From 3dc242fceffa6a47836572ffe2945f05bdfed278 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 18 May 2013 15:03:02 -0400 Subject: [PATCH 1/1] Imported Upstream version 2.81 --- AUTHORS | 22 + BspDemo.bsp | Bin 0 -> 105100 bytes BulletLicense.txt | 18 + Bullet_User_Manual.pdf | Bin 0 -> 1168019 bytes CMakeLists.txt | 420 + COPYING | 17 + ChangeLog | 791 + Demos/AllBulletDemos/CMakeLists.txt | 104 + Demos/AllBulletDemos/DemoEntries.cpp | 178 + Demos/AllBulletDemos/DemoEntries.h | 34 + Demos/AllBulletDemos/Main.cpp | 574 + Demos/AllBulletDemos/Makefile.am | 34 + Demos/AllBulletDemos/Makefile.in | 837 + Demos/BasicDemo/BasicDemo.cpp | 242 + Demos/BasicDemo/BasicDemo.h | 82 + Demos/BasicDemo/CMakeLists.txt | 87 + Demos/BasicDemo/Makefile.am | 5 + Demos/BasicDemo/Makefile.in | 518 + Demos/BasicDemo/Win32BasicDemo.cpp | 25 + Demos/BasicDemo/main.cpp | 39 + Demos/Benchmarks/BenchmarkDemo.cpp | 1329 + Demos/Benchmarks/BenchmarkDemo.h | 265 + Demos/Benchmarks/CMakeLists.txt | 107 + Demos/Benchmarks/Taru.mdl | 49 + Demos/Benchmarks/Win32BenchmarkDemo.cpp | 25 + Demos/Benchmarks/landscape.mdl | 84369 +++++++++++++++++++ Demos/Benchmarks/main.cpp | 89 + Demos/Benchmarks/premake4.lua | 22 + Demos/Box2dDemo/Box2dDemo.cpp | 370 + Demos/Box2dDemo/Box2dDemo.h | 89 + Demos/Box2dDemo/CMakeLists.txt | 75 + Demos/Box2dDemo/Win32Box2dDemo.cpp | 25 + Demos/Box2dDemo/main.cpp | 61 + Demos/BspDemo/BspConverter.cpp | 207 + Demos/BspDemo/BspConverter.h | 39 + Demos/BspDemo/BspDemo.cpp | 321 + Demos/BspDemo/BspDemo.h | 71 + Demos/BspDemo/BspLoader.cpp | 730 + Demos/BspDemo/BspLoader.h | 295 + Demos/BspDemo/CMakeLists.txt | 60 + Demos/BspDemo/main.cpp | 59 + Demos/BulletDinoDemo/BulletDino.c | 996 + Demos/BulletDinoDemo/CMakeLists.txt | 61 + Demos/BulletXmlImportDemo/BulletXmlImportDemo.cpp | 180 + Demos/BulletXmlImportDemo/BulletXmlImportDemo.h | 87 + Demos/BulletXmlImportDemo/CMakeLists.txt | 94 + .../Win32BulletXmlImportDemo.cpp | 25 + Demos/BulletXmlImportDemo/bullet_basic.xml | 668 + Demos/BulletXmlImportDemo/bulletser.xml | 24344 ++++++ Demos/BulletXmlImportDemo/main.cpp | 107 + Demos/CMakeLists.txt | 67 + Demos/CcdPhysicsDemo/CMakeLists.txt | 59 + Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp | 424 + Demos/CcdPhysicsDemo/CcdPhysicsDemo.h | 94 + Demos/CcdPhysicsDemo/Makefile.am | 5 + Demos/CcdPhysicsDemo/Makefile.in | 519 + Demos/CcdPhysicsDemo/main.cpp | 49 + Demos/CellSpuDemo/BasicDemo2.cpp | 277 + Demos/CellSpuDemo/BasicDemo2.h | 62 + Demos/CharacterDemo/CMakeLists.txt | 75 + Demos/CharacterDemo/CharacterDemo.cpp | 531 + Demos/CharacterDemo/CharacterDemo.h | 153 + Demos/CharacterDemo/DynamicCharacterController.cpp | 204 + Demos/CharacterDemo/DynamicCharacterController.h | 55 + Demos/CharacterDemo/main.cpp | 19 + Demos/CollisionDemo/CMakeLists.txt | 54 + Demos/CollisionDemo/CollisionDemo.cpp | 380 + Demos/CollisionDemo/CollisionDemo.h | 38 + Demos/CollisionInterfaceDemo/CMakeLists.txt | 77 + .../CollisionInterfaceDemo.cpp | 292 + .../CollisionInterfaceDemo.h | 42 + .../Win32CollisionInterfaceDemo.cpp | 25 + Demos/CollisionInterfaceDemo/main.cpp | 19 + Demos/ConcaveConvexcastDemo/CMakeLists.txt | 48 + .../ConcaveConvexcastDemo.cpp | 516 + .../ConcaveConvexcastDemo/ConcaveConvexcastDemo.h | 84 + Demos/ConcaveConvexcastDemo/main.cpp | 15 + Demos/ConcaveDemo/CMakeLists.txt | 80 + Demos/ConcaveDemo/ConcaveDemo.h | 91 + Demos/ConcaveDemo/ConcavePhysicsDemo.cpp | 474 + Demos/ConcaveDemo/Jamfile | 3 + Demos/ConcaveDemo/Win32ConcaveDemo.cpp | 25 + Demos/ConcaveDemo/main.cpp | 19 + Demos/ConcaveRaycastDemo/CMakeLists.txt | 57 + Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp | 490 + Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.h | 85 + Demos/ConcaveRaycastDemo/main.cpp | 15 + Demos/ConstraintDemo/CMakeLists.txt | 71 + Demos/ConstraintDemo/ConstraintDemo.cpp | 820 + Demos/ConstraintDemo/ConstraintDemo.h | 75 + Demos/ConstraintDemo/Win32ConstraintDemo.cpp | 25 + Demos/ConstraintDemo/main.cpp | 20 + Demos/ContinuousConvexCollision/CMakeLists.txt | 47 + .../ContinuousConvexCollision.h | 36 + .../ContinuousConvexCollisionDemo.cpp | 287 + Demos/ConvexDecompositionDemo/CMakeLists.txt | 83 + .../ConvexDecompositionDemo.cpp | 741 + .../ConvexDecompositionDemo.h | 89 + .../Win32ConvexDecompositionDemo.cpp | 25 + Demos/ConvexDecompositionDemo/main.cpp | 32 + .../testFile32Single.bullet | Bin 0 -> 67844 bytes Demos/ConvexHullDistance/CMakeLists.txt | 82 + .../ConvexHullDistance/ConvexHullDistanceDemo.cpp | 508 + Demos/DX11ClothDemo/CMakeLists.txt | 166 + Demos/DX11ClothDemo/DXUT/Core/DXUT.cpp | 5846 ++ Demos/DX11ClothDemo/DXUT/Core/DXUT.h | 378 + Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.cpp | 1154 + Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.h | 210 + Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.cpp | 1177 + Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.h | 207 + Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.cpp | 1785 + Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.h | 594 + Demos/DX11ClothDemo/DXUT/Core/dpiaware.manifest | 7 + .../DX11ClothDemo/DXUT/Optional/DXUTLockFreePipe.h | 227 + Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.cpp | 5663 ++ Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.h | 24 + Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.cpp | 1525 + Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.h | 517 + Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.cpp | 7241 ++ Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.h | 1383 + Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.cpp | 990 + Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.h | 141 + Demos/DX11ClothDemo/DXUT/Optional/DXUTres.cpp | 8338 ++ Demos/DX11ClothDemo/DXUT/Optional/DXUTres.h | 18 + .../DXUT/Optional/DXUTsettingsdlg.cpp | 2853 + .../DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.h | 248 + Demos/DX11ClothDemo/DXUT/Optional/ImeUi.cpp | 3662 + Demos/DX11ClothDemo/DXUT/Optional/ImeUi.h | 124 + Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.cpp | 2348 + Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.h | 589 + Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp | 1695 + Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.h | 368 + Demos/DX11ClothDemo/DXUT/Optional/SDKsound.cpp | 1053 + Demos/DX11ClothDemo/DXUT/Optional/SDKsound.h | 124 + Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.cpp | 539 + Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.h | 59 + Demos/DX11ClothDemo/DXUT/Optional/directx.ico | Bin 0 -> 25214 bytes Demos/DX11ClothDemo/Media/Tiny/Tiny_skin.dds | Bin 0 -> 262272 bytes Demos/DX11ClothDemo/Media/Tiny/tiny.sdkmesh | Bin 0 -> 231612 bytes Demos/DX11ClothDemo/Media/Tiny/tiny.x | 53984 ++++++++++++ Demos/DX11ClothDemo/Media/UI/DXUTShared.fx | 69 + Demos/DX11ClothDemo/Media/UI/Font.dds | Bin 0 -> 76128 bytes Demos/DX11ClothDemo/Media/UI/arrow.x | 1050 + Demos/DX11ClothDemo/Media/UI/dxutcontrols.dds | Bin 0 -> 262272 bytes Demos/DX11ClothDemo/amdFlag.bmp | Bin 0 -> 1396038 bytes Demos/DX11ClothDemo/atiFlag.bmp | Bin 0 -> 1396038 bytes Demos/DX11ClothDemo/btDirectComputeSupport.h | 180 + Demos/DX11ClothDemo/cap.h | 298 + Demos/DX11ClothDemo/capsule.h | 67 + Demos/DX11ClothDemo/cloth.h | 312 + Demos/DX11ClothDemo/cloth_renderer.cpp | 1356 + Demos/DX11ClothDemo/cloth_renderer.fx | 157 + Demos/DX11ClothDemo/cloth_renderer.rc | 77 + Demos/DX11ClothDemo/cloth_renderer_PS.hlsl | 90 + Demos/DX11ClothDemo/cloth_renderer_VS.hlsl | 48 + Demos/DX11ClothDemo/cylinder.h | 297 + Demos/DX11ClothDemo/premake4.lua | 41 + Demos/DX11ClothDemo/resource.h | 16 + Demos/DX11ClothDemo/texture.bmp | Bin 0 -> 263222 bytes Demos/DX11ClothDemo/texture.png | Bin 0 -> 7922 bytes Demos/DoublePrecisionDemo/CMakeLists.txt | 49 + Demos/DoublePrecisionDemo/DoublePrecisionDemo.cpp | 280 + Demos/DoublePrecisionDemo/DoublePrecisionDemo.h | 41 + Demos/DynamicControlDemo/CMakeLists.txt | 49 + Demos/DynamicControlDemo/MotorDemo.cpp | 468 + Demos/DynamicControlDemo/MotorDemo.h | 80 + Demos/DynamicControlDemo/main.cpp | 28 + Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp | 856 + Demos/ForkLiftDemo/CMakeLists.txt | 59 + Demos/ForkLiftDemo/ForkLiftDemo.cpp | 866 + Demos/ForkLiftDemo/ForkLiftDemo.h | 113 + Demos/ForkLiftDemo/main.cpp | 18 + Demos/FractureDemo/CMakeLists.txt | 96 + Demos/FractureDemo/FractureDemo.cpp | 362 + Demos/FractureDemo/FractureDemo.h | 87 + Demos/FractureDemo/Win32FractureDemo.cpp | 25 + Demos/FractureDemo/btFractureBody.cpp | 139 + Demos/FractureDemo/btFractureBody.h | 78 + Demos/FractureDemo/btFractureDynamicsWorld.cpp | 688 + Demos/FractureDemo/btFractureDynamicsWorld.h | 51 + Demos/FractureDemo/main.cpp | 42 + Demos/GenericJointDemo/CMakeLists.txt | 82 + Demos/GenericJointDemo/GenericJointDemo.cpp | 135 + Demos/GenericJointDemo/GenericJointDemo.h | 51 + Demos/GenericJointDemo/Ragdoll.cpp | 373 + Demos/GenericJointDemo/Ragdoll.h | 71 + Demos/GenericJointDemo/Win32GenericJointDemo.cpp | 25 + Demos/GenericJointDemo/main.cpp | 28 + Demos/GimpactTestDemo/BunnyMesh.h | 1379 + Demos/GimpactTestDemo/CMakeLists.txt | 58 + Demos/GimpactTestDemo/GimpactTestDemo.cpp | 688 + Demos/GimpactTestDemo/GimpactTestDemo.h | 145 + Demos/GimpactTestDemo/TorusMesh.h | 921 + Demos/GimpactTestDemo/Win32GimpactDemo.cpp | 25 + Demos/GimpactTestDemo/main.cpp | 13 + Demos/GjkConvexCastDemo/CMakeLists.txt | 48 + Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp | 188 + Demos/GjkConvexCastDemo/LinearConvexCastDemo.h | 44 + Demos/GjkConvexCastDemo/main.cpp | 17 + Demos/Gpu2dDemo/BasicDemo.cpp | 808 + Demos/Gpu2dDemo/BasicDemo.h | 99 + Demos/Gpu2dDemo/CMakeLists.txt | 38 + Demos/Gpu2dDemo/Makefile.am | 5 + Demos/Gpu2dDemo/btGpuDemo2dCpuFunc.cpp | 30 + Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h | 497 + Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h | 33 + Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h | 35 + Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.cpp | 592 + Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.h | 291 + Demos/Gpu2dDemo/btGpuDemoPairCache.cpp | 76 + Demos/Gpu2dDemo/btGpuDemoPairCache.h | 136 + Demos/Gpu2dDemo/main.cpp | 62 + Demos/Gpu2dDemo/oecakeLoader.cpp | 264 + Demos/Gpu2dDemo/oecakeLoader.h | 35 + Demos/Gpu3dDemo/BasicDemo3d.cpp | 852 + Demos/Gpu3dDemo/BasicDemo3d.h | 93 + Demos/Gpu3dDemo/CMakeLists.txt | 34 + Demos/Gpu3dDemo/btGpuDemo3dCpuFunc.cpp | 32 + Demos/Gpu3dDemo/btGpuDemo3dSharedCode.h | 545 + Demos/Gpu3dDemo/btGpuDemo3dSharedDefs.h | 38 + Demos/Gpu3dDemo/btGpuDemo3dSharedTypes.h | 39 + Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.cpp | 593 + Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.h | 252 + Demos/Gpu3dDemo/main.cpp | 61 + Demos/GyroscopicDemo/CMakeLists.txt | 71 + Demos/GyroscopicDemo/GyroscopicDemo.cpp | 240 + Demos/GyroscopicDemo/GyroscopicDemo.h | 71 + Demos/GyroscopicDemo/Win32GyroscopicDemo.cpp | 25 + Demos/GyroscopicDemo/main.cpp | 20 + Demos/HelloWorld/CMakeLists.txt | 29 + Demos/HelloWorld/HelloWorld.cpp | 180 + Demos/HelloWorld/premake4.lua | 22 + Demos/InternalEdgeDemo/CMakeLists.txt | 69 + Demos/InternalEdgeDemo/InternalEdgeDemo.cpp | 623 + Demos/InternalEdgeDemo/InternalEdgeDemo.h | 93 + Demos/InternalEdgeDemo/Taru.mdl | 49 + Demos/InternalEdgeDemo/Win32InternalEdgeDemo.cpp | 25 + Demos/InternalEdgeDemo/main.cpp | 19 + Demos/Makefile.am | 5 + Demos/Makefile.in | 562 + Demos/MovingConcaveDemo/CMakeLists.txt | 51 + Demos/MovingConcaveDemo/ConcaveDemo.h | 48 + Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp | 1926 + Demos/MultiMaterialDemo/CMakeLists.txt | 31 + Demos/MultiMaterialDemo/MultiMaterialDemo.cpp | 383 + Demos/MultiMaterialDemo/MultiMaterialDemo.h | 84 + Demos/MultiMaterialDemo/main.cpp | 22 + Demos/MultiThreadedDemo/CMakeLists.txt | 55 + Demos/MultiThreadedDemo/Makefile.am | 5 + Demos/MultiThreadedDemo/Makefile.in | 520 + Demos/MultiThreadedDemo/MultiThreadedDemo.cpp | 505 + Demos/MultiThreadedDemo/MultiThreadedDemo.h | 79 + Demos/MultiThreadedDemo/main.cpp | 36 + Demos/NativeClient/bin_html/bind.js | 22 + Demos/NativeClient/bin_html/dragger.js | 134 + Demos/NativeClient/bin_html/httpd.cmd | 9 + Demos/NativeClient/bin_html/httpd.py | 114 + Demos/NativeClient/bin_html/index.html | 33 + Demos/NativeClient/bin_html/trackball.js | 296 + Demos/NativeClient/bin_html/tumbler.js | 133 + Demos/NativeClient/bin_html/tumbler.nmf | 6 + Demos/NativeClient/bin_html/vector3.js | 91 + Demos/NativeClient/callback.h | 92 + Demos/NativeClient/cube.cc | 267 + Demos/NativeClient/cube.h | 97 + Demos/NativeClient/opengl_context.cc | 72 + Demos/NativeClient/opengl_context.h | 90 + Demos/NativeClient/opengl_context_ptrs.h | 22 + Demos/NativeClient/premake4.lua | 27 + Demos/NativeClient/scripting_bridge.cc | 95 + Demos/NativeClient/scripting_bridge.h | 52 + Demos/NativeClient/shader_util.cc | 95 + Demos/NativeClient/shader_util.h | 29 + Demos/NativeClient/transforms.cc | 116 + Demos/NativeClient/transforms.h | 45 + Demos/NativeClient/tumbler.cc | 136 + Demos/NativeClient/tumbler.h | 64 + Demos/NativeClient/tumbler_module.cc | 45 + Demos/OpenCLClothDemo/AMD/CMakeLists.txt | 86 + Demos/OpenCLClothDemo/AMD/premake4.lua | 67 + Demos/OpenCLClothDemo/Apple/CMakeLists.txt | 55 + Demos/OpenCLClothDemo/CLClothDemo.sln | 20 + Demos/OpenCLClothDemo/CLClothDemo.vcproj | 233 + Demos/OpenCLClothDemo/CMakeLists.txt | 17 + Demos/OpenCLClothDemo/Intel/CMakeLists.txt | 83 + Demos/OpenCLClothDemo/Intel/premake4.lua | 68 + Demos/OpenCLClothDemo/MiniCL/CMakeLists.txt | 88 + Demos/OpenCLClothDemo/NVidia/CMakeLists.txt | 86 + Demos/OpenCLClothDemo/NVidia/premake4.lua | 68 + Demos/OpenCLClothDemo/btOpenCLSupport.h | 84 + Demos/OpenCLClothDemo/cl_cloth_demo.cpp | 614 + Demos/OpenCLClothDemo/cloth.h | 258 + Demos/OpenCLClothDemo/clstuff.cpp | 71 + Demos/OpenCLClothDemo/clstuff.h | 11 + Demos/OpenCLClothDemo/clstuff.hpp | 10 + Demos/OpenCLClothDemo/fragment.glsl | 7 + Demos/OpenCLClothDemo/gl_win.cpp | 268 + Demos/OpenCLClothDemo/gl_win.h | 49 + Demos/OpenCLClothDemo/gl_win.hpp | 34 + Demos/OpenCLClothDemo/shaders.cl | 535 + Demos/OpenCLClothDemo/vertex.glsl | 7 + Demos/OpenGL/CMakeLists.txt | 67 + Demos/OpenGL/CommandLineArguments.h | 112 + Demos/OpenGL/DebugCastResult.h | 88 + Demos/OpenGL/DemoApplication.cpp | 1382 + Demos/OpenGL/DemoApplication.h | 258 + Demos/OpenGL/GLDebugDrawer.cpp | 130 + Demos/OpenGL/GLDebugDrawer.h | 37 + Demos/OpenGL/GLDebugFont.cpp | 1000 + Demos/OpenGL/GLDebugFont.h | 29 + Demos/OpenGL/GL_DialogDynamicsWorld.cpp | 761 + Demos/OpenGL/GL_DialogDynamicsWorld.h | 91 + Demos/OpenGL/GL_DialogWindow.cpp | 358 + Demos/OpenGL/GL_DialogWindow.h | 285 + Demos/OpenGL/GL_ShapeDrawer.cpp | 987 + Demos/OpenGL/GL_ShapeDrawer.h | 70 + Demos/OpenGL/GL_Simplex1to4.cpp | 80 + Demos/OpenGL/GL_Simplex1to4.h | 41 + Demos/OpenGL/GlutDemoApplication.cpp | 87 + Demos/OpenGL/GlutDemoApplication.h | 36 + Demos/OpenGL/GlutStuff.cpp | 120 + Demos/OpenGL/GlutStuff.h | 86 + Demos/OpenGL/Makefile.am | 12 + Demos/OpenGL/Makefile.in | 501 + Demos/OpenGL/RenderTexture.cpp | 86 + Demos/OpenGL/RenderTexture.h | 73 + Demos/OpenGL/Win32AppMain.cpp | 405 + Demos/OpenGL/Win32DemoApplication.cpp | 79 + Demos/OpenGL/Win32DemoApplication.h | 41 + Demos/OpenGL/premake4.lua | 18 + Demos/OpenGL/stb_image.cpp | 4341 + Demos/OpenGL/stb_image.h | 332 + Demos/OpenPL_Demo/CApi.cpp | 159 + Demos/OpenPL_Demo/OpenPL_Demo.c | 44 + Demos/ParticlesOpenCL/AMD/CMakeLists.txt | 86 + Demos/ParticlesOpenCL/Apple/CMakeLists.txt | 84 + Demos/ParticlesOpenCL/CMakeLists.txt | 19 + Demos/ParticlesOpenCL/Intel/CMakeLists.txt | 86 + Demos/ParticlesOpenCL/MiniCL/CMakeLists.txt | 94 + Demos/ParticlesOpenCL/MiniCL/MiniCLTaskWrap.cpp | 33 + Demos/ParticlesOpenCL/NVidia/CMakeLists.txt | 95 + Demos/ParticlesOpenCL/ParticlesDemo.cpp | 651 + Demos/ParticlesOpenCL/ParticlesDemo.h | 128 + Demos/ParticlesOpenCL/ParticlesOCL.cl | 467 + .../btParticlesDemoDynamicsWorld.cpp | 1177 + Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h | 183 + Demos/ParticlesOpenCL/btParticlesSharedDefs.h | 14 + Demos/ParticlesOpenCL/btParticlesSharedTypes.h | 54 + Demos/ParticlesOpenCL/main.cpp | 51 + Demos/ParticlesOpenCL/shaders.cpp | 56 + Demos/ParticlesOpenCL/shaders.h | 2 + Demos/RagdollDemo/CMakeLists.txt | 49 + Demos/RagdollDemo/RagdollDemo.cpp | 507 + Demos/RagdollDemo/RagdollDemo.h | 77 + Demos/RagdollDemo/main.cpp | 31 + Demos/RaytestDemo/CMakeLists.txt | 87 + Demos/RaytestDemo/Makefile.am | 5 + Demos/RaytestDemo/RaytestDemo.cpp | 326 + Demos/RaytestDemo/RaytestDemo.h | 82 + Demos/RaytestDemo/Win32RaytestDemo.cpp | 25 + Demos/RaytestDemo/main.cpp | 41 + Demos/Raytracer/CMakeLists.txt | 49 + Demos/Raytracer/Raytracer.cpp | 627 + Demos/Raytracer/Raytracer.h | 65 + Demos/Raytracer/main.cpp | 16 + Demos/RollingFrictionDemo/CMakeLists.txt | 87 + Demos/RollingFrictionDemo/Makefile.am | 5 + Demos/RollingFrictionDemo/RollingFrictionDemo.cpp | 291 + Demos/RollingFrictionDemo/RollingFrictionDemo.h | 82 + .../Win32RollingFrictionDemo.cpp | 25 + Demos/RollingFrictionDemo/main.cpp | 41 + Demos/SerializeDemo/AMD/CMakeLists.txt | 157 + Demos/SerializeDemo/AMD/premake4.lua | 65 + Demos/SerializeDemo/CMakeLists.txt | 95 + Demos/SerializeDemo/SerializeDemo.cpp | 940 + Demos/SerializeDemo/SerializeDemo.h | 103 + Demos/SerializeDemo/Win32SerializeDemo.cpp | 25 + Demos/SerializeDemo/main.cpp | 134 + Demos/SerializeDemo/testFile.bullet | Bin 0 -> 171368 bytes Demos/SerializeDemo/testFileCloth.bullet | Bin 0 -> 98740 bytes Demos/SharedOpenCL/btOpenCLInclude.h | 41 + Demos/SharedOpenCL/btOpenCLUtils.cpp | 789 + Demos/SharedOpenCL/btOpenCLUtils.h | 107 + Demos/SharedOpenCL/clew.c | 313 + Demos/SharedOpenCL/clew.h | 1316 + Demos/SimplexDemo/CMakeLists.txt | 48 + Demos/SimplexDemo/SimplexDemo.cpp | 123 + Demos/SimplexDemo/SimplexDemo.h | 36 + Demos/SliderConstraintDemo/CMakeLists.txt | 51 + .../SliderConstraintDemo/SliderConstraintDemo.cpp | 512 + Demos/SliderConstraintDemo/SliderConstraintDemo.h | 73 + Demos/SliderConstraintDemo/main.cpp | 25 + Demos/SoftDemo/AMD/premake4.lua | 59 + Demos/SoftDemo/CMakeLists.txt | 64 + Demos/SoftDemo/Makefile.am | 5 + Demos/SoftDemo/Makefile.in | 518 + Demos/SoftDemo/SoftDemo.cpp | 2293 + Demos/SoftDemo/SoftDemo.h | 197 + Demos/SoftDemo/bunny.inl | 4 + Demos/SoftDemo/cube.inl | 4 + Demos/SoftDemo/main.cpp | 37 + Demos/TerrainDemo/Makefile.am | 6 + Demos/TerrainDemo/Makefile.in | 518 + Demos/TerrainDemo/TerrainDemo.cpp | 921 + Demos/TerrainDemo/TerrainDemo.h | 27 + Demos/TerrainDemo/main.cpp | 14 + Demos/ThreadingDemo/CMakeLists.txt | 47 + Demos/ThreadingDemo/main.cpp | 185 + Demos/UserCollisionAlgorithm/CMakeLists.txt | 38 + .../UserCollisionAlgorithm.cpp | 175 + .../UserCollisionAlgorithm.h | 36 + Demos/VectorAdd_OpenCL/AMD/CMakeLists.txt | 34 + Demos/VectorAdd_OpenCL/Apple/CMakeLists.txt | 25 + Demos/VectorAdd_OpenCL/CMakeLists.txt | 16 + Demos/VectorAdd_OpenCL/MiniCL/CMakeLists.txt | 38 + Demos/VectorAdd_OpenCL/MiniCL_VectorAdd.cpp | 389 + Demos/VectorAdd_OpenCL/NVidia/CMakeLists.txt | 28 + Demos/VectorAdd_OpenCL/VectorAddKernels.cl | 35 + Demos/VehicleDemo/CMakeLists.txt | 31 + Demos/VehicleDemo/Makefile.am | 5 + Demos/VehicleDemo/Makefile.in | 518 + Demos/VehicleDemo/VehicleDemo.cpp | 671 + Demos/VehicleDemo/VehicleDemo.h | 91 + Demos/VehicleDemo/main.cpp | 18 + Demos/VoronoiFractureDemo/CMakeLists.txt | 87 + Demos/VoronoiFractureDemo/Makefile.am | 5 + Demos/VoronoiFractureDemo/VoronoiFractureDemo.cpp | 660 + Demos/VoronoiFractureDemo/VoronoiFractureDemo.h | 97 + .../Win32VoronoiFractureDemo.cpp | 25 + Demos/VoronoiFractureDemo/main.cpp | 51 + Demos/premake4.lua | 100 + Doxyfile | 780 + .../AllBulletDemos.xcodeproj/TemplateIcon.icns | Bin 0 -> 52318 bytes .../AllBulletDemos.xcodeproj/project.pbxproj | 1941 + .../AllBulletDemos.xcodeproj/zakariya.pbxuser | 248 + .../zakariya.perspectivev3 | 1517 + Extras/AllBulletDemosOSX/AllBulletDemos_Prefix.pch | 7 + Extras/AllBulletDemosOSX/BulletIcon.icns | Bin 0 -> 28472 bytes Extras/AllBulletDemosOSX/BulletIcon.psd | Bin 0 -> 101941 bytes Extras/AllBulletDemosOSX/English.lproj/Credits.rtf | 11 + .../English.lproj/InfoPlist.strings | Bin 0 -> 92 bytes .../AllBulletDemosOSX/English.lproj/MainMenu.xib | 2157 + Extras/AllBulletDemosOSX/Info.plist | 28 + Extras/AllBulletDemosOSX/README.txt | 6 + Extras/AllBulletDemosOSX/main.m | 14 + Extras/AllBulletDemosOSX/src/BTDemo.h | 106 + Extras/AllBulletDemosOSX/src/BTDemo.mm | 413 + .../AllBulletDemosOSX/src/BTDemosAppController.h | 54 + .../AllBulletDemosOSX/src/BTDemosAppController.m | 151 + .../AllBulletDemosOSX/src/BTSimulationParameters.h | 47 + .../AllBulletDemosOSX/src/BTSimulationParameters.m | 96 + .../src/toolkit/BTFullscreenWindow.h | 25 + .../src/toolkit/BTFullscreenWindow.m | 48 + .../src/toolkit/BTGLUTKeyAdapter.h | 46 + .../src/toolkit/BTGLUTKeyAdapter.m | 128 + .../src/toolkit/BTOpenGLDisplayDelegate.h | 50 + .../AllBulletDemosOSX/src/toolkit/BTOpenGLView.h | 65 + .../AllBulletDemosOSX/src/toolkit/BTOpenGLView.m | 603 + Extras/CDTestFramework/AntTweakBar/ChangeLog.txt | 208 + Extras/CDTestFramework/AntTweakBar/Clean.bat | 24 + Extras/CDTestFramework/AntTweakBar/License.txt | 24 + Extras/CDTestFramework/AntTweakBar/Readme.txt | 15 + .../AntTweakBar/include/AntTweakBar.h | 381 + .../CDTestFramework/AntTweakBar/src/AntPerfTimer.h | 56 + .../CDTestFramework/AntTweakBar/src/AntTweakBar.rc | 83 + .../AntTweakBar/src/AntTweakBar.sln | 25 + .../AntTweakBar/src/AntTweakBar.vcproj | 997 + Extras/CDTestFramework/AntTweakBar/src/LoadOGL.cpp | 531 + Extras/CDTestFramework/AntTweakBar/src/LoadOGL.h | 397 + .../AntTweakBar/src/LoadOGLCore.cpp | 527 + .../CDTestFramework/AntTweakBar/src/LoadOGLCore.h | 403 + Extras/CDTestFramework/AntTweakBar/src/Makefile | 100 + .../AntTweakBar/src/Makefile.x86_64 | 97 + Extras/CDTestFramework/AntTweakBar/src/MiniGLUT.h | 142 + Extras/CDTestFramework/AntTweakBar/src/TwBar.cpp | 7766 ++ Extras/CDTestFramework/AntTweakBar/src/TwBar.h | 438 + .../CDTestFramework/AntTweakBar/src/TwColors.cpp | 153 + Extras/CDTestFramework/AntTweakBar/src/TwColors.h | 80 + .../AntTweakBar/src/TwDirect3D10.cpp | 1291 + .../CDTestFramework/AntTweakBar/src/TwDirect3D10.h | 108 + .../AntTweakBar/src/TwDirect3D11.cpp | 1653 + .../CDTestFramework/AntTweakBar/src/TwDirect3D11.h | 117 + .../AntTweakBar/src/TwDirect3D9.cpp | 640 + .../CDTestFramework/AntTweakBar/src/TwDirect3D9.h | 90 + .../CDTestFramework/AntTweakBar/src/TwEventGLFW.c | 212 + .../CDTestFramework/AntTweakBar/src/TwEventGLUT.c | 150 + .../CDTestFramework/AntTweakBar/src/TwEventSDL.c | 43 + .../CDTestFramework/AntTweakBar/src/TwEventWin.c | 256 + .../CDTestFramework/AntTweakBar/src/TwEventWin32.c | 188 + .../CDTestFramework/AntTweakBar/src/TwEventX11.c | 205 + Extras/CDTestFramework/AntTweakBar/src/TwFonts.cpp | 4898 ++ Extras/CDTestFramework/AntTweakBar/src/TwFonts.h | 66 + Extras/CDTestFramework/AntTweakBar/src/TwGraph.h | 58 + Extras/CDTestFramework/AntTweakBar/src/TwMgr.cpp | 6726 ++ Extras/CDTestFramework/AntTweakBar/src/TwMgr.h | 518 + .../CDTestFramework/AntTweakBar/src/TwOpenGL.cpp | 907 + Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.h | 99 + .../AntTweakBar/src/TwOpenGLCore.cpp | 927 + .../CDTestFramework/AntTweakBar/src/TwOpenGLCore.h | 121 + .../CDTestFramework/AntTweakBar/src/TwPrecomp.cpp | 1 + Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.h | 93 + .../CDTestFramework/AntTweakBar/src/d3d10vs2003.h | 46 + .../AntTweakBar/src/res/FontChars.txt | 232 + .../AntTweakBar/src/res/FontFixed1.pgm | 28788 +++++++ .../AntTweakBar/src/res/FontLargeAA.pgm | 1197 + .../AntTweakBar/src/res/FontNormal.pgm | 895 + .../AntTweakBar/src/res/FontNormalAA.pgm | 1012 + .../AntTweakBar/src/res/FontSmall.pgm | 603 + .../AntTweakBar/src/res/TwXCursors.h | 908 + .../AntTweakBar/src/res/cur00000.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00001.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00002.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00003.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00004.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00005.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00006.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00007.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00008.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00009.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00010.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00011.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00012.cur | Bin 0 -> 326 bytes .../AntTweakBar/src/res/cur00013.cur | Bin 0 -> 326 bytes .../CDTestFramework/AntTweakBar/src/res/curs00.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs01.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs02.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs03.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs04.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs05.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs06.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs07.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs08.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs09.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs10.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs11.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs12.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/curs13.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask00.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask01.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask02.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask03.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask04.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask05.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask06.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask07.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask08.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask09.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask10.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask11.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask12.pbm | 32 + .../CDTestFramework/AntTweakBar/src/res/mask13.pbm | 32 + Extras/CDTestFramework/AntTweakBar/src/resource.h | 29 + Extras/CDTestFramework/BipartiteBoxPruning.cpp | 166 + Extras/CDTestFramework/BipartiteBoxPruning.h | 51 + .../BulletSAPCompleteBoxPruningTest.cpp | 1069 + .../BulletSAPCompleteBoxPruningTest.h | 65 + Extras/CDTestFramework/CDTestFramework.cpp | 448 + Extras/CDTestFramework/CDTestFramework.h | 20 + Extras/CDTestFramework/CDTestFramework.sln | 96 + Extras/CDTestFramework/CDTestFramework.txt | 31 + Extras/CDTestFramework/CDTestFramework.vcproj | 451 + Extras/CDTestFramework/Camera.cpp | 156 + Extras/CDTestFramework/Camera.h | 32 + Extras/CDTestFramework/CapsuleMeshQuery.cpp | 127 + Extras/CDTestFramework/CapsuleMeshQuery.h | 49 + Extras/CDTestFramework/CollisionTest.cpp | 38 + Extras/CDTestFramework/CollisionTest.h | 50 + Extras/CDTestFramework/CompleteBoxPruning.cpp | 168 + Extras/CDTestFramework/CompleteBoxPruning.h | 53 + Extras/CDTestFramework/GLFontData.h | 1047 + Extras/CDTestFramework/GLFontRenderer.cpp | 207 + Extras/CDTestFramework/GLFontRenderer.h | 37 + Extras/CDTestFramework/GLUT32.DLL | Bin 0 -> 237568 bytes Extras/CDTestFramework/History.txt | 11 + Extras/CDTestFramework/IceHelpers.cpp | 358 + Extras/CDTestFramework/IceHelpers.h | 41 + Extras/CDTestFramework/License.txt | 49 + Extras/CDTestFramework/License.txt.bak | 0 Extras/CDTestFramework/OBBMeshQuery.cpp | 157 + Extras/CDTestFramework/OBBMeshQuery.h | 53 + Extras/CDTestFramework/Opcode/Ice/IceAABB.cpp | 422 + Extras/CDTestFramework/Opcode/Ice/IceAABB.h | 514 + Extras/CDTestFramework/Opcode/Ice/IceAllocator.cpp | 805 + Extras/CDTestFramework/Opcode/Ice/IceAllocator.h | 52 + Extras/CDTestFramework/Opcode/Ice/IceAssert.h | 48 + Extras/CDTestFramework/Opcode/Ice/IceAxes.h | 70 + Extras/CDTestFramework/Opcode/Ice/IceBitArray.cpp | 73 + Extras/CDTestFramework/Opcode/Ice/IceBitArray.h | 82 + .../CDTestFramework/Opcode/Ice/IceBoundingSphere.h | 158 + Extras/CDTestFramework/Opcode/Ice/IceContainer.cpp | 423 + Extras/CDTestFramework/Opcode/Ice/IceContainer.h | 254 + Extras/CDTestFramework/Opcode/Ice/IceFPU.h | 403 + Extras/CDTestFramework/Opcode/Ice/IceHPoint.cpp | 87 + Extras/CDTestFramework/Opcode/Ice/IceHPoint.h | 173 + Extras/CDTestFramework/Opcode/Ice/IceHashing.h | 78 + .../Opcode/Ice/IceIndexedTriangle.cpp | 564 + .../Opcode/Ice/IceIndexedTriangle.h | 84 + Extras/CDTestFramework/Opcode/Ice/IceLSS.h | 91 + Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.cpp | 64 + Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.h | 512 + Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.cpp | 152 + Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.h | 471 + .../CDTestFramework/Opcode/Ice/IceMemoryMacros.h | 180 + Extras/CDTestFramework/Opcode/Ice/IceOBB.cpp | 339 + Extras/CDTestFramework/Opcode/Ice/IceOBB.h | 193 + Extras/CDTestFramework/Opcode/Ice/IcePairs.h | 61 + Extras/CDTestFramework/Opcode/Ice/IcePlane.cpp | 61 + Extras/CDTestFramework/Opcode/Ice/IcePlane.h | 129 + Extras/CDTestFramework/Opcode/Ice/IcePoint.cpp | 209 + Extras/CDTestFramework/Opcode/Ice/IcePoint.h | 544 + .../CDTestFramework/Opcode/Ice/IcePreprocessor.h | 158 + Extras/CDTestFramework/Opcode/Ice/IceRandom.cpp | 52 + Extras/CDTestFramework/Opcode/Ice/IceRandom.h | 58 + Extras/CDTestFramework/Opcode/Ice/IceRay.cpp | 100 + Extras/CDTestFramework/Opcode/Ice/IceRay.h | 114 + .../Opcode/Ice/IceRevisitedRadix.cpp | 592 + .../CDTestFramework/Opcode/Ice/IceRevisitedRadix.h | 74 + Extras/CDTestFramework/Opcode/Ice/IceSegment.cpp | 73 + Extras/CDTestFramework/Opcode/Ice/IceSegment.h | 71 + Extras/CDTestFramework/Opcode/Ice/IceTriangle.cpp | 302 + Extras/CDTestFramework/Opcode/Ice/IceTriangle.h | 84 + Extras/CDTestFramework/Opcode/Ice/IceTrilist.h | 77 + Extras/CDTestFramework/Opcode/Ice/IceTypes.h | 181 + Extras/CDTestFramework/Opcode/Ice/IceUtils.cpp | 55 + Extras/CDTestFramework/Opcode/Ice/IceUtils.h | 377 + Extras/CDTestFramework/Opcode/Ice/_IceAABB.h | 522 + .../CDTestFramework/Opcode/Ice/_IceContainer.cpp | 361 + Extras/CDTestFramework/Opcode/Ice/_IceContainer.h | 228 + Extras/CDTestFramework/Opcode/Ice/_IceFPU.h | 333 + .../CDTestFramework/Opcode/Ice/_IceMemoryMacros.h | 121 + .../CDTestFramework/Opcode/Ice/_IcePreprocessor.h | 144 + .../Opcode/Ice/_IceRevisitedRadix.cpp | 536 + .../Opcode/Ice/_IceRevisitedRadix.h | 81 + Extras/CDTestFramework/Opcode/Ice/_IceTypes.h | 173 + Extras/CDTestFramework/Opcode/Ice/_IceUtils.h | 272 + Extras/CDTestFramework/Opcode/OPC_AABBCollider.cpp | 705 + Extras/CDTestFramework/Opcode/OPC_AABBCollider.h | 106 + Extras/CDTestFramework/Opcode/OPC_AABBTree.cpp | 582 + Extras/CDTestFramework/Opcode/OPC_AABBTree.h | 146 + Extras/CDTestFramework/Opcode/OPC_ArraySAP.cpp | 1228 + Extras/CDTestFramework/Opcode/OPC_ArraySAP.h | 159 + Extras/CDTestFramework/Opcode/OPC_BaseModel.cpp | 147 + Extras/CDTestFramework/Opcode/OPC_BaseModel.h | 184 + Extras/CDTestFramework/Opcode/OPC_BoxBoxOverlap.h | 139 + Extras/CDTestFramework/Opcode/OPC_BoxPruning.cpp | 376 + Extras/CDTestFramework/Opcode/OPC_BoxPruning.h | 40 + Extras/CDTestFramework/Opcode/OPC_Collider.cpp | 63 + Extras/CDTestFramework/Opcode/OPC_Collider.h | 185 + Extras/CDTestFramework/Opcode/OPC_Common.cpp | 57 + Extras/CDTestFramework/Opcode/OPC_Common.h | 110 + Extras/CDTestFramework/Opcode/OPC_HybridModel.cpp | 475 + Extras/CDTestFramework/Opcode/OPC_HybridModel.h | 115 + Extras/CDTestFramework/Opcode/OPC_IceHook.h | 92 + Extras/CDTestFramework/Opcode/OPC_LSSAABBOverlap.h | 539 + Extras/CDTestFramework/Opcode/OPC_LSSCollider.cpp | 734 + Extras/CDTestFramework/Opcode/OPC_LSSCollider.h | 108 + Extras/CDTestFramework/Opcode/OPC_LSSTriOverlap.h | 696 + .../CDTestFramework/Opcode/OPC_MeshInterface.cpp | 308 + Extras/CDTestFramework/Opcode/OPC_MeshInterface.h | 191 + Extras/CDTestFramework/Opcode/OPC_Model.cpp | 231 + Extras/CDTestFramework/Opcode/OPC_Model.h | 74 + Extras/CDTestFramework/Opcode/OPC_OBBCollider.cpp | 776 + Extras/CDTestFramework/Opcode/OPC_OBBCollider.h | 151 + .../CDTestFramework/Opcode/OPC_OptimizedTree.cpp | 791 + Extras/CDTestFramework/Opcode/OPC_OptimizedTree.h | 215 + Extras/CDTestFramework/Opcode/OPC_Picking.cpp | 191 + Extras/CDTestFramework/Opcode/OPC_Picking.h | 54 + .../CDTestFramework/Opcode/OPC_PlanesAABBOverlap.h | 67 + .../CDTestFramework/Opcode/OPC_PlanesCollider.cpp | 662 + Extras/CDTestFramework/Opcode/OPC_PlanesCollider.h | 130 + .../CDTestFramework/Opcode/OPC_PlanesTriOverlap.h | 57 + Extras/CDTestFramework/Opcode/OPC_RayAABBOverlap.h | 81 + Extras/CDTestFramework/Opcode/OPC_RayCollider.cpp | 771 + Extras/CDTestFramework/Opcode/OPC_RayCollider.h | 234 + Extras/CDTestFramework/Opcode/OPC_RayTriOverlap.h | 106 + Extras/CDTestFramework/Opcode/OPC_Settings.h | 58 + .../CDTestFramework/Opcode/OPC_SphereAABBOverlap.h | 145 + .../CDTestFramework/Opcode/OPC_SphereCollider.cpp | 735 + Extras/CDTestFramework/Opcode/OPC_SphereCollider.h | 105 + .../CDTestFramework/Opcode/OPC_SphereTriOverlap.h | 203 + .../CDTestFramework/Opcode/OPC_SweepAndPrune.cpp | 673 + Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.h | 95 + Extras/CDTestFramework/Opcode/OPC_TreeBuilders.cpp | 264 + Extras/CDTestFramework/Opcode/OPC_TreeBuilders.h | 182 + Extras/CDTestFramework/Opcode/OPC_TreeCollider.cpp | 952 + Extras/CDTestFramework/Opcode/OPC_TreeCollider.h | 253 + Extras/CDTestFramework/Opcode/OPC_TriBoxOverlap.h | 356 + Extras/CDTestFramework/Opcode/OPC_TriTriOverlap.h | 295 + .../CDTestFramework/Opcode/OPC_VolumeCollider.cpp | 112 + Extras/CDTestFramework/Opcode/OPC_VolumeCollider.h | 147 + Extras/CDTestFramework/Opcode/Opcode.cpp | 74 + Extras/CDTestFramework/Opcode/Opcode.dsp | 517 + Extras/CDTestFramework/Opcode/Opcode.dsw | 29 + Extras/CDTestFramework/Opcode/Opcode.h | 99 + Extras/CDTestFramework/Opcode/Opcode.sln | 21 + Extras/CDTestFramework/Opcode/Opcode.vcproj | 1416 + Extras/CDTestFramework/Opcode/ReadMe.txt | 188 + Extras/CDTestFramework/Opcode/StdAfx.cpp | 19 + Extras/CDTestFramework/Opcode/StdAfx.h | 33 + Extras/CDTestFramework/OpcodeArraySAPTest.cpp | 215 + Extras/CDTestFramework/OpcodeArraySAPTest.h | 52 + Extras/CDTestFramework/Profiling.h | 102 + Extras/CDTestFramework/ReadMe.txt | 22 + Extras/CDTestFramework/RenderingHelpers.cpp | 1164 + Extras/CDTestFramework/RenderingHelpers.h | 26 + Extras/CDTestFramework/SphereMeshQuery.cpp | 141 + Extras/CDTestFramework/SphereMeshQuery.h | 48 + Extras/CDTestFramework/Terrain.cpp | 470 + Extras/CDTestFramework/Terrain.h | 47 + Extras/CDTestFramework/convex1.bin | Bin 0 -> 2924 bytes Extras/CDTestFramework/stdafx.cpp | 23 + Extras/CDTestFramework/stdafx.h | 23 + Extras/CMakeLists.txt | 7 + Extras/CUDA/btCudaBroadphase.cpp | 207 + Extras/CUDA/btCudaBroadphase.cu | 74 + Extras/CUDA/btCudaBroadphase.h | 69 + Extras/CUDA/btCudaDefines.h | 138 + Extras/CUDA/btCudaUtils.cu | 84 + Extras/CUDA/btGpuDemo2dCudaFunc.cu | 42 + Extras/CUDA/btGpuDemo3dCudaFunc.cu | 46 + Extras/CUDA/cutil_gl_error.h | 86 + Extras/CUDA/cutil_math.h | 767 + Extras/CUDA/libbulletcuda.vcproj | 665 + Extras/CUDA/radixsort.cu | 79 + Extras/CUDA/radixsort.cuh | 63 + Extras/CUDA/radixsort_kernel.cu | 577 + Extras/ConvexDecomposition/CMakeLists.txt | 64 + Extras/ConvexDecomposition/ConvexBuilder.cpp | 373 + Extras/ConvexDecomposition/ConvexBuilder.h | 112 + Extras/ConvexDecomposition/ConvexDecomposition.cpp | 375 + Extras/ConvexDecomposition/ConvexDecomposition.h | 220 + Extras/ConvexDecomposition/bestfit.cpp | 466 + Extras/ConvexDecomposition/bestfit.h | 65 + Extras/ConvexDecomposition/bestfitobb.cpp | 173 + Extras/ConvexDecomposition/bestfitobb.h | 43 + Extras/ConvexDecomposition/cd_hull.cpp | 3261 + Extras/ConvexDecomposition/cd_hull.h | 153 + Extras/ConvexDecomposition/cd_vector.h | 1185 + Extras/ConvexDecomposition/cd_wavefront.cpp | 860 + Extras/ConvexDecomposition/cd_wavefront.h | 62 + Extras/ConvexDecomposition/concavity.cpp | 795 + Extras/ConvexDecomposition/concavity.h | 60 + Extras/ConvexDecomposition/fitsphere.cpp | 202 + Extras/ConvexDecomposition/fitsphere.h | 43 + Extras/ConvexDecomposition/float_math.cpp | 257 + Extras/ConvexDecomposition/float_math.h | 72 + Extras/ConvexDecomposition/meshvolume.cpp | 128 + Extras/ConvexDecomposition/meshvolume.h | 45 + Extras/ConvexDecomposition/planetri.cpp | 238 + Extras/ConvexDecomposition/planetri.h | 58 + Extras/ConvexDecomposition/premake4.lua | 9 + Extras/ConvexDecomposition/raytri.cpp | 134 + Extras/ConvexDecomposition/raytri.h | 45 + Extras/ConvexDecomposition/splitplane.cpp | 306 + Extras/ConvexDecomposition/splitplane.h | 59 + Extras/ConvexDecomposition/vlookup.cpp | 326 + Extras/ConvexDecomposition/vlookup.h | 119 + Extras/GIMPACTUtils/CMakeLists.txt | 37 + .../btGImpactConvexDecompositionShape.cpp | 240 + .../btGImpactConvexDecompositionShape.h | 87 + Extras/HACD/CMakeLists.txt | 51 + Extras/HACD/hacdCircularList.h | 80 + Extras/HACD/hacdCircularList.inl | 163 + Extras/HACD/hacdGraph.cpp | 292 + Extras/HACD/hacdGraph.h | 120 + Extras/HACD/hacdHACD.cpp | 847 + Extras/HACD/hacdHACD.h | 282 + Extras/HACD/hacdICHull.cpp | 1010 + Extras/HACD/hacdICHull.h | 120 + Extras/HACD/hacdManifoldMesh.cpp | 577 + Extras/HACD/hacdManifoldMesh.h | 250 + Extras/HACD/hacdVector.h | 67 + Extras/HACD/hacdVector.inl | 178 + Extras/HACD/hacdVersion.h | 20 + Extras/HACD/premake4.lua | 9 + Extras/Makefile.am | 95 + Extras/Makefile.in | 1406 + Extras/Serialize/BlenderSerialize/CMakeLists.txt | 7 + Extras/Serialize/BlenderSerialize/bBlenderFile.cpp | 225 + Extras/Serialize/BlenderSerialize/bBlenderFile.h | 63 + Extras/Serialize/BlenderSerialize/bMain.cpp | 392 + Extras/Serialize/BlenderSerialize/bMain.h | 110 + Extras/Serialize/BlenderSerialize/dna249-64bit.cpp | 1411 + Extras/Serialize/BlenderSerialize/dna249.cpp | 1411 + Extras/Serialize/BulletFileLoader/CMakeLists.txt | 49 + .../BulletFileLoader/autogenerated/bullet.h | 1051 + Extras/Serialize/BulletFileLoader/bChunk.cpp | 75 + Extras/Serialize/BulletFileLoader/bChunk.h | 92 + Extras/Serialize/BulletFileLoader/bCommon.h | 39 + Extras/Serialize/BulletFileLoader/bDNA.cpp | 635 + Extras/Serialize/BulletFileLoader/bDNA.h | 110 + Extras/Serialize/BulletFileLoader/bDefines.h | 140 + Extras/Serialize/BulletFileLoader/bFile.cpp | 1429 + Extras/Serialize/BulletFileLoader/bFile.h | 164 + Extras/Serialize/BulletFileLoader/btBulletFile.cpp | 406 + Extras/Serialize/BulletFileLoader/btBulletFile.h | 83 + Extras/Serialize/BulletFileLoader/premake4.lua | 12 + .../Serialize/BulletWorldImporter/CMakeLists.txt | 40 + .../BulletWorldImporter/btBulletWorldImporter.cpp | 326 + .../BulletWorldImporter/btBulletWorldImporter.h | 66 + .../BulletWorldImporter/btWorldImporter.cpp | 1422 + .../BulletWorldImporter/btWorldImporter.h | 201 + Extras/Serialize/BulletWorldImporter/premake4.lua | 13 + .../BulletXmlWorldImporter/CMakeLists.txt | 47 + .../btBulletXmlWorldImporter.cpp | 870 + .../btBulletXmlWorldImporter.h | 82 + .../Serialize/BulletXmlWorldImporter/premake4.lua | 14 + .../BulletXmlWorldImporter/string_split.cpp | 250 + .../BulletXmlWorldImporter/string_split.h | 49 + .../Serialize/BulletXmlWorldImporter/tinystr.cpp | 111 + Extras/Serialize/BulletXmlWorldImporter/tinystr.h | 305 + .../Serialize/BulletXmlWorldImporter/tinyxml.cpp | 1886 + Extras/Serialize/BulletXmlWorldImporter/tinyxml.h | 1805 + .../BulletXmlWorldImporter/tinyxmlerror.cpp | 52 + .../BulletXmlWorldImporter/tinyxmlparser.cpp | 1638 + Extras/Serialize/CMakeLists.txt | 20 + Extras/Serialize/HeaderGenerator/CMakeLists.txt | 32 + Extras/Serialize/HeaderGenerator/apiGen.cpp | 464 + .../Serialize/HeaderGenerator/blenderGenerate.py | 111 + Extras/Serialize/HeaderGenerator/bulletGenerate.py | 83 + .../Serialize/HeaderGenerator/createDnaString.bat | 7 + .../ReadBulletSample/BulletDataExtractor.cpp | 345 + .../ReadBulletSample/BulletDataExtractor.h | 32 + Extras/Serialize/ReadBulletSample/CMakeLists.txt | 33 + Extras/Serialize/ReadBulletSample/main.cpp | 63 + Extras/Serialize/makesdna/CMakeLists.txt | 37 + Extras/Serialize/makesdna/DNA_rigidbody.h | 29 + Extras/Serialize/makesdna/makesdna.cpp | 1251 + Extras/glui/CMakeLists.txt | 66 + Extras/glui/GL/glui.h | 2723 + Extras/glui/algebra3.cpp | 1609 + Extras/glui/algebra3.h | 475 + Extras/glui/arcball.cpp | 237 + Extras/glui/arcball.h | 97 + Extras/glui/glui.cpp | 2171 + Extras/glui/glui_add_controls.cpp | 319 + Extras/glui/glui_bitmap_img_data.cpp | 138 + Extras/glui/glui_bitmaps.cpp | 176 + Extras/glui/glui_button.cpp | 186 + Extras/glui/glui_checkbox.cpp | 188 + Extras/glui/glui_column.cpp | 89 + Extras/glui/glui_commandline.cpp | 197 + Extras/glui/glui_control.cpp | 1203 + Extras/glui/glui_edittext.cpp | 1198 + Extras/glui/glui_filebrowser.cpp | 165 + Extras/glui/glui_internal.h | 107 + Extras/glui/glui_internal_control.h | 45 + Extras/glui/glui_list.cpp | 542 + Extras/glui/glui_listbox.cpp | 448 + Extras/glui/glui_mouse_iaction.cpp | 210 + Extras/glui/glui_node.cpp | 212 + Extras/glui/glui_panel.cpp | 186 + Extras/glui/glui_radio.cpp | 362 + Extras/glui/glui_rollout.cpp | 275 + Extras/glui/glui_rotation.cpp | 473 + Extras/glui/glui_scrollbar.cpp | 832 + Extras/glui/glui_separator.cpp | 75 + Extras/glui/glui_spinner.cpp | 630 + Extras/glui/glui_statictext.cpp | 105 + Extras/glui/glui_string.cpp | 62 + Extras/glui/glui_textbox.cpp | 1108 + Extras/glui/glui_translation.cpp | 559 + Extras/glui/glui_tree.cpp | 278 + Extras/glui/glui_treepanel.cpp | 388 + Extras/glui/glui_window.cpp | 44 + Extras/glui/quaternion.cpp | 243 + Extras/glui/quaternion.h | 114 + Extras/glui/readme.txt | 228 + Extras/khx2dae/Bullet_dae_screenshot.jpg | Bin 0 -> 18301 bytes Extras/khx2dae/Havok5.5toColladaPhysics.dae | 480 + Extras/khx2dae/Havok_hkx_screenshot.jpg | Bin 0 -> 16013 bytes Extras/khx2dae/SimpleLoadDemo.patch | 428 + Extras/khx2dae/readme.txt | 6 + Extras/premake4.lua | 8 + Extras/sph/READ_ME.txt | 35 + Extras/sph/cmp.sh | 5 + Extras/sph/common/GLee.c | 18170 ++++ Extras/sph/common/GLee.h | 17647 ++++ Extras/sph/common/common_defs.h | 52 + Extras/sph/common/geomx.cpp | 443 + Extras/sph/common/geomx.h | 125 + Extras/sph/common/gl_helper.cpp | 402 + Extras/sph/common/gl_helper.h | 89 + Extras/sph/common/glext.h | 7139 ++ Extras/sph/common/glut.h | 791 + Extras/sph/common/image.cpp | 1948 + Extras/sph/common/image.h | 188 + Extras/sph/common/matrix-inline.h | 1879 + Extras/sph/common/matrix.cci | 2046 + Extras/sph/common/matrix.cpp | 23 + Extras/sph/common/matrix.h | 429 + Extras/sph/common/mdebug.cpp | 583 + Extras/sph/common/mdebug.h | 138 + Extras/sph/common/mesh.cpp | 955 + Extras/sph/common/mesh.h | 160 + Extras/sph/common/mesh_info.h | 97 + Extras/sph/common/mtime.cpp | 612 + Extras/sph/common/mtime.h | 234 + Extras/sph/common/particle.cpp | 23 + Extras/sph/common/particle.h | 29 + Extras/sph/common/point_set.cpp | 539 + Extras/sph/common/point_set.h | 165 + Extras/sph/common/vector-inline.h | 782 + Extras/sph/common/vector.cci | 761 + Extras/sph/common/vector.cpp | 70 + Extras/sph/common/vector.h | 785 + Extras/sph/fluid_system_host.linkinfo | 1 + Extras/sph/fluids.vcproj | 306 + Extras/sph/fluids/fluid.cpp | 22 + Extras/sph/fluids/fluid.h | 44 + Extras/sph/fluids/fluid_system.cpp | 869 + Extras/sph/fluids/fluid_system.cu | 71 + Extras/sph/fluids/fluid_system.h | 106 + Extras/sph/fluids/fluid_system_host.cu | 250 + Extras/sph/fluids/fluid_system_host.cuh | 63 + Extras/sph/fluids/fluid_system_kern.cu | 402 + Extras/sph/fluids/fluid_system_kern.cuh | 45 + Extras/sph/fluids/radixsort.cu | 79 + Extras/sph/fluids/radixsort.cuh | 63 + Extras/sph/fluids/radixsort_kernel.cu | 577 + Extras/sph/fluids_2005.sln | 23 + Extras/sph/fluids_2005.vcproj | 447 + Extras/sph/main.cpp | 594 + GLUT32.DLL | Bin 0 -> 160256 bytes Glut/EmptyGL/GL/egl_cpx.h | 13 + Glut/EmptyGL/GL/egl_defs.h | 706 + Glut/EmptyGL/GL/egl_logged.h | 20 + Glut/EmptyGL/GL/egl_tokens.h | 459 + Glut/EmptyGL/GL/egl_void.h | 422 + Glut/EmptyGL/GL/gl.h | 47 + Glut/EmptyGL/GL/glu.h | 23 + Glut/EmptyGL/GL/glut.h | 60 + Glut/GL/glew.h | 15507 ++++ Glut/GL/glext.h | 3326 + Glut/GL/glut.h | 607 + Glut/GL/glxew.h | 1587 + Glut/GL/glxext.h | 546 + Glut/GL/wglew.h | 1363 + Glut/GL/wglext.h | 466 + Glut/btGlutInclude.h | 43 + Glut/glew32s.lib | Bin 0 -> 1288450 bytes Glut/glew64s.lib | Bin 0 -> 1378464 bytes Glut/glut32.lib | Bin 0 -> 29180 bytes Glut/glut64.lib | Bin 0 -> 26180 bytes INSTALL | 111 + Makefile.am | 7 + Makefile.in | 776 + NEWS | 5 + README | 6 + RELEASING.TXT | 34 + Test/Info.plist | 47 + Test/README.txt | 28 + Test/Source/TestList.cpp | 97 + Test/Source/TestList.h | 28 + Test/Source/Tests/Test_3x3getRot.cpp | 158 + Test/Source/Tests/Test_3x3getRot.h | 22 + Test/Source/Tests/Test_3x3mulM.cpp | 169 + Test/Source/Tests/Test_3x3mulM.h | 22 + Test/Source/Tests/Test_3x3mulM1M2.cpp | 164 + Test/Source/Tests/Test_3x3mulM1M2.h | 22 + Test/Source/Tests/Test_3x3mulMV.cpp | 112 + Test/Source/Tests/Test_3x3mulMV.h | 23 + Test/Source/Tests/Test_3x3mulVM.cpp | 112 + Test/Source/Tests/Test_3x3mulVM.h | 22 + Test/Source/Tests/Test_3x3setRot.cpp | 171 + Test/Source/Tests/Test_3x3setRot.h | 22 + Test/Source/Tests/Test_3x3timesTranspose.cpp | 117 + Test/Source/Tests/Test_3x3timesTranspose.h | 22 + Test/Source/Tests/Test_3x3transpose.cpp | 116 + Test/Source/Tests/Test_3x3transpose.h | 22 + Test/Source/Tests/Test_3x3transposeTimes.cpp | 168 + Test/Source/Tests/Test_3x3transposeTimes.h | 22 + Test/Source/Tests/Test_btDbvt.cpp | 495 + Test/Source/Tests/Test_btDbvt.h | 21 + Test/Source/Tests/Test_dot3.cpp | 153 + Test/Source/Tests/Test_dot3.h | 22 + Test/Source/Tests/Test_maxdot.cpp | 281 + Test/Source/Tests/Test_maxdot.h | 22 + Test/Source/Tests/Test_mindot.cpp | 269 + Test/Source/Tests/Test_mindot.h | 22 + Test/Source/Tests/Test_qtdot.cpp | 162 + Test/Source/Tests/Test_qtdot.h | 22 + Test/Source/Tests/Test_qtmul.cpp | 183 + Test/Source/Tests/Test_qtmul.h | 22 + Test/Source/Tests/Test_qtmulQV3.cpp | 162 + Test/Source/Tests/Test_qtmulQV3.h | 22 + Test/Source/Tests/Test_qtmulV3Q.cpp | 161 + Test/Source/Tests/Test_qtmulV3Q.h | 22 + Test/Source/Tests/Test_qtnorm.cpp | 176 + Test/Source/Tests/Test_qtnorm.h | 22 + Test/Source/Tests/Test_quat_aos_neon.cpp | 599 + Test/Source/Tests/Test_quat_aos_neon.h | 21 + Test/Source/Tests/Test_v3cross.cpp | 181 + Test/Source/Tests/Test_v3cross.h | 22 + Test/Source/Tests/Test_v3div.cpp | 178 + Test/Source/Tests/Test_v3div.h | 22 + Test/Source/Tests/Test_v3dot.cpp | 164 + Test/Source/Tests/Test_v3dot.h | 22 + Test/Source/Tests/Test_v3interp.cpp | 195 + Test/Source/Tests/Test_v3interp.h | 22 + Test/Source/Tests/Test_v3lerp.cpp | 198 + Test/Source/Tests/Test_v3lerp.h | 22 + Test/Source/Tests/Test_v3norm.cpp | 170 + Test/Source/Tests/Test_v3norm.h | 22 + Test/Source/Tests/Test_v3rotate.cpp | 194 + Test/Source/Tests/Test_v3rotate.h | 22 + Test/Source/Tests/Test_v3sdiv.cpp | 181 + Test/Source/Tests/Test_v3sdiv.h | 22 + Test/Source/Tests/Test_v3skew.cpp | 197 + Test/Source/Tests/Test_v3skew.h | 22 + Test/Source/Tests/Test_v3triple.cpp | 180 + Test/Source/Tests/Test_v3triple.h | 22 + Test/Source/Utils.cpp | 272 + Test/Source/Utils.h | 72 + Test/Source/btIntDefines.h | 19 + Test/Source/main.cpp | 326 + Test/Source/main.h | 25 + Test/Source/vector.h | 70 + Test/premake4.lua | 23 + UnitTests/BulletUnitTests/CMakeLists.txt | 31 + UnitTests/BulletUnitTests/Main.cpp | 47 + UnitTests/BulletUnitTests/TestBulletOnly.h | 119 + .../BulletUnitTests/TestCholeskyDecomposition.cpp | 68 + .../BulletUnitTests/TestCholeskyDecomposition.h | 52 + UnitTests/BulletUnitTests/TestLinearMath.h | 210 + .../BulletUnitTests/TestPolarDecomposition.cpp | 103 + UnitTests/BulletUnitTests/TestPolarDecomposition.h | 88 + .../BulletUnitTests/btCholeskyDecomposition.cpp | 40 + .../BulletUnitTests/btCholeskyDecomposition.h | 19 + UnitTests/CMakeLists.txt | 2 + UnitTests/cppunit/AUTHORS | 6 + UnitTests/cppunit/BUGS | 6 + UnitTests/cppunit/CMakeLists.txt | 74 + UnitTests/cppunit/ChangeLog | 3749 + UnitTests/cppunit/CodingGuideLines.txt | 61 + UnitTests/cppunit/THANKS | 23 + UnitTests/cppunit/TODO | 35 + .../cppunit/include/cppunit/AdditionalMessage.h | 76 + UnitTests/cppunit/include/cppunit/Asserter.h | 143 + .../include/cppunit/BriefTestProgressListener.h | 43 + .../cppunit/include/cppunit/CompilerOutputter.h | 146 + UnitTests/cppunit/include/cppunit/Exception.h | 90 + UnitTests/cppunit/include/cppunit/Message.h | 156 + UnitTests/cppunit/include/cppunit/Outputter.h | 26 + UnitTests/cppunit/include/cppunit/Portability.h | 183 + UnitTests/cppunit/include/cppunit/Protector.h | 94 + UnitTests/cppunit/include/cppunit/SourceLine.h | 63 + .../cppunit/include/cppunit/SynchronizedObject.h | 80 + UnitTests/cppunit/include/cppunit/Test.h | 117 + UnitTests/cppunit/include/cppunit/TestAssert.h | 428 + UnitTests/cppunit/include/cppunit/TestCaller.h | 204 + UnitTests/cppunit/include/cppunit/TestCase.h | 55 + UnitTests/cppunit/include/cppunit/TestComposite.h | 45 + UnitTests/cppunit/include/cppunit/TestFailure.h | 58 + UnitTests/cppunit/include/cppunit/TestFixture.h | 99 + UnitTests/cppunit/include/cppunit/TestLeaf.h | 44 + UnitTests/cppunit/include/cppunit/TestListener.h | 148 + UnitTests/cppunit/include/cppunit/TestPath.h | 211 + UnitTests/cppunit/include/cppunit/TestResult.h | 156 + .../cppunit/include/cppunit/TestResultCollector.h | 87 + UnitTests/cppunit/include/cppunit/TestRunner.h | 135 + .../cppunit/include/cppunit/TestSuccessListener.h | 39 + UnitTests/cppunit/include/cppunit/TestSuite.h | 80 + UnitTests/cppunit/include/cppunit/TextOutputter.h | 59 + .../include/cppunit/TextTestProgressListener.h | 44 + UnitTests/cppunit/include/cppunit/TextTestResult.h | 39 + UnitTests/cppunit/include/cppunit/TextTestRunner.h | 6 + UnitTests/cppunit/include/cppunit/XmlOutputter.h | 167 + .../cppunit/include/cppunit/XmlOutputterHook.h | 163 + UnitTests/cppunit/include/cppunit/config-auto.h | 179 + .../cppunit/include/cppunit/config/CppUnitApi.h | 33 + .../include/cppunit/config/SelectDllLoader.h | 76 + .../cppunit/include/cppunit/config/SourcePrefix.h | 14 + .../cppunit/include/cppunit/config/config-bcb5.h | 47 + .../cppunit/include/cppunit/config/config-evc4.h | 78 + .../cppunit/include/cppunit/config/config-mac.h | 58 + .../cppunit/include/cppunit/config/config-msvc6.h | 86 + .../include/cppunit/extensions/AutoRegisterSuite.h | 83 + .../extensions/ExceptionTestCaseDecorator.h | 104 + .../include/cppunit/extensions/HelperMacros.h | 541 + .../cppunit/include/cppunit/extensions/Orthodox.h | 95 + .../include/cppunit/extensions/RepeatedTest.h | 43 + .../include/cppunit/extensions/TestCaseDecorator.h | 40 + .../include/cppunit/extensions/TestDecorator.h | 49 + .../include/cppunit/extensions/TestFactory.h | 27 + .../cppunit/extensions/TestFactoryRegistry.h | 182 + .../cppunit/extensions/TestFixtureFactory.h | 50 + .../cppunit/include/cppunit/extensions/TestNamer.h | 89 + .../cppunit/include/cppunit/extensions/TestSetUp.h | 34 + .../cppunit/extensions/TestSuiteBuilderContext.h | 131 + .../include/cppunit/extensions/TestSuiteFactory.h | 27 + .../include/cppunit/extensions/TypeInfoHelper.h | 33 + .../include/cppunit/extensions/XmlInputHelper.h | 23 + .../include/cppunit/plugin/DynamicLibraryManager.h | 121 + .../plugin/DynamicLibraryManagerException.h | 53 + .../cppunit/include/cppunit/plugin/PlugInManager.h | 113 + .../include/cppunit/plugin/PlugInParameters.h | 36 + .../cppunit/include/cppunit/plugin/TestPlugIn.h | 200 + .../include/cppunit/plugin/TestPlugInDefaultImpl.h | 61 + .../include/cppunit/portability/CppUnitDeque.h | 25 + .../include/cppunit/portability/CppUnitMap.h | 29 + .../include/cppunit/portability/CppUnitSet.h | 28 + .../include/cppunit/portability/CppUnitStack.h | 26 + .../include/cppunit/portability/CppUnitVector.h | 25 + .../include/cppunit/portability/FloatingPoint.h | 54 + .../cppunit/include/cppunit/portability/Stream.h | 347 + .../cppunit/include/cppunit/tools/Algorithm.h | 23 + .../cppunit/include/cppunit/tools/StringTools.h | 34 + .../cppunit/include/cppunit/tools/XmlDocument.h | 86 + .../cppunit/include/cppunit/tools/XmlElement.h | 149 + .../cppunit/include/cppunit/ui/text/TestRunner.h | 24 + .../include/cppunit/ui/text/TextTestRunner.h | 97 + .../cppunit/src/cppunit/AdditionalMessage.cpp | 41 + UnitTests/cppunit/src/cppunit/Asserter.cpp | 101 + .../src/cppunit/BeOsDynamicLibraryManager.cpp | 49 + .../src/cppunit/BriefTestProgressListener.cpp | 49 + .../cppunit/src/cppunit/CompilerOutputter.cpp | 216 + UnitTests/cppunit/src/cppunit/DefaultProtector.cpp | 42 + UnitTests/cppunit/src/cppunit/DefaultProtector.h | 27 + UnitTests/cppunit/src/cppunit/DllMain.cpp | 16 + .../cppunit/src/cppunit/DynamicLibraryManager.cpp | 77 + .../src/cppunit/DynamicLibraryManagerException.cpp | 41 + UnitTests/cppunit/src/cppunit/Exception.cpp | 126 + UnitTests/cppunit/src/cppunit/Message.cpp | 170 + UnitTests/cppunit/src/cppunit/PlugInManager.cpp | 110 + UnitTests/cppunit/src/cppunit/PlugInParameters.cpp | 28 + UnitTests/cppunit/src/cppunit/Protector.cpp | 86 + UnitTests/cppunit/src/cppunit/ProtectorChain.cpp | 86 + UnitTests/cppunit/src/cppunit/ProtectorChain.h | 51 + UnitTests/cppunit/src/cppunit/ProtectorContext.h | 38 + UnitTests/cppunit/src/cppunit/RepeatedTest.cpp | 29 + .../src/cppunit/ShlDynamicLibraryManager.cpp | 53 + UnitTests/cppunit/src/cppunit/SourceLine.cpp | 81 + UnitTests/cppunit/src/cppunit/StringTools.cpp | 80 + .../cppunit/src/cppunit/SynchronizedObject.cpp | 32 + UnitTests/cppunit/src/cppunit/Test.cpp | 97 + UnitTests/cppunit/src/cppunit/TestAssert.cpp | 46 + UnitTests/cppunit/src/cppunit/TestCase.cpp | 137 + .../cppunit/src/cppunit/TestCaseDecorator.cpp | 47 + UnitTests/cppunit/src/cppunit/TestComposite.cpp | 77 + UnitTests/cppunit/src/cppunit/TestDecorator.cpp | 53 + .../cppunit/src/cppunit/TestFactoryRegistry.cpp | 161 + UnitTests/cppunit/src/cppunit/TestFailure.cpp | 71 + UnitTests/cppunit/src/cppunit/TestLeaf.cpp | 28 + UnitTests/cppunit/src/cppunit/TestNamer.cpp | 44 + UnitTests/cppunit/src/cppunit/TestPath.cpp | 254 + .../cppunit/src/cppunit/TestPlugInDefaultImpl.cpp | 63 + UnitTests/cppunit/src/cppunit/TestResult.cpp | 199 + .../cppunit/src/cppunit/TestResultCollector.cpp | 117 + UnitTests/cppunit/src/cppunit/TestRunner.cpp | 101 + UnitTests/cppunit/src/cppunit/TestSetUp.cpp | 32 + .../cppunit/src/cppunit/TestSuccessListener.cpp | 44 + UnitTests/cppunit/src/cppunit/TestSuite.cpp | 64 + .../src/cppunit/TestSuiteBuilderContext.cpp | 85 + UnitTests/cppunit/src/cppunit/TextOutputter.cpp | 140 + .../src/cppunit/TextTestProgressListener.cpp | 45 + UnitTests/cppunit/src/cppunit/TextTestResult.cpp | 50 + UnitTests/cppunit/src/cppunit/TextTestRunner.cpp | 144 + UnitTests/cppunit/src/cppunit/TypeInfoHelper.cpp | 54 + .../src/cppunit/UnixDynamicLibraryManager.cpp | 44 + .../src/cppunit/Win32DynamicLibraryManager.cpp | 73 + UnitTests/cppunit/src/cppunit/XmlDocument.cpp | 106 + UnitTests/cppunit/src/cppunit/XmlElement.cpp | 226 + UnitTests/cppunit/src/cppunit/XmlOutputter.cpp | 205 + UnitTests/cppunit/src/cppunit/XmlOutputterHook.cpp | 44 + VERSION | 1 + acinclude.m4 | 3054 + aclocal.m4 | 9414 +++ autogen.sh | 61 + autom4te.cache/output.0 | 18219 ++++ autom4te.cache/output.1 | 18215 ++++ autom4te.cache/requests | 393 + autom4te.cache/traces.0 | 3415 + autom4te.cache/traces.1 | 638 + build/Info.plist | 42 + build/autoexp_dat.txt | 66 + build/bullet.rc | 29 + build/bullet_ico.ico | Bin 0 -> 21630 bytes build/findDirectX11.lua | 36 + build/findOpenCL.lua | 84 + build/fruitstrap_osx | Bin 0 -> 33360 bytes build/icon.png | Bin 0 -> 3742 bytes build/ios_build.sh | 3 + build/ios_run.sh | 2 + build/premake4.exe | Bin 0 -> 281088 bytes build/premake4.lua | 198 + build/premake4_linux | Bin 0 -> 350460 bytes build/premake4_osx | Bin 0 -> 450200 bytes build/vs2005.bat | 4 + build/vs2008.bat | 10 + build/vs2010.bat | 4 + build/vs2010_dx11.bat | 5 + build/vs2010_opencl.bat | 8 + build/vs_all.bat | 36 + bullet.pc.cmake | 6 + bullet.pc.in | 11 + bullet_logo.png | Bin 0 -> 3380 bytes compile | 143 + config.guess | 1561 + config.h.in | 113 + config.sub | 1686 + configure | 18215 ++++ configure.ac | 172 + convex0.bin | Bin 0 -> 548 bytes depcomp | 630 + docs/BulletQuickstart.pdf | Bin 0 -> 147920 bytes docs/BulletQuickstart.tex | 106 + docs/building.tex | 45 + docs/bullet_logo_2010_9.eps | 1815 + docs/faq.tex | 3 + docs/helloworld.tex | 15 + docs/intro.tex | 36 + docs/titlepic.sty | 68 + file.obj | 3578 + glut64.dll | Bin 0 -> 272896 bytes heightfield128x128.raw | 37 + install-sh | 322 + jenga.dae | 5632 ++ lib/readme.txt | 13 + ltmain.sh | 9636 +++ missing | 376 + src/Bullet-C-Api.h | 176 + .../BroadphaseCollision/btAxisSweep3.cpp | 37 + .../BroadphaseCollision/btAxisSweep3.h | 1051 + .../BroadphaseCollision/btBroadphaseInterface.h | 82 + .../BroadphaseCollision/btBroadphaseProxy.cpp | 17 + .../BroadphaseCollision/btBroadphaseProxy.h | 270 + .../BroadphaseCollision/btCollisionAlgorithm.cpp | 23 + .../BroadphaseCollision/btCollisionAlgorithm.h | 81 + src/BulletCollision/BroadphaseCollision/btDbvt.cpp | 1295 + src/BulletCollision/BroadphaseCollision/btDbvt.h | 1270 + .../BroadphaseCollision/btDbvtBroadphase.cpp | 796 + .../BroadphaseCollision/btDbvtBroadphase.h | 146 + .../BroadphaseCollision/btDispatcher.cpp | 22 + .../BroadphaseCollision/btDispatcher.h | 110 + .../BroadphaseCollision/btMultiSapBroadphase.cpp | 489 + .../BroadphaseCollision/btMultiSapBroadphase.h | 151 + .../BroadphaseCollision/btOverlappingPairCache.cpp | 633 + .../BroadphaseCollision/btOverlappingPairCache.h | 469 + .../btOverlappingPairCallback.h | 40 + .../BroadphaseCollision/btQuantizedBvh.cpp | 1375 + .../BroadphaseCollision/btQuantizedBvh.h | 581 + .../BroadphaseCollision/btSimpleBroadphase.cpp | 349 + .../BroadphaseCollision/btSimpleBroadphase.h | 171 + src/BulletCollision/CMakeLists.txt | 279 + .../CollisionDispatch/SphereTriangleDetector.cpp | 200 + .../CollisionDispatch/SphereTriangleDetector.h | 51 + .../btActivatingCollisionAlgorithm.cpp | 47 + .../btActivatingCollisionAlgorithm.h | 36 + .../btBox2dBox2dCollisionAlgorithm.cpp | 421 + .../btBox2dBox2dCollisionAlgorithm.h | 66 + .../btBoxBoxCollisionAlgorithm.cpp | 84 + .../CollisionDispatch/btBoxBoxCollisionAlgorithm.h | 66 + .../CollisionDispatch/btBoxBoxDetector.cpp | 718 + .../CollisionDispatch/btBoxBoxDetector.h | 44 + .../CollisionDispatch/btCollisionConfiguration.h | 48 + .../CollisionDispatch/btCollisionCreateFunc.h | 45 + .../CollisionDispatch/btCollisionDispatcher.cpp | 314 + .../CollisionDispatch/btCollisionDispatcher.h | 171 + .../CollisionDispatch/btCollisionObject.cpp | 116 + .../CollisionDispatch/btCollisionObject.h | 534 + .../CollisionDispatch/btCollisionObjectWrapper.h | 40 + .../CollisionDispatch/btCollisionWorld.cpp | 1539 + .../CollisionDispatch/btCollisionWorld.h | 522 + .../btCompoundCollisionAlgorithm.cpp | 366 + .../btCompoundCollisionAlgorithm.h | 86 + .../btConvex2dConvex2dAlgorithm.cpp | 247 + .../btConvex2dConvex2dAlgorithm.h | 95 + .../btConvexConcaveCollisionAlgorithm.cpp | 329 + .../btConvexConcaveCollisionAlgorithm.h | 121 + .../CollisionDispatch/btConvexConvexAlgorithm.cpp | 784 + .../CollisionDispatch/btConvexConvexAlgorithm.h | 108 + .../btConvexPlaneCollisionAlgorithm.cpp | 174 + .../btConvexPlaneCollisionAlgorithm.h | 84 + .../btDefaultCollisionConfiguration.cpp | 309 + .../btDefaultCollisionConfiguration.h | 135 + .../btEmptyCollisionAlgorithm.cpp | 34 + .../CollisionDispatch/btEmptyCollisionAlgorithm.h | 54 + .../CollisionDispatch/btGhostObject.cpp | 171 + .../CollisionDispatch/btGhostObject.h | 175 + .../CollisionDispatch/btInternalEdgeUtility.cpp | 842 + .../CollisionDispatch/btInternalEdgeUtility.h | 47 + .../CollisionDispatch/btManifoldResult.cpp | 154 + .../CollisionDispatch/btManifoldResult.h | 150 + .../btSimulationIslandManager.cpp | 450 + .../CollisionDispatch/btSimulationIslandManager.h | 81 + .../btSphereBoxCollisionAlgorithm.cpp | 214 + .../btSphereBoxCollisionAlgorithm.h | 75 + .../btSphereSphereCollisionAlgorithm.cpp | 106 + .../btSphereSphereCollisionAlgorithm.h | 66 + .../btSphereTriangleCollisionAlgorithm.cpp | 84 + .../btSphereTriangleCollisionAlgorithm.h | 69 + .../CollisionDispatch/btUnionFind.cpp | 82 + .../CollisionDispatch/btUnionFind.h | 129 + .../CollisionShapes/btBox2dShape.cpp | 42 + src/BulletCollision/CollisionShapes/btBox2dShape.h | 371 + src/BulletCollision/CollisionShapes/btBoxShape.cpp | 51 + src/BulletCollision/CollisionShapes/btBoxShape.h | 314 + .../CollisionShapes/btBvhTriangleMeshShape.cpp | 466 + .../CollisionShapes/btBvhTriangleMeshShape.h | 139 + .../CollisionShapes/btCapsuleShape.cpp | 171 + .../CollisionShapes/btCapsuleShape.h | 184 + .../CollisionShapes/btCollisionMargin.h | 27 + .../CollisionShapes/btCollisionShape.cpp | 119 + .../CollisionShapes/btCollisionShape.h | 159 + .../CollisionShapes/btCompoundShape.cpp | 354 + .../CollisionShapes/btCompoundShape.h | 212 + .../CollisionShapes/btConcaveShape.cpp | 27 + .../CollisionShapes/btConcaveShape.h | 62 + .../CollisionShapes/btConeShape.cpp | 143 + src/BulletCollision/CollisionShapes/btConeShape.h | 122 + .../CollisionShapes/btConvex2dShape.cpp | 92 + .../CollisionShapes/btConvex2dShape.h | 82 + .../CollisionShapes/btConvexHullShape.cpp | 245 + .../CollisionShapes/btConvexHullShape.h | 122 + .../CollisionShapes/btConvexInternalShape.cpp | 151 + .../CollisionShapes/btConvexInternalShape.h | 224 + .../CollisionShapes/btConvexPointCloudShape.cpp | 139 + .../CollisionShapes/btConvexPointCloudShape.h | 105 + .../CollisionShapes/btConvexPolyhedron.cpp | 302 + .../CollisionShapes/btConvexPolyhedron.h | 65 + .../CollisionShapes/btConvexShape.cpp | 445 + .../CollisionShapes/btConvexShape.h | 84 + .../CollisionShapes/btConvexTriangleMeshShape.cpp | 315 + .../CollisionShapes/btConvexTriangleMeshShape.h | 77 + .../CollisionShapes/btCylinderShape.cpp | 281 + .../CollisionShapes/btCylinderShape.h | 213 + .../CollisionShapes/btEmptyShape.cpp | 50 + src/BulletCollision/CollisionShapes/btEmptyShape.h | 72 + .../CollisionShapes/btHeightfieldTerrainShape.cpp | 410 + .../CollisionShapes/btHeightfieldTerrainShape.h | 167 + src/BulletCollision/CollisionShapes/btMaterial.h | 35 + .../CollisionShapes/btMinkowskiSumShape.cpp | 60 + .../CollisionShapes/btMinkowskiSumShape.h | 62 + .../CollisionShapes/btMultiSphereShape.cpp | 180 + .../CollisionShapes/btMultiSphereShape.h | 101 + .../btMultimaterialTriangleMeshShape.cpp | 45 + .../btMultimaterialTriangleMeshShape.h | 120 + .../CollisionShapes/btOptimizedBvh.cpp | 391 + .../CollisionShapes/btOptimizedBvh.h | 65 + .../CollisionShapes/btPolyhedralConvexShape.cpp | 497 + .../CollisionShapes/btPolyhedralConvexShape.h | 116 + .../btScaledBvhTriangleMeshShape.cpp | 121 + .../CollisionShapes/btScaledBvhTriangleMeshShape.h | 95 + .../CollisionShapes/btShapeHull.cpp | 170 + src/BulletCollision/CollisionShapes/btShapeHull.h | 61 + .../CollisionShapes/btSphereShape.cpp | 71 + .../CollisionShapes/btSphereShape.h | 73 + .../CollisionShapes/btStaticPlaneShape.cpp | 107 + .../CollisionShapes/btStaticPlaneShape.h | 105 + .../CollisionShapes/btStridingMeshInterface.cpp | 381 + .../CollisionShapes/btStridingMeshInterface.h | 164 + .../CollisionShapes/btTetrahedronShape.cpp | 218 + .../CollisionShapes/btTetrahedronShape.h | 76 + .../CollisionShapes/btTriangleBuffer.cpp | 35 + .../CollisionShapes/btTriangleBuffer.h | 69 + .../CollisionShapes/btTriangleCallback.cpp | 28 + .../CollisionShapes/btTriangleCallback.h | 42 + .../CollisionShapes/btTriangleIndexVertexArray.cpp | 95 + .../CollisionShapes/btTriangleIndexVertexArray.h | 133 + .../btTriangleIndexVertexMaterialArray.cpp | 86 + .../btTriangleIndexVertexMaterialArray.h | 84 + .../CollisionShapes/btTriangleInfoMap.h | 241 + .../CollisionShapes/btTriangleMesh.cpp | 162 + .../CollisionShapes/btTriangleMesh.h | 69 + .../CollisionShapes/btTriangleMeshShape.cpp | 207 + .../CollisionShapes/btTriangleMeshShape.h | 90 + .../CollisionShapes/btTriangleShape.h | 184 + .../CollisionShapes/btUniformScalingShape.cpp | 160 + .../CollisionShapes/btUniformScalingShape.h | 89 + src/BulletCollision/Doxyfile | 746 + src/BulletCollision/Gimpact/btBoxCollision.h | 645 + src/BulletCollision/Gimpact/btClipPolygon.h | 182 + .../Gimpact/btContactProcessing.cpp | 181 + src/BulletCollision/Gimpact/btContactProcessing.h | 145 + src/BulletCollision/Gimpact/btGImpactBvh.cpp | 498 + src/BulletCollision/Gimpact/btGImpactBvh.h | 396 + .../Gimpact/btGImpactCollisionAlgorithm.cpp | 880 + .../Gimpact/btGImpactCollisionAlgorithm.h | 306 + src/BulletCollision/Gimpact/btGImpactMassUtil.h | 60 + .../Gimpact/btGImpactQuantizedBvh.cpp | 528 + .../Gimpact/btGImpactQuantizedBvh.h | 372 + src/BulletCollision/Gimpact/btGImpactShape.cpp | 203 + src/BulletCollision/Gimpact/btGImpactShape.h | 1171 + .../Gimpact/btGenericPoolAllocator.cpp | 283 + .../Gimpact/btGenericPoolAllocator.h | 163 + src/BulletCollision/Gimpact/btGeometryOperations.h | 212 + src/BulletCollision/Gimpact/btQuantization.h | 88 + src/BulletCollision/Gimpact/btTriangleShapeEx.cpp | 218 + src/BulletCollision/Gimpact/btTriangleShapeEx.h | 180 + src/BulletCollision/Gimpact/gim_array.h | 324 + .../Gimpact/gim_basic_geometry_operations.h | 543 + src/BulletCollision/Gimpact/gim_bitset.h | 123 + src/BulletCollision/Gimpact/gim_box_collision.h | 588 + src/BulletCollision/Gimpact/gim_box_set.cpp | 182 + src/BulletCollision/Gimpact/gim_box_set.h | 674 + src/BulletCollision/Gimpact/gim_clip_polygon.h | 210 + src/BulletCollision/Gimpact/gim_contact.cpp | 146 + src/BulletCollision/Gimpact/gim_contact.h | 164 + src/BulletCollision/Gimpact/gim_geom_types.h | 97 + src/BulletCollision/Gimpact/gim_geometry.h | 42 + src/BulletCollision/Gimpact/gim_hash_table.h | 902 + src/BulletCollision/Gimpact/gim_linear_math.h | 1573 + src/BulletCollision/Gimpact/gim_math.h | 157 + src/BulletCollision/Gimpact/gim_memory.cpp | 135 + src/BulletCollision/Gimpact/gim_memory.h | 190 + src/BulletCollision/Gimpact/gim_radixsort.h | 406 + src/BulletCollision/Gimpact/gim_tri_collision.cpp | 640 + src/BulletCollision/Gimpact/gim_tri_collision.h | 379 + .../btContinuousConvexCollision.cpp | 242 + .../btContinuousConvexCollision.h | 59 + .../NarrowPhaseCollision/btConvexCast.cpp | 20 + .../NarrowPhaseCollision/btConvexCast.h | 73 + .../btConvexPenetrationDepthSolver.h | 42 + .../btDiscreteCollisionDetectorInterface.h | 91 + .../NarrowPhaseCollision/btGjkConvexCast.cpp | 176 + .../NarrowPhaseCollision/btGjkConvexCast.h | 50 + .../NarrowPhaseCollision/btGjkEpa2.cpp | 1031 + .../NarrowPhaseCollision/btGjkEpa2.h | 75 + .../btGjkEpaPenetrationDepthSolver.cpp | 66 + .../btGjkEpaPenetrationDepthSolver.h | 43 + .../NarrowPhaseCollision/btGjkPairDetector.cpp | 457 + .../NarrowPhaseCollision/btGjkPairDetector.h | 103 + .../NarrowPhaseCollision/btManifoldPoint.h | 156 + .../btMinkowskiPenetrationDepthSolver.cpp | 362 + .../btMinkowskiPenetrationDepthSolver.h | 40 + .../NarrowPhaseCollision/btPersistentManifold.cpp | 305 + .../NarrowPhaseCollision/btPersistentManifold.h | 240 + .../NarrowPhaseCollision/btPointCollector.h | 64 + .../btPolyhedralContactClipping.cpp | 570 + .../btPolyhedralContactClipping.h | 46 + .../NarrowPhaseCollision/btRaycastCallback.cpp | 178 + .../NarrowPhaseCollision/btRaycastCallback.h | 72 + .../btSimplexSolverInterface.h | 63 + .../btSubSimplexConvexCast.cpp | 160 + .../NarrowPhaseCollision/btSubSimplexConvexCast.h | 50 + .../btVoronoiSimplexSolver.cpp | 609 + .../NarrowPhaseCollision/btVoronoiSimplexSolver.h | 181 + src/BulletCollision/premake4.lua | 11 + src/BulletDynamics/CMakeLists.txt | 114 + .../Character/btCharacterControllerInterface.h | 46 + .../Character/btKinematicCharacterController.cpp | 655 + .../Character/btKinematicCharacterController.h | 166 + .../ConstraintSolver/btConeTwistConstraint.cpp | 1135 + .../ConstraintSolver/btConeTwistConstraint.h | 349 + .../ConstraintSolver/btConstraintSolver.h | 52 + .../ConstraintSolver/btContactConstraint.cpp | 178 + .../ConstraintSolver/btContactConstraint.h | 71 + .../ConstraintSolver/btContactSolverInfo.h | 159 + .../ConstraintSolver/btGearConstraint.cpp | 54 + .../ConstraintSolver/btGearConstraint.h | 56 + .../ConstraintSolver/btGeneric6DofConstraint.cpp | 1064 + .../ConstraintSolver/btGeneric6DofConstraint.h | 616 + .../btGeneric6DofSpringConstraint.cpp | 185 + .../btGeneric6DofSpringConstraint.h | 102 + .../ConstraintSolver/btHinge2Constraint.cpp | 66 + .../ConstraintSolver/btHinge2Constraint.h | 60 + .../ConstraintSolver/btHingeConstraint.cpp | 1034 + .../ConstraintSolver/btHingeConstraint.h | 383 + .../ConstraintSolver/btJacobianEntry.h | 155 + .../ConstraintSolver/btPoint2PointConstraint.cpp | 230 + .../ConstraintSolver/btPoint2PointConstraint.h | 163 + .../btSequentialImpulseConstraintSolver.cpp | 1650 + .../btSequentialImpulseConstraintSolver.h | 141 + .../ConstraintSolver/btSliderConstraint.cpp | 857 + .../ConstraintSolver/btSliderConstraint.h | 335 + .../ConstraintSolver/btSolve2LinearConstraint.cpp | 255 + .../ConstraintSolver/btSolve2LinearConstraint.h | 107 + src/BulletDynamics/ConstraintSolver/btSolverBody.h | 293 + .../ConstraintSolver/btSolverConstraint.h | 79 + .../ConstraintSolver/btTypedConstraint.cpp | 222 + .../ConstraintSolver/btTypedConstraint.h | 482 + .../ConstraintSolver/btUniversalConstraint.cpp | 87 + .../ConstraintSolver/btUniversalConstraint.h | 65 + src/BulletDynamics/Dynamics/Bullet-C-API.cpp | 405 + src/BulletDynamics/Dynamics/btActionInterface.h | 46 + .../Dynamics/btDiscreteDynamicsWorld.cpp | 1466 + .../Dynamics/btDiscreteDynamicsWorld.h | 221 + src/BulletDynamics/Dynamics/btDynamicsWorld.h | 166 + src/BulletDynamics/Dynamics/btRigidBody.cpp | 400 + src/BulletDynamics/Dynamics/btRigidBody.h | 600 + .../Dynamics/btSimpleDynamicsWorld.cpp | 280 + .../Dynamics/btSimpleDynamicsWorld.h | 89 + src/BulletDynamics/Vehicle/btRaycastVehicle.cpp | 771 + src/BulletDynamics/Vehicle/btRaycastVehicle.h | 236 + src/BulletDynamics/Vehicle/btVehicleRaycaster.h | 35 + src/BulletDynamics/Vehicle/btWheelInfo.cpp | 56 + src/BulletDynamics/Vehicle/btWheelInfo.h | 119 + src/BulletDynamics/premake4.lua | 11 + src/BulletMultiThreaded/CMakeLists.txt | 123 + .../GpuSoftBodySolvers/CMakeLists.txt | 13 + .../GpuSoftBodySolvers/DX11/CMakeLists.txt | 83 + .../GpuSoftBodySolvers/DX11/HLSL/ApplyForces.hlsl | 95 + .../DX11/HLSL/ComputeBounds.hlsl | 83 + .../GpuSoftBodySolvers/DX11/HLSL/Integrate.hlsl | 41 + .../DX11/HLSL/OutputToVertexArray.hlsl | 63 + .../GpuSoftBodySolvers/DX11/HLSL/PrepareLinks.hlsl | 44 + .../DX11/HLSL/SolvePositions.hlsl | 55 + .../DX11/HLSL/SolvePositionsSIMDBatched.hlsl | 147 + .../DX11/HLSL/UpdateConstants.hlsl | 48 + .../GpuSoftBodySolvers/DX11/HLSL/UpdateNodes.hlsl | 49 + .../DX11/HLSL/UpdateNormals.hlsl | 98 + .../DX11/HLSL/UpdatePositions.hlsl | 44 + .../DX11/HLSL/UpdatePositionsFromVelocities.hlsl | 35 + .../GpuSoftBodySolvers/DX11/HLSL/VSolveLinks.hlsl | 55 + .../HLSL/solveCollisionsAndUpdateVelocities.hlsl | 170 + ...veCollisionsAndUpdateVelocitiesSIMDBatched.hlsl | 191 + .../DX11/btSoftBodySolverBuffer_DX11.h | 323 + .../DX11/btSoftBodySolverLinkData_DX11.h | 103 + .../DX11/btSoftBodySolverLinkData_DX11SIMDAware.h | 173 + .../DX11/btSoftBodySolverTriangleData_DX11.h | 96 + .../DX11/btSoftBodySolverVertexBuffer_DX11.h | 107 + .../DX11/btSoftBodySolverVertexData_DX11.h | 63 + .../DX11/btSoftBodySolver_DX11.cpp | 2236 + .../DX11/btSoftBodySolver_DX11.h | 691 + .../DX11/btSoftBodySolver_DX11SIMDAware.cpp | 1051 + .../DX11/btSoftBodySolver_DX11SIMDAware.h | 81 + .../GpuSoftBodySolvers/DX11/premake4.lua | 23 + .../GpuSoftBodySolvers/OpenCL/AMD/CMakeLists.txt | 62 + .../GpuSoftBodySolvers/OpenCL/AMD/premake4.lua | 27 + .../GpuSoftBodySolvers/OpenCL/Apple/CMakeLists.txt | 77 + .../GpuSoftBodySolvers/OpenCL/CMakeLists.txt | 17 + .../GpuSoftBodySolvers/OpenCL/Intel/CMakeLists.txt | 82 + .../GpuSoftBodySolvers/OpenCL/Intel/premake4.lua | 27 + .../OpenCL/MiniCL/CMakeLists.txt | 75 + .../OpenCL/MiniCL/MiniCLTaskWrap.cpp | 249 + .../OpenCL/NVidia/CMakeLists.txt | 81 + .../GpuSoftBodySolvers/OpenCL/NVidia/premake4.lua | 27 + .../OpenCL/OpenCLC10/ApplyForces.cl | 102 + .../OpenCL/OpenCLC10/ComputeBounds.cl | 82 + .../OpenCL/OpenCLC10/Integrate.cl | 35 + .../OpenCL/OpenCLC10/OutputToVertexArray.cl | 46 + .../OpenCL/OpenCLC10/PrepareLinks.cl | 38 + .../SolveCollisionsAndUpdateVelocities.cl | 204 + ...olveCollisionsAndUpdateVelocitiesSIMDBatched.cl | 242 + .../OpenCL/OpenCLC10/SolvePositions.cl | 57 + .../OpenCL/OpenCLC10/SolvePositionsSIMDBatched.cl | 130 + .../OpenCL/OpenCLC10/UpdateConstants.cl | 44 + .../OpenCL/OpenCLC10/UpdateFixedVertexPositions.cl | 25 + .../OpenCL/OpenCLC10/UpdateNodes.cl | 39 + .../OpenCL/OpenCLC10/UpdateNormals.cl | 102 + .../OpenCL/OpenCLC10/UpdatePositions.cl | 34 + .../OpenCLC10/UpdatePositionsFromVelocities.cl | 28 + .../OpenCL/OpenCLC10/VSolveLinks.cl | 45 + .../OpenCL/btSoftBodySolverBuffer_OpenCL.h | 209 + .../OpenCL/btSoftBodySolverLinkData_OpenCL.h | 99 + .../btSoftBodySolverLinkData_OpenCLSIMDAware.h | 169 + .../OpenCL/btSoftBodySolverOutputCLtoGL.cpp | 126 + .../OpenCL/btSoftBodySolverOutputCLtoGL.h | 62 + .../OpenCL/btSoftBodySolverTriangleData_OpenCL.h | 84 + .../OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h | 166 + .../OpenCL/btSoftBodySolverVertexData_OpenCL.h | 52 + .../OpenCL/btSoftBodySolver_OpenCL.cpp | 1820 + .../OpenCL/btSoftBodySolver_OpenCL.h | 527 + .../OpenCL/btSoftBodySolver_OpenCLSIMDAware.cpp | 1101 + .../OpenCL/btSoftBodySolver_OpenCLSIMDAware.h | 81 + .../Shared/btSoftBodySolverData.h | 748 + src/BulletMultiThreaded/HeapManager.h | 117 + src/BulletMultiThreaded/PlatformDefinitions.h | 99 + src/BulletMultiThreaded/PosixThreadSupport.cpp | 409 + src/BulletMultiThreaded/PosixThreadSupport.h | 147 + src/BulletMultiThreaded/PpuAddressSpace.h | 37 + .../SequentialThreadSupport.cpp | 181 + src/BulletMultiThreaded/SequentialThreadSupport.h | 100 + .../SpuCollisionObjectWrapper.cpp | 48 + .../SpuCollisionObjectWrapper.h | 40 + .../SpuCollisionTaskProcess.cpp | 317 + src/BulletMultiThreaded/SpuCollisionTaskProcess.h | 163 + .../SpuContactManifoldCollisionAlgorithm.cpp | 69 + .../SpuContactManifoldCollisionAlgorithm.h | 121 + src/BulletMultiThreaded/SpuDoubleBuffer.h | 126 + src/BulletMultiThreaded/SpuFakeDma.cpp | 215 + src/BulletMultiThreaded/SpuFakeDma.h | 135 + .../SpuGatheringCollisionDispatcher.cpp | 283 + .../SpuGatheringCollisionDispatcher.h | 72 + src/BulletMultiThreaded/SpuLibspe2Support.cpp | 257 + src/BulletMultiThreaded/SpuLibspe2Support.h | 180 + .../SpuNarrowPhaseCollisionTask/Box.h | 167 + .../SpuCollisionShapes.cpp | 302 + .../SpuCollisionShapes.h | 128 + .../SpuContactResult.cpp | 248 + .../SpuNarrowPhaseCollisionTask/SpuContactResult.h | 106 + .../SpuConvexPenetrationDepthSolver.h | 51 + .../SpuGatheringCollisionTask.cpp | 1432 + .../SpuGatheringCollisionTask.h | 140 + .../SpuNarrowPhaseCollisionTask/SpuLocalSupport.h | 19 + .../SpuMinkowskiPenetrationDepthSolver.cpp | 348 + .../SpuMinkowskiPenetrationDepthSolver.h | 48 + .../SpuPreferredPenetrationDirections.h | 70 + .../SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp | 1160 + .../SpuNarrowPhaseCollisionTask/boxBoxDistance.h | 65 + .../SpuNarrowPhaseCollisionTask/readme.txt | 1 + .../SpuSampleTask/SpuSampleTask.cpp | 214 + .../SpuSampleTask/SpuSampleTask.h | 54 + src/BulletMultiThreaded/SpuSampleTask/readme.txt | 1 + src/BulletMultiThreaded/SpuSampleTaskProcess.cpp | 222 + src/BulletMultiThreaded/SpuSampleTaskProcess.h | 153 + src/BulletMultiThreaded/SpuSync.h | 149 + src/BulletMultiThreaded/TrbDynBody.h | 79 + src/BulletMultiThreaded/TrbStateVec.h | 339 + src/BulletMultiThreaded/Win32ThreadSupport.cpp | 458 + src/BulletMultiThreaded/Win32ThreadSupport.h | 141 + src/BulletMultiThreaded/btGpu3DGridBroadphase.cpp | 590 + src/BulletMultiThreaded/btGpu3DGridBroadphase.h | 140 + .../btGpu3DGridBroadphaseSharedCode.h | 430 + .../btGpu3DGridBroadphaseSharedDefs.h | 61 + .../btGpu3DGridBroadphaseSharedTypes.h | 67 + src/BulletMultiThreaded/btGpuDefines.h | 211 + src/BulletMultiThreaded/btGpuUtilsSharedCode.h | 55 + src/BulletMultiThreaded/btGpuUtilsSharedDefs.h | 52 + .../btParallelConstraintSolver.cpp | 1552 + .../btParallelConstraintSolver.h | 288 + .../btThreadSupportInterface.cpp | 22 + src/BulletMultiThreaded/btThreadSupportInterface.h | 89 + src/BulletMultiThreaded/vectormath2bullet.h | 73 + src/BulletSoftBody/CMakeLists.txt | 65 + src/BulletSoftBody/btDefaultSoftBodySolver.cpp | 151 + src/BulletSoftBody/btDefaultSoftBodySolver.h | 63 + src/BulletSoftBody/btSoftBody.cpp | 3639 + src/BulletSoftBody/btSoftBody.h | 998 + .../btSoftBodyConcaveCollisionAlgorithm.cpp | 357 + .../btSoftBodyConcaveCollisionAlgorithm.h | 155 + src/BulletSoftBody/btSoftBodyData.h | 217 + src/BulletSoftBody/btSoftBodyHelpers.cpp | 1055 + src/BulletSoftBody/btSoftBodyHelpers.h | 143 + src/BulletSoftBody/btSoftBodyInternals.h | 908 + .../btSoftBodyRigidBodyCollisionConfiguration.cpp | 134 + .../btSoftBodyRigidBodyCollisionConfiguration.h | 48 + src/BulletSoftBody/btSoftBodySolverVertexBuffer.h | 165 + src/BulletSoftBody/btSoftBodySolvers.h | 154 + .../btSoftRigidCollisionAlgorithm.cpp | 86 + src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h | 75 + src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp | 367 + src/BulletSoftBody/btSoftRigidDynamicsWorld.h | 107 + .../btSoftSoftCollisionAlgorithm.cpp | 48 + src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h | 69 + src/BulletSoftBody/btSparseSDF.h | 306 + src/BulletSoftBody/premake4.lua | 11 + src/CMakeLists.txt | 32 + src/LinearMath/CMakeLists.txt | 69 + src/LinearMath/btAabbUtil2.h | 232 + src/LinearMath/btAlignedAllocator.cpp | 181 + src/LinearMath/btAlignedAllocator.h | 107 + src/LinearMath/btAlignedObjectArray.h | 511 + src/LinearMath/btConvexHull.cpp | 1167 + src/LinearMath/btConvexHull.h | 241 + src/LinearMath/btConvexHullComputer.cpp | 2751 + src/LinearMath/btConvexHullComputer.h | 103 + src/LinearMath/btDefaultMotionState.h | 42 + src/LinearMath/btGeometryUtil.cpp | 185 + src/LinearMath/btGeometryUtil.h | 42 + src/LinearMath/btGrahamScan2dConvexHull.h | 117 + src/LinearMath/btHashMap.h | 450 + src/LinearMath/btIDebugDraw.h | 419 + src/LinearMath/btList.h | 73 + src/LinearMath/btMatrix3x3.h | 1362 + src/LinearMath/btMinMax.h | 71 + src/LinearMath/btMotionState.h | 40 + src/LinearMath/btPolarDecomposition.cpp | 99 + src/LinearMath/btPolarDecomposition.h | 73 + src/LinearMath/btPoolAllocator.h | 121 + src/LinearMath/btQuadWord.h | 244 + src/LinearMath/btQuaternion.h | 877 + src/LinearMath/btQuickprof.cpp | 566 + src/LinearMath/btQuickprof.h | 203 + src/LinearMath/btRandom.h | 42 + src/LinearMath/btScalar.h | 661 + src/LinearMath/btSerializer.cpp | 908 + src/LinearMath/btSerializer.h | 640 + src/LinearMath/btStackAlloc.h | 116 + src/LinearMath/btTransform.h | 305 + src/LinearMath/btTransformUtil.h | 228 + src/LinearMath/btVector3.cpp | 1631 + src/LinearMath/btVector3.h | 1343 + src/LinearMath/premake4.lua | 11 + src/Makefile.am | 563 + src/Makefile.in | 2603 + src/MiniCL/CMakeLists.txt | 66 + src/MiniCL/MiniCL.cpp | 788 + src/MiniCL/MiniCLTask/MiniCLTask.cpp | 74 + src/MiniCL/MiniCLTask/MiniCLTask.h | 62 + src/MiniCL/MiniCLTaskScheduler.cpp | 519 + src/MiniCL/MiniCLTaskScheduler.h | 194 + src/MiniCL/cl.h | 867 + src/MiniCL/cl_MiniCL_Defs.h | 439 + src/MiniCL/cl_gl.h | 113 + src/MiniCL/cl_platform.h | 254 + src/btBulletCollisionCommon.h | 68 + src/btBulletDynamicsCommon.h | 49 + src/vectormath/neon/boolInVec.h | 226 + src/vectormath/neon/floatInVec.h | 344 + src/vectormath/neon/mat_aos.h | 1631 + src/vectormath/neon/quat_aos.h | 413 + src/vectormath/neon/vec_aos.h | 1427 + src/vectormath/neon/vectormath_aos.h | 1890 + src/vectormath/scalar/boolInVec.h | 225 + src/vectormath/scalar/floatInVec.h | 343 + src/vectormath/scalar/mat_aos.h | 1630 + src/vectormath/scalar/quat_aos.h | 433 + src/vectormath/scalar/vec_aos.h | 1426 + src/vectormath/scalar/vectormath_aos.h | 1872 + src/vectormath/sse/boolInVec.h | 247 + src/vectormath/sse/floatInVec.h | 340 + src/vectormath/sse/mat_aos.h | 2190 + src/vectormath/sse/quat_aos.h | 579 + src/vectormath/sse/vec_aos.h | 1455 + src/vectormath/sse/vecidx_aos.h | 80 + src/vectormath/sse/vectormath_aos.h | 2547 + src/vectormath/vmInclude.h | 31 + test1.oec | 227 + 1710 files changed, 822623 insertions(+) create mode 100644 AUTHORS create mode 100644 BspDemo.bsp create mode 100644 BulletLicense.txt create mode 100644 Bullet_User_Manual.pdf create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Demos/AllBulletDemos/CMakeLists.txt create mode 100644 Demos/AllBulletDemos/DemoEntries.cpp create mode 100644 Demos/AllBulletDemos/DemoEntries.h create mode 100644 Demos/AllBulletDemos/Main.cpp create mode 100644 Demos/AllBulletDemos/Makefile.am create mode 100644 Demos/AllBulletDemos/Makefile.in create mode 100644 Demos/BasicDemo/BasicDemo.cpp create mode 100644 Demos/BasicDemo/BasicDemo.h create mode 100644 Demos/BasicDemo/CMakeLists.txt create mode 100644 Demos/BasicDemo/Makefile.am create mode 100644 Demos/BasicDemo/Makefile.in create mode 100644 Demos/BasicDemo/Win32BasicDemo.cpp create mode 100644 Demos/BasicDemo/main.cpp create mode 100644 Demos/Benchmarks/BenchmarkDemo.cpp create mode 100644 Demos/Benchmarks/BenchmarkDemo.h create mode 100644 Demos/Benchmarks/CMakeLists.txt create mode 100644 Demos/Benchmarks/Taru.mdl create mode 100644 Demos/Benchmarks/Win32BenchmarkDemo.cpp create mode 100644 Demos/Benchmarks/landscape.mdl create mode 100644 Demos/Benchmarks/main.cpp create mode 100644 Demos/Benchmarks/premake4.lua create mode 100644 Demos/Box2dDemo/Box2dDemo.cpp create mode 100644 Demos/Box2dDemo/Box2dDemo.h create mode 100644 Demos/Box2dDemo/CMakeLists.txt create mode 100644 Demos/Box2dDemo/Win32Box2dDemo.cpp create mode 100644 Demos/Box2dDemo/main.cpp create mode 100644 Demos/BspDemo/BspConverter.cpp create mode 100644 Demos/BspDemo/BspConverter.h create mode 100644 Demos/BspDemo/BspDemo.cpp create mode 100644 Demos/BspDemo/BspDemo.h create mode 100644 Demos/BspDemo/BspLoader.cpp create mode 100644 Demos/BspDemo/BspLoader.h create mode 100644 Demos/BspDemo/CMakeLists.txt create mode 100644 Demos/BspDemo/main.cpp create mode 100644 Demos/BulletDinoDemo/BulletDino.c create mode 100644 Demos/BulletDinoDemo/CMakeLists.txt create mode 100644 Demos/BulletXmlImportDemo/BulletXmlImportDemo.cpp create mode 100644 Demos/BulletXmlImportDemo/BulletXmlImportDemo.h create mode 100644 Demos/BulletXmlImportDemo/CMakeLists.txt create mode 100644 Demos/BulletXmlImportDemo/Win32BulletXmlImportDemo.cpp create mode 100644 Demos/BulletXmlImportDemo/bullet_basic.xml create mode 100644 Demos/BulletXmlImportDemo/bulletser.xml create mode 100644 Demos/BulletXmlImportDemo/main.cpp create mode 100644 Demos/CMakeLists.txt create mode 100644 Demos/CcdPhysicsDemo/CMakeLists.txt create mode 100644 Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp create mode 100644 Demos/CcdPhysicsDemo/CcdPhysicsDemo.h create mode 100644 Demos/CcdPhysicsDemo/Makefile.am create mode 100644 Demos/CcdPhysicsDemo/Makefile.in create mode 100644 Demos/CcdPhysicsDemo/main.cpp create mode 100644 Demos/CellSpuDemo/BasicDemo2.cpp create mode 100644 Demos/CellSpuDemo/BasicDemo2.h create mode 100644 Demos/CharacterDemo/CMakeLists.txt create mode 100644 Demos/CharacterDemo/CharacterDemo.cpp create mode 100644 Demos/CharacterDemo/CharacterDemo.h create mode 100644 Demos/CharacterDemo/DynamicCharacterController.cpp create mode 100644 Demos/CharacterDemo/DynamicCharacterController.h create mode 100644 Demos/CharacterDemo/main.cpp create mode 100644 Demos/CollisionDemo/CMakeLists.txt create mode 100644 Demos/CollisionDemo/CollisionDemo.cpp create mode 100644 Demos/CollisionDemo/CollisionDemo.h create mode 100644 Demos/CollisionInterfaceDemo/CMakeLists.txt create mode 100644 Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp create mode 100644 Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h create mode 100644 Demos/CollisionInterfaceDemo/Win32CollisionInterfaceDemo.cpp create mode 100644 Demos/CollisionInterfaceDemo/main.cpp create mode 100644 Demos/ConcaveConvexcastDemo/CMakeLists.txt create mode 100644 Demos/ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp create mode 100644 Demos/ConcaveConvexcastDemo/ConcaveConvexcastDemo.h create mode 100644 Demos/ConcaveConvexcastDemo/main.cpp create mode 100644 Demos/ConcaveDemo/CMakeLists.txt create mode 100644 Demos/ConcaveDemo/ConcaveDemo.h create mode 100644 Demos/ConcaveDemo/ConcavePhysicsDemo.cpp create mode 100644 Demos/ConcaveDemo/Jamfile create mode 100644 Demos/ConcaveDemo/Win32ConcaveDemo.cpp create mode 100644 Demos/ConcaveDemo/main.cpp create mode 100644 Demos/ConcaveRaycastDemo/CMakeLists.txt create mode 100644 Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp create mode 100644 Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.h create mode 100644 Demos/ConcaveRaycastDemo/main.cpp create mode 100644 Demos/ConstraintDemo/CMakeLists.txt create mode 100644 Demos/ConstraintDemo/ConstraintDemo.cpp create mode 100644 Demos/ConstraintDemo/ConstraintDemo.h create mode 100644 Demos/ConstraintDemo/Win32ConstraintDemo.cpp create mode 100644 Demos/ConstraintDemo/main.cpp create mode 100644 Demos/ContinuousConvexCollision/CMakeLists.txt create mode 100644 Demos/ContinuousConvexCollision/ContinuousConvexCollision.h create mode 100644 Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp create mode 100644 Demos/ConvexDecompositionDemo/CMakeLists.txt create mode 100644 Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp create mode 100644 Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.h create mode 100644 Demos/ConvexDecompositionDemo/Win32ConvexDecompositionDemo.cpp create mode 100644 Demos/ConvexDecompositionDemo/main.cpp create mode 100644 Demos/ConvexDecompositionDemo/testFile32Single.bullet create mode 100644 Demos/ConvexHullDistance/CMakeLists.txt create mode 100644 Demos/ConvexHullDistance/ConvexHullDistanceDemo.cpp create mode 100644 Demos/DX11ClothDemo/CMakeLists.txt create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUT.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUT.h create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.h create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.h create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.h create mode 100644 Demos/DX11ClothDemo/DXUT/Core/dpiaware.manifest create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTLockFreePipe.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTres.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTres.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/ImeUi.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/ImeUi.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKsound.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKsound.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.cpp create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.h create mode 100644 Demos/DX11ClothDemo/DXUT/Optional/directx.ico create mode 100644 Demos/DX11ClothDemo/Media/Tiny/Tiny_skin.dds create mode 100644 Demos/DX11ClothDemo/Media/Tiny/tiny.sdkmesh create mode 100644 Demos/DX11ClothDemo/Media/Tiny/tiny.x create mode 100644 Demos/DX11ClothDemo/Media/UI/DXUTShared.fx create mode 100644 Demos/DX11ClothDemo/Media/UI/Font.dds create mode 100644 Demos/DX11ClothDemo/Media/UI/arrow.x create mode 100644 Demos/DX11ClothDemo/Media/UI/dxutcontrols.dds create mode 100644 Demos/DX11ClothDemo/amdFlag.bmp create mode 100644 Demos/DX11ClothDemo/atiFlag.bmp create mode 100644 Demos/DX11ClothDemo/btDirectComputeSupport.h create mode 100644 Demos/DX11ClothDemo/cap.h create mode 100644 Demos/DX11ClothDemo/capsule.h create mode 100644 Demos/DX11ClothDemo/cloth.h create mode 100644 Demos/DX11ClothDemo/cloth_renderer.cpp create mode 100644 Demos/DX11ClothDemo/cloth_renderer.fx create mode 100644 Demos/DX11ClothDemo/cloth_renderer.rc create mode 100644 Demos/DX11ClothDemo/cloth_renderer_PS.hlsl create mode 100644 Demos/DX11ClothDemo/cloth_renderer_VS.hlsl create mode 100644 Demos/DX11ClothDemo/cylinder.h create mode 100644 Demos/DX11ClothDemo/premake4.lua create mode 100644 Demos/DX11ClothDemo/resource.h create mode 100644 Demos/DX11ClothDemo/texture.bmp create mode 100644 Demos/DX11ClothDemo/texture.png create mode 100644 Demos/DoublePrecisionDemo/CMakeLists.txt create mode 100644 Demos/DoublePrecisionDemo/DoublePrecisionDemo.cpp create mode 100644 Demos/DoublePrecisionDemo/DoublePrecisionDemo.h create mode 100644 Demos/DynamicControlDemo/CMakeLists.txt create mode 100644 Demos/DynamicControlDemo/MotorDemo.cpp create mode 100644 Demos/DynamicControlDemo/MotorDemo.h create mode 100644 Demos/DynamicControlDemo/main.cpp create mode 100644 Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp create mode 100644 Demos/ForkLiftDemo/CMakeLists.txt create mode 100644 Demos/ForkLiftDemo/ForkLiftDemo.cpp create mode 100644 Demos/ForkLiftDemo/ForkLiftDemo.h create mode 100644 Demos/ForkLiftDemo/main.cpp create mode 100644 Demos/FractureDemo/CMakeLists.txt create mode 100644 Demos/FractureDemo/FractureDemo.cpp create mode 100644 Demos/FractureDemo/FractureDemo.h create mode 100644 Demos/FractureDemo/Win32FractureDemo.cpp create mode 100644 Demos/FractureDemo/btFractureBody.cpp create mode 100644 Demos/FractureDemo/btFractureBody.h create mode 100644 Demos/FractureDemo/btFractureDynamicsWorld.cpp create mode 100644 Demos/FractureDemo/btFractureDynamicsWorld.h create mode 100644 Demos/FractureDemo/main.cpp create mode 100644 Demos/GenericJointDemo/CMakeLists.txt create mode 100644 Demos/GenericJointDemo/GenericJointDemo.cpp create mode 100644 Demos/GenericJointDemo/GenericJointDemo.h create mode 100644 Demos/GenericJointDemo/Ragdoll.cpp create mode 100644 Demos/GenericJointDemo/Ragdoll.h create mode 100644 Demos/GenericJointDemo/Win32GenericJointDemo.cpp create mode 100644 Demos/GenericJointDemo/main.cpp create mode 100644 Demos/GimpactTestDemo/BunnyMesh.h create mode 100644 Demos/GimpactTestDemo/CMakeLists.txt create mode 100644 Demos/GimpactTestDemo/GimpactTestDemo.cpp create mode 100644 Demos/GimpactTestDemo/GimpactTestDemo.h create mode 100644 Demos/GimpactTestDemo/TorusMesh.h create mode 100644 Demos/GimpactTestDemo/Win32GimpactDemo.cpp create mode 100644 Demos/GimpactTestDemo/main.cpp create mode 100644 Demos/GjkConvexCastDemo/CMakeLists.txt create mode 100644 Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp create mode 100644 Demos/GjkConvexCastDemo/LinearConvexCastDemo.h create mode 100644 Demos/GjkConvexCastDemo/main.cpp create mode 100644 Demos/Gpu2dDemo/BasicDemo.cpp create mode 100644 Demos/Gpu2dDemo/BasicDemo.h create mode 100644 Demos/Gpu2dDemo/CMakeLists.txt create mode 100644 Demos/Gpu2dDemo/Makefile.am create mode 100644 Demos/Gpu2dDemo/btGpuDemo2dCpuFunc.cpp create mode 100644 Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h create mode 100644 Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h create mode 100644 Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h create mode 100644 Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.cpp create mode 100644 Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.h create mode 100644 Demos/Gpu2dDemo/btGpuDemoPairCache.cpp create mode 100644 Demos/Gpu2dDemo/btGpuDemoPairCache.h create mode 100644 Demos/Gpu2dDemo/main.cpp create mode 100644 Demos/Gpu2dDemo/oecakeLoader.cpp create mode 100644 Demos/Gpu2dDemo/oecakeLoader.h create mode 100644 Demos/Gpu3dDemo/BasicDemo3d.cpp create mode 100644 Demos/Gpu3dDemo/BasicDemo3d.h create mode 100644 Demos/Gpu3dDemo/CMakeLists.txt create mode 100644 Demos/Gpu3dDemo/btGpuDemo3dCpuFunc.cpp create mode 100644 Demos/Gpu3dDemo/btGpuDemo3dSharedCode.h create mode 100644 Demos/Gpu3dDemo/btGpuDemo3dSharedDefs.h create mode 100644 Demos/Gpu3dDemo/btGpuDemo3dSharedTypes.h create mode 100644 Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.cpp create mode 100644 Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.h create mode 100644 Demos/Gpu3dDemo/main.cpp create mode 100644 Demos/GyroscopicDemo/CMakeLists.txt create mode 100644 Demos/GyroscopicDemo/GyroscopicDemo.cpp create mode 100644 Demos/GyroscopicDemo/GyroscopicDemo.h create mode 100644 Demos/GyroscopicDemo/Win32GyroscopicDemo.cpp create mode 100644 Demos/GyroscopicDemo/main.cpp create mode 100644 Demos/HelloWorld/CMakeLists.txt create mode 100644 Demos/HelloWorld/HelloWorld.cpp create mode 100644 Demos/HelloWorld/premake4.lua create mode 100644 Demos/InternalEdgeDemo/CMakeLists.txt create mode 100644 Demos/InternalEdgeDemo/InternalEdgeDemo.cpp create mode 100644 Demos/InternalEdgeDemo/InternalEdgeDemo.h create mode 100644 Demos/InternalEdgeDemo/Taru.mdl create mode 100644 Demos/InternalEdgeDemo/Win32InternalEdgeDemo.cpp create mode 100644 Demos/InternalEdgeDemo/main.cpp create mode 100644 Demos/Makefile.am create mode 100644 Demos/Makefile.in create mode 100644 Demos/MovingConcaveDemo/CMakeLists.txt create mode 100644 Demos/MovingConcaveDemo/ConcaveDemo.h create mode 100644 Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp create mode 100644 Demos/MultiMaterialDemo/CMakeLists.txt create mode 100644 Demos/MultiMaterialDemo/MultiMaterialDemo.cpp create mode 100644 Demos/MultiMaterialDemo/MultiMaterialDemo.h create mode 100644 Demos/MultiMaterialDemo/main.cpp create mode 100644 Demos/MultiThreadedDemo/CMakeLists.txt create mode 100644 Demos/MultiThreadedDemo/Makefile.am create mode 100644 Demos/MultiThreadedDemo/Makefile.in create mode 100644 Demos/MultiThreadedDemo/MultiThreadedDemo.cpp create mode 100644 Demos/MultiThreadedDemo/MultiThreadedDemo.h create mode 100644 Demos/MultiThreadedDemo/main.cpp create mode 100644 Demos/NativeClient/bin_html/bind.js create mode 100644 Demos/NativeClient/bin_html/dragger.js create mode 100644 Demos/NativeClient/bin_html/httpd.cmd create mode 100644 Demos/NativeClient/bin_html/httpd.py create mode 100644 Demos/NativeClient/bin_html/index.html create mode 100644 Demos/NativeClient/bin_html/trackball.js create mode 100644 Demos/NativeClient/bin_html/tumbler.js create mode 100644 Demos/NativeClient/bin_html/tumbler.nmf create mode 100644 Demos/NativeClient/bin_html/vector3.js create mode 100644 Demos/NativeClient/callback.h create mode 100644 Demos/NativeClient/cube.cc create mode 100644 Demos/NativeClient/cube.h create mode 100644 Demos/NativeClient/opengl_context.cc create mode 100644 Demos/NativeClient/opengl_context.h create mode 100644 Demos/NativeClient/opengl_context_ptrs.h create mode 100644 Demos/NativeClient/premake4.lua create mode 100644 Demos/NativeClient/scripting_bridge.cc create mode 100644 Demos/NativeClient/scripting_bridge.h create mode 100644 Demos/NativeClient/shader_util.cc create mode 100644 Demos/NativeClient/shader_util.h create mode 100644 Demos/NativeClient/transforms.cc create mode 100644 Demos/NativeClient/transforms.h create mode 100644 Demos/NativeClient/tumbler.cc create mode 100644 Demos/NativeClient/tumbler.h create mode 100644 Demos/NativeClient/tumbler_module.cc create mode 100644 Demos/OpenCLClothDemo/AMD/CMakeLists.txt create mode 100644 Demos/OpenCLClothDemo/AMD/premake4.lua create mode 100644 Demos/OpenCLClothDemo/Apple/CMakeLists.txt create mode 100644 Demos/OpenCLClothDemo/CLClothDemo.sln create mode 100644 Demos/OpenCLClothDemo/CLClothDemo.vcproj create mode 100644 Demos/OpenCLClothDemo/CMakeLists.txt create mode 100644 Demos/OpenCLClothDemo/Intel/CMakeLists.txt create mode 100644 Demos/OpenCLClothDemo/Intel/premake4.lua create mode 100644 Demos/OpenCLClothDemo/MiniCL/CMakeLists.txt create mode 100644 Demos/OpenCLClothDemo/NVidia/CMakeLists.txt create mode 100644 Demos/OpenCLClothDemo/NVidia/premake4.lua create mode 100644 Demos/OpenCLClothDemo/btOpenCLSupport.h create mode 100644 Demos/OpenCLClothDemo/cl_cloth_demo.cpp create mode 100644 Demos/OpenCLClothDemo/cloth.h create mode 100644 Demos/OpenCLClothDemo/clstuff.cpp create mode 100644 Demos/OpenCLClothDemo/clstuff.h create mode 100644 Demos/OpenCLClothDemo/clstuff.hpp create mode 100644 Demos/OpenCLClothDemo/fragment.glsl create mode 100644 Demos/OpenCLClothDemo/gl_win.cpp create mode 100644 Demos/OpenCLClothDemo/gl_win.h create mode 100644 Demos/OpenCLClothDemo/gl_win.hpp create mode 100644 Demos/OpenCLClothDemo/shaders.cl create mode 100644 Demos/OpenCLClothDemo/vertex.glsl create mode 100644 Demos/OpenGL/CMakeLists.txt create mode 100644 Demos/OpenGL/CommandLineArguments.h create mode 100644 Demos/OpenGL/DebugCastResult.h create mode 100644 Demos/OpenGL/DemoApplication.cpp create mode 100644 Demos/OpenGL/DemoApplication.h create mode 100644 Demos/OpenGL/GLDebugDrawer.cpp create mode 100644 Demos/OpenGL/GLDebugDrawer.h create mode 100644 Demos/OpenGL/GLDebugFont.cpp create mode 100644 Demos/OpenGL/GLDebugFont.h create mode 100644 Demos/OpenGL/GL_DialogDynamicsWorld.cpp create mode 100644 Demos/OpenGL/GL_DialogDynamicsWorld.h create mode 100644 Demos/OpenGL/GL_DialogWindow.cpp create mode 100644 Demos/OpenGL/GL_DialogWindow.h create mode 100644 Demos/OpenGL/GL_ShapeDrawer.cpp create mode 100644 Demos/OpenGL/GL_ShapeDrawer.h create mode 100644 Demos/OpenGL/GL_Simplex1to4.cpp create mode 100644 Demos/OpenGL/GL_Simplex1to4.h create mode 100644 Demos/OpenGL/GlutDemoApplication.cpp create mode 100644 Demos/OpenGL/GlutDemoApplication.h create mode 100644 Demos/OpenGL/GlutStuff.cpp create mode 100644 Demos/OpenGL/GlutStuff.h create mode 100644 Demos/OpenGL/Makefile.am create mode 100644 Demos/OpenGL/Makefile.in create mode 100644 Demos/OpenGL/RenderTexture.cpp create mode 100644 Demos/OpenGL/RenderTexture.h create mode 100644 Demos/OpenGL/Win32AppMain.cpp create mode 100644 Demos/OpenGL/Win32DemoApplication.cpp create mode 100644 Demos/OpenGL/Win32DemoApplication.h create mode 100644 Demos/OpenGL/premake4.lua create mode 100644 Demos/OpenGL/stb_image.cpp create mode 100644 Demos/OpenGL/stb_image.h create mode 100644 Demos/OpenPL_Demo/CApi.cpp create mode 100644 Demos/OpenPL_Demo/OpenPL_Demo.c create mode 100644 Demos/ParticlesOpenCL/AMD/CMakeLists.txt create mode 100644 Demos/ParticlesOpenCL/Apple/CMakeLists.txt create mode 100644 Demos/ParticlesOpenCL/CMakeLists.txt create mode 100644 Demos/ParticlesOpenCL/Intel/CMakeLists.txt create mode 100644 Demos/ParticlesOpenCL/MiniCL/CMakeLists.txt create mode 100644 Demos/ParticlesOpenCL/MiniCL/MiniCLTaskWrap.cpp create mode 100644 Demos/ParticlesOpenCL/NVidia/CMakeLists.txt create mode 100644 Demos/ParticlesOpenCL/ParticlesDemo.cpp create mode 100644 Demos/ParticlesOpenCL/ParticlesDemo.h create mode 100644 Demos/ParticlesOpenCL/ParticlesOCL.cl create mode 100644 Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp create mode 100644 Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h create mode 100644 Demos/ParticlesOpenCL/btParticlesSharedDefs.h create mode 100644 Demos/ParticlesOpenCL/btParticlesSharedTypes.h create mode 100644 Demos/ParticlesOpenCL/main.cpp create mode 100644 Demos/ParticlesOpenCL/shaders.cpp create mode 100644 Demos/ParticlesOpenCL/shaders.h create mode 100644 Demos/RagdollDemo/CMakeLists.txt create mode 100644 Demos/RagdollDemo/RagdollDemo.cpp create mode 100644 Demos/RagdollDemo/RagdollDemo.h create mode 100644 Demos/RagdollDemo/main.cpp create mode 100644 Demos/RaytestDemo/CMakeLists.txt create mode 100644 Demos/RaytestDemo/Makefile.am create mode 100644 Demos/RaytestDemo/RaytestDemo.cpp create mode 100644 Demos/RaytestDemo/RaytestDemo.h create mode 100644 Demos/RaytestDemo/Win32RaytestDemo.cpp create mode 100644 Demos/RaytestDemo/main.cpp create mode 100644 Demos/Raytracer/CMakeLists.txt create mode 100644 Demos/Raytracer/Raytracer.cpp create mode 100644 Demos/Raytracer/Raytracer.h create mode 100644 Demos/Raytracer/main.cpp create mode 100644 Demos/RollingFrictionDemo/CMakeLists.txt create mode 100644 Demos/RollingFrictionDemo/Makefile.am create mode 100644 Demos/RollingFrictionDemo/RollingFrictionDemo.cpp create mode 100644 Demos/RollingFrictionDemo/RollingFrictionDemo.h create mode 100644 Demos/RollingFrictionDemo/Win32RollingFrictionDemo.cpp create mode 100644 Demos/RollingFrictionDemo/main.cpp create mode 100644 Demos/SerializeDemo/AMD/CMakeLists.txt create mode 100644 Demos/SerializeDemo/AMD/premake4.lua create mode 100644 Demos/SerializeDemo/CMakeLists.txt create mode 100644 Demos/SerializeDemo/SerializeDemo.cpp create mode 100644 Demos/SerializeDemo/SerializeDemo.h create mode 100644 Demos/SerializeDemo/Win32SerializeDemo.cpp create mode 100644 Demos/SerializeDemo/main.cpp create mode 100644 Demos/SerializeDemo/testFile.bullet create mode 100644 Demos/SerializeDemo/testFileCloth.bullet create mode 100644 Demos/SharedOpenCL/btOpenCLInclude.h create mode 100644 Demos/SharedOpenCL/btOpenCLUtils.cpp create mode 100644 Demos/SharedOpenCL/btOpenCLUtils.h create mode 100644 Demos/SharedOpenCL/clew.c create mode 100644 Demos/SharedOpenCL/clew.h create mode 100644 Demos/SimplexDemo/CMakeLists.txt create mode 100644 Demos/SimplexDemo/SimplexDemo.cpp create mode 100644 Demos/SimplexDemo/SimplexDemo.h create mode 100644 Demos/SliderConstraintDemo/CMakeLists.txt create mode 100755 Demos/SliderConstraintDemo/SliderConstraintDemo.cpp create mode 100755 Demos/SliderConstraintDemo/SliderConstraintDemo.h create mode 100755 Demos/SliderConstraintDemo/main.cpp create mode 100644 Demos/SoftDemo/AMD/premake4.lua create mode 100644 Demos/SoftDemo/CMakeLists.txt create mode 100644 Demos/SoftDemo/Makefile.am create mode 100644 Demos/SoftDemo/Makefile.in create mode 100644 Demos/SoftDemo/SoftDemo.cpp create mode 100644 Demos/SoftDemo/SoftDemo.h create mode 100755 Demos/SoftDemo/bunny.inl create mode 100755 Demos/SoftDemo/cube.inl create mode 100644 Demos/SoftDemo/main.cpp create mode 100644 Demos/TerrainDemo/Makefile.am create mode 100644 Demos/TerrainDemo/Makefile.in create mode 100644 Demos/TerrainDemo/TerrainDemo.cpp create mode 100644 Demos/TerrainDemo/TerrainDemo.h create mode 100644 Demos/TerrainDemo/main.cpp create mode 100644 Demos/ThreadingDemo/CMakeLists.txt create mode 100644 Demos/ThreadingDemo/main.cpp create mode 100644 Demos/UserCollisionAlgorithm/CMakeLists.txt create mode 100644 Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp create mode 100644 Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.h create mode 100644 Demos/VectorAdd_OpenCL/AMD/CMakeLists.txt create mode 100644 Demos/VectorAdd_OpenCL/Apple/CMakeLists.txt create mode 100644 Demos/VectorAdd_OpenCL/CMakeLists.txt create mode 100644 Demos/VectorAdd_OpenCL/MiniCL/CMakeLists.txt create mode 100644 Demos/VectorAdd_OpenCL/MiniCL_VectorAdd.cpp create mode 100644 Demos/VectorAdd_OpenCL/NVidia/CMakeLists.txt create mode 100644 Demos/VectorAdd_OpenCL/VectorAddKernels.cl create mode 100644 Demos/VehicleDemo/CMakeLists.txt create mode 100644 Demos/VehicleDemo/Makefile.am create mode 100644 Demos/VehicleDemo/Makefile.in create mode 100644 Demos/VehicleDemo/VehicleDemo.cpp create mode 100644 Demos/VehicleDemo/VehicleDemo.h create mode 100644 Demos/VehicleDemo/main.cpp create mode 100644 Demos/VoronoiFractureDemo/CMakeLists.txt create mode 100644 Demos/VoronoiFractureDemo/Makefile.am create mode 100644 Demos/VoronoiFractureDemo/VoronoiFractureDemo.cpp create mode 100644 Demos/VoronoiFractureDemo/VoronoiFractureDemo.h create mode 100644 Demos/VoronoiFractureDemo/Win32VoronoiFractureDemo.cpp create mode 100644 Demos/VoronoiFractureDemo/main.cpp create mode 100644 Demos/premake4.lua create mode 100644 Doxyfile create mode 100644 Extras/AllBulletDemosOSX/AllBulletDemos.xcodeproj/TemplateIcon.icns create mode 100644 Extras/AllBulletDemosOSX/AllBulletDemos.xcodeproj/project.pbxproj create mode 100644 Extras/AllBulletDemosOSX/AllBulletDemos.xcodeproj/zakariya.pbxuser create mode 100644 Extras/AllBulletDemosOSX/AllBulletDemos.xcodeproj/zakariya.perspectivev3 create mode 100644 Extras/AllBulletDemosOSX/AllBulletDemos_Prefix.pch create mode 100644 Extras/AllBulletDemosOSX/BulletIcon.icns create mode 100644 Extras/AllBulletDemosOSX/BulletIcon.psd create mode 100644 Extras/AllBulletDemosOSX/English.lproj/Credits.rtf create mode 100644 Extras/AllBulletDemosOSX/English.lproj/InfoPlist.strings create mode 100644 Extras/AllBulletDemosOSX/English.lproj/MainMenu.xib create mode 100644 Extras/AllBulletDemosOSX/Info.plist create mode 100644 Extras/AllBulletDemosOSX/README.txt create mode 100644 Extras/AllBulletDemosOSX/main.m create mode 100644 Extras/AllBulletDemosOSX/src/BTDemo.h create mode 100644 Extras/AllBulletDemosOSX/src/BTDemo.mm create mode 100644 Extras/AllBulletDemosOSX/src/BTDemosAppController.h create mode 100644 Extras/AllBulletDemosOSX/src/BTDemosAppController.m create mode 100644 Extras/AllBulletDemosOSX/src/BTSimulationParameters.h create mode 100644 Extras/AllBulletDemosOSX/src/BTSimulationParameters.m create mode 100644 Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.h create mode 100644 Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.m create mode 100644 Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.h create mode 100644 Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.m create mode 100644 Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLDisplayDelegate.h create mode 100644 Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.h create mode 100644 Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.m create mode 100644 Extras/CDTestFramework/AntTweakBar/ChangeLog.txt create mode 100644 Extras/CDTestFramework/AntTweakBar/Clean.bat create mode 100644 Extras/CDTestFramework/AntTweakBar/License.txt create mode 100644 Extras/CDTestFramework/AntTweakBar/Readme.txt create mode 100644 Extras/CDTestFramework/AntTweakBar/include/AntTweakBar.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/AntPerfTimer.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.rc create mode 100644 Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.sln create mode 100644 Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.vcproj create mode 100644 Extras/CDTestFramework/AntTweakBar/src/LoadOGL.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/LoadOGL.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/Makefile create mode 100644 Extras/CDTestFramework/AntTweakBar/src/Makefile.x86_64 create mode 100644 Extras/CDTestFramework/AntTweakBar/src/MiniGLUT.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwBar.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwBar.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwColors.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwColors.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwEventGLFW.c create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwEventGLUT.c create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwEventSDL.c create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwEventWin.c create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwEventWin32.c create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwEventX11.c create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwFonts.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwFonts.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwGraph.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwMgr.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwMgr.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.cpp create mode 100644 Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/d3d10vs2003.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/FontChars.txt create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/FontFixed1.pgm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/FontLargeAA.pgm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/FontNormal.pgm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/FontNormalAA.pgm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/FontSmall.pgm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/TwXCursors.h create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00000.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00001.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00002.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00003.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00004.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00005.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00006.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00007.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00008.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00009.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00010.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00011.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00012.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/cur00013.cur create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs00.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs01.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs02.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs03.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs04.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs05.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs06.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs07.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs08.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs09.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs10.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs11.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs12.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/curs13.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask00.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask01.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask02.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask03.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask04.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask05.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask06.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask07.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask08.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask09.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask10.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask11.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask12.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/res/mask13.pbm create mode 100644 Extras/CDTestFramework/AntTweakBar/src/resource.h create mode 100644 Extras/CDTestFramework/BipartiteBoxPruning.cpp create mode 100644 Extras/CDTestFramework/BipartiteBoxPruning.h create mode 100644 Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.cpp create mode 100644 Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.h create mode 100644 Extras/CDTestFramework/CDTestFramework.cpp create mode 100644 Extras/CDTestFramework/CDTestFramework.h create mode 100644 Extras/CDTestFramework/CDTestFramework.sln create mode 100644 Extras/CDTestFramework/CDTestFramework.txt create mode 100644 Extras/CDTestFramework/CDTestFramework.vcproj create mode 100644 Extras/CDTestFramework/Camera.cpp create mode 100644 Extras/CDTestFramework/Camera.h create mode 100644 Extras/CDTestFramework/CapsuleMeshQuery.cpp create mode 100644 Extras/CDTestFramework/CapsuleMeshQuery.h create mode 100644 Extras/CDTestFramework/CollisionTest.cpp create mode 100644 Extras/CDTestFramework/CollisionTest.h create mode 100644 Extras/CDTestFramework/CompleteBoxPruning.cpp create mode 100644 Extras/CDTestFramework/CompleteBoxPruning.h create mode 100644 Extras/CDTestFramework/GLFontData.h create mode 100644 Extras/CDTestFramework/GLFontRenderer.cpp create mode 100644 Extras/CDTestFramework/GLFontRenderer.h create mode 100644 Extras/CDTestFramework/GLUT32.DLL create mode 100644 Extras/CDTestFramework/History.txt create mode 100644 Extras/CDTestFramework/IceHelpers.cpp create mode 100644 Extras/CDTestFramework/IceHelpers.h create mode 100644 Extras/CDTestFramework/License.txt create mode 100644 Extras/CDTestFramework/License.txt.bak create mode 100644 Extras/CDTestFramework/OBBMeshQuery.cpp create mode 100644 Extras/CDTestFramework/OBBMeshQuery.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceAABB.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceAABB.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceAllocator.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceAllocator.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceAssert.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceAxes.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceBitArray.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceBitArray.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceBoundingSphere.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceContainer.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceContainer.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceFPU.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceHPoint.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceHPoint.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceHashing.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceLSS.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceMemoryMacros.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceOBB.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceOBB.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IcePairs.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IcePlane.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IcePlane.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IcePoint.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IcePoint.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IcePreprocessor.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceRandom.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceRandom.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceRay.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceRay.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceRevisitedRadix.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceRevisitedRadix.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceSegment.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceSegment.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceTriangle.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceTriangle.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceTrilist.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceTypes.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceUtils.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/IceUtils.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceAABB.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceContainer.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceContainer.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceFPU.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceMemoryMacros.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IcePreprocessor.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceRevisitedRadix.cpp create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceRevisitedRadix.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceTypes.h create mode 100644 Extras/CDTestFramework/Opcode/Ice/_IceUtils.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_AABBCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_AABBCollider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_AABBTree.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_AABBTree.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_ArraySAP.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_ArraySAP.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_BaseModel.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_BaseModel.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_BoxBoxOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_BoxPruning.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_BoxPruning.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_Collider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_Collider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_Common.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_Common.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_HybridModel.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_HybridModel.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_IceHook.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_LSSAABBOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_LSSCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_LSSCollider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_LSSTriOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_MeshInterface.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_MeshInterface.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_Model.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_Model.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_OBBCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_OBBCollider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_OptimizedTree.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_OptimizedTree.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_Picking.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_Picking.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_PlanesAABBOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_PlanesCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_PlanesCollider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_PlanesTriOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_RayAABBOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_RayCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_RayCollider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_RayTriOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_Settings.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_SphereAABBOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_SphereCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_SphereCollider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_SphereTriOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_TreeBuilders.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_TreeBuilders.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_TreeCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_TreeCollider.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_TriBoxOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_TriTriOverlap.h create mode 100644 Extras/CDTestFramework/Opcode/OPC_VolumeCollider.cpp create mode 100644 Extras/CDTestFramework/Opcode/OPC_VolumeCollider.h create mode 100644 Extras/CDTestFramework/Opcode/Opcode.cpp create mode 100644 Extras/CDTestFramework/Opcode/Opcode.dsp create mode 100644 Extras/CDTestFramework/Opcode/Opcode.dsw create mode 100644 Extras/CDTestFramework/Opcode/Opcode.h create mode 100644 Extras/CDTestFramework/Opcode/Opcode.sln create mode 100644 Extras/CDTestFramework/Opcode/Opcode.vcproj create mode 100644 Extras/CDTestFramework/Opcode/ReadMe.txt create mode 100644 Extras/CDTestFramework/Opcode/StdAfx.cpp create mode 100644 Extras/CDTestFramework/Opcode/StdAfx.h create mode 100644 Extras/CDTestFramework/OpcodeArraySAPTest.cpp create mode 100644 Extras/CDTestFramework/OpcodeArraySAPTest.h create mode 100644 Extras/CDTestFramework/Profiling.h create mode 100644 Extras/CDTestFramework/ReadMe.txt create mode 100644 Extras/CDTestFramework/RenderingHelpers.cpp create mode 100644 Extras/CDTestFramework/RenderingHelpers.h create mode 100644 Extras/CDTestFramework/SphereMeshQuery.cpp create mode 100644 Extras/CDTestFramework/SphereMeshQuery.h create mode 100644 Extras/CDTestFramework/Terrain.cpp create mode 100644 Extras/CDTestFramework/Terrain.h create mode 100644 Extras/CDTestFramework/convex1.bin create mode 100644 Extras/CDTestFramework/stdafx.cpp create mode 100644 Extras/CDTestFramework/stdafx.h create mode 100644 Extras/CMakeLists.txt create mode 100644 Extras/CUDA/btCudaBroadphase.cpp create mode 100644 Extras/CUDA/btCudaBroadphase.cu create mode 100644 Extras/CUDA/btCudaBroadphase.h create mode 100644 Extras/CUDA/btCudaDefines.h create mode 100644 Extras/CUDA/btCudaUtils.cu create mode 100644 Extras/CUDA/btGpuDemo2dCudaFunc.cu create mode 100644 Extras/CUDA/btGpuDemo3dCudaFunc.cu create mode 100644 Extras/CUDA/cutil_gl_error.h create mode 100644 Extras/CUDA/cutil_math.h create mode 100644 Extras/CUDA/libbulletcuda.vcproj create mode 100644 Extras/CUDA/radixsort.cu create mode 100644 Extras/CUDA/radixsort.cuh create mode 100644 Extras/CUDA/radixsort_kernel.cu create mode 100644 Extras/ConvexDecomposition/CMakeLists.txt create mode 100644 Extras/ConvexDecomposition/ConvexBuilder.cpp create mode 100644 Extras/ConvexDecomposition/ConvexBuilder.h create mode 100644 Extras/ConvexDecomposition/ConvexDecomposition.cpp create mode 100644 Extras/ConvexDecomposition/ConvexDecomposition.h create mode 100644 Extras/ConvexDecomposition/bestfit.cpp create mode 100644 Extras/ConvexDecomposition/bestfit.h create mode 100644 Extras/ConvexDecomposition/bestfitobb.cpp create mode 100644 Extras/ConvexDecomposition/bestfitobb.h create mode 100644 Extras/ConvexDecomposition/cd_hull.cpp create mode 100644 Extras/ConvexDecomposition/cd_hull.h create mode 100644 Extras/ConvexDecomposition/cd_vector.h create mode 100644 Extras/ConvexDecomposition/cd_wavefront.cpp create mode 100644 Extras/ConvexDecomposition/cd_wavefront.h create mode 100644 Extras/ConvexDecomposition/concavity.cpp create mode 100644 Extras/ConvexDecomposition/concavity.h create mode 100644 Extras/ConvexDecomposition/fitsphere.cpp create mode 100644 Extras/ConvexDecomposition/fitsphere.h create mode 100644 Extras/ConvexDecomposition/float_math.cpp create mode 100644 Extras/ConvexDecomposition/float_math.h create mode 100644 Extras/ConvexDecomposition/meshvolume.cpp create mode 100644 Extras/ConvexDecomposition/meshvolume.h create mode 100644 Extras/ConvexDecomposition/planetri.cpp create mode 100644 Extras/ConvexDecomposition/planetri.h create mode 100644 Extras/ConvexDecomposition/premake4.lua create mode 100644 Extras/ConvexDecomposition/raytri.cpp create mode 100644 Extras/ConvexDecomposition/raytri.h create mode 100644 Extras/ConvexDecomposition/splitplane.cpp create mode 100644 Extras/ConvexDecomposition/splitplane.h create mode 100644 Extras/ConvexDecomposition/vlookup.cpp create mode 100644 Extras/ConvexDecomposition/vlookup.h create mode 100644 Extras/GIMPACTUtils/CMakeLists.txt create mode 100644 Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp create mode 100644 Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h create mode 100644 Extras/HACD/CMakeLists.txt create mode 100644 Extras/HACD/hacdCircularList.h create mode 100644 Extras/HACD/hacdCircularList.inl create mode 100644 Extras/HACD/hacdGraph.cpp create mode 100644 Extras/HACD/hacdGraph.h create mode 100644 Extras/HACD/hacdHACD.cpp create mode 100644 Extras/HACD/hacdHACD.h create mode 100644 Extras/HACD/hacdICHull.cpp create mode 100644 Extras/HACD/hacdICHull.h create mode 100644 Extras/HACD/hacdManifoldMesh.cpp create mode 100644 Extras/HACD/hacdManifoldMesh.h create mode 100644 Extras/HACD/hacdVector.h create mode 100644 Extras/HACD/hacdVector.inl create mode 100644 Extras/HACD/hacdVersion.h create mode 100644 Extras/HACD/premake4.lua create mode 100644 Extras/Makefile.am create mode 100644 Extras/Makefile.in create mode 100644 Extras/Serialize/BlenderSerialize/CMakeLists.txt create mode 100644 Extras/Serialize/BlenderSerialize/bBlenderFile.cpp create mode 100644 Extras/Serialize/BlenderSerialize/bBlenderFile.h create mode 100644 Extras/Serialize/BlenderSerialize/bMain.cpp create mode 100644 Extras/Serialize/BlenderSerialize/bMain.h create mode 100644 Extras/Serialize/BlenderSerialize/dna249-64bit.cpp create mode 100644 Extras/Serialize/BlenderSerialize/dna249.cpp create mode 100644 Extras/Serialize/BulletFileLoader/CMakeLists.txt create mode 100644 Extras/Serialize/BulletFileLoader/autogenerated/bullet.h create mode 100644 Extras/Serialize/BulletFileLoader/bChunk.cpp create mode 100644 Extras/Serialize/BulletFileLoader/bChunk.h create mode 100644 Extras/Serialize/BulletFileLoader/bCommon.h create mode 100644 Extras/Serialize/BulletFileLoader/bDNA.cpp create mode 100644 Extras/Serialize/BulletFileLoader/bDNA.h create mode 100644 Extras/Serialize/BulletFileLoader/bDefines.h create mode 100644 Extras/Serialize/BulletFileLoader/bFile.cpp create mode 100644 Extras/Serialize/BulletFileLoader/bFile.h create mode 100644 Extras/Serialize/BulletFileLoader/btBulletFile.cpp create mode 100644 Extras/Serialize/BulletFileLoader/btBulletFile.h create mode 100644 Extras/Serialize/BulletFileLoader/premake4.lua create mode 100644 Extras/Serialize/BulletWorldImporter/CMakeLists.txt create mode 100644 Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp create mode 100644 Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h create mode 100644 Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp create mode 100644 Extras/Serialize/BulletWorldImporter/btWorldImporter.h create mode 100644 Extras/Serialize/BulletWorldImporter/premake4.lua create mode 100644 Extras/Serialize/BulletXmlWorldImporter/CMakeLists.txt create mode 100644 Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp create mode 100644 Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h create mode 100644 Extras/Serialize/BulletXmlWorldImporter/premake4.lua create mode 100644 Extras/Serialize/BulletXmlWorldImporter/string_split.cpp create mode 100644 Extras/Serialize/BulletXmlWorldImporter/string_split.h create mode 100644 Extras/Serialize/BulletXmlWorldImporter/tinystr.cpp create mode 100644 Extras/Serialize/BulletXmlWorldImporter/tinystr.h create mode 100644 Extras/Serialize/BulletXmlWorldImporter/tinyxml.cpp create mode 100644 Extras/Serialize/BulletXmlWorldImporter/tinyxml.h create mode 100644 Extras/Serialize/BulletXmlWorldImporter/tinyxmlerror.cpp create mode 100644 Extras/Serialize/BulletXmlWorldImporter/tinyxmlparser.cpp create mode 100644 Extras/Serialize/CMakeLists.txt create mode 100644 Extras/Serialize/HeaderGenerator/CMakeLists.txt create mode 100644 Extras/Serialize/HeaderGenerator/apiGen.cpp create mode 100644 Extras/Serialize/HeaderGenerator/blenderGenerate.py create mode 100644 Extras/Serialize/HeaderGenerator/bulletGenerate.py create mode 100644 Extras/Serialize/HeaderGenerator/createDnaString.bat create mode 100644 Extras/Serialize/ReadBulletSample/BulletDataExtractor.cpp create mode 100644 Extras/Serialize/ReadBulletSample/BulletDataExtractor.h create mode 100644 Extras/Serialize/ReadBulletSample/CMakeLists.txt create mode 100644 Extras/Serialize/ReadBulletSample/main.cpp create mode 100644 Extras/Serialize/makesdna/CMakeLists.txt create mode 100644 Extras/Serialize/makesdna/DNA_rigidbody.h create mode 100644 Extras/Serialize/makesdna/makesdna.cpp create mode 100644 Extras/glui/CMakeLists.txt create mode 100644 Extras/glui/GL/glui.h create mode 100644 Extras/glui/algebra3.cpp create mode 100644 Extras/glui/algebra3.h create mode 100644 Extras/glui/arcball.cpp create mode 100644 Extras/glui/arcball.h create mode 100644 Extras/glui/glui.cpp create mode 100644 Extras/glui/glui_add_controls.cpp create mode 100644 Extras/glui/glui_bitmap_img_data.cpp create mode 100644 Extras/glui/glui_bitmaps.cpp create mode 100644 Extras/glui/glui_button.cpp create mode 100644 Extras/glui/glui_checkbox.cpp create mode 100644 Extras/glui/glui_column.cpp create mode 100644 Extras/glui/glui_commandline.cpp create mode 100644 Extras/glui/glui_control.cpp create mode 100644 Extras/glui/glui_edittext.cpp create mode 100644 Extras/glui/glui_filebrowser.cpp create mode 100644 Extras/glui/glui_internal.h create mode 100644 Extras/glui/glui_internal_control.h create mode 100644 Extras/glui/glui_list.cpp create mode 100644 Extras/glui/glui_listbox.cpp create mode 100644 Extras/glui/glui_mouse_iaction.cpp create mode 100644 Extras/glui/glui_node.cpp create mode 100644 Extras/glui/glui_panel.cpp create mode 100644 Extras/glui/glui_radio.cpp create mode 100644 Extras/glui/glui_rollout.cpp create mode 100644 Extras/glui/glui_rotation.cpp create mode 100644 Extras/glui/glui_scrollbar.cpp create mode 100644 Extras/glui/glui_separator.cpp create mode 100644 Extras/glui/glui_spinner.cpp create mode 100644 Extras/glui/glui_statictext.cpp create mode 100644 Extras/glui/glui_string.cpp create mode 100644 Extras/glui/glui_textbox.cpp create mode 100644 Extras/glui/glui_translation.cpp create mode 100644 Extras/glui/glui_tree.cpp create mode 100644 Extras/glui/glui_treepanel.cpp create mode 100644 Extras/glui/glui_window.cpp create mode 100644 Extras/glui/quaternion.cpp create mode 100644 Extras/glui/quaternion.h create mode 100644 Extras/glui/readme.txt create mode 100644 Extras/khx2dae/Bullet_dae_screenshot.jpg create mode 100644 Extras/khx2dae/Havok5.5toColladaPhysics.dae create mode 100644 Extras/khx2dae/Havok_hkx_screenshot.jpg create mode 100644 Extras/khx2dae/SimpleLoadDemo.patch create mode 100644 Extras/khx2dae/readme.txt create mode 100644 Extras/premake4.lua create mode 100644 Extras/sph/READ_ME.txt create mode 100644 Extras/sph/cmp.sh create mode 100644 Extras/sph/common/GLee.c create mode 100644 Extras/sph/common/GLee.h create mode 100644 Extras/sph/common/common_defs.h create mode 100644 Extras/sph/common/geomx.cpp create mode 100644 Extras/sph/common/geomx.h create mode 100644 Extras/sph/common/gl_helper.cpp create mode 100644 Extras/sph/common/gl_helper.h create mode 100644 Extras/sph/common/glext.h create mode 100644 Extras/sph/common/glut.h create mode 100644 Extras/sph/common/image.cpp create mode 100644 Extras/sph/common/image.h create mode 100644 Extras/sph/common/matrix-inline.h create mode 100644 Extras/sph/common/matrix.cci create mode 100644 Extras/sph/common/matrix.cpp create mode 100644 Extras/sph/common/matrix.h create mode 100644 Extras/sph/common/mdebug.cpp create mode 100644 Extras/sph/common/mdebug.h create mode 100644 Extras/sph/common/mesh.cpp create mode 100644 Extras/sph/common/mesh.h create mode 100644 Extras/sph/common/mesh_info.h create mode 100644 Extras/sph/common/mtime.cpp create mode 100644 Extras/sph/common/mtime.h create mode 100644 Extras/sph/common/particle.cpp create mode 100644 Extras/sph/common/particle.h create mode 100644 Extras/sph/common/point_set.cpp create mode 100644 Extras/sph/common/point_set.h create mode 100644 Extras/sph/common/vector-inline.h create mode 100644 Extras/sph/common/vector.cci create mode 100644 Extras/sph/common/vector.cpp create mode 100644 Extras/sph/common/vector.h create mode 100644 Extras/sph/fluid_system_host.linkinfo create mode 100644 Extras/sph/fluids.vcproj create mode 100644 Extras/sph/fluids/fluid.cpp create mode 100644 Extras/sph/fluids/fluid.h create mode 100644 Extras/sph/fluids/fluid_system.cpp create mode 100644 Extras/sph/fluids/fluid_system.cu create mode 100644 Extras/sph/fluids/fluid_system.h create mode 100644 Extras/sph/fluids/fluid_system_host.cu create mode 100644 Extras/sph/fluids/fluid_system_host.cuh create mode 100644 Extras/sph/fluids/fluid_system_kern.cu create mode 100644 Extras/sph/fluids/fluid_system_kern.cuh create mode 100644 Extras/sph/fluids/radixsort.cu create mode 100644 Extras/sph/fluids/radixsort.cuh create mode 100644 Extras/sph/fluids/radixsort_kernel.cu create mode 100644 Extras/sph/fluids_2005.sln create mode 100644 Extras/sph/fluids_2005.vcproj create mode 100644 Extras/sph/main.cpp create mode 100644 GLUT32.DLL create mode 100644 Glut/EmptyGL/GL/egl_cpx.h create mode 100644 Glut/EmptyGL/GL/egl_defs.h create mode 100644 Glut/EmptyGL/GL/egl_logged.h create mode 100644 Glut/EmptyGL/GL/egl_tokens.h create mode 100644 Glut/EmptyGL/GL/egl_void.h create mode 100644 Glut/EmptyGL/GL/gl.h create mode 100644 Glut/EmptyGL/GL/glu.h create mode 100644 Glut/EmptyGL/GL/glut.h create mode 100644 Glut/GL/glew.h create mode 100644 Glut/GL/glext.h create mode 100644 Glut/GL/glut.h create mode 100644 Glut/GL/glxew.h create mode 100644 Glut/GL/glxext.h create mode 100644 Glut/GL/wglew.h create mode 100644 Glut/GL/wglext.h create mode 100644 Glut/btGlutInclude.h create mode 100644 Glut/glew32s.lib create mode 100644 Glut/glew64s.lib create mode 100644 Glut/glut32.lib create mode 100644 Glut/glut64.lib create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 RELEASING.TXT create mode 100644 Test/Info.plist create mode 100644 Test/README.txt create mode 100644 Test/Source/TestList.cpp create mode 100644 Test/Source/TestList.h create mode 100644 Test/Source/Tests/Test_3x3getRot.cpp create mode 100644 Test/Source/Tests/Test_3x3getRot.h create mode 100644 Test/Source/Tests/Test_3x3mulM.cpp create mode 100644 Test/Source/Tests/Test_3x3mulM.h create mode 100644 Test/Source/Tests/Test_3x3mulM1M2.cpp create mode 100644 Test/Source/Tests/Test_3x3mulM1M2.h create mode 100644 Test/Source/Tests/Test_3x3mulMV.cpp create mode 100644 Test/Source/Tests/Test_3x3mulMV.h create mode 100644 Test/Source/Tests/Test_3x3mulVM.cpp create mode 100644 Test/Source/Tests/Test_3x3mulVM.h create mode 100644 Test/Source/Tests/Test_3x3setRot.cpp create mode 100644 Test/Source/Tests/Test_3x3setRot.h create mode 100644 Test/Source/Tests/Test_3x3timesTranspose.cpp create mode 100644 Test/Source/Tests/Test_3x3timesTranspose.h create mode 100644 Test/Source/Tests/Test_3x3transpose.cpp create mode 100644 Test/Source/Tests/Test_3x3transpose.h create mode 100644 Test/Source/Tests/Test_3x3transposeTimes.cpp create mode 100644 Test/Source/Tests/Test_3x3transposeTimes.h create mode 100644 Test/Source/Tests/Test_btDbvt.cpp create mode 100644 Test/Source/Tests/Test_btDbvt.h create mode 100644 Test/Source/Tests/Test_dot3.cpp create mode 100644 Test/Source/Tests/Test_dot3.h create mode 100644 Test/Source/Tests/Test_maxdot.cpp create mode 100644 Test/Source/Tests/Test_maxdot.h create mode 100644 Test/Source/Tests/Test_mindot.cpp create mode 100644 Test/Source/Tests/Test_mindot.h create mode 100644 Test/Source/Tests/Test_qtdot.cpp create mode 100644 Test/Source/Tests/Test_qtdot.h create mode 100644 Test/Source/Tests/Test_qtmul.cpp create mode 100644 Test/Source/Tests/Test_qtmul.h create mode 100644 Test/Source/Tests/Test_qtmulQV3.cpp create mode 100644 Test/Source/Tests/Test_qtmulQV3.h create mode 100644 Test/Source/Tests/Test_qtmulV3Q.cpp create mode 100644 Test/Source/Tests/Test_qtmulV3Q.h create mode 100644 Test/Source/Tests/Test_qtnorm.cpp create mode 100644 Test/Source/Tests/Test_qtnorm.h create mode 100644 Test/Source/Tests/Test_quat_aos_neon.cpp create mode 100644 Test/Source/Tests/Test_quat_aos_neon.h create mode 100644 Test/Source/Tests/Test_v3cross.cpp create mode 100644 Test/Source/Tests/Test_v3cross.h create mode 100644 Test/Source/Tests/Test_v3div.cpp create mode 100644 Test/Source/Tests/Test_v3div.h create mode 100644 Test/Source/Tests/Test_v3dot.cpp create mode 100644 Test/Source/Tests/Test_v3dot.h create mode 100644 Test/Source/Tests/Test_v3interp.cpp create mode 100644 Test/Source/Tests/Test_v3interp.h create mode 100644 Test/Source/Tests/Test_v3lerp.cpp create mode 100644 Test/Source/Tests/Test_v3lerp.h create mode 100644 Test/Source/Tests/Test_v3norm.cpp create mode 100644 Test/Source/Tests/Test_v3norm.h create mode 100644 Test/Source/Tests/Test_v3rotate.cpp create mode 100644 Test/Source/Tests/Test_v3rotate.h create mode 100644 Test/Source/Tests/Test_v3sdiv.cpp create mode 100644 Test/Source/Tests/Test_v3sdiv.h create mode 100644 Test/Source/Tests/Test_v3skew.cpp create mode 100644 Test/Source/Tests/Test_v3skew.h create mode 100644 Test/Source/Tests/Test_v3triple.cpp create mode 100644 Test/Source/Tests/Test_v3triple.h create mode 100644 Test/Source/Utils.cpp create mode 100644 Test/Source/Utils.h create mode 100644 Test/Source/btIntDefines.h create mode 100644 Test/Source/main.cpp create mode 100644 Test/Source/main.h create mode 100644 Test/Source/vector.h create mode 100644 Test/premake4.lua create mode 100644 UnitTests/BulletUnitTests/CMakeLists.txt create mode 100644 UnitTests/BulletUnitTests/Main.cpp create mode 100644 UnitTests/BulletUnitTests/TestBulletOnly.h create mode 100644 UnitTests/BulletUnitTests/TestCholeskyDecomposition.cpp create mode 100644 UnitTests/BulletUnitTests/TestCholeskyDecomposition.h create mode 100644 UnitTests/BulletUnitTests/TestLinearMath.h create mode 100644 UnitTests/BulletUnitTests/TestPolarDecomposition.cpp create mode 100644 UnitTests/BulletUnitTests/TestPolarDecomposition.h create mode 100644 UnitTests/BulletUnitTests/btCholeskyDecomposition.cpp create mode 100644 UnitTests/BulletUnitTests/btCholeskyDecomposition.h create mode 100644 UnitTests/CMakeLists.txt create mode 100644 UnitTests/cppunit/AUTHORS create mode 100644 UnitTests/cppunit/BUGS create mode 100644 UnitTests/cppunit/CMakeLists.txt create mode 100644 UnitTests/cppunit/ChangeLog create mode 100644 UnitTests/cppunit/CodingGuideLines.txt create mode 100644 UnitTests/cppunit/THANKS create mode 100644 UnitTests/cppunit/TODO create mode 100644 UnitTests/cppunit/include/cppunit/AdditionalMessage.h create mode 100644 UnitTests/cppunit/include/cppunit/Asserter.h create mode 100644 UnitTests/cppunit/include/cppunit/BriefTestProgressListener.h create mode 100644 UnitTests/cppunit/include/cppunit/CompilerOutputter.h create mode 100644 UnitTests/cppunit/include/cppunit/Exception.h create mode 100644 UnitTests/cppunit/include/cppunit/Message.h create mode 100644 UnitTests/cppunit/include/cppunit/Outputter.h create mode 100644 UnitTests/cppunit/include/cppunit/Portability.h create mode 100644 UnitTests/cppunit/include/cppunit/Protector.h create mode 100644 UnitTests/cppunit/include/cppunit/SourceLine.h create mode 100644 UnitTests/cppunit/include/cppunit/SynchronizedObject.h create mode 100644 UnitTests/cppunit/include/cppunit/Test.h create mode 100644 UnitTests/cppunit/include/cppunit/TestAssert.h create mode 100644 UnitTests/cppunit/include/cppunit/TestCaller.h create mode 100644 UnitTests/cppunit/include/cppunit/TestCase.h create mode 100644 UnitTests/cppunit/include/cppunit/TestComposite.h create mode 100644 UnitTests/cppunit/include/cppunit/TestFailure.h create mode 100644 UnitTests/cppunit/include/cppunit/TestFixture.h create mode 100644 UnitTests/cppunit/include/cppunit/TestLeaf.h create mode 100644 UnitTests/cppunit/include/cppunit/TestListener.h create mode 100644 UnitTests/cppunit/include/cppunit/TestPath.h create mode 100644 UnitTests/cppunit/include/cppunit/TestResult.h create mode 100644 UnitTests/cppunit/include/cppunit/TestResultCollector.h create mode 100644 UnitTests/cppunit/include/cppunit/TestRunner.h create mode 100644 UnitTests/cppunit/include/cppunit/TestSuccessListener.h create mode 100644 UnitTests/cppunit/include/cppunit/TestSuite.h create mode 100644 UnitTests/cppunit/include/cppunit/TextOutputter.h create mode 100644 UnitTests/cppunit/include/cppunit/TextTestProgressListener.h create mode 100644 UnitTests/cppunit/include/cppunit/TextTestResult.h create mode 100644 UnitTests/cppunit/include/cppunit/TextTestRunner.h create mode 100644 UnitTests/cppunit/include/cppunit/XmlOutputter.h create mode 100644 UnitTests/cppunit/include/cppunit/XmlOutputterHook.h create mode 100644 UnitTests/cppunit/include/cppunit/config-auto.h create mode 100644 UnitTests/cppunit/include/cppunit/config/CppUnitApi.h create mode 100644 UnitTests/cppunit/include/cppunit/config/SelectDllLoader.h create mode 100644 UnitTests/cppunit/include/cppunit/config/SourcePrefix.h create mode 100644 UnitTests/cppunit/include/cppunit/config/config-bcb5.h create mode 100644 UnitTests/cppunit/include/cppunit/config/config-evc4.h create mode 100644 UnitTests/cppunit/include/cppunit/config/config-mac.h create mode 100644 UnitTests/cppunit/include/cppunit/config/config-msvc6.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/AutoRegisterSuite.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/ExceptionTestCaseDecorator.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/HelperMacros.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/Orthodox.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/RepeatedTest.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestCaseDecorator.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestDecorator.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestFactory.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestFactoryRegistry.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestFixtureFactory.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestNamer.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestSetUp.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestSuiteBuilderContext.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TestSuiteFactory.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/TypeInfoHelper.h create mode 100644 UnitTests/cppunit/include/cppunit/extensions/XmlInputHelper.h create mode 100644 UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManager.h create mode 100644 UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManagerException.h create mode 100644 UnitTests/cppunit/include/cppunit/plugin/PlugInManager.h create mode 100644 UnitTests/cppunit/include/cppunit/plugin/PlugInParameters.h create mode 100644 UnitTests/cppunit/include/cppunit/plugin/TestPlugIn.h create mode 100644 UnitTests/cppunit/include/cppunit/plugin/TestPlugInDefaultImpl.h create mode 100644 UnitTests/cppunit/include/cppunit/portability/CppUnitDeque.h create mode 100644 UnitTests/cppunit/include/cppunit/portability/CppUnitMap.h create mode 100644 UnitTests/cppunit/include/cppunit/portability/CppUnitSet.h create mode 100644 UnitTests/cppunit/include/cppunit/portability/CppUnitStack.h create mode 100644 UnitTests/cppunit/include/cppunit/portability/CppUnitVector.h create mode 100644 UnitTests/cppunit/include/cppunit/portability/FloatingPoint.h create mode 100644 UnitTests/cppunit/include/cppunit/portability/Stream.h create mode 100644 UnitTests/cppunit/include/cppunit/tools/Algorithm.h create mode 100644 UnitTests/cppunit/include/cppunit/tools/StringTools.h create mode 100644 UnitTests/cppunit/include/cppunit/tools/XmlDocument.h create mode 100644 UnitTests/cppunit/include/cppunit/tools/XmlElement.h create mode 100644 UnitTests/cppunit/include/cppunit/ui/text/TestRunner.h create mode 100644 UnitTests/cppunit/include/cppunit/ui/text/TextTestRunner.h create mode 100644 UnitTests/cppunit/src/cppunit/AdditionalMessage.cpp create mode 100644 UnitTests/cppunit/src/cppunit/Asserter.cpp create mode 100644 UnitTests/cppunit/src/cppunit/BeOsDynamicLibraryManager.cpp create mode 100644 UnitTests/cppunit/src/cppunit/BriefTestProgressListener.cpp create mode 100644 UnitTests/cppunit/src/cppunit/CompilerOutputter.cpp create mode 100644 UnitTests/cppunit/src/cppunit/DefaultProtector.cpp create mode 100644 UnitTests/cppunit/src/cppunit/DefaultProtector.h create mode 100644 UnitTests/cppunit/src/cppunit/DllMain.cpp create mode 100644 UnitTests/cppunit/src/cppunit/DynamicLibraryManager.cpp create mode 100644 UnitTests/cppunit/src/cppunit/DynamicLibraryManagerException.cpp create mode 100644 UnitTests/cppunit/src/cppunit/Exception.cpp create mode 100644 UnitTests/cppunit/src/cppunit/Message.cpp create mode 100644 UnitTests/cppunit/src/cppunit/PlugInManager.cpp create mode 100644 UnitTests/cppunit/src/cppunit/PlugInParameters.cpp create mode 100644 UnitTests/cppunit/src/cppunit/Protector.cpp create mode 100644 UnitTests/cppunit/src/cppunit/ProtectorChain.cpp create mode 100644 UnitTests/cppunit/src/cppunit/ProtectorChain.h create mode 100644 UnitTests/cppunit/src/cppunit/ProtectorContext.h create mode 100644 UnitTests/cppunit/src/cppunit/RepeatedTest.cpp create mode 100644 UnitTests/cppunit/src/cppunit/ShlDynamicLibraryManager.cpp create mode 100644 UnitTests/cppunit/src/cppunit/SourceLine.cpp create mode 100644 UnitTests/cppunit/src/cppunit/StringTools.cpp create mode 100644 UnitTests/cppunit/src/cppunit/SynchronizedObject.cpp create mode 100644 UnitTests/cppunit/src/cppunit/Test.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestAssert.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestCase.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestCaseDecorator.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestComposite.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestDecorator.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestFactoryRegistry.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestFailure.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestLeaf.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestNamer.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestPath.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestPlugInDefaultImpl.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestResult.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestResultCollector.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestRunner.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestSetUp.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestSuccessListener.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestSuite.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TestSuiteBuilderContext.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TextOutputter.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TextTestProgressListener.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TextTestResult.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TextTestRunner.cpp create mode 100644 UnitTests/cppunit/src/cppunit/TypeInfoHelper.cpp create mode 100644 UnitTests/cppunit/src/cppunit/UnixDynamicLibraryManager.cpp create mode 100644 UnitTests/cppunit/src/cppunit/Win32DynamicLibraryManager.cpp create mode 100644 UnitTests/cppunit/src/cppunit/XmlDocument.cpp create mode 100644 UnitTests/cppunit/src/cppunit/XmlElement.cpp create mode 100644 UnitTests/cppunit/src/cppunit/XmlOutputter.cpp create mode 100644 UnitTests/cppunit/src/cppunit/XmlOutputterHook.cpp create mode 100644 VERSION create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100755 autogen.sh create mode 100644 autom4te.cache/output.0 create mode 100644 autom4te.cache/output.1 create mode 100644 autom4te.cache/requests create mode 100644 autom4te.cache/traces.0 create mode 100644 autom4te.cache/traces.1 create mode 100755 build/Info.plist create mode 100644 build/autoexp_dat.txt create mode 100644 build/bullet.rc create mode 100644 build/bullet_ico.ico create mode 100644 build/findDirectX11.lua create mode 100644 build/findOpenCL.lua create mode 100755 build/fruitstrap_osx create mode 100644 build/icon.png create mode 100755 build/ios_build.sh create mode 100755 build/ios_run.sh create mode 100644 build/premake4.exe create mode 100644 build/premake4.lua create mode 100755 build/premake4_linux create mode 100755 build/premake4_osx create mode 100644 build/vs2005.bat create mode 100644 build/vs2008.bat create mode 100644 build/vs2010.bat create mode 100644 build/vs2010_dx11.bat create mode 100644 build/vs2010_opencl.bat create mode 100644 build/vs_all.bat create mode 100644 bullet.pc.cmake create mode 100644 bullet.pc.in create mode 100644 bullet_logo.png create mode 100755 compile create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100644 convex0.bin create mode 100755 depcomp create mode 100644 docs/BulletQuickstart.pdf create mode 100644 docs/BulletQuickstart.tex create mode 100644 docs/building.tex create mode 100644 docs/bullet_logo_2010_9.eps create mode 100644 docs/faq.tex create mode 100644 docs/helloworld.tex create mode 100644 docs/intro.tex create mode 100644 docs/titlepic.sty create mode 100644 file.obj create mode 100644 glut64.dll create mode 100644 heightfield128x128.raw create mode 100755 install-sh create mode 100644 jenga.dae create mode 100644 lib/readme.txt create mode 100755 ltmain.sh create mode 100755 missing create mode 100644 src/Bullet-C-Api.h create mode 100644 src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btAxisSweep3.h create mode 100644 src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h create mode 100644 src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h create mode 100644 src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h create mode 100644 src/BulletCollision/BroadphaseCollision/btDbvt.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btDbvt.h create mode 100644 src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h create mode 100644 src/BulletCollision/BroadphaseCollision/btDispatcher.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btDispatcher.h create mode 100644 src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h create mode 100644 src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h create mode 100644 src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h create mode 100644 src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h create mode 100644 src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp create mode 100644 src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h create mode 100644 src/BulletCollision/CMakeLists.txt create mode 100644 src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp create mode 100644 src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h create mode 100644 src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionObject.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionObject.h create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btCollisionWorld.h create mode 100644 src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h create mode 100644 src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btGhostObject.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btGhostObject.h create mode 100644 src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h create mode 100644 src/BulletCollision/CollisionDispatch/btManifoldResult.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btManifoldResult.h create mode 100644 src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h create mode 100644 src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h create mode 100644 src/BulletCollision/CollisionDispatch/btUnionFind.cpp create mode 100644 src/BulletCollision/CollisionDispatch/btUnionFind.h create mode 100644 src/BulletCollision/CollisionShapes/btBox2dShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btBox2dShape.h create mode 100644 src/BulletCollision/CollisionShapes/btBoxShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btBoxShape.h create mode 100644 src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h create mode 100644 src/BulletCollision/CollisionShapes/btCapsuleShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btCapsuleShape.h create mode 100644 src/BulletCollision/CollisionShapes/btCollisionMargin.h create mode 100644 src/BulletCollision/CollisionShapes/btCollisionShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btCollisionShape.h create mode 100644 src/BulletCollision/CollisionShapes/btCompoundShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btCompoundShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConcaveShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConcaveShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConeShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConeShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConvex2dShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConvex2dShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConvexHullShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConvexHullShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConvexInternalShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConvexPolyhedron.h create mode 100644 src/BulletCollision/CollisionShapes/btConvexShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConvexShape.h create mode 100644 src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h create mode 100644 src/BulletCollision/CollisionShapes/btCylinderShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btCylinderShape.h create mode 100644 src/BulletCollision/CollisionShapes/btEmptyShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btEmptyShape.h create mode 100644 src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h create mode 100644 src/BulletCollision/CollisionShapes/btMaterial.h create mode 100644 src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h create mode 100644 src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btMultiSphereShape.h create mode 100644 src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h create mode 100644 src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp create mode 100644 src/BulletCollision/CollisionShapes/btOptimizedBvh.h create mode 100644 src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h create mode 100644 src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h create mode 100644 src/BulletCollision/CollisionShapes/btShapeHull.cpp create mode 100644 src/BulletCollision/CollisionShapes/btShapeHull.h create mode 100644 src/BulletCollision/CollisionShapes/btSphereShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btSphereShape.h create mode 100644 src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btStaticPlaneShape.h create mode 100644 src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp create mode 100644 src/BulletCollision/CollisionShapes/btStridingMeshInterface.h create mode 100644 src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btTetrahedronShape.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp create mode 100644 src/BulletCollision/CollisionShapes/btTriangleBuffer.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleCallback.cpp create mode 100644 src/BulletCollision/CollisionShapes/btTriangleCallback.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp create mode 100644 src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp create mode 100644 src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleInfoMap.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleMesh.cpp create mode 100644 src/BulletCollision/CollisionShapes/btTriangleMesh.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btTriangleMeshShape.h create mode 100644 src/BulletCollision/CollisionShapes/btTriangleShape.h create mode 100644 src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp create mode 100644 src/BulletCollision/CollisionShapes/btUniformScalingShape.h create mode 100644 src/BulletCollision/Doxyfile create mode 100644 src/BulletCollision/Gimpact/btBoxCollision.h create mode 100644 src/BulletCollision/Gimpact/btClipPolygon.h create mode 100644 src/BulletCollision/Gimpact/btContactProcessing.cpp create mode 100644 src/BulletCollision/Gimpact/btContactProcessing.h create mode 100644 src/BulletCollision/Gimpact/btGImpactBvh.cpp create mode 100644 src/BulletCollision/Gimpact/btGImpactBvh.h create mode 100644 src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp create mode 100644 src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h create mode 100644 src/BulletCollision/Gimpact/btGImpactMassUtil.h create mode 100644 src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp create mode 100644 src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h create mode 100644 src/BulletCollision/Gimpact/btGImpactShape.cpp create mode 100644 src/BulletCollision/Gimpact/btGImpactShape.h create mode 100644 src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp create mode 100644 src/BulletCollision/Gimpact/btGenericPoolAllocator.h create mode 100644 src/BulletCollision/Gimpact/btGeometryOperations.h create mode 100644 src/BulletCollision/Gimpact/btQuantization.h create mode 100644 src/BulletCollision/Gimpact/btTriangleShapeEx.cpp create mode 100644 src/BulletCollision/Gimpact/btTriangleShapeEx.h create mode 100644 src/BulletCollision/Gimpact/gim_array.h create mode 100644 src/BulletCollision/Gimpact/gim_basic_geometry_operations.h create mode 100644 src/BulletCollision/Gimpact/gim_bitset.h create mode 100644 src/BulletCollision/Gimpact/gim_box_collision.h create mode 100644 src/BulletCollision/Gimpact/gim_box_set.cpp create mode 100644 src/BulletCollision/Gimpact/gim_box_set.h create mode 100644 src/BulletCollision/Gimpact/gim_clip_polygon.h create mode 100644 src/BulletCollision/Gimpact/gim_contact.cpp create mode 100644 src/BulletCollision/Gimpact/gim_contact.h create mode 100644 src/BulletCollision/Gimpact/gim_geom_types.h create mode 100644 src/BulletCollision/Gimpact/gim_geometry.h create mode 100644 src/BulletCollision/Gimpact/gim_hash_table.h create mode 100644 src/BulletCollision/Gimpact/gim_linear_math.h create mode 100644 src/BulletCollision/Gimpact/gim_math.h create mode 100644 src/BulletCollision/Gimpact/gim_memory.cpp create mode 100644 src/BulletCollision/Gimpact/gim_memory.h create mode 100644 src/BulletCollision/Gimpact/gim_radixsort.h create mode 100644 src/BulletCollision/Gimpact/gim_tri_collision.cpp create mode 100644 src/BulletCollision/Gimpact/gim_tri_collision.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btConvexCast.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btPointCollector.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h create mode 100644 src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp create mode 100644 src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h create mode 100644 src/BulletCollision/premake4.lua create mode 100644 src/BulletDynamics/CMakeLists.txt create mode 100644 src/BulletDynamics/Character/btCharacterControllerInterface.h create mode 100644 src/BulletDynamics/Character/btKinematicCharacterController.cpp create mode 100644 src/BulletDynamics/Character/btKinematicCharacterController.h create mode 100644 src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btConstraintSolver.h create mode 100644 src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btContactConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h create mode 100644 src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btGearConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btHingeConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btJacobianEntry.h create mode 100644 src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h create mode 100755 src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp create mode 100755 src/BulletDynamics/ConstraintSolver/btSliderConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btSolverBody.h create mode 100644 src/BulletDynamics/ConstraintSolver/btSolverConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btTypedConstraint.h create mode 100644 src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp create mode 100644 src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h create mode 100644 src/BulletDynamics/Dynamics/Bullet-C-API.cpp create mode 100644 src/BulletDynamics/Dynamics/btActionInterface.h create mode 100644 src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp create mode 100644 src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h create mode 100644 src/BulletDynamics/Dynamics/btDynamicsWorld.h create mode 100644 src/BulletDynamics/Dynamics/btRigidBody.cpp create mode 100644 src/BulletDynamics/Dynamics/btRigidBody.h create mode 100644 src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp create mode 100644 src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h create mode 100644 src/BulletDynamics/Vehicle/btRaycastVehicle.cpp create mode 100644 src/BulletDynamics/Vehicle/btRaycastVehicle.h create mode 100644 src/BulletDynamics/Vehicle/btVehicleRaycaster.h create mode 100644 src/BulletDynamics/Vehicle/btWheelInfo.cpp create mode 100644 src/BulletDynamics/Vehicle/btWheelInfo.h create mode 100644 src/BulletDynamics/premake4.lua create mode 100644 src/BulletMultiThreaded/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ApplyForces.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ComputeBounds.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/Integrate.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/OutputToVertexArray.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/PrepareLinks.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositions.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositionsSIMDBatched.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateConstants.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNodes.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNormals.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositions.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositionsFromVelocities.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/VSolveLinks.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocities.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocitiesSIMDBatched.hlsl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverBuffer_DX11.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11SIMDAware.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverTriangleData_DX11.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexBuffer_DX11.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexData_DX11.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.cpp create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.cpp create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/premake4.lua create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/premake4.lua create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Apple/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/premake4.lua create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/MiniCLTaskWrap.cpp create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/CMakeLists.txt create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/premake4.lua create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ApplyForces.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ComputeBounds.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/Integrate.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/OutputToVertexArray.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/PrepareLinks.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocities.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositions.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositionsSIMDBatched.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateConstants.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateFixedVertexPositions.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNodes.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNormals.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositions.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositionsFromVelocities.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/VSolveLinks.cl create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCL.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCLSIMDAware.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.cpp create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverTriangleData_OpenCL.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexData_OpenCL.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.cpp create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.cpp create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h create mode 100644 src/BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h create mode 100644 src/BulletMultiThreaded/HeapManager.h create mode 100644 src/BulletMultiThreaded/PlatformDefinitions.h create mode 100644 src/BulletMultiThreaded/PosixThreadSupport.cpp create mode 100644 src/BulletMultiThreaded/PosixThreadSupport.h create mode 100644 src/BulletMultiThreaded/PpuAddressSpace.h create mode 100644 src/BulletMultiThreaded/SequentialThreadSupport.cpp create mode 100644 src/BulletMultiThreaded/SequentialThreadSupport.h create mode 100644 src/BulletMultiThreaded/SpuCollisionObjectWrapper.cpp create mode 100644 src/BulletMultiThreaded/SpuCollisionObjectWrapper.h create mode 100644 src/BulletMultiThreaded/SpuCollisionTaskProcess.cpp create mode 100644 src/BulletMultiThreaded/SpuCollisionTaskProcess.h create mode 100644 src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp create mode 100644 src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h create mode 100644 src/BulletMultiThreaded/SpuDoubleBuffer.h create mode 100644 src/BulletMultiThreaded/SpuFakeDma.cpp create mode 100644 src/BulletMultiThreaded/SpuFakeDma.h create mode 100644 src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp create mode 100644 src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h create mode 100644 src/BulletMultiThreaded/SpuLibspe2Support.cpp create mode 100644 src/BulletMultiThreaded/SpuLibspe2Support.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h create mode 100644 src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/readme.txt create mode 100644 src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp create mode 100644 src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h create mode 100644 src/BulletMultiThreaded/SpuSampleTask/readme.txt create mode 100644 src/BulletMultiThreaded/SpuSampleTaskProcess.cpp create mode 100644 src/BulletMultiThreaded/SpuSampleTaskProcess.h create mode 100644 src/BulletMultiThreaded/SpuSync.h create mode 100644 src/BulletMultiThreaded/TrbDynBody.h create mode 100644 src/BulletMultiThreaded/TrbStateVec.h create mode 100644 src/BulletMultiThreaded/Win32ThreadSupport.cpp create mode 100644 src/BulletMultiThreaded/Win32ThreadSupport.h create mode 100644 src/BulletMultiThreaded/btGpu3DGridBroadphase.cpp create mode 100644 src/BulletMultiThreaded/btGpu3DGridBroadphase.h create mode 100644 src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedCode.h create mode 100644 src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedDefs.h create mode 100644 src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedTypes.h create mode 100644 src/BulletMultiThreaded/btGpuDefines.h create mode 100644 src/BulletMultiThreaded/btGpuUtilsSharedCode.h create mode 100644 src/BulletMultiThreaded/btGpuUtilsSharedDefs.h create mode 100644 src/BulletMultiThreaded/btParallelConstraintSolver.cpp create mode 100644 src/BulletMultiThreaded/btParallelConstraintSolver.h create mode 100644 src/BulletMultiThreaded/btThreadSupportInterface.cpp create mode 100644 src/BulletMultiThreaded/btThreadSupportInterface.h create mode 100644 src/BulletMultiThreaded/vectormath2bullet.h create mode 100644 src/BulletSoftBody/CMakeLists.txt create mode 100644 src/BulletSoftBody/btDefaultSoftBodySolver.cpp create mode 100644 src/BulletSoftBody/btDefaultSoftBodySolver.h create mode 100644 src/BulletSoftBody/btSoftBody.cpp create mode 100644 src/BulletSoftBody/btSoftBody.h create mode 100644 src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp create mode 100644 src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h create mode 100644 src/BulletSoftBody/btSoftBodyData.h create mode 100644 src/BulletSoftBody/btSoftBodyHelpers.cpp create mode 100644 src/BulletSoftBody/btSoftBodyHelpers.h create mode 100644 src/BulletSoftBody/btSoftBodyInternals.h create mode 100644 src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp create mode 100644 src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h create mode 100644 src/BulletSoftBody/btSoftBodySolverVertexBuffer.h create mode 100644 src/BulletSoftBody/btSoftBodySolvers.h create mode 100644 src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp create mode 100644 src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h create mode 100644 src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp create mode 100644 src/BulletSoftBody/btSoftRigidDynamicsWorld.h create mode 100644 src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp create mode 100644 src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h create mode 100644 src/BulletSoftBody/btSparseSDF.h create mode 100644 src/BulletSoftBody/premake4.lua create mode 100644 src/CMakeLists.txt create mode 100644 src/LinearMath/CMakeLists.txt create mode 100644 src/LinearMath/btAabbUtil2.h create mode 100644 src/LinearMath/btAlignedAllocator.cpp create mode 100644 src/LinearMath/btAlignedAllocator.h create mode 100644 src/LinearMath/btAlignedObjectArray.h create mode 100644 src/LinearMath/btConvexHull.cpp create mode 100644 src/LinearMath/btConvexHull.h create mode 100644 src/LinearMath/btConvexHullComputer.cpp create mode 100644 src/LinearMath/btConvexHullComputer.h create mode 100644 src/LinearMath/btDefaultMotionState.h create mode 100644 src/LinearMath/btGeometryUtil.cpp create mode 100644 src/LinearMath/btGeometryUtil.h create mode 100644 src/LinearMath/btGrahamScan2dConvexHull.h create mode 100644 src/LinearMath/btHashMap.h create mode 100644 src/LinearMath/btIDebugDraw.h create mode 100644 src/LinearMath/btList.h create mode 100644 src/LinearMath/btMatrix3x3.h create mode 100644 src/LinearMath/btMinMax.h create mode 100644 src/LinearMath/btMotionState.h create mode 100644 src/LinearMath/btPolarDecomposition.cpp create mode 100644 src/LinearMath/btPolarDecomposition.h create mode 100755 src/LinearMath/btPoolAllocator.h create mode 100644 src/LinearMath/btQuadWord.h create mode 100644 src/LinearMath/btQuaternion.h create mode 100644 src/LinearMath/btQuickprof.cpp create mode 100644 src/LinearMath/btQuickprof.h create mode 100644 src/LinearMath/btRandom.h create mode 100644 src/LinearMath/btScalar.h create mode 100644 src/LinearMath/btSerializer.cpp create mode 100644 src/LinearMath/btSerializer.h create mode 100644 src/LinearMath/btStackAlloc.h create mode 100644 src/LinearMath/btTransform.h create mode 100644 src/LinearMath/btTransformUtil.h create mode 100644 src/LinearMath/btVector3.cpp create mode 100644 src/LinearMath/btVector3.h create mode 100644 src/LinearMath/premake4.lua create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/MiniCL/CMakeLists.txt create mode 100644 src/MiniCL/MiniCL.cpp create mode 100644 src/MiniCL/MiniCLTask/MiniCLTask.cpp create mode 100644 src/MiniCL/MiniCLTask/MiniCLTask.h create mode 100644 src/MiniCL/MiniCLTaskScheduler.cpp create mode 100644 src/MiniCL/MiniCLTaskScheduler.h create mode 100644 src/MiniCL/cl.h create mode 100644 src/MiniCL/cl_MiniCL_Defs.h create mode 100644 src/MiniCL/cl_gl.h create mode 100644 src/MiniCL/cl_platform.h create mode 100644 src/btBulletCollisionCommon.h create mode 100644 src/btBulletDynamicsCommon.h create mode 100644 src/vectormath/neon/boolInVec.h create mode 100644 src/vectormath/neon/floatInVec.h create mode 100644 src/vectormath/neon/mat_aos.h create mode 100644 src/vectormath/neon/quat_aos.h create mode 100644 src/vectormath/neon/vec_aos.h create mode 100644 src/vectormath/neon/vectormath_aos.h create mode 100644 src/vectormath/scalar/boolInVec.h create mode 100644 src/vectormath/scalar/floatInVec.h create mode 100644 src/vectormath/scalar/mat_aos.h create mode 100644 src/vectormath/scalar/quat_aos.h create mode 100644 src/vectormath/scalar/vec_aos.h create mode 100644 src/vectormath/scalar/vectormath_aos.h create mode 100644 src/vectormath/sse/boolInVec.h create mode 100644 src/vectormath/sse/floatInVec.h create mode 100644 src/vectormath/sse/mat_aos.h create mode 100644 src/vectormath/sse/quat_aos.h create mode 100644 src/vectormath/sse/vec_aos.h create mode 100644 src/vectormath/sse/vecidx_aos.h create mode 100644 src/vectormath/sse/vectormath_aos.h create mode 100644 src/vectormath/vmInclude.h create mode 100644 test1.oec diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..f2cc86d --- /dev/null +++ b/AUTHORS @@ -0,0 +1,22 @@ + +Bullet Physics Library is an open source project with help from the community at the Physics Forum +See the forum at http://bulletphysics.com + +The project was started by Erwin Coumans + +Following people contributed to Bullet +(random order, please let us know on the forum if your name should be in this list) + +Gino van den Bergen: LinearMath classes +Christer Ericson: parts of the voronoi simplex solver +Simon Hobbs: 3d axis sweep and prune, Extras/SATCollision, separating axis theorem + SIMD code +Dirk Gregorius: generic D6 constraint +Erin Catto: accumulated impulse in sequential impulse +Nathanael Presson: EPA penetration depth calculation +Francisco Leon: GIMPACT Concave Concave collision +Joerg Henrichs: make buildsystem (work in progress) +Eric Sunshine: jam + msvcgen buildsystem +Steve Baker: GPU physics and general implementation improvements +Jay Lee: Double precision support +KleMiX, aka Vsevolod Klementjev, managed version, rewritten in C# for XNA +Erwin Coumans: most other source code diff --git a/BspDemo.bsp b/BspDemo.bsp new file mode 100644 index 0000000000000000000000000000000000000000..4ed414d75b92d4d94b05589c46bc8f66bee34686 GIT binary patch literal 105100 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 HQ-1y*qN~We literal 0 HcmV?d00001 diff --git a/BulletLicense.txt b/BulletLicense.txt new file mode 100644 index 0000000..2e5680a --- /dev/null +++ b/BulletLicense.txt @@ -0,0 +1,18 @@ +/* +Copyright (c) 2003-2010 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +Free for commercial use, please report projects in the forum at http://www.bulletphysics.org + +In case you want to display a Bullet logo in your software: you can download the Bullet logo in various vector formats and high resolution at the download section in http://bullet.googlecode.com diff --git a/Bullet_User_Manual.pdf b/Bullet_User_Manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..596241732184044bf31e290be8b03a9269cc5a97 GIT binary patch literal 1168019 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 z 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

LtkUCCGFAJ2V;ZHSiDPL{5gxB&J_E7X8A7n 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

%Ger)e&tuI}w6>S@oSxhSIT*6AwcifW;xCRfUA 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

X0u@yA=f6b4JN=lNp%hFwYE?lfVBw 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 z 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

    +81ejuOwdf{5)^F>~KTyJ7D`6GDL9SBLpsrx|) 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

  1. ;!LLRq%(QW>|^|2GmxKXY@SY@u{tYiYu1%PTcVVse|bwf7t~k z5;8z7wz)7RwM@sjX-xBFs$}oLxpLY~?!W^tv&Q#2MYH((zz{(wOv1Q+0zQ(@NT>7sMQI4FXr^~!O4yn9{{Wv98{+c>b}n#1|Q)V&V1?N_eyteS;} zPgjC5XFj3g9@5|BgpKt-EkQti;^`uD9Oz&|ilt9bu<0QS$GNcwdJp9pR+g zitn9gxoRqm4u$Ipaj`G}w!R*Tt(Ik^B;p$RWwW~4fL&2B1sLYgVTpkbeeq}|JT1AxV zJt}Lcvf}Gn#n;u|B3w=k+lRfanJEpp=N{&+x}X0obZMV$H%+1+N`D0MosIKWPy7{J zt1p4aHH=q1f%kWTlTLG15Z1~>;}r4xUz2`^KsBSo%SJBVCTvG;t=@u&IZd1vO2?AN z=<9&Ud@nMUklwl<0uGx>q_+!f#)}(nOy9*;NM}+d&yG@GGNp)?l=@P^DtzBWo~jlJ zBtm8%mo^fqi|zWE%dp%OncViF-esXF+O7qO88&p*`h%(eze)b`-h#xry0_`t=F{@_ z`r%3})i!khZS&>C{(hL;johqnvClIdb9E*A(Kq_MZTkn4`C2;C5@jW^;@X$jlME&8 zI7VqroXw&xWk1Wk{`U66 zhqnkgd9P4Yp9S2UKFCqMVSQd+ZSeH)0F1$4sZQG?j>?b&8ihxin&PD2Y6rcJz%UZY zh~#$l!HZh??{$-L{3KKT?-vARTi~bkKj@3d+M(K%QhZ#zi=PWh()8nTWEF(($HG4^MM{&K9E z=o1Ep>Q)Bek;bveIrP5{ssBK}lO1y&=L*+f{VER>1yKnHhJ?sIa;dKdaXGNNipG$s zLE`8qw?^m&yMyR#5oBhCiIiGSKvm#Qj0gCrDxM-7lY)wM7D%)oi_sW%$&VZ!SYZfW zXOTD8kvUf0BZ7!R7_ch)?aVb1pIDq~Sc`n`?_15!n|Ra)3TsE)()>rPD5otm6wnM- zd?kubhg zhHX)JueCRH+zL<2g-F@b(EXcG@6@TV@B!gH`y@Xq$z1YIs%~G@Ued?5hkN_w9ToB1>pZyhpixQYDrvTcYz6*{zVGdG6ND}N0S9nwU-%_I{fb|( zGznQ9WS)7VvTSG>q+a7teaA+ACcK^5}5B^hWVaP8U#o1);QKb?=v zGv2xmuKjD*4iD|YtFfACJmj-+&|9>*h(-sv{jEIsd(Dz-=EUtbOripQ@6b}E_C4EB zC;k(*6ERNgFl6o0+jcK1cwNLYBq;pB7feZ-xL5BGNx$Hk;#LvMBGtngd~xXXpu(Jk z&qEaXfge1hLnWJ5@ZsT zC`oq0QiZ0A*^7wUNn*-Yg{AxVD`-j^hhUGuk67GEV9HXZ#D*nm|Fj+GGN%N0N1?a2 zJa0Nl_T%-6f;JL_@X7)YHo!O+t5!vsYbqhr)gBS-kB@TCjCG|&1}hb;Ixwy`%xQ@8pq4T$V|GLw z;$3jHo*a3bceRpCvq&Og)s!N&ZLUlddaF;i{n^Jzqtd$HY$ZO@TZMgFxM>U_@oQ7m zRekaSd67D&i8tYSq9>PxUdZiWNhde(-3iYd^v$AGgxetXjwW_hlp^1uYf|Y|hceYq zBc3E=WmkOtp~;MfA2ocdgT9CLL1b97UoSn2R^#QKbK5en7ZWbz5W@JdWk7KD^=RgZ zV3`*CzSj^qi*2m^Z`I3@E`@~snFTbF&Dl#<+2Hm_DkkKgZ)YrN-6SfOBPZqVQ5Ad3 zs0{jWEpi#(s))Z&Rv=efh+cb{_Q->?fKT^^)4UQH{TLqoSO7%nSxU>uMXp{`oT;Y} zF1bJtaLDJgoyM5r=+{Fq`jR%=$%lQE&9T31QchsuJkG`3zi;`Fdp$5mlB-S4Cy09f zT{I(q-JTafsKALeP?QKsV1-N}&IP?9>qNhSlXwGXNEJmRZBl|J;>B*i*2I{P3tN4a zkP!6~+69XKCPs?t%m4Pu{vB*ycCPkEl{Kx|xJ>uI-(X)OJ7@f(s*T3XPP!W!@y!7r zRfPF1zvep_J){r9r%xV~r@16upo?*6l%r1N!VZvZaXGfwr4c+ajPbuIMxLbNg4{@uy^|@`)jeV96HKJ1*D&Bh3hQ^%l~m&V5MTi=geG0B zu*a2hx$=I`7(U@0P(_qo$OR9|p8b-@H?2sB^q#^whs9q6`bfcyGqzIab=X1Lf<&g| zQ+Pp0XwFuZ%7xa#ac^P^GvP25UvWr^K*Tr4q*8rPzOm4bQyYe3=8wo*()X0e0x!h2Jrqw zO|APKmsw2X-GRW{0+5|^z4oC@dv11%@<1XvdT_u^^y}MTx&yNC-)ccq=v>3hl1eX=z`yU3B@(}o{DTX;DLr*4238U#OuJlb4o~tEsY9bYn((dzUTH~seY065iuTZUXt2st7X(f&nB;JDD+&@=y^fejU#lBR1Q45&@h-Hy0*~xFn zGTieyK7S_xhn(I2?h>r#8n~AXw~juO|J_A%f##Oys3a;V!)*wFBg?hqh;OINHn-&; z=50M{|EY>*dAjEbl}kFO>(8DF(3X!crtvKCRrow#jjjfBKf{n5=cy(l@LDSMuhCX4 zlZ%xhHI7$Jgy{9TEFNB9(~u9&x<*GaIJ?sFR;h|-s6i}b^%$l$|jcI;-IOP$1zurJTL7&H;t%@HpDL%OFJJ+ z8*lC4p{fe@?LBue{Cd>iI6)6s@tiy|g$Hv#cij$@hjF#V#7+FkRRpl|X~zl%Sd?g_q0N#9Z04!olmslvX+ zxw1&+FsA^DBr35hBAMRDe)4F z>le#C(0ZjHYJPKN%81+?796-RpI=4BHk8%;g0z>h+f~z_4_%iU^tqw?Gv+Lv|g{&4WAaDFIP{7 z3#4uiRY~p_9A~0&J^UoT6w@u9DTGcJo1ssFTjx7%gp5sI zDWz3?jyTk8JOfsYxXD9<1#No6!7kbCpQ>+F;&cxc77UE072*W5$%9d-`Q$ouyb+8x zU9H;Arla{K$CI29Iud@(63E}&YKe>+TXPN~r3OrFYTRY`2T{XI2ItRnQ|XIq#f*zn zM{fqfyI!v16F9f4B)d{|(L`9+WN9X^m>oQl1bOcA<0c{3lImC$cs(npzg%{gHBBlb zIxFt$?^!PGCmRoM!YWBBC0-q@o09%fX`WRgzgH%i(g?0%9wO|q31IPKJ<=;;DRKy| zHw^xr>bd>p>FC~Q9%qhbaQ-xTOJK0Odij(!?2hXBzCF$lll`T8uE1t!&&CL;d+lL` znAl#HFOzBo3k2UiTWz_#zYbb+705Q@YRtGs?g-h8I9f|^{h{#ya3v9W_~eyZY5}zE zp(Q()emKi-cuRhZZ5{KS_EmIl0=ASyT7%+1(}OM#$X=nxmecj-5&93hUe(98ABG>_ z?dow>gdzkVFuWpK7h{`JqPibsypmcc_3dkLg3iUg{^Hu$*SUqSgR&kJ9OAM}&7+hb zd|z@~rv+)H`KjOLuuM!*Rz>+4b;eP5u{?^->9-P=$Ib>j>ch@Si^ueD%&r5@>EOaG z9cu~cyW{)!nXiioNu|P1ZWKIfQb|eT(IQtJqY25ollJzVcKMzHy`=|6H1;cu+q}iP zX?zndM@GpMBu5noXrIzv<$jDZ?cUpoekB$ctszcRXw zo9u?G#SSBK&s}RJWz9}mRJ7mv-^OF@L^}*=H)RfI4p;I{VNPMH>zN1MMgyij<~`=E zwmU(cCLGRNPFpSbJS03MTJl*ZQ(Wq7=GAOKs}p*MWX%-r@k~>7Yx9uXD3`K^HR;+l zZtEGJU25&+w1@o&KGk+8){3>z#p)K^A&P zpmUIo-X-V)WVg8uIssX_fFB+nnmyfLJYTf9JmK8ow7NR`JIN~rw-UAzma4kJ-X9Im z&w^kdJCy6mtI68XXR~KBt$uGOZ>LK1?n`f=PRq;T)1el*50Vd36`zl+w`^sHx2#Xy z(q{K!_uG<>?>dQD*G|oWy@kXR!IO^W{A~6af_3ssHBw)npe1 zJpO~7E*Dn$KH4By%ThbqKpKy~aw3iT3zk)29f~J_Us2o8&#=c_V_WGv@Glnk;UDvs zGnamT4?7C3KBt+gy`}qat@oR-*`nYtEp_sCsx4&<8;5o}>yGOkSs)oZ9IzE%AL!Jz z!Mbg^V|m?W^Wp;1KCmUlD{6BFbcEWR(I&Q;=St_+>eb;B!8g~n+&w`Aif!g=t+T7# zoYmWTw=y^x>No>cZ2aOH?4H^@FJ9Z+w7uYbk>r|`Z}4hAxnS%_$pBr{*&}oao~w8G zX@1m_K4ck@_g&OpB3*vl8uayVb&Gh98+m`jibz)$cvj_Xk_F{Ie=|O! zAiw+eJL5DDyKMUF7>kBmsXVtGT9JSznOkh=*kE@HH*4oFBLCs>N=r1u2ZSS?MfEh`-0E+$t(P>!7HJ1x%GE;a3pzmld%^iBar}E$`;W zX;~#bW4WwU?2e-9jS5m6oU*PPR+M$2`jA-t-Lw*{eA-@Iz&JrOn%0m4d{NP__>kp0 zv{zT+l8^dDxSW}Lk(0X(k@RyWELt!f;m$o#S+ITgvlx)eAELQ@S#nc$|G z%NxgiJ&V}UqUKb+?&siUNz<{Vy+C4v*nB^b;P4!jdFL8(>*@%6y|MOhG(84e8{60} z;)g@3#VaQ#Irt0nk5%Ss%jF5D?MiELGW))qcV0KRqn7Xja2+`o7;iXxrv!H#jn0&lVVsP) z63%5>=oYf$)CkC#qIe7al`wba{j0w{zhOU4vP-USu`B3o-r@G702Mz1-#Qb9ZYTM( zvO}@5BrrWtf$~gNI_dg{VUI?hNhAkSmVcUyPI}goi@6#ZScX_NcRNu4!rN}M%qN)Q};=Sgk0 z=!k0Wy=c#Bw(f{>g$(K;UY@m!{7s0ELqv2%?=N2OZu*$bQ{HQ^N7LqDA4F&&Oh6*r z0lm7`x?W{@bB8A8ir%oMtfsEu(mH|@ZLNrcX$dXCsW>;sDtt+-YFvynJ~vKnM;4_5 zn`@0zo)dZp(DIQNfhq+r_?OGj&W{oOHiu`k^41HLmG&bL1ewr_FuF0x_=QwOd;}CYzx(_xDI>n z-;A=NEO2QKUnDx8ranh{3M|AlvR;n{l~hZzw%5wd&EHgW%rsn2euCeZ$-2wqg@y2fJA-C*I*VH# z?`dJ$Zd~uunD5d$N&`A|w#0TE6A2|^4!Vvdu;iJ_Ej-c1nDE1N<3_0x4rzFZSro@h zBE}JJ@P0nEymHC-Vhc>hWj~PYr&Cjry-Pfi&GiI#AEkE>-=)LNby5IBH{AAr>Bjs~ z4)-wVj?+~=P%C^=@{LZlbi}v1iFk!(InLRif5SYGOPNow4$TaBOmn0hOQSF+J>cg- zW4S$u8zF!^zKDvnZ`?S6@x*qDM`toiIey@{K&xLZV!J$sLd^!S6MF`+qEKAM<54rH z9xC~?>0C%;?2iIT&;0p+q8yMSWFsU-`5vk+(@>Q)$Lm8N+sJ+x1%cu>F?@? z{w8QanKQW1k7c*rZ2mdFWgGV!u7!NjxyHFhJYB)gyzpe#wRf>%qhb{8upRq)bHgqi z&TnUB6BKKL29_*`#y*o++}yg5S6c+_J&25DZ0dZk%i;UP0=3yojdu=9)4#dH9sAo} zDm~#MtMpdyLXY~$4on;@)m9Myt`F7^?)3?W1Cvs2ZX(d&*-<)z9NqHvZMfh}FI>S& zfXUDw>;x(>lc8##qwnRzQ4EF|BUi8Vf+0uLBlZUo*KRMvPZyH>eoe?nAz&17r{Pvo zqIXyFhr{g6klxlXTG}ew5ixSFjoj%i4~6Rrg{#0LuC#M!?z=KX=@0V7p6a9d2U{P& z9cyMN@bKLWdYHuqIhLs*r8mgOon$wZf~a=?Cn1OIGqNmiD1}~sM3M*NG>n%OaixWO zEr!rgoN}tszu!g(QM7?Cguy<2Qdk4REMF_Re)_8-gBLkBG&GR0#L$K0ki|L=d)GqY z&LY1uHe)9Zld)iSx8+u`Vyv)gov?1Lgl#<+yt{fic;goQP9i)OwlBslNJi4De4EbR zd5Cho2F>%CW!it4KXkUxTVK%L9RyRj+(`-9s6|frt8sb%M=(c?biZ}qRl0^kf@=Jk z-V?Dg`>=Gs!~54^pYKA#oo2k2snwx7+@w9w9T8tUd?=>qy47Ey*5;T+I{u#WD@y1nsc`S#O?1hDC-FabF|R9do2d_1Lnvy|>1Lij-d3m(wy1*u2&n;5-=#)WkgGZ088T{GiK(iE;4Flhs|TL7&3-rS7PfX- z30!d0SOD&)Hv=p5tV|NBv#37?cnh#8)MpfzQ{D^Hvz+YJa?0Z-?LS*}%o#?e#{yet z?q{^aw6ge1mlB)wb;_fin=sRHwfhl6@1B2Nm*20qcJsB0R=Iw^A5-ec{vk^wh$I~r zwKVy@Ay34ukK+Pw>!S2#q+YD3y~%Tw^v}UOG0FCt<950({ucZGYUNzL zUUvB+Q@srqYDzJ9rb!E}`j*_Iw-VFyFEzWtL z?8mdZk4X<<@iIHMDSD<|=+O95F+sRjyY!|cz`9tj)Ppw0dr*PY^o=8$g&&APe`ibm zaP)VMdUENY)RHXg@sMvM(^B$M&O=0x?Oxw@u9{{{;yGpkzrPxs+CX6y;;H$TPppws zO8wh3+%kwqbVtnMr0$^f0GC7ECzn|CSR*N9rXRiwmhKpegM@)ieiIJ+1Kxo^&f2Hu z9cN)BzEZoFrKGiyJ_%ZI*{2RgvRWwzc@^3d^)?J4>(#*dfu4rXR>)wE#c72M%^4%Fywi5Xv`)53-fp7Oa zjxw*pC~BAs-!S!2eA0@s(|()PGM%+0coL_o`r;KQo-OuF)A_ZpL8Y>Mc`nhaT1iKo zQfDr}y6U*GUoV}N2v}fpQSra{C25a&nT{d&?#*6xp1r(Fn*+1$JxUU89y|`G zKPghd3an~ z#Ji8%`nSj)o@XS^raf_Zk2}{x ztr;F0itc+s*(Zvn^l3EK8 zyaHCBu!l#;JncXWJSF)4P^9U5<+W;JI=1V)*(Uoc)ogVzs>Uvwt(uLSb@upZ->tI+ zHC`Ic0lXP`w&q;PfKvd&93hlV^~b)@rHwWaOnrthqAq&8hfi~n+z$A-yz$(%3dhF&RhhH+0HR=L}GkZRh$yKKPlt;RLu z=~kqET)PEz^f}5rx5$p_9YwSj=a$v+=V_tP1MhN`?j@gVDwt@HO<*3$HD$9#wEi>` zqXTx@JSMW>bU~K^ttxRSR6Rad90=?Jmz_g`xmJ(1s`l3lq*$~@**7qe8lZa#^)#6a|hw_ zc0wOJ=8%dZs>K3xqj(Nczrk|sa*oiWI|I#A@G~jjwYwjq1C>zP9_IFfHsyjkN^qtA zF;f!Y<*$muC)l#?W4=RzPgis5P0~IEf+5w1rJeCbGlA*&zTG2*5j@~xr6?9v#yR0P zkPPxe)$oysRqhks&$m*6CboL*Oj=ohTHz@*0;gtiwg!?v!YR)!f!^H(b7M%_-QJk; zbe&aZ`ZrHMV&P-u^BPj$KW)5Hz4c1BSJ1KRr*`YQZPe8mhOwjr0bG`76z683yx@B<^?E<7 zMa>VJ)(4qBNz0la=SHBUV1fLuKeY~PbO;1B5U|{&f$$6!AaVg&$_8Z4t9A&@z8C_qpQ9YN#vF)J40hF=X|IW3*rklsPPHAx>$3AzdZ2NBnXWOW!WzSvu}Zo zOkcA}j`5D^QXjsMc?ZNnu}PSKV8nHcyZpl+){w$mRlGiEJn6 zzgC76bOVgjAGSyZ|5MJD_Qu;{c;#iuf^@t2lF|aRuKryTs}89=SgSz-9e0&qEd!st z8^JXKy&UF{6DMG{bGtgWmb7}{@vLNONVd?d#ovev=X?pR&90vqHI^W-K5UN2872lA z*aQU>_`(xsY_Di?>`*TE(Wf7hom)~yEB}c=9f}}S+2s~Yk6!sDwT=ezHcqcITgc=v z$06&6X{~SD8AC$R(6?x<57`;R{*YRI8s=~@`1tS(7tT>||H+uwoTd`69w}86Ia+$78o`F!^6baY~;Ih9t>C^oPnjrxT)N ziYyU3pIFBV#5NA3XF^u`5@Z4qJaq{?&Olb1Z>B4{W3@DiMr_pmQ(~cSs8Oo-70+6g zryb>7TAim~9WT7c+HPr%1Vc0Vkl$EXFAEYqNJ=IMq9$HskG1xJ!|{I8B7QOSuhgbH zQZz_ZO4tg8^n{`Gg#CX+4?`wQ6oUuI$eD_xU!hI+VMaz2MOEWdFlm^mRQ2`!J3FD% zO zZ&n7m4zn%-mHhrrqI+acN)Ug1_L6bVGESV-N*+0+*Zt*mY%^(-T##0f)~_O=V6I47 z64&r`@+BR-YLbpH2|aHqIOF|qAzgZsBo(&p9g&R0N>F^i{E!xD(Yx>|+>&FNeR+l4 z7{!on0NEOl!!!JjfcIKjdXYf^h!o2KbP+~0QXEjT5=kHjn(A=FFe!Rm*>R&w<% z^W~c#V*1cLb3a)({NB6=?~u?W8_T=aJAFofgFE)_^z~6{y7{dQY-mikH3?X z2cwzJ1dfRu@pONi>>~!`@2uagOOD-y*I&9Z$PM!sZJz;&yg zL2lc2Z~Xq?xxp6WY>lUiR3idlC|>g|DD`9fb)36BXpc#zvYuYDvfhSNeYK`RqBFy- zfxWT`DBc+cu5EkOdHp1NV1LD>iG6v{<=*$!N%E}c`!xqg-8eHO2{$qcch7IYFBmWM zDGt5YGde*t4*dg0C}xE36O+4$0q*kE2o>m>a)J86f%~BmnX%m>X8CDG^u=6%knd1CevTLs5@>Lj3>G zUs;Gn@@)WOeklA7_4pksnPTJ9*SqVWPb?UKn)>yK=kyufM}4!y4m??F)dsxOuDJ zKE3BO`3(W=EbMEG0!dfMn8i^u2p&XNkmx1jp>?Q#ei8in1@Vu6;E%5#-YZ8tHE251 zbG?`~wUxCoMg&^gD>(h#BiT?oiH4j$so4T}>iFu2B$>U~0c_nvWPRY!OH=;WvmJvl zAkh}e$Nkmv&Lt9XIv+aZ`_1^3wH(%a$ra5IOcZmHAv!jxX0SwngudvnMPz|-Eb%_p zz>Xd01m>jg7}Vj=&+<Co_=Id^)STMx<4J=&_ut6ydp*OGxP+}Whd1Uj~*Q;PaqTb0T{<{ z@_PO<8BL_V5?^@e5)boVj$>X4#S8s=l=i@QC)pP=oEpC|C4}Lrg9*&k#2q=o_Y!^o z`%2ZU+0FO?BS?*S9d{6y*K*L)@arko8}9mp0cb9LLq$!L^GPG5;m0O&)&z#jBN`cc zJA5;4AqQN7g&wjjcIRNFkV^4x6VB? zS!TB`m&aGWy+-CN(>2cS%k8)AxAY2Nf=&CcPgNIWW-nP6ZmndG$mmyive@23`OrBm zN!x7HkI`k&Id#;KF0c$qR_NEOh`Vf933xe&wci5}w*Ex44Ct3>a(RgDoOJ6me?ZTg~Y@kJIiI8k`5y53T;pvjOdlO zMHj(pKoiCCSpP31RPQ>%ui)TQqD8*%5+c60fFr;Wx*tv>SB|TlQ2BG#sQ~lAOF1~t z7{`s)rTM3_p86Yl0vdosRKhQc8`5p0^ts^_*1K+)Px@YC@tb$uJfGIR;-bK#aSzy} z{H0t`lMwW*0G}YLb~U(lS@=~R{uFBMbG9(wKTI*R;0fVhl;LbK;cP+SY=6TWxc6t{ zxd&j}ibLo>xiKP2!@3otyA_8Oh8Fe>3(c5|W}8k2{|e(r6QcSNCV+J#`jgRHq)0Jr zKR{+)G&z)h@HJ3oK3qyjmcKpO{jOo4z&b))!(YUW4ezc^@zu{Rkgs4-;FN2XKY!Zh z{_F8A%*>H=v*ug#GqR2ha{FtZ&k6ooN_BzHNrQ#KvsM0_X#Sk{TERO;oh51lH5Kf^ zKrZVn71eX}(#FijC+n?+S1fdqOs8;eqzG>E2=0Oi?jx%U>x&>zo`exZNlk3~d`{(-2=GU@lk zPePt@ZHh}n{Tt?*glcV1+�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πP6Rikks$j;6-FY=wQ$Zln)lX!Y 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%0Ayh}o zE&R^3*;?jLGZHgmH=)zWh4+DsfbKVaDNYH%E6E0K(`DQ~BY4g_eeY95s2}#vgYoV% z)AXbNV&xyh&>r`SK;GF25klE4D=%)~$~)!(_~%FgsON+MX3J0?r?ryrZb8AV>XrdHmk#JWS@ZdMK8~95OF{a* ziaC1@#LaH$L`M!--*14ZV<-BKCfB_kWC5w$!A63{J{b3iu@jZ&R}`QMmABK6Go!Po z*B*}BqyFaWEfoCGCYh=%JOq2h*wGW689^@Mnx^hA&DjA=wpgFF+t5>tO581&Pr-?| zZO@{$8qY*@3&+U)F{N;W@ShF+fP4uFH_0w#&UAt+oB%LX(OP zL*5W%Dh{3yB7^7e2=4=aWaY3H<*{+`I+zMuNlVB(^@eY+cQAhp)}p=18c||IQ(67x zRJ*0Do1~`4#?bxCT3~2<9o%v9!8m?y` zy#?RC+>PvB{;8P$J{M3`q_&wsq9C1_RR@z8EPKa+?iDOs+{8%AtrLlA=uv-=l_1Zp zfb|QZdUP$!WU6`1DfdpcdL&(!iS-}xm7+D*K+XkT-#^P}c#}Xrp07U9;(tD}s{plCTVa%JoOY}__ z!iR2#G)bTb?H?u(@0dX5NW0%)dPTifP?gofqjyKK69PU^cX?k(aQVKcN0EPuNI=jc zfH)-Mdl?Qkv<@Sa>yr<67y>}?@Ha)^>%b->$Y^<@$8x!ZrY9zFNmQ#Ed_J(Se+fBFw+eYHD^qFt=YmI1qcP=zhITu90&4@;<-dch9bRWV zbPj|EA||+Q0$Zm!@ZTWpYSd1BIkH>B$?Tr!`i=- z-Y^xtB~(v+9m(Cy32V7&aKn%j(*WbvWn%}k8sLP!ewk0I!0HDlY#0t+borlVIkJwDAWXE%*d6R zDqVBqM0cGfwCz@bQf&)nOvr`7JzG_`rL!gU63yr&kun>g$l$UmHb^j32V3XTi25mC;QRbDmcf+?Z%nfFhLjMLP)wY)6nDER<4HYyj5wQG1j{pSUjdC znMS^SB--{%#Yy4%_6BN(8s3*#Yfr>5oJnbSiTOgN$dfoKH3Qg zc4K!AIAdyLJ2^tN&+@+9_sz_FJz9(ymmT8%E` zWyY&Me7&T{oz0zg$8Of$ilY^D?BPKROro9i-6?@Vu9YeUgM37cU4)94Lcu! zZ9Sjfd^m$%|5`VI{hIzdi-E_MK9EI$Z}y^1&xaf&13FEaZ1Xe9f2dwDtg+)}l3YGX zfvVSUo>X#&03sb;__}~~i?Z<@hR4Rrw*Z81K1o;)R4^=I5@?(L& z-f*TZXql+-KK&iknL^-_`reaieyJ3_`O78Oxx;LNFHg*;VNz5k>oLhoOxiY`Gme^i z)A#OA!X-VE0I|N7yAlV+vIc%x&hUKfj{R$ozz*k?HI3Xd-5aEZQYwv3(T9^U_8R3}aqApa z3LWz^m*lg}_?P)HL@owZOzor>R5P4f-PV;kwE*>27*F}uc@|X%_2w^H2m0f_oke`m zs>zb{vJY}d(8q3Rd4dptOB z(;6;$AzlpvZhE+fC48^Vl^5w@oGagVH+&=DmLs}X>M0g}@upe_L&w>}c~8p6{YzzMlAU zOh`2~%>yrzo@7pZ>nS2k1jC(nTA2GYtMwx{(m}15iTxWab`h>mKM6z2{#`VZ56$94 z2d;gCPx(O?U^73vQEwXIaSushG@xX&rWJHVS04LeShQ;1Y{~_z1Ei^9Sn7ia_Br|U(Gf9qJ2KLzEb61(#r7t-5UvwQkp zH`^i8x74*Xt*hDe&Ic}9`>1LZ&Dq7#tyOG`ro2|{rZ=8fc&}yW8C1)v@jEiURuB!N zTBlMPvX}8Mmsa}G^8>%S{oJ<$D4qTQ8Jvb&^x{^=3QGs^K%`a4hw+85%Vj^LSEZlw z;agP7c1fL4yDee`Urk{-OlmA4(*tbj6*=>=jos#52DM8rpAxE)PoWHGq9<|~`?Udt zPx6{J*%Ah^$?k-Y2Rlx8*~AyPV~cP1V#BlHi=^(}i0a*}{GR7$WXmyrfi+k!DRl+O(3p@9)q4bhcv^QrfIJ^mwuk@iI8x}-EUiEZX;ei*y5gu*nWG^?Pto_ zA>hZl4kXtuo#6dbJGP$+kojmOFZFR!lQQdwj}tI2&-yb-bhIiF(c5bazgIknc3I&W z_|+Y)!!FxHX1l#NxFsDRE04j){^Yc!cUI9b+F+*V;mxnp#F+)LJ(L8F*b(B~*#$k0 zaz*QKW?}KSRAo-d=I{auj?Au4$i6iRIO^YI?MG&mK#l5J%~v_(R$68t7dffP$zI&) z%FSE}WOqN2qI(qcb zb6|OYYfU~(_zhOcJ*pgSCJ!J&+BbYLeHIU0Al{jfy4P$eMj-7uWg(C~y0s9WS~m_$ zgs@t+&JpjgLl1@W;^Hj3eqe7GW-!8r2JtHDsNaz>pOvlJ<1@PheVhVPfz7noJCY7XUna_e@)GY<+cIDUhB#KZN;Y|4_YiHstv?Z9JS| zG(CRAxfS$&9(>4~Bi5DYg#b#{ntbG=eBM0_%dfmMn~cjtHccJSXhS(q3wkei&-`Mu z5g(|f6UjT2I5>a#)WgU4FHzh3`YUvb=U_H&v>MNl*G4u3zzbXiL4WgV3cl)A@3N!E z+fi`j@!vEw$CH4Ek|EkKcOZd(kKQ+bM0a2y9Q5N8v4^;0H$GR-a!PC+JI0Euq$jKUe&k>~is0*MF5h zcba^-6dv=o!G2PuZ@PV>)+dDj{25#}{sQ4ra~kf3PIy_Pjn`;EePe@oz-I#J7kxDO z*4EDXuZC~>7Vpv@dEB854k904#(llNm!CqHV9zSZwA3r-9A~-`I`awcQfZmH@8hN; zb;~8LUjW5D{s`(V&}Ym=o2kv>OI-WW&mq=UEPiTF{V9W=o;QM`=JeVZ3w9iBla=ttS^P}`WjKEF?}(Ea9GzoYQ3%xm$mL(?Bw zmw+^18ZlRLgs`lcFGf?0Yz3M7)MOf;Kx}Qg0<$^NxiAyeer3H#u>z&V&AA1W+7dnj zlh%~02$s_0R*WTT^wTa-CO$aLi5JOXKD0ruiS8w4aiGY(i$zx09q;*YfCo3#$-^8;l6rz9-zr#F0OIyg7^E}WwW5?T~PA| z%XC`f>xIv+qUJTi-T}+k3%Fk$Dj41Brhm8|M$@k44x+cpKP#{lSNjGqsO->O=bBgO4t|J~45=M58qrnD1aSAa zR=iu_tf-v{!b!bOMjxWS(e1fY`$ycg-m4?bpWHsFm8=~+ax!;TGju=xc-7F+k=ceL}yOlz+u=&@UZ`ebq0YFes?@ciSFTzd7?_CI(*)iH$NxMoUEcjEGW%N#^Doz#`V;3^~ zJIhI-X3n(CD<6c0;d>AWD6J(Pq6oNc0sfN7R&=yj3)fWoB3 zhtb$?=8D}&h0x1N80!xWgzplPh-XV!JW`t_!2>h|ENkR#yp7wD;LSfaLq;XLql?TK z6By8}P#65Rab4@+tQ)isSj>2fqmxJh)3BxCM7ea0%|N z!C`UTUEJNB#oaZy1$TFMU)Sm^UURQU`Oig{N`}OO7p9gu`_@dNVv`KS} zaf@J@|7MXLGh{z%C^CVc#VM9+jye@|Fy$14hw5-B8U))ra_Au%w#9kl_iYWzdXu~5 z6?Bo4+!NN*5wRVOL;8#EZgxYW8u=#J;sY!u zdc}O463#KmfxBUub+{2OmOAFWkvtZi4aXLzQanT*@-`bDH^LT1CcV8By3UGftQ zSjG1#?+Cf@v;UN;g=eoJ8)#0|HiWJH4;vAt9B#ag6c_JryIz{#2Xc5Q5Kfo$Csc3C zr;ekr9Q;lMLt5_0w6`g!%S@c*(4?U@R|SFT4ATsgXr5(ny^#gm>vFxVMgN2>fwtU- z3d8Xr*IEc8N=_UoZ0^o4K>Z@#d*5q-8G1C&m-7bNl617Ts) zhl;JHocA{zi9jXE_cN$w3SwWZ8)Un8yJvecxcB3(^x4DsdawGX+W7{_ql%7>k%bYR zD!wU2AC;fv&Lcr&{Zfi*!Ul-_L?+!A6WbdSAO?HsA48Fktkom^O@oIC8;MG!*&Y{~ zVTh~w>$6%QbvFa-<|^D)uD$eMMqP|bq=f+KtrmMx&96y;={-zaXq!p)3hrMHNRgt& zzKf_*i?mUR)H8_8-UN(>d_@lZdQU7}qWMidlruV1d{<0sR*ZWVB)R`j{3m3Q?qlV~ z_&pXStarPZN8S`^S;x1Q*a0=lF5GR)LZ=Pgc0Z(byTkM=|JGZH`Crj8-wg)utO#iV zDSR1N)?AJoKE5EfUp-SazbF)$2ia-ScX@^pJaBQcS>o;yIzOw^JnU~8^<{bd|WLU$;>E5hfA*x&=iZ}9!@Bj`!g9?^k(h4h3@E`2DR!*ED>h(KPIs}zHM zgB7zd=?y0>E)4fb`vf?IzX5#up84`V9-YH^GeHaUsu1)0hJ_sRvlD(u1by-%`@-w+ zJzF6MCPqO8o}M@}Kg$1XglfX!9d5D1B0(~1XS^t`SYzs-c%gV<5^sQRKHTm4G^JIYbueY1 zw2{*?*;H&-N(4%8gSewH9)0(WPs=S-B;gc&B~C5jJ-&zyd_p)T`zrTJ*${%?V?d-DD{o)9+91Tj*y-d>kq|_GwIXV|VBAyHMi9rUH}~Na`KLvMu}g5wg5$ zi%9^1!r!Vb{r)l&$h|Rgf9?PBLwGp)`XfZI@Bqsd!waEzdgln>`u0cm(uaaQ_q%(z%$LoMG^DpV0|Jm3DaZZXfbP;v|7=WSG%^}szDNi4!1tUR2`Q(^; z>~(S*W-1%zJY3&_y;;nLfDY2j$PhqwSV(CI{Y~T-YQJs(v7}cnzfl&2(J4ec!4dUa zC00FAJzhQ8F!h$xS7&@@Y-i%(N+QTXOM?El+X;q}_#86_K^ftNA`~Q=ELGipRN7t< zG>a@xOa|`!2qg2jwr#%E5VrA1Iu(&A{xI)->I8xu?0S*0y~0G^oa2uNsN`ksnWH2I$`LMpNLg{h59oHoejg>_p$IUNgnj!rOhls8bNI|qIY8$2?`kRv*62lg zZ-;mYm`f>_;;HEI_l~u>J&ZqF8qlCvd7a0ao+7L+UG;6US>IB(0rVU+D6Y0 zjAHBfr}S7f3)V8&86lY?6WjZ?!1Pw0mvqRBAUAvZwR*Ygu<5d>tyFTk>e$U=J_i~n z>aD%Ux`127CvZ`8XZ_R&Qtq7K=6w-sk75?uJoFG@;dxpwz$1ZCIHVewM3^6m!gvca zIo0!=W9>F@`rRoDAw7{EI7Rq~*T;FiKyv+pIxy`;pMiy|rmm?(r3~nT{hFSggP-3IV-Mc+i397tV0+D<-~CKF$jeljv>?*j0W#=Hp?3R#$J z3+Sgc&=VqD`Fy*-1EOf$^@s;a#tRk#C|p$hPZ1$U<9u z#xBd`U>@uw~#@LDsZ zjicFdR$PG-#t?QyOu$vgh`569r zm?!?-EyvKv#C2F33MG=)T6MPiCuvL;0QyYYOTsA&+;lb(rat$5M~uAoty5*=1N}t> z%JZF{Cgf(W{ksnUo|!l~&r;8eLNKr3{u(TD%Q%ed(@ib06!0KK?-MKpH}^WR6z~TZ zFdh^;Pk)3)<|~p~vV?94{_1-pd_JRbraeq95c!kwVDeXf5N}5zw~NdXpzx^q5~@b8 zWM|U%#=5H^N}tGZUqkvRb;^zo+S%#2av&qPivN~4?nee|AO$3Q5IxGEBw*NLx^trY zl{h+1Fe)4BGArCytz&ezc{be0@RYOGiJa3mtTCtCRqM4uL| z`01Gs2kL!Z%I*boW{dKZ*2-E(&+(qJH!l>OUQWFl@)J)ByHp4pDG>b*hQuB_2;hAK zC1(Ox)s3I=Yh$CAM0Jzv{Z9;6U`-~!=IJ+VSaWRhHVWHBblqEe&*B$k_iOgerudA6 zj>X*=QPr}h{$uIl*VPEM{7rcY|BpllXhI!I*HuU-9l7*fo<9OHVYXjIM#4ns?tM74 z|Fg|WLWYDfa$;LQTe*8Ay*VL6Vs5`xL46JGicvvsta>RS9A><4yQ&o-&Xt~Q9vGW_ zE9Kya#5Y@#M&AiK-Mj()O1C(0pmD3BjpADrDm7u45t<45Dz2rd-OUJMrQ=oR*JR0WorDYuPGfVR+CyPJJn+R1K?gJB6mclC6F@2#ZjT zLlTSdilbmFqL3TgGAl@VOrc)n#Hx7Olk~t#G;&^YHWzjCcCO1(6t$LXI@{6&)y{TX zaDnI)oe;R}ELz01GFdUkePbn?b2~p-RY6LEZgnCS+<;ncdKPJwj=Hmq_LwnE8Zd9z z8_~G%qlkoqu_Z$C1btquH|&JxXd;b)aHTwGrIP2=OC-!>IH?i(<>dhD@j_*fL2d?s}gaCK}r$<;k+`94!QQoGsWXWLZ%w=(Xj z;J@A;-+pukoOjY2Ewa9yS3 zRa+F4XIQoc@j|ltB5C0ke>JErXJE%8iTn0@Tjef^pc**ae9-F&@$u(G4biQ@v%@RO z-Ni$Opf*d7b=0gscxC5C*(+DyNMWkXe&g)OGg45tX_L1JGRx~#$-MJi3z_Hi$~kXL zJ`^&>LbGLVjK8b% z>CB$kau9mgQL@{tr?Z573oqZv~MGoEkUy~c31m4 z+MHeOfBJ(T>9$|`-9Fl04v1!eQR#F2G7>m2i^gLT|D)i$`^(_F z$0Uy!C2o5FPYi4vDk#-d)Zp9FWOR&;1=~uEKK1^2h>CZrll&un=bf5} z%{a7-!+I4M3I+Sh!5} zAYC%{{{NhA_^J_{`o8QyP*1ycSurXDU{pH35clw2oBNQcb$uI+Hb)eukj{GH{mVl1 z1F`NK;a?~h6!DrIUeg}#A%Ng(I2iVd!ssWlQJ3tGcW$319Yo=?46NugTyo{Q$Gf(;+EvTT|W_~PN^QtmBND(Mh{PZ{nD@T{nQYVKue`ME>B1a0#r9@Cq8p9+X#q_9+AL1&1Vr21(8fQM9>-^EK`K$0NNi4 z+8b0qWS^M}T+byw>r7$H&OglGC7GTfxDNfU-7ThisG&UOdcp~jMdG>v`nK@mx;5vT zZihRHR|z53+qNe#mz6H)yZ?oMge=uTx1a?xJqXSkwuGgh>V3qq)Lx{_)<)MZRMciZ3uO{D#V z2x027L@@(pNd1IzWkV8X_E3n$li%EUE^}XXccVe}cKD?37Py#8Yt*)fH=lskK+g@cx5+3`3nE zNod7Er=BUwp19IfwqAZw8EREu;BU4hzwBsRWE8V@njW zG_j47Yv7#PP}j z;v9NLZDfd>iIc&gd_io6lEtvXG|At{v?9nia`$z-xKVO*R!;Xjo+xB@d+8H%sO%nF zdD$u=GlIAO$j-REIC(+9PV;XXx{A%xzl1Frb@s$G{uUWTJP}mM*AAJw+&9ZMxAyJ2 z!kL4p##xTNtF+wXat`dP#7%?UrF-+`pjF$=ynu_y))8B$`&9NW#l-P#*Hi-hbi{p> z^1m*01U3u2Mp`oQY!&IsT+qj^7Mje@vKUNz>~000HAl*lcuO=jag#1v8gZrmIJcmVXSv9DWB9bagcA3*JN_O z1`D&9(5!maTq~BVhBKZk=Z~(Fq$l~AG{U@A34=v*$XQqt3OVRUA>Ch^MkYJRfcG|& zU-Y&~w+QMrBGB&-{$Iybh5eaox!U=w)bbwlndTQdp^g1L*7 ziQpGIh8=}GHID&aYy6XmyPfUY;L?jrZa&D)s}3ieXwuq`vP0uk4kJ0SpMfa0UqbjP{&)EModtz4_VFK#AlHYm%D1^= zuxz&<@_4^y2zc1-4~@pBHjTJSLSHkEG}@heE)GvyT5KMI%I=4?SGfPifo09@3#@^u zMbfENtOSn(2$3y?rMvwSM{@%m&Fq@4;nvG2r9ipJoJ4=X8SKV90S7cKw=5lgW42_> z%_R!NelW=Gn1tGzG@}~--f8qk)?$Q)6uGH`ItMFyM3MtlV-n##vc0NfZ?99h5Ne4!fx{$Jf@`YH9PwE%I{Ak3o{nymajy)@OETRe z3~Obt5+zj17qHWVGTl~>Hcu=0hV8&cq`9jP7f&qr+;@oFGt=z`^lv(Jzot$B!HOOZs~|MzAIz$O}M^VOYev7BC{Zy zRt>&EWPcsPZj;d@zM;lyV$bsUN_it)f$0VYTFBpzbv~4KV0Vrher+8M>_l z62j#L+@Lu^J6B6*9}SEjBfhCTGSbsX+Q7p?{KYD9*H0GfhGnBqVAd}TWTR^+;-ju( zh2(=?l|6rBH0wPy#JRyQPmtCrtY#S`vQl8llXHjv=J#E_bvk0b*F1mI>JW@$iQcV2 zh~7&kjeZmGCeEbU8@L_(OB_12vuE6Tb70GtrZPM+Mrr*pxU6i@ouPnB!d>Me0KxK* zHmw*;KN<>LhF>!9v}yD_i$BK@Y%ExkosKi{I>mTYH-&`U2p2x9`8 zFs}J64$&Wwh1PFJ51U%s1(yD!zpQ*M5ZImk4rf4w^m_CVPv1F{hOp&;{5whf;=uRl z0n@cUTv)Ec3{@dt;!YNBK3@(wvK51ovl__)YhGS(v|z2lo7>&cI*Xq|ykbxM-F8-b7@D0LLy*z)ogg@PhXQyk(<7WH>k7(JeJuRl5pWRG3ttl-j%SQ<>knn!2E{>b2%?Jy7 z&&iVsy1m-4=n%|SI51L6&Z}?LZ>lV;jo#F-D^yn^{gKB`f~UC7Q8d=4-O>2C9z@95 z5ReSsAAu~oWP{YL9Y}vNkpE;LQN0BkK-}9c?HFHviJfyfNPa(A^bD6Axy<-!r9IVv zS4BDf~TDPs~%t?3L_VO2( zo8?=Gf$e<)<(&g>Ro@;lZnBdmFf23rvQ>On04JGU{^ge!bBHkEL+nG}-fv6;tLvI5 zZ{6{)m&u>CtW7Fw!mZm;DIAkR0Cmm$9qiS~>|+0`1l^(FPvl4M?+5TUvQX^`#1`9J zP=;#X$;ZYBvVHS16&Xhjz2k}sjk*)c^>WMYdXoBn#zW(|?2;J6Zz^)v8*u84c+2Fa zXWX{7L6>f`kl|?SCeqLO%}akDL1n+JhjCTr1RowI=7Q;9zfxzU!?Y|-`_=nK|3l|Z<>+p@ z+7pqQxt@g*Ep`dzv|@gZ6mqPS7+=EkDKSu=9utoa_lSw@r)kXK9K}L-1WxLAHt}88 z*j90~@KGF(A2AC~GKlr15EYXMiNGXaVbd}#9dwTM z5 z53>xbie{dMi>mRd7n2{;;CqMsOAJqnbDY){mfZe#YwDBlMASqyI^QRxU8P**_0u9K z`-awEynZ?=ULEh=4leHI?}d#XH5LQ$$mfDKN_kB?IZ2xgO0NMIGyA zSCUp!SL0u}npsk%Q&n9{9ZR)K)l2nDm9CytXH?5npH&A`7gT@Iryi#srxT_S#u0vF zlR3%nFQP6gEG#TKms?9tOZMbxAaB6;pl)DmK+;O~Bw9*Y_OnqqlSzCuQTFnOyh^5C zy^7~-4kSZlhCt$K;+=hO*mJa{Ov-t*3gD}~A`hkX+-qg8aAsw?V|DC!!Eg5g-VWce zU-|+W-?l}#yd82dKgz=fy2Yo5AK8a6xW&S(y7Q3^08G0QCt?$5nYgwDXT(;ROrdB< zdS6L!NeGTH+l4$ui@lshoQ-KQ+Ic-?X>l?!^hjG6TPRxCIOtlqTKG9qJ3FAz_wA&> zUbSAzhmPUeNv#~k*GS(%nW|2~7(L&F#2xzDmXizg2iI4!CY`JU1ZBFfT1OtWepjY0 z2cb&(9SvjFq>E*ha?RclJfJ?dRFlcXX!w%%0Z!n!%)^xmof4-KrIHT#3iI)WL!n+e zBl$1w6cdIl_T>!26ici;imYxrKIJlEXnLSrJmF)vRsD&QhOwn_YQ)^oOF`sUZsAF;S#Oo`zogM;Lw^@-Y>F+9~xLZS=BUVynw0`+4j($@Twlsfl}Hg7+zb$04t*U^Mh zlH79L{EN$8Z0>)gQ9~7=im}snhrv6|SWmIg_$@rcnS`SIeL9-!1mw-k&G`=0JIn5U z=spy;P;e0*-J&b$a0RoVaa}QMnv`gdX>Dm%J96*VojGvAzZ0>OHD4x2uc99}g^1N_x$_hwyAHT!5f^I~^8y?Z!~f}2ElnLqR2p;iU^Fzui+pL?Y; zIDBPi8e^^FS1tQcw@yR7xd1m>bh2z`v^!8W1OWiIzj^IsbDX{aYn`eA8*k<>B<}G* zVvqV%?_uzxFlmdinx%pG0ZE)2eFXEScTOmyyLSePlYpzDjrGhtyN38?T8RPjElPSG zo$CQz=tTw{_rkQf_(2F#dF5dm5J{lwA=F6cXdHg$fe)7dapj-?u;OA#Eu_H>w3;7dk7MDVPtYhD>1%*Fppu(?p^wM_G*xq62AtHZbO8 z(iK5Yp3I`^Fh##-dQwX!(8PQG;ORhc@5*&+8fTU{*tA7k-~T_EMS>~343Tcu$uiBp zB17;xD5`1VXhETN4bhXot6`G@N?uSqzpC5sK$eu=&1Mg2%4)v!A19a_NUn?%T#w_w(XkPC^>Huk-`n*6zakLBYE(D zg7=4TyNELShcV69>Rs>*;(MTd1Hy0qgP3CClDeb>a-pfMq%l@OnulXC6u+p(_mELKKYkKpI_n)h5;aRHB3w$J z_2!n*Sz`RPHbL2G9yCaApXPfuhG0t5z)L0vbIocEmF$ixPX>UNJTjBjSQxe?**eQZ z>=9oO$Dr%-^Wsux?G#sC8WxU2yw;l5I23W{y%Tl%D0!U*k}7P|8l%@$nnwmTj-Ask zgyhy=JG!esSn}9cpCzEC;+NG~+Fb7zL3DX6SoLFeqh9*elly#k16w!NKgHw~$Hi8x z$9T6NG0$3`l1FELy8ZNYFp5E6m?7<3!hQAXYB!Dc$iU^mBgu9)@kygneuE5ttI(KP~S30k%jBz5+&dt%dPOR zvv!AV3x4ZByUHDa*yc3e@*QLf64Rl|)F!n?aW`G6{ zs=6-VWd(SR_yjKvMvLdVC(t-d-=Jpp#COQ`3tO-Id`~>`KQ?S;fqrA6Hx^Be>;ib` z*Yy|r){$`wic^^dPRdtt?oOS`b`rgk)+1}Mc^R^WPppHgd{y#FfOCRnktNiI1+}9E zNwaWh-B?)JCbA?8+Jr$4|6Ya-qij9Mx}yoP@fj66hV;1hbiU z$iJ0SkxKD^y0{k4d5*vA%BKJ%d=4~=9Onj}BNS!7lcJwpHj=KBy;=bnZ0A$G!?Wgh zRk^h73(Xv-+;HDJ?{&gnrShz;LUJ?E8`SZ(udDCrPwa@<6)$lF+xc%_H~bI$9u2wN zd3i)9vs~ge8$ZW`O~%}ZdoN&9(9Qgl{jK8r!F=n5d7(K+2bNJ|xpqlHdOyfU;aL#o zI+&6`HM&Nzb-IXP8H-2z2dK}1|I+53A*)AWmDthe@pS^A8T79H){=CNAPQpqg1u9O zFWmP)M@`swJa(3wWcSUTmuVvuk_qL6a@KctyfaT#TX;P&SA1@lc>pH29Qc)z9SlWI zg!&Z?XX;-Y(bQ&`A{KppHNfe$-t=!DFSqN1v*0rJpckz8LyDJ?z3PCyW(UQz|2ywk zMmv0-=TfF@4fl4RO_0MdMRzxDgl3I$F&*+q(opn9FMiGa;bb_ARokS~?9E;j)%eez zvBstPLTXK}e1mHhwCxE=)J*(ZfSIc*k|2X$f|;BDg0nnB=7pyZ;X&6(IArx|7s)K} zbV}Ag)Q4(Z`&n4QUC)n?+L+~K#y^f$+O$`(7J3}YLQ_9M&=lQTiYW7{HPX}gtk}p1 zXZXWig*f`DA=3mFW|PapGEwbIiMJ`C%^P%{E}~nafFrMHQGf?`=-VfP zj^1>J#8w5L`)tUC9>ar=c2G_7n!#koueI~AH$_H+*(NNr$c|R~rmZbD5ScN(%G37- zQssz@pbkP(G(Y6(i-9p`zo^#d1T%me!;5isL2gOjy_QNe$b+^SPR6qUEPk_OnmNrG4wM&(!y>E%TFT+lDG*E6@0>ac{*aP`V@XDsI7aj4Sly~Wbi$EA%ZpN>OI>`#-01$_<6jA$aqmS z|7$MA--5@()7!}V1({}AZIj2Ioo3XHN4j#G`1wEX!-y>UKg>sn9yAJ!pCQw~PxiLi zHBLNDwoE>Z27W}7A!HW{o+?p1HzT*Dh<9BRc=dIym2TJgq`99;A++G!e+R5jS1J7i z)Zip zGYx9{eC_p*6UmgY~lyvJ4&?0qJNnNB^vD=~I^%?wUcBG-v{~Kmp=im9^?v z#S>#^A~&h-NIGhTOQ|?Vpx6!qMdQSCO2cH9maWo(xk@|#2oNh$xW~k<3t=XYNK=K| z@V(=nm(o~?Qdj3RD!`Zc=Ir^6A7 zTO(H=60BZs(->ZI4h>)t;>a46?%ALtgG-y(YoFA1#GNI?<$F5_AHE6=6`up!t<%GA z*NvY1c~1vB?@0|^&jQ2SH?Tn7=LRFqmxO zG0)}b)dA1dqMbv$A8Fo7ksCuZ53|!c6{GfJmTf0aq>2%%MP4zj`Wg^^8Nia?a(Dr> zp!~dKxS&#;$yVfupqz08Fv*pY^n|^nvnOFTzN3F9bm7EBJB+0LPrfBtP!;eyuYqMf zy`}d_+;joJgP7nLPVledjHbPaXkD=7`X=anwUl6;EZ6pKco30csPZ+m%WF83WHUXX z@Fl(*<4G)2oDG-XS+daiv!+CrN0N3MoJ-kBrXJfgR{e((;n*?i;e=^21xwsj9Lb#q zF!+Q%b3cKfxx8rK>SpfK7uv>si?L9pAS`mi>eK>U znq@3eGPT8NuiXOo&Wsz&*}Tc|EWMLe+<0AD*>$Wi9@jQim+K;G_#>ZpNFpBUPT8&r zPS7lHj|6+{i8vW*F2b5N&&oH$G- z$DdP}MtB(Hoj(F;1WQbNE0~v@iiN3Qj}=J_?0vg>;n`b1$U47OsL=sMjFGc#fvJ1OG}@5jJ(geyD+Gn|M!%@gVrrw~TyG zMcD*@&HWmgp1K46NfhvWvExm7r@=O?aqRV9>cP`Lx5l<4i z>C$yFIU+Md1KACD9)q1umK3pfMAGfycCSs;Qx$jqg#fjow?l8K@+9AkfHleP%WS>q zBF8AbUjlm9IZ)tQ;;Nb$0QW+;>?+~&2dTY|q#2JG*NP<24u-`nigT~B9>oR=>eLPV zLDZI^-2CkBW*@ZSzX$0qYJ1%76l_D}5$yV?Q$@!!(MnI>7n@57wJ6P@+X>>2MRy{GOlk-r6nS zLw_OAjXzaR_Fm~pkOy`w(zDJL&reis$E6>PQX>enT1K0?<*=5yRj?^vu}7lJL3F8= z>v^v(u<+?VhRlv#7S>B?Iqk~?jCrw~x@hE2TnFg+ZpR}@>w&~xto5QOp0XzbMwZmg zI0C>ZYV4n==xu6)rh?ep+Nwly`kpc$b;^okv@0ImbzJ~|!gz*GVmJg-qAlPH1E2yx zGis5=rtv!1TvIX*yKgJ^Bl=FDs}9~%4OWM?g>{?Pmvs#Ztq)9bce|NK@H(Qpb8v)m zNh-F1S^kS3pmGij4HkZG?*_P>RyQk2Ze096LgF~sa{818%S0wOYM|Qw?&pnZD->#R z*uzvPo?pX8bqInAX4W|ID^~WV@*h^+wpAIy@0v(6duv z?sDb@+!=l#q)%+!c554AzVdGpa#;Qdq7J_UhW7ue`#j-cA=9;WXqz59lU20UXDD~t zYFLN$f(ZHqBwG#Uh8G^O5VGlVI#S{(O@rFK=!Sqqt3N$0EiNW$K1Xgca`dvPPd zFu0Zar+2+qvj(HrvjzuuDceg+EL`bu?Uy2MAd`N~`QMTk!QD<<;dCzD`;9En>N8|g zc{I%>X-e$1^kQQ(-2$2Os@RT{78w7FRUdL=d@rg*2pPl{5tL$Qnoz0`id$8V!!;LM9KeTh3hkrPj>x4ef zjf9QTC9zvl3v5BsM&Y26A##-P8>w9CyBe9~hM)E~ciK%H7t~xjRQvD64ayeErHB{g zZwQ}>5!FqdTl|KfElT*&(Xn7pi`s8 zG^#si17@jKZG`1{vS^p>a1;UzDq0H9sZP$Bq|_1+(BW>O3(h$S8wEzmH|22Jm ze-62`VKirDKiRo15`7}_EhJd8Mmh{s-~f(<0_8kGn1_C-Y{@=2sgTl=pTw@#6<-~k zSWwK$`=LnoTwL6~R2C8l>l}?m-L|{taK&6@Y_&x^N}f;Hmo-j8kUQ^RzdO*3SLAuF zbrm;q+2ecfeE@!FAa7|CS|%HW(jefWYyU*+=7~Gyd$6!#x*`F4Gq|wBkoeW+rmC2_ z9{F|1kV;~UrF(hd@;G#Yk4w}qy_i90WI0YD49ckKjrijaJ|RRXNKYmLAZ4GNsYdJ%7-QB zfIpD70=4PaHL8WvmsiJSe{piJU=tHrAw zAujX&uiYhw7d_LBM!abRo4=rQhJfj*RLhm}RRMT1g^JkCudS`D48VO&lgXlUvmlW&X#6~+%OV{HIj^FD265&#g6hC{WI@% zN)EYKndB}=UZ#@dV@_^7w#8A_8s0w;l{Sa)I!*FT+Ex3LzK`6iXzQY6Sa+|YVZr3Ofd*Az}k8^eALIZa6$b5lxNCw4BMO97$g45_q(Of!D; zqc7q7WVI&0`2);;Mbi1H8Pe2nFX=o0Km(j#B(<3LdJhmhV07@Sb^+*Dyn-7H+9n=< zH(!5x@i;%dTOlFn@K=ItKq|N9m*O{S?rvCSGJL>IjssU0ZOmyi4{O$y>u4fO8FxKJ z9#8wFi3H_tz-x%#NdiBB=v8RQSo~fm@4g$=ieR|}pH!^EE^J*!e8*odvIFNdsOdX+ z|Jp7e28>o3X&|+n~!U3(HSrj~SD3g_*_Yro-Y*iYy>99P4Dpz_<}ha&9FiI8Gn|4s>R` zoYDAaI1G53tU8HbGp}^_wl0WYv(_afH<&ige}B!`mI9+`C_O`eLxm>QoN2amW}D^g zL-W|%D$6#6jt|!hwNyE`U=~NWLP5ox=<7(M4z>UGKTM|ld@I(xMTdiYPb>X)!@bsB za8K{{&c^awnsV&_xih)r;j1}cLltvZ3C?HdIrj#2T`HB%Rb7Op8=}E*Nqw60`F6?G zS^tRJ&QRV(C*-$+axK5Ui97^Vm)jM|Xm)xW(xY>`rp<^P$y#&{O_8X`_LB09S>_QQ z5L~WiwxD(eecE8eS3&_rH!T@Dy>Nf=mO-Hs8ux{|li+bcwmfjTF!~fz=aF7N2-AeV z1U>+W$JKA1X^-y@#IJc?)E@4k-O$d#h^H=ZMSB7FtXvJHsaKl6|H(0HN>7y_2t|N| zZQyC22y9w>{OQ`ifGJ<785jJ7vjM^2X5)NH;Mc`3>26zi{s-9}s6sGcnnkQJ;$;ubdSn{HS)cAea|4Ik$&B=$DDKQv5dzyS#fL zQfiYKm{;l>^InZ!11dDJUJ!~d0$0I2Lafn~7Xm-?aC_M1k*o7&vmsS=JPFC(z8b&8 z@Y<(MDSPa7>c!Yxbv=H4sP&nYQ8Vt#ClG(1l%xQ+$UC#Gb*LbS)opRmaE9!BIi2;8f?d)*iqOLI_gcad1(^j0-Fr5C-g^%DsAx1jeBumm4Idc%FXUWhp~u&$~!->PJ<`@<|F7a z_h6s39j`H_AH%r~hAWa>x8T@S@Gp=JATi5sB^jr`&gwA}vT$0qJ+v(Z;hGZb5zWz& zYfU|43n7>PEF15O)7q_N*3~|&y0L8Jt;_LdiES{as4AE z)#NbH$P`t{#fIhdp_c!_RNG`Ayd`LKbJ<)FrV`l0 zv&gR;d&6u$Jhk184Zy$-;I8YxG|@~Xb#UFtPC)r!6R;&U1Pbog@yFjqbieD7vv-pq zFRwjfJt&Z8)eTl^)h~I)X_x;E8MBPeHFpNejE&4vakng3l!@f@o^=y$nzZbg-ZXjb zbYEk)hlQOBcf(mYcFTmx3qp-fpN-gmPE8ojz!CpG5{D9PasS^4ycxlvB-!%sl2~j* z?!*^B7_){FK>53~EcPd}hO>aJvII-I&#U%9qwR^>?>{y;rjs6W=Li#Z5WdknkQ1JpZ1Pppx#%c)@+~3?FSb&4 zD_Kx0YU8yfX){gjY^;8|L(t3eBGE)fSMMY{6<fHWD1Uam0I*r#&DiTiSid6_llpVz<(uXe<2@6U%Er@QBX30) z{r55201;O#58;hgRrXNMx%|!T)~w6_196^pRDEAFx(tWQszN;1po^}93h3Qo=f60x zxSbFGEPaqc^xnpnx#2r`h6Vr4+B?z1e}t{uns9~x>3?Q}X&2y`V*dcKmEQjk#Dif@ zDUbhO5HI!q55(9XAP&h9O&`M|XJ6F~*~5ei+J9S5>*^dR{Br95;TCLiQRhhM-Ic{? z3gl6^91<~O8T{?q={G|O;2^Ax?4G8IL%aUBhGx#>u3*GYR!^|Wb;HFXh|E^@e?ZLp z@Balc!8V(hp7vp!>=;?eAITS!n}6SW2ruIfA)*s94igAkId2rp0w|_I_?|}iTB52X zE6DsEyULI@(^Ge)g=(lfl89h&QO`$fD+^W_#}wy*i(S); zNZK)z7ui&huz%d7vW4Aa9{+e9j&1l{bMjmT(&hd6GF9AcBv)`fe%5$S%tqYbKmuRY>H6zLBl;DHFKD?3w9%}}g|R_xoVF}O3_TUHcs z<@A=KLonN@uuwof{57}_(#mD*fXd}EYG7C@*0kFnWal|WKD^VC6aoj$_mR~Hqu0Vo zr{LQ$Qw5O!R$GO@D*k%-^f(j;DyJExK{~#f^R0kI#hS9M^ft)Ms}MVK-WCn*Cq!uk z3g+Id9BS3W1S(p;B&LNUIr zm*=ut%o}xTO>uwAB&z>6Hc$w^`l-n{6|M?4nr@g_SqMVI9JGN9iT=Y`ozNu8zh!A7 zq12QtG^IyauO&NhwYp$=K>e`38OleL-s@!|OkStE(N-cj9Hq7wuBAR~vN~Qs}Xo-e~qnd6{ThOU(r-iyz0Sh?+&TQc83&%oOD2oHH)I!WrFP zCaD@@#eUq5R7r1!_nW~B439-R~0v4l3Ji@_Pcie zWmL5&cl9;^qeX*peIkpLgy_TSKXTnRWL>g$=IQF3Qk843FT!HP8o4-6k5pCASZFPn zkBcB0qR-!=*Mao;HdEU8l)6C^GChH1SE!Zs%bZGaLmo?=;*3I%ZADS0mYGGq@URF` zOSzJAJ&(`irQ+cre13t_Ez#0ULRr&lcH>RtL`K^bg{HjRr3Q-K;%AV(b53+?`{LWCcF+qP}nwr$(Ct!Yi$ z)3)ueZQI7zedeCr^W!GxCg=A_Dl2R6s+FBxYo}6`?Dal^0&7gtD1#hSW-iVKHQnB{ zm(h z-tVXAB~m@RGAu^)w-cGx8THp@nT*H8_`TERWQ!HtV{#ssWe1K&?4fxp_?rvee~eUU znG$Xrl{##cf__(fCT*C0ZoInn)2I;f#RWc8H!C~#%uF^7ljo zEC6Gn1yj9Qi1C8?_Us4zY?L8~v&|IOYqJH%nv=b36!di2StrU?t9wxB3kxQ2r=I)? z+LHSwpk(gQ;)jfZ^0jAWA#9xGuV%Fozflvqt7=z1na>*@CEz^3g28D!(%iI1oIU(? z4eBW=g|HD}n9}UG_-f^v;D~q%9!}i~_FArV2YzmG8Gs|DD`6y0_3MxMLaq>|lnaLZ zaz!b9f~}3*ts;#?)Ps}h4s6Z0<>FZO{3koP4U1~ok8T<8QK$@L4Hzr6V=_Kmxg(9Y z*&_9I#emucPntILHeRPH9W6O-mJtEy%F(LDd6BHgKhgTbORk;y4ev1W<$LcQ?m54M zd%#Q7XBN+|#k13M&K2gaioylRfUu-hXu>_@pUR9qxAZ25hfAWz&A?l-}hhg~H^QsJNH%@cwH` z#>=~n2d1y)V{Z;1&R~!)L|C)LsOJdr#eANxbzR-7LbD{VHdv{7ptTmb{I{N{);*OCWteSGdmt-m za^|Is!oz`NL{p-~@2%_-Ags6Jx`v{TQ8rD|skINWR)U!+Xps0`>tU2B1Z&H0W}B1) zA%Wr>@$LopKOjqr5ff7sc-MkdUKOA67@hN7t|WE}B}wkZ^K>K(yfN>wRO1OMGs)zD zvOD+wWP=Yr^1P+Nt+Y1}du;@c`F2nuobZ(eObz941uNP3x#m({z|MfMZJb%hBCvbX zRU-a6*!ye^MY99e*v4DCOeN6T()!#(CC3y0^rl2T7zw5BfJ>^fxuP_2Sj5?j zHXjtKe2F9S(Yvc=I>11(I2D=Grz0Fxb>z20G2X(dSIGyV8y``ACHB!TU>GaVrswd? zx#vqb8=j(OdGAmt-}B#HFBt)?bSx->`HVUG(|4c|&Ig-F+uT37yS*~vXPb2xCLNiUsZvI8b!W+$x62rieRx^LgktoTA=8$E4494@mrmH zAt&UVR-wkD$YMVV^;q@Tq|%G2Aytyj+1l?{SjJ+z+0(|DKL98JuW;e|Z&}o;>@UEV z^0SoMV@9=CV9PDM4+0PfpDUE~3gkNh3ZC94%~{WtughaprfbS&Rj37m2TGyH^3;+B z9^ts(@WZUS8tLPNTa|y7Q#>v;@8hR9*k|OwpVUL-P`C$E1B*V+B9Vf+y;=yM9ox99hG@P%Ij zisLM7P8rCS8W??AVI#xhS zPOwKqp$SKhCyJ%Wm1|3M6mzZ0w;T2zs0rd(>i zYe;kCFe2WY&!q3>#wmkhK-Q<|l6j3})GD?ba*c~;q8lI_U>vZ`TpOH{(@d<#G(t7< z8kh)O>OA*8M`S0p6<$rQ$1{R8N~q;qcV+rOe5SzNlq*Xh#TDTUa)jQa9e4|c@!7}C zl7Z4duBF(NZp*nfoQ>C8&l-iAMb;fTx+sufK>1r zpbl+@!a-&yu?@jIiz138yOiL}bVS|b9NN#P3T=Wyfy_XzCEkqG9B4{$B-k?=NC`cG zs(Zd%>L@#5-xC?Iz$T-3M6S&5?s!Ti3f&7`gL*(lCy$L4BR8`efDToIv_W1b@y$`( zY2UN-5&nXra?G;`r~OuroR?_%zOfAMxj7Q*JO#E6!$!Xi!s@?+zUw1`t#jq{oP2u- z!`8eMnB2mUlws{@R>d=|C|Lc~$6V}YGzWr$|FdQJ(8-rv01{7rIUpJIqbe5RWdW>N z38KVz>O(Gc7QPRV@W_Zha^Oi3EJT$k3A)T_Q1Zflkpzfw*%1ytSKPIUUy?vS_o`-oU zzX6}DUVvl@;7(CeFTheV+jE=ssH!ZALk2~GC4a8C;sEQuENVpt(K=Uk6yX)+G?KLDP=d`SpmGAs9Yr`(03*71scX>OEG$ z>Zoo6;hbE&I`n_)RSI5iSicYk`1Od|wf54`5r$vcl5>`Xb}@Nk+qCe+Hle|-EIAKV z%Npuzm|kGVr_X68o-hR@oF81sW;@9k+Q=9>$Qatm0xlfr&K>N|Z*TxRJI?2d@_G{$ zFTU~X@_d_8e4BE7pL7-sN0-I9q7!?BT=;EMwzUCf$U`BCONypyoJ+YYNl(qzbe{DJ z7fDoI6UXmae|Ihp76u-4=6yk?QB4$9QF5D6(}QiZa9{XT>!hB%%k{?xy*NF+nzVovtj*X$Ok5he2MRVttbqnkX|kX%WI37R{;Im9<|)zO zQj^D3u}{MhR?|wZdP*PTiSIr}q@@o``P(6jc|CFw}v*t}zGN@!Itj;bW7vf^mk`o8!R{j~F zvF^x*M+3;Rp-@-W0W=h){(+fx)z}oKLnh8`p4htn^eF8JqCM5TqgPgnStF^c$N-Q% z_2|@O3Ols_qzl0{3)ci@TbF7>H3O`hv8@+B(ls&G9<`zd`rLi?#jTC~Qx1b!desv7n5tP|%L3N% z$2*!dUqjtP1Z!75qk_3)>JUd;$UM>@UMfQHuvCt#~1Hh8Ivq_ zu?&%Cr&vUIXNO(-P4xpY0;#$%>mXFTXm7x5JRP=imiPIK7^)8l?!W5u5spKQNC-wE z`pNm@6GEmxWxmL4_nO{_R;hjekp!ZUi++*DOcX(vSmv4Q%A%=cF&f8ZO)(ZvTcTUF zux&K%oBK5J(HOb2@-!x!D>PBWF#BY6Yf?3}uH~e$zxaeVF{^`Cp>>+UHDSrP2j^CP z`ju6%#08w#99#_Dyn(-p-%&)<)ZJF%Qb$0lwyV-3mE4!}66Z~n-A5U!38EpMsS&A3 zhL&e6O%ki3sfme!qZJa1imM5yAsSIji$%#+{-vfHP}5RVH&s7U^GXs^Q$!P0SCdjh zUQ;zw)9NazET<;!tgNk!!L1ClCUUN1uZ$ZjU9WH_Zax3a9m!kSbWVH!ue)ljtfT6h zxc9u&JL+d;>p2~C<;&7XQ6lzl@W_F4lBXn3EjT3+Q6x59I1I5RNj7Cvm4ZqIvCwx} zKXT$FO*VB@jROFulCYd2il`Kuk{qfMwf=C7vUPMev2>M{bv9+Oc{x^5b#|$Fl(Th9 zHr+&3yLGLn*tEuj7+A9)9U_`qury*CK)6}4s}j9xxTx`6-;Y6GMWCEO6s=j84nu7z z;aoyV4p`!kTvx?r9amnvT;Wy}zW$p%GTS<3oz%L5&N`;NrlrDeAMPJ|1knvZ-z)=A z^8w&1Dg5J%AURY5t$WMs;LAaag1AfIqr%T4xrw)xM*&QCE!?H@QR3&}9Yokw8|N*a z5?g8>Vkm9~TNrXnB2QJ8$NDm7c?wXC&0vaoa?81FqlYckbc`nL4Y+L-<0-!ebozBb zG-d;8?*6sjQS5J#j{&I<=<_Y~i&L&=1H6yAcwmleY*wD50Kt&+J#ta@JZ7VyRyizN zAwO&XMVNeBz)j3YP!c2hz7aZYAXz=~@}T=Fgv1`LZdhkq6U4ERydVK02p_01=r+X~ z&2NVBwm<~QXZTk{GurU?lvp@S!A6Zf!DJ^8f}~5lTc!zpO?$@i)j%RrA23)lEDXk2 z)0;pf%7gk%$>au*g2YQS#%NRBzA{oD2;cBVj&vLmX7*i|LEqXKLJa zU~XJBGmV-Yd!Z+h(G&M~#L~KEZX8%jBhWKf@0j{LWNw-;GjE=p!p=x4&=X&7kFEB= zTH9rAoHsK~nH)pUNUEVH+0Yel>5RSn7b_Y|OCqNw6KngG6MN~5wRXkaIBI5EH#x>Y zPx7HBj;tpR-xiDOip6!v>^x+4SUx$%q@fYtIhE^}#dXH)GGTW7cXA3VBguuH@a9@Oe7=8Ku;XMJ(kxU%j=x^e#(q=+>CVXAInLA1^qRvA+rE0<|C^ibaKkf_>i2* zxd79vh)wJpqW+p=OU?!sY?Ys14}k6_#xt+)ihL85UzBl5w~av%y=NSXNyU#;JXGd+ z<*c5Iaxx6&q@;_SF^uMiQGDj=cKWT@-hr+kouLt-;!}P4F2bA=Qu{Y z2;EUh0sum^9@%0T3139wDT*);+C{8BBpeut;?#z6O7b2^_a5cH8~L?wavL>n%v^#& zGfWS8m-d)e(h0j~h_x1*5ql{PPg0gNIc9grbdUY^I94x#aC*%hQh#zShg$R@#MJRC zKWmmQ>8Kq!tYA`vTnsiHoMdRu;BngF5MslQV+fLs851jxkt7Al-ju!3Fe>2hBoW6i z?0#|YK~~;y)-LftBdnG^OnwopAo0Y)8xJhb7LZjiKX?v(Ch9rb4nS7L;R3O2wLCqxSiy_rWZhH^dE{AF<7*~@{9fl)@x@IFOM@Ij+rwHFG8s6dw| z3r2AMQME6y*pNF$ke<*eMyQof)6AbLM%c0uSd1uieHx57$9=k)5D$Ace<5}RfBM3} z?D1&+ikav3MUdHp&;*|}0{e_?*{9G1t1^Q7gtalk(~gI$M`G_cU;U|LgtMN6SC8V} zZ@&uavxo7Q`hy4wzE6nrSHvFVdZvjZu6&;qCs^4Ytah%8BR+kfSlh3RJ?QlU8%I3* zKDjoq);)ObVjo8W{63LaH2i)O&z}l=SfoPCCBKDPzR2rlac;vu>Au(_F*n1?4Z@$4?lFAEb+2NVC?8@)oP_YvBK!56#PQK4`)!;=^3f{$e>qK3Stc&N ze{mqkfsP0rBs#5f8soCXV~xh4j7S}%I<0e>!%Np_eNZ*1_D__v)gV_DN}NxYdzZ%nhLE55Ugk?`T= zo{+!i!y@6Cq;IUcB=4NWZ!C*V>o(23r280qF*D$OA4f0?;1YySB^VdFH{sHRPZBv| zS$R-;SVn-X(q+%D?RkTF4U$PDb=zn5rN{vy>FUviH7)T&LpIP`88vQN!9G;bHP zPun6!Mb9PnS4U@{+~Rpg5HBlFm=JIMn*LE6>0< z6!VhOPuDn9^ODog;5d}?lG#r8IMjQSVeDFo(qkLlYoH1xJ+tP89PY}j16J$w6vbkA>_I<&NI@LcLW+xsMRuY3(} zTimpwT!B6deboDn@LL$vGpuP`+C0;J#QV+mI0)1etoN=bT#i1Yd{h9Z~sYD43ZKUI5Ny6_LNcfbPRR-b9F^%%jFfqVMZ*it|5)o|1R;OFeoL z^iwgZ$A-BW7iB`8j5iq&_PQl~E|cBsWQ;rLAx#cBw@KsgcPNceP6l4*I4?5OsZYT& zhiLxV!isy$z0)<#Fk{jR-YV%Vd8sy9Hl3;ATAt-CZl3lYB01ByvgwfF#^?s>LH2D4 z$v?iiIYOW&;2XkeTi6cZ|J1cBR{R_^m_sRnuKeIAFNY^-%qCuKWL`}Kaqk8VYfKykXj`(0GqO&l_>PZQ;(rta9tSK~fKReF=3NpB z2qKj5S*Sf`HIL_XN99|wzKxHZk~DifevGs*oT7aI!vsEyIdVh&Zwc^ky>9NmvpGJu zHVO@LBfmbp>Rzd@`5(6jdmrXL;=S7*JTI?#^7m^G@HU-fi}^-fH=THeYW#56p7d%m zdf()?xte!egL7Tw>r=L&oP_gW<;5wc#t%bzvhrx<)hTiwl2f+E_YPg1x!Uu1<@G5F zQg*0zQ9o52cn)WQHPDLbjRs>E8fN2cEZ z|5J{DI+m*V{W!;0fS&893kIJ_mpPZj=3Cr5 zT$3Abc~AL<>>oHV#bEVpFab;T~d|Mz-yr+rhSZt@W*x8@qA0;`Mafln$sH z=X3{jgDqz#7Pg(O$*ss6do`CeQ|{hXUR4cx+t}OKwymu#t?U~I|9(Chd-lfh!f7z* zlIxON<-h6NwrttinBPdkgYTR4cOSC06Kg6~*Qo;Kv3F}UUbFfKbT?U-2)} z<)onU^WkK-(23|8`Zy8Luw-w`HX^@UxYI~A1YNj{YV>Y^DATl{d2(^-=1SkJNyoS< z%AT~{xCZ^NR)M7{Yk11qoW+2-DTiw+*PNcEHEVRr=9uLn2W%?XoT#b(tx;=;)*79K zWJ6}6*R)wv18G2t`2QsezBU7_m^q^py2WSo+M0&KSK>A zzP@QQ?KR5efsqgxuWk8Hwf-P&PfE*B3BoQ=Imdw2p9zMRArjuFffA69p_-6kFNF-I zp&*{7154vXxnPZiW3e`@xQ&grv^b{49@zQ=Pud8L2i|r+xlSwW<+Ur?HDP0dHXqYP z@RwtTh4i0^J`h(PA=!UI*DI`2QjU$(Gbv(fIP!MI(!4@Y4lFmiDW=+)>ktNCner5J zZaGj3(J(|m1K7@LRbV zH(I8;z`d^cSOXG4cqjEI>i9rX2I3o&qb@w-Mi=o3Kq6TVD+o&cJuD-HwtM5E4150k znL1)qEu#o-_l`yx;||1571{6yJ)yqRjGoi9zLn=px2+ga4$tVv0wT`8C%@i=B}$f+l+a-GHtg<0vXqZI+ldl9@M>x%f|qEvRdm?E*bs zCgCq+9BZ&RwipRroWCQyKE>2vRa`Xdc_r)l%DezysP<`I@-6i6_hU1A?JPTMQIU77 zW#>~z#Eyz9r9kaAlkLEbRqj72GDh@!A1+;xfB_+|_%0+A@aY;UU(ZN{e5ZFch6Xg0n zzA>ij$kqVnX-sFxFU-)MZwSnUo-at*QZ54_moF0UTbBA{^Dm0*H#OFWDy!p_xv6hi zmR@we4?4|=Z6JKL1VX_toVfxYLyl{wfnCCD8|OZ$%}LbIm^PY*J@RY%g?_xpyFE{^ zz;wjA#17C?8p-nN8|J>8cRL(Q!+>4Yuq{t{b@sEc$@y0MZ;{e~6^P$Eru)r*mfyT* z&qNvmPC;1#y&>+4oT|kZFGRf=2ZYsB%eJ;IHO**lpA9t{@P8K6dU`3i$`OV)^}m)^ z8ZD>4{=J$-crx9u#;{o1LP8zOL^{@Sbnh{A>Bcbq#xM|57`nzV_BG)M+d^U;Ovx6; zNLwSuwSh-d7?Cmbe{oZiEs6onCVcUIdrQO8<&PP&!JJK+jL*yzG-JeCTIyL#rcVtX zHChzQal?CGR){z=;!RGg=dkPD9dB>X&HAHCkZF^VP)T?A6HQ zEthJ^SDI+acv@`9Os7lDmlNm7u^cScRpH&A#K!C4z*OH8uO@Y^#%;+i})s}iN*Hw!Hg=YNnDOt6S`Zl zA^Fs=N8Vk+4N+CY@0+sx;*94&b!xA;>EV6aAKH~vs&dK&-?wJC_HvBpy zWz2JLdqAl%ZFHK1UFFPqefXHT46YiiPN3~DiO5c(?F_PHi{VbPZw4LdTC$%+Bb&Ad zUGbW6a?L7ovfb(n=|*EI>4sO6b(G1}AF}v+vgE4nHL2RWW5TS%X{mp+6!UMETGKiA zc}Zy+tylvVt&Yv-rlw1>a>Q6((5BaHvzxeBV_d9`kLRbR%d$SSXCpX5F%if{SP&1e zqV5=tc~O|~_^w^!}jdQ8}ITc*LU|b z*GF~tw+(RlrFWVC!t|d+EP+>(s~{#7Dv0>+HfTdK;)b5vcQq+vx=gs^KrcgjNARAh z_Hu~aZ!6nuUFnfTo3Wa|wAw^hke@#U20%C?Rox+2BC;l@OpaM#GI_E(6ZiiC{#a%i zXPIZ2W?2{*FANz-iQpE9K<|b8Df=!>dMut<1Q-RFAu>Z~Nqws2s;8^zs$G}W)xl{} zn&X=D)JCW+@GSBS^Gwz1skPLqRjPfeKdQ~uVJ?s^JeCQn%c@VRGpaSJIjZH^1#|-G z#>^YFY}s=L!)=LLuyyik`t$piO;v2^bz=CEYNnTsE*hU!-)%u#h&Ceart*i_jTFok zjB*;MSC4IBTF6XA;6oKrqlKJa;h+0o6u~Eiw|UE%<9VTQ?U)hW)_(I(7r+W0BE}a< zv$rFQrQ!PS&<-(`AjZRn-M!X9UNK%V5>0qS)`cP-(45dvh~GZlKM|XY-XRn9$7CSt zu(1%JRCbj^B>}L95W=gCMd6Pr_j_eli^_YWGK1dw;U7Zyjw7-%3CxZB9s53aBj5U= z9tLfv5N0w7jt%`YC$R+&858JYE&K5n2c%_ToE(1@g{htLDj+|6BPD#f;D5Hho;5{e zzFH%{T0`$&P)64k!}i3R+-2G9vaAeS@WT|eqa2rT6%;9er}X#N%w_M!(d8gH4_ryV(uhc}2yNQB=>u=+U2kYdJ~Ai1Qn-J`uZY;s`ck4~2CBO* zGNThgIv};Cubr&+ghW0x`=|Yq2F=N6U7$NI| zuJog3f^!VIW`eZ#(`LfC7~<0gcJAW0AzVj5>)M0Jait0B!4R?k0l`6>~4g5 z*EpmAJglZ#txiAr(=Z731P(|9un0gzS!4Dif(fbZV`_hl52T7dZQy%H z5~ug>bkmRD(fgLjPtRR!$Si{7jjbTt*g0I3_r(27x7ceAf)LRf+)3F#06NcvofwaM z{7nRF1bsgmA*8k)2$M+jTFptuBW(RYX@qH!hj&OLPzQEKM48yBr0>M|#;J<5a970J!YPBUp-66foAoC567%Ft zi9f?TLo~Wrs@!=GEJ9&VXA_O+G^Yj4WDre%z%hiQnNSOv$eOefZRG7m*anOsZ);!2 zN}5VAAt&VxNea6&7l*fgu@|GSm4PKP!z5BhlY*s!VW0>y3L+-u8xoc!{>TO5qCPoC zb2g9hPjf|FK18a5q>AJUiLi1-lJJ&H2$v)dl-+2V%qE6@%(aH}GDG&k{$vaZG}M*WZ_{_(%Zz4wYsW}rzQ3oW#8%9RgflV7ZX=}-e>iqY(gJL-^MOg_9SFDN90>^DY*MyZ1;S(! zU1Chiu!{6ZDBqrZC{n+qXm_OJ<7|#Gb0KOtUM&4}wx#os|9!T9-tUT-*X>eygH#

    uZP{aL?~S@>F3253Exf%P5|8|17~EF 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

  2. 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 literal 0 HcmV?d00001 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..594c908 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,420 @@ +cmake_minimum_required(VERSION 2.4.3) +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +#this line has to appear before 'PROJECT' in order to be able to disable incremental linking +SET(MSVC_INCREMENTAL_DEFAULT ON) + +PROJECT(BULLET_PHYSICS) +SET(BULLET_VERSION 2.81) + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +IF (NOT CMAKE_BUILD_TYPE) +# SET(CMAKE_BUILD_TYPE "Debug") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF (NOT CMAKE_BUILD_TYPE) + +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") +#MESSAGE("CMAKE_CXX_FLAGS_DEBUG="+${CMAKE_CXX_FLAGS_DEBUG}) + +OPTION(USE_DOUBLE_PRECISION "Use double precision" OFF) +OPTION(USE_GRAPHICAL_BENCHMARK "Use Graphical Benchmark" ON) + + +OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" OFF) +OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF) + +OPTION(USE_CUSTOM_VECTOR_MATH "Use custom vectormath library" OFF) + +IF (USE_CUSTOM_VECTOR_MATH) + ADD_DEFINITIONS(-DUSE_SYSTEM_VECTORMATH) + IF(WIN32) + SET (VECTOR_MATH_INCLUDE ${BULLET_PHYSICS_SOURCE_DIR}/src/vectormath/sse CACHE PATH "Vector Math library include path.") + ELSE(WIN32) + SET (VECTOR_MATH_INCLUDE ${BULLET_PHYSICS_SOURCE_DIR}/src/vectormath/scalar CACHE PATH "Vector Math library include path.") + ENDIF(WIN32) +ENDIF(USE_CUSTOM_VECTOR_MATH) + + +IF (APPLE OR MSVC) + OPTION(BUILD_MULTITHREADING "Use BulletMultiThreading" ON) +ELSE() + OPTION(BUILD_MULTITHREADING "Use BulletMultiThreading" OFF) +ENDIF() + +IF (BUILD_MULTITHREADING) + OPTION(USE_MULTITHREADED_BENCHMARK "Use Multithreaded Benchmark" OFF) + IF (USE_MULTITHREADED_BENCHMARK) + ADD_DEFINITIONS(-DUSE_PARALLEL_SOLVER_BENCHMARK -DUSE_PARALLEL_DISPATCHER_BENCHMARK) + ENDIF(USE_MULTITHREADED_BENCHMARK) + + IF (MSVC OR APPLE) + OPTION(BUILD_MINICL_OPENCL_DEMOS "Build OpenCL demos for MiniCL (Generic CPU)" ON) + ELSE() + OPTION(BUILD_MINICL_OPENCL_DEMOS "Build OpenCL demos for MiniCL (Generic CPU)" OFF) + ENDIF(MSVC OR APPLE) + + IF(MSVC) + FIND_PATH(DIRECTX_SDK_BASE_DIR Include/D3D11.h PATH $ENV{DXSDK_DIR} ) + IF(DIRECTX_SDK_BASE_DIR) + OPTION(USE_DX11 "Use DirectX 11" ON) + ELSE() + OPTION(USE_DX11 "Use DirectX 11" OFF) + ENDIF() + + FIND_PATH(AMD_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{ATISTREAMSDKROOT} $ENV{AMDAPPSDKROOT} ) + IF(AMD_OPENCL_BASE_DIR) + #AMD adds an extras slash at the end of the ATISTREAMSDKROOT variable + SET(AMD_OPENCL_INCLUDES ${AMD_OPENCL_BASE_DIR}/include ) + MESSAGE("AMD OPENCL SDK FOUND") + IF (CMAKE_CL_64) + SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86_64 ) + ELSE(CMAKE_CL_64) + SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86 ) + ENDIF(CMAKE_CL_64) + SET(CMAKE_ATISTREAMSDK_LIBRARY ${CMAKE_ATISTREAMSDK_LIBPATH}/OpenCL.lib ) + OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" ON) + IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY + ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) + ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) + ENDIF(CMAKE_CL_64) + ELSE() + OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" OFF) + ENDIF() + + FIND_PATH(INTEL_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{INTELOCLSDKROOT} ) + IF(INTEL_OPENCL_BASE_DIR) + SET(INTEL_OPENCL_INCLUDES ${INTEL_OPENCL_BASE_DIR}/include ) + MESSAGE("INTEL OPENCL SDK FOUND") + MESSAGE(${INTEL_OPENCL_INCLUDES}) + IF (CMAKE_CL_64) + SET(CMAKE_INTELOCLSDK_LIBPATH ${INTEL_OPENCL_BASE_DIR}/lib/x64 ) + ELSE(CMAKE_CL_64) + SET(CMAKE_INTELOCLSDK_LIBPATH ${INTEL_OPENCL_BASE_DIR}/lib/x86 ) + ENDIF(CMAKE_CL_64) + SET(INTEL_OPENCL_LIBRARIES ${CMAKE_INTELOCLSDK_LIBPATH}/OpenCL.lib) + OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" ON) + ELSE() + OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" OFF) + ENDIF() + + FIND_PATH(NVIDIA_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{CUDA_PATH} ) + IF(NVIDIA_OPENCL_BASE_DIR) + SET(NVIDIA_OPENCL_INCLUDES ${NVIDIA_OPENCL_BASE_DIR}/include ) + MESSAGE("NVIDIA OPENCL SDK FOUND") + MESSAGE(${NVIDIA_OPENCL_INCLUDES}) + IF (CMAKE_CL_64) + SET(CMAKE_NVSDKCOMPUTE_LIBPATH ${NVIDIA_OPENCL_BASE_DIR}/lib/x64 ) + ELSE(CMAKE_CL_64) + SET(CMAKE_NVSDKCOMPUTE_LIBPATH ${NVIDIA_OPENCL_BASE_DIR}/lib/Win32 ) + ENDIF(CMAKE_CL_64) + SET(NVIDIA_OPENCL_LIBRARIES ${CMAKE_NVSDKCOMPUTE_LIBPATH}/OpenCL.lib) + + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" ON) + ELSE() + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" OFF) + ENDIF() + ELSE(MSVC) + FIND_PATH(AMD_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{ATISTREAMSDKROOT} $ENV{AMDAPPSDKROOT} ) + IF(AMD_OPENCL_BASE_DIR) + #AMD adds an extras slash at the end of the ATISTREAMSDKROOT variable + SET(AMD_OPENCL_INCLUDES ${AMD_OPENCL_BASE_DIR}/include ) + MESSAGE("AMD OPENCL SDK FOUND") + MESSAGE(${AMD_OPENCL_INCLUDES}) + IF (CMAKE_CL_64) + SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86_64 ) + ELSE(CMAKE_CL_64) + SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86 ) + ENDIF(CMAKE_CL_64) + OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" ON) + SET(CMAKE_ATISTREAMSDK_LIBRARY OpenCL ) + ELSE() + OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" OFF) + ENDIF(AMD_OPENCL_BASE_DIR) + + FIND_PATH(INTEL_OPENCL_INCLUDES CL/cl.h) + FIND_PATH(INTEL_OPENCL_ICD_CFG intelocl64.icd /etc/OpenCL/vendors) + FIND_LIBRARY(INTEL_OPENCL_LIBRARIES OpenCL PATH /usr/lib64) + IF (INTEL_OPENCL_INCLUDES AND INTEL_OPENCL_LIBRARIES AND INTEL_OPENCL_ICD_CFG) + MESSAGE("INTEL OPENCL SDK FOUND") + MESSAGE(${INTEL_OPENCL_LIBRARIES}) + OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" ON) + ELSE () + MESSAGE("INTEL OPENCL NOT FOUND") + OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" OFF) + ENDIF () + + + FIND_PATH(NVIDIA_OPENCL_INCLUDES CL/cl.h) + FIND_PATH(NVIDIA_OPENCL_ICD_CFG nvidia.icd /etc/OpenCL/vendors) + FIND_LIBRARY(NVIDIA_OPENCL_LIBRARIES OpenCL PATH /usr/lib64 /usr/local/lib) + IF (NVIDIA_OPENCL_INCLUDES AND NVIDIA_OPENCL_LIBRARIES AND NVIDIA_OPENCL_ICD_CFG) + MESSAGE("NVidia OPENCL FOUND") + MESSAGE(${NVIDIA_OPENCL_LIBRARIES}) + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" ON) + ELSE () + MESSAGE("NVidia OPENCL NOT FOUND") + OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" OFF) + ENDIF () + ENDIF(MSVC) + +ELSE(BUILD_MULTITHREADING) +# SET(BUILD_NVIDIA_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for NVidia" FORCE) +# SET(BUILD_AMD_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for AMD" FORCE) +# SET(BUILD_INTEL_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for Intel (CPU)" FORCE) +# SET(BUILD_MINICL_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for MiniCL (Generic CPU)" FORCE) +# SET(USE_DX11 OFF CACHE BOOL "Use DirectX 11" FORCE) +# SET(USE_MULTITHREADED_BENCHMARK OFF CACHE BOOL "Use Multithreaded Benchmark" FORCE) +ENDIF(BUILD_MULTITHREADING) + + + + +#SET(CMAKE_EXE_LINKER_FLAGS_INIT "/STACK:10000000 /INCREMENTAL:NO") +#SET(CMAKE_EXE_LINKER_FLAGS "/STACK:10000000 /INCREMENTAL:NO") + +#MESSAGE("MSVC_INCREMENTAL_YES_FLAG"+${MSVC_INCREMENTAL_YES_FLAG}) + + +IF(MSVC) + IF (NOT USE_MSVC_INCREMENTAL_LINKING) + #MESSAGE("MSVC_INCREMENTAL_DEFAULT"+${MSVC_INCREMENTAL_DEFAULT}) + SET( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:NO") + + STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags ${CMAKE_EXE_LINKER_FLAGS_DEBUG}) + SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/INCREMENTAL:NO ${replacementFlags}" ) + MESSAGE("CMAKE_EXE_LINKER_FLAGS_DEBUG=${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + +# STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags2 ${CMAKE_EXE_LINKER_FLAGS}) +# SET(CMAKE_EXE_LINKER_FLAGS ${replacementFlag2}) +# STRING(REPLACE "INCREMENTAL:YES" "" replacementFlags3 ${CMAKE_EXTRA_LINK_FLAGS}) +# SET(CMAKE_EXTRA_LINK_FLAGS ${replacementFlag3}) + + + STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags3 ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}) + SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacementFlags3}) + SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/INCREMENTAL:NO ${replacementFlags3}" ) + + ENDIF (NOT USE_MSVC_INCREMENTAL_LINKING) + + IF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) + #We statically link to reduce dependancies + FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + IF(${flag_var} MATCHES "/MD") + STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + ENDIF(${flag_var} MATCHES "/MD") + IF(${flag_var} MATCHES "/MDd") + STRING(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}") + ENDIF(${flag_var} MATCHES "/MDd") + ENDFOREACH(flag_var) + ENDIF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) + + OPTION(USE_MSVC_SSE "Use MSVC /arch:sse option" ON) + IF (USE_MSVC_SSE) + ADD_DEFINITIONS(/arch:SSE) + ENDIF() + OPTION(USE_MSVC_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON) + IF (USE_MSVC_FAST_FLOATINGPOINT) + ADD_DEFINITIONS(/fp:fast) + ENDIF() +ENDIF(MSVC) + + + +IF (WIN32) +OPTION(INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES "Create MSVC projectfiles that can be distributed" OFF) + +IF (INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + SET (LIBRARY_OUTPUT_PATH ${BULLET_PHYSICS_SOURCE_DIR}/lib CACHE PATH "Single output directory for building all libraries.") + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${BULLET_PHYSICS_SOURCE_DIR}) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${BULLET_PHYSICS_SOURCE_DIR}) +ELSE() + SET (LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib CACHE PATH "Single output directory for building all libraries.") +ENDIF() + + + +OPTION(INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES "Create MSVC projectfiles with relative paths" OFF) +OPTION(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES "Add MSVC postfix for executable names (_Debug)" OFF) + +SET(CMAKE_DEBUG_POSTFIX "_Debug" CACHE STRING "Adds a postfix for debug-built libraries.") +SET(CMAKE_MINSIZEREL_POSTFIX "_MinsizeRel" CACHE STRING "Adds a postfix for MinsizeRelease-built libraries.") +SET(CMAKE_RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo" CACHE STRING "Adds a postfix for ReleaseWithDebug-built libraries.") + + + + + +IF (INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) +SET(CMAKE_SUPPRESS_REGENERATION 1) +SET(CMAKE_USE_RELATIVE_PATHS 1) +ENDIF(INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) + +ENDIF (WIN32) + + +OPTION(BUILD_CPU_DEMOS "Build original Bullet CPU demos" ON) + + + +OPTION(INTERNAL_UPDATE_SERIALIZATION_STRUCTURES "Internal update serialization structures" OFF) +IF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) +ADD_DEFINITIONS( -DBT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) +ENDIF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) + +IF (USE_DOUBLE_PRECISION) +ADD_DEFINITIONS( -DBT_USE_DOUBLE_PRECISION) +SET( BULLET_DOUBLE_DEF "-DBT_USE_DOUBLE_PRECISION") +ENDIF (USE_DOUBLE_PRECISION) + +IF(USE_GRAPHICAL_BENCHMARK) +ADD_DEFINITIONS( -DUSE_GRAPHICAL_BENCHMARK) +ENDIF (USE_GRAPHICAL_BENCHMARK) + +IF (WIN32) +OPTION(USE_GLUT "Use Glut" ON) +ADD_DEFINITIONS( -D_IRR_STATIC_LIB_ ) +ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS ) +ADD_DEFINITIONS( -D_CRT_SECURE_NO_DEPRECATE ) +ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS ) + +IF (USE_GLUT AND MSVC) + string (REPLACE "/D_WINDOWS" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + remove_definitions(-D_WINDOWS ) +ENDIF() + + + +ELSE(WIN32) +OPTION(USE_GLUT "Use Glut" ON) +ENDIF(WIN32) + + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + + +# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system +# This should be the case. + +FIND_PACKAGE(OpenGL) +IF (OPENGL_FOUND) + MESSAGE("OPENGL FOUND") + MESSAGE(${OPENGL_LIBRARIES}) +ELSE (OPENGL_FOUND) + MESSAGE("OPENGL NOT FOUND") + SET(OPENGL_gl_LIBRARY opengl32) + SET(OPENGL_glu_LIBRARY glu32) +ENDIF (OPENGL_FOUND) + +# ADD_DEFINITIONS(-DBT_USE_FREEGLUT) + +FIND_PACKAGE(GLU) + +IF (USE_GLUT) + FIND_PACKAGE(GLUT) + IF (GLUT_FOUND) + MESSAGE("GLUT FOUND") + MESSAGE(${GLUT_glut_LIBRARY}) + ELSE (GLUT_FOUND) + IF (MINGW) + MESSAGE ("GLUT NOT FOUND not found, trying to use MINGW glut32") + SET(GLUT_glut_LIBRARY glut32) + #TODO add better GLUT detection for MinGW + SET(GLUT_FOUND TRUE) + ENDIF (MINGW) + IF (MSVC) + SET(GLUT_FOUND TRUE) + IF (CMAKE_CL_64) + message("Win64 using Glut/glut64.lib") + SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut64.lib) + ELSE(CMAKE_CL_64) + message("Win32 using Glut/glut32.lib") + SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib) + ENDIF (CMAKE_CL_64) + INCLUDE_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/Glut) + ELSE() + MESSAGE("GLUT NOT FOUND") + ENDIF (MSVC) + ENDIF (GLUT_FOUND) + + IF(NOT WIN32) + # This is added for linux. This should always work if everything is installed and working fine. + INCLUDE_DIRECTORIES(/usr/include /usr/local/include) + ENDIF() +ENDIF(USE_GLUT) + + +OPTION(BUILD_DEMOS "Set when you want to build the demos" ON) +IF(BUILD_DEMOS) + IF(EXISTS ${BULLET_PHYSICS_SOURCE_DIR}/Demos AND IS_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}/Demos) + SUBDIRS(Demos) + ENDIF() +ENDIF(BUILD_DEMOS) + +# "Demos_ps3") +IF (MSVC) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF(EXISTS ${BULLET_PHYSICS_SOURCE_DIR}/Demos_ps3 AND IS_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}/Demos_ps3) + MESSAGE("Demos_ps3 found") + SUBDIRS(Demos_ps3) + ENDIF() + ENDIF() +ENDIF(MSVC) + + +OPTION(BUILD_EXTRAS "Set when you want to build the extras" ON) +IF(BUILD_EXTRAS) + SUBDIRS(Extras) +ENDIF(BUILD_EXTRAS) + +#Maya Dynamica plugin is moved to http://dynamica.googlecode.com + +SUBDIRS(src) + +IF("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") + OPTION(INSTALL_LIBS "Set when you want to install libraries" ON) +ELSE() + IF(APPLE AND FRAMEWORK) + OPTION(INSTALL_LIBS "Set when you want to install libraries" ON) + ELSE() +#by default, don't enable the 'INSTALL' option for Xcode and MSVC projectfiles + OPTION(INSTALL_LIBS "Set when you want to install libraries" OFF) + ENDIF() +ENDIF() + +IF(INSTALL_LIBS) + SET (LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" ) + SET (LIB_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE STRING "Library directory name") + ## the following are directories where stuff will be installed to + SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/bullet/" CACHE PATH "The subdirectory to the header prefix") + SET(PKGCONFIG_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig/" CACHE STRING "Base directory for pkgconfig files") + IF(NOT WIN32) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/bullet.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/bullet.pc @ONLY) + INSTALL( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/bullet.pc + DESTINATION + ${PKGCONFIG_INSTALL_PREFIX}) + ENDIF(NOT WIN32) +ENDIF(INSTALL_LIBS) + +#INSTALL of other files requires CMake 2.6 +IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + OPTION(INSTALL_EXTRA_LIBS "Set when you want extra libraries installed" OFF) +ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + +OPTION(BUILD_UNIT_TESTS "Build Unit Tests" OFF) + +IF (BUILD_UNIT_TESTS) + SUBDIRS(UnitTests) +ENDIF() diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..794842d --- /dev/null +++ b/COPYING @@ -0,0 +1,17 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2011 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +All files in the Bullet/src folder are under this Zlib license. +Files in the Extras and Demos folder may have a different license, see the respective files. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..4a0ccf4 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,791 @@ +Bullet Continuous Collision Detection and Physics Library +Primary author and maintainer: Erwin Coumans + +This ChangeLog is incomplete, for an up-to-date list of all fixed issues see http://bullet.googlecode.com +using http://tinyurl.com/yabmjjj + +2012 September 10 + - Bullet 2.81 release preparation + +2011 September 15 + - Bullet 2.79 release, revision 2433 (mainly a bugfix release) + - Revert a change in 2.78 related to speculative contacts (it has undesired side effects) + - Use HACD Hierachical Approximate Convex Decomposition (thanks to Khaled Mammou and Sujeon Kim) + - Add Intel cmake-build support for OpenCL accelerated cloth/particle + - add premake4 build system support to autogenerate visual studio project files that can be shipped (see msvc folder) + - preliminary build support for Google NativeClient, using premake4 (see msvc folder) + + +2011 April 8 + - Bullet 2.78 release 2383 + - Added FractureDemo + - Added Separatinx Axis Test and Polyhedral Clipping support (See InternalEdgeDemo) + - Added speculative contacts as CCD response method (See CcdPhysicsDemo) + - OpenCL and DirectCompute cloth as basic support for capsule collision + +2010 September 7 + - autotools now uses CamelCase naming for libraries just like cmake: + libbulletdynamics -> libBulletDynamics, libbulletmath -> libLinearMath + +2010 July 21 + - Preparing for Bullet 2.77 release, around revision r2135 + - Added an OpenCL particle demo, running on NVidia, AMD and MiniCL + Thanks to NVidia for the original particle demo from their OpenCL SDK + - Added GPU deformable object solvers for OpenCL and DirectCompute, and a DirectX 11 cloth demo + Thanks to AMD + - Create a separate library for MiniCL, + MiniCL is a rudimentary OpenCL wrapper that allows to compile OpenCL kernels for multi-core CPU, using Win32 Threads or Posix + - Moved vectormath into Bullet/src, and added a SSE implementation + - Added a btParallelConstraintSolver, mainly for PlayStation 3 Cell SPUs (although it runs fine on CPU too) + +2010 March 6 + - Dynamica Maya plugin (and COLLADA support) is moved to http://dynamica.googlecode.com + +2010 February + - Bullet 2.76 release, revision 2010 + - support for the .bullet binary file format + - btInternalEdgeUtility to adjust unwanted collisions against internal triangle edges + - Improved Maya Dynamica plugin with better constraint authoring and .bullet file export + + +2009 September 17 + - Minor update to Bullet 2.75 release, revision 1776 + - Support for btConvex2dShape, check out Bullet/Demos/Box2dDemo + - Fixes in build systems + - Minor fix in btGjkPairDetector + - Initialize world transform for btCollisionShape in constructor + + +2009 September 6 + - Bullet 2.75 release + - Added SPH fluid simulation in Extras, not integrated with rigid body / soft body yet + Thanks to Rama Hoetzlein to make this contribution available under the ZLib license + - add special capsule-capsule collider code in btConvexConvexCollisionAlgorithm, to speed up capsule-ragdolls + - soft body improvement: faster building of bending constraints + - soft body improvement: allow to disable/enable cluster self-collision + - soft body fix: 'exploding' soft bodies when using cluster collision + - fix some degenerate cases in continuous convex cast, could impact ray cast/convex cast + Thanks to Jacob Langford for the report and reproduction cases, see http://code.google.com/p/bullet/issues/detail?id=250&can=1&start=200 + - re-enabled split impulse + - added btHinge2Constraint, btUniversalConstraint, btGeneric6DofSpringConstraint + - demonstrate 2D physics with 2D/3D object interaction + + +2008 December 2 + - Fix contact refresh issues with btCompoundShape, introduced with btDbvt acceleration structure in btCompoundCollisionAlgorithm + - Made btSequentialImpulseConstraintSolver 100% compatible with ODE quickstep + constraints can use 'solveConstraint' method or 'getInfo/getInfo2' + +2008 November 30 + - Add highly optimized SIMD branchless PGS/SI solver innerloop + +2008 November 12 + - Add compound shape export to BulletColladaConverter + Thanks to JamesH for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=12&t=2840 + - Fix compiler build for Visual Studio 6 + Thanks to JoF for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2841 + +2008 November 11 + - Add CProfileManager::dumpAll() to dump performance statistics to console using printf. + - Add support for interaction between btSoftBody and btCollisionObject/btGhostObject + +2008 November 8 + - Fix PosixThreadSupport + - Add improved btHeightfieldTerrainShape support and new Demos/TerrainDemo + Thanks to tomva, http://code.google.com/p/bullet/issues/detail?id=63&can=1 + - Moved kinematic character controller from Demos/CharacterDemo into src/BulletDynamics/Character/btKinematicCharacterController.cpp + +2008 November 6 + - reduced default memory pool allocation from 40Mb to 3Mb. This should be more suitable for all platforms, including iPhone + - improved CUDA broadphase + - IBM Cell SDK 3.x support, fix ibmsdk Makefiles + - improved CMake support with 'install' and 'framework option + +2008 November 4 + - add btAxisSweep::resetPool to avoid non-determinism due to shuffled linked list + Thanks to Ole for the contribution, + +2008 October 30 + - disabled btTriangleMesh duplicate search by default, it is extremely slow + - added Extras/IFF binary chunk serialization library as preparation for in-game native platform serialization (planned COLLADA DOM -> IFF converter) + +2008 October 20 + - added SCE Physics Effects box-box collision detection for SPU/BulletMultiThreaded version + See Bullet/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp + Thanks to Sony Computer Entertainment Japan, SCEI for the contribution + +2008 October 17 + - Added btGhostObject support, this helps character controller, explosions, triggers and other local spatial queries + +2008 October 10 + - Moved aabb to btBroadphaseProxy, improves rayTest dramatically. Further raytest improvements using the broadphase acceleration structures are planned + - Moved BulletMultiThreaded from Extras to /src/BulletMultiThreaded for better integration + + +2008 October 3 + - Add support for autoconf automake + ./autogen.sh and ./configure will create both Makefile and Jamfile. CMake and autogenerated Visual Studio projectfiles remain supported too. + - Improved ColladaConverter: plane shape export, and callback for shape construction to allow deletion of memory + +2008 Sept 30 + - Improved Soft Body support, fixed issues related to soft body colliding against concave triangle meshes + - Shared more code between regular version and SPU/BulletMultiThreaded, in particular GJK/EPA + +2008 Sept 28 + - Fixed rotation issues in Dynamic Maya Plugin + +2008 Sept 11 + - Enable CCD motion clamping for btDiscreteDynamicsWorld, to avoid tunneling. A more advanced solution will be implemented in btContinuousDynamicsWorld. + +2008 Sept 7 + - Add btScaledBvhTriangleMeshShape, to allow re-use of btBvhTriangleMeshShape of different sizes, without copying of the BVH data. + +2008 Sept 5 + - Enabled Demos/ForkLiftDemo + Thanks Roman Ponomarev. + +2008 Sept 4 + - Added btCudaBroadphase in Extras/CUDA: some research into accelerating Bullet using CUDA. + Thanks to the particle demo from the NVidia CUDA SDK. + +2008 Sept 3 + - Several bug fixes and contributions related to inertia tensor, memory leaks etc. + Thanks to Ole K. + +2008 Sept 1 + - Updated CDTestFramework, with latest version of OPCODE Array SAP. See Extras/CDTestFramework + Thanks to Pierre Terdiman for the update + +2008 August 25 + - Walt Disney Studios contributes their in-house Maya Plugin for simulating Bullet physics, with options for other engines such as PhysBam or PhysX. + Thanks to Nicola Candussi and Arthur Shek + +2008 August 14 + - Improved performance for btDbvtBroadphase, based on dual dynamic AABB trees (one for static, one for dynamic objects, where objects can move from one to the other tree) + Thanks to Nathanael Presson again, for all his work. + +2008 July 31 + - Added Havok .hkx to COLLADA Physics .dae converter patch+information + - Fix btSubsimplexConvexCast + Thanks to Nacho, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2422) + - Fix in rendering, GL_STENCIL + - btTriangleIndexVertexArray indices should be unsigned int/unsigned short int, + - Made InternalProcessAllTriangles virtual, thanks to + Both thank to Fullmetalcoder, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2401 + - clamp impulse for btPoint2PointConstraint + Thanks to Martijn Reuvers, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2418 + - Free memory of bvh, pass in scaling factor (optional) + Thanks to Roy Eltham, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2375 + +2008 July 27 + +btDbvtBroadphase: + - Fixed a performance issues reported by 'reltham' + - Added btDbvtBroadphase::optimize() for people who want good performances right +away or don't do dynamics. + - fixed compilation issues when DBVT_BP_PROFILE was set. +btSoftBody: + - Fixed singular matrix issues related to polar decomposition (flat meshes). +DemoApplication: + - Shadows (enable/disable through 'g' or DemoApplication::setShadows(bool)). + - Texture can be enable/disable through 'u' +CDFramework: + - fixed compilation issues. + All thanks to Nathanael Presson + +2008 July 10 + - Added btMultimaterialTriangleMeshShape and MultiMaterialDemo + Thanks to Alex Silverman for the contribution + +2008 June 30 + - Added initial support for kinematic character controller + Thanks to John McCutchan + +2008 April 14 + - Added ray cast support for Soft Bodies + Thanks to Nathanael Presson for the contribution + +2008 April 9 + - Cleanup of Stan Melax ConvexHull, removed Extras/ConvexHull, moved sources into LinearMath/BulletCollision + +2008 April 4 + - Added btSliderConstraint and demo + Thanks Roman Ponomarev + +2008 April 3 + - Fixed btMinkowskiSumShape, and added hitpoint to btSubsimplexConvexCast + +2008 April 2 + - Added Extras/CdTestFrameWork + Thanks Pierre Terdiman + +2008 April 1 + - Added posix thread (pthread) support + Thanks Enrico + +2008 March 30 + - Added Soft Body, cloth, rope and deformable volumes, including demos and interaction + Thanks Nathanael Presson for this great contribution + + 2008 March 17 + - Improved BulletColladaConverter + Thanks John McCutchan + +2008 March 15 + - btMultiSapBroadphase in a working state. Needs more optimizations to be fully useable. + - Allow btOptimizedBvh to be used for arbitrary objects, not just triangles + - added quicksort to btAlignedObjectArray + - removed btTypedUserInfo, added btHashMap + +2008 March 30 + - Moved quickstep solver and boxbox into Bullet/src folder + Thanks Russell L. Smith for permission to redistribute Open Dynamics Engine quickstep and box-box under the ZLib license + +2008 Feb 27 + - Added initial version for Character Control Demo + - Applied fixes to IBM Cell SDK 3.0 build makefiles + Thanks Jochen and mojo for reporting/providing patch: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1922 + +2008 Feb 8 + - Bugfixes in ConvexCast support against the world. + Thanks to Isgmasa for reporting/providing fix: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1823 + +2008 Feb 6 + - Added btCapsuleShapeX and btCapsuleShapeZ for capsules around X and Z axis (default capsule is around Y) + +2008 Feb 3 + - Added btTypedUserInfo, useful for serialization + +2008 Jan 31 + - Add support for 16 and 32-bit indices for SPU / BulletMultiThreaded version. + +2008 Jan 29 + - Added COLLADA Physics export/serialization/snapshot from any Bullet btDynamicsWorld. Saving the physics world into a text .xml file is useful for debugging etc. + +2008 Jan 23 + - Added Stan Melax Convex Hull utility library in Extras/ConvexHull. This is useful to render non-polyhedral convex objects, and to simplify convex polyhedra. + +2008 Jan 14 + - Add support for batch raycasting on SPU / BulletMultiThreaded + +2007 Dec 16 + - Added btRigidBodyConstructionInfo, to make it easier to set individual setting (and leave other untouched) during rigid body construction. + Thanks Vangelis Kokkevis for pointing this out. + - Fixed memoryleak in the ConstraintDemo and Raytracer demo. + - Fixed issue with clearing forces/gravity at the end of the stepSimulation, instead of during internalSingleStepSimulation. + Thanks chunky for pointing this out: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1780 + - Disabled additional damping in rigid body by default, but enable it in most demos. Set btRigidBodyConstructionInfo m_additionalDamping to true to enable this. + - Removed obsolete QUICKPROF BEGIN/END_PROFILE, and enabled BT_PROFILE. Profiling is enabled by default (see Bullet/Demos/OpenGL/DemoApplication.cpp how to use this). + User can switch off profiling by enabling define BT_NO_PROFILE in Bullet/src/btQuickprof.h. + +2007 Dec 14 + - Added Hello World and BulletMultiThreaded demos + - Add portable version of BulletMultiThreaded, through SequentialThreadSupport (non-parallel but sharing the same code-path) + - Add Cmake support for AllBulletDemos + + +2007 Dec 11 + - Moved the 'btRigidBody::clearForce' to the end of the stepSimulation, instead of in each substep. + See discussion http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1601 + - Added btConvexPlaneCollisionAlgorithm, makes planes perform better, and prevents tunneling + Thanks Andy O'Neil for reporting the performance/functionality issue + - Fixes for IBM Cell SDK 3.0 + Thanks to Jochen Roth for the patch. + +2007 Dec 10 + - Fixes in btHeightfieldTerrainShape + Thanks to Jay Lee for the patch. + +2007 Dec 9 + - Only update aabb of active objects + Thanks Peter Tchernev for reporting (http://bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1764 ) + - Added workaround to compile libxml under Visual Studio 2008 Beta 2 + - Make glui compile under MSVC 9.0 beta (vsnprintf is already defined) + +2007 Dec 6 + - Added DynamicControlDemo, showing dynamic control through constraint motors + Thanks to Eddy Boxerman + - Add support for generic concave shapes for convex cast. + - Added convex cast query to collision world. + - Added workaround for OpenGL bug in Mac OS X 10.5.0 (Leopard) + - Added concave raycast demo + All above thanks to John McCutchan (JMC) + - Fixed issues that prevent Linux version to compile. + Thanks to Enrico for reporting and patch, see + - Fixed misleading name 'numTriangleIndices' into 'numTriangles' + Thanks Sean Tasker for reporting: + +2007 Nov 28: + - Added raycast against trianglemesh. Will be extended to object cast soon. + Thanks John McCutchan (JMC) + - make getNumPoints const correct, add const getPoints(). + Thanks Dirk Gregorius + - Bugfix: allow btCollisionObjects (non-btRigidBody) to interact properly with btRigidBody for cache-friendly btSequentialImpulseConstraintSolver. + Thanks Andy O'Neil for pointing this out. + - Bugfix: don't fail if spheres have identical center, use arbitrary separating normal (1,0,0) + Thanks Sean Tasker for reporting! http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1681 + + +2007, November 20 + - Added hierarchical profiling + - Fixed memory leak in btMultiSapBroadphase, + - Fixed hash function (typo, should use 2 proxies) + Thanks to Stephen (shatcher) for reporting and fixes! http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1696 + +2007 Nov 11 + - Fixed parallel solver (BulletMultiThreaded) friction issue + - Terminate Win32 Threads when closing the CcdPhysicsDemo (when USE_PARALLEL_SOLVER/USE_PARALLEL_DISPATCHER is defined) + +2007 Nov 6 + - Added support for 16-bit indices for triangle meshes + - Added support for multiple mesh parts using btBvhTriangleMeshShape. + Thanks to Tim Johansson + +2007 Oct 22 + - All memory allocations go through btAlignedAlloc/btAlignedFree. User can override this to verify memory leaks + - added a few more demos to AllBulletDemos + - fix for one of the constructors of btHingeConstraint + Thanks Marcus Hennix + +2007 Oct 20 + - included glui, a GLUT/OpenGL based toolkit for some graphical user elements + Removed dynamic_cast from glui, to allow linkage without rtti + - added Box2D framework using glui, allowing all demos to run within one executable + Thanks Erin Catto for the FrameWork skeleton (http://www.box2d.org) + +2007 Ocy 17 + - Allow user to pass in their own memory (stack and pool) allocators, through collisionConfiguration. See demos how to use this + +2007 Oct 14 + - Included working version of Cell SPU parallel optimized version for Libspe2 SPU task scheduler. + This version compiles and runs on Playstation 3 Linux and IBM CellBlade, see BulletSpuOptimized.pdf for build instructions + (Official Playstation 3 developers can request a SPURS version through Sony PS3 Devnet.) + Thanks to IBM 'Extreme Blue' project for the contribution + http://www-913.ibm.com/employment/us/extremeblue/ + Thanks Minh Cuong Tran, Benjamin Hoeferlin, Frederick Roth and Martina Huellmann + for various contributions to get this initial Libspe2 parallel version up and running. + +2007 Oct 13 + - made 'btCollisionShape::calculateLocalInertia' const + Thanks to cgripeos, see http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1514 + - applied a large patch to remove warnings + Thanks to Enrico, see http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1568 + - removed SSE includes, added #incude for memset in Extras/quickstep, thanks Eternl Knight + +2007 Oct 11 + - added Hashed Overlapping Pair Cache, recommended by Pierre Terdiman. It works like a charm, thanks Pierre and Erin Catto (code from Box2D) + - modified some margins inside btBoxShape, btCylinderShape and btSphereShape + - added cone debug rendering (for cones with x, y and z up-axis) + - added improvements for optional Extra/quickstep, thanks to Remotion + - some performance improvements for Bullet constraint solver + +2007 Sept 28 + - upgraded GIMPACT to version 0.3 + Thanks to Francisco Leon + +2007 Sept 27 + - added contribution from IBM Extreme Blue project for Libspe2 support. This allow to execute BulletMultiThreaded on Cell SPU under PS3 Linux and Cell Blade. See http://www-913.ibm.com/employment/us/extremeblue + Thanks to Minh Cuong Tran, Frederick Roth, Martina Heullmann and Benjamin Hoeferlin. + +2007 Sept 13 + - Improved btGenericD6Constraint. It can be used to create ragdolls (similar to the new btConeTwistConstraint). See GenericJointDemo + - Added support for Bullet constraints in the optional Extras/quickstep ODE solver. See CcdPhysicsDemo, enable #COMPARE_WITH_QUICKSTEP and add libquickstep to the dependencies. + For both patches/improvements thanks Francisco Leon/projectileman + +2007 Sept 10 + - removed union from btQuadWordStorage, it caused issues under certain version of gcc/Linux + +2007 Sept 10 + - Reverted constraint solver, due to some issues. Need to review the recent memory allocation changes. + - Fixed issue with kinematic objects rotating at low speed: quaternion was de-normalized, passing value > 1 into acosf returns #IND00 invalid values + - 16 byte memory alignment for BVH serialization + - memory cleanup for btPoolAllocator + +2007 Sept 9 + - Added serialization for BVH/btBvhTriangleMeshShape, including endian swapping. See ConcaveDemo for an example. + Thanks to Phil Knight for the contribution. + - Fixed issues related to stack allocator/compound collision algorithm + Thanks Proctoid, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=18&t=1460 + - Increase some default memory pool settings, and added a fallback for the constraints solver to use heap memory + - Removed accidential testing code in btScalar.h related to operator new. + - Enable btAxis3Sweep and bt32BitAxis3Sweep to be linked in at the same time, using template + +2007 Sept 7 + - Replaced several dynamic memory allocations by stack allocation and pool allocations + - Added branch-free quantized aabb bounding box overlap check, works better on Playstation 3 and XBox 360 + Thanks to Phil Knight. Also see www.cellperformance.com for related articles + - Collision algorithms and settings for the memory/stack allocator can be done using btDefaultCollisionConfiguration + This is an API change. See demos how to modify existing implementations with a one-liner. + - Register several collision algorithms by default (sphere-sphere, sphere-box, sphere-triangle) + - Use other traveral method for BVH by default, this improves triangle mesh collision performance. + +2007 Aug 31 + - fixed MSVC 6 build + Thanks Proctoid, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1375 + - fixed double precision build issues + Thanks Alex Silverman, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1434 + +2007 Aug 24 + - fixed bug in btMatrix3x3::transposeTimes(const btMatrix3x3& m) const. Luckily it wasn't used in core parts of the library (yet). + Thanks to Jay Lee + +2007 Aug 15 + - fixed bug in Extras/GIMPACT 0.2 related to moving triangle meshes + Thanks Thomas, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1368 + +2007 Aug 14 + - added parallel constraint solver. Works on Playstation 3 Cell SPU and multi core (Win Threads on PC and XBox 360). + See Extras/BulletMultiThreaded for SpuSolverTask subfolder and SpuParallelSolver.cpp + Thanks Marten Svanfeldt (Starbreeze Studios) + - fixed some bugs related to parallel collision detection (Extras/BulletMultiThreaded) + Thanks Marten Svanfeldt (Starbreeze Studios) + +2007 Aug 2 + - added compound and concave-convex (swapped) case for BulletMultiThreaded collision detection, thanks to Marten Svanfeldt + - refactored broadphase and overlapping pair cache. This allows performance improvement by combining multiple broadphases. This helps add/remove of large batches of objects and large worlds. See also Pierre Terdiman forum topic: + http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329 + + +2007 July 27 + - added Ragdoll Demo + Thanks to Marten Svanfeldt (Starbreeze Studios) + + - added Vector Math library for SIMD 3D graphics linear algebra (vector, matrix, quaternion) + See Bullet/Extras/vectormathlibrary + Supports SIMD SSE, PowerPC PPU and Cell SPU (including PS3 Linux and CellBlade), as well as generic portable scalar version + Will be used to improve BulletMultiThreaded performance + Open Sourced by Sony Computer Entertainment Inc. under the new BSD license + - added SIMD math library + 4-way SIMD for common math functions like atan2f4, cosf4, floorf4, fabsf4, rsqrtf4 etc. Used by Vector Math library under PPU and SPU. + Supports PowerPC (PPU) and Cell SPU, including PS3 Linux and CellBlade. + See Bullet/Extras/simdmathlibrary + Open sourced by Sony Computer Entertainment Inc. under the new BSD license + + +2007 July 25 + - added several patches: per-rigidbody sleeping threshold. added Assert to prevent deletion of rigidbody while constraints are still pointing at it + Thanks to Marten Svanfeldt (Starbreeze Studios) + +2007 July 13 + - fixed relative #include paths again. We can't use "../" relative paths: some compilers choke on it (it causes extreme long paths) + Within the libraries, we always need to start with "BulletCollision/" or "BulletDynamics/ or "LinearMath/" + +2007 July 10 + - Updated Bullet User Manual + +2007 July 5 + - added btConeTwistConstraint, especially useful for ragdolls. See Demos/RagdollDemo + Thanks to Marten Svanfeldt (Starbreeze Studios) + +2007 June 29 + - btHeightfieldTerrainShape: Added heightfield support, with customizations + - Upgraded to GIMPACT 0.2, see Extras/GIMPACT and MovingConcaveDemo + - Several patches from Marten Svanfeldt (Starbreeze Studios) + Improved collision filtering (in broadphase and rigidbody) + Improved debug rendering + Allow to set collision filter group/mask in addRigidBody + + +2007 June 15 + - Changed btAlignedObjectArray to call copy constructor/replacement new for duplication, rather then assignment operator (operator=). + +2007 June 11 + - Added multi-threading. Originally for Playstation 3 Cell SPU, but the same code can run using Win32 Threads using fake DMA transfers (memcpy) + Libspe2 support for Cell Blade / PS3 Linux is upcoming + See Extras/BulletMultiThreaded. Usage: replace btCollisionDispatcher by btSpuGatheringCollisionDispatcher + + - Added managed Bullet library, entirely rewritten in C# for Windows and XBox 360 XNA + See Extras/BulletX + Thanks to KleMiX, aka Vsevolod Klementjev + +2007 May 31 + - sign-bit went wrong in case of 32-bit broadphase, causing quantization problems. + Thanks DevO for reporting. + +2007 May 23 + - Fixed quantization problem for planar triangle meshes in btOptimizedBvh + Thanks Phil Knight for reporting and helping to fix this bug. + +2007 May 20 + - btAxisSweep3: Fixed a bug in btAxisSweep3 (sweep and prune) related to object removal. Only showed up when at least one btStaticPlaneShape was inserted. + Thanks tbp for more details on reproducing case. + - btAxisSweep3: Fixed issue with full 32bit precision btAxisSweep3 (define BP_USE_FIXEDPOINT_INT_32), it used only 0xffff/65536 for quantization instead of full integer space (0xffffffff) + - btRaycastVehicle: Added 'getForwardVector' and getCurrentSpeedKmHour utility functions + - Fixed local scaling issues (btConvexTriangleMeshShape, btBvhTriangleMeshShape, removed scaling from btMatrix3x3). + Thanks Volker for reporting! + - Added second filename search, so that starting BspDemo and ConvexDecompositionDemo from within Visual Studio (without setting the starting path) still works + +2007 April 22 + - Added braking functionality to btRaycastVehicle + - Removed tons of warnings, under MSVC 2005 compilation in -W4 + +2007 March 21 + - Fixed issues: comma at end of enum causes errors for some compilers + - Fixed initialization bug in LocalRayResult ( m_localShapeInfo(localShapeInfo) ) + +2007 March 20 + - Added refit tree to quantized stackless tree, and updated ConcaveDemo as example. + +2007 March 17 + - Added constraint solver optimizations, avoiding cross products during iterations, and gather rigidbody/constraint info in contiguous memory (btSolverBody/btSolverConstraint) + - These optimizations don't give large benefit yet, but it has good potential. Turned on by default. Can be switched off using solver->setSolverMode(SOLVER_RANDMIZE_ORDER). + - Enabled anti-jitter for rigid bodies. This is experimental, and can be switched off by setting a global (it is experimental so no proper interface) gJitterVelocityDampingFactor = 1.0; + - Fixed bug in islandmanifold.heapSort(btPersistentManifoldSortPredicate()); , thanks Noehrgel for reporting this (affected Sun Solaris) + +2007 March 12 + - Added compile-time toggle between on 16-bit and 32-bit fixed-point SAP broadphase. + This allows the number of bodies to exceed 32767 + - Enable useQuantizedAabbCompression on btTriangleMesh, see ColladaDemo + +2007 March 8 + - Fixed bug in constraint/island sorting (caused by replacing STL by dedicated btAlignedObjectArray with heapSort) + Thanks Clemens Unterkofler for pointing this out! + +2007 March 6 + - removed STL from the Bullet library: replace std::vector by btAlignedObjectArray. Also removed the std::set for overlapping pair set, and turned it into an overlapping pair array. The SAP only adds objects, never removed. Removal is postponed for during traversal of overlapping pairs (duplicates and non-overlapping pairs are removed during that traversal). + - added heap sort and binary search/linear search to btAlignedObjectArray + - fixed wrong cast, thanks Hamstray, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1015 + + +2007 Feb 25 + - Improved performance of convex collision shapes, cache local AABB instead of recomputation. This fixes issue with very slow performance in larger .bsp levels + +2007 Feb 24 + - Added compressed/quantized AABB tree, 16 bytes per node, while supporting 32-bit (triangle) indices. + Should be faster and smaller then original version (quantized aabb check is done in integer space) + Original aabb tree nodes are still supported. They are 44 bytes, with full floating point precision and additional subPart index. + - added meter-unit scaling support in ColladaConverter.cpp + +2007 Feb 21 + - Build system: updated bullet.pc.in library names + - Updated EPA comparison integration (missing parameter) + +2007 Jan 04 + - fixed optimized AABB tree building: in some cases the tree building fails due to unbalanced trees, which generated stack overflow + +2006 Dec 15 + - added contribution to allow double precision collision detection/dynamics. Define BT_USE_DOUBLE_PRECISION in your project and libraries that include Bullet + +2006 Dec 14 + - merged contact and non-contact constraint solving into one loop, will improve stability of jointed bodies during collisions + - added first draft for hingeConstraint motor + +2006 Dec 8, Erwin Coumans + - preparation for SIMD: added btAlignedAllocator and btAlignedObjectArray, to replace stl std::vector, same interface, but compatible with 16 byte alignment + - cleaned up dependencies in autogenerated msvc projectfiles + - aligned btVector3 on 16 bytes boundary, under win32. see if developers will come up with problems + +2006 Dec 04, Erwin Coumans + Added btNearCallback. This is similar to Open Dynamics Engine (ODE) dNearCallback, but important differences: + - contact points are persistent (lifetime more then one frame, for warmstarting/incremental contact point management) + - continuous collision detection, time of impact + Added btRigidBody::isInWorld(), returns true if btRigidBody is inside a btCollisionWorld/btDynamicsWorld derived class + Added angularFactor to btRigidbody, this helps some character control (no angular impulse applied) + + +2006 Nov 28 + Moved StackAlloc from EPA into LinearMath/btStackAlloc + renamed internal class ConcaveShape into btConcaveShape + added btHeightfieldTerrainShape (not completed yet) + +2006 Nov 15 Nathanael Presson + Added EPA penetration depth algorithm, Expanding Polytope Algorithm + Added Pierre Terdiman penetration depth comparison/test DEMO + Fixed Bullet's Minkowski sampling penetration depth solver + Contributed by Nathanael Presson + +2006 Nov 11 Francisco León Nájera + Added GIMPACT trimesh collision detection: concave versus concave, + Contributed by Francisco León Nájera + +2006 Nov 2 + Minor refactoring: btCollisionObject changes from struct into class, added accessor methods + Force use of btMotionState to synchronize graphics transform, disabled old btRigidBody constructor that accepts btTransform + Renamed treshold into threshold throughout the code + +2006 Oct 30 + Enable decoupling of physics and graphics framerate using interpolation and internal fixed timestep, based on btMotionState + Enabled raycast vehicle demo (still needs tuning) + Refresh contact points, even when they are already persistent. + Fixed debugDraw colors (thanks pc0de for reporting) + Use Dispatcher in ConcaveConvexCollisionAlgorithm (so it uses the registered collision algorithm, not hardcoded convexconcave) + Improved performance of constraint solver by precalculating the cross product/impulse arm + Added collision comparison code: ODE box-box, also sphere-triangle + Added safety check into GJK, and an assert for AABB's that are very large + Fixed kinematic support (deriving velocities for animated objects) + Updated comparison/optional quickstep solver in Extras + UserCollisionAlgorithm demonstrates btTriangleMesh usage (easier trimesh compared to index array version) + Removed scaling from btTransform (we only want to deal with rigid transforms) + +2006 Oct 4 + Fixed minor leak in btOptimizeBVH + Cleanup of btRigidBody construction + added getW() in btQuaternion + assert when setLinearVelocity is called on btRigidBody + renamed projectfile library from collada-dom to colladadom (to make VC6 happy) + +2006 Sept 27 + Big Refactoring: renamed and moved files, create a replacement for CcdPhysicsEnvironment/CcdPhysicsController. + All Bullet classes in LinearMath, BulletCollision and BulletDynamics start with bt, and methods start with lowercase. + Moved classes into src folder, which is the only include folder needed. + Added 2 headerfiles in src: btBulletCollisionCommon.h and btBulletDynamicsCommon.h + +2006 Sept 23 + Fixed 2 bugs, causing crashes when removing objects. Should do better unit-testing. UnionFind and 3D SAP were involved. + +2006 Sept 19 + Allow programmable friction and contact solver model. User can register their own functions for several interaction types. + Improved performance, and removed hardcoded maximum overlaps (switched from C-array to stl::set) + +2006 Sept 16 + Added Bullet 2.0 User Manual + Allow registration of custom user collision algorithms + +2006 Sept 10 + Started cleaning up demos + +2006 Sept 4 + Fixed concave collision bug (caused instability/missing collisions in meshes/compounds) + Fixed memoryleak in OptimizedBvh, added RayTestSingle to CollisionWorld + Prepared for VehicleDemo + Increased Performance (island generation for sleeping objects took too much time) + Better COLLADA 1.4.1 physics conformance in ColladaDemo + +2006 August 11 + Added Quake BspDemo + Improved CCD for compound and non-convex objects + +2006 August 10 + Added per-triangle material (friction/restitution) support for non-convex meshes. See ConcaveDemo for usage. + +2006 August 9 + Added CMake support (see http://cmake.org) + This can autogenerate makefiles, projectfiles cross platform (including MacOS X Xcode ) + Just run cmake . in the root folder and it will autogenerate build files + +2006 July 26 Erwin Coumans + Upgraded to COLLADA-DOM 1.4.1, latest SVN version + ColladaDemo can export snapshots to .dae + +2006 July 24 Erwin Coumans + Added Compound CollisionShape support + (this is still low performance -> requires stackless tree-versus-tree traversal for better performance) + +2006 July 15 Erwin Coumans + Added initial support for Parallel execution (collision detection, constraint solving) + See ParallelPhysicsEnvironment in Extras\PhysicsInterface\CcdPhysics + +2006 July 10 Erwin Coumans + Added MacOS X support (some build issues mainly) + +2006 July 5 Erwin Coumans + Improved COLLADA 1.4 physics import, both COLLADA-DOM and FCollada + +2006 June 29 Erwin Coumans + Refactoring of the broadphase + Moved some optional files to Extras: Algebraic ccd and EPA, quickstep + Moved the limits on bodies/overlap to 32k and 65k + +2006 June 25 Erwin Coumans + Added basic Collision Filtering, during broadphase + Allow adding meshes to the TriangleIndexVertexArray, + (input for TriangleMeshShape) + Preparation for CompoundShape + +2006 June 19 Erwin Coumans + Added support for COLLADA Physics Import. + Both jam and Visual Studio can compile ColladaDemo + +2006 June 18 Dirk Gregorius + Started implementing Generic6DOF joint and setup basic interface + + +2006 June 17 Frank Richter + Bumped version in configure.ac to 1.5.6 (assuming that "1.5f" is + the next version released). + Updated files in mk/autoconf and mk/jam with copies from CS; fixes a + GLU detection issue on MinGW. + Set msvc/bullet_ico.ico as the default application icon. + Disabled exceptions for gcc builds. + Applied a patch from Michael D. Adams to fix a warning with gcc. +2006 jUNE 16 Erwin Coumans + Constraints now merge simulation islands. + +2006 May 24 + Improved GJK accuracy, fixed GjkConvexCast issue, thanks to ~MyXa~ for reporting + +2006 May 19 + Added restitution support + Moved out Friction and Dynamics info from ManifoldPoint (removed logical dependency) + Added a void* m_userPersistentData in ManifoldPoint. + Added a ContactDestroyedCallback, to allow user to handle destruction of m_userPersistentData + +2006 May 13 + Fixed some bugs in friction / jacobian calculations. Reported by Dirk Gregorius. Thanks! + +2006 May 9 + Fixed raycasting filtering + Moved repository to SVN at https://svn.sourceforge.net/svnroot/bullet + +2006 April 27 + Moved raycasting to CollisionWorld, to make it more generic + Added basic CCD option in the CcdCollisionDemo + Fixed 'noResponse' mode, for triggering rigidbodies (useful for Artificial Intelligence queries) + Improved Bullet/ODE sample (in Extras) + +2006 April 10 + Separating Axis Test (SAT) convex hull collision detector, contribution by Simon Hobbs + Added SIMD SSE Math classes (for above SAT) + Added Mouse picking in CcdPhysicsDemo + Improved penetration depth estimation in MinkowskiPenetrationDepthSolver, both accuracy and performance + Added Hinge constraint + Added quickprof profiling (see http://sourceforge.net/projects/quickprof ) + +2006 March 21 Frank Richter + Removed VC manifest files. + Removed superfluous "grpplugins" projects. + +2006 March 20 Erwin Coumans + Clamped the acculumated impulse rather then intermediate impulse (within the iteration) + Use the persistent contacts for reusing the impulse + Separated friction and normal solving for better stability + Decreased the default number of iterations of the constraint solver from 10 to 4 + +2006 March 19 Frank Richter + Removed a couple of CSisms from the VC projects. + Fixed VC include & lib paths to go to the Addtional* options + instead the command line arguments. + Added pkgconfig support. + +2006 March 14 Frank Richter + Added support for shipped GLUT on MinGW. + Fixed GLUT support on MinGW. + +2006 March 13 Frank Richter + Bolted on Jam-based build system. + Generated VC project files. + Fixed GCC warnings. + Fixed Linux build issues. + +2006 March 13 +Added 3D Sweep and Prune Broadphase Collision Detection, Contribution from Simon Hobbs. + +2006 March 2 + Minor change in license to ZLib/LibPNG + This makes it legally a bit easier to deploy on Playstation 3 + Prepared for more generic constraints, added ConstraintsDemo + +2006 Feb 23 + Rearranged files and dependencies to allow for easier standalone Collision Detection without Bullet Dynamics. + See Demos/CollisionInterfaceDemo and Extras/ode/ode/test/test_BulletGjk.cpp for examples how to use. + +2005 August 6 + Bullet 0.2 release with demos, sources, doxygen, draft manual + +2005 June 1 + First public release of Bullet + + +... todo: add history + +2003 Initial version (continuous collision detection) diff --git a/Demos/AllBulletDemos/CMakeLists.txt b/Demos/AllBulletDemos/CMakeLists.txt new file mode 100644 index 0000000..7e566db --- /dev/null +++ b/Demos/AllBulletDemos/CMakeLists.txt @@ -0,0 +1,104 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/Extras +${BULLET_PHYSICS_SOURCE_DIR}/Extras/GIMPACTUtils +${BULLET_PHYSICS_SOURCE_DIR}/Extras/HACD +${BULLET_PHYSICS_SOURCE_DIR}/Extras/ConvexDecomposition +${BULLET_PHYSICS_SOURCE_DIR}/Extras/LibXML +${BULLET_PHYSICS_SOURCE_DIR}/Extras/LibXML/include +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +${VECTOR_MATH_INCLUDE} +) + +LINK_LIBRARIES( +GLUI GIMPACTUtils HACD ConvexDecomposition OpenGLSupport BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +SET(AllBulletDemos_SRCS + Main.cpp + DemoEntries.cpp + ../CcdPhysicsDemo/CcdPhysicsDemo.cpp + ../BasicDemo/BasicDemo.cpp + ../BspDemo/BspDemo.cpp + ../BspDemo/BspConverter.cpp + ../BspDemo/BspLoader.cpp + ../DynamicControlDemo/MotorDemo.cpp + ../ConcaveDemo/ConcavePhysicsDemo.cpp + ../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp + ../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp + ../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp + ../SliderConstraintDemo/SliderConstraintDemo.cpp + ../RagdollDemo/RagdollDemo.cpp + ../GimpactTestDemo/GimpactTestDemo.cpp + ../Raytracer/Raytracer.cpp + ../GjkConvexCastDemo/LinearConvexCastDemo.cpp + ../ForkLiftDemo/ForkLiftDemo.cpp + ../SoftDemo/SoftDemo.cpp + ../ConstraintDemo/ConstraintDemo.cpp + ../Benchmarks/BenchmarkDemo.cpp + ../Box2dDemo/Box2dDemo.cpp + +) + +IF (WIN32) + ADD_EXECUTABLE(AppAllBulletDemos + ${AllBulletDemos_SRCS} + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppAllBulletDemos + ${AllBulletDemos_SRCS} + ) +ENDIF() + + +IF (WIN32) + IF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppAllBulletDemos + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppAllBulletDemos + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) +ENDIF(WIN32) + + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( + TARGET AppAllBulletDemos + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SerializeDemo/testFile.bullet ${CMAKE_CURRENT_BINARY_DIR}/testFile.bullet + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/file.obj ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppAllBulletDemos PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppAllBulletDemos PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppAllBulletDemos PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/AllBulletDemos/DemoEntries.cpp b/Demos/AllBulletDemos/DemoEntries.cpp new file mode 100644 index 0000000..eb35f02 --- /dev/null +++ b/Demos/AllBulletDemos/DemoEntries.cpp @@ -0,0 +1,178 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "DemoEntries.h" + +#include "../CcdPhysicsDemo/CcdPhysicsDemo.h" +#include "../BspDemo/BspDemo.h" +#include "../BasicDemo/BasicDemo.h" +#include "../ConcaveDemo/ConcaveDemo.h" +#include "../ConcaveRaycastDemo/ConcaveRaycastDemo.h" +#include "../ConcaveConvexcastDemo/ConcaveConvexcastDemo.h" +#include "../ConvexDecompositionDemo/ConvexDecompositionDemo.h" +#include "../DynamicControlDemo/MotorDemo.h" +#include "../SliderConstraintDemo/SliderConstraintDemo.h" +#include "../RagdollDemo/RagdollDemo.h" +#include "../GimpactTestDemo/GimpactTestDemo.h" +#include "../Raytracer/Raytracer.h" +#include "../GjkConvexCastDemo/LinearConvexCastDemo.h" +#include "../ForkLiftDemo/ForkLiftDemo.h" +#include "../ConstraintDemo/ConstraintDemo.h" +//#include "../Benchmarks/BenchmarkDemo.h" +#include "../SoftDemo/SoftDemo.h" +//#include "../Box2dDemo/Box2dDemo.h" + +#include "GLDebugFont.h" + +#include "GlutStuff.h"//OpenGL stuff + + +extern int gNumAlignedAllocs; +extern int gNumAlignedFree; +extern int gTotalBytesAlignedAllocs; + +class btEmptyDebugDemo : public GlutDemoApplication +{ +public: + btEmptyDebugDemo() + { + + } + + virtual void clientMoveAndDisplay() + { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float xOffset = 10.f; + float yStart = 20.f; + float yIncr = 20.f; + char buf[124]; + + + glColor3f(0, 0, 0); + + setOrthographicProjection(); + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gNumAlignedAllocs= %d",gNumAlignedAllocs); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gNumAlignedFree= %d",gNumAlignedFree); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"# alloc-free = %d",gNumAlignedAllocs-gNumAlignedFree); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gTotalBytesAlignedAllocs = %d",gTotalBytesAlignedAllocs); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; +#endif //BT_DEBUG_MEMORY_ALLOCATIONS + + glFlush(); + glutSwapBuffers(); + + } + + virtual void initPhysics() {} + + static DemoApplication* Create() + { + btEmptyDebugDemo* demo = new btEmptyDebugDemo(); + demo->myinit(); + return demo; + } + +}; + + +btDemoEntry g_demoEntries[] = +{ +// {"Box2dDemo",Box2dDemo::Create}, + {"ForkLift Demo",ForkLiftDemo::Create}, + {"Dynamic Control Demo",MotorDemo::Create}, + {"ConstraintDemo",ConstraintDemo::Create}, + + {"Ragdoll Demo",RagdollDemo::Create}, + {"Basic Demo", BasicDemo::Create}, + {"CcdPhysicsDemo", CcdPhysicsDemo::Create}, + {"Convex Decomposition",ConvexDecompositionDemo::Create}, + {"Concave Moving", GimpactConcaveDemo::Create}, + + {"ConcaveDemo",ConcaveDemo::Create}, + {"Concave Convexcast Demo",ConcaveConvexcastDemo::Create}, + {"SoftBody Cluster Collide1",SoftDemo19::Create}, + + {"SoftBody Ropes Attach",SoftDemo4::Create}, + + {"SoftBody Cloth Attach",SoftDemo5::Create}, + + {"SoftBody Cloth",SoftDemo0::Create}, + +// {"SoftBody Volume",SoftDemo2::Create}, + {"SoftBody Pressure",SoftDemo1::Create}, + {"SoftBody Cluster Car",SoftDemo24::Create}, + {"SoftBody Cluster Robot",SoftDemo25::Create}, + // {"SoftBody Ropes",SoftDemo3::Create}, + {"SoftBody Sticks",SoftDemo6::Create}, + {"SoftBody Collide",SoftDemo7::Create}, + {"SoftBody Collide2",SoftDemo8::Create}, +// {"SoftBody Collide3",SoftDemo9::Create}, +// {"SoftBody Impact",SoftDemo10::Create}, + {"SoftBody Aero",SoftDemo11::Create}, + {"SoftBody Friction",SoftDemo12::Create}, +// {"SoftBody Torus",SoftDemo13::Create}, +// {"SoftBody Torus Match",SoftDemo14::Create}, +// {"SoftBody Bunny",SoftDemo15::Create}, +// {"SoftBody Bunny Match",SoftDemo16::Create}, + {"SoftBody Init Cutting",SoftDemo17::Create}, +// {"SoftBody Cluster Deform",SoftDemo18::Create}, + +// {"SoftBody Cluster Collide2",SoftDemo20::Create}, +// {"SoftBody Cluster Socket",SoftDemo21::Create}, + {"SoftBody Cluster Hinge",SoftDemo22::Create}, + {"SoftBody Cluster Combine",SoftDemo23::Create}, +// {"SoftBody Cluster Stack Soft",SoftDemo26::Create}, + {"SoftBody Cluster Stack Mixed",SoftDemo27::Create}, + + {"SoftBody TetGen Tetrahedral Cube",SoftDemo28::Create}, + {"SoftBody TetGen Tetrahedral Bunny",SoftDemo29::Create}, + + +// {"SliderConstraint",SliderConstraintDemo::Create}, + +// {"ConcaveRaycastDemo",ConcaveRaycastDemo::Create}, + //{"BspDemo", BspDemo::Create}, +// {"Raytracer Test",Raytracer::Create}, +// {"GjkConvexCast",LinearConvexCastDemo::Create}, +// {"Benchmark 3000 FALL",BenchmarkDemo1::Create}, +// {"Benchmark 1000 STACK",BenchmarkDemo2::Create}, +// {"Benchmark 136 RAGDOLLS",BenchmarkDemo3::Create}, +// {"Benchmark 1000 CONVEX",BenchmarkDemo4::Create}, +// {"Benchmark Mesh-Prim",BenchmarkDemo5::Create}, +// {"Benchmark Mesh-Convex",BenchmarkDemo6::Create}, +// {"Benchmark Raycast",BenchmarkDemo7::Create}, + + {"MemoryLeak Checker",btEmptyDebugDemo::Create}, + {0, 0} +}; + + diff --git a/Demos/AllBulletDemos/DemoEntries.h b/Demos/AllBulletDemos/DemoEntries.h new file mode 100644 index 0000000..41fd857 --- /dev/null +++ b/Demos/AllBulletDemos/DemoEntries.h @@ -0,0 +1,34 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_DEMO_ENTRIES_H +#define BT_DEMO_ENTRIES_H + + +class DemoApplication; + +typedef DemoApplication* DemoCreateFcn(); + +struct btDemoEntry +{ + const char *name; + DemoCreateFcn *createFcn; +}; + +extern btDemoEntry g_demoEntries[]; + + + +#endif //BT_DEMO_ENTRIES_H diff --git a/Demos/AllBulletDemos/Main.cpp b/Demos/AllBulletDemos/Main.cpp new file mode 100644 index 0000000..c59e18d --- /dev/null +++ b/Demos/AllBulletDemos/Main.cpp @@ -0,0 +1,574 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include + +#include "glui/GL/glui.h" +#include "LinearMath/btScalar.h" +#include "LinearMath/btMinMax.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "DemoApplication.h" +#include "DemoEntries.h" +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "BulletSoftBody/btSoftRigidDynamicsWorld.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" + +#include "GLDebugDrawer.h" +static GLDebugDrawer dDebugDraw2; + +#include "LinearMath/btQuickprof.h" + + + +namespace +{ + int testIndex=1; + int testSelection=0; + btDemoEntry* entry; + DemoApplication* demo; + int iterationCount; + int width; + int height; + int framePeriod;//todo: test if this value should be 0 + int mainWindow; + GLUI *glui; + //float hz; + float viewZoom=20.f; + float viewX; + float viewY; + int tx, ty, tw, th; + int gDrawAabb; + int gWireFrame; + int gDrawNormals; + int gHelpText; + int gDebugConstraints; + int gDebugContacts; + int gDrawTextures=1; + int gDrawShadows=0; + int gDrawClusters=0; + int gDebugNoDeactivation; + int gUseWarmstarting; + int gRandomizeConstraints; + int gUseSplitImpulse; + float gErp; + float gSlop; + float gErp2; + float gWarmStartingParameter; +} + + + +void setDefaultSettings() +{ + viewX = 0.0f; + viewY = 0.0f; + framePeriod = 6;//16;//16;//todo: test if this value should be 0 + + width = 1280; + height = 768;//480; + iterationCount = 10; + gDrawAabb=0; + gDrawNormals=0; + gWireFrame=0; + gDebugContacts=0; + //enable constraint debug visualization for first demo, only if user hasn't overridden the setting + if (testSelection>1) + { + gDebugConstraints=0; + } else + { + gDebugConstraints=1; + } + gHelpText = 0; + gDrawTextures=1; + gDrawShadows=0; + gDrawClusters=0; + + gDebugNoDeactivation = 0; + gUseSplitImpulse = 1; + gUseWarmstarting = 1; + gRandomizeConstraints = 0; + gErp = 0.2f; + gSlop=0.0f; + gErp2 = 0.81f; + gWarmStartingParameter = 0.85f; + +} + +void setDefaultSettingsAndSync() +{ + setDefaultSettings(); + glui->sync_live(); +} + + +void TogglePause() +{ + if (demo) + demo->toggleIdle(); +} + +void ResetScene() +{ + if (demo) + demo->clientResetScene(); +} + +void NextScene() +{ + testSelection++; + if (testSelection>1) + { + gDebugConstraints=0; + } else + { + gDebugConstraints=1; + } + + if(testSelection>28) + testSelection=0; + if (glui) + glui->sync_live(); +} + + +void SingleSimulationStep() +{ + if (demo) + demo->clientMoveAndDisplay(); +} + + +void Resize(int w, int h) +{ + width = w; + height = h; + + GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th ); + glViewport( tx, ty, tw, th ); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if (demo) + demo->reshape(tw, th); +} + +DemoApplication* CreatDemo(btDemoEntry* entry) +{ + DemoApplication* demo = entry->createFcn(); + btAssert(demo); + if (demo->getDynamicsWorld()) + { + demo->getDynamicsWorld()->setDebugDrawer(&dDebugDraw2); + gDrawTextures = demo->getTexturing(); + gDrawShadows = demo->getShadows(); + if (glui) + glui->sync_live(); + } + +#ifndef BT_NO_PROFILE + CProfileManager::Reset(); +#endif //BT_NO_PROFILE + + return demo; + +} + +/*b2Vec2 ConvertScreenToWorld(int x, int y) +{ + b2Vec2 p; + + float ratio = float(tw) / float(th); + float u = x / float(tw); + float v = (th - y) / float(th); + p.x = viewZoom * (viewX - ratio) * (1.0f - u) + viewZoom * (ratio + viewX) * u; + p.y = viewZoom * (viewY - 0.1f) * (1.0f - v) + viewZoom * (viewY + 1.9f) * v; + return p; +} +*/ + +// This is used to control the frame rate (60Hz). +void Timer(int) +{ + glutSetWindow(mainWindow); + glutPostRedisplay(); + glutTimerFunc(framePeriod, Timer, 0); +} + +void SimulationLoop() +{ + Resize(width, height); + + + + if (gDrawAabb) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawAabb); + } else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawAabb)); + } + if (gWireFrame) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawWireframe); + } else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawWireframe)); + } + if (gDrawNormals) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawNormals); + } else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawNormals)); + } + if (gHelpText) + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_NoHelpText)); + } else + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_NoHelpText); + } + if (gDebugConstraints) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits); + } else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits)); + } + if (gDebugContacts) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawContactPoints); + } else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawContactPoints)); + } + + demo->setTexturing(0!=gDrawTextures); + demo->setShadows(0!=gDrawShadows); + demo->setDrawClusters(0!=gDrawClusters); + + if (gDebugNoDeactivation) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_NoDeactivation); + } else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_NoDeactivation)); + } + + + + + if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getWorldType() == BT_DISCRETE_DYNAMICS_WORLD) + { + btDiscreteDynamicsWorld* discreteWorld = (btDiscreteDynamicsWorld*) demo->getDynamicsWorld(); + discreteWorld->getSolverInfo().m_numIterations = iterationCount; + discreteWorld->getSolverInfo().m_erp = gErp; + discreteWorld->getSolverInfo().m_erp2 = gErp2; + + discreteWorld->getSolverInfo().m_linearSlop = gSlop; + + discreteWorld->getSolverInfo().m_warmstartingFactor = gWarmStartingParameter; + discreteWorld->getSolverInfo().m_splitImpulse = gUseSplitImpulse; + + // btSequentialImpulseConstraintSolver* solver = ((btSequentialImpulseConstraintSolver*) discreteWorld->getConstraintSolver()); + + if (gUseWarmstarting) + { + discreteWorld->getSolverInfo().m_solverMode |= SOLVER_USE_WARMSTARTING; + } else + { + discreteWorld->getSolverInfo().m_solverMode &= (~SOLVER_USE_WARMSTARTING); + } + if (gRandomizeConstraints) + { + discreteWorld->getSolverInfo().m_solverMode |= SOLVER_RANDMIZE_ORDER; + } else + { + discreteWorld->getSolverInfo().m_solverMode &= (~SOLVER_RANDMIZE_ORDER); + } + } + + if (!demo->isIdle()) + { + demo->clientMoveAndDisplay(); + + + } + else + { + demo->displayCallback(); + } + + if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD) + { + btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)demo->getDynamicsWorld(); + for ( int i=0;igetSoftBodyArray().size();i++) + { + btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i]; + if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) + { + btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags()); + } + } + } + + if (testSelection != testIndex) + { + if (testSelection>1) + { + gDebugConstraints=0; + } else + { + gDebugConstraints=1; + } + + testIndex = testSelection; + delete demo; + entry = g_demoEntries + testIndex; + demo = CreatDemo(entry); + viewZoom = 20.0f; + viewX = 0.0f; + viewY = 0.0f; + Resize(width, height); + } +} + +void RestartScene() +{ + delete demo; + entry = g_demoEntries + testIndex; + demo = CreatDemo(entry); + viewZoom = 20.0f; + viewX = 0.0f; + viewY = 0.0f; + Resize(width, height); +} + +void Keyboard(unsigned char key, int x, int y) +{ + + + + + switch (key) + { + case 27: + exit(0); + break; + + // Press 'r' to reset. + case 'r': + delete demo; + demo = CreatDemo(entry); + Resize(width,height); + break; + + default: + if (demo) + { + demo->keyboardCallback(key,x,y); + } + } +} + +void KeyboardSpecialUp(int key, int x, int y) +{ + if (demo) + { + demo->specialKeyboardUp(key,x,y); + } + +} + + +void GlutIdleFunc() +{ + int current_window, new_window=-1; + current_window = glutGetWindow(); + if (GLUI_Master.gluis.first_child() != NULL ) + { + new_window = ((GLUI_Main*)GLUI_Master.gluis.first_child())->getMainWindowId(); + } + if ( (new_window > 0) && (new_window != current_window )) + { + //--- Window is changed only if its not already the current window --- + glutSetWindow( new_window ); + } + + if (demo) + demo->moveAndDisplay(); + + glutSetWindow( current_window ); +} + +void KeyboardSpecial(int key, int x, int y) +{ + + if (demo) + { + demo->specialKeyboard(key,x,y); + } + +} + + +void Mouse(int button, int state, int x, int y) +{ + if (demo) + demo->mouseFunc(button,state,x,y); +} + +void MouseMotion(int x, int y) +{ + demo->mouseMotionFunc(x,y); +} + +#ifdef BT_USE_FREEGLUT +#include "GL/freeglut_ext.h" +#endif + +int main(int argc, char** argv) +{ + +//#define CHECK_FPU_EXCEPTIONS 1 +#ifdef CHECK_FPU_EXCEPTIONS + + int cw = _control87(0, 0); + + // Set the exception masks off, turn exceptions on + cw &= ~(EM_ZERODIVIDE | EM_INVALID); + + printf("control87 = %#x\n", cw); + + // Set the control word + _control87(cw, MCW_EM); +#endif //CHECK_FPU_EXCEPTIONS + + + setDefaultSettings(); + + int bulletVersion = btGetVersion(); + printf("Bullet version %d\n",bulletVersion); + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH | GLUT_STENCIL); + glutInitWindowSize(width, height); + mainWindow = glutCreateWindow("http://bulletphysics.com"); +#ifdef BT_USE_FREEGLUT + glutSetOption (GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); +#endif + entry = g_demoEntries + testIndex; + demo = CreatDemo(entry); + + glutDisplayFunc(SimulationLoop); + GLUI_Master.set_glutReshapeFunc(Resize); + GLUI_Master.set_glutKeyboardFunc(Keyboard); + GLUI_Master.set_glutSpecialFunc(KeyboardSpecial); + GLUI_Master.set_glutIdleFunc(GlutIdleFunc); + GLUI_Master.set_glutSpecialUpFunc(KeyboardSpecialUp); + GLUI_Master.set_glutMouseFunc(Mouse); + glutMotionFunc(MouseMotion); + + + glui = GLUI_Master.create_glui_subwindow( mainWindow, + GLUI_SUBWINDOW_RIGHT ); + + + + glui->add_statictext("Tests"); + GLUI_Listbox* testList = + glui->add_listbox("", &testSelection); + glui->add_button("Next Scene", 0,(GLUI_Update_CB)NextScene); + + glui->add_separator(); + + GLUI_Spinner* iterationSpinner = + glui->add_spinner("Iterations", GLUI_SPINNER_INT, &iterationCount); + iterationSpinner->set_int_limits(1, 250); + +/* GLUI_Spinner* hertzSpinner = + glui->add_spinner("Hertz", GLUI_SPINNER_FLOAT, &hz); + hertzSpinner->set_float_limits(5.0f, 200.0f); +*/ + + + glui->add_checkbox("DisableDeactivation", &gDebugNoDeactivation); + glui->add_checkbox("Split Impulse", &gUseSplitImpulse); + GLUI_Spinner* spinner = 0; + + spinner = glui->add_spinner("ERP", GLUI_SPINNER_FLOAT, &gErp); +// spinner->set_float_limits(0.f,1.f); +// spinner = glui->add_spinner("ERP2", GLUI_SPINNER_FLOAT, &gErp2); + spinner->set_float_limits(0.f,1.f); + spinner = glui->add_spinner("Slop", GLUI_SPINNER_FLOAT, &gSlop); + spinner->set_float_limits(0.f,1.f); +// spinner = glui->add_spinner("WSP", GLUI_SPINNER_FLOAT,&gWarmStartingParameter); +// spinner->set_float_limits (0.f,1.0); + glui->add_checkbox("Warmstarting", &gUseWarmstarting); + glui->add_checkbox("Randomize Constraints", &gRandomizeConstraints); + + + glui->add_button("Reset Defaults", 0,(GLUI_Update_CB)setDefaultSettingsAndSync); + glui->add_separator(); + + GLUI_Panel* drawPanel = glui->add_panel("Debug Draw"); + + + glui->add_checkbox_to_panel(drawPanel, "Help", &gHelpText); + glui->add_checkbox_to_panel(drawPanel, "AABBs", &gDrawAabb); + glui->add_checkbox_to_panel(drawPanel, "Wireframe", &gWireFrame); + glui->add_checkbox_to_panel(drawPanel, "Normals", &gDrawNormals); + glui->add_checkbox_to_panel(drawPanel, "Contacts", &gDebugContacts); + glui->add_checkbox_to_panel(drawPanel, "Constraints", &gDebugConstraints); + + glui->add_checkbox_to_panel(drawPanel, "Textures", &gDrawTextures); + glui->add_checkbox_to_panel(drawPanel, "Shadows", &gDrawShadows); + glui->add_checkbox_to_panel(drawPanel, "Clusters", &gDrawClusters); + + int testCount = 0; + btDemoEntry* e = g_demoEntries; + while (e->createFcn) + { + testList->add_item(testCount, e->name); + ++testCount; + ++e; + } + + glui->add_separator(); + + glui->add_button("Toggle Pause", 0,(GLUI_Update_CB)TogglePause); + + glui->add_button("Single Step", 0,(GLUI_Update_CB)SingleSimulationStep); + glui->add_button("Reset Scene", 0,(GLUI_Update_CB)ResetScene); + glui->add_button("Restart Scene", 0,(GLUI_Update_CB)RestartScene); + + glui->add_separator(); + +// glui->add_button("Exit", 0,(GLUI_Update_CB)exit); + + glui->set_main_gfx_window( mainWindow ); + + // Use a timer to control the frame rate. + glutTimerFunc(framePeriod, Timer, 0); + + glutMainLoop(); + + return 0; +} diff --git a/Demos/AllBulletDemos/Makefile.am b/Demos/AllBulletDemos/Makefile.am new file mode 100644 index 0000000..aab8b98 --- /dev/null +++ b/Demos/AllBulletDemos/Makefile.am @@ -0,0 +1,34 @@ +noinst_PROGRAMS=AllBulletDemo + +AllBulletDemo_SOURCES=\ + ../SoftDemo/SoftDemo.cpp \ + ../ConstraintDemo/ConstraintDemo.cpp \ + ../ForkLiftDemo/ForkLiftDemo.cpp \ + ../RagdollDemo/RagdollDemo.cpp \ + ../BasicDemo/BasicDemo.cpp \ + ../CcdPhysicsDemo/CcdPhysicsDemo.cpp \ + ../SliderConstraintDemo/SliderConstraintDemo.cpp \ + ../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp \ + ../Raytracer/Raytracer.cpp \ + ../BspDemo/BspDemo.cpp \ + ../BspDemo/BspLoader.cpp \ + ../BspDemo/BspConverter.cpp \ + ../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp \ + ../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp \ + ../GimpactTestDemo/GimpactTestDemo.cpp \ + ../GjkConvexCastDemo/LinearConvexCastDemo.cpp \ + ../ConcaveDemo/ConcavePhysicsDemo.cpp \ + ../DynamicControlDemo/MotorDemo.cpp \ + DemoEntries.cpp \ + DemoEntries.h\ + Main.cpp +AllBulletDemo_CXXFLAGS=\ + -I@top_builddir@/src \ + -I@top_builddir@/Extras/GIMPACTUtils \ + -I@top_builddir@/Extras/ConvexDecomposition \ + -I@top_builddir@/Extras/HACD \ + -I@top_builddir@/Extras \ + -I@top_builddir@/Demos/OpenGL \ + -I@top_builddir@/Demos/SoftDemo \ + $(CXXFLAGS) +AllBulletDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -L../../Extras -lgimpactutils -lconvexdecomposition -lHACD -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath -lglui @opengl_LIBS@ diff --git a/Demos/AllBulletDemos/Makefile.in b/Demos/AllBulletDemos/Makefile.in new file mode 100644 index 0000000..08cb093 --- /dev/null +++ b/Demos/AllBulletDemos/Makefile.in @@ -0,0 +1,837 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = AllBulletDemo$(EXEEXT) +subdir = Demos/AllBulletDemos +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_AllBulletDemo_OBJECTS = AllBulletDemo-SoftDemo.$(OBJEXT) \ + AllBulletDemo-ConstraintDemo.$(OBJEXT) \ + AllBulletDemo-ForkLiftDemo.$(OBJEXT) \ + AllBulletDemo-RagdollDemo.$(OBJEXT) \ + AllBulletDemo-BasicDemo.$(OBJEXT) \ + AllBulletDemo-CcdPhysicsDemo.$(OBJEXT) \ + AllBulletDemo-SliderConstraintDemo.$(OBJEXT) \ + AllBulletDemo-ConcaveRaycastDemo.$(OBJEXT) \ + AllBulletDemo-Raytracer.$(OBJEXT) \ + AllBulletDemo-BspDemo.$(OBJEXT) \ + AllBulletDemo-BspLoader.$(OBJEXT) \ + AllBulletDemo-BspConverter.$(OBJEXT) \ + AllBulletDemo-ConcaveConvexcastDemo.$(OBJEXT) \ + AllBulletDemo-ConvexDecompositionDemo.$(OBJEXT) \ + AllBulletDemo-GimpactTestDemo.$(OBJEXT) \ + AllBulletDemo-LinearConvexCastDemo.$(OBJEXT) \ + AllBulletDemo-ConcavePhysicsDemo.$(OBJEXT) \ + AllBulletDemo-MotorDemo.$(OBJEXT) \ + AllBulletDemo-DemoEntries.$(OBJEXT) \ + AllBulletDemo-Main.$(OBJEXT) +AllBulletDemo_OBJECTS = $(am_AllBulletDemo_OBJECTS) +AllBulletDemo_DEPENDENCIES = +AllBulletDemo_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AllBulletDemo_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(AllBulletDemo_SOURCES) +DIST_SOURCES = $(AllBulletDemo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AllBulletDemo_SOURCES = \ + ../SoftDemo/SoftDemo.cpp \ + ../ConstraintDemo/ConstraintDemo.cpp \ + ../ForkLiftDemo/ForkLiftDemo.cpp \ + ../RagdollDemo/RagdollDemo.cpp \ + ../BasicDemo/BasicDemo.cpp \ + ../CcdPhysicsDemo/CcdPhysicsDemo.cpp \ + ../SliderConstraintDemo/SliderConstraintDemo.cpp \ + ../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp \ + ../Raytracer/Raytracer.cpp \ + ../BspDemo/BspDemo.cpp \ + ../BspDemo/BspLoader.cpp \ + ../BspDemo/BspConverter.cpp \ + ../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp \ + ../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp \ + ../GimpactTestDemo/GimpactTestDemo.cpp \ + ../GjkConvexCastDemo/LinearConvexCastDemo.cpp \ + ../ConcaveDemo/ConcavePhysicsDemo.cpp \ + ../DynamicControlDemo/MotorDemo.cpp \ + DemoEntries.cpp \ + DemoEntries.h\ + Main.cpp + +AllBulletDemo_CXXFLAGS = \ + -I@top_builddir@/src \ + -I@top_builddir@/Extras/GIMPACTUtils \ + -I@top_builddir@/Extras/ConvexDecomposition \ + -I@top_builddir@/Extras/HACD \ + -I@top_builddir@/Extras \ + -I@top_builddir@/Demos/OpenGL \ + -I@top_builddir@/Demos/SoftDemo \ + $(CXXFLAGS) + +AllBulletDemo_LDADD = -L../OpenGL -lbulletopenglsupport -L../../src -L../../Extras -lgimpactutils -lconvexdecomposition -lHACD -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath -lglui @opengl_LIBS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/AllBulletDemos/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/AllBulletDemos/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +AllBulletDemo$(EXEEXT): $(AllBulletDemo_OBJECTS) $(AllBulletDemo_DEPENDENCIES) + @rm -f AllBulletDemo$(EXEEXT) + $(AllBulletDemo_LINK) $(AllBulletDemo_OBJECTS) $(AllBulletDemo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-BasicDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-BspConverter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-BspDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-BspLoader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-CcdPhysicsDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-ConcaveConvexcastDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-ConcavePhysicsDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-ConcaveRaycastDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-ConstraintDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-ConvexDecompositionDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-DemoEntries.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-ForkLiftDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-GimpactTestDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-LinearConvexCastDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-Main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-MotorDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-RagdollDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-Raytracer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-SliderConstraintDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllBulletDemo-SoftDemo.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +AllBulletDemo-SoftDemo.o: ../SoftDemo/SoftDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-SoftDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-SoftDemo.Tpo -c -o AllBulletDemo-SoftDemo.o `test -f '../SoftDemo/SoftDemo.cpp' || echo '$(srcdir)/'`../SoftDemo/SoftDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-SoftDemo.Tpo $(DEPDIR)/AllBulletDemo-SoftDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../SoftDemo/SoftDemo.cpp' object='AllBulletDemo-SoftDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-SoftDemo.o `test -f '../SoftDemo/SoftDemo.cpp' || echo '$(srcdir)/'`../SoftDemo/SoftDemo.cpp + +AllBulletDemo-SoftDemo.obj: ../SoftDemo/SoftDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-SoftDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-SoftDemo.Tpo -c -o AllBulletDemo-SoftDemo.obj `if test -f '../SoftDemo/SoftDemo.cpp'; then $(CYGPATH_W) '../SoftDemo/SoftDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../SoftDemo/SoftDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-SoftDemo.Tpo $(DEPDIR)/AllBulletDemo-SoftDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../SoftDemo/SoftDemo.cpp' object='AllBulletDemo-SoftDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-SoftDemo.obj `if test -f '../SoftDemo/SoftDemo.cpp'; then $(CYGPATH_W) '../SoftDemo/SoftDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../SoftDemo/SoftDemo.cpp'; fi` + +AllBulletDemo-ConstraintDemo.o: ../ConstraintDemo/ConstraintDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConstraintDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConstraintDemo.Tpo -c -o AllBulletDemo-ConstraintDemo.o `test -f '../ConstraintDemo/ConstraintDemo.cpp' || echo '$(srcdir)/'`../ConstraintDemo/ConstraintDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConstraintDemo.Tpo $(DEPDIR)/AllBulletDemo-ConstraintDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConstraintDemo/ConstraintDemo.cpp' object='AllBulletDemo-ConstraintDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConstraintDemo.o `test -f '../ConstraintDemo/ConstraintDemo.cpp' || echo '$(srcdir)/'`../ConstraintDemo/ConstraintDemo.cpp + +AllBulletDemo-ConstraintDemo.obj: ../ConstraintDemo/ConstraintDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConstraintDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConstraintDemo.Tpo -c -o AllBulletDemo-ConstraintDemo.obj `if test -f '../ConstraintDemo/ConstraintDemo.cpp'; then $(CYGPATH_W) '../ConstraintDemo/ConstraintDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConstraintDemo/ConstraintDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConstraintDemo.Tpo $(DEPDIR)/AllBulletDemo-ConstraintDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConstraintDemo/ConstraintDemo.cpp' object='AllBulletDemo-ConstraintDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConstraintDemo.obj `if test -f '../ConstraintDemo/ConstraintDemo.cpp'; then $(CYGPATH_W) '../ConstraintDemo/ConstraintDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConstraintDemo/ConstraintDemo.cpp'; fi` + +AllBulletDemo-ForkLiftDemo.o: ../ForkLiftDemo/ForkLiftDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ForkLiftDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-ForkLiftDemo.Tpo -c -o AllBulletDemo-ForkLiftDemo.o `test -f '../ForkLiftDemo/ForkLiftDemo.cpp' || echo '$(srcdir)/'`../ForkLiftDemo/ForkLiftDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ForkLiftDemo.Tpo $(DEPDIR)/AllBulletDemo-ForkLiftDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ForkLiftDemo/ForkLiftDemo.cpp' object='AllBulletDemo-ForkLiftDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ForkLiftDemo.o `test -f '../ForkLiftDemo/ForkLiftDemo.cpp' || echo '$(srcdir)/'`../ForkLiftDemo/ForkLiftDemo.cpp + +AllBulletDemo-ForkLiftDemo.obj: ../ForkLiftDemo/ForkLiftDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ForkLiftDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-ForkLiftDemo.Tpo -c -o AllBulletDemo-ForkLiftDemo.obj `if test -f '../ForkLiftDemo/ForkLiftDemo.cpp'; then $(CYGPATH_W) '../ForkLiftDemo/ForkLiftDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ForkLiftDemo/ForkLiftDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ForkLiftDemo.Tpo $(DEPDIR)/AllBulletDemo-ForkLiftDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ForkLiftDemo/ForkLiftDemo.cpp' object='AllBulletDemo-ForkLiftDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ForkLiftDemo.obj `if test -f '../ForkLiftDemo/ForkLiftDemo.cpp'; then $(CYGPATH_W) '../ForkLiftDemo/ForkLiftDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ForkLiftDemo/ForkLiftDemo.cpp'; fi` + +AllBulletDemo-RagdollDemo.o: ../RagdollDemo/RagdollDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-RagdollDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-RagdollDemo.Tpo -c -o AllBulletDemo-RagdollDemo.o `test -f '../RagdollDemo/RagdollDemo.cpp' || echo '$(srcdir)/'`../RagdollDemo/RagdollDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-RagdollDemo.Tpo $(DEPDIR)/AllBulletDemo-RagdollDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../RagdollDemo/RagdollDemo.cpp' object='AllBulletDemo-RagdollDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-RagdollDemo.o `test -f '../RagdollDemo/RagdollDemo.cpp' || echo '$(srcdir)/'`../RagdollDemo/RagdollDemo.cpp + +AllBulletDemo-RagdollDemo.obj: ../RagdollDemo/RagdollDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-RagdollDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-RagdollDemo.Tpo -c -o AllBulletDemo-RagdollDemo.obj `if test -f '../RagdollDemo/RagdollDemo.cpp'; then $(CYGPATH_W) '../RagdollDemo/RagdollDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../RagdollDemo/RagdollDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-RagdollDemo.Tpo $(DEPDIR)/AllBulletDemo-RagdollDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../RagdollDemo/RagdollDemo.cpp' object='AllBulletDemo-RagdollDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-RagdollDemo.obj `if test -f '../RagdollDemo/RagdollDemo.cpp'; then $(CYGPATH_W) '../RagdollDemo/RagdollDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../RagdollDemo/RagdollDemo.cpp'; fi` + +AllBulletDemo-BasicDemo.o: ../BasicDemo/BasicDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BasicDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-BasicDemo.Tpo -c -o AllBulletDemo-BasicDemo.o `test -f '../BasicDemo/BasicDemo.cpp' || echo '$(srcdir)/'`../BasicDemo/BasicDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BasicDemo.Tpo $(DEPDIR)/AllBulletDemo-BasicDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BasicDemo/BasicDemo.cpp' object='AllBulletDemo-BasicDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BasicDemo.o `test -f '../BasicDemo/BasicDemo.cpp' || echo '$(srcdir)/'`../BasicDemo/BasicDemo.cpp + +AllBulletDemo-BasicDemo.obj: ../BasicDemo/BasicDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BasicDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-BasicDemo.Tpo -c -o AllBulletDemo-BasicDemo.obj `if test -f '../BasicDemo/BasicDemo.cpp'; then $(CYGPATH_W) '../BasicDemo/BasicDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../BasicDemo/BasicDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BasicDemo.Tpo $(DEPDIR)/AllBulletDemo-BasicDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BasicDemo/BasicDemo.cpp' object='AllBulletDemo-BasicDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BasicDemo.obj `if test -f '../BasicDemo/BasicDemo.cpp'; then $(CYGPATH_W) '../BasicDemo/BasicDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../BasicDemo/BasicDemo.cpp'; fi` + +AllBulletDemo-CcdPhysicsDemo.o: ../CcdPhysicsDemo/CcdPhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-CcdPhysicsDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-CcdPhysicsDemo.Tpo -c -o AllBulletDemo-CcdPhysicsDemo.o `test -f '../CcdPhysicsDemo/CcdPhysicsDemo.cpp' || echo '$(srcdir)/'`../CcdPhysicsDemo/CcdPhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-CcdPhysicsDemo.Tpo $(DEPDIR)/AllBulletDemo-CcdPhysicsDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../CcdPhysicsDemo/CcdPhysicsDemo.cpp' object='AllBulletDemo-CcdPhysicsDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-CcdPhysicsDemo.o `test -f '../CcdPhysicsDemo/CcdPhysicsDemo.cpp' || echo '$(srcdir)/'`../CcdPhysicsDemo/CcdPhysicsDemo.cpp + +AllBulletDemo-CcdPhysicsDemo.obj: ../CcdPhysicsDemo/CcdPhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-CcdPhysicsDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-CcdPhysicsDemo.Tpo -c -o AllBulletDemo-CcdPhysicsDemo.obj `if test -f '../CcdPhysicsDemo/CcdPhysicsDemo.cpp'; then $(CYGPATH_W) '../CcdPhysicsDemo/CcdPhysicsDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../CcdPhysicsDemo/CcdPhysicsDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-CcdPhysicsDemo.Tpo $(DEPDIR)/AllBulletDemo-CcdPhysicsDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../CcdPhysicsDemo/CcdPhysicsDemo.cpp' object='AllBulletDemo-CcdPhysicsDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-CcdPhysicsDemo.obj `if test -f '../CcdPhysicsDemo/CcdPhysicsDemo.cpp'; then $(CYGPATH_W) '../CcdPhysicsDemo/CcdPhysicsDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../CcdPhysicsDemo/CcdPhysicsDemo.cpp'; fi` + +AllBulletDemo-SliderConstraintDemo.o: ../SliderConstraintDemo/SliderConstraintDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-SliderConstraintDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-SliderConstraintDemo.Tpo -c -o AllBulletDemo-SliderConstraintDemo.o `test -f '../SliderConstraintDemo/SliderConstraintDemo.cpp' || echo '$(srcdir)/'`../SliderConstraintDemo/SliderConstraintDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-SliderConstraintDemo.Tpo $(DEPDIR)/AllBulletDemo-SliderConstraintDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../SliderConstraintDemo/SliderConstraintDemo.cpp' object='AllBulletDemo-SliderConstraintDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-SliderConstraintDemo.o `test -f '../SliderConstraintDemo/SliderConstraintDemo.cpp' || echo '$(srcdir)/'`../SliderConstraintDemo/SliderConstraintDemo.cpp + +AllBulletDemo-SliderConstraintDemo.obj: ../SliderConstraintDemo/SliderConstraintDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-SliderConstraintDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-SliderConstraintDemo.Tpo -c -o AllBulletDemo-SliderConstraintDemo.obj `if test -f '../SliderConstraintDemo/SliderConstraintDemo.cpp'; then $(CYGPATH_W) '../SliderConstraintDemo/SliderConstraintDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../SliderConstraintDemo/SliderConstraintDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-SliderConstraintDemo.Tpo $(DEPDIR)/AllBulletDemo-SliderConstraintDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../SliderConstraintDemo/SliderConstraintDemo.cpp' object='AllBulletDemo-SliderConstraintDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-SliderConstraintDemo.obj `if test -f '../SliderConstraintDemo/SliderConstraintDemo.cpp'; then $(CYGPATH_W) '../SliderConstraintDemo/SliderConstraintDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../SliderConstraintDemo/SliderConstraintDemo.cpp'; fi` + +AllBulletDemo-ConcaveRaycastDemo.o: ../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConcaveRaycastDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConcaveRaycastDemo.Tpo -c -o AllBulletDemo-ConcaveRaycastDemo.o `test -f '../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp' || echo '$(srcdir)/'`../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConcaveRaycastDemo.Tpo $(DEPDIR)/AllBulletDemo-ConcaveRaycastDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp' object='AllBulletDemo-ConcaveRaycastDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConcaveRaycastDemo.o `test -f '../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp' || echo '$(srcdir)/'`../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp + +AllBulletDemo-ConcaveRaycastDemo.obj: ../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConcaveRaycastDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConcaveRaycastDemo.Tpo -c -o AllBulletDemo-ConcaveRaycastDemo.obj `if test -f '../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp'; then $(CYGPATH_W) '../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConcaveRaycastDemo.Tpo $(DEPDIR)/AllBulletDemo-ConcaveRaycastDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp' object='AllBulletDemo-ConcaveRaycastDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConcaveRaycastDemo.obj `if test -f '../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp'; then $(CYGPATH_W) '../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConcaveRaycastDemo/ConcaveRaycastDemo.cpp'; fi` + +AllBulletDemo-Raytracer.o: ../Raytracer/Raytracer.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-Raytracer.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-Raytracer.Tpo -c -o AllBulletDemo-Raytracer.o `test -f '../Raytracer/Raytracer.cpp' || echo '$(srcdir)/'`../Raytracer/Raytracer.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-Raytracer.Tpo $(DEPDIR)/AllBulletDemo-Raytracer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../Raytracer/Raytracer.cpp' object='AllBulletDemo-Raytracer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-Raytracer.o `test -f '../Raytracer/Raytracer.cpp' || echo '$(srcdir)/'`../Raytracer/Raytracer.cpp + +AllBulletDemo-Raytracer.obj: ../Raytracer/Raytracer.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-Raytracer.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-Raytracer.Tpo -c -o AllBulletDemo-Raytracer.obj `if test -f '../Raytracer/Raytracer.cpp'; then $(CYGPATH_W) '../Raytracer/Raytracer.cpp'; else $(CYGPATH_W) '$(srcdir)/../Raytracer/Raytracer.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-Raytracer.Tpo $(DEPDIR)/AllBulletDemo-Raytracer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../Raytracer/Raytracer.cpp' object='AllBulletDemo-Raytracer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-Raytracer.obj `if test -f '../Raytracer/Raytracer.cpp'; then $(CYGPATH_W) '../Raytracer/Raytracer.cpp'; else $(CYGPATH_W) '$(srcdir)/../Raytracer/Raytracer.cpp'; fi` + +AllBulletDemo-BspDemo.o: ../BspDemo/BspDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BspDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-BspDemo.Tpo -c -o AllBulletDemo-BspDemo.o `test -f '../BspDemo/BspDemo.cpp' || echo '$(srcdir)/'`../BspDemo/BspDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BspDemo.Tpo $(DEPDIR)/AllBulletDemo-BspDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BspDemo/BspDemo.cpp' object='AllBulletDemo-BspDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BspDemo.o `test -f '../BspDemo/BspDemo.cpp' || echo '$(srcdir)/'`../BspDemo/BspDemo.cpp + +AllBulletDemo-BspDemo.obj: ../BspDemo/BspDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BspDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-BspDemo.Tpo -c -o AllBulletDemo-BspDemo.obj `if test -f '../BspDemo/BspDemo.cpp'; then $(CYGPATH_W) '../BspDemo/BspDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../BspDemo/BspDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BspDemo.Tpo $(DEPDIR)/AllBulletDemo-BspDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BspDemo/BspDemo.cpp' object='AllBulletDemo-BspDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BspDemo.obj `if test -f '../BspDemo/BspDemo.cpp'; then $(CYGPATH_W) '../BspDemo/BspDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../BspDemo/BspDemo.cpp'; fi` + +AllBulletDemo-BspLoader.o: ../BspDemo/BspLoader.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BspLoader.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-BspLoader.Tpo -c -o AllBulletDemo-BspLoader.o `test -f '../BspDemo/BspLoader.cpp' || echo '$(srcdir)/'`../BspDemo/BspLoader.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BspLoader.Tpo $(DEPDIR)/AllBulletDemo-BspLoader.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BspDemo/BspLoader.cpp' object='AllBulletDemo-BspLoader.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BspLoader.o `test -f '../BspDemo/BspLoader.cpp' || echo '$(srcdir)/'`../BspDemo/BspLoader.cpp + +AllBulletDemo-BspLoader.obj: ../BspDemo/BspLoader.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BspLoader.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-BspLoader.Tpo -c -o AllBulletDemo-BspLoader.obj `if test -f '../BspDemo/BspLoader.cpp'; then $(CYGPATH_W) '../BspDemo/BspLoader.cpp'; else $(CYGPATH_W) '$(srcdir)/../BspDemo/BspLoader.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BspLoader.Tpo $(DEPDIR)/AllBulletDemo-BspLoader.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BspDemo/BspLoader.cpp' object='AllBulletDemo-BspLoader.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BspLoader.obj `if test -f '../BspDemo/BspLoader.cpp'; then $(CYGPATH_W) '../BspDemo/BspLoader.cpp'; else $(CYGPATH_W) '$(srcdir)/../BspDemo/BspLoader.cpp'; fi` + +AllBulletDemo-BspConverter.o: ../BspDemo/BspConverter.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BspConverter.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-BspConverter.Tpo -c -o AllBulletDemo-BspConverter.o `test -f '../BspDemo/BspConverter.cpp' || echo '$(srcdir)/'`../BspDemo/BspConverter.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BspConverter.Tpo $(DEPDIR)/AllBulletDemo-BspConverter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BspDemo/BspConverter.cpp' object='AllBulletDemo-BspConverter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BspConverter.o `test -f '../BspDemo/BspConverter.cpp' || echo '$(srcdir)/'`../BspDemo/BspConverter.cpp + +AllBulletDemo-BspConverter.obj: ../BspDemo/BspConverter.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-BspConverter.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-BspConverter.Tpo -c -o AllBulletDemo-BspConverter.obj `if test -f '../BspDemo/BspConverter.cpp'; then $(CYGPATH_W) '../BspDemo/BspConverter.cpp'; else $(CYGPATH_W) '$(srcdir)/../BspDemo/BspConverter.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-BspConverter.Tpo $(DEPDIR)/AllBulletDemo-BspConverter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../BspDemo/BspConverter.cpp' object='AllBulletDemo-BspConverter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-BspConverter.obj `if test -f '../BspDemo/BspConverter.cpp'; then $(CYGPATH_W) '../BspDemo/BspConverter.cpp'; else $(CYGPATH_W) '$(srcdir)/../BspDemo/BspConverter.cpp'; fi` + +AllBulletDemo-ConcaveConvexcastDemo.o: ../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConcaveConvexcastDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConcaveConvexcastDemo.Tpo -c -o AllBulletDemo-ConcaveConvexcastDemo.o `test -f '../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp' || echo '$(srcdir)/'`../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConcaveConvexcastDemo.Tpo $(DEPDIR)/AllBulletDemo-ConcaveConvexcastDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp' object='AllBulletDemo-ConcaveConvexcastDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConcaveConvexcastDemo.o `test -f '../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp' || echo '$(srcdir)/'`../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp + +AllBulletDemo-ConcaveConvexcastDemo.obj: ../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConcaveConvexcastDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConcaveConvexcastDemo.Tpo -c -o AllBulletDemo-ConcaveConvexcastDemo.obj `if test -f '../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp'; then $(CYGPATH_W) '../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConcaveConvexcastDemo.Tpo $(DEPDIR)/AllBulletDemo-ConcaveConvexcastDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp' object='AllBulletDemo-ConcaveConvexcastDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConcaveConvexcastDemo.obj `if test -f '../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp'; then $(CYGPATH_W) '../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp'; fi` + +AllBulletDemo-ConvexDecompositionDemo.o: ../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConvexDecompositionDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConvexDecompositionDemo.Tpo -c -o AllBulletDemo-ConvexDecompositionDemo.o `test -f '../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp' || echo '$(srcdir)/'`../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConvexDecompositionDemo.Tpo $(DEPDIR)/AllBulletDemo-ConvexDecompositionDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp' object='AllBulletDemo-ConvexDecompositionDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConvexDecompositionDemo.o `test -f '../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp' || echo '$(srcdir)/'`../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp + +AllBulletDemo-ConvexDecompositionDemo.obj: ../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConvexDecompositionDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConvexDecompositionDemo.Tpo -c -o AllBulletDemo-ConvexDecompositionDemo.obj `if test -f '../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp'; then $(CYGPATH_W) '../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConvexDecompositionDemo.Tpo $(DEPDIR)/AllBulletDemo-ConvexDecompositionDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp' object='AllBulletDemo-ConvexDecompositionDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConvexDecompositionDemo.obj `if test -f '../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp'; then $(CYGPATH_W) '../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp'; fi` + +AllBulletDemo-GimpactTestDemo.o: ../GimpactTestDemo/GimpactTestDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-GimpactTestDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-GimpactTestDemo.Tpo -c -o AllBulletDemo-GimpactTestDemo.o `test -f '../GimpactTestDemo/GimpactTestDemo.cpp' || echo '$(srcdir)/'`../GimpactTestDemo/GimpactTestDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-GimpactTestDemo.Tpo $(DEPDIR)/AllBulletDemo-GimpactTestDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../GimpactTestDemo/GimpactTestDemo.cpp' object='AllBulletDemo-GimpactTestDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-GimpactTestDemo.o `test -f '../GimpactTestDemo/GimpactTestDemo.cpp' || echo '$(srcdir)/'`../GimpactTestDemo/GimpactTestDemo.cpp + +AllBulletDemo-GimpactTestDemo.obj: ../GimpactTestDemo/GimpactTestDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-GimpactTestDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-GimpactTestDemo.Tpo -c -o AllBulletDemo-GimpactTestDemo.obj `if test -f '../GimpactTestDemo/GimpactTestDemo.cpp'; then $(CYGPATH_W) '../GimpactTestDemo/GimpactTestDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../GimpactTestDemo/GimpactTestDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-GimpactTestDemo.Tpo $(DEPDIR)/AllBulletDemo-GimpactTestDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../GimpactTestDemo/GimpactTestDemo.cpp' object='AllBulletDemo-GimpactTestDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-GimpactTestDemo.obj `if test -f '../GimpactTestDemo/GimpactTestDemo.cpp'; then $(CYGPATH_W) '../GimpactTestDemo/GimpactTestDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../GimpactTestDemo/GimpactTestDemo.cpp'; fi` + +AllBulletDemo-LinearConvexCastDemo.o: ../GjkConvexCastDemo/LinearConvexCastDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-LinearConvexCastDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-LinearConvexCastDemo.Tpo -c -o AllBulletDemo-LinearConvexCastDemo.o `test -f '../GjkConvexCastDemo/LinearConvexCastDemo.cpp' || echo '$(srcdir)/'`../GjkConvexCastDemo/LinearConvexCastDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-LinearConvexCastDemo.Tpo $(DEPDIR)/AllBulletDemo-LinearConvexCastDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../GjkConvexCastDemo/LinearConvexCastDemo.cpp' object='AllBulletDemo-LinearConvexCastDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-LinearConvexCastDemo.o `test -f '../GjkConvexCastDemo/LinearConvexCastDemo.cpp' || echo '$(srcdir)/'`../GjkConvexCastDemo/LinearConvexCastDemo.cpp + +AllBulletDemo-LinearConvexCastDemo.obj: ../GjkConvexCastDemo/LinearConvexCastDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-LinearConvexCastDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-LinearConvexCastDemo.Tpo -c -o AllBulletDemo-LinearConvexCastDemo.obj `if test -f '../GjkConvexCastDemo/LinearConvexCastDemo.cpp'; then $(CYGPATH_W) '../GjkConvexCastDemo/LinearConvexCastDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../GjkConvexCastDemo/LinearConvexCastDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-LinearConvexCastDemo.Tpo $(DEPDIR)/AllBulletDemo-LinearConvexCastDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../GjkConvexCastDemo/LinearConvexCastDemo.cpp' object='AllBulletDemo-LinearConvexCastDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-LinearConvexCastDemo.obj `if test -f '../GjkConvexCastDemo/LinearConvexCastDemo.cpp'; then $(CYGPATH_W) '../GjkConvexCastDemo/LinearConvexCastDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../GjkConvexCastDemo/LinearConvexCastDemo.cpp'; fi` + +AllBulletDemo-ConcavePhysicsDemo.o: ../ConcaveDemo/ConcavePhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConcavePhysicsDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConcavePhysicsDemo.Tpo -c -o AllBulletDemo-ConcavePhysicsDemo.o `test -f '../ConcaveDemo/ConcavePhysicsDemo.cpp' || echo '$(srcdir)/'`../ConcaveDemo/ConcavePhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConcavePhysicsDemo.Tpo $(DEPDIR)/AllBulletDemo-ConcavePhysicsDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConcaveDemo/ConcavePhysicsDemo.cpp' object='AllBulletDemo-ConcavePhysicsDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConcavePhysicsDemo.o `test -f '../ConcaveDemo/ConcavePhysicsDemo.cpp' || echo '$(srcdir)/'`../ConcaveDemo/ConcavePhysicsDemo.cpp + +AllBulletDemo-ConcavePhysicsDemo.obj: ../ConcaveDemo/ConcavePhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-ConcavePhysicsDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-ConcavePhysicsDemo.Tpo -c -o AllBulletDemo-ConcavePhysicsDemo.obj `if test -f '../ConcaveDemo/ConcavePhysicsDemo.cpp'; then $(CYGPATH_W) '../ConcaveDemo/ConcavePhysicsDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConcaveDemo/ConcavePhysicsDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-ConcavePhysicsDemo.Tpo $(DEPDIR)/AllBulletDemo-ConcavePhysicsDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../ConcaveDemo/ConcavePhysicsDemo.cpp' object='AllBulletDemo-ConcavePhysicsDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-ConcavePhysicsDemo.obj `if test -f '../ConcaveDemo/ConcavePhysicsDemo.cpp'; then $(CYGPATH_W) '../ConcaveDemo/ConcavePhysicsDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../ConcaveDemo/ConcavePhysicsDemo.cpp'; fi` + +AllBulletDemo-MotorDemo.o: ../DynamicControlDemo/MotorDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-MotorDemo.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-MotorDemo.Tpo -c -o AllBulletDemo-MotorDemo.o `test -f '../DynamicControlDemo/MotorDemo.cpp' || echo '$(srcdir)/'`../DynamicControlDemo/MotorDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-MotorDemo.Tpo $(DEPDIR)/AllBulletDemo-MotorDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../DynamicControlDemo/MotorDemo.cpp' object='AllBulletDemo-MotorDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-MotorDemo.o `test -f '../DynamicControlDemo/MotorDemo.cpp' || echo '$(srcdir)/'`../DynamicControlDemo/MotorDemo.cpp + +AllBulletDemo-MotorDemo.obj: ../DynamicControlDemo/MotorDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-MotorDemo.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-MotorDemo.Tpo -c -o AllBulletDemo-MotorDemo.obj `if test -f '../DynamicControlDemo/MotorDemo.cpp'; then $(CYGPATH_W) '../DynamicControlDemo/MotorDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../DynamicControlDemo/MotorDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-MotorDemo.Tpo $(DEPDIR)/AllBulletDemo-MotorDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../DynamicControlDemo/MotorDemo.cpp' object='AllBulletDemo-MotorDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-MotorDemo.obj `if test -f '../DynamicControlDemo/MotorDemo.cpp'; then $(CYGPATH_W) '../DynamicControlDemo/MotorDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/../DynamicControlDemo/MotorDemo.cpp'; fi` + +AllBulletDemo-DemoEntries.o: DemoEntries.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-DemoEntries.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-DemoEntries.Tpo -c -o AllBulletDemo-DemoEntries.o `test -f 'DemoEntries.cpp' || echo '$(srcdir)/'`DemoEntries.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-DemoEntries.Tpo $(DEPDIR)/AllBulletDemo-DemoEntries.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DemoEntries.cpp' object='AllBulletDemo-DemoEntries.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-DemoEntries.o `test -f 'DemoEntries.cpp' || echo '$(srcdir)/'`DemoEntries.cpp + +AllBulletDemo-DemoEntries.obj: DemoEntries.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-DemoEntries.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-DemoEntries.Tpo -c -o AllBulletDemo-DemoEntries.obj `if test -f 'DemoEntries.cpp'; then $(CYGPATH_W) 'DemoEntries.cpp'; else $(CYGPATH_W) '$(srcdir)/DemoEntries.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-DemoEntries.Tpo $(DEPDIR)/AllBulletDemo-DemoEntries.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DemoEntries.cpp' object='AllBulletDemo-DemoEntries.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-DemoEntries.obj `if test -f 'DemoEntries.cpp'; then $(CYGPATH_W) 'DemoEntries.cpp'; else $(CYGPATH_W) '$(srcdir)/DemoEntries.cpp'; fi` + +AllBulletDemo-Main.o: Main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-Main.o -MD -MP -MF $(DEPDIR)/AllBulletDemo-Main.Tpo -c -o AllBulletDemo-Main.o `test -f 'Main.cpp' || echo '$(srcdir)/'`Main.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-Main.Tpo $(DEPDIR)/AllBulletDemo-Main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Main.cpp' object='AllBulletDemo-Main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-Main.o `test -f 'Main.cpp' || echo '$(srcdir)/'`Main.cpp + +AllBulletDemo-Main.obj: Main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -MT AllBulletDemo-Main.obj -MD -MP -MF $(DEPDIR)/AllBulletDemo-Main.Tpo -c -o AllBulletDemo-Main.obj `if test -f 'Main.cpp'; then $(CYGPATH_W) 'Main.cpp'; else $(CYGPATH_W) '$(srcdir)/Main.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/AllBulletDemo-Main.Tpo $(DEPDIR)/AllBulletDemo-Main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Main.cpp' object='AllBulletDemo-Main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AllBulletDemo_CXXFLAGS) $(CXXFLAGS) -c -o AllBulletDemo-Main.obj `if test -f 'Main.cpp'; then $(CYGPATH_W) 'Main.cpp'; else $(CYGPATH_W) '$(srcdir)/Main.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/BasicDemo/BasicDemo.cpp b/Demos/BasicDemo/BasicDemo.cpp new file mode 100644 index 0000000..ae22362 --- /dev/null +++ b/Demos/BasicDemo/BasicDemo.cpp @@ -0,0 +1,242 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "BasicDemo.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" + +#include //printf debugging +#include "GLDebugDrawer.h" + +static GLDebugDrawer gDebugDraw; + + +void BasicDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + glFlush(); + + swapBuffers(); + +} + + + +void BasicDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + + + + + +void BasicDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + setCameraDistance(btScalar(SCALING*50.)); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld->setDebugDrawer(&gDebugDraw); + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + ///create a few basic rigid bodies + btBoxShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + //groundShape->initializePolyhedralFeatures(); +// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + btBoxShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(colShape); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); + + float start_x = START_POS_X - ARRAY_SIZE_X/2; + float start_y = START_POS_Y; + float start_z = START_POS_Z - ARRAY_SIZE_Z/2; + + for (int k=0;kaddRigidBody(body); + } + } + } + } + + +} +void BasicDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} + + +void BasicDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + public: + + BasicDemo() + { + } + virtual ~BasicDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + virtual void clientResetScene(); + + static DemoApplication* Create() + { + BasicDemo* demo = new BasicDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //BASIC_DEMO_H + diff --git a/Demos/BasicDemo/CMakeLists.txt b/Demos/BasicDemo/CMakeLists.txt new file mode 100644 index 0000000..253b8b4 --- /dev/null +++ b/Demos/BasicDemo/CMakeLists.txt @@ -0,0 +1,87 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + +IF (WIN32) +ADD_EXECUTABLE(AppBasicDemo + main.cpp + BasicDemo.cpp + BasicDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppBasicDemo + main.cpp + BasicDemo.cpp + BasicDemo.h + ) +ENDIF() + + + + + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBasicDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBasicDemo + POST_BUILD +# COMMAND copy /Y ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + ENDIF(WIN32) +ELSE (USE_GLUT) + + + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + + ADD_EXECUTABLE(AppBasicDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32BasicDemo.cpp + BasicDemo.cpp + BasicDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + + +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppBasicDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppBasicDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppBasicDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/BasicDemo/Makefile.am b/Demos/BasicDemo/Makefile.am new file mode 100644 index 0000000..0554616 --- /dev/null +++ b/Demos/BasicDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=BasicDemo + +BasicDemo_SOURCES=BasicDemo.cpp BasicDemo.h main.cpp +BasicDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +BasicDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/BasicDemo/Makefile.in b/Demos/BasicDemo/Makefile.in new file mode 100644 index 0000000..6d516e9 --- /dev/null +++ b/Demos/BasicDemo/Makefile.in @@ -0,0 +1,518 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = BasicDemo$(EXEEXT) +subdir = Demos/BasicDemo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_BasicDemo_OBJECTS = BasicDemo-BasicDemo.$(OBJEXT) \ + BasicDemo-main.$(OBJEXT) +BasicDemo_OBJECTS = $(am_BasicDemo_OBJECTS) +BasicDemo_DEPENDENCIES = +BasicDemo_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(BasicDemo_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(BasicDemo_SOURCES) +DIST_SOURCES = $(BasicDemo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +BasicDemo_SOURCES = BasicDemo.cpp BasicDemo.h main.cpp +BasicDemo_CXXFLAGS = -I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +BasicDemo_LDADD = -L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/BasicDemo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/BasicDemo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +BasicDemo$(EXEEXT): $(BasicDemo_OBJECTS) $(BasicDemo_DEPENDENCIES) + @rm -f BasicDemo$(EXEEXT) + $(BasicDemo_LINK) $(BasicDemo_OBJECTS) $(BasicDemo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BasicDemo-BasicDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BasicDemo-main.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +BasicDemo-BasicDemo.o: BasicDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -MT BasicDemo-BasicDemo.o -MD -MP -MF $(DEPDIR)/BasicDemo-BasicDemo.Tpo -c -o BasicDemo-BasicDemo.o `test -f 'BasicDemo.cpp' || echo '$(srcdir)/'`BasicDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/BasicDemo-BasicDemo.Tpo $(DEPDIR)/BasicDemo-BasicDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BasicDemo.cpp' object='BasicDemo-BasicDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -c -o BasicDemo-BasicDemo.o `test -f 'BasicDemo.cpp' || echo '$(srcdir)/'`BasicDemo.cpp + +BasicDemo-BasicDemo.obj: BasicDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -MT BasicDemo-BasicDemo.obj -MD -MP -MF $(DEPDIR)/BasicDemo-BasicDemo.Tpo -c -o BasicDemo-BasicDemo.obj `if test -f 'BasicDemo.cpp'; then $(CYGPATH_W) 'BasicDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/BasicDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/BasicDemo-BasicDemo.Tpo $(DEPDIR)/BasicDemo-BasicDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BasicDemo.cpp' object='BasicDemo-BasicDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -c -o BasicDemo-BasicDemo.obj `if test -f 'BasicDemo.cpp'; then $(CYGPATH_W) 'BasicDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/BasicDemo.cpp'; fi` + +BasicDemo-main.o: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -MT BasicDemo-main.o -MD -MP -MF $(DEPDIR)/BasicDemo-main.Tpo -c -o BasicDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/BasicDemo-main.Tpo $(DEPDIR)/BasicDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='BasicDemo-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -c -o BasicDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp + +BasicDemo-main.obj: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -MT BasicDemo-main.obj -MD -MP -MF $(DEPDIR)/BasicDemo-main.Tpo -c -o BasicDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/BasicDemo-main.Tpo $(DEPDIR)/BasicDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='BasicDemo-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(BasicDemo_CXXFLAGS) $(CXXFLAGS) -c -o BasicDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/BasicDemo/Win32BasicDemo.cpp b/Demos/BasicDemo/Win32BasicDemo.cpp new file mode 100644 index 0000000..72f92a1 --- /dev/null +++ b/Demos/BasicDemo/Win32BasicDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BasicDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new BasicDemo(); +} + +#endif diff --git a/Demos/BasicDemo/main.cpp b/Demos/BasicDemo/main.cpp new file mode 100644 index 0000000..d666630 --- /dev/null +++ b/Demos/BasicDemo/main.cpp @@ -0,0 +1,39 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BasicDemo.h" +#include "GlutStuff.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + + + +int main(int argc,char** argv) +{ + + BasicDemo ccdDemo; + ccdDemo.initPhysics(); + + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,1024,600,"Bullet Physics Demo. http://bulletphysics.org",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/Benchmarks/BenchmarkDemo.cpp b/Demos/Benchmarks/BenchmarkDemo.cpp new file mode 100644 index 0000000..b65a341 --- /dev/null +++ b/Demos/Benchmarks/BenchmarkDemo.cpp @@ -0,0 +1,1329 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +// Collision Radius +#define COLLISION_RADIUS 0.0f + +#include "BenchmarkDemo.h" +#ifdef USE_GRAPHICAL_BENCHMARK +#include "GlutStuff.h" +#endif //USE_GRAPHICAL_BENCHMARK + +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include //printf debugging +#include "Taru.mdl" +#include "landscape.mdl" +#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h" +#ifdef USE_PARALLEL_DISPATCHER_BENCHMARK +#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#include "BulletMultiThreaded/SequentialThreadSupport.h" +#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#endif + +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" + + +#ifdef USE_PARALLEL_DISPATCHER_BENCHMARK +#ifdef _WIN32 +#include "BulletMultiThreaded/Win32ThreadSupport.h" +#elif defined (USE_PTHREADS) +#include "BulletMultiThreaded/PosixThreadSupport.h" +#endif +#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#include "BulletMultiThreaded/btParallelConstraintSolver.h" + + + + +btThreadSupportInterface* createSolverThreadSupport(int maxNumThreads) +{ +//#define SEQUENTIAL +#ifdef SEQUENTIAL + SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads",SolverThreadFunc,SolverlsMemoryFunc); + SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci); + threadSupport->startSPU(); +#else + +#ifdef _WIN32 + Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("solverThreads",SolverThreadFunc,SolverlsMemoryFunc,maxNumThreads); + Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo); + threadSupport->startSPU(); +#elif defined (USE_PTHREADS) + PosixThreadSupport::ThreadConstructionInfo solverConstructionInfo("solver", SolverThreadFunc, + SolverlsMemoryFunc, maxNumThreads); + + PosixThreadSupport* threadSupport = new PosixThreadSupport(solverConstructionInfo); + +#else + SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads",SolverThreadFunc,SolverlsMemoryFunc); + SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci); + threadSupport->startSPU(); +#endif + +#endif + + return threadSupport; +} +#endif + +class btRaycastBar2 +{ +public: + btVector3 source[NUMRAYS]; + btVector3 dest[NUMRAYS]; + btVector3 direction[NUMRAYS]; + btVector3 hit[NUMRAYS]; + btVector3 normal[NUMRAYS]; + + int frame_counter; + int ms; + int sum_ms; + int sum_ms_samples; + int min_ms; + int max_ms; + +#ifdef USE_BT_CLOCK + btClock frame_timer; +#endif //USE_BT_CLOCK + + btScalar dx; + btScalar min_x; + btScalar max_x; + btScalar max_y; + btScalar sign; + + btRaycastBar2 () + { + ms = 0; + max_ms = 0; + min_ms = 9999; + sum_ms_samples = 0; + sum_ms = 0; + } + + + + btRaycastBar2 (btScalar ray_length, btScalar z,btScalar max_y) + { + frame_counter = 0; + ms = 0; + max_ms = 0; + min_ms = 9999; + sum_ms_samples = 0; + sum_ms = 0; + dx = 10.0; + min_x = 0; + max_x = 0; + this->max_y = max_y; + sign = 1.0; + btScalar dalpha = 2*SIMD_2_PI/NUMRAYS; + for (int i = 0; i < NUMRAYS; i++) + { + btScalar alpha = dalpha * i; + // rotate around by alpha degrees y + btQuaternion q(btVector3(0.0, 1.0, 0.0), alpha); + direction[i] = btVector3(1.0, 0.0, 0.0); + direction[i] = quatRotate(q , direction[i]); + direction[i] = direction[i] * ray_length; + + + source[i] = btVector3(min_x, max_y, z); + dest[i] = source[i] + direction[i]; + dest[i][1]=-1000; + normal[i] = btVector3(1.0, 0.0, 0.0); + } + } + + void move (btScalar dt) + { + if (dt > btScalar(1.0/60.0)) + dt = btScalar(1.0/60.0); + for (int i = 0; i < NUMRAYS; i++) + { + source[i][0] += dx * dt * sign; + dest[i][0] += dx * dt * sign; + } + if (source[0][0] < min_x) + sign = 1.0; + else if (source[0][0] > max_x) + sign = -1.0; + } + + void cast (btCollisionWorld* cw) + { +#ifdef USE_BT_CLOCK + frame_timer.reset (); +#endif //USE_BT_CLOCK + +#ifdef BATCH_RAYCASTER + if (!gBatchRaycaster) + return; + + gBatchRaycaster->clearRays (); + for (int i = 0; i < NUMRAYS; i++) + { + gBatchRaycaster->addRay (source[i], dest[i]); + } + gBatchRaycaster->performBatchRaycast (); + for (int i = 0; i < gBatchRaycaster->getNumRays (); i++) + { + const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i]; + hit[i].setInterpolate3(source[i],dest[i],out.hitFraction); + normal[i] = out.hitNormal; + normal[i].normalize (); + } +#else + for (int i = 0; i < NUMRAYS; i++) + { + btCollisionWorld::ClosestRayResultCallback cb(source[i], dest[i]); + + cw->rayTest (source[i], dest[i], cb); + if (cb.hasHit ()) + { + hit[i] = cb.m_hitPointWorld; + normal[i] = cb.m_hitNormalWorld; + normal[i].normalize (); + } else { + hit[i] = dest[i]; + normal[i] = btVector3(1.0, 0.0, 0.0); + } + + } +#ifdef USE_BT_CLOCK + ms += frame_timer.getTimeMilliseconds (); +#endif //USE_BT_CLOCK + frame_counter++; + if (frame_counter > 50) + { + min_ms = ms < min_ms ? ms : min_ms; + max_ms = ms > max_ms ? ms : max_ms; + sum_ms += ms; + sum_ms_samples++; + btScalar mean_ms = (btScalar)sum_ms/(btScalar)sum_ms_samples; + printf("%d rays in %d ms %d %d %f\n", NUMRAYS * frame_counter, ms, min_ms, max_ms, mean_ms); + ms = 0; + frame_counter = 0; + } +#endif + } + + void draw () + { +#ifdef USE_GRAPHICAL_BENCHMARK + glDisable (GL_LIGHTING); + glColor3f (0.0, 1.0, 0.0); + glBegin (GL_LINES); + int i; + + for (i = 0; i < NUMRAYS; i++) + { + glVertex3f (source[i][0], source[i][1], source[i][2]); + glVertex3f (hit[i][0], hit[i][1], hit[i][2]); + } + glEnd (); + glColor3f (1.0, 1.0, 1.0); + glBegin (GL_LINES); + for (i = 0; i < NUMRAYS; i++) + { + glVertex3f (hit[i][0], hit[i][1], hit[i][2]); + glVertex3f (hit[i][0] + normal[i][0], hit[i][1] + normal[i][1], hit[i][2] + normal[i][2]); + } + glEnd (); + glColor3f (0.0, 1.0, 1.0); + glBegin (GL_POINTS); + for ( i = 0; i < NUMRAYS; i++) + { + glVertex3f (hit[i][0], hit[i][1], hit[i][2]); + } + glEnd (); + glEnable (GL_LIGHTING); +#endif //USE_GRAPHICAL_BENCHMARK + + } +}; + + +static btRaycastBar2 raycastBar; + + +void BenchmarkDemo::clientMoveAndDisplay() +{ +#ifdef USE_GRAPHICAL_BENCHMARK + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#endif //USE_GRAPHICAL_BENCHMARK + + //simple dynamics world doesn't handle fixed-time-stepping + //float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(btScalar(1./60.)); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + if (m_benchmark==7) + { + castRays(); + + raycastBar.draw(); + + } + + renderme(); + +#ifdef USE_GRAPHICAL_BENCHMARK + glFlush(); + + swapBuffers(); +#endif //USE_GRAPHICAL_BENCHMARK + +} + + + +void BenchmarkDemo::displayCallback(void) +{ + +#ifdef USE_GRAPHICAL_BENCHMARK + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +#endif //USE_GRAPHICAL_BENCHMARK +} + + + + +void BenchmarkDemo::initPhysics() +{ + + setCameraDistance(btScalar(100.)); + + ///collision configuration contains default setup for memory, collision setup + btDefaultCollisionConstructionInfo cci; + cci.m_defaultMaxPersistentManifoldPoolSize = 32768; + m_collisionConfiguration = new btDefaultCollisionConfiguration(cci); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); + +#if USE_PARALLEL_DISPATCHER_BENCHMARK + + int maxNumOutstandingTasks = 4; +#ifdef _WIN32 + Win32ThreadSupport* threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( "collision",processCollisionTask, createCollisionLocalStoreMemory,maxNumOutstandingTasks)); +#elif defined (USE_PTHREADS) + PosixThreadSupport::ThreadConstructionInfo collisionConstructionInfo( "collision",processCollisionTask, createCollisionLocalStoreMemory,maxNumOutstandingTasks); + PosixThreadSupport* threadSupportCollision = new PosixThreadSupport(collisionConstructionInfo); +#endif + //SequentialThreadSupport::SequentialThreadConstructionInfo sci("spuCD", processCollisionTask, createCollisionLocalStoreMemory); + //SequentialThreadSupport* seq = new SequentialThreadSupport(sci); + m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupportCollision,1,m_collisionConfiguration); +#endif + + + ///the maximum size of the collision world. Make sure objects stay within these boundaries + ///Don't make the world AABB size too large, it will harm simulation quality and performance + btVector3 worldAabbMin(-1000,-1000,-1000); + btVector3 worldAabbMax(1000,1000,1000); + + btHashedOverlappingPairCache* pairCache = new btHashedOverlappingPairCache(); + m_overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,3500,pairCache); +// m_overlappingPairCache = new btSimpleBroadphase(); +// m_overlappingPairCache = new btDbvtBroadphase(); + + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) +#ifdef USE_PARALLEL_DISPATCHER_BENCHMARK + + btThreadSupportInterface* thread = createSolverThreadSupport(4); + btConstraintSolver* sol = new btParallelConstraintSolver(thread); +#else + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; +#endif //USE_PARALLEL_DISPATCHER_BENCHMARK + + + m_solver = sol; + + btDiscreteDynamicsWorld* dynamicsWorld; + m_dynamicsWorld = dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver,m_collisionConfiguration); + +#ifdef USE_PARALLEL_DISPATCHER_BENCHMARK + dynamicsWorld->getSimulationIslandManager()->setSplitIslands(false); +#endif //USE_PARALLEL_DISPATCHER_BENCHMARK + + ///the following 3 lines increase the performance dramatically, with a little bit of loss of quality + m_dynamicsWorld->getSolverInfo().m_solverMode |=SOLVER_ENABLE_FRICTION_DIRECTION_CACHING; //don't recalculate friction values each frame + dynamicsWorld->getSolverInfo().m_numIterations = 5; //few solver iterations + m_defaultContactProcessingThreshold = 0.f;//used when creating bodies: body->setContactProcessingThreshold(...); + + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + if (m_benchmark<5) + { + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(250.),btScalar(50.),btScalar(250.))); + // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + } + + switch (m_benchmark) + { + case 1: + { + createTest1(); + break; + } + case 2: + { + createTest2(); + break; + } + case 3: + { + createTest3(); + break; + } + case 4: + { + createTest4(); + break; + } + case 5: + { + createTest5(); + break; + } + case 6: + { + createTest6(); + break; + } + case 7: + { + createTest7(); + break; + } + + + default: + { + } + } + + + clientResetScene(); +} + + +void BenchmarkDemo::createTest1() +{ + // 3000 + int size = 8; + const float cubeSize = 1.0f; + float spacing = cubeSize; + btVector3 pos(0.0f, cubeSize * 2,0.f); + float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; + + btBoxShape* blockShape = new btBoxShape(btVector3(cubeSize-COLLISION_RADIUS,cubeSize-COLLISION_RADIUS,cubeSize-COLLISION_RADIUS)); + btVector3 localInertia(0,0,0); + float mass = 2.f; + blockShape->calculateLocalInertia(mass,localInertia); + + btTransform trans; + trans.setIdentity(); + + for(int k=0;k<47;k++) { + for(int j=0;jcalculateLocalInertia(mass,localInertia); + +// btScalar diffX = boxSize[0] * 1.0f; + btScalar diffY = boxSize[1] * 1.0f; + btScalar diffZ = boxSize[2] * 1.0f; + + btScalar offset = -stackSize * (diffZ * 2.0f) * 0.5f; + btVector3 pos(0.0f, diffY, 0.0f); + + btTransform trans; + trans.setIdentity(); + + while(stackSize) { + for(int i=0;icalculateLocalInertia(mass,localInertia); + + + btScalar diffX = boxSize[0]*1.02f; + btScalar diffY = boxSize[1]*1.02f; + btScalar diffZ = boxSize[2]*1.02f; + + btScalar offsetX = -stackSize * (diffX * 2.0f + space) * 0.5f; + btScalar offsetZ = -stackSize * (diffZ * 2.0f + space) * 0.5f; + while(stackSize) { + for(int j=0;jlocalCreateRigidBody(mass,trans,blockShape); + + + } + } + offsetX += diffX; + offsetZ += diffZ; + pos[1] += (diffY * 2.0f + space); + stackSize--; + } + +} + + const btVector3 rotate( const btQuaternion& quat, const btVector3 & vec ) +{ + float tmpX, tmpY, tmpZ, tmpW; + tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); + tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); + tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); + tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); + return btVector3( + ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), + ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), + ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) + ); +} + +void BenchmarkDemo::createTowerCircle(const btVector3& offsetPosition,int stackSize,int rotSize,const btVector3& boxSize) +{ + + btBoxShape* blockShape = new btBoxShape(btVector3(boxSize[0]-COLLISION_RADIUS,boxSize[1]-COLLISION_RADIUS,boxSize[2]-COLLISION_RADIUS)); + + btTransform trans; + trans.setIdentity(); + + float mass = 1.f; + btVector3 localInertia(0,0,0); + blockShape->calculateLocalInertia(mass,localInertia); + + + float radius = 1.3f * rotSize * boxSize[0] / SIMD_PI; + + // create active boxes + btQuaternion rotY(0,1,0,0); + float posY = boxSize[1]; + + for(int i=0;icalculateLocalInertia(mass,localInertia); + + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + m_ownerWorld->addRigidBody(body); + + return body; + } + +public: + RagDoll (btDynamicsWorld* ownerWorld, const btVector3& positionOffset,btScalar scale) + : m_ownerWorld (ownerWorld) + { + // Setup the geometry + m_shapes[BODYPART_PELVIS] = new btCapsuleShape(btScalar(0.15)*scale, btScalar(0.20)*scale); + m_shapes[BODYPART_SPINE] = new btCapsuleShape(btScalar(0.15)*scale, btScalar(0.28)*scale); + m_shapes[BODYPART_HEAD] = new btCapsuleShape(btScalar(0.10)*scale, btScalar(0.05)*scale); + m_shapes[BODYPART_LEFT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07)*scale, btScalar(0.45)*scale); + m_shapes[BODYPART_LEFT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.37)*scale); + m_shapes[BODYPART_RIGHT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07)*scale, btScalar(0.45)*scale); + m_shapes[BODYPART_RIGHT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.37)*scale); + m_shapes[BODYPART_LEFT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.33)*scale); + m_shapes[BODYPART_LEFT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04)*scale, btScalar(0.25)*scale); + m_shapes[BODYPART_RIGHT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.33)*scale); + m_shapes[BODYPART_RIGHT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04)*scale, btScalar(0.25)*scale); + + // Setup all the rigid bodies + btTransform offset; offset.setIdentity(); + offset.setOrigin(positionOffset); + + btTransform transform; + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(0.), btScalar(1.), btScalar(0.))); + m_bodies[BODYPART_PELVIS] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_PELVIS]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(0.), btScalar(1.2), btScalar(0.))); + m_bodies[BODYPART_SPINE] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_SPINE]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(0.), btScalar(1.6), btScalar(0.))); + m_bodies[BODYPART_HEAD] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_HEAD]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(-0.18), btScalar(0.65), btScalar(0.))); + m_bodies[BODYPART_LEFT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_LEG]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(-0.18), btScalar(0.2), btScalar(0.))); + m_bodies[BODYPART_LEFT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_LEG]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(0.18), btScalar(0.65), btScalar(0.))); + m_bodies[BODYPART_RIGHT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_LEG]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(0.18), btScalar(0.2), btScalar(0.))); + m_bodies[BODYPART_RIGHT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_LEG]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(-0.35), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,M_PI_2); + m_bodies[BODYPART_LEFT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_ARM]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(-0.7), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,M_PI_2); + m_bodies[BODYPART_LEFT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_ARM]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(0.35), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,-M_PI_2); + m_bodies[BODYPART_RIGHT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_ARM]); + + transform.setIdentity(); + transform.setOrigin(scale*btVector3(btScalar(0.7), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,-M_PI_2); + m_bodies[BODYPART_RIGHT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_ARM]); + + // Setup some damping on the m_bodies + for (int i = 0; i < BODYPART_COUNT; ++i) + { + m_bodies[i]->setDamping(btScalar(0.05), btScalar(0.85)); + m_bodies[i]->setDeactivationTime(btScalar(0.8)); + m_bodies[i]->setSleepingThresholds(btScalar(1.6), btScalar(2.5)); + } + + // Now setup the constraints + btHingeConstraint* hingeC; + btConeTwistConstraint* coneC; + + btTransform localA, localB; + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB); + hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2)); + m_joints[JOINT_PELVIS_SPINE] = hingeC; + m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,M_PI_2); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.30), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_HEAD], localA, localB); + coneC->setLimit(M_PI_4, M_PI_4, M_PI_2); + m_joints[JOINT_SPINE_HEAD] = coneC; + m_ownerWorld->addConstraint(m_joints[JOINT_SPINE_HEAD], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,-M_PI_4*5); localA.setOrigin(scale*btVector3(btScalar(-0.18), btScalar(-0.10), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,-M_PI_4*5); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_LEFT_UPPER_LEG], localA, localB); + coneC->setLimit(M_PI_4, M_PI_4, 0); + m_joints[JOINT_LEFT_HIP] = coneC; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_HIP], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_LEG], *m_bodies[BODYPART_LEFT_LOWER_LEG], localA, localB); + hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); + m_joints[JOINT_LEFT_KNEE] = hingeC; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_KNEE], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,M_PI_4); localA.setOrigin(scale*btVector3(btScalar(0.18), btScalar(-0.10), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_4); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_RIGHT_UPPER_LEG], localA, localB); + coneC->setLimit(M_PI_4, M_PI_4, 0); + m_joints[JOINT_RIGHT_HIP] = coneC; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_HIP], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_LEG], *m_bodies[BODYPART_RIGHT_LOWER_LEG], localA, localB); + hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); + m_joints[JOINT_RIGHT_KNEE] = hingeC; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_KNEE], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,M_PI); localA.setOrigin(scale*btVector3(btScalar(-0.2), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_LEFT_UPPER_ARM], localA, localB); + coneC->setLimit(M_PI_2, M_PI_2, 0); + m_joints[JOINT_LEFT_SHOULDER] = coneC; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_SHOULDER], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_ARM], *m_bodies[BODYPART_LEFT_LOWER_ARM], localA, localB); + hingeC->setLimit(btScalar(-M_PI_2), btScalar(0)); + m_joints[JOINT_LEFT_ELBOW] = hingeC; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_ELBOW], true); + + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,0); localA.setOrigin(scale*btVector3(btScalar(0.2), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_RIGHT_UPPER_ARM], localA, localB); + coneC->setLimit(M_PI_2, M_PI_2, 0); + m_joints[JOINT_RIGHT_SHOULDER] = coneC; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_SHOULDER], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_ARM], *m_bodies[BODYPART_RIGHT_LOWER_ARM], localA, localB); + hingeC->setLimit(btScalar(-M_PI_2), btScalar(0)); + m_joints[JOINT_RIGHT_ELBOW] = hingeC; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_ELBOW], true); + } + + virtual ~RagDoll () + { + int i; + + // Remove all constraints + for ( i = 0; i < JOINT_COUNT; ++i) + { + m_ownerWorld->removeConstraint(m_joints[i]); + delete m_joints[i]; m_joints[i] = 0; + } + + // Remove all bodies and shapes + for ( i = 0; i < BODYPART_COUNT; ++i) + { + m_ownerWorld->removeRigidBody(m_bodies[i]); + + delete m_bodies[i]->getMotionState(); + + delete m_bodies[i]; m_bodies[i] = 0; + delete m_shapes[i]; m_shapes[i] = 0; + } + } +}; + +void BenchmarkDemo::createTest3() +{ + setCameraDistance(btScalar(50.)); + + int size = 16; + + float sizeX = 1.f; + float sizeY = 1.f; + + //int rc=0; + + btScalar scale(3.5); + btVector3 pos(0.0f, sizeY, 0.0f); + while(size) { + float offset = -size * (sizeX * 6.0f) * 0.5f; + for(int i=0;isetLocalScaling(btVector3(scaling,scaling,scaling)); + + for (int i=0;iaddPoint(vtx*btScalar(1./scaling)); + } + + //this will enable polyhedral contact clipping, better quality, slightly slower + //convexHullShape->initializePolyhedralFeatures(); + + btTransform trans; + trans.setIdentity(); + + float mass = 1.f; + btVector3 localInertia(0,0,0); + convexHullShape->calculateLocalInertia(mass,localInertia); + + for(int k=0;k<15;k++) { + for(int j=0;jaddIndexedMesh(part,PHY_SHORT); + + bool useQuantizedAabbCompression = true; + btBvhTriangleMeshShape* trimeshShape = new btBvhTriangleMeshShape(meshInterface,useQuantizedAabbCompression); + btVector3 localInertia(0,0,0); + trans.setOrigin(btVector3(0,-25,0)); + + btRigidBody* body = localCreateRigidBody(0,trans,trimeshShape); + body->setFriction (btScalar(0.9)); + + } + +} + + +void BenchmarkDemo::createTest5() +{ + setCameraDistance(btScalar(250.)); + btVector3 boxSize(1.5f,1.5f,1.5f); + float boxMass = 1.0f; + float sphereRadius = 1.5f; + float sphereMass = 1.0f; + float capsuleHalf = 2.0f; + float capsuleRadius = 1.0f; + float capsuleMass = 1.0f; + + { + int size = 10; + int height = 10; + + const float cubeSize = boxSize[0]; + float spacing = 2.0f; + btVector3 pos(0.0f, 20.0f, 0.0f); + float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; + + int numBodies = 0; + + for(int k=0;kaddPoint(vtx); + } + + btTransform trans; + trans.setIdentity(); + + float mass = 1.f; + btVector3 localInertia(0,0,0); + convexHullShape->calculateLocalInertia(mass,localInertia); + + + { + int size = 10; + int height = 10; + + const float cubeSize = boxSize[0]; + float spacing = 2.0f; + btVector3 pos(0.0f, 20.0f, 0.0f); + float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; + + + for(int k=0;kgetNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + } + + //delete collision shapes + for (int j=0;jgetShapeType() != INVALID_SHAPE_PROXYTYPE)); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + shape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + + btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + body->setWorldTransform(startTransform); + body->setContactProcessingThreshold(m_defaultContactProcessingThreshold); + m_dynamicsWorld->addRigidBody(body); + + return body; +} +#endif //USE_GRAPHICAL_BENCHMARK + diff --git a/Demos/Benchmarks/BenchmarkDemo.h b/Demos/Benchmarks/BenchmarkDemo.h new file mode 100644 index 0000000..b9f1052 --- /dev/null +++ b/Demos/Benchmarks/BenchmarkDemo.h @@ -0,0 +1,265 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BENCHMARK_DEMO_H +#define BENCHMARK_DEMO_H + + +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btTransform.h" + +class btDynamicsWorld; + +#define NUMRAYS 500 + +class btRigidBody; +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; + + +#ifndef USE_GRAPHICAL_BENCHMARK +///empty placeholder +class DemoApplication +{ +protected: + + btDynamicsWorld* m_dynamicsWorld; + btScalar m_defaultContactProcessingThreshold; + +public: + DemoApplication() + :m_defaultContactProcessingThreshold(BT_LARGE_FLOAT) + { + } + virtual void myinit() {} + virtual btDynamicsWorld* getDynamicsWorld() + { + return m_dynamicsWorld; + } + + btScalar getDeltaTimeMicroseconds() + { + return 1.f; + } + + void renderme() {} + void setCameraDistance(btScalar dist){} + void clientResetScene(){} + btRigidBody* localCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape); + +}; +///BenchmarkDemo is provides several performance tests +#define PlatformDemoApplication DemoApplication +#else //USE_GRAPHICAL_BENCHMARK + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +#endif //USE_GRAPHICAL_BENCHMARK + + +class BenchmarkDemo : public PlatformDemoApplication +{ + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btAlignedObjectArray m_ragdolls; + + btBroadphaseInterface* m_overlappingPairCache; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + int m_benchmark; + + void createTest1(); + void createTest2(); + void createTest3(); + void createTest4(); + void createTest5(); + void createTest6(); + void createTest7(); + + void createWall(const btVector3& offsetPosition,int stackSize,const btVector3& boxSize); + void createPyramid(const btVector3& offsetPosition,int stackSize,const btVector3& boxSize); + void createTowerCircle(const btVector3& offsetPosition,int stackSize,int rotSize,const btVector3& boxSize); + void createLargeMeshBody(); + + + class SpuBatchRaycaster* m_batchRaycaster; + class btThreadSupportInterface* m_batchRaycasterThreadSupport; + + void castRays(); + void initRays(); + + public: + + BenchmarkDemo(int benchmark) + :m_benchmark(benchmark) + { + } + virtual ~BenchmarkDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + + + +}; + +class BenchmarkDemo1 : public BenchmarkDemo +{ +public: + BenchmarkDemo1() + :BenchmarkDemo(1) + { + } + + static DemoApplication* Create() + { + BenchmarkDemo1* demo = new BenchmarkDemo1; + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +class BenchmarkDemo2 : public BenchmarkDemo +{ +public: + BenchmarkDemo2() + :BenchmarkDemo(2) + { + } + + static DemoApplication* Create() + { + BenchmarkDemo2* demo = new BenchmarkDemo2; + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +class BenchmarkDemo3 : public BenchmarkDemo +{ +public: + BenchmarkDemo3() + :BenchmarkDemo(3) + { + } + + static DemoApplication* Create() + { + BenchmarkDemo3* demo = new BenchmarkDemo3; + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +class BenchmarkDemo4 : public BenchmarkDemo +{ +public: + BenchmarkDemo4() + :BenchmarkDemo(4) + { + } + + static DemoApplication* Create() + { + BenchmarkDemo4* demo = new BenchmarkDemo4; + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + + +class BenchmarkDemo5 : public BenchmarkDemo +{ +public: + BenchmarkDemo5() + :BenchmarkDemo(5) + { + } + + static DemoApplication* Create() + { + BenchmarkDemo5* demo = new BenchmarkDemo5; + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + + +class BenchmarkDemo6 : public BenchmarkDemo +{ +public: + BenchmarkDemo6() + :BenchmarkDemo(6) + { + } + + static DemoApplication* Create() + { + BenchmarkDemo6* demo = new BenchmarkDemo6; + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +class BenchmarkDemo7 : public BenchmarkDemo +{ +public: + BenchmarkDemo7() + :BenchmarkDemo(7) + { + } + + static DemoApplication* Create() + { + BenchmarkDemo7* demo = new BenchmarkDemo7; + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +#endif //BENCHMARK_DEMO_H + diff --git a/Demos/Benchmarks/CMakeLists.txt b/Demos/Benchmarks/CMakeLists.txt new file mode 100644 index 0000000..ce66719 --- /dev/null +++ b/Demos/Benchmarks/CMakeLists.txt @@ -0,0 +1,107 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# You shouldn't have to modify anything below this line +######################################################## + +IF (USE_GRAPHICAL_BENCHMARK) +IF (USE_GLUT) + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + IF (USE_MULTITHREADED_BENCHMARK) + INCLUDE_DIRECTORIES( ${VECTOR_MATH_INCLUDE} ) + LINK_LIBRARIES( OpenGLSupport BulletMultiThreaded BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) + ELSE() + LINK_LIBRARIES( OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) + ENDIF(USE_MULTITHREADED_BENCHMARK) + + IF (WIN32) + ADD_EXECUTABLE(AppBenchmarks + main.cpp + BenchmarkDemo.cpp + BenchmarkDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppBenchmarks + main.cpp + BenchmarkDemo.cpp + BenchmarkDemo.h + ) + ENDIF () + IF (WIN32) + IF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBenchmarks + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBenchmarks + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) + IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppBenchmarks PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppBenchmarks PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppBenchmarks PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") + ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + + ENDIF(WIN32) +ELSE (USE_GLUT) + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + IF (USE_MULTITHREADED_BENCHMARK) + INCLUDE_DIRECTORIES( ${VECTOR_MATH_INCLUDE} ) + LINK_LIBRARIES( + OpenGLSupport BulletMultiThreaded BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + ELSE() + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ENDIF() + + ADD_EXECUTABLE(AppBenchmarks + WIN32 + ../OpenGL/Win32AppMain.cpp + BenchmarkDemo.cpp + BenchmarkDemo.h + Win32BenchmarkDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ENDIF (USE_GLUT) +ELSE (USE_GRAPHICAL_BENCHMARK) + + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + IF (USE_MULTITHREADED_BENCHMARK) + LINK_LIBRARIES( BulletMultiThreaded BulletDynamics BulletCollision LinearMath ) + ELSE() + LINK_LIBRARIES( BulletDynamics BulletCollision LinearMath ) + ENDIF() + + + ADD_EXECUTABLE(AppBenchmarks + main.cpp + BenchmarkDemo.cpp + ) +ENDIF (USE_GRAPHICAL_BENCHMARK) \ No newline at end of file diff --git a/Demos/Benchmarks/Taru.mdl b/Demos/Benchmarks/Taru.mdl new file mode 100644 index 0000000..73f708c --- /dev/null +++ b/Demos/Benchmarks/Taru.mdl @@ -0,0 +1,49 @@ +#define TaruVtxCount 43 +#define TaruIdxCount 132 + +static float TaruVtx[] = { +1.08664f,-1.99237f,0.0f, +0.768369f,-1.99237f,-0.768369f, +1.28852f,1.34412e-007f,-1.28852f, +1.82224f,1.90735e-007f,0.0f, +0.0f,-1.99237f,-1.08664f, +0.0f,0.0f,-1.82224f, +0.0f,-1.99237f,-1.08664f, +-0.768369f,-1.99237f,-0.768369f, +-1.28852f,1.34412e-007f,-1.28852f, +0.0f,0.0f,-1.82224f, +-1.08664f,-1.99237f,1.82086e-007f, +-1.82224f,1.90735e-007f,1.59305e-007f, +-0.768369f,-1.99237f,0.76837f, +-1.28852f,2.47058e-007f,1.28852f, +1.42495e-007f,-1.99237f,1.08664f, +2.38958e-007f,2.70388e-007f,1.82224f, +0.768369f,-1.99237f,0.768369f, +1.28852f,2.47058e-007f,1.28852f, +0.768369f,1.99237f,-0.768369f, +1.08664f,1.99237f,0.0f, +0.0f,1.99237f,-1.08664f, +-0.768369f,1.99237f,-0.768369f, +0.0f,1.99237f,-1.08664f, +-1.08664f,1.99237f,0.0f, +-0.768369f,1.99237f,0.768369f, +1.42495e-007f,1.99237f,1.08664f, +0.768369f,1.99237f,0.768369f, +1.42495e-007f,-1.99237f,1.08664f, +-0.768369f,-1.99237f,0.76837f, +-1.08664f,-1.99237f,1.82086e-007f, +-0.768369f,-1.99237f,-0.768369f, +0.0f,-1.99237f,-1.08664f, +0.768369f,-1.99237f,-0.768369f, +1.08664f,-1.99237f,0.0f, +0.768369f,-1.99237f,0.768369f, +0.768369f,1.99237f,-0.768369f, +0.0f,1.99237f,-1.08664f, +-0.768369f,1.99237f,-0.768369f, +-1.08664f,1.99237f,0.0f, +-0.768369f,1.99237f,0.768369f, +1.42495e-007f,1.99237f,1.08664f, +0.768369f,1.99237f,0.768369f, +1.08664f,1.99237f,0.0f, +}; + diff --git a/Demos/Benchmarks/Win32BenchmarkDemo.cpp b/Demos/Benchmarks/Win32BenchmarkDemo.cpp new file mode 100644 index 0000000..486f308 --- /dev/null +++ b/Demos/Benchmarks/Win32BenchmarkDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BenchmarkDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new BenchmarkDemo(1); +} + +#endif diff --git a/Demos/Benchmarks/landscape.mdl b/Demos/Benchmarks/landscape.mdl new file mode 100644 index 0000000..6b879b2 --- /dev/null +++ b/Demos/Benchmarks/landscape.mdl @@ -0,0 +1,84369 @@ +#define Landscape02VtxCount 1980 +#define Landscape02IdxCount 11310 +#include "LinearMath/btScalar.h" + +btScalar Landscape02Vtx[] = { +-250.0f,2.99192f,113.281f, +-250.0f,2.18397f,117.188f, +-246.094f,1.62262f,113.281f, +-246.094f,1.51628f,117.188f, +-242.188f,0.847411f,113.281f, +-242.188f,0.628327f,117.188f, +-238.281f,-0.697436f,113.281f, +-238.281f,-0.567933f,117.188f, +-234.375f,-2.65115f,113.281f, +-234.375f,-2.01568f,117.188f, +-230.469f,-3.82201f,113.281f, +-230.469f,-3.41089f,117.188f, +-226.563f,-3.99138f,113.281f, +-226.563f,-3.82758f,117.188f, +-222.656f,-5.51066f,113.281f, +-222.656f,-5.01586f,117.188f, +-218.75f,-5.62904f,113.281f, +-218.75f,-4.74822f,117.188f, +-214.844f,-4.90514f,113.281f, +-214.844f,-3.30853f,117.188f, +-210.938f,-2.9572f,113.281f, +-210.938f,-2.32499f,117.188f, +-207.031f,-2.44242f,113.281f, +-207.031f,-1.71509f,117.188f, +-203.125f,-1.5086f,113.281f, +-203.125f,-1.19203f,117.188f, +-199.219f,-0.130838f,113.281f, +-199.219f,0.219498f,117.188f, +-195.313f,0.985417f,113.281f, +-195.313f,1.66304f,117.188f, +-191.406f,3.20064f,113.281f, +-191.406f,4.35105f,117.188f, +-187.5f,4.6779f,113.281f, +-187.5f,6.33228f,117.188f, +-183.594f,6.16902f,113.281f, +-183.594f,8.00972f,117.188f, +-179.688f,8.18835f,113.281f, +-179.688f,9.71486f,117.188f, +-175.781f,9.35082f,113.281f, +-175.781f,10.7727f,117.188f, +-171.875f,9.50665f,113.281f, +-171.875f,11.358f,117.188f, +-167.969f,12.1301f,113.281f, +-167.969f,12.5239f,117.188f, +-164.063f,14.8728f,113.281f, +-164.063f,14.6278f,117.188f, +-160.156f,16.3761f,113.281f, +-160.156f,17.2069f,117.188f, +-156.25f,18.5367f,113.281f, +-156.25f,19.9779f,117.188f, +-152.344f,22.4636f,113.281f, +-152.344f,23.4607f,117.188f, +-148.438f,26.1459f,113.281f, +-148.438f,26.6108f,117.188f, +-144.531f,28.6071f,113.281f, +-144.531f,28.4635f,117.188f, +-140.625f,30.2795f,113.281f, +-140.625f,29.7705f,117.188f, +-136.719f,32.2229f,113.281f, +-136.719f,31.0684f,117.188f, +-132.813f,32.8919f,113.281f, +-132.813f,31.8395f,117.188f, +-128.906f,33.5143f,113.281f, +-128.906f,32.1658f,117.188f, +-125.0f,34.6963f,113.281f, +-125.0f,34.7478f,117.188f, +-121.094f,37.3995f,113.281f, +-121.094f,36.0624f,117.188f, +-117.188f,38.0464f,113.281f, +-117.188f,37.2702f,117.188f, +-113.281f,37.8506f,113.281f, +-113.281f,37.3474f,117.188f, +-109.375f,37.8984f,113.281f, +-109.375f,37.242f,117.188f, +-105.469f,36.0464f,113.281f, +-105.469f,36.1544f,117.188f, +-101.563f,34.1136f,113.281f, +-101.563f,33.403f,117.188f, +-97.6563f,32.0925f,113.281f, +-97.6563f,31.294f,117.188f, +-93.75f,29.8306f,113.281f, +-93.75f,29.4961f,117.188f, +-89.8438f,30.1499f,113.281f, +-89.8438f,29.0556f,117.188f, +-85.9375f,28.8377f,113.281f, +-85.9375f,28.2757f,117.188f, +-82.0313f,26.9726f,113.281f, +-82.0313f,26.6322f,117.188f, +-78.125f,25.4597f,113.281f, +-78.125f,24.8286f,117.188f, +-74.2188f,23.3572f,113.281f, +-74.2188f,22.7019f,117.188f, +-70.3125f,21.1615f,113.281f, +-70.3125f,20.4725f,117.188f, +-66.4063f,18.1212f,113.281f, +-66.4063f,17.984f,117.188f, +-62.5f,16.3411f,113.281f, +-62.5f,16.3033f,117.188f, +-58.5938f,15.075f,113.281f, +-58.5938f,14.2087f,117.188f, +-54.6875f,14.2482f,113.281f, +-54.6875f,12.8086f,117.188f, +-50.7813f,13.7945f,113.281f, +-50.7813f,12.5463f,117.188f, +-46.875f,12.7086f,113.281f, +-46.875f,12.1781f,117.188f, +-42.9688f,10.5756f,113.281f, +-42.9688f,11.1391f,117.188f, +-39.0625f,9.99343f,113.281f, +-39.0625f,10.4623f,117.188f, +-35.1563f,11.0936f,113.281f, +-35.1563f,11.0528f,117.188f, +-31.25f,11.9553f,113.281f, +-31.25f,11.454f,117.188f, +-27.3438f,11.5734f,113.281f, +-27.3438f,10.5577f,117.188f, +-23.4375f,11.0397f,113.281f, +-23.4375f,10.6328f,117.188f, +-19.5313f,12.5166f,113.281f, +-19.5313f,12.5569f,117.188f, +-15.625f,13.856f,113.281f, +-15.625f,13.5389f,117.188f, +-11.7188f,14.525f,113.281f, +-11.7188f,14.3792f,117.188f, +-7.8125f,14.7554f,113.281f, +-7.8125f,15.4809f,117.188f, +-3.90625f,15.9168f,113.281f, +-3.90625f,16.1008f,117.188f, +0.0f,17.0728f,113.281f, +0.0f,17.3675f,117.188f, +3.90625f,18.3498f,113.281f, +3.90625f,18.919f,117.188f, +-250.0f,4.66213f,109.375f, +-246.094f,2.25542f,109.375f, +-242.188f,0.972654f,109.375f, +-238.281f,-1.95429f,109.375f, +-234.375f,-2.74128f,109.375f, +-230.469f,-3.62525f,109.375f, +-226.563f,-4.55305f,109.375f, +-222.656f,-6.4124f,109.375f, +-218.75f,-6.73329f,109.375f, +-214.844f,-5.91703f,109.375f, +-210.938f,-4.73996f,109.375f, +-207.031f,-3.31105f,109.375f, +-203.125f,-2.06764f,109.375f, +-199.219f,-0.969242f,109.375f, +-195.313f,0.268778f,109.375f, +-191.406f,1.94799f,109.375f, +-187.5f,2.80754f,109.375f, +-183.594f,4.22131f,109.375f, +-179.688f,5.20723f,109.375f, +-175.781f,7.47197f,109.375f, +-171.875f,9.45267f,109.375f, +-167.969f,12.6425f,109.375f, +-164.063f,14.9382f,109.375f, +-160.156f,16.7967f,109.375f, +-156.25f,19.5153f,109.375f, +-152.344f,21.4005f,109.375f, +-148.438f,25.1259f,109.375f, +-144.531f,28.4102f,109.375f, +-140.625f,30.7572f,109.375f, +-136.719f,33.0194f,109.375f, +-132.813f,33.072f,109.375f, +-128.906f,33.1358f,109.375f, +-125.0f,35.0549f,109.375f, +-121.094f,36.4427f,109.375f, +-117.188f,38.3265f,109.375f, +-113.281f,38.5339f,109.375f, +-109.375f,37.0126f,109.375f, +-105.469f,34.9063f,109.375f, +-101.563f,32.9886f,109.375f, +-97.6563f,30.8964f,109.375f, +-93.75f,30.5048f,109.375f, +-89.8438f,30.4943f,109.375f, +-85.9375f,28.8782f,109.375f, +-82.0313f,28.1966f,109.375f, +-78.125f,25.9164f,109.375f, +-74.2188f,23.3428f,109.375f, +-70.3125f,20.9839f,109.375f, +-66.4063f,18.3885f,109.375f, +-62.5f,16.9034f,109.375f, +-58.5938f,15.2602f,109.375f, +-54.6875f,14.3223f,109.375f, +-50.7813f,13.3767f,109.375f, +-46.875f,12.5798f,109.375f, +-42.9688f,11.3276f,109.375f, +-39.0625f,11.0169f,109.375f, +-35.1563f,11.7482f,109.375f, +-31.25f,12.5037f,109.375f, +-27.3438f,12.3832f,109.375f, +-23.4375f,12.3097f,109.375f, +-19.5313f,12.6165f,109.375f, +-15.625f,13.7744f,109.375f, +-11.7188f,14.363f,109.375f, +-7.8125f,14.828f,109.375f, +-3.90625f,15.599f,109.375f, +0.0f,16.3885f,109.375f, +3.90625f,18.0017f,109.375f, +-250.0f,5.23892f,105.469f, +-246.094f,2.90481f,105.469f, +-242.188f,0.264647f,105.469f, +-238.281f,-0.288927f,105.469f, +-234.375f,-0.910295f,105.469f, +-230.469f,-2.20742f,105.469f, +-226.563f,-3.6968f,105.469f, +-222.656f,-5.2145f,105.469f, +-218.75f,-6.07198f,105.469f, +-214.844f,-5.42535f,105.469f, +-210.938f,-4.82182f,105.469f, +-207.031f,-3.22017f,105.469f, +-203.125f,-2.28037f,105.469f, +-199.219f,-1.51966f,105.469f, +-195.313f,-0.0464115f,105.469f, +-191.406f,1.73523f,105.469f, +-187.5f,2.72489f,105.469f, +-183.594f,4.39996f,105.469f, +-179.688f,5.48007f,105.469f, +-175.781f,7.27769f,105.469f, +-171.875f,10.1115f,105.469f, +-167.969f,13.0557f,105.469f, +-164.063f,15.7105f,105.469f, +-160.156f,17.8448f,105.469f, +-156.25f,19.8398f,105.469f, +-152.344f,21.6672f,105.469f, +-148.438f,24.1475f,105.469f, +-144.531f,28.4217f,105.469f, +-140.625f,31.6921f,105.469f, +-136.719f,34.3814f,105.469f, +-132.813f,34.9011f,105.469f, +-128.906f,33.8056f,105.469f, +-125.0f,34.3226f,105.469f, +-121.094f,35.6061f,105.469f, +-117.188f,37.9636f,105.469f, +-113.281f,38.6673f,105.469f, +-109.375f,36.8831f,105.469f, +-105.469f,34.5846f,105.469f, +-101.563f,32.2221f,105.469f, +-97.6563f,30.3826f,105.469f, +-93.75f,30.4243f,105.469f, +-89.8438f,30.7761f,105.469f, +-85.9375f,29.8335f,105.469f, +-82.0313f,28.0208f,105.469f, +-78.125f,25.7215f,105.469f, +-74.2188f,22.9019f,105.469f, +-70.3125f,20.9096f,105.469f, +-66.4063f,18.2558f,105.469f, +-62.5f,16.689f,105.469f, +-58.5938f,15.8032f,105.469f, +-54.6875f,14.8311f,105.469f, +-50.7813f,13.7628f,105.469f, +-46.875f,13.0048f,105.469f, +-42.9688f,11.9222f,105.469f, +-39.0625f,12.021f,105.469f, +-35.1563f,12.2727f,105.469f, +-31.25f,12.6336f,105.469f, +-27.3438f,12.6865f,105.469f, +-23.4375f,12.3758f,105.469f, +-19.5313f,13.0149f,105.469f, +-15.625f,14.0448f,105.469f, +-11.7188f,14.6064f,105.469f, +-7.8125f,15.1105f,105.469f, +-3.90625f,15.8367f,105.469f, +0.0f,16.822f,105.469f, +3.90625f,17.9608f,105.469f, +-250.0f,4.27755f,101.563f, +-246.094f,2.84639f,101.563f, +-242.188f,2.00001f,101.563f, +-238.281f,1.59426f,101.563f, +-234.375f,0.494548f,101.563f, +-230.469f,-1.78619f,101.563f, +-226.563f,-2.8668f,101.563f, +-222.656f,-5.00406f,101.563f, +-218.75f,-6.01721f,101.563f, +-214.844f,-5.29731f,101.563f, +-210.938f,-4.08939f,101.563f, +-207.031f,-3.76734f,101.563f, +-203.125f,-2.53974f,101.563f, +-199.219f,-1.06933f,101.563f, +-195.313f,-0.447271f,101.563f, +-191.406f,1.52362f,101.563f, +-187.5f,3.40783f,101.563f, +-183.594f,4.48418f,101.563f, +-179.688f,6.791f,101.563f, +-175.781f,8.68642f,101.563f, +-171.875f,11.1511f,101.563f, +-167.969f,14.4536f,101.563f, +-164.063f,17.5923f,101.563f, +-160.156f,19.4108f,101.563f, +-156.25f,20.7669f,101.563f, +-152.344f,22.2683f,101.563f, +-148.438f,24.0251f,101.563f, +-144.531f,27.7431f,101.563f, +-140.625f,31.4827f,101.563f, +-136.719f,34.3945f,101.563f, +-132.813f,35.3451f,101.563f, +-128.906f,34.9912f,101.563f, +-125.0f,34.2253f,101.563f, +-121.094f,35.1765f,101.563f, +-117.188f,37.3095f,101.563f, +-113.281f,37.7256f,101.563f, +-109.375f,36.2331f,101.563f, +-105.469f,34.435f,101.563f, +-101.563f,32.1021f,101.563f, +-97.6563f,31.0728f,101.563f, +-93.75f,30.7462f,101.563f, +-89.8438f,30.8125f,101.563f, +-85.9375f,29.6802f,101.563f, +-82.0313f,27.3023f,101.563f, +-78.125f,25.1113f,101.563f, +-74.2188f,22.6475f,101.563f, +-70.3125f,20.1315f,101.563f, +-66.4063f,18.0132f,101.563f, +-62.5f,17.1414f,101.563f, +-58.5938f,16.7884f,101.563f, +-54.6875f,15.7107f,101.563f, +-50.7813f,14.6855f,101.563f, +-46.875f,13.3626f,101.563f, +-42.9688f,11.6073f,101.563f, +-39.0625f,11.3359f,101.563f, +-35.1563f,12.4227f,101.563f, +-31.25f,13.068f,101.563f, +-27.3438f,12.4485f,101.563f, +-23.4375f,11.8491f,101.563f, +-19.5313f,13.6925f,101.563f, +-15.625f,14.7114f,101.563f, +-11.7188f,14.963f,101.563f, +-7.8125f,15.0631f,101.563f, +-3.90625f,16.1214f,101.563f, +0.0f,17.0818f,101.563f, +3.90625f,17.7074f,101.563f, +-250.0f,4.24758f,97.6563f, +-246.094f,3.92716f,97.6563f, +-242.188f,3.12473f,97.6563f, +-238.281f,2.07357f,97.6563f, +-234.375f,0.407895f,97.6563f, +-230.469f,-0.904646f,97.6563f, +-226.563f,-2.62182f,97.6563f, +-222.656f,-3.89204f,97.6563f, +-218.75f,-5.61944f,97.6563f, +-214.844f,-4.00077f,97.6563f, +-210.938f,-2.40041f,97.6563f, +-207.031f,-2.40061f,97.6563f, +-203.125f,-1.96286f,97.6563f, +-199.219f,-1.48062f,97.6563f, +-195.313f,-0.101653f,97.6563f, +-191.406f,1.73583f,97.6563f, +-187.5f,3.67572f,97.6563f, +-183.594f,5.12213f,97.6563f, +-179.688f,7.63637f,97.6563f, +-175.781f,10.1724f,97.6563f, +-171.875f,12.2812f,97.6563f, +-167.969f,15.2851f,97.6563f, +-164.063f,18.2233f,97.6563f, +-160.156f,20.4971f,97.6563f, +-156.25f,21.878f,97.6563f, +-152.344f,23.2306f,97.6563f, +-148.438f,24.2686f,97.6563f, +-144.531f,28.1874f,97.6563f, +-140.625f,31.2597f,97.6563f, +-136.719f,33.3133f,97.6563f, +-132.813f,35.319f,97.6563f, +-128.906f,35.1009f,97.6563f, +-125.0f,34.8265f,97.6563f, +-121.094f,34.2935f,97.6563f, +-117.188f,36.4908f,97.6563f, +-113.281f,37.1964f,97.6563f, +-109.375f,36.1354f,97.6563f, +-105.469f,34.3852f,97.6563f, +-101.563f,30.8829f,97.6563f, +-97.6563f,30.1091f,97.6563f, +-93.75f,30.9329f,97.6563f, +-89.8438f,30.8751f,97.6563f, +-85.9375f,29.018f,97.6563f, +-82.0313f,27.3105f,97.6563f, +-78.125f,25.0087f,97.6563f, +-74.2188f,21.6466f,97.6563f, +-70.3125f,18.5043f,97.6563f, +-66.4063f,18.66f,97.6563f, +-62.5f,18.1592f,97.6563f, +-58.5938f,17.521f,97.6563f, +-54.6875f,16.3389f,97.6563f, +-50.7813f,14.8664f,97.6563f, +-46.875f,13.5991f,97.6563f, +-42.9688f,11.873f,97.6563f, +-39.0625f,11.498f,97.6563f, +-35.1563f,11.5171f,97.6563f, +-31.25f,12.5588f,97.6563f, +-27.3438f,12.2172f,97.6563f, +-23.4375f,11.2491f,97.6563f, +-19.5313f,13.2373f,97.6563f, +-15.625f,13.5683f,97.6563f, +-11.7188f,14.0875f,97.6563f, +-7.8125f,14.6591f,97.6563f, +-3.90625f,15.1275f,97.6563f, +0.0f,15.8243f,97.6563f, +3.90625f,18.0176f,97.6563f, +-250.0f,4.93619f,93.75f, +-246.094f,3.50077f,93.75f, +-242.188f,2.88532f,93.75f, +-238.281f,2.19691f,93.75f, +-234.375f,1.45343f,93.75f, +-230.469f,-0.151238f,93.75f, +-226.563f,-1.0856f,93.75f, +-222.656f,-2.29205f,93.75f, +-218.75f,-3.83678f,93.75f, +-214.844f,-2.73856f,93.75f, +-210.938f,-2.19574f,93.75f, +-207.031f,-0.222008f,93.75f, +-203.125f,-0.117961f,93.75f, +-199.219f,-0.17607f,93.75f, +-195.313f,1.32212f,93.75f, +-191.406f,2.64292f,93.75f, +-187.5f,3.72678f,93.75f, +-183.594f,5.78729f,93.75f, +-179.688f,9.09616f,93.75f, +-175.781f,11.4833f,93.75f, +-171.875f,13.1923f,93.75f, +-167.969f,15.68f,93.75f, +-164.063f,17.9844f,93.75f, +-160.156f,20.7688f,93.75f, +-156.25f,23.4925f,93.75f, +-152.344f,25.2252f,93.75f, +-148.438f,25.9373f,93.75f, +-144.531f,28.1941f,93.75f, +-140.625f,31.9896f,93.75f, +-136.719f,33.5688f,93.75f, +-132.813f,34.7177f,93.75f, +-128.906f,35.1459f,93.75f, +-125.0f,34.9785f,93.75f, +-121.094f,34.3971f,93.75f, +-117.188f,35.2455f,93.75f, +-113.281f,36.0209f,93.75f, +-109.375f,35.244f,93.75f, +-105.469f,33.4542f,93.75f, +-101.563f,30.3707f,93.75f, +-97.6563f,30.709f,93.75f, +-93.75f,31.2489f,93.75f, +-89.8438f,30.5476f,93.75f, +-85.9375f,28.5982f,93.75f, +-82.0313f,26.6838f,93.75f, +-78.125f,24.1646f,93.75f, +-74.2188f,21.261f,93.75f, +-70.3125f,19.8206f,93.75f, +-66.4063f,19.4952f,93.75f, +-62.5f,18.3276f,93.75f, +-58.5938f,18.1028f,93.75f, +-54.6875f,17.0878f,93.75f, +-50.7813f,15.0144f,93.75f, +-46.875f,13.5565f,93.75f, +-42.9688f,11.0211f,93.75f, +-39.0625f,11.1986f,93.75f, +-35.1563f,10.4097f,93.75f, +-31.25f,11.2207f,93.75f, +-27.3438f,11.4539f,93.75f, +-23.4375f,11.4014f,93.75f, +-19.5313f,12.2344f,93.75f, +-15.625f,13.5348f,93.75f, +-11.7188f,14.2772f,93.75f, +-7.8125f,14.0447f,93.75f, +-3.90625f,14.1587f,93.75f, +0.0f,15.3266f,93.75f, +3.90625f,17.1671f,93.75f, +-250.0f,5.40499f,89.8438f, +-246.094f,3.9236f,89.8438f, +-242.188f,2.78029f,89.8438f, +-238.281f,2.337f,89.8438f, +-234.375f,1.45614f,89.8438f, +-230.469f,0.487402f,89.8438f, +-226.563f,0.814658f,89.8438f, +-222.656f,-0.244101f,89.8438f, +-218.75f,-2.09422f,89.8438f, +-214.844f,-1.48441f,89.8438f, +-210.938f,-0.695794f,89.8438f, +-207.031f,0.742314f,89.8438f, +-203.125f,1.30594f,89.8438f, +-199.219f,1.49011f,89.8438f, +-195.313f,2.5687f,89.8438f, +-191.406f,3.72318f,89.8438f, +-187.5f,4.658f,89.8438f, +-183.594f,7.20615f,89.8438f, +-179.688f,9.85211f,89.8438f, +-175.781f,12.8482f,89.8438f, +-171.875f,14.6361f,89.8438f, +-167.969f,16.6036f,89.8438f, +-164.063f,19.7308f,89.8438f, +-160.156f,22.7068f,89.8438f, +-156.25f,24.421f,89.8438f, +-152.344f,25.8961f,89.8438f, +-148.438f,27.1249f,89.8438f, +-144.531f,29.0138f,89.8438f, +-140.625f,31.6384f,89.8438f, +-136.719f,33.9142f,89.8438f, +-132.813f,34.3317f,89.8438f, +-128.906f,36.0856f,89.8438f, +-125.0f,35.5134f,89.8438f, +-121.094f,34.7035f,89.8438f, +-117.188f,33.6847f,89.8438f, +-113.281f,34.2624f,89.8438f, +-109.375f,34.2147f,89.8438f, +-105.469f,32.2925f,89.8438f, +-101.563f,30.4889f,89.8438f, +-97.6563f,30.8562f,89.8438f, +-93.75f,31.4717f,89.8438f, +-89.8438f,30.2623f,89.8438f, +-85.9375f,28.4623f,89.8438f, +-82.0313f,26.6117f,89.8438f, +-78.125f,24.1755f,89.8438f, +-74.2188f,22.4752f,89.8438f, +-70.3125f,20.3246f,89.8438f, +-66.4063f,19.488f,89.8438f, +-62.5f,18.6447f,89.8438f, +-58.5938f,17.8933f,89.8438f, +-54.6875f,16.177f,89.8438f, +-50.7813f,15.2537f,89.8438f, +-46.875f,13.5232f,89.8438f, +-42.9688f,11.842f,89.8438f, +-39.0625f,10.223f,89.8438f, +-35.1563f,9.54441f,89.8438f, +-31.25f,9.73488f,89.8438f, +-27.3438f,10.7057f,89.8438f, +-23.4375f,11.9185f,89.8438f, +-19.5313f,13.2106f,89.8438f, +-15.625f,13.0807f,89.8438f, +-11.7188f,12.8112f,89.8438f, +-7.8125f,12.7972f,89.8438f, +-3.90625f,14.1049f,89.8438f, +0.0f,14.9674f,89.8438f, +3.90625f,15.6427f,89.8438f, +-250.0f,6.21462f,85.9375f, +-246.094f,4.66025f,85.9375f, +-242.188f,3.36279f,85.9375f, +-238.281f,1.97426f,85.9375f, +-234.375f,0.590897f,85.9375f, +-230.469f,2.01222f,85.9375f, +-226.563f,2.15192f,85.9375f, +-222.656f,0.78006f,85.9375f, +-218.75f,-0.424968f,85.9375f, +-214.844f,-0.512869f,85.9375f, +-210.938f,0.00319427f,85.9375f, +-207.031f,1.05715f,85.9375f, +-203.125f,2.11926f,85.9375f, +-199.219f,2.48862f,85.9375f, +-195.313f,3.89944f,85.9375f, +-191.406f,5.71899f,85.9375f, +-187.5f,6.41674f,85.9375f, +-183.594f,7.94295f,85.9375f, +-179.688f,10.9562f,85.9375f, +-175.781f,13.1951f,85.9375f, +-171.875f,15.7827f,85.9375f, +-167.969f,17.6951f,85.9375f, +-164.063f,20.2261f,85.9375f, +-160.156f,22.5211f,85.9375f, +-156.25f,24.8103f,85.9375f, +-152.344f,26.6666f,85.9375f, +-148.438f,27.7052f,85.9375f, +-144.531f,29.2234f,85.9375f, +-140.625f,31.4629f,85.9375f, +-136.719f,34.0955f,85.9375f, +-132.813f,34.7124f,85.9375f, +-128.906f,36.1712f,85.9375f, +-125.0f,36.4743f,85.9375f, +-121.094f,35.3967f,85.9375f, +-117.188f,34.3505f,85.9375f, +-113.281f,33.5175f,85.9375f, +-109.375f,32.9976f,85.9375f, +-105.469f,31.7882f,85.9375f, +-101.563f,31.1746f,85.9375f, +-97.6563f,31.0271f,85.9375f, +-93.75f,31.5303f,85.9375f, +-89.8438f,30.8744f,85.9375f, +-85.9375f,28.1434f,85.9375f, +-82.0313f,25.9196f,85.9375f, +-78.125f,24.4044f,85.9375f, +-74.2188f,21.9984f,85.9375f, +-70.3125f,20.0411f,85.9375f, +-66.4063f,19.9449f,85.9375f, +-62.5f,18.3893f,85.9375f, +-58.5938f,16.9846f,85.9375f, +-54.6875f,15.6155f,85.9375f, +-50.7813f,14.6152f,85.9375f, +-46.875f,12.7358f,85.9375f, +-42.9688f,12.1599f,85.9375f, +-39.0625f,10.1045f,85.9375f, +-35.1563f,9.61416f,85.9375f, +-31.25f,10.0784f,85.9375f, +-27.3438f,10.2188f,85.9375f, +-23.4375f,11.574f,85.9375f, +-19.5313f,11.8712f,85.9375f, +-15.625f,11.9109f,85.9375f, +-11.7188f,11.509f,85.9375f, +-7.8125f,13.9979f,85.9375f, +-3.90625f,14.8453f,85.9375f, +0.0f,14.7941f,85.9375f, +3.90625f,15.5916f,85.9375f, +-250.0f,6.94324f,82.0313f, +-246.094f,4.77131f,82.0313f, +-242.188f,3.62143f,82.0313f, +-238.281f,2.50324f,82.0313f, +-234.375f,1.40345f,82.0313f, +-230.469f,2.05881f,82.0313f, +-226.563f,2.41769f,82.0313f, +-222.656f,1.23736f,82.0313f, +-218.75f,1.59545f,82.0313f, +-214.844f,1.25313f,82.0313f, +-210.938f,1.53594f,82.0313f, +-207.031f,2.33073f,82.0313f, +-203.125f,2.59696f,82.0313f, +-199.219f,4.25487f,82.0313f, +-195.313f,5.86136f,82.0313f, +-191.406f,7.54631f,82.0313f, +-187.5f,8.7315f,82.0313f, +-183.594f,9.65737f,82.0313f, +-179.688f,11.5328f,82.0313f, +-175.781f,14.3069f,82.0313f, +-171.875f,16.2889f,82.0313f, +-167.969f,17.6379f,82.0313f, +-164.063f,20.4422f,82.0313f, +-160.156f,22.9557f,82.0313f, +-156.25f,25.0731f,82.0313f, +-152.344f,27.3881f,82.0313f, +-148.438f,28.7955f,82.0313f, +-144.531f,30.2575f,82.0313f, +-140.625f,32.5888f,82.0313f, +-136.719f,33.9884f,82.0313f, +-132.813f,34.4838f,82.0313f, +-128.906f,35.7672f,82.0313f, +-125.0f,36.1002f,82.0313f, +-121.094f,35.9318f,82.0313f, +-117.188f,34.9715f,82.0313f, +-113.281f,33.3187f,82.0313f, +-109.375f,31.9477f,82.0313f, +-105.469f,31.4437f,82.0313f, +-101.563f,31.2817f,82.0313f, +-97.6563f,32.08f,82.0313f, +-93.75f,31.4037f,82.0313f, +-89.8438f,30.2769f,82.0313f, +-85.9375f,28.1374f,82.0313f, +-82.0313f,25.4814f,82.0313f, +-78.125f,24.1831f,82.0313f, +-74.2188f,22.6148f,82.0313f, +-70.3125f,19.2585f,82.0313f, +-66.4063f,18.6785f,82.0313f, +-62.5f,17.7889f,82.0313f, +-58.5938f,16.5855f,82.0313f, +-54.6875f,14.6918f,82.0313f, +-50.7813f,12.9532f,82.0313f, +-46.875f,12.1502f,82.0313f, +-42.9688f,11.3533f,82.0313f, +-39.0625f,9.8302f,82.0313f, +-35.1563f,9.95311f,82.0313f, +-31.25f,10.7631f,82.0313f, +-27.3438f,10.2187f,82.0313f, +-23.4375f,10.1072f,82.0313f, +-19.5313f,11.299f,82.0313f, +-15.625f,11.5563f,82.0313f, +-11.7188f,13.9188f,82.0313f, +-7.8125f,15.247f,82.0313f, +-3.90625f,15.6866f,82.0313f, +0.0f,15.9694f,82.0313f, +3.90625f,16.9644f,82.0313f, +-250.0f,6.39735f,78.125f, +-246.094f,5.09353f,78.125f, +-242.188f,4.53503f,78.125f, +-238.281f,3.72522f,78.125f, +-234.375f,3.02648f,78.125f, +-230.469f,3.02057f,78.125f, +-226.563f,3.8807f,78.125f, +-222.656f,4.47382f,78.125f, +-218.75f,3.84005f,78.125f, +-214.844f,2.7347f,78.125f, +-210.938f,4.55018f,78.125f, +-207.031f,5.04579f,78.125f, +-203.125f,4.45937f,78.125f, +-199.219f,5.32656f,78.125f, +-195.313f,7.13791f,78.125f, +-191.406f,8.89822f,78.125f, +-187.5f,10.3911f,78.125f, +-183.594f,11.3679f,78.125f, +-179.688f,13.4068f,78.125f, +-175.781f,16.3393f,78.125f, +-171.875f,17.801f,78.125f, +-167.969f,19.0455f,78.125f, +-164.063f,21.4178f,78.125f, +-160.156f,23.555f,78.125f, +-156.25f,25.3953f,78.125f, +-152.344f,26.9657f,78.125f, +-148.438f,28.8194f,78.125f, +-144.531f,31.456f,78.125f, +-140.625f,33.3499f,78.125f, +-136.719f,34.2296f,78.125f, +-132.813f,34.5964f,78.125f, +-128.906f,35.7399f,78.125f, +-125.0f,35.4576f,78.125f, +-121.094f,35.7986f,78.125f, +-117.188f,34.4641f,78.125f, +-113.281f,33.925f,78.125f, +-109.375f,32.0574f,78.125f, +-105.469f,31.6743f,78.125f, +-101.563f,31.65f,78.125f, +-97.6563f,31.9461f,78.125f, +-93.75f,31.2261f,78.125f, +-89.8438f,30.4701f,78.125f, +-85.9375f,27.7569f,78.125f, +-82.0313f,25.4553f,78.125f, +-78.125f,23.3917f,78.125f, +-74.2188f,21.6944f,78.125f, +-70.3125f,18.6818f,78.125f, +-66.4063f,17.4066f,78.125f, +-62.5f,17.1317f,78.125f, +-58.5938f,16.5093f,78.125f, +-54.6875f,14.9512f,78.125f, +-50.7813f,13.228f,78.125f, +-46.875f,11.4638f,78.125f, +-42.9688f,10.3877f,78.125f, +-39.0625f,9.7131f,78.125f, +-35.1563f,10.0477f,78.125f, +-31.25f,10.325f,78.125f, +-27.3438f,10.317f,78.125f, +-23.4375f,10.9076f,78.125f, +-19.5313f,11.7808f,78.125f, +-15.625f,14.1905f,78.125f, +-11.7188f,15.6035f,78.125f, +-7.8125f,16.0979f,78.125f, +-3.90625f,16.6425f,78.125f, +0.0f,17.2837f,78.125f, +3.90625f,18.8244f,78.125f, +-250.0f,6.03592f,74.2188f, +-246.094f,5.17606f,74.2188f, +-242.188f,3.7036f,74.2188f, +-238.281f,3.69f,74.2188f, +-234.375f,4.60611f,74.2188f, +-230.469f,4.52682f,74.2188f, +-226.563f,5.59937f,74.2188f, +-222.656f,6.25837f,74.2188f, +-218.75f,5.11517f,74.2188f, +-214.844f,4.67242f,74.2188f, +-210.938f,5.76173f,74.2188f, +-207.031f,6.80461f,74.2188f, +-203.125f,6.95083f,74.2188f, +-199.219f,7.35893f,74.2188f, +-195.313f,8.63949f,74.2188f, +-191.406f,10.4144f,74.2188f, +-187.5f,11.8105f,74.2188f, +-183.594f,13.4583f,74.2188f, +-179.688f,15.5665f,74.2188f, +-175.781f,18.2568f,74.2188f, +-171.875f,19.1732f,74.2188f, +-167.969f,21.3098f,74.2188f, +-164.063f,23.6359f,74.2188f, +-160.156f,25.3154f,74.2188f, +-156.25f,27.6289f,74.2188f, +-152.344f,28.8953f,74.2188f, +-148.438f,30.5098f,74.2188f, +-144.531f,32.3942f,74.2188f, +-140.625f,33.3325f,74.2188f, +-136.719f,33.8009f,74.2188f, +-132.813f,35.0803f,74.2188f, +-128.906f,34.737f,74.2188f, +-125.0f,34.3656f,74.2188f, +-121.094f,34.2107f,74.2188f, +-117.188f,33.1645f,74.2188f, +-113.281f,32.0615f,74.2188f, +-109.375f,32.0827f,74.2188f, +-105.469f,32.4658f,74.2188f, +-101.563f,31.6315f,74.2188f, +-97.6563f,30.9698f,74.2188f, +-93.75f,30.6464f,74.2188f, +-89.8438f,29.9645f,74.2188f, +-85.9375f,27.4393f,74.2188f, +-82.0313f,25.2807f,74.2188f, +-78.125f,23.57f,74.2188f, +-74.2188f,20.653f,74.2188f, +-70.3125f,18.1395f,74.2188f, +-66.4063f,17.6585f,74.2188f, +-62.5f,17.2798f,74.2188f, +-58.5938f,16.6041f,74.2188f, +-54.6875f,14.6913f,74.2188f, +-50.7813f,13.1416f,74.2188f, +-46.875f,10.9374f,74.2188f, +-42.9688f,9.39485f,74.2188f, +-39.0625f,9.21956f,74.2188f, +-35.1563f,9.74875f,74.2188f, +-31.25f,10.3932f,74.2188f, +-27.3438f,10.7996f,74.2188f, +-23.4375f,11.5538f,74.2188f, +-19.5313f,13.5418f,74.2188f, +-15.625f,15.6336f,74.2188f, +-11.7188f,16.3846f,74.2188f, +-7.8125f,17.738f,74.2188f, +-3.90625f,17.98f,74.2188f, +0.0f,19.1669f,74.2188f, +3.90625f,20.6829f,74.2188f, +-250.0f,5.45149f,70.3125f, +-246.094f,4.83779f,70.3125f, +-242.188f,3.60093f,70.3125f, +-238.281f,3.26469f,70.3125f, +-234.375f,4.06145f,70.3125f, +-230.469f,5.31565f,70.3125f, +-226.563f,6.65809f,70.3125f, +-222.656f,6.70538f,70.3125f, +-218.75f,6.93258f,70.3125f, +-214.844f,6.84841f,70.3125f, +-210.938f,6.9662f,70.3125f, +-207.031f,7.74003f,70.3125f, +-203.125f,8.68749f,70.3125f, +-199.219f,9.06225f,70.3125f, +-195.313f,10.0803f,70.3125f, +-191.406f,12.202f,70.3125f, +-187.5f,14.063f,70.3125f, +-183.594f,15.732f,70.3125f, +-179.688f,18.3972f,70.3125f, +-175.781f,19.5054f,70.3125f, +-171.875f,20.8927f,70.3125f, +-167.969f,23.3843f,70.3125f, +-164.063f,25.5894f,70.3125f, +-160.156f,27.0506f,70.3125f, +-156.25f,28.6483f,70.3125f, +-152.344f,31.3986f,70.3125f, +-148.438f,32.5255f,70.3125f, +-144.531f,33.0315f,70.3125f, +-140.625f,33.0927f,70.3125f, +-136.719f,33.7595f,70.3125f, +-132.813f,34.1872f,70.3125f, +-128.906f,33.4924f,70.3125f, +-125.0f,34.1817f,70.3125f, +-121.094f,33.4642f,70.3125f, +-117.188f,32.3231f,70.3125f, +-113.281f,32.1235f,70.3125f, +-109.375f,32.674f,70.3125f, +-105.469f,32.7558f,70.3125f, +-101.563f,32.4896f,70.3125f, +-97.6563f,30.7945f,70.3125f, +-93.75f,30.1182f,70.3125f, +-89.8438f,28.6969f,70.3125f, +-85.9375f,26.606f,70.3125f, +-82.0313f,24.8053f,70.3125f, +-78.125f,23.3599f,70.3125f, +-74.2188f,20.5363f,70.3125f, +-70.3125f,18.2858f,70.3125f, +-66.4063f,17.647f,70.3125f, +-62.5f,17.3761f,70.3125f, +-58.5938f,16.3124f,70.3125f, +-54.6875f,14.016f,70.3125f, +-50.7813f,11.6317f,70.3125f, +-46.875f,9.68832f,70.3125f, +-42.9688f,8.63692f,70.3125f, +-39.0625f,8.52412f,70.3125f, +-35.1563f,10.3549f,70.3125f, +-31.25f,11.1185f,70.3125f, +-27.3438f,12.8223f,70.3125f, +-23.4375f,14.2548f,70.3125f, +-19.5313f,15.4066f,70.3125f, +-15.625f,16.875f,70.3125f, +-11.7188f,17.7202f,70.3125f, +-7.8125f,18.6716f,70.3125f, +-3.90625f,19.72f,70.3125f, +0.0f,21.3086f,70.3125f, +3.90625f,22.948f,70.3125f, +-250.0f,4.53118f,66.4063f, +-246.094f,3.73568f,66.4063f, +-242.188f,3.80679f,66.4063f, +-238.281f,4.42509f,66.4063f, +-234.375f,5.0317f,66.4063f, +-230.469f,6.63484f,66.4063f, +-226.563f,7.65599f,66.4063f, +-222.656f,8.55305f,66.4063f, +-218.75f,8.71866f,66.4063f, +-214.844f,7.68897f,66.4063f, +-210.938f,8.59141f,66.4063f, +-207.031f,9.73811f,66.4063f, +-203.125f,10.1348f,66.4063f, +-199.219f,10.1075f,66.4063f, +-195.313f,11.1394f,66.4063f, +-191.406f,13.5829f,66.4063f, +-187.5f,15.4951f,66.4063f, +-183.594f,17.5574f,66.4063f, +-179.688f,19.9291f,66.4063f, +-175.781f,21.0567f,66.4063f, +-171.875f,22.5003f,66.4063f, +-167.969f,25.5993f,66.4063f, +-164.063f,27.0097f,66.4063f, +-160.156f,27.9166f,66.4063f, +-156.25f,29.8989f,66.4063f, +-152.344f,32.1785f,66.4063f, +-148.438f,34.0669f,66.4063f, +-144.531f,34.5129f,66.4063f, +-140.625f,34.1795f,66.4063f, +-136.719f,33.3311f,66.4063f, +-132.813f,32.969f,66.4063f, +-128.906f,32.9477f,66.4063f, +-125.0f,33.5186f,66.4063f, +-121.094f,32.9715f,66.4063f, +-117.188f,32.4898f,66.4063f, +-113.281f,33.0858f,66.4063f, +-109.375f,32.6501f,66.4063f, +-105.469f,32.847f,66.4063f, +-101.563f,32.8074f,66.4063f, +-97.6563f,31.5661f,66.4063f, +-93.75f,29.4807f,66.4063f, +-89.8438f,28.6706f,66.4063f, +-85.9375f,26.408f,66.4063f, +-82.0313f,24.3989f,66.4063f, +-78.125f,22.4069f,66.4063f, +-74.2188f,20.2026f,66.4063f, +-70.3125f,18.5513f,66.4063f, +-66.4063f,17.0548f,66.4063f, +-62.5f,17.0623f,66.4063f, +-58.5938f,15.9909f,66.4063f, +-54.6875f,13.3885f,66.4063f, +-50.7813f,11.8657f,66.4063f, +-46.875f,9.02652f,66.4063f, +-42.9688f,8.99046f,66.4063f, +-39.0625f,10.0543f,66.4063f, +-35.1563f,11.7078f,66.4063f, +-31.25f,12.4956f,66.4063f, +-27.3438f,14.0575f,66.4063f, +-23.4375f,15.2147f,66.4063f, +-19.5313f,16.7089f,66.4063f, +-15.625f,17.8009f,66.4063f, +-11.7188f,19.0086f,66.4063f, +-7.8125f,20.9864f,66.4063f, +-3.90625f,22.6943f,66.4063f, +0.0f,23.9641f,66.4063f, +3.90625f,25.5564f,66.4063f, +-250.0f,4.6779f,62.5f, +-246.094f,4.41735f,62.5f, +-242.188f,3.93647f,62.5f, +-238.281f,4.50648f,62.5f, +-234.375f,5.52163f,62.5f, +-230.469f,7.10395f,62.5f, +-226.563f,8.10257f,62.5f, +-222.656f,8.36726f,62.5f, +-218.75f,8.58321f,62.5f, +-214.844f,8.56809f,62.5f, +-210.938f,9.95321f,62.5f, +-207.031f,10.4904f,62.5f, +-203.125f,10.812f,62.5f, +-199.219f,11.5942f,62.5f, +-195.313f,13.0371f,62.5f, +-191.406f,14.6432f,62.5f, +-187.5f,16.7375f,62.5f, +-183.594f,18.4129f,62.5f, +-179.688f,20.9534f,62.5f, +-175.781f,23.1161f,62.5f, +-171.875f,25.0267f,62.5f, +-167.969f,26.7355f,62.5f, +-164.063f,27.6983f,62.5f, +-160.156f,29.1111f,62.5f, +-156.25f,31.1905f,62.5f, +-152.344f,32.9766f,62.5f, +-148.438f,33.4703f,62.5f, +-144.531f,33.714f,62.5f, +-140.625f,33.649f,62.5f, +-136.719f,33.0246f,62.5f, +-132.813f,32.7386f,62.5f, +-128.906f,32.6069f,62.5f, +-125.0f,32.6579f,62.5f, +-121.094f,31.5955f,62.5f, +-117.188f,31.8589f,62.5f, +-113.281f,32.7188f,62.5f, +-109.375f,32.889f,62.5f, +-105.469f,32.7317f,62.5f, +-101.563f,32.4229f,62.5f, +-97.6563f,31.2118f,62.5f, +-93.75f,30.6824f,62.5f, +-89.8438f,28.584f,62.5f, +-85.9375f,26.1183f,62.5f, +-82.0313f,23.8148f,62.5f, +-78.125f,22.0333f,62.5f, +-74.2188f,20.178f,62.5f, +-70.3125f,18.704f,62.5f, +-66.4063f,16.8036f,62.5f, +-62.5f,15.7173f,62.5f, +-58.5938f,13.9284f,62.5f, +-54.6875f,13.0731f,62.5f, +-50.7813f,11.8974f,62.5f, +-46.875f,9.91347f,62.5f, +-42.9688f,10.1439f,62.5f, +-39.0625f,11.304f,62.5f, +-35.1563f,12.5111f,62.5f, +-31.25f,14.112f,62.5f, +-27.3438f,15.3325f,62.5f, +-23.4375f,16.6214f,62.5f, +-19.5313f,17.8469f,62.5f, +-15.625f,19.2987f,62.5f, +-11.7188f,20.9518f,62.5f, +-7.8125f,23.4289f,62.5f, +-3.90625f,24.9379f,62.5f, +0.0f,26.156f,62.5f, +3.90625f,27.1929f,62.5f, +-250.0f,4.23938f,58.5938f, +-246.094f,4.819f,58.5938f, +-242.188f,4.63067f,58.5938f, +-238.281f,5.29023f,58.5938f, +-234.375f,6.48193f,58.5938f, +-230.469f,6.85856f,58.5938f, +-226.563f,8.4748f,58.5938f, +-222.656f,8.76416f,58.5938f, +-218.75f,9.24425f,58.5938f, +-214.844f,9.67654f,58.5938f, +-210.938f,10.8063f,58.5938f, +-207.031f,12.3237f,58.5938f, +-203.125f,12.7409f,58.5938f, +-199.219f,12.7587f,58.5938f, +-195.313f,14.3653f,58.5938f, +-191.406f,16.1467f,58.5938f, +-187.5f,17.0489f,58.5938f, +-183.594f,19.2091f,58.5938f, +-179.688f,21.7856f,58.5938f, +-175.781f,24.7829f,58.5938f, +-171.875f,26.2396f,58.5938f, +-167.969f,27.2756f,58.5938f, +-164.063f,28.2919f,58.5938f, +-160.156f,30.5945f,58.5938f, +-156.25f,32.2617f,58.5938f, +-152.344f,32.9049f,58.5938f, +-148.438f,32.8002f,58.5938f, +-144.531f,32.4751f,58.5938f, +-140.625f,32.4049f,58.5938f, +-136.719f,33.5631f,58.5938f, +-132.813f,33.3828f,58.5938f, +-128.906f,33.1064f,58.5938f, +-125.0f,32.3054f,58.5938f, +-121.094f,32.5047f,58.5938f, +-117.188f,32.3246f,58.5938f, +-113.281f,32.4393f,58.5938f, +-109.375f,32.553f,58.5938f, +-105.469f,32.9281f,58.5938f, +-101.563f,31.8539f,58.5938f, +-97.6563f,30.9253f,58.5938f, +-93.75f,30.4328f,58.5938f, +-89.8438f,28.3295f,58.5938f, +-85.9375f,25.5393f,58.5938f, +-82.0313f,23.0691f,58.5938f, +-78.125f,21.505f,58.5938f, +-74.2188f,21.0748f,58.5938f, +-70.3125f,19.1186f,58.5938f, +-66.4063f,16.7814f,58.5938f, +-62.5f,15.2179f,58.5938f, +-58.5938f,14.1291f,58.5938f, +-54.6875f,13.2351f,58.5938f, +-50.7813f,11.896f,58.5938f, +-46.875f,11.0911f,58.5938f, +-42.9688f,12.7485f,58.5938f, +-39.0625f,13.7045f,58.5938f, +-35.1563f,14.6128f,58.5938f, +-31.25f,15.546f,58.5938f, +-27.3438f,16.7828f,58.5938f, +-23.4375f,18.7578f,58.5938f, +-19.5313f,19.7951f,58.5938f, +-15.625f,21.8594f,58.5938f, +-11.7188f,22.7269f,58.5938f, +-7.8125f,24.983f,58.5938f, +-3.90625f,26.43f,58.5938f, +0.0f,27.4466f,58.5938f, +3.90625f,28.3495f,58.5938f, +-250.0f,3.62748f,54.6875f, +-246.094f,3.83329f,54.6875f, +-242.188f,4.44022f,54.6875f, +-238.281f,5.27514f,54.6875f, +-234.375f,7.43995f,54.6875f, +-230.469f,7.59176f,54.6875f, +-226.563f,8.28985f,54.6875f, +-222.656f,9.62184f,54.6875f, +-218.75f,10.6613f,54.6875f, +-214.844f,11.0914f,54.6875f, +-210.938f,12.2186f,54.6875f, +-207.031f,13.1985f,54.6875f, +-203.125f,13.9982f,54.6875f, +-199.219f,14.3187f,54.6875f, +-195.313f,14.8791f,54.6875f, +-191.406f,16.5829f,54.6875f, +-187.5f,18.231f,54.6875f, +-183.594f,20.0621f,54.6875f, +-179.688f,22.8941f,54.6875f, +-175.781f,25.0841f,54.6875f, +-171.875f,26.5655f,54.6875f, +-167.969f,27.3542f,54.6875f, +-164.063f,29.2247f,54.6875f, +-160.156f,30.91f,54.6875f, +-156.25f,33.3376f,54.6875f, +-152.344f,32.8808f,54.6875f, +-148.438f,32.5783f,54.6875f, +-144.531f,32.6138f,54.6875f, +-140.625f,32.9002f,54.6875f, +-136.719f,34.2312f,54.6875f, +-132.813f,33.8335f,54.6875f, +-128.906f,32.8545f,54.6875f, +-125.0f,33.6683f,54.6875f, +-121.094f,32.9953f,54.6875f, +-117.188f,32.5096f,54.6875f, +-113.281f,32.4307f,54.6875f, +-109.375f,31.8214f,54.6875f, +-105.469f,31.851f,54.6875f, +-101.563f,31.6383f,54.6875f, +-97.6563f,30.4359f,54.6875f, +-93.75f,28.9306f,54.6875f, +-89.8438f,26.5955f,54.6875f, +-85.9375f,24.7234f,54.6875f, +-82.0313f,23.0595f,54.6875f, +-78.125f,21.3558f,54.6875f, +-74.2188f,20.3788f,54.6875f, +-70.3125f,19.3201f,54.6875f, +-66.4063f,16.9597f,54.6875f, +-62.5f,14.6652f,54.6875f, +-58.5938f,14.4899f,54.6875f, +-54.6875f,13.3432f,54.6875f, +-50.7813f,12.3286f,54.6875f, +-46.875f,12.6498f,54.6875f, +-42.9688f,14.2651f,54.6875f, +-39.0625f,15.6887f,54.6875f, +-35.1563f,16.2038f,54.6875f, +-31.25f,17.2337f,54.6875f, +-27.3438f,18.7628f,54.6875f, +-23.4375f,20.2472f,54.6875f, +-19.5313f,21.6809f,54.6875f, +-15.625f,24.084f,54.6875f, +-11.7188f,25.1582f,54.6875f, +-7.8125f,26.7f,54.6875f, +-3.90625f,27.5421f,54.6875f, +0.0f,28.3244f,54.6875f, +3.90625f,29.2057f,54.6875f, +-250.0f,3.74657f,50.7813f, +-246.094f,3.89172f,50.7813f, +-242.188f,4.12295f,50.7813f, +-238.281f,5.16915f,50.7813f, +-234.375f,6.30394f,50.7813f, +-230.469f,7.21975f,50.7813f, +-226.563f,8.61249f,50.7813f, +-222.656f,10.1295f,50.7813f, +-218.75f,12.2813f,50.7813f, +-214.844f,12.3309f,50.7813f, +-210.938f,13.3907f,50.7813f, +-207.031f,14.1528f,50.7813f, +-203.125f,14.0334f,50.7813f, +-199.219f,14.814f,50.7813f, +-195.313f,16.69f,50.7813f, +-191.406f,17.639f,50.7813f, +-187.5f,19.261f,50.7813f, +-183.594f,20.748f,50.7813f, +-179.688f,23.3343f,50.7813f, +-175.781f,25.4837f,50.7813f, +-171.875f,26.8456f,50.7813f, +-167.969f,27.7788f,50.7813f, +-164.063f,30.0174f,50.7813f, +-160.156f,31.0689f,50.7813f, +-156.25f,32.5898f,50.7813f, +-152.344f,32.5672f,50.7813f, +-148.438f,32.4654f,50.7813f, +-144.531f,33.702f,50.7813f, +-140.625f,34.7593f,50.7813f, +-136.719f,33.9086f,50.7813f, +-132.813f,33.681f,50.7813f, +-128.906f,33.6369f,50.7813f, +-125.0f,34.0371f,50.7813f, +-121.094f,34.0479f,50.7813f, +-117.188f,34.513f,50.7813f, +-113.281f,33.7072f,50.7813f, +-109.375f,32.2763f,50.7813f, +-105.469f,32.0608f,50.7813f, +-101.563f,31.0833f,50.7813f, +-97.6563f,29.9168f,50.7813f, +-93.75f,28.7604f,50.7813f, +-89.8438f,26.9563f,50.7813f, +-85.9375f,24.7908f,50.7813f, +-82.0313f,23.7925f,50.7813f, +-78.125f,21.7037f,50.7813f, +-74.2188f,19.5308f,50.7813f, +-70.3125f,19.3367f,50.7813f, +-66.4063f,17.8482f,50.7813f, +-62.5f,14.2491f,50.7813f, +-58.5938f,14.7414f,50.7813f, +-54.6875f,14.0395f,50.7813f, +-50.7813f,12.9738f,50.7813f, +-46.875f,13.9471f,50.7813f, +-42.9688f,15.8319f,50.7813f, +-39.0625f,16.6566f,50.7813f, +-35.1563f,17.1252f,50.7813f, +-31.25f,18.6998f,50.7813f, +-27.3438f,20.877f,50.7813f, +-23.4375f,22.0249f,50.7813f, +-19.5313f,22.9369f,50.7813f, +-15.625f,25.686f,50.7813f, +-11.7188f,26.1758f,50.7813f, +-7.8125f,28.3828f,50.7813f, +-3.90625f,28.7973f,50.7813f, +0.0f,29.7276f,50.7813f, +3.90625f,30.4306f,50.7813f, +-250.0f,3.69244f,46.875f, +-246.094f,3.88583f,46.875f, +-242.188f,3.98468f,46.875f, +-238.281f,5.01772f,46.875f, +-234.375f,7.23791f,46.875f, +-230.469f,7.78117f,46.875f, +-226.563f,8.55298f,46.875f, +-222.656f,10.2684f,46.875f, +-218.75f,11.1917f,46.875f, +-214.844f,12.411f,46.875f, +-210.938f,13.7214f,46.875f, +-207.031f,14.4662f,46.875f, +-203.125f,15.536f,46.875f, +-199.219f,15.6035f,46.875f, +-195.313f,16.8456f,46.875f, +-191.406f,18.4656f,46.875f, +-187.5f,19.415f,46.875f, +-183.594f,20.8504f,46.875f, +-179.688f,23.9388f,46.875f, +-175.781f,26.2956f,46.875f, +-171.875f,27.6728f,46.875f, +-167.969f,28.2497f,46.875f, +-164.063f,29.6503f,46.875f, +-160.156f,31.9344f,46.875f, +-156.25f,33.4163f,46.875f, +-152.344f,33.428f,46.875f, +-148.438f,33.3157f,46.875f, +-144.531f,33.6261f,46.875f, +-140.625f,35.1888f,46.875f, +-136.719f,34.8434f,46.875f, +-132.813f,34.1219f,46.875f, +-128.906f,34.4564f,46.875f, +-125.0f,34.9729f,46.875f, +-121.094f,34.8811f,46.875f, +-117.188f,35.185f,46.875f, +-113.281f,34.138f,46.875f, +-109.375f,32.7077f,46.875f, +-105.469f,32.2219f,46.875f, +-101.563f,31.2475f,46.875f, +-97.6563f,29.9637f,46.875f, +-93.75f,28.1214f,46.875f, +-89.8438f,27.0889f,46.875f, +-85.9375f,25.092f,46.875f, +-82.0313f,23.3983f,46.875f, +-78.125f,22.275f,46.875f, +-74.2188f,19.8598f,46.875f, +-70.3125f,18.8797f,46.875f, +-66.4063f,17.2468f,46.875f, +-62.5f,15.4985f,46.875f, +-58.5938f,14.5357f,46.875f, +-54.6875f,14.6964f,46.875f, +-50.7813f,13.3496f,46.875f, +-46.875f,15.6354f,46.875f, +-42.9688f,16.7177f,46.875f, +-39.0625f,17.4527f,46.875f, +-35.1563f,18.2826f,46.875f, +-31.25f,20.3293f,46.875f, +-27.3438f,22.684f,46.875f, +-23.4375f,23.538f,46.875f, +-19.5313f,24.3046f,46.875f, +-15.625f,26.1113f,46.875f, +-11.7188f,27.4881f,46.875f, +-7.8125f,29.3572f,46.875f, +-3.90625f,29.786f,46.875f, +0.0f,30.3637f,46.875f, +3.90625f,30.8772f,46.875f, +-250.0f,4.08083f,42.9688f, +-246.094f,4.09778f,42.9688f, +-242.188f,3.87631f,42.9688f, +-238.281f,5.12214f,42.9688f, +-234.375f,6.70993f,42.9688f, +-230.469f,7.75806f,42.9688f, +-226.563f,8.13676f,42.9688f, +-222.656f,8.85151f,42.9688f, +-218.75f,10.9378f,42.9688f, +-214.844f,12.4043f,42.9688f, +-210.938f,13.4636f,42.9688f, +-207.031f,14.7352f,42.9688f, +-203.125f,15.605f,42.9688f, +-199.219f,15.7497f,42.9688f, +-195.313f,17.184f,42.9688f, +-191.406f,19.3679f,42.9688f, +-187.5f,21.1701f,42.9688f, +-183.594f,22.7204f,42.9688f, +-179.688f,24.8128f,42.9688f, +-175.781f,26.7707f,42.9688f, +-171.875f,27.7521f,42.9688f, +-167.969f,28.8689f,42.9688f, +-164.063f,31.1205f,42.9688f, +-160.156f,33.289f,42.9688f, +-156.25f,34.2815f,42.9688f, +-152.344f,33.9797f,42.9688f, +-148.438f,34.2527f,42.9688f, +-144.531f,34.1886f,42.9688f, +-140.625f,34.868f,42.9688f, +-136.719f,35.6569f,42.9688f, +-132.813f,35.4999f,42.9688f, +-128.906f,35.4373f,42.9688f, +-125.0f,36.373f,42.9688f, +-121.094f,35.4304f,42.9688f, +-117.188f,34.3543f,42.9688f, +-113.281f,35.0651f,42.9688f, +-109.375f,33.5051f,42.9688f, +-105.469f,32.471f,42.9688f, +-101.563f,31.2764f,42.9688f, +-97.6563f,29.7633f,42.9688f, +-93.75f,27.9107f,42.9688f, +-89.8438f,26.5273f,42.9688f, +-85.9375f,25.2444f,42.9688f, +-82.0313f,23.6093f,42.9688f, +-78.125f,21.9684f,42.9688f, +-74.2188f,19.4992f,42.9688f, +-70.3125f,17.8231f,42.9688f, +-66.4063f,17.4082f,42.9688f, +-62.5f,17.0938f,42.9688f, +-58.5938f,15.3348f,42.9688f, +-54.6875f,14.7964f,42.9688f, +-50.7813f,14.9948f,42.9688f, +-46.875f,17.1807f,42.9688f, +-42.9688f,18.118f,42.9688f, +-39.0625f,19.0809f,42.9688f, +-35.1563f,19.6971f,42.9688f, +-31.25f,21.652f,42.9688f, +-27.3438f,23.4343f,42.9688f, +-23.4375f,24.5708f,42.9688f, +-19.5313f,25.2003f,42.9688f, +-15.625f,26.8391f,42.9688f, +-11.7188f,28.9343f,42.9688f, +-7.8125f,29.9079f,42.9688f, +-3.90625f,31.268f,42.9688f, +0.0f,31.3916f,42.9688f, +3.90625f,31.8945f,42.9688f, +-250.0f,4.27976f,39.0625f, +-246.094f,4.20341f,39.0625f, +-242.188f,3.80298f,39.0625f, +-238.281f,4.79243f,39.0625f, +-234.375f,5.51846f,39.0625f, +-230.469f,6.91597f,39.0625f, +-226.563f,8.25726f,39.0625f, +-222.656f,8.85037f,39.0625f, +-218.75f,9.57429f,39.0625f, +-214.844f,11.3899f,39.0625f, +-210.938f,12.5806f,39.0625f, +-207.031f,14.2509f,39.0625f, +-203.125f,14.7828f,39.0625f, +-199.219f,15.9801f,39.0625f, +-195.313f,17.4225f,39.0625f, +-191.406f,19.6018f,39.0625f, +-187.5f,22.1095f,39.0625f, +-183.594f,23.8333f,39.0625f, +-179.688f,25.0671f,39.0625f, +-175.781f,27.1067f,39.0625f, +-171.875f,28.5f,39.0625f, +-167.969f,29.9625f,39.0625f, +-164.063f,32.3895f,39.0625f, +-160.156f,33.8224f,39.0625f, +-156.25f,34.3349f,39.0625f, +-152.344f,34.4661f,39.0625f, +-148.438f,34.7236f,39.0625f, +-144.531f,34.1129f,39.0625f, +-140.625f,34.9033f,39.0625f, +-136.719f,35.6229f,39.0625f, +-132.813f,35.7143f,39.0625f, +-128.906f,36.7151f,39.0625f, +-125.0f,36.9574f,39.0625f, +-121.094f,36.0729f,39.0625f, +-117.188f,35.2171f,39.0625f, +-113.281f,34.9343f,39.0625f, +-109.375f,34.5707f,39.0625f, +-105.469f,33.5046f,39.0625f, +-101.563f,31.353f,39.0625f, +-97.6563f,30.0283f,39.0625f, +-93.75f,28.6272f,39.0625f, +-89.8438f,26.4389f,39.0625f, +-85.9375f,24.8159f,39.0625f, +-82.0313f,23.0295f,39.0625f, +-78.125f,21.1082f,39.0625f, +-74.2188f,19.1239f,39.0625f, +-70.3125f,18.0914f,39.0625f, +-66.4063f,17.3227f,39.0625f, +-62.5f,17.1022f,39.0625f, +-58.5938f,16.4298f,39.0625f, +-54.6875f,15.6704f,39.0625f, +-50.7813f,16.5664f,39.0625f, +-46.875f,18.478f,39.0625f, +-42.9688f,19.4144f,39.0625f, +-39.0625f,19.9351f,39.0625f, +-35.1563f,20.3447f,39.0625f, +-31.25f,22.4348f,39.0625f, +-27.3438f,24.5713f,39.0625f, +-23.4375f,25.5465f,39.0625f, +-19.5313f,26.485f,39.0625f, +-15.625f,28.292f,39.0625f, +-11.7188f,30.0016f,39.0625f, +-7.8125f,32.2532f,39.0625f, +-3.90625f,33.6327f,39.0625f, +0.0f,33.835f,39.0625f, +3.90625f,34.9171f,39.0625f, +-250.0f,3.91889f,35.1563f, +-246.094f,3.38127f,35.1563f, +-242.188f,3.26935f,35.1563f, +-238.281f,4.06778f,35.1563f, +-234.375f,4.87411f,35.1563f, +-230.469f,6.48873f,35.1563f, +-226.563f,7.17326f,35.1563f, +-222.656f,8.21235f,35.1563f, +-218.75f,8.21965f,35.1563f, +-214.844f,10.417f,35.1563f, +-210.938f,11.9497f,35.1563f, +-207.031f,13.4145f,35.1563f, +-203.125f,14.0876f,35.1563f, +-199.219f,15.5077f,35.1563f, +-195.313f,16.9011f,35.1563f, +-191.406f,20.4395f,35.1563f, +-187.5f,23.001f,35.1563f, +-183.594f,24.0199f,35.1563f, +-179.688f,25.7082f,35.1563f, +-175.781f,27.3018f,35.1563f, +-171.875f,28.9584f,35.1563f, +-167.969f,31.1478f,35.1563f, +-164.063f,32.8635f,35.1563f, +-160.156f,33.5517f,35.1563f, +-156.25f,34.5761f,35.1563f, +-152.344f,34.5761f,35.1563f, +-148.438f,34.2002f,35.1563f, +-144.531f,34.7177f,35.1563f, +-140.625f,35.5653f,35.1563f, +-136.719f,35.7993f,35.1563f, +-132.813f,37.1127f,35.1563f, +-128.906f,37.2477f,35.1563f, +-125.0f,36.8734f,35.1563f, +-121.094f,35.4154f,35.1563f, +-117.188f,34.8545f,35.1563f, +-113.281f,35.4317f,35.1563f, +-109.375f,34.9205f,35.1563f, +-105.469f,33.5115f,35.1563f, +-101.563f,32.2368f,35.1563f, +-97.6563f,30.3601f,35.1563f, +-93.75f,29.2913f,35.1563f, +-89.8438f,27.4791f,35.1563f, +-85.9375f,24.811f,35.1563f, +-82.0313f,23.4984f,35.1563f, +-78.125f,21.456f,35.1563f, +-74.2188f,19.8992f,35.1563f, +-70.3125f,17.7354f,35.1563f, +-66.4063f,17.3066f,35.1563f, +-62.5f,17.1745f,35.1563f, +-58.5938f,16.5285f,35.1563f, +-54.6875f,17.2826f,35.1563f, +-50.7813f,18.6936f,35.1563f, +-46.875f,19.4228f,35.1563f, +-42.9688f,20.2022f,35.1563f, +-39.0625f,21.4261f,35.1563f, +-35.1563f,21.5779f,35.1563f, +-31.25f,24.0097f,35.1563f, +-27.3438f,25.4481f,35.1563f, +-23.4375f,26.0036f,35.1563f, +-19.5313f,27.4346f,35.1563f, +-15.625f,30.2459f,35.1563f, +-11.7188f,32.81f,35.1563f, +-7.8125f,34.7924f,35.1563f, +-3.90625f,35.8907f,35.1563f, +0.0f,36.9755f,35.1563f, +3.90625f,38.5427f,35.1563f, +-250.0f,2.28536f,31.25f, +-246.094f,1.63842f,31.25f, +-242.188f,2.40273f,31.25f, +-238.281f,3.19518f,31.25f, +-234.375f,3.99394f,31.25f, +-230.469f,4.99674f,31.25f, +-226.563f,5.63235f,31.25f, +-222.656f,6.86331f,31.25f, +-218.75f,7.37515f,31.25f, +-214.844f,9.34737f,31.25f, +-210.938f,11.7034f,31.25f, +-207.031f,13.4309f,31.25f, +-203.125f,14.4474f,31.25f, +-199.219f,15.8817f,31.25f, +-195.313f,17.87f,31.25f, +-191.406f,20.9938f,31.25f, +-187.5f,23.5333f,31.25f, +-183.594f,24.4107f,31.25f, +-179.688f,26.0811f,31.25f, +-175.781f,27.9797f,31.25f, +-171.875f,29.4813f,31.25f, +-167.969f,31.7071f,31.25f, +-164.063f,33.0836f,31.25f, +-160.156f,33.5998f,31.25f, +-156.25f,33.5304f,31.25f, +-152.344f,33.9929f,31.25f, +-148.438f,35.4297f,31.25f, +-144.531f,36.4531f,31.25f, +-140.625f,35.9197f,31.25f, +-136.719f,36.6849f,31.25f, +-132.813f,37.8161f,31.25f, +-128.906f,37.6166f,31.25f, +-125.0f,36.9426f,31.25f, +-121.094f,35.6388f,31.25f, +-117.188f,35.0026f,31.25f, +-113.281f,35.386f,31.25f, +-109.375f,34.6287f,31.25f, +-105.469f,33.8962f,31.25f, +-101.563f,32.1844f,31.25f, +-97.6563f,30.7868f,31.25f, +-93.75f,29.267f,31.25f, +-89.8438f,27.2585f,31.25f, +-85.9375f,25.4236f,31.25f, +-82.0313f,23.0281f,31.25f, +-78.125f,21.4593f,31.25f, +-74.2188f,19.4556f,31.25f, +-70.3125f,18.0982f,31.25f, +-66.4063f,17.1214f,31.25f, +-62.5f,17.1751f,31.25f, +-58.5938f,17.1429f,31.25f, +-54.6875f,18.4434f,31.25f, +-50.7813f,19.9422f,31.25f, +-46.875f,21.2124f,31.25f, +-42.9688f,21.2106f,31.25f, +-39.0625f,22.1346f,31.25f, +-35.1563f,23.3082f,31.25f, +-31.25f,24.7044f,31.25f, +-27.3438f,26.2688f,31.25f, +-23.4375f,27.5692f,31.25f, +-19.5313f,30.4099f,31.25f, +-15.625f,33.0453f,31.25f, +-11.7188f,34.9857f,31.25f, +-7.8125f,37.0727f,31.25f, +-3.90625f,39.2219f,31.25f, +0.0f,40.3658f,31.25f, +3.90625f,41.4381f,31.25f, +-250.0f,0.4773f,27.3438f, +-246.094f,0.631847f,27.3438f, +-242.188f,1.21449f,27.3438f, +-238.281f,1.52728f,27.3438f, +-234.375f,2.73146f,27.3438f, +-230.469f,3.65375f,27.3438f, +-226.563f,5.03467f,27.3438f, +-222.656f,6.27065f,27.3438f, +-218.75f,7.56964f,27.3438f, +-214.844f,9.63719f,27.3438f, +-210.938f,11.4022f,27.3438f, +-207.031f,12.7085f,27.3438f, +-203.125f,14.3808f,27.3438f, +-199.219f,15.9121f,27.3438f, +-195.313f,17.8953f,27.3438f, +-191.406f,20.8456f,27.3438f, +-187.5f,22.7705f,27.3438f, +-183.594f,24.5794f,27.3437f, +-179.688f,27.055f,27.3438f, +-175.781f,29.3548f,27.3437f, +-171.875f,30.4534f,27.3438f, +-167.969f,32.4366f,27.3437f, +-164.063f,34.4967f,27.3438f, +-160.156f,34.9614f,27.3437f, +-156.25f,34.9405f,27.3438f, +-152.344f,35.7165f,27.3437f, +-148.438f,37.0387f,27.3438f, +-144.531f,38.0934f,27.3437f, +-140.625f,37.3872f,27.3438f, +-136.719f,36.4336f,27.3437f, +-132.813f,37.0365f,27.3438f, +-128.906f,37.2591f,27.3437f, +-125.0f,36.5502f,27.3438f, +-121.094f,35.4814f,27.3437f, +-117.188f,35.3267f,27.3438f, +-113.281f,34.3757f,27.3437f, +-109.375f,34.2455f,27.3438f, +-105.469f,33.6851f,27.3437f, +-101.563f,32.3527f,27.3438f, +-97.6563f,30.111f,27.3437f, +-93.75f,28.4912f,27.3438f, +-89.8438f,27.0398f,27.3437f, +-85.9375f,24.9699f,27.3438f, +-82.0313f,22.9703f,27.3437f, +-78.125f,21.7502f,27.3438f, +-74.2188f,18.8537f,27.3438f, +-70.3125f,18.2353f,27.3438f, +-66.4063f,18.3708f,27.3438f, +-62.5f,18.6738f,27.3438f, +-58.5938f,18.5559f,27.3438f, +-54.6875f,19.1603f,27.3438f, +-50.7813f,20.8349f,27.3438f, +-46.875f,21.6092f,27.3438f, +-42.9688f,21.9317f,27.3437f, +-39.0625f,23.0486f,27.3438f, +-35.1563f,24.8675f,27.3437f, +-31.25f,25.6906f,27.3438f, +-27.3438f,27.9695f,27.3437f, +-23.4375f,30.3105f,27.3438f, +-19.5313f,33.9897f,27.3437f, +-15.625f,35.6988f,27.3438f, +-11.7188f,37.9213f,27.3437f, +-7.8125f,40.1355f,27.3438f, +-3.90625f,41.6062f,27.3437f, +0.0f,42.273f,27.3438f, +3.90625f,42.7334f,27.3437f, +-250.0f,0.178144f,23.4375f, +-246.094f,1.07943f,23.4375f, +-242.188f,1.52473f,23.4375f, +-238.281f,2.58652f,23.4375f, +-234.375f,3.51451f,23.4375f, +-230.469f,4.23103f,23.4375f, +-226.563f,5.80506f,23.4375f, +-222.656f,7.26086f,23.4375f, +-218.75f,8.85201f,23.4375f, +-214.844f,10.9029f,23.4375f, +-210.938f,12.7138f,23.4375f, +-207.031f,14.9249f,23.4375f, +-203.125f,15.6506f,23.4375f, +-199.219f,16.529f,23.4375f, +-195.313f,17.1535f,23.4375f, +-191.406f,20.5632f,23.4375f, +-187.5f,23.1009f,23.4375f, +-183.594f,24.7859f,23.4375f, +-179.688f,26.8635f,23.4375f, +-175.781f,28.5723f,23.4375f, +-171.875f,30.2918f,23.4375f, +-167.969f,32.7768f,23.4375f, +-164.063f,34.6199f,23.4375f, +-160.156f,35.6902f,23.4375f, +-156.25f,37.1166f,23.4375f, +-152.344f,37.0816f,23.4375f, +-148.438f,37.9995f,23.4375f, +-144.531f,38.687f,23.4375f, +-140.625f,37.9261f,23.4375f, +-136.719f,36.7476f,23.4375f, +-132.813f,37.1839f,23.4375f, +-128.906f,36.8682f,23.4375f, +-125.0f,36.2555f,23.4375f, +-121.094f,34.8461f,23.4375f, +-117.188f,34.5757f,23.4375f, +-113.281f,33.8965f,23.4375f, +-109.375f,33.4987f,23.4375f, +-105.469f,33.02f,23.4375f, +-101.563f,31.4543f,23.4375f, +-97.6563f,29.5899f,23.4375f, +-93.75f,27.8808f,23.4375f, +-89.8438f,26.4886f,23.4375f, +-85.9375f,24.5413f,23.4375f, +-82.0313f,22.6097f,23.4375f, +-78.125f,21.38f,23.4375f, +-74.2188f,19.2574f,23.4375f, +-70.3125f,19.6862f,23.4375f, +-66.4063f,19.3283f,23.4375f, +-62.5f,20.3608f,23.4375f, +-58.5938f,20.9969f,23.4375f, +-54.6875f,20.5645f,23.4375f, +-50.7813f,21.6338f,23.4375f, +-46.875f,22.0705f,23.4375f, +-42.9688f,23.2924f,23.4375f, +-39.0625f,24.8627f,23.4375f, +-35.1563f,25.9292f,23.4375f, +-31.25f,27.2133f,23.4375f, +-27.3438f,29.7296f,23.4375f, +-23.4375f,32.8149f,23.4375f, +-19.5313f,35.5321f,23.4375f, +-15.625f,38.2144f,23.4375f, +-11.7188f,40.2421f,23.4375f, +-7.8125f,41.7479f,23.4375f, +-3.90625f,43.372f,23.4375f, +0.0f,43.7526f,23.4375f, +3.90625f,44.6783f,23.4375f, +-250.0f,0.138221f,19.5313f, +-246.094f,1.4004f,19.5313f, +-242.188f,3.26515f,19.5313f, +-238.281f,3.65276f,19.5313f, +-234.375f,4.90602f,19.5313f, +-230.469f,6.03349f,19.5313f, +-226.563f,7.99773f,19.5313f, +-222.656f,9.41728f,19.5313f, +-218.75f,10.0435f,19.5313f, +-214.844f,12.1613f,19.5313f, +-210.938f,13.6999f,19.5313f, +-207.031f,15.7603f,19.5313f, +-203.125f,16.1549f,19.5313f, +-199.219f,17.1021f,19.5313f, +-195.313f,18.1867f,19.5313f, +-191.406f,20.6836f,19.5313f, +-187.5f,23.0865f,19.5312f, +-183.594f,24.3015f,19.5313f, +-179.688f,26.6623f,19.5312f, +-175.781f,28.232f,19.5313f, +-171.875f,30.6454f,19.5312f, +-167.969f,32.8674f,19.5313f, +-164.063f,35.0881f,19.5312f, +-160.156f,37.2715f,19.5313f, +-156.25f,38.6025f,19.5312f, +-152.344f,38.2781f,19.5313f, +-148.438f,38.4813f,19.5312f, +-144.531f,38.3281f,19.5313f, +-140.625f,38.1441f,19.5312f, +-136.719f,37.6066f,19.5312f, +-132.813f,37.2097f,19.5312f, +-128.906f,36.5694f,19.5312f, +-125.0f,36.2416f,19.5312f, +-121.094f,34.5305f,19.5312f, +-117.188f,33.3684f,19.5312f, +-113.281f,32.7805f,19.5312f, +-109.375f,31.8563f,19.5312f, +-105.469f,31.3398f,19.5312f, +-101.563f,29.7387f,19.5312f, +-97.6563f,28.7121f,19.5312f, +-93.75f,27.8904f,19.5312f, +-89.8438f,26.0256f,19.5312f, +-85.9375f,24.5469f,19.5312f, +-82.0313f,23.3531f,19.5312f, +-78.125f,21.4621f,19.5313f, +-74.2188f,20.3507f,19.5313f, +-70.3125f,20.1879f,19.5313f, +-66.4063f,20.9838f,19.5313f, +-62.5f,22.229f,19.5312f, +-58.5938f,22.355f,19.5312f, +-54.6875f,22.7659f,19.5312f, +-50.7813f,22.9258f,19.5312f, +-46.875f,23.554f,19.5312f, +-42.9688f,24.3861f,19.5312f, +-39.0625f,25.5112f,19.5312f, +-35.1563f,26.8691f,19.5312f, +-31.25f,28.968f,19.5312f, +-27.3438f,31.0124f,19.5312f, +-23.4375f,34.8357f,19.5312f, +-19.5313f,37.2362f,19.5312f, +-15.625f,39.5924f,19.5312f, +-11.7188f,41.5691f,19.5312f, +-7.8125f,43.2441f,19.5312f, +-3.90625f,45.1168f,19.5312f, +0.0f,45.7555f,19.5312f, +3.90625f,46.9055f,19.5312f, +-250.0f,0.462936f,15.625f, +-246.094f,2.15489f,15.625f, +-242.188f,3.69232f,15.625f, +-238.281f,4.89361f,15.625f, +-234.375f,6.95706f,15.625f, +-230.469f,8.37916f,15.625f, +-226.563f,9.21515f,15.625f, +-222.656f,10.0624f,15.625f, +-218.75f,11.6477f,15.625f, +-214.844f,13.257f,15.625f, +-210.938f,14.8699f,15.625f, +-207.031f,15.9852f,15.625f, +-203.125f,17.025f,15.625f, +-199.219f,17.8511f,15.625f, +-195.313f,20.3581f,15.625f, +-191.406f,22.0829f,15.625f, +-187.5f,24.4216f,15.625f, +-183.594f,25.5625f,15.625f, +-179.688f,27.0961f,15.625f, +-175.781f,30.0958f,15.625f, +-171.875f,31.7977f,15.625f, +-167.969f,34.7043f,15.625f, +-164.063f,37.1655f,15.625f, +-160.156f,37.6823f,15.625f, +-156.25f,37.6204f,15.625f, +-152.344f,37.8037f,15.625f, +-148.438f,37.8555f,15.625f, +-144.531f,37.9638f,15.625f, +-140.625f,37.4821f,15.625f, +-136.719f,37.0202f,15.625f, +-132.813f,36.4604f,15.625f, +-128.906f,36.1575f,15.625f, +-125.0f,35.4218f,15.625f, +-121.094f,33.5202f,15.625f, +-117.188f,32.116f,15.625f, +-113.281f,30.9352f,15.625f, +-109.375f,29.8297f,15.625f, +-105.469f,29.9146f,15.625f, +-101.563f,28.7245f,15.625f, +-97.6563f,27.7205f,15.625f, +-93.75f,27.4217f,15.625f, +-89.8438f,25.8557f,15.625f, +-85.9375f,24.0609f,15.625f, +-82.0313f,22.7869f,15.625f, +-78.125f,20.4923f,15.625f, +-74.2188f,21.0025f,15.625f, +-70.3125f,21.2985f,15.625f, +-66.4063f,22.5717f,15.625f, +-62.5f,23.0569f,15.625f, +-58.5938f,23.2123f,15.625f, +-54.6875f,24.1861f,15.625f, +-50.7813f,24.5626f,15.625f, +-46.875f,25.1259f,15.625f, +-42.9688f,25.9995f,15.625f, +-39.0625f,26.8682f,15.625f, +-35.1563f,27.8593f,15.625f, +-31.25f,29.8924f,15.625f, +-27.3438f,32.8894f,15.625f, +-23.4375f,36.2901f,15.625f, +-19.5313f,38.2475f,15.625f, +-15.625f,40.593f,15.625f, +-11.7188f,42.2973f,15.625f, +-7.8125f,45.3308f,15.625f, +-3.90625f,47.345f,15.625f, +0.0f,48.9808f,15.625f, +3.90625f,49.2295f,15.625f, +-250.0f,1.16646f,11.7188f, +-246.094f,2.99331f,11.7188f, +-242.188f,4.37829f,11.7188f, +-238.281f,5.21593f,11.7188f, +-234.375f,6.84374f,11.7188f, +-230.469f,8.34616f,11.7188f, +-226.563f,9.2826f,11.7188f, +-222.656f,9.90104f,11.7188f, +-218.75f,10.9211f,11.7187f, +-214.844f,13.6881f,11.7187f, +-210.938f,15.7745f,11.7187f, +-207.031f,16.2325f,11.7187f, +-203.125f,17.2525f,11.7187f, +-199.219f,19.1108f,11.7187f, +-195.313f,21.4743f,11.7187f, +-191.406f,24.021f,11.7187f, +-187.5f,25.8676f,11.7187f, +-183.594f,27.021f,11.7187f, +-179.688f,28.254f,11.7187f, +-175.781f,31.6036f,11.7187f, +-171.875f,32.629f,11.7187f, +-167.969f,34.9526f,11.7187f, +-164.063f,36.8236f,11.7187f, +-160.156f,37.152f,11.7187f, +-156.25f,37.6659f,11.7187f, +-152.344f,37.4102f,11.7187f, +-148.438f,37.0806f,11.7187f, +-144.531f,37.6299f,11.7187f, +-140.625f,36.7269f,11.7187f, +-136.719f,36.4841f,11.7187f, +-132.813f,35.2557f,11.7187f, +-128.906f,34.7066f,11.7187f, +-125.0f,34.0947f,11.7187f, +-121.094f,32.7343f,11.7187f, +-117.188f,31.5605f,11.7187f, +-113.281f,30.7492f,11.7187f, +-109.375f,30.1608f,11.7187f, +-105.469f,29.9144f,11.7187f, +-101.563f,28.5532f,11.7187f, +-97.6563f,26.2051f,11.7187f, +-93.75f,26.0432f,11.7187f, +-89.8438f,25.1831f,11.7187f, +-85.9375f,23.7935f,11.7187f, +-82.0313f,22.6952f,11.7187f, +-78.125f,21.9812f,11.7187f, +-74.2188f,22.3423f,11.7187f, +-70.3125f,22.4959f,11.7187f, +-66.4063f,22.9438f,11.7187f, +-62.5f,23.6591f,11.7187f, +-58.5938f,24.1634f,11.7187f, +-54.6875f,24.8781f,11.7187f, +-50.7813f,25.3471f,11.7187f, +-46.875f,25.7599f,11.7187f, +-42.9688f,26.61f,11.7187f, +-39.0625f,27.5033f,11.7187f, +-35.1563f,29.2751f,11.7187f, +-31.25f,31.9147f,11.7187f, +-27.3438f,34.1964f,11.7187f, +-23.4375f,36.7734f,11.7187f, +-19.5313f,39.2441f,11.7187f, +-15.625f,41.3269f,11.7187f, +-11.7188f,44.2682f,11.7187f, +-7.8125f,47.2458f,11.7187f, +-3.90625f,49.2199f,11.7187f, +0.0f,50.2546f,11.7187f, +3.90625f,51.1233f,11.7187f, +-250.0f,1.52698f,7.8125f, +-246.094f,2.97227f,7.8125f, +-242.188f,3.77319f,7.8125f, +-238.281f,4.81095f,7.8125f, +-234.375f,5.94458f,7.8125f, +-230.469f,7.45352f,7.8125f, +-226.563f,8.9683f,7.8125f, +-222.656f,9.37348f,7.8125f, +-218.75f,10.3818f,7.8125f, +-214.844f,13.0632f,7.8125f, +-210.938f,15.5836f,7.8125f, +-207.031f,17.1532f,7.8125f, +-203.125f,19.3065f,7.8125f, +-199.219f,21.746f,7.8125f, +-195.313f,23.0026f,7.8125f, +-191.406f,25.1876f,7.8125f, +-187.5f,27.4911f,7.8125f, +-183.594f,28.651f,7.8125f, +-179.688f,28.9685f,7.8125f, +-175.781f,31.1275f,7.8125f, +-171.875f,32.457f,7.8125f, +-167.969f,34.4336f,7.8125f, +-164.063f,35.9124f,7.8125f, +-160.156f,36.5078f,7.8125f, +-156.25f,36.9999f,7.8125f, +-152.344f,36.9517f,7.8125f, +-148.438f,37.9713f,7.8125f, +-144.531f,37.929f,7.8125f, +-140.625f,37.5334f,7.8125f, +-136.719f,36.2798f,7.8125f, +-132.813f,35.1904f,7.8125f, +-128.906f,33.7356f,7.8125f, +-125.0f,34.0968f,7.8125f, +-121.094f,33.5838f,7.8125f, +-117.188f,32.9371f,7.8125f, +-113.281f,32.0353f,7.8125f, +-109.375f,31.4623f,7.8125f, +-105.469f,30.5184f,7.8125f, +-101.563f,28.7396f,7.8125f, +-97.6563f,27.2715f,7.8125f, +-93.75f,26.1242f,7.8125f, +-89.8438f,24.5691f,7.8125f, +-85.9375f,23.931f,7.8125f, +-82.0313f,23.7643f,7.8125f, +-78.125f,22.4588f,7.8125f, +-74.2188f,22.5395f,7.8125f, +-70.3125f,22.9322f,7.8125f, +-66.4063f,23.4361f,7.8125f, +-62.5f,24.2733f,7.8125f, +-58.5938f,24.1873f,7.8125f, +-54.6875f,24.2666f,7.8125f, +-50.7813f,25.2522f,7.8125f, +-46.875f,26.3494f,7.8125f, +-42.9688f,26.8365f,7.8125f, +-39.0625f,27.5515f,7.8125f, +-35.1563f,30.4441f,7.8125f, +-31.25f,33.5547f,7.8125f, +-27.3438f,36.1409f,7.8125f, +-23.4375f,38.1103f,7.8125f, +-19.5313f,39.8171f,7.8125f, +-15.625f,42.1146f,7.8125f, +-11.7188f,45.3603f,7.8125f, +-7.8125f,47.6602f,7.8125f, +-3.90625f,49.963f,7.8125f, +0.0f,51.8119f,7.8125f, +3.90625f,52.2527f,7.8125f, +-250.0f,0.139875f,3.90625f, +-246.094f,1.72995f,3.90625f, +-242.188f,2.60122f,3.90625f, +-238.281f,4.01346f,3.90625f, +-234.375f,5.13654f,3.90625f, +-230.469f,6.69665f,3.90625f, +-226.563f,8.43203f,3.90625f, +-222.656f,9.83442f,3.90625f, +-218.75f,11.3645f,3.90625f, +-214.844f,14.222f,3.90625f, +-210.938f,16.1758f,3.90625f, +-207.031f,18.9127f,3.90625f, +-203.125f,21.2478f,3.90625f, +-199.219f,23.0589f,3.90625f, +-195.313f,24.6025f,3.90625f, +-191.406f,25.8143f,3.90625f, +-187.5f,27.5696f,3.90625f, +-183.594f,29.2176f,3.90625f, +-179.688f,29.6835f,3.90625f, +-175.781f,30.7416f,3.90625f, +-171.875f,31.4405f,3.90625f, +-167.969f,33.0831f,3.90625f, +-164.063f,34.6225f,3.90625f, +-160.156f,35.4992f,3.90625f, +-156.25f,37.4126f,3.90625f, +-152.344f,38.453f,3.90625f, +-148.438f,38.9974f,3.90625f, +-144.531f,38.7871f,3.90625f, +-140.625f,37.6021f,3.90625f, +-136.719f,36.1797f,3.90625f, +-132.813f,34.9906f,3.90625f, +-128.906f,34.1304f,3.90625f, +-125.0f,34.3517f,3.90625f, +-121.094f,33.6612f,3.90625f, +-117.188f,32.7047f,3.90625f, +-113.281f,32.3958f,3.90625f, +-109.375f,31.0818f,3.90625f, +-105.469f,30.9536f,3.90625f, +-101.563f,29.8205f,3.90625f, +-97.6563f,28.4796f,3.90625f, +-93.75f,27.6494f,3.90625f, +-89.8438f,25.5721f,3.90625f, +-85.9375f,24.227f,3.90625f, +-82.0313f,23.2611f,3.90625f, +-78.125f,22.4589f,3.90625f, +-74.2188f,23.2261f,3.90625f, +-70.3125f,23.5025f,3.90625f, +-66.4063f,23.6913f,3.90625f, +-62.5f,24.6785f,3.90625f, +-58.5938f,25.4946f,3.90625f, +-54.6875f,25.9722f,3.90625f, +-50.7813f,26.1977f,3.90625f, +-46.875f,26.8539f,3.90625f, +-42.9688f,27.7268f,3.90625f, +-39.0625f,29.2046f,3.90625f, +-35.1563f,31.79f,3.90625f, +-31.25f,34.2658f,3.90625f, +-27.3438f,35.9914f,3.90625f, +-23.4375f,38.3776f,3.90625f, +-19.5313f,39.8852f,3.90625f, +-15.625f,43.1455f,3.90625f, +-11.7188f,45.5059f,3.90625f, +-7.8125f,47.4257f,3.90625f, +-3.90625f,49.9032f,3.90625f, +0.0f,52.0322f,3.90625f, +3.90625f,52.6186f,3.90625f, +}; + +btScalar Landscape02Nml[] = { +0.376889f,0.897995f,0.227068f, +0.251083f,0.961355f,0.112931f, +0.256071f,0.961946f,0.0953332f, +0.188246f,0.981544f,0.0336933f, +0.321782f,0.946812f,0.00191405f, +0.277829f,0.960055f,0.0332431f, +0.366908f,0.922321f,-0.121252f, +0.346681f,0.936118f,-0.0591191f, +0.34598f,0.936023f,-0.0644918f, +0.326882f,0.934733f,-0.139364f, +0.195537f,0.979014f,-0.0574119f, +0.208421f,0.974173f,-0.0868766f, +0.220158f,0.96963f,-0.106528f, +0.21764f,0.974169f,-0.0602246f, +0.194781f,0.966032f,-0.169831f, +0.137923f,0.97923f,-0.148611f, +-0.0890295f,0.968844f,-0.231118f, +-0.164208f,0.952108f,-0.257926f, +-0.299547f,0.905883f,-0.299413f, +-0.331781f,0.892916f,-0.304338f, +-0.275234f,0.921181f,-0.275086f, +-0.190055f,0.968186f,-0.162776f, +-0.191147f,0.964101f,-0.184313f, +-0.167051f,0.973656f,-0.155201f, +-0.260549f,0.956867f,-0.128527f, +-0.236175f,0.968373f,-0.080466f, +-0.305083f,0.942279f,-0.137969f, +-0.32302f,0.940678f,-0.103844f, +-0.376654f,0.91108f,-0.167524f, +-0.43665f,0.882087f,-0.176802f, +-0.404697f,0.87224f,-0.274621f, +-0.461396f,0.842558f,-0.277868f, +-0.340534f,0.861872f,-0.375783f, +-0.381498f,0.847049f,-0.370091f, +-0.349262f,0.83292f,-0.429255f, +-0.383821f,0.842401f,-0.378209f, +-0.350717f,0.827302f,-0.438826f, +-0.312636f,0.886963f,-0.339934f, +-0.202637f,0.921293f,-0.331899f, +-0.164853f,0.917655f,-0.361571f, +-0.320762f,0.929092f,-0.184116f, +-0.291289f,0.89543f,-0.336684f, +-0.523923f,0.850919f,-0.0379686f, +-0.415222f,0.907809f,-0.0589323f, +-0.464751f,0.884928f,0.030152f, +-0.464228f,0.885715f,0.00114487f, +-0.460666f,0.887573f,-0.00119475f, +-0.527574f,0.824073f,-0.206324f, +-0.569463f,0.819886f,-0.0591577f, +-0.624043f,0.739025f,-0.253797f, +-0.677912f,0.708815f,-0.19498f, +-0.654991f,0.737431f,-0.164874f, +-0.612102f,0.778841f,-0.136883f, +-0.555251f,0.829082f,-0.0657209f, +-0.466796f,0.884362f,-0.00238444f, +-0.393172f,0.917844f,0.0545768f, +-0.415266f,0.902781f,0.111985f, +-0.346174f,0.92512f,0.155936f, +-0.270143f,0.942251f,0.197955f, +-0.242693f,0.931939f,0.269424f, +-0.146828f,0.979561f,0.137484f, +-0.151815f,0.949716f,0.273847f, +-0.23746f,0.962635f,0.130183f, +-0.242269f,0.936807f,0.252385f, +-0.439066f,0.897439f,0.0427119f, +-0.506925f,0.859633f,0.0637107f, +-0.369534f,0.927612f,0.0545955f, +-0.266432f,0.921234f,0.283447f, +-0.0849634f,0.983229f,0.161377f, +-0.142422f,0.97399f,0.176238f, +0.059987f,0.992193f,0.109333f, +-0.00609097f,0.990503f,0.137353f, +0.218751f,0.975042f,-0.0379662f, +0.195675f,0.973574f,0.117747f, +0.412438f,0.903178f,-0.119012f, +0.389829f,0.920771f,0.01463f, +0.471887f,0.878868f,-0.0700914f, +0.512637f,0.843878f,0.158344f, +0.438398f,0.898776f,-0.0028899f, +0.463505f,0.872879f,0.152466f, +0.213581f,0.96879f,0.125817f, +0.217949f,0.966902f,0.132661f, +0.150053f,0.978231f,0.143348f, +0.183142f,0.954792f,0.234161f, +0.324547f,0.937949f,0.122152f, +0.305949f,0.944044f,0.123194f, +0.404781f,0.90011f,0.161105f, +0.386685f,0.917163f,0.0963685f, +0.43511f,0.894378f,0.103764f, +0.444378f,0.884165f,0.144156f, +0.485066f,0.871945f,0.0665013f, +0.480511f,0.864609f,0.146835f, +0.542329f,0.83784f,0.0624783f, +0.538258f,0.834152f,0.120286f, +0.497652f,0.86488f,0.0657686f, +0.471897f,0.881288f,0.0253797f, +0.368509f,0.927548f,0.0620863f, +0.391828f,0.918428f,0.0544149f, +0.284879f,0.953389f,0.0994662f, +0.359932f,0.902669f,0.235877f, +0.19297f,0.969614f,0.150374f, +0.198191f,0.923716f,0.327825f, +0.174784f,0.978101f,0.113003f, +0.121688f,0.95783f,0.260297f, +0.3291f,0.939598f,0.094074f, +0.241925f,0.967997f,0.066744f, +0.275982f,0.959352f,0.0589789f, +0.207349f,0.969048f,-0.133986f, +-0.048418f,0.997403f,0.0533214f, +-0.0214229f,0.995947f,-0.0873486f, +-0.224808f,0.97209f,0.0671032f, +-0.154526f,0.98721f,0.0392114f, +-0.0539424f,0.990401f,0.127262f, +0.0294265f,0.986864f,0.158851f, +0.115045f,0.967726f,0.224212f, +0.135755f,0.967813f,0.211917f, +-0.0987201f,0.976534f,0.191406f, +-0.208734f,0.974954f,0.0767793f, +-0.346094f,0.938088f,0.0144628f, +-0.364883f,0.930977f,0.0119327f, +-0.234075f,0.972082f,0.0162811f, +-0.216489f,0.973875f,0.0685516f, +-0.126585f,0.991898f,0.0107448f, +-0.188432f,0.981937f,-0.0171439f, +-0.186728f,0.980312f,-0.0641921f, +-0.243763f,0.959118f,-0.14378f, +-0.256453f,0.962392f,-0.0896326f, +-0.227009f,0.972481f,-0.0524148f, +-0.308642f,0.945388f,-0.104794f, +-0.322884f,0.94242f,-0.0871231f, +-0.32494f,0.940988f,-0.0946312f, +-0.365791f,0.920972f,-0.134189f, +0.507209f,0.830952f,0.228598f, +0.427157f,0.893788f,0.136676f, +0.390358f,0.920644f,0.00595094f, +0.357f,0.931227f,0.0732586f, +0.253669f,0.95455f,0.156478f, +0.247974f,0.954291f,0.166849f, +0.303694f,0.950352f,0.0678299f, +0.260247f,0.965246f,0.0238949f, +-0.0615746f,0.996768f,-0.0515863f, +-0.225111f,0.970921f,-0.0814727f, +-0.33579f,0.924057f,-0.18266f, +-0.286567f,0.949099f,-0.13073f, +-0.266283f,0.957101f,-0.114241f, +-0.297972f,0.942451f,-0.151651f, +-0.345158f,0.930403f,-0.123358f, +-0.323606f,0.933615f,-0.153759f, +-0.295216f,0.935234f,-0.195409f, +-0.294262f,0.935546f,-0.195355f, +-0.367877f,0.896699f,-0.246165f, +-0.460611f,0.856308f,-0.233612f, +-0.493615f,0.869663f,0.00556421f, +-0.56572f,0.819247f,0.0937815f, +-0.482796f,0.868728f,0.110547f, +-0.473443f,0.870107f,0.136985f, +-0.486628f,0.863931f,0.12968f, +-0.584612f,0.809918f,-0.0475519f, +-0.673803f,0.720247f,-0.165027f, +-0.584438f,0.811258f,-0.0171189f, +-0.49626f,0.855798f,0.146063f, +-0.266763f,0.927018f,0.26358f, +-0.000318467f,0.974136f,0.225963f, +-0.2098f,0.977621f,0.015525f, +-0.363964f,0.929076f,-0.0659462f, +-0.427799f,0.890708f,-0.153708f, +-0.226888f,0.973494f,-0.0288381f, +0.176474f,0.981f,0.080593f, +0.382766f,0.920418f,-0.0794987f, +0.4558f,0.874041f,-0.16822f, +0.44168f,0.87342f,-0.205075f, +0.269141f,0.944688f,-0.187422f, +0.0983269f,0.994746f,0.0285051f, +0.164874f,0.980231f,0.10938f, +0.300398f,0.949423f,0.0914149f, +0.370498f,0.925363f,0.0802133f, +0.51325f,0.857062f,0.0449297f, +0.515688f,0.85628f,-0.0291725f, +0.532902f,0.845818f,-0.0246416f, +0.470584f,0.882352f,0.00224652f, +0.358364f,0.932053f,0.0534101f, +0.299916f,0.948938f,0.0978121f, +0.234125f,0.96956f,0.0716857f, +0.201429f,0.97943f,0.0119968f, +0.257021f,0.965839f,0.0330825f, +0.205585f,0.966488f,0.153741f, +-0.0291083f,0.972977f,0.22906f, +-0.183781f,0.97216f,0.145362f, +-0.0880966f,0.991634f,0.0943445f, +0.0404056f,0.991359f,0.124796f, +-0.0259416f,0.986408f,0.162256f, +-0.213262f,0.97241f,0.0945471f, +-0.221976f,0.974645f,0.0281856f, +-0.137418f,0.990413f,0.014064f, +-0.147111f,0.988464f,0.0360112f, +-0.213681f,0.97687f,0.00813376f, +-0.286716f,0.957516f,-0.0309366f, +-0.362687f,0.929548f,-0.0663186f, +0.471826f,0.881687f,0.00273101f, +0.493844f,0.862721f,0.108764f, +0.305852f,0.940961f,0.145073f, +0.225186f,0.91763f,0.327484f, +0.255894f,0.905552f,0.33837f, +0.302798f,0.922674f,0.238719f, +0.353759f,0.914443f,0.196594f, +0.301669f,0.941039f,0.153105f, +0.00675732f,0.993813f,0.110864f, +-0.180673f,0.978312f,0.101302f, +-0.247784f,0.966857f,0.0615767f, +-0.309703f,0.949482f,-0.0506691f, +-0.243038f,0.969623f,-0.0276337f, +-0.257234f,0.966017f,-0.0253295f, +-0.381367f,0.920413f,-0.0860151f, +-0.354157f,0.93479f,-0.027217f, +-0.299485f,0.952671f,0.0522246f, +-0.356888f,0.9323f,0.0587106f, +-0.335176f,0.924244f,0.182839f, +-0.500593f,0.855036f,0.135351f, +-0.576428f,0.801243f,0.160441f, +-0.583679f,0.788168f,0.195218f, +-0.491918f,0.829821f,0.263465f, +-0.431671f,0.862042f,0.2656f, +-0.443518f,0.883408f,0.151265f, +-0.464317f,0.881859f,0.0820666f, +-0.652068f,0.753609f,-0.0829502f, +-0.681939f,0.728217f,-0.068254f, +-0.591161f,0.804152f,0.0621953f, +-0.352647f,0.921747f,0.161318f, +0.0545396f,0.95959f,0.276065f, +0.0694942f,0.971972f,0.224591f, +-0.253858f,0.964902f,-0.0672354f, +-0.408551f,0.900688f,-0.147807f, +-0.327666f,0.933936f,-0.142825f, +0.129878f,0.985787f,-0.106564f, +0.442239f,0.89421f,-0.0693695f, +0.506959f,0.860716f,-0.0464834f, +0.440087f,0.895465f,-0.0668225f, +0.226441f,0.974021f,0.00265329f, +-0.0272959f,0.999596f,0.00787303f, +0.0903893f,0.995643f,0.0228958f, +0.359925f,0.931179f,0.0579615f, +0.431266f,0.899788f,-0.0662666f, +0.53735f,0.839722f,-0.0782406f, +0.525898f,0.846474f,-0.0831443f, +0.503404f,0.859213f,-0.0913118f, +0.450901f,0.892319f,-0.0213084f, +0.278054f,0.959353f,0.048252f, +0.254295f,0.953824f,0.159853f, +0.246692f,0.953779f,0.171608f, +0.237766f,0.960301f,0.145908f, +0.249319f,0.965473f,0.0755121f, +0.140552f,0.989905f,0.0182753f, +-0.0589195f,0.996842f,0.0532477f, +-0.101426f,0.988847f,0.109061f, +-0.043669f,0.99706f,0.0629708f, +0.0474685f,0.998853f,-0.0063145f, +-0.0867729f,0.996136f,-0.0135299f, +-0.196161f,0.972844f,0.12286f, +-0.192413f,0.974994f,0.111196f, +-0.123107f,0.990318f,0.0641543f, +-0.164426f,0.985628f,0.0387435f, +-0.213922f,0.974633f,0.0657922f, +-0.241049f,0.968373f,0.0644173f, +-0.307154f,0.951627f,-0.00792363f, +0.280771f,0.958227f,-0.0544817f, +0.299035f,0.949091f,0.0990176f, +0.225174f,0.937279f,0.266091f, +0.201765f,0.945847f,0.254291f, +0.341377f,0.920786f,0.18872f, +0.3743f,0.913661f,0.158502f, +0.359138f,0.923211f,0.136755f, +0.36518f,0.919296f,0.146759f, +0.0046348f,0.996002f,0.0892048f, +-0.241229f,0.954179f,0.177061f, +-0.158349f,0.951157f,0.265002f, +-0.207545f,0.971279f,0.116375f, +-0.289845f,0.957072f,0.00156201f, +-0.257416f,0.96626f,0.00885102f, +-0.326801f,0.944936f,0.0172234f, +-0.439204f,0.898379f,-0.00377194f, +-0.336537f,0.936282f,0.100589f, +-0.407285f,0.907139f,0.105914f, +-0.44858f,0.865076f,0.224543f, +-0.454994f,0.838311f,0.300358f, +-0.578424f,0.785375f,0.220483f, +-0.613986f,0.761879f,0.206302f, +-0.509143f,0.819763f,0.262226f, +-0.364105f,0.879908f,0.30527f, +-0.344494f,0.905138f,0.249097f, +-0.369295f,0.913195f,0.172323f, +-0.574832f,0.817482f,0.0359178f, +-0.689125f,0.724332f,-0.0212343f, +-0.619919f,0.781232f,-0.0733212f, +-0.441345f,0.892835f,-0.0897783f, +-0.0649595f,0.996915f,0.0440505f, +0.146397f,0.977716f,0.150467f, +-0.0177868f,0.998167f,0.0578468f, +-0.37006f,0.91802f,-0.14246f, +-0.30849f,0.937533f,-0.160828f, +0.107382f,0.980696f,-0.163415f, +0.392635f,0.914926f,-0.093533f, +0.501877f,0.862749f,-0.0615151f, +0.381618f,0.912204f,-0.14917f, +0.160415f,0.986769f,-0.0235493f, +0.0253729f,0.99703f,0.0727145f, +0.144484f,0.989507f,0.000443305f, +0.379228f,0.922372f,-0.073601f, +0.493599f,0.867009f,-0.0682314f, +0.529895f,0.842151f,-0.099967f, +0.549367f,0.821638f,-0.152008f, +0.439412f,0.876451f,-0.196851f, +0.349224f,0.935858f,0.0470259f, +0.182079f,0.971589f,0.151205f, +0.194383f,0.962201f,0.190749f, +0.266182f,0.94835f,0.172569f, +0.284034f,0.949535f,0.133071f, +0.347472f,0.93345f,0.089069f, +0.226103f,0.974059f,0.00925465f, +-0.0773561f,0.993257f,-0.0863519f, +-0.200366f,0.974099f,-0.104811f, +-0.00292133f,0.99995f,-0.00953497f, +0.144264f,0.988303f,-0.0494442f, +-0.155865f,0.979469f,-0.127857f, +-0.286146f,0.957784f,-0.0277406f, +-0.165259f,0.985103f,-0.0475661f, +-0.069504f,0.996782f,-0.0399387f, +-0.139315f,0.988254f,-0.0628056f, +-0.230813f,0.967463f,-0.103639f, +-0.24543f,0.966984f,-0.0686046f, +-0.189537f,0.981091f,0.0391957f, +0.151487f,0.988375f,0.0128779f, +0.16936f,0.984329f,0.0491336f, +0.218781f,0.968894f,0.115672f, +0.279098f,0.952669f,0.120523f, +0.344688f,0.931221f,0.118397f, +0.359727f,0.914297f,0.186165f, +0.326371f,0.918389f,0.223703f, +0.361839f,0.886899f,0.287197f, +-0.000924981f,0.965442f,0.260617f, +-0.321168f,0.914653f,0.24548f, +-0.23578f,0.933549f,0.269988f, +-0.0519805f,0.910912f,0.409313f, +-0.120702f,0.947306f,0.296721f, +-0.257649f,0.956241f,0.138637f, +-0.340179f,0.924947f,0.169564f, +-0.415425f,0.90289f,0.110507f, +-0.41038f,0.91038f,0.0528755f, +-0.447459f,0.881081f,0.153222f, +-0.521314f,0.820871f,0.233245f, +-0.470597f,0.83806f,0.27603f, +-0.530303f,0.820989f,0.211554f, +-0.59428f,0.795918f,0.11552f, +-0.564828f,0.823165f,0.0580397f, +-0.435129f,0.882511f,0.17843f, +-0.320859f,0.891866f,0.318787f, +-0.272192f,0.902535f,0.33368f, +-0.476067f,0.856837f,0.197967f, +-0.671403f,0.739101f,0.0543033f, +-0.548598f,0.834125f,0.0572312f, +-0.459373f,0.883769f,-0.0890421f, +-0.194341f,0.977153f,-0.0860449f, +0.0638196f,0.997784f,0.0188364f, +0.119241f,0.989813f,0.0777976f, +-0.189205f,0.978439f,-0.0828203f, +-0.328042f,0.913868f,-0.239234f, +0.0439005f,0.976566f,-0.210694f, +0.345392f,0.929362f,-0.130351f, +0.531991f,0.841029f,-0.0982628f, +0.385958f,0.912021f,-0.13876f, +0.00996624f,0.998173f,-0.059598f, +-0.0397997f,0.999182f,0.00710574f, +0.22423f,0.974041f,-0.0310806f, +0.399529f,0.909843f,-0.112084f, +0.472825f,0.876316f,-0.0922302f, +0.567959f,0.818431f,-0.0871407f, +0.591097f,0.802347f,-0.0827227f, +0.294969f,0.954774f,-0.0374031f, +0.136562f,0.986139f,0.0942395f, +0.140836f,0.978895f,0.148089f, +0.208743f,0.962024f,0.175889f, +0.331657f,0.931412f,0.149918f, +0.32318f,0.945148f,0.0474422f, +0.378499f,0.925602f,0.000447487f, +0.240237f,0.969087f,-0.0561752f, +0.0676245f,0.996927f,-0.0395359f, +-0.154966f,0.962822f,-0.221268f, +-0.087338f,0.971663f,-0.219642f, +0.144581f,0.983839f,-0.105631f, +-0.0884322f,0.993076f,-0.0773351f, +-0.293638f,0.94457f,-0.146848f, +-0.135408f,0.983934f,-0.116358f, +-0.103543f,0.987494f,-0.11889f, +-0.104597f,0.98248f,-0.15425f, +-0.176622f,0.962045f,-0.208023f, +-0.325467f,0.923065f,-0.204992f, +-0.403927f,0.903415f,-0.143824f, +0.344389f,0.929213f,0.134014f, +0.233815f,0.972165f,0.0150206f, +0.162621f,0.985815f,-0.0415186f, +0.195602f,0.980526f,0.0175561f, +0.28987f,0.950331f,0.113346f, +0.255987f,0.942074f,0.216718f, +0.263495f,0.890351f,0.371275f, +0.315069f,0.864416f,0.391812f, +0.0646003f,0.916859f,0.39395f, +-0.213657f,0.9234f,0.318877f, +-0.307635f,0.926495f,0.216719f, +-0.201977f,0.923807f,0.325246f, +-0.0210673f,0.916391f,0.399731f, +-0.17042f,0.919713f,0.353674f, +-0.316748f,0.899919f,0.299695f, +-0.294061f,0.92391f,0.244781f, +-0.396636f,0.905857f,0.14867f, +-0.523471f,0.83043f,0.190696f, +-0.568887f,0.791598f,0.223024f, +-0.446362f,0.844948f,0.294659f, +-0.453253f,0.853996f,0.255447f, +-0.541011f,0.824142f,0.167623f, +-0.550736f,0.81694f,0.171169f, +-0.53915f,0.819657f,0.193597f, +-0.444412f,0.862352f,0.242584f, +-0.285315f,0.907749f,0.30755f, +-0.329395f,0.886574f,0.324786f, +-0.610599f,0.78547f,0.101022f, +-0.543486f,0.838015f,0.0485148f, +-0.319704f,0.945394f,0.0634074f, +-0.262212f,0.963421f,-0.055354f, +0.000253525f,0.995852f,0.0909893f, +0.105619f,0.991464f,0.0764441f, +0.0245363f,0.999682f,-0.00586488f, +-0.22917f,0.926966f,-0.29701f, +-0.0159754f,0.943632f,-0.33061f, +0.309925f,0.920539f,-0.237812f, +0.48714f,0.850311f,-0.199165f, +0.288684f,0.955866f,-0.0546085f, +-0.0787222f,0.994967f,0.0619939f, +0.0273777f,0.99772f,0.0616831f, +0.291481f,0.955243f,-0.0505022f, +0.438727f,0.89664f,-0.0596253f, +0.485213f,0.871546f,-0.0705428f, +0.5406f,0.839608f,-0.0530067f, +0.49511f,0.866937f,0.0573254f, +0.280189f,0.947413f,0.154605f, +0.158816f,0.979113f,0.126949f, +0.168625f,0.983554f,0.0647105f, +0.187616f,0.98216f,0.0127302f, +0.334023f,0.942557f,0.00379923f, +0.401318f,0.914355f,0.0538517f, +0.424638f,0.905172f,0.0185914f, +0.289448f,0.956081f,-0.0461475f, +0.0899479f,0.980871f,-0.172633f, +-0.00560791f,0.970967f,-0.23915f, +-0.153691f,0.938842f,-0.308149f, +-0.0450622f,0.984719f,-0.168219f, +-0.0818032f,0.994271f,0.0687937f, +-0.254478f,0.967062f,-0.0056871f, +-0.190127f,0.974114f,-0.122284f, +-0.0615121f,0.986397f,-0.152435f, +-0.0478084f,0.984317f,-0.169808f, +-0.157882f,0.979732f,-0.123284f, +-0.307356f,0.93941f,-0.151791f, +-0.432596f,0.869844f,-0.237133f, +0.35469f,0.923204f,0.147951f, +0.317903f,0.938384f,0.135547f, +0.209784f,0.976723f,0.0447562f, +0.188401f,0.980806f,-0.0502544f, +0.153267f,0.987748f,-0.0293859f, +0.102074f,0.966336f,0.236167f, +0.128463f,0.933972f,0.333456f, +0.308207f,0.882627f,0.354934f, +0.141883f,0.91146f,0.386148f, +-0.174863f,0.945456f,0.274837f, +-0.248524f,0.937312f,0.244299f, +-0.268339f,0.945888f,0.182456f, +-0.0843285f,0.960488f,0.265238f, +-0.151825f,0.934815f,0.321045f, +-0.286064f,0.900967f,0.326231f, +-0.240679f,0.904695f,0.351568f, +-0.362345f,0.88785f,0.2836f, +-0.538142f,0.813225f,0.221511f, +-0.57294f,0.797677f,0.188284f, +-0.51091f,0.838129f,0.191079f, +-0.412611f,0.865658f,0.283528f, +-0.528395f,0.821979f,0.212483f, +-0.579097f,0.792111f,0.192891f, +-0.502268f,0.843036f,0.192398f, +-0.402738f,0.896524f,0.184518f, +-0.323371f,0.930281f,0.173231f, +-0.341027f,0.92193f,0.183699f, +-0.49586f,0.861123f,0.112209f, +-0.562176f,0.82675f,-0.0210484f, +-0.29935f,0.952705f,0.0523715f, +-0.273263f,0.96182f,0.0151701f, +-0.127856f,0.984802f,0.117552f, +0.16681f,0.967622f,0.189425f, +0.219885f,0.966852f,0.1298f, +0.0444925f,0.994595f,-0.093817f, +-0.0559771f,0.948894f,-0.31059f, +0.229668f,0.93439f,-0.272337f, +0.391338f,0.907289f,-0.153889f, +0.215699f,0.975228f,0.0490428f, +-0.1202f,0.992098f,0.0359644f, +0.0568932f,0.997098f,0.0505773f, +0.369571f,0.928802f,0.0272646f, +0.435039f,0.898005f,-0.0657877f, +0.45866f,0.886154f,-0.0660444f, +0.484136f,0.874975f,0.00559808f, +0.464546f,0.884206f,0.0487577f, +0.311084f,0.947795f,0.0700806f, +0.215922f,0.975139f,0.0498078f, +0.229266f,0.973122f,-0.0216826f, +0.269391f,0.956816f,-0.109228f, +0.297276f,0.941247f,-0.160256f, +0.352506f,0.931874f,-0.0857318f, +0.363875f,0.92958f,-0.0589632f, +0.421372f,0.901903f,0.094954f, +0.220959f,0.972251f,-0.0768509f, +0.0552433f,0.994093f,-0.0934223f, +-0.134577f,0.980922f,-0.140288f, +-0.247593f,0.953903f,-0.169607f, +-0.238891f,0.96987f,-0.0477791f, +-0.130123f,0.990325f,-0.0482061f, +0.00814361f,0.986901f,-0.161119f, +-0.0740374f,0.970051f,-0.231345f, +-0.135238f,0.990526f,-0.0238593f, +-0.204897f,0.978574f,0.0202582f, +-0.205889f,0.977122f,-0.0533174f, +-0.236999f,0.963982f,-0.120711f, +0.399314f,0.905653f,0.142621f, +0.334882f,0.936094f,0.107618f, +0.310789f,0.943606f,0.114093f, +0.298988f,0.952609f,0.0560503f, +0.00373107f,0.999894f,-0.0140921f, +-0.127729f,0.983543f,0.12778f, +0.134365f,0.969696f,0.204046f, +0.250753f,0.938877f,0.235867f, +0.172971f,0.901933f,0.395725f, +-0.0661635f,0.938085f,0.340027f, +-0.190026f,0.944561f,0.267758f, +-0.246469f,0.952194f,0.180498f, +-0.199636f,0.962622f,0.183041f, +-0.204824f,0.924659f,0.321019f, +-0.345906f,0.869848f,0.351729f, +-0.272906f,0.86539f,0.420265f, +-0.23738f,0.86577f,0.44056f, +-0.476597f,0.838274f,0.264863f, +-0.549692f,0.815624f,0.180542f, +-0.521659f,0.837826f,0.160993f, +-0.461012f,0.874551f,0.150426f, +-0.498406f,0.858536f,0.120447f, +-0.538861f,0.837113f,0.0941878f, +-0.51696f,0.855065f,0.0401927f, +-0.464195f,0.882878f,0.0710582f, +-0.339798f,0.923706f,0.176929f, +-0.307071f,0.929998f,0.202016f, +-0.435636f,0.887155f,0.152245f, +-0.50925f,0.856289f,0.0862179f, +-0.352613f,0.935762f,-0.00363908f, +-0.24432f,0.969666f,0.0074465f, +-0.223693f,0.974193f,-0.0301471f, +0.0924619f,0.993171f,0.071143f, +0.248444f,0.955155f,0.161104f, +0.25541f,0.957577f,0.133462f, +0.152224f,0.983188f,-0.100846f, +0.175485f,0.954332f,-0.241774f, +0.229817f,0.96697f,-0.110245f, +0.104087f,0.990176f,0.0933667f, +-0.0251916f,0.99085f,0.132593f, +0.0299952f,0.999356f,-0.0197015f, +0.374506f,0.927216f,-0.00387803f, +0.523769f,0.851516f,-0.0242066f, +0.412003f,0.903869f,-0.115217f, +0.44751f,0.89427f,-0.00401492f, +0.502351f,0.864643f,-0.0060566f, +0.261187f,0.953407f,-0.150988f, +0.201827f,0.974066f,-0.102283f, +0.328474f,0.941424f,-0.0763319f, +0.327281f,0.932573f,-0.152297f, +0.312159f,0.927432f,-0.205977f, +0.304739f,0.922289f,-0.237734f, +0.291399f,0.941708f,-0.168142f, +0.325323f,0.94222f,-0.0799213f, +0.270502f,0.962573f,-0.0167793f, +-0.00135827f,0.998382f,0.0568385f, +-0.0464612f,0.993882f,0.100202f, +-0.163616f,0.983349f,-0.0790802f, +-0.219372f,0.956704f,-0.191292f, +-0.0798083f,0.976764f,-0.198904f, +-0.0362508f,0.993161f,-0.11098f, +-0.194493f,0.976824f,0.0893684f, +-0.303508f,0.929002f,0.211751f, +-0.120982f,0.967912f,0.220249f, +-0.126864f,0.979558f,0.156117f, +-0.190168f,0.969475f,0.154773f, +0.442277f,0.894635f,0.0633978f, +0.351901f,0.932017f,0.0866602f, +0.271089f,0.951246f,0.147111f, +0.263373f,0.940704f,0.2138f, +0.0780789f,0.961317f,0.264145f, +-0.165165f,0.972713f,0.162944f, +0.054241f,0.96435f,0.259011f, +0.119009f,0.928226f,0.352467f, +0.062551f,0.905107f,0.420558f, +-0.0376962f,0.903166f,0.427633f, +-0.119235f,0.864868f,0.487634f, +-0.107099f,0.89512f,0.43277f, +-0.228241f,0.933808f,0.275515f, +-0.34367f,0.891778f,0.294319f, +-0.360994f,0.863066f,0.353271f, +-0.329935f,0.870805f,0.364474f, +-0.225803f,0.873787f,0.430708f, +-0.324138f,0.85889f,0.396537f, +-0.511071f,0.812187f,0.281352f, +-0.475013f,0.824987f,0.306202f, +-0.392033f,0.887928f,0.240612f, +-0.45534f,0.876633f,0.155499f, +-0.547025f,0.829694f,0.111226f, +-0.496064f,0.862275f,0.101992f, +-0.479515f,0.87606f,0.0508306f, +-0.424535f,0.90465f,0.0371277f, +-0.362147f,0.919497f,0.152886f, +-0.412742f,0.878092f,0.24207f, +-0.402299f,0.893898f,0.197745f, +-0.26297f,0.963672f,0.0467231f, +-0.219075f,0.975598f,-0.0146319f, +-0.186267f,0.980099f,-0.0686323f, +-0.0357984f,0.992879f,-0.113625f, +0.180598f,0.983509f,0.00973344f, +0.28459f,0.957748f,0.0415635f, +0.350884f,0.934731f,0.0561944f, +0.201029f,0.975728f,-0.0868401f, +0.10163f,0.994331f,-0.0312587f, +-0.0498772f,0.998294f,0.0303674f, +0.0144565f,0.996475f,0.082632f, +0.17671f,0.984206f,0.0105968f, +0.384098f,0.921983f,-0.049144f, +0.526508f,0.848767f,-0.048829f, +0.451141f,0.890087f,-0.0649363f, +0.349978f,0.927792f,-0.129298f, +0.525028f,0.849511f,-0.051734f, +0.403316f,0.902994f,-0.148114f, +0.146493f,0.950082f,-0.275472f, +0.257494f,0.953663f,-0.155639f, +0.363336f,0.930153f,-0.0529431f, +0.407301f,0.911128f,-0.0628641f, +0.309341f,0.935596f,-0.170201f, +0.234661f,0.952473f,-0.194238f, +0.248922f,0.950735f,-0.18477f, +0.176271f,0.982701f,-0.0568089f, +-0.0817466f,0.996475f,0.0188703f, +-0.0390696f,0.99855f,0.0370285f, +0.0392849f,0.997614f,0.0567754f, +-0.165147f,0.985538f,-0.0379532f, +-0.216905f,0.97598f,0.020392f, +-0.25871f,0.942954f,0.209538f, +-0.318314f,0.87576f,0.362933f, +-0.238112f,0.92993f,0.280235f, +-0.11178f,0.963059f,0.244995f, +-0.156033f,0.939968f,0.303502f, +-0.219558f,0.904757f,0.364977f, +0.29059f,0.953077f,-0.0848643f, +0.282679f,0.959209f,-0.00326087f, +0.165956f,0.986031f,0.0141778f, +0.145774f,0.971701f,0.185869f, +0.0971539f,0.92606f,0.364656f, +-0.126893f,0.938591f,0.320851f, +-0.158756f,0.918948f,0.361014f, +0.0576791f,0.877286f,0.47649f, +0.151465f,0.884095f,0.442079f, +-0.0842052f,0.912347f,0.400665f, +-0.236928f,0.870703f,0.430978f, +-0.0173538f,0.858153f,0.513101f, +-0.0453547f,0.868839f,0.493013f, +-0.308698f,0.88215f,0.355692f, +-0.391959f,0.868398f,0.303732f, +-0.360504f,0.877037f,0.317558f, +-0.289644f,0.88703f,0.359561f, +-0.323579f,0.85156f,0.412484f, +-0.483914f,0.781191f,0.39442f, +-0.428744f,0.813324f,0.393297f, +-0.337017f,0.871068f,0.357294f, +-0.382215f,0.837599f,0.390306f, +-0.472752f,0.816976f,0.330237f, +-0.454132f,0.848356f,0.272131f, +-0.386129f,0.879637f,0.277745f, +-0.408175f,0.895196f,0.178931f, +-0.461039f,0.873474f,0.15648f, +-0.444429f,0.876284f,0.186035f, +-0.324725f,0.941951f,0.085336f, +-0.200261f,0.979518f,0.0209972f, +-0.146655f,0.98862f,0.0335086f, +-0.105669f,0.986512f,-0.125016f, +-0.0113758f,0.977088f,-0.21253f, +0.125756f,0.969156f,-0.211948f, +0.231535f,0.947003f,-0.222657f, +0.267937f,0.954488f,-0.131005f, +0.231299f,0.971277f,0.055871f, +0.0809071f,0.991774f,0.0991925f, +0.000207679f,0.999953f,0.00973996f, +0.0247831f,0.993578f,-0.110402f, +0.181304f,0.979201f,-0.0910725f, +0.390907f,0.919373f,-0.0441033f, +0.523664f,0.849877f,-0.0590321f, +0.487061f,0.873094f,-0.0218679f, +0.442794f,0.892691f,-0.0838822f, +0.486459f,0.850567f,-0.199735f, +0.449595f,0.886474f,-0.10967f, +0.172841f,0.979158f,-0.106661f, +0.134151f,0.987388f,-0.084069f, +0.292984f,0.955775f,-0.0255695f, +0.391346f,0.920229f,-0.00512785f, +0.418943f,0.907957f,0.00999318f, +0.324262f,0.936698f,-0.1321f, +0.190686f,0.957473f,-0.216527f, +0.0619887f,0.993289f,-0.097645f, +-0.0829846f,0.99633f,-0.0209901f, +-0.0646754f,0.997763f,-0.0169202f, +-0.0614217f,0.996217f,0.0614677f, +-0.189778f,0.963623f,0.188191f, +-0.363861f,0.896503f,0.25276f, +-0.348308f,0.859996f,0.372945f, +-0.264506f,0.906439f,0.329249f, +-0.140762f,0.939057f,0.31362f, +-0.154941f,0.944783f,0.288752f, +-0.237481f,0.904164f,0.355093f, +-0.314839f,0.867723f,0.38462f, +0.199283f,0.97456f,-0.102566f, +0.290362f,0.956152f,-0.0382605f, +0.163603f,0.98144f,-0.10005f, +-0.0845537f,0.992536f,-0.0878854f, +-0.0995819f,0.988025f,0.117859f, +-0.128698f,0.94862f,0.289062f, +-0.181988f,0.934999f,0.304396f, +0.0121717f,0.953274f,0.301863f, +0.15771f,0.909532f,0.384551f, +-0.030083f,0.904525f,0.425359f, +-0.262213f,0.918561f,0.295788f, +-0.150427f,0.932893f,0.327234f, +-0.0433771f,0.888915f,0.456013f, +-0.194904f,0.882492f,0.428042f, +-0.359771f,0.865678f,0.348089f, +-0.358104f,0.856009f,0.37284f, +-0.334766f,0.853069f,0.400257f, +-0.382047f,0.809514f,0.445788f, +-0.440041f,0.772384f,0.458024f, +-0.392897f,0.847233f,0.357532f, +-0.352962f,0.862399f,0.362885f, +-0.432462f,0.797784f,0.42014f, +-0.40741f,0.807767f,0.426063f, +-0.417686f,0.831448f,0.366378f, +-0.406533f,0.835025f,0.370761f, +-0.302917f,0.831265f,0.466089f, +-0.354465f,0.85583f,0.376708f, +-0.320875f,0.930472f,0.17681f, +-0.210666f,0.977556f,0.00208309f, +-0.202152f,0.976764f,-0.0711849f, +-0.0734606f,0.993473f,-0.0872598f, +0.0104554f,0.979699f,-0.2002f, +0.0812548f,0.981491f,-0.173417f, +0.133484f,0.953074f,-0.271721f, +0.239226f,0.941558f,-0.23715f, +0.0986638f,0.979162f,-0.177504f, +0.0167662f,0.999807f,0.0102821f, +0.0608252f,0.989728f,0.129377f, +0.193478f,0.976369f,0.0962839f, +0.105893f,0.986391f,-0.125774f, +0.159018f,0.972139f,-0.17222f, +0.348199f,0.916375f,-0.197521f, +0.506641f,0.853561f,-0.121441f, +0.438954f,0.895697f,-0.0710352f, +0.508211f,0.861156f,-0.0114456f, +0.538629f,0.837641f,-0.0907543f, +0.350973f,0.934296f,-0.0625226f, +0.130826f,0.991364f,0.00901604f, +0.142249f,0.989581f,0.0222434f, +0.314713f,0.948656f,-0.0317428f, +0.413134f,0.902882f,-0.118849f, +0.421178f,0.889709f,-0.176143f, +0.40304f,0.897538f,-0.178843f, +0.190553f,0.961133f,-0.199782f, +-0.0704956f,0.989551f,-0.125772f, +-0.145721f,0.988685f,0.035603f, +-0.158165f,0.979549f,0.124366f, +-0.141884f,0.945197f,0.294061f, +-0.282634f,0.89813f,0.336869f, +-0.398539f,0.847577f,0.350398f, +-0.326007f,0.891199f,0.31541f, +-0.257935f,0.930645f,0.259558f, +-0.189362f,0.933131f,0.305628f, +-0.181998f,0.908713f,0.375656f, +-0.284451f,0.857477f,0.428743f, +-0.324962f,0.834267f,0.445419f, +0.162722f,0.967013f,-0.19598f, +0.196801f,0.96943f,-0.146541f, +0.171798f,0.98444f,0.0369126f, +-0.0614366f,0.993745f,0.0932502f, +-0.263807f,0.962515f,0.063023f, +-0.262644f,0.943232f,0.203304f, +-0.183229f,0.945939f,0.267632f, +-0.0512022f,0.955564f,0.290302f, +0.0500709f,0.932925f,0.356571f, +-0.017607f,0.930336f,0.366286f, +-0.141345f,0.917863f,0.370876f, +-0.196664f,0.921785f,0.334121f, +-0.123639f,0.931227f,0.342826f, +-0.166673f,0.929929f,0.327799f, +-0.365314f,0.882118f,0.297345f, +-0.422119f,0.842584f,0.334465f, +-0.378137f,0.838603f,0.392119f, +-0.433991f,0.800503f,0.413336f, +-0.373446f,0.819157f,0.435339f, +-0.321191f,0.877582f,0.35593f, +-0.410179f,0.839146f,0.357194f, +-0.450466f,0.792998f,0.410164f, +-0.383405f,0.853385f,0.353178f, +-0.361072f,0.88078f,0.306355f, +-0.471517f,0.844691f,0.253315f, +-0.399349f,0.852332f,0.337713f, +-0.193735f,0.889811f,0.413163f, +-0.0964184f,0.953204f,0.28654f, +-0.0731968f,0.993583f,0.0862245f, +-0.107213f,0.990087f,-0.0907379f, +-0.0139207f,0.976637f,-0.214443f, +-0.00517032f,0.976967f,-0.213328f, +0.032564f,0.990278f,-0.135238f, +0.193406f,0.974103f,-0.117123f, +0.137302f,0.989014f,-0.0547632f, +0.0149454f,0.997504f,0.06901f, +-0.0673257f,0.995987f,0.0589639f, +0.00671915f,0.997834f,0.0654375f, +0.236496f,0.961793f,0.137925f, +0.296243f,0.953456f,0.0562338f, +0.227931f,0.966806f,-0.11547f, +0.392626f,0.909868f,-0.134105f, +0.455312f,0.880641f,-0.131003f, +0.402519f,0.906647f,-0.126375f, +0.459051f,0.879656f,-0.124406f, +0.531911f,0.846049f,-0.0356662f, +0.366681f,0.930218f,0.0155094f, +0.101768f,0.992829f,-0.0627213f, +0.169781f,0.984995f,-0.0309622f, +0.383193f,0.921183f,-0.0677109f, +0.483652f,0.86784f,-0.113728f, +0.481548f,0.864447f,-0.144373f, +0.322376f,0.925659f,-0.198063f, +0.121084f,0.992307f,-0.0257868f, +-0.189201f,0.97803f,0.0875253f, +-0.272481f,0.941614f,0.197779f, +-0.28107f,0.929157f,0.240138f, +-0.316277f,0.890261f,0.327726f, +-0.284096f,0.875896f,0.389994f, +-0.304764f,0.879665f,0.365114f, +-0.295018f,0.913863f,0.278959f, +-0.233864f,0.913909f,0.331779f, +-0.25276f,0.886942f,0.386584f, +-0.254968f,0.846261f,0.467797f, +-0.324913f,0.811645f,0.485452f, +-0.330966f,0.801562f,0.497956f, +0.166281f,0.984047f,-0.0632562f, +0.102172f,0.992786f,-0.0627485f, +-0.0446214f,0.999004f,-0.000325965f, +-0.137659f,0.980871f,0.13763f, +-0.270041f,0.94552f,0.18185f, +-0.300503f,0.932348f,0.201063f, +-0.224552f,0.960314f,0.165452f, +-0.109331f,0.978965f,0.17226f, +0.0684226f,0.972288f,0.223551f, +-0.0281009f,0.965962f,0.257154f, +-0.203983f,0.927334f,0.313757f, +-0.170837f,0.935943f,0.307937f, +-0.0844776f,0.951083f,0.29716f, +-0.140439f,0.935294f,0.32481f, +-0.360713f,0.879742f,0.309743f, +-0.466354f,0.845167f,0.261162f, +-0.425659f,0.859392f,0.283303f, +-0.470194f,0.836884f,0.280256f, +-0.410878f,0.856359f,0.312777f, +-0.293557f,0.864483f,0.408036f, +-0.429097f,0.81157f,0.396523f, +-0.438172f,0.837036f,0.327683f, +-0.303084f,0.911643f,0.277574f, +-0.346895f,0.902405f,0.255594f, +-0.444307f,0.857916f,0.258015f, +-0.440123f,0.885255f,0.150386f, +-0.246442f,0.965625f,0.0826743f, +-0.0242341f,0.995753f,0.0888192f, +0.128537f,0.987977f,0.085905f, +0.10291f,0.993755f,-0.0431449f, +0.0280177f,0.986869f,-0.159076f, +-0.0318503f,0.988236f,-0.149584f, +0.00777626f,0.97932f,-0.202168f, +0.111085f,0.970769f,-0.212762f, +-0.00220326f,0.997417f,-0.0718009f, +-0.0152092f,0.997571f,0.0679693f, +0.0100591f,0.998816f,0.0476033f, +-0.00783919f,0.999851f,-0.0153546f, +0.1632f,0.986482f,-0.0148045f, +0.356551f,0.93118f,0.0760001f, +0.33409f,0.940767f,0.0578066f, +0.378555f,0.924836f,-0.0370621f, +0.481573f,0.874509f,-0.0576253f, +0.443664f,0.890369f,-0.102011f, +0.449245f,0.88434f,-0.126968f, +0.449063f,0.892098f,-0.05003f, +0.400085f,0.916232f,0.0212355f, +0.189459f,0.975149f,-0.114846f, +0.154225f,0.96178f,-0.226258f, +0.36559f,0.902984f,-0.225751f, +0.443305f,0.891814f,-0.0902669f, +0.481296f,0.876165f,0.0262584f, +0.274557f,0.96003f,0.0544047f, +-0.0951468f,0.983236f,0.155547f, +-0.272231f,0.920302f,0.280953f, +-0.309095f,0.909629f,0.277553f, +-0.260629f,0.904898f,0.336501f, +-0.319906f,0.899874f,0.296456f, +-0.309019f,0.910231f,0.275658f, +-0.301457f,0.909911f,0.284931f, +-0.289244f,0.908198f,0.302514f, +-0.349317f,0.867088f,0.355157f, +-0.355035f,0.811266f,0.46454f, +-0.291879f,0.804435f,0.517388f, +-0.292737f,0.815956f,0.498519f, +-0.341117f,0.83204f,0.437434f, +0.012939f,0.999781f,0.0164623f, +0.101117f,0.986501f,0.12881f, +-0.0315137f,0.991787f,0.123953f, +-0.202813f,0.972667f,0.113078f, +-0.267039f,0.954882f,0.129964f, +-0.329248f,0.943109f,0.0462825f, +-0.158801f,0.981787f,0.104294f, +-0.0896983f,0.994441f,0.0551561f, +-0.03797f,0.996172f,0.0787436f, +-0.124773f,0.970658f,0.205561f, +-0.242396f,0.92942f,0.278248f, +-0.1236f,0.936757f,0.327428f, +-0.115597f,0.950099f,0.289742f, +-0.242269f,0.924532f,0.294187f, +-0.335063f,0.873272f,0.353736f, +-0.402827f,0.872268f,0.27727f, +-0.433494f,0.882428f,0.182769f, +-0.472347f,0.860126f,0.192541f, +-0.516304f,0.829671f,0.212311f, +-0.401557f,0.840095f,0.364681f, +-0.365647f,0.853697f,0.370816f, +-0.342203f,0.911984f,0.226234f, +-0.319568f,0.928553f,0.188855f, +-0.368607f,0.886665f,0.279203f, +-0.401013f,0.885839f,0.233406f, +-0.263462f,0.961384f,0.0795548f, +-0.119336f,0.983737f,-0.134243f, +-0.028348f,0.969034f,-0.245295f, +0.0404463f,0.983879f,-0.174201f, +0.11875f,0.992593f,0.0256534f, +0.0602272f,0.997166f,0.0450923f, +0.0340291f,0.999414f,-0.00366965f, +0.0708792f,0.992684f,-0.097743f, +0.0958935f,0.99395f,-0.0535485f, +-0.0943801f,0.993296f,-0.0667466f, +-0.119267f,0.988594f,-0.0919588f, +0.000759128f,0.999891f,-0.0147216f, +0.0724665f,0.997368f,-0.00256206f, +0.170906f,0.979948f,-0.10244f, +0.214916f,0.97339f,-0.079521f, +0.347938f,0.935698f,0.0583811f, +0.479062f,0.877734f,-0.00909944f, +0.517939f,0.850313f,-0.0933121f, +0.446396f,0.884197f,-0.137574f, +0.389313f,0.918353f,-0.0711587f, +0.410982f,0.908412f,0.0766878f, +0.41147f,0.910096f,0.0491837f, +0.356411f,0.933637f,-0.0359751f, +0.291892f,0.941315f,-0.169483f, +0.292525f,0.936947f,-0.191205f, +0.303478f,0.950202f,-0.0708325f, +0.350076f,0.936333f,0.0269695f, +0.186651f,0.94527f,0.26763f, +-0.145022f,0.9031f,0.404201f, +-0.257588f,0.88179f,0.395088f, +-0.316433f,0.892435f,0.321607f, +-0.301856f,0.895088f,0.328177f, +-0.311714f,0.888624f,0.336427f, +-0.275146f,0.879635f,0.387991f, +-0.320358f,0.874704f,0.363681f, +-0.312957f,0.856468f,0.410514f, +-0.417707f,0.826376f,0.377656f, +-0.402058f,0.821773f,0.403779f, +-0.299174f,0.86271f,0.407708f, +-0.252864f,0.886408f,0.387737f, +-0.266831f,0.899401f,0.346235f, +-0.121912f,0.980245f,-0.155747f, +-0.0467045f,0.996241f,-0.0729522f, +-0.0560423f,0.996609f,0.0602479f, +-0.253613f,0.959854f,0.119832f, +-0.17852f,0.958289f,0.223189f, +-0.25091f,0.965294f,0.0724672f, +-0.244405f,0.968888f,0.0390022f, +-0.111828f,0.978686f,0.172245f, +-0.104286f,0.963728f,0.245667f, +-0.172657f,0.941673f,0.288863f, +-0.302965f,0.917419f,0.257981f, +-0.21274f,0.929075f,0.302592f, +-0.0577232f,0.923128f,0.380136f, +-0.183983f,0.930078f,0.31797f, +-0.384056f,0.900387f,0.204463f, +-0.327378f,0.913703f,0.240771f, +-0.374063f,0.905896f,0.198566f, +-0.504219f,0.846296f,0.17189f, +-0.555467f,0.810974f,0.183786f, +-0.456478f,0.86757f,0.197356f, +-0.300554f,0.935674f,0.184881f, +-0.295051f,0.948068f,0.118792f, +-0.362387f,0.917821f,0.162113f, +-0.440667f,0.875232f,0.199453f, +-0.248631f,0.939944f,0.233854f, +-0.0966352f,0.995188f,0.0161918f, +0.0243217f,0.996259f,-0.0829196f, +0.0213875f,0.994057f,-0.106741f, +-0.13683f,0.98707f,-0.0834831f, +-0.0593385f,0.994125f,0.0905282f, +0.0836318f,0.990077f,0.112932f, +0.079675f,0.993049f,0.0866394f, +0.0726138f,0.990126f,0.119908f, +0.0468689f,0.990824f,0.126776f, +0.00048966f,0.99587f,0.0907856f, +-0.0299455f,0.998898f,-0.0361395f, +-0.0528047f,0.988171f,-0.143981f, +0.0771474f,0.992034f,-0.0995875f, +0.233f,0.968973f,-0.0824758f, +0.215078f,0.967265f,-0.134683f, +0.299646f,0.93128f,-0.207193f, +0.500666f,0.844143f,-0.191721f, +0.5316f,0.838001f,-0.123112f, +0.45137f,0.888237f,-0.0854371f, +0.26295f,0.958984f,-0.105862f, +0.297072f,0.954855f,-0.000735176f, +0.467586f,0.880091f,0.0824758f, +0.451683f,0.892137f,0.00862833f, +0.280097f,0.955995f,-0.0872873f, +0.27353f,0.961001f,0.0407195f, +0.263182f,0.963734f,0.044184f, +0.22357f,0.970136f,0.0940863f, +-0.055048f,0.955137f,0.291002f, +-0.267739f,0.863744f,0.426921f, +-0.199104f,0.857693f,0.474046f, +-0.21681f,0.879018f,0.424642f, +-0.270209f,0.885026f,0.379098f, +-0.341336f,0.865644f,0.366267f, +-0.32372f,0.861174f,0.391898f, +-0.34092f,0.838889f,0.42431f, +-0.295898f,0.818794f,0.491956f, +-0.331f,0.829823f,0.449258f, +-0.389842f,0.853312f,0.34624f, +-0.281201f,0.9123f,0.297716f, +-0.234572f,0.935622f,0.263795f, +-0.225355f,0.942001f,0.248696f, +-0.0486057f,0.996635f,-0.0660014f, +-0.101682f,0.988174f,-0.114771f, +-0.162649f,0.983215f,-0.0826606f, +-0.318288f,0.946728f,-0.048975f, +-0.258454f,0.965864f,-0.0175802f, +-0.136613f,0.987862f,0.0739351f, +-0.281595f,0.958211f,0.0503573f, +-0.28706f,0.943479f,0.165663f, +-0.148179f,0.930819f,0.334095f, +-0.182832f,0.931383f,0.314798f, +-0.242578f,0.923022f,0.298642f, +-0.204404f,0.955935f,0.21073f, +-0.142784f,0.976536f,0.161212f, +-0.136962f,0.950722f,0.278153f, +-0.274249f,0.920019f,0.279915f, +-0.389723f,0.904453f,0.173436f, +-0.370261f,0.901011f,0.226022f, +-0.50377f,0.847021f,0.169619f, +-0.52553f,0.835875f,0.158529f, +-0.435894f,0.894864f,0.0959897f, +-0.279872f,0.956869f,0.07793f, +-0.331658f,0.940229f,0.0772765f, +-0.372127f,0.91403f,0.161461f, +-0.456876f,0.888328f,0.0462339f, +-0.204408f,0.978272f,0.0346564f, +0.0554954f,0.998458f,-0.00157713f, +-0.0102256f,0.999947f,0.00149442f, +-0.0507499f,0.985345f,0.162848f, +-0.124313f,0.970082f,0.208536f, +-0.111836f,0.992788f,0.0431796f, +0.135986f,0.987999f,0.0732526f, +0.00980425f,0.997155f,0.0747439f, +0.00734776f,0.982792f,0.184568f, +0.0872171f,0.965097f,0.246944f, +0.0795152f,0.966423f,0.244345f, +0.106439f,0.984803f,0.137237f, +0.0584187f,0.998092f,-0.0199996f, +0.0370568f,0.991888f,-0.121591f, +0.199554f,0.972297f,-0.121727f, +0.308311f,0.945569f,-0.104131f, +0.399439f,0.904394f,-0.150064f, +0.468199f,0.870932f,-0.149223f, +0.412212f,0.907025f,-0.0859413f, +0.425915f,0.903304f,0.0513667f, +0.351639f,0.936099f,-0.00832492f, +0.20857f,0.966693f,-0.148333f, +0.395551f,0.918183f,0.0219088f, +0.538432f,0.838724f,0.0814483f, +0.24402f,0.966591f,-0.0784634f, +0.178953f,0.981938f,0.0614245f, +0.258979f,0.960241f,0.104243f, +0.0759782f,0.986383f,0.145865f, +-0.19655f,0.929601f,0.311786f, +-0.328358f,0.883678f,0.333607f, +-0.21216f,0.920721f,0.327507f, +-0.208125f,0.923292f,0.322823f, +-0.300181f,0.87973f,0.368737f, +-0.312111f,0.847974f,0.428401f, +-0.324858f,0.873038f,0.363693f, +-0.410275f,0.846963f,0.338124f, +-0.346514f,0.853308f,0.389607f, +-0.303825f,0.86928f,0.389926f, +-0.270707f,0.881074f,0.387848f, +-0.213937f,0.928705f,0.302885f, +-0.20202f,0.939889f,0.275312f, +-0.214102f,0.943299f,0.253667f, +-0.0402111f,0.999126f,0.011392f, +-0.0458289f,0.99894f,0.00442323f, +-0.170695f,0.984267f,-0.0456311f, +-0.29333f,0.955986f,-0.00691228f, +-0.274679f,0.961535f,-0.00118788f, +-0.240876f,0.970372f,-0.0188751f, +-0.335158f,0.942005f,0.0172014f, +-0.387782f,0.921031f,0.0364391f, +-0.254694f,0.964339f,0.0719752f, +-0.156383f,0.970864f,0.181569f, +-0.223749f,0.957301f,0.183063f, +-0.122594f,0.972034f,0.200303f, +-0.0910709f,0.976799f,0.193828f, +-0.28429f,0.950625f,0.124466f, +-0.315477f,0.924742f,0.212902f, +-0.305454f,0.925312f,0.224713f, +-0.365063f,0.920836f,0.137077f, +-0.474911f,0.873286f,0.108772f, +-0.523018f,0.843362f,0.123259f, +-0.405348f,0.903149f,0.141474f, +-0.272593f,0.953587f,0.127925f, +-0.342778f,0.935924f,0.0809316f, +-0.402631f,0.912044f,0.0778773f, +-0.324862f,0.935409f,0.139553f, +-0.213356f,0.97623f,0.0381383f, +0.0301299f,0.998064f,0.0544045f, +-0.104927f,0.992798f,0.0578138f, +-0.261101f,0.959724f,0.103713f, +-0.0217785f,0.964552f,0.262994f, +0.0803134f,0.988499f,0.128142f, +0.028164f,0.998669f,0.043203f, +-0.0183001f,0.984341f,0.175323f, +-0.0612635f,0.982917f,0.173556f, +-0.0331225f,0.977326f,0.209135f, +0.0728156f,0.957515f,0.279039f, +0.245559f,0.942697f,0.225881f, +0.183786f,0.974714f,0.127102f, +0.141547f,0.988409f,0.0548866f, +0.245636f,0.968932f,-0.0288843f, +0.304552f,0.94926f,-0.0784495f, +0.340339f,0.936344f,-0.0861948f, +0.460805f,0.886321f,0.0457651f, +0.380493f,0.924294f,0.030084f, +0.352595f,0.93478f,0.0431689f, +0.472573f,0.87479f,0.106851f, +0.264087f,0.962772f,-0.057695f, +0.234368f,0.968348f,-0.0858683f, +0.503248f,0.863251f,0.0392276f, +0.302957f,0.950423f,0.0700943f, +0.0199528f,0.999731f,0.0118377f, +0.239816f,0.960125f,0.143695f, +-0.0259597f,0.9852f,0.16943f, +-0.288371f,0.907451f,0.305574f, +-0.301113f,0.913287f,0.274296f, +-0.184882f,0.952263f,0.242927f, +-0.251998f,0.931999f,0.260528f, +-0.398011f,0.856633f,0.32828f, +-0.335641f,0.851294f,0.403292f, +-0.239383f,0.893387f,0.380205f, +-0.388171f,0.875539f,0.287671f, +-0.364652f,0.897686f,0.247364f, +-0.31107f,0.908317f,0.279636f, +-0.277708f,0.915298f,0.291733f, +-0.164862f,0.947448f,0.274159f, +-0.18884f,0.953184f,0.236178f, +-0.183001f,0.960107f,0.211435f, +-0.0382166f,0.998778f,0.0313295f, +-0.025601f,0.999566f,0.0145695f, +-0.151993f,0.98817f,-0.0204673f, +-0.361566f,0.932093f,-0.021731f, +-0.304279f,0.951825f,0.0379804f, +-0.164708f,0.984119f,0.0661845f, +-0.289794f,0.954555f,-0.0695987f, +-0.339732f,0.933497f,-0.114741f, +-0.304944f,0.945342f,-0.115492f, +-0.266385f,0.963249f,-0.0345067f, +-0.261205f,0.96511f,0.0183122f, +-0.220073f,0.973176f,0.06706f, +-0.108437f,0.981443f,0.158152f, +-0.188668f,0.971426f,0.143996f, +-0.373149f,0.923277f,0.0912126f, +-0.308957f,0.927563f,0.210174f, +-0.302984f,0.922237f,0.240167f, +-0.457665f,0.867903f,0.193102f, +-0.548023f,0.825328f,0.136032f, +-0.407198f,0.903776f,0.131829f, +-0.253292f,0.959077f,0.126545f, +-0.271541f,0.948088f,0.165511f, +-0.43428f,0.889355f,0.142997f, +-0.382973f,0.89965f,0.20967f, +-0.169509f,0.965022f,0.199998f, +0.00160887f,0.982078f,0.188467f, +-0.0137168f,0.977172f,0.212005f, +-0.230009f,0.971053f,0.0644371f, +-0.165502f,0.985539f,0.036359f, +0.129892f,0.967237f,0.218131f, +0.0422409f,0.973374f,0.225299f, +-0.105762f,0.968925f,0.223604f, +-0.0226547f,0.965849f,0.258115f, +0.0138374f,0.990856f,0.134211f, +0.0309349f,0.998739f,0.0395399f, +0.294589f,0.940971f,0.166706f, +0.248856f,0.959421f,0.132596f, +0.181153f,0.982002f,0.053445f, +0.283788f,0.958737f,0.0169453f, +0.366617f,0.930251f,-0.0149969f, +0.332578f,0.93839f,-0.0938972f, +0.358957f,0.931691f,-0.0557027f, +0.429022f,0.901938f,0.0494683f, +0.332897f,0.942781f,-0.0185381f, +0.429131f,0.903242f,-0.000810457f, +0.405301f,0.91403f,-0.0167607f, +0.256936f,0.958211f,-0.12576f, +0.354456f,0.935063f,-0.00433271f, +0.385431f,0.888673f,0.248403f, +0.0742527f,0.992531f,0.0967874f, +0.121836f,0.985927f,0.11447f, +-0.100545f,0.965192f,0.241444f, +-0.337975f,0.881899f,0.328674f, +-0.242866f,0.922974f,0.298555f, +-0.185171f,0.940279f,0.285633f, +-0.313033f,0.906226f,0.28419f, +-0.448562f,0.843983f,0.294082f, +-0.356046f,0.888609f,0.289144f, +-0.196811f,0.931399f,0.306206f, +-0.298585f,0.916744f,0.265384f, +-0.410663f,0.894937f,0.17448f, +-0.325435f,0.90586f,0.271126f, +-0.301755f,0.928362f,0.216998f, +-0.109278f,0.952007f,0.285903f, +-0.14523f,0.965578f,0.215795f, +-0.139372f,0.971047f,0.194018f, +0.00163448f,0.997617f,0.0689798f, +0.026224f,0.998835f,0.04051f, +-0.128032f,0.991559f,-0.0204567f, +-0.309968f,0.948873f,-0.0596736f, +-0.340105f,0.924291f,-0.173245f, +-0.190965f,0.977348f,-0.0912302f, +-0.146645f,0.988782f,-0.028384f, +-0.31072f,0.935549f,-0.167929f, +-0.380234f,0.90209f,-0.204096f, +-0.300275f,0.945729f,-0.124224f, +-0.302914f,0.945705f,-0.117837f, +-0.237161f,0.970049f,-0.0525309f, +-0.165718f,0.984724f,-0.0534418f, +-0.190643f,0.98063f,0.0449474f, +-0.411915f,0.909141f,0.0615588f, +-0.453396f,0.88136f,0.1328f, +-0.362905f,0.886473f,0.287169f, +-0.380477f,0.872742f,0.305874f, +-0.476636f,0.866585f,0.147809f, +-0.366115f,0.923073f,0.117878f, +-0.278065f,0.952821f,0.121709f, +-0.370509f,0.910147f,0.18535f, +-0.442894f,0.857435f,0.26201f, +-0.347292f,0.915122f,0.204794f, +-0.111317f,0.983727f,0.141034f, +-0.00583658f,0.989977f,0.14111f, +0.00293304f,0.989031f,0.147679f, +-0.0932614f,0.992658f,0.0770272f, +-0.209442f,0.977765f,-0.0104574f, +-0.0521744f,0.996134f,0.0706788f, +0.0111918f,0.977173f,0.21215f, +-0.0985288f,0.958328f,0.268141f, +0.0097532f,0.972945f,0.23083f, +0.214151f,0.960047f,0.180136f, +0.0316331f,0.999392f,0.014672f, +0.114623f,0.990459f,0.0765015f, +0.302992f,0.926463f,0.223298f, +0.283203f,0.948444f,0.142303f, +0.315435f,0.948621f,0.0248881f, +0.37741f,0.92565f,0.0270755f, +0.401819f,0.915069f,0.0345122f, +0.321768f,0.943567f,-0.0784028f, +0.371664f,0.926589f,-0.0574381f, +0.394659f,0.917373f,-0.0516908f, +0.434962f,0.894125f,-0.106531f, +0.447382f,0.892016f,-0.0644733f, +0.241542f,0.966428f,-0.0876093f, +0.127706f,0.991493f,-0.0251536f, +0.250404f,0.953051f,0.170269f, +0.250954f,0.937023f,0.242919f, +-0.000559693f,0.986358f,0.164614f, +-0.211006f,0.922632f,0.32284f, +-0.34675f,0.881023f,0.321811f, +-0.216454f,0.925604f,0.310492f, +-0.177379f,0.942447f,0.283426f, +-0.307121f,0.917748f,0.251824f, +-0.427987f,0.86998f,0.244872f, +-0.348579f,0.908707f,0.229659f, +-0.214211f,0.945769f,0.244201f, +-0.272299f,0.924949f,0.265184f, +-0.413173f,0.878684f,0.239168f, +-0.359354f,0.883418f,0.300728f, +-0.292273f,0.892332f,0.343978f, +-0.146355f,0.897543f,0.415929f, +-0.0984727f,0.903088f,0.418013f, +-0.114958f,0.888054f,0.445134f, +0.0486539f,0.997583f,-0.0496084f, +0.0486095f,0.995772f,-0.0779487f, +-0.0727955f,0.994312f,-0.0777426f, +-0.222675f,0.967501f,-0.119823f, +-0.286744f,0.93984f,-0.185682f, +-0.296641f,0.937378f,-0.182555f, +-0.219022f,0.967026f,-0.12996f, +-0.147314f,0.984117f,-0.0990538f, +-0.3428f,0.902622f,-0.26031f, +-0.347893f,0.908635f,-0.230983f, +-0.327008f,0.925901f,-0.189136f, +-0.254527f,0.952486f,-0.167289f, +-0.228332f,0.958887f,-0.168522f, +-0.287734f,0.955666f,-0.0625468f, +-0.451431f,0.892304f,0.00185963f, +-0.510909f,0.851571f,0.11747f, +-0.434919f,0.884052f,0.171166f, +-0.355658f,0.920763f,0.16032f, +-0.392075f,0.91242f,0.117331f, +-0.40418f,0.912194f,0.0673793f, +-0.347001f,0.925636f,0.15096f, +-0.406528f,0.883834f,0.231457f, +-0.406378f,0.897555f,0.171031f, +-0.271349f,0.960134f,0.0671726f, +-0.0926357f,0.994526f,0.0483373f, +-0.0156467f,0.998994f,0.0420269f, +0.00801384f,0.999533f,0.0295044f, +-0.0412004f,0.995482f,0.0855485f, +-0.171347f,0.982792f,0.068987f, +-0.142796f,0.988044f,0.0581328f, +-0.101871f,0.981247f,0.163632f, +-0.103189f,0.979569f,0.172615f, +0.0761964f,0.994828f,0.0671726f, +0.210538f,0.977574f,0.00485915f, +0.123577f,0.988892f,0.0825912f, +0.0553491f,0.995759f,0.0734865f, +0.223203f,0.966768f,0.124662f, +0.344575f,0.927512f,0.144881f, +0.388873f,0.91351f,0.119485f, +0.324349f,0.942843f,0.0764535f, +0.411999f,0.8978f,0.155603f, +0.440079f,0.892774f,0.0963553f, +0.378616f,0.925121f,-0.0283174f, +0.428515f,0.90345f,-0.0123871f, +0.429626f,0.902172f,-0.0388249f, +0.396609f,0.917987f,-0.000717735f, +0.233551f,0.972137f,-0.020091f, +0.111169f,0.993801f,0.000982701f, +0.115357f,0.993291f,0.00809163f, +0.164275f,0.973308f,0.160266f, +-0.0349159f,0.947849f,0.316803f, +-0.267423f,0.890391f,0.368361f, +-0.327503f,0.90805f,0.261125f, +-0.196107f,0.942247f,0.271499f, +-0.118776f,0.949723f,0.289686f, +-0.296931f,0.925681f,0.234405f, +-0.445051f,0.862967f,0.239201f, +-0.335704f,0.917243f,0.2144f, +-0.25181f,0.948438f,0.1925f, +-0.329983f,0.903347f,0.274f, +-0.391867f,0.838521f,0.378579f, +-0.417038f,0.817641f,0.396917f, +-0.341558f,0.812981f,0.471594f, +-0.188106f,0.834488f,0.517925f, +-0.137025f,0.804598f,0.577794f, +-0.18711f,0.76127f,0.620852f, +0.138194f,0.960364f,-0.242082f, +0.0401358f,0.96162f,-0.271434f, +-0.076195f,0.979732f,-0.185256f, +-0.203103f,0.960439f,-0.190543f, +-0.267864f,0.941416f,-0.2049f, +-0.261748f,0.936741f,-0.232388f, +-0.231434f,0.930091f,-0.285254f, +-0.126583f,0.962607f,-0.239509f, +-0.258776f,0.934905f,-0.242872f, +-0.430322f,0.876496f,-0.215819f, +-0.353956f,0.929119f,-0.107016f, +-0.27861f,0.956787f,-0.0832819f, +-0.250796f,0.967007f,-0.0447179f, +-0.348257f,0.937394f,-0.0030026f, +-0.497787f,0.866258f,0.0424905f, +-0.584411f,0.803193f,0.115522f, +-0.394257f,0.905213f,0.158588f, +-0.343138f,0.935038f,0.0892179f, +-0.380878f,0.917442f,0.115034f, +-0.389256f,0.914513f,0.11021f, +-0.431967f,0.895633f,0.10605f, +-0.414636f,0.893675f,0.171528f, +-0.300214f,0.948969f,0.0965901f, +-0.20281f,0.978452f,-0.0387339f, +-0.123855f,0.987388f,-0.098611f, +-0.0140563f,0.999899f,0.0019046f, +-0.052066f,0.991601f,0.118388f, +-0.0936165f,0.973604f,0.208163f, +-0.149626f,0.978491f,0.142013f, +-0.198198f,0.970011f,0.140699f, +-0.130637f,0.968649f,0.211313f, +0.013631f,0.991214f,0.131563f, +0.20118f,0.979295f,0.0225449f, +0.231889f,0.971935f,-0.0396138f, +0.0131145f,0.999014f,-0.0424166f, +0.0264969f,0.999403f,0.0221517f, +0.210411f,0.977103f,0.0315571f, +0.327081f,0.943965f,0.0441437f, +0.381166f,0.920813f,0.0825546f, +0.346088f,0.933621f,0.0925967f, +0.356105f,0.932513f,0.0600724f, +0.479238f,0.87232f,0.0968908f, +0.446186f,0.89276f,0.062428f, +0.391504f,0.920172f,-0.00287489f, +0.426134f,0.9041f,0.0318405f, +0.417296f,0.907685f,0.0444148f, +0.286592f,0.957965f,0.012947f, +0.07628f,0.996621f,-0.030475f, +0.0820652f,0.99629f,0.0259114f, +-0.0280556f,0.994071f,0.105053f, +-0.213977f,0.933546f,0.287585f, +-0.245374f,0.890565f,0.382995f, +-0.189692f,0.923736f,0.332759f, +-0.238316f,0.94737f,0.213765f, +-0.176209f,0.945132f,0.275092f, +-0.265622f,0.907592f,0.32515f, +-0.420635f,0.873046f,0.246691f, +-0.275407f,0.930254f,0.242441f, +-0.273955f,0.921146f,0.276474f, +-0.415501f,0.828882f,0.374585f, +-0.488833f,0.76092f,0.426664f, +-0.43149f,0.76785f,0.473522f, +-0.33634f,0.787599f,0.516297f, +-0.228347f,0.790629f,0.568123f, +-0.231089f,0.763668f,0.602835f, +-0.28515f,0.752352f,0.593849f, +0.109283f,0.926796f,-0.359314f, +-0.0105223f,0.944186f,-0.329244f, +-0.147017f,0.945286f,-0.29124f, +-0.202823f,0.935685f,-0.288714f, +-0.214861f,0.941374f,-0.260095f, +-0.2356f,0.926477f,-0.293483f, +-0.224333f,0.941495f,-0.251519f, +-0.230404f,0.948768f,-0.216226f, +-0.277442f,0.956386f,-0.0913908f, +-0.472179f,0.876647f,-0.0923929f, +-0.428177f,0.898465f,-0.0970806f, +-0.3387f,0.938243f,-0.0705803f, +-0.291725f,0.956079f,0.0284457f, +-0.399526f,0.915525f,0.0468393f, +-0.527082f,0.845186f,0.0885769f, +-0.577694f,0.815576f,0.0332458f, +-0.408723f,0.912647f,0.00457497f, +-0.331162f,0.938989f,0.0929031f, +-0.4185f,0.893481f,0.162938f, +-0.372755f,0.902119f,0.217335f, +-0.419905f,0.891761f,0.168648f, +-0.426162f,0.889671f,0.163929f, +-0.238048f,0.949403f,0.20486f, +-0.0631417f,0.981494f,0.180781f, +-0.0934621f,0.991987f,0.0850084f, +-0.209815f,0.971464f,0.110612f, +-0.239382f,0.928806f,0.282871f, +-0.0385152f,0.924665f,0.378829f, +-0.0229585f,0.976683f,0.213458f, +-0.204415f,0.977814f,0.0457583f, +-0.131276f,0.991302f,0.00937849f, +0.100844f,0.99484f,0.0110965f, +0.227419f,0.973508f,-0.0237273f, +0.22975f,0.97307f,0.0187244f, +0.0718328f,0.997222f,0.0197173f, +0.0214849f,0.994143f,-0.105917f, +0.174121f,0.982096f,-0.0718949f, +0.303053f,0.952921f,0.010044f, +0.38012f,0.924935f,0.00218727f, +0.364895f,0.929903f,-0.0461611f, +0.383009f,0.921386f,-0.0659776f, +0.441676f,0.895702f,-0.0513817f, +0.484548f,0.87476f,0.00284626f, +0.413676f,0.910113f,-0.0237944f, +0.449057f,0.893501f,-0.00212143f, +0.360983f,0.928147f,-0.090746f, +0.274993f,0.958661f,0.0731286f, +0.0881261f,0.984394f,0.15232f, +0.00584658f,0.984704f,0.174138f, +-0.113749f,0.971528f,0.207834f, +-0.320112f,0.923512f,0.211313f, +-0.308899f,0.921582f,0.23509f, +-0.147069f,0.956187f,0.253135f, +-0.14137f,0.959806f,0.242461f, +-0.277438f,0.935166f,0.220209f, +-0.254545f,0.906523f,0.336782f, +-0.385464f,0.89189f,0.236535f, +-0.346902f,0.887297f,0.303913f, +-0.404152f,0.809818f,0.425271f, +-0.45263f,0.705418f,0.545446f, +-0.436346f,0.733679f,0.520882f, +-0.40606f,0.758487f,0.509719f, +-0.399991f,0.76519f,0.504471f, +-0.29927f,0.789873f,0.535292f, +-0.216265f,0.823324f,0.524754f, +-0.25441f,0.854784f,0.452349f, +-0.0876585f,0.974972f,-0.204317f, +-0.064531f,0.993199f,-0.096908f, +-0.142906f,0.98657f,-0.0790982f, +-0.190225f,0.979959f,-0.0591132f, +-0.245075f,0.966633f,-0.0745641f, +-0.286525f,0.954682f,-0.0805399f, +-0.302328f,0.953201f,0.00253574f, +-0.315251f,0.947498f,0.0535207f, +-0.363913f,0.92013f,0.144666f, +-0.433014f,0.884677f,0.172759f, +-0.39903f,0.904384f,0.151207f, +-0.340877f,0.927749f,0.15194f, +-0.34367f,0.933336f,0.103799f, +-0.371228f,0.927804f,0.0370044f, +-0.540653f,0.838686f,-0.0655789f, +-0.541683f,0.840171f,-0.0263209f, +-0.443789f,0.895468f,-0.0344719f, +-0.446175f,0.894923f,0.00646964f, +-0.489716f,0.870366f,0.0513954f, +-0.393228f,0.91623f,0.0767741f, +-0.386844f,0.914535f,0.118231f, +-0.456614f,0.881467f,0.1205f, +-0.291641f,0.939064f,0.181947f, +-0.0983466f,0.949337f,0.298474f, +-0.0663966f,0.917799f,0.391455f, +-0.225097f,0.912905f,0.340494f, +-0.270333f,0.917625f,0.291349f, +-0.0378823f,0.963845f,0.263756f, +0.203246f,0.94956f,0.238803f, +-0.00658121f,0.998329f,0.057403f, +-0.104339f,0.991332f,-0.0798442f, +0.0714998f,0.99184f,-0.105548f, +0.229254f,0.968801f,-0.0941692f, +0.162963f,0.980447f,-0.110304f, +0.144794f,0.987619f,-0.0603599f, +0.1028f,0.982727f,-0.153883f, +0.103742f,0.981824f,-0.158931f, +0.242509f,0.962807f,-0.119129f, +0.409757f,0.908112f,-0.0862081f, +0.420763f,0.899369f,-0.118717f, +0.356993f,0.920491f,-0.158908f, +0.417923f,0.902816f,-0.101306f, +0.45294f,0.886743f,-0.0923743f, +0.388277f,0.919595f,-0.0598771f, +0.442705f,0.896663f,-0.00260706f, +0.330753f,0.943188f,0.0316099f, +0.0976556f,0.983098f,0.154858f, +-0.0408134f,0.964902f,0.259421f, +-0.0353778f,0.920067f,0.39016f, +-0.0336634f,0.909873f,0.413518f, +-0.27131f,0.928078f,0.255075f, +-0.276299f,0.942343f,0.188808f, +-0.178846f,0.97249f,0.149254f, +-0.173925f,0.95192f,0.252185f, +-0.312455f,0.905292f,0.287781f, +-0.299358f,0.905887f,0.299588f, +-0.361522f,0.88183f,0.302783f, +-0.474485f,0.805519f,0.35497f, +-0.514467f,0.728892f,0.451708f, +-0.495653f,0.729457f,0.471404f, +-0.395267f,0.75904f,0.517322f, +-0.414244f,0.765988f,0.491594f, +-0.375453f,0.800102f,0.467837f, +-0.23686f,0.857078f,0.457509f, +-0.153599f,0.897001f,0.414483f, +-0.139778f,0.900978f,0.410733f, +-0.246424f,0.968956f,-0.0200009f, +-0.187575f,0.975459f,0.115309f, +-0.169324f,0.958565f,0.229092f, +-0.227196f,0.942917f,0.243495f, +-0.216356f,0.935609f,0.278972f, +-0.279085f,0.916546f,0.286453f, +-0.337088f,0.885038f,0.32106f, +-0.317388f,0.891504f,0.323242f, +-0.400555f,0.875243f,0.271117f, +-0.420396f,0.865286f,0.273034f, +-0.438864f,0.863369f,0.248983f, +-0.296161f,0.903481f,0.309855f, +-0.22181f,0.945018f,0.240296f, +-0.217483f,0.959525f,0.178924f, +-0.432196f,0.899705f,0.0611361f, +-0.592514f,0.805005f,-0.029893f, +-0.445437f,0.89528f,0.00770123f, +-0.444106f,0.895735f,-0.0207082f, +-0.441178f,0.89658f,-0.0387967f, +-0.433316f,0.896401f,-0.0932815f, +-0.448061f,0.893999f,-0.00273746f, +-0.479681f,0.876222f,0.046264f, +-0.38049f,0.918735f,0.105607f, +-0.274091f,0.928692f,0.249812f, +-0.115693f,0.919238f,0.37632f, +-0.109076f,0.943601f,0.312601f, +-0.183297f,0.969532f,0.162513f, +-0.0200265f,0.998099f,0.0582807f, +0.217564f,0.969248f,0.114995f, +0.107422f,0.986137f,0.126469f, +-0.0101958f,0.999802f,0.0170616f, +0.0917708f,0.993871f,-0.0616322f, +0.259886f,0.964354f,-0.049807f, +0.22181f,0.965636f,-0.135454f, +0.11068f,0.965795f,-0.234499f, +0.156396f,0.962982f,-0.219561f, +0.0996902f,0.954613f,-0.28067f, +0.240821f,0.930419f,-0.276271f, +0.362585f,0.892287f,-0.268992f, +0.39828f,0.905306f,-0.147629f, +0.377219f,0.92249f,-0.0819651f, +0.379471f,0.918832f,-0.108391f, +0.428571f,0.902988f,-0.0306522f, +0.390587f,0.920304f,0.0219829f, +0.365451f,0.930816f,-0.00527733f, +0.226127f,0.963781f,0.141399f, +-0.014879f,0.969939f,0.242893f, +-0.0990439f,0.938525f,0.330697f, +-0.160986f,0.911469f,0.37856f, +-0.0311141f,0.900531f,0.433676f, +-0.0818559f,0.904519f,0.418503f, +-0.202897f,0.939947f,0.274469f, +-0.199596f,0.951915f,0.232421f, +-0.290928f,0.922977f,0.251942f, +-0.30301f,0.91121f,0.279072f, +-0.315746f,0.908229f,0.274635f, +-0.386173f,0.858884f,0.336435f, +-0.56045f,0.768828f,0.307894f, +-0.529456f,0.742805f,0.409776f, +-0.545227f,0.770059f,0.331265f, +-0.460487f,0.804404f,0.375346f, +-0.384041f,0.835484f,0.393038f, +-0.366328f,0.856374f,0.363907f, +-0.227066f,0.886912f,0.40228f, +-0.162423f,0.896635f,0.411903f, +-0.18398f,0.877261f,0.443356f, +-0.33059f,0.941987f,0.0580528f, +-0.349053f,0.930827f,0.108275f, +-0.250298f,0.937413f,0.242089f, +-0.231173f,0.921233f,0.312871f, +-0.267366f,0.883285f,0.385127f, +-0.300638f,0.858727f,0.414975f, +-0.348846f,0.869854f,0.348799f, +-0.262698f,0.902187f,0.342122f, +-0.319043f,0.887638f,0.33213f, +-0.407631f,0.874264f,0.263628f, +-0.391131f,0.891388f,0.229006f, +-0.306387f,0.939971f,0.150271f, +-0.172289f,0.969062f,0.176734f, +-0.280735f,0.939942f,0.194158f, +-0.35822f,0.876748f,0.320922f, +-0.540223f,0.822439f,0.178196f, +-0.415201f,0.897062f,0.151285f, +-0.398489f,0.913332f,0.0838552f, +-0.47388f,0.879024f,0.052479f, +-0.430994f,0.889287f,0.153011f, +-0.501585f,0.850518f,0.158213f, +-0.493115f,0.843586f,0.212601f, +-0.437044f,0.869936f,0.228482f, +-0.335665f,0.928238f,0.160321f, +-0.135997f,0.987913f,0.0743886f, +0.0115105f,0.995614f,0.0928467f, +-0.0367985f,0.999249f,0.0121783f, +0.0254956f,0.996874f,-0.0747791f, +0.107382f,0.991622f,-0.0717932f, +0.144184f,0.989518f,0.00810907f, +0.0943487f,0.994079f,-0.0539027f, +0.124876f,0.987862f,-0.0923827f, +0.25534f,0.960035f,-0.114602f, +0.339105f,0.927956f,-0.154613f, +0.200588f,0.937015f,-0.285951f, +0.184172f,0.917658f,-0.352115f, +0.137125f,0.909076f,-0.393417f, +0.231522f,0.90798f,-0.349242f, +0.299652f,0.902049f,-0.310671f, +0.23061f,0.944613f,-0.233507f, +0.336481f,0.938772f,-0.0740748f, +0.38792f,0.918977f,-0.070704f, +0.337723f,0.938393f,-0.073227f, +0.392706f,0.919584f,-0.012147f, +0.294051f,0.954956f,-0.0399037f, +0.173344f,0.964432f,0.199555f, +-0.108669f,0.967119f,0.22994f, +-0.18728f,0.925976f,0.327863f, +-0.156223f,0.937505f,0.310931f, +-0.0961609f,0.948752f,0.301037f, +-0.051031f,0.914222f,0.401987f, +-0.116652f,0.921592f,0.370216f, +-0.16747f,0.919727f,0.355044f, +-0.233888f,0.917713f,0.321092f, +-0.296558f,0.924646f,0.23892f, +-0.384099f,0.898594f,0.212122f, +-0.451252f,0.843433f,0.291535f, +-0.561019f,0.766309f,0.313095f, +-0.56702f,0.761029f,0.315156f, +-0.502958f,0.815049f,0.287624f, +-0.46769f,0.845823f,0.256612f, +-0.438846f,0.860082f,0.260142f, +-0.380472f,0.841841f,0.382812f, +-0.286801f,0.84573f,0.449984f, +-0.166497f,0.837941f,0.519744f, +-0.237954f,0.844014f,0.480644f, +-0.400938f,0.907575f,0.124721f, +-0.36178f,0.91645f,0.170983f, +-0.326178f,0.936068f,0.131852f, +-0.348093f,0.925471f,0.149445f, +-0.380521f,0.903785f,0.195901f, +-0.261965f,0.932138f,0.249988f, +-0.229009f,0.957451f,0.175621f, +-0.296226f,0.953377f,0.0576446f, +-0.385007f,0.916429f,0.109216f, +-0.396898f,0.895963f,0.199304f, +-0.30002f,0.927264f,0.223985f, +-0.290512f,0.953204f,0.083697f, +-0.240862f,0.959505f,0.146069f, +-0.368638f,0.900621f,0.230189f, +-0.437205f,0.833732f,0.337256f, +-0.435531f,0.825298f,0.359438f, +-0.382764f,0.869714f,0.311593f, +-0.302351f,0.902083f,0.307944f, +-0.504704f,0.84016f,0.198507f, +-0.44412f,0.839306f,0.313565f, +-0.494888f,0.841296f,0.217503f, +-0.530329f,0.827106f,0.186138f, +-0.314084f,0.933199f,0.174614f, +-0.124034f,0.990967f,0.050983f, +-0.0452003f,0.995178f,-0.0870557f, +-0.00182424f,0.990385f,-0.138326f, +-0.0388611f,0.986686f,-0.157927f, +0.0684221f,0.991564f,-0.11009f, +0.102533f,0.981475f,-0.161848f, +0.149983f,0.975213f,-0.162681f, +0.108711f,0.963953f,-0.24285f, +0.134579f,0.963238f,-0.232511f, +0.280754f,0.932346f,-0.227832f, +0.370391f,0.907723f,-0.197103f, +0.290987f,0.936165f,-0.197286f, +0.244643f,0.947659f,-0.205165f, +0.12819f,0.972148f,-0.196204f, +0.159014f,0.967422f,-0.197002f, +0.312607f,0.930748f,-0.189697f, +0.153027f,0.941997f,-0.298704f, +0.218578f,0.950985f,-0.218748f, +0.390534f,0.915543f,-0.0962525f, +0.350134f,0.933592f,-0.0762398f, +0.369694f,0.928637f,-0.030973f, +0.182224f,0.981373f,0.0608345f, +-0.0452136f,0.980467f,0.191416f, +-0.152401f,0.95767f,0.244216f, +-0.205784f,0.951891f,0.22706f, +-0.112228f,0.971017f,0.211022f, +-0.130106f,0.967854f,0.215247f, +-0.151633f,0.958079f,0.243087f, +-0.104162f,0.953804f,0.281796f, +-0.17561f,0.947845f,0.265989f, +-0.209606f,0.941523f,0.263816f, +-0.251275f,0.930745f,0.265659f, +-0.361f,0.884718f,0.294879f, +-0.50281f,0.813876f,0.291185f, +-0.583247f,0.763934f,0.276094f, +-0.556622f,0.802134f,0.216224f, +-0.473532f,0.851987f,0.223352f, +-0.473757f,0.85285f,0.219548f, +-0.491496f,0.823107f,0.284477f, +-0.477559f,0.793154f,0.377946f, +-0.368868f,0.830921f,0.416542f, +-0.202419f,0.861608f,0.465466f, +-0.095407f,0.855544f,0.508864f, +-0.40239f,0.909528f,0.104118f, +-0.357524f,0.930915f,0.0746555f, +-0.280797f,0.959558f,0.0200349f, +-0.296463f,0.954936f,-0.0143765f, +-0.381172f,0.918388f,-0.106166f, +-0.308734f,0.946435f,-0.094572f, +-0.184864f,0.981918f,-0.0407667f, +-0.211096f,0.97426f,-0.0790985f, +-0.431269f,0.892976f,-0.128847f, +-0.508723f,0.860224f,-0.0348507f, +-0.315588f,0.942693f,0.108326f, +-0.229963f,0.954167f,0.191527f, +-0.338476f,0.90391f,0.261495f, +-0.399866f,0.843393f,0.358882f, +-0.508212f,0.817205f,0.271838f, +-0.45663f,0.829465f,0.321678f, +-0.343829f,0.869846f,0.353765f, +-0.25214f,0.908629f,0.332893f, +-0.465924f,0.864347f,0.189262f, +-0.451321f,0.885092f,0.11367f, +-0.398038f,0.913426f,0.0849568f, +-0.473433f,0.880353f,-0.0289816f, +-0.282123f,0.951018f,-0.126376f, +-0.111297f,0.983512f,-0.142537f, +-0.0203568f,0.995748f,-0.089847f, +0.0177076f,0.998505f,-0.0517153f, +-0.0210973f,0.999746f,0.00787929f, +0.0422415f,0.999104f,-0.00245387f, +0.162083f,0.986673f,-0.0143034f, +0.184873f,0.978111f,-0.0954998f, +0.225836f,0.960454f,-0.162869f, +0.105652f,0.960265f,-0.25832f, +0.22096f,0.965567f,-0.137321f, +0.306187f,0.951906f,0.0111556f, +0.252563f,0.963728f,0.0862585f, +0.185211f,0.975091f,0.122044f, +0.141716f,0.976503f,0.162355f, +0.200688f,0.976886f,0.0736112f, +0.398894f,0.916482f,0.0307355f, +0.27456f,0.96012f,-0.0527967f, +0.152825f,0.971043f,-0.183632f, +0.271211f,0.950001f,-0.154736f, +0.286301f,0.958137f,0.00244849f, +0.246502f,0.96458f,0.0939299f, +0.102065f,0.977178f,0.186298f, +-0.0761105f,0.976837f,0.19999f, +-0.0810786f,0.974651f,0.208524f, +-0.174214f,0.975155f,0.136831f, +-0.127689f,0.983595f,0.127422f, +-0.123239f,0.988203f,0.0909257f, +-0.173027f,0.984333f,0.033919f, +-0.13019f,0.985916f,0.104975f, +-0.151236f,0.977557f,0.146665f, +-0.212082f,0.972216f,0.0990861f, +-0.346196f,0.93167f,0.110181f, +-0.461867f,0.845088f,0.269268f, +-0.491314f,0.790968f,0.364663f, +-0.499721f,0.798886f,0.334753f, +-0.533877f,0.823302f,0.192741f, +-0.489959f,0.855912f,0.165393f, +-0.540105f,0.823669f,0.172786f, +-0.55174f,0.789596f,0.268553f, +-0.518837f,0.818462f,0.246838f, +-0.35793f,0.879679f,0.31313f, +-0.226645f,0.914368f,0.335505f, +-0.174062f,0.93173f,0.31872f, +-0.352372f,0.928926f,-0.113715f, +-0.283164f,0.949292f,-0.13661f, +-0.253833f,0.949289f,-0.185523f, +-0.258433f,0.953837f,-0.152994f, +-0.329686f,0.925665f,-0.185613f, +-0.360482f,0.913899f,-0.186657f, +-0.246398f,0.964945f,-0.0903879f, +-0.197613f,0.98019f,0.013309f, +-0.409684f,0.910684f,0.0530475f, +-0.545574f,0.83677f,0.0465257f, +-0.477964f,0.876264f,0.060934f, +-0.386247f,0.882258f,0.269135f, +-0.437443f,0.816448f,0.376904f, +-0.381546f,0.830459f,0.405906f, +-0.378931f,0.857772f,0.347329f, +-0.484349f,0.854204f,0.189053f, +-0.391934f,0.899277f,0.194136f, +-0.180618f,0.947297f,0.264585f, +-0.285059f,0.943094f,0.171219f, +-0.41449f,0.905591f,-0.0900102f, +-0.367364f,0.916679f,-0.157298f, +-0.4046f,0.892318f,-0.200168f, +-0.265207f,0.933534f,-0.241204f, +-0.171437f,0.970625f,-0.168809f, +-0.091648f,0.995789f,0.00231266f, +-0.0988725f,0.989781f,0.102747f, +-0.0749525f,0.978356f,0.192877f, +0.0618361f,0.988236f,0.139875f, +0.222758f,0.971067f,0.0860673f, +0.260459f,0.965435f,-0.00983276f, +0.296216f,0.954928f,-0.0191894f, +0.108089f,0.992937f,-0.0489145f, +0.0559635f,0.998425f,-0.00391097f, +0.182072f,0.980129f,0.0787236f, +0.189029f,0.972269f,0.137697f, +0.20292f,0.962368f,0.180751f, +0.162611f,0.977583f,0.133749f, +0.283117f,0.944546f,0.166365f, +0.362781f,0.917623f,0.162352f, +0.322808f,0.912852f,0.249991f, +0.306817f,0.930382f,0.200629f, +0.265368f,0.963264f,0.0412725f, +0.150516f,0.988588f,0.00624705f, +0.192187f,0.980013f,0.0513622f, +0.111093f,0.98864f,0.101236f, +-0.0652663f,0.990994f,0.116922f, +-0.0960853f,0.989279f,0.109972f, +-0.171018f,0.980514f,0.0966674f, +-0.118023f,0.981194f,0.152737f, +-0.0297124f,0.980668f,0.19341f, +-0.130364f,0.983461f,0.125733f, +-0.228583f,0.970632f,0.0749913f, +-0.187681f,0.973906f,0.127608f, +-0.18184f,0.968481f,0.170233f, +-0.382626f,0.904754f,0.187128f, +-0.565004f,0.795638f,0.218473f, +-0.54964f,0.808473f,0.210397f, +-0.494188f,0.848001f,0.191501f, +-0.42417f,0.88632f,0.185785f, +-0.490729f,0.864039f,0.112346f, +-0.547278f,0.819965f,0.167765f, +-0.555649f,0.823683f,0.113141f, +-0.525063f,0.850181f,0.0387426f, +-0.465555f,0.881687f,0.0767294f, +-0.25104f,0.948586f,0.19278f, +-0.134177f,0.968986f,0.207515f, +-0.358148f,0.879839f,-0.31243f, +-0.281248f,0.911984f,-0.298639f, +-0.261128f,0.923339f,-0.281526f, +-0.281121f,0.935581f,-0.213678f, +-0.316696f,0.928992f,-0.191515f, +-0.378661f,0.908066f,-0.178974f, +-0.357733f,0.923356f,-0.139433f, +-0.295419f,0.953886f,0.0531873f, +-0.456379f,0.869265f,0.18999f, +-0.492836f,0.836159f,0.240731f, +-0.533039f,0.832034f,0.153586f, +-0.471339f,0.822176f,0.319166f, +-0.417097f,0.817012f,0.398149f, +-0.397475f,0.860419f,0.318894f, +-0.295585f,0.889222f,0.349162f, +-0.397825f,0.896297f,0.195927f, +-0.426121f,0.903442f,0.0470364f, +-0.225108f,0.967792f,0.11272f, +-0.180332f,0.969123f,0.168172f, +-0.283694f,0.958436f,-0.0303046f, +-0.31011f,0.929142f,-0.201316f, +-0.379988f,0.880118f,-0.284609f, +-0.280631f,0.91033f,-0.304213f, +-0.299273f,0.919298f,-0.255591f, +-0.271669f,0.962178f,0.0202533f, +-0.127278f,0.946024f,0.298058f, +-0.0668081f,0.957542f,0.280447f, +0.156177f,0.962373f,0.222366f, +0.269377f,0.960799f,0.0655824f, +0.307217f,0.951527f,-0.0146071f, +0.247019f,0.968029f,-0.0436127f, +0.117286f,0.99106f,0.0635867f, +0.0498813f,0.996011f,0.0739844f, +0.194956f,0.980335f,0.0305971f, +0.139483f,0.989424f,-0.0398183f, +0.235447f,0.970519f,0.0515568f, +0.132445f,0.989845f,-0.05162f, +0.206421f,0.976844f,0.0562743f, +0.330371f,0.919083f,0.214804f, +0.266375f,0.922982f,0.277756f, +0.331232f,0.885792f,0.325049f, +0.36267f,0.895106f,0.259337f, +0.240431f,0.963714f,0.115964f, +0.171746f,0.982113f,-0.0771883f, +0.0351621f,0.99889f,-0.0313443f, +-0.0882653f,0.987488f,0.130674f, +-0.0658856f,0.986287f,0.151318f, +-0.167193f,0.982329f,0.0841182f, +-0.21476f,0.97234f,0.0918338f, +-0.104496f,0.958461f,0.265392f, +-0.0605561f,0.923444f,0.378926f, +-0.152497f,0.949101f,0.275594f, +-0.216118f,0.964594f,0.151167f, +-0.26219f,0.945639f,0.192413f, +-0.408309f,0.854572f,0.320922f, +-0.530012f,0.797788f,0.28744f, +-0.48417f,0.855541f,0.183383f, +-0.504616f,0.863257f,0.012294f, +-0.421367f,0.905956f,0.0411587f, +-0.517653f,0.855189f,0.0262018f, +-0.533316f,0.826853f,0.178574f, +-0.514944f,0.854185f,0.0721125f, +-0.506113f,0.861889f,-0.0315744f, +-0.499639f,0.865958f,-0.0218358f, +-0.302149f,0.952465f,0.038937f, +-0.129933f,0.988738f,0.0742583f, +}; + +btScalar Landscape02Tex[] = { +0.0f,0.273438f, +0.0f,0.265625f, +0.0078125f,0.273438f, +0.0078125f,0.265625f, +0.015625f,0.273438f, +0.015625f,0.265625f, +0.0234375f,0.273438f, +0.0234375f,0.265625f, +0.03125f,0.273438f, +0.03125f,0.265625f, +0.0390625f,0.273438f, +0.0390625f,0.265625f, +0.046875f,0.273438f, +0.046875f,0.265625f, +0.0546875f,0.273438f, +0.0546875f,0.265625f, +0.0625f,0.273438f, +0.0625f,0.265625f, +0.0703125f,0.273438f, +0.0703125f,0.265625f, +0.078125f,0.273438f, +0.078125f,0.265625f, +0.0859375f,0.273438f, +0.0859375f,0.265625f, +0.09375f,0.273438f, +0.09375f,0.265625f, +0.101563f,0.273438f, +0.101563f,0.265625f, +0.109375f,0.273438f, +0.109375f,0.265625f, +0.117188f,0.273438f, +0.117188f,0.265625f, +0.125f,0.273438f, +0.125f,0.265625f, +0.132813f,0.273438f, +0.132813f,0.265625f, +0.140625f,0.273438f, +0.140625f,0.265625f, +0.148438f,0.273438f, +0.148438f,0.265625f, +0.15625f,0.273438f, +0.15625f,0.265625f, +0.164063f,0.273438f, +0.164063f,0.265625f, +0.171875f,0.273438f, +0.171875f,0.265625f, +0.179688f,0.273438f, +0.179688f,0.265625f, +0.1875f,0.273438f, +0.1875f,0.265625f, +0.195313f,0.273438f, +0.195313f,0.265625f, +0.203125f,0.273438f, +0.203125f,0.265625f, +0.210938f,0.273438f, +0.210938f,0.265625f, +0.21875f,0.273438f, +0.21875f,0.265625f, +0.226563f,0.273438f, +0.226563f,0.265625f, +0.234375f,0.273438f, +0.234375f,0.265625f, +0.242188f,0.273438f, +0.242188f,0.265625f, +0.25f,0.273438f, +0.25f,0.265625f, +0.257813f,0.273438f, +0.257813f,0.265625f, +0.265625f,0.273438f, +0.265625f,0.265625f, +0.273438f,0.273438f, +0.273438f,0.265625f, +0.28125f,0.273438f, +0.28125f,0.265625f, +0.289063f,0.273438f, +0.289063f,0.265625f, +0.296875f,0.273438f, +0.296875f,0.265625f, +0.304688f,0.273438f, +0.304688f,0.265625f, +0.3125f,0.273438f, +0.3125f,0.265625f, +0.320313f,0.273438f, +0.320313f,0.265625f, +0.328125f,0.273438f, +0.328125f,0.265625f, +0.335938f,0.273438f, +0.335938f,0.265625f, +0.34375f,0.273438f, +0.34375f,0.265625f, +0.351563f,0.273438f, +0.351563f,0.265625f, +0.359375f,0.273438f, +0.359375f,0.265625f, +0.367188f,0.273438f, +0.367188f,0.265625f, +0.375f,0.273438f, +0.375f,0.265625f, +0.382813f,0.273438f, +0.382813f,0.265625f, +0.390625f,0.273438f, +0.390625f,0.265625f, +0.398438f,0.273438f, +0.398438f,0.265625f, +0.40625f,0.273438f, +0.40625f,0.265625f, +0.414063f,0.273438f, +0.414063f,0.265625f, +0.421875f,0.273438f, +0.421875f,0.265625f, +0.429688f,0.273438f, +0.429688f,0.265625f, +0.4375f,0.273438f, +0.4375f,0.265625f, +0.445313f,0.273438f, +0.445313f,0.265625f, +0.453125f,0.273438f, +0.453125f,0.265625f, +0.460938f,0.273438f, +0.460938f,0.265625f, +0.46875f,0.273438f, +0.46875f,0.265625f, +0.476563f,0.273438f, +0.476563f,0.265625f, +0.484375f,0.273438f, +0.484375f,0.265625f, +0.492188f,0.273438f, +0.492188f,0.265625f, +0.5f,0.273438f, +0.5f,0.265625f, +0.507813f,0.273438f, +0.507813f,0.265625f, +0.0f,0.28125f, +0.0078125f,0.28125f, +0.015625f,0.28125f, +0.0234375f,0.28125f, +0.03125f,0.28125f, +0.0390625f,0.28125f, +0.046875f,0.28125f, +0.0546875f,0.28125f, +0.0625f,0.28125f, +0.0703125f,0.28125f, +0.078125f,0.28125f, +0.0859375f,0.28125f, +0.09375f,0.28125f, +0.101563f,0.28125f, +0.109375f,0.28125f, +0.117188f,0.28125f, +0.125f,0.28125f, +0.132813f,0.28125f, +0.140625f,0.28125f, +0.148438f,0.28125f, +0.15625f,0.28125f, +0.164063f,0.28125f, +0.171875f,0.28125f, +0.179688f,0.28125f, +0.1875f,0.28125f, +0.195313f,0.28125f, +0.203125f,0.28125f, +0.210938f,0.28125f, +0.21875f,0.28125f, +0.226563f,0.28125f, +0.234375f,0.28125f, +0.242188f,0.28125f, +0.25f,0.28125f, +0.257813f,0.28125f, +0.265625f,0.28125f, +0.273438f,0.28125f, +0.28125f,0.28125f, +0.289063f,0.28125f, +0.296875f,0.28125f, +0.304688f,0.28125f, +0.3125f,0.28125f, +0.320313f,0.28125f, +0.328125f,0.28125f, +0.335938f,0.28125f, +0.34375f,0.28125f, +0.351563f,0.28125f, +0.359375f,0.28125f, +0.367188f,0.28125f, +0.375f,0.28125f, +0.382813f,0.28125f, +0.390625f,0.28125f, +0.398438f,0.28125f, +0.40625f,0.28125f, +0.414063f,0.28125f, +0.421875f,0.28125f, +0.429688f,0.28125f, +0.4375f,0.28125f, +0.445313f,0.28125f, +0.453125f,0.28125f, +0.460938f,0.28125f, +0.46875f,0.28125f, +0.476563f,0.28125f, +0.484375f,0.28125f, +0.492188f,0.28125f, +0.5f,0.28125f, +0.507813f,0.28125f, +0.0f,0.289063f, +0.0078125f,0.289063f, +0.015625f,0.289063f, +0.0234375f,0.289063f, +0.03125f,0.289063f, +0.0390625f,0.289063f, +0.046875f,0.289063f, +0.0546875f,0.289063f, +0.0625f,0.289063f, +0.0703125f,0.289063f, +0.078125f,0.289063f, +0.0859375f,0.289063f, +0.09375f,0.289063f, +0.101563f,0.289063f, +0.109375f,0.289063f, +0.117188f,0.289063f, +0.125f,0.289063f, +0.132813f,0.289063f, +0.140625f,0.289063f, +0.148438f,0.289063f, +0.15625f,0.289063f, +0.164063f,0.289063f, +0.171875f,0.289063f, +0.179688f,0.289063f, +0.1875f,0.289063f, +0.195313f,0.289063f, +0.203125f,0.289063f, +0.210938f,0.289063f, +0.21875f,0.289063f, +0.226563f,0.289063f, +0.234375f,0.289063f, +0.242188f,0.289063f, +0.25f,0.289063f, +0.257813f,0.289063f, +0.265625f,0.289063f, +0.273438f,0.289063f, +0.28125f,0.289063f, +0.289063f,0.289063f, +0.296875f,0.289063f, +0.304688f,0.289063f, +0.3125f,0.289063f, +0.320313f,0.289063f, +0.328125f,0.289063f, +0.335938f,0.289063f, +0.34375f,0.289063f, +0.351563f,0.289063f, +0.359375f,0.289063f, +0.367188f,0.289063f, +0.375f,0.289063f, +0.382813f,0.289063f, +0.390625f,0.289063f, +0.398438f,0.289063f, +0.40625f,0.289063f, +0.414063f,0.289063f, +0.421875f,0.289063f, +0.429688f,0.289063f, +0.4375f,0.289063f, +0.445313f,0.289063f, +0.453125f,0.289063f, +0.460938f,0.289063f, +0.46875f,0.289063f, +0.476563f,0.289063f, +0.484375f,0.289063f, +0.492188f,0.289063f, +0.5f,0.289063f, +0.507813f,0.289063f, +0.0f,0.296875f, +0.0078125f,0.296875f, +0.015625f,0.296875f, +0.0234375f,0.296875f, +0.03125f,0.296875f, +0.0390625f,0.296875f, +0.046875f,0.296875f, +0.0546875f,0.296875f, +0.0625f,0.296875f, +0.0703125f,0.296875f, +0.078125f,0.296875f, +0.0859375f,0.296875f, +0.09375f,0.296875f, +0.101563f,0.296875f, +0.109375f,0.296875f, +0.117188f,0.296875f, +0.125f,0.296875f, +0.132813f,0.296875f, +0.140625f,0.296875f, +0.148438f,0.296875f, +0.15625f,0.296875f, +0.164063f,0.296875f, +0.171875f,0.296875f, +0.179688f,0.296875f, +0.1875f,0.296875f, +0.195313f,0.296875f, +0.203125f,0.296875f, +0.210938f,0.296875f, +0.21875f,0.296875f, +0.226563f,0.296875f, +0.234375f,0.296875f, +0.242188f,0.296875f, +0.25f,0.296875f, +0.257813f,0.296875f, +0.265625f,0.296875f, +0.273438f,0.296875f, +0.28125f,0.296875f, +0.289063f,0.296875f, +0.296875f,0.296875f, +0.304688f,0.296875f, +0.3125f,0.296875f, +0.320313f,0.296875f, +0.328125f,0.296875f, +0.335938f,0.296875f, +0.34375f,0.296875f, +0.351563f,0.296875f, +0.359375f,0.296875f, +0.367188f,0.296875f, +0.375f,0.296875f, +0.382813f,0.296875f, +0.390625f,0.296875f, +0.398438f,0.296875f, +0.40625f,0.296875f, +0.414063f,0.296875f, +0.421875f,0.296875f, +0.429688f,0.296875f, +0.4375f,0.296875f, +0.445313f,0.296875f, +0.453125f,0.296875f, +0.460938f,0.296875f, +0.46875f,0.296875f, +0.476563f,0.296875f, +0.484375f,0.296875f, +0.492188f,0.296875f, +0.5f,0.296875f, +0.507813f,0.296875f, +0.0f,0.304688f, +0.0078125f,0.304688f, +0.015625f,0.304688f, +0.0234375f,0.304688f, +0.03125f,0.304688f, +0.0390625f,0.304688f, +0.046875f,0.304688f, +0.0546875f,0.304688f, +0.0625f,0.304688f, +0.0703125f,0.304688f, +0.078125f,0.304688f, +0.0859375f,0.304688f, +0.09375f,0.304688f, +0.101563f,0.304688f, +0.109375f,0.304688f, +0.117188f,0.304688f, +0.125f,0.304688f, +0.132813f,0.304688f, +0.140625f,0.304688f, +0.148438f,0.304688f, +0.15625f,0.304688f, +0.164063f,0.304688f, +0.171875f,0.304688f, +0.179688f,0.304688f, +0.1875f,0.304688f, +0.195313f,0.304688f, +0.203125f,0.304688f, +0.210938f,0.304688f, +0.21875f,0.304688f, +0.226563f,0.304688f, +0.234375f,0.304688f, +0.242188f,0.304688f, +0.25f,0.304688f, +0.257813f,0.304688f, +0.265625f,0.304688f, +0.273438f,0.304688f, +0.28125f,0.304688f, +0.289063f,0.304688f, +0.296875f,0.304688f, +0.304688f,0.304688f, +0.3125f,0.304688f, +0.320313f,0.304688f, +0.328125f,0.304688f, +0.335938f,0.304688f, +0.34375f,0.304688f, +0.351563f,0.304688f, +0.359375f,0.304688f, +0.367188f,0.304688f, +0.375f,0.304688f, +0.382813f,0.304688f, +0.390625f,0.304688f, +0.398438f,0.304688f, +0.40625f,0.304688f, +0.414063f,0.304688f, +0.421875f,0.304688f, +0.429688f,0.304688f, +0.4375f,0.304688f, +0.445313f,0.304688f, +0.453125f,0.304688f, +0.460938f,0.304688f, +0.46875f,0.304688f, +0.476563f,0.304688f, +0.484375f,0.304688f, +0.492188f,0.304688f, +0.5f,0.304688f, +0.507813f,0.304688f, +0.0f,0.3125f, +0.0078125f,0.3125f, +0.015625f,0.3125f, +0.0234375f,0.3125f, +0.03125f,0.3125f, +0.0390625f,0.3125f, +0.046875f,0.3125f, +0.0546875f,0.3125f, +0.0625f,0.3125f, +0.0703125f,0.3125f, +0.078125f,0.3125f, +0.0859375f,0.3125f, +0.09375f,0.3125f, +0.101563f,0.3125f, +0.109375f,0.3125f, +0.117188f,0.3125f, +0.125f,0.3125f, +0.132813f,0.3125f, +0.140625f,0.3125f, +0.148438f,0.3125f, +0.15625f,0.3125f, +0.164063f,0.3125f, +0.171875f,0.3125f, +0.179688f,0.3125f, +0.1875f,0.3125f, +0.195313f,0.3125f, +0.203125f,0.3125f, +0.210938f,0.3125f, +0.21875f,0.3125f, +0.226563f,0.3125f, +0.234375f,0.3125f, +0.242188f,0.3125f, +0.25f,0.3125f, +0.257813f,0.3125f, +0.265625f,0.3125f, +0.273438f,0.3125f, +0.28125f,0.3125f, +0.289063f,0.3125f, +0.296875f,0.3125f, +0.304688f,0.3125f, +0.3125f,0.3125f, +0.320313f,0.3125f, +0.328125f,0.3125f, +0.335938f,0.3125f, +0.34375f,0.3125f, +0.351563f,0.3125f, +0.359375f,0.3125f, +0.367188f,0.3125f, +0.375f,0.3125f, +0.382813f,0.3125f, +0.390625f,0.3125f, +0.398438f,0.3125f, +0.40625f,0.3125f, +0.414063f,0.3125f, +0.421875f,0.3125f, +0.429688f,0.3125f, +0.4375f,0.3125f, +0.445313f,0.3125f, +0.453125f,0.3125f, +0.460938f,0.3125f, +0.46875f,0.3125f, +0.476563f,0.3125f, +0.484375f,0.3125f, +0.492188f,0.3125f, +0.5f,0.3125f, +0.507813f,0.3125f, +0.0f,0.320313f, +0.0078125f,0.320313f, +0.015625f,0.320313f, +0.0234375f,0.320313f, +0.03125f,0.320313f, +0.0390625f,0.320313f, +0.046875f,0.320313f, +0.0546875f,0.320313f, +0.0625f,0.320313f, +0.0703125f,0.320313f, +0.078125f,0.320313f, +0.0859375f,0.320313f, +0.09375f,0.320313f, +0.101563f,0.320313f, +0.109375f,0.320313f, +0.117188f,0.320313f, +0.125f,0.320313f, +0.132813f,0.320313f, +0.140625f,0.320313f, +0.148438f,0.320313f, +0.15625f,0.320313f, +0.164063f,0.320313f, +0.171875f,0.320313f, +0.179688f,0.320313f, +0.1875f,0.320313f, +0.195313f,0.320313f, +0.203125f,0.320313f, +0.210938f,0.320313f, +0.21875f,0.320313f, +0.226563f,0.320313f, +0.234375f,0.320313f, +0.242188f,0.320313f, +0.25f,0.320313f, +0.257813f,0.320313f, +0.265625f,0.320313f, +0.273438f,0.320313f, +0.28125f,0.320313f, +0.289063f,0.320313f, +0.296875f,0.320313f, +0.304688f,0.320313f, +0.3125f,0.320313f, +0.320313f,0.320313f, +0.328125f,0.320313f, +0.335938f,0.320313f, +0.34375f,0.320313f, +0.351563f,0.320313f, +0.359375f,0.320313f, +0.367188f,0.320313f, +0.375f,0.320313f, +0.382813f,0.320313f, +0.390625f,0.320313f, +0.398438f,0.320313f, +0.40625f,0.320313f, +0.414063f,0.320313f, +0.421875f,0.320313f, +0.429688f,0.320313f, +0.4375f,0.320313f, +0.445313f,0.320313f, +0.453125f,0.320313f, +0.460938f,0.320313f, +0.46875f,0.320313f, +0.476563f,0.320313f, +0.484375f,0.320313f, +0.492188f,0.320313f, +0.5f,0.320313f, +0.507813f,0.320313f, +0.0f,0.328125f, +0.0078125f,0.328125f, +0.015625f,0.328125f, +0.0234375f,0.328125f, +0.03125f,0.328125f, +0.0390625f,0.328125f, +0.046875f,0.328125f, +0.0546875f,0.328125f, +0.0625f,0.328125f, +0.0703125f,0.328125f, +0.078125f,0.328125f, +0.0859375f,0.328125f, +0.09375f,0.328125f, +0.101563f,0.328125f, +0.109375f,0.328125f, +0.117188f,0.328125f, +0.125f,0.328125f, +0.132813f,0.328125f, +0.140625f,0.328125f, +0.148438f,0.328125f, +0.15625f,0.328125f, +0.164063f,0.328125f, +0.171875f,0.328125f, +0.179688f,0.328125f, +0.1875f,0.328125f, +0.195313f,0.328125f, +0.203125f,0.328125f, +0.210938f,0.328125f, +0.21875f,0.328125f, +0.226563f,0.328125f, +0.234375f,0.328125f, +0.242188f,0.328125f, +0.25f,0.328125f, +0.257813f,0.328125f, +0.265625f,0.328125f, +0.273438f,0.328125f, +0.28125f,0.328125f, +0.289063f,0.328125f, +0.296875f,0.328125f, +0.304688f,0.328125f, +0.3125f,0.328125f, +0.320313f,0.328125f, +0.328125f,0.328125f, +0.335938f,0.328125f, +0.34375f,0.328125f, +0.351563f,0.328125f, +0.359375f,0.328125f, +0.367188f,0.328125f, +0.375f,0.328125f, +0.382813f,0.328125f, +0.390625f,0.328125f, +0.398438f,0.328125f, +0.40625f,0.328125f, +0.414063f,0.328125f, +0.421875f,0.328125f, +0.429688f,0.328125f, +0.4375f,0.328125f, +0.445313f,0.328125f, +0.453125f,0.328125f, +0.460938f,0.328125f, +0.46875f,0.328125f, +0.476563f,0.328125f, +0.484375f,0.328125f, +0.492188f,0.328125f, +0.5f,0.328125f, +0.507813f,0.328125f, +0.0f,0.335938f, +0.0078125f,0.335938f, +0.015625f,0.335938f, +0.0234375f,0.335938f, +0.03125f,0.335938f, +0.0390625f,0.335938f, +0.046875f,0.335938f, +0.0546875f,0.335938f, +0.0625f,0.335938f, +0.0703125f,0.335938f, +0.078125f,0.335938f, +0.0859375f,0.335938f, +0.09375f,0.335938f, +0.101563f,0.335938f, +0.109375f,0.335938f, +0.117188f,0.335938f, +0.125f,0.335938f, +0.132813f,0.335938f, +0.140625f,0.335938f, +0.148438f,0.335938f, +0.15625f,0.335938f, +0.164063f,0.335938f, +0.171875f,0.335938f, +0.179688f,0.335938f, +0.1875f,0.335938f, +0.195313f,0.335938f, +0.203125f,0.335938f, +0.210938f,0.335938f, +0.21875f,0.335938f, +0.226563f,0.335938f, +0.234375f,0.335938f, +0.242188f,0.335938f, +0.25f,0.335938f, +0.257813f,0.335938f, +0.265625f,0.335938f, +0.273438f,0.335938f, +0.28125f,0.335938f, +0.289063f,0.335938f, +0.296875f,0.335938f, +0.304688f,0.335938f, +0.3125f,0.335938f, +0.320313f,0.335938f, +0.328125f,0.335938f, +0.335938f,0.335938f, +0.34375f,0.335938f, +0.351563f,0.335938f, +0.359375f,0.335938f, +0.367188f,0.335938f, +0.375f,0.335938f, +0.382813f,0.335938f, +0.390625f,0.335938f, +0.398438f,0.335938f, +0.40625f,0.335938f, +0.414063f,0.335938f, +0.421875f,0.335938f, +0.429688f,0.335938f, +0.4375f,0.335938f, +0.445313f,0.335938f, +0.453125f,0.335938f, +0.460938f,0.335938f, +0.46875f,0.335938f, +0.476563f,0.335938f, +0.484375f,0.335938f, +0.492188f,0.335938f, +0.5f,0.335938f, +0.507813f,0.335938f, +0.0f,0.34375f, +0.0078125f,0.34375f, +0.015625f,0.34375f, +0.0234375f,0.34375f, +0.03125f,0.34375f, +0.0390625f,0.34375f, +0.046875f,0.34375f, +0.0546875f,0.34375f, +0.0625f,0.34375f, +0.0703125f,0.34375f, +0.078125f,0.34375f, +0.0859375f,0.34375f, +0.09375f,0.34375f, +0.101563f,0.34375f, +0.109375f,0.34375f, +0.117188f,0.34375f, +0.125f,0.34375f, +0.132813f,0.34375f, +0.140625f,0.34375f, +0.148438f,0.34375f, +0.15625f,0.34375f, +0.164063f,0.34375f, +0.171875f,0.34375f, +0.179688f,0.34375f, +0.1875f,0.34375f, +0.195313f,0.34375f, +0.203125f,0.34375f, +0.210938f,0.34375f, +0.21875f,0.34375f, +0.226563f,0.34375f, +0.234375f,0.34375f, +0.242188f,0.34375f, +0.25f,0.34375f, +0.257813f,0.34375f, +0.265625f,0.34375f, +0.273438f,0.34375f, +0.28125f,0.34375f, +0.289063f,0.34375f, +0.296875f,0.34375f, +0.304688f,0.34375f, +0.3125f,0.34375f, +0.320313f,0.34375f, +0.328125f,0.34375f, +0.335938f,0.34375f, +0.34375f,0.34375f, +0.351563f,0.34375f, +0.359375f,0.34375f, +0.367188f,0.34375f, +0.375f,0.34375f, +0.382813f,0.34375f, +0.390625f,0.34375f, +0.398438f,0.34375f, +0.40625f,0.34375f, +0.414063f,0.34375f, +0.421875f,0.34375f, +0.429688f,0.34375f, +0.4375f,0.34375f, +0.445313f,0.34375f, +0.453125f,0.34375f, +0.460938f,0.34375f, +0.46875f,0.34375f, +0.476563f,0.34375f, +0.484375f,0.34375f, +0.492188f,0.34375f, +0.5f,0.34375f, +0.507813f,0.34375f, +0.0f,0.351563f, +0.0078125f,0.351563f, +0.015625f,0.351563f, +0.0234375f,0.351563f, +0.03125f,0.351563f, +0.0390625f,0.351563f, +0.046875f,0.351563f, +0.0546875f,0.351563f, +0.0625f,0.351563f, +0.0703125f,0.351563f, +0.078125f,0.351563f, +0.0859375f,0.351563f, +0.09375f,0.351563f, +0.101563f,0.351563f, +0.109375f,0.351563f, +0.117188f,0.351563f, +0.125f,0.351563f, +0.132813f,0.351563f, +0.140625f,0.351563f, +0.148438f,0.351563f, +0.15625f,0.351563f, +0.164063f,0.351563f, +0.171875f,0.351563f, +0.179688f,0.351563f, +0.1875f,0.351563f, +0.195313f,0.351563f, +0.203125f,0.351563f, +0.210938f,0.351563f, +0.21875f,0.351563f, +0.226563f,0.351563f, +0.234375f,0.351563f, +0.242188f,0.351563f, +0.25f,0.351563f, +0.257813f,0.351563f, +0.265625f,0.351563f, +0.273438f,0.351563f, +0.28125f,0.351563f, +0.289063f,0.351563f, +0.296875f,0.351563f, +0.304688f,0.351563f, +0.3125f,0.351563f, +0.320313f,0.351563f, +0.328125f,0.351563f, +0.335938f,0.351563f, +0.34375f,0.351563f, +0.351563f,0.351563f, +0.359375f,0.351563f, +0.367188f,0.351563f, +0.375f,0.351563f, +0.382813f,0.351563f, +0.390625f,0.351563f, +0.398438f,0.351563f, +0.40625f,0.351563f, +0.414063f,0.351563f, +0.421875f,0.351563f, +0.429688f,0.351563f, +0.4375f,0.351563f, +0.445313f,0.351563f, +0.453125f,0.351563f, +0.460938f,0.351563f, +0.46875f,0.351563f, +0.476563f,0.351563f, +0.484375f,0.351563f, +0.492188f,0.351563f, +0.5f,0.351563f, +0.507813f,0.351563f, +0.0f,0.359375f, +0.0078125f,0.359375f, +0.015625f,0.359375f, +0.0234375f,0.359375f, +0.03125f,0.359375f, +0.0390625f,0.359375f, +0.046875f,0.359375f, +0.0546875f,0.359375f, +0.0625f,0.359375f, +0.0703125f,0.359375f, +0.078125f,0.359375f, +0.0859375f,0.359375f, +0.09375f,0.359375f, +0.101563f,0.359375f, +0.109375f,0.359375f, +0.117188f,0.359375f, +0.125f,0.359375f, +0.132813f,0.359375f, +0.140625f,0.359375f, +0.148438f,0.359375f, +0.15625f,0.359375f, +0.164063f,0.359375f, +0.171875f,0.359375f, +0.179688f,0.359375f, +0.1875f,0.359375f, +0.195313f,0.359375f, +0.203125f,0.359375f, +0.210938f,0.359375f, +0.21875f,0.359375f, +0.226563f,0.359375f, +0.234375f,0.359375f, +0.242188f,0.359375f, +0.25f,0.359375f, +0.257813f,0.359375f, +0.265625f,0.359375f, +0.273438f,0.359375f, +0.28125f,0.359375f, +0.289063f,0.359375f, +0.296875f,0.359375f, +0.304688f,0.359375f, +0.3125f,0.359375f, +0.320313f,0.359375f, +0.328125f,0.359375f, +0.335938f,0.359375f, +0.34375f,0.359375f, +0.351563f,0.359375f, +0.359375f,0.359375f, +0.367188f,0.359375f, +0.375f,0.359375f, +0.382813f,0.359375f, +0.390625f,0.359375f, +0.398438f,0.359375f, +0.40625f,0.359375f, +0.414063f,0.359375f, +0.421875f,0.359375f, +0.429688f,0.359375f, +0.4375f,0.359375f, +0.445313f,0.359375f, +0.453125f,0.359375f, +0.460938f,0.359375f, +0.46875f,0.359375f, +0.476563f,0.359375f, +0.484375f,0.359375f, +0.492188f,0.359375f, +0.5f,0.359375f, +0.507813f,0.359375f, +0.0f,0.367188f, +0.0078125f,0.367188f, +0.015625f,0.367188f, +0.0234375f,0.367188f, +0.03125f,0.367188f, +0.0390625f,0.367188f, +0.046875f,0.367188f, +0.0546875f,0.367188f, +0.0625f,0.367188f, +0.0703125f,0.367188f, +0.078125f,0.367188f, +0.0859375f,0.367188f, +0.09375f,0.367188f, +0.101563f,0.367188f, +0.109375f,0.367188f, +0.117188f,0.367188f, +0.125f,0.367188f, +0.132813f,0.367188f, +0.140625f,0.367188f, +0.148438f,0.367188f, +0.15625f,0.367188f, +0.164063f,0.367188f, +0.171875f,0.367188f, +0.179688f,0.367188f, +0.1875f,0.367188f, +0.195313f,0.367188f, +0.203125f,0.367188f, +0.210938f,0.367188f, +0.21875f,0.367188f, +0.226563f,0.367188f, +0.234375f,0.367188f, +0.242188f,0.367188f, +0.25f,0.367188f, +0.257813f,0.367188f, +0.265625f,0.367188f, +0.273438f,0.367188f, +0.28125f,0.367188f, +0.289063f,0.367188f, +0.296875f,0.367188f, +0.304688f,0.367188f, +0.3125f,0.367188f, +0.320313f,0.367188f, +0.328125f,0.367188f, +0.335938f,0.367188f, +0.34375f,0.367188f, +0.351563f,0.367188f, +0.359375f,0.367188f, +0.367188f,0.367188f, +0.375f,0.367188f, +0.382813f,0.367188f, +0.390625f,0.367188f, +0.398438f,0.367188f, +0.40625f,0.367188f, +0.414063f,0.367188f, +0.421875f,0.367188f, +0.429688f,0.367188f, +0.4375f,0.367188f, +0.445313f,0.367188f, +0.453125f,0.367188f, +0.460938f,0.367188f, +0.46875f,0.367188f, +0.476563f,0.367188f, +0.484375f,0.367188f, +0.492188f,0.367188f, +0.5f,0.367188f, +0.507813f,0.367188f, +0.0f,0.375f, +0.0078125f,0.375f, +0.015625f,0.375f, +0.0234375f,0.375f, +0.03125f,0.375f, +0.0390625f,0.375f, +0.046875f,0.375f, +0.0546875f,0.375f, +0.0625f,0.375f, +0.0703125f,0.375f, +0.078125f,0.375f, +0.0859375f,0.375f, +0.09375f,0.375f, +0.101563f,0.375f, +0.109375f,0.375f, +0.117188f,0.375f, +0.125f,0.375f, +0.132813f,0.375f, +0.140625f,0.375f, +0.148438f,0.375f, +0.15625f,0.375f, +0.164063f,0.375f, +0.171875f,0.375f, +0.179688f,0.375f, +0.1875f,0.375f, +0.195313f,0.375f, +0.203125f,0.375f, +0.210938f,0.375f, +0.21875f,0.375f, +0.226563f,0.375f, +0.234375f,0.375f, +0.242188f,0.375f, +0.25f,0.375f, +0.257813f,0.375f, +0.265625f,0.375f, +0.273438f,0.375f, +0.28125f,0.375f, +0.289063f,0.375f, +0.296875f,0.375f, +0.304688f,0.375f, +0.3125f,0.375f, +0.320313f,0.375f, +0.328125f,0.375f, +0.335938f,0.375f, +0.34375f,0.375f, +0.351563f,0.375f, +0.359375f,0.375f, +0.367188f,0.375f, +0.375f,0.375f, +0.382813f,0.375f, +0.390625f,0.375f, +0.398438f,0.375f, +0.40625f,0.375f, +0.414063f,0.375f, +0.421875f,0.375f, +0.429688f,0.375f, +0.4375f,0.375f, +0.445313f,0.375f, +0.453125f,0.375f, +0.460938f,0.375f, +0.46875f,0.375f, +0.476563f,0.375f, +0.484375f,0.375f, +0.492188f,0.375f, +0.5f,0.375f, +0.507813f,0.375f, +0.0f,0.382813f, +0.0078125f,0.382813f, +0.015625f,0.382813f, +0.0234375f,0.382813f, +0.03125f,0.382813f, +0.0390625f,0.382813f, +0.046875f,0.382813f, +0.0546875f,0.382813f, +0.0625f,0.382813f, +0.0703125f,0.382813f, +0.078125f,0.382813f, +0.0859375f,0.382813f, +0.09375f,0.382813f, +0.101563f,0.382813f, +0.109375f,0.382813f, +0.117188f,0.382813f, +0.125f,0.382813f, +0.132813f,0.382813f, +0.140625f,0.382813f, +0.148438f,0.382813f, +0.15625f,0.382813f, +0.164063f,0.382813f, +0.171875f,0.382813f, +0.179688f,0.382813f, +0.1875f,0.382813f, +0.195313f,0.382813f, +0.203125f,0.382813f, +0.210938f,0.382813f, +0.21875f,0.382813f, +0.226563f,0.382813f, +0.234375f,0.382813f, +0.242188f,0.382813f, +0.25f,0.382813f, +0.257813f,0.382813f, +0.265625f,0.382813f, +0.273438f,0.382813f, +0.28125f,0.382813f, +0.289063f,0.382813f, +0.296875f,0.382813f, +0.304688f,0.382813f, +0.3125f,0.382813f, +0.320313f,0.382813f, +0.328125f,0.382813f, +0.335938f,0.382813f, +0.34375f,0.382813f, +0.351563f,0.382813f, +0.359375f,0.382813f, +0.367188f,0.382813f, +0.375f,0.382813f, +0.382813f,0.382813f, +0.390625f,0.382813f, +0.398438f,0.382813f, +0.40625f,0.382813f, +0.414063f,0.382813f, +0.421875f,0.382813f, +0.429688f,0.382813f, +0.4375f,0.382813f, +0.445313f,0.382813f, +0.453125f,0.382813f, +0.460938f,0.382813f, +0.46875f,0.382813f, +0.476563f,0.382813f, +0.484375f,0.382813f, +0.492188f,0.382813f, +0.5f,0.382813f, +0.507813f,0.382813f, +0.0f,0.390625f, +0.0078125f,0.390625f, +0.015625f,0.390625f, +0.0234375f,0.390625f, +0.03125f,0.390625f, +0.0390625f,0.390625f, +0.046875f,0.390625f, +0.0546875f,0.390625f, +0.0625f,0.390625f, +0.0703125f,0.390625f, +0.078125f,0.390625f, +0.0859375f,0.390625f, +0.09375f,0.390625f, +0.101563f,0.390625f, +0.109375f,0.390625f, +0.117188f,0.390625f, +0.125f,0.390625f, +0.132813f,0.390625f, +0.140625f,0.390625f, +0.148438f,0.390625f, +0.15625f,0.390625f, +0.164063f,0.390625f, +0.171875f,0.390625f, +0.179688f,0.390625f, +0.1875f,0.390625f, +0.195313f,0.390625f, +0.203125f,0.390625f, +0.210938f,0.390625f, +0.21875f,0.390625f, +0.226563f,0.390625f, +0.234375f,0.390625f, +0.242188f,0.390625f, +0.25f,0.390625f, +0.257813f,0.390625f, +0.265625f,0.390625f, +0.273438f,0.390625f, +0.28125f,0.390625f, +0.289063f,0.390625f, +0.296875f,0.390625f, +0.304688f,0.390625f, +0.3125f,0.390625f, +0.320313f,0.390625f, +0.328125f,0.390625f, +0.335938f,0.390625f, +0.34375f,0.390625f, +0.351563f,0.390625f, +0.359375f,0.390625f, +0.367188f,0.390625f, +0.375f,0.390625f, +0.382813f,0.390625f, +0.390625f,0.390625f, +0.398438f,0.390625f, +0.40625f,0.390625f, +0.414063f,0.390625f, +0.421875f,0.390625f, +0.429688f,0.390625f, +0.4375f,0.390625f, +0.445313f,0.390625f, +0.453125f,0.390625f, +0.460938f,0.390625f, +0.46875f,0.390625f, +0.476563f,0.390625f, +0.484375f,0.390625f, +0.492188f,0.390625f, +0.5f,0.390625f, +0.507813f,0.390625f, +0.0f,0.398438f, +0.0078125f,0.398438f, +0.015625f,0.398438f, +0.0234375f,0.398438f, +0.03125f,0.398438f, +0.0390625f,0.398438f, +0.046875f,0.398438f, +0.0546875f,0.398438f, +0.0625f,0.398438f, +0.0703125f,0.398438f, +0.078125f,0.398438f, +0.0859375f,0.398438f, +0.09375f,0.398438f, +0.101563f,0.398438f, +0.109375f,0.398438f, +0.117188f,0.398438f, +0.125f,0.398438f, +0.132813f,0.398438f, +0.140625f,0.398438f, +0.148438f,0.398438f, +0.15625f,0.398438f, +0.164063f,0.398438f, +0.171875f,0.398438f, +0.179688f,0.398438f, +0.1875f,0.398438f, +0.195313f,0.398438f, +0.203125f,0.398438f, +0.210938f,0.398438f, +0.21875f,0.398438f, +0.226563f,0.398438f, +0.234375f,0.398438f, +0.242188f,0.398438f, +0.25f,0.398438f, +0.257813f,0.398438f, +0.265625f,0.398438f, +0.273438f,0.398438f, +0.28125f,0.398438f, +0.289063f,0.398438f, +0.296875f,0.398438f, +0.304688f,0.398438f, +0.3125f,0.398438f, +0.320313f,0.398438f, +0.328125f,0.398438f, +0.335938f,0.398438f, +0.34375f,0.398438f, +0.351563f,0.398438f, +0.359375f,0.398438f, +0.367188f,0.398438f, +0.375f,0.398438f, +0.382813f,0.398438f, +0.390625f,0.398438f, +0.398438f,0.398438f, +0.40625f,0.398438f, +0.414063f,0.398438f, +0.421875f,0.398438f, +0.429688f,0.398438f, +0.4375f,0.398438f, +0.445313f,0.398438f, +0.453125f,0.398438f, +0.460938f,0.398438f, +0.46875f,0.398438f, +0.476563f,0.398438f, +0.484375f,0.398438f, +0.492188f,0.398438f, +0.5f,0.398438f, +0.507813f,0.398438f, +0.0f,0.40625f, +0.0078125f,0.40625f, +0.015625f,0.40625f, +0.0234375f,0.40625f, +0.03125f,0.40625f, +0.0390625f,0.40625f, +0.046875f,0.40625f, +0.0546875f,0.40625f, +0.0625f,0.40625f, +0.0703125f,0.40625f, +0.078125f,0.40625f, +0.0859375f,0.40625f, +0.09375f,0.40625f, +0.101563f,0.40625f, +0.109375f,0.40625f, +0.117188f,0.40625f, +0.125f,0.40625f, +0.132813f,0.40625f, +0.140625f,0.40625f, +0.148438f,0.40625f, +0.15625f,0.40625f, +0.164063f,0.40625f, +0.171875f,0.40625f, +0.179688f,0.40625f, +0.1875f,0.40625f, +0.195313f,0.40625f, +0.203125f,0.40625f, +0.210938f,0.40625f, +0.21875f,0.40625f, +0.226563f,0.40625f, +0.234375f,0.40625f, +0.242188f,0.40625f, +0.25f,0.40625f, +0.257813f,0.40625f, +0.265625f,0.40625f, +0.273438f,0.40625f, +0.28125f,0.40625f, +0.289063f,0.40625f, +0.296875f,0.40625f, +0.304688f,0.40625f, +0.3125f,0.40625f, +0.320313f,0.40625f, +0.328125f,0.40625f, +0.335938f,0.40625f, +0.34375f,0.40625f, +0.351563f,0.40625f, +0.359375f,0.40625f, +0.367188f,0.40625f, +0.375f,0.40625f, +0.382813f,0.40625f, +0.390625f,0.40625f, +0.398438f,0.40625f, +0.40625f,0.40625f, +0.414063f,0.40625f, +0.421875f,0.40625f, +0.429688f,0.40625f, +0.4375f,0.40625f, +0.445313f,0.40625f, +0.453125f,0.40625f, +0.460938f,0.40625f, +0.46875f,0.40625f, +0.476563f,0.40625f, +0.484375f,0.40625f, +0.492188f,0.40625f, +0.5f,0.40625f, +0.507813f,0.40625f, +0.0f,0.414063f, +0.0078125f,0.414063f, +0.015625f,0.414063f, +0.0234375f,0.414063f, +0.03125f,0.414063f, +0.0390625f,0.414063f, +0.046875f,0.414063f, +0.0546875f,0.414063f, +0.0625f,0.414063f, +0.0703125f,0.414063f, +0.078125f,0.414063f, +0.0859375f,0.414063f, +0.09375f,0.414063f, +0.101563f,0.414063f, +0.109375f,0.414063f, +0.117188f,0.414063f, +0.125f,0.414063f, +0.132813f,0.414063f, +0.140625f,0.414063f, +0.148438f,0.414063f, +0.15625f,0.414063f, +0.164063f,0.414063f, +0.171875f,0.414063f, +0.179688f,0.414063f, +0.1875f,0.414063f, +0.195313f,0.414063f, +0.203125f,0.414063f, +0.210938f,0.414063f, +0.21875f,0.414063f, +0.226563f,0.414063f, +0.234375f,0.414063f, +0.242188f,0.414063f, +0.25f,0.414063f, +0.257813f,0.414063f, +0.265625f,0.414063f, +0.273438f,0.414063f, +0.28125f,0.414063f, +0.289063f,0.414063f, +0.296875f,0.414063f, +0.304688f,0.414063f, +0.3125f,0.414063f, +0.320313f,0.414063f, +0.328125f,0.414063f, +0.335938f,0.414063f, +0.34375f,0.414063f, +0.351563f,0.414063f, +0.359375f,0.414063f, +0.367188f,0.414063f, +0.375f,0.414063f, +0.382813f,0.414063f, +0.390625f,0.414063f, +0.398438f,0.414063f, +0.40625f,0.414063f, +0.414063f,0.414063f, +0.421875f,0.414063f, +0.429688f,0.414063f, +0.4375f,0.414063f, +0.445313f,0.414063f, +0.453125f,0.414063f, +0.460938f,0.414063f, +0.46875f,0.414063f, +0.476563f,0.414063f, +0.484375f,0.414063f, +0.492188f,0.414063f, +0.5f,0.414063f, +0.507813f,0.414063f, +0.0f,0.421875f, +0.0078125f,0.421875f, +0.015625f,0.421875f, +0.0234375f,0.421875f, +0.03125f,0.421875f, +0.0390625f,0.421875f, +0.046875f,0.421875f, +0.0546875f,0.421875f, +0.0625f,0.421875f, +0.0703125f,0.421875f, +0.078125f,0.421875f, +0.0859375f,0.421875f, +0.09375f,0.421875f, +0.101563f,0.421875f, +0.109375f,0.421875f, +0.117188f,0.421875f, +0.125f,0.421875f, +0.132813f,0.421875f, +0.140625f,0.421875f, +0.148438f,0.421875f, +0.15625f,0.421875f, +0.164063f,0.421875f, +0.171875f,0.421875f, +0.179688f,0.421875f, +0.1875f,0.421875f, +0.195313f,0.421875f, +0.203125f,0.421875f, +0.210938f,0.421875f, +0.21875f,0.421875f, +0.226563f,0.421875f, +0.234375f,0.421875f, +0.242188f,0.421875f, +0.25f,0.421875f, +0.257813f,0.421875f, +0.265625f,0.421875f, +0.273438f,0.421875f, +0.28125f,0.421875f, +0.289063f,0.421875f, +0.296875f,0.421875f, +0.304688f,0.421875f, +0.3125f,0.421875f, +0.320313f,0.421875f, +0.328125f,0.421875f, +0.335938f,0.421875f, +0.34375f,0.421875f, +0.351563f,0.421875f, +0.359375f,0.421875f, +0.367188f,0.421875f, +0.375f,0.421875f, +0.382813f,0.421875f, +0.390625f,0.421875f, +0.398438f,0.421875f, +0.40625f,0.421875f, +0.414063f,0.421875f, +0.421875f,0.421875f, +0.429688f,0.421875f, +0.4375f,0.421875f, +0.445313f,0.421875f, +0.453125f,0.421875f, +0.460938f,0.421875f, +0.46875f,0.421875f, +0.476563f,0.421875f, +0.484375f,0.421875f, +0.492188f,0.421875f, +0.5f,0.421875f, +0.507813f,0.421875f, +0.0f,0.429688f, +0.0078125f,0.429688f, +0.015625f,0.429688f, +0.0234375f,0.429688f, +0.03125f,0.429688f, +0.0390625f,0.429688f, +0.046875f,0.429688f, +0.0546875f,0.429688f, +0.0625f,0.429688f, +0.0703125f,0.429688f, +0.078125f,0.429688f, +0.0859375f,0.429688f, +0.09375f,0.429688f, +0.101563f,0.429688f, +0.109375f,0.429688f, +0.117188f,0.429688f, +0.125f,0.429688f, +0.132813f,0.429688f, +0.140625f,0.429688f, +0.148438f,0.429688f, +0.15625f,0.429688f, +0.164063f,0.429688f, +0.171875f,0.429688f, +0.179688f,0.429688f, +0.1875f,0.429688f, +0.195313f,0.429688f, +0.203125f,0.429688f, +0.210938f,0.429688f, +0.21875f,0.429688f, +0.226563f,0.429688f, +0.234375f,0.429688f, +0.242188f,0.429688f, +0.25f,0.429688f, +0.257813f,0.429688f, +0.265625f,0.429688f, +0.273438f,0.429688f, +0.28125f,0.429688f, +0.289063f,0.429688f, +0.296875f,0.429688f, +0.304688f,0.429688f, +0.3125f,0.429688f, +0.320313f,0.429688f, +0.328125f,0.429688f, +0.335938f,0.429688f, +0.34375f,0.429688f, +0.351563f,0.429688f, +0.359375f,0.429688f, +0.367188f,0.429688f, +0.375f,0.429688f, +0.382813f,0.429688f, +0.390625f,0.429688f, +0.398438f,0.429688f, +0.40625f,0.429688f, +0.414063f,0.429688f, +0.421875f,0.429688f, +0.429688f,0.429688f, +0.4375f,0.429688f, +0.445313f,0.429688f, +0.453125f,0.429688f, +0.460938f,0.429688f, +0.46875f,0.429688f, +0.476563f,0.429688f, +0.484375f,0.429688f, +0.492188f,0.429688f, +0.5f,0.429688f, +0.507813f,0.429688f, +0.0f,0.4375f, +0.0078125f,0.4375f, +0.015625f,0.4375f, +0.0234375f,0.4375f, +0.03125f,0.4375f, +0.0390625f,0.4375f, +0.046875f,0.4375f, +0.0546875f,0.4375f, +0.0625f,0.4375f, +0.0703125f,0.4375f, +0.078125f,0.4375f, +0.0859375f,0.4375f, +0.09375f,0.4375f, +0.101563f,0.4375f, +0.109375f,0.4375f, +0.117188f,0.4375f, +0.125f,0.4375f, +0.132813f,0.4375f, +0.140625f,0.4375f, +0.148438f,0.4375f, +0.15625f,0.4375f, +0.164063f,0.4375f, +0.171875f,0.4375f, +0.179688f,0.4375f, +0.1875f,0.4375f, +0.195313f,0.4375f, +0.203125f,0.4375f, +0.210938f,0.4375f, +0.21875f,0.4375f, +0.226563f,0.4375f, +0.234375f,0.4375f, +0.242188f,0.4375f, +0.25f,0.4375f, +0.257813f,0.4375f, +0.265625f,0.4375f, +0.273438f,0.4375f, +0.28125f,0.4375f, +0.289063f,0.4375f, +0.296875f,0.4375f, +0.304688f,0.4375f, +0.3125f,0.4375f, +0.320313f,0.4375f, +0.328125f,0.4375f, +0.335938f,0.4375f, +0.34375f,0.4375f, +0.351563f,0.4375f, +0.359375f,0.4375f, +0.367188f,0.4375f, +0.375f,0.4375f, +0.382813f,0.4375f, +0.390625f,0.4375f, +0.398438f,0.4375f, +0.40625f,0.4375f, +0.414063f,0.4375f, +0.421875f,0.4375f, +0.429688f,0.4375f, +0.4375f,0.4375f, +0.445313f,0.4375f, +0.453125f,0.4375f, +0.460938f,0.4375f, +0.46875f,0.4375f, +0.476563f,0.4375f, +0.484375f,0.4375f, +0.492188f,0.4375f, +0.5f,0.4375f, +0.507813f,0.4375f, +0.0f,0.445313f, +0.0078125f,0.445313f, +0.015625f,0.445313f, +0.0234375f,0.445313f, +0.03125f,0.445313f, +0.0390625f,0.445313f, +0.046875f,0.445313f, +0.0546875f,0.445313f, +0.0625f,0.445313f, +0.0703125f,0.445313f, +0.078125f,0.445313f, +0.0859375f,0.445313f, +0.09375f,0.445313f, +0.101563f,0.445313f, +0.109375f,0.445313f, +0.117188f,0.445313f, +0.125f,0.445313f, +0.132813f,0.445313f, +0.140625f,0.445313f, +0.148438f,0.445313f, +0.15625f,0.445313f, +0.164063f,0.445313f, +0.171875f,0.445313f, +0.179688f,0.445313f, +0.1875f,0.445313f, +0.195313f,0.445313f, +0.203125f,0.445313f, +0.210938f,0.445313f, +0.21875f,0.445313f, +0.226563f,0.445313f, +0.234375f,0.445313f, +0.242188f,0.445313f, +0.25f,0.445313f, +0.257813f,0.445313f, +0.265625f,0.445313f, +0.273438f,0.445313f, +0.28125f,0.445313f, +0.289063f,0.445313f, +0.296875f,0.445313f, +0.304688f,0.445313f, +0.3125f,0.445313f, +0.320313f,0.445313f, +0.328125f,0.445313f, +0.335938f,0.445313f, +0.34375f,0.445313f, +0.351563f,0.445313f, +0.359375f,0.445313f, +0.367188f,0.445313f, +0.375f,0.445313f, +0.382813f,0.445313f, +0.390625f,0.445313f, +0.398438f,0.445313f, +0.40625f,0.445313f, +0.414063f,0.445313f, +0.421875f,0.445313f, +0.429688f,0.445313f, +0.4375f,0.445313f, +0.445313f,0.445313f, +0.453125f,0.445313f, +0.460938f,0.445313f, +0.46875f,0.445313f, +0.476563f,0.445313f, +0.484375f,0.445313f, +0.492188f,0.445313f, +0.5f,0.445313f, +0.507813f,0.445313f, +0.0f,0.453125f, +0.0078125f,0.453125f, +0.015625f,0.453125f, +0.0234375f,0.453125f, +0.03125f,0.453125f, +0.0390625f,0.453125f, +0.046875f,0.453125f, +0.0546875f,0.453125f, +0.0625f,0.453125f, +0.0703125f,0.453125f, +0.078125f,0.453125f, +0.0859375f,0.453125f, +0.09375f,0.453125f, +0.101563f,0.453125f, +0.109375f,0.453125f, +0.117188f,0.453125f, +0.125f,0.453125f, +0.132813f,0.453125f, +0.140625f,0.453125f, +0.148438f,0.453125f, +0.15625f,0.453125f, +0.164063f,0.453125f, +0.171875f,0.453125f, +0.179688f,0.453125f, +0.1875f,0.453125f, +0.195313f,0.453125f, +0.203125f,0.453125f, +0.210938f,0.453125f, +0.21875f,0.453125f, +0.226563f,0.453125f, +0.234375f,0.453125f, +0.242188f,0.453125f, +0.25f,0.453125f, +0.257813f,0.453125f, +0.265625f,0.453125f, +0.273438f,0.453125f, +0.28125f,0.453125f, +0.289063f,0.453125f, +0.296875f,0.453125f, +0.304688f,0.453125f, +0.3125f,0.453125f, +0.320313f,0.453125f, +0.328125f,0.453125f, +0.335938f,0.453125f, +0.34375f,0.453125f, +0.351563f,0.453125f, +0.359375f,0.453125f, +0.367188f,0.453125f, +0.375f,0.453125f, +0.382813f,0.453125f, +0.390625f,0.453125f, +0.398438f,0.453125f, +0.40625f,0.453125f, +0.414063f,0.453125f, +0.421875f,0.453125f, +0.429688f,0.453125f, +0.4375f,0.453125f, +0.445313f,0.453125f, +0.453125f,0.453125f, +0.460938f,0.453125f, +0.46875f,0.453125f, +0.476563f,0.453125f, +0.484375f,0.453125f, +0.492188f,0.453125f, +0.5f,0.453125f, +0.507813f,0.453125f, +0.0f,0.460938f, +0.0078125f,0.460938f, +0.015625f,0.460938f, +0.0234375f,0.460938f, +0.03125f,0.460938f, +0.0390625f,0.460938f, +0.046875f,0.460938f, +0.0546875f,0.460938f, +0.0625f,0.460938f, +0.0703125f,0.460938f, +0.078125f,0.460938f, +0.0859375f,0.460938f, +0.09375f,0.460938f, +0.101563f,0.460938f, +0.109375f,0.460938f, +0.117188f,0.460938f, +0.125f,0.460938f, +0.132813f,0.460938f, +0.140625f,0.460938f, +0.148438f,0.460938f, +0.15625f,0.460938f, +0.164063f,0.460938f, +0.171875f,0.460938f, +0.179688f,0.460938f, +0.1875f,0.460938f, +0.195313f,0.460938f, +0.203125f,0.460938f, +0.210938f,0.460938f, +0.21875f,0.460938f, +0.226563f,0.460938f, +0.234375f,0.460938f, +0.242188f,0.460938f, +0.25f,0.460938f, +0.257813f,0.460938f, +0.265625f,0.460938f, +0.273438f,0.460938f, +0.28125f,0.460938f, +0.289063f,0.460938f, +0.296875f,0.460938f, +0.304688f,0.460938f, +0.3125f,0.460938f, +0.320313f,0.460938f, +0.328125f,0.460938f, +0.335938f,0.460938f, +0.34375f,0.460938f, +0.351563f,0.460938f, +0.359375f,0.460938f, +0.367188f,0.460938f, +0.375f,0.460938f, +0.382813f,0.460938f, +0.390625f,0.460938f, +0.398438f,0.460938f, +0.40625f,0.460938f, +0.414063f,0.460938f, +0.421875f,0.460938f, +0.429688f,0.460938f, +0.4375f,0.460938f, +0.445313f,0.460938f, +0.453125f,0.460938f, +0.460938f,0.460938f, +0.46875f,0.460938f, +0.476563f,0.460938f, +0.484375f,0.460938f, +0.492188f,0.460938f, +0.5f,0.460938f, +0.507813f,0.460938f, +0.0f,0.46875f, +0.0078125f,0.46875f, +0.015625f,0.46875f, +0.0234375f,0.46875f, +0.03125f,0.46875f, +0.0390625f,0.46875f, +0.046875f,0.46875f, +0.0546875f,0.46875f, +0.0625f,0.46875f, +0.0703125f,0.46875f, +0.078125f,0.46875f, +0.0859375f,0.46875f, +0.09375f,0.46875f, +0.101563f,0.46875f, +0.109375f,0.46875f, +0.117188f,0.46875f, +0.125f,0.46875f, +0.132813f,0.46875f, +0.140625f,0.46875f, +0.148438f,0.46875f, +0.15625f,0.46875f, +0.164063f,0.46875f, +0.171875f,0.46875f, +0.179688f,0.46875f, +0.1875f,0.46875f, +0.195313f,0.46875f, +0.203125f,0.46875f, +0.210938f,0.46875f, +0.21875f,0.46875f, +0.226563f,0.46875f, +0.234375f,0.46875f, +0.242188f,0.46875f, +0.25f,0.46875f, +0.257813f,0.46875f, +0.265625f,0.46875f, +0.273438f,0.46875f, +0.28125f,0.46875f, +0.289063f,0.46875f, +0.296875f,0.46875f, +0.304688f,0.46875f, +0.3125f,0.46875f, +0.320313f,0.46875f, +0.328125f,0.46875f, +0.335938f,0.46875f, +0.34375f,0.46875f, +0.351563f,0.46875f, +0.359375f,0.46875f, +0.367188f,0.46875f, +0.375f,0.46875f, +0.382813f,0.46875f, +0.390625f,0.46875f, +0.398438f,0.46875f, +0.40625f,0.46875f, +0.414063f,0.46875f, +0.421875f,0.46875f, +0.429688f,0.46875f, +0.4375f,0.46875f, +0.445313f,0.46875f, +0.453125f,0.46875f, +0.460938f,0.46875f, +0.46875f,0.46875f, +0.476563f,0.46875f, +0.484375f,0.46875f, +0.492188f,0.46875f, +0.5f,0.46875f, +0.507813f,0.46875f, +0.0f,0.476563f, +0.0078125f,0.476563f, +0.015625f,0.476563f, +0.0234375f,0.476563f, +0.03125f,0.476563f, +0.0390625f,0.476563f, +0.046875f,0.476563f, +0.0546875f,0.476563f, +0.0625f,0.476563f, +0.0703125f,0.476563f, +0.078125f,0.476563f, +0.0859375f,0.476563f, +0.09375f,0.476563f, +0.101563f,0.476563f, +0.109375f,0.476563f, +0.117188f,0.476563f, +0.125f,0.476563f, +0.132813f,0.476563f, +0.140625f,0.476563f, +0.148438f,0.476563f, +0.15625f,0.476563f, +0.164063f,0.476563f, +0.171875f,0.476563f, +0.179688f,0.476563f, +0.1875f,0.476563f, +0.195313f,0.476563f, +0.203125f,0.476563f, +0.210938f,0.476563f, +0.21875f,0.476563f, +0.226563f,0.476563f, +0.234375f,0.476563f, +0.242188f,0.476563f, +0.25f,0.476563f, +0.257813f,0.476563f, +0.265625f,0.476563f, +0.273438f,0.476563f, +0.28125f,0.476563f, +0.289063f,0.476563f, +0.296875f,0.476563f, +0.304688f,0.476563f, +0.3125f,0.476563f, +0.320313f,0.476563f, +0.328125f,0.476563f, +0.335938f,0.476563f, +0.34375f,0.476563f, +0.351563f,0.476563f, +0.359375f,0.476563f, +0.367188f,0.476563f, +0.375f,0.476563f, +0.382813f,0.476563f, +0.390625f,0.476563f, +0.398438f,0.476563f, +0.40625f,0.476563f, +0.414063f,0.476563f, +0.421875f,0.476563f, +0.429688f,0.476563f, +0.4375f,0.476563f, +0.445313f,0.476563f, +0.453125f,0.476563f, +0.460938f,0.476563f, +0.46875f,0.476563f, +0.476563f,0.476563f, +0.484375f,0.476563f, +0.492188f,0.476563f, +0.5f,0.476563f, +0.507813f,0.476563f, +0.0f,0.484375f, +0.0078125f,0.484375f, +0.015625f,0.484375f, +0.0234375f,0.484375f, +0.03125f,0.484375f, +0.0390625f,0.484375f, +0.046875f,0.484375f, +0.0546875f,0.484375f, +0.0625f,0.484375f, +0.0703125f,0.484375f, +0.078125f,0.484375f, +0.0859375f,0.484375f, +0.09375f,0.484375f, +0.101563f,0.484375f, +0.109375f,0.484375f, +0.117188f,0.484375f, +0.125f,0.484375f, +0.132813f,0.484375f, +0.140625f,0.484375f, +0.148438f,0.484375f, +0.15625f,0.484375f, +0.164063f,0.484375f, +0.171875f,0.484375f, +0.179688f,0.484375f, +0.1875f,0.484375f, +0.195313f,0.484375f, +0.203125f,0.484375f, +0.210938f,0.484375f, +0.21875f,0.484375f, +0.226563f,0.484375f, +0.234375f,0.484375f, +0.242188f,0.484375f, +0.25f,0.484375f, +0.257813f,0.484375f, +0.265625f,0.484375f, +0.273438f,0.484375f, +0.28125f,0.484375f, +0.289063f,0.484375f, +0.296875f,0.484375f, +0.304688f,0.484375f, +0.3125f,0.484375f, +0.320313f,0.484375f, +0.328125f,0.484375f, +0.335938f,0.484375f, +0.34375f,0.484375f, +0.351563f,0.484375f, +0.359375f,0.484375f, +0.367188f,0.484375f, +0.375f,0.484375f, +0.382813f,0.484375f, +0.390625f,0.484375f, +0.398438f,0.484375f, +0.40625f,0.484375f, +0.414063f,0.484375f, +0.421875f,0.484375f, +0.429688f,0.484375f, +0.4375f,0.484375f, +0.445313f,0.484375f, +0.453125f,0.484375f, +0.460938f,0.484375f, +0.46875f,0.484375f, +0.476563f,0.484375f, +0.484375f,0.484375f, +0.492188f,0.484375f, +0.5f,0.484375f, +0.507813f,0.484375f, +0.0f,0.492188f, +0.0078125f,0.492188f, +0.015625f,0.492188f, +0.0234375f,0.492188f, +0.03125f,0.492188f, +0.0390625f,0.492188f, +0.046875f,0.492188f, +0.0546875f,0.492188f, +0.0625f,0.492188f, +0.0703125f,0.492188f, +0.078125f,0.492188f, +0.0859375f,0.492188f, +0.09375f,0.492188f, +0.101563f,0.492188f, +0.109375f,0.492188f, +0.117188f,0.492188f, +0.125f,0.492188f, +0.132813f,0.492188f, +0.140625f,0.492188f, +0.148438f,0.492188f, +0.15625f,0.492188f, +0.164063f,0.492188f, +0.171875f,0.492188f, +0.179688f,0.492188f, +0.1875f,0.492188f, +0.195313f,0.492188f, +0.203125f,0.492188f, +0.210938f,0.492188f, +0.21875f,0.492188f, +0.226563f,0.492188f, +0.234375f,0.492188f, +0.242188f,0.492188f, +0.25f,0.492188f, +0.257813f,0.492188f, +0.265625f,0.492188f, +0.273438f,0.492188f, +0.28125f,0.492188f, +0.289063f,0.492188f, +0.296875f,0.492188f, +0.304688f,0.492188f, +0.3125f,0.492188f, +0.320313f,0.492188f, +0.328125f,0.492188f, +0.335938f,0.492188f, +0.34375f,0.492188f, +0.351563f,0.492188f, +0.359375f,0.492188f, +0.367188f,0.492188f, +0.375f,0.492188f, +0.382813f,0.492188f, +0.390625f,0.492188f, +0.398438f,0.492188f, +0.40625f,0.492188f, +0.414063f,0.492188f, +0.421875f,0.492188f, +0.429688f,0.492188f, +0.4375f,0.492188f, +0.445313f,0.492188f, +0.453125f,0.492188f, +0.460938f,0.492188f, +0.46875f,0.492188f, +0.476563f,0.492188f, +0.484375f,0.492188f, +0.492188f,0.492188f, +0.5f,0.492188f, +0.507813f,0.492188f, +}; + +unsigned short Landscape02Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +126,127,128, +129,128,127, +128,129,130, +131,130,129, +132,0,133, +2,133,0, +133,2,134, +4,134,2, +134,4,135, +6,135,4, +135,6,136, +8,136,6, +136,8,137, +10,137,8, +137,10,138, +12,138,10, +138,12,139, +14,139,12, +139,14,140, +16,140,14, +140,16,141, +18,141,16, +141,18,142, +20,142,18, +142,20,143, +22,143,20, +143,22,144, +24,144,22, +144,24,145, +26,145,24, +145,26,146, +28,146,26, +146,28,147, +30,147,28, +147,30,148, +32,148,30, +148,32,149, +34,149,32, +149,34,150, +36,150,34, +150,36,151, +38,151,36, +151,38,152, +40,152,38, +152,40,153, +42,153,40, +153,42,154, +44,154,42, +154,44,155, +46,155,44, +155,46,156, +48,156,46, +156,48,157, +50,157,48, +157,50,158, +52,158,50, +158,52,159, +54,159,52, +159,54,160, +56,160,54, +160,56,161, +58,161,56, +161,58,162, +60,162,58, +162,60,163, +62,163,60, +163,62,164, +64,164,62, +164,64,165, +66,165,64, +165,66,166, +68,166,66, +166,68,167, +70,167,68, +167,70,168, +72,168,70, +168,72,169, +74,169,72, +169,74,170, +76,170,74, +170,76,171, +78,171,76, +171,78,172, +80,172,78, +172,80,173, +82,173,80, +173,82,174, +84,174,82, +174,84,175, +86,175,84, +175,86,176, +88,176,86, +176,88,177, +90,177,88, +177,90,178, +92,178,90, +178,92,179, +94,179,92, +179,94,180, +96,180,94, +180,96,181, +98,181,96, +181,98,182, +100,182,98, +182,100,183, +102,183,100, +183,102,184, +104,184,102, +184,104,185, +106,185,104, +185,106,186, +108,186,106, +186,108,187, +110,187,108, +187,110,188, +112,188,110, +188,112,189, +114,189,112, +189,114,190, +116,190,114, +190,116,191, +118,191,116, +191,118,192, +120,192,118, +192,120,193, +122,193,120, +193,122,194, +124,194,122, +194,124,195, +126,195,124, +195,126,196, +128,196,126, +196,128,197, +130,197,128, +198,132,199, +133,199,132, +199,133,200, +134,200,133, +200,134,201, +135,201,134, +201,135,202, +136,202,135, +202,136,203, +137,203,136, +203,137,204, +138,204,137, +204,138,205, +139,205,138, +205,139,206, +140,206,139, +206,140,207, +141,207,140, +207,141,208, +142,208,141, +208,142,209, +143,209,142, +209,143,210, +144,210,143, +210,144,211, +145,211,144, +211,145,212, +146,212,145, +212,146,213, +147,213,146, +213,147,214, +148,214,147, +214,148,215, +149,215,148, +215,149,216, +150,216,149, +216,150,217, +151,217,150, +217,151,218, +152,218,151, +218,152,219, +153,219,152, +219,153,220, +154,220,153, +220,154,221, +155,221,154, +221,155,222, +156,222,155, +222,156,223, +157,223,156, +223,157,224, +158,224,157, +224,158,225, +159,225,158, +225,159,226, +160,226,159, +226,160,227, +161,227,160, +227,161,228, +162,228,161, +228,162,229, +163,229,162, +229,163,230, +164,230,163, +230,164,231, +165,231,164, +231,165,232, +166,232,165, +232,166,233, +167,233,166, +233,167,234, +168,234,167, +234,168,235, +169,235,168, +235,169,236, +170,236,169, +236,170,237, +171,237,170, +237,171,238, +172,238,171, +238,172,239, +173,239,172, +239,173,240, +174,240,173, +240,174,241, +175,241,174, +241,175,242, +176,242,175, +242,176,243, +177,243,176, +243,177,244, +178,244,177, +244,178,245, +179,245,178, +245,179,246, +180,246,179, +246,180,247, +181,247,180, +247,181,248, +182,248,181, +248,182,249, +183,249,182, +249,183,250, +184,250,183, +250,184,251, +185,251,184, +251,185,252, +186,252,185, +252,186,253, +187,253,186, +253,187,254, +188,254,187, +254,188,255, +189,255,188, +255,189,256, +190,256,189, +256,190,257, +191,257,190, +257,191,258, +192,258,191, +258,192,259, +193,259,192, +259,193,260, +194,260,193, +260,194,261, +195,261,194, +261,195,262, +196,262,195, +262,196,263, +197,263,196, +264,198,265, +199,265,198, +265,199,266, +200,266,199, +266,200,267, +201,267,200, +267,201,268, +202,268,201, +268,202,269, +203,269,202, +269,203,270, +204,270,203, +270,204,271, +205,271,204, +271,205,272, +206,272,205, +272,206,273, +207,273,206, +273,207,274, +208,274,207, +274,208,275, +209,275,208, +275,209,276, +210,276,209, +276,210,277, +211,277,210, +277,211,278, +212,278,211, +278,212,279, +213,279,212, +279,213,280, +214,280,213, +280,214,281, +215,281,214, +281,215,282, +216,282,215, +282,216,283, +217,283,216, +283,217,284, +218,284,217, +284,218,285, +219,285,218, +285,219,286, +220,286,219, +286,220,287, +221,287,220, +287,221,288, +222,288,221, +288,222,289, +223,289,222, +289,223,290, +224,290,223, +290,224,291, +225,291,224, +291,225,292, +226,292,225, +292,226,293, +227,293,226, +293,227,294, +228,294,227, +294,228,295, +229,295,228, +295,229,296, +230,296,229, +296,230,297, +231,297,230, +297,231,298, +232,298,231, +298,232,299, +233,299,232, +299,233,300, +234,300,233, +300,234,301, +235,301,234, +301,235,302, +236,302,235, +302,236,303, +237,303,236, +303,237,304, +238,304,237, +304,238,305, +239,305,238, +305,239,306, +240,306,239, +306,240,307, +241,307,240, +307,241,308, +242,308,241, +308,242,309, +243,309,242, +309,243,310, +244,310,243, +310,244,311, +245,311,244, +311,245,312, +246,312,245, +312,246,313, +247,313,246, +313,247,314, +248,314,247, +314,248,315, +249,315,248, +315,249,316, +250,316,249, +316,250,317, +251,317,250, +317,251,318, +252,318,251, +318,252,319, +253,319,252, +319,253,320, +254,320,253, +320,254,321, +255,321,254, +321,255,322, +256,322,255, +322,256,323, +257,323,256, +323,257,324, +258,324,257, +324,258,325, +259,325,258, +325,259,326, +260,326,259, +326,260,327, +261,327,260, +327,261,328, +262,328,261, +328,262,329, +263,329,262, +330,264,331, +265,331,264, +331,265,332, +266,332,265, +332,266,333, +267,333,266, +333,267,334, +268,334,267, +334,268,335, +269,335,268, +335,269,336, +270,336,269, +336,270,337, +271,337,270, +337,271,338, +272,338,271, +338,272,339, +273,339,272, +339,273,340, +274,340,273, +340,274,341, +275,341,274, +341,275,342, +276,342,275, +342,276,343, +277,343,276, +343,277,344, +278,344,277, +344,278,345, +279,345,278, +345,279,346, +280,346,279, +346,280,347, +281,347,280, +347,281,348, +282,348,281, +348,282,349, +283,349,282, +349,283,350, +284,350,283, +350,284,351, +285,351,284, +351,285,352, +286,352,285, +352,286,353, +287,353,286, +353,287,354, +288,354,287, +354,288,355, +289,355,288, +355,289,356, +290,356,289, +356,290,357, +291,357,290, +357,291,358, +292,358,291, +358,292,359, +293,359,292, +359,293,360, +294,360,293, +360,294,361, +295,361,294, +361,295,362, +296,362,295, +362,296,363, +297,363,296, +363,297,364, +298,364,297, +364,298,365, +299,365,298, +365,299,366, +300,366,299, +366,300,367, +301,367,300, +367,301,368, +302,368,301, +368,302,369, +303,369,302, +369,303,370, +304,370,303, +370,304,371, +305,371,304, +371,305,372, +306,372,305, +372,306,373, +307,373,306, +373,307,374, +308,374,307, +374,308,375, +309,375,308, +375,309,376, +310,376,309, +376,310,377, +311,377,310, +377,311,378, +312,378,311, +378,312,379, +313,379,312, +379,313,380, +314,380,313, +380,314,381, +315,381,314, +381,315,382, +316,382,315, +382,316,383, +317,383,316, +383,317,384, +318,384,317, +384,318,385, +319,385,318, +385,319,386, +320,386,319, +386,320,387, +321,387,320, +387,321,388, +322,388,321, +388,322,389, +323,389,322, +389,323,390, +324,390,323, +390,324,391, +325,391,324, +391,325,392, +326,392,325, +392,326,393, +327,393,326, +393,327,394, +328,394,327, +394,328,395, +329,395,328, +396,330,397, +331,397,330, +397,331,398, +332,398,331, +398,332,399, +333,399,332, +399,333,400, +334,400,333, +400,334,401, +335,401,334, +401,335,402, +336,402,335, +402,336,403, +337,403,336, +403,337,404, +338,404,337, +404,338,405, +339,405,338, +405,339,406, +340,406,339, +406,340,407, +341,407,340, +407,341,408, +342,408,341, +408,342,409, +343,409,342, +409,343,410, +344,410,343, +410,344,411, +345,411,344, +411,345,412, +346,412,345, +412,346,413, +347,413,346, +413,347,414, +348,414,347, +414,348,415, +349,415,348, +415,349,416, +350,416,349, +416,350,417, +351,417,350, +417,351,418, +352,418,351, +418,352,419, +353,419,352, +419,353,420, +354,420,353, +420,354,421, +355,421,354, +421,355,422, +356,422,355, +422,356,423, +357,423,356, +423,357,424, +358,424,357, +424,358,425, +359,425,358, +425,359,426, +360,426,359, +426,360,427, +361,427,360, +427,361,428, +362,428,361, +428,362,429, +363,429,362, +429,363,430, +364,430,363, +430,364,431, +365,431,364, +431,365,432, +366,432,365, +432,366,433, +367,433,366, +433,367,434, +368,434,367, +434,368,435, +369,435,368, +435,369,436, +370,436,369, +436,370,437, +371,437,370, +437,371,438, +372,438,371, +438,372,439, +373,439,372, +439,373,440, +374,440,373, +440,374,441, +375,441,374, +441,375,442, +376,442,375, +442,376,443, +377,443,376, +443,377,444, +378,444,377, +444,378,445, +379,445,378, +445,379,446, +380,446,379, +446,380,447, +381,447,380, +447,381,448, +382,448,381, +448,382,449, +383,449,382, +449,383,450, +384,450,383, +450,384,451, +385,451,384, +451,385,452, +386,452,385, +452,386,453, +387,453,386, +453,387,454, +388,454,387, +454,388,455, +389,455,388, +455,389,456, +390,456,389, +456,390,457, +391,457,390, +457,391,458, +392,458,391, +458,392,459, +393,459,392, +459,393,460, +394,460,393, +460,394,461, +395,461,394, +462,396,463, +397,463,396, +463,397,464, +398,464,397, +464,398,465, +399,465,398, +465,399,466, +400,466,399, +466,400,467, +401,467,400, +467,401,468, +402,468,401, +468,402,469, +403,469,402, +469,403,470, +404,470,403, +470,404,471, +405,471,404, +471,405,472, +406,472,405, +472,406,473, +407,473,406, +473,407,474, +408,474,407, +474,408,475, +409,475,408, +475,409,476, +410,476,409, +476,410,477, +411,477,410, +477,411,478, +412,478,411, +478,412,479, +413,479,412, +479,413,480, +414,480,413, +480,414,481, +415,481,414, +481,415,482, +416,482,415, +482,416,483, +417,483,416, +483,417,484, +418,484,417, +484,418,485, +419,485,418, +485,419,486, +420,486,419, +486,420,487, +421,487,420, +487,421,488, +422,488,421, +488,422,489, +423,489,422, +489,423,490, +424,490,423, +490,424,491, +425,491,424, +491,425,492, +426,492,425, +492,426,493, +427,493,426, +493,427,494, +428,494,427, +494,428,495, +429,495,428, +495,429,496, +430,496,429, +496,430,497, +431,497,430, +497,431,498, +432,498,431, +498,432,499, +433,499,432, +499,433,500, +434,500,433, +500,434,501, +435,501,434, +501,435,502, +436,502,435, +502,436,503, +437,503,436, +503,437,504, +438,504,437, +504,438,505, +439,505,438, +505,439,506, +440,506,439, +506,440,507, +441,507,440, +507,441,508, +442,508,441, +508,442,509, +443,509,442, +509,443,510, +444,510,443, +510,444,511, +445,511,444, +511,445,512, +446,512,445, +512,446,513, +447,513,446, +513,447,514, +448,514,447, +514,448,515, +449,515,448, +515,449,516, +450,516,449, +516,450,517, +451,517,450, +517,451,518, +452,518,451, +518,452,519, +453,519,452, +519,453,520, +454,520,453, +520,454,521, +455,521,454, +521,455,522, +456,522,455, +522,456,523, +457,523,456, +523,457,524, +458,524,457, +524,458,525, +459,525,458, +525,459,526, +460,526,459, +526,460,527, +461,527,460, +528,462,529, +463,529,462, +529,463,530, +464,530,463, +530,464,531, +465,531,464, +531,465,532, +466,532,465, +532,466,533, +467,533,466, +533,467,534, +468,534,467, +534,468,535, +469,535,468, +535,469,536, +470,536,469, +536,470,537, +471,537,470, +537,471,538, +472,538,471, +538,472,539, +473,539,472, +539,473,540, +474,540,473, +540,474,541, +475,541,474, +541,475,542, +476,542,475, +542,476,543, +477,543,476, +543,477,544, +478,544,477, +544,478,545, +479,545,478, +545,479,546, +480,546,479, +546,480,547, +481,547,480, +547,481,548, +482,548,481, +548,482,549, +483,549,482, +549,483,550, +484,550,483, +550,484,551, +485,551,484, +551,485,552, +486,552,485, +552,486,553, +487,553,486, +553,487,554, +488,554,487, +554,488,555, +489,555,488, +555,489,556, +490,556,489, +556,490,557, +491,557,490, +557,491,558, +492,558,491, +558,492,559, +493,559,492, +559,493,560, +494,560,493, +560,494,561, +495,561,494, +561,495,562, +496,562,495, +562,496,563, +497,563,496, +563,497,564, +498,564,497, +564,498,565, +499,565,498, +565,499,566, +500,566,499, +566,500,567, +501,567,500, +567,501,568, +502,568,501, +568,502,569, +503,569,502, +569,503,570, +504,570,503, +570,504,571, +505,571,504, +571,505,572, +506,572,505, +572,506,573, +507,573,506, +573,507,574, +508,574,507, +574,508,575, +509,575,508, +575,509,576, +510,576,509, +576,510,577, +511,577,510, +577,511,578, +512,578,511, +578,512,579, +513,579,512, +579,513,580, +514,580,513, +580,514,581, +515,581,514, +581,515,582, +516,582,515, +582,516,583, +517,583,516, +583,517,584, +518,584,517, +584,518,585, +519,585,518, +585,519,586, +520,586,519, +586,520,587, +521,587,520, +587,521,588, +522,588,521, +588,522,589, +523,589,522, +589,523,590, +524,590,523, +590,524,591, +525,591,524, +591,525,592, +526,592,525, +592,526,593, +527,593,526, +594,528,595, +529,595,528, +595,529,596, +530,596,529, +596,530,597, +531,597,530, +597,531,598, +532,598,531, +598,532,599, +533,599,532, +599,533,600, +534,600,533, +600,534,601, +535,601,534, +601,535,602, +536,602,535, +602,536,603, +537,603,536, +603,537,604, +538,604,537, +604,538,605, +539,605,538, +605,539,606, +540,606,539, +606,540,607, +541,607,540, +607,541,608, +542,608,541, +608,542,609, +543,609,542, +609,543,610, +544,610,543, +610,544,611, +545,611,544, +611,545,612, +546,612,545, +612,546,613, +547,613,546, +613,547,614, +548,614,547, +614,548,615, +549,615,548, +615,549,616, +550,616,549, +616,550,617, +551,617,550, +617,551,618, +552,618,551, +618,552,619, +553,619,552, +619,553,620, +554,620,553, +620,554,621, +555,621,554, +621,555,622, +556,622,555, +622,556,623, +557,623,556, +623,557,624, +558,624,557, +624,558,625, +559,625,558, +625,559,626, +560,626,559, +626,560,627, +561,627,560, +627,561,628, +562,628,561, +628,562,629, +563,629,562, +629,563,630, +564,630,563, +630,564,631, +565,631,564, +631,565,632, +566,632,565, +632,566,633, +567,633,566, +633,567,634, +568,634,567, +634,568,635, +569,635,568, +635,569,636, +570,636,569, +636,570,637, +571,637,570, +637,571,638, +572,638,571, +638,572,639, +573,639,572, +639,573,640, +574,640,573, +640,574,641, +575,641,574, +641,575,642, +576,642,575, +642,576,643, +577,643,576, +643,577,644, +578,644,577, +644,578,645, +579,645,578, +645,579,646, +580,646,579, +646,580,647, +581,647,580, +647,581,648, +582,648,581, +648,582,649, +583,649,582, +649,583,650, +584,650,583, +650,584,651, +585,651,584, +651,585,652, +586,652,585, +652,586,653, +587,653,586, +653,587,654, +588,654,587, +654,588,655, +589,655,588, +655,589,656, +590,656,589, +656,590,657, +591,657,590, +657,591,658, +592,658,591, +658,592,659, +593,659,592, +660,594,661, +595,661,594, +661,595,662, +596,662,595, +662,596,663, +597,663,596, +663,597,664, +598,664,597, +664,598,665, +599,665,598, +665,599,666, +600,666,599, +666,600,667, +601,667,600, +667,601,668, +602,668,601, +668,602,669, +603,669,602, +669,603,670, +604,670,603, +670,604,671, +605,671,604, +671,605,672, +606,672,605, +672,606,673, +607,673,606, +673,607,674, +608,674,607, +674,608,675, +609,675,608, +675,609,676, +610,676,609, +676,610,677, +611,677,610, +677,611,678, +612,678,611, +678,612,679, +613,679,612, +679,613,680, +614,680,613, +680,614,681, +615,681,614, +681,615,682, +616,682,615, +682,616,683, +617,683,616, +683,617,684, +618,684,617, +684,618,685, +619,685,618, +685,619,686, +620,686,619, +686,620,687, +621,687,620, +687,621,688, +622,688,621, +688,622,689, +623,689,622, +689,623,690, +624,690,623, +690,624,691, +625,691,624, +691,625,692, +626,692,625, +692,626,693, +627,693,626, +693,627,694, +628,694,627, +694,628,695, +629,695,628, +695,629,696, +630,696,629, +696,630,697, +631,697,630, +697,631,698, +632,698,631, +698,632,699, +633,699,632, +699,633,700, +634,700,633, +700,634,701, +635,701,634, +701,635,702, +636,702,635, +702,636,703, +637,703,636, +703,637,704, +638,704,637, +704,638,705, +639,705,638, +705,639,706, +640,706,639, +706,640,707, +641,707,640, +707,641,708, +642,708,641, +708,642,709, +643,709,642, +709,643,710, +644,710,643, +710,644,711, +645,711,644, +711,645,712, +646,712,645, +712,646,713, +647,713,646, +713,647,714, +648,714,647, +714,648,715, +649,715,648, +715,649,716, +650,716,649, +716,650,717, +651,717,650, +717,651,718, +652,718,651, +718,652,719, +653,719,652, +719,653,720, +654,720,653, +720,654,721, +655,721,654, +721,655,722, +656,722,655, +722,656,723, +657,723,656, +723,657,724, +658,724,657, +724,658,725, +659,725,658, +726,660,727, +661,727,660, +727,661,728, +662,728,661, +728,662,729, +663,729,662, +729,663,730, +664,730,663, +730,664,731, +665,731,664, +731,665,732, +666,732,665, +732,666,733, +667,733,666, +733,667,734, +668,734,667, +734,668,735, +669,735,668, +735,669,736, +670,736,669, +736,670,737, +671,737,670, +737,671,738, +672,738,671, +738,672,739, +673,739,672, +739,673,740, +674,740,673, +740,674,741, +675,741,674, +741,675,742, +676,742,675, +742,676,743, +677,743,676, +743,677,744, +678,744,677, +744,678,745, +679,745,678, +745,679,746, +680,746,679, +746,680,747, +681,747,680, +747,681,748, +682,748,681, +748,682,749, +683,749,682, +749,683,750, +684,750,683, +750,684,751, +685,751,684, +751,685,752, +686,752,685, +752,686,753, +687,753,686, +753,687,754, +688,754,687, +754,688,755, +689,755,688, +755,689,756, +690,756,689, +756,690,757, +691,757,690, +757,691,758, +692,758,691, +758,692,759, +693,759,692, +759,693,760, +694,760,693, +760,694,761, +695,761,694, +761,695,762, +696,762,695, +762,696,763, +697,763,696, +763,697,764, +698,764,697, +764,698,765, +699,765,698, +765,699,766, +700,766,699, +766,700,767, +701,767,700, +767,701,768, +702,768,701, +768,702,769, +703,769,702, +769,703,770, +704,770,703, +770,704,771, +705,771,704, +771,705,772, +706,772,705, +772,706,773, +707,773,706, +773,707,774, +708,774,707, +774,708,775, +709,775,708, +775,709,776, +710,776,709, +776,710,777, +711,777,710, +777,711,778, +712,778,711, +778,712,779, +713,779,712, +779,713,780, +714,780,713, +780,714,781, +715,781,714, +781,715,782, +716,782,715, +782,716,783, +717,783,716, +783,717,784, +718,784,717, +784,718,785, +719,785,718, +785,719,786, +720,786,719, +786,720,787, +721,787,720, +787,721,788, +722,788,721, +788,722,789, +723,789,722, +789,723,790, +724,790,723, +790,724,791, +725,791,724, +792,726,793, +727,793,726, +793,727,794, +728,794,727, +794,728,795, +729,795,728, +795,729,796, +730,796,729, +796,730,797, +731,797,730, +797,731,798, +732,798,731, +798,732,799, +733,799,732, +799,733,800, +734,800,733, +800,734,801, +735,801,734, +801,735,802, +736,802,735, +802,736,803, +737,803,736, +803,737,804, +738,804,737, +804,738,805, +739,805,738, +805,739,806, +740,806,739, +806,740,807, +741,807,740, +807,741,808, +742,808,741, +808,742,809, +743,809,742, +809,743,810, +744,810,743, +810,744,811, +745,811,744, +811,745,812, +746,812,745, +812,746,813, +747,813,746, +813,747,814, +748,814,747, +814,748,815, +749,815,748, +815,749,816, +750,816,749, +816,750,817, +751,817,750, +817,751,818, +752,818,751, +818,752,819, +753,819,752, +819,753,820, +754,820,753, +820,754,821, +755,821,754, +821,755,822, +756,822,755, +822,756,823, +757,823,756, +823,757,824, +758,824,757, +824,758,825, +759,825,758, +825,759,826, +760,826,759, +826,760,827, +761,827,760, +827,761,828, +762,828,761, +828,762,829, +763,829,762, +829,763,830, +764,830,763, +830,764,831, +765,831,764, +831,765,832, +766,832,765, +832,766,833, +767,833,766, +833,767,834, +768,834,767, +834,768,835, +769,835,768, +835,769,836, +770,836,769, +836,770,837, +771,837,770, +837,771,838, +772,838,771, +838,772,839, +773,839,772, +839,773,840, +774,840,773, +840,774,841, +775,841,774, +841,775,842, +776,842,775, +842,776,843, +777,843,776, +843,777,844, +778,844,777, +844,778,845, +779,845,778, +845,779,846, +780,846,779, +846,780,847, +781,847,780, +847,781,848, +782,848,781, +848,782,849, +783,849,782, +849,783,850, +784,850,783, +850,784,851, +785,851,784, +851,785,852, +786,852,785, +852,786,853, +787,853,786, +853,787,854, +788,854,787, +854,788,855, +789,855,788, +855,789,856, +790,856,789, +856,790,857, +791,857,790, +858,792,859, +793,859,792, +859,793,860, +794,860,793, +860,794,861, +795,861,794, +861,795,862, +796,862,795, +862,796,863, +797,863,796, +863,797,864, +798,864,797, +864,798,865, +799,865,798, +865,799,866, +800,866,799, +866,800,867, +801,867,800, +867,801,868, +802,868,801, +868,802,869, +803,869,802, +869,803,870, +804,870,803, +870,804,871, +805,871,804, +871,805,872, +806,872,805, +872,806,873, +807,873,806, +873,807,874, +808,874,807, +874,808,875, +809,875,808, +875,809,876, +810,876,809, +876,810,877, +811,877,810, +877,811,878, +812,878,811, +878,812,879, +813,879,812, +879,813,880, +814,880,813, +880,814,881, +815,881,814, +881,815,882, +816,882,815, +882,816,883, +817,883,816, +883,817,884, +818,884,817, +884,818,885, +819,885,818, +885,819,886, +820,886,819, +886,820,887, +821,887,820, +887,821,888, +822,888,821, +888,822,889, +823,889,822, +889,823,890, +824,890,823, +890,824,891, +825,891,824, +891,825,892, +826,892,825, +892,826,893, +827,893,826, +893,827,894, +828,894,827, +894,828,895, +829,895,828, +895,829,896, +830,896,829, +896,830,897, +831,897,830, +897,831,898, +832,898,831, +898,832,899, +833,899,832, +899,833,900, +834,900,833, +900,834,901, +835,901,834, +901,835,902, +836,902,835, +902,836,903, +837,903,836, +903,837,904, +838,904,837, +904,838,905, +839,905,838, +905,839,906, +840,906,839, +906,840,907, +841,907,840, +907,841,908, +842,908,841, +908,842,909, +843,909,842, +909,843,910, +844,910,843, +910,844,911, +845,911,844, +911,845,912, +846,912,845, +912,846,913, +847,913,846, +913,847,914, +848,914,847, +914,848,915, +849,915,848, +915,849,916, +850,916,849, +916,850,917, +851,917,850, +917,851,918, +852,918,851, +918,852,919, +853,919,852, +919,853,920, +854,920,853, +920,854,921, +855,921,854, +921,855,922, +856,922,855, +922,856,923, +857,923,856, +924,858,925, +859,925,858, +925,859,926, +860,926,859, +926,860,927, +861,927,860, +927,861,928, +862,928,861, +928,862,929, +863,929,862, +929,863,930, +864,930,863, +930,864,931, +865,931,864, +931,865,932, +866,932,865, +932,866,933, +867,933,866, +933,867,934, +868,934,867, +934,868,935, +869,935,868, +935,869,936, +870,936,869, +936,870,937, +871,937,870, +937,871,938, +872,938,871, +938,872,939, +873,939,872, +939,873,940, +874,940,873, +940,874,941, +875,941,874, +941,875,942, +876,942,875, +942,876,943, +877,943,876, +943,877,944, +878,944,877, +944,878,945, +879,945,878, +945,879,946, +880,946,879, +946,880,947, +881,947,880, +947,881,948, +882,948,881, +948,882,949, +883,949,882, +949,883,950, +884,950,883, +950,884,951, +885,951,884, +951,885,952, +886,952,885, +952,886,953, +887,953,886, +953,887,954, +888,954,887, +954,888,955, +889,955,888, +955,889,956, +890,956,889, +956,890,957, +891,957,890, +957,891,958, +892,958,891, +958,892,959, +893,959,892, +959,893,960, +894,960,893, +960,894,961, +895,961,894, +961,895,962, +896,962,895, +962,896,963, +897,963,896, +963,897,964, +898,964,897, +964,898,965, +899,965,898, +965,899,966, +900,966,899, +966,900,967, +901,967,900, +967,901,968, +902,968,901, +968,902,969, +903,969,902, +969,903,970, +904,970,903, +970,904,971, +905,971,904, +971,905,972, +906,972,905, +972,906,973, +907,973,906, +973,907,974, +908,974,907, +974,908,975, +909,975,908, +975,909,976, +910,976,909, +976,910,977, +911,977,910, +977,911,978, +912,978,911, +978,912,979, +913,979,912, +979,913,980, +914,980,913, +980,914,981, +915,981,914, +981,915,982, +916,982,915, +982,916,983, +917,983,916, +983,917,984, +918,984,917, +984,918,985, +919,985,918, +985,919,986, +920,986,919, +986,920,987, +921,987,920, +987,921,988, +922,988,921, +988,922,989, +923,989,922, +990,924,991, +925,991,924, +991,925,992, +926,992,925, +992,926,993, +927,993,926, +993,927,994, +928,994,927, +994,928,995, +929,995,928, +995,929,996, +930,996,929, +996,930,997, +931,997,930, +997,931,998, +932,998,931, +998,932,999, +933,999,932, +999,933,1000, +934,1000,933, +1000,934,1001, +935,1001,934, +1001,935,1002, +936,1002,935, +1002,936,1003, +937,1003,936, +1003,937,1004, +938,1004,937, +1004,938,1005, +939,1005,938, +1005,939,1006, +940,1006,939, +1006,940,1007, +941,1007,940, +1007,941,1008, +942,1008,941, +1008,942,1009, +943,1009,942, +1009,943,1010, +944,1010,943, +1010,944,1011, +945,1011,944, +1011,945,1012, +946,1012,945, +1012,946,1013, +947,1013,946, +1013,947,1014, +948,1014,947, +1014,948,1015, +949,1015,948, +1015,949,1016, +950,1016,949, +1016,950,1017, +951,1017,950, +1017,951,1018, +952,1018,951, +1018,952,1019, +953,1019,952, +1019,953,1020, +954,1020,953, +1020,954,1021, +955,1021,954, +1021,955,1022, +956,1022,955, +1022,956,1023, +957,1023,956, +1023,957,1024, +958,1024,957, +1024,958,1025, +959,1025,958, +1025,959,1026, +960,1026,959, +1026,960,1027, +961,1027,960, +1027,961,1028, +962,1028,961, +1028,962,1029, +963,1029,962, +1029,963,1030, +964,1030,963, +1030,964,1031, +965,1031,964, +1031,965,1032, +966,1032,965, +1032,966,1033, +967,1033,966, +1033,967,1034, +968,1034,967, +1034,968,1035, +969,1035,968, +1035,969,1036, +970,1036,969, +1036,970,1037, +971,1037,970, +1037,971,1038, +972,1038,971, +1038,972,1039, +973,1039,972, +1039,973,1040, +974,1040,973, +1040,974,1041, +975,1041,974, +1041,975,1042, +976,1042,975, +1042,976,1043, +977,1043,976, +1043,977,1044, +978,1044,977, +1044,978,1045, +979,1045,978, +1045,979,1046, +980,1046,979, +1046,980,1047, +981,1047,980, +1047,981,1048, +982,1048,981, +1048,982,1049, +983,1049,982, +1049,983,1050, +984,1050,983, +1050,984,1051, +985,1051,984, +1051,985,1052, +986,1052,985, +1052,986,1053, +987,1053,986, +1053,987,1054, +988,1054,987, +1054,988,1055, +989,1055,988, +1056,990,1057, +991,1057,990, +1057,991,1058, +992,1058,991, +1058,992,1059, +993,1059,992, +1059,993,1060, +994,1060,993, +1060,994,1061, +995,1061,994, +1061,995,1062, +996,1062,995, +1062,996,1063, +997,1063,996, +1063,997,1064, +998,1064,997, +1064,998,1065, +999,1065,998, +1065,999,1066, +1000,1066,999, +1066,1000,1067, +1001,1067,1000, +1067,1001,1068, +1002,1068,1001, +1068,1002,1069, +1003,1069,1002, +1069,1003,1070, +1004,1070,1003, +1070,1004,1071, +1005,1071,1004, +1071,1005,1072, +1006,1072,1005, +1072,1006,1073, +1007,1073,1006, +1073,1007,1074, +1008,1074,1007, +1074,1008,1075, +1009,1075,1008, +1075,1009,1076, +1010,1076,1009, +1076,1010,1077, +1011,1077,1010, +1077,1011,1078, +1012,1078,1011, +1078,1012,1079, +1013,1079,1012, +1079,1013,1080, +1014,1080,1013, +1080,1014,1081, +1015,1081,1014, +1081,1015,1082, +1016,1082,1015, +1082,1016,1083, +1017,1083,1016, +1083,1017,1084, +1018,1084,1017, +1084,1018,1085, +1019,1085,1018, +1085,1019,1086, +1020,1086,1019, +1086,1020,1087, +1021,1087,1020, +1087,1021,1088, +1022,1088,1021, +1088,1022,1089, +1023,1089,1022, +1089,1023,1090, +1024,1090,1023, +1090,1024,1091, +1025,1091,1024, +1091,1025,1092, +1026,1092,1025, +1092,1026,1093, +1027,1093,1026, +1093,1027,1094, +1028,1094,1027, +1094,1028,1095, +1029,1095,1028, +1095,1029,1096, +1030,1096,1029, +1096,1030,1097, +1031,1097,1030, +1097,1031,1098, +1032,1098,1031, +1098,1032,1099, +1033,1099,1032, +1099,1033,1100, +1034,1100,1033, +1100,1034,1101, +1035,1101,1034, +1101,1035,1102, +1036,1102,1035, +1102,1036,1103, +1037,1103,1036, +1103,1037,1104, +1038,1104,1037, +1104,1038,1105, +1039,1105,1038, +1105,1039,1106, +1040,1106,1039, +1106,1040,1107, +1041,1107,1040, +1107,1041,1108, +1042,1108,1041, +1108,1042,1109, +1043,1109,1042, +1109,1043,1110, +1044,1110,1043, +1110,1044,1111, +1045,1111,1044, +1111,1045,1112, +1046,1112,1045, +1112,1046,1113, +1047,1113,1046, +1113,1047,1114, +1048,1114,1047, +1114,1048,1115, +1049,1115,1048, +1115,1049,1116, +1050,1116,1049, +1116,1050,1117, +1051,1117,1050, +1117,1051,1118, +1052,1118,1051, +1118,1052,1119, +1053,1119,1052, +1119,1053,1120, +1054,1120,1053, +1120,1054,1121, +1055,1121,1054, +1122,1056,1123, +1057,1123,1056, +1123,1057,1124, +1058,1124,1057, +1124,1058,1125, +1059,1125,1058, +1125,1059,1126, +1060,1126,1059, +1126,1060,1127, +1061,1127,1060, +1127,1061,1128, +1062,1128,1061, +1128,1062,1129, +1063,1129,1062, +1129,1063,1130, +1064,1130,1063, +1130,1064,1131, +1065,1131,1064, +1131,1065,1132, +1066,1132,1065, +1132,1066,1133, +1067,1133,1066, +1133,1067,1134, +1068,1134,1067, +1134,1068,1135, +1069,1135,1068, +1135,1069,1136, +1070,1136,1069, +1136,1070,1137, +1071,1137,1070, +1137,1071,1138, +1072,1138,1071, +1138,1072,1139, +1073,1139,1072, +1139,1073,1140, +1074,1140,1073, +1140,1074,1141, +1075,1141,1074, +1141,1075,1142, +1076,1142,1075, +1142,1076,1143, +1077,1143,1076, +1143,1077,1144, +1078,1144,1077, +1144,1078,1145, +1079,1145,1078, +1145,1079,1146, +1080,1146,1079, +1146,1080,1147, +1081,1147,1080, +1147,1081,1148, +1082,1148,1081, +1148,1082,1149, +1083,1149,1082, +1149,1083,1150, +1084,1150,1083, +1150,1084,1151, +1085,1151,1084, +1151,1085,1152, +1086,1152,1085, +1152,1086,1153, +1087,1153,1086, +1153,1087,1154, +1088,1154,1087, +1154,1088,1155, +1089,1155,1088, +1155,1089,1156, +1090,1156,1089, +1156,1090,1157, +1091,1157,1090, +1157,1091,1158, +1092,1158,1091, +1158,1092,1159, +1093,1159,1092, +1159,1093,1160, +1094,1160,1093, +1160,1094,1161, +1095,1161,1094, +1161,1095,1162, +1096,1162,1095, +1162,1096,1163, +1097,1163,1096, +1163,1097,1164, +1098,1164,1097, +1164,1098,1165, +1099,1165,1098, +1165,1099,1166, +1100,1166,1099, +1166,1100,1167, +1101,1167,1100, +1167,1101,1168, +1102,1168,1101, +1168,1102,1169, +1103,1169,1102, +1169,1103,1170, +1104,1170,1103, +1170,1104,1171, +1105,1171,1104, +1171,1105,1172, +1106,1172,1105, +1172,1106,1173, +1107,1173,1106, +1173,1107,1174, +1108,1174,1107, +1174,1108,1175, +1109,1175,1108, +1175,1109,1176, +1110,1176,1109, +1176,1110,1177, +1111,1177,1110, +1177,1111,1178, +1112,1178,1111, +1178,1112,1179, +1113,1179,1112, +1179,1113,1180, +1114,1180,1113, +1180,1114,1181, +1115,1181,1114, +1181,1115,1182, +1116,1182,1115, +1182,1116,1183, +1117,1183,1116, +1183,1117,1184, +1118,1184,1117, +1184,1118,1185, +1119,1185,1118, +1185,1119,1186, +1120,1186,1119, +1186,1120,1187, +1121,1187,1120, +1188,1122,1189, +1123,1189,1122, +1189,1123,1190, +1124,1190,1123, +1190,1124,1191, +1125,1191,1124, +1191,1125,1192, +1126,1192,1125, +1192,1126,1193, +1127,1193,1126, +1193,1127,1194, +1128,1194,1127, +1194,1128,1195, +1129,1195,1128, +1195,1129,1196, +1130,1196,1129, +1196,1130,1197, +1131,1197,1130, +1197,1131,1198, +1132,1198,1131, +1198,1132,1199, +1133,1199,1132, +1199,1133,1200, +1134,1200,1133, +1200,1134,1201, +1135,1201,1134, +1201,1135,1202, +1136,1202,1135, +1202,1136,1203, +1137,1203,1136, +1203,1137,1204, +1138,1204,1137, +1204,1138,1205, +1139,1205,1138, +1205,1139,1206, +1140,1206,1139, +1206,1140,1207, +1141,1207,1140, +1207,1141,1208, +1142,1208,1141, +1208,1142,1209, +1143,1209,1142, +1209,1143,1210, +1144,1210,1143, +1210,1144,1211, +1145,1211,1144, +1211,1145,1212, +1146,1212,1145, +1212,1146,1213, +1147,1213,1146, +1213,1147,1214, +1148,1214,1147, +1214,1148,1215, +1149,1215,1148, +1215,1149,1216, +1150,1216,1149, +1216,1150,1217, +1151,1217,1150, +1217,1151,1218, +1152,1218,1151, +1218,1152,1219, +1153,1219,1152, +1219,1153,1220, +1154,1220,1153, +1220,1154,1221, +1155,1221,1154, +1221,1155,1222, +1156,1222,1155, +1222,1156,1223, +1157,1223,1156, +1223,1157,1224, +1158,1224,1157, +1224,1158,1225, +1159,1225,1158, +1225,1159,1226, +1160,1226,1159, +1226,1160,1227, +1161,1227,1160, +1227,1161,1228, +1162,1228,1161, +1228,1162,1229, +1163,1229,1162, +1229,1163,1230, +1164,1230,1163, +1230,1164,1231, +1165,1231,1164, +1231,1165,1232, +1166,1232,1165, +1232,1166,1233, +1167,1233,1166, +1233,1167,1234, +1168,1234,1167, +1234,1168,1235, +1169,1235,1168, +1235,1169,1236, +1170,1236,1169, +1236,1170,1237, +1171,1237,1170, +1237,1171,1238, +1172,1238,1171, +1238,1172,1239, +1173,1239,1172, +1239,1173,1240, +1174,1240,1173, +1240,1174,1241, +1175,1241,1174, +1241,1175,1242, +1176,1242,1175, +1242,1176,1243, +1177,1243,1176, +1243,1177,1244, +1178,1244,1177, +1244,1178,1245, +1179,1245,1178, +1245,1179,1246, +1180,1246,1179, +1246,1180,1247, +1181,1247,1180, +1247,1181,1248, +1182,1248,1181, +1248,1182,1249, +1183,1249,1182, +1249,1183,1250, +1184,1250,1183, +1250,1184,1251, +1185,1251,1184, +1251,1185,1252, +1186,1252,1185, +1252,1186,1253, +1187,1253,1186, +1254,1188,1255, +1189,1255,1188, +1255,1189,1256, +1190,1256,1189, +1256,1190,1257, +1191,1257,1190, +1257,1191,1258, +1192,1258,1191, +1258,1192,1259, +1193,1259,1192, +1259,1193,1260, +1194,1260,1193, +1260,1194,1261, +1195,1261,1194, +1261,1195,1262, +1196,1262,1195, +1262,1196,1263, +1197,1263,1196, +1263,1197,1264, +1198,1264,1197, +1264,1198,1265, +1199,1265,1198, +1265,1199,1266, +1200,1266,1199, +1266,1200,1267, +1201,1267,1200, +1267,1201,1268, +1202,1268,1201, +1268,1202,1269, +1203,1269,1202, +1269,1203,1270, +1204,1270,1203, +1270,1204,1271, +1205,1271,1204, +1271,1205,1272, +1206,1272,1205, +1272,1206,1273, +1207,1273,1206, +1273,1207,1274, +1208,1274,1207, +1274,1208,1275, +1209,1275,1208, +1275,1209,1276, +1210,1276,1209, +1276,1210,1277, +1211,1277,1210, +1277,1211,1278, +1212,1278,1211, +1278,1212,1279, +1213,1279,1212, +1279,1213,1280, +1214,1280,1213, +1280,1214,1281, +1215,1281,1214, +1281,1215,1282, +1216,1282,1215, +1282,1216,1283, +1217,1283,1216, +1283,1217,1284, +1218,1284,1217, +1284,1218,1285, +1219,1285,1218, +1285,1219,1286, +1220,1286,1219, +1286,1220,1287, +1221,1287,1220, +1287,1221,1288, +1222,1288,1221, +1288,1222,1289, +1223,1289,1222, +1289,1223,1290, +1224,1290,1223, +1290,1224,1291, +1225,1291,1224, +1291,1225,1292, +1226,1292,1225, +1292,1226,1293, +1227,1293,1226, +1293,1227,1294, +1228,1294,1227, +1294,1228,1295, +1229,1295,1228, +1295,1229,1296, +1230,1296,1229, +1296,1230,1297, +1231,1297,1230, +1297,1231,1298, +1232,1298,1231, +1298,1232,1299, +1233,1299,1232, +1299,1233,1300, +1234,1300,1233, +1300,1234,1301, +1235,1301,1234, +1301,1235,1302, +1236,1302,1235, +1302,1236,1303, +1237,1303,1236, +1303,1237,1304, +1238,1304,1237, +1304,1238,1305, +1239,1305,1238, +1305,1239,1306, +1240,1306,1239, +1306,1240,1307, +1241,1307,1240, +1307,1241,1308, +1242,1308,1241, +1308,1242,1309, +1243,1309,1242, +1309,1243,1310, +1244,1310,1243, +1310,1244,1311, +1245,1311,1244, +1311,1245,1312, +1246,1312,1245, +1312,1246,1313, +1247,1313,1246, +1313,1247,1314, +1248,1314,1247, +1314,1248,1315, +1249,1315,1248, +1315,1249,1316, +1250,1316,1249, +1316,1250,1317, +1251,1317,1250, +1317,1251,1318, +1252,1318,1251, +1318,1252,1319, +1253,1319,1252, +1320,1254,1321, +1255,1321,1254, +1321,1255,1322, +1256,1322,1255, +1322,1256,1323, +1257,1323,1256, +1323,1257,1324, +1258,1324,1257, +1324,1258,1325, +1259,1325,1258, +1325,1259,1326, +1260,1326,1259, +1326,1260,1327, +1261,1327,1260, +1327,1261,1328, +1262,1328,1261, +1328,1262,1329, +1263,1329,1262, +1329,1263,1330, +1264,1330,1263, +1330,1264,1331, +1265,1331,1264, +1331,1265,1332, +1266,1332,1265, +1332,1266,1333, +1267,1333,1266, +1333,1267,1334, +1268,1334,1267, +1334,1268,1335, +1269,1335,1268, +1335,1269,1336, +1270,1336,1269, +1336,1270,1337, +1271,1337,1270, +1337,1271,1338, +1272,1338,1271, +1338,1272,1339, +1273,1339,1272, +1339,1273,1340, +1274,1340,1273, +1340,1274,1341, +1275,1341,1274, +1341,1275,1342, +1276,1342,1275, +1342,1276,1343, +1277,1343,1276, +1343,1277,1344, +1278,1344,1277, +1344,1278,1345, +1279,1345,1278, +1345,1279,1346, +1280,1346,1279, +1346,1280,1347, +1281,1347,1280, +1347,1281,1348, +1282,1348,1281, +1348,1282,1349, +1283,1349,1282, +1349,1283,1350, +1284,1350,1283, +1350,1284,1351, +1285,1351,1284, +1351,1285,1352, +1286,1352,1285, +1352,1286,1353, +1287,1353,1286, +1353,1287,1354, +1288,1354,1287, +1354,1288,1355, +1289,1355,1288, +1355,1289,1356, +1290,1356,1289, +1356,1290,1357, +1291,1357,1290, +1357,1291,1358, +1292,1358,1291, +1358,1292,1359, +1293,1359,1292, +1359,1293,1360, +1294,1360,1293, +1360,1294,1361, +1295,1361,1294, +1361,1295,1362, +1296,1362,1295, +1362,1296,1363, +1297,1363,1296, +1363,1297,1364, +1298,1364,1297, +1364,1298,1365, +1299,1365,1298, +1365,1299,1366, +1300,1366,1299, +1366,1300,1367, +1301,1367,1300, +1367,1301,1368, +1302,1368,1301, +1368,1302,1369, +1303,1369,1302, +1369,1303,1370, +1304,1370,1303, +1370,1304,1371, +1305,1371,1304, +1371,1305,1372, +1306,1372,1305, +1372,1306,1373, +1307,1373,1306, +1373,1307,1374, +1308,1374,1307, +1374,1308,1375, +1309,1375,1308, +1375,1309,1376, +1310,1376,1309, +1376,1310,1377, +1311,1377,1310, +1377,1311,1378, +1312,1378,1311, +1378,1312,1379, +1313,1379,1312, +1379,1313,1380, +1314,1380,1313, +1380,1314,1381, +1315,1381,1314, +1381,1315,1382, +1316,1382,1315, +1382,1316,1383, +1317,1383,1316, +1383,1317,1384, +1318,1384,1317, +1384,1318,1385, +1319,1385,1318, +1386,1320,1387, +1321,1387,1320, +1387,1321,1388, +1322,1388,1321, +1388,1322,1389, +1323,1389,1322, +1389,1323,1390, +1324,1390,1323, +1390,1324,1391, +1325,1391,1324, +1391,1325,1392, +1326,1392,1325, +1392,1326,1393, +1327,1393,1326, +1393,1327,1394, +1328,1394,1327, +1394,1328,1395, +1329,1395,1328, +1395,1329,1396, +1330,1396,1329, +1396,1330,1397, +1331,1397,1330, +1397,1331,1398, +1332,1398,1331, +1398,1332,1399, +1333,1399,1332, +1399,1333,1400, +1334,1400,1333, +1400,1334,1401, +1335,1401,1334, +1401,1335,1402, +1336,1402,1335, +1402,1336,1403, +1337,1403,1336, +1403,1337,1404, +1338,1404,1337, +1404,1338,1405, +1339,1405,1338, +1405,1339,1406, +1340,1406,1339, +1406,1340,1407, +1341,1407,1340, +1407,1341,1408, +1342,1408,1341, +1408,1342,1409, +1343,1409,1342, +1409,1343,1410, +1344,1410,1343, +1410,1344,1411, +1345,1411,1344, +1411,1345,1412, +1346,1412,1345, +1412,1346,1413, +1347,1413,1346, +1413,1347,1414, +1348,1414,1347, +1414,1348,1415, +1349,1415,1348, +1415,1349,1416, +1350,1416,1349, +1416,1350,1417, +1351,1417,1350, +1417,1351,1418, +1352,1418,1351, +1418,1352,1419, +1353,1419,1352, +1419,1353,1420, +1354,1420,1353, +1420,1354,1421, +1355,1421,1354, +1421,1355,1422, +1356,1422,1355, +1422,1356,1423, +1357,1423,1356, +1423,1357,1424, +1358,1424,1357, +1424,1358,1425, +1359,1425,1358, +1425,1359,1426, +1360,1426,1359, +1426,1360,1427, +1361,1427,1360, +1427,1361,1428, +1362,1428,1361, +1428,1362,1429, +1363,1429,1362, +1429,1363,1430, +1364,1430,1363, +1430,1364,1431, +1365,1431,1364, +1431,1365,1432, +1366,1432,1365, +1432,1366,1433, +1367,1433,1366, +1433,1367,1434, +1368,1434,1367, +1434,1368,1435, +1369,1435,1368, +1435,1369,1436, +1370,1436,1369, +1436,1370,1437, +1371,1437,1370, +1437,1371,1438, +1372,1438,1371, +1438,1372,1439, +1373,1439,1372, +1439,1373,1440, +1374,1440,1373, +1440,1374,1441, +1375,1441,1374, +1441,1375,1442, +1376,1442,1375, +1442,1376,1443, +1377,1443,1376, +1443,1377,1444, +1378,1444,1377, +1444,1378,1445, +1379,1445,1378, +1445,1379,1446, +1380,1446,1379, +1446,1380,1447, +1381,1447,1380, +1447,1381,1448, +1382,1448,1381, +1448,1382,1449, +1383,1449,1382, +1449,1383,1450, +1384,1450,1383, +1450,1384,1451, +1385,1451,1384, +1452,1386,1453, +1387,1453,1386, +1453,1387,1454, +1388,1454,1387, +1454,1388,1455, +1389,1455,1388, +1455,1389,1456, +1390,1456,1389, +1456,1390,1457, +1391,1457,1390, +1457,1391,1458, +1392,1458,1391, +1458,1392,1459, +1393,1459,1392, +1459,1393,1460, +1394,1460,1393, +1460,1394,1461, +1395,1461,1394, +1461,1395,1462, +1396,1462,1395, +1462,1396,1463, +1397,1463,1396, +1463,1397,1464, +1398,1464,1397, +1464,1398,1465, +1399,1465,1398, +1465,1399,1466, +1400,1466,1399, +1466,1400,1467, +1401,1467,1400, +1467,1401,1468, +1402,1468,1401, +1468,1402,1469, +1403,1469,1402, +1469,1403,1470, +1404,1470,1403, +1470,1404,1471, +1405,1471,1404, +1471,1405,1472, +1406,1472,1405, +1472,1406,1473, +1407,1473,1406, +1473,1407,1474, +1408,1474,1407, +1474,1408,1475, +1409,1475,1408, +1475,1409,1476, +1410,1476,1409, +1476,1410,1477, +1411,1477,1410, +1477,1411,1478, +1412,1478,1411, +1478,1412,1479, +1413,1479,1412, +1479,1413,1480, +1414,1480,1413, +1480,1414,1481, +1415,1481,1414, +1481,1415,1482, +1416,1482,1415, +1482,1416,1483, +1417,1483,1416, +1483,1417,1484, +1418,1484,1417, +1484,1418,1485, +1419,1485,1418, +1485,1419,1486, +1420,1486,1419, +1486,1420,1487, +1421,1487,1420, +1487,1421,1488, +1422,1488,1421, +1488,1422,1489, +1423,1489,1422, +1489,1423,1490, +1424,1490,1423, +1490,1424,1491, +1425,1491,1424, +1491,1425,1492, +1426,1492,1425, +1492,1426,1493, +1427,1493,1426, +1493,1427,1494, +1428,1494,1427, +1494,1428,1495, +1429,1495,1428, +1495,1429,1496, +1430,1496,1429, +1496,1430,1497, +1431,1497,1430, +1497,1431,1498, +1432,1498,1431, +1498,1432,1499, +1433,1499,1432, +1499,1433,1500, +1434,1500,1433, +1500,1434,1501, +1435,1501,1434, +1501,1435,1502, +1436,1502,1435, +1502,1436,1503, +1437,1503,1436, +1503,1437,1504, +1438,1504,1437, +1504,1438,1505, +1439,1505,1438, +1505,1439,1506, +1440,1506,1439, +1506,1440,1507, +1441,1507,1440, +1507,1441,1508, +1442,1508,1441, +1508,1442,1509, +1443,1509,1442, +1509,1443,1510, +1444,1510,1443, +1510,1444,1511, +1445,1511,1444, +1511,1445,1512, +1446,1512,1445, +1512,1446,1513, +1447,1513,1446, +1513,1447,1514, +1448,1514,1447, +1514,1448,1515, +1449,1515,1448, +1515,1449,1516, +1450,1516,1449, +1516,1450,1517, +1451,1517,1450, +1518,1452,1519, +1453,1519,1452, +1519,1453,1520, +1454,1520,1453, +1520,1454,1521, +1455,1521,1454, +1521,1455,1522, +1456,1522,1455, +1522,1456,1523, +1457,1523,1456, +1523,1457,1524, +1458,1524,1457, +1524,1458,1525, +1459,1525,1458, +1525,1459,1526, +1460,1526,1459, +1526,1460,1527, +1461,1527,1460, +1527,1461,1528, +1462,1528,1461, +1528,1462,1529, +1463,1529,1462, +1529,1463,1530, +1464,1530,1463, +1530,1464,1531, +1465,1531,1464, +1531,1465,1532, +1466,1532,1465, +1532,1466,1533, +1467,1533,1466, +1533,1467,1534, +1468,1534,1467, +1534,1468,1535, +1469,1535,1468, +1535,1469,1536, +1470,1536,1469, +1536,1470,1537, +1471,1537,1470, +1537,1471,1538, +1472,1538,1471, +1538,1472,1539, +1473,1539,1472, +1539,1473,1540, +1474,1540,1473, +1540,1474,1541, +1475,1541,1474, +1541,1475,1542, +1476,1542,1475, +1542,1476,1543, +1477,1543,1476, +1543,1477,1544, +1478,1544,1477, +1544,1478,1545, +1479,1545,1478, +1545,1479,1546, +1480,1546,1479, +1546,1480,1547, +1481,1547,1480, +1547,1481,1548, +1482,1548,1481, +1548,1482,1549, +1483,1549,1482, +1549,1483,1550, +1484,1550,1483, +1550,1484,1551, +1485,1551,1484, +1551,1485,1552, +1486,1552,1485, +1552,1486,1553, +1487,1553,1486, +1553,1487,1554, +1488,1554,1487, +1554,1488,1555, +1489,1555,1488, +1555,1489,1556, +1490,1556,1489, +1556,1490,1557, +1491,1557,1490, +1557,1491,1558, +1492,1558,1491, +1558,1492,1559, +1493,1559,1492, +1559,1493,1560, +1494,1560,1493, +1560,1494,1561, +1495,1561,1494, +1561,1495,1562, +1496,1562,1495, +1562,1496,1563, +1497,1563,1496, +1563,1497,1564, +1498,1564,1497, +1564,1498,1565, +1499,1565,1498, +1565,1499,1566, +1500,1566,1499, +1566,1500,1567, +1501,1567,1500, +1567,1501,1568, +1502,1568,1501, +1568,1502,1569, +1503,1569,1502, +1569,1503,1570, +1504,1570,1503, +1570,1504,1571, +1505,1571,1504, +1571,1505,1572, +1506,1572,1505, +1572,1506,1573, +1507,1573,1506, +1573,1507,1574, +1508,1574,1507, +1574,1508,1575, +1509,1575,1508, +1575,1509,1576, +1510,1576,1509, +1576,1510,1577, +1511,1577,1510, +1577,1511,1578, +1512,1578,1511, +1578,1512,1579, +1513,1579,1512, +1579,1513,1580, +1514,1580,1513, +1580,1514,1581, +1515,1581,1514, +1581,1515,1582, +1516,1582,1515, +1582,1516,1583, +1517,1583,1516, +1584,1518,1585, +1519,1585,1518, +1585,1519,1586, +1520,1586,1519, +1586,1520,1587, +1521,1587,1520, +1587,1521,1588, +1522,1588,1521, +1588,1522,1589, +1523,1589,1522, +1589,1523,1590, +1524,1590,1523, +1590,1524,1591, +1525,1591,1524, +1591,1525,1592, +1526,1592,1525, +1592,1526,1593, +1527,1593,1526, +1593,1527,1594, +1528,1594,1527, +1594,1528,1595, +1529,1595,1528, +1595,1529,1596, +1530,1596,1529, +1596,1530,1597, +1531,1597,1530, +1597,1531,1598, +1532,1598,1531, +1598,1532,1599, +1533,1599,1532, +1599,1533,1600, +1534,1600,1533, +1600,1534,1601, +1535,1601,1534, +1601,1535,1602, +1536,1602,1535, +1602,1536,1603, +1537,1603,1536, +1603,1537,1604, +1538,1604,1537, +1604,1538,1605, +1539,1605,1538, +1605,1539,1606, +1540,1606,1539, +1606,1540,1607, +1541,1607,1540, +1607,1541,1608, +1542,1608,1541, +1608,1542,1609, +1543,1609,1542, +1609,1543,1610, +1544,1610,1543, +1610,1544,1611, +1545,1611,1544, +1611,1545,1612, +1546,1612,1545, +1612,1546,1613, +1547,1613,1546, +1613,1547,1614, +1548,1614,1547, +1614,1548,1615, +1549,1615,1548, +1615,1549,1616, +1550,1616,1549, +1616,1550,1617, +1551,1617,1550, +1617,1551,1618, +1552,1618,1551, +1618,1552,1619, +1553,1619,1552, +1619,1553,1620, +1554,1620,1553, +1620,1554,1621, +1555,1621,1554, +1621,1555,1622, +1556,1622,1555, +1622,1556,1623, +1557,1623,1556, +1623,1557,1624, +1558,1624,1557, +1624,1558,1625, +1559,1625,1558, +1625,1559,1626, +1560,1626,1559, +1626,1560,1627, +1561,1627,1560, +1627,1561,1628, +1562,1628,1561, +1628,1562,1629, +1563,1629,1562, +1629,1563,1630, +1564,1630,1563, +1630,1564,1631, +1565,1631,1564, +1631,1565,1632, +1566,1632,1565, +1632,1566,1633, +1567,1633,1566, +1633,1567,1634, +1568,1634,1567, +1634,1568,1635, +1569,1635,1568, +1635,1569,1636, +1570,1636,1569, +1636,1570,1637, +1571,1637,1570, +1637,1571,1638, +1572,1638,1571, +1638,1572,1639, +1573,1639,1572, +1639,1573,1640, +1574,1640,1573, +1640,1574,1641, +1575,1641,1574, +1641,1575,1642, +1576,1642,1575, +1642,1576,1643, +1577,1643,1576, +1643,1577,1644, +1578,1644,1577, +1644,1578,1645, +1579,1645,1578, +1645,1579,1646, +1580,1646,1579, +1646,1580,1647, +1581,1647,1580, +1647,1581,1648, +1582,1648,1581, +1648,1582,1649, +1583,1649,1582, +1650,1584,1651, +1585,1651,1584, +1651,1585,1652, +1586,1652,1585, +1652,1586,1653, +1587,1653,1586, +1653,1587,1654, +1588,1654,1587, +1654,1588,1655, +1589,1655,1588, +1655,1589,1656, +1590,1656,1589, +1656,1590,1657, +1591,1657,1590, +1657,1591,1658, +1592,1658,1591, +1658,1592,1659, +1593,1659,1592, +1659,1593,1660, +1594,1660,1593, +1660,1594,1661, +1595,1661,1594, +1661,1595,1662, +1596,1662,1595, +1662,1596,1663, +1597,1663,1596, +1663,1597,1664, +1598,1664,1597, +1664,1598,1665, +1599,1665,1598, +1665,1599,1666, +1600,1666,1599, +1666,1600,1667, +1601,1667,1600, +1667,1601,1668, +1602,1668,1601, +1668,1602,1669, +1603,1669,1602, +1669,1603,1670, +1604,1670,1603, +1670,1604,1671, +1605,1671,1604, +1671,1605,1672, +1606,1672,1605, +1672,1606,1673, +1607,1673,1606, +1673,1607,1674, +1608,1674,1607, +1674,1608,1675, +1609,1675,1608, +1675,1609,1676, +1610,1676,1609, +1676,1610,1677, +1611,1677,1610, +1677,1611,1678, +1612,1678,1611, +1678,1612,1679, +1613,1679,1612, +1679,1613,1680, +1614,1680,1613, +1680,1614,1681, +1615,1681,1614, +1681,1615,1682, +1616,1682,1615, +1682,1616,1683, +1617,1683,1616, +1683,1617,1684, +1618,1684,1617, +1684,1618,1685, +1619,1685,1618, +1685,1619,1686, +1620,1686,1619, +1686,1620,1687, +1621,1687,1620, +1687,1621,1688, +1622,1688,1621, +1688,1622,1689, +1623,1689,1622, +1689,1623,1690, +1624,1690,1623, +1690,1624,1691, +1625,1691,1624, +1691,1625,1692, +1626,1692,1625, +1692,1626,1693, +1627,1693,1626, +1693,1627,1694, +1628,1694,1627, +1694,1628,1695, +1629,1695,1628, +1695,1629,1696, +1630,1696,1629, +1696,1630,1697, +1631,1697,1630, +1697,1631,1698, +1632,1698,1631, +1698,1632,1699, +1633,1699,1632, +1699,1633,1700, +1634,1700,1633, +1700,1634,1701, +1635,1701,1634, +1701,1635,1702, +1636,1702,1635, +1702,1636,1703, +1637,1703,1636, +1703,1637,1704, +1638,1704,1637, +1704,1638,1705, +1639,1705,1638, +1705,1639,1706, +1640,1706,1639, +1706,1640,1707, +1641,1707,1640, +1707,1641,1708, +1642,1708,1641, +1708,1642,1709, +1643,1709,1642, +1709,1643,1710, +1644,1710,1643, +1710,1644,1711, +1645,1711,1644, +1711,1645,1712, +1646,1712,1645, +1712,1646,1713, +1647,1713,1646, +1713,1647,1714, +1648,1714,1647, +1714,1648,1715, +1649,1715,1648, +1716,1650,1717, +1651,1717,1650, +1717,1651,1718, +1652,1718,1651, +1718,1652,1719, +1653,1719,1652, +1719,1653,1720, +1654,1720,1653, +1720,1654,1721, +1655,1721,1654, +1721,1655,1722, +1656,1722,1655, +1722,1656,1723, +1657,1723,1656, +1723,1657,1724, +1658,1724,1657, +1724,1658,1725, +1659,1725,1658, +1725,1659,1726, +1660,1726,1659, +1726,1660,1727, +1661,1727,1660, +1727,1661,1728, +1662,1728,1661, +1728,1662,1729, +1663,1729,1662, +1729,1663,1730, +1664,1730,1663, +1730,1664,1731, +1665,1731,1664, +1731,1665,1732, +1666,1732,1665, +1732,1666,1733, +1667,1733,1666, +1733,1667,1734, +1668,1734,1667, +1734,1668,1735, +1669,1735,1668, +1735,1669,1736, +1670,1736,1669, +1736,1670,1737, +1671,1737,1670, +1737,1671,1738, +1672,1738,1671, +1738,1672,1739, +1673,1739,1672, +1739,1673,1740, +1674,1740,1673, +1740,1674,1741, +1675,1741,1674, +1741,1675,1742, +1676,1742,1675, +1742,1676,1743, +1677,1743,1676, +1743,1677,1744, +1678,1744,1677, +1744,1678,1745, +1679,1745,1678, +1745,1679,1746, +1680,1746,1679, +1746,1680,1747, +1681,1747,1680, +1747,1681,1748, +1682,1748,1681, +1748,1682,1749, +1683,1749,1682, +1749,1683,1750, +1684,1750,1683, +1750,1684,1751, +1685,1751,1684, +1751,1685,1752, +1686,1752,1685, +1752,1686,1753, +1687,1753,1686, +1753,1687,1754, +1688,1754,1687, +1754,1688,1755, +1689,1755,1688, +1755,1689,1756, +1690,1756,1689, +1756,1690,1757, +1691,1757,1690, +1757,1691,1758, +1692,1758,1691, +1758,1692,1759, +1693,1759,1692, +1759,1693,1760, +1694,1760,1693, +1760,1694,1761, +1695,1761,1694, +1761,1695,1762, +1696,1762,1695, +1762,1696,1763, +1697,1763,1696, +1763,1697,1764, +1698,1764,1697, +1764,1698,1765, +1699,1765,1698, +1765,1699,1766, +1700,1766,1699, +1766,1700,1767, +1701,1767,1700, +1767,1701,1768, +1702,1768,1701, +1768,1702,1769, +1703,1769,1702, +1769,1703,1770, +1704,1770,1703, +1770,1704,1771, +1705,1771,1704, +1771,1705,1772, +1706,1772,1705, +1772,1706,1773, +1707,1773,1706, +1773,1707,1774, +1708,1774,1707, +1774,1708,1775, +1709,1775,1708, +1775,1709,1776, +1710,1776,1709, +1776,1710,1777, +1711,1777,1710, +1777,1711,1778, +1712,1778,1711, +1778,1712,1779, +1713,1779,1712, +1779,1713,1780, +1714,1780,1713, +1780,1714,1781, +1715,1781,1714, +1782,1716,1783, +1717,1783,1716, +1783,1717,1784, +1718,1784,1717, +1784,1718,1785, +1719,1785,1718, +1785,1719,1786, +1720,1786,1719, +1786,1720,1787, +1721,1787,1720, +1787,1721,1788, +1722,1788,1721, +1788,1722,1789, +1723,1789,1722, +1789,1723,1790, +1724,1790,1723, +1790,1724,1791, +1725,1791,1724, +1791,1725,1792, +1726,1792,1725, +1792,1726,1793, +1727,1793,1726, +1793,1727,1794, +1728,1794,1727, +1794,1728,1795, +1729,1795,1728, +1795,1729,1796, +1730,1796,1729, +1796,1730,1797, +1731,1797,1730, +1797,1731,1798, +1732,1798,1731, +1798,1732,1799, +1733,1799,1732, +1799,1733,1800, +1734,1800,1733, +1800,1734,1801, +1735,1801,1734, +1801,1735,1802, +1736,1802,1735, +1802,1736,1803, +1737,1803,1736, +1803,1737,1804, +1738,1804,1737, +1804,1738,1805, +1739,1805,1738, +1805,1739,1806, +1740,1806,1739, +1806,1740,1807, +1741,1807,1740, +1807,1741,1808, +1742,1808,1741, +1808,1742,1809, +1743,1809,1742, +1809,1743,1810, +1744,1810,1743, +1810,1744,1811, +1745,1811,1744, +1811,1745,1812, +1746,1812,1745, +1812,1746,1813, +1747,1813,1746, +1813,1747,1814, +1748,1814,1747, +1814,1748,1815, +1749,1815,1748, +1815,1749,1816, +1750,1816,1749, +1816,1750,1817, +1751,1817,1750, +1817,1751,1818, +1752,1818,1751, +1818,1752,1819, +1753,1819,1752, +1819,1753,1820, +1754,1820,1753, +1820,1754,1821, +1755,1821,1754, +1821,1755,1822, +1756,1822,1755, +1822,1756,1823, +1757,1823,1756, +1823,1757,1824, +1758,1824,1757, +1824,1758,1825, +1759,1825,1758, +1825,1759,1826, +1760,1826,1759, +1826,1760,1827, +1761,1827,1760, +1827,1761,1828, +1762,1828,1761, +1828,1762,1829, +1763,1829,1762, +1829,1763,1830, +1764,1830,1763, +1830,1764,1831, +1765,1831,1764, +1831,1765,1832, +1766,1832,1765, +1832,1766,1833, +1767,1833,1766, +1833,1767,1834, +1768,1834,1767, +1834,1768,1835, +1769,1835,1768, +1835,1769,1836, +1770,1836,1769, +1836,1770,1837, +1771,1837,1770, +1837,1771,1838, +1772,1838,1771, +1838,1772,1839, +1773,1839,1772, +1839,1773,1840, +1774,1840,1773, +1840,1774,1841, +1775,1841,1774, +1841,1775,1842, +1776,1842,1775, +1842,1776,1843, +1777,1843,1776, +1843,1777,1844, +1778,1844,1777, +1844,1778,1845, +1779,1845,1778, +1845,1779,1846, +1780,1846,1779, +1846,1780,1847, +1781,1847,1780, +1848,1782,1849, +1783,1849,1782, +1849,1783,1850, +1784,1850,1783, +1850,1784,1851, +1785,1851,1784, +1851,1785,1852, +1786,1852,1785, +1852,1786,1853, +1787,1853,1786, +1853,1787,1854, +1788,1854,1787, +1854,1788,1855, +1789,1855,1788, +1855,1789,1856, +1790,1856,1789, +1856,1790,1857, +1791,1857,1790, +1857,1791,1858, +1792,1858,1791, +1858,1792,1859, +1793,1859,1792, +1859,1793,1860, +1794,1860,1793, +1860,1794,1861, +1795,1861,1794, +1861,1795,1862, +1796,1862,1795, +1862,1796,1863, +1797,1863,1796, +1863,1797,1864, +1798,1864,1797, +1864,1798,1865, +1799,1865,1798, +1865,1799,1866, +1800,1866,1799, +1866,1800,1867, +1801,1867,1800, +1867,1801,1868, +1802,1868,1801, +1868,1802,1869, +1803,1869,1802, +1869,1803,1870, +1804,1870,1803, +1870,1804,1871, +1805,1871,1804, +1871,1805,1872, +1806,1872,1805, +1872,1806,1873, +1807,1873,1806, +1873,1807,1874, +1808,1874,1807, +1874,1808,1875, +1809,1875,1808, +1875,1809,1876, +1810,1876,1809, +1876,1810,1877, +1811,1877,1810, +1877,1811,1878, +1812,1878,1811, +1878,1812,1879, +1813,1879,1812, +1879,1813,1880, +1814,1880,1813, +1880,1814,1881, +1815,1881,1814, +1881,1815,1882, +1816,1882,1815, +1882,1816,1883, +1817,1883,1816, +1883,1817,1884, +1818,1884,1817, +1884,1818,1885, +1819,1885,1818, +1885,1819,1886, +1820,1886,1819, +1886,1820,1887, +1821,1887,1820, +1887,1821,1888, +1822,1888,1821, +1888,1822,1889, +1823,1889,1822, +1889,1823,1890, +1824,1890,1823, +1890,1824,1891, +1825,1891,1824, +1891,1825,1892, +1826,1892,1825, +1892,1826,1893, +1827,1893,1826, +1893,1827,1894, +1828,1894,1827, +1894,1828,1895, +1829,1895,1828, +1895,1829,1896, +1830,1896,1829, +1896,1830,1897, +1831,1897,1830, +1897,1831,1898, +1832,1898,1831, +1898,1832,1899, +1833,1899,1832, +1899,1833,1900, +1834,1900,1833, +1900,1834,1901, +1835,1901,1834, +1901,1835,1902, +1836,1902,1835, +1902,1836,1903, +1837,1903,1836, +1903,1837,1904, +1838,1904,1837, +1904,1838,1905, +1839,1905,1838, +1905,1839,1906, +1840,1906,1839, +1906,1840,1907, +1841,1907,1840, +1907,1841,1908, +1842,1908,1841, +1908,1842,1909, +1843,1909,1842, +1909,1843,1910, +1844,1910,1843, +1910,1844,1911, +1845,1911,1844, +1911,1845,1912, +1846,1912,1845, +1912,1846,1913, +1847,1913,1846, +1914,1848,1915, +1849,1915,1848, +1915,1849,1916, +1850,1916,1849, +1916,1850,1917, +1851,1917,1850, +1917,1851,1918, +1852,1918,1851, +1918,1852,1919, +1853,1919,1852, +1919,1853,1920, +1854,1920,1853, +1920,1854,1921, +1855,1921,1854, +1921,1855,1922, +1856,1922,1855, +1922,1856,1923, +1857,1923,1856, +1923,1857,1924, +1858,1924,1857, +1924,1858,1925, +1859,1925,1858, +1925,1859,1926, +1860,1926,1859, +1926,1860,1927, +1861,1927,1860, +1927,1861,1928, +1862,1928,1861, +1928,1862,1929, +1863,1929,1862, +1929,1863,1930, +1864,1930,1863, +1930,1864,1931, +1865,1931,1864, +1931,1865,1932, +1866,1932,1865, +1932,1866,1933, +1867,1933,1866, +1933,1867,1934, +1868,1934,1867, +1934,1868,1935, +1869,1935,1868, +1935,1869,1936, +1870,1936,1869, +1936,1870,1937, +1871,1937,1870, +1937,1871,1938, +1872,1938,1871, +1938,1872,1939, +1873,1939,1872, +1939,1873,1940, +1874,1940,1873, +1940,1874,1941, +1875,1941,1874, +1941,1875,1942, +1876,1942,1875, +1942,1876,1943, +1877,1943,1876, +1943,1877,1944, +1878,1944,1877, +1944,1878,1945, +1879,1945,1878, +1945,1879,1946, +1880,1946,1879, +1946,1880,1947, +1881,1947,1880, +1947,1881,1948, +1882,1948,1881, +1948,1882,1949, +1883,1949,1882, +1949,1883,1950, +1884,1950,1883, +1950,1884,1951, +1885,1951,1884, +1951,1885,1952, +1886,1952,1885, +1952,1886,1953, +1887,1953,1886, +1953,1887,1954, +1888,1954,1887, +1954,1888,1955, +1889,1955,1888, +1955,1889,1956, +1890,1956,1889, +1956,1890,1957, +1891,1957,1890, +1957,1891,1958, +1892,1958,1891, +1958,1892,1959, +1893,1959,1892, +1959,1893,1960, +1894,1960,1893, +1960,1894,1961, +1895,1961,1894, +1961,1895,1962, +1896,1962,1895, +1962,1896,1963, +1897,1963,1896, +1963,1897,1964, +1898,1964,1897, +1964,1898,1965, +1899,1965,1898, +1965,1899,1966, +1900,1966,1899, +1966,1900,1967, +1901,1967,1900, +1967,1901,1968, +1902,1968,1901, +1968,1902,1969, +1903,1969,1902, +1969,1903,1970, +1904,1970,1903, +1970,1904,1971, +1905,1971,1904, +1971,1905,1972, +1906,1972,1905, +1972,1906,1973, +1907,1973,1906, +1973,1907,1974, +1908,1974,1907, +1974,1908,1975, +1909,1975,1908, +1975,1909,1976, +1910,1976,1909, +1976,1910,1977, +1911,1977,1910, +1977,1911,1978, +1912,1978,1911, +1978,1912,1979, +1913,1979,1912, +}; + +#define Landscape03VtxCount 2048 +#define Landscape03IdxCount 11718 + +btScalar Landscape03Vtx[] = { +3.90625f,50.3865f,-2.20246e-006f, +3.90625f,52.6186f,3.90625f, +7.8125f,50.3905f,-2.20264e-006f, +7.8125f,51.8648f,3.90625f, +11.7188f,49.8171f,-2.17758e-006f, +11.7188f,51.1949f,3.90625f, +15.625f,50.595f,-2.21158e-006f, +15.625f,50.2102f,3.90625f, +19.5313f,50.405f,-2.20327e-006f, +19.5313f,50.6058f,3.90625f, +23.4375f,50.9679f,-2.22788e-006f, +23.4375f,50.7008f,3.90625f, +27.3438f,52.4635f,-2.29325e-006f, +27.3438f,51.2163f,3.90625f, +31.25f,53.1505f,-2.32328e-006f, +31.25f,51.4263f,3.90625f, +35.1563f,53.061f,-2.31937e-006f, +35.1563f,52.1968f,3.90625f, +39.0625f,53.6772f,-2.34631e-006f, +39.0625f,53.9783f,3.90625f, +42.9688f,54.3062f,-2.3738e-006f, +42.9688f,53.8927f,3.90625f, +46.875f,54.6795f,-2.39012e-006f, +46.875f,53.3266f,3.90625f, +50.7813f,55.3188f,-2.41806e-006f, +50.7813f,53.5901f,3.90625f, +54.6875f,56.913f,-2.48775e-006f, +54.6875f,55.5679f,3.90625f, +58.5938f,57.4575f,-2.51155e-006f, +58.5938f,55.1819f,3.90625f, +62.5f,56.5398f,-2.47143e-006f, +62.5f,53.6891f,3.90625f, +66.4063f,55.8786f,-2.44253e-006f, +66.4063f,53.0541f,3.90625f, +70.3125f,53.6497f,-2.3451e-006f, +70.3125f,51.6665f,3.90625f, +74.2188f,51.6447f,-2.25746e-006f, +74.2188f,51.4469f,3.90625f, +78.125f,51.8145f,-2.26488e-006f, +78.125f,51.9591f,3.90625f, +82.0313f,51.335f,-2.24392e-006f, +82.0313f,51.0418f,3.90625f, +85.9375f,50.1836f,-2.1936e-006f, +85.9375f,49.7513f,3.90625f, +89.8438f,49.0536f,-2.1442e-006f, +89.8438f,48.7329f,3.90625f, +93.75f,47.3968f,-2.07178e-006f, +93.75f,46.8713f,3.90625f, +97.6563f,45.8014f,-2.00204e-006f, +97.6563f,46.3905f,3.90625f, +101.563f,45.2347f,-1.97727e-006f, +101.563f,45.4241f,3.90625f, +105.469f,44.6501f,-1.95172e-006f, +105.469f,45.6811f,3.90625f, +109.375f,44.3569f,-1.9389e-006f, +109.375f,45.3238f,3.90625f, +113.281f,44.1147f,-1.92831e-006f, +113.281f,43.6112f,3.90625f, +117.188f,43.4037f,-1.89723e-006f, +117.188f,42.1291f,3.90625f, +121.094f,41.1606f,-1.79919e-006f, +121.094f,40.4747f,3.90625f, +125.0f,40.195f,-1.75698e-006f, +125.0f,39.3351f,3.90625f, +128.906f,39.5659f,-1.72948e-006f, +128.906f,38.0742f,3.90625f, +132.813f,38.2592f,-1.67236e-006f, +132.813f,36.7758f,3.90625f, +136.719f,36.4337f,-1.59257e-006f, +136.719f,34.9213f,3.90625f, +140.625f,34.1507f,-1.49277e-006f, +140.625f,32.3643f,3.90625f, +144.531f,31.5531f,-1.37923e-006f, +144.531f,31.7157f,3.90625f, +148.438f,29.9056f,-1.30722e-006f, +148.438f,30.6005f,3.90625f, +152.344f,30.5219f,-1.33416e-006f, +152.344f,31.6034f,3.90625f, +156.25f,31.1254f,-1.36053e-006f, +156.25f,32.6503f,3.90625f, +160.156f,31.8976f,-1.39429e-006f, +160.156f,33.3131f,3.90625f, +164.063f,31.5364f,-1.3785e-006f, +164.063f,32.5745f,3.90625f, +167.969f,30.5585f,-1.33575e-006f, +167.969f,31.5017f,3.90625f, +171.875f,30.0528f,-1.31365e-006f, +171.875f,30.6842f,3.90625f, +175.781f,29.2833f,-1.28002e-006f, +175.781f,29.8734f,3.90625f, +179.688f,28.3316f,-1.23841e-006f, +179.688f,28.6537f,3.90625f, +183.594f,27.0177f,-1.18098e-006f, +183.594f,27.2073f,3.90625f, +187.5f,24.7626f,-1.08241e-006f, +187.5f,25.4367f,3.90625f, +191.406f,22.7371f,-9.9387e-007f, +191.406f,24.1609f,3.90625f, +195.313f,21.6497f,-9.46338e-007f, +195.313f,23.9724f,3.90625f, +199.219f,21.3313f,-9.32422e-007f, +199.219f,23.7702f,3.90625f, +203.125f,20.9148f,-9.14215e-007f, +203.125f,22.4031f,3.90625f, +207.031f,19.4875f,-8.51826e-007f, +207.031f,22.1587f,3.90625f, +210.938f,19.0037f,-8.30679e-007f, +210.938f,21.6154f,3.90625f, +214.844f,18.408f,-8.0464e-007f, +214.844f,21.8202f,3.90625f, +218.75f,18.7855f,-8.2114e-007f, +218.75f,21.017f,3.90625f, +222.656f,18.1497f,-7.9335e-007f, +222.656f,19.3736f,3.90625f, +226.563f,17.6889f,-7.73205e-007f, +226.563f,18.2127f,3.90625f, +230.469f,16.8429f,-7.36228e-007f, +230.469f,17.2263f,3.90625f, +234.375f,16.3712f,-7.15609e-007f, +234.375f,16.2938f,3.90625f, +238.281f,14.3259f,-6.26204e-007f, +238.281f,14.4518f,3.90625f, +242.188f,12.4394f,-5.43742e-007f, +242.188f,13.6398f,3.90625f, +246.094f,12.3876f,-5.41479e-007f, +246.094f,13.2404f,3.90625f, +250.0f,11.9236f,-5.21196e-007f, +250.0f,12.7102f,3.90625f, +3.90625f,48.8559f,-3.90625f, +7.8125f,49.3575f,-3.90625f, +11.7188f,49.963f,-3.90625f, +15.625f,50.1126f,-3.90625f, +19.5313f,51.6247f,-3.90625f, +23.4375f,52.1716f,-3.90625f, +27.3438f,52.8679f,-3.90625f, +31.25f,53.978f,-3.90625f, +35.1563f,53.8948f,-3.90625f, +39.0625f,54.8492f,-3.90625f, +42.9688f,56.1714f,-3.90625f, +46.875f,56.4915f,-3.90625f, +50.7813f,56.5729f,-3.90625f, +54.6875f,57.9767f,-3.90625f, +58.5938f,58.6125f,-3.90625f, +62.5f,58.0023f,-3.90625f, +66.4063f,57.5742f,-3.90625f, +70.3125f,55.4949f,-3.90625f, +74.2188f,53.7219f,-3.90625f, +78.125f,53.233f,-3.90625f, +82.0313f,52.5499f,-3.90625f, +85.9375f,51.1842f,-3.90625f, +89.8438f,49.6534f,-3.90625f, +93.75f,47.6829f,-3.90625f, +97.6563f,45.813f,-3.90625f, +101.563f,44.7099f,-3.90625f, +105.469f,45.0932f,-3.90625f, +109.375f,44.8326f,-3.90625f, +113.281f,44.5197f,-3.90625f, +117.188f,43.7399f,-3.90625f, +121.094f,42.3088f,-3.90625f, +125.0f,40.4224f,-3.90625f, +128.906f,39.437f,-3.90625f, +132.813f,39.825f,-3.90625f, +136.719f,38.2979f,-3.90625f, +140.625f,35.2095f,-3.90625f, +144.531f,32.0692f,-3.90625f, +148.438f,31.1765f,-3.90625f, +152.344f,32.2065f,-3.90625f, +156.25f,31.4774f,-3.90625f, +160.156f,31.7166f,-3.90625f, +164.063f,31.7667f,-3.90625f, +167.969f,31.1742f,-3.90625f, +171.875f,29.6515f,-3.90625f, +175.781f,28.7845f,-3.90625f, +179.688f,28.3154f,-3.90625f, +183.594f,26.6187f,-3.90625f, +187.5f,24.7363f,-3.90625f, +191.406f,22.9162f,-3.90625f, +195.313f,21.5211f,-3.90625f, +199.219f,19.7693f,-3.90625f, +203.125f,18.9792f,-3.90625f, +207.031f,18.8399f,-3.90625f, +210.938f,18.8797f,-3.90625f, +214.844f,18.8123f,-3.90625f, +218.75f,18.5136f,-3.90625f, +222.656f,18.5607f,-3.90625f, +226.563f,17.5053f,-3.90625f, +230.469f,17.4838f,-3.90625f, +234.375f,16.6728f,-3.90625f, +238.281f,14.8594f,-3.90625f, +242.188f,12.9613f,-3.90625f, +246.094f,12.8624f,-3.90625f, +250.0f,11.5894f,-3.90625f, +3.90625f,48.7225f,-7.8125f, +7.8125f,49.1281f,-7.8125f, +11.7188f,50.0005f,-7.8125f, +15.625f,50.5896f,-7.8125f, +19.5313f,51.5499f,-7.8125f, +23.4375f,52.9511f,-7.8125f, +27.3438f,53.117f,-7.8125f, +31.25f,54.0682f,-7.8125f, +35.1563f,55.2353f,-7.8125f, +39.0625f,57.2741f,-7.8125f, +42.9688f,57.4338f,-7.8125f, +46.875f,57.766f,-7.8125f, +50.7813f,57.2724f,-7.8125f, +54.6875f,58.0147f,-7.8125f, +58.5938f,58.764f,-7.8125f, +62.5f,58.6375f,-7.8125f, +66.4063f,57.2699f,-7.8125f, +70.3125f,55.9883f,-7.8125f, +74.2188f,54.8767f,-7.8125f, +78.125f,54.5266f,-7.8125f, +82.0313f,53.7148f,-7.8125f, +85.9375f,52.3735f,-7.8125f, +89.8438f,50.9637f,-7.8125f, +93.75f,48.4983f,-7.8125f, +97.6563f,45.9034f,-7.8125f, +101.563f,45.0863f,-7.8125f, +105.469f,44.2432f,-7.8125f, +109.375f,43.9561f,-7.8125f, +113.281f,43.3015f,-7.8125f, +117.188f,43.254f,-7.8125f, +121.094f,42.7388f,-7.8125f, +125.0f,41.1851f,-7.8125f, +128.906f,39.7522f,-7.8125f, +132.813f,39.8116f,-7.8125f, +136.719f,38.7148f,-7.8125f, +140.625f,36.0845f,-7.8125f, +144.531f,34.0308f,-7.8125f, +148.438f,33.0368f,-7.8125f, +152.344f,32.5867f,-7.8125f, +156.25f,32.8758f,-7.8125f, +160.156f,32.65f,-7.8125f, +164.063f,32.6826f,-7.8125f, +167.969f,31.5243f,-7.8125f, +171.875f,30.4061f,-7.8125f, +175.781f,29.2721f,-7.8125f, +179.688f,28.0417f,-7.8125f, +183.594f,26.2041f,-7.8125f, +187.5f,24.2168f,-7.8125f, +191.406f,22.7847f,-7.8125f, +195.313f,20.5069f,-7.8125f, +199.219f,18.6189f,-7.8125f, +203.125f,17.5296f,-7.8125f, +207.031f,18.0846f,-7.8125f, +210.938f,18.4802f,-7.8125f, +214.844f,18.5436f,-7.8125f, +218.75f,18.3296f,-7.8125f, +222.656f,17.9158f,-7.8125f, +226.563f,17.0318f,-7.8125f, +230.469f,16.2818f,-7.8125f, +234.375f,15.4949f,-7.8125f, +238.281f,13.4891f,-7.8125f, +242.188f,13.3349f,-7.8125f, +246.094f,12.2716f,-7.8125f, +250.0f,10.9901f,-7.8125f, +3.90625f,49.6298f,-11.7188f, +7.8125f,50.0683f,-11.7188f, +11.7188f,50.6295f,-11.7188f, +15.625f,51.0495f,-11.7188f, +19.5313f,52.4884f,-11.7188f, +23.4375f,53.3147f,-11.7188f, +27.3438f,54.4311f,-11.7188f, +31.25f,55.2874f,-11.7188f, +35.1563f,56.5549f,-11.7188f, +39.0625f,57.9376f,-11.7188f, +42.9688f,58.2302f,-11.7188f, +46.875f,59.1419f,-11.7188f, +50.7813f,58.8724f,-11.7188f, +54.6875f,58.5393f,-11.7188f, +58.5938f,58.6416f,-11.7188f, +62.5f,58.1973f,-11.7188f, +66.4063f,57.9168f,-11.7188f, +70.3125f,56.4347f,-11.7188f, +74.2188f,55.7911f,-11.7188f, +78.125f,55.946f,-11.7188f, +82.0313f,54.9033f,-11.7188f, +85.9375f,53.0954f,-11.7188f, +89.8438f,51.7428f,-11.7188f, +93.75f,49.2198f,-11.7188f, +97.6563f,46.1127f,-11.7188f, +101.563f,43.9953f,-11.7188f, +105.469f,43.5777f,-11.7188f, +109.375f,43.3284f,-11.7188f, +113.281f,43.5152f,-11.7188f, +117.188f,43.6687f,-11.7188f, +121.094f,42.5477f,-11.7188f, +125.0f,41.4079f,-11.7188f, +128.906f,39.4512f,-11.7188f, +132.813f,39.5183f,-11.7188f, +136.719f,37.8068f,-11.7188f, +140.625f,36.5652f,-11.7188f, +144.531f,34.8202f,-11.7188f, +148.438f,34.0166f,-11.7188f, +152.344f,33.5311f,-11.7188f, +156.25f,34.1672f,-11.7188f, +160.156f,33.8602f,-11.7188f, +164.063f,33.8717f,-11.7188f, +167.969f,33.1703f,-11.7188f, +171.875f,31.0241f,-11.7188f, +175.781f,30.2798f,-11.7188f, +179.688f,28.3241f,-11.7188f, +183.594f,26.4432f,-11.7188f, +187.5f,24.9758f,-11.7188f, +191.406f,22.2834f,-11.7188f, +195.313f,19.3875f,-11.7188f, +199.219f,18.4079f,-11.7188f, +203.125f,16.6498f,-11.7188f, +207.031f,16.1235f,-11.7188f, +210.938f,16.9462f,-11.7188f, +214.844f,17.2638f,-11.7188f, +218.75f,17.0386f,-11.7188f, +222.656f,16.7666f,-11.7188f, +226.563f,15.3591f,-11.7188f, +230.469f,14.4048f,-11.7188f, +234.375f,13.3079f,-11.7188f, +238.281f,13.0895f,-11.7188f, +242.188f,12.8462f,-11.7188f, +246.094f,12.6287f,-11.7188f, +250.0f,11.4682f,-11.7188f, +3.90625f,50.6915f,-15.625f, +7.8125f,51.2382f,-15.625f, +11.7188f,52.3659f,-15.625f, +15.625f,52.3873f,-15.625f, +19.5313f,53.1083f,-15.625f, +23.4375f,54.652f,-15.625f, +27.3438f,56.0359f,-15.625f, +31.25f,56.4398f,-15.625f, +35.1563f,57.3156f,-15.625f, +39.0625f,58.2355f,-15.625f, +42.9688f,59.4547f,-15.625f, +46.875f,59.9176f,-15.625f, +50.7813f,60.0789f,-15.625f, +54.6875f,59.004f,-15.625f, +58.5938f,59.3361f,-15.625f, +62.5f,59.2681f,-15.625f, +66.4063f,58.5571f,-15.625f, +70.3125f,57.1801f,-15.625f, +74.2188f,56.2048f,-15.625f, +78.125f,56.9427f,-15.625f, +82.0313f,55.401f,-15.625f, +85.9375f,53.0457f,-15.625f, +89.8438f,51.6378f,-15.625f, +93.75f,49.1297f,-15.625f, +97.6563f,46.6267f,-15.625f, +101.563f,44.7255f,-15.625f, +105.469f,43.3819f,-15.625f, +109.375f,42.8703f,-15.625f, +113.281f,42.7636f,-15.625f, +117.188f,42.1897f,-15.625f, +121.094f,41.9269f,-15.625f, +125.0f,41.5365f,-15.625f, +128.906f,39.5408f,-15.625f, +132.813f,38.9178f,-15.625f, +136.719f,38.1447f,-15.625f, +140.625f,36.5145f,-15.625f, +144.531f,34.8696f,-15.625f, +148.438f,34.8203f,-15.625f, +152.344f,34.409f,-15.625f, +156.25f,35.1394f,-15.625f, +160.156f,35.619f,-15.625f, +164.063f,34.7784f,-15.625f, +167.969f,33.6548f,-15.625f, +171.875f,32.1822f,-15.625f, +175.781f,31.1666f,-15.625f, +179.688f,28.9574f,-15.625f, +183.594f,27.3989f,-15.625f, +187.5f,24.7201f,-15.625f, +191.406f,21.7859f,-15.625f, +195.313f,19.2508f,-15.625f, +199.219f,18.0209f,-15.625f, +203.125f,16.8441f,-15.625f, +207.031f,15.8846f,-15.625f, +210.938f,15.6902f,-15.625f, +214.844f,15.3143f,-15.625f, +218.75f,15.3862f,-15.625f, +222.656f,14.2743f,-15.625f, +226.563f,13.5791f,-15.625f, +230.469f,13.4953f,-15.625f, +234.375f,13.3484f,-15.625f, +238.281f,13.2722f,-15.625f, +242.188f,13.4455f,-15.625f, +246.094f,13.0725f,-15.625f, +250.0f,11.5558f,-15.625f, +3.90625f,52.1028f,-19.5313f, +7.8125f,52.877f,-19.5313f, +11.7188f,54.5397f,-19.5313f, +15.625f,54.8941f,-19.5313f, +19.5313f,54.9009f,-19.5313f, +23.4375f,56.1681f,-19.5313f, +27.3438f,56.5579f,-19.5313f, +31.25f,57.7962f,-19.5313f, +35.1563f,58.728f,-19.5313f, +39.0625f,59.4794f,-19.5313f, +42.9688f,60.2636f,-19.5313f, +46.875f,61.2139f,-19.5313f, +50.7813f,60.4636f,-19.5313f, +54.6875f,59.681f,-19.5313f, +58.5938f,60.2068f,-19.5313f, +62.5f,59.1055f,-19.5313f, +66.4063f,57.6126f,-19.5313f, +70.3125f,56.6416f,-19.5313f, +74.2188f,56.4864f,-19.5313f, +78.125f,56.1784f,-19.5313f, +82.0313f,54.8451f,-19.5313f, +85.9375f,53.4094f,-19.5313f, +89.8438f,51.7161f,-19.5313f, +93.75f,48.9933f,-19.5313f, +97.6563f,47.5116f,-19.5313f, +101.563f,45.7701f,-19.5313f, +105.469f,44.0377f,-19.5313f, +109.375f,43.0918f,-19.5313f, +113.281f,42.3992f,-19.5313f, +117.188f,42.0928f,-19.5313f, +121.094f,42.0543f,-19.5313f, +125.0f,41.793f,-19.5313f, +128.906f,39.3232f,-19.5313f, +132.813f,39.1149f,-19.5313f, +136.719f,38.2381f,-19.5313f, +140.625f,36.1019f,-19.5313f, +144.531f,36.4503f,-19.5313f, +148.438f,35.6809f,-19.5313f, +152.344f,35.8022f,-19.5313f, +156.25f,36.4955f,-19.5313f, +160.156f,36.3187f,-19.5313f, +164.063f,35.0268f,-19.5313f, +167.969f,34.0134f,-19.5313f, +171.875f,33.6455f,-19.5313f, +175.781f,31.5932f,-19.5313f, +179.688f,30.0326f,-19.5313f, +183.594f,28.3453f,-19.5313f, +187.5f,25.3719f,-19.5313f, +191.406f,22.0833f,-19.5313f, +195.313f,18.7475f,-19.5313f, +199.219f,17.5517f,-19.5313f, +203.125f,16.1528f,-19.5313f, +207.031f,15.6144f,-19.5313f, +210.938f,14.9281f,-19.5313f, +214.844f,14.5711f,-19.5313f, +218.75f,13.8446f,-19.5313f, +222.656f,13.6892f,-19.5313f, +226.563f,13.1595f,-19.5313f, +230.469f,13.2872f,-19.5313f, +234.375f,13.6153f,-19.5313f, +238.281f,12.8725f,-19.5313f, +242.188f,12.7128f,-19.5313f, +246.094f,13.0658f,-19.5313f, +250.0f,11.5414f,-19.5313f, +3.90625f,54.332f,-23.4375f, +7.8125f,55.636f,-23.4375f, +11.7188f,56.3899f,-23.4375f, +15.625f,56.3763f,-23.4375f, +19.5313f,56.9523f,-23.4375f, +23.4375f,57.5593f,-23.4375f, +27.3438f,57.8056f,-23.4375f, +31.25f,58.5489f,-23.4375f, +35.1563f,59.2321f,-23.4375f, +39.0625f,60.5971f,-23.4375f, +42.9688f,60.1728f,-23.4375f, +46.875f,60.9341f,-23.4375f, +50.7813f,59.5118f,-23.4375f, +54.6875f,59.7552f,-23.4375f, +58.5938f,59.9126f,-23.4375f, +62.5f,58.501f,-23.4375f, +66.4063f,57.8539f,-23.4375f, +70.3125f,56.8693f,-23.4375f, +74.2188f,56.0687f,-23.4375f, +78.125f,55.4392f,-23.4375f, +82.0313f,53.7167f,-23.4375f, +85.9375f,52.1078f,-23.4375f, +89.8438f,50.8869f,-23.4375f, +93.75f,49.9812f,-23.4375f, +97.6563f,47.9233f,-23.4375f, +101.563f,46.1166f,-23.4375f, +105.469f,44.4826f,-23.4375f, +109.375f,42.8924f,-23.4375f, +113.281f,41.9991f,-23.4375f, +117.188f,41.1759f,-23.4375f, +121.094f,41.1189f,-23.4375f, +125.0f,39.9128f,-23.4375f, +128.906f,39.8641f,-23.4375f, +132.813f,39.8777f,-23.4375f, +136.719f,38.3567f,-23.4375f, +140.625f,37.4926f,-23.4375f, +144.531f,37.0275f,-23.4375f, +148.438f,36.7211f,-23.4375f, +152.344f,36.9355f,-23.4375f, +156.25f,37.7455f,-23.4375f, +160.156f,37.3585f,-23.4375f, +164.063f,36.1837f,-23.4375f, +167.969f,34.768f,-23.4375f, +171.875f,33.2179f,-23.4375f, +175.781f,31.6883f,-23.4375f, +179.688f,30.1136f,-23.4375f, +183.594f,28.1155f,-23.4375f, +187.5f,25.4881f,-23.4375f, +191.406f,22.8498f,-23.4375f, +195.313f,19.4425f,-23.4375f, +199.219f,17.1253f,-23.4375f, +203.125f,14.8354f,-23.4375f, +207.031f,14.1771f,-23.4375f, +210.938f,13.9227f,-23.4375f, +214.844f,13.3404f,-23.4375f, +218.75f,13.0525f,-23.4375f, +222.656f,13.0744f,-23.4375f, +226.563f,13.0432f,-23.4375f, +230.469f,13.3341f,-23.4375f, +234.375f,13.6022f,-23.4375f, +238.281f,13.3878f,-23.4375f, +242.188f,12.5812f,-23.4375f, +246.094f,11.8699f,-23.4375f, +250.0f,11.3395f,-23.4375f, +3.90625f,57.5273f,-27.3438f, +7.8125f,57.8217f,-27.3438f, +11.7188f,57.5626f,-27.3438f, +15.625f,57.7794f,-27.3438f, +19.5313f,58.7949f,-27.3438f, +23.4375f,59.3547f,-27.3438f, +27.3438f,59.2359f,-27.3438f, +31.25f,58.8772f,-27.3438f, +35.1563f,58.7149f,-27.3438f, +39.0625f,59.7221f,-27.3438f, +42.9688f,60.0457f,-27.3438f, +46.875f,59.6559f,-27.3438f, +50.7813f,59.9346f,-27.3438f, +54.6875f,60.4095f,-27.3438f, +58.5938f,59.3107f,-27.3438f, +62.5f,57.9086f,-27.3438f, +66.4063f,57.3034f,-27.3438f, +70.3125f,55.5758f,-27.3438f, +74.2188f,54.7167f,-27.3438f, +78.125f,54.405f,-27.3438f, +82.0313f,53.0644f,-27.3438f, +85.9375f,50.9689f,-27.3438f, +89.8438f,49.5959f,-27.3438f, +93.75f,49.2817f,-27.3438f, +97.6563f,48.9188f,-27.3438f, +101.563f,47.0066f,-27.3438f, +105.469f,44.4266f,-27.3438f, +109.375f,42.4539f,-27.3438f, +113.281f,41.5486f,-27.3438f, +117.188f,41.4419f,-27.3438f, +121.094f,41.2039f,-27.3438f, +125.0f,40.188f,-27.3438f, +128.906f,40.4744f,-27.3438f, +132.813f,40.1187f,-27.3438f, +136.719f,38.8055f,-27.3438f, +140.625f,38.024f,-27.3438f, +144.531f,37.5255f,-27.3438f, +148.438f,36.8676f,-27.3438f, +152.344f,37.8967f,-27.3438f, +156.25f,38.4708f,-27.3438f, +160.156f,37.8284f,-27.3438f, +164.063f,36.6094f,-27.3438f, +167.969f,34.4523f,-27.3438f, +171.875f,32.2936f,-27.3438f, +175.781f,31.7467f,-27.3438f, +179.688f,29.9455f,-27.3438f, +183.594f,27.7546f,-27.3438f, +187.5f,25.1902f,-27.3438f, +191.406f,22.537f,-27.3438f, +195.313f,19.5657f,-27.3438f, +199.219f,17.4406f,-27.3438f, +203.125f,15.5459f,-27.3438f, +207.031f,14.92f,-27.3438f, +210.938f,13.472f,-27.3438f, +214.844f,12.9933f,-27.3438f, +218.75f,13.2849f,-27.3438f, +222.656f,12.3375f,-27.3438f, +226.563f,12.0553f,-27.3438f, +230.469f,12.4756f,-27.3438f, +234.375f,12.0857f,-27.3438f, +238.281f,12.1988f,-27.3438f, +242.188f,11.9091f,-27.3438f, +246.094f,10.7301f,-27.3438f, +250.0f,10.1068f,-27.3438f, +3.90625f,59.4204f,-31.25f, +7.8125f,59.5424f,-31.25f, +11.7188f,58.7785f,-31.25f, +15.625f,59.7851f,-31.25f, +19.5313f,60.4897f,-31.25f, +23.4375f,60.6095f,-31.25f, +27.3438f,60.3384f,-31.25f, +31.25f,59.5445f,-31.25f, +35.1563f,58.6838f,-31.25f, +39.0625f,58.847f,-31.25f, +42.9688f,59.3885f,-31.25f, +46.875f,59.447f,-31.25f, +50.7813f,59.5998f,-31.25f, +54.6875f,58.9947f,-31.25f, +58.5938f,58.7482f,-31.25f, +62.5f,56.5947f,-31.25f, +66.4063f,56.2941f,-31.25f, +70.3125f,54.6423f,-31.25f, +74.2188f,53.7392f,-31.25f, +78.125f,53.2955f,-31.25f, +82.0313f,52.8233f,-31.25f, +85.9375f,52.1194f,-31.25f, +89.8438f,51.3335f,-31.25f, +93.75f,49.9201f,-31.25f, +97.6563f,49.1642f,-31.25f, +101.563f,47.4466f,-31.25f, +105.469f,44.6086f,-31.25f, +109.375f,42.885f,-31.25f, +113.281f,42.947f,-31.25f, +117.188f,42.2436f,-31.25f, +121.094f,41.6479f,-31.25f, +125.0f,41.6151f,-31.25f, +128.906f,41.2079f,-31.25f, +132.813f,40.7975f,-31.25f, +136.719f,39.8341f,-31.25f, +140.625f,38.7649f,-31.25f, +144.531f,37.7387f,-31.25f, +148.438f,37.2112f,-31.25f, +152.344f,38.3278f,-31.25f, +156.25f,38.7659f,-31.25f, +160.156f,37.5608f,-31.25f, +164.063f,35.9966f,-31.25f, +167.969f,33.737f,-31.25f, +171.875f,32.0109f,-31.25f, +175.781f,31.1169f,-31.25f, +179.688f,30.0211f,-31.25f, +183.594f,27.5633f,-31.25f, +187.5f,25.0292f,-31.25f, +191.406f,22.8265f,-31.25f, +195.313f,19.8972f,-31.25f, +199.219f,17.6714f,-31.25f, +203.125f,16.2679f,-31.25f, +207.031f,15.0546f,-31.25f, +210.938f,14.037f,-31.25f, +214.844f,12.5501f,-31.25f, +218.75f,12.1528f,-31.25f, +222.656f,12.0576f,-31.25f, +226.563f,11.2847f,-31.25f, +230.469f,11.5946f,-31.25f, +234.375f,10.9216f,-31.25f, +238.281f,10.9182f,-31.25f, +242.188f,11.2826f,-31.25f, +246.094f,11.5781f,-31.25f, +250.0f,11.536f,-31.25f, +3.90625f,60.2212f,-35.1563f, +7.8125f,59.3731f,-35.1563f, +11.7188f,58.5327f,-35.1563f, +15.625f,59.5785f,-35.1563f, +19.5313f,60.1491f,-35.1563f, +23.4375f,60.5297f,-35.1563f, +27.3438f,60.5336f,-35.1563f, +31.25f,60.162f,-35.1563f, +35.1563f,58.5927f,-35.1563f, +39.0625f,57.9369f,-35.1563f, +42.9688f,58.4405f,-35.1563f, +46.875f,58.7374f,-35.1563f, +50.7813f,57.6198f,-35.1563f, +54.6875f,57.3277f,-35.1563f, +58.5938f,56.6423f,-35.1563f, +62.5f,56.2444f,-35.1563f, +66.4063f,56.132f,-35.1563f, +70.3125f,54.6673f,-35.1563f, +74.2188f,53.2924f,-35.1563f, +78.125f,53.2569f,-35.1563f, +82.0313f,52.0828f,-35.1563f, +85.9375f,51.9661f,-35.1563f, +89.8438f,50.9045f,-35.1563f, +93.75f,49.4997f,-35.1563f, +97.6563f,48.0748f,-35.1563f, +101.563f,46.3182f,-35.1563f, +105.469f,44.0878f,-35.1563f, +109.375f,42.863f,-35.1563f, +113.281f,42.8044f,-35.1563f, +117.188f,42.9648f,-35.1563f, +121.094f,42.3221f,-35.1563f, +125.0f,41.6576f,-35.1563f, +128.906f,41.1606f,-35.1563f, +132.813f,39.59f,-35.1563f, +136.719f,38.5602f,-35.1563f, +140.625f,37.9389f,-35.1563f, +144.531f,37.2602f,-35.1563f, +148.438f,37.3784f,-35.1563f, +152.344f,37.8906f,-35.1563f, +156.25f,37.8221f,-35.1563f, +160.156f,36.3088f,-35.1563f, +164.063f,35.1881f,-35.1563f, +167.969f,33.2601f,-35.1563f, +171.875f,31.8157f,-35.1563f, +175.781f,31.3416f,-35.1563f, +179.688f,30.0265f,-35.1563f, +183.594f,27.3943f,-35.1563f, +187.5f,24.641f,-35.1563f, +191.406f,22.2525f,-35.1563f, +195.313f,20.2011f,-35.1563f, +199.219f,18.7104f,-35.1563f, +203.125f,17.3459f,-35.1563f, +207.031f,15.2838f,-35.1563f, +210.938f,13.6157f,-35.1563f, +214.844f,13.3893f,-35.1563f, +218.75f,12.9319f,-35.1563f, +222.656f,11.5191f,-35.1563f, +226.563f,10.4878f,-35.1563f, +230.469f,9.83031f,-35.1563f, +234.375f,9.91945f,-35.1563f, +238.281f,10.9647f,-35.1563f, +242.188f,11.5866f,-35.1563f, +246.094f,11.8313f,-35.1563f, +250.0f,11.9419f,-35.1563f, +3.90625f,59.9094f,-39.0625f, +7.8125f,58.6207f,-39.0625f, +11.7188f,57.735f,-39.0625f, +15.625f,58.9909f,-39.0625f, +19.5313f,60.0678f,-39.0625f, +23.4375f,60.5419f,-39.0625f, +27.3438f,60.4672f,-39.0625f, +31.25f,59.5824f,-39.0625f, +35.1563f,58.4068f,-39.0625f, +39.0625f,57.5098f,-39.0625f, +42.9688f,57.6631f,-39.0625f, +46.875f,57.8211f,-39.0625f, +50.7813f,57.1897f,-39.0625f, +54.6875f,55.6789f,-39.0625f, +58.5938f,55.3212f,-39.0625f, +62.5f,55.2941f,-39.0625f, +66.4063f,55.8101f,-39.0625f, +70.3125f,54.309f,-39.0625f, +74.2188f,53.6313f,-39.0625f, +78.125f,52.7246f,-39.0625f, +82.0313f,51.5473f,-39.0625f, +85.9375f,51.5315f,-39.0625f, +89.8438f,50.6121f,-39.0625f, +93.75f,50.3734f,-39.0625f, +97.6563f,48.8877f,-39.0625f, +101.563f,47.0081f,-39.0625f, +105.469f,44.4827f,-39.0625f, +109.375f,43.5851f,-39.0625f, +113.281f,43.2668f,-39.0625f, +117.188f,43.4016f,-39.0625f, +121.094f,41.962f,-39.0625f, +125.0f,41.4641f,-39.0625f, +128.906f,40.2221f,-39.0625f, +132.813f,38.9234f,-39.0625f, +136.719f,37.7062f,-39.0625f, +140.625f,37.6455f,-39.0625f, +144.531f,37.8691f,-39.0625f, +148.438f,37.4139f,-39.0625f, +152.344f,37.204f,-39.0625f, +156.25f,36.7774f,-39.0625f, +160.156f,35.8962f,-39.0625f, +164.063f,34.5247f,-39.0625f, +167.969f,32.7322f,-39.0625f, +171.875f,32.1044f,-39.0625f, +175.781f,31.321f,-39.0625f, +179.688f,29.7775f,-39.0625f, +183.594f,26.7381f,-39.0625f, +187.5f,24.0216f,-39.0625f, +191.406f,22.277f,-39.0625f, +195.313f,21.2497f,-39.0625f, +199.219f,19.9529f,-39.0625f, +203.125f,18.3349f,-39.0625f, +207.031f,16.7961f,-39.0625f, +210.938f,15.071f,-39.0625f, +214.844f,13.5616f,-39.0625f, +218.75f,13.1679f,-39.0625f, +222.656f,11.2729f,-39.0625f, +226.563f,10.5025f,-39.0625f, +230.469f,9.72086f,-39.0625f, +234.375f,9.90489f,-39.0625f, +238.281f,10.7231f,-39.0625f, +242.188f,11.2573f,-39.0625f, +246.094f,12.0761f,-39.0625f, +250.0f,11.902f,-39.0625f, +3.90625f,59.5207f,-42.9688f, +7.8125f,58.2483f,-42.9688f, +11.7188f,58.069f,-42.9688f, +15.625f,59.4248f,-42.9688f, +19.5313f,60.5261f,-42.9688f, +23.4375f,60.668f,-42.9688f, +27.3438f,60.0252f,-42.9688f, +31.25f,58.0523f,-42.9688f, +35.1563f,56.7426f,-42.9688f, +39.0625f,57.2045f,-42.9688f, +42.9688f,57.166f,-42.9688f, +46.875f,56.9465f,-42.9688f, +50.7813f,55.7381f,-42.9688f, +54.6875f,55.2924f,-42.9688f, +58.5938f,54.6074f,-42.9688f, +62.5f,54.1882f,-42.9688f, +66.4063f,53.672f,-42.9688f, +70.3125f,53.3122f,-42.9688f, +74.2188f,53.0852f,-42.9688f, +78.125f,52.6173f,-42.9688f, +82.0313f,51.616f,-42.9688f, +85.9375f,50.148f,-42.9688f, +89.8438f,49.4823f,-42.9688f, +93.75f,50.0221f,-42.9688f, +97.6563f,48.9931f,-42.9688f, +101.563f,47.1045f,-42.9688f, +105.469f,44.442f,-42.9688f, +109.375f,44.5071f,-42.9688f, +113.281f,44.1005f,-42.9688f, +117.188f,42.8414f,-42.9688f, +121.094f,42.5419f,-42.9688f, +125.0f,41.5451f,-42.9688f, +128.906f,39.4272f,-42.9688f, +132.813f,39.8815f,-42.9688f, +136.719f,39.1366f,-42.9688f, +140.625f,38.7457f,-42.9688f, +144.531f,38.4257f,-42.9688f, +148.438f,37.9899f,-42.9688f, +152.344f,37.1716f,-42.9688f, +156.25f,36.0431f,-42.9688f, +160.156f,35.0784f,-42.9688f, +164.063f,33.3564f,-42.9688f, +167.969f,32.1522f,-42.9688f, +171.875f,30.9698f,-42.9688f, +175.781f,29.7186f,-42.9688f, +179.688f,28.0509f,-42.9688f, +183.594f,25.8254f,-42.9688f, +187.5f,24.8502f,-42.9688f, +191.406f,22.9031f,-42.9688f, +195.313f,20.8135f,-42.9688f, +199.219f,19.6651f,-42.9688f, +203.125f,18.4753f,-42.9688f, +207.031f,17.2259f,-42.9688f, +210.938f,15.6171f,-42.9688f, +214.844f,13.2953f,-42.9688f, +218.75f,13.1679f,-42.9688f, +222.656f,10.7772f,-42.9688f, +226.563f,9.62294f,-42.9688f, +230.469f,9.27609f,-42.9688f, +234.375f,9.47241f,-42.9688f, +238.281f,10.2411f,-42.9688f, +242.188f,11.3745f,-42.9688f, +246.094f,10.981f,-42.9688f, +250.0f,9.93179f,-42.9688f, +3.90625f,58.9086f,-46.875f, +7.8125f,58.895f,-46.875f, +11.7188f,59.1807f,-46.875f, +15.625f,60.2442f,-46.875f, +19.5313f,60.6114f,-46.875f, +23.4375f,59.9439f,-46.875f, +27.3438f,58.704f,-46.875f, +31.25f,58.3729f,-46.875f, +35.1563f,57.0256f,-46.875f, +39.0625f,57.069f,-46.875f, +42.9688f,57.0536f,-46.875f, +46.875f,55.7912f,-46.875f, +50.7813f,54.8674f,-46.875f, +54.6875f,53.8265f,-46.875f, +58.5938f,53.563f,-46.875f, +62.5f,52.5979f,-46.875f, +66.4063f,52.3986f,-46.875f, +70.3125f,52.1891f,-46.875f, +74.2188f,52.2468f,-46.875f, +78.125f,52.3398f,-46.875f, +82.0313f,50.9875f,-46.875f, +85.9375f,49.4072f,-46.875f, +89.8438f,48.3295f,-46.875f, +93.75f,48.9009f,-46.875f, +97.6563f,47.6633f,-46.875f, +101.563f,44.4101f,-46.875f, +105.469f,44.0249f,-46.875f, +109.375f,43.7395f,-46.875f, +113.281f,44.0967f,-46.875f, +117.188f,43.3593f,-46.875f, +121.094f,42.11f,-46.875f, +125.0f,40.8903f,-46.875f, +128.906f,40.3861f,-46.875f, +132.813f,40.075f,-46.875f, +136.719f,39.6347f,-46.875f, +140.625f,38.7369f,-46.875f, +144.531f,37.9042f,-46.875f, +148.438f,36.8546f,-46.875f, +152.344f,36.4012f,-46.875f, +156.25f,35.3977f,-46.875f, +160.156f,34.0947f,-46.875f, +164.063f,32.2545f,-46.875f, +167.969f,30.0086f,-46.875f, +171.875f,29.202f,-46.875f, +175.781f,28.0362f,-46.875f, +179.688f,26.7114f,-46.875f, +183.594f,25.9577f,-46.875f, +187.5f,25.3242f,-46.875f, +191.406f,23.8586f,-46.875f, +195.313f,20.6056f,-46.875f, +199.219f,19.3835f,-46.875f, +203.125f,17.4503f,-46.875f, +207.031f,16.5736f,-46.875f, +210.938f,14.945f,-46.875f, +214.844f,12.5914f,-46.875f, +218.75f,11.835f,-46.875f, +222.656f,10.1636f,-46.875f, +226.563f,9.71281f,-46.875f, +230.469f,9.27988f,-46.875f, +234.375f,8.50394f,-46.875f, +238.281f,9.20978f,-46.875f, +242.188f,9.21707f,-46.875f, +246.094f,9.40089f,-46.875f, +250.0f,8.55411f,-46.875f, +3.90625f,59.8509f,-50.7813f, +7.8125f,59.6141f,-50.7813f, +11.7188f,59.7453f,-50.7813f, +15.625f,60.4259f,-50.7813f, +19.5313f,59.4314f,-50.7813f, +23.4375f,59.033f,-50.7813f, +27.3438f,57.561f,-50.7813f, +31.25f,57.9511f,-50.7813f, +35.1563f,57.0088f,-50.7813f, +39.0625f,56.2469f,-50.7813f, +42.9688f,55.8604f,-50.7813f, +46.875f,55.2326f,-50.7813f, +50.7813f,54.8965f,-50.7813f, +54.6875f,53.1713f,-50.7813f, +58.5938f,52.6122f,-50.7813f, +62.5f,50.9097f,-50.7813f, +66.4063f,50.8144f,-50.7813f, +70.3125f,50.2702f,-50.7813f, +74.2188f,51.4962f,-50.7813f, +78.125f,50.7879f,-50.7813f, +82.0313f,49.5502f,-50.7813f, +85.9375f,48.3386f,-50.7813f, +89.8438f,48.0143f,-50.7813f, +93.75f,46.7527f,-50.7813f, +97.6563f,45.5374f,-50.7813f, +101.563f,44.3542f,-50.7813f, +105.469f,44.8366f,-50.7813f, +109.375f,45.0192f,-50.7813f, +113.281f,44.4763f,-50.7813f, +117.188f,43.4751f,-50.7813f, +121.094f,42.029f,-50.7813f, +125.0f,40.9708f,-50.7813f, +128.906f,40.3658f,-50.7813f, +132.813f,40.0768f,-50.7813f, +136.719f,40.0333f,-50.7813f, +140.625f,38.2667f,-50.7813f, +144.531f,36.5326f,-50.7813f, +148.438f,35.8183f,-50.7813f, +152.344f,35.3934f,-50.7813f, +156.25f,34.9787f,-50.7813f, +160.156f,33.4969f,-50.7813f, +164.063f,31.7517f,-50.7813f, +167.969f,29.499f,-50.7813f, +171.875f,27.1729f,-50.7813f, +175.781f,25.4931f,-50.7813f, +179.688f,25.2745f,-50.7813f, +183.594f,25.2315f,-50.7813f, +187.5f,24.531f,-50.7813f, +191.406f,23.4387f,-50.7813f, +195.313f,21.3665f,-50.7813f, +199.219f,19.2834f,-50.7813f, +203.125f,17.7694f,-50.7813f, +207.031f,16.0247f,-50.7813f, +210.938f,13.9451f,-50.7813f, +214.844f,12.3369f,-50.7813f, +218.75f,10.9033f,-50.7813f, +222.656f,10.0734f,-50.7813f, +226.563f,9.08212f,-50.7813f, +230.469f,9.04527f,-50.7813f, +234.375f,8.83458f,-50.7813f, +238.281f,9.03578f,-50.7813f, +242.188f,9.06782f,-50.7813f, +246.094f,9.03068f,-50.7813f, +250.0f,9.66685f,-50.7813f, +3.90625f,60.3928f,-54.6875f, +7.8125f,60.9235f,-54.6875f, +11.7188f,60.8946f,-54.6875f, +15.625f,60.5131f,-54.6875f, +19.5313f,58.455f,-54.6875f, +23.4375f,57.9712f,-54.6875f, +27.3438f,57.0716f,-54.6875f, +31.25f,56.9372f,-54.6875f, +35.1563f,57.5607f,-54.6875f, +39.0625f,56.6778f,-54.6875f, +42.9688f,56.24f,-54.6875f, +46.875f,55.0661f,-54.6875f, +50.7813f,54.3546f,-54.6875f, +54.6875f,52.1641f,-54.6875f, +58.5938f,51.2643f,-54.6875f, +62.5f,49.4484f,-54.6875f, +66.4063f,48.4401f,-54.6875f, +70.3125f,48.0181f,-54.6875f, +74.2188f,48.8036f,-54.6875f, +78.125f,48.2106f,-54.6875f, +82.0313f,47.8181f,-54.6875f, +85.9375f,47.3982f,-54.6875f, +89.8438f,46.4776f,-54.6875f, +93.75f,45.3848f,-54.6875f, +97.6563f,44.5336f,-54.6875f, +101.563f,45.1445f,-54.6875f, +105.469f,45.5775f,-54.6875f, +109.375f,45.4274f,-54.6875f, +113.281f,44.4184f,-54.6875f, +117.188f,43.6208f,-54.6875f, +121.094f,43.0133f,-54.6875f, +125.0f,41.2193f,-54.6875f, +128.906f,40.0465f,-54.6875f, +132.813f,40.3451f,-54.6875f, +136.719f,39.4272f,-54.6875f, +140.625f,37.2935f,-54.6875f, +144.531f,35.9597f,-54.6875f, +148.438f,34.766f,-54.6875f, +152.344f,33.3503f,-54.6875f, +156.25f,33.6732f,-54.6875f, +160.156f,32.5764f,-54.6875f, +164.063f,30.6942f,-54.6875f, +167.969f,28.8727f,-54.6875f, +171.875f,26.8203f,-54.6875f, +175.781f,24.7162f,-54.6875f, +179.688f,23.5533f,-54.6875f, +183.594f,23.5154f,-54.6875f, +187.5f,23.3554f,-54.6875f, +191.406f,22.7735f,-54.6875f, +195.313f,22.2741f,-54.6875f, +199.219f,20.9717f,-54.6875f, +203.125f,18.5469f,-54.6875f, +207.031f,16.0531f,-54.6875f, +210.938f,13.6058f,-54.6875f, +214.844f,11.0674f,-54.6875f, +218.75f,9.89862f,-54.6875f, +222.656f,9.6172f,-54.6875f, +226.563f,8.63026f,-54.6875f, +230.469f,8.95799f,-54.6875f, +234.375f,8.84522f,-54.6875f, +238.281f,8.9176f,-54.6875f, +242.188f,9.19248f,-54.6875f, +246.094f,9.16691f,-54.6875f, +250.0f,9.42022f,-54.6875f, +3.90625f,61.5747f,-58.5938f, +7.8125f,61.244f,-58.5938f, +11.7188f,60.3982f,-58.5938f, +15.625f,59.4267f,-58.5938f, +19.5313f,58.5294f,-58.5938f, +23.4375f,56.6412f,-58.5938f, +27.3438f,56.0648f,-58.5938f, +31.25f,56.4883f,-58.5938f, +35.1563f,56.5562f,-58.5938f, +39.0625f,56.745f,-58.5938f, +42.9688f,55.6505f,-58.5938f, +46.875f,54.6622f,-58.5938f, +50.7813f,53.7206f,-58.5938f, +54.6875f,51.9309f,-58.5938f, +58.5938f,50.4214f,-58.5938f, +62.5f,48.4353f,-58.5938f, +66.4063f,47.1373f,-58.5938f, +70.3125f,46.0037f,-58.5938f, +74.2188f,45.9795f,-58.5938f, +78.125f,45.2396f,-58.5938f, +82.0313f,45.264f,-58.5938f, +85.9375f,45.2603f,-58.5938f, +89.8438f,45.3076f,-58.5938f, +93.75f,44.8744f,-58.5938f, +97.6563f,44.3646f,-58.5938f, +101.563f,45.1043f,-58.5938f, +105.469f,45.6336f,-58.5938f, +109.375f,44.6129f,-58.5938f, +113.281f,44.3333f,-58.5938f, +117.188f,44.3267f,-58.5938f, +121.094f,42.9064f,-58.5938f, +125.0f,40.63f,-58.5938f, +128.906f,41.2828f,-58.5938f, +132.813f,40.2801f,-58.5938f, +136.719f,39.4089f,-58.5938f, +140.625f,37.0919f,-58.5938f, +144.531f,34.889f,-58.5938f, +148.438f,32.5161f,-58.5938f, +152.344f,31.9597f,-58.5938f, +156.25f,31.5986f,-58.5938f, +160.156f,31.1966f,-58.5938f, +164.063f,30.4149f,-58.5938f, +167.969f,29.0304f,-58.5938f, +171.875f,27.2929f,-58.5938f, +175.781f,26.0835f,-58.5938f, +179.688f,24.7373f,-58.5938f, +183.594f,23.6409f,-58.5938f, +187.5f,23.3059f,-58.5938f, +191.406f,22.8781f,-58.5938f, +195.313f,22.319f,-58.5938f, +199.219f,21.2986f,-58.5938f, +203.125f,19.8613f,-58.5938f, +207.031f,16.8941f,-58.5938f, +210.938f,13.7519f,-58.5938f, +214.844f,11.895f,-58.5938f, +218.75f,9.64673f,-58.5938f, +222.656f,9.27102f,-58.5938f, +226.563f,9.40316f,-58.5938f, +230.469f,8.90628f,-58.5938f, +234.375f,8.63691f,-58.5938f, +238.281f,9.10736f,-58.5938f, +242.188f,9.6506f,-58.5938f, +246.094f,9.20945f,-58.5938f, +250.0f,10.1973f,-58.5938f, +3.90625f,62.1111f,-62.5f, +7.8125f,60.6401f,-62.5f, +11.7188f,59.5734f,-62.5f, +15.625f,59.219f,-62.5f, +19.5313f,57.489f,-62.5f, +23.4375f,55.7813f,-62.5f, +27.3438f,55.9775f,-62.5f, +31.25f,55.9857f,-62.5f, +35.1563f,55.7053f,-62.5f, +39.0625f,55.9712f,-62.5f, +42.9688f,54.6904f,-62.5f, +46.875f,53.8065f,-62.5f, +50.7813f,52.4182f,-62.5f, +54.6875f,50.8531f,-62.5f, +58.5938f,49.1994f,-62.5f, +62.5f,47.7017f,-62.5f, +66.4063f,45.469f,-62.5f, +70.3125f,44.3384f,-62.5f, +74.2188f,43.2272f,-62.5f, +78.125f,43.8591f,-62.5f, +82.0313f,44.3452f,-62.5f, +85.9375f,44.3048f,-62.5f, +89.8438f,44.2242f,-62.5f, +93.75f,44.0587f,-62.5f, +97.6563f,43.7317f,-62.5f, +101.563f,44.5392f,-62.5f, +105.469f,44.5257f,-62.5f, +109.375f,43.5595f,-62.5f, +113.281f,44.5114f,-62.5f, +117.188f,43.2895f,-62.5f, +121.094f,41.6188f,-62.5f, +125.0f,39.9989f,-62.5f, +128.906f,40.9613f,-62.5f, +132.813f,39.8454f,-62.5f, +136.719f,38.9499f,-62.5f, +140.625f,36.7405f,-62.5f, +144.531f,34.8983f,-62.5f, +148.438f,33.5172f,-62.5f, +152.344f,31.5497f,-62.5f, +156.25f,31.3001f,-62.5f, +160.156f,30.8035f,-62.5f, +164.063f,30.3361f,-62.5f, +167.969f,29.7129f,-62.5f, +171.875f,28.9356f,-62.5f, +175.781f,27.3605f,-62.5f, +179.688f,26.5354f,-62.5f, +183.594f,25.1923f,-62.5f, +187.5f,23.8745f,-62.5f, +191.406f,22.6444f,-62.5f, +195.313f,22.0412f,-62.5f, +199.219f,20.9675f,-62.5f, +203.125f,18.5243f,-62.5f, +207.031f,15.5154f,-62.5f, +210.938f,13.2419f,-62.5f, +214.844f,11.0082f,-62.5f, +218.75f,9.92645f,-62.5f, +222.656f,9.66787f,-62.5f, +226.563f,10.141f,-62.5f, +230.469f,9.5559f,-62.5f, +234.375f,8.93799f,-62.5f, +238.281f,9.36179f,-62.5f, +242.188f,9.32325f,-62.5f, +246.094f,9.89448f,-62.5f, +250.0f,11.3062f,-62.5f, +3.90625f,60.8569f,-66.4063f, +7.8125f,59.3087f,-66.4063f, +11.7188f,58.6192f,-66.4063f, +15.625f,57.567f,-66.4063f, +19.5313f,54.6351f,-66.4063f, +23.4375f,53.6183f,-66.4063f, +27.3438f,54.0844f,-66.4063f, +31.25f,54.4962f,-66.4063f, +35.1563f,53.9539f,-66.4063f, +39.0625f,53.4324f,-66.4063f, +42.9688f,52.6655f,-66.4063f, +46.875f,51.9681f,-66.4063f, +50.7813f,51.1623f,-66.4063f, +54.6875f,50.0114f,-66.4063f, +58.5938f,47.9598f,-66.4063f, +62.5f,46.2999f,-66.4063f, +66.4063f,44.4466f,-66.4063f, +70.3125f,42.2001f,-66.4063f, +74.2188f,41.2192f,-66.4063f, +78.125f,41.7209f,-66.4063f, +82.0313f,42.7363f,-66.4063f, +85.9375f,42.9552f,-66.4063f, +89.8438f,43.0346f,-66.4063f, +93.75f,43.4604f,-66.4063f, +97.6563f,42.6437f,-66.4063f, +101.563f,42.6894f,-66.4063f, +105.469f,43.1054f,-66.4063f, +109.375f,42.7138f,-66.4063f, +113.281f,42.4744f,-66.4063f, +117.188f,42.2299f,-66.4063f, +121.094f,41.2421f,-66.4063f, +125.0f,40.3737f,-66.4063f, +128.906f,40.1758f,-66.4063f, +132.813f,39.5421f,-66.4063f, +136.719f,39.0437f,-66.4063f, +140.625f,37.1531f,-66.4063f, +144.531f,34.9841f,-66.4063f, +148.438f,33.2713f,-66.4063f, +152.344f,32.4185f,-66.4063f, +156.25f,31.779f,-66.4063f, +160.156f,30.7377f,-66.4063f, +164.063f,30.5524f,-66.4063f, +167.969f,29.5693f,-66.4063f, +171.875f,28.9756f,-66.4063f, +175.781f,27.4499f,-66.4063f, +179.688f,26.7907f,-66.4063f, +183.594f,25.5886f,-66.4063f, +187.5f,24.2807f,-66.4063f, +191.406f,22.1754f,-66.4063f, +195.313f,20.7766f,-66.4063f, +199.219f,19.914f,-66.4063f, +203.125f,17.149f,-66.4063f, +207.031f,14.0043f,-66.4063f, +210.938f,11.404f,-66.4063f, +214.844f,10.0012f,-66.4063f, +218.75f,8.65109f,-66.4063f, +222.656f,9.38897f,-66.4063f, +226.563f,9.4612f,-66.4063f, +230.469f,8.86613f,-66.4063f, +234.375f,8.68429f,-66.4063f, +238.281f,9.75985f,-66.4063f, +242.188f,10.3807f,-66.4063f, +246.094f,10.966f,-66.4063f, +250.0f,11.4354f,-66.4063f, +3.90625f,59.1482f,-70.3125f, +7.8125f,57.7892f,-70.3125f, +11.7188f,55.5839f,-70.3125f, +15.625f,54.3451f,-70.3125f, +19.5313f,52.0576f,-70.3125f, +23.4375f,50.5935f,-70.3125f, +27.3438f,50.8648f,-70.3125f, +31.25f,51.3182f,-70.3125f, +35.1563f,51.6726f,-70.3125f, +39.0625f,51.1264f,-70.3125f, +42.9688f,51.6239f,-70.3125f, +46.875f,49.728f,-70.3125f, +50.7813f,48.7924f,-70.3125f, +54.6875f,47.3884f,-70.3125f, +58.5938f,46.4477f,-70.3125f, +62.5f,45.2447f,-70.3125f, +66.4063f,42.8677f,-70.3125f, +70.3125f,40.9023f,-70.3125f, +74.2188f,39.5284f,-70.3125f, +78.125f,39.6524f,-70.3125f, +82.0313f,40.5173f,-70.3125f, +85.9375f,41.0204f,-70.3125f, +89.8438f,41.9366f,-70.3125f, +93.75f,42.1341f,-70.3125f, +97.6563f,41.4699f,-70.3125f, +101.563f,40.6754f,-70.3125f, +105.469f,41.2206f,-70.3125f, +109.375f,40.9668f,-70.3125f, +113.281f,41.1079f,-70.3125f, +117.188f,40.7056f,-70.3125f, +121.094f,39.8305f,-70.3125f, +125.0f,40.959f,-70.3125f, +128.906f,41.7481f,-70.3125f, +132.813f,41.1255f,-70.3125f, +136.719f,39.8634f,-70.3125f, +140.625f,37.8454f,-70.3125f, +144.531f,35.3914f,-70.3125f, +148.438f,33.8462f,-70.3125f, +152.344f,33.0994f,-70.3125f, +156.25f,32.4757f,-70.3125f, +160.156f,31.4779f,-70.3125f, +164.063f,29.4211f,-70.3125f, +167.969f,28.0779f,-70.3125f, +171.875f,27.802f,-70.3125f, +175.781f,26.7406f,-70.3125f, +179.688f,25.4777f,-70.3125f, +183.594f,24.7569f,-70.3125f, +187.5f,22.9331f,-70.3125f, +191.406f,21.2419f,-70.3125f, +195.313f,19.5082f,-70.3125f, +199.219f,17.6022f,-70.3125f, +203.125f,15.316f,-70.3125f, +207.031f,12.7546f,-70.3125f, +210.938f,10.3646f,-70.3125f, +214.844f,8.2502f,-70.3125f, +218.75f,8.14317f,-70.3125f, +222.656f,8.65089f,-70.3125f, +226.563f,8.60005f,-70.3125f, +230.469f,8.58165f,-70.3125f, +234.375f,9.40162f,-70.3125f, +238.281f,9.96281f,-70.3125f, +242.188f,9.81934f,-70.3125f, +246.094f,10.3078f,-70.3125f, +250.0f,10.4404f,-70.3125f, +3.90625f,56.5167f,-74.2188f, +7.8125f,55.7237f,-74.2188f, +11.7188f,53.4039f,-74.2188f, +15.625f,51.0313f,-74.2188f, +19.5313f,49.1141f,-74.2188f, +23.4375f,47.8398f,-74.2188f, +27.3438f,47.778f,-74.2188f, +31.25f,48.3917f,-74.2188f, +35.1563f,48.2503f,-74.2188f, +39.0625f,49.1497f,-74.2188f, +42.9688f,48.8224f,-74.2188f, +46.875f,47.4358f,-74.2188f, +50.7813f,47.051f,-74.2188f, +54.6875f,45.4218f,-74.2188f, +58.5938f,44.3385f,-74.2188f, +62.5f,42.9758f,-74.2188f, +66.4063f,41.4743f,-74.2188f, +70.3125f,39.4251f,-74.2188f, +74.2188f,37.5972f,-74.2188f, +78.125f,37.8246f,-74.2188f, +82.0313f,38.9578f,-74.2188f, +85.9375f,40.148f,-74.2188f, +89.8438f,41.1035f,-74.2188f, +93.75f,40.631f,-74.2188f, +97.6563f,40.0863f,-74.2188f, +101.563f,40.3273f,-74.2188f, +105.469f,40.0413f,-74.2188f, +109.375f,40.0514f,-74.2188f, +113.281f,39.4849f,-74.2188f, +117.188f,39.5903f,-74.2188f, +121.094f,40.1543f,-74.2188f, +125.0f,40.3424f,-74.2188f, +128.906f,41.779f,-74.2188f, +132.813f,41.4976f,-74.2188f, +136.719f,41.1475f,-74.2188f, +140.625f,38.8105f,-74.2188f, +144.531f,35.834f,-74.2188f, +148.438f,34.6385f,-74.2188f, +152.344f,33.7088f,-74.2188f, +156.25f,32.7137f,-74.2188f, +160.156f,30.7745f,-74.2188f, +164.063f,28.172f,-74.2188f, +167.969f,27.1433f,-74.2188f, +171.875f,26.7248f,-74.2188f, +175.781f,25.7807f,-74.2188f, +179.688f,24.8758f,-74.2188f, +183.594f,23.4994f,-74.2188f, +187.5f,23.3209f,-74.2188f, +191.406f,22.3523f,-74.2188f, +195.313f,20.3275f,-74.2188f, +199.219f,17.2927f,-74.2188f, +203.125f,15.0486f,-74.2188f, +207.031f,12.2721f,-74.2188f, +210.938f,9.60109f,-74.2188f, +214.844f,7.36411f,-74.2188f, +218.75f,7.27514f,-74.2188f, +222.656f,8.35951f,-74.2188f, +226.563f,8.18334f,-74.2188f, +230.469f,8.98708f,-74.2188f, +234.375f,8.98011f,-74.2188f, +238.281f,9.03329f,-74.2188f, +242.188f,8.88664f,-74.2188f, +246.094f,8.62938f,-74.2188f, +250.0f,9.6823f,-74.2188f, +3.90625f,54.4402f,-78.125f, +7.8125f,53.0525f,-78.125f, +11.7188f,51.2204f,-78.125f, +15.625f,48.7251f,-78.125f, +19.5313f,45.9841f,-78.125f, +23.4375f,45.0227f,-78.125f, +27.3438f,45.3099f,-78.125f, +31.25f,45.9225f,-78.125f, +35.1563f,46.8025f,-78.125f, +39.0625f,46.8434f,-78.125f, +42.9688f,46.0024f,-78.125f, +46.875f,45.6669f,-78.125f, +50.7813f,45.4624f,-78.125f, +54.6875f,43.4573f,-78.125f, +58.5938f,42.1273f,-78.125f, +62.5f,41.0088f,-78.125f, +66.4063f,38.8967f,-78.125f, +70.3125f,38.002f,-78.125f, +74.2188f,36.5282f,-78.125f, +78.125f,37.0499f,-78.125f, +82.0313f,37.3419f,-78.125f, +85.9375f,38.6056f,-78.125f, +89.8438f,39.7527f,-78.125f, +93.75f,40.3513f,-78.125f, +97.6563f,40.6919f,-78.125f, +101.563f,40.7736f,-78.125f, +105.469f,40.3007f,-78.125f, +109.375f,39.3023f,-78.125f, +113.281f,39.1369f,-78.125f, +117.188f,39.884f,-78.125f, +121.094f,40.5674f,-78.125f, +125.0f,40.8192f,-78.125f, +128.906f,41.893f,-78.125f, +132.813f,42.3647f,-78.125f, +136.719f,41.2455f,-78.125f, +140.625f,38.7064f,-78.125f, +144.531f,36.9679f,-78.125f, +148.438f,36.03f,-78.125f, +152.344f,33.9946f,-78.125f, +156.25f,32.2274f,-78.125f, +160.156f,30.474f,-78.125f, +164.063f,28.4739f,-78.125f, +167.969f,27.222f,-78.125f, +171.875f,26.6935f,-78.125f, +175.781f,25.0624f,-78.125f, +179.688f,24.162f,-78.125f, +183.594f,24.0176f,-78.125f, +187.5f,24.0379f,-78.125f, +191.406f,22.4301f,-78.125f, +195.313f,19.7078f,-78.125f, +199.219f,17.0911f,-78.125f, +203.125f,14.784f,-78.125f, +207.031f,11.8835f,-78.125f, +210.938f,9.34715f,-78.125f, +214.844f,7.23075f,-78.125f, +218.75f,7.91637f,-78.125f, +222.656f,8.69702f,-78.125f, +226.563f,8.56112f,-78.125f, +230.469f,9.86446f,-78.125f, +234.375f,9.26431f,-78.125f, +238.281f,8.47473f,-78.125f, +242.188f,7.8386f,-78.125f, +246.094f,7.82236f,-78.125f, +250.0f,8.68625f,-78.125f, +3.90625f,51.949f,-82.0313f, +7.8125f,50.1159f,-82.0313f, +11.7188f,48.9067f,-82.0313f, +15.625f,46.6417f,-82.0313f, +19.5313f,44.5725f,-82.0313f, +23.4375f,43.435f,-82.0313f, +27.3438f,43.6749f,-82.0313f, +31.25f,44.8399f,-82.0313f, +35.1563f,45.0253f,-82.0313f, +39.0625f,44.7335f,-82.0313f, +42.9688f,44.4485f,-82.0313f, +46.875f,44.8284f,-82.0313f, +50.7813f,43.5547f,-82.0313f, +54.6875f,41.2266f,-82.0313f, +58.5938f,40.4716f,-82.0313f, +62.5f,38.4361f,-82.0313f, +66.4063f,36.3554f,-82.0313f, +70.3125f,35.5722f,-82.0313f, +74.2188f,35.0069f,-82.0313f, +78.125f,35.8289f,-82.0313f, +82.0313f,37.0933f,-82.0313f, +85.9375f,38.1008f,-82.0313f, +89.8438f,38.9582f,-82.0313f, +93.75f,40.0751f,-82.0313f, +97.6563f,40.3989f,-82.0313f, +101.563f,40.2487f,-82.0313f, +105.469f,39.9234f,-82.0313f, +109.375f,40.0277f,-82.0313f, +113.281f,40.6647f,-82.0313f, +117.188f,40.69f,-82.0313f, +121.094f,40.7857f,-82.0313f, +125.0f,41.5688f,-82.0313f, +128.906f,41.836f,-82.0313f, +132.813f,41.6054f,-82.0313f, +136.719f,39.6237f,-82.0313f, +140.625f,38.6765f,-82.0313f, +144.531f,36.9959f,-82.0313f, +148.438f,35.8215f,-82.0313f, +152.344f,34.799f,-82.0313f, +156.25f,33.2398f,-82.0313f, +160.156f,30.7864f,-82.0313f, +164.063f,28.6776f,-82.0313f, +167.969f,26.6558f,-82.0313f, +171.875f,25.8282f,-82.0313f, +175.781f,24.7932f,-82.0313f, +179.688f,22.3283f,-82.0313f, +183.594f,23.1666f,-82.0313f, +187.5f,23.1721f,-82.0313f, +191.406f,21.3358f,-82.0313f, +195.313f,18.8226f,-82.0313f, +199.219f,16.5471f,-82.0313f, +203.125f,14.4667f,-82.0313f, +207.031f,11.1533f,-82.0313f, +210.938f,8.28389f,-82.0313f, +214.844f,8.02411f,-82.0313f, +218.75f,8.03784f,-82.0313f, +222.656f,8.27638f,-82.0313f, +226.563f,8.14824f,-82.0313f, +230.469f,8.45286f,-82.0313f, +234.375f,8.21959f,-82.0313f, +238.281f,8.25224f,-82.0313f, +242.188f,7.67129f,-82.0313f, +246.094f,8.04143f,-82.0313f, +250.0f,8.6199f,-82.0313f, +3.90625f,50.007f,-85.9375f, +7.8125f,48.4593f,-85.9375f, +11.7188f,46.0233f,-85.9375f, +15.625f,44.0556f,-85.9375f, +19.5313f,42.3324f,-85.9375f, +23.4375f,41.8982f,-85.9375f, +27.3438f,42.3931f,-85.9375f, +31.25f,43.1153f,-85.9375f, +35.1563f,43.1285f,-85.9375f, +39.0625f,43.422f,-85.9375f, +42.9688f,43.5417f,-85.9375f, +46.875f,42.2294f,-85.9375f, +50.7813f,40.9068f,-85.9375f, +54.6875f,39.4177f,-85.9375f, +58.5938f,37.2575f,-85.9375f, +62.5f,35.2254f,-85.9375f, +66.4063f,33.8821f,-85.9375f, +70.3125f,33.1531f,-85.9375f, +74.2188f,34.2747f,-85.9375f, +78.125f,35.599f,-85.9375f, +82.0313f,37.007f,-85.9375f, +85.9375f,37.5018f,-85.9375f, +89.8438f,38.1376f,-85.9375f, +93.75f,38.9449f,-85.9375f, +97.6563f,38.9221f,-85.9375f, +101.563f,38.8555f,-85.9375f, +105.469f,39.5572f,-85.9375f, +109.375f,40.1231f,-85.9375f, +113.281f,40.7416f,-85.9375f, +117.188f,40.3888f,-85.9375f, +121.094f,40.6715f,-85.9375f, +125.0f,40.7246f,-85.9375f, +128.906f,40.6124f,-85.9375f, +132.813f,39.685f,-85.9375f, +136.719f,39.2043f,-85.9375f, +140.625f,38.1816f,-85.9375f, +144.531f,36.598f,-85.9375f, +148.438f,36.2907f,-85.9375f, +152.344f,34.8832f,-85.9375f, +156.25f,33.4024f,-85.9375f, +160.156f,31.2463f,-85.9375f, +164.063f,29.1669f,-85.9375f, +167.969f,26.7298f,-85.9375f, +171.875f,24.3407f,-85.9375f, +175.781f,23.4854f,-85.9375f, +179.688f,21.3474f,-85.9375f, +183.594f,21.2953f,-85.9375f, +187.5f,21.7398f,-85.9375f, +191.406f,20.4218f,-85.9375f, +195.313f,17.9433f,-85.9375f, +199.219f,15.3133f,-85.9375f, +203.125f,13.0586f,-85.9375f, +207.031f,9.24996f,-85.9375f, +210.938f,7.18408f,-85.9375f, +214.844f,7.59758f,-85.9375f, +218.75f,8.04641f,-85.9375f, +222.656f,8.01634f,-85.9375f, +226.563f,7.95015f,-85.9375f, +230.469f,7.86343f,-85.9375f, +234.375f,6.21751f,-85.9375f, +238.281f,7.40112f,-85.9375f, +242.188f,7.60481f,-85.9375f, +246.094f,6.77129f,-85.9375f, +250.0f,7.87753f,-85.9375f, +3.90625f,47.6596f,-89.8438f, +7.8125f,45.9136f,-89.8438f, +11.7188f,44.0495f,-89.8438f, +15.625f,42.5127f,-89.8438f, +19.5313f,41.5996f,-89.8438f, +23.4375f,41.2638f,-89.8438f, +27.3438f,41.2672f,-89.8438f, +31.25f,41.5402f,-89.8438f, +35.1563f,42.558f,-89.8438f, +39.0625f,42.49f,-89.8438f, +42.9688f,42.2839f,-89.8438f, +46.875f,40.9401f,-89.8438f, +50.7813f,38.7346f,-89.8438f, +54.6875f,36.624f,-89.8438f, +58.5938f,35.1978f,-89.8438f, +62.5f,34.9272f,-89.8438f, +66.4063f,32.893f,-89.8438f, +70.3125f,32.4101f,-89.8438f, +74.2188f,33.9814f,-89.8438f, +78.125f,35.8825f,-89.8438f, +82.0313f,37.1245f,-89.8438f, +85.9375f,37.3954f,-89.8438f, +89.8438f,38.0118f,-89.8438f, +93.75f,37.5426f,-89.8438f, +97.6563f,38.0776f,-89.8438f, +101.563f,37.9785f,-89.8438f, +105.469f,38.6389f,-89.8438f, +109.375f,39.284f,-89.8438f, +113.281f,40.0027f,-89.8438f, +117.188f,41.2412f,-89.8438f, +121.094f,41.2301f,-89.8438f, +125.0f,40.7611f,-89.8438f, +128.906f,39.7426f,-89.8438f, +132.813f,39.1387f,-89.8438f, +136.719f,38.499f,-89.8438f, +140.625f,37.714f,-89.8438f, +144.531f,36.6379f,-89.8438f, +148.438f,36.1196f,-89.8438f, +152.344f,35.7001f,-89.8438f, +156.25f,33.9038f,-89.8438f, +160.156f,32.0706f,-89.8438f, +164.063f,29.746f,-89.8438f, +167.969f,26.4482f,-89.8438f, +171.875f,23.8046f,-89.8438f, +175.781f,21.9675f,-89.8438f, +179.688f,20.7011f,-89.8438f, +183.594f,20.6699f,-89.8438f, +187.5f,20.1508f,-89.8438f, +191.406f,17.8245f,-89.8438f, +195.313f,16.2785f,-89.8438f, +199.219f,13.4596f,-89.8438f, +203.125f,9.54647f,-89.8438f, +207.031f,6.02727f,-89.8438f, +210.938f,5.88903f,-89.8438f, +214.844f,6.47568f,-89.8438f, +218.75f,6.20004f,-89.8438f, +222.656f,6.0849f,-89.8438f, +226.563f,6.84648f,-89.8438f, +230.469f,6.3424f,-89.8438f, +234.375f,5.81853f,-89.8438f, +238.281f,5.89205f,-89.8438f, +242.188f,6.84078f,-89.8438f, +246.094f,6.32426f,-89.8438f, +250.0f,6.29368f,-89.8438f, +3.90625f,45.4182f,-93.75f, +7.8125f,44.5664f,-93.75f, +11.7188f,44.0207f,-93.75f, +15.625f,42.2553f,-93.75f, +19.5313f,40.8951f,-93.75f, +23.4375f,40.7665f,-93.75f, +27.3438f,40.5756f,-93.75f, +31.25f,41.2988f,-93.75f, +35.1563f,40.6862f,-93.75f, +39.0625f,40.6007f,-93.75f, +42.9688f,39.5329f,-93.75f, +46.875f,38.2364f,-93.75f, +50.7813f,36.1442f,-93.75f, +54.6875f,34.7353f,-93.75f, +58.5938f,34.4214f,-93.75f, +62.5f,33.9528f,-93.75f, +66.4063f,32.4931f,-93.75f, +70.3125f,32.5145f,-93.75f, +74.2188f,33.393f,-93.75f, +78.125f,34.9658f,-93.75f, +82.0313f,36.3611f,-93.75f, +85.9375f,37.568f,-93.75f, +89.8438f,37.012f,-93.75f, +93.75f,37.6392f,-93.75f, +97.6563f,38.4371f,-93.75f, +101.563f,38.3719f,-93.75f, +105.469f,39.1179f,-93.75f, +109.375f,38.5168f,-93.75f, +113.281f,40.0403f,-93.75f, +117.188f,40.2277f,-93.75f, +121.094f,40.8985f,-93.75f, +125.0f,40.189f,-93.75f, +128.906f,39.9435f,-93.75f, +132.813f,39.6824f,-93.75f, +136.719f,38.844f,-93.75f, +140.625f,37.4579f,-93.75f, +144.531f,36.8375f,-93.75f, +148.438f,36.2601f,-93.75f, +152.344f,35.6484f,-93.75f, +156.25f,34.179f,-93.75f, +160.156f,32.0651f,-93.75f, +164.063f,28.6431f,-93.75f, +167.969f,25.1239f,-93.75f, +171.875f,22.4459f,-93.75f, +175.781f,19.5301f,-93.75f, +179.688f,18.4371f,-93.75f, +183.594f,18.6076f,-93.75f, +187.5f,17.488f,-93.75f, +191.406f,15.1604f,-93.75f, +195.313f,13.0197f,-93.75f, +199.219f,9.4702f,-93.75f, +203.125f,5.597f,-93.75f, +207.031f,3.59409f,-93.75f, +210.938f,4.28966f,-93.75f, +214.844f,4.21811f,-93.75f, +218.75f,4.11546f,-93.75f, +222.656f,5.40815f,-93.75f, +226.563f,5.56249f,-93.75f, +230.469f,5.35075f,-93.75f, +234.375f,5.24306f,-93.75f, +238.281f,4.85548f,-93.75f, +242.188f,5.02825f,-93.75f, +246.094f,5.32318f,-93.75f, +250.0f,5.59512f,-93.75f, +3.90625f,44.9637f,-97.6563f, +7.8125f,44.7813f,-97.6563f, +11.7188f,43.457f,-97.6563f, +15.625f,42.5329f,-97.6563f, +19.5313f,40.506f,-97.6563f, +23.4375f,39.8146f,-97.6563f, +27.3438f,40.2245f,-97.6563f, +31.25f,39.497f,-97.6563f, +35.1563f,38.8152f,-97.6563f, +39.0625f,38.3406f,-97.6563f, +42.9688f,37.57f,-97.6563f, +46.875f,36.3128f,-97.6563f, +50.7813f,34.2277f,-97.6563f, +54.6875f,33.3395f,-97.6563f, +58.5938f,32.972f,-97.6563f, +62.5f,32.6315f,-97.6563f, +66.4063f,32.4796f,-97.6563f, +70.3125f,31.6472f,-97.6563f, +74.2188f,32.2256f,-97.6563f, +78.125f,33.8073f,-97.6563f, +82.0313f,35.7591f,-97.6563f, +85.9375f,36.5001f,-97.6563f, +89.8438f,36.9113f,-97.6563f, +93.75f,37.6902f,-97.6563f, +97.6563f,37.9643f,-97.6563f, +101.563f,38.9556f,-97.6563f, +105.469f,39.6823f,-97.6563f, +109.375f,38.9917f,-97.6563f, +113.281f,40.0872f,-97.6563f, +117.188f,40.44f,-97.6563f, +121.094f,39.6877f,-97.6563f, +125.0f,39.0011f,-97.6563f, +128.906f,39.8735f,-97.6563f, +132.813f,39.5503f,-97.6563f, +136.719f,37.743f,-97.6563f, +140.625f,36.4691f,-97.6563f, +144.531f,36.1765f,-97.6563f, +148.438f,35.9476f,-97.6563f, +152.344f,35.1141f,-97.6563f, +156.25f,33.2516f,-97.6563f, +160.156f,30.654f,-97.6563f, +164.063f,27.2318f,-97.6563f, +167.969f,23.3975f,-97.6563f, +171.875f,20.6722f,-97.6563f, +175.781f,18.394f,-97.6563f, +179.688f,17.6475f,-97.6563f, +183.594f,16.1037f,-97.6563f, +187.5f,14.761f,-97.6563f, +191.406f,12.2456f,-97.6563f, +195.313f,9.43327f,-97.6563f, +199.219f,6.9118f,-97.6563f, +203.125f,4.26334f,-97.6563f, +207.031f,3.47413f,-97.6563f, +210.938f,3.74872f,-97.6563f, +214.844f,3.7631f,-97.6563f, +218.75f,3.80513f,-97.6563f, +222.656f,4.23443f,-97.6563f, +226.563f,3.71016f,-97.6563f, +230.469f,3.772f,-97.6563f, +234.375f,3.80374f,-97.6563f, +238.281f,3.70762f,-97.6563f, +242.188f,4.23931f,-97.6563f, +246.094f,4.40519f,-97.6563f, +250.0f,4.5119f,-97.6563f, +3.90625f,44.5311f,-101.563f, +7.8125f,44.4181f,-101.563f, +11.7188f,43.4864f,-101.563f, +15.625f,42.259f,-101.563f, +19.5313f,41.0558f,-101.563f, +23.4375f,39.9996f,-101.563f, +27.3438f,39.3917f,-101.563f, +31.25f,39.5691f,-101.563f, +35.1563f,37.0889f,-101.563f, +39.0625f,36.4296f,-101.563f, +42.9688f,36.543f,-101.563f, +46.875f,35.4365f,-101.563f, +50.7813f,33.3641f,-101.563f, +54.6875f,32.0629f,-101.563f, +58.5938f,32.175f,-101.563f, +62.5f,32.775f,-101.563f, +66.4063f,31.6335f,-101.563f, +70.3125f,32.1001f,-101.563f, +74.2188f,32.5906f,-101.563f, +78.125f,33.1502f,-101.563f, +82.0313f,35.1972f,-101.563f, +85.9375f,36.0132f,-101.563f, +89.8438f,37.3442f,-101.563f, +93.75f,37.6109f,-101.563f, +97.6563f,38.1601f,-101.563f, +101.563f,39.77f,-101.563f, +105.469f,39.6862f,-101.563f, +109.375f,39.4829f,-101.563f, +113.281f,40.1383f,-101.563f, +117.188f,40.8908f,-101.563f, +121.094f,39.3517f,-101.563f, +125.0f,38.9321f,-101.563f, +128.906f,39.2537f,-101.563f, +132.813f,38.4876f,-101.563f, +136.719f,36.6755f,-101.563f, +140.625f,35.2803f,-101.563f, +144.531f,35.8754f,-101.563f, +148.438f,36.2761f,-101.563f, +152.344f,34.7815f,-101.563f, +156.25f,32.2662f,-101.563f, +160.156f,29.8191f,-101.563f, +164.063f,25.8929f,-101.563f, +167.969f,22.552f,-101.563f, +171.875f,20.3186f,-101.563f, +175.781f,17.2917f,-101.563f, +179.688f,16.8305f,-101.563f, +183.594f,14.7168f,-101.563f, +187.5f,12.0609f,-101.563f, +191.406f,9.91022f,-101.563f, +195.313f,7.22029f,-101.563f, +199.219f,5.48379f,-101.563f, +203.125f,3.03759f,-101.563f, +207.031f,3.02148f,-101.563f, +210.938f,2.88667f,-101.563f, +214.844f,3.08795f,-101.563f, +218.75f,3.43814f,-101.563f, +222.656f,3.58591f,-101.563f, +226.563f,3.17855f,-101.563f, +230.469f,2.48711f,-101.563f, +234.375f,2.66471f,-101.563f, +238.281f,2.06432f,-101.563f, +242.188f,2.49704f,-101.563f, +246.094f,3.05219f,-101.563f, +250.0f,3.69155f,-101.563f, +3.90625f,44.8466f,-105.469f, +7.8125f,44.3102f,-105.469f, +11.7188f,43.8936f,-105.469f, +15.625f,43.2285f,-105.469f, +19.5313f,42.7384f,-105.469f, +23.4375f,41.2954f,-105.469f, +27.3438f,39.4813f,-105.469f, +31.25f,38.4483f,-105.469f, +35.1563f,35.8264f,-105.469f, +39.0625f,35.0991f,-105.469f, +42.9688f,35.1929f,-105.469f, +46.875f,34.3044f,-105.469f, +50.7813f,31.4169f,-105.469f, +54.6875f,30.8206f,-105.469f, +58.5938f,31.2902f,-105.469f, +62.5f,32.2869f,-105.469f, +66.4063f,32.5121f,-105.469f, +70.3125f,32.772f,-105.469f, +74.2188f,32.5422f,-105.469f, +78.125f,34.0506f,-105.469f, +82.0313f,35.4894f,-105.469f, +85.9375f,36.753f,-105.469f, +89.8438f,37.6901f,-105.469f, +93.75f,37.848f,-105.469f, +97.6563f,38.9724f,-105.469f, +101.563f,40.0724f,-105.469f, +105.469f,39.7381f,-105.469f, +109.375f,39.3905f,-105.469f, +113.281f,39.8577f,-105.469f, +117.188f,40.4957f,-105.469f, +121.094f,39.554f,-105.469f, +125.0f,39.0384f,-105.469f, +128.906f,38.2112f,-105.469f, +132.813f,36.7141f,-105.469f, +136.719f,34.736f,-105.469f, +140.625f,34.2236f,-105.469f, +144.531f,35.4181f,-105.469f, +148.438f,35.4456f,-105.469f, +152.344f,33.4389f,-105.469f, +156.25f,29.9708f,-105.469f, +160.156f,27.2392f,-105.469f, +164.063f,24.3409f,-105.469f, +167.969f,22.4438f,-105.469f, +171.875f,19.5326f,-105.469f, +175.781f,16.9951f,-105.469f, +179.688f,14.77f,-105.469f, +183.594f,13.1816f,-105.469f, +187.5f,10.3711f,-105.469f, +191.406f,7.10511f,-105.469f, +195.313f,5.43711f,-105.469f, +199.219f,3.35463f,-105.469f, +203.125f,2.41276f,-105.469f, +207.031f,2.35357f,-105.469f, +210.938f,2.28627f,-105.469f, +214.844f,1.61561f,-105.469f, +218.75f,2.61087f,-105.469f, +222.656f,2.34638f,-105.469f, +226.563f,1.47074f,-105.469f, +230.469f,0.63025f,-105.469f, +234.375f,0.847991f,-105.469f, +238.281f,1.35199f,-105.469f, +242.188f,2.21032f,-105.469f, +246.094f,3.01323f,-105.469f, +250.0f,3.12713f,-105.469f, +3.90625f,45.3987f,-109.375f, +7.8125f,44.6273f,-109.375f, +11.7188f,44.5674f,-109.375f, +15.625f,44.2998f,-109.375f, +19.5313f,43.5383f,-109.375f, +23.4375f,42.0306f,-109.375f, +27.3438f,40.7068f,-109.375f, +31.25f,39.6497f,-109.375f, +35.1563f,36.2161f,-109.375f, +39.0625f,34.8769f,-109.375f, +42.9688f,35.1989f,-109.375f, +46.875f,33.9714f,-109.375f, +50.7813f,30.9979f,-109.375f, +54.6875f,31.9366f,-109.375f, +58.5938f,31.5755f,-109.375f, +62.5f,31.572f,-109.375f, +66.4063f,33.0668f,-109.375f, +70.3125f,33.6444f,-109.375f, +74.2188f,32.5467f,-109.375f, +78.125f,34.2686f,-109.375f, +82.0313f,36.0633f,-109.375f, +85.9375f,37.5569f,-109.375f, +89.8438f,38.5599f,-109.375f, +93.75f,38.6708f,-109.375f, +97.6563f,39.2558f,-109.375f, +101.563f,39.9111f,-109.375f, +105.469f,39.9236f,-109.375f, +109.375f,39.5666f,-109.375f, +113.281f,40.1532f,-109.375f, +117.188f,40.8773f,-109.375f, +121.094f,40.133f,-109.375f, +125.0f,38.348f,-109.375f, +128.906f,36.9174f,-109.375f, +132.813f,34.8975f,-109.375f, +136.719f,32.9097f,-109.375f, +140.625f,32.6666f,-109.375f, +144.531f,33.1207f,-109.375f, +148.438f,32.6024f,-109.375f, +152.344f,31.1149f,-109.375f, +156.25f,27.7885f,-109.375f, +160.156f,24.9665f,-109.375f, +164.063f,22.789f,-109.375f, +167.969f,20.4907f,-109.375f, +171.875f,18.2402f,-109.375f, +175.781f,15.9409f,-109.375f, +179.688f,12.7122f,-109.375f, +183.594f,10.9582f,-109.375f, +187.5f,7.47226f,-109.375f, +191.406f,4.87747f,-109.375f, +195.313f,2.78589f,-109.375f, +199.219f,1.53429f,-109.375f, +203.125f,1.61775f,-109.375f, +207.031f,1.772f,-109.375f, +210.938f,1.15444f,-109.375f, +214.844f,0.342505f,-109.375f, +218.75f,0.510183f,-109.375f, +222.656f,0.254977f,-109.375f, +226.563f,-0.22727f,-109.375f, +230.469f,-0.840625f,-109.375f, +234.375f,-0.282154f,-109.375f, +238.281f,0.424945f,-109.375f, +242.188f,1.73577f,-109.375f, +246.094f,1.80217f,-109.375f, +250.0f,1.60105f,-109.375f, +3.90625f,47.4869f,-113.281f, +7.8125f,46.3185f,-113.281f, +11.7188f,46.4911f,-113.281f, +15.625f,45.2506f,-113.281f, +19.5313f,43.7939f,-113.281f, +23.4375f,42.6062f,-113.281f, +27.3438f,41.6674f,-113.281f, +31.25f,39.5196f,-113.281f, +35.1563f,36.6784f,-113.281f, +39.0625f,35.8546f,-113.281f, +42.9688f,35.2647f,-113.281f, +46.875f,33.0882f,-113.281f, +50.7813f,31.1331f,-113.281f, +54.6875f,31.9095f,-113.281f, +58.5938f,31.5715f,-113.281f, +62.5f,32.3642f,-113.281f, +66.4063f,33.2578f,-113.281f, +70.3125f,33.1847f,-113.281f, +74.2188f,33.6624f,-113.281f, +78.125f,35.6582f,-113.281f, +82.0313f,36.7989f,-113.281f, +85.9375f,37.9951f,-113.281f, +89.8438f,38.7063f,-113.281f, +93.75f,39.9727f,-113.281f, +97.6563f,39.641f,-113.281f, +101.563f,40.1318f,-113.281f, +105.469f,40.117f,-113.281f, +109.375f,40.0678f,-113.281f, +113.281f,40.1534f,-113.281f, +117.188f,40.7841f,-113.281f, +121.094f,39.3312f,-113.281f, +125.0f,38.1823f,-113.281f, +128.906f,37.0921f,-113.281f, +132.813f,34.9687f,-113.281f, +136.719f,32.6631f,-113.281f, +140.625f,30.9601f,-113.281f, +144.531f,31.0644f,-113.281f, +148.438f,29.6495f,-113.281f, +152.344f,27.5095f,-113.281f, +156.25f,24.9361f,-113.281f, +160.156f,22.6206f,-113.281f, +164.063f,20.1136f,-113.281f, +167.969f,17.9862f,-113.281f, +171.875f,16.1252f,-113.281f, +175.781f,14.2991f,-113.281f, +179.688f,11.4262f,-113.281f, +183.594f,8.55749f,-113.281f, +187.5f,6.02067f,-113.281f, +191.406f,3.1883f,-113.281f, +195.313f,1.54808f,-113.281f, +199.219f,0.0223479f,-113.281f, +203.125f,-0.0807506f,-113.281f, +207.031f,-0.420855f,-113.281f, +210.938f,-0.531322f,-113.281f, +214.844f,-1.34393f,-113.281f, +218.75f,-2.28346f,-113.281f, +222.656f,-2.245f,-113.281f, +226.563f,-2.22932f,-113.281f, +230.469f,-1.47268f,-113.281f, +234.375f,-0.543695f,-113.281f, +238.281f,-0.391948f,-113.281f, +242.188f,-0.270077f,-113.281f, +246.094f,-0.650629f,-113.281f, +250.0f,0.111517f,-113.281f, +3.90625f,48.3887f,-117.188f, +7.8125f,48.004f,-117.188f, +11.7188f,46.8723f,-117.188f, +15.625f,45.5005f,-117.188f, +19.5313f,43.3644f,-117.188f, +23.4375f,42.3352f,-117.188f, +27.3438f,41.1562f,-117.188f, +31.25f,39.1736f,-117.188f, +35.1563f,38.0627f,-117.188f, +39.0625f,36.4728f,-117.188f, +42.9688f,34.8001f,-117.188f, +46.875f,32.5103f,-117.188f, +50.7813f,31.6328f,-117.188f, +54.6875f,31.6106f,-117.188f, +58.5938f,32.3004f,-117.188f, +62.5f,32.696f,-117.188f, +66.4063f,33.3795f,-117.188f, +70.3125f,33.9696f,-117.188f, +74.2188f,34.9211f,-117.188f, +78.125f,36.7686f,-117.188f, +82.0313f,37.7676f,-117.188f, +85.9375f,37.8174f,-117.188f, +89.8438f,38.2878f,-117.188f, +93.75f,39.6151f,-117.188f, +97.6563f,39.7422f,-117.188f, +101.563f,40.9611f,-117.188f, +105.469f,40.8932f,-117.188f, +109.375f,40.6603f,-117.188f, +113.281f,40.2935f,-117.188f, +117.188f,39.8681f,-117.188f, +121.094f,39.0965f,-117.188f, +125.0f,37.1333f,-117.188f, +128.906f,35.5222f,-117.188f, +132.813f,33.9068f,-117.188f, +136.719f,32.2618f,-117.188f, +140.625f,29.8657f,-117.188f, +144.531f,28.1704f,-117.188f, +148.438f,27.1495f,-117.188f, +152.344f,24.5217f,-117.188f, +156.25f,22.0419f,-117.188f, +160.156f,19.9238f,-117.188f, +164.063f,17.6875f,-117.188f, +167.969f,15.5636f,-117.188f, +171.875f,13.5497f,-117.188f, +175.781f,11.2761f,-117.188f, +179.688f,8.95864f,-117.188f, +183.594f,7.04623f,-117.188f, +187.5f,4.83635f,-117.188f, +191.406f,2.76046f,-117.188f, +195.313f,0.190119f,-117.188f, +199.219f,-0.558379f,-117.188f, +203.125f,-1.03303f,-117.188f, +207.031f,-2.17563f,-117.188f, +210.938f,-1.91155f,-117.188f, +214.844f,-3.00018f,-117.188f, +218.75f,-4.26691f,-117.188f, +222.656f,-5.15855f,-117.188f, +226.563f,-3.46348f,-117.188f, +230.469f,-2.16077f,-117.188f, +234.375f,-1.47785f,-117.188f, +238.281f,-1.78424f,-117.188f, +242.188f,-1.00317f,-117.188f, +246.094f,-1.97981f,-117.188f, +250.0f,-2.29372f,-117.188f, +}; + +btScalar Landscape03Nml[] = { +-0.0301669f,0.913898f,-0.404822f, +0.0925944f,0.901922f,-0.421856f, +0.0550338f,0.955133f,-0.291019f, +0.163554f,0.924847f,-0.343379f, +-0.00160556f,0.985516f,-0.169577f, +0.0975687f,0.967908f,-0.23159f, +-0.0718641f,0.997324f,-0.0134097f, +0.108884f,0.992259f,0.0597208f, +-0.0649193f,0.987727f,0.142057f, +-0.0923076f,0.995503f,-0.0212622f, +-0.212176f,0.966905f,0.141687f, +-0.135924f,0.982555f,0.126925f, +-0.248136f,0.950917f,0.184892f, +-0.114969f,0.937595f,0.328173f, +-0.0596382f,0.954355f,0.292661f, +-0.0673134f,0.931098f,0.358506f, +-0.100514f,0.963905f,0.246544f, +-0.237357f,0.960335f,0.146353f, +-0.210275f,0.964506f,0.159726f, +-0.243879f,0.969407f,-0.027797f, +-0.0995316f,0.963559f,0.248291f, +0.0232774f,0.986211f,0.163848f, +-0.0780955f,0.939808f,0.33266f, +0.0143543f,0.937354f,0.348083f, +-0.242603f,0.911487f,0.332166f, +-0.217791f,0.899583f,0.378572f, +-0.259297f,0.919695f,0.294833f, +-0.235372f,0.900382f,0.365939f, +0.0548314f,0.924698f,0.376733f, +0.17577f,0.83537f,0.520828f, +0.183628f,0.8685f,0.460423f, +0.206319f,0.791195f,0.57571f, +0.291585f,0.831097f,0.473557f, +0.258977f,0.806104f,0.532097f, +0.406441f,0.807616f,0.427274f, +0.279416f,0.89888f,0.337552f, +0.161449f,0.944511f,0.286064f, +-0.0153595f,0.999467f,0.0288015f, +0.0344442f,0.986316f,0.16123f, +0.0228147f,0.999694f,-0.00950936f, +0.221267f,0.961345f,0.163882f, +0.262982f,0.961437f,0.0804904f, +0.292545f,0.943495f,0.155677f, +0.287728f,0.952627f,0.0985627f, +0.338791f,0.935036f,0.104535f, +0.332042f,0.939101f,0.0885263f, +0.395865f,0.914692f,0.0814219f, +0.342439f,0.937891f,0.0556409f, +0.24643f,0.967531f,-0.0561722f, +0.155524f,0.980084f,-0.12348f, +0.12756f,0.989194f,-0.0722747f, +0.141529f,0.984734f,-0.10133f, +0.0842668f,0.99539f,-0.0458028f, +0.00840046f,0.967846f,-0.251403f, +0.0723924f,0.995277f,-0.0646756f, +0.161395f,0.974624f,-0.155111f, +0.168526f,0.983485f,0.0660013f, +0.32936f,0.929371f,0.166709f, +0.334018f,0.924548f,0.18342f, +0.39263f,0.883836f,0.254313f, +0.373683f,0.906029f,0.198675f, +0.318503f,0.931732f,0.174444f, +0.214891f,0.969497f,0.117891f, +0.248914f,0.936934f,0.245348f, +0.199074f,0.96113f,0.19131f, +0.293417f,0.893252f,0.340597f, +0.339667f,0.873015f,0.349959f, +0.354613f,0.873548f,0.333412f, +0.457963f,0.824157f,0.333219f, +0.455319f,0.825254f,0.334127f, +0.52695f,0.805593f,0.270821f, +0.439193f,0.858556f,0.264557f, +0.401282f,0.908751f,0.114652f, +0.249111f,0.965853f,-0.0712114f, +0.0897089f,0.991664f,0.0924929f, +0.0376765f,0.979393f,-0.19842f, +-0.126991f,0.990951f,0.0434627f, +-0.217753f,0.933113f,-0.286154f, +-0.167574f,0.97576f,-0.140749f, +-0.203937f,0.914317f,-0.349907f, +-0.0608955f,0.980207f,-0.188379f, +-0.0120075f,0.947447f,-0.319686f, +0.167601f,0.980952f,-0.0982003f, +0.212052f,0.945824f,-0.245868f, +0.218606f,0.972968f,-0.0744646f, +0.212851f,0.953898f,-0.211596f, +0.171647f,0.974969f,-0.141323f, +0.199197f,0.967793f,-0.153938f, +0.200412f,0.972091f,-0.121957f, +0.23265f,0.963849f,-0.129883f, +0.296235f,0.953212f,-0.060261f, +0.314311f,0.946698f,-0.0705058f, +0.404868f,0.912189f,-0.0631982f, +0.403087f,0.912504f,-0.0696997f, +0.463227f,0.884095f,-0.0616207f, +0.39479f,0.897802f,-0.195171f, +0.35121f,0.926619f,-0.13427f, +0.220773f,0.898508f,-0.379398f, +0.189824f,0.93595f,-0.296589f, +0.0483901f,0.855509f,-0.515522f, +0.0904515f,0.884685f,-0.457329f, +0.120283f,0.865017f,-0.487112f, +0.203986f,0.900002f,-0.385209f, +0.248454f,0.881227f,-0.402131f, +0.178575f,0.929214f,-0.323532f, +0.0792679f,0.824417f,-0.560404f, +0.115378f,0.950213f,-0.289454f, +0.0725597f,0.807744f,-0.585051f, +0.0327706f,0.953791f,-0.298679f, +0.0099385f,0.78612f,-0.617994f, +0.0403637f,0.952173f,-0.302881f, +0.215114f,0.87002f,-0.443611f, +0.182967f,0.972742f,-0.142465f, +0.292542f,0.923312f,-0.248827f, +0.159782f,0.983577f,-0.0839386f, +0.255356f,0.959339f,-0.120256f, +0.180088f,0.983508f,0.0167535f, +0.210595f,0.975243f,-0.0674566f, +0.305089f,0.951559f,0.0381592f, +0.342154f,0.939613f,0.00764387f, +0.44387f,0.894627f,0.0512048f, +0.377004f,0.921573f,-0.0925792f, +0.197535f,0.978807f,-0.0540106f, +0.128094f,0.953819f,-0.271702f, +0.10228f,0.991256f,-0.0833686f, +0.111348f,0.971755f,-0.208074f, +0.120727f,0.982203f,-0.143886f, +0.131919f,0.971754f,-0.195681f, +-0.118481f,0.971727f,-0.204228f, +-0.131824f,0.977685f,-0.163569f, +-0.0725384f,0.997366f,-0.000133281f, +-0.204047f,0.978951f,0.00446862f, +-0.227431f,0.966677f,0.117515f, +-0.137601f,0.963906f,0.227929f, +-0.242399f,0.965055f,0.0995586f, +-0.153062f,0.97808f,0.141178f, +-0.129415f,0.948353f,0.289617f, +-0.22442f,0.902886f,0.366649f, +-0.173979f,0.92147f,0.34731f, +-0.0318649f,0.93595f,0.350687f, +-0.176397f,0.955508f,0.236408f, +-0.254551f,0.956811f,0.140418f, +-0.0162894f,0.984782f,0.173032f, +0.167302f,0.961803f,0.216667f, +0.267797f,0.948626f,0.168505f, +0.412955f,0.869957f,0.269525f, +0.258065f,0.893814f,0.366742f, +0.124905f,0.932115f,0.339941f, +0.234805f,0.927845f,0.289777f, +0.325979f,0.90761f,0.264542f, +0.401458f,0.890435f,0.214374f, +0.44845f,0.886659f,0.112823f, +0.337292f,0.940965f,0.0286028f, +0.110729f,0.992952f,-0.0422648f, +0.0165495f,0.996512f,-0.0817925f, +0.0843804f,0.994583f,-0.0606957f, +0.1131f,0.990749f,-0.0749933f, +0.241223f,0.970417f,0.0100747f, +0.396578f,0.902933f,0.165644f, +0.324808f,0.936808f,0.129963f, +0.0728626f,0.997053f,0.0240034f, +0.167633f,0.975741f,0.140815f, +0.474631f,0.846984f,0.239465f, +0.567824f,0.786908f,0.24156f, +0.402496f,0.873451f,0.274008f, +0.0459982f,0.950641f,0.306865f, +-0.0582337f,0.962437f,0.265188f, +0.030037f,0.970181f,0.240514f, +-0.0533502f,0.992438f,0.110548f, +0.0995416f,0.988544f,0.11346f, +0.255626f,0.959556f,0.11793f, +0.26735f,0.961569f,0.0625254f, +0.18836f,0.981833f,-0.0228855f, +0.278864f,0.958778f,-0.0545789f, +0.407529f,0.909061f,-0.086769f, +0.427129f,0.902011f,-0.0627458f, +0.408272f,0.912551f,-0.0237565f, +0.36375f,0.922794f,-0.127037f, +0.266363f,0.919721f,-0.28838f, +0.0788795f,0.927162f,-0.366263f, +0.0391177f,0.978258f,-0.20367f, +0.0160429f,0.996725f,-0.0792609f, +0.0608773f,0.998141f,0.00292939f, +0.025245f,0.998361f,-0.0513526f, +0.140845f,0.988959f,-0.046063f, +0.138979f,0.986427f,-0.0874468f, +0.128983f,0.987322f,-0.0925141f, +0.303074f,0.948227f,-0.0949297f, +0.392011f,0.918105f,-0.0584085f, +0.26566f,0.960779f,0.0795528f, +0.166068f,0.98603f,-0.0129125f, +0.262845f,0.962536f,-0.0666132f, +-0.104783f,0.989703f,0.0975085f, +-0.153604f,0.984769f,0.0814646f, +-0.17021f,0.98292f,0.0699758f, +-0.192965f,0.974203f,0.117018f, +-0.286836f,0.952199f,0.105086f, +-0.195248f,0.969752f,0.146488f, +-0.150662f,0.967412f,0.203504f, +-0.264752f,0.950334f,0.163619f, +-0.315905f,0.913283f,0.257134f, +-0.224744f,0.91965f,0.322078f, +-0.108929f,0.947464f,0.300743f, +0.0128823f,0.944776f,0.327463f, +-0.0190359f,0.964202f,0.264485f, +-0.187346f,0.97974f,0.0707926f, +-0.0647113f,0.997854f,-0.0100069f, +0.163923f,0.98566f,0.0400324f, +0.299244f,0.952147f,0.0622031f, +0.300231f,0.948028f,0.105378f, +0.182306f,0.951449f,0.248009f, +0.15023f,0.937487f,0.313924f, +0.264855f,0.926023f,0.268948f, +0.322593f,0.919374f,0.225135f, +0.43093f,0.873406f,0.22685f, +0.536094f,0.828094f,0.163899f, +0.40435f,0.914491f,0.0144028f, +0.203744f,0.975451f,-0.0835749f, +0.102706f,0.983162f,-0.151145f, +0.0912494f,0.98262f,-0.161654f, +0.0714052f,0.991795f,-0.106042f, +0.113839f,0.992199f,-0.0508211f, +0.266818f,0.963676f,0.0116937f, +0.379059f,0.920849f,0.091386f, +0.155245f,0.98775f,0.0158058f, +0.135484f,0.989724f,-0.0457313f, +0.394833f,0.917954f,-0.0383045f, +0.510875f,0.847518f,0.143943f, +0.369724f,0.884704f,0.283906f, +0.16927f,0.926331f,0.336538f, +-0.0368298f,0.974452f,0.221557f, +0.0247064f,0.955492f,0.293981f, +0.0101397f,0.960739f,0.27727f, +0.120365f,0.954563f,0.272621f, +0.285189f,0.933274f,0.218327f, +0.27356f,0.947401f,0.16612f, +0.298803f,0.939862f,0.165455f, +0.344494f,0.938521f,0.0223999f, +0.423232f,0.90602f,-0.00171397f, +0.428479f,0.903517f,-0.00795118f, +0.445837f,0.889867f,-0.0967762f, +0.420806f,0.885752f,-0.195872f, +0.361482f,0.916002f,-0.173987f, +0.0888846f,0.94798f,-0.305668f, +-0.104291f,0.938663f,-0.328687f, +-0.0525896f,0.969771f,-0.238281f, +0.0233793f,0.980465f,-0.1953f, +0.0772242f,0.980658f,-0.179852f, +0.158397f,0.962723f,-0.219259f, +0.207852f,0.94171f,-0.264536f, +0.167471f,0.922973f,-0.346518f, +0.273321f,0.900673f,-0.337764f, +0.244245f,0.947327f,-0.207161f, +0.179974f,0.982676f,-0.0442354f, +0.256056f,0.966655f,0.00369743f, +0.311224f,0.950239f,-0.0136096f, +-0.114346f,0.96184f,0.248574f, +-0.136601f,0.952445f,0.272377f, +-0.118024f,0.9521f,0.282091f, +-0.208962f,0.956737f,0.20246f, +-0.278994f,0.940284f,0.195009f, +-0.257672f,0.939434f,0.225986f, +-0.195307f,0.931658f,0.306381f, +-0.244185f,0.930201f,0.274044f, +-0.297894f,0.926606f,0.229479f, +-0.247712f,0.954952f,0.163421f, +-0.130651f,0.964187f,0.230812f, +-0.0752954f,0.962878f,0.259223f, +0.102408f,0.945859f,0.308f, +-0.0116154f,0.986031f,0.166158f, +0.0110135f,0.994405f,0.105056f, +0.0951503f,0.992756f,0.0733669f, +0.243797f,0.961487f,0.12691f, +0.260872f,0.955085f,0.140567f, +0.0581113f,0.983556f,0.170998f, +0.136043f,0.955475f,0.261839f, +0.341254f,0.920705f,0.189336f, +0.362462f,0.927476f,0.0917096f, +0.434756f,0.897441f,0.0747436f, +0.56712f,0.819757f,0.0798336f, +0.532941f,0.840799f,0.0950342f, +0.285812f,0.957415f,-0.0408404f, +0.105292f,0.985973f,-0.129498f, +0.0183827f,0.988838f,-0.147857f, +0.00614806f,0.993133f,-0.116825f, +0.099955f,0.989102f,-0.108098f, +0.238003f,0.969438f,-0.0595305f, +0.37769f,0.925502f,0.0282058f, +0.22782f,0.973089f,-0.0345812f, +0.169707f,0.981804f,-0.085208f, +0.345833f,0.936168f,-0.0631539f, +0.390375f,0.920563f,0.0130624f, +0.292594f,0.949139f,0.116291f, +0.162356f,0.962761f,0.216174f, +-0.0222207f,0.972687f,0.231055f, +-0.0543181f,0.955402f,0.290271f, +0.0573363f,0.941579f,0.331875f, +0.0971816f,0.964596f,0.245172f, +0.31345f,0.917083f,0.246388f, +0.307384f,0.923753f,0.228463f, +0.331585f,0.921188f,0.203628f, +0.40966f,0.902178f,0.135106f, +0.421265f,0.901117f,0.102585f, +0.477285f,0.878068f,0.0345826f, +0.547818f,0.833857f,-0.0676607f, +0.41388f,0.899953f,-0.13707f, +0.336726f,0.938017f,-0.0820957f, +0.267129f,0.960427f,-0.0788775f, +-0.0301028f,0.966021f,-0.256704f, +-0.102361f,0.925067f,-0.36575f, +-0.0109209f,0.925593f,-0.378364f, +0.0802595f,0.925005f,-0.371381f, +0.178475f,0.901809f,-0.393558f, +0.234643f,0.9031f,-0.359657f, +0.21073f,0.932522f,-0.29325f, +0.145492f,0.962309f,-0.22977f, +0.0986234f,0.992893f,-0.0666048f, +0.0609779f,0.998071f,0.0116837f, +0.208222f,0.976086f,0.0624398f, +0.291247f,0.954621f,0.0622453f, +-0.144182f,0.940028f,0.309126f, +-0.205006f,0.91833f,0.33859f, +-0.12423f,0.88968f,0.43936f, +-0.080186f,0.900963f,0.426423f, +-0.276852f,0.915664f,0.291398f, +-0.294009f,0.912157f,0.285532f, +-0.229314f,0.935643f,0.268306f, +-0.167187f,0.934278f,0.314918f, +-0.22242f,0.937858f,0.266367f, +-0.260643f,0.947201f,0.186748f, +-0.191964f,0.952786f,0.235261f, +-0.0626162f,0.968356f,0.24159f, +0.113658f,0.975135f,0.190246f, +0.0609991f,0.983083f,0.172707f, +0.00661942f,0.987494f,0.157516f, +0.132957f,0.988179f,0.0763221f, +0.229975f,0.973129f,-0.011475f, +0.267568f,0.962445f,0.0458956f, +0.0512446f,0.996521f,0.0657221f, +0.10251f,0.994623f,0.0147167f, +0.405413f,0.913613f,0.0308412f, +0.422693f,0.905322f,0.0415123f, +0.446493f,0.894763f,-0.00665318f, +0.517619f,0.855611f,0.00103599f, +0.493254f,0.857934f,0.143698f, +0.391227f,0.901201f,0.186488f, +0.212519f,0.97466f,0.0698119f, +0.0889638f,0.99521f,-0.0405254f, +0.0684633f,0.989971f,-0.123576f, +0.0764325f,0.983592f,-0.163418f, +0.104882f,0.990961f,-0.0836475f, +0.31755f,0.948184f,0.0104726f, +0.297752f,0.954642f,-0.00148102f, +0.157954f,0.986909f,-0.0325777f, +0.331713f,0.943333f,0.00940707f, +0.320973f,0.946975f,0.014661f, +0.220471f,0.961455f,0.164306f, +0.0647366f,0.977455f,0.200976f, +-0.0349474f,0.961311f,0.273238f, +-0.125874f,0.956852f,0.261896f, +0.0785055f,0.963364f,0.256449f, +0.211427f,0.962249f,0.171395f, +0.267083f,0.952021f,0.149409f, +0.340455f,0.905998f,0.251512f, +0.343062f,0.921876f,0.180149f, +0.420249f,0.886024f,0.195835f, +0.477229f,0.85754f,0.192034f, +0.564804f,0.822942f,0.0613434f, +0.583206f,0.811559f,-0.0352364f, +0.433319f,0.897576f,-0.0811897f, +0.291913f,0.950865f,-0.103166f, +0.268144f,0.961121f,-0.065914f, +0.14681f,0.986926f,-0.0665068f, +0.0393351f,0.975019f,-0.218612f, +0.042722f,0.945279f,-0.323454f, +0.104892f,0.926937f,-0.360257f, +0.188153f,0.928382f,-0.320477f, +0.104479f,0.956869f,-0.271082f, +0.039684f,0.98773f,-0.151046f, +0.0798596f,0.996734f,-0.0120106f, +0.0027229f,0.999081f,-0.0427778f, +0.0156228f,0.999853f,-0.00700924f, +0.224664f,0.97266f,0.058815f, +0.342188f,0.939164f,0.029646f, +-0.199093f,0.881081f,0.429019f, +-0.240385f,0.861587f,0.447083f, +-0.200309f,0.881599f,0.427386f, +-0.0492643f,0.888913f,0.455419f, +-0.146605f,0.886582f,0.438724f, +-0.194932f,0.91844f,0.344193f, +-0.212452f,0.949737f,0.229922f, +-0.231229f,0.946978f,0.223083f, +-0.22018f,0.943947f,0.245937f, +-0.155384f,0.954263f,0.255419f, +-0.222552f,0.970336f,0.0944332f, +0.0103498f,0.996133f,0.0872447f, +0.133012f,0.991064f,-0.00997971f, +0.0530236f,0.995787f,0.0748093f, +0.0840279f,0.994917f,0.0554967f, +0.25995f,0.964887f,-0.0376792f, +0.277109f,0.958722f,-0.0637373f, +0.172083f,0.982525f,-0.0709421f, +0.0951551f,0.994032f,-0.0533466f, +0.177084f,0.970483f,-0.163718f, +0.336303f,0.91861f,-0.207499f, +0.381503f,0.916211f,-0.122527f, +0.437128f,0.898759f,-0.0339342f, +0.471093f,0.8784f,0.0805223f, +0.407138f,0.905658f,0.118413f, +0.402844f,0.901612f,0.157519f, +0.327464f,0.936685f,0.124046f, +0.19809f,0.980129f,0.0103207f, +0.123868f,0.987803f,-0.0943524f, +0.0527864f,0.989238f,-0.136459f, +0.072462f,0.988213f,-0.134849f, +0.248671f,0.959688f,-0.131005f, +0.280617f,0.958078f,0.0577984f, +0.169552f,0.981657f,0.0871871f, +0.315169f,0.946806f,0.0650122f, +0.205308f,0.973708f,0.0986977f, +0.0950386f,0.972165f,0.214158f, +0.053629f,0.964124f,0.259978f, +-0.0859535f,0.951705f,0.294738f, +-0.0564482f,0.948883f,0.31054f, +0.154105f,0.958817f,0.238582f, +0.276457f,0.946116f,0.168629f, +0.211552f,0.972531f,0.0971047f, +0.294402f,0.951062f,0.0938527f, +0.390766f,0.916003f,0.0907783f, +0.406836f,0.907458f,0.104904f, +0.487803f,0.868421f,0.0888414f, +0.60401f,0.790886f,0.0983406f, +0.637938f,0.762279f,0.109387f, +0.4874f,0.873178f,0.00117935f, +0.336067f,0.93258f,-0.131735f, +0.229766f,0.943375f,-0.239272f, +0.152224f,0.966237f,-0.207882f, +0.121199f,0.969969f,-0.210883f, +0.121425f,0.965511f,-0.230314f, +0.0800447f,0.963578f,-0.255166f, +0.0996944f,0.981315f,-0.164563f, +0.0506382f,0.996401f,-0.0679735f, +-0.049503f,0.998346f,-0.0292297f, +0.050214f,0.998168f,0.0337586f, +0.113307f,0.993459f,0.014176f, +-0.000723347f,0.991208f,-0.132313f, +0.134265f,0.980729f,-0.141929f, +0.363008f,0.931437f,-0.0254801f, +-0.23486f,0.827656f,0.509732f, +-0.18483f,0.851106f,0.491383f, +-0.113579f,0.917253f,0.381767f, +-0.0885467f,0.926234f,0.366401f, +-0.119506f,0.895756f,0.428181f, +-0.107176f,0.917761f,0.382398f, +-0.0925542f,0.950614f,0.296253f, +-0.166069f,0.978511f,0.12222f, +-0.250375f,0.968134f,-0.00545859f, +-0.116612f,0.99254f,0.0355817f, +-0.0441586f,0.99869f,-0.0258397f, +0.0237183f,0.990591f,-0.134786f, +0.114156f,0.992737f,-0.0379611f, +0.0216237f,0.999568f,0.0199155f, +0.13918f,0.98521f,-0.0999564f, +0.240654f,0.960885f,-0.137059f, +0.249305f,0.964708f,-0.0847689f, +0.222546f,0.966381f,-0.128771f, +0.148234f,0.971026f,-0.187443f, +0.258813f,0.946284f,-0.193812f, +0.386195f,0.898799f,-0.207397f, +0.325896f,0.902531f,-0.281478f, +0.250321f,0.93543f,-0.249621f, +0.351402f,0.936022f,0.01949f, +0.42413f,0.889134f,0.171914f, +0.422963f,0.898638f,0.116411f, +0.393976f,0.918547f,0.0324739f, +0.283361f,0.957155f,-0.0596804f, +0.186222f,0.979389f,-0.0782236f, +0.100294f,0.99243f,-0.0708823f, +0.151138f,0.983442f,-0.0999959f, +0.115742f,0.982035f,-0.149033f, +0.0920961f,0.993962f,0.0596489f, +0.180728f,0.97583f,0.122852f, +0.267575f,0.959234f,0.0909572f, +0.204025f,0.959594f,0.193785f, +0.0830398f,0.98516f,0.150214f, +0.000808908f,0.987078f,0.160239f, +-0.115905f,0.961815f,0.247948f, +-0.0397732f,0.972025f,0.231484f, +0.185186f,0.964166f,0.189976f, +0.333936f,0.928543f,0.162155f, +0.358439f,0.932281f,0.0487095f, +0.30639f,0.946624f,-0.100142f, +0.389119f,0.921183f,-0.00273847f, +0.418957f,0.907889f,-0.0145855f, +0.498018f,0.86538f,-0.05563f, +0.565975f,0.823958f,-0.0276542f, +0.61235f,0.789736f,0.0366549f, +0.580326f,0.809292f,0.0909313f, +0.472624f,0.880866f,0.0264734f, +0.31167f,0.948991f,-0.0477351f, +0.149242f,0.981946f,-0.116226f, +0.114121f,0.974963f,-0.190851f, +0.0836789f,0.981905f,-0.169884f, +0.0779767f,0.990421f,-0.113957f, +0.0144442f,0.982901f,-0.183565f, +-0.021091f,0.988398f,-0.150415f, +-0.0454971f,0.990828f,-0.127242f, +-0.0180398f,0.984723f,-0.173189f, +0.129331f,0.988095f,-0.0833159f, +0.183553f,0.978578f,-0.0932403f, +0.123107f,0.958699f,-0.256402f, +0.189949f,0.953063f,-0.235775f, +-0.0544616f,0.84489f,0.53216f, +-0.0113297f,0.890886f,0.454085f, +-0.0462225f,0.938549f,0.342038f, +-0.128436f,0.915911f,0.380277f, +-0.159132f,0.90887f,0.385529f, +-0.0486608f,0.932565f,0.357708f, +0.0612592f,0.9505f,0.304627f, +0.0533898f,0.988914f,0.138559f, +-0.104607f,0.992177f,-0.0681298f, +-0.180998f,0.963403f,-0.197725f, +0.0184775f,0.993878f,-0.108929f, +-0.0166014f,0.988229f,-0.152078f, +-0.0077365f,0.996975f,-0.0773314f, +0.0579939f,0.995726f,-0.071872f, +0.284878f,0.950639f,-0.123003f, +0.233331f,0.946766f,-0.221789f, +0.274724f,0.943287f,-0.186374f, +0.284827f,0.926731f,-0.245036f, +0.143673f,0.947988f,-0.284037f, +0.183874f,0.951741f,-0.245725f, +0.373811f,0.924384f,-0.0760214f, +0.370847f,0.928183f,0.0307872f, +0.230777f,0.972874f,0.0160428f, +0.116854f,0.992434f,-0.0376857f, +0.311514f,0.945104f,0.0986779f, +0.493623f,0.85792f,0.14251f, +0.47336f,0.879733f,0.0447334f, +0.299829f,0.953139f,0.0403417f, +0.142324f,0.985386f,0.0935816f, +0.0780161f,0.991843f,0.100799f, +0.120483f,0.987279f,0.10375f, +0.113666f,0.977351f,0.178507f, +0.020827f,0.987302f,0.157484f, +0.18308f,0.973453f,0.137371f, +0.268344f,0.949436f,0.162981f, +0.178652f,0.97403f,0.139099f, +0.140521f,0.985536f,0.0947243f, +-0.0588959f,0.995353f,0.0761881f, +-0.17043f,0.974748f,0.144293f, +0.0194468f,0.992819f,0.118038f, +0.23167f,0.972512f,0.0234243f, +0.390625f,0.920274f,-0.0225152f, +0.45457f,0.886543f,-0.086066f, +0.307368f,0.941264f,-0.13981f, +0.289942f,0.953608f,-0.0810322f, +0.455218f,0.890309f,-0.0112281f, +0.513837f,0.856124f,-0.0549855f, +0.546925f,0.836241f,-0.0396788f, +0.583367f,0.812208f,-0.00110721f, +0.552934f,0.832422f,0.0365798f, +0.448406f,0.891004f,0.0710176f, +0.325547f,0.934833f,0.141795f, +0.239603f,0.963586f,0.118709f, +0.230453f,0.97295f,0.0160981f, +0.0486317f,0.9909f,-0.125509f, +0.0743177f,0.991871f,-0.103291f, +0.139517f,0.9837f,-0.11344f, +-0.0210587f,0.976395f,-0.214963f, +0.00854959f,0.97326f,-0.229548f, +0.0184659f,0.95097f,-0.308733f, +0.0120962f,0.95636f,-0.291939f, +0.153044f,0.979201f,-0.1332f, +0.190748f,0.981634f,-0.00308124f, +0.151842f,0.988041f,0.0268087f, +0.0319983f,0.964154f,0.263409f, +0.0761375f,0.979983f,0.183946f, +-0.0471561f,0.98918f,0.13892f, +-0.184804f,0.965808f,0.181831f, +-0.118202f,0.977652f,0.173852f, +-0.00263192f,0.986244f,0.165277f, +0.113935f,0.977488f,0.177586f, +0.213178f,0.965311f,0.150764f, +0.0917926f,0.995582f,-0.0197448f, +-0.112968f,0.973922f,-0.196759f, +-0.0750323f,0.977001f,-0.199598f, +0.0257774f,0.985322f,-0.168747f, +0.042721f,0.964979f,-0.258825f, +0.0821835f,0.934135f,-0.34733f, +0.254423f,0.923351f,-0.287563f, +0.255965f,0.951062f,-0.173101f, +0.240055f,0.959513f,-0.147338f, +0.319995f,0.939284f,-0.123892f, +0.15271f,0.974885f,-0.162111f, +0.132954f,0.978157f,-0.159787f, +0.156062f,0.978958f,-0.131476f, +0.237325f,0.969005f,0.0685979f, +0.280555f,0.951122f,0.129056f, +0.254605f,0.966124f,0.0421956f, +0.282663f,0.955227f,-0.087427f, +0.484968f,0.871846f,-0.0684877f, +0.483506f,0.87515f,-0.0182894f, +0.210764f,0.97671f,0.0402119f, +0.0804806f,0.985666f,0.148275f, +0.143859f,0.967897f,0.206108f, +0.0874346f,0.987357f,0.132215f, +0.0878227f,0.985433f,0.145635f, +0.118466f,0.990277f,0.0729134f, +0.170426f,0.983396f,-0.0623508f, +0.249461f,0.967984f,-0.0278496f, +0.240586f,0.970589f,0.00866192f, +0.158755f,0.987312f,0.00339798f, +-0.0496588f,0.997869f,0.0423253f, +-0.174436f,0.984473f,-0.0196346f, +0.0953847f,0.991998f,-0.0827112f, +0.301757f,0.941321f,-0.151184f, +0.416386f,0.897492f,-0.145363f, +0.439988f,0.889223f,-0.125274f, +0.313047f,0.948071f,-0.0562344f, +0.243151f,0.96888f,-0.0463665f, +0.428373f,0.903467f,-0.0156432f, +0.536849f,0.842847f,-0.0374461f, +0.521753f,0.850621f,-0.0649361f, +0.537565f,0.842885f,-0.02384f, +0.530522f,0.843125f,0.087673f, +0.408082f,0.90082f,0.148295f, +0.350282f,0.920762f,0.171756f, +0.275878f,0.960222f,0.0431791f, +0.279727f,0.959242f,0.0400889f, +0.199403f,0.977085f,0.0744484f, +0.0837631f,0.994427f,-0.0640234f, +0.142714f,0.98022f,-0.137117f, +0.0724844f,0.974795f,-0.211f, +0.0199047f,0.956284f,-0.29176f, +0.0419923f,0.973015f,-0.226887f, +-0.0571486f,0.988577f,-0.139464f, +-0.0620153f,0.996095f,-0.0628396f, +0.00941635f,0.995205f,0.097359f, +0.0452536f,0.980521f,0.191132f, +0.238692f,0.970551f,0.032497f, +0.18188f,0.979621f,-0.0852148f, +-0.0338772f,0.991689f,-0.124115f, +-0.215207f,0.972977f,-0.0836781f, +-0.127875f,0.990711f,-0.0462653f, +-0.0382254f,0.999079f,-0.0194842f, +0.0717625f,0.997386f,-0.00848587f, +0.235337f,0.971913f,0.00129577f, +0.258073f,0.965901f,-0.0208375f, +0.00563659f,0.988134f,-0.153488f, +-0.0963466f,0.971245f,-0.217715f, +0.0933449f,0.976181f,-0.19585f, +0.172697f,0.943118f,-0.284084f, +0.114064f,0.91464f,-0.387844f, +0.105309f,0.920749f,-0.375675f, +0.0952503f,0.976152f,-0.195075f, +0.198665f,0.977736f,-0.0675672f, +0.327274f,0.944589f,-0.0253815f, +0.185125f,0.982311f,-0.0281882f, +0.161734f,0.983206f,-0.0845435f, +0.135269f,0.981463f,-0.135765f, +0.160555f,0.98307f,-0.0882893f, +0.258909f,0.96483f,-0.0454967f, +0.342126f,0.938267f,0.0510447f, +0.36458f,0.930989f,-0.0184394f, +0.461971f,0.885156f,-0.0555142f, +0.401049f,0.915892f,-0.0173601f, +0.179695f,0.981649f,0.0638365f, +-0.0160491f,0.998918f,0.0436388f, +0.112643f,0.989219f,0.093583f, +0.158223f,0.986353f,0.0455405f, +0.150051f,0.988439f,-0.0217303f, +0.238384f,0.964999f,-0.10932f, +0.283357f,0.938433f,-0.197616f, +0.1814f,0.953903f,-0.239086f, +0.147672f,0.981223f,-0.124073f, +0.0988803f,0.99502f,-0.0125399f, +-0.0367309f,0.999167f,-0.0177995f, +-0.0641669f,0.988893f,-0.134067f, +0.155868f,0.964972f,-0.211032f, +0.311449f,0.929937f,-0.195488f, +0.363438f,0.913854f,-0.181064f, +0.379108f,0.919625f,-0.102794f, +0.251516f,0.967833f,-0.00624272f, +0.239964f,0.970767f,0.0053561f, +0.444229f,0.895407f,-0.0301255f, +0.561208f,0.823627f,-0.0817525f, +0.529532f,0.843694f,-0.0881851f, +0.463417f,0.885698f,-0.0280076f, +0.42264f,0.895689f,0.138263f, +0.360725f,0.902736f,0.234403f, +0.374064f,0.893088f,0.249939f, +0.398158f,0.891769f,0.214982f, +0.241834f,0.965676f,0.0947983f, +0.124224f,0.988267f,0.0888664f, +0.239364f,0.964398f,0.112437f, +0.252174f,0.966402f,-0.0497516f, +0.205848f,0.974166f,-0.0928869f, +0.0402048f,0.980488f,-0.192421f, +-0.109787f,0.981783f,-0.155076f, +-0.172809f,0.983136f,-0.0598348f, +-0.119927f,0.992756f,0.00723519f, +-0.0378691f,0.997707f,0.0560999f, +-0.018583f,0.999146f,0.0369096f, +0.311296f,0.946614f,-0.0837655f, +0.23235f,0.967065f,-0.103921f, +-0.0472012f,0.997512f,-0.0523709f, +-0.280913f,0.95942f,-0.0245033f, +-0.168558f,0.985462f,0.0212842f, +-0.0297654f,0.999551f,-0.00345095f, +0.14783f,0.984722f,-0.0920209f, +0.234818f,0.942556f,-0.23759f, +0.226f,0.954601f,-0.194065f, +0.0915505f,0.991576f,-0.0916283f, +-0.0384295f,0.986109f,-0.161594f, +0.0699749f,0.969463f,-0.235043f, +0.242042f,0.947128f,-0.210628f, +0.200696f,0.954776f,-0.21937f, +0.0684629f,0.960296f,-0.270452f, +-0.0178037f,0.955193f,-0.295449f, +0.106419f,0.956511f,-0.271592f, +0.250177f,0.956337f,-0.151101f, +0.206468f,0.977841f,-0.0346042f, +0.226301f,0.972897f,-0.047521f, +0.19172f,0.975927f,-0.103973f, +0.110286f,0.969903f,-0.217085f, +0.124805f,0.979571f,-0.157684f, +0.230362f,0.972377f,0.0376307f, +0.390327f,0.9143f,0.108165f, +0.486088f,0.869528f,0.0874049f, +0.355552f,0.931184f,0.0804947f, +0.162837f,0.968115f,0.190362f, +0.0587916f,0.990094f,0.127507f, +0.122084f,0.99234f,0.0189101f, +0.227899f,0.973107f,0.0335246f, +0.245712f,0.968327f,-0.0443735f, +0.235392f,0.962107f,-0.137626f, +0.299512f,0.953154f,0.0423112f, +0.158421f,0.985528f,0.0603087f, +0.0139537f,0.99778f,0.0651181f, +0.05695f,0.991196f,0.119526f, +0.0853993f,0.993434f,0.0761332f, +0.0800124f,0.992698f,-0.0902652f, +0.152744f,0.965412f,-0.211303f, +0.298303f,0.938225f,-0.175354f, +0.346617f,0.918158f,-0.191946f, +0.306791f,0.939305f,-0.153575f, +0.213668f,0.966817f,-0.140039f, +0.269123f,0.94608f,-0.180294f, +0.462084f,0.866259f,-0.189928f, +0.547323f,0.828917f,-0.11547f, +0.492713f,0.870051f,0.0156307f, +0.377637f,0.925543f,0.0275792f, +0.309374f,0.94993f,0.0438272f, +0.339128f,0.933648f,0.115296f, +0.355844f,0.92275f,0.148012f, +0.387104f,0.898496f,0.207015f, +0.394935f,0.895155f,0.206698f, +0.187014f,0.981688f,0.0362499f, +0.286474f,0.957988f,0.0138101f, +0.315633f,0.944806f,-0.0878444f, +0.189054f,0.976628f,-0.102261f, +0.071001f,0.995263f,-0.066411f, +-0.121993f,0.990638f,-0.0612738f, +-0.195423f,0.978588f,-0.0646113f, +-0.134933f,0.988908f,-0.0620808f, +-0.0362027f,0.9885f,-0.146822f, +0.0247852f,0.975168f,-0.220074f, +0.236634f,0.970435f,-0.0475491f, +0.163622f,0.985347f,0.0481553f, +-0.110204f,0.98299f,0.146921f, +-0.274076f,0.953125f,0.128197f, +-0.127913f,0.990913f,0.0415925f, +0.0693505f,0.994264f,-0.081428f, +0.246728f,0.957329f,-0.15049f, +0.356012f,0.927656f,-0.112735f, +0.108926f,0.979602f,-0.168863f, +-0.0117435f,0.995074f,-0.0984399f, +0.0591802f,0.992813f,-0.104017f, +0.152983f,0.961405f,-0.228683f, +0.199436f,0.939216f,-0.279462f, +0.158919f,0.956661f,-0.244017f, +0.142246f,0.964436f,-0.222776f, +0.0928224f,0.948092f,-0.304146f, +0.072096f,0.927878f,-0.365849f, +0.0949024f,0.954182f,-0.28378f, +0.0839904f,0.981792f,-0.17038f, +0.207123f,0.975655f,-0.0720922f, +0.306863f,0.948734f,-0.075756f, +0.227677f,0.946857f,-0.22721f, +0.0209281f,0.957849f,-0.28651f, +0.0889558f,0.973432f,-0.210993f, +0.377519f,0.908654f,-0.178401f, +0.444767f,0.867771f,-0.22171f, +0.296477f,0.952876f,-0.0642486f, +0.049587f,0.998699f,0.0118749f, +0.185088f,0.975344f,0.120192f, +0.179316f,0.983776f,0.00553586f, +0.203508f,0.978758f,-0.0248474f, +0.30632f,0.951877f,-0.00993344f, +0.182507f,0.983075f,0.0159703f, +0.0804506f,0.991985f,0.0974322f, +0.170994f,0.963788f,0.204629f, +0.0962731f,0.986887f,0.12956f, +0.097797f,0.995201f,0.00337759f, +0.147003f,0.987459f,-0.0575677f, +0.218112f,0.972969f,-0.0758899f, +0.244949f,0.956598f,-0.157862f, +0.315584f,0.924587f,-0.213415f, +0.352441f,0.893692f,-0.277668f, +0.28482f,0.905458f,-0.31468f, +0.265138f,0.910445f,-0.317477f, +0.308383f,0.884493f,-0.350102f, +0.390084f,0.870652f,-0.299665f, +0.373263f,0.922794f,-0.0955261f, +0.378781f,0.918384f,0.114439f, +0.476669f,0.866105f,0.150494f, +0.353048f,0.93424f,-0.0505168f, +0.309942f,0.946077f,-0.0942048f, +0.298518f,0.948219f,-0.108479f, +0.350416f,0.935917f,-0.0356219f, +0.447907f,0.893892f,-0.0183155f, +0.280155f,0.95286f,-0.116492f, +0.270748f,0.951225f,-0.147871f, +0.374052f,0.922269f,-0.0974917f, +0.176754f,0.980223f,-0.0889943f, +0.0634799f,0.992926f,-0.100339f, +-0.11806f,0.977045f,-0.177329f, +-0.199746f,0.955239f,-0.218219f, +-0.0812223f,0.969857f,-0.229739f, +0.130179f,0.951543f,-0.278602f, +0.200559f,0.919086f,-0.339202f, +0.0174361f,0.999489f,0.0268061f, +0.0105554f,0.991703f,0.128113f, +-0.141198f,0.973013f,0.182506f, +-0.142313f,0.985833f,0.0887713f, +0.00597934f,0.99465f,-0.103131f, +0.213448f,0.959986f,-0.181295f, +0.150446f,0.953754f,-0.260228f, +0.244008f,0.968351f,-0.0525036f, +0.184758f,0.982743f,0.00893989f, +-0.00567918f,0.992902f,-0.118797f, +0.138037f,0.98016f,-0.142241f, +0.21929f,0.962205f,-0.16147f, +0.269703f,0.95408f,-0.13035f, +0.150911f,0.956731f,-0.24878f, +0.180021f,0.944452f,-0.27496f, +0.119147f,0.92214f,-0.368051f, +0.0669033f,0.930661f,-0.359714f, +-0.0113587f,0.942765f,-0.333265f, +0.0142182f,0.972628f,-0.231934f, +0.163413f,0.959027f,-0.231437f, +0.324001f,0.919871f,-0.221046f, +0.291919f,0.93701f,-0.19182f, +0.107512f,0.968299f,-0.225473f, +0.0749887f,0.923898f,-0.375218f, +0.415609f,0.849812f,-0.324172f, +0.314994f,0.92041f,-0.231569f, +0.136459f,0.990645f,0.000905767f, +0.00734966f,0.998995f,0.0442195f, +0.0805668f,0.996634f,0.0151596f, +0.266119f,0.962333f,0.0556322f, +0.269187f,0.962624f,-0.0298845f, +0.209195f,0.975524f,-0.0677535f, +0.153299f,0.985902f,0.0670637f, +0.0587395f,0.996349f,0.0619523f, +0.20348f,0.97612f,0.0760684f, +0.225978f,0.971688f,-0.0689656f, +0.204562f,0.957442f,-0.203617f, +0.164418f,0.955123f,-0.246386f, +0.1725f,0.961839f,-0.212392f, +0.288653f,0.947463f,-0.137816f, +0.355829f,0.918236f,-0.173863f, +0.453757f,0.873536f,-0.176182f, +0.355645f,0.881401f,-0.310884f, +0.238917f,0.864251f,-0.442706f, +0.251593f,0.863453f,-0.437206f, +0.231383f,0.92049f,-0.314896f, +0.219172f,0.968344f,-0.119471f, +0.254773f,0.966196f,-0.0394394f, +0.482542f,0.873342f,0.0665443f, +0.470019f,0.880685f,0.0589576f, +0.359563f,0.932576f,-0.0318683f, +0.336062f,0.937393f,-0.0914179f, +0.320744f,0.932455f,-0.166285f, +0.428106f,0.887361f,-0.171217f, +0.372336f,0.918652f,-0.132074f, +0.247289f,0.941171f,-0.230314f, +0.287477f,0.950239f,-0.120008f, +0.121799f,0.989487f,-0.0779795f, +0.132326f,0.991166f,-0.00888466f, +-0.00459516f,0.997934f,-0.0640824f, +-0.0924696f,0.984613f,-0.148277f, +-0.0479758f,0.968834f,-0.243019f, +0.052427f,0.976364f,-0.209677f, +0.223214f,0.97397f,-0.0394671f, +0.0112214f,0.972418f,0.232975f, +0.0106355f,0.967748f,0.251694f, +-0.0743183f,0.979789f,0.185717f, +0.0581795f,0.9982f,0.01459f, +0.133434f,0.964693f,-0.227076f, +0.215981f,0.948544f,-0.231554f, +0.137408f,0.968029f,-0.209856f, +0.0442022f,0.987042f,-0.154256f, +0.228305f,0.972284f,0.0504f, +0.121617f,0.992241f,-0.0258404f, +0.134527f,0.985242f,-0.105833f, +0.151618f,0.980953f,-0.121423f, +0.275183f,0.956894f,-0.092891f, +0.263324f,0.945384f,-0.192117f, +0.25647f,0.929449f,-0.26523f, +0.21073f,0.904026f,-0.371926f, +0.0728135f,0.89169f,-0.446751f, +-0.0691284f,0.877831f,-0.473955f, +-0.019884f,0.913569f,-0.406197f, +0.178205f,0.891525f,-0.416444f, +0.263993f,0.900279f,-0.34613f, +0.210305f,0.939702f,-0.269689f, +0.208408f,0.948624f,-0.238074f, +0.229275f,0.910156f,-0.345036f, +0.227512f,0.924458f,-0.305966f, +0.142229f,0.989234f,0.0344507f, +-0.0464441f,0.986357f,0.157934f, +0.073391f,0.981122f,0.178921f, +0.158555f,0.984472f,0.0753311f, +0.265489f,0.961878f,0.0656237f, +0.318063f,0.94383f,0.0895592f, +0.229589f,0.973115f,0.0183382f, +0.0918017f,0.995548f,-0.0213497f, +0.0710209f,0.997458f,0.00582691f, +0.234172f,0.971044f,-0.0473045f, +0.373198f,0.918081f,-0.133603f, +0.27855f,0.93462f,-0.221124f, +0.174681f,0.94082f,-0.290421f, +0.0816739f,0.936818f,-0.34015f, +0.233666f,0.948403f,-0.214319f, +0.373882f,0.91082f,-0.174984f, +0.44036f,0.88198f,-0.16791f, +0.496092f,0.86017f,-0.118324f, +0.420226f,0.875748f,-0.237645f, +0.228936f,0.896528f,-0.379243f, +0.0594423f,0.913794f,-0.401806f, +0.0971839f,0.949435f,-0.298544f, +0.201575f,0.953775f,-0.222894f, +0.339139f,0.935667f,-0.0975326f, +0.471026f,0.864094f,0.177416f, +0.409402f,0.896788f,0.167814f, +0.414181f,0.90532f,0.0940739f, +0.426161f,0.903473f,-0.0460849f, +0.431652f,0.886771f,-0.165266f, +0.36903f,0.909898f,-0.189479f, +0.237762f,0.950577f,-0.199683f, +0.250405f,0.963718f,-0.0924377f, +0.100123f,0.989034f,-0.108572f, +0.0410755f,0.997876f,-0.0505615f, +0.0233843f,0.999496f,0.0214792f, +-0.0536722f,0.998467f,-0.0135057f, +0.00107433f,0.999993f,-0.00356525f, +-0.0705196f,0.996911f,-0.0345704f, +-0.0688919f,0.997514f,0.0148223f, +-0.0812179f,0.983535f,0.161436f, +-0.0138011f,0.988231f,0.152344f, +0.0655184f,0.995642f,0.0663652f, +0.220598f,0.973784f,-0.0554998f, +0.309629f,0.942731f,-0.124049f, +0.155774f,0.947975f,-0.27763f, +0.127196f,0.974249f,-0.186174f, +-0.058769f,0.981296f,-0.183314f, +0.0497615f,0.99612f,-0.0725919f, +0.182926f,0.98205f,0.0460018f, +0.19209f,0.981195f,-0.0189005f, +0.224403f,0.972569f,-0.0612647f, +0.315645f,0.941316f,-0.119552f, +0.360736f,0.920207f,-0.151949f, +0.310465f,0.916626f,-0.251809f, +0.327403f,0.899549f,-0.28917f, +0.161725f,0.896729f,-0.411973f, +-0.0141039f,0.865769f,-0.500245f, +-0.0292484f,0.82172f,-0.56914f, +0.0961328f,0.815723f,-0.570398f, +0.101793f,0.868026f,-0.485972f, +0.156302f,0.922247f,-0.353597f, +0.205267f,0.935719f,-0.286871f, +0.229076f,0.948515f,-0.218729f, +0.0347356f,0.987904f,-0.151126f, +-0.079026f,0.996018f,0.0412683f, +-0.00943989f,0.997185f,0.0743796f, +0.111542f,0.993598f,-0.0179121f, +0.186771f,0.982172f,0.0213291f, +0.207496f,0.975443f,0.0738717f, +0.321818f,0.944637f,0.0639911f, +0.281397f,0.958917f,0.0359716f, +0.126766f,0.988281f,0.0850327f, +0.0940702f,0.995531f,0.0082479f, +0.338235f,0.93955f,-0.0533163f, +0.410978f,0.899199f,-0.150126f, +0.338008f,0.912085f,-0.232059f, +0.265939f,0.902685f,-0.338284f, +0.120839f,0.912428f,-0.39099f, +0.0943411f,0.91428f,-0.393944f, +0.326367f,0.911608f,-0.24991f, +0.410002f,0.90171f,-0.137175f, +0.446036f,0.89335f,-0.054576f, +0.453415f,0.890674f,0.0333893f, +0.369882f,0.926554f,0.0684487f, +0.15305f,0.985829f,-0.0686756f, +0.0307343f,0.980172f,-0.195752f, +0.104404f,0.981192f,-0.162361f, +0.153412f,0.984343f,-0.086793f, +0.259868f,0.962798f,0.0740869f, +0.405239f,0.886729f,0.222469f, +0.507863f,0.829218f,0.233395f, +0.530784f,0.842353f,0.0933228f, +0.515092f,0.857118f,0.0053912f, +0.421652f,0.904509f,-0.0638277f, +0.186762f,0.968676f,-0.16367f, +0.141357f,0.986443f,-0.0833539f, +0.10637f,0.994244f,0.0127965f, +-0.010764f,0.999348f,-0.0344492f, +-0.00443345f,0.999867f,-0.0156939f, +-0.0569297f,0.998142f,0.0217125f, +-0.0108274f,0.998516f,0.0533776f, +-0.0518054f,0.997615f,0.0456197f, +-0.08879f,0.991878f,0.0910736f, +0.15627f,0.9777f,0.14029f, +0.127078f,0.991794f,-0.0140045f, +0.182153f,0.975854f,-0.12054f, +0.236919f,0.957374f,-0.165238f, +0.354425f,0.924081f,-0.143031f, +0.22947f,0.95204f,-0.202395f, +0.0414456f,0.986576f,-0.157956f, +-0.0334694f,0.988237f,-0.149222f, +-0.0516418f,0.976013f,-0.2115f, +0.149794f,0.980531f,-0.126967f, +0.232135f,0.958309f,-0.166606f, +0.253821f,0.951991f,-0.171138f, +0.306434f,0.927336f,-0.214818f, +0.397399f,0.902704f,-0.164923f, +0.371523f,0.904625f,-0.208864f, +0.394746f,0.892045f,-0.220071f, +0.272791f,0.90211f,-0.334339f, +0.143123f,0.890975f,-0.430905f, +0.0302622f,0.843122f,-0.53687f, +0.0628652f,0.888185f,-0.455165f, +0.00848379f,0.914478f,-0.404546f, +0.009201f,0.926788f,-0.375473f, +0.0671766f,0.952807f,-0.296052f, +0.132209f,0.974746f,-0.179973f, +-0.0203291f,0.99362f,-0.110936f, +-0.138553f,0.985569f,-0.0972441f, +0.0605753f,0.989699f,-0.129717f, +0.0968295f,0.980926f,-0.168548f, +0.0979519f,0.993956f,-0.0495753f, +0.201443f,0.976928f,-0.0709446f, +0.381986f,0.916436f,-0.119294f, +0.157625f,0.97891f,-0.12996f, +0.10065f,0.993729f,0.0486956f, +0.194299f,0.980695f,-0.0220253f, +0.364962f,0.929379f,-0.0552881f, +0.487949f,0.871552f,-0.0479875f, +0.462417f,0.883871f,-0.0702998f, +0.341292f,0.927621f,-0.151788f, +0.13195f,0.962323f,-0.237746f, +0.0784249f,0.961522f,-0.263298f, +0.155522f,0.961843f,-0.225101f, +0.275269f,0.959916f,-0.0528088f, +0.354301f,0.927858f,0.116403f, +0.359914f,0.906647f,0.22012f, +0.307706f,0.904557f,0.295117f, +0.281691f,0.897787f,0.338569f, +0.169122f,0.964903f,0.200898f, +0.116857f,0.992098f,0.045666f, +0.131422f,0.991068f,-0.0226175f, +0.19688f,0.980005f,-0.0287978f, +0.332698f,0.942383f,-0.0350149f, +0.49437f,0.868541f,-0.0351363f, +0.591151f,0.806162f,-0.0253575f, +0.528595f,0.848271f,-0.0319893f, +0.452945f,0.891538f,3.96151e-005f, +0.269718f,0.962267f,0.0359679f, +0.0172075f,0.99965f,0.0201157f, +0.0836306f,0.98488f,0.151715f, +0.0817519f,0.992549f,0.0903531f, +-0.0289252f,0.999464f,0.015311f, +-0.0977995f,0.99488f,0.0254794f, +-0.0368101f,0.998502f,0.0404932f, +-0.0917396f,0.988968f,0.116306f, +-0.19824f,0.961924f,0.188156f, +0.355147f,0.931267f,-0.0813196f, +0.261709f,0.946669f,-0.187953f, +0.187089f,0.954576f,-0.23191f, +0.281523f,0.925027f,-0.255086f, +0.340665f,0.862289f,-0.374707f, +0.168991f,0.920317f,-0.352786f, +-0.0114217f,0.969014f,-0.246743f, +0.0275027f,0.971061f,-0.237244f, +0.0127748f,0.945787f,-0.324537f, +0.106685f,0.927276f,-0.358857f, +0.242554f,0.910981f,-0.333589f, +0.254201f,0.919334f,-0.300346f, +0.319051f,0.907348f,-0.273727f, +0.384836f,0.892504f,-0.235241f, +0.359386f,0.889916f,-0.280877f, +0.418755f,0.87516f,-0.242361f, +0.378513f,0.873068f,-0.307377f, +0.247447f,0.872868f,-0.420561f, +0.0334574f,0.868028f,-0.495387f, +-0.104393f,0.897693f,-0.428077f, +-0.0466408f,0.949283f,-0.310944f, +0.00907853f,0.960916f,-0.276691f, +0.00868667f,0.966036f,-0.258261f, +0.0845957f,0.976098f,-0.200192f, +-0.0296926f,0.969375f,-0.243785f, +-0.104852f,0.955765f,-0.274807f, +0.0855702f,0.957819f,-0.274336f, +0.0411396f,0.961225f,-0.272681f, +0.0481708f,0.973933f,-0.221661f, +0.28909f,0.93695f,-0.196346f, +0.356766f,0.919532f,-0.164859f, +0.126757f,0.9882f,-0.0859897f, +0.0144124f,0.990867f,-0.134068f, +0.233251f,0.969449f,-0.075909f, +0.354937f,0.93426f,-0.034317f, +0.469402f,0.882971f,-0.00493066f, +0.398385f,0.917184f,-0.00790304f, +0.386606f,0.918227f,0.0859925f, +0.228789f,0.970147f,0.0804364f, +0.115903f,0.993259f,0.0019484f, +0.110471f,0.992802f,-0.0462595f, +0.159257f,0.98723f,-0.00373461f, +0.193831f,0.979844f,0.0483161f, +0.304703f,0.938233f,0.163935f, +0.27363f,0.944953f,0.179417f, +0.268196f,0.936861f,0.224416f, +0.306571f,0.922686f,0.233806f, +0.304362f,0.944561f,0.123164f, +0.226364f,0.97021f,-0.0863264f, +0.198019f,0.963611f,-0.179562f, +0.39862f,0.902547f,-0.162819f, +0.534677f,0.804719f,-0.257967f, +0.537872f,0.788638f,-0.297899f, +0.486148f,0.837034f,-0.251066f, +0.374822f,0.901369f,-0.216893f, +0.171725f,0.976903f,-0.127168f, +-0.0108013f,0.999941f,-0.00151679f, +0.0247265f,0.999687f,-0.00377037f, +0.135958f,0.990654f,0.0109791f, +-0.00717425f,0.999252f,0.0379956f, +-0.0710711f,0.991911f,0.105175f, +-0.0859239f,0.990395f,0.108328f, +-0.18335f,0.97033f,0.157612f, +-0.315275f,0.941315f,0.120535f, +0.340669f,0.883831f,-0.320605f, +0.289176f,0.886429f,-0.361416f, +0.20883f,0.874721f,-0.437325f, +0.364068f,0.812937f,-0.454519f, +0.367133f,0.769647f,-0.522357f, +0.0748495f,0.818621f,-0.569436f, +-0.0872921f,0.835085f,-0.543151f, +0.00846427f,0.872897f,-0.48783f, +0.114223f,0.886407f,-0.448593f, +0.0920189f,0.872463f,-0.479939f, +0.2125f,0.893929f,-0.394633f, +0.175058f,0.869572f,-0.461735f, +0.23988f,0.874417f,-0.421725f, +0.3397f,0.869601f,-0.358326f, +0.392151f,0.874231f,-0.286248f, +0.401032f,0.871377f,-0.282622f, +0.447169f,0.847971f,-0.28458f, +0.337548f,0.868339f,-0.363386f, +0.0674983f,0.896564f,-0.437742f, +-0.167145f,0.867884f,-0.467804f, +-0.130341f,0.888597f,-0.43978f, +-0.0513088f,0.927515f,-0.370248f, +-0.0499693f,0.955154f,-0.291861f, +0.0619562f,0.966501f,-0.249073f, +0.104114f,0.952328f,-0.28676f, +-0.0782617f,0.904542f,-0.419141f, +0.00654125f,0.918336f,-0.395747f, +0.0825819f,0.944757f,-0.317199f, +0.028702f,0.9283f,-0.370722f, +0.170752f,0.927761f,-0.331819f, +0.188742f,0.965638f,-0.178664f, +0.126613f,0.983535f,0.12895f, +0.0677004f,0.989289f,0.129321f, +0.179931f,0.977134f,0.113286f, +0.301628f,0.94869f,0.0949132f, +0.473083f,0.874439f,0.107469f, +0.430087f,0.900068f,0.0700241f, +0.294529f,0.954232f,0.0519033f, +0.218538f,0.963065f,0.157309f, +0.194139f,0.967934f,0.159416f, +0.193754f,0.980213f,0.0405318f, +0.162395f,0.97825f,-0.129057f, +0.175319f,0.968352f,-0.177646f, +0.248014f,0.960103f,-0.129196f, +0.28568f,0.95369f,-0.0941428f, +0.21993f,0.968315f,-0.118312f, +0.322085f,0.944206f,-0.068818f, +0.382868f,0.918715f,-0.0968289f, +0.390317f,0.908769f,-0.147618f, +0.269935f,0.914207f,-0.30226f, +0.374262f,0.856519f,-0.355391f, +0.561588f,0.771614f,-0.298716f, +0.563679f,0.781086f,-0.268646f, +0.435393f,0.841674f,-0.319402f, +0.305805f,0.901875f,-0.305133f, +0.0714141f,0.973517f,-0.217175f, +-0.0655193f,0.984454f,-0.162963f, +0.0352485f,0.985949f,-0.163286f, +0.0657594f,0.9937f,-0.0907542f, +-0.080707f,0.996331f,0.0284757f, +-0.168129f,0.985261f,0.0315202f, +-0.129479f,0.990858f,0.0378905f, +-0.12231f,0.991737f,0.0387141f, +-0.178343f,0.98279f,-0.0481504f, +0.273318f,0.858026f,-0.434843f, +0.385091f,0.836836f,-0.389114f, +0.340339f,0.786413f,-0.515483f, +0.318221f,0.733035f,-0.601161f, +0.367621f,0.755443f,-0.542366f, +0.119455f,0.799665f,-0.588444f, +-0.0802011f,0.78091f,-0.619473f, +-0.0688818f,0.778398f,-0.623981f, +0.0140135f,0.818686f,-0.574071f, +0.0274992f,0.866697f,-0.498077f, +0.177071f,0.88196f,-0.436797f, +0.265217f,0.852958f,-0.449581f, +0.257768f,0.854407f,-0.45116f, +0.248846f,0.837431f,-0.486605f, +0.267639f,0.861569f,-0.431356f, +0.378672f,0.856274f,-0.351288f, +0.453357f,0.836299f,-0.308337f, +0.386424f,0.863215f,-0.324865f, +0.128686f,0.904609f,-0.406352f, +-0.130252f,0.895612f,-0.425338f, +-0.18148f,0.896143f,-0.40496f, +-0.161324f,0.928509f,-0.334435f, +-0.0897102f,0.95467f,-0.283825f, +0.0454642f,0.942898f,-0.329963f, +0.150896f,0.947175f,-0.283f, +0.0358472f,0.960013f,-0.277651f, +-0.0385071f,0.932002f,-0.360402f, +0.0386813f,0.938718f,-0.342507f, +0.0283698f,0.934985f,-0.353551f, +0.108122f,0.956069f,-0.272473f, +0.00374271f,0.987226f,-0.159284f, +-0.196358f,0.979545f,-0.0439957f, +-0.00408304f,0.984849f,0.173364f, +0.19648f,0.945984f,0.257896f, +0.360526f,0.896905f,0.256092f, +0.497904f,0.850304f,0.170515f, +0.432778f,0.894142f,0.114953f, +0.285493f,0.945844f,0.154508f, +0.185631f,0.971794f,0.145459f, +0.230083f,0.969236f,0.0874248f, +0.368311f,0.929659f,-0.00905859f, +0.334163f,0.916764f,-0.218814f, +0.186339f,0.940464f,-0.284262f, +0.166871f,0.945707f,-0.278912f, +0.282007f,0.937612f,-0.20336f, +0.24104f,0.942322f,-0.232226f, +0.269154f,0.937876f,-0.218962f, +0.376707f,0.923358f,-0.0741695f, +0.419282f,0.907855f,0.00132882f, +0.443207f,0.893334f,-0.0743096f, +0.437794f,0.862232f,-0.254741f, +0.526311f,0.818963f,-0.228685f, +0.539618f,0.818293f,-0.198015f, +0.495179f,0.844909f,-0.202303f, +0.231134f,0.928947f,-0.289195f, +-0.0315579f,0.980647f,-0.193222f, +-0.0610949f,0.990009f,-0.12708f, +-0.0213691f,0.991115f,-0.131279f, +-0.0564833f,0.997988f,-0.0288065f, +-0.126885f,0.991868f,-0.0099403f, +-0.0683923f,0.994887f,-0.0743097f, +-0.0443491f,0.981445f,-0.186542f, +-0.106156f,0.962217f,-0.250737f, +-0.0540242f,0.978674f,-0.198191f, +0.194886f,0.824241f,-0.531645f, +0.320074f,0.809438f,-0.492303f, +0.464438f,0.773143f,-0.431911f, +0.405677f,0.746051f,-0.528047f, +0.305674f,0.751501f,-0.584645f, +0.130892f,0.809782f,-0.571944f, +-0.0644176f,0.819769f,-0.56906f, +-0.0714323f,0.833301f,-0.548185f, +-0.0643631f,0.853923f,-0.516404f, +-0.0107306f,0.851684f,-0.523946f, +0.13746f,0.827954f,-0.543688f, +0.198685f,0.868523f,-0.454084f, +0.246871f,0.881894f,-0.401644f, +0.296117f,0.852853f,-0.430066f, +0.256816f,0.850031f,-0.459883f, +0.314177f,0.830121f,-0.460643f, +0.37334f,0.830673f,-0.413038f, +0.413553f,0.857071f,-0.30725f, +0.158679f,0.931259f,-0.327989f, +-0.130088f,0.933779f,-0.333368f, +-0.259668f,0.892475f,-0.368866f, +-0.237565f,0.924215f,-0.298981f, +-0.0871208f,0.968004f,-0.235327f, +0.0797031f,0.982117f,-0.17057f, +0.0461708f,0.99392f,-0.0999594f, +0.0445161f,0.998669f,-0.0260401f, +0.0420509f,0.9919f,-0.119856f, +0.0652827f,0.976809f,-0.203917f, +0.0163117f,0.980129f,-0.197692f, +-0.0727832f,0.991022f,-0.112154f, +-0.0519999f,0.997388f,0.0501216f, +-0.215497f,0.976498f,0.00360735f, +-0.144793f,0.989191f,0.023161f, +0.11495f,0.986032f,0.120527f, +0.332155f,0.934954f,0.124633f, +0.520936f,0.843883f,0.128405f, +0.426058f,0.883139f,0.196317f, +0.297882f,0.930389f,0.213643f, +0.255462f,0.962333f,0.0930293f, +0.330201f,0.94382f,-0.0130553f, +0.464814f,0.88236f,-0.0734001f, +0.396624f,0.912293f,-0.10203f, +0.190826f,0.974675f,-0.116592f, +0.186045f,0.970537f,-0.153119f, +0.228366f,0.951236f,-0.207361f, +0.252282f,0.958154f,-0.135261f, +0.163352f,0.984522f,-0.0635096f, +0.214627f,0.974395f,0.066997f, +0.385854f,0.917468f,0.096793f, +0.519216f,0.853803f,0.0378886f, +0.535665f,0.843867f,-0.0308472f, +0.541689f,0.838373f,-0.060851f, +0.563197f,0.822059f,-0.0838289f, +0.51966f,0.848391f,-0.100928f, +0.236369f,0.967062f,-0.0944536f, +-0.111969f,0.993037f,-0.0366171f, +-0.0968965f,0.995233f,-0.011032f, +-0.0970566f,0.995182f,0.013894f, +-0.0559363f,0.991458f,0.117821f, +-0.00538008f,0.999824f,-0.0179674f, +0.0108998f,0.982438f,-0.186268f, +0.0427996f,0.970253f,-0.238279f, +-0.10823f,0.95386f,-0.280066f, +-0.196538f,0.942983f,-0.26862f, +0.307908f,0.814842f,-0.491147f, +0.299308f,0.78907f,-0.536455f, +0.435133f,0.777699f,-0.453699f, +0.495126f,0.764316f,-0.413124f, +0.362871f,0.81835f,-0.445676f, +0.0803271f,0.871076f,-0.484534f, +-0.110099f,0.885293f,-0.451812f, +-0.149245f,0.895891f,-0.418456f, +-0.0670569f,0.907151f,-0.415428f, +0.0527044f,0.88691f,-0.458926f, +0.100471f,0.888224f,-0.448291f, +0.121208f,0.922825f,-0.365653f, +0.249787f,0.879883f,-0.404243f, +0.334334f,0.839973f,-0.427396f, +0.283757f,0.852792f,-0.438437f, +0.337422f,0.812854f,-0.474778f, +0.291967f,0.807546f,-0.512469f, +0.269633f,0.862064f,-0.429119f, +0.108203f,0.943068f,-0.314506f, +-0.121343f,0.966872f,-0.224575f, +-0.202731f,0.95836f,-0.201115f, +-0.275106f,0.928104f,-0.25088f, +-0.220959f,0.943196f,-0.248108f, +-0.0845259f,0.990859f,-0.105139f, +-0.0183112f,0.999824f,0.00404228f, +0.0398541f,0.999205f,-0.000234289f, +0.144105f,0.989245f,0.0250549f, +0.0887732f,0.994681f,0.052239f, +-0.0385311f,0.993554f,0.106613f, +-0.141743f,0.984863f,0.099766f, +-0.130913f,0.987043f,0.0927824f, +-0.138468f,0.982136f,0.12742f, +-0.181593f,0.983362f,-0.00473479f, +0.124018f,0.991703f,-0.0338209f, +0.350394f,0.929846f,-0.112294f, +0.471172f,0.881999f,-0.00866642f, +0.362692f,0.927143f,0.0941279f, +0.321547f,0.934446f,0.153031f, +0.39706f,0.903274f,0.162601f, +0.408629f,0.910814f,0.0586596f, +0.440544f,0.897708f,-0.00641084f, +0.417743f,0.90832f,0.0210971f, +0.223429f,0.972702f,-0.0626924f, +0.239878f,0.966667f,-0.0895152f, +0.326998f,0.934073f,-0.143454f, +0.0984577f,0.955256f,-0.278913f, +0.055814f,0.995135f,-0.081185f, +0.198837f,0.979583f,-0.0296926f, +0.452343f,0.887429f,-0.0886289f, +0.538988f,0.831253f,-0.136052f, +0.534759f,0.840783f,-0.084361f, +0.557911f,0.827063f,-0.0685738f, +0.570718f,0.812258f,-0.120488f, +0.469437f,0.877038f,-0.102147f, +0.179725f,0.982175f,0.0550563f, +-0.143773f,0.988083f,0.054972f, +-0.0900032f,0.995941f,-0.00107895f, +-0.112639f,0.992937f,-0.0372634f, +-0.0770822f,0.995012f,-0.0633234f, +0.131283f,0.990073f,-0.0501953f, +0.151552f,0.985928f,-0.0705498f, +0.0547644f,0.990744f,-0.124209f, +-0.0889999f,0.992043f,-0.0890439f, +-0.225525f,0.966809f,-0.120075f, +0.367815f,0.812209f,-0.4528f, +0.333749f,0.806687f,-0.487716f, +0.350467f,0.776679f,-0.523395f, +0.428661f,0.776887f,-0.461189f, +0.344028f,0.851962f,-0.394722f, +0.0917588f,0.929121f,-0.35821f, +-0.151193f,0.922445f,-0.355297f, +-0.135334f,0.926245f,-0.351788f, +-0.0236046f,0.919658f,-0.39201f, +0.0475929f,0.924342f,-0.378586f, +0.0534474f,0.931533f,-0.359707f, +0.122967f,0.908442f,-0.399514f, +0.333531f,0.836829f,-0.434137f, +0.345062f,0.821786f,-0.45343f, +0.298405f,0.81077f,-0.503594f, +0.369796f,0.765054f,-0.527202f, +0.289381f,0.806079f,-0.516232f, +0.106326f,0.866117f,-0.488402f, +-0.0247184f,0.959589f,-0.280318f, +-0.247885f,0.952117f,-0.178958f, +-0.233969f,0.968302f,-0.0874651f, +-0.230973f,0.963517f,-0.135224f, +-0.23946f,0.950685f,-0.197121f, +-0.148981f,0.968772f,-0.198205f, +-0.0244446f,0.976892f,-0.212332f, +0.0214143f,0.979888f,-0.198397f, +0.0179015f,0.996249f,-0.084666f, +-0.0584671f,0.995927f,0.0686411f, +-0.0472317f,0.986168f,0.158874f, +-0.0434315f,0.994906f,0.0909663f, +-0.106857f,0.994237f,0.00858694f, +-0.103595f,0.993848f,-0.0391609f, +-0.0110181f,0.988269f,-0.152323f, +0.194953f,0.947451f,-0.253632f, +0.318956f,0.92262f,-0.216885f, +0.355303f,0.928796f,-0.105349f, +0.319482f,0.947371f,-0.0204796f, +0.274811f,0.961125f,0.0267891f, +0.33758f,0.938163f,0.0767414f, +0.445225f,0.885597f,0.132261f, +0.483843f,0.868855f,0.104815f, +0.473616f,0.877987f,0.069475f, +0.358094f,0.929841f,-0.0846442f, +0.209896f,0.940516f,-0.267156f, +0.398687f,0.89746f,-0.188715f, +0.164362f,0.933368f,-0.319075f, +-0.0806345f,0.937721f,-0.337901f, +0.19678f,0.945117f,-0.26083f, +0.467829f,0.857531f,-0.213953f, +0.522616f,0.828828f,-0.199792f, +0.48751f,0.848849f,-0.204424f, +0.559553f,0.806974f,-0.18893f, +0.585339f,0.775984f,-0.235006f, +0.309037f,0.923705f,-0.22642f, +0.0763335f,0.997082f,0.00115348f, +-0.0450053f,0.998556f,0.0293498f, +-0.0333568f,0.997154f,-0.0676115f, +-0.00964185f,0.995848f,-0.0905243f, +0.000956175f,0.96601f,-0.258503f, +0.00169255f,0.940578f,-0.339574f, +0.0710047f,0.988076f,-0.136617f, +0.0666563f,0.995318f,-0.0699874f, +-0.123764f,0.98454f,-0.123946f, +-0.163961f,0.983022f,-0.0823738f, +0.335205f,0.824436f,-0.456008f, +0.40434f,0.809075f,-0.426506f, +0.410475f,0.791681f,-0.452494f, +0.374361f,0.829194f,-0.41508f, +0.245781f,0.909811f,-0.33442f, +0.0263815f,0.954919f,-0.295693f, +-0.125325f,0.941665f,-0.312348f, +-0.129375f,0.929134f,-0.346369f, +-0.0304152f,0.953686f,-0.299263f, +-0.0235504f,0.953092f,-0.301762f, +0.153775f,0.94901f,-0.275197f, +0.274986f,0.871191f,-0.406705f, +0.301999f,0.805469f,-0.509919f, +0.376419f,0.798039f,-0.470576f, +0.361388f,0.809968f,-0.461899f, +0.38255f,0.848875f,-0.364783f, +0.240129f,0.889938f,-0.387747f, +-0.0576931f,0.937865f,-0.342172f, +-0.263371f,0.95113f,-0.161204f, +-0.310954f,0.950327f,-0.0136276f, +-0.223147f,0.974756f,-0.00746382f, +-0.15809f,0.984734f,-0.0728478f, +-0.146587f,0.977645f,-0.150739f, +-0.120405f,0.952352f,-0.280228f, +0.00186508f,0.961595f,-0.274467f, +-0.0732237f,0.95724f,-0.279876f, +-0.12777f,0.973556f,-0.189377f, +-0.137722f,0.985013f,-0.103834f, +-0.0840689f,0.995964f,-0.0314252f, +0.00572333f,0.997438f,0.0713008f, +-0.0203309f,0.999218f,0.033924f, +0.0131655f,0.994107f,-0.107599f, +0.106442f,0.965608f,-0.237214f, +0.156613f,0.948157f,-0.276534f, +0.221784f,0.959186f,-0.175425f, +0.297839f,0.94933f,-0.100322f, +0.237415f,0.96993f,-0.0535752f, +0.206724f,0.977649f,0.0383141f, +0.342833f,0.933108f,0.108513f, +0.413098f,0.906827f,0.0837554f, +0.485601f,0.86482f,0.127586f, +0.517433f,0.850444f,0.0949105f, +0.521609f,0.853001f,-0.0177076f, +0.35462f,0.907818f,-0.223854f, +0.320255f,0.896065f,-0.307417f, +0.254422f,0.945666f,-0.202447f, +-0.0420832f,0.95285f,-0.300511f, +0.132146f,0.911038f,-0.390572f, +0.397135f,0.84337f,-0.361954f, +0.530962f,0.805014f,-0.264634f, +0.518015f,0.788476f,-0.331612f, +0.536794f,0.726368f,-0.429234f, +0.499189f,0.748129f,-0.437165f, +0.193048f,0.933972f,-0.300713f, +-0.0642143f,0.969885f,-0.234947f, +-0.0349143f,0.97216f,-0.231701f, +-0.020308f,0.973327f,-0.22852f, +0.0335645f,0.983758f,-0.176336f, +0.162495f,0.963807f,-0.211356f, +0.0549435f,0.960153f,-0.274021f, +-0.150243f,0.943756f,-0.294538f, +0.093877f,0.988384f,-0.119518f, +-0.0288967f,0.977445f,-0.209205f, +-0.228292f,0.925763f,-0.301406f, +0.329933f,0.832357f,-0.445339f, +0.354113f,0.855807f,-0.377092f, +0.402588f,0.885182f,-0.233185f, +0.310305f,0.922327f,-0.23027f, +0.169674f,0.966179f,-0.194188f, +0.0510686f,0.987038f,-0.152145f, +-0.0638218f,0.978386f,-0.196689f, +-0.116946f,0.960297f,-0.253286f, +-0.0788814f,0.945056f,-0.317249f, +0.0429532f,0.937478f,-0.345383f, +0.160798f,0.890341f,-0.425953f, +0.370061f,0.833359f,-0.410569f, +0.405144f,0.796477f,-0.448867f, +0.330775f,0.831238f,-0.446802f, +0.214187f,0.914592f,-0.342995f, +0.302956f,0.933789f,-0.190409f, +0.260411f,0.956162f,-0.13394f, +-0.0987797f,0.989363f,-0.106786f, +-0.381946f,0.915584f,-0.125788f, +-0.356892f,0.930397f,-0.0835967f, +-0.219462f,0.974624f,-0.0441002f, +-0.0826206f,0.996346f,-0.0216629f, +-0.0522166f,0.993096f,-0.10504f, +-0.0544454f,0.992373f,-0.110596f, +-0.0392289f,0.996233f,-0.0773398f, +-0.0738534f,0.995703f,-0.0558676f, +-0.126249f,0.987782f,-0.0913672f, +-0.191576f,0.965578f,-0.17595f, +-0.204819f,0.971278f,-0.121116f, +-0.121301f,0.991656f,-0.0436452f, +0.0591737f,0.997785f,0.0303762f, +0.146031f,0.988908f,-0.0271181f, +0.164489f,0.985353f,-0.0449734f, +0.1732f,0.984753f,-0.0162076f, +0.192999f,0.97944f,-0.0587201f, +0.224284f,0.970976f,-0.0830781f, +0.215597f,0.976395f,0.0130766f, +0.11857f,0.99294f,-0.00337615f, +0.283009f,0.956652f,0.0687283f, +0.418445f,0.903636f,0.0913547f, +0.498249f,0.865176f,0.0567366f, +0.572218f,0.818628f,-0.0491444f, +0.584595f,0.798602f,-0.143119f, +0.499999f,0.838004f,-0.218521f, +0.312173f,0.860973f,-0.401589f, +0.169015f,0.918853f,-0.356571f, +0.0805256f,0.94115f,-0.328258f, +0.268694f,0.864193f,-0.42541f, +0.373719f,0.773399f,-0.512044f, +0.442856f,0.749728f,-0.491717f, +0.564815f,0.671761f,-0.479293f, +0.549235f,0.627986f,-0.551338f, +0.305274f,0.788247f,-0.534298f, +0.0146963f,0.910216f,-0.413874f, +-0.0347141f,0.920746f,-0.388614f, +-0.0142092f,0.918584f,-0.394971f, +-0.0593092f,0.944757f,-0.32236f, +-0.0129026f,0.951456f,-0.307515f, +0.101136f,0.954598f,-0.280203f, +0.103786f,0.979836f,-0.170731f, +-0.130724f,0.946294f,-0.2957f, +-0.0475497f,0.951312f,-0.30454f, +0.068843f,0.980898f,-0.181933f, +-0.0601749f,0.975587f,-0.21121f, +0.164088f,0.946673f,-0.277283f, +0.219167f,0.958752f,-0.180996f, +0.292116f,0.952214f,-0.0892046f, +0.382294f,0.923975f,-0.0110254f, +0.185963f,0.972429f,-0.140709f, +0.0282036f,0.98507f,-0.16983f, +-0.0260978f,0.984942f,-0.170904f, +0.00347731f,0.966818f,-0.255444f, +0.046523f,0.915606f,-0.399376f, +0.121249f,0.881024f,-0.457269f, +0.234655f,0.843553f,-0.483069f, +0.349259f,0.806387f,-0.47724f, +0.352024f,0.817545f,-0.455741f, +0.21f,0.895765f,-0.391796f, +0.123731f,0.946466f,-0.298149f, +0.189246f,0.953263f,-0.235533f, +0.21574f,0.971887f,-0.0943018f, +-0.0878709f,0.988681f,-0.12161f, +-0.31365f,0.930831f,-0.187554f, +-0.370884f,0.90378f,-0.213602f, +-0.292833f,0.938489f,-0.182993f, +-0.076513f,0.991298f,-0.107116f, +-0.0492348f,0.994225f,-0.0953508f, +-0.128831f,0.991129f,-0.0326479f, +-0.117178f,0.99304f,0.0118732f, +-0.0834857f,0.989043f,0.12175f, +-0.0124631f,0.991817f,0.127061f, +-0.133134f,0.991073f,-0.00703918f, +-0.190067f,0.981738f,-0.00811131f, +-0.0950662f,0.989352f,-0.110206f, +0.0262188f,0.977376f,-0.209877f, +0.0774906f,0.981033f,-0.177679f, +0.0911686f,0.995787f,-0.00982619f, +0.177517f,0.984043f,0.0121696f, +0.260966f,0.962001f,-0.0803208f, +0.219093f,0.96759f,-0.12557f, +0.15488f,0.986019f,-0.06147f, +0.155325f,0.987507f,-0.0265508f, +0.257438f,0.9633f,-0.0760109f, +0.429699f,0.898131f,-0.0933795f, +0.553938f,0.821258f,-0.136702f, +0.635333f,0.740056f,-0.220611f, +0.590775f,0.752696f,-0.290577f, +0.544721f,0.782975f,-0.300381f, +0.386007f,0.854199f,-0.348343f, +0.159868f,0.903698f,-0.397205f, +0.111475f,0.854344f,-0.507613f, +0.32886f,0.783243f,-0.527619f, +0.428722f,0.729381f,-0.533105f, +0.463071f,0.680849f,-0.567459f, +0.578683f,0.643078f,-0.501575f, +0.498776f,0.750313f,-0.433881f, +0.172367f,0.935224f,-0.309265f, +-0.0549105f,0.957697f,-0.282492f, +-0.000989137f,0.955961f,-0.293491f, +-0.105185f,0.947134f,-0.303107f, +-0.108598f,0.951252f,-0.288662f, +-0.0192021f,0.937992f,-0.346125f, +0.0434621f,0.947915f,-0.315545f, +0.0658084f,0.965866f,-0.250542f, +0.00168367f,0.969468f,-0.245211f, +-0.0752902f,0.953259f,-0.292624f, +-0.0406571f,0.962797f,-0.267151f, +-0.0486067f,0.969651f,-0.239615f, +0.0419974f,0.993223f,-0.108371f, +0.194169f,0.980548f,-0.0286949f, +0.261981f,0.963651f,-0.0523696f, +0.349136f,0.937066f,-0.00343362f, +0.31121f,0.950026f,0.0244779f, +0.0510089f,0.992585f,-0.110335f, +0.0314098f,0.989653f,-0.140003f, +0.185979f,0.958236f,-0.217244f, +0.136104f,0.898638f,-0.417044f, +0.108771f,0.892335f,-0.438072f, +0.238757f,0.906785f,-0.34747f, +0.373646f,0.87379f,-0.311256f, +0.340425f,0.883999f,-0.320402f, +0.14853f,0.93597f,-0.319217f, +0.0564088f,0.968057f,-0.244304f, +0.0971116f,0.979187f,-0.17822f, +0.12449f,0.986246f,-0.108724f, +0.00791995f,0.999591f,-0.0274806f, +-0.236925f,0.964883f,-0.113439f, +-0.404549f,0.891486f,-0.203944f, +-0.302952f,0.940514f,-0.153798f, +-0.187243f,0.970939f,-0.149055f, +-0.103813f,0.994585f,-0.00480558f, +-0.136945f,0.990579f,0.00047278f, +-0.192386f,0.981319f,0.000301484f, +-0.157118f,0.980577f,0.117404f, +-0.0205849f,0.995936f,0.0876826f, +-0.0389376f,0.992928f,0.112147f, +-0.205589f,0.977918f,0.0375515f, +0.0799477f,0.995293f,0.0547661f, +0.128711f,0.981689f,-0.140426f, +-0.00377139f,0.985264f,-0.170999f, +-0.0186288f,0.990563f,-0.135788f, +0.247861f,0.95847f,-0.141069f, +0.335397f,0.913398f,-0.230679f, +0.164127f,0.956335f,-0.241837f, +0.0560549f,0.992155f,-0.111746f, +0.165621f,0.985752f,-0.0293729f, +0.329655f,0.93718f,-0.114108f, +0.47188f,0.859421f,-0.196784f, +0.593068f,0.774119f,-0.22138f, +0.65363f,0.716422f,-0.24394f, +0.606788f,0.760352f,-0.231675f, +0.536399f,0.810894f,-0.23394f, +0.343135f,0.901586f,-0.263439f, +0.295862f,0.930397f,-0.216396f, +0.307346f,0.85762f,-0.412342f, +0.36437f,0.770675f,-0.522776f, +0.48977f,0.726784f,-0.481571f, +0.467664f,0.727396f,-0.50218f, +0.516451f,0.759976f,-0.394608f, +0.369408f,0.883578f,-0.287798f, +0.11272f,0.986131f,-0.121821f, +-0.0556185f,0.985996f,-0.157218f, +-0.0141506f,0.99059f,-0.13613f, +-0.0462718f,0.993931f,-0.099801f, +-0.0190733f,0.9801f,-0.197584f, +0.0617351f,0.955747f,-0.287639f, +-0.00791345f,0.937814f,-0.347049f, +0.0263533f,0.943249f,-0.331038f, +-0.0408223f,0.937006f,-0.34692f, +-0.0840519f,0.9495f,-0.302299f, +-0.0536227f,0.964498f,-0.25859f, +-0.0366453f,0.973297f,-0.226607f, +0.0559372f,0.997556f,-0.0418806f, +0.117658f,0.99199f,-0.0459629f, +0.260816f,0.963552f,0.059517f, +0.265721f,0.95723f,0.114473f, +0.305022f,0.92568f,0.223781f, +0.229311f,0.961539f,0.151192f, +0.0614828f,0.993074f,-0.10012f, +0.279787f,0.947394f,-0.15545f, +0.307005f,0.902601f,-0.301762f, +0.0599313f,0.924785f,-0.375741f, +0.138459f,0.941623f,-0.306881f, +0.380474f,0.890209f,-0.250536f, +0.362157f,0.883362f,-0.297512f, +0.118666f,0.951617f,-0.283449f, +-0.0864913f,0.973386f,-0.212226f, +0.0535968f,0.99807f,-0.0313783f, +0.0571748f,0.998014f,0.026449f, +-0.0576417f,0.995225f,0.0787756f, +-0.164671f,0.983729f,0.0718444f, +-0.317398f,0.947117f,0.0472105f, +-0.350813f,0.936189f,-0.0219157f, +-0.249283f,0.968275f,0.0173648f, +-0.166219f,0.983818f,0.0668861f, +-0.137263f,0.989074f,0.0537794f, +-0.237615f,0.966132f,0.100634f, +-0.156805f,0.98112f,0.113207f, +0.0155394f,0.999476f,0.0283817f, +-0.0358194f,0.998926f,0.0293752f, +-0.187269f,0.982125f,-0.01898f, +0.0856923f,0.996255f,0.0114998f, +0.21812f,0.975918f,0.00295422f, +0.0575266f,0.997525f,-0.0404377f, +0.0557844f,0.976324f,-0.208997f, +0.282723f,0.906166f,-0.314533f, +0.34017f,0.885713f,-0.315906f, +0.0703654f,0.964786f,-0.253451f, +-0.0857039f,0.987005f,-0.135924f, +0.161068f,0.982423f,-0.0943491f, +0.439921f,0.879468f,-0.181673f, +0.499341f,0.805071f,-0.320185f, +0.581376f,0.752639f,-0.309089f, +0.634744f,0.735927f,-0.235609f, +0.590228f,0.797974f,-0.121932f, +0.552123f,0.824777f,-0.122079f, +0.403254f,0.893687f,-0.196749f, +0.282279f,0.904426f,-0.319896f, +0.487441f,0.821419f,-0.296095f, +0.471414f,0.771013f,-0.428146f, +0.452383f,0.750947f,-0.48107f, +0.453351f,0.789814f,-0.413117f, +0.426317f,0.829282f,-0.361311f, +0.274227f,0.935292f,-0.223671f, +0.0409647f,0.985686f,-0.16354f, +0.00611451f,0.980211f,-0.19786f, +-0.0818346f,0.965065f,-0.248905f, +-0.0402149f,0.984168f,-0.172615f, +0.0358772f,0.970818f,-0.237119f, +0.140843f,0.951316f,-0.274156f, +0.0386407f,0.935491f,-0.351232f, +0.02521f,0.945244f,-0.325388f, +-0.00704123f,0.966541f,-0.256414f, +-0.132543f,0.963814f,-0.231288f, +-0.120001f,0.972985f,-0.197233f, +-0.125856f,0.970406f,-0.20609f, +0.150068f,0.984139f,0.0946078f, +0.0962514f,0.994035f,0.0512922f, +0.139768f,0.98134f,0.132051f, +0.167943f,0.959948f,0.224265f, +0.248876f,0.931236f,0.266197f, +0.347088f,0.901338f,0.259075f, +0.298327f,0.935934f,0.187161f, +0.410224f,0.911771f,0.0197232f, +0.382392f,0.916875f,-0.11453f, +0.0687189f,0.981224f,-0.180215f, +0.109108f,0.978331f,-0.175964f, +0.423091f,0.889035f,-0.17496f, +0.308023f,0.9305f,-0.198221f, +0.0610242f,0.996399f,-0.0588678f, +-0.139679f,0.983461f,-0.1153f, +-0.178862f,0.976278f,-0.122024f, +-0.0279755f,0.98865f,0.147609f, +0.0175582f,0.984678f,0.173494f, +-0.182965f,0.982824f,0.0240987f, +-0.334982f,0.934918f,0.117109f, +-0.346361f,0.929574f,0.126201f, +-0.256073f,0.950373f,0.176686f, +-0.14622f,0.975847f,0.162306f, +-0.145894f,0.982033f,0.119692f, +-0.243091f,0.96438f,0.104295f, +-0.119399f,0.991881f,0.0437603f, +0.0792305f,0.996134f,0.0379462f, +-0.0234512f,0.999544f,0.0190445f, +-0.148416f,0.988869f,0.0105176f, +0.0279419f,0.999576f,0.00824062f, +0.239276f,0.970159f,0.0392311f, +0.182184f,0.979477f,-0.086222f, +0.251919f,0.933495f,-0.255194f, +0.359782f,0.855042f,-0.373444f, +0.260041f,0.87469f,-0.409017f, +-0.0332083f,0.931159f,-0.363099f, +-0.108678f,0.933514f,-0.341673f, +0.191287f,0.909011f,-0.370282f, +0.516055f,0.783319f,-0.346553f, +0.557568f,0.726461f,-0.401711f, +0.511814f,0.738467f,-0.438991f, +0.509794f,0.789775f,-0.341125f, +0.522098f,0.819729f,-0.235496f, +0.54438f,0.815602f,-0.196071f, +0.540927f,0.823066f,-0.173089f, +0.36892f,0.838043f,-0.401972f, +0.461826f,0.790802f,-0.401684f, +0.549439f,0.728653f,-0.408878f, +0.455853f,0.753497f,-0.473751f, +0.389397f,0.799772f,-0.456875f, +0.293181f,0.868874f,-0.398878f, +0.155589f,0.965139f,-0.210473f, +0.031565f,0.984349f,-0.173382f, +0.0970165f,0.970686f,-0.219901f, +-0.0352366f,0.943342f,-0.329946f, +-0.0636858f,0.931929f,-0.357006f, +0.111555f,0.924517f,-0.364451f, +0.180963f,0.908751f,-0.376064f, +0.0582409f,0.924666f,-0.376299f, +-0.091325f,0.934476f,-0.344113f, +-0.148498f,0.963415f,-0.223113f, +-0.170646f,0.976481f,-0.131776f, +-0.0961794f,0.980781f,-0.169761f, +-0.06221f,0.973089f,-0.221874f, +0.206636f,0.934831f,0.288777f, +0.0869406f,0.963592f,0.252847f, +0.0799701f,0.959241f,0.271038f, +0.160525f,0.963414f,0.21463f, +0.255681f,0.955661f,0.146082f, +0.323027f,0.93103f,0.169812f, +0.330118f,0.920313f,0.209873f, +0.447578f,0.884885f,0.12904f, +0.467368f,0.874534f,0.129448f, +0.130174f,0.988207f,0.0806387f, +0.145402f,0.989036f,-0.0258009f, +0.425216f,0.898822f,-0.106345f, +0.205136f,0.977985f,-0.0382811f, +-0.0258123f,0.995757f,0.0883314f, +-0.00518813f,0.996132f,0.0877124f, +-0.192412f,0.980974f,0.0258233f, +-0.196114f,0.979963f,0.0348015f, +0.0217983f,0.995754f,0.0894399f, +-0.10216f,0.980256f,0.169296f, +-0.384424f,0.908881f,0.161723f, +-0.367551f,0.91996f,0.136309f, +-0.285788f,0.948719f,0.135118f, +-0.171256f,0.972185f,0.159771f, +-0.0605854f,0.969905f,0.235826f, +-0.167372f,0.981266f,0.0954134f, +-0.0977838f,0.994994f,0.0206294f, +0.0451608f,0.997867f,0.0471292f, +-0.0136124f,0.997411f,0.0706177f, +-0.158818f,0.986831f,0.0306748f, +0.0267005f,0.99957f,0.0121357f, +0.289361f,0.957076f,-0.0166175f, +0.336393f,0.939976f,-0.0573177f, +0.390118f,0.913466f,-0.115702f, +0.445853f,0.875576f,-0.185959f, +0.293335f,0.914816f,-0.277609f, +-0.00739937f,0.915657f,-0.401893f, +0.00533725f,0.872492f,-0.488599f, +0.197734f,0.788261f,-0.582705f, +0.43334f,0.722538f,-0.53866f, +0.548408f,0.706281f,-0.447678f, +0.484095f,0.751007f,-0.449045f, +0.458828f,0.77804f,-0.429103f, +0.441245f,0.787203f,-0.430829f, +0.474553f,0.805707f,-0.354451f, +0.550933f,0.789486f,-0.270526f, +0.502032f,0.792798f,-0.345594f, +0.478273f,0.764634f,-0.43196f, +0.556872f,0.730832f,-0.394687f, +0.471855f,0.788619f,-0.394251f, +0.354943f,0.841801f,-0.406677f, +0.154029f,0.899791f,-0.40823f, +0.0155123f,0.938951f,-0.343701f, +0.0497714f,0.948037f,-0.314243f, +0.154285f,0.935402f,-0.31815f, +0.101927f,0.920411f,-0.377432f, +-0.0203862f,0.864666f,-0.501933f, +0.070179f,0.866621f,-0.494007f, +0.100294f,0.910674f,-0.400766f, +0.000402101f,0.968295f,-0.249809f, +-0.128961f,0.971456f,-0.199105f, +-0.199723f,0.946207f,-0.254564f, +-0.134113f,0.940975f,-0.310772f, +-0.0316747f,0.927512f,-0.372449f, +0.0302907f,0.938917f,-0.342807f, +0.218976f,0.899032f,0.379198f, +0.139079f,0.919337f,0.368072f, +0.135024f,0.957047f,0.256573f, +0.313512f,0.936875f,0.154838f, +0.29644f,0.95504f,0.00476296f, +0.279277f,0.959996f,0.0202722f, +0.3625f,0.931007f,0.0426625f, +0.472022f,0.881367f,0.0196857f, +0.429567f,0.887347f,0.167594f, +0.224991f,0.963227f,0.146879f, +0.296133f,0.954919f,-0.0208476f, +0.415966f,0.902166f,-0.114319f, +0.183129f,0.982743f,0.0260829f, +-0.0925135f,0.995706f,-0.00325499f, +-0.0437431f,0.995986f,0.0780946f, +-0.179713f,0.977607f,0.109486f, +-0.141385f,0.986823f,0.0786845f, +-0.085949f,0.993479f,0.0749198f, +-0.233157f,0.944593f,0.231044f, +-0.345216f,0.897121f,0.275681f, +-0.266518f,0.944857f,0.190296f, +-0.236509f,0.971079f,0.032684f, +-0.255527f,0.96653f,-0.0229239f, +-0.0941044f,0.991025f,0.0949427f, +-0.0715158f,0.990946f,0.113625f, +-0.0636481f,0.988651f,0.136079f, +0.0130078f,0.992968f,0.11767f, +0.0194535f,0.99321f,0.114698f, +-0.0733749f,0.997304f,0.000320173f, +0.0745089f,0.991949f,-0.102398f, +0.316045f,0.940065f,-0.128038f, +0.302503f,0.936628f,-0.176692f, +0.365578f,0.917629f,-0.155918f, +0.474055f,0.875706f,-0.091714f, +0.462666f,0.882661f,-0.0827679f, +0.197672f,0.918824f,-0.341598f, +0.1211f,0.851979f,-0.509379f, +0.340562f,0.776445f,-0.530237f, +0.411588f,0.704014f,-0.578756f, +0.454493f,0.713166f,-0.533695f, +0.463114f,0.742631f,-0.483761f, +0.44079f,0.754688f,-0.485953f, +0.400302f,0.772025f,-0.493696f, +0.38659f,0.783016f,-0.487272f, +0.457033f,0.766931f,-0.450487f, +0.547084f,0.759757f,-0.351382f, +0.508566f,0.782012f,-0.360303f, +0.54699f,0.792915f,-0.268492f, +0.489855f,0.837224f,-0.243102f, +0.350988f,0.891534f,-0.286312f, +0.195385f,0.947495f,-0.253137f, +0.0709694f,0.939176f,-0.336023f, +0.0288377f,0.903143f,-0.42837f, +0.128806f,0.91498f,-0.382389f, +0.209123f,0.895775f,-0.392243f, +0.0981301f,0.852621f,-0.513233f, +-0.0414306f,0.841347f,-0.538906f, +-0.0951984f,0.922571f,-0.373899f, +-0.157973f,0.963972f,-0.214014f, +-0.107909f,0.978829f,-0.173926f, +-0.0713291f,0.969594f,-0.234092f, +0.0141898f,0.950434f,-0.310602f, +-0.0202439f,0.895649f,-0.4443f, +-0.114151f,0.867225f,-0.484655f, +0.0955354f,0.969912f,0.223927f, +0.218114f,0.913651f,0.343028f, +0.223104f,0.958808f,0.175816f, +0.39761f,0.915149f,0.0663907f, +0.332649f,0.940641f,-0.0673772f, +0.280455f,0.956871f,-0.0757854f, +0.359446f,0.926985f,-0.107225f, +0.369482f,0.924827f,-0.0904272f, +0.410746f,0.887001f,0.210991f, +0.335823f,0.922126f,0.192112f, +0.395669f,0.917218f,-0.0464346f, +0.353697f,0.926083f,-0.131407f, +0.179534f,0.981887f,0.0605388f, +-0.13479f,0.99057f,-0.0245515f, +-0.0725996f,0.990136f,0.119831f, +-0.160567f,0.981095f,0.108036f, +-0.173547f,0.983858f,0.0436428f, +-0.151709f,0.976244f,0.154697f, +-0.302597f,0.914896f,0.267208f, +-0.328732f,0.906446f,0.265123f, +-0.132663f,0.960039f,0.246424f, +-0.138673f,0.989957f,0.0274833f, +-0.234284f,0.968151f,-0.0882923f, +-0.176173f,0.979923f,-0.0933525f, +-0.138089f,0.990412f,-0.00402308f, +-0.0957719f,0.981754f,0.164279f, +0.0343111f,0.979592f,0.198047f, +0.0638942f,0.984862f,0.161133f, +0.0719687f,0.995312f,0.0646062f, +0.0847007f,0.982914f,-0.163422f, +0.363247f,0.926697f,-0.0963506f, +0.36667f,0.908341f,-0.201173f, +0.337169f,0.882657f,-0.327465f, +0.394509f,0.879929f,-0.264742f, +0.48646f,0.864989f,-0.123088f, +0.417344f,0.883151f,-0.21417f, +0.20086f,0.830272f,-0.519907f, +0.38892f,0.767179f,-0.510077f, +0.449414f,0.718324f,-0.531072f, +0.423477f,0.726204f,-0.541567f, +0.422958f,0.74196f,-0.520194f, +0.433204f,0.760712f,-0.483374f, +0.409051f,0.775415f,-0.481049f, +0.416047f,0.762178f,-0.495973f, +0.412818f,0.728929f,-0.546117f, +0.422596f,0.756339f,-0.499363f, +0.473538f,0.806572f,-0.353841f, +0.474731f,0.838081f,-0.268794f, +0.539079f,0.832631f,-0.126962f, +0.311124f,0.910644f,-0.271898f, +0.195648f,0.962321f,-0.18884f, +0.177086f,0.961235f,-0.211349f, +0.0559264f,0.927874f,-0.368677f, +0.121016f,0.928529f,-0.350982f, +0.256538f,0.895264f,-0.364269f, +0.222607f,0.876269f,-0.427317f, +-0.106542f,0.82471f,-0.55543f, +-0.245122f,0.890501f,-0.383305f, +-0.209725f,0.956698f,-0.201855f, +-0.0624605f,0.97406f,-0.2175f, +-0.0812465f,0.947824f,-0.308266f, +0.0649824f,0.972455f,-0.223851f, +0.119957f,0.950206f,-0.287609f, +-0.0414767f,0.905483f,-0.422351f, +}; + +btScalar Landscape03Tex[] = { +0.507813f,0.5f, +0.507813f,0.492188f, +0.515625f,0.5f, +0.515625f,0.492188f, +0.523438f,0.5f, +0.523438f,0.492188f, +0.53125f,0.5f, +0.53125f,0.492188f, +0.539063f,0.5f, +0.539063f,0.492188f, +0.546875f,0.5f, +0.546875f,0.492188f, +0.554688f,0.5f, +0.554688f,0.492188f, +0.5625f,0.5f, +0.5625f,0.492188f, +0.570313f,0.5f, +0.570313f,0.492188f, +0.578125f,0.5f, +0.578125f,0.492188f, +0.585938f,0.5f, +0.585938f,0.492188f, +0.59375f,0.5f, +0.59375f,0.492188f, +0.601563f,0.5f, +0.601563f,0.492188f, +0.609375f,0.5f, +0.609375f,0.492188f, +0.617188f,0.5f, +0.617188f,0.492188f, +0.625f,0.5f, +0.625f,0.492188f, +0.632813f,0.5f, +0.632813f,0.492188f, +0.640625f,0.5f, +0.640625f,0.492188f, +0.648438f,0.5f, +0.648438f,0.492188f, +0.65625f,0.5f, +0.65625f,0.492188f, +0.664063f,0.5f, +0.664063f,0.492188f, +0.671875f,0.5f, +0.671875f,0.492188f, +0.679688f,0.5f, +0.679688f,0.492188f, +0.6875f,0.5f, +0.6875f,0.492188f, +0.695313f,0.5f, +0.695313f,0.492188f, +0.703125f,0.5f, +0.703125f,0.492188f, +0.710938f,0.5f, +0.710938f,0.492188f, +0.71875f,0.5f, +0.71875f,0.492188f, +0.726563f,0.5f, +0.726563f,0.492188f, +0.734375f,0.5f, +0.734375f,0.492188f, +0.742188f,0.5f, +0.742188f,0.492188f, +0.75f,0.5f, +0.75f,0.492188f, +0.757813f,0.5f, +0.757813f,0.492188f, +0.765625f,0.5f, +0.765625f,0.492188f, +0.773438f,0.5f, +0.773438f,0.492188f, +0.78125f,0.5f, +0.78125f,0.492188f, +0.789063f,0.5f, +0.789063f,0.492188f, +0.796875f,0.5f, +0.796875f,0.492188f, +0.804688f,0.5f, +0.804688f,0.492188f, +0.8125f,0.5f, +0.8125f,0.492188f, +0.820313f,0.5f, +0.820313f,0.492188f, +0.828125f,0.5f, +0.828125f,0.492188f, +0.835938f,0.5f, +0.835938f,0.492188f, +0.84375f,0.5f, +0.84375f,0.492188f, +0.851563f,0.5f, +0.851563f,0.492188f, +0.859375f,0.5f, +0.859375f,0.492188f, +0.867188f,0.5f, +0.867188f,0.492188f, +0.875f,0.5f, +0.875f,0.492188f, +0.882813f,0.5f, +0.882813f,0.492188f, +0.890625f,0.5f, +0.890625f,0.492188f, +0.898438f,0.5f, +0.898438f,0.492188f, +0.90625f,0.5f, +0.90625f,0.492188f, +0.914063f,0.5f, +0.914063f,0.492188f, +0.921875f,0.5f, +0.921875f,0.492188f, +0.929688f,0.5f, +0.929688f,0.492188f, +0.9375f,0.5f, +0.9375f,0.492188f, +0.945313f,0.5f, +0.945313f,0.492188f, +0.953125f,0.5f, +0.953125f,0.492188f, +0.960938f,0.5f, +0.960938f,0.492188f, +0.96875f,0.5f, +0.96875f,0.492188f, +0.976563f,0.5f, +0.976563f,0.492188f, +0.984375f,0.5f, +0.984375f,0.492188f, +0.992188f,0.5f, +0.992188f,0.492188f, +1.0f,0.5f, +1.0f,0.492188f, +0.507813f,0.507813f, +0.515625f,0.507813f, +0.523438f,0.507813f, +0.53125f,0.507813f, +0.539063f,0.507813f, +0.546875f,0.507813f, +0.554688f,0.507813f, +0.5625f,0.507813f, +0.570313f,0.507813f, +0.578125f,0.507813f, +0.585938f,0.507813f, +0.59375f,0.507813f, +0.601563f,0.507813f, +0.609375f,0.507813f, +0.617188f,0.507813f, +0.625f,0.507813f, +0.632813f,0.507813f, +0.640625f,0.507813f, +0.648438f,0.507813f, +0.65625f,0.507813f, +0.664063f,0.507813f, +0.671875f,0.507813f, +0.679688f,0.507813f, +0.6875f,0.507813f, +0.695313f,0.507813f, +0.703125f,0.507813f, +0.710938f,0.507813f, +0.71875f,0.507813f, +0.726563f,0.507813f, +0.734375f,0.507813f, +0.742188f,0.507813f, +0.75f,0.507813f, +0.757813f,0.507813f, +0.765625f,0.507813f, +0.773438f,0.507813f, +0.78125f,0.507813f, +0.789063f,0.507813f, +0.796875f,0.507813f, +0.804688f,0.507813f, +0.8125f,0.507813f, +0.820313f,0.507813f, +0.828125f,0.507813f, +0.835938f,0.507813f, +0.84375f,0.507813f, +0.851563f,0.507813f, +0.859375f,0.507813f, +0.867188f,0.507813f, +0.875f,0.507813f, +0.882813f,0.507813f, +0.890625f,0.507813f, +0.898438f,0.507813f, +0.90625f,0.507813f, +0.914063f,0.507813f, +0.921875f,0.507813f, +0.929688f,0.507813f, +0.9375f,0.507813f, +0.945313f,0.507813f, +0.953125f,0.507813f, +0.960938f,0.507813f, +0.96875f,0.507813f, +0.976563f,0.507813f, +0.984375f,0.507813f, +0.992188f,0.507813f, +1.0f,0.507813f, +0.507813f,0.515625f, +0.515625f,0.515625f, +0.523438f,0.515625f, +0.53125f,0.515625f, +0.539063f,0.515625f, +0.546875f,0.515625f, +0.554688f,0.515625f, +0.5625f,0.515625f, +0.570313f,0.515625f, +0.578125f,0.515625f, +0.585938f,0.515625f, +0.59375f,0.515625f, +0.601563f,0.515625f, +0.609375f,0.515625f, +0.617188f,0.515625f, +0.625f,0.515625f, +0.632813f,0.515625f, +0.640625f,0.515625f, +0.648438f,0.515625f, +0.65625f,0.515625f, +0.664063f,0.515625f, +0.671875f,0.515625f, +0.679688f,0.515625f, +0.6875f,0.515625f, +0.695313f,0.515625f, +0.703125f,0.515625f, +0.710938f,0.515625f, +0.71875f,0.515625f, +0.726563f,0.515625f, +0.734375f,0.515625f, +0.742188f,0.515625f, +0.75f,0.515625f, +0.757813f,0.515625f, +0.765625f,0.515625f, +0.773438f,0.515625f, +0.78125f,0.515625f, +0.789063f,0.515625f, +0.796875f,0.515625f, +0.804688f,0.515625f, +0.8125f,0.515625f, +0.820313f,0.515625f, +0.828125f,0.515625f, +0.835938f,0.515625f, +0.84375f,0.515625f, +0.851563f,0.515625f, +0.859375f,0.515625f, +0.867188f,0.515625f, +0.875f,0.515625f, +0.882813f,0.515625f, +0.890625f,0.515625f, +0.898438f,0.515625f, +0.90625f,0.515625f, +0.914063f,0.515625f, +0.921875f,0.515625f, +0.929688f,0.515625f, +0.9375f,0.515625f, +0.945313f,0.515625f, +0.953125f,0.515625f, +0.960938f,0.515625f, +0.96875f,0.515625f, +0.976563f,0.515625f, +0.984375f,0.515625f, +0.992188f,0.515625f, +1.0f,0.515625f, +0.507813f,0.523438f, +0.515625f,0.523438f, +0.523438f,0.523438f, +0.53125f,0.523438f, +0.539063f,0.523438f, +0.546875f,0.523438f, +0.554688f,0.523438f, +0.5625f,0.523438f, +0.570313f,0.523438f, +0.578125f,0.523438f, +0.585938f,0.523438f, +0.59375f,0.523438f, +0.601563f,0.523438f, +0.609375f,0.523438f, +0.617188f,0.523438f, +0.625f,0.523438f, +0.632813f,0.523438f, +0.640625f,0.523438f, +0.648438f,0.523438f, +0.65625f,0.523438f, +0.664063f,0.523438f, +0.671875f,0.523438f, +0.679688f,0.523438f, +0.6875f,0.523438f, +0.695313f,0.523438f, +0.703125f,0.523438f, +0.710938f,0.523438f, +0.71875f,0.523438f, +0.726563f,0.523438f, +0.734375f,0.523438f, +0.742188f,0.523438f, +0.75f,0.523438f, +0.757813f,0.523438f, +0.765625f,0.523438f, +0.773438f,0.523438f, +0.78125f,0.523438f, +0.789063f,0.523438f, +0.796875f,0.523438f, +0.804688f,0.523438f, +0.8125f,0.523438f, +0.820313f,0.523438f, +0.828125f,0.523438f, +0.835938f,0.523438f, +0.84375f,0.523438f, +0.851563f,0.523438f, +0.859375f,0.523438f, +0.867188f,0.523438f, +0.875f,0.523438f, +0.882813f,0.523438f, +0.890625f,0.523438f, +0.898438f,0.523438f, +0.90625f,0.523438f, +0.914063f,0.523438f, +0.921875f,0.523438f, +0.929688f,0.523438f, +0.9375f,0.523438f, +0.945313f,0.523438f, +0.953125f,0.523438f, +0.960938f,0.523438f, +0.96875f,0.523438f, +0.976563f,0.523438f, +0.984375f,0.523438f, +0.992188f,0.523438f, +1.0f,0.523438f, +0.507813f,0.53125f, +0.515625f,0.53125f, +0.523438f,0.53125f, +0.53125f,0.53125f, +0.539063f,0.53125f, +0.546875f,0.53125f, +0.554688f,0.53125f, +0.5625f,0.53125f, +0.570313f,0.53125f, +0.578125f,0.53125f, +0.585938f,0.53125f, +0.59375f,0.53125f, +0.601563f,0.53125f, +0.609375f,0.53125f, +0.617188f,0.53125f, +0.625f,0.53125f, +0.632813f,0.53125f, +0.640625f,0.53125f, +0.648438f,0.53125f, +0.65625f,0.53125f, +0.664063f,0.53125f, +0.671875f,0.53125f, +0.679688f,0.53125f, +0.6875f,0.53125f, +0.695313f,0.53125f, +0.703125f,0.53125f, +0.710938f,0.53125f, +0.71875f,0.53125f, +0.726563f,0.53125f, +0.734375f,0.53125f, +0.742188f,0.53125f, +0.75f,0.53125f, +0.757813f,0.53125f, +0.765625f,0.53125f, +0.773438f,0.53125f, +0.78125f,0.53125f, +0.789063f,0.53125f, +0.796875f,0.53125f, +0.804688f,0.53125f, +0.8125f,0.53125f, +0.820313f,0.53125f, +0.828125f,0.53125f, +0.835938f,0.53125f, +0.84375f,0.53125f, +0.851563f,0.53125f, +0.859375f,0.53125f, +0.867188f,0.53125f, +0.875f,0.53125f, +0.882813f,0.53125f, +0.890625f,0.53125f, +0.898438f,0.53125f, +0.90625f,0.53125f, +0.914063f,0.53125f, +0.921875f,0.53125f, +0.929688f,0.53125f, +0.9375f,0.53125f, +0.945313f,0.53125f, +0.953125f,0.53125f, +0.960938f,0.53125f, +0.96875f,0.53125f, +0.976563f,0.53125f, +0.984375f,0.53125f, +0.992188f,0.53125f, +1.0f,0.53125f, +0.507813f,0.539063f, +0.515625f,0.539063f, +0.523438f,0.539063f, +0.53125f,0.539063f, +0.539063f,0.539063f, +0.546875f,0.539063f, +0.554688f,0.539063f, +0.5625f,0.539063f, +0.570313f,0.539063f, +0.578125f,0.539063f, +0.585938f,0.539063f, +0.59375f,0.539063f, +0.601563f,0.539063f, +0.609375f,0.539063f, +0.617188f,0.539063f, +0.625f,0.539063f, +0.632813f,0.539063f, +0.640625f,0.539063f, +0.648438f,0.539063f, +0.65625f,0.539063f, +0.664063f,0.539063f, +0.671875f,0.539063f, +0.679688f,0.539063f, +0.6875f,0.539063f, +0.695313f,0.539063f, +0.703125f,0.539063f, +0.710938f,0.539063f, +0.71875f,0.539063f, +0.726563f,0.539063f, +0.734375f,0.539063f, +0.742188f,0.539063f, +0.75f,0.539063f, +0.757813f,0.539063f, +0.765625f,0.539063f, +0.773438f,0.539063f, +0.78125f,0.539063f, +0.789063f,0.539063f, +0.796875f,0.539063f, +0.804688f,0.539063f, +0.8125f,0.539063f, +0.820313f,0.539063f, +0.828125f,0.539063f, +0.835938f,0.539063f, +0.84375f,0.539063f, +0.851563f,0.539063f, +0.859375f,0.539063f, +0.867188f,0.539063f, +0.875f,0.539063f, +0.882813f,0.539063f, +0.890625f,0.539063f, +0.898438f,0.539063f, +0.90625f,0.539063f, +0.914063f,0.539063f, +0.921875f,0.539063f, +0.929688f,0.539063f, +0.9375f,0.539063f, +0.945313f,0.539063f, +0.953125f,0.539063f, +0.960938f,0.539063f, +0.96875f,0.539063f, +0.976563f,0.539063f, +0.984375f,0.539063f, +0.992188f,0.539063f, +1.0f,0.539063f, +0.507813f,0.546875f, +0.515625f,0.546875f, +0.523438f,0.546875f, +0.53125f,0.546875f, +0.539063f,0.546875f, +0.546875f,0.546875f, +0.554688f,0.546875f, +0.5625f,0.546875f, +0.570313f,0.546875f, +0.578125f,0.546875f, +0.585938f,0.546875f, +0.59375f,0.546875f, +0.601563f,0.546875f, +0.609375f,0.546875f, +0.617188f,0.546875f, +0.625f,0.546875f, +0.632813f,0.546875f, +0.640625f,0.546875f, +0.648438f,0.546875f, +0.65625f,0.546875f, +0.664063f,0.546875f, +0.671875f,0.546875f, +0.679688f,0.546875f, +0.6875f,0.546875f, +0.695313f,0.546875f, +0.703125f,0.546875f, +0.710938f,0.546875f, +0.71875f,0.546875f, +0.726563f,0.546875f, +0.734375f,0.546875f, +0.742188f,0.546875f, +0.75f,0.546875f, +0.757813f,0.546875f, +0.765625f,0.546875f, +0.773438f,0.546875f, +0.78125f,0.546875f, +0.789063f,0.546875f, +0.796875f,0.546875f, +0.804688f,0.546875f, +0.8125f,0.546875f, +0.820313f,0.546875f, +0.828125f,0.546875f, +0.835938f,0.546875f, +0.84375f,0.546875f, +0.851563f,0.546875f, +0.859375f,0.546875f, +0.867188f,0.546875f, +0.875f,0.546875f, +0.882813f,0.546875f, +0.890625f,0.546875f, +0.898438f,0.546875f, +0.90625f,0.546875f, +0.914063f,0.546875f, +0.921875f,0.546875f, +0.929688f,0.546875f, +0.9375f,0.546875f, +0.945313f,0.546875f, +0.953125f,0.546875f, +0.960938f,0.546875f, +0.96875f,0.546875f, +0.976563f,0.546875f, +0.984375f,0.546875f, +0.992188f,0.546875f, +1.0f,0.546875f, +0.507813f,0.554688f, +0.515625f,0.554688f, +0.523438f,0.554688f, +0.53125f,0.554688f, +0.539063f,0.554688f, +0.546875f,0.554688f, +0.554688f,0.554688f, +0.5625f,0.554688f, +0.570313f,0.554688f, +0.578125f,0.554688f, +0.585938f,0.554688f, +0.59375f,0.554688f, +0.601563f,0.554688f, +0.609375f,0.554688f, +0.617188f,0.554688f, +0.625f,0.554688f, +0.632813f,0.554688f, +0.640625f,0.554688f, +0.648438f,0.554688f, +0.65625f,0.554688f, +0.664063f,0.554688f, +0.671875f,0.554688f, +0.679688f,0.554688f, +0.6875f,0.554688f, +0.695313f,0.554688f, +0.703125f,0.554688f, +0.710938f,0.554688f, +0.71875f,0.554688f, +0.726563f,0.554688f, +0.734375f,0.554688f, +0.742188f,0.554688f, +0.75f,0.554688f, +0.757813f,0.554688f, +0.765625f,0.554688f, +0.773438f,0.554688f, +0.78125f,0.554688f, +0.789063f,0.554688f, +0.796875f,0.554688f, +0.804688f,0.554688f, +0.8125f,0.554688f, +0.820313f,0.554688f, +0.828125f,0.554688f, +0.835938f,0.554688f, +0.84375f,0.554688f, +0.851563f,0.554688f, +0.859375f,0.554688f, +0.867188f,0.554688f, +0.875f,0.554688f, +0.882813f,0.554688f, +0.890625f,0.554688f, +0.898438f,0.554688f, +0.90625f,0.554688f, +0.914063f,0.554688f, +0.921875f,0.554688f, +0.929688f,0.554688f, +0.9375f,0.554688f, +0.945313f,0.554688f, +0.953125f,0.554688f, +0.960938f,0.554688f, +0.96875f,0.554688f, +0.976563f,0.554688f, +0.984375f,0.554688f, +0.992188f,0.554688f, +1.0f,0.554688f, +0.507813f,0.5625f, +0.515625f,0.5625f, +0.523438f,0.5625f, +0.53125f,0.5625f, +0.539063f,0.5625f, +0.546875f,0.5625f, +0.554688f,0.5625f, +0.5625f,0.5625f, +0.570313f,0.5625f, +0.578125f,0.5625f, +0.585938f,0.5625f, +0.59375f,0.5625f, +0.601563f,0.5625f, +0.609375f,0.5625f, +0.617188f,0.5625f, +0.625f,0.5625f, +0.632813f,0.5625f, +0.640625f,0.5625f, +0.648438f,0.5625f, +0.65625f,0.5625f, +0.664063f,0.5625f, +0.671875f,0.5625f, +0.679688f,0.5625f, +0.6875f,0.5625f, +0.695313f,0.5625f, +0.703125f,0.5625f, +0.710938f,0.5625f, +0.71875f,0.5625f, +0.726563f,0.5625f, +0.734375f,0.5625f, +0.742188f,0.5625f, +0.75f,0.5625f, +0.757813f,0.5625f, +0.765625f,0.5625f, +0.773438f,0.5625f, +0.78125f,0.5625f, +0.789063f,0.5625f, +0.796875f,0.5625f, +0.804688f,0.5625f, +0.8125f,0.5625f, +0.820313f,0.5625f, +0.828125f,0.5625f, +0.835938f,0.5625f, +0.84375f,0.5625f, +0.851563f,0.5625f, +0.859375f,0.5625f, +0.867188f,0.5625f, +0.875f,0.5625f, +0.882813f,0.5625f, +0.890625f,0.5625f, +0.898438f,0.5625f, +0.90625f,0.5625f, +0.914063f,0.5625f, +0.921875f,0.5625f, +0.929688f,0.5625f, +0.9375f,0.5625f, +0.945313f,0.5625f, +0.953125f,0.5625f, +0.960938f,0.5625f, +0.96875f,0.5625f, +0.976563f,0.5625f, +0.984375f,0.5625f, +0.992188f,0.5625f, +1.0f,0.5625f, +0.507813f,0.570313f, +0.515625f,0.570313f, +0.523438f,0.570313f, +0.53125f,0.570313f, +0.539063f,0.570313f, +0.546875f,0.570313f, +0.554688f,0.570313f, +0.5625f,0.570313f, +0.570313f,0.570313f, +0.578125f,0.570313f, +0.585938f,0.570313f, +0.59375f,0.570313f, +0.601563f,0.570313f, +0.609375f,0.570313f, +0.617188f,0.570313f, +0.625f,0.570313f, +0.632813f,0.570313f, +0.640625f,0.570313f, +0.648438f,0.570313f, +0.65625f,0.570313f, +0.664063f,0.570313f, +0.671875f,0.570313f, +0.679688f,0.570313f, +0.6875f,0.570313f, +0.695313f,0.570313f, +0.703125f,0.570313f, +0.710938f,0.570313f, +0.71875f,0.570313f, +0.726563f,0.570313f, +0.734375f,0.570313f, +0.742188f,0.570313f, +0.75f,0.570313f, +0.757813f,0.570313f, +0.765625f,0.570313f, +0.773438f,0.570313f, +0.78125f,0.570313f, +0.789063f,0.570313f, +0.796875f,0.570313f, +0.804688f,0.570313f, +0.8125f,0.570313f, +0.820313f,0.570313f, +0.828125f,0.570313f, +0.835938f,0.570313f, +0.84375f,0.570313f, +0.851563f,0.570313f, +0.859375f,0.570313f, +0.867188f,0.570313f, +0.875f,0.570313f, +0.882813f,0.570313f, +0.890625f,0.570313f, +0.898438f,0.570313f, +0.90625f,0.570313f, +0.914063f,0.570313f, +0.921875f,0.570313f, +0.929688f,0.570313f, +0.9375f,0.570313f, +0.945313f,0.570313f, +0.953125f,0.570313f, +0.960938f,0.570313f, +0.96875f,0.570313f, +0.976563f,0.570313f, +0.984375f,0.570313f, +0.992188f,0.570313f, +1.0f,0.570313f, +0.507813f,0.578125f, +0.515625f,0.578125f, +0.523438f,0.578125f, +0.53125f,0.578125f, +0.539063f,0.578125f, +0.546875f,0.578125f, +0.554688f,0.578125f, +0.5625f,0.578125f, +0.570313f,0.578125f, +0.578125f,0.578125f, +0.585938f,0.578125f, +0.59375f,0.578125f, +0.601563f,0.578125f, +0.609375f,0.578125f, +0.617188f,0.578125f, +0.625f,0.578125f, +0.632813f,0.578125f, +0.640625f,0.578125f, +0.648438f,0.578125f, +0.65625f,0.578125f, +0.664063f,0.578125f, +0.671875f,0.578125f, +0.679688f,0.578125f, +0.6875f,0.578125f, +0.695313f,0.578125f, +0.703125f,0.578125f, +0.710938f,0.578125f, +0.71875f,0.578125f, +0.726563f,0.578125f, +0.734375f,0.578125f, +0.742188f,0.578125f, +0.75f,0.578125f, +0.757813f,0.578125f, +0.765625f,0.578125f, +0.773438f,0.578125f, +0.78125f,0.578125f, +0.789063f,0.578125f, +0.796875f,0.578125f, +0.804688f,0.578125f, +0.8125f,0.578125f, +0.820313f,0.578125f, +0.828125f,0.578125f, +0.835938f,0.578125f, +0.84375f,0.578125f, +0.851563f,0.578125f, +0.859375f,0.578125f, +0.867188f,0.578125f, +0.875f,0.578125f, +0.882813f,0.578125f, +0.890625f,0.578125f, +0.898438f,0.578125f, +0.90625f,0.578125f, +0.914063f,0.578125f, +0.921875f,0.578125f, +0.929688f,0.578125f, +0.9375f,0.578125f, +0.945313f,0.578125f, +0.953125f,0.578125f, +0.960938f,0.578125f, +0.96875f,0.578125f, +0.976563f,0.578125f, +0.984375f,0.578125f, +0.992188f,0.578125f, +1.0f,0.578125f, +0.507813f,0.585938f, +0.515625f,0.585938f, +0.523438f,0.585938f, +0.53125f,0.585938f, +0.539063f,0.585938f, +0.546875f,0.585938f, +0.554688f,0.585938f, +0.5625f,0.585938f, +0.570313f,0.585938f, +0.578125f,0.585938f, +0.585938f,0.585938f, +0.59375f,0.585938f, +0.601563f,0.585938f, +0.609375f,0.585938f, +0.617188f,0.585938f, +0.625f,0.585938f, +0.632813f,0.585938f, +0.640625f,0.585938f, +0.648438f,0.585938f, +0.65625f,0.585938f, +0.664063f,0.585938f, +0.671875f,0.585938f, +0.679688f,0.585938f, +0.6875f,0.585938f, +0.695313f,0.585938f, +0.703125f,0.585938f, +0.710938f,0.585938f, +0.71875f,0.585938f, +0.726563f,0.585938f, +0.734375f,0.585938f, +0.742188f,0.585938f, +0.75f,0.585938f, +0.757813f,0.585938f, +0.765625f,0.585938f, +0.773438f,0.585938f, +0.78125f,0.585938f, +0.789063f,0.585938f, +0.796875f,0.585938f, +0.804688f,0.585938f, +0.8125f,0.585938f, +0.820313f,0.585938f, +0.828125f,0.585938f, +0.835938f,0.585938f, +0.84375f,0.585938f, +0.851563f,0.585938f, +0.859375f,0.585938f, +0.867188f,0.585938f, +0.875f,0.585938f, +0.882813f,0.585938f, +0.890625f,0.585938f, +0.898438f,0.585938f, +0.90625f,0.585938f, +0.914063f,0.585938f, +0.921875f,0.585938f, +0.929688f,0.585938f, +0.9375f,0.585938f, +0.945313f,0.585938f, +0.953125f,0.585938f, +0.960938f,0.585938f, +0.96875f,0.585938f, +0.976563f,0.585938f, +0.984375f,0.585938f, +0.992188f,0.585938f, +1.0f,0.585938f, +0.507813f,0.59375f, +0.515625f,0.59375f, +0.523438f,0.59375f, +0.53125f,0.59375f, +0.539063f,0.59375f, +0.546875f,0.59375f, +0.554688f,0.59375f, +0.5625f,0.59375f, +0.570313f,0.59375f, +0.578125f,0.59375f, +0.585938f,0.59375f, +0.59375f,0.59375f, +0.601563f,0.59375f, +0.609375f,0.59375f, +0.617188f,0.59375f, +0.625f,0.59375f, +0.632813f,0.59375f, +0.640625f,0.59375f, +0.648438f,0.59375f, +0.65625f,0.59375f, +0.664063f,0.59375f, +0.671875f,0.59375f, +0.679688f,0.59375f, +0.6875f,0.59375f, +0.695313f,0.59375f, +0.703125f,0.59375f, +0.710938f,0.59375f, +0.71875f,0.59375f, +0.726563f,0.59375f, +0.734375f,0.59375f, +0.742188f,0.59375f, +0.75f,0.59375f, +0.757813f,0.59375f, +0.765625f,0.59375f, +0.773438f,0.59375f, +0.78125f,0.59375f, +0.789063f,0.59375f, +0.796875f,0.59375f, +0.804688f,0.59375f, +0.8125f,0.59375f, +0.820313f,0.59375f, +0.828125f,0.59375f, +0.835938f,0.59375f, +0.84375f,0.59375f, +0.851563f,0.59375f, +0.859375f,0.59375f, +0.867188f,0.59375f, +0.875f,0.59375f, +0.882813f,0.59375f, +0.890625f,0.59375f, +0.898438f,0.59375f, +0.90625f,0.59375f, +0.914063f,0.59375f, +0.921875f,0.59375f, +0.929688f,0.59375f, +0.9375f,0.59375f, +0.945313f,0.59375f, +0.953125f,0.59375f, +0.960938f,0.59375f, +0.96875f,0.59375f, +0.976563f,0.59375f, +0.984375f,0.59375f, +0.992188f,0.59375f, +1.0f,0.59375f, +0.507813f,0.601563f, +0.515625f,0.601563f, +0.523438f,0.601563f, +0.53125f,0.601563f, +0.539063f,0.601563f, +0.546875f,0.601563f, +0.554688f,0.601563f, +0.5625f,0.601563f, +0.570313f,0.601563f, +0.578125f,0.601563f, +0.585938f,0.601563f, +0.59375f,0.601563f, +0.601563f,0.601563f, +0.609375f,0.601563f, +0.617188f,0.601563f, +0.625f,0.601563f, +0.632813f,0.601563f, +0.640625f,0.601563f, +0.648438f,0.601563f, +0.65625f,0.601563f, +0.664063f,0.601563f, +0.671875f,0.601563f, +0.679688f,0.601563f, +0.6875f,0.601563f, +0.695313f,0.601563f, +0.703125f,0.601563f, +0.710938f,0.601563f, +0.71875f,0.601563f, +0.726563f,0.601563f, +0.734375f,0.601563f, +0.742188f,0.601563f, +0.75f,0.601563f, +0.757813f,0.601563f, +0.765625f,0.601563f, +0.773438f,0.601563f, +0.78125f,0.601563f, +0.789063f,0.601563f, +0.796875f,0.601563f, +0.804688f,0.601563f, +0.8125f,0.601563f, +0.820313f,0.601563f, +0.828125f,0.601563f, +0.835938f,0.601563f, +0.84375f,0.601563f, +0.851563f,0.601563f, +0.859375f,0.601563f, +0.867188f,0.601563f, +0.875f,0.601563f, +0.882813f,0.601563f, +0.890625f,0.601563f, +0.898438f,0.601563f, +0.90625f,0.601563f, +0.914063f,0.601563f, +0.921875f,0.601563f, +0.929688f,0.601563f, +0.9375f,0.601563f, +0.945313f,0.601563f, +0.953125f,0.601563f, +0.960938f,0.601563f, +0.96875f,0.601563f, +0.976563f,0.601563f, +0.984375f,0.601563f, +0.992188f,0.601563f, +1.0f,0.601563f, +0.507813f,0.609375f, +0.515625f,0.609375f, +0.523438f,0.609375f, +0.53125f,0.609375f, +0.539063f,0.609375f, +0.546875f,0.609375f, +0.554688f,0.609375f, +0.5625f,0.609375f, +0.570313f,0.609375f, +0.578125f,0.609375f, +0.585938f,0.609375f, +0.59375f,0.609375f, +0.601563f,0.609375f, +0.609375f,0.609375f, +0.617188f,0.609375f, +0.625f,0.609375f, +0.632813f,0.609375f, +0.640625f,0.609375f, +0.648438f,0.609375f, +0.65625f,0.609375f, +0.664063f,0.609375f, +0.671875f,0.609375f, +0.679688f,0.609375f, +0.6875f,0.609375f, +0.695313f,0.609375f, +0.703125f,0.609375f, +0.710938f,0.609375f, +0.71875f,0.609375f, +0.726563f,0.609375f, +0.734375f,0.609375f, +0.742188f,0.609375f, +0.75f,0.609375f, +0.757813f,0.609375f, +0.765625f,0.609375f, +0.773438f,0.609375f, +0.78125f,0.609375f, +0.789063f,0.609375f, +0.796875f,0.609375f, +0.804688f,0.609375f, +0.8125f,0.609375f, +0.820313f,0.609375f, +0.828125f,0.609375f, +0.835938f,0.609375f, +0.84375f,0.609375f, +0.851563f,0.609375f, +0.859375f,0.609375f, +0.867188f,0.609375f, +0.875f,0.609375f, +0.882813f,0.609375f, +0.890625f,0.609375f, +0.898438f,0.609375f, +0.90625f,0.609375f, +0.914063f,0.609375f, +0.921875f,0.609375f, +0.929688f,0.609375f, +0.9375f,0.609375f, +0.945313f,0.609375f, +0.953125f,0.609375f, +0.960938f,0.609375f, +0.96875f,0.609375f, +0.976563f,0.609375f, +0.984375f,0.609375f, +0.992188f,0.609375f, +1.0f,0.609375f, +0.507813f,0.617188f, +0.515625f,0.617188f, +0.523438f,0.617188f, +0.53125f,0.617188f, +0.539063f,0.617188f, +0.546875f,0.617188f, +0.554688f,0.617188f, +0.5625f,0.617188f, +0.570313f,0.617188f, +0.578125f,0.617188f, +0.585938f,0.617188f, +0.59375f,0.617188f, +0.601563f,0.617188f, +0.609375f,0.617188f, +0.617188f,0.617188f, +0.625f,0.617188f, +0.632813f,0.617188f, +0.640625f,0.617188f, +0.648438f,0.617188f, +0.65625f,0.617188f, +0.664063f,0.617188f, +0.671875f,0.617188f, +0.679688f,0.617188f, +0.6875f,0.617188f, +0.695313f,0.617188f, +0.703125f,0.617188f, +0.710938f,0.617188f, +0.71875f,0.617188f, +0.726563f,0.617188f, +0.734375f,0.617188f, +0.742188f,0.617188f, +0.75f,0.617188f, +0.757813f,0.617188f, +0.765625f,0.617188f, +0.773438f,0.617188f, +0.78125f,0.617188f, +0.789063f,0.617188f, +0.796875f,0.617188f, +0.804688f,0.617188f, +0.8125f,0.617188f, +0.820313f,0.617188f, +0.828125f,0.617188f, +0.835938f,0.617188f, +0.84375f,0.617188f, +0.851563f,0.617188f, +0.859375f,0.617188f, +0.867188f,0.617188f, +0.875f,0.617188f, +0.882813f,0.617188f, +0.890625f,0.617188f, +0.898438f,0.617188f, +0.90625f,0.617188f, +0.914063f,0.617188f, +0.921875f,0.617188f, +0.929688f,0.617188f, +0.9375f,0.617188f, +0.945313f,0.617188f, +0.953125f,0.617188f, +0.960938f,0.617188f, +0.96875f,0.617188f, +0.976563f,0.617188f, +0.984375f,0.617188f, +0.992188f,0.617188f, +1.0f,0.617188f, +0.507813f,0.625f, +0.515625f,0.625f, +0.523438f,0.625f, +0.53125f,0.625f, +0.539063f,0.625f, +0.546875f,0.625f, +0.554688f,0.625f, +0.5625f,0.625f, +0.570313f,0.625f, +0.578125f,0.625f, +0.585938f,0.625f, +0.59375f,0.625f, +0.601563f,0.625f, +0.609375f,0.625f, +0.617188f,0.625f, +0.625f,0.625f, +0.632813f,0.625f, +0.640625f,0.625f, +0.648438f,0.625f, +0.65625f,0.625f, +0.664063f,0.625f, +0.671875f,0.625f, +0.679688f,0.625f, +0.6875f,0.625f, +0.695313f,0.625f, +0.703125f,0.625f, +0.710938f,0.625f, +0.71875f,0.625f, +0.726563f,0.625f, +0.734375f,0.625f, +0.742188f,0.625f, +0.75f,0.625f, +0.757813f,0.625f, +0.765625f,0.625f, +0.773438f,0.625f, +0.78125f,0.625f, +0.789063f,0.625f, +0.796875f,0.625f, +0.804688f,0.625f, +0.8125f,0.625f, +0.820313f,0.625f, +0.828125f,0.625f, +0.835938f,0.625f, +0.84375f,0.625f, +0.851563f,0.625f, +0.859375f,0.625f, +0.867188f,0.625f, +0.875f,0.625f, +0.882813f,0.625f, +0.890625f,0.625f, +0.898438f,0.625f, +0.90625f,0.625f, +0.914063f,0.625f, +0.921875f,0.625f, +0.929688f,0.625f, +0.9375f,0.625f, +0.945313f,0.625f, +0.953125f,0.625f, +0.960938f,0.625f, +0.96875f,0.625f, +0.976563f,0.625f, +0.984375f,0.625f, +0.992188f,0.625f, +1.0f,0.625f, +0.507813f,0.632813f, +0.515625f,0.632813f, +0.523438f,0.632813f, +0.53125f,0.632813f, +0.539063f,0.632813f, +0.546875f,0.632813f, +0.554688f,0.632813f, +0.5625f,0.632813f, +0.570313f,0.632813f, +0.578125f,0.632813f, +0.585938f,0.632813f, +0.59375f,0.632813f, +0.601563f,0.632813f, +0.609375f,0.632813f, +0.617188f,0.632813f, +0.625f,0.632813f, +0.632813f,0.632813f, +0.640625f,0.632813f, +0.648438f,0.632813f, +0.65625f,0.632813f, +0.664063f,0.632813f, +0.671875f,0.632813f, +0.679688f,0.632813f, +0.6875f,0.632813f, +0.695313f,0.632813f, +0.703125f,0.632813f, +0.710938f,0.632813f, +0.71875f,0.632813f, +0.726563f,0.632813f, +0.734375f,0.632813f, +0.742188f,0.632813f, +0.75f,0.632813f, +0.757813f,0.632813f, +0.765625f,0.632813f, +0.773438f,0.632813f, +0.78125f,0.632813f, +0.789063f,0.632813f, +0.796875f,0.632813f, +0.804688f,0.632813f, +0.8125f,0.632813f, +0.820313f,0.632813f, +0.828125f,0.632813f, +0.835938f,0.632813f, +0.84375f,0.632813f, +0.851563f,0.632813f, +0.859375f,0.632813f, +0.867188f,0.632813f, +0.875f,0.632813f, +0.882813f,0.632813f, +0.890625f,0.632813f, +0.898438f,0.632813f, +0.90625f,0.632813f, +0.914063f,0.632813f, +0.921875f,0.632813f, +0.929688f,0.632813f, +0.9375f,0.632813f, +0.945313f,0.632813f, +0.953125f,0.632813f, +0.960938f,0.632813f, +0.96875f,0.632813f, +0.976563f,0.632813f, +0.984375f,0.632813f, +0.992188f,0.632813f, +1.0f,0.632813f, +0.507813f,0.640625f, +0.515625f,0.640625f, +0.523438f,0.640625f, +0.53125f,0.640625f, +0.539063f,0.640625f, +0.546875f,0.640625f, +0.554688f,0.640625f, +0.5625f,0.640625f, +0.570313f,0.640625f, +0.578125f,0.640625f, +0.585938f,0.640625f, +0.59375f,0.640625f, +0.601563f,0.640625f, +0.609375f,0.640625f, +0.617188f,0.640625f, +0.625f,0.640625f, +0.632813f,0.640625f, +0.640625f,0.640625f, +0.648438f,0.640625f, +0.65625f,0.640625f, +0.664063f,0.640625f, +0.671875f,0.640625f, +0.679688f,0.640625f, +0.6875f,0.640625f, +0.695313f,0.640625f, +0.703125f,0.640625f, +0.710938f,0.640625f, +0.71875f,0.640625f, +0.726563f,0.640625f, +0.734375f,0.640625f, +0.742188f,0.640625f, +0.75f,0.640625f, +0.757813f,0.640625f, +0.765625f,0.640625f, +0.773438f,0.640625f, +0.78125f,0.640625f, +0.789063f,0.640625f, +0.796875f,0.640625f, +0.804688f,0.640625f, +0.8125f,0.640625f, +0.820313f,0.640625f, +0.828125f,0.640625f, +0.835938f,0.640625f, +0.84375f,0.640625f, +0.851563f,0.640625f, +0.859375f,0.640625f, +0.867188f,0.640625f, +0.875f,0.640625f, +0.882813f,0.640625f, +0.890625f,0.640625f, +0.898438f,0.640625f, +0.90625f,0.640625f, +0.914063f,0.640625f, +0.921875f,0.640625f, +0.929688f,0.640625f, +0.9375f,0.640625f, +0.945313f,0.640625f, +0.953125f,0.640625f, +0.960938f,0.640625f, +0.96875f,0.640625f, +0.976563f,0.640625f, +0.984375f,0.640625f, +0.992188f,0.640625f, +1.0f,0.640625f, +0.507813f,0.648438f, +0.515625f,0.648438f, +0.523438f,0.648438f, +0.53125f,0.648438f, +0.539063f,0.648438f, +0.546875f,0.648438f, +0.554688f,0.648438f, +0.5625f,0.648438f, +0.570313f,0.648438f, +0.578125f,0.648438f, +0.585938f,0.648438f, +0.59375f,0.648438f, +0.601563f,0.648438f, +0.609375f,0.648438f, +0.617188f,0.648438f, +0.625f,0.648438f, +0.632813f,0.648438f, +0.640625f,0.648438f, +0.648438f,0.648438f, +0.65625f,0.648438f, +0.664063f,0.648438f, +0.671875f,0.648438f, +0.679688f,0.648438f, +0.6875f,0.648438f, +0.695313f,0.648438f, +0.703125f,0.648438f, +0.710938f,0.648438f, +0.71875f,0.648438f, +0.726563f,0.648438f, +0.734375f,0.648438f, +0.742188f,0.648438f, +0.75f,0.648438f, +0.757813f,0.648438f, +0.765625f,0.648438f, +0.773438f,0.648438f, +0.78125f,0.648438f, +0.789063f,0.648438f, +0.796875f,0.648438f, +0.804688f,0.648438f, +0.8125f,0.648438f, +0.820313f,0.648438f, +0.828125f,0.648438f, +0.835938f,0.648438f, +0.84375f,0.648438f, +0.851563f,0.648438f, +0.859375f,0.648438f, +0.867188f,0.648438f, +0.875f,0.648438f, +0.882813f,0.648438f, +0.890625f,0.648438f, +0.898438f,0.648438f, +0.90625f,0.648438f, +0.914063f,0.648438f, +0.921875f,0.648438f, +0.929688f,0.648438f, +0.9375f,0.648438f, +0.945313f,0.648438f, +0.953125f,0.648438f, +0.960938f,0.648438f, +0.96875f,0.648438f, +0.976563f,0.648438f, +0.984375f,0.648438f, +0.992188f,0.648438f, +1.0f,0.648438f, +0.507813f,0.65625f, +0.515625f,0.65625f, +0.523438f,0.65625f, +0.53125f,0.65625f, +0.539063f,0.65625f, +0.546875f,0.65625f, +0.554688f,0.65625f, +0.5625f,0.65625f, +0.570313f,0.65625f, +0.578125f,0.65625f, +0.585938f,0.65625f, +0.59375f,0.65625f, +0.601563f,0.65625f, +0.609375f,0.65625f, +0.617188f,0.65625f, +0.625f,0.65625f, +0.632813f,0.65625f, +0.640625f,0.65625f, +0.648438f,0.65625f, +0.65625f,0.65625f, +0.664063f,0.65625f, +0.671875f,0.65625f, +0.679688f,0.65625f, +0.6875f,0.65625f, +0.695313f,0.65625f, +0.703125f,0.65625f, +0.710938f,0.65625f, +0.71875f,0.65625f, +0.726563f,0.65625f, +0.734375f,0.65625f, +0.742188f,0.65625f, +0.75f,0.65625f, +0.757813f,0.65625f, +0.765625f,0.65625f, +0.773438f,0.65625f, +0.78125f,0.65625f, +0.789063f,0.65625f, +0.796875f,0.65625f, +0.804688f,0.65625f, +0.8125f,0.65625f, +0.820313f,0.65625f, +0.828125f,0.65625f, +0.835938f,0.65625f, +0.84375f,0.65625f, +0.851563f,0.65625f, +0.859375f,0.65625f, +0.867188f,0.65625f, +0.875f,0.65625f, +0.882813f,0.65625f, +0.890625f,0.65625f, +0.898438f,0.65625f, +0.90625f,0.65625f, +0.914063f,0.65625f, +0.921875f,0.65625f, +0.929688f,0.65625f, +0.9375f,0.65625f, +0.945313f,0.65625f, +0.953125f,0.65625f, +0.960938f,0.65625f, +0.96875f,0.65625f, +0.976563f,0.65625f, +0.984375f,0.65625f, +0.992188f,0.65625f, +1.0f,0.65625f, +0.507813f,0.664063f, +0.515625f,0.664063f, +0.523438f,0.664063f, +0.53125f,0.664063f, +0.539063f,0.664063f, +0.546875f,0.664063f, +0.554688f,0.664063f, +0.5625f,0.664063f, +0.570313f,0.664063f, +0.578125f,0.664063f, +0.585938f,0.664063f, +0.59375f,0.664063f, +0.601563f,0.664063f, +0.609375f,0.664063f, +0.617188f,0.664063f, +0.625f,0.664063f, +0.632813f,0.664063f, +0.640625f,0.664063f, +0.648438f,0.664063f, +0.65625f,0.664063f, +0.664063f,0.664063f, +0.671875f,0.664063f, +0.679688f,0.664063f, +0.6875f,0.664063f, +0.695313f,0.664063f, +0.703125f,0.664063f, +0.710938f,0.664063f, +0.71875f,0.664063f, +0.726563f,0.664063f, +0.734375f,0.664063f, +0.742188f,0.664063f, +0.75f,0.664063f, +0.757813f,0.664063f, +0.765625f,0.664063f, +0.773438f,0.664063f, +0.78125f,0.664063f, +0.789063f,0.664063f, +0.796875f,0.664063f, +0.804688f,0.664063f, +0.8125f,0.664063f, +0.820313f,0.664063f, +0.828125f,0.664063f, +0.835938f,0.664063f, +0.84375f,0.664063f, +0.851563f,0.664063f, +0.859375f,0.664063f, +0.867188f,0.664063f, +0.875f,0.664063f, +0.882813f,0.664063f, +0.890625f,0.664063f, +0.898438f,0.664063f, +0.90625f,0.664063f, +0.914063f,0.664063f, +0.921875f,0.664063f, +0.929688f,0.664063f, +0.9375f,0.664063f, +0.945313f,0.664063f, +0.953125f,0.664063f, +0.960938f,0.664063f, +0.96875f,0.664063f, +0.976563f,0.664063f, +0.984375f,0.664063f, +0.992188f,0.664063f, +1.0f,0.664063f, +0.507813f,0.671875f, +0.515625f,0.671875f, +0.523438f,0.671875f, +0.53125f,0.671875f, +0.539063f,0.671875f, +0.546875f,0.671875f, +0.554688f,0.671875f, +0.5625f,0.671875f, +0.570313f,0.671875f, +0.578125f,0.671875f, +0.585938f,0.671875f, +0.59375f,0.671875f, +0.601563f,0.671875f, +0.609375f,0.671875f, +0.617188f,0.671875f, +0.625f,0.671875f, +0.632813f,0.671875f, +0.640625f,0.671875f, +0.648438f,0.671875f, +0.65625f,0.671875f, +0.664063f,0.671875f, +0.671875f,0.671875f, +0.679688f,0.671875f, +0.6875f,0.671875f, +0.695313f,0.671875f, +0.703125f,0.671875f, +0.710938f,0.671875f, +0.71875f,0.671875f, +0.726563f,0.671875f, +0.734375f,0.671875f, +0.742188f,0.671875f, +0.75f,0.671875f, +0.757813f,0.671875f, +0.765625f,0.671875f, +0.773438f,0.671875f, +0.78125f,0.671875f, +0.789063f,0.671875f, +0.796875f,0.671875f, +0.804688f,0.671875f, +0.8125f,0.671875f, +0.820313f,0.671875f, +0.828125f,0.671875f, +0.835938f,0.671875f, +0.84375f,0.671875f, +0.851563f,0.671875f, +0.859375f,0.671875f, +0.867188f,0.671875f, +0.875f,0.671875f, +0.882813f,0.671875f, +0.890625f,0.671875f, +0.898438f,0.671875f, +0.90625f,0.671875f, +0.914063f,0.671875f, +0.921875f,0.671875f, +0.929688f,0.671875f, +0.9375f,0.671875f, +0.945313f,0.671875f, +0.953125f,0.671875f, +0.960938f,0.671875f, +0.96875f,0.671875f, +0.976563f,0.671875f, +0.984375f,0.671875f, +0.992188f,0.671875f, +1.0f,0.671875f, +0.507813f,0.679688f, +0.515625f,0.679688f, +0.523438f,0.679688f, +0.53125f,0.679688f, +0.539063f,0.679688f, +0.546875f,0.679688f, +0.554688f,0.679688f, +0.5625f,0.679688f, +0.570313f,0.679688f, +0.578125f,0.679688f, +0.585938f,0.679688f, +0.59375f,0.679688f, +0.601563f,0.679688f, +0.609375f,0.679688f, +0.617188f,0.679688f, +0.625f,0.679688f, +0.632813f,0.679688f, +0.640625f,0.679688f, +0.648438f,0.679688f, +0.65625f,0.679688f, +0.664063f,0.679688f, +0.671875f,0.679688f, +0.679688f,0.679688f, +0.6875f,0.679688f, +0.695313f,0.679688f, +0.703125f,0.679688f, +0.710938f,0.679688f, +0.71875f,0.679688f, +0.726563f,0.679688f, +0.734375f,0.679688f, +0.742188f,0.679688f, +0.75f,0.679688f, +0.757813f,0.679688f, +0.765625f,0.679688f, +0.773438f,0.679688f, +0.78125f,0.679688f, +0.789063f,0.679688f, +0.796875f,0.679688f, +0.804688f,0.679688f, +0.8125f,0.679688f, +0.820313f,0.679688f, +0.828125f,0.679688f, +0.835938f,0.679688f, +0.84375f,0.679688f, +0.851563f,0.679688f, +0.859375f,0.679688f, +0.867188f,0.679688f, +0.875f,0.679688f, +0.882813f,0.679688f, +0.890625f,0.679688f, +0.898438f,0.679688f, +0.90625f,0.679688f, +0.914063f,0.679688f, +0.921875f,0.679688f, +0.929688f,0.679688f, +0.9375f,0.679688f, +0.945313f,0.679688f, +0.953125f,0.679688f, +0.960938f,0.679688f, +0.96875f,0.679688f, +0.976563f,0.679688f, +0.984375f,0.679688f, +0.992188f,0.679688f, +1.0f,0.679688f, +0.507813f,0.6875f, +0.515625f,0.6875f, +0.523438f,0.6875f, +0.53125f,0.6875f, +0.539063f,0.6875f, +0.546875f,0.6875f, +0.554688f,0.6875f, +0.5625f,0.6875f, +0.570313f,0.6875f, +0.578125f,0.6875f, +0.585938f,0.6875f, +0.59375f,0.6875f, +0.601563f,0.6875f, +0.609375f,0.6875f, +0.617188f,0.6875f, +0.625f,0.6875f, +0.632813f,0.6875f, +0.640625f,0.6875f, +0.648438f,0.6875f, +0.65625f,0.6875f, +0.664063f,0.6875f, +0.671875f,0.6875f, +0.679688f,0.6875f, +0.6875f,0.6875f, +0.695313f,0.6875f, +0.703125f,0.6875f, +0.710938f,0.6875f, +0.71875f,0.6875f, +0.726563f,0.6875f, +0.734375f,0.6875f, +0.742188f,0.6875f, +0.75f,0.6875f, +0.757813f,0.6875f, +0.765625f,0.6875f, +0.773438f,0.6875f, +0.78125f,0.6875f, +0.789063f,0.6875f, +0.796875f,0.6875f, +0.804688f,0.6875f, +0.8125f,0.6875f, +0.820313f,0.6875f, +0.828125f,0.6875f, +0.835938f,0.6875f, +0.84375f,0.6875f, +0.851563f,0.6875f, +0.859375f,0.6875f, +0.867188f,0.6875f, +0.875f,0.6875f, +0.882813f,0.6875f, +0.890625f,0.6875f, +0.898438f,0.6875f, +0.90625f,0.6875f, +0.914063f,0.6875f, +0.921875f,0.6875f, +0.929688f,0.6875f, +0.9375f,0.6875f, +0.945313f,0.6875f, +0.953125f,0.6875f, +0.960938f,0.6875f, +0.96875f,0.6875f, +0.976563f,0.6875f, +0.984375f,0.6875f, +0.992188f,0.6875f, +1.0f,0.6875f, +0.507813f,0.695313f, +0.515625f,0.695313f, +0.523438f,0.695313f, +0.53125f,0.695313f, +0.539063f,0.695313f, +0.546875f,0.695313f, +0.554688f,0.695313f, +0.5625f,0.695313f, +0.570313f,0.695313f, +0.578125f,0.695313f, +0.585938f,0.695313f, +0.59375f,0.695313f, +0.601563f,0.695313f, +0.609375f,0.695313f, +0.617188f,0.695313f, +0.625f,0.695313f, +0.632813f,0.695313f, +0.640625f,0.695313f, +0.648438f,0.695313f, +0.65625f,0.695313f, +0.664063f,0.695313f, +0.671875f,0.695313f, +0.679688f,0.695313f, +0.6875f,0.695313f, +0.695313f,0.695313f, +0.703125f,0.695313f, +0.710938f,0.695313f, +0.71875f,0.695313f, +0.726563f,0.695313f, +0.734375f,0.695313f, +0.742188f,0.695313f, +0.75f,0.695313f, +0.757813f,0.695313f, +0.765625f,0.695313f, +0.773438f,0.695313f, +0.78125f,0.695313f, +0.789063f,0.695313f, +0.796875f,0.695313f, +0.804688f,0.695313f, +0.8125f,0.695313f, +0.820313f,0.695313f, +0.828125f,0.695313f, +0.835938f,0.695313f, +0.84375f,0.695313f, +0.851563f,0.695313f, +0.859375f,0.695313f, +0.867188f,0.695313f, +0.875f,0.695313f, +0.882813f,0.695313f, +0.890625f,0.695313f, +0.898438f,0.695313f, +0.90625f,0.695313f, +0.914063f,0.695313f, +0.921875f,0.695313f, +0.929688f,0.695313f, +0.9375f,0.695313f, +0.945313f,0.695313f, +0.953125f,0.695313f, +0.960938f,0.695313f, +0.96875f,0.695313f, +0.976563f,0.695313f, +0.984375f,0.695313f, +0.992188f,0.695313f, +1.0f,0.695313f, +0.507813f,0.703125f, +0.515625f,0.703125f, +0.523438f,0.703125f, +0.53125f,0.703125f, +0.539063f,0.703125f, +0.546875f,0.703125f, +0.554688f,0.703125f, +0.5625f,0.703125f, +0.570313f,0.703125f, +0.578125f,0.703125f, +0.585938f,0.703125f, +0.59375f,0.703125f, +0.601563f,0.703125f, +0.609375f,0.703125f, +0.617188f,0.703125f, +0.625f,0.703125f, +0.632813f,0.703125f, +0.640625f,0.703125f, +0.648438f,0.703125f, +0.65625f,0.703125f, +0.664063f,0.703125f, +0.671875f,0.703125f, +0.679688f,0.703125f, +0.6875f,0.703125f, +0.695313f,0.703125f, +0.703125f,0.703125f, +0.710938f,0.703125f, +0.71875f,0.703125f, +0.726563f,0.703125f, +0.734375f,0.703125f, +0.742188f,0.703125f, +0.75f,0.703125f, +0.757813f,0.703125f, +0.765625f,0.703125f, +0.773438f,0.703125f, +0.78125f,0.703125f, +0.789063f,0.703125f, +0.796875f,0.703125f, +0.804688f,0.703125f, +0.8125f,0.703125f, +0.820313f,0.703125f, +0.828125f,0.703125f, +0.835938f,0.703125f, +0.84375f,0.703125f, +0.851563f,0.703125f, +0.859375f,0.703125f, +0.867188f,0.703125f, +0.875f,0.703125f, +0.882813f,0.703125f, +0.890625f,0.703125f, +0.898438f,0.703125f, +0.90625f,0.703125f, +0.914063f,0.703125f, +0.921875f,0.703125f, +0.929688f,0.703125f, +0.9375f,0.703125f, +0.945313f,0.703125f, +0.953125f,0.703125f, +0.960938f,0.703125f, +0.96875f,0.703125f, +0.976563f,0.703125f, +0.984375f,0.703125f, +0.992188f,0.703125f, +1.0f,0.703125f, +0.507813f,0.710938f, +0.515625f,0.710938f, +0.523438f,0.710938f, +0.53125f,0.710938f, +0.539063f,0.710938f, +0.546875f,0.710938f, +0.554688f,0.710938f, +0.5625f,0.710938f, +0.570313f,0.710938f, +0.578125f,0.710938f, +0.585938f,0.710938f, +0.59375f,0.710938f, +0.601563f,0.710938f, +0.609375f,0.710938f, +0.617188f,0.710938f, +0.625f,0.710938f, +0.632813f,0.710938f, +0.640625f,0.710938f, +0.648438f,0.710938f, +0.65625f,0.710938f, +0.664063f,0.710938f, +0.671875f,0.710938f, +0.679688f,0.710938f, +0.6875f,0.710938f, +0.695313f,0.710938f, +0.703125f,0.710938f, +0.710938f,0.710938f, +0.71875f,0.710938f, +0.726563f,0.710938f, +0.734375f,0.710938f, +0.742188f,0.710938f, +0.75f,0.710938f, +0.757813f,0.710938f, +0.765625f,0.710938f, +0.773438f,0.710938f, +0.78125f,0.710938f, +0.789063f,0.710938f, +0.796875f,0.710938f, +0.804688f,0.710938f, +0.8125f,0.710938f, +0.820313f,0.710938f, +0.828125f,0.710938f, +0.835938f,0.710938f, +0.84375f,0.710938f, +0.851563f,0.710938f, +0.859375f,0.710938f, +0.867188f,0.710938f, +0.875f,0.710938f, +0.882813f,0.710938f, +0.890625f,0.710938f, +0.898438f,0.710938f, +0.90625f,0.710938f, +0.914063f,0.710938f, +0.921875f,0.710938f, +0.929688f,0.710938f, +0.9375f,0.710938f, +0.945313f,0.710938f, +0.953125f,0.710938f, +0.960938f,0.710938f, +0.96875f,0.710938f, +0.976563f,0.710938f, +0.984375f,0.710938f, +0.992188f,0.710938f, +1.0f,0.710938f, +0.507813f,0.71875f, +0.515625f,0.71875f, +0.523438f,0.71875f, +0.53125f,0.71875f, +0.539063f,0.71875f, +0.546875f,0.71875f, +0.554688f,0.71875f, +0.5625f,0.71875f, +0.570313f,0.71875f, +0.578125f,0.71875f, +0.585938f,0.71875f, +0.59375f,0.71875f, +0.601563f,0.71875f, +0.609375f,0.71875f, +0.617188f,0.71875f, +0.625f,0.71875f, +0.632813f,0.71875f, +0.640625f,0.71875f, +0.648438f,0.71875f, +0.65625f,0.71875f, +0.664063f,0.71875f, +0.671875f,0.71875f, +0.679688f,0.71875f, +0.6875f,0.71875f, +0.695313f,0.71875f, +0.703125f,0.71875f, +0.710938f,0.71875f, +0.71875f,0.71875f, +0.726563f,0.71875f, +0.734375f,0.71875f, +0.742188f,0.71875f, +0.75f,0.71875f, +0.757813f,0.71875f, +0.765625f,0.71875f, +0.773438f,0.71875f, +0.78125f,0.71875f, +0.789063f,0.71875f, +0.796875f,0.71875f, +0.804688f,0.71875f, +0.8125f,0.71875f, +0.820313f,0.71875f, +0.828125f,0.71875f, +0.835938f,0.71875f, +0.84375f,0.71875f, +0.851563f,0.71875f, +0.859375f,0.71875f, +0.867188f,0.71875f, +0.875f,0.71875f, +0.882813f,0.71875f, +0.890625f,0.71875f, +0.898438f,0.71875f, +0.90625f,0.71875f, +0.914063f,0.71875f, +0.921875f,0.71875f, +0.929688f,0.71875f, +0.9375f,0.71875f, +0.945313f,0.71875f, +0.953125f,0.71875f, +0.960938f,0.71875f, +0.96875f,0.71875f, +0.976563f,0.71875f, +0.984375f,0.71875f, +0.992188f,0.71875f, +1.0f,0.71875f, +0.507813f,0.726563f, +0.515625f,0.726563f, +0.523438f,0.726563f, +0.53125f,0.726563f, +0.539063f,0.726563f, +0.546875f,0.726563f, +0.554688f,0.726563f, +0.5625f,0.726563f, +0.570313f,0.726563f, +0.578125f,0.726563f, +0.585938f,0.726563f, +0.59375f,0.726563f, +0.601563f,0.726563f, +0.609375f,0.726563f, +0.617188f,0.726563f, +0.625f,0.726563f, +0.632813f,0.726563f, +0.640625f,0.726563f, +0.648438f,0.726563f, +0.65625f,0.726563f, +0.664063f,0.726563f, +0.671875f,0.726563f, +0.679688f,0.726563f, +0.6875f,0.726563f, +0.695313f,0.726563f, +0.703125f,0.726563f, +0.710938f,0.726563f, +0.71875f,0.726563f, +0.726563f,0.726563f, +0.734375f,0.726563f, +0.742188f,0.726563f, +0.75f,0.726563f, +0.757813f,0.726563f, +0.765625f,0.726563f, +0.773438f,0.726563f, +0.78125f,0.726563f, +0.789063f,0.726563f, +0.796875f,0.726563f, +0.804688f,0.726563f, +0.8125f,0.726563f, +0.820313f,0.726563f, +0.828125f,0.726563f, +0.835938f,0.726563f, +0.84375f,0.726563f, +0.851563f,0.726563f, +0.859375f,0.726563f, +0.867188f,0.726563f, +0.875f,0.726563f, +0.882813f,0.726563f, +0.890625f,0.726563f, +0.898438f,0.726563f, +0.90625f,0.726563f, +0.914063f,0.726563f, +0.921875f,0.726563f, +0.929688f,0.726563f, +0.9375f,0.726563f, +0.945313f,0.726563f, +0.953125f,0.726563f, +0.960938f,0.726563f, +0.96875f,0.726563f, +0.976563f,0.726563f, +0.984375f,0.726563f, +0.992188f,0.726563f, +1.0f,0.726563f, +0.507813f,0.734375f, +0.515625f,0.734375f, +0.523438f,0.734375f, +0.53125f,0.734375f, +0.539063f,0.734375f, +0.546875f,0.734375f, +0.554688f,0.734375f, +0.5625f,0.734375f, +0.570313f,0.734375f, +0.578125f,0.734375f, +0.585938f,0.734375f, +0.59375f,0.734375f, +0.601563f,0.734375f, +0.609375f,0.734375f, +0.617188f,0.734375f, +0.625f,0.734375f, +0.632813f,0.734375f, +0.640625f,0.734375f, +0.648438f,0.734375f, +0.65625f,0.734375f, +0.664063f,0.734375f, +0.671875f,0.734375f, +0.679688f,0.734375f, +0.6875f,0.734375f, +0.695313f,0.734375f, +0.703125f,0.734375f, +0.710938f,0.734375f, +0.71875f,0.734375f, +0.726563f,0.734375f, +0.734375f,0.734375f, +0.742188f,0.734375f, +0.75f,0.734375f, +0.757813f,0.734375f, +0.765625f,0.734375f, +0.773438f,0.734375f, +0.78125f,0.734375f, +0.789063f,0.734375f, +0.796875f,0.734375f, +0.804688f,0.734375f, +0.8125f,0.734375f, +0.820313f,0.734375f, +0.828125f,0.734375f, +0.835938f,0.734375f, +0.84375f,0.734375f, +0.851563f,0.734375f, +0.859375f,0.734375f, +0.867188f,0.734375f, +0.875f,0.734375f, +0.882813f,0.734375f, +0.890625f,0.734375f, +0.898438f,0.734375f, +0.90625f,0.734375f, +0.914063f,0.734375f, +0.921875f,0.734375f, +0.929688f,0.734375f, +0.9375f,0.734375f, +0.945313f,0.734375f, +0.953125f,0.734375f, +0.960938f,0.734375f, +0.96875f,0.734375f, +0.976563f,0.734375f, +0.984375f,0.734375f, +0.992188f,0.734375f, +1.0f,0.734375f, +}; + +unsigned short Landscape03Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +128,0,129, +2,129,0, +129,2,130, +4,130,2, +130,4,131, +6,131,4, +131,6,132, +8,132,6, +132,8,133, +10,133,8, +133,10,134, +12,134,10, +134,12,135, +14,135,12, +135,14,136, +16,136,14, +136,16,137, +18,137,16, +137,18,138, +20,138,18, +138,20,139, +22,139,20, +139,22,140, +24,140,22, +140,24,141, +26,141,24, +141,26,142, +28,142,26, +142,28,143, +30,143,28, +143,30,144, +32,144,30, +144,32,145, +34,145,32, +145,34,146, +36,146,34, +146,36,147, +38,147,36, +147,38,148, +40,148,38, +148,40,149, +42,149,40, +149,42,150, +44,150,42, +150,44,151, +46,151,44, +151,46,152, +48,152,46, +152,48,153, +50,153,48, +153,50,154, +52,154,50, +154,52,155, +54,155,52, +155,54,156, +56,156,54, +156,56,157, +58,157,56, +157,58,158, +60,158,58, +158,60,159, +62,159,60, +159,62,160, +64,160,62, +160,64,161, +66,161,64, +161,66,162, +68,162,66, +162,68,163, +70,163,68, +163,70,164, +72,164,70, +164,72,165, +74,165,72, +165,74,166, +76,166,74, +166,76,167, +78,167,76, +167,78,168, +80,168,78, +168,80,169, +82,169,80, +169,82,170, +84,170,82, +170,84,171, +86,171,84, +171,86,172, +88,172,86, +172,88,173, +90,173,88, +173,90,174, +92,174,90, +174,92,175, +94,175,92, +175,94,176, +96,176,94, +176,96,177, +98,177,96, +177,98,178, +100,178,98, +178,100,179, +102,179,100, +179,102,180, +104,180,102, +180,104,181, +106,181,104, +181,106,182, +108,182,106, +182,108,183, +110,183,108, +183,110,184, +112,184,110, +184,112,185, +114,185,112, +185,114,186, +116,186,114, +186,116,187, +118,187,116, +187,118,188, +120,188,118, +188,120,189, +122,189,120, +189,122,190, +124,190,122, +190,124,191, +126,191,124, +192,128,193, +129,193,128, +193,129,194, +130,194,129, +194,130,195, +131,195,130, +195,131,196, +132,196,131, +196,132,197, +133,197,132, +197,133,198, +134,198,133, +198,134,199, +135,199,134, +199,135,200, +136,200,135, +200,136,201, +137,201,136, +201,137,202, +138,202,137, +202,138,203, +139,203,138, +203,139,204, +140,204,139, +204,140,205, +141,205,140, +205,141,206, +142,206,141, +206,142,207, +143,207,142, +207,143,208, +144,208,143, +208,144,209, +145,209,144, +209,145,210, +146,210,145, +210,146,211, +147,211,146, +211,147,212, +148,212,147, +212,148,213, +149,213,148, +213,149,214, +150,214,149, +214,150,215, +151,215,150, +215,151,216, +152,216,151, +216,152,217, +153,217,152, +217,153,218, +154,218,153, +218,154,219, +155,219,154, +219,155,220, +156,220,155, +220,156,221, +157,221,156, +221,157,222, +158,222,157, +222,158,223, +159,223,158, +223,159,224, +160,224,159, +224,160,225, +161,225,160, +225,161,226, +162,226,161, +226,162,227, +163,227,162, +227,163,228, +164,228,163, +228,164,229, +165,229,164, +229,165,230, +166,230,165, +230,166,231, +167,231,166, +231,167,232, +168,232,167, +232,168,233, +169,233,168, +233,169,234, +170,234,169, +234,170,235, +171,235,170, +235,171,236, +172,236,171, +236,172,237, +173,237,172, +237,173,238, +174,238,173, +238,174,239, +175,239,174, +239,175,240, +176,240,175, +240,176,241, +177,241,176, +241,177,242, +178,242,177, +242,178,243, +179,243,178, +243,179,244, +180,244,179, +244,180,245, +181,245,180, +245,181,246, +182,246,181, +246,182,247, +183,247,182, +247,183,248, +184,248,183, +248,184,249, +185,249,184, +249,185,250, +186,250,185, +250,186,251, +187,251,186, +251,187,252, +188,252,187, +252,188,253, +189,253,188, +253,189,254, +190,254,189, +254,190,255, +191,255,190, +256,192,257, +193,257,192, +257,193,258, +194,258,193, +258,194,259, +195,259,194, +259,195,260, +196,260,195, +260,196,261, +197,261,196, +261,197,262, +198,262,197, +262,198,263, +199,263,198, +263,199,264, +200,264,199, +264,200,265, +201,265,200, +265,201,266, +202,266,201, +266,202,267, +203,267,202, +267,203,268, +204,268,203, +268,204,269, +205,269,204, +269,205,270, +206,270,205, +270,206,271, +207,271,206, +271,207,272, +208,272,207, +272,208,273, +209,273,208, +273,209,274, +210,274,209, +274,210,275, +211,275,210, +275,211,276, +212,276,211, +276,212,277, +213,277,212, +277,213,278, +214,278,213, +278,214,279, +215,279,214, +279,215,280, +216,280,215, +280,216,281, +217,281,216, +281,217,282, +218,282,217, +282,218,283, +219,283,218, +283,219,284, +220,284,219, +284,220,285, +221,285,220, +285,221,286, +222,286,221, +286,222,287, +223,287,222, +287,223,288, +224,288,223, +288,224,289, +225,289,224, +289,225,290, +226,290,225, +290,226,291, +227,291,226, +291,227,292, +228,292,227, +292,228,293, +229,293,228, +293,229,294, +230,294,229, +294,230,295, +231,295,230, +295,231,296, +232,296,231, +296,232,297, +233,297,232, +297,233,298, +234,298,233, +298,234,299, +235,299,234, +299,235,300, +236,300,235, +300,236,301, +237,301,236, +301,237,302, +238,302,237, +302,238,303, +239,303,238, +303,239,304, +240,304,239, +304,240,305, +241,305,240, +305,241,306, +242,306,241, +306,242,307, +243,307,242, +307,243,308, +244,308,243, +308,244,309, +245,309,244, +309,245,310, +246,310,245, +310,246,311, +247,311,246, +311,247,312, +248,312,247, +312,248,313, +249,313,248, +313,249,314, +250,314,249, +314,250,315, +251,315,250, +315,251,316, +252,316,251, +316,252,317, +253,317,252, +317,253,318, +254,318,253, +318,254,319, +255,319,254, +320,256,321, +257,321,256, +321,257,322, +258,322,257, +322,258,323, +259,323,258, +323,259,324, +260,324,259, +324,260,325, +261,325,260, +325,261,326, +262,326,261, +326,262,327, +263,327,262, +327,263,328, +264,328,263, +328,264,329, +265,329,264, +329,265,330, +266,330,265, +330,266,331, +267,331,266, +331,267,332, +268,332,267, +332,268,333, +269,333,268, +333,269,334, +270,334,269, +334,270,335, +271,335,270, +335,271,336, +272,336,271, +336,272,337, +273,337,272, +337,273,338, +274,338,273, +338,274,339, +275,339,274, +339,275,340, +276,340,275, +340,276,341, +277,341,276, +341,277,342, +278,342,277, +342,278,343, +279,343,278, +343,279,344, +280,344,279, +344,280,345, +281,345,280, +345,281,346, +282,346,281, +346,282,347, +283,347,282, +347,283,348, +284,348,283, +348,284,349, +285,349,284, +349,285,350, +286,350,285, +350,286,351, +287,351,286, +351,287,352, +288,352,287, +352,288,353, +289,353,288, +353,289,354, +290,354,289, +354,290,355, +291,355,290, +355,291,356, +292,356,291, +356,292,357, +293,357,292, +357,293,358, +294,358,293, +358,294,359, +295,359,294, +359,295,360, +296,360,295, +360,296,361, +297,361,296, +361,297,362, +298,362,297, +362,298,363, +299,363,298, +363,299,364, +300,364,299, +364,300,365, +301,365,300, +365,301,366, +302,366,301, +366,302,367, +303,367,302, +367,303,368, +304,368,303, +368,304,369, +305,369,304, +369,305,370, +306,370,305, +370,306,371, +307,371,306, +371,307,372, +308,372,307, +372,308,373, +309,373,308, +373,309,374, +310,374,309, +374,310,375, +311,375,310, +375,311,376, +312,376,311, +376,312,377, +313,377,312, +377,313,378, +314,378,313, +378,314,379, +315,379,314, +379,315,380, +316,380,315, +380,316,381, +317,381,316, +381,317,382, +318,382,317, +382,318,383, +319,383,318, +384,320,385, +321,385,320, +385,321,386, +322,386,321, +386,322,387, +323,387,322, +387,323,388, +324,388,323, +388,324,389, +325,389,324, +389,325,390, +326,390,325, +390,326,391, +327,391,326, +391,327,392, +328,392,327, +392,328,393, +329,393,328, +393,329,394, +330,394,329, +394,330,395, +331,395,330, +395,331,396, +332,396,331, +396,332,397, +333,397,332, +397,333,398, +334,398,333, +398,334,399, +335,399,334, +399,335,400, +336,400,335, +400,336,401, +337,401,336, +401,337,402, +338,402,337, +402,338,403, +339,403,338, +403,339,404, +340,404,339, +404,340,405, +341,405,340, +405,341,406, +342,406,341, +406,342,407, +343,407,342, +407,343,408, +344,408,343, +408,344,409, +345,409,344, +409,345,410, +346,410,345, +410,346,411, +347,411,346, +411,347,412, +348,412,347, +412,348,413, +349,413,348, +413,349,414, +350,414,349, +414,350,415, +351,415,350, +415,351,416, +352,416,351, +416,352,417, +353,417,352, +417,353,418, +354,418,353, +418,354,419, +355,419,354, +419,355,420, +356,420,355, +420,356,421, +357,421,356, +421,357,422, +358,422,357, +422,358,423, +359,423,358, +423,359,424, +360,424,359, +424,360,425, +361,425,360, +425,361,426, +362,426,361, +426,362,427, +363,427,362, +427,363,428, +364,428,363, +428,364,429, +365,429,364, +429,365,430, +366,430,365, +430,366,431, +367,431,366, +431,367,432, +368,432,367, +432,368,433, +369,433,368, +433,369,434, +370,434,369, +434,370,435, +371,435,370, +435,371,436, +372,436,371, +436,372,437, +373,437,372, +437,373,438, +374,438,373, +438,374,439, +375,439,374, +439,375,440, +376,440,375, +440,376,441, +377,441,376, +441,377,442, +378,442,377, +442,378,443, +379,443,378, +443,379,444, +380,444,379, +444,380,445, +381,445,380, +445,381,446, +382,446,381, +446,382,447, +383,447,382, +448,384,449, +385,449,384, +449,385,450, +386,450,385, +450,386,451, +387,451,386, +451,387,452, +388,452,387, +452,388,453, +389,453,388, +453,389,454, +390,454,389, +454,390,455, +391,455,390, +455,391,456, +392,456,391, +456,392,457, +393,457,392, +457,393,458, +394,458,393, +458,394,459, +395,459,394, +459,395,460, +396,460,395, +460,396,461, +397,461,396, +461,397,462, +398,462,397, +462,398,463, +399,463,398, +463,399,464, +400,464,399, +464,400,465, +401,465,400, +465,401,466, +402,466,401, +466,402,467, +403,467,402, +467,403,468, +404,468,403, +468,404,469, +405,469,404, +469,405,470, +406,470,405, +470,406,471, +407,471,406, +471,407,472, +408,472,407, +472,408,473, +409,473,408, +473,409,474, +410,474,409, +474,410,475, +411,475,410, +475,411,476, +412,476,411, +476,412,477, +413,477,412, +477,413,478, +414,478,413, +478,414,479, +415,479,414, +479,415,480, +416,480,415, +480,416,481, +417,481,416, +481,417,482, +418,482,417, +482,418,483, +419,483,418, +483,419,484, +420,484,419, +484,420,485, +421,485,420, +485,421,486, +422,486,421, +486,422,487, +423,487,422, +487,423,488, +424,488,423, +488,424,489, +425,489,424, +489,425,490, +426,490,425, +490,426,491, +427,491,426, +491,427,492, +428,492,427, +492,428,493, +429,493,428, +493,429,494, +430,494,429, +494,430,495, +431,495,430, +495,431,496, +432,496,431, +496,432,497, +433,497,432, +497,433,498, +434,498,433, +498,434,499, +435,499,434, +499,435,500, +436,500,435, +500,436,501, +437,501,436, +501,437,502, +438,502,437, +502,438,503, +439,503,438, +503,439,504, +440,504,439, +504,440,505, +441,505,440, +505,441,506, +442,506,441, +506,442,507, +443,507,442, +507,443,508, +444,508,443, +508,444,509, +445,509,444, +509,445,510, +446,510,445, +510,446,511, +447,511,446, +512,448,513, +449,513,448, +513,449,514, +450,514,449, +514,450,515, +451,515,450, +515,451,516, +452,516,451, +516,452,517, +453,517,452, +517,453,518, +454,518,453, +518,454,519, +455,519,454, +519,455,520, +456,520,455, +520,456,521, +457,521,456, +521,457,522, +458,522,457, +522,458,523, +459,523,458, +523,459,524, +460,524,459, +524,460,525, +461,525,460, +525,461,526, +462,526,461, +526,462,527, +463,527,462, +527,463,528, +464,528,463, +528,464,529, +465,529,464, +529,465,530, +466,530,465, +530,466,531, +467,531,466, +531,467,532, +468,532,467, +532,468,533, +469,533,468, +533,469,534, +470,534,469, +534,470,535, +471,535,470, +535,471,536, +472,536,471, +536,472,537, +473,537,472, +537,473,538, +474,538,473, +538,474,539, +475,539,474, +539,475,540, +476,540,475, +540,476,541, +477,541,476, +541,477,542, +478,542,477, +542,478,543, +479,543,478, +543,479,544, +480,544,479, +544,480,545, +481,545,480, +545,481,546, +482,546,481, +546,482,547, +483,547,482, +547,483,548, +484,548,483, +548,484,549, +485,549,484, +549,485,550, +486,550,485, +550,486,551, +487,551,486, +551,487,552, +488,552,487, +552,488,553, +489,553,488, +553,489,554, +490,554,489, +554,490,555, +491,555,490, +555,491,556, +492,556,491, +556,492,557, +493,557,492, +557,493,558, +494,558,493, +558,494,559, +495,559,494, +559,495,560, +496,560,495, +560,496,561, +497,561,496, +561,497,562, +498,562,497, +562,498,563, +499,563,498, +563,499,564, +500,564,499, +564,500,565, +501,565,500, +565,501,566, +502,566,501, +566,502,567, +503,567,502, +567,503,568, +504,568,503, +568,504,569, +505,569,504, +569,505,570, +506,570,505, +570,506,571, +507,571,506, +571,507,572, +508,572,507, +572,508,573, +509,573,508, +573,509,574, +510,574,509, +574,510,575, +511,575,510, +576,512,577, +513,577,512, +577,513,578, +514,578,513, +578,514,579, +515,579,514, +579,515,580, +516,580,515, +580,516,581, +517,581,516, +581,517,582, +518,582,517, +582,518,583, +519,583,518, +583,519,584, +520,584,519, +584,520,585, +521,585,520, +585,521,586, +522,586,521, +586,522,587, +523,587,522, +587,523,588, +524,588,523, +588,524,589, +525,589,524, +589,525,590, +526,590,525, +590,526,591, +527,591,526, +591,527,592, +528,592,527, +592,528,593, +529,593,528, +593,529,594, +530,594,529, +594,530,595, +531,595,530, +595,531,596, +532,596,531, +596,532,597, +533,597,532, +597,533,598, +534,598,533, +598,534,599, +535,599,534, +599,535,600, +536,600,535, +600,536,601, +537,601,536, +601,537,602, +538,602,537, +602,538,603, +539,603,538, +603,539,604, +540,604,539, +604,540,605, +541,605,540, +605,541,606, +542,606,541, +606,542,607, +543,607,542, +607,543,608, +544,608,543, +608,544,609, +545,609,544, +609,545,610, +546,610,545, +610,546,611, +547,611,546, +611,547,612, +548,612,547, +612,548,613, +549,613,548, +613,549,614, +550,614,549, +614,550,615, +551,615,550, +615,551,616, +552,616,551, +616,552,617, +553,617,552, +617,553,618, +554,618,553, +618,554,619, +555,619,554, +619,555,620, +556,620,555, +620,556,621, +557,621,556, +621,557,622, +558,622,557, +622,558,623, +559,623,558, +623,559,624, +560,624,559, +624,560,625, +561,625,560, +625,561,626, +562,626,561, +626,562,627, +563,627,562, +627,563,628, +564,628,563, +628,564,629, +565,629,564, +629,565,630, +566,630,565, +630,566,631, +567,631,566, +631,567,632, +568,632,567, +632,568,633, +569,633,568, +633,569,634, +570,634,569, +634,570,635, +571,635,570, +635,571,636, +572,636,571, +636,572,637, +573,637,572, +637,573,638, +574,638,573, +638,574,639, +575,639,574, +640,576,641, +577,641,576, +641,577,642, +578,642,577, +642,578,643, +579,643,578, +643,579,644, +580,644,579, +644,580,645, +581,645,580, +645,581,646, +582,646,581, +646,582,647, +583,647,582, +647,583,648, +584,648,583, +648,584,649, +585,649,584, +649,585,650, +586,650,585, +650,586,651, +587,651,586, +651,587,652, +588,652,587, +652,588,653, +589,653,588, +653,589,654, +590,654,589, +654,590,655, +591,655,590, +655,591,656, +592,656,591, +656,592,657, +593,657,592, +657,593,658, +594,658,593, +658,594,659, +595,659,594, +659,595,660, +596,660,595, +660,596,661, +597,661,596, +661,597,662, +598,662,597, +662,598,663, +599,663,598, +663,599,664, +600,664,599, +664,600,665, +601,665,600, +665,601,666, +602,666,601, +666,602,667, +603,667,602, +667,603,668, +604,668,603, +668,604,669, +605,669,604, +669,605,670, +606,670,605, +670,606,671, +607,671,606, +671,607,672, +608,672,607, +672,608,673, +609,673,608, +673,609,674, +610,674,609, +674,610,675, +611,675,610, +675,611,676, +612,676,611, +676,612,677, +613,677,612, +677,613,678, +614,678,613, +678,614,679, +615,679,614, +679,615,680, +616,680,615, +680,616,681, +617,681,616, +681,617,682, +618,682,617, +682,618,683, +619,683,618, +683,619,684, +620,684,619, +684,620,685, +621,685,620, +685,621,686, +622,686,621, +686,622,687, +623,687,622, +687,623,688, +624,688,623, +688,624,689, +625,689,624, +689,625,690, +626,690,625, +690,626,691, +627,691,626, +691,627,692, +628,692,627, +692,628,693, +629,693,628, +693,629,694, +630,694,629, +694,630,695, +631,695,630, +695,631,696, +632,696,631, +696,632,697, +633,697,632, +697,633,698, +634,698,633, +698,634,699, +635,699,634, +699,635,700, +636,700,635, +700,636,701, +637,701,636, +701,637,702, +638,702,637, +702,638,703, +639,703,638, +704,640,705, +641,705,640, +705,641,706, +642,706,641, +706,642,707, +643,707,642, +707,643,708, +644,708,643, +708,644,709, +645,709,644, +709,645,710, +646,710,645, +710,646,711, +647,711,646, +711,647,712, +648,712,647, +712,648,713, +649,713,648, +713,649,714, +650,714,649, +714,650,715, +651,715,650, +715,651,716, +652,716,651, +716,652,717, +653,717,652, +717,653,718, +654,718,653, +718,654,719, +655,719,654, +719,655,720, +656,720,655, +720,656,721, +657,721,656, +721,657,722, +658,722,657, +722,658,723, +659,723,658, +723,659,724, +660,724,659, +724,660,725, +661,725,660, +725,661,726, +662,726,661, +726,662,727, +663,727,662, +727,663,728, +664,728,663, +728,664,729, +665,729,664, +729,665,730, +666,730,665, +730,666,731, +667,731,666, +731,667,732, +668,732,667, +732,668,733, +669,733,668, +733,669,734, +670,734,669, +734,670,735, +671,735,670, +735,671,736, +672,736,671, +736,672,737, +673,737,672, +737,673,738, +674,738,673, +738,674,739, +675,739,674, +739,675,740, +676,740,675, +740,676,741, +677,741,676, +741,677,742, +678,742,677, +742,678,743, +679,743,678, +743,679,744, +680,744,679, +744,680,745, +681,745,680, +745,681,746, +682,746,681, +746,682,747, +683,747,682, +747,683,748, +684,748,683, +748,684,749, +685,749,684, +749,685,750, +686,750,685, +750,686,751, +687,751,686, +751,687,752, +688,752,687, +752,688,753, +689,753,688, +753,689,754, +690,754,689, +754,690,755, +691,755,690, +755,691,756, +692,756,691, +756,692,757, +693,757,692, +757,693,758, +694,758,693, +758,694,759, +695,759,694, +759,695,760, +696,760,695, +760,696,761, +697,761,696, +761,697,762, +698,762,697, +762,698,763, +699,763,698, +763,699,764, +700,764,699, +764,700,765, +701,765,700, +765,701,766, +702,766,701, +766,702,767, +703,767,702, +768,704,769, +705,769,704, +769,705,770, +706,770,705, +770,706,771, +707,771,706, +771,707,772, +708,772,707, +772,708,773, +709,773,708, +773,709,774, +710,774,709, +774,710,775, +711,775,710, +775,711,776, +712,776,711, +776,712,777, +713,777,712, +777,713,778, +714,778,713, +778,714,779, +715,779,714, +779,715,780, +716,780,715, +780,716,781, +717,781,716, +781,717,782, +718,782,717, +782,718,783, +719,783,718, +783,719,784, +720,784,719, +784,720,785, +721,785,720, +785,721,786, +722,786,721, +786,722,787, +723,787,722, +787,723,788, +724,788,723, +788,724,789, +725,789,724, +789,725,790, +726,790,725, +790,726,791, +727,791,726, +791,727,792, +728,792,727, +792,728,793, +729,793,728, +793,729,794, +730,794,729, +794,730,795, +731,795,730, +795,731,796, +732,796,731, +796,732,797, +733,797,732, +797,733,798, +734,798,733, +798,734,799, +735,799,734, +799,735,800, +736,800,735, +800,736,801, +737,801,736, +801,737,802, +738,802,737, +802,738,803, +739,803,738, +803,739,804, +740,804,739, +804,740,805, +741,805,740, +805,741,806, +742,806,741, +806,742,807, +743,807,742, +807,743,808, +744,808,743, +808,744,809, +745,809,744, +809,745,810, +746,810,745, +810,746,811, +747,811,746, +811,747,812, +748,812,747, +812,748,813, +749,813,748, +813,749,814, +750,814,749, +814,750,815, +751,815,750, +815,751,816, +752,816,751, +816,752,817, +753,817,752, +817,753,818, +754,818,753, +818,754,819, +755,819,754, +819,755,820, +756,820,755, +820,756,821, +757,821,756, +821,757,822, +758,822,757, +822,758,823, +759,823,758, +823,759,824, +760,824,759, +824,760,825, +761,825,760, +825,761,826, +762,826,761, +826,762,827, +763,827,762, +827,763,828, +764,828,763, +828,764,829, +765,829,764, +829,765,830, +766,830,765, +830,766,831, +767,831,766, +832,768,833, +769,833,768, +833,769,834, +770,834,769, +834,770,835, +771,835,770, +835,771,836, +772,836,771, +836,772,837, +773,837,772, +837,773,838, +774,838,773, +838,774,839, +775,839,774, +839,775,840, +776,840,775, +840,776,841, +777,841,776, +841,777,842, +778,842,777, +842,778,843, +779,843,778, +843,779,844, +780,844,779, +844,780,845, +781,845,780, +845,781,846, +782,846,781, +846,782,847, +783,847,782, +847,783,848, +784,848,783, +848,784,849, +785,849,784, +849,785,850, +786,850,785, +850,786,851, +787,851,786, +851,787,852, +788,852,787, +852,788,853, +789,853,788, +853,789,854, +790,854,789, +854,790,855, +791,855,790, +855,791,856, +792,856,791, +856,792,857, +793,857,792, +857,793,858, +794,858,793, +858,794,859, +795,859,794, +859,795,860, +796,860,795, +860,796,861, +797,861,796, +861,797,862, +798,862,797, +862,798,863, +799,863,798, +863,799,864, +800,864,799, +864,800,865, +801,865,800, +865,801,866, +802,866,801, +866,802,867, +803,867,802, +867,803,868, +804,868,803, +868,804,869, +805,869,804, +869,805,870, +806,870,805, +870,806,871, +807,871,806, +871,807,872, +808,872,807, +872,808,873, +809,873,808, +873,809,874, +810,874,809, +874,810,875, +811,875,810, +875,811,876, +812,876,811, +876,812,877, +813,877,812, +877,813,878, +814,878,813, +878,814,879, +815,879,814, +879,815,880, +816,880,815, +880,816,881, +817,881,816, +881,817,882, +818,882,817, +882,818,883, +819,883,818, +883,819,884, +820,884,819, +884,820,885, +821,885,820, +885,821,886, +822,886,821, +886,822,887, +823,887,822, +887,823,888, +824,888,823, +888,824,889, +825,889,824, +889,825,890, +826,890,825, +890,826,891, +827,891,826, +891,827,892, +828,892,827, +892,828,893, +829,893,828, +893,829,894, +830,894,829, +894,830,895, +831,895,830, +896,832,897, +833,897,832, +897,833,898, +834,898,833, +898,834,899, +835,899,834, +899,835,900, +836,900,835, +900,836,901, +837,901,836, +901,837,902, +838,902,837, +902,838,903, +839,903,838, +903,839,904, +840,904,839, +904,840,905, +841,905,840, +905,841,906, +842,906,841, +906,842,907, +843,907,842, +907,843,908, +844,908,843, +908,844,909, +845,909,844, +909,845,910, +846,910,845, +910,846,911, +847,911,846, +911,847,912, +848,912,847, +912,848,913, +849,913,848, +913,849,914, +850,914,849, +914,850,915, +851,915,850, +915,851,916, +852,916,851, +916,852,917, +853,917,852, +917,853,918, +854,918,853, +918,854,919, +855,919,854, +919,855,920, +856,920,855, +920,856,921, +857,921,856, +921,857,922, +858,922,857, +922,858,923, +859,923,858, +923,859,924, +860,924,859, +924,860,925, +861,925,860, +925,861,926, +862,926,861, +926,862,927, +863,927,862, +927,863,928, +864,928,863, +928,864,929, +865,929,864, +929,865,930, +866,930,865, +930,866,931, +867,931,866, +931,867,932, +868,932,867, +932,868,933, +869,933,868, +933,869,934, +870,934,869, +934,870,935, +871,935,870, +935,871,936, +872,936,871, +936,872,937, +873,937,872, +937,873,938, +874,938,873, +938,874,939, +875,939,874, +939,875,940, +876,940,875, +940,876,941, +877,941,876, +941,877,942, +878,942,877, +942,878,943, +879,943,878, +943,879,944, +880,944,879, +944,880,945, +881,945,880, +945,881,946, +882,946,881, +946,882,947, +883,947,882, +947,883,948, +884,948,883, +948,884,949, +885,949,884, +949,885,950, +886,950,885, +950,886,951, +887,951,886, +951,887,952, +888,952,887, +952,888,953, +889,953,888, +953,889,954, +890,954,889, +954,890,955, +891,955,890, +955,891,956, +892,956,891, +956,892,957, +893,957,892, +957,893,958, +894,958,893, +958,894,959, +895,959,894, +960,896,961, +897,961,896, +961,897,962, +898,962,897, +962,898,963, +899,963,898, +963,899,964, +900,964,899, +964,900,965, +901,965,900, +965,901,966, +902,966,901, +966,902,967, +903,967,902, +967,903,968, +904,968,903, +968,904,969, +905,969,904, +969,905,970, +906,970,905, +970,906,971, +907,971,906, +971,907,972, +908,972,907, +972,908,973, +909,973,908, +973,909,974, +910,974,909, +974,910,975, +911,975,910, +975,911,976, +912,976,911, +976,912,977, +913,977,912, +977,913,978, +914,978,913, +978,914,979, +915,979,914, +979,915,980, +916,980,915, +980,916,981, +917,981,916, +981,917,982, +918,982,917, +982,918,983, +919,983,918, +983,919,984, +920,984,919, +984,920,985, +921,985,920, +985,921,986, +922,986,921, +986,922,987, +923,987,922, +987,923,988, +924,988,923, +988,924,989, +925,989,924, +989,925,990, +926,990,925, +990,926,991, +927,991,926, +991,927,992, +928,992,927, +992,928,993, +929,993,928, +993,929,994, +930,994,929, +994,930,995, +931,995,930, +995,931,996, +932,996,931, +996,932,997, +933,997,932, +997,933,998, +934,998,933, +998,934,999, +935,999,934, +999,935,1000, +936,1000,935, +1000,936,1001, +937,1001,936, +1001,937,1002, +938,1002,937, +1002,938,1003, +939,1003,938, +1003,939,1004, +940,1004,939, +1004,940,1005, +941,1005,940, +1005,941,1006, +942,1006,941, +1006,942,1007, +943,1007,942, +1007,943,1008, +944,1008,943, +1008,944,1009, +945,1009,944, +1009,945,1010, +946,1010,945, +1010,946,1011, +947,1011,946, +1011,947,1012, +948,1012,947, +1012,948,1013, +949,1013,948, +1013,949,1014, +950,1014,949, +1014,950,1015, +951,1015,950, +1015,951,1016, +952,1016,951, +1016,952,1017, +953,1017,952, +1017,953,1018, +954,1018,953, +1018,954,1019, +955,1019,954, +1019,955,1020, +956,1020,955, +1020,956,1021, +957,1021,956, +1021,957,1022, +958,1022,957, +1022,958,1023, +959,1023,958, +1024,960,1025, +961,1025,960, +1025,961,1026, +962,1026,961, +1026,962,1027, +963,1027,962, +1027,963,1028, +964,1028,963, +1028,964,1029, +965,1029,964, +1029,965,1030, +966,1030,965, +1030,966,1031, +967,1031,966, +1031,967,1032, +968,1032,967, +1032,968,1033, +969,1033,968, +1033,969,1034, +970,1034,969, +1034,970,1035, +971,1035,970, +1035,971,1036, +972,1036,971, +1036,972,1037, +973,1037,972, +1037,973,1038, +974,1038,973, +1038,974,1039, +975,1039,974, +1039,975,1040, +976,1040,975, +1040,976,1041, +977,1041,976, +1041,977,1042, +978,1042,977, +1042,978,1043, +979,1043,978, +1043,979,1044, +980,1044,979, +1044,980,1045, +981,1045,980, +1045,981,1046, +982,1046,981, +1046,982,1047, +983,1047,982, +1047,983,1048, +984,1048,983, +1048,984,1049, +985,1049,984, +1049,985,1050, +986,1050,985, +1050,986,1051, +987,1051,986, +1051,987,1052, +988,1052,987, +1052,988,1053, +989,1053,988, +1053,989,1054, +990,1054,989, +1054,990,1055, +991,1055,990, +1055,991,1056, +992,1056,991, +1056,992,1057, +993,1057,992, +1057,993,1058, +994,1058,993, +1058,994,1059, +995,1059,994, +1059,995,1060, +996,1060,995, +1060,996,1061, +997,1061,996, +1061,997,1062, +998,1062,997, +1062,998,1063, +999,1063,998, +1063,999,1064, +1000,1064,999, +1064,1000,1065, +1001,1065,1000, +1065,1001,1066, +1002,1066,1001, +1066,1002,1067, +1003,1067,1002, +1067,1003,1068, +1004,1068,1003, +1068,1004,1069, +1005,1069,1004, +1069,1005,1070, +1006,1070,1005, +1070,1006,1071, +1007,1071,1006, +1071,1007,1072, +1008,1072,1007, +1072,1008,1073, +1009,1073,1008, +1073,1009,1074, +1010,1074,1009, +1074,1010,1075, +1011,1075,1010, +1075,1011,1076, +1012,1076,1011, +1076,1012,1077, +1013,1077,1012, +1077,1013,1078, +1014,1078,1013, +1078,1014,1079, +1015,1079,1014, +1079,1015,1080, +1016,1080,1015, +1080,1016,1081, +1017,1081,1016, +1081,1017,1082, +1018,1082,1017, +1082,1018,1083, +1019,1083,1018, +1083,1019,1084, +1020,1084,1019, +1084,1020,1085, +1021,1085,1020, +1085,1021,1086, +1022,1086,1021, +1086,1022,1087, +1023,1087,1022, +1088,1024,1089, +1025,1089,1024, +1089,1025,1090, +1026,1090,1025, +1090,1026,1091, +1027,1091,1026, +1091,1027,1092, +1028,1092,1027, +1092,1028,1093, +1029,1093,1028, +1093,1029,1094, +1030,1094,1029, +1094,1030,1095, +1031,1095,1030, +1095,1031,1096, +1032,1096,1031, +1096,1032,1097, +1033,1097,1032, +1097,1033,1098, +1034,1098,1033, +1098,1034,1099, +1035,1099,1034, +1099,1035,1100, +1036,1100,1035, +1100,1036,1101, +1037,1101,1036, +1101,1037,1102, +1038,1102,1037, +1102,1038,1103, +1039,1103,1038, +1103,1039,1104, +1040,1104,1039, +1104,1040,1105, +1041,1105,1040, +1105,1041,1106, +1042,1106,1041, +1106,1042,1107, +1043,1107,1042, +1107,1043,1108, +1044,1108,1043, +1108,1044,1109, +1045,1109,1044, +1109,1045,1110, +1046,1110,1045, +1110,1046,1111, +1047,1111,1046, +1111,1047,1112, +1048,1112,1047, +1112,1048,1113, +1049,1113,1048, +1113,1049,1114, +1050,1114,1049, +1114,1050,1115, +1051,1115,1050, +1115,1051,1116, +1052,1116,1051, +1116,1052,1117, +1053,1117,1052, +1117,1053,1118, +1054,1118,1053, +1118,1054,1119, +1055,1119,1054, +1119,1055,1120, +1056,1120,1055, +1120,1056,1121, +1057,1121,1056, +1121,1057,1122, +1058,1122,1057, +1122,1058,1123, +1059,1123,1058, +1123,1059,1124, +1060,1124,1059, +1124,1060,1125, +1061,1125,1060, +1125,1061,1126, +1062,1126,1061, +1126,1062,1127, +1063,1127,1062, +1127,1063,1128, +1064,1128,1063, +1128,1064,1129, +1065,1129,1064, +1129,1065,1130, +1066,1130,1065, +1130,1066,1131, +1067,1131,1066, +1131,1067,1132, +1068,1132,1067, +1132,1068,1133, +1069,1133,1068, +1133,1069,1134, +1070,1134,1069, +1134,1070,1135, +1071,1135,1070, +1135,1071,1136, +1072,1136,1071, +1136,1072,1137, +1073,1137,1072, +1137,1073,1138, +1074,1138,1073, +1138,1074,1139, +1075,1139,1074, +1139,1075,1140, +1076,1140,1075, +1140,1076,1141, +1077,1141,1076, +1141,1077,1142, +1078,1142,1077, +1142,1078,1143, +1079,1143,1078, +1143,1079,1144, +1080,1144,1079, +1144,1080,1145, +1081,1145,1080, +1145,1081,1146, +1082,1146,1081, +1146,1082,1147, +1083,1147,1082, +1147,1083,1148, +1084,1148,1083, +1148,1084,1149, +1085,1149,1084, +1149,1085,1150, +1086,1150,1085, +1150,1086,1151, +1087,1151,1086, +1152,1088,1153, +1089,1153,1088, +1153,1089,1154, +1090,1154,1089, +1154,1090,1155, +1091,1155,1090, +1155,1091,1156, +1092,1156,1091, +1156,1092,1157, +1093,1157,1092, +1157,1093,1158, +1094,1158,1093, +1158,1094,1159, +1095,1159,1094, +1159,1095,1160, +1096,1160,1095, +1160,1096,1161, +1097,1161,1096, +1161,1097,1162, +1098,1162,1097, +1162,1098,1163, +1099,1163,1098, +1163,1099,1164, +1100,1164,1099, +1164,1100,1165, +1101,1165,1100, +1165,1101,1166, +1102,1166,1101, +1166,1102,1167, +1103,1167,1102, +1167,1103,1168, +1104,1168,1103, +1168,1104,1169, +1105,1169,1104, +1169,1105,1170, +1106,1170,1105, +1170,1106,1171, +1107,1171,1106, +1171,1107,1172, +1108,1172,1107, +1172,1108,1173, +1109,1173,1108, +1173,1109,1174, +1110,1174,1109, +1174,1110,1175, +1111,1175,1110, +1175,1111,1176, +1112,1176,1111, +1176,1112,1177, +1113,1177,1112, +1177,1113,1178, +1114,1178,1113, +1178,1114,1179, +1115,1179,1114, +1179,1115,1180, +1116,1180,1115, +1180,1116,1181, +1117,1181,1116, +1181,1117,1182, +1118,1182,1117, +1182,1118,1183, +1119,1183,1118, +1183,1119,1184, +1120,1184,1119, +1184,1120,1185, +1121,1185,1120, +1185,1121,1186, +1122,1186,1121, +1186,1122,1187, +1123,1187,1122, +1187,1123,1188, +1124,1188,1123, +1188,1124,1189, +1125,1189,1124, +1189,1125,1190, +1126,1190,1125, +1190,1126,1191, +1127,1191,1126, +1191,1127,1192, +1128,1192,1127, +1192,1128,1193, +1129,1193,1128, +1193,1129,1194, +1130,1194,1129, +1194,1130,1195, +1131,1195,1130, +1195,1131,1196, +1132,1196,1131, +1196,1132,1197, +1133,1197,1132, +1197,1133,1198, +1134,1198,1133, +1198,1134,1199, +1135,1199,1134, +1199,1135,1200, +1136,1200,1135, +1200,1136,1201, +1137,1201,1136, +1201,1137,1202, +1138,1202,1137, +1202,1138,1203, +1139,1203,1138, +1203,1139,1204, +1140,1204,1139, +1204,1140,1205, +1141,1205,1140, +1205,1141,1206, +1142,1206,1141, +1206,1142,1207, +1143,1207,1142, +1207,1143,1208, +1144,1208,1143, +1208,1144,1209, +1145,1209,1144, +1209,1145,1210, +1146,1210,1145, +1210,1146,1211, +1147,1211,1146, +1211,1147,1212, +1148,1212,1147, +1212,1148,1213, +1149,1213,1148, +1213,1149,1214, +1150,1214,1149, +1214,1150,1215, +1151,1215,1150, +1216,1152,1217, +1153,1217,1152, +1217,1153,1218, +1154,1218,1153, +1218,1154,1219, +1155,1219,1154, +1219,1155,1220, +1156,1220,1155, +1220,1156,1221, +1157,1221,1156, +1221,1157,1222, +1158,1222,1157, +1222,1158,1223, +1159,1223,1158, +1223,1159,1224, +1160,1224,1159, +1224,1160,1225, +1161,1225,1160, +1225,1161,1226, +1162,1226,1161, +1226,1162,1227, +1163,1227,1162, +1227,1163,1228, +1164,1228,1163, +1228,1164,1229, +1165,1229,1164, +1229,1165,1230, +1166,1230,1165, +1230,1166,1231, +1167,1231,1166, +1231,1167,1232, +1168,1232,1167, +1232,1168,1233, +1169,1233,1168, +1233,1169,1234, +1170,1234,1169, +1234,1170,1235, +1171,1235,1170, +1235,1171,1236, +1172,1236,1171, +1236,1172,1237, +1173,1237,1172, +1237,1173,1238, +1174,1238,1173, +1238,1174,1239, +1175,1239,1174, +1239,1175,1240, +1176,1240,1175, +1240,1176,1241, +1177,1241,1176, +1241,1177,1242, +1178,1242,1177, +1242,1178,1243, +1179,1243,1178, +1243,1179,1244, +1180,1244,1179, +1244,1180,1245, +1181,1245,1180, +1245,1181,1246, +1182,1246,1181, +1246,1182,1247, +1183,1247,1182, +1247,1183,1248, +1184,1248,1183, +1248,1184,1249, +1185,1249,1184, +1249,1185,1250, +1186,1250,1185, +1250,1186,1251, +1187,1251,1186, +1251,1187,1252, +1188,1252,1187, +1252,1188,1253, +1189,1253,1188, +1253,1189,1254, +1190,1254,1189, +1254,1190,1255, +1191,1255,1190, +1255,1191,1256, +1192,1256,1191, +1256,1192,1257, +1193,1257,1192, +1257,1193,1258, +1194,1258,1193, +1258,1194,1259, +1195,1259,1194, +1259,1195,1260, +1196,1260,1195, +1260,1196,1261, +1197,1261,1196, +1261,1197,1262, +1198,1262,1197, +1262,1198,1263, +1199,1263,1198, +1263,1199,1264, +1200,1264,1199, +1264,1200,1265, +1201,1265,1200, +1265,1201,1266, +1202,1266,1201, +1266,1202,1267, +1203,1267,1202, +1267,1203,1268, +1204,1268,1203, +1268,1204,1269, +1205,1269,1204, +1269,1205,1270, +1206,1270,1205, +1270,1206,1271, +1207,1271,1206, +1271,1207,1272, +1208,1272,1207, +1272,1208,1273, +1209,1273,1208, +1273,1209,1274, +1210,1274,1209, +1274,1210,1275, +1211,1275,1210, +1275,1211,1276, +1212,1276,1211, +1276,1212,1277, +1213,1277,1212, +1277,1213,1278, +1214,1278,1213, +1278,1214,1279, +1215,1279,1214, +1280,1216,1281, +1217,1281,1216, +1281,1217,1282, +1218,1282,1217, +1282,1218,1283, +1219,1283,1218, +1283,1219,1284, +1220,1284,1219, +1284,1220,1285, +1221,1285,1220, +1285,1221,1286, +1222,1286,1221, +1286,1222,1287, +1223,1287,1222, +1287,1223,1288, +1224,1288,1223, +1288,1224,1289, +1225,1289,1224, +1289,1225,1290, +1226,1290,1225, +1290,1226,1291, +1227,1291,1226, +1291,1227,1292, +1228,1292,1227, +1292,1228,1293, +1229,1293,1228, +1293,1229,1294, +1230,1294,1229, +1294,1230,1295, +1231,1295,1230, +1295,1231,1296, +1232,1296,1231, +1296,1232,1297, +1233,1297,1232, +1297,1233,1298, +1234,1298,1233, +1298,1234,1299, +1235,1299,1234, +1299,1235,1300, +1236,1300,1235, +1300,1236,1301, +1237,1301,1236, +1301,1237,1302, +1238,1302,1237, +1302,1238,1303, +1239,1303,1238, +1303,1239,1304, +1240,1304,1239, +1304,1240,1305, +1241,1305,1240, +1305,1241,1306, +1242,1306,1241, +1306,1242,1307, +1243,1307,1242, +1307,1243,1308, +1244,1308,1243, +1308,1244,1309, +1245,1309,1244, +1309,1245,1310, +1246,1310,1245, +1310,1246,1311, +1247,1311,1246, +1311,1247,1312, +1248,1312,1247, +1312,1248,1313, +1249,1313,1248, +1313,1249,1314, +1250,1314,1249, +1314,1250,1315, +1251,1315,1250, +1315,1251,1316, +1252,1316,1251, +1316,1252,1317, +1253,1317,1252, +1317,1253,1318, +1254,1318,1253, +1318,1254,1319, +1255,1319,1254, +1319,1255,1320, +1256,1320,1255, +1320,1256,1321, +1257,1321,1256, +1321,1257,1322, +1258,1322,1257, +1322,1258,1323, +1259,1323,1258, +1323,1259,1324, +1260,1324,1259, +1324,1260,1325, +1261,1325,1260, +1325,1261,1326, +1262,1326,1261, +1326,1262,1327, +1263,1327,1262, +1327,1263,1328, +1264,1328,1263, +1328,1264,1329, +1265,1329,1264, +1329,1265,1330, +1266,1330,1265, +1330,1266,1331, +1267,1331,1266, +1331,1267,1332, +1268,1332,1267, +1332,1268,1333, +1269,1333,1268, +1333,1269,1334, +1270,1334,1269, +1334,1270,1335, +1271,1335,1270, +1335,1271,1336, +1272,1336,1271, +1336,1272,1337, +1273,1337,1272, +1337,1273,1338, +1274,1338,1273, +1338,1274,1339, +1275,1339,1274, +1339,1275,1340, +1276,1340,1275, +1340,1276,1341, +1277,1341,1276, +1341,1277,1342, +1278,1342,1277, +1342,1278,1343, +1279,1343,1278, +1344,1280,1345, +1281,1345,1280, +1345,1281,1346, +1282,1346,1281, +1346,1282,1347, +1283,1347,1282, +1347,1283,1348, +1284,1348,1283, +1348,1284,1349, +1285,1349,1284, +1349,1285,1350, +1286,1350,1285, +1350,1286,1351, +1287,1351,1286, +1351,1287,1352, +1288,1352,1287, +1352,1288,1353, +1289,1353,1288, +1353,1289,1354, +1290,1354,1289, +1354,1290,1355, +1291,1355,1290, +1355,1291,1356, +1292,1356,1291, +1356,1292,1357, +1293,1357,1292, +1357,1293,1358, +1294,1358,1293, +1358,1294,1359, +1295,1359,1294, +1359,1295,1360, +1296,1360,1295, +1360,1296,1361, +1297,1361,1296, +1361,1297,1362, +1298,1362,1297, +1362,1298,1363, +1299,1363,1298, +1363,1299,1364, +1300,1364,1299, +1364,1300,1365, +1301,1365,1300, +1365,1301,1366, +1302,1366,1301, +1366,1302,1367, +1303,1367,1302, +1367,1303,1368, +1304,1368,1303, +1368,1304,1369, +1305,1369,1304, +1369,1305,1370, +1306,1370,1305, +1370,1306,1371, +1307,1371,1306, +1371,1307,1372, +1308,1372,1307, +1372,1308,1373, +1309,1373,1308, +1373,1309,1374, +1310,1374,1309, +1374,1310,1375, +1311,1375,1310, +1375,1311,1376, +1312,1376,1311, +1376,1312,1377, +1313,1377,1312, +1377,1313,1378, +1314,1378,1313, +1378,1314,1379, +1315,1379,1314, +1379,1315,1380, +1316,1380,1315, +1380,1316,1381, +1317,1381,1316, +1381,1317,1382, +1318,1382,1317, +1382,1318,1383, +1319,1383,1318, +1383,1319,1384, +1320,1384,1319, +1384,1320,1385, +1321,1385,1320, +1385,1321,1386, +1322,1386,1321, +1386,1322,1387, +1323,1387,1322, +1387,1323,1388, +1324,1388,1323, +1388,1324,1389, +1325,1389,1324, +1389,1325,1390, +1326,1390,1325, +1390,1326,1391, +1327,1391,1326, +1391,1327,1392, +1328,1392,1327, +1392,1328,1393, +1329,1393,1328, +1393,1329,1394, +1330,1394,1329, +1394,1330,1395, +1331,1395,1330, +1395,1331,1396, +1332,1396,1331, +1396,1332,1397, +1333,1397,1332, +1397,1333,1398, +1334,1398,1333, +1398,1334,1399, +1335,1399,1334, +1399,1335,1400, +1336,1400,1335, +1400,1336,1401, +1337,1401,1336, +1401,1337,1402, +1338,1402,1337, +1402,1338,1403, +1339,1403,1338, +1403,1339,1404, +1340,1404,1339, +1404,1340,1405, +1341,1405,1340, +1405,1341,1406, +1342,1406,1341, +1406,1342,1407, +1343,1407,1342, +1408,1344,1409, +1345,1409,1344, +1409,1345,1410, +1346,1410,1345, +1410,1346,1411, +1347,1411,1346, +1411,1347,1412, +1348,1412,1347, +1412,1348,1413, +1349,1413,1348, +1413,1349,1414, +1350,1414,1349, +1414,1350,1415, +1351,1415,1350, +1415,1351,1416, +1352,1416,1351, +1416,1352,1417, +1353,1417,1352, +1417,1353,1418, +1354,1418,1353, +1418,1354,1419, +1355,1419,1354, +1419,1355,1420, +1356,1420,1355, +1420,1356,1421, +1357,1421,1356, +1421,1357,1422, +1358,1422,1357, +1422,1358,1423, +1359,1423,1358, +1423,1359,1424, +1360,1424,1359, +1424,1360,1425, +1361,1425,1360, +1425,1361,1426, +1362,1426,1361, +1426,1362,1427, +1363,1427,1362, +1427,1363,1428, +1364,1428,1363, +1428,1364,1429, +1365,1429,1364, +1429,1365,1430, +1366,1430,1365, +1430,1366,1431, +1367,1431,1366, +1431,1367,1432, +1368,1432,1367, +1432,1368,1433, +1369,1433,1368, +1433,1369,1434, +1370,1434,1369, +1434,1370,1435, +1371,1435,1370, +1435,1371,1436, +1372,1436,1371, +1436,1372,1437, +1373,1437,1372, +1437,1373,1438, +1374,1438,1373, +1438,1374,1439, +1375,1439,1374, +1439,1375,1440, +1376,1440,1375, +1440,1376,1441, +1377,1441,1376, +1441,1377,1442, +1378,1442,1377, +1442,1378,1443, +1379,1443,1378, +1443,1379,1444, +1380,1444,1379, +1444,1380,1445, +1381,1445,1380, +1445,1381,1446, +1382,1446,1381, +1446,1382,1447, +1383,1447,1382, +1447,1383,1448, +1384,1448,1383, +1448,1384,1449, +1385,1449,1384, +1449,1385,1450, +1386,1450,1385, +1450,1386,1451, +1387,1451,1386, +1451,1387,1452, +1388,1452,1387, +1452,1388,1453, +1389,1453,1388, +1453,1389,1454, +1390,1454,1389, +1454,1390,1455, +1391,1455,1390, +1455,1391,1456, +1392,1456,1391, +1456,1392,1457, +1393,1457,1392, +1457,1393,1458, +1394,1458,1393, +1458,1394,1459, +1395,1459,1394, +1459,1395,1460, +1396,1460,1395, +1460,1396,1461, +1397,1461,1396, +1461,1397,1462, +1398,1462,1397, +1462,1398,1463, +1399,1463,1398, +1463,1399,1464, +1400,1464,1399, +1464,1400,1465, +1401,1465,1400, +1465,1401,1466, +1402,1466,1401, +1466,1402,1467, +1403,1467,1402, +1467,1403,1468, +1404,1468,1403, +1468,1404,1469, +1405,1469,1404, +1469,1405,1470, +1406,1470,1405, +1470,1406,1471, +1407,1471,1406, +1472,1408,1473, +1409,1473,1408, +1473,1409,1474, +1410,1474,1409, +1474,1410,1475, +1411,1475,1410, +1475,1411,1476, +1412,1476,1411, +1476,1412,1477, +1413,1477,1412, +1477,1413,1478, +1414,1478,1413, +1478,1414,1479, +1415,1479,1414, +1479,1415,1480, +1416,1480,1415, +1480,1416,1481, +1417,1481,1416, +1481,1417,1482, +1418,1482,1417, +1482,1418,1483, +1419,1483,1418, +1483,1419,1484, +1420,1484,1419, +1484,1420,1485, +1421,1485,1420, +1485,1421,1486, +1422,1486,1421, +1486,1422,1487, +1423,1487,1422, +1487,1423,1488, +1424,1488,1423, +1488,1424,1489, +1425,1489,1424, +1489,1425,1490, +1426,1490,1425, +1490,1426,1491, +1427,1491,1426, +1491,1427,1492, +1428,1492,1427, +1492,1428,1493, +1429,1493,1428, +1493,1429,1494, +1430,1494,1429, +1494,1430,1495, +1431,1495,1430, +1495,1431,1496, +1432,1496,1431, +1496,1432,1497, +1433,1497,1432, +1497,1433,1498, +1434,1498,1433, +1498,1434,1499, +1435,1499,1434, +1499,1435,1500, +1436,1500,1435, +1500,1436,1501, +1437,1501,1436, +1501,1437,1502, +1438,1502,1437, +1502,1438,1503, +1439,1503,1438, +1503,1439,1504, +1440,1504,1439, +1504,1440,1505, +1441,1505,1440, +1505,1441,1506, +1442,1506,1441, +1506,1442,1507, +1443,1507,1442, +1507,1443,1508, +1444,1508,1443, +1508,1444,1509, +1445,1509,1444, +1509,1445,1510, +1446,1510,1445, +1510,1446,1511, +1447,1511,1446, +1511,1447,1512, +1448,1512,1447, +1512,1448,1513, +1449,1513,1448, +1513,1449,1514, +1450,1514,1449, +1514,1450,1515, +1451,1515,1450, +1515,1451,1516, +1452,1516,1451, +1516,1452,1517, +1453,1517,1452, +1517,1453,1518, +1454,1518,1453, +1518,1454,1519, +1455,1519,1454, +1519,1455,1520, +1456,1520,1455, +1520,1456,1521, +1457,1521,1456, +1521,1457,1522, +1458,1522,1457, +1522,1458,1523, +1459,1523,1458, +1523,1459,1524, +1460,1524,1459, +1524,1460,1525, +1461,1525,1460, +1525,1461,1526, +1462,1526,1461, +1526,1462,1527, +1463,1527,1462, +1527,1463,1528, +1464,1528,1463, +1528,1464,1529, +1465,1529,1464, +1529,1465,1530, +1466,1530,1465, +1530,1466,1531, +1467,1531,1466, +1531,1467,1532, +1468,1532,1467, +1532,1468,1533, +1469,1533,1468, +1533,1469,1534, +1470,1534,1469, +1534,1470,1535, +1471,1535,1470, +1536,1472,1537, +1473,1537,1472, +1537,1473,1538, +1474,1538,1473, +1538,1474,1539, +1475,1539,1474, +1539,1475,1540, +1476,1540,1475, +1540,1476,1541, +1477,1541,1476, +1541,1477,1542, +1478,1542,1477, +1542,1478,1543, +1479,1543,1478, +1543,1479,1544, +1480,1544,1479, +1544,1480,1545, +1481,1545,1480, +1545,1481,1546, +1482,1546,1481, +1546,1482,1547, +1483,1547,1482, +1547,1483,1548, +1484,1548,1483, +1548,1484,1549, +1485,1549,1484, +1549,1485,1550, +1486,1550,1485, +1550,1486,1551, +1487,1551,1486, +1551,1487,1552, +1488,1552,1487, +1552,1488,1553, +1489,1553,1488, +1553,1489,1554, +1490,1554,1489, +1554,1490,1555, +1491,1555,1490, +1555,1491,1556, +1492,1556,1491, +1556,1492,1557, +1493,1557,1492, +1557,1493,1558, +1494,1558,1493, +1558,1494,1559, +1495,1559,1494, +1559,1495,1560, +1496,1560,1495, +1560,1496,1561, +1497,1561,1496, +1561,1497,1562, +1498,1562,1497, +1562,1498,1563, +1499,1563,1498, +1563,1499,1564, +1500,1564,1499, +1564,1500,1565, +1501,1565,1500, +1565,1501,1566, +1502,1566,1501, +1566,1502,1567, +1503,1567,1502, +1567,1503,1568, +1504,1568,1503, +1568,1504,1569, +1505,1569,1504, +1569,1505,1570, +1506,1570,1505, +1570,1506,1571, +1507,1571,1506, +1571,1507,1572, +1508,1572,1507, +1572,1508,1573, +1509,1573,1508, +1573,1509,1574, +1510,1574,1509, +1574,1510,1575, +1511,1575,1510, +1575,1511,1576, +1512,1576,1511, +1576,1512,1577, +1513,1577,1512, +1577,1513,1578, +1514,1578,1513, +1578,1514,1579, +1515,1579,1514, +1579,1515,1580, +1516,1580,1515, +1580,1516,1581, +1517,1581,1516, +1581,1517,1582, +1518,1582,1517, +1582,1518,1583, +1519,1583,1518, +1583,1519,1584, +1520,1584,1519, +1584,1520,1585, +1521,1585,1520, +1585,1521,1586, +1522,1586,1521, +1586,1522,1587, +1523,1587,1522, +1587,1523,1588, +1524,1588,1523, +1588,1524,1589, +1525,1589,1524, +1589,1525,1590, +1526,1590,1525, +1590,1526,1591, +1527,1591,1526, +1591,1527,1592, +1528,1592,1527, +1592,1528,1593, +1529,1593,1528, +1593,1529,1594, +1530,1594,1529, +1594,1530,1595, +1531,1595,1530, +1595,1531,1596, +1532,1596,1531, +1596,1532,1597, +1533,1597,1532, +1597,1533,1598, +1534,1598,1533, +1598,1534,1599, +1535,1599,1534, +1600,1536,1601, +1537,1601,1536, +1601,1537,1602, +1538,1602,1537, +1602,1538,1603, +1539,1603,1538, +1603,1539,1604, +1540,1604,1539, +1604,1540,1605, +1541,1605,1540, +1605,1541,1606, +1542,1606,1541, +1606,1542,1607, +1543,1607,1542, +1607,1543,1608, +1544,1608,1543, +1608,1544,1609, +1545,1609,1544, +1609,1545,1610, +1546,1610,1545, +1610,1546,1611, +1547,1611,1546, +1611,1547,1612, +1548,1612,1547, +1612,1548,1613, +1549,1613,1548, +1613,1549,1614, +1550,1614,1549, +1614,1550,1615, +1551,1615,1550, +1615,1551,1616, +1552,1616,1551, +1616,1552,1617, +1553,1617,1552, +1617,1553,1618, +1554,1618,1553, +1618,1554,1619, +1555,1619,1554, +1619,1555,1620, +1556,1620,1555, +1620,1556,1621, +1557,1621,1556, +1621,1557,1622, +1558,1622,1557, +1622,1558,1623, +1559,1623,1558, +1623,1559,1624, +1560,1624,1559, +1624,1560,1625, +1561,1625,1560, +1625,1561,1626, +1562,1626,1561, +1626,1562,1627, +1563,1627,1562, +1627,1563,1628, +1564,1628,1563, +1628,1564,1629, +1565,1629,1564, +1629,1565,1630, +1566,1630,1565, +1630,1566,1631, +1567,1631,1566, +1631,1567,1632, +1568,1632,1567, +1632,1568,1633, +1569,1633,1568, +1633,1569,1634, +1570,1634,1569, +1634,1570,1635, +1571,1635,1570, +1635,1571,1636, +1572,1636,1571, +1636,1572,1637, +1573,1637,1572, +1637,1573,1638, +1574,1638,1573, +1638,1574,1639, +1575,1639,1574, +1639,1575,1640, +1576,1640,1575, +1640,1576,1641, +1577,1641,1576, +1641,1577,1642, +1578,1642,1577, +1642,1578,1643, +1579,1643,1578, +1643,1579,1644, +1580,1644,1579, +1644,1580,1645, +1581,1645,1580, +1645,1581,1646, +1582,1646,1581, +1646,1582,1647, +1583,1647,1582, +1647,1583,1648, +1584,1648,1583, +1648,1584,1649, +1585,1649,1584, +1649,1585,1650, +1586,1650,1585, +1650,1586,1651, +1587,1651,1586, +1651,1587,1652, +1588,1652,1587, +1652,1588,1653, +1589,1653,1588, +1653,1589,1654, +1590,1654,1589, +1654,1590,1655, +1591,1655,1590, +1655,1591,1656, +1592,1656,1591, +1656,1592,1657, +1593,1657,1592, +1657,1593,1658, +1594,1658,1593, +1658,1594,1659, +1595,1659,1594, +1659,1595,1660, +1596,1660,1595, +1660,1596,1661, +1597,1661,1596, +1661,1597,1662, +1598,1662,1597, +1662,1598,1663, +1599,1663,1598, +1664,1600,1665, +1601,1665,1600, +1665,1601,1666, +1602,1666,1601, +1666,1602,1667, +1603,1667,1602, +1667,1603,1668, +1604,1668,1603, +1668,1604,1669, +1605,1669,1604, +1669,1605,1670, +1606,1670,1605, +1670,1606,1671, +1607,1671,1606, +1671,1607,1672, +1608,1672,1607, +1672,1608,1673, +1609,1673,1608, +1673,1609,1674, +1610,1674,1609, +1674,1610,1675, +1611,1675,1610, +1675,1611,1676, +1612,1676,1611, +1676,1612,1677, +1613,1677,1612, +1677,1613,1678, +1614,1678,1613, +1678,1614,1679, +1615,1679,1614, +1679,1615,1680, +1616,1680,1615, +1680,1616,1681, +1617,1681,1616, +1681,1617,1682, +1618,1682,1617, +1682,1618,1683, +1619,1683,1618, +1683,1619,1684, +1620,1684,1619, +1684,1620,1685, +1621,1685,1620, +1685,1621,1686, +1622,1686,1621, +1686,1622,1687, +1623,1687,1622, +1687,1623,1688, +1624,1688,1623, +1688,1624,1689, +1625,1689,1624, +1689,1625,1690, +1626,1690,1625, +1690,1626,1691, +1627,1691,1626, +1691,1627,1692, +1628,1692,1627, +1692,1628,1693, +1629,1693,1628, +1693,1629,1694, +1630,1694,1629, +1694,1630,1695, +1631,1695,1630, +1695,1631,1696, +1632,1696,1631, +1696,1632,1697, +1633,1697,1632, +1697,1633,1698, +1634,1698,1633, +1698,1634,1699, +1635,1699,1634, +1699,1635,1700, +1636,1700,1635, +1700,1636,1701, +1637,1701,1636, +1701,1637,1702, +1638,1702,1637, +1702,1638,1703, +1639,1703,1638, +1703,1639,1704, +1640,1704,1639, +1704,1640,1705, +1641,1705,1640, +1705,1641,1706, +1642,1706,1641, +1706,1642,1707, +1643,1707,1642, +1707,1643,1708, +1644,1708,1643, +1708,1644,1709, +1645,1709,1644, +1709,1645,1710, +1646,1710,1645, +1710,1646,1711, +1647,1711,1646, +1711,1647,1712, +1648,1712,1647, +1712,1648,1713, +1649,1713,1648, +1713,1649,1714, +1650,1714,1649, +1714,1650,1715, +1651,1715,1650, +1715,1651,1716, +1652,1716,1651, +1716,1652,1717, +1653,1717,1652, +1717,1653,1718, +1654,1718,1653, +1718,1654,1719, +1655,1719,1654, +1719,1655,1720, +1656,1720,1655, +1720,1656,1721, +1657,1721,1656, +1721,1657,1722, +1658,1722,1657, +1722,1658,1723, +1659,1723,1658, +1723,1659,1724, +1660,1724,1659, +1724,1660,1725, +1661,1725,1660, +1725,1661,1726, +1662,1726,1661, +1726,1662,1727, +1663,1727,1662, +1728,1664,1729, +1665,1729,1664, +1729,1665,1730, +1666,1730,1665, +1730,1666,1731, +1667,1731,1666, +1731,1667,1732, +1668,1732,1667, +1732,1668,1733, +1669,1733,1668, +1733,1669,1734, +1670,1734,1669, +1734,1670,1735, +1671,1735,1670, +1735,1671,1736, +1672,1736,1671, +1736,1672,1737, +1673,1737,1672, +1737,1673,1738, +1674,1738,1673, +1738,1674,1739, +1675,1739,1674, +1739,1675,1740, +1676,1740,1675, +1740,1676,1741, +1677,1741,1676, +1741,1677,1742, +1678,1742,1677, +1742,1678,1743, +1679,1743,1678, +1743,1679,1744, +1680,1744,1679, +1744,1680,1745, +1681,1745,1680, +1745,1681,1746, +1682,1746,1681, +1746,1682,1747, +1683,1747,1682, +1747,1683,1748, +1684,1748,1683, +1748,1684,1749, +1685,1749,1684, +1749,1685,1750, +1686,1750,1685, +1750,1686,1751, +1687,1751,1686, +1751,1687,1752, +1688,1752,1687, +1752,1688,1753, +1689,1753,1688, +1753,1689,1754, +1690,1754,1689, +1754,1690,1755, +1691,1755,1690, +1755,1691,1756, +1692,1756,1691, +1756,1692,1757, +1693,1757,1692, +1757,1693,1758, +1694,1758,1693, +1758,1694,1759, +1695,1759,1694, +1759,1695,1760, +1696,1760,1695, +1760,1696,1761, +1697,1761,1696, +1761,1697,1762, +1698,1762,1697, +1762,1698,1763, +1699,1763,1698, +1763,1699,1764, +1700,1764,1699, +1764,1700,1765, +1701,1765,1700, +1765,1701,1766, +1702,1766,1701, +1766,1702,1767, +1703,1767,1702, +1767,1703,1768, +1704,1768,1703, +1768,1704,1769, +1705,1769,1704, +1769,1705,1770, +1706,1770,1705, +1770,1706,1771, +1707,1771,1706, +1771,1707,1772, +1708,1772,1707, +1772,1708,1773, +1709,1773,1708, +1773,1709,1774, +1710,1774,1709, +1774,1710,1775, +1711,1775,1710, +1775,1711,1776, +1712,1776,1711, +1776,1712,1777, +1713,1777,1712, +1777,1713,1778, +1714,1778,1713, +1778,1714,1779, +1715,1779,1714, +1779,1715,1780, +1716,1780,1715, +1780,1716,1781, +1717,1781,1716, +1781,1717,1782, +1718,1782,1717, +1782,1718,1783, +1719,1783,1718, +1783,1719,1784, +1720,1784,1719, +1784,1720,1785, +1721,1785,1720, +1785,1721,1786, +1722,1786,1721, +1786,1722,1787, +1723,1787,1722, +1787,1723,1788, +1724,1788,1723, +1788,1724,1789, +1725,1789,1724, +1789,1725,1790, +1726,1790,1725, +1790,1726,1791, +1727,1791,1726, +1792,1728,1793, +1729,1793,1728, +1793,1729,1794, +1730,1794,1729, +1794,1730,1795, +1731,1795,1730, +1795,1731,1796, +1732,1796,1731, +1796,1732,1797, +1733,1797,1732, +1797,1733,1798, +1734,1798,1733, +1798,1734,1799, +1735,1799,1734, +1799,1735,1800, +1736,1800,1735, +1800,1736,1801, +1737,1801,1736, +1801,1737,1802, +1738,1802,1737, +1802,1738,1803, +1739,1803,1738, +1803,1739,1804, +1740,1804,1739, +1804,1740,1805, +1741,1805,1740, +1805,1741,1806, +1742,1806,1741, +1806,1742,1807, +1743,1807,1742, +1807,1743,1808, +1744,1808,1743, +1808,1744,1809, +1745,1809,1744, +1809,1745,1810, +1746,1810,1745, +1810,1746,1811, +1747,1811,1746, +1811,1747,1812, +1748,1812,1747, +1812,1748,1813, +1749,1813,1748, +1813,1749,1814, +1750,1814,1749, +1814,1750,1815, +1751,1815,1750, +1815,1751,1816, +1752,1816,1751, +1816,1752,1817, +1753,1817,1752, +1817,1753,1818, +1754,1818,1753, +1818,1754,1819, +1755,1819,1754, +1819,1755,1820, +1756,1820,1755, +1820,1756,1821, +1757,1821,1756, +1821,1757,1822, +1758,1822,1757, +1822,1758,1823, +1759,1823,1758, +1823,1759,1824, +1760,1824,1759, +1824,1760,1825, +1761,1825,1760, +1825,1761,1826, +1762,1826,1761, +1826,1762,1827, +1763,1827,1762, +1827,1763,1828, +1764,1828,1763, +1828,1764,1829, +1765,1829,1764, +1829,1765,1830, +1766,1830,1765, +1830,1766,1831, +1767,1831,1766, +1831,1767,1832, +1768,1832,1767, +1832,1768,1833, +1769,1833,1768, +1833,1769,1834, +1770,1834,1769, +1834,1770,1835, +1771,1835,1770, +1835,1771,1836, +1772,1836,1771, +1836,1772,1837, +1773,1837,1772, +1837,1773,1838, +1774,1838,1773, +1838,1774,1839, +1775,1839,1774, +1839,1775,1840, +1776,1840,1775, +1840,1776,1841, +1777,1841,1776, +1841,1777,1842, +1778,1842,1777, +1842,1778,1843, +1779,1843,1778, +1843,1779,1844, +1780,1844,1779, +1844,1780,1845, +1781,1845,1780, +1845,1781,1846, +1782,1846,1781, +1846,1782,1847, +1783,1847,1782, +1847,1783,1848, +1784,1848,1783, +1848,1784,1849, +1785,1849,1784, +1849,1785,1850, +1786,1850,1785, +1850,1786,1851, +1787,1851,1786, +1851,1787,1852, +1788,1852,1787, +1852,1788,1853, +1789,1853,1788, +1853,1789,1854, +1790,1854,1789, +1854,1790,1855, +1791,1855,1790, +1856,1792,1857, +1793,1857,1792, +1857,1793,1858, +1794,1858,1793, +1858,1794,1859, +1795,1859,1794, +1859,1795,1860, +1796,1860,1795, +1860,1796,1861, +1797,1861,1796, +1861,1797,1862, +1798,1862,1797, +1862,1798,1863, +1799,1863,1798, +1863,1799,1864, +1800,1864,1799, +1864,1800,1865, +1801,1865,1800, +1865,1801,1866, +1802,1866,1801, +1866,1802,1867, +1803,1867,1802, +1867,1803,1868, +1804,1868,1803, +1868,1804,1869, +1805,1869,1804, +1869,1805,1870, +1806,1870,1805, +1870,1806,1871, +1807,1871,1806, +1871,1807,1872, +1808,1872,1807, +1872,1808,1873, +1809,1873,1808, +1873,1809,1874, +1810,1874,1809, +1874,1810,1875, +1811,1875,1810, +1875,1811,1876, +1812,1876,1811, +1876,1812,1877, +1813,1877,1812, +1877,1813,1878, +1814,1878,1813, +1878,1814,1879, +1815,1879,1814, +1879,1815,1880, +1816,1880,1815, +1880,1816,1881, +1817,1881,1816, +1881,1817,1882, +1818,1882,1817, +1882,1818,1883, +1819,1883,1818, +1883,1819,1884, +1820,1884,1819, +1884,1820,1885, +1821,1885,1820, +1885,1821,1886, +1822,1886,1821, +1886,1822,1887, +1823,1887,1822, +1887,1823,1888, +1824,1888,1823, +1888,1824,1889, +1825,1889,1824, +1889,1825,1890, +1826,1890,1825, +1890,1826,1891, +1827,1891,1826, +1891,1827,1892, +1828,1892,1827, +1892,1828,1893, +1829,1893,1828, +1893,1829,1894, +1830,1894,1829, +1894,1830,1895, +1831,1895,1830, +1895,1831,1896, +1832,1896,1831, +1896,1832,1897, +1833,1897,1832, +1897,1833,1898, +1834,1898,1833, +1898,1834,1899, +1835,1899,1834, +1899,1835,1900, +1836,1900,1835, +1900,1836,1901, +1837,1901,1836, +1901,1837,1902, +1838,1902,1837, +1902,1838,1903, +1839,1903,1838, +1903,1839,1904, +1840,1904,1839, +1904,1840,1905, +1841,1905,1840, +1905,1841,1906, +1842,1906,1841, +1906,1842,1907, +1843,1907,1842, +1907,1843,1908, +1844,1908,1843, +1908,1844,1909, +1845,1909,1844, +1909,1845,1910, +1846,1910,1845, +1910,1846,1911, +1847,1911,1846, +1911,1847,1912, +1848,1912,1847, +1912,1848,1913, +1849,1913,1848, +1913,1849,1914, +1850,1914,1849, +1914,1850,1915, +1851,1915,1850, +1915,1851,1916, +1852,1916,1851, +1916,1852,1917, +1853,1917,1852, +1917,1853,1918, +1854,1918,1853, +1918,1854,1919, +1855,1919,1854, +1920,1856,1921, +1857,1921,1856, +1921,1857,1922, +1858,1922,1857, +1922,1858,1923, +1859,1923,1858, +1923,1859,1924, +1860,1924,1859, +1924,1860,1925, +1861,1925,1860, +1925,1861,1926, +1862,1926,1861, +1926,1862,1927, +1863,1927,1862, +1927,1863,1928, +1864,1928,1863, +1928,1864,1929, +1865,1929,1864, +1929,1865,1930, +1866,1930,1865, +1930,1866,1931, +1867,1931,1866, +1931,1867,1932, +1868,1932,1867, +1932,1868,1933, +1869,1933,1868, +1933,1869,1934, +1870,1934,1869, +1934,1870,1935, +1871,1935,1870, +1935,1871,1936, +1872,1936,1871, +1936,1872,1937, +1873,1937,1872, +1937,1873,1938, +1874,1938,1873, +1938,1874,1939, +1875,1939,1874, +1939,1875,1940, +1876,1940,1875, +1940,1876,1941, +1877,1941,1876, +1941,1877,1942, +1878,1942,1877, +1942,1878,1943, +1879,1943,1878, +1943,1879,1944, +1880,1944,1879, +1944,1880,1945, +1881,1945,1880, +1945,1881,1946, +1882,1946,1881, +1946,1882,1947, +1883,1947,1882, +1947,1883,1948, +1884,1948,1883, +1948,1884,1949, +1885,1949,1884, +1949,1885,1950, +1886,1950,1885, +1950,1886,1951, +1887,1951,1886, +1951,1887,1952, +1888,1952,1887, +1952,1888,1953, +1889,1953,1888, +1953,1889,1954, +1890,1954,1889, +1954,1890,1955, +1891,1955,1890, +1955,1891,1956, +1892,1956,1891, +1956,1892,1957, +1893,1957,1892, +1957,1893,1958, +1894,1958,1893, +1958,1894,1959, +1895,1959,1894, +1959,1895,1960, +1896,1960,1895, +1960,1896,1961, +1897,1961,1896, +1961,1897,1962, +1898,1962,1897, +1962,1898,1963, +1899,1963,1898, +1963,1899,1964, +1900,1964,1899, +1964,1900,1965, +1901,1965,1900, +1965,1901,1966, +1902,1966,1901, +1966,1902,1967, +1903,1967,1902, +1967,1903,1968, +1904,1968,1903, +1968,1904,1969, +1905,1969,1904, +1969,1905,1970, +1906,1970,1905, +1970,1906,1971, +1907,1971,1906, +1971,1907,1972, +1908,1972,1907, +1972,1908,1973, +1909,1973,1908, +1973,1909,1974, +1910,1974,1909, +1974,1910,1975, +1911,1975,1910, +1975,1911,1976, +1912,1976,1911, +1976,1912,1977, +1913,1977,1912, +1977,1913,1978, +1914,1978,1913, +1978,1914,1979, +1915,1979,1914, +1979,1915,1980, +1916,1980,1915, +1980,1916,1981, +1917,1981,1916, +1981,1917,1982, +1918,1982,1917, +1982,1918,1983, +1919,1983,1918, +1984,1920,1985, +1921,1985,1920, +1985,1921,1986, +1922,1986,1921, +1986,1922,1987, +1923,1987,1922, +1987,1923,1988, +1924,1988,1923, +1988,1924,1989, +1925,1989,1924, +1989,1925,1990, +1926,1990,1925, +1990,1926,1991, +1927,1991,1926, +1991,1927,1992, +1928,1992,1927, +1992,1928,1993, +1929,1993,1928, +1993,1929,1994, +1930,1994,1929, +1994,1930,1995, +1931,1995,1930, +1995,1931,1996, +1932,1996,1931, +1996,1932,1997, +1933,1997,1932, +1997,1933,1998, +1934,1998,1933, +1998,1934,1999, +1935,1999,1934, +1999,1935,2000, +1936,2000,1935, +2000,1936,2001, +1937,2001,1936, +2001,1937,2002, +1938,2002,1937, +2002,1938,2003, +1939,2003,1938, +2003,1939,2004, +1940,2004,1939, +2004,1940,2005, +1941,2005,1940, +2005,1941,2006, +1942,2006,1941, +2006,1942,2007, +1943,2007,1942, +2007,1943,2008, +1944,2008,1943, +2008,1944,2009, +1945,2009,1944, +2009,1945,2010, +1946,2010,1945, +2010,1946,2011, +1947,2011,1946, +2011,1947,2012, +1948,2012,1947, +2012,1948,2013, +1949,2013,1948, +2013,1949,2014, +1950,2014,1949, +2014,1950,2015, +1951,2015,1950, +2015,1951,2016, +1952,2016,1951, +2016,1952,2017, +1953,2017,1952, +2017,1953,2018, +1954,2018,1953, +2018,1954,2019, +1955,2019,1954, +2019,1955,2020, +1956,2020,1955, +2020,1956,2021, +1957,2021,1956, +2021,1957,2022, +1958,2022,1957, +2022,1958,2023, +1959,2023,1958, +2023,1959,2024, +1960,2024,1959, +2024,1960,2025, +1961,2025,1960, +2025,1961,2026, +1962,2026,1961, +2026,1962,2027, +1963,2027,1962, +2027,1963,2028, +1964,2028,1963, +2028,1964,2029, +1965,2029,1964, +2029,1965,2030, +1966,2030,1965, +2030,1966,2031, +1967,2031,1966, +2031,1967,2032, +1968,2032,1967, +2032,1968,2033, +1969,2033,1968, +2033,1969,2034, +1970,2034,1969, +2034,1970,2035, +1971,2035,1970, +2035,1971,2036, +1972,2036,1971, +2036,1972,2037, +1973,2037,1972, +2037,1973,2038, +1974,2038,1973, +2038,1974,2039, +1975,2039,1974, +2039,1975,2040, +1976,2040,1975, +2040,1976,2041, +1977,2041,1976, +2041,1977,2042, +1978,2042,1977, +2042,1978,2043, +1979,2043,1978, +2043,1979,2044, +1980,2044,1979, +2044,1980,2045, +1981,2045,1980, +2045,1981,2046, +1982,2046,1981, +2046,1982,2047, +1983,2047,1982, +}; + +#define Landscape04VtxCount 2112 +#define Landscape04IdxCount 12096 + +btScalar Landscape04Vtx[] = { +3.90625f,18.9654f,125.0f, +3.90625f,20.0876f,128.906f, +7.8125f,20.5764f,125.0f, +7.8125f,21.0764f,128.906f, +11.7188f,21.5489f,125.0f, +11.7188f,21.4076f,128.906f, +15.625f,22.4963f,125.0f, +15.625f,22.6299f,128.906f, +19.5313f,22.3264f,125.0f, +19.5313f,22.1174f,128.906f, +23.4375f,20.3987f,125.0f, +23.4375f,20.3977f,128.906f, +27.3438f,18.6622f,125.0f, +27.3438f,18.7343f,128.906f, +31.25f,17.4724f,125.0f, +31.25f,17.9144f,128.906f, +35.1563f,16.4832f,125.0f, +35.1563f,17.2941f,128.906f, +39.0625f,15.2653f,125.0f, +39.0625f,16.5386f,128.906f, +42.9688f,14.379f,125.0f, +42.9688f,15.6892f,128.906f, +46.875f,13.9872f,125.0f, +46.875f,14.6414f,128.906f, +50.7813f,14.7002f,125.0f, +50.7813f,14.3505f,128.906f, +54.6875f,15.1119f,125.0f, +54.6875f,14.1604f,128.906f, +58.5938f,14.6638f,125.0f, +58.5938f,14.517f,128.906f, +62.5f,14.668f,125.0f, +62.5f,15.1057f,128.906f, +66.4063f,14.9792f,125.0f, +66.4063f,16.0684f,128.906f, +70.3125f,15.4776f,125.0f, +70.3125f,16.6251f,128.906f, +74.2188f,15.0939f,125.0f, +74.2188f,15.9689f,128.906f, +78.125f,15.5318f,125.0f, +78.125f,16.0234f,128.906f, +82.0313f,16.0777f,125.0f, +82.0313f,16.205f,128.906f, +85.9375f,17.8753f,125.0f, +85.9375f,18.8167f,128.906f, +89.8438f,18.8786f,125.0f, +89.8438f,19.6433f,128.906f, +93.75f,19.8208f,125.0f, +93.75f,20.2916f,128.906f, +97.6563f,23.2578f,125.0f, +97.6563f,23.2308f,128.906f, +101.563f,25.3117f,125.0f, +101.563f,25.882f,128.906f, +105.469f,26.8718f,125.0f, +105.469f,27.5736f,128.906f, +109.375f,28.7414f,125.0f, +109.375f,28.9662f,128.906f, +113.281f,29.9339f,125.0f, +113.281f,30.5702f,128.906f, +117.188f,30.6849f,125.0f, +117.188f,31.8627f,128.906f, +121.094f,32.4202f,125.0f, +121.094f,32.5216f,128.906f, +125.0f,34.7495f,125.0f, +125.0f,34.1918f,128.906f, +128.906f,37.137f,125.0f, +128.906f,37.0161f,128.906f, +132.813f,38.4113f,125.0f, +132.813f,38.5084f,128.906f, +136.719f,38.1788f,125.0f, +136.719f,39.1631f,128.906f, +140.625f,38.7652f,125.0f, +140.625f,39.0529f,128.906f, +144.531f,37.9353f,125.0f, +144.531f,38.9229f,128.906f, +148.438f,38.5681f,125.0f, +148.438f,38.4312f,128.906f, +152.344f,38.6243f,125.0f, +152.344f,39.1086f,128.906f, +156.25f,39.6341f,125.0f, +156.25f,39.7022f,128.906f, +160.156f,39.762f,125.0f, +160.156f,39.3007f,128.906f, +164.063f,38.5385f,125.0f, +164.063f,38.2318f,128.906f, +167.969f,36.3551f,125.0f, +167.969f,36.7493f,128.906f, +171.875f,36.1936f,125.0f, +171.875f,35.9781f,128.906f, +175.781f,35.5636f,125.0f, +175.781f,35.7712f,128.906f, +179.688f,34.6544f,125.0f, +179.688f,35.6247f,128.906f, +183.594f,34.1597f,125.0f, +183.594f,35.4808f,128.906f, +187.5f,33.5567f,125.0f, +187.5f,35.6102f,128.906f, +191.406f,33.0138f,125.0f, +191.406f,34.0305f,128.906f, +195.313f,31.2722f,125.0f, +195.313f,32.0227f,128.906f, +199.219f,29.2529f,125.0f, +199.219f,29.7666f,128.906f, +203.125f,26.9435f,125.0f, +203.125f,27.3968f,128.906f, +207.031f,25.0844f,125.0f, +207.031f,25.1642f,128.906f, +210.938f,23.6605f,125.0f, +210.938f,24.279f,128.906f, +214.844f,22.0745f,125.0f, +214.844f,22.4357f,128.906f, +218.75f,20.3206f,125.0f, +218.75f,21.7754f,128.906f, +222.656f,20.0402f,125.0f, +222.656f,19.6381f,128.906f, +226.563f,20.1162f,125.0f, +226.563f,19.78f,128.906f, +230.469f,20.2399f,125.0f, +230.469f,20.0349f,128.906f, +234.375f,19.6142f,125.0f, +234.375f,19.1534f,128.906f, +238.281f,18.6118f,125.0f, +238.281f,17.863f,128.906f, +242.188f,17.3711f,125.0f, +242.188f,17.658f,128.906f, +246.094f,17.675f,125.0f, +246.094f,16.951f,128.906f, +250.0f,17.3999f,125.0f, +250.0f,16.2961f,128.906f, +3.90625f,18.5327f,121.094f, +7.8125f,19.7267f,121.094f, +11.7188f,20.9891f,121.094f, +15.625f,22.237f,121.094f, +19.5313f,22.3238f,121.094f, +23.4375f,20.1525f,121.094f, +27.3438f,17.9536f,121.094f, +31.25f,17.647f,121.094f, +35.1563f,16.241f,121.094f, +39.0625f,14.6821f,121.094f, +42.9688f,14.4948f,121.094f, +46.875f,15.0351f,121.094f, +50.7813f,15.3893f,121.094f, +54.6875f,15.1531f,121.094f, +58.5938f,14.9284f,121.094f, +62.5f,15.1197f,121.094f, +66.4063f,15.1561f,121.094f, +70.3125f,15.1593f,121.094f, +74.2188f,15.0707f,121.094f, +78.125f,16.0455f,121.094f, +82.0313f,16.6186f,121.094f, +85.9375f,17.4149f,121.094f, +89.8438f,18.746f,121.094f, +93.75f,18.8475f,121.094f, +97.6563f,21.6899f,121.094f, +101.563f,24.567f,121.094f, +105.469f,25.7581f,121.094f, +109.375f,27.437f,121.094f, +113.281f,29.1226f,121.094f, +117.188f,30.137f,121.094f, +121.094f,32.1062f,121.094f, +125.0f,34.674f,121.094f, +128.906f,37.1044f,121.094f, +132.813f,37.8111f,121.094f, +136.719f,37.7901f,121.094f, +140.625f,37.5727f,121.094f, +144.531f,37.1561f,121.094f, +148.438f,38.1976f,121.094f, +152.344f,38.9227f,121.094f, +156.25f,40.3124f,121.094f, +160.156f,40.6867f,121.094f, +164.063f,39.5374f,121.094f, +167.969f,38.019f,121.094f, +171.875f,36.4573f,121.094f, +175.781f,35.2509f,121.094f, +179.688f,34.6709f,121.094f, +183.594f,33.5584f,121.094f, +187.5f,33.2411f,121.094f, +191.406f,31.7588f,121.094f, +195.313f,30.3558f,121.094f, +199.219f,28.879f,121.094f, +203.125f,26.7589f,121.094f, +207.031f,25.0535f,121.094f, +210.938f,23.0477f,121.094f, +214.844f,20.6897f,121.094f, +218.75f,19.3676f,121.094f, +222.656f,19.2985f,121.094f, +226.563f,20.2312f,121.094f, +230.469f,20.317f,121.094f, +234.375f,20.2468f,121.094f, +238.281f,20.3734f,121.094f, +242.188f,18.3676f,121.094f, +246.094f,16.642f,121.094f, +250.0f,17.5995f,121.094f, +3.90625f,18.919f,117.188f, +7.8125f,19.2124f,117.188f, +11.7188f,20.7659f,117.188f, +15.625f,20.5809f,117.188f, +19.5313f,20.3134f,117.188f, +23.4375f,18.6669f,117.188f, +27.3438f,17.5145f,117.188f, +31.25f,17.0813f,117.188f, +35.1563f,15.6789f,117.188f, +39.0625f,14.7581f,117.188f, +42.9688f,14.4424f,117.188f, +46.875f,14.7991f,117.188f, +50.7813f,15.0726f,117.188f, +54.6875f,14.8056f,117.188f, +58.5938f,15.756f,117.188f, +62.5f,16.3024f,117.188f, +66.4063f,16.0449f,117.188f, +70.3125f,15.9115f,117.188f, +74.2188f,16.1633f,117.188f, +78.125f,17.3323f,117.188f, +82.0313f,17.2659f,117.188f, +85.9375f,17.987f,117.188f, +89.8438f,18.3044f,117.188f, +93.75f,18.2665f,117.188f, +97.6563f,19.5364f,117.188f, +101.563f,21.7536f,117.188f, +105.469f,23.6545f,117.188f, +109.375f,25.5212f,117.188f, +113.281f,28.1179f,117.188f, +117.188f,29.5931f,117.188f, +121.094f,31.8126f,117.188f, +125.0f,34.0227f,117.188f, +128.906f,36.3895f,117.188f, +132.813f,37.0423f,117.188f, +136.719f,36.8278f,117.188f, +140.625f,36.2349f,117.188f, +144.531f,36.8825f,117.188f, +148.438f,39.6492f,117.188f, +152.344f,41.6626f,117.188f, +156.25f,42.5091f,117.188f, +160.156f,43.0711f,117.188f, +164.063f,41.7733f,117.188f, +167.969f,40.5985f,117.188f, +171.875f,38.1852f,117.188f, +175.781f,37.023f,117.188f, +179.688f,35.8533f,117.188f, +183.594f,34.5754f,117.188f, +187.5f,33.6585f,117.188f, +191.406f,32.534f,117.188f, +195.313f,31.0632f,117.188f, +199.219f,29.0243f,117.188f, +203.125f,27.0248f,117.188f, +207.031f,25.1597f,117.188f, +210.938f,22.6282f,117.188f, +214.844f,20.6205f,117.188f, +218.75f,19.2556f,117.188f, +222.656f,18.8259f,117.188f, +226.563f,19.2235f,117.188f, +230.469f,20.4441f,117.188f, +234.375f,20.5373f,117.188f, +238.281f,20.3082f,117.188f, +242.188f,19.4397f,117.188f, +246.094f,17.9806f,117.188f, +250.0f,17.3395f,117.188f, +3.90625f,18.3498f,113.281f, +7.8125f,18.7009f,113.281f, +11.7188f,19.3704f,113.281f, +15.625f,19.5203f,113.281f, +19.5313f,18.5704f,113.281f, +23.4375f,17.6697f,113.281f, +27.3438f,16.8001f,113.281f, +31.25f,16.54f,113.281f, +35.1563f,15.8558f,113.281f, +39.0625f,15.1296f,113.281f, +42.9688f,15.8599f,113.281f, +46.875f,16.437f,113.281f, +50.7813f,16.2977f,113.281f, +54.6875f,16.7076f,113.281f, +58.5938f,16.8187f,113.281f, +62.5f,17.1513f,113.281f, +66.4063f,16.5296f,113.281f, +70.3125f,15.8782f,113.281f, +74.2188f,16.614f,113.281f, +78.125f,17.0474f,113.281f, +82.0313f,17.3371f,113.281f, +85.9375f,17.9565f,113.281f, +89.8438f,18.3918f,113.281f, +93.75f,19.0258f,113.281f, +97.6563f,19.2791f,113.281f, +101.563f,20.1533f,113.281f, +105.469f,22.2922f,113.281f, +109.375f,24.6835f,113.281f, +113.281f,25.7755f,113.281f, +117.188f,28.8805f,113.281f, +121.094f,31.2119f,113.281f, +125.0f,33.4657f,113.281f, +128.906f,35.1055f,113.281f, +132.813f,36.4197f,113.281f, +136.719f,37.3017f,113.281f, +140.625f,37.1796f,113.281f, +144.531f,38.2037f,113.281f, +148.438f,41.4383f,113.281f, +152.344f,43.9714f,113.281f, +156.25f,45.0067f,113.281f, +160.156f,45.1491f,113.281f, +164.063f,43.8042f,113.281f, +167.969f,42.5165f,113.281f, +171.875f,40.361f,113.281f, +175.781f,38.3494f,113.281f, +179.688f,37.4529f,113.281f, +183.594f,35.5766f,113.281f, +187.5f,34.2438f,113.281f, +191.406f,32.0218f,113.281f, +195.313f,30.2021f,113.281f, +199.219f,28.8256f,113.281f, +203.125f,27.2081f,113.281f, +207.031f,24.992f,113.281f, +210.938f,22.5332f,113.281f, +214.844f,19.7765f,113.281f, +218.75f,18.5573f,113.281f, +222.656f,18.1469f,113.281f, +226.563f,17.9659f,113.281f, +230.469f,19.2f,113.281f, +234.375f,20.0741f,113.281f, +238.281f,20.1159f,113.281f, +242.188f,19.0382f,113.281f, +246.094f,18.3417f,113.281f, +250.0f,18.7603f,113.281f, +3.90625f,18.0017f,109.375f, +7.8125f,18.1552f,109.375f, +11.7188f,18.2026f,109.375f, +15.625f,18.2042f,109.375f, +19.5313f,17.7806f,109.375f, +23.4375f,17.5378f,109.375f, +27.3438f,16.8627f,109.375f, +31.25f,15.9329f,109.375f, +35.1563f,15.192f,109.375f, +39.0625f,16.0796f,109.375f, +42.9688f,16.1895f,109.375f, +46.875f,15.9774f,109.375f, +50.7813f,16.9529f,109.375f, +54.6875f,17.0901f,109.375f, +58.5938f,17.3722f,109.375f, +62.5f,16.5809f,109.375f, +66.4063f,16.8111f,109.375f, +70.3125f,16.9238f,109.375f, +74.2188f,16.8422f,109.375f, +78.125f,17.0401f,109.375f, +82.0313f,16.8637f,109.375f, +85.9375f,17.4071f,109.375f, +89.8438f,17.944f,109.375f, +93.75f,18.5255f,109.375f, +97.6563f,18.2829f,109.375f, +101.563f,19.0975f,109.375f, +105.469f,20.4292f,109.375f, +109.375f,22.163f,109.375f, +113.281f,25.6773f,109.375f, +117.188f,27.8617f,109.375f, +121.094f,30.6543f,109.375f, +125.0f,33.4226f,109.375f, +128.906f,34.4263f,109.375f, +132.813f,36.8747f,109.375f, +136.719f,37.4551f,109.375f, +140.625f,37.4975f,109.375f, +144.531f,40.0751f,109.375f, +148.438f,42.7524f,109.375f, +152.344f,44.7756f,109.375f, +156.25f,46.1787f,109.375f, +160.156f,46.3753f,109.375f, +164.063f,45.2089f,109.375f, +167.969f,43.7487f,109.375f, +171.875f,41.6365f,109.375f, +175.781f,39.7459f,109.375f, +179.688f,36.9804f,109.375f, +183.594f,35.6688f,109.375f, +187.5f,35.0212f,109.375f, +191.406f,32.4383f,109.375f, +195.313f,29.6046f,109.375f, +199.219f,28.1822f,109.375f, +203.125f,26.2444f,109.375f, +207.031f,24.1442f,109.375f, +210.938f,22.1072f,109.375f, +214.844f,20.0401f,109.375f, +218.75f,18.0663f,109.375f, +222.656f,16.866f,109.375f, +226.563f,16.9372f,109.375f, +230.469f,16.9853f,109.375f, +234.375f,17.6761f,109.375f, +238.281f,18.3669f,109.375f, +242.188f,18.4156f,109.375f, +246.094f,18.2171f,109.375f, +250.0f,18.5941f,109.375f, +3.90625f,17.9608f,105.469f, +7.8125f,18.4369f,105.469f, +11.7188f,18.4406f,105.469f, +15.625f,17.8685f,105.469f, +19.5313f,17.7519f,105.469f, +23.4375f,17.5734f,105.469f, +27.3438f,16.3397f,105.469f, +31.25f,15.8618f,105.469f, +35.1563f,16.1194f,105.469f, +39.0625f,16.889f,105.469f, +42.9688f,16.2804f,105.469f, +46.875f,15.8474f,105.469f, +50.7813f,16.2892f,105.469f, +54.6875f,16.2854f,105.469f, +58.5938f,16.7368f,105.469f, +62.5f,17.4055f,105.469f, +66.4063f,16.8808f,105.469f, +70.3125f,17.3183f,105.469f, +74.2188f,17.7166f,105.469f, +78.125f,17.0657f,105.469f, +82.0313f,16.7305f,105.469f, +85.9375f,16.3929f,105.469f, +89.8438f,16.6475f,105.469f, +93.75f,17.7645f,105.469f, +97.6563f,18.4212f,105.469f, +101.563f,18.4107f,105.469f, +105.469f,19.3751f,105.469f, +109.375f,21.843f,105.469f, +113.281f,25.0143f,105.469f, +117.188f,26.9168f,105.469f, +121.094f,29.8403f,105.469f, +125.0f,32.4937f,105.469f, +128.906f,34.4076f,105.469f, +132.813f,35.2497f,105.469f, +136.719f,36.4785f,105.469f, +140.625f,37.7983f,105.469f, +144.531f,40.5712f,105.469f, +148.438f,43.3698f,105.469f, +152.344f,45.784f,105.469f, +156.25f,46.9835f,105.469f, +160.156f,47.2774f,105.469f, +164.063f,46.7695f,105.469f, +167.969f,45.0199f,105.469f, +171.875f,42.588f,105.469f, +175.781f,39.988f,105.469f, +179.688f,38.0653f,105.469f, +183.594f,37.5754f,105.469f, +187.5f,35.6316f,105.469f, +191.406f,32.4143f,105.469f, +195.313f,29.5342f,105.469f, +199.219f,27.2795f,105.469f, +203.125f,26.065f,105.469f, +207.031f,24.8633f,105.469f, +210.938f,23.0216f,105.469f, +214.844f,21.1684f,105.469f, +218.75f,18.9315f,105.469f, +222.656f,17.7013f,105.469f, +226.563f,16.9466f,105.469f, +230.469f,17.1437f,105.469f, +234.375f,17.6691f,105.469f, +238.281f,17.9243f,105.469f, +242.188f,18.0005f,105.469f, +246.094f,18.6179f,105.469f, +250.0f,19.2165f,105.469f, +3.90625f,17.7074f,101.563f, +7.8125f,18.411f,101.563f, +11.7188f,17.9916f,101.563f, +15.625f,18.5349f,101.563f, +19.5313f,18.6607f,101.563f, +23.4375f,17.406f,101.563f, +27.3438f,17.2356f,101.563f, +31.25f,17.0395f,101.563f, +35.1563f,17.9903f,101.563f, +39.0625f,18.2603f,101.563f, +42.9688f,17.9037f,101.563f, +46.875f,17.2358f,101.563f, +50.7813f,16.1089f,101.563f, +54.6875f,16.6043f,101.563f, +58.5938f,16.5656f,101.563f, +62.5f,16.8655f,101.563f, +66.4063f,17.0123f,101.563f, +70.3125f,17.4985f,101.563f, +74.2188f,18.0195f,101.563f, +78.125f,17.3417f,101.563f, +82.0313f,16.8477f,101.563f, +85.9375f,15.4602f,101.563f, +89.8438f,15.6001f,101.563f, +93.75f,16.8889f,101.563f, +97.6563f,17.2944f,101.563f, +101.563f,17.3431f,101.563f, +105.469f,18.2306f,101.563f, +109.375f,20.5556f,101.563f, +113.281f,22.5598f,101.563f, +117.188f,25.0997f,101.563f, +121.094f,28.2048f,101.563f, +125.0f,30.46f,101.563f, +128.906f,32.5729f,101.563f, +132.813f,34.5568f,101.563f, +136.719f,36.463f,101.563f, +140.625f,37.8259f,101.563f, +144.531f,40.4357f,101.563f, +148.438f,43.6544f,101.563f, +152.344f,46.204f,101.563f, +156.25f,47.3874f,101.563f, +160.156f,47.5222f,101.563f, +164.063f,46.8312f,101.563f, +167.969f,44.5065f,101.563f, +171.875f,43.7648f,101.563f, +175.781f,41.9789f,101.563f, +179.688f,40.785f,101.563f, +183.594f,38.7639f,101.563f, +187.5f,36.1589f,101.563f, +191.406f,33.4197f,101.563f, +195.313f,29.7568f,101.563f, +199.219f,27.2343f,101.563f, +203.125f,26.3845f,101.563f, +207.031f,25.3149f,101.563f, +210.938f,23.4896f,101.563f, +214.844f,22.229f,101.563f, +218.75f,20.0014f,101.563f, +222.656f,19.0955f,101.563f, +226.563f,17.971f,101.563f, +230.469f,16.9303f,101.563f, +234.375f,17.3619f,101.563f, +238.281f,17.0337f,101.563f, +242.188f,17.1424f,101.563f, +246.094f,18.334f,101.563f, +250.0f,19.2744f,101.563f, +3.90625f,18.0176f,97.6563f, +7.8125f,18.1916f,97.6563f, +11.7188f,17.72f,97.6563f, +15.625f,18.3444f,97.6563f, +19.5313f,18.7102f,97.6563f, +23.4375f,17.4143f,97.6563f, +27.3438f,18.0085f,97.6563f, +31.25f,18.4924f,97.6563f, +35.1563f,19.4324f,97.6563f, +39.0625f,19.7998f,97.6563f, +42.9688f,19.5444f,97.6563f, +46.875f,19.5513f,97.6563f, +50.7813f,17.9397f,97.6563f, +54.6875f,16.6383f,97.6563f, +58.5938f,16.0619f,97.6563f, +62.5f,16.7402f,97.6563f, +66.4063f,16.955f,97.6563f, +70.3125f,17.5912f,97.6563f, +74.2188f,17.1181f,97.6563f, +78.125f,16.9063f,97.6563f, +82.0313f,16.3988f,97.6563f, +85.9375f,15.935f,97.6563f, +89.8438f,16.0664f,97.6563f, +93.75f,16.1926f,97.6563f, +97.6563f,16.5004f,97.6563f, +101.563f,17.1185f,97.6563f, +105.469f,17.2859f,97.6563f, +109.375f,19.0026f,97.6563f, +113.281f,21.0018f,97.6563f, +117.188f,23.6336f,97.6563f, +121.094f,26.4831f,97.6563f, +125.0f,29.3075f,97.6563f, +128.906f,32.5702f,97.6563f, +132.813f,34.5711f,97.6563f, +136.719f,36.1666f,97.6563f, +140.625f,37.5909f,97.6563f, +144.531f,40.3232f,97.6563f, +148.438f,42.661f,97.6563f, +152.344f,45.5604f,97.6563f, +156.25f,47.6984f,97.6563f, +160.156f,47.4129f,97.6563f, +164.063f,47.1564f,97.6563f, +167.969f,45.3058f,97.6563f, +171.875f,44.8069f,97.6563f, +175.781f,43.6847f,97.6563f, +179.688f,41.6831f,97.6563f, +183.594f,39.4072f,97.6563f, +187.5f,36.6118f,97.6563f, +191.406f,33.396f,97.6563f, +195.313f,29.9372f,97.6563f, +199.219f,28.0616f,97.6563f, +203.125f,27.3957f,97.6563f, +207.031f,25.6934f,97.6563f, +210.938f,24.4412f,97.6563f, +214.844f,23.2356f,97.6563f, +218.75f,21.445f,97.6563f, +222.656f,19.5412f,97.6563f, +226.563f,18.4898f,97.6563f, +230.469f,17.727f,97.6563f, +234.375f,16.5139f,97.6563f, +238.281f,16.2579f,97.6563f, +242.188f,16.1539f,97.6563f, +246.094f,17.0856f,97.6563f, +250.0f,18.5151f,97.6563f, +3.90625f,17.1671f,93.75f, +7.8125f,16.817f,93.75f, +11.7188f,17.5293f,93.75f, +15.625f,18.7701f,93.75f, +19.5313f,18.3362f,93.75f, +23.4375f,19.0869f,93.75f, +27.3438f,19.7557f,93.75f, +31.25f,20.0113f,93.75f, +35.1563f,20.3441f,93.75f, +39.0625f,21.4434f,93.75f, +42.9688f,21.6008f,93.75f, +46.875f,21.5423f,93.75f, +50.7813f,20.7592f,93.75f, +54.6875f,18.9207f,93.75f, +58.5938f,17.6772f,93.75f, +62.5f,17.5409f,93.75f, +66.4063f,17.599f,93.75f, +70.3125f,18.2626f,93.75f, +74.2188f,18.4046f,93.75f, +78.125f,18.215f,93.75f, +82.0313f,18.4743f,93.75f, +85.9375f,17.6579f,93.75f, +89.8438f,17.732f,93.75f, +93.75f,18.4172f,93.75f, +97.6563f,19.0439f,93.75f, +101.563f,19.7437f,93.75f, +105.469f,19.8588f,93.75f, +109.375f,19.7414f,93.75f, +113.281f,21.4756f,93.75f, +117.188f,24.1862f,93.75f, +121.094f,26.8351f,93.75f, +125.0f,29.9621f,93.75f, +128.906f,32.8267f,93.75f, +132.813f,34.6779f,93.75f, +136.719f,36.0083f,93.75f, +140.625f,36.9812f,93.75f, +144.531f,39.6087f,93.75f, +148.438f,42.2269f,93.75f, +152.344f,44.492f,93.75f, +156.25f,47.1767f,93.75f, +160.156f,47.5667f,93.75f, +164.063f,46.9625f,93.75f, +167.969f,45.6865f,93.75f, +171.875f,45.7668f,93.75f, +175.781f,44.8303f,93.75f, +179.688f,42.5904f,93.75f, +183.594f,40.3536f,93.75f, +187.5f,37.9498f,93.75f, +191.406f,35.1415f,93.75f, +195.313f,31.5011f,93.75f, +199.219f,29.695f,93.75f, +203.125f,27.7988f,93.75f, +207.031f,26.3522f,93.75f, +210.938f,25.8544f,93.75f, +214.844f,24.7269f,93.75f, +218.75f,23.7697f,93.75f, +222.656f,20.9249f,93.75f, +226.563f,19.1368f,93.75f, +230.469f,18.5704f,93.75f, +234.375f,17.554f,93.75f, +238.281f,14.9004f,93.75f, +242.188f,16.3253f,93.75f, +246.094f,16.0037f,93.75f, +250.0f,15.9921f,93.75f, +3.90625f,15.6427f,89.8438f, +7.8125f,16.2722f,89.8438f, +11.7188f,17.6471f,89.8438f, +15.625f,18.8565f,89.8438f, +19.5313f,19.651f,89.8438f, +23.4375f,20.9243f,89.8438f, +27.3438f,20.8045f,89.8438f, +31.25f,20.2274f,89.8438f, +35.1563f,21.5768f,89.8438f, +39.0625f,22.566f,89.8438f, +42.9688f,23.4111f,89.8438f, +46.875f,23.5063f,89.8438f, +50.7813f,22.9631f,89.8438f, +54.6875f,21.5642f,89.8438f, +58.5938f,20.3649f,89.8438f, +62.5f,19.6177f,89.8438f, +66.4063f,18.6758f,89.8438f, +70.3125f,18.6837f,89.8438f, +74.2188f,19.7593f,89.8438f, +78.125f,20.4356f,89.8438f, +82.0313f,20.1806f,89.8438f, +85.9375f,19.4513f,89.8438f, +89.8438f,19.2942f,89.8438f, +93.75f,19.9864f,89.8438f, +97.6563f,20.6569f,89.8438f, +101.563f,20.8985f,89.8438f, +105.469f,20.8027f,89.8438f, +109.375f,21.5099f,89.8438f, +113.281f,22.7491f,89.8438f, +117.188f,24.1938f,89.8438f, +121.094f,27.3472f,89.8438f, +125.0f,29.9546f,89.8438f, +128.906f,32.3821f,89.8438f, +132.813f,34.2078f,89.8438f, +136.719f,35.7419f,89.8438f, +140.625f,36.6408f,89.8438f, +144.531f,39.1756f,89.8438f, +148.438f,42.1721f,89.8438f, +152.344f,43.7891f,89.8438f, +156.25f,45.9566f,89.8438f, +160.156f,47.5521f,89.8438f, +164.063f,47.0165f,89.8438f, +167.969f,46.0084f,89.8438f, +171.875f,46.0374f,89.8438f, +175.781f,45.9301f,89.8438f, +179.688f,43.5326f,89.8438f, +183.594f,40.5203f,89.8438f, +187.5f,38.133f,89.8438f, +191.406f,35.8688f,89.8438f, +195.313f,33.0648f,89.8438f, +199.219f,31.0451f,89.8438f, +203.125f,27.691f,89.8438f, +207.031f,26.7927f,89.8438f, +210.938f,26.334f,89.8438f, +214.844f,25.0669f,89.8438f, +218.75f,23.4149f,89.8438f, +222.656f,20.9786f,89.8438f, +226.563f,18.963f,89.8438f, +230.469f,18.7894f,89.8438f, +234.375f,17.2683f,89.8438f, +238.281f,14.98f,89.8438f, +242.188f,15.4163f,89.8438f, +246.094f,15.4238f,89.8438f, +250.0f,15.9208f,89.8438f, +3.90625f,15.5916f,85.9375f, +7.8125f,16.3916f,85.9375f, +11.7188f,18.2047f,85.9375f, +15.625f,19.1861f,85.9375f, +19.5313f,20.7525f,85.9375f, +23.4375f,21.6364f,85.9375f, +27.3438f,21.9262f,85.9375f, +31.25f,21.6225f,85.9375f, +35.1563f,22.4806f,85.9375f, +39.0625f,23.7973f,85.9375f, +42.9688f,24.6135f,85.9375f, +46.875f,24.8421f,85.9375f, +50.7813f,24.5451f,85.9375f, +54.6875f,23.688f,85.9375f, +58.5938f,22.221f,85.9375f, +62.5f,21.5009f,85.9375f, +66.4063f,21.2241f,85.9375f, +70.3125f,20.2058f,85.9375f, +74.2188f,20.3437f,85.9375f, +78.125f,21.8786f,85.9375f, +82.0313f,21.9425f,85.9375f, +85.9375f,20.6496f,85.9375f, +89.8438f,20.6855f,85.9375f, +93.75f,20.6495f,85.9375f, +97.6563f,21.0738f,85.9375f, +101.563f,21.7991f,85.9375f, +105.469f,22.3795f,85.9375f, +109.375f,22.4292f,85.9375f, +113.281f,23.6451f,85.9375f, +117.188f,24.8457f,85.9375f, +121.094f,26.7121f,85.9375f, +125.0f,29.2236f,85.9375f, +128.906f,31.5942f,85.9375f, +132.813f,33.8517f,85.9375f, +136.719f,35.7145f,85.9375f, +140.625f,36.6808f,85.9375f, +144.531f,38.8926f,85.9375f, +148.438f,41.6484f,85.9375f, +152.344f,44.2035f,85.9375f, +156.25f,45.1997f,85.9375f, +160.156f,46.1921f,85.9375f, +164.063f,47.2097f,85.9375f, +167.969f,47.0691f,85.9375f, +171.875f,45.5257f,85.9375f, +175.781f,44.6746f,85.9375f, +179.688f,43.6223f,85.9375f, +183.594f,40.2395f,85.9375f, +187.5f,38.445f,85.9375f, +191.406f,36.5002f,85.9375f, +195.313f,33.7977f,85.9375f, +199.219f,31.5943f,85.9375f, +203.125f,28.8305f,85.9375f, +207.031f,27.4922f,85.9375f, +210.938f,26.0386f,85.9375f, +214.844f,24.1792f,85.9375f, +218.75f,22.1567f,85.9375f, +222.656f,20.1169f,85.9375f, +226.563f,19.3603f,85.9375f, +230.469f,17.7703f,85.9375f, +234.375f,16.3147f,85.9375f, +238.281f,15.0886f,85.9375f, +242.188f,15.1332f,85.9375f, +246.094f,14.7802f,85.9375f, +250.0f,15.2259f,85.9375f, +3.90625f,16.9644f,82.0313f, +7.8125f,17.8f,82.0313f, +11.7188f,19.2943f,82.0313f, +15.625f,21.0269f,82.0313f, +19.5313f,22.3312f,82.0313f, +23.4375f,23.0871f,82.0313f, +27.3438f,23.1115f,82.0313f, +31.25f,23.5304f,82.0313f, +35.1563f,24.1493f,82.0313f, +39.0625f,25.0848f,82.0313f, +42.9688f,26.0789f,82.0313f, +46.875f,26.3399f,82.0313f, +50.7813f,25.4397f,82.0313f, +54.6875f,24.894f,82.0313f, +58.5938f,24.1026f,82.0313f, +62.5f,24.0749f,82.0313f, +66.4063f,23.5256f,82.0313f, +70.3125f,21.9612f,82.0313f, +74.2188f,21.932f,82.0313f, +78.125f,22.6241f,82.0313f, +82.0313f,22.672f,82.0313f, +85.9375f,21.4303f,82.0313f, +89.8438f,21.6964f,82.0313f, +93.75f,21.7198f,82.0313f, +97.6563f,22.4953f,82.0313f, +101.563f,23.0451f,82.0313f, +105.469f,23.0285f,82.0313f, +109.375f,23.24f,82.0313f, +113.281f,23.6861f,82.0313f, +117.188f,24.7685f,82.0313f, +121.094f,26.4466f,82.0313f, +125.0f,28.8315f,82.0313f, +128.906f,30.9624f,82.0313f, +132.813f,33.7991f,82.0313f, +136.719f,35.8079f,82.0313f, +140.625f,37.0254f,82.0313f, +144.531f,38.7479f,82.0313f, +148.438f,42.0473f,82.0313f, +152.344f,43.7879f,82.0313f, +156.25f,45.1826f,82.0313f, +160.156f,46.2454f,82.0313f, +164.063f,47.0196f,82.0313f, +167.969f,47.2872f,82.0313f, +171.875f,46.2496f,82.0313f, +175.781f,44.3338f,82.0313f, +179.688f,43.1095f,82.0313f, +183.594f,40.7857f,82.0313f, +187.5f,39.646f,82.0313f, +191.406f,37.5425f,82.0313f, +195.313f,35.2951f,82.0313f, +199.219f,33.6324f,82.0313f, +203.125f,30.8911f,82.0313f, +207.031f,27.2798f,82.0313f, +210.938f,25.4308f,82.0313f, +214.844f,23.8814f,82.0313f, +218.75f,22.4441f,82.0313f, +222.656f,20.3771f,82.0313f, +226.563f,19.2073f,82.0313f, +230.469f,19.0082f,82.0313f, +234.375f,17.769f,82.0313f, +238.281f,15.8302f,82.0313f, +242.188f,14.2967f,82.0313f, +246.094f,15.1365f,82.0313f, +250.0f,14.9159f,82.0313f, +3.90625f,18.8244f,78.125f, +7.8125f,19.5283f,78.125f, +11.7188f,20.9466f,78.125f, +15.625f,22.0951f,78.125f, +19.5313f,23.2483f,78.125f, +23.4375f,23.8238f,78.125f, +27.3438f,24.6236f,78.125f, +31.25f,24.0856f,78.125f, +35.1563f,25.6129f,78.125f, +39.0625f,26.8525f,78.125f, +42.9688f,26.9859f,78.125f, +46.875f,26.6403f,78.125f, +50.7813f,26.6419f,78.125f, +54.6875f,27.4236f,78.125f, +58.5938f,26.5989f,78.125f, +62.5f,26.137f,78.125f, +66.4063f,24.8717f,78.125f, +70.3125f,23.8694f,78.125f, +74.2188f,23.2668f,78.125f, +78.125f,23.1081f,78.125f, +82.0313f,23.3134f,78.125f, +85.9375f,23.0903f,78.125f, +89.8438f,23.2822f,78.125f, +93.75f,24.291f,78.125f, +97.6563f,24.5546f,78.125f, +101.563f,24.4216f,78.125f, +105.469f,24.6379f,78.125f, +109.375f,24.5235f,78.125f, +113.281f,24.88f,78.125f, +117.188f,25.6988f,78.125f, +121.094f,26.9155f,78.125f, +125.0f,29.7499f,78.125f, +128.906f,31.361f,78.125f, +132.813f,33.9367f,78.125f, +136.719f,35.4066f,78.125f, +140.625f,36.6153f,78.125f, +144.531f,38.6091f,78.125f, +148.438f,41.2276f,78.125f, +152.344f,43.2187f,78.125f, +156.25f,45.2494f,78.125f, +160.156f,46.5334f,78.125f, +164.063f,47.1659f,78.125f, +167.969f,47.5409f,78.125f, +171.875f,46.3778f,78.125f, +175.781f,44.8935f,78.125f, +179.688f,43.7429f,78.125f, +183.594f,42.4748f,78.125f, +187.5f,40.5234f,78.125f, +191.406f,38.2806f,78.125f, +195.313f,36.297f,78.125f, +199.219f,35.0641f,78.125f, +203.125f,32.4145f,78.125f, +207.031f,29.4539f,78.125f, +210.938f,25.7399f,78.125f, +214.844f,23.157f,78.125f, +218.75f,20.9425f,78.125f, +222.656f,19.2349f,78.125f, +226.563f,18.5576f,78.125f, +230.469f,18.8407f,78.125f, +234.375f,17.6562f,78.125f, +238.281f,15.7207f,78.125f, +242.188f,14.3385f,78.125f, +246.094f,13.9958f,78.125f, +250.0f,14.6888f,78.125f, +3.90625f,20.6829f,74.2188f, +7.8125f,22.7393f,74.2188f, +11.7188f,22.9007f,74.2188f, +15.625f,23.3717f,74.2188f, +19.5313f,23.7991f,74.2188f, +23.4375f,24.5576f,74.2188f, +27.3438f,25.3464f,74.2188f, +31.25f,25.8349f,74.2188f, +35.1563f,26.2326f,74.2188f, +39.0625f,27.8003f,74.2188f, +42.9688f,28.502f,74.2188f, +46.875f,28.7947f,74.2188f, +50.7813f,29.109f,74.2188f, +54.6875f,29.4315f,74.2188f, +58.5938f,29.1948f,74.2188f, +62.5f,28.241f,74.2188f, +66.4063f,26.6727f,74.2188f, +70.3125f,25.5496f,74.2188f, +74.2188f,24.2265f,74.2188f, +78.125f,24.8641f,74.2188f, +82.0313f,24.8692f,74.2188f, +85.9375f,23.8066f,74.2188f, +89.8438f,24.5827f,74.2188f, +93.75f,25.5885f,74.2188f, +97.6563f,25.005f,74.2188f, +101.563f,25.4768f,74.2188f, +105.469f,25.8326f,74.2188f, +109.375f,25.8587f,74.2188f, +113.281f,26.8029f,74.2188f, +117.188f,27.8764f,74.2188f, +121.094f,28.8835f,74.2188f, +125.0f,30.0077f,74.2188f, +128.906f,31.9776f,74.2188f, +132.813f,34.2008f,74.2188f, +136.719f,35.4023f,74.2188f, +140.625f,36.3754f,74.2188f, +144.531f,38.9991f,74.2188f, +148.438f,41.295f,74.2188f, +152.344f,44.1131f,74.2188f, +156.25f,46.2221f,74.2188f, +160.156f,46.7797f,74.2188f, +164.063f,47.446f,74.2188f, +167.969f,47.1396f,74.2188f, +171.875f,45.9937f,74.2188f, +175.781f,45.4284f,74.2188f, +179.688f,45.018f,74.2188f, +183.594f,43.1233f,74.2188f, +187.5f,41.2272f,74.2188f, +191.406f,37.8072f,74.2188f, +195.313f,36.5304f,74.2188f, +199.219f,35.1638f,74.2188f, +203.125f,33.1538f,74.2188f, +207.031f,30.2207f,74.2188f, +210.938f,26.1665f,74.2188f, +214.844f,22.1619f,74.2188f, +218.75f,18.452f,74.2188f, +222.656f,17.0925f,74.2188f, +226.563f,17.3468f,74.2188f, +230.469f,16.447f,74.2188f, +234.375f,15.7197f,74.2188f, +238.281f,14.7889f,74.2188f, +242.188f,13.641f,74.2188f, +246.094f,12.7728f,74.2188f, +250.0f,13.3875f,74.2188f, +3.90625f,22.948f,70.3125f, +7.8125f,24.3431f,70.3125f, +11.7188f,24.6307f,70.3125f, +15.625f,24.9963f,70.3125f, +19.5313f,25.2034f,70.3125f, +23.4375f,25.2791f,70.3125f, +27.3438f,25.8257f,70.3125f, +31.25f,27.1123f,70.3125f, +35.1563f,27.8795f,70.3125f, +39.0625f,28.8437f,70.3125f, +42.9688f,29.8883f,70.3125f, +46.875f,30.6548f,70.3125f, +50.7813f,31.0396f,70.3125f, +54.6875f,31.6324f,70.3125f, +58.5938f,31.5222f,70.3125f, +62.5f,30.4696f,70.3125f, +66.4063f,28.7208f,70.3125f, +70.3125f,26.8611f,70.3125f, +74.2188f,25.6776f,70.3125f, +78.125f,26.1193f,70.3125f, +82.0313f,25.1971f,70.3125f, +85.9375f,24.4814f,70.3125f, +89.8438f,25.1213f,70.3125f, +93.75f,26.1411f,70.3125f, +97.6563f,26.4276f,70.3125f, +101.563f,26.0728f,70.3125f, +105.469f,26.113f,70.3125f, +109.375f,27.5702f,70.3125f, +113.281f,28.6199f,70.3125f, +117.188f,30.054f,70.3125f, +121.094f,30.255f,70.3125f, +125.0f,30.9839f,70.3125f, +128.906f,32.4045f,70.3125f, +132.813f,33.9858f,70.3125f, +136.719f,35.8568f,70.3125f, +140.625f,37.5803f,70.3125f, +144.531f,40.2984f,70.3125f, +148.438f,41.9326f,70.3125f, +152.344f,44.1607f,70.3125f, +156.25f,45.6454f,70.3125f, +160.156f,47.3567f,70.3125f, +164.063f,48.1147f,70.3125f, +167.969f,47.7671f,70.3125f, +171.875f,46.1009f,70.3125f, +175.781f,45.3829f,70.3125f, +179.688f,44.3458f,70.3125f, +183.594f,42.818f,70.3125f, +187.5f,40.5253f,70.3125f, +191.406f,37.6731f,70.3125f, +195.313f,36.7234f,70.3125f, +199.219f,35.0848f,70.3125f, +203.125f,33.0857f,70.3125f, +207.031f,30.0508f,70.3125f, +210.938f,26.741f,70.3125f, +214.844f,22.7613f,70.3125f, +218.75f,18.5375f,70.3125f, +222.656f,15.6052f,70.3125f, +226.563f,14.6945f,70.3125f, +230.469f,15.0013f,70.3125f, +234.375f,13.9965f,70.3125f, +238.281f,12.4404f,70.3125f, +242.188f,12.4448f,70.3125f, +246.094f,11.7446f,70.3125f, +250.0f,11.7886f,70.3125f, +3.90625f,25.5564f,66.4063f, +7.8125f,26.1216f,66.4063f, +11.7188f,26.234f,66.4063f, +15.625f,26.4553f,66.4063f, +19.5313f,26.9827f,66.4063f, +23.4375f,27.0173f,66.4063f, +27.3438f,27.3577f,66.4063f, +31.25f,28.895f,66.4063f, +35.1563f,30.1057f,66.4063f, +39.0625f,30.249f,66.4063f, +42.9688f,31.1394f,66.4063f, +46.875f,31.7197f,66.4063f, +50.7813f,33.2905f,66.4063f, +54.6875f,33.6208f,66.4063f, +58.5938f,33.5152f,66.4063f, +62.5f,31.5128f,66.4063f, +66.4063f,30.1049f,66.4063f, +70.3125f,28.9139f,66.4063f, +74.2188f,27.093f,66.4063f, +78.125f,26.8272f,66.4063f, +82.0313f,25.8777f,66.4063f, +85.9375f,25.2597f,66.4063f, +89.8438f,25.8742f,66.4063f, +93.75f,27.4783f,66.4063f, +97.6563f,27.1897f,66.4063f, +101.563f,26.8406f,66.4063f, +105.469f,27.2889f,66.4063f, +109.375f,28.6616f,66.4063f, +113.281f,29.2852f,66.4063f, +117.188f,30.3362f,66.4063f, +121.094f,32.0648f,66.4063f, +125.0f,32.6693f,66.4063f, +128.906f,33.7239f,66.4063f, +132.813f,34.8193f,66.4063f, +136.719f,36.6878f,66.4063f, +140.625f,38.5422f,66.4063f, +144.531f,40.5193f,66.4063f, +148.438f,42.0434f,66.4063f, +152.344f,43.692f,66.4063f, +156.25f,46.2f,66.4063f, +160.156f,47.7247f,66.4063f, +164.063f,48.3486f,66.4063f, +167.969f,48.4057f,66.4063f, +171.875f,47.4141f,66.4063f, +175.781f,45.925f,66.4063f, +179.688f,44.0772f,66.4063f, +183.594f,42.0866f,66.4063f, +187.5f,40.2687f,66.4063f, +191.406f,38.0236f,66.4063f, +195.313f,36.9223f,66.4063f, +199.219f,35.6323f,66.4063f, +203.125f,33.0001f,66.4063f, +207.031f,30.1425f,66.4063f, +210.938f,26.4551f,66.4063f, +214.844f,22.4224f,66.4063f, +218.75f,18.5557f,66.4063f, +222.656f,16.1428f,66.4063f, +226.563f,14.9942f,66.4063f, +230.469f,14.9221f,66.4063f, +234.375f,13.3816f,66.4063f, +238.281f,10.9914f,66.4063f, +242.188f,10.6094f,66.4063f, +246.094f,9.77905f,66.4063f, +250.0f,9.99853f,66.4063f, +3.90625f,27.1929f,62.5f, +7.8125f,28.1411f,62.5f, +11.7188f,27.9312f,62.5f, +15.625f,27.692f,62.5f, +19.5313f,27.8511f,62.5f, +23.4375f,28.2162f,62.5f, +27.3438f,29.5518f,62.5f, +31.25f,30.2367f,62.5f, +35.1563f,31.1075f,62.5f, +39.0625f,31.6239f,62.5f, +42.9688f,32.8498f,62.5f, +46.875f,33.1521f,62.5f, +50.7813f,34.6411f,62.5f, +54.6875f,35.0063f,62.5f, +58.5938f,33.8006f,62.5f, +62.5f,33.1029f,62.5f, +66.4063f,32.1466f,62.5f, +70.3125f,30.2614f,62.5f, +74.2188f,28.2978f,62.5f, +78.125f,28.0764f,62.5f, +82.0313f,27.2473f,62.5f, +85.9375f,26.2769f,62.5f, +89.8438f,26.2922f,62.5f, +93.75f,27.1235f,62.5f, +97.6563f,27.498f,62.5f, +101.563f,27.2257f,62.5f, +105.469f,28.2897f,62.5f, +109.375f,28.8921f,62.5f, +113.281f,30.563f,62.5f, +117.188f,32.1298f,62.5f, +121.094f,32.8639f,62.5f, +125.0f,34.6537f,62.5f, +128.906f,35.4867f,62.5f, +132.813f,36.6181f,62.5f, +136.719f,37.6418f,62.5f, +140.625f,39.2228f,62.5f, +144.531f,40.5105f,62.5f, +148.438f,42.215f,62.5f, +152.344f,43.5394f,62.5f, +156.25f,45.1171f,62.5f, +160.156f,46.6711f,62.5f, +164.063f,47.4274f,62.5f, +167.969f,47.6821f,62.5f, +171.875f,48.0762f,62.5f, +175.781f,46.4607f,62.5f, +179.688f,44.7623f,62.5f, +183.594f,42.6372f,62.5f, +187.5f,40.3231f,62.5f, +191.406f,38.4371f,62.5f, +195.313f,36.1978f,62.5f, +199.219f,35.38f,62.5f, +203.125f,32.0325f,62.5f, +207.031f,29.2047f,62.5f, +210.938f,27.481f,62.5f, +214.844f,24.0627f,62.5f, +218.75f,20.6235f,62.5f, +222.656f,18.5468f,62.5f, +226.563f,17.2736f,62.5f, +230.469f,15.4125f,62.5f, +234.375f,13.6775f,62.5f, +238.281f,11.4407f,62.5f, +242.188f,9.73154f,62.5f, +246.094f,8.55197f,62.5f, +250.0f,8.43693f,62.5f, +3.90625f,28.3495f,58.5938f, +7.8125f,28.8832f,58.5938f, +11.7188f,28.5512f,58.5938f, +15.625f,28.8533f,58.5938f, +19.5313f,29.0576f,58.5938f, +23.4375f,30.3079f,58.5938f, +27.3438f,31.3861f,58.5938f, +31.25f,33.0252f,58.5938f, +35.1563f,33.4087f,58.5938f, +39.0625f,34.3736f,58.5938f, +42.9688f,34.6944f,58.5938f, +46.875f,34.1156f,58.5938f, +50.7813f,34.7246f,58.5938f, +54.6875f,35.3934f,58.5938f, +58.5938f,34.9508f,58.5938f, +62.5f,34.469f,58.5938f, +66.4063f,33.1584f,58.5938f, +70.3125f,30.5913f,58.5938f, +74.2188f,30.4147f,58.5938f, +78.125f,30.821f,58.5938f, +82.0313f,29.9244f,58.5938f, +85.9375f,28.365f,58.5938f, +89.8438f,27.8694f,58.5938f, +93.75f,27.7517f,58.5938f, +97.6563f,27.9188f,58.5938f, +101.563f,27.7605f,58.5938f, +105.469f,28.252f,58.5938f, +109.375f,29.4592f,58.5938f, +113.281f,31.2608f,58.5938f, +117.188f,33.5373f,58.5938f, +121.094f,34.4995f,58.5938f, +125.0f,35.1593f,58.5938f, +128.906f,36.6148f,58.5938f, +132.813f,37.1425f,58.5938f, +136.719f,38.2148f,58.5938f, +140.625f,38.9964f,58.5938f, +144.531f,40.3196f,58.5938f, +148.438f,42.4959f,58.5938f, +152.344f,43.37f,58.5938f, +156.25f,44.3488f,58.5938f, +160.156f,45.6441f,58.5937f, +164.063f,45.6597f,58.5937f, +167.969f,46.9631f,58.5938f, +171.875f,47.0933f,58.5938f, +175.781f,45.839f,58.5937f, +179.688f,44.0491f,58.5937f, +183.594f,41.6462f,58.5938f, +187.5f,39.9012f,58.5938f, +191.406f,37.8373f,58.5938f, +195.313f,35.0871f,58.5938f, +199.219f,34.6045f,58.5938f, +203.125f,32.4469f,58.5938f, +207.031f,30.5103f,58.5938f, +210.938f,28.7194f,58.5938f, +214.844f,26.3358f,58.5938f, +218.75f,24.3668f,58.5938f, +222.656f,22.1719f,58.5938f, +226.563f,20.1708f,58.5938f, +230.469f,18.1384f,58.5938f, +234.375f,15.6994f,58.5938f, +238.281f,12.6124f,58.5938f, +242.188f,11.2279f,58.5938f, +246.094f,10.4938f,58.5938f, +250.0f,9.45058f,58.5938f, +3.90625f,29.2057f,54.6875f, +7.8125f,29.4161f,54.6875f, +11.7188f,29.6274f,54.6875f, +15.625f,29.8747f,54.6875f, +19.5313f,31.3353f,54.6875f, +23.4375f,32.5261f,54.6875f, +27.3438f,34.3893f,54.6875f, +31.25f,34.9525f,54.6875f, +35.1563f,35.8992f,54.6875f, +39.0625f,36.2066f,54.6875f, +42.9688f,36.4212f,54.6875f, +46.875f,36.1377f,54.6875f, +50.7813f,35.4213f,54.6875f, +54.6875f,35.5045f,54.6875f, +58.5938f,36.0891f,54.6875f, +62.5f,36.0244f,54.6875f, +66.4063f,34.9086f,54.6875f, +70.3125f,32.8671f,54.6875f, +74.2188f,33.5578f,54.6875f, +78.125f,33.8468f,54.6875f, +82.0313f,32.868f,54.6875f, +85.9375f,31.2245f,54.6875f, +89.8438f,29.442f,54.6875f, +93.75f,28.9144f,54.6875f, +97.6563f,27.6797f,54.6875f, +101.563f,27.9585f,54.6875f, +105.469f,28.5492f,54.6875f, +109.375f,29.119f,54.6875f, +113.281f,30.7234f,54.6875f, +117.188f,32.402f,54.6875f, +121.094f,34.3605f,54.6875f, +125.0f,35.6614f,54.6875f, +128.906f,37.1814f,54.6875f, +132.813f,37.8509f,54.6875f, +136.719f,38.3282f,54.6875f, +140.625f,39.021f,54.6875f, +144.531f,39.8455f,54.6875f, +148.438f,41.3547f,54.6875f, +152.344f,42.0848f,54.6875f, +156.25f,42.4546f,54.6875f, +160.156f,43.3035f,54.6875f, +164.063f,44.2757f,54.6875f, +167.969f,45.0917f,54.6875f, +171.875f,44.9479f,54.6875f, +175.781f,44.386f,54.6875f, +179.688f,43.1031f,54.6875f, +183.594f,41.5243f,54.6875f, +187.5f,39.9976f,54.6875f, +191.406f,37.1931f,54.6875f, +195.313f,35.2297f,54.6875f, +199.219f,34.439f,54.6875f, +203.125f,32.7399f,54.6875f, +207.031f,31.4766f,54.6875f, +210.938f,29.9402f,54.6875f, +214.844f,28.6752f,54.6875f, +218.75f,27.0387f,54.6875f, +222.656f,24.4777f,54.6875f, +226.563f,21.7169f,54.6875f, +230.469f,20.0299f,54.6875f, +234.375f,17.3103f,54.6875f, +238.281f,14.1891f,54.6875f, +242.188f,12.1605f,54.6875f, +246.094f,10.9065f,54.6875f, +250.0f,10.6619f,54.6875f, +3.90625f,30.4306f,50.7813f, +7.8125f,30.9679f,50.7813f, +11.7188f,31.3065f,50.7813f, +15.625f,32.0527f,50.7813f, +19.5313f,33.9185f,50.7813f, +23.4375f,34.6834f,50.7813f, +27.3438f,35.8025f,50.7813f, +31.25f,36.824f,50.7813f, +35.1563f,37.9949f,50.7813f, +39.0625f,38.2428f,50.7813f, +42.9688f,37.3912f,50.7813f, +46.875f,37.2849f,50.7813f, +50.7813f,36.4441f,50.7813f, +54.6875f,36.5986f,50.7813f, +58.5938f,36.7371f,50.7813f, +62.5f,36.6154f,50.7813f, +66.4063f,35.9475f,50.7813f, +70.3125f,35.1832f,50.7813f, +74.2188f,35.7876f,50.7813f, +78.125f,35.9086f,50.7813f, +82.0313f,35.0048f,50.7813f, +85.9375f,33.7202f,50.7813f, +89.8438f,32.6473f,50.7813f, +93.75f,30.9552f,50.7813f, +97.6563f,28.7453f,50.7813f, +101.563f,29.1526f,50.7813f, +105.469f,29.9957f,50.7813f, +109.375f,30.5544f,50.7813f, +113.281f,31.6947f,50.7813f, +117.188f,32.7584f,50.7813f, +121.094f,34.2518f,50.7813f, +125.0f,36.3694f,50.7813f, +128.906f,36.9477f,50.7813f, +132.813f,37.2918f,50.7813f, +136.719f,37.8325f,50.7813f, +140.625f,38.0845f,50.7813f, +144.531f,40.0088f,50.7813f, +148.438f,40.8219f,50.7813f, +152.344f,42.4039f,50.7813f, +156.25f,42.6086f,50.7813f, +160.156f,43.5487f,50.7813f, +164.063f,43.5328f,50.7813f, +167.969f,44.212f,50.7812f, +171.875f,43.6744f,50.7813f, +175.781f,43.198f,50.7813f, +179.688f,42.957f,50.7813f, +183.594f,41.4993f,50.7813f, +187.5f,39.5101f,50.7813f, +191.406f,38.1729f,50.7813f, +195.313f,35.4881f,50.7813f, +199.219f,34.6384f,50.7813f, +203.125f,34.1873f,50.7813f, +207.031f,32.1155f,50.7813f, +210.938f,30.912f,50.7813f, +214.844f,30.3391f,50.7813f, +218.75f,28.1256f,50.7813f, +222.656f,24.902f,50.7813f, +226.563f,22.2443f,50.7813f, +230.469f,20.9172f,50.7813f, +234.375f,18.8508f,50.7813f, +238.281f,15.9912f,50.7813f, +242.188f,12.7716f,50.7813f, +246.094f,11.6189f,50.7813f, +250.0f,12.2688f,50.7813f, +3.90625f,30.8772f,46.875f, +7.8125f,32.4754f,46.875f, +11.7188f,33.6983f,46.875f, +15.625f,35.14f,46.875f, +19.5313f,37.0369f,46.875f, +23.4375f,38.369f,46.875f, +27.3438f,38.6134f,46.875f, +31.25f,38.9784f,46.875f, +35.1563f,39.9891f,46.875f, +39.0625f,40.3197f,46.875f, +42.9688f,39.9692f,46.875f, +46.875f,39.6994f,46.875f, +50.7813f,39.4183f,46.875f, +54.6875f,38.2948f,46.875f, +58.5938f,38.32f,46.875f, +62.5f,38.621f,46.875f, +66.4063f,38.2134f,46.875f, +70.3125f,36.9577f,46.875f, +74.2188f,37.2936f,46.875f, +78.125f,37.8653f,46.875f, +82.0313f,36.9058f,46.875f, +85.9375f,36.1841f,46.875f, +89.8438f,34.8143f,46.875f, +93.75f,33.0783f,46.875f, +97.6563f,30.9854f,46.875f, +101.563f,30.934f,46.875f, +105.469f,32.108f,46.875f, +109.375f,33.0462f,46.875f, +113.281f,32.9253f,46.875f, +117.188f,33.3377f,46.875f, +121.094f,34.2153f,46.875f, +125.0f,35.0739f,46.875f, +128.906f,36.8239f,46.875f, +132.813f,37.1463f,46.875f, +136.719f,37.5409f,46.875f, +140.625f,38.8265f,46.875f, +144.531f,40.7241f,46.875f, +148.438f,40.9349f,46.875f, +152.344f,42.4491f,46.875f, +156.25f,43.9695f,46.875f, +160.156f,44.2191f,46.875f, +164.063f,44.9265f,46.875f, +167.969f,43.9423f,46.875f, +171.875f,43.273f,46.875f, +175.781f,43.2543f,46.875f, +179.688f,42.5328f,46.875f, +183.594f,41.1777f,46.875f, +187.5f,39.3553f,46.875f, +191.406f,37.8242f,46.875f, +195.313f,36.4649f,46.875f, +199.219f,35.6955f,46.875f, +203.125f,35.1878f,46.875f, +207.031f,32.9438f,46.875f, +210.938f,31.3677f,46.875f, +214.844f,30.7282f,46.875f, +218.75f,28.3328f,46.875f, +222.656f,25.0599f,46.875f, +226.563f,24.1932f,46.875f, +230.469f,22.3853f,46.875f, +234.375f,19.4896f,46.875f, +238.281f,16.8753f,46.875f, +242.188f,13.9469f,46.875f, +246.094f,13.2975f,46.875f, +250.0f,13.2524f,46.875f, +3.90625f,31.8945f,42.9688f, +7.8125f,34.0117f,42.9688f, +11.7188f,36.2441f,42.9688f, +15.625f,37.3622f,42.9688f, +19.5313f,39.5877f,42.9688f, +23.4375f,41.0994f,42.9688f, +27.3438f,42.0864f,42.9688f, +31.25f,42.0849f,42.9688f, +35.1563f,42.2038f,42.9688f, +39.0625f,43.473f,42.9688f, +42.9688f,42.7754f,42.9688f, +46.875f,42.3177f,42.9688f, +50.7813f,42.209f,42.9688f, +54.6875f,41.3095f,42.9688f, +58.5938f,40.8629f,42.9688f, +62.5f,40.4776f,42.9688f, +66.4063f,40.1396f,42.9688f, +70.3125f,39.1169f,42.9688f, +74.2188f,39.1382f,42.9688f, +78.125f,39.1421f,42.9688f, +82.0313f,38.9022f,42.9688f, +85.9375f,37.5711f,42.9688f, +89.8438f,36.7924f,42.9688f, +93.75f,34.7734f,42.9688f, +97.6563f,33.167f,42.9688f, +101.563f,32.4173f,42.9688f, +105.469f,33.0466f,42.9688f, +109.375f,33.3882f,42.9688f, +113.281f,33.7538f,42.9688f, +117.188f,33.5661f,42.9688f, +121.094f,33.9051f,42.9688f, +125.0f,34.9181f,42.9688f, +128.906f,35.2925f,42.9688f, +132.813f,37.1741f,42.9688f, +136.719f,38.0993f,42.9688f, +140.625f,38.7621f,42.9688f, +144.531f,39.712f,42.9688f, +148.438f,40.7257f,42.9688f, +152.344f,42.2465f,42.9688f, +156.25f,43.5331f,42.9688f, +160.156f,44.6745f,42.9687f, +164.063f,44.564f,42.9688f, +167.969f,44.6075f,42.9688f, +171.875f,43.2227f,42.9688f, +175.781f,42.5688f,42.9688f, +179.688f,41.9742f,42.9688f, +183.594f,40.3484f,42.9688f, +187.5f,38.9109f,42.9688f, +191.406f,37.7273f,42.9688f, +195.313f,36.5287f,42.9688f, +199.219f,35.9361f,42.9688f, +203.125f,35.1638f,42.9688f, +207.031f,33.6615f,42.9688f, +210.938f,31.2785f,42.9688f, +214.844f,30.1259f,42.9688f, +218.75f,28.6143f,42.9688f, +222.656f,26.1162f,42.9688f, +226.563f,24.2882f,42.9688f, +230.469f,22.5195f,42.9688f, +234.375f,20.1462f,42.9688f, +238.281f,17.4811f,42.9688f, +242.188f,15.2736f,42.9688f, +246.094f,13.788f,42.9688f, +250.0f,13.1723f,42.9688f, +3.90625f,34.9171f,39.0625f, +7.8125f,36.7711f,39.0625f, +11.7188f,38.5677f,39.0625f, +15.625f,40.0524f,39.0625f, +19.5313f,42.2392f,39.0625f, +23.4375f,43.2332f,39.0625f, +27.3438f,44.8254f,39.0625f, +31.25f,45.1808f,39.0625f, +35.1563f,44.9684f,39.0625f, +39.0625f,45.0647f,39.0625f, +42.9688f,45.0888f,39.0625f, +46.875f,45.5266f,39.0625f, +50.7813f,45.2542f,39.0625f, +54.6875f,44.1797f,39.0625f, +58.5938f,43.2658f,39.0625f, +62.5f,42.7568f,39.0625f, +66.4063f,42.4159f,39.0625f, +70.3125f,41.3883f,39.0625f, +74.2188f,41.1975f,39.0625f, +78.125f,41.3073f,39.0625f, +82.0313f,41.0587f,39.0625f, +85.9375f,40.0611f,39.0625f, +89.8438f,38.7299f,39.0625f, +93.75f,37.2923f,39.0625f, +97.6563f,35.7971f,39.0625f, +101.563f,35.1982f,39.0625f, +105.469f,33.6408f,39.0625f, +109.375f,33.2619f,39.0625f, +113.281f,33.8387f,39.0625f, +117.188f,34.7554f,39.0625f, +121.094f,33.8569f,39.0625f, +125.0f,34.7741f,39.0625f, +128.906f,35.7319f,39.0625f, +132.813f,36.6023f,39.0625f, +136.719f,37.7084f,39.0625f, +140.625f,38.2513f,39.0625f, +144.531f,39.1992f,39.0625f, +148.438f,40.2336f,39.0625f, +152.344f,41.0883f,39.0625f, +156.25f,42.4004f,39.0625f, +160.156f,42.8753f,39.0625f, +164.063f,43.1631f,39.0625f, +167.969f,43.6378f,39.0625f, +171.875f,43.2113f,39.0625f, +175.781f,42.5474f,39.0625f, +179.688f,41.3413f,39.0625f, +183.594f,39.4383f,39.0625f, +187.5f,38.9723f,39.0625f, +191.406f,37.3549f,39.0625f, +195.313f,35.8615f,39.0625f, +199.219f,34.9243f,39.0625f, +203.125f,34.598f,39.0625f, +207.031f,33.6592f,39.0625f, +210.938f,32.2347f,39.0625f, +214.844f,30.4117f,39.0625f, +218.75f,28.4787f,39.0625f, +222.656f,26.6538f,39.0625f, +226.563f,24.4892f,39.0625f, +230.469f,22.9637f,39.0625f, +234.375f,20.6363f,39.0625f, +238.281f,18.4584f,39.0625f, +242.188f,16.293f,39.0625f, +246.094f,13.7473f,39.0625f, +250.0f,13.2449f,39.0625f, +3.90625f,38.5427f,35.1563f, +7.8125f,39.2771f,35.1563f, +11.7188f,40.4801f,35.1563f, +15.625f,42.2714f,35.1563f, +19.5313f,44.0743f,35.1562f, +23.4375f,45.9071f,35.1562f, +27.3438f,47.4425f,35.1563f, +31.25f,47.765f,35.1563f, +35.1563f,46.8453f,35.1562f, +39.0625f,47.1161f,35.1562f, +42.9688f,46.591f,35.1563f, +46.875f,47.4064f,35.1563f, +50.7813f,47.2001f,35.1562f, +54.6875f,47.2372f,35.1562f, +58.5938f,46.9666f,35.1563f, +62.5f,45.3322f,35.1563f, +66.4063f,44.4351f,35.1562f, +70.3125f,43.869f,35.1562f, +74.2188f,43.7604f,35.1563f, +78.125f,43.6414f,35.1563f, +82.0313f,43.6044f,35.1563f, +85.9375f,41.9765f,35.1563f, +89.8438f,40.597f,35.1563f, +93.75f,38.8088f,35.1563f, +97.6563f,37.4254f,35.1563f, +101.563f,36.4869f,35.1563f, +105.469f,34.7975f,35.1563f, +109.375f,32.6051f,35.1563f, +113.281f,32.3929f,35.1563f, +117.188f,33.3906f,35.1563f, +121.094f,33.728f,35.1563f, +125.0f,33.8089f,35.1563f, +128.906f,35.2443f,35.1563f, +132.813f,35.9877f,35.1563f, +136.719f,36.3747f,35.1563f, +140.625f,37.6045f,35.1563f, +144.531f,38.3698f,35.1563f, +148.438f,39.393f,35.1563f, +152.344f,40.0115f,35.1563f, +156.25f,40.8722f,35.1563f, +160.156f,40.7302f,35.1563f, +164.063f,41.6767f,35.1563f, +167.969f,42.1719f,35.1563f, +171.875f,41.924f,35.1563f, +175.781f,40.9628f,35.1563f, +179.688f,39.3209f,35.1563f, +183.594f,37.9615f,35.1563f, +187.5f,37.2902f,35.1563f, +191.406f,36.1521f,35.1563f, +195.313f,35.5697f,35.1563f, +199.219f,35.0547f,35.1563f, +203.125f,33.8422f,35.1563f, +207.031f,33.1699f,35.1563f, +210.938f,32.4197f,35.1563f, +214.844f,31.0723f,35.1563f, +218.75f,29.1069f,35.1563f, +222.656f,26.4015f,35.1563f, +226.563f,23.6862f,35.1563f, +230.469f,22.3142f,35.1563f, +234.375f,20.9225f,35.1563f, +238.281f,18.6533f,35.1563f, +242.188f,16.5438f,35.1563f, +246.094f,14.5457f,35.1563f, +250.0f,13.5112f,35.1563f, +3.90625f,41.4381f,31.25f, +7.8125f,41.4661f,31.25f, +11.7188f,42.5211f,31.25f, +15.625f,44.1517f,31.25f, +19.5313f,45.8301f,31.25f, +23.4375f,47.3213f,31.25f, +27.3438f,49.1504f,31.25f, +31.25f,49.1313f,31.25f, +35.1563f,48.4621f,31.25f, +39.0625f,48.0866f,31.25f, +42.9688f,47.5259f,31.25f, +46.875f,48.2042f,31.25f, +50.7813f,48.2678f,31.25f, +54.6875f,48.6796f,31.25f, +58.5938f,49.1508f,31.25f, +62.5f,48.5261f,31.25f, +66.4063f,47.2699f,31.25f, +70.3125f,46.3239f,31.25f, +74.2188f,45.9053f,31.25f, +78.125f,45.2948f,31.25f, +82.0313f,45.1222f,31.25f, +85.9375f,44.1773f,31.25f, +89.8438f,42.0751f,31.25f, +93.75f,39.8181f,31.25f, +97.6563f,38.1904f,31.25f, +101.563f,36.9029f,31.25f, +105.469f,35.9897f,31.25f, +109.375f,34.1082f,31.25f, +113.281f,33.9882f,31.25f, +117.188f,33.4544f,31.25f, +121.094f,32.7435f,31.25f, +125.0f,32.2982f,31.25f, +128.906f,33.2893f,31.25f, +132.813f,34.4302f,31.25f, +136.719f,35.501f,31.25f, +140.625f,36.4162f,31.25f, +144.531f,38.0795f,31.25f, +148.438f,38.4184f,31.25f, +152.344f,38.1695f,31.25f, +156.25f,39.1334f,31.25f, +160.156f,39.8018f,31.25f, +164.063f,40.4009f,31.25f, +167.969f,40.6662f,31.25f, +171.875f,40.6389f,31.25f, +175.781f,40.0005f,31.25f, +179.688f,38.1437f,31.25f, +183.594f,36.1677f,31.25f, +187.5f,35.7553f,31.25f, +191.406f,35.2539f,31.25f, +195.313f,34.5258f,31.25f, +199.219f,33.9511f,31.25f, +203.125f,33.8209f,31.25f, +207.031f,32.5194f,31.25f, +210.938f,31.6797f,31.25f, +214.844f,30.494f,31.25f, +218.75f,28.9089f,31.25f, +222.656f,27.096f,31.25f, +226.563f,23.5752f,31.25f, +230.469f,22.5423f,31.25f, +234.375f,20.8438f,31.25f, +238.281f,18.7938f,31.25f, +242.188f,16.7022f,31.25f, +246.094f,14.6115f,31.25f, +250.0f,12.7758f,31.25f, +3.90625f,42.7334f,27.3437f, +7.8125f,43.3658f,27.3438f, +11.7188f,44.93f,27.3437f, +15.625f,46.7113f,27.3438f, +19.5313f,48.1031f,27.3437f, +23.4375f,48.7173f,27.3438f, +27.3438f,49.0875f,27.3437f, +31.25f,50.1272f,27.3438f, +35.1563f,49.1784f,27.3437f, +39.0625f,50.4569f,27.3438f, +42.9688f,49.7216f,27.3437f, +46.875f,49.0563f,27.3438f, +50.7813f,48.7494f,27.3437f, +54.6875f,49.0519f,27.3438f, +58.5938f,49.8264f,27.3437f, +62.5f,49.8194f,27.3438f, +66.4063f,48.9033f,27.3437f, +70.3125f,47.5002f,27.3438f, +74.2188f,46.7308f,27.3437f, +78.125f,45.8132f,27.3438f, +82.0313f,45.4303f,27.3437f, +85.9375f,44.4837f,27.3438f, +89.8438f,42.6706f,27.3437f, +93.75f,40.5108f,27.3438f, +97.6563f,38.4748f,27.3437f, +101.563f,38.2458f,27.3438f, +105.469f,37.8191f,27.3437f, +109.375f,37.5503f,27.3438f, +113.281f,36.4883f,27.3437f, +117.188f,35.7025f,27.3438f, +121.094f,34.3569f,27.3437f, +125.0f,34.052f,27.3438f, +128.906f,34.3166f,27.3437f, +132.813f,33.9873f,27.3438f, +136.719f,33.8326f,27.3437f, +140.625f,35.5138f,27.3438f, +144.531f,35.9847f,27.3437f, +148.438f,36.3159f,27.3438f, +152.344f,38.1026f,27.3437f, +156.25f,39.0191f,27.3438f, +160.156f,39.0705f,27.3437f, +164.063f,38.9644f,27.3438f, +167.969f,38.0972f,27.3437f, +171.875f,38.277f,27.3438f, +175.781f,37.5686f,27.3437f, +179.688f,35.9897f,27.3438f, +183.594f,34.1554f,27.3437f, +187.5f,33.9646f,27.3438f, +191.406f,33.9556f,27.3437f, +195.313f,33.7374f,27.3438f, +199.219f,33.3736f,27.3437f, +203.125f,32.1967f,27.3438f, +207.031f,32.2131f,27.3437f, +210.938f,30.4757f,27.3438f, +214.844f,29.0495f,27.3437f, +218.75f,27.539f,27.3438f, +222.656f,25.7435f,27.3437f, +226.563f,23.5358f,27.3438f, +230.469f,22.5305f,27.3437f, +234.375f,20.3466f,27.3438f, +238.281f,18.5956f,27.3438f, +242.188f,16.6554f,27.3438f, +246.094f,14.7633f,27.3438f, +250.0f,12.979f,27.3438f, +3.90625f,44.6783f,23.4375f, +7.8125f,46.1279f,23.4375f, +11.7188f,47.9921f,23.4375f, +15.625f,48.593f,23.4375f, +19.5313f,49.826f,23.4375f, +23.4375f,50.0111f,23.4375f, +27.3438f,49.773f,23.4375f, +31.25f,50.6443f,23.4375f, +35.1563f,50.242f,23.4375f, +39.0625f,51.5289f,23.4375f, +42.9688f,51.3905f,23.4375f, +46.875f,50.5543f,23.4375f, +50.7813f,49.96f,23.4375f, +54.6875f,51.029f,23.4375f, +58.5938f,50.4996f,23.4375f, +62.5f,50.0508f,23.4375f, +66.4063f,49.4463f,23.4375f, +70.3125f,48.7613f,23.4375f, +74.2188f,48.0188f,23.4375f, +78.125f,48.0992f,23.4375f, +82.0313f,47.1947f,23.4375f, +85.9375f,45.1889f,23.4375f, +89.8438f,43.9247f,23.4375f, +93.75f,41.7965f,23.4375f, +97.6563f,40.363f,23.4375f, +101.563f,40.3201f,23.4375f, +105.469f,39.2422f,23.4375f, +109.375f,38.6318f,23.4375f, +113.281f,37.9263f,23.4375f, +117.188f,37.113f,23.4375f, +121.094f,35.4884f,23.4375f, +125.0f,35.8385f,23.4375f, +128.906f,35.4941f,23.4375f, +132.813f,34.1911f,23.4375f, +136.719f,33.6791f,23.4375f, +140.625f,33.4506f,23.4375f, +144.531f,35.4822f,23.4375f, +148.438f,36.0187f,23.4375f, +152.344f,38.231f,23.4375f, +156.25f,39.1197f,23.4375f, +160.156f,38.9095f,23.4375f, +164.063f,38.1737f,23.4375f, +167.969f,36.7498f,23.4375f, +171.875f,36.6113f,23.4375f, +175.781f,35.5895f,23.4375f, +179.688f,34.7415f,23.4375f, +183.594f,32.6574f,23.4375f, +187.5f,32.5837f,23.4375f, +191.406f,32.5272f,23.4375f, +195.313f,32.3611f,23.4375f, +199.219f,31.4784f,23.4375f, +203.125f,30.8078f,23.4375f, +207.031f,29.9524f,23.4375f, +210.938f,29.9998f,23.4375f, +214.844f,28.4828f,23.4375f, +218.75f,26.6709f,23.4375f, +222.656f,24.9874f,23.4375f, +226.563f,23.0213f,23.4375f, +230.469f,21.3587f,23.4375f, +234.375f,19.0527f,23.4375f, +238.281f,18.1056f,23.4375f, +242.188f,16.7916f,23.4375f, +246.094f,14.9561f,23.4375f, +250.0f,13.0063f,23.4375f, +3.90625f,46.9055f,19.5312f, +7.8125f,48.3769f,19.5312f, +11.7188f,50.0613f,19.5312f, +15.625f,50.9962f,19.5312f, +19.5313f,51.161f,19.5312f, +23.4375f,51.7721f,19.5312f, +27.3438f,51.5823f,19.5312f, +31.25f,51.5274f,19.5312f, +35.1563f,51.5913f,19.5312f, +39.0625f,52.4399f,19.5312f, +42.9688f,52.5999f,19.5312f, +46.875f,51.9309f,19.5312f, +50.7813f,51.6062f,19.5312f, +54.6875f,50.86f,19.5312f, +58.5938f,51.1496f,19.5312f, +62.5f,50.1957f,19.5312f, +66.4063f,49.8047f,19.5312f, +70.3125f,49.1838f,19.5312f, +74.2188f,48.7276f,19.5312f, +78.125f,48.4967f,19.5312f, +82.0313f,47.4515f,19.5312f, +85.9375f,46.2594f,19.5312f, +89.8438f,44.6756f,19.5312f, +93.75f,43.0377f,19.5312f, +97.6563f,41.3508f,19.5312f, +101.563f,40.8261f,19.5312f, +105.469f,40.5524f,19.5312f, +109.375f,39.7289f,19.5312f, +113.281f,38.9437f,19.5312f, +117.188f,38.3781f,19.5312f, +121.094f,36.9618f,19.5312f, +125.0f,35.9735f,19.5312f, +128.906f,35.3887f,19.5312f, +132.813f,34.5133f,19.5312f, +136.719f,34.7253f,19.5312f, +140.625f,33.9228f,19.5312f, +144.531f,34.2826f,19.5312f, +148.438f,35.5643f,19.5312f, +152.344f,37.7492f,19.5312f, +156.25f,38.7871f,19.5312f, +160.156f,38.6036f,19.5312f, +164.063f,38.2702f,19.5312f, +167.969f,35.931f,19.5312f, +171.875f,34.8252f,19.5312f, +175.781f,33.99f,19.5312f, +179.688f,33.664f,19.5312f, +183.594f,31.6973f,19.5312f, +187.5f,31.3559f,19.5312f, +191.406f,31.3589f,19.5312f, +195.313f,30.7614f,19.5312f, +199.219f,29.2596f,19.5312f, +203.125f,28.7711f,19.5312f, +207.031f,27.9455f,19.5312f, +210.938f,28.3339f,19.5312f, +214.844f,28.3863f,19.5312f, +218.75f,27.4513f,19.5312f, +222.656f,25.0652f,19.5312f, +226.563f,23.2291f,19.5312f, +230.469f,20.8477f,19.5313f, +234.375f,19.424f,19.5313f, +238.281f,17.7051f,19.5313f, +242.188f,16.5977f,19.5313f, +246.094f,14.7851f,19.5313f, +250.0f,12.8344f,19.5313f, +3.90625f,49.2295f,15.625f, +7.8125f,50.0754f,15.625f, +11.7188f,51.5873f,15.625f, +15.625f,52.0525f,15.625f, +19.5313f,51.4269f,15.625f, +23.4375f,51.8405f,15.625f, +27.3438f,52.3327f,15.625f, +31.25f,53.011f,15.625f, +35.1563f,52.7359f,15.625f, +39.0625f,53.2852f,15.625f, +42.9688f,53.6617f,15.625f, +46.875f,52.4883f,15.625f, +50.7813f,51.9362f,15.625f, +54.6875f,50.8372f,15.625f, +58.5938f,50.1782f,15.625f, +62.5f,49.0401f,15.625f, +66.4063f,49.1011f,15.625f, +70.3125f,48.7903f,15.625f, +74.2188f,48.6124f,15.625f, +78.125f,48.1259f,15.625f, +82.0313f,47.7267f,15.625f, +85.9375f,46.9214f,15.625f, +89.8438f,45.0939f,15.625f, +93.75f,43.6563f,15.625f, +97.6563f,42.5709f,15.625f, +101.563f,41.9572f,15.625f, +105.469f,40.973f,15.625f, +109.375f,40.7682f,15.625f, +113.281f,39.3641f,15.625f, +117.188f,39.2768f,15.625f, +121.094f,37.5977f,15.625f, +125.0f,36.0608f,15.625f, +128.906f,36.045f,15.625f, +132.813f,35.1379f,15.625f, +136.719f,34.9875f,15.625f, +140.625f,34.0482f,15.625f, +144.531f,33.8104f,15.625f, +148.438f,34.9994f,15.625f, +152.344f,36.2664f,15.625f, +156.25f,37.7694f,15.625f, +160.156f,37.6584f,15.625f, +164.063f,36.9226f,15.625f, +167.969f,34.7519f,15.625f, +171.875f,33.2827f,15.625f, +175.781f,32.8949f,15.625f, +179.688f,32.1339f,15.625f, +183.594f,30.407f,15.625f, +187.5f,28.996f,15.625f, +191.406f,29.3357f,15.625f, +195.313f,29.1098f,15.625f, +199.219f,27.8354f,15.625f, +203.125f,26.4739f,15.625f, +207.031f,26.1829f,15.625f, +210.938f,27.387f,15.625f, +214.844f,27.4944f,15.625f, +218.75f,26.4893f,15.625f, +222.656f,24.7764f,15.625f, +226.563f,22.9689f,15.625f, +230.469f,20.4237f,15.625f, +234.375f,18.8049f,15.625f, +238.281f,17.4547f,15.625f, +242.188f,16.2758f,15.625f, +246.094f,14.2192f,15.625f, +250.0f,11.8103f,15.625f, +3.90625f,51.1233f,11.7187f, +7.8125f,51.8127f,11.7187f, +11.7188f,52.0971f,11.7187f, +15.625f,51.8317f,11.7187f, +19.5313f,52.1213f,11.7187f, +23.4375f,51.7889f,11.7187f, +27.3438f,52.2065f,11.7187f, +31.25f,52.438f,11.7187f, +35.1563f,52.6021f,11.7187f, +39.0625f,53.2864f,11.7187f, +42.9688f,52.8882f,11.7187f, +46.875f,52.6009f,11.7187f, +50.7813f,52.8442f,11.7187f, +54.6875f,52.6512f,11.7187f, +58.5938f,51.6436f,11.7187f, +62.5f,50.4271f,11.7187f, +66.4063f,49.3264f,11.7187f, +70.3125f,48.6522f,11.7187f, +74.2188f,49.5854f,11.7187f, +78.125f,50.3492f,11.7187f, +82.0313f,49.035f,11.7187f, +85.9375f,47.6474f,11.7187f, +89.8438f,46.0472f,11.7187f, +93.75f,44.7337f,11.7187f, +97.6563f,44.3349f,11.7187f, +101.563f,43.475f,11.7187f, +105.469f,42.9461f,11.7187f, +109.375f,41.7731f,11.7187f, +113.281f,40.717f,11.7187f, +117.188f,39.399f,11.7187f, +121.094f,38.1327f,11.7187f, +125.0f,36.3286f,11.7187f, +128.906f,36.2512f,11.7187f, +132.813f,35.1997f,11.7187f, +136.719f,33.9406f,11.7187f, +140.625f,33.3109f,11.7187f, +144.531f,33.8153f,11.7187f, +148.438f,33.6823f,11.7187f, +152.344f,34.7077f,11.7187f, +156.25f,35.4472f,11.7187f, +160.156f,35.6332f,11.7187f, +164.063f,34.3651f,11.7187f, +167.969f,32.9876f,11.7187f, +171.875f,32.2858f,11.7187f, +175.781f,32.1374f,11.7187f, +179.688f,30.9575f,11.7187f, +183.594f,29.1111f,11.7187f, +187.5f,28.149f,11.7187f, +191.406f,27.4443f,11.7187f, +195.313f,27.3781f,11.7187f, +199.219f,26.4413f,11.7187f, +203.125f,24.9734f,11.7187f, +207.031f,25.0959f,11.7187f, +210.938f,26.2472f,11.7187f, +214.844f,26.1569f,11.7187f, +218.75f,24.8556f,11.7187f, +222.656f,22.8797f,11.7187f, +226.563f,21.8102f,11.7187f, +230.469f,19.294f,11.7187f, +234.375f,17.5291f,11.7187f, +238.281f,16.242f,11.7187f, +242.188f,15.2738f,11.7187f, +246.094f,13.8715f,11.7187f, +250.0f,12.3043f,11.7187f, +3.90625f,52.2527f,7.8125f, +7.8125f,52.7759f,7.8125f, +11.7188f,52.1635f,7.8125f, +15.625f,52.2016f,7.8125f, +19.5313f,51.9832f,7.8125f, +23.4375f,51.4669f,7.8125f, +27.3438f,51.0033f,7.8125f, +31.25f,50.7124f,7.8125f, +35.1563f,51.6427f,7.8125f, +39.0625f,52.5008f,7.8125f, +42.9688f,53.2834f,7.8125f, +46.875f,52.5339f,7.8125f, +50.7813f,52.627f,7.8125f, +54.6875f,52.9017f,7.8125f, +58.5938f,52.8616f,7.8125f, +62.5f,51.7566f,7.8125f, +66.4063f,51.3268f,7.8125f, +70.3125f,50.6108f,7.8125f, +74.2188f,50.9277f,7.8125f, +78.125f,51.701f,7.8125f, +82.0313f,50.5549f,7.8125f, +85.9375f,48.4345f,7.8125f, +89.8438f,47.3592f,7.8125f, +93.75f,45.7216f,7.8125f, +97.6563f,45.75f,7.8125f, +101.563f,44.4249f,7.8125f, +105.469f,44.7192f,7.8125f, +109.375f,44.4938f,7.8125f, +113.281f,43.252f,7.8125f, +117.188f,41.3735f,7.8125f, +121.094f,39.8664f,7.8125f, +125.0f,37.025f,7.8125f, +128.906f,36.5094f,7.8125f, +132.813f,35.3554f,7.8125f, +136.719f,33.9389f,7.8125f, +140.625f,32.7715f,7.8125f, +144.531f,32.8295f,7.8125f, +148.438f,32.4513f,7.8125f, +152.344f,33.4598f,7.8125f, +156.25f,34.3434f,7.8125f, +160.156f,34.8633f,7.8125f, +164.063f,33.7043f,7.8125f, +167.969f,32.5629f,7.8125f, +171.875f,31.5117f,7.8125f, +175.781f,30.9816f,7.8125f, +179.688f,30.2039f,7.8125f, +183.594f,28.5054f,7.8125f, +187.5f,26.8519f,7.8125f, +191.406f,25.6078f,7.8125f, +195.313f,26.0906f,7.8125f, +199.219f,25.313f,7.8125f, +203.125f,24.0014f,7.8125f, +207.031f,24.066f,7.8125f, +210.938f,24.4935f,7.8125f, +214.844f,24.3803f,7.8125f, +218.75f,23.0075f,7.8125f, +222.656f,21.1023f,7.8125f, +226.563f,19.0418f,7.8125f, +230.469f,17.9588f,7.8125f, +234.375f,16.5211f,7.8125f, +238.281f,15.4949f,7.8125f, +242.188f,14.0938f,7.8125f, +246.094f,13.3141f,7.8125f, +250.0f,12.9595f,7.8125f, +3.90625f,52.6186f,3.90625f, +7.8125f,51.8648f,3.90625f, +11.7188f,51.1949f,3.90625f, +15.625f,50.2102f,3.90625f, +19.5313f,50.6058f,3.90625f, +23.4375f,50.7008f,3.90625f, +27.3438f,51.2163f,3.90625f, +31.25f,51.4263f,3.90625f, +35.1563f,52.1968f,3.90625f, +39.0625f,53.9783f,3.90625f, +42.9688f,53.8927f,3.90625f, +46.875f,53.3266f,3.90625f, +50.7813f,53.5901f,3.90625f, +54.6875f,55.5679f,3.90625f, +58.5938f,55.1819f,3.90625f, +62.5f,53.6891f,3.90625f, +66.4063f,53.0541f,3.90625f, +70.3125f,51.6665f,3.90625f, +74.2188f,51.4469f,3.90625f, +78.125f,51.9591f,3.90625f, +82.0313f,51.0418f,3.90625f, +85.9375f,49.7513f,3.90625f, +89.8438f,48.7329f,3.90625f, +93.75f,46.8713f,3.90625f, +97.6563f,46.3905f,3.90625f, +101.563f,45.4241f,3.90625f, +105.469f,45.6811f,3.90625f, +109.375f,45.3238f,3.90625f, +113.281f,43.6112f,3.90625f, +117.188f,42.1291f,3.90625f, +121.094f,40.4747f,3.90625f, +125.0f,39.3351f,3.90625f, +128.906f,38.0742f,3.90625f, +132.813f,36.7758f,3.90625f, +136.719f,34.9213f,3.90625f, +140.625f,32.3643f,3.90625f, +144.531f,31.7157f,3.90625f, +148.438f,30.6005f,3.90625f, +152.344f,31.6034f,3.90625f, +156.25f,32.6503f,3.90625f, +160.156f,33.3131f,3.90625f, +164.063f,32.5745f,3.90625f, +167.969f,31.5017f,3.90625f, +171.875f,30.6842f,3.90625f, +175.781f,29.8734f,3.90625f, +179.688f,28.6537f,3.90625f, +183.594f,27.2073f,3.90625f, +187.5f,25.4367f,3.90625f, +191.406f,24.1609f,3.90625f, +195.313f,23.9724f,3.90625f, +199.219f,23.7702f,3.90625f, +203.125f,22.4031f,3.90625f, +207.031f,22.1587f,3.90625f, +210.938f,21.6154f,3.90625f, +214.844f,21.8202f,3.90625f, +218.75f,21.017f,3.90625f, +222.656f,19.3736f,3.90625f, +226.563f,18.2127f,3.90625f, +230.469f,17.2263f,3.90625f, +234.375f,16.2938f,3.90625f, +238.281f,14.4518f,3.90625f, +242.188f,13.6398f,3.90625f, +246.094f,13.2404f,3.90625f, +250.0f,12.7102f,3.90625f, +}; + +btScalar Landscape04Nml[] = { +-0.350125f,0.914758f,-0.201568f, +-0.310159f,0.930741f,-0.193707f, +-0.297809f,0.93918f,-0.171025f, +-0.203808f,0.975413f,-0.083855f, +-0.227869f,0.971729f,-0.0617958f, +-0.175976f,0.984209f,0.0190985f, +-0.113434f,0.992992f,-0.0331636f, +-0.10748f,0.994138f,-0.0117748f, +0.264437f,0.964372f,0.00769155f, +0.281666f,0.958691f,0.0397075f, +0.430486f,0.901936f,-0.0345351f, +0.401178f,0.915992f,-0.00383073f, +0.323069f,0.944057f,-0.0662002f, +0.321744f,0.945983f,-0.039967f, +0.269775f,0.962292f,-0.0348534f, +0.20193f,0.970428f,-0.132266f, +0.268889f,0.954681f,-0.127604f, +0.194635f,0.954618f,-0.225435f, +0.221506f,0.956393f,-0.190387f, +0.193103f,0.932235f,-0.306022f, +0.127904f,0.985279f,-0.113427f, +0.190082f,0.941797f,-0.277285f, +-0.00897869f,0.999816f,0.0169309f, +0.104995f,0.98929f,-0.101393f, +-0.0904331f,0.992726f,0.0794834f, +0.0230108f,0.991613f,0.127174f, +0.0155488f,0.993572f,0.11213f, +0.0288983f,0.981821f,0.187597f, +0.0247864f,0.996149f,0.0840949f, +-0.0831472f,0.996537f,0.000391199f, +-0.0501709f,0.99867f,0.0118531f, +-0.153f,0.976743f,-0.15021f, +-0.106591f,0.988499f,-0.107277f, +-0.178503f,0.946807f,-0.267757f, +-0.0254657f,0.984638f,-0.172739f, +-0.00387521f,0.963955f,-0.266035f, +-0.0158619f,0.994497f,-0.103554f, +0.0516719f,0.979433f,-0.195043f, +-0.113536f,0.993496f,-0.00869834f, +-0.0532458f,0.993386f,-0.101726f, +-0.240923f,0.970479f,0.0112676f, +-0.272825f,0.959264f,-0.0733371f, +-0.364171f,0.921854f,-0.132533f, +-0.38043f,0.901643f,-0.205699f, +-0.208475f,0.967633f,-0.142215f, +-0.200209f,0.964847f,-0.170257f, +-0.436593f,0.880066f,-0.186734f, +-0.420663f,0.90307f,-0.0866427f, +-0.564169f,0.813693f,-0.140058f, +-0.556718f,0.83037f,-0.0234562f, +-0.419122f,0.896066f,-0.146295f, +-0.466908f,0.873897f,-0.135282f, +-0.39151f,0.89596f,-0.209704f, +-0.388383f,0.911455f,-0.135677f, +-0.356022f,0.918213f,-0.173589f, +-0.334437f,0.939184f,-0.0780065f, +-0.257665f,0.953587f,-0.155824f, +-0.309301f,0.93272f,-0.185382f, +-0.315034f,0.931862f,-0.179961f, +-0.295926f,0.931298f,-0.212393f, +-0.436779f,0.896592f,-0.0731173f, +-0.317368f,0.948237f,0.0111289f, +-0.503169f,0.863334f,0.0383931f, +-0.468116f,0.877337f,0.105583f, +-0.41232f,0.911034f,0.00307775f, +-0.465256f,0.885053f,0.0147642f, +-0.139311f,0.987488f,-0.0738976f, +-0.20689f,0.974976f,-0.0813499f, +-0.0453849f,0.98457f,-0.169006f, +-0.109269f,0.973649f,-0.20017f, +0.0405907f,0.980595f,-0.191794f, +0.0742781f,0.990348f,-0.117022f, +-0.00934593f,0.982385f,-0.186633f, +0.00811898f,0.984163f,-0.177079f, +-0.0726933f,0.996391f,-0.043832f, +0.0160265f,0.999861f,-0.00453309f, +-0.163053f,0.986585f,0.00801872f, +-0.185529f,0.978031f,-0.0950467f, +-0.137829f,0.987875f,0.0714611f, +-0.0578854f,0.998186f,0.0165557f, +0.148249f,0.976119f,0.158788f, +0.193139f,0.975453f,0.10578f, +0.369772f,0.912299f,0.176006f, +0.348645f,0.936628f,0.0342667f, +0.282769f,0.952501f,0.113063f, +0.239504f,0.96906f,-0.059674f, +0.137712f,0.990197f,0.0233582f, +0.149987f,0.988306f,0.0274647f, +0.169834f,0.984573f,-0.0420991f, +0.0927723f,0.990592f,-0.100603f, +0.171676f,0.97845f,-0.114732f, +0.0567364f,0.963622f,-0.261179f, +0.117062f,0.969073f,-0.217242f, +0.0434058f,0.931949f,-0.359981f, +0.148347f,0.946865f,-0.285375f, +0.103327f,0.903437f,-0.416082f, +0.28421f,0.914779f,-0.287061f, +0.391793f,0.893555f,-0.21922f, +0.419866f,0.888994f,-0.182764f, +0.461528f,0.873246f,-0.156313f, +0.483081f,0.869853f,-0.099941f, +0.503438f,0.857022f,-0.109831f, +0.46584f,0.882166f,-0.0691099f, +0.489623f,0.868073f,-0.0819641f, +0.410796f,0.910896f,-0.0389227f, +0.393119f,0.918063f,-0.0511611f, +0.359627f,0.921042f,-0.1495f, +0.306646f,0.942147f,-0.135377f, +0.381773f,0.903228f,-0.196033f, +0.360002f,0.920948f,-0.149176f, +0.203221f,0.945872f,-0.253037f, +0.218471f,0.943498f,-0.249162f, +0.0567054f,0.995659f,-0.0738017f, +0.229305f,0.968679f,0.0952866f, +-0.0263963f,0.99794f,0.0584726f, +-0.0422212f,0.996107f,0.0773806f, +0.0415928f,0.997459f,0.0578396f, +0.0625406f,0.995706f,0.0682456f, +0.174866f,0.970931f,0.163448f, +0.248971f,0.959664f,0.13061f, +0.296526f,0.91909f,0.259511f, +0.244457f,0.962524f,0.117427f, +0.144028f,0.988219f,0.0517682f, +0.0516566f,0.998622f,-0.00921711f, +-0.0100473f,0.999479f,-0.0306849f, +0.144821f,0.968281f,0.203614f, +0.0927686f,0.985877f,0.139429f, +0.159268f,0.950036f,0.268448f, +-0.238265f,0.969366f,-0.0596594f, +-0.317162f,0.937667f,-0.14209f, +-0.252226f,0.956124f,-0.149026f, +-0.139275f,0.959516f,-0.244809f, +0.225678f,0.948782f,-0.221092f, +0.454598f,0.876109f,-0.160545f, +0.280777f,0.950726f,-0.131467f, +0.235562f,0.968875f,-0.076101f, +0.32523f,0.943278f,-0.0667146f, +0.204883f,0.977104f,-0.0573623f, +-0.016814f,0.999658f,-0.0200258f, +-0.0821474f,0.994185f,0.0696248f, +-0.0248008f,0.998098f,0.0564331f, +0.000698274f,0.999817f,0.0191283f, +0.0007523f,0.989994f,0.141106f, +-0.0137951f,0.98192f,0.188792f, +-0.00956379f,0.990301f,0.138609f, +-0.0156365f,0.996604f,0.0808513f, +-0.104293f,0.986463f,0.126542f, +-0.156424f,0.969975f,0.186228f, +-0.167617f,0.975111f,0.145129f, +-0.261339f,0.965118f,0.0157997f, +-0.160877f,0.9832f,-0.0862302f, +-0.296054f,0.934306f,-0.198555f, +-0.550185f,0.752769f,-0.361436f, +-0.408582f,0.840233f,-0.356467f, +-0.339245f,0.876729f,-0.340968f, +-0.402741f,0.85772f,-0.319556f, +-0.316164f,0.924069f,-0.214795f, +-0.348907f,0.927941f,-0.131109f, +-0.48502f,0.870548f,-0.0830789f, +-0.53006f,0.843646f,-0.085433f, +-0.352226f,0.931519f,-0.0906107f, +-0.0975811f,0.982258f,-0.160146f, +0.0477418f,0.981235f,-0.186812f, +0.0219054f,0.966987f,-0.253882f, +-0.115057f,0.988784f,-0.0952266f, +-0.238673f,0.960258f,0.144707f, +-0.213447f,0.931011f,0.296071f, +-0.201955f,0.923284f,0.326742f, +0.101325f,0.921693f,0.374453f, +0.294403f,0.882174f,0.367555f, +0.373397f,0.835094f,0.403971f, +0.278351f,0.921647f,0.270347f, +0.215461f,0.962466f,0.16503f, +0.225302f,0.965479f,0.13073f, +0.175997f,0.983214f,0.0481225f, +0.220124f,0.97536f,0.0147531f, +0.32343f,0.94566f,-0.0334783f, +0.369971f,0.927728f,-0.0494253f, +0.427777f,0.903113f,-0.037328f, +0.446874f,0.894597f,9.72625e-005f, +0.445338f,0.895316f,-0.00910111f, +0.463955f,0.88101f,-0.0925573f, +0.398143f,0.905258f,-0.148289f, +0.190091f,0.969836f,-0.152589f, +-0.0830374f,0.980972f,-0.175495f, +-0.1343f,0.985908f,-0.0997463f, +-0.00843053f,0.999434f,0.0325608f, +0.021819f,0.995847f,0.0883913f, +0.206682f,0.96009f,0.188439f, +0.388829f,0.882727f,0.263827f, +0.0707915f,0.996578f,0.0426701f, +-0.161491f,0.983232f,-0.0847068f, +-0.0785342f,0.996721f,-0.0194704f, +-0.224473f,0.966422f,-0.125062f, +-0.159666f,0.968511f,-0.191032f, +0.0318558f,0.951557f,-0.305817f, +0.187349f,0.896729f,-0.400972f, +0.324927f,0.900628f,-0.288602f, +0.217775f,0.961772f,-0.16604f, +0.20019f,0.973241f,-0.112807f, +0.277242f,0.959937f,-0.0407145f, +0.14204f,0.987332f,0.0707153f, +-0.0153938f,0.984428f,0.175114f, +-0.0735255f,0.984081f,0.161796f, +-0.0237909f,0.990594f,0.134749f, +-0.0614906f,0.985818f,0.156146f, +-0.143236f,0.970943f,0.191711f, +-0.0137498f,0.973243f,0.229369f, +0.0567477f,0.984597f,0.165372f, +-0.0347212f,0.993259f,0.110594f, +-0.143386f,0.976741f,0.159429f, +-0.139502f,0.982211f,0.125705f, +-0.0993842f,0.989216f,0.107588f, +-0.136731f,0.987843f,0.0739654f, +-0.0893069f,0.995969f,0.00840628f, +-0.123862f,0.992294f,-0.00315825f, +-0.391175f,0.886683f,-0.246529f, +-0.44403f,0.793263f,-0.41662f, +-0.399761f,0.83626f,-0.375315f, +-0.422675f,0.841058f,-0.33759f, +-0.445112f,0.835127f,-0.323168f, +-0.410733f,0.898417f,-0.155389f, +-0.485628f,0.867891f,-0.104549f, +-0.491383f,0.859111f,-0.143077f, +-0.358033f,0.910383f,-0.207399f, +-0.0910122f,0.986127f,-0.138818f, +0.0820594f,0.995842f,-0.039567f, +-0.0287013f,0.999312f,-0.0234726f, +-0.346268f,0.933835f,0.0897299f, +-0.471073f,0.825151f,0.311795f, +-0.27505f,0.819541f,0.502693f, +-0.154238f,0.84574f,0.510818f, +0.0836929f,0.869512f,0.48677f, +0.266688f,0.84547f,0.462663f, +0.365749f,0.809921f,0.458537f, +0.371864f,0.832105f,0.411483f, +0.260242f,0.895369f,0.361371f, +0.283389f,0.903576f,0.321311f, +0.269874f,0.934168f,0.233448f, +0.265321f,0.957928f,0.10945f, +0.333071f,0.942841f,0.0106961f, +0.387903f,0.9217f,0.000193271f, +0.435792f,0.899834f,0.0195967f, +0.454676f,0.88982f,0.0386129f, +0.482276f,0.876019f,-0.000723308f, +0.505259f,0.860654f,-0.0631586f, +0.398328f,0.910448f,-0.111444f, +0.21929f,0.970647f,-0.0987756f, +0.0111053f,0.988208f,-0.152714f, +-0.210805f,0.943357f,-0.256201f, +-0.146846f,0.978658f,-0.143755f, +0.0139602f,0.999731f,-0.0184963f, +0.133096f,0.990721f,-0.0275154f, +0.2933f,0.953875f,0.0640122f, +0.228393f,0.945969f,0.230173f, +0.0546169f,0.969859f,0.237467f, +-0.0762534f,0.988779f,-0.128459f, +-0.106647f,0.982213f,-0.154543f, +-0.122396f,0.949634f,-0.28847f, +0.0920652f,0.954226f,-0.284566f, +0.185259f,0.946785f,-0.263206f, +0.232314f,0.960849f,-0.150996f, +0.169992f,0.979263f,-0.110207f, +0.125326f,0.980516f,-0.151267f, +0.149673f,0.98818f,-0.0331477f, +0.0238199f,0.989878f,0.139909f, +-0.107594f,0.981438f,0.158754f, +-0.0846643f,0.982313f,0.167013f, +-0.0375415f,0.970751f,0.237134f, +-0.0510768f,0.964816f,0.257917f, +-0.0443365f,0.980593f,0.190977f, +0.00242513f,0.997744f,0.0670872f, +0.124335f,0.983389f,0.132238f, +-0.00301992f,0.993206f,0.116332f, +-0.125192f,0.990103f,0.0634287f, +-0.100487f,0.994519f,-0.0288746f, +-0.101663f,0.992712f,-0.0647098f, +-0.139647f,0.987963f,-0.0665471f, +-0.130136f,0.990189f,-0.0508981f, +-0.0756901f,0.997123f,-0.00415316f, +-0.171558f,0.977059f,-0.126185f, +-0.351855f,0.892529f,-0.282117f, +-0.447333f,0.817645f,-0.362422f, +-0.423851f,0.857249f,-0.29236f, +-0.448058f,0.866215f,-0.221171f, +-0.531086f,0.820738f,-0.210565f, +-0.511898f,0.851158f,-0.116153f, +-0.425868f,0.900461f,-0.0883553f, +-0.399025f,0.900598f,-0.172345f, +-0.24223f,0.968919f,-0.0502012f, +-0.0663613f,0.996507f,0.0506899f, +-0.138021f,0.972657f,0.186782f, +-0.4139f,0.851097f,0.322987f, +-0.550512f,0.782849f,0.289973f, +-0.380287f,0.863038f,0.332486f, +-0.131533f,0.903571f,0.407748f, +0.119586f,0.9109f,0.394918f, +0.299052f,0.87558f,0.379379f, +0.370047f,0.8611f,0.348671f, +0.442832f,0.822723f,0.356408f, +0.35885f,0.890772f,0.278839f, +0.314791f,0.940053f,0.131179f, +0.339464f,0.925728f,0.166711f, +0.403599f,0.900778f,0.160334f, +0.45653f,0.889636f,-0.0113152f, +0.365242f,0.916509f,-0.163124f, +0.379822f,0.91652f,-0.125407f, +0.442125f,0.891797f,-0.096041f, +0.493888f,0.864551f,-0.0928755f, +0.541781f,0.83947f,-0.041994f, +0.441424f,0.894377f,-0.0723577f, +0.226514f,0.958331f,-0.174048f, +0.0664964f,0.969681f,-0.235153f, +-0.103823f,0.949537f,-0.295973f, +-0.233692f,0.889012f,-0.39376f, +-0.0987171f,0.939339f,-0.328477f, +0.103986f,0.972613f,-0.207871f, +0.198802f,0.974287f,-0.106033f, +0.0601774f,0.998175f,0.00500958f, +-0.0421158f,0.995212f,0.0882012f, +-0.0598721f,0.997785f,-0.0289851f, +-0.030607f,0.999125f,-0.0285146f, +-0.00697633f,0.993471f,-0.113875f, +0.0388611f,0.980882f,-0.190686f, +0.0977483f,0.98843f,-0.115983f, +0.15403f,0.986798f,-0.0500538f, +0.193054f,0.979913f,-0.0500083f, +0.157678f,0.98694f,-0.0329733f, +-0.0158549f,0.999428f,0.0298765f, +-0.0525571f,0.987534f,0.14837f, +0.000720533f,0.997813f,0.0660913f, +-0.102677f,0.99254f,-0.0657426f, +-0.099341f,0.994285f,-0.0391091f, +-0.0676495f,0.996952f,-0.0388727f, +0.0225146f,0.999293f,0.0301014f, +0.0577235f,0.997453f,0.0418936f, +-0.0269869f,0.999243f,0.0280361f, +0.00446401f,0.985157f,0.171599f, +-0.0141502f,0.990326f,0.138035f, +-0.00518586f,0.999975f,0.00477817f, +-0.0328139f,0.995381f,-0.09022f, +-0.128063f,0.971338f,-0.200254f, +-0.151852f,0.967914f,-0.200209f, +-0.0720493f,0.989055f,-0.128759f, +-0.0591129f,0.991504f,-0.115868f, +-0.248059f,0.943661f,-0.219024f, +-0.389946f,0.877483f,-0.279225f, +-0.523332f,0.810744f,-0.262332f, +-0.51839f,0.842544f,-0.146256f, +-0.550368f,0.815716f,-0.178051f, +-0.560732f,0.813038f,-0.156683f, +-0.427123f,0.899415f,-0.0928351f, +-0.366593f,0.924495f,-0.104494f, +-0.322547f,0.93696f,-0.134426f, +-0.128035f,0.99042f,-0.0517317f, +-0.291376f,0.953688f,0.0746902f, +-0.520094f,0.826135f,0.216802f, +-0.516864f,0.826474f,0.22314f, +-0.396988f,0.892552f,0.213897f, +-0.184148f,0.954818f,0.233263f, +0.0957205f,0.95579f,0.278034f, +0.314018f,0.892294f,0.32435f, +0.401668f,0.873128f,0.276243f, +0.463054f,0.857596f,0.223851f, +0.480022f,0.855973f,0.192066f, +0.375927f,0.916106f,0.13939f, +0.288789f,0.941864f,0.171735f, +0.396643f,0.909563f,0.123974f, +0.561623f,0.825897f,0.0497286f, +0.465605f,0.881752f,-0.0756653f, +0.370044f,0.915005f,-0.160728f, +0.427822f,0.898624f,-0.0971747f, +0.465206f,0.885137f,-0.0107503f, +0.468824f,0.88183f,0.0507874f, +0.478143f,0.868746f,0.12907f, +0.351411f,0.934208f,0.0613665f, +0.140442f,0.98844f,-0.0571117f, +-0.0122878f,0.991421f,-0.130131f, +-0.117862f,0.972142f,-0.202603f, +-0.15815f,0.947613f,-0.27752f, +-0.0729629f,0.95654f,-0.282325f, +0.0272484f,0.989771f,-0.14004f, +-0.0137333f,0.999563f,0.0261849f, +-0.0985129f,0.993299f,0.0604412f, +-0.135233f,0.990548f,-0.0229695f, +-0.0373153f,0.999264f,0.00888433f, +0.0352261f,0.99933f,0.00994916f, +0.061219f,0.99588f,0.0668911f, +0.0815695f,0.99444f,0.0665983f, +0.144386f,0.989424f,0.0139045f, +0.184662f,0.980318f,0.0698361f, +0.0224217f,0.989677f,0.14155f, +-0.0794321f,0.954058f,0.288901f, +-0.0304562f,0.959461f,0.280192f, +0.112423f,0.968918f,0.220359f, +0.0390938f,0.993037f,0.111126f, +-0.0885962f,0.9933f,-0.0741985f, +-0.0453085f,0.996418f,-0.0714089f, +-0.123875f,0.985221f,-0.118298f, +0.00670832f,0.999925f,0.010273f, +-0.0146906f,0.998569f,0.0514303f, +-0.0998092f,0.992773f,0.0666264f, +0.0466126f,0.990197f,0.131669f, +0.103009f,0.992862f,0.0601126f, +0.113553f,0.993084f,-0.0298385f, +-0.0128779f,0.975704f,-0.218713f, +-0.177855f,0.94662f,-0.268846f, +-0.191482f,0.955424f,-0.224722f, +-0.0532043f,0.987628f,-0.147512f, +-0.140744f,0.970833f,-0.194099f, +-0.387395f,0.889373f,-0.242778f, +-0.531553f,0.818908f,-0.216427f, +-0.531571f,0.799354f,-0.280115f, +-0.51407f,0.81292f,-0.273666f, +-0.549112f,0.793924f,-0.261078f, +-0.484709f,0.822384f,-0.297895f, +-0.322663f,0.926066f,-0.195678f, +-0.315438f,0.927311f,-0.201479f, +-0.289702f,0.947148f,-0.13778f, +-0.417457f,0.908684f,-0.00477603f, +-0.584599f,0.810188f,0.0428868f, +-0.55194f,0.828316f,0.0962071f, +-0.397599f,0.904432f,0.154656f, +-0.183216f,0.971572f,0.149931f, +0.0355131f,0.990243f,0.134751f, +0.298837f,0.942288f,0.150964f, +0.413659f,0.900634f,0.133206f, +0.498073f,0.828388f,0.256313f, +0.444018f,0.853405f,0.273035f, +0.327561f,0.881897f,0.339061f, +0.313826f,0.898686f,0.306392f, +0.495157f,0.851292f,0.173556f, +0.614747f,0.78345f,0.0910662f, +0.55187f,0.833866f,0.0103585f, +0.367713f,0.926545f,-0.0793776f, +0.311567f,0.950223f,0.00108255f, +0.382947f,0.917094f,0.110859f, +0.410945f,0.895808f,0.169272f, +0.455231f,0.858878f,0.234721f, +0.373673f,0.896264f,0.238911f, +0.246571f,0.935158f,0.254328f, +0.0808975f,0.990111f,0.114608f, +-0.0843211f,0.99633f,-0.0147289f, +-0.0859474f,0.994869f,-0.0533687f, +-0.0567528f,0.986639f,-0.152718f, +-0.104487f,0.984189f,-0.143019f, +-0.139027f,0.990289f,8.5057e-005f, +-0.137547f,0.987918f,0.0714029f, +-0.144256f,0.989201f,-0.0259182f, +-0.026694f,0.998838f,-0.0401331f, +-0.0313342f,0.99664f,-0.0756769f, +-0.0574884f,0.99781f,0.0327011f, +0.145005f,0.983413f,0.108961f, +0.119257f,0.992151f,0.0376122f, +0.0587452f,0.978725f,0.196585f, +-0.0803833f,0.947865f,0.308369f, +-0.127827f,0.919581f,0.371526f, +-0.00616421f,0.930831f,0.365399f, +0.107639f,0.912609f,0.394409f, +0.210572f,0.88729f,0.410336f, +0.0740329f,0.980065f,0.184368f, +-0.0250926f,0.999613f,0.0120275f, +-0.0610433f,0.996433f,-0.05826f, +-0.0708404f,0.994984f,-0.0706271f, +-0.0640037f,0.997923f,-0.00726403f, +-0.0949547f,0.99548f,0.00148231f, +0.00929451f,0.997943f,-0.0634315f, +0.147986f,0.988795f,-0.0195964f, +0.19874f,0.98001f,-0.00909425f, +0.119683f,0.99247f,-0.0260466f, +-0.140841f,0.984951f,-0.10018f, +-0.197496f,0.959342f,-0.201637f, +-0.0821482f,0.973605f,-0.212945f, +-0.090387f,0.978841f,-0.18358f, +-0.34459f,0.903344f,-0.255395f, +-0.465169f,0.833236f,-0.29889f, +-0.493353f,0.789348f,-0.365421f, +-0.529455f,0.773394f,-0.348624f, +-0.541108f,0.776645f,-0.322528f, +-0.503238f,0.814279f,-0.289312f, +-0.451111f,0.869282f,-0.202106f, +-0.405307f,0.906179f,-0.120689f, +-0.367499f,0.92846f,-0.0539062f, +-0.448648f,0.893437f,-0.0220131f, +-0.582415f,0.811815f,-0.0418214f, +-0.587857f,0.805915f,-0.0701802f, +-0.440963f,0.897524f,0.00144435f, +-0.150082f,0.985674f,0.0769547f, +0.0512849f,0.998035f,0.0359923f, +0.331471f,0.9412f,0.0653422f, +0.327057f,0.943418f,0.0547333f, +0.325027f,0.917755f,0.228216f, +0.374201f,0.856118f,0.35642f, +0.374565f,0.858588f,0.350039f, +0.460817f,0.854058f,0.241312f, +0.556465f,0.823608f,0.109619f, +0.63153f,0.770458f,0.0869767f, +0.587056f,0.806123f,0.074369f, +0.365958f,0.924908f,0.10305f, +0.26636f,0.954918f,0.131089f, +0.330741f,0.937061f,0.111923f, +0.358992f,0.918233f,0.167249f, +0.397317f,0.888574f,0.229294f, +0.378918f,0.890078f,0.253343f, +0.252398f,0.944302f,0.211161f, +0.242388f,0.947895f,0.206744f, +0.0865865f,0.99456f,0.0579091f, +-0.0181168f,0.990006f,-0.139854f, +0.0162661f,0.98021f,-0.197289f, +-0.148111f,0.960303f,-0.236394f, +-0.255052f,0.949006f,-0.185302f, +-0.211751f,0.971559f,-0.105997f, +-0.0120621f,0.994912f,-0.100021f, +-0.015173f,0.98959f,-0.143115f, +-0.0401151f,0.99847f,-0.0380528f, +-0.0979763f,0.995187f,0.00194195f, +0.0571375f,0.998251f,0.0151643f, +0.0776787f,0.976915f,0.199006f, +-0.101892f,0.95655f,0.273185f, +-0.133768f,0.938598f,0.318024f, +-0.177801f,0.93623f,0.303084f, +-0.022321f,0.922329f,0.385761f, +0.0333931f,0.905943f,0.422081f, +0.163361f,0.862964f,0.478127f, +0.305267f,0.821497f,0.481617f, +0.18106f,0.939243f,0.291615f, +-0.00700511f,0.992472f,0.122275f, +-0.0966012f,0.992994f,0.068052f, +-0.106034f,0.991731f,0.0722919f, +-0.0353039f,0.993084f,0.11197f, +0.0541772f,0.995603f,0.0764134f, +0.08347f,0.989853f,0.114994f, +0.130868f,0.975887f,0.174696f, +0.0723356f,0.969665f,0.23349f, +-0.0470347f,0.960948f,0.272703f, +-0.10077f,0.971805f,0.213169f, +-0.119566f,0.974584f,0.189448f, +-0.0774738f,0.965859f,0.247214f, +-0.198029f,0.968836f,0.1488f, +-0.435505f,0.897132f,-0.0740912f, +-0.502708f,0.857298f,-0.111019f, +-0.564282f,0.819749f,-0.0979722f, +-0.594236f,0.795147f,-0.120937f, +-0.591492f,0.803058f,-0.0723546f, +-0.526826f,0.849968f,-0.0029614f, +-0.410127f,0.912007f,0.00617969f, +-0.355675f,0.932755f,-0.0588432f, +-0.457125f,0.883759f,-0.100032f, +-0.544765f,0.834451f,-0.0832032f, +-0.554858f,0.819866f,-0.141253f, +-0.535218f,0.826621f,-0.173894f, +-0.203549f,0.978635f,-0.0289948f, +0.0668755f,0.997729f,0.00799418f, +0.247034f,0.968844f,0.017759f, +0.275407f,0.949712f,0.148988f, +0.19759f,0.950103f,0.241375f, +0.374575f,0.880138f,0.291635f, +0.446827f,0.865948f,0.224675f, +0.519968f,0.833624f,0.186291f, +0.587008f,0.786117f,0.193499f, +0.636373f,0.75334f,0.165857f, +0.540728f,0.822377f,0.176944f, +0.345338f,0.910903f,0.225828f, +0.278322f,0.945193f,0.170723f, +0.30876f,0.936535f,0.166043f, +0.303863f,0.916063f,0.261719f, +0.319419f,0.895614f,0.309591f, +0.43277f,0.828092f,0.356332f, +0.333077f,0.917687f,0.216587f, +0.219655f,0.964319f,0.147787f, +0.242228f,0.95005f,0.196802f, +0.204875f,0.978767f,-0.00640881f, +-0.000192716f,0.97566f,-0.219288f, +-0.0681124f,0.988809f,-0.132732f, +-0.241144f,0.919453f,-0.310573f, +-0.290276f,0.882193f,-0.370776f, +0.0292627f,0.97223f,-0.232189f, +-0.0803803f,0.976804f,-0.198478f, +-0.203999f,0.977793f,-0.0480039f, +-0.118856f,0.989202f,0.0857425f, +-0.0783112f,0.985397f,0.151198f, +-0.0878718f,0.938803f,0.333059f, +-0.083435f,0.948159f,0.30665f, +-0.110585f,0.962509f,0.247682f, +-0.186686f,0.943514f,0.273733f, +-0.149516f,0.932553f,0.32862f, +-0.00475332f,0.899494f,0.436906f, +0.0862131f,0.885009f,0.457522f, +0.277459f,0.815555f,0.507825f, +0.298118f,0.799955f,0.520766f, +0.14455f,0.869997f,0.471392f, +0.0121492f,0.942115f,0.335071f, +-0.0752209f,0.977077f,0.199154f, +-0.128636f,0.97789f,0.164878f, +-0.000660482f,0.945164f,0.326595f, +0.00550592f,0.919316f,0.393482f, +0.0803772f,0.905979f,0.415621f, +0.0810259f,0.907487f,0.412192f, +-0.090779f,0.919652f,0.382099f, +-0.137864f,0.897436f,0.419048f, +-0.130404f,0.886486f,0.444001f, +-0.0852724f,0.906321f,0.413897f, +-0.0259127f,0.906615f,0.421163f, +-0.225351f,0.915922f,0.332119f, +-0.462548f,0.869686f,0.172323f, +-0.572668f,0.816922f,0.0684804f, +-0.585929f,0.806118f,0.0828267f, +-0.593406f,0.803366f,0.0497268f, +-0.516762f,0.856027f,-0.0132014f, +-0.38427f,0.922646f,-0.0325731f, +-0.287245f,0.956724f,-0.0465863f, +-0.413146f,0.905396f,-0.097823f, +-0.564236f,0.818421f,-0.108744f, +-0.507227f,0.858315f,-0.0775611f, +-0.527754f,0.82927f,-0.183811f, +-0.354765f,0.918321f,-0.175582f, +0.0463007f,0.998926f,-0.00175561f, +0.214268f,0.976774f,0.00151756f, +0.165544f,0.983729f,0.0698077f, +0.096445f,0.982342f,0.16032f, +0.366991f,0.896711f,0.24744f, +0.500788f,0.845195f,0.186699f, +0.507012f,0.85355f,0.119965f, +0.542994f,0.824496f,0.159261f, +0.605757f,0.757486f,0.243463f, +0.532123f,0.786802f,0.312711f, +0.44869f,0.847812f,0.282652f, +0.34333f,0.935092f,0.0879082f, +0.24319f,0.961353f,0.129073f, +0.223708f,0.954136f,0.198946f, +0.276144f,0.94134f,0.193965f, +0.41277f,0.892522f,0.181731f, +0.485836f,0.856185f,0.175815f, +0.251109f,0.963495f,0.0928509f, +0.217377f,0.969921f,0.109544f, +0.402023f,0.911537f,0.0864706f, +0.0930878f,0.988366f,-0.120284f, +-0.0926141f,0.987658f,-0.126311f, +-0.0129498f,0.988134f,-0.153049f, +-0.0752509f,0.973537f,-0.215783f, +-0.167591f,0.970187f,-0.175075f, +-0.227938f,0.971032f,-0.0717025f, +-0.288377f,0.95589f,0.0557925f, +-0.2706f,0.959797f,0.0746015f, +-0.201821f,0.948409f,0.244517f, +-0.135104f,0.944724f,0.298737f, +0.0536332f,0.953012f,0.298147f, +-0.104499f,0.972769f,0.206883f, +-0.26012f,0.936243f,0.236192f, +-0.221301f,0.933098f,0.283468f, +-0.0976008f,0.934678f,0.341835f, +0.0488135f,0.920165f,0.388475f, +0.20566f,0.878417f,0.431379f, +0.294052f,0.82595f,0.480979f, +0.211093f,0.846234f,0.489211f, +0.1526f,0.86506f,0.477897f, +0.100541f,0.907805f,0.407163f, +-0.126416f,0.965258f,0.228683f, +-0.211306f,0.949302f,0.232755f, +-0.037039f,0.912463f,0.40748f, +0.117233f,0.908378f,0.401379f, +0.101997f,0.928038f,0.35825f, +-0.0502775f,0.939056f,0.340069f, +-0.158243f,0.952358f,0.260718f, +-0.125329f,0.958222f,0.257106f, +-0.051336f,0.956723f,0.286436f, +-0.0625203f,0.954305f,0.29222f, +-0.207996f,0.932703f,0.294623f, +-0.319481f,0.91161f,0.258649f, +-0.495077f,0.865137f,0.0802322f, +-0.579132f,0.814857f,-0.0247929f, +-0.549115f,0.83292f,-0.0686783f, +-0.493373f,0.86244f,-0.113053f, +-0.402759f,0.911225f,-0.0863345f, +-0.292096f,0.955556f,-0.0399004f, +-0.382523f,0.923047f,-0.0407488f, +-0.572187f,0.816414f,-0.0779103f, +-0.512485f,0.857517f,-0.0449819f, +-0.420369f,0.906318f,-0.0433336f, +-0.419207f,0.879291f,-0.22608f, +-0.129012f,0.980121f,-0.150729f, +0.168538f,0.98409f,0.056222f, +0.177285f,0.97778f,0.111881f, +0.0313595f,0.998166f,-0.0517722f, +0.266622f,0.963684f,-0.0150476f, +0.566513f,0.817464f,0.103999f, +0.539244f,0.841888f,0.0209898f, +0.503392f,0.861782f,0.0626771f, +0.548011f,0.825978f,0.132075f, +0.53464f,0.817691f,0.213407f, +0.52656f,0.822061f,0.21668f, +0.418461f,0.898681f,0.131391f, +0.217077f,0.97168f,0.0933593f, +0.230073f,0.97316f,0.00512693f, +0.352039f,0.933499f,-0.0681773f, +0.427612f,0.891089f,-0.152014f, +0.47402f,0.877861f,-0.0682997f, +0.292505f,0.956178f,-0.0128375f, +0.212998f,0.971167f,-0.107084f, +0.394409f,0.913171f,-0.102761f, +0.229015f,0.973422f,0.000912976f, +-0.0760893f,0.988509f,-0.130618f, +-0.0515625f,0.984716f,-0.166362f, +-0.0928406f,0.987408f,-0.128086f, +-0.200115f,0.967117f,0.156969f, +-0.29324f,0.941681f,0.165066f, +-0.336305f,0.919935f,0.201539f, +-0.298108f,0.921775f,0.247915f, +-0.262609f,0.920325f,0.289892f, +-0.146209f,0.952657f,0.266586f, +-0.00778438f,0.956339f,0.292158f, +-0.050022f,0.92665f,0.372583f, +-0.258705f,0.916977f,0.303687f, +-0.247478f,0.923305f,0.293706f, +-0.126717f,0.938107f,0.322331f, +0.0303988f,0.946862f,0.320201f, +0.135735f,0.944675f,0.298606f, +0.25669f,0.889672f,0.377616f, +0.215508f,0.868916f,0.44558f, +0.117717f,0.868155f,0.482129f, +0.172493f,0.853951f,0.490931f, +0.0744588f,0.909987f,0.407897f, +-0.203499f,0.942765f,0.264163f, +-0.165852f,0.956441f,0.240237f, +0.150303f,0.946565f,0.285349f, +0.126121f,0.955231f,0.267632f, +0.00383767f,0.957166f,0.289515f, +-0.0803601f,0.965694f,0.246937f, +-0.14415f,0.963474f,0.225698f, +-0.128772f,0.964294f,0.231421f, +-0.0634991f,0.964707f,0.255554f, +-0.15178f,0.96554f,0.211412f, +-0.290877f,0.950446f,0.109737f, +-0.365587f,0.928197f,0.069257f, +-0.512709f,0.855901f,-0.0675528f, +-0.522587f,0.843414f,-0.12472f, +-0.519355f,0.843468f,-0.13723f, +-0.458617f,0.886978f,-0.054221f, +-0.335795f,0.941914f,0.00633015f, +-0.354719f,0.934449f,0.0312872f, +-0.552854f,0.83289f,-0.025441f, +-0.550469f,0.834453f,-0.0259307f, +-0.388185f,0.921529f,-0.00983026f, +-0.282899f,0.957493f,-0.056358f, +-0.256814f,0.955751f,-0.143483f, +-0.0731312f,0.996697f,-0.0353254f, +0.211397f,0.967055f,0.141832f, +0.27554f,0.960583f,0.0368595f, +0.217196f,0.959783f,-0.177882f, +0.479261f,0.875236f,-0.0653524f, +0.513664f,0.856169f,0.0558883f, +0.446145f,0.882397f,0.149434f, +0.498219f,0.84712f,0.184837f, +0.503236f,0.827823f,0.247916f, +0.51285f,0.815024f,0.269666f, +0.506381f,0.824734f,0.251778f, +0.333663f,0.940706f,0.0611746f, +0.353215f,0.932965f,-0.069389f, +0.414309f,0.904024f,-0.105298f, +0.451897f,0.886486f,-0.0996557f, +0.345824f,0.933767f,-0.0921138f, +0.280994f,0.95917f,0.0321915f, +0.317081f,0.945948f,0.0681282f, +0.344866f,0.938141f,0.0309596f, +0.224406f,0.974203f,0.0238892f, +-0.0108486f,0.995761f,-0.0913323f, +-0.00158176f,0.998953f,-0.0457292f, +-0.115676f,0.985559f,-0.123663f, +-0.188171f,0.911466f,0.365816f, +-0.262724f,0.896783f,0.356029f, +-0.358149f,0.883197f,0.302807f, +-0.323424f,0.894918f,0.307438f, +-0.242922f,0.924564f,0.293548f, +-0.121147f,0.94907f,0.290844f, +-0.0341414f,0.951299f,0.306374f, +-0.132493f,0.945016f,0.298983f, +-0.194216f,0.905093f,0.378268f, +-0.212944f,0.914784f,0.343257f, +-0.127802f,0.956235f,0.263215f, +0.0483659f,0.968777f,0.243172f, +0.117573f,0.942608f,0.312517f, +0.164225f,0.89741f,0.409494f, +0.122313f,0.88201f,0.455081f, +0.101965f,0.875392f,0.472537f, +0.209339f,0.879095f,0.428217f, +0.174899f,0.892224f,0.416349f, +-0.060088f,0.941634f,0.331231f, +-0.120508f,0.975773f,0.182606f, +0.112168f,0.972734f,0.202994f, +0.117253f,0.950933f,0.286318f, +-0.0544328f,0.941394f,0.332887f, +-0.0790068f,0.915303f,0.394942f, +-0.127609f,0.917525f,0.376648f, +-0.0756868f,0.941409f,0.328666f, +-0.0332439f,0.958716f,0.282415f, +-0.0735168f,0.965505f,0.249792f, +-0.203882f,0.964791f,0.166163f, +-0.320453f,0.94269f,0.0929826f, +-0.471247f,0.881185f,0.0379224f, +-0.492278f,0.869051f,0.0491152f, +-0.532259f,0.846256f,-0.0234739f, +-0.499446f,0.866138f,-0.0189645f, +-0.373407f,0.92679f,-0.0403466f, +-0.352534f,0.935772f,-0.00715155f, +-0.527726f,0.848793f,-0.0324855f, +-0.520812f,0.852354f,-0.0474108f, +-0.409147f,0.909436f,-0.0743255f, +-0.294722f,0.955583f,0.000817458f, +-0.222255f,0.974321f,0.0360744f, +-0.14278f,0.989739f,0.00545783f, +0.112175f,0.992761f,0.0429195f, +0.349968f,0.931754f,0.0967357f, +0.338116f,0.939385f,0.056869f, +0.379594f,0.923814f,0.0497667f, +0.434257f,0.879279f,0.195674f, +0.391146f,0.89525f,0.213383f, +0.465582f,0.860371f,0.207352f, +0.429826f,0.860017f,0.274991f, +0.465148f,0.815034f,0.34548f, +0.575943f,0.73808f,0.351465f, +0.535537f,0.824709f,0.181813f, +0.414278f,0.908562f,-0.0537569f, +0.380258f,0.913027f,-0.147599f, +0.408447f,0.90132f,-0.144197f, +0.367806f,0.925659f,-0.0887431f, +0.142987f,0.986995f,-0.073455f, +0.215691f,0.972786f,0.0846483f, +0.373384f,0.916381f,0.144331f, +0.381582f,0.918997f,0.0991966f, +0.0727073f,0.993287f,-0.0899678f, +-0.0658262f,0.992454f,-0.103446f, +0.0138596f,0.999564f,-0.0260736f, +-0.215981f,0.852322f,0.47634f, +-0.206677f,0.845053f,0.493123f, +-0.272991f,0.879681f,0.389406f, +-0.267376f,0.924267f,0.272471f, +-0.22026f,0.956955f,0.189003f, +-0.175208f,0.966589f,0.187106f, +-0.043064f,0.959071f,0.279872f, +-0.116589f,0.955061f,0.272519f, +-0.310776f,0.922421f,0.229257f, +-0.169995f,0.929299f,0.32788f, +-0.0175005f,0.941141f,0.337561f, +0.0138751f,0.95035f,0.310874f, +-0.0519487f,0.924056f,0.37871f, +0.0171204f,0.875115f,0.483613f, +0.148666f,0.835016f,0.529761f, +0.187668f,0.864969f,0.465412f, +0.241037f,0.89408f,0.377521f, +0.22255f,0.900707f,0.373093f, +0.0517034f,0.945752f,0.320749f, +-0.0271248f,0.957046f,0.288665f, +0.0325916f,0.970401f,0.239289f, +0.0171507f,0.960836f,0.276588f, +-0.143534f,0.9275f,0.345169f, +-0.0983366f,0.916766f,0.38713f, +-0.0476997f,0.944806f,0.32414f, +-0.0337303f,0.946895f,0.319767f, +-0.0100366f,0.942379f,0.334396f, +-0.0544901f,0.938102f,0.342046f, +-0.14598f,0.916868f,0.371541f, +-0.23743f,0.904478f,0.354324f, +-0.411826f,0.87795f,0.244136f, +-0.481531f,0.866693f,0.130273f, +-0.469337f,0.874903f,0.119446f, +-0.452816f,0.890509f,0.0441746f, +-0.332275f,0.942324f,-0.0402274f, +-0.391441f,0.91825f,-0.0599172f, +-0.492183f,0.870395f,0.0129854f, +-0.540952f,0.839903f,-0.0439814f, +-0.452633f,0.891182f,0.0302916f, +-0.353037f,0.931758f,0.0848037f, +-0.230998f,0.971043f,0.0609518f, +-0.110559f,0.993184f,0.0368984f, +0.0985994f,0.994896f,-0.0214387f, +0.290703f,0.956813f,-0.000841556f, +0.306742f,0.941069f,0.142471f, +0.309512f,0.928678f,0.20435f, +0.393276f,0.890035f,0.23059f, +0.472781f,0.864565f,0.170309f, +0.455511f,0.888755f,0.0512287f, +0.387199f,0.912459f,0.13227f, +0.420125f,0.891345f,0.170293f, +0.568557f,0.791084f,0.225676f, +0.642678f,0.725845f,0.245181f, +0.61301f,0.785525f,0.0846683f, +0.519083f,0.833826f,-0.187849f, +0.390386f,0.832025f,-0.394123f, +0.254733f,0.897839f,-0.359161f, +0.0968538f,0.955535f,-0.278518f, +0.110338f,0.951183f,-0.288231f, +0.337547f,0.917961f,-0.20835f, +0.382401f,0.916771f,-0.115327f, +0.232755f,0.967238f,-0.101374f, +-0.075544f,0.963631f,-0.256338f, +-0.111861f,0.963998f,-0.241238f, +-0.403631f,0.823611f,0.398431f, +-0.211285f,0.853176f,0.476917f, +-0.0996818f,0.887327f,0.450237f, +-0.119017f,0.926423f,0.357178f, +-0.147962f,0.959424f,0.240027f, +-0.17904f,0.969453f,0.167646f, +-0.182698f,0.967757f,0.173402f, +-0.0875162f,0.935774f,0.341566f, +-0.247354f,0.926662f,0.283043f, +-0.269706f,0.932828f,0.238937f, +-0.116046f,0.932011f,0.34335f, +-0.054572f,0.895119f,0.442474f, +-0.0702883f,0.870311f,0.487462f, +-0.0238769f,0.872685f,0.4877f, +0.145141f,0.847062f,0.511292f, +0.26226f,0.839585f,0.475728f, +0.307436f,0.859155f,0.409067f, +0.272452f,0.896089f,0.35042f, +0.0602872f,0.949936f,0.306572f, +-0.0269541f,0.950357f,0.309992f, +0.110161f,0.964193f,0.241239f, +0.0112822f,0.980274f,0.19732f, +-0.201697f,0.957263f,0.207282f, +-0.0780713f,0.964435f,0.252529f, +0.00973745f,0.973101f,0.230172f, +-0.0755968f,0.981149f,0.177855f, +-0.0876613f,0.97114f,0.221817f, +-0.111729f,0.927016f,0.357991f, +-0.221124f,0.882386f,0.41533f, +-0.204491f,0.867297f,0.45385f, +-0.238609f,0.89578f,0.375026f, +-0.38933f,0.904206f,0.175592f, +-0.447525f,0.889442f,0.0928077f, +-0.421271f,0.9063f,0.0339399f, +-0.295839f,0.951557f,0.0837779f, +-0.40469f,0.90695f,0.116906f, +-0.500893f,0.852054f,0.152018f, +-0.539765f,0.838827f,0.0708671f, +-0.497421f,0.864837f,0.068037f, +-0.338953f,0.937284f,0.0813017f, +-0.178116f,0.975677f,0.127782f, +-0.0428295f,0.992057f,0.118272f, +0.176596f,0.983706f,0.0336999f, +0.217356f,0.975284f,-0.0397137f, +0.172156f,0.984981f,0.0131952f, +0.279801f,0.958586f,0.0531518f, +0.429228f,0.901897f,0.0484305f, +0.537427f,0.843269f,0.00840869f, +0.461159f,0.886671f,-0.0338697f, +0.347666f,0.937337f,0.022966f, +0.390524f,0.920568f,0.00669632f, +0.544615f,0.837115f,0.0513162f, +0.64737f,0.75903f,0.0691749f, +0.709483f,0.698136f,0.0961199f, +0.69002f,0.723355f,-0.0250988f, +0.510759f,0.819636f,-0.259464f, +0.161066f,0.87948f,-0.447854f, +0.0742832f,0.901252f,-0.426881f, +0.164688f,0.896506f,-0.411284f, +0.211827f,0.873436f,-0.43845f, +0.238498f,0.898773f,-0.367868f, +0.244991f,0.941894f,-0.229815f, +0.0339169f,0.959887f,-0.278328f, +-0.150927f,0.928909f,-0.338156f, +-0.262269f,0.839002f,0.47675f, +-0.199453f,0.89484f,0.39935f, +-0.0695117f,0.920513f,0.384478f, +-0.0794509f,0.922822f,0.376943f, +-0.0384813f,0.923599f,0.381424f, +-0.0906334f,0.946866f,0.308593f, +-0.231342f,0.940055f,0.250554f, +-0.228342f,0.910605f,0.344468f, +-0.168052f,0.897027f,0.408779f, +-0.249241f,0.920512f,0.300892f, +-0.201125f,0.932701f,0.29936f, +-0.156169f,0.918655f,0.362882f, +-0.101964f,0.881359f,0.461314f, +-0.0479674f,0.88379f,0.465418f, +0.160937f,0.878499f,0.449821f, +0.298148f,0.878819f,0.372539f, +0.363972f,0.843945f,0.394059f, +0.330687f,0.867316f,0.372033f, +0.109951f,0.941418f,0.318814f, +0.0530775f,0.967978f,0.245361f, +0.171035f,0.972595f,0.157499f, +0.0211384f,0.985036f,0.171048f, +-0.223743f,0.958122f,0.178723f, +-0.143003f,0.966115f,0.214875f, +0.0335442f,0.969798f,0.24159f, +0.00108957f,0.977785f,0.209606f, +-0.185748f,0.96522f,0.183978f, +-0.245345f,0.928456f,0.278881f, +-0.278935f,0.920412f,0.273928f, +-0.227379f,0.922009f,0.313367f, +-0.127558f,0.911679f,0.390603f, +-0.252363f,0.916101f,0.311563f, +-0.353299f,0.912723f,0.205222f, +-0.418007f,0.90407f,0.089031f, +-0.400603f,0.906481f,0.133452f, +-0.448512f,0.870078f,0.204452f, +-0.467166f,0.869433f,0.160757f, +-0.442544f,0.892618f,0.0859534f, +-0.465336f,0.885122f,-0.00451183f, +-0.389888f,0.920791f,0.0114409f, +-0.26105f,0.96208f,0.079086f, +-0.0611649f,0.990413f,0.123862f, +0.218817f,0.959555f,0.177126f, +0.289447f,0.944291f,0.156638f, +0.238555f,0.970242f,0.0415028f, +0.303951f,0.946528f,-0.108164f, +0.431424f,0.894504f,-0.117199f, +0.527248f,0.845956f,-0.0797999f, +0.433918f,0.900916f,0.0081213f, +0.311993f,0.948885f,0.0477355f, +0.430547f,0.901487f,0.0441572f, +0.533619f,0.845624f,-0.013065f, +0.634808f,0.772557f,-0.013228f, +0.691864f,0.721963f,0.00965866f, +0.719067f,0.694383f,0.0278453f, +0.653183f,0.756562f,0.0310991f, +0.386363f,0.918778f,-0.0810638f, +0.0570874f,0.970389f,-0.234704f, +0.136394f,0.961794f,-0.237379f, +0.31236f,0.906525f,-0.283977f, +0.169471f,0.890916f,-0.421365f, +0.117142f,0.913195f,-0.390323f, +0.0777866f,0.931625f,-0.354998f, +-0.0437682f,0.92941f,-0.366443f, +-0.144429f,0.859889f,0.489623f, +-0.0880742f,0.890372f,0.446633f, +-0.0314378f,0.923882f,0.381384f, +-0.0838814f,0.944139f,0.318693f, +-0.0693885f,0.945887f,0.316991f, +-0.0723769f,0.923178f,0.377496f, +-0.19706f,0.892458f,0.405815f, +-0.297386f,0.892332f,0.339566f, +-0.156962f,0.91638f,0.368254f, +-0.15276f,0.919794f,0.361447f, +-0.17017f,0.922781f,0.345714f, +-0.253151f,0.920843f,0.296586f, +-0.189094f,0.905109f,0.380816f, +0.00126887f,0.929197f,0.369582f, +0.193396f,0.936415f,0.292787f, +0.338227f,0.878943f,0.336247f, +0.32269f,0.878938f,0.351198f, +0.355444f,0.867037f,0.34915f, +0.217316f,0.918786f,0.329554f, +0.123007f,0.956146f,0.265807f, +0.19987f,0.950731f,0.236986f, +0.0209731f,0.979076f,0.202411f, +-0.247784f,0.961065f,0.122302f, +-0.158935f,0.979718f,0.122036f, +0.0602949f,0.986043f,0.155188f, +-0.0308065f,0.985867f,0.164674f, +-0.185866f,0.954971f,0.231267f, +-0.272851f,0.942767f,0.191682f, +-0.226832f,0.938998f,0.258516f, +-0.311155f,0.923351f,0.224958f, +-0.264965f,0.917378f,0.297004f, +-0.186536f,0.890461f,0.41507f, +-0.257136f,0.895376f,0.363569f, +-0.330368f,0.897563f,0.291955f, +-0.415623f,0.888172f,0.19598f, +-0.414839f,0.89462f,0.166025f, +-0.429244f,0.901932f,0.0476213f, +-0.370358f,0.92848f,0.0275516f, +-0.456696f,0.886215f,-0.0777874f, +-0.424934f,0.901633f,-0.0805556f, +-0.26755f,0.960865f,-0.0718042f, +-0.0958709f,0.992595f,-0.0745981f, +0.0853594f,0.996177f,0.0185983f, +0.317006f,0.925486f,0.207323f, +0.362438f,0.919121f,0.154455f, +0.423147f,0.903697f,0.0654098f, +0.439077f,0.898135f,-0.0237805f, +0.463592f,0.885685f,-0.0253961f, +0.432904f,0.900567f,0.0396714f, +0.274262f,0.960561f,-0.0458644f, +0.460874f,0.887433f,0.00757752f, +0.557878f,0.824691f,-0.0930446f, +0.608392f,0.791916f,-0.0522232f, +0.68605f,0.722282f,0.0874302f, +0.697187f,0.705867f,0.125228f, +0.597474f,0.77589f,0.202532f, +0.400677f,0.868028f,0.293233f, +0.18602f,0.951589f,0.244694f, +0.190924f,0.979879f,0.0581851f, +0.431268f,0.902043f,-0.01807f, +0.329374f,0.934061f,-0.137997f, +0.144406f,0.935772f,-0.321679f, +0.0779514f,0.92222f,-0.378727f, +-0.0417532f,0.914206f,-0.403093f, +-0.201619f,0.929423f,0.309066f, +-0.0738258f,0.948242f,0.308847f, +0.0288118f,0.952024f,0.304665f, +-0.00526808f,0.951397f,0.307922f, +-0.0992485f,0.952014f,0.289515f, +-0.179425f,0.914994f,0.361376f, +-0.223397f,0.866943f,0.445538f, +-0.185005f,0.868122f,0.460584f, +-0.180405f,0.90051f,0.395646f, +-0.165976f,0.891215f,0.422122f, +-0.142635f,0.91411f,0.37955f, +-0.196593f,0.942079f,0.271733f, +-0.231892f,0.955708f,0.181242f, +0.0754625f,0.968764f,0.236224f, +0.189929f,0.95814f,0.214232f, +0.245783f,0.922809f,0.29667f, +0.350212f,0.885135f,0.30641f, +0.361791f,0.894635f,0.262174f, +0.218601f,0.892888f,0.393656f, +0.122578f,0.888731f,0.441737f, +0.221602f,0.877963f,0.42435f, +0.113111f,0.927784f,0.355561f, +-0.0962286f,0.967788f,0.232652f, +-0.169743f,0.984124f,0.0518298f, +0.00440837f,0.997134f,0.0755295f, +-0.0780505f,0.992255f,0.096638f, +-0.206915f,0.971074f,0.119173f, +-0.298261f,0.946469f,0.123437f, +-0.365054f,0.904843f,0.219077f, +-0.255666f,0.897337f,0.35975f, +-0.290965f,0.914197f,0.282104f, +-0.292271f,0.916518f,0.27308f, +-0.219619f,0.919339f,0.326472f, +-0.256286f,0.928086f,0.270137f, +-0.310598f,0.93305f,0.18151f, +-0.350728f,0.934452f,0.0615507f, +-0.388138f,0.92156f,0.00876308f, +-0.343471f,0.93847f,0.0360903f, +-0.339947f,0.939272f,-0.0469463f, +-0.382902f,0.903055f,-0.19462f, +-0.249239f,0.929446f,-0.272047f, +-0.147764f,0.944907f,-0.29209f, +-0.0668186f,0.978447f,-0.19539f, +0.17553f,0.981686f,-0.0740426f, +0.388973f,0.921211f,-0.00833323f, +0.44678f,0.894539f,-0.0136777f, +0.47739f,0.878112f,-0.0318964f, +0.465567f,0.884409f,-0.0326842f, +0.484387f,0.873859f,-0.0417148f, +0.315003f,0.932104f,-0.178762f, +0.426472f,0.898104f,-0.107381f, +0.587094f,0.80929f,-0.0192587f, +0.491946f,0.869904f,0.0354452f, +0.550379f,0.808299f,0.209131f, +0.597166f,0.706874f,0.379107f, +0.503286f,0.706664f,0.497322f, +0.349603f,0.761935f,0.545191f, +0.317931f,0.791281f,0.522298f, +0.357034f,0.859818f,0.365021f, +0.457671f,0.859336f,0.22821f, +0.436038f,0.880267f,0.187085f, +0.291237f,0.949467f,0.117016f, +0.172846f,0.983353f,0.0560389f, +0.00924155f,0.999014f,-0.043417f, +-0.112379f,0.966854f,0.22927f, +-0.0543436f,0.980353f,0.189616f, +0.0014105f,0.977032f,0.213089f, +-0.0810261f,0.954455f,0.287143f, +-0.162384f,0.905883f,0.391161f, +-0.248623f,0.850337f,0.463803f, +-0.272281f,0.829594f,0.48748f, +-0.210534f,0.842738f,0.495447f, +-0.142516f,0.845822f,0.514076f, +-0.128959f,0.864859f,0.485168f, +-0.000520612f,0.895905f,0.444245f, +0.00320439f,0.940529f,0.339698f, +-0.169376f,0.979765f,0.106637f, +-0.0517963f,0.994886f,0.0867084f, +0.124214f,0.955178f,0.268711f, +0.208945f,0.916166f,0.342027f, +0.39407f,0.858275f,0.328745f, +0.248342f,0.913565f,0.322063f, +0.031165f,0.861455f,0.506877f, +0.0654094f,0.812115f,0.57982f, +0.246891f,0.786687f,0.565834f, +0.230643f,0.834381f,0.500612f, +0.069509f,0.924157f,0.375637f, +0.0080049f,0.977951f,0.208681f, +-0.0216545f,0.998818f,0.043521f, +-0.0416834f,0.994806f,0.0928633f, +-0.209164f,0.977378f,0.0313447f, +-0.33727f,0.941399f,0.00405643f, +-0.445763f,0.895148f,-0.00236945f, +-0.379089f,0.924127f,0.0477591f, +-0.212534f,0.958583f,0.189598f, +-0.289703f,0.944216f,0.156615f, +-0.225857f,0.954875f,0.19288f, +-0.19812f,0.968114f,0.153308f, +-0.225491f,0.970896f,0.0807165f, +-0.268028f,0.963292f,-0.0151842f, +-0.386115f,0.917249f,-0.0978197f, +-0.332792f,0.935954f,-0.115065f, +-0.223332f,0.957817f,-0.180856f, +-0.272615f,0.913397f,-0.302304f, +-0.182015f,0.92061f,-0.345468f, +-0.156497f,0.91949f,-0.36062f, +-0.125465f,0.931751f,-0.340733f, +0.1054f,0.935905f,-0.336114f, +0.348771f,0.906917f,-0.236346f, +0.444797f,0.880373f,-0.164617f, +0.451025f,0.885434f,-0.112171f, +0.467976f,0.880983f,-0.0697667f, +0.499335f,0.858868f,-0.114062f, +0.349601f,0.930335f,-0.110707f, +0.307802f,0.944888f,-0.11156f, +0.473394f,0.878106f,0.0694821f, +0.43441f,0.869457f,0.23523f, +0.41901f,0.855868f,0.303184f, +0.452664f,0.775597f,0.439937f, +0.432369f,0.72522f,0.535829f, +0.415514f,0.737038f,0.533032f, +0.381011f,0.793693f,0.474217f, +0.445314f,0.773558f,0.450892f, +0.520117f,0.767192f,0.375359f, +0.457464f,0.838846f,0.295064f, +0.276432f,0.924946f,0.260884f, +0.199394f,0.937964f,0.283664f, +0.190897f,0.927436f,0.32159f, +-0.0705492f,0.959049f,0.274315f, +-0.0655623f,0.961527f,0.266772f, +-0.0518964f,0.943387f,0.32761f, +-0.202287f,0.906319f,0.371032f, +-0.245861f,0.842829f,0.478739f, +-0.310342f,0.836362f,0.451869f, +-0.256381f,0.850522f,0.459219f, +-0.198762f,0.867072f,0.456815f, +-0.12379f,0.863897f,0.48822f, +-0.0469651f,0.900623f,0.432056f, +-8.11553e-005f,0.943721f,0.330744f, +0.129628f,0.925055f,0.357028f, +0.0340614f,0.966037f,0.256151f, +-0.0890995f,0.983963f,0.154524f, +-0.0322587f,0.981394f,0.189278f, +0.138447f,0.956229f,0.257794f, +0.317932f,0.883665f,0.343592f, +0.154174f,0.859961f,0.486516f, +-0.0823702f,0.837125f,0.540774f, +0.067942f,0.838652f,0.540413f, +0.256779f,0.806501f,0.532561f, +0.317316f,0.771073f,0.552047f, +0.228943f,0.837474f,0.496208f, +0.221417f,0.908583f,0.354192f, +0.0661321f,0.986936f,0.146917f, +-0.101631f,0.981129f,0.164493f, +-0.140334f,0.967949f,0.20828f, +-0.26644f,0.954208f,0.136f, +-0.376833f,0.92539f,0.0406146f, +-0.423125f,0.902479f,-0.0805992f, +-0.378547f,0.924929f,-0.0347556f, +-0.294214f,0.950388f,0.101004f, +-0.253707f,0.966868f,0.0282789f, +-0.1425f,0.989661f,0.0162607f, +-0.152778f,0.987285f,-0.0438961f, +-0.226417f,0.971142f,-0.0749508f, +-0.278106f,0.959626f,-0.0421373f, +-0.315252f,0.936348f,-0.154492f, +-0.13807f,0.983353f,-0.118124f, +-0.169891f,0.968928f,-0.179762f, +-0.200272f,0.947942f,-0.247583f, +-0.182846f,0.93983f,-0.288594f, +-0.0836086f,0.941177f,-0.327408f, +0.0732417f,0.918516f,-0.388542f, +0.208177f,0.929929f,-0.303139f, +0.350352f,0.926406f,-0.137933f, +0.401951f,0.914196f,-0.0517823f, +0.448456f,0.893661f,-0.0160636f, +0.515556f,0.856358f,0.0291996f, +0.347689f,0.937245f,0.0261378f, +0.255909f,0.965329f,0.0514824f, +0.382053f,0.909938f,0.161395f, +0.340926f,0.922929f,0.178808f, +0.312845f,0.910786f,0.269439f, +0.364196f,0.849776f,0.381106f, +0.45928f,0.814969f,0.353394f, +0.52951f,0.800019f,0.282116f, +0.449914f,0.855375f,0.256731f, +0.454599f,0.838858f,0.299428f, +0.555327f,0.766362f,0.322957f, +0.54417f,0.781393f,0.305455f, +0.357615f,0.911759f,0.202005f, +0.139813f,0.972952f,0.183891f, +0.109083f,0.950848f,0.289808f, +-0.192892f,0.944314f,0.266579f, +-0.117537f,0.919218f,0.375796f, +-0.132138f,0.875254f,0.465263f, +-0.253971f,0.812679f,0.524453f, +-0.263136f,0.777105f,0.571723f, +-0.18663f,0.797568f,0.573633f, +-0.239071f,0.855961f,0.458449f, +-0.228946f,0.872463f,0.431732f, +-0.154745f,0.876861f,0.455159f, +0.0511929f,0.876307f,0.479025f, +0.079622f,0.902874f,0.422468f, +0.0999946f,0.903351f,0.417083f, +0.103272f,0.908778f,0.404299f, +-0.0300958f,0.943633f,0.329622f, +-0.0276233f,0.954592f,0.296632f, +0.0865379f,0.944508f,0.316884f, +0.19572f,0.915809f,0.350694f, +0.0629871f,0.902785f,0.425456f, +-0.0973105f,0.893058f,0.439293f, +0.0850344f,0.884912f,0.45793f, +0.226219f,0.859273f,0.458775f, +0.265876f,0.822998f,0.50198f, +0.299522f,0.800365f,0.519329f, +0.365936f,0.804413f,0.467986f, +0.167843f,0.908094f,0.383659f, +-0.151292f,0.923022f,0.353753f, +-0.16349f,0.897488f,0.409618f, +-0.164454f,0.89713f,0.410016f, +-0.256833f,0.931773f,0.256583f, +-0.308509f,0.944441f,0.11337f, +-0.397192f,0.916896f,-0.0392391f, +-0.321804f,0.945652f,-0.046751f, +-0.145617f,0.989197f,-0.0168656f, +-0.117605f,0.989571f,-0.083174f, +-0.131213f,0.988938f,-0.0691672f, +-0.264465f,0.964357f,-0.00857016f, +-0.279285f,0.95849f,0.0574115f, +-0.308064f,0.950873f,-0.0306128f, +-0.232189f,0.97071f,0.0617333f, +-0.126956f,0.977263f,0.169823f, +-0.134913f,0.981643f,0.134817f, +-0.0643092f,0.996192f,0.0588766f, +-0.0179518f,0.989177f,-0.145623f, +0.100718f,0.978365f,-0.180716f, +0.107842f,0.981772f,-0.156502f, +0.235537f,0.96668f,-0.100264f, +0.400696f,0.915349f,-0.0397433f, +0.382123f,0.921514f,-0.0692327f, +0.451191f,0.890657f,0.0561954f, +0.368356f,0.915308f,0.162865f, +0.16123f,0.974745f,0.154523f, +0.326647f,0.914341f,0.239337f, +0.365189f,0.91282f,0.182749f, +0.230086f,0.959458f,0.162792f, +0.336546f,0.918886f,0.205876f, +0.545838f,0.824177f,0.150977f, +0.544526f,0.829407f,0.124801f, +0.442013f,0.862414f,0.24671f, +0.417167f,0.87901f,0.230894f, +0.525918f,0.823184f,0.213956f, +0.591278f,0.763502f,0.259719f, +0.412761f,0.877728f,0.243355f, +0.079495f,0.961838f,0.261818f, +-0.108191f,0.959339f,0.260698f, +-0.395968f,0.898347f,0.190215f, +-0.315805f,0.885393f,0.341095f, +-0.255081f,0.831656f,0.493236f, +-0.32798f,0.786298f,0.523607f, +-0.31899f,0.766541f,0.557369f, +-0.160414f,0.763167f,0.625974f, +-0.0711111f,0.771377f,0.632393f, +-0.143173f,0.825852f,0.545409f, +-0.172278f,0.854223f,0.490534f, +0.0123154f,0.838365f,0.544971f, +0.0830743f,0.830631f,0.550592f, +0.0507686f,0.835031f,0.547855f, +0.149519f,0.800804f,0.579962f, +0.0893025f,0.847618f,0.523038f, +-0.0238205f,0.893087f,0.449253f, +0.0209713f,0.900623f,0.434095f, +0.182588f,0.867377f,0.462945f, +0.0933756f,0.88802f,0.450223f, +-0.0988317f,0.917919f,0.384262f, +0.0323919f,0.922001f,0.38583f, +0.205498f,0.882674f,0.422678f, +0.228981f,0.875897f,0.424702f, +0.330967f,0.833446f,0.442526f, +0.386545f,0.82285f,0.416534f, +0.244254f,0.85459f,0.458275f, +-0.128515f,0.915454f,0.381351f, +-0.221592f,0.919582f,0.324447f, +-0.103305f,0.941351f,0.321226f, +-0.0534104f,0.960954f,0.271504f, +-0.164863f,0.980806f,0.104112f, +-0.239884f,0.970598f,-0.0198681f, +-0.303213f,0.937604f,-0.170178f, +-0.252015f,0.951441f,-0.176773f, +-0.108694f,0.994072f,0.00232095f, +-0.192935f,0.981013f,0.0197642f, +-0.322908f,0.946132f,0.0237552f, +-0.269028f,0.963107f,-0.00704542f, +-0.230013f,0.973161f,0.00722315f, +-0.357365f,0.933662f,-0.0237822f, +-0.204315f,0.973479f,0.102922f, +-0.115797f,0.983778f,0.137007f, +0.0200406f,0.991033f,0.132107f, +0.176509f,0.981212f,0.0778953f, +0.102914f,0.991977f,-0.0734239f, +0.103634f,0.990563f,-0.0896973f, +0.246302f,0.962545f,-0.113327f, +0.365449f,0.921945f,-0.12831f, +0.388572f,0.919102f,-0.0652967f, +0.33675f,0.940592f,-0.0434361f, +0.294334f,0.951251f,0.0921318f, +0.170376f,0.973956f,0.149605f, +0.291052f,0.946977f,0.136102f, +0.448607f,0.879963f,0.156258f, +0.275208f,0.960522f,0.0407201f, +0.320727f,0.94717f,-0.00171267f, +0.563867f,0.822582f,0.0735748f, +0.458264f,0.882692f,0.104155f, +0.35932f,0.917336f,0.171414f, +0.473577f,0.85831f,0.197555f, +0.552768f,0.818756f,0.155195f, +0.56022f,0.811568f,0.165865f, +0.410483f,0.877955f,0.246373f, +0.119318f,0.965792f,0.230239f, +-0.0302464f,0.98755f,0.15437f, +-0.434902f,0.821345f,0.369123f, +-0.425801f,0.804682f,0.41374f, +-0.330648f,0.807018f,0.489278f, +-0.341863f,0.793213f,0.503928f, +-0.356504f,0.786512f,0.504286f, +-0.269874f,0.813284f,0.515498f, +-0.0937663f,0.786137f,0.610898f, +-0.0122488f,0.782782f,0.622176f, +-0.145176f,0.838097f,0.525849f, +-0.0659853f,0.863648f,0.499758f, +0.0911511f,0.81559f,0.571406f, +0.0567409f,0.801208f,0.59569f, +0.110855f,0.801019f,0.588286f, +0.153854f,0.799367f,0.580811f, +0.0810561f,0.837494f,0.540401f, +0.0627084f,0.873537f,0.482702f, +0.153028f,0.87118f,0.466506f, +0.121758f,0.869515f,0.478663f, +-0.0139367f,0.889364f,0.456987f, +0.0116753f,0.909652f,0.415206f, +0.182976f,0.873078f,0.451946f, +0.230254f,0.874104f,0.427698f, +0.299542f,0.853577f,0.42624f, +0.365816f,0.815944f,0.447677f, +0.258135f,0.828321f,0.497243f, +0.0438733f,0.899999f,0.433678f, +-0.113551f,0.976415f,0.183628f, +-0.115165f,0.991964f,0.0523877f, +-0.0427249f,0.989973f,0.134639f, +-0.000526251f,0.987641f,0.156735f, +-0.182878f,0.982656f,-0.0306907f, +-0.187196f,0.982029f,-0.0240342f, +-0.272847f,0.956238f,-0.105656f, +-0.292658f,0.95046f,-0.104775f, +-0.178909f,0.983865f,0.00116467f, +-0.22078f,0.973898f,-0.0527095f, +-0.269354f,0.950491f,-0.154966f, +-0.262457f,0.956005f,-0.131038f, +-0.333574f,0.929233f,-0.158915f, +-0.27846f,0.93913f,-0.201231f, +-0.105722f,0.98028f,-0.166954f, +-0.03086f,0.983393f,-0.178845f, +0.166296f,0.985117f,-0.0434662f, +0.22991f,0.973119f,0.0134671f, +0.156605f,0.983722f,-0.0881293f, +0.276714f,0.94824f,-0.155787f, +0.32696f,0.929339f,-0.171541f, +0.339039f,0.938238f,-0.0690071f, +0.308789f,0.948131f,-0.0754727f, +0.23717f,0.967343f,-0.0894326f, +0.163558f,0.982662f,-0.0873214f, +0.252735f,0.966333f,-0.0482272f, +0.434287f,0.896865f,0.0838305f, +0.398093f,0.912104f,0.0979158f, +0.320154f,0.94669f,-0.0357668f, +0.45783f,0.889003f,0.00810452f, +0.504235f,0.85135f,0.144742f, +0.385352f,0.920157f,0.0693918f, +0.466232f,0.882239f,0.0654287f, +0.538345f,0.833943f,0.121343f, +0.517827f,0.838051f,0.171829f, +0.46128f,0.862173f,0.209471f, +0.229103f,0.969676f,0.085091f, +0.119821f,0.992172f,0.0351865f, +-0.316654f,0.75101f,0.579409f, +-0.356062f,0.779142f,0.515904f, +-0.357471f,0.814286f,0.457331f, +-0.357809f,0.798452f,0.484198f, +-0.344344f,0.806376f,0.480818f, +-0.279175f,0.813317f,0.510467f, +-0.188283f,0.817533f,0.544233f, +0.0108927f,0.825394f,0.564451f, +0.000505664f,0.854739f,0.519058f, +-0.0291193f,0.899152f,0.436667f, +-0.043893f,0.902469f,0.428513f, +-0.00142614f,0.854428f,0.519568f, +0.10644f,0.82426f,0.556117f, +0.17821f,0.772022f,0.610101f, +0.155558f,0.792656f,0.58949f, +0.103298f,0.851042f,0.514837f, +0.136998f,0.86222f,0.487656f, +0.128814f,0.846529f,0.516522f, +0.0086465f,0.861582f,0.507544f, +0.0126115f,0.865086f,0.501464f, +0.152876f,0.854998f,0.495588f, +0.261992f,0.846686f,0.463122f, +0.298132f,0.855648f,0.423065f, +0.330245f,0.846388f,0.417811f, +0.241868f,0.85891f,0.451412f, +0.243399f,0.870337f,0.428102f, +0.218863f,0.950296f,0.221442f, +-0.0230145f,0.994562f,-0.101567f, +-0.18143f,0.968994f,-0.167732f, +-0.00536077f,0.999859f,-0.0158957f, +-0.0149312f,0.999841f,-0.00972481f, +-0.248945f,0.961384f,-0.11733f, +-0.206226f,0.978121f,-0.0273758f, +-0.251569f,0.958037f,-0.137399f, +-0.215501f,0.957565f,-0.191386f, +-0.183194f,0.972176f,-0.145991f, +-0.242363f,0.956164f,-0.164351f, +-0.223675f,0.959477f,-0.171387f, +-0.263678f,0.929229f,-0.25886f, +-0.190809f,0.923444f,-0.332932f, +-0.125476f,0.902264f,-0.412524f, +-0.0800599f,0.931052f,-0.355994f, +0.00289679f,0.952892f,-0.303297f, +0.173027f,0.965415f,-0.195025f, +0.23552f,0.951626f,-0.197328f, +0.324166f,0.90746f,-0.26727f, +0.272213f,0.920502f,-0.280314f, +0.263103f,0.942676f,-0.205278f, +0.331376f,0.931643f,-0.1491f, +0.273621f,0.957062f,-0.0957296f, +0.174678f,0.976512f,-0.126141f, +0.162465f,0.97193f,-0.170168f, +0.285207f,0.956722f,-0.0577913f, +0.392887f,0.912166f,0.116586f, +0.413213f,0.901715f,0.127138f, +0.444428f,0.894805f,0.0425078f, +0.482399f,0.875952f,0.000225918f, +0.414394f,0.908379f,-0.0559034f, +0.421361f,0.906852f,-0.00856344f, +0.501069f,0.86151f,0.0820434f, +0.492896f,0.86226f,0.116453f, +0.497628f,0.854344f,0.149874f, +0.327901f,0.939568f,0.0984569f, +0.134608f,0.990256f,0.0356963f, +-0.115732f,0.781457f,0.613132f, +-0.224646f,0.82464f,0.519137f, +-0.330602f,0.837584f,0.434919f, +-0.37055f,0.826801f,0.423193f, +-0.389755f,0.836631f,0.38489f, +-0.35019f,0.83732f,0.419835f, +-0.192063f,0.866433f,0.460875f, +0.0577661f,0.893053f,0.446228f, +0.0715028f,0.909685f,0.409097f, +0.0355467f,0.937027f,0.347443f, +-0.0473295f,0.949618f,0.309815f, +-0.0714543f,0.946618f,0.31434f, +0.0109848f,0.930588f,0.365903f, +0.0306039f,0.876434f,0.480548f, +0.171338f,0.790427f,0.588106f, +0.228263f,0.773415f,0.591376f, +0.15062f,0.839076f,0.522748f, +0.0933237f,0.852392f,0.514508f, +0.0403687f,0.864191f,0.501542f, +0.0159293f,0.89067f,0.454371f, +0.162582f,0.873944f,0.458028f, +0.324998f,0.838057f,0.438219f, +0.361417f,0.861814f,0.355886f, +0.357364f,0.88789f,0.289727f, +0.288052f,0.920034f,0.265637f, +0.274707f,0.932706f,0.233657f, +0.415911f,0.867317f,0.273456f, +0.214502f,0.965967f,0.144559f, +-0.0739208f,0.997262f,-0.00212715f, +-0.130316f,0.972201f,-0.194533f, +0.00262571f,0.981048f,-0.193747f, +-0.190851f,0.93935f,-0.284951f, +-0.250649f,0.92646f,-0.280798f, +-0.16238f,0.957944f,-0.236595f, +-0.204897f,0.9457f,-0.252327f, +-0.246487f,0.945291f,-0.213705f, +-0.204741f,0.966747f,-0.153234f, +-0.173965f,0.952924f,-0.248341f, +-0.185492f,0.924696f,-0.332461f, +-0.120486f,0.929748f,-0.347926f, +-0.0981061f,0.932335f,-0.348033f, +-0.143961f,0.923839f,-0.354678f, +-0.0348514f,0.936175f,-0.349804f, +0.141193f,0.941481f,-0.306069f, +0.298926f,0.908144f,-0.293117f, +0.339558f,0.869399f,-0.35895f, +0.236934f,0.893673f,-0.381064f, +0.188986f,0.916304f,-0.353088f, +0.222126f,0.937284f,-0.268624f, +0.165461f,0.966952f,-0.193976f, +0.194618f,0.975642f,-0.101229f, +0.225585f,0.970105f,-0.0894815f, +0.18757f,0.970367f,-0.152331f, +0.271776f,0.9587f,-0.0838549f, +0.390134f,0.920749f,0.00399703f, +0.487191f,0.870564f,0.0690114f, +0.567845f,0.821826f,0.0464111f, +0.430596f,0.898843f,-0.0816633f, +0.345462f,0.936301f,-0.063213f, +0.439054f,0.898457f,0.0025505f, +0.485886f,0.873093f,0.040301f, +0.468523f,0.882438f,0.0422951f, +0.395695f,0.916215f,0.0630502f, +0.224264f,0.974198f,-0.0253916f, +-0.04074f,0.869731f,0.491842f, +-0.147521f,0.861626f,0.485632f, +-0.290306f,0.828918f,0.47814f, +-0.344291f,0.81826f,0.460342f, +-0.325822f,0.848235f,0.417537f, +-0.347006f,0.892025f,0.289618f, +-0.23289f,0.9484f,0.215175f, +0.0826503f,0.953848f,0.288692f, +0.0849803f,0.942357f,0.323639f, +0.0946367f,0.912864f,0.397143f, +0.0188563f,0.944615f,0.327637f, +-0.0844647f,0.976435f,0.198596f, +-0.0480441f,0.982086f,0.182207f, +-0.108246f,0.969423f,0.220233f, +0.0163534f,0.944153f,0.329102f, +0.218936f,0.864112f,0.453186f, +0.243602f,0.846524f,0.473344f, +0.157715f,0.898021f,0.410713f, +0.124101f,0.930824f,0.343753f, +0.0887369f,0.958556f,0.270731f, +0.13199f,0.965856f,0.222935f, +0.34996f,0.900513f,0.258077f, +0.45204f,0.856515f,0.249081f, +0.434574f,0.879659f,0.19325f, +0.307812f,0.936972f,0.165332f, +0.238408f,0.942387f,0.234669f, +0.292411f,0.883524f,0.365897f, +0.235944f,0.851222f,0.468777f, +0.0834983f,0.888208f,0.45179f, +0.120252f,0.948234f,0.293925f, +0.107426f,0.988487f,0.106553f, +-0.0604958f,0.997925f,0.0220282f, +-0.22861f,0.965114f,-0.127644f, +-0.213845f,0.934088f,-0.285919f, +-0.236679f,0.925441f,-0.295876f, +-0.274282f,0.922231f,-0.272506f, +-0.200442f,0.934584f,-0.293896f, +-0.0905439f,0.955043f,-0.282301f, +-0.107977f,0.974204f,-0.198159f, +-0.176859f,0.954188f,-0.241343f, +-0.109412f,0.961464f,-0.252221f, +-0.0832631f,0.934053f,-0.347292f, +-0.0389646f,0.894623f,-0.44512f, +0.0844722f,0.90285f,-0.421576f, +0.278944f,0.884527f,-0.373902f, +0.405411f,0.845478f,-0.347577f, +0.241979f,0.880406f,-0.407837f, +0.10107f,0.917999f,-0.383487f, +0.153454f,0.950374f,-0.270631f, +0.150056f,0.964994f,-0.215103f, +0.116981f,0.964373f,-0.237277f, +0.171185f,0.966068f,-0.19341f, +0.269303f,0.954896f,-0.1251f, +0.246577f,0.939836f,-0.236448f, +0.325998f,0.915178f,-0.237011f, +0.400262f,0.89707f,-0.18723f, +0.540095f,0.838463f,-0.0726465f, +0.4591f,0.888384f,0.000734802f, +0.350121f,0.936701f,0.00262749f, +0.415959f,0.907987f,-0.0503785f, +0.469999f,0.882626f,-0.00849165f, +0.46759f,0.883776f,0.0172864f, +0.444948f,0.895095f,0.0287648f, +0.38429f,0.923043f,-0.0176926f, +-0.184131f,0.893945f,0.408605f, +-0.22256f,0.84592f,0.484651f, +-0.306803f,0.799127f,0.516979f, +-0.327467f,0.825975f,0.458836f, +-0.215523f,0.873324f,0.43687f, +-0.122358f,0.93676f,0.327886f, +-0.214245f,0.969738f,0.117081f, +0.00165628f,0.984816f,0.173596f, +-0.0471807f,0.97232f,0.228838f, +-0.042786f,0.929182f,0.367137f, +0.159108f,0.885534f,0.43648f, +0.0848362f,0.945025f,0.315803f, +-0.0323525f,0.969808f,0.241716f, +-0.0998895f,0.964402f,0.244849f, +-0.0727123f,0.986494f,0.146772f, +0.121392f,0.97688f,0.175982f, +0.260802f,0.928486f,0.264378f, +0.24004f,0.922405f,0.302572f, +0.162896f,0.94112f,0.296239f, +0.158069f,0.936377f,0.313389f, +0.18876f,0.956613f,0.221947f, +0.312407f,0.939867f,0.138025f, +0.450948f,0.870255f,0.198248f, +0.44762f,0.863366f,0.232885f, +0.235953f,0.935784f,0.261983f, +0.128819f,0.928252f,0.348933f, +0.106701f,0.927182f,0.359094f, +0.172918f,0.882203f,0.437968f, +0.183128f,0.868984f,0.459707f, +0.240959f,0.881259f,0.406597f, +0.154256f,0.918617f,0.363797f, +0.0253035f,0.919137f,0.393124f, +0.0182377f,0.964511f,0.263413f, +0.0263571f,0.99964f,0.00499089f, +-0.149002f,0.961331f,-0.231604f, +-0.264821f,0.912849f,-0.310769f, +-0.139498f,0.954507f,-0.263548f, +-0.253683f,0.93262f,-0.25664f, +-0.265231f,0.9626f,-0.0552561f, +-0.114883f,0.993341f,-0.00868247f, +0.0072742f,0.99351f,-0.113513f, +0.112563f,0.957036f,-0.26723f, +0.0621414f,0.905176f,-0.420469f, +0.0722297f,0.880288f,-0.468909f, +0.230329f,0.856327f,-0.462225f, +0.381575f,0.843927f,-0.377079f, +0.221134f,0.891315f,-0.395799f, +0.0308171f,0.923698f,-0.381879f, +0.0400222f,0.939112f,-0.341272f, +0.100477f,0.950816f,-0.293006f, +0.177047f,0.942783f,-0.282515f, +0.133298f,0.926135f,-0.352852f, +0.196525f,0.937661f,-0.286653f, +0.349249f,0.920399f,-0.17576f, +0.344233f,0.909171f,-0.234334f, +0.376056f,0.891226f,-0.25357f, +0.439076f,0.869021f,-0.228069f, +0.419906f,0.900431f,-0.113589f, +0.367672f,0.919513f,-0.13897f, +0.413581f,0.894358f,-0.170514f, +0.417856f,0.905717f,-0.0712231f, +0.442627f,0.896671f,0.00788109f, +0.434719f,0.900071f,0.0298519f, +0.417993f,0.908131f,0.0240916f, +-0.312333f,0.839022f,0.445522f, +-0.320499f,0.80841f,0.493714f, +-0.254519f,0.811123f,0.526593f, +-0.204612f,0.85744f,0.472156f, +-0.178862f,0.910868f,0.371925f, +-0.00702334f,0.926328f,0.376653f, +-0.0708828f,0.954444f,0.289847f, +-0.0771525f,0.977635f,0.195648f, +-0.0751036f,0.961343f,0.264914f, +-0.145577f,0.95681f,0.25164f, +0.127391f,0.9356f,0.329278f, +0.155803f,0.922417f,0.353372f, +-0.0158909f,0.953782f,0.300078f, +-0.071615f,0.974742f,0.211541f, +0.0985463f,0.976728f,0.190504f, +0.112633f,0.991267f,0.0685771f, +0.169574f,0.979892f,0.105153f, +0.189025f,0.96308f,0.191696f, +0.0919285f,0.967342f,0.236218f, +0.12853f,0.953507f,0.272588f, +0.291986f,0.918653f,0.266123f, +0.353363f,0.907675f,0.226407f, +0.385555f,0.89484f,0.224962f, +0.404454f,0.872627f,0.273752f, +0.205311f,0.929054f,0.307743f, +0.110161f,0.942272f,0.316208f, +0.185964f,0.923078f,0.336668f, +0.152054f,0.949861f,0.273212f, +0.185461f,0.938647f,0.290768f, +0.273329f,0.907935f,0.317718f, +0.1744f,0.944567f,0.278169f, +0.0252708f,0.979111f,0.20175f, +0.168508f,0.972599f,0.160178f, +0.171022f,0.978059f,0.118964f, +0.0998107f,0.989636f,0.103241f, +-0.201522f,0.966723f,-0.157591f, +-0.270475f,0.936595f,-0.222784f, +-0.312657f,0.944755f,-0.0984088f, +-0.352005f,0.934773f,-0.0478632f, +-0.0861214f,0.995901f,-0.0276381f, +0.0987576f,0.994369f,-0.0384345f, +0.271502f,0.95802f,-0.0921061f, +0.198786f,0.941001f,-0.273863f, +0.12025f,0.91375f,-0.388073f, +0.19318f,0.901312f,-0.38771f, +0.347672f,0.893681f,-0.283653f, +0.243349f,0.925421f,-0.290477f, +0.0173943f,0.947888f,-0.318129f, +0.037959f,0.944705f,-0.325718f, +0.138906f,0.919468f,-0.36781f, +0.157447f,0.882137f,-0.443897f, +0.187757f,0.895179f,-0.404229f, +0.0607904f,0.891083f,-0.44975f, +0.186006f,0.945946f,-0.265685f, +0.365887f,0.929282f,-0.0506235f, +0.41897f,0.907686f,-0.0238758f, +0.421784f,0.903427f,-0.0769231f, +0.443234f,0.894342f,-0.0608035f, +0.410975f,0.898831f,-0.152323f, +0.386797f,0.913648f,-0.125039f, +0.291947f,0.94823f,-0.125004f, +0.388472f,0.921139f,-0.0243475f, +0.43729f,0.89932f,0.000909095f, +0.438439f,0.898727f,-0.00777216f, +-0.28789f,0.841477f,0.457204f, +-0.335895f,0.843138f,0.419871f, +-0.2812f,0.876582f,0.390553f, +-0.0955224f,0.927302f,0.361922f, +-0.12003f,0.968207f,0.219473f, +-0.0624603f,0.972133f,0.225956f, +0.00876105f,0.944888f,0.327276f, +-0.0188296f,0.951986f,0.305562f, +-0.0880524f,0.955492f,0.28157f, +-0.14211f,0.96142f,0.235533f, +0.0867118f,0.963277f,0.254122f, +0.135173f,0.965034f,0.224584f, +0.150393f,0.96446f,0.217252f, +0.0301773f,0.99954f,0.00289386f, +0.112215f,0.991225f,-0.0698593f, +0.139936f,0.985559f,-0.0953439f, +0.125274f,0.991296f,-0.0404889f, +0.130003f,0.991461f,0.0102436f, +0.104702f,0.992835f,0.0575904f, +0.129192f,0.991077f,0.0328109f, +0.258743f,0.962487f,0.0816753f, +0.358319f,0.917773f,0.171175f, +0.362543f,0.919373f,0.152698f, +0.379026f,0.899795f,0.216122f, +0.252574f,0.930076f,0.266767f, +0.106065f,0.974915f,0.195683f, +0.13953f,0.968709f,0.205267f, +0.207814f,0.946678f,0.246198f, +0.149976f,0.969192f,0.195383f, +0.250422f,0.937237f,0.242644f, +0.308573f,0.924236f,0.224878f, +0.137327f,0.986571f,0.0884273f, +0.176869f,0.981357f,0.0752039f, +0.106914f,0.989761f,0.0945676f, +0.0990876f,0.985862f,0.135123f, +0.0562231f,0.995571f,0.0753513f, +-0.246892f,0.957072f,-0.15185f, +-0.351837f,0.92065f,-0.169157f, +-0.377614f,0.902561f,-0.206862f, +-0.10132f,0.980362f,-0.169188f, +0.0776454f,0.98254f,-0.169077f, +0.306304f,0.93954f,-0.153108f, +0.377181f,0.900422f,-0.216738f, +0.189257f,0.917577f,-0.349621f, +0.154953f,0.928643f,-0.337063f, +0.267717f,0.911458f,-0.312367f, +0.294676f,0.908518f,-0.296244f, +0.0231864f,0.917435f,-0.39721f, +0.0626224f,0.928776f,-0.365314f, +0.222796f,0.906686f,-0.358165f, +0.23143f,0.87959f,-0.415646f, +0.13808f,0.870415f,-0.472559f, +0.025291f,0.910796f,-0.412081f, +-0.0453254f,0.945277f,-0.323104f, +0.159501f,0.971914f,-0.17304f, +0.38445f,0.922508f,-0.0343154f, +0.457445f,0.889226f,-0.00452937f, +0.479545f,0.877417f,-0.0132742f, +0.420093f,0.902443f,-0.0954967f, +0.386091f,0.921349f,-0.0452663f, +0.319162f,0.945851f,-0.059174f, +0.358596f,0.930564f,-0.0738904f, +0.442653f,0.891593f,-0.0955061f, +0.442432f,0.88607f,-0.138327f, +-0.180108f,0.868506f,0.461799f, +-0.252344f,0.891893f,0.375298f, +-0.214515f,0.951228f,0.221693f, +-0.0232238f,0.989215f,0.144618f, +0.0240637f,0.992144f,0.122761f, +-0.119024f,0.992873f,0.00598183f, +-0.113037f,0.992656f,0.0430988f, +-0.0429691f,0.994091f,0.0996822f, +-0.0494378f,0.98881f,0.140751f, +-0.101045f,0.990831f,0.0896877f, +0.0748729f,0.995782f,0.0530223f, +0.173588f,0.976877f,0.124814f, +0.168744f,0.967443f,0.188628f, +0.211654f,0.955224f,0.206761f, +0.198232f,0.976689f,0.0823528f, +0.160641f,0.986993f,-0.00630407f, +0.0575905f,0.994633f,-0.0859521f, +0.0365841f,0.998447f,-0.0420043f, +0.0556411f,0.989086f,0.136432f, +0.127974f,0.973486f,0.1896f, +0.188609f,0.96964f,0.155643f, +0.316079f,0.935031f,0.16066f, +0.368833f,0.913789f,0.170151f, +0.28567f,0.933317f,0.217512f, +0.224877f,0.919424f,0.322631f, +0.173372f,0.927466f,0.331284f, +0.14641f,0.951279f,0.271352f, +0.199618f,0.950197f,0.239328f, +0.194716f,0.961761f,0.192616f, +0.211001f,0.970026f,0.12053f, +0.377145f,0.915922f,0.137289f, +0.173279f,0.983115f,0.0588147f, +0.137169f,0.986854f,0.085457f, +0.167124f,0.984519f,0.0528309f, +0.114693f,0.990538f,-0.0753596f, +0.120988f,0.991416f,-0.0495523f, +-0.0934722f,0.99234f,-0.0807704f, +-0.28812f,0.930265f,-0.227141f, +-0.319246f,0.884516f,-0.340167f, +-0.147049f,0.912977f,-0.380591f, +0.113837f,0.925954f,-0.360071f, +0.286328f,0.873071f,-0.394668f, +0.386305f,0.86841f,-0.310857f, +0.201568f,0.937185f,-0.284702f, +0.165365f,0.953527f,-0.251875f, +0.277218f,0.910704f,-0.306215f, +0.350715f,0.890932f,-0.288511f, +0.130261f,0.920935f,-0.367302f, +-0.00793534f,0.891743f,-0.452472f, +0.173424f,0.90309f,-0.392878f, +0.309572f,0.891597f,-0.330484f, +0.155483f,0.904383f,-0.397387f, +-0.0901615f,0.931774f,-0.351664f, +-0.12522f,0.950283f,-0.285102f, +0.116309f,0.952999f,-0.279758f, +0.314059f,0.900664f,-0.300285f, +0.399484f,0.884115f,-0.242388f, +0.476487f,0.865346f,-0.155359f, +0.461331f,0.87037f,-0.172132f, +0.340659f,0.915541f,-0.213858f, +0.307988f,0.934535f,-0.178292f, +0.356904f,0.924065f,-0.136833f, +0.470016f,0.879468f,-0.0749671f, +0.505067f,0.862447f,-0.0330571f, +-0.15355f,0.924768f,0.348175f, +-0.09321f,0.949622f,0.299215f, +-0.0484808f,0.991662f,0.1194f, +-0.0103305f,0.999605f,0.0261285f, +0.0401188f,0.998578f,0.0351042f, +-0.00661539f,0.998628f,-0.0519471f, +-0.0683745f,0.981776f,-0.177318f, +-0.0856989f,0.966825f,-0.240633f, +-0.0983519f,0.984458f,-0.145499f, +-0.0680709f,0.995572f,-0.0648268f, +0.0777629f,0.996246f,-0.0380386f, +0.0383267f,0.998901f,-0.0269619f, +0.00333347f,0.997094f,0.0761077f, +0.139217f,0.959624f,0.244419f, +0.245721f,0.912381f,0.327386f, +0.246821f,0.907772f,0.339159f, +0.175417f,0.940931f,0.289617f, +-0.027159f,0.9789f,0.202525f, +-0.173424f,0.953226f,0.247557f, +0.0844967f,0.921276f,0.37962f, +0.304261f,0.89366f,0.329845f, +0.31812f,0.923926f,0.21251f, +0.353311f,0.902952f,0.244642f, +0.195957f,0.945525f,0.25997f, +0.182247f,0.923305f,0.338075f, +0.134205f,0.934918f,0.328507f, +0.176553f,0.881734f,0.437463f, +0.22427f,0.87574f,0.42753f, +0.29074f,0.869795f,0.398657f, +0.272684f,0.924539f,0.266215f, +0.39631f,0.892935f,0.213556f, +0.227086f,0.96746f,0.111597f, +0.14196f,0.988195f,0.0576051f, +0.283679f,0.958555f,0.0264133f, +0.216474f,0.969698f,-0.113251f, +0.0386649f,0.982201f,-0.183812f, +-0.0151491f,0.988164f,-0.152652f, +-0.145516f,0.952277f,-0.268316f, +-0.219857f,0.921944f,-0.318875f, +-0.140821f,0.920717f,-0.363936f, +0.13255f,0.932146f,-0.33695f, +0.285156f,0.898104f,-0.334807f, +0.270867f,0.921389f,-0.278701f, +0.136545f,0.958362f,-0.250793f, +0.156889f,0.960437f,-0.230103f, +0.337521f,0.917391f,-0.210889f, +0.340375f,0.909959f,-0.236896f, +0.226521f,0.931852f,-0.283443f, +0.0467156f,0.919678f,-0.389885f, +0.11829f,0.926104f,-0.358244f, +0.284734f,0.910765f,-0.299055f, +0.155007f,0.943096f,-0.294183f, +-0.117772f,0.948884f,-0.29283f, +-0.124268f,0.932168f,-0.340029f, +0.155477f,0.92011f,-0.359477f, +0.348711f,0.859859f,-0.372885f, +0.344156f,0.842199f,-0.415039f, +0.367487f,0.839547f,-0.400142f, +0.45537f,0.851179f,-0.261021f, +0.340771f,0.905445f,-0.25307f, +0.281592f,0.927438f,-0.246101f, +0.270207f,0.930215f,-0.248371f, +0.337751f,0.936799f,-0.0912801f, +0.415821f,0.905383f,0.085868f, +-0.0508816f,0.992949f,0.107064f, +0.00772943f,0.999926f,0.0093874f, +0.0748585f,0.990585f,-0.114623f, +0.0155266f,0.983672f,-0.179298f, +0.0579395f,0.986738f,-0.15163f, +0.0876255f,0.991018f,-0.10102f, +0.0527296f,0.995461f,-0.0792264f, +-0.086898f,0.99085f,-0.103274f, +-0.226618f,0.972789f,-0.0482267f, +-0.175193f,0.983195f,0.0513344f, +0.0267808f,0.994997f,0.0962477f, +0.0618698f,0.991981f,0.110211f, +-0.098328f,0.984739f,0.143601f, +-0.00458312f,0.952299f,0.305132f, +0.173153f,0.913691f,0.367678f, +0.186464f,0.911194f,0.367365f, +0.171431f,0.905309f,0.388622f, +0.0620384f,0.93682f,0.344266f, +-0.143644f,0.960893f,0.23675f, +0.0362541f,0.97893f,0.200951f, +0.349667f,0.904284f,0.244957f, +0.338175f,0.903327f,0.26389f, +0.333852f,0.898218f,0.285914f, +0.192181f,0.948404f,0.252183f, +0.15408f,0.957234f,0.244873f, +0.108314f,0.961372f,0.253046f, +0.0186373f,0.953687f,0.300223f, +0.205839f,0.914416f,0.34853f, +0.331275f,0.886521f,0.323015f, +0.368345f,0.875165f,0.313702f, +0.405591f,0.862022f,0.303997f, +0.335644f,0.884308f,0.324566f, +0.194457f,0.953987f,0.228245f, +0.317589f,0.932139f,0.173936f, +0.34707f,0.93458f,0.0781131f, +0.1429f,0.981779f,-0.125256f, +0.0457434f,0.962864f,-0.266085f, +-0.0800896f,0.929514f,-0.359987f, +-0.224976f,0.908098f,-0.353191f, +-0.16594f,0.929111f,-0.330481f, +0.0749763f,0.957672f,-0.277928f, +0.277052f,0.936424f,-0.215295f, +0.266206f,0.947023f,-0.17967f, +0.192217f,0.96172f,-0.195315f, +0.159333f,0.947925f,-0.275775f, +0.291985f,0.916673f,-0.272864f, +0.390644f,0.893072f,-0.223205f, +0.316013f,0.901654f,-0.295223f, +0.0938304f,0.916417f,-0.38907f, +0.0371906f,0.918056f,-0.394702f, +0.249356f,0.914822f,-0.317682f, +0.159281f,0.933374f,-0.321625f, +-0.034507f,0.927426f,-0.372412f, +-0.0639276f,0.876921f,-0.476365f, +0.150154f,0.87361f,-0.462881f, +0.34577f,0.845394f,-0.407127f, +0.406017f,0.841234f,-0.357037f, +0.322181f,0.876026f,-0.358855f, +0.315882f,0.91236f,-0.260417f, +0.325378f,0.928704f,-0.177873f, +0.281437f,0.937288f,-0.205633f, +0.23991f,0.955112f,-0.173792f, +0.165717f,0.980838f,-0.102443f, +0.16591f,0.98582f,-0.0251575f, +0.188672f,0.97776f,0.0915829f, +0.0994257f,0.983812f,-0.14909f, +0.199087f,0.95198f,-0.232593f, +0.0121878f,0.914874f,-0.403556f, +-0.0234414f,0.930265f,-0.36614f, +-0.038124f,0.972539f,-0.229595f, +-0.0300917f,0.999515f,-0.00796094f, +-0.092201f,0.984658f,0.148144f, +-0.315366f,0.938181f,0.142688f, +-0.138968f,0.942311f,0.304528f, +0.0277459f,0.977812f,0.207641f, +0.0496201f,0.98101f,0.187502f, +-0.256039f,0.940975f,0.22138f, +-0.0796386f,0.864833f,0.495703f, +0.172206f,0.836979f,0.519434f, +0.218401f,0.8652f,0.451365f, +0.211231f,0.888948f,0.406391f, +0.153922f,0.942863f,0.295494f, +-0.0705923f,0.983817f,0.164685f, +0.0334153f,0.99603f,0.0825054f, +0.282635f,0.9535f,0.104667f, +0.322121f,0.91103f,0.257413f, +0.32296f,0.89395f,0.310726f, +0.263681f,0.921808f,0.284152f, +0.145976f,0.970498f,0.191897f, +0.110214f,0.967993f,0.225482f, +0.0100073f,0.970397f,0.241307f, +0.231259f,0.94984f,0.210532f, +0.350804f,0.929639f,0.112731f, +0.388908f,0.908557f,0.152559f, +0.325259f,0.933029f,0.153831f, +0.358244f,0.845843f,0.395235f, +0.245479f,0.88292f,0.400241f, +0.340078f,0.880829f,0.329372f, +0.448713f,0.860203f,0.242295f, +0.291253f,0.956268f,-0.0268833f, +0.174446f,0.957532f,-0.229565f, +-0.0246181f,0.920367f,-0.390281f, +-0.230596f,0.878986f,-0.417383f, +-0.188847f,0.897269f,-0.399054f, +0.0175328f,0.926292f,-0.376398f, +0.23985f,0.925856f,-0.291997f, +0.22945f,0.938275f,-0.258829f, +0.212396f,0.953082f,-0.21569f, +0.229329f,0.940641f,-0.250204f, +0.284501f,0.899212f,-0.33238f, +0.376241f,0.875275f,-0.30387f, +0.33476f,0.887829f,-0.315744f, +0.163808f,0.925647f,-0.341094f, +0.00890663f,0.895805f,-0.444357f, +0.214972f,0.896442f,-0.38753f, +0.17587f,0.912162f,-0.370177f, +0.075136f,0.903308f,-0.422362f, +-0.00910936f,0.832148f,-0.55448f, +0.080579f,0.825188f,-0.559082f, +0.296201f,0.838595f,-0.457191f, +0.316267f,0.8627f,-0.39462f, +0.301959f,0.9215f,-0.24425f, +0.239667f,0.953185f,-0.184387f, +0.359606f,0.929321f,-0.0839473f, +0.264487f,0.941897f,-0.207066f, +0.184815f,0.971569f,-0.147976f, +0.141833f,0.988976f,-0.0425335f, +0.112364f,0.992816f,-0.0411276f, +}; + +btScalar Landscape04Tex[] = { +0.507813f,0.25f, +0.507813f,0.242188f, +0.515625f,0.25f, +0.515625f,0.242188f, +0.523438f,0.25f, +0.523438f,0.242188f, +0.53125f,0.25f, +0.53125f,0.242188f, +0.539063f,0.25f, +0.539063f,0.242188f, +0.546875f,0.25f, +0.546875f,0.242188f, +0.554688f,0.25f, +0.554688f,0.242188f, +0.5625f,0.25f, +0.5625f,0.242188f, +0.570313f,0.25f, +0.570313f,0.242188f, +0.578125f,0.25f, +0.578125f,0.242188f, +0.585938f,0.25f, +0.585938f,0.242188f, +0.59375f,0.25f, +0.59375f,0.242188f, +0.601563f,0.25f, +0.601563f,0.242188f, +0.609375f,0.25f, +0.609375f,0.242188f, +0.617188f,0.25f, +0.617188f,0.242188f, +0.625f,0.25f, +0.625f,0.242188f, +0.632813f,0.25f, +0.632813f,0.242188f, +0.640625f,0.25f, +0.640625f,0.242188f, +0.648438f,0.25f, +0.648438f,0.242188f, +0.65625f,0.25f, +0.65625f,0.242188f, +0.664063f,0.25f, +0.664063f,0.242188f, +0.671875f,0.25f, +0.671875f,0.242188f, +0.679688f,0.25f, +0.679688f,0.242188f, +0.6875f,0.25f, +0.6875f,0.242188f, +0.695313f,0.25f, +0.695313f,0.242188f, +0.703125f,0.25f, +0.703125f,0.242188f, +0.710938f,0.25f, +0.710938f,0.242188f, +0.71875f,0.25f, +0.71875f,0.242188f, +0.726563f,0.25f, +0.726563f,0.242188f, +0.734375f,0.25f, +0.734375f,0.242188f, +0.742188f,0.25f, +0.742188f,0.242188f, +0.75f,0.25f, +0.75f,0.242188f, +0.757813f,0.25f, +0.757813f,0.242188f, +0.765625f,0.25f, +0.765625f,0.242188f, +0.773438f,0.25f, +0.773438f,0.242188f, +0.78125f,0.25f, +0.78125f,0.242188f, +0.789063f,0.25f, +0.789063f,0.242188f, +0.796875f,0.25f, +0.796875f,0.242188f, +0.804688f,0.25f, +0.804688f,0.242188f, +0.8125f,0.25f, +0.8125f,0.242188f, +0.820313f,0.25f, +0.820313f,0.242188f, +0.828125f,0.25f, +0.828125f,0.242188f, +0.835938f,0.25f, +0.835938f,0.242188f, +0.84375f,0.25f, +0.84375f,0.242188f, +0.851563f,0.25f, +0.851563f,0.242188f, +0.859375f,0.25f, +0.859375f,0.242188f, +0.867188f,0.25f, +0.867188f,0.242188f, +0.875f,0.25f, +0.875f,0.242188f, +0.882813f,0.25f, +0.882813f,0.242188f, +0.890625f,0.25f, +0.890625f,0.242188f, +0.898438f,0.25f, +0.898438f,0.242188f, +0.90625f,0.25f, +0.90625f,0.242188f, +0.914063f,0.25f, +0.914063f,0.242188f, +0.921875f,0.25f, +0.921875f,0.242188f, +0.929688f,0.25f, +0.929688f,0.242188f, +0.9375f,0.25f, +0.9375f,0.242188f, +0.945313f,0.25f, +0.945313f,0.242188f, +0.953125f,0.25f, +0.953125f,0.242188f, +0.960938f,0.25f, +0.960938f,0.242188f, +0.96875f,0.25f, +0.96875f,0.242188f, +0.976563f,0.25f, +0.976563f,0.242188f, +0.984375f,0.25f, +0.984375f,0.242188f, +0.992188f,0.25f, +0.992188f,0.242188f, +1.0f,0.25f, +1.0f,0.242188f, +0.507813f,0.257813f, +0.515625f,0.257813f, +0.523438f,0.257813f, +0.53125f,0.257813f, +0.539063f,0.257813f, +0.546875f,0.257813f, +0.554688f,0.257813f, +0.5625f,0.257813f, +0.570313f,0.257813f, +0.578125f,0.257813f, +0.585938f,0.257813f, +0.59375f,0.257813f, +0.601563f,0.257813f, +0.609375f,0.257813f, +0.617188f,0.257813f, +0.625f,0.257813f, +0.632813f,0.257813f, +0.640625f,0.257813f, +0.648438f,0.257813f, +0.65625f,0.257813f, +0.664063f,0.257813f, +0.671875f,0.257813f, +0.679688f,0.257813f, +0.6875f,0.257813f, +0.695313f,0.257813f, +0.703125f,0.257813f, +0.710938f,0.257813f, +0.71875f,0.257813f, +0.726563f,0.257813f, +0.734375f,0.257813f, +0.742188f,0.257813f, +0.75f,0.257813f, +0.757813f,0.257813f, +0.765625f,0.257813f, +0.773438f,0.257813f, +0.78125f,0.257813f, +0.789063f,0.257813f, +0.796875f,0.257813f, +0.804688f,0.257813f, +0.8125f,0.257813f, +0.820313f,0.257813f, +0.828125f,0.257813f, +0.835938f,0.257813f, +0.84375f,0.257813f, +0.851563f,0.257813f, +0.859375f,0.257813f, +0.867188f,0.257813f, +0.875f,0.257813f, +0.882813f,0.257813f, +0.890625f,0.257813f, +0.898438f,0.257813f, +0.90625f,0.257813f, +0.914063f,0.257813f, +0.921875f,0.257813f, +0.929688f,0.257813f, +0.9375f,0.257813f, +0.945313f,0.257813f, +0.953125f,0.257813f, +0.960938f,0.257813f, +0.96875f,0.257813f, +0.976563f,0.257813f, +0.984375f,0.257813f, +0.992188f,0.257813f, +1.0f,0.257813f, +0.507813f,0.265625f, +0.515625f,0.265625f, +0.523438f,0.265625f, +0.53125f,0.265625f, +0.539063f,0.265625f, +0.546875f,0.265625f, +0.554688f,0.265625f, +0.5625f,0.265625f, +0.570313f,0.265625f, +0.578125f,0.265625f, +0.585938f,0.265625f, +0.59375f,0.265625f, +0.601563f,0.265625f, +0.609375f,0.265625f, +0.617188f,0.265625f, +0.625f,0.265625f, +0.632813f,0.265625f, +0.640625f,0.265625f, +0.648438f,0.265625f, +0.65625f,0.265625f, +0.664063f,0.265625f, +0.671875f,0.265625f, +0.679688f,0.265625f, +0.6875f,0.265625f, +0.695313f,0.265625f, +0.703125f,0.265625f, +0.710938f,0.265625f, +0.71875f,0.265625f, +0.726563f,0.265625f, +0.734375f,0.265625f, +0.742188f,0.265625f, +0.75f,0.265625f, +0.757813f,0.265625f, +0.765625f,0.265625f, +0.773438f,0.265625f, +0.78125f,0.265625f, +0.789063f,0.265625f, +0.796875f,0.265625f, +0.804688f,0.265625f, +0.8125f,0.265625f, +0.820313f,0.265625f, +0.828125f,0.265625f, +0.835938f,0.265625f, +0.84375f,0.265625f, +0.851563f,0.265625f, +0.859375f,0.265625f, +0.867188f,0.265625f, +0.875f,0.265625f, +0.882813f,0.265625f, +0.890625f,0.265625f, +0.898438f,0.265625f, +0.90625f,0.265625f, +0.914063f,0.265625f, +0.921875f,0.265625f, +0.929688f,0.265625f, +0.9375f,0.265625f, +0.945313f,0.265625f, +0.953125f,0.265625f, +0.960938f,0.265625f, +0.96875f,0.265625f, +0.976563f,0.265625f, +0.984375f,0.265625f, +0.992188f,0.265625f, +1.0f,0.265625f, +0.507813f,0.273438f, +0.515625f,0.273438f, +0.523438f,0.273438f, +0.53125f,0.273438f, +0.539063f,0.273438f, +0.546875f,0.273438f, +0.554688f,0.273438f, +0.5625f,0.273438f, +0.570313f,0.273438f, +0.578125f,0.273438f, +0.585938f,0.273438f, +0.59375f,0.273438f, +0.601563f,0.273438f, +0.609375f,0.273438f, +0.617188f,0.273438f, +0.625f,0.273438f, +0.632813f,0.273438f, +0.640625f,0.273438f, +0.648438f,0.273438f, +0.65625f,0.273438f, +0.664063f,0.273438f, +0.671875f,0.273438f, +0.679688f,0.273438f, +0.6875f,0.273438f, +0.695313f,0.273438f, +0.703125f,0.273438f, +0.710938f,0.273438f, +0.71875f,0.273438f, +0.726563f,0.273438f, +0.734375f,0.273438f, +0.742188f,0.273438f, +0.75f,0.273438f, +0.757813f,0.273438f, +0.765625f,0.273438f, +0.773438f,0.273438f, +0.78125f,0.273438f, +0.789063f,0.273438f, +0.796875f,0.273438f, +0.804688f,0.273438f, +0.8125f,0.273438f, +0.820313f,0.273438f, +0.828125f,0.273438f, +0.835938f,0.273438f, +0.84375f,0.273438f, +0.851563f,0.273438f, +0.859375f,0.273438f, +0.867188f,0.273438f, +0.875f,0.273438f, +0.882813f,0.273438f, +0.890625f,0.273438f, +0.898438f,0.273438f, +0.90625f,0.273438f, +0.914063f,0.273438f, +0.921875f,0.273438f, +0.929688f,0.273438f, +0.9375f,0.273438f, +0.945313f,0.273438f, +0.953125f,0.273438f, +0.960938f,0.273438f, +0.96875f,0.273438f, +0.976563f,0.273438f, +0.984375f,0.273438f, +0.992188f,0.273438f, +1.0f,0.273438f, +0.507813f,0.28125f, +0.515625f,0.28125f, +0.523438f,0.28125f, +0.53125f,0.28125f, +0.539063f,0.28125f, +0.546875f,0.28125f, +0.554688f,0.28125f, +0.5625f,0.28125f, +0.570313f,0.28125f, +0.578125f,0.28125f, +0.585938f,0.28125f, +0.59375f,0.28125f, +0.601563f,0.28125f, +0.609375f,0.28125f, +0.617188f,0.28125f, +0.625f,0.28125f, +0.632813f,0.28125f, +0.640625f,0.28125f, +0.648438f,0.28125f, +0.65625f,0.28125f, +0.664063f,0.28125f, +0.671875f,0.28125f, +0.679688f,0.28125f, +0.6875f,0.28125f, +0.695313f,0.28125f, +0.703125f,0.28125f, +0.710938f,0.28125f, +0.71875f,0.28125f, +0.726563f,0.28125f, +0.734375f,0.28125f, +0.742188f,0.28125f, +0.75f,0.28125f, +0.757813f,0.28125f, +0.765625f,0.28125f, +0.773438f,0.28125f, +0.78125f,0.28125f, +0.789063f,0.28125f, +0.796875f,0.28125f, +0.804688f,0.28125f, +0.8125f,0.28125f, +0.820313f,0.28125f, +0.828125f,0.28125f, +0.835938f,0.28125f, +0.84375f,0.28125f, +0.851563f,0.28125f, +0.859375f,0.28125f, +0.867188f,0.28125f, +0.875f,0.28125f, +0.882813f,0.28125f, +0.890625f,0.28125f, +0.898438f,0.28125f, +0.90625f,0.28125f, +0.914063f,0.28125f, +0.921875f,0.28125f, +0.929688f,0.28125f, +0.9375f,0.28125f, +0.945313f,0.28125f, +0.953125f,0.28125f, +0.960938f,0.28125f, +0.96875f,0.28125f, +0.976563f,0.28125f, +0.984375f,0.28125f, +0.992188f,0.28125f, +1.0f,0.28125f, +0.507813f,0.289063f, +0.515625f,0.289063f, +0.523438f,0.289063f, +0.53125f,0.289063f, +0.539063f,0.289063f, +0.546875f,0.289063f, +0.554688f,0.289063f, +0.5625f,0.289063f, +0.570313f,0.289063f, +0.578125f,0.289063f, +0.585938f,0.289063f, +0.59375f,0.289063f, +0.601563f,0.289063f, +0.609375f,0.289063f, +0.617188f,0.289063f, +0.625f,0.289063f, +0.632813f,0.289063f, +0.640625f,0.289063f, +0.648438f,0.289063f, +0.65625f,0.289063f, +0.664063f,0.289063f, +0.671875f,0.289063f, +0.679688f,0.289063f, +0.6875f,0.289063f, +0.695313f,0.289063f, +0.703125f,0.289063f, +0.710938f,0.289063f, +0.71875f,0.289063f, +0.726563f,0.289063f, +0.734375f,0.289063f, +0.742188f,0.289063f, +0.75f,0.289063f, +0.757813f,0.289063f, +0.765625f,0.289063f, +0.773438f,0.289063f, +0.78125f,0.289063f, +0.789063f,0.289063f, +0.796875f,0.289063f, +0.804688f,0.289063f, +0.8125f,0.289063f, +0.820313f,0.289063f, +0.828125f,0.289063f, +0.835938f,0.289063f, +0.84375f,0.289063f, +0.851563f,0.289063f, +0.859375f,0.289063f, +0.867188f,0.289063f, +0.875f,0.289063f, +0.882813f,0.289063f, +0.890625f,0.289063f, +0.898438f,0.289063f, +0.90625f,0.289063f, +0.914063f,0.289063f, +0.921875f,0.289063f, +0.929688f,0.289063f, +0.9375f,0.289063f, +0.945313f,0.289063f, +0.953125f,0.289063f, +0.960938f,0.289063f, +0.96875f,0.289063f, +0.976563f,0.289063f, +0.984375f,0.289063f, +0.992188f,0.289063f, +1.0f,0.289063f, +0.507813f,0.296875f, +0.515625f,0.296875f, +0.523438f,0.296875f, +0.53125f,0.296875f, +0.539063f,0.296875f, +0.546875f,0.296875f, +0.554688f,0.296875f, +0.5625f,0.296875f, +0.570313f,0.296875f, +0.578125f,0.296875f, +0.585938f,0.296875f, +0.59375f,0.296875f, +0.601563f,0.296875f, +0.609375f,0.296875f, +0.617188f,0.296875f, +0.625f,0.296875f, +0.632813f,0.296875f, +0.640625f,0.296875f, +0.648438f,0.296875f, +0.65625f,0.296875f, +0.664063f,0.296875f, +0.671875f,0.296875f, +0.679688f,0.296875f, +0.6875f,0.296875f, +0.695313f,0.296875f, +0.703125f,0.296875f, +0.710938f,0.296875f, +0.71875f,0.296875f, +0.726563f,0.296875f, +0.734375f,0.296875f, +0.742188f,0.296875f, +0.75f,0.296875f, +0.757813f,0.296875f, +0.765625f,0.296875f, +0.773438f,0.296875f, +0.78125f,0.296875f, +0.789063f,0.296875f, +0.796875f,0.296875f, +0.804688f,0.296875f, +0.8125f,0.296875f, +0.820313f,0.296875f, +0.828125f,0.296875f, +0.835938f,0.296875f, +0.84375f,0.296875f, +0.851563f,0.296875f, +0.859375f,0.296875f, +0.867188f,0.296875f, +0.875f,0.296875f, +0.882813f,0.296875f, +0.890625f,0.296875f, +0.898438f,0.296875f, +0.90625f,0.296875f, +0.914063f,0.296875f, +0.921875f,0.296875f, +0.929688f,0.296875f, +0.9375f,0.296875f, +0.945313f,0.296875f, +0.953125f,0.296875f, +0.960938f,0.296875f, +0.96875f,0.296875f, +0.976563f,0.296875f, +0.984375f,0.296875f, +0.992188f,0.296875f, +1.0f,0.296875f, +0.507813f,0.304688f, +0.515625f,0.304688f, +0.523438f,0.304688f, +0.53125f,0.304688f, +0.539063f,0.304688f, +0.546875f,0.304688f, +0.554688f,0.304688f, +0.5625f,0.304688f, +0.570313f,0.304688f, +0.578125f,0.304688f, +0.585938f,0.304688f, +0.59375f,0.304688f, +0.601563f,0.304688f, +0.609375f,0.304688f, +0.617188f,0.304688f, +0.625f,0.304688f, +0.632813f,0.304688f, +0.640625f,0.304688f, +0.648438f,0.304688f, +0.65625f,0.304688f, +0.664063f,0.304688f, +0.671875f,0.304688f, +0.679688f,0.304688f, +0.6875f,0.304688f, +0.695313f,0.304688f, +0.703125f,0.304688f, +0.710938f,0.304688f, +0.71875f,0.304688f, +0.726563f,0.304688f, +0.734375f,0.304688f, +0.742188f,0.304688f, +0.75f,0.304688f, +0.757813f,0.304688f, +0.765625f,0.304688f, +0.773438f,0.304688f, +0.78125f,0.304688f, +0.789063f,0.304688f, +0.796875f,0.304688f, +0.804688f,0.304688f, +0.8125f,0.304688f, +0.820313f,0.304688f, +0.828125f,0.304688f, +0.835938f,0.304688f, +0.84375f,0.304688f, +0.851563f,0.304688f, +0.859375f,0.304688f, +0.867188f,0.304688f, +0.875f,0.304688f, +0.882813f,0.304688f, +0.890625f,0.304688f, +0.898438f,0.304688f, +0.90625f,0.304688f, +0.914063f,0.304688f, +0.921875f,0.304688f, +0.929688f,0.304688f, +0.9375f,0.304688f, +0.945313f,0.304688f, +0.953125f,0.304688f, +0.960938f,0.304688f, +0.96875f,0.304688f, +0.976563f,0.304688f, +0.984375f,0.304688f, +0.992188f,0.304688f, +1.0f,0.304688f, +0.507813f,0.3125f, +0.515625f,0.3125f, +0.523438f,0.3125f, +0.53125f,0.3125f, +0.539063f,0.3125f, +0.546875f,0.3125f, +0.554688f,0.3125f, +0.5625f,0.3125f, +0.570313f,0.3125f, +0.578125f,0.3125f, +0.585938f,0.3125f, +0.59375f,0.3125f, +0.601563f,0.3125f, +0.609375f,0.3125f, +0.617188f,0.3125f, +0.625f,0.3125f, +0.632813f,0.3125f, +0.640625f,0.3125f, +0.648438f,0.3125f, +0.65625f,0.3125f, +0.664063f,0.3125f, +0.671875f,0.3125f, +0.679688f,0.3125f, +0.6875f,0.3125f, +0.695313f,0.3125f, +0.703125f,0.3125f, +0.710938f,0.3125f, +0.71875f,0.3125f, +0.726563f,0.3125f, +0.734375f,0.3125f, +0.742188f,0.3125f, +0.75f,0.3125f, +0.757813f,0.3125f, +0.765625f,0.3125f, +0.773438f,0.3125f, +0.78125f,0.3125f, +0.789063f,0.3125f, +0.796875f,0.3125f, +0.804688f,0.3125f, +0.8125f,0.3125f, +0.820313f,0.3125f, +0.828125f,0.3125f, +0.835938f,0.3125f, +0.84375f,0.3125f, +0.851563f,0.3125f, +0.859375f,0.3125f, +0.867188f,0.3125f, +0.875f,0.3125f, +0.882813f,0.3125f, +0.890625f,0.3125f, +0.898438f,0.3125f, +0.90625f,0.3125f, +0.914063f,0.3125f, +0.921875f,0.3125f, +0.929688f,0.3125f, +0.9375f,0.3125f, +0.945313f,0.3125f, +0.953125f,0.3125f, +0.960938f,0.3125f, +0.96875f,0.3125f, +0.976563f,0.3125f, +0.984375f,0.3125f, +0.992188f,0.3125f, +1.0f,0.3125f, +0.507813f,0.320313f, +0.515625f,0.320313f, +0.523438f,0.320313f, +0.53125f,0.320313f, +0.539063f,0.320313f, +0.546875f,0.320313f, +0.554688f,0.320313f, +0.5625f,0.320313f, +0.570313f,0.320313f, +0.578125f,0.320313f, +0.585938f,0.320313f, +0.59375f,0.320313f, +0.601563f,0.320313f, +0.609375f,0.320313f, +0.617188f,0.320313f, +0.625f,0.320313f, +0.632813f,0.320313f, +0.640625f,0.320313f, +0.648438f,0.320313f, +0.65625f,0.320313f, +0.664063f,0.320313f, +0.671875f,0.320313f, +0.679688f,0.320313f, +0.6875f,0.320313f, +0.695313f,0.320313f, +0.703125f,0.320313f, +0.710938f,0.320313f, +0.71875f,0.320313f, +0.726563f,0.320313f, +0.734375f,0.320313f, +0.742188f,0.320313f, +0.75f,0.320313f, +0.757813f,0.320313f, +0.765625f,0.320313f, +0.773438f,0.320313f, +0.78125f,0.320313f, +0.789063f,0.320313f, +0.796875f,0.320313f, +0.804688f,0.320313f, +0.8125f,0.320313f, +0.820313f,0.320313f, +0.828125f,0.320313f, +0.835938f,0.320313f, +0.84375f,0.320313f, +0.851563f,0.320313f, +0.859375f,0.320313f, +0.867188f,0.320313f, +0.875f,0.320313f, +0.882813f,0.320313f, +0.890625f,0.320313f, +0.898438f,0.320313f, +0.90625f,0.320313f, +0.914063f,0.320313f, +0.921875f,0.320313f, +0.929688f,0.320313f, +0.9375f,0.320313f, +0.945313f,0.320313f, +0.953125f,0.320313f, +0.960938f,0.320313f, +0.96875f,0.320313f, +0.976563f,0.320313f, +0.984375f,0.320313f, +0.992188f,0.320313f, +1.0f,0.320313f, +0.507813f,0.328125f, +0.515625f,0.328125f, +0.523438f,0.328125f, +0.53125f,0.328125f, +0.539063f,0.328125f, +0.546875f,0.328125f, +0.554688f,0.328125f, +0.5625f,0.328125f, +0.570313f,0.328125f, +0.578125f,0.328125f, +0.585938f,0.328125f, +0.59375f,0.328125f, +0.601563f,0.328125f, +0.609375f,0.328125f, +0.617188f,0.328125f, +0.625f,0.328125f, +0.632813f,0.328125f, +0.640625f,0.328125f, +0.648438f,0.328125f, +0.65625f,0.328125f, +0.664063f,0.328125f, +0.671875f,0.328125f, +0.679688f,0.328125f, +0.6875f,0.328125f, +0.695313f,0.328125f, +0.703125f,0.328125f, +0.710938f,0.328125f, +0.71875f,0.328125f, +0.726563f,0.328125f, +0.734375f,0.328125f, +0.742188f,0.328125f, +0.75f,0.328125f, +0.757813f,0.328125f, +0.765625f,0.328125f, +0.773438f,0.328125f, +0.78125f,0.328125f, +0.789063f,0.328125f, +0.796875f,0.328125f, +0.804688f,0.328125f, +0.8125f,0.328125f, +0.820313f,0.328125f, +0.828125f,0.328125f, +0.835938f,0.328125f, +0.84375f,0.328125f, +0.851563f,0.328125f, +0.859375f,0.328125f, +0.867188f,0.328125f, +0.875f,0.328125f, +0.882813f,0.328125f, +0.890625f,0.328125f, +0.898438f,0.328125f, +0.90625f,0.328125f, +0.914063f,0.328125f, +0.921875f,0.328125f, +0.929688f,0.328125f, +0.9375f,0.328125f, +0.945313f,0.328125f, +0.953125f,0.328125f, +0.960938f,0.328125f, +0.96875f,0.328125f, +0.976563f,0.328125f, +0.984375f,0.328125f, +0.992188f,0.328125f, +1.0f,0.328125f, +0.507813f,0.335938f, +0.515625f,0.335938f, +0.523438f,0.335938f, +0.53125f,0.335938f, +0.539063f,0.335938f, +0.546875f,0.335938f, +0.554688f,0.335938f, +0.5625f,0.335938f, +0.570313f,0.335938f, +0.578125f,0.335938f, +0.585938f,0.335938f, +0.59375f,0.335938f, +0.601563f,0.335938f, +0.609375f,0.335938f, +0.617188f,0.335938f, +0.625f,0.335938f, +0.632813f,0.335938f, +0.640625f,0.335938f, +0.648438f,0.335938f, +0.65625f,0.335938f, +0.664063f,0.335938f, +0.671875f,0.335938f, +0.679688f,0.335938f, +0.6875f,0.335938f, +0.695313f,0.335938f, +0.703125f,0.335938f, +0.710938f,0.335938f, +0.71875f,0.335938f, +0.726563f,0.335938f, +0.734375f,0.335938f, +0.742188f,0.335938f, +0.75f,0.335938f, +0.757813f,0.335938f, +0.765625f,0.335938f, +0.773438f,0.335938f, +0.78125f,0.335938f, +0.789063f,0.335938f, +0.796875f,0.335938f, +0.804688f,0.335938f, +0.8125f,0.335938f, +0.820313f,0.335938f, +0.828125f,0.335938f, +0.835938f,0.335938f, +0.84375f,0.335938f, +0.851563f,0.335938f, +0.859375f,0.335938f, +0.867188f,0.335938f, +0.875f,0.335938f, +0.882813f,0.335938f, +0.890625f,0.335938f, +0.898438f,0.335938f, +0.90625f,0.335938f, +0.914063f,0.335938f, +0.921875f,0.335938f, +0.929688f,0.335938f, +0.9375f,0.335938f, +0.945313f,0.335938f, +0.953125f,0.335938f, +0.960938f,0.335938f, +0.96875f,0.335938f, +0.976563f,0.335938f, +0.984375f,0.335938f, +0.992188f,0.335938f, +1.0f,0.335938f, +0.507813f,0.34375f, +0.515625f,0.34375f, +0.523438f,0.34375f, +0.53125f,0.34375f, +0.539063f,0.34375f, +0.546875f,0.34375f, +0.554688f,0.34375f, +0.5625f,0.34375f, +0.570313f,0.34375f, +0.578125f,0.34375f, +0.585938f,0.34375f, +0.59375f,0.34375f, +0.601563f,0.34375f, +0.609375f,0.34375f, +0.617188f,0.34375f, +0.625f,0.34375f, +0.632813f,0.34375f, +0.640625f,0.34375f, +0.648438f,0.34375f, +0.65625f,0.34375f, +0.664063f,0.34375f, +0.671875f,0.34375f, +0.679688f,0.34375f, +0.6875f,0.34375f, +0.695313f,0.34375f, +0.703125f,0.34375f, +0.710938f,0.34375f, +0.71875f,0.34375f, +0.726563f,0.34375f, +0.734375f,0.34375f, +0.742188f,0.34375f, +0.75f,0.34375f, +0.757813f,0.34375f, +0.765625f,0.34375f, +0.773438f,0.34375f, +0.78125f,0.34375f, +0.789063f,0.34375f, +0.796875f,0.34375f, +0.804688f,0.34375f, +0.8125f,0.34375f, +0.820313f,0.34375f, +0.828125f,0.34375f, +0.835938f,0.34375f, +0.84375f,0.34375f, +0.851563f,0.34375f, +0.859375f,0.34375f, +0.867188f,0.34375f, +0.875f,0.34375f, +0.882813f,0.34375f, +0.890625f,0.34375f, +0.898438f,0.34375f, +0.90625f,0.34375f, +0.914063f,0.34375f, +0.921875f,0.34375f, +0.929688f,0.34375f, +0.9375f,0.34375f, +0.945313f,0.34375f, +0.953125f,0.34375f, +0.960938f,0.34375f, +0.96875f,0.34375f, +0.976563f,0.34375f, +0.984375f,0.34375f, +0.992188f,0.34375f, +1.0f,0.34375f, +0.507813f,0.351563f, +0.515625f,0.351563f, +0.523438f,0.351563f, +0.53125f,0.351563f, +0.539063f,0.351563f, +0.546875f,0.351563f, +0.554688f,0.351563f, +0.5625f,0.351563f, +0.570313f,0.351563f, +0.578125f,0.351563f, +0.585938f,0.351563f, +0.59375f,0.351563f, +0.601563f,0.351563f, +0.609375f,0.351563f, +0.617188f,0.351563f, +0.625f,0.351563f, +0.632813f,0.351563f, +0.640625f,0.351563f, +0.648438f,0.351563f, +0.65625f,0.351563f, +0.664063f,0.351563f, +0.671875f,0.351563f, +0.679688f,0.351563f, +0.6875f,0.351563f, +0.695313f,0.351563f, +0.703125f,0.351563f, +0.710938f,0.351563f, +0.71875f,0.351563f, +0.726563f,0.351563f, +0.734375f,0.351563f, +0.742188f,0.351563f, +0.75f,0.351563f, +0.757813f,0.351563f, +0.765625f,0.351563f, +0.773438f,0.351563f, +0.78125f,0.351563f, +0.789063f,0.351563f, +0.796875f,0.351563f, +0.804688f,0.351563f, +0.8125f,0.351563f, +0.820313f,0.351563f, +0.828125f,0.351563f, +0.835938f,0.351563f, +0.84375f,0.351563f, +0.851563f,0.351563f, +0.859375f,0.351563f, +0.867188f,0.351563f, +0.875f,0.351563f, +0.882813f,0.351563f, +0.890625f,0.351563f, +0.898438f,0.351563f, +0.90625f,0.351563f, +0.914063f,0.351563f, +0.921875f,0.351563f, +0.929688f,0.351563f, +0.9375f,0.351563f, +0.945313f,0.351563f, +0.953125f,0.351563f, +0.960938f,0.351563f, +0.96875f,0.351563f, +0.976563f,0.351563f, +0.984375f,0.351563f, +0.992188f,0.351563f, +1.0f,0.351563f, +0.507813f,0.359375f, +0.515625f,0.359375f, +0.523438f,0.359375f, +0.53125f,0.359375f, +0.539063f,0.359375f, +0.546875f,0.359375f, +0.554688f,0.359375f, +0.5625f,0.359375f, +0.570313f,0.359375f, +0.578125f,0.359375f, +0.585938f,0.359375f, +0.59375f,0.359375f, +0.601563f,0.359375f, +0.609375f,0.359375f, +0.617188f,0.359375f, +0.625f,0.359375f, +0.632813f,0.359375f, +0.640625f,0.359375f, +0.648438f,0.359375f, +0.65625f,0.359375f, +0.664063f,0.359375f, +0.671875f,0.359375f, +0.679688f,0.359375f, +0.6875f,0.359375f, +0.695313f,0.359375f, +0.703125f,0.359375f, +0.710938f,0.359375f, +0.71875f,0.359375f, +0.726563f,0.359375f, +0.734375f,0.359375f, +0.742188f,0.359375f, +0.75f,0.359375f, +0.757813f,0.359375f, +0.765625f,0.359375f, +0.773438f,0.359375f, +0.78125f,0.359375f, +0.789063f,0.359375f, +0.796875f,0.359375f, +0.804688f,0.359375f, +0.8125f,0.359375f, +0.820313f,0.359375f, +0.828125f,0.359375f, +0.835938f,0.359375f, +0.84375f,0.359375f, +0.851563f,0.359375f, +0.859375f,0.359375f, +0.867188f,0.359375f, +0.875f,0.359375f, +0.882813f,0.359375f, +0.890625f,0.359375f, +0.898438f,0.359375f, +0.90625f,0.359375f, +0.914063f,0.359375f, +0.921875f,0.359375f, +0.929688f,0.359375f, +0.9375f,0.359375f, +0.945313f,0.359375f, +0.953125f,0.359375f, +0.960938f,0.359375f, +0.96875f,0.359375f, +0.976563f,0.359375f, +0.984375f,0.359375f, +0.992188f,0.359375f, +1.0f,0.359375f, +0.507813f,0.367188f, +0.515625f,0.367188f, +0.523438f,0.367188f, +0.53125f,0.367188f, +0.539063f,0.367188f, +0.546875f,0.367188f, +0.554688f,0.367188f, +0.5625f,0.367188f, +0.570313f,0.367188f, +0.578125f,0.367188f, +0.585938f,0.367188f, +0.59375f,0.367188f, +0.601563f,0.367188f, +0.609375f,0.367188f, +0.617188f,0.367188f, +0.625f,0.367188f, +0.632813f,0.367188f, +0.640625f,0.367188f, +0.648438f,0.367188f, +0.65625f,0.367188f, +0.664063f,0.367188f, +0.671875f,0.367188f, +0.679688f,0.367188f, +0.6875f,0.367188f, +0.695313f,0.367188f, +0.703125f,0.367188f, +0.710938f,0.367188f, +0.71875f,0.367188f, +0.726563f,0.367188f, +0.734375f,0.367188f, +0.742188f,0.367188f, +0.75f,0.367188f, +0.757813f,0.367188f, +0.765625f,0.367188f, +0.773438f,0.367188f, +0.78125f,0.367188f, +0.789063f,0.367188f, +0.796875f,0.367188f, +0.804688f,0.367188f, +0.8125f,0.367188f, +0.820313f,0.367188f, +0.828125f,0.367188f, +0.835938f,0.367188f, +0.84375f,0.367188f, +0.851563f,0.367188f, +0.859375f,0.367188f, +0.867188f,0.367188f, +0.875f,0.367188f, +0.882813f,0.367188f, +0.890625f,0.367188f, +0.898438f,0.367188f, +0.90625f,0.367188f, +0.914063f,0.367188f, +0.921875f,0.367188f, +0.929688f,0.367188f, +0.9375f,0.367188f, +0.945313f,0.367188f, +0.953125f,0.367188f, +0.960938f,0.367188f, +0.96875f,0.367188f, +0.976563f,0.367188f, +0.984375f,0.367188f, +0.992188f,0.367188f, +1.0f,0.367188f, +0.507813f,0.375f, +0.515625f,0.375f, +0.523438f,0.375f, +0.53125f,0.375f, +0.539063f,0.375f, +0.546875f,0.375f, +0.554688f,0.375f, +0.5625f,0.375f, +0.570313f,0.375f, +0.578125f,0.375f, +0.585938f,0.375f, +0.59375f,0.375f, +0.601563f,0.375f, +0.609375f,0.375f, +0.617188f,0.375f, +0.625f,0.375f, +0.632813f,0.375f, +0.640625f,0.375f, +0.648438f,0.375f, +0.65625f,0.375f, +0.664063f,0.375f, +0.671875f,0.375f, +0.679688f,0.375f, +0.6875f,0.375f, +0.695313f,0.375f, +0.703125f,0.375f, +0.710938f,0.375f, +0.71875f,0.375f, +0.726563f,0.375f, +0.734375f,0.375f, +0.742188f,0.375f, +0.75f,0.375f, +0.757813f,0.375f, +0.765625f,0.375f, +0.773438f,0.375f, +0.78125f,0.375f, +0.789063f,0.375f, +0.796875f,0.375f, +0.804688f,0.375f, +0.8125f,0.375f, +0.820313f,0.375f, +0.828125f,0.375f, +0.835938f,0.375f, +0.84375f,0.375f, +0.851563f,0.375f, +0.859375f,0.375f, +0.867188f,0.375f, +0.875f,0.375f, +0.882813f,0.375f, +0.890625f,0.375f, +0.898438f,0.375f, +0.90625f,0.375f, +0.914063f,0.375f, +0.921875f,0.375f, +0.929688f,0.375f, +0.9375f,0.375f, +0.945313f,0.375f, +0.953125f,0.375f, +0.960938f,0.375f, +0.96875f,0.375f, +0.976563f,0.375f, +0.984375f,0.375f, +0.992188f,0.375f, +1.0f,0.375f, +0.507813f,0.382813f, +0.515625f,0.382813f, +0.523438f,0.382813f, +0.53125f,0.382813f, +0.539063f,0.382813f, +0.546875f,0.382813f, +0.554688f,0.382813f, +0.5625f,0.382813f, +0.570313f,0.382813f, +0.578125f,0.382813f, +0.585938f,0.382813f, +0.59375f,0.382813f, +0.601563f,0.382813f, +0.609375f,0.382813f, +0.617188f,0.382813f, +0.625f,0.382813f, +0.632813f,0.382813f, +0.640625f,0.382813f, +0.648438f,0.382813f, +0.65625f,0.382813f, +0.664063f,0.382813f, +0.671875f,0.382813f, +0.679688f,0.382813f, +0.6875f,0.382813f, +0.695313f,0.382813f, +0.703125f,0.382813f, +0.710938f,0.382813f, +0.71875f,0.382813f, +0.726563f,0.382813f, +0.734375f,0.382813f, +0.742188f,0.382813f, +0.75f,0.382813f, +0.757813f,0.382813f, +0.765625f,0.382813f, +0.773438f,0.382813f, +0.78125f,0.382813f, +0.789063f,0.382813f, +0.796875f,0.382813f, +0.804688f,0.382813f, +0.8125f,0.382813f, +0.820313f,0.382813f, +0.828125f,0.382813f, +0.835938f,0.382813f, +0.84375f,0.382813f, +0.851563f,0.382813f, +0.859375f,0.382813f, +0.867188f,0.382813f, +0.875f,0.382813f, +0.882813f,0.382813f, +0.890625f,0.382813f, +0.898438f,0.382813f, +0.90625f,0.382813f, +0.914063f,0.382813f, +0.921875f,0.382813f, +0.929688f,0.382813f, +0.9375f,0.382813f, +0.945313f,0.382813f, +0.953125f,0.382813f, +0.960938f,0.382813f, +0.96875f,0.382813f, +0.976563f,0.382813f, +0.984375f,0.382813f, +0.992188f,0.382813f, +1.0f,0.382813f, +0.507813f,0.390625f, +0.515625f,0.390625f, +0.523438f,0.390625f, +0.53125f,0.390625f, +0.539063f,0.390625f, +0.546875f,0.390625f, +0.554688f,0.390625f, +0.5625f,0.390625f, +0.570313f,0.390625f, +0.578125f,0.390625f, +0.585938f,0.390625f, +0.59375f,0.390625f, +0.601563f,0.390625f, +0.609375f,0.390625f, +0.617188f,0.390625f, +0.625f,0.390625f, +0.632813f,0.390625f, +0.640625f,0.390625f, +0.648438f,0.390625f, +0.65625f,0.390625f, +0.664063f,0.390625f, +0.671875f,0.390625f, +0.679688f,0.390625f, +0.6875f,0.390625f, +0.695313f,0.390625f, +0.703125f,0.390625f, +0.710938f,0.390625f, +0.71875f,0.390625f, +0.726563f,0.390625f, +0.734375f,0.390625f, +0.742188f,0.390625f, +0.75f,0.390625f, +0.757813f,0.390625f, +0.765625f,0.390625f, +0.773438f,0.390625f, +0.78125f,0.390625f, +0.789063f,0.390625f, +0.796875f,0.390625f, +0.804688f,0.390625f, +0.8125f,0.390625f, +0.820313f,0.390625f, +0.828125f,0.390625f, +0.835938f,0.390625f, +0.84375f,0.390625f, +0.851563f,0.390625f, +0.859375f,0.390625f, +0.867188f,0.390625f, +0.875f,0.390625f, +0.882813f,0.390625f, +0.890625f,0.390625f, +0.898438f,0.390625f, +0.90625f,0.390625f, +0.914063f,0.390625f, +0.921875f,0.390625f, +0.929688f,0.390625f, +0.9375f,0.390625f, +0.945313f,0.390625f, +0.953125f,0.390625f, +0.960938f,0.390625f, +0.96875f,0.390625f, +0.976563f,0.390625f, +0.984375f,0.390625f, +0.992188f,0.390625f, +1.0f,0.390625f, +0.507813f,0.398438f, +0.515625f,0.398438f, +0.523438f,0.398438f, +0.53125f,0.398438f, +0.539063f,0.398438f, +0.546875f,0.398438f, +0.554688f,0.398438f, +0.5625f,0.398438f, +0.570313f,0.398438f, +0.578125f,0.398438f, +0.585938f,0.398438f, +0.59375f,0.398438f, +0.601563f,0.398438f, +0.609375f,0.398438f, +0.617188f,0.398438f, +0.625f,0.398438f, +0.632813f,0.398438f, +0.640625f,0.398438f, +0.648438f,0.398438f, +0.65625f,0.398438f, +0.664063f,0.398438f, +0.671875f,0.398438f, +0.679688f,0.398438f, +0.6875f,0.398438f, +0.695313f,0.398438f, +0.703125f,0.398438f, +0.710938f,0.398438f, +0.71875f,0.398438f, +0.726563f,0.398438f, +0.734375f,0.398438f, +0.742188f,0.398438f, +0.75f,0.398438f, +0.757813f,0.398438f, +0.765625f,0.398438f, +0.773438f,0.398438f, +0.78125f,0.398438f, +0.789063f,0.398438f, +0.796875f,0.398438f, +0.804688f,0.398438f, +0.8125f,0.398438f, +0.820313f,0.398438f, +0.828125f,0.398438f, +0.835938f,0.398438f, +0.84375f,0.398438f, +0.851563f,0.398438f, +0.859375f,0.398438f, +0.867188f,0.398438f, +0.875f,0.398438f, +0.882813f,0.398438f, +0.890625f,0.398438f, +0.898438f,0.398438f, +0.90625f,0.398438f, +0.914063f,0.398438f, +0.921875f,0.398438f, +0.929688f,0.398438f, +0.9375f,0.398438f, +0.945313f,0.398438f, +0.953125f,0.398438f, +0.960938f,0.398438f, +0.96875f,0.398438f, +0.976563f,0.398438f, +0.984375f,0.398438f, +0.992188f,0.398438f, +1.0f,0.398438f, +0.507813f,0.40625f, +0.515625f,0.40625f, +0.523438f,0.40625f, +0.53125f,0.40625f, +0.539063f,0.40625f, +0.546875f,0.40625f, +0.554688f,0.40625f, +0.5625f,0.40625f, +0.570313f,0.40625f, +0.578125f,0.40625f, +0.585938f,0.40625f, +0.59375f,0.40625f, +0.601563f,0.40625f, +0.609375f,0.40625f, +0.617188f,0.40625f, +0.625f,0.40625f, +0.632813f,0.40625f, +0.640625f,0.40625f, +0.648438f,0.40625f, +0.65625f,0.40625f, +0.664063f,0.40625f, +0.671875f,0.40625f, +0.679688f,0.40625f, +0.6875f,0.40625f, +0.695313f,0.40625f, +0.703125f,0.40625f, +0.710938f,0.40625f, +0.71875f,0.40625f, +0.726563f,0.40625f, +0.734375f,0.40625f, +0.742188f,0.40625f, +0.75f,0.40625f, +0.757813f,0.40625f, +0.765625f,0.40625f, +0.773438f,0.40625f, +0.78125f,0.40625f, +0.789063f,0.40625f, +0.796875f,0.40625f, +0.804688f,0.40625f, +0.8125f,0.40625f, +0.820313f,0.40625f, +0.828125f,0.40625f, +0.835938f,0.40625f, +0.84375f,0.40625f, +0.851563f,0.40625f, +0.859375f,0.40625f, +0.867188f,0.40625f, +0.875f,0.40625f, +0.882813f,0.40625f, +0.890625f,0.40625f, +0.898438f,0.40625f, +0.90625f,0.40625f, +0.914063f,0.40625f, +0.921875f,0.40625f, +0.929688f,0.40625f, +0.9375f,0.40625f, +0.945313f,0.40625f, +0.953125f,0.40625f, +0.960938f,0.40625f, +0.96875f,0.40625f, +0.976563f,0.40625f, +0.984375f,0.40625f, +0.992188f,0.40625f, +1.0f,0.40625f, +0.507813f,0.414063f, +0.515625f,0.414063f, +0.523438f,0.414063f, +0.53125f,0.414063f, +0.539063f,0.414063f, +0.546875f,0.414063f, +0.554688f,0.414063f, +0.5625f,0.414063f, +0.570313f,0.414063f, +0.578125f,0.414063f, +0.585938f,0.414063f, +0.59375f,0.414063f, +0.601563f,0.414063f, +0.609375f,0.414063f, +0.617188f,0.414063f, +0.625f,0.414063f, +0.632813f,0.414063f, +0.640625f,0.414063f, +0.648438f,0.414063f, +0.65625f,0.414063f, +0.664063f,0.414063f, +0.671875f,0.414063f, +0.679688f,0.414063f, +0.6875f,0.414063f, +0.695313f,0.414063f, +0.703125f,0.414063f, +0.710938f,0.414063f, +0.71875f,0.414063f, +0.726563f,0.414063f, +0.734375f,0.414063f, +0.742188f,0.414063f, +0.75f,0.414063f, +0.757813f,0.414063f, +0.765625f,0.414063f, +0.773438f,0.414063f, +0.78125f,0.414063f, +0.789063f,0.414063f, +0.796875f,0.414063f, +0.804688f,0.414063f, +0.8125f,0.414063f, +0.820313f,0.414063f, +0.828125f,0.414063f, +0.835938f,0.414063f, +0.84375f,0.414063f, +0.851563f,0.414063f, +0.859375f,0.414063f, +0.867188f,0.414063f, +0.875f,0.414063f, +0.882813f,0.414063f, +0.890625f,0.414063f, +0.898438f,0.414063f, +0.90625f,0.414063f, +0.914063f,0.414063f, +0.921875f,0.414063f, +0.929688f,0.414063f, +0.9375f,0.414063f, +0.945313f,0.414063f, +0.953125f,0.414063f, +0.960938f,0.414063f, +0.96875f,0.414063f, +0.976563f,0.414063f, +0.984375f,0.414063f, +0.992188f,0.414063f, +1.0f,0.414063f, +0.507813f,0.421875f, +0.515625f,0.421875f, +0.523438f,0.421875f, +0.53125f,0.421875f, +0.539063f,0.421875f, +0.546875f,0.421875f, +0.554688f,0.421875f, +0.5625f,0.421875f, +0.570313f,0.421875f, +0.578125f,0.421875f, +0.585938f,0.421875f, +0.59375f,0.421875f, +0.601563f,0.421875f, +0.609375f,0.421875f, +0.617188f,0.421875f, +0.625f,0.421875f, +0.632813f,0.421875f, +0.640625f,0.421875f, +0.648438f,0.421875f, +0.65625f,0.421875f, +0.664063f,0.421875f, +0.671875f,0.421875f, +0.679688f,0.421875f, +0.6875f,0.421875f, +0.695313f,0.421875f, +0.703125f,0.421875f, +0.710938f,0.421875f, +0.71875f,0.421875f, +0.726563f,0.421875f, +0.734375f,0.421875f, +0.742188f,0.421875f, +0.75f,0.421875f, +0.757813f,0.421875f, +0.765625f,0.421875f, +0.773438f,0.421875f, +0.78125f,0.421875f, +0.789063f,0.421875f, +0.796875f,0.421875f, +0.804688f,0.421875f, +0.8125f,0.421875f, +0.820313f,0.421875f, +0.828125f,0.421875f, +0.835938f,0.421875f, +0.84375f,0.421875f, +0.851563f,0.421875f, +0.859375f,0.421875f, +0.867188f,0.421875f, +0.875f,0.421875f, +0.882813f,0.421875f, +0.890625f,0.421875f, +0.898438f,0.421875f, +0.90625f,0.421875f, +0.914063f,0.421875f, +0.921875f,0.421875f, +0.929688f,0.421875f, +0.9375f,0.421875f, +0.945313f,0.421875f, +0.953125f,0.421875f, +0.960938f,0.421875f, +0.96875f,0.421875f, +0.976563f,0.421875f, +0.984375f,0.421875f, +0.992188f,0.421875f, +1.0f,0.421875f, +0.507813f,0.429688f, +0.515625f,0.429688f, +0.523438f,0.429688f, +0.53125f,0.429688f, +0.539063f,0.429688f, +0.546875f,0.429688f, +0.554688f,0.429688f, +0.5625f,0.429688f, +0.570313f,0.429688f, +0.578125f,0.429688f, +0.585938f,0.429688f, +0.59375f,0.429688f, +0.601563f,0.429688f, +0.609375f,0.429688f, +0.617188f,0.429688f, +0.625f,0.429688f, +0.632813f,0.429688f, +0.640625f,0.429688f, +0.648438f,0.429688f, +0.65625f,0.429688f, +0.664063f,0.429688f, +0.671875f,0.429688f, +0.679688f,0.429688f, +0.6875f,0.429688f, +0.695313f,0.429688f, +0.703125f,0.429688f, +0.710938f,0.429688f, +0.71875f,0.429688f, +0.726563f,0.429688f, +0.734375f,0.429688f, +0.742188f,0.429688f, +0.75f,0.429688f, +0.757813f,0.429688f, +0.765625f,0.429688f, +0.773438f,0.429688f, +0.78125f,0.429688f, +0.789063f,0.429688f, +0.796875f,0.429688f, +0.804688f,0.429688f, +0.8125f,0.429688f, +0.820313f,0.429688f, +0.828125f,0.429688f, +0.835938f,0.429688f, +0.84375f,0.429688f, +0.851563f,0.429688f, +0.859375f,0.429688f, +0.867188f,0.429688f, +0.875f,0.429688f, +0.882813f,0.429688f, +0.890625f,0.429688f, +0.898438f,0.429688f, +0.90625f,0.429688f, +0.914063f,0.429688f, +0.921875f,0.429688f, +0.929688f,0.429688f, +0.9375f,0.429688f, +0.945313f,0.429688f, +0.953125f,0.429688f, +0.960938f,0.429688f, +0.96875f,0.429688f, +0.976563f,0.429688f, +0.984375f,0.429688f, +0.992188f,0.429688f, +1.0f,0.429688f, +0.507813f,0.4375f, +0.515625f,0.4375f, +0.523438f,0.4375f, +0.53125f,0.4375f, +0.539063f,0.4375f, +0.546875f,0.4375f, +0.554688f,0.4375f, +0.5625f,0.4375f, +0.570313f,0.4375f, +0.578125f,0.4375f, +0.585938f,0.4375f, +0.59375f,0.4375f, +0.601563f,0.4375f, +0.609375f,0.4375f, +0.617188f,0.4375f, +0.625f,0.4375f, +0.632813f,0.4375f, +0.640625f,0.4375f, +0.648438f,0.4375f, +0.65625f,0.4375f, +0.664063f,0.4375f, +0.671875f,0.4375f, +0.679688f,0.4375f, +0.6875f,0.4375f, +0.695313f,0.4375f, +0.703125f,0.4375f, +0.710938f,0.4375f, +0.71875f,0.4375f, +0.726563f,0.4375f, +0.734375f,0.4375f, +0.742188f,0.4375f, +0.75f,0.4375f, +0.757813f,0.4375f, +0.765625f,0.4375f, +0.773438f,0.4375f, +0.78125f,0.4375f, +0.789063f,0.4375f, +0.796875f,0.4375f, +0.804688f,0.4375f, +0.8125f,0.4375f, +0.820313f,0.4375f, +0.828125f,0.4375f, +0.835938f,0.4375f, +0.84375f,0.4375f, +0.851563f,0.4375f, +0.859375f,0.4375f, +0.867188f,0.4375f, +0.875f,0.4375f, +0.882813f,0.4375f, +0.890625f,0.4375f, +0.898438f,0.4375f, +0.90625f,0.4375f, +0.914063f,0.4375f, +0.921875f,0.4375f, +0.929688f,0.4375f, +0.9375f,0.4375f, +0.945313f,0.4375f, +0.953125f,0.4375f, +0.960938f,0.4375f, +0.96875f,0.4375f, +0.976563f,0.4375f, +0.984375f,0.4375f, +0.992188f,0.4375f, +1.0f,0.4375f, +0.507813f,0.445313f, +0.515625f,0.445313f, +0.523438f,0.445313f, +0.53125f,0.445313f, +0.539063f,0.445313f, +0.546875f,0.445313f, +0.554688f,0.445313f, +0.5625f,0.445313f, +0.570313f,0.445313f, +0.578125f,0.445313f, +0.585938f,0.445313f, +0.59375f,0.445313f, +0.601563f,0.445313f, +0.609375f,0.445313f, +0.617188f,0.445313f, +0.625f,0.445313f, +0.632813f,0.445313f, +0.640625f,0.445313f, +0.648438f,0.445313f, +0.65625f,0.445313f, +0.664063f,0.445313f, +0.671875f,0.445313f, +0.679688f,0.445313f, +0.6875f,0.445313f, +0.695313f,0.445313f, +0.703125f,0.445313f, +0.710938f,0.445313f, +0.71875f,0.445313f, +0.726563f,0.445313f, +0.734375f,0.445313f, +0.742188f,0.445313f, +0.75f,0.445313f, +0.757813f,0.445313f, +0.765625f,0.445313f, +0.773438f,0.445313f, +0.78125f,0.445313f, +0.789063f,0.445313f, +0.796875f,0.445313f, +0.804688f,0.445313f, +0.8125f,0.445313f, +0.820313f,0.445313f, +0.828125f,0.445313f, +0.835938f,0.445313f, +0.84375f,0.445313f, +0.851563f,0.445313f, +0.859375f,0.445313f, +0.867188f,0.445313f, +0.875f,0.445313f, +0.882813f,0.445313f, +0.890625f,0.445313f, +0.898438f,0.445313f, +0.90625f,0.445313f, +0.914063f,0.445313f, +0.921875f,0.445313f, +0.929688f,0.445313f, +0.9375f,0.445313f, +0.945313f,0.445313f, +0.953125f,0.445313f, +0.960938f,0.445313f, +0.96875f,0.445313f, +0.976563f,0.445313f, +0.984375f,0.445313f, +0.992188f,0.445313f, +1.0f,0.445313f, +0.507813f,0.453125f, +0.515625f,0.453125f, +0.523438f,0.453125f, +0.53125f,0.453125f, +0.539063f,0.453125f, +0.546875f,0.453125f, +0.554688f,0.453125f, +0.5625f,0.453125f, +0.570313f,0.453125f, +0.578125f,0.453125f, +0.585938f,0.453125f, +0.59375f,0.453125f, +0.601563f,0.453125f, +0.609375f,0.453125f, +0.617188f,0.453125f, +0.625f,0.453125f, +0.632813f,0.453125f, +0.640625f,0.453125f, +0.648438f,0.453125f, +0.65625f,0.453125f, +0.664063f,0.453125f, +0.671875f,0.453125f, +0.679688f,0.453125f, +0.6875f,0.453125f, +0.695313f,0.453125f, +0.703125f,0.453125f, +0.710938f,0.453125f, +0.71875f,0.453125f, +0.726563f,0.453125f, +0.734375f,0.453125f, +0.742188f,0.453125f, +0.75f,0.453125f, +0.757813f,0.453125f, +0.765625f,0.453125f, +0.773438f,0.453125f, +0.78125f,0.453125f, +0.789063f,0.453125f, +0.796875f,0.453125f, +0.804688f,0.453125f, +0.8125f,0.453125f, +0.820313f,0.453125f, +0.828125f,0.453125f, +0.835938f,0.453125f, +0.84375f,0.453125f, +0.851563f,0.453125f, +0.859375f,0.453125f, +0.867188f,0.453125f, +0.875f,0.453125f, +0.882813f,0.453125f, +0.890625f,0.453125f, +0.898438f,0.453125f, +0.90625f,0.453125f, +0.914063f,0.453125f, +0.921875f,0.453125f, +0.929688f,0.453125f, +0.9375f,0.453125f, +0.945313f,0.453125f, +0.953125f,0.453125f, +0.960938f,0.453125f, +0.96875f,0.453125f, +0.976563f,0.453125f, +0.984375f,0.453125f, +0.992188f,0.453125f, +1.0f,0.453125f, +0.507813f,0.460938f, +0.515625f,0.460938f, +0.523438f,0.460938f, +0.53125f,0.460938f, +0.539063f,0.460938f, +0.546875f,0.460938f, +0.554688f,0.460938f, +0.5625f,0.460938f, +0.570313f,0.460938f, +0.578125f,0.460938f, +0.585938f,0.460938f, +0.59375f,0.460938f, +0.601563f,0.460938f, +0.609375f,0.460938f, +0.617188f,0.460938f, +0.625f,0.460938f, +0.632813f,0.460938f, +0.640625f,0.460938f, +0.648438f,0.460938f, +0.65625f,0.460938f, +0.664063f,0.460938f, +0.671875f,0.460938f, +0.679688f,0.460938f, +0.6875f,0.460938f, +0.695313f,0.460938f, +0.703125f,0.460938f, +0.710938f,0.460938f, +0.71875f,0.460938f, +0.726563f,0.460938f, +0.734375f,0.460938f, +0.742188f,0.460938f, +0.75f,0.460938f, +0.757813f,0.460938f, +0.765625f,0.460938f, +0.773438f,0.460938f, +0.78125f,0.460938f, +0.789063f,0.460938f, +0.796875f,0.460938f, +0.804688f,0.460938f, +0.8125f,0.460938f, +0.820313f,0.460938f, +0.828125f,0.460938f, +0.835938f,0.460938f, +0.84375f,0.460938f, +0.851563f,0.460938f, +0.859375f,0.460938f, +0.867188f,0.460938f, +0.875f,0.460938f, +0.882813f,0.460938f, +0.890625f,0.460938f, +0.898438f,0.460938f, +0.90625f,0.460938f, +0.914063f,0.460938f, +0.921875f,0.460938f, +0.929688f,0.460938f, +0.9375f,0.460938f, +0.945313f,0.460938f, +0.953125f,0.460938f, +0.960938f,0.460938f, +0.96875f,0.460938f, +0.976563f,0.460938f, +0.984375f,0.460938f, +0.992188f,0.460938f, +1.0f,0.460938f, +0.507813f,0.46875f, +0.515625f,0.46875f, +0.523438f,0.46875f, +0.53125f,0.46875f, +0.539063f,0.46875f, +0.546875f,0.46875f, +0.554688f,0.46875f, +0.5625f,0.46875f, +0.570313f,0.46875f, +0.578125f,0.46875f, +0.585938f,0.46875f, +0.59375f,0.46875f, +0.601563f,0.46875f, +0.609375f,0.46875f, +0.617188f,0.46875f, +0.625f,0.46875f, +0.632813f,0.46875f, +0.640625f,0.46875f, +0.648438f,0.46875f, +0.65625f,0.46875f, +0.664063f,0.46875f, +0.671875f,0.46875f, +0.679688f,0.46875f, +0.6875f,0.46875f, +0.695313f,0.46875f, +0.703125f,0.46875f, +0.710938f,0.46875f, +0.71875f,0.46875f, +0.726563f,0.46875f, +0.734375f,0.46875f, +0.742188f,0.46875f, +0.75f,0.46875f, +0.757813f,0.46875f, +0.765625f,0.46875f, +0.773438f,0.46875f, +0.78125f,0.46875f, +0.789063f,0.46875f, +0.796875f,0.46875f, +0.804688f,0.46875f, +0.8125f,0.46875f, +0.820313f,0.46875f, +0.828125f,0.46875f, +0.835938f,0.46875f, +0.84375f,0.46875f, +0.851563f,0.46875f, +0.859375f,0.46875f, +0.867188f,0.46875f, +0.875f,0.46875f, +0.882813f,0.46875f, +0.890625f,0.46875f, +0.898438f,0.46875f, +0.90625f,0.46875f, +0.914063f,0.46875f, +0.921875f,0.46875f, +0.929688f,0.46875f, +0.9375f,0.46875f, +0.945313f,0.46875f, +0.953125f,0.46875f, +0.960938f,0.46875f, +0.96875f,0.46875f, +0.976563f,0.46875f, +0.984375f,0.46875f, +0.992188f,0.46875f, +1.0f,0.46875f, +0.507813f,0.476563f, +0.515625f,0.476563f, +0.523438f,0.476563f, +0.53125f,0.476563f, +0.539063f,0.476563f, +0.546875f,0.476563f, +0.554688f,0.476563f, +0.5625f,0.476563f, +0.570313f,0.476563f, +0.578125f,0.476563f, +0.585938f,0.476563f, +0.59375f,0.476563f, +0.601563f,0.476563f, +0.609375f,0.476563f, +0.617188f,0.476563f, +0.625f,0.476563f, +0.632813f,0.476563f, +0.640625f,0.476563f, +0.648438f,0.476563f, +0.65625f,0.476563f, +0.664063f,0.476563f, +0.671875f,0.476563f, +0.679688f,0.476563f, +0.6875f,0.476563f, +0.695313f,0.476563f, +0.703125f,0.476563f, +0.710938f,0.476563f, +0.71875f,0.476563f, +0.726563f,0.476563f, +0.734375f,0.476563f, +0.742188f,0.476563f, +0.75f,0.476563f, +0.757813f,0.476563f, +0.765625f,0.476563f, +0.773438f,0.476563f, +0.78125f,0.476563f, +0.789063f,0.476563f, +0.796875f,0.476563f, +0.804688f,0.476563f, +0.8125f,0.476563f, +0.820313f,0.476563f, +0.828125f,0.476563f, +0.835938f,0.476563f, +0.84375f,0.476563f, +0.851563f,0.476563f, +0.859375f,0.476563f, +0.867188f,0.476563f, +0.875f,0.476563f, +0.882813f,0.476563f, +0.890625f,0.476563f, +0.898438f,0.476563f, +0.90625f,0.476563f, +0.914063f,0.476563f, +0.921875f,0.476563f, +0.929688f,0.476563f, +0.9375f,0.476563f, +0.945313f,0.476563f, +0.953125f,0.476563f, +0.960938f,0.476563f, +0.96875f,0.476563f, +0.976563f,0.476563f, +0.984375f,0.476563f, +0.992188f,0.476563f, +1.0f,0.476563f, +0.507813f,0.484375f, +0.515625f,0.484375f, +0.523438f,0.484375f, +0.53125f,0.484375f, +0.539063f,0.484375f, +0.546875f,0.484375f, +0.554688f,0.484375f, +0.5625f,0.484375f, +0.570313f,0.484375f, +0.578125f,0.484375f, +0.585938f,0.484375f, +0.59375f,0.484375f, +0.601563f,0.484375f, +0.609375f,0.484375f, +0.617188f,0.484375f, +0.625f,0.484375f, +0.632813f,0.484375f, +0.640625f,0.484375f, +0.648438f,0.484375f, +0.65625f,0.484375f, +0.664063f,0.484375f, +0.671875f,0.484375f, +0.679688f,0.484375f, +0.6875f,0.484375f, +0.695313f,0.484375f, +0.703125f,0.484375f, +0.710938f,0.484375f, +0.71875f,0.484375f, +0.726563f,0.484375f, +0.734375f,0.484375f, +0.742188f,0.484375f, +0.75f,0.484375f, +0.757813f,0.484375f, +0.765625f,0.484375f, +0.773438f,0.484375f, +0.78125f,0.484375f, +0.789063f,0.484375f, +0.796875f,0.484375f, +0.804688f,0.484375f, +0.8125f,0.484375f, +0.820313f,0.484375f, +0.828125f,0.484375f, +0.835938f,0.484375f, +0.84375f,0.484375f, +0.851563f,0.484375f, +0.859375f,0.484375f, +0.867188f,0.484375f, +0.875f,0.484375f, +0.882813f,0.484375f, +0.890625f,0.484375f, +0.898438f,0.484375f, +0.90625f,0.484375f, +0.914063f,0.484375f, +0.921875f,0.484375f, +0.929688f,0.484375f, +0.9375f,0.484375f, +0.945313f,0.484375f, +0.953125f,0.484375f, +0.960938f,0.484375f, +0.96875f,0.484375f, +0.976563f,0.484375f, +0.984375f,0.484375f, +0.992188f,0.484375f, +1.0f,0.484375f, +0.507813f,0.492188f, +0.515625f,0.492188f, +0.523438f,0.492188f, +0.53125f,0.492188f, +0.539063f,0.492188f, +0.546875f,0.492188f, +0.554688f,0.492188f, +0.5625f,0.492188f, +0.570313f,0.492188f, +0.578125f,0.492188f, +0.585938f,0.492188f, +0.59375f,0.492188f, +0.601563f,0.492188f, +0.609375f,0.492188f, +0.617188f,0.492188f, +0.625f,0.492188f, +0.632813f,0.492188f, +0.640625f,0.492188f, +0.648438f,0.492188f, +0.65625f,0.492188f, +0.664063f,0.492188f, +0.671875f,0.492188f, +0.679688f,0.492188f, +0.6875f,0.492188f, +0.695313f,0.492188f, +0.703125f,0.492188f, +0.710938f,0.492188f, +0.71875f,0.492188f, +0.726563f,0.492188f, +0.734375f,0.492188f, +0.742188f,0.492188f, +0.75f,0.492188f, +0.757813f,0.492188f, +0.765625f,0.492188f, +0.773438f,0.492188f, +0.78125f,0.492188f, +0.789063f,0.492188f, +0.796875f,0.492188f, +0.804688f,0.492188f, +0.8125f,0.492188f, +0.820313f,0.492188f, +0.828125f,0.492188f, +0.835938f,0.492188f, +0.84375f,0.492188f, +0.851563f,0.492188f, +0.859375f,0.492188f, +0.867188f,0.492188f, +0.875f,0.492188f, +0.882813f,0.492188f, +0.890625f,0.492188f, +0.898438f,0.492188f, +0.90625f,0.492188f, +0.914063f,0.492188f, +0.921875f,0.492188f, +0.929688f,0.492188f, +0.9375f,0.492188f, +0.945313f,0.492188f, +0.953125f,0.492188f, +0.960938f,0.492188f, +0.96875f,0.492188f, +0.976563f,0.492188f, +0.984375f,0.492188f, +0.992188f,0.492188f, +1.0f,0.492188f, +}; + +unsigned short Landscape04Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +128,0,129, +2,129,0, +129,2,130, +4,130,2, +130,4,131, +6,131,4, +131,6,132, +8,132,6, +132,8,133, +10,133,8, +133,10,134, +12,134,10, +134,12,135, +14,135,12, +135,14,136, +16,136,14, +136,16,137, +18,137,16, +137,18,138, +20,138,18, +138,20,139, +22,139,20, +139,22,140, +24,140,22, +140,24,141, +26,141,24, +141,26,142, +28,142,26, +142,28,143, +30,143,28, +143,30,144, +32,144,30, +144,32,145, +34,145,32, +145,34,146, +36,146,34, +146,36,147, +38,147,36, +147,38,148, +40,148,38, +148,40,149, +42,149,40, +149,42,150, +44,150,42, +150,44,151, +46,151,44, +151,46,152, +48,152,46, +152,48,153, +50,153,48, +153,50,154, +52,154,50, +154,52,155, +54,155,52, +155,54,156, +56,156,54, +156,56,157, +58,157,56, +157,58,158, +60,158,58, +158,60,159, +62,159,60, +159,62,160, +64,160,62, +160,64,161, +66,161,64, +161,66,162, +68,162,66, +162,68,163, +70,163,68, +163,70,164, +72,164,70, +164,72,165, +74,165,72, +165,74,166, +76,166,74, +166,76,167, +78,167,76, +167,78,168, +80,168,78, +168,80,169, +82,169,80, +169,82,170, +84,170,82, +170,84,171, +86,171,84, +171,86,172, +88,172,86, +172,88,173, +90,173,88, +173,90,174, +92,174,90, +174,92,175, +94,175,92, +175,94,176, +96,176,94, +176,96,177, +98,177,96, +177,98,178, +100,178,98, +178,100,179, +102,179,100, +179,102,180, +104,180,102, +180,104,181, +106,181,104, +181,106,182, +108,182,106, +182,108,183, +110,183,108, +183,110,184, +112,184,110, +184,112,185, +114,185,112, +185,114,186, +116,186,114, +186,116,187, +118,187,116, +187,118,188, +120,188,118, +188,120,189, +122,189,120, +189,122,190, +124,190,122, +190,124,191, +126,191,124, +192,128,193, +129,193,128, +193,129,194, +130,194,129, +194,130,195, +131,195,130, +195,131,196, +132,196,131, +196,132,197, +133,197,132, +197,133,198, +134,198,133, +198,134,199, +135,199,134, +199,135,200, +136,200,135, +200,136,201, +137,201,136, +201,137,202, +138,202,137, +202,138,203, +139,203,138, +203,139,204, +140,204,139, +204,140,205, +141,205,140, +205,141,206, +142,206,141, +206,142,207, +143,207,142, +207,143,208, +144,208,143, +208,144,209, +145,209,144, +209,145,210, +146,210,145, +210,146,211, +147,211,146, +211,147,212, +148,212,147, +212,148,213, +149,213,148, +213,149,214, +150,214,149, +214,150,215, +151,215,150, +215,151,216, +152,216,151, +216,152,217, +153,217,152, +217,153,218, +154,218,153, +218,154,219, +155,219,154, +219,155,220, +156,220,155, +220,156,221, +157,221,156, +221,157,222, +158,222,157, +222,158,223, +159,223,158, +223,159,224, +160,224,159, +224,160,225, +161,225,160, +225,161,226, +162,226,161, +226,162,227, +163,227,162, +227,163,228, +164,228,163, +228,164,229, +165,229,164, +229,165,230, +166,230,165, +230,166,231, +167,231,166, +231,167,232, +168,232,167, +232,168,233, +169,233,168, +233,169,234, +170,234,169, +234,170,235, +171,235,170, +235,171,236, +172,236,171, +236,172,237, +173,237,172, +237,173,238, +174,238,173, +238,174,239, +175,239,174, +239,175,240, +176,240,175, +240,176,241, +177,241,176, +241,177,242, +178,242,177, +242,178,243, +179,243,178, +243,179,244, +180,244,179, +244,180,245, +181,245,180, +245,181,246, +182,246,181, +246,182,247, +183,247,182, +247,183,248, +184,248,183, +248,184,249, +185,249,184, +249,185,250, +186,250,185, +250,186,251, +187,251,186, +251,187,252, +188,252,187, +252,188,253, +189,253,188, +253,189,254, +190,254,189, +254,190,255, +191,255,190, +256,192,257, +193,257,192, +257,193,258, +194,258,193, +258,194,259, +195,259,194, +259,195,260, +196,260,195, +260,196,261, +197,261,196, +261,197,262, +198,262,197, +262,198,263, +199,263,198, +263,199,264, +200,264,199, +264,200,265, +201,265,200, +265,201,266, +202,266,201, +266,202,267, +203,267,202, +267,203,268, +204,268,203, +268,204,269, +205,269,204, +269,205,270, +206,270,205, +270,206,271, +207,271,206, +271,207,272, +208,272,207, +272,208,273, +209,273,208, +273,209,274, +210,274,209, +274,210,275, +211,275,210, +275,211,276, +212,276,211, +276,212,277, +213,277,212, +277,213,278, +214,278,213, +278,214,279, +215,279,214, +279,215,280, +216,280,215, +280,216,281, +217,281,216, +281,217,282, +218,282,217, +282,218,283, +219,283,218, +283,219,284, +220,284,219, +284,220,285, +221,285,220, +285,221,286, +222,286,221, +286,222,287, +223,287,222, +287,223,288, +224,288,223, +288,224,289, +225,289,224, +289,225,290, +226,290,225, +290,226,291, +227,291,226, +291,227,292, +228,292,227, +292,228,293, +229,293,228, +293,229,294, +230,294,229, +294,230,295, +231,295,230, +295,231,296, +232,296,231, +296,232,297, +233,297,232, +297,233,298, +234,298,233, +298,234,299, +235,299,234, +299,235,300, +236,300,235, +300,236,301, +237,301,236, +301,237,302, +238,302,237, +302,238,303, +239,303,238, +303,239,304, +240,304,239, +304,240,305, +241,305,240, +305,241,306, +242,306,241, +306,242,307, +243,307,242, +307,243,308, +244,308,243, +308,244,309, +245,309,244, +309,245,310, +246,310,245, +310,246,311, +247,311,246, +311,247,312, +248,312,247, +312,248,313, +249,313,248, +313,249,314, +250,314,249, +314,250,315, +251,315,250, +315,251,316, +252,316,251, +316,252,317, +253,317,252, +317,253,318, +254,318,253, +318,254,319, +255,319,254, +320,256,321, +257,321,256, +321,257,322, +258,322,257, +322,258,323, +259,323,258, +323,259,324, +260,324,259, +324,260,325, +261,325,260, +325,261,326, +262,326,261, +326,262,327, +263,327,262, +327,263,328, +264,328,263, +328,264,329, +265,329,264, +329,265,330, +266,330,265, +330,266,331, +267,331,266, +331,267,332, +268,332,267, +332,268,333, +269,333,268, +333,269,334, +270,334,269, +334,270,335, +271,335,270, +335,271,336, +272,336,271, +336,272,337, +273,337,272, +337,273,338, +274,338,273, +338,274,339, +275,339,274, +339,275,340, +276,340,275, +340,276,341, +277,341,276, +341,277,342, +278,342,277, +342,278,343, +279,343,278, +343,279,344, +280,344,279, +344,280,345, +281,345,280, +345,281,346, +282,346,281, +346,282,347, +283,347,282, +347,283,348, +284,348,283, +348,284,349, +285,349,284, +349,285,350, +286,350,285, +350,286,351, +287,351,286, +351,287,352, +288,352,287, +352,288,353, +289,353,288, +353,289,354, +290,354,289, +354,290,355, +291,355,290, +355,291,356, +292,356,291, +356,292,357, +293,357,292, +357,293,358, +294,358,293, +358,294,359, +295,359,294, +359,295,360, +296,360,295, +360,296,361, +297,361,296, +361,297,362, +298,362,297, +362,298,363, +299,363,298, +363,299,364, +300,364,299, +364,300,365, +301,365,300, +365,301,366, +302,366,301, +366,302,367, +303,367,302, +367,303,368, +304,368,303, +368,304,369, +305,369,304, +369,305,370, +306,370,305, +370,306,371, +307,371,306, +371,307,372, +308,372,307, +372,308,373, +309,373,308, +373,309,374, +310,374,309, +374,310,375, +311,375,310, +375,311,376, +312,376,311, +376,312,377, +313,377,312, +377,313,378, +314,378,313, +378,314,379, +315,379,314, +379,315,380, +316,380,315, +380,316,381, +317,381,316, +381,317,382, +318,382,317, +382,318,383, +319,383,318, +384,320,385, +321,385,320, +385,321,386, +322,386,321, +386,322,387, +323,387,322, +387,323,388, +324,388,323, +388,324,389, +325,389,324, +389,325,390, +326,390,325, +390,326,391, +327,391,326, +391,327,392, +328,392,327, +392,328,393, +329,393,328, +393,329,394, +330,394,329, +394,330,395, +331,395,330, +395,331,396, +332,396,331, +396,332,397, +333,397,332, +397,333,398, +334,398,333, +398,334,399, +335,399,334, +399,335,400, +336,400,335, +400,336,401, +337,401,336, +401,337,402, +338,402,337, +402,338,403, +339,403,338, +403,339,404, +340,404,339, +404,340,405, +341,405,340, +405,341,406, +342,406,341, +406,342,407, +343,407,342, +407,343,408, +344,408,343, +408,344,409, +345,409,344, +409,345,410, +346,410,345, +410,346,411, +347,411,346, +411,347,412, +348,412,347, +412,348,413, +349,413,348, +413,349,414, +350,414,349, +414,350,415, +351,415,350, +415,351,416, +352,416,351, +416,352,417, +353,417,352, +417,353,418, +354,418,353, +418,354,419, +355,419,354, +419,355,420, +356,420,355, +420,356,421, +357,421,356, +421,357,422, +358,422,357, +422,358,423, +359,423,358, +423,359,424, +360,424,359, +424,360,425, +361,425,360, +425,361,426, +362,426,361, +426,362,427, +363,427,362, +427,363,428, +364,428,363, +428,364,429, +365,429,364, +429,365,430, +366,430,365, +430,366,431, +367,431,366, +431,367,432, +368,432,367, +432,368,433, +369,433,368, +433,369,434, +370,434,369, +434,370,435, +371,435,370, +435,371,436, +372,436,371, +436,372,437, +373,437,372, +437,373,438, +374,438,373, +438,374,439, +375,439,374, +439,375,440, +376,440,375, +440,376,441, +377,441,376, +441,377,442, +378,442,377, +442,378,443, +379,443,378, +443,379,444, +380,444,379, +444,380,445, +381,445,380, +445,381,446, +382,446,381, +446,382,447, +383,447,382, +448,384,449, +385,449,384, +449,385,450, +386,450,385, +450,386,451, +387,451,386, +451,387,452, +388,452,387, +452,388,453, +389,453,388, +453,389,454, +390,454,389, +454,390,455, +391,455,390, +455,391,456, +392,456,391, +456,392,457, +393,457,392, +457,393,458, +394,458,393, +458,394,459, +395,459,394, +459,395,460, +396,460,395, +460,396,461, +397,461,396, +461,397,462, +398,462,397, +462,398,463, +399,463,398, +463,399,464, +400,464,399, +464,400,465, +401,465,400, +465,401,466, +402,466,401, +466,402,467, +403,467,402, +467,403,468, +404,468,403, +468,404,469, +405,469,404, +469,405,470, +406,470,405, +470,406,471, +407,471,406, +471,407,472, +408,472,407, +472,408,473, +409,473,408, +473,409,474, +410,474,409, +474,410,475, +411,475,410, +475,411,476, +412,476,411, +476,412,477, +413,477,412, +477,413,478, +414,478,413, +478,414,479, +415,479,414, +479,415,480, +416,480,415, +480,416,481, +417,481,416, +481,417,482, +418,482,417, +482,418,483, +419,483,418, +483,419,484, +420,484,419, +484,420,485, +421,485,420, +485,421,486, +422,486,421, +486,422,487, +423,487,422, +487,423,488, +424,488,423, +488,424,489, +425,489,424, +489,425,490, +426,490,425, +490,426,491, +427,491,426, +491,427,492, +428,492,427, +492,428,493, +429,493,428, +493,429,494, +430,494,429, +494,430,495, +431,495,430, +495,431,496, +432,496,431, +496,432,497, +433,497,432, +497,433,498, +434,498,433, +498,434,499, +435,499,434, +499,435,500, +436,500,435, +500,436,501, +437,501,436, +501,437,502, +438,502,437, +502,438,503, +439,503,438, +503,439,504, +440,504,439, +504,440,505, +441,505,440, +505,441,506, +442,506,441, +506,442,507, +443,507,442, +507,443,508, +444,508,443, +508,444,509, +445,509,444, +509,445,510, +446,510,445, +510,446,511, +447,511,446, +512,448,513, +449,513,448, +513,449,514, +450,514,449, +514,450,515, +451,515,450, +515,451,516, +452,516,451, +516,452,517, +453,517,452, +517,453,518, +454,518,453, +518,454,519, +455,519,454, +519,455,520, +456,520,455, +520,456,521, +457,521,456, +521,457,522, +458,522,457, +522,458,523, +459,523,458, +523,459,524, +460,524,459, +524,460,525, +461,525,460, +525,461,526, +462,526,461, +526,462,527, +463,527,462, +527,463,528, +464,528,463, +528,464,529, +465,529,464, +529,465,530, +466,530,465, +530,466,531, +467,531,466, +531,467,532, +468,532,467, +532,468,533, +469,533,468, +533,469,534, +470,534,469, +534,470,535, +471,535,470, +535,471,536, +472,536,471, +536,472,537, +473,537,472, +537,473,538, +474,538,473, +538,474,539, +475,539,474, +539,475,540, +476,540,475, +540,476,541, +477,541,476, +541,477,542, +478,542,477, +542,478,543, +479,543,478, +543,479,544, +480,544,479, +544,480,545, +481,545,480, +545,481,546, +482,546,481, +546,482,547, +483,547,482, +547,483,548, +484,548,483, +548,484,549, +485,549,484, +549,485,550, +486,550,485, +550,486,551, +487,551,486, +551,487,552, +488,552,487, +552,488,553, +489,553,488, +553,489,554, +490,554,489, +554,490,555, +491,555,490, +555,491,556, +492,556,491, +556,492,557, +493,557,492, +557,493,558, +494,558,493, +558,494,559, +495,559,494, +559,495,560, +496,560,495, +560,496,561, +497,561,496, +561,497,562, +498,562,497, +562,498,563, +499,563,498, +563,499,564, +500,564,499, +564,500,565, +501,565,500, +565,501,566, +502,566,501, +566,502,567, +503,567,502, +567,503,568, +504,568,503, +568,504,569, +505,569,504, +569,505,570, +506,570,505, +570,506,571, +507,571,506, +571,507,572, +508,572,507, +572,508,573, +509,573,508, +573,509,574, +510,574,509, +574,510,575, +511,575,510, +576,512,577, +513,577,512, +577,513,578, +514,578,513, +578,514,579, +515,579,514, +579,515,580, +516,580,515, +580,516,581, +517,581,516, +581,517,582, +518,582,517, +582,518,583, +519,583,518, +583,519,584, +520,584,519, +584,520,585, +521,585,520, +585,521,586, +522,586,521, +586,522,587, +523,587,522, +587,523,588, +524,588,523, +588,524,589, +525,589,524, +589,525,590, +526,590,525, +590,526,591, +527,591,526, +591,527,592, +528,592,527, +592,528,593, +529,593,528, +593,529,594, +530,594,529, +594,530,595, +531,595,530, +595,531,596, +532,596,531, +596,532,597, +533,597,532, +597,533,598, +534,598,533, +598,534,599, +535,599,534, +599,535,600, +536,600,535, +600,536,601, +537,601,536, +601,537,602, +538,602,537, +602,538,603, +539,603,538, +603,539,604, +540,604,539, +604,540,605, +541,605,540, +605,541,606, +542,606,541, +606,542,607, +543,607,542, +607,543,608, +544,608,543, +608,544,609, +545,609,544, +609,545,610, +546,610,545, +610,546,611, +547,611,546, +611,547,612, +548,612,547, +612,548,613, +549,613,548, +613,549,614, +550,614,549, +614,550,615, +551,615,550, +615,551,616, +552,616,551, +616,552,617, +553,617,552, +617,553,618, +554,618,553, +618,554,619, +555,619,554, +619,555,620, +556,620,555, +620,556,621, +557,621,556, +621,557,622, +558,622,557, +622,558,623, +559,623,558, +623,559,624, +560,624,559, +624,560,625, +561,625,560, +625,561,626, +562,626,561, +626,562,627, +563,627,562, +627,563,628, +564,628,563, +628,564,629, +565,629,564, +629,565,630, +566,630,565, +630,566,631, +567,631,566, +631,567,632, +568,632,567, +632,568,633, +569,633,568, +633,569,634, +570,634,569, +634,570,635, +571,635,570, +635,571,636, +572,636,571, +636,572,637, +573,637,572, +637,573,638, +574,638,573, +638,574,639, +575,639,574, +640,576,641, +577,641,576, +641,577,642, +578,642,577, +642,578,643, +579,643,578, +643,579,644, +580,644,579, +644,580,645, +581,645,580, +645,581,646, +582,646,581, +646,582,647, +583,647,582, +647,583,648, +584,648,583, +648,584,649, +585,649,584, +649,585,650, +586,650,585, +650,586,651, +587,651,586, +651,587,652, +588,652,587, +652,588,653, +589,653,588, +653,589,654, +590,654,589, +654,590,655, +591,655,590, +655,591,656, +592,656,591, +656,592,657, +593,657,592, +657,593,658, +594,658,593, +658,594,659, +595,659,594, +659,595,660, +596,660,595, +660,596,661, +597,661,596, +661,597,662, +598,662,597, +662,598,663, +599,663,598, +663,599,664, +600,664,599, +664,600,665, +601,665,600, +665,601,666, +602,666,601, +666,602,667, +603,667,602, +667,603,668, +604,668,603, +668,604,669, +605,669,604, +669,605,670, +606,670,605, +670,606,671, +607,671,606, +671,607,672, +608,672,607, +672,608,673, +609,673,608, +673,609,674, +610,674,609, +674,610,675, +611,675,610, +675,611,676, +612,676,611, +676,612,677, +613,677,612, +677,613,678, +614,678,613, +678,614,679, +615,679,614, +679,615,680, +616,680,615, +680,616,681, +617,681,616, +681,617,682, +618,682,617, +682,618,683, +619,683,618, +683,619,684, +620,684,619, +684,620,685, +621,685,620, +685,621,686, +622,686,621, +686,622,687, +623,687,622, +687,623,688, +624,688,623, +688,624,689, +625,689,624, +689,625,690, +626,690,625, +690,626,691, +627,691,626, +691,627,692, +628,692,627, +692,628,693, +629,693,628, +693,629,694, +630,694,629, +694,630,695, +631,695,630, +695,631,696, +632,696,631, +696,632,697, +633,697,632, +697,633,698, +634,698,633, +698,634,699, +635,699,634, +699,635,700, +636,700,635, +700,636,701, +637,701,636, +701,637,702, +638,702,637, +702,638,703, +639,703,638, +704,640,705, +641,705,640, +705,641,706, +642,706,641, +706,642,707, +643,707,642, +707,643,708, +644,708,643, +708,644,709, +645,709,644, +709,645,710, +646,710,645, +710,646,711, +647,711,646, +711,647,712, +648,712,647, +712,648,713, +649,713,648, +713,649,714, +650,714,649, +714,650,715, +651,715,650, +715,651,716, +652,716,651, +716,652,717, +653,717,652, +717,653,718, +654,718,653, +718,654,719, +655,719,654, +719,655,720, +656,720,655, +720,656,721, +657,721,656, +721,657,722, +658,722,657, +722,658,723, +659,723,658, +723,659,724, +660,724,659, +724,660,725, +661,725,660, +725,661,726, +662,726,661, +726,662,727, +663,727,662, +727,663,728, +664,728,663, +728,664,729, +665,729,664, +729,665,730, +666,730,665, +730,666,731, +667,731,666, +731,667,732, +668,732,667, +732,668,733, +669,733,668, +733,669,734, +670,734,669, +734,670,735, +671,735,670, +735,671,736, +672,736,671, +736,672,737, +673,737,672, +737,673,738, +674,738,673, +738,674,739, +675,739,674, +739,675,740, +676,740,675, +740,676,741, +677,741,676, +741,677,742, +678,742,677, +742,678,743, +679,743,678, +743,679,744, +680,744,679, +744,680,745, +681,745,680, +745,681,746, +682,746,681, +746,682,747, +683,747,682, +747,683,748, +684,748,683, +748,684,749, +685,749,684, +749,685,750, +686,750,685, +750,686,751, +687,751,686, +751,687,752, +688,752,687, +752,688,753, +689,753,688, +753,689,754, +690,754,689, +754,690,755, +691,755,690, +755,691,756, +692,756,691, +756,692,757, +693,757,692, +757,693,758, +694,758,693, +758,694,759, +695,759,694, +759,695,760, +696,760,695, +760,696,761, +697,761,696, +761,697,762, +698,762,697, +762,698,763, +699,763,698, +763,699,764, +700,764,699, +764,700,765, +701,765,700, +765,701,766, +702,766,701, +766,702,767, +703,767,702, +768,704,769, +705,769,704, +769,705,770, +706,770,705, +770,706,771, +707,771,706, +771,707,772, +708,772,707, +772,708,773, +709,773,708, +773,709,774, +710,774,709, +774,710,775, +711,775,710, +775,711,776, +712,776,711, +776,712,777, +713,777,712, +777,713,778, +714,778,713, +778,714,779, +715,779,714, +779,715,780, +716,780,715, +780,716,781, +717,781,716, +781,717,782, +718,782,717, +782,718,783, +719,783,718, +783,719,784, +720,784,719, +784,720,785, +721,785,720, +785,721,786, +722,786,721, +786,722,787, +723,787,722, +787,723,788, +724,788,723, +788,724,789, +725,789,724, +789,725,790, +726,790,725, +790,726,791, +727,791,726, +791,727,792, +728,792,727, +792,728,793, +729,793,728, +793,729,794, +730,794,729, +794,730,795, +731,795,730, +795,731,796, +732,796,731, +796,732,797, +733,797,732, +797,733,798, +734,798,733, +798,734,799, +735,799,734, +799,735,800, +736,800,735, +800,736,801, +737,801,736, +801,737,802, +738,802,737, +802,738,803, +739,803,738, +803,739,804, +740,804,739, +804,740,805, +741,805,740, +805,741,806, +742,806,741, +806,742,807, +743,807,742, +807,743,808, +744,808,743, +808,744,809, +745,809,744, +809,745,810, +746,810,745, +810,746,811, +747,811,746, +811,747,812, +748,812,747, +812,748,813, +749,813,748, +813,749,814, +750,814,749, +814,750,815, +751,815,750, +815,751,816, +752,816,751, +816,752,817, +753,817,752, +817,753,818, +754,818,753, +818,754,819, +755,819,754, +819,755,820, +756,820,755, +820,756,821, +757,821,756, +821,757,822, +758,822,757, +822,758,823, +759,823,758, +823,759,824, +760,824,759, +824,760,825, +761,825,760, +825,761,826, +762,826,761, +826,762,827, +763,827,762, +827,763,828, +764,828,763, +828,764,829, +765,829,764, +829,765,830, +766,830,765, +830,766,831, +767,831,766, +832,768,833, +769,833,768, +833,769,834, +770,834,769, +834,770,835, +771,835,770, +835,771,836, +772,836,771, +836,772,837, +773,837,772, +837,773,838, +774,838,773, +838,774,839, +775,839,774, +839,775,840, +776,840,775, +840,776,841, +777,841,776, +841,777,842, +778,842,777, +842,778,843, +779,843,778, +843,779,844, +780,844,779, +844,780,845, +781,845,780, +845,781,846, +782,846,781, +846,782,847, +783,847,782, +847,783,848, +784,848,783, +848,784,849, +785,849,784, +849,785,850, +786,850,785, +850,786,851, +787,851,786, +851,787,852, +788,852,787, +852,788,853, +789,853,788, +853,789,854, +790,854,789, +854,790,855, +791,855,790, +855,791,856, +792,856,791, +856,792,857, +793,857,792, +857,793,858, +794,858,793, +858,794,859, +795,859,794, +859,795,860, +796,860,795, +860,796,861, +797,861,796, +861,797,862, +798,862,797, +862,798,863, +799,863,798, +863,799,864, +800,864,799, +864,800,865, +801,865,800, +865,801,866, +802,866,801, +866,802,867, +803,867,802, +867,803,868, +804,868,803, +868,804,869, +805,869,804, +869,805,870, +806,870,805, +870,806,871, +807,871,806, +871,807,872, +808,872,807, +872,808,873, +809,873,808, +873,809,874, +810,874,809, +874,810,875, +811,875,810, +875,811,876, +812,876,811, +876,812,877, +813,877,812, +877,813,878, +814,878,813, +878,814,879, +815,879,814, +879,815,880, +816,880,815, +880,816,881, +817,881,816, +881,817,882, +818,882,817, +882,818,883, +819,883,818, +883,819,884, +820,884,819, +884,820,885, +821,885,820, +885,821,886, +822,886,821, +886,822,887, +823,887,822, +887,823,888, +824,888,823, +888,824,889, +825,889,824, +889,825,890, +826,890,825, +890,826,891, +827,891,826, +891,827,892, +828,892,827, +892,828,893, +829,893,828, +893,829,894, +830,894,829, +894,830,895, +831,895,830, +896,832,897, +833,897,832, +897,833,898, +834,898,833, +898,834,899, +835,899,834, +899,835,900, +836,900,835, +900,836,901, +837,901,836, +901,837,902, +838,902,837, +902,838,903, +839,903,838, +903,839,904, +840,904,839, +904,840,905, +841,905,840, +905,841,906, +842,906,841, +906,842,907, +843,907,842, +907,843,908, +844,908,843, +908,844,909, +845,909,844, +909,845,910, +846,910,845, +910,846,911, +847,911,846, +911,847,912, +848,912,847, +912,848,913, +849,913,848, +913,849,914, +850,914,849, +914,850,915, +851,915,850, +915,851,916, +852,916,851, +916,852,917, +853,917,852, +917,853,918, +854,918,853, +918,854,919, +855,919,854, +919,855,920, +856,920,855, +920,856,921, +857,921,856, +921,857,922, +858,922,857, +922,858,923, +859,923,858, +923,859,924, +860,924,859, +924,860,925, +861,925,860, +925,861,926, +862,926,861, +926,862,927, +863,927,862, +927,863,928, +864,928,863, +928,864,929, +865,929,864, +929,865,930, +866,930,865, +930,866,931, +867,931,866, +931,867,932, +868,932,867, +932,868,933, +869,933,868, +933,869,934, +870,934,869, +934,870,935, +871,935,870, +935,871,936, +872,936,871, +936,872,937, +873,937,872, +937,873,938, +874,938,873, +938,874,939, +875,939,874, +939,875,940, +876,940,875, +940,876,941, +877,941,876, +941,877,942, +878,942,877, +942,878,943, +879,943,878, +943,879,944, +880,944,879, +944,880,945, +881,945,880, +945,881,946, +882,946,881, +946,882,947, +883,947,882, +947,883,948, +884,948,883, +948,884,949, +885,949,884, +949,885,950, +886,950,885, +950,886,951, +887,951,886, +951,887,952, +888,952,887, +952,888,953, +889,953,888, +953,889,954, +890,954,889, +954,890,955, +891,955,890, +955,891,956, +892,956,891, +956,892,957, +893,957,892, +957,893,958, +894,958,893, +958,894,959, +895,959,894, +960,896,961, +897,961,896, +961,897,962, +898,962,897, +962,898,963, +899,963,898, +963,899,964, +900,964,899, +964,900,965, +901,965,900, +965,901,966, +902,966,901, +966,902,967, +903,967,902, +967,903,968, +904,968,903, +968,904,969, +905,969,904, +969,905,970, +906,970,905, +970,906,971, +907,971,906, +971,907,972, +908,972,907, +972,908,973, +909,973,908, +973,909,974, +910,974,909, +974,910,975, +911,975,910, +975,911,976, +912,976,911, +976,912,977, +913,977,912, +977,913,978, +914,978,913, +978,914,979, +915,979,914, +979,915,980, +916,980,915, +980,916,981, +917,981,916, +981,917,982, +918,982,917, +982,918,983, +919,983,918, +983,919,984, +920,984,919, +984,920,985, +921,985,920, +985,921,986, +922,986,921, +986,922,987, +923,987,922, +987,923,988, +924,988,923, +988,924,989, +925,989,924, +989,925,990, +926,990,925, +990,926,991, +927,991,926, +991,927,992, +928,992,927, +992,928,993, +929,993,928, +993,929,994, +930,994,929, +994,930,995, +931,995,930, +995,931,996, +932,996,931, +996,932,997, +933,997,932, +997,933,998, +934,998,933, +998,934,999, +935,999,934, +999,935,1000, +936,1000,935, +1000,936,1001, +937,1001,936, +1001,937,1002, +938,1002,937, +1002,938,1003, +939,1003,938, +1003,939,1004, +940,1004,939, +1004,940,1005, +941,1005,940, +1005,941,1006, +942,1006,941, +1006,942,1007, +943,1007,942, +1007,943,1008, +944,1008,943, +1008,944,1009, +945,1009,944, +1009,945,1010, +946,1010,945, +1010,946,1011, +947,1011,946, +1011,947,1012, +948,1012,947, +1012,948,1013, +949,1013,948, +1013,949,1014, +950,1014,949, +1014,950,1015, +951,1015,950, +1015,951,1016, +952,1016,951, +1016,952,1017, +953,1017,952, +1017,953,1018, +954,1018,953, +1018,954,1019, +955,1019,954, +1019,955,1020, +956,1020,955, +1020,956,1021, +957,1021,956, +1021,957,1022, +958,1022,957, +1022,958,1023, +959,1023,958, +1024,960,1025, +961,1025,960, +1025,961,1026, +962,1026,961, +1026,962,1027, +963,1027,962, +1027,963,1028, +964,1028,963, +1028,964,1029, +965,1029,964, +1029,965,1030, +966,1030,965, +1030,966,1031, +967,1031,966, +1031,967,1032, +968,1032,967, +1032,968,1033, +969,1033,968, +1033,969,1034, +970,1034,969, +1034,970,1035, +971,1035,970, +1035,971,1036, +972,1036,971, +1036,972,1037, +973,1037,972, +1037,973,1038, +974,1038,973, +1038,974,1039, +975,1039,974, +1039,975,1040, +976,1040,975, +1040,976,1041, +977,1041,976, +1041,977,1042, +978,1042,977, +1042,978,1043, +979,1043,978, +1043,979,1044, +980,1044,979, +1044,980,1045, +981,1045,980, +1045,981,1046, +982,1046,981, +1046,982,1047, +983,1047,982, +1047,983,1048, +984,1048,983, +1048,984,1049, +985,1049,984, +1049,985,1050, +986,1050,985, +1050,986,1051, +987,1051,986, +1051,987,1052, +988,1052,987, +1052,988,1053, +989,1053,988, +1053,989,1054, +990,1054,989, +1054,990,1055, +991,1055,990, +1055,991,1056, +992,1056,991, +1056,992,1057, +993,1057,992, +1057,993,1058, +994,1058,993, +1058,994,1059, +995,1059,994, +1059,995,1060, +996,1060,995, +1060,996,1061, +997,1061,996, +1061,997,1062, +998,1062,997, +1062,998,1063, +999,1063,998, +1063,999,1064, +1000,1064,999, +1064,1000,1065, +1001,1065,1000, +1065,1001,1066, +1002,1066,1001, +1066,1002,1067, +1003,1067,1002, +1067,1003,1068, +1004,1068,1003, +1068,1004,1069, +1005,1069,1004, +1069,1005,1070, +1006,1070,1005, +1070,1006,1071, +1007,1071,1006, +1071,1007,1072, +1008,1072,1007, +1072,1008,1073, +1009,1073,1008, +1073,1009,1074, +1010,1074,1009, +1074,1010,1075, +1011,1075,1010, +1075,1011,1076, +1012,1076,1011, +1076,1012,1077, +1013,1077,1012, +1077,1013,1078, +1014,1078,1013, +1078,1014,1079, +1015,1079,1014, +1079,1015,1080, +1016,1080,1015, +1080,1016,1081, +1017,1081,1016, +1081,1017,1082, +1018,1082,1017, +1082,1018,1083, +1019,1083,1018, +1083,1019,1084, +1020,1084,1019, +1084,1020,1085, +1021,1085,1020, +1085,1021,1086, +1022,1086,1021, +1086,1022,1087, +1023,1087,1022, +1088,1024,1089, +1025,1089,1024, +1089,1025,1090, +1026,1090,1025, +1090,1026,1091, +1027,1091,1026, +1091,1027,1092, +1028,1092,1027, +1092,1028,1093, +1029,1093,1028, +1093,1029,1094, +1030,1094,1029, +1094,1030,1095, +1031,1095,1030, +1095,1031,1096, +1032,1096,1031, +1096,1032,1097, +1033,1097,1032, +1097,1033,1098, +1034,1098,1033, +1098,1034,1099, +1035,1099,1034, +1099,1035,1100, +1036,1100,1035, +1100,1036,1101, +1037,1101,1036, +1101,1037,1102, +1038,1102,1037, +1102,1038,1103, +1039,1103,1038, +1103,1039,1104, +1040,1104,1039, +1104,1040,1105, +1041,1105,1040, +1105,1041,1106, +1042,1106,1041, +1106,1042,1107, +1043,1107,1042, +1107,1043,1108, +1044,1108,1043, +1108,1044,1109, +1045,1109,1044, +1109,1045,1110, +1046,1110,1045, +1110,1046,1111, +1047,1111,1046, +1111,1047,1112, +1048,1112,1047, +1112,1048,1113, +1049,1113,1048, +1113,1049,1114, +1050,1114,1049, +1114,1050,1115, +1051,1115,1050, +1115,1051,1116, +1052,1116,1051, +1116,1052,1117, +1053,1117,1052, +1117,1053,1118, +1054,1118,1053, +1118,1054,1119, +1055,1119,1054, +1119,1055,1120, +1056,1120,1055, +1120,1056,1121, +1057,1121,1056, +1121,1057,1122, +1058,1122,1057, +1122,1058,1123, +1059,1123,1058, +1123,1059,1124, +1060,1124,1059, +1124,1060,1125, +1061,1125,1060, +1125,1061,1126, +1062,1126,1061, +1126,1062,1127, +1063,1127,1062, +1127,1063,1128, +1064,1128,1063, +1128,1064,1129, +1065,1129,1064, +1129,1065,1130, +1066,1130,1065, +1130,1066,1131, +1067,1131,1066, +1131,1067,1132, +1068,1132,1067, +1132,1068,1133, +1069,1133,1068, +1133,1069,1134, +1070,1134,1069, +1134,1070,1135, +1071,1135,1070, +1135,1071,1136, +1072,1136,1071, +1136,1072,1137, +1073,1137,1072, +1137,1073,1138, +1074,1138,1073, +1138,1074,1139, +1075,1139,1074, +1139,1075,1140, +1076,1140,1075, +1140,1076,1141, +1077,1141,1076, +1141,1077,1142, +1078,1142,1077, +1142,1078,1143, +1079,1143,1078, +1143,1079,1144, +1080,1144,1079, +1144,1080,1145, +1081,1145,1080, +1145,1081,1146, +1082,1146,1081, +1146,1082,1147, +1083,1147,1082, +1147,1083,1148, +1084,1148,1083, +1148,1084,1149, +1085,1149,1084, +1149,1085,1150, +1086,1150,1085, +1150,1086,1151, +1087,1151,1086, +1152,1088,1153, +1089,1153,1088, +1153,1089,1154, +1090,1154,1089, +1154,1090,1155, +1091,1155,1090, +1155,1091,1156, +1092,1156,1091, +1156,1092,1157, +1093,1157,1092, +1157,1093,1158, +1094,1158,1093, +1158,1094,1159, +1095,1159,1094, +1159,1095,1160, +1096,1160,1095, +1160,1096,1161, +1097,1161,1096, +1161,1097,1162, +1098,1162,1097, +1162,1098,1163, +1099,1163,1098, +1163,1099,1164, +1100,1164,1099, +1164,1100,1165, +1101,1165,1100, +1165,1101,1166, +1102,1166,1101, +1166,1102,1167, +1103,1167,1102, +1167,1103,1168, +1104,1168,1103, +1168,1104,1169, +1105,1169,1104, +1169,1105,1170, +1106,1170,1105, +1170,1106,1171, +1107,1171,1106, +1171,1107,1172, +1108,1172,1107, +1172,1108,1173, +1109,1173,1108, +1173,1109,1174, +1110,1174,1109, +1174,1110,1175, +1111,1175,1110, +1175,1111,1176, +1112,1176,1111, +1176,1112,1177, +1113,1177,1112, +1177,1113,1178, +1114,1178,1113, +1178,1114,1179, +1115,1179,1114, +1179,1115,1180, +1116,1180,1115, +1180,1116,1181, +1117,1181,1116, +1181,1117,1182, +1118,1182,1117, +1182,1118,1183, +1119,1183,1118, +1183,1119,1184, +1120,1184,1119, +1184,1120,1185, +1121,1185,1120, +1185,1121,1186, +1122,1186,1121, +1186,1122,1187, +1123,1187,1122, +1187,1123,1188, +1124,1188,1123, +1188,1124,1189, +1125,1189,1124, +1189,1125,1190, +1126,1190,1125, +1190,1126,1191, +1127,1191,1126, +1191,1127,1192, +1128,1192,1127, +1192,1128,1193, +1129,1193,1128, +1193,1129,1194, +1130,1194,1129, +1194,1130,1195, +1131,1195,1130, +1195,1131,1196, +1132,1196,1131, +1196,1132,1197, +1133,1197,1132, +1197,1133,1198, +1134,1198,1133, +1198,1134,1199, +1135,1199,1134, +1199,1135,1200, +1136,1200,1135, +1200,1136,1201, +1137,1201,1136, +1201,1137,1202, +1138,1202,1137, +1202,1138,1203, +1139,1203,1138, +1203,1139,1204, +1140,1204,1139, +1204,1140,1205, +1141,1205,1140, +1205,1141,1206, +1142,1206,1141, +1206,1142,1207, +1143,1207,1142, +1207,1143,1208, +1144,1208,1143, +1208,1144,1209, +1145,1209,1144, +1209,1145,1210, +1146,1210,1145, +1210,1146,1211, +1147,1211,1146, +1211,1147,1212, +1148,1212,1147, +1212,1148,1213, +1149,1213,1148, +1213,1149,1214, +1150,1214,1149, +1214,1150,1215, +1151,1215,1150, +1216,1152,1217, +1153,1217,1152, +1217,1153,1218, +1154,1218,1153, +1218,1154,1219, +1155,1219,1154, +1219,1155,1220, +1156,1220,1155, +1220,1156,1221, +1157,1221,1156, +1221,1157,1222, +1158,1222,1157, +1222,1158,1223, +1159,1223,1158, +1223,1159,1224, +1160,1224,1159, +1224,1160,1225, +1161,1225,1160, +1225,1161,1226, +1162,1226,1161, +1226,1162,1227, +1163,1227,1162, +1227,1163,1228, +1164,1228,1163, +1228,1164,1229, +1165,1229,1164, +1229,1165,1230, +1166,1230,1165, +1230,1166,1231, +1167,1231,1166, +1231,1167,1232, +1168,1232,1167, +1232,1168,1233, +1169,1233,1168, +1233,1169,1234, +1170,1234,1169, +1234,1170,1235, +1171,1235,1170, +1235,1171,1236, +1172,1236,1171, +1236,1172,1237, +1173,1237,1172, +1237,1173,1238, +1174,1238,1173, +1238,1174,1239, +1175,1239,1174, +1239,1175,1240, +1176,1240,1175, +1240,1176,1241, +1177,1241,1176, +1241,1177,1242, +1178,1242,1177, +1242,1178,1243, +1179,1243,1178, +1243,1179,1244, +1180,1244,1179, +1244,1180,1245, +1181,1245,1180, +1245,1181,1246, +1182,1246,1181, +1246,1182,1247, +1183,1247,1182, +1247,1183,1248, +1184,1248,1183, +1248,1184,1249, +1185,1249,1184, +1249,1185,1250, +1186,1250,1185, +1250,1186,1251, +1187,1251,1186, +1251,1187,1252, +1188,1252,1187, +1252,1188,1253, +1189,1253,1188, +1253,1189,1254, +1190,1254,1189, +1254,1190,1255, +1191,1255,1190, +1255,1191,1256, +1192,1256,1191, +1256,1192,1257, +1193,1257,1192, +1257,1193,1258, +1194,1258,1193, +1258,1194,1259, +1195,1259,1194, +1259,1195,1260, +1196,1260,1195, +1260,1196,1261, +1197,1261,1196, +1261,1197,1262, +1198,1262,1197, +1262,1198,1263, +1199,1263,1198, +1263,1199,1264, +1200,1264,1199, +1264,1200,1265, +1201,1265,1200, +1265,1201,1266, +1202,1266,1201, +1266,1202,1267, +1203,1267,1202, +1267,1203,1268, +1204,1268,1203, +1268,1204,1269, +1205,1269,1204, +1269,1205,1270, +1206,1270,1205, +1270,1206,1271, +1207,1271,1206, +1271,1207,1272, +1208,1272,1207, +1272,1208,1273, +1209,1273,1208, +1273,1209,1274, +1210,1274,1209, +1274,1210,1275, +1211,1275,1210, +1275,1211,1276, +1212,1276,1211, +1276,1212,1277, +1213,1277,1212, +1277,1213,1278, +1214,1278,1213, +1278,1214,1279, +1215,1279,1214, +1280,1216,1281, +1217,1281,1216, +1281,1217,1282, +1218,1282,1217, +1282,1218,1283, +1219,1283,1218, +1283,1219,1284, +1220,1284,1219, +1284,1220,1285, +1221,1285,1220, +1285,1221,1286, +1222,1286,1221, +1286,1222,1287, +1223,1287,1222, +1287,1223,1288, +1224,1288,1223, +1288,1224,1289, +1225,1289,1224, +1289,1225,1290, +1226,1290,1225, +1290,1226,1291, +1227,1291,1226, +1291,1227,1292, +1228,1292,1227, +1292,1228,1293, +1229,1293,1228, +1293,1229,1294, +1230,1294,1229, +1294,1230,1295, +1231,1295,1230, +1295,1231,1296, +1232,1296,1231, +1296,1232,1297, +1233,1297,1232, +1297,1233,1298, +1234,1298,1233, +1298,1234,1299, +1235,1299,1234, +1299,1235,1300, +1236,1300,1235, +1300,1236,1301, +1237,1301,1236, +1301,1237,1302, +1238,1302,1237, +1302,1238,1303, +1239,1303,1238, +1303,1239,1304, +1240,1304,1239, +1304,1240,1305, +1241,1305,1240, +1305,1241,1306, +1242,1306,1241, +1306,1242,1307, +1243,1307,1242, +1307,1243,1308, +1244,1308,1243, +1308,1244,1309, +1245,1309,1244, +1309,1245,1310, +1246,1310,1245, +1310,1246,1311, +1247,1311,1246, +1311,1247,1312, +1248,1312,1247, +1312,1248,1313, +1249,1313,1248, +1313,1249,1314, +1250,1314,1249, +1314,1250,1315, +1251,1315,1250, +1315,1251,1316, +1252,1316,1251, +1316,1252,1317, +1253,1317,1252, +1317,1253,1318, +1254,1318,1253, +1318,1254,1319, +1255,1319,1254, +1319,1255,1320, +1256,1320,1255, +1320,1256,1321, +1257,1321,1256, +1321,1257,1322, +1258,1322,1257, +1322,1258,1323, +1259,1323,1258, +1323,1259,1324, +1260,1324,1259, +1324,1260,1325, +1261,1325,1260, +1325,1261,1326, +1262,1326,1261, +1326,1262,1327, +1263,1327,1262, +1327,1263,1328, +1264,1328,1263, +1328,1264,1329, +1265,1329,1264, +1329,1265,1330, +1266,1330,1265, +1330,1266,1331, +1267,1331,1266, +1331,1267,1332, +1268,1332,1267, +1332,1268,1333, +1269,1333,1268, +1333,1269,1334, +1270,1334,1269, +1334,1270,1335, +1271,1335,1270, +1335,1271,1336, +1272,1336,1271, +1336,1272,1337, +1273,1337,1272, +1337,1273,1338, +1274,1338,1273, +1338,1274,1339, +1275,1339,1274, +1339,1275,1340, +1276,1340,1275, +1340,1276,1341, +1277,1341,1276, +1341,1277,1342, +1278,1342,1277, +1342,1278,1343, +1279,1343,1278, +1344,1280,1345, +1281,1345,1280, +1345,1281,1346, +1282,1346,1281, +1346,1282,1347, +1283,1347,1282, +1347,1283,1348, +1284,1348,1283, +1348,1284,1349, +1285,1349,1284, +1349,1285,1350, +1286,1350,1285, +1350,1286,1351, +1287,1351,1286, +1351,1287,1352, +1288,1352,1287, +1352,1288,1353, +1289,1353,1288, +1353,1289,1354, +1290,1354,1289, +1354,1290,1355, +1291,1355,1290, +1355,1291,1356, +1292,1356,1291, +1356,1292,1357, +1293,1357,1292, +1357,1293,1358, +1294,1358,1293, +1358,1294,1359, +1295,1359,1294, +1359,1295,1360, +1296,1360,1295, +1360,1296,1361, +1297,1361,1296, +1361,1297,1362, +1298,1362,1297, +1362,1298,1363, +1299,1363,1298, +1363,1299,1364, +1300,1364,1299, +1364,1300,1365, +1301,1365,1300, +1365,1301,1366, +1302,1366,1301, +1366,1302,1367, +1303,1367,1302, +1367,1303,1368, +1304,1368,1303, +1368,1304,1369, +1305,1369,1304, +1369,1305,1370, +1306,1370,1305, +1370,1306,1371, +1307,1371,1306, +1371,1307,1372, +1308,1372,1307, +1372,1308,1373, +1309,1373,1308, +1373,1309,1374, +1310,1374,1309, +1374,1310,1375, +1311,1375,1310, +1375,1311,1376, +1312,1376,1311, +1376,1312,1377, +1313,1377,1312, +1377,1313,1378, +1314,1378,1313, +1378,1314,1379, +1315,1379,1314, +1379,1315,1380, +1316,1380,1315, +1380,1316,1381, +1317,1381,1316, +1381,1317,1382, +1318,1382,1317, +1382,1318,1383, +1319,1383,1318, +1383,1319,1384, +1320,1384,1319, +1384,1320,1385, +1321,1385,1320, +1385,1321,1386, +1322,1386,1321, +1386,1322,1387, +1323,1387,1322, +1387,1323,1388, +1324,1388,1323, +1388,1324,1389, +1325,1389,1324, +1389,1325,1390, +1326,1390,1325, +1390,1326,1391, +1327,1391,1326, +1391,1327,1392, +1328,1392,1327, +1392,1328,1393, +1329,1393,1328, +1393,1329,1394, +1330,1394,1329, +1394,1330,1395, +1331,1395,1330, +1395,1331,1396, +1332,1396,1331, +1396,1332,1397, +1333,1397,1332, +1397,1333,1398, +1334,1398,1333, +1398,1334,1399, +1335,1399,1334, +1399,1335,1400, +1336,1400,1335, +1400,1336,1401, +1337,1401,1336, +1401,1337,1402, +1338,1402,1337, +1402,1338,1403, +1339,1403,1338, +1403,1339,1404, +1340,1404,1339, +1404,1340,1405, +1341,1405,1340, +1405,1341,1406, +1342,1406,1341, +1406,1342,1407, +1343,1407,1342, +1408,1344,1409, +1345,1409,1344, +1409,1345,1410, +1346,1410,1345, +1410,1346,1411, +1347,1411,1346, +1411,1347,1412, +1348,1412,1347, +1412,1348,1413, +1349,1413,1348, +1413,1349,1414, +1350,1414,1349, +1414,1350,1415, +1351,1415,1350, +1415,1351,1416, +1352,1416,1351, +1416,1352,1417, +1353,1417,1352, +1417,1353,1418, +1354,1418,1353, +1418,1354,1419, +1355,1419,1354, +1419,1355,1420, +1356,1420,1355, +1420,1356,1421, +1357,1421,1356, +1421,1357,1422, +1358,1422,1357, +1422,1358,1423, +1359,1423,1358, +1423,1359,1424, +1360,1424,1359, +1424,1360,1425, +1361,1425,1360, +1425,1361,1426, +1362,1426,1361, +1426,1362,1427, +1363,1427,1362, +1427,1363,1428, +1364,1428,1363, +1428,1364,1429, +1365,1429,1364, +1429,1365,1430, +1366,1430,1365, +1430,1366,1431, +1367,1431,1366, +1431,1367,1432, +1368,1432,1367, +1432,1368,1433, +1369,1433,1368, +1433,1369,1434, +1370,1434,1369, +1434,1370,1435, +1371,1435,1370, +1435,1371,1436, +1372,1436,1371, +1436,1372,1437, +1373,1437,1372, +1437,1373,1438, +1374,1438,1373, +1438,1374,1439, +1375,1439,1374, +1439,1375,1440, +1376,1440,1375, +1440,1376,1441, +1377,1441,1376, +1441,1377,1442, +1378,1442,1377, +1442,1378,1443, +1379,1443,1378, +1443,1379,1444, +1380,1444,1379, +1444,1380,1445, +1381,1445,1380, +1445,1381,1446, +1382,1446,1381, +1446,1382,1447, +1383,1447,1382, +1447,1383,1448, +1384,1448,1383, +1448,1384,1449, +1385,1449,1384, +1449,1385,1450, +1386,1450,1385, +1450,1386,1451, +1387,1451,1386, +1451,1387,1452, +1388,1452,1387, +1452,1388,1453, +1389,1453,1388, +1453,1389,1454, +1390,1454,1389, +1454,1390,1455, +1391,1455,1390, +1455,1391,1456, +1392,1456,1391, +1456,1392,1457, +1393,1457,1392, +1457,1393,1458, +1394,1458,1393, +1458,1394,1459, +1395,1459,1394, +1459,1395,1460, +1396,1460,1395, +1460,1396,1461, +1397,1461,1396, +1461,1397,1462, +1398,1462,1397, +1462,1398,1463, +1399,1463,1398, +1463,1399,1464, +1400,1464,1399, +1464,1400,1465, +1401,1465,1400, +1465,1401,1466, +1402,1466,1401, +1466,1402,1467, +1403,1467,1402, +1467,1403,1468, +1404,1468,1403, +1468,1404,1469, +1405,1469,1404, +1469,1405,1470, +1406,1470,1405, +1470,1406,1471, +1407,1471,1406, +1472,1408,1473, +1409,1473,1408, +1473,1409,1474, +1410,1474,1409, +1474,1410,1475, +1411,1475,1410, +1475,1411,1476, +1412,1476,1411, +1476,1412,1477, +1413,1477,1412, +1477,1413,1478, +1414,1478,1413, +1478,1414,1479, +1415,1479,1414, +1479,1415,1480, +1416,1480,1415, +1480,1416,1481, +1417,1481,1416, +1481,1417,1482, +1418,1482,1417, +1482,1418,1483, +1419,1483,1418, +1483,1419,1484, +1420,1484,1419, +1484,1420,1485, +1421,1485,1420, +1485,1421,1486, +1422,1486,1421, +1486,1422,1487, +1423,1487,1422, +1487,1423,1488, +1424,1488,1423, +1488,1424,1489, +1425,1489,1424, +1489,1425,1490, +1426,1490,1425, +1490,1426,1491, +1427,1491,1426, +1491,1427,1492, +1428,1492,1427, +1492,1428,1493, +1429,1493,1428, +1493,1429,1494, +1430,1494,1429, +1494,1430,1495, +1431,1495,1430, +1495,1431,1496, +1432,1496,1431, +1496,1432,1497, +1433,1497,1432, +1497,1433,1498, +1434,1498,1433, +1498,1434,1499, +1435,1499,1434, +1499,1435,1500, +1436,1500,1435, +1500,1436,1501, +1437,1501,1436, +1501,1437,1502, +1438,1502,1437, +1502,1438,1503, +1439,1503,1438, +1503,1439,1504, +1440,1504,1439, +1504,1440,1505, +1441,1505,1440, +1505,1441,1506, +1442,1506,1441, +1506,1442,1507, +1443,1507,1442, +1507,1443,1508, +1444,1508,1443, +1508,1444,1509, +1445,1509,1444, +1509,1445,1510, +1446,1510,1445, +1510,1446,1511, +1447,1511,1446, +1511,1447,1512, +1448,1512,1447, +1512,1448,1513, +1449,1513,1448, +1513,1449,1514, +1450,1514,1449, +1514,1450,1515, +1451,1515,1450, +1515,1451,1516, +1452,1516,1451, +1516,1452,1517, +1453,1517,1452, +1517,1453,1518, +1454,1518,1453, +1518,1454,1519, +1455,1519,1454, +1519,1455,1520, +1456,1520,1455, +1520,1456,1521, +1457,1521,1456, +1521,1457,1522, +1458,1522,1457, +1522,1458,1523, +1459,1523,1458, +1523,1459,1524, +1460,1524,1459, +1524,1460,1525, +1461,1525,1460, +1525,1461,1526, +1462,1526,1461, +1526,1462,1527, +1463,1527,1462, +1527,1463,1528, +1464,1528,1463, +1528,1464,1529, +1465,1529,1464, +1529,1465,1530, +1466,1530,1465, +1530,1466,1531, +1467,1531,1466, +1531,1467,1532, +1468,1532,1467, +1532,1468,1533, +1469,1533,1468, +1533,1469,1534, +1470,1534,1469, +1534,1470,1535, +1471,1535,1470, +1536,1472,1537, +1473,1537,1472, +1537,1473,1538, +1474,1538,1473, +1538,1474,1539, +1475,1539,1474, +1539,1475,1540, +1476,1540,1475, +1540,1476,1541, +1477,1541,1476, +1541,1477,1542, +1478,1542,1477, +1542,1478,1543, +1479,1543,1478, +1543,1479,1544, +1480,1544,1479, +1544,1480,1545, +1481,1545,1480, +1545,1481,1546, +1482,1546,1481, +1546,1482,1547, +1483,1547,1482, +1547,1483,1548, +1484,1548,1483, +1548,1484,1549, +1485,1549,1484, +1549,1485,1550, +1486,1550,1485, +1550,1486,1551, +1487,1551,1486, +1551,1487,1552, +1488,1552,1487, +1552,1488,1553, +1489,1553,1488, +1553,1489,1554, +1490,1554,1489, +1554,1490,1555, +1491,1555,1490, +1555,1491,1556, +1492,1556,1491, +1556,1492,1557, +1493,1557,1492, +1557,1493,1558, +1494,1558,1493, +1558,1494,1559, +1495,1559,1494, +1559,1495,1560, +1496,1560,1495, +1560,1496,1561, +1497,1561,1496, +1561,1497,1562, +1498,1562,1497, +1562,1498,1563, +1499,1563,1498, +1563,1499,1564, +1500,1564,1499, +1564,1500,1565, +1501,1565,1500, +1565,1501,1566, +1502,1566,1501, +1566,1502,1567, +1503,1567,1502, +1567,1503,1568, +1504,1568,1503, +1568,1504,1569, +1505,1569,1504, +1569,1505,1570, +1506,1570,1505, +1570,1506,1571, +1507,1571,1506, +1571,1507,1572, +1508,1572,1507, +1572,1508,1573, +1509,1573,1508, +1573,1509,1574, +1510,1574,1509, +1574,1510,1575, +1511,1575,1510, +1575,1511,1576, +1512,1576,1511, +1576,1512,1577, +1513,1577,1512, +1577,1513,1578, +1514,1578,1513, +1578,1514,1579, +1515,1579,1514, +1579,1515,1580, +1516,1580,1515, +1580,1516,1581, +1517,1581,1516, +1581,1517,1582, +1518,1582,1517, +1582,1518,1583, +1519,1583,1518, +1583,1519,1584, +1520,1584,1519, +1584,1520,1585, +1521,1585,1520, +1585,1521,1586, +1522,1586,1521, +1586,1522,1587, +1523,1587,1522, +1587,1523,1588, +1524,1588,1523, +1588,1524,1589, +1525,1589,1524, +1589,1525,1590, +1526,1590,1525, +1590,1526,1591, +1527,1591,1526, +1591,1527,1592, +1528,1592,1527, +1592,1528,1593, +1529,1593,1528, +1593,1529,1594, +1530,1594,1529, +1594,1530,1595, +1531,1595,1530, +1595,1531,1596, +1532,1596,1531, +1596,1532,1597, +1533,1597,1532, +1597,1533,1598, +1534,1598,1533, +1598,1534,1599, +1535,1599,1534, +1600,1536,1601, +1537,1601,1536, +1601,1537,1602, +1538,1602,1537, +1602,1538,1603, +1539,1603,1538, +1603,1539,1604, +1540,1604,1539, +1604,1540,1605, +1541,1605,1540, +1605,1541,1606, +1542,1606,1541, +1606,1542,1607, +1543,1607,1542, +1607,1543,1608, +1544,1608,1543, +1608,1544,1609, +1545,1609,1544, +1609,1545,1610, +1546,1610,1545, +1610,1546,1611, +1547,1611,1546, +1611,1547,1612, +1548,1612,1547, +1612,1548,1613, +1549,1613,1548, +1613,1549,1614, +1550,1614,1549, +1614,1550,1615, +1551,1615,1550, +1615,1551,1616, +1552,1616,1551, +1616,1552,1617, +1553,1617,1552, +1617,1553,1618, +1554,1618,1553, +1618,1554,1619, +1555,1619,1554, +1619,1555,1620, +1556,1620,1555, +1620,1556,1621, +1557,1621,1556, +1621,1557,1622, +1558,1622,1557, +1622,1558,1623, +1559,1623,1558, +1623,1559,1624, +1560,1624,1559, +1624,1560,1625, +1561,1625,1560, +1625,1561,1626, +1562,1626,1561, +1626,1562,1627, +1563,1627,1562, +1627,1563,1628, +1564,1628,1563, +1628,1564,1629, +1565,1629,1564, +1629,1565,1630, +1566,1630,1565, +1630,1566,1631, +1567,1631,1566, +1631,1567,1632, +1568,1632,1567, +1632,1568,1633, +1569,1633,1568, +1633,1569,1634, +1570,1634,1569, +1634,1570,1635, +1571,1635,1570, +1635,1571,1636, +1572,1636,1571, +1636,1572,1637, +1573,1637,1572, +1637,1573,1638, +1574,1638,1573, +1638,1574,1639, +1575,1639,1574, +1639,1575,1640, +1576,1640,1575, +1640,1576,1641, +1577,1641,1576, +1641,1577,1642, +1578,1642,1577, +1642,1578,1643, +1579,1643,1578, +1643,1579,1644, +1580,1644,1579, +1644,1580,1645, +1581,1645,1580, +1645,1581,1646, +1582,1646,1581, +1646,1582,1647, +1583,1647,1582, +1647,1583,1648, +1584,1648,1583, +1648,1584,1649, +1585,1649,1584, +1649,1585,1650, +1586,1650,1585, +1650,1586,1651, +1587,1651,1586, +1651,1587,1652, +1588,1652,1587, +1652,1588,1653, +1589,1653,1588, +1653,1589,1654, +1590,1654,1589, +1654,1590,1655, +1591,1655,1590, +1655,1591,1656, +1592,1656,1591, +1656,1592,1657, +1593,1657,1592, +1657,1593,1658, +1594,1658,1593, +1658,1594,1659, +1595,1659,1594, +1659,1595,1660, +1596,1660,1595, +1660,1596,1661, +1597,1661,1596, +1661,1597,1662, +1598,1662,1597, +1662,1598,1663, +1599,1663,1598, +1664,1600,1665, +1601,1665,1600, +1665,1601,1666, +1602,1666,1601, +1666,1602,1667, +1603,1667,1602, +1667,1603,1668, +1604,1668,1603, +1668,1604,1669, +1605,1669,1604, +1669,1605,1670, +1606,1670,1605, +1670,1606,1671, +1607,1671,1606, +1671,1607,1672, +1608,1672,1607, +1672,1608,1673, +1609,1673,1608, +1673,1609,1674, +1610,1674,1609, +1674,1610,1675, +1611,1675,1610, +1675,1611,1676, +1612,1676,1611, +1676,1612,1677, +1613,1677,1612, +1677,1613,1678, +1614,1678,1613, +1678,1614,1679, +1615,1679,1614, +1679,1615,1680, +1616,1680,1615, +1680,1616,1681, +1617,1681,1616, +1681,1617,1682, +1618,1682,1617, +1682,1618,1683, +1619,1683,1618, +1683,1619,1684, +1620,1684,1619, +1684,1620,1685, +1621,1685,1620, +1685,1621,1686, +1622,1686,1621, +1686,1622,1687, +1623,1687,1622, +1687,1623,1688, +1624,1688,1623, +1688,1624,1689, +1625,1689,1624, +1689,1625,1690, +1626,1690,1625, +1690,1626,1691, +1627,1691,1626, +1691,1627,1692, +1628,1692,1627, +1692,1628,1693, +1629,1693,1628, +1693,1629,1694, +1630,1694,1629, +1694,1630,1695, +1631,1695,1630, +1695,1631,1696, +1632,1696,1631, +1696,1632,1697, +1633,1697,1632, +1697,1633,1698, +1634,1698,1633, +1698,1634,1699, +1635,1699,1634, +1699,1635,1700, +1636,1700,1635, +1700,1636,1701, +1637,1701,1636, +1701,1637,1702, +1638,1702,1637, +1702,1638,1703, +1639,1703,1638, +1703,1639,1704, +1640,1704,1639, +1704,1640,1705, +1641,1705,1640, +1705,1641,1706, +1642,1706,1641, +1706,1642,1707, +1643,1707,1642, +1707,1643,1708, +1644,1708,1643, +1708,1644,1709, +1645,1709,1644, +1709,1645,1710, +1646,1710,1645, +1710,1646,1711, +1647,1711,1646, +1711,1647,1712, +1648,1712,1647, +1712,1648,1713, +1649,1713,1648, +1713,1649,1714, +1650,1714,1649, +1714,1650,1715, +1651,1715,1650, +1715,1651,1716, +1652,1716,1651, +1716,1652,1717, +1653,1717,1652, +1717,1653,1718, +1654,1718,1653, +1718,1654,1719, +1655,1719,1654, +1719,1655,1720, +1656,1720,1655, +1720,1656,1721, +1657,1721,1656, +1721,1657,1722, +1658,1722,1657, +1722,1658,1723, +1659,1723,1658, +1723,1659,1724, +1660,1724,1659, +1724,1660,1725, +1661,1725,1660, +1725,1661,1726, +1662,1726,1661, +1726,1662,1727, +1663,1727,1662, +1728,1664,1729, +1665,1729,1664, +1729,1665,1730, +1666,1730,1665, +1730,1666,1731, +1667,1731,1666, +1731,1667,1732, +1668,1732,1667, +1732,1668,1733, +1669,1733,1668, +1733,1669,1734, +1670,1734,1669, +1734,1670,1735, +1671,1735,1670, +1735,1671,1736, +1672,1736,1671, +1736,1672,1737, +1673,1737,1672, +1737,1673,1738, +1674,1738,1673, +1738,1674,1739, +1675,1739,1674, +1739,1675,1740, +1676,1740,1675, +1740,1676,1741, +1677,1741,1676, +1741,1677,1742, +1678,1742,1677, +1742,1678,1743, +1679,1743,1678, +1743,1679,1744, +1680,1744,1679, +1744,1680,1745, +1681,1745,1680, +1745,1681,1746, +1682,1746,1681, +1746,1682,1747, +1683,1747,1682, +1747,1683,1748, +1684,1748,1683, +1748,1684,1749, +1685,1749,1684, +1749,1685,1750, +1686,1750,1685, +1750,1686,1751, +1687,1751,1686, +1751,1687,1752, +1688,1752,1687, +1752,1688,1753, +1689,1753,1688, +1753,1689,1754, +1690,1754,1689, +1754,1690,1755, +1691,1755,1690, +1755,1691,1756, +1692,1756,1691, +1756,1692,1757, +1693,1757,1692, +1757,1693,1758, +1694,1758,1693, +1758,1694,1759, +1695,1759,1694, +1759,1695,1760, +1696,1760,1695, +1760,1696,1761, +1697,1761,1696, +1761,1697,1762, +1698,1762,1697, +1762,1698,1763, +1699,1763,1698, +1763,1699,1764, +1700,1764,1699, +1764,1700,1765, +1701,1765,1700, +1765,1701,1766, +1702,1766,1701, +1766,1702,1767, +1703,1767,1702, +1767,1703,1768, +1704,1768,1703, +1768,1704,1769, +1705,1769,1704, +1769,1705,1770, +1706,1770,1705, +1770,1706,1771, +1707,1771,1706, +1771,1707,1772, +1708,1772,1707, +1772,1708,1773, +1709,1773,1708, +1773,1709,1774, +1710,1774,1709, +1774,1710,1775, +1711,1775,1710, +1775,1711,1776, +1712,1776,1711, +1776,1712,1777, +1713,1777,1712, +1777,1713,1778, +1714,1778,1713, +1778,1714,1779, +1715,1779,1714, +1779,1715,1780, +1716,1780,1715, +1780,1716,1781, +1717,1781,1716, +1781,1717,1782, +1718,1782,1717, +1782,1718,1783, +1719,1783,1718, +1783,1719,1784, +1720,1784,1719, +1784,1720,1785, +1721,1785,1720, +1785,1721,1786, +1722,1786,1721, +1786,1722,1787, +1723,1787,1722, +1787,1723,1788, +1724,1788,1723, +1788,1724,1789, +1725,1789,1724, +1789,1725,1790, +1726,1790,1725, +1790,1726,1791, +1727,1791,1726, +1792,1728,1793, +1729,1793,1728, +1793,1729,1794, +1730,1794,1729, +1794,1730,1795, +1731,1795,1730, +1795,1731,1796, +1732,1796,1731, +1796,1732,1797, +1733,1797,1732, +1797,1733,1798, +1734,1798,1733, +1798,1734,1799, +1735,1799,1734, +1799,1735,1800, +1736,1800,1735, +1800,1736,1801, +1737,1801,1736, +1801,1737,1802, +1738,1802,1737, +1802,1738,1803, +1739,1803,1738, +1803,1739,1804, +1740,1804,1739, +1804,1740,1805, +1741,1805,1740, +1805,1741,1806, +1742,1806,1741, +1806,1742,1807, +1743,1807,1742, +1807,1743,1808, +1744,1808,1743, +1808,1744,1809, +1745,1809,1744, +1809,1745,1810, +1746,1810,1745, +1810,1746,1811, +1747,1811,1746, +1811,1747,1812, +1748,1812,1747, +1812,1748,1813, +1749,1813,1748, +1813,1749,1814, +1750,1814,1749, +1814,1750,1815, +1751,1815,1750, +1815,1751,1816, +1752,1816,1751, +1816,1752,1817, +1753,1817,1752, +1817,1753,1818, +1754,1818,1753, +1818,1754,1819, +1755,1819,1754, +1819,1755,1820, +1756,1820,1755, +1820,1756,1821, +1757,1821,1756, +1821,1757,1822, +1758,1822,1757, +1822,1758,1823, +1759,1823,1758, +1823,1759,1824, +1760,1824,1759, +1824,1760,1825, +1761,1825,1760, +1825,1761,1826, +1762,1826,1761, +1826,1762,1827, +1763,1827,1762, +1827,1763,1828, +1764,1828,1763, +1828,1764,1829, +1765,1829,1764, +1829,1765,1830, +1766,1830,1765, +1830,1766,1831, +1767,1831,1766, +1831,1767,1832, +1768,1832,1767, +1832,1768,1833, +1769,1833,1768, +1833,1769,1834, +1770,1834,1769, +1834,1770,1835, +1771,1835,1770, +1835,1771,1836, +1772,1836,1771, +1836,1772,1837, +1773,1837,1772, +1837,1773,1838, +1774,1838,1773, +1838,1774,1839, +1775,1839,1774, +1839,1775,1840, +1776,1840,1775, +1840,1776,1841, +1777,1841,1776, +1841,1777,1842, +1778,1842,1777, +1842,1778,1843, +1779,1843,1778, +1843,1779,1844, +1780,1844,1779, +1844,1780,1845, +1781,1845,1780, +1845,1781,1846, +1782,1846,1781, +1846,1782,1847, +1783,1847,1782, +1847,1783,1848, +1784,1848,1783, +1848,1784,1849, +1785,1849,1784, +1849,1785,1850, +1786,1850,1785, +1850,1786,1851, +1787,1851,1786, +1851,1787,1852, +1788,1852,1787, +1852,1788,1853, +1789,1853,1788, +1853,1789,1854, +1790,1854,1789, +1854,1790,1855, +1791,1855,1790, +1856,1792,1857, +1793,1857,1792, +1857,1793,1858, +1794,1858,1793, +1858,1794,1859, +1795,1859,1794, +1859,1795,1860, +1796,1860,1795, +1860,1796,1861, +1797,1861,1796, +1861,1797,1862, +1798,1862,1797, +1862,1798,1863, +1799,1863,1798, +1863,1799,1864, +1800,1864,1799, +1864,1800,1865, +1801,1865,1800, +1865,1801,1866, +1802,1866,1801, +1866,1802,1867, +1803,1867,1802, +1867,1803,1868, +1804,1868,1803, +1868,1804,1869, +1805,1869,1804, +1869,1805,1870, +1806,1870,1805, +1870,1806,1871, +1807,1871,1806, +1871,1807,1872, +1808,1872,1807, +1872,1808,1873, +1809,1873,1808, +1873,1809,1874, +1810,1874,1809, +1874,1810,1875, +1811,1875,1810, +1875,1811,1876, +1812,1876,1811, +1876,1812,1877, +1813,1877,1812, +1877,1813,1878, +1814,1878,1813, +1878,1814,1879, +1815,1879,1814, +1879,1815,1880, +1816,1880,1815, +1880,1816,1881, +1817,1881,1816, +1881,1817,1882, +1818,1882,1817, +1882,1818,1883, +1819,1883,1818, +1883,1819,1884, +1820,1884,1819, +1884,1820,1885, +1821,1885,1820, +1885,1821,1886, +1822,1886,1821, +1886,1822,1887, +1823,1887,1822, +1887,1823,1888, +1824,1888,1823, +1888,1824,1889, +1825,1889,1824, +1889,1825,1890, +1826,1890,1825, +1890,1826,1891, +1827,1891,1826, +1891,1827,1892, +1828,1892,1827, +1892,1828,1893, +1829,1893,1828, +1893,1829,1894, +1830,1894,1829, +1894,1830,1895, +1831,1895,1830, +1895,1831,1896, +1832,1896,1831, +1896,1832,1897, +1833,1897,1832, +1897,1833,1898, +1834,1898,1833, +1898,1834,1899, +1835,1899,1834, +1899,1835,1900, +1836,1900,1835, +1900,1836,1901, +1837,1901,1836, +1901,1837,1902, +1838,1902,1837, +1902,1838,1903, +1839,1903,1838, +1903,1839,1904, +1840,1904,1839, +1904,1840,1905, +1841,1905,1840, +1905,1841,1906, +1842,1906,1841, +1906,1842,1907, +1843,1907,1842, +1907,1843,1908, +1844,1908,1843, +1908,1844,1909, +1845,1909,1844, +1909,1845,1910, +1846,1910,1845, +1910,1846,1911, +1847,1911,1846, +1911,1847,1912, +1848,1912,1847, +1912,1848,1913, +1849,1913,1848, +1913,1849,1914, +1850,1914,1849, +1914,1850,1915, +1851,1915,1850, +1915,1851,1916, +1852,1916,1851, +1916,1852,1917, +1853,1917,1852, +1917,1853,1918, +1854,1918,1853, +1918,1854,1919, +1855,1919,1854, +1920,1856,1921, +1857,1921,1856, +1921,1857,1922, +1858,1922,1857, +1922,1858,1923, +1859,1923,1858, +1923,1859,1924, +1860,1924,1859, +1924,1860,1925, +1861,1925,1860, +1925,1861,1926, +1862,1926,1861, +1926,1862,1927, +1863,1927,1862, +1927,1863,1928, +1864,1928,1863, +1928,1864,1929, +1865,1929,1864, +1929,1865,1930, +1866,1930,1865, +1930,1866,1931, +1867,1931,1866, +1931,1867,1932, +1868,1932,1867, +1932,1868,1933, +1869,1933,1868, +1933,1869,1934, +1870,1934,1869, +1934,1870,1935, +1871,1935,1870, +1935,1871,1936, +1872,1936,1871, +1936,1872,1937, +1873,1937,1872, +1937,1873,1938, +1874,1938,1873, +1938,1874,1939, +1875,1939,1874, +1939,1875,1940, +1876,1940,1875, +1940,1876,1941, +1877,1941,1876, +1941,1877,1942, +1878,1942,1877, +1942,1878,1943, +1879,1943,1878, +1943,1879,1944, +1880,1944,1879, +1944,1880,1945, +1881,1945,1880, +1945,1881,1946, +1882,1946,1881, +1946,1882,1947, +1883,1947,1882, +1947,1883,1948, +1884,1948,1883, +1948,1884,1949, +1885,1949,1884, +1949,1885,1950, +1886,1950,1885, +1950,1886,1951, +1887,1951,1886, +1951,1887,1952, +1888,1952,1887, +1952,1888,1953, +1889,1953,1888, +1953,1889,1954, +1890,1954,1889, +1954,1890,1955, +1891,1955,1890, +1955,1891,1956, +1892,1956,1891, +1956,1892,1957, +1893,1957,1892, +1957,1893,1958, +1894,1958,1893, +1958,1894,1959, +1895,1959,1894, +1959,1895,1960, +1896,1960,1895, +1960,1896,1961, +1897,1961,1896, +1961,1897,1962, +1898,1962,1897, +1962,1898,1963, +1899,1963,1898, +1963,1899,1964, +1900,1964,1899, +1964,1900,1965, +1901,1965,1900, +1965,1901,1966, +1902,1966,1901, +1966,1902,1967, +1903,1967,1902, +1967,1903,1968, +1904,1968,1903, +1968,1904,1969, +1905,1969,1904, +1969,1905,1970, +1906,1970,1905, +1970,1906,1971, +1907,1971,1906, +1971,1907,1972, +1908,1972,1907, +1972,1908,1973, +1909,1973,1908, +1973,1909,1974, +1910,1974,1909, +1974,1910,1975, +1911,1975,1910, +1975,1911,1976, +1912,1976,1911, +1976,1912,1977, +1913,1977,1912, +1977,1913,1978, +1914,1978,1913, +1978,1914,1979, +1915,1979,1914, +1979,1915,1980, +1916,1980,1915, +1980,1916,1981, +1917,1981,1916, +1981,1917,1982, +1918,1982,1917, +1982,1918,1983, +1919,1983,1918, +1984,1920,1985, +1921,1985,1920, +1985,1921,1986, +1922,1986,1921, +1986,1922,1987, +1923,1987,1922, +1987,1923,1988, +1924,1988,1923, +1988,1924,1989, +1925,1989,1924, +1989,1925,1990, +1926,1990,1925, +1990,1926,1991, +1927,1991,1926, +1991,1927,1992, +1928,1992,1927, +1992,1928,1993, +1929,1993,1928, +1993,1929,1994, +1930,1994,1929, +1994,1930,1995, +1931,1995,1930, +1995,1931,1996, +1932,1996,1931, +1996,1932,1997, +1933,1997,1932, +1997,1933,1998, +1934,1998,1933, +1998,1934,1999, +1935,1999,1934, +1999,1935,2000, +1936,2000,1935, +2000,1936,2001, +1937,2001,1936, +2001,1937,2002, +1938,2002,1937, +2002,1938,2003, +1939,2003,1938, +2003,1939,2004, +1940,2004,1939, +2004,1940,2005, +1941,2005,1940, +2005,1941,2006, +1942,2006,1941, +2006,1942,2007, +1943,2007,1942, +2007,1943,2008, +1944,2008,1943, +2008,1944,2009, +1945,2009,1944, +2009,1945,2010, +1946,2010,1945, +2010,1946,2011, +1947,2011,1946, +2011,1947,2012, +1948,2012,1947, +2012,1948,2013, +1949,2013,1948, +2013,1949,2014, +1950,2014,1949, +2014,1950,2015, +1951,2015,1950, +2015,1951,2016, +1952,2016,1951, +2016,1952,2017, +1953,2017,1952, +2017,1953,2018, +1954,2018,1953, +2018,1954,2019, +1955,2019,1954, +2019,1955,2020, +1956,2020,1955, +2020,1956,2021, +1957,2021,1956, +2021,1957,2022, +1958,2022,1957, +2022,1958,2023, +1959,2023,1958, +2023,1959,2024, +1960,2024,1959, +2024,1960,2025, +1961,2025,1960, +2025,1961,2026, +1962,2026,1961, +2026,1962,2027, +1963,2027,1962, +2027,1963,2028, +1964,2028,1963, +2028,1964,2029, +1965,2029,1964, +2029,1965,2030, +1966,2030,1965, +2030,1966,2031, +1967,2031,1966, +2031,1967,2032, +1968,2032,1967, +2032,1968,2033, +1969,2033,1968, +2033,1969,2034, +1970,2034,1969, +2034,1970,2035, +1971,2035,1970, +2035,1971,2036, +1972,2036,1971, +2036,1972,2037, +1973,2037,1972, +2037,1973,2038, +1974,2038,1973, +2038,1974,2039, +1975,2039,1974, +2039,1975,2040, +1976,2040,1975, +2040,1976,2041, +1977,2041,1976, +2041,1977,2042, +1978,2042,1977, +2042,1978,2043, +1979,2043,1978, +2043,1979,2044, +1980,2044,1979, +2044,1980,2045, +1981,2045,1980, +2045,1981,2046, +1982,2046,1981, +2046,1982,2047, +1983,2047,1982, +2048,1984,2049, +1985,2049,1984, +2049,1985,2050, +1986,2050,1985, +2050,1986,2051, +1987,2051,1986, +2051,1987,2052, +1988,2052,1987, +2052,1988,2053, +1989,2053,1988, +2053,1989,2054, +1990,2054,1989, +2054,1990,2055, +1991,2055,1990, +2055,1991,2056, +1992,2056,1991, +2056,1992,2057, +1993,2057,1992, +2057,1993,2058, +1994,2058,1993, +2058,1994,2059, +1995,2059,1994, +2059,1995,2060, +1996,2060,1995, +2060,1996,2061, +1997,2061,1996, +2061,1997,2062, +1998,2062,1997, +2062,1998,2063, +1999,2063,1998, +2063,1999,2064, +2000,2064,1999, +2064,2000,2065, +2001,2065,2000, +2065,2001,2066, +2002,2066,2001, +2066,2002,2067, +2003,2067,2002, +2067,2003,2068, +2004,2068,2003, +2068,2004,2069, +2005,2069,2004, +2069,2005,2070, +2006,2070,2005, +2070,2006,2071, +2007,2071,2006, +2071,2007,2072, +2008,2072,2007, +2072,2008,2073, +2009,2073,2008, +2073,2009,2074, +2010,2074,2009, +2074,2010,2075, +2011,2075,2010, +2075,2011,2076, +2012,2076,2011, +2076,2012,2077, +2013,2077,2012, +2077,2013,2078, +2014,2078,2013, +2078,2014,2079, +2015,2079,2014, +2079,2015,2080, +2016,2080,2015, +2080,2016,2081, +2017,2081,2016, +2081,2017,2082, +2018,2082,2017, +2082,2018,2083, +2019,2083,2018, +2083,2019,2084, +2020,2084,2019, +2084,2020,2085, +2021,2085,2020, +2085,2021,2086, +2022,2086,2021, +2086,2022,2087, +2023,2087,2022, +2087,2023,2088, +2024,2088,2023, +2088,2024,2089, +2025,2089,2024, +2089,2025,2090, +2026,2090,2025, +2090,2026,2091, +2027,2091,2026, +2091,2027,2092, +2028,2092,2027, +2092,2028,2093, +2029,2093,2028, +2093,2029,2094, +2030,2094,2029, +2094,2030,2095, +2031,2095,2030, +2095,2031,2096, +2032,2096,2031, +2096,2032,2097, +2033,2097,2032, +2097,2033,2098, +2034,2098,2033, +2098,2034,2099, +2035,2099,2034, +2099,2035,2100, +2036,2100,2035, +2100,2036,2101, +2037,2101,2036, +2101,2037,2102, +2038,2102,2037, +2102,2038,2103, +2039,2103,2038, +2103,2039,2104, +2040,2104,2039, +2104,2040,2105, +2041,2105,2040, +2105,2041,2106, +2042,2106,2041, +2106,2042,2107, +2043,2107,2042, +2107,2043,2108, +2044,2108,2043, +2108,2044,2109, +2045,2109,2044, +2109,2045,2110, +2046,2110,2045, +2110,2046,2111, +2047,2111,2046, +}; + +#define Landscape05VtxCount 2244 +#define Landscape05IdxCount 12870 + +btScalar Landscape05Vtx[] = { +-250.0f,-0.990273f,0.0f, +-250.0f,0.139875f,3.90625f, +-246.094f,0.671004f,0.0f, +-246.094f,1.72995f,3.90625f, +-242.188f,1.84097f,0.0f, +-242.188f,2.60122f,3.90625f, +-238.281f,3.67319f,-1.6056e-007f, +-238.281f,4.01346f,3.90625f, +-234.375f,4.96849f,-2.1718e-007f, +-234.375f,5.13654f,3.90625f, +-230.469f,6.56215f,-2.86841e-007f, +-230.469f,6.69665f,3.90625f, +-226.563f,8.30102f,-3.62849e-007f, +-226.563f,8.43203f,3.90625f, +-222.656f,9.94385f,-4.3466e-007f, +-222.656f,9.83442f,3.90625f, +-218.75f,11.5986f,-5.06992e-007f, +-218.75f,11.3645f,3.90625f, +-214.844f,14.3141f,-6.2569e-007f, +-214.844f,14.222f,3.90625f, +-210.938f,16.5538f,-7.2359e-007f, +-210.938f,16.1758f,3.90625f, +-207.031f,18.852f,-8.24046e-007f, +-207.031f,18.9127f,3.90625f, +-203.125f,21.5344f,-9.41301e-007f, +-203.125f,21.2478f,3.90625f, +-199.219f,22.7337f,-9.93723e-007f, +-199.219f,23.0589f,3.90625f, +-195.313f,24.4712f,-1.06967e-006f, +-195.313f,24.6025f,3.90625f, +-191.406f,26.1169f,-1.14161e-006f, +-191.406f,25.8143f,3.90625f, +-187.5f,26.9988f,-1.18015e-006f, +-187.5f,27.5696f,3.90625f, +-183.594f,28.3854f,-1.24077e-006f, +-183.594f,29.2176f,3.90625f, +-179.688f,29.0457f,-1.26963e-006f, +-179.688f,29.6835f,3.90625f, +-175.781f,29.802f,-1.30269e-006f, +-175.781f,30.7416f,3.90625f, +-171.875f,30.1559f,-1.31816e-006f, +-171.875f,31.4405f,3.90625f, +-167.969f,32.3708f,-1.41497e-006f, +-167.969f,33.0831f,3.90625f, +-164.063f,34.9705f,-1.52861e-006f, +-164.063f,34.6225f,3.90625f, +-160.156f,36.396f,-1.59092e-006f, +-160.156f,35.4992f,3.90625f, +-156.25f,37.2947f,-1.6302e-006f, +-156.25f,37.4126f,3.90625f, +-152.344f,38.248f,-1.67187e-006f, +-152.344f,38.453f,3.90625f, +-148.438f,38.3176f,-1.67491e-006f, +-148.438f,38.9974f,3.90625f, +-144.531f,38.1589f,-1.66798e-006f, +-144.531f,38.7871f,3.90625f, +-140.625f,36.5895f,-1.59938e-006f, +-140.625f,37.6021f,3.90625f, +-136.719f,35.718f,-1.56128e-006f, +-136.719f,36.1797f,3.90625f, +-132.813f,33.7519f,-1.47534e-006f, +-132.813f,34.9906f,3.90625f, +-128.906f,33.2853f,-1.45495e-006f, +-128.906f,34.1304f,3.90625f, +-125.0f,33.4003f,-1.45997e-006f, +-125.0f,34.3517f,3.90625f, +-121.094f,33.1132f,-1.44742e-006f, +-121.094f,33.6612f,3.90625f, +-117.188f,32.7861f,-1.43313e-006f, +-117.188f,32.7047f,3.90625f, +-113.281f,33.0037f,-1.44264e-006f, +-113.281f,32.3958f,3.90625f, +-109.375f,32.508f,-1.42097e-006f, +-109.375f,31.0818f,3.90625f, +-105.469f,31.8384f,-1.3917e-006f, +-105.469f,30.9536f,3.90625f, +-101.563f,31.1858f,-1.36317e-006f, +-101.563f,29.8205f,3.90625f, +-97.6563f,29.6739f,-1.29709e-006f, +-97.6563f,28.4796f,3.90625f, +-93.75f,27.8258f,-1.2163e-006f, +-93.75f,27.6494f,3.90625f, +-89.8438f,25.9046f,-1.13232e-006f, +-89.8438f,25.5721f,3.90625f, +-85.9375f,23.4229f,-1.02385e-006f, +-85.9375f,24.227f,3.90625f, +-82.0313f,23.3671f,-1.02141e-006f, +-82.0313f,23.2611f,3.90625f, +-78.125f,23.0585f,-1.00792e-006f, +-78.125f,22.4589f,3.90625f, +-74.2188f,23.9226f,-1.04569e-006f, +-74.2188f,23.2261f,3.90625f, +-70.3125f,23.6449f,-1.03355e-006f, +-70.3125f,23.5025f,3.90625f, +-66.4063f,23.2789f,-1.01755e-006f, +-66.4063f,23.6913f,3.90625f, +-62.5f,24.5841f,-1.07461e-006f, +-62.5f,24.6785f,3.90625f, +-58.5938f,25.71f,-1.12382e-006f, +-58.5938f,25.4946f,3.90625f, +-54.6875f,26.9872f,-1.17965e-006f, +-54.6875f,25.9722f,3.90625f, +-50.7813f,27.8632f,-1.21794e-006f, +-50.7813f,26.1977f,3.90625f, +-46.875f,28.0326f,-1.22534e-006f, +-46.875f,26.8539f,3.90625f, +-42.9688f,28.0866f,-1.2277e-006f, +-42.9688f,27.7268f,3.90625f, +-39.0625f,30.1482f,-1.31782e-006f, +-39.0625f,29.2046f,3.90625f, +-35.1563f,32.4049f,-1.41646e-006f, +-35.1563f,31.79f,3.90625f, +-31.25f,34.4714f,-1.50679e-006f, +-31.25f,34.2658f,3.90625f, +-27.3438f,37.2668f,-1.62898e-006f, +-27.3438f,35.9914f,3.90625f, +-23.4375f,38.7934f,-1.69571e-006f, +-23.4375f,38.3776f,3.90625f, +-19.5313f,40.4024f,-1.76605e-006f, +-19.5313f,39.8852f,3.90625f, +-15.625f,42.8177f,-1.87162e-006f, +-15.625f,43.1455f,3.90625f, +-11.7188f,45.0198f,-1.96788e-006f, +-11.7188f,45.5059f,3.90625f, +-7.8125f,46.7349f,-2.04285e-006f, +-7.8125f,47.4257f,3.90625f, +-3.90625f,48.376f,-2.11458e-006f, +-3.90625f,49.9032f,3.90625f, +0.0f,49.9016f,-2.18127e-006f, +0.0f,52.0322f,3.90625f, +3.90625f,50.3865f,-2.20246e-006f, +3.90625f,52.6186f,3.90625f, +-250.0f,-0.818988f,-3.90625f, +-246.094f,0.671433f,-3.90625f, +-242.188f,2.83415f,-3.90625f, +-238.281f,4.19978f,-3.90625f, +-234.375f,5.59158f,-3.90625f, +-230.469f,6.94041f,-3.90625f, +-226.563f,8.34599f,-3.90625f, +-222.656f,9.85416f,-3.90625f, +-218.75f,10.8989f,-3.90625f, +-214.844f,13.6339f,-3.90625f, +-210.938f,16.5116f,-3.90625f, +-207.031f,17.7111f,-3.90625f, +-203.125f,20.7442f,-3.90625f, +-199.219f,22.5356f,-3.90625f, +-195.313f,24.3988f,-3.90625f, +-191.406f,25.8062f,-3.90625f, +-187.5f,26.9714f,-3.90625f, +-183.594f,27.7397f,-3.90625f, +-179.688f,28.8632f,-3.90625f, +-175.781f,29.9688f,-3.90625f, +-171.875f,32.154f,-3.90625f, +-167.969f,33.3799f,-3.90625f, +-164.063f,35.3882f,-3.90625f, +-160.156f,35.9765f,-3.90625f, +-156.25f,36.5306f,-3.90625f, +-152.344f,37.3214f,-3.90625f, +-148.438f,36.8126f,-3.90625f, +-144.531f,36.5407f,-3.90625f, +-140.625f,35.696f,-3.90625f, +-136.719f,35.1152f,-3.90625f, +-132.813f,34.1963f,-3.90625f, +-128.906f,34.0796f,-3.90625f, +-125.0f,34.2398f,-3.90625f, +-121.094f,34.1503f,-3.90625f, +-117.188f,33.7958f,-3.90625f, +-113.281f,33.856f,-3.90625f, +-109.375f,33.2705f,-3.90625f, +-105.469f,32.5804f,-3.90625f, +-101.563f,31.911f,-3.90625f, +-97.6563f,30.3705f,-3.90625f, +-93.75f,29.0627f,-3.90625f, +-89.8438f,26.6822f,-3.90625f, +-85.9375f,24.8309f,-3.90625f, +-82.0313f,23.8581f,-3.90625f, +-78.125f,23.3764f,-3.90625f, +-74.2188f,23.9582f,-3.90625f, +-70.3125f,24.13f,-3.90625f, +-66.4063f,24.4426f,-3.90625f, +-62.5f,25.5839f,-3.90625f, +-58.5938f,26.6899f,-3.90625f, +-54.6875f,27.9086f,-3.90625f, +-50.7813f,28.5131f,-3.90625f, +-46.875f,29.2612f,-3.90625f, +-42.9688f,29.4581f,-3.90625f, +-39.0625f,30.8972f,-3.90625f, +-35.1563f,32.9085f,-3.90625f, +-31.25f,34.9204f,-3.90625f, +-27.3438f,37.7223f,-3.90625f, +-23.4375f,38.921f,-3.90625f, +-19.5313f,40.2983f,-3.90625f, +-15.625f,41.7689f,-3.90625f, +-11.7188f,43.8388f,-3.90625f, +-7.8125f,44.7599f,-3.90625f, +-3.90625f,46.53f,-3.90625f, +0.0f,48.2498f,-3.90625f, +3.90625f,48.8559f,-3.90625f, +-250.0f,0.432867f,-7.8125f, +-246.094f,1.93096f,-7.8125f, +-242.188f,3.28774f,-7.8125f, +-238.281f,4.53112f,-7.8125f, +-234.375f,5.67699f,-7.8125f, +-230.469f,7.34068f,-7.8125f, +-226.563f,8.48553f,-7.8125f, +-222.656f,10.127f,-7.8125f, +-218.75f,11.3267f,-7.8125f, +-214.844f,13.3914f,-7.8125f, +-210.938f,15.5197f,-7.8125f, +-207.031f,17.9403f,-7.8125f, +-203.125f,20.5644f,-7.8125f, +-199.219f,22.8796f,-7.8125f, +-195.313f,23.715f,-7.8125f, +-191.406f,26.1312f,-7.8125f, +-187.5f,28.0754f,-7.8125f, +-183.594f,29.1199f,-7.8125f, +-179.688f,29.5774f,-7.8125f, +-175.781f,30.2676f,-7.8125f, +-171.875f,31.8275f,-7.8125f, +-167.969f,33.4969f,-7.8125f, +-164.063f,34.4445f,-7.8125f, +-160.156f,35.3881f,-7.8125f, +-156.25f,36.0267f,-7.8125f, +-152.344f,36.1221f,-7.8125f, +-148.438f,36.7707f,-7.8125f, +-144.531f,36.3067f,-7.8125f, +-140.625f,36.2295f,-7.8125f, +-136.719f,35.6858f,-7.8125f, +-132.813f,34.6232f,-7.8125f, +-128.906f,34.1675f,-7.8125f, +-125.0f,34.1756f,-7.8125f, +-121.094f,33.6453f,-7.8125f, +-117.188f,34.2516f,-7.8125f, +-113.281f,34.228f,-7.8125f, +-109.375f,34.253f,-7.8125f, +-105.469f,33.1798f,-7.8125f, +-101.563f,32.238f,-7.8125f, +-97.6563f,31.0377f,-7.8125f, +-93.75f,29.6795f,-7.8125f, +-89.8438f,27.5934f,-7.8125f, +-85.9375f,25.7426f,-7.8125f, +-82.0313f,24.4001f,-7.8125f, +-78.125f,24.4095f,-7.8125f, +-74.2188f,25.1494f,-7.8125f, +-70.3125f,25.0193f,-7.8125f, +-66.4063f,25.3902f,-7.8125f, +-62.5f,25.8612f,-7.8125f, +-58.5938f,26.8169f,-7.8125f, +-54.6875f,28.0698f,-7.8125f, +-50.7813f,28.978f,-7.8125f, +-46.875f,29.1063f,-7.8125f, +-42.9688f,30.6071f,-7.8125f, +-39.0625f,31.7015f,-7.8125f, +-35.1563f,32.6112f,-7.8125f, +-31.25f,34.6006f,-7.8125f, +-27.3438f,36.3005f,-7.8125f, +-23.4375f,38.4757f,-7.8125f, +-19.5313f,39.7014f,-7.8125f, +-15.625f,40.7762f,-7.8125f, +-11.7188f,42.6458f,-7.8125f, +-7.8125f,45.0307f,-7.8125f, +-3.90625f,47.2861f,-7.8125f, +0.0f,48.5591f,-7.8125f, +3.90625f,48.7225f,-7.8125f, +-250.0f,0.568294f,-11.7188f, +-246.094f,1.83097f,-11.7188f, +-242.188f,3.32037f,-11.7188f, +-238.281f,4.29184f,-11.7188f, +-234.375f,6.04113f,-11.7188f, +-230.469f,7.01872f,-11.7188f, +-226.563f,8.96731f,-11.7188f, +-222.656f,10.3749f,-11.7188f, +-218.75f,11.568f,-11.7188f, +-214.844f,13.9092f,-11.7188f, +-210.938f,15.6547f,-11.7188f, +-207.031f,18.2156f,-11.7188f, +-203.125f,20.0116f,-11.7188f, +-199.219f,21.5443f,-11.7188f, +-195.313f,23.4553f,-11.7188f, +-191.406f,26.2778f,-11.7188f, +-187.5f,28.0543f,-11.7188f, +-183.594f,29.2657f,-11.7188f, +-179.688f,29.6454f,-11.7188f, +-175.781f,30.699f,-11.7188f, +-171.875f,30.8229f,-11.7188f, +-167.969f,32.9874f,-11.7188f, +-164.063f,33.581f,-11.7188f, +-160.156f,34.6365f,-11.7188f, +-156.25f,35.6153f,-11.7188f, +-152.344f,36.2491f,-11.7188f, +-148.438f,36.2996f,-11.7188f, +-144.531f,36.5456f,-11.7188f, +-140.625f,36.3803f,-11.7188f, +-136.719f,35.2403f,-11.7188f, +-132.813f,34.0595f,-11.7188f, +-128.906f,34.1384f,-11.7188f, +-125.0f,33.59f,-11.7188f, +-121.094f,33.7745f,-11.7188f, +-117.188f,33.7284f,-11.7188f, +-113.281f,33.7013f,-11.7188f, +-109.375f,33.6335f,-11.7188f, +-105.469f,33.2451f,-11.7188f, +-101.563f,32.8691f,-11.7188f, +-97.6563f,31.1343f,-11.7188f, +-93.75f,29.5843f,-11.7188f, +-89.8438f,27.5891f,-11.7188f, +-85.9375f,25.75f,-11.7188f, +-82.0313f,25.4336f,-11.7188f, +-78.125f,25.6207f,-11.7188f, +-74.2188f,25.1627f,-11.7188f, +-70.3125f,25.542f,-11.7188f, +-66.4063f,25.5384f,-11.7188f, +-62.5f,25.9238f,-11.7188f, +-58.5938f,26.0718f,-11.7188f, +-54.6875f,27.4395f,-11.7188f, +-50.7813f,28.8032f,-11.7188f, +-46.875f,29.9667f,-11.7188f, +-42.9688f,31.7598f,-11.7188f, +-39.0625f,32.2636f,-11.7188f, +-35.1563f,32.5734f,-11.7188f, +-31.25f,33.543f,-11.7188f, +-27.3438f,35.1143f,-11.7188f, +-23.4375f,37.3147f,-11.7188f, +-19.5313f,39.2413f,-11.7188f, +-15.625f,41.8344f,-11.7188f, +-11.7188f,43.9992f,-11.7188f, +-7.8125f,46.8581f,-11.7188f, +-3.90625f,48.5977f,-11.7188f, +0.0f,48.7029f,-11.7188f, +3.90625f,49.6298f,-11.7188f, +-250.0f,1.50235f,-15.625f, +-246.094f,1.79115f,-15.625f, +-242.188f,2.52523f,-15.625f, +-238.281f,4.09278f,-15.625f, +-234.375f,6.21068f,-15.625f, +-230.469f,7.49819f,-15.625f, +-226.563f,8.56548f,-15.625f, +-222.656f,9.98954f,-15.625f, +-218.75f,12.3263f,-15.625f, +-214.844f,14.495f,-15.625f, +-210.938f,15.3551f,-15.625f, +-207.031f,17.6989f,-15.625f, +-203.125f,19.2847f,-15.625f, +-199.219f,21.1027f,-15.625f, +-195.313f,23.3408f,-15.625f, +-191.406f,25.3739f,-15.625f, +-187.5f,27.368f,-15.625f, +-183.594f,28.3731f,-15.625f, +-179.688f,29.5532f,-15.625f, +-175.781f,30.0011f,-15.625f, +-171.875f,31.0216f,-15.625f, +-167.969f,32.5546f,-15.625f, +-164.063f,32.6717f,-15.625f, +-160.156f,33.8465f,-15.625f, +-156.25f,35.1272f,-15.625f, +-152.344f,35.5572f,-15.625f, +-148.438f,36.643f,-15.625f, +-144.531f,36.4283f,-15.625f, +-140.625f,35.6122f,-15.625f, +-136.719f,35.358f,-15.625f, +-132.813f,34.1938f,-15.625f, +-128.906f,34.3913f,-15.625f, +-125.0f,33.2147f,-15.625f, +-121.094f,32.799f,-15.625f, +-117.188f,33.1385f,-15.625f, +-113.281f,33.1487f,-15.625f, +-109.375f,33.6564f,-15.625f, +-105.469f,33.2315f,-15.625f, +-101.563f,32.6066f,-15.625f, +-97.6563f,30.6926f,-15.625f, +-93.75f,28.534f,-15.625f, +-89.8438f,27.6738f,-15.625f, +-85.9375f,27.4216f,-15.625f, +-82.0313f,26.0324f,-15.625f, +-78.125f,25.775f,-15.625f, +-74.2188f,25.909f,-15.625f, +-70.3125f,25.0198f,-15.625f, +-66.4063f,25.9376f,-15.625f, +-62.5f,26.0382f,-15.625f, +-58.5938f,25.856f,-15.625f, +-54.6875f,27.3648f,-15.625f, +-50.7813f,28.9059f,-15.625f, +-46.875f,30.6601f,-15.625f, +-42.9688f,32.6996f,-15.625f, +-39.0625f,32.6909f,-15.625f, +-35.1563f,33.1697f,-15.625f, +-31.25f,34.6947f,-15.625f, +-27.3438f,35.6982f,-15.625f, +-23.4375f,38.2946f,-15.625f, +-19.5313f,40.6765f,-15.625f, +-15.625f,43.5894f,-15.625f, +-11.7188f,46.3071f,-15.625f, +-7.8125f,48.6578f,-15.625f, +-3.90625f,49.0003f,-15.625f, +0.0f,50.5123f,-15.625f, +3.90625f,50.6915f,-15.625f, +-250.0f,1.44302f,-19.5313f, +-246.094f,1.65093f,-19.5313f, +-242.188f,2.94233f,-19.5313f, +-238.281f,4.72065f,-19.5313f, +-234.375f,6.57861f,-19.5313f, +-230.469f,7.31849f,-19.5313f, +-226.563f,7.90567f,-19.5313f, +-222.656f,9.84414f,-19.5313f, +-218.75f,12.1574f,-19.5313f, +-214.844f,13.2825f,-19.5313f, +-210.938f,15.2284f,-19.5313f, +-207.031f,17.2765f,-19.5313f, +-203.125f,19.1565f,-19.5313f, +-199.219f,20.3098f,-19.5313f, +-195.313f,21.9346f,-19.5313f, +-191.406f,23.8549f,-19.5313f, +-187.5f,26.133f,-19.5313f, +-183.594f,27.5858f,-19.5313f, +-179.688f,28.557f,-19.5313f, +-175.781f,28.9754f,-19.5313f, +-171.875f,29.9709f,-19.5313f, +-167.969f,31.2632f,-19.5313f, +-164.063f,31.4957f,-19.5313f, +-160.156f,33.6753f,-19.5313f, +-156.25f,35.1342f,-19.5313f, +-152.344f,35.0617f,-19.5313f, +-148.438f,34.9467f,-19.5313f, +-144.531f,35.1042f,-19.5313f, +-140.625f,35.0842f,-19.5313f, +-136.719f,34.7766f,-19.5313f, +-132.813f,33.8305f,-19.5313f, +-128.906f,33.3013f,-19.5313f, +-125.0f,32.5726f,-19.5313f, +-121.094f,31.5139f,-19.5313f, +-117.188f,31.4576f,-19.5313f, +-113.281f,31.6546f,-19.5313f, +-109.375f,32.4663f,-19.5313f, +-105.469f,32.6148f,-19.5313f, +-101.563f,31.253f,-19.5313f, +-97.6563f,29.5875f,-19.5313f, +-93.75f,28.4866f,-19.5313f, +-89.8438f,29.106f,-19.5313f, +-85.9375f,28.7092f,-19.5313f, +-82.0313f,27.4567f,-19.5313f, +-78.125f,26.5225f,-19.5313f, +-74.2188f,26.7534f,-19.5313f, +-70.3125f,26.278f,-19.5313f, +-66.4063f,25.6949f,-19.5313f, +-62.5f,25.7385f,-19.5313f, +-58.5938f,25.8791f,-19.5313f, +-54.6875f,27.42f,-19.5313f, +-50.7813f,29.0777f,-19.5313f, +-46.875f,31.016f,-19.5313f, +-42.9688f,32.5331f,-19.5313f, +-39.0625f,33.213f,-19.5313f, +-35.1563f,33.9437f,-19.5313f, +-31.25f,35.6737f,-19.5313f, +-27.3438f,37.8841f,-19.5313f, +-23.4375f,40.5289f,-19.5313f, +-19.5313f,43.6786f,-19.5313f, +-15.625f,47.2945f,-19.5313f, +-11.7188f,49.7082f,-19.5313f, +-7.8125f,51.1285f,-19.5313f, +-3.90625f,51.5532f,-19.5313f, +0.0f,52.3342f,-19.5313f, +3.90625f,52.1028f,-19.5313f, +-250.0f,1.05337f,-23.4375f, +-246.094f,1.28315f,-23.4375f, +-242.188f,3.38102f,-23.4375f, +-238.281f,4.51357f,-23.4375f, +-234.375f,5.63288f,-23.4375f, +-230.469f,6.49498f,-23.4375f, +-226.563f,7.71248f,-23.4375f, +-222.656f,8.83716f,-23.4375f, +-218.75f,10.4002f,-23.4375f, +-214.844f,11.8049f,-23.4375f, +-210.938f,13.7948f,-23.4375f, +-207.031f,16.5066f,-23.4375f, +-203.125f,18.598f,-23.4375f, +-199.219f,20.3069f,-23.4375f, +-195.313f,21.6868f,-23.4375f, +-191.406f,22.5781f,-23.4375f, +-187.5f,25.0292f,-23.4375f, +-183.594f,26.5386f,-23.4375f, +-179.688f,27.1952f,-23.4375f, +-175.781f,28.4023f,-23.4375f, +-171.875f,29.0264f,-23.4375f, +-167.969f,29.9302f,-23.4375f, +-164.063f,31.7992f,-23.4375f, +-160.156f,33.4902f,-23.4375f, +-156.25f,34.4307f,-23.4375f, +-152.344f,34.1463f,-23.4375f, +-148.438f,33.5881f,-23.4375f, +-144.531f,34.0515f,-23.4375f, +-140.625f,33.7128f,-23.4375f, +-136.719f,33.2076f,-23.4375f, +-132.813f,32.0419f,-23.4375f, +-128.906f,31.3464f,-23.4375f, +-125.0f,31.3552f,-23.4375f, +-121.094f,30.6713f,-23.4375f, +-117.188f,30.1403f,-23.4375f, +-113.281f,30.1753f,-23.4375f, +-109.375f,30.6182f,-23.4375f, +-105.469f,31.2785f,-23.4375f, +-101.563f,30.4839f,-23.4375f, +-97.6563f,28.9907f,-23.4375f, +-93.75f,29.3427f,-23.4375f, +-89.8438f,29.5539f,-23.4375f, +-85.9375f,29.4313f,-23.4375f, +-82.0313f,28.0148f,-23.4375f, +-78.125f,27.3569f,-23.4375f, +-74.2188f,26.8569f,-23.4375f, +-70.3125f,25.6193f,-23.4375f, +-66.4063f,25.8188f,-23.4375f, +-62.5f,25.458f,-23.4375f, +-58.5938f,26.5128f,-23.4375f, +-54.6875f,27.2598f,-23.4375f, +-50.7813f,28.4912f,-23.4375f, +-46.875f,31.0376f,-23.4375f, +-42.9688f,33.0941f,-23.4375f, +-39.0625f,34.4933f,-23.4375f, +-35.1563f,37.1957f,-23.4375f, +-31.25f,39.4612f,-23.4375f, +-27.3438f,41.4598f,-23.4375f, +-23.4375f,43.5893f,-23.4375f, +-19.5313f,46.8054f,-23.4375f, +-15.625f,49.4177f,-23.4375f, +-11.7188f,51.7957f,-23.4375f, +-7.8125f,53.1306f,-23.4375f, +-3.90625f,53.4872f,-23.4375f, +0.0f,53.6348f,-23.4375f, +3.90625f,54.332f,-23.4375f, +-250.0f,1.05459f,-27.3438f, +-246.094f,2.15725f,-27.3438f, +-242.188f,3.16747f,-27.3438f, +-238.281f,4.17562f,-27.3438f, +-234.375f,5.17097f,-27.3438f, +-230.469f,6.61997f,-27.3438f, +-226.563f,7.25727f,-27.3438f, +-222.656f,9.26302f,-27.3438f, +-218.75f,10.7606f,-27.3438f, +-214.844f,11.6966f,-27.3438f, +-210.938f,13.0425f,-27.3438f, +-207.031f,15.0672f,-27.3438f, +-203.125f,17.5971f,-27.3438f, +-199.219f,19.3182f,-27.3438f, +-195.313f,20.4505f,-27.3438f, +-191.406f,20.7017f,-27.3438f, +-187.5f,22.8054f,-27.3438f, +-183.594f,24.7406f,-27.3438f, +-179.688f,25.7957f,-27.3438f, +-175.781f,28.4608f,-27.3438f, +-171.875f,29.5031f,-27.3438f, +-167.969f,29.8812f,-27.3438f, +-164.063f,31.4954f,-27.3438f, +-160.156f,32.6053f,-27.3438f, +-156.25f,32.9274f,-27.3438f, +-152.344f,32.6481f,-27.3438f, +-148.438f,32.4456f,-27.3438f, +-144.531f,32.0065f,-27.3438f, +-140.625f,31.7655f,-27.3438f, +-136.719f,31.6836f,-27.3438f, +-132.813f,30.9994f,-27.3438f, +-128.906f,30.4065f,-27.3438f, +-125.0f,29.7478f,-27.3438f, +-121.094f,29.3871f,-27.3438f, +-117.188f,28.6628f,-27.3438f, +-113.281f,28.88f,-27.3438f, +-109.375f,29.3757f,-27.3438f, +-105.469f,29.7372f,-27.3438f, +-101.563f,28.9035f,-27.3438f, +-97.6563f,29.0842f,-27.3438f, +-93.75f,28.969f,-27.3438f, +-89.8438f,29.282f,-27.3438f, +-85.9375f,29.4429f,-27.3438f, +-82.0313f,29.2385f,-27.3438f, +-78.125f,28.2845f,-27.3438f, +-74.2188f,26.9413f,-27.3438f, +-70.3125f,26.3888f,-27.3438f, +-66.4063f,26.4127f,-27.3438f, +-62.5f,27.4297f,-27.3438f, +-58.5938f,28.0301f,-27.3438f, +-54.6875f,28.3682f,-27.3438f, +-50.7813f,30.4624f,-27.3438f, +-46.875f,32.6469f,-27.3438f, +-42.9688f,34.7681f,-27.3438f, +-39.0625f,37.3677f,-27.3438f, +-35.1563f,40.0943f,-27.3438f, +-31.25f,42.4424f,-27.3438f, +-27.3438f,44.5954f,-27.3438f, +-23.4375f,48.1538f,-27.3438f, +-19.5313f,50.5809f,-27.3438f, +-15.625f,52.7959f,-27.3438f, +-11.7188f,53.9779f,-27.3438f, +-7.8125f,55.2657f,-27.3438f, +-3.90625f,55.7427f,-27.3438f, +0.0f,56.6047f,-27.3438f, +3.90625f,57.5273f,-27.3438f, +-250.0f,1.91243f,-31.25f, +-246.094f,1.77508f,-31.25f, +-242.188f,2.89721f,-31.25f, +-238.281f,4.82177f,-31.25f, +-234.375f,5.57483f,-31.25f, +-230.469f,6.15697f,-31.25f, +-226.563f,7.43219f,-31.25f, +-222.656f,9.10752f,-31.25f, +-218.75f,10.7345f,-31.25f, +-214.844f,11.7298f,-31.25f, +-210.938f,13.0008f,-31.25f, +-207.031f,14.4465f,-31.25f, +-203.125f,16.7635f,-31.25f, +-199.219f,18.7095f,-31.25f, +-195.313f,19.057f,-31.25f, +-191.406f,19.522f,-31.25f, +-187.5f,21.0252f,-31.25f, +-183.594f,22.477f,-31.25f, +-179.688f,24.9456f,-31.25f, +-175.781f,27.5579f,-31.25f, +-171.875f,28.9367f,-31.25f, +-167.969f,29.5938f,-31.25f, +-164.063f,29.9491f,-31.25f, +-160.156f,31.1043f,-31.25f, +-156.25f,31.898f,-31.25f, +-152.344f,32.025f,-31.25f, +-148.438f,32.2848f,-31.25f, +-144.531f,31.4433f,-31.25f, +-140.625f,29.9423f,-31.25f, +-136.719f,30.2535f,-31.25f, +-132.813f,30.4668f,-31.25f, +-128.906f,30.1261f,-31.25f, +-125.0f,29.2612f,-31.25f, +-121.094f,27.5496f,-31.25f, +-117.188f,27.0659f,-31.25f, +-113.281f,27.3359f,-31.25f, +-109.375f,27.8418f,-31.25f, +-105.469f,28.9814f,-31.25f, +-101.563f,28.4429f,-31.25f, +-97.6563f,28.5833f,-31.25f, +-93.75f,28.9986f,-31.25f, +-89.8438f,30.3273f,-31.25f, +-85.9375f,30.5898f,-31.25f, +-82.0313f,29.8768f,-31.25f, +-78.125f,28.7278f,-31.25f, +-74.2188f,28.2599f,-31.25f, +-70.3125f,27.5942f,-31.25f, +-66.4063f,28.2721f,-31.25f, +-62.5f,28.9526f,-31.25f, +-58.5938f,29.4527f,-31.25f, +-54.6875f,30.1605f,-31.25f, +-50.7813f,32.6242f,-31.25f, +-46.875f,35.2708f,-31.25f, +-42.9688f,37.6696f,-31.25f, +-39.0625f,40.1477f,-31.25f, +-35.1563f,42.5127f,-31.25f, +-31.25f,45.655f,-31.25f, +-27.3438f,48.5747f,-31.25f, +-23.4375f,51.2069f,-31.25f, +-19.5313f,53.5599f,-31.25f, +-15.625f,55.3726f,-31.25f, +-11.7188f,56.4687f,-31.25f, +-7.8125f,56.313f,-31.25f, +-3.90625f,58.0363f,-31.25f, +0.0f,59.422f,-31.25f, +3.90625f,59.4204f,-31.25f, +-250.0f,1.80637f,-35.1563f, +-246.094f,1.14243f,-35.1563f, +-242.188f,2.08309f,-35.1563f, +-238.281f,3.66548f,-35.1563f, +-234.375f,4.49251f,-35.1563f, +-230.469f,5.63985f,-35.1563f, +-226.563f,7.33778f,-35.1563f, +-222.656f,9.15183f,-35.1563f, +-218.75f,10.0463f,-35.1563f, +-214.844f,11.7521f,-35.1563f, +-210.938f,12.6919f,-35.1563f, +-207.031f,14.0216f,-35.1563f, +-203.125f,14.9825f,-35.1563f, +-199.219f,16.2286f,-35.1563f, +-195.313f,17.2153f,-35.1563f, +-191.406f,18.0692f,-35.1563f, +-187.5f,19.858f,-35.1563f, +-183.594f,22.2715f,-35.1563f, +-179.688f,25.6457f,-35.1563f, +-175.781f,27.6627f,-35.1563f, +-171.875f,28.6491f,-35.1563f, +-167.969f,29.5869f,-35.1563f, +-164.063f,29.5582f,-35.1563f, +-160.156f,30.7619f,-35.1563f, +-156.25f,31.372f,-35.1563f, +-152.344f,31.4423f,-35.1563f, +-148.438f,31.7578f,-35.1563f, +-144.531f,31.1339f,-35.1563f, +-140.625f,29.3454f,-35.1563f, +-136.719f,28.0675f,-35.1563f, +-132.813f,28.1828f,-35.1563f, +-128.906f,28.2649f,-35.1563f, +-125.0f,27.2326f,-35.1563f, +-121.094f,26.2567f,-35.1563f, +-117.188f,25.4914f,-35.1563f, +-113.281f,25.5444f,-35.1563f, +-109.375f,25.8703f,-35.1563f, +-105.469f,27.9373f,-35.1563f, +-101.563f,27.9306f,-35.1563f, +-97.6563f,27.9282f,-35.1563f, +-93.75f,28.9199f,-35.1563f, +-89.8438f,30.142f,-35.1563f, +-85.9375f,30.3479f,-35.1563f, +-82.0313f,29.749f,-35.1563f, +-78.125f,29.2656f,-35.1563f, +-74.2188f,28.8561f,-35.1563f, +-70.3125f,28.7144f,-35.1563f, +-66.4063f,29.3204f,-35.1563f, +-62.5f,29.6751f,-35.1563f, +-58.5938f,31.0647f,-35.1563f, +-54.6875f,32.3243f,-35.1563f, +-50.7813f,34.476f,-35.1563f, +-46.875f,37.0984f,-35.1563f, +-42.9688f,40.1281f,-35.1563f, +-39.0625f,42.4472f,-35.1563f, +-35.1563f,45.6772f,-35.1563f, +-31.25f,49.5655f,-35.1563f, +-27.3438f,51.5783f,-35.1563f, +-23.4375f,53.3f,-35.1563f, +-19.5313f,55.4127f,-35.1563f, +-15.625f,56.8152f,-35.1563f, +-11.7188f,56.8985f,-35.1563f, +-7.8125f,57.5886f,-35.1563f, +-3.90625f,58.9321f,-35.1563f, +0.0f,60.2297f,-35.1563f, +3.90625f,60.2212f,-35.1563f, +-250.0f,2.59935f,-39.0625f, +-246.094f,1.55278f,-39.0625f, +-242.188f,1.42243f,-39.0625f, +-238.281f,2.78238f,-39.0625f, +-234.375f,3.85918f,-39.0625f, +-230.469f,5.01321f,-39.0625f, +-226.563f,6.56707f,-39.0625f, +-222.656f,7.99762f,-39.0625f, +-218.75f,9.72642f,-39.0625f, +-214.844f,11.975f,-39.0625f, +-210.938f,12.8008f,-39.0625f, +-207.031f,13.6902f,-39.0625f, +-203.125f,14.2017f,-39.0625f, +-199.219f,14.8784f,-39.0625f, +-195.313f,16.6265f,-39.0625f, +-191.406f,17.066f,-39.0625f, +-187.5f,19.3153f,-39.0625f, +-183.594f,23.4017f,-39.0625f, +-179.688f,26.2073f,-39.0625f, +-175.781f,27.92f,-39.0625f, +-171.875f,29.0435f,-39.0625f, +-167.969f,28.8537f,-39.0625f, +-164.063f,29.6445f,-39.0625f, +-160.156f,30.2119f,-39.0625f, +-156.25f,30.4693f,-39.0625f, +-152.344f,30.6063f,-39.0625f, +-148.438f,30.8716f,-39.0625f, +-144.531f,30.3253f,-39.0625f, +-140.625f,29.3941f,-39.0625f, +-136.719f,27.7606f,-39.0625f, +-132.813f,26.806f,-39.0625f, +-128.906f,26.6501f,-39.0625f, +-125.0f,25.6992f,-39.0625f, +-121.094f,24.4674f,-39.0625f, +-117.188f,24.1124f,-39.0625f, +-113.281f,24.9142f,-39.0625f, +-109.375f,25.5696f,-39.0625f, +-105.469f,25.4691f,-39.0625f, +-101.563f,26.7147f,-39.0625f, +-97.6563f,26.7558f,-39.0625f, +-93.75f,27.9278f,-39.0625f, +-89.8438f,29.0149f,-39.0625f, +-85.9375f,29.3557f,-39.0625f, +-82.0313f,29.6134f,-39.0625f, +-78.125f,29.4742f,-39.0625f, +-74.2188f,29.3377f,-39.0625f, +-70.3125f,29.6082f,-39.0625f, +-66.4063f,29.4634f,-39.0625f, +-62.5f,31.1775f,-39.0625f, +-58.5938f,32.7227f,-39.0625f, +-54.6875f,34.2233f,-39.0625f, +-50.7813f,36.1862f,-39.0625f, +-46.875f,38.7123f,-39.0625f, +-42.9688f,41.2396f,-39.0625f, +-39.0625f,44.5857f,-39.0625f, +-35.1563f,47.0183f,-39.0625f, +-31.25f,50.9933f,-39.0625f, +-27.3438f,53.2967f,-39.0625f, +-23.4375f,55.2026f,-39.0625f, +-19.5313f,56.3858f,-39.0625f, +-15.625f,57.8615f,-39.0625f, +-11.7188f,57.7515f,-39.0625f, +-7.8125f,58.8071f,-39.0625f, +-3.90625f,59.73f,-39.0625f, +0.0f,59.8999f,-39.0625f, +3.90625f,59.9094f,-39.0625f, +-250.0f,2.73015f,-42.9688f, +-246.094f,1.9296f,-42.9688f, +-242.188f,2.00835f,-42.9688f, +-238.281f,3.16245f,-42.9688f, +-234.375f,3.35198f,-42.9688f, +-230.469f,4.50732f,-42.9688f, +-226.563f,6.28971f,-42.9688f, +-222.656f,7.89723f,-42.9688f, +-218.75f,9.28447f,-42.9688f, +-214.844f,11.4302f,-42.9688f, +-210.938f,12.7156f,-42.9688f, +-207.031f,13.6281f,-42.9688f, +-203.125f,14.5932f,-42.9688f, +-199.219f,14.8129f,-42.9688f, +-195.313f,15.7965f,-42.9688f, +-191.406f,16.3571f,-42.9688f, +-187.5f,20.257f,-42.9688f, +-183.594f,23.2993f,-42.9688f, +-179.688f,25.4583f,-42.9688f, +-175.781f,27.2887f,-42.9688f, +-171.875f,27.9862f,-42.9688f, +-167.969f,28.274f,-42.9688f, +-164.063f,28.9264f,-42.9688f, +-160.156f,29.1855f,-42.9688f, +-156.25f,29.8898f,-42.9688f, +-152.344f,29.4922f,-42.9688f, +-148.438f,29.257f,-42.9688f, +-144.531f,28.9137f,-42.9688f, +-140.625f,27.618f,-42.9688f, +-136.719f,26.8539f,-42.9688f, +-132.813f,26.2806f,-42.9688f, +-128.906f,25.1378f,-42.9688f, +-125.0f,24.508f,-42.9688f, +-121.094f,23.8458f,-42.9688f, +-117.188f,23.501f,-42.9688f, +-113.281f,24.0593f,-42.9688f, +-109.375f,24.1366f,-42.9688f, +-105.469f,24.075f,-42.9688f, +-101.563f,24.5025f,-42.9688f, +-97.6563f,24.8457f,-42.9688f, +-93.75f,26.5028f,-42.9688f, +-89.8438f,26.9842f,-42.9688f, +-85.9375f,28.5672f,-42.9688f, +-82.0313f,28.9848f,-42.9688f, +-78.125f,29.1484f,-42.9688f, +-74.2188f,28.8735f,-42.9688f, +-70.3125f,29.9085f,-42.9688f, +-66.4063f,31.647f,-42.9688f, +-62.5f,32.8553f,-42.9688f, +-58.5938f,34.4488f,-42.9688f, +-54.6875f,35.7724f,-42.9688f, +-50.7813f,38.5181f,-42.9688f, +-46.875f,40.619f,-42.9688f, +-42.9688f,42.6158f,-42.9688f, +-39.0625f,45.9557f,-42.9688f, +-35.1563f,48.8071f,-42.9688f, +-31.25f,51.5425f,-42.9688f, +-27.3438f,54.1461f,-42.9688f, +-23.4375f,56.6935f,-42.9688f, +-19.5313f,57.353f,-42.9688f, +-15.625f,58.289f,-42.9688f, +-11.7188f,58.4633f,-42.9688f, +-7.8125f,59.0033f,-42.9688f, +-3.90625f,59.61f,-42.9688f, +0.0f,59.6115f,-42.9688f, +3.90625f,59.5207f,-42.9688f, +-250.0f,2.05499f,-46.875f, +-246.094f,1.44228f,-46.875f, +-242.188f,1.95946f,-46.875f, +-238.281f,2.50642f,-46.875f, +-234.375f,3.23732f,-46.875f, +-230.469f,4.46051f,-46.875f, +-226.563f,6.17815f,-46.875f, +-222.656f,7.58101f,-46.875f, +-218.75f,9.4063f,-46.875f, +-214.844f,11.394f,-46.875f, +-210.938f,12.4493f,-46.875f, +-207.031f,13.1281f,-46.875f, +-203.125f,13.8316f,-46.875f, +-199.219f,14.1574f,-46.875f, +-195.313f,15.0289f,-46.875f, +-191.406f,17.2095f,-46.875f, +-187.5f,20.3326f,-46.875f, +-183.594f,22.5046f,-46.875f, +-179.688f,24.7998f,-46.875f, +-175.781f,26.3728f,-46.875f, +-171.875f,27.3394f,-46.875f, +-167.969f,27.2989f,-46.875f, +-164.063f,27.5191f,-46.875f, +-160.156f,28.1581f,-46.875f, +-156.25f,28.357f,-46.875f, +-152.344f,27.2465f,-46.875f, +-148.438f,27.6591f,-46.875f, +-144.531f,26.7196f,-46.875f, +-140.625f,25.3776f,-46.875f, +-136.719f,25.1174f,-46.875f, +-132.813f,24.6913f,-46.875f, +-128.906f,23.828f,-46.875f, +-125.0f,22.7885f,-46.875f, +-121.094f,23.6316f,-46.875f, +-117.188f,23.288f,-46.875f, +-113.281f,22.8849f,-46.875f, +-109.375f,22.6367f,-46.875f, +-105.469f,22.2282f,-46.875f, +-101.563f,22.7539f,-46.875f, +-97.6563f,23.4319f,-46.875f, +-93.75f,25.0494f,-46.875f, +-89.8438f,25.7759f,-46.875f, +-85.9375f,27.2287f,-46.875f, +-82.0313f,28.1554f,-46.875f, +-78.125f,28.6794f,-46.875f, +-74.2188f,30.4763f,-46.875f, +-70.3125f,32.23f,-46.875f, +-66.4063f,33.6868f,-46.875f, +-62.5f,34.7841f,-46.875f, +-58.5938f,36.2585f,-46.875f, +-54.6875f,38.2534f,-46.875f, +-50.7813f,39.5261f,-46.875f, +-46.875f,41.7676f,-46.875f, +-42.9688f,44.8849f,-46.875f, +-39.0625f,47.6394f,-46.875f, +-35.1563f,49.5783f,-46.875f, +-31.25f,52.3871f,-46.875f, +-27.3438f,54.9333f,-46.875f, +-23.4375f,56.6705f,-46.875f, +-19.5313f,56.898f,-46.875f, +-15.625f,58.678f,-46.875f, +-11.7188f,59.6595f,-46.875f, +-7.8125f,59.0163f,-46.875f, +-3.90625f,59.3587f,-46.875f, +0.0f,58.5405f,-46.875f, +3.90625f,58.9086f,-46.875f, +-250.0f,2.57742f,-50.7813f, +-246.094f,2.06275f,-50.7813f, +-242.188f,2.26453f,-50.7813f, +-238.281f,2.43527f,-50.7813f, +-234.375f,2.63858f,-50.7813f, +-230.469f,4.44964f,-50.7813f, +-226.563f,6.50192f,-50.7813f, +-222.656f,8.11006f,-50.7813f, +-218.75f,10.1023f,-50.7813f, +-214.844f,11.3708f,-50.7813f, +-210.938f,12.7395f,-50.7813f, +-207.031f,13.6541f,-50.7813f, +-203.125f,13.6317f,-50.7813f, +-199.219f,13.4823f,-50.7813f, +-195.313f,15.3032f,-50.7813f, +-191.406f,17.5085f,-50.7813f, +-187.5f,19.5731f,-50.7813f, +-183.594f,22.0894f,-50.7813f, +-179.688f,23.8927f,-50.7813f, +-175.781f,24.9335f,-50.7813f, +-171.875f,26.1125f,-50.7813f, +-167.969f,25.9034f,-50.7813f, +-164.063f,26.9549f,-50.7813f, +-160.156f,26.7939f,-50.7813f, +-156.25f,26.3447f,-50.7813f, +-152.344f,25.6085f,-50.7813f, +-148.438f,25.2823f,-50.7813f, +-144.531f,25.4854f,-50.7813f, +-140.625f,23.906f,-50.7813f, +-136.719f,23.7094f,-50.7813f, +-132.813f,22.9599f,-50.7813f, +-128.906f,22.3089f,-50.7813f, +-125.0f,22.302f,-50.7813f, +-121.094f,23.3289f,-50.7813f, +-117.188f,23.1804f,-50.7813f, +-113.281f,22.6693f,-50.7813f, +-109.375f,21.2587f,-50.7813f, +-105.469f,20.4638f,-50.7813f, +-101.563f,21.4819f,-50.7813f, +-97.6563f,22.0137f,-50.7813f, +-93.75f,23.4763f,-50.7813f, +-89.8438f,25.2125f,-50.7813f, +-85.9375f,26.446f,-50.7813f, +-82.0313f,27.5614f,-50.7813f, +-78.125f,29.5641f,-50.7813f, +-74.2188f,31.1552f,-50.7813f, +-70.3125f,33.5337f,-50.7813f, +-66.4063f,35.653f,-50.7813f, +-62.5f,36.2419f,-50.7813f, +-58.5938f,37.4297f,-50.7813f, +-54.6875f,39.7492f,-50.7813f, +-50.7813f,41.494f,-50.7813f, +-46.875f,44.5449f,-50.7813f, +-42.9688f,47.2689f,-50.7813f, +-39.0625f,49.6705f,-50.7813f, +-35.1563f,51.8942f,-50.7813f, +-31.25f,53.9483f,-50.7813f, +-27.3438f,55.2444f,-50.7813f, +-23.4375f,56.5482f,-50.7813f, +-19.5313f,58.5545f,-50.7813f, +-15.625f,59.5559f,-50.7813f, +-11.7188f,58.8699f,-50.7813f, +-7.8125f,59.0373f,-50.7813f, +-3.90625f,59.5884f,-50.7813f, +0.0f,59.6491f,-50.7813f, +3.90625f,59.8509f,-50.7813f, +-250.0f,2.04136f,-54.6875f, +-246.094f,2.5492f,-54.6875f, +-242.188f,2.70952f,-54.6875f, +-238.281f,3.00758f,-54.6875f, +-234.375f,3.54707f,-54.6875f, +-230.469f,5.09851f,-54.6875f, +-226.563f,7.09409f,-54.6875f, +-222.656f,8.40975f,-54.6875f, +-218.75f,10.0555f,-54.6875f, +-214.844f,11.4962f,-54.6875f, +-210.938f,12.1806f,-54.6875f, +-207.031f,12.7217f,-54.6875f, +-203.125f,12.6935f,-54.6875f, +-199.219f,14.0259f,-54.6875f, +-195.313f,16.1147f,-54.6875f, +-191.406f,18.3888f,-54.6875f, +-187.5f,19.3549f,-54.6875f, +-183.594f,21.6563f,-54.6875f, +-179.688f,22.9906f,-54.6875f, +-175.781f,23.7728f,-54.6875f, +-171.875f,25.2286f,-54.6875f, +-167.969f,26.0764f,-54.6875f, +-164.063f,26.746f,-54.6875f, +-160.156f,26.3029f,-54.6875f, +-156.25f,25.6172f,-54.6875f, +-152.344f,24.537f,-54.6875f, +-148.438f,23.8458f,-54.6875f, +-144.531f,23.3726f,-54.6875f, +-140.625f,22.8694f,-54.6875f, +-136.719f,22.5247f,-54.6875f, +-132.813f,21.436f,-54.6875f, +-128.906f,21.4712f,-54.6875f, +-125.0f,22.1621f,-54.6875f, +-121.094f,22.4599f,-54.6875f, +-117.188f,21.4148f,-54.6875f, +-113.281f,20.8237f,-54.6875f, +-109.375f,19.6257f,-54.6875f, +-105.469f,20.1462f,-54.6875f, +-101.563f,21.5895f,-54.6875f, +-97.6563f,22.2376f,-54.6875f, +-93.75f,23.679f,-54.6875f, +-89.8438f,24.9403f,-54.6875f, +-85.9375f,26.4205f,-54.6875f, +-82.0313f,27.9125f,-54.6875f, +-78.125f,30.0689f,-54.6875f, +-74.2188f,32.7388f,-54.6875f, +-70.3125f,34.3502f,-54.6875f, +-66.4063f,35.6763f,-54.6875f, +-62.5f,37.4625f,-54.6875f, +-58.5938f,38.3448f,-54.6875f, +-54.6875f,40.6027f,-54.6875f, +-50.7813f,44.4532f,-54.6875f, +-46.875f,47.6182f,-54.6875f, +-42.9688f,49.7683f,-54.6875f, +-39.0625f,52.1875f,-54.6875f, +-35.1563f,54.4951f,-54.6875f, +-31.25f,55.9437f,-54.6875f, +-27.3438f,57.1353f,-54.6875f, +-23.4375f,58.016f,-54.6875f, +-19.5313f,59.6013f,-54.6875f, +-15.625f,59.9872f,-54.6875f, +-11.7188f,59.8299f,-54.6875f, +-7.8125f,60.1035f,-54.6875f, +-3.90625f,60.8558f,-54.6875f, +0.0f,60.5619f,-54.6875f, +3.90625f,60.3928f,-54.6875f, +-250.0f,4.01167f,-58.5938f, +-246.094f,3.0694f,-58.5938f, +-242.188f,3.37661f,-58.5938f, +-238.281f,3.71931f,-58.5938f, +-234.375f,4.08816f,-58.5938f, +-230.469f,5.56386f,-58.5938f, +-226.563f,7.3314f,-58.5938f, +-222.656f,8.61323f,-58.5938f, +-218.75f,9.77849f,-58.5938f, +-214.844f,11.9744f,-58.5938f, +-210.938f,12.9366f,-58.5938f, +-207.031f,13.5175f,-58.5938f, +-203.125f,13.948f,-58.5938f, +-199.219f,14.4053f,-58.5938f, +-195.313f,16.1496f,-58.5938f, +-191.406f,17.8653f,-58.5938f, +-187.5f,18.9853f,-58.5938f, +-183.594f,21.2985f,-58.5938f, +-179.688f,23.4932f,-58.5938f, +-175.781f,25.3544f,-58.5938f, +-171.875f,26.1087f,-58.5938f, +-167.969f,26.5864f,-58.5938f, +-164.063f,25.8729f,-58.5938f, +-160.156f,25.0068f,-58.5938f, +-156.25f,25.2867f,-58.5938f, +-152.344f,23.9482f,-58.5938f, +-148.438f,23.23f,-58.5938f, +-144.531f,22.6171f,-58.5938f, +-140.625f,21.4991f,-58.5938f, +-136.719f,21.0822f,-58.5938f, +-132.813f,21.0037f,-58.5938f, +-128.906f,21.8362f,-58.5938f, +-125.0f,21.5985f,-58.5938f, +-121.094f,20.951f,-58.5938f, +-117.188f,21.2066f,-58.5938f, +-113.281f,19.7479f,-58.5938f, +-109.375f,18.5787f,-58.5938f, +-105.469f,20.3984f,-58.5938f, +-101.563f,22.257f,-58.5938f, +-97.6563f,23.3411f,-58.5938f, +-93.75f,24.362f,-58.5938f, +-89.8438f,25.7544f,-58.5938f, +-85.9375f,27.7522f,-58.5938f, +-82.0313f,28.9204f,-58.5938f, +-78.125f,30.8124f,-58.5938f, +-74.2188f,32.9097f,-58.5938f, +-70.3125f,34.8737f,-58.5938f, +-66.4063f,36.0518f,-58.5938f, +-62.5f,38.506f,-58.5938f, +-58.5938f,41.2951f,-58.5938f, +-54.6875f,43.3387f,-58.5938f, +-50.7813f,46.5457f,-58.5938f, +-46.875f,49.2409f,-58.5938f, +-42.9688f,51.3946f,-58.5938f, +-39.0625f,54.0957f,-58.5938f, +-35.1563f,55.8205f,-58.5938f, +-31.25f,57.094f,-58.5938f, +-27.3438f,58.0636f,-58.5938f, +-23.4375f,58.8159f,-58.5938f, +-19.5313f,59.9761f,-58.5938f, +-15.625f,60.2094f,-58.5938f, +-11.7188f,60.0275f,-58.5938f, +-7.8125f,61.0991f,-58.5938f, +-3.90625f,61.4786f,-58.5938f, +0.0f,61.4895f,-58.5938f, +3.90625f,61.5747f,-58.5938f, +-250.0f,5.54938f,-62.5f, +-246.094f,4.18374f,-62.5f, +-242.188f,3.90057f,-62.5f, +-238.281f,4.25951f,-62.5f, +-234.375f,4.82365f,-62.5f, +-230.469f,6.03197f,-62.5f, +-226.563f,7.69909f,-62.5f, +-222.656f,8.80826f,-62.5f, +-218.75f,10.8241f,-62.5f, +-214.844f,13.5771f,-62.5f, +-210.938f,14.456f,-62.5f, +-207.031f,15.0395f,-62.5f, +-203.125f,14.5505f,-62.5f, +-199.219f,16.1706f,-62.5f, +-195.313f,16.9508f,-62.5f, +-191.406f,18.2016f,-62.5f, +-187.5f,19.8694f,-62.5f, +-183.594f,22.6167f,-62.5f, +-179.688f,24.5727f,-62.5f, +-175.781f,26.0063f,-62.5f, +-171.875f,26.0399f,-62.5f, +-167.969f,26.6416f,-62.5f, +-164.063f,25.6476f,-62.5f, +-160.156f,24.4615f,-62.5f, +-156.25f,23.5295f,-62.5f, +-152.344f,23.7879f,-62.5f, +-148.438f,22.8826f,-62.5f, +-144.531f,21.6558f,-62.5f, +-140.625f,20.6405f,-62.5f, +-136.719f,20.1695f,-62.5f, +-132.813f,20.7715f,-62.5f, +-128.906f,20.5918f,-62.5f, +-125.0f,20.4476f,-62.5f, +-121.094f,19.9068f,-62.5f, +-117.188f,19.4838f,-62.5f, +-113.281f,17.843f,-62.5f, +-109.375f,18.5661f,-62.5f, +-105.469f,20.1106f,-62.5f, +-101.563f,21.3182f,-62.5f, +-97.6563f,23.2851f,-62.5f, +-93.75f,24.3601f,-62.5f, +-89.8438f,26.3742f,-62.5f, +-85.9375f,27.7409f,-62.5f, +-82.0313f,29.533f,-62.5f, +-78.125f,31.5622f,-62.5f, +-74.2188f,33.2773f,-62.5f, +-70.3125f,35.6025f,-62.5f, +-66.4063f,38.4255f,-62.5f, +-62.5f,40.916f,-62.5f, +-58.5938f,43.9378f,-62.5f, +-54.6875f,45.9116f,-62.5f, +-50.7813f,48.3177f,-62.5f, +-46.875f,50.1977f,-62.5f, +-42.9688f,52.4552f,-62.5f, +-39.0625f,54.6779f,-62.5f, +-35.1563f,56.1564f,-62.5f, +-31.25f,57.5665f,-62.5f, +-27.3438f,58.7762f,-62.5f, +-23.4375f,59.115f,-62.5f, +-19.5313f,58.5535f,-62.5f, +-15.625f,58.2117f,-62.5f, +-11.7188f,59.0863f,-62.5f, +-7.8125f,60.3775f,-62.5f, +-3.90625f,61.0192f,-62.5f, +0.0f,61.864f,-62.5f, +3.90625f,62.1111f,-62.5f, +-250.0f,6.08003f,-66.4063f, +-246.094f,5.13458f,-66.4063f, +-242.188f,5.0967f,-66.4063f, +-238.281f,5.36926f,-66.4063f, +-234.375f,5.21926f,-66.4063f, +-230.469f,6.37997f,-66.4063f, +-226.563f,7.85032f,-66.4063f, +-222.656f,9.36117f,-66.4063f, +-218.75f,11.896f,-66.4063f, +-214.844f,13.9549f,-66.4063f, +-210.938f,15.4673f,-66.4063f, +-207.031f,15.9885f,-66.4063f, +-203.125f,16.4425f,-66.4063f, +-199.219f,17.4253f,-66.4063f, +-195.313f,18.1385f,-66.4063f, +-191.406f,18.8676f,-66.4063f, +-187.5f,20.1316f,-66.4063f, +-183.594f,22.8534f,-66.4063f, +-179.688f,24.5364f,-66.4063f, +-175.781f,25.6234f,-66.4063f, +-171.875f,25.9362f,-66.4063f, +-167.969f,25.7735f,-66.4063f, +-164.063f,25.1524f,-66.4063f, +-160.156f,24.4245f,-66.4063f, +-156.25f,22.8769f,-66.4063f, +-152.344f,22.8762f,-66.4063f, +-148.438f,21.9008f,-66.4063f, +-144.531f,20.9242f,-66.4063f, +-140.625f,20.1022f,-66.4063f, +-136.719f,19.5823f,-66.4063f, +-132.813f,19.4415f,-66.4063f, +-128.906f,18.9513f,-66.4063f, +-125.0f,18.9264f,-66.4063f, +-121.094f,18.6878f,-66.4063f, +-117.188f,17.8998f,-66.4063f, +-113.281f,17.9815f,-66.4063f, +-109.375f,18.2652f,-66.4063f, +-105.469f,19.533f,-66.4063f, +-101.563f,21.0045f,-66.4063f, +-97.6563f,22.2461f,-66.4063f, +-93.75f,23.7189f,-66.4063f, +-89.8438f,25.574f,-66.4063f, +-85.9375f,27.55f,-66.4063f, +-82.0313f,29.733f,-66.4063f, +-78.125f,31.0763f,-66.4063f, +-74.2188f,33.9607f,-66.4063f, +-70.3125f,37.3595f,-66.4063f, +-66.4063f,41.019f,-66.4063f, +-62.5f,43.7286f,-66.4063f, +-58.5938f,46.5077f,-66.4063f, +-54.6875f,47.985f,-66.4063f, +-50.7813f,49.2623f,-66.4063f, +-46.875f,50.9465f,-66.4063f, +-42.9688f,52.912f,-66.4063f, +-39.0625f,55.0349f,-66.4063f, +-35.1563f,56.428f,-66.4063f, +-31.25f,57.3951f,-66.4063f, +-27.3438f,58.5332f,-66.4063f, +-23.4375f,58.3328f,-66.4063f, +-19.5313f,56.9549f,-66.4063f, +-15.625f,56.9387f,-66.4063f, +-11.7188f,58.3656f,-66.4063f, +-7.8125f,59.6577f,-66.4063f, +-3.90625f,59.8566f,-66.4063f, +0.0f,60.693f,-66.4063f, +3.90625f,60.8569f,-66.4063f, +-250.0f,6.38861f,-70.3125f, +-246.094f,6.37976f,-70.3125f, +-242.188f,6.52455f,-70.3125f, +-238.281f,6.93657f,-70.3125f, +-234.375f,6.77321f,-70.3125f, +-230.469f,7.26034f,-70.3125f, +-226.563f,8.99316f,-70.3125f, +-222.656f,10.5015f,-70.3125f, +-218.75f,11.631f,-70.3125f, +-214.844f,14.0548f,-70.3125f, +-210.938f,15.9163f,-70.3125f, +-207.031f,16.6824f,-70.3125f, +-203.125f,17.1063f,-70.3125f, +-199.219f,18.066f,-70.3125f, +-195.313f,18.5539f,-70.3125f, +-191.406f,18.8425f,-70.3125f, +-187.5f,20.7731f,-70.3125f, +-183.594f,22.8929f,-70.3125f, +-179.688f,24.2011f,-70.3125f, +-175.781f,24.5512f,-70.3125f, +-171.875f,24.651f,-70.3125f, +-167.969f,23.9906f,-70.3125f, +-164.063f,23.6279f,-70.3125f, +-160.156f,23.6162f,-70.3125f, +-156.25f,22.3196f,-70.3125f, +-152.344f,22.173f,-70.3125f, +-148.438f,20.6833f,-70.3125f, +-144.531f,19.6848f,-70.3125f, +-140.625f,18.4633f,-70.3125f, +-136.719f,18.2692f,-70.3125f, +-132.813f,18.0595f,-70.3125f, +-128.906f,17.2062f,-70.3125f, +-125.0f,17.0103f,-70.3125f, +-121.094f,17.1584f,-70.3125f, +-117.188f,17.5441f,-70.3125f, +-113.281f,17.5669f,-70.3125f, +-109.375f,17.7536f,-70.3125f, +-105.469f,18.3913f,-70.3125f, +-101.563f,19.7264f,-70.3125f, +-97.6563f,20.8943f,-70.3125f, +-93.75f,22.7517f,-70.3125f, +-89.8438f,25.1479f,-70.3125f, +-85.9375f,27.3953f,-70.3125f, +-82.0313f,29.5127f,-70.3125f, +-78.125f,31.2816f,-70.3125f, +-74.2188f,34.6589f,-70.3125f, +-70.3125f,38.2161f,-70.3125f, +-66.4063f,42.3872f,-70.3125f, +-62.5f,45.4363f,-70.3125f, +-58.5938f,47.0181f,-70.3125f, +-54.6875f,48.7348f,-70.3125f, +-50.7813f,49.8739f,-70.3125f, +-46.875f,51.2434f,-70.3125f, +-42.9688f,52.9444f,-70.3125f, +-39.0625f,54.8413f,-70.3125f, +-35.1563f,55.8776f,-70.3125f, +-31.25f,56.9088f,-70.3125f, +-27.3438f,56.8827f,-70.3125f, +-23.4375f,56.1649f,-70.3125f, +-19.5313f,54.9828f,-70.3125f, +-15.625f,56.5543f,-70.3125f, +-11.7188f,58.0071f,-70.3125f, +-7.8125f,58.1204f,-70.3125f, +-3.90625f,58.8019f,-70.3125f, +0.0f,59.3765f,-70.3125f, +3.90625f,59.1482f,-70.3125f, +-250.0f,7.29753f,-74.2188f, +-246.094f,6.9318f,-74.2188f, +-242.188f,7.9493f,-74.2188f, +-238.281f,7.61482f,-74.2188f, +-234.375f,8.38948f,-74.2188f, +-230.469f,8.85034f,-74.2188f, +-226.563f,10.783f,-74.2188f, +-222.656f,12.203f,-74.2188f, +-218.75f,12.7122f,-74.2188f, +-214.844f,14.2813f,-74.2188f, +-210.938f,16.1159f,-74.2188f, +-207.031f,16.8501f,-74.2188f, +-203.125f,17.728f,-74.2188f, +-199.219f,18.6948f,-74.2188f, +-195.313f,19.0254f,-74.2188f, +-191.406f,18.9874f,-74.2188f, +-187.5f,20.7575f,-74.2188f, +-183.594f,22.4682f,-74.2188f, +-179.688f,23.785f,-74.2188f, +-175.781f,23.136f,-74.2188f, +-171.875f,22.2872f,-74.2188f, +-167.969f,21.9381f,-74.2188f, +-164.063f,22.818f,-74.2188f, +-160.156f,21.8019f,-74.2188f, +-156.25f,21.3496f,-74.2188f, +-152.344f,19.9092f,-74.2188f, +-148.438f,19.5338f,-74.2188f, +-144.531f,19.2227f,-74.2188f, +-140.625f,17.2583f,-74.2188f, +-136.719f,15.7727f,-74.2188f, +-132.813f,15.2069f,-74.2188f, +-128.906f,15.0929f,-74.2188f, +-125.0f,15.3066f,-74.2188f, +-121.094f,15.1161f,-74.2188f, +-117.188f,16.1171f,-74.2188f, +-113.281f,17.2851f,-74.2188f, +-109.375f,16.8359f,-74.2188f, +-105.469f,17.6612f,-74.2188f, +-101.563f,18.1651f,-74.2188f, +-97.6563f,18.9354f,-74.2188f, +-93.75f,21.1152f,-74.2188f, +-89.8438f,23.9267f,-74.2188f, +-85.9375f,26.5361f,-74.2188f, +-82.0313f,29.6007f,-74.2188f, +-78.125f,31.8355f,-74.2188f, +-74.2188f,34.5711f,-74.2188f, +-70.3125f,37.6211f,-74.2188f, +-66.4063f,41.978f,-74.2188f, +-62.5f,44.757f,-74.2188f, +-58.5938f,47.2561f,-74.2188f, +-54.6875f,48.796f,-74.2188f, +-50.7813f,50.085f,-74.2188f, +-46.875f,51.427f,-74.2188f, +-42.9688f,52.9103f,-74.2188f, +-39.0625f,53.6345f,-74.2188f, +-35.1563f,55.5589f,-74.2188f, +-31.25f,56.4557f,-74.2188f, +-27.3438f,55.8259f,-74.2188f, +-23.4375f,55.2472f,-74.2188f, +-19.5313f,54.9161f,-74.2188f, +-15.625f,56.2403f,-74.2188f, +-11.7188f,57.7266f,-74.2188f, +-7.8125f,57.6855f,-74.2188f, +-3.90625f,57.4796f,-74.2188f, +0.0f,56.3955f,-74.2188f, +3.90625f,56.5167f,-74.2188f, +-250.0f,8.88618f,-78.125f, +-246.094f,8.31776f,-78.125f, +-242.188f,8.67289f,-78.125f, +-238.281f,9.52219f,-78.125f, +-234.375f,9.78196f,-78.125f, +-230.469f,11.3032f,-78.125f, +-226.563f,13.1558f,-78.125f, +-222.656f,14.4361f,-78.125f, +-218.75f,15.5721f,-78.125f, +-214.844f,14.3491f,-78.125f, +-210.938f,15.6393f,-78.125f, +-207.031f,16.9133f,-78.125f, +-203.125f,18.1402f,-78.125f, +-199.219f,19.179f,-78.125f, +-195.313f,18.9448f,-78.125f, +-191.406f,19.5289f,-78.125f, +-187.5f,20.8547f,-78.125f, +-183.594f,22.7611f,-78.125f, +-179.688f,22.8314f,-78.125f, +-175.781f,21.815f,-78.125f, +-171.875f,22.2112f,-78.125f, +-167.969f,21.9322f,-78.125f, +-164.063f,21.3024f,-78.125f, +-160.156f,20.354f,-78.125f, +-156.25f,19.8588f,-78.125f, +-152.344f,17.8458f,-78.125f, +-148.438f,18.0613f,-78.125f, +-144.531f,17.0664f,-78.125f, +-140.625f,16.2256f,-78.125f, +-136.719f,14.3082f,-78.125f, +-132.813f,13.3463f,-78.125f, +-128.906f,14.3881f,-78.125f, +-125.0f,14.6865f,-78.125f, +-121.094f,14.2011f,-78.125f, +-117.188f,15.4562f,-78.125f, +-113.281f,16.6171f,-78.125f, +-109.375f,16.2869f,-78.125f, +-105.469f,15.9406f,-78.125f, +-101.563f,17.5579f,-78.125f, +-97.6563f,19.157f,-78.125f, +-93.75f,21.0678f,-78.125f, +-89.8438f,23.1633f,-78.125f, +-85.9375f,25.2991f,-78.125f, +-82.0313f,28.9462f,-78.125f, +-78.125f,31.8594f,-78.125f, +-74.2188f,35.2294f,-78.125f, +-70.3125f,36.9557f,-78.125f, +-66.4063f,40.692f,-78.125f, +-62.5f,44.5904f,-78.125f, +-58.5938f,46.9805f,-78.125f, +-54.6875f,48.3073f,-78.125f, +-50.7813f,49.8001f,-78.125f, +-46.875f,51.4881f,-78.125f, +-42.9688f,52.7488f,-78.125f, +-39.0625f,53.0994f,-78.125f, +-35.1563f,54.6505f,-78.125f, +-31.25f,55.3393f,-78.125f, +-27.3438f,55.3608f,-78.125f, +-23.4375f,54.3833f,-78.125f, +-19.5313f,53.9595f,-78.125f, +-15.625f,55.0695f,-78.125f, +-11.7188f,56.423f,-78.125f, +-7.8125f,56.1568f,-78.125f, +-3.90625f,56.2841f,-78.125f, +0.0f,54.7508f,-78.125f, +3.90625f,54.4402f,-78.125f, +-250.0f,10.7839f,-82.0313f, +-246.094f,10.1255f,-82.0313f, +-242.188f,10.6621f,-82.0313f, +-238.281f,11.4172f,-82.0313f, +-234.375f,12.3063f,-82.0313f, +-230.469f,13.4915f,-82.0313f, +-226.563f,14.9113f,-82.0313f, +-222.656f,16.5463f,-82.0313f, +-218.75f,17.3752f,-82.0313f, +-214.844f,16.6701f,-82.0313f, +-210.938f,15.5847f,-82.0313f, +-207.031f,16.6988f,-82.0313f, +-203.125f,17.6449f,-82.0313f, +-199.219f,18.4976f,-82.0313f, +-195.313f,18.033f,-82.0313f, +-191.406f,19.1758f,-82.0313f, +-187.5f,20.7116f,-82.0313f, +-183.594f,21.5492f,-82.0313f, +-179.688f,20.7908f,-82.0313f, +-175.781f,20.6891f,-82.0313f, +-171.875f,21.6368f,-82.0313f, +-167.969f,21.6862f,-82.0313f, +-164.063f,20.4236f,-82.0313f, +-160.156f,19.4449f,-82.0313f, +-156.25f,17.8718f,-82.0313f, +-152.344f,16.0984f,-82.0313f, +-148.438f,16.1225f,-82.0313f, +-144.531f,15.3001f,-82.0313f, +-140.625f,14.0113f,-82.0313f, +-136.719f,12.7128f,-82.0313f, +-132.813f,13.1695f,-82.0313f, +-128.906f,14.1608f,-82.0313f, +-125.0f,14.006f,-82.0313f, +-121.094f,13.5671f,-82.0313f, +-117.188f,14.799f,-82.0313f, +-113.281f,15.6819f,-82.0313f, +-109.375f,15.1047f,-82.0313f, +-105.469f,15.4826f,-82.0313f, +-101.563f,17.2178f,-82.0313f, +-97.6563f,19.1794f,-82.0313f, +-93.75f,21.3021f,-82.0313f, +-89.8438f,21.9981f,-82.0313f, +-85.9375f,24.4031f,-82.0313f, +-82.0313f,28.8062f,-82.0313f, +-78.125f,31.7576f,-82.0313f, +-74.2188f,34.6198f,-82.0313f, +-70.3125f,37.0145f,-82.0313f, +-66.4063f,39.5952f,-82.0313f, +-62.5f,43.4294f,-82.0313f, +-58.5938f,45.9611f,-82.0313f, +-54.6875f,47.398f,-82.0313f, +-50.7813f,49.5672f,-82.0313f, +-46.875f,51.4863f,-82.0313f, +-42.9688f,52.3277f,-82.0313f, +-39.0625f,52.6736f,-82.0313f, +-35.1563f,53.5554f,-82.0313f, +-31.25f,54.4611f,-82.0313f, +-27.3438f,53.3151f,-82.0313f, +-23.4375f,52.9631f,-82.0313f, +-19.5313f,52.3147f,-82.0313f, +-15.625f,53.7891f,-82.0313f, +-11.7188f,54.3962f,-82.0313f, +-7.8125f,54.2326f,-82.0313f, +-3.90625f,53.6717f,-82.0313f, +0.0f,52.8681f,-82.0313f, +3.90625f,51.949f,-82.0313f, +-250.0f,12.2756f,-85.9375f, +-246.094f,11.9011f,-85.9375f, +-242.188f,13.4495f,-85.9375f, +-238.281f,14.3858f,-85.9375f, +-234.375f,14.855f,-85.9375f, +-230.469f,15.3384f,-85.9375f, +-226.563f,17.3357f,-85.9375f, +-222.656f,18.7108f,-85.9375f, +-218.75f,18.0095f,-85.9375f, +-214.844f,17.4308f,-85.9375f, +-210.938f,17.0565f,-85.9375f, +-207.031f,16.4039f,-85.9375f, +-203.125f,17.3449f,-85.9375f, +-199.219f,17.5816f,-85.9375f, +-195.313f,17.7511f,-85.9375f, +-191.406f,18.792f,-85.9375f, +-187.5f,19.7983f,-85.9375f, +-183.594f,19.6069f,-85.9375f, +-179.688f,19.1396f,-85.9375f, +-175.781f,19.0184f,-85.9375f, +-171.875f,19.7492f,-85.9375f, +-167.969f,19.6428f,-85.9375f, +-164.063f,18.6091f,-85.9375f, +-160.156f,18.1998f,-85.9375f, +-156.25f,16.6809f,-85.9375f, +-152.344f,15.0269f,-85.9375f, +-148.438f,13.3773f,-85.9375f, +-144.531f,12.7371f,-85.9375f, +-140.625f,12.2537f,-85.9375f, +-136.719f,12.6536f,-85.9375f, +-132.813f,12.7798f,-85.9375f, +-128.906f,13.2089f,-85.9375f, +-125.0f,12.8356f,-85.9375f, +-121.094f,12.5484f,-85.9375f, +-117.188f,13.5275f,-85.9375f, +-113.281f,13.5387f,-85.9375f, +-109.375f,13.6111f,-85.9375f, +-105.469f,14.7023f,-85.9375f, +-101.563f,16.6526f,-85.9375f, +-97.6563f,17.9729f,-85.9375f, +-93.75f,19.8258f,-85.9375f, +-89.8438f,21.7903f,-85.9375f, +-85.9375f,23.4003f,-85.9375f, +-82.0313f,27.4381f,-85.9375f, +-78.125f,30.1644f,-85.9375f, +-74.2188f,33.7682f,-85.9375f, +-70.3125f,36.1779f,-85.9375f, +-66.4063f,38.1368f,-85.9375f, +-62.5f,41.5768f,-85.9375f, +-58.5938f,43.7832f,-85.9375f, +-54.6875f,45.866f,-85.9375f, +-50.7813f,48.5751f,-85.9375f, +-46.875f,50.4188f,-85.9375f, +-42.9688f,51.0239f,-85.9375f, +-39.0625f,51.2389f,-85.9375f, +-35.1563f,51.8865f,-85.9375f, +-31.25f,52.9036f,-85.9375f, +-27.3438f,52.5405f,-85.9375f, +-23.4375f,52.3296f,-85.9375f, +-19.5313f,52.5889f,-85.9375f, +-15.625f,52.3033f,-85.9375f, +-11.7188f,52.1239f,-85.9375f, +-7.8125f,52.0608f,-85.9375f, +-3.90625f,51.0213f,-85.9375f, +0.0f,50.5601f,-85.9375f, +3.90625f,50.007f,-85.9375f, +-250.0f,13.6424f,-89.8438f, +-246.094f,14.2919f,-89.8438f, +-242.188f,15.9647f,-89.8438f, +-238.281f,17.1274f,-89.8438f, +-234.375f,17.9206f,-89.8438f, +-230.469f,17.9917f,-89.8438f, +-226.563f,19.3423f,-89.8438f, +-222.656f,20.1401f,-89.8438f, +-218.75f,19.295f,-89.8438f, +-214.844f,18.1101f,-89.8438f, +-210.938f,17.3485f,-89.8438f, +-207.031f,17.1077f,-89.8438f, +-203.125f,17.7413f,-89.8438f, +-199.219f,17.2325f,-89.8438f, +-195.313f,17.6696f,-89.8438f, +-191.406f,18.8437f,-89.8438f, +-187.5f,19.1808f,-89.8438f, +-183.594f,18.6366f,-89.8438f, +-179.688f,17.3251f,-89.8438f, +-175.781f,17.5752f,-89.8438f, +-171.875f,18.1005f,-89.8438f, +-167.969f,18.0907f,-89.8438f, +-164.063f,16.519f,-89.8438f, +-160.156f,15.5225f,-89.8438f, +-156.25f,14.3937f,-89.8438f, +-152.344f,13.4199f,-89.8438f, +-148.438f,12.8584f,-89.8438f, +-144.531f,12.8604f,-89.8438f, +-140.625f,12.2817f,-89.8438f, +-136.719f,12.4113f,-89.8438f, +-132.813f,12.9949f,-89.8438f, +-128.906f,11.9716f,-89.8438f, +-125.0f,11.8348f,-89.8438f, +-121.094f,12.2532f,-89.8438f, +-117.188f,12.5983f,-89.8438f, +-113.281f,13.2095f,-89.8438f, +-109.375f,13.7209f,-89.8438f, +-105.469f,13.8655f,-89.8438f, +-101.563f,14.8679f,-89.8438f, +-97.6563f,16.1039f,-89.8438f, +-93.75f,17.9997f,-89.8438f, +-89.8438f,20.0247f,-89.8438f, +-85.9375f,22.8012f,-89.8438f, +-82.0313f,25.8255f,-89.8438f, +-78.125f,29.0288f,-89.8438f, +-74.2188f,31.8325f,-89.8438f, +-70.3125f,34.2688f,-89.8438f, +-66.4063f,37.2576f,-89.8438f, +-62.5f,40.8036f,-89.8438f, +-58.5938f,43.0354f,-89.8438f, +-54.6875f,44.5176f,-89.8438f, +-50.7813f,47.4827f,-89.8438f, +-46.875f,48.9307f,-89.8438f, +-42.9688f,48.82f,-89.8438f, +-39.0625f,48.8887f,-89.8438f, +-35.1563f,50.05f,-89.8438f, +-31.25f,50.9253f,-89.8438f, +-27.3438f,52.3859f,-89.8438f, +-23.4375f,52.2702f,-89.8438f, +-19.5313f,52.0708f,-89.8438f, +-15.625f,51.2832f,-89.8438f, +-11.7188f,50.0989f,-89.8438f, +-7.8125f,49.6111f,-89.8438f, +-3.90625f,48.7785f,-89.8438f, +0.0f,48.7183f,-89.8438f, +3.90625f,47.6596f,-89.8438f, +-250.0f,15.247f,-93.75f, +-246.094f,17.6018f,-93.75f, +-242.188f,19.2494f,-93.75f, +-238.281f,20.8362f,-93.75f, +-234.375f,20.4345f,-93.75f, +-230.469f,21.1572f,-93.75f, +-226.563f,21.3131f,-93.75f, +-222.656f,20.8797f,-93.75f, +-218.75f,20.5347f,-93.75f, +-214.844f,19.3559f,-93.75f, +-210.938f,18.2443f,-93.75f, +-207.031f,17.5994f,-93.75f, +-203.125f,18.0336f,-93.75f, +-199.219f,18.0561f,-93.75f, +-195.313f,17.673f,-93.75f, +-191.406f,18.7132f,-93.75f, +-187.5f,18.4272f,-93.75f, +-183.594f,18.078f,-93.75f, +-179.688f,16.7984f,-93.75f, +-175.781f,16.1827f,-93.75f, +-171.875f,16.5937f,-93.75f, +-167.969f,16.0698f,-93.75f, +-164.063f,14.9813f,-93.75f, +-160.156f,13.1718f,-93.75f, +-156.25f,12.1738f,-93.75f, +-152.344f,12.229f,-93.75f, +-148.438f,12.2803f,-93.75f, +-144.531f,12.526f,-93.75f, +-140.625f,11.9028f,-93.75f, +-136.719f,12.3491f,-93.75f, +-132.813f,11.7412f,-93.75f, +-128.906f,11.5455f,-93.75f, +-125.0f,11.6285f,-93.75f, +-121.094f,11.478f,-93.75f, +-117.188f,11.536f,-93.75f, +-113.281f,11.8722f,-93.75f, +-109.375f,12.61f,-93.75f, +-105.469f,12.6899f,-93.75f, +-101.563f,13.1659f,-93.75f, +-97.6563f,14.5994f,-93.75f, +-93.75f,16.6015f,-93.75f, +-89.8438f,19.9429f,-93.75f, +-85.9375f,22.8876f,-93.75f, +-82.0313f,26.3209f,-93.75f, +-78.125f,28.8526f,-93.75f, +-74.2188f,30.2969f,-93.75f, +-70.3125f,33.1597f,-93.75f, +-66.4063f,36.2648f,-93.75f, +-62.5f,39.1918f,-93.75f, +-58.5938f,41.4171f,-93.75f, +-54.6875f,43.4299f,-93.75f, +-50.7813f,45.5438f,-93.75f, +-46.875f,46.6281f,-93.75f, +-42.9688f,46.784f,-93.75f, +-39.0625f,47.3415f,-93.75f, +-35.1563f,48.5539f,-93.75f, +-31.25f,50.5714f,-93.75f, +-27.3438f,51.0532f,-93.75f, +-23.4375f,51.7685f,-93.75f, +-19.5313f,51.3638f,-93.75f, +-15.625f,49.6289f,-93.75f, +-11.7188f,50.0322f,-93.75f, +-7.8125f,48.6289f,-93.75f, +-3.90625f,46.7733f,-93.75f, +0.0f,45.5993f,-93.75f, +3.90625f,45.4182f,-93.75f, +-250.0f,18.5038f,-97.6563f, +-246.094f,20.1199f,-97.6563f, +-242.188f,22.7365f,-97.6563f, +-238.281f,24.311f,-97.6563f, +-234.375f,24.2572f,-97.6563f, +-230.469f,24.3322f,-97.6563f, +-226.563f,24.3501f,-97.6563f, +-222.656f,23.3494f,-97.6563f, +-218.75f,21.7677f,-97.6563f, +-214.844f,20.6573f,-97.6563f, +-210.938f,18.8509f,-97.6563f, +-207.031f,18.1355f,-97.6563f, +-203.125f,18.5785f,-97.6563f, +-199.219f,18.2049f,-97.6563f, +-195.313f,17.4136f,-97.6563f, +-191.406f,18.6105f,-97.6563f, +-187.5f,18.0859f,-97.6563f, +-183.594f,17.3286f,-97.6563f, +-179.688f,16.66f,-97.6563f, +-175.781f,15.1619f,-97.6563f, +-171.875f,14.271f,-97.6563f, +-167.969f,13.4801f,-97.6563f, +-164.063f,12.6373f,-97.6563f, +-160.156f,11.4464f,-97.6563f, +-156.25f,11.5423f,-97.6563f, +-152.344f,11.795f,-97.6563f, +-148.438f,10.9108f,-97.6563f, +-144.531f,11.2217f,-97.6563f, +-140.625f,11.0533f,-97.6563f, +-136.719f,11.5512f,-97.6563f, +-132.813f,11.6628f,-97.6563f, +-128.906f,10.9589f,-97.6563f, +-125.0f,10.3779f,-97.6563f, +-121.094f,9.96294f,-97.6563f, +-117.188f,10.6728f,-97.6563f, +-113.281f,11.2587f,-97.6563f, +-109.375f,11.2512f,-97.6563f, +-105.469f,12.1215f,-97.6563f, +-101.563f,12.0908f,-97.6563f, +-97.6563f,13.5835f,-97.6563f, +-93.75f,16.6536f,-97.6563f, +-89.8438f,19.7104f,-97.6563f, +-85.9375f,22.8325f,-97.6563f, +-82.0313f,26.7422f,-97.6563f, +-78.125f,29.4762f,-97.6563f, +-74.2188f,30.148f,-97.6563f, +-70.3125f,33.5961f,-97.6563f, +-66.4063f,36.1685f,-97.6563f, +-62.5f,37.3648f,-97.6563f, +-58.5938f,39.4445f,-97.6563f, +-54.6875f,40.3698f,-97.6563f, +-50.7813f,43.2595f,-97.6563f, +-46.875f,43.8006f,-97.6563f, +-42.9688f,44.8371f,-97.6563f, +-39.0625f,46.8993f,-97.6563f, +-35.1563f,48.8152f,-97.6563f, +-31.25f,50.2801f,-97.6563f, +-27.3438f,49.7242f,-97.6563f, +-23.4375f,49.8502f,-97.6563f, +-19.5313f,49.8568f,-97.6563f, +-15.625f,48.3267f,-97.6563f, +-11.7188f,47.8521f,-97.6563f, +-7.8125f,47.3364f,-97.6563f, +-3.90625f,46.156f,-97.6563f, +0.0f,44.8966f,-97.6563f, +3.90625f,44.9637f,-97.6563f, +-250.0f,21.0334f,-101.563f, +-246.094f,23.093f,-101.563f, +-242.188f,25.4189f,-101.563f, +-238.281f,27.31f,-101.563f, +-234.375f,26.8223f,-101.563f, +-230.469f,26.375f,-101.563f, +-226.563f,26.7718f,-101.563f, +-222.656f,25.3642f,-101.563f, +-218.75f,23.7619f,-101.563f, +-214.844f,21.4458f,-101.563f, +-210.938f,19.7809f,-101.563f, +-207.031f,19.054f,-101.563f, +-203.125f,19.6087f,-101.563f, +-199.219f,19.2503f,-101.563f, +-195.313f,18.0809f,-101.563f, +-191.406f,17.75f,-101.563f, +-187.5f,17.1292f,-101.563f, +-183.594f,16.2151f,-101.563f, +-179.688f,15.8928f,-101.563f, +-175.781f,14.4866f,-101.563f, +-171.875f,13.9039f,-101.563f, +-167.969f,12.278f,-101.563f, +-164.063f,11.5804f,-101.563f, +-160.156f,12.0152f,-101.563f, +-156.25f,11.7113f,-101.563f, +-152.344f,10.7496f,-101.563f, +-148.438f,9.67121f,-101.563f, +-144.531f,9.72628f,-101.563f, +-140.625f,9.99849f,-101.563f, +-136.719f,10.504f,-101.563f, +-132.813f,11.0917f,-101.563f, +-128.906f,10.4997f,-101.563f, +-125.0f,9.12306f,-101.563f, +-121.094f,8.34841f,-101.563f, +-117.188f,8.92074f,-101.563f, +-113.281f,9.44857f,-101.563f, +-109.375f,10.5456f,-101.563f, +-105.469f,10.7435f,-101.563f, +-101.563f,11.6413f,-101.563f, +-97.6563f,14.2233f,-101.563f, +-93.75f,17.0641f,-101.563f, +-89.8438f,20.5963f,-101.563f, +-85.9375f,22.9601f,-101.563f, +-82.0313f,26.0881f,-101.563f, +-78.125f,28.3451f,-101.563f, +-74.2188f,30.4473f,-101.563f, +-70.3125f,33.7644f,-101.563f, +-66.4063f,36.3074f,-101.563f, +-62.5f,38.0683f,-101.563f, +-58.5938f,39.1597f,-101.563f, +-54.6875f,40.3396f,-101.563f, +-50.7813f,41.4946f,-101.563f, +-46.875f,43.0029f,-101.563f, +-42.9688f,44.8434f,-101.563f, +-39.0625f,47.2094f,-101.563f, +-35.1563f,47.3449f,-101.563f, +-31.25f,49.1989f,-101.563f, +-27.3438f,48.845f,-101.563f, +-23.4375f,47.635f,-101.563f, +-19.5313f,47.9355f,-101.563f, +-15.625f,47.1439f,-101.563f, +-11.7188f,45.929f,-101.563f, +-7.8125f,46.9058f,-101.563f, +-3.90625f,46.1235f,-101.563f, +0.0f,45.2655f,-101.563f, +3.90625f,44.5311f,-101.563f, +-250.0f,24.0006f,-105.469f, +-246.094f,26.733f,-105.469f, +-242.188f,28.4305f,-105.469f, +-238.281f,29.0431f,-105.469f, +-234.375f,28.1582f,-105.469f, +-230.469f,28.0178f,-105.469f, +-226.563f,27.4417f,-105.469f, +-222.656f,27.0081f,-105.469f, +-218.75f,24.9646f,-105.469f, +-214.844f,22.8713f,-105.469f, +-210.938f,21.4507f,-105.469f, +-207.031f,21.2058f,-105.469f, +-203.125f,20.8114f,-105.469f, +-199.219f,20.7281f,-105.469f, +-195.313f,19.7358f,-105.469f, +-191.406f,18.4733f,-105.469f, +-187.5f,17.1875f,-105.469f, +-183.594f,15.4383f,-105.469f, +-179.688f,14.151f,-105.469f, +-175.781f,13.882f,-105.469f, +-171.875f,12.9008f,-105.469f, +-167.969f,11.246f,-105.469f, +-164.063f,11.1287f,-105.469f, +-160.156f,10.748f,-105.469f, +-156.25f,11.5003f,-105.469f, +-152.344f,10.3683f,-105.469f, +-148.438f,9.87346f,-105.469f, +-144.531f,9.6524f,-105.469f, +-140.625f,8.36957f,-105.469f, +-136.719f,9.12242f,-105.469f, +-132.813f,9.41585f,-105.469f, +-128.906f,8.97735f,-105.469f, +-125.0f,7.89593f,-105.469f, +-121.094f,7.20155f,-105.469f, +-117.188f,6.63681f,-105.469f, +-113.281f,8.27572f,-105.469f, +-109.375f,8.39126f,-105.469f, +-105.469f,9.69363f,-105.469f, +-101.563f,12.2269f,-105.469f, +-97.6563f,15.3785f,-105.469f, +-93.75f,18.1643f,-105.469f, +-89.8438f,20.8715f,-105.469f, +-85.9375f,23.5096f,-105.469f, +-82.0313f,25.2072f,-105.469f, +-78.125f,27.8536f,-105.469f, +-74.2188f,30.8436f,-105.469f, +-70.3125f,33.8966f,-105.469f, +-66.4063f,36.3107f,-105.469f, +-62.5f,37.9291f,-105.469f, +-58.5938f,39.7963f,-105.469f, +-54.6875f,40.5554f,-105.469f, +-50.7813f,42.1374f,-105.469f, +-46.875f,42.7622f,-105.469f, +-42.9688f,44.5703f,-105.469f, +-39.0625f,46.4665f,-105.469f, +-35.1563f,46.6101f,-105.469f, +-31.25f,47.1188f,-105.469f, +-27.3438f,48.052f,-105.469f, +-23.4375f,47.7845f,-105.469f, +-19.5313f,47.8159f,-105.469f, +-15.625f,46.7772f,-105.469f, +-11.7188f,46.0033f,-105.469f, +-7.8125f,47.2861f,-105.469f, +-3.90625f,46.9832f,-105.469f, +0.0f,45.6472f,-105.469f, +3.90625f,44.8466f,-105.469f, +-250.0f,27.0053f,-109.375f, +-246.094f,28.4873f,-109.375f, +-242.188f,29.8219f,-109.375f, +-238.281f,30.0561f,-109.375f, +-234.375f,29.2892f,-109.375f, +-230.469f,29.5933f,-109.375f, +-226.563f,28.8697f,-109.375f, +-222.656f,27.4881f,-109.375f, +-218.75f,25.7165f,-109.375f, +-214.844f,23.9985f,-109.375f, +-210.938f,23.3958f,-109.375f, +-207.031f,23.3567f,-109.375f, +-203.125f,23.3311f,-109.375f, +-199.219f,22.2114f,-109.375f, +-195.313f,21.0452f,-109.375f, +-191.406f,20.2153f,-109.375f, +-187.5f,18.8202f,-109.375f, +-183.594f,16.7998f,-109.375f, +-179.688f,15.8942f,-109.375f, +-175.781f,14.8638f,-109.375f, +-171.875f,13.1475f,-109.375f, +-167.969f,12.7375f,-109.375f, +-164.063f,10.7456f,-109.375f, +-160.156f,10.2908f,-109.375f, +-156.25f,9.65347f,-109.375f, +-152.344f,10.1273f,-109.375f, +-148.438f,9.91826f,-109.375f, +-144.531f,8.92229f,-109.375f, +-140.625f,8.34112f,-109.375f, +-136.719f,7.82043f,-109.375f, +-132.813f,7.17703f,-109.375f, +-128.906f,7.28288f,-109.375f, +-125.0f,6.94364f,-109.375f, +-121.094f,6.57742f,-109.375f, +-117.188f,5.68794f,-109.375f, +-113.281f,5.66654f,-109.375f, +-109.375f,6.9457f,-109.375f, +-105.469f,9.81036f,-109.375f, +-101.563f,12.6651f,-109.375f, +-97.6563f,15.2246f,-109.375f, +-93.75f,18.3914f,-109.375f, +-89.8438f,21.0454f,-109.375f, +-85.9375f,23.3579f,-109.375f, +-82.0313f,25.0292f,-109.375f, +-78.125f,28.9637f,-109.375f, +-74.2188f,31.9858f,-109.375f, +-70.3125f,34.5815f,-109.375f, +-66.4063f,37.1495f,-109.375f, +-62.5f,38.5371f,-109.375f, +-58.5938f,39.6993f,-109.375f, +-54.6875f,41.3314f,-109.375f, +-50.7813f,42.3279f,-109.375f, +-46.875f,43.399f,-109.375f, +-42.9688f,44.8971f,-109.375f, +-39.0625f,46.4515f,-109.375f, +-35.1563f,46.6684f,-109.375f, +-31.25f,47.2696f,-109.375f, +-27.3438f,48.2082f,-109.375f, +-23.4375f,47.2707f,-109.375f, +-19.5313f,47.952f,-109.375f, +-15.625f,47.4088f,-109.375f, +-11.7188f,47.3981f,-109.375f, +-7.8125f,48.0766f,-109.375f, +-3.90625f,47.4974f,-109.375f, +0.0f,46.1817f,-109.375f, +3.90625f,45.3987f,-109.375f, +-250.0f,28.5243f,-113.281f, +-246.094f,30.3032f,-113.281f, +-242.188f,31.2443f,-113.281f, +-238.281f,30.733f,-113.281f, +-234.375f,31.2433f,-113.281f, +-230.469f,31.5829f,-113.281f, +-226.563f,30.3008f,-113.281f, +-222.656f,28.2348f,-113.281f, +-218.75f,25.8116f,-113.281f, +-214.844f,25.3702f,-113.281f, +-210.938f,24.8435f,-113.281f, +-207.031f,25.7524f,-113.281f, +-203.125f,26.0021f,-113.281f, +-199.219f,24.9024f,-113.281f, +-195.313f,23.7348f,-113.281f, +-191.406f,21.9608f,-113.281f, +-187.5f,20.2108f,-113.281f, +-183.594f,18.963f,-113.281f, +-179.688f,17.7929f,-113.281f, +-175.781f,16.3625f,-113.281f, +-171.875f,14.6525f,-113.281f, +-167.969f,13.4453f,-113.281f, +-164.063f,11.5352f,-113.281f, +-160.156f,10.457f,-113.281f, +-156.25f,9.86849f,-113.281f, +-152.344f,9.76379f,-113.281f, +-148.438f,9.40799f,-113.281f, +-144.531f,8.38098f,-113.281f, +-140.625f,8.03078f,-113.281f, +-136.719f,7.4536f,-113.281f, +-132.813f,6.32375f,-113.281f, +-128.906f,5.90846f,-113.281f, +-125.0f,5.44126f,-113.281f, +-121.094f,5.53385f,-113.281f, +-117.188f,5.35081f,-113.281f, +-113.281f,6.14244f,-113.281f, +-109.375f,7.72509f,-113.281f, +-105.469f,9.98969f,-113.281f, +-101.563f,12.8924f,-113.281f, +-97.6563f,15.6605f,-113.281f, +-93.75f,18.4427f,-113.281f, +-89.8438f,20.4633f,-113.281f, +-85.9375f,22.3484f,-113.281f, +-82.0313f,25.7434f,-113.281f, +-78.125f,29.5649f,-113.281f, +-74.2188f,32.7377f,-113.281f, +-70.3125f,34.4529f,-113.281f, +-66.4063f,37.0096f,-113.281f, +-62.5f,38.2565f,-113.281f, +-58.5938f,39.8951f,-113.281f, +-54.6875f,41.291f,-113.281f, +-50.7813f,42.6018f,-113.281f, +-46.875f,43.3624f,-113.281f, +-42.9688f,44.3449f,-113.281f, +-39.0625f,45.4446f,-113.281f, +-35.1563f,46.0157f,-113.281f, +-31.25f,47.6632f,-113.281f, +-27.3438f,47.6934f,-113.281f, +-23.4375f,46.4824f,-113.281f, +-19.5313f,48.2708f,-113.281f, +-15.625f,48.5036f,-113.281f, +-11.7188f,47.6795f,-113.281f, +-7.8125f,48.4742f,-113.281f, +-3.90625f,48.509f,-113.281f, +0.0f,47.4037f,-113.281f, +3.90625f,47.4869f,-113.281f, +-250.0f,30.7007f,-117.188f, +-246.094f,31.6625f,-117.188f, +-242.188f,31.8246f,-117.188f, +-238.281f,32.4951f,-117.188f, +-234.375f,33.3552f,-117.188f, +-230.469f,32.7471f,-117.188f, +-226.563f,30.8092f,-117.188f, +-222.656f,28.3135f,-117.188f, +-218.75f,27.0912f,-117.188f, +-214.844f,27.0184f,-117.188f, +-210.938f,27.5702f,-117.188f, +-207.031f,27.9311f,-117.188f, +-203.125f,28.0909f,-117.188f, +-199.219f,26.6916f,-117.188f, +-195.313f,25.6983f,-117.188f, +-191.406f,24.0617f,-117.188f, +-187.5f,22.1476f,-117.188f, +-183.594f,20.964f,-117.188f, +-179.688f,19.1417f,-117.188f, +-175.781f,18.0941f,-117.188f, +-171.875f,16.3483f,-117.188f, +-167.969f,13.8969f,-117.188f, +-164.063f,12.2065f,-117.188f, +-160.156f,10.4346f,-117.188f, +-156.25f,9.28283f,-117.188f, +-152.344f,8.20933f,-117.188f, +-148.438f,7.69157f,-117.188f, +-144.531f,7.05251f,-117.188f, +-140.625f,6.38685f,-117.188f, +-136.719f,5.88862f,-117.188f, +-132.813f,4.48007f,-117.188f, +-128.906f,4.03049f,-117.188f, +-125.0f,4.96603f,-117.188f, +-121.094f,6.08105f,-117.188f, +-117.188f,6.76315f,-117.188f, +-113.281f,7.41087f,-117.188f, +-109.375f,7.5353f,-117.188f, +-105.469f,9.88018f,-117.188f, +-101.563f,11.8887f,-117.188f, +-97.6563f,14.4702f,-117.188f, +-93.75f,17.2187f,-117.188f, +-89.8438f,20.2241f,-117.188f, +-85.9375f,22.2766f,-117.188f, +-82.0313f,25.968f,-117.188f, +-78.125f,29.2923f,-117.188f, +-74.2188f,31.9825f,-117.188f, +-70.3125f,34.0756f,-117.188f, +-66.4063f,35.9202f,-117.188f, +-62.5f,37.9131f,-117.188f, +-58.5938f,39.2288f,-117.188f, +-54.6875f,40.591f,-117.188f, +-50.7813f,42.5191f,-117.188f, +-46.875f,42.7237f,-117.188f, +-42.9688f,43.8388f,-117.188f, +-39.0625f,45.2151f,-117.188f, +-35.1563f,45.096f,-117.188f, +-31.25f,45.9904f,-117.188f, +-27.3438f,45.2594f,-117.188f, +-23.4375f,45.7333f,-117.188f, +-19.5313f,47.4248f,-117.188f, +-15.625f,48.122f,-117.188f, +-11.7188f,48.0312f,-117.188f, +-7.8125f,49.0431f,-117.188f, +-3.90625f,49.2804f,-117.188f, +0.0f,48.803f,-117.188f, +3.90625f,48.3887f,-117.188f, +-250.0f,31.7497f,-121.094f, +-246.094f,31.3973f,-121.094f, +-242.188f,32.0742f,-121.094f, +-238.281f,33.1521f,-121.094f, +-234.375f,33.6068f,-121.094f, +-230.469f,31.9815f,-121.094f, +-226.563f,30.2957f,-121.094f, +-222.656f,28.5699f,-121.094f, +-218.75f,28.3353f,-121.094f, +-214.844f,28.8422f,-121.094f, +-210.938f,29.4292f,-121.094f, +-207.031f,29.2833f,-121.094f, +-203.125f,28.4123f,-121.094f, +-199.219f,27.4455f,-121.094f, +-195.313f,26.9053f,-121.094f, +-191.406f,24.8164f,-121.094f, +-187.5f,22.4409f,-121.094f, +-183.594f,21.5447f,-121.094f, +-179.688f,20.6668f,-121.094f, +-175.781f,18.9757f,-121.094f, +-171.875f,16.8092f,-121.094f, +-167.969f,14.4997f,-121.094f, +-164.063f,13.0122f,-121.094f, +-160.156f,11.2904f,-121.094f, +-156.25f,9.63825f,-121.094f, +-152.344f,8.62771f,-121.094f, +-148.438f,7.36842f,-121.094f, +-144.531f,6.44275f,-121.094f, +-140.625f,5.50805f,-121.094f, +-136.719f,6.00349f,-121.094f, +-132.813f,4.67796f,-121.094f, +-128.906f,3.93081f,-121.094f, +-125.0f,5.39329f,-121.094f, +-121.094f,6.95361f,-121.094f, +-117.188f,8.00676f,-121.094f, +-113.281f,7.76936f,-121.094f, +-109.375f,8.598f,-121.094f, +-105.469f,9.71941f,-121.094f, +-101.563f,11.4789f,-121.094f, +-97.6563f,13.572f,-121.094f, +-93.75f,16.0296f,-121.094f, +-89.8438f,18.5079f,-121.094f, +-85.9375f,22.5232f,-121.094f, +-82.0313f,25.7298f,-121.094f, +-78.125f,29.0421f,-121.094f, +-74.2188f,31.8936f,-121.094f, +-70.3125f,33.6857f,-121.094f, +-66.4063f,35.8951f,-121.094f, +-62.5f,37.4244f,-121.094f, +-58.5938f,39.1337f,-121.094f, +-54.6875f,40.6842f,-121.094f, +-50.7813f,41.8829f,-121.094f, +-46.875f,42.9851f,-121.094f, +-42.9688f,42.3613f,-121.094f, +-39.0625f,44.0627f,-121.094f, +-35.1563f,43.3741f,-121.094f, +-31.25f,43.2393f,-121.094f, +-27.3438f,44.1982f,-121.094f, +-23.4375f,45.2747f,-121.094f, +-19.5313f,46.6461f,-121.094f, +-15.625f,47.338f,-121.094f, +-11.7188f,48.1318f,-121.094f, +-7.8125f,49.3601f,-121.094f, +-3.90625f,49.6752f,-121.094f, +0.0f,49.3611f,-121.094f, +3.90625f,49.6769f,-121.094f, +-250.0f,31.4025f,-125.0f, +-246.094f,31.4165f,-125.0f, +-242.188f,32.314f,-125.0f, +-238.281f,32.9822f,-125.0f, +-234.375f,32.6962f,-125.0f, +-230.469f,31.3632f,-125.0f, +-226.563f,29.4391f,-125.0f, +-222.656f,29.519f,-125.0f, +-218.75f,29.4481f,-125.0f, +-214.844f,29.8481f,-125.0f, +-210.938f,30.408f,-125.0f, +-207.031f,30.291f,-125.0f, +-203.125f,28.7473f,-125.0f, +-199.219f,28.1816f,-125.0f, +-195.313f,27.2839f,-125.0f, +-191.406f,25.7018f,-125.0f, +-187.5f,23.2882f,-125.0f, +-183.594f,22.1614f,-125.0f, +-179.688f,20.658f,-125.0f, +-175.781f,18.8433f,-125.0f, +-171.875f,16.364f,-125.0f, +-167.969f,14.7298f,-125.0f, +-164.063f,12.9859f,-125.0f, +-160.156f,11.3306f,-125.0f, +-156.25f,10.1916f,-125.0f, +-152.344f,8.3967f,-125.0f, +-148.438f,6.23292f,-125.0f, +-144.531f,5.48985f,-125.0f, +-140.625f,5.18276f,-125.0f, +-136.719f,5.56059f,-125.0f, +-132.813f,5.75157f,-125.0f, +-128.906f,5.32154f,-125.0f, +-125.0f,6.15672f,-125.0f, +-121.094f,7.53373f,-125.0f, +-117.188f,8.38676f,-125.0f, +-113.281f,8.64274f,-125.0f, +-109.375f,8.49941f,-125.0f, +-105.469f,9.24481f,-125.0f, +-101.563f,11.5178f,-125.0f, +-97.6563f,13.4113f,-125.0f, +-93.75f,15.4997f,-125.0f, +-89.8438f,17.3502f,-125.0f, +-85.9375f,20.8168f,-125.0f, +-82.0313f,24.9405f,-125.0f, +-78.125f,27.8681f,-125.0f, +-74.2188f,30.1495f,-125.0f, +-70.3125f,32.4402f,-125.0f, +-66.4063f,34.2537f,-125.0f, +-62.5f,36.5623f,-125.0f, +-58.5938f,38.9027f,-125.0f, +-54.6875f,40.1192f,-125.0f, +-50.7813f,41.9393f,-125.0f, +-46.875f,41.8765f,-125.0f, +-42.9688f,41.6371f,-125.0f, +-39.0625f,41.6432f,-125.0f, +-35.1563f,41.2852f,-125.0f, +-31.25f,41.5629f,-125.0f, +-27.3438f,42.2956f,-125.0f, +-23.4375f,43.9719f,-125.0f, +-19.5313f,46.2232f,-125.0f, +-15.625f,47.3104f,-125.0f, +-11.7188f,47.5943f,-125.0f, +-7.8125f,49.1192f,-125.0f, +-3.90625f,49.6341f,-125.0f, +0.0f,50.3481f,-125.0f, +3.90625f,50.3021f,-125.0f, +}; + +btScalar Landscape05Nml[] = { +-0.379368f,0.918093f,-0.114827f, +-0.372144f,0.893697f,-0.250627f, +-0.36483f,0.925769f,-0.0992527f, +-0.303739f,0.924201f,-0.231506f, +-0.333317f,0.942796f,0.0059764f, +-0.301915f,0.940094f,-0.158338f, +-0.363026f,0.931698f,0.0122604f, +-0.316966f,0.945703f,-0.0719588f, +-0.334188f,0.941548f,0.0424963f, +-0.326039f,0.944563f,-0.0387196f, +-0.382515f,0.923758f,0.0188291f, +-0.388659f,0.920843f,-0.0315106f, +-0.393577f,0.919186f,-0.013971f, +-0.384968f,0.922772f,-0.0170923f, +-0.36589f,0.930393f,-0.0222354f, +-0.357745f,0.933231f,0.0331438f, +-0.482959f,0.873942f,-0.0545559f, +-0.473203f,0.879732f,0.0463645f, +-0.550088f,0.834035f,-0.0423024f, +-0.534007f,0.844766f,0.0347315f, +-0.469703f,0.882824f,0.000376011f, +-0.490919f,0.868868f,0.0637728f, +-0.552202f,0.826862f,-0.106641f, +-0.558464f,0.829519f,0.00395409f, +-0.437742f,0.897949f,-0.0454837f, +-0.437659f,0.898576f,0.0318733f, +-0.370538f,0.927929f,-0.0406078f, +-0.403245f,0.912789f,-0.064878f, +-0.385648f,0.921933f,-0.0362754f, +-0.356223f,0.934382f,-0.00604283f, +-0.30076f,0.953691f,-0.00400305f, +-0.305622f,0.951852f,0.0239231f, +-0.284526f,0.956527f,-0.0640436f, +-0.380428f,0.91278f,-0.148684f, +-0.270228f,0.949845f,-0.157392f, +-0.258662f,0.947281f,-0.189085f, +-0.182234f,0.978377f,-0.0978241f, +-0.170558f,0.969333f,-0.176927f, +-0.205282f,0.978149f,-0.0329196f, +-0.190223f,0.949267f,-0.250415f, +-0.274135f,0.959498f,0.0649128f, +-0.310884f,0.912161f,-0.267046f, +-0.496348f,0.868119f,0.00275513f, +-0.43081f,0.896388f,-0.104358f, +-0.405094f,0.913485f,0.0380057f, +-0.324068f,0.9389f,0.115955f, +-0.25697f,0.965908f,0.0314342f, +-0.271227f,0.948776f,0.162051f, +-0.254963f,0.963309f,-0.0838379f, +-0.344475f,0.938191f,-0.03368f, +-0.111765f,0.981495f,-0.15549f, +-0.167507f,0.982459f,-0.0819529f, +-0.0010222f,0.966945f,-0.254984f, +-0.0444844f,0.98477f,-0.168075f, +0.186055f,0.950323f,-0.249537f, +0.1896f,0.965697f,-0.177427f, +0.271688f,0.939248f,-0.209761f, +0.279232f,0.936599f,-0.211687f, +0.322549f,0.939459f,-0.115666f, +0.354799f,0.922502f,-0.152013f, +0.252542f,0.965579f,-0.0622893f, +0.223889f,0.935481f,-0.273404f, +0.054661f,0.998373f,-0.0162575f, +0.0861707f,0.972348f,-0.217056f, +0.0124775f,0.999913f,-0.00421609f, +0.0330599f,0.976575f,-0.212621f, +0.0918366f,0.994675f,0.046771f, +0.166973f,0.980978f,-0.0990035f, +0.0387017f,0.993028f,0.111346f, +0.125297f,0.990619f,0.054541f, +0.0541059f,0.984899f,0.164456f, +0.149711f,0.968151f,0.200673f, +0.168008f,0.956272f,0.239411f, +0.195367f,0.93223f,0.304595f, +0.147118f,0.96491f,0.217497f, +0.125818f,0.960755f,0.247225f, +0.270517f,0.934497f,0.23138f, +0.29818f,0.904256f,0.305629f, +0.363841f,0.900609f,0.237745f, +0.316827f,0.923009f,0.218347f, +0.413166f,0.893779f,0.17451f, +0.334815f,0.940911f,0.0508378f, +0.474676f,0.869519f,0.136452f, +0.456974f,0.889396f,0.0122055f, +0.272216f,0.960219f,0.0622813f, +0.228855f,0.962963f,-0.142573f, +0.0810211f,0.995842f,0.0416494f, +0.189938f,0.980101f,0.0576713f, +-0.0449078f,0.994712f,0.0923629f, +-0.00155869f,0.98749f,0.157671f, +-0.0840704f,0.991095f,0.103263f, +-0.0968834f,0.985327f,0.140515f, +0.0427121f,0.991995f,0.118832f, +-0.0240058f,0.999711f,0.000939081f, +-0.124569f,0.986858f,0.10293f, +-0.167243f,0.982306f,-0.0842863f, +-0.286295f,0.953093f,0.0982316f, +-0.243406f,0.969914f,-0.00444377f, +-0.280466f,0.950626f,0.132851f, +-0.21091f,0.972115f,0.102516f, +-0.230061f,0.951476f,0.204368f, +-0.123921f,0.950092f,0.286301f, +-0.126792f,0.952499f,0.276893f, +-0.0764868f,0.927481f,0.365962f, +-0.0452811f,0.949055f,0.31184f, +-0.138647f,0.960819f,0.240008f, +-0.25036f,0.943892f,0.215377f, +-0.314158f,0.941939f,0.118561f, +-0.458647f,0.872527f,0.168342f, +-0.427047f,0.882261f,0.198106f, +-0.485467f,0.864542f,0.129958f, +-0.523912f,0.844181f,0.113461f, +-0.532843f,0.842328f,0.081008f, +-0.518838f,0.84918f,0.0984888f, +-0.439028f,0.883929f,0.16101f, +-0.409166f,0.878784f,0.245606f, +-0.386543f,0.918859f,0.0792661f, +-0.447749f,0.88853f,0.100178f, +-0.431191f,0.90206f,0.0190184f, +-0.467639f,0.880276f,0.0801789f, +-0.518882f,0.844495f,-0.132623f, +-0.570181f,0.817923f,-0.076789f, +-0.420368f,0.883342f,-0.207357f, +-0.464447f,0.877342f,-0.120667f, +-0.386958f,0.877414f,-0.283564f, +-0.442101f,0.874511f,-0.199442f, +-0.380012f,0.859996f,-0.340584f, +-0.442865f,0.822467f,-0.356959f, +-0.24551f,0.880879f,-0.404695f, +-0.263304f,0.844058f,-0.467159f, +-0.116714f,0.897206f,-0.425909f, +-0.129252f,0.860962f,-0.491974f, +-0.352237f,0.922053f,0.160457f, +-0.402553f,0.906198f,0.129446f, +-0.377478f,0.915341f,0.140219f, +-0.336315f,0.935519f,0.10815f, +-0.335675f,0.937548f,0.0912505f, +-0.330532f,0.939201f,0.0930086f, +-0.361761f,0.931606f,0.035208f, +-0.318172f,0.947538f,0.0306247f, +-0.418525f,0.907834f,-0.0259689f, +-0.56364f,0.818048f,-0.114485f, +-0.461029f,0.882661f,-0.0914388f, +-0.472492f,0.87835f,-0.0724725f, +-0.523319f,0.846244f,-0.100037f, +-0.381187f,0.924062f,-0.0283799f, +-0.407557f,0.911105f,-0.0615298f, +-0.340677f,0.939702f,0.0299913f, +-0.237849f,0.962659f,0.129291f, +-0.233755f,0.968303f,0.0880164f, +-0.248597f,0.967837f,0.0386268f, +-0.357032f,0.933656f,0.0285478f, +-0.359392f,0.919937f,0.156695f, +-0.375075f,0.918577f,0.12464f, +-0.326685f,0.944457f,-0.0357437f, +-0.172605f,0.980131f,-0.0977257f, +-0.156177f,0.9732f,-0.168789f, +-0.0732432f,0.97238f,-0.221612f, +0.0871915f,0.980367f,-0.176858f, +0.1118f,0.973873f,-0.197667f, +0.197176f,0.978426f,-0.0616824f, +0.202039f,0.979229f,-0.0170475f, +0.172249f,0.982761f,0.0671591f, +0.0103709f,0.995351f,0.095751f, +0.00657151f,0.996617f,0.0819183f, +0.0314022f,0.995508f,0.0893156f, +0.0387801f,0.982532f,0.182011f, +0.0412148f,0.983254f,0.177521f, +0.166642f,0.964252f,0.20603f, +0.177047f,0.971307f,0.1588f, +0.255603f,0.956785f,0.138671f, +0.338465f,0.927074f,0.161166f, +0.418264f,0.886168f,0.199401f, +0.454161f,0.868211f,0.199869f, +0.355471f,0.903694f,0.2387f, +0.136408f,0.975339f,0.173515f, +-0.0223692f,0.983821f,0.177753f, +-0.0947578f,0.983833f,0.151964f, +-0.0484831f,0.985895f,0.16019f, +-0.137652f,0.965784f,0.219802f, +-0.273035f,0.949633f,0.153782f, +-0.284296f,0.949219f,0.134753f, +-0.233616f,0.961781f,0.142834f, +-0.158293f,0.979011f,0.128376f, +-0.142079f,0.977628f,0.155106f, +-0.179667f,0.940095f,0.289726f, +-0.385363f,0.907468f,0.167324f, +-0.462662f,0.886082f,0.0283396f, +-0.500483f,0.865637f,-0.0137244f, +-0.459387f,0.885328f,-0.0718224f, +-0.318003f,0.947491f,-0.0336944f, +-0.336522f,0.937427f,-0.0893505f, +-0.421711f,0.882359f,-0.208814f, +-0.386976f,0.894588f,-0.223522f, +-0.348564f,0.925302f,-0.149395f, +-0.389936f,0.911457f,-0.131135f, +-0.262418f,0.94867f,-0.17653f, +-0.142966f,0.967048f,-0.210661f, +-0.341303f,0.927435f,0.152892f, +-0.342877f,0.929169f,0.138133f, +-0.327958f,0.941991f,0.0713955f, +-0.312837f,0.949244f,0.0326933f, +-0.32505f,0.944749f,0.0423311f, +-0.35038f,0.936272f,0.0250833f, +-0.334661f,0.939274f,0.0759313f, +-0.336592f,0.939816f,0.0587454f, +-0.383743f,0.919849f,0.0813597f, +-0.479391f,0.876726f,0.0391772f, +-0.521184f,0.850742f,-0.0678625f, +-0.496942f,0.867777f,0.00353465f, +-0.521763f,0.848113f,-0.0920201f, +-0.373289f,0.923494f,-0.0883984f, +-0.40896f,0.910065f,-0.067337f, +-0.458758f,0.888254f,0.0233657f, +-0.335137f,0.935384f,0.112868f, +-0.174079f,0.969266f,0.173839f, +-0.174994f,0.976179f,0.128265f, +-0.244694f,0.967717f,0.0603988f, +-0.409093f,0.90433f,-0.121779f, +-0.290803f,0.954139f,-0.0710763f, +-0.266076f,0.946406f,-0.183082f, +-0.19492f,0.966664f,-0.166031f, +-0.107014f,0.989078f,-0.101359f, +-0.0950037f,0.987234f,-0.127838f, +-0.0081899f,0.996807f,-0.0794301f, +0.0655685f,0.997841f,0.0038314f, +0.121704f,0.991617f,0.0433953f, +0.204125f,0.978885f,0.010797f, +0.169834f,0.985465f,0.00398161f, +0.0639966f,0.99795f,0.000581677f, +0.0389498f,0.997722f,-0.0550831f, +-0.00230315f,0.998522f,-0.0543072f, +-0.0428959f,0.99833f,-0.0386874f, +8.35518e-005f,0.999804f,-0.0198162f, +0.12638f,0.991004f,0.0440296f, +0.219728f,0.969155f,0.111616f, +0.270292f,0.956521f,0.109589f, +0.325159f,0.942616f,0.0758083f, +0.394886f,0.91647f,0.0644013f, +0.455483f,0.885289f,0.0937962f, +0.346134f,0.927862f,0.13879f, +0.142703f,0.967217f,0.210065f, +-0.0417806f,0.973195f,0.226154f, +-0.0873343f,0.983405f,0.159022f, +-0.027932f,0.984118f,0.175304f, +-0.101812f,0.985941f,0.132496f, +-0.174734f,0.983884f,0.037939f, +-0.279511f,0.957793f,-0.0671252f, +-0.277834f,0.959638f,-0.04362f, +-0.153076f,0.986374f,0.0602763f, +-0.221825f,0.968529f,0.112897f, +-0.256381f,0.940693f,0.222182f, +-0.236646f,0.958592f,0.158432f, +-0.345917f,0.937587f,-0.0356594f, +-0.417749f,0.894423f,-0.159665f, +-0.456832f,0.853011f,-0.252341f, +-0.379407f,0.905637f,-0.189399f, +-0.328991f,0.940983f,-0.0794707f, +-0.363362f,0.931271f,0.0264943f, +-0.48653f,0.873119f,0.0308429f, +-0.459174f,0.871133f,0.174033f, +-0.359639f,0.91236f,0.1956f, +-0.2127f,0.972657f,0.0932592f, +-0.0697188f,0.989689f,0.12512f, +-0.251887f,0.965064f,0.0721469f, +-0.317161f,0.947815f,-0.0324826f, +-0.311043f,0.947329f,-0.076288f, +-0.343705f,0.938452f,-0.0342691f, +-0.318958f,0.946045f,0.0571365f, +-0.341405f,0.939767f,0.0167816f, +-0.371963f,0.928183f,-0.0109617f, +-0.353511f,0.935132f,0.0236193f, +-0.398287f,0.910412f,0.111881f, +-0.43162f,0.897024f,0.0951448f, +-0.485116f,0.874338f,-0.0140269f, +-0.473699f,0.879939f,-0.03627f, +-0.417805f,0.900966f,-0.117046f, +-0.424936f,0.889519f,-0.167884f, +-0.467852f,0.878936f,-0.0926624f, +-0.493825f,0.865439f,-0.0845782f, +-0.351989f,0.932075f,-0.0856709f, +-0.214961f,0.974111f,-0.0700008f, +-0.163285f,0.986387f,-0.0194449f, +-0.162841f,0.986548f,-0.0143588f, +-0.285987f,0.956112f,-0.0637334f, +-0.292441f,0.94548f,-0.143341f, +-0.215932f,0.955314f,-0.201864f, +-0.253415f,0.950159f,-0.181603f, +-0.183417f,0.974504f,-0.129231f, +-0.101906f,0.993299f,-0.0545242f, +-0.042238f,0.99904f,-0.0116303f, +0.0329811f,0.99907f,-0.0277622f, +0.132201f,0.990073f,-0.0477429f, +0.267032f,0.963432f,-0.0221792f, +0.1278f,0.990718f,-0.0463084f, +0.0964891f,0.995299f,-0.00830296f, +0.0476853f,0.991211f,-0.123396f, +-0.00640997f,0.993203f,-0.116222f, +-0.0126443f,0.992773f,-0.119338f, +-0.00631822f,0.992917f,-0.118638f, +0.0563885f,0.995667f,-0.073943f, +0.12664f,0.991687f,-0.022778f, +0.273262f,0.961705f,0.021246f, +0.388375f,0.920615f,-0.0403992f, +0.37695f,0.920931f,-0.0989673f, +0.400211f,0.914808f,0.0543818f, +0.279689f,0.947142f,0.15715f, +0.0626591f,0.985325f,0.158772f, +0.0197159f,0.983213f,0.181391f, +0.0112307f,0.995546f,0.0936022f, +-0.0611233f,0.998037f,0.013638f, +-0.0515369f,0.996025f,0.0726543f, +-0.060221f,0.998076f,0.0147593f, +-0.21333f,0.972986f,-0.0882534f, +-0.330599f,0.94012f,-0.0829391f, +-0.311254f,0.950309f,-0.00575056f, +-0.324983f,0.931955f,0.160768f, +-0.245964f,0.942146f,0.227736f, +-0.125195f,0.981121f,0.147403f, +-0.193437f,0.975595f,0.103908f, +-0.319958f,0.946961f,0.029845f, +-0.440983f,0.895915f,-0.0535662f, +-0.477838f,0.878381f,-0.0108058f, +-0.480471f,0.872693f,0.0869201f, +-0.478968f,0.83494f,0.271043f, +-0.490257f,0.796981f,0.352803f, +-0.434277f,0.834185f,0.339909f, +-0.265882f,0.929328f,0.256236f, +-0.142385f,0.958793f,0.245852f, +-0.182126f,0.963412f,0.196642f, +-0.0681643f,0.992157f,0.104781f, +-0.176883f,0.983918f,0.024857f, +-0.305513f,0.952069f,-0.0150524f, +-0.401485f,0.91552f,0.0251517f, +-0.372509f,0.927256f,0.0378572f, +-0.265017f,0.964159f,0.0127972f, +-0.342134f,0.935688f,-0.0862078f, +-0.427338f,0.901948f,-0.062226f, +-0.447549f,0.894216f,0.00877894f, +-0.382185f,0.923573f,-0.0307708f, +-0.386509f,0.921774f,-0.0307138f, +-0.457766f,0.884255f,-0.0924303f, +-0.384262f,0.916404f,-0.11201f, +-0.431623f,0.886784f,-0.165273f, +-0.460575f,0.869789f,-0.177024f, +-0.471547f,0.850265f,-0.233865f, +-0.351048f,0.911491f,-0.214361f, +-0.263539f,0.9431f,-0.202755f, +-0.173283f,0.972074f,-0.158258f, +-0.19847f,0.960809f,-0.193536f, +-0.275034f,0.951707f,-0.136422f, +-0.217032f,0.958372f,-0.185526f, +-0.201987f,0.95666f,-0.209771f, +-0.299318f,0.94727f,-0.114406f, +-0.187056f,0.978613f,-0.0855959f, +-0.155621f,0.97153f,-0.178637f, +-0.0810385f,0.981009f,-0.176221f, +0.0905036f,0.986207f,-0.138581f, +0.115825f,0.982705f,-0.14448f, +0.19636f,0.97731f,-0.0794224f, +0.143519f,0.988245f,-0.0526749f, +0.109744f,0.989619f,-0.0927937f, +0.197571f,0.972036f,-0.12693f, +0.00332495f,0.962309f,-0.271939f, +-0.0356976f,0.959351f,-0.279948f, +-0.0721767f,0.96735f,-0.242948f, +-0.00843005f,0.989549f,-0.143952f, +0.152572f,0.983317f,-0.0990425f, +0.281378f,0.943362f,-0.175768f, +0.428891f,0.891683f,-0.144753f, +0.290445f,0.954517f,-0.0673633f, +0.176401f,0.973557f,0.145155f, +0.232983f,0.924473f,0.301776f, +0.181127f,0.950255f,0.253393f, +-0.00165339f,0.991402f,0.130837f, +0.0981935f,0.976268f,0.193027f, +0.000170743f,0.996657f,0.0816968f, +-0.0970384f,0.995225f,-0.0105345f, +-0.00895717f,0.999951f,-0.00426387f, +-0.170944f,0.985202f,-0.0124686f, +-0.362907f,0.93182f,-0.00317037f, +-0.388121f,0.921046f,0.0322033f, +-0.407598f,0.90852f,0.0919578f, +-0.247403f,0.962759f,0.109032f, +-0.0829823f,0.986114f,0.143848f, +-0.240859f,0.956011f,0.167424f, +-0.312142f,0.912012f,0.266086f, +-0.398269f,0.862926f,0.311032f, +-0.511957f,0.795091f,0.325161f, +-0.506846f,0.755093f,0.415864f, +-0.506747f,0.718735f,0.476054f, +-0.45002f,0.736589f,0.504895f, +-0.287855f,0.833759f,0.471153f, +-0.237765f,0.90713f,0.34725f, +-0.146865f,0.915961f,0.373425f, +-0.0859218f,0.935714f,0.342136f, +-0.054455f,0.996952f,-0.0558782f, +-0.211499f,0.976662f,-0.0374149f, +-0.331452f,0.940975f,0.0686022f, +-0.397421f,0.917381f,0.0216451f, +-0.316207f,0.946964f,-0.0572054f, +-0.202804f,0.975284f,-0.0877067f, +-0.28846f,0.951091f,-0.110532f, +-0.440756f,0.882415f,-0.164552f, +-0.391159f,0.897816f,-0.202288f, +-0.37945f,0.884355f,-0.27191f, +-0.436492f,0.880924f,-0.182888f, +-0.458204f,0.880643f,-0.12049f, +-0.365575f,0.927969f,-0.0723085f, +-0.344164f,0.93545f,-0.0805227f, +-0.392565f,0.898448f,-0.196683f, +-0.458844f,0.839155f,-0.292028f, +-0.406986f,0.873305f,-0.267769f, +-0.264536f,0.933458f,-0.242234f, +-0.197907f,0.946975f,-0.253123f, +-0.162416f,0.964761f,-0.207018f, +-0.261287f,0.932524f,-0.249254f, +-0.237723f,0.937266f,-0.25499f, +-0.255938f,0.959549f,-0.117312f, +-0.378394f,0.921703f,-0.0853291f, +-0.154569f,0.983106f,-0.098032f, +0.020864f,0.98441f,-0.174648f, +-0.0493076f,0.945704f,-0.321268f, +0.00354211f,0.950539f,-0.310586f, +0.0705741f,0.962405f,-0.262289f, +0.155003f,0.952815f,-0.260992f, +0.190084f,0.945182f,-0.265518f, +0.109466f,0.94166f,-0.318268f, +0.219465f,0.948713f,-0.227551f, +0.131592f,0.95776f,-0.255694f, +-0.023132f,0.936016f,-0.351196f, +-0.102398f,0.923738f,-0.369083f, +-0.11778f,0.928743f,-0.351518f, +0.14699f,0.959781f,-0.239196f, +0.329451f,0.917295f,-0.223678f, +0.290403f,0.942778f,-0.163815f, +0.10086f,0.993272f,0.056896f, +0.00690717f,0.980954f,0.194116f, +0.198478f,0.949829f,0.241726f, +0.257584f,0.935998f,0.239913f, +0.0870031f,0.976807f,0.195647f, +0.0578083f,0.994066f,0.0921449f, +0.121554f,0.989161f,0.0823711f, +0.0335983f,0.999242f,0.0196737f, +-0.0544848f,0.997579f,-0.0432265f, +-0.170331f,0.98419f,0.0485619f, +-0.366378f,0.930108f,-0.0258115f, +-0.430564f,0.901925f,-0.0338598f, +-0.412156f,0.909498f,0.0542308f, +-0.303685f,0.949097f,0.0836093f, +-0.198153f,0.949404f,0.243656f, +-0.267445f,0.871756f,0.410506f, +-0.393769f,0.805932f,0.442062f, +-0.427473f,0.750775f,0.50359f, +-0.522691f,0.707231f,0.476044f, +-0.550081f,0.670741f,0.497511f, +-0.518356f,0.695815f,0.49714f, +-0.372017f,0.764162f,0.526934f, +-0.210863f,0.841692f,0.497082f, +-0.116051f,0.87101f,0.477362f, +-0.106872f,0.906726f,0.407954f, +0.0295506f,0.897687f,0.439643f, +-0.11391f,0.993475f,0.00559176f, +-0.238885f,0.970513f,0.0322297f, +-0.352278f,0.935893f,0.00201985f, +-0.29155f,0.955165f,-0.0515582f, +-0.283012f,0.950207f,-0.130422f, +-0.233718f,0.966509f,-0.105997f, +-0.293314f,0.953293f,-0.0721f, +-0.344057f,0.937935f,-0.0436188f, +-0.359338f,0.921856f,-0.145114f, +-0.361988f,0.90939f,-0.204876f, +-0.478777f,0.840974f,-0.252063f, +-0.501126f,0.832032f,-0.237897f, +-0.42396f,0.887247f,-0.1818f, +-0.340692f,0.929815f,-0.13919f, +-0.261328f,0.946412f,-0.189766f, +-0.383135f,0.863856f,-0.327048f, +-0.4248f,0.838392f,-0.341533f, +-0.258907f,0.912327f,-0.317216f, +-0.273875f,0.922352f,-0.272505f, +-0.216284f,0.973372f,-0.0759435f, +-0.186061f,0.980681f,-0.0603919f, +-0.327344f,0.93227f,-0.15401f, +-0.354135f,0.933013f,-0.0638423f, +-0.30838f,0.94174f,-0.13427f, +-0.0952482f,0.963393f,-0.250602f, +0.0864929f,0.957116f,-0.276491f, +0.0265645f,0.947809f,-0.31773f, +-0.00743162f,0.929747f,-0.368124f, +0.0794584f,0.926075f,-0.368877f, +0.177698f,0.921503f,-0.345334f, +0.210118f,0.923104f,-0.322071f, +0.0972314f,0.929984f,-0.354507f, +0.0931107f,0.932401f,-0.349226f, +0.163846f,0.947557f,-0.274392f, +0.04099f,0.947023f,-0.318539f, +-0.0637185f,0.942657f,-0.327625f, +-0.131539f,0.923216f,-0.361068f, +0.0323928f,0.932437f,-0.359877f, +0.242794f,0.937436f,-0.249528f, +0.154647f,0.984538f,-0.0822692f, +-0.0290139f,0.999421f,0.0177744f, +-0.0330797f,0.998482f,0.0440283f, +0.157195f,0.980432f,0.118503f, +0.251646f,0.94505f,0.208697f, +0.178529f,0.966849f,0.182568f, +0.171641f,0.982807f,0.0680498f, +0.107902f,0.993714f,0.0298233f, +0.00302695f,0.994036f,0.109006f, +-0.0844358f,0.977656f,0.19251f, +-0.18119f,0.958323f,0.220878f, +-0.285317f,0.945377f,0.157659f, +-0.419121f,0.895183f,0.151606f, +-0.490039f,0.857134f,0.158693f, +-0.402244f,0.878123f,0.259038f, +-0.398659f,0.825161f,0.400226f, +-0.427626f,0.728675f,0.534948f, +-0.378859f,0.704334f,0.600316f, +-0.386613f,0.684959f,0.617545f, +-0.440363f,0.648556f,0.62085f, +-0.484249f,0.659981f,0.574394f, +-0.462576f,0.728741f,0.504936f, +-0.380875f,0.811463f,0.443241f, +-0.190303f,0.865049f,0.464193f, +-0.0749094f,0.86956f,0.488113f, +-0.11614f,0.868815f,0.481323f, +-0.102623f,0.843113f,0.527854f, +-0.198362f,0.979655f,0.0304707f, +-0.238942f,0.970277f,0.0383318f, +-0.308109f,0.951351f,-0.000213496f, +-0.245044f,0.968893f,0.0346459f, +-0.275786f,0.960816f,-0.0278198f, +-0.256726f,0.965729f,-0.0381932f, +-0.318964f,0.947473f,-0.0236049f, +-0.388409f,0.921405f,0.0123096f, +-0.298771f,0.953298f,0.0442638f, +-0.291187f,0.956662f,0.00282226f, +-0.39367f,0.915026f,-0.0880448f, +-0.501897f,0.840236f,-0.20519f, +-0.460271f,0.863055f,-0.208055f, +-0.311786f,0.925724f,-0.214066f, +-0.177876f,0.937081f,-0.300397f, +-0.256831f,0.902901f,-0.344683f, +-0.413909f,0.808626f,-0.418096f, +-0.347694f,0.845102f,-0.406092f, +-0.390269f,0.881564f,-0.265585f, +-0.38258f,0.915768f,-0.122479f, +-0.172737f,0.984864f,-0.0142896f, +-0.221138f,0.97315f,-0.0638528f, +-0.32806f,0.922266f,-0.204454f, +-0.20334f,0.945769f,-0.253326f, +-0.0362109f,0.959773f,-0.278433f, +0.0451082f,0.968522f,-0.244806f, +0.103574f,0.977375f,-0.184421f, +0.095607f,0.942862f,-0.319172f, +0.028855f,0.903939f,-0.426688f, +0.0781753f,0.937277f,-0.339707f, +0.163597f,0.966118f,-0.199631f, +0.165445f,0.973063f,-0.160553f, +0.145787f,0.95097f,-0.272767f, +0.130591f,0.92029f,-0.368799f, +0.0531207f,0.931628f,-0.35951f, +-0.0802666f,0.935074f,-0.345244f, +-0.124987f,0.942063f,-0.311281f, +0.0397165f,0.963525f,-0.264653f, +0.0790619f,0.96623f,-0.245254f, +0.0277086f,0.995754f,-0.0877838f, +-0.0718135f,0.997414f,0.00271225f, +-0.0601764f,0.993596f,0.0956336f, +0.0305316f,0.992338f,0.119724f, +0.184993f,0.96549f,0.183324f, +0.240982f,0.949316f,0.20181f, +0.205406f,0.960305f,0.188739f, +0.0685231f,0.967991f,0.241448f, +-0.121139f,0.95072f,0.285408f, +-0.150135f,0.918283f,0.366355f, +-0.132611f,0.919499f,0.370048f, +-0.285199f,0.893271f,0.34746f, +-0.428415f,0.803512f,0.413316f, +-0.445474f,0.783214f,0.433738f, +-0.459983f,0.771026f,0.44038f, +-0.467611f,0.730475f,0.497741f, +-0.48066f,0.718458f,0.502777f, +-0.417628f,0.706128f,0.571814f, +-0.464585f,0.665035f,0.584713f, +-0.472738f,0.646587f,0.598702f, +-0.412146f,0.689264f,0.595861f, +-0.326825f,0.752406f,0.5719f, +-0.254151f,0.834713f,0.48853f, +-0.235109f,0.888903f,0.39316f, +-0.153581f,0.849492f,0.504753f, +-0.150095f,0.815518f,0.558929f, +-0.18873f,0.837012f,0.513607f, +0.0689174f,0.995773f,0.0607139f, +-0.155258f,0.983404f,-0.0938683f, +-0.345692f,0.927547f,-0.141961f, +-0.289881f,0.953783f,-0.079168f, +-0.192407f,0.979661f,-0.0569578f, +-0.267677f,0.960104f,-0.0809323f, +-0.338627f,0.940905f,-0.0054102f, +-0.378143f,0.925406f,-0.0251327f, +-0.331689f,0.941021f,-0.0667991f, +-0.266964f,0.963694f,-0.00485284f, +-0.326986f,0.944023f,-0.0435962f, +-0.406544f,0.902607f,-0.141498f, +-0.445264f,0.84532f,-0.295253f, +-0.261882f,0.90946f,-0.322956f, +-0.131634f,0.928868f,-0.346231f, +-0.231876f,0.922232f,-0.30939f, +-0.381112f,0.87967f,-0.284489f, +-0.459513f,0.85999f,-0.22196f, +-0.498013f,0.864257f,-0.0710131f, +-0.440544f,0.89211f,-0.100303f, +-0.247938f,0.96287f,-0.106806f, +-0.10732f,0.992504f,-0.0584663f, +-0.221465f,0.956592f,-0.189431f, +-0.229248f,0.946541f,-0.22695f, +-0.0978243f,0.972744f,-0.210239f, +-0.0379465f,0.985853f,-0.163259f, +0.0806013f,0.992194f,-0.0951546f, +0.280296f,0.95443f,-0.102456f, +0.155799f,0.941292f,-0.299494f, +-0.0466248f,0.90184f,-0.429548f, +0.0333539f,0.93989f,-0.339845f, +0.15766f,0.95203f,-0.262264f, +0.275219f,0.92494f,-0.262186f, +0.226492f,0.914035f,-0.336513f, +0.0375497f,0.921004f,-0.387739f, +-0.0841489f,0.913809f,-0.39733f, +-0.216548f,0.901013f,-0.375874f, +-0.0617755f,0.971104f,-0.230524f, +0.0635289f,0.988552f,-0.136856f, +-0.0898172f,0.987883f,-0.126568f, +-0.195744f,0.9803f,-0.0263689f, +-0.163398f,0.98375f,0.0744142f, +0.0549941f,0.99236f,0.110438f, +0.19398f,0.975972f,0.0992507f, +0.191759f,0.972804f,0.129928f, +0.149866f,0.963222f,0.223034f, +-0.00306242f,0.957956f,0.286898f, +-0.13576f,0.938575f,0.317249f, +-0.176601f,0.936485f,0.303f, +-0.158083f,0.914215f,0.373122f, +-0.316693f,0.854194f,0.412381f, +-0.498069f,0.774619f,0.389733f, +-0.492142f,0.755365f,0.432688f, +-0.453311f,0.739293f,0.49795f, +-0.471661f,0.730931f,0.49323f, +-0.504596f,0.695479f,0.511558f, +-0.486075f,0.660592f,0.572145f, +-0.455536f,0.681017f,0.573326f, +-0.475459f,0.732851f,0.486691f, +-0.40679f,0.784517f,0.468032f, +-0.294511f,0.862991f,0.410499f, +-0.137096f,0.926626f,0.350098f, +-0.212171f,0.92693f,0.30949f, +-0.320702f,0.890591f,0.322488f, +-0.144781f,0.913051f,0.381284f, +-0.0467088f,0.929255f,0.366475f, +0.190524f,0.979715f,0.0621193f, +-0.0159571f,0.99888f,-0.0445494f, +-0.299493f,0.937414f,-0.177647f, +-0.30245f,0.926474f,-0.223986f, +-0.236991f,0.948637f,-0.209579f, +-0.316653f,0.935173f,-0.15869f, +-0.385652f,0.9143f,-0.123807f, +-0.33937f,0.934637f,-0.106213f, +-0.347064f,0.934195f,-0.0826249f, +-0.295744f,0.955249f,0.00583919f, +-0.275005f,0.961059f,-0.0271544f, +-0.269439f,0.957464f,-0.103275f, +-0.282112f,0.919833f,-0.272616f, +-0.294141f,0.877255f,-0.379347f, +-0.188084f,0.929949f,-0.315942f, +-0.305781f,0.908958f,-0.283361f, +-0.494244f,0.854771f,-0.158396f, +-0.556326f,0.828917f,0.0582992f, +-0.534005f,0.83843f,0.108964f, +-0.372194f,0.92607f,0.0621723f, +-0.216902f,0.97615f,-0.00922891f, +-0.129625f,0.988755f,-0.0745716f, +-0.137022f,0.98954f,-0.0451077f, +-0.210914f,0.969697f,-0.123297f, +-0.0927848f,0.980946f,-0.170691f, +-0.0487293f,0.98279f,-0.178186f, +0.0377154f,0.983594f,-0.176409f, +0.270827f,0.95519f,-0.119436f, +0.365037f,0.928517f,-0.0678507f, +0.131842f,0.951604f,-0.277612f, +-0.0185121f,0.905238f,-0.424502f, +0.118166f,0.903064f,-0.412931f, +0.230045f,0.8849f,-0.405008f, +0.2101f,0.906634f,-0.365886f, +0.0544702f,0.94453f,-0.323878f, +-0.0630069f,0.9598f,-0.273522f, +-0.203027f,0.928033f,-0.312304f, +-0.22235f,0.90002f,-0.374866f, +0.0164141f,0.973192f,-0.229407f, +-0.131299f,0.967472f,-0.216237f, +-0.248586f,0.95668f,-0.151553f, +-0.180678f,0.971697f,-0.152182f, +0.021506f,0.991774f,-0.126182f, +0.129882f,0.991187f,-0.0260519f, +0.125479f,0.988703f,0.0819803f, +0.0585413f,0.987325f,0.14752f, +-0.0186301f,0.977162f,0.211676f, +-0.162972f,0.968132f,0.19016f, +-0.218545f,0.935778f,0.276691f, +-0.284144f,0.890895f,0.354356f, +-0.345593f,0.839997f,0.418295f, +-0.488331f,0.792258f,0.36587f, +-0.545891f,0.770241f,0.329746f, +-0.533891f,0.766492f,0.357002f, +-0.51665f,0.749346f,0.414189f, +-0.616561f,0.690345f,0.37852f, +-0.519109f,0.719346f,0.461593f, +-0.392236f,0.782177f,0.484097f, +-0.398436f,0.817816f,0.415241f, +-0.392025f,0.864189f,0.315428f, +-0.176475f,0.937288f,0.300577f, +-0.137444f,0.969881f,0.201097f, +-0.206545f,0.942409f,0.263066f, +-0.293185f,0.938992f,0.179823f, +-0.159029f,0.985376f,0.0611911f, +0.00174953f,0.998094f,0.0616789f, +0.241821f,0.962041f,0.126492f, +0.127737f,0.984773f,0.117921f, +-0.17559f,0.984255f,0.0202494f, +-0.277772f,0.957333f,-0.0797282f, +-0.264237f,0.953214f,-0.146839f, +-0.330132f,0.935063f,-0.129113f, +-0.363469f,0.924563f,-0.114338f, +-0.371034f,0.917638f,-0.142388f, +-0.425424f,0.897691f,-0.114736f, +-0.353654f,0.934652f,-0.0368062f, +-0.218582f,0.975792f,0.007136f, +-0.203676f,0.978799f,-0.0216238f, +-0.149661f,0.987587f,-0.0476727f, +-0.278943f,0.945373f,-0.1687f, +-0.239375f,0.951961f,-0.190969f, +-0.360119f,0.921099f,-0.147955f, +-0.584157f,0.811569f,0.0107674f, +-0.61484f,0.786528f,0.0578414f, +-0.504089f,0.86363f,-0.00605437f, +-0.333455f,0.94143f,-0.0501755f, +-0.123418f,0.989972f,-0.0687344f, +-0.105519f,0.985418f,-0.133478f, +-0.134701f,0.9843f,-0.114061f, +-0.137014f,0.977235f,-0.161985f, +-0.0439551f,0.980481f,-0.191638f, +-0.0327274f,0.96544f,-0.258561f, +0.0268923f,0.955378f,-0.294159f, +0.189265f,0.941783f,-0.277892f, +0.306008f,0.930356f,-0.201982f, +0.2909f,0.948465f,-0.12566f, +0.135694f,0.963424f,-0.231086f, +0.114996f,0.92781f,-0.354886f, +0.243157f,0.920361f,-0.306286f, +0.181493f,0.943785f,-0.27628f, +-0.0348676f,0.964621f,-0.261325f, +-0.138397f,0.964431f,-0.225208f, +-0.0584572f,0.973863f,-0.219483f, +-0.160488f,0.904663f,-0.394751f, +-0.113572f,0.901558f,-0.417487f, +-0.155065f,0.923521f,-0.350803f, +-0.242307f,0.919914f,-0.308295f, +-0.206106f,0.923371f,-0.323891f, +-0.0753677f,0.972428f,-0.220691f, +0.00286078f,0.993423f,-0.114469f, +0.0506503f,0.998257f,-0.0302924f, +-0.0328546f,0.999299f,0.017926f, +-0.060813f,0.979003f,0.194565f, +-0.19049f,0.94338f,0.271567f, +-0.332962f,0.885593f,0.323821f, +-0.330466f,0.869145f,0.367938f, +-0.383415f,0.840587f,0.382632f, +-0.450848f,0.795155f,0.405542f, +-0.50223f,0.7918f,0.347589f, +-0.586371f,0.768822f,0.255112f, +-0.550176f,0.765625f,0.333355f, +-0.594581f,0.747662f,0.295761f, +-0.604774f,0.771025f,0.199423f, +-0.461798f,0.840354f,0.283809f, +-0.323989f,0.875237f,0.359155f, +-0.321766f,0.916629f,0.23719f, +-0.168943f,0.967667f,0.187293f, +-0.107108f,0.976625f,0.186366f, +-0.222921f,0.963011f,0.151379f, +-0.142187f,0.985732f,0.0900906f, +-0.0555822f,0.997373f,-0.0464466f, +-0.00128055f,0.995901f,-0.0904418f, +0.189226f,0.980362f,-0.0555288f, +0.085267f,0.996327f,-0.00782177f, +-0.128918f,0.990746f,0.042464f, +-0.188312f,0.982054f,-0.0104463f, +-0.196136f,0.979449f,-0.0470074f, +-0.346836f,0.935484f,-0.0676365f, +-0.385817f,0.920741f,-0.0581445f, +-0.364523f,0.930255f,-0.0418259f, +-0.413227f,0.910109f,-0.0307546f, +-0.395357f,0.915702f,-0.071985f, +-0.249105f,0.966325f,-0.0645241f, +-0.224404f,0.97132f,-0.0786097f, +-0.136636f,0.989057f,-0.0556425f, +-0.161967f,0.98357f,-0.0797312f, +-0.264069f,0.956689f,-0.122532f, +-0.415862f,0.909427f,-0.00117779f, +-0.618635f,0.784039f,0.0507281f, +-0.569525f,0.818988f,-0.0700017f, +-0.458442f,0.876243f,-0.148424f, +-0.301532f,0.936403f,-0.179521f, +-0.125352f,0.969963f,-0.208469f, +-0.0885456f,0.971015f,-0.222014f, +-0.127345f,0.96169f,-0.242765f, +-0.111865f,0.95953f,-0.258434f, +-0.00408963f,0.957803f,-0.287396f, +0.0423217f,0.932535f,-0.358592f, +0.0695614f,0.921939f,-0.381037f, +0.190852f,0.890613f,-0.412775f, +0.209386f,0.879353f,-0.427663f, +0.178912f,0.925963f,-0.332541f, +0.21012f,0.943847f,-0.254954f, +0.194248f,0.92787f,-0.318316f, +0.12116f,0.941808f,-0.313556f, +0.143074f,0.982238f,-0.121399f, +0.00445755f,0.990826f,-0.135068f, +-0.0763662f,0.964673f,-0.252139f, +-0.00960064f,0.938734f,-0.34451f, +-0.0448775f,0.923487f,-0.380997f, +-0.121038f,0.899958f,-0.418839f, +-0.214432f,0.896136f,-0.388536f, +-0.236628f,0.909444f,-0.341933f, +-0.245801f,0.902665f,-0.353239f, +-0.210816f,0.938091f,-0.274848f, +-0.0790665f,0.981118f,-0.17651f, +-0.0418777f,0.998086f,-0.0455073f, +-0.112513f,0.981903f,0.152339f, +-0.289647f,0.921573f,0.258473f, +-0.276284f,0.866929f,0.414851f, +-0.316808f,0.857367f,0.405653f, +-0.333206f,0.853137f,0.401412f, +-0.396081f,0.828088f,0.396725f, +-0.485909f,0.809843f,0.328705f, +-0.463328f,0.813789f,0.350819f, +-0.520203f,0.774122f,0.360725f, +-0.581754f,0.763678f,0.279925f, +-0.55781f,0.791203f,0.250691f, +-0.576356f,0.800103f,0.166282f, +-0.522214f,0.839566f,0.149738f, +-0.327667f,0.934488f,0.139166f, +-0.239893f,0.965369f,0.102537f, +-0.178401f,0.973537f,0.142826f, +-0.0446164f,0.980327f,0.192274f, +-0.152707f,0.98769f,0.0338934f, +-0.061376f,0.996098f,-0.0634113f, +-0.00816896f,0.988579f,-0.150483f, +0.0167009f,0.992551f,-0.120678f, +0.148875f,0.988771f,-0.0129578f, +0.0273451f,0.999626f,0.000950796f, +-0.109359f,0.99398f,0.00672756f, +-0.162948f,0.982686f,-0.0881845f, +-0.242271f,0.966262f,-0.0874275f, +-0.357996f,0.933723f,0.000140943f, +-0.377863f,0.925289f,0.0325572f, +-0.389424f,0.920391f,0.0350616f, +-0.408888f,0.910343f,0.0639282f, +-0.371945f,0.928232f,0.00649489f, +-0.230632f,0.97289f,0.0171594f, +-0.159091f,0.987197f,-0.0114848f, +-0.122759f,0.984183f,-0.127724f, +-0.175251f,0.974473f,-0.14032f, +-0.35571f,0.933079f,-0.0532364f, +-0.501387f,0.863164f,0.0596562f, +-0.575441f,0.816492f,-0.0470046f, +-0.501056f,0.856673f,-0.122698f, +-0.414992f,0.888139f,-0.19746f, +-0.309585f,0.914677f,-0.259854f, +-0.0986663f,0.965073f,-0.242693f, +-0.0576728f,0.965088f,-0.255499f, +-0.0928316f,0.963296f,-0.251879f, +-0.0710107f,0.944633f,-0.320352f, +0.0799711f,0.918771f,-0.386606f, +0.0834923f,0.89273f,-0.442789f, +0.0521243f,0.897343f,-0.438246f, +0.251171f,0.890827f,-0.378604f, +0.176541f,0.892631f,-0.414781f, +0.102505f,0.91423f,-0.392015f, +0.148543f,0.910792f,-0.385219f, +0.204336f,0.92739f,-0.313361f, +0.00672261f,0.969577f,-0.244696f, +-0.0203828f,0.994006f,-0.10741f, +0.0984818f,0.994155f,-0.0442492f, +0.0884297f,0.979853f,-0.179077f, +0.079756f,0.934869f,-0.345919f, +-0.0373135f,0.916973f,-0.3972f, +-0.13475f,0.922044f,-0.362873f, +-0.248554f,0.90561f,-0.343645f, +-0.298871f,0.900649f,-0.315447f, +-0.245556f,0.942684f,-0.225941f, +-0.29156f,0.92569f,-0.241018f, +-0.210251f,0.966564f,-0.146796f, +-0.258034f,0.965595f,0.0323199f, +-0.368176f,0.902709f,0.22263f, +-0.350064f,0.851117f,0.391223f, +-0.273287f,0.858969f,0.432996f, +-0.285306f,0.881397f,0.376483f, +-0.391023f,0.856564f,0.336748f, +-0.346592f,0.838969f,0.419529f, +-0.422742f,0.829366f,0.365295f, +-0.513303f,0.775065f,0.368504f, +-0.526999f,0.742246f,0.413935f, +-0.485934f,0.782442f,0.389426f, +-0.494091f,0.808005f,0.32094f, +-0.527377f,0.820007f,0.222402f, +-0.463863f,0.878834f,0.111725f, +-0.310302f,0.94881f,0.0589178f, +-0.228025f,0.964645f,0.132153f, +-0.25901f,0.96255f,0.080067f, +-0.0424596f,0.997867f,0.0495831f, +-0.00646979f,0.998786f,0.048831f, +0.0235108f,0.999153f,0.033786f, +0.0350773f,0.999112f,0.0233587f, +-0.06489f,0.99782f,0.0120079f, +0.0653571f,0.99589f,0.0626978f, +0.0437681f,0.989758f,0.13588f, +-0.0612591f,0.992124f,0.109253f, +-0.0700659f,0.993846f,0.085792f, +-0.245254f,0.968292f,0.0475526f, +-0.425333f,0.903383f,0.0546907f, +-0.406557f,0.90921f,0.0897132f, +-0.40303f,0.911526f,0.0817765f, +-0.380881f,0.92142f,0.0769048f, +-0.320213f,0.947262f,0.0126033f, +-0.2583f,0.964583f,-0.0534921f, +-0.102892f,0.993091f,-0.0564197f, +-0.0482689f,0.996133f,-0.0734163f, +-0.214829f,0.976629f,0.00662477f, +-0.431775f,0.896672f,0.0977224f, +-0.451215f,0.886255f,0.104672f, +-0.522087f,0.848838f,-0.0830587f, +-0.458286f,0.880944f,-0.117949f, +-0.338524f,0.917937f,-0.206865f, +-0.285281f,0.916752f,-0.279607f, +-0.142352f,0.962006f,-0.232982f, +-0.0943041f,0.983891f,-0.151875f, +-0.0753867f,0.988192f,-0.133394f, +0.0592214f,0.975378f,-0.212437f, +0.135178f,0.93923f,-0.315553f, +0.146098f,0.928461f,-0.34149f, +0.0154593f,0.901088f,-0.433361f, +0.163565f,0.906515f,-0.389201f, +0.204593f,0.933049f,-0.295907f, +0.124274f,0.938076f,-0.323371f, +0.137407f,0.92485f,-0.354642f, +0.063168f,0.960879f,-0.269671f, +-0.0720239f,0.98835f,-0.134077f, +-0.0757271f,0.981006f,-0.178587f, +0.0897227f,0.968994f,-0.23022f, +0.219073f,0.948381f,-0.229303f, +0.192275f,0.938149f,-0.287936f, +-0.0492263f,0.973953f,-0.221343f, +-0.181885f,0.971294f,-0.153316f, +-0.242476f,0.960686f,-0.135229f, +-0.363624f,0.917475f,-0.161301f, +-0.330978f,0.935565f,-0.12317f, +-0.30439f,0.949195f,-0.0798413f, +-0.362853f,0.931339f,-0.0307322f, +-0.401675f,0.903644f,0.148607f, +-0.425736f,0.872787f,0.238731f, +-0.458216f,0.866256f,0.199096f, +-0.325646f,0.913769f,0.242862f, +-0.214745f,0.922085f,0.321938f, +-0.398463f,0.884492f,0.242694f, +-0.475038f,0.830832f,0.289927f, +-0.448294f,0.764081f,0.463909f, +-0.497042f,0.7065f,0.503792f, +-0.489906f,0.735868f,0.467431f, +-0.460921f,0.76339f,0.452535f, +-0.40897f,0.781052f,0.471913f, +-0.371818f,0.839399f,0.396435f, +-0.326758f,0.904742f,0.27326f, +-0.383198f,0.91056f,0.155045f, +-0.284609f,0.924825f,0.252383f, +-0.0749114f,0.976737f,0.200932f, +0.00799324f,0.997093f,0.0757729f, +-0.0700844f,0.990942f,0.114551f, +-0.0596966f,0.983848f,0.168758f, +0.00586433f,0.977052f,0.212922f, +-0.0605914f,0.978841f,0.195443f, +-0.0438257f,0.995801f,0.0803703f, +-0.0570689f,0.993344f,0.100052f, +-0.0606116f,0.987839f,0.143177f, +-0.0960986f,0.983658f,0.152253f, +-0.240218f,0.956553f,0.16523f, +-0.410215f,0.902731f,0.129617f, +-0.38596f,0.917352f,0.0974681f, +-0.348531f,0.935694f,0.0547901f, +-0.396424f,0.918039f,-0.00721866f, +-0.26358f,0.961512f,0.0775866f, +-0.177577f,0.982975f,0.0471779f, +-0.0921077f,0.995708f,0.00907831f, +-0.131805f,0.991186f,0.0133294f, +-0.348565f,0.935587f,0.0563885f, +-0.467549f,0.880933f,0.0731775f, +-0.372581f,0.926945f,0.0442312f, +-0.408929f,0.911847f,-0.0362219f, +-0.445009f,0.893478f,-0.0605312f, +-0.306432f,0.951885f,-0.00384437f, +-0.259351f,0.965029f,0.0381644f, +-0.265204f,0.963994f,-0.0195798f, +-0.114808f,0.993343f,0.00942441f, +-0.0279481f,0.990324f,-0.135929f, +0.103339f,0.977655f,-0.18306f, +0.218767f,0.966894f,-0.131368f, +0.207579f,0.958824f,-0.193824f, +0.136905f,0.960239f,-0.243308f, +0.117272f,0.934734f,-0.335438f, +0.133403f,0.937193f,-0.322294f, +0.140113f,0.948531f,-0.284001f, +0.0924439f,0.975124f,-0.201463f, +-0.0405443f,0.993271f,-0.108481f, +-0.0729426f,0.987394f,-0.140474f, +0.0307633f,0.972795f,-0.229615f, +0.200951f,0.951021f,-0.2349f, +0.206873f,0.91785f,-0.338755f, +0.0409109f,0.957201f,-0.286518f, +-0.211311f,0.976629f,-0.0392802f, +-0.256735f,0.961768f,0.0953371f, +-0.237528f,0.960421f,0.145504f, +-0.329105f,0.937835f,0.110248f, +-0.355083f,0.930437f,0.0905737f, +-0.33751f,0.931415f,0.13621f, +-0.400013f,0.905919f,0.138928f, +-0.505595f,0.854442f,0.119596f, +-0.452675f,0.873473f,0.179247f, +-0.360085f,0.917004f,0.17159f, +-0.404496f,0.910531f,0.0855373f, +-0.324231f,0.903855f,0.279141f, +-0.336075f,0.852068f,0.40129f, +-0.562491f,0.75864f,0.328737f, +-0.580482f,0.703244f,0.410473f, +-0.499356f,0.747889f,0.437385f, +-0.47057f,0.77436f,0.423001f, +-0.457721f,0.780273f,0.426221f, +-0.387043f,0.830428f,0.400733f, +-0.304454f,0.882516f,0.358431f, +-0.240482f,0.915056f,0.323791f, +-0.289179f,0.919765f,0.265345f, +-0.239541f,0.954664f,0.176742f, +-0.0468358f,0.993768f,0.10115f, +-0.0227943f,0.987776f,0.154204f, +-0.112093f,0.964309f,0.239881f, +-0.0599845f,0.969963f,0.235741f, +0.0387578f,0.968143f,0.24738f, +0.0187191f,0.971458f,0.236471f, +0.242021f,0.896343f,0.371478f, +0.0480335f,0.972296f,0.228765f, +-0.0779729f,0.986176f,0.146206f, +-0.0941394f,0.982277f,0.16208f, +-0.22083f,0.962927f,0.154936f, +-0.380194f,0.918443f,0.109152f, +-0.362825f,0.928988f,0.0730715f, +-0.322334f,0.943799f,0.0731113f, +-0.408658f,0.905696f,0.112752f, +-0.342623f,0.91378f,0.218209f, +-0.178962f,0.947287f,0.265744f, +-0.0963031f,0.962264f,0.254507f, +-0.129686f,0.959928f,0.248434f, +-0.25861f,0.932715f,0.251325f, +-0.400538f,0.911394f,0.0944958f, +-0.371118f,0.928542f,0.00899351f, +-0.395096f,0.916517f,0.0624194f, +-0.492959f,0.864551f,0.097688f, +-0.425957f,0.892844f,0.146255f, +-0.256791f,0.9425f,0.213898f, +-0.177422f,0.976398f,0.123157f, +0.0269208f,0.996881f,0.0741829f, +0.164645f,0.980831f,-0.104223f, +0.0973784f,0.963273f,-0.250244f, +0.114359f,0.965463f,-0.234102f, +0.250084f,0.96398f,-0.0905583f, +0.183861f,0.973241f,-0.137829f, +0.203921f,0.957737f,-0.202868f, +0.170155f,0.95208f,-0.254149f, +0.0373443f,0.963666f,-0.264487f, +-0.0311132f,0.98854f,-0.147717f, +-0.0500681f,0.990616f,-0.127173f, +0.0774781f,0.980584f,-0.180143f, +0.0416659f,0.952342f,-0.302174f, +0.183971f,0.945491f,-0.268702f, +0.234504f,0.932825f,-0.27358f, +-0.0611848f,0.988685f,-0.13696f, +-0.37387f,0.925543f,-0.059925f, +-0.361069f,0.932447f,-0.0130774f, +-0.247932f,0.961796f,0.1161f, +-0.321909f,0.940217f,0.111206f, +-0.373794f,0.915694f,0.147587f, +-0.370927f,0.915202f,0.157537f, +-0.367344f,0.908177f,0.20068f, +-0.445687f,0.879826f,0.165134f, +-0.480845f,0.872838f,0.0833169f, +-0.396228f,0.900984f,0.176722f, +-0.39533f,0.870559f,0.292987f, +-0.514705f,0.791717f,0.329034f, +-0.426478f,0.754312f,0.49913f, +-0.476928f,0.731476f,0.487321f, +-0.555203f,0.748777f,0.362053f, +-0.513793f,0.811828f,0.277402f, +-0.498737f,0.823176f,0.271372f, +-0.459197f,0.851815f,0.252089f, +-0.364638f,0.907849f,0.207f, +-0.280535f,0.937686f,0.205051f, +-0.204645f,0.959273f,0.194721f, +-0.188424f,0.978285f,0.0863425f, +-0.16576f,0.97773f,-0.128717f, +-0.0413953f,0.984504f,-0.170405f, +-0.119175f,0.989154f,-0.0858603f, +-0.164393f,0.986215f,0.018821f, +-0.0876541f,0.994439f,0.0583851f, +-0.00781607f,0.987179f,0.159428f, +-0.00608226f,0.980142f,0.198203f, +0.294056f,0.919888f,0.259494f, +0.176099f,0.946212f,0.271426f, +-0.0256669f,0.973237f,0.228366f, +-0.0934761f,0.978631f,0.183149f, +-0.211202f,0.968374f,0.132837f, +-0.345036f,0.933287f,0.0996237f, +-0.346043f,0.935088f,0.0765773f, +-0.381385f,0.918419f,0.105127f, +-0.476923f,0.857096f,0.19476f, +-0.397907f,0.88874f,0.227622f, +-0.175271f,0.936954f,0.30232f, +-0.040477f,0.944541f,0.325889f, +-0.142418f,0.942444f,0.302518f, +-0.246569f,0.91514f,0.318938f, +-0.255277f,0.933873f,0.25043f, +-0.348488f,0.92941f,0.121466f, +-0.472178f,0.874219f,0.113089f, +-0.490306f,0.858256f,0.151645f, +-0.38804f,0.914553f,0.114097f, +-0.196584f,0.979051f,0.0530513f, +-0.0793551f,0.996572f,-0.0234008f, +0.0406197f,0.994776f,-0.0936505f, +0.24653f,0.966821f,-0.0669378f, +0.269235f,0.959692f,-0.0806517f, +0.0569112f,0.963296f,-0.26234f, +0.131503f,0.973945f,-0.184764f, +0.24729f,0.957434f,-0.148892f, +0.248779f,0.951221f,-0.18245f, +0.18718f,0.966303f,-0.176696f, +0.00607471f,0.977895f,-0.20901f, +-0.0210706f,0.975074f,-0.220878f, +0.00501251f,0.949574f,-0.313502f, +0.0771251f,0.945518f,-0.316304f, +0.130553f,0.948445f,-0.288805f, +0.175519f,0.929764f,-0.323623f, +0.111769f,0.971665f,-0.208266f, +-0.210844f,0.971563f,-0.107753f, +-0.345299f,0.9344f,-0.087551f, +-0.367127f,0.918607f,-0.146212f, +-0.340753f,0.929779f,-0.139279f, +-0.358585f,0.929839f,-0.0825605f, +-0.393886f,0.919008f,-0.0166963f, +-0.401193f,0.915983f,0.00451588f, +-0.406108f,0.91192f,0.0589777f, +-0.45609f,0.887954f,0.0593294f, +-0.481921f,0.86351f,0.148669f, +-0.533578f,0.80576f,0.256994f, +-0.480795f,0.753832f,0.447854f, +-0.502576f,0.721353f,0.476516f, +-0.457582f,0.746697f,0.482766f, +-0.419108f,0.791496f,0.44484f, +-0.465376f,0.834036f,0.296325f, +-0.468919f,0.860429f,0.199442f, +-0.486627f,0.858618f,0.161151f, +-0.430227f,0.89524f,0.115972f, +-0.34028f,0.937953f,0.066739f, +-0.311486f,0.949765f,0.0303886f, +-0.166884f,0.985403f,0.0336267f, +0.0381647f,0.996782f,-0.0704869f, +0.0486826f,0.951753f,-0.302979f, +-0.0940893f,0.932244f,-0.349383f, +-0.229015f,0.944857f,-0.234089f, +-0.214421f,0.956596f,-0.19735f, +-0.17466f,0.962579f,-0.207209f, +-0.106663f,0.986513f,-0.124157f, +-0.0523564f,0.993983f,-0.0962102f, +0.1751f,0.970986f,0.162867f, +0.126838f,0.957099f,0.260524f, +-0.0248407f,0.948904f,0.314587f, +-0.0169284f,0.94527f,0.325849f, +-0.126002f,0.963121f,0.237743f, +-0.322368f,0.933961f,0.154262f, +-0.357267f,0.920847f,0.156206f, +-0.40825f,0.900639f,0.148934f, +-0.500408f,0.86145f,0.0865774f, +-0.437173f,0.895731f,0.0809122f, +-0.234862f,0.957423f,0.167871f, +-0.122112f,0.971133f,0.204913f, +-0.146988f,0.949325f,0.277805f, +-0.214866f,0.947227f,0.237893f, +-0.166781f,0.968529f,0.184757f, +-0.279132f,0.953637f,0.112522f, +-0.438908f,0.892826f,0.101101f, +-0.476448f,0.878957f,0.0207741f, +-0.317496f,0.946313f,-0.0607282f, +-0.175675f,0.968847f,-0.174568f, +0.00443594f,0.981128f,-0.193308f, +0.0639918f,0.955901f,-0.286634f, +0.156615f,0.959233f,-0.235253f, +0.281138f,0.953388f,-0.109604f, +0.173642f,0.975105f,-0.137905f, +0.125725f,0.970112f,-0.207546f, +0.23259f,0.936622f,-0.261996f, +0.234534f,0.938208f,-0.25448f, +0.160485f,0.952598f,-0.258459f, +0.0824642f,0.968528f,-0.234849f, +0.0634583f,0.946763f,-0.315614f, +0.0567562f,0.917557f,-0.393532f, +0.0240187f,0.918352f,-0.395035f, +0.0995244f,0.946786f,-0.30609f, +0.0782245f,0.971194f,-0.225085f, +0.0104903f,0.995647f,-0.0926114f, +-0.185802f,0.976721f,-0.107212f, +-0.328502f,0.923412f,-0.198486f, +-0.311331f,0.92975f,-0.196566f, +-0.349149f,0.904891f,-0.24345f, +-0.388436f,0.90322f,-0.182515f, +-0.447323f,0.88531f,-0.126995f, +-0.452109f,0.890067f,-0.0581177f, +-0.409043f,0.912515f,0.000312055f, +-0.489105f,0.872225f,-0.000401423f, +-0.602394f,0.789815f,0.115381f, +-0.644891f,0.727938f,0.232857f, +-0.581256f,0.729671f,0.360168f, +-0.503025f,0.763549f,0.404917f, +-0.449741f,0.833702f,0.320428f, +-0.320295f,0.891402f,0.320645f, +-0.365897f,0.908793f,0.200535f, +-0.418513f,0.900509f,0.118029f, +-0.464312f,0.883882f,0.0562756f, +-0.399182f,0.916811f,0.0105308f, +-0.291715f,0.956056f,-0.0293054f, +-0.237447f,0.965751f,-0.104617f, +-0.100041f,0.966568f,-0.236091f, +0.160871f,0.934989f,-0.316096f, +0.093049f,0.931221f,-0.352375f, +-0.15859f,0.964926f,-0.209204f, +-0.273524f,0.944194f,-0.183526f, +-0.190425f,0.948278f,-0.253984f, +-0.130985f,0.95529f,-0.265074f, +-0.109109f,0.943759f,-0.312112f, +-0.0442587f,0.936376f,-0.348197f, +0.0244075f,0.991066f,0.131121f, +-0.0145509f,0.975134f,0.221137f, +-0.0404534f,0.947565f,0.316994f, +-0.0554847f,0.953641f,0.295787f, +-0.0378486f,0.926136f,0.375287f, +-0.276884f,0.909741f,0.309364f, +-0.35531f,0.878584f,0.319132f, +-0.28855f,0.905318f,0.311668f, +-0.418654f,0.900829f,0.115051f, +-0.470621f,0.881923f,0.0269622f, +-0.302456f,0.950707f,0.0683814f, +-0.155931f,0.981097f,0.114601f, +-0.172528f,0.971746f,0.161072f, +-0.175279f,0.972437f,0.153763f, +-0.0948884f,0.989506f,0.108971f, +-0.271832f,0.96203f,0.0246161f, +-0.434113f,0.899816f,0.0433328f, +-0.41192f,0.910729f,-0.0299284f, +-0.184465f,0.976107f,-0.114836f, +-0.0519711f,0.950434f,-0.306552f, +0.0510061f,0.914254f,-0.401918f, +0.0714878f,0.915457f,-0.396015f, +0.0823148f,0.944294f,-0.318643f, +0.154376f,0.938672f,-0.308322f, +0.218285f,0.948145f,-0.231024f, +0.158935f,0.938404f,-0.306818f, +0.261223f,0.9329f,-0.247912f, +0.285998f,0.932056f,-0.222434f, +0.190198f,0.913869f,-0.358703f, +0.0636773f,0.892218f,-0.447094f, +0.10205f,0.889697f,-0.445f, +0.100031f,0.900986f,-0.422159f, +0.0104969f,0.905423f,-0.424381f, +-0.0688464f,0.910262f,-0.408268f, +-0.0482237f,0.974352f,-0.219802f, +-0.0083558f,0.994225f,-0.106992f, +-0.112134f,0.979056f,-0.169927f, +-0.229912f,0.945374f,-0.231102f, +-0.280533f,0.899591f,-0.334719f, +-0.346884f,0.867971f,-0.355384f, +-0.459064f,0.843199f,-0.279779f, +-0.497889f,0.848119f,-0.181111f, +-0.501207f,0.860371f,-0.0924901f, +-0.458162f,0.888868f,-0.00122281f, +-0.514613f,0.855463f,0.0579275f, +-0.647763f,0.760835f,0.0391491f, +-0.704753f,0.709026f,0.0246046f, +-0.656653f,0.750377f,0.0757771f, +-0.504188f,0.854115f,0.127601f, +-0.41033f,0.905141f,0.111126f, +-0.337511f,0.936543f,0.0947305f, +-0.307169f,0.946112f,0.10256f, +-0.367429f,0.928128f,0.0597776f, +-0.393986f,0.91872f,-0.0269814f, +-0.373766f,0.918684f,-0.127743f, +-0.26114f,0.960116f,-0.0999132f, +-0.103927f,0.984722f,-0.139723f, +0.0511518f,0.955672f,-0.289956f, +0.187205f,0.928701f,-0.320109f, +-0.0295799f,0.970029f,-0.241182f, +-0.314429f,0.940081f,-0.13184f, +-0.185337f,0.978913f,-0.0859053f, +-0.104364f,0.967564f,-0.230061f, +-0.0895833f,0.932754f,-0.349206f, +-0.054587f,0.891296f,-0.450124f, +0.0297567f,0.885691f,-0.463321f, +0.100841f,0.951386f,0.291024f, +-0.0719364f,0.970866f,0.22857f, +-0.0950354f,0.957535f,0.272204f, +-0.063148f,0.9475f,0.313457f, +-0.147905f,0.922206f,0.357295f, +-0.255052f,0.862392f,0.437296f, +-0.348295f,0.831026f,0.433689f, +-0.228735f,0.861593f,0.453141f, +-0.189137f,0.904176f,0.383004f, +-0.40614f,0.912877f,0.041313f, +-0.322035f,0.946605f,-0.0152552f, +-0.213289f,0.976152f,0.0404333f, +-0.216957f,0.96919f,0.116619f, +-0.143471f,0.982181f,0.121395f, +-0.0619809f,0.995307f,0.0743149f, +-0.20303f,0.975599f,0.0835793f, +-0.415979f,0.909172f,0.0191678f, +-0.336954f,0.94062f,-0.0411873f, +-0.0679584f,0.981162f,-0.180839f, +0.116786f,0.956914f,-0.265849f, +0.119526f,0.96094f,-0.249616f, +-0.00488697f,0.95735f,-0.288889f, +0.0539017f,0.947486f,-0.315223f, +0.147321f,0.922615f,-0.35648f, +0.255572f,0.910786f,-0.324272f, +0.156463f,0.885962f,-0.436566f, +0.1301f,0.92297f,-0.362215f, +0.25276f,0.923086f,-0.289871f, +0.383737f,0.889757f,-0.247141f, +0.211205f,0.883014f,-0.419141f, +0.0342331f,0.879599f,-0.474482f, +0.00319575f,0.938694f,-0.344735f, +0.0177214f,0.953292f,-0.301529f, +-0.111253f,0.93857f,-0.326663f, +-0.240335f,0.933381f,-0.26653f, +-0.0538188f,0.987001f,-0.151433f, +-0.0274864f,0.979377f,-0.200162f, +-0.187631f,0.946384f,-0.262966f, +-0.206926f,0.955659f,-0.209519f, +-0.334901f,0.924406f,-0.182523f, +-0.500035f,0.842333f,-0.201099f, +-0.536058f,0.812568f,-0.228857f, +-0.57838f,0.789021f,-0.207176f, +-0.551453f,0.831854f,-0.0625953f, +-0.537806f,0.840551f,0.0651045f, +-0.581123f,0.812541f,0.0455343f, +-0.677773f,0.725811f,-0.117567f, +-0.674512f,0.726391f,-0.131871f, +-0.561194f,0.823313f,-0.0849523f, +-0.426155f,0.904036f,-0.0333265f, +-0.350057f,0.935877f,-0.0399208f, +-0.324764f,0.94579f,-0.0029281f, +-0.334572f,0.942069f,0.0238272f, +-0.264187f,0.96401f,-0.0298196f, +-0.331302f,0.926674f,-0.177522f, +-0.297768f,0.937944f,-0.177749f, +-0.0551409f,0.983889f,-0.170067f, +0.144484f,0.972505f,-0.182644f, +0.119335f,0.96645f,-0.227451f, +-0.0885992f,0.982619f,-0.163126f, +-0.33707f,0.92576f,-0.171324f, +-0.162854f,0.966557f,-0.198108f, +0.0162126f,0.974218f,-0.225026f, +0.138436f,0.947057f,-0.289688f, +0.0835536f,0.876982f,-0.473204f, +-0.010237f,0.848096f,-0.529743f, +0.136921f,0.906371f,0.399681f, +0.0140824f,0.922185f,0.386492f, +-0.160268f,0.929321f,0.33268f, +-0.112451f,0.900092f,0.420938f, +-0.203296f,0.876433f,0.436504f, +-0.322996f,0.829667f,0.455332f, +-0.340765f,0.827757f,0.445755f, +-0.257344f,0.84669f,0.465715f, +0.00366351f,0.865541f,0.500825f, +-0.0425812f,0.956742f,0.287804f, +-0.322344f,0.945159f,-0.052618f, +-0.280797f,0.958795f,-0.0431994f, +-0.262333f,0.964629f,-0.0259446f, +-0.0891831f,0.995449f,-0.0335709f, +-0.0801038f,0.992742f,-0.0896982f, +-0.224206f,0.974484f,0.0105758f, +-0.364477f,0.9309f,-0.0241328f, +-0.198506f,0.970273f,-0.138443f, +0.0492304f,0.955815f,-0.289816f, +0.0465241f,0.961334f,-0.271428f, +0.0147498f,0.993644f,-0.111598f, +0.136409f,0.989222f,-0.0532271f, +0.148553f,0.957532f,-0.247113f, +0.203722f,0.927854f,-0.312384f, +0.268253f,0.883803f,-0.383317f, +0.18614f,0.887058f,-0.422469f, +0.10218f,0.907566f,-0.407286f, +0.200645f,0.878358f,-0.433854f, +0.320433f,0.870875f,-0.372692f, +0.278243f,0.911383f,-0.303252f, +-0.0169368f,0.97379f,-0.226818f, +-0.116502f,0.978925f,-0.16773f, +0.0246686f,0.985931f,-0.165321f, +-0.099417f,0.977857f,-0.184152f, +-0.275352f,0.945128f,-0.175824f, +-0.0928967f,0.974055f,-0.206368f, +0.0664566f,0.97817f,-0.196893f, +-0.180659f,0.959555f,-0.21591f, +-0.356529f,0.924348f,-0.135896f, +-0.392702f,0.919607f,0.0104344f, +-0.427591f,0.903919f,-0.00980201f, +-0.491673f,0.851131f,-0.183941f, +-0.597871f,0.779934f,-0.185076f, +-0.630214f,0.771159f,-0.0902474f, +-0.603795f,0.796392f,-0.0345128f, +-0.532942f,0.846043f,0.013577f, +-0.560658f,0.826581f,-0.049261f, +-0.693149f,0.692482f,-0.200033f, +-0.591049f,0.792583f,-0.14991f, +-0.423413f,0.894971f,-0.14053f, +-0.360923f,0.922234f,-0.138633f, +-0.376728f,0.924323f,-0.0608465f, +-0.330964f,0.94352f,-0.0152562f, +-0.205049f,0.976512f,-0.0661789f, +-0.221147f,0.966952f,-0.126878f, +-0.282753f,0.933366f,-0.221083f, +-0.0599842f,0.959615f,-0.274846f, +0.119046f,0.947951f,-0.295324f, +0.164559f,0.948383f,-0.27109f, +-0.0951076f,0.948417f,-0.302424f, +-0.271887f,0.913351f,-0.303098f, +-0.128933f,0.917201f,-0.376985f, +0.0280066f,0.909443f,-0.414885f, +0.150608f,0.898143f,-0.413106f, +0.212115f,0.88838f,-0.407172f, +0.0467869f,0.87371f,-0.484191f, +0.135605f,0.903203f,0.407228f, +-0.01172f,0.896648f,0.44259f, +-0.138887f,0.847422f,0.512432f, +-0.170991f,0.843044f,0.50994f, +-0.191878f,0.839246f,0.508772f, +-0.300268f,0.838171f,0.455311f, +-0.32966f,0.831286f,0.447535f, +-0.223175f,0.877254f,0.424992f, +-0.0256774f,0.953915f,0.298977f, +0.199545f,0.913698f,0.354031f, +-0.0319727f,0.980881f,0.191963f, +-0.258985f,0.964126f,-0.0582107f, +-0.212788f,0.970943f,-0.109502f, +-0.0721792f,0.982085f,-0.174064f, +-0.0849627f,0.985898f,-0.144175f, +-0.290021f,0.949136f,-0.122591f, +-0.248272f,0.954348f,-0.166075f, +-0.0507313f,0.942327f,-0.330828f, +0.0792104f,0.910775f,-0.405234f, +-0.0679775f,0.927432f,-0.367762f, +-0.0963141f,0.945938f,-0.309718f, +0.147422f,0.952479f,-0.266555f, +0.232988f,0.930423f,-0.282895f, +0.296671f,0.921407f,-0.250989f, +0.346023f,0.880014f,-0.325337f, +0.246011f,0.893818f,-0.374924f, +0.0779935f,0.862828f,-0.499444f, +0.218748f,0.861753f,-0.457746f, +0.236169f,0.890523f,-0.388836f, +0.122215f,0.968128f,-0.218613f, +-0.119249f,0.983741f,-0.134288f, +-0.0975043f,0.983669f,-0.151287f, +0.0551556f,0.975975f,-0.210786f, +-0.0858442f,0.972611f,-0.216008f, +-0.228301f,0.939116f,-0.256789f, +-0.0600278f,0.94195f,-0.330342f, +-0.00498162f,0.954835f,-0.297095f, +-0.236752f,0.956732f,-0.169151f, +-0.404481f,0.905728f,-0.126698f, +-0.442956f,0.884106f,-0.148815f, +-0.353117f,0.929811f,-0.103732f, +-0.367684f,0.920274f,-0.133808f, +-0.620195f,0.758926f,-0.19847f, +-0.650875f,0.742352f,-0.158981f, +-0.60395f,0.783223f,-0.147668f, +-0.562027f,0.815077f,-0.140626f, +-0.504739f,0.855197f,-0.117796f, +-0.629314f,0.743816f,-0.22517f, +-0.590837f,0.750634f,-0.295736f, +-0.432954f,0.842346f,-0.320942f, +-0.414184f,0.8722f,-0.260227f, +-0.438355f,0.884876f,-0.157606f, +-0.309198f,0.940747f,-0.13925f, +-0.155389f,0.967122f,-0.20132f, +-0.14424f,0.961525f,-0.233805f, +-0.235758f,0.924f,-0.301067f, +0.0151186f,0.960375f,-0.278299f, +0.144315f,0.944571f,-0.294888f, +0.112415f,0.964242f,-0.239999f, +-0.0426025f,0.977992f,-0.204249f, +-0.206795f,0.910666f,-0.357663f, +-0.0742651f,0.885367f,-0.458922f, +0.0946583f,0.875247f,-0.474324f, +0.121834f,0.836586f,-0.534117f, +0.198513f,0.859849f,-0.470374f, +0.17646f,0.872184f,-0.456242f, +0.0304109f,0.916616f,0.39861f, +-0.119037f,0.881644f,0.456655f, +-0.241587f,0.81204f,0.53125f, +-0.146676f,0.796898f,0.586037f, +-0.0991089f,0.808485f,0.580111f, +-0.265015f,0.835696f,0.481019f, +-0.330941f,0.833473f,0.442495f, +-0.0736129f,0.908742f,0.410816f, +0.128357f,0.956244f,0.26291f, +0.135386f,0.977167f,0.163754f, +0.135126f,0.969499f,0.204482f, +-0.0826833f,0.991706f,0.0984031f, +-0.125203f,0.992066f,-0.0113628f, +-0.0793175f,0.988189f,-0.131112f, +-0.135148f,0.988869f,-0.0622353f, +-0.236045f,0.96998f,-0.0584937f, +-0.106098f,0.976702f,-0.186536f, +0.0734477f,0.937214f,-0.340932f, +0.0657813f,0.913127f,-0.402333f, +-0.0656411f,0.925185f,-0.373797f, +-0.0812155f,0.911514f,-0.403169f, +0.138018f,0.895606f,-0.422895f, +0.180346f,0.87052f,-0.457898f, +0.220345f,0.874256f,-0.43258f, +0.337626f,0.867122f,-0.366208f, +0.351448f,0.893332f,-0.280076f, +0.206919f,0.931373f,-0.299548f, +0.143612f,0.950749f,-0.274684f, +0.0388897f,0.972032f,-0.231606f, +-0.0281782f,0.996586f,-0.077599f, +-0.0348963f,0.997716f,-0.0578427f, +-0.0315338f,0.968969f,-0.245163f, +0.0536322f,0.969299f,-0.239965f, +-0.0592746f,0.980608f,-0.186802f, +-0.146447f,0.958871f,-0.243144f, +-0.0489008f,0.966653f,-0.251379f, +-0.0921771f,0.973026f,-0.211482f, +-0.303489f,0.921788f,-0.24125f, +-0.360359f,0.892722f,-0.270533f, +-0.374413f,0.86994f,-0.320965f, +-0.420297f,0.839321f,-0.344805f, +-0.400389f,0.890168f,-0.217463f, +-0.5519f,0.817694f,-0.163655f, +-0.641175f,0.723209f,-0.25664f, +-0.591295f,0.757829f,-0.275801f, +-0.562781f,0.775127f,-0.287152f, +-0.492934f,0.830818f,-0.258375f, +-0.559738f,0.799568f,-0.21768f, +-0.572862f,0.78051f,-0.250266f, +-0.449965f,0.836305f,-0.31325f, +-0.485973f,0.815927f,-0.313197f, +-0.461831f,0.850292f,-0.252418f, +-0.261301f,0.911823f,-0.316702f, +-0.0988633f,0.911184f,-0.399961f, +-0.117544f,0.902602f,-0.414118f, +-0.193385f,0.896249f,-0.399173f, +-0.121448f,0.924471f,-0.361392f, +0.0924319f,0.986306f,-0.136592f, +0.0129691f,0.994218f,-0.106593f, +0.0478938f,0.996018f,-0.0752017f, +0.0322924f,0.95892f,-0.281832f, +0.0176709f,0.880909f,-0.472956f, +0.117774f,0.85642f,-0.502666f, +0.141956f,0.850649f,-0.506206f, +0.133057f,0.865588f,-0.482757f, +0.139695f,0.858438f,-0.493528f, +-0.227309f,0.878161f,0.420907f, +-0.208802f,0.809453f,0.548805f, +-0.283627f,0.767885f,0.574377f, +-0.166581f,0.77975f,0.603523f, +-0.0979994f,0.806409f,0.583181f, +-0.132228f,0.805326f,0.577898f, +-0.219374f,0.878043f,0.425342f, +-0.024745f,0.955845f,0.292828f, +0.235018f,0.923494f,0.303193f, +0.225806f,0.944421f,0.238915f, +0.125193f,0.981151f,0.147203f, +-0.0300197f,0.990754f,0.132305f, +-0.0418198f,0.992604f,0.113964f, +0.010498f,0.998335f,0.0567192f, +-0.187859f,0.981941f,-0.0223995f, +-0.164152f,0.985849f,-0.0340039f, +-0.00148231f,0.989313f,-0.145799f, +0.214865f,0.96059f,-0.176353f, +0.130927f,0.950976f,-0.280185f, +-0.0784848f,0.932131f,-0.353513f, +-0.05291f,0.922588f,-0.382142f, +0.16861f,0.90111f,-0.399463f, +0.291627f,0.864919f,-0.408495f, +0.209787f,0.830907f,-0.515347f, +0.211969f,0.855025f,-0.473287f, +0.179371f,0.927145f,-0.328982f, +0.0938016f,0.98223f,-0.162562f, +0.0948278f,0.994302f,-0.0487031f, +0.0439203f,0.998532f,-0.0316906f, +-0.0612398f,0.9958f,-0.0680553f, +0.0442323f,0.992295f,-0.115732f, +0.0938163f,0.983362f,-0.155559f, +-0.00984882f,0.984434f,-0.175479f, +-0.064778f,0.984002f,-0.165961f, +-0.129271f,0.96358f,-0.234101f, +-0.126642f,0.968315f,-0.215238f, +-0.066296f,0.988071f,-0.138997f, +-0.153283f,0.960153f,-0.233691f, +-0.288259f,0.887225f,-0.360193f, +-0.349196f,0.862768f,-0.365641f, +-0.457337f,0.833523f,-0.309971f, +-0.510223f,0.838902f,-0.189514f, +-0.576482f,0.813491f,-0.0768136f, +-0.627022f,0.773599f,-0.0915885f, +-0.562811f,0.806938f,-0.179152f, +-0.554556f,0.77173f,-0.31129f, +-0.544029f,0.784112f,-0.298665f, +-0.593089f,0.773019f,-0.225135f, +-0.565758f,0.788678f,-0.240633f, +-0.424914f,0.871459f,-0.244963f, +-0.461935f,0.845882f,-0.266647f, +-0.437432f,0.833935f,-0.336461f, +-0.166572f,0.89804f,-0.407159f, +-0.027465f,0.893903f,-0.447419f, +-0.142495f,0.890824f,-0.431426f, +-0.254187f,0.896659f,-0.36248f, +-0.245781f,0.925153f,-0.289282f, +-0.124728f,0.970098f,-0.208211f, +0.0496061f,0.995502f,-0.0807218f, +0.134453f,0.977049f,-0.165221f, +0.178593f,0.948688f,-0.260952f, +0.203783f,0.948389f,-0.242962f, +0.169172f,0.89845f,-0.405178f, +0.129822f,0.855112f,-0.501925f, +0.114157f,0.849198f,-0.515587f, +0.207913f,0.855521f,-0.47419f, +-0.447508f,0.787815f,0.423184f, +-0.372189f,0.752087f,0.543911f, +-0.298757f,0.721076f,0.625135f, +-0.109779f,0.732409f,0.671956f, +-0.05023f,0.773443f,0.631872f, +-0.0721375f,0.784971f,0.615319f, +0.0161123f,0.834678f,0.550503f, +0.0881584f,0.925537f,0.368252f, +0.194291f,0.939133f,0.283338f, +0.290284f,0.915951f,0.277072f, +0.206501f,0.959193f,0.193147f, +0.0129994f,0.989588f,0.143339f, +-0.0515539f,0.993638f,0.100126f, +0.0752528f,0.992857f,0.0925807f, +-0.11243f,0.993659f,-0.00132253f, +-0.0900456f,0.995381f,-0.0332891f, +0.0735618f,0.988585f,-0.131483f, +0.187914f,0.97058f,-0.150539f, +0.259537f,0.959521f,-0.109363f, +0.039582f,0.950958f,-0.306778f, +0.0151247f,0.899216f,-0.437243f, +0.157602f,0.861329f,-0.482984f, +0.313265f,0.852495f,-0.41847f, +0.26241f,0.877515f,-0.401384f, +0.106606f,0.940488f,-0.322671f, +0.0451106f,0.964729f,-0.259351f, +-0.0198008f,0.966294f,-0.256677f, +0.0415355f,0.979836f,-0.195439f, +0.019077f,0.98811f,-0.15256f, +0.00843283f,0.995377f,-0.095676f, +0.0813095f,0.98616f,-0.14449f, +0.0601215f,0.98288f,-0.174159f, +0.0231889f,0.98066f,-0.194342f, +-0.0257967f,0.969536f,-0.243588f, +-0.0655874f,0.972755f,-0.222364f, +-0.116074f,0.960607f,-0.252509f, +-0.11539f,0.952331f,-0.282402f, +-0.0547002f,0.971779f,-0.229464f, +-0.238443f,0.921749f,-0.305817f, +-0.409013f,0.87493f,-0.259242f, +-0.537403f,0.830349f,-0.147369f, +-0.604026f,0.794872f,-0.0577237f, +-0.636334f,0.771366f,0.00856593f, +-0.598176f,0.796287f,0.0900769f, +-0.445184f,0.894265f,0.0458439f, +-0.510078f,0.851049f,-0.124644f, +-0.584904f,0.80616f,-0.0894032f, +-0.566358f,0.809139f,-0.156631f, +-0.526778f,0.78194f,-0.333278f, +-0.411595f,0.815587f,-0.406703f, +-0.430581f,0.806825f,-0.404517f, +-0.346574f,0.828739f,-0.439406f, +-0.163187f,0.84355f,-0.511658f, +-0.120565f,0.900123f,-0.41862f, +-0.22033f,0.94784f,-0.230335f, +-0.354954f,0.922144f,-0.15381f, +-0.229701f,0.962171f,-0.146509f, +-0.156358f,0.938689f,-0.30727f, +-0.0202846f,0.954287f,-0.298202f, +0.237025f,0.938874f,-0.24967f, +0.153523f,0.923965f,-0.350312f, +0.146234f,0.948682f,-0.280389f, +0.334575f,0.915861f,-0.221942f, +0.32488f,0.905199f,-0.273985f, +0.124349f,0.918374f,-0.375668f, +0.0853809f,0.932635f,-0.350575f, +-0.326098f,0.745953f,0.580702f, +-0.408924f,0.742079f,0.53113f, +-0.380928f,0.732802f,0.563822f, +-0.135265f,0.771831f,0.621274f, +0.0172939f,0.791015f,0.611552f, +-0.0321407f,0.821651f,0.569084f, +0.110827f,0.821493f,0.559345f, +0.260047f,0.831043f,0.491674f, +0.30077f,0.882298f,0.362061f, +0.33436f,0.910333f,0.243922f, +0.27591f,0.939307f,0.203903f, +0.0278945f,0.981912f,0.18727f, +-0.00885636f,0.980185f,0.197887f, +0.145141f,0.978135f,0.148949f, +-0.0144219f,0.999761f,0.0164012f, +-0.0725846f,0.989236f,-0.127057f, +0.156537f,0.975005f,-0.157677f, +0.153594f,0.966224f,-0.206929f, +0.277291f,0.95249f,-0.125986f, +0.254121f,0.951784f,-0.171844f, +0.192884f,0.934802f,-0.298229f, +0.176671f,0.893747f,-0.412315f, +0.195208f,0.917965f,-0.345303f, +0.157451f,0.974963f,-0.157023f, +0.0279983f,0.991052f,-0.13051f, +0.088609f,0.976865f,-0.194637f, +0.0507072f,0.953301f,-0.297735f, +-0.0277167f,0.944799f,-0.326477f, +-0.027462f,0.967827f,-0.250115f, +-0.0885824f,0.972427f,-0.215728f, +0.0938124f,0.990405f,-0.101477f, +0.168783f,0.975825f,-0.138845f, +0.111665f,0.949064f,-0.294633f, +-0.0373777f,0.928827f,-0.368623f, +-0.132876f,0.934016f,-0.3316f, +-0.0938993f,0.959978f,-0.263865f, +-0.105226f,0.962669f,-0.249392f, +-0.104341f,0.966883f,-0.232916f, +-0.220802f,0.965347f,-0.13911f, +-0.478375f,0.876928f,-0.0464122f, +-0.604444f,0.796064f,0.0305022f, +-0.611643f,0.789038f,0.0575453f, +-0.651561f,0.758511f,-0.0113831f, +-0.622019f,0.781788f,-0.0435906f, +-0.406862f,0.913403f,-0.012587f, +-0.447294f,0.893518f,0.0394196f, +-0.595605f,0.801728f,0.049859f, +-0.453119f,0.890822f,0.0334497f, +-0.397535f,0.913376f,-0.0878049f, +-0.358743f,0.901381f,-0.242521f, +-0.368468f,0.876571f,-0.309604f, +-0.3524f,0.834147f,-0.42428f, +-0.221095f,0.907887f,-0.356171f, +-0.336012f,0.912731f,-0.232418f, +-0.365521f,0.924164f,-0.110978f, +-0.381997f,0.913352f,-0.140951f, +-0.128103f,0.980976f,-0.145863f, +0.0620369f,0.958271f,-0.279048f, +-0.0393717f,0.894694f,-0.44494f, +0.166576f,0.906235f,-0.388576f, +0.257306f,0.912784f,-0.317204f, +0.0500832f,0.912737f,-0.405466f, +0.219062f,0.950498f,-0.220374f, +0.303476f,0.949102f,-0.0843104f, +0.167756f,0.983709f,-0.0646101f, +-0.00137806f,0.991718f,-0.128423f, +-0.411803f,0.737245f,0.535619f, +-0.383529f,0.716567f,0.582612f, +-0.385829f,0.756694f,0.527779f, +-0.125894f,0.866623f,0.482821f, +0.0864817f,0.885592f,0.456341f, +0.0185611f,0.909875f,0.414467f, +0.0890012f,0.92755f,0.362947f, +0.3312f,0.85507f,0.39895f, +0.411118f,0.842585f,0.347898f, +0.395768f,0.87253f,0.286458f, +0.265631f,0.912624f,0.310738f, +0.0432866f,0.942781f,0.330591f, +-0.0291247f,0.959608f,0.279829f, +0.17674f,0.935093f,0.307187f, +0.194038f,0.946511f,0.25781f, +0.0938941f,0.995535f,0.00965941f, +0.2133f,0.967919f,-0.132802f, +0.174202f,0.951285f,-0.254382f, +0.185706f,0.942688f,-0.277223f, +0.254853f,0.951817f,-0.170569f, +0.272452f,0.946195f,-0.174599f, +0.236374f,0.944357f,-0.228728f, +0.0622104f,0.974295f,-0.216517f, +0.00421412f,0.994674f,-0.102989f, +0.150974f,0.988535f,0.00252771f, +0.198367f,0.972494f,-0.122094f, +0.128147f,0.983415f,-0.128347f, +0.00128047f,0.972843f,-0.231463f, +-0.0877992f,0.94046f,-0.328368f, +-0.123322f,0.945018f,-0.302876f, +0.0120775f,0.960206f,-0.279033f, +0.230563f,0.945381f,-0.230424f, +0.231597f,0.934072f,-0.271795f, +0.0492688f,0.934225f,-0.353265f, +-0.160672f,0.892999f,-0.4204f, +-0.160391f,0.913064f,-0.374951f, +-0.146451f,0.932705f,-0.329565f, +-0.203905f,0.952995f,-0.224107f, +-0.374034f,0.927408f,-0.00361175f, +-0.538909f,0.826945f,0.160435f, +-0.614792f,0.776175f,0.139939f, +-0.589081f,0.79961f,0.116649f, +-0.558852f,0.827241f,0.0579274f, +-0.582196f,0.802416f,-0.131063f, +-0.51435f,0.846005f,-0.140428f, +-0.52517f,0.850476f,0.0297862f, +-0.596917f,0.80173f,0.0303285f, +-0.476386f,0.879145f,0.0126877f, +-0.346071f,0.935165f,0.0755073f, +-0.29506f,0.953573f,0.0603189f, +-0.290873f,0.956376f,0.0271545f, +-0.342792f,0.934849f,-0.0924672f, +-0.36131f,0.919889f,-0.152511f, +-0.440677f,0.895263f,-0.0656364f, +-0.27224f,0.960453f,-0.0584458f, +-0.239345f,0.939791f,-0.243941f, +-0.184322f,0.924268f,-0.334296f, +0.170265f,0.967851f,-0.185131f, +0.0831722f,0.975078f,-0.205681f, +0.0764752f,0.962386f,-0.2607f, +0.25092f,0.948574f,-0.192995f, +-0.000511184f,0.983325f,-0.181855f, +0.00805518f,0.99922f,-0.0386666f, +0.231558f,0.969957f,0.0745867f, +0.213284f,0.97378f,0.0791335f, +0.134707f,0.990255f,0.0353415f, +-0.461887f,0.727903f,0.506772f, +-0.409704f,0.769768f,0.48949f, +-0.245031f,0.85373f,0.459461f, +-0.000652498f,0.933053f,0.359739f, +0.0977619f,0.940993f,0.323999f, +0.0976539f,0.925223f,0.366641f, +0.122528f,0.958779f,0.256377f, +0.300256f,0.92807f,0.220301f, +0.434057f,0.868364f,0.239872f, +0.373936f,0.875783f,0.305249f, +0.188752f,0.892291f,0.41011f, +0.0749298f,0.875078f,0.478146f, +0.0539526f,0.905587f,0.420716f, +0.139771f,0.930537f,0.338475f, +0.252071f,0.902374f,0.349544f, +0.271241f,0.91149f,0.309214f, +0.343876f,0.91657f,0.204082f, +0.324141f,0.940857f,0.098591f, +0.18373f,0.982977f,-0.000581414f, +0.215424f,0.976468f,-0.0101277f, +0.272942f,0.961141f,-0.0413737f, +0.263192f,0.964688f,-0.010384f, +0.0834313f,0.988492f,-0.126183f, +-0.0244777f,0.972824f,-0.230248f, +0.037395f,0.972598f,-0.229465f, +0.188221f,0.98005f,-0.0638298f, +0.133895f,0.99093f,-0.0113778f, +0.15553f,0.985289f,-0.0708293f, +0.062154f,0.97927f,-0.19279f, +-0.0906565f,0.929896f,-0.356476f, +-0.00537849f,0.905315f,-0.424706f, +0.162604f,0.918237f,-0.361109f, +0.211297f,0.942163f,-0.260159f, +0.166674f,0.959094f,-0.22882f, +-0.0900843f,0.919646f,-0.382278f, +-0.185542f,0.891522f,-0.413234f, +-0.236454f,0.911319f,-0.337026f, +-0.404129f,0.904849f,-0.133894f, +-0.540771f,0.839361f,0.0551279f, +-0.598434f,0.794978f,0.0994372f, +-0.56944f,0.810652f,0.136315f, +-0.572323f,0.818089f,0.0563579f, +-0.472334f,0.880613f,0.0376913f, +-0.539685f,0.840552f,-0.0470301f, +-0.574258f,0.816988f,0.0525225f, +-0.582793f,0.802613f,0.127141f, +-0.577964f,0.810669f,0.0936681f, +-0.453297f,0.886551f,0.0924669f, +-0.392456f,0.918879f,0.0405067f, +-0.316387f,0.94595f,0.0712573f, +-0.278453f,0.953269f,0.117224f, +-0.268053f,0.957793f,0.103824f, +-0.307148f,0.94927f,0.0674248f, +-0.42059f,0.907249f,-0.00173726f, +-0.259446f,0.962613f,-0.0778756f, +-0.0851837f,0.992966f,-0.082236f, +-0.215247f,0.960313f,-0.177393f, +-0.0219544f,0.989556f,-0.14247f, +0.0391647f,0.99769f,-0.0555004f, +0.102045f,0.994433f,0.0262785f, +0.194292f,0.978837f,0.0642512f, +-0.0292693f,0.988875f,0.145839f, +-0.101853f,0.986247f,0.130166f, +0.212882f,0.964861f,0.15403f, +0.245798f,0.960888f,0.127587f, +0.195444f,0.974318f,0.111832f, +-0.321858f,0.809731f,0.490656f, +-0.324834f,0.8531f,0.408293f, +-0.169338f,0.931652f,0.321478f, +0.0137661f,0.965459f,0.260189f, +0.0568655f,0.931751f,0.358619f, +0.0773718f,0.91837f,0.388084f, +0.261047f,0.911575f,0.317625f, +0.360487f,0.919759f,0.155217f, +0.377368f,0.917164f,0.128078f, +0.276887f,0.917903f,0.284232f, +0.0739314f,0.913495f,0.400076f, +0.00592871f,0.863726f,0.503926f, +0.12818f,0.830694f,0.541773f, +0.218813f,0.849726f,0.479673f, +0.242686f,0.877276f,0.414115f, +0.274843f,0.886896f,0.371318f, +0.349234f,0.864992f,0.360313f, +0.316807f,0.866747f,0.385206f, +0.243026f,0.8884f,0.389467f, +0.293176f,0.904042f,0.311057f, +0.24905f,0.947495f,0.200568f, +0.307601f,0.926121f,0.21836f, +0.250581f,0.964737f,0.0805682f, +0.134636f,0.99035f,-0.0328548f, +0.000251354f,0.985828f,-0.167762f, +0.0218107f,0.990992f,-0.132131f, +0.159951f,0.984761f,-0.068279f, +0.165852f,0.977778f,-0.128229f, +0.162621f,0.98447f,-0.06613f, +0.121502f,0.975682f,-0.182435f, +0.0565286f,0.935574f,-0.348576f, +0.0461029f,0.9227f,-0.382752f, +0.0939341f,0.947555f,-0.305477f, +0.144515f,0.970016f,-0.195409f, +0.0775217f,0.989125f,-0.124991f, +-0.200827f,0.965332f,-0.16674f, +-0.401609f,0.907839f,-0.120577f, +-0.559375f,0.828885f,-0.00699655f, +-0.565805f,0.821746f,0.0678162f, +-0.593147f,0.804311f,0.0354918f, +-0.576294f,0.817225f,0.00543077f, +-0.525544f,0.848999f,-0.0548173f, +-0.499547f,0.863338f,-0.0714126f, +-0.553806f,0.830814f,0.0551944f, +-0.639015f,0.755184f,0.146141f, +-0.555848f,0.812796f,0.174341f, +-0.558245f,0.826947f,0.0672363f, +-0.433561f,0.898303f,0.0712505f, +-0.328723f,0.942541f,0.0596481f, +-0.348698f,0.936876f,0.0259581f, +-0.301092f,0.95068f,0.0745005f, +-0.263015f,0.962594f,0.0650869f, +-0.284818f,0.957539f,0.0446894f, +-0.359379f,0.932627f,-0.032449f, +-0.231945f,0.967322f,-0.102417f, +-0.134462f,0.989922f,-0.0444264f, +-0.162306f,0.986023f,0.0376183f, +0.00794699f,0.998548f,-0.0532871f, +-0.0239448f,0.993657f,-0.109874f, +-0.0216422f,0.99782f,0.0623378f, +0.109723f,0.978713f,0.173443f, +-0.0637399f,0.980084f,0.188075f, +-0.0488189f,0.981371f,0.185814f, +0.215314f,0.95546f,0.201833f, +0.226954f,0.944659f,0.236876f, +0.18874f,0.93582f,0.297688f, +-0.35388f,0.863488f,0.359384f, +-0.279389f,0.900607f,0.332938f, +-0.0980507f,0.952584f,0.288043f, +-0.0324622f,0.946395f,0.321377f, +-0.0380375f,0.913004f,0.406173f, +0.128955f,0.929408f,0.345792f, +0.375928f,0.898621f,0.226181f, +0.446257f,0.883274f,0.143813f, +0.289683f,0.938589f,0.187442f, +0.125289f,0.928145f,0.350499f, +-0.0288389f,0.895239f,0.444652f, +-0.103894f,0.871209f,0.479793f, +0.105997f,0.859294f,0.500378f, +0.239743f,0.842088f,0.483127f, +0.302444f,0.818919f,0.48775f, +0.351983f,0.830309f,0.432082f, +0.318807f,0.868172f,0.380315f, +0.306771f,0.857612f,0.412787f, +0.273726f,0.881543f,0.384651f, +0.337032f,0.866043f,0.369295f, +0.363605f,0.874829f,0.320103f, +0.334634f,0.927168f,0.168463f, +0.372292f,0.916204f,0.148217f, +0.206342f,0.978274f,0.0200943f, +0.119354f,0.989819f,-0.077546f, +0.042858f,0.974765f,-0.21908f, +0.15227f,0.956258f,-0.24977f, +0.17642f,0.955622f,-0.235928f, +0.119264f,0.963567f,-0.239406f, +0.210452f,0.949288f,-0.233584f, +0.171674f,0.93622f,-0.306626f, +0.0511268f,0.942128f,-0.331333f, +0.00960037f,0.978635f,-0.205381f, +-0.00181509f,0.99884f,-0.048118f, +-0.0483779f,0.993619f,0.101885f, +-0.221067f,0.964285f,0.145887f, +-0.435375f,0.898142f,0.0615596f, +-0.544434f,0.838804f,-0.00062539f, +-0.579913f,0.810216f,-0.0851529f, +-0.5726f,0.815766f,-0.0815813f, +-0.546649f,0.832873f,-0.0865884f, +-0.465735f,0.88205f,-0.071268f, +-0.55864f,0.824018f,-0.0944285f, +-0.642115f,0.765228f,0.0459774f, +-0.656804f,0.753752f,0.0216163f, +-0.520592f,0.853762f,0.00863503f, +-0.481258f,0.875004f,-0.0525228f, +-0.443379f,0.889071f,-0.113874f, +-0.339817f,0.937077f,-0.0800719f, +-0.346478f,0.935462f,-0.0697409f, +-0.350474f,0.934462f,-0.0628307f, +-0.228751f,0.97348f,-0.00313391f, +-0.230759f,0.970493f,-0.0699589f, +-0.279469f,0.954379f,-0.105155f, +-0.198889f,0.96686f,-0.16008f, +-0.230529f,0.946681f,-0.225058f, +-0.14204f,0.970201f,-0.196301f, +0.0687794f,0.962113f,-0.263834f, +-0.0677159f,0.979986f,-0.187196f, +-0.220027f,0.972288f,-0.0790245f, +0.07326f,0.993712f,0.0846721f, +-0.0289367f,0.993146f,0.113239f, +-0.106822f,0.986395f,0.124957f, +0.128381f,0.967004f,0.22005f, +0.141757f,0.945235f,0.293998f, +0.0274083f,0.95189f,0.30521f, +-0.150915f,0.940582f,0.304189f, +-0.174369f,0.970549f,0.166222f, +-0.140821f,0.979995f,0.140639f, +-0.141606f,0.959082f,0.245171f, +0.011894f,0.972798f,0.23135f, +0.262326f,0.961504f,0.0818187f, +0.456393f,0.889018f,0.036791f, +0.382632f,0.920315f,0.0813253f, +0.174752f,0.942069f,0.286301f, +-0.045852f,0.917014f,0.396211f, +-0.0633233f,0.882412f,0.466197f, +-0.0422981f,0.919143f,0.391647f, +0.126089f,0.949054f,0.288786f, +0.256733f,0.912921f,0.317275f, +0.315104f,0.887032f,0.337468f, +0.409846f,0.864148f,0.292018f, +0.343944f,0.901166f,0.263823f, +0.312798f,0.897029f,0.312244f, +0.323227f,0.888441f,0.325879f, +0.342446f,0.89904f,0.272869f, +0.451059f,0.860524f,0.236736f, +0.423682f,0.891569f,0.159992f, +0.404089f,0.899665f,0.165275f, +0.34072f,0.934631f,0.101855f, +0.255675f,0.966712f,-0.00994645f, +0.192495f,0.972523f,-0.130939f, +0.146493f,0.95759f,-0.248115f, +0.177747f,0.950895f,-0.253387f, +0.10258f,0.958737f,-0.265144f, +0.233714f,0.956929f,-0.172236f, +0.223818f,0.95591f,-0.190111f, +-0.0753718f,0.974181f,-0.212814f, +-0.223858f,0.97386f,-0.0385406f, +-0.201603f,0.967155f,0.154817f, +-0.110966f,0.95618f,0.270934f, +-0.121146f,0.966863f,0.224722f, +-0.291476f,0.94891f,0.120877f, +-0.477923f,0.877529f,-0.0391374f, +-0.509066f,0.849204f,-0.140369f, +-0.547573f,0.807834f,-0.218101f, +-0.563212f,0.785973f,-0.255028f, +-0.550783f,0.817799f,-0.166865f, +-0.567941f,0.823056f,0.00472398f, +-0.662541f,0.748994f,-0.00687841f, +-0.61971f,0.78387f,-0.03883f, +-0.523314f,0.847679f,-0.0870804f, +-0.447797f,0.889814f,-0.0877948f, +-0.443749f,0.888577f,-0.116264f, +-0.376466f,0.920201f,-0.107257f, +-0.337652f,0.938208f,-0.0758775f, +-0.365552f,0.926461f,-0.0896778f, +-0.259904f,0.962681f,-0.0754604f, +-0.126151f,0.988548f,-0.0828222f, +-0.30144f,0.926166f,-0.226606f, +-0.124801f,0.973148f,-0.193411f, +-0.0842547f,0.941418f,-0.326548f, +-0.0799027f,0.902475f,-0.423267f, +-0.00736616f,0.932864f,-0.360152f, +-0.199402f,0.957181f,-0.209865f, +-0.285967f,0.938676f,-0.192641f, +-0.0884894f,0.987166f,-0.132941f, +-0.0982017f,0.994337f,0.0406204f, +-0.151395f,0.982648f,0.107153f, +0.0310104f,0.988838f,0.14573f, +0.106405f,0.964191f,0.242925f, +0.070474f,0.952157f,0.297374f, +0.0656706f,0.9919f,0.108725f, +-0.0894851f,0.995828f,0.0178395f, +-0.190523f,0.981135f,0.0327999f, +-0.155304f,0.987556f,0.0247798f, +0.115224f,0.991572f,-0.0592235f, +0.36579f,0.920032f,-0.140496f, +0.356271f,0.926984f,-0.117348f, +0.248335f,0.959842f,0.130508f, +0.000801886f,0.966476f,0.256755f, +-0.114974f,0.940419f,0.319989f, +-0.0524682f,0.940494f,0.335734f, +0.129742f,0.951002f,0.280646f, +0.183656f,0.974747f,0.127042f, +0.210533f,0.964529f,0.159247f, +0.299776f,0.935816f,0.185429f, +0.476652f,0.857927f,0.191739f, +0.365421f,0.920615f,0.137608f, +0.247354f,0.961561f,0.119232f, +0.333488f,0.932256f,0.140299f, +0.428629f,0.898219f,0.0973634f, +0.470887f,0.881687f,0.0298847f, +0.443595f,0.892268f,0.0841461f, +0.38152f,0.920309f,0.0864469f, +0.381462f,0.916941f,0.117074f, +0.327497f,0.93955f,0.099957f, +0.304803f,0.952409f,-0.00357992f, +0.239937f,0.959204f,-0.149528f, +0.202117f,0.965308f,-0.165315f, +0.0495866f,0.988011f,-0.146203f, +0.0854477f,0.995976f,-0.027023f, +0.244078f,0.956317f,0.160886f, +-0.0753613f,0.986424f,0.145905f, +-0.339089f,0.932874f,0.12151f, +-0.294837f,0.942606f,0.15673f, +-0.104304f,0.973462f,0.203698f, +-0.0723227f,0.985619f,0.152724f, +-0.210009f,0.973927f,0.0858055f, +-0.391811f,0.919671f,-0.0262484f, +-0.442429f,0.895892f,-0.0404195f, +-0.501975f,0.857758f,-0.11078f, +-0.516547f,0.834688f,-0.190982f, +-0.606461f,0.747704f,-0.270451f, +-0.650373f,0.745527f,-0.145618f, +-0.638901f,0.762805f,-0.0996673f, +-0.598555f,0.785548f,-0.156994f, +-0.501024f,0.846694f,-0.179123f, +-0.446137f,0.875545f,-0.185426f, +-0.431282f,0.886668f,-0.16678f, +-0.409115f,0.903871f,-0.125073f, +-0.364534f,0.929271f,-0.0597475f, +-0.342967f,0.93838f,-0.0426101f, +-0.26831f,0.95962f,-0.0844963f, +-0.0393852f,0.992201f,-0.118264f, +-0.116204f,0.958118f,-0.261737f, +-0.10396f,0.911216f,-0.398596f, +0.0690263f,0.90803f,-0.41318f, +-0.107766f,0.879323f,-0.463872f, +-0.204112f,0.904181f,-0.375227f, +-0.300499f,0.93243f,-0.200683f, +-0.27347f,0.953749f,-0.124807f, +-0.169754f,0.978593f,-0.116359f, +-0.231778f,0.970053f,-0.072634f, +-0.190395f,0.98166f,0.00964305f, +-0.0305984f,0.996687f,0.0753532f, +0.015862f,0.984083f,0.177002f, +-0.0353434f,0.980638f,0.192612f, +-0.00358253f,0.996067f,-0.0885361f, +-0.091201f,0.995656f,-0.0187243f, +-0.182622f,0.982071f,0.0467509f, +-0.0739202f,0.997106f,-0.017751f, +0.154438f,0.971547f,-0.179571f, +0.395535f,0.904532f,-0.159291f, +0.194508f,0.960754f,-0.197781f, +0.113269f,0.98581f,0.123894f, +-0.030891f,0.963944f,0.264306f, +-0.124571f,0.959262f,0.253572f, +-0.0553429f,0.968125f,0.244277f, +0.192328f,0.950681f,0.243343f, +0.217769f,0.968216f,0.123025f, +0.205296f,0.966103f,0.156522f, +0.276023f,0.954237f,0.11508f, +0.467224f,0.868183f,0.167212f, +0.402263f,0.894308f,0.195955f, +0.299601f,0.940084f,0.162733f, +0.355906f,0.933872f,0.0348486f, +0.474044f,0.880198f,-0.0230946f, +0.444725f,0.891474f,-0.0865651f, +0.431452f,0.901988f,0.0163334f, +0.385491f,0.922676f,0.00810292f, +0.339313f,0.940655f,0.00595024f, +0.37483f,0.92173f,0.099581f, +0.41171f,0.911266f,-0.00949356f, +0.281208f,0.933096f,-0.224175f, +0.138066f,0.959634f,-0.245031f, +0.0299217f,0.992057f,-0.122182f, +-0.0797424f,0.99128f,-0.104905f, +0.124146f,0.977522f,0.170405f, +-0.0302976f,0.947743f,0.317594f, +-0.301142f,0.928457f,0.21744f, +-0.278579f,0.94845f,0.151119f, +-0.150217f,0.982764f,0.107745f, +0.0163995f,0.982022f,0.188052f, +-0.137431f,0.989816f,0.0370977f, +-0.36652f,0.926186f,-0.0885568f, +-0.445397f,0.895157f,-0.0177851f, +-0.463397f,0.885777f,-0.0257252f, +-0.466469f,0.878885f,-0.099842f, +-0.557948f,0.804805f,-0.202443f, +-0.681509f,0.679149f,-0.272587f, +-0.629296f,0.753928f,-0.188625f, +-0.5596f,0.798482f,-0.221976f, +-0.503025f,0.800303f,-0.326313f, +-0.422254f,0.855253f,-0.300408f, +-0.454716f,0.829192f,-0.325075f, +-0.46025f,0.856807f,-0.232488f, +-0.37729f,0.921922f,-0.0878209f, +-0.375084f,0.920087f,-0.112928f, +-0.173161f,0.984659f,-0.0214944f, +-0.0348229f,0.978528f,-0.20315f, +0.0523603f,0.977312f,-0.205229f, +-0.0533357f,0.893335f,-0.446215f, +0.0246713f,0.873256f,-0.486637f, +-0.0923807f,0.905308f,-0.414587f, +-0.269958f,0.871402f,-0.409612f, +-0.388686f,0.862358f,-0.324442f, +-0.340148f,0.928537f,-0.148722f, +-0.147166f,0.988619f,-0.0312327f, +-0.248059f,0.963625f,-0.099463f, +-0.232297f,0.969578f,-0.0771772f, +-0.142695f,0.989498f,-0.02308f, +-0.0198137f,0.98287f,0.18323f, +-0.0333475f,0.978727f,0.202438f, +}; + +btScalar Landscape05Tex[] = { +0.0f,0.5f, +0.0f,0.492188f, +0.0078125f,0.5f, +0.0078125f,0.492188f, +0.015625f,0.5f, +0.015625f,0.492188f, +0.0234375f,0.5f, +0.0234375f,0.492188f, +0.03125f,0.5f, +0.03125f,0.492188f, +0.0390625f,0.5f, +0.0390625f,0.492188f, +0.046875f,0.5f, +0.046875f,0.492188f, +0.0546875f,0.5f, +0.0546875f,0.492188f, +0.0625f,0.5f, +0.0625f,0.492188f, +0.0703125f,0.5f, +0.0703125f,0.492188f, +0.078125f,0.5f, +0.078125f,0.492188f, +0.0859375f,0.5f, +0.0859375f,0.492188f, +0.09375f,0.5f, +0.09375f,0.492188f, +0.101563f,0.5f, +0.101563f,0.492188f, +0.109375f,0.5f, +0.109375f,0.492188f, +0.117188f,0.5f, +0.117188f,0.492188f, +0.125f,0.5f, +0.125f,0.492188f, +0.132813f,0.5f, +0.132813f,0.492188f, +0.140625f,0.5f, +0.140625f,0.492188f, +0.148438f,0.5f, +0.148438f,0.492188f, +0.15625f,0.5f, +0.15625f,0.492188f, +0.164063f,0.5f, +0.164063f,0.492188f, +0.171875f,0.5f, +0.171875f,0.492188f, +0.179688f,0.5f, +0.179688f,0.492188f, +0.1875f,0.5f, +0.1875f,0.492188f, +0.195313f,0.5f, +0.195313f,0.492188f, +0.203125f,0.5f, +0.203125f,0.492188f, +0.210938f,0.5f, +0.210938f,0.492188f, +0.21875f,0.5f, +0.21875f,0.492188f, +0.226563f,0.5f, +0.226563f,0.492188f, +0.234375f,0.5f, +0.234375f,0.492188f, +0.242188f,0.5f, +0.242188f,0.492188f, +0.25f,0.5f, +0.25f,0.492188f, +0.257813f,0.5f, +0.257813f,0.492188f, +0.265625f,0.5f, +0.265625f,0.492188f, +0.273438f,0.5f, +0.273438f,0.492188f, +0.28125f,0.5f, +0.28125f,0.492188f, +0.289063f,0.5f, +0.289063f,0.492188f, +0.296875f,0.5f, +0.296875f,0.492188f, +0.304688f,0.5f, +0.304688f,0.492188f, +0.3125f,0.5f, +0.3125f,0.492188f, +0.320313f,0.5f, +0.320313f,0.492188f, +0.328125f,0.5f, +0.328125f,0.492188f, +0.335938f,0.5f, +0.335938f,0.492188f, +0.34375f,0.5f, +0.34375f,0.492188f, +0.351563f,0.5f, +0.351563f,0.492188f, +0.359375f,0.5f, +0.359375f,0.492188f, +0.367188f,0.5f, +0.367188f,0.492188f, +0.375f,0.5f, +0.375f,0.492188f, +0.382813f,0.5f, +0.382813f,0.492188f, +0.390625f,0.5f, +0.390625f,0.492188f, +0.398438f,0.5f, +0.398438f,0.492188f, +0.40625f,0.5f, +0.40625f,0.492188f, +0.414063f,0.5f, +0.414063f,0.492188f, +0.421875f,0.5f, +0.421875f,0.492188f, +0.429688f,0.5f, +0.429688f,0.492188f, +0.4375f,0.5f, +0.4375f,0.492188f, +0.445313f,0.5f, +0.445313f,0.492188f, +0.453125f,0.5f, +0.453125f,0.492188f, +0.460938f,0.5f, +0.460938f,0.492188f, +0.46875f,0.5f, +0.46875f,0.492188f, +0.476563f,0.5f, +0.476563f,0.492188f, +0.484375f,0.5f, +0.484375f,0.492188f, +0.492188f,0.5f, +0.492188f,0.492188f, +0.5f,0.5f, +0.5f,0.492188f, +0.507813f,0.5f, +0.507813f,0.492188f, +0.0f,0.507813f, +0.0078125f,0.507813f, +0.015625f,0.507813f, +0.0234375f,0.507813f, +0.03125f,0.507813f, +0.0390625f,0.507813f, +0.046875f,0.507813f, +0.0546875f,0.507813f, +0.0625f,0.507813f, +0.0703125f,0.507813f, +0.078125f,0.507813f, +0.0859375f,0.507813f, +0.09375f,0.507813f, +0.101563f,0.507813f, +0.109375f,0.507813f, +0.117188f,0.507813f, +0.125f,0.507813f, +0.132813f,0.507813f, +0.140625f,0.507813f, +0.148438f,0.507813f, +0.15625f,0.507813f, +0.164063f,0.507813f, +0.171875f,0.507813f, +0.179688f,0.507813f, +0.1875f,0.507813f, +0.195313f,0.507813f, +0.203125f,0.507813f, +0.210938f,0.507813f, +0.21875f,0.507813f, +0.226563f,0.507813f, +0.234375f,0.507813f, +0.242188f,0.507813f, +0.25f,0.507813f, +0.257813f,0.507813f, +0.265625f,0.507813f, +0.273438f,0.507813f, +0.28125f,0.507813f, +0.289063f,0.507813f, +0.296875f,0.507813f, +0.304688f,0.507813f, +0.3125f,0.507813f, +0.320313f,0.507813f, +0.328125f,0.507813f, +0.335938f,0.507813f, +0.34375f,0.507813f, +0.351563f,0.507813f, +0.359375f,0.507813f, +0.367188f,0.507813f, +0.375f,0.507813f, +0.382813f,0.507813f, +0.390625f,0.507813f, +0.398438f,0.507813f, +0.40625f,0.507813f, +0.414063f,0.507813f, +0.421875f,0.507813f, +0.429688f,0.507813f, +0.4375f,0.507813f, +0.445313f,0.507813f, +0.453125f,0.507813f, +0.460938f,0.507813f, +0.46875f,0.507813f, +0.476563f,0.507813f, +0.484375f,0.507813f, +0.492188f,0.507813f, +0.5f,0.507813f, +0.507813f,0.507813f, +0.0f,0.515625f, +0.0078125f,0.515625f, +0.015625f,0.515625f, +0.0234375f,0.515625f, +0.03125f,0.515625f, +0.0390625f,0.515625f, +0.046875f,0.515625f, +0.0546875f,0.515625f, +0.0625f,0.515625f, +0.0703125f,0.515625f, +0.078125f,0.515625f, +0.0859375f,0.515625f, +0.09375f,0.515625f, +0.101563f,0.515625f, +0.109375f,0.515625f, +0.117188f,0.515625f, +0.125f,0.515625f, +0.132813f,0.515625f, +0.140625f,0.515625f, +0.148438f,0.515625f, +0.15625f,0.515625f, +0.164063f,0.515625f, +0.171875f,0.515625f, +0.179688f,0.515625f, +0.1875f,0.515625f, +0.195313f,0.515625f, +0.203125f,0.515625f, +0.210938f,0.515625f, +0.21875f,0.515625f, +0.226563f,0.515625f, +0.234375f,0.515625f, +0.242188f,0.515625f, +0.25f,0.515625f, +0.257813f,0.515625f, +0.265625f,0.515625f, +0.273438f,0.515625f, +0.28125f,0.515625f, +0.289063f,0.515625f, +0.296875f,0.515625f, +0.304688f,0.515625f, +0.3125f,0.515625f, +0.320313f,0.515625f, +0.328125f,0.515625f, +0.335938f,0.515625f, +0.34375f,0.515625f, +0.351563f,0.515625f, +0.359375f,0.515625f, +0.367188f,0.515625f, +0.375f,0.515625f, +0.382813f,0.515625f, +0.390625f,0.515625f, +0.398438f,0.515625f, +0.40625f,0.515625f, +0.414063f,0.515625f, +0.421875f,0.515625f, +0.429688f,0.515625f, +0.4375f,0.515625f, +0.445313f,0.515625f, +0.453125f,0.515625f, +0.460938f,0.515625f, +0.46875f,0.515625f, +0.476563f,0.515625f, +0.484375f,0.515625f, +0.492188f,0.515625f, +0.5f,0.515625f, +0.507813f,0.515625f, +0.0f,0.523438f, +0.0078125f,0.523438f, +0.015625f,0.523438f, +0.0234375f,0.523438f, +0.03125f,0.523438f, +0.0390625f,0.523438f, +0.046875f,0.523438f, +0.0546875f,0.523438f, +0.0625f,0.523438f, +0.0703125f,0.523438f, +0.078125f,0.523438f, +0.0859375f,0.523438f, +0.09375f,0.523438f, +0.101563f,0.523438f, +0.109375f,0.523438f, +0.117188f,0.523438f, +0.125f,0.523438f, +0.132813f,0.523438f, +0.140625f,0.523438f, +0.148438f,0.523438f, +0.15625f,0.523438f, +0.164063f,0.523438f, +0.171875f,0.523438f, +0.179688f,0.523438f, +0.1875f,0.523438f, +0.195313f,0.523438f, +0.203125f,0.523438f, +0.210938f,0.523438f, +0.21875f,0.523438f, +0.226563f,0.523438f, +0.234375f,0.523438f, +0.242188f,0.523438f, +0.25f,0.523438f, +0.257813f,0.523438f, +0.265625f,0.523438f, +0.273438f,0.523438f, +0.28125f,0.523438f, +0.289063f,0.523438f, +0.296875f,0.523438f, +0.304688f,0.523438f, +0.3125f,0.523438f, +0.320313f,0.523438f, +0.328125f,0.523438f, +0.335938f,0.523438f, +0.34375f,0.523438f, +0.351563f,0.523438f, +0.359375f,0.523438f, +0.367188f,0.523438f, +0.375f,0.523438f, +0.382813f,0.523438f, +0.390625f,0.523438f, +0.398438f,0.523438f, +0.40625f,0.523438f, +0.414063f,0.523438f, +0.421875f,0.523438f, +0.429688f,0.523438f, +0.4375f,0.523438f, +0.445313f,0.523438f, +0.453125f,0.523438f, +0.460938f,0.523438f, +0.46875f,0.523438f, +0.476563f,0.523438f, +0.484375f,0.523438f, +0.492188f,0.523438f, +0.5f,0.523438f, +0.507813f,0.523438f, +0.0f,0.53125f, +0.0078125f,0.53125f, +0.015625f,0.53125f, +0.0234375f,0.53125f, +0.03125f,0.53125f, +0.0390625f,0.53125f, +0.046875f,0.53125f, +0.0546875f,0.53125f, +0.0625f,0.53125f, +0.0703125f,0.53125f, +0.078125f,0.53125f, +0.0859375f,0.53125f, +0.09375f,0.53125f, +0.101563f,0.53125f, +0.109375f,0.53125f, +0.117188f,0.53125f, +0.125f,0.53125f, +0.132813f,0.53125f, +0.140625f,0.53125f, +0.148438f,0.53125f, +0.15625f,0.53125f, +0.164063f,0.53125f, +0.171875f,0.53125f, +0.179688f,0.53125f, +0.1875f,0.53125f, +0.195313f,0.53125f, +0.203125f,0.53125f, +0.210938f,0.53125f, +0.21875f,0.53125f, +0.226563f,0.53125f, +0.234375f,0.53125f, +0.242188f,0.53125f, +0.25f,0.53125f, +0.257813f,0.53125f, +0.265625f,0.53125f, +0.273438f,0.53125f, +0.28125f,0.53125f, +0.289063f,0.53125f, +0.296875f,0.53125f, +0.304688f,0.53125f, +0.3125f,0.53125f, +0.320313f,0.53125f, +0.328125f,0.53125f, +0.335938f,0.53125f, +0.34375f,0.53125f, +0.351563f,0.53125f, +0.359375f,0.53125f, +0.367188f,0.53125f, +0.375f,0.53125f, +0.382813f,0.53125f, +0.390625f,0.53125f, +0.398438f,0.53125f, +0.40625f,0.53125f, +0.414063f,0.53125f, +0.421875f,0.53125f, +0.429688f,0.53125f, +0.4375f,0.53125f, +0.445313f,0.53125f, +0.453125f,0.53125f, +0.460938f,0.53125f, +0.46875f,0.53125f, +0.476563f,0.53125f, +0.484375f,0.53125f, +0.492188f,0.53125f, +0.5f,0.53125f, +0.507813f,0.53125f, +0.0f,0.539063f, +0.0078125f,0.539063f, +0.015625f,0.539063f, +0.0234375f,0.539063f, +0.03125f,0.539063f, +0.0390625f,0.539063f, +0.046875f,0.539063f, +0.0546875f,0.539063f, +0.0625f,0.539063f, +0.0703125f,0.539063f, +0.078125f,0.539063f, +0.0859375f,0.539063f, +0.09375f,0.539063f, +0.101563f,0.539063f, +0.109375f,0.539063f, +0.117188f,0.539063f, +0.125f,0.539063f, +0.132813f,0.539063f, +0.140625f,0.539063f, +0.148438f,0.539063f, +0.15625f,0.539063f, +0.164063f,0.539063f, +0.171875f,0.539063f, +0.179688f,0.539063f, +0.1875f,0.539063f, +0.195313f,0.539063f, +0.203125f,0.539063f, +0.210938f,0.539063f, +0.21875f,0.539063f, +0.226563f,0.539063f, +0.234375f,0.539063f, +0.242188f,0.539063f, +0.25f,0.539063f, +0.257813f,0.539063f, +0.265625f,0.539063f, +0.273438f,0.539063f, +0.28125f,0.539063f, +0.289063f,0.539063f, +0.296875f,0.539063f, +0.304688f,0.539063f, +0.3125f,0.539063f, +0.320313f,0.539063f, +0.328125f,0.539063f, +0.335938f,0.539063f, +0.34375f,0.539063f, +0.351563f,0.539063f, +0.359375f,0.539063f, +0.367188f,0.539063f, +0.375f,0.539063f, +0.382813f,0.539063f, +0.390625f,0.539063f, +0.398438f,0.539063f, +0.40625f,0.539063f, +0.414063f,0.539063f, +0.421875f,0.539063f, +0.429688f,0.539063f, +0.4375f,0.539063f, +0.445313f,0.539063f, +0.453125f,0.539063f, +0.460938f,0.539063f, +0.46875f,0.539063f, +0.476563f,0.539063f, +0.484375f,0.539063f, +0.492188f,0.539063f, +0.5f,0.539063f, +0.507813f,0.539063f, +0.0f,0.546875f, +0.0078125f,0.546875f, +0.015625f,0.546875f, +0.0234375f,0.546875f, +0.03125f,0.546875f, +0.0390625f,0.546875f, +0.046875f,0.546875f, +0.0546875f,0.546875f, +0.0625f,0.546875f, +0.0703125f,0.546875f, +0.078125f,0.546875f, +0.0859375f,0.546875f, +0.09375f,0.546875f, +0.101563f,0.546875f, +0.109375f,0.546875f, +0.117188f,0.546875f, +0.125f,0.546875f, +0.132813f,0.546875f, +0.140625f,0.546875f, +0.148438f,0.546875f, +0.15625f,0.546875f, +0.164063f,0.546875f, +0.171875f,0.546875f, +0.179688f,0.546875f, +0.1875f,0.546875f, +0.195313f,0.546875f, +0.203125f,0.546875f, +0.210938f,0.546875f, +0.21875f,0.546875f, +0.226563f,0.546875f, +0.234375f,0.546875f, +0.242188f,0.546875f, +0.25f,0.546875f, +0.257813f,0.546875f, +0.265625f,0.546875f, +0.273438f,0.546875f, +0.28125f,0.546875f, +0.289063f,0.546875f, +0.296875f,0.546875f, +0.304688f,0.546875f, +0.3125f,0.546875f, +0.320313f,0.546875f, +0.328125f,0.546875f, +0.335938f,0.546875f, +0.34375f,0.546875f, +0.351563f,0.546875f, +0.359375f,0.546875f, +0.367188f,0.546875f, +0.375f,0.546875f, +0.382813f,0.546875f, +0.390625f,0.546875f, +0.398438f,0.546875f, +0.40625f,0.546875f, +0.414063f,0.546875f, +0.421875f,0.546875f, +0.429688f,0.546875f, +0.4375f,0.546875f, +0.445313f,0.546875f, +0.453125f,0.546875f, +0.460938f,0.546875f, +0.46875f,0.546875f, +0.476563f,0.546875f, +0.484375f,0.546875f, +0.492188f,0.546875f, +0.5f,0.546875f, +0.507813f,0.546875f, +0.0f,0.554688f, +0.0078125f,0.554688f, +0.015625f,0.554688f, +0.0234375f,0.554688f, +0.03125f,0.554688f, +0.0390625f,0.554688f, +0.046875f,0.554688f, +0.0546875f,0.554688f, +0.0625f,0.554688f, +0.0703125f,0.554688f, +0.078125f,0.554688f, +0.0859375f,0.554688f, +0.09375f,0.554688f, +0.101563f,0.554688f, +0.109375f,0.554688f, +0.117188f,0.554688f, +0.125f,0.554688f, +0.132813f,0.554688f, +0.140625f,0.554688f, +0.148438f,0.554688f, +0.15625f,0.554688f, +0.164063f,0.554688f, +0.171875f,0.554688f, +0.179688f,0.554688f, +0.1875f,0.554688f, +0.195313f,0.554688f, +0.203125f,0.554688f, +0.210938f,0.554688f, +0.21875f,0.554688f, +0.226563f,0.554688f, +0.234375f,0.554688f, +0.242188f,0.554688f, +0.25f,0.554688f, +0.257813f,0.554688f, +0.265625f,0.554688f, +0.273438f,0.554688f, +0.28125f,0.554688f, +0.289063f,0.554688f, +0.296875f,0.554688f, +0.304688f,0.554688f, +0.3125f,0.554688f, +0.320313f,0.554688f, +0.328125f,0.554688f, +0.335938f,0.554688f, +0.34375f,0.554688f, +0.351563f,0.554688f, +0.359375f,0.554688f, +0.367188f,0.554688f, +0.375f,0.554688f, +0.382813f,0.554688f, +0.390625f,0.554688f, +0.398438f,0.554688f, +0.40625f,0.554688f, +0.414063f,0.554688f, +0.421875f,0.554688f, +0.429688f,0.554688f, +0.4375f,0.554688f, +0.445313f,0.554688f, +0.453125f,0.554688f, +0.460938f,0.554688f, +0.46875f,0.554688f, +0.476563f,0.554688f, +0.484375f,0.554688f, +0.492188f,0.554688f, +0.5f,0.554688f, +0.507813f,0.554688f, +0.0f,0.5625f, +0.0078125f,0.5625f, +0.015625f,0.5625f, +0.0234375f,0.5625f, +0.03125f,0.5625f, +0.0390625f,0.5625f, +0.046875f,0.5625f, +0.0546875f,0.5625f, +0.0625f,0.5625f, +0.0703125f,0.5625f, +0.078125f,0.5625f, +0.0859375f,0.5625f, +0.09375f,0.5625f, +0.101563f,0.5625f, +0.109375f,0.5625f, +0.117188f,0.5625f, +0.125f,0.5625f, +0.132813f,0.5625f, +0.140625f,0.5625f, +0.148438f,0.5625f, +0.15625f,0.5625f, +0.164063f,0.5625f, +0.171875f,0.5625f, +0.179688f,0.5625f, +0.1875f,0.5625f, +0.195313f,0.5625f, +0.203125f,0.5625f, +0.210938f,0.5625f, +0.21875f,0.5625f, +0.226563f,0.5625f, +0.234375f,0.5625f, +0.242188f,0.5625f, +0.25f,0.5625f, +0.257813f,0.5625f, +0.265625f,0.5625f, +0.273438f,0.5625f, +0.28125f,0.5625f, +0.289063f,0.5625f, +0.296875f,0.5625f, +0.304688f,0.5625f, +0.3125f,0.5625f, +0.320313f,0.5625f, +0.328125f,0.5625f, +0.335938f,0.5625f, +0.34375f,0.5625f, +0.351563f,0.5625f, +0.359375f,0.5625f, +0.367188f,0.5625f, +0.375f,0.5625f, +0.382813f,0.5625f, +0.390625f,0.5625f, +0.398438f,0.5625f, +0.40625f,0.5625f, +0.414063f,0.5625f, +0.421875f,0.5625f, +0.429688f,0.5625f, +0.4375f,0.5625f, +0.445313f,0.5625f, +0.453125f,0.5625f, +0.460938f,0.5625f, +0.46875f,0.5625f, +0.476563f,0.5625f, +0.484375f,0.5625f, +0.492188f,0.5625f, +0.5f,0.5625f, +0.507813f,0.5625f, +0.0f,0.570313f, +0.0078125f,0.570313f, +0.015625f,0.570313f, +0.0234375f,0.570313f, +0.03125f,0.570313f, +0.0390625f,0.570313f, +0.046875f,0.570313f, +0.0546875f,0.570313f, +0.0625f,0.570313f, +0.0703125f,0.570313f, +0.078125f,0.570313f, +0.0859375f,0.570313f, +0.09375f,0.570313f, +0.101563f,0.570313f, +0.109375f,0.570313f, +0.117188f,0.570313f, +0.125f,0.570313f, +0.132813f,0.570313f, +0.140625f,0.570313f, +0.148438f,0.570313f, +0.15625f,0.570313f, +0.164063f,0.570313f, +0.171875f,0.570313f, +0.179688f,0.570313f, +0.1875f,0.570313f, +0.195313f,0.570313f, +0.203125f,0.570313f, +0.210938f,0.570313f, +0.21875f,0.570313f, +0.226563f,0.570313f, +0.234375f,0.570313f, +0.242188f,0.570313f, +0.25f,0.570313f, +0.257813f,0.570313f, +0.265625f,0.570313f, +0.273438f,0.570313f, +0.28125f,0.570313f, +0.289063f,0.570313f, +0.296875f,0.570313f, +0.304688f,0.570313f, +0.3125f,0.570313f, +0.320313f,0.570313f, +0.328125f,0.570313f, +0.335938f,0.570313f, +0.34375f,0.570313f, +0.351563f,0.570313f, +0.359375f,0.570313f, +0.367188f,0.570313f, +0.375f,0.570313f, +0.382813f,0.570313f, +0.390625f,0.570313f, +0.398438f,0.570313f, +0.40625f,0.570313f, +0.414063f,0.570313f, +0.421875f,0.570313f, +0.429688f,0.570313f, +0.4375f,0.570313f, +0.445313f,0.570313f, +0.453125f,0.570313f, +0.460938f,0.570313f, +0.46875f,0.570313f, +0.476563f,0.570313f, +0.484375f,0.570313f, +0.492188f,0.570313f, +0.5f,0.570313f, +0.507813f,0.570313f, +0.0f,0.578125f, +0.0078125f,0.578125f, +0.015625f,0.578125f, +0.0234375f,0.578125f, +0.03125f,0.578125f, +0.0390625f,0.578125f, +0.046875f,0.578125f, +0.0546875f,0.578125f, +0.0625f,0.578125f, +0.0703125f,0.578125f, +0.078125f,0.578125f, +0.0859375f,0.578125f, +0.09375f,0.578125f, +0.101563f,0.578125f, +0.109375f,0.578125f, +0.117188f,0.578125f, +0.125f,0.578125f, +0.132813f,0.578125f, +0.140625f,0.578125f, +0.148438f,0.578125f, +0.15625f,0.578125f, +0.164063f,0.578125f, +0.171875f,0.578125f, +0.179688f,0.578125f, +0.1875f,0.578125f, +0.195313f,0.578125f, +0.203125f,0.578125f, +0.210938f,0.578125f, +0.21875f,0.578125f, +0.226563f,0.578125f, +0.234375f,0.578125f, +0.242188f,0.578125f, +0.25f,0.578125f, +0.257813f,0.578125f, +0.265625f,0.578125f, +0.273438f,0.578125f, +0.28125f,0.578125f, +0.289063f,0.578125f, +0.296875f,0.578125f, +0.304688f,0.578125f, +0.3125f,0.578125f, +0.320313f,0.578125f, +0.328125f,0.578125f, +0.335938f,0.578125f, +0.34375f,0.578125f, +0.351563f,0.578125f, +0.359375f,0.578125f, +0.367188f,0.578125f, +0.375f,0.578125f, +0.382813f,0.578125f, +0.390625f,0.578125f, +0.398438f,0.578125f, +0.40625f,0.578125f, +0.414063f,0.578125f, +0.421875f,0.578125f, +0.429688f,0.578125f, +0.4375f,0.578125f, +0.445313f,0.578125f, +0.453125f,0.578125f, +0.460938f,0.578125f, +0.46875f,0.578125f, +0.476563f,0.578125f, +0.484375f,0.578125f, +0.492188f,0.578125f, +0.5f,0.578125f, +0.507813f,0.578125f, +0.0f,0.585938f, +0.0078125f,0.585938f, +0.015625f,0.585938f, +0.0234375f,0.585938f, +0.03125f,0.585938f, +0.0390625f,0.585938f, +0.046875f,0.585938f, +0.0546875f,0.585938f, +0.0625f,0.585938f, +0.0703125f,0.585938f, +0.078125f,0.585938f, +0.0859375f,0.585938f, +0.09375f,0.585938f, +0.101563f,0.585938f, +0.109375f,0.585938f, +0.117188f,0.585938f, +0.125f,0.585938f, +0.132813f,0.585938f, +0.140625f,0.585938f, +0.148438f,0.585938f, +0.15625f,0.585938f, +0.164063f,0.585938f, +0.171875f,0.585938f, +0.179688f,0.585938f, +0.1875f,0.585938f, +0.195313f,0.585938f, +0.203125f,0.585938f, +0.210938f,0.585938f, +0.21875f,0.585938f, +0.226563f,0.585938f, +0.234375f,0.585938f, +0.242188f,0.585938f, +0.25f,0.585938f, +0.257813f,0.585938f, +0.265625f,0.585938f, +0.273438f,0.585938f, +0.28125f,0.585938f, +0.289063f,0.585938f, +0.296875f,0.585938f, +0.304688f,0.585938f, +0.3125f,0.585938f, +0.320313f,0.585938f, +0.328125f,0.585938f, +0.335938f,0.585938f, +0.34375f,0.585938f, +0.351563f,0.585938f, +0.359375f,0.585938f, +0.367188f,0.585938f, +0.375f,0.585938f, +0.382813f,0.585938f, +0.390625f,0.585938f, +0.398438f,0.585938f, +0.40625f,0.585938f, +0.414063f,0.585938f, +0.421875f,0.585938f, +0.429688f,0.585938f, +0.4375f,0.585938f, +0.445313f,0.585938f, +0.453125f,0.585938f, +0.460938f,0.585938f, +0.46875f,0.585938f, +0.476563f,0.585938f, +0.484375f,0.585938f, +0.492188f,0.585938f, +0.5f,0.585938f, +0.507813f,0.585938f, +0.0f,0.59375f, +0.0078125f,0.59375f, +0.015625f,0.59375f, +0.0234375f,0.59375f, +0.03125f,0.59375f, +0.0390625f,0.59375f, +0.046875f,0.59375f, +0.0546875f,0.59375f, +0.0625f,0.59375f, +0.0703125f,0.59375f, +0.078125f,0.59375f, +0.0859375f,0.59375f, +0.09375f,0.59375f, +0.101563f,0.59375f, +0.109375f,0.59375f, +0.117188f,0.59375f, +0.125f,0.59375f, +0.132813f,0.59375f, +0.140625f,0.59375f, +0.148438f,0.59375f, +0.15625f,0.59375f, +0.164063f,0.59375f, +0.171875f,0.59375f, +0.179688f,0.59375f, +0.1875f,0.59375f, +0.195313f,0.59375f, +0.203125f,0.59375f, +0.210938f,0.59375f, +0.21875f,0.59375f, +0.226563f,0.59375f, +0.234375f,0.59375f, +0.242188f,0.59375f, +0.25f,0.59375f, +0.257813f,0.59375f, +0.265625f,0.59375f, +0.273438f,0.59375f, +0.28125f,0.59375f, +0.289063f,0.59375f, +0.296875f,0.59375f, +0.304688f,0.59375f, +0.3125f,0.59375f, +0.320313f,0.59375f, +0.328125f,0.59375f, +0.335938f,0.59375f, +0.34375f,0.59375f, +0.351563f,0.59375f, +0.359375f,0.59375f, +0.367188f,0.59375f, +0.375f,0.59375f, +0.382813f,0.59375f, +0.390625f,0.59375f, +0.398438f,0.59375f, +0.40625f,0.59375f, +0.414063f,0.59375f, +0.421875f,0.59375f, +0.429688f,0.59375f, +0.4375f,0.59375f, +0.445313f,0.59375f, +0.453125f,0.59375f, +0.460938f,0.59375f, +0.46875f,0.59375f, +0.476563f,0.59375f, +0.484375f,0.59375f, +0.492188f,0.59375f, +0.5f,0.59375f, +0.507813f,0.59375f, +0.0f,0.601563f, +0.0078125f,0.601563f, +0.015625f,0.601563f, +0.0234375f,0.601563f, +0.03125f,0.601563f, +0.0390625f,0.601563f, +0.046875f,0.601563f, +0.0546875f,0.601563f, +0.0625f,0.601563f, +0.0703125f,0.601563f, +0.078125f,0.601563f, +0.0859375f,0.601563f, +0.09375f,0.601563f, +0.101563f,0.601563f, +0.109375f,0.601563f, +0.117188f,0.601563f, +0.125f,0.601563f, +0.132813f,0.601563f, +0.140625f,0.601563f, +0.148438f,0.601563f, +0.15625f,0.601563f, +0.164063f,0.601563f, +0.171875f,0.601563f, +0.179688f,0.601563f, +0.1875f,0.601563f, +0.195313f,0.601563f, +0.203125f,0.601563f, +0.210938f,0.601563f, +0.21875f,0.601563f, +0.226563f,0.601563f, +0.234375f,0.601563f, +0.242188f,0.601563f, +0.25f,0.601563f, +0.257813f,0.601563f, +0.265625f,0.601563f, +0.273438f,0.601563f, +0.28125f,0.601563f, +0.289063f,0.601563f, +0.296875f,0.601563f, +0.304688f,0.601563f, +0.3125f,0.601563f, +0.320313f,0.601563f, +0.328125f,0.601563f, +0.335938f,0.601563f, +0.34375f,0.601563f, +0.351563f,0.601563f, +0.359375f,0.601563f, +0.367188f,0.601563f, +0.375f,0.601563f, +0.382813f,0.601563f, +0.390625f,0.601563f, +0.398438f,0.601563f, +0.40625f,0.601563f, +0.414063f,0.601563f, +0.421875f,0.601563f, +0.429688f,0.601563f, +0.4375f,0.601563f, +0.445313f,0.601563f, +0.453125f,0.601563f, +0.460938f,0.601563f, +0.46875f,0.601563f, +0.476563f,0.601563f, +0.484375f,0.601563f, +0.492188f,0.601563f, +0.5f,0.601563f, +0.507813f,0.601563f, +0.0f,0.609375f, +0.0078125f,0.609375f, +0.015625f,0.609375f, +0.0234375f,0.609375f, +0.03125f,0.609375f, +0.0390625f,0.609375f, +0.046875f,0.609375f, +0.0546875f,0.609375f, +0.0625f,0.609375f, +0.0703125f,0.609375f, +0.078125f,0.609375f, +0.0859375f,0.609375f, +0.09375f,0.609375f, +0.101563f,0.609375f, +0.109375f,0.609375f, +0.117188f,0.609375f, +0.125f,0.609375f, +0.132813f,0.609375f, +0.140625f,0.609375f, +0.148438f,0.609375f, +0.15625f,0.609375f, +0.164063f,0.609375f, +0.171875f,0.609375f, +0.179688f,0.609375f, +0.1875f,0.609375f, +0.195313f,0.609375f, +0.203125f,0.609375f, +0.210938f,0.609375f, +0.21875f,0.609375f, +0.226563f,0.609375f, +0.234375f,0.609375f, +0.242188f,0.609375f, +0.25f,0.609375f, +0.257813f,0.609375f, +0.265625f,0.609375f, +0.273438f,0.609375f, +0.28125f,0.609375f, +0.289063f,0.609375f, +0.296875f,0.609375f, +0.304688f,0.609375f, +0.3125f,0.609375f, +0.320313f,0.609375f, +0.328125f,0.609375f, +0.335938f,0.609375f, +0.34375f,0.609375f, +0.351563f,0.609375f, +0.359375f,0.609375f, +0.367188f,0.609375f, +0.375f,0.609375f, +0.382813f,0.609375f, +0.390625f,0.609375f, +0.398438f,0.609375f, +0.40625f,0.609375f, +0.414063f,0.609375f, +0.421875f,0.609375f, +0.429688f,0.609375f, +0.4375f,0.609375f, +0.445313f,0.609375f, +0.453125f,0.609375f, +0.460938f,0.609375f, +0.46875f,0.609375f, +0.476563f,0.609375f, +0.484375f,0.609375f, +0.492188f,0.609375f, +0.5f,0.609375f, +0.507813f,0.609375f, +0.0f,0.617188f, +0.0078125f,0.617188f, +0.015625f,0.617188f, +0.0234375f,0.617188f, +0.03125f,0.617188f, +0.0390625f,0.617188f, +0.046875f,0.617188f, +0.0546875f,0.617188f, +0.0625f,0.617188f, +0.0703125f,0.617188f, +0.078125f,0.617188f, +0.0859375f,0.617188f, +0.09375f,0.617188f, +0.101563f,0.617188f, +0.109375f,0.617188f, +0.117188f,0.617188f, +0.125f,0.617188f, +0.132813f,0.617188f, +0.140625f,0.617188f, +0.148438f,0.617188f, +0.15625f,0.617188f, +0.164063f,0.617188f, +0.171875f,0.617188f, +0.179688f,0.617188f, +0.1875f,0.617188f, +0.195313f,0.617188f, +0.203125f,0.617188f, +0.210938f,0.617188f, +0.21875f,0.617188f, +0.226563f,0.617188f, +0.234375f,0.617188f, +0.242188f,0.617188f, +0.25f,0.617188f, +0.257813f,0.617188f, +0.265625f,0.617188f, +0.273438f,0.617188f, +0.28125f,0.617188f, +0.289063f,0.617188f, +0.296875f,0.617188f, +0.304688f,0.617188f, +0.3125f,0.617188f, +0.320313f,0.617188f, +0.328125f,0.617188f, +0.335938f,0.617188f, +0.34375f,0.617188f, +0.351563f,0.617188f, +0.359375f,0.617188f, +0.367188f,0.617188f, +0.375f,0.617188f, +0.382813f,0.617188f, +0.390625f,0.617188f, +0.398438f,0.617188f, +0.40625f,0.617188f, +0.414063f,0.617188f, +0.421875f,0.617188f, +0.429688f,0.617188f, +0.4375f,0.617188f, +0.445313f,0.617188f, +0.453125f,0.617188f, +0.460938f,0.617188f, +0.46875f,0.617188f, +0.476563f,0.617188f, +0.484375f,0.617188f, +0.492188f,0.617188f, +0.5f,0.617188f, +0.507813f,0.617188f, +0.0f,0.625f, +0.0078125f,0.625f, +0.015625f,0.625f, +0.0234375f,0.625f, +0.03125f,0.625f, +0.0390625f,0.625f, +0.046875f,0.625f, +0.0546875f,0.625f, +0.0625f,0.625f, +0.0703125f,0.625f, +0.078125f,0.625f, +0.0859375f,0.625f, +0.09375f,0.625f, +0.101563f,0.625f, +0.109375f,0.625f, +0.117188f,0.625f, +0.125f,0.625f, +0.132813f,0.625f, +0.140625f,0.625f, +0.148438f,0.625f, +0.15625f,0.625f, +0.164063f,0.625f, +0.171875f,0.625f, +0.179688f,0.625f, +0.1875f,0.625f, +0.195313f,0.625f, +0.203125f,0.625f, +0.210938f,0.625f, +0.21875f,0.625f, +0.226563f,0.625f, +0.234375f,0.625f, +0.242188f,0.625f, +0.25f,0.625f, +0.257813f,0.625f, +0.265625f,0.625f, +0.273438f,0.625f, +0.28125f,0.625f, +0.289063f,0.625f, +0.296875f,0.625f, +0.304688f,0.625f, +0.3125f,0.625f, +0.320313f,0.625f, +0.328125f,0.625f, +0.335938f,0.625f, +0.34375f,0.625f, +0.351563f,0.625f, +0.359375f,0.625f, +0.367188f,0.625f, +0.375f,0.625f, +0.382813f,0.625f, +0.390625f,0.625f, +0.398438f,0.625f, +0.40625f,0.625f, +0.414063f,0.625f, +0.421875f,0.625f, +0.429688f,0.625f, +0.4375f,0.625f, +0.445313f,0.625f, +0.453125f,0.625f, +0.460938f,0.625f, +0.46875f,0.625f, +0.476563f,0.625f, +0.484375f,0.625f, +0.492188f,0.625f, +0.5f,0.625f, +0.507813f,0.625f, +0.0f,0.632813f, +0.0078125f,0.632813f, +0.015625f,0.632813f, +0.0234375f,0.632813f, +0.03125f,0.632813f, +0.0390625f,0.632813f, +0.046875f,0.632813f, +0.0546875f,0.632813f, +0.0625f,0.632813f, +0.0703125f,0.632813f, +0.078125f,0.632813f, +0.0859375f,0.632813f, +0.09375f,0.632813f, +0.101563f,0.632813f, +0.109375f,0.632813f, +0.117188f,0.632813f, +0.125f,0.632813f, +0.132813f,0.632813f, +0.140625f,0.632813f, +0.148438f,0.632813f, +0.15625f,0.632813f, +0.164063f,0.632813f, +0.171875f,0.632813f, +0.179688f,0.632813f, +0.1875f,0.632813f, +0.195313f,0.632813f, +0.203125f,0.632813f, +0.210938f,0.632813f, +0.21875f,0.632813f, +0.226563f,0.632813f, +0.234375f,0.632813f, +0.242188f,0.632813f, +0.25f,0.632813f, +0.257813f,0.632813f, +0.265625f,0.632813f, +0.273438f,0.632813f, +0.28125f,0.632813f, +0.289063f,0.632813f, +0.296875f,0.632813f, +0.304688f,0.632813f, +0.3125f,0.632813f, +0.320313f,0.632813f, +0.328125f,0.632813f, +0.335938f,0.632813f, +0.34375f,0.632813f, +0.351563f,0.632813f, +0.359375f,0.632813f, +0.367188f,0.632813f, +0.375f,0.632813f, +0.382813f,0.632813f, +0.390625f,0.632813f, +0.398438f,0.632813f, +0.40625f,0.632813f, +0.414063f,0.632813f, +0.421875f,0.632813f, +0.429688f,0.632813f, +0.4375f,0.632813f, +0.445313f,0.632813f, +0.453125f,0.632813f, +0.460938f,0.632813f, +0.46875f,0.632813f, +0.476563f,0.632813f, +0.484375f,0.632813f, +0.492188f,0.632813f, +0.5f,0.632813f, +0.507813f,0.632813f, +0.0f,0.640625f, +0.0078125f,0.640625f, +0.015625f,0.640625f, +0.0234375f,0.640625f, +0.03125f,0.640625f, +0.0390625f,0.640625f, +0.046875f,0.640625f, +0.0546875f,0.640625f, +0.0625f,0.640625f, +0.0703125f,0.640625f, +0.078125f,0.640625f, +0.0859375f,0.640625f, +0.09375f,0.640625f, +0.101563f,0.640625f, +0.109375f,0.640625f, +0.117188f,0.640625f, +0.125f,0.640625f, +0.132813f,0.640625f, +0.140625f,0.640625f, +0.148438f,0.640625f, +0.15625f,0.640625f, +0.164063f,0.640625f, +0.171875f,0.640625f, +0.179688f,0.640625f, +0.1875f,0.640625f, +0.195313f,0.640625f, +0.203125f,0.640625f, +0.210938f,0.640625f, +0.21875f,0.640625f, +0.226563f,0.640625f, +0.234375f,0.640625f, +0.242188f,0.640625f, +0.25f,0.640625f, +0.257813f,0.640625f, +0.265625f,0.640625f, +0.273438f,0.640625f, +0.28125f,0.640625f, +0.289063f,0.640625f, +0.296875f,0.640625f, +0.304688f,0.640625f, +0.3125f,0.640625f, +0.320313f,0.640625f, +0.328125f,0.640625f, +0.335938f,0.640625f, +0.34375f,0.640625f, +0.351563f,0.640625f, +0.359375f,0.640625f, +0.367188f,0.640625f, +0.375f,0.640625f, +0.382813f,0.640625f, +0.390625f,0.640625f, +0.398438f,0.640625f, +0.40625f,0.640625f, +0.414063f,0.640625f, +0.421875f,0.640625f, +0.429688f,0.640625f, +0.4375f,0.640625f, +0.445313f,0.640625f, +0.453125f,0.640625f, +0.460938f,0.640625f, +0.46875f,0.640625f, +0.476563f,0.640625f, +0.484375f,0.640625f, +0.492188f,0.640625f, +0.5f,0.640625f, +0.507813f,0.640625f, +0.0f,0.648438f, +0.0078125f,0.648438f, +0.015625f,0.648438f, +0.0234375f,0.648438f, +0.03125f,0.648438f, +0.0390625f,0.648438f, +0.046875f,0.648438f, +0.0546875f,0.648438f, +0.0625f,0.648438f, +0.0703125f,0.648438f, +0.078125f,0.648438f, +0.0859375f,0.648438f, +0.09375f,0.648438f, +0.101563f,0.648438f, +0.109375f,0.648438f, +0.117188f,0.648438f, +0.125f,0.648438f, +0.132813f,0.648438f, +0.140625f,0.648438f, +0.148438f,0.648438f, +0.15625f,0.648438f, +0.164063f,0.648438f, +0.171875f,0.648438f, +0.179688f,0.648438f, +0.1875f,0.648438f, +0.195313f,0.648438f, +0.203125f,0.648438f, +0.210938f,0.648438f, +0.21875f,0.648438f, +0.226563f,0.648438f, +0.234375f,0.648438f, +0.242188f,0.648438f, +0.25f,0.648438f, +0.257813f,0.648438f, +0.265625f,0.648438f, +0.273438f,0.648438f, +0.28125f,0.648438f, +0.289063f,0.648438f, +0.296875f,0.648438f, +0.304688f,0.648438f, +0.3125f,0.648438f, +0.320313f,0.648438f, +0.328125f,0.648438f, +0.335938f,0.648438f, +0.34375f,0.648438f, +0.351563f,0.648438f, +0.359375f,0.648438f, +0.367188f,0.648438f, +0.375f,0.648438f, +0.382813f,0.648438f, +0.390625f,0.648438f, +0.398438f,0.648438f, +0.40625f,0.648438f, +0.414063f,0.648438f, +0.421875f,0.648438f, +0.429688f,0.648438f, +0.4375f,0.648438f, +0.445313f,0.648438f, +0.453125f,0.648438f, +0.460938f,0.648438f, +0.46875f,0.648438f, +0.476563f,0.648438f, +0.484375f,0.648438f, +0.492188f,0.648438f, +0.5f,0.648438f, +0.507813f,0.648438f, +0.0f,0.65625f, +0.0078125f,0.65625f, +0.015625f,0.65625f, +0.0234375f,0.65625f, +0.03125f,0.65625f, +0.0390625f,0.65625f, +0.046875f,0.65625f, +0.0546875f,0.65625f, +0.0625f,0.65625f, +0.0703125f,0.65625f, +0.078125f,0.65625f, +0.0859375f,0.65625f, +0.09375f,0.65625f, +0.101563f,0.65625f, +0.109375f,0.65625f, +0.117188f,0.65625f, +0.125f,0.65625f, +0.132813f,0.65625f, +0.140625f,0.65625f, +0.148438f,0.65625f, +0.15625f,0.65625f, +0.164063f,0.65625f, +0.171875f,0.65625f, +0.179688f,0.65625f, +0.1875f,0.65625f, +0.195313f,0.65625f, +0.203125f,0.65625f, +0.210938f,0.65625f, +0.21875f,0.65625f, +0.226563f,0.65625f, +0.234375f,0.65625f, +0.242188f,0.65625f, +0.25f,0.65625f, +0.257813f,0.65625f, +0.265625f,0.65625f, +0.273438f,0.65625f, +0.28125f,0.65625f, +0.289063f,0.65625f, +0.296875f,0.65625f, +0.304688f,0.65625f, +0.3125f,0.65625f, +0.320313f,0.65625f, +0.328125f,0.65625f, +0.335938f,0.65625f, +0.34375f,0.65625f, +0.351563f,0.65625f, +0.359375f,0.65625f, +0.367188f,0.65625f, +0.375f,0.65625f, +0.382813f,0.65625f, +0.390625f,0.65625f, +0.398438f,0.65625f, +0.40625f,0.65625f, +0.414063f,0.65625f, +0.421875f,0.65625f, +0.429688f,0.65625f, +0.4375f,0.65625f, +0.445313f,0.65625f, +0.453125f,0.65625f, +0.460938f,0.65625f, +0.46875f,0.65625f, +0.476563f,0.65625f, +0.484375f,0.65625f, +0.492188f,0.65625f, +0.5f,0.65625f, +0.507813f,0.65625f, +0.0f,0.664063f, +0.0078125f,0.664063f, +0.015625f,0.664063f, +0.0234375f,0.664063f, +0.03125f,0.664063f, +0.0390625f,0.664063f, +0.046875f,0.664063f, +0.0546875f,0.664063f, +0.0625f,0.664063f, +0.0703125f,0.664063f, +0.078125f,0.664063f, +0.0859375f,0.664063f, +0.09375f,0.664063f, +0.101563f,0.664063f, +0.109375f,0.664063f, +0.117188f,0.664063f, +0.125f,0.664063f, +0.132813f,0.664063f, +0.140625f,0.664063f, +0.148438f,0.664063f, +0.15625f,0.664063f, +0.164063f,0.664063f, +0.171875f,0.664063f, +0.179688f,0.664063f, +0.1875f,0.664063f, +0.195313f,0.664063f, +0.203125f,0.664063f, +0.210938f,0.664063f, +0.21875f,0.664063f, +0.226563f,0.664063f, +0.234375f,0.664063f, +0.242188f,0.664063f, +0.25f,0.664063f, +0.257813f,0.664063f, +0.265625f,0.664063f, +0.273438f,0.664063f, +0.28125f,0.664063f, +0.289063f,0.664063f, +0.296875f,0.664063f, +0.304688f,0.664063f, +0.3125f,0.664063f, +0.320313f,0.664063f, +0.328125f,0.664063f, +0.335938f,0.664063f, +0.34375f,0.664063f, +0.351563f,0.664063f, +0.359375f,0.664063f, +0.367188f,0.664063f, +0.375f,0.664063f, +0.382813f,0.664063f, +0.390625f,0.664063f, +0.398438f,0.664063f, +0.40625f,0.664063f, +0.414063f,0.664063f, +0.421875f,0.664063f, +0.429688f,0.664063f, +0.4375f,0.664063f, +0.445313f,0.664063f, +0.453125f,0.664063f, +0.460938f,0.664063f, +0.46875f,0.664063f, +0.476563f,0.664063f, +0.484375f,0.664063f, +0.492188f,0.664063f, +0.5f,0.664063f, +0.507813f,0.664063f, +0.0f,0.671875f, +0.0078125f,0.671875f, +0.015625f,0.671875f, +0.0234375f,0.671875f, +0.03125f,0.671875f, +0.0390625f,0.671875f, +0.046875f,0.671875f, +0.0546875f,0.671875f, +0.0625f,0.671875f, +0.0703125f,0.671875f, +0.078125f,0.671875f, +0.0859375f,0.671875f, +0.09375f,0.671875f, +0.101563f,0.671875f, +0.109375f,0.671875f, +0.117188f,0.671875f, +0.125f,0.671875f, +0.132813f,0.671875f, +0.140625f,0.671875f, +0.148438f,0.671875f, +0.15625f,0.671875f, +0.164063f,0.671875f, +0.171875f,0.671875f, +0.179688f,0.671875f, +0.1875f,0.671875f, +0.195313f,0.671875f, +0.203125f,0.671875f, +0.210938f,0.671875f, +0.21875f,0.671875f, +0.226563f,0.671875f, +0.234375f,0.671875f, +0.242188f,0.671875f, +0.25f,0.671875f, +0.257813f,0.671875f, +0.265625f,0.671875f, +0.273438f,0.671875f, +0.28125f,0.671875f, +0.289063f,0.671875f, +0.296875f,0.671875f, +0.304688f,0.671875f, +0.3125f,0.671875f, +0.320313f,0.671875f, +0.328125f,0.671875f, +0.335938f,0.671875f, +0.34375f,0.671875f, +0.351563f,0.671875f, +0.359375f,0.671875f, +0.367188f,0.671875f, +0.375f,0.671875f, +0.382813f,0.671875f, +0.390625f,0.671875f, +0.398438f,0.671875f, +0.40625f,0.671875f, +0.414063f,0.671875f, +0.421875f,0.671875f, +0.429688f,0.671875f, +0.4375f,0.671875f, +0.445313f,0.671875f, +0.453125f,0.671875f, +0.460938f,0.671875f, +0.46875f,0.671875f, +0.476563f,0.671875f, +0.484375f,0.671875f, +0.492188f,0.671875f, +0.5f,0.671875f, +0.507813f,0.671875f, +0.0f,0.679688f, +0.0078125f,0.679688f, +0.015625f,0.679688f, +0.0234375f,0.679688f, +0.03125f,0.679688f, +0.0390625f,0.679688f, +0.046875f,0.679688f, +0.0546875f,0.679688f, +0.0625f,0.679688f, +0.0703125f,0.679688f, +0.078125f,0.679688f, +0.0859375f,0.679688f, +0.09375f,0.679688f, +0.101563f,0.679688f, +0.109375f,0.679688f, +0.117188f,0.679688f, +0.125f,0.679688f, +0.132813f,0.679688f, +0.140625f,0.679688f, +0.148438f,0.679688f, +0.15625f,0.679688f, +0.164063f,0.679688f, +0.171875f,0.679688f, +0.179688f,0.679688f, +0.1875f,0.679688f, +0.195313f,0.679688f, +0.203125f,0.679688f, +0.210938f,0.679688f, +0.21875f,0.679688f, +0.226563f,0.679688f, +0.234375f,0.679688f, +0.242188f,0.679688f, +0.25f,0.679688f, +0.257813f,0.679688f, +0.265625f,0.679688f, +0.273438f,0.679688f, +0.28125f,0.679688f, +0.289063f,0.679688f, +0.296875f,0.679688f, +0.304688f,0.679688f, +0.3125f,0.679688f, +0.320313f,0.679688f, +0.328125f,0.679688f, +0.335938f,0.679688f, +0.34375f,0.679688f, +0.351563f,0.679688f, +0.359375f,0.679688f, +0.367188f,0.679688f, +0.375f,0.679688f, +0.382813f,0.679688f, +0.390625f,0.679688f, +0.398438f,0.679688f, +0.40625f,0.679688f, +0.414063f,0.679688f, +0.421875f,0.679688f, +0.429688f,0.679688f, +0.4375f,0.679688f, +0.445313f,0.679688f, +0.453125f,0.679688f, +0.460938f,0.679688f, +0.46875f,0.679688f, +0.476563f,0.679688f, +0.484375f,0.679688f, +0.492188f,0.679688f, +0.5f,0.679688f, +0.507813f,0.679688f, +0.0f,0.6875f, +0.0078125f,0.6875f, +0.015625f,0.6875f, +0.0234375f,0.6875f, +0.03125f,0.6875f, +0.0390625f,0.6875f, +0.046875f,0.6875f, +0.0546875f,0.6875f, +0.0625f,0.6875f, +0.0703125f,0.6875f, +0.078125f,0.6875f, +0.0859375f,0.6875f, +0.09375f,0.6875f, +0.101563f,0.6875f, +0.109375f,0.6875f, +0.117188f,0.6875f, +0.125f,0.6875f, +0.132813f,0.6875f, +0.140625f,0.6875f, +0.148438f,0.6875f, +0.15625f,0.6875f, +0.164063f,0.6875f, +0.171875f,0.6875f, +0.179688f,0.6875f, +0.1875f,0.6875f, +0.195313f,0.6875f, +0.203125f,0.6875f, +0.210938f,0.6875f, +0.21875f,0.6875f, +0.226563f,0.6875f, +0.234375f,0.6875f, +0.242188f,0.6875f, +0.25f,0.6875f, +0.257813f,0.6875f, +0.265625f,0.6875f, +0.273438f,0.6875f, +0.28125f,0.6875f, +0.289063f,0.6875f, +0.296875f,0.6875f, +0.304688f,0.6875f, +0.3125f,0.6875f, +0.320313f,0.6875f, +0.328125f,0.6875f, +0.335938f,0.6875f, +0.34375f,0.6875f, +0.351563f,0.6875f, +0.359375f,0.6875f, +0.367188f,0.6875f, +0.375f,0.6875f, +0.382813f,0.6875f, +0.390625f,0.6875f, +0.398438f,0.6875f, +0.40625f,0.6875f, +0.414063f,0.6875f, +0.421875f,0.6875f, +0.429688f,0.6875f, +0.4375f,0.6875f, +0.445313f,0.6875f, +0.453125f,0.6875f, +0.460938f,0.6875f, +0.46875f,0.6875f, +0.476563f,0.6875f, +0.484375f,0.6875f, +0.492188f,0.6875f, +0.5f,0.6875f, +0.507813f,0.6875f, +0.0f,0.695313f, +0.0078125f,0.695313f, +0.015625f,0.695313f, +0.0234375f,0.695313f, +0.03125f,0.695313f, +0.0390625f,0.695313f, +0.046875f,0.695313f, +0.0546875f,0.695313f, +0.0625f,0.695313f, +0.0703125f,0.695313f, +0.078125f,0.695313f, +0.0859375f,0.695313f, +0.09375f,0.695313f, +0.101563f,0.695313f, +0.109375f,0.695313f, +0.117188f,0.695313f, +0.125f,0.695313f, +0.132813f,0.695313f, +0.140625f,0.695313f, +0.148438f,0.695313f, +0.15625f,0.695313f, +0.164063f,0.695313f, +0.171875f,0.695313f, +0.179688f,0.695313f, +0.1875f,0.695313f, +0.195313f,0.695313f, +0.203125f,0.695313f, +0.210938f,0.695313f, +0.21875f,0.695313f, +0.226563f,0.695313f, +0.234375f,0.695313f, +0.242188f,0.695313f, +0.25f,0.695313f, +0.257813f,0.695313f, +0.265625f,0.695313f, +0.273438f,0.695313f, +0.28125f,0.695313f, +0.289063f,0.695313f, +0.296875f,0.695313f, +0.304688f,0.695313f, +0.3125f,0.695313f, +0.320313f,0.695313f, +0.328125f,0.695313f, +0.335938f,0.695313f, +0.34375f,0.695313f, +0.351563f,0.695313f, +0.359375f,0.695313f, +0.367188f,0.695313f, +0.375f,0.695313f, +0.382813f,0.695313f, +0.390625f,0.695313f, +0.398438f,0.695313f, +0.40625f,0.695313f, +0.414063f,0.695313f, +0.421875f,0.695313f, +0.429688f,0.695313f, +0.4375f,0.695313f, +0.445313f,0.695313f, +0.453125f,0.695313f, +0.460938f,0.695313f, +0.46875f,0.695313f, +0.476563f,0.695313f, +0.484375f,0.695313f, +0.492188f,0.695313f, +0.5f,0.695313f, +0.507813f,0.695313f, +0.0f,0.703125f, +0.0078125f,0.703125f, +0.015625f,0.703125f, +0.0234375f,0.703125f, +0.03125f,0.703125f, +0.0390625f,0.703125f, +0.046875f,0.703125f, +0.0546875f,0.703125f, +0.0625f,0.703125f, +0.0703125f,0.703125f, +0.078125f,0.703125f, +0.0859375f,0.703125f, +0.09375f,0.703125f, +0.101563f,0.703125f, +0.109375f,0.703125f, +0.117188f,0.703125f, +0.125f,0.703125f, +0.132813f,0.703125f, +0.140625f,0.703125f, +0.148438f,0.703125f, +0.15625f,0.703125f, +0.164063f,0.703125f, +0.171875f,0.703125f, +0.179688f,0.703125f, +0.1875f,0.703125f, +0.195313f,0.703125f, +0.203125f,0.703125f, +0.210938f,0.703125f, +0.21875f,0.703125f, +0.226563f,0.703125f, +0.234375f,0.703125f, +0.242188f,0.703125f, +0.25f,0.703125f, +0.257813f,0.703125f, +0.265625f,0.703125f, +0.273438f,0.703125f, +0.28125f,0.703125f, +0.289063f,0.703125f, +0.296875f,0.703125f, +0.304688f,0.703125f, +0.3125f,0.703125f, +0.320313f,0.703125f, +0.328125f,0.703125f, +0.335938f,0.703125f, +0.34375f,0.703125f, +0.351563f,0.703125f, +0.359375f,0.703125f, +0.367188f,0.703125f, +0.375f,0.703125f, +0.382813f,0.703125f, +0.390625f,0.703125f, +0.398438f,0.703125f, +0.40625f,0.703125f, +0.414063f,0.703125f, +0.421875f,0.703125f, +0.429688f,0.703125f, +0.4375f,0.703125f, +0.445313f,0.703125f, +0.453125f,0.703125f, +0.460938f,0.703125f, +0.46875f,0.703125f, +0.476563f,0.703125f, +0.484375f,0.703125f, +0.492188f,0.703125f, +0.5f,0.703125f, +0.507813f,0.703125f, +0.0f,0.710938f, +0.0078125f,0.710938f, +0.015625f,0.710938f, +0.0234375f,0.710938f, +0.03125f,0.710938f, +0.0390625f,0.710938f, +0.046875f,0.710938f, +0.0546875f,0.710938f, +0.0625f,0.710938f, +0.0703125f,0.710938f, +0.078125f,0.710938f, +0.0859375f,0.710938f, +0.09375f,0.710938f, +0.101563f,0.710938f, +0.109375f,0.710938f, +0.117188f,0.710938f, +0.125f,0.710938f, +0.132813f,0.710938f, +0.140625f,0.710938f, +0.148438f,0.710938f, +0.15625f,0.710938f, +0.164063f,0.710938f, +0.171875f,0.710938f, +0.179688f,0.710938f, +0.1875f,0.710938f, +0.195313f,0.710938f, +0.203125f,0.710938f, +0.210938f,0.710938f, +0.21875f,0.710938f, +0.226563f,0.710938f, +0.234375f,0.710938f, +0.242188f,0.710938f, +0.25f,0.710938f, +0.257813f,0.710938f, +0.265625f,0.710938f, +0.273438f,0.710938f, +0.28125f,0.710938f, +0.289063f,0.710938f, +0.296875f,0.710938f, +0.304688f,0.710938f, +0.3125f,0.710938f, +0.320313f,0.710938f, +0.328125f,0.710938f, +0.335938f,0.710938f, +0.34375f,0.710938f, +0.351563f,0.710938f, +0.359375f,0.710938f, +0.367188f,0.710938f, +0.375f,0.710938f, +0.382813f,0.710938f, +0.390625f,0.710938f, +0.398438f,0.710938f, +0.40625f,0.710938f, +0.414063f,0.710938f, +0.421875f,0.710938f, +0.429688f,0.710938f, +0.4375f,0.710938f, +0.445313f,0.710938f, +0.453125f,0.710938f, +0.460938f,0.710938f, +0.46875f,0.710938f, +0.476563f,0.710938f, +0.484375f,0.710938f, +0.492188f,0.710938f, +0.5f,0.710938f, +0.507813f,0.710938f, +0.0f,0.71875f, +0.0078125f,0.71875f, +0.015625f,0.71875f, +0.0234375f,0.71875f, +0.03125f,0.71875f, +0.0390625f,0.71875f, +0.046875f,0.71875f, +0.0546875f,0.71875f, +0.0625f,0.71875f, +0.0703125f,0.71875f, +0.078125f,0.71875f, +0.0859375f,0.71875f, +0.09375f,0.71875f, +0.101563f,0.71875f, +0.109375f,0.71875f, +0.117188f,0.71875f, +0.125f,0.71875f, +0.132813f,0.71875f, +0.140625f,0.71875f, +0.148438f,0.71875f, +0.15625f,0.71875f, +0.164063f,0.71875f, +0.171875f,0.71875f, +0.179688f,0.71875f, +0.1875f,0.71875f, +0.195313f,0.71875f, +0.203125f,0.71875f, +0.210938f,0.71875f, +0.21875f,0.71875f, +0.226563f,0.71875f, +0.234375f,0.71875f, +0.242188f,0.71875f, +0.25f,0.71875f, +0.257813f,0.71875f, +0.265625f,0.71875f, +0.273438f,0.71875f, +0.28125f,0.71875f, +0.289063f,0.71875f, +0.296875f,0.71875f, +0.304688f,0.71875f, +0.3125f,0.71875f, +0.320313f,0.71875f, +0.328125f,0.71875f, +0.335938f,0.71875f, +0.34375f,0.71875f, +0.351563f,0.71875f, +0.359375f,0.71875f, +0.367188f,0.71875f, +0.375f,0.71875f, +0.382813f,0.71875f, +0.390625f,0.71875f, +0.398438f,0.71875f, +0.40625f,0.71875f, +0.414063f,0.71875f, +0.421875f,0.71875f, +0.429688f,0.71875f, +0.4375f,0.71875f, +0.445313f,0.71875f, +0.453125f,0.71875f, +0.460938f,0.71875f, +0.46875f,0.71875f, +0.476563f,0.71875f, +0.484375f,0.71875f, +0.492188f,0.71875f, +0.5f,0.71875f, +0.507813f,0.71875f, +0.0f,0.726563f, +0.0078125f,0.726563f, +0.015625f,0.726563f, +0.0234375f,0.726563f, +0.03125f,0.726563f, +0.0390625f,0.726563f, +0.046875f,0.726563f, +0.0546875f,0.726563f, +0.0625f,0.726563f, +0.0703125f,0.726563f, +0.078125f,0.726563f, +0.0859375f,0.726563f, +0.09375f,0.726563f, +0.101563f,0.726563f, +0.109375f,0.726563f, +0.117188f,0.726563f, +0.125f,0.726563f, +0.132813f,0.726563f, +0.140625f,0.726563f, +0.148438f,0.726563f, +0.15625f,0.726563f, +0.164063f,0.726563f, +0.171875f,0.726563f, +0.179688f,0.726563f, +0.1875f,0.726563f, +0.195313f,0.726563f, +0.203125f,0.726563f, +0.210938f,0.726563f, +0.21875f,0.726563f, +0.226563f,0.726563f, +0.234375f,0.726563f, +0.242188f,0.726563f, +0.25f,0.726563f, +0.257813f,0.726563f, +0.265625f,0.726563f, +0.273438f,0.726563f, +0.28125f,0.726563f, +0.289063f,0.726563f, +0.296875f,0.726563f, +0.304688f,0.726563f, +0.3125f,0.726563f, +0.320313f,0.726563f, +0.328125f,0.726563f, +0.335938f,0.726563f, +0.34375f,0.726563f, +0.351563f,0.726563f, +0.359375f,0.726563f, +0.367188f,0.726563f, +0.375f,0.726563f, +0.382813f,0.726563f, +0.390625f,0.726563f, +0.398438f,0.726563f, +0.40625f,0.726563f, +0.414063f,0.726563f, +0.421875f,0.726563f, +0.429688f,0.726563f, +0.4375f,0.726563f, +0.445313f,0.726563f, +0.453125f,0.726563f, +0.460938f,0.726563f, +0.46875f,0.726563f, +0.476563f,0.726563f, +0.484375f,0.726563f, +0.492188f,0.726563f, +0.5f,0.726563f, +0.507813f,0.726563f, +0.0f,0.734375f, +0.0078125f,0.734375f, +0.015625f,0.734375f, +0.0234375f,0.734375f, +0.03125f,0.734375f, +0.0390625f,0.734375f, +0.046875f,0.734375f, +0.0546875f,0.734375f, +0.0625f,0.734375f, +0.0703125f,0.734375f, +0.078125f,0.734375f, +0.0859375f,0.734375f, +0.09375f,0.734375f, +0.101563f,0.734375f, +0.109375f,0.734375f, +0.117188f,0.734375f, +0.125f,0.734375f, +0.132813f,0.734375f, +0.140625f,0.734375f, +0.148438f,0.734375f, +0.15625f,0.734375f, +0.164063f,0.734375f, +0.171875f,0.734375f, +0.179688f,0.734375f, +0.1875f,0.734375f, +0.195313f,0.734375f, +0.203125f,0.734375f, +0.210938f,0.734375f, +0.21875f,0.734375f, +0.226563f,0.734375f, +0.234375f,0.734375f, +0.242188f,0.734375f, +0.25f,0.734375f, +0.257813f,0.734375f, +0.265625f,0.734375f, +0.273438f,0.734375f, +0.28125f,0.734375f, +0.289063f,0.734375f, +0.296875f,0.734375f, +0.304688f,0.734375f, +0.3125f,0.734375f, +0.320313f,0.734375f, +0.328125f,0.734375f, +0.335938f,0.734375f, +0.34375f,0.734375f, +0.351563f,0.734375f, +0.359375f,0.734375f, +0.367188f,0.734375f, +0.375f,0.734375f, +0.382813f,0.734375f, +0.390625f,0.734375f, +0.398438f,0.734375f, +0.40625f,0.734375f, +0.414063f,0.734375f, +0.421875f,0.734375f, +0.429688f,0.734375f, +0.4375f,0.734375f, +0.445313f,0.734375f, +0.453125f,0.734375f, +0.460938f,0.734375f, +0.46875f,0.734375f, +0.476563f,0.734375f, +0.484375f,0.734375f, +0.492188f,0.734375f, +0.5f,0.734375f, +0.507813f,0.734375f, +0.0f,0.742188f, +0.0078125f,0.742188f, +0.015625f,0.742188f, +0.0234375f,0.742188f, +0.03125f,0.742188f, +0.0390625f,0.742188f, +0.046875f,0.742188f, +0.0546875f,0.742188f, +0.0625f,0.742188f, +0.0703125f,0.742188f, +0.078125f,0.742188f, +0.0859375f,0.742188f, +0.09375f,0.742188f, +0.101563f,0.742188f, +0.109375f,0.742188f, +0.117188f,0.742188f, +0.125f,0.742188f, +0.132813f,0.742188f, +0.140625f,0.742188f, +0.148438f,0.742188f, +0.15625f,0.742188f, +0.164063f,0.742188f, +0.171875f,0.742188f, +0.179688f,0.742188f, +0.1875f,0.742188f, +0.195313f,0.742188f, +0.203125f,0.742188f, +0.210938f,0.742188f, +0.21875f,0.742188f, +0.226563f,0.742188f, +0.234375f,0.742188f, +0.242188f,0.742188f, +0.25f,0.742188f, +0.257813f,0.742188f, +0.265625f,0.742188f, +0.273438f,0.742188f, +0.28125f,0.742188f, +0.289063f,0.742188f, +0.296875f,0.742188f, +0.304688f,0.742188f, +0.3125f,0.742188f, +0.320313f,0.742188f, +0.328125f,0.742188f, +0.335938f,0.742188f, +0.34375f,0.742188f, +0.351563f,0.742188f, +0.359375f,0.742188f, +0.367188f,0.742188f, +0.375f,0.742188f, +0.382813f,0.742188f, +0.390625f,0.742188f, +0.398438f,0.742188f, +0.40625f,0.742188f, +0.414063f,0.742188f, +0.421875f,0.742188f, +0.429688f,0.742188f, +0.4375f,0.742188f, +0.445313f,0.742188f, +0.453125f,0.742188f, +0.460938f,0.742188f, +0.46875f,0.742188f, +0.476563f,0.742188f, +0.484375f,0.742188f, +0.492188f,0.742188f, +0.5f,0.742188f, +0.507813f,0.742188f, +0.0f,0.75f, +0.0078125f,0.75f, +0.015625f,0.75f, +0.0234375f,0.75f, +0.03125f,0.75f, +0.0390625f,0.75f, +0.046875f,0.75f, +0.0546875f,0.75f, +0.0625f,0.75f, +0.0703125f,0.75f, +0.078125f,0.75f, +0.0859375f,0.75f, +0.09375f,0.75f, +0.101563f,0.75f, +0.109375f,0.75f, +0.117188f,0.75f, +0.125f,0.75f, +0.132813f,0.75f, +0.140625f,0.75f, +0.148438f,0.75f, +0.15625f,0.75f, +0.164063f,0.75f, +0.171875f,0.75f, +0.179688f,0.75f, +0.1875f,0.75f, +0.195313f,0.75f, +0.203125f,0.75f, +0.210938f,0.75f, +0.21875f,0.75f, +0.226563f,0.75f, +0.234375f,0.75f, +0.242188f,0.75f, +0.25f,0.75f, +0.257813f,0.75f, +0.265625f,0.75f, +0.273438f,0.75f, +0.28125f,0.75f, +0.289063f,0.75f, +0.296875f,0.75f, +0.304688f,0.75f, +0.3125f,0.75f, +0.320313f,0.75f, +0.328125f,0.75f, +0.335938f,0.75f, +0.34375f,0.75f, +0.351563f,0.75f, +0.359375f,0.75f, +0.367188f,0.75f, +0.375f,0.75f, +0.382813f,0.75f, +0.390625f,0.75f, +0.398438f,0.75f, +0.40625f,0.75f, +0.414063f,0.75f, +0.421875f,0.75f, +0.429688f,0.75f, +0.4375f,0.75f, +0.445313f,0.75f, +0.453125f,0.75f, +0.460938f,0.75f, +0.46875f,0.75f, +0.476563f,0.75f, +0.484375f,0.75f, +0.492188f,0.75f, +0.5f,0.75f, +0.507813f,0.75f, +}; + +unsigned short Landscape05Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +126,127,128, +129,128,127, +128,129,130, +131,130,129, +132,0,133, +2,133,0, +133,2,134, +4,134,2, +134,4,135, +6,135,4, +135,6,136, +8,136,6, +136,8,137, +10,137,8, +137,10,138, +12,138,10, +138,12,139, +14,139,12, +139,14,140, +16,140,14, +140,16,141, +18,141,16, +141,18,142, +20,142,18, +142,20,143, +22,143,20, +143,22,144, +24,144,22, +144,24,145, +26,145,24, +145,26,146, +28,146,26, +146,28,147, +30,147,28, +147,30,148, +32,148,30, +148,32,149, +34,149,32, +149,34,150, +36,150,34, +150,36,151, +38,151,36, +151,38,152, +40,152,38, +152,40,153, +42,153,40, +153,42,154, +44,154,42, +154,44,155, +46,155,44, +155,46,156, +48,156,46, +156,48,157, +50,157,48, +157,50,158, +52,158,50, +158,52,159, +54,159,52, +159,54,160, +56,160,54, +160,56,161, +58,161,56, +161,58,162, +60,162,58, +162,60,163, +62,163,60, +163,62,164, +64,164,62, +164,64,165, +66,165,64, +165,66,166, +68,166,66, +166,68,167, +70,167,68, +167,70,168, +72,168,70, +168,72,169, +74,169,72, +169,74,170, +76,170,74, +170,76,171, +78,171,76, +171,78,172, +80,172,78, +172,80,173, +82,173,80, +173,82,174, +84,174,82, +174,84,175, +86,175,84, +175,86,176, +88,176,86, +176,88,177, +90,177,88, +177,90,178, +92,178,90, +178,92,179, +94,179,92, +179,94,180, +96,180,94, +180,96,181, +98,181,96, +181,98,182, +100,182,98, +182,100,183, +102,183,100, +183,102,184, +104,184,102, +184,104,185, +106,185,104, +185,106,186, +108,186,106, +186,108,187, +110,187,108, +187,110,188, +112,188,110, +188,112,189, +114,189,112, +189,114,190, +116,190,114, +190,116,191, +118,191,116, +191,118,192, +120,192,118, +192,120,193, +122,193,120, +193,122,194, +124,194,122, +194,124,195, +126,195,124, +195,126,196, +128,196,126, +196,128,197, +130,197,128, +198,132,199, +133,199,132, +199,133,200, +134,200,133, +200,134,201, +135,201,134, +201,135,202, +136,202,135, +202,136,203, +137,203,136, +203,137,204, +138,204,137, +204,138,205, +139,205,138, +205,139,206, +140,206,139, +206,140,207, +141,207,140, +207,141,208, +142,208,141, +208,142,209, +143,209,142, +209,143,210, +144,210,143, +210,144,211, +145,211,144, +211,145,212, +146,212,145, +212,146,213, +147,213,146, +213,147,214, +148,214,147, +214,148,215, +149,215,148, +215,149,216, +150,216,149, +216,150,217, +151,217,150, +217,151,218, +152,218,151, +218,152,219, +153,219,152, +219,153,220, +154,220,153, +220,154,221, +155,221,154, +221,155,222, +156,222,155, +222,156,223, +157,223,156, +223,157,224, +158,224,157, +224,158,225, +159,225,158, +225,159,226, +160,226,159, +226,160,227, +161,227,160, +227,161,228, +162,228,161, +228,162,229, +163,229,162, +229,163,230, +164,230,163, +230,164,231, +165,231,164, +231,165,232, +166,232,165, +232,166,233, +167,233,166, +233,167,234, +168,234,167, +234,168,235, +169,235,168, +235,169,236, +170,236,169, +236,170,237, +171,237,170, +237,171,238, +172,238,171, +238,172,239, +173,239,172, +239,173,240, +174,240,173, +240,174,241, +175,241,174, +241,175,242, +176,242,175, +242,176,243, +177,243,176, +243,177,244, +178,244,177, +244,178,245, +179,245,178, +245,179,246, +180,246,179, +246,180,247, +181,247,180, +247,181,248, +182,248,181, +248,182,249, +183,249,182, +249,183,250, +184,250,183, +250,184,251, +185,251,184, +251,185,252, +186,252,185, +252,186,253, +187,253,186, +253,187,254, +188,254,187, +254,188,255, +189,255,188, +255,189,256, +190,256,189, +256,190,257, +191,257,190, +257,191,258, +192,258,191, +258,192,259, +193,259,192, +259,193,260, +194,260,193, +260,194,261, +195,261,194, +261,195,262, +196,262,195, +262,196,263, +197,263,196, +264,198,265, +199,265,198, +265,199,266, +200,266,199, +266,200,267, +201,267,200, +267,201,268, +202,268,201, +268,202,269, +203,269,202, +269,203,270, +204,270,203, +270,204,271, +205,271,204, +271,205,272, +206,272,205, +272,206,273, +207,273,206, +273,207,274, +208,274,207, +274,208,275, +209,275,208, +275,209,276, +210,276,209, +276,210,277, +211,277,210, +277,211,278, +212,278,211, +278,212,279, +213,279,212, +279,213,280, +214,280,213, +280,214,281, +215,281,214, +281,215,282, +216,282,215, +282,216,283, +217,283,216, +283,217,284, +218,284,217, +284,218,285, +219,285,218, +285,219,286, +220,286,219, +286,220,287, +221,287,220, +287,221,288, +222,288,221, +288,222,289, +223,289,222, +289,223,290, +224,290,223, +290,224,291, +225,291,224, +291,225,292, +226,292,225, +292,226,293, +227,293,226, +293,227,294, +228,294,227, +294,228,295, +229,295,228, +295,229,296, +230,296,229, +296,230,297, +231,297,230, +297,231,298, +232,298,231, +298,232,299, +233,299,232, +299,233,300, +234,300,233, +300,234,301, +235,301,234, +301,235,302, +236,302,235, +302,236,303, +237,303,236, +303,237,304, +238,304,237, +304,238,305, +239,305,238, +305,239,306, +240,306,239, +306,240,307, +241,307,240, +307,241,308, +242,308,241, +308,242,309, +243,309,242, +309,243,310, +244,310,243, +310,244,311, +245,311,244, +311,245,312, +246,312,245, +312,246,313, +247,313,246, +313,247,314, +248,314,247, +314,248,315, +249,315,248, +315,249,316, +250,316,249, +316,250,317, +251,317,250, +317,251,318, +252,318,251, +318,252,319, +253,319,252, +319,253,320, +254,320,253, +320,254,321, +255,321,254, +321,255,322, +256,322,255, +322,256,323, +257,323,256, +323,257,324, +258,324,257, +324,258,325, +259,325,258, +325,259,326, +260,326,259, +326,260,327, +261,327,260, +327,261,328, +262,328,261, +328,262,329, +263,329,262, +330,264,331, +265,331,264, +331,265,332, +266,332,265, +332,266,333, +267,333,266, +333,267,334, +268,334,267, +334,268,335, +269,335,268, +335,269,336, +270,336,269, +336,270,337, +271,337,270, +337,271,338, +272,338,271, +338,272,339, +273,339,272, +339,273,340, +274,340,273, +340,274,341, +275,341,274, +341,275,342, +276,342,275, +342,276,343, +277,343,276, +343,277,344, +278,344,277, +344,278,345, +279,345,278, +345,279,346, +280,346,279, +346,280,347, +281,347,280, +347,281,348, +282,348,281, +348,282,349, +283,349,282, +349,283,350, +284,350,283, +350,284,351, +285,351,284, +351,285,352, +286,352,285, +352,286,353, +287,353,286, +353,287,354, +288,354,287, +354,288,355, +289,355,288, +355,289,356, +290,356,289, +356,290,357, +291,357,290, +357,291,358, +292,358,291, +358,292,359, +293,359,292, +359,293,360, +294,360,293, +360,294,361, +295,361,294, +361,295,362, +296,362,295, +362,296,363, +297,363,296, +363,297,364, +298,364,297, +364,298,365, +299,365,298, +365,299,366, +300,366,299, +366,300,367, +301,367,300, +367,301,368, +302,368,301, +368,302,369, +303,369,302, +369,303,370, +304,370,303, +370,304,371, +305,371,304, +371,305,372, +306,372,305, +372,306,373, +307,373,306, +373,307,374, +308,374,307, +374,308,375, +309,375,308, +375,309,376, +310,376,309, +376,310,377, +311,377,310, +377,311,378, +312,378,311, +378,312,379, +313,379,312, +379,313,380, +314,380,313, +380,314,381, +315,381,314, +381,315,382, +316,382,315, +382,316,383, +317,383,316, +383,317,384, +318,384,317, +384,318,385, +319,385,318, +385,319,386, +320,386,319, +386,320,387, +321,387,320, +387,321,388, +322,388,321, +388,322,389, +323,389,322, +389,323,390, +324,390,323, +390,324,391, +325,391,324, +391,325,392, +326,392,325, +392,326,393, +327,393,326, +393,327,394, +328,394,327, +394,328,395, +329,395,328, +396,330,397, +331,397,330, +397,331,398, +332,398,331, +398,332,399, +333,399,332, +399,333,400, +334,400,333, +400,334,401, +335,401,334, +401,335,402, +336,402,335, +402,336,403, +337,403,336, +403,337,404, +338,404,337, +404,338,405, +339,405,338, +405,339,406, +340,406,339, +406,340,407, +341,407,340, +407,341,408, +342,408,341, +408,342,409, +343,409,342, +409,343,410, +344,410,343, +410,344,411, +345,411,344, +411,345,412, +346,412,345, +412,346,413, +347,413,346, +413,347,414, +348,414,347, +414,348,415, +349,415,348, +415,349,416, +350,416,349, +416,350,417, +351,417,350, +417,351,418, +352,418,351, +418,352,419, +353,419,352, +419,353,420, +354,420,353, +420,354,421, +355,421,354, +421,355,422, +356,422,355, +422,356,423, +357,423,356, +423,357,424, +358,424,357, +424,358,425, +359,425,358, +425,359,426, +360,426,359, +426,360,427, +361,427,360, +427,361,428, +362,428,361, +428,362,429, +363,429,362, +429,363,430, +364,430,363, +430,364,431, +365,431,364, +431,365,432, +366,432,365, +432,366,433, +367,433,366, +433,367,434, +368,434,367, +434,368,435, +369,435,368, +435,369,436, +370,436,369, +436,370,437, +371,437,370, +437,371,438, +372,438,371, +438,372,439, +373,439,372, +439,373,440, +374,440,373, +440,374,441, +375,441,374, +441,375,442, +376,442,375, +442,376,443, +377,443,376, +443,377,444, +378,444,377, +444,378,445, +379,445,378, +445,379,446, +380,446,379, +446,380,447, +381,447,380, +447,381,448, +382,448,381, +448,382,449, +383,449,382, +449,383,450, +384,450,383, +450,384,451, +385,451,384, +451,385,452, +386,452,385, +452,386,453, +387,453,386, +453,387,454, +388,454,387, +454,388,455, +389,455,388, +455,389,456, +390,456,389, +456,390,457, +391,457,390, +457,391,458, +392,458,391, +458,392,459, +393,459,392, +459,393,460, +394,460,393, +460,394,461, +395,461,394, +462,396,463, +397,463,396, +463,397,464, +398,464,397, +464,398,465, +399,465,398, +465,399,466, +400,466,399, +466,400,467, +401,467,400, +467,401,468, +402,468,401, +468,402,469, +403,469,402, +469,403,470, +404,470,403, +470,404,471, +405,471,404, +471,405,472, +406,472,405, +472,406,473, +407,473,406, +473,407,474, +408,474,407, +474,408,475, +409,475,408, +475,409,476, +410,476,409, +476,410,477, +411,477,410, +477,411,478, +412,478,411, +478,412,479, +413,479,412, +479,413,480, +414,480,413, +480,414,481, +415,481,414, +481,415,482, +416,482,415, +482,416,483, +417,483,416, +483,417,484, +418,484,417, +484,418,485, +419,485,418, +485,419,486, +420,486,419, +486,420,487, +421,487,420, +487,421,488, +422,488,421, +488,422,489, +423,489,422, +489,423,490, +424,490,423, +490,424,491, +425,491,424, +491,425,492, +426,492,425, +492,426,493, +427,493,426, +493,427,494, +428,494,427, +494,428,495, +429,495,428, +495,429,496, +430,496,429, +496,430,497, +431,497,430, +497,431,498, +432,498,431, +498,432,499, +433,499,432, +499,433,500, +434,500,433, +500,434,501, +435,501,434, +501,435,502, +436,502,435, +502,436,503, +437,503,436, +503,437,504, +438,504,437, +504,438,505, +439,505,438, +505,439,506, +440,506,439, +506,440,507, +441,507,440, +507,441,508, +442,508,441, +508,442,509, +443,509,442, +509,443,510, +444,510,443, +510,444,511, +445,511,444, +511,445,512, +446,512,445, +512,446,513, +447,513,446, +513,447,514, +448,514,447, +514,448,515, +449,515,448, +515,449,516, +450,516,449, +516,450,517, +451,517,450, +517,451,518, +452,518,451, +518,452,519, +453,519,452, +519,453,520, +454,520,453, +520,454,521, +455,521,454, +521,455,522, +456,522,455, +522,456,523, +457,523,456, +523,457,524, +458,524,457, +524,458,525, +459,525,458, +525,459,526, +460,526,459, +526,460,527, +461,527,460, +528,462,529, +463,529,462, +529,463,530, +464,530,463, +530,464,531, +465,531,464, +531,465,532, +466,532,465, +532,466,533, +467,533,466, +533,467,534, +468,534,467, +534,468,535, +469,535,468, +535,469,536, +470,536,469, +536,470,537, +471,537,470, +537,471,538, +472,538,471, +538,472,539, +473,539,472, +539,473,540, +474,540,473, +540,474,541, +475,541,474, +541,475,542, +476,542,475, +542,476,543, +477,543,476, +543,477,544, +478,544,477, +544,478,545, +479,545,478, +545,479,546, +480,546,479, +546,480,547, +481,547,480, +547,481,548, +482,548,481, +548,482,549, +483,549,482, +549,483,550, +484,550,483, +550,484,551, +485,551,484, +551,485,552, +486,552,485, +552,486,553, +487,553,486, +553,487,554, +488,554,487, +554,488,555, +489,555,488, +555,489,556, +490,556,489, +556,490,557, +491,557,490, +557,491,558, +492,558,491, +558,492,559, +493,559,492, +559,493,560, +494,560,493, +560,494,561, +495,561,494, +561,495,562, +496,562,495, +562,496,563, +497,563,496, +563,497,564, +498,564,497, +564,498,565, +499,565,498, +565,499,566, +500,566,499, +566,500,567, +501,567,500, +567,501,568, +502,568,501, +568,502,569, +503,569,502, +569,503,570, +504,570,503, +570,504,571, +505,571,504, +571,505,572, +506,572,505, +572,506,573, +507,573,506, +573,507,574, +508,574,507, +574,508,575, +509,575,508, +575,509,576, +510,576,509, +576,510,577, +511,577,510, +577,511,578, +512,578,511, +578,512,579, +513,579,512, +579,513,580, +514,580,513, +580,514,581, +515,581,514, +581,515,582, +516,582,515, +582,516,583, +517,583,516, +583,517,584, +518,584,517, +584,518,585, +519,585,518, +585,519,586, +520,586,519, +586,520,587, +521,587,520, +587,521,588, +522,588,521, +588,522,589, +523,589,522, +589,523,590, +524,590,523, +590,524,591, +525,591,524, +591,525,592, +526,592,525, +592,526,593, +527,593,526, +594,528,595, +529,595,528, +595,529,596, +530,596,529, +596,530,597, +531,597,530, +597,531,598, +532,598,531, +598,532,599, +533,599,532, +599,533,600, +534,600,533, +600,534,601, +535,601,534, +601,535,602, +536,602,535, +602,536,603, +537,603,536, +603,537,604, +538,604,537, +604,538,605, +539,605,538, +605,539,606, +540,606,539, +606,540,607, +541,607,540, +607,541,608, +542,608,541, +608,542,609, +543,609,542, +609,543,610, +544,610,543, +610,544,611, +545,611,544, +611,545,612, +546,612,545, +612,546,613, +547,613,546, +613,547,614, +548,614,547, +614,548,615, +549,615,548, +615,549,616, +550,616,549, +616,550,617, +551,617,550, +617,551,618, +552,618,551, +618,552,619, +553,619,552, +619,553,620, +554,620,553, +620,554,621, +555,621,554, +621,555,622, +556,622,555, +622,556,623, +557,623,556, +623,557,624, +558,624,557, +624,558,625, +559,625,558, +625,559,626, +560,626,559, +626,560,627, +561,627,560, +627,561,628, +562,628,561, +628,562,629, +563,629,562, +629,563,630, +564,630,563, +630,564,631, +565,631,564, +631,565,632, +566,632,565, +632,566,633, +567,633,566, +633,567,634, +568,634,567, +634,568,635, +569,635,568, +635,569,636, +570,636,569, +636,570,637, +571,637,570, +637,571,638, +572,638,571, +638,572,639, +573,639,572, +639,573,640, +574,640,573, +640,574,641, +575,641,574, +641,575,642, +576,642,575, +642,576,643, +577,643,576, +643,577,644, +578,644,577, +644,578,645, +579,645,578, +645,579,646, +580,646,579, +646,580,647, +581,647,580, +647,581,648, +582,648,581, +648,582,649, +583,649,582, +649,583,650, +584,650,583, +650,584,651, +585,651,584, +651,585,652, +586,652,585, +652,586,653, +587,653,586, +653,587,654, +588,654,587, +654,588,655, +589,655,588, +655,589,656, +590,656,589, +656,590,657, +591,657,590, +657,591,658, +592,658,591, +658,592,659, +593,659,592, +660,594,661, +595,661,594, +661,595,662, +596,662,595, +662,596,663, +597,663,596, +663,597,664, +598,664,597, +664,598,665, +599,665,598, +665,599,666, +600,666,599, +666,600,667, +601,667,600, +667,601,668, +602,668,601, +668,602,669, +603,669,602, +669,603,670, +604,670,603, +670,604,671, +605,671,604, +671,605,672, +606,672,605, +672,606,673, +607,673,606, +673,607,674, +608,674,607, +674,608,675, +609,675,608, +675,609,676, +610,676,609, +676,610,677, +611,677,610, +677,611,678, +612,678,611, +678,612,679, +613,679,612, +679,613,680, +614,680,613, +680,614,681, +615,681,614, +681,615,682, +616,682,615, +682,616,683, +617,683,616, +683,617,684, +618,684,617, +684,618,685, +619,685,618, +685,619,686, +620,686,619, +686,620,687, +621,687,620, +687,621,688, +622,688,621, +688,622,689, +623,689,622, +689,623,690, +624,690,623, +690,624,691, +625,691,624, +691,625,692, +626,692,625, +692,626,693, +627,693,626, +693,627,694, +628,694,627, +694,628,695, +629,695,628, +695,629,696, +630,696,629, +696,630,697, +631,697,630, +697,631,698, +632,698,631, +698,632,699, +633,699,632, +699,633,700, +634,700,633, +700,634,701, +635,701,634, +701,635,702, +636,702,635, +702,636,703, +637,703,636, +703,637,704, +638,704,637, +704,638,705, +639,705,638, +705,639,706, +640,706,639, +706,640,707, +641,707,640, +707,641,708, +642,708,641, +708,642,709, +643,709,642, +709,643,710, +644,710,643, +710,644,711, +645,711,644, +711,645,712, +646,712,645, +712,646,713, +647,713,646, +713,647,714, +648,714,647, +714,648,715, +649,715,648, +715,649,716, +650,716,649, +716,650,717, +651,717,650, +717,651,718, +652,718,651, +718,652,719, +653,719,652, +719,653,720, +654,720,653, +720,654,721, +655,721,654, +721,655,722, +656,722,655, +722,656,723, +657,723,656, +723,657,724, +658,724,657, +724,658,725, +659,725,658, +726,660,727, +661,727,660, +727,661,728, +662,728,661, +728,662,729, +663,729,662, +729,663,730, +664,730,663, +730,664,731, +665,731,664, +731,665,732, +666,732,665, +732,666,733, +667,733,666, +733,667,734, +668,734,667, +734,668,735, +669,735,668, +735,669,736, +670,736,669, +736,670,737, +671,737,670, +737,671,738, +672,738,671, +738,672,739, +673,739,672, +739,673,740, +674,740,673, +740,674,741, +675,741,674, +741,675,742, +676,742,675, +742,676,743, +677,743,676, +743,677,744, +678,744,677, +744,678,745, +679,745,678, +745,679,746, +680,746,679, +746,680,747, +681,747,680, +747,681,748, +682,748,681, +748,682,749, +683,749,682, +749,683,750, +684,750,683, +750,684,751, +685,751,684, +751,685,752, +686,752,685, +752,686,753, +687,753,686, +753,687,754, +688,754,687, +754,688,755, +689,755,688, +755,689,756, +690,756,689, +756,690,757, +691,757,690, +757,691,758, +692,758,691, +758,692,759, +693,759,692, +759,693,760, +694,760,693, +760,694,761, +695,761,694, +761,695,762, +696,762,695, +762,696,763, +697,763,696, +763,697,764, +698,764,697, +764,698,765, +699,765,698, +765,699,766, +700,766,699, +766,700,767, +701,767,700, +767,701,768, +702,768,701, +768,702,769, +703,769,702, +769,703,770, +704,770,703, +770,704,771, +705,771,704, +771,705,772, +706,772,705, +772,706,773, +707,773,706, +773,707,774, +708,774,707, +774,708,775, +709,775,708, +775,709,776, +710,776,709, +776,710,777, +711,777,710, +777,711,778, +712,778,711, +778,712,779, +713,779,712, +779,713,780, +714,780,713, +780,714,781, +715,781,714, +781,715,782, +716,782,715, +782,716,783, +717,783,716, +783,717,784, +718,784,717, +784,718,785, +719,785,718, +785,719,786, +720,786,719, +786,720,787, +721,787,720, +787,721,788, +722,788,721, +788,722,789, +723,789,722, +789,723,790, +724,790,723, +790,724,791, +725,791,724, +792,726,793, +727,793,726, +793,727,794, +728,794,727, +794,728,795, +729,795,728, +795,729,796, +730,796,729, +796,730,797, +731,797,730, +797,731,798, +732,798,731, +798,732,799, +733,799,732, +799,733,800, +734,800,733, +800,734,801, +735,801,734, +801,735,802, +736,802,735, +802,736,803, +737,803,736, +803,737,804, +738,804,737, +804,738,805, +739,805,738, +805,739,806, +740,806,739, +806,740,807, +741,807,740, +807,741,808, +742,808,741, +808,742,809, +743,809,742, +809,743,810, +744,810,743, +810,744,811, +745,811,744, +811,745,812, +746,812,745, +812,746,813, +747,813,746, +813,747,814, +748,814,747, +814,748,815, +749,815,748, +815,749,816, +750,816,749, +816,750,817, +751,817,750, +817,751,818, +752,818,751, +818,752,819, +753,819,752, +819,753,820, +754,820,753, +820,754,821, +755,821,754, +821,755,822, +756,822,755, +822,756,823, +757,823,756, +823,757,824, +758,824,757, +824,758,825, +759,825,758, +825,759,826, +760,826,759, +826,760,827, +761,827,760, +827,761,828, +762,828,761, +828,762,829, +763,829,762, +829,763,830, +764,830,763, +830,764,831, +765,831,764, +831,765,832, +766,832,765, +832,766,833, +767,833,766, +833,767,834, +768,834,767, +834,768,835, +769,835,768, +835,769,836, +770,836,769, +836,770,837, +771,837,770, +837,771,838, +772,838,771, +838,772,839, +773,839,772, +839,773,840, +774,840,773, +840,774,841, +775,841,774, +841,775,842, +776,842,775, +842,776,843, +777,843,776, +843,777,844, +778,844,777, +844,778,845, +779,845,778, +845,779,846, +780,846,779, +846,780,847, +781,847,780, +847,781,848, +782,848,781, +848,782,849, +783,849,782, +849,783,850, +784,850,783, +850,784,851, +785,851,784, +851,785,852, +786,852,785, +852,786,853, +787,853,786, +853,787,854, +788,854,787, +854,788,855, +789,855,788, +855,789,856, +790,856,789, +856,790,857, +791,857,790, +858,792,859, +793,859,792, +859,793,860, +794,860,793, +860,794,861, +795,861,794, +861,795,862, +796,862,795, +862,796,863, +797,863,796, +863,797,864, +798,864,797, +864,798,865, +799,865,798, +865,799,866, +800,866,799, +866,800,867, +801,867,800, +867,801,868, +802,868,801, +868,802,869, +803,869,802, +869,803,870, +804,870,803, +870,804,871, +805,871,804, +871,805,872, +806,872,805, +872,806,873, +807,873,806, +873,807,874, +808,874,807, +874,808,875, +809,875,808, +875,809,876, +810,876,809, +876,810,877, +811,877,810, +877,811,878, +812,878,811, +878,812,879, +813,879,812, +879,813,880, +814,880,813, +880,814,881, +815,881,814, +881,815,882, +816,882,815, +882,816,883, +817,883,816, +883,817,884, +818,884,817, +884,818,885, +819,885,818, +885,819,886, +820,886,819, +886,820,887, +821,887,820, +887,821,888, +822,888,821, +888,822,889, +823,889,822, +889,823,890, +824,890,823, +890,824,891, +825,891,824, +891,825,892, +826,892,825, +892,826,893, +827,893,826, +893,827,894, +828,894,827, +894,828,895, +829,895,828, +895,829,896, +830,896,829, +896,830,897, +831,897,830, +897,831,898, +832,898,831, +898,832,899, +833,899,832, +899,833,900, +834,900,833, +900,834,901, +835,901,834, +901,835,902, +836,902,835, +902,836,903, +837,903,836, +903,837,904, +838,904,837, +904,838,905, +839,905,838, +905,839,906, +840,906,839, +906,840,907, +841,907,840, +907,841,908, +842,908,841, +908,842,909, +843,909,842, +909,843,910, +844,910,843, +910,844,911, +845,911,844, +911,845,912, +846,912,845, +912,846,913, +847,913,846, +913,847,914, +848,914,847, +914,848,915, +849,915,848, +915,849,916, +850,916,849, +916,850,917, +851,917,850, +917,851,918, +852,918,851, +918,852,919, +853,919,852, +919,853,920, +854,920,853, +920,854,921, +855,921,854, +921,855,922, +856,922,855, +922,856,923, +857,923,856, +924,858,925, +859,925,858, +925,859,926, +860,926,859, +926,860,927, +861,927,860, +927,861,928, +862,928,861, +928,862,929, +863,929,862, +929,863,930, +864,930,863, +930,864,931, +865,931,864, +931,865,932, +866,932,865, +932,866,933, +867,933,866, +933,867,934, +868,934,867, +934,868,935, +869,935,868, +935,869,936, +870,936,869, +936,870,937, +871,937,870, +937,871,938, +872,938,871, +938,872,939, +873,939,872, +939,873,940, +874,940,873, +940,874,941, +875,941,874, +941,875,942, +876,942,875, +942,876,943, +877,943,876, +943,877,944, +878,944,877, +944,878,945, +879,945,878, +945,879,946, +880,946,879, +946,880,947, +881,947,880, +947,881,948, +882,948,881, +948,882,949, +883,949,882, +949,883,950, +884,950,883, +950,884,951, +885,951,884, +951,885,952, +886,952,885, +952,886,953, +887,953,886, +953,887,954, +888,954,887, +954,888,955, +889,955,888, +955,889,956, +890,956,889, +956,890,957, +891,957,890, +957,891,958, +892,958,891, +958,892,959, +893,959,892, +959,893,960, +894,960,893, +960,894,961, +895,961,894, +961,895,962, +896,962,895, +962,896,963, +897,963,896, +963,897,964, +898,964,897, +964,898,965, +899,965,898, +965,899,966, +900,966,899, +966,900,967, +901,967,900, +967,901,968, +902,968,901, +968,902,969, +903,969,902, +969,903,970, +904,970,903, +970,904,971, +905,971,904, +971,905,972, +906,972,905, +972,906,973, +907,973,906, +973,907,974, +908,974,907, +974,908,975, +909,975,908, +975,909,976, +910,976,909, +976,910,977, +911,977,910, +977,911,978, +912,978,911, +978,912,979, +913,979,912, +979,913,980, +914,980,913, +980,914,981, +915,981,914, +981,915,982, +916,982,915, +982,916,983, +917,983,916, +983,917,984, +918,984,917, +984,918,985, +919,985,918, +985,919,986, +920,986,919, +986,920,987, +921,987,920, +987,921,988, +922,988,921, +988,922,989, +923,989,922, +990,924,991, +925,991,924, +991,925,992, +926,992,925, +992,926,993, +927,993,926, +993,927,994, +928,994,927, +994,928,995, +929,995,928, +995,929,996, +930,996,929, +996,930,997, +931,997,930, +997,931,998, +932,998,931, +998,932,999, +933,999,932, +999,933,1000, +934,1000,933, +1000,934,1001, +935,1001,934, +1001,935,1002, +936,1002,935, +1002,936,1003, +937,1003,936, +1003,937,1004, +938,1004,937, +1004,938,1005, +939,1005,938, +1005,939,1006, +940,1006,939, +1006,940,1007, +941,1007,940, +1007,941,1008, +942,1008,941, +1008,942,1009, +943,1009,942, +1009,943,1010, +944,1010,943, +1010,944,1011, +945,1011,944, +1011,945,1012, +946,1012,945, +1012,946,1013, +947,1013,946, +1013,947,1014, +948,1014,947, +1014,948,1015, +949,1015,948, +1015,949,1016, +950,1016,949, +1016,950,1017, +951,1017,950, +1017,951,1018, +952,1018,951, +1018,952,1019, +953,1019,952, +1019,953,1020, +954,1020,953, +1020,954,1021, +955,1021,954, +1021,955,1022, +956,1022,955, +1022,956,1023, +957,1023,956, +1023,957,1024, +958,1024,957, +1024,958,1025, +959,1025,958, +1025,959,1026, +960,1026,959, +1026,960,1027, +961,1027,960, +1027,961,1028, +962,1028,961, +1028,962,1029, +963,1029,962, +1029,963,1030, +964,1030,963, +1030,964,1031, +965,1031,964, +1031,965,1032, +966,1032,965, +1032,966,1033, +967,1033,966, +1033,967,1034, +968,1034,967, +1034,968,1035, +969,1035,968, +1035,969,1036, +970,1036,969, +1036,970,1037, +971,1037,970, +1037,971,1038, +972,1038,971, +1038,972,1039, +973,1039,972, +1039,973,1040, +974,1040,973, +1040,974,1041, +975,1041,974, +1041,975,1042, +976,1042,975, +1042,976,1043, +977,1043,976, +1043,977,1044, +978,1044,977, +1044,978,1045, +979,1045,978, +1045,979,1046, +980,1046,979, +1046,980,1047, +981,1047,980, +1047,981,1048, +982,1048,981, +1048,982,1049, +983,1049,982, +1049,983,1050, +984,1050,983, +1050,984,1051, +985,1051,984, +1051,985,1052, +986,1052,985, +1052,986,1053, +987,1053,986, +1053,987,1054, +988,1054,987, +1054,988,1055, +989,1055,988, +1056,990,1057, +991,1057,990, +1057,991,1058, +992,1058,991, +1058,992,1059, +993,1059,992, +1059,993,1060, +994,1060,993, +1060,994,1061, +995,1061,994, +1061,995,1062, +996,1062,995, +1062,996,1063, +997,1063,996, +1063,997,1064, +998,1064,997, +1064,998,1065, +999,1065,998, +1065,999,1066, +1000,1066,999, +1066,1000,1067, +1001,1067,1000, +1067,1001,1068, +1002,1068,1001, +1068,1002,1069, +1003,1069,1002, +1069,1003,1070, +1004,1070,1003, +1070,1004,1071, +1005,1071,1004, +1071,1005,1072, +1006,1072,1005, +1072,1006,1073, +1007,1073,1006, +1073,1007,1074, +1008,1074,1007, +1074,1008,1075, +1009,1075,1008, +1075,1009,1076, +1010,1076,1009, +1076,1010,1077, +1011,1077,1010, +1077,1011,1078, +1012,1078,1011, +1078,1012,1079, +1013,1079,1012, +1079,1013,1080, +1014,1080,1013, +1080,1014,1081, +1015,1081,1014, +1081,1015,1082, +1016,1082,1015, +1082,1016,1083, +1017,1083,1016, +1083,1017,1084, +1018,1084,1017, +1084,1018,1085, +1019,1085,1018, +1085,1019,1086, +1020,1086,1019, +1086,1020,1087, +1021,1087,1020, +1087,1021,1088, +1022,1088,1021, +1088,1022,1089, +1023,1089,1022, +1089,1023,1090, +1024,1090,1023, +1090,1024,1091, +1025,1091,1024, +1091,1025,1092, +1026,1092,1025, +1092,1026,1093, +1027,1093,1026, +1093,1027,1094, +1028,1094,1027, +1094,1028,1095, +1029,1095,1028, +1095,1029,1096, +1030,1096,1029, +1096,1030,1097, +1031,1097,1030, +1097,1031,1098, +1032,1098,1031, +1098,1032,1099, +1033,1099,1032, +1099,1033,1100, +1034,1100,1033, +1100,1034,1101, +1035,1101,1034, +1101,1035,1102, +1036,1102,1035, +1102,1036,1103, +1037,1103,1036, +1103,1037,1104, +1038,1104,1037, +1104,1038,1105, +1039,1105,1038, +1105,1039,1106, +1040,1106,1039, +1106,1040,1107, +1041,1107,1040, +1107,1041,1108, +1042,1108,1041, +1108,1042,1109, +1043,1109,1042, +1109,1043,1110, +1044,1110,1043, +1110,1044,1111, +1045,1111,1044, +1111,1045,1112, +1046,1112,1045, +1112,1046,1113, +1047,1113,1046, +1113,1047,1114, +1048,1114,1047, +1114,1048,1115, +1049,1115,1048, +1115,1049,1116, +1050,1116,1049, +1116,1050,1117, +1051,1117,1050, +1117,1051,1118, +1052,1118,1051, +1118,1052,1119, +1053,1119,1052, +1119,1053,1120, +1054,1120,1053, +1120,1054,1121, +1055,1121,1054, +1122,1056,1123, +1057,1123,1056, +1123,1057,1124, +1058,1124,1057, +1124,1058,1125, +1059,1125,1058, +1125,1059,1126, +1060,1126,1059, +1126,1060,1127, +1061,1127,1060, +1127,1061,1128, +1062,1128,1061, +1128,1062,1129, +1063,1129,1062, +1129,1063,1130, +1064,1130,1063, +1130,1064,1131, +1065,1131,1064, +1131,1065,1132, +1066,1132,1065, +1132,1066,1133, +1067,1133,1066, +1133,1067,1134, +1068,1134,1067, +1134,1068,1135, +1069,1135,1068, +1135,1069,1136, +1070,1136,1069, +1136,1070,1137, +1071,1137,1070, +1137,1071,1138, +1072,1138,1071, +1138,1072,1139, +1073,1139,1072, +1139,1073,1140, +1074,1140,1073, +1140,1074,1141, +1075,1141,1074, +1141,1075,1142, +1076,1142,1075, +1142,1076,1143, +1077,1143,1076, +1143,1077,1144, +1078,1144,1077, +1144,1078,1145, +1079,1145,1078, +1145,1079,1146, +1080,1146,1079, +1146,1080,1147, +1081,1147,1080, +1147,1081,1148, +1082,1148,1081, +1148,1082,1149, +1083,1149,1082, +1149,1083,1150, +1084,1150,1083, +1150,1084,1151, +1085,1151,1084, +1151,1085,1152, +1086,1152,1085, +1152,1086,1153, +1087,1153,1086, +1153,1087,1154, +1088,1154,1087, +1154,1088,1155, +1089,1155,1088, +1155,1089,1156, +1090,1156,1089, +1156,1090,1157, +1091,1157,1090, +1157,1091,1158, +1092,1158,1091, +1158,1092,1159, +1093,1159,1092, +1159,1093,1160, +1094,1160,1093, +1160,1094,1161, +1095,1161,1094, +1161,1095,1162, +1096,1162,1095, +1162,1096,1163, +1097,1163,1096, +1163,1097,1164, +1098,1164,1097, +1164,1098,1165, +1099,1165,1098, +1165,1099,1166, +1100,1166,1099, +1166,1100,1167, +1101,1167,1100, +1167,1101,1168, +1102,1168,1101, +1168,1102,1169, +1103,1169,1102, +1169,1103,1170, +1104,1170,1103, +1170,1104,1171, +1105,1171,1104, +1171,1105,1172, +1106,1172,1105, +1172,1106,1173, +1107,1173,1106, +1173,1107,1174, +1108,1174,1107, +1174,1108,1175, +1109,1175,1108, +1175,1109,1176, +1110,1176,1109, +1176,1110,1177, +1111,1177,1110, +1177,1111,1178, +1112,1178,1111, +1178,1112,1179, +1113,1179,1112, +1179,1113,1180, +1114,1180,1113, +1180,1114,1181, +1115,1181,1114, +1181,1115,1182, +1116,1182,1115, +1182,1116,1183, +1117,1183,1116, +1183,1117,1184, +1118,1184,1117, +1184,1118,1185, +1119,1185,1118, +1185,1119,1186, +1120,1186,1119, +1186,1120,1187, +1121,1187,1120, +1188,1122,1189, +1123,1189,1122, +1189,1123,1190, +1124,1190,1123, +1190,1124,1191, +1125,1191,1124, +1191,1125,1192, +1126,1192,1125, +1192,1126,1193, +1127,1193,1126, +1193,1127,1194, +1128,1194,1127, +1194,1128,1195, +1129,1195,1128, +1195,1129,1196, +1130,1196,1129, +1196,1130,1197, +1131,1197,1130, +1197,1131,1198, +1132,1198,1131, +1198,1132,1199, +1133,1199,1132, +1199,1133,1200, +1134,1200,1133, +1200,1134,1201, +1135,1201,1134, +1201,1135,1202, +1136,1202,1135, +1202,1136,1203, +1137,1203,1136, +1203,1137,1204, +1138,1204,1137, +1204,1138,1205, +1139,1205,1138, +1205,1139,1206, +1140,1206,1139, +1206,1140,1207, +1141,1207,1140, +1207,1141,1208, +1142,1208,1141, +1208,1142,1209, +1143,1209,1142, +1209,1143,1210, +1144,1210,1143, +1210,1144,1211, +1145,1211,1144, +1211,1145,1212, +1146,1212,1145, +1212,1146,1213, +1147,1213,1146, +1213,1147,1214, +1148,1214,1147, +1214,1148,1215, +1149,1215,1148, +1215,1149,1216, +1150,1216,1149, +1216,1150,1217, +1151,1217,1150, +1217,1151,1218, +1152,1218,1151, +1218,1152,1219, +1153,1219,1152, +1219,1153,1220, +1154,1220,1153, +1220,1154,1221, +1155,1221,1154, +1221,1155,1222, +1156,1222,1155, +1222,1156,1223, +1157,1223,1156, +1223,1157,1224, +1158,1224,1157, +1224,1158,1225, +1159,1225,1158, +1225,1159,1226, +1160,1226,1159, +1226,1160,1227, +1161,1227,1160, +1227,1161,1228, +1162,1228,1161, +1228,1162,1229, +1163,1229,1162, +1229,1163,1230, +1164,1230,1163, +1230,1164,1231, +1165,1231,1164, +1231,1165,1232, +1166,1232,1165, +1232,1166,1233, +1167,1233,1166, +1233,1167,1234, +1168,1234,1167, +1234,1168,1235, +1169,1235,1168, +1235,1169,1236, +1170,1236,1169, +1236,1170,1237, +1171,1237,1170, +1237,1171,1238, +1172,1238,1171, +1238,1172,1239, +1173,1239,1172, +1239,1173,1240, +1174,1240,1173, +1240,1174,1241, +1175,1241,1174, +1241,1175,1242, +1176,1242,1175, +1242,1176,1243, +1177,1243,1176, +1243,1177,1244, +1178,1244,1177, +1244,1178,1245, +1179,1245,1178, +1245,1179,1246, +1180,1246,1179, +1246,1180,1247, +1181,1247,1180, +1247,1181,1248, +1182,1248,1181, +1248,1182,1249, +1183,1249,1182, +1249,1183,1250, +1184,1250,1183, +1250,1184,1251, +1185,1251,1184, +1251,1185,1252, +1186,1252,1185, +1252,1186,1253, +1187,1253,1186, +1254,1188,1255, +1189,1255,1188, +1255,1189,1256, +1190,1256,1189, +1256,1190,1257, +1191,1257,1190, +1257,1191,1258, +1192,1258,1191, +1258,1192,1259, +1193,1259,1192, +1259,1193,1260, +1194,1260,1193, +1260,1194,1261, +1195,1261,1194, +1261,1195,1262, +1196,1262,1195, +1262,1196,1263, +1197,1263,1196, +1263,1197,1264, +1198,1264,1197, +1264,1198,1265, +1199,1265,1198, +1265,1199,1266, +1200,1266,1199, +1266,1200,1267, +1201,1267,1200, +1267,1201,1268, +1202,1268,1201, +1268,1202,1269, +1203,1269,1202, +1269,1203,1270, +1204,1270,1203, +1270,1204,1271, +1205,1271,1204, +1271,1205,1272, +1206,1272,1205, +1272,1206,1273, +1207,1273,1206, +1273,1207,1274, +1208,1274,1207, +1274,1208,1275, +1209,1275,1208, +1275,1209,1276, +1210,1276,1209, +1276,1210,1277, +1211,1277,1210, +1277,1211,1278, +1212,1278,1211, +1278,1212,1279, +1213,1279,1212, +1279,1213,1280, +1214,1280,1213, +1280,1214,1281, +1215,1281,1214, +1281,1215,1282, +1216,1282,1215, +1282,1216,1283, +1217,1283,1216, +1283,1217,1284, +1218,1284,1217, +1284,1218,1285, +1219,1285,1218, +1285,1219,1286, +1220,1286,1219, +1286,1220,1287, +1221,1287,1220, +1287,1221,1288, +1222,1288,1221, +1288,1222,1289, +1223,1289,1222, +1289,1223,1290, +1224,1290,1223, +1290,1224,1291, +1225,1291,1224, +1291,1225,1292, +1226,1292,1225, +1292,1226,1293, +1227,1293,1226, +1293,1227,1294, +1228,1294,1227, +1294,1228,1295, +1229,1295,1228, +1295,1229,1296, +1230,1296,1229, +1296,1230,1297, +1231,1297,1230, +1297,1231,1298, +1232,1298,1231, +1298,1232,1299, +1233,1299,1232, +1299,1233,1300, +1234,1300,1233, +1300,1234,1301, +1235,1301,1234, +1301,1235,1302, +1236,1302,1235, +1302,1236,1303, +1237,1303,1236, +1303,1237,1304, +1238,1304,1237, +1304,1238,1305, +1239,1305,1238, +1305,1239,1306, +1240,1306,1239, +1306,1240,1307, +1241,1307,1240, +1307,1241,1308, +1242,1308,1241, +1308,1242,1309, +1243,1309,1242, +1309,1243,1310, +1244,1310,1243, +1310,1244,1311, +1245,1311,1244, +1311,1245,1312, +1246,1312,1245, +1312,1246,1313, +1247,1313,1246, +1313,1247,1314, +1248,1314,1247, +1314,1248,1315, +1249,1315,1248, +1315,1249,1316, +1250,1316,1249, +1316,1250,1317, +1251,1317,1250, +1317,1251,1318, +1252,1318,1251, +1318,1252,1319, +1253,1319,1252, +1320,1254,1321, +1255,1321,1254, +1321,1255,1322, +1256,1322,1255, +1322,1256,1323, +1257,1323,1256, +1323,1257,1324, +1258,1324,1257, +1324,1258,1325, +1259,1325,1258, +1325,1259,1326, +1260,1326,1259, +1326,1260,1327, +1261,1327,1260, +1327,1261,1328, +1262,1328,1261, +1328,1262,1329, +1263,1329,1262, +1329,1263,1330, +1264,1330,1263, +1330,1264,1331, +1265,1331,1264, +1331,1265,1332, +1266,1332,1265, +1332,1266,1333, +1267,1333,1266, +1333,1267,1334, +1268,1334,1267, +1334,1268,1335, +1269,1335,1268, +1335,1269,1336, +1270,1336,1269, +1336,1270,1337, +1271,1337,1270, +1337,1271,1338, +1272,1338,1271, +1338,1272,1339, +1273,1339,1272, +1339,1273,1340, +1274,1340,1273, +1340,1274,1341, +1275,1341,1274, +1341,1275,1342, +1276,1342,1275, +1342,1276,1343, +1277,1343,1276, +1343,1277,1344, +1278,1344,1277, +1344,1278,1345, +1279,1345,1278, +1345,1279,1346, +1280,1346,1279, +1346,1280,1347, +1281,1347,1280, +1347,1281,1348, +1282,1348,1281, +1348,1282,1349, +1283,1349,1282, +1349,1283,1350, +1284,1350,1283, +1350,1284,1351, +1285,1351,1284, +1351,1285,1352, +1286,1352,1285, +1352,1286,1353, +1287,1353,1286, +1353,1287,1354, +1288,1354,1287, +1354,1288,1355, +1289,1355,1288, +1355,1289,1356, +1290,1356,1289, +1356,1290,1357, +1291,1357,1290, +1357,1291,1358, +1292,1358,1291, +1358,1292,1359, +1293,1359,1292, +1359,1293,1360, +1294,1360,1293, +1360,1294,1361, +1295,1361,1294, +1361,1295,1362, +1296,1362,1295, +1362,1296,1363, +1297,1363,1296, +1363,1297,1364, +1298,1364,1297, +1364,1298,1365, +1299,1365,1298, +1365,1299,1366, +1300,1366,1299, +1366,1300,1367, +1301,1367,1300, +1367,1301,1368, +1302,1368,1301, +1368,1302,1369, +1303,1369,1302, +1369,1303,1370, +1304,1370,1303, +1370,1304,1371, +1305,1371,1304, +1371,1305,1372, +1306,1372,1305, +1372,1306,1373, +1307,1373,1306, +1373,1307,1374, +1308,1374,1307, +1374,1308,1375, +1309,1375,1308, +1375,1309,1376, +1310,1376,1309, +1376,1310,1377, +1311,1377,1310, +1377,1311,1378, +1312,1378,1311, +1378,1312,1379, +1313,1379,1312, +1379,1313,1380, +1314,1380,1313, +1380,1314,1381, +1315,1381,1314, +1381,1315,1382, +1316,1382,1315, +1382,1316,1383, +1317,1383,1316, +1383,1317,1384, +1318,1384,1317, +1384,1318,1385, +1319,1385,1318, +1386,1320,1387, +1321,1387,1320, +1387,1321,1388, +1322,1388,1321, +1388,1322,1389, +1323,1389,1322, +1389,1323,1390, +1324,1390,1323, +1390,1324,1391, +1325,1391,1324, +1391,1325,1392, +1326,1392,1325, +1392,1326,1393, +1327,1393,1326, +1393,1327,1394, +1328,1394,1327, +1394,1328,1395, +1329,1395,1328, +1395,1329,1396, +1330,1396,1329, +1396,1330,1397, +1331,1397,1330, +1397,1331,1398, +1332,1398,1331, +1398,1332,1399, +1333,1399,1332, +1399,1333,1400, +1334,1400,1333, +1400,1334,1401, +1335,1401,1334, +1401,1335,1402, +1336,1402,1335, +1402,1336,1403, +1337,1403,1336, +1403,1337,1404, +1338,1404,1337, +1404,1338,1405, +1339,1405,1338, +1405,1339,1406, +1340,1406,1339, +1406,1340,1407, +1341,1407,1340, +1407,1341,1408, +1342,1408,1341, +1408,1342,1409, +1343,1409,1342, +1409,1343,1410, +1344,1410,1343, +1410,1344,1411, +1345,1411,1344, +1411,1345,1412, +1346,1412,1345, +1412,1346,1413, +1347,1413,1346, +1413,1347,1414, +1348,1414,1347, +1414,1348,1415, +1349,1415,1348, +1415,1349,1416, +1350,1416,1349, +1416,1350,1417, +1351,1417,1350, +1417,1351,1418, +1352,1418,1351, +1418,1352,1419, +1353,1419,1352, +1419,1353,1420, +1354,1420,1353, +1420,1354,1421, +1355,1421,1354, +1421,1355,1422, +1356,1422,1355, +1422,1356,1423, +1357,1423,1356, +1423,1357,1424, +1358,1424,1357, +1424,1358,1425, +1359,1425,1358, +1425,1359,1426, +1360,1426,1359, +1426,1360,1427, +1361,1427,1360, +1427,1361,1428, +1362,1428,1361, +1428,1362,1429, +1363,1429,1362, +1429,1363,1430, +1364,1430,1363, +1430,1364,1431, +1365,1431,1364, +1431,1365,1432, +1366,1432,1365, +1432,1366,1433, +1367,1433,1366, +1433,1367,1434, +1368,1434,1367, +1434,1368,1435, +1369,1435,1368, +1435,1369,1436, +1370,1436,1369, +1436,1370,1437, +1371,1437,1370, +1437,1371,1438, +1372,1438,1371, +1438,1372,1439, +1373,1439,1372, +1439,1373,1440, +1374,1440,1373, +1440,1374,1441, +1375,1441,1374, +1441,1375,1442, +1376,1442,1375, +1442,1376,1443, +1377,1443,1376, +1443,1377,1444, +1378,1444,1377, +1444,1378,1445, +1379,1445,1378, +1445,1379,1446, +1380,1446,1379, +1446,1380,1447, +1381,1447,1380, +1447,1381,1448, +1382,1448,1381, +1448,1382,1449, +1383,1449,1382, +1449,1383,1450, +1384,1450,1383, +1450,1384,1451, +1385,1451,1384, +1452,1386,1453, +1387,1453,1386, +1453,1387,1454, +1388,1454,1387, +1454,1388,1455, +1389,1455,1388, +1455,1389,1456, +1390,1456,1389, +1456,1390,1457, +1391,1457,1390, +1457,1391,1458, +1392,1458,1391, +1458,1392,1459, +1393,1459,1392, +1459,1393,1460, +1394,1460,1393, +1460,1394,1461, +1395,1461,1394, +1461,1395,1462, +1396,1462,1395, +1462,1396,1463, +1397,1463,1396, +1463,1397,1464, +1398,1464,1397, +1464,1398,1465, +1399,1465,1398, +1465,1399,1466, +1400,1466,1399, +1466,1400,1467, +1401,1467,1400, +1467,1401,1468, +1402,1468,1401, +1468,1402,1469, +1403,1469,1402, +1469,1403,1470, +1404,1470,1403, +1470,1404,1471, +1405,1471,1404, +1471,1405,1472, +1406,1472,1405, +1472,1406,1473, +1407,1473,1406, +1473,1407,1474, +1408,1474,1407, +1474,1408,1475, +1409,1475,1408, +1475,1409,1476, +1410,1476,1409, +1476,1410,1477, +1411,1477,1410, +1477,1411,1478, +1412,1478,1411, +1478,1412,1479, +1413,1479,1412, +1479,1413,1480, +1414,1480,1413, +1480,1414,1481, +1415,1481,1414, +1481,1415,1482, +1416,1482,1415, +1482,1416,1483, +1417,1483,1416, +1483,1417,1484, +1418,1484,1417, +1484,1418,1485, +1419,1485,1418, +1485,1419,1486, +1420,1486,1419, +1486,1420,1487, +1421,1487,1420, +1487,1421,1488, +1422,1488,1421, +1488,1422,1489, +1423,1489,1422, +1489,1423,1490, +1424,1490,1423, +1490,1424,1491, +1425,1491,1424, +1491,1425,1492, +1426,1492,1425, +1492,1426,1493, +1427,1493,1426, +1493,1427,1494, +1428,1494,1427, +1494,1428,1495, +1429,1495,1428, +1495,1429,1496, +1430,1496,1429, +1496,1430,1497, +1431,1497,1430, +1497,1431,1498, +1432,1498,1431, +1498,1432,1499, +1433,1499,1432, +1499,1433,1500, +1434,1500,1433, +1500,1434,1501, +1435,1501,1434, +1501,1435,1502, +1436,1502,1435, +1502,1436,1503, +1437,1503,1436, +1503,1437,1504, +1438,1504,1437, +1504,1438,1505, +1439,1505,1438, +1505,1439,1506, +1440,1506,1439, +1506,1440,1507, +1441,1507,1440, +1507,1441,1508, +1442,1508,1441, +1508,1442,1509, +1443,1509,1442, +1509,1443,1510, +1444,1510,1443, +1510,1444,1511, +1445,1511,1444, +1511,1445,1512, +1446,1512,1445, +1512,1446,1513, +1447,1513,1446, +1513,1447,1514, +1448,1514,1447, +1514,1448,1515, +1449,1515,1448, +1515,1449,1516, +1450,1516,1449, +1516,1450,1517, +1451,1517,1450, +1518,1452,1519, +1453,1519,1452, +1519,1453,1520, +1454,1520,1453, +1520,1454,1521, +1455,1521,1454, +1521,1455,1522, +1456,1522,1455, +1522,1456,1523, +1457,1523,1456, +1523,1457,1524, +1458,1524,1457, +1524,1458,1525, +1459,1525,1458, +1525,1459,1526, +1460,1526,1459, +1526,1460,1527, +1461,1527,1460, +1527,1461,1528, +1462,1528,1461, +1528,1462,1529, +1463,1529,1462, +1529,1463,1530, +1464,1530,1463, +1530,1464,1531, +1465,1531,1464, +1531,1465,1532, +1466,1532,1465, +1532,1466,1533, +1467,1533,1466, +1533,1467,1534, +1468,1534,1467, +1534,1468,1535, +1469,1535,1468, +1535,1469,1536, +1470,1536,1469, +1536,1470,1537, +1471,1537,1470, +1537,1471,1538, +1472,1538,1471, +1538,1472,1539, +1473,1539,1472, +1539,1473,1540, +1474,1540,1473, +1540,1474,1541, +1475,1541,1474, +1541,1475,1542, +1476,1542,1475, +1542,1476,1543, +1477,1543,1476, +1543,1477,1544, +1478,1544,1477, +1544,1478,1545, +1479,1545,1478, +1545,1479,1546, +1480,1546,1479, +1546,1480,1547, +1481,1547,1480, +1547,1481,1548, +1482,1548,1481, +1548,1482,1549, +1483,1549,1482, +1549,1483,1550, +1484,1550,1483, +1550,1484,1551, +1485,1551,1484, +1551,1485,1552, +1486,1552,1485, +1552,1486,1553, +1487,1553,1486, +1553,1487,1554, +1488,1554,1487, +1554,1488,1555, +1489,1555,1488, +1555,1489,1556, +1490,1556,1489, +1556,1490,1557, +1491,1557,1490, +1557,1491,1558, +1492,1558,1491, +1558,1492,1559, +1493,1559,1492, +1559,1493,1560, +1494,1560,1493, +1560,1494,1561, +1495,1561,1494, +1561,1495,1562, +1496,1562,1495, +1562,1496,1563, +1497,1563,1496, +1563,1497,1564, +1498,1564,1497, +1564,1498,1565, +1499,1565,1498, +1565,1499,1566, +1500,1566,1499, +1566,1500,1567, +1501,1567,1500, +1567,1501,1568, +1502,1568,1501, +1568,1502,1569, +1503,1569,1502, +1569,1503,1570, +1504,1570,1503, +1570,1504,1571, +1505,1571,1504, +1571,1505,1572, +1506,1572,1505, +1572,1506,1573, +1507,1573,1506, +1573,1507,1574, +1508,1574,1507, +1574,1508,1575, +1509,1575,1508, +1575,1509,1576, +1510,1576,1509, +1576,1510,1577, +1511,1577,1510, +1577,1511,1578, +1512,1578,1511, +1578,1512,1579, +1513,1579,1512, +1579,1513,1580, +1514,1580,1513, +1580,1514,1581, +1515,1581,1514, +1581,1515,1582, +1516,1582,1515, +1582,1516,1583, +1517,1583,1516, +1584,1518,1585, +1519,1585,1518, +1585,1519,1586, +1520,1586,1519, +1586,1520,1587, +1521,1587,1520, +1587,1521,1588, +1522,1588,1521, +1588,1522,1589, +1523,1589,1522, +1589,1523,1590, +1524,1590,1523, +1590,1524,1591, +1525,1591,1524, +1591,1525,1592, +1526,1592,1525, +1592,1526,1593, +1527,1593,1526, +1593,1527,1594, +1528,1594,1527, +1594,1528,1595, +1529,1595,1528, +1595,1529,1596, +1530,1596,1529, +1596,1530,1597, +1531,1597,1530, +1597,1531,1598, +1532,1598,1531, +1598,1532,1599, +1533,1599,1532, +1599,1533,1600, +1534,1600,1533, +1600,1534,1601, +1535,1601,1534, +1601,1535,1602, +1536,1602,1535, +1602,1536,1603, +1537,1603,1536, +1603,1537,1604, +1538,1604,1537, +1604,1538,1605, +1539,1605,1538, +1605,1539,1606, +1540,1606,1539, +1606,1540,1607, +1541,1607,1540, +1607,1541,1608, +1542,1608,1541, +1608,1542,1609, +1543,1609,1542, +1609,1543,1610, +1544,1610,1543, +1610,1544,1611, +1545,1611,1544, +1611,1545,1612, +1546,1612,1545, +1612,1546,1613, +1547,1613,1546, +1613,1547,1614, +1548,1614,1547, +1614,1548,1615, +1549,1615,1548, +1615,1549,1616, +1550,1616,1549, +1616,1550,1617, +1551,1617,1550, +1617,1551,1618, +1552,1618,1551, +1618,1552,1619, +1553,1619,1552, +1619,1553,1620, +1554,1620,1553, +1620,1554,1621, +1555,1621,1554, +1621,1555,1622, +1556,1622,1555, +1622,1556,1623, +1557,1623,1556, +1623,1557,1624, +1558,1624,1557, +1624,1558,1625, +1559,1625,1558, +1625,1559,1626, +1560,1626,1559, +1626,1560,1627, +1561,1627,1560, +1627,1561,1628, +1562,1628,1561, +1628,1562,1629, +1563,1629,1562, +1629,1563,1630, +1564,1630,1563, +1630,1564,1631, +1565,1631,1564, +1631,1565,1632, +1566,1632,1565, +1632,1566,1633, +1567,1633,1566, +1633,1567,1634, +1568,1634,1567, +1634,1568,1635, +1569,1635,1568, +1635,1569,1636, +1570,1636,1569, +1636,1570,1637, +1571,1637,1570, +1637,1571,1638, +1572,1638,1571, +1638,1572,1639, +1573,1639,1572, +1639,1573,1640, +1574,1640,1573, +1640,1574,1641, +1575,1641,1574, +1641,1575,1642, +1576,1642,1575, +1642,1576,1643, +1577,1643,1576, +1643,1577,1644, +1578,1644,1577, +1644,1578,1645, +1579,1645,1578, +1645,1579,1646, +1580,1646,1579, +1646,1580,1647, +1581,1647,1580, +1647,1581,1648, +1582,1648,1581, +1648,1582,1649, +1583,1649,1582, +1650,1584,1651, +1585,1651,1584, +1651,1585,1652, +1586,1652,1585, +1652,1586,1653, +1587,1653,1586, +1653,1587,1654, +1588,1654,1587, +1654,1588,1655, +1589,1655,1588, +1655,1589,1656, +1590,1656,1589, +1656,1590,1657, +1591,1657,1590, +1657,1591,1658, +1592,1658,1591, +1658,1592,1659, +1593,1659,1592, +1659,1593,1660, +1594,1660,1593, +1660,1594,1661, +1595,1661,1594, +1661,1595,1662, +1596,1662,1595, +1662,1596,1663, +1597,1663,1596, +1663,1597,1664, +1598,1664,1597, +1664,1598,1665, +1599,1665,1598, +1665,1599,1666, +1600,1666,1599, +1666,1600,1667, +1601,1667,1600, +1667,1601,1668, +1602,1668,1601, +1668,1602,1669, +1603,1669,1602, +1669,1603,1670, +1604,1670,1603, +1670,1604,1671, +1605,1671,1604, +1671,1605,1672, +1606,1672,1605, +1672,1606,1673, +1607,1673,1606, +1673,1607,1674, +1608,1674,1607, +1674,1608,1675, +1609,1675,1608, +1675,1609,1676, +1610,1676,1609, +1676,1610,1677, +1611,1677,1610, +1677,1611,1678, +1612,1678,1611, +1678,1612,1679, +1613,1679,1612, +1679,1613,1680, +1614,1680,1613, +1680,1614,1681, +1615,1681,1614, +1681,1615,1682, +1616,1682,1615, +1682,1616,1683, +1617,1683,1616, +1683,1617,1684, +1618,1684,1617, +1684,1618,1685, +1619,1685,1618, +1685,1619,1686, +1620,1686,1619, +1686,1620,1687, +1621,1687,1620, +1687,1621,1688, +1622,1688,1621, +1688,1622,1689, +1623,1689,1622, +1689,1623,1690, +1624,1690,1623, +1690,1624,1691, +1625,1691,1624, +1691,1625,1692, +1626,1692,1625, +1692,1626,1693, +1627,1693,1626, +1693,1627,1694, +1628,1694,1627, +1694,1628,1695, +1629,1695,1628, +1695,1629,1696, +1630,1696,1629, +1696,1630,1697, +1631,1697,1630, +1697,1631,1698, +1632,1698,1631, +1698,1632,1699, +1633,1699,1632, +1699,1633,1700, +1634,1700,1633, +1700,1634,1701, +1635,1701,1634, +1701,1635,1702, +1636,1702,1635, +1702,1636,1703, +1637,1703,1636, +1703,1637,1704, +1638,1704,1637, +1704,1638,1705, +1639,1705,1638, +1705,1639,1706, +1640,1706,1639, +1706,1640,1707, +1641,1707,1640, +1707,1641,1708, +1642,1708,1641, +1708,1642,1709, +1643,1709,1642, +1709,1643,1710, +1644,1710,1643, +1710,1644,1711, +1645,1711,1644, +1711,1645,1712, +1646,1712,1645, +1712,1646,1713, +1647,1713,1646, +1713,1647,1714, +1648,1714,1647, +1714,1648,1715, +1649,1715,1648, +1716,1650,1717, +1651,1717,1650, +1717,1651,1718, +1652,1718,1651, +1718,1652,1719, +1653,1719,1652, +1719,1653,1720, +1654,1720,1653, +1720,1654,1721, +1655,1721,1654, +1721,1655,1722, +1656,1722,1655, +1722,1656,1723, +1657,1723,1656, +1723,1657,1724, +1658,1724,1657, +1724,1658,1725, +1659,1725,1658, +1725,1659,1726, +1660,1726,1659, +1726,1660,1727, +1661,1727,1660, +1727,1661,1728, +1662,1728,1661, +1728,1662,1729, +1663,1729,1662, +1729,1663,1730, +1664,1730,1663, +1730,1664,1731, +1665,1731,1664, +1731,1665,1732, +1666,1732,1665, +1732,1666,1733, +1667,1733,1666, +1733,1667,1734, +1668,1734,1667, +1734,1668,1735, +1669,1735,1668, +1735,1669,1736, +1670,1736,1669, +1736,1670,1737, +1671,1737,1670, +1737,1671,1738, +1672,1738,1671, +1738,1672,1739, +1673,1739,1672, +1739,1673,1740, +1674,1740,1673, +1740,1674,1741, +1675,1741,1674, +1741,1675,1742, +1676,1742,1675, +1742,1676,1743, +1677,1743,1676, +1743,1677,1744, +1678,1744,1677, +1744,1678,1745, +1679,1745,1678, +1745,1679,1746, +1680,1746,1679, +1746,1680,1747, +1681,1747,1680, +1747,1681,1748, +1682,1748,1681, +1748,1682,1749, +1683,1749,1682, +1749,1683,1750, +1684,1750,1683, +1750,1684,1751, +1685,1751,1684, +1751,1685,1752, +1686,1752,1685, +1752,1686,1753, +1687,1753,1686, +1753,1687,1754, +1688,1754,1687, +1754,1688,1755, +1689,1755,1688, +1755,1689,1756, +1690,1756,1689, +1756,1690,1757, +1691,1757,1690, +1757,1691,1758, +1692,1758,1691, +1758,1692,1759, +1693,1759,1692, +1759,1693,1760, +1694,1760,1693, +1760,1694,1761, +1695,1761,1694, +1761,1695,1762, +1696,1762,1695, +1762,1696,1763, +1697,1763,1696, +1763,1697,1764, +1698,1764,1697, +1764,1698,1765, +1699,1765,1698, +1765,1699,1766, +1700,1766,1699, +1766,1700,1767, +1701,1767,1700, +1767,1701,1768, +1702,1768,1701, +1768,1702,1769, +1703,1769,1702, +1769,1703,1770, +1704,1770,1703, +1770,1704,1771, +1705,1771,1704, +1771,1705,1772, +1706,1772,1705, +1772,1706,1773, +1707,1773,1706, +1773,1707,1774, +1708,1774,1707, +1774,1708,1775, +1709,1775,1708, +1775,1709,1776, +1710,1776,1709, +1776,1710,1777, +1711,1777,1710, +1777,1711,1778, +1712,1778,1711, +1778,1712,1779, +1713,1779,1712, +1779,1713,1780, +1714,1780,1713, +1780,1714,1781, +1715,1781,1714, +1782,1716,1783, +1717,1783,1716, +1783,1717,1784, +1718,1784,1717, +1784,1718,1785, +1719,1785,1718, +1785,1719,1786, +1720,1786,1719, +1786,1720,1787, +1721,1787,1720, +1787,1721,1788, +1722,1788,1721, +1788,1722,1789, +1723,1789,1722, +1789,1723,1790, +1724,1790,1723, +1790,1724,1791, +1725,1791,1724, +1791,1725,1792, +1726,1792,1725, +1792,1726,1793, +1727,1793,1726, +1793,1727,1794, +1728,1794,1727, +1794,1728,1795, +1729,1795,1728, +1795,1729,1796, +1730,1796,1729, +1796,1730,1797, +1731,1797,1730, +1797,1731,1798, +1732,1798,1731, +1798,1732,1799, +1733,1799,1732, +1799,1733,1800, +1734,1800,1733, +1800,1734,1801, +1735,1801,1734, +1801,1735,1802, +1736,1802,1735, +1802,1736,1803, +1737,1803,1736, +1803,1737,1804, +1738,1804,1737, +1804,1738,1805, +1739,1805,1738, +1805,1739,1806, +1740,1806,1739, +1806,1740,1807, +1741,1807,1740, +1807,1741,1808, +1742,1808,1741, +1808,1742,1809, +1743,1809,1742, +1809,1743,1810, +1744,1810,1743, +1810,1744,1811, +1745,1811,1744, +1811,1745,1812, +1746,1812,1745, +1812,1746,1813, +1747,1813,1746, +1813,1747,1814, +1748,1814,1747, +1814,1748,1815, +1749,1815,1748, +1815,1749,1816, +1750,1816,1749, +1816,1750,1817, +1751,1817,1750, +1817,1751,1818, +1752,1818,1751, +1818,1752,1819, +1753,1819,1752, +1819,1753,1820, +1754,1820,1753, +1820,1754,1821, +1755,1821,1754, +1821,1755,1822, +1756,1822,1755, +1822,1756,1823, +1757,1823,1756, +1823,1757,1824, +1758,1824,1757, +1824,1758,1825, +1759,1825,1758, +1825,1759,1826, +1760,1826,1759, +1826,1760,1827, +1761,1827,1760, +1827,1761,1828, +1762,1828,1761, +1828,1762,1829, +1763,1829,1762, +1829,1763,1830, +1764,1830,1763, +1830,1764,1831, +1765,1831,1764, +1831,1765,1832, +1766,1832,1765, +1832,1766,1833, +1767,1833,1766, +1833,1767,1834, +1768,1834,1767, +1834,1768,1835, +1769,1835,1768, +1835,1769,1836, +1770,1836,1769, +1836,1770,1837, +1771,1837,1770, +1837,1771,1838, +1772,1838,1771, +1838,1772,1839, +1773,1839,1772, +1839,1773,1840, +1774,1840,1773, +1840,1774,1841, +1775,1841,1774, +1841,1775,1842, +1776,1842,1775, +1842,1776,1843, +1777,1843,1776, +1843,1777,1844, +1778,1844,1777, +1844,1778,1845, +1779,1845,1778, +1845,1779,1846, +1780,1846,1779, +1846,1780,1847, +1781,1847,1780, +1848,1782,1849, +1783,1849,1782, +1849,1783,1850, +1784,1850,1783, +1850,1784,1851, +1785,1851,1784, +1851,1785,1852, +1786,1852,1785, +1852,1786,1853, +1787,1853,1786, +1853,1787,1854, +1788,1854,1787, +1854,1788,1855, +1789,1855,1788, +1855,1789,1856, +1790,1856,1789, +1856,1790,1857, +1791,1857,1790, +1857,1791,1858, +1792,1858,1791, +1858,1792,1859, +1793,1859,1792, +1859,1793,1860, +1794,1860,1793, +1860,1794,1861, +1795,1861,1794, +1861,1795,1862, +1796,1862,1795, +1862,1796,1863, +1797,1863,1796, +1863,1797,1864, +1798,1864,1797, +1864,1798,1865, +1799,1865,1798, +1865,1799,1866, +1800,1866,1799, +1866,1800,1867, +1801,1867,1800, +1867,1801,1868, +1802,1868,1801, +1868,1802,1869, +1803,1869,1802, +1869,1803,1870, +1804,1870,1803, +1870,1804,1871, +1805,1871,1804, +1871,1805,1872, +1806,1872,1805, +1872,1806,1873, +1807,1873,1806, +1873,1807,1874, +1808,1874,1807, +1874,1808,1875, +1809,1875,1808, +1875,1809,1876, +1810,1876,1809, +1876,1810,1877, +1811,1877,1810, +1877,1811,1878, +1812,1878,1811, +1878,1812,1879, +1813,1879,1812, +1879,1813,1880, +1814,1880,1813, +1880,1814,1881, +1815,1881,1814, +1881,1815,1882, +1816,1882,1815, +1882,1816,1883, +1817,1883,1816, +1883,1817,1884, +1818,1884,1817, +1884,1818,1885, +1819,1885,1818, +1885,1819,1886, +1820,1886,1819, +1886,1820,1887, +1821,1887,1820, +1887,1821,1888, +1822,1888,1821, +1888,1822,1889, +1823,1889,1822, +1889,1823,1890, +1824,1890,1823, +1890,1824,1891, +1825,1891,1824, +1891,1825,1892, +1826,1892,1825, +1892,1826,1893, +1827,1893,1826, +1893,1827,1894, +1828,1894,1827, +1894,1828,1895, +1829,1895,1828, +1895,1829,1896, +1830,1896,1829, +1896,1830,1897, +1831,1897,1830, +1897,1831,1898, +1832,1898,1831, +1898,1832,1899, +1833,1899,1832, +1899,1833,1900, +1834,1900,1833, +1900,1834,1901, +1835,1901,1834, +1901,1835,1902, +1836,1902,1835, +1902,1836,1903, +1837,1903,1836, +1903,1837,1904, +1838,1904,1837, +1904,1838,1905, +1839,1905,1838, +1905,1839,1906, +1840,1906,1839, +1906,1840,1907, +1841,1907,1840, +1907,1841,1908, +1842,1908,1841, +1908,1842,1909, +1843,1909,1842, +1909,1843,1910, +1844,1910,1843, +1910,1844,1911, +1845,1911,1844, +1911,1845,1912, +1846,1912,1845, +1912,1846,1913, +1847,1913,1846, +1914,1848,1915, +1849,1915,1848, +1915,1849,1916, +1850,1916,1849, +1916,1850,1917, +1851,1917,1850, +1917,1851,1918, +1852,1918,1851, +1918,1852,1919, +1853,1919,1852, +1919,1853,1920, +1854,1920,1853, +1920,1854,1921, +1855,1921,1854, +1921,1855,1922, +1856,1922,1855, +1922,1856,1923, +1857,1923,1856, +1923,1857,1924, +1858,1924,1857, +1924,1858,1925, +1859,1925,1858, +1925,1859,1926, +1860,1926,1859, +1926,1860,1927, +1861,1927,1860, +1927,1861,1928, +1862,1928,1861, +1928,1862,1929, +1863,1929,1862, +1929,1863,1930, +1864,1930,1863, +1930,1864,1931, +1865,1931,1864, +1931,1865,1932, +1866,1932,1865, +1932,1866,1933, +1867,1933,1866, +1933,1867,1934, +1868,1934,1867, +1934,1868,1935, +1869,1935,1868, +1935,1869,1936, +1870,1936,1869, +1936,1870,1937, +1871,1937,1870, +1937,1871,1938, +1872,1938,1871, +1938,1872,1939, +1873,1939,1872, +1939,1873,1940, +1874,1940,1873, +1940,1874,1941, +1875,1941,1874, +1941,1875,1942, +1876,1942,1875, +1942,1876,1943, +1877,1943,1876, +1943,1877,1944, +1878,1944,1877, +1944,1878,1945, +1879,1945,1878, +1945,1879,1946, +1880,1946,1879, +1946,1880,1947, +1881,1947,1880, +1947,1881,1948, +1882,1948,1881, +1948,1882,1949, +1883,1949,1882, +1949,1883,1950, +1884,1950,1883, +1950,1884,1951, +1885,1951,1884, +1951,1885,1952, +1886,1952,1885, +1952,1886,1953, +1887,1953,1886, +1953,1887,1954, +1888,1954,1887, +1954,1888,1955, +1889,1955,1888, +1955,1889,1956, +1890,1956,1889, +1956,1890,1957, +1891,1957,1890, +1957,1891,1958, +1892,1958,1891, +1958,1892,1959, +1893,1959,1892, +1959,1893,1960, +1894,1960,1893, +1960,1894,1961, +1895,1961,1894, +1961,1895,1962, +1896,1962,1895, +1962,1896,1963, +1897,1963,1896, +1963,1897,1964, +1898,1964,1897, +1964,1898,1965, +1899,1965,1898, +1965,1899,1966, +1900,1966,1899, +1966,1900,1967, +1901,1967,1900, +1967,1901,1968, +1902,1968,1901, +1968,1902,1969, +1903,1969,1902, +1969,1903,1970, +1904,1970,1903, +1970,1904,1971, +1905,1971,1904, +1971,1905,1972, +1906,1972,1905, +1972,1906,1973, +1907,1973,1906, +1973,1907,1974, +1908,1974,1907, +1974,1908,1975, +1909,1975,1908, +1975,1909,1976, +1910,1976,1909, +1976,1910,1977, +1911,1977,1910, +1977,1911,1978, +1912,1978,1911, +1978,1912,1979, +1913,1979,1912, +1980,1914,1981, +1915,1981,1914, +1981,1915,1982, +1916,1982,1915, +1982,1916,1983, +1917,1983,1916, +1983,1917,1984, +1918,1984,1917, +1984,1918,1985, +1919,1985,1918, +1985,1919,1986, +1920,1986,1919, +1986,1920,1987, +1921,1987,1920, +1987,1921,1988, +1922,1988,1921, +1988,1922,1989, +1923,1989,1922, +1989,1923,1990, +1924,1990,1923, +1990,1924,1991, +1925,1991,1924, +1991,1925,1992, +1926,1992,1925, +1992,1926,1993, +1927,1993,1926, +1993,1927,1994, +1928,1994,1927, +1994,1928,1995, +1929,1995,1928, +1995,1929,1996, +1930,1996,1929, +1996,1930,1997, +1931,1997,1930, +1997,1931,1998, +1932,1998,1931, +1998,1932,1999, +1933,1999,1932, +1999,1933,2000, +1934,2000,1933, +2000,1934,2001, +1935,2001,1934, +2001,1935,2002, +1936,2002,1935, +2002,1936,2003, +1937,2003,1936, +2003,1937,2004, +1938,2004,1937, +2004,1938,2005, +1939,2005,1938, +2005,1939,2006, +1940,2006,1939, +2006,1940,2007, +1941,2007,1940, +2007,1941,2008, +1942,2008,1941, +2008,1942,2009, +1943,2009,1942, +2009,1943,2010, +1944,2010,1943, +2010,1944,2011, +1945,2011,1944, +2011,1945,2012, +1946,2012,1945, +2012,1946,2013, +1947,2013,1946, +2013,1947,2014, +1948,2014,1947, +2014,1948,2015, +1949,2015,1948, +2015,1949,2016, +1950,2016,1949, +2016,1950,2017, +1951,2017,1950, +2017,1951,2018, +1952,2018,1951, +2018,1952,2019, +1953,2019,1952, +2019,1953,2020, +1954,2020,1953, +2020,1954,2021, +1955,2021,1954, +2021,1955,2022, +1956,2022,1955, +2022,1956,2023, +1957,2023,1956, +2023,1957,2024, +1958,2024,1957, +2024,1958,2025, +1959,2025,1958, +2025,1959,2026, +1960,2026,1959, +2026,1960,2027, +1961,2027,1960, +2027,1961,2028, +1962,2028,1961, +2028,1962,2029, +1963,2029,1962, +2029,1963,2030, +1964,2030,1963, +2030,1964,2031, +1965,2031,1964, +2031,1965,2032, +1966,2032,1965, +2032,1966,2033, +1967,2033,1966, +2033,1967,2034, +1968,2034,1967, +2034,1968,2035, +1969,2035,1968, +2035,1969,2036, +1970,2036,1969, +2036,1970,2037, +1971,2037,1970, +2037,1971,2038, +1972,2038,1971, +2038,1972,2039, +1973,2039,1972, +2039,1973,2040, +1974,2040,1973, +2040,1974,2041, +1975,2041,1974, +2041,1975,2042, +1976,2042,1975, +2042,1976,2043, +1977,2043,1976, +2043,1977,2044, +1978,2044,1977, +2044,1978,2045, +1979,2045,1978, +2046,1980,2047, +1981,2047,1980, +2047,1981,2048, +1982,2048,1981, +2048,1982,2049, +1983,2049,1982, +2049,1983,2050, +1984,2050,1983, +2050,1984,2051, +1985,2051,1984, +2051,1985,2052, +1986,2052,1985, +2052,1986,2053, +1987,2053,1986, +2053,1987,2054, +1988,2054,1987, +2054,1988,2055, +1989,2055,1988, +2055,1989,2056, +1990,2056,1989, +2056,1990,2057, +1991,2057,1990, +2057,1991,2058, +1992,2058,1991, +2058,1992,2059, +1993,2059,1992, +2059,1993,2060, +1994,2060,1993, +2060,1994,2061, +1995,2061,1994, +2061,1995,2062, +1996,2062,1995, +2062,1996,2063, +1997,2063,1996, +2063,1997,2064, +1998,2064,1997, +2064,1998,2065, +1999,2065,1998, +2065,1999,2066, +2000,2066,1999, +2066,2000,2067, +2001,2067,2000, +2067,2001,2068, +2002,2068,2001, +2068,2002,2069, +2003,2069,2002, +2069,2003,2070, +2004,2070,2003, +2070,2004,2071, +2005,2071,2004, +2071,2005,2072, +2006,2072,2005, +2072,2006,2073, +2007,2073,2006, +2073,2007,2074, +2008,2074,2007, +2074,2008,2075, +2009,2075,2008, +2075,2009,2076, +2010,2076,2009, +2076,2010,2077, +2011,2077,2010, +2077,2011,2078, +2012,2078,2011, +2078,2012,2079, +2013,2079,2012, +2079,2013,2080, +2014,2080,2013, +2080,2014,2081, +2015,2081,2014, +2081,2015,2082, +2016,2082,2015, +2082,2016,2083, +2017,2083,2016, +2083,2017,2084, +2018,2084,2017, +2084,2018,2085, +2019,2085,2018, +2085,2019,2086, +2020,2086,2019, +2086,2020,2087, +2021,2087,2020, +2087,2021,2088, +2022,2088,2021, +2088,2022,2089, +2023,2089,2022, +2089,2023,2090, +2024,2090,2023, +2090,2024,2091, +2025,2091,2024, +2091,2025,2092, +2026,2092,2025, +2092,2026,2093, +2027,2093,2026, +2093,2027,2094, +2028,2094,2027, +2094,2028,2095, +2029,2095,2028, +2095,2029,2096, +2030,2096,2029, +2096,2030,2097, +2031,2097,2030, +2097,2031,2098, +2032,2098,2031, +2098,2032,2099, +2033,2099,2032, +2099,2033,2100, +2034,2100,2033, +2100,2034,2101, +2035,2101,2034, +2101,2035,2102, +2036,2102,2035, +2102,2036,2103, +2037,2103,2036, +2103,2037,2104, +2038,2104,2037, +2104,2038,2105, +2039,2105,2038, +2105,2039,2106, +2040,2106,2039, +2106,2040,2107, +2041,2107,2040, +2107,2041,2108, +2042,2108,2041, +2108,2042,2109, +2043,2109,2042, +2109,2043,2110, +2044,2110,2043, +2110,2044,2111, +2045,2111,2044, +2112,2046,2113, +2047,2113,2046, +2113,2047,2114, +2048,2114,2047, +2114,2048,2115, +2049,2115,2048, +2115,2049,2116, +2050,2116,2049, +2116,2050,2117, +2051,2117,2050, +2117,2051,2118, +2052,2118,2051, +2118,2052,2119, +2053,2119,2052, +2119,2053,2120, +2054,2120,2053, +2120,2054,2121, +2055,2121,2054, +2121,2055,2122, +2056,2122,2055, +2122,2056,2123, +2057,2123,2056, +2123,2057,2124, +2058,2124,2057, +2124,2058,2125, +2059,2125,2058, +2125,2059,2126, +2060,2126,2059, +2126,2060,2127, +2061,2127,2060, +2127,2061,2128, +2062,2128,2061, +2128,2062,2129, +2063,2129,2062, +2129,2063,2130, +2064,2130,2063, +2130,2064,2131, +2065,2131,2064, +2131,2065,2132, +2066,2132,2065, +2132,2066,2133, +2067,2133,2066, +2133,2067,2134, +2068,2134,2067, +2134,2068,2135, +2069,2135,2068, +2135,2069,2136, +2070,2136,2069, +2136,2070,2137, +2071,2137,2070, +2137,2071,2138, +2072,2138,2071, +2138,2072,2139, +2073,2139,2072, +2139,2073,2140, +2074,2140,2073, +2140,2074,2141, +2075,2141,2074, +2141,2075,2142, +2076,2142,2075, +2142,2076,2143, +2077,2143,2076, +2143,2077,2144, +2078,2144,2077, +2144,2078,2145, +2079,2145,2078, +2145,2079,2146, +2080,2146,2079, +2146,2080,2147, +2081,2147,2080, +2147,2081,2148, +2082,2148,2081, +2148,2082,2149, +2083,2149,2082, +2149,2083,2150, +2084,2150,2083, +2150,2084,2151, +2085,2151,2084, +2151,2085,2152, +2086,2152,2085, +2152,2086,2153, +2087,2153,2086, +2153,2087,2154, +2088,2154,2087, +2154,2088,2155, +2089,2155,2088, +2155,2089,2156, +2090,2156,2089, +2156,2090,2157, +2091,2157,2090, +2157,2091,2158, +2092,2158,2091, +2158,2092,2159, +2093,2159,2092, +2159,2093,2160, +2094,2160,2093, +2160,2094,2161, +2095,2161,2094, +2161,2095,2162, +2096,2162,2095, +2162,2096,2163, +2097,2163,2096, +2163,2097,2164, +2098,2164,2097, +2164,2098,2165, +2099,2165,2098, +2165,2099,2166, +2100,2166,2099, +2166,2100,2167, +2101,2167,2100, +2167,2101,2168, +2102,2168,2101, +2168,2102,2169, +2103,2169,2102, +2169,2103,2170, +2104,2170,2103, +2170,2104,2171, +2105,2171,2104, +2171,2105,2172, +2106,2172,2105, +2172,2106,2173, +2107,2173,2106, +2173,2107,2174, +2108,2174,2107, +2174,2108,2175, +2109,2175,2108, +2175,2109,2176, +2110,2176,2109, +2176,2110,2177, +2111,2177,2110, +2178,2112,2179, +2113,2179,2112, +2179,2113,2180, +2114,2180,2113, +2180,2114,2181, +2115,2181,2114, +2181,2115,2182, +2116,2182,2115, +2182,2116,2183, +2117,2183,2116, +2183,2117,2184, +2118,2184,2117, +2184,2118,2185, +2119,2185,2118, +2185,2119,2186, +2120,2186,2119, +2186,2120,2187, +2121,2187,2120, +2187,2121,2188, +2122,2188,2121, +2188,2122,2189, +2123,2189,2122, +2189,2123,2190, +2124,2190,2123, +2190,2124,2191, +2125,2191,2124, +2191,2125,2192, +2126,2192,2125, +2192,2126,2193, +2127,2193,2126, +2193,2127,2194, +2128,2194,2127, +2194,2128,2195, +2129,2195,2128, +2195,2129,2196, +2130,2196,2129, +2196,2130,2197, +2131,2197,2130, +2197,2131,2198, +2132,2198,2131, +2198,2132,2199, +2133,2199,2132, +2199,2133,2200, +2134,2200,2133, +2200,2134,2201, +2135,2201,2134, +2201,2135,2202, +2136,2202,2135, +2202,2136,2203, +2137,2203,2136, +2203,2137,2204, +2138,2204,2137, +2204,2138,2205, +2139,2205,2138, +2205,2139,2206, +2140,2206,2139, +2206,2140,2207, +2141,2207,2140, +2207,2141,2208, +2142,2208,2141, +2208,2142,2209, +2143,2209,2142, +2209,2143,2210, +2144,2210,2143, +2210,2144,2211, +2145,2211,2144, +2211,2145,2212, +2146,2212,2145, +2212,2146,2213, +2147,2213,2146, +2213,2147,2214, +2148,2214,2147, +2214,2148,2215, +2149,2215,2148, +2215,2149,2216, +2150,2216,2149, +2216,2150,2217, +2151,2217,2150, +2217,2151,2218, +2152,2218,2151, +2218,2152,2219, +2153,2219,2152, +2219,2153,2220, +2154,2220,2153, +2220,2154,2221, +2155,2221,2154, +2221,2155,2222, +2156,2222,2155, +2222,2156,2223, +2157,2223,2156, +2223,2157,2224, +2158,2224,2157, +2224,2158,2225, +2159,2225,2158, +2225,2159,2226, +2160,2226,2159, +2226,2160,2227, +2161,2227,2160, +2227,2161,2228, +2162,2228,2161, +2228,2162,2229, +2163,2229,2162, +2229,2163,2230, +2164,2230,2163, +2230,2164,2231, +2165,2231,2164, +2231,2165,2232, +2166,2232,2165, +2232,2166,2233, +2167,2233,2166, +2233,2167,2234, +2168,2234,2167, +2234,2168,2235, +2169,2235,2168, +2235,2169,2236, +2170,2236,2169, +2236,2170,2237, +2171,2237,2170, +2237,2171,2238, +2172,2238,2171, +2238,2172,2239, +2173,2239,2172, +2239,2173,2240, +2174,2240,2173, +2240,2174,2241, +2175,2241,2174, +2241,2175,2242, +2176,2242,2175, +2242,2176,2243, +2177,2243,2176, +}; + +#define Landscape06VtxCount 2310 +#define Landscape06IdxCount 13260 + +btScalar Landscape06Vtx[] = { +-250.0f,5.63631f,246.094f, +-250.0f,8.1152f,250.0f, +-246.094f,7.06461f,246.094f, +-246.094f,9.72778f,250.0f, +-242.188f,9.8471f,246.094f, +-242.188f,11.659f,250.0f, +-238.281f,12.8404f,246.094f, +-238.281f,12.5619f,250.0f, +-234.375f,13.9879f,246.094f, +-234.375f,12.9518f,250.0f, +-230.469f,15.7239f,246.094f, +-230.469f,15.1373f,250.0f, +-226.563f,17.5095f,246.094f, +-226.563f,17.0421f,250.0f, +-222.656f,18.4322f,246.094f, +-222.656f,17.9919f,250.0f, +-218.75f,19.0755f,246.094f, +-218.75f,18.7918f,250.0f, +-214.844f,19.9271f,246.094f, +-214.844f,19.5719f,250.0f, +-210.938f,19.7244f,246.094f, +-210.938f,20.0866f,250.0f, +-207.031f,18.9716f,246.094f, +-207.031f,19.7869f,250.0f, +-203.125f,19.1922f,246.094f, +-203.125f,20.0264f,250.0f, +-199.219f,17.8506f,246.094f, +-199.219f,19.3207f,250.0f, +-195.313f,15.238f,246.094f, +-195.313f,18.0244f,250.0f, +-191.406f,14.6904f,246.094f, +-191.406f,16.2939f,250.0f, +-187.5f,12.9803f,246.094f, +-187.5f,14.9619f,250.0f, +-183.594f,11.6545f,246.094f, +-183.594f,12.6676f,250.0f, +-179.688f,12.4631f,246.094f, +-179.688f,13.6712f,250.0f, +-175.781f,13.1206f,246.094f, +-175.781f,14.5417f,250.0f, +-171.875f,13.3105f,246.094f, +-171.875f,15.8974f,250.0f, +-167.969f,13.4543f,246.094f, +-167.969f,15.9641f,250.0f, +-164.063f,13.4505f,246.094f, +-164.063f,15.4826f,250.0f, +-160.156f,14.6873f,246.094f, +-160.156f,15.1093f,250.0f, +-156.25f,14.1623f,246.094f, +-156.25f,14.8119f,250.0f, +-152.344f,14.0111f,246.094f, +-152.344f,14.4017f,250.0f, +-148.438f,13.2014f,246.094f, +-148.438f,14.2916f,250.0f, +-144.531f,12.8662f,246.094f, +-144.531f,13.5685f,250.0f, +-140.625f,13.1721f,246.094f, +-140.625f,14.2972f,250.0f, +-136.719f,12.9479f,246.094f, +-136.719f,15.0727f,250.0f, +-132.813f,13.4221f,246.094f, +-132.813f,14.5344f,250.0f, +-128.906f,14.0862f,246.094f, +-128.906f,15.7145f,250.0f, +-125.0f,13.481f,246.094f, +-125.0f,15.4608f,250.0f, +-121.094f,12.6228f,246.094f, +-121.094f,15.1857f,250.0f, +-117.188f,12.0584f,246.094f, +-117.188f,15.444f,250.0f, +-113.281f,12.7173f,246.094f, +-113.281f,15.8882f,250.0f, +-109.375f,12.3498f,246.094f, +-109.375f,15.2023f,250.0f, +-105.469f,13.0125f,246.094f, +-105.469f,15.1747f,250.0f, +-101.563f,13.7023f,246.094f, +-101.563f,14.7499f,250.0f, +-97.6563f,14.0674f,246.094f, +-97.6563f,15.0991f,250.0f, +-93.75f,13.8437f,246.094f, +-93.75f,14.6676f,250.0f, +-89.8438f,14.6327f,246.094f, +-89.8438f,14.1527f,250.0f, +-85.9375f,13.2966f,246.094f, +-85.9375f,14.0388f,250.0f, +-82.0313f,12.8094f,246.094f, +-82.0313f,13.7786f,250.0f, +-78.125f,11.8006f,246.094f, +-78.125f,13.0685f,250.0f, +-74.2188f,11.6837f,246.094f, +-74.2188f,12.8361f,250.0f, +-70.3125f,11.0326f,246.094f, +-70.3125f,12.3629f,250.0f, +-66.4063f,11.893f,246.094f, +-66.4063f,11.1909f,250.0f, +-62.5f,10.6469f,246.094f, +-62.5f,9.92966f,250.0f, +-58.5938f,8.55287f,246.094f, +-58.5938f,8.8871f,250.0f, +-54.6875f,7.1029f,246.094f, +-54.6875f,7.4963f,250.0f, +-50.7813f,6.9758f,246.094f, +-50.7813f,6.23897f,250.0f, +-46.875f,7.98262f,246.094f, +-46.875f,6.88918f,250.0f, +-42.9688f,9.11554f,246.094f, +-42.9688f,7.29319f,250.0f, +-39.0625f,8.74373f,246.094f, +-39.0625f,6.89167f,250.0f, +-35.1563f,7.46275f,246.094f, +-35.1563f,6.659f,250.0f, +-31.25f,7.67626f,246.094f, +-31.25f,6.75404f,250.0f, +-27.3438f,7.00511f,246.094f, +-27.3438f,6.15573f,250.0f, +-23.4375f,5.63813f,246.094f, +-23.4375f,5.72737f,250.0f, +-19.5313f,5.11885f,246.094f, +-19.5313f,4.00822f,250.0f, +-15.625f,3.60038f,246.094f, +-15.625f,3.50471f,250.0f, +-11.7188f,3.05357f,246.094f, +-11.7188f,3.0992f,250.0f, +-7.8125f,2.48195f,246.094f, +-7.8125f,2.46052f,250.0f, +-3.90625f,1.69136f,246.094f, +-3.90625f,2.5505f,250.0f, +0.0f,1.14548f,246.094f, +0.0f,2.18079f,250.0f, +3.90625f,0.45291f,246.094f, +3.90625f,1.52302f,250.0f, +-250.0f,5.2159f,242.188f, +-246.094f,7.35218f,242.188f, +-242.188f,10.2284f,242.188f, +-238.281f,12.7552f,242.188f, +-234.375f,14.3317f,242.188f, +-230.469f,16.3594f,242.188f, +-226.563f,17.8216f,242.188f, +-222.656f,18.5321f,242.188f, +-218.75f,18.7578f,242.188f, +-214.844f,19.504f,242.188f, +-210.938f,18.9422f,242.188f, +-207.031f,17.9771f,242.188f, +-203.125f,17.2798f,242.188f, +-199.219f,15.2252f,242.188f, +-195.313f,13.8769f,242.188f, +-191.406f,12.8727f,242.188f, +-187.5f,11.7858f,242.188f, +-183.594f,12.4886f,242.188f, +-179.688f,12.9814f,242.188f, +-175.781f,13.5265f,242.188f, +-171.875f,13.8082f,242.188f, +-167.969f,13.8407f,242.188f, +-164.063f,13.5872f,242.188f, +-160.156f,13.8287f,242.188f, +-156.25f,13.5778f,242.188f, +-152.344f,13.0026f,242.188f, +-148.438f,12.6259f,242.188f, +-144.531f,12.4666f,242.188f, +-140.625f,12.634f,242.188f, +-136.719f,12.1746f,242.188f, +-132.813f,11.7885f,242.188f, +-128.906f,11.4539f,242.188f, +-125.0f,11.0084f,242.188f, +-121.094f,10.1521f,242.188f, +-117.188f,10.6008f,242.188f, +-113.281f,10.2088f,242.188f, +-109.375f,11.0344f,242.188f, +-105.469f,11.1441f,242.188f, +-101.563f,12.3959f,242.188f, +-97.6563f,13.3587f,242.188f, +-93.75f,14.2415f,242.188f, +-89.8438f,13.9809f,242.188f, +-85.9375f,13.3276f,242.188f, +-82.0313f,11.9639f,242.188f, +-78.125f,11.5863f,242.188f, +-74.2188f,11.7327f,242.188f, +-70.3125f,11.5527f,242.188f, +-66.4063f,12.3699f,242.188f, +-62.5f,11.1959f,242.188f, +-58.5938f,9.59967f,242.188f, +-54.6875f,8.38887f,242.188f, +-50.7813f,7.42613f,242.188f, +-46.875f,8.34697f,242.188f, +-42.9688f,9.7013f,242.188f, +-39.0625f,9.10668f,242.188f, +-35.1563f,8.24657f,242.188f, +-31.25f,8.06656f,242.188f, +-27.3438f,6.98555f,242.188f, +-23.4375f,6.88836f,242.188f, +-19.5313f,5.88079f,242.188f, +-15.625f,4.43148f,242.188f, +-11.7188f,3.65843f,242.188f, +-7.8125f,2.85687f,242.188f, +-3.90625f,1.8332f,242.188f, +0.0f,2.03971f,242.188f, +3.90625f,2.21488f,242.188f, +-250.0f,5.44463f,238.281f, +-246.094f,7.90885f,238.281f, +-242.188f,10.3908f,238.281f, +-238.281f,12.875f,238.281f, +-234.375f,14.8255f,238.281f, +-230.469f,16.5404f,238.281f, +-226.563f,17.8109f,238.281f, +-222.656f,19.0205f,238.281f, +-218.75f,18.7565f,238.281f, +-214.844f,18.9852f,238.281f, +-210.938f,18.3753f,238.281f, +-207.031f,16.6829f,238.281f, +-203.125f,15.8099f,238.281f, +-199.219f,13.2915f,238.281f, +-195.313f,13.447f,238.281f, +-191.406f,13.5971f,238.281f, +-187.5f,12.1473f,238.281f, +-183.594f,13.3531f,238.281f, +-179.688f,14.4732f,238.281f, +-175.781f,15.0267f,238.281f, +-171.875f,14.7852f,238.281f, +-167.969f,15.5706f,238.281f, +-164.063f,14.267f,238.281f, +-160.156f,14.0772f,238.281f, +-156.25f,12.4965f,238.281f, +-152.344f,12.1473f,238.281f, +-148.438f,11.8693f,238.281f, +-144.531f,11.2795f,238.281f, +-140.625f,10.8173f,238.281f, +-136.719f,10.792f,238.281f, +-132.813f,10.8481f,238.281f, +-128.906f,9.95928f,238.281f, +-125.0f,10.0976f,238.281f, +-121.094f,8.74444f,238.281f, +-117.188f,9.1761f,238.281f, +-113.281f,10.2354f,238.281f, +-109.375f,10.7023f,238.281f, +-105.469f,11.6386f,238.281f, +-101.563f,12.7789f,238.281f, +-97.6563f,13.956f,238.281f, +-93.75f,14.1101f,238.281f, +-89.8438f,13.2653f,238.281f, +-85.9375f,12.1604f,238.281f, +-82.0313f,11.6914f,238.281f, +-78.125f,11.3706f,238.281f, +-74.2188f,12.1449f,238.281f, +-70.3125f,12.4512f,238.281f, +-66.4063f,12.6436f,238.281f, +-62.5f,11.6692f,238.281f, +-58.5938f,10.8304f,238.281f, +-54.6875f,8.88158f,238.281f, +-50.7813f,7.94904f,238.281f, +-46.875f,8.47525f,238.281f, +-42.9688f,9.08763f,238.281f, +-39.0625f,9.21095f,238.281f, +-35.1563f,9.12926f,238.281f, +-31.25f,8.5517f,238.281f, +-27.3438f,7.86146f,238.281f, +-23.4375f,7.33662f,238.281f, +-19.5313f,6.37551f,238.281f, +-15.625f,5.59324f,238.281f, +-11.7188f,4.81831f,238.281f, +-7.8125f,4.35695f,238.281f, +-3.90625f,3.64159f,238.281f, +0.0f,3.70314f,238.281f, +3.90625f,3.04396f,238.281f, +-250.0f,5.92848f,234.375f, +-246.094f,8.10446f,234.375f, +-242.188f,10.3516f,234.375f, +-238.281f,12.4984f,234.375f, +-234.375f,15.0991f,234.375f, +-230.469f,16.0002f,234.375f, +-226.563f,17.2585f,234.375f, +-222.656f,18.1852f,234.375f, +-218.75f,18.7811f,234.375f, +-214.844f,18.4638f,234.375f, +-210.938f,18.3171f,234.375f, +-207.031f,16.1085f,234.375f, +-203.125f,15.1926f,234.375f, +-199.219f,14.1792f,234.375f, +-195.313f,13.5589f,234.375f, +-191.406f,13.9362f,234.375f, +-187.5f,13.303f,234.375f, +-183.594f,13.6602f,234.375f, +-179.688f,15.1086f,234.375f, +-175.781f,15.5943f,234.375f, +-171.875f,15.3663f,234.375f, +-167.969f,14.9609f,234.375f, +-164.063f,14.4285f,234.375f, +-160.156f,14.1532f,234.375f, +-156.25f,13.0139f,234.375f, +-152.344f,11.6503f,234.375f, +-148.438f,11.6112f,234.375f, +-144.531f,11.1097f,234.375f, +-140.625f,10.8763f,234.375f, +-136.719f,10.2321f,234.375f, +-132.813f,9.71321f,234.375f, +-128.906f,9.04388f,234.375f, +-125.0f,9.53542f,234.375f, +-121.094f,8.10006f,234.375f, +-117.188f,9.16948f,234.375f, +-113.281f,9.67824f,234.375f, +-109.375f,10.2679f,234.375f, +-105.469f,10.9669f,234.375f, +-101.563f,12.2942f,234.375f, +-97.6563f,13.2952f,234.375f, +-93.75f,13.0932f,234.375f, +-89.8438f,12.4514f,234.375f, +-85.9375f,12.2395f,234.375f, +-82.0313f,11.7622f,234.375f, +-78.125f,11.9666f,234.375f, +-74.2188f,12.2346f,234.375f, +-70.3125f,13.1648f,234.375f, +-66.4063f,13.506f,234.375f, +-62.5f,13.1773f,234.375f, +-58.5938f,11.9168f,234.375f, +-54.6875f,10.0208f,234.375f, +-50.7813f,9.08267f,234.375f, +-46.875f,8.4406f,234.375f, +-42.9688f,9.27515f,234.375f, +-39.0625f,10.2228f,234.375f, +-35.1563f,9.77624f,234.375f, +-31.25f,9.17943f,234.375f, +-27.3438f,8.83272f,234.375f, +-23.4375f,8.00355f,234.375f, +-19.5313f,7.37167f,234.375f, +-15.625f,6.87424f,234.375f, +-11.7188f,6.23994f,234.375f, +-7.8125f,5.50641f,234.375f, +-3.90625f,5.06839f,234.375f, +0.0f,5.06846f,234.375f, +3.90625f,5.19166f,234.375f, +-250.0f,4.98265f,230.469f, +-246.094f,7.878f,230.469f, +-242.188f,10.9188f,230.469f, +-238.281f,12.8549f,230.469f, +-234.375f,14.5578f,230.469f, +-230.469f,16.067f,230.469f, +-226.563f,17.9938f,230.469f, +-222.656f,18.3449f,230.469f, +-218.75f,18.4423f,230.469f, +-214.844f,18.9411f,230.469f, +-210.938f,17.3131f,230.469f, +-207.031f,15.3292f,230.469f, +-203.125f,15.5278f,230.469f, +-199.219f,14.9451f,230.469f, +-195.313f,13.8026f,230.469f, +-191.406f,13.1586f,230.469f, +-187.5f,13.4388f,230.469f, +-183.594f,14.2213f,230.469f, +-179.688f,14.907f,230.469f, +-175.781f,15.2295f,230.469f, +-171.875f,14.8701f,230.469f, +-167.969f,14.1393f,230.469f, +-164.063f,13.7829f,230.469f, +-160.156f,13.0614f,230.469f, +-156.25f,12.3416f,230.469f, +-152.344f,11.5366f,230.469f, +-148.438f,11.5201f,230.469f, +-144.531f,11.0918f,230.469f, +-140.625f,11.139f,230.469f, +-136.719f,10.0387f,230.469f, +-132.813f,8.59099f,230.469f, +-128.906f,7.71771f,230.469f, +-125.0f,7.44273f,230.469f, +-121.094f,8.17087f,230.469f, +-117.188f,8.34002f,230.469f, +-113.281f,9.22169f,230.469f, +-109.375f,10.2195f,230.469f, +-105.469f,11.523f,230.469f, +-101.563f,12.7411f,230.469f, +-97.6563f,12.7429f,230.469f, +-93.75f,12.3959f,230.469f, +-89.8438f,11.7559f,230.469f, +-85.9375f,10.3669f,230.469f, +-82.0313f,10.0825f,230.469f, +-78.125f,11.4451f,230.469f, +-74.2188f,12.235f,230.469f, +-70.3125f,13.6016f,230.469f, +-66.4063f,14.377f,230.469f, +-62.5f,13.967f,230.469f, +-58.5938f,12.862f,230.469f, +-54.6875f,11.4719f,230.469f, +-50.7813f,9.99381f,230.469f, +-46.875f,8.68857f,230.469f, +-42.9688f,9.43448f,230.469f, +-39.0625f,10.4708f,230.469f, +-35.1563f,11.0521f,230.469f, +-31.25f,10.5864f,230.469f, +-27.3438f,10.8331f,230.469f, +-23.4375f,9.96112f,230.469f, +-19.5313f,8.61029f,230.469f, +-15.625f,7.42407f,230.469f, +-11.7188f,6.43202f,230.469f, +-7.8125f,6.36726f,230.469f, +-3.90625f,6.52581f,230.469f, +0.0f,6.18686f,230.469f, +3.90625f,5.885f,230.469f, +-250.0f,4.92227f,226.563f, +-246.094f,8.66811f,226.563f, +-242.188f,11.7599f,226.563f, +-238.281f,13.6581f,226.563f, +-234.375f,15.6409f,226.563f, +-230.469f,16.7907f,226.563f, +-226.563f,17.4606f,226.563f, +-222.656f,18.4841f,226.563f, +-218.75f,18.4506f,226.563f, +-214.844f,17.5936f,226.563f, +-210.938f,16.5941f,226.563f, +-207.031f,14.8805f,226.563f, +-203.125f,15.3743f,226.563f, +-199.219f,15.4493f,226.563f, +-195.313f,14.5184f,226.563f, +-191.406f,12.9285f,226.563f, +-187.5f,13.3898f,226.563f, +-183.594f,14.0358f,226.563f, +-179.688f,15.2884f,226.563f, +-175.781f,14.972f,226.563f, +-171.875f,14.2355f,226.563f, +-167.969f,13.6786f,226.563f, +-164.063f,13.0771f,226.563f, +-160.156f,12.7879f,226.563f, +-156.25f,12.4767f,226.563f, +-152.344f,11.5156f,226.563f, +-148.438f,11.1725f,226.563f, +-144.531f,10.8869f,226.563f, +-140.625f,9.77232f,226.563f, +-136.719f,8.75728f,226.563f, +-132.813f,6.77705f,226.563f, +-128.906f,6.35083f,226.563f, +-125.0f,6.59888f,226.563f, +-121.094f,7.81295f,226.563f, +-117.188f,8.10078f,226.563f, +-113.281f,9.07634f,226.563f, +-109.375f,10.2289f,226.563f, +-105.469f,11.5342f,226.563f, +-101.563f,12.9142f,226.563f, +-97.6563f,12.8729f,226.563f, +-93.75f,12.8149f,226.563f, +-89.8438f,10.9671f,226.563f, +-85.9375f,10.0649f,226.563f, +-82.0313f,9.28012f,226.563f, +-78.125f,10.1324f,226.563f, +-74.2188f,11.8638f,226.563f, +-70.3125f,12.6141f,226.563f, +-66.4063f,13.6851f,226.563f, +-62.5f,13.9389f,226.563f, +-58.5938f,13.5413f,226.563f, +-54.6875f,12.4869f,226.563f, +-50.7813f,11.2774f,226.563f, +-46.875f,10.6009f,226.563f, +-42.9688f,11.4839f,226.563f, +-39.0625f,12.5408f,226.563f, +-35.1563f,12.8694f,226.563f, +-31.25f,12.5253f,226.563f, +-27.3438f,12.1887f,226.563f, +-23.4375f,11.5356f,226.563f, +-19.5313f,9.53151f,226.563f, +-15.625f,8.29811f,226.563f, +-11.7188f,7.38375f,226.563f, +-7.8125f,7.57607f,226.563f, +-3.90625f,7.41156f,226.563f, +0.0f,6.9836f,226.563f, +3.90625f,6.89682f,226.563f, +-250.0f,4.66781f,222.656f, +-246.094f,7.89882f,222.656f, +-242.188f,10.8629f,222.656f, +-238.281f,14.1235f,222.656f, +-234.375f,15.6001f,222.656f, +-230.469f,17.0347f,222.656f, +-226.563f,17.4872f,222.656f, +-222.656f,17.6157f,222.656f, +-218.75f,16.8213f,222.656f, +-214.844f,16.4076f,222.656f, +-210.938f,15.0745f,222.656f, +-207.031f,14.2914f,222.656f, +-203.125f,14.6094f,222.656f, +-199.219f,14.4637f,222.656f, +-195.313f,14.0807f,222.656f, +-191.406f,12.4559f,222.656f, +-187.5f,13.0367f,222.656f, +-183.594f,13.975f,222.656f, +-179.688f,14.802f,222.656f, +-175.781f,14.6145f,222.656f, +-171.875f,13.4733f,222.656f, +-167.969f,13.3385f,222.656f, +-164.063f,13.721f,222.656f, +-160.156f,12.5775f,222.656f, +-156.25f,11.962f,222.656f, +-152.344f,11.2422f,222.656f, +-148.438f,10.827f,222.656f, +-144.531f,10.2848f,222.656f, +-140.625f,8.45922f,222.656f, +-136.719f,7.72182f,222.656f, +-132.813f,6.23545f,222.656f, +-128.906f,5.69752f,222.656f, +-125.0f,6.29925f,222.656f, +-121.094f,7.1991f,222.656f, +-117.188f,7.56788f,222.656f, +-113.281f,8.87895f,222.656f, +-109.375f,9.92302f,222.656f, +-105.469f,10.2628f,222.656f, +-101.563f,11.427f,222.656f, +-97.6563f,12.2929f,222.656f, +-93.75f,11.6083f,222.656f, +-89.8438f,11.594f,222.656f, +-85.9375f,10.1683f,222.656f, +-82.0313f,10.4152f,222.656f, +-78.125f,10.765f,222.656f, +-74.2188f,11.5311f,222.656f, +-70.3125f,12.8761f,222.656f, +-66.4063f,14.8794f,222.656f, +-62.5f,15.7341f,222.656f, +-58.5938f,15.0851f,222.656f, +-54.6875f,14.4719f,222.656f, +-50.7813f,13.6899f,222.656f, +-46.875f,13.0842f,222.656f, +-42.9688f,13.1059f,222.656f, +-39.0625f,13.9942f,222.656f, +-35.1563f,13.8877f,222.656f, +-31.25f,14.1293f,222.656f, +-27.3438f,13.6276f,222.656f, +-23.4375f,12.2206f,222.656f, +-19.5313f,10.8481f,222.656f, +-15.625f,9.71168f,222.656f, +-11.7188f,8.51834f,222.656f, +-7.8125f,9.04274f,222.656f, +-3.90625f,8.46981f,222.656f, +0.0f,8.26045f,222.656f, +3.90625f,6.81349f,222.656f, +-250.0f,5.16984f,218.75f, +-246.094f,6.64731f,218.75f, +-242.188f,9.50207f,218.75f, +-238.281f,12.5115f,218.75f, +-234.375f,15.8009f,218.75f, +-230.469f,17.6139f,218.75f, +-226.563f,18.128f,218.75f, +-222.656f,17.3111f,218.75f, +-218.75f,16.3962f,218.75f, +-214.844f,16.0245f,218.75f, +-210.938f,14.5344f,218.75f, +-207.031f,13.4459f,218.75f, +-203.125f,13.3987f,218.75f, +-199.219f,13.5444f,218.75f, +-195.313f,12.1973f,218.75f, +-191.406f,11.8337f,218.75f, +-187.5f,13.3027f,218.75f, +-183.594f,13.2862f,218.75f, +-179.688f,14.577f,218.75f, +-175.781f,14.4312f,218.75f, +-171.875f,13.3065f,218.75f, +-167.969f,14.2726f,218.75f, +-164.063f,14.5522f,218.75f, +-160.156f,13.8269f,218.75f, +-156.25f,12.4234f,218.75f, +-152.344f,10.5035f,218.75f, +-148.438f,9.65297f,218.75f, +-144.531f,8.3692f,218.75f, +-140.625f,7.39811f,218.75f, +-136.719f,6.29024f,218.75f, +-132.813f,5.37103f,218.75f, +-128.906f,5.29069f,218.75f, +-125.0f,5.59696f,218.75f, +-121.094f,6.15404f,218.75f, +-117.188f,7.15855f,218.75f, +-113.281f,8.08243f,218.75f, +-109.375f,8.97937f,218.75f, +-105.469f,9.67177f,218.75f, +-101.563f,10.7738f,218.75f, +-97.6563f,11.4256f,218.75f, +-93.75f,11.6906f,218.75f, +-89.8438f,11.4527f,218.75f, +-85.9375f,11.5445f,218.75f, +-82.0313f,11.9384f,218.75f, +-78.125f,12.452f,218.75f, +-74.2188f,13.3202f,218.75f, +-70.3125f,14.2351f,218.75f, +-66.4063f,15.021f,218.75f, +-62.5f,16.1053f,218.75f, +-58.5938f,16.0633f,218.75f, +-54.6875f,15.6154f,218.75f, +-50.7813f,15.3347f,218.75f, +-46.875f,14.8984f,218.75f, +-42.9688f,14.1541f,218.75f, +-39.0625f,14.8343f,218.75f, +-35.1563f,14.8393f,218.75f, +-31.25f,14.865f,218.75f, +-27.3438f,13.9913f,218.75f, +-23.4375f,13.7749f,218.75f, +-19.5313f,12.6247f,218.75f, +-15.625f,11.3466f,218.75f, +-11.7188f,10.5048f,218.75f, +-7.8125f,9.94742f,218.75f, +-3.90625f,8.79577f,218.75f, +0.0f,8.31646f,218.75f, +3.90625f,8.02546f,218.75f, +-250.0f,4.42455f,214.844f, +-246.094f,6.15686f,214.844f, +-242.188f,8.4919f,214.844f, +-238.281f,12.2627f,214.844f, +-234.375f,15.9215f,214.844f, +-230.469f,17.6896f,214.844f, +-226.563f,18.1835f,214.844f, +-222.656f,17.9341f,214.844f, +-218.75f,16.9803f,214.844f, +-214.844f,15.6617f,214.844f, +-210.938f,14.3989f,214.844f, +-207.031f,12.7777f,214.844f, +-203.125f,12.7635f,214.844f, +-199.219f,12.8533f,214.844f, +-195.313f,12.1672f,214.844f, +-191.406f,12.2357f,214.844f, +-187.5f,12.5806f,214.844f, +-183.594f,12.5597f,214.844f, +-179.688f,13.6296f,214.844f, +-175.781f,13.8382f,214.844f, +-171.875f,14.4001f,214.844f, +-167.969f,14.3002f,214.844f, +-164.063f,14.3353f,214.844f, +-160.156f,14.0346f,214.844f, +-156.25f,12.9823f,214.844f, +-152.344f,10.8141f,214.844f, +-148.438f,9.57028f,214.844f, +-144.531f,8.18427f,214.844f, +-140.625f,6.89938f,214.844f, +-136.719f,5.79227f,214.844f, +-132.813f,4.60172f,214.844f, +-128.906f,4.59969f,214.844f, +-125.0f,5.20294f,214.844f, +-121.094f,6.17542f,214.844f, +-117.188f,7.13347f,214.844f, +-113.281f,8.1045f,214.844f, +-109.375f,8.73005f,214.844f, +-105.469f,9.96489f,214.844f, +-101.563f,11.1039f,214.844f, +-97.6563f,11.6791f,214.844f, +-93.75f,11.9246f,214.844f, +-89.8438f,12.0071f,214.844f, +-85.9375f,12.8099f,214.844f, +-82.0313f,13.3672f,214.844f, +-78.125f,13.5811f,214.844f, +-74.2188f,14.7559f,214.844f, +-70.3125f,15.4274f,214.844f, +-66.4063f,15.487f,214.844f, +-62.5f,16.3346f,214.844f, +-58.5938f,16.424f,214.844f, +-54.6875f,17.1014f,214.844f, +-50.7813f,17.634f,214.844f, +-46.875f,16.5132f,214.844f, +-42.9688f,15.1728f,214.844f, +-39.0625f,15.4699f,214.844f, +-35.1563f,16.154f,214.844f, +-31.25f,15.8527f,214.844f, +-27.3438f,15.4057f,214.844f, +-23.4375f,14.6476f,214.844f, +-19.5313f,13.1705f,214.844f, +-15.625f,11.9754f,214.844f, +-11.7188f,11.7453f,214.844f, +-7.8125f,10.8384f,214.844f, +-3.90625f,10.1259f,214.844f, +0.0f,9.49925f,214.844f, +3.90625f,9.25513f,214.844f, +-250.0f,3.60269f,210.938f, +-246.094f,5.37638f,210.938f, +-242.188f,7.66914f,210.938f, +-238.281f,11.9863f,210.938f, +-234.375f,14.9525f,210.938f, +-230.469f,16.5034f,210.938f, +-226.563f,17.8663f,210.938f, +-222.656f,17.1002f,210.938f, +-218.75f,16.0413f,210.938f, +-214.844f,14.8516f,210.938f, +-210.938f,13.8904f,210.938f, +-207.031f,11.9929f,210.938f, +-203.125f,11.8171f,210.938f, +-199.219f,11.6849f,210.938f, +-195.313f,11.056f,210.938f, +-191.406f,11.6318f,210.938f, +-187.5f,11.9333f,210.938f, +-183.594f,12.599f,210.938f, +-179.688f,14.0437f,210.938f, +-175.781f,14.7937f,210.938f, +-171.875f,14.8844f,210.938f, +-167.969f,14.3312f,210.938f, +-164.063f,13.2879f,210.938f, +-160.156f,12.3423f,210.938f, +-156.25f,11.4768f,210.938f, +-152.344f,9.94481f,210.938f, +-148.438f,7.76655f,210.938f, +-144.531f,6.59218f,210.938f, +-140.625f,6.49848f,210.938f, +-136.719f,5.2458f,210.938f, +-132.813f,4.27164f,210.938f, +-128.906f,4.68484f,210.938f, +-125.0f,5.2746f,210.938f, +-121.094f,6.12822f,210.938f, +-117.188f,8.02215f,210.938f, +-113.281f,8.95036f,210.938f, +-109.375f,9.92538f,210.938f, +-105.469f,10.4058f,210.938f, +-101.563f,11.2862f,210.938f, +-97.6563f,11.7274f,210.938f, +-93.75f,12.3175f,210.938f, +-89.8438f,12.6423f,210.938f, +-85.9375f,13.2212f,210.938f, +-82.0313f,13.9379f,210.938f, +-78.125f,15.3332f,210.938f, +-74.2188f,16.2893f,210.938f, +-70.3125f,16.1032f,210.938f, +-66.4063f,16.7786f,210.938f, +-62.5f,16.8038f,210.938f, +-58.5938f,16.1537f,210.938f, +-54.6875f,17.4306f,210.938f, +-50.7813f,17.313f,210.938f, +-46.875f,16.2568f,210.938f, +-42.9688f,16.0266f,210.938f, +-39.0625f,16.9569f,210.938f, +-35.1563f,18.0733f,210.938f, +-31.25f,17.4779f,210.938f, +-27.3438f,17.2939f,210.938f, +-23.4375f,16.1477f,210.938f, +-19.5313f,15.409f,210.938f, +-15.625f,14.0019f,210.938f, +-11.7188f,13.3531f,210.938f, +-7.8125f,12.4823f,210.938f, +-3.90625f,11.7842f,210.938f, +0.0f,11.0776f,210.938f, +3.90625f,10.5728f,210.938f, +-250.0f,3.49901f,207.031f, +-246.094f,4.00092f,207.031f, +-242.188f,7.06194f,207.031f, +-238.281f,10.1502f,207.031f, +-234.375f,13.0262f,207.031f, +-230.469f,15.541f,207.031f, +-226.563f,16.4029f,207.031f, +-222.656f,16.0741f,207.031f, +-218.75f,15.3706f,207.031f, +-214.844f,14.3529f,207.031f, +-210.938f,13.1351f,207.031f, +-207.031f,11.2939f,207.031f, +-203.125f,11.4337f,207.031f, +-199.219f,11.43f,207.031f, +-195.313f,10.6048f,207.031f, +-191.406f,10.859f,207.031f, +-187.5f,11.8447f,207.031f, +-183.594f,12.8305f,207.031f, +-179.688f,14.9116f,207.031f, +-175.781f,15.0225f,207.031f, +-171.875f,14.847f,207.031f, +-167.969f,13.7464f,207.031f, +-164.063f,12.6716f,207.031f, +-160.156f,10.4028f,207.031f, +-156.25f,9.61156f,207.031f, +-152.344f,9.08545f,207.031f, +-148.438f,6.96088f,207.031f, +-144.531f,6.6794f,207.031f, +-140.625f,6.08012f,207.031f, +-136.719f,5.02964f,207.031f, +-132.813f,4.93996f,207.031f, +-128.906f,4.955f,207.031f, +-125.0f,5.23446f,207.031f, +-121.094f,7.14164f,207.031f, +-117.188f,9.21655f,207.031f, +-113.281f,10.8802f,207.031f, +-109.375f,11.0518f,207.031f, +-105.469f,11.5707f,207.031f, +-101.563f,12.2834f,207.031f, +-97.6563f,12.7498f,207.031f, +-93.75f,12.6608f,207.031f, +-89.8438f,12.3649f,207.031f, +-85.9375f,13.1678f,207.031f, +-82.0313f,13.541f,207.031f, +-78.125f,14.3448f,207.031f, +-74.2188f,15.6006f,207.031f, +-70.3125f,17.0141f,207.031f, +-66.4063f,17.4107f,207.031f, +-62.5f,18.0045f,207.031f, +-58.5938f,17.6582f,207.031f, +-54.6875f,17.0297f,207.031f, +-50.7813f,16.6619f,207.031f, +-46.875f,17.1267f,207.031f, +-42.9688f,18.0618f,207.031f, +-39.0625f,18.7698f,207.031f, +-35.1563f,19.3034f,207.031f, +-31.25f,19.1566f,207.031f, +-27.3438f,19.1107f,207.031f, +-23.4375f,17.3298f,207.031f, +-19.5313f,15.7204f,207.031f, +-15.625f,14.7827f,207.031f, +-11.7188f,14.2027f,207.031f, +-7.8125f,13.5758f,207.031f, +-3.90625f,13.1935f,207.031f, +0.0f,11.8526f,207.031f, +3.90625f,10.4539f,207.031f, +-250.0f,3.85941f,203.125f, +-246.094f,3.80391f,203.125f, +-242.188f,6.8342f,203.125f, +-238.281f,10.0313f,203.125f, +-234.375f,12.9894f,203.125f, +-230.469f,15.1588f,203.125f, +-226.563f,15.6234f,203.125f, +-222.656f,15.112f,203.125f, +-218.75f,14.5577f,203.125f, +-214.844f,14.0703f,203.125f, +-210.938f,13.3523f,203.125f, +-207.031f,12.1264f,203.125f, +-203.125f,11.037f,203.125f, +-199.219f,10.3379f,203.125f, +-195.313f,11.3f,203.125f, +-191.406f,10.6845f,203.125f, +-187.5f,11.7023f,203.125f, +-183.594f,13.2057f,203.125f, +-179.688f,13.976f,203.125f, +-175.781f,14.994f,203.125f, +-171.875f,14.6465f,203.125f, +-167.969f,13.4879f,203.125f, +-164.063f,12.0617f,203.125f, +-160.156f,10.6454f,203.125f, +-156.25f,10.2693f,203.125f, +-152.344f,8.33279f,203.125f, +-148.438f,7.60557f,203.125f, +-144.531f,6.19774f,203.125f, +-140.625f,5.7751f,203.125f, +-136.719f,5.28903f,203.125f, +-132.813f,5.10696f,203.125f, +-128.906f,5.61944f,203.125f, +-125.0f,7.32929f,203.125f, +-121.094f,9.09158f,203.125f, +-117.188f,10.6952f,203.125f, +-113.281f,11.555f,203.125f, +-109.375f,12.5837f,203.125f, +-105.469f,13.4444f,203.125f, +-101.563f,14.3191f,203.125f, +-97.6563f,14.5546f,203.125f, +-93.75f,13.9216f,203.125f, +-89.8438f,13.07f,203.125f, +-85.9375f,13.0497f,203.125f, +-82.0313f,13.8884f,203.125f, +-78.125f,14.2048f,203.125f, +-74.2188f,16.2809f,203.125f, +-70.3125f,17.1518f,203.125f, +-66.4063f,18.4883f,203.125f, +-62.5f,19.2231f,203.125f, +-58.5938f,19.0199f,203.125f, +-54.6875f,18.4606f,203.125f, +-50.7813f,17.3076f,203.125f, +-46.875f,17.0012f,203.125f, +-42.9688f,18.4311f,203.125f, +-39.0625f,19.9758f,203.125f, +-35.1563f,20.1252f,203.125f, +-31.25f,20.126f,203.125f, +-27.3438f,18.9276f,203.125f, +-23.4375f,18.3938f,203.125f, +-19.5313f,16.6811f,203.125f, +-15.625f,15.7398f,203.125f, +-11.7188f,14.6978f,203.125f, +-7.8125f,14.7567f,203.125f, +-3.90625f,14.377f,203.125f, +0.0f,13.0029f,203.125f, +3.90625f,11.4706f,203.125f, +-250.0f,4.68355f,199.219f, +-246.094f,4.65569f,199.219f, +-242.188f,6.34925f,199.219f, +-238.281f,9.03665f,199.219f, +-234.375f,11.4587f,199.219f, +-230.469f,13.9932f,199.219f, +-226.563f,14.8268f,199.219f, +-222.656f,14.0552f,199.219f, +-218.75f,14.4455f,199.219f, +-214.844f,14.3053f,199.219f, +-210.938f,12.5781f,199.219f, +-207.031f,11.5778f,199.219f, +-203.125f,9.91652f,199.219f, +-199.219f,9.20832f,199.219f, +-195.313f,10.1078f,199.219f, +-191.406f,10.5638f,199.219f, +-187.5f,11.6649f,199.219f, +-183.594f,13.3758f,199.219f, +-179.688f,15.2035f,199.219f, +-175.781f,14.6909f,199.219f, +-171.875f,14.0312f,199.219f, +-167.969f,12.6808f,199.219f, +-164.063f,12.649f,199.219f, +-160.156f,11.6333f,199.219f, +-156.25f,10.8896f,199.219f, +-152.344f,8.72848f,199.219f, +-148.438f,7.55753f,199.219f, +-144.531f,6.70035f,199.219f, +-140.625f,5.28209f,199.219f, +-136.719f,5.47347f,199.219f, +-132.813f,7.25678f,199.219f, +-128.906f,9.06223f,199.219f, +-125.0f,9.91604f,199.219f, +-121.094f,10.882f,199.219f, +-117.188f,11.8314f,199.219f, +-113.281f,12.9729f,199.219f, +-109.375f,14.1144f,199.219f, +-105.469f,15.0374f,199.219f, +-101.563f,15.4321f,199.219f, +-97.6563f,15.9823f,199.219f, +-93.75f,15.4663f,199.219f, +-89.8438f,14.4094f,199.219f, +-85.9375f,14.1599f,199.219f, +-82.0313f,14.4239f,199.219f, +-78.125f,14.7717f,199.219f, +-74.2188f,15.3979f,199.219f, +-70.3125f,16.4014f,199.219f, +-66.4063f,17.9486f,199.219f, +-62.5f,19.3767f,199.219f, +-58.5938f,19.7322f,199.219f, +-54.6875f,19.0648f,199.219f, +-50.7813f,18.2481f,199.219f, +-46.875f,17.1507f,199.219f, +-42.9688f,18.6306f,199.219f, +-39.0625f,19.2486f,199.219f, +-35.1563f,20.3158f,199.219f, +-31.25f,19.6441f,199.219f, +-27.3438f,18.7294f,199.219f, +-23.4375f,17.9051f,199.219f, +-19.5313f,17.278f,199.219f, +-15.625f,16.1912f,199.219f, +-11.7188f,15.3685f,199.219f, +-7.8125f,14.8376f,199.219f, +-3.90625f,13.8988f,199.219f, +0.0f,12.5645f,199.219f, +3.90625f,12.1184f,199.219f, +-250.0f,5.71048f,195.313f, +-246.094f,4.68298f,195.313f, +-242.188f,5.30012f,195.313f, +-238.281f,7.72299f,195.313f, +-234.375f,10.9797f,195.313f, +-230.469f,12.6343f,195.313f, +-226.563f,13.8962f,195.313f, +-222.656f,13.2189f,195.313f, +-218.75f,14.0254f,195.313f, +-214.844f,14.5903f,195.313f, +-210.938f,12.6794f,195.313f, +-207.031f,9.8479f,195.313f, +-203.125f,8.05763f,195.313f, +-199.219f,7.68254f,195.313f, +-195.313f,9.0324f,195.313f, +-191.406f,10.7973f,195.313f, +-187.5f,12.1516f,195.313f, +-183.594f,13.1888f,195.313f, +-179.688f,14.2559f,195.313f, +-175.781f,14.0455f,195.313f, +-171.875f,13.2785f,195.313f, +-167.969f,12.7724f,195.313f, +-164.063f,12.56f,195.313f, +-160.156f,11.4647f,195.313f, +-156.25f,10.6463f,195.313f, +-152.344f,9.36927f,195.313f, +-148.438f,7.87862f,195.313f, +-144.531f,6.78168f,195.313f, +-140.625f,5.32688f,195.313f, +-136.719f,6.62928f,195.313f, +-132.813f,8.97871f,195.313f, +-128.906f,10.3174f,195.313f, +-125.0f,11.2136f,195.313f, +-121.094f,12.2822f,195.313f, +-117.188f,13.7351f,195.313f, +-113.281f,14.0196f,195.313f, +-109.375f,15.5457f,195.313f, +-105.469f,16.1402f,195.313f, +-101.563f,16.6719f,195.313f, +-97.6563f,16.2658f,195.313f, +-93.75f,16.5379f,195.313f, +-89.8438f,15.1289f,195.313f, +-85.9375f,14.7687f,195.313f, +-82.0313f,15.4638f,195.313f, +-78.125f,15.3391f,195.313f, +-74.2188f,14.8602f,195.313f, +-70.3125f,16.2701f,195.313f, +-66.4063f,17.9511f,195.313f, +-62.5f,19.108f,195.313f, +-58.5938f,19.5253f,195.313f, +-54.6875f,19.1648f,195.313f, +-50.7813f,18.0624f,195.313f, +-46.875f,17.2201f,195.313f, +-42.9688f,19.4165f,195.313f, +-39.0625f,20.3781f,195.313f, +-35.1563f,19.796f,195.313f, +-31.25f,18.9841f,195.313f, +-27.3438f,18.3143f,195.313f, +-23.4375f,18.1973f,195.313f, +-19.5313f,17.5121f,195.313f, +-15.625f,16.5969f,195.313f, +-11.7188f,15.3539f,195.313f, +-7.8125f,14.4654f,195.313f, +-3.90625f,13.8161f,195.313f, +0.0f,12.4727f,195.313f, +3.90625f,13.8013f,195.313f, +-250.0f,6.07831f,191.406f, +-246.094f,5.46721f,191.406f, +-242.188f,4.48351f,191.406f, +-238.281f,6.74031f,191.406f, +-234.375f,9.75661f,191.406f, +-230.469f,11.5382f,191.406f, +-226.563f,12.9559f,191.406f, +-222.656f,12.6196f,191.406f, +-218.75f,12.4516f,191.406f, +-214.844f,13.5738f,191.406f, +-210.938f,12.2334f,191.406f, +-207.031f,9.36284f,191.406f, +-203.125f,7.56119f,191.406f, +-199.219f,8.2975f,191.406f, +-195.313f,10.0432f,191.406f, +-191.406f,11.528f,191.406f, +-187.5f,12.9338f,191.406f, +-183.594f,13.9397f,191.406f, +-179.688f,14.1423f,191.406f, +-175.781f,13.7637f,191.406f, +-171.875f,12.7983f,191.406f, +-167.969f,12.6132f,191.406f, +-164.063f,12.07f,191.406f, +-160.156f,11.7037f,191.406f, +-156.25f,10.3692f,191.406f, +-152.344f,9.29784f,191.406f, +-148.438f,7.91508f,191.406f, +-144.531f,6.85636f,191.406f, +-140.625f,8.06021f,191.406f, +-136.719f,8.86078f,191.406f, +-132.813f,11.0565f,191.406f, +-128.906f,12.4031f,191.406f, +-125.0f,13.4308f,191.406f, +-121.094f,13.8732f,191.406f, +-117.188f,15.0555f,191.406f, +-113.281f,16.0219f,191.406f, +-109.375f,16.8646f,191.406f, +-105.469f,16.9156f,191.406f, +-101.563f,16.9811f,191.406f, +-97.6563f,17.1773f,191.406f, +-93.75f,16.9233f,191.406f, +-89.8438f,15.3563f,191.406f, +-85.9375f,14.4936f,191.406f, +-82.0313f,15.6108f,191.406f, +-78.125f,15.9615f,191.406f, +-74.2188f,14.6365f,191.406f, +-70.3125f,15.5344f,191.406f, +-66.4063f,17.4295f,191.406f, +-62.5f,18.2646f,191.406f, +-58.5938f,19.0205f,191.406f, +-54.6875f,19.0503f,191.406f, +-50.7813f,17.6912f,191.406f, +-46.875f,17.6816f,191.406f, +-42.9688f,18.8066f,191.406f, +-39.0625f,19.8444f,191.406f, +-35.1563f,18.7929f,191.406f, +-31.25f,18.6865f,191.406f, +-27.3438f,19.0671f,191.406f, +-23.4375f,18.6708f,191.406f, +-19.5313f,17.7215f,191.406f, +-15.625f,16.4711f,191.406f, +-11.7188f,15.4735f,191.406f, +-7.8125f,14.6316f,191.406f, +-3.90625f,13.8779f,191.406f, +0.0f,13.7777f,191.406f, +3.90625f,14.3936f,191.406f, +-250.0f,6.25219f,187.5f, +-246.094f,5.98752f,187.5f, +-242.188f,5.50108f,187.5f, +-238.281f,5.52049f,187.5f, +-234.375f,7.87236f,187.5f, +-230.469f,10.0244f,187.5f, +-226.563f,10.9579f,187.5f, +-222.656f,11.4176f,187.5f, +-218.75f,11.1583f,187.5f, +-214.844f,12.0797f,187.5f, +-210.938f,10.8226f,187.5f, +-207.031f,8.91363f,187.5f, +-203.125f,7.71952f,187.5f, +-199.219f,8.97116f,187.5f, +-195.313f,10.8813f,187.5f, +-191.406f,12.5874f,187.5f, +-187.5f,13.3418f,187.5f, +-183.594f,13.6407f,187.5f, +-179.688f,13.8787f,187.5f, +-175.781f,13.7918f,187.5f, +-171.875f,12.965f,187.5f, +-167.969f,12.2732f,187.5f, +-164.063f,11.6063f,187.5f, +-160.156f,10.9159f,187.5f, +-156.25f,10.2447f,187.5f, +-152.344f,9.32757f,187.5f, +-148.438f,9.17721f,187.5f, +-144.531f,9.53961f,187.5f, +-140.625f,10.4339f,187.5f, +-136.719f,11.8144f,187.5f, +-132.813f,13.3081f,187.5f, +-128.906f,13.571f,187.5f, +-125.0f,13.9242f,187.5f, +-121.094f,15.4069f,187.5f, +-117.188f,16.9689f,187.5f, +-113.281f,17.987f,187.5f, +-109.375f,18.7838f,187.5f, +-105.469f,18.7737f,187.5f, +-101.563f,18.6666f,187.5f, +-97.6563f,18.4809f,187.5f, +-93.75f,18.3562f,187.5f, +-89.8438f,16.3715f,187.5f, +-85.9375f,14.5483f,187.5f, +-82.0313f,14.9648f,187.5f, +-78.125f,16.1061f,187.5f, +-74.2188f,14.4715f,187.5f, +-70.3125f,14.8322f,187.5f, +-66.4063f,16.3093f,187.5f, +-62.5f,17.3305f,187.5f, +-58.5938f,18.3312f,187.5f, +-54.6875f,18.2865f,187.5f, +-50.7813f,17.4373f,187.5f, +-46.875f,17.9803f,187.5f, +-42.9688f,18.679f,187.5f, +-39.0625f,19.2363f,187.5f, +-35.1563f,19.9926f,187.5f, +-31.25f,19.8827f,187.5f, +-27.3438f,19.283f,187.5f, +-23.4375f,19.0081f,187.5f, +-19.5313f,17.5129f,187.5f, +-15.625f,16.6754f,187.5f, +-11.7188f,15.6685f,187.5f, +-7.8125f,14.6133f,187.5f, +-3.90625f,13.9468f,187.5f, +0.0f,14.2206f,187.5f, +3.90625f,14.1738f,187.5f, +-250.0f,7.10023f,183.594f, +-246.094f,6.39376f,183.594f, +-242.188f,5.78017f,183.594f, +-238.281f,5.07235f,183.594f, +-234.375f,5.98564f,183.594f, +-230.469f,7.6542f,183.594f, +-226.563f,8.75539f,183.594f, +-222.656f,9.90845f,183.594f, +-218.75f,10.2067f,183.594f, +-214.844f,10.2019f,183.594f, +-210.938f,9.2327f,183.594f, +-207.031f,7.67088f,183.594f, +-203.125f,8.15546f,183.594f, +-199.219f,9.42269f,183.594f, +-195.313f,10.8046f,183.594f, +-191.406f,13.3042f,183.594f, +-187.5f,13.9971f,183.594f, +-183.594f,13.621f,183.594f, +-179.688f,13.5612f,183.594f, +-175.781f,13.5357f,183.594f, +-171.875f,12.8778f,183.594f, +-167.969f,12.0385f,183.594f, +-164.063f,11.4391f,183.594f, +-160.156f,10.4255f,183.594f, +-156.25f,10.5692f,183.594f, +-152.344f,10.5452f,183.594f, +-148.438f,11.506f,183.594f, +-144.531f,12.1591f,183.594f, +-140.625f,12.6212f,183.594f, +-136.719f,13.5025f,183.594f, +-132.813f,14.3363f,183.594f, +-128.906f,14.5206f,183.594f, +-125.0f,15.4902f,183.594f, +-121.094f,17.4029f,183.594f, +-117.188f,17.9537f,183.594f, +-113.281f,18.5532f,183.594f, +-109.375f,19.2939f,183.594f, +-105.469f,19.2503f,183.594f, +-101.563f,19.8772f,183.594f, +-97.6563f,19.6753f,183.594f, +-93.75f,18.6744f,183.594f, +-89.8438f,17.7905f,183.594f, +-85.9375f,16.1613f,183.594f, +-82.0313f,15.7839f,183.594f, +-78.125f,15.657f,183.594f, +-74.2188f,14.4171f,183.594f, +-70.3125f,14.6083f,183.594f, +-66.4063f,15.5594f,183.594f, +-62.5f,16.1338f,183.594f, +-58.5938f,17.1134f,183.594f, +-54.6875f,16.8192f,183.594f, +-50.7813f,17.6885f,183.594f, +-46.875f,18.5331f,183.594f, +-42.9688f,19.7359f,183.594f, +-39.0625f,20.7966f,183.594f, +-35.1563f,20.414f,183.594f, +-31.25f,20.1587f,183.594f, +-27.3438f,19.9385f,183.594f, +-23.4375f,18.4694f,183.594f, +-19.5313f,16.9742f,183.594f, +-15.625f,16.0698f,183.594f, +-11.7188f,15.4466f,183.594f, +-7.8125f,15.0614f,183.594f, +-3.90625f,15.2165f,183.594f, +0.0f,14.2632f,183.594f, +3.90625f,13.9878f,183.594f, +-250.0f,8.16978f,179.688f, +-246.094f,7.02044f,179.688f, +-242.188f,6.49336f,179.688f, +-238.281f,6.17674f,179.688f, +-234.375f,4.65977f,179.688f, +-230.469f,5.28977f,179.688f, +-226.563f,7.10711f,179.688f, +-222.656f,8.03062f,179.688f, +-218.75f,9.32719f,179.688f, +-214.844f,9.22926f,179.688f, +-210.938f,8.64588f,179.688f, +-207.031f,7.76534f,179.688f, +-203.125f,8.37552f,179.688f, +-199.219f,8.61402f,179.688f, +-195.313f,10.7567f,179.688f, +-191.406f,12.1961f,179.688f, +-187.5f,13.5076f,179.688f, +-183.594f,13.5739f,179.688f, +-179.688f,13.6032f,179.688f, +-175.781f,13.5388f,179.688f, +-171.875f,13.0425f,179.688f, +-167.969f,13.5885f,179.688f, +-164.063f,13.2666f,179.688f, +-160.156f,11.7827f,179.688f, +-156.25f,12.3517f,179.688f, +-152.344f,13.1307f,179.688f, +-148.438f,13.6688f,179.688f, +-144.531f,13.758f,179.688f, +-140.625f,14.023f,179.688f, +-136.719f,15.1514f,179.688f, +-132.813f,16.004f,179.688f, +-128.906f,16.8991f,179.688f, +-125.0f,17.3616f,179.688f, +-121.094f,18.6059f,179.688f, +-117.188f,19.3263f,179.688f, +-113.281f,19.1956f,179.688f, +-109.375f,19.7991f,179.688f, +-105.469f,20.6907f,179.688f, +-101.563f,21.7059f,179.688f, +-97.6563f,21.5595f,179.688f, +-93.75f,20.4072f,179.688f, +-89.8438f,19.1786f,179.688f, +-85.9375f,18.2895f,179.688f, +-82.0313f,17.1568f,179.688f, +-78.125f,15.2991f,179.688f, +-74.2188f,14.0951f,179.688f, +-70.3125f,14.2935f,179.688f, +-66.4063f,15.0579f,179.688f, +-62.5f,15.3497f,179.688f, +-58.5938f,15.4148f,179.688f, +-54.6875f,17.2528f,179.688f, +-50.7813f,18.38f,179.688f, +-46.875f,19.343f,179.688f, +-42.9688f,20.2151f,179.688f, +-39.0625f,21.1482f,179.688f, +-35.1563f,20.8113f,179.688f, +-31.25f,19.3685f,179.688f, +-27.3438f,18.4966f,179.688f, +-23.4375f,17.1162f,179.688f, +-19.5313f,16.1739f,179.688f, +-15.625f,15.1081f,179.688f, +-11.7188f,15.5766f,179.688f, +-7.8125f,16.3649f,179.688f, +-3.90625f,16.3198f,179.688f, +0.0f,15.6844f,179.688f, +3.90625f,14.6785f,179.688f, +-250.0f,9.32456f,175.781f, +-246.094f,8.37571f,175.781f, +-242.188f,7.57502f,175.781f, +-238.281f,7.01497f,175.781f, +-234.375f,5.67261f,175.781f, +-230.469f,4.32895f,175.781f, +-226.563f,5.20027f,175.781f, +-222.656f,6.31061f,175.781f, +-218.75f,7.56464f,175.781f, +-214.844f,8.35874f,175.781f, +-210.938f,8.24556f,175.781f, +-207.031f,7.58905f,175.781f, +-203.125f,8.23662f,175.781f, +-199.219f,8.64236f,175.781f, +-195.313f,10.4842f,175.781f, +-191.406f,11.8296f,175.781f, +-187.5f,13.5307f,175.781f, +-183.594f,14.3422f,175.781f, +-179.688f,14.0725f,175.781f, +-175.781f,14.6f,175.781f, +-171.875f,13.9877f,175.781f, +-167.969f,13.7556f,175.781f, +-164.063f,13.4564f,175.781f, +-160.156f,13.6823f,175.781f, +-156.25f,14.2643f,175.781f, +-152.344f,14.5034f,175.781f, +-148.438f,14.905f,175.781f, +-144.531f,15.0207f,175.781f, +-140.625f,15.2745f,175.781f, +-136.719f,16.7553f,175.781f, +-132.813f,17.9777f,175.781f, +-128.906f,18.5468f,175.781f, +-125.0f,19.2067f,175.781f, +-121.094f,19.2384f,175.781f, +-117.188f,19.4993f,175.781f, +-113.281f,20.2276f,175.781f, +-109.375f,21.3946f,175.781f, +-105.469f,22.0598f,175.781f, +-101.563f,23.2713f,175.781f, +-97.6563f,22.6691f,175.781f, +-93.75f,21.3119f,175.781f, +-89.8438f,20.6083f,175.781f, +-85.9375f,19.4937f,175.781f, +-82.0313f,18.1998f,175.781f, +-78.125f,15.7716f,175.781f, +-74.2188f,14.2438f,175.781f, +-70.3125f,14.4105f,175.781f, +-66.4063f,15.1879f,175.781f, +-62.5f,15.7946f,175.781f, +-58.5938f,16.2302f,175.781f, +-54.6875f,17.1058f,175.781f, +-50.7813f,18.9688f,175.781f, +-46.875f,19.3102f,175.781f, +-42.9688f,19.3902f,175.781f, +-39.0625f,19.6545f,175.781f, +-35.1563f,19.2909f,175.781f, +-31.25f,18.5385f,175.781f, +-27.3438f,16.4388f,175.781f, +-23.4375f,15.5576f,175.781f, +-19.5313f,15.7726f,175.781f, +-15.625f,16.3756f,175.781f, +-11.7188f,16.9626f,175.781f, +-7.8125f,17.219f,175.781f, +-3.90625f,17.063f,175.781f, +0.0f,16.3609f,175.781f, +3.90625f,15.2963f,175.781f, +-250.0f,10.0329f,171.875f, +-246.094f,8.57258f,171.875f, +-242.188f,7.81755f,171.875f, +-238.281f,6.9951f,171.875f, +-234.375f,5.59199f,171.875f, +-230.469f,4.81205f,171.875f, +-226.563f,4.7432f,171.875f, +-222.656f,5.42683f,171.875f, +-218.75f,6.16332f,171.875f, +-214.844f,6.63573f,171.875f, +-210.938f,6.97578f,171.875f, +-207.031f,7.49804f,171.875f, +-203.125f,8.51155f,171.875f, +-199.219f,7.94356f,171.875f, +-195.313f,9.50881f,171.875f, +-191.406f,10.9726f,171.875f, +-187.5f,13.1622f,171.875f, +-183.594f,13.8249f,171.875f, +-179.688f,15.1925f,171.875f, +-175.781f,14.9284f,171.875f, +-171.875f,13.915f,171.875f, +-167.969f,14.2258f,171.875f, +-164.063f,13.435f,171.875f, +-160.156f,13.9359f,171.875f, +-156.25f,14.8963f,171.875f, +-152.344f,15.2933f,171.875f, +-148.438f,15.0124f,171.875f, +-144.531f,15.0787f,171.875f, +-140.625f,15.1958f,171.875f, +-136.719f,17.151f,171.875f, +-132.813f,18.8799f,171.875f, +-128.906f,19.5273f,171.875f, +-125.0f,19.6894f,171.875f, +-121.094f,19.6466f,171.875f, +-117.188f,20.5941f,171.875f, +-113.281f,21.5237f,171.875f, +-109.375f,22.5435f,171.875f, +-105.469f,23.0706f,171.875f, +-101.563f,23.614f,171.875f, +-97.6563f,22.4198f,171.875f, +-93.75f,21.9598f,171.875f, +-89.8438f,22.3051f,171.875f, +-85.9375f,21.7459f,171.875f, +-82.0313f,20.1308f,171.875f, +-78.125f,17.6018f,171.875f, +-74.2188f,15.106f,171.875f, +-70.3125f,16.0838f,171.875f, +-66.4063f,16.4153f,171.875f, +-62.5f,16.9093f,171.875f, +-58.5938f,16.7439f,171.875f, +-54.6875f,16.4659f,171.875f, +-50.7813f,18.0893f,171.875f, +-46.875f,18.8298f,171.875f, +-42.9688f,18.459f,171.875f, +-39.0625f,18.0953f,171.875f, +-35.1563f,18.2461f,171.875f, +-31.25f,17.0625f,171.875f, +-27.3438f,15.3181f,171.875f, +-23.4375f,15.1837f,171.875f, +-19.5313f,17.2025f,171.875f, +-15.625f,18.3144f,171.875f, +-11.7188f,18.4161f,171.875f, +-7.8125f,18.3279f,171.875f, +-3.90625f,17.5657f,171.875f, +0.0f,16.2057f,171.875f, +3.90625f,16.0791f,171.875f, +-250.0f,9.46368f,167.969f, +-246.094f,8.91851f,167.969f, +-242.188f,7.83383f,167.969f, +-238.281f,7.4147f,167.969f, +-234.375f,6.33692f,167.969f, +-230.469f,5.44334f,167.969f, +-226.563f,4.39369f,167.969f, +-222.656f,3.44146f,167.969f, +-218.75f,4.44651f,167.969f, +-214.844f,5.36701f,167.969f, +-210.938f,6.2915f,167.969f, +-207.031f,6.3588f,167.969f, +-203.125f,7.36203f,167.969f, +-199.219f,7.7957f,167.969f, +-195.313f,9.3926f,167.969f, +-191.406f,11.2699f,167.969f, +-187.5f,12.3727f,167.969f, +-183.594f,14.7022f,167.969f, +-179.688f,15.4324f,167.969f, +-175.781f,15.226f,167.969f, +-171.875f,13.6658f,167.969f, +-167.969f,14.0361f,167.969f, +-164.063f,13.5871f,167.969f, +-160.156f,14.725f,167.969f, +-156.25f,15.5452f,167.969f, +-152.344f,16.3685f,167.969f, +-148.438f,17.0213f,167.969f, +-144.531f,16.2228f,167.969f, +-140.625f,15.1123f,167.969f, +-136.719f,16.9339f,167.969f, +-132.813f,18.4025f,167.969f, +-128.906f,19.9945f,167.969f, +-125.0f,20.4069f,167.969f, +-121.094f,21.447f,167.969f, +-117.188f,22.384f,167.969f, +-113.281f,22.4822f,167.969f, +-109.375f,22.9018f,167.969f, +-105.469f,23.4936f,167.969f, +-101.563f,23.0085f,167.969f, +-97.6563f,22.8398f,167.969f, +-93.75f,23.2939f,167.969f, +-89.8438f,23.3336f,167.969f, +-85.9375f,22.6883f,167.969f, +-82.0313f,21.8752f,167.969f, +-78.125f,18.7456f,167.969f, +-74.2188f,16.5685f,167.969f, +-70.3125f,17.179f,167.969f, +-66.4063f,18.1074f,167.969f, +-62.5f,18.9865f,167.969f, +-58.5938f,17.4851f,167.969f, +-54.6875f,17.2795f,167.969f, +-50.7813f,16.9142f,167.969f, +-46.875f,17.1532f,167.969f, +-42.9688f,17.796f,167.969f, +-39.0625f,17.6868f,167.969f, +-35.1563f,16.7998f,167.969f, +-31.25f,16.0556f,167.969f, +-27.3438f,14.7864f,167.969f, +-23.4375f,16.8386f,167.969f, +-19.5313f,17.9676f,167.969f, +-15.625f,18.4144f,167.969f, +-11.7188f,18.9248f,167.969f, +-7.8125f,18.4614f,167.969f, +-3.90625f,17.2197f,167.969f, +0.0f,16.7097f,167.969f, +3.90625f,17.1455f,167.969f, +-250.0f,9.27861f,164.063f, +-246.094f,8.67875f,164.063f, +-242.188f,8.39269f,164.063f, +-238.281f,7.54041f,164.063f, +-234.375f,6.37361f,164.063f, +-230.469f,5.0066f,164.063f, +-226.563f,3.63142f,164.063f, +-222.656f,2.77898f,164.063f, +-218.75f,2.89032f,164.063f, +-214.844f,4.01591f,164.063f, +-210.938f,4.52151f,164.063f, +-207.031f,4.85596f,164.063f, +-203.125f,6.21759f,164.063f, +-199.219f,8.25574f,164.063f, +-195.313f,10.3856f,164.063f, +-191.406f,11.6593f,164.063f, +-187.5f,12.5334f,164.063f, +-183.594f,14.1044f,164.063f, +-179.688f,14.8149f,164.063f, +-175.781f,14.9916f,164.063f, +-171.875f,14.6218f,164.063f, +-167.969f,14.5374f,164.063f, +-164.063f,13.7748f,164.063f, +-160.156f,15.1069f,164.063f, +-156.25f,16.5225f,164.063f, +-152.344f,17.8264f,164.063f, +-148.438f,18.5076f,164.063f, +-144.531f,17.6099f,164.063f, +-140.625f,16.4656f,164.063f, +-136.719f,16.7761f,164.063f, +-132.813f,19.1652f,164.063f, +-128.906f,20.565f,164.063f, +-125.0f,21.7781f,164.063f, +-121.094f,22.7613f,164.063f, +-117.188f,23.5743f,164.063f, +-113.281f,23.3567f,164.063f, +-109.375f,24.4075f,164.063f, +-105.469f,24.4502f,164.063f, +-101.563f,24.044f,164.063f, +-97.6563f,24.669f,164.063f, +-93.75f,24.7946f,164.063f, +-89.8438f,23.9722f,164.063f, +-85.9375f,23.2481f,164.063f, +-82.0313f,22.4202f,164.063f, +-78.125f,19.4816f,164.063f, +-74.2188f,18.3571f,164.063f, +-70.3125f,19.3195f,164.063f, +-66.4063f,19.6276f,164.063f, +-62.5f,19.775f,164.063f, +-58.5938f,18.4049f,164.063f, +-54.6875f,17.6998f,164.063f, +-50.7813f,16.7989f,164.063f, +-46.875f,16.5351f,164.063f, +-42.9688f,16.0836f,164.063f, +-39.0625f,16.4446f,164.063f, +-35.1563f,15.0322f,164.063f, +-31.25f,14.1679f,164.063f, +-27.3438f,16.0461f,164.063f, +-23.4375f,16.985f,164.063f, +-19.5313f,17.3286f,164.063f, +-15.625f,18.477f,164.063f, +-11.7188f,17.8736f,164.063f, +-7.8125f,17.8059f,164.063f, +-3.90625f,17.2079f,164.063f, +0.0f,16.7726f,164.063f, +3.90625f,16.4621f,164.063f, +-250.0f,8.56359f,160.156f, +-246.094f,8.04536f,160.156f, +-242.188f,7.71795f,160.156f, +-238.281f,7.20369f,160.156f, +-234.375f,5.51432f,160.156f, +-230.469f,5.00541f,160.156f, +-226.563f,4.36899f,160.156f, +-222.656f,3.03865f,160.156f, +-218.75f,2.92915f,160.156f, +-214.844f,2.63693f,160.156f, +-210.938f,2.69254f,160.156f, +-207.031f,3.5578f,160.156f, +-203.125f,5.61634f,160.156f, +-199.219f,7.61065f,160.156f, +-195.313f,9.64763f,160.156f, +-191.406f,11.2848f,160.156f, +-187.5f,12.7624f,160.156f, +-183.594f,13.2875f,160.156f, +-179.688f,15.2776f,160.156f, +-175.781f,15.3268f,160.156f, +-171.875f,15.211f,160.156f, +-167.969f,14.343f,160.156f, +-164.063f,14.8683f,160.156f, +-160.156f,16.1659f,160.156f, +-156.25f,16.4538f,160.156f, +-152.344f,18.5601f,160.156f, +-148.438f,19.2615f,160.156f, +-144.531f,18.8155f,160.156f, +-140.625f,17.4377f,160.156f, +-136.719f,17.6478f,160.156f, +-132.813f,19.7168f,160.156f, +-128.906f,21.4745f,160.156f, +-125.0f,23.0596f,160.156f, +-121.094f,24.6069f,160.156f, +-117.188f,25.9676f,160.156f, +-113.281f,26.2865f,160.156f, +-109.375f,27.1441f,160.156f, +-105.469f,27.0334f,160.156f, +-101.563f,26.0567f,160.156f, +-97.6563f,26.2584f,160.156f, +-93.75f,26.2751f,160.156f, +-89.8438f,25.6929f,160.156f, +-85.9375f,24.0275f,160.156f, +-82.0313f,22.2346f,160.156f, +-78.125f,20.4728f,160.156f, +-74.2188f,19.6229f,160.156f, +-70.3125f,20.0997f,160.156f, +-66.4063f,21.118f,160.156f, +-62.5f,20.4515f,160.156f, +-58.5938f,19.4599f,160.156f, +-54.6875f,18.2081f,160.156f, +-50.7813f,16.8263f,160.156f, +-46.875f,16.3719f,160.156f, +-42.9688f,15.1416f,160.156f, +-39.0625f,14.5969f,160.156f, +-35.1563f,14.7039f,160.156f, +-31.25f,14.8314f,160.156f, +-27.3438f,16.4129f,160.156f, +-23.4375f,16.144f,160.156f, +-19.5313f,17.5764f,160.156f, +-15.625f,17.9247f,160.156f, +-11.7188f,17.0582f,160.156f, +-7.8125f,17.1554f,160.156f, +-3.90625f,16.8369f,160.156f, +0.0f,16.4316f,160.156f, +3.90625f,16.628f,160.156f, +-250.0f,7.51933f,156.25f, +-246.094f,7.63381f,156.25f, +-242.188f,7.57378f,156.25f, +-238.281f,6.94606f,156.25f, +-234.375f,4.79198f,156.25f, +-230.469f,4.43262f,156.25f, +-226.563f,4.13314f,156.25f, +-222.656f,2.75517f,156.25f, +-218.75f,2.67631f,156.25f, +-214.844f,3.321f,156.25f, +-210.938f,3.33063f,156.25f, +-207.031f,3.60719f,156.25f, +-203.125f,4.44636f,156.25f, +-199.219f,6.02108f,156.25f, +-195.313f,8.25702f,156.25f, +-191.406f,10.5762f,156.25f, +-187.5f,11.4514f,156.25f, +-183.594f,12.7361f,156.25f, +-179.688f,15.4206f,156.25f, +-175.781f,16.1997f,156.25f, +-171.875f,14.8996f,156.25f, +-167.969f,14.1118f,156.25f, +-164.063f,16.0576f,156.25f, +-160.156f,17.6078f,156.25f, +-156.25f,17.7518f,156.25f, +-152.344f,18.4278f,156.25f, +-148.438f,19.5827f,156.25f, +-144.531f,19.2756f,156.25f, +-140.625f,18.2888f,156.25f, +-136.719f,18.7157f,156.25f, +-132.813f,20.4669f,156.25f, +-128.906f,22.5748f,156.25f, +-125.0f,24.648f,156.25f, +-121.094f,27.1223f,156.25f, +-117.188f,28.0709f,156.25f, +-113.281f,28.4982f,156.25f, +-109.375f,29.0927f,156.25f, +-105.469f,29.2755f,156.25f, +-101.563f,28.9208f,156.25f, +-97.6563f,28.3829f,156.25f, +-93.75f,26.8508f,156.25f, +-89.8438f,25.9621f,156.25f, +-85.9375f,24.2707f,156.25f, +-82.0313f,22.6235f,156.25f, +-78.125f,21.9368f,156.25f, +-74.2188f,21.0831f,156.25f, +-70.3125f,21.368f,156.25f, +-66.4063f,21.3333f,156.25f, +-62.5f,20.5296f,156.25f, +-58.5938f,19.98f,156.25f, +-54.6875f,18.5818f,156.25f, +-50.7813f,17.2025f,156.25f, +-46.875f,16.1859f,156.25f, +-42.9688f,14.4559f,156.25f, +-39.0625f,13.7597f,156.25f, +-35.1563f,14.6354f,156.25f, +-31.25f,15.6213f,156.25f, +-27.3438f,15.683f,156.25f, +-23.4375f,16.5331f,156.25f, +-19.5313f,16.8272f,156.25f, +-15.625f,16.551f,156.25f, +-11.7188f,16.34f,156.25f, +-7.8125f,16.4067f,156.25f, +-3.90625f,15.8725f,156.25f, +0.0f,16.3451f,156.25f, +3.90625f,16.9346f,156.25f, +-250.0f,6.48899f,152.344f, +-246.094f,6.4047f,152.344f, +-242.188f,6.57203f,152.344f, +-238.281f,5.4628f,152.344f, +-234.375f,4.20753f,152.344f, +-230.469f,2.81156f,152.344f, +-226.563f,1.88132f,152.344f, +-222.656f,1.57153f,152.344f, +-218.75f,2.48106f,152.344f, +-214.844f,2.88884f,152.344f, +-210.938f,2.63578f,152.344f, +-207.031f,2.9717f,152.344f, +-203.125f,3.6084f,152.344f, +-199.219f,3.99032f,152.344f, +-195.313f,7.36858f,152.344f, +-191.406f,9.54951f,152.344f, +-187.5f,10.6254f,152.344f, +-183.594f,12.3317f,152.344f, +-179.688f,14.015f,152.344f, +-175.781f,14.8857f,152.344f, +-171.875f,14.9944f,152.344f, +-167.969f,14.7547f,152.344f, +-164.063f,16.7748f,152.344f, +-160.156f,18.5461f,152.344f, +-156.25f,19.5932f,152.344f, +-152.344f,19.1033f,152.344f, +-148.438f,19.012f,152.344f, +-144.531f,19.4428f,152.344f, +-140.625f,19.3453f,152.344f, +-136.719f,20.6611f,152.344f, +-132.813f,22.2914f,152.344f, +-128.906f,24.3802f,152.344f, +-125.0f,26.4048f,152.344f, +-121.094f,28.3525f,152.344f, +-117.188f,30.0561f,152.344f, +-113.281f,30.1155f,152.344f, +-109.375f,30.9005f,152.344f, +-105.469f,30.8767f,152.344f, +-101.563f,30.9056f,152.344f, +-97.6563f,30.3635f,152.344f, +-93.75f,28.3996f,152.344f, +-89.8438f,25.8081f,152.344f, +-85.9375f,24.3731f,152.344f, +-82.0313f,22.7783f,152.344f, +-78.125f,22.5973f,152.344f, +-74.2188f,21.8359f,152.344f, +-70.3125f,21.4903f,152.344f, +-66.4063f,21.0461f,152.344f, +-62.5f,19.9934f,152.344f, +-58.5938f,19.4729f,152.344f, +-54.6875f,18.1265f,152.344f, +-50.7813f,16.4684f,152.344f, +-46.875f,15.0104f,152.344f, +-42.9688f,13.8642f,152.344f, +-39.0625f,14.8875f,152.344f, +-35.1563f,15.117f,152.344f, +-31.25f,15.0707f,152.344f, +-27.3438f,15.3829f,152.344f, +-23.4375f,15.5218f,152.344f, +-19.5313f,15.215f,152.344f, +-15.625f,15.2099f,152.344f, +-11.7188f,15.5383f,152.344f, +-7.8125f,15.6462f,152.344f, +-3.90625f,15.3096f,152.344f, +0.0f,16.3854f,152.344f, +3.90625f,17.6952f,152.344f, +-250.0f,5.17712f,148.438f, +-246.094f,4.67214f,148.438f, +-242.188f,4.31659f,148.438f, +-238.281f,3.2191f,148.438f, +-234.375f,2.13365f,148.438f, +-230.469f,1.19555f,148.438f, +-226.563f,0.110638f,148.438f, +-222.656f,0.945025f,148.438f, +-218.75f,1.43378f,148.438f, +-214.844f,2.06915f,148.438f, +-210.938f,2.27715f,148.438f, +-207.031f,2.23051f,148.438f, +-203.125f,2.64045f,148.438f, +-199.219f,2.99575f,148.438f, +-195.313f,5.40402f,148.438f, +-191.406f,8.03643f,148.438f, +-187.5f,10.0212f,148.438f, +-183.594f,12.2205f,148.438f, +-179.688f,14.1884f,148.438f, +-175.781f,14.5505f,148.438f, +-171.875f,15.188f,148.438f, +-167.969f,15.2222f,148.438f, +-164.063f,17.4791f,148.438f, +-160.156f,19.6158f,148.438f, +-156.25f,20.2107f,148.438f, +-152.344f,20.552f,148.438f, +-148.438f,20.2463f,148.438f, +-144.531f,20.4526f,148.438f, +-140.625f,20.9426f,148.438f, +-136.719f,22.6331f,148.438f, +-132.813f,25.1345f,148.438f, +-128.906f,27.0299f,148.438f, +-125.0f,29.381f,148.438f, +-121.094f,31.0494f,148.438f, +-117.188f,31.7246f,148.438f, +-113.281f,31.9331f,148.438f, +-109.375f,31.9517f,148.438f, +-105.469f,32.217f,148.438f, +-101.563f,31.9001f,148.438f, +-97.6563f,30.471f,148.438f, +-93.75f,28.6143f,148.438f, +-89.8438f,26.5696f,148.438f, +-85.9375f,24.7785f,148.438f, +-82.0313f,23.3248f,148.438f, +-78.125f,22.2737f,148.438f, +-74.2188f,22.0395f,148.438f, +-70.3125f,21.4879f,148.438f, +-66.4063f,20.5539f,148.438f, +-62.5f,19.3981f,148.438f, +-58.5938f,18.0902f,148.438f, +-54.6875f,16.6154f,148.438f, +-50.7813f,15.8338f,148.438f, +-46.875f,14.0809f,148.438f, +-42.9688f,12.8188f,148.438f, +-39.0625f,14.0819f,148.438f, +-35.1563f,14.3673f,148.438f, +-31.25f,14.2973f,148.438f, +-27.3438f,15.1616f,148.438f, +-23.4375f,13.9458f,148.438f, +-19.5313f,14.9412f,148.438f, +-15.625f,15.4488f,148.438f, +-11.7188f,15.3397f,148.438f, +-7.8125f,15.0356f,148.438f, +-3.90625f,15.6431f,148.438f, +0.0f,16.6218f,148.438f, +3.90625f,18.4109f,148.438f, +-250.0f,5.38918f,144.531f, +-246.094f,4.29322f,144.531f, +-242.188f,2.99843f,144.531f, +-238.281f,2.80561f,144.531f, +-234.375f,1.65282f,144.531f, +-230.469f,-0.268879f,144.531f, +-226.563f,-0.474469f,144.531f, +-222.656f,-0.0607398f,144.531f, +-218.75f,0.859532f,144.531f, +-214.844f,1.28455f,144.531f, +-210.938f,1.69755f,144.531f, +-207.031f,2.1277f,144.531f, +-203.125f,2.92014f,144.531f, +-199.219f,3.85473f,144.531f, +-195.313f,4.38999f,144.531f, +-191.406f,6.72101f,144.531f, +-187.5f,9.24433f,144.531f, +-183.594f,11.6027f,144.531f, +-179.688f,13.2042f,144.531f, +-175.781f,14.6647f,144.531f, +-171.875f,14.7252f,144.531f, +-167.969f,16.1425f,144.531f, +-164.063f,18.1823f,144.531f, +-160.156f,19.9802f,144.531f, +-156.25f,22.2009f,144.531f, +-152.344f,21.9313f,144.531f, +-148.438f,22.3421f,144.531f, +-144.531f,21.6393f,144.531f, +-140.625f,23.0621f,144.531f, +-136.719f,24.695f,144.531f, +-132.813f,26.6159f,144.531f, +-128.906f,29.9912f,144.531f, +-125.0f,31.6471f,144.531f, +-121.094f,32.4919f,144.531f, +-117.188f,32.9775f,144.531f, +-113.281f,33.1587f,144.531f, +-109.375f,33.0247f,144.531f, +-105.469f,32.4654f,144.531f, +-101.563f,31.5009f,144.531f, +-97.6563f,30.2211f,144.531f, +-93.75f,28.3655f,144.531f, +-89.8438f,26.6696f,144.531f, +-85.9375f,25.6101f,144.531f, +-82.0313f,23.5563f,144.531f, +-78.125f,21.8779f,144.531f, +-74.2188f,21.4789f,144.531f, +-70.3125f,21.2134f,144.531f, +-66.4063f,20.0494f,144.531f, +-62.5f,19.4674f,144.531f, +-58.5938f,17.3288f,144.531f, +-54.6875f,16.7337f,144.531f, +-50.7813f,15.9259f,144.531f, +-46.875f,14.3007f,144.531f, +-42.9688f,13.3631f,144.531f, +-39.0625f,12.7904f,144.531f, +-35.1563f,13.6627f,144.531f, +-31.25f,13.6872f,144.531f, +-27.3438f,14.0818f,144.531f, +-23.4375f,13.953f,144.531f, +-19.5313f,14.0386f,144.531f, +-15.625f,14.1249f,144.531f, +-11.7188f,14.1069f,144.531f, +-7.8125f,14.4968f,144.531f, +-3.90625f,15.4283f,144.531f, +0.0f,16.5593f,144.531f, +3.90625f,17.8758f,144.531f, +-250.0f,5.32443f,140.625f, +-246.094f,4.53202f,140.625f, +-242.188f,2.85351f,140.625f, +-238.281f,1.48443f,140.625f, +-234.375f,0.193579f,140.625f, +-230.469f,-0.0240196f,140.625f, +-226.563f,-0.195521f,140.625f, +-222.656f,-0.525286f,140.625f, +-218.75f,0.255241f,140.625f, +-214.844f,0.505993f,140.625f, +-210.938f,1.2501f,140.625f, +-207.031f,2.77282f,140.625f, +-203.125f,3.23678f,140.625f, +-199.219f,3.81665f,140.625f, +-195.313f,4.45749f,140.625f, +-191.406f,6.57237f,140.625f, +-187.5f,8.78049f,140.625f, +-183.594f,10.653f,140.625f, +-179.688f,12.1762f,140.625f, +-175.781f,13.836f,140.625f, +-171.875f,14.4421f,140.625f, +-167.969f,16.2272f,140.625f, +-164.063f,17.8194f,140.625f, +-160.156f,20.3268f,140.625f, +-156.25f,21.6942f,140.625f, +-152.344f,21.8506f,140.625f, +-148.438f,22.857f,140.625f, +-144.531f,23.0189f,140.625f, +-140.625f,24.7041f,140.625f, +-136.719f,26.468f,140.625f, +-132.813f,28.6459f,140.625f, +-128.906f,30.9708f,140.625f, +-125.0f,33.2917f,140.625f, +-121.094f,34.9879f,140.625f, +-117.188f,34.5936f,140.625f, +-113.281f,34.2431f,140.625f, +-109.375f,33.7219f,140.625f, +-105.469f,32.9679f,140.625f, +-101.563f,31.3296f,140.625f, +-97.6563f,30.0001f,140.625f, +-93.75f,28.0182f,140.625f, +-89.8438f,26.2542f,140.625f, +-85.9375f,24.9632f,140.625f, +-82.0313f,23.5598f,140.625f, +-78.125f,21.3613f,140.625f, +-74.2188f,20.8425f,140.625f, +-70.3125f,20.6976f,140.625f, +-66.4063f,19.4459f,140.625f, +-62.5f,17.9969f,140.625f, +-58.5938f,17.2754f,140.625f, +-54.6875f,16.763f,140.625f, +-50.7813f,15.8668f,140.625f, +-46.875f,15.2278f,140.625f, +-42.9688f,14.0988f,140.625f, +-39.0625f,13.4132f,140.625f, +-35.1563f,12.9004f,140.625f, +-31.25f,12.6267f,140.625f, +-27.3438f,12.7032f,140.625f, +-23.4375f,12.0508f,140.625f, +-19.5313f,12.8332f,140.625f, +-15.625f,12.2269f,140.625f, +-11.7188f,12.2256f,140.625f, +-7.8125f,13.9086f,140.625f, +-3.90625f,15.559f,140.625f, +0.0f,16.8086f,140.625f, +3.90625f,18.5798f,140.625f, +-250.0f,4.69677f,136.719f, +-246.094f,3.45683f,136.719f, +-242.188f,1.81964f,136.719f, +-238.281f,1.13059f,136.719f, +-234.375f,0.535221f,136.719f, +-230.469f,0.868904f,136.719f, +-226.563f,0.574251f,136.719f, +-222.656f,0.279368f,136.719f, +-218.75f,-1.1876f,136.719f, +-214.844f,-0.688708f,136.719f, +-210.938f,0.470686f,136.719f, +-207.031f,2.00488f,136.719f, +-203.125f,3.42644f,136.719f, +-199.219f,4.20503f,136.719f, +-195.313f,5.23588f,136.719f, +-191.406f,6.02424f,136.719f, +-187.5f,7.96541f,136.719f, +-183.594f,10.5299f,136.719f, +-179.688f,12.0941f,136.719f, +-175.781f,13.5058f,136.719f, +-171.875f,14.8816f,136.719f, +-167.969f,16.551f,136.719f, +-164.063f,17.712f,136.719f, +-160.156f,19.6536f,136.719f, +-156.25f,21.4322f,136.719f, +-152.344f,22.672f,136.719f, +-148.438f,23.3463f,136.719f, +-144.531f,24.5334f,136.719f, +-140.625f,26.061f,136.719f, +-136.719f,27.7423f,136.719f, +-132.813f,30.1692f,136.719f, +-128.906f,33.3739f,136.719f, +-125.0f,34.9742f,136.719f, +-121.094f,35.9387f,136.719f, +-117.188f,36.0925f,136.719f, +-113.281f,35.6549f,136.719f, +-109.375f,34.5646f,136.719f, +-105.469f,34.6062f,136.719f, +-101.563f,32.8375f,136.719f, +-97.6563f,30.2678f,136.719f, +-93.75f,27.2213f,136.719f, +-89.8438f,26.1126f,136.719f, +-85.9375f,24.9965f,136.719f, +-82.0313f,22.5841f,136.719f, +-78.125f,21.7213f,136.719f, +-74.2188f,21.534f,136.719f, +-70.3125f,20.5652f,136.719f, +-66.4063f,19.032f,136.719f, +-62.5f,17.4252f,136.719f, +-58.5938f,16.7783f,136.719f, +-54.6875f,15.9619f,136.719f, +-50.7813f,14.8707f,136.719f, +-46.875f,14.3143f,136.719f, +-42.9688f,13.8793f,136.719f, +-39.0625f,12.6352f,136.719f, +-35.1563f,12.0433f,136.719f, +-31.25f,11.8551f,136.719f, +-27.3438f,12.0193f,136.719f, +-23.4375f,11.2795f,136.719f, +-19.5313f,11.6002f,136.719f, +-15.625f,10.9143f,136.719f, +-11.7188f,12.1473f,136.719f, +-7.8125f,14.3093f,136.719f, +-3.90625f,16.245f,136.719f, +0.0f,17.3141f,136.719f, +3.90625f,19.7224f,136.719f, +-250.0f,3.94613f,132.813f, +-246.094f,2.33247f,132.813f, +-242.188f,1.96569f,132.813f, +-238.281f,1.1741f,132.813f, +-234.375f,0.606142f,132.813f, +-230.469f,0.00901447f,132.813f, +-226.563f,0.143339f,132.813f, +-222.656f,-0.356031f,132.813f, +-218.75f,-1.55439f,132.813f, +-214.844f,-1.22801f,132.813f, +-210.938f,-0.390443f,132.813f, +-207.031f,1.15349f,132.813f, +-203.125f,2.6275f,132.813f, +-199.219f,3.55895f,132.813f, +-195.313f,4.99281f,132.813f, +-191.406f,4.99673f,132.813f, +-187.5f,6.96468f,132.813f, +-183.594f,10.0691f,132.813f, +-179.688f,12.3783f,132.813f, +-175.781f,13.2459f,132.813f, +-171.875f,14.3637f,132.813f, +-167.969f,16.3222f,132.813f, +-164.063f,17.6984f,132.813f, +-160.156f,19.3295f,132.813f, +-156.25f,20.9768f,132.813f, +-152.344f,23.1452f,132.813f, +-148.438f,23.885f,132.813f, +-144.531f,24.7169f,132.813f, +-140.625f,27.1655f,132.813f, +-136.719f,29.0232f,132.813f, +-132.813f,30.2573f,132.813f, +-128.906f,33.5563f,132.813f, +-125.0f,35.1858f,132.813f, +-121.094f,36.4332f,132.813f, +-117.188f,36.6359f,132.813f, +-113.281f,36.0253f,132.813f, +-109.375f,34.7127f,132.813f, +-105.469f,34.6833f,132.813f, +-101.563f,33.7208f,132.813f, +-97.6563f,30.9809f,132.813f, +-93.75f,27.9091f,132.813f, +-89.8438f,25.709f,132.813f, +-85.9375f,24.452f,132.813f, +-82.0313f,22.4897f,132.813f, +-78.125f,22.0485f,132.813f, +-74.2188f,22.1517f,132.813f, +-70.3125f,20.4874f,132.813f, +-66.4063f,19.0482f,132.813f, +-62.5f,17.1019f,132.813f, +-58.5938f,16.7815f,132.813f, +-54.6875f,15.1253f,132.813f, +-50.7813f,14.5074f,132.813f, +-46.875f,12.7631f,132.813f, +-42.9688f,12.6595f,132.813f, +-39.0625f,11.9406f,132.813f, +-35.1563f,11.7459f,132.813f, +-31.25f,10.8406f,132.813f, +-27.3438f,11.0393f,132.813f, +-23.4375f,10.4798f,132.813f, +-19.5313f,10.8165f,132.813f, +-15.625f,12.4368f,132.813f, +-11.7188f,13.2405f,132.813f, +-7.8125f,14.9282f,132.813f, +-3.90625f,16.4449f,132.813f, +0.0f,17.8238f,132.813f, +3.90625f,19.9574f,132.813f, +-250.0f,2.5744f,128.906f, +-246.094f,2.12474f,128.906f, +-242.188f,0.674823f,128.906f, +-238.281f,-0.305135f,128.906f, +-234.375f,-0.948647f,128.906f, +-230.469f,-0.982836f,128.906f, +-226.563f,-1.17369f,128.906f, +-222.656f,-1.48697f,128.906f, +-218.75f,-2.23137f,128.906f, +-214.844f,-2.13825f,128.906f, +-210.938f,-1.06826f,128.906f, +-207.031f,0.0666403f,128.906f, +-203.125f,1.15717f,128.906f, +-199.219f,3.14762f,128.906f, +-195.313f,4.08858f,128.906f, +-191.406f,5.07728f,128.906f, +-187.5f,8.06699f,128.906f, +-183.594f,10.7473f,128.906f, +-179.688f,12.0801f,128.906f, +-175.781f,13.1617f,128.906f, +-171.875f,14.5283f,128.906f, +-167.969f,15.8148f,128.906f, +-164.063f,16.9067f,128.906f, +-160.156f,18.6293f,128.906f, +-156.25f,20.8869f,128.906f, +-152.344f,22.6168f,128.906f, +-148.438f,23.9359f,128.906f, +-144.531f,26.521f,128.906f, +-140.625f,27.4381f,128.906f, +-136.719f,29.5698f,128.906f, +-132.813f,30.681f,128.906f, +-128.906f,33.28f,128.906f, +-125.0f,35.3433f,128.906f, +-121.094f,36.3509f,128.906f, +-117.188f,36.2098f,128.906f, +-113.281f,35.157f,128.906f, +-109.375f,35.3884f,128.906f, +-105.469f,35.7158f,128.906f, +-101.563f,34.3449f,128.906f, +-97.6563f,32.5198f,128.906f, +-93.75f,29.0611f,128.906f, +-89.8438f,25.9945f,128.906f, +-85.9375f,24.2624f,128.906f, +-82.0313f,23.0248f,128.906f, +-78.125f,21.6012f,128.906f, +-74.2188f,21.0399f,128.906f, +-70.3125f,20.1719f,128.906f, +-66.4063f,18.6862f,128.906f, +-62.5f,17.3287f,128.906f, +-58.5938f,16.0916f,128.906f, +-54.6875f,14.1153f,128.906f, +-50.7813f,12.6292f,128.906f, +-46.875f,12.0431f,128.906f, +-42.9688f,11.4785f,128.906f, +-39.0625f,11.911f,128.906f, +-35.1563f,11.6609f,128.906f, +-31.25f,10.4332f,128.906f, +-27.3438f,9.68026f,128.906f, +-23.4375f,9.84506f,128.906f, +-19.5313f,11.6097f,128.906f, +-15.625f,13.2944f,128.906f, +-11.7188f,14.0518f,128.906f, +-7.8125f,15.2998f,128.906f, +-3.90625f,16.8731f,128.906f, +0.0f,18.0594f,128.906f, +3.90625f,20.0876f,128.906f, +-250.0f,2.47782f,125.0f, +-246.094f,1.27263f,125.0f, +-242.188f,-0.535855f,125.0f, +-238.281f,-1.33089f,125.0f, +-234.375f,-1.63273f,125.0f, +-230.469f,-2.30607f,125.0f, +-226.563f,-2.13647f,125.0f, +-222.656f,-2.95807f,125.0f, +-218.75f,-2.92133f,125.0f, +-214.844f,-3.33811f,125.0f, +-210.938f,-2.29807f,125.0f, +-207.031f,-0.860766f,125.0f, +-203.125f,0.507027f,125.0f, +-199.219f,1.54044f,125.0f, +-195.313f,3.32139f,125.0f, +-191.406f,5.76593f,125.0f, +-187.5f,8.17548f,125.0f, +-183.594f,10.5223f,125.0f, +-179.688f,11.4741f,125.0f, +-175.781f,12.3545f,125.0f, +-171.875f,13.5542f,125.0f, +-167.969f,14.4358f,125.0f, +-164.063f,16.6197f,125.0f, +-160.156f,18.7561f,125.0f, +-156.25f,21.2618f,125.0f, +-152.344f,22.9541f,125.0f, +-148.438f,24.7574f,125.0f, +-144.531f,26.8375f,125.0f, +-140.625f,28.3307f,125.0f, +-136.719f,29.2598f,125.0f, +-132.813f,31.2334f,125.0f, +-128.906f,32.9236f,125.0f, +-125.0f,34.4853f,125.0f, +-121.094f,35.1589f,125.0f, +-117.188f,34.4655f,125.0f, +-113.281f,35.7692f,125.0f, +-109.375f,35.9985f,125.0f, +-105.469f,35.7974f,125.0f, +-101.563f,34.6099f,125.0f, +-97.6563f,32.4066f,125.0f, +-93.75f,28.8398f,125.0f, +-89.8438f,26.014f,125.0f, +-85.9375f,25.0319f,125.0f, +-82.0313f,23.7685f,125.0f, +-78.125f,22.4099f,125.0f, +-74.2188f,20.9166f,125.0f, +-70.3125f,19.1502f,125.0f, +-66.4063f,17.8355f,125.0f, +-62.5f,16.5146f,125.0f, +-58.5938f,14.9189f,125.0f, +-54.6875f,13.2423f,125.0f, +-50.7813f,12.2568f,125.0f, +-46.875f,11.4853f,125.0f, +-42.9688f,10.7795f,125.0f, +-39.0625f,10.3251f,125.0f, +-35.1563f,10.4077f,125.0f, +-31.25f,9.96202f,125.0f, +-27.3438f,9.77658f,125.0f, +-23.4375f,10.6703f,125.0f, +-19.5313f,12.2058f,125.0f, +-15.625f,13.8385f,125.0f, +-11.7188f,15.1556f,125.0f, +-7.8125f,15.7626f,125.0f, +-3.90625f,16.911f,125.0f, +0.0f,18.0803f,125.0f, +3.90625f,18.9654f,125.0f, +-250.0f,1.97449f,121.094f, +-246.094f,1.28169f,121.094f, +-242.188f,0.0699786f,121.094f, +-238.281f,-1.31551f,121.094f, +-234.375f,-2.33115f,121.094f, +-230.469f,-3.19445f,121.094f, +-226.563f,-3.91693f,121.094f, +-222.656f,-4.0298f,121.094f, +-218.75f,-4.334f,121.094f, +-214.844f,-3.5405f,121.094f, +-210.938f,-2.70043f,121.094f, +-207.031f,-2.86125f,121.094f, +-203.125f,-1.24727f,121.094f, +-199.219f,0.20797f,121.094f, +-195.313f,2.52573f,121.094f, +-191.406f,4.8544f,121.094f, +-187.5f,7.37504f,121.094f, +-183.594f,9.40828f,121.094f, +-179.688f,11.0747f,121.094f, +-175.781f,11.9892f,121.094f, +-171.875f,12.3358f,121.094f, +-167.969f,13.2084f,121.094f, +-164.063f,15.8626f,121.094f, +-160.156f,18.1098f,121.094f, +-156.25f,20.2905f,121.094f, +-152.344f,22.8183f,121.094f, +-148.438f,25.3439f,121.094f, +-144.531f,26.7908f,121.094f, +-140.625f,29.0959f,121.094f, +-136.719f,29.9478f,121.094f, +-132.813f,30.8054f,121.094f, +-128.906f,31.9545f,121.094f, +-125.0f,33.8025f,121.094f, +-121.094f,35.2826f,121.094f, +-117.188f,36.2373f,121.094f, +-113.281f,36.7861f,121.094f, +-109.375f,36.509f,121.094f, +-105.469f,35.7461f,121.094f, +-101.563f,33.7802f,121.094f, +-97.6563f,30.788f,121.094f, +-93.75f,28.1422f,121.094f, +-89.8438f,26.6316f,121.094f, +-85.9375f,26.0349f,121.094f, +-82.0313f,24.8022f,121.094f, +-78.125f,23.5217f,121.094f, +-74.2188f,21.74f,121.094f, +-70.3125f,20.0101f,121.094f, +-66.4063f,17.8705f,121.094f, +-62.5f,15.6785f,121.094f, +-58.5938f,13.74f,121.094f, +-54.6875f,12.3387f,121.094f, +-50.7813f,11.9457f,121.094f, +-46.875f,12.0102f,121.094f, +-42.9688f,11.0065f,121.094f, +-39.0625f,9.84571f,121.094f, +-35.1563f,10.0894f,121.094f, +-31.25f,10.5366f,121.094f, +-27.3438f,9.94957f,121.094f, +-23.4375f,11.0038f,121.094f, +-19.5313f,12.8084f,121.094f, +-15.625f,13.8969f,121.094f, +-11.7188f,14.9146f,121.094f, +-7.8125f,15.4187f,121.094f, +-3.90625f,16.094f,121.094f, +0.0f,17.0612f,121.094f, +3.90625f,18.5327f,121.094f, +-250.0f,2.18397f,117.188f, +-246.094f,1.51628f,117.188f, +-242.188f,0.628327f,117.188f, +-238.281f,-0.567933f,117.188f, +-234.375f,-2.01568f,117.188f, +-230.469f,-3.41089f,117.188f, +-226.563f,-3.82758f,117.188f, +-222.656f,-5.01586f,117.188f, +-218.75f,-4.74822f,117.188f, +-214.844f,-3.30853f,117.188f, +-210.938f,-2.32499f,117.188f, +-207.031f,-1.71509f,117.188f, +-203.125f,-1.19203f,117.188f, +-199.219f,0.219498f,117.188f, +-195.313f,1.66304f,117.188f, +-191.406f,4.35105f,117.188f, +-187.5f,6.33228f,117.188f, +-183.594f,8.00972f,117.188f, +-179.688f,9.71486f,117.188f, +-175.781f,10.7727f,117.188f, +-171.875f,11.358f,117.188f, +-167.969f,12.5239f,117.188f, +-164.063f,14.6278f,117.188f, +-160.156f,17.2069f,117.188f, +-156.25f,19.9779f,117.188f, +-152.344f,23.4607f,117.188f, +-148.438f,26.6108f,117.188f, +-144.531f,28.4635f,117.188f, +-140.625f,29.7705f,117.188f, +-136.719f,31.0684f,117.188f, +-132.813f,31.8395f,117.188f, +-128.906f,32.1658f,117.188f, +-125.0f,34.7478f,117.188f, +-121.094f,36.0624f,117.188f, +-117.188f,37.2702f,117.188f, +-113.281f,37.3474f,117.188f, +-109.375f,37.242f,117.188f, +-105.469f,36.1544f,117.188f, +-101.563f,33.403f,117.188f, +-97.6563f,31.294f,117.188f, +-93.75f,29.4961f,117.188f, +-89.8438f,29.0556f,117.188f, +-85.9375f,28.2757f,117.188f, +-82.0313f,26.6322f,117.188f, +-78.125f,24.8286f,117.188f, +-74.2188f,22.7019f,117.188f, +-70.3125f,20.4725f,117.188f, +-66.4063f,17.984f,117.188f, +-62.5f,16.3033f,117.188f, +-58.5938f,14.2087f,117.188f, +-54.6875f,12.8086f,117.188f, +-50.7813f,12.5463f,117.188f, +-46.875f,12.1781f,117.188f, +-42.9688f,11.1391f,117.188f, +-39.0625f,10.4623f,117.188f, +-35.1563f,11.0528f,117.188f, +-31.25f,11.454f,117.188f, +-27.3438f,10.5577f,117.188f, +-23.4375f,10.6328f,117.188f, +-19.5313f,12.5569f,117.188f, +-15.625f,13.5389f,117.188f, +-11.7188f,14.3792f,117.188f, +-7.8125f,15.4809f,117.188f, +-3.90625f,16.1008f,117.188f, +0.0f,17.3675f,117.188f, +3.90625f,18.919f,117.188f, +}; + +btScalar Landscape06Nml[] = { +-0.373915f,0.891474f,-0.255855f, +-0.31015f,0.793525f,-0.52357f, +-0.450332f,0.86393f,-0.225447f, +-0.404472f,0.777981f,-0.480778f, +-0.557629f,0.811458f,-0.174885f, +-0.428564f,0.86234f,-0.269633f, +-0.414608f,0.909847f,-0.0166634f, +-0.208047f,0.971233f,0.115854f, +-0.328757f,0.932331f,0.150588f, +-0.263029f,0.937991f,0.225808f, +-0.409412f,0.900937f,0.143853f, +-0.455309f,0.881347f,0.126178f, +-0.31951f,0.943247f,0.0905511f, +-0.33825f,0.934582f,0.1102f, +-0.183669f,0.981438f,0.0551769f, +-0.208308f,0.97293f,0.100072f, +-0.189578f,0.981862f,-0.00282566f, +-0.201983f,0.97649f,0.0752952f, +-0.0672914f,0.99749f,-0.0220572f, +-0.118523f,0.991949f,0.0446084f, +0.102757f,0.986595f,-0.126773f, +0.00122687f,0.992675f,-0.120808f, +0.0798054f,0.967751f,-0.238933f, +0.00875196f,0.978629f,-0.205448f, +0.141554f,0.932155f,-0.333242f, +0.0918343f,0.965319f,-0.244387f, +0.372959f,0.842559f,-0.388582f, +0.280191f,0.875069f,-0.394647f, +0.314921f,0.849656f,-0.422977f, +0.258676f,0.813335f,-0.521127f, +0.266443f,0.876708f,-0.400489f, +0.358307f,0.856764f,-0.370907f, +0.280512f,0.913716f,-0.293999f, +0.337561f,0.857178f,-0.388971f, +0.0927666f,0.994197f,-0.0544758f, +0.155544f,0.953116f,-0.259567f, +-0.18671f,0.979157f,-0.0799463f, +-0.20939f,0.930283f,-0.301212f, +-0.117108f,0.986639f,-0.113269f, +-0.190516f,0.897405f,-0.397956f, +-0.0703231f,0.977433f,-0.199199f, +-0.142735f,0.82748f,-0.54305f, +-0.00706444f,0.969596f,-0.244609f, +0.0216131f,0.85384f,-0.520087f, +-0.100606f,0.961424f,-0.256011f, +0.00977565f,0.925054f,-0.379709f, +-0.0412166f,0.978641f,-0.201403f, +0.099113f,0.987693f,-0.12099f, +0.0911178f,0.982669f,-0.16143f, +0.0730708f,0.986329f,-0.147703f, +0.114859f,0.978874f,-0.169152f, +0.109302f,0.983788f,-0.142175f, +0.116167f,0.976713f,-0.180378f, +0.0784892f,0.966143f,-0.24578f, +0.0196949f,0.987682f,-0.155232f, +0.0258077f,0.978923f,-0.202593f, +-0.0161862f,0.979217f,-0.202168f, +-0.120896f,0.935381f,-0.332336f, +-0.0291128f,0.941335f,-0.336215f, +-0.0776893f,0.901631f,-0.425472f, +-0.0768763f,0.919716f,-0.384983f, +-0.0462705f,0.951989f,-0.302615f, +-0.0260847f,0.891121f,-0.453016f, +-0.0818404f,0.911776f,-0.40245f, +0.152271f,0.86407f,-0.479789f, +0.0880729f,0.874485f,-0.476991f, +0.11644f,0.855496f,-0.504548f, +0.0395982f,0.813262f,-0.580548f, +0.00631598f,0.857568f,-0.514332f, +-0.0780909f,0.759651f,-0.645626f, +-0.0538158f,0.822232f,-0.566603f, +0.0102932f,0.785194f,-0.619165f, +-0.00905015f,0.879608f,-0.475613f, +0.0439442f,0.825793f,-0.562259f, +-0.15058f,0.877556f,-0.455216f, +-0.0080088f,0.902753f,-0.430085f, +-0.112334f,0.946952f,-0.301104f, +0.00843129f,0.966084f,-0.258092f, +-0.0520095f,0.981628f,-0.183579f, +-0.0023169f,0.970009f,-0.243057f, +-0.0302799f,0.995335f,-0.0916051f, +0.0376961f,0.991328f,-0.125888f, +0.0852061f,0.995425f,-0.0432221f, +0.156966f,0.986644f,0.0435404f, +0.21491f,0.973384f,-0.079613f, +0.060548f,0.977921f,-0.200013f, +0.158822f,0.967125f,-0.198606f, +0.134591f,0.957423f,-0.255396f, +0.121293f,0.978974f,-0.164008f, +0.108432f,0.947609f,-0.300465f, +0.0857608f,0.988377f,-0.125519f, +0.0956294f,0.951748f,-0.291599f, +-0.0286686f,0.995404f,-0.0913747f, +0.0793846f,0.975448f,-0.205424f, +0.106071f,0.990697f,0.085251f, +0.292453f,0.941038f,0.170056f, +0.371746f,0.914213f,0.161306f, +0.341006f,0.933768f,0.108596f, +0.372402f,0.920827f,0.115737f, +0.298439f,0.950662f,-0.0847083f, +0.211549f,0.974139f,0.0793788f, +0.255698f,0.96634f,-0.0283838f, +-0.0706076f,0.991212f,0.111867f, +0.0490836f,0.977096f,0.207063f, +-0.256838f,0.950876f,0.172827f, +-0.168627f,0.937168f,0.30542f, +-0.0642391f,0.963856f,0.258562f, +-0.00196823f,0.905532f,0.424274f, +0.182795f,0.945782f,0.268481f, +0.13515f,0.919671f,0.368699f, +0.107184f,0.970151f,0.217528f, +0.00985613f,0.977921f,0.208742f, +0.0734564f,0.98632f,0.147572f, +0.067487f,0.972043f,0.224896f, +0.20672f,0.968081f,0.141727f, +0.186648f,0.970679f,0.151478f, +0.213561f,0.965286f,0.150383f, +0.189498f,0.980689f,0.0483704f, +0.277013f,0.94213f,0.188824f, +0.316429f,0.927757f,0.197839f, +0.225121f,0.964838f,0.135677f, +0.124434f,0.992109f,0.0153398f, +0.14416f,0.987262f,0.0673169f, +0.128154f,0.991727f,-0.0073791f, +0.1809f,0.982671f,0.0404037f, +0.125271f,0.99083f,-0.0506329f, +0.117639f,0.992303f,-0.0386759f, +0.0449726f,0.973305f,-0.225068f, +0.124809f,0.992058f,0.0156083f, +0.127135f,0.958258f,-0.256082f, +0.171896f,0.982167f,0.0761593f, +0.160304f,0.951991f,-0.260798f, +-0.494953f,0.868907f,-0.00477061f, +-0.512017f,0.856533f,0.0647248f, +-0.564588f,0.823588f,0.0542513f, +-0.480746f,0.876502f,0.0250513f, +-0.397786f,0.91419f,0.0776024f, +-0.3922f,0.916181f,0.0824136f, +-0.288362f,0.955571f,0.0610852f, +-0.109541f,0.991807f,0.0657195f, +-0.119597f,0.99188f,-0.0432477f, +-0.0246849f,0.992746f,-0.117673f, +0.197846f,0.964215f,-0.176481f, +0.198977f,0.940868f,-0.274182f, +0.288209f,0.884317f,-0.367314f, +0.309487f,0.847917f,-0.430411f, +0.274335f,0.939851f,-0.20352f, +0.256503f,0.958634f,-0.123399f, +0.0454718f,0.993939f,-0.100084f, +-0.104233f,0.980418f,0.167081f, +-0.137204f,0.957647f,0.253153f, +-0.0909923f,0.97094f,0.221352f, +-0.0588081f,0.977218f,0.203928f, +0.0555628f,0.971956f,0.228506f, +0.00693538f,0.995197f,0.0976442f, +0.0112691f,0.996103f,-0.0874744f, +0.104487f,0.972486f,-0.208215f, +0.102504f,0.971128f,-0.215412f, +0.0933319f,0.976682f,-0.193342f, +0.023135f,0.974909f,-0.221399f, +0.0195254f,0.964185f,-0.264511f, +0.0843961f,0.966003f,-0.244368f, +0.0791804f,0.94997f,-0.30214f, +0.048562f,0.904645f,-0.423391f, +0.168302f,0.901104f,-0.399607f, +0.0460994f,0.899241f,-0.435018f, +-0.0201301f,0.942734f,-0.332937f, +-0.0651933f,0.964794f,-0.254799f, +-0.107417f,0.971064f,-0.213298f, +-0.17484f,0.97454f,-0.140369f, +-0.26177f,0.957564f,-0.120611f, +-0.18964f,0.980348f,-0.0543506f, +-0.0244255f,0.999511f,-0.0195208f, +0.0943164f,0.983888f,-0.151887f, +0.241216f,0.961222f,-0.133665f, +0.186016f,0.976207f,-0.111437f, +0.0288865f,0.998091f,-0.0545842f, +-0.00269516f,0.997826f,0.0658428f, +-0.0454406f,0.988515f,0.144131f, +0.0349744f,0.994103f,0.102646f, +0.310638f,0.939659f,0.143339f, +0.362637f,0.904005f,0.226428f, +0.268459f,0.940968f,0.206177f, +-0.0101438f,0.990408f,0.137803f, +-0.259956f,0.964753f,0.0409231f, +-0.105214f,0.99436f,0.0133734f, +0.151003f,0.984401f,0.0902917f, +0.153972f,0.971331f,0.181133f, +0.131893f,0.982033f,0.134962f, +0.145326f,0.983866f,0.104346f, +0.172165f,0.970545f,0.16853f, +0.260168f,0.947172f,0.18756f, +0.265906f,0.934787f,0.235514f, +0.175251f,0.956563f,0.232968f, +0.205308f,0.948623f,0.240753f, +0.093567f,0.968565f,0.230493f, +0.000708259f,0.964766f,0.263107f, +0.00657781f,0.964909f,0.262504f, +-0.520396f,0.851586f,0.063156f, +-0.521936f,0.850242f,0.0683468f, +-0.537166f,0.843365f,0.0137284f, +-0.507784f,0.86143f,-0.00972442f, +-0.393238f,0.917684f,0.0567504f, +-0.362634f,0.931285f,-0.0347048f, +-0.298916f,0.951591f,-0.0715749f, +-0.125797f,0.991634f,-0.0289454f, +0.00629701f,0.999979f,0.00117199f, +0.0170902f,0.994718f,-0.101214f, +0.290594f,0.952688f,-0.0891078f, +0.285259f,0.936469f,-0.20409f, +0.342737f,0.918097f,-0.199071f, +0.262981f,0.956466f,-0.126547f, +-0.000199178f,0.996828f,-0.0795833f, +0.16652f,0.978742f,0.119733f, +0.0382843f,0.984413f,0.171653f, +-0.277981f,0.950703f,0.137441f, +-0.18354f,0.954113f,0.236605f, +-0.0382213f,0.967232f,0.251001f, +-0.0471282f,0.983482f,0.174763f, +0.05509f,0.990469f,0.126237f, +0.154415f,0.97865f,0.135647f, +0.187824f,0.979878f,0.0675348f, +0.226039f,0.971999f,-0.0642243f, +0.0780765f,0.982532f,-0.168921f, +0.109774f,0.985685f,-0.127961f, +0.112009f,0.982676f,-0.147653f, +0.0632751f,0.975786f,-0.209375f, +0.0264674f,0.962968f,-0.268312f, +0.10845f,0.959018f,-0.261771f, +0.0643921f,0.961817f,-0.266009f, +0.166593f,0.964859f,-0.203209f, +0.0747121f,0.973608f,-0.215653f, +-0.165051f,0.968419f,-0.186874f, +-0.148108f,0.983106f,-0.10755f, +-0.179372f,0.979451f,-0.0922022f, +-0.237948f,0.970437f,-0.0404116f, +-0.2824f,0.959184f,-0.014723f, +-0.146028f,0.988959f,-0.0252228f, +0.05616f,0.991975f,-0.113275f, +0.196359f,0.969761f,-0.144935f, +0.181455f,0.976082f,-0.119739f, +0.110973f,0.993178f,-0.035804f, +-0.0390828f,0.998775f,0.0303582f, +-0.136356f,0.988616f,0.0636122f, +-0.0521843f,0.980102f,0.191512f, +0.0572854f,0.981374f,0.183367f, +0.238568f,0.946616f,0.216801f, +0.340107f,0.907515f,0.246464f, +0.312043f,0.926088f,0.212108f, +0.0846085f,0.98223f,0.167527f, +-0.163231f,0.986101f,0.0309937f, +-0.143013f,0.98971f,-0.00457425f, +0.0291614f,0.993948f,0.105909f, +0.107232f,0.980268f,0.16606f, +0.13514f,0.977368f,0.162754f, +0.171582f,0.963454f,0.205708f, +0.160805f,0.97344f,0.162963f, +0.206565f,0.959827f,0.189905f, +0.203733f,0.939018f,0.277016f, +0.156541f,0.940477f,0.30166f, +0.14264f,0.938158f,0.315457f, +0.0877292f,0.924317f,0.371405f, +0.0427952f,0.921735f,0.385453f, +0.102307f,0.915297f,0.389569f, +-0.518725f,0.854828f,-0.0138881f, +-0.516652f,0.85588f,0.023226f, +-0.490153f,0.869598f,0.0595683f, +-0.505693f,0.862598f,-0.0140982f, +-0.393758f,0.918824f,-0.0267811f, +-0.308114f,0.951253f,-0.0135724f, +-0.25353f,0.967309f,0.00592796f, +-0.183935f,0.978787f,-0.0902442f, +-0.0335384f,0.998587f,-0.0412272f, +0.0888831f,0.995408f,-0.0355216f, +0.275528f,0.951614f,-0.136073f, +0.317879f,0.941106f,-0.115209f, +0.22556f,0.974028f,-0.0197739f, +0.262726f,0.954534f,0.140851f, +0.0383338f,0.998565f,0.0373963f, +0.0108706f,0.999386f,-0.0333096f, +0.0472758f,0.987524f,0.150202f, +-0.22401f,0.968166f,0.111686f, +-0.221122f,0.974472f,0.0388438f, +-0.0303833f,0.999266f,0.0233175f, +0.0911048f,0.995841f,0.000284795f, +0.0750561f,0.987717f,-0.137044f, +0.140099f,0.985231f,-0.098447f, +0.159287f,0.981153f,-0.10939f, +0.301657f,0.953265f,-0.0169985f, +0.140836f,0.988971f,-0.0458453f, +0.074059f,0.996008f,-0.0498236f, +0.0873182f,0.996023f,-0.0176849f, +0.132872f,0.990946f,0.019257f, +0.15553f,0.982355f,-0.103875f, +0.133638f,0.955183f,-0.264135f, +0.0505536f,0.951293f,-0.304114f, +0.0663471f,0.962897f,-0.261588f, +0.0679148f,0.992885f,-0.0978063f, +-0.186921f,0.976146f,-0.110452f, +-0.16844f,0.980926f,-0.0970201f, +-0.17716f,0.9831f,-0.0461376f, +-0.252028f,0.967676f,-0.00920485f, +-0.25063f,0.967236f,-0.0404965f, +-0.0995772f,0.983353f,-0.151991f, +0.0940064f,0.974734f,-0.202626f, +0.146102f,0.962693f,-0.227766f, +0.10874f,0.966405f,-0.232891f, +-0.0013416f,0.987029f,-0.160533f, +-0.0603915f,0.998129f,0.00954783f, +-0.17946f,0.98293f,0.040526f, +-0.153066f,0.978461f,0.138509f, +0.00546813f,0.977756f,0.209673f, +0.202775f,0.944505f,0.258443f, +0.334531f,0.904949f,0.262976f, +0.339399f,0.898505f,0.278385f, +0.212792f,0.950144f,0.227917f, +-0.0583572f,0.996371f,0.0619671f, +-0.218128f,0.975136f,0.0391184f, +-0.0703437f,0.983861f,0.16453f, +0.113041f,0.961301f,0.25124f, +0.0979771f,0.959037f,0.265798f, +0.151767f,0.929082f,0.337302f, +0.185905f,0.937423f,0.294409f, +0.169611f,0.955662f,0.240713f, +0.159864f,0.96582f,0.204047f, +0.151538f,0.965571f,0.211446f, +0.11661f,0.954852f,0.273241f, +0.0708035f,0.941966f,0.328158f, +-0.00402057f,0.956357f,0.292174f, +0.0123647f,0.956622f,0.291069f, +-0.626234f,0.777268f,-0.0607036f, +-0.590408f,0.806122f,0.0398278f, +-0.512253f,0.84829f,0.134171f, +-0.429387f,0.891471f,0.144588f, +-0.394702f,0.915407f,0.0789917f, +-0.352114f,0.935018f,0.0419128f, +-0.269358f,0.962596f,0.0292454f, +-0.0709514f,0.996127f,0.0519312f, +-0.0485279f,0.996417f,-0.069268f, +0.139101f,0.983953f,-0.111751f, +0.369972f,0.916386f,-0.152833f, +0.200502f,0.96864f,-0.146752f, +0.063154f,0.997971f,0.00814434f, +0.218613f,0.964332f,0.149236f, +0.233367f,0.966768f,0.104401f, +0.00832713f,0.995958f,-0.0894382f, +-0.101235f,0.994608f,-0.0224841f, +-0.188929f,0.980627f,0.051742f, +-0.131276f,0.990999f,0.026226f, +0.0111642f,0.996226f,-0.0860703f, +0.127344f,0.982944f,-0.132683f, +0.133649f,0.978353f,-0.157998f, +0.127047f,0.978674f,-0.161419f, +0.154013f,0.97768f,-0.142902f, +0.207952f,0.974577f,-0.0833996f, +0.130584f,0.99044f,-0.0444555f, +0.0527996f,0.997244f,-0.0521173f, +0.0873033f,0.993919f,-0.0671111f, +0.134372f,0.9813f,-0.137819f, +0.302979f,0.937443f,-0.171475f, +0.235087f,0.922651f,-0.305694f, +0.116878f,0.945593f,-0.303632f, +-0.0892912f,0.947762f,-0.306226f, +-0.0487728f,0.993685f,-0.101049f, +-0.161853f,0.9816f,-0.101314f, +-0.226351f,0.97061f,-0.0817454f, +-0.270044f,0.962691f,-0.0173905f, +-0.294262f,0.954053f,0.0565031f, +-0.151555f,0.985239f,0.0795882f, +0.00297078f,0.999916f,-0.0126498f, +0.158118f,0.985077f,-0.067991f, +0.232676f,0.957923f,-0.168067f, +0.184787f,0.953241f,-0.239135f, +-0.102652f,0.943763f,-0.314284f, +-0.249925f,0.941897f,-0.224429f, +-0.230538f,0.969668f,-0.0812203f, +-0.256878f,0.964046f,-0.0680376f, +-0.0528332f,0.99816f,0.0297627f, +0.16253f,0.979605f,0.118148f, +0.292443f,0.935246f,0.199479f, +0.337448f,0.899957f,0.276054f, +0.288581f,0.911989f,0.291541f, +0.0381605f,0.961598f,0.271797f, +-0.217082f,0.942133f,0.25546f, +-0.187341f,0.947099f,0.26059f, +0.0122725f,0.939216f,0.343107f, +0.0450967f,0.927047f,0.372224f, +0.0805118f,0.921403f,0.380178f, +0.269621f,0.884781f,0.380089f, +0.278457f,0.920235f,0.275007f, +0.240432f,0.950543f,0.19662f, +0.110916f,0.980787f,0.160482f, +0.0190768f,0.974013f,0.225685f, +0.0421661f,0.96323f,0.26535f, +0.0623149f,0.965243f,0.253816f, +0.0484827f,0.970002f,0.238214f, +-0.675447f,0.735679f,-0.050474f, +-0.639324f,0.768795f,-0.0148056f, +-0.556082f,0.830482f,0.0327513f, +-0.42972f,0.893254f,0.132053f, +-0.365389f,0.922739f,0.122653f, +-0.226979f,0.966229f,0.121993f, +-0.221717f,0.973751f,-0.051483f, +-0.0779728f,0.987923f,-0.133899f, +0.0930073f,0.979917f,-0.176386f, +0.192144f,0.942491f,-0.27348f, +0.309496f,0.916222f,-0.254459f, +0.155051f,0.977443f,-0.143405f, +-0.0554135f,0.989739f,-0.131708f, +0.110672f,0.991805f,-0.0638304f, +0.310319f,0.950296f,0.0252996f, +0.103349f,0.993006f,-0.0570824f, +-0.143599f,0.988502f,-0.0473533f, +-0.226116f,0.973312f,-0.0391734f, +-0.100068f,0.994649f,-0.0257001f, +0.124656f,0.989757f,-0.0695779f, +0.137305f,0.97907f,-0.150231f, +0.12072f,0.989818f,-0.075415f, +0.132256f,0.990827f,-0.0277589f, +0.0994133f,0.991446f,-0.0845708f, +0.16457f,0.984921f,-0.0533595f, +0.161357f,0.986289f,-0.034624f, +0.0776395f,0.993281f,-0.0858198f, +0.196429f,0.972629f,-0.124127f, +0.213597f,0.93634f,-0.278645f, +0.333587f,0.906552f,-0.258619f, +0.264447f,0.928271f,-0.261499f, +0.0224352f,0.968338f,-0.248633f, +-0.153007f,0.973949f,-0.167368f, +-0.171971f,0.976037f,-0.133332f, +-0.164739f,0.982172f,-0.0905542f, +-0.256427f,0.965345f,-0.0485236f, +-0.266685f,0.961164f,-0.0710119f, +-0.315314f,0.936338f,-0.154429f, +-0.180509f,0.974939f,-0.130043f, +0.0306802f,0.996715f,-0.0749509f, +0.181216f,0.981966f,-0.0538862f, +0.308423f,0.951239f,-0.0044789f, +0.193412f,0.981099f,-0.00609358f, +-0.00883535f,0.999181f,0.039479f, +-0.293629f,0.95203f,-0.0861418f, +-0.288511f,0.952707f,-0.0954526f, +-0.270635f,0.961763f,-0.0420598f, +-0.176015f,0.982039f,0.0679556f, +0.0472003f,0.981703f,0.184478f, +0.185293f,0.947852f,0.259313f, +0.26012f,0.901797f,0.345109f, +0.219376f,0.887657f,0.404894f, +0.015248f,0.892187f,0.451408f, +-0.212632f,0.887876f,0.407999f, +-0.145904f,0.908525f,0.391529f, +-0.0226457f,0.932703f,0.359933f, +0.0874951f,0.910834f,0.403393f, +0.125007f,0.935932f,0.329249f, +0.288568f,0.918223f,0.271284f, +0.34457f,0.896771f,0.277619f, +0.261558f,0.928634f,0.263108f, +0.0802026f,0.961218f,0.26387f, +0.0163948f,0.952196f,0.305047f, +0.0566148f,0.964684f,0.257253f, +0.102872f,0.970943f,0.216073f, +0.0353576f,0.994079f,0.102749f, +-0.569322f,0.820332f,-0.0541097f, +-0.616679f,0.764093f,-0.18939f, +-0.605157f,0.764062f,-0.223597f, +-0.50856f,0.856476f,-0.0884048f, +-0.372491f,0.927008f,0.0436669f, +-0.225048f,0.969626f,0.0958063f, +-0.0508165f,0.996801f,0.0616925f, +0.0586358f,0.990558f,-0.123919f, +0.126111f,0.966195f,-0.224862f, +0.229194f,0.950926f,-0.207869f, +0.252375f,0.936474f,-0.243564f, +0.0944308f,0.971404f,-0.217846f, +-0.0355117f,0.972557f,-0.229939f, +0.0856503f,0.962722f,-0.256575f, +0.220711f,0.941477f,-0.254769f, +0.0934053f,0.989629f,-0.109133f, +-0.156897f,0.986627f,-0.0441527f, +-0.224564f,0.970579f,-0.0868729f, +-0.0948813f,0.992594f,-0.0758608f, +0.168753f,0.983045f,-0.0717275f, +0.110894f,0.991432f,-0.0690319f, +-0.0147158f,0.998265f,0.0570193f, +0.10964f,0.979883f,0.16676f, +0.213201f,0.96906f,0.124368f, +0.195873f,0.980015f,-0.0346975f, +0.162476f,0.975738f,-0.146751f, +0.136902f,0.9692f,-0.204718f, +0.244929f,0.933568f,-0.26165f, +0.288988f,0.918188f,-0.270954f, +0.254175f,0.924529f,-0.283974f, +0.243695f,0.954587f,-0.171397f, +-0.00175415f,0.99017f,-0.13986f, +-0.165264f,0.975245f,-0.146916f, +-0.185767f,0.967008f,-0.174319f, +-0.191354f,0.972667f,-0.131541f, +-0.271241f,0.952999f,-0.134987f, +-0.1847f,0.972855f,-0.139424f, +-0.209304f,0.957842f,-0.1968f, +-0.243194f,0.936f,-0.254482f, +-0.0210884f,0.983365f,-0.18041f, +0.0761402f,0.989042f,-0.126486f, +0.185372f,0.981538f,0.047127f, +0.117606f,0.973445f,0.196404f, +-0.0453061f,0.954332f,0.295292f, +-0.152267f,0.943756f,0.293495f, +-0.272105f,0.944288f,0.185149f, +-0.341417f,0.929337f,0.140592f, +-0.316477f,0.938022f,0.141266f, +-0.0291064f,0.965694f,0.258045f, +0.139271f,0.938861f,0.31487f, +0.16066f,0.916793f,0.36562f, +0.163005f,0.879828f,0.446466f, +0.088987f,0.884248f,0.458461f, +-0.126118f,0.932849f,0.337472f, +-0.101381f,0.953175f,0.284919f, +-0.0233764f,0.967738f,0.250872f, +0.0600962f,0.965273f,0.254236f, +0.184472f,0.94915f,0.255117f, +0.293565f,0.911429f,0.288301f, +0.309916f,0.89217f,0.328611f, +0.260108f,0.896879f,0.357704f, +0.0945809f,0.935133f,0.341439f, +0.0335311f,0.964748f,0.261032f, +0.0942492f,0.979731f,0.176762f, +0.167685f,0.967918f,0.187127f, +0.258869f,0.942682f,0.210564f, +-0.367443f,0.929937f,-0.0142236f, +-0.499723f,0.853143f,-0.149749f, +-0.60287f,0.768676f,-0.213739f, +-0.628893f,0.759885f,-0.164524f, +-0.498958f,0.866588f,-0.00814533f, +-0.266358f,0.961387f,0.0691948f, +0.0209306f,0.994406f,0.103533f, +0.18825f,0.979809f,0.0673512f, +0.186929f,0.982347f,-0.00722501f, +0.221871f,0.971137f,-0.0875532f, +0.321849f,0.94224f,-0.0927163f, +0.129468f,0.975377f,-0.178544f, +-0.0214597f,0.975387f,-0.219454f, +0.135606f,0.972282f,-0.19047f, +0.166947f,0.968719f,-0.18361f, +-0.0604962f,0.993281f,-0.0986602f, +-0.147333f,0.985679f,-0.0820398f, +-0.177745f,0.972235f,-0.152201f, +-0.13389f,0.979994f,-0.147259f, +0.107621f,0.993068f,-0.0472599f, +0.0496354f,0.9956f,0.0794756f, +-0.114638f,0.990271f,0.0788811f, +0.0386746f,0.994961f,0.0924988f, +0.257639f,0.951075f,0.170521f, +0.371556f,0.918219f,0.137186f, +0.306734f,0.951256f,-0.0320228f, +0.251981f,0.957147f,-0.142743f, +0.259956f,0.937158f,-0.232721f, +0.273432f,0.938847f,-0.209289f, +0.242378f,0.942977f,-0.228139f, +0.135357f,0.967026f,-0.21573f, +-0.0237633f,0.989278f,-0.144096f, +-0.131198f,0.984621f,-0.11536f, +-0.202181f,0.972555f,-0.115152f, +-0.221308f,0.9725f,-0.0725642f, +-0.229514f,0.969023f,-0.0912046f, +-0.218972f,0.967608f,-0.125639f, +-0.212632f,0.976006f,-0.0469096f, +-0.218674f,0.974967f,-0.0402565f, +-0.122558f,0.989962f,-0.0703905f, +0.0166378f,0.999654f,0.0203946f, +-0.0104674f,0.996634f,0.0813074f, +-0.0169459f,0.959611f,0.28082f, +-0.0960206f,0.935549f,0.339894f, +-0.167668f,0.926307f,0.337405f, +-0.198261f,0.909687f,0.364915f, +-0.193335f,0.935754f,0.294935f, +-0.259424f,0.960196f,0.103554f, +-0.126539f,0.989254f,0.073239f, +0.0445245f,0.981975f,0.183692f, +0.070195f,0.9396f,0.334999f, +0.116045f,0.901991f,0.415867f, +0.160437f,0.912696f,0.375828f, +-0.00552585f,0.963507f,0.267627f, +-0.111729f,0.971129f,0.210774f, +0.00935468f,0.964114f,0.265323f, +0.084172f,0.968508f,0.234323f, +0.13752f,0.967988f,0.209968f, +0.208575f,0.947382f,0.242826f, +0.289545f,0.920265f,0.263203f, +0.228797f,0.929214f,0.290195f, +0.185013f,0.916649f,0.354295f, +0.160823f,0.950358f,0.266374f, +0.183734f,0.959776f,0.212302f, +0.0865279f,0.982909f,0.162492f, +0.143782f,0.963199f,0.227098f, +-0.40108f,0.898526f,-0.178287f, +-0.447805f,0.881163f,-0.15173f, +-0.619629f,0.769135f,-0.156501f, +-0.663764f,0.743697f,-0.0795752f, +-0.534645f,0.83883f,-0.102567f, +-0.293541f,0.950588f,-0.101077f, +-0.0154638f,0.998684f,-0.048892f, +0.170364f,0.984269f,-0.0468065f, +0.272586f,0.961403f,-0.0374194f, +0.276742f,0.955139f,-0.105472f, +0.3572f,0.929651f,-0.0903144f, +0.185848f,0.967712f,-0.170277f, +-0.00167559f,0.978573f,-0.205892f, +0.0698456f,0.971595f,-0.226108f, +0.0821889f,0.985623f,-0.147624f, +-0.0376538f,0.998466f,-0.0405822f, +-0.0983702f,0.988409f,-0.115634f, +-0.140633f,0.987279f,-0.0741791f, +-0.185061f,0.981813f,-0.0423742f, +-0.0718387f,0.997236f,0.0189748f, +0.00846681f,0.991398f,0.130611f, +0.00870324f,0.999937f,0.00714861f, +0.043927f,0.984772f,-0.168207f, +0.173423f,0.967972f,-0.181535f, +0.363952f,0.925731f,-0.10277f, +0.415083f,0.906279f,-0.0797799f, +0.295656f,0.934439f,-0.198525f, +0.285411f,0.94244f,-0.174208f, +0.286359f,0.952372f,-0.104818f, +0.274f,0.954057f,-0.121243f, +0.125082f,0.985323f,-0.116157f, +-0.0728358f,0.994219f,-0.0788892f, +-0.183935f,0.981488f,-0.0533801f, +-0.254614f,0.966975f,0.0114848f, +-0.238556f,0.965368f,0.105624f, +-0.207746f,0.971319f,0.115674f, +-0.215469f,0.971204f,0.101667f, +-0.267107f,0.96138f,0.0663435f, +-0.207576f,0.97646f,0.0586408f, +-0.117358f,0.991748f,0.0516096f, +-0.0500459f,0.994852f,0.0881198f, +-0.093813f,0.986665f,0.133006f, +-0.152698f,0.969858f,0.18989f, +-0.1251f,0.953778f,0.273236f, +-0.165614f,0.925222f,0.341373f, +-0.185498f,0.929562f,0.3186f, +-0.115032f,0.960173f,0.254626f, +-0.110794f,0.97049f,0.214181f, +-0.10146f,0.992209f,0.072301f, +-0.111958f,0.99337f,0.026117f, +-0.0975457f,0.980844f,0.168611f, +0.086247f,0.976994f,0.195051f, +0.241113f,0.947591f,0.20961f, +0.0868755f,0.959222f,0.268972f, +-0.141994f,0.949853f,0.278599f, +-0.0178282f,0.934163f,0.356401f, +0.0726972f,0.940594f,0.331659f, +0.165529f,0.917627f,0.361333f, +0.223743f,0.920886f,0.319231f, +0.302189f,0.900958f,0.311378f, +0.181249f,0.939198f,0.291642f, +0.15269f,0.934294f,0.32215f, +0.181639f,0.932767f,0.311371f, +0.174351f,0.925291f,0.336805f, +0.107261f,0.938861f,0.327163f, +0.0621733f,0.949825f,0.306542f, +-0.336425f,0.924181f,-0.180852f, +-0.467727f,0.856958f,-0.216458f, +-0.602238f,0.781026f,-0.165251f, +-0.647361f,0.734151f,-0.204809f, +-0.50962f,0.821617f,-0.255407f, +-0.329682f,0.908003f,-0.258533f, +-0.0514578f,0.97257f,-0.226846f, +0.197411f,0.959315f,-0.201849f, +0.264136f,0.946231f,-0.186758f, +0.271989f,0.947232f,-0.169627f, +0.342182f,0.926412f,-0.157076f, +0.226068f,0.960114f,-0.164544f, +0.0298714f,0.986995f,-0.157954f, +0.0947848f,0.979734f,-0.176458f, +0.0184686f,0.978597f,-0.204958f, +-0.115417f,0.979217f,-0.166771f, +-0.133289f,0.987752f,-0.0811202f, +-0.254272f,0.966705f,0.0287551f, +-0.238007f,0.962858f,0.127508f, +-0.0805244f,0.989118f,0.123135f, +0.0609568f,0.996652f,0.0544921f, +0.185345f,0.981121f,-0.0552078f, +0.246025f,0.947034f,-0.206392f, +0.188933f,0.898455f,-0.396338f, +0.253355f,0.896162f,-0.364288f, +0.431339f,0.877591f,-0.209237f, +0.33179f,0.90994f,-0.248847f, +0.173449f,0.964884f,-0.197267f, +0.195848f,0.971573f,-0.133f, +0.242458f,0.968164f,-0.0622215f, +0.0872514f,0.995924f,0.0228468f, +-0.104392f,0.994289f,0.0221861f, +-0.212909f,0.976423f,0.0355982f, +-0.329497f,0.936369f,0.121017f, +-0.322708f,0.91595f,0.238528f, +-0.206447f,0.929806f,0.304697f, +-0.167225f,0.947523f,0.272462f, +-0.184928f,0.959175f,0.213976f, +-0.173343f,0.972643f,0.154651f, +-0.113658f,0.986612f,0.116951f, +-0.0855668f,0.994338f,0.0630098f, +-0.114452f,0.992427f,0.0446133f, +-0.159653f,0.986324f,0.0409453f, +-0.238644f,0.971105f,-0.00174015f, +-0.263001f,0.962569f,0.0655076f, +-0.150786f,0.97653f,0.153794f, +-0.0789227f,0.973225f,0.21588f, +-0.0862836f,0.967962f,0.235807f, +0.0429765f,0.969236f,0.242351f, +-0.0440941f,0.992467f,0.114305f, +-0.115348f,0.992717f,-0.0347649f, +0.0790257f,0.995351f,-0.0550642f, +0.126473f,0.98592f,0.109395f, +-0.0409487f,0.953557f,0.298417f, +-0.206016f,0.913735f,0.350208f, +-0.0633912f,0.92675f,0.370293f, +0.0785739f,0.913264f,0.399719f, +0.177609f,0.899902f,0.398285f, +0.238034f,0.923241f,0.301604f, +0.255943f,0.926508f,0.27582f, +0.232022f,0.914012f,0.332787f, +0.162081f,0.936068f,0.312259f, +0.177513f,0.926269f,0.332437f, +0.185532f,0.921601f,0.340924f, +0.173632f,0.950356f,0.258214f, +0.111166f,0.980225f,0.163712f, +-0.0923042f,0.995727f,-0.00270435f, +-0.408896f,0.902709f,-0.133863f, +-0.602302f,0.79183f,-0.10118f, +-0.624884f,0.765307f,-0.154352f, +-0.552184f,0.809036f,-0.201379f, +-0.343811f,0.917937f,-0.197956f, +-0.0748905f,0.960991f,-0.266248f, +0.134998f,0.958099f,-0.252631f, +0.206547f,0.962195f,-0.177534f, +0.264489f,0.960553f,-0.0859237f, +0.340814f,0.939333f,-0.0387315f, +0.235136f,0.971602f,-0.0264814f, +0.0144037f,0.991275f,-0.131023f, +0.053242f,0.991683f,-0.117173f, +0.0920982f,0.995717f,0.00816044f, +-0.164789f,0.980567f,-0.106454f, +-0.239234f,0.97035f,-0.0344802f, +-0.316227f,0.948287f,0.0274269f, +-0.260328f,0.965493f,0.00728909f, +-0.00635978f,0.999169f,0.0402508f, +0.152101f,0.988094f,-0.023159f, +0.261272f,0.960304f,-0.0977355f, +0.363311f,0.923635f,-0.122082f, +0.303719f,0.94151f,-0.145994f, +0.209258f,0.960639f,-0.182713f, +0.299827f,0.935978f,-0.184526f, +0.310225f,0.948937f,-0.0572597f, +0.134013f,0.988326f,-0.0724722f, +0.173294f,0.983169f,-0.0578515f, +0.150596f,0.988589f,-0.00352276f, +0.0218728f,0.99535f,0.093809f, +-0.090936f,0.980927f,0.171796f, +-0.253868f,0.938693f,0.233251f, +-0.400767f,0.870372f,0.286074f, +-0.392418f,0.877786f,0.274773f, +-0.219224f,0.925755f,0.308089f, +-0.114269f,0.92983f,0.349798f, +-0.147993f,0.921652f,0.358685f, +-0.138523f,0.925121f,0.353501f, +-0.0290531f,0.945854f,0.32329f, +0.0440242f,0.978167f,0.203106f, +-0.0576599f,0.997178f,0.0480716f, +-0.156038f,0.987653f,-0.0139414f, +-0.143901f,0.989541f,-0.0100722f, +-0.293059f,0.951458f,-0.0940478f, +-0.298958f,0.953936f,-0.0251005f, +-0.203233f,0.972711f,0.111937f, +-0.134891f,0.965356f,0.223367f, +-0.0182075f,0.958686f,0.283884f, +0.123188f,0.934113f,0.33505f, +0.0872404f,0.983488f,0.15856f, +0.00440122f,0.999845f,-0.0170726f, +-0.143813f,0.987727f,0.0609306f, +-0.192356f,0.942318f,0.273927f, +-0.141157f,0.926207f,0.349593f, +-0.0674076f,0.959831f,0.272363f, +0.0730938f,0.959591f,0.27174f, +0.173541f,0.961002f,0.215311f, +0.369237f,0.888798f,0.271483f, +0.277281f,0.944196f,0.177789f, +0.215184f,0.95909f,0.183961f, +0.13088f,0.973624f,0.186887f, +0.130607f,0.953976f,0.269946f, +0.212637f,0.930888f,0.297042f, +0.306976f,0.920481f,0.241829f, +0.280289f,0.947029f,0.156763f, +0.0123331f,0.988431f,0.151171f, +-0.297868f,0.952288f,0.0664969f, +-0.612229f,0.786332f,-0.0828155f, +-0.600387f,0.789438f,-0.127758f, +-0.542733f,0.826042f,-0.151972f, +-0.320126f,0.93364f,-0.160733f, +0.000589343f,0.981171f,-0.193142f, +0.0980808f,0.971507f,-0.215763f, +0.124748f,0.986178f,-0.109047f, +0.199191f,0.978521f,-0.0531043f, +0.247764f,0.965734f,-0.0772702f, +0.318214f,0.948019f,-0.000766246f, +0.183917f,0.97162f,-0.148756f, +-0.0488566f,0.965709f,-0.25499f, +-0.0165518f,0.99654f,-0.0814512f, +-0.0793375f,0.996823f,-0.00696945f, +-0.310737f,0.950344f,-0.0169863f, +-0.292329f,0.952706f,0.0830406f, +-0.217409f,0.975529f,0.0328f, +-0.044323f,0.995765f,-0.0805443f, +0.185778f,0.977354f,-0.101323f, +0.271832f,0.958328f,-0.0878372f, +0.32088f,0.946924f,0.019279f, +0.252443f,0.960909f,0.113697f, +0.290552f,0.947257f,0.135217f, +0.289238f,0.957058f,-0.0195476f, +0.286171f,0.957114f,0.0451517f, +0.220997f,0.975269f,0.00320969f, +0.0994052f,0.991378f,-0.0853655f, +0.0429034f,0.994069f,0.099932f, +-0.0709962f,0.952332f,0.296687f, +-0.214284f,0.897012f,0.38659f, +-0.318505f,0.838002f,0.443066f, +-0.352211f,0.849573f,0.392649f, +-0.30013f,0.898851f,0.319356f, +-0.250783f,0.928599f,0.273517f, +-0.200191f,0.919896f,0.337217f, +-0.179596f,0.907951f,0.378643f, +-0.135043f,0.919145f,0.370049f, +0.0368434f,0.920312f,0.389447f, +0.16581f,0.924682f,0.34274f, +0.0946402f,0.961136f,0.259346f, +-0.111217f,0.985094f,0.131228f, +-0.13188f,0.98641f,0.0979915f, +-0.254562f,0.966634f,0.028585f, +-0.324299f,0.94515f,-0.0390035f, +-0.293729f,0.954471f,-0.0520494f, +-0.247862f,0.966889f,0.0607495f, +-0.0794894f,0.980131f,0.181727f, +0.101373f,0.964007f,0.245794f, +0.197084f,0.947574f,0.251517f, +0.177833f,0.964662f,0.194431f, +-0.161149f,0.986485f,0.0296539f, +-0.316387f,0.94824f,0.02721f, +-0.207789f,0.976057f,0.0643106f, +-0.00905536f,0.99298f,0.117933f, +0.141544f,0.987983f,0.062088f, +0.189336f,0.98168f,-0.0213574f, +0.273454f,0.960225f,0.0564811f, +0.315806f,0.930776f,0.184181f, +0.235283f,0.955417f,0.17838f, +0.124851f,0.982004f,0.141708f, +0.0792257f,0.989953f,0.117114f, +0.210835f,0.9739f,0.0840678f, +0.31429f,0.942479f,0.113817f, +0.350241f,0.914076f,0.20444f, +0.0694749f,0.983151f,0.169077f, +-0.169784f,0.982476f,0.076909f, +-0.507716f,0.850133f,-0.139637f, +-0.564212f,0.800379f,-0.202629f, +-0.514428f,0.829332f,-0.218112f, +-0.369417f,0.885582f,-0.28156f, +0.00180169f,0.974596f,-0.223965f, +0.0258344f,0.976386f,-0.214484f, +-0.024f,0.996868f,-0.0753534f, +0.239975f,0.969587f,0.0481022f, +0.34797f,0.931588f,-0.105173f, +0.316295f,0.909782f,-0.268803f, +0.250422f,0.912989f,-0.322087f, +-0.0369252f,0.950156f,-0.30958f, +-0.207502f,0.950188f,-0.232562f, +-0.167975f,0.985706f,-0.0129903f, +-0.315712f,0.948273f,0.0332206f, +-0.386969f,0.921609f,-0.0298463f, +-0.12805f,0.991662f,0.0144567f, +0.102711f,0.991948f,-0.0740863f, +0.21217f,0.967879f,-0.134884f, +0.167738f,0.98185f,-0.0885116f, +0.176293f,0.984226f,0.0148055f, +0.233609f,0.968608f,0.0850021f, +0.30166f,0.950058f,0.0799509f, +0.387591f,0.914349f,0.117215f, +0.244561f,0.968825f,0.0395933f, +0.294792f,0.954101f,0.0528114f, +0.0843374f,0.996399f,0.00873819f, +-0.221704f,0.963341f,0.151067f, +-0.335663f,0.86809f,0.365719f, +-0.262618f,0.850841f,0.455085f, +-0.222709f,0.867235f,0.445313f, +-0.24917f,0.884312f,0.39485f, +-0.238336f,0.907466f,0.345978f, +-0.270997f,0.917236f,0.291956f, +-0.229194f,0.914337f,0.333853f, +-0.15897f,0.933059f,0.322692f, +-0.100911f,0.956766f,0.272794f, +-0.0211523f,0.974532f,0.223248f, +0.201297f,0.933635f,0.29632f, +0.155914f,0.954519f,0.254134f, +-0.0218294f,0.971898f,0.234389f, +-0.079809f,0.976613f,0.199646f, +-0.0874479f,0.990326f,0.10774f, +-0.258167f,0.959037f,-0.116608f, +-0.306401f,0.945943f,-0.106352f, +-0.341562f,0.936596f,-0.0782577f, +-0.199458f,0.979359f,-0.0327519f, +0.0464294f,0.997405f,0.0550308f, +0.191208f,0.978076f,0.0825056f, +0.238583f,0.96711f,0.0881811f, +-0.0888379f,0.993271f,0.0743033f, +-0.264236f,0.955782f,0.129075f, +-0.188913f,0.981529f,0.0302016f, +-0.0145673f,0.997134f,-0.0742444f, +0.169633f,0.978852f,-0.114338f, +0.20381f,0.976959f,-0.0633407f, +0.175314f,0.984354f,-0.0176521f, +0.240514f,0.967819f,0.0740208f, +0.244396f,0.964775f,0.0973589f, +0.18832f,0.980026f,0.0639107f, +0.156937f,0.987568f,-0.00896143f, +0.262584f,0.963481f,-0.0524761f, +0.165405f,0.986171f,-0.0103631f, +0.180443f,0.960877f,0.210132f, +0.22428f,0.955199f,0.193116f, +0.0674282f,0.994387f,0.0815297f, +-0.367623f,0.911009f,-0.186858f, +-0.569756f,0.78903f,-0.229805f, +-0.492917f,0.847419f,-0.197265f, +-0.366141f,0.895981f,-0.251313f, +-0.0646011f,0.969824f,-0.235091f, +0.018291f,0.976889f,-0.212961f, +-0.170757f,0.95698f,-0.234588f, +0.158661f,0.98264f,-0.0961541f, +0.509439f,0.859861f,-0.0333235f, +0.45757f,0.865797f,-0.202548f, +0.211042f,0.949174f,-0.233516f, +-0.116125f,0.987892f,-0.102876f, +-0.347298f,0.937329f,-0.028262f, +-0.3353f,0.938887f,0.0778782f, +-0.281604f,0.948411f,0.145656f, +-0.254278f,0.964997f,0.0642133f, +-0.124948f,0.985399f,-0.115656f, +0.137997f,0.981596f,-0.132006f, +0.145883f,0.979226f,-0.140833f, +0.128056f,0.990732f,-0.0452937f, +0.135002f,0.989818f,-0.0451192f, +0.250583f,0.968082f,-0.00493589f, +0.249752f,0.966686f,-0.056052f, +0.354812f,0.933896f,0.0441336f, +0.303438f,0.951308f,0.0542095f, +0.224177f,0.96836f,0.10965f, +0.0241424f,0.959753f,0.279804f, +-0.360787f,0.871516f,0.332105f, +-0.379082f,0.837086f,0.394442f, +-0.267154f,0.880877f,0.390749f, +-0.209592f,0.899886f,0.382462f, +-0.280017f,0.899934f,0.33423f, +-0.205094f,0.90311f,0.377265f, +-0.215487f,0.908768f,0.35736f, +-0.222303f,0.927919f,0.299247f, +-0.133955f,0.964793f,0.226343f, +-0.0310722f,0.978213f,0.205265f, +0.00222901f,0.986522f,0.163613f, +0.163026f,0.975343f,0.148754f, +0.222032f,0.968535f,0.112436f, +-0.0591592f,0.996482f,0.0593585f, +-0.0736093f,0.986012f,0.149538f, +0.0883465f,0.986402f,0.138585f, +-0.129755f,0.988677f,-0.0753772f, +-0.360418f,0.926521f,-0.10797f, +-0.325602f,0.942448f,-0.0759939f, +-0.212184f,0.970083f,-0.117968f, +-0.0173686f,0.99664f,-0.0800487f, +0.199307f,0.979749f,-0.0191744f, +0.207601f,0.977585f,-0.0350739f, +-0.111673f,0.993337f,0.0284751f, +-0.348081f,0.937445f,0.00599776f, +-0.0214784f,0.998661f,0.0470579f, +0.101424f,0.987937f,-0.11702f, +0.14864f,0.985437f,-0.0825872f, +0.115279f,0.993006f,0.0255073f, +0.132171f,0.98902f,0.0661133f, +0.208651f,0.976857f,0.0470664f, +0.263292f,0.96404f,0.0361305f, +0.248825f,0.968171f,0.0270552f, +0.185161f,0.982538f,-0.018271f, +0.217415f,0.97571f,0.0268649f, +0.0197241f,0.992022f,0.124516f, +-0.222642f,0.960275f,0.168234f, +0.132211f,0.987109f,0.0902005f, +0.194249f,0.96722f,0.163561f, +-0.121192f,0.992517f,0.0149198f, +-0.530811f,0.812343f,-0.241533f, +-0.504434f,0.808747f,-0.302447f, +-0.34313f,0.885425f,-0.313504f, +-0.137778f,0.93664f,-0.322061f, +0.0757018f,0.968813f,-0.235947f, +-0.132891f,0.938587f,-0.318425f, +0.0404124f,0.947798f,-0.316301f, +0.44786f,0.871235f,-0.200923f, +0.490699f,0.867082f,-0.0859319f, +0.104719f,0.99418f,-0.0252995f, +-0.266739f,0.955461f,0.126271f, +-0.36926f,0.905342f,0.209771f, +-0.330235f,0.922316f,0.200695f, +-0.269586f,0.955277f,0.121531f, +-0.151874f,0.986716f,0.0576671f, +-0.0142621f,0.999832f,-0.0115305f, +0.159425f,0.986955f,-0.0224599f, +0.153623f,0.986882f,-0.0496328f, +0.106278f,0.991325f,-0.0773283f, +0.114508f,0.986134f,-0.120113f, +0.21169f,0.974687f,-0.0719165f, +0.274634f,0.961096f,-0.0295159f, +0.269382f,0.962666f,0.0266079f, +0.255851f,0.94689f,0.19478f, +-0.00861224f,0.958716f,0.284234f, +-0.164949f,0.853283f,0.494671f, +-0.299895f,0.797641f,0.523289f, +-0.348319f,0.830543f,0.434595f, +-0.252787f,0.902204f,0.349467f, +-0.200686f,0.920719f,0.334665f, +-0.211731f,0.897332f,0.387253f, +-0.253565f,0.89104f,0.376502f, +-0.186105f,0.884245f,0.42834f, +-0.119153f,0.910802f,0.395274f, +-0.0259565f,0.945107f,0.325728f, +-0.0365208f,0.969055f,0.244127f, +0.0217438f,0.965814f,0.258322f, +0.21499f,0.950394f,0.224789f, +0.314831f,0.941255f,0.12215f, +-0.024099f,0.99913f,-0.0340298f, +-0.193558f,0.979871f,-0.0488714f, +0.141024f,0.987427f,0.0714227f, +0.042141f,0.998281f,-0.0407328f, +-0.330902f,0.928766f,-0.167024f, +-0.316891f,0.928564f,-0.193256f, +-0.212611f,0.956496f,-0.199781f, +-0.0848317f,0.98296f,-0.163073f, +0.159095f,0.98144f,-0.107074f, +0.142493f,0.988352f,-0.0534431f, +-0.0993206f,0.99343f,0.0568515f, +-0.282995f,0.956355f,-0.0727984f, +-0.0511781f,0.994657f,-0.0896605f, +0.128118f,0.991123f,0.0355009f, +0.0178584f,0.998165f,0.057865f, +0.0308308f,0.995199f,0.0928875f, +0.176093f,0.979878f,0.0939732f, +0.250441f,0.967914f,0.0205173f, +0.266597f,0.963616f,0.0192599f, +0.242746f,0.969766f,0.0250589f, +0.198829f,0.979834f,0.0197961f, +0.092758f,0.995177f,0.031931f, +-0.00514037f,0.987257f,0.15905f, +-0.197401f,0.976423f,0.0873538f, +0.0947848f,0.990346f,0.101148f, +0.11003f,0.98867f,0.102099f, +0.0979659f,0.987432f,0.124019f, +-0.288467f,0.943192f,-0.16485f, +-0.465875f,0.798355f,-0.381562f, +-0.320527f,0.848593f,-0.420894f, +-0.189264f,0.880141f,-0.435352f, +-0.0157309f,0.942454f,-0.333965f, +-0.0523924f,0.9528f,-0.299042f, +0.0243535f,0.924362f,-0.38074f, +0.347438f,0.877508f,-0.330555f, +0.339023f,0.92439f,-0.174834f, +0.0111821f,0.998297f,0.0572478f, +-0.344224f,0.932997f,0.105009f, +-0.433099f,0.895278f,0.104414f, +-0.282796f,0.937116f,0.204547f, +-0.130039f,0.982692f,0.131936f, +-0.0814764f,0.996291f,-0.027691f, +-0.0200688f,0.997106f,-0.0733289f, +0.118984f,0.992345f,-0.0330638f, +0.199561f,0.979885f,0.00110984f, +0.153394f,0.986654f,-0.0546216f, +0.176634f,0.980572f,-0.0853107f, +0.13548f,0.982889f,-0.124795f, +0.191838f,0.980855f,0.0334985f, +0.104996f,0.978045f,0.180009f, +0.00782433f,0.923816f,0.382758f, +-0.0895214f,0.848914f,0.520894f, +-0.239967f,0.84054f,0.485703f, +-0.280756f,0.842357f,0.460011f, +-0.207606f,0.901917f,0.378742f, +-0.122486f,0.94404f,0.306245f, +-0.244402f,0.93107f,0.270881f, +-0.292773f,0.891472f,0.345777f, +-0.276286f,0.909624f,0.310243f, +-0.213016f,0.932947f,0.290231f, +-0.0942691f,0.953854f,0.28509f, +-0.0105057f,0.953135f,0.302364f, +0.0307865f,0.936068f,0.35047f, +0.0538732f,0.955717f,0.289315f, +0.209391f,0.949668f,0.232994f, +0.403861f,0.868428f,0.287628f, +0.149382f,0.968969f,0.196936f, +-0.176548f,0.984269f,0.00674917f, +0.0687777f,0.996274f,-0.0520396f, +0.147821f,0.988716f,-0.0242998f, +-0.223164f,0.968308f,-0.112148f, +-0.295488f,0.928787f,-0.2237f, +-0.23574f,0.935973f,-0.261496f, +-0.100501f,0.963432f,-0.248392f, +0.0576299f,0.973773f,-0.220102f, +0.0436147f,0.999029f,-0.00621142f, +-0.153496f,0.982634f,0.104254f, +-0.184805f,0.972589f,0.141133f, +-0.14696f,0.984535f,0.0953571f, +-0.0211774f,0.989717f,0.141466f, +0.0758245f,0.9782f,0.193326f, +0.117048f,0.987762f,0.103083f, +0.217731f,0.97559f,-0.0285914f, +0.270726f,0.959521f,-0.0776314f, +0.230415f,0.971747f,-0.0511441f, +0.234903f,0.971865f,0.0172727f, +0.182122f,0.97948f,0.0863184f, +0.0884364f,0.988499f,0.122674f, +-0.00977715f,0.999042f,0.0426606f, +-0.0304096f,0.999492f,-0.00954367f, +0.200711f,0.957383f,0.207686f, +0.148405f,0.978101f,0.145929f, +0.14921f,0.978785f,0.140417f, +0.0273685f,0.999287f,0.0260052f, +-0.3017f,0.88706f,-0.349431f, +-0.32483f,0.824834f,-0.462746f, +-0.238736f,0.866733f,-0.437926f, +-0.174101f,0.907603f,-0.382029f, +-0.0165261f,0.968715f,-0.247625f, +0.078914f,0.949167f,-0.30472f, +0.287731f,0.926482f,-0.242571f, +0.12793f,0.981688f,-0.141147f, +-0.134026f,0.990975f,-0.00233563f, +-0.342476f,0.939327f,-0.0193419f, +-0.427311f,0.903697f,-0.027138f, +-0.353742f,0.934457f,-0.0407041f, +-0.055135f,0.997815f,0.0363915f, +0.0312575f,0.999385f,0.0158812f, +0.00264454f,0.999634f,-0.0269175f, +0.0835808f,0.996075f,-0.0291308f, +0.150499f,0.987413f,0.0486412f, +0.165157f,0.971811f,0.168246f, +0.215634f,0.960222f,0.177413f, +0.0835282f,0.988765f,0.123967f, +-0.00975779f,0.968408f,0.249181f, +-0.06977f,0.918125f,0.3901f, +-0.139283f,0.878718f,0.456569f, +-0.11373f,0.882765f,0.455842f, +-0.169944f,0.889011f,0.42518f, +-0.209287f,0.894084f,0.395996f, +-0.156853f,0.920873f,0.356917f, +-0.124966f,0.921391f,0.367997f, +-0.29021f,0.888579f,0.355255f, +-0.269725f,0.894676f,0.356094f, +-0.146199f,0.945073f,0.292342f, +-0.175209f,0.971632f,0.15885f, +-0.117718f,0.980316f,0.158504f, +-0.0825429f,0.966227f,0.244116f, +-0.0312586f,0.938703f,0.343308f, +0.145253f,0.922109f,0.358632f, +0.209296f,0.943478f,0.256992f, +0.299421f,0.901575f,0.312265f, +0.248395f,0.88619f,0.39111f, +0.0914055f,0.966416f,0.240179f, +0.127765f,0.989974f,-0.0602251f, +0.140331f,0.988333f,-0.0592086f, +-0.14269f,0.987394f,-0.0685058f, +-0.196659f,0.96924f,-0.147981f, +-0.173702f,0.951221f,-0.254961f, +-0.143754f,0.948468f,-0.282389f, +-0.0849965f,0.99069f,-0.106347f, +-0.164159f,0.984178f,0.0666661f, +-0.232036f,0.961292f,0.148586f, +-0.256871f,0.951713f,0.168109f, +-0.0692891f,0.973705f,0.217018f, +0.083167f,0.991239f,0.102607f, +0.0755656f,0.994003f,-0.07904f, +0.210733f,0.972404f,-0.100116f, +0.30249f,0.937213f,-0.173582f, +0.293071f,0.941554f,-0.166086f, +0.154342f,0.975072f,-0.159414f, +0.102764f,0.994605f,0.0141294f, +0.056079f,0.980415f,0.188792f, +0.109909f,0.955557f,0.273554f, +0.133139f,0.972499f,0.191102f, +0.0554464f,0.995429f,0.0777578f, +0.259868f,0.925249f,0.276374f, +0.196037f,0.949951f,0.243232f, +0.114869f,0.970528f,0.21185f, +0.223665f,0.947755f,0.227452f, +0.0930818f,0.995219f,-0.0295687f, +-0.269847f,0.892223f,-0.362106f, +-0.284642f,0.866853f,-0.409321f, +-0.255009f,0.880625f,-0.399336f, +-0.131932f,0.93993f,-0.314842f, +0.0677192f,0.974824f,-0.212442f, +0.187299f,0.973952f,-0.127815f, +0.0529524f,0.998138f,-0.0302806f, +-0.109006f,0.993972f,0.0117426f, +-0.296161f,0.95278f,-0.067077f, +-0.391399f,0.918205f,-0.0608803f, +-0.369652f,0.920023f,-0.130056f, +-0.175066f,0.983052f,-0.0544101f, +0.0114037f,0.997649f,0.0675687f, +-0.0112147f,0.996664f,0.0808418f, +0.0734363f,0.988721f,0.130533f, +0.0224625f,0.993745f,0.109391f, +0.0118323f,0.985875f,0.167063f, +0.164185f,0.947186f,0.275466f, +0.0854603f,0.916044f,0.391867f, +-0.130673f,0.906994f,0.400358f, +-0.128332f,0.898319f,0.420183f, +-0.0833752f,0.911617f,0.402496f, +-0.0573327f,0.932174f,0.357442f, +-0.17852f,0.926686f,0.330734f, +-0.230606f,0.897072f,0.376939f, +-0.191094f,0.893503f,0.406369f, +-0.142227f,0.886795f,0.439733f, +-0.17679f,0.896492f,0.40626f, +-0.238548f,0.945234f,0.222772f, +-0.0952672f,0.973092f,0.209801f, +-0.096256f,0.964628f,0.245412f, +-0.179685f,0.951666f,0.249087f, +-0.204503f,0.928081f,0.311197f, +-0.0772696f,0.924068f,0.374336f, +0.158946f,0.926358f,0.341463f, +0.256333f,0.910209f,0.325291f, +0.24298f,0.91134f,0.332296f, +0.258464f,0.899993f,0.351011f, +0.335956f,0.897826f,0.28468f, +0.32299f,0.94494f,0.0525965f, +0.125001f,0.99187f,-0.0238687f, +-0.121525f,0.992278f,-0.0248174f, +-0.149564f,0.988264f,-0.0310731f, +-0.0664528f,0.99755f,-0.021853f, +-0.216702f,0.971886f,-0.0920818f, +-0.313688f,0.949511f,-0.0053432f, +-0.230579f,0.964148f,0.131349f, +-0.200205f,0.977444f,0.06724f, +-0.214561f,0.975215f,-0.0540219f, +-0.0751922f,0.988525f,-0.131015f, +0.196994f,0.973692f,-0.114533f, +0.277294f,0.941009f,-0.193932f, +0.227557f,0.901482f,-0.368168f, +0.240964f,0.919471f,-0.31066f, +0.212207f,0.970864f,-0.111317f, +0.0629816f,0.997092f,0.0428958f, +-0.106678f,0.985091f,0.134967f, +-0.0538645f,0.972292f,0.227481f, +0.0800601f,0.969345f,0.232295f, +0.209708f,0.947853f,0.239995f, +0.200719f,0.957631f,0.206531f, +0.262538f,0.945755f,0.191366f, +0.219609f,0.958448f,0.182068f, +0.16942f,0.971857f,0.163679f, +0.226298f,0.968297f,0.105781f, +0.311569f,0.942438f,0.12139f, +0.0252626f,0.999298f,-0.0276703f, +-0.250271f,0.93337f,-0.257262f, +-0.253906f,0.911858f,-0.322563f, +-0.227242f,0.899531f,-0.373102f, +-0.0651757f,0.944171f,-0.322945f, +0.0757455f,0.97969f,-0.185662f, +-0.00346825f,0.999555f,-0.0296364f, +-0.101674f,0.994706f,-0.0148914f, +-0.257112f,0.961591f,-0.0961018f, +-0.383381f,0.91395f,-0.133094f, +-0.376104f,0.917884f,-0.12663f, +-0.286338f,0.956389f,-0.0577212f, +-0.0969792f,0.993405f,0.061176f, +-0.0181638f,0.982944f,0.183006f, +0.0407231f,0.989025f,0.142023f, +0.0858284f,0.987795f,0.129982f, +0.0586048f,0.994197f,0.0902062f, +0.00131743f,0.999561f,0.0296072f, +-0.0615813f,0.973472f,0.220363f, +-0.103673f,0.946783f,0.304719f, +-0.0728984f,0.963065f,0.259214f, +-0.0671535f,0.98356f,0.16763f, +-0.0415144f,0.986558f,0.158053f, +-0.226194f,0.961315f,0.157196f, +-0.322442f,0.916637f,0.236235f, +-0.20303f,0.923357f,0.32587f, +-0.141662f,0.940817f,0.307889f, +-0.0764267f,0.960304f,0.268283f, +-0.0942789f,0.977491f,0.188741f, +-0.142883f,0.973984f,0.175899f, +-0.198273f,0.947542f,0.250702f, +-0.198314f,0.931193f,0.305861f, +-0.212116f,0.938506f,0.272421f, +-0.0469422f,0.977819f,0.204126f, +0.196637f,0.969918f,0.1435f, +0.210661f,0.950426f,0.228718f, +0.210629f,0.90739f,0.363701f, +0.274296f,0.882172f,0.382799f, +0.402024f,0.855402f,0.326595f, +0.442462f,0.866019f,0.232889f, +0.128104f,0.97894f,0.158954f, +-0.10509f,0.973708f,0.202109f, +-0.168744f,0.972176f,0.162479f, +-0.102712f,0.980722f,0.166234f, +-0.117365f,0.985855f,0.119644f, +-0.348177f,0.934585f,-0.0729569f, +-0.249993f,0.967414f,-0.040164f, +-0.059218f,0.996444f,-0.0599467f, +-0.0488698f,0.975685f,-0.21366f, +-0.0228314f,0.943327f,-0.331077f, +0.144917f,0.936565f,-0.319132f, +0.332603f,0.901794f,-0.275938f, +0.285592f,0.906866f,-0.309889f, +0.0349917f,0.981145f,-0.190079f, +-0.0795345f,0.991829f,0.0997459f, +-0.0793233f,0.9451f,0.317009f, +-0.0879959f,0.940679f,0.327688f, +-0.00912821f,0.970457f,0.241099f, +0.124716f,0.982357f,0.13936f, +0.187981f,0.977561f,0.0950669f, +0.255482f,0.951122f,0.173483f, +0.297001f,0.952441f,0.0681659f, +0.265042f,0.961574f,0.0716068f, +0.186715f,0.981446f,0.0436002f, +0.255349f,0.964505f,0.0672885f, +0.267248f,0.96042f,0.078566f, +0.154901f,0.983709f,0.0912232f, +-0.0558054f,0.990723f,-0.123913f, +-0.190326f,0.930089f,-0.314182f, +-0.171804f,0.925365f,-0.337911f, +-0.124574f,0.93618f,-0.328706f, +-0.0782933f,0.960403f,-0.267387f, +-0.15298f,0.970001f,-0.188931f, +-0.0717491f,0.993745f,-0.0855706f, +-0.147047f,0.986451f,-0.0727437f, +-0.378361f,0.919377f,-0.107652f, +-0.386168f,0.917464f,-0.0955771f, +-0.364818f,0.925918f,-0.097894f, +-0.234461f,0.971639f,0.0307667f, +-0.0876095f,0.988677f,0.121826f, +0.151616f,0.984538f,0.0877402f, +0.0730881f,0.996968f,-0.0267174f, +0.0661066f,0.997404f,0.0285557f, +0.00089126f,0.998637f,0.052186f, +-0.169004f,0.978667f,0.116824f, +-0.169994f,0.972188f,0.161096f, +-0.0375438f,0.966292f,0.254695f, +0.0282607f,0.96926f,0.244409f, +0.0134123f,0.993493f,0.113096f, +-0.245106f,0.969303f,-0.0193377f, +-0.4073f,0.913294f,0.000911808f, +-0.297873f,0.952205f,0.0676567f, +-0.106293f,0.976869f,0.185552f, +-0.0629676f,0.97793f,0.199217f, +-0.110366f,0.958688f,0.262177f, +-0.181956f,0.936769f,0.298926f, +-0.212233f,0.945122f,0.248398f, +-0.195256f,0.962306f,0.189318f, +-0.105775f,0.982974f,0.150248f, +0.0268617f,0.999457f,0.0191026f, +0.158413f,0.985011f,0.068261f, +0.0517671f,0.977028f,0.206729f, +0.0576574f,0.95413f,0.293788f, +0.234396f,0.901434f,0.363971f, +0.437391f,0.816127f,0.377659f, +0.504071f,0.803908f,0.315666f, +0.133347f,0.946928f,0.292483f, +-0.151412f,0.933905f,0.323877f, +-0.120106f,0.92207f,0.367915f, +-0.00325057f,0.939171f,0.343435f, +0.0348166f,0.983178f,0.179299f, +-0.135523f,0.990774f,0.00106677f, +-0.269937f,0.929173f,-0.252528f, +-0.0598233f,0.968739f,-0.240761f, +0.0705133f,0.981516f,-0.177915f, +0.0411605f,0.966746f,-0.252403f, +0.126252f,0.944488f,-0.30332f, +0.315542f,0.911296f,-0.264523f, +0.160596f,0.976989f,-0.140362f, +-0.167382f,0.98071f,0.100946f, +-0.298691f,0.934743f,0.192454f, +-0.145935f,0.9608f,0.235724f, +-0.00307512f,0.970287f,0.241936f, +0.110563f,0.982642f,0.148964f, +0.216043f,0.97432f,0.0634533f, +0.143964f,0.986263f,0.0809867f, +0.0914437f,0.980957f,0.17135f, +0.140934f,0.985084f,-0.0987321f, +0.206841f,0.978337f,0.00859891f, +0.190086f,0.979435f,0.0676362f, +0.201515f,0.978077f,0.0525072f, +0.267937f,0.960786f,0.0714189f, +0.246755f,0.968907f,0.0182169f, +0.214715f,0.971106f,-0.104168f, +-0.0180649f,0.956568f,-0.290949f, +-0.219959f,0.899081f,-0.378512f, +-0.191729f,0.921961f,-0.336494f, +-0.106738f,0.947718f,-0.300729f, +-0.152636f,0.943663f,-0.293602f, +-0.224106f,0.947646f,-0.227472f, +-0.228203f,0.973419f,0.019469f, +-0.388401f,0.917519f,0.0854554f, +-0.336148f,0.939599f,0.0644837f, +-0.402605f,0.913568f,-0.0574625f, +-0.305232f,0.952235f,-0.00907982f, +-0.096739f,0.995183f,-0.0159156f, +0.180076f,0.982792f,0.0411394f, +0.136148f,0.986894f,0.0866302f, +0.0219341f,0.999371f,0.0278606f, +-0.0791566f,0.996134f,0.0381004f, +-0.239326f,0.960376f,0.142833f, +-0.218166f,0.951783f,0.215666f, +-0.166214f,0.94168f,0.292596f, +0.0428911f,0.92465f,0.378394f, +0.200943f,0.923885f,0.325667f, +-0.0783125f,0.985711f,0.149132f, +-0.415101f,0.909654f,-0.0148509f, +-0.366356f,0.929766f,0.0363078f, +-0.239727f,0.962799f,0.124698f, +-0.166496f,0.955565f,0.243259f, +-0.200219f,0.921854f,0.331809f, +-0.112297f,0.932828f,0.342375f, +-0.106223f,0.957221f,0.269154f, +-0.127872f,0.96503f,0.228835f, +-0.0138049f,0.984551f,0.174552f, +0.0256733f,0.993774f,0.108417f, +0.00728748f,0.973829f,0.227164f, +-0.00741294f,0.956693f,0.291004f, +0.0683597f,0.974464f,0.213887f, +0.177941f,0.966015f,0.187489f, +0.424978f,0.876377f,0.226619f, +0.505816f,0.827485f,0.243758f, +0.166361f,0.911198f,0.376885f, +-0.17476f,0.913668f,0.366973f, +-0.176728f,0.923512f,0.340431f, +0.0722139f,0.943797f,0.322541f, +0.177366f,0.957288f,0.228344f, +0.0913959f,0.986484f,0.136004f, +-0.0297265f,0.993047f,-0.113903f, +-0.0869422f,0.951911f,-0.293781f, +-0.0450316f,0.952406f,-0.301489f, +0.143119f,0.964298f,-0.222813f, +0.165675f,0.921893f,-0.350237f, +0.164354f,0.949667f,-0.266682f, +-0.039757f,0.998354f,0.0413462f, +-0.291683f,0.947651f,0.12992f, +-0.239728f,0.968947f,0.0605947f, +-0.107127f,0.994229f,0.00574708f, +-0.00468879f,0.997776f,-0.0664969f, +0.179786f,0.983119f,-0.033983f, +0.200209f,0.979349f,-0.0281487f, +0.0601426f,0.997956f,0.0216006f, +-0.0759803f,0.997037f,0.0120005f, +0.14599f,0.98347f,-0.107112f, +0.111543f,0.987674f,-0.109808f, +0.157618f,0.987042f,-0.0300797f, +0.250909f,0.967637f,-0.026879f, +0.281043f,0.956928f,-0.0728269f, +0.296885f,0.954758f,-0.0172396f, +0.276747f,0.960894f,-0.00969537f, +0.102049f,0.992961f,-0.0601211f, +-0.130111f,0.972079f,-0.195279f, +-0.17254f,0.923261f,-0.343248f, +-0.125309f,0.912244f,-0.390012f, +-0.211743f,0.924189f,-0.317868f, +-0.376287f,0.901788f,-0.212569f, +-0.427638f,0.901509f,-0.0663888f, +-0.389415f,0.920624f,0.0283935f, +-0.297925f,0.953877f,0.0368632f, +-0.273734f,0.961504f,0.0240644f, +-0.334113f,0.936286f,-0.108341f, +-0.109536f,0.993721f,-0.0228029f, +0.0288145f,0.999546f,0.00876748f, +0.119784f,0.984043f,0.131571f, +0.0511538f,0.994284f,0.0937163f, +-0.0752276f,0.983313f,0.165639f, +-0.293078f,0.946365f,0.136011f, +-0.332793f,0.935954f,0.115063f, +-0.225106f,0.941939f,0.249154f, +0.0114661f,0.958888f,0.283552f, +0.24485f,0.921506f,0.301455f, +0.100987f,0.953885f,0.282675f, +-0.340266f,0.932035f,0.124616f, +-0.415762f,0.898895f,0.138312f, +-0.325966f,0.925955f,0.190664f, +-0.250966f,0.918836f,0.304559f, +-0.221816f,0.898675f,0.378392f, +-0.0852583f,0.899614f,0.428282f, +-0.0998073f,0.904564f,0.41449f, +-0.102816f,0.885513f,0.453096f, +0.0414724f,0.91382f,0.403996f, +-0.0128006f,0.939036f,0.343581f, +-0.0641104f,0.924175f,0.376551f, +0.0655361f,0.926269f,0.37112f, +0.187467f,0.942186f,0.277743f, +0.21985f,0.965692f,0.138218f, +0.3812f,0.921864f,0.0696633f, +0.433954f,0.878909f,0.197998f, +0.0643484f,0.944154f,0.32316f, +-0.162002f,0.923385f,0.348016f, +-0.0466746f,0.93461f,0.352597f, +0.113297f,0.96975f,0.216212f, +0.268791f,0.938715f,0.215791f, +0.199257f,0.972974f,0.116695f, +0.13591f,0.990721f,-0.000598755f, +0.098836f,0.989317f,-0.107165f, +0.00840194f,0.94937f,-0.314049f, +0.0977197f,0.93606f,-0.337997f, +0.228369f,0.952655f,-0.20074f, +-0.102319f,0.98537f,-0.136295f, +-0.210478f,0.975126f,0.0694824f, +-0.226245f,0.97389f,-0.0187694f, +-0.184535f,0.981701f,-0.0470082f, +-0.0356904f,0.995184f,-0.0912977f, +0.0448449f,0.980059f,-0.193583f, +0.0871766f,0.981936f,-0.167935f, +0.149691f,0.986438f,-0.0673319f, +0.081336f,0.996451f,-0.021693f, +0.0320348f,0.999323f,-0.0181162f, +0.0913657f,0.979354f,-0.180329f, +0.100696f,0.986931f,-0.125808f, +0.108832f,0.988438f,-0.105573f, +0.287509f,0.953f,-0.0955498f, +0.243655f,0.954139f,-0.173927f, +0.160509f,0.983073f,-0.0883436f, +0.264497f,0.963724f,0.0357424f, +0.162998f,0.986545f,0.0127154f, +0.0143391f,0.999851f,0.00965394f, +-0.0125406f,0.999093f,-0.0406807f, +-0.106874f,0.984584f,-0.138462f, +-0.285824f,0.938351f,-0.194429f, +-0.419998f,0.877928f,-0.22988f, +-0.451562f,0.860313f,-0.236545f, +-0.434075f,0.875052f,-0.214154f, +-0.338822f,0.927615f,-0.157258f, +-0.245036f,0.962096f,-0.119701f, +-0.344114f,0.932339f,-0.111035f, +-0.226404f,0.972006f,0.0628119f, +0.0419787f,0.991974f,0.119273f, +0.128473f,0.991295f,0.0288037f, +-0.0257017f,0.999564f,0.0145347f, +-0.185301f,0.952066f,0.243378f, +-0.184541f,0.936895f,0.29694f, +-0.273419f,0.950852f,0.145334f, +-0.319783f,0.945196f,0.0659039f, +-0.035432f,0.98966f,0.138987f, +0.220222f,0.955124f,0.19809f, +0.125192f,0.96286f,0.239224f, +-0.256002f,0.939458f,0.227776f, +-0.448892f,0.878586f,0.163043f, +-0.385115f,0.893165f,0.232256f, +-0.361248f,0.871706f,0.331103f, +-0.291851f,0.846516f,0.445235f, +-0.17348f,0.85884f,0.481973f, +-0.107775f,0.841326f,0.529675f, +-0.0921307f,0.850827f,0.517306f, +0.0950699f,0.836893f,0.539048f, +0.0822562f,0.850572f,0.519385f, +0.00749303f,0.916802f,0.399272f, +0.0761143f,0.966912f,0.243491f, +0.269493f,0.937399f,0.220582f, +0.37073f,0.916186f,0.152194f, +0.358083f,0.929944f,0.083549f, +0.335187f,0.907961f,0.251509f, +0.0578141f,0.947361f,0.314904f, +-0.166707f,0.957873f,0.233855f, +-0.0184246f,0.983369f,0.180682f, +0.167068f,0.976917f,0.13312f, +0.286534f,0.942354f,0.172822f, +0.301062f,0.945554f,0.123648f, +0.228175f,0.972518f,0.0463188f, +0.216797f,0.97484f,-0.0518194f, +0.199106f,0.962895f,-0.18218f, +0.00394531f,0.962307f,-0.271937f, +-0.0105699f,0.99745f,-0.0705888f, +-0.131705f,0.985651f,0.105578f, +-0.19725f,0.980353f,0.00065076f, +-0.141436f,0.988723f,-0.0492296f, +-0.163841f,0.979948f,-0.113394f, +0.0189882f,0.981225f,-0.191928f, +0.0882705f,0.978772f,-0.18497f, +0.0393937f,0.981447f,-0.187645f, +0.0729287f,0.986122f,-0.149146f, +0.0148824f,0.998969f,-0.0428982f, +-0.0177962f,0.999449f,0.0279995f, +-0.0162323f,0.963189f,-0.268333f, +0.00641467f,0.976357f,-0.216067f, +0.107749f,0.98057f,-0.16393f, +0.293413f,0.939289f,-0.177892f, +0.308304f,0.934826f,-0.17621f, +0.101903f,0.952869f,-0.285755f, +0.182917f,0.946528f,-0.265755f, +0.146405f,0.977668f,-0.15077f, +-0.0629734f,0.995858f,-0.0655825f, +-0.0448201f,0.998977f,-0.00597126f, +-0.0400505f,0.999191f,-0.00375744f, +-0.153158f,0.98627f,-0.0617534f, +-0.285484f,0.92871f,-0.236637f, +-0.448842f,0.826713f,-0.339243f, +-0.479202f,0.840256f,-0.253646f, +-0.347296f,0.912974f,-0.214157f, +-0.288381f,0.931416f,-0.222037f, +-0.393139f,0.905395f,-0.160316f, +-0.362299f,0.919254f,-0.153982f, +0.042344f,0.998556f,-0.0330675f, +0.205011f,0.978411f,0.0261187f, +-0.127573f,0.99058f,0.0497635f, +-0.371574f,0.908811f,0.189723f, +-0.216831f,0.928294f,0.302084f, +-0.0703165f,0.93644f,0.343708f, +-0.232099f,0.969924f,0.0733245f, +-0.112472f,0.99344f,-0.0206566f, +0.137846f,0.985164f,0.102232f, +0.0558694f,0.966778f,0.249437f, +-0.236804f,0.911959f,0.335045f, +-0.429918f,0.856338f,0.286105f, +-0.441526f,0.844766f,0.302366f, +-0.455345f,0.82665f,0.330622f, +-0.361376f,0.843549f,0.397281f, +-0.152799f,0.875871f,0.457714f, +-0.118894f,0.891156f,0.437842f, +-0.0896442f,0.897342f,0.432135f, +0.0157836f,0.897193f,0.441356f, +0.112602f,0.854856f,0.5065f, +0.219938f,0.859901f,0.460648f, +0.288065f,0.92641f,0.242451f, +0.293811f,0.955367f,0.0308066f, +0.390529f,0.919592f,0.0428713f, +0.271277f,0.959279f,0.0786938f, +0.217133f,0.949907f,0.22479f, +0.0884504f,0.963513f,0.252624f, +-0.0236259f,0.986232f,0.163669f, +0.0800779f,0.996646f,0.0168362f, +0.165418f,0.984838f,-0.0522657f, +0.249596f,0.968284f,-0.0113122f, +0.338274f,0.940962f,-0.0126639f, +0.305431f,0.950632f,-0.0548703f, +0.294152f,0.946987f,-0.12919f, +0.225417f,0.970184f,-0.0890507f, +-0.00713906f,0.99978f,0.0197001f, +-0.176932f,0.984214f,-0.00420403f, +-0.111846f,0.993652f,0.0120569f, +-0.1391f,0.984895f,-0.103119f, +-0.088794f,0.987668f,-0.128949f, +-0.0465185f,0.96883f,-0.243321f, +0.0250763f,0.955082f,-0.295277f, +0.0363238f,0.977208f,-0.209152f, +0.0515148f,0.981849f,-0.182534f, +-0.0181f,0.986039f,-0.165529f, +-0.1292f,0.991547f,-0.0118974f, +-0.123925f,0.986172f,0.110035f, +0.0445182f,0.949745f,-0.309843f, +-0.00147152f,0.93224f,-0.361838f, +0.114309f,0.919114f,-0.377045f, +0.249456f,0.882365f,-0.399004f, +0.318339f,0.895336f,-0.311503f, +0.245085f,0.904168f,-0.349877f, +0.0939131f,0.907167f,-0.410156f, +-0.0302879f,0.963667f,-0.265383f, +-0.13844f,0.974516f,-0.176503f, +-0.0411687f,0.989896f,-0.135687f, +-0.00628724f,0.990542f,-0.137063f, +-0.112489f,0.976976f,-0.181283f, +-0.1315f,0.967086f,-0.217836f, +-0.376506f,0.872387f,-0.311743f, +-0.531305f,0.793042f,-0.297992f, +-0.39351f,0.883689f,-0.253462f, +-0.336847f,0.927504f,-0.162083f, +-0.393317f,0.917094f,-0.0651222f, +-0.321501f,0.93797f,-0.129808f, +-0.135804f,0.972419f,-0.189625f, +0.0526632f,0.998612f,0.00112608f, +-0.194024f,0.972777f,0.126724f, +-0.436845f,0.883669f,0.168215f, +-0.311688f,0.924669f,0.218719f, +-0.0696464f,0.953993f,0.291628f, +0.0409792f,0.956788f,0.287884f, +-0.0764775f,0.990645f,0.113025f, +-0.0364568f,0.989186f,0.142066f, +-0.121833f,0.946798f,0.297877f, +-0.315082f,0.850341f,0.421476f, +-0.377714f,0.797842f,0.469873f, +-0.420842f,0.786479f,0.452043f, +-0.397492f,0.78965f,0.467389f, +-0.380055f,0.83336f,0.401334f, +-0.183142f,0.896787f,0.402781f, +-0.0888282f,0.916137f,0.3909f, +-0.0940934f,0.935116f,0.34162f, +0.00386799f,0.937503f,0.347956f, +0.10018f,0.944394f,0.313183f, +0.280679f,0.93056f,0.235113f, +0.465087f,0.85876f,0.215002f, +0.41466f,0.904302f,0.101461f, +0.364139f,0.929581f,0.0572809f, +0.242065f,0.968602f,0.0566915f, +0.117842f,0.992149f,0.0418746f, +0.148716f,0.982681f,0.110551f, +0.0959266f,0.995185f,0.0201233f, +0.176327f,0.980433f,-0.0875236f, +0.210189f,0.965141f,-0.155959f, +0.226725f,0.946611f,-0.229181f, +0.330781f,0.920607f,-0.207526f, +0.365923f,0.916599f,-0.161081f, +0.298516f,0.923753f,-0.239936f, +0.0221976f,0.976238f,-0.215559f, +-0.104515f,0.994469f,-0.0104162f, +-0.0427336f,0.998984f,-0.0143091f, +-0.0839971f,0.989572f,-0.117013f, +-0.00725244f,0.993108f,-0.116977f, +-0.0399839f,0.966361f,-0.254064f, +0.00504893f,0.980798f,-0.194961f, +-0.018473f,0.987693f,-0.155309f, +-0.0253738f,0.987423f,-0.15605f, +0.000452807f,0.989468f,-0.144748f, +-0.0811148f,0.995994f,-0.0376225f, +-0.286969f,0.957515f,0.0285449f, +-0.27524f,0.951495f,0.137481f, +0.163018f,0.971572f,-0.171676f, +0.122581f,0.955248f,-0.269212f, +0.130974f,0.917919f,-0.374527f, +0.258812f,0.917892f,-0.300816f, +0.268244f,0.908354f,-0.320839f, +0.223034f,0.911459f,-0.345686f, +0.0389184f,0.957275f,-0.28655f, +-0.140597f,0.964524f,-0.223439f, +-0.145862f,0.970122f,-0.193875f, +-0.104111f,0.974098f,-0.200733f, +-0.0208986f,0.992723f,-0.118595f, +-0.0701237f,0.994147f,-0.08218f, +-0.122604f,0.99062f,-0.0603304f, +-0.259222f,0.963912f,-0.0606481f, +-0.533518f,0.797325f,-0.282189f, +-0.48726f,0.821939f,-0.294948f, +-0.445665f,0.877532f,-0.176975f, +-0.446224f,0.888631f,-0.105925f, +-0.296073f,0.952805f,-0.0671049f, +-0.124475f,0.991773f,-0.0298685f, +-0.112069f,0.99368f,-0.00632266f, +-0.24484f,0.957295f,0.15375f, +-0.472578f,0.869701f,0.142444f, +-0.348902f,0.914252f,0.205937f, +-0.110311f,0.945787f,0.30548f, +-0.00134709f,0.941519f,0.336957f, +0.0293716f,0.928574f,0.369983f, +-0.116225f,0.946895f,0.299803f, +-0.223618f,0.889099f,0.399372f, +-0.413824f,0.817577f,0.400396f, +-0.452277f,0.775981f,0.439658f, +-0.398113f,0.749968f,0.528257f, +-0.374899f,0.784234f,0.494397f, +-0.25264f,0.860337f,0.442712f, +-0.127446f,0.920564f,0.369215f, +-0.018556f,0.935495f,0.352851f, +-0.0323754f,0.965116f,0.259814f, +0.0357851f,0.98547f,0.166039f, +0.195904f,0.976812f,0.0863732f, +0.361612f,0.932271f,0.0103395f, +0.440593f,0.897705f,0.00204446f, +0.433278f,0.895277f,0.103679f, +0.385805f,0.912456f,0.136304f, +0.326244f,0.9426f,0.0712044f, +0.139247f,0.987833f,-0.0692571f, +0.107504f,0.992792f,-0.0529845f, +0.186477f,0.981836f,-0.0349818f, +0.2261f,0.969793f,-0.0915407f, +0.319918f,0.94368f,-0.0843796f, +0.284455f,0.935881f,-0.207877f, +0.26738f,0.950319f,-0.159379f, +0.326413f,0.941309f,-0.085975f, +0.340028f,0.93811f,-0.0657985f, +0.0548427f,0.991972f,-0.113944f, +-0.195067f,0.950504f,-0.241849f, +-0.0282147f,0.982936f,-0.181769f, +-0.0838232f,0.97875f,-0.187144f, +0.0287357f,0.988886f,-0.145871f, +0.0192345f,0.984318f,-0.175351f, +-0.131262f,0.971109f,-0.199292f, +-0.0357158f,0.988874f,-0.144408f, +0.0171216f,0.989641f,-0.142542f, +-0.0610371f,0.990627f,-0.122202f, +-0.174272f,0.984646f,-0.0100664f, +-0.321779f,0.946758f,0.0104107f, +-0.391721f,0.920071f,-0.0049163f, +0.251962f,0.967049f,0.0364793f, +0.286588f,0.95799f,-0.0110494f, +0.190653f,0.96361f,-0.187371f, +0.192921f,0.95146f,-0.239803f, +0.313234f,0.932132f,-0.181696f, +0.220402f,0.968379f,-0.116899f, +0.0241557f,0.995754f,-0.0888337f, +-0.173138f,0.969731f,-0.172177f, +-0.148056f,0.974915f,-0.166191f, +-0.121802f,0.976444f,-0.178104f, +-0.134617f,0.985638f,-0.10196f, +-0.12881f,0.990748f,0.0427476f, +-0.193234f,0.979772f,0.0520324f, +-0.169584f,0.981577f,0.0880205f, +-0.37404f,0.925821f,-0.0543154f, +-0.520547f,0.83989f,-0.153672f, +-0.499517f,0.851003f,-0.162103f, +-0.4353f,0.881523f,-0.182841f, +-0.371568f,0.902946f,-0.21593f, +-0.165948f,0.980792f,-0.10251f, +-0.208618f,0.975931f,-0.0635357f, +-0.355123f,0.932394f,0.0673039f, +-0.461506f,0.884901f,0.0629418f, +-0.443442f,0.893747f,0.0676439f, +-0.18907f,0.971969f,0.139742f, +-0.0546977f,0.978989f,0.19644f, +0.0244551f,0.950588f,0.309492f, +-0.115369f,0.932748f,0.341572f, +-0.31704f,0.862788f,0.393805f, +-0.382907f,0.826411f,0.412829f, +-0.514077f,0.784716f,0.346333f, +-0.482563f,0.790781f,0.37656f, +-0.301253f,0.838125f,0.454745f, +-0.149029f,0.885064f,0.440966f, +-0.0699981f,0.93986f,0.33431f, +0.00541731f,0.96209f,0.272677f, +0.0875381f,0.972016f,0.217994f, +0.185287f,0.977612f,0.0997159f, +0.257792f,0.964794f,-0.0521163f, +0.377486f,0.923846f,-0.0633437f, +0.414459f,0.907288f,-0.071082f, +0.347034f,0.936287f,-0.0541691f, +0.366281f,0.930406f,0.0134975f, +0.42839f,0.903092f,0.0301138f, +0.236883f,0.966501f,-0.0988031f, +0.0750179f,0.986987f,-0.142226f, +0.187793f,0.976018f,-0.110108f, +0.233114f,0.960011f,-0.155038f, +0.295131f,0.944107f,-0.146833f, +0.293935f,0.952937f,-0.0742579f, +0.206131f,0.978459f,-0.0112805f, +0.26541f,0.963541f,0.0338617f, +0.315062f,0.940538f,0.126983f, +0.200639f,0.96888f,0.144968f, +-0.0482349f,0.996749f,-0.0645292f, +-0.0829471f,0.973987f,-0.210875f, +-0.0395681f,0.974449f,-0.221097f, +-0.0327152f,0.953444f,-0.299791f, +0.0198675f,0.970814f,-0.23901f, +-0.0300308f,0.967142f,-0.252456f, +-0.0212823f,0.929856f,-0.367308f, +-0.0806959f,0.938686f,-0.335198f, +-0.165388f,0.976093f,-0.141032f, +-0.248602f,0.968455f,-0.0171025f, +-0.306518f,0.951371f,0.0306604f, +-0.345042f,0.93733f,0.04856f, +0.223548f,0.968386f,-0.110699f, +0.301936f,0.947319f,-0.106873f, +0.333496f,0.936283f,-0.110248f, +0.267715f,0.952143f,-0.147486f, +0.160925f,0.980864f,-0.109589f, +0.106924f,0.990465f,0.086874f, +0.0634847f,0.989163f,0.132389f, +-0.00868593f,0.99995f,-0.00503069f, +-0.137697f,0.961899f,-0.236198f, +-0.140914f,0.964191f,-0.224676f, +-0.263955f,0.951239f,-0.159597f, +-0.23775f,0.971227f,-0.0138849f, +-0.148246f,0.985689f,0.0802536f, +-0.176705f,0.981995f,0.0667941f, +-0.283636f,0.956796f,0.0639697f, +-0.481368f,0.872896f,-0.0796102f, +-0.48359f,0.86775f,-0.114673f, +-0.410361f,0.90546f,-0.10838f, +-0.368916f,0.919839f,-0.133408f, +-0.290849f,0.948818f,-0.123086f, +-0.265473f,0.964116f,-0.001833f, +-0.375668f,0.926391f,0.025952f, +-0.457607f,0.88747f,-0.0547004f, +-0.428989f,0.902388f,-0.0407983f, +-0.246051f,0.968578f,-0.0362744f, +-0.121016f,0.990282f,0.0685327f, +-0.158606f,0.977484f,0.139173f, +-0.181659f,0.932387f,0.312498f, +-0.374645f,0.868516f,0.324533f, +-0.427131f,0.84162f,0.330508f, +-0.473189f,0.797198f,0.374923f, +-0.486417f,0.800363f,0.350452f, +-0.401778f,0.85438f,0.329557f, +-0.142919f,0.913903f,0.379941f, +0.0660554f,0.918312f,0.390308f, +0.107243f,0.947465f,0.301346f, +0.120927f,0.966132f,0.227959f, +0.280478f,0.92581f,0.253394f, +0.365712f,0.921405f,0.131406f, +0.413772f,0.910147f,-0.0206163f, +0.410674f,0.90493f,-0.111572f, +0.355567f,0.932765f,-0.0593443f, +0.345425f,0.933621f,-0.0950402f, +0.397628f,0.912297f,-0.0980078f, +0.290063f,0.956994f,0.00506036f, +0.106586f,0.994174f,-0.016042f, +0.184529f,0.978373f,-0.093465f, +0.32595f,0.937225f,-0.12396f, +0.234333f,0.947332f,-0.218287f, +0.205568f,0.971289f,-0.119751f, +0.183661f,0.977533f,-0.103434f, +0.18646f,0.974485f,-0.124944f, +0.228632f,0.97345f,-0.0111031f, +0.2372f,0.970015f,0.0529807f, +0.150741f,0.988413f,-0.0177775f, +0.0529111f,0.986113f,-0.15742f, +0.0129012f,0.976239f,-0.216311f, +0.0638914f,0.966774f,-0.247521f, +-0.013106f,0.949224f,-0.314329f, +0.00301657f,0.947335f,-0.320229f, +0.0158116f,0.945699f,-0.32466f, +-0.206362f,0.955554f,-0.21055f, +-0.363868f,0.929813f,-0.0551994f, +-0.322459f,0.943841f,0.0720059f, +-0.369143f,0.923823f,0.101411f, +-0.383217f,0.903675f,0.191093f, +0.316947f,0.930379f,-0.184227f, +0.292606f,0.932053f,-0.213681f, +0.281637f,0.95325f,-0.109518f, +0.181192f,0.981727f,-0.0581435f, +0.0846872f,0.996407f,0.000962506f, +-0.00109762f,0.999999f,0.000234158f, +0.0777708f,0.996176f,0.0398008f, +0.205791f,0.978243f,0.0262708f, +0.0568816f,0.985436f,-0.160253f, +-0.183235f,0.956309f,-0.227811f, +-0.306851f,0.928821f,-0.207686f, +-0.348537f,0.918038f,-0.189017f, +-0.243342f,0.965099f,-0.0967916f, +-0.232072f,0.972378f,-0.0249578f, +-0.190489f,0.981246f,0.0294989f, +-0.361119f,0.921084f,-0.145596f, +-0.509056f,0.842731f,-0.175118f, +-0.463553f,0.883903f,-0.0619248f, +-0.339892f,0.940435f,0.00741701f, +-0.334839f,0.939566f,-0.0714062f, +-0.350156f,0.936419f,-0.0225887f, +-0.347741f,0.937357f,0.020947f, +-0.370099f,0.928938f,-0.0100614f, +-0.438593f,0.892875f,-0.102033f, +-0.372504f,0.925425f,-0.0694955f, +-0.205666f,0.969919f,0.130228f, +-0.228734f,0.96522f,0.126612f, +-0.319826f,0.92691f,0.196338f, +-0.371568f,0.883063f,0.286595f, +-0.42486f,0.867995f,0.257059f, +-0.575514f,0.802019f,0.159839f, +-0.477155f,0.843037f,0.248216f, +-0.322215f,0.91617f,0.238347f, +-0.15776f,0.967147f,0.199344f, +0.0563134f,0.972277f,0.226949f, +0.189774f,0.959109f,0.209989f, +0.114773f,0.983426f,0.140357f, +0.195319f,0.960799f,0.196765f, +0.466014f,0.846607f,0.257076f, +0.551779f,0.823036f,0.13473f, +0.451922f,0.891695f,-0.0254353f, +0.295217f,0.951228f,-0.0895088f, +0.39575f,0.916754f,-0.0542532f, +0.335629f,0.937827f,-0.0885088f, +0.163272f,0.984979f,0.0561951f, +0.175225f,0.975709f,0.131485f, +0.276736f,0.960943f,0.00255915f, +0.374077f,0.92611f,-0.0488528f, +0.257806f,0.961501f,-0.0951409f, +0.210674f,0.973483f,-0.0891523f, +0.210996f,0.9611f,-0.178234f, +0.230566f,0.953272f,-0.195223f, +0.113631f,0.949966f,-0.290949f, +0.210906f,0.960561f,-0.181223f, +0.197018f,0.968285f,-0.153646f, +0.117662f,0.979392f,-0.164157f, +0.00452083f,0.974487f,-0.224398f, +0.0685234f,0.976453f,-0.20456f, +0.0486196f,0.979817f,-0.193895f, +-0.041249f,0.985341f,-0.165533f, +-0.0536621f,0.998462f,0.0138937f, +-0.34438f,0.936413f,0.0673216f, +-0.441342f,0.892502f,0.0930463f, +-0.35428f,0.929013f,0.106864f, +-0.394607f,0.91136f,0.117083f, +-0.495153f,0.861045f,0.115868f, +0.317163f,0.930357f,-0.183965f, +0.258032f,0.948579f,-0.183348f, +0.18786f,0.965135f,-0.182274f, +0.168177f,0.970722f,-0.171508f, +0.130487f,0.977884f,-0.163448f, +0.0391868f,0.976408f,-0.212349f, +0.0535243f,0.973465f,-0.222489f, +0.187797f,0.962281f,-0.196843f, +0.12136f,0.981658f,-0.147035f, +-0.157459f,0.973185f,-0.167681f, +-0.281843f,0.941023f,-0.18719f, +-0.339259f,0.910185f,-0.237625f, +-0.312535f,0.920718f,-0.233666f, +-0.266508f,0.952365f,-0.148237f, +-0.190534f,0.974186f,-0.121073f, +-0.276015f,0.959165f,-0.0617859f, +-0.523368f,0.852103f,0.00254573f, +-0.538f,0.84284f,-0.0133122f, +-0.352764f,0.935613f,-0.0136594f, +-0.269435f,0.962844f,-0.0183539f, +-0.350798f,0.93502f,-0.0517468f, +-0.373067f,0.922044f,-0.103225f, +-0.354323f,0.929911f,-0.0985928f, +-0.409705f,0.907488f,-0.0927797f, +-0.42852f,0.900791f,-0.070324f, +-0.329659f,0.944032f,-0.0113329f, +-0.243515f,0.962301f,0.121152f, +-0.341781f,0.918017f,0.201073f, +-0.462572f,0.875527f,0.139571f, +-0.350168f,0.914262f,0.203733f, +-0.49611f,0.864935f,0.0759072f, +-0.527565f,0.849514f,0.000485091f, +-0.337106f,0.940759f,0.0364912f, +-0.159402f,0.986691f,0.0321325f, +0.0661572f,0.997809f,-0.000201698f, +0.185343f,0.982618f,-0.0104608f, +0.145499f,0.981994f,0.120491f, +0.134704f,0.982549f,0.128264f, +0.406275f,0.89759f,0.17109f, +0.586902f,0.779785f,0.217901f, +0.565709f,0.807524f,0.166967f, +0.384632f,0.92307f,-3.36604e-005f, +0.35623f,0.932256f,-0.0632309f, +0.323525f,0.94617f,0.00968274f, +0.0775419f,0.995759f,-0.0495083f, +0.170196f,0.984289f,-0.0470022f, +0.351353f,0.935822f,-0.0280704f, +0.38341f,0.923157f,-0.0278874f, +0.285688f,0.957776f,-0.0323514f, +0.254076f,0.961785f,-0.102057f, +0.271137f,0.936424f,-0.222698f, +0.261266f,0.933845f,-0.24428f, +0.199017f,0.946563f,-0.253793f, +0.0763778f,0.960008f,-0.269355f, +0.131471f,0.985485f,-0.107402f, +0.160318f,0.984539f,-0.0705758f, +0.0961684f,0.977977f,-0.185235f, +0.0245162f,0.963631f,-0.26611f, +-0.0125968f,0.989853f,-0.141538f, +-0.234149f,0.972198f,0.00219358f, +-0.224015f,0.949544f,0.219506f, +-0.294091f,0.928539f,0.226551f, +-0.388903f,0.912184f,0.129128f, +-0.352208f,0.9324f,0.0811158f, +-0.3962f,0.915032f,0.0757807f, +-0.491066f,0.869445f,0.0540404f, +0.157697f,0.961233f,-0.226193f, +0.272083f,0.946677f,-0.172551f, +0.25297f,0.931319f,-0.262015f, +0.179666f,0.941632f,-0.284691f, +0.0998509f,0.952676f,-0.287122f, +0.0337305f,0.95661f,-0.289412f, +0.0669213f,0.956372f,-0.284383f, +0.111493f,0.948222f,-0.297395f, +0.109434f,0.973643f,-0.200107f, +-0.146896f,0.95648f,-0.252126f, +-0.266533f,0.937028f,-0.225695f, +-0.287184f,0.932451f,-0.219226f, +-0.333493f,0.906758f,-0.258015f, +-0.32756f,0.915563f,-0.233343f, +-0.294553f,0.94475f,-0.143827f, +-0.391872f,0.91893f,0.0447686f, +-0.558682f,0.823628f,0.0975275f, +-0.441987f,0.895769f,0.0473795f, +-0.31507f,0.944961f,-0.0882052f, +-0.286026f,0.950757f,-0.119373f, +-0.300544f,0.946699f,-0.115905f, +-0.336723f,0.926445f,-0.168278f, +-0.353572f,0.929204f,-0.107543f, +-0.453641f,0.88906f,-0.0615028f, +-0.438343f,0.898681f,0.0151213f, +-0.388424f,0.921475f,0.00321393f, +-0.409039f,0.909757f,0.0709235f, +-0.363684f,0.905932f,0.216843f, +-0.363969f,0.919331f,0.149522f, +-0.393196f,0.918247f,0.0470974f, +-0.399628f,0.911703f,0.0953624f, +-0.51262f,0.855967f,-0.0673815f, +-0.335242f,0.936382f,-0.103929f, +-0.0973696f,0.981557f,-0.164516f, +0.067792f,0.980923f,-0.182192f, +0.0872383f,0.996018f,-0.0183907f, +-0.00523703f,0.995218f,0.0975357f, +0.128581f,0.983098f,0.130327f, +0.373617f,0.921384f,0.107058f, +0.560261f,0.820373f,0.114439f, +0.627317f,0.771722f,0.104494f, +0.477878f,0.875076f,0.0766505f, +0.339671f,0.937101f,0.080413f, +0.338185f,0.931593f,0.133286f, +0.241006f,0.969638f,0.0414564f, +0.184566f,0.96984f,-0.159206f, +0.299844f,0.937156f,-0.178416f, +0.33645f,0.93097f,-0.14176f, +0.33978f,0.935566f,-0.0962638f, +0.338458f,0.922961f,-0.183273f, +0.376116f,0.905613f,-0.195964f, +0.229101f,0.942068f,-0.244989f, +0.179681f,0.964126f,-0.195387f, +0.0309568f,0.968834f,-0.245768f, +0.00573259f,0.975463f,-0.220088f, +0.156849f,0.977783f,-0.139061f, +0.21782f,0.972525f,-0.0821593f, +0.0218621f,0.99451f,-0.102332f, +-0.198564f,0.980065f,-0.00663249f, +-0.36267f,0.923836f,0.122463f, +-0.30382f,0.935102f,0.182419f, +-0.225949f,0.949998f,0.215522f, +-0.338005f,0.935768f,0.100459f, +-0.329518f,0.942604f,0.0540005f, +-0.353044f,0.9356f,0.00366832f, +-0.46383f,0.880375f,-0.0990046f, +0.265153f,0.963251f,-0.0429098f, +0.322279f,0.944597f,-0.0622248f, +0.315505f,0.945542f,-0.0800488f, +0.163962f,0.974749f,-0.151597f, +0.137337f,0.972433f,-0.188448f, +0.0704319f,0.957822f,-0.278599f, +0.0704671f,0.945462f,-0.318019f, +0.0908986f,0.948607f,-0.303121f, +0.035224f,0.968727f,-0.245614f, +-0.0832465f,0.983302f,-0.161824f, +-0.246429f,0.938519f,-0.241773f, +-0.316726f,0.889326f,-0.329823f, +-0.284897f,0.918994f,-0.272549f, +-0.362325f,0.886545f,-0.287677f, +-0.440048f,0.874713f,-0.203063f, +-0.497142f,0.865956f,-0.0544999f, +-0.523445f,0.849121f,-0.0707108f, +-0.401725f,0.907593f,-0.122034f, +-0.239401f,0.964528f,-0.111235f, +-0.233733f,0.958501f,-0.163231f, +-0.252964f,0.932836f,-0.256566f, +-0.367645f,0.889692f,-0.270713f, +-0.454692f,0.878935f,-0.143978f, +-0.492544f,0.866924f,-0.0764391f, +-0.481959f,0.875013f,-0.0454739f, +-0.427088f,0.903155f,0.0436767f, +-0.414523f,0.900313f,0.132691f, +-0.445145f,0.893064f,0.0654368f, +-0.272596f,0.94477f,0.181937f, +-0.346295f,0.936658f,0.0524542f, +-0.387211f,0.921676f,-0.0241059f, +-0.412405f,0.90305f,-0.120098f, +-0.307707f,0.940243f,-0.145806f, +-0.0608418f,0.995582f,-0.0715164f, +-0.0645131f,0.997917f,-0.000435129f, +-0.102008f,0.988043f,0.115607f, +0.0143588f,0.992143f,0.12428f, +0.177967f,0.984035f,-0.00139713f, +0.41001f,0.908001f,-0.0861781f, +0.552955f,0.819416f,-0.150989f, +0.604866f,0.793986f,-0.061019f, +0.412532f,0.907382f,0.080473f, +0.292095f,0.937176f,0.190737f, +0.30791f,0.927063f,0.213882f, +0.344775f,0.913992f,0.21389f, +0.356481f,0.927786f,0.110156f, +0.364153f,0.931072f,-0.0223179f, +0.345291f,0.930006f,-0.125944f, +0.351321f,0.913987f,-0.20298f, +0.3587f,0.898336f,-0.253627f, +0.30452f,0.930923f,-0.201617f, +0.2074f,0.975489f,-0.0735288f, +0.18932f,0.981882f,-0.00809888f, +0.163933f,0.983471f,-0.0768774f, +0.0155138f,0.975385f,-0.219964f, +0.0271837f,0.983796f,-0.177221f, +0.116676f,0.992898f,-0.0232359f, +-0.0753728f,0.996934f,0.0209924f, +-0.279745f,0.951672f,0.12674f, +-0.364174f,0.921867f,0.132433f, +-0.344523f,0.936581f,0.0641857f, +-0.216332f,0.972578f,0.0853902f, +-0.223892f,0.974436f,0.0186366f, +-0.28965f,0.953049f,-0.0883156f, +-0.269918f,0.95756f,-0.101108f, +-0.286201f,0.950564f,-0.120491f, +0.172976f,0.984286f,-0.0355076f, +0.24194f,0.969981f,0.0245291f, +0.324379f,0.937283f,0.127591f, +0.286811f,0.953171f,0.0959428f, +0.228455f,0.972614f,-0.0427886f, +0.182359f,0.97568f,-0.121631f, +0.113036f,0.971479f,-0.208452f, +0.0547152f,0.964701f,-0.257601f, +-0.089806f,0.977237f,-0.192205f, +-0.171631f,0.984685f,-0.0306458f, +-0.116586f,0.992809f,0.0271681f, +-0.181607f,0.981068f,-0.0672723f, +-0.351307f,0.914748f,-0.199546f, +-0.388005f,0.90325f,-0.183278f, +-0.498044f,0.847159f,-0.185132f, +-0.510366f,0.84434f,-0.163145f, +-0.479522f,0.851128f,-0.213636f, +-0.42037f,0.86671f,-0.268518f, +-0.285469f,0.932257f,-0.22227f, +-0.161107f,0.969121f,-0.186679f, +-0.183754f,0.955302f,-0.231585f, +-0.370817f,0.89935f,-0.231654f, +-0.514998f,0.83014f,-0.213645f, +-0.498206f,0.85286f,-0.156273f, +-0.539513f,0.835182f,-0.106757f, +-0.535773f,0.843208f,0.0441435f, +-0.434698f,0.878206f,0.19948f, +-0.415775f,0.89222f,0.176277f, +-0.35414f,0.920981f,0.162413f, +-0.208366f,0.953013f,0.219884f, +-0.257177f,0.962661f,0.0845243f, +-0.386488f,0.920792f,-0.0526133f, +-0.381213f,0.924327f,0.0172227f, +-0.280093f,0.955497f,0.0925905f, +-0.1219f,0.953555f,0.275451f, +-0.0595691f,0.973079f,0.222641f, +0.124431f,0.978938f,0.161854f, +0.328706f,0.943592f,0.0398269f, +0.495224f,0.863825f,-0.0925162f, +0.549494f,0.832161f,-0.0745945f, +0.445758f,0.890738f,0.0887957f, +0.286029f,0.911685f,0.294987f, +0.236342f,0.90766f,0.346837f, +0.306156f,0.900003f,0.310262f, +0.362522f,0.893707f,0.264322f, +0.407318f,0.891604f,0.197826f, +0.447705f,0.883296f,0.139101f, +0.451832f,0.890524f,0.0530504f, +0.450032f,0.892977f,-0.00796524f, +0.380264f,0.922022f,-0.0726326f, +0.220431f,0.973877f,-0.0545382f, +0.073814f,0.997262f,0.00436123f, +0.143916f,0.987825f,0.059083f, +0.242994f,0.967605f,0.068523f, +0.0793826f,0.995647f,0.0488496f, +-0.0810126f,0.994023f,0.0731786f, +0.0550609f,0.987118f,0.150223f, +-0.0403249f,0.995863f,0.0814341f, +-0.341404f,0.939899f,-0.00574405f, +-0.333197f,0.942331f,0.0315063f, +-0.270492f,0.962353f,-0.0266656f, +-0.217149f,0.973729f,-0.0685481f, +-0.150518f,0.988024f,-0.0339529f, +-0.227799f,0.970772f,-0.0755549f, +-0.30247f,0.950166f,-0.0754703f, +-0.319718f,0.946617f,-0.0411916f, +0.16825f,0.98433f,0.0527868f, +0.196178f,0.978898f,0.0572086f, +0.274186f,0.954613f,0.116347f, +0.32563f,0.930709f,0.166568f, +0.315871f,0.943308f,0.101959f, +0.191037f,0.981318f,-0.0227958f, +0.218135f,0.975914f,0.0029357f, +0.0466483f,0.982299f,-0.18142f, +-0.170175f,0.975305f,-0.140788f, +-0.258133f,0.965917f,0.0192531f, +-0.189679f,0.978131f,0.0853348f, +-0.0936377f,0.967266f,0.235858f, +-0.301926f,0.950003f,0.0795937f, +-0.345647f,0.93835f,0.00528925f, +-0.494118f,0.858314f,-0.138363f, +-0.492927f,0.860507f,-0.128646f, +-0.443878f,0.87267f,-0.203517f, +-0.398442f,0.869961f,-0.290537f, +-0.31747f,0.894846f,-0.313789f, +-0.189431f,0.934926f,-0.300049f, +-0.194231f,0.947861f,-0.252654f, +-0.355627f,0.917296f,-0.179159f, +-0.521351f,0.821848f,-0.229692f, +-0.537173f,0.817848f,-0.206322f, +-0.595314f,0.798098f,-0.0929575f, +-0.612312f,0.785394f,0.0907203f, +-0.484809f,0.839064f,0.246843f, +-0.327417f,0.875762f,0.354737f, +-0.358949f,0.909479f,0.20977f, +-0.221142f,0.943893f,0.245282f, +-0.137619f,0.956208f,0.258316f, +-0.37682f,0.920718f,0.101416f, +-0.393482f,0.900899f,0.183174f, +-0.309483f,0.930699f,0.194988f, +-0.137506f,0.96116f,0.2393f, +-0.0256175f,0.984881f,0.171327f, +0.155024f,0.972933f,0.171372f, +0.40312f,0.907825f,0.115531f, +0.491485f,0.869632f,-0.0467184f, +0.488586f,0.869843f,0.0682392f, +0.313615f,0.910806f,0.268473f, +0.190736f,0.863506f,0.466881f, +0.238952f,0.837112f,0.492083f, +0.344695f,0.840122f,0.418784f, +0.396648f,0.860615f,0.319393f, +0.456384f,0.85928f,0.230981f, +0.487857f,0.863295f,0.129295f, +0.451906f,0.891012f,0.043332f, +0.456211f,0.882737f,0.112455f, +0.397431f,0.910062f,0.117622f, +0.204941f,0.971778f,0.116821f, +0.0877111f,0.985798f,0.143208f, +0.14813f,0.986469f,0.0702648f, +0.212033f,0.976625f,0.035296f, +0.0413914f,0.99116f,0.126047f, +-0.10186f,0.970634f,0.217932f, +0.0558102f,0.971334f,0.231076f, +0.0834757f,0.981533f,0.172117f, +-0.293392f,0.955612f,-0.0269471f, +-0.339064f,0.938377f,-0.0669636f, +-0.232942f,0.969004f,-0.0822698f, +-0.249298f,0.960887f,-0.120613f, +-0.178309f,0.98375f,-0.0210319f, +-0.23671f,0.971566f,0.00516088f, +-0.322203f,0.944986f,0.0564443f, +-0.359276f,0.929551f,0.0827968f, +}; + +btScalar Landscape06Tex[] = { +0.0f,0.0078125f, +0.0f,0.0f, +0.0078125f,0.0078125f, +0.0078125f,0.0f, +0.015625f,0.0078125f, +0.015625f,0.0f, +0.0234375f,0.0078125f, +0.0234375f,0.0f, +0.03125f,0.0078125f, +0.03125f,0.0f, +0.0390625f,0.0078125f, +0.0390625f,0.0f, +0.046875f,0.0078125f, +0.046875f,0.0f, +0.0546875f,0.0078125f, +0.0546875f,0.0f, +0.0625f,0.0078125f, +0.0625f,0.0f, +0.0703125f,0.0078125f, +0.0703125f,0.0f, +0.078125f,0.0078125f, +0.078125f,0.0f, +0.0859375f,0.0078125f, +0.0859375f,0.0f, +0.09375f,0.0078125f, +0.09375f,0.0f, +0.101563f,0.0078125f, +0.101563f,0.0f, +0.109375f,0.0078125f, +0.109375f,0.0f, +0.117188f,0.0078125f, +0.117188f,0.0f, +0.125f,0.0078125f, +0.125f,0.0f, +0.132813f,0.0078125f, +0.132813f,0.0f, +0.140625f,0.0078125f, +0.140625f,0.0f, +0.148438f,0.0078125f, +0.148438f,0.0f, +0.15625f,0.0078125f, +0.15625f,0.0f, +0.164063f,0.0078125f, +0.164063f,0.0f, +0.171875f,0.0078125f, +0.171875f,0.0f, +0.179688f,0.0078125f, +0.179688f,0.0f, +0.1875f,0.0078125f, +0.1875f,0.0f, +0.195313f,0.0078125f, +0.195313f,0.0f, +0.203125f,0.0078125f, +0.203125f,0.0f, +0.210938f,0.0078125f, +0.210938f,0.0f, +0.21875f,0.0078125f, +0.21875f,0.0f, +0.226563f,0.0078125f, +0.226563f,0.0f, +0.234375f,0.0078125f, +0.234375f,0.0f, +0.242188f,0.0078125f, +0.242188f,0.0f, +0.25f,0.0078125f, +0.25f,0.0f, +0.257813f,0.0078125f, +0.257813f,0.0f, +0.265625f,0.0078125f, +0.265625f,0.0f, +0.273438f,0.0078125f, +0.273438f,0.0f, +0.28125f,0.0078125f, +0.28125f,0.0f, +0.289063f,0.0078125f, +0.289063f,0.0f, +0.296875f,0.0078125f, +0.296875f,0.0f, +0.304688f,0.0078125f, +0.304688f,0.0f, +0.3125f,0.0078125f, +0.3125f,0.0f, +0.320313f,0.0078125f, +0.320313f,0.0f, +0.328125f,0.0078125f, +0.328125f,0.0f, +0.335938f,0.0078125f, +0.335938f,0.0f, +0.34375f,0.0078125f, +0.34375f,0.0f, +0.351563f,0.0078125f, +0.351563f,0.0f, +0.359375f,0.0078125f, +0.359375f,0.0f, +0.367188f,0.0078125f, +0.367188f,0.0f, +0.375f,0.0078125f, +0.375f,0.0f, +0.382813f,0.0078125f, +0.382813f,0.0f, +0.390625f,0.0078125f, +0.390625f,0.0f, +0.398438f,0.0078125f, +0.398438f,0.0f, +0.40625f,0.0078125f, +0.40625f,0.0f, +0.414063f,0.0078125f, +0.414063f,0.0f, +0.421875f,0.0078125f, +0.421875f,0.0f, +0.429688f,0.0078125f, +0.429688f,0.0f, +0.4375f,0.0078125f, +0.4375f,0.0f, +0.445313f,0.0078125f, +0.445313f,0.0f, +0.453125f,0.0078125f, +0.453125f,0.0f, +0.460938f,0.0078125f, +0.460938f,0.0f, +0.46875f,0.0078125f, +0.46875f,0.0f, +0.476563f,0.0078125f, +0.476563f,0.0f, +0.484375f,0.0078125f, +0.484375f,0.0f, +0.492188f,0.0078125f, +0.492188f,0.0f, +0.5f,0.0078125f, +0.5f,0.0f, +0.507813f,0.0078125f, +0.507813f,0.0f, +0.0f,0.015625f, +0.0078125f,0.015625f, +0.015625f,0.015625f, +0.0234375f,0.015625f, +0.03125f,0.015625f, +0.0390625f,0.015625f, +0.046875f,0.015625f, +0.0546875f,0.015625f, +0.0625f,0.015625f, +0.0703125f,0.015625f, +0.078125f,0.015625f, +0.0859375f,0.015625f, +0.09375f,0.015625f, +0.101563f,0.015625f, +0.109375f,0.015625f, +0.117188f,0.015625f, +0.125f,0.015625f, +0.132813f,0.015625f, +0.140625f,0.015625f, +0.148438f,0.015625f, +0.15625f,0.015625f, +0.164063f,0.015625f, +0.171875f,0.015625f, +0.179688f,0.015625f, +0.1875f,0.015625f, +0.195313f,0.015625f, +0.203125f,0.015625f, +0.210938f,0.015625f, +0.21875f,0.015625f, +0.226563f,0.015625f, +0.234375f,0.015625f, +0.242188f,0.015625f, +0.25f,0.015625f, +0.257813f,0.015625f, +0.265625f,0.015625f, +0.273438f,0.015625f, +0.28125f,0.015625f, +0.289063f,0.015625f, +0.296875f,0.015625f, +0.304688f,0.015625f, +0.3125f,0.015625f, +0.320313f,0.015625f, +0.328125f,0.015625f, +0.335938f,0.015625f, +0.34375f,0.015625f, +0.351563f,0.015625f, +0.359375f,0.015625f, +0.367188f,0.015625f, +0.375f,0.015625f, +0.382813f,0.015625f, +0.390625f,0.015625f, +0.398438f,0.015625f, +0.40625f,0.015625f, +0.414063f,0.015625f, +0.421875f,0.015625f, +0.429688f,0.015625f, +0.4375f,0.015625f, +0.445313f,0.015625f, +0.453125f,0.015625f, +0.460938f,0.015625f, +0.46875f,0.015625f, +0.476563f,0.015625f, +0.484375f,0.015625f, +0.492188f,0.015625f, +0.5f,0.015625f, +0.507813f,0.015625f, +0.0f,0.0234375f, +0.0078125f,0.0234375f, +0.015625f,0.0234375f, +0.0234375f,0.0234375f, +0.03125f,0.0234375f, +0.0390625f,0.0234375f, +0.046875f,0.0234375f, +0.0546875f,0.0234375f, +0.0625f,0.0234375f, +0.0703125f,0.0234375f, +0.078125f,0.0234375f, +0.0859375f,0.0234375f, +0.09375f,0.0234375f, +0.101563f,0.0234375f, +0.109375f,0.0234375f, +0.117188f,0.0234375f, +0.125f,0.0234375f, +0.132813f,0.0234375f, +0.140625f,0.0234375f, +0.148438f,0.0234375f, +0.15625f,0.0234375f, +0.164063f,0.0234375f, +0.171875f,0.0234375f, +0.179688f,0.0234375f, +0.1875f,0.0234375f, +0.195313f,0.0234375f, +0.203125f,0.0234375f, +0.210938f,0.0234375f, +0.21875f,0.0234375f, +0.226563f,0.0234375f, +0.234375f,0.0234375f, +0.242188f,0.0234375f, +0.25f,0.0234375f, +0.257813f,0.0234375f, +0.265625f,0.0234375f, +0.273438f,0.0234375f, +0.28125f,0.0234375f, +0.289063f,0.0234375f, +0.296875f,0.0234375f, +0.304688f,0.0234375f, +0.3125f,0.0234375f, +0.320313f,0.0234375f, +0.328125f,0.0234375f, +0.335938f,0.0234375f, +0.34375f,0.0234375f, +0.351563f,0.0234375f, +0.359375f,0.0234375f, +0.367188f,0.0234375f, +0.375f,0.0234375f, +0.382813f,0.0234375f, +0.390625f,0.0234375f, +0.398438f,0.0234375f, +0.40625f,0.0234375f, +0.414063f,0.0234375f, +0.421875f,0.0234375f, +0.429688f,0.0234375f, +0.4375f,0.0234375f, +0.445313f,0.0234375f, +0.453125f,0.0234375f, +0.460938f,0.0234375f, +0.46875f,0.0234375f, +0.476563f,0.0234375f, +0.484375f,0.0234375f, +0.492188f,0.0234375f, +0.5f,0.0234375f, +0.507813f,0.0234375f, +0.0f,0.03125f, +0.0078125f,0.03125f, +0.015625f,0.03125f, +0.0234375f,0.03125f, +0.03125f,0.03125f, +0.0390625f,0.03125f, +0.046875f,0.03125f, +0.0546875f,0.03125f, +0.0625f,0.03125f, +0.0703125f,0.03125f, +0.078125f,0.03125f, +0.0859375f,0.03125f, +0.09375f,0.03125f, +0.101563f,0.03125f, +0.109375f,0.03125f, +0.117188f,0.03125f, +0.125f,0.03125f, +0.132813f,0.03125f, +0.140625f,0.03125f, +0.148438f,0.03125f, +0.15625f,0.03125f, +0.164063f,0.03125f, +0.171875f,0.03125f, +0.179688f,0.03125f, +0.1875f,0.03125f, +0.195313f,0.03125f, +0.203125f,0.03125f, +0.210938f,0.03125f, +0.21875f,0.03125f, +0.226563f,0.03125f, +0.234375f,0.03125f, +0.242188f,0.03125f, +0.25f,0.03125f, +0.257813f,0.03125f, +0.265625f,0.03125f, +0.273438f,0.03125f, +0.28125f,0.03125f, +0.289063f,0.03125f, +0.296875f,0.03125f, +0.304688f,0.03125f, +0.3125f,0.03125f, +0.320313f,0.03125f, +0.328125f,0.03125f, +0.335938f,0.03125f, +0.34375f,0.03125f, +0.351563f,0.03125f, +0.359375f,0.03125f, +0.367188f,0.03125f, +0.375f,0.03125f, +0.382813f,0.03125f, +0.390625f,0.03125f, +0.398438f,0.03125f, +0.40625f,0.03125f, +0.414063f,0.03125f, +0.421875f,0.03125f, +0.429688f,0.03125f, +0.4375f,0.03125f, +0.445313f,0.03125f, +0.453125f,0.03125f, +0.460938f,0.03125f, +0.46875f,0.03125f, +0.476563f,0.03125f, +0.484375f,0.03125f, +0.492188f,0.03125f, +0.5f,0.03125f, +0.507813f,0.03125f, +0.0f,0.0390625f, +0.0078125f,0.0390625f, +0.015625f,0.0390625f, +0.0234375f,0.0390625f, +0.03125f,0.0390625f, +0.0390625f,0.0390625f, +0.046875f,0.0390625f, +0.0546875f,0.0390625f, +0.0625f,0.0390625f, +0.0703125f,0.0390625f, +0.078125f,0.0390625f, +0.0859375f,0.0390625f, +0.09375f,0.0390625f, +0.101563f,0.0390625f, +0.109375f,0.0390625f, +0.117188f,0.0390625f, +0.125f,0.0390625f, +0.132813f,0.0390625f, +0.140625f,0.0390625f, +0.148438f,0.0390625f, +0.15625f,0.0390625f, +0.164063f,0.0390625f, +0.171875f,0.0390625f, +0.179688f,0.0390625f, +0.1875f,0.0390625f, +0.195313f,0.0390625f, +0.203125f,0.0390625f, +0.210938f,0.0390625f, +0.21875f,0.0390625f, +0.226563f,0.0390625f, +0.234375f,0.0390625f, +0.242188f,0.0390625f, +0.25f,0.0390625f, +0.257813f,0.0390625f, +0.265625f,0.0390625f, +0.273438f,0.0390625f, +0.28125f,0.0390625f, +0.289063f,0.0390625f, +0.296875f,0.0390625f, +0.304688f,0.0390625f, +0.3125f,0.0390625f, +0.320313f,0.0390625f, +0.328125f,0.0390625f, +0.335938f,0.0390625f, +0.34375f,0.0390625f, +0.351563f,0.0390625f, +0.359375f,0.0390625f, +0.367188f,0.0390625f, +0.375f,0.0390625f, +0.382813f,0.0390625f, +0.390625f,0.0390625f, +0.398438f,0.0390625f, +0.40625f,0.0390625f, +0.414063f,0.0390625f, +0.421875f,0.0390625f, +0.429688f,0.0390625f, +0.4375f,0.0390625f, +0.445313f,0.0390625f, +0.453125f,0.0390625f, +0.460938f,0.0390625f, +0.46875f,0.0390625f, +0.476563f,0.0390625f, +0.484375f,0.0390625f, +0.492188f,0.0390625f, +0.5f,0.0390625f, +0.507813f,0.0390625f, +0.0f,0.046875f, +0.0078125f,0.046875f, +0.015625f,0.046875f, +0.0234375f,0.046875f, +0.03125f,0.046875f, +0.0390625f,0.046875f, +0.046875f,0.046875f, +0.0546875f,0.046875f, +0.0625f,0.046875f, +0.0703125f,0.046875f, +0.078125f,0.046875f, +0.0859375f,0.046875f, +0.09375f,0.046875f, +0.101563f,0.046875f, +0.109375f,0.046875f, +0.117188f,0.046875f, +0.125f,0.046875f, +0.132813f,0.046875f, +0.140625f,0.046875f, +0.148438f,0.046875f, +0.15625f,0.046875f, +0.164063f,0.046875f, +0.171875f,0.046875f, +0.179688f,0.046875f, +0.1875f,0.046875f, +0.195313f,0.046875f, +0.203125f,0.046875f, +0.210938f,0.046875f, +0.21875f,0.046875f, +0.226563f,0.046875f, +0.234375f,0.046875f, +0.242188f,0.046875f, +0.25f,0.046875f, +0.257813f,0.046875f, +0.265625f,0.046875f, +0.273438f,0.046875f, +0.28125f,0.046875f, +0.289063f,0.046875f, +0.296875f,0.046875f, +0.304688f,0.046875f, +0.3125f,0.046875f, +0.320313f,0.046875f, +0.328125f,0.046875f, +0.335938f,0.046875f, +0.34375f,0.046875f, +0.351563f,0.046875f, +0.359375f,0.046875f, +0.367188f,0.046875f, +0.375f,0.046875f, +0.382813f,0.046875f, +0.390625f,0.046875f, +0.398438f,0.046875f, +0.40625f,0.046875f, +0.414063f,0.046875f, +0.421875f,0.046875f, +0.429688f,0.046875f, +0.4375f,0.046875f, +0.445313f,0.046875f, +0.453125f,0.046875f, +0.460938f,0.046875f, +0.46875f,0.046875f, +0.476563f,0.046875f, +0.484375f,0.046875f, +0.492188f,0.046875f, +0.5f,0.046875f, +0.507813f,0.046875f, +0.0f,0.0546875f, +0.0078125f,0.0546875f, +0.015625f,0.0546875f, +0.0234375f,0.0546875f, +0.03125f,0.0546875f, +0.0390625f,0.0546875f, +0.046875f,0.0546875f, +0.0546875f,0.0546875f, +0.0625f,0.0546875f, +0.0703125f,0.0546875f, +0.078125f,0.0546875f, +0.0859375f,0.0546875f, +0.09375f,0.0546875f, +0.101563f,0.0546875f, +0.109375f,0.0546875f, +0.117188f,0.0546875f, +0.125f,0.0546875f, +0.132813f,0.0546875f, +0.140625f,0.0546875f, +0.148438f,0.0546875f, +0.15625f,0.0546875f, +0.164063f,0.0546875f, +0.171875f,0.0546875f, +0.179688f,0.0546875f, +0.1875f,0.0546875f, +0.195313f,0.0546875f, +0.203125f,0.0546875f, +0.210938f,0.0546875f, +0.21875f,0.0546875f, +0.226563f,0.0546875f, +0.234375f,0.0546875f, +0.242188f,0.0546875f, +0.25f,0.0546875f, +0.257813f,0.0546875f, +0.265625f,0.0546875f, +0.273438f,0.0546875f, +0.28125f,0.0546875f, +0.289063f,0.0546875f, +0.296875f,0.0546875f, +0.304688f,0.0546875f, +0.3125f,0.0546875f, +0.320313f,0.0546875f, +0.328125f,0.0546875f, +0.335938f,0.0546875f, +0.34375f,0.0546875f, +0.351563f,0.0546875f, +0.359375f,0.0546875f, +0.367188f,0.0546875f, +0.375f,0.0546875f, +0.382813f,0.0546875f, +0.390625f,0.0546875f, +0.398438f,0.0546875f, +0.40625f,0.0546875f, +0.414063f,0.0546875f, +0.421875f,0.0546875f, +0.429688f,0.0546875f, +0.4375f,0.0546875f, +0.445313f,0.0546875f, +0.453125f,0.0546875f, +0.460938f,0.0546875f, +0.46875f,0.0546875f, +0.476563f,0.0546875f, +0.484375f,0.0546875f, +0.492188f,0.0546875f, +0.5f,0.0546875f, +0.507813f,0.0546875f, +0.0f,0.0625f, +0.0078125f,0.0625f, +0.015625f,0.0625f, +0.0234375f,0.0625f, +0.03125f,0.0625f, +0.0390625f,0.0625f, +0.046875f,0.0625f, +0.0546875f,0.0625f, +0.0625f,0.0625f, +0.0703125f,0.0625f, +0.078125f,0.0625f, +0.0859375f,0.0625f, +0.09375f,0.0625f, +0.101563f,0.0625f, +0.109375f,0.0625f, +0.117188f,0.0625f, +0.125f,0.0625f, +0.132813f,0.0625f, +0.140625f,0.0625f, +0.148438f,0.0625f, +0.15625f,0.0625f, +0.164063f,0.0625f, +0.171875f,0.0625f, +0.179688f,0.0625f, +0.1875f,0.0625f, +0.195313f,0.0625f, +0.203125f,0.0625f, +0.210938f,0.0625f, +0.21875f,0.0625f, +0.226563f,0.0625f, +0.234375f,0.0625f, +0.242188f,0.0625f, +0.25f,0.0625f, +0.257813f,0.0625f, +0.265625f,0.0625f, +0.273438f,0.0625f, +0.28125f,0.0625f, +0.289063f,0.0625f, +0.296875f,0.0625f, +0.304688f,0.0625f, +0.3125f,0.0625f, +0.320313f,0.0625f, +0.328125f,0.0625f, +0.335938f,0.0625f, +0.34375f,0.0625f, +0.351563f,0.0625f, +0.359375f,0.0625f, +0.367188f,0.0625f, +0.375f,0.0625f, +0.382813f,0.0625f, +0.390625f,0.0625f, +0.398438f,0.0625f, +0.40625f,0.0625f, +0.414063f,0.0625f, +0.421875f,0.0625f, +0.429688f,0.0625f, +0.4375f,0.0625f, +0.445313f,0.0625f, +0.453125f,0.0625f, +0.460938f,0.0625f, +0.46875f,0.0625f, +0.476563f,0.0625f, +0.484375f,0.0625f, +0.492188f,0.0625f, +0.5f,0.0625f, +0.507813f,0.0625f, +0.0f,0.0703125f, +0.0078125f,0.0703125f, +0.015625f,0.0703125f, +0.0234375f,0.0703125f, +0.03125f,0.0703125f, +0.0390625f,0.0703125f, +0.046875f,0.0703125f, +0.0546875f,0.0703125f, +0.0625f,0.0703125f, +0.0703125f,0.0703125f, +0.078125f,0.0703125f, +0.0859375f,0.0703125f, +0.09375f,0.0703125f, +0.101563f,0.0703125f, +0.109375f,0.0703125f, +0.117188f,0.0703125f, +0.125f,0.0703125f, +0.132813f,0.0703125f, +0.140625f,0.0703125f, +0.148438f,0.0703125f, +0.15625f,0.0703125f, +0.164063f,0.0703125f, +0.171875f,0.0703125f, +0.179688f,0.0703125f, +0.1875f,0.0703125f, +0.195313f,0.0703125f, +0.203125f,0.0703125f, +0.210938f,0.0703125f, +0.21875f,0.0703125f, +0.226563f,0.0703125f, +0.234375f,0.0703125f, +0.242188f,0.0703125f, +0.25f,0.0703125f, +0.257813f,0.0703125f, +0.265625f,0.0703125f, +0.273438f,0.0703125f, +0.28125f,0.0703125f, +0.289063f,0.0703125f, +0.296875f,0.0703125f, +0.304688f,0.0703125f, +0.3125f,0.0703125f, +0.320313f,0.0703125f, +0.328125f,0.0703125f, +0.335938f,0.0703125f, +0.34375f,0.0703125f, +0.351563f,0.0703125f, +0.359375f,0.0703125f, +0.367188f,0.0703125f, +0.375f,0.0703125f, +0.382813f,0.0703125f, +0.390625f,0.0703125f, +0.398438f,0.0703125f, +0.40625f,0.0703125f, +0.414063f,0.0703125f, +0.421875f,0.0703125f, +0.429688f,0.0703125f, +0.4375f,0.0703125f, +0.445313f,0.0703125f, +0.453125f,0.0703125f, +0.460938f,0.0703125f, +0.46875f,0.0703125f, +0.476563f,0.0703125f, +0.484375f,0.0703125f, +0.492188f,0.0703125f, +0.5f,0.0703125f, +0.507813f,0.0703125f, +0.0f,0.078125f, +0.0078125f,0.078125f, +0.015625f,0.078125f, +0.0234375f,0.078125f, +0.03125f,0.078125f, +0.0390625f,0.078125f, +0.046875f,0.078125f, +0.0546875f,0.078125f, +0.0625f,0.078125f, +0.0703125f,0.078125f, +0.078125f,0.078125f, +0.0859375f,0.078125f, +0.09375f,0.078125f, +0.101563f,0.078125f, +0.109375f,0.078125f, +0.117188f,0.078125f, +0.125f,0.078125f, +0.132813f,0.078125f, +0.140625f,0.078125f, +0.148438f,0.078125f, +0.15625f,0.078125f, +0.164063f,0.078125f, +0.171875f,0.078125f, +0.179688f,0.078125f, +0.1875f,0.078125f, +0.195313f,0.078125f, +0.203125f,0.078125f, +0.210938f,0.078125f, +0.21875f,0.078125f, +0.226563f,0.078125f, +0.234375f,0.078125f, +0.242188f,0.078125f, +0.25f,0.078125f, +0.257813f,0.078125f, +0.265625f,0.078125f, +0.273438f,0.078125f, +0.28125f,0.078125f, +0.289063f,0.078125f, +0.296875f,0.078125f, +0.304688f,0.078125f, +0.3125f,0.078125f, +0.320313f,0.078125f, +0.328125f,0.078125f, +0.335938f,0.078125f, +0.34375f,0.078125f, +0.351563f,0.078125f, +0.359375f,0.078125f, +0.367188f,0.078125f, +0.375f,0.078125f, +0.382813f,0.078125f, +0.390625f,0.078125f, +0.398438f,0.078125f, +0.40625f,0.078125f, +0.414063f,0.078125f, +0.421875f,0.078125f, +0.429688f,0.078125f, +0.4375f,0.078125f, +0.445313f,0.078125f, +0.453125f,0.078125f, +0.460938f,0.078125f, +0.46875f,0.078125f, +0.476563f,0.078125f, +0.484375f,0.078125f, +0.492188f,0.078125f, +0.5f,0.078125f, +0.507813f,0.078125f, +0.0f,0.0859375f, +0.0078125f,0.0859375f, +0.015625f,0.0859375f, +0.0234375f,0.0859375f, +0.03125f,0.0859375f, +0.0390625f,0.0859375f, +0.046875f,0.0859375f, +0.0546875f,0.0859375f, +0.0625f,0.0859375f, +0.0703125f,0.0859375f, +0.078125f,0.0859375f, +0.0859375f,0.0859375f, +0.09375f,0.0859375f, +0.101563f,0.0859375f, +0.109375f,0.0859375f, +0.117188f,0.0859375f, +0.125f,0.0859375f, +0.132813f,0.0859375f, +0.140625f,0.0859375f, +0.148438f,0.0859375f, +0.15625f,0.0859375f, +0.164063f,0.0859375f, +0.171875f,0.0859375f, +0.179688f,0.0859375f, +0.1875f,0.0859375f, +0.195313f,0.0859375f, +0.203125f,0.0859375f, +0.210938f,0.0859375f, +0.21875f,0.0859375f, +0.226563f,0.0859375f, +0.234375f,0.0859375f, +0.242188f,0.0859375f, +0.25f,0.0859375f, +0.257813f,0.0859375f, +0.265625f,0.0859375f, +0.273438f,0.0859375f, +0.28125f,0.0859375f, +0.289063f,0.0859375f, +0.296875f,0.0859375f, +0.304688f,0.0859375f, +0.3125f,0.0859375f, +0.320313f,0.0859375f, +0.328125f,0.0859375f, +0.335938f,0.0859375f, +0.34375f,0.0859375f, +0.351563f,0.0859375f, +0.359375f,0.0859375f, +0.367188f,0.0859375f, +0.375f,0.0859375f, +0.382813f,0.0859375f, +0.390625f,0.0859375f, +0.398438f,0.0859375f, +0.40625f,0.0859375f, +0.414063f,0.0859375f, +0.421875f,0.0859375f, +0.429688f,0.0859375f, +0.4375f,0.0859375f, +0.445313f,0.0859375f, +0.453125f,0.0859375f, +0.460938f,0.0859375f, +0.46875f,0.0859375f, +0.476563f,0.0859375f, +0.484375f,0.0859375f, +0.492188f,0.0859375f, +0.5f,0.0859375f, +0.507813f,0.0859375f, +0.0f,0.09375f, +0.0078125f,0.09375f, +0.015625f,0.09375f, +0.0234375f,0.09375f, +0.03125f,0.09375f, +0.0390625f,0.09375f, +0.046875f,0.09375f, +0.0546875f,0.09375f, +0.0625f,0.09375f, +0.0703125f,0.09375f, +0.078125f,0.09375f, +0.0859375f,0.09375f, +0.09375f,0.09375f, +0.101563f,0.09375f, +0.109375f,0.09375f, +0.117188f,0.09375f, +0.125f,0.09375f, +0.132813f,0.09375f, +0.140625f,0.09375f, +0.148438f,0.09375f, +0.15625f,0.09375f, +0.164063f,0.09375f, +0.171875f,0.09375f, +0.179688f,0.09375f, +0.1875f,0.09375f, +0.195313f,0.09375f, +0.203125f,0.09375f, +0.210938f,0.09375f, +0.21875f,0.09375f, +0.226563f,0.09375f, +0.234375f,0.09375f, +0.242188f,0.09375f, +0.25f,0.09375f, +0.257813f,0.09375f, +0.265625f,0.09375f, +0.273438f,0.09375f, +0.28125f,0.09375f, +0.289063f,0.09375f, +0.296875f,0.09375f, +0.304688f,0.09375f, +0.3125f,0.09375f, +0.320313f,0.09375f, +0.328125f,0.09375f, +0.335938f,0.09375f, +0.34375f,0.09375f, +0.351563f,0.09375f, +0.359375f,0.09375f, +0.367188f,0.09375f, +0.375f,0.09375f, +0.382813f,0.09375f, +0.390625f,0.09375f, +0.398438f,0.09375f, +0.40625f,0.09375f, +0.414063f,0.09375f, +0.421875f,0.09375f, +0.429688f,0.09375f, +0.4375f,0.09375f, +0.445313f,0.09375f, +0.453125f,0.09375f, +0.460938f,0.09375f, +0.46875f,0.09375f, +0.476563f,0.09375f, +0.484375f,0.09375f, +0.492188f,0.09375f, +0.5f,0.09375f, +0.507813f,0.09375f, +0.0f,0.101563f, +0.0078125f,0.101563f, +0.015625f,0.101563f, +0.0234375f,0.101563f, +0.03125f,0.101563f, +0.0390625f,0.101563f, +0.046875f,0.101563f, +0.0546875f,0.101563f, +0.0625f,0.101563f, +0.0703125f,0.101563f, +0.078125f,0.101563f, +0.0859375f,0.101563f, +0.09375f,0.101563f, +0.101563f,0.101563f, +0.109375f,0.101563f, +0.117188f,0.101563f, +0.125f,0.101563f, +0.132813f,0.101563f, +0.140625f,0.101563f, +0.148438f,0.101563f, +0.15625f,0.101563f, +0.164063f,0.101563f, +0.171875f,0.101563f, +0.179688f,0.101563f, +0.1875f,0.101563f, +0.195313f,0.101563f, +0.203125f,0.101563f, +0.210938f,0.101563f, +0.21875f,0.101563f, +0.226563f,0.101563f, +0.234375f,0.101563f, +0.242188f,0.101563f, +0.25f,0.101563f, +0.257813f,0.101563f, +0.265625f,0.101563f, +0.273438f,0.101563f, +0.28125f,0.101563f, +0.289063f,0.101563f, +0.296875f,0.101563f, +0.304688f,0.101563f, +0.3125f,0.101563f, +0.320313f,0.101563f, +0.328125f,0.101563f, +0.335938f,0.101563f, +0.34375f,0.101563f, +0.351563f,0.101563f, +0.359375f,0.101563f, +0.367188f,0.101563f, +0.375f,0.101563f, +0.382813f,0.101563f, +0.390625f,0.101563f, +0.398438f,0.101563f, +0.40625f,0.101563f, +0.414063f,0.101563f, +0.421875f,0.101563f, +0.429688f,0.101563f, +0.4375f,0.101563f, +0.445313f,0.101563f, +0.453125f,0.101563f, +0.460938f,0.101563f, +0.46875f,0.101563f, +0.476563f,0.101563f, +0.484375f,0.101563f, +0.492188f,0.101563f, +0.5f,0.101563f, +0.507813f,0.101563f, +0.0f,0.109375f, +0.0078125f,0.109375f, +0.015625f,0.109375f, +0.0234375f,0.109375f, +0.03125f,0.109375f, +0.0390625f,0.109375f, +0.046875f,0.109375f, +0.0546875f,0.109375f, +0.0625f,0.109375f, +0.0703125f,0.109375f, +0.078125f,0.109375f, +0.0859375f,0.109375f, +0.09375f,0.109375f, +0.101563f,0.109375f, +0.109375f,0.109375f, +0.117188f,0.109375f, +0.125f,0.109375f, +0.132813f,0.109375f, +0.140625f,0.109375f, +0.148438f,0.109375f, +0.15625f,0.109375f, +0.164063f,0.109375f, +0.171875f,0.109375f, +0.179688f,0.109375f, +0.1875f,0.109375f, +0.195313f,0.109375f, +0.203125f,0.109375f, +0.210938f,0.109375f, +0.21875f,0.109375f, +0.226563f,0.109375f, +0.234375f,0.109375f, +0.242188f,0.109375f, +0.25f,0.109375f, +0.257813f,0.109375f, +0.265625f,0.109375f, +0.273438f,0.109375f, +0.28125f,0.109375f, +0.289063f,0.109375f, +0.296875f,0.109375f, +0.304688f,0.109375f, +0.3125f,0.109375f, +0.320313f,0.109375f, +0.328125f,0.109375f, +0.335938f,0.109375f, +0.34375f,0.109375f, +0.351563f,0.109375f, +0.359375f,0.109375f, +0.367188f,0.109375f, +0.375f,0.109375f, +0.382813f,0.109375f, +0.390625f,0.109375f, +0.398438f,0.109375f, +0.40625f,0.109375f, +0.414063f,0.109375f, +0.421875f,0.109375f, +0.429688f,0.109375f, +0.4375f,0.109375f, +0.445313f,0.109375f, +0.453125f,0.109375f, +0.460938f,0.109375f, +0.46875f,0.109375f, +0.476563f,0.109375f, +0.484375f,0.109375f, +0.492188f,0.109375f, +0.5f,0.109375f, +0.507813f,0.109375f, +0.0f,0.117188f, +0.0078125f,0.117188f, +0.015625f,0.117188f, +0.0234375f,0.117188f, +0.03125f,0.117188f, +0.0390625f,0.117188f, +0.046875f,0.117188f, +0.0546875f,0.117188f, +0.0625f,0.117188f, +0.0703125f,0.117188f, +0.078125f,0.117188f, +0.0859375f,0.117188f, +0.09375f,0.117188f, +0.101563f,0.117188f, +0.109375f,0.117188f, +0.117188f,0.117188f, +0.125f,0.117188f, +0.132813f,0.117188f, +0.140625f,0.117188f, +0.148438f,0.117188f, +0.15625f,0.117188f, +0.164063f,0.117188f, +0.171875f,0.117188f, +0.179688f,0.117188f, +0.1875f,0.117188f, +0.195313f,0.117188f, +0.203125f,0.117188f, +0.210938f,0.117188f, +0.21875f,0.117188f, +0.226563f,0.117188f, +0.234375f,0.117188f, +0.242188f,0.117188f, +0.25f,0.117188f, +0.257813f,0.117188f, +0.265625f,0.117188f, +0.273438f,0.117188f, +0.28125f,0.117188f, +0.289063f,0.117188f, +0.296875f,0.117188f, +0.304688f,0.117188f, +0.3125f,0.117188f, +0.320313f,0.117188f, +0.328125f,0.117188f, +0.335938f,0.117188f, +0.34375f,0.117188f, +0.351563f,0.117188f, +0.359375f,0.117188f, +0.367188f,0.117188f, +0.375f,0.117188f, +0.382813f,0.117188f, +0.390625f,0.117188f, +0.398438f,0.117188f, +0.40625f,0.117188f, +0.414063f,0.117188f, +0.421875f,0.117188f, +0.429688f,0.117188f, +0.4375f,0.117188f, +0.445313f,0.117188f, +0.453125f,0.117188f, +0.460938f,0.117188f, +0.46875f,0.117188f, +0.476563f,0.117188f, +0.484375f,0.117188f, +0.492188f,0.117188f, +0.5f,0.117188f, +0.507813f,0.117188f, +0.0f,0.125f, +0.0078125f,0.125f, +0.015625f,0.125f, +0.0234375f,0.125f, +0.03125f,0.125f, +0.0390625f,0.125f, +0.046875f,0.125f, +0.0546875f,0.125f, +0.0625f,0.125f, +0.0703125f,0.125f, +0.078125f,0.125f, +0.0859375f,0.125f, +0.09375f,0.125f, +0.101563f,0.125f, +0.109375f,0.125f, +0.117188f,0.125f, +0.125f,0.125f, +0.132813f,0.125f, +0.140625f,0.125f, +0.148438f,0.125f, +0.15625f,0.125f, +0.164063f,0.125f, +0.171875f,0.125f, +0.179688f,0.125f, +0.1875f,0.125f, +0.195313f,0.125f, +0.203125f,0.125f, +0.210938f,0.125f, +0.21875f,0.125f, +0.226563f,0.125f, +0.234375f,0.125f, +0.242188f,0.125f, +0.25f,0.125f, +0.257813f,0.125f, +0.265625f,0.125f, +0.273438f,0.125f, +0.28125f,0.125f, +0.289063f,0.125f, +0.296875f,0.125f, +0.304688f,0.125f, +0.3125f,0.125f, +0.320313f,0.125f, +0.328125f,0.125f, +0.335938f,0.125f, +0.34375f,0.125f, +0.351563f,0.125f, +0.359375f,0.125f, +0.367188f,0.125f, +0.375f,0.125f, +0.382813f,0.125f, +0.390625f,0.125f, +0.398438f,0.125f, +0.40625f,0.125f, +0.414063f,0.125f, +0.421875f,0.125f, +0.429688f,0.125f, +0.4375f,0.125f, +0.445313f,0.125f, +0.453125f,0.125f, +0.460938f,0.125f, +0.46875f,0.125f, +0.476563f,0.125f, +0.484375f,0.125f, +0.492188f,0.125f, +0.5f,0.125f, +0.507813f,0.125f, +0.0f,0.132813f, +0.0078125f,0.132813f, +0.015625f,0.132813f, +0.0234375f,0.132813f, +0.03125f,0.132813f, +0.0390625f,0.132813f, +0.046875f,0.132813f, +0.0546875f,0.132813f, +0.0625f,0.132813f, +0.0703125f,0.132813f, +0.078125f,0.132813f, +0.0859375f,0.132813f, +0.09375f,0.132813f, +0.101563f,0.132813f, +0.109375f,0.132813f, +0.117188f,0.132813f, +0.125f,0.132813f, +0.132813f,0.132813f, +0.140625f,0.132813f, +0.148438f,0.132813f, +0.15625f,0.132813f, +0.164063f,0.132813f, +0.171875f,0.132813f, +0.179688f,0.132813f, +0.1875f,0.132813f, +0.195313f,0.132813f, +0.203125f,0.132813f, +0.210938f,0.132813f, +0.21875f,0.132813f, +0.226563f,0.132813f, +0.234375f,0.132813f, +0.242188f,0.132813f, +0.25f,0.132813f, +0.257813f,0.132813f, +0.265625f,0.132813f, +0.273438f,0.132813f, +0.28125f,0.132813f, +0.289063f,0.132813f, +0.296875f,0.132813f, +0.304688f,0.132813f, +0.3125f,0.132813f, +0.320313f,0.132813f, +0.328125f,0.132813f, +0.335938f,0.132813f, +0.34375f,0.132813f, +0.351563f,0.132813f, +0.359375f,0.132813f, +0.367188f,0.132813f, +0.375f,0.132813f, +0.382813f,0.132813f, +0.390625f,0.132813f, +0.398438f,0.132813f, +0.40625f,0.132813f, +0.414063f,0.132813f, +0.421875f,0.132813f, +0.429688f,0.132813f, +0.4375f,0.132813f, +0.445313f,0.132813f, +0.453125f,0.132813f, +0.460938f,0.132813f, +0.46875f,0.132813f, +0.476563f,0.132813f, +0.484375f,0.132813f, +0.492188f,0.132813f, +0.5f,0.132813f, +0.507813f,0.132813f, +0.0f,0.140625f, +0.0078125f,0.140625f, +0.015625f,0.140625f, +0.0234375f,0.140625f, +0.03125f,0.140625f, +0.0390625f,0.140625f, +0.046875f,0.140625f, +0.0546875f,0.140625f, +0.0625f,0.140625f, +0.0703125f,0.140625f, +0.078125f,0.140625f, +0.0859375f,0.140625f, +0.09375f,0.140625f, +0.101563f,0.140625f, +0.109375f,0.140625f, +0.117188f,0.140625f, +0.125f,0.140625f, +0.132813f,0.140625f, +0.140625f,0.140625f, +0.148438f,0.140625f, +0.15625f,0.140625f, +0.164063f,0.140625f, +0.171875f,0.140625f, +0.179688f,0.140625f, +0.1875f,0.140625f, +0.195313f,0.140625f, +0.203125f,0.140625f, +0.210938f,0.140625f, +0.21875f,0.140625f, +0.226563f,0.140625f, +0.234375f,0.140625f, +0.242188f,0.140625f, +0.25f,0.140625f, +0.257813f,0.140625f, +0.265625f,0.140625f, +0.273438f,0.140625f, +0.28125f,0.140625f, +0.289063f,0.140625f, +0.296875f,0.140625f, +0.304688f,0.140625f, +0.3125f,0.140625f, +0.320313f,0.140625f, +0.328125f,0.140625f, +0.335938f,0.140625f, +0.34375f,0.140625f, +0.351563f,0.140625f, +0.359375f,0.140625f, +0.367188f,0.140625f, +0.375f,0.140625f, +0.382813f,0.140625f, +0.390625f,0.140625f, +0.398438f,0.140625f, +0.40625f,0.140625f, +0.414063f,0.140625f, +0.421875f,0.140625f, +0.429688f,0.140625f, +0.4375f,0.140625f, +0.445313f,0.140625f, +0.453125f,0.140625f, +0.460938f,0.140625f, +0.46875f,0.140625f, +0.476563f,0.140625f, +0.484375f,0.140625f, +0.492188f,0.140625f, +0.5f,0.140625f, +0.507813f,0.140625f, +0.0f,0.148438f, +0.0078125f,0.148438f, +0.015625f,0.148438f, +0.0234375f,0.148438f, +0.03125f,0.148438f, +0.0390625f,0.148438f, +0.046875f,0.148438f, +0.0546875f,0.148438f, +0.0625f,0.148438f, +0.0703125f,0.148438f, +0.078125f,0.148438f, +0.0859375f,0.148438f, +0.09375f,0.148438f, +0.101563f,0.148438f, +0.109375f,0.148438f, +0.117188f,0.148438f, +0.125f,0.148438f, +0.132813f,0.148438f, +0.140625f,0.148438f, +0.148438f,0.148438f, +0.15625f,0.148438f, +0.164063f,0.148438f, +0.171875f,0.148438f, +0.179688f,0.148438f, +0.1875f,0.148438f, +0.195313f,0.148438f, +0.203125f,0.148438f, +0.210938f,0.148438f, +0.21875f,0.148438f, +0.226563f,0.148438f, +0.234375f,0.148438f, +0.242188f,0.148438f, +0.25f,0.148438f, +0.257813f,0.148438f, +0.265625f,0.148438f, +0.273438f,0.148438f, +0.28125f,0.148438f, +0.289063f,0.148438f, +0.296875f,0.148438f, +0.304688f,0.148438f, +0.3125f,0.148438f, +0.320313f,0.148438f, +0.328125f,0.148438f, +0.335938f,0.148438f, +0.34375f,0.148438f, +0.351563f,0.148438f, +0.359375f,0.148438f, +0.367188f,0.148438f, +0.375f,0.148438f, +0.382813f,0.148438f, +0.390625f,0.148438f, +0.398438f,0.148438f, +0.40625f,0.148438f, +0.414063f,0.148438f, +0.421875f,0.148438f, +0.429688f,0.148438f, +0.4375f,0.148438f, +0.445313f,0.148438f, +0.453125f,0.148438f, +0.460938f,0.148438f, +0.46875f,0.148438f, +0.476563f,0.148438f, +0.484375f,0.148438f, +0.492188f,0.148438f, +0.5f,0.148438f, +0.507813f,0.148438f, +0.0f,0.15625f, +0.0078125f,0.15625f, +0.015625f,0.15625f, +0.0234375f,0.15625f, +0.03125f,0.15625f, +0.0390625f,0.15625f, +0.046875f,0.15625f, +0.0546875f,0.15625f, +0.0625f,0.15625f, +0.0703125f,0.15625f, +0.078125f,0.15625f, +0.0859375f,0.15625f, +0.09375f,0.15625f, +0.101563f,0.15625f, +0.109375f,0.15625f, +0.117188f,0.15625f, +0.125f,0.15625f, +0.132813f,0.15625f, +0.140625f,0.15625f, +0.148438f,0.15625f, +0.15625f,0.15625f, +0.164063f,0.15625f, +0.171875f,0.15625f, +0.179688f,0.15625f, +0.1875f,0.15625f, +0.195313f,0.15625f, +0.203125f,0.15625f, +0.210938f,0.15625f, +0.21875f,0.15625f, +0.226563f,0.15625f, +0.234375f,0.15625f, +0.242188f,0.15625f, +0.25f,0.15625f, +0.257813f,0.15625f, +0.265625f,0.15625f, +0.273438f,0.15625f, +0.28125f,0.15625f, +0.289063f,0.15625f, +0.296875f,0.15625f, +0.304688f,0.15625f, +0.3125f,0.15625f, +0.320313f,0.15625f, +0.328125f,0.15625f, +0.335938f,0.15625f, +0.34375f,0.15625f, +0.351563f,0.15625f, +0.359375f,0.15625f, +0.367188f,0.15625f, +0.375f,0.15625f, +0.382813f,0.15625f, +0.390625f,0.15625f, +0.398438f,0.15625f, +0.40625f,0.15625f, +0.414063f,0.15625f, +0.421875f,0.15625f, +0.429688f,0.15625f, +0.4375f,0.15625f, +0.445313f,0.15625f, +0.453125f,0.15625f, +0.460938f,0.15625f, +0.46875f,0.15625f, +0.476563f,0.15625f, +0.484375f,0.15625f, +0.492188f,0.15625f, +0.5f,0.15625f, +0.507813f,0.15625f, +0.0f,0.164063f, +0.0078125f,0.164063f, +0.015625f,0.164063f, +0.0234375f,0.164063f, +0.03125f,0.164063f, +0.0390625f,0.164063f, +0.046875f,0.164063f, +0.0546875f,0.164063f, +0.0625f,0.164063f, +0.0703125f,0.164063f, +0.078125f,0.164063f, +0.0859375f,0.164063f, +0.09375f,0.164063f, +0.101563f,0.164063f, +0.109375f,0.164063f, +0.117188f,0.164063f, +0.125f,0.164063f, +0.132813f,0.164063f, +0.140625f,0.164063f, +0.148438f,0.164063f, +0.15625f,0.164063f, +0.164063f,0.164063f, +0.171875f,0.164063f, +0.179688f,0.164063f, +0.1875f,0.164063f, +0.195313f,0.164063f, +0.203125f,0.164063f, +0.210938f,0.164063f, +0.21875f,0.164063f, +0.226563f,0.164063f, +0.234375f,0.164063f, +0.242188f,0.164063f, +0.25f,0.164063f, +0.257813f,0.164063f, +0.265625f,0.164063f, +0.273438f,0.164063f, +0.28125f,0.164063f, +0.289063f,0.164063f, +0.296875f,0.164063f, +0.304688f,0.164063f, +0.3125f,0.164063f, +0.320313f,0.164063f, +0.328125f,0.164063f, +0.335938f,0.164063f, +0.34375f,0.164063f, +0.351563f,0.164063f, +0.359375f,0.164063f, +0.367188f,0.164063f, +0.375f,0.164063f, +0.382813f,0.164063f, +0.390625f,0.164063f, +0.398438f,0.164063f, +0.40625f,0.164063f, +0.414063f,0.164063f, +0.421875f,0.164063f, +0.429688f,0.164063f, +0.4375f,0.164063f, +0.445313f,0.164063f, +0.453125f,0.164063f, +0.460938f,0.164063f, +0.46875f,0.164063f, +0.476563f,0.164063f, +0.484375f,0.164063f, +0.492188f,0.164063f, +0.5f,0.164063f, +0.507813f,0.164063f, +0.0f,0.171875f, +0.0078125f,0.171875f, +0.015625f,0.171875f, +0.0234375f,0.171875f, +0.03125f,0.171875f, +0.0390625f,0.171875f, +0.046875f,0.171875f, +0.0546875f,0.171875f, +0.0625f,0.171875f, +0.0703125f,0.171875f, +0.078125f,0.171875f, +0.0859375f,0.171875f, +0.09375f,0.171875f, +0.101563f,0.171875f, +0.109375f,0.171875f, +0.117188f,0.171875f, +0.125f,0.171875f, +0.132813f,0.171875f, +0.140625f,0.171875f, +0.148438f,0.171875f, +0.15625f,0.171875f, +0.164063f,0.171875f, +0.171875f,0.171875f, +0.179688f,0.171875f, +0.1875f,0.171875f, +0.195313f,0.171875f, +0.203125f,0.171875f, +0.210938f,0.171875f, +0.21875f,0.171875f, +0.226563f,0.171875f, +0.234375f,0.171875f, +0.242188f,0.171875f, +0.25f,0.171875f, +0.257813f,0.171875f, +0.265625f,0.171875f, +0.273438f,0.171875f, +0.28125f,0.171875f, +0.289063f,0.171875f, +0.296875f,0.171875f, +0.304688f,0.171875f, +0.3125f,0.171875f, +0.320313f,0.171875f, +0.328125f,0.171875f, +0.335938f,0.171875f, +0.34375f,0.171875f, +0.351563f,0.171875f, +0.359375f,0.171875f, +0.367188f,0.171875f, +0.375f,0.171875f, +0.382813f,0.171875f, +0.390625f,0.171875f, +0.398438f,0.171875f, +0.40625f,0.171875f, +0.414063f,0.171875f, +0.421875f,0.171875f, +0.429688f,0.171875f, +0.4375f,0.171875f, +0.445313f,0.171875f, +0.453125f,0.171875f, +0.460938f,0.171875f, +0.46875f,0.171875f, +0.476563f,0.171875f, +0.484375f,0.171875f, +0.492188f,0.171875f, +0.5f,0.171875f, +0.507813f,0.171875f, +0.0f,0.179688f, +0.0078125f,0.179688f, +0.015625f,0.179688f, +0.0234375f,0.179688f, +0.03125f,0.179688f, +0.0390625f,0.179688f, +0.046875f,0.179688f, +0.0546875f,0.179688f, +0.0625f,0.179688f, +0.0703125f,0.179688f, +0.078125f,0.179688f, +0.0859375f,0.179688f, +0.09375f,0.179688f, +0.101563f,0.179688f, +0.109375f,0.179688f, +0.117188f,0.179688f, +0.125f,0.179688f, +0.132813f,0.179688f, +0.140625f,0.179688f, +0.148438f,0.179688f, +0.15625f,0.179688f, +0.164063f,0.179688f, +0.171875f,0.179688f, +0.179688f,0.179688f, +0.1875f,0.179688f, +0.195313f,0.179688f, +0.203125f,0.179688f, +0.210938f,0.179688f, +0.21875f,0.179688f, +0.226563f,0.179688f, +0.234375f,0.179688f, +0.242188f,0.179688f, +0.25f,0.179688f, +0.257813f,0.179688f, +0.265625f,0.179688f, +0.273438f,0.179688f, +0.28125f,0.179688f, +0.289063f,0.179688f, +0.296875f,0.179688f, +0.304688f,0.179688f, +0.3125f,0.179688f, +0.320313f,0.179688f, +0.328125f,0.179688f, +0.335938f,0.179688f, +0.34375f,0.179688f, +0.351563f,0.179688f, +0.359375f,0.179688f, +0.367188f,0.179688f, +0.375f,0.179688f, +0.382813f,0.179688f, +0.390625f,0.179688f, +0.398438f,0.179688f, +0.40625f,0.179688f, +0.414063f,0.179688f, +0.421875f,0.179688f, +0.429688f,0.179688f, +0.4375f,0.179688f, +0.445313f,0.179688f, +0.453125f,0.179688f, +0.460938f,0.179688f, +0.46875f,0.179688f, +0.476563f,0.179688f, +0.484375f,0.179688f, +0.492188f,0.179688f, +0.5f,0.179688f, +0.507813f,0.179688f, +0.0f,0.1875f, +0.0078125f,0.1875f, +0.015625f,0.1875f, +0.0234375f,0.1875f, +0.03125f,0.1875f, +0.0390625f,0.1875f, +0.046875f,0.1875f, +0.0546875f,0.1875f, +0.0625f,0.1875f, +0.0703125f,0.1875f, +0.078125f,0.1875f, +0.0859375f,0.1875f, +0.09375f,0.1875f, +0.101563f,0.1875f, +0.109375f,0.1875f, +0.117188f,0.1875f, +0.125f,0.1875f, +0.132813f,0.1875f, +0.140625f,0.1875f, +0.148438f,0.1875f, +0.15625f,0.1875f, +0.164063f,0.1875f, +0.171875f,0.1875f, +0.179688f,0.1875f, +0.1875f,0.1875f, +0.195313f,0.1875f, +0.203125f,0.1875f, +0.210938f,0.1875f, +0.21875f,0.1875f, +0.226563f,0.1875f, +0.234375f,0.1875f, +0.242188f,0.1875f, +0.25f,0.1875f, +0.257813f,0.1875f, +0.265625f,0.1875f, +0.273438f,0.1875f, +0.28125f,0.1875f, +0.289063f,0.1875f, +0.296875f,0.1875f, +0.304688f,0.1875f, +0.3125f,0.1875f, +0.320313f,0.1875f, +0.328125f,0.1875f, +0.335938f,0.1875f, +0.34375f,0.1875f, +0.351563f,0.1875f, +0.359375f,0.1875f, +0.367188f,0.1875f, +0.375f,0.1875f, +0.382813f,0.1875f, +0.390625f,0.1875f, +0.398438f,0.1875f, +0.40625f,0.1875f, +0.414063f,0.1875f, +0.421875f,0.1875f, +0.429688f,0.1875f, +0.4375f,0.1875f, +0.445313f,0.1875f, +0.453125f,0.1875f, +0.460938f,0.1875f, +0.46875f,0.1875f, +0.476563f,0.1875f, +0.484375f,0.1875f, +0.492188f,0.1875f, +0.5f,0.1875f, +0.507813f,0.1875f, +0.0f,0.195313f, +0.0078125f,0.195313f, +0.015625f,0.195313f, +0.0234375f,0.195313f, +0.03125f,0.195313f, +0.0390625f,0.195313f, +0.046875f,0.195313f, +0.0546875f,0.195313f, +0.0625f,0.195313f, +0.0703125f,0.195313f, +0.078125f,0.195313f, +0.0859375f,0.195313f, +0.09375f,0.195313f, +0.101563f,0.195313f, +0.109375f,0.195313f, +0.117188f,0.195313f, +0.125f,0.195313f, +0.132813f,0.195313f, +0.140625f,0.195313f, +0.148438f,0.195313f, +0.15625f,0.195313f, +0.164063f,0.195313f, +0.171875f,0.195313f, +0.179688f,0.195313f, +0.1875f,0.195313f, +0.195313f,0.195313f, +0.203125f,0.195313f, +0.210938f,0.195313f, +0.21875f,0.195313f, +0.226563f,0.195313f, +0.234375f,0.195313f, +0.242188f,0.195313f, +0.25f,0.195313f, +0.257813f,0.195313f, +0.265625f,0.195313f, +0.273438f,0.195313f, +0.28125f,0.195313f, +0.289063f,0.195313f, +0.296875f,0.195313f, +0.304688f,0.195313f, +0.3125f,0.195313f, +0.320313f,0.195313f, +0.328125f,0.195313f, +0.335938f,0.195313f, +0.34375f,0.195313f, +0.351563f,0.195313f, +0.359375f,0.195313f, +0.367188f,0.195313f, +0.375f,0.195313f, +0.382813f,0.195313f, +0.390625f,0.195313f, +0.398438f,0.195313f, +0.40625f,0.195313f, +0.414063f,0.195313f, +0.421875f,0.195313f, +0.429688f,0.195313f, +0.4375f,0.195313f, +0.445313f,0.195313f, +0.453125f,0.195313f, +0.460938f,0.195313f, +0.46875f,0.195313f, +0.476563f,0.195313f, +0.484375f,0.195313f, +0.492188f,0.195313f, +0.5f,0.195313f, +0.507813f,0.195313f, +0.0f,0.203125f, +0.0078125f,0.203125f, +0.015625f,0.203125f, +0.0234375f,0.203125f, +0.03125f,0.203125f, +0.0390625f,0.203125f, +0.046875f,0.203125f, +0.0546875f,0.203125f, +0.0625f,0.203125f, +0.0703125f,0.203125f, +0.078125f,0.203125f, +0.0859375f,0.203125f, +0.09375f,0.203125f, +0.101563f,0.203125f, +0.109375f,0.203125f, +0.117188f,0.203125f, +0.125f,0.203125f, +0.132813f,0.203125f, +0.140625f,0.203125f, +0.148438f,0.203125f, +0.15625f,0.203125f, +0.164063f,0.203125f, +0.171875f,0.203125f, +0.179688f,0.203125f, +0.1875f,0.203125f, +0.195313f,0.203125f, +0.203125f,0.203125f, +0.210938f,0.203125f, +0.21875f,0.203125f, +0.226563f,0.203125f, +0.234375f,0.203125f, +0.242188f,0.203125f, +0.25f,0.203125f, +0.257813f,0.203125f, +0.265625f,0.203125f, +0.273438f,0.203125f, +0.28125f,0.203125f, +0.289063f,0.203125f, +0.296875f,0.203125f, +0.304688f,0.203125f, +0.3125f,0.203125f, +0.320313f,0.203125f, +0.328125f,0.203125f, +0.335938f,0.203125f, +0.34375f,0.203125f, +0.351563f,0.203125f, +0.359375f,0.203125f, +0.367188f,0.203125f, +0.375f,0.203125f, +0.382813f,0.203125f, +0.390625f,0.203125f, +0.398438f,0.203125f, +0.40625f,0.203125f, +0.414063f,0.203125f, +0.421875f,0.203125f, +0.429688f,0.203125f, +0.4375f,0.203125f, +0.445313f,0.203125f, +0.453125f,0.203125f, +0.460938f,0.203125f, +0.46875f,0.203125f, +0.476563f,0.203125f, +0.484375f,0.203125f, +0.492188f,0.203125f, +0.5f,0.203125f, +0.507813f,0.203125f, +0.0f,0.210938f, +0.0078125f,0.210938f, +0.015625f,0.210938f, +0.0234375f,0.210938f, +0.03125f,0.210938f, +0.0390625f,0.210938f, +0.046875f,0.210938f, +0.0546875f,0.210938f, +0.0625f,0.210938f, +0.0703125f,0.210938f, +0.078125f,0.210938f, +0.0859375f,0.210938f, +0.09375f,0.210938f, +0.101563f,0.210938f, +0.109375f,0.210938f, +0.117188f,0.210938f, +0.125f,0.210938f, +0.132813f,0.210938f, +0.140625f,0.210938f, +0.148438f,0.210938f, +0.15625f,0.210938f, +0.164063f,0.210938f, +0.171875f,0.210938f, +0.179688f,0.210938f, +0.1875f,0.210938f, +0.195313f,0.210938f, +0.203125f,0.210938f, +0.210938f,0.210938f, +0.21875f,0.210938f, +0.226563f,0.210938f, +0.234375f,0.210938f, +0.242188f,0.210938f, +0.25f,0.210938f, +0.257813f,0.210938f, +0.265625f,0.210938f, +0.273438f,0.210938f, +0.28125f,0.210938f, +0.289063f,0.210938f, +0.296875f,0.210938f, +0.304688f,0.210938f, +0.3125f,0.210938f, +0.320313f,0.210938f, +0.328125f,0.210938f, +0.335938f,0.210938f, +0.34375f,0.210938f, +0.351563f,0.210938f, +0.359375f,0.210938f, +0.367188f,0.210938f, +0.375f,0.210938f, +0.382813f,0.210938f, +0.390625f,0.210938f, +0.398438f,0.210938f, +0.40625f,0.210938f, +0.414063f,0.210938f, +0.421875f,0.210938f, +0.429688f,0.210938f, +0.4375f,0.210938f, +0.445313f,0.210938f, +0.453125f,0.210938f, +0.460938f,0.210938f, +0.46875f,0.210938f, +0.476563f,0.210938f, +0.484375f,0.210938f, +0.492188f,0.210938f, +0.5f,0.210938f, +0.507813f,0.210938f, +0.0f,0.21875f, +0.0078125f,0.21875f, +0.015625f,0.21875f, +0.0234375f,0.21875f, +0.03125f,0.21875f, +0.0390625f,0.21875f, +0.046875f,0.21875f, +0.0546875f,0.21875f, +0.0625f,0.21875f, +0.0703125f,0.21875f, +0.078125f,0.21875f, +0.0859375f,0.21875f, +0.09375f,0.21875f, +0.101563f,0.21875f, +0.109375f,0.21875f, +0.117188f,0.21875f, +0.125f,0.21875f, +0.132813f,0.21875f, +0.140625f,0.21875f, +0.148438f,0.21875f, +0.15625f,0.21875f, +0.164063f,0.21875f, +0.171875f,0.21875f, +0.179688f,0.21875f, +0.1875f,0.21875f, +0.195313f,0.21875f, +0.203125f,0.21875f, +0.210938f,0.21875f, +0.21875f,0.21875f, +0.226563f,0.21875f, +0.234375f,0.21875f, +0.242188f,0.21875f, +0.25f,0.21875f, +0.257813f,0.21875f, +0.265625f,0.21875f, +0.273438f,0.21875f, +0.28125f,0.21875f, +0.289063f,0.21875f, +0.296875f,0.21875f, +0.304688f,0.21875f, +0.3125f,0.21875f, +0.320313f,0.21875f, +0.328125f,0.21875f, +0.335938f,0.21875f, +0.34375f,0.21875f, +0.351563f,0.21875f, +0.359375f,0.21875f, +0.367188f,0.21875f, +0.375f,0.21875f, +0.382813f,0.21875f, +0.390625f,0.21875f, +0.398438f,0.21875f, +0.40625f,0.21875f, +0.414063f,0.21875f, +0.421875f,0.21875f, +0.429688f,0.21875f, +0.4375f,0.21875f, +0.445313f,0.21875f, +0.453125f,0.21875f, +0.460938f,0.21875f, +0.46875f,0.21875f, +0.476563f,0.21875f, +0.484375f,0.21875f, +0.492188f,0.21875f, +0.5f,0.21875f, +0.507813f,0.21875f, +0.0f,0.226563f, +0.0078125f,0.226563f, +0.015625f,0.226563f, +0.0234375f,0.226563f, +0.03125f,0.226563f, +0.0390625f,0.226563f, +0.046875f,0.226563f, +0.0546875f,0.226563f, +0.0625f,0.226563f, +0.0703125f,0.226563f, +0.078125f,0.226563f, +0.0859375f,0.226563f, +0.09375f,0.226563f, +0.101563f,0.226563f, +0.109375f,0.226563f, +0.117188f,0.226563f, +0.125f,0.226563f, +0.132813f,0.226563f, +0.140625f,0.226563f, +0.148438f,0.226563f, +0.15625f,0.226563f, +0.164063f,0.226563f, +0.171875f,0.226563f, +0.179688f,0.226563f, +0.1875f,0.226563f, +0.195313f,0.226563f, +0.203125f,0.226563f, +0.210938f,0.226563f, +0.21875f,0.226563f, +0.226563f,0.226563f, +0.234375f,0.226563f, +0.242188f,0.226563f, +0.25f,0.226563f, +0.257813f,0.226563f, +0.265625f,0.226563f, +0.273438f,0.226563f, +0.28125f,0.226563f, +0.289063f,0.226563f, +0.296875f,0.226563f, +0.304688f,0.226563f, +0.3125f,0.226563f, +0.320313f,0.226563f, +0.328125f,0.226563f, +0.335938f,0.226563f, +0.34375f,0.226563f, +0.351563f,0.226563f, +0.359375f,0.226563f, +0.367188f,0.226563f, +0.375f,0.226563f, +0.382813f,0.226563f, +0.390625f,0.226563f, +0.398438f,0.226563f, +0.40625f,0.226563f, +0.414063f,0.226563f, +0.421875f,0.226563f, +0.429688f,0.226563f, +0.4375f,0.226563f, +0.445313f,0.226563f, +0.453125f,0.226563f, +0.460938f,0.226563f, +0.46875f,0.226563f, +0.476563f,0.226563f, +0.484375f,0.226563f, +0.492188f,0.226563f, +0.5f,0.226563f, +0.507813f,0.226563f, +0.0f,0.234375f, +0.0078125f,0.234375f, +0.015625f,0.234375f, +0.0234375f,0.234375f, +0.03125f,0.234375f, +0.0390625f,0.234375f, +0.046875f,0.234375f, +0.0546875f,0.234375f, +0.0625f,0.234375f, +0.0703125f,0.234375f, +0.078125f,0.234375f, +0.0859375f,0.234375f, +0.09375f,0.234375f, +0.101563f,0.234375f, +0.109375f,0.234375f, +0.117188f,0.234375f, +0.125f,0.234375f, +0.132813f,0.234375f, +0.140625f,0.234375f, +0.148438f,0.234375f, +0.15625f,0.234375f, +0.164063f,0.234375f, +0.171875f,0.234375f, +0.179688f,0.234375f, +0.1875f,0.234375f, +0.195313f,0.234375f, +0.203125f,0.234375f, +0.210938f,0.234375f, +0.21875f,0.234375f, +0.226563f,0.234375f, +0.234375f,0.234375f, +0.242188f,0.234375f, +0.25f,0.234375f, +0.257813f,0.234375f, +0.265625f,0.234375f, +0.273438f,0.234375f, +0.28125f,0.234375f, +0.289063f,0.234375f, +0.296875f,0.234375f, +0.304688f,0.234375f, +0.3125f,0.234375f, +0.320313f,0.234375f, +0.328125f,0.234375f, +0.335938f,0.234375f, +0.34375f,0.234375f, +0.351563f,0.234375f, +0.359375f,0.234375f, +0.367188f,0.234375f, +0.375f,0.234375f, +0.382813f,0.234375f, +0.390625f,0.234375f, +0.398438f,0.234375f, +0.40625f,0.234375f, +0.414063f,0.234375f, +0.421875f,0.234375f, +0.429688f,0.234375f, +0.4375f,0.234375f, +0.445313f,0.234375f, +0.453125f,0.234375f, +0.460938f,0.234375f, +0.46875f,0.234375f, +0.476563f,0.234375f, +0.484375f,0.234375f, +0.492188f,0.234375f, +0.5f,0.234375f, +0.507813f,0.234375f, +0.0f,0.242188f, +0.0078125f,0.242188f, +0.015625f,0.242188f, +0.0234375f,0.242188f, +0.03125f,0.242188f, +0.0390625f,0.242188f, +0.046875f,0.242188f, +0.0546875f,0.242188f, +0.0625f,0.242188f, +0.0703125f,0.242188f, +0.078125f,0.242188f, +0.0859375f,0.242188f, +0.09375f,0.242188f, +0.101563f,0.242188f, +0.109375f,0.242188f, +0.117188f,0.242188f, +0.125f,0.242188f, +0.132813f,0.242188f, +0.140625f,0.242188f, +0.148438f,0.242188f, +0.15625f,0.242188f, +0.164063f,0.242188f, +0.171875f,0.242188f, +0.179688f,0.242188f, +0.1875f,0.242188f, +0.195313f,0.242188f, +0.203125f,0.242188f, +0.210938f,0.242188f, +0.21875f,0.242188f, +0.226563f,0.242188f, +0.234375f,0.242188f, +0.242188f,0.242188f, +0.25f,0.242188f, +0.257813f,0.242188f, +0.265625f,0.242188f, +0.273438f,0.242188f, +0.28125f,0.242188f, +0.289063f,0.242188f, +0.296875f,0.242188f, +0.304688f,0.242188f, +0.3125f,0.242188f, +0.320313f,0.242188f, +0.328125f,0.242188f, +0.335938f,0.242188f, +0.34375f,0.242188f, +0.351563f,0.242188f, +0.359375f,0.242188f, +0.367188f,0.242188f, +0.375f,0.242188f, +0.382813f,0.242188f, +0.390625f,0.242188f, +0.398438f,0.242188f, +0.40625f,0.242188f, +0.414063f,0.242188f, +0.421875f,0.242188f, +0.429688f,0.242188f, +0.4375f,0.242188f, +0.445313f,0.242188f, +0.453125f,0.242188f, +0.460938f,0.242188f, +0.46875f,0.242188f, +0.476563f,0.242188f, +0.484375f,0.242188f, +0.492188f,0.242188f, +0.5f,0.242188f, +0.507813f,0.242188f, +0.0f,0.25f, +0.0078125f,0.25f, +0.015625f,0.25f, +0.0234375f,0.25f, +0.03125f,0.25f, +0.0390625f,0.25f, +0.046875f,0.25f, +0.0546875f,0.25f, +0.0625f,0.25f, +0.0703125f,0.25f, +0.078125f,0.25f, +0.0859375f,0.25f, +0.09375f,0.25f, +0.101563f,0.25f, +0.109375f,0.25f, +0.117188f,0.25f, +0.125f,0.25f, +0.132813f,0.25f, +0.140625f,0.25f, +0.148438f,0.25f, +0.15625f,0.25f, +0.164063f,0.25f, +0.171875f,0.25f, +0.179688f,0.25f, +0.1875f,0.25f, +0.195313f,0.25f, +0.203125f,0.25f, +0.210938f,0.25f, +0.21875f,0.25f, +0.226563f,0.25f, +0.234375f,0.25f, +0.242188f,0.25f, +0.25f,0.25f, +0.257813f,0.25f, +0.265625f,0.25f, +0.273438f,0.25f, +0.28125f,0.25f, +0.289063f,0.25f, +0.296875f,0.25f, +0.304688f,0.25f, +0.3125f,0.25f, +0.320313f,0.25f, +0.328125f,0.25f, +0.335938f,0.25f, +0.34375f,0.25f, +0.351563f,0.25f, +0.359375f,0.25f, +0.367188f,0.25f, +0.375f,0.25f, +0.382813f,0.25f, +0.390625f,0.25f, +0.398438f,0.25f, +0.40625f,0.25f, +0.414063f,0.25f, +0.421875f,0.25f, +0.429688f,0.25f, +0.4375f,0.25f, +0.445313f,0.25f, +0.453125f,0.25f, +0.460938f,0.25f, +0.46875f,0.25f, +0.476563f,0.25f, +0.484375f,0.25f, +0.492188f,0.25f, +0.5f,0.25f, +0.507813f,0.25f, +0.0f,0.257813f, +0.0078125f,0.257813f, +0.015625f,0.257813f, +0.0234375f,0.257813f, +0.03125f,0.257813f, +0.0390625f,0.257813f, +0.046875f,0.257813f, +0.0546875f,0.257813f, +0.0625f,0.257813f, +0.0703125f,0.257813f, +0.078125f,0.257813f, +0.0859375f,0.257813f, +0.09375f,0.257813f, +0.101563f,0.257813f, +0.109375f,0.257813f, +0.117188f,0.257813f, +0.125f,0.257813f, +0.132813f,0.257813f, +0.140625f,0.257813f, +0.148438f,0.257813f, +0.15625f,0.257813f, +0.164063f,0.257813f, +0.171875f,0.257813f, +0.179688f,0.257813f, +0.1875f,0.257813f, +0.195313f,0.257813f, +0.203125f,0.257813f, +0.210938f,0.257813f, +0.21875f,0.257813f, +0.226563f,0.257813f, +0.234375f,0.257813f, +0.242188f,0.257813f, +0.25f,0.257813f, +0.257813f,0.257813f, +0.265625f,0.257813f, +0.273438f,0.257813f, +0.28125f,0.257813f, +0.289063f,0.257813f, +0.296875f,0.257813f, +0.304688f,0.257813f, +0.3125f,0.257813f, +0.320313f,0.257813f, +0.328125f,0.257813f, +0.335938f,0.257813f, +0.34375f,0.257813f, +0.351563f,0.257813f, +0.359375f,0.257813f, +0.367188f,0.257813f, +0.375f,0.257813f, +0.382813f,0.257813f, +0.390625f,0.257813f, +0.398438f,0.257813f, +0.40625f,0.257813f, +0.414063f,0.257813f, +0.421875f,0.257813f, +0.429688f,0.257813f, +0.4375f,0.257813f, +0.445313f,0.257813f, +0.453125f,0.257813f, +0.460938f,0.257813f, +0.46875f,0.257813f, +0.476563f,0.257813f, +0.484375f,0.257813f, +0.492188f,0.257813f, +0.5f,0.257813f, +0.507813f,0.257813f, +0.0f,0.265625f, +0.0078125f,0.265625f, +0.015625f,0.265625f, +0.0234375f,0.265625f, +0.03125f,0.265625f, +0.0390625f,0.265625f, +0.046875f,0.265625f, +0.0546875f,0.265625f, +0.0625f,0.265625f, +0.0703125f,0.265625f, +0.078125f,0.265625f, +0.0859375f,0.265625f, +0.09375f,0.265625f, +0.101563f,0.265625f, +0.109375f,0.265625f, +0.117188f,0.265625f, +0.125f,0.265625f, +0.132813f,0.265625f, +0.140625f,0.265625f, +0.148438f,0.265625f, +0.15625f,0.265625f, +0.164063f,0.265625f, +0.171875f,0.265625f, +0.179688f,0.265625f, +0.1875f,0.265625f, +0.195313f,0.265625f, +0.203125f,0.265625f, +0.210938f,0.265625f, +0.21875f,0.265625f, +0.226563f,0.265625f, +0.234375f,0.265625f, +0.242188f,0.265625f, +0.25f,0.265625f, +0.257813f,0.265625f, +0.265625f,0.265625f, +0.273438f,0.265625f, +0.28125f,0.265625f, +0.289063f,0.265625f, +0.296875f,0.265625f, +0.304688f,0.265625f, +0.3125f,0.265625f, +0.320313f,0.265625f, +0.328125f,0.265625f, +0.335938f,0.265625f, +0.34375f,0.265625f, +0.351563f,0.265625f, +0.359375f,0.265625f, +0.367188f,0.265625f, +0.375f,0.265625f, +0.382813f,0.265625f, +0.390625f,0.265625f, +0.398438f,0.265625f, +0.40625f,0.265625f, +0.414063f,0.265625f, +0.421875f,0.265625f, +0.429688f,0.265625f, +0.4375f,0.265625f, +0.445313f,0.265625f, +0.453125f,0.265625f, +0.460938f,0.265625f, +0.46875f,0.265625f, +0.476563f,0.265625f, +0.484375f,0.265625f, +0.492188f,0.265625f, +0.5f,0.265625f, +0.507813f,0.265625f, +}; + +unsigned short Landscape06Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +126,127,128, +129,128,127, +128,129,130, +131,130,129, +132,0,133, +2,133,0, +133,2,134, +4,134,2, +134,4,135, +6,135,4, +135,6,136, +8,136,6, +136,8,137, +10,137,8, +137,10,138, +12,138,10, +138,12,139, +14,139,12, +139,14,140, +16,140,14, +140,16,141, +18,141,16, +141,18,142, +20,142,18, +142,20,143, +22,143,20, +143,22,144, +24,144,22, +144,24,145, +26,145,24, +145,26,146, +28,146,26, +146,28,147, +30,147,28, +147,30,148, +32,148,30, +148,32,149, +34,149,32, +149,34,150, +36,150,34, +150,36,151, +38,151,36, +151,38,152, +40,152,38, +152,40,153, +42,153,40, +153,42,154, +44,154,42, +154,44,155, +46,155,44, +155,46,156, +48,156,46, +156,48,157, +50,157,48, +157,50,158, +52,158,50, +158,52,159, +54,159,52, +159,54,160, +56,160,54, +160,56,161, +58,161,56, +161,58,162, +60,162,58, +162,60,163, +62,163,60, +163,62,164, +64,164,62, +164,64,165, +66,165,64, +165,66,166, +68,166,66, +166,68,167, +70,167,68, +167,70,168, +72,168,70, +168,72,169, +74,169,72, +169,74,170, +76,170,74, +170,76,171, +78,171,76, +171,78,172, +80,172,78, +172,80,173, +82,173,80, +173,82,174, +84,174,82, +174,84,175, +86,175,84, +175,86,176, +88,176,86, +176,88,177, +90,177,88, +177,90,178, +92,178,90, +178,92,179, +94,179,92, +179,94,180, +96,180,94, +180,96,181, +98,181,96, +181,98,182, +100,182,98, +182,100,183, +102,183,100, +183,102,184, +104,184,102, +184,104,185, +106,185,104, +185,106,186, +108,186,106, +186,108,187, +110,187,108, +187,110,188, +112,188,110, +188,112,189, +114,189,112, +189,114,190, +116,190,114, +190,116,191, +118,191,116, +191,118,192, +120,192,118, +192,120,193, +122,193,120, +193,122,194, +124,194,122, +194,124,195, +126,195,124, +195,126,196, +128,196,126, +196,128,197, +130,197,128, +198,132,199, +133,199,132, +199,133,200, +134,200,133, +200,134,201, +135,201,134, +201,135,202, +136,202,135, +202,136,203, +137,203,136, +203,137,204, +138,204,137, +204,138,205, +139,205,138, +205,139,206, +140,206,139, +206,140,207, +141,207,140, +207,141,208, +142,208,141, +208,142,209, +143,209,142, +209,143,210, +144,210,143, +210,144,211, +145,211,144, +211,145,212, +146,212,145, +212,146,213, +147,213,146, +213,147,214, +148,214,147, +214,148,215, +149,215,148, +215,149,216, +150,216,149, +216,150,217, +151,217,150, +217,151,218, +152,218,151, +218,152,219, +153,219,152, +219,153,220, +154,220,153, +220,154,221, +155,221,154, +221,155,222, +156,222,155, +222,156,223, +157,223,156, +223,157,224, +158,224,157, +224,158,225, +159,225,158, +225,159,226, +160,226,159, +226,160,227, +161,227,160, +227,161,228, +162,228,161, +228,162,229, +163,229,162, +229,163,230, +164,230,163, +230,164,231, +165,231,164, +231,165,232, +166,232,165, +232,166,233, +167,233,166, +233,167,234, +168,234,167, +234,168,235, +169,235,168, +235,169,236, +170,236,169, +236,170,237, +171,237,170, +237,171,238, +172,238,171, +238,172,239, +173,239,172, +239,173,240, +174,240,173, +240,174,241, +175,241,174, +241,175,242, +176,242,175, +242,176,243, +177,243,176, +243,177,244, +178,244,177, +244,178,245, +179,245,178, +245,179,246, +180,246,179, +246,180,247, +181,247,180, +247,181,248, +182,248,181, +248,182,249, +183,249,182, +249,183,250, +184,250,183, +250,184,251, +185,251,184, +251,185,252, +186,252,185, +252,186,253, +187,253,186, +253,187,254, +188,254,187, +254,188,255, +189,255,188, +255,189,256, +190,256,189, +256,190,257, +191,257,190, +257,191,258, +192,258,191, +258,192,259, +193,259,192, +259,193,260, +194,260,193, +260,194,261, +195,261,194, +261,195,262, +196,262,195, +262,196,263, +197,263,196, +264,198,265, +199,265,198, +265,199,266, +200,266,199, +266,200,267, +201,267,200, +267,201,268, +202,268,201, +268,202,269, +203,269,202, +269,203,270, +204,270,203, +270,204,271, +205,271,204, +271,205,272, +206,272,205, +272,206,273, +207,273,206, +273,207,274, +208,274,207, +274,208,275, +209,275,208, +275,209,276, +210,276,209, +276,210,277, +211,277,210, +277,211,278, +212,278,211, +278,212,279, +213,279,212, +279,213,280, +214,280,213, +280,214,281, +215,281,214, +281,215,282, +216,282,215, +282,216,283, +217,283,216, +283,217,284, +218,284,217, +284,218,285, +219,285,218, +285,219,286, +220,286,219, +286,220,287, +221,287,220, +287,221,288, +222,288,221, +288,222,289, +223,289,222, +289,223,290, +224,290,223, +290,224,291, +225,291,224, +291,225,292, +226,292,225, +292,226,293, +227,293,226, +293,227,294, +228,294,227, +294,228,295, +229,295,228, +295,229,296, +230,296,229, +296,230,297, +231,297,230, +297,231,298, +232,298,231, +298,232,299, +233,299,232, +299,233,300, +234,300,233, +300,234,301, +235,301,234, +301,235,302, +236,302,235, +302,236,303, +237,303,236, +303,237,304, +238,304,237, +304,238,305, +239,305,238, +305,239,306, +240,306,239, +306,240,307, +241,307,240, +307,241,308, +242,308,241, +308,242,309, +243,309,242, +309,243,310, +244,310,243, +310,244,311, +245,311,244, +311,245,312, +246,312,245, +312,246,313, +247,313,246, +313,247,314, +248,314,247, +314,248,315, +249,315,248, +315,249,316, +250,316,249, +316,250,317, +251,317,250, +317,251,318, +252,318,251, +318,252,319, +253,319,252, +319,253,320, +254,320,253, +320,254,321, +255,321,254, +321,255,322, +256,322,255, +322,256,323, +257,323,256, +323,257,324, +258,324,257, +324,258,325, +259,325,258, +325,259,326, +260,326,259, +326,260,327, +261,327,260, +327,261,328, +262,328,261, +328,262,329, +263,329,262, +330,264,331, +265,331,264, +331,265,332, +266,332,265, +332,266,333, +267,333,266, +333,267,334, +268,334,267, +334,268,335, +269,335,268, +335,269,336, +270,336,269, +336,270,337, +271,337,270, +337,271,338, +272,338,271, +338,272,339, +273,339,272, +339,273,340, +274,340,273, +340,274,341, +275,341,274, +341,275,342, +276,342,275, +342,276,343, +277,343,276, +343,277,344, +278,344,277, +344,278,345, +279,345,278, +345,279,346, +280,346,279, +346,280,347, +281,347,280, +347,281,348, +282,348,281, +348,282,349, +283,349,282, +349,283,350, +284,350,283, +350,284,351, +285,351,284, +351,285,352, +286,352,285, +352,286,353, +287,353,286, +353,287,354, +288,354,287, +354,288,355, +289,355,288, +355,289,356, +290,356,289, +356,290,357, +291,357,290, +357,291,358, +292,358,291, +358,292,359, +293,359,292, +359,293,360, +294,360,293, +360,294,361, +295,361,294, +361,295,362, +296,362,295, +362,296,363, +297,363,296, +363,297,364, +298,364,297, +364,298,365, +299,365,298, +365,299,366, +300,366,299, +366,300,367, +301,367,300, +367,301,368, +302,368,301, +368,302,369, +303,369,302, +369,303,370, +304,370,303, +370,304,371, +305,371,304, +371,305,372, +306,372,305, +372,306,373, +307,373,306, +373,307,374, +308,374,307, +374,308,375, +309,375,308, +375,309,376, +310,376,309, +376,310,377, +311,377,310, +377,311,378, +312,378,311, +378,312,379, +313,379,312, +379,313,380, +314,380,313, +380,314,381, +315,381,314, +381,315,382, +316,382,315, +382,316,383, +317,383,316, +383,317,384, +318,384,317, +384,318,385, +319,385,318, +385,319,386, +320,386,319, +386,320,387, +321,387,320, +387,321,388, +322,388,321, +388,322,389, +323,389,322, +389,323,390, +324,390,323, +390,324,391, +325,391,324, +391,325,392, +326,392,325, +392,326,393, +327,393,326, +393,327,394, +328,394,327, +394,328,395, +329,395,328, +396,330,397, +331,397,330, +397,331,398, +332,398,331, +398,332,399, +333,399,332, +399,333,400, +334,400,333, +400,334,401, +335,401,334, +401,335,402, +336,402,335, +402,336,403, +337,403,336, +403,337,404, +338,404,337, +404,338,405, +339,405,338, +405,339,406, +340,406,339, +406,340,407, +341,407,340, +407,341,408, +342,408,341, +408,342,409, +343,409,342, +409,343,410, +344,410,343, +410,344,411, +345,411,344, +411,345,412, +346,412,345, +412,346,413, +347,413,346, +413,347,414, +348,414,347, +414,348,415, +349,415,348, +415,349,416, +350,416,349, +416,350,417, +351,417,350, +417,351,418, +352,418,351, +418,352,419, +353,419,352, +419,353,420, +354,420,353, +420,354,421, +355,421,354, +421,355,422, +356,422,355, +422,356,423, +357,423,356, +423,357,424, +358,424,357, +424,358,425, +359,425,358, +425,359,426, +360,426,359, +426,360,427, +361,427,360, +427,361,428, +362,428,361, +428,362,429, +363,429,362, +429,363,430, +364,430,363, +430,364,431, +365,431,364, +431,365,432, +366,432,365, +432,366,433, +367,433,366, +433,367,434, +368,434,367, +434,368,435, +369,435,368, +435,369,436, +370,436,369, +436,370,437, +371,437,370, +437,371,438, +372,438,371, +438,372,439, +373,439,372, +439,373,440, +374,440,373, +440,374,441, +375,441,374, +441,375,442, +376,442,375, +442,376,443, +377,443,376, +443,377,444, +378,444,377, +444,378,445, +379,445,378, +445,379,446, +380,446,379, +446,380,447, +381,447,380, +447,381,448, +382,448,381, +448,382,449, +383,449,382, +449,383,450, +384,450,383, +450,384,451, +385,451,384, +451,385,452, +386,452,385, +452,386,453, +387,453,386, +453,387,454, +388,454,387, +454,388,455, +389,455,388, +455,389,456, +390,456,389, +456,390,457, +391,457,390, +457,391,458, +392,458,391, +458,392,459, +393,459,392, +459,393,460, +394,460,393, +460,394,461, +395,461,394, +462,396,463, +397,463,396, +463,397,464, +398,464,397, +464,398,465, +399,465,398, +465,399,466, +400,466,399, +466,400,467, +401,467,400, +467,401,468, +402,468,401, +468,402,469, +403,469,402, +469,403,470, +404,470,403, +470,404,471, +405,471,404, +471,405,472, +406,472,405, +472,406,473, +407,473,406, +473,407,474, +408,474,407, +474,408,475, +409,475,408, +475,409,476, +410,476,409, +476,410,477, +411,477,410, +477,411,478, +412,478,411, +478,412,479, +413,479,412, +479,413,480, +414,480,413, +480,414,481, +415,481,414, +481,415,482, +416,482,415, +482,416,483, +417,483,416, +483,417,484, +418,484,417, +484,418,485, +419,485,418, +485,419,486, +420,486,419, +486,420,487, +421,487,420, +487,421,488, +422,488,421, +488,422,489, +423,489,422, +489,423,490, +424,490,423, +490,424,491, +425,491,424, +491,425,492, +426,492,425, +492,426,493, +427,493,426, +493,427,494, +428,494,427, +494,428,495, +429,495,428, +495,429,496, +430,496,429, +496,430,497, +431,497,430, +497,431,498, +432,498,431, +498,432,499, +433,499,432, +499,433,500, +434,500,433, +500,434,501, +435,501,434, +501,435,502, +436,502,435, +502,436,503, +437,503,436, +503,437,504, +438,504,437, +504,438,505, +439,505,438, +505,439,506, +440,506,439, +506,440,507, +441,507,440, +507,441,508, +442,508,441, +508,442,509, +443,509,442, +509,443,510, +444,510,443, +510,444,511, +445,511,444, +511,445,512, +446,512,445, +512,446,513, +447,513,446, +513,447,514, +448,514,447, +514,448,515, +449,515,448, +515,449,516, +450,516,449, +516,450,517, +451,517,450, +517,451,518, +452,518,451, +518,452,519, +453,519,452, +519,453,520, +454,520,453, +520,454,521, +455,521,454, +521,455,522, +456,522,455, +522,456,523, +457,523,456, +523,457,524, +458,524,457, +524,458,525, +459,525,458, +525,459,526, +460,526,459, +526,460,527, +461,527,460, +528,462,529, +463,529,462, +529,463,530, +464,530,463, +530,464,531, +465,531,464, +531,465,532, +466,532,465, +532,466,533, +467,533,466, +533,467,534, +468,534,467, +534,468,535, +469,535,468, +535,469,536, +470,536,469, +536,470,537, +471,537,470, +537,471,538, +472,538,471, +538,472,539, +473,539,472, +539,473,540, +474,540,473, +540,474,541, +475,541,474, +541,475,542, +476,542,475, +542,476,543, +477,543,476, +543,477,544, +478,544,477, +544,478,545, +479,545,478, +545,479,546, +480,546,479, +546,480,547, +481,547,480, +547,481,548, +482,548,481, +548,482,549, +483,549,482, +549,483,550, +484,550,483, +550,484,551, +485,551,484, +551,485,552, +486,552,485, +552,486,553, +487,553,486, +553,487,554, +488,554,487, +554,488,555, +489,555,488, +555,489,556, +490,556,489, +556,490,557, +491,557,490, +557,491,558, +492,558,491, +558,492,559, +493,559,492, +559,493,560, +494,560,493, +560,494,561, +495,561,494, +561,495,562, +496,562,495, +562,496,563, +497,563,496, +563,497,564, +498,564,497, +564,498,565, +499,565,498, +565,499,566, +500,566,499, +566,500,567, +501,567,500, +567,501,568, +502,568,501, +568,502,569, +503,569,502, +569,503,570, +504,570,503, +570,504,571, +505,571,504, +571,505,572, +506,572,505, +572,506,573, +507,573,506, +573,507,574, +508,574,507, +574,508,575, +509,575,508, +575,509,576, +510,576,509, +576,510,577, +511,577,510, +577,511,578, +512,578,511, +578,512,579, +513,579,512, +579,513,580, +514,580,513, +580,514,581, +515,581,514, +581,515,582, +516,582,515, +582,516,583, +517,583,516, +583,517,584, +518,584,517, +584,518,585, +519,585,518, +585,519,586, +520,586,519, +586,520,587, +521,587,520, +587,521,588, +522,588,521, +588,522,589, +523,589,522, +589,523,590, +524,590,523, +590,524,591, +525,591,524, +591,525,592, +526,592,525, +592,526,593, +527,593,526, +594,528,595, +529,595,528, +595,529,596, +530,596,529, +596,530,597, +531,597,530, +597,531,598, +532,598,531, +598,532,599, +533,599,532, +599,533,600, +534,600,533, +600,534,601, +535,601,534, +601,535,602, +536,602,535, +602,536,603, +537,603,536, +603,537,604, +538,604,537, +604,538,605, +539,605,538, +605,539,606, +540,606,539, +606,540,607, +541,607,540, +607,541,608, +542,608,541, +608,542,609, +543,609,542, +609,543,610, +544,610,543, +610,544,611, +545,611,544, +611,545,612, +546,612,545, +612,546,613, +547,613,546, +613,547,614, +548,614,547, +614,548,615, +549,615,548, +615,549,616, +550,616,549, +616,550,617, +551,617,550, +617,551,618, +552,618,551, +618,552,619, +553,619,552, +619,553,620, +554,620,553, +620,554,621, +555,621,554, +621,555,622, +556,622,555, +622,556,623, +557,623,556, +623,557,624, +558,624,557, +624,558,625, +559,625,558, +625,559,626, +560,626,559, +626,560,627, +561,627,560, +627,561,628, +562,628,561, +628,562,629, +563,629,562, +629,563,630, +564,630,563, +630,564,631, +565,631,564, +631,565,632, +566,632,565, +632,566,633, +567,633,566, +633,567,634, +568,634,567, +634,568,635, +569,635,568, +635,569,636, +570,636,569, +636,570,637, +571,637,570, +637,571,638, +572,638,571, +638,572,639, +573,639,572, +639,573,640, +574,640,573, +640,574,641, +575,641,574, +641,575,642, +576,642,575, +642,576,643, +577,643,576, +643,577,644, +578,644,577, +644,578,645, +579,645,578, +645,579,646, +580,646,579, +646,580,647, +581,647,580, +647,581,648, +582,648,581, +648,582,649, +583,649,582, +649,583,650, +584,650,583, +650,584,651, +585,651,584, +651,585,652, +586,652,585, +652,586,653, +587,653,586, +653,587,654, +588,654,587, +654,588,655, +589,655,588, +655,589,656, +590,656,589, +656,590,657, +591,657,590, +657,591,658, +592,658,591, +658,592,659, +593,659,592, +660,594,661, +595,661,594, +661,595,662, +596,662,595, +662,596,663, +597,663,596, +663,597,664, +598,664,597, +664,598,665, +599,665,598, +665,599,666, +600,666,599, +666,600,667, +601,667,600, +667,601,668, +602,668,601, +668,602,669, +603,669,602, +669,603,670, +604,670,603, +670,604,671, +605,671,604, +671,605,672, +606,672,605, +672,606,673, +607,673,606, +673,607,674, +608,674,607, +674,608,675, +609,675,608, +675,609,676, +610,676,609, +676,610,677, +611,677,610, +677,611,678, +612,678,611, +678,612,679, +613,679,612, +679,613,680, +614,680,613, +680,614,681, +615,681,614, +681,615,682, +616,682,615, +682,616,683, +617,683,616, +683,617,684, +618,684,617, +684,618,685, +619,685,618, +685,619,686, +620,686,619, +686,620,687, +621,687,620, +687,621,688, +622,688,621, +688,622,689, +623,689,622, +689,623,690, +624,690,623, +690,624,691, +625,691,624, +691,625,692, +626,692,625, +692,626,693, +627,693,626, +693,627,694, +628,694,627, +694,628,695, +629,695,628, +695,629,696, +630,696,629, +696,630,697, +631,697,630, +697,631,698, +632,698,631, +698,632,699, +633,699,632, +699,633,700, +634,700,633, +700,634,701, +635,701,634, +701,635,702, +636,702,635, +702,636,703, +637,703,636, +703,637,704, +638,704,637, +704,638,705, +639,705,638, +705,639,706, +640,706,639, +706,640,707, +641,707,640, +707,641,708, +642,708,641, +708,642,709, +643,709,642, +709,643,710, +644,710,643, +710,644,711, +645,711,644, +711,645,712, +646,712,645, +712,646,713, +647,713,646, +713,647,714, +648,714,647, +714,648,715, +649,715,648, +715,649,716, +650,716,649, +716,650,717, +651,717,650, +717,651,718, +652,718,651, +718,652,719, +653,719,652, +719,653,720, +654,720,653, +720,654,721, +655,721,654, +721,655,722, +656,722,655, +722,656,723, +657,723,656, +723,657,724, +658,724,657, +724,658,725, +659,725,658, +726,660,727, +661,727,660, +727,661,728, +662,728,661, +728,662,729, +663,729,662, +729,663,730, +664,730,663, +730,664,731, +665,731,664, +731,665,732, +666,732,665, +732,666,733, +667,733,666, +733,667,734, +668,734,667, +734,668,735, +669,735,668, +735,669,736, +670,736,669, +736,670,737, +671,737,670, +737,671,738, +672,738,671, +738,672,739, +673,739,672, +739,673,740, +674,740,673, +740,674,741, +675,741,674, +741,675,742, +676,742,675, +742,676,743, +677,743,676, +743,677,744, +678,744,677, +744,678,745, +679,745,678, +745,679,746, +680,746,679, +746,680,747, +681,747,680, +747,681,748, +682,748,681, +748,682,749, +683,749,682, +749,683,750, +684,750,683, +750,684,751, +685,751,684, +751,685,752, +686,752,685, +752,686,753, +687,753,686, +753,687,754, +688,754,687, +754,688,755, +689,755,688, +755,689,756, +690,756,689, +756,690,757, +691,757,690, +757,691,758, +692,758,691, +758,692,759, +693,759,692, +759,693,760, +694,760,693, +760,694,761, +695,761,694, +761,695,762, +696,762,695, +762,696,763, +697,763,696, +763,697,764, +698,764,697, +764,698,765, +699,765,698, +765,699,766, +700,766,699, +766,700,767, +701,767,700, +767,701,768, +702,768,701, +768,702,769, +703,769,702, +769,703,770, +704,770,703, +770,704,771, +705,771,704, +771,705,772, +706,772,705, +772,706,773, +707,773,706, +773,707,774, +708,774,707, +774,708,775, +709,775,708, +775,709,776, +710,776,709, +776,710,777, +711,777,710, +777,711,778, +712,778,711, +778,712,779, +713,779,712, +779,713,780, +714,780,713, +780,714,781, +715,781,714, +781,715,782, +716,782,715, +782,716,783, +717,783,716, +783,717,784, +718,784,717, +784,718,785, +719,785,718, +785,719,786, +720,786,719, +786,720,787, +721,787,720, +787,721,788, +722,788,721, +788,722,789, +723,789,722, +789,723,790, +724,790,723, +790,724,791, +725,791,724, +792,726,793, +727,793,726, +793,727,794, +728,794,727, +794,728,795, +729,795,728, +795,729,796, +730,796,729, +796,730,797, +731,797,730, +797,731,798, +732,798,731, +798,732,799, +733,799,732, +799,733,800, +734,800,733, +800,734,801, +735,801,734, +801,735,802, +736,802,735, +802,736,803, +737,803,736, +803,737,804, +738,804,737, +804,738,805, +739,805,738, +805,739,806, +740,806,739, +806,740,807, +741,807,740, +807,741,808, +742,808,741, +808,742,809, +743,809,742, +809,743,810, +744,810,743, +810,744,811, +745,811,744, +811,745,812, +746,812,745, +812,746,813, +747,813,746, +813,747,814, +748,814,747, +814,748,815, +749,815,748, +815,749,816, +750,816,749, +816,750,817, +751,817,750, +817,751,818, +752,818,751, +818,752,819, +753,819,752, +819,753,820, +754,820,753, +820,754,821, +755,821,754, +821,755,822, +756,822,755, +822,756,823, +757,823,756, +823,757,824, +758,824,757, +824,758,825, +759,825,758, +825,759,826, +760,826,759, +826,760,827, +761,827,760, +827,761,828, +762,828,761, +828,762,829, +763,829,762, +829,763,830, +764,830,763, +830,764,831, +765,831,764, +831,765,832, +766,832,765, +832,766,833, +767,833,766, +833,767,834, +768,834,767, +834,768,835, +769,835,768, +835,769,836, +770,836,769, +836,770,837, +771,837,770, +837,771,838, +772,838,771, +838,772,839, +773,839,772, +839,773,840, +774,840,773, +840,774,841, +775,841,774, +841,775,842, +776,842,775, +842,776,843, +777,843,776, +843,777,844, +778,844,777, +844,778,845, +779,845,778, +845,779,846, +780,846,779, +846,780,847, +781,847,780, +847,781,848, +782,848,781, +848,782,849, +783,849,782, +849,783,850, +784,850,783, +850,784,851, +785,851,784, +851,785,852, +786,852,785, +852,786,853, +787,853,786, +853,787,854, +788,854,787, +854,788,855, +789,855,788, +855,789,856, +790,856,789, +856,790,857, +791,857,790, +858,792,859, +793,859,792, +859,793,860, +794,860,793, +860,794,861, +795,861,794, +861,795,862, +796,862,795, +862,796,863, +797,863,796, +863,797,864, +798,864,797, +864,798,865, +799,865,798, +865,799,866, +800,866,799, +866,800,867, +801,867,800, +867,801,868, +802,868,801, +868,802,869, +803,869,802, +869,803,870, +804,870,803, +870,804,871, +805,871,804, +871,805,872, +806,872,805, +872,806,873, +807,873,806, +873,807,874, +808,874,807, +874,808,875, +809,875,808, +875,809,876, +810,876,809, +876,810,877, +811,877,810, +877,811,878, +812,878,811, +878,812,879, +813,879,812, +879,813,880, +814,880,813, +880,814,881, +815,881,814, +881,815,882, +816,882,815, +882,816,883, +817,883,816, +883,817,884, +818,884,817, +884,818,885, +819,885,818, +885,819,886, +820,886,819, +886,820,887, +821,887,820, +887,821,888, +822,888,821, +888,822,889, +823,889,822, +889,823,890, +824,890,823, +890,824,891, +825,891,824, +891,825,892, +826,892,825, +892,826,893, +827,893,826, +893,827,894, +828,894,827, +894,828,895, +829,895,828, +895,829,896, +830,896,829, +896,830,897, +831,897,830, +897,831,898, +832,898,831, +898,832,899, +833,899,832, +899,833,900, +834,900,833, +900,834,901, +835,901,834, +901,835,902, +836,902,835, +902,836,903, +837,903,836, +903,837,904, +838,904,837, +904,838,905, +839,905,838, +905,839,906, +840,906,839, +906,840,907, +841,907,840, +907,841,908, +842,908,841, +908,842,909, +843,909,842, +909,843,910, +844,910,843, +910,844,911, +845,911,844, +911,845,912, +846,912,845, +912,846,913, +847,913,846, +913,847,914, +848,914,847, +914,848,915, +849,915,848, +915,849,916, +850,916,849, +916,850,917, +851,917,850, +917,851,918, +852,918,851, +918,852,919, +853,919,852, +919,853,920, +854,920,853, +920,854,921, +855,921,854, +921,855,922, +856,922,855, +922,856,923, +857,923,856, +924,858,925, +859,925,858, +925,859,926, +860,926,859, +926,860,927, +861,927,860, +927,861,928, +862,928,861, +928,862,929, +863,929,862, +929,863,930, +864,930,863, +930,864,931, +865,931,864, +931,865,932, +866,932,865, +932,866,933, +867,933,866, +933,867,934, +868,934,867, +934,868,935, +869,935,868, +935,869,936, +870,936,869, +936,870,937, +871,937,870, +937,871,938, +872,938,871, +938,872,939, +873,939,872, +939,873,940, +874,940,873, +940,874,941, +875,941,874, +941,875,942, +876,942,875, +942,876,943, +877,943,876, +943,877,944, +878,944,877, +944,878,945, +879,945,878, +945,879,946, +880,946,879, +946,880,947, +881,947,880, +947,881,948, +882,948,881, +948,882,949, +883,949,882, +949,883,950, +884,950,883, +950,884,951, +885,951,884, +951,885,952, +886,952,885, +952,886,953, +887,953,886, +953,887,954, +888,954,887, +954,888,955, +889,955,888, +955,889,956, +890,956,889, +956,890,957, +891,957,890, +957,891,958, +892,958,891, +958,892,959, +893,959,892, +959,893,960, +894,960,893, +960,894,961, +895,961,894, +961,895,962, +896,962,895, +962,896,963, +897,963,896, +963,897,964, +898,964,897, +964,898,965, +899,965,898, +965,899,966, +900,966,899, +966,900,967, +901,967,900, +967,901,968, +902,968,901, +968,902,969, +903,969,902, +969,903,970, +904,970,903, +970,904,971, +905,971,904, +971,905,972, +906,972,905, +972,906,973, +907,973,906, +973,907,974, +908,974,907, +974,908,975, +909,975,908, +975,909,976, +910,976,909, +976,910,977, +911,977,910, +977,911,978, +912,978,911, +978,912,979, +913,979,912, +979,913,980, +914,980,913, +980,914,981, +915,981,914, +981,915,982, +916,982,915, +982,916,983, +917,983,916, +983,917,984, +918,984,917, +984,918,985, +919,985,918, +985,919,986, +920,986,919, +986,920,987, +921,987,920, +987,921,988, +922,988,921, +988,922,989, +923,989,922, +990,924,991, +925,991,924, +991,925,992, +926,992,925, +992,926,993, +927,993,926, +993,927,994, +928,994,927, +994,928,995, +929,995,928, +995,929,996, +930,996,929, +996,930,997, +931,997,930, +997,931,998, +932,998,931, +998,932,999, +933,999,932, +999,933,1000, +934,1000,933, +1000,934,1001, +935,1001,934, +1001,935,1002, +936,1002,935, +1002,936,1003, +937,1003,936, +1003,937,1004, +938,1004,937, +1004,938,1005, +939,1005,938, +1005,939,1006, +940,1006,939, +1006,940,1007, +941,1007,940, +1007,941,1008, +942,1008,941, +1008,942,1009, +943,1009,942, +1009,943,1010, +944,1010,943, +1010,944,1011, +945,1011,944, +1011,945,1012, +946,1012,945, +1012,946,1013, +947,1013,946, +1013,947,1014, +948,1014,947, +1014,948,1015, +949,1015,948, +1015,949,1016, +950,1016,949, +1016,950,1017, +951,1017,950, +1017,951,1018, +952,1018,951, +1018,952,1019, +953,1019,952, +1019,953,1020, +954,1020,953, +1020,954,1021, +955,1021,954, +1021,955,1022, +956,1022,955, +1022,956,1023, +957,1023,956, +1023,957,1024, +958,1024,957, +1024,958,1025, +959,1025,958, +1025,959,1026, +960,1026,959, +1026,960,1027, +961,1027,960, +1027,961,1028, +962,1028,961, +1028,962,1029, +963,1029,962, +1029,963,1030, +964,1030,963, +1030,964,1031, +965,1031,964, +1031,965,1032, +966,1032,965, +1032,966,1033, +967,1033,966, +1033,967,1034, +968,1034,967, +1034,968,1035, +969,1035,968, +1035,969,1036, +970,1036,969, +1036,970,1037, +971,1037,970, +1037,971,1038, +972,1038,971, +1038,972,1039, +973,1039,972, +1039,973,1040, +974,1040,973, +1040,974,1041, +975,1041,974, +1041,975,1042, +976,1042,975, +1042,976,1043, +977,1043,976, +1043,977,1044, +978,1044,977, +1044,978,1045, +979,1045,978, +1045,979,1046, +980,1046,979, +1046,980,1047, +981,1047,980, +1047,981,1048, +982,1048,981, +1048,982,1049, +983,1049,982, +1049,983,1050, +984,1050,983, +1050,984,1051, +985,1051,984, +1051,985,1052, +986,1052,985, +1052,986,1053, +987,1053,986, +1053,987,1054, +988,1054,987, +1054,988,1055, +989,1055,988, +1056,990,1057, +991,1057,990, +1057,991,1058, +992,1058,991, +1058,992,1059, +993,1059,992, +1059,993,1060, +994,1060,993, +1060,994,1061, +995,1061,994, +1061,995,1062, +996,1062,995, +1062,996,1063, +997,1063,996, +1063,997,1064, +998,1064,997, +1064,998,1065, +999,1065,998, +1065,999,1066, +1000,1066,999, +1066,1000,1067, +1001,1067,1000, +1067,1001,1068, +1002,1068,1001, +1068,1002,1069, +1003,1069,1002, +1069,1003,1070, +1004,1070,1003, +1070,1004,1071, +1005,1071,1004, +1071,1005,1072, +1006,1072,1005, +1072,1006,1073, +1007,1073,1006, +1073,1007,1074, +1008,1074,1007, +1074,1008,1075, +1009,1075,1008, +1075,1009,1076, +1010,1076,1009, +1076,1010,1077, +1011,1077,1010, +1077,1011,1078, +1012,1078,1011, +1078,1012,1079, +1013,1079,1012, +1079,1013,1080, +1014,1080,1013, +1080,1014,1081, +1015,1081,1014, +1081,1015,1082, +1016,1082,1015, +1082,1016,1083, +1017,1083,1016, +1083,1017,1084, +1018,1084,1017, +1084,1018,1085, +1019,1085,1018, +1085,1019,1086, +1020,1086,1019, +1086,1020,1087, +1021,1087,1020, +1087,1021,1088, +1022,1088,1021, +1088,1022,1089, +1023,1089,1022, +1089,1023,1090, +1024,1090,1023, +1090,1024,1091, +1025,1091,1024, +1091,1025,1092, +1026,1092,1025, +1092,1026,1093, +1027,1093,1026, +1093,1027,1094, +1028,1094,1027, +1094,1028,1095, +1029,1095,1028, +1095,1029,1096, +1030,1096,1029, +1096,1030,1097, +1031,1097,1030, +1097,1031,1098, +1032,1098,1031, +1098,1032,1099, +1033,1099,1032, +1099,1033,1100, +1034,1100,1033, +1100,1034,1101, +1035,1101,1034, +1101,1035,1102, +1036,1102,1035, +1102,1036,1103, +1037,1103,1036, +1103,1037,1104, +1038,1104,1037, +1104,1038,1105, +1039,1105,1038, +1105,1039,1106, +1040,1106,1039, +1106,1040,1107, +1041,1107,1040, +1107,1041,1108, +1042,1108,1041, +1108,1042,1109, +1043,1109,1042, +1109,1043,1110, +1044,1110,1043, +1110,1044,1111, +1045,1111,1044, +1111,1045,1112, +1046,1112,1045, +1112,1046,1113, +1047,1113,1046, +1113,1047,1114, +1048,1114,1047, +1114,1048,1115, +1049,1115,1048, +1115,1049,1116, +1050,1116,1049, +1116,1050,1117, +1051,1117,1050, +1117,1051,1118, +1052,1118,1051, +1118,1052,1119, +1053,1119,1052, +1119,1053,1120, +1054,1120,1053, +1120,1054,1121, +1055,1121,1054, +1122,1056,1123, +1057,1123,1056, +1123,1057,1124, +1058,1124,1057, +1124,1058,1125, +1059,1125,1058, +1125,1059,1126, +1060,1126,1059, +1126,1060,1127, +1061,1127,1060, +1127,1061,1128, +1062,1128,1061, +1128,1062,1129, +1063,1129,1062, +1129,1063,1130, +1064,1130,1063, +1130,1064,1131, +1065,1131,1064, +1131,1065,1132, +1066,1132,1065, +1132,1066,1133, +1067,1133,1066, +1133,1067,1134, +1068,1134,1067, +1134,1068,1135, +1069,1135,1068, +1135,1069,1136, +1070,1136,1069, +1136,1070,1137, +1071,1137,1070, +1137,1071,1138, +1072,1138,1071, +1138,1072,1139, +1073,1139,1072, +1139,1073,1140, +1074,1140,1073, +1140,1074,1141, +1075,1141,1074, +1141,1075,1142, +1076,1142,1075, +1142,1076,1143, +1077,1143,1076, +1143,1077,1144, +1078,1144,1077, +1144,1078,1145, +1079,1145,1078, +1145,1079,1146, +1080,1146,1079, +1146,1080,1147, +1081,1147,1080, +1147,1081,1148, +1082,1148,1081, +1148,1082,1149, +1083,1149,1082, +1149,1083,1150, +1084,1150,1083, +1150,1084,1151, +1085,1151,1084, +1151,1085,1152, +1086,1152,1085, +1152,1086,1153, +1087,1153,1086, +1153,1087,1154, +1088,1154,1087, +1154,1088,1155, +1089,1155,1088, +1155,1089,1156, +1090,1156,1089, +1156,1090,1157, +1091,1157,1090, +1157,1091,1158, +1092,1158,1091, +1158,1092,1159, +1093,1159,1092, +1159,1093,1160, +1094,1160,1093, +1160,1094,1161, +1095,1161,1094, +1161,1095,1162, +1096,1162,1095, +1162,1096,1163, +1097,1163,1096, +1163,1097,1164, +1098,1164,1097, +1164,1098,1165, +1099,1165,1098, +1165,1099,1166, +1100,1166,1099, +1166,1100,1167, +1101,1167,1100, +1167,1101,1168, +1102,1168,1101, +1168,1102,1169, +1103,1169,1102, +1169,1103,1170, +1104,1170,1103, +1170,1104,1171, +1105,1171,1104, +1171,1105,1172, +1106,1172,1105, +1172,1106,1173, +1107,1173,1106, +1173,1107,1174, +1108,1174,1107, +1174,1108,1175, +1109,1175,1108, +1175,1109,1176, +1110,1176,1109, +1176,1110,1177, +1111,1177,1110, +1177,1111,1178, +1112,1178,1111, +1178,1112,1179, +1113,1179,1112, +1179,1113,1180, +1114,1180,1113, +1180,1114,1181, +1115,1181,1114, +1181,1115,1182, +1116,1182,1115, +1182,1116,1183, +1117,1183,1116, +1183,1117,1184, +1118,1184,1117, +1184,1118,1185, +1119,1185,1118, +1185,1119,1186, +1120,1186,1119, +1186,1120,1187, +1121,1187,1120, +1188,1122,1189, +1123,1189,1122, +1189,1123,1190, +1124,1190,1123, +1190,1124,1191, +1125,1191,1124, +1191,1125,1192, +1126,1192,1125, +1192,1126,1193, +1127,1193,1126, +1193,1127,1194, +1128,1194,1127, +1194,1128,1195, +1129,1195,1128, +1195,1129,1196, +1130,1196,1129, +1196,1130,1197, +1131,1197,1130, +1197,1131,1198, +1132,1198,1131, +1198,1132,1199, +1133,1199,1132, +1199,1133,1200, +1134,1200,1133, +1200,1134,1201, +1135,1201,1134, +1201,1135,1202, +1136,1202,1135, +1202,1136,1203, +1137,1203,1136, +1203,1137,1204, +1138,1204,1137, +1204,1138,1205, +1139,1205,1138, +1205,1139,1206, +1140,1206,1139, +1206,1140,1207, +1141,1207,1140, +1207,1141,1208, +1142,1208,1141, +1208,1142,1209, +1143,1209,1142, +1209,1143,1210, +1144,1210,1143, +1210,1144,1211, +1145,1211,1144, +1211,1145,1212, +1146,1212,1145, +1212,1146,1213, +1147,1213,1146, +1213,1147,1214, +1148,1214,1147, +1214,1148,1215, +1149,1215,1148, +1215,1149,1216, +1150,1216,1149, +1216,1150,1217, +1151,1217,1150, +1217,1151,1218, +1152,1218,1151, +1218,1152,1219, +1153,1219,1152, +1219,1153,1220, +1154,1220,1153, +1220,1154,1221, +1155,1221,1154, +1221,1155,1222, +1156,1222,1155, +1222,1156,1223, +1157,1223,1156, +1223,1157,1224, +1158,1224,1157, +1224,1158,1225, +1159,1225,1158, +1225,1159,1226, +1160,1226,1159, +1226,1160,1227, +1161,1227,1160, +1227,1161,1228, +1162,1228,1161, +1228,1162,1229, +1163,1229,1162, +1229,1163,1230, +1164,1230,1163, +1230,1164,1231, +1165,1231,1164, +1231,1165,1232, +1166,1232,1165, +1232,1166,1233, +1167,1233,1166, +1233,1167,1234, +1168,1234,1167, +1234,1168,1235, +1169,1235,1168, +1235,1169,1236, +1170,1236,1169, +1236,1170,1237, +1171,1237,1170, +1237,1171,1238, +1172,1238,1171, +1238,1172,1239, +1173,1239,1172, +1239,1173,1240, +1174,1240,1173, +1240,1174,1241, +1175,1241,1174, +1241,1175,1242, +1176,1242,1175, +1242,1176,1243, +1177,1243,1176, +1243,1177,1244, +1178,1244,1177, +1244,1178,1245, +1179,1245,1178, +1245,1179,1246, +1180,1246,1179, +1246,1180,1247, +1181,1247,1180, +1247,1181,1248, +1182,1248,1181, +1248,1182,1249, +1183,1249,1182, +1249,1183,1250, +1184,1250,1183, +1250,1184,1251, +1185,1251,1184, +1251,1185,1252, +1186,1252,1185, +1252,1186,1253, +1187,1253,1186, +1254,1188,1255, +1189,1255,1188, +1255,1189,1256, +1190,1256,1189, +1256,1190,1257, +1191,1257,1190, +1257,1191,1258, +1192,1258,1191, +1258,1192,1259, +1193,1259,1192, +1259,1193,1260, +1194,1260,1193, +1260,1194,1261, +1195,1261,1194, +1261,1195,1262, +1196,1262,1195, +1262,1196,1263, +1197,1263,1196, +1263,1197,1264, +1198,1264,1197, +1264,1198,1265, +1199,1265,1198, +1265,1199,1266, +1200,1266,1199, +1266,1200,1267, +1201,1267,1200, +1267,1201,1268, +1202,1268,1201, +1268,1202,1269, +1203,1269,1202, +1269,1203,1270, +1204,1270,1203, +1270,1204,1271, +1205,1271,1204, +1271,1205,1272, +1206,1272,1205, +1272,1206,1273, +1207,1273,1206, +1273,1207,1274, +1208,1274,1207, +1274,1208,1275, +1209,1275,1208, +1275,1209,1276, +1210,1276,1209, +1276,1210,1277, +1211,1277,1210, +1277,1211,1278, +1212,1278,1211, +1278,1212,1279, +1213,1279,1212, +1279,1213,1280, +1214,1280,1213, +1280,1214,1281, +1215,1281,1214, +1281,1215,1282, +1216,1282,1215, +1282,1216,1283, +1217,1283,1216, +1283,1217,1284, +1218,1284,1217, +1284,1218,1285, +1219,1285,1218, +1285,1219,1286, +1220,1286,1219, +1286,1220,1287, +1221,1287,1220, +1287,1221,1288, +1222,1288,1221, +1288,1222,1289, +1223,1289,1222, +1289,1223,1290, +1224,1290,1223, +1290,1224,1291, +1225,1291,1224, +1291,1225,1292, +1226,1292,1225, +1292,1226,1293, +1227,1293,1226, +1293,1227,1294, +1228,1294,1227, +1294,1228,1295, +1229,1295,1228, +1295,1229,1296, +1230,1296,1229, +1296,1230,1297, +1231,1297,1230, +1297,1231,1298, +1232,1298,1231, +1298,1232,1299, +1233,1299,1232, +1299,1233,1300, +1234,1300,1233, +1300,1234,1301, +1235,1301,1234, +1301,1235,1302, +1236,1302,1235, +1302,1236,1303, +1237,1303,1236, +1303,1237,1304, +1238,1304,1237, +1304,1238,1305, +1239,1305,1238, +1305,1239,1306, +1240,1306,1239, +1306,1240,1307, +1241,1307,1240, +1307,1241,1308, +1242,1308,1241, +1308,1242,1309, +1243,1309,1242, +1309,1243,1310, +1244,1310,1243, +1310,1244,1311, +1245,1311,1244, +1311,1245,1312, +1246,1312,1245, +1312,1246,1313, +1247,1313,1246, +1313,1247,1314, +1248,1314,1247, +1314,1248,1315, +1249,1315,1248, +1315,1249,1316, +1250,1316,1249, +1316,1250,1317, +1251,1317,1250, +1317,1251,1318, +1252,1318,1251, +1318,1252,1319, +1253,1319,1252, +1320,1254,1321, +1255,1321,1254, +1321,1255,1322, +1256,1322,1255, +1322,1256,1323, +1257,1323,1256, +1323,1257,1324, +1258,1324,1257, +1324,1258,1325, +1259,1325,1258, +1325,1259,1326, +1260,1326,1259, +1326,1260,1327, +1261,1327,1260, +1327,1261,1328, +1262,1328,1261, +1328,1262,1329, +1263,1329,1262, +1329,1263,1330, +1264,1330,1263, +1330,1264,1331, +1265,1331,1264, +1331,1265,1332, +1266,1332,1265, +1332,1266,1333, +1267,1333,1266, +1333,1267,1334, +1268,1334,1267, +1334,1268,1335, +1269,1335,1268, +1335,1269,1336, +1270,1336,1269, +1336,1270,1337, +1271,1337,1270, +1337,1271,1338, +1272,1338,1271, +1338,1272,1339, +1273,1339,1272, +1339,1273,1340, +1274,1340,1273, +1340,1274,1341, +1275,1341,1274, +1341,1275,1342, +1276,1342,1275, +1342,1276,1343, +1277,1343,1276, +1343,1277,1344, +1278,1344,1277, +1344,1278,1345, +1279,1345,1278, +1345,1279,1346, +1280,1346,1279, +1346,1280,1347, +1281,1347,1280, +1347,1281,1348, +1282,1348,1281, +1348,1282,1349, +1283,1349,1282, +1349,1283,1350, +1284,1350,1283, +1350,1284,1351, +1285,1351,1284, +1351,1285,1352, +1286,1352,1285, +1352,1286,1353, +1287,1353,1286, +1353,1287,1354, +1288,1354,1287, +1354,1288,1355, +1289,1355,1288, +1355,1289,1356, +1290,1356,1289, +1356,1290,1357, +1291,1357,1290, +1357,1291,1358, +1292,1358,1291, +1358,1292,1359, +1293,1359,1292, +1359,1293,1360, +1294,1360,1293, +1360,1294,1361, +1295,1361,1294, +1361,1295,1362, +1296,1362,1295, +1362,1296,1363, +1297,1363,1296, +1363,1297,1364, +1298,1364,1297, +1364,1298,1365, +1299,1365,1298, +1365,1299,1366, +1300,1366,1299, +1366,1300,1367, +1301,1367,1300, +1367,1301,1368, +1302,1368,1301, +1368,1302,1369, +1303,1369,1302, +1369,1303,1370, +1304,1370,1303, +1370,1304,1371, +1305,1371,1304, +1371,1305,1372, +1306,1372,1305, +1372,1306,1373, +1307,1373,1306, +1373,1307,1374, +1308,1374,1307, +1374,1308,1375, +1309,1375,1308, +1375,1309,1376, +1310,1376,1309, +1376,1310,1377, +1311,1377,1310, +1377,1311,1378, +1312,1378,1311, +1378,1312,1379, +1313,1379,1312, +1379,1313,1380, +1314,1380,1313, +1380,1314,1381, +1315,1381,1314, +1381,1315,1382, +1316,1382,1315, +1382,1316,1383, +1317,1383,1316, +1383,1317,1384, +1318,1384,1317, +1384,1318,1385, +1319,1385,1318, +1386,1320,1387, +1321,1387,1320, +1387,1321,1388, +1322,1388,1321, +1388,1322,1389, +1323,1389,1322, +1389,1323,1390, +1324,1390,1323, +1390,1324,1391, +1325,1391,1324, +1391,1325,1392, +1326,1392,1325, +1392,1326,1393, +1327,1393,1326, +1393,1327,1394, +1328,1394,1327, +1394,1328,1395, +1329,1395,1328, +1395,1329,1396, +1330,1396,1329, +1396,1330,1397, +1331,1397,1330, +1397,1331,1398, +1332,1398,1331, +1398,1332,1399, +1333,1399,1332, +1399,1333,1400, +1334,1400,1333, +1400,1334,1401, +1335,1401,1334, +1401,1335,1402, +1336,1402,1335, +1402,1336,1403, +1337,1403,1336, +1403,1337,1404, +1338,1404,1337, +1404,1338,1405, +1339,1405,1338, +1405,1339,1406, +1340,1406,1339, +1406,1340,1407, +1341,1407,1340, +1407,1341,1408, +1342,1408,1341, +1408,1342,1409, +1343,1409,1342, +1409,1343,1410, +1344,1410,1343, +1410,1344,1411, +1345,1411,1344, +1411,1345,1412, +1346,1412,1345, +1412,1346,1413, +1347,1413,1346, +1413,1347,1414, +1348,1414,1347, +1414,1348,1415, +1349,1415,1348, +1415,1349,1416, +1350,1416,1349, +1416,1350,1417, +1351,1417,1350, +1417,1351,1418, +1352,1418,1351, +1418,1352,1419, +1353,1419,1352, +1419,1353,1420, +1354,1420,1353, +1420,1354,1421, +1355,1421,1354, +1421,1355,1422, +1356,1422,1355, +1422,1356,1423, +1357,1423,1356, +1423,1357,1424, +1358,1424,1357, +1424,1358,1425, +1359,1425,1358, +1425,1359,1426, +1360,1426,1359, +1426,1360,1427, +1361,1427,1360, +1427,1361,1428, +1362,1428,1361, +1428,1362,1429, +1363,1429,1362, +1429,1363,1430, +1364,1430,1363, +1430,1364,1431, +1365,1431,1364, +1431,1365,1432, +1366,1432,1365, +1432,1366,1433, +1367,1433,1366, +1433,1367,1434, +1368,1434,1367, +1434,1368,1435, +1369,1435,1368, +1435,1369,1436, +1370,1436,1369, +1436,1370,1437, +1371,1437,1370, +1437,1371,1438, +1372,1438,1371, +1438,1372,1439, +1373,1439,1372, +1439,1373,1440, +1374,1440,1373, +1440,1374,1441, +1375,1441,1374, +1441,1375,1442, +1376,1442,1375, +1442,1376,1443, +1377,1443,1376, +1443,1377,1444, +1378,1444,1377, +1444,1378,1445, +1379,1445,1378, +1445,1379,1446, +1380,1446,1379, +1446,1380,1447, +1381,1447,1380, +1447,1381,1448, +1382,1448,1381, +1448,1382,1449, +1383,1449,1382, +1449,1383,1450, +1384,1450,1383, +1450,1384,1451, +1385,1451,1384, +1452,1386,1453, +1387,1453,1386, +1453,1387,1454, +1388,1454,1387, +1454,1388,1455, +1389,1455,1388, +1455,1389,1456, +1390,1456,1389, +1456,1390,1457, +1391,1457,1390, +1457,1391,1458, +1392,1458,1391, +1458,1392,1459, +1393,1459,1392, +1459,1393,1460, +1394,1460,1393, +1460,1394,1461, +1395,1461,1394, +1461,1395,1462, +1396,1462,1395, +1462,1396,1463, +1397,1463,1396, +1463,1397,1464, +1398,1464,1397, +1464,1398,1465, +1399,1465,1398, +1465,1399,1466, +1400,1466,1399, +1466,1400,1467, +1401,1467,1400, +1467,1401,1468, +1402,1468,1401, +1468,1402,1469, +1403,1469,1402, +1469,1403,1470, +1404,1470,1403, +1470,1404,1471, +1405,1471,1404, +1471,1405,1472, +1406,1472,1405, +1472,1406,1473, +1407,1473,1406, +1473,1407,1474, +1408,1474,1407, +1474,1408,1475, +1409,1475,1408, +1475,1409,1476, +1410,1476,1409, +1476,1410,1477, +1411,1477,1410, +1477,1411,1478, +1412,1478,1411, +1478,1412,1479, +1413,1479,1412, +1479,1413,1480, +1414,1480,1413, +1480,1414,1481, +1415,1481,1414, +1481,1415,1482, +1416,1482,1415, +1482,1416,1483, +1417,1483,1416, +1483,1417,1484, +1418,1484,1417, +1484,1418,1485, +1419,1485,1418, +1485,1419,1486, +1420,1486,1419, +1486,1420,1487, +1421,1487,1420, +1487,1421,1488, +1422,1488,1421, +1488,1422,1489, +1423,1489,1422, +1489,1423,1490, +1424,1490,1423, +1490,1424,1491, +1425,1491,1424, +1491,1425,1492, +1426,1492,1425, +1492,1426,1493, +1427,1493,1426, +1493,1427,1494, +1428,1494,1427, +1494,1428,1495, +1429,1495,1428, +1495,1429,1496, +1430,1496,1429, +1496,1430,1497, +1431,1497,1430, +1497,1431,1498, +1432,1498,1431, +1498,1432,1499, +1433,1499,1432, +1499,1433,1500, +1434,1500,1433, +1500,1434,1501, +1435,1501,1434, +1501,1435,1502, +1436,1502,1435, +1502,1436,1503, +1437,1503,1436, +1503,1437,1504, +1438,1504,1437, +1504,1438,1505, +1439,1505,1438, +1505,1439,1506, +1440,1506,1439, +1506,1440,1507, +1441,1507,1440, +1507,1441,1508, +1442,1508,1441, +1508,1442,1509, +1443,1509,1442, +1509,1443,1510, +1444,1510,1443, +1510,1444,1511, +1445,1511,1444, +1511,1445,1512, +1446,1512,1445, +1512,1446,1513, +1447,1513,1446, +1513,1447,1514, +1448,1514,1447, +1514,1448,1515, +1449,1515,1448, +1515,1449,1516, +1450,1516,1449, +1516,1450,1517, +1451,1517,1450, +1518,1452,1519, +1453,1519,1452, +1519,1453,1520, +1454,1520,1453, +1520,1454,1521, +1455,1521,1454, +1521,1455,1522, +1456,1522,1455, +1522,1456,1523, +1457,1523,1456, +1523,1457,1524, +1458,1524,1457, +1524,1458,1525, +1459,1525,1458, +1525,1459,1526, +1460,1526,1459, +1526,1460,1527, +1461,1527,1460, +1527,1461,1528, +1462,1528,1461, +1528,1462,1529, +1463,1529,1462, +1529,1463,1530, +1464,1530,1463, +1530,1464,1531, +1465,1531,1464, +1531,1465,1532, +1466,1532,1465, +1532,1466,1533, +1467,1533,1466, +1533,1467,1534, +1468,1534,1467, +1534,1468,1535, +1469,1535,1468, +1535,1469,1536, +1470,1536,1469, +1536,1470,1537, +1471,1537,1470, +1537,1471,1538, +1472,1538,1471, +1538,1472,1539, +1473,1539,1472, +1539,1473,1540, +1474,1540,1473, +1540,1474,1541, +1475,1541,1474, +1541,1475,1542, +1476,1542,1475, +1542,1476,1543, +1477,1543,1476, +1543,1477,1544, +1478,1544,1477, +1544,1478,1545, +1479,1545,1478, +1545,1479,1546, +1480,1546,1479, +1546,1480,1547, +1481,1547,1480, +1547,1481,1548, +1482,1548,1481, +1548,1482,1549, +1483,1549,1482, +1549,1483,1550, +1484,1550,1483, +1550,1484,1551, +1485,1551,1484, +1551,1485,1552, +1486,1552,1485, +1552,1486,1553, +1487,1553,1486, +1553,1487,1554, +1488,1554,1487, +1554,1488,1555, +1489,1555,1488, +1555,1489,1556, +1490,1556,1489, +1556,1490,1557, +1491,1557,1490, +1557,1491,1558, +1492,1558,1491, +1558,1492,1559, +1493,1559,1492, +1559,1493,1560, +1494,1560,1493, +1560,1494,1561, +1495,1561,1494, +1561,1495,1562, +1496,1562,1495, +1562,1496,1563, +1497,1563,1496, +1563,1497,1564, +1498,1564,1497, +1564,1498,1565, +1499,1565,1498, +1565,1499,1566, +1500,1566,1499, +1566,1500,1567, +1501,1567,1500, +1567,1501,1568, +1502,1568,1501, +1568,1502,1569, +1503,1569,1502, +1569,1503,1570, +1504,1570,1503, +1570,1504,1571, +1505,1571,1504, +1571,1505,1572, +1506,1572,1505, +1572,1506,1573, +1507,1573,1506, +1573,1507,1574, +1508,1574,1507, +1574,1508,1575, +1509,1575,1508, +1575,1509,1576, +1510,1576,1509, +1576,1510,1577, +1511,1577,1510, +1577,1511,1578, +1512,1578,1511, +1578,1512,1579, +1513,1579,1512, +1579,1513,1580, +1514,1580,1513, +1580,1514,1581, +1515,1581,1514, +1581,1515,1582, +1516,1582,1515, +1582,1516,1583, +1517,1583,1516, +1584,1518,1585, +1519,1585,1518, +1585,1519,1586, +1520,1586,1519, +1586,1520,1587, +1521,1587,1520, +1587,1521,1588, +1522,1588,1521, +1588,1522,1589, +1523,1589,1522, +1589,1523,1590, +1524,1590,1523, +1590,1524,1591, +1525,1591,1524, +1591,1525,1592, +1526,1592,1525, +1592,1526,1593, +1527,1593,1526, +1593,1527,1594, +1528,1594,1527, +1594,1528,1595, +1529,1595,1528, +1595,1529,1596, +1530,1596,1529, +1596,1530,1597, +1531,1597,1530, +1597,1531,1598, +1532,1598,1531, +1598,1532,1599, +1533,1599,1532, +1599,1533,1600, +1534,1600,1533, +1600,1534,1601, +1535,1601,1534, +1601,1535,1602, +1536,1602,1535, +1602,1536,1603, +1537,1603,1536, +1603,1537,1604, +1538,1604,1537, +1604,1538,1605, +1539,1605,1538, +1605,1539,1606, +1540,1606,1539, +1606,1540,1607, +1541,1607,1540, +1607,1541,1608, +1542,1608,1541, +1608,1542,1609, +1543,1609,1542, +1609,1543,1610, +1544,1610,1543, +1610,1544,1611, +1545,1611,1544, +1611,1545,1612, +1546,1612,1545, +1612,1546,1613, +1547,1613,1546, +1613,1547,1614, +1548,1614,1547, +1614,1548,1615, +1549,1615,1548, +1615,1549,1616, +1550,1616,1549, +1616,1550,1617, +1551,1617,1550, +1617,1551,1618, +1552,1618,1551, +1618,1552,1619, +1553,1619,1552, +1619,1553,1620, +1554,1620,1553, +1620,1554,1621, +1555,1621,1554, +1621,1555,1622, +1556,1622,1555, +1622,1556,1623, +1557,1623,1556, +1623,1557,1624, +1558,1624,1557, +1624,1558,1625, +1559,1625,1558, +1625,1559,1626, +1560,1626,1559, +1626,1560,1627, +1561,1627,1560, +1627,1561,1628, +1562,1628,1561, +1628,1562,1629, +1563,1629,1562, +1629,1563,1630, +1564,1630,1563, +1630,1564,1631, +1565,1631,1564, +1631,1565,1632, +1566,1632,1565, +1632,1566,1633, +1567,1633,1566, +1633,1567,1634, +1568,1634,1567, +1634,1568,1635, +1569,1635,1568, +1635,1569,1636, +1570,1636,1569, +1636,1570,1637, +1571,1637,1570, +1637,1571,1638, +1572,1638,1571, +1638,1572,1639, +1573,1639,1572, +1639,1573,1640, +1574,1640,1573, +1640,1574,1641, +1575,1641,1574, +1641,1575,1642, +1576,1642,1575, +1642,1576,1643, +1577,1643,1576, +1643,1577,1644, +1578,1644,1577, +1644,1578,1645, +1579,1645,1578, +1645,1579,1646, +1580,1646,1579, +1646,1580,1647, +1581,1647,1580, +1647,1581,1648, +1582,1648,1581, +1648,1582,1649, +1583,1649,1582, +1650,1584,1651, +1585,1651,1584, +1651,1585,1652, +1586,1652,1585, +1652,1586,1653, +1587,1653,1586, +1653,1587,1654, +1588,1654,1587, +1654,1588,1655, +1589,1655,1588, +1655,1589,1656, +1590,1656,1589, +1656,1590,1657, +1591,1657,1590, +1657,1591,1658, +1592,1658,1591, +1658,1592,1659, +1593,1659,1592, +1659,1593,1660, +1594,1660,1593, +1660,1594,1661, +1595,1661,1594, +1661,1595,1662, +1596,1662,1595, +1662,1596,1663, +1597,1663,1596, +1663,1597,1664, +1598,1664,1597, +1664,1598,1665, +1599,1665,1598, +1665,1599,1666, +1600,1666,1599, +1666,1600,1667, +1601,1667,1600, +1667,1601,1668, +1602,1668,1601, +1668,1602,1669, +1603,1669,1602, +1669,1603,1670, +1604,1670,1603, +1670,1604,1671, +1605,1671,1604, +1671,1605,1672, +1606,1672,1605, +1672,1606,1673, +1607,1673,1606, +1673,1607,1674, +1608,1674,1607, +1674,1608,1675, +1609,1675,1608, +1675,1609,1676, +1610,1676,1609, +1676,1610,1677, +1611,1677,1610, +1677,1611,1678, +1612,1678,1611, +1678,1612,1679, +1613,1679,1612, +1679,1613,1680, +1614,1680,1613, +1680,1614,1681, +1615,1681,1614, +1681,1615,1682, +1616,1682,1615, +1682,1616,1683, +1617,1683,1616, +1683,1617,1684, +1618,1684,1617, +1684,1618,1685, +1619,1685,1618, +1685,1619,1686, +1620,1686,1619, +1686,1620,1687, +1621,1687,1620, +1687,1621,1688, +1622,1688,1621, +1688,1622,1689, +1623,1689,1622, +1689,1623,1690, +1624,1690,1623, +1690,1624,1691, +1625,1691,1624, +1691,1625,1692, +1626,1692,1625, +1692,1626,1693, +1627,1693,1626, +1693,1627,1694, +1628,1694,1627, +1694,1628,1695, +1629,1695,1628, +1695,1629,1696, +1630,1696,1629, +1696,1630,1697, +1631,1697,1630, +1697,1631,1698, +1632,1698,1631, +1698,1632,1699, +1633,1699,1632, +1699,1633,1700, +1634,1700,1633, +1700,1634,1701, +1635,1701,1634, +1701,1635,1702, +1636,1702,1635, +1702,1636,1703, +1637,1703,1636, +1703,1637,1704, +1638,1704,1637, +1704,1638,1705, +1639,1705,1638, +1705,1639,1706, +1640,1706,1639, +1706,1640,1707, +1641,1707,1640, +1707,1641,1708, +1642,1708,1641, +1708,1642,1709, +1643,1709,1642, +1709,1643,1710, +1644,1710,1643, +1710,1644,1711, +1645,1711,1644, +1711,1645,1712, +1646,1712,1645, +1712,1646,1713, +1647,1713,1646, +1713,1647,1714, +1648,1714,1647, +1714,1648,1715, +1649,1715,1648, +1716,1650,1717, +1651,1717,1650, +1717,1651,1718, +1652,1718,1651, +1718,1652,1719, +1653,1719,1652, +1719,1653,1720, +1654,1720,1653, +1720,1654,1721, +1655,1721,1654, +1721,1655,1722, +1656,1722,1655, +1722,1656,1723, +1657,1723,1656, +1723,1657,1724, +1658,1724,1657, +1724,1658,1725, +1659,1725,1658, +1725,1659,1726, +1660,1726,1659, +1726,1660,1727, +1661,1727,1660, +1727,1661,1728, +1662,1728,1661, +1728,1662,1729, +1663,1729,1662, +1729,1663,1730, +1664,1730,1663, +1730,1664,1731, +1665,1731,1664, +1731,1665,1732, +1666,1732,1665, +1732,1666,1733, +1667,1733,1666, +1733,1667,1734, +1668,1734,1667, +1734,1668,1735, +1669,1735,1668, +1735,1669,1736, +1670,1736,1669, +1736,1670,1737, +1671,1737,1670, +1737,1671,1738, +1672,1738,1671, +1738,1672,1739, +1673,1739,1672, +1739,1673,1740, +1674,1740,1673, +1740,1674,1741, +1675,1741,1674, +1741,1675,1742, +1676,1742,1675, +1742,1676,1743, +1677,1743,1676, +1743,1677,1744, +1678,1744,1677, +1744,1678,1745, +1679,1745,1678, +1745,1679,1746, +1680,1746,1679, +1746,1680,1747, +1681,1747,1680, +1747,1681,1748, +1682,1748,1681, +1748,1682,1749, +1683,1749,1682, +1749,1683,1750, +1684,1750,1683, +1750,1684,1751, +1685,1751,1684, +1751,1685,1752, +1686,1752,1685, +1752,1686,1753, +1687,1753,1686, +1753,1687,1754, +1688,1754,1687, +1754,1688,1755, +1689,1755,1688, +1755,1689,1756, +1690,1756,1689, +1756,1690,1757, +1691,1757,1690, +1757,1691,1758, +1692,1758,1691, +1758,1692,1759, +1693,1759,1692, +1759,1693,1760, +1694,1760,1693, +1760,1694,1761, +1695,1761,1694, +1761,1695,1762, +1696,1762,1695, +1762,1696,1763, +1697,1763,1696, +1763,1697,1764, +1698,1764,1697, +1764,1698,1765, +1699,1765,1698, +1765,1699,1766, +1700,1766,1699, +1766,1700,1767, +1701,1767,1700, +1767,1701,1768, +1702,1768,1701, +1768,1702,1769, +1703,1769,1702, +1769,1703,1770, +1704,1770,1703, +1770,1704,1771, +1705,1771,1704, +1771,1705,1772, +1706,1772,1705, +1772,1706,1773, +1707,1773,1706, +1773,1707,1774, +1708,1774,1707, +1774,1708,1775, +1709,1775,1708, +1775,1709,1776, +1710,1776,1709, +1776,1710,1777, +1711,1777,1710, +1777,1711,1778, +1712,1778,1711, +1778,1712,1779, +1713,1779,1712, +1779,1713,1780, +1714,1780,1713, +1780,1714,1781, +1715,1781,1714, +1782,1716,1783, +1717,1783,1716, +1783,1717,1784, +1718,1784,1717, +1784,1718,1785, +1719,1785,1718, +1785,1719,1786, +1720,1786,1719, +1786,1720,1787, +1721,1787,1720, +1787,1721,1788, +1722,1788,1721, +1788,1722,1789, +1723,1789,1722, +1789,1723,1790, +1724,1790,1723, +1790,1724,1791, +1725,1791,1724, +1791,1725,1792, +1726,1792,1725, +1792,1726,1793, +1727,1793,1726, +1793,1727,1794, +1728,1794,1727, +1794,1728,1795, +1729,1795,1728, +1795,1729,1796, +1730,1796,1729, +1796,1730,1797, +1731,1797,1730, +1797,1731,1798, +1732,1798,1731, +1798,1732,1799, +1733,1799,1732, +1799,1733,1800, +1734,1800,1733, +1800,1734,1801, +1735,1801,1734, +1801,1735,1802, +1736,1802,1735, +1802,1736,1803, +1737,1803,1736, +1803,1737,1804, +1738,1804,1737, +1804,1738,1805, +1739,1805,1738, +1805,1739,1806, +1740,1806,1739, +1806,1740,1807, +1741,1807,1740, +1807,1741,1808, +1742,1808,1741, +1808,1742,1809, +1743,1809,1742, +1809,1743,1810, +1744,1810,1743, +1810,1744,1811, +1745,1811,1744, +1811,1745,1812, +1746,1812,1745, +1812,1746,1813, +1747,1813,1746, +1813,1747,1814, +1748,1814,1747, +1814,1748,1815, +1749,1815,1748, +1815,1749,1816, +1750,1816,1749, +1816,1750,1817, +1751,1817,1750, +1817,1751,1818, +1752,1818,1751, +1818,1752,1819, +1753,1819,1752, +1819,1753,1820, +1754,1820,1753, +1820,1754,1821, +1755,1821,1754, +1821,1755,1822, +1756,1822,1755, +1822,1756,1823, +1757,1823,1756, +1823,1757,1824, +1758,1824,1757, +1824,1758,1825, +1759,1825,1758, +1825,1759,1826, +1760,1826,1759, +1826,1760,1827, +1761,1827,1760, +1827,1761,1828, +1762,1828,1761, +1828,1762,1829, +1763,1829,1762, +1829,1763,1830, +1764,1830,1763, +1830,1764,1831, +1765,1831,1764, +1831,1765,1832, +1766,1832,1765, +1832,1766,1833, +1767,1833,1766, +1833,1767,1834, +1768,1834,1767, +1834,1768,1835, +1769,1835,1768, +1835,1769,1836, +1770,1836,1769, +1836,1770,1837, +1771,1837,1770, +1837,1771,1838, +1772,1838,1771, +1838,1772,1839, +1773,1839,1772, +1839,1773,1840, +1774,1840,1773, +1840,1774,1841, +1775,1841,1774, +1841,1775,1842, +1776,1842,1775, +1842,1776,1843, +1777,1843,1776, +1843,1777,1844, +1778,1844,1777, +1844,1778,1845, +1779,1845,1778, +1845,1779,1846, +1780,1846,1779, +1846,1780,1847, +1781,1847,1780, +1848,1782,1849, +1783,1849,1782, +1849,1783,1850, +1784,1850,1783, +1850,1784,1851, +1785,1851,1784, +1851,1785,1852, +1786,1852,1785, +1852,1786,1853, +1787,1853,1786, +1853,1787,1854, +1788,1854,1787, +1854,1788,1855, +1789,1855,1788, +1855,1789,1856, +1790,1856,1789, +1856,1790,1857, +1791,1857,1790, +1857,1791,1858, +1792,1858,1791, +1858,1792,1859, +1793,1859,1792, +1859,1793,1860, +1794,1860,1793, +1860,1794,1861, +1795,1861,1794, +1861,1795,1862, +1796,1862,1795, +1862,1796,1863, +1797,1863,1796, +1863,1797,1864, +1798,1864,1797, +1864,1798,1865, +1799,1865,1798, +1865,1799,1866, +1800,1866,1799, +1866,1800,1867, +1801,1867,1800, +1867,1801,1868, +1802,1868,1801, +1868,1802,1869, +1803,1869,1802, +1869,1803,1870, +1804,1870,1803, +1870,1804,1871, +1805,1871,1804, +1871,1805,1872, +1806,1872,1805, +1872,1806,1873, +1807,1873,1806, +1873,1807,1874, +1808,1874,1807, +1874,1808,1875, +1809,1875,1808, +1875,1809,1876, +1810,1876,1809, +1876,1810,1877, +1811,1877,1810, +1877,1811,1878, +1812,1878,1811, +1878,1812,1879, +1813,1879,1812, +1879,1813,1880, +1814,1880,1813, +1880,1814,1881, +1815,1881,1814, +1881,1815,1882, +1816,1882,1815, +1882,1816,1883, +1817,1883,1816, +1883,1817,1884, +1818,1884,1817, +1884,1818,1885, +1819,1885,1818, +1885,1819,1886, +1820,1886,1819, +1886,1820,1887, +1821,1887,1820, +1887,1821,1888, +1822,1888,1821, +1888,1822,1889, +1823,1889,1822, +1889,1823,1890, +1824,1890,1823, +1890,1824,1891, +1825,1891,1824, +1891,1825,1892, +1826,1892,1825, +1892,1826,1893, +1827,1893,1826, +1893,1827,1894, +1828,1894,1827, +1894,1828,1895, +1829,1895,1828, +1895,1829,1896, +1830,1896,1829, +1896,1830,1897, +1831,1897,1830, +1897,1831,1898, +1832,1898,1831, +1898,1832,1899, +1833,1899,1832, +1899,1833,1900, +1834,1900,1833, +1900,1834,1901, +1835,1901,1834, +1901,1835,1902, +1836,1902,1835, +1902,1836,1903, +1837,1903,1836, +1903,1837,1904, +1838,1904,1837, +1904,1838,1905, +1839,1905,1838, +1905,1839,1906, +1840,1906,1839, +1906,1840,1907, +1841,1907,1840, +1907,1841,1908, +1842,1908,1841, +1908,1842,1909, +1843,1909,1842, +1909,1843,1910, +1844,1910,1843, +1910,1844,1911, +1845,1911,1844, +1911,1845,1912, +1846,1912,1845, +1912,1846,1913, +1847,1913,1846, +1914,1848,1915, +1849,1915,1848, +1915,1849,1916, +1850,1916,1849, +1916,1850,1917, +1851,1917,1850, +1917,1851,1918, +1852,1918,1851, +1918,1852,1919, +1853,1919,1852, +1919,1853,1920, +1854,1920,1853, +1920,1854,1921, +1855,1921,1854, +1921,1855,1922, +1856,1922,1855, +1922,1856,1923, +1857,1923,1856, +1923,1857,1924, +1858,1924,1857, +1924,1858,1925, +1859,1925,1858, +1925,1859,1926, +1860,1926,1859, +1926,1860,1927, +1861,1927,1860, +1927,1861,1928, +1862,1928,1861, +1928,1862,1929, +1863,1929,1862, +1929,1863,1930, +1864,1930,1863, +1930,1864,1931, +1865,1931,1864, +1931,1865,1932, +1866,1932,1865, +1932,1866,1933, +1867,1933,1866, +1933,1867,1934, +1868,1934,1867, +1934,1868,1935, +1869,1935,1868, +1935,1869,1936, +1870,1936,1869, +1936,1870,1937, +1871,1937,1870, +1937,1871,1938, +1872,1938,1871, +1938,1872,1939, +1873,1939,1872, +1939,1873,1940, +1874,1940,1873, +1940,1874,1941, +1875,1941,1874, +1941,1875,1942, +1876,1942,1875, +1942,1876,1943, +1877,1943,1876, +1943,1877,1944, +1878,1944,1877, +1944,1878,1945, +1879,1945,1878, +1945,1879,1946, +1880,1946,1879, +1946,1880,1947, +1881,1947,1880, +1947,1881,1948, +1882,1948,1881, +1948,1882,1949, +1883,1949,1882, +1949,1883,1950, +1884,1950,1883, +1950,1884,1951, +1885,1951,1884, +1951,1885,1952, +1886,1952,1885, +1952,1886,1953, +1887,1953,1886, +1953,1887,1954, +1888,1954,1887, +1954,1888,1955, +1889,1955,1888, +1955,1889,1956, +1890,1956,1889, +1956,1890,1957, +1891,1957,1890, +1957,1891,1958, +1892,1958,1891, +1958,1892,1959, +1893,1959,1892, +1959,1893,1960, +1894,1960,1893, +1960,1894,1961, +1895,1961,1894, +1961,1895,1962, +1896,1962,1895, +1962,1896,1963, +1897,1963,1896, +1963,1897,1964, +1898,1964,1897, +1964,1898,1965, +1899,1965,1898, +1965,1899,1966, +1900,1966,1899, +1966,1900,1967, +1901,1967,1900, +1967,1901,1968, +1902,1968,1901, +1968,1902,1969, +1903,1969,1902, +1969,1903,1970, +1904,1970,1903, +1970,1904,1971, +1905,1971,1904, +1971,1905,1972, +1906,1972,1905, +1972,1906,1973, +1907,1973,1906, +1973,1907,1974, +1908,1974,1907, +1974,1908,1975, +1909,1975,1908, +1975,1909,1976, +1910,1976,1909, +1976,1910,1977, +1911,1977,1910, +1977,1911,1978, +1912,1978,1911, +1978,1912,1979, +1913,1979,1912, +1980,1914,1981, +1915,1981,1914, +1981,1915,1982, +1916,1982,1915, +1982,1916,1983, +1917,1983,1916, +1983,1917,1984, +1918,1984,1917, +1984,1918,1985, +1919,1985,1918, +1985,1919,1986, +1920,1986,1919, +1986,1920,1987, +1921,1987,1920, +1987,1921,1988, +1922,1988,1921, +1988,1922,1989, +1923,1989,1922, +1989,1923,1990, +1924,1990,1923, +1990,1924,1991, +1925,1991,1924, +1991,1925,1992, +1926,1992,1925, +1992,1926,1993, +1927,1993,1926, +1993,1927,1994, +1928,1994,1927, +1994,1928,1995, +1929,1995,1928, +1995,1929,1996, +1930,1996,1929, +1996,1930,1997, +1931,1997,1930, +1997,1931,1998, +1932,1998,1931, +1998,1932,1999, +1933,1999,1932, +1999,1933,2000, +1934,2000,1933, +2000,1934,2001, +1935,2001,1934, +2001,1935,2002, +1936,2002,1935, +2002,1936,2003, +1937,2003,1936, +2003,1937,2004, +1938,2004,1937, +2004,1938,2005, +1939,2005,1938, +2005,1939,2006, +1940,2006,1939, +2006,1940,2007, +1941,2007,1940, +2007,1941,2008, +1942,2008,1941, +2008,1942,2009, +1943,2009,1942, +2009,1943,2010, +1944,2010,1943, +2010,1944,2011, +1945,2011,1944, +2011,1945,2012, +1946,2012,1945, +2012,1946,2013, +1947,2013,1946, +2013,1947,2014, +1948,2014,1947, +2014,1948,2015, +1949,2015,1948, +2015,1949,2016, +1950,2016,1949, +2016,1950,2017, +1951,2017,1950, +2017,1951,2018, +1952,2018,1951, +2018,1952,2019, +1953,2019,1952, +2019,1953,2020, +1954,2020,1953, +2020,1954,2021, +1955,2021,1954, +2021,1955,2022, +1956,2022,1955, +2022,1956,2023, +1957,2023,1956, +2023,1957,2024, +1958,2024,1957, +2024,1958,2025, +1959,2025,1958, +2025,1959,2026, +1960,2026,1959, +2026,1960,2027, +1961,2027,1960, +2027,1961,2028, +1962,2028,1961, +2028,1962,2029, +1963,2029,1962, +2029,1963,2030, +1964,2030,1963, +2030,1964,2031, +1965,2031,1964, +2031,1965,2032, +1966,2032,1965, +2032,1966,2033, +1967,2033,1966, +2033,1967,2034, +1968,2034,1967, +2034,1968,2035, +1969,2035,1968, +2035,1969,2036, +1970,2036,1969, +2036,1970,2037, +1971,2037,1970, +2037,1971,2038, +1972,2038,1971, +2038,1972,2039, +1973,2039,1972, +2039,1973,2040, +1974,2040,1973, +2040,1974,2041, +1975,2041,1974, +2041,1975,2042, +1976,2042,1975, +2042,1976,2043, +1977,2043,1976, +2043,1977,2044, +1978,2044,1977, +2044,1978,2045, +1979,2045,1978, +2046,1980,2047, +1981,2047,1980, +2047,1981,2048, +1982,2048,1981, +2048,1982,2049, +1983,2049,1982, +2049,1983,2050, +1984,2050,1983, +2050,1984,2051, +1985,2051,1984, +2051,1985,2052, +1986,2052,1985, +2052,1986,2053, +1987,2053,1986, +2053,1987,2054, +1988,2054,1987, +2054,1988,2055, +1989,2055,1988, +2055,1989,2056, +1990,2056,1989, +2056,1990,2057, +1991,2057,1990, +2057,1991,2058, +1992,2058,1991, +2058,1992,2059, +1993,2059,1992, +2059,1993,2060, +1994,2060,1993, +2060,1994,2061, +1995,2061,1994, +2061,1995,2062, +1996,2062,1995, +2062,1996,2063, +1997,2063,1996, +2063,1997,2064, +1998,2064,1997, +2064,1998,2065, +1999,2065,1998, +2065,1999,2066, +2000,2066,1999, +2066,2000,2067, +2001,2067,2000, +2067,2001,2068, +2002,2068,2001, +2068,2002,2069, +2003,2069,2002, +2069,2003,2070, +2004,2070,2003, +2070,2004,2071, +2005,2071,2004, +2071,2005,2072, +2006,2072,2005, +2072,2006,2073, +2007,2073,2006, +2073,2007,2074, +2008,2074,2007, +2074,2008,2075, +2009,2075,2008, +2075,2009,2076, +2010,2076,2009, +2076,2010,2077, +2011,2077,2010, +2077,2011,2078, +2012,2078,2011, +2078,2012,2079, +2013,2079,2012, +2079,2013,2080, +2014,2080,2013, +2080,2014,2081, +2015,2081,2014, +2081,2015,2082, +2016,2082,2015, +2082,2016,2083, +2017,2083,2016, +2083,2017,2084, +2018,2084,2017, +2084,2018,2085, +2019,2085,2018, +2085,2019,2086, +2020,2086,2019, +2086,2020,2087, +2021,2087,2020, +2087,2021,2088, +2022,2088,2021, +2088,2022,2089, +2023,2089,2022, +2089,2023,2090, +2024,2090,2023, +2090,2024,2091, +2025,2091,2024, +2091,2025,2092, +2026,2092,2025, +2092,2026,2093, +2027,2093,2026, +2093,2027,2094, +2028,2094,2027, +2094,2028,2095, +2029,2095,2028, +2095,2029,2096, +2030,2096,2029, +2096,2030,2097, +2031,2097,2030, +2097,2031,2098, +2032,2098,2031, +2098,2032,2099, +2033,2099,2032, +2099,2033,2100, +2034,2100,2033, +2100,2034,2101, +2035,2101,2034, +2101,2035,2102, +2036,2102,2035, +2102,2036,2103, +2037,2103,2036, +2103,2037,2104, +2038,2104,2037, +2104,2038,2105, +2039,2105,2038, +2105,2039,2106, +2040,2106,2039, +2106,2040,2107, +2041,2107,2040, +2107,2041,2108, +2042,2108,2041, +2108,2042,2109, +2043,2109,2042, +2109,2043,2110, +2044,2110,2043, +2110,2044,2111, +2045,2111,2044, +2112,2046,2113, +2047,2113,2046, +2113,2047,2114, +2048,2114,2047, +2114,2048,2115, +2049,2115,2048, +2115,2049,2116, +2050,2116,2049, +2116,2050,2117, +2051,2117,2050, +2117,2051,2118, +2052,2118,2051, +2118,2052,2119, +2053,2119,2052, +2119,2053,2120, +2054,2120,2053, +2120,2054,2121, +2055,2121,2054, +2121,2055,2122, +2056,2122,2055, +2122,2056,2123, +2057,2123,2056, +2123,2057,2124, +2058,2124,2057, +2124,2058,2125, +2059,2125,2058, +2125,2059,2126, +2060,2126,2059, +2126,2060,2127, +2061,2127,2060, +2127,2061,2128, +2062,2128,2061, +2128,2062,2129, +2063,2129,2062, +2129,2063,2130, +2064,2130,2063, +2130,2064,2131, +2065,2131,2064, +2131,2065,2132, +2066,2132,2065, +2132,2066,2133, +2067,2133,2066, +2133,2067,2134, +2068,2134,2067, +2134,2068,2135, +2069,2135,2068, +2135,2069,2136, +2070,2136,2069, +2136,2070,2137, +2071,2137,2070, +2137,2071,2138, +2072,2138,2071, +2138,2072,2139, +2073,2139,2072, +2139,2073,2140, +2074,2140,2073, +2140,2074,2141, +2075,2141,2074, +2141,2075,2142, +2076,2142,2075, +2142,2076,2143, +2077,2143,2076, +2143,2077,2144, +2078,2144,2077, +2144,2078,2145, +2079,2145,2078, +2145,2079,2146, +2080,2146,2079, +2146,2080,2147, +2081,2147,2080, +2147,2081,2148, +2082,2148,2081, +2148,2082,2149, +2083,2149,2082, +2149,2083,2150, +2084,2150,2083, +2150,2084,2151, +2085,2151,2084, +2151,2085,2152, +2086,2152,2085, +2152,2086,2153, +2087,2153,2086, +2153,2087,2154, +2088,2154,2087, +2154,2088,2155, +2089,2155,2088, +2155,2089,2156, +2090,2156,2089, +2156,2090,2157, +2091,2157,2090, +2157,2091,2158, +2092,2158,2091, +2158,2092,2159, +2093,2159,2092, +2159,2093,2160, +2094,2160,2093, +2160,2094,2161, +2095,2161,2094, +2161,2095,2162, +2096,2162,2095, +2162,2096,2163, +2097,2163,2096, +2163,2097,2164, +2098,2164,2097, +2164,2098,2165, +2099,2165,2098, +2165,2099,2166, +2100,2166,2099, +2166,2100,2167, +2101,2167,2100, +2167,2101,2168, +2102,2168,2101, +2168,2102,2169, +2103,2169,2102, +2169,2103,2170, +2104,2170,2103, +2170,2104,2171, +2105,2171,2104, +2171,2105,2172, +2106,2172,2105, +2172,2106,2173, +2107,2173,2106, +2173,2107,2174, +2108,2174,2107, +2174,2108,2175, +2109,2175,2108, +2175,2109,2176, +2110,2176,2109, +2176,2110,2177, +2111,2177,2110, +2178,2112,2179, +2113,2179,2112, +2179,2113,2180, +2114,2180,2113, +2180,2114,2181, +2115,2181,2114, +2181,2115,2182, +2116,2182,2115, +2182,2116,2183, +2117,2183,2116, +2183,2117,2184, +2118,2184,2117, +2184,2118,2185, +2119,2185,2118, +2185,2119,2186, +2120,2186,2119, +2186,2120,2187, +2121,2187,2120, +2187,2121,2188, +2122,2188,2121, +2188,2122,2189, +2123,2189,2122, +2189,2123,2190, +2124,2190,2123, +2190,2124,2191, +2125,2191,2124, +2191,2125,2192, +2126,2192,2125, +2192,2126,2193, +2127,2193,2126, +2193,2127,2194, +2128,2194,2127, +2194,2128,2195, +2129,2195,2128, +2195,2129,2196, +2130,2196,2129, +2196,2130,2197, +2131,2197,2130, +2197,2131,2198, +2132,2198,2131, +2198,2132,2199, +2133,2199,2132, +2199,2133,2200, +2134,2200,2133, +2200,2134,2201, +2135,2201,2134, +2201,2135,2202, +2136,2202,2135, +2202,2136,2203, +2137,2203,2136, +2203,2137,2204, +2138,2204,2137, +2204,2138,2205, +2139,2205,2138, +2205,2139,2206, +2140,2206,2139, +2206,2140,2207, +2141,2207,2140, +2207,2141,2208, +2142,2208,2141, +2208,2142,2209, +2143,2209,2142, +2209,2143,2210, +2144,2210,2143, +2210,2144,2211, +2145,2211,2144, +2211,2145,2212, +2146,2212,2145, +2212,2146,2213, +2147,2213,2146, +2213,2147,2214, +2148,2214,2147, +2214,2148,2215, +2149,2215,2148, +2215,2149,2216, +2150,2216,2149, +2216,2150,2217, +2151,2217,2150, +2217,2151,2218, +2152,2218,2151, +2218,2152,2219, +2153,2219,2152, +2219,2153,2220, +2154,2220,2153, +2220,2154,2221, +2155,2221,2154, +2221,2155,2222, +2156,2222,2155, +2222,2156,2223, +2157,2223,2156, +2223,2157,2224, +2158,2224,2157, +2224,2158,2225, +2159,2225,2158, +2225,2159,2226, +2160,2226,2159, +2226,2160,2227, +2161,2227,2160, +2227,2161,2228, +2162,2228,2161, +2228,2162,2229, +2163,2229,2162, +2229,2163,2230, +2164,2230,2163, +2230,2164,2231, +2165,2231,2164, +2231,2165,2232, +2166,2232,2165, +2232,2166,2233, +2167,2233,2166, +2233,2167,2234, +2168,2234,2167, +2234,2168,2235, +2169,2235,2168, +2235,2169,2236, +2170,2236,2169, +2236,2170,2237, +2171,2237,2170, +2237,2171,2238, +2172,2238,2171, +2238,2172,2239, +2173,2239,2172, +2239,2173,2240, +2174,2240,2173, +2240,2174,2241, +2175,2241,2174, +2241,2175,2242, +2176,2242,2175, +2242,2176,2243, +2177,2243,2176, +2244,2178,2245, +2179,2245,2178, +2245,2179,2246, +2180,2246,2179, +2246,2180,2247, +2181,2247,2180, +2247,2181,2248, +2182,2248,2181, +2248,2182,2249, +2183,2249,2182, +2249,2183,2250, +2184,2250,2183, +2250,2184,2251, +2185,2251,2184, +2251,2185,2252, +2186,2252,2185, +2252,2186,2253, +2187,2253,2186, +2253,2187,2254, +2188,2254,2187, +2254,2188,2255, +2189,2255,2188, +2255,2189,2256, +2190,2256,2189, +2256,2190,2257, +2191,2257,2190, +2257,2191,2258, +2192,2258,2191, +2258,2192,2259, +2193,2259,2192, +2259,2193,2260, +2194,2260,2193, +2260,2194,2261, +2195,2261,2194, +2261,2195,2262, +2196,2262,2195, +2262,2196,2263, +2197,2263,2196, +2263,2197,2264, +2198,2264,2197, +2264,2198,2265, +2199,2265,2198, +2265,2199,2266, +2200,2266,2199, +2266,2200,2267, +2201,2267,2200, +2267,2201,2268, +2202,2268,2201, +2268,2202,2269, +2203,2269,2202, +2269,2203,2270, +2204,2270,2203, +2270,2204,2271, +2205,2271,2204, +2271,2205,2272, +2206,2272,2205, +2272,2206,2273, +2207,2273,2206, +2273,2207,2274, +2208,2274,2207, +2274,2208,2275, +2209,2275,2208, +2275,2209,2276, +2210,2276,2209, +2276,2210,2277, +2211,2277,2210, +2277,2211,2278, +2212,2278,2211, +2278,2212,2279, +2213,2279,2212, +2279,2213,2280, +2214,2280,2213, +2280,2214,2281, +2215,2281,2214, +2281,2215,2282, +2216,2282,2215, +2282,2216,2283, +2217,2283,2216, +2283,2217,2284, +2218,2284,2217, +2284,2218,2285, +2219,2285,2218, +2285,2219,2286, +2220,2286,2219, +2286,2220,2287, +2221,2287,2220, +2287,2221,2288, +2222,2288,2221, +2288,2222,2289, +2223,2289,2222, +2289,2223,2290, +2224,2290,2223, +2290,2224,2291, +2225,2291,2224, +2291,2225,2292, +2226,2292,2225, +2292,2226,2293, +2227,2293,2226, +2293,2227,2294, +2228,2294,2227, +2294,2228,2295, +2229,2295,2228, +2295,2229,2296, +2230,2296,2229, +2296,2230,2297, +2231,2297,2230, +2297,2231,2298, +2232,2298,2231, +2298,2232,2299, +2233,2299,2232, +2299,2233,2300, +2234,2300,2233, +2300,2234,2301, +2235,2301,2234, +2301,2235,2302, +2236,2302,2235, +2302,2236,2303, +2237,2303,2236, +2303,2237,2304, +2238,2304,2237, +2304,2238,2305, +2239,2305,2238, +2305,2239,2306, +2240,2306,2239, +2306,2240,2307, +2241,2307,2240, +2307,2241,2308, +2242,2308,2241, +2308,2242,2309, +2243,2309,2242, +}; + +#define Landscape07VtxCount 2240 +#define Landscape07IdxCount 12852 + +btScalar Landscape07Vtx[] = { +3.90625f,49.6769f,-121.094f, +3.90625f,48.3887f,-117.188f, +7.8125f,48.8687f,-121.094f, +7.8125f,48.004f,-117.188f, +11.7188f,47.3453f,-121.094f, +11.7188f,46.8723f,-117.188f, +15.625f,44.9132f,-121.094f, +15.625f,45.5005f,-117.188f, +19.5313f,43.1526f,-121.094f, +19.5313f,43.3644f,-117.188f, +23.4375f,41.3946f,-121.094f, +23.4375f,42.3352f,-117.188f, +27.3438f,40.1349f,-121.094f, +27.3438f,41.1562f,-117.188f, +31.25f,39.2733f,-121.094f, +31.25f,39.1736f,-117.188f, +35.1563f,38.3718f,-121.094f, +35.1563f,38.0627f,-117.188f, +39.0625f,37.16f,-121.094f, +39.0625f,36.4728f,-117.188f, +42.9688f,35.2678f,-121.094f, +42.9688f,34.8001f,-117.188f, +46.875f,32.8529f,-121.094f, +46.875f,32.5103f,-117.188f, +50.7813f,32.0924f,-121.094f, +50.7813f,31.6328f,-117.188f, +54.6875f,33.2013f,-121.094f, +54.6875f,31.6106f,-117.188f, +58.5938f,34.1499f,-121.094f, +58.5938f,32.3004f,-117.188f, +62.5f,33.7675f,-121.094f, +62.5f,32.696f,-117.188f, +66.4063f,34.4892f,-121.094f, +66.4063f,33.3795f,-117.188f, +70.3125f,34.7441f,-121.094f, +70.3125f,33.9696f,-117.188f, +74.2188f,35.4435f,-121.094f, +74.2188f,34.9211f,-117.188f, +78.125f,36.6876f,-121.094f, +78.125f,36.7686f,-117.188f, +82.0313f,37.8831f,-121.094f, +82.0313f,37.7676f,-117.188f, +85.9375f,37.8533f,-121.094f, +85.9375f,37.8174f,-117.188f, +89.8438f,38.2467f,-121.094f, +89.8438f,38.2878f,-117.188f, +93.75f,39.5884f,-121.094f, +93.75f,39.6151f,-117.188f, +97.6563f,39.7164f,-121.094f, +97.6563f,39.7422f,-117.188f, +101.563f,40.296f,-121.094f, +101.563f,40.9611f,-117.188f, +105.469f,40.7222f,-121.094f, +105.469f,40.8932f,-117.188f, +109.375f,40.1304f,-121.094f, +109.375f,40.6603f,-117.188f, +113.281f,39.4566f,-121.094f, +113.281f,40.2935f,-117.188f, +117.188f,39.003f,-121.094f, +117.188f,39.8681f,-117.188f, +121.094f,38.091f,-121.094f, +121.094f,39.0965f,-117.188f, +125.0f,37.216f,-121.094f, +125.0f,37.1333f,-117.188f, +128.906f,35.4631f,-121.094f, +128.906f,35.5222f,-117.188f, +132.813f,33.4698f,-121.094f, +132.813f,33.9068f,-117.188f, +136.719f,31.5516f,-121.094f, +136.719f,32.2618f,-117.188f, +140.625f,28.6676f,-121.094f, +140.625f,29.8657f,-117.188f, +144.531f,26.5656f,-121.094f, +144.531f,28.1704f,-117.188f, +148.438f,24.1962f,-121.094f, +148.438f,27.1495f,-117.188f, +152.344f,22.2193f,-121.094f, +152.344f,24.5217f,-117.188f, +156.25f,20.1818f,-121.094f, +156.25f,22.0419f,-117.188f, +160.156f,17.6116f,-121.094f, +160.156f,19.9238f,-117.188f, +164.063f,15.5398f,-121.094f, +164.063f,17.6875f,-117.188f, +167.969f,13.7972f,-121.094f, +167.969f,15.5636f,-117.188f, +171.875f,11.7291f,-121.094f, +171.875f,13.5497f,-117.188f, +175.781f,9.31738f,-121.094f, +175.781f,11.2761f,-117.188f, +179.688f,6.60425f,-121.094f, +179.688f,8.95864f,-117.188f, +183.594f,4.50127f,-121.094f, +183.594f,7.04623f,-117.188f, +187.5f,2.77579f,-121.094f, +187.5f,4.83635f,-117.188f, +191.406f,1.39292f,-121.094f, +191.406f,2.76046f,-117.188f, +195.313f,-1.41093f,-121.094f, +195.313f,0.190119f,-117.188f, +199.219f,-2.1383f,-121.094f, +199.219f,-0.558379f,-117.188f, +203.125f,-2.43203f,-121.094f, +203.125f,-1.03303f,-117.188f, +207.031f,-3.74398f,-121.094f, +207.031f,-2.17563f,-117.188f, +210.938f,-4.31531f,-121.094f, +210.938f,-1.91155f,-117.188f, +214.844f,-5.42965f,-121.094f, +214.844f,-3.00018f,-117.188f, +218.75f,-6.70056f,-121.094f, +218.75f,-4.26691f,-117.188f, +222.656f,-6.19564f,-121.094f, +222.656f,-5.15855f,-117.188f, +226.563f,-4.68254f,-121.094f, +226.563f,-3.46348f,-117.188f, +230.469f,-3.31858f,-121.094f, +230.469f,-2.16077f,-117.188f, +234.375f,-3.88428f,-121.094f, +234.375f,-1.47785f,-117.188f, +238.281f,-3.80321f,-121.094f, +238.281f,-1.78424f,-117.188f, +242.188f,-3.43571f,-121.094f, +242.188f,-1.00317f,-117.188f, +246.094f,-3.77556f,-121.094f, +246.094f,-1.97981f,-117.188f, +250.0f,-3.83169f,-121.094f, +250.0f,-2.29372f,-117.188f, +3.90625f,50.3021f,-125.0f, +7.8125f,50.0186f,-125.0f, +11.7188f,47.8026f,-125.0f, +15.625f,45.4122f,-125.0f, +19.5313f,42.7204f,-125.0f, +23.4375f,42.1093f,-125.0f, +27.3438f,41.0672f,-125.0f, +31.25f,40.3016f,-125.0f, +35.1563f,38.401f,-125.0f, +39.0625f,36.5811f,-125.0f, +42.9688f,35.0771f,-125.0f, +46.875f,32.9255f,-125.0f, +50.7813f,31.2736f,-125.0f, +54.6875f,33.4622f,-125.0f, +58.5938f,34.314f,-125.0f, +62.5f,34.4185f,-125.0f, +66.4063f,34.621f,-125.0f, +70.3125f,34.9532f,-125.0f, +74.2188f,35.7305f,-125.0f, +78.125f,37.4446f,-125.0f, +82.0313f,37.6824f,-125.0f, +85.9375f,37.9835f,-125.0f, +89.8438f,38.5713f,-125.0f, +93.75f,39.56f,-125.0f, +97.6563f,40.0645f,-125.0f, +101.563f,39.9237f,-125.0f, +105.469f,39.8912f,-125.0f, +109.375f,39.9678f,-125.0f, +113.281f,39.7665f,-125.0f, +117.188f,38.758f,-125.0f, +121.094f,37.6738f,-125.0f, +125.0f,36.834f,-125.0f, +128.906f,34.7637f,-125.0f, +132.813f,31.9691f,-125.0f, +136.719f,30.7311f,-125.0f, +140.625f,27.9768f,-125.0f, +144.531f,25.22f,-125.0f, +148.438f,22.2616f,-125.0f, +152.344f,20.6399f,-125.0f, +156.25f,18.9363f,-125.0f, +160.156f,16.8778f,-125.0f, +164.063f,14.7425f,-125.0f, +167.969f,12.4299f,-125.0f, +171.875f,10.1017f,-125.0f, +175.781f,7.82169f,-125.0f, +179.688f,5.46502f,-125.0f, +183.594f,2.71076f,-125.0f, +187.5f,1.07736f,-125.0f, +191.406f,-0.592638f,-125.0f, +195.313f,-2.99173f,-125.0f, +199.219f,-4.30517f,-125.0f, +203.125f,-4.79591f,-125.0f, +207.031f,-6.32671f,-125.0f, +210.938f,-6.6914f,-125.0f, +214.844f,-8.34188f,-125.0f, +218.75f,-8.94371f,-125.0f, +222.656f,-7.16417f,-125.0f, +226.563f,-5.53904f,-125.0f, +230.469f,-5.10207f,-125.0f, +234.375f,-5.77507f,-125.0f, +238.281f,-5.5948f,-125.0f, +242.188f,-5.81224f,-125.0f, +246.094f,-5.48291f,-125.0f, +250.0f,-5.3221f,-125.0f, +3.90625f,50.4716f,-128.906f, +7.8125f,50.3922f,-128.906f, +11.7188f,48.0997f,-128.906f, +15.625f,44.9895f,-128.906f, +19.5313f,43.3038f,-128.906f, +23.4375f,42.8795f,-128.906f, +27.3438f,42.0905f,-128.906f, +31.25f,40.0566f,-128.906f, +35.1563f,37.7024f,-128.906f, +39.0625f,35.7533f,-128.906f, +42.9688f,32.9949f,-128.906f, +46.875f,31.7476f,-128.906f, +50.7813f,30.9413f,-128.906f, +54.6875f,31.9364f,-128.906f, +58.5938f,33.2028f,-128.906f, +62.5f,34.0103f,-128.906f, +66.4063f,34.3126f,-128.906f, +70.3125f,34.6096f,-128.906f, +74.2188f,35.8861f,-128.906f, +78.125f,36.5754f,-128.906f, +82.0313f,36.9009f,-128.906f, +85.9375f,37.369f,-128.906f, +89.8438f,38.2734f,-128.906f, +93.75f,38.7518f,-128.906f, +97.6563f,39.7576f,-128.906f, +101.563f,39.3413f,-128.906f, +105.469f,40.4224f,-128.906f, +109.375f,40.506f,-128.906f, +113.281f,39.7509f,-128.906f, +117.188f,38.6208f,-128.906f, +121.094f,37.1513f,-128.906f, +125.0f,36.003f,-128.906f, +128.906f,34.1307f,-128.906f, +132.813f,31.5523f,-128.906f, +136.719f,29.2003f,-128.906f, +140.625f,26.3718f,-128.906f, +144.531f,24.0851f,-128.906f, +148.438f,21.0492f,-128.906f, +152.344f,18.9709f,-128.906f, +156.25f,16.5536f,-128.906f, +160.156f,14.5588f,-128.906f, +164.063f,12.8386f,-128.906f, +167.969f,11.3092f,-128.906f, +171.875f,9.19396f,-128.906f, +175.781f,6.84617f,-128.906f, +179.688f,3.80062f,-128.906f, +183.594f,0.734751f,-128.906f, +187.5f,0.121523f,-128.906f, +191.406f,-1.9203f,-128.906f, +195.313f,-5.35291f,-128.906f, +199.219f,-7.06575f,-128.906f, +203.125f,-8.27325f,-128.906f, +207.031f,-8.82541f,-128.906f, +210.938f,-9.36185f,-128.906f, +214.844f,-10.8597f,-128.906f, +218.75f,-10.695f,-128.906f, +222.656f,-8.91012f,-128.906f, +226.563f,-8.24825f,-128.906f, +230.469f,-7.79624f,-128.906f, +234.375f,-6.74578f,-128.906f, +238.281f,-7.41285f,-128.906f, +242.188f,-7.01421f,-128.906f, +246.094f,-6.91669f,-128.906f, +250.0f,-6.09876f,-128.906f, +3.90625f,49.1054f,-132.813f, +7.8125f,48.771f,-132.813f, +11.7188f,46.9765f,-132.813f, +15.625f,44.4736f,-132.813f, +19.5313f,43.2026f,-132.813f, +23.4375f,42.2898f,-132.813f, +27.3438f,41.7492f,-132.813f, +31.25f,39.5792f,-132.813f, +35.1563f,36.5653f,-132.813f, +39.0625f,33.5612f,-132.813f, +42.9688f,31.9604f,-132.813f, +46.875f,30.953f,-132.813f, +50.7813f,30.5912f,-132.813f, +54.6875f,31.76f,-132.813f, +58.5938f,33.0843f,-132.813f, +62.5f,33.4323f,-132.813f, +66.4063f,33.9264f,-132.813f, +70.3125f,33.9268f,-132.813f, +74.2188f,33.8122f,-132.813f, +78.125f,34.9456f,-132.813f, +82.0313f,35.6308f,-132.813f, +85.9375f,35.8317f,-132.813f, +89.8438f,36.8255f,-132.813f, +93.75f,37.5781f,-132.813f, +97.6563f,39.0469f,-132.813f, +101.563f,38.905f,-132.813f, +105.469f,39.3656f,-132.813f, +109.375f,39.9706f,-132.813f, +113.281f,38.8077f,-132.813f, +117.188f,37.8378f,-132.813f, +121.094f,36.8368f,-132.813f, +125.0f,35.8474f,-132.813f, +128.906f,33.8502f,-132.813f, +132.813f,31.6251f,-132.813f, +136.719f,28.2781f,-132.813f, +140.625f,24.9841f,-132.813f, +144.531f,22.2281f,-132.813f, +148.438f,19.2974f,-132.813f, +152.344f,17.1516f,-132.813f, +156.25f,14.7654f,-132.813f, +160.156f,13.1833f,-132.813f, +164.063f,11.0184f,-132.813f, +167.969f,9.1589f,-132.813f, +171.875f,6.82631f,-132.813f, +175.781f,4.30633f,-132.813f, +179.688f,2.04751f,-132.813f, +183.594f,-0.74554f,-132.813f, +187.5f,-1.24688f,-132.813f, +191.406f,-3.70884f,-132.813f, +195.313f,-7.20423f,-132.813f, +199.219f,-9.63057f,-132.813f, +203.125f,-10.6411f,-132.813f, +207.031f,-11.1561f,-132.813f, +210.938f,-11.9998f,-132.813f, +214.844f,-13.1369f,-132.813f, +218.75f,-12.4543f,-132.813f, +222.656f,-11.5031f,-132.813f, +226.563f,-11.4632f,-132.813f, +230.469f,-10.5609f,-132.813f, +234.375f,-9.96017f,-132.813f, +238.281f,-9.64047f,-132.813f, +242.188f,-8.79112f,-132.813f, +246.094f,-8.33514f,-132.813f, +250.0f,-6.32649f,-132.813f, +3.90625f,47.9f,-136.719f, +7.8125f,47.0423f,-136.719f, +11.7188f,46.1087f,-136.719f, +15.625f,42.8209f,-136.719f, +19.5313f,41.8846f,-136.719f, +23.4375f,41.4071f,-136.719f, +27.3438f,39.6798f,-136.719f, +31.25f,38.1881f,-136.719f, +35.1563f,35.3952f,-136.719f, +39.0625f,31.8297f,-136.719f, +42.9688f,31.014f,-136.719f, +46.875f,29.29f,-136.719f, +50.7813f,29.4455f,-136.719f, +54.6875f,30.368f,-136.719f, +58.5938f,31.6261f,-136.719f, +62.5f,31.8803f,-136.719f, +66.4063f,32.8102f,-136.719f, +70.3125f,33.4331f,-136.719f, +74.2188f,33.19f,-136.719f, +78.125f,33.74f,-136.719f, +82.0313f,35.1047f,-136.719f, +85.9375f,36.2436f,-136.719f, +89.8438f,36.4928f,-136.719f, +93.75f,36.192f,-136.719f, +97.6563f,37.547f,-136.719f, +101.563f,38.0632f,-136.719f, +105.469f,38.6551f,-136.719f, +109.375f,38.4484f,-136.719f, +113.281f,37.8421f,-136.719f, +117.188f,37.5588f,-136.719f, +121.094f,37.278f,-136.719f, +125.0f,35.3541f,-136.719f, +128.906f,33.0939f,-136.719f, +132.813f,30.522f,-136.719f, +136.719f,27.5957f,-136.719f, +140.625f,24.4595f,-136.719f, +144.531f,21.0335f,-136.719f, +148.438f,18.0163f,-136.719f, +152.344f,15.3659f,-136.719f, +156.25f,13.4036f,-136.719f, +160.156f,11.6819f,-136.719f, +164.063f,9.68686f,-136.719f, +167.969f,7.56782f,-136.719f, +171.875f,4.49435f,-136.719f, +175.781f,1.55284f,-136.719f, +179.688f,0.275057f,-136.719f, +183.594f,-2.20168f,-136.719f, +187.5f,-3.16842f,-136.719f, +191.406f,-5.74212f,-136.719f, +195.313f,-8.33918f,-136.719f, +199.219f,-11.9926f,-136.719f, +203.125f,-13.7382f,-136.719f, +207.031f,-14.2163f,-136.719f, +210.938f,-14.76f,-136.719f, +214.844f,-14.7917f,-136.719f, +218.75f,-15.4594f,-136.719f, +222.656f,-14.7722f,-136.719f, +226.563f,-14.7687f,-136.719f, +230.469f,-13.0502f,-136.719f, +234.375f,-12.7522f,-136.719f, +238.281f,-12.1277f,-136.719f, +242.188f,-11.9805f,-136.719f, +246.094f,-9.26664f,-136.719f, +250.0f,-6.42671f,-136.719f, +3.90625f,47.2681f,-140.625f, +7.8125f,46.3513f,-140.625f, +11.7188f,45.1181f,-140.625f, +15.625f,42.9593f,-140.625f, +19.5313f,40.04f,-140.625f, +23.4375f,38.1657f,-140.625f, +27.3438f,37.2537f,-140.625f, +31.25f,35.6767f,-140.625f, +35.1563f,33.3413f,-140.625f, +39.0625f,30.7556f,-140.625f, +42.9688f,29.0258f,-140.625f, +46.875f,27.8122f,-140.625f, +50.7813f,27.4512f,-140.625f, +54.6875f,28.1912f,-140.625f, +58.5938f,29.8142f,-140.625f, +62.5f,30.1394f,-140.625f, +66.4063f,30.7105f,-140.625f, +70.3125f,31.9295f,-140.625f, +74.2188f,32.6689f,-140.625f, +78.125f,32.9232f,-140.625f, +82.0313f,35.5221f,-140.625f, +85.9375f,36.1785f,-140.625f, +89.8438f,35.864f,-140.625f, +93.75f,35.2473f,-140.625f, +97.6563f,35.6334f,-140.625f, +101.563f,36.5759f,-140.625f, +105.469f,37.2506f,-140.625f, +109.375f,36.7249f,-140.625f, +113.281f,36.4287f,-140.625f, +117.188f,36.6819f,-140.625f, +121.094f,36.4294f,-140.625f, +125.0f,35.2358f,-140.625f, +128.906f,32.9869f,-140.625f, +132.813f,30.156f,-140.625f, +136.719f,27.0471f,-140.625f, +140.625f,23.8554f,-140.625f, +144.531f,20.3993f,-140.625f, +148.438f,16.6224f,-140.625f, +152.344f,13.058f,-140.625f, +156.25f,11.1345f,-140.625f, +160.156f,9.35133f,-140.625f, +164.063f,7.36194f,-140.625f, +167.969f,5.31819f,-140.625f, +171.875f,2.78652f,-140.625f, +175.781f,0.868982f,-140.625f, +179.688f,-1.31465f,-140.625f, +183.594f,-3.64199f,-140.625f, +187.5f,-5.38333f,-140.625f, +191.406f,-8.08251f,-140.625f, +195.313f,-10.9184f,-140.625f, +199.219f,-14.2737f,-140.625f, +203.125f,-16.1495f,-140.625f, +207.031f,-16.9134f,-140.625f, +210.938f,-16.9575f,-140.625f, +214.844f,-17.6023f,-140.625f, +218.75f,-17.6633f,-140.625f, +222.656f,-17.159f,-140.625f, +226.563f,-16.2062f,-140.625f, +230.469f,-15.7685f,-140.625f, +234.375f,-15.0547f,-140.625f, +238.281f,-14.7858f,-140.625f, +242.188f,-12.8534f,-140.625f, +246.094f,-9.20599f,-140.625f, +250.0f,-5.60644f,-140.625f, +3.90625f,45.2398f,-144.531f, +7.8125f,45.0428f,-144.531f, +11.7188f,44.1179f,-144.531f, +15.625f,42.444f,-144.531f, +19.5313f,39.732f,-144.531f, +23.4375f,37.0479f,-144.531f, +27.3438f,34.3624f,-144.531f, +31.25f,33.2513f,-144.531f, +35.1563f,31.1146f,-144.531f, +39.0625f,29.2726f,-144.531f, +42.9688f,27.3159f,-144.531f, +46.875f,27.1241f,-144.531f, +50.7813f,26.6524f,-144.531f, +54.6875f,26.3337f,-144.531f, +58.5938f,27.8201f,-144.531f, +62.5f,27.8456f,-144.531f, +66.4063f,27.8306f,-144.531f, +70.3125f,29.8911f,-144.531f, +74.2188f,31.0667f,-144.531f, +78.125f,32.5778f,-144.531f, +82.0313f,34.5337f,-144.531f, +85.9375f,35.1457f,-144.531f, +89.8438f,34.7649f,-144.531f, +93.75f,34.0929f,-144.531f, +97.6563f,34.2934f,-144.531f, +101.563f,34.8046f,-144.531f, +105.469f,36.2496f,-144.531f, +109.375f,35.8351f,-144.531f, +113.281f,35.8228f,-144.531f, +117.188f,35.7495f,-144.531f, +121.094f,34.832f,-144.531f, +125.0f,34.3351f,-144.531f, +128.906f,32.4744f,-144.531f, +132.813f,29.6967f,-144.531f, +136.719f,26.263f,-144.531f, +140.625f,23.3556f,-144.531f, +144.531f,19.3517f,-144.531f, +148.438f,14.458f,-144.531f, +152.344f,11.2423f,-144.531f, +156.25f,9.75514f,-144.531f, +160.156f,7.96146f,-144.531f, +164.063f,5.67024f,-144.531f, +167.969f,4.08006f,-144.531f, +171.875f,1.71102f,-144.531f, +175.781f,-0.915369f,-144.531f, +179.688f,-2.66343f,-144.531f, +183.594f,-5.5816f,-144.531f, +187.5f,-7.79353f,-144.531f, +191.406f,-10.1772f,-144.531f, +195.313f,-13.5463f,-144.531f, +199.219f,-16.0692f,-144.531f, +203.125f,-17.2505f,-144.531f, +207.031f,-18.7241f,-144.531f, +210.938f,-18.7295f,-144.531f, +214.844f,-19.3f,-144.531f, +218.75f,-20.3181f,-144.531f, +222.656f,-19.4871f,-144.531f, +226.563f,-18.5465f,-144.531f, +230.469f,-17.525f,-144.531f, +234.375f,-16.5076f,-144.531f, +238.281f,-15.0993f,-144.531f, +242.188f,-13.0716f,-144.531f, +246.094f,-9.99063f,-144.531f, +250.0f,-5.64288f,-144.531f, +3.90625f,43.4167f,-148.438f, +7.8125f,43.0193f,-148.438f, +11.7188f,42.6242f,-148.438f, +15.625f,40.8831f,-148.438f, +19.5313f,38.6824f,-148.438f, +23.4375f,36.0177f,-148.438f, +27.3438f,32.9654f,-148.438f, +31.25f,31.3995f,-148.438f, +35.1563f,29.5101f,-148.438f, +39.0625f,27.4588f,-148.438f, +42.9688f,25.129f,-148.438f, +46.875f,25.4533f,-148.438f, +50.7813f,25.7106f,-148.438f, +54.6875f,25.737f,-148.438f, +58.5938f,26.1608f,-148.438f, +62.5f,27.2373f,-148.438f, +66.4063f,27.3635f,-148.438f, +70.3125f,27.7787f,-148.438f, +74.2188f,29.0906f,-148.438f, +78.125f,31.3992f,-148.438f, +82.0313f,32.9373f,-148.438f, +85.9375f,33.743f,-148.438f, +89.8438f,34.4265f,-148.438f, +93.75f,33.525f,-148.438f, +97.6563f,33.8231f,-148.438f, +101.563f,34.6826f,-148.438f, +105.469f,35.0275f,-148.438f, +109.375f,34.4667f,-148.438f, +113.281f,34.7266f,-148.438f, +117.188f,34.0788f,-148.438f, +121.094f,33.2521f,-148.438f, +125.0f,32.1914f,-148.438f, +128.906f,30.7782f,-148.438f, +132.813f,28.8615f,-148.438f, +136.719f,25.3691f,-148.438f, +140.625f,21.5786f,-148.438f, +144.531f,17.2969f,-148.438f, +148.438f,13.1925f,-148.438f, +152.344f,10.0632f,-148.438f, +156.25f,8.32421f,-148.438f, +160.156f,6.57856f,-148.438f, +164.063f,4.18522f,-148.438f, +167.969f,2.25091f,-148.438f, +171.875f,0.445952f,-148.438f, +175.781f,-1.73703f,-148.438f, +179.688f,-3.44886f,-148.438f, +183.594f,-6.77108f,-148.438f, +187.5f,-9.26031f,-148.438f, +191.406f,-12.38f,-148.438f, +195.313f,-14.6453f,-148.438f, +199.219f,-15.8435f,-148.438f, +203.125f,-17.3242f,-148.438f, +207.031f,-19.3932f,-148.438f, +210.938f,-19.7735f,-148.438f, +214.844f,-20.1293f,-148.438f, +218.75f,-20.5777f,-148.438f, +222.656f,-20.7145f,-148.438f, +226.563f,-20.64f,-148.438f, +230.469f,-19.6971f,-148.438f, +234.375f,-17.5016f,-148.438f, +238.281f,-14.644f,-148.438f, +242.188f,-12.3094f,-148.438f, +246.094f,-10.1634f,-148.438f, +250.0f,-6.79503f,-148.438f, +3.90625f,42.7212f,-152.344f, +7.8125f,41.7463f,-152.344f, +11.7188f,40.5249f,-152.344f, +15.625f,39.5225f,-152.344f, +19.5313f,36.6967f,-152.344f, +23.4375f,34.0075f,-152.344f, +27.3438f,31.2054f,-152.344f, +31.25f,28.8502f,-152.344f, +35.1563f,27.2625f,-152.344f, +39.0625f,24.9496f,-152.344f, +42.9688f,23.5897f,-152.344f, +46.875f,23.4709f,-152.344f, +50.7813f,24.179f,-152.344f, +54.6875f,25.021f,-152.344f, +58.5938f,25.6664f,-152.344f, +62.5f,25.7063f,-152.344f, +66.4063f,26.6928f,-152.344f, +70.3125f,26.8261f,-152.344f, +74.2188f,28.2549f,-152.344f, +78.125f,30.3373f,-152.344f, +82.0313f,31.6194f,-152.344f, +85.9375f,32.9189f,-152.344f, +89.8438f,32.7162f,-152.344f, +93.75f,33.0001f,-152.344f, +97.6563f,34.4407f,-152.344f, +101.563f,35.0813f,-152.344f, +105.469f,34.4143f,-152.344f, +109.375f,33.5195f,-152.344f, +113.281f,32.927f,-152.344f, +117.188f,32.6509f,-152.344f, +121.094f,32.6775f,-152.344f, +125.0f,30.887f,-152.344f, +128.906f,28.4296f,-152.344f, +132.813f,26.5539f,-152.344f, +136.719f,24.0803f,-152.344f, +140.625f,20.196f,-152.344f, +144.531f,16.4293f,-152.344f, +148.438f,12.8243f,-152.344f, +152.344f,9.76479f,-152.344f, +156.25f,7.14206f,-152.344f, +160.156f,4.74684f,-152.344f, +164.063f,2.30008f,-152.344f, +167.969f,1.49801f,-152.344f, +171.875f,-0.62719f,-152.344f, +175.781f,-1.99004f,-152.344f, +179.688f,-4.80775f,-152.344f, +183.594f,-8.00986f,-152.344f, +187.5f,-11.4771f,-152.344f, +191.406f,-12.8743f,-152.344f, +195.313f,-13.8733f,-152.344f, +199.219f,-15.0749f,-152.344f, +203.125f,-16.9234f,-152.344f, +207.031f,-18.3258f,-152.344f, +210.938f,-19.6583f,-152.344f, +214.844f,-20.9396f,-152.344f, +218.75f,-21.8071f,-152.344f, +222.656f,-21.4908f,-152.344f, +226.563f,-21.4698f,-152.344f, +230.469f,-19.3773f,-152.344f, +234.375f,-17.0448f,-152.344f, +238.281f,-14.0123f,-152.344f, +242.188f,-11.2372f,-152.344f, +246.094f,-9.11286f,-152.344f, +250.0f,-6.76792f,-152.344f, +3.90625f,41.7368f,-156.25f, +7.8125f,40.8494f,-156.25f, +11.7188f,39.2286f,-156.25f, +15.625f,37.4784f,-156.25f, +19.5313f,36.0345f,-156.25f, +23.4375f,33.9716f,-156.25f, +27.3438f,31.3041f,-156.25f, +31.25f,28.9777f,-156.25f, +35.1563f,26.0934f,-156.25f, +39.0625f,23.7421f,-156.25f, +42.9688f,22.4401f,-156.25f, +46.875f,22.1238f,-156.25f, +50.7813f,22.6669f,-156.25f, +54.6875f,23.7702f,-156.25f, +58.5938f,24.63f,-156.25f, +62.5f,25.2145f,-156.25f, +66.4063f,26.6101f,-156.25f, +70.3125f,27.3664f,-156.25f, +74.2188f,28.121f,-156.25f, +78.125f,29.5305f,-156.25f, +82.0313f,30.4367f,-156.25f, +85.9375f,30.627f,-156.25f, +89.8438f,30.4079f,-156.25f, +93.75f,32.2186f,-156.25f, +97.6563f,33.2916f,-156.25f, +101.563f,33.8066f,-156.25f, +105.469f,32.5269f,-156.25f, +109.375f,32.0751f,-156.25f, +113.281f,31.0298f,-156.25f, +117.188f,30.9869f,-156.25f, +121.094f,30.9826f,-156.25f, +125.0f,29.0676f,-156.25f, +128.906f,26.8988f,-156.25f, +132.813f,24.0771f,-156.25f, +136.719f,21.8087f,-156.25f, +140.625f,18.8179f,-156.25f, +144.531f,14.2483f,-156.25f, +148.438f,10.9236f,-156.25f, +152.344f,9.05948f,-156.25f, +156.25f,6.86087f,-156.25f, +160.156f,3.50699f,-156.25f, +164.063f,1.14903f,-156.25f, +167.969f,-0.639847f,-156.25f, +171.875f,-2.73828f,-156.25f, +175.781f,-4.02372f,-156.25f, +179.688f,-6.15141f,-156.25f, +183.594f,-8.81231f,-156.25f, +187.5f,-10.3417f,-156.25f, +191.406f,-11.1895f,-156.25f, +195.313f,-13.1464f,-156.25f, +199.219f,-14.5401f,-156.25f, +203.125f,-15.9427f,-156.25f, +207.031f,-17.492f,-156.25f, +210.938f,-19.0599f,-156.25f, +214.844f,-21.1101f,-156.25f, +218.75f,-21.3872f,-156.25f, +222.656f,-21.1481f,-156.25f, +226.563f,-20.2836f,-156.25f, +230.469f,-18.1679f,-156.25f, +234.375f,-15.72f,-156.25f, +238.281f,-13.4579f,-156.25f, +242.188f,-10.1453f,-156.25f, +246.094f,-8.09411f,-156.25f, +250.0f,-5.46467f,-156.25f, +3.90625f,40.4755f,-160.156f, +7.8125f,39.299f,-160.156f, +11.7188f,37.3972f,-160.156f, +15.625f,36.1894f,-160.156f, +19.5313f,34.3138f,-160.156f, +23.4375f,32.893f,-160.156f, +27.3438f,30.4515f,-160.156f, +31.25f,28.5808f,-160.156f, +35.1563f,25.8839f,-160.156f, +39.0625f,23.8505f,-160.156f, +42.9688f,22.3057f,-160.156f, +46.875f,21.4418f,-160.156f, +50.7813f,21.9709f,-160.156f, +54.6875f,23.0083f,-160.156f, +58.5938f,24.899f,-160.156f, +62.5f,25.213f,-160.156f, +66.4063f,26.1428f,-160.156f, +70.3125f,27.2675f,-160.156f, +74.2188f,28.0843f,-160.156f, +78.125f,28.9474f,-160.156f, +82.0313f,29.5078f,-160.156f, +85.9375f,29.7468f,-160.156f, +89.8438f,30.8621f,-160.156f, +93.75f,31.5001f,-160.156f, +97.6563f,32.1184f,-160.156f, +101.563f,31.2692f,-160.156f, +105.469f,30.4985f,-160.156f, +109.375f,29.4368f,-160.156f, +113.281f,30.6889f,-160.156f, +117.188f,29.6238f,-160.156f, +121.094f,28.6487f,-160.156f, +125.0f,26.3174f,-160.156f, +128.906f,24.6125f,-160.156f, +132.813f,22.1993f,-160.156f, +136.719f,19.3934f,-160.156f, +140.625f,16.5457f,-160.156f, +144.531f,13.4024f,-160.156f, +148.438f,9.69887f,-160.156f, +152.344f,8.13305f,-160.156f, +156.25f,6.48921f,-160.156f, +160.156f,2.56153f,-160.156f, +164.063f,0.0733139f,-160.156f, +167.969f,-1.11414f,-160.156f, +171.875f,-3.04708f,-160.156f, +175.781f,-6.18654f,-160.156f, +179.688f,-7.4188f,-160.156f, +183.594f,-9.1718f,-160.156f, +187.5f,-9.78027f,-160.156f, +191.406f,-10.5496f,-160.156f, +195.313f,-12.7259f,-160.156f, +199.219f,-13.9068f,-160.156f, +203.125f,-15.4772f,-160.156f, +207.031f,-17.6287f,-160.156f, +210.938f,-19.2502f,-160.156f, +214.844f,-19.5824f,-160.156f, +218.75f,-19.3114f,-160.156f, +222.656f,-19.5266f,-160.156f, +226.563f,-17.8446f,-160.156f, +230.469f,-16.3027f,-160.156f, +234.375f,-14.5015f,-160.156f, +238.281f,-11.9891f,-160.156f, +242.188f,-9.40017f,-160.156f, +246.094f,-6.63794f,-160.156f, +250.0f,-3.71573f,-160.156f, +3.90625f,38.8633f,-164.063f, +7.8125f,37.4382f,-164.063f, +11.7188f,35.7214f,-164.063f, +15.625f,34.0614f,-164.063f, +19.5313f,33.0957f,-164.063f, +23.4375f,32.0369f,-164.063f, +27.3438f,29.7096f,-164.063f, +31.25f,27.3216f,-164.063f, +35.1563f,25.2446f,-164.063f, +39.0625f,23.6071f,-164.063f, +42.9688f,22.2443f,-164.063f, +46.875f,21.2807f,-164.063f, +50.7813f,21.0358f,-164.063f, +54.6875f,22.8177f,-164.063f, +58.5938f,24.4434f,-164.063f, +62.5f,25.1375f,-164.063f, +66.4063f,25.3266f,-164.063f, +70.3125f,26.6102f,-164.063f, +74.2188f,27.6569f,-164.063f, +78.125f,27.8248f,-164.063f, +82.0313f,28.0421f,-164.063f, +85.9375f,29.1719f,-164.063f, +89.8438f,29.9529f,-164.063f, +93.75f,30.947f,-164.063f, +97.6563f,30.6189f,-164.063f, +101.563f,29.7913f,-164.063f, +105.469f,27.6858f,-164.063f, +109.375f,27.3234f,-164.063f, +113.281f,27.8148f,-164.063f, +117.188f,27.3571f,-164.063f, +121.094f,26.1572f,-164.063f, +125.0f,23.8557f,-164.063f, +128.906f,21.6383f,-164.063f, +132.813f,19.0681f,-164.063f, +136.719f,16.7352f,-164.063f, +140.625f,14.4004f,-164.063f, +144.531f,11.082f,-164.063f, +148.438f,8.38754f,-164.063f, +152.344f,7.0054f,-164.063f, +156.25f,4.95122f,-164.063f, +160.156f,2.47298f,-164.063f, +164.063f,0.777691f,-164.063f, +167.969f,-1.44055f,-164.063f, +171.875f,-3.57218f,-164.063f, +175.781f,-6.3396f,-164.063f, +179.688f,-7.49937f,-164.063f, +183.594f,-9.17485f,-164.063f, +187.5f,-9.92705f,-164.063f, +191.406f,-11.0737f,-164.063f, +195.313f,-12.8264f,-164.063f, +199.219f,-14.9306f,-164.063f, +203.125f,-15.9553f,-164.063f, +207.031f,-17.0898f,-164.063f, +210.938f,-18.5283f,-164.063f, +214.844f,-18.545f,-164.063f, +218.75f,-18.553f,-164.063f, +222.656f,-17.5725f,-164.063f, +226.563f,-15.6444f,-164.063f, +230.469f,-14.565f,-164.063f, +234.375f,-12.5578f,-164.063f, +238.281f,-10.6498f,-164.063f, +242.188f,-8.28284f,-164.063f, +246.094f,-5.87682f,-164.063f, +250.0f,-2.5339f,-164.063f, +3.90625f,37.2199f,-167.969f, +7.8125f,36.6782f,-167.969f, +11.7188f,36.2393f,-167.969f, +15.625f,33.4745f,-167.969f, +19.5313f,32.0928f,-167.969f, +23.4375f,30.5662f,-167.969f, +27.3438f,28.5968f,-167.969f, +31.25f,26.4298f,-167.969f, +35.1563f,23.9469f,-167.969f, +39.0625f,22.5415f,-167.969f, +42.9688f,21.8267f,-167.969f, +46.875f,21.2097f,-167.969f, +50.7813f,21.0841f,-167.969f, +54.6875f,21.7877f,-167.969f, +58.5938f,22.9351f,-167.969f, +62.5f,24.0641f,-167.969f, +66.4063f,24.42f,-167.969f, +70.3125f,24.8355f,-167.969f, +74.2188f,25.2701f,-167.969f, +78.125f,26.0252f,-167.969f, +82.0313f,26.8612f,-167.969f, +85.9375f,27.4256f,-167.969f, +89.8438f,28.994f,-167.969f, +93.75f,29.1766f,-167.969f, +97.6563f,27.8964f,-167.969f, +101.563f,26.6384f,-167.969f, +105.469f,24.9844f,-167.969f, +109.375f,25.0669f,-167.969f, +113.281f,24.572f,-167.969f, +117.188f,23.7817f,-167.969f, +121.094f,22.2089f,-167.969f, +125.0f,19.7633f,-167.969f, +128.906f,17.7618f,-167.969f, +132.813f,15.7339f,-167.969f, +136.719f,13.4975f,-167.969f, +140.625f,11.7364f,-167.969f, +144.531f,9.85351f,-167.969f, +148.438f,8.05282f,-167.969f, +152.344f,6.97463f,-167.969f, +156.25f,5.11511f,-167.969f, +160.156f,3.12954f,-167.969f, +164.063f,1.56555f,-167.969f, +167.969f,-1.77415f,-167.969f, +171.875f,-4.16322f,-167.969f, +175.781f,-5.85214f,-167.969f, +179.688f,-7.97892f,-167.969f, +183.594f,-9.87953f,-167.969f, +187.5f,-10.2762f,-167.969f, +191.406f,-11.5319f,-167.969f, +195.313f,-13.3612f,-167.969f, +199.219f,-15.3709f,-167.969f, +203.125f,-16.5674f,-167.969f, +207.031f,-17.6903f,-167.969f, +210.938f,-17.6736f,-167.969f, +214.844f,-16.8207f,-167.969f, +218.75f,-17.0254f,-167.969f, +222.656f,-16.3676f,-167.969f, +226.563f,-14.2816f,-167.969f, +230.469f,-13.3488f,-167.969f, +234.375f,-12.0136f,-167.969f, +238.281f,-9.90116f,-167.969f, +242.188f,-7.92295f,-167.969f, +246.094f,-5.41594f,-167.969f, +250.0f,-1.87299f,-167.969f, +3.90625f,35.3898f,-171.875f, +7.8125f,35.2527f,-171.875f, +11.7188f,34.3178f,-171.875f, +15.625f,33.0736f,-171.875f, +19.5313f,31.4013f,-171.875f, +23.4375f,28.9174f,-171.875f, +27.3438f,26.607f,-171.875f, +31.25f,24.7766f,-171.875f, +35.1563f,23.21f,-171.875f, +39.0625f,21.903f,-171.875f, +42.9688f,20.775f,-171.875f, +46.875f,20.114f,-171.875f, +50.7813f,19.6974f,-171.875f, +54.6875f,20.6726f,-171.875f, +58.5938f,22.241f,-171.875f, +62.5f,22.075f,-171.875f, +66.4063f,22.6771f,-171.875f, +70.3125f,22.4456f,-171.875f, +74.2188f,22.8643f,-171.875f, +78.125f,24.7268f,-171.875f, +82.0313f,25.7019f,-171.875f, +85.9375f,26.1196f,-171.875f, +89.8438f,25.6156f,-171.875f, +93.75f,24.7881f,-171.875f, +97.6563f,24.0074f,-171.875f, +101.563f,23.4739f,-171.875f, +105.469f,23.362f,-171.875f, +109.375f,22.2604f,-171.875f, +113.281f,21.2772f,-171.875f, +117.188f,19.7815f,-171.875f, +121.094f,17.9686f,-171.875f, +125.0f,16.3211f,-171.875f, +128.906f,14.2631f,-171.875f, +132.813f,12.4914f,-171.875f, +136.719f,10.3941f,-171.875f, +140.625f,8.91613f,-171.875f, +144.531f,9.17409f,-171.875f, +148.438f,7.34154f,-171.875f, +152.344f,6.13056f,-171.875f, +156.25f,4.58272f,-171.875f, +160.156f,2.77083f,-171.875f, +164.063f,1.11181f,-171.875f, +167.969f,-2.00034f,-171.875f, +171.875f,-3.64525f,-171.875f, +175.781f,-5.12602f,-171.875f, +179.688f,-8.3325f,-171.875f, +183.594f,-10.0807f,-171.875f, +187.5f,-10.8974f,-171.875f, +191.406f,-11.9623f,-171.875f, +195.313f,-14.5041f,-171.875f, +199.219f,-15.8629f,-171.875f, +203.125f,-17.2342f,-171.875f, +207.031f,-18.2786f,-171.875f, +210.938f,-16.9405f,-171.875f, +214.844f,-16.1592f,-171.875f, +218.75f,-15.9928f,-171.875f, +222.656f,-14.9179f,-171.875f, +226.563f,-13.6308f,-171.875f, +230.469f,-12.822f,-171.875f, +234.375f,-11.0168f,-171.875f, +238.281f,-8.54191f,-171.875f, +242.188f,-6.16464f,-171.875f, +246.094f,-4.35579f,-171.875f, +250.0f,-1.83408f,-171.875f, +3.90625f,34.823f,-175.781f, +7.8125f,33.9621f,-175.781f, +11.7188f,33.7226f,-175.781f, +15.625f,31.9821f,-175.781f, +19.5313f,29.6933f,-175.781f, +23.4375f,27.247f,-175.781f, +27.3438f,25.1394f,-175.781f, +31.25f,23.3125f,-175.781f, +35.1563f,21.288f,-175.781f, +39.0625f,21.2432f,-175.781f, +42.9688f,19.7041f,-175.781f, +46.875f,19.3043f,-175.781f, +50.7813f,18.5669f,-175.781f, +54.6875f,19.5408f,-175.781f, +58.5938f,20.3028f,-175.781f, +62.5f,20.573f,-175.781f, +66.4063f,20.7874f,-175.781f, +70.3125f,21.4507f,-175.781f, +74.2188f,22.9166f,-175.781f, +78.125f,23.6886f,-175.781f, +82.0313f,24.4139f,-175.781f, +85.9375f,25.1097f,-175.781f, +89.8438f,24.1395f,-175.781f, +93.75f,23.5282f,-175.781f, +97.6563f,22.7881f,-175.781f, +101.563f,21.2087f,-175.781f, +105.469f,20.6461f,-175.781f, +109.375f,19.7212f,-175.781f, +113.281f,17.9239f,-175.781f, +117.188f,16.9142f,-175.781f, +121.094f,16.1581f,-175.781f, +125.0f,15.1171f,-175.781f, +128.906f,13.1305f,-175.781f, +132.813f,10.3035f,-175.781f, +136.719f,7.95438f,-175.781f, +140.625f,7.49768f,-175.781f, +144.531f,7.76486f,-175.781f, +148.438f,6.84318f,-175.781f, +152.344f,6.0204f,-175.781f, +156.25f,4.83875f,-175.781f, +160.156f,2.59906f,-175.781f, +164.063f,1.35973f,-175.781f, +167.969f,-1.40345f,-175.781f, +171.875f,-3.6985f,-175.781f, +175.781f,-5.60686f,-175.781f, +179.688f,-8.15914f,-175.781f, +183.594f,-9.0389f,-175.781f, +187.5f,-11.2771f,-175.781f, +191.406f,-13.1363f,-175.781f, +195.313f,-14.845f,-175.781f, +199.219f,-15.885f,-175.781f, +203.125f,-17.6421f,-175.781f, +207.031f,-18.1972f,-175.781f, +210.938f,-16.4052f,-175.781f, +214.844f,-16.4522f,-175.781f, +218.75f,-15.8261f,-175.781f, +222.656f,-13.6816f,-175.781f, +226.563f,-12.8394f,-175.781f, +230.469f,-11.638f,-175.781f, +234.375f,-8.87545f,-175.781f, +238.281f,-6.82071f,-175.781f, +242.188f,-3.82988f,-175.781f, +246.094f,-2.34543f,-175.781f, +250.0f,-0.72787f,-175.781f, +3.90625f,32.9461f,-179.688f, +7.8125f,32.0951f,-179.688f, +11.7188f,31.1161f,-179.688f, +15.625f,29.4f,-179.688f, +19.5313f,27.5196f,-179.688f, +23.4375f,26.3351f,-179.688f, +27.3438f,24.0706f,-179.688f, +31.25f,21.9677f,-179.688f, +35.1563f,20.1582f,-179.688f, +39.0625f,19.3604f,-179.688f, +42.9688f,18.5912f,-179.688f, +46.875f,18.0845f,-179.688f, +50.7813f,18.0311f,-179.688f, +54.6875f,17.5412f,-179.688f, +58.5938f,17.724f,-179.688f, +62.5f,18.1752f,-179.688f, +66.4063f,18.8435f,-179.688f, +70.3125f,20.8887f,-179.688f, +74.2188f,21.9179f,-179.688f, +78.125f,22.3044f,-179.688f, +82.0313f,22.1491f,-179.688f, +85.9375f,23.261f,-179.688f, +89.8438f,22.4285f,-179.688f, +93.75f,21.5354f,-179.688f, +97.6563f,19.6399f,-179.688f, +101.563f,18.1312f,-179.688f, +105.469f,17.0655f,-179.688f, +109.375f,16.1471f,-179.688f, +113.281f,15.8256f,-179.688f, +117.188f,14.9609f,-179.688f, +121.094f,15.4508f,-179.688f, +125.0f,14.9122f,-179.688f, +128.906f,12.3324f,-179.688f, +132.813f,9.95184f,-179.688f, +136.719f,7.31755f,-179.688f, +140.625f,6.91109f,-179.688f, +144.531f,7.29489f,-179.688f, +148.438f,6.73968f,-179.688f, +152.344f,6.0555f,-179.688f, +156.25f,5.42266f,-179.688f, +160.156f,3.84651f,-179.688f, +164.063f,2.44552f,-179.688f, +167.969f,-0.187962f,-179.688f, +171.875f,-3.00626f,-179.688f, +175.781f,-5.38527f,-179.688f, +179.688f,-6.48806f,-179.688f, +183.594f,-9.24275f,-179.688f, +187.5f,-11.5122f,-179.688f, +191.406f,-12.6735f,-179.688f, +195.313f,-14.1843f,-179.688f, +199.219f,-15.4787f,-179.688f, +203.125f,-16.6061f,-179.688f, +207.031f,-17.1175f,-179.688f, +210.938f,-16.022f,-179.688f, +214.844f,-15.9349f,-179.688f, +218.75f,-14.6169f,-179.688f, +222.656f,-13.0146f,-179.688f, +226.563f,-12.2f,-179.688f, +230.469f,-9.81169f,-179.688f, +234.375f,-6.72224f,-179.688f, +238.281f,-4.11664f,-179.688f, +242.188f,-2.18066f,-179.688f, +246.094f,-0.510192f,-179.688f, +250.0f,1.48603f,-179.688f, +3.90625f,30.0027f,-183.594f, +7.8125f,29.6114f,-183.594f, +11.7188f,28.342f,-183.594f, +15.625f,26.9383f,-183.594f, +19.5313f,26.0219f,-183.594f, +23.4375f,25.017f,-183.594f, +27.3438f,22.7851f,-183.594f, +31.25f,20.6488f,-183.594f, +35.1563f,18.7107f,-183.594f, +39.0625f,17.0893f,-183.594f, +42.9688f,17.4316f,-183.594f, +46.875f,17.3211f,-183.594f, +50.7813f,16.5318f,-183.594f, +54.6875f,16.2012f,-183.594f, +58.5938f,17.0855f,-183.594f, +62.5f,17.2472f,-183.594f, +66.4063f,18.0123f,-183.594f, +70.3125f,18.684f,-183.594f, +74.2188f,19.625f,-183.594f, +78.125f,19.9442f,-183.594f, +82.0313f,19.9236f,-183.594f, +85.9375f,19.2286f,-183.594f, +89.8438f,19.5358f,-183.594f, +93.75f,18.429f,-183.594f, +97.6563f,16.1318f,-183.594f, +101.563f,14.371f,-183.594f, +105.469f,13.894f,-183.594f, +109.375f,13.5457f,-183.594f, +113.281f,13.7348f,-183.594f, +117.188f,14.0078f,-183.594f, +121.094f,14.2652f,-183.594f, +125.0f,13.5964f,-183.594f, +128.906f,11.3529f,-183.594f, +132.813f,8.43645f,-183.594f, +136.719f,6.95213f,-183.594f, +140.625f,7.16061f,-183.594f, +144.531f,6.71961f,-183.594f, +148.438f,5.35597f,-183.594f, +152.344f,5.22708f,-183.594f, +156.25f,5.07045f,-183.594f, +160.156f,3.44698f,-183.594f, +164.063f,2.33212f,-183.594f, +167.969f,0.462143f,-183.594f, +171.875f,-2.31458f,-183.594f, +175.781f,-4.89712f,-183.594f, +179.688f,-6.66797f,-183.594f, +183.594f,-9.25909f,-183.594f, +187.5f,-9.93472f,-183.594f, +191.406f,-12.0357f,-183.594f, +195.313f,-13.4286f,-183.594f, +199.219f,-14.4671f,-183.594f, +203.125f,-15.0102f,-183.594f, +207.031f,-14.8104f,-183.594f, +210.938f,-13.4733f,-183.594f, +214.844f,-14.0715f,-183.594f, +218.75f,-14.2416f,-183.594f, +222.656f,-12.2774f,-183.594f, +226.563f,-11.1048f,-183.594f, +230.469f,-8.72548f,-183.594f, +234.375f,-5.50563f,-183.594f, +238.281f,-2.81853f,-183.594f, +242.188f,-0.555239f,-183.594f, +246.094f,1.07177f,-183.594f, +250.0f,3.1022f,-183.594f, +3.90625f,27.6405f,-187.5f, +7.8125f,27.1266f,-187.5f, +11.7188f,26.0941f,-187.5f, +15.625f,25.1443f,-187.5f, +19.5313f,24.6236f,-187.5f, +23.4375f,23.7274f,-187.5f, +27.3438f,22.5792f,-187.5f, +31.25f,19.7482f,-187.5f, +35.1563f,17.6829f,-187.5f, +39.0625f,16.5577f,-187.5f, +42.9688f,15.8636f,-187.5f, +46.875f,16.0968f,-187.5f, +50.7813f,15.5614f,-187.5f, +54.6875f,15.4655f,-187.5f, +58.5938f,16.304f,-187.5f, +62.5f,16.7706f,-187.5f, +66.4063f,16.3947f,-187.5f, +70.3125f,16.6761f,-187.5f, +74.2188f,16.7627f,-187.5f, +78.125f,17.2579f,-187.5f, +82.0313f,16.7208f,-187.5f, +85.9375f,16.5278f,-187.5f, +89.8438f,16.2251f,-187.5f, +93.75f,15.0741f,-187.5f, +97.6563f,14.2628f,-187.5f, +101.563f,12.432f,-187.5f, +105.469f,10.8877f,-187.5f, +109.375f,11.903f,-187.5f, +113.281f,12.5606f,-187.5f, +117.188f,13.2652f,-187.5f, +121.094f,13.6914f,-187.5f, +125.0f,12.7849f,-187.5f, +128.906f,10.4802f,-187.5f, +132.813f,8.75276f,-187.5f, +136.719f,6.90392f,-187.5f, +140.625f,6.91636f,-187.5f, +144.531f,6.78271f,-187.5f, +148.438f,5.25436f,-187.5f, +152.344f,4.14458f,-187.5f, +156.25f,3.58445f,-187.5f, +160.156f,3.67538f,-187.5f, +164.063f,1.88171f,-187.5f, +167.969f,1.16358f,-187.5f, +171.875f,-0.909335f,-187.5f, +175.781f,-4.00056f,-187.5f, +179.688f,-6.532f,-187.5f, +183.594f,-8.29174f,-187.5f, +187.5f,-9.0196f,-187.5f, +191.406f,-10.1189f,-187.5f, +195.313f,-11.1349f,-187.5f, +199.219f,-12.4853f,-187.5f, +203.125f,-12.7324f,-187.5f, +207.031f,-12.949f,-187.5f, +210.938f,-11.8708f,-187.5f, +214.844f,-12.2515f,-187.5f, +218.75f,-12.8455f,-187.5f, +222.656f,-10.7923f,-187.5f, +226.563f,-8.82819f,-187.5f, +230.469f,-7.36721f,-187.5f, +234.375f,-5.23714f,-187.5f, +238.281f,-2.63334f,-187.5f, +242.188f,0.485313f,-187.5f, +246.094f,2.78278f,-187.5f, +250.0f,3.96313f,-187.5f, +3.90625f,25.3652f,-191.406f, +7.8125f,24.7195f,-191.406f, +11.7188f,25.004f,-191.406f, +15.625f,24.1773f,-191.406f, +19.5313f,22.7395f,-191.406f, +23.4375f,21.4739f,-191.406f, +27.3438f,21.0405f,-191.406f, +31.25f,18.3321f,-191.406f, +35.1563f,16.9491f,-191.406f, +39.0625f,15.1898f,-191.406f, +42.9688f,14.5842f,-191.406f, +46.875f,14.234f,-191.406f, +50.7813f,14.0689f,-191.406f, +54.6875f,15.4103f,-191.406f, +58.5938f,15.0749f,-191.406f, +62.5f,14.6893f,-191.406f, +66.4063f,14.8987f,-191.406f, +70.3125f,14.4416f,-191.406f, +74.2188f,14.3436f,-191.406f, +78.125f,13.5844f,-191.406f, +82.0313f,13.3989f,-191.406f, +85.9375f,14.3892f,-191.406f, +89.8438f,13.3595f,-191.406f, +93.75f,13.3004f,-191.406f, +97.6563f,11.8557f,-191.406f, +101.563f,9.50387f,-191.406f, +105.469f,9.09049f,-191.406f, +109.375f,10.2607f,-191.406f, +113.281f,11.3275f,-191.406f, +117.188f,11.8898f,-191.406f, +121.094f,11.9585f,-191.406f, +125.0f,11.0034f,-191.406f, +128.906f,10.0704f,-191.406f, +132.813f,8.84472f,-191.406f, +136.719f,7.56972f,-191.406f, +140.625f,6.66467f,-191.406f, +144.531f,5.57509f,-191.406f, +148.438f,4.43943f,-191.406f, +152.344f,3.51469f,-191.406f, +156.25f,2.91572f,-191.406f, +160.156f,3.43161f,-191.406f, +164.063f,1.97664f,-191.406f, +167.969f,1.37279f,-191.406f, +171.875f,-0.545961f,-191.406f, +175.781f,-3.78517f,-191.406f, +179.688f,-6.09483f,-191.406f, +183.594f,-6.45627f,-191.406f, +187.5f,-7.27376f,-191.406f, +191.406f,-8.99215f,-191.406f, +195.313f,-9.89915f,-191.406f, +199.219f,-10.9608f,-191.406f, +203.125f,-10.8387f,-191.406f, +207.031f,-10.5261f,-191.406f, +210.938f,-10.1365f,-191.406f, +214.844f,-10.631f,-191.406f, +218.75f,-10.8413f,-191.406f, +222.656f,-9.03823f,-191.406f, +226.563f,-7.39571f,-191.406f, +230.469f,-4.8409f,-191.406f, +234.375f,-3.47756f,-191.406f, +238.281f,-1.63291f,-191.406f, +242.188f,1.44814f,-191.406f, +246.094f,2.93141f,-191.406f, +250.0f,4.03991f,-191.406f, +3.90625f,23.0993f,-195.313f, +7.8125f,23.2309f,-195.313f, +11.7188f,23.4293f,-195.313f, +15.625f,22.4425f,-195.313f, +19.5313f,21.4905f,-195.313f, +23.4375f,19.6567f,-195.313f, +27.3438f,18.1324f,-195.313f, +31.25f,17.3872f,-195.313f, +35.1563f,16.265f,-195.313f, +39.0625f,13.8338f,-195.313f, +42.9688f,12.7629f,-195.313f, +46.875f,13.1006f,-195.313f, +50.7813f,13.3481f,-195.313f, +54.6875f,13.8039f,-195.313f, +58.5938f,13.0621f,-195.313f, +62.5f,12.4363f,-195.313f, +66.4063f,12.748f,-195.313f, +70.3125f,12.2979f,-195.313f, +74.2188f,11.3997f,-195.313f, +78.125f,12.1637f,-195.313f, +82.0313f,12.2143f,-195.313f, +85.9375f,12.0963f,-195.313f, +89.8438f,11.3468f,-195.313f, +93.75f,11.1939f,-195.313f, +97.6563f,9.31577f,-195.313f, +101.563f,9.0203f,-195.313f, +105.469f,8.39154f,-195.313f, +109.375f,8.72501f,-195.313f, +113.281f,9.3763f,-195.313f, +117.188f,9.56963f,-195.313f, +121.094f,9.54203f,-195.313f, +125.0f,9.30859f,-195.313f, +128.906f,9.02325f,-195.313f, +132.813f,8.54457f,-195.313f, +136.719f,7.91487f,-195.313f, +140.625f,5.8935f,-195.313f, +144.531f,4.77605f,-195.313f, +148.438f,3.03324f,-195.313f, +152.344f,2.63999f,-195.313f, +156.25f,1.85254f,-195.313f, +160.156f,2.58504f,-195.313f, +164.063f,1.86646f,-195.313f, +167.969f,0.472293f,-195.313f, +171.875f,-0.819486f,-195.313f, +175.781f,-3.28005f,-195.313f, +179.688f,-4.07223f,-195.313f, +183.594f,-5.23099f,-195.313f, +187.5f,-5.93446f,-195.313f, +191.406f,-7.40083f,-195.313f, +195.313f,-9.52595f,-195.313f, +199.219f,-9.06593f,-195.313f, +203.125f,-8.64632f,-195.313f, +207.031f,-8.71126f,-195.313f, +210.938f,-7.66946f,-195.313f, +214.844f,-8.22025f,-195.313f, +218.75f,-8.77434f,-195.313f, +222.656f,-7.8003f,-195.313f, +226.563f,-5.29317f,-195.313f, +230.469f,-3.13421f,-195.313f, +234.375f,-1.47978f,-195.313f, +238.281f,0.0436352f,-195.313f, +242.188f,1.56763f,-195.313f, +246.094f,3.2707f,-195.313f, +250.0f,5.38332f,-195.313f, +3.90625f,21.5827f,-199.219f, +7.8125f,21.5884f,-199.219f, +11.7188f,22.0551f,-199.219f, +15.625f,21.1895f,-199.219f, +19.5313f,19.9629f,-199.219f, +23.4375f,18.1891f,-199.219f, +27.3438f,17.3914f,-199.219f, +31.25f,15.7832f,-199.219f, +35.1563f,13.9537f,-199.219f, +39.0625f,11.7784f,-199.219f, +42.9688f,12.6473f,-199.219f, +46.875f,12.1685f,-199.219f, +50.7813f,12.2586f,-199.219f, +54.6875f,12.032f,-199.219f, +58.5938f,12.5025f,-199.219f, +62.5f,12.2207f,-199.219f, +66.4063f,10.4332f,-199.219f, +70.3125f,10.2093f,-199.219f, +74.2188f,9.56536f,-199.219f, +78.125f,10.5041f,-199.219f, +82.0313f,10.9136f,-199.219f, +85.9375f,10.6303f,-199.219f, +89.8438f,11.148f,-199.219f, +93.75f,10.2169f,-199.219f, +97.6563f,8.56966f,-199.219f, +101.563f,8.81808f,-199.219f, +105.469f,7.92638f,-199.219f, +109.375f,7.988f,-199.219f, +113.281f,8.07342f,-199.219f, +117.188f,8.41463f,-199.219f, +121.094f,8.44317f,-199.219f, +125.0f,8.93315f,-199.219f, +128.906f,8.02242f,-199.219f, +132.813f,7.78977f,-199.219f, +136.719f,7.24422f,-199.219f, +140.625f,6.65469f,-199.219f, +144.531f,5.63698f,-199.219f, +148.438f,3.71906f,-199.219f, +152.344f,1.94989f,-199.219f, +156.25f,1.5781f,-199.219f, +160.156f,2.54367f,-199.219f, +164.063f,2.24455f,-199.219f, +167.969f,0.172967f,-199.219f, +171.875f,-1.24076f,-199.219f, +175.781f,-2.09517f,-199.219f, +179.688f,-2.60068f,-199.219f, +183.594f,-3.35838f,-199.219f, +187.5f,-5.02796f,-199.219f, +191.406f,-6.75939f,-199.219f, +195.313f,-7.86176f,-199.219f, +199.219f,-7.60703f,-199.219f, +203.125f,-7.1176f,-199.219f, +207.031f,-7.21926f,-199.219f, +210.938f,-6.354f,-199.219f, +214.844f,-6.26146f,-199.219f, +218.75f,-7.39202f,-199.219f, +222.656f,-6.10132f,-199.219f, +226.563f,-4.15677f,-199.219f, +230.469f,-1.72339f,-199.219f, +234.375f,0.220408f,-199.219f, +238.281f,1.71501f,-199.219f, +242.188f,2.32136f,-199.219f, +246.094f,3.9302f,-199.219f, +250.0f,6.99831f,-199.219f, +3.90625f,20.3179f,-203.125f, +7.8125f,19.0038f,-203.125f, +11.7188f,19.8795f,-203.125f, +15.625f,18.863f,-203.125f, +19.5313f,17.2513f,-203.125f, +23.4375f,16.7786f,-203.125f, +27.3438f,16.4605f,-203.125f, +31.25f,14.0944f,-203.125f, +35.1563f,12.6715f,-203.125f, +39.0625f,12.2869f,-203.125f, +42.9688f,12.0256f,-203.125f, +46.875f,11.4308f,-203.125f, +50.7813f,11.5543f,-203.125f, +54.6875f,10.8247f,-203.125f, +58.5938f,12.5385f,-203.125f, +62.5f,12.1754f,-203.125f, +66.4063f,10.0857f,-203.125f, +70.3125f,8.73654f,-203.125f, +74.2188f,8.35323f,-203.125f, +78.125f,8.75049f,-203.125f, +82.0313f,9.69714f,-203.125f, +85.9375f,9.93848f,-203.125f, +89.8438f,9.99533f,-203.125f, +93.75f,9.28937f,-203.125f, +97.6563f,8.19048f,-203.125f, +101.563f,7.82659f,-203.125f, +105.469f,6.70152f,-203.125f, +109.375f,6.35245f,-203.125f, +113.281f,6.80811f,-203.125f, +117.188f,7.88474f,-203.125f, +121.094f,8.76964f,-203.125f, +125.0f,9.33913f,-203.125f, +128.906f,9.12843f,-203.125f, +132.813f,7.62144f,-203.125f, +136.719f,6.32841f,-203.125f, +140.625f,6.30299f,-203.125f, +144.531f,5.78467f,-203.125f, +148.438f,4.2404f,-203.125f, +152.344f,2.7611f,-203.125f, +156.25f,1.95904f,-203.125f, +160.156f,2.27166f,-203.125f, +164.063f,2.22405f,-203.125f, +167.969f,1.12279f,-203.125f, +171.875f,-0.169061f,-203.125f, +175.781f,-0.887647f,-203.125f, +179.688f,-0.896535f,-203.125f, +183.594f,-2.41604f,-203.125f, +187.5f,-3.63423f,-203.125f, +191.406f,-6.00826f,-203.125f, +195.313f,-5.87316f,-203.125f, +199.219f,-5.18767f,-203.125f, +203.125f,-4.23762f,-203.125f, +207.031f,-4.7338f,-203.125f, +210.938f,-4.88225f,-203.125f, +214.844f,-4.82274f,-203.125f, +218.75f,-5.06338f,-203.125f, +222.656f,-5.13737f,-203.125f, +226.563f,-2.74217f,-203.125f, +230.469f,0.0831564f,-203.125f, +234.375f,2.00986f,-203.125f, +238.281f,2.89937f,-203.125f, +242.188f,3.79442f,-203.125f, +246.094f,5.43821f,-203.125f, +250.0f,8.47222f,-203.125f, +3.90625f,18.3149f,-207.031f, +7.8125f,16.9318f,-207.031f, +11.7188f,16.7123f,-207.031f, +15.625f,16.066f,-207.031f, +19.5313f,15.8401f,-207.031f, +23.4375f,14.9793f,-207.031f, +27.3438f,13.5136f,-207.031f, +31.25f,12.316f,-207.031f, +35.1563f,12.4286f,-207.031f, +39.0625f,12.5926f,-207.031f, +42.9688f,12.419f,-207.031f, +46.875f,11.7087f,-207.031f, +50.7813f,10.9033f,-207.031f, +54.6875f,10.2175f,-207.031f, +58.5938f,10.7307f,-207.031f, +62.5f,9.9283f,-207.031f, +66.4063f,9.11458f,-207.031f, +70.3125f,6.81804f,-207.031f, +74.2188f,6.85559f,-207.031f, +78.125f,6.98146f,-207.031f, +82.0313f,8.41059f,-207.031f, +85.9375f,8.81018f,-207.031f, +89.8438f,9.25882f,-207.031f, +93.75f,8.4973f,-207.031f, +97.6563f,7.11312f,-207.031f, +101.563f,6.11367f,-207.031f, +105.469f,4.54171f,-207.031f, +109.375f,3.984f,-207.031f, +113.281f,6.23536f,-207.031f, +117.188f,7.41972f,-207.031f, +121.094f,8.40005f,-207.031f, +125.0f,9.21009f,-207.031f, +128.906f,9.10113f,-207.031f, +132.813f,8.69785f,-207.031f, +136.719f,7.08314f,-207.031f, +140.625f,6.14113f,-207.031f, +144.531f,4.85123f,-207.031f, +148.438f,4.53013f,-207.031f, +152.344f,4.73052f,-207.031f, +156.25f,3.50435f,-207.031f, +160.156f,3.02093f,-207.031f, +164.063f,2.65317f,-207.031f, +167.969f,1.91936f,-207.031f, +171.875f,1.31638f,-207.031f, +175.781f,0.631767f,-207.031f, +179.688f,-0.185018f,-207.031f, +183.594f,-1.04617f,-207.031f, +187.5f,-2.59594f,-207.031f, +191.406f,-3.62219f,-207.031f, +195.313f,-3.17366f,-207.031f, +199.219f,-3.0812f,-207.031f, +203.125f,-2.21365f,-207.031f, +207.031f,-3.02851f,-207.031f, +210.938f,-4.12823f,-207.031f, +214.844f,-3.42208f,-207.031f, +218.75f,-3.83284f,-207.031f, +222.656f,-3.83483f,-207.031f, +226.563f,-1.81388f,-207.031f, +230.469f,1.06182f,-207.031f, +234.375f,3.0063f,-207.031f, +238.281f,3.97581f,-207.031f, +242.188f,5.25584f,-207.031f, +246.094f,6.1092f,-207.031f, +250.0f,9.89458f,-207.031f, +3.90625f,16.2147f,-210.938f, +7.8125f,15.8155f,-210.938f, +11.7188f,14.9704f,-210.938f, +15.625f,14.6853f,-210.938f, +19.5313f,14.3326f,-210.938f, +23.4375f,14.0488f,-210.938f, +27.3438f,12.2057f,-210.938f, +31.25f,12.7526f,-210.938f, +35.1563f,13.1468f,-210.938f, +39.0625f,12.959f,-210.938f, +42.9688f,12.3931f,-210.938f, +46.875f,11.9578f,-210.938f, +50.7813f,10.5381f,-210.938f, +54.6875f,9.28222f,-210.938f, +58.5938f,9.20117f,-210.938f, +62.5f,8.74359f,-210.938f, +66.4063f,7.58308f,-210.938f, +70.3125f,5.98903f,-210.938f, +74.2188f,5.92315f,-210.938f, +78.125f,6.30208f,-210.938f, +82.0313f,7.35787f,-210.938f, +85.9375f,7.64729f,-210.938f, +89.8438f,7.89394f,-210.938f, +93.75f,7.64523f,-210.938f, +97.6563f,5.66526f,-210.938f, +101.563f,4.1348f,-210.938f, +105.469f,2.65548f,-210.938f, +109.375f,4.20615f,-210.938f, +113.281f,5.82801f,-210.938f, +117.188f,6.92681f,-210.938f, +121.094f,8.52107f,-210.938f, +125.0f,9.29929f,-210.938f, +128.906f,10.1454f,-210.938f, +132.813f,9.39782f,-210.938f, +136.719f,8.72704f,-210.938f, +140.625f,7.91058f,-210.938f, +144.531f,5.32835f,-210.938f, +148.438f,5.30143f,-210.938f, +152.344f,4.98294f,-210.938f, +156.25f,5.27331f,-210.938f, +160.156f,4.054f,-210.938f, +164.063f,4.25352f,-210.938f, +167.969f,3.60791f,-210.938f, +171.875f,2.94898f,-210.938f, +175.781f,1.97064f,-210.938f, +179.688f,1.21275f,-210.938f, +183.594f,-0.419751f,-210.938f, +187.5f,-1.77221f,-210.938f, +191.406f,-1.94763f,-210.938f, +195.313f,-1.32172f,-210.938f, +199.219f,-1.74453f,-210.938f, +203.125f,-0.694964f,-210.938f, +207.031f,-1.77277f,-210.938f, +210.938f,-2.39571f,-210.938f, +214.844f,-2.61021f,-210.938f, +218.75f,-3.16f,-210.938f, +222.656f,-2.46606f,-210.938f, +226.563f,-0.862086f,-210.938f, +230.469f,1.4487f,-210.938f, +234.375f,3.44239f,-210.938f, +238.281f,5.41949f,-210.938f, +242.188f,6.28416f,-210.938f, +246.094f,7.24993f,-210.938f, +250.0f,10.7227f,-210.938f, +3.90625f,14.284f,-214.844f, +7.8125f,14.031f,-214.844f, +11.7188f,12.8153f,-214.844f, +15.625f,12.2914f,-214.844f, +19.5313f,12.0657f,-214.844f, +23.4375f,12.4452f,-214.844f, +27.3438f,12.703f,-214.844f, +31.25f,12.3401f,-214.844f, +35.1563f,13.2219f,-214.844f, +39.0625f,12.9074f,-214.844f, +42.9688f,12.5934f,-214.844f, +46.875f,11.4717f,-214.844f, +50.7813f,10.548f,-214.844f, +54.6875f,9.43614f,-214.844f, +58.5938f,10.0982f,-214.844f, +62.5f,9.36536f,-214.844f, +66.4063f,8.07196f,-214.844f, +70.3125f,6.4483f,-214.844f, +74.2188f,5.80499f,-214.844f, +78.125f,5.60605f,-214.844f, +82.0313f,6.64906f,-214.844f, +85.9375f,7.64402f,-214.844f, +89.8438f,8.31151f,-214.844f, +93.75f,7.97344f,-214.844f, +97.6563f,5.39549f,-214.844f, +101.563f,3.66809f,-214.844f, +105.469f,3.2001f,-214.844f, +109.375f,5.91373f,-214.844f, +113.281f,7.40339f,-214.844f, +117.188f,8.30807f,-214.844f, +121.094f,9.75774f,-214.844f, +125.0f,10.2383f,-214.844f, +128.906f,10.3408f,-214.844f, +132.813f,10.6262f,-214.844f, +136.719f,10.8818f,-214.844f, +140.625f,9.09087f,-214.844f, +144.531f,6.48291f,-214.844f, +148.438f,5.02116f,-214.844f, +152.344f,5.97543f,-214.844f, +156.25f,6.33053f,-214.844f, +160.156f,5.91049f,-214.844f, +164.063f,5.03025f,-214.844f, +167.969f,5.01201f,-214.844f, +171.875f,4.36222f,-214.844f, +175.781f,3.69208f,-214.844f, +179.688f,2.96539f,-214.844f, +183.594f,1.43789f,-214.844f, +187.5f,-0.374301f,-214.844f, +191.406f,-0.955695f,-214.844f, +195.313f,-0.123769f,-214.844f, +199.219f,-0.113436f,-214.844f, +203.125f,-0.0171993f,-214.844f, +207.031f,-1.0984f,-214.844f, +210.938f,-1.10949f,-214.844f, +214.844f,-1.92471f,-214.844f, +218.75f,-2.26183f,-214.844f, +222.656f,-1.32064f,-214.844f, +226.563f,0.209158f,-214.844f, +230.469f,2.41199f,-214.844f, +234.375f,4.66871f,-214.844f, +238.281f,6.29773f,-214.844f, +242.188f,7.20184f,-214.844f, +246.094f,8.08018f,-214.844f, +250.0f,10.3057f,-214.844f, +3.90625f,13.272f,-218.75f, +7.8125f,12.8218f,-218.75f, +11.7188f,11.8102f,-218.75f, +15.625f,11.7105f,-218.75f, +19.5313f,11.5191f,-218.75f, +23.4375f,12.1253f,-218.75f, +27.3438f,12.0266f,-218.75f, +31.25f,12.3549f,-218.75f, +35.1563f,12.3822f,-218.75f, +39.0625f,12.268f,-218.75f, +42.9688f,12.5022f,-218.75f, +46.875f,11.2878f,-218.75f, +50.7813f,10.1823f,-218.75f, +54.6875f,10.4244f,-218.75f, +58.5938f,10.0047f,-218.75f, +62.5f,9.96061f,-218.75f, +66.4063f,8.64873f,-218.75f, +70.3125f,6.45636f,-218.75f, +74.2188f,5.30254f,-218.75f, +78.125f,5.2915f,-218.75f, +82.0313f,7.2575f,-218.75f, +85.9375f,8.1568f,-218.75f, +89.8438f,8.97514f,-218.75f, +93.75f,7.72908f,-218.75f, +97.6563f,5.41501f,-218.75f, +101.563f,4.24025f,-218.75f, +105.469f,5.39134f,-218.75f, +109.375f,7.69518f,-218.75f, +113.281f,8.87616f,-218.75f, +117.188f,9.44758f,-218.75f, +121.094f,9.21473f,-218.75f, +125.0f,10.1366f,-218.75f, +128.906f,11.6088f,-218.75f, +132.813f,12.0083f,-218.75f, +136.719f,12.3184f,-218.75f, +140.625f,10.8438f,-218.75f, +144.531f,7.65837f,-218.75f, +148.438f,6.07316f,-218.75f, +152.344f,6.4613f,-218.75f, +156.25f,7.01972f,-218.75f, +160.156f,7.25454f,-218.75f, +164.063f,6.31416f,-218.75f, +167.969f,6.48096f,-218.75f, +171.875f,5.89274f,-218.75f, +175.781f,5.71289f,-218.75f, +179.688f,4.3046f,-218.75f, +183.594f,2.49719f,-218.75f, +187.5f,1.16956f,-218.75f, +191.406f,1.21673f,-218.75f, +195.313f,1.19652f,-218.75f, +199.219f,1.27819f,-218.75f, +203.125f,1.06325f,-218.75f, +207.031f,0.133118f,-218.75f, +210.938f,-0.283675f,-218.75f, +214.844f,-0.471323f,-218.75f, +218.75f,-0.941533f,-218.75f, +222.656f,-0.953851f,-218.75f, +226.563f,0.751216f,-218.75f, +230.469f,2.54245f,-218.75f, +234.375f,5.17863f,-218.75f, +238.281f,7.22669f,-218.75f, +242.188f,8.44723f,-218.75f, +246.094f,8.59229f,-218.75f, +250.0f,10.4333f,-218.75f, +3.90625f,13.0199f,-222.656f, +7.8125f,13.1789f,-222.656f, +11.7188f,12.4614f,-222.656f, +15.625f,10.8521f,-222.656f, +19.5313f,11.2552f,-222.656f, +23.4375f,12.1618f,-222.656f, +27.3438f,12.6207f,-222.656f, +31.25f,12.7195f,-222.656f, +35.1563f,12.6379f,-222.656f, +39.0625f,12.5247f,-222.656f, +42.9688f,11.5493f,-222.656f, +46.875f,11.1218f,-222.656f, +50.7813f,11.1036f,-222.656f, +54.6875f,11.2909f,-222.656f, +58.5938f,9.99718f,-222.656f, +62.5f,9.07075f,-222.656f, +66.4063f,7.85904f,-222.656f, +70.3125f,6.00034f,-222.656f, +74.2188f,6.20222f,-222.656f, +78.125f,6.90091f,-222.656f, +82.0313f,8.15724f,-222.656f, +85.9375f,8.92624f,-222.656f, +89.8438f,9.54135f,-222.656f, +93.75f,8.05473f,-222.656f, +97.6563f,5.80654f,-222.656f, +101.563f,5.02178f,-222.656f, +105.469f,7.15584f,-222.656f, +109.375f,8.94755f,-222.656f, +113.281f,9.86631f,-222.656f, +117.188f,10.6421f,-222.656f, +121.094f,10.7891f,-222.656f, +125.0f,11.0716f,-222.656f, +128.906f,12.6376f,-222.656f, +132.813f,12.4373f,-222.656f, +136.719f,12.1143f,-222.656f, +140.625f,11.4028f,-222.656f, +144.531f,8.95242f,-222.656f, +148.438f,6.83012f,-222.656f, +152.344f,7.65217f,-222.656f, +156.25f,8.26579f,-222.656f, +160.156f,7.9665f,-222.656f, +164.063f,7.5217f,-222.656f, +167.969f,7.17758f,-222.656f, +171.875f,5.9966f,-222.656f, +175.781f,5.77514f,-222.656f, +179.688f,4.77675f,-222.656f, +183.594f,3.39545f,-222.656f, +187.5f,2.95911f,-222.656f, +191.406f,1.85368f,-222.656f, +195.313f,1.31365f,-222.656f, +199.219f,1.12622f,-222.656f, +203.125f,1.47676f,-222.656f, +207.031f,1.89446f,-222.656f, +210.938f,0.63056f,-222.656f, +214.844f,0.297565f,-222.656f, +218.75f,-0.0109998f,-222.656f, +222.656f,-0.225082f,-222.656f, +226.563f,0.63258f,-222.656f, +230.469f,2.89831f,-222.656f, +234.375f,5.64839f,-222.656f, +238.281f,7.22414f,-222.656f, +242.188f,7.89951f,-222.656f, +246.094f,8.80151f,-222.656f, +250.0f,10.9602f,-222.656f, +3.90625f,11.9733f,-226.563f, +7.8125f,12.8862f,-226.563f, +11.7188f,12.1283f,-226.563f, +15.625f,10.7234f,-226.563f, +19.5313f,11.6866f,-226.563f, +23.4375f,12.6552f,-226.563f, +27.3438f,12.7353f,-226.563f, +31.25f,11.7992f,-226.563f, +35.1563f,11.2006f,-226.563f, +39.0625f,10.9699f,-226.563f, +42.9688f,10.7653f,-226.563f, +46.875f,10.9947f,-226.563f, +50.7813f,11.2791f,-226.563f, +54.6875f,11.0716f,-226.563f, +58.5938f,10.7092f,-226.563f, +62.5f,9.16355f,-226.563f, +66.4063f,7.59431f,-226.563f, +70.3125f,6.68502f,-226.563f, +74.2188f,6.98133f,-226.563f, +78.125f,7.72239f,-226.563f, +82.0313f,9.00293f,-226.563f, +85.9375f,9.47866f,-226.563f, +89.8438f,8.94458f,-226.563f, +93.75f,7.79648f,-226.563f, +97.6563f,6.07787f,-226.563f, +101.563f,6.60546f,-226.563f, +105.469f,8.5652f,-226.563f, +109.375f,10.2869f,-226.563f, +113.281f,11.4751f,-226.563f, +117.188f,11.6224f,-226.563f, +121.094f,12.0803f,-226.563f, +125.0f,12.5335f,-226.563f, +128.906f,13.5918f,-226.563f, +132.813f,12.9198f,-226.563f, +136.719f,11.521f,-226.563f, +140.625f,10.6418f,-226.563f, +144.531f,8.8393f,-226.563f, +148.438f,8.79941f,-226.563f, +152.344f,9.4929f,-226.563f, +156.25f,9.96206f,-226.563f, +160.156f,8.75524f,-226.563f, +164.063f,7.64157f,-226.563f, +167.969f,7.1963f,-226.563f, +171.875f,6.83929f,-226.563f, +175.781f,6.10665f,-226.563f, +179.688f,4.70473f,-226.563f, +183.594f,4.54758f,-226.563f, +187.5f,3.58616f,-226.563f, +191.406f,2.97998f,-226.563f, +195.313f,1.49179f,-226.563f, +199.219f,1.85834f,-226.563f, +203.125f,1.49089f,-226.563f, +207.031f,1.39949f,-226.563f, +210.938f,0.863002f,-226.563f, +214.844f,1.15546f,-226.563f, +218.75f,0.609373f,-226.563f, +222.656f,1.04332f,-226.563f, +226.563f,1.58038f,-226.563f, +230.469f,4.11549f,-226.563f, +234.375f,5.64696f,-226.563f, +238.281f,6.61687f,-226.563f, +242.188f,7.3113f,-226.563f, +246.094f,8.56955f,-226.563f, +250.0f,10.7891f,-226.563f, +3.90625f,10.4619f,-230.469f, +7.8125f,11.4179f,-230.469f, +11.7188f,10.7841f,-230.469f, +15.625f,10.597f,-230.469f, +19.5313f,10.9999f,-230.469f, +23.4375f,11.5972f,-230.469f, +27.3438f,11.4553f,-230.469f, +31.25f,10.1015f,-230.469f, +35.1563f,10.412f,-230.469f, +39.0625f,9.72694f,-230.469f, +42.9688f,9.71973f,-230.469f, +46.875f,10.7767f,-230.469f, +50.7813f,10.8775f,-230.469f, +54.6875f,10.3186f,-230.469f, +58.5938f,10.4188f,-230.469f, +62.5f,8.94879f,-230.469f, +66.4063f,7.92103f,-230.469f, +70.3125f,8.48295f,-230.469f, +74.2188f,8.74782f,-230.469f, +78.125f,8.87976f,-230.469f, +82.0313f,9.68632f,-230.469f, +85.9375f,9.54993f,-230.469f, +89.8438f,9.04624f,-230.469f, +93.75f,8.49407f,-230.469f, +97.6563f,7.90008f,-230.469f, +101.563f,9.20657f,-230.469f, +105.469f,10.5114f,-230.469f, +109.375f,11.5284f,-230.469f, +113.281f,12.0378f,-230.469f, +117.188f,12.9398f,-230.469f, +121.094f,13.1489f,-230.469f, +125.0f,13.8974f,-230.469f, +128.906f,14.5048f,-230.469f, +132.813f,13.1823f,-230.469f, +136.719f,11.6226f,-230.469f, +140.625f,11.1108f,-230.469f, +144.531f,10.0418f,-230.469f, +148.438f,10.2026f,-230.469f, +152.344f,10.9585f,-230.469f, +156.25f,11.0258f,-230.469f, +160.156f,9.88552f,-230.469f, +164.063f,8.92538f,-230.469f, +167.969f,7.90306f,-230.469f, +171.875f,7.23733f,-230.469f, +175.781f,6.09503f,-230.469f, +179.688f,5.15065f,-230.469f, +183.594f,4.73006f,-230.469f, +187.5f,4.05091f,-230.469f, +191.406f,3.01834f,-230.469f, +195.313f,1.83317f,-230.469f, +199.219f,2.77945f,-230.469f, +203.125f,3.05633f,-230.469f, +207.031f,2.07007f,-230.469f, +210.938f,2.01993f,-230.469f, +214.844f,2.13491f,-230.469f, +218.75f,1.65812f,-230.469f, +222.656f,1.8404f,-230.469f, +226.563f,2.78297f,-230.469f, +230.469f,3.94561f,-230.469f, +234.375f,5.83019f,-230.469f, +238.281f,6.9093f,-230.469f, +242.188f,7.96229f,-230.469f, +246.094f,7.63052f,-230.469f, +250.0f,10.2449f,-230.469f, +3.90625f,8.85224f,-234.375f, +7.8125f,9.40139f,-234.375f, +11.7188f,9.62814f,-234.375f, +15.625f,9.97075f,-234.375f, +19.5313f,9.96073f,-234.375f, +23.4375f,9.70541f,-234.375f, +27.3438f,10.0435f,-234.375f, +31.25f,9.85879f,-234.375f, +35.1563f,9.52681f,-234.375f, +39.0625f,8.75341f,-234.375f, +42.9688f,8.99686f,-234.375f, +46.875f,9.56309f,-234.375f, +50.7813f,9.54486f,-234.375f, +54.6875f,10.0225f,-234.375f, +58.5938f,9.56394f,-234.375f, +62.5f,9.18474f,-234.375f, +66.4063f,9.29208f,-234.375f, +70.3125f,10.4881f,-234.375f, +74.2188f,10.8865f,-234.375f, +78.125f,11.0201f,-234.375f, +82.0313f,11.7722f,-234.375f, +85.9375f,11.1624f,-234.375f, +89.8438f,10.602f,-234.375f, +93.75f,9.93284f,-234.375f, +97.6563f,10.2532f,-234.375f, +101.563f,11.0848f,-234.375f, +105.469f,12.6576f,-234.375f, +109.375f,13.4783f,-234.375f, +113.281f,14.7992f,-234.375f, +117.188f,15.3803f,-234.375f, +121.094f,15.9985f,-234.375f, +125.0f,14.9035f,-234.375f, +128.906f,14.2715f,-234.375f, +132.813f,14.0098f,-234.375f, +136.719f,13.1141f,-234.375f, +140.625f,12.5809f,-234.375f, +144.531f,11.8546f,-234.375f, +148.438f,11.5219f,-234.375f, +152.344f,11.8842f,-234.375f, +156.25f,11.6581f,-234.375f, +160.156f,10.8307f,-234.375f, +164.063f,10.2712f,-234.375f, +167.969f,8.58443f,-234.375f, +171.875f,7.00592f,-234.375f, +175.781f,5.65553f,-234.375f, +179.688f,5.07429f,-234.375f, +183.594f,4.41004f,-234.375f, +187.5f,3.95516f,-234.375f, +191.406f,3.42243f,-234.375f, +195.313f,2.54334f,-234.375f, +199.219f,3.95931f,-234.375f, +203.125f,3.9139f,-234.375f, +207.031f,2.90644f,-234.375f, +210.938f,3.11525f,-234.375f, +214.844f,3.33135f,-234.375f, +218.75f,2.64229f,-234.375f, +222.656f,2.64397f,-234.375f, +226.563f,3.186f,-234.375f, +230.469f,4.46201f,-234.375f, +234.375f,5.92783f,-234.375f, +238.281f,6.79968f,-234.375f, +242.188f,8.7067f,-234.375f, +246.094f,8.47322f,-234.375f, +250.0f,10.3839f,-234.375f, +3.90625f,7.99527f,-238.281f, +7.8125f,8.62199f,-238.281f, +11.7188f,9.06695f,-238.281f, +15.625f,9.12589f,-238.281f, +19.5313f,8.97926f,-238.281f, +23.4375f,9.75152f,-238.281f, +27.3438f,9.58038f,-238.281f, +31.25f,9.30169f,-238.281f, +35.1563f,8.63599f,-238.281f, +39.0625f,8.72973f,-238.281f, +42.9688f,8.49513f,-238.281f, +46.875f,8.78362f,-238.281f, +50.7813f,8.75045f,-238.281f, +54.6875f,8.96186f,-238.281f, +58.5938f,10.0611f,-238.281f, +62.5f,11.1275f,-238.281f, +66.4063f,10.8209f,-238.281f, +70.3125f,12.0108f,-238.281f, +74.2188f,13.2126f,-238.281f, +78.125f,14.1323f,-238.281f, +82.0313f,14.3575f,-238.281f, +85.9375f,13.2781f,-238.281f, +89.8438f,12.8024f,-238.281f, +93.75f,12.0484f,-238.281f, +97.6563f,12.7657f,-238.281f, +101.563f,14.0307f,-238.281f, +105.469f,15.9567f,-238.281f, +109.375f,17.7803f,-238.281f, +113.281f,19.0777f,-238.281f, +117.188f,18.7555f,-238.281f, +121.094f,18.8129f,-238.281f, +125.0f,17.4807f,-238.281f, +128.906f,16.4022f,-238.281f, +132.813f,16.01f,-238.281f, +136.719f,15.1852f,-238.281f, +140.625f,13.9301f,-238.281f, +144.531f,12.8841f,-238.281f, +148.438f,11.7108f,-238.281f, +152.344f,11.414f,-238.281f, +156.25f,11.056f,-238.281f, +160.156f,10.8688f,-238.281f, +164.063f,10.5672f,-238.281f, +167.969f,10.0938f,-238.281f, +171.875f,7.73603f,-238.281f, +175.781f,5.94931f,-238.281f, +179.688f,5.51512f,-238.281f, +183.594f,5.27449f,-238.281f, +187.5f,4.94763f,-238.281f, +191.406f,4.13161f,-238.281f, +195.313f,3.59426f,-238.281f, +199.219f,4.03163f,-238.281f, +203.125f,4.38188f,-238.281f, +207.031f,3.09959f,-238.281f, +210.938f,3.1766f,-238.281f, +214.844f,3.05715f,-238.281f, +218.75f,3.20329f,-238.281f, +222.656f,2.53565f,-238.281f, +226.563f,3.1275f,-238.281f, +230.469f,4.54736f,-238.281f, +234.375f,5.9361f,-238.281f, +238.281f,6.99977f,-238.281f, +242.188f,8.20813f,-238.281f, +246.094f,9.56614f,-238.281f, +250.0f,11.4751f,-238.281f, +3.90625f,6.40337f,-242.188f, +7.8125f,7.88741f,-242.188f, +11.7188f,8.60661f,-242.188f, +15.625f,8.56923f,-242.188f, +19.5313f,8.60588f,-242.188f, +23.4375f,8.63232f,-242.188f, +27.3438f,8.3446f,-242.188f, +31.25f,7.50857f,-242.188f, +35.1563f,7.64026f,-242.188f, +39.0625f,7.75851f,-242.188f, +42.9688f,7.56672f,-242.188f, +46.875f,7.98994f,-242.188f, +50.7813f,9.62391f,-242.188f, +54.6875f,9.28711f,-242.188f, +58.5938f,10.3792f,-242.188f, +62.5f,11.2793f,-242.188f, +66.4063f,12.3048f,-242.188f, +70.3125f,13.5272f,-242.188f, +74.2188f,14.5101f,-242.188f, +78.125f,15.2091f,-242.188f, +82.0313f,15.9007f,-242.188f, +85.9375f,15.4601f,-242.188f, +89.8438f,14.5171f,-242.188f, +93.75f,14.2266f,-242.188f, +97.6563f,13.9558f,-242.188f, +101.563f,15.8234f,-242.188f, +105.469f,18.6741f,-242.188f, +109.375f,20.7296f,-242.188f, +113.281f,21.5353f,-242.188f, +117.188f,20.9821f,-242.188f, +121.094f,20.2232f,-242.188f, +125.0f,18.5423f,-242.188f, +128.906f,17.8591f,-242.188f, +132.813f,17.6716f,-242.188f, +136.719f,16.8982f,-242.188f, +140.625f,14.8574f,-242.188f, +144.531f,13.0736f,-242.188f, +148.438f,12.4847f,-242.188f, +152.344f,11.8101f,-242.188f, +156.25f,11.7863f,-242.188f, +160.156f,11.4288f,-242.188f, +164.063f,10.8653f,-242.188f, +167.969f,9.75951f,-242.188f, +171.875f,8.13212f,-242.188f, +175.781f,6.91851f,-242.188f, +179.688f,5.93418f,-242.188f, +183.594f,5.79732f,-242.188f, +187.5f,5.8082f,-242.188f, +191.406f,4.85116f,-242.188f, +195.313f,4.2744f,-242.188f, +199.219f,4.23009f,-242.188f, +203.125f,3.99841f,-242.188f, +207.031f,3.48205f,-242.188f, +210.938f,3.71102f,-242.188f, +214.844f,3.52803f,-242.188f, +218.75f,3.41263f,-242.188f, +222.656f,2.40768f,-242.188f, +226.563f,3.40111f,-242.188f, +230.469f,4.51594f,-242.188f, +234.375f,5.96131f,-242.188f, +238.281f,7.68646f,-242.188f, +242.188f,8.54536f,-242.188f, +246.094f,9.49379f,-242.188f, +250.0f,12.0532f,-242.188f, +3.90625f,6.09425f,-246.094f, +7.8125f,7.62532f,-246.094f, +11.7188f,8.33141f,-246.094f, +15.625f,8.6172f,-246.094f, +19.5313f,8.7607f,-246.094f, +23.4375f,7.89699f,-246.094f, +27.3438f,7.77868f,-246.094f, +31.25f,7.41037f,-246.094f, +35.1563f,6.57203f,-246.094f, +39.0625f,6.31554f,-246.094f, +42.9688f,7.72481f,-246.094f, +46.875f,8.88325f,-246.094f, +50.7813f,10.0433f,-246.094f, +54.6875f,10.7945f,-246.094f, +58.5938f,11.7506f,-246.094f, +62.5f,13.1397f,-246.094f, +66.4063f,13.1294f,-246.094f, +70.3125f,14.8885f,-246.094f, +74.2188f,15.5444f,-246.094f, +78.125f,16.4867f,-246.094f, +82.0313f,17.0601f,-246.094f, +85.9375f,17.2351f,-246.094f, +89.8438f,16.4292f,-246.094f, +93.75f,16.32f,-246.094f, +97.6563f,17.0323f,-246.094f, +101.563f,17.5524f,-246.094f, +105.469f,20.0544f,-246.094f, +109.375f,21.7596f,-246.094f, +113.281f,22.3401f,-246.094f, +117.188f,22.7891f,-246.094f, +121.094f,21.705f,-246.094f, +125.0f,20.4875f,-246.094f, +128.906f,19.3013f,-246.094f, +132.813f,18.5254f,-246.094f, +136.719f,17.4179f,-246.094f, +140.625f,14.7663f,-246.094f, +144.531f,13.8915f,-246.094f, +148.438f,12.0594f,-246.094f, +152.344f,11.8343f,-246.094f, +156.25f,12.3176f,-246.094f, +160.156f,12.7287f,-246.094f, +164.063f,10.9779f,-246.094f, +167.969f,10.1928f,-246.094f, +171.875f,8.20833f,-246.094f, +175.781f,7.71383f,-246.094f, +179.688f,7.59678f,-246.094f, +183.594f,6.98083f,-246.094f, +187.5f,6.81055f,-246.094f, +191.406f,6.13881f,-246.094f, +195.313f,4.42472f,-246.094f, +199.219f,3.97044f,-246.094f, +203.125f,4.06157f,-246.094f, +207.031f,3.73524f,-246.094f, +210.938f,4.45121f,-246.094f, +214.844f,3.42347f,-246.094f, +218.75f,2.70444f,-246.094f, +222.656f,3.88027f,-246.094f, +226.563f,4.53456f,-246.094f, +230.469f,5.69259f,-246.094f, +234.375f,6.23366f,-246.094f, +238.281f,7.38965f,-246.094f, +242.188f,8.96481f,-246.094f, +246.094f,10.9805f,-246.094f, +250.0f,13.0168f,-246.094f, +3.90625f,6.31953f,-250.0f, +7.8125f,6.89279f,-250.0f, +11.7188f,8.63362f,-250.0f, +15.625f,9.28278f,-250.0f, +19.5313f,9.05374f,-250.0f, +23.4375f,8.51295f,-250.0f, +27.3438f,8.2676f,-250.0f, +31.25f,7.86717f,-250.0f, +35.1563f,6.56073f,-250.0f, +39.0625f,6.77605f,-250.0f, +42.9688f,8.67577f,-250.0f, +46.875f,10.2384f,-250.0f, +50.7813f,11.5086f,-250.0f, +54.6875f,12.7259f,-250.0f, +58.5938f,14.4625f,-250.0f, +62.5f,15.7352f,-250.0f, +66.4063f,15.1953f,-250.0f, +70.3125f,16.1585f,-250.0f, +74.2188f,17.1058f,-250.0f, +78.125f,17.3014f,-250.0f, +82.0313f,18.6932f,-250.0f, +85.9375f,18.6138f,-250.0f, +89.8438f,18.0431f,-250.0f, +93.75f,18.293f,-250.0f, +97.6563f,18.5338f,-250.0f, +101.563f,18.8033f,-250.0f, +105.469f,22.2037f,-250.0f, +109.375f,24.04f,-250.0f, +113.281f,24.711f,-250.0f, +117.188f,24.2801f,-250.0f, +121.094f,23.1052f,-250.0f, +125.0f,21.9886f,-250.0f, +128.906f,21.2657f,-250.0f, +132.813f,19.5364f,-250.0f, +136.719f,18.5278f,-250.0f, +140.625f,15.9806f,-250.0f, +144.531f,14.8577f,-250.0f, +148.438f,13.3645f,-250.0f, +152.344f,12.8082f,-250.0f, +156.25f,13.3689f,-250.0f, +160.156f,12.7449f,-250.0f, +164.063f,11.1108f,-250.0f, +167.969f,9.59991f,-250.0f, +171.875f,8.88472f,-250.0f, +175.781f,8.39035f,-250.0f, +179.688f,7.9163f,-250.0f, +183.594f,7.4118f,-250.0f, +187.5f,6.98082f,-250.0f, +191.406f,7.20793f,-250.0f, +195.313f,6.19875f,-250.0f, +199.219f,4.05745f,-250.0f, +203.125f,4.65884f,-250.0f, +207.031f,3.75824f,-250.0f, +210.938f,4.17504f,-250.0f, +214.844f,4.37516f,-250.0f, +218.75f,4.69345f,-250.0f, +222.656f,5.87678f,-250.0f, +226.563f,6.28295f,-250.0f, +230.469f,7.2125f,-250.0f, +234.375f,7.55925f,-250.0f, +238.281f,7.93922f,-250.0f, +242.188f,9.87332f,-250.0f, +246.094f,11.5957f,-250.0f, +250.0f,13.3418f,-250.0f, +}; + +btScalar Landscape07Nml[] = { +0.163295f,0.951018f,0.262487f, +0.144468f,0.954269f,0.261724f, +0.284339f,0.929979f,0.233003f, +0.211332f,0.959058f,0.188537f, +0.433374f,0.893306f,0.11913f, +0.363648f,0.930033f,0.052906f, +0.467682f,0.883824f,-0.0113249f, +0.383618f,0.915858f,-0.118494f, +0.389479f,0.919494f,-0.0532637f, +0.409514f,0.907723f,-0.0913076f, +0.332107f,0.943241f,-0.00112667f, +0.268223f,0.935541f,-0.229827f, +0.254548f,0.967046f,-0.0051751f, +0.306606f,0.933957f,-0.183623f, +0.282468f,0.956486f,0.073117f, +0.352033f,0.935268f,0.0366899f, +0.28404f,0.958651f,0.0175868f, +0.303901f,0.947745f,0.0970751f, +0.36555f,0.930735f,0.0102418f, +0.393208f,0.907605f,0.147107f, +0.468517f,0.882377f,0.0436299f, +0.45621f,0.884295f,0.0994741f, +0.387946f,0.921329f,0.0254982f, +0.35572f,0.93034f,0.0890492f, +-0.0727074f,0.997226f,-0.0159048f, +0.0416391f,0.981376f,0.187527f, +-0.216733f,0.958137f,0.187084f, +-0.0894435f,0.917028f,0.388664f, +-0.0768893f,0.966885f,0.243356f, +-0.0850782f,0.918088f,0.387139f, +-0.0500426f,0.973558f,0.222893f, +-0.133165f,0.955198f,0.264319f, +-0.123001f,0.980349f,0.154228f, +-0.136539f,0.958129f,0.251685f, +-0.132627f,0.981796f,0.135965f, +-0.174651f,0.968606f,0.176918f, +-0.259357f,0.958248f,0.120395f, +-0.298496f,0.949786f,0.0938444f, +-0.287382f,0.955091f,0.0721996f, +-0.350088f,0.936687f,-0.00747904f, +-0.148232f,0.988935f,-0.00587251f, +-0.126386f,0.991686f,0.0242043f, +-0.0549856f,0.99804f,0.0298927f, +-0.061356f,0.998107f,0.00430538f, +-0.205447f,0.97828f,0.0275574f, +-0.222811f,0.974816f,-0.00939735f, +-0.192208f,0.981343f,0.00477232f, +-0.179009f,0.983825f,-0.00666687f, +-0.0670729f,0.997581f,0.0182672f, +-0.127994f,0.990724f,-0.0456448f, +-0.132352f,0.983294f,-0.124961f, +-0.16906f,0.976471f,-0.133875f, +0.0163433f,0.992538f,-0.120836f, +0.061026f,0.995929f,-0.0663405f, +0.133906f,0.98909f,-0.0613958f, +0.0943148f,0.983776f,-0.152607f, +0.150352f,0.985874f,-0.0738065f, +0.100217f,0.972528f,-0.210109f, +0.174622f,0.974275f,-0.142462f, +0.154561f,0.962801f,-0.221644f, +0.214773f,0.96191f,-0.169122f, +0.258606f,0.948184f,-0.184582f, +0.352689f,0.932616f,-0.0764078f, +0.422646f,0.906225f,0.0112396f, +0.443105f,0.890896f,-0.0998108f, +0.401063f,0.915401f,-0.0344995f, +0.415945f,0.889086f,-0.19109f, +0.396075f,0.910803f,-0.116459f, +0.504361f,0.849207f,-0.15642f, +0.465554f,0.866637f,-0.179442f, +0.527872f,0.824305f,-0.204628f, +0.465951f,0.840148f,-0.277561f, +0.474007f,0.822715f,-0.31378f, +0.361245f,0.837173f,-0.410663f, +0.405138f,0.793126f,-0.454769f, +0.304965f,0.772294f,-0.557277f, +0.421648f,0.811214f,-0.405148f, +0.482203f,0.762506f,-0.431353f, +0.478963f,0.817038f,-0.321005f, +0.485062f,0.781955f,-0.391486f, +0.478205f,0.82345f,-0.305368f, +0.426707f,0.781297f,-0.455518f, +0.428677f,0.841565f,-0.32864f, +0.430024f,0.798188f,-0.421871f, +0.423016f,0.835924f,-0.349699f, +0.437416f,0.818455f,-0.372557f, +0.461522f,0.813116f,-0.354739f, +0.446182f,0.808887f,-0.382915f, +0.507869f,0.791896f,-0.339072f, +0.474665f,0.780232f,-0.407346f, +0.494125f,0.792543f,-0.357373f, +0.430265f,0.769469f,-0.472006f, +0.389469f,0.809375f,-0.439574f, +0.38782f,0.781711f,-0.488389f, +0.349938f,0.837293f,-0.4201f, +0.417236f,0.816738f,-0.398564f, +0.440298f,0.822173f,-0.360789f, +0.490994f,0.819158f,-0.296487f, +0.379279f,0.852728f,-0.359169f, +0.3675f,0.860963f,-0.351692f, +0.122152f,0.892865f,-0.433442f, +0.135293f,0.922235f,-0.362185f, +0.188083f,0.883941f,-0.428104f, +0.194653f,0.9204f,-0.339078f, +0.200053f,0.870677f,-0.449332f, +0.149584f,0.899445f,-0.410639f, +0.170948f,0.845446f,-0.505962f, +0.0834541f,0.848059f,-0.523289f, +0.233208f,0.811352f,-0.536024f, +0.246347f,0.822898f,-0.512008f, +0.0429626f,0.875995f,-0.480403f, +0.171623f,0.870482f,-0.461311f, +-0.202408f,0.938053f,-0.281226f, +-0.0831604f,0.960463f,-0.265698f, +-0.312635f,0.912112f,-0.265162f, +-0.344362f,0.89728f,-0.276231f, +-0.0852182f,0.932714f,-0.350403f, +-0.156991f,0.922287f,-0.353185f, +0.0213728f,0.893503f,-0.448548f, +-0.0577934f,0.860578f,-0.506029f, +-0.0250381f,0.886654f,-0.461755f, +-0.0319956f,0.87749f,-0.478526f, +-0.0302913f,0.865602f,-0.499816f, +-0.00892741f,0.865625f,-0.500613f, +0.0556557f,0.906734f,-0.418015f, +0.137632f,0.905698f,-0.400959f, +0.0276894f,0.926625f,-0.374965f, +0.074566f,0.927887f,-0.365329f, +0.0588963f,0.991806f,0.113367f, +0.300045f,0.940314f,0.160571f, +0.505162f,0.858812f,0.0851652f, +0.523651f,0.851407f,0.0299276f, +0.336751f,0.940492f,0.0455315f, +0.231254f,0.960478f,0.15493f, +0.265257f,0.945144f,0.190637f, +0.327138f,0.941822f,0.0771526f, +0.406507f,0.912216f,-0.0511354f, +0.398687f,0.900126f,-0.17556f, +0.399875f,0.884983f,-0.238547f, +0.421808f,0.899838f,-0.11122f, +-0.041369f,0.987502f,-0.152078f, +-0.327111f,0.932019f,-0.156008f, +-0.143307f,0.985559f,-0.0902006f, +-0.0270205f,0.999466f,0.0183744f, +-0.0836031f,0.996473f,-0.00727851f, +-0.153499f,0.988141f,-0.00380883f, +-0.269657f,0.962702f,0.0221269f, +-0.220011f,0.975241f,-0.0223422f, +-0.104184f,0.990611f,-0.0885198f, +-0.112376f,0.99176f,-0.0615135f, +-0.176142f,0.984186f,-0.0187604f, +-0.211815f,0.974306f,-0.076572f, +-0.0254097f,0.999559f,-0.0153608f, +-0.0364109f,0.99734f,-0.0631393f, +-0.0203648f,0.999538f,-0.0225481f, +0.0549873f,0.998448f,0.00884961f, +0.169599f,0.985346f,0.0181241f, +0.253148f,0.96653f,-0.0416731f, +0.241207f,0.963047f,-0.119834f, +0.334221f,0.932038f,-0.140004f, +0.510774f,0.849501f,-0.132124f, +0.446103f,0.866333f,-0.224633f, +0.443332f,0.853241f,-0.274658f, +0.556199f,0.799442f,-0.227011f, +0.56349f,0.790862f,-0.238781f, +0.469847f,0.819465f,-0.32821f, +0.384148f,0.843359f,-0.375735f, +0.405196f,0.828658f,-0.386189f, +0.451519f,0.832227f,-0.321758f, +0.460293f,0.845627f,-0.27027f, +0.479361f,0.841341f,-0.249716f, +0.486527f,0.832565f,-0.264815f, +0.505678f,0.817374f,-0.276024f, +0.532701f,0.792427f,-0.297134f, +0.419998f,0.832504f,-0.361301f, +0.381252f,0.872209f,-0.306428f, +0.441269f,0.820876f,-0.362552f, +0.40003f,0.811169f,-0.426593f, +0.192925f,0.829083f,-0.524786f, +0.183969f,0.805942f,-0.562684f, +0.196671f,0.822252f,-0.534063f, +0.210296f,0.820946f,-0.530871f, +0.203797f,0.82129f,-0.532869f, +-0.110131f,0.879911f,-0.462199f, +-0.313522f,0.874849f,-0.369247f, +-0.225349f,0.894153f,-0.386922f, +-0.0425073f,0.90311f,-0.4273f, +0.0811921f,0.929959f,-0.358587f, +-0.0097083f,0.913772f,-0.406111f, +-0.0203212f,0.916094f,-0.400448f, +-0.0594319f,0.92652f,-0.371521f, +-0.0269889f,0.956838f,-0.289365f, +0.0349749f,0.98646f,-0.160231f, +0.256968f,0.956769f,-0.13624f, +0.548943f,0.832681f,-0.0728256f, +0.489119f,0.868806f,-0.0770563f, +0.299363f,0.954014f,0.0154449f, +0.150669f,0.988307f,0.0233966f, +0.338483f,0.938561f,0.0673226f, +0.470525f,0.880363f,-0.0597344f, +0.482272f,0.850276f,-0.210818f, +0.467725f,0.834993f,-0.289861f, +0.394888f,0.866151f,-0.306343f, +0.253937f,0.935832f,-0.244407f, +-0.00400266f,0.994244f,-0.107062f, +-0.309146f,0.937501f,-0.15975f, +-0.226806f,0.957844f,-0.176334f, +-0.122632f,0.982531f,-0.139981f, +-0.0635605f,0.992861f,-0.10093f, +-0.151586f,0.973622f,-0.170534f, +-0.231525f,0.948656f,-0.215516f, +-0.166237f,0.951792f,-0.257795f, +-0.0869197f,0.960928f,-0.262798f, +-0.164573f,0.950876f,-0.262203f, +-0.167249f,0.963013f,-0.211268f, +-0.211402f,0.954271f,-0.211366f, +-0.0642089f,0.988782f,-0.134861f, +-0.0696806f,0.987799f,-0.139279f, +-0.124243f,0.98904f,-0.0797755f, +0.0962393f,0.995288f,-0.0118021f, +0.210783f,0.972894f,-0.0951158f, +0.297355f,0.950074f,-0.0945467f, +0.301001f,0.949737f,-0.0860135f, +0.352321f,0.929179f,-0.111785f, +0.488103f,0.867307f,-0.0976422f, +0.556803f,0.828121f,-0.0646904f, +0.522997f,0.817722f,-0.240427f, +0.526158f,0.791225f,-0.311642f, +0.539548f,0.783883f,-0.30727f, +0.519736f,0.798926f,-0.302643f, +0.456854f,0.816569f,-0.352845f, +0.429557f,0.807438f,-0.404381f, +0.403588f,0.823842f,-0.397997f, +0.363835f,0.833866f,-0.415079f, +0.411515f,0.83345f,-0.368804f, +0.472303f,0.812756f,-0.341113f, +0.520866f,0.78709f,-0.330436f, +0.571303f,0.758641f,-0.313172f, +0.364947f,0.85616f,-0.365791f, +0.334117f,0.892356f,-0.303424f, +0.531373f,0.790182f,-0.305376f, +0.490437f,0.768139f,-0.411624f, +0.28549f,0.798709f,-0.529679f, +0.166173f,0.802828f,-0.572585f, +0.142862f,0.826392f,-0.544671f, +0.199443f,0.816751f,-0.541424f, +0.128075f,0.851947f,-0.507724f, +-0.168704f,0.879688f,-0.444621f, +-0.244755f,0.842741f,-0.479461f, +-0.150804f,0.809643f,-0.567218f, +-0.142654f,0.804501f,-0.576565f, +-0.00468689f,0.885234f,-0.465123f, +-0.00403137f,0.903548f,-0.428468f, +-0.0506207f,0.931001f,-0.361489f, +-0.153442f,0.941817f,-0.299058f, +-0.162811f,0.972443f,-0.166875f, +0.109587f,0.934225f,-0.339431f, +0.212963f,0.908729f,-0.358967f, +0.490721f,0.837065f,-0.2419f, +0.423339f,0.87185f,-0.246298f, +0.265687f,0.948953f,-0.169996f, +0.19754f,0.959782f,-0.199488f, +0.295591f,0.918793f,-0.261622f, +0.531499f,0.826018f,-0.187622f, +0.59212f,0.773761f,-0.225139f, +0.430882f,0.823206f,-0.369692f, +0.346812f,0.896722f,-0.274977f, +0.157001f,0.944818f,-0.287523f, +-0.0770972f,0.974843f,-0.209133f, +-0.291803f,0.93708f,-0.191656f, +-0.196019f,0.961744f,-0.191378f, +-0.131765f,0.96396f,-0.231124f, +-0.0745388f,0.982069f,-0.173159f, +0.00914064f,0.98959f,-0.143621f, +-0.138284f,0.94748f,-0.288373f, +-0.221669f,0.91917f,-0.325561f, +-0.129149f,0.970549f,-0.203358f, +-0.130482f,0.980721f,-0.145466f, +-0.176902f,0.951987f,-0.249854f, +-0.247465f,0.916992f,-0.31287f, +-0.158128f,0.953184f,-0.25775f, +-0.0356987f,0.985511f,-0.165812f, +-0.125849f,0.96636f,-0.224301f, +0.0681695f,0.96619f,-0.248655f, +0.227225f,0.953018f,-0.200315f, +0.225952f,0.967572f,-0.112919f, +0.287704f,0.957355f,-0.0264129f, +0.36102f,0.928385f,-0.0881278f, +0.475672f,0.87145f,-0.119627f, +0.569214f,0.81507f,-0.107964f, +0.623663f,0.769908f,-0.13523f, +0.603105f,0.773542f,-0.19467f, +0.556766f,0.776509f,-0.295034f, +0.523993f,0.789717f,-0.319025f, +0.458736f,0.810878f,-0.36337f, +0.42608f,0.838013f,-0.340867f, +0.413816f,0.852215f,-0.320134f, +0.428047f,0.839676f,-0.334247f, +0.440545f,0.806668f,-0.393963f, +0.471664f,0.754066f,-0.457075f, +0.438131f,0.75533f,-0.487358f, +0.513035f,0.778713f,-0.361111f, +0.362236f,0.865985f,-0.344753f, +0.319311f,0.872794f,-0.36915f, +0.546544f,0.761872f,-0.347621f, +0.587841f,0.74763f,-0.309017f, +0.346001f,0.792234f,-0.502642f, +0.160837f,0.807416f,-0.567637f, +0.137348f,0.82025f,-0.555271f, +0.177955f,0.827144f,-0.533071f, +0.0951091f,0.870125f,-0.483567f, +-0.154432f,0.835911f,-0.526691f, +-0.124368f,0.808763f,-0.574834f, +-0.126819f,0.782715f,-0.609323f, +-0.137751f,0.811099f,-0.568456f, +-0.111652f,0.799108f,-0.590729f, +-0.083265f,0.829705f,-0.551957f, +-0.187386f,0.858237f,-0.477825f, +-0.293723f,0.918982f,-0.263055f, +-0.393626f,0.913021f,-0.107009f, +0.212209f,0.950224f,-0.228125f, +0.209499f,0.936607f,-0.280851f, +0.442676f,0.872148f,-0.208317f, +0.471617f,0.857429f,-0.205893f, +0.203873f,0.890799f,-0.406094f, +0.238352f,0.874506f,-0.422408f, +0.316589f,0.834877f,-0.45028f, +0.439788f,0.802413f,-0.403384f, +0.591147f,0.75018f,-0.29627f, +0.446858f,0.837414f,-0.314732f, +0.297014f,0.892204f,-0.340228f, +0.174626f,0.914769f,-0.364286f, +-0.105816f,0.915255f,-0.388731f, +-0.264967f,0.884964f,-0.382925f, +-0.17731f,0.909999f,-0.374785f, +-0.129483f,0.910653f,-0.39236f, +-0.183919f,0.912509f,-0.365379f, +-0.0547605f,0.971103f,-0.232295f, +-0.0329197f,0.988161f,-0.149845f, +-0.283679f,0.94023f,-0.188398f, +-0.271484f,0.961222f,-0.0484715f, +-0.126156f,0.992006f,-0.00297784f, +-0.0077445f,0.99412f,-0.10801f, +-0.122479f,0.952558f,-0.278626f, +-0.22816f,0.898995f,-0.373834f, +-0.116624f,0.94701f,-0.299285f, +-0.0338322f,0.962019f,-0.270876f, +0.0643125f,0.93366f,-0.352339f, +0.108033f,0.951056f,-0.28952f, +0.0914872f,0.981979f,-0.165373f, +0.260441f,0.963994f,-0.0537291f, +0.448443f,0.892711f,-0.0443492f, +0.523825f,0.846692f,-0.0933822f, +0.566469f,0.810587f,-0.148532f, +0.615421f,0.777098f,-0.131818f, +0.641634f,0.7586f,-0.11328f, +0.626845f,0.758026f,-0.180172f, +0.575952f,0.768546f,-0.278596f, +0.455289f,0.793648f,-0.403527f, +0.401888f,0.827012f,-0.393113f, +0.390072f,0.829628f,-0.399451f, +0.432707f,0.817098f,-0.380939f, +0.498394f,0.785084f,-0.367759f, +0.54453f,0.759415f,-0.356056f, +0.443321f,0.820621f,-0.360621f, +0.413861f,0.828476f,-0.377289f, +0.394054f,0.852433f,-0.343626f, +0.354186f,0.831754f,-0.427477f, +0.501406f,0.754246f,-0.423916f, +0.58911f,0.726277f,-0.354219f, +0.489087f,0.757568f,-0.432301f, +0.219144f,0.803913f,-0.552901f, +0.0950257f,0.808184f,-0.581213f, +0.0824554f,0.830823f,-0.550395f, +0.0933748f,0.860985f,-0.499987f, +-0.0248456f,0.850125f,-0.525994f, +-0.102917f,0.824622f,-0.556243f, +-0.137975f,0.843048f,-0.519839f, +-0.191841f,0.811585f,-0.551839f, +-0.0960986f,0.833755f,-0.543707f, +-0.122745f,0.850064f,-0.512177f, +-0.326981f,0.870361f,-0.368177f, +-0.538824f,0.830097f,-0.143558f, +-0.554748f,0.831168f,0.0375988f, +0.183636f,0.945911f,-0.267453f, +0.248003f,0.941284f,-0.229083f, +0.367193f,0.90606f,-0.210295f, +0.559963f,0.826078f,-0.0635307f, +0.486301f,0.848236f,-0.209779f, +0.313552f,0.830527f,-0.460336f, +0.26103f,0.794184f,-0.548758f, +0.384376f,0.78311f,-0.488869f, +0.479781f,0.77201f,-0.416905f, +0.481011f,0.825397f,-0.295547f, +0.281884f,0.886831f,-0.366158f, +0.202383f,0.940438f,-0.273162f, +-0.0238314f,0.938511f,-0.344426f, +-0.257973f,0.859678f,-0.440913f, +-0.194719f,0.873936f,-0.445332f, +-0.0838372f,0.877697f,-0.471825f, +-0.223876f,0.839024f,-0.495901f, +-0.216019f,0.888182f,-0.405548f, +-0.127765f,0.960438f,-0.247457f, +-0.306436f,0.940762f,-0.145138f, +-0.327317f,0.939981f,-0.096429f, +-0.0557083f,0.990847f,-0.122959f, +0.0995056f,0.975129f,-0.198043f, +0.0247654f,0.966343f,-0.256062f, +-0.1694f,0.916546f,-0.362281f, +-0.197841f,0.908709f,-0.367568f, +-0.0185126f,0.95561f,-0.294052f, +0.0824185f,0.951583f,-0.296138f, +0.0241627f,0.96387f,-0.265277f, +0.0355962f,0.964767f,-0.260688f, +0.155357f,0.948871f,-0.274788f, +0.403654f,0.905713f,-0.129414f, +0.540931f,0.838513f,-0.0654957f, +0.603296f,0.79305f,-0.0842943f, +0.615316f,0.778563f,-0.123395f, +0.650635f,0.750663f,-0.114799f, +0.681129f,0.712532f,-0.16841f, +0.640077f,0.706799f,-0.301225f, +0.501905f,0.776085f,-0.381816f, +0.395956f,0.833034f,-0.386359f, +0.40448f,0.824611f,-0.39549f, +0.410354f,0.816219f,-0.406689f, +0.470853f,0.807605f,-0.355065f, +0.489936f,0.812779f,-0.315203f, +0.459069f,0.843316f,-0.279417f, +0.469145f,0.829489f,-0.303069f, +0.440235f,0.819159f,-0.367657f, +0.420347f,0.792019f,-0.442734f, +0.528602f,0.735131f,-0.424456f, +0.540602f,0.708419f,-0.453752f, +0.493287f,0.777492f,-0.390095f, +0.304413f,0.86604f,-0.396619f, +0.0820709f,0.870144f,-0.485916f, +0.0884612f,0.883073f,-0.460823f, +0.0898563f,0.860973f,-0.500651f, +-0.0421635f,0.844727f,-0.533535f, +-0.161922f,0.847271f,-0.505878f, +-0.14449f,0.888235f,-0.436074f, +-0.171293f,0.877903f,-0.447153f, +-0.137238f,0.90321f,-0.406666f, +-0.254069f,0.918554f,-0.302831f, +-0.505168f,0.843216f,-0.183829f, +-0.675277f,0.734237f,-0.069976f, +-0.653992f,0.755215f,0.0440947f, +0.0555085f,0.890635f,-0.451319f, +0.137334f,0.909799f,-0.39167f, +0.308301f,0.903589f,-0.297451f, +0.471952f,0.852104f,-0.226231f, +0.566013f,0.811602f,-0.144679f, +0.544915f,0.811135f,-0.212433f, +0.36963f,0.829124f,-0.419437f, +0.344038f,0.821377f,-0.454948f, +0.421617f,0.811326f,-0.404955f, +0.42674f,0.823996f,-0.372724f, +0.214619f,0.881696f,-0.42018f, +0.0910032f,0.951585f,-0.293606f, +0.0846967f,0.975495f,-0.203065f, +-0.12731f,0.949549f,-0.286616f, +-0.203708f,0.900619f,-0.383912f, +-0.0136138f,0.94578f,-0.324521f, +-0.1774f,0.907831f,-0.379963f, +-0.319591f,0.828051f,-0.460644f, +-0.309551f,0.868477f,-0.387202f, +-0.350068f,0.908991f,-0.226245f, +-0.314996f,0.908797f,-0.273615f, +-0.0601423f,0.962735f,-0.263674f, +0.136393f,0.973573f,-0.183175f, +0.0532739f,0.976623f,-0.208255f, +-0.105007f,0.973025f,-0.205419f, +-0.20872f,0.948662f,-0.237649f, +-0.0905915f,0.950284f,-0.297915f, +0.0475864f,0.961005f,-0.272405f, +0.0362517f,0.97079f,-0.237174f, +0.105725f,0.948531f,-0.298516f, +0.162566f,0.915122f,-0.368949f, +0.273546f,0.895769f,-0.350385f, +0.484941f,0.844255f,-0.228179f, +0.616479f,0.776457f,-0.130645f, +0.628311f,0.758456f,-0.173119f, +0.646758f,0.730427f,-0.2195f, +0.713832f,0.657703f,-0.240564f, +0.670883f,0.685042f,-0.283959f, +0.484582f,0.813502f,-0.32155f, +0.374759f,0.869215f,-0.322522f, +0.442437f,0.844514f,-0.301738f, +0.417442f,0.841211f,-0.343666f, +0.423405f,0.844004f,-0.329219f, +0.51768f,0.821209f,-0.240049f, +0.452859f,0.851327f,-0.264878f, +0.509187f,0.825405f,-0.243796f, +0.514747f,0.798114f,-0.313129f, +0.470791f,0.788824f,-0.395111f, +0.531455f,0.747848f,-0.397843f, +0.533283f,0.783064f,-0.32003f, +0.426956f,0.884256f,-0.18921f, +0.350467f,0.920762f,-0.171379f, +0.166727f,0.944055f,-0.284537f, +0.0641204f,0.940994f,-0.332292f, +0.176576f,0.941646f,-0.286573f, +0.033479f,0.945913f,-0.322688f, +-0.166217f,0.885456f,-0.433982f, +-0.211415f,0.849321f,-0.483692f, +-0.245686f,0.873508f,-0.420264f, +-0.318583f,0.913339f,-0.253606f, +-0.37482f,0.927017f,-0.0122188f, +-0.519112f,0.853899f,0.0371293f, +-0.674751f,0.732141f,-0.0931649f, +-0.717847f,0.685588f,-0.121095f, +0.129526f,0.933398f,-0.33465f, +0.109756f,0.909727f,-0.400439f, +0.235187f,0.88528f,-0.401206f, +0.43527f,0.839228f,-0.32594f, +0.509145f,0.799028f,-0.319883f, +0.559944f,0.774395f,-0.294577f, +0.481154f,0.808934f,-0.337812f, +0.346903f,0.826321f,-0.443681f, +0.419785f,0.810323f,-0.408849f, +0.424579f,0.803602f,-0.417081f, +0.213763f,0.882039f,-0.419896f, +-0.065439f,0.903315f,-0.423958f, +-0.0365788f,0.953894f,-0.297908f, +-0.052968f,0.984136f,-0.169324f, +-0.178873f,0.950393f,-0.254476f, +-0.13588f,0.955299f,-0.262566f, +-0.0549577f,0.986053f,-0.157096f, +-0.250853f,0.921347f,-0.296972f, +-0.383387f,0.86801f,-0.31555f, +-0.39517f,0.874494f,-0.281248f, +-0.297344f,0.903399f,-0.308961f, +-0.146671f,0.942034f,-0.301762f, +0.0292749f,0.969498f,-0.243343f, +0.0315554f,0.994938f,-0.0954108f, +-0.135353f,0.99076f,0.00864549f, +-0.109362f,0.993969f,-0.00807889f, +0.00178341f,0.978683f,-0.205368f, +0.0583577f,0.951175f,-0.303086f, +0.0448944f,0.938747f,-0.341671f, +0.135893f,0.935013f,-0.327543f, +0.248098f,0.92828f,-0.277025f, +0.287291f,0.872499f,-0.395234f, +0.360517f,0.825037f,-0.435134f, +0.531263f,0.786524f,-0.314864f, +0.667801f,0.716872f,-0.200342f, +0.67932f,0.687853f,-0.2557f, +0.702261f,0.671608f,-0.236161f, +0.672702f,0.722764f,-0.15838f, +0.529805f,0.828764f,-0.180158f, +0.396956f,0.86756f,-0.29961f, +0.439447f,0.830334f,-0.342683f, +0.431898f,0.838796f,-0.33149f, +0.414335f,0.865026f,-0.282941f, +0.433505f,0.865399f,-0.251314f, +0.473777f,0.866492f,-0.157252f, +0.513796f,0.828002f,-0.224559f, +0.584841f,0.771201f,-0.251417f, +0.518412f,0.788719f,-0.330412f, +0.507007f,0.831445f,-0.227253f, +0.414775f,0.908203f,-0.0559478f, +0.370241f,0.92627f,0.07033f, +0.386742f,0.919823f,0.0659988f, +0.294152f,0.955333f,0.0285335f, +0.1108f,0.9849f,-0.133022f, +0.118551f,0.967697f,-0.222506f, +0.0772752f,0.978981f,-0.188747f, +-0.0200413f,0.97522f,-0.220327f, +-0.18076f,0.942791f,-0.280125f, +-0.356914f,0.914544f,-0.190318f, +-0.511643f,0.854464f,-0.0900754f, +-0.529301f,0.843485f,0.0915077f, +-0.481356f,0.855106f,0.192586f, +-0.566596f,0.818312f,0.0966086f, +-0.682392f,0.727753f,-0.0686784f, +0.232504f,0.952167f,-0.198291f, +0.256414f,0.932781f,-0.253323f, +0.252094f,0.888895f,-0.38251f, +0.391259f,0.847753f,-0.358095f, +0.537533f,0.80784f,-0.241771f, +0.561137f,0.803605f,-0.198354f, +0.542606f,0.822395f,-0.171013f, +0.447025f,0.853524f,-0.267703f, +0.421457f,0.829331f,-0.366857f, +0.381949f,0.841011f,-0.383165f, +0.196905f,0.918187f,-0.343745f, +-0.0750719f,0.92165f,-0.380691f, +-0.176435f,0.915143f,-0.362469f, +-0.162121f,0.952528f,-0.257698f, +-0.094717f,0.979068f,-0.180149f, +-0.167752f,0.965606f,-0.198655f, +-0.133367f,0.985758f,-0.102438f, +-0.176519f,0.982527f,-0.0590077f, +-0.382392f,0.914243f,-0.133925f, +-0.379354f,0.898635f,-0.220329f, +-0.2745f,0.907747f,-0.317246f, +-0.107475f,0.924008f,-0.366959f, +-0.0783766f,0.915897f,-0.393688f, +-0.161723f,0.964079f,-0.210708f, +-0.213776f,0.971922f,-0.0983248f, +0.0126393f,0.993361f,-0.114343f, +0.146279f,0.956353f,-0.252963f, +0.181548f,0.939791f,-0.289541f, +0.0719106f,0.91394f,-0.399427f, +0.0405362f,0.92481f,-0.378262f, +0.227996f,0.9289f,-0.291825f, +0.430007f,0.847434f,-0.311368f, +0.444003f,0.803436f,-0.396676f, +0.425815f,0.77314f,-0.470039f, +0.591393f,0.731624f,-0.339089f, +0.68448f,0.684033f,-0.252165f, +0.663878f,0.696032f,-0.273504f, +0.62681f,0.752096f,-0.203619f, +0.578478f,0.810023f,-0.0960529f, +0.535256f,0.829774f,-0.158038f, +0.488949f,0.817442f,-0.304496f, +0.370902f,0.857519f,-0.356501f, +0.349699f,0.870975f,-0.345126f, +0.374514f,0.863134f,-0.338731f, +0.45144f,0.856074f,-0.251673f, +0.565254f,0.789722f,-0.238384f, +0.610208f,0.775791f,-0.160605f, +0.460354f,0.88479f,-0.0722568f, +0.360414f,0.930663f,0.0629891f, +0.310809f,0.940565f,0.136874f, +0.344153f,0.923997f,0.166701f, +0.371378f,0.913473f,0.166271f, +0.349168f,0.916329f,0.196019f, +0.310264f,0.946182f,0.0920588f, +0.219218f,0.972739f,-0.075642f, +0.0579784f,0.994476f,-0.087501f, +-0.0556996f,0.997544f,-0.0424565f, +-0.239345f,0.970003f,0.0425244f, +-0.461388f,0.876311f,0.138566f, +-0.538726f,0.825514f,0.168229f, +-0.597717f,0.791468f,0.127721f, +-0.507215f,0.833365f,0.219627f, +-0.488959f,0.84151f,0.229738f, +-0.545304f,0.815937f,0.192066f, +0.227692f,0.931856f,-0.282489f, +0.297935f,0.90904f,-0.291343f, +0.353719f,0.876832f,-0.325652f, +0.346915f,0.865884f,-0.36041f, +0.409305f,0.867351f,-0.283145f, +0.519851f,0.844165f,-0.130922f, +0.531147f,0.844051f,-0.0738934f, +0.549452f,0.835136f,-0.0255055f, +0.519598f,0.847001f,-0.112281f, +0.416821f,0.899711f,-0.12954f, +0.213877f,0.961324f,-0.173531f, +-0.0327967f,0.969436f,-0.243141f, +-0.200151f,0.944585f,-0.26019f, +-0.261086f,0.940261f,-0.218503f, +-0.16617f,0.980036f,-0.109163f, +-0.211362f,0.973049f,-0.0922088f, +-0.262019f,0.96267f,-0.0679153f, +-0.172722f,0.984229f,0.0382049f, +-0.269464f,0.962867f,-0.0166155f, +-0.289017f,0.944015f,-0.159073f, +-0.146887f,0.958128f,-0.245795f, +-0.0700562f,0.951312f,-0.300164f, +-0.140619f,0.963564f,-0.227533f, +-0.278995f,0.930049f,-0.239105f, +-0.16269f,0.936868f,-0.309531f, +0.070144f,0.909561f,-0.409607f, +0.193776f,0.876857f,-0.43997f, +0.127038f,0.902686f,-0.411121f, +0.150617f,0.947884f,-0.280767f, +0.0386496f,0.919015f,-0.392324f, +0.208973f,0.868713f,-0.449075f, +0.403894f,0.796876f,-0.449287f, +0.495348f,0.781817f,-0.378673f, +0.489779f,0.764879f,-0.418421f, +0.499102f,0.742417f,-0.446893f, +0.648968f,0.690613f,-0.319208f, +0.677239f,0.687846f,-0.26118f, +0.512369f,0.799495f,-0.313506f, +0.465181f,0.863456f,-0.195064f, +0.589095f,0.803266f,-0.0879238f, +0.56026f,0.801619f,-0.208601f, +0.442292f,0.866151f,-0.232723f, +0.407485f,0.876049f,-0.257867f, +0.41887f,0.854839f,-0.306264f, +0.344336f,0.834896f,-0.429397f, +0.497957f,0.824163f,-0.269804f, +0.448098f,0.886678f,-0.114058f, +0.337837f,0.929162f,0.150081f, +0.341034f,0.908641f,0.240972f, +0.356163f,0.918925f,0.169481f, +0.332963f,0.932465f,0.140159f, +0.378366f,0.915215f,0.13864f, +0.366597f,0.926522f,0.0846395f, +0.364364f,0.925578f,0.102688f, +0.226565f,0.954799f,0.192424f, +0.0359845f,0.964557f,0.261408f, +-0.155471f,0.954274f,0.255321f, +-0.290268f,0.886689f,0.359898f, +-0.467017f,0.828082f,0.31012f, +-0.499403f,0.82291f,0.270953f, +-0.565258f,0.797609f,0.210482f, +-0.553063f,0.809532f,0.196925f, +-0.499446f,0.823964f,0.267652f, +-0.522286f,0.796771f,0.30393f, +0.282895f,0.896955f,-0.339766f, +0.328074f,0.870604f,-0.366628f, +0.343521f,0.854938f,-0.388683f, +0.333693f,0.867418f,-0.369101f, +0.350459f,0.883644f,-0.310405f, +0.440013f,0.868347f,-0.228826f, +0.488334f,0.85139f,-0.191483f, +0.49066f,0.852892f,-0.178404f, +0.509846f,0.855822f,-0.0873222f, +0.418823f,0.907869f,-0.0190138f, +0.288806f,0.957176f,-0.0201137f, +0.0497186f,0.992214f,-0.114191f, +-0.215841f,0.960205f,-0.177253f, +-0.338759f,0.933444f,-0.118004f, +-0.242696f,0.969321f,-0.0389388f, +-0.141909f,0.989578f,-0.0244358f, +-0.270493f,0.952883f,-0.137288f, +-0.235245f,0.967095f,-0.0968818f, +-0.186427f,0.979041f,-0.0819931f, +-0.181825f,0.962183f,-0.20284f, +-0.135402f,0.958028f,-0.252681f, +-0.153581f,0.96935f,-0.191767f, +-0.186528f,0.978878f,-0.0837011f, +-0.164286f,0.974581f,-0.152324f, +0.0119477f,0.951315f,-0.307988f, +0.181241f,0.876938f,-0.44512f, +0.193514f,0.837326f,-0.51131f, +-0.00806995f,0.853668f,-0.520756f, +0.0461085f,0.918292f,-0.393209f, +0.210027f,0.898011f,-0.386606f, +0.313179f,0.820953f,-0.477447f, +0.395672f,0.762863f,-0.511355f, +0.407119f,0.752829f,-0.517206f, +0.491283f,0.735772f,-0.466133f, +0.508563f,0.731088f,-0.454835f, +0.557969f,0.720001f,-0.412637f, +0.635268f,0.712821f,-0.297187f, +0.514275f,0.818992f,-0.254505f, +0.384017f,0.888427f,-0.251454f, +0.535431f,0.823023f,-0.189597f, +0.597396f,0.79853f,-0.0739445f, +0.435766f,0.897283f,-0.0706489f, +0.387025f,0.91478f,-0.115713f, +0.532369f,0.842082f,-0.0864959f, +0.42055f,0.882636f,-0.209979f, +0.370951f,0.912219f,-0.173928f, +0.309089f,0.948381f,-0.0709704f, +0.21321f,0.976943f,0.0111471f, +0.331446f,0.943237f,0.0211533f, +0.410945f,0.911483f,0.0179772f, +0.321726f,0.946051f,-0.0384626f, +0.397145f,0.917286f,0.0293659f, +0.411757f,0.908804f,0.0673213f, +0.22276f,0.971882f,0.0763077f, +0.069501f,0.964908f,0.253224f, +-0.028986f,0.93542f,0.352349f, +-0.1774f,0.888082f,0.424074f, +-0.313309f,0.830284f,0.460941f, +-0.375142f,0.83463f,0.403313f, +-0.455516f,0.824707f,0.335207f, +-0.516585f,0.80896f,0.280577f, +-0.560057f,0.80406f,0.199559f, +-0.56953f,0.792393f,0.218515f, +-0.567769f,0.776958f,0.271984f, +0.281384f,0.90217f,-0.326974f, +0.32181f,0.911348f,-0.256676f, +0.424167f,0.891125f,-0.16118f, +0.302129f,0.903121f,-0.305108f, +0.274213f,0.914554f,-0.297318f, +0.377666f,0.887315f,-0.264651f, +0.50458f,0.840574f,-0.197063f, +0.48044f,0.846134f,-0.230726f, +0.426379f,0.87586f,-0.225987f, +0.348305f,0.925694f,-0.147563f, +0.27972f,0.958581f,-0.053649f, +0.144728f,0.989215f,-0.0225097f, +-0.168728f,0.979072f,-0.113791f, +-0.360157f,0.915919f,-0.177143f, +-0.292774f,0.933287f,-0.207987f, +-0.10309f,0.983541f,-0.148387f, +-0.174215f,0.960869f,-0.215359f, +-0.250891f,0.918965f,-0.304233f, +-0.150246f,0.940005f,-0.306294f, +-0.0860686f,0.946791f,-0.310127f, +-0.15131f,0.934427f,-0.322415f, +-0.22276f,0.935306f,-0.27492f, +-0.201088f,0.949203f,-0.242028f, +-0.0437143f,0.949864f,-0.309592f, +0.109977f,0.887847f,-0.446802f, +0.297781f,0.833674f,-0.465096f, +0.214775f,0.818536f,-0.532795f, +0.0269455f,0.850361f,-0.52551f, +-0.017632f,0.796129f,-0.60487f, +0.185146f,0.781388f,-0.595948f, +0.323386f,0.740218f,-0.589491f, +0.406653f,0.707179f,-0.578387f, +0.409551f,0.698057f,-0.587354f, +0.432954f,0.696782f,-0.57188f, +0.429959f,0.722053f,-0.54201f, +0.513634f,0.737641f,-0.438254f, +0.557438f,0.766448f,-0.319093f, +0.451237f,0.872287f,-0.188415f, +0.398866f,0.907449f,-0.132071f, +0.479702f,0.868398f,-0.125579f, +0.492136f,0.869715f,0.0373829f, +0.490052f,0.864036f,0.115287f, +0.467195f,0.882543f,-0.0533554f, +0.500676f,0.860686f,-0.092427f, +0.467521f,0.883982f,0.000254135f, +0.346172f,0.935182f,-0.0748316f, +0.285844f,0.955101f,-0.0779434f, +0.233788f,0.970423f,-0.0601792f, +0.33578f,0.93567f,-0.108509f, +0.44843f,0.890103f,-0.0814045f, +0.344049f,0.926181f,-0.154332f, +0.278254f,0.949058f,-0.147866f, +0.299653f,0.954043f,0.00333978f, +0.154533f,0.964067f,0.21609f, +0.0182142f,0.948347f,0.316711f, +-0.116946f,0.954294f,0.275039f, +-0.30019f,0.894483f,0.33134f, +-0.320232f,0.867471f,0.380717f, +-0.340655f,0.881399f,0.327246f, +-0.432069f,0.860755f,0.269105f, +-0.470649f,0.851696f,0.23044f, +-0.520568f,0.837827f,0.164485f, +-0.594362f,0.792684f,0.135598f, +-0.629645f,0.760492f,0.15874f, +0.105475f,0.917668f,-0.383094f, +0.157333f,0.940076f,-0.302494f, +0.34936f,0.922619f,-0.163471f, +0.441147f,0.892415f,-0.0947875f, +0.353266f,0.911437f,-0.210916f, +0.379048f,0.861228f,-0.33854f, +0.442622f,0.833751f,-0.330068f, +0.481137f,0.838111f,-0.257053f, +0.418048f,0.882249f,-0.216499f, +0.270753f,0.936711f,-0.221958f, +0.184979f,0.961951f,-0.201082f, +0.112903f,0.979904f,-0.164442f, +-0.0774318f,0.983977f,-0.160602f, +-0.269214f,0.939575f,-0.211477f, +-0.244405f,0.926884f,-0.284872f, +-0.16522f,0.91825f,-0.359887f, +-0.0697709f,0.937892f,-0.339838f, +-0.121807f,0.888033f,-0.443351f, +-0.178259f,0.862094f,-0.474361f, +-0.173573f,0.911189f,-0.373641f, +-0.145335f,0.940854f,-0.30606f, +-0.196672f,0.897435f,-0.394881f, +-0.142648f,0.86312f,-0.484434f, +0.079713f,0.828378f,-0.554469f, +0.216417f,0.76965f,-0.600668f, +0.249468f,0.776353f,-0.578828f, +0.204058f,0.841867f,-0.499621f, +0.0644049f,0.826788f,-0.558814f, +0.116412f,0.767322f,-0.630607f, +0.208898f,0.705315f,-0.677416f, +0.323537f,0.664792f,-0.673332f, +0.378749f,0.668133f,-0.640428f, +0.350681f,0.681998f,-0.641795f, +0.388988f,0.701053f,-0.597673f, +0.366172f,0.724838f,-0.583548f, +0.331191f,0.791609f,-0.513486f, +0.441902f,0.864123f,-0.240861f, +0.365381f,0.918735f,-0.149742f, +0.346761f,0.932102f,-0.104611f, +0.441617f,0.896164f,-0.0431763f, +0.429069f,0.903098f,0.0177174f, +0.509493f,0.859732f,0.035759f, +0.550737f,0.834518f,-0.0163997f, +0.446836f,0.894607f,0.00385291f, +0.489488f,0.868437f,0.0788584f, +0.430014f,0.900385f,-0.0662903f, +0.277285f,0.953602f,-0.117285f, +0.208284f,0.969937f,-0.12586f, +0.377184f,0.918436f,-0.119197f, +0.417651f,0.892053f,-0.172653f, +0.381197f,0.917074f,-0.116891f, +0.274507f,0.95009f,-0.148238f, +0.0946799f,0.989623f,-0.108088f, +-0.059654f,0.986641f,0.151597f, +-0.0667871f,0.959734f,0.272857f, +-0.0714815f,0.942101f,0.327622f, +-0.300084f,0.906469f,0.297092f, +-0.336918f,0.914203f,0.225209f, +-0.288002f,0.930996f,0.224278f, +-0.416386f,0.886687f,0.201018f, +-0.454428f,0.859405f,0.234346f, +-0.478891f,0.849426f,0.221671f, +-0.583336f,0.801078f,0.13414f, +-0.664795f,0.744846f,0.0570272f, +0.0774054f,0.9409f,-0.329722f, +0.120466f,0.940242f,-0.318486f, +0.258377f,0.92069f,-0.292526f, +0.391172f,0.892344f,-0.225179f, +0.441921f,0.861239f,-0.250944f, +0.474164f,0.819484f,-0.321892f, +0.430001f,0.828794f,-0.358051f, +0.388327f,0.849227f,-0.357794f, +0.321794f,0.900086f,-0.293759f, +0.306798f,0.936469f,-0.170002f, +0.197413f,0.950888f,-0.238412f, +0.140677f,0.959941f,-0.242328f, +-0.0738732f,0.952166f,-0.296516f, +-0.264161f,0.917561f,-0.297155f, +-0.156821f,0.939785f,-0.303665f, +-0.074827f,0.921443f,-0.381239f, +-0.0597443f,0.912887f,-0.403816f, +-0.0722702f,0.937805f,-0.339556f, +-0.223343f,0.933173f,-0.281613f, +-0.284993f,0.906137f,-0.31256f, +-0.17102f,0.941557f,-0.290212f, +0.0188228f,0.955829f,-0.29332f, +0.0949729f,0.880183f,-0.465036f, +0.154174f,0.836833f,-0.525301f, +0.175395f,0.823625f,-0.539331f, +0.0906162f,0.806123f,-0.584769f, +0.167569f,0.848038f,-0.502744f, +0.206981f,0.812951f,-0.544306f, +0.220466f,0.75453f,-0.618126f, +0.281661f,0.74367f,-0.606318f, +0.323085f,0.773947f,-0.544631f, +0.389827f,0.796004f,-0.463047f, +0.409468f,0.784217f,-0.466197f, +0.383754f,0.755374f,-0.531172f, +0.333252f,0.782449f,-0.526039f, +0.13472f,0.877229f,-0.460782f, +0.220453f,0.931705f,-0.288664f, +0.346271f,0.928921f,-0.131156f, +0.317872f,0.942854f,-0.0999207f, +0.41364f,0.908959f,-0.0519229f, +0.398453f,0.915561f,-0.0546188f, +0.505703f,0.862625f,-0.0119489f, +0.526627f,0.849939f,0.0163649f, +0.402553f,0.915142f,0.0215902f, +0.486926f,0.872826f,0.0328415f, +0.480317f,0.876602f,0.0293992f, +0.350224f,0.935385f,0.0489656f, +0.241613f,0.961192f,-0.13317f, +0.388714f,0.905381f,-0.170843f, +0.410083f,0.900693f,-0.14347f, +0.356005f,0.930194f,-0.0894385f, +0.273996f,0.955273f,-0.111267f, +-0.044831f,0.997624f,-0.0523075f, +-0.196423f,0.976135f,0.0926162f, +-0.135564f,0.988784f,0.0626771f, +-0.172489f,0.970476f,0.168594f, +-0.254529f,0.9218f,0.292405f, +-0.284378f,0.936305f,0.206065f, +-0.327372f,0.917976f,0.223935f, +-0.435353f,0.844597f,0.311647f, +-0.503149f,0.802852f,0.319796f, +-0.41775f,0.811758f,0.408086f, +-0.454925f,0.830308f,0.321918f, +-0.572823f,0.802298f,0.167904f, +0.20617f,0.937765f,-0.279448f, +0.12824f,0.920264f,-0.369687f, +0.239724f,0.89965f,-0.364914f, +0.406692f,0.839091f,-0.361286f, +0.450018f,0.81612f,-0.362535f, +0.486709f,0.828644f,-0.276522f, +0.440087f,0.85086f,-0.286985f, +0.416932f,0.85696f,-0.302962f, +0.239451f,0.901982f,-0.359293f, +0.202502f,0.927776f,-0.313409f, +0.221835f,0.941111f,-0.255147f, +0.127859f,0.963075f,-0.236935f, +0.0102396f,0.970361f,-0.241441f, +-0.185811f,0.907396f,-0.376969f, +-0.143f,0.87175f,-0.468618f, +-0.054802f,0.895065f,-0.442557f, +-0.153942f,0.908075f,-0.389489f, +-0.214862f,0.949277f,-0.22958f, +-0.226443f,0.961303f,-0.156909f, +-0.189142f,0.939849f,-0.284446f, +-0.183498f,0.904381f,-0.385258f, +0.0372666f,0.939229f,-0.341264f, +0.17942f,0.912891f,-0.366659f, +0.186987f,0.89504f,-0.404894f, +0.249987f,0.855827f,-0.452843f, +0.209164f,0.815071f,-0.540287f, +0.137636f,0.780743f,-0.609506f, +0.248264f,0.780183f,-0.574177f, +0.268876f,0.805155f,-0.528613f, +0.166884f,0.854291f,-0.492277f, +0.223895f,0.925944f,-0.304136f, +0.382591f,0.903499f,-0.193167f, +0.505015f,0.839819f,-0.199159f, +0.522375f,0.816711f,-0.245169f, +0.295143f,0.898426f,-0.32515f, +0.045309f,0.962545f,-0.26731f, +0.0698554f,0.972543f,-0.221991f, +0.23803f,0.966556f,-0.0954522f, +0.24345f,0.969904f,-0.00421011f, +0.387893f,0.915554f,0.106303f, +0.388608f,0.912695f,0.126382f, +0.452964f,0.880246f,0.141388f, +0.553021f,0.816379f,0.166411f, +0.46714f,0.881043f,0.0744546f, +0.450683f,0.892414f,0.0219511f, +0.444978f,0.886482f,0.127064f, +0.382178f,0.921652f,0.0670691f, +0.411319f,0.911388f,-0.0137033f, +0.389838f,0.919191f,-0.0558004f, +0.35617f,0.934375f,0.0092699f, +0.326889f,0.943423f,0.0556465f, +0.261297f,0.961477f,0.0853544f, +-0.107365f,0.988428f,0.107158f, +-0.198313f,0.974378f,0.106114f, +-0.119767f,0.989964f,0.0750203f, +-0.291683f,0.947022f,0.134427f, +-0.31644f,0.92799f,0.196723f, +-0.289311f,0.932636f,0.215615f, +-0.411791f,0.85345f,0.319455f, +-0.469106f,0.777331f,0.419161f, +-0.481552f,0.76826f,0.421765f, +-0.441444f,0.803246f,0.399904f, +-0.347505f,0.834501f,0.427607f, +-0.388172f,0.828163f,0.404313f, +0.166663f,0.855647f,-0.489991f, +0.206118f,0.852788f,-0.479863f, +0.253643f,0.809648f,-0.529278f, +0.34663f,0.798296f,-0.492515f, +0.334799f,0.852879f,-0.400633f, +0.411503f,0.867459f,-0.279608f, +0.469719f,0.846111f,-0.251912f, +0.425418f,0.857617f,-0.288986f, +0.321984f,0.890401f,-0.321733f, +0.13105f,0.897315f,-0.421487f, +0.163065f,0.944711f,-0.284482f, +0.0880681f,0.960841f,-0.262734f, +0.0835185f,0.96106f,-0.263417f, +-0.0250069f,0.943064f,-0.33167f, +-0.080502f,0.931121f,-0.355714f, +-0.129429f,0.916002f,-0.379721f, +-0.246145f,0.898013f,-0.36467f, +-0.295885f,0.891242f,-0.343715f, +-0.176282f,0.915144f,-0.362541f, +-0.0418985f,0.91018f,-0.412089f, +-0.0774111f,0.852502f,-0.51696f, +-0.0321668f,0.826692f,-0.561735f, +0.194406f,0.844754f,-0.498595f, +0.282885f,0.80862f,-0.515859f, +0.302949f,0.736294f,-0.605056f, +0.233445f,0.738314f,-0.632768f, +0.172128f,0.759349f,-0.627504f, +0.112225f,0.79134f,-0.600988f, +0.137255f,0.870359f,-0.472902f, +0.0541041f,0.935131f,-0.350147f, +0.048453f,0.960354f,-0.274541f, +0.350102f,0.918679f,-0.182913f, +0.524752f,0.830609f,-0.186344f, +0.518158f,0.835225f,-0.184147f, +0.313736f,0.944893f,-0.0935296f, +0.0308812f,0.997052f,-0.070238f, +0.048477f,0.985949f,-0.159858f, +0.14972f,0.972865f,-0.1764f, +0.155626f,0.983809f,-0.0888849f, +0.284416f,0.958659f,0.0089454f, +0.3659f,0.926807f,0.0845335f, +0.421454f,0.897257f,0.131556f, +0.563402f,0.804293f,0.188919f, +0.539736f,0.827553f,0.154408f, +0.404327f,0.91158f,0.0744378f, +0.452914f,0.883943f,0.116249f, +0.458215f,0.8862f,0.0684684f, +0.412404f,0.90336f,0.117745f, +0.337667f,0.93426f,0.114626f, +0.331072f,0.928113f,0.170285f, +0.265924f,0.943818f,0.196193f, +0.193837f,0.929607f,0.313462f, +-0.0688814f,0.919176f,0.387776f, +-0.142537f,0.930406f,0.33768f, +-0.12463f,0.963373f,0.237444f, +-0.336333f,0.924835f,0.17765f, +-0.311125f,0.930755f,0.192081f, +-0.359893f,0.911001f,0.201382f, +-0.532454f,0.800855f,0.274086f, +-0.552598f,0.767696f,0.324466f, +-0.457025f,0.795874f,0.39713f, +-0.406778f,0.834647f,0.371344f, +-0.39211f,0.844207f,0.365466f, +-0.407171f,0.83024f,0.380675f, +0.088004f,0.820624f,-0.564651f, +0.180508f,0.82686f,-0.532654f, +0.264125f,0.820464f,-0.507027f, +0.247967f,0.854234f,-0.456943f, +0.24322f,0.902001f,-0.356704f, +0.342999f,0.897422f,-0.277462f, +0.495739f,0.849894f,-0.178668f, +0.449958f,0.858561f,-0.245787f, +0.384562f,0.884942f,-0.262659f, +0.158931f,0.931299f,-0.327755f, +-0.00482349f,0.936712f,-0.350067f, +0.115045f,0.961792f,-0.248435f, +0.108639f,0.956333f,-0.271339f, +-0.0605962f,0.963938f,-0.259135f, +-0.116693f,0.974935f,-0.189434f, +-0.0876965f,0.975552f,-0.201512f, +-0.158272f,0.938607f,-0.30654f, +-0.195709f,0.870225f,-0.452113f, +-0.139804f,0.831767f,-0.537233f, +-0.0224753f,0.834621f,-0.550366f, +0.0691358f,0.82738f,-0.557371f, +0.021368f,0.778901f,-0.626782f, +0.103745f,0.763834f,-0.637021f, +0.295282f,0.754578f,-0.586021f, +0.391718f,0.767187f,-0.507919f, +0.243831f,0.78308f,-0.57213f, +0.0624167f,0.795727f,-0.60243f, +0.0157622f,0.882125f,-0.470752f, +-0.0549233f,0.922741f,-0.381487f, +-0.0376875f,0.97f,-0.240167f, +0.0506221f,0.974297f,-0.219507f, +0.328414f,0.911788f,-0.246548f, +0.524714f,0.832523f,-0.177709f, +0.470173f,0.873047f,-0.12933f, +0.188699f,0.978079f,-0.0880599f, +0.0393835f,0.999181f,-0.00932192f, +0.202516f,0.978334f,-0.0430044f, +0.188361f,0.964087f,-0.187232f, +0.0636833f,0.962187f,-0.264841f, +0.180234f,0.965248f,-0.18924f, +0.346543f,0.937198f,-0.0395955f, +0.331037f,0.942573f,-0.0443968f, +0.504726f,0.851052f,0.144785f, +0.565376f,0.80039f,0.199312f, +0.492317f,0.859822f,0.135391f, +0.448961f,0.892857f,0.0352157f, +0.367625f,0.92412f,0.104186f, +0.329385f,0.906428f,0.264373f, +0.348699f,0.881448f,0.318526f, +0.290794f,0.899496f,0.326107f, +0.185082f,0.919339f,0.347219f, +0.0676347f,0.907778f,0.413962f, +-0.145808f,0.884054f,0.444059f, +-0.0815232f,0.884669f,0.459037f, +0.0810938f,0.898461f,0.431499f, +-0.248842f,0.934053f,0.256168f, +-0.367995f,0.892045f,0.262364f, +-0.356163f,0.871443f,0.337246f, +-0.546503f,0.805165f,0.230312f, +-0.590616f,0.793807f,0.145063f, +-0.541291f,0.82267f,0.173836f, +-0.431572f,0.851071f,0.299038f, +-0.381298f,0.858781f,0.342208f, +-0.443875f,0.85724f,0.260987f, +0.118157f,0.850415f,-0.512673f, +0.134653f,0.857894f,-0.49587f, +0.229214f,0.896945f,-0.378087f, +0.208074f,0.910502f,-0.35734f, +0.182505f,0.899208f,-0.397639f, +0.219865f,0.895989f,-0.385828f, +0.451196f,0.865461f,-0.217713f, +0.490084f,0.844039f,-0.217752f, +0.378309f,0.899823f,-0.217259f, +0.231483f,0.942802f,-0.239876f, +0.0439163f,0.94313f,-0.329511f, +0.0365981f,0.93055f,-0.364332f, +0.0406622f,0.963235f,-0.265566f, +-0.0474005f,0.988537f,-0.143342f, +-0.135564f,0.953464f,-0.269312f, +-0.0159099f,0.95648f,-0.291363f, +6.71815e-006f,0.933398f,-0.358843f, +-0.0477574f,0.880875f,-0.470933f, +-0.0515582f,0.822668f,-0.56618f, +0.00280332f,0.78244f,-0.62272f, +0.0365076f,0.790824f,-0.610954f, +0.0809221f,0.832084f,-0.548715f, +0.112086f,0.801748f,-0.587057f, +0.219407f,0.814817f,-0.536594f, +0.31647f,0.811557f,-0.491143f, +0.326532f,0.816359f,-0.476376f, +0.0311646f,0.874097f,-0.484751f, +-0.166146f,0.898216f,-0.406943f, +-0.145486f,0.939877f,-0.308975f, +-0.113562f,0.952885f,-0.281273f, +0.0633693f,0.957888f,-0.280063f, +0.322061f,0.911056f,-0.257398f, +0.438519f,0.889327f,-0.12961f, +0.430695f,0.901938f,0.0317863f, +0.232727f,0.970972f,0.0552405f, +0.0388751f,0.995464f,-0.0868351f, +0.197289f,0.970749f,-0.136837f, +0.308804f,0.945817f,-0.100347f, +0.177873f,0.966831f,-0.183299f, +0.0327621f,0.970738f,-0.237896f, +0.244781f,0.968393f,-0.0479323f, +0.27827f,0.960269f,-0.0211936f, +0.355239f,0.931705f,0.0757045f, +0.555707f,0.816071f,0.158801f, +0.563884f,0.814994f,0.133487f, +0.420142f,0.89843f,0.127685f, +0.31027f,0.90429f,0.293243f, +0.233723f,0.926208f,0.295826f, +0.272016f,0.906457f,0.323021f, +0.267428f,0.881549f,0.389042f, +0.161017f,0.891985f,0.422417f, +0.0459966f,0.878435f,0.475642f, +-0.0917474f,0.877231f,0.47122f, +-0.0819927f,0.91503f,0.394964f, +0.108269f,0.907964f,0.40482f, +-0.16221f,0.904236f,0.395026f, +-0.422279f,0.840786f,0.338761f, +-0.374364f,0.835182f,0.402893f, +-0.384829f,0.826017f,0.411828f, +-0.512379f,0.829197f,0.223383f, +-0.585197f,0.801652f,0.122056f, +-0.526709f,0.831787f,0.175237f, +-0.374079f,0.907515f,0.191003f, +-0.329797f,0.931547f,0.153144f, +0.105779f,0.878895f,-0.465138f, +0.0405535f,0.897741f,-0.438654f, +0.106545f,0.927041f,-0.359504f, +0.255352f,0.917446f,-0.305103f, +0.298997f,0.88918f,-0.346352f, +0.205215f,0.859845f,-0.467497f, +0.304244f,0.842016f,-0.445471f, +0.435228f,0.863678f,-0.254238f, +0.39753f,0.896082f,-0.197502f, +0.268558f,0.910516f,-0.314385f, +0.0970216f,0.931439f,-0.350727f, +0.0336528f,0.944013f,-0.328188f, +-0.0988412f,0.948055f,-0.302362f, +-0.0597673f,0.966409f,-0.249964f, +0.0558923f,0.934228f,-0.352269f, +-0.00489276f,0.88655f,-0.462606f, +0.0451038f,0.899627f,-0.434323f, +0.0627933f,0.870215f,-0.488654f, +0.0536848f,0.846805f,-0.529187f, +0.0729181f,0.867797f,-0.491539f, +-0.0450251f,0.86132f,-0.506063f, +0.0321391f,0.857039f,-0.514249f, +0.105366f,0.853869f,-0.509711f, +0.20021f,0.860626f,-0.468229f, +0.336826f,0.823703f,-0.456137f, +0.291163f,0.890761f,-0.348954f, +-0.0337704f,0.937324f,-0.34682f, +-0.238938f,0.893089f,-0.381184f, +-0.1654f,0.905926f,-0.389797f, +-0.0746684f,0.904792f,-0.419256f, +0.0731105f,0.895556f,-0.438901f, +0.199233f,0.902713f,-0.381334f, +0.277877f,0.941082f,-0.192742f, +0.300522f,0.95354f,-0.0211427f, +0.316945f,0.945681f,0.0723468f, +0.218722f,0.970853f,-0.0980014f, +0.256356f,0.93882f,-0.229999f, +0.242436f,0.93442f,-0.26093f, +0.1983f,0.960329f,-0.196077f, +0.00223103f,0.977894f,-0.209089f, +0.104164f,0.98625f,-0.128296f, +0.285507f,0.957716f,-0.0355725f, +0.283907f,0.956269f,-0.0703361f, +0.529334f,0.848145f,0.0213636f, +0.533064f,0.836918f,0.124145f, +0.319483f,0.916151f,0.242069f, +0.17728f,0.930248f,0.321263f, +0.27524f,0.891192f,0.360581f, +0.317681f,0.901882f,0.292724f, +0.194688f,0.951543f,0.23804f, +0.108971f,0.911619f,0.396329f, +-0.0300123f,0.895185f,0.444683f, +-0.0818392f,0.875146f,0.476887f, +-0.0034355f,0.872809f,0.48805f, +0.0854438f,0.889906f,0.448069f, +-0.143928f,0.891079f,0.430422f, +-0.400827f,0.846578f,0.350204f, +-0.436121f,0.820693f,0.369135f, +-0.389169f,0.817738f,0.42409f, +-0.354493f,0.838309f,0.414212f, +-0.495629f,0.825913f,0.268736f, +-0.491187f,0.862049f,0.124928f, +-0.360891f,0.926358f,0.107794f, +-0.272797f,0.945677f,0.17685f, +-0.0230447f,0.8982f,-0.438983f, +-0.0253824f,0.922509f,-0.38514f, +0.0868314f,0.93389f,-0.346856f, +0.228815f,0.908408f,-0.349913f, +0.325232f,0.887343f,-0.326875f, +0.342601f,0.877959f,-0.334385f, +0.256841f,0.884237f,-0.390073f, +0.281416f,0.889548f,-0.359874f, +0.383834f,0.865745f,-0.321181f, +0.3194f,0.893039f,-0.316962f, +0.102059f,0.965529f,-0.239452f, +-0.0466698f,0.958891f,-0.279912f, +-0.0536344f,0.964707f,-0.257804f, +-0.0261637f,0.940106f,-0.339875f, +0.144391f,0.948897f,-0.280616f, +0.0981473f,0.936323f,-0.337144f, +0.012852f,0.869861f,-0.493129f, +0.144402f,0.872896f,-0.466049f, +-0.00636809f,0.871363f,-0.490597f, +-0.0613187f,0.915967f,-0.396541f, +0.0199429f,0.949099f,-0.314346f, +0.0355652f,0.92816f,-0.370479f, +0.140076f,0.947915f,-0.286071f, +0.222188f,0.910114f,-0.349749f, +0.215543f,0.917499f,-0.33427f, +0.183013f,0.971215f,-0.152469f, +0.0390344f,0.988083f,-0.14889f, +-0.127226f,0.955382f,-0.266569f, +-0.116102f,0.92344f,-0.365757f, +-0.0309649f,0.920225f,-0.390164f, +0.00625843f,0.924708f,-0.380627f, +0.101949f,0.952725f,-0.286221f, +0.10526f,0.958946f,-0.263332f, +0.1589f,0.975537f,-0.151918f, +0.291601f,0.956292f,-0.0217678f, +0.33385f,0.942155f,0.0297851f, +0.349208f,0.937042f,0.00260008f, +0.278057f,0.953965f,-0.112407f, +0.149531f,0.968881f,-0.197256f, +-0.00612536f,0.988275f,-0.152563f, +-0.00797921f,0.994274f,-0.106558f, +0.301027f,0.953574f,-0.00894642f, +0.304582f,0.944145f,-0.125778f, +0.403446f,0.913254f,-0.0565483f, +0.37426f,0.908704f,0.184893f, +0.255667f,0.895707f,0.363791f, +0.219787f,0.909558f,0.352701f, +0.267099f,0.929513f,0.254289f, +0.378434f,0.885367f,0.270025f, +0.147409f,0.95291f,0.265015f, +-0.0634097f,0.932842f,0.354663f, +-0.0326192f,0.907501f,0.418782f, +-0.118713f,0.911859f,0.392963f, +-0.0609125f,0.902157f,0.427087f, +0.138333f,0.871993f,0.469567f, +-0.0649916f,0.904886f,0.420664f, +-0.383734f,0.861279f,0.333085f, +-0.474942f,0.817835f,0.324924f, +-0.422908f,0.836367f,0.348768f, +-0.339416f,0.853379f,0.395651f, +-0.324702f,0.875389f,0.358137f, +-0.41353f,0.899847f,0.138815f, +-0.448451f,0.884614f,0.12787f, +-0.414049f,0.866279f,0.279505f, +0.070634f,0.912028f,-0.404001f, +-0.0676482f,0.885638f,-0.459422f, +0.0565435f,0.906984f,-0.417353f, +0.246119f,0.879096f,-0.408185f, +0.292529f,0.859337f,-0.419485f, +0.280896f,0.904751f,-0.320192f, +0.320721f,0.917291f,-0.23604f, +0.350916f,0.874365f,-0.335178f, +0.376904f,0.866371f,-0.327636f, +0.17512f,0.962866f,-0.205478f, +0.0176642f,0.987314f,-0.157793f, +0.0227212f,0.982851f,-0.182998f, +0.0272561f,0.971904f,-0.233795f, +-0.0877209f,0.950392f,-0.298429f, +0.0166276f,0.994097f,-0.107211f, +0.266845f,0.962366f,-0.0514236f, +0.216132f,0.934464f,-0.282956f, +0.0993362f,0.906446f,-0.410472f, +-0.0104212f,0.924877f,-0.380123f, +-0.166185f,0.907878f,-0.384889f, +-0.0197905f,0.953108f,-0.301983f, +-0.0183125f,0.962192f,-0.271757f, +0.0845408f,0.976284f,-0.199307f, +0.269635f,0.943751f,-0.191394f, +0.189274f,0.968047f,-0.164501f, +0.102539f,0.979864f,-0.171327f, +0.106979f,0.970988f,-0.213865f, +-0.0373949f,0.962501f,-0.268688f, +-0.0919497f,0.957563f,-0.273163f, +-0.0692205f,0.979823f,-0.187497f, +-0.0661107f,0.993399f,-0.093741f, +0.0537161f,0.998551f,0.00311785f, +0.163558f,0.98647f,-0.0111964f, +0.128373f,0.980868f,-0.146347f, +0.126964f,0.974881f,-0.182993f, +0.228868f,0.973261f,0.0195364f, +0.336464f,0.933228f,0.126005f, +0.409696f,0.899435f,0.152205f, +0.227221f,0.973118f,0.0375761f, +-0.0400449f,0.999001f,-0.0198394f, +-0.0832424f,0.995769f,-0.0389306f, +0.262425f,0.963268f,0.0569854f, +0.380638f,0.919787f,0.0954299f, +0.267185f,0.959941f,0.0844166f, +0.200067f,0.945675f,0.256267f, +0.180437f,0.922348f,0.341639f, +0.274022f,0.906356f,0.321607f, +0.375587f,0.88639f,0.270641f, +0.289567f,0.933145f,0.213051f, +0.118001f,0.9078f,0.402461f, +-0.100351f,0.886215f,0.452275f, +-0.0321373f,0.879207f,0.475355f, +-0.064732f,0.903306f,0.424085f, +-0.117284f,0.933968f,0.337563f, +0.107835f,0.909874f,0.400625f, +-0.00684675f,0.915037f,0.403311f, +-0.3665f,0.879987f,0.302161f, +-0.484488f,0.825175f,0.290444f, +-0.455029f,0.825809f,0.33315f, +-0.355514f,0.861697f,0.362061f, +-0.249905f,0.90704f,0.338859f, +-0.283441f,0.915216f,0.286426f, +-0.489082f,0.840765f,0.232193f, +-0.566036f,0.779585f,0.26805f, +0.300059f,0.882066f,-0.363212f, +0.0511478f,0.860745f,-0.506461f, +0.0202137f,0.82997f,-0.557442f, +0.244641f,0.828925f,-0.503024f, +0.229733f,0.86489f,-0.446306f, +0.151553f,0.888421f,-0.433289f, +0.276054f,0.875076f,-0.397538f, +0.35746f,0.874812f,-0.326997f, +0.20869f,0.962246f,-0.174729f, +0.135202f,0.98952f,0.050694f, +0.0768682f,0.997036f,0.00329808f, +0.0854955f,0.992826f,-0.08359f, +0.0751533f,0.982531f,-0.170249f, +-0.0858423f,0.966447f,-0.242097f, +-0.101218f,0.962967f,-0.2499f, +0.245897f,0.943422f,-0.222463f, +0.411229f,0.896277f,-0.166064f, +0.160383f,0.921177f,-0.354556f, +0.0135902f,0.93936f,-0.342662f, +-0.185366f,0.907574f,-0.37676f, +-0.130182f,0.940725f,-0.313191f, +-0.0326676f,0.972591f,-0.230215f, +0.0675199f,0.972602f,-0.222457f, +0.233107f,0.94649f,-0.2232f, +0.212831f,0.95378f,-0.212148f, +0.167019f,0.9356f,-0.311059f, +0.16946f,0.90555f,-0.388925f, +-0.0763448f,0.914067f,-0.398312f, +-0.178349f,0.9565f,-0.230865f, +-0.221816f,0.964561f,-0.142896f, +-0.163528f,0.986246f,-0.0240246f, +-0.0459992f,0.998297f,0.0358721f, +0.192503f,0.971257f,0.140008f, +0.306262f,0.942491f,0.133843f, +0.166989f,0.985549f,-0.0284312f, +0.110164f,0.988175f,-0.106645f, +0.230491f,0.969982f,-0.0775155f, +0.320779f,0.937031f,0.138109f, +0.2844f,0.912116f,0.295231f, +0.0676957f,0.97278f,0.221621f, +-0.0445371f,0.996486f,0.0709375f, +0.140086f,0.988598f,0.0552233f, +0.294951f,0.934183f,0.200765f, +0.239076f,0.923996f,0.298453f, +0.115077f,0.947116f,0.299546f, +0.169084f,0.942486f,0.288323f, +0.304609f,0.90997f,0.281369f, +0.369662f,0.880322f,0.297294f, +0.206677f,0.906857f,0.36728f, +-0.0427609f,0.882729f,0.467933f, +-0.167345f,0.859324f,0.483279f, +-0.0302574f,0.860894f,0.507884f, +0.0910322f,0.886636f,0.453421f, +-0.0366606f,0.947171f,0.318627f, +0.025939f,0.94095f,0.337552f, +0.0591946f,0.91956f,0.388466f, +-0.284221f,0.911546f,0.297158f, +-0.532586f,0.813173f,0.234739f, +-0.487487f,0.825499f,0.284445f, +-0.31853f,0.893358f,0.316938f, +-0.238637f,0.92505f,0.295524f, +-0.265409f,0.911937f,0.312937f, +-0.505062f,0.827653f,0.244749f, +-0.589625f,0.757122f,0.281262f, +0.260545f,0.875981f,-0.405923f, +0.198469f,0.90372f,-0.379342f, +0.0608985f,0.867502f,-0.493691f, +0.108599f,0.877043f,-0.467977f, +0.149016f,0.918586f,-0.366053f, +0.269933f,0.909568f,-0.315946f, +0.225091f,0.894351f,-0.386613f, +0.14483f,0.975181f,-0.16747f, +0.0237141f,0.999718f,0.00125985f, +0.0312597f,0.997955f,0.0557504f, +0.105656f,0.993029f,0.0522575f, +0.205288f,0.977382f,0.0508146f, +0.175007f,0.977751f,-0.115656f, +0.0411408f,0.976103f,-0.213378f, +-0.0123853f,0.935985f,-0.351821f, +0.185506f,0.902134f,-0.38954f, +0.361594f,0.882471f,-0.300824f, +0.229178f,0.926898f,-0.297216f, +-0.016076f,0.953923f,-0.299621f, +-0.176229f,0.940869f,-0.289326f, +-0.197595f,0.933757f,-0.298419f, +-0.0925101f,0.952321f,-0.290735f, +0.0363018f,0.966473f,-0.254189f, +0.27059f,0.939141f,-0.211649f, +0.283887f,0.910685f,-0.300101f, +0.267987f,0.87929f,-0.39374f, +0.167837f,0.906306f,-0.387866f, +-0.162045f,0.958045f,-0.236411f, +-0.34242f,0.923851f,-0.171018f, +-0.280408f,0.954479f,-0.101693f, +-0.219474f,0.974995f,-0.0348799f, +-0.111179f,0.993643f,0.0176973f, +0.0791225f,0.990452f,0.112896f, +0.243665f,0.947394f,0.207537f, +0.282223f,0.914505f,0.289882f, +0.280685f,0.943977f,0.173563f, +0.165641f,0.985889f,-0.0242044f, +0.0702016f,0.994363f,0.0794649f, +0.118053f,0.960325f,0.252664f, +0.204772f,0.904931f,0.373051f, +0.0632983f,0.962848f,0.262521f, +0.122554f,0.958346f,0.257978f, +0.174517f,0.943136f,0.28291f, +0.181765f,0.923678f,0.337315f, +0.176745f,0.924152f,0.338681f, +0.201711f,0.945597f,0.255262f, +0.29766f,0.929054f,0.219676f, +0.268359f,0.928086f,0.258147f, +0.100906f,0.896734f,0.430912f, +-0.0388415f,0.876619f,0.479615f, +-0.130193f,0.899332f,0.417434f, +0.000668505f,0.914851f,0.403791f, +0.198601f,0.908384f,0.367961f, +0.0382447f,0.953766f,0.298106f, +-0.0134843f,0.968824f,0.247384f, +0.0247843f,0.964757f,0.261972f, +-0.214942f,0.928034f,0.304224f, +-0.51491f,0.834181f,0.197508f, +-0.514132f,0.845f,0.147116f, +-0.364403f,0.910649f,0.194754f, +-0.252308f,0.925047f,0.283953f, +-0.245043f,0.926077f,0.286941f, +-0.475784f,0.852889f,0.214964f, +-0.66621f,0.724577f,0.176499f, +0.0831836f,0.888999f,-0.45029f, +0.181271f,0.909397f,-0.374349f, +0.118635f,0.893305f,-0.433511f, +0.0803087f,0.896743f,-0.435204f, +0.0532614f,0.909245f,-0.41284f, +0.209897f,0.941844f,-0.262435f, +0.164344f,0.979747f,-0.114402f, +-0.0796744f,0.996148f,-0.0366233f, +-0.0133458f,0.996096f,0.0872637f, +0.0764545f,0.99532f,0.0590999f, +0.136206f,0.990597f,0.0128964f, +0.22076f,0.975032f,-0.0240476f, +0.302428f,0.952936f,-0.021205f, +0.123508f,0.990766f,-0.0559322f, +0.0598433f,0.996046f,-0.06566f, +0.217088f,0.972764f,-0.0812636f, +0.324106f,0.93941f,-0.111642f, +0.231973f,0.969426f,-0.0800149f, +-0.0239272f,0.988929f,-0.146448f, +-0.168479f,0.969286f,-0.179165f, +-0.198758f,0.9628f,-0.183064f, +-0.0847832f,0.988177f,-0.12774f, +-0.00304443f,0.993662f,-0.112364f, +0.297886f,0.949812f,-0.0955022f, +0.392699f,0.900627f,-0.186169f, +0.309254f,0.921444f,-0.235165f, +-0.0368216f,0.992281f,-0.118418f, +-0.30784f,0.939111f,0.152661f, +-0.339391f,0.929078f,0.147065f, +-0.31987f,0.942094f,0.100706f, +-0.261939f,0.955297f,0.137099f, +-0.18149f,0.977639f,0.106224f, +-0.0176854f,0.987381f,0.157371f, +0.134774f,0.952305f,0.273773f, +0.227558f,0.898637f,0.375058f, +0.367312f,0.872839f,0.3213f, +0.289472f,0.940027f,0.180432f, +0.0121921f,0.995617f,0.0927227f, +-0.0151053f,0.984704f,0.173582f, +0.12465f,0.941586f,0.312855f, +0.123765f,0.936041f,0.329407f, +0.0496474f,0.956015f,0.289087f, +0.155803f,0.919433f,0.361065f, +0.180039f,0.912678f,0.366885f, +0.192318f,0.910529f,0.365993f, +0.269572f,0.892548f,0.361509f, +0.331198f,0.898525f,0.288029f, +0.198758f,0.948186f,0.247866f, +-0.0345441f,0.951973f,0.304226f, +-0.0327497f,0.929484f,0.367404f, +-0.0643392f,0.937143f,0.342962f, +0.00774044f,0.965859f,0.258952f, +0.179174f,0.948429f,0.261495f, +0.132443f,0.935778f,0.32677f, +0.0607758f,0.973146f,0.222018f, +-0.0289622f,0.977742f,0.2078f, +-0.247283f,0.928769f,0.276114f, +-0.440694f,0.866976f,0.232681f, +-0.493254f,0.853754f,0.166745f, +-0.437376f,0.881741f,0.176734f, +-0.303558f,0.920161f,0.247297f, +-0.230002f,0.942128f,0.243914f, +-0.435382f,0.879414f,0.192544f, +-0.672886f,0.738322f,0.045878f, +0.0719528f,0.93004f,-0.360345f, +0.170321f,0.920666f,-0.351232f, +0.181011f,0.922477f,-0.340985f, +0.0828362f,0.939404f,-0.332654f, +-0.0227994f,0.947238f,-0.31972f, +-0.0485785f,0.963562f,-0.263036f, +0.0586424f,0.995988f,-0.0676002f, +-0.0660447f,0.996659f,-0.0480482f, +-0.0602898f,0.992772f,-0.103773f, +0.058767f,0.996066f,-0.0663303f, +0.189158f,0.981943f,0.00282556f, +0.237805f,0.968932f,-0.0679702f, +0.226076f,0.973949f,-0.0176966f, +0.0903031f,0.990597f,0.102775f, +0.00876316f,0.995102f,0.0984623f, +0.239141f,0.958139f,0.157419f, +0.358816f,0.926379f,0.11434f, +0.290281f,0.955997f,0.0425008f, +0.0827916f,0.995067f,-0.054651f, +-0.14974f,0.985436f,-0.0805802f, +-0.250148f,0.9681f,-0.0144092f, +-0.190918f,0.980525f,0.0460446f, +0.000678111f,0.99542f,0.0955933f, +0.316233f,0.948486f,0.019255f, +0.451155f,0.892443f,0.00187563f, +0.20864f,0.975493f,0.0698802f, +-0.187263f,0.946264f,0.263661f, +-0.412354f,0.843904f,0.343207f, +-0.267988f,0.899756f,0.344414f, +-0.237384f,0.936767f,0.25713f, +-0.24929f,0.96341f,0.0984657f, +-0.12508f,0.979898f,0.155419f, +-0.075281f,0.975532f,0.206567f, +-0.0362475f,0.956877f,0.288223f, +0.179598f,0.903623f,0.388856f, +0.452503f,0.830262f,0.325433f, +0.44384f,0.859576f,0.253251f, +0.0283124f,0.992393f,0.119807f, +-0.131018f,0.979645f,0.152082f, +-0.0108162f,0.971878f,0.235238f, +0.177243f,0.920605f,0.347953f, +0.0690998f,0.954542f,0.289956f, +0.0964158f,0.939858f,0.327675f, +0.141817f,0.921257f,0.362178f, +0.189018f,0.897606f,0.398216f, +0.266469f,0.899974f,0.345024f, +0.359545f,0.871551f,0.333357f, +0.237931f,0.897592f,0.371104f, +-0.0217966f,0.934365f,0.355651f, +-0.0978092f,0.948287f,0.30197f, +0.00875447f,0.940305f,0.340221f, +0.0870369f,0.963741f,0.252246f, +0.143744f,0.964801f,0.220218f, +0.0987042f,0.960888f,0.25875f, +0.124661f,0.953903f,0.273f, +-0.0397023f,0.970451f,0.238011f, +-0.294392f,0.938787f,0.17892f, +-0.415783f,0.892445f,0.175119f, +-0.502145f,0.854833f,0.130809f, +-0.438287f,0.876552f,0.198899f, +-0.315043f,0.920499f,0.231147f, +-0.194294f,0.951114f,0.240065f, +-0.351808f,0.923717f,0.151587f, +-0.54821f,0.835857f,0.0284484f, +0.0750917f,0.989867f,-0.120519f, +0.16891f,0.981624f,-0.0887941f, +0.190217f,0.976992f,-0.0964579f, +0.031324f,0.983953f,-0.175657f, +-0.0605958f,0.993695f,-0.0943344f, +-0.0750681f,0.99685f,-0.025582f, +-0.0331924f,0.999431f,-0.00606515f, +-0.0198899f,0.99954f,0.0228873f, +-0.0160511f,0.998799f,-0.0462827f, +0.0298246f,0.995221f,-0.092978f, +0.113995f,0.985706f,-0.124048f, +0.249662f,0.968309f,-0.00683024f, +0.100872f,0.992347f,0.0712218f, +0.0920036f,0.982533f,0.161755f, +0.0527146f,0.998589f,-0.00636128f, +0.182827f,0.9816f,-0.0550969f, +0.393766f,0.919069f,-0.0161334f, +0.337394f,0.941358f,0.00313128f, +0.105574f,0.990777f,0.0849468f, +-0.199161f,0.971911f,0.125398f, +-0.309481f,0.93868f,0.151989f, +-0.20903f,0.965522f,0.15516f, +0.0624223f,0.987754f,0.142987f, +0.384312f,0.922399f,0.0385395f, +0.395292f,0.916973f,0.0539f, +-0.00445825f,0.983693f,0.179798f, +-0.32103f,0.866957f,0.381215f, +-0.378167f,0.863609f,0.33342f, +-0.220175f,0.926633f,0.304752f, +-0.0614943f,0.950074f,0.305906f, +-0.12116f,0.98024f,0.156364f, +-0.278268f,0.956461f,0.0880323f, +-0.168756f,0.960122f,0.222908f, +-0.0650574f,0.977781f,0.199281f, +0.11325f,0.979757f,0.165078f, +0.469769f,0.846474f,0.250598f, +0.492575f,0.830428f,0.260305f, +0.123756f,0.962501f,0.241404f, +-0.13585f,0.964887f,0.224807f, +-0.0763658f,0.97309f,0.217403f, +0.0878568f,0.965257f,0.246088f, +0.105594f,0.951417f,0.289233f, +0.0757959f,0.967864f,0.239781f, +0.0993833f,0.975608f,0.195732f, +0.186309f,0.954458f,0.23302f, +0.338273f,0.909543f,0.241458f, +0.326788f,0.907649f,0.263405f, +0.193788f,0.920444f,0.339454f, +0.0304147f,0.954662f,0.296135f, +-0.0232537f,0.980981f,0.192706f, +0.000389577f,0.986091f,0.166207f, +0.0882095f,0.967853f,0.235542f, +0.188357f,0.927906f,0.321731f, +0.0670292f,0.972109f,0.224745f, +0.0943312f,0.961869f,0.256728f, +0.0613113f,0.959756f,0.274061f, +-0.207348f,0.967924f,0.141881f, +-0.415608f,0.907723f,0.0575284f, +-0.500123f,0.863342f,0.0672098f, +-0.492039f,0.866172f,0.0874256f, +-0.354073f,0.931677f,0.0813054f, +-0.181316f,0.978479f,0.0985071f, +-0.266622f,0.956284f,0.120138f, +-0.442863f,0.891447f,0.0958846f, +-0.0871303f,0.98944f,-0.115829f, +0.0906659f,0.9958f,-0.0127409f, +0.283182f,0.958456f,0.0342056f, +0.0813038f,0.994836f,-0.0607581f, +-0.14732f,0.989082f,0.00362058f, +-0.15085f,0.987502f,0.0456442f, +-0.0204288f,0.99901f,0.039516f, +0.00607957f,0.996993f,-0.0772516f, +0.0245166f,0.989435f,-0.142892f, +0.112542f,0.984768f,-0.132539f, +0.117701f,0.980135f,-0.159633f, +0.0712861f,0.996099f,-0.0520052f, +0.0255235f,0.995475f,0.0915291f, +0.102558f,0.988742f,0.10895f, +0.263691f,0.960156f,0.0925667f, +0.248163f,0.965214f,-0.0823197f, +0.340591f,0.934756f,-0.101139f, +0.19652f,0.980248f,0.0222232f, +-0.0707824f,0.98306f,0.169067f, +-0.214629f,0.938414f,0.270766f, +-0.253216f,0.94197f,0.220395f, +-0.140751f,0.981088f,0.132876f, +0.0855474f,0.99626f,0.0121329f, +0.407822f,0.912623f,0.0283097f, +0.314806f,0.941456f,0.120654f, +-0.127318f,0.956166f,0.263699f, +-0.403379f,0.856412f,0.322248f, +-0.326125f,0.89105f,0.315709f, +-0.192548f,0.934549f,0.29924f, +-0.115959f,0.956033f,0.26936f, +-0.0455884f,0.940005f,0.3381f, +-0.221624f,0.931041f,0.289905f, +-0.142796f,0.963558f,0.226198f, +0.0818112f,0.991531f,0.100865f, +0.115133f,0.989689f,-0.0852087f, +0.362891f,0.931224f,-0.0336289f, +0.464909f,0.869676f,0.1659f, +0.12135f,0.938462f,0.323362f, +-0.154102f,0.92745f,0.340718f, +-0.00840056f,0.94535f,0.325948f, +0.0978542f,0.97811f,0.183647f, +0.11792f,0.982347f,0.145222f, +0.146369f,0.980631f,0.130149f, +0.169334f,0.978423f,0.118383f, +0.164013f,0.985699f,0.0386944f, +0.265906f,0.961228f,0.0730397f, +0.245913f,0.944548f,0.217615f, +0.193695f,0.94265f,0.271832f, +0.193351f,0.95598f,0.22072f, +0.0582845f,0.995708f,0.0718875f, +-0.00685416f,0.998237f,0.0589609f, +-0.0637908f,0.997757f,0.0202719f, +0.11477f,0.985697f,0.123411f, +0.150647f,0.970382f,0.188848f, +0.0830539f,0.976206f,0.200309f, +0.0503424f,0.976583f,0.20917f, +-0.0756986f,0.967299f,0.242081f, +-0.38538f,0.913963f,0.127097f, +-0.499709f,0.856093f,0.131896f, +-0.457912f,0.888414f,0.0322019f, +-0.285439f,0.956482f,-0.0605596f, +-0.224005f,0.968049f,-0.112706f, +-0.33892f,0.940492f,-0.0246551f, +-0.468811f,0.882994f,0.0231736f, +-0.219323f,0.927554f,-0.302556f, +0.0032435f,0.972826f,-0.231515f, +0.227016f,0.959392f,-0.167423f, +0.0751831f,0.995555f,-0.0567285f, +-0.21163f,0.975526f,-0.0596754f, +-0.120787f,0.989714f,-0.0766664f, +0.103292f,0.984862f,-0.139202f, +0.130327f,0.957045f,-0.258998f, +0.100597f,0.957666f,-0.269734f, +0.0434385f,0.943793f,-0.327671f, +-0.00659457f,0.974177f,-0.225689f, +-0.0387678f,0.996731f,-0.0708824f, +0.0108947f,0.998722f,-0.049343f, +0.045379f,0.994354f,-0.0959194f, +0.256328f,0.966322f,0.0227405f, +0.338426f,0.940797f,0.0191927f, +0.245639f,0.967185f,0.0649251f, +0.104201f,0.958601f,0.265004f, +-0.106481f,0.952706f,0.284628f, +-0.229215f,0.947098f,0.224647f, +-0.194403f,0.966329f,0.168569f, +-0.00252669f,0.996043f,0.0888332f, +0.156392f,0.987666f,-0.00755935f, +0.321695f,0.943636f,0.0778705f, +0.130492f,0.960095f,0.247363f, +-0.218806f,0.887212f,0.406175f, +-0.387978f,0.851763f,0.352097f, +-0.317465f,0.905687f,0.280974f, +-0.175202f,0.945708f,0.273753f, +-0.0852507f,0.952748f,0.291554f, +-0.110501f,0.951599f,0.28679f, +-0.162568f,0.933525f,0.319534f, +-0.0379096f,0.973407f,0.225923f, +0.243134f,0.964593f,0.102203f, +0.236277f,0.971524f,-0.017745f, +0.298887f,0.954255f,-0.00800205f, +0.225509f,0.966982f,0.118704f, +-0.0160588f,0.939828f,0.341271f, +-0.127862f,0.916925f,0.378021f, +0.078893f,0.93958f,0.333116f, +0.244086f,0.933689f,0.262004f, +0.186692f,0.967385f,0.17121f, +0.108188f,0.990525f,0.0845894f, +0.174941f,0.977766f,0.115627f, +0.231991f,0.970242f,0.0693606f, +0.186114f,0.981267f,0.0497696f, +0.166608f,0.977012f,0.133002f, +0.191728f,0.971565f,0.138929f, +0.25765f,0.957218f,0.131718f, +0.087274f,0.989729f,0.113225f, +-0.00280678f,0.977756f,0.209725f, +0.0607703f,0.980671f,0.185986f, +0.0485237f,0.997381f,0.053629f, +0.0587736f,0.987863f,0.14378f, +0.0482407f,0.976088f,0.211956f, +0.0134663f,0.978159f,0.20742f, +-0.112292f,0.962623f,0.246469f, +-0.319272f,0.919627f,0.228803f, +-0.453582f,0.883075f,0.120176f, +-0.338159f,0.939324f,0.0576029f, +-0.23768f,0.971299f,-0.0092623f, +-0.191895f,0.980604f,-0.0399f, +-0.401044f,0.906011f,-0.135303f, +-0.489506f,0.868205f,-0.081269f, +-0.196977f,0.901169f,-0.386128f, +-0.0562291f,0.922285f,-0.382399f, +0.0867548f,0.952728f,-0.291176f, +0.0232316f,0.988917f,-0.146644f, +-0.11605f,0.968007f,-0.222475f, +-0.0789033f,0.942785f,-0.323929f, +0.139529f,0.948189f,-0.285427f, +0.132434f,0.962288f,-0.23762f, +0.0765905f,0.96807f,-0.238692f, +0.0641003f,0.96574f,-0.251472f, +-0.105766f,0.965216f,-0.239106f, +-0.110895f,0.972771f,-0.203515f, +0.0206339f,0.984024f,-0.176838f, +0.0647147f,0.988173f,-0.139018f, +0.148599f,0.980872f,-0.125734f, +0.271512f,0.961735f,0.0367049f, +0.0561912f,0.976773f,0.206777f, +-0.0583132f,0.913697f,0.402191f, +-0.0462589f,0.893353f,0.446968f, +-0.125152f,0.910112f,0.39501f, +-0.0803843f,0.940756f,0.329418f, +0.0619859f,0.973174f,0.221562f, +0.135828f,0.971328f,0.195124f, +0.132962f,0.954202f,0.267992f, +-0.0325488f,0.903596f,0.427147f, +-0.270164f,0.841605f,0.467668f, +-0.262238f,0.850223f,0.456456f, +-0.212116f,0.889937f,0.403757f, +-0.177521f,0.909486f,0.375929f, +-0.116828f,0.901627f,0.416436f, +-0.0747169f,0.915103f,0.396238f, +-0.119776f,0.962629f,0.242896f, +0.0380452f,0.99097f,0.128572f, +0.304108f,0.937317f,0.17016f, +0.240764f,0.951762f,0.190215f, +0.194326f,0.952804f,0.233243f, +0.142453f,0.936947f,0.31912f, +-0.0935081f,0.945618f,0.31155f, +-0.0887705f,0.956167f,0.27904f, +0.107828f,0.967058f,0.230592f, +0.241042f,0.935322f,0.258984f, +0.259409f,0.922717f,0.285133f, +0.218487f,0.962504f,0.160778f, +0.220571f,0.975062f,0.0245473f, +0.235132f,0.971421f,-0.0324531f, +0.193322f,0.980828f,0.0245576f, +0.123827f,0.992302f,-0.00201728f, +0.206505f,0.97706f,0.0520531f, +0.250594f,0.965023f,0.0770254f, +0.0246334f,0.99033f,0.136524f, +-0.123437f,0.964871f,0.231923f, +0.10276f,0.956911f,0.271591f, +0.090829f,0.970486f,0.223397f, +0.00393218f,0.964068f,0.265627f, +0.045739f,0.962581f,0.267105f, +0.0438394f,0.968724f,0.244235f, +-0.1348f,0.971521f,0.194876f, +-0.247965f,0.950768f,0.185883f, +-0.385563f,0.920067f,0.0694089f, +-0.33646f,0.941527f,0.0179056f, +-0.284408f,0.957673f,0.0444463f, +-0.0809611f,0.98246f,0.167982f, +-0.272195f,0.961849f,0.0275091f, +-0.538305f,0.840251f,-0.0648443f, +-0.138085f,0.947265f,-0.289173f, +-0.112292f,0.943405f,-0.312055f, +-0.0366032f,0.968339f,-0.246942f, +-0.0207584f,0.978499f,-0.205204f, +-0.0114432f,0.978269f,-0.207024f, +-0.017206f,0.978017f,-0.207814f, +-0.00196221f,0.968739f,-0.248075f, +0.111459f,0.982805f,-0.147209f, +0.0917515f,0.980196f,-0.175495f, +0.0783409f,0.987595f,-0.136083f, +-0.0849004f,0.981698f,-0.170473f, +-0.0826208f,0.969176f,-0.232103f, +-0.0513296f,0.962825f,-0.265205f, +-0.0169212f,0.988046f,-0.153227f, +0.0442536f,0.99886f,0.017891f, +0.0803284f,0.974024f,0.211719f, +-0.118041f,0.942704f,0.312052f, +-0.187621f,0.893485f,0.408023f, +-0.0735772f,0.857937f,0.508459f, +-0.0838693f,0.837024f,0.5407f, +-0.00356882f,0.863268f,0.504733f, +0.117551f,0.889838f,0.440874f, +0.141271f,0.893306f,0.426669f, +0.0270129f,0.906148f,0.422097f, +-0.109486f,0.851548f,0.512717f, +-0.266831f,0.814637f,0.514944f, +-0.253628f,0.788787f,0.559899f, +-0.216685f,0.776961f,0.591083f, +-0.15137f,0.760068f,0.631968f, +-0.119157f,0.801398f,0.586143f, +0.0626697f,0.817134f,0.573031f, +0.150716f,0.886392f,0.437714f, +0.0719955f,0.965525f,0.250157f, +0.170594f,0.93758f,0.303054f, +0.205981f,0.906978f,0.367374f, +0.159242f,0.93166f,0.326575f, +0.163686f,0.939188f,0.301881f, +0.00255834f,0.983457f,0.181126f, +-0.0246414f,0.997684f,0.063397f, +0.103068f,0.994148f,0.0323463f, +0.175261f,0.977189f,0.119941f, +0.238397f,0.946614f,0.216998f, +0.376211f,0.893689f,0.244508f, +0.336321f,0.93903f,0.0714918f, +0.22632f,0.974025f,-0.00733613f, +0.155366f,0.98668f,0.0481989f, +0.129371f,0.988467f,0.0787169f, +0.140766f,0.985457f,0.095182f, +0.181141f,0.974304f,0.133867f, +-0.0259321f,0.983166f,0.180868f, +-0.16382f,0.974748f,0.151756f, +0.12842f,0.977623f,0.166619f, +0.102805f,0.986615f,0.12658f, +-0.0352231f,0.991461f,0.125559f, +0.0344472f,0.990276f,0.134782f, +0.100258f,0.97877f,0.178768f, +-0.0763414f,0.992566f,0.0947915f, +-0.24142f,0.968616f,0.059149f, +-0.325267f,0.943242f,0.06705f, +-0.302069f,0.9528f,0.0304413f, +-0.317187f,0.948361f,-0.0017587f, +-0.219267f,0.973832f,0.059775f, +-0.187608f,0.954493f,0.231832f, +-0.46452f,0.867868f,0.176143f, +-0.203418f,0.948131f,-0.244273f, +-0.139664f,0.973265f,-0.182342f, +-0.0536959f,0.988785f,-0.139361f, +-0.00355604f,0.986781f,-0.162022f, +-0.0572809f,0.980561f,-0.187669f, +-0.0374007f,0.985205f,-0.167247f, +0.0555765f,0.976159f,-0.209822f, +0.0908927f,0.962348f,-0.256173f, +0.0600715f,0.972748f,-0.223946f, +0.0442581f,0.987652f,-0.150282f, +-0.0260568f,0.986636f,-0.160841f, +-0.0937884f,0.986183f,-0.136552f, +-0.00585357f,0.999959f,-0.00691373f, +-0.168872f,0.982349f,-0.0804476f, +-0.215485f,0.975309f,0.0483622f, +-0.0961691f,0.964354f,0.246521f, +-0.114487f,0.922048f,0.369757f, +-0.269656f,0.899414f,0.344007f, +-0.21772f,0.897789f,0.382849f, +-0.126818f,0.886934f,0.444145f, +0.0624514f,0.872607f,0.484415f, +0.170504f,0.863439f,0.474764f, +0.127681f,0.882519f,0.452612f, +0.0249418f,0.887332f,0.460457f, +-0.228952f,0.87943f,0.417354f, +-0.336679f,0.801754f,0.493799f, +-0.354676f,0.742594f,0.568119f, +-0.265358f,0.728648f,0.631393f, +-0.0874663f,0.774696f,0.626255f, +0.0313715f,0.816845f,0.576004f, +0.138491f,0.877406f,0.459325f, +0.251487f,0.873743f,0.416325f, +0.149012f,0.891076f,0.428695f, +0.134082f,0.895567f,0.424244f, +0.259356f,0.879751f,0.398462f, +0.273738f,0.923515f,0.268677f, +0.242075f,0.954352f,0.174962f, +0.166067f,0.977105f,0.132992f, +0.0519593f,0.998404f,0.022142f, +0.0706628f,0.997395f,0.0145074f, +0.0910476f,0.994722f,0.0473141f, +0.126598f,0.990827f,0.0472679f, +0.33108f,0.937289f,0.108974f, +0.427456f,0.888646f,0.166103f, +0.265492f,0.95292f,0.14648f, +0.0868945f,0.990384f,0.10765f, +0.0739344f,0.98242f,0.171417f, +0.14882f,0.964095f,0.219937f, +0.160065f,0.969614f,0.185009f, +0.0379065f,0.980794f,0.191328f, +-0.111879f,0.992654f,0.0460448f, +0.101571f,0.994616f,0.0205655f, +0.134276f,0.987226f,0.0857599f, +0.00322228f,0.996946f,0.0780295f, +-0.00585508f,0.99961f,0.0273218f, +0.102527f,0.992913f,0.0601057f, +-0.0243337f,0.999696f,0.00385478f, +-0.236106f,0.971591f,0.0163038f, +-0.335881f,0.941896f,0.00400261f, +-0.319925f,0.947097f,0.0255887f, +-0.262465f,0.960477f,0.0927118f, +-0.320184f,0.947305f,-0.00973767f, +-0.358146f,0.929034f,0.0928862f, +-0.431591f,0.882961f,0.184686f, +-0.350194f,0.913588f,-0.20669f, +-0.241714f,0.958821f,-0.149118f, +-0.0874799f,0.991928f,-0.0917931f, +-0.00637736f,0.998289f,-0.0581162f, +0.0261719f,0.997729f,-0.0620574f, +0.00430678f,0.979141f,-0.203135f, +0.121705f,0.971178f,-0.20494f, +0.10219f,0.965909f,-0.237861f, +0.00407698f,0.957171f,-0.289495f, +-0.0386862f,0.968014f,-0.247897f, +-0.0509849f,0.995926f,-0.0743816f, +-0.228245f,0.973592f,-0.00474817f, +-0.140696f,0.979081f,0.146984f, +-0.104046f,0.966867f,0.233113f, +-0.254332f,0.94315f,0.213969f, +-0.211685f,0.953746f,0.213442f, +-0.245201f,0.93619f,0.251844f, +-0.247199f,0.912647f,0.325527f, +-0.213426f,0.932543f,0.291228f, +-0.170741f,0.942588f,0.28701f, +-0.0363946f,0.943193f,0.330245f, +0.169433f,0.88607f,0.431478f, +0.12169f,0.89261f,0.434096f, +0.0508642f,0.869951f,0.490509f, +-0.175065f,0.875657f,0.450086f, +-0.464211f,0.815419f,0.345833f, +-0.467728f,0.796275f,0.383635f, +-0.295863f,0.865688f,0.403795f, +-0.0706376f,0.91172f,0.404693f, +0.151265f,0.880258f,0.449738f, +0.239887f,0.896678f,0.372052f, +0.270966f,0.902061f,0.335952f, +0.133682f,0.938928f,0.317085f, +0.132181f,0.949509f,0.284538f, +0.337234f,0.911457f,0.235624f, +0.391568f,0.908725f,0.144547f, +0.297707f,0.949115f,0.10272f, +0.163642f,0.985787f,0.038011f, +0.0603665f,0.994817f,0.0818182f, +0.0342529f,0.984393f,0.172617f, +0.146f,0.969394f,0.197379f, +0.189586f,0.979398f,0.0695505f, +0.32179f,0.946595f,0.0202369f, +0.339913f,0.938655f,0.0581868f, +0.255631f,0.940824f,0.222493f, +0.130905f,0.959362f,0.249975f, +0.0245005f,0.97884f,0.203155f, +0.116898f,0.96642f,0.228839f, +0.217161f,0.952887f,0.211771f, +0.0905814f,0.991503f,0.0933592f, +0.00963547f,0.999795f,0.0178162f, +0.0707892f,0.997359f,-0.0162393f, +0.0454623f,0.996335f,0.0724521f, +0.025845f,0.99119f,0.129903f, +0.0553395f,0.998031f,0.0295398f, +0.0632528f,0.997901f,0.0138837f, +-0.000723073f,0.987186f,0.159572f, +-0.246121f,0.956173f,0.158611f, +-0.292993f,0.948379f,0.121377f, +-0.358856f,0.933219f,0.0180357f, +-0.312153f,0.948631f,0.0515794f, +-0.263061f,0.955548f,0.133141f, +-0.387996f,0.907685f,0.159898f, +-0.516559f,0.845117f,0.137638f, +-0.310178f,0.948377f,-0.0661154f, +-0.300026f,0.949757f,-0.0891454f, +-0.137668f,0.990363f,0.0151269f, +-0.0326899f,0.997118f,0.0684562f, +0.0835016f,0.994462f,0.0638203f, +0.0992766f,0.995028f,0.00796582f, +0.068628f,0.997514f,-0.0159775f, +0.181484f,0.983266f,0.0158879f, +0.0929905f,0.991619f,-0.0896955f, +-0.159863f,0.9831f,-0.0892104f, +-0.274969f,0.956779f,0.094689f, +-0.2578f,0.933703f,0.248472f, +-0.255563f,0.934109f,0.249254f, +-0.183445f,0.905456f,0.382751f, +-0.258353f,0.860148f,0.439771f, +-0.12588f,0.873686f,0.469923f, +-0.210169f,0.916013f,0.341684f, +-0.272883f,0.91339f,0.302083f, +-0.180317f,0.937251f,0.298406f, +-0.199625f,0.942232f,0.268977f, +-0.0859427f,0.9396f,0.33131f, +0.0831524f,0.928739f,0.361288f, +0.0997333f,0.904186f,0.415333f, +-0.0517762f,0.893569f,0.445931f, +-0.109718f,0.87826f,0.465426f, +-0.369685f,0.848108f,0.379534f, +-0.446603f,0.811841f,0.376112f, +-0.267849f,0.883969f,0.383218f, +-0.10672f,0.930725f,0.349801f, +0.10205f,0.92892f,0.355941f, +0.253281f,0.903219f,0.346475f, +0.270898f,0.880967f,0.387957f, +0.236849f,0.896348f,0.374784f, +0.206634f,0.946539f,0.247723f, +0.405577f,0.89206f,0.199342f, +0.379351f,0.915673f,0.1328f, +0.334598f,0.922412f,0.192872f, +0.211991f,0.969195f,0.125385f, +-0.0201216f,0.993487f,0.112152f, +-0.0648495f,0.986484f,0.150479f, +0.170924f,0.975936f,0.135405f, +0.29249f,0.9553f,0.0430209f, +0.300918f,0.953641f,0.00421578f, +0.280252f,0.954656f,0.100457f, +0.110799f,0.982326f,0.150862f, +0.111953f,0.970209f,0.214852f, +0.0917898f,0.974074f,0.206772f, +0.0706157f,0.981239f,0.179398f, +0.263217f,0.920389f,0.289137f, +0.266708f,0.942871f,0.199653f, +0.0169344f,0.99983f,0.00724636f, +0.0586405f,0.99674f,0.0554216f, +-0.0335948f,0.99924f,0.0197934f, +0.0130139f,0.996641f,0.0808552f, +0.158081f,0.974057f,0.161934f, +-0.0718701f,0.984912f,0.157428f, +-0.146615f,0.930223f,0.336437f, +-0.215441f,0.915614f,0.339465f, +-0.194576f,0.929319f,0.313857f, +-0.21244f,0.956751f,0.198736f, +-0.353032f,0.933914f,0.0563254f, +-0.387138f,0.913346f,0.126188f, +-0.421226f,0.884098f,0.202334f, +-0.478159f,0.863227f,0.161871f, +-0.144962f,0.987796f,0.0569687f, +-0.329752f,0.937067f,-0.114758f, +-0.228627f,0.973393f,0.0153452f, +-0.0297707f,0.988896f,0.1456f, +0.0737235f,0.992418f,0.0983429f, +0.119683f,0.983634f,0.134687f, +0.0735029f,0.988539f,0.131863f, +0.205816f,0.971725f,0.115713f, +0.105316f,0.994111f,0.0255379f, +-0.224655f,0.970814f,0.0839657f, +-0.371877f,0.9075f,0.195325f, +-0.304303f,0.906448f,0.292833f, +-0.280483f,0.900657f,0.331883f, +-0.306628f,0.862929f,0.401664f, +-0.272078f,0.807801f,0.522907f, +-0.0728986f,0.827771f,0.55631f, +-0.0766844f,0.868115f,0.490404f, +-0.262952f,0.903979f,0.337163f, +-0.116268f,0.92805f,0.353844f, +-0.236581f,0.941122f,0.241494f, +-0.103825f,0.933685f,0.342713f, +0.0620174f,0.936003f,0.346485f, +0.0525461f,0.928042f,0.368751f, +-0.037371f,0.900626f,0.432986f, +-0.0859425f,0.920181f,0.381944f, +-0.402084f,0.867474f,0.292945f, +-0.458834f,0.792013f,0.402725f, +-0.247545f,0.839465f,0.483756f, +-0.0206347f,0.857039f,0.514838f, +0.131938f,0.906082f,0.402004f, +0.260907f,0.906936f,0.330749f, +0.222736f,0.912076f,0.344246f, +0.286017f,0.867948f,0.406029f, +0.265664f,0.918021f,0.29438f, +0.386646f,0.888781f,0.246116f, +0.416594f,0.869611f,0.265003f, +0.291338f,0.924889f,0.244341f, +0.264598f,0.920497f,0.287528f, +-0.0209737f,0.965015f,0.261353f, +0.011928f,0.966786f,0.255307f, +0.209759f,0.975171f,0.0710066f, +0.379568f,0.924828f,0.0249204f, +0.227757f,0.968062f,-0.104795f, +0.230276f,0.968937f,0.0901831f, +0.121279f,0.97806f,0.169381f, +0.101139f,0.989453f,0.103701f, +0.125341f,0.986876f,0.101809f, +0.00931107f,0.998148f,0.0601183f, +0.147262f,0.96746f,0.205755f, +0.372526f,0.861294f,0.34554f, +0.0770606f,0.989688f,0.120749f, +0.0673416f,0.990666f,0.11852f, +0.0242126f,0.998823f,0.0420167f, +-0.0975945f,0.993903f,-0.0513095f, +0.0117629f,0.986762f,0.16175f, +-0.119035f,0.908985f,0.399472f, +-0.171696f,0.877378f,0.448027f, +-0.168225f,0.894295f,0.414653f, +-0.158105f,0.915758f,0.369311f, +-0.0984338f,0.938718f,0.330333f, +-0.319812f,0.930617f,0.177966f, +-0.398204f,0.897351f,0.190248f, +-0.414882f,0.896338f,0.156369f, +-0.434877f,0.894265f,0.105701f, +}; + +btScalar Landscape07Tex[] = { +0.507813f,0.742188f, +0.507813f,0.734375f, +0.515625f,0.742188f, +0.515625f,0.734375f, +0.523438f,0.742188f, +0.523438f,0.734375f, +0.53125f,0.742188f, +0.53125f,0.734375f, +0.539063f,0.742188f, +0.539063f,0.734375f, +0.546875f,0.742188f, +0.546875f,0.734375f, +0.554688f,0.742188f, +0.554688f,0.734375f, +0.5625f,0.742188f, +0.5625f,0.734375f, +0.570313f,0.742188f, +0.570313f,0.734375f, +0.578125f,0.742188f, +0.578125f,0.734375f, +0.585938f,0.742188f, +0.585938f,0.734375f, +0.59375f,0.742188f, +0.59375f,0.734375f, +0.601563f,0.742188f, +0.601563f,0.734375f, +0.609375f,0.742188f, +0.609375f,0.734375f, +0.617188f,0.742188f, +0.617188f,0.734375f, +0.625f,0.742188f, +0.625f,0.734375f, +0.632813f,0.742188f, +0.632813f,0.734375f, +0.640625f,0.742188f, +0.640625f,0.734375f, +0.648438f,0.742188f, +0.648438f,0.734375f, +0.65625f,0.742188f, +0.65625f,0.734375f, +0.664063f,0.742188f, +0.664063f,0.734375f, +0.671875f,0.742188f, +0.671875f,0.734375f, +0.679688f,0.742188f, +0.679688f,0.734375f, +0.6875f,0.742188f, +0.6875f,0.734375f, +0.695313f,0.742188f, +0.695313f,0.734375f, +0.703125f,0.742188f, +0.703125f,0.734375f, +0.710938f,0.742188f, +0.710938f,0.734375f, +0.71875f,0.742188f, +0.71875f,0.734375f, +0.726563f,0.742188f, +0.726563f,0.734375f, +0.734375f,0.742188f, +0.734375f,0.734375f, +0.742188f,0.742188f, +0.742188f,0.734375f, +0.75f,0.742188f, +0.75f,0.734375f, +0.757813f,0.742188f, +0.757813f,0.734375f, +0.765625f,0.742188f, +0.765625f,0.734375f, +0.773438f,0.742188f, +0.773438f,0.734375f, +0.78125f,0.742188f, +0.78125f,0.734375f, +0.789063f,0.742188f, +0.789063f,0.734375f, +0.796875f,0.742188f, +0.796875f,0.734375f, +0.804688f,0.742188f, +0.804688f,0.734375f, +0.8125f,0.742188f, +0.8125f,0.734375f, +0.820313f,0.742188f, +0.820313f,0.734375f, +0.828125f,0.742188f, +0.828125f,0.734375f, +0.835938f,0.742188f, +0.835938f,0.734375f, +0.84375f,0.742188f, +0.84375f,0.734375f, +0.851563f,0.742188f, +0.851563f,0.734375f, +0.859375f,0.742188f, +0.859375f,0.734375f, +0.867188f,0.742188f, +0.867188f,0.734375f, +0.875f,0.742188f, +0.875f,0.734375f, +0.882813f,0.742188f, +0.882813f,0.734375f, +0.890625f,0.742188f, +0.890625f,0.734375f, +0.898438f,0.742188f, +0.898438f,0.734375f, +0.90625f,0.742188f, +0.90625f,0.734375f, +0.914063f,0.742188f, +0.914063f,0.734375f, +0.921875f,0.742188f, +0.921875f,0.734375f, +0.929688f,0.742188f, +0.929688f,0.734375f, +0.9375f,0.742188f, +0.9375f,0.734375f, +0.945313f,0.742188f, +0.945313f,0.734375f, +0.953125f,0.742188f, +0.953125f,0.734375f, +0.960938f,0.742188f, +0.960938f,0.734375f, +0.96875f,0.742188f, +0.96875f,0.734375f, +0.976563f,0.742188f, +0.976563f,0.734375f, +0.984375f,0.742188f, +0.984375f,0.734375f, +0.992188f,0.742188f, +0.992188f,0.734375f, +1.0f,0.742188f, +1.0f,0.734375f, +0.507813f,0.75f, +0.515625f,0.75f, +0.523438f,0.75f, +0.53125f,0.75f, +0.539063f,0.75f, +0.546875f,0.75f, +0.554688f,0.75f, +0.5625f,0.75f, +0.570313f,0.75f, +0.578125f,0.75f, +0.585938f,0.75f, +0.59375f,0.75f, +0.601563f,0.75f, +0.609375f,0.75f, +0.617188f,0.75f, +0.625f,0.75f, +0.632813f,0.75f, +0.640625f,0.75f, +0.648438f,0.75f, +0.65625f,0.75f, +0.664063f,0.75f, +0.671875f,0.75f, +0.679688f,0.75f, +0.6875f,0.75f, +0.695313f,0.75f, +0.703125f,0.75f, +0.710938f,0.75f, +0.71875f,0.75f, +0.726563f,0.75f, +0.734375f,0.75f, +0.742188f,0.75f, +0.75f,0.75f, +0.757813f,0.75f, +0.765625f,0.75f, +0.773438f,0.75f, +0.78125f,0.75f, +0.789063f,0.75f, +0.796875f,0.75f, +0.804688f,0.75f, +0.8125f,0.75f, +0.820313f,0.75f, +0.828125f,0.75f, +0.835938f,0.75f, +0.84375f,0.75f, +0.851563f,0.75f, +0.859375f,0.75f, +0.867188f,0.75f, +0.875f,0.75f, +0.882813f,0.75f, +0.890625f,0.75f, +0.898438f,0.75f, +0.90625f,0.75f, +0.914063f,0.75f, +0.921875f,0.75f, +0.929688f,0.75f, +0.9375f,0.75f, +0.945313f,0.75f, +0.953125f,0.75f, +0.960938f,0.75f, +0.96875f,0.75f, +0.976563f,0.75f, +0.984375f,0.75f, +0.992188f,0.75f, +1.0f,0.75f, +0.507813f,0.757813f, +0.515625f,0.757813f, +0.523438f,0.757813f, +0.53125f,0.757813f, +0.539063f,0.757813f, +0.546875f,0.757813f, +0.554688f,0.757813f, +0.5625f,0.757813f, +0.570313f,0.757813f, +0.578125f,0.757813f, +0.585938f,0.757813f, +0.59375f,0.757813f, +0.601563f,0.757813f, +0.609375f,0.757813f, +0.617188f,0.757813f, +0.625f,0.757813f, +0.632813f,0.757813f, +0.640625f,0.757813f, +0.648438f,0.757813f, +0.65625f,0.757813f, +0.664063f,0.757813f, +0.671875f,0.757813f, +0.679688f,0.757813f, +0.6875f,0.757813f, +0.695313f,0.757813f, +0.703125f,0.757813f, +0.710938f,0.757813f, +0.71875f,0.757813f, +0.726563f,0.757813f, +0.734375f,0.757813f, +0.742188f,0.757813f, +0.75f,0.757813f, +0.757813f,0.757813f, +0.765625f,0.757813f, +0.773438f,0.757813f, +0.78125f,0.757813f, +0.789063f,0.757813f, +0.796875f,0.757813f, +0.804688f,0.757813f, +0.8125f,0.757813f, +0.820313f,0.757813f, +0.828125f,0.757813f, +0.835938f,0.757813f, +0.84375f,0.757813f, +0.851563f,0.757813f, +0.859375f,0.757813f, +0.867188f,0.757813f, +0.875f,0.757813f, +0.882813f,0.757813f, +0.890625f,0.757813f, +0.898438f,0.757813f, +0.90625f,0.757813f, +0.914063f,0.757813f, +0.921875f,0.757813f, +0.929688f,0.757813f, +0.9375f,0.757813f, +0.945313f,0.757813f, +0.953125f,0.757813f, +0.960938f,0.757813f, +0.96875f,0.757813f, +0.976563f,0.757813f, +0.984375f,0.757813f, +0.992188f,0.757813f, +1.0f,0.757813f, +0.507813f,0.765625f, +0.515625f,0.765625f, +0.523438f,0.765625f, +0.53125f,0.765625f, +0.539063f,0.765625f, +0.546875f,0.765625f, +0.554688f,0.765625f, +0.5625f,0.765625f, +0.570313f,0.765625f, +0.578125f,0.765625f, +0.585938f,0.765625f, +0.59375f,0.765625f, +0.601563f,0.765625f, +0.609375f,0.765625f, +0.617188f,0.765625f, +0.625f,0.765625f, +0.632813f,0.765625f, +0.640625f,0.765625f, +0.648438f,0.765625f, +0.65625f,0.765625f, +0.664063f,0.765625f, +0.671875f,0.765625f, +0.679688f,0.765625f, +0.6875f,0.765625f, +0.695313f,0.765625f, +0.703125f,0.765625f, +0.710938f,0.765625f, +0.71875f,0.765625f, +0.726563f,0.765625f, +0.734375f,0.765625f, +0.742188f,0.765625f, +0.75f,0.765625f, +0.757813f,0.765625f, +0.765625f,0.765625f, +0.773438f,0.765625f, +0.78125f,0.765625f, +0.789063f,0.765625f, +0.796875f,0.765625f, +0.804688f,0.765625f, +0.8125f,0.765625f, +0.820313f,0.765625f, +0.828125f,0.765625f, +0.835938f,0.765625f, +0.84375f,0.765625f, +0.851563f,0.765625f, +0.859375f,0.765625f, +0.867188f,0.765625f, +0.875f,0.765625f, +0.882813f,0.765625f, +0.890625f,0.765625f, +0.898438f,0.765625f, +0.90625f,0.765625f, +0.914063f,0.765625f, +0.921875f,0.765625f, +0.929688f,0.765625f, +0.9375f,0.765625f, +0.945313f,0.765625f, +0.953125f,0.765625f, +0.960938f,0.765625f, +0.96875f,0.765625f, +0.976563f,0.765625f, +0.984375f,0.765625f, +0.992188f,0.765625f, +1.0f,0.765625f, +0.507813f,0.773438f, +0.515625f,0.773438f, +0.523438f,0.773438f, +0.53125f,0.773438f, +0.539063f,0.773438f, +0.546875f,0.773438f, +0.554688f,0.773438f, +0.5625f,0.773438f, +0.570313f,0.773438f, +0.578125f,0.773438f, +0.585938f,0.773438f, +0.59375f,0.773438f, +0.601563f,0.773438f, +0.609375f,0.773438f, +0.617188f,0.773438f, +0.625f,0.773438f, +0.632813f,0.773438f, +0.640625f,0.773438f, +0.648438f,0.773438f, +0.65625f,0.773438f, +0.664063f,0.773438f, +0.671875f,0.773438f, +0.679688f,0.773438f, +0.6875f,0.773438f, +0.695313f,0.773438f, +0.703125f,0.773438f, +0.710938f,0.773438f, +0.71875f,0.773438f, +0.726563f,0.773438f, +0.734375f,0.773438f, +0.742188f,0.773438f, +0.75f,0.773438f, +0.757813f,0.773438f, +0.765625f,0.773438f, +0.773438f,0.773438f, +0.78125f,0.773438f, +0.789063f,0.773438f, +0.796875f,0.773438f, +0.804688f,0.773438f, +0.8125f,0.773438f, +0.820313f,0.773438f, +0.828125f,0.773438f, +0.835938f,0.773438f, +0.84375f,0.773438f, +0.851563f,0.773438f, +0.859375f,0.773438f, +0.867188f,0.773438f, +0.875f,0.773438f, +0.882813f,0.773438f, +0.890625f,0.773438f, +0.898438f,0.773438f, +0.90625f,0.773438f, +0.914063f,0.773438f, +0.921875f,0.773438f, +0.929688f,0.773438f, +0.9375f,0.773438f, +0.945313f,0.773438f, +0.953125f,0.773438f, +0.960938f,0.773438f, +0.96875f,0.773438f, +0.976563f,0.773438f, +0.984375f,0.773438f, +0.992188f,0.773438f, +1.0f,0.773438f, +0.507813f,0.78125f, +0.515625f,0.78125f, +0.523438f,0.78125f, +0.53125f,0.78125f, +0.539063f,0.78125f, +0.546875f,0.78125f, +0.554688f,0.78125f, +0.5625f,0.78125f, +0.570313f,0.78125f, +0.578125f,0.78125f, +0.585938f,0.78125f, +0.59375f,0.78125f, +0.601563f,0.78125f, +0.609375f,0.78125f, +0.617188f,0.78125f, +0.625f,0.78125f, +0.632813f,0.78125f, +0.640625f,0.78125f, +0.648438f,0.78125f, +0.65625f,0.78125f, +0.664063f,0.78125f, +0.671875f,0.78125f, +0.679688f,0.78125f, +0.6875f,0.78125f, +0.695313f,0.78125f, +0.703125f,0.78125f, +0.710938f,0.78125f, +0.71875f,0.78125f, +0.726563f,0.78125f, +0.734375f,0.78125f, +0.742188f,0.78125f, +0.75f,0.78125f, +0.757813f,0.78125f, +0.765625f,0.78125f, +0.773438f,0.78125f, +0.78125f,0.78125f, +0.789063f,0.78125f, +0.796875f,0.78125f, +0.804688f,0.78125f, +0.8125f,0.78125f, +0.820313f,0.78125f, +0.828125f,0.78125f, +0.835938f,0.78125f, +0.84375f,0.78125f, +0.851563f,0.78125f, +0.859375f,0.78125f, +0.867188f,0.78125f, +0.875f,0.78125f, +0.882813f,0.78125f, +0.890625f,0.78125f, +0.898438f,0.78125f, +0.90625f,0.78125f, +0.914063f,0.78125f, +0.921875f,0.78125f, +0.929688f,0.78125f, +0.9375f,0.78125f, +0.945313f,0.78125f, +0.953125f,0.78125f, +0.960938f,0.78125f, +0.96875f,0.78125f, +0.976563f,0.78125f, +0.984375f,0.78125f, +0.992188f,0.78125f, +1.0f,0.78125f, +0.507813f,0.789063f, +0.515625f,0.789063f, +0.523438f,0.789063f, +0.53125f,0.789063f, +0.539063f,0.789063f, +0.546875f,0.789063f, +0.554688f,0.789063f, +0.5625f,0.789063f, +0.570313f,0.789063f, +0.578125f,0.789063f, +0.585938f,0.789063f, +0.59375f,0.789063f, +0.601563f,0.789063f, +0.609375f,0.789063f, +0.617188f,0.789063f, +0.625f,0.789063f, +0.632813f,0.789063f, +0.640625f,0.789063f, +0.648438f,0.789063f, +0.65625f,0.789063f, +0.664063f,0.789063f, +0.671875f,0.789063f, +0.679688f,0.789063f, +0.6875f,0.789063f, +0.695313f,0.789063f, +0.703125f,0.789063f, +0.710938f,0.789063f, +0.71875f,0.789063f, +0.726563f,0.789063f, +0.734375f,0.789063f, +0.742188f,0.789063f, +0.75f,0.789063f, +0.757813f,0.789063f, +0.765625f,0.789063f, +0.773438f,0.789063f, +0.78125f,0.789063f, +0.789063f,0.789063f, +0.796875f,0.789063f, +0.804688f,0.789063f, +0.8125f,0.789063f, +0.820313f,0.789063f, +0.828125f,0.789063f, +0.835938f,0.789063f, +0.84375f,0.789063f, +0.851563f,0.789063f, +0.859375f,0.789063f, +0.867188f,0.789063f, +0.875f,0.789063f, +0.882813f,0.789063f, +0.890625f,0.789063f, +0.898438f,0.789063f, +0.90625f,0.789063f, +0.914063f,0.789063f, +0.921875f,0.789063f, +0.929688f,0.789063f, +0.9375f,0.789063f, +0.945313f,0.789063f, +0.953125f,0.789063f, +0.960938f,0.789063f, +0.96875f,0.789063f, +0.976563f,0.789063f, +0.984375f,0.789063f, +0.992188f,0.789063f, +1.0f,0.789063f, +0.507813f,0.796875f, +0.515625f,0.796875f, +0.523438f,0.796875f, +0.53125f,0.796875f, +0.539063f,0.796875f, +0.546875f,0.796875f, +0.554688f,0.796875f, +0.5625f,0.796875f, +0.570313f,0.796875f, +0.578125f,0.796875f, +0.585938f,0.796875f, +0.59375f,0.796875f, +0.601563f,0.796875f, +0.609375f,0.796875f, +0.617188f,0.796875f, +0.625f,0.796875f, +0.632813f,0.796875f, +0.640625f,0.796875f, +0.648438f,0.796875f, +0.65625f,0.796875f, +0.664063f,0.796875f, +0.671875f,0.796875f, +0.679688f,0.796875f, +0.6875f,0.796875f, +0.695313f,0.796875f, +0.703125f,0.796875f, +0.710938f,0.796875f, +0.71875f,0.796875f, +0.726563f,0.796875f, +0.734375f,0.796875f, +0.742188f,0.796875f, +0.75f,0.796875f, +0.757813f,0.796875f, +0.765625f,0.796875f, +0.773438f,0.796875f, +0.78125f,0.796875f, +0.789063f,0.796875f, +0.796875f,0.796875f, +0.804688f,0.796875f, +0.8125f,0.796875f, +0.820313f,0.796875f, +0.828125f,0.796875f, +0.835938f,0.796875f, +0.84375f,0.796875f, +0.851563f,0.796875f, +0.859375f,0.796875f, +0.867188f,0.796875f, +0.875f,0.796875f, +0.882813f,0.796875f, +0.890625f,0.796875f, +0.898438f,0.796875f, +0.90625f,0.796875f, +0.914063f,0.796875f, +0.921875f,0.796875f, +0.929688f,0.796875f, +0.9375f,0.796875f, +0.945313f,0.796875f, +0.953125f,0.796875f, +0.960938f,0.796875f, +0.96875f,0.796875f, +0.976563f,0.796875f, +0.984375f,0.796875f, +0.992188f,0.796875f, +1.0f,0.796875f, +0.507813f,0.804688f, +0.515625f,0.804688f, +0.523438f,0.804688f, +0.53125f,0.804688f, +0.539063f,0.804688f, +0.546875f,0.804688f, +0.554688f,0.804688f, +0.5625f,0.804688f, +0.570313f,0.804688f, +0.578125f,0.804688f, +0.585938f,0.804688f, +0.59375f,0.804688f, +0.601563f,0.804688f, +0.609375f,0.804688f, +0.617188f,0.804688f, +0.625f,0.804688f, +0.632813f,0.804688f, +0.640625f,0.804688f, +0.648438f,0.804688f, +0.65625f,0.804688f, +0.664063f,0.804688f, +0.671875f,0.804688f, +0.679688f,0.804688f, +0.6875f,0.804688f, +0.695313f,0.804688f, +0.703125f,0.804688f, +0.710938f,0.804688f, +0.71875f,0.804688f, +0.726563f,0.804688f, +0.734375f,0.804688f, +0.742188f,0.804688f, +0.75f,0.804688f, +0.757813f,0.804688f, +0.765625f,0.804688f, +0.773438f,0.804688f, +0.78125f,0.804688f, +0.789063f,0.804688f, +0.796875f,0.804688f, +0.804688f,0.804688f, +0.8125f,0.804688f, +0.820313f,0.804688f, +0.828125f,0.804688f, +0.835938f,0.804688f, +0.84375f,0.804688f, +0.851563f,0.804688f, +0.859375f,0.804688f, +0.867188f,0.804688f, +0.875f,0.804688f, +0.882813f,0.804688f, +0.890625f,0.804688f, +0.898438f,0.804688f, +0.90625f,0.804688f, +0.914063f,0.804688f, +0.921875f,0.804688f, +0.929688f,0.804688f, +0.9375f,0.804688f, +0.945313f,0.804688f, +0.953125f,0.804688f, +0.960938f,0.804688f, +0.96875f,0.804688f, +0.976563f,0.804688f, +0.984375f,0.804688f, +0.992188f,0.804688f, +1.0f,0.804688f, +0.507813f,0.8125f, +0.515625f,0.8125f, +0.523438f,0.8125f, +0.53125f,0.8125f, +0.539063f,0.8125f, +0.546875f,0.8125f, +0.554688f,0.8125f, +0.5625f,0.8125f, +0.570313f,0.8125f, +0.578125f,0.8125f, +0.585938f,0.8125f, +0.59375f,0.8125f, +0.601563f,0.8125f, +0.609375f,0.8125f, +0.617188f,0.8125f, +0.625f,0.8125f, +0.632813f,0.8125f, +0.640625f,0.8125f, +0.648438f,0.8125f, +0.65625f,0.8125f, +0.664063f,0.8125f, +0.671875f,0.8125f, +0.679688f,0.8125f, +0.6875f,0.8125f, +0.695313f,0.8125f, +0.703125f,0.8125f, +0.710938f,0.8125f, +0.71875f,0.8125f, +0.726563f,0.8125f, +0.734375f,0.8125f, +0.742188f,0.8125f, +0.75f,0.8125f, +0.757813f,0.8125f, +0.765625f,0.8125f, +0.773438f,0.8125f, +0.78125f,0.8125f, +0.789063f,0.8125f, +0.796875f,0.8125f, +0.804688f,0.8125f, +0.8125f,0.8125f, +0.820313f,0.8125f, +0.828125f,0.8125f, +0.835938f,0.8125f, +0.84375f,0.8125f, +0.851563f,0.8125f, +0.859375f,0.8125f, +0.867188f,0.8125f, +0.875f,0.8125f, +0.882813f,0.8125f, +0.890625f,0.8125f, +0.898438f,0.8125f, +0.90625f,0.8125f, +0.914063f,0.8125f, +0.921875f,0.8125f, +0.929688f,0.8125f, +0.9375f,0.8125f, +0.945313f,0.8125f, +0.953125f,0.8125f, +0.960938f,0.8125f, +0.96875f,0.8125f, +0.976563f,0.8125f, +0.984375f,0.8125f, +0.992188f,0.8125f, +1.0f,0.8125f, +0.507813f,0.820313f, +0.515625f,0.820313f, +0.523438f,0.820313f, +0.53125f,0.820313f, +0.539063f,0.820313f, +0.546875f,0.820313f, +0.554688f,0.820313f, +0.5625f,0.820313f, +0.570313f,0.820313f, +0.578125f,0.820313f, +0.585938f,0.820313f, +0.59375f,0.820313f, +0.601563f,0.820313f, +0.609375f,0.820313f, +0.617188f,0.820313f, +0.625f,0.820313f, +0.632813f,0.820313f, +0.640625f,0.820313f, +0.648438f,0.820313f, +0.65625f,0.820313f, +0.664063f,0.820313f, +0.671875f,0.820313f, +0.679688f,0.820313f, +0.6875f,0.820313f, +0.695313f,0.820313f, +0.703125f,0.820313f, +0.710938f,0.820313f, +0.71875f,0.820313f, +0.726563f,0.820313f, +0.734375f,0.820313f, +0.742188f,0.820313f, +0.75f,0.820313f, +0.757813f,0.820313f, +0.765625f,0.820313f, +0.773438f,0.820313f, +0.78125f,0.820313f, +0.789063f,0.820313f, +0.796875f,0.820313f, +0.804688f,0.820313f, +0.8125f,0.820313f, +0.820313f,0.820313f, +0.828125f,0.820313f, +0.835938f,0.820313f, +0.84375f,0.820313f, +0.851563f,0.820313f, +0.859375f,0.820313f, +0.867188f,0.820313f, +0.875f,0.820313f, +0.882813f,0.820313f, +0.890625f,0.820313f, +0.898438f,0.820313f, +0.90625f,0.820313f, +0.914063f,0.820313f, +0.921875f,0.820313f, +0.929688f,0.820313f, +0.9375f,0.820313f, +0.945313f,0.820313f, +0.953125f,0.820313f, +0.960938f,0.820313f, +0.96875f,0.820313f, +0.976563f,0.820313f, +0.984375f,0.820313f, +0.992188f,0.820313f, +1.0f,0.820313f, +0.507813f,0.828125f, +0.515625f,0.828125f, +0.523438f,0.828125f, +0.53125f,0.828125f, +0.539063f,0.828125f, +0.546875f,0.828125f, +0.554688f,0.828125f, +0.5625f,0.828125f, +0.570313f,0.828125f, +0.578125f,0.828125f, +0.585938f,0.828125f, +0.59375f,0.828125f, +0.601563f,0.828125f, +0.609375f,0.828125f, +0.617188f,0.828125f, +0.625f,0.828125f, +0.632813f,0.828125f, +0.640625f,0.828125f, +0.648438f,0.828125f, +0.65625f,0.828125f, +0.664063f,0.828125f, +0.671875f,0.828125f, +0.679688f,0.828125f, +0.6875f,0.828125f, +0.695313f,0.828125f, +0.703125f,0.828125f, +0.710938f,0.828125f, +0.71875f,0.828125f, +0.726563f,0.828125f, +0.734375f,0.828125f, +0.742188f,0.828125f, +0.75f,0.828125f, +0.757813f,0.828125f, +0.765625f,0.828125f, +0.773438f,0.828125f, +0.78125f,0.828125f, +0.789063f,0.828125f, +0.796875f,0.828125f, +0.804688f,0.828125f, +0.8125f,0.828125f, +0.820313f,0.828125f, +0.828125f,0.828125f, +0.835938f,0.828125f, +0.84375f,0.828125f, +0.851563f,0.828125f, +0.859375f,0.828125f, +0.867188f,0.828125f, +0.875f,0.828125f, +0.882813f,0.828125f, +0.890625f,0.828125f, +0.898438f,0.828125f, +0.90625f,0.828125f, +0.914063f,0.828125f, +0.921875f,0.828125f, +0.929688f,0.828125f, +0.9375f,0.828125f, +0.945313f,0.828125f, +0.953125f,0.828125f, +0.960938f,0.828125f, +0.96875f,0.828125f, +0.976563f,0.828125f, +0.984375f,0.828125f, +0.992188f,0.828125f, +1.0f,0.828125f, +0.507813f,0.835938f, +0.515625f,0.835938f, +0.523438f,0.835938f, +0.53125f,0.835938f, +0.539063f,0.835938f, +0.546875f,0.835938f, +0.554688f,0.835938f, +0.5625f,0.835938f, +0.570313f,0.835938f, +0.578125f,0.835938f, +0.585938f,0.835938f, +0.59375f,0.835938f, +0.601563f,0.835938f, +0.609375f,0.835938f, +0.617188f,0.835938f, +0.625f,0.835938f, +0.632813f,0.835938f, +0.640625f,0.835938f, +0.648438f,0.835938f, +0.65625f,0.835938f, +0.664063f,0.835938f, +0.671875f,0.835938f, +0.679688f,0.835938f, +0.6875f,0.835938f, +0.695313f,0.835938f, +0.703125f,0.835938f, +0.710938f,0.835938f, +0.71875f,0.835938f, +0.726563f,0.835938f, +0.734375f,0.835938f, +0.742188f,0.835938f, +0.75f,0.835938f, +0.757813f,0.835938f, +0.765625f,0.835938f, +0.773438f,0.835938f, +0.78125f,0.835938f, +0.789063f,0.835938f, +0.796875f,0.835938f, +0.804688f,0.835938f, +0.8125f,0.835938f, +0.820313f,0.835938f, +0.828125f,0.835938f, +0.835938f,0.835938f, +0.84375f,0.835938f, +0.851563f,0.835938f, +0.859375f,0.835938f, +0.867188f,0.835938f, +0.875f,0.835938f, +0.882813f,0.835938f, +0.890625f,0.835938f, +0.898438f,0.835938f, +0.90625f,0.835938f, +0.914063f,0.835938f, +0.921875f,0.835938f, +0.929688f,0.835938f, +0.9375f,0.835938f, +0.945313f,0.835938f, +0.953125f,0.835938f, +0.960938f,0.835938f, +0.96875f,0.835938f, +0.976563f,0.835938f, +0.984375f,0.835938f, +0.992188f,0.835938f, +1.0f,0.835938f, +0.507813f,0.84375f, +0.515625f,0.84375f, +0.523438f,0.84375f, +0.53125f,0.84375f, +0.539063f,0.84375f, +0.546875f,0.84375f, +0.554688f,0.84375f, +0.5625f,0.84375f, +0.570313f,0.84375f, +0.578125f,0.84375f, +0.585938f,0.84375f, +0.59375f,0.84375f, +0.601563f,0.84375f, +0.609375f,0.84375f, +0.617188f,0.84375f, +0.625f,0.84375f, +0.632813f,0.84375f, +0.640625f,0.84375f, +0.648438f,0.84375f, +0.65625f,0.84375f, +0.664063f,0.84375f, +0.671875f,0.84375f, +0.679688f,0.84375f, +0.6875f,0.84375f, +0.695313f,0.84375f, +0.703125f,0.84375f, +0.710938f,0.84375f, +0.71875f,0.84375f, +0.726563f,0.84375f, +0.734375f,0.84375f, +0.742188f,0.84375f, +0.75f,0.84375f, +0.757813f,0.84375f, +0.765625f,0.84375f, +0.773438f,0.84375f, +0.78125f,0.84375f, +0.789063f,0.84375f, +0.796875f,0.84375f, +0.804688f,0.84375f, +0.8125f,0.84375f, +0.820313f,0.84375f, +0.828125f,0.84375f, +0.835938f,0.84375f, +0.84375f,0.84375f, +0.851563f,0.84375f, +0.859375f,0.84375f, +0.867188f,0.84375f, +0.875f,0.84375f, +0.882813f,0.84375f, +0.890625f,0.84375f, +0.898438f,0.84375f, +0.90625f,0.84375f, +0.914063f,0.84375f, +0.921875f,0.84375f, +0.929688f,0.84375f, +0.9375f,0.84375f, +0.945313f,0.84375f, +0.953125f,0.84375f, +0.960938f,0.84375f, +0.96875f,0.84375f, +0.976563f,0.84375f, +0.984375f,0.84375f, +0.992188f,0.84375f, +1.0f,0.84375f, +0.507813f,0.851563f, +0.515625f,0.851563f, +0.523438f,0.851563f, +0.53125f,0.851563f, +0.539063f,0.851563f, +0.546875f,0.851563f, +0.554688f,0.851563f, +0.5625f,0.851563f, +0.570313f,0.851563f, +0.578125f,0.851563f, +0.585938f,0.851563f, +0.59375f,0.851563f, +0.601563f,0.851563f, +0.609375f,0.851563f, +0.617188f,0.851563f, +0.625f,0.851563f, +0.632813f,0.851563f, +0.640625f,0.851563f, +0.648438f,0.851563f, +0.65625f,0.851563f, +0.664063f,0.851563f, +0.671875f,0.851563f, +0.679688f,0.851563f, +0.6875f,0.851563f, +0.695313f,0.851563f, +0.703125f,0.851563f, +0.710938f,0.851563f, +0.71875f,0.851563f, +0.726563f,0.851563f, +0.734375f,0.851563f, +0.742188f,0.851563f, +0.75f,0.851563f, +0.757813f,0.851563f, +0.765625f,0.851563f, +0.773438f,0.851563f, +0.78125f,0.851563f, +0.789063f,0.851563f, +0.796875f,0.851563f, +0.804688f,0.851563f, +0.8125f,0.851563f, +0.820313f,0.851563f, +0.828125f,0.851563f, +0.835938f,0.851563f, +0.84375f,0.851563f, +0.851563f,0.851563f, +0.859375f,0.851563f, +0.867188f,0.851563f, +0.875f,0.851563f, +0.882813f,0.851563f, +0.890625f,0.851563f, +0.898438f,0.851563f, +0.90625f,0.851563f, +0.914063f,0.851563f, +0.921875f,0.851563f, +0.929688f,0.851563f, +0.9375f,0.851563f, +0.945313f,0.851563f, +0.953125f,0.851563f, +0.960938f,0.851563f, +0.96875f,0.851563f, +0.976563f,0.851563f, +0.984375f,0.851563f, +0.992188f,0.851563f, +1.0f,0.851563f, +0.507813f,0.859375f, +0.515625f,0.859375f, +0.523438f,0.859375f, +0.53125f,0.859375f, +0.539063f,0.859375f, +0.546875f,0.859375f, +0.554688f,0.859375f, +0.5625f,0.859375f, +0.570313f,0.859375f, +0.578125f,0.859375f, +0.585938f,0.859375f, +0.59375f,0.859375f, +0.601563f,0.859375f, +0.609375f,0.859375f, +0.617188f,0.859375f, +0.625f,0.859375f, +0.632813f,0.859375f, +0.640625f,0.859375f, +0.648438f,0.859375f, +0.65625f,0.859375f, +0.664063f,0.859375f, +0.671875f,0.859375f, +0.679688f,0.859375f, +0.6875f,0.859375f, +0.695313f,0.859375f, +0.703125f,0.859375f, +0.710938f,0.859375f, +0.71875f,0.859375f, +0.726563f,0.859375f, +0.734375f,0.859375f, +0.742188f,0.859375f, +0.75f,0.859375f, +0.757813f,0.859375f, +0.765625f,0.859375f, +0.773438f,0.859375f, +0.78125f,0.859375f, +0.789063f,0.859375f, +0.796875f,0.859375f, +0.804688f,0.859375f, +0.8125f,0.859375f, +0.820313f,0.859375f, +0.828125f,0.859375f, +0.835938f,0.859375f, +0.84375f,0.859375f, +0.851563f,0.859375f, +0.859375f,0.859375f, +0.867188f,0.859375f, +0.875f,0.859375f, +0.882813f,0.859375f, +0.890625f,0.859375f, +0.898438f,0.859375f, +0.90625f,0.859375f, +0.914063f,0.859375f, +0.921875f,0.859375f, +0.929688f,0.859375f, +0.9375f,0.859375f, +0.945313f,0.859375f, +0.953125f,0.859375f, +0.960938f,0.859375f, +0.96875f,0.859375f, +0.976563f,0.859375f, +0.984375f,0.859375f, +0.992188f,0.859375f, +1.0f,0.859375f, +0.507813f,0.867188f, +0.515625f,0.867188f, +0.523438f,0.867188f, +0.53125f,0.867188f, +0.539063f,0.867188f, +0.546875f,0.867188f, +0.554688f,0.867188f, +0.5625f,0.867188f, +0.570313f,0.867188f, +0.578125f,0.867188f, +0.585938f,0.867188f, +0.59375f,0.867188f, +0.601563f,0.867188f, +0.609375f,0.867188f, +0.617188f,0.867188f, +0.625f,0.867188f, +0.632813f,0.867188f, +0.640625f,0.867188f, +0.648438f,0.867188f, +0.65625f,0.867188f, +0.664063f,0.867188f, +0.671875f,0.867188f, +0.679688f,0.867188f, +0.6875f,0.867188f, +0.695313f,0.867188f, +0.703125f,0.867188f, +0.710938f,0.867188f, +0.71875f,0.867188f, +0.726563f,0.867188f, +0.734375f,0.867188f, +0.742188f,0.867188f, +0.75f,0.867188f, +0.757813f,0.867188f, +0.765625f,0.867188f, +0.773438f,0.867188f, +0.78125f,0.867188f, +0.789063f,0.867188f, +0.796875f,0.867188f, +0.804688f,0.867188f, +0.8125f,0.867188f, +0.820313f,0.867188f, +0.828125f,0.867188f, +0.835938f,0.867188f, +0.84375f,0.867188f, +0.851563f,0.867188f, +0.859375f,0.867188f, +0.867188f,0.867188f, +0.875f,0.867188f, +0.882813f,0.867188f, +0.890625f,0.867188f, +0.898438f,0.867188f, +0.90625f,0.867188f, +0.914063f,0.867188f, +0.921875f,0.867188f, +0.929688f,0.867188f, +0.9375f,0.867188f, +0.945313f,0.867188f, +0.953125f,0.867188f, +0.960938f,0.867188f, +0.96875f,0.867188f, +0.976563f,0.867188f, +0.984375f,0.867188f, +0.992188f,0.867188f, +1.0f,0.867188f, +0.507813f,0.875f, +0.515625f,0.875f, +0.523438f,0.875f, +0.53125f,0.875f, +0.539063f,0.875f, +0.546875f,0.875f, +0.554688f,0.875f, +0.5625f,0.875f, +0.570313f,0.875f, +0.578125f,0.875f, +0.585938f,0.875f, +0.59375f,0.875f, +0.601563f,0.875f, +0.609375f,0.875f, +0.617188f,0.875f, +0.625f,0.875f, +0.632813f,0.875f, +0.640625f,0.875f, +0.648438f,0.875f, +0.65625f,0.875f, +0.664063f,0.875f, +0.671875f,0.875f, +0.679688f,0.875f, +0.6875f,0.875f, +0.695313f,0.875f, +0.703125f,0.875f, +0.710938f,0.875f, +0.71875f,0.875f, +0.726563f,0.875f, +0.734375f,0.875f, +0.742188f,0.875f, +0.75f,0.875f, +0.757813f,0.875f, +0.765625f,0.875f, +0.773438f,0.875f, +0.78125f,0.875f, +0.789063f,0.875f, +0.796875f,0.875f, +0.804688f,0.875f, +0.8125f,0.875f, +0.820313f,0.875f, +0.828125f,0.875f, +0.835938f,0.875f, +0.84375f,0.875f, +0.851563f,0.875f, +0.859375f,0.875f, +0.867188f,0.875f, +0.875f,0.875f, +0.882813f,0.875f, +0.890625f,0.875f, +0.898438f,0.875f, +0.90625f,0.875f, +0.914063f,0.875f, +0.921875f,0.875f, +0.929688f,0.875f, +0.9375f,0.875f, +0.945313f,0.875f, +0.953125f,0.875f, +0.960938f,0.875f, +0.96875f,0.875f, +0.976563f,0.875f, +0.984375f,0.875f, +0.992188f,0.875f, +1.0f,0.875f, +0.507813f,0.882813f, +0.515625f,0.882813f, +0.523438f,0.882813f, +0.53125f,0.882813f, +0.539063f,0.882813f, +0.546875f,0.882813f, +0.554688f,0.882813f, +0.5625f,0.882813f, +0.570313f,0.882813f, +0.578125f,0.882813f, +0.585938f,0.882813f, +0.59375f,0.882813f, +0.601563f,0.882813f, +0.609375f,0.882813f, +0.617188f,0.882813f, +0.625f,0.882813f, +0.632813f,0.882813f, +0.640625f,0.882813f, +0.648438f,0.882813f, +0.65625f,0.882813f, +0.664063f,0.882813f, +0.671875f,0.882813f, +0.679688f,0.882813f, +0.6875f,0.882813f, +0.695313f,0.882813f, +0.703125f,0.882813f, +0.710938f,0.882813f, +0.71875f,0.882813f, +0.726563f,0.882813f, +0.734375f,0.882813f, +0.742188f,0.882813f, +0.75f,0.882813f, +0.757813f,0.882813f, +0.765625f,0.882813f, +0.773438f,0.882813f, +0.78125f,0.882813f, +0.789063f,0.882813f, +0.796875f,0.882813f, +0.804688f,0.882813f, +0.8125f,0.882813f, +0.820313f,0.882813f, +0.828125f,0.882813f, +0.835938f,0.882813f, +0.84375f,0.882813f, +0.851563f,0.882813f, +0.859375f,0.882813f, +0.867188f,0.882813f, +0.875f,0.882813f, +0.882813f,0.882813f, +0.890625f,0.882813f, +0.898438f,0.882813f, +0.90625f,0.882813f, +0.914063f,0.882813f, +0.921875f,0.882813f, +0.929688f,0.882813f, +0.9375f,0.882813f, +0.945313f,0.882813f, +0.953125f,0.882813f, +0.960938f,0.882813f, +0.96875f,0.882813f, +0.976563f,0.882813f, +0.984375f,0.882813f, +0.992188f,0.882813f, +1.0f,0.882813f, +0.507813f,0.890625f, +0.515625f,0.890625f, +0.523438f,0.890625f, +0.53125f,0.890625f, +0.539063f,0.890625f, +0.546875f,0.890625f, +0.554688f,0.890625f, +0.5625f,0.890625f, +0.570313f,0.890625f, +0.578125f,0.890625f, +0.585938f,0.890625f, +0.59375f,0.890625f, +0.601563f,0.890625f, +0.609375f,0.890625f, +0.617188f,0.890625f, +0.625f,0.890625f, +0.632813f,0.890625f, +0.640625f,0.890625f, +0.648438f,0.890625f, +0.65625f,0.890625f, +0.664063f,0.890625f, +0.671875f,0.890625f, +0.679688f,0.890625f, +0.6875f,0.890625f, +0.695313f,0.890625f, +0.703125f,0.890625f, +0.710938f,0.890625f, +0.71875f,0.890625f, +0.726563f,0.890625f, +0.734375f,0.890625f, +0.742188f,0.890625f, +0.75f,0.890625f, +0.757813f,0.890625f, +0.765625f,0.890625f, +0.773438f,0.890625f, +0.78125f,0.890625f, +0.789063f,0.890625f, +0.796875f,0.890625f, +0.804688f,0.890625f, +0.8125f,0.890625f, +0.820313f,0.890625f, +0.828125f,0.890625f, +0.835938f,0.890625f, +0.84375f,0.890625f, +0.851563f,0.890625f, +0.859375f,0.890625f, +0.867188f,0.890625f, +0.875f,0.890625f, +0.882813f,0.890625f, +0.890625f,0.890625f, +0.898438f,0.890625f, +0.90625f,0.890625f, +0.914063f,0.890625f, +0.921875f,0.890625f, +0.929688f,0.890625f, +0.9375f,0.890625f, +0.945313f,0.890625f, +0.953125f,0.890625f, +0.960938f,0.890625f, +0.96875f,0.890625f, +0.976563f,0.890625f, +0.984375f,0.890625f, +0.992188f,0.890625f, +1.0f,0.890625f, +0.507813f,0.898438f, +0.515625f,0.898438f, +0.523438f,0.898438f, +0.53125f,0.898438f, +0.539063f,0.898438f, +0.546875f,0.898438f, +0.554688f,0.898438f, +0.5625f,0.898438f, +0.570313f,0.898438f, +0.578125f,0.898438f, +0.585938f,0.898438f, +0.59375f,0.898438f, +0.601563f,0.898438f, +0.609375f,0.898438f, +0.617188f,0.898438f, +0.625f,0.898438f, +0.632813f,0.898438f, +0.640625f,0.898438f, +0.648438f,0.898438f, +0.65625f,0.898438f, +0.664063f,0.898438f, +0.671875f,0.898438f, +0.679688f,0.898438f, +0.6875f,0.898438f, +0.695313f,0.898438f, +0.703125f,0.898438f, +0.710938f,0.898438f, +0.71875f,0.898438f, +0.726563f,0.898438f, +0.734375f,0.898438f, +0.742188f,0.898438f, +0.75f,0.898438f, +0.757813f,0.898438f, +0.765625f,0.898438f, +0.773438f,0.898438f, +0.78125f,0.898438f, +0.789063f,0.898438f, +0.796875f,0.898438f, +0.804688f,0.898438f, +0.8125f,0.898438f, +0.820313f,0.898438f, +0.828125f,0.898438f, +0.835938f,0.898438f, +0.84375f,0.898438f, +0.851563f,0.898438f, +0.859375f,0.898438f, +0.867188f,0.898438f, +0.875f,0.898438f, +0.882813f,0.898438f, +0.890625f,0.898438f, +0.898438f,0.898438f, +0.90625f,0.898438f, +0.914063f,0.898438f, +0.921875f,0.898438f, +0.929688f,0.898438f, +0.9375f,0.898438f, +0.945313f,0.898438f, +0.953125f,0.898438f, +0.960938f,0.898438f, +0.96875f,0.898438f, +0.976563f,0.898438f, +0.984375f,0.898438f, +0.992188f,0.898438f, +1.0f,0.898438f, +0.507813f,0.90625f, +0.515625f,0.90625f, +0.523438f,0.90625f, +0.53125f,0.90625f, +0.539063f,0.90625f, +0.546875f,0.90625f, +0.554688f,0.90625f, +0.5625f,0.90625f, +0.570313f,0.90625f, +0.578125f,0.90625f, +0.585938f,0.90625f, +0.59375f,0.90625f, +0.601563f,0.90625f, +0.609375f,0.90625f, +0.617188f,0.90625f, +0.625f,0.90625f, +0.632813f,0.90625f, +0.640625f,0.90625f, +0.648438f,0.90625f, +0.65625f,0.90625f, +0.664063f,0.90625f, +0.671875f,0.90625f, +0.679688f,0.90625f, +0.6875f,0.90625f, +0.695313f,0.90625f, +0.703125f,0.90625f, +0.710938f,0.90625f, +0.71875f,0.90625f, +0.726563f,0.90625f, +0.734375f,0.90625f, +0.742188f,0.90625f, +0.75f,0.90625f, +0.757813f,0.90625f, +0.765625f,0.90625f, +0.773438f,0.90625f, +0.78125f,0.90625f, +0.789063f,0.90625f, +0.796875f,0.90625f, +0.804688f,0.90625f, +0.8125f,0.90625f, +0.820313f,0.90625f, +0.828125f,0.90625f, +0.835938f,0.90625f, +0.84375f,0.90625f, +0.851563f,0.90625f, +0.859375f,0.90625f, +0.867188f,0.90625f, +0.875f,0.90625f, +0.882813f,0.90625f, +0.890625f,0.90625f, +0.898438f,0.90625f, +0.90625f,0.90625f, +0.914063f,0.90625f, +0.921875f,0.90625f, +0.929688f,0.90625f, +0.9375f,0.90625f, +0.945313f,0.90625f, +0.953125f,0.90625f, +0.960938f,0.90625f, +0.96875f,0.90625f, +0.976563f,0.90625f, +0.984375f,0.90625f, +0.992188f,0.90625f, +1.0f,0.90625f, +0.507813f,0.914063f, +0.515625f,0.914063f, +0.523438f,0.914063f, +0.53125f,0.914063f, +0.539063f,0.914063f, +0.546875f,0.914063f, +0.554688f,0.914063f, +0.5625f,0.914063f, +0.570313f,0.914063f, +0.578125f,0.914063f, +0.585938f,0.914063f, +0.59375f,0.914063f, +0.601563f,0.914063f, +0.609375f,0.914063f, +0.617188f,0.914063f, +0.625f,0.914063f, +0.632813f,0.914063f, +0.640625f,0.914063f, +0.648438f,0.914063f, +0.65625f,0.914063f, +0.664063f,0.914063f, +0.671875f,0.914063f, +0.679688f,0.914063f, +0.6875f,0.914063f, +0.695313f,0.914063f, +0.703125f,0.914063f, +0.710938f,0.914063f, +0.71875f,0.914063f, +0.726563f,0.914063f, +0.734375f,0.914063f, +0.742188f,0.914063f, +0.75f,0.914063f, +0.757813f,0.914063f, +0.765625f,0.914063f, +0.773438f,0.914063f, +0.78125f,0.914063f, +0.789063f,0.914063f, +0.796875f,0.914063f, +0.804688f,0.914063f, +0.8125f,0.914063f, +0.820313f,0.914063f, +0.828125f,0.914063f, +0.835938f,0.914063f, +0.84375f,0.914063f, +0.851563f,0.914063f, +0.859375f,0.914063f, +0.867188f,0.914063f, +0.875f,0.914063f, +0.882813f,0.914063f, +0.890625f,0.914063f, +0.898438f,0.914063f, +0.90625f,0.914063f, +0.914063f,0.914063f, +0.921875f,0.914063f, +0.929688f,0.914063f, +0.9375f,0.914063f, +0.945313f,0.914063f, +0.953125f,0.914063f, +0.960938f,0.914063f, +0.96875f,0.914063f, +0.976563f,0.914063f, +0.984375f,0.914063f, +0.992188f,0.914063f, +1.0f,0.914063f, +0.507813f,0.921875f, +0.515625f,0.921875f, +0.523438f,0.921875f, +0.53125f,0.921875f, +0.539063f,0.921875f, +0.546875f,0.921875f, +0.554688f,0.921875f, +0.5625f,0.921875f, +0.570313f,0.921875f, +0.578125f,0.921875f, +0.585938f,0.921875f, +0.59375f,0.921875f, +0.601563f,0.921875f, +0.609375f,0.921875f, +0.617188f,0.921875f, +0.625f,0.921875f, +0.632813f,0.921875f, +0.640625f,0.921875f, +0.648438f,0.921875f, +0.65625f,0.921875f, +0.664063f,0.921875f, +0.671875f,0.921875f, +0.679688f,0.921875f, +0.6875f,0.921875f, +0.695313f,0.921875f, +0.703125f,0.921875f, +0.710938f,0.921875f, +0.71875f,0.921875f, +0.726563f,0.921875f, +0.734375f,0.921875f, +0.742188f,0.921875f, +0.75f,0.921875f, +0.757813f,0.921875f, +0.765625f,0.921875f, +0.773438f,0.921875f, +0.78125f,0.921875f, +0.789063f,0.921875f, +0.796875f,0.921875f, +0.804688f,0.921875f, +0.8125f,0.921875f, +0.820313f,0.921875f, +0.828125f,0.921875f, +0.835938f,0.921875f, +0.84375f,0.921875f, +0.851563f,0.921875f, +0.859375f,0.921875f, +0.867188f,0.921875f, +0.875f,0.921875f, +0.882813f,0.921875f, +0.890625f,0.921875f, +0.898438f,0.921875f, +0.90625f,0.921875f, +0.914063f,0.921875f, +0.921875f,0.921875f, +0.929688f,0.921875f, +0.9375f,0.921875f, +0.945313f,0.921875f, +0.953125f,0.921875f, +0.960938f,0.921875f, +0.96875f,0.921875f, +0.976563f,0.921875f, +0.984375f,0.921875f, +0.992188f,0.921875f, +1.0f,0.921875f, +0.507813f,0.929688f, +0.515625f,0.929688f, +0.523438f,0.929688f, +0.53125f,0.929688f, +0.539063f,0.929688f, +0.546875f,0.929688f, +0.554688f,0.929688f, +0.5625f,0.929688f, +0.570313f,0.929688f, +0.578125f,0.929688f, +0.585938f,0.929688f, +0.59375f,0.929688f, +0.601563f,0.929688f, +0.609375f,0.929688f, +0.617188f,0.929688f, +0.625f,0.929688f, +0.632813f,0.929688f, +0.640625f,0.929688f, +0.648438f,0.929688f, +0.65625f,0.929688f, +0.664063f,0.929688f, +0.671875f,0.929688f, +0.679688f,0.929688f, +0.6875f,0.929688f, +0.695313f,0.929688f, +0.703125f,0.929688f, +0.710938f,0.929688f, +0.71875f,0.929688f, +0.726563f,0.929688f, +0.734375f,0.929688f, +0.742188f,0.929688f, +0.75f,0.929688f, +0.757813f,0.929688f, +0.765625f,0.929688f, +0.773438f,0.929688f, +0.78125f,0.929688f, +0.789063f,0.929688f, +0.796875f,0.929688f, +0.804688f,0.929688f, +0.8125f,0.929688f, +0.820313f,0.929688f, +0.828125f,0.929688f, +0.835938f,0.929688f, +0.84375f,0.929688f, +0.851563f,0.929688f, +0.859375f,0.929688f, +0.867188f,0.929688f, +0.875f,0.929688f, +0.882813f,0.929688f, +0.890625f,0.929688f, +0.898438f,0.929688f, +0.90625f,0.929688f, +0.914063f,0.929688f, +0.921875f,0.929688f, +0.929688f,0.929688f, +0.9375f,0.929688f, +0.945313f,0.929688f, +0.953125f,0.929688f, +0.960938f,0.929688f, +0.96875f,0.929688f, +0.976563f,0.929688f, +0.984375f,0.929688f, +0.992188f,0.929688f, +1.0f,0.929688f, +0.507813f,0.9375f, +0.515625f,0.9375f, +0.523438f,0.9375f, +0.53125f,0.9375f, +0.539063f,0.9375f, +0.546875f,0.9375f, +0.554688f,0.9375f, +0.5625f,0.9375f, +0.570313f,0.9375f, +0.578125f,0.9375f, +0.585938f,0.9375f, +0.59375f,0.9375f, +0.601563f,0.9375f, +0.609375f,0.9375f, +0.617188f,0.9375f, +0.625f,0.9375f, +0.632813f,0.9375f, +0.640625f,0.9375f, +0.648438f,0.9375f, +0.65625f,0.9375f, +0.664063f,0.9375f, +0.671875f,0.9375f, +0.679688f,0.9375f, +0.6875f,0.9375f, +0.695313f,0.9375f, +0.703125f,0.9375f, +0.710938f,0.9375f, +0.71875f,0.9375f, +0.726563f,0.9375f, +0.734375f,0.9375f, +0.742188f,0.9375f, +0.75f,0.9375f, +0.757813f,0.9375f, +0.765625f,0.9375f, +0.773438f,0.9375f, +0.78125f,0.9375f, +0.789063f,0.9375f, +0.796875f,0.9375f, +0.804688f,0.9375f, +0.8125f,0.9375f, +0.820313f,0.9375f, +0.828125f,0.9375f, +0.835938f,0.9375f, +0.84375f,0.9375f, +0.851563f,0.9375f, +0.859375f,0.9375f, +0.867188f,0.9375f, +0.875f,0.9375f, +0.882813f,0.9375f, +0.890625f,0.9375f, +0.898438f,0.9375f, +0.90625f,0.9375f, +0.914063f,0.9375f, +0.921875f,0.9375f, +0.929688f,0.9375f, +0.9375f,0.9375f, +0.945313f,0.9375f, +0.953125f,0.9375f, +0.960938f,0.9375f, +0.96875f,0.9375f, +0.976563f,0.9375f, +0.984375f,0.9375f, +0.992188f,0.9375f, +1.0f,0.9375f, +0.507813f,0.945313f, +0.515625f,0.945313f, +0.523438f,0.945313f, +0.53125f,0.945313f, +0.539063f,0.945313f, +0.546875f,0.945313f, +0.554688f,0.945313f, +0.5625f,0.945313f, +0.570313f,0.945313f, +0.578125f,0.945313f, +0.585938f,0.945313f, +0.59375f,0.945313f, +0.601563f,0.945313f, +0.609375f,0.945313f, +0.617188f,0.945313f, +0.625f,0.945313f, +0.632813f,0.945313f, +0.640625f,0.945313f, +0.648438f,0.945313f, +0.65625f,0.945313f, +0.664063f,0.945313f, +0.671875f,0.945313f, +0.679688f,0.945313f, +0.6875f,0.945313f, +0.695313f,0.945313f, +0.703125f,0.945313f, +0.710938f,0.945313f, +0.71875f,0.945313f, +0.726563f,0.945313f, +0.734375f,0.945313f, +0.742188f,0.945313f, +0.75f,0.945313f, +0.757813f,0.945313f, +0.765625f,0.945313f, +0.773438f,0.945313f, +0.78125f,0.945313f, +0.789063f,0.945313f, +0.796875f,0.945313f, +0.804688f,0.945313f, +0.8125f,0.945313f, +0.820313f,0.945313f, +0.828125f,0.945313f, +0.835938f,0.945313f, +0.84375f,0.945313f, +0.851563f,0.945313f, +0.859375f,0.945313f, +0.867188f,0.945313f, +0.875f,0.945313f, +0.882813f,0.945313f, +0.890625f,0.945313f, +0.898438f,0.945313f, +0.90625f,0.945313f, +0.914063f,0.945313f, +0.921875f,0.945313f, +0.929688f,0.945313f, +0.9375f,0.945313f, +0.945313f,0.945313f, +0.953125f,0.945313f, +0.960938f,0.945313f, +0.96875f,0.945313f, +0.976563f,0.945313f, +0.984375f,0.945313f, +0.992188f,0.945313f, +1.0f,0.945313f, +0.507813f,0.953125f, +0.515625f,0.953125f, +0.523438f,0.953125f, +0.53125f,0.953125f, +0.539063f,0.953125f, +0.546875f,0.953125f, +0.554688f,0.953125f, +0.5625f,0.953125f, +0.570313f,0.953125f, +0.578125f,0.953125f, +0.585938f,0.953125f, +0.59375f,0.953125f, +0.601563f,0.953125f, +0.609375f,0.953125f, +0.617188f,0.953125f, +0.625f,0.953125f, +0.632813f,0.953125f, +0.640625f,0.953125f, +0.648438f,0.953125f, +0.65625f,0.953125f, +0.664063f,0.953125f, +0.671875f,0.953125f, +0.679688f,0.953125f, +0.6875f,0.953125f, +0.695313f,0.953125f, +0.703125f,0.953125f, +0.710938f,0.953125f, +0.71875f,0.953125f, +0.726563f,0.953125f, +0.734375f,0.953125f, +0.742188f,0.953125f, +0.75f,0.953125f, +0.757813f,0.953125f, +0.765625f,0.953125f, +0.773438f,0.953125f, +0.78125f,0.953125f, +0.789063f,0.953125f, +0.796875f,0.953125f, +0.804688f,0.953125f, +0.8125f,0.953125f, +0.820313f,0.953125f, +0.828125f,0.953125f, +0.835938f,0.953125f, +0.84375f,0.953125f, +0.851563f,0.953125f, +0.859375f,0.953125f, +0.867188f,0.953125f, +0.875f,0.953125f, +0.882813f,0.953125f, +0.890625f,0.953125f, +0.898438f,0.953125f, +0.90625f,0.953125f, +0.914063f,0.953125f, +0.921875f,0.953125f, +0.929688f,0.953125f, +0.9375f,0.953125f, +0.945313f,0.953125f, +0.953125f,0.953125f, +0.960938f,0.953125f, +0.96875f,0.953125f, +0.976563f,0.953125f, +0.984375f,0.953125f, +0.992188f,0.953125f, +1.0f,0.953125f, +0.507813f,0.960938f, +0.515625f,0.960938f, +0.523438f,0.960938f, +0.53125f,0.960938f, +0.539063f,0.960938f, +0.546875f,0.960938f, +0.554688f,0.960938f, +0.5625f,0.960938f, +0.570313f,0.960938f, +0.578125f,0.960938f, +0.585938f,0.960938f, +0.59375f,0.960938f, +0.601563f,0.960938f, +0.609375f,0.960938f, +0.617188f,0.960938f, +0.625f,0.960938f, +0.632813f,0.960938f, +0.640625f,0.960938f, +0.648438f,0.960938f, +0.65625f,0.960938f, +0.664063f,0.960938f, +0.671875f,0.960938f, +0.679688f,0.960938f, +0.6875f,0.960938f, +0.695313f,0.960938f, +0.703125f,0.960938f, +0.710938f,0.960938f, +0.71875f,0.960938f, +0.726563f,0.960938f, +0.734375f,0.960938f, +0.742188f,0.960938f, +0.75f,0.960938f, +0.757813f,0.960938f, +0.765625f,0.960938f, +0.773438f,0.960938f, +0.78125f,0.960938f, +0.789063f,0.960938f, +0.796875f,0.960938f, +0.804688f,0.960938f, +0.8125f,0.960938f, +0.820313f,0.960938f, +0.828125f,0.960938f, +0.835938f,0.960938f, +0.84375f,0.960938f, +0.851563f,0.960938f, +0.859375f,0.960938f, +0.867188f,0.960938f, +0.875f,0.960938f, +0.882813f,0.960938f, +0.890625f,0.960938f, +0.898438f,0.960938f, +0.90625f,0.960938f, +0.914063f,0.960938f, +0.921875f,0.960938f, +0.929688f,0.960938f, +0.9375f,0.960938f, +0.945313f,0.960938f, +0.953125f,0.960938f, +0.960938f,0.960938f, +0.96875f,0.960938f, +0.976563f,0.960938f, +0.984375f,0.960938f, +0.992188f,0.960938f, +1.0f,0.960938f, +0.507813f,0.96875f, +0.515625f,0.96875f, +0.523438f,0.96875f, +0.53125f,0.96875f, +0.539063f,0.96875f, +0.546875f,0.96875f, +0.554688f,0.96875f, +0.5625f,0.96875f, +0.570313f,0.96875f, +0.578125f,0.96875f, +0.585938f,0.96875f, +0.59375f,0.96875f, +0.601563f,0.96875f, +0.609375f,0.96875f, +0.617188f,0.96875f, +0.625f,0.96875f, +0.632813f,0.96875f, +0.640625f,0.96875f, +0.648438f,0.96875f, +0.65625f,0.96875f, +0.664063f,0.96875f, +0.671875f,0.96875f, +0.679688f,0.96875f, +0.6875f,0.96875f, +0.695313f,0.96875f, +0.703125f,0.96875f, +0.710938f,0.96875f, +0.71875f,0.96875f, +0.726563f,0.96875f, +0.734375f,0.96875f, +0.742188f,0.96875f, +0.75f,0.96875f, +0.757813f,0.96875f, +0.765625f,0.96875f, +0.773438f,0.96875f, +0.78125f,0.96875f, +0.789063f,0.96875f, +0.796875f,0.96875f, +0.804688f,0.96875f, +0.8125f,0.96875f, +0.820313f,0.96875f, +0.828125f,0.96875f, +0.835938f,0.96875f, +0.84375f,0.96875f, +0.851563f,0.96875f, +0.859375f,0.96875f, +0.867188f,0.96875f, +0.875f,0.96875f, +0.882813f,0.96875f, +0.890625f,0.96875f, +0.898438f,0.96875f, +0.90625f,0.96875f, +0.914063f,0.96875f, +0.921875f,0.96875f, +0.929688f,0.96875f, +0.9375f,0.96875f, +0.945313f,0.96875f, +0.953125f,0.96875f, +0.960938f,0.96875f, +0.96875f,0.96875f, +0.976563f,0.96875f, +0.984375f,0.96875f, +0.992188f,0.96875f, +1.0f,0.96875f, +0.507813f,0.976563f, +0.515625f,0.976563f, +0.523438f,0.976563f, +0.53125f,0.976563f, +0.539063f,0.976563f, +0.546875f,0.976563f, +0.554688f,0.976563f, +0.5625f,0.976563f, +0.570313f,0.976563f, +0.578125f,0.976563f, +0.585938f,0.976563f, +0.59375f,0.976563f, +0.601563f,0.976563f, +0.609375f,0.976563f, +0.617188f,0.976563f, +0.625f,0.976563f, +0.632813f,0.976563f, +0.640625f,0.976563f, +0.648438f,0.976563f, +0.65625f,0.976563f, +0.664063f,0.976563f, +0.671875f,0.976563f, +0.679688f,0.976563f, +0.6875f,0.976563f, +0.695313f,0.976563f, +0.703125f,0.976563f, +0.710938f,0.976563f, +0.71875f,0.976563f, +0.726563f,0.976563f, +0.734375f,0.976563f, +0.742188f,0.976563f, +0.75f,0.976563f, +0.757813f,0.976563f, +0.765625f,0.976563f, +0.773438f,0.976563f, +0.78125f,0.976563f, +0.789063f,0.976563f, +0.796875f,0.976563f, +0.804688f,0.976563f, +0.8125f,0.976563f, +0.820313f,0.976563f, +0.828125f,0.976563f, +0.835938f,0.976563f, +0.84375f,0.976563f, +0.851563f,0.976563f, +0.859375f,0.976563f, +0.867188f,0.976563f, +0.875f,0.976563f, +0.882813f,0.976563f, +0.890625f,0.976563f, +0.898438f,0.976563f, +0.90625f,0.976563f, +0.914063f,0.976563f, +0.921875f,0.976563f, +0.929688f,0.976563f, +0.9375f,0.976563f, +0.945313f,0.976563f, +0.953125f,0.976563f, +0.960938f,0.976563f, +0.96875f,0.976563f, +0.976563f,0.976563f, +0.984375f,0.976563f, +0.992188f,0.976563f, +1.0f,0.976563f, +0.507813f,0.984375f, +0.515625f,0.984375f, +0.523438f,0.984375f, +0.53125f,0.984375f, +0.539063f,0.984375f, +0.546875f,0.984375f, +0.554688f,0.984375f, +0.5625f,0.984375f, +0.570313f,0.984375f, +0.578125f,0.984375f, +0.585938f,0.984375f, +0.59375f,0.984375f, +0.601563f,0.984375f, +0.609375f,0.984375f, +0.617188f,0.984375f, +0.625f,0.984375f, +0.632813f,0.984375f, +0.640625f,0.984375f, +0.648438f,0.984375f, +0.65625f,0.984375f, +0.664063f,0.984375f, +0.671875f,0.984375f, +0.679688f,0.984375f, +0.6875f,0.984375f, +0.695313f,0.984375f, +0.703125f,0.984375f, +0.710938f,0.984375f, +0.71875f,0.984375f, +0.726563f,0.984375f, +0.734375f,0.984375f, +0.742188f,0.984375f, +0.75f,0.984375f, +0.757813f,0.984375f, +0.765625f,0.984375f, +0.773438f,0.984375f, +0.78125f,0.984375f, +0.789063f,0.984375f, +0.796875f,0.984375f, +0.804688f,0.984375f, +0.8125f,0.984375f, +0.820313f,0.984375f, +0.828125f,0.984375f, +0.835938f,0.984375f, +0.84375f,0.984375f, +0.851563f,0.984375f, +0.859375f,0.984375f, +0.867188f,0.984375f, +0.875f,0.984375f, +0.882813f,0.984375f, +0.890625f,0.984375f, +0.898438f,0.984375f, +0.90625f,0.984375f, +0.914063f,0.984375f, +0.921875f,0.984375f, +0.929688f,0.984375f, +0.9375f,0.984375f, +0.945313f,0.984375f, +0.953125f,0.984375f, +0.960938f,0.984375f, +0.96875f,0.984375f, +0.976563f,0.984375f, +0.984375f,0.984375f, +0.992188f,0.984375f, +1.0f,0.984375f, +0.507813f,0.992188f, +0.515625f,0.992188f, +0.523438f,0.992188f, +0.53125f,0.992188f, +0.539063f,0.992188f, +0.546875f,0.992188f, +0.554688f,0.992188f, +0.5625f,0.992188f, +0.570313f,0.992188f, +0.578125f,0.992188f, +0.585938f,0.992188f, +0.59375f,0.992188f, +0.601563f,0.992188f, +0.609375f,0.992188f, +0.617188f,0.992188f, +0.625f,0.992188f, +0.632813f,0.992188f, +0.640625f,0.992188f, +0.648438f,0.992188f, +0.65625f,0.992188f, +0.664063f,0.992188f, +0.671875f,0.992188f, +0.679688f,0.992188f, +0.6875f,0.992188f, +0.695313f,0.992188f, +0.703125f,0.992188f, +0.710938f,0.992188f, +0.71875f,0.992188f, +0.726563f,0.992188f, +0.734375f,0.992188f, +0.742188f,0.992188f, +0.75f,0.992188f, +0.757813f,0.992188f, +0.765625f,0.992188f, +0.773438f,0.992188f, +0.78125f,0.992188f, +0.789063f,0.992188f, +0.796875f,0.992188f, +0.804688f,0.992188f, +0.8125f,0.992188f, +0.820313f,0.992188f, +0.828125f,0.992188f, +0.835938f,0.992188f, +0.84375f,0.992188f, +0.851563f,0.992188f, +0.859375f,0.992188f, +0.867188f,0.992188f, +0.875f,0.992188f, +0.882813f,0.992188f, +0.890625f,0.992188f, +0.898438f,0.992188f, +0.90625f,0.992188f, +0.914063f,0.992188f, +0.921875f,0.992188f, +0.929688f,0.992188f, +0.9375f,0.992188f, +0.945313f,0.992188f, +0.953125f,0.992188f, +0.960938f,0.992188f, +0.96875f,0.992188f, +0.976563f,0.992188f, +0.984375f,0.992188f, +0.992188f,0.992188f, +1.0f,0.992188f, +0.507813f,1.0f, +0.515625f,1.0f, +0.523438f,1.0f, +0.53125f,1.0f, +0.539063f,1.0f, +0.546875f,1.0f, +0.554688f,1.0f, +0.5625f,1.0f, +0.570313f,1.0f, +0.578125f,1.0f, +0.585938f,1.0f, +0.59375f,1.0f, +0.601563f,1.0f, +0.609375f,1.0f, +0.617188f,1.0f, +0.625f,1.0f, +0.632813f,1.0f, +0.640625f,1.0f, +0.648438f,1.0f, +0.65625f,1.0f, +0.664063f,1.0f, +0.671875f,1.0f, +0.679688f,1.0f, +0.6875f,1.0f, +0.695313f,1.0f, +0.703125f,1.0f, +0.710938f,1.0f, +0.71875f,1.0f, +0.726563f,1.0f, +0.734375f,1.0f, +0.742188f,1.0f, +0.75f,1.0f, +0.757813f,1.0f, +0.765625f,1.0f, +0.773438f,1.0f, +0.78125f,1.0f, +0.789063f,1.0f, +0.796875f,1.0f, +0.804688f,1.0f, +0.8125f,1.0f, +0.820313f,1.0f, +0.828125f,1.0f, +0.835938f,1.0f, +0.84375f,1.0f, +0.851563f,1.0f, +0.859375f,1.0f, +0.867188f,1.0f, +0.875f,1.0f, +0.882813f,1.0f, +0.890625f,1.0f, +0.898438f,1.0f, +0.90625f,1.0f, +0.914063f,1.0f, +0.921875f,1.0f, +0.929688f,1.0f, +0.9375f,1.0f, +0.945313f,1.0f, +0.953125f,1.0f, +0.960938f,1.0f, +0.96875f,1.0f, +0.976563f,1.0f, +0.984375f,1.0f, +0.992188f,1.0f, +1.0f,1.0f, +}; + +unsigned short Landscape07Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +128,0,129, +2,129,0, +129,2,130, +4,130,2, +130,4,131, +6,131,4, +131,6,132, +8,132,6, +132,8,133, +10,133,8, +133,10,134, +12,134,10, +134,12,135, +14,135,12, +135,14,136, +16,136,14, +136,16,137, +18,137,16, +137,18,138, +20,138,18, +138,20,139, +22,139,20, +139,22,140, +24,140,22, +140,24,141, +26,141,24, +141,26,142, +28,142,26, +142,28,143, +30,143,28, +143,30,144, +32,144,30, +144,32,145, +34,145,32, +145,34,146, +36,146,34, +146,36,147, +38,147,36, +147,38,148, +40,148,38, +148,40,149, +42,149,40, +149,42,150, +44,150,42, +150,44,151, +46,151,44, +151,46,152, +48,152,46, +152,48,153, +50,153,48, +153,50,154, +52,154,50, +154,52,155, +54,155,52, +155,54,156, +56,156,54, +156,56,157, +58,157,56, +157,58,158, +60,158,58, +158,60,159, +62,159,60, +159,62,160, +64,160,62, +160,64,161, +66,161,64, +161,66,162, +68,162,66, +162,68,163, +70,163,68, +163,70,164, +72,164,70, +164,72,165, +74,165,72, +165,74,166, +76,166,74, +166,76,167, +78,167,76, +167,78,168, +80,168,78, +168,80,169, +82,169,80, +169,82,170, +84,170,82, +170,84,171, +86,171,84, +171,86,172, +88,172,86, +172,88,173, +90,173,88, +173,90,174, +92,174,90, +174,92,175, +94,175,92, +175,94,176, +96,176,94, +176,96,177, +98,177,96, +177,98,178, +100,178,98, +178,100,179, +102,179,100, +179,102,180, +104,180,102, +180,104,181, +106,181,104, +181,106,182, +108,182,106, +182,108,183, +110,183,108, +183,110,184, +112,184,110, +184,112,185, +114,185,112, +185,114,186, +116,186,114, +186,116,187, +118,187,116, +187,118,188, +120,188,118, +188,120,189, +122,189,120, +189,122,190, +124,190,122, +190,124,191, +126,191,124, +192,128,193, +129,193,128, +193,129,194, +130,194,129, +194,130,195, +131,195,130, +195,131,196, +132,196,131, +196,132,197, +133,197,132, +197,133,198, +134,198,133, +198,134,199, +135,199,134, +199,135,200, +136,200,135, +200,136,201, +137,201,136, +201,137,202, +138,202,137, +202,138,203, +139,203,138, +203,139,204, +140,204,139, +204,140,205, +141,205,140, +205,141,206, +142,206,141, +206,142,207, +143,207,142, +207,143,208, +144,208,143, +208,144,209, +145,209,144, +209,145,210, +146,210,145, +210,146,211, +147,211,146, +211,147,212, +148,212,147, +212,148,213, +149,213,148, +213,149,214, +150,214,149, +214,150,215, +151,215,150, +215,151,216, +152,216,151, +216,152,217, +153,217,152, +217,153,218, +154,218,153, +218,154,219, +155,219,154, +219,155,220, +156,220,155, +220,156,221, +157,221,156, +221,157,222, +158,222,157, +222,158,223, +159,223,158, +223,159,224, +160,224,159, +224,160,225, +161,225,160, +225,161,226, +162,226,161, +226,162,227, +163,227,162, +227,163,228, +164,228,163, +228,164,229, +165,229,164, +229,165,230, +166,230,165, +230,166,231, +167,231,166, +231,167,232, +168,232,167, +232,168,233, +169,233,168, +233,169,234, +170,234,169, +234,170,235, +171,235,170, +235,171,236, +172,236,171, +236,172,237, +173,237,172, +237,173,238, +174,238,173, +238,174,239, +175,239,174, +239,175,240, +176,240,175, +240,176,241, +177,241,176, +241,177,242, +178,242,177, +242,178,243, +179,243,178, +243,179,244, +180,244,179, +244,180,245, +181,245,180, +245,181,246, +182,246,181, +246,182,247, +183,247,182, +247,183,248, +184,248,183, +248,184,249, +185,249,184, +249,185,250, +186,250,185, +250,186,251, +187,251,186, +251,187,252, +188,252,187, +252,188,253, +189,253,188, +253,189,254, +190,254,189, +254,190,255, +191,255,190, +256,192,257, +193,257,192, +257,193,258, +194,258,193, +258,194,259, +195,259,194, +259,195,260, +196,260,195, +260,196,261, +197,261,196, +261,197,262, +198,262,197, +262,198,263, +199,263,198, +263,199,264, +200,264,199, +264,200,265, +201,265,200, +265,201,266, +202,266,201, +266,202,267, +203,267,202, +267,203,268, +204,268,203, +268,204,269, +205,269,204, +269,205,270, +206,270,205, +270,206,271, +207,271,206, +271,207,272, +208,272,207, +272,208,273, +209,273,208, +273,209,274, +210,274,209, +274,210,275, +211,275,210, +275,211,276, +212,276,211, +276,212,277, +213,277,212, +277,213,278, +214,278,213, +278,214,279, +215,279,214, +279,215,280, +216,280,215, +280,216,281, +217,281,216, +281,217,282, +218,282,217, +282,218,283, +219,283,218, +283,219,284, +220,284,219, +284,220,285, +221,285,220, +285,221,286, +222,286,221, +286,222,287, +223,287,222, +287,223,288, +224,288,223, +288,224,289, +225,289,224, +289,225,290, +226,290,225, +290,226,291, +227,291,226, +291,227,292, +228,292,227, +292,228,293, +229,293,228, +293,229,294, +230,294,229, +294,230,295, +231,295,230, +295,231,296, +232,296,231, +296,232,297, +233,297,232, +297,233,298, +234,298,233, +298,234,299, +235,299,234, +299,235,300, +236,300,235, +300,236,301, +237,301,236, +301,237,302, +238,302,237, +302,238,303, +239,303,238, +303,239,304, +240,304,239, +304,240,305, +241,305,240, +305,241,306, +242,306,241, +306,242,307, +243,307,242, +307,243,308, +244,308,243, +308,244,309, +245,309,244, +309,245,310, +246,310,245, +310,246,311, +247,311,246, +311,247,312, +248,312,247, +312,248,313, +249,313,248, +313,249,314, +250,314,249, +314,250,315, +251,315,250, +315,251,316, +252,316,251, +316,252,317, +253,317,252, +317,253,318, +254,318,253, +318,254,319, +255,319,254, +320,256,321, +257,321,256, +321,257,322, +258,322,257, +322,258,323, +259,323,258, +323,259,324, +260,324,259, +324,260,325, +261,325,260, +325,261,326, +262,326,261, +326,262,327, +263,327,262, +327,263,328, +264,328,263, +328,264,329, +265,329,264, +329,265,330, +266,330,265, +330,266,331, +267,331,266, +331,267,332, +268,332,267, +332,268,333, +269,333,268, +333,269,334, +270,334,269, +334,270,335, +271,335,270, +335,271,336, +272,336,271, +336,272,337, +273,337,272, +337,273,338, +274,338,273, +338,274,339, +275,339,274, +339,275,340, +276,340,275, +340,276,341, +277,341,276, +341,277,342, +278,342,277, +342,278,343, +279,343,278, +343,279,344, +280,344,279, +344,280,345, +281,345,280, +345,281,346, +282,346,281, +346,282,347, +283,347,282, +347,283,348, +284,348,283, +348,284,349, +285,349,284, +349,285,350, +286,350,285, +350,286,351, +287,351,286, +351,287,352, +288,352,287, +352,288,353, +289,353,288, +353,289,354, +290,354,289, +354,290,355, +291,355,290, +355,291,356, +292,356,291, +356,292,357, +293,357,292, +357,293,358, +294,358,293, +358,294,359, +295,359,294, +359,295,360, +296,360,295, +360,296,361, +297,361,296, +361,297,362, +298,362,297, +362,298,363, +299,363,298, +363,299,364, +300,364,299, +364,300,365, +301,365,300, +365,301,366, +302,366,301, +366,302,367, +303,367,302, +367,303,368, +304,368,303, +368,304,369, +305,369,304, +369,305,370, +306,370,305, +370,306,371, +307,371,306, +371,307,372, +308,372,307, +372,308,373, +309,373,308, +373,309,374, +310,374,309, +374,310,375, +311,375,310, +375,311,376, +312,376,311, +376,312,377, +313,377,312, +377,313,378, +314,378,313, +378,314,379, +315,379,314, +379,315,380, +316,380,315, +380,316,381, +317,381,316, +381,317,382, +318,382,317, +382,318,383, +319,383,318, +384,320,385, +321,385,320, +385,321,386, +322,386,321, +386,322,387, +323,387,322, +387,323,388, +324,388,323, +388,324,389, +325,389,324, +389,325,390, +326,390,325, +390,326,391, +327,391,326, +391,327,392, +328,392,327, +392,328,393, +329,393,328, +393,329,394, +330,394,329, +394,330,395, +331,395,330, +395,331,396, +332,396,331, +396,332,397, +333,397,332, +397,333,398, +334,398,333, +398,334,399, +335,399,334, +399,335,400, +336,400,335, +400,336,401, +337,401,336, +401,337,402, +338,402,337, +402,338,403, +339,403,338, +403,339,404, +340,404,339, +404,340,405, +341,405,340, +405,341,406, +342,406,341, +406,342,407, +343,407,342, +407,343,408, +344,408,343, +408,344,409, +345,409,344, +409,345,410, +346,410,345, +410,346,411, +347,411,346, +411,347,412, +348,412,347, +412,348,413, +349,413,348, +413,349,414, +350,414,349, +414,350,415, +351,415,350, +415,351,416, +352,416,351, +416,352,417, +353,417,352, +417,353,418, +354,418,353, +418,354,419, +355,419,354, +419,355,420, +356,420,355, +420,356,421, +357,421,356, +421,357,422, +358,422,357, +422,358,423, +359,423,358, +423,359,424, +360,424,359, +424,360,425, +361,425,360, +425,361,426, +362,426,361, +426,362,427, +363,427,362, +427,363,428, +364,428,363, +428,364,429, +365,429,364, +429,365,430, +366,430,365, +430,366,431, +367,431,366, +431,367,432, +368,432,367, +432,368,433, +369,433,368, +433,369,434, +370,434,369, +434,370,435, +371,435,370, +435,371,436, +372,436,371, +436,372,437, +373,437,372, +437,373,438, +374,438,373, +438,374,439, +375,439,374, +439,375,440, +376,440,375, +440,376,441, +377,441,376, +441,377,442, +378,442,377, +442,378,443, +379,443,378, +443,379,444, +380,444,379, +444,380,445, +381,445,380, +445,381,446, +382,446,381, +446,382,447, +383,447,382, +448,384,449, +385,449,384, +449,385,450, +386,450,385, +450,386,451, +387,451,386, +451,387,452, +388,452,387, +452,388,453, +389,453,388, +453,389,454, +390,454,389, +454,390,455, +391,455,390, +455,391,456, +392,456,391, +456,392,457, +393,457,392, +457,393,458, +394,458,393, +458,394,459, +395,459,394, +459,395,460, +396,460,395, +460,396,461, +397,461,396, +461,397,462, +398,462,397, +462,398,463, +399,463,398, +463,399,464, +400,464,399, +464,400,465, +401,465,400, +465,401,466, +402,466,401, +466,402,467, +403,467,402, +467,403,468, +404,468,403, +468,404,469, +405,469,404, +469,405,470, +406,470,405, +470,406,471, +407,471,406, +471,407,472, +408,472,407, +472,408,473, +409,473,408, +473,409,474, +410,474,409, +474,410,475, +411,475,410, +475,411,476, +412,476,411, +476,412,477, +413,477,412, +477,413,478, +414,478,413, +478,414,479, +415,479,414, +479,415,480, +416,480,415, +480,416,481, +417,481,416, +481,417,482, +418,482,417, +482,418,483, +419,483,418, +483,419,484, +420,484,419, +484,420,485, +421,485,420, +485,421,486, +422,486,421, +486,422,487, +423,487,422, +487,423,488, +424,488,423, +488,424,489, +425,489,424, +489,425,490, +426,490,425, +490,426,491, +427,491,426, +491,427,492, +428,492,427, +492,428,493, +429,493,428, +493,429,494, +430,494,429, +494,430,495, +431,495,430, +495,431,496, +432,496,431, +496,432,497, +433,497,432, +497,433,498, +434,498,433, +498,434,499, +435,499,434, +499,435,500, +436,500,435, +500,436,501, +437,501,436, +501,437,502, +438,502,437, +502,438,503, +439,503,438, +503,439,504, +440,504,439, +504,440,505, +441,505,440, +505,441,506, +442,506,441, +506,442,507, +443,507,442, +507,443,508, +444,508,443, +508,444,509, +445,509,444, +509,445,510, +446,510,445, +510,446,511, +447,511,446, +512,448,513, +449,513,448, +513,449,514, +450,514,449, +514,450,515, +451,515,450, +515,451,516, +452,516,451, +516,452,517, +453,517,452, +517,453,518, +454,518,453, +518,454,519, +455,519,454, +519,455,520, +456,520,455, +520,456,521, +457,521,456, +521,457,522, +458,522,457, +522,458,523, +459,523,458, +523,459,524, +460,524,459, +524,460,525, +461,525,460, +525,461,526, +462,526,461, +526,462,527, +463,527,462, +527,463,528, +464,528,463, +528,464,529, +465,529,464, +529,465,530, +466,530,465, +530,466,531, +467,531,466, +531,467,532, +468,532,467, +532,468,533, +469,533,468, +533,469,534, +470,534,469, +534,470,535, +471,535,470, +535,471,536, +472,536,471, +536,472,537, +473,537,472, +537,473,538, +474,538,473, +538,474,539, +475,539,474, +539,475,540, +476,540,475, +540,476,541, +477,541,476, +541,477,542, +478,542,477, +542,478,543, +479,543,478, +543,479,544, +480,544,479, +544,480,545, +481,545,480, +545,481,546, +482,546,481, +546,482,547, +483,547,482, +547,483,548, +484,548,483, +548,484,549, +485,549,484, +549,485,550, +486,550,485, +550,486,551, +487,551,486, +551,487,552, +488,552,487, +552,488,553, +489,553,488, +553,489,554, +490,554,489, +554,490,555, +491,555,490, +555,491,556, +492,556,491, +556,492,557, +493,557,492, +557,493,558, +494,558,493, +558,494,559, +495,559,494, +559,495,560, +496,560,495, +560,496,561, +497,561,496, +561,497,562, +498,562,497, +562,498,563, +499,563,498, +563,499,564, +500,564,499, +564,500,565, +501,565,500, +565,501,566, +502,566,501, +566,502,567, +503,567,502, +567,503,568, +504,568,503, +568,504,569, +505,569,504, +569,505,570, +506,570,505, +570,506,571, +507,571,506, +571,507,572, +508,572,507, +572,508,573, +509,573,508, +573,509,574, +510,574,509, +574,510,575, +511,575,510, +576,512,577, +513,577,512, +577,513,578, +514,578,513, +578,514,579, +515,579,514, +579,515,580, +516,580,515, +580,516,581, +517,581,516, +581,517,582, +518,582,517, +582,518,583, +519,583,518, +583,519,584, +520,584,519, +584,520,585, +521,585,520, +585,521,586, +522,586,521, +586,522,587, +523,587,522, +587,523,588, +524,588,523, +588,524,589, +525,589,524, +589,525,590, +526,590,525, +590,526,591, +527,591,526, +591,527,592, +528,592,527, +592,528,593, +529,593,528, +593,529,594, +530,594,529, +594,530,595, +531,595,530, +595,531,596, +532,596,531, +596,532,597, +533,597,532, +597,533,598, +534,598,533, +598,534,599, +535,599,534, +599,535,600, +536,600,535, +600,536,601, +537,601,536, +601,537,602, +538,602,537, +602,538,603, +539,603,538, +603,539,604, +540,604,539, +604,540,605, +541,605,540, +605,541,606, +542,606,541, +606,542,607, +543,607,542, +607,543,608, +544,608,543, +608,544,609, +545,609,544, +609,545,610, +546,610,545, +610,546,611, +547,611,546, +611,547,612, +548,612,547, +612,548,613, +549,613,548, +613,549,614, +550,614,549, +614,550,615, +551,615,550, +615,551,616, +552,616,551, +616,552,617, +553,617,552, +617,553,618, +554,618,553, +618,554,619, +555,619,554, +619,555,620, +556,620,555, +620,556,621, +557,621,556, +621,557,622, +558,622,557, +622,558,623, +559,623,558, +623,559,624, +560,624,559, +624,560,625, +561,625,560, +625,561,626, +562,626,561, +626,562,627, +563,627,562, +627,563,628, +564,628,563, +628,564,629, +565,629,564, +629,565,630, +566,630,565, +630,566,631, +567,631,566, +631,567,632, +568,632,567, +632,568,633, +569,633,568, +633,569,634, +570,634,569, +634,570,635, +571,635,570, +635,571,636, +572,636,571, +636,572,637, +573,637,572, +637,573,638, +574,638,573, +638,574,639, +575,639,574, +640,576,641, +577,641,576, +641,577,642, +578,642,577, +642,578,643, +579,643,578, +643,579,644, +580,644,579, +644,580,645, +581,645,580, +645,581,646, +582,646,581, +646,582,647, +583,647,582, +647,583,648, +584,648,583, +648,584,649, +585,649,584, +649,585,650, +586,650,585, +650,586,651, +587,651,586, +651,587,652, +588,652,587, +652,588,653, +589,653,588, +653,589,654, +590,654,589, +654,590,655, +591,655,590, +655,591,656, +592,656,591, +656,592,657, +593,657,592, +657,593,658, +594,658,593, +658,594,659, +595,659,594, +659,595,660, +596,660,595, +660,596,661, +597,661,596, +661,597,662, +598,662,597, +662,598,663, +599,663,598, +663,599,664, +600,664,599, +664,600,665, +601,665,600, +665,601,666, +602,666,601, +666,602,667, +603,667,602, +667,603,668, +604,668,603, +668,604,669, +605,669,604, +669,605,670, +606,670,605, +670,606,671, +607,671,606, +671,607,672, +608,672,607, +672,608,673, +609,673,608, +673,609,674, +610,674,609, +674,610,675, +611,675,610, +675,611,676, +612,676,611, +676,612,677, +613,677,612, +677,613,678, +614,678,613, +678,614,679, +615,679,614, +679,615,680, +616,680,615, +680,616,681, +617,681,616, +681,617,682, +618,682,617, +682,618,683, +619,683,618, +683,619,684, +620,684,619, +684,620,685, +621,685,620, +685,621,686, +622,686,621, +686,622,687, +623,687,622, +687,623,688, +624,688,623, +688,624,689, +625,689,624, +689,625,690, +626,690,625, +690,626,691, +627,691,626, +691,627,692, +628,692,627, +692,628,693, +629,693,628, +693,629,694, +630,694,629, +694,630,695, +631,695,630, +695,631,696, +632,696,631, +696,632,697, +633,697,632, +697,633,698, +634,698,633, +698,634,699, +635,699,634, +699,635,700, +636,700,635, +700,636,701, +637,701,636, +701,637,702, +638,702,637, +702,638,703, +639,703,638, +704,640,705, +641,705,640, +705,641,706, +642,706,641, +706,642,707, +643,707,642, +707,643,708, +644,708,643, +708,644,709, +645,709,644, +709,645,710, +646,710,645, +710,646,711, +647,711,646, +711,647,712, +648,712,647, +712,648,713, +649,713,648, +713,649,714, +650,714,649, +714,650,715, +651,715,650, +715,651,716, +652,716,651, +716,652,717, +653,717,652, +717,653,718, +654,718,653, +718,654,719, +655,719,654, +719,655,720, +656,720,655, +720,656,721, +657,721,656, +721,657,722, +658,722,657, +722,658,723, +659,723,658, +723,659,724, +660,724,659, +724,660,725, +661,725,660, +725,661,726, +662,726,661, +726,662,727, +663,727,662, +727,663,728, +664,728,663, +728,664,729, +665,729,664, +729,665,730, +666,730,665, +730,666,731, +667,731,666, +731,667,732, +668,732,667, +732,668,733, +669,733,668, +733,669,734, +670,734,669, +734,670,735, +671,735,670, +735,671,736, +672,736,671, +736,672,737, +673,737,672, +737,673,738, +674,738,673, +738,674,739, +675,739,674, +739,675,740, +676,740,675, +740,676,741, +677,741,676, +741,677,742, +678,742,677, +742,678,743, +679,743,678, +743,679,744, +680,744,679, +744,680,745, +681,745,680, +745,681,746, +682,746,681, +746,682,747, +683,747,682, +747,683,748, +684,748,683, +748,684,749, +685,749,684, +749,685,750, +686,750,685, +750,686,751, +687,751,686, +751,687,752, +688,752,687, +752,688,753, +689,753,688, +753,689,754, +690,754,689, +754,690,755, +691,755,690, +755,691,756, +692,756,691, +756,692,757, +693,757,692, +757,693,758, +694,758,693, +758,694,759, +695,759,694, +759,695,760, +696,760,695, +760,696,761, +697,761,696, +761,697,762, +698,762,697, +762,698,763, +699,763,698, +763,699,764, +700,764,699, +764,700,765, +701,765,700, +765,701,766, +702,766,701, +766,702,767, +703,767,702, +768,704,769, +705,769,704, +769,705,770, +706,770,705, +770,706,771, +707,771,706, +771,707,772, +708,772,707, +772,708,773, +709,773,708, +773,709,774, +710,774,709, +774,710,775, +711,775,710, +775,711,776, +712,776,711, +776,712,777, +713,777,712, +777,713,778, +714,778,713, +778,714,779, +715,779,714, +779,715,780, +716,780,715, +780,716,781, +717,781,716, +781,717,782, +718,782,717, +782,718,783, +719,783,718, +783,719,784, +720,784,719, +784,720,785, +721,785,720, +785,721,786, +722,786,721, +786,722,787, +723,787,722, +787,723,788, +724,788,723, +788,724,789, +725,789,724, +789,725,790, +726,790,725, +790,726,791, +727,791,726, +791,727,792, +728,792,727, +792,728,793, +729,793,728, +793,729,794, +730,794,729, +794,730,795, +731,795,730, +795,731,796, +732,796,731, +796,732,797, +733,797,732, +797,733,798, +734,798,733, +798,734,799, +735,799,734, +799,735,800, +736,800,735, +800,736,801, +737,801,736, +801,737,802, +738,802,737, +802,738,803, +739,803,738, +803,739,804, +740,804,739, +804,740,805, +741,805,740, +805,741,806, +742,806,741, +806,742,807, +743,807,742, +807,743,808, +744,808,743, +808,744,809, +745,809,744, +809,745,810, +746,810,745, +810,746,811, +747,811,746, +811,747,812, +748,812,747, +812,748,813, +749,813,748, +813,749,814, +750,814,749, +814,750,815, +751,815,750, +815,751,816, +752,816,751, +816,752,817, +753,817,752, +817,753,818, +754,818,753, +818,754,819, +755,819,754, +819,755,820, +756,820,755, +820,756,821, +757,821,756, +821,757,822, +758,822,757, +822,758,823, +759,823,758, +823,759,824, +760,824,759, +824,760,825, +761,825,760, +825,761,826, +762,826,761, +826,762,827, +763,827,762, +827,763,828, +764,828,763, +828,764,829, +765,829,764, +829,765,830, +766,830,765, +830,766,831, +767,831,766, +832,768,833, +769,833,768, +833,769,834, +770,834,769, +834,770,835, +771,835,770, +835,771,836, +772,836,771, +836,772,837, +773,837,772, +837,773,838, +774,838,773, +838,774,839, +775,839,774, +839,775,840, +776,840,775, +840,776,841, +777,841,776, +841,777,842, +778,842,777, +842,778,843, +779,843,778, +843,779,844, +780,844,779, +844,780,845, +781,845,780, +845,781,846, +782,846,781, +846,782,847, +783,847,782, +847,783,848, +784,848,783, +848,784,849, +785,849,784, +849,785,850, +786,850,785, +850,786,851, +787,851,786, +851,787,852, +788,852,787, +852,788,853, +789,853,788, +853,789,854, +790,854,789, +854,790,855, +791,855,790, +855,791,856, +792,856,791, +856,792,857, +793,857,792, +857,793,858, +794,858,793, +858,794,859, +795,859,794, +859,795,860, +796,860,795, +860,796,861, +797,861,796, +861,797,862, +798,862,797, +862,798,863, +799,863,798, +863,799,864, +800,864,799, +864,800,865, +801,865,800, +865,801,866, +802,866,801, +866,802,867, +803,867,802, +867,803,868, +804,868,803, +868,804,869, +805,869,804, +869,805,870, +806,870,805, +870,806,871, +807,871,806, +871,807,872, +808,872,807, +872,808,873, +809,873,808, +873,809,874, +810,874,809, +874,810,875, +811,875,810, +875,811,876, +812,876,811, +876,812,877, +813,877,812, +877,813,878, +814,878,813, +878,814,879, +815,879,814, +879,815,880, +816,880,815, +880,816,881, +817,881,816, +881,817,882, +818,882,817, +882,818,883, +819,883,818, +883,819,884, +820,884,819, +884,820,885, +821,885,820, +885,821,886, +822,886,821, +886,822,887, +823,887,822, +887,823,888, +824,888,823, +888,824,889, +825,889,824, +889,825,890, +826,890,825, +890,826,891, +827,891,826, +891,827,892, +828,892,827, +892,828,893, +829,893,828, +893,829,894, +830,894,829, +894,830,895, +831,895,830, +896,832,897, +833,897,832, +897,833,898, +834,898,833, +898,834,899, +835,899,834, +899,835,900, +836,900,835, +900,836,901, +837,901,836, +901,837,902, +838,902,837, +902,838,903, +839,903,838, +903,839,904, +840,904,839, +904,840,905, +841,905,840, +905,841,906, +842,906,841, +906,842,907, +843,907,842, +907,843,908, +844,908,843, +908,844,909, +845,909,844, +909,845,910, +846,910,845, +910,846,911, +847,911,846, +911,847,912, +848,912,847, +912,848,913, +849,913,848, +913,849,914, +850,914,849, +914,850,915, +851,915,850, +915,851,916, +852,916,851, +916,852,917, +853,917,852, +917,853,918, +854,918,853, +918,854,919, +855,919,854, +919,855,920, +856,920,855, +920,856,921, +857,921,856, +921,857,922, +858,922,857, +922,858,923, +859,923,858, +923,859,924, +860,924,859, +924,860,925, +861,925,860, +925,861,926, +862,926,861, +926,862,927, +863,927,862, +927,863,928, +864,928,863, +928,864,929, +865,929,864, +929,865,930, +866,930,865, +930,866,931, +867,931,866, +931,867,932, +868,932,867, +932,868,933, +869,933,868, +933,869,934, +870,934,869, +934,870,935, +871,935,870, +935,871,936, +872,936,871, +936,872,937, +873,937,872, +937,873,938, +874,938,873, +938,874,939, +875,939,874, +939,875,940, +876,940,875, +940,876,941, +877,941,876, +941,877,942, +878,942,877, +942,878,943, +879,943,878, +943,879,944, +880,944,879, +944,880,945, +881,945,880, +945,881,946, +882,946,881, +946,882,947, +883,947,882, +947,883,948, +884,948,883, +948,884,949, +885,949,884, +949,885,950, +886,950,885, +950,886,951, +887,951,886, +951,887,952, +888,952,887, +952,888,953, +889,953,888, +953,889,954, +890,954,889, +954,890,955, +891,955,890, +955,891,956, +892,956,891, +956,892,957, +893,957,892, +957,893,958, +894,958,893, +958,894,959, +895,959,894, +960,896,961, +897,961,896, +961,897,962, +898,962,897, +962,898,963, +899,963,898, +963,899,964, +900,964,899, +964,900,965, +901,965,900, +965,901,966, +902,966,901, +966,902,967, +903,967,902, +967,903,968, +904,968,903, +968,904,969, +905,969,904, +969,905,970, +906,970,905, +970,906,971, +907,971,906, +971,907,972, +908,972,907, +972,908,973, +909,973,908, +973,909,974, +910,974,909, +974,910,975, +911,975,910, +975,911,976, +912,976,911, +976,912,977, +913,977,912, +977,913,978, +914,978,913, +978,914,979, +915,979,914, +979,915,980, +916,980,915, +980,916,981, +917,981,916, +981,917,982, +918,982,917, +982,918,983, +919,983,918, +983,919,984, +920,984,919, +984,920,985, +921,985,920, +985,921,986, +922,986,921, +986,922,987, +923,987,922, +987,923,988, +924,988,923, +988,924,989, +925,989,924, +989,925,990, +926,990,925, +990,926,991, +927,991,926, +991,927,992, +928,992,927, +992,928,993, +929,993,928, +993,929,994, +930,994,929, +994,930,995, +931,995,930, +995,931,996, +932,996,931, +996,932,997, +933,997,932, +997,933,998, +934,998,933, +998,934,999, +935,999,934, +999,935,1000, +936,1000,935, +1000,936,1001, +937,1001,936, +1001,937,1002, +938,1002,937, +1002,938,1003, +939,1003,938, +1003,939,1004, +940,1004,939, +1004,940,1005, +941,1005,940, +1005,941,1006, +942,1006,941, +1006,942,1007, +943,1007,942, +1007,943,1008, +944,1008,943, +1008,944,1009, +945,1009,944, +1009,945,1010, +946,1010,945, +1010,946,1011, +947,1011,946, +1011,947,1012, +948,1012,947, +1012,948,1013, +949,1013,948, +1013,949,1014, +950,1014,949, +1014,950,1015, +951,1015,950, +1015,951,1016, +952,1016,951, +1016,952,1017, +953,1017,952, +1017,953,1018, +954,1018,953, +1018,954,1019, +955,1019,954, +1019,955,1020, +956,1020,955, +1020,956,1021, +957,1021,956, +1021,957,1022, +958,1022,957, +1022,958,1023, +959,1023,958, +1024,960,1025, +961,1025,960, +1025,961,1026, +962,1026,961, +1026,962,1027, +963,1027,962, +1027,963,1028, +964,1028,963, +1028,964,1029, +965,1029,964, +1029,965,1030, +966,1030,965, +1030,966,1031, +967,1031,966, +1031,967,1032, +968,1032,967, +1032,968,1033, +969,1033,968, +1033,969,1034, +970,1034,969, +1034,970,1035, +971,1035,970, +1035,971,1036, +972,1036,971, +1036,972,1037, +973,1037,972, +1037,973,1038, +974,1038,973, +1038,974,1039, +975,1039,974, +1039,975,1040, +976,1040,975, +1040,976,1041, +977,1041,976, +1041,977,1042, +978,1042,977, +1042,978,1043, +979,1043,978, +1043,979,1044, +980,1044,979, +1044,980,1045, +981,1045,980, +1045,981,1046, +982,1046,981, +1046,982,1047, +983,1047,982, +1047,983,1048, +984,1048,983, +1048,984,1049, +985,1049,984, +1049,985,1050, +986,1050,985, +1050,986,1051, +987,1051,986, +1051,987,1052, +988,1052,987, +1052,988,1053, +989,1053,988, +1053,989,1054, +990,1054,989, +1054,990,1055, +991,1055,990, +1055,991,1056, +992,1056,991, +1056,992,1057, +993,1057,992, +1057,993,1058, +994,1058,993, +1058,994,1059, +995,1059,994, +1059,995,1060, +996,1060,995, +1060,996,1061, +997,1061,996, +1061,997,1062, +998,1062,997, +1062,998,1063, +999,1063,998, +1063,999,1064, +1000,1064,999, +1064,1000,1065, +1001,1065,1000, +1065,1001,1066, +1002,1066,1001, +1066,1002,1067, +1003,1067,1002, +1067,1003,1068, +1004,1068,1003, +1068,1004,1069, +1005,1069,1004, +1069,1005,1070, +1006,1070,1005, +1070,1006,1071, +1007,1071,1006, +1071,1007,1072, +1008,1072,1007, +1072,1008,1073, +1009,1073,1008, +1073,1009,1074, +1010,1074,1009, +1074,1010,1075, +1011,1075,1010, +1075,1011,1076, +1012,1076,1011, +1076,1012,1077, +1013,1077,1012, +1077,1013,1078, +1014,1078,1013, +1078,1014,1079, +1015,1079,1014, +1079,1015,1080, +1016,1080,1015, +1080,1016,1081, +1017,1081,1016, +1081,1017,1082, +1018,1082,1017, +1082,1018,1083, +1019,1083,1018, +1083,1019,1084, +1020,1084,1019, +1084,1020,1085, +1021,1085,1020, +1085,1021,1086, +1022,1086,1021, +1086,1022,1087, +1023,1087,1022, +1088,1024,1089, +1025,1089,1024, +1089,1025,1090, +1026,1090,1025, +1090,1026,1091, +1027,1091,1026, +1091,1027,1092, +1028,1092,1027, +1092,1028,1093, +1029,1093,1028, +1093,1029,1094, +1030,1094,1029, +1094,1030,1095, +1031,1095,1030, +1095,1031,1096, +1032,1096,1031, +1096,1032,1097, +1033,1097,1032, +1097,1033,1098, +1034,1098,1033, +1098,1034,1099, +1035,1099,1034, +1099,1035,1100, +1036,1100,1035, +1100,1036,1101, +1037,1101,1036, +1101,1037,1102, +1038,1102,1037, +1102,1038,1103, +1039,1103,1038, +1103,1039,1104, +1040,1104,1039, +1104,1040,1105, +1041,1105,1040, +1105,1041,1106, +1042,1106,1041, +1106,1042,1107, +1043,1107,1042, +1107,1043,1108, +1044,1108,1043, +1108,1044,1109, +1045,1109,1044, +1109,1045,1110, +1046,1110,1045, +1110,1046,1111, +1047,1111,1046, +1111,1047,1112, +1048,1112,1047, +1112,1048,1113, +1049,1113,1048, +1113,1049,1114, +1050,1114,1049, +1114,1050,1115, +1051,1115,1050, +1115,1051,1116, +1052,1116,1051, +1116,1052,1117, +1053,1117,1052, +1117,1053,1118, +1054,1118,1053, +1118,1054,1119, +1055,1119,1054, +1119,1055,1120, +1056,1120,1055, +1120,1056,1121, +1057,1121,1056, +1121,1057,1122, +1058,1122,1057, +1122,1058,1123, +1059,1123,1058, +1123,1059,1124, +1060,1124,1059, +1124,1060,1125, +1061,1125,1060, +1125,1061,1126, +1062,1126,1061, +1126,1062,1127, +1063,1127,1062, +1127,1063,1128, +1064,1128,1063, +1128,1064,1129, +1065,1129,1064, +1129,1065,1130, +1066,1130,1065, +1130,1066,1131, +1067,1131,1066, +1131,1067,1132, +1068,1132,1067, +1132,1068,1133, +1069,1133,1068, +1133,1069,1134, +1070,1134,1069, +1134,1070,1135, +1071,1135,1070, +1135,1071,1136, +1072,1136,1071, +1136,1072,1137, +1073,1137,1072, +1137,1073,1138, +1074,1138,1073, +1138,1074,1139, +1075,1139,1074, +1139,1075,1140, +1076,1140,1075, +1140,1076,1141, +1077,1141,1076, +1141,1077,1142, +1078,1142,1077, +1142,1078,1143, +1079,1143,1078, +1143,1079,1144, +1080,1144,1079, +1144,1080,1145, +1081,1145,1080, +1145,1081,1146, +1082,1146,1081, +1146,1082,1147, +1083,1147,1082, +1147,1083,1148, +1084,1148,1083, +1148,1084,1149, +1085,1149,1084, +1149,1085,1150, +1086,1150,1085, +1150,1086,1151, +1087,1151,1086, +1152,1088,1153, +1089,1153,1088, +1153,1089,1154, +1090,1154,1089, +1154,1090,1155, +1091,1155,1090, +1155,1091,1156, +1092,1156,1091, +1156,1092,1157, +1093,1157,1092, +1157,1093,1158, +1094,1158,1093, +1158,1094,1159, +1095,1159,1094, +1159,1095,1160, +1096,1160,1095, +1160,1096,1161, +1097,1161,1096, +1161,1097,1162, +1098,1162,1097, +1162,1098,1163, +1099,1163,1098, +1163,1099,1164, +1100,1164,1099, +1164,1100,1165, +1101,1165,1100, +1165,1101,1166, +1102,1166,1101, +1166,1102,1167, +1103,1167,1102, +1167,1103,1168, +1104,1168,1103, +1168,1104,1169, +1105,1169,1104, +1169,1105,1170, +1106,1170,1105, +1170,1106,1171, +1107,1171,1106, +1171,1107,1172, +1108,1172,1107, +1172,1108,1173, +1109,1173,1108, +1173,1109,1174, +1110,1174,1109, +1174,1110,1175, +1111,1175,1110, +1175,1111,1176, +1112,1176,1111, +1176,1112,1177, +1113,1177,1112, +1177,1113,1178, +1114,1178,1113, +1178,1114,1179, +1115,1179,1114, +1179,1115,1180, +1116,1180,1115, +1180,1116,1181, +1117,1181,1116, +1181,1117,1182, +1118,1182,1117, +1182,1118,1183, +1119,1183,1118, +1183,1119,1184, +1120,1184,1119, +1184,1120,1185, +1121,1185,1120, +1185,1121,1186, +1122,1186,1121, +1186,1122,1187, +1123,1187,1122, +1187,1123,1188, +1124,1188,1123, +1188,1124,1189, +1125,1189,1124, +1189,1125,1190, +1126,1190,1125, +1190,1126,1191, +1127,1191,1126, +1191,1127,1192, +1128,1192,1127, +1192,1128,1193, +1129,1193,1128, +1193,1129,1194, +1130,1194,1129, +1194,1130,1195, +1131,1195,1130, +1195,1131,1196, +1132,1196,1131, +1196,1132,1197, +1133,1197,1132, +1197,1133,1198, +1134,1198,1133, +1198,1134,1199, +1135,1199,1134, +1199,1135,1200, +1136,1200,1135, +1200,1136,1201, +1137,1201,1136, +1201,1137,1202, +1138,1202,1137, +1202,1138,1203, +1139,1203,1138, +1203,1139,1204, +1140,1204,1139, +1204,1140,1205, +1141,1205,1140, +1205,1141,1206, +1142,1206,1141, +1206,1142,1207, +1143,1207,1142, +1207,1143,1208, +1144,1208,1143, +1208,1144,1209, +1145,1209,1144, +1209,1145,1210, +1146,1210,1145, +1210,1146,1211, +1147,1211,1146, +1211,1147,1212, +1148,1212,1147, +1212,1148,1213, +1149,1213,1148, +1213,1149,1214, +1150,1214,1149, +1214,1150,1215, +1151,1215,1150, +1216,1152,1217, +1153,1217,1152, +1217,1153,1218, +1154,1218,1153, +1218,1154,1219, +1155,1219,1154, +1219,1155,1220, +1156,1220,1155, +1220,1156,1221, +1157,1221,1156, +1221,1157,1222, +1158,1222,1157, +1222,1158,1223, +1159,1223,1158, +1223,1159,1224, +1160,1224,1159, +1224,1160,1225, +1161,1225,1160, +1225,1161,1226, +1162,1226,1161, +1226,1162,1227, +1163,1227,1162, +1227,1163,1228, +1164,1228,1163, +1228,1164,1229, +1165,1229,1164, +1229,1165,1230, +1166,1230,1165, +1230,1166,1231, +1167,1231,1166, +1231,1167,1232, +1168,1232,1167, +1232,1168,1233, +1169,1233,1168, +1233,1169,1234, +1170,1234,1169, +1234,1170,1235, +1171,1235,1170, +1235,1171,1236, +1172,1236,1171, +1236,1172,1237, +1173,1237,1172, +1237,1173,1238, +1174,1238,1173, +1238,1174,1239, +1175,1239,1174, +1239,1175,1240, +1176,1240,1175, +1240,1176,1241, +1177,1241,1176, +1241,1177,1242, +1178,1242,1177, +1242,1178,1243, +1179,1243,1178, +1243,1179,1244, +1180,1244,1179, +1244,1180,1245, +1181,1245,1180, +1245,1181,1246, +1182,1246,1181, +1246,1182,1247, +1183,1247,1182, +1247,1183,1248, +1184,1248,1183, +1248,1184,1249, +1185,1249,1184, +1249,1185,1250, +1186,1250,1185, +1250,1186,1251, +1187,1251,1186, +1251,1187,1252, +1188,1252,1187, +1252,1188,1253, +1189,1253,1188, +1253,1189,1254, +1190,1254,1189, +1254,1190,1255, +1191,1255,1190, +1255,1191,1256, +1192,1256,1191, +1256,1192,1257, +1193,1257,1192, +1257,1193,1258, +1194,1258,1193, +1258,1194,1259, +1195,1259,1194, +1259,1195,1260, +1196,1260,1195, +1260,1196,1261, +1197,1261,1196, +1261,1197,1262, +1198,1262,1197, +1262,1198,1263, +1199,1263,1198, +1263,1199,1264, +1200,1264,1199, +1264,1200,1265, +1201,1265,1200, +1265,1201,1266, +1202,1266,1201, +1266,1202,1267, +1203,1267,1202, +1267,1203,1268, +1204,1268,1203, +1268,1204,1269, +1205,1269,1204, +1269,1205,1270, +1206,1270,1205, +1270,1206,1271, +1207,1271,1206, +1271,1207,1272, +1208,1272,1207, +1272,1208,1273, +1209,1273,1208, +1273,1209,1274, +1210,1274,1209, +1274,1210,1275, +1211,1275,1210, +1275,1211,1276, +1212,1276,1211, +1276,1212,1277, +1213,1277,1212, +1277,1213,1278, +1214,1278,1213, +1278,1214,1279, +1215,1279,1214, +1280,1216,1281, +1217,1281,1216, +1281,1217,1282, +1218,1282,1217, +1282,1218,1283, +1219,1283,1218, +1283,1219,1284, +1220,1284,1219, +1284,1220,1285, +1221,1285,1220, +1285,1221,1286, +1222,1286,1221, +1286,1222,1287, +1223,1287,1222, +1287,1223,1288, +1224,1288,1223, +1288,1224,1289, +1225,1289,1224, +1289,1225,1290, +1226,1290,1225, +1290,1226,1291, +1227,1291,1226, +1291,1227,1292, +1228,1292,1227, +1292,1228,1293, +1229,1293,1228, +1293,1229,1294, +1230,1294,1229, +1294,1230,1295, +1231,1295,1230, +1295,1231,1296, +1232,1296,1231, +1296,1232,1297, +1233,1297,1232, +1297,1233,1298, +1234,1298,1233, +1298,1234,1299, +1235,1299,1234, +1299,1235,1300, +1236,1300,1235, +1300,1236,1301, +1237,1301,1236, +1301,1237,1302, +1238,1302,1237, +1302,1238,1303, +1239,1303,1238, +1303,1239,1304, +1240,1304,1239, +1304,1240,1305, +1241,1305,1240, +1305,1241,1306, +1242,1306,1241, +1306,1242,1307, +1243,1307,1242, +1307,1243,1308, +1244,1308,1243, +1308,1244,1309, +1245,1309,1244, +1309,1245,1310, +1246,1310,1245, +1310,1246,1311, +1247,1311,1246, +1311,1247,1312, +1248,1312,1247, +1312,1248,1313, +1249,1313,1248, +1313,1249,1314, +1250,1314,1249, +1314,1250,1315, +1251,1315,1250, +1315,1251,1316, +1252,1316,1251, +1316,1252,1317, +1253,1317,1252, +1317,1253,1318, +1254,1318,1253, +1318,1254,1319, +1255,1319,1254, +1319,1255,1320, +1256,1320,1255, +1320,1256,1321, +1257,1321,1256, +1321,1257,1322, +1258,1322,1257, +1322,1258,1323, +1259,1323,1258, +1323,1259,1324, +1260,1324,1259, +1324,1260,1325, +1261,1325,1260, +1325,1261,1326, +1262,1326,1261, +1326,1262,1327, +1263,1327,1262, +1327,1263,1328, +1264,1328,1263, +1328,1264,1329, +1265,1329,1264, +1329,1265,1330, +1266,1330,1265, +1330,1266,1331, +1267,1331,1266, +1331,1267,1332, +1268,1332,1267, +1332,1268,1333, +1269,1333,1268, +1333,1269,1334, +1270,1334,1269, +1334,1270,1335, +1271,1335,1270, +1335,1271,1336, +1272,1336,1271, +1336,1272,1337, +1273,1337,1272, +1337,1273,1338, +1274,1338,1273, +1338,1274,1339, +1275,1339,1274, +1339,1275,1340, +1276,1340,1275, +1340,1276,1341, +1277,1341,1276, +1341,1277,1342, +1278,1342,1277, +1342,1278,1343, +1279,1343,1278, +1344,1280,1345, +1281,1345,1280, +1345,1281,1346, +1282,1346,1281, +1346,1282,1347, +1283,1347,1282, +1347,1283,1348, +1284,1348,1283, +1348,1284,1349, +1285,1349,1284, +1349,1285,1350, +1286,1350,1285, +1350,1286,1351, +1287,1351,1286, +1351,1287,1352, +1288,1352,1287, +1352,1288,1353, +1289,1353,1288, +1353,1289,1354, +1290,1354,1289, +1354,1290,1355, +1291,1355,1290, +1355,1291,1356, +1292,1356,1291, +1356,1292,1357, +1293,1357,1292, +1357,1293,1358, +1294,1358,1293, +1358,1294,1359, +1295,1359,1294, +1359,1295,1360, +1296,1360,1295, +1360,1296,1361, +1297,1361,1296, +1361,1297,1362, +1298,1362,1297, +1362,1298,1363, +1299,1363,1298, +1363,1299,1364, +1300,1364,1299, +1364,1300,1365, +1301,1365,1300, +1365,1301,1366, +1302,1366,1301, +1366,1302,1367, +1303,1367,1302, +1367,1303,1368, +1304,1368,1303, +1368,1304,1369, +1305,1369,1304, +1369,1305,1370, +1306,1370,1305, +1370,1306,1371, +1307,1371,1306, +1371,1307,1372, +1308,1372,1307, +1372,1308,1373, +1309,1373,1308, +1373,1309,1374, +1310,1374,1309, +1374,1310,1375, +1311,1375,1310, +1375,1311,1376, +1312,1376,1311, +1376,1312,1377, +1313,1377,1312, +1377,1313,1378, +1314,1378,1313, +1378,1314,1379, +1315,1379,1314, +1379,1315,1380, +1316,1380,1315, +1380,1316,1381, +1317,1381,1316, +1381,1317,1382, +1318,1382,1317, +1382,1318,1383, +1319,1383,1318, +1383,1319,1384, +1320,1384,1319, +1384,1320,1385, +1321,1385,1320, +1385,1321,1386, +1322,1386,1321, +1386,1322,1387, +1323,1387,1322, +1387,1323,1388, +1324,1388,1323, +1388,1324,1389, +1325,1389,1324, +1389,1325,1390, +1326,1390,1325, +1390,1326,1391, +1327,1391,1326, +1391,1327,1392, +1328,1392,1327, +1392,1328,1393, +1329,1393,1328, +1393,1329,1394, +1330,1394,1329, +1394,1330,1395, +1331,1395,1330, +1395,1331,1396, +1332,1396,1331, +1396,1332,1397, +1333,1397,1332, +1397,1333,1398, +1334,1398,1333, +1398,1334,1399, +1335,1399,1334, +1399,1335,1400, +1336,1400,1335, +1400,1336,1401, +1337,1401,1336, +1401,1337,1402, +1338,1402,1337, +1402,1338,1403, +1339,1403,1338, +1403,1339,1404, +1340,1404,1339, +1404,1340,1405, +1341,1405,1340, +1405,1341,1406, +1342,1406,1341, +1406,1342,1407, +1343,1407,1342, +1408,1344,1409, +1345,1409,1344, +1409,1345,1410, +1346,1410,1345, +1410,1346,1411, +1347,1411,1346, +1411,1347,1412, +1348,1412,1347, +1412,1348,1413, +1349,1413,1348, +1413,1349,1414, +1350,1414,1349, +1414,1350,1415, +1351,1415,1350, +1415,1351,1416, +1352,1416,1351, +1416,1352,1417, +1353,1417,1352, +1417,1353,1418, +1354,1418,1353, +1418,1354,1419, +1355,1419,1354, +1419,1355,1420, +1356,1420,1355, +1420,1356,1421, +1357,1421,1356, +1421,1357,1422, +1358,1422,1357, +1422,1358,1423, +1359,1423,1358, +1423,1359,1424, +1360,1424,1359, +1424,1360,1425, +1361,1425,1360, +1425,1361,1426, +1362,1426,1361, +1426,1362,1427, +1363,1427,1362, +1427,1363,1428, +1364,1428,1363, +1428,1364,1429, +1365,1429,1364, +1429,1365,1430, +1366,1430,1365, +1430,1366,1431, +1367,1431,1366, +1431,1367,1432, +1368,1432,1367, +1432,1368,1433, +1369,1433,1368, +1433,1369,1434, +1370,1434,1369, +1434,1370,1435, +1371,1435,1370, +1435,1371,1436, +1372,1436,1371, +1436,1372,1437, +1373,1437,1372, +1437,1373,1438, +1374,1438,1373, +1438,1374,1439, +1375,1439,1374, +1439,1375,1440, +1376,1440,1375, +1440,1376,1441, +1377,1441,1376, +1441,1377,1442, +1378,1442,1377, +1442,1378,1443, +1379,1443,1378, +1443,1379,1444, +1380,1444,1379, +1444,1380,1445, +1381,1445,1380, +1445,1381,1446, +1382,1446,1381, +1446,1382,1447, +1383,1447,1382, +1447,1383,1448, +1384,1448,1383, +1448,1384,1449, +1385,1449,1384, +1449,1385,1450, +1386,1450,1385, +1450,1386,1451, +1387,1451,1386, +1451,1387,1452, +1388,1452,1387, +1452,1388,1453, +1389,1453,1388, +1453,1389,1454, +1390,1454,1389, +1454,1390,1455, +1391,1455,1390, +1455,1391,1456, +1392,1456,1391, +1456,1392,1457, +1393,1457,1392, +1457,1393,1458, +1394,1458,1393, +1458,1394,1459, +1395,1459,1394, +1459,1395,1460, +1396,1460,1395, +1460,1396,1461, +1397,1461,1396, +1461,1397,1462, +1398,1462,1397, +1462,1398,1463, +1399,1463,1398, +1463,1399,1464, +1400,1464,1399, +1464,1400,1465, +1401,1465,1400, +1465,1401,1466, +1402,1466,1401, +1466,1402,1467, +1403,1467,1402, +1467,1403,1468, +1404,1468,1403, +1468,1404,1469, +1405,1469,1404, +1469,1405,1470, +1406,1470,1405, +1470,1406,1471, +1407,1471,1406, +1472,1408,1473, +1409,1473,1408, +1473,1409,1474, +1410,1474,1409, +1474,1410,1475, +1411,1475,1410, +1475,1411,1476, +1412,1476,1411, +1476,1412,1477, +1413,1477,1412, +1477,1413,1478, +1414,1478,1413, +1478,1414,1479, +1415,1479,1414, +1479,1415,1480, +1416,1480,1415, +1480,1416,1481, +1417,1481,1416, +1481,1417,1482, +1418,1482,1417, +1482,1418,1483, +1419,1483,1418, +1483,1419,1484, +1420,1484,1419, +1484,1420,1485, +1421,1485,1420, +1485,1421,1486, +1422,1486,1421, +1486,1422,1487, +1423,1487,1422, +1487,1423,1488, +1424,1488,1423, +1488,1424,1489, +1425,1489,1424, +1489,1425,1490, +1426,1490,1425, +1490,1426,1491, +1427,1491,1426, +1491,1427,1492, +1428,1492,1427, +1492,1428,1493, +1429,1493,1428, +1493,1429,1494, +1430,1494,1429, +1494,1430,1495, +1431,1495,1430, +1495,1431,1496, +1432,1496,1431, +1496,1432,1497, +1433,1497,1432, +1497,1433,1498, +1434,1498,1433, +1498,1434,1499, +1435,1499,1434, +1499,1435,1500, +1436,1500,1435, +1500,1436,1501, +1437,1501,1436, +1501,1437,1502, +1438,1502,1437, +1502,1438,1503, +1439,1503,1438, +1503,1439,1504, +1440,1504,1439, +1504,1440,1505, +1441,1505,1440, +1505,1441,1506, +1442,1506,1441, +1506,1442,1507, +1443,1507,1442, +1507,1443,1508, +1444,1508,1443, +1508,1444,1509, +1445,1509,1444, +1509,1445,1510, +1446,1510,1445, +1510,1446,1511, +1447,1511,1446, +1511,1447,1512, +1448,1512,1447, +1512,1448,1513, +1449,1513,1448, +1513,1449,1514, +1450,1514,1449, +1514,1450,1515, +1451,1515,1450, +1515,1451,1516, +1452,1516,1451, +1516,1452,1517, +1453,1517,1452, +1517,1453,1518, +1454,1518,1453, +1518,1454,1519, +1455,1519,1454, +1519,1455,1520, +1456,1520,1455, +1520,1456,1521, +1457,1521,1456, +1521,1457,1522, +1458,1522,1457, +1522,1458,1523, +1459,1523,1458, +1523,1459,1524, +1460,1524,1459, +1524,1460,1525, +1461,1525,1460, +1525,1461,1526, +1462,1526,1461, +1526,1462,1527, +1463,1527,1462, +1527,1463,1528, +1464,1528,1463, +1528,1464,1529, +1465,1529,1464, +1529,1465,1530, +1466,1530,1465, +1530,1466,1531, +1467,1531,1466, +1531,1467,1532, +1468,1532,1467, +1532,1468,1533, +1469,1533,1468, +1533,1469,1534, +1470,1534,1469, +1534,1470,1535, +1471,1535,1470, +1536,1472,1537, +1473,1537,1472, +1537,1473,1538, +1474,1538,1473, +1538,1474,1539, +1475,1539,1474, +1539,1475,1540, +1476,1540,1475, +1540,1476,1541, +1477,1541,1476, +1541,1477,1542, +1478,1542,1477, +1542,1478,1543, +1479,1543,1478, +1543,1479,1544, +1480,1544,1479, +1544,1480,1545, +1481,1545,1480, +1545,1481,1546, +1482,1546,1481, +1546,1482,1547, +1483,1547,1482, +1547,1483,1548, +1484,1548,1483, +1548,1484,1549, +1485,1549,1484, +1549,1485,1550, +1486,1550,1485, +1550,1486,1551, +1487,1551,1486, +1551,1487,1552, +1488,1552,1487, +1552,1488,1553, +1489,1553,1488, +1553,1489,1554, +1490,1554,1489, +1554,1490,1555, +1491,1555,1490, +1555,1491,1556, +1492,1556,1491, +1556,1492,1557, +1493,1557,1492, +1557,1493,1558, +1494,1558,1493, +1558,1494,1559, +1495,1559,1494, +1559,1495,1560, +1496,1560,1495, +1560,1496,1561, +1497,1561,1496, +1561,1497,1562, +1498,1562,1497, +1562,1498,1563, +1499,1563,1498, +1563,1499,1564, +1500,1564,1499, +1564,1500,1565, +1501,1565,1500, +1565,1501,1566, +1502,1566,1501, +1566,1502,1567, +1503,1567,1502, +1567,1503,1568, +1504,1568,1503, +1568,1504,1569, +1505,1569,1504, +1569,1505,1570, +1506,1570,1505, +1570,1506,1571, +1507,1571,1506, +1571,1507,1572, +1508,1572,1507, +1572,1508,1573, +1509,1573,1508, +1573,1509,1574, +1510,1574,1509, +1574,1510,1575, +1511,1575,1510, +1575,1511,1576, +1512,1576,1511, +1576,1512,1577, +1513,1577,1512, +1577,1513,1578, +1514,1578,1513, +1578,1514,1579, +1515,1579,1514, +1579,1515,1580, +1516,1580,1515, +1580,1516,1581, +1517,1581,1516, +1581,1517,1582, +1518,1582,1517, +1582,1518,1583, +1519,1583,1518, +1583,1519,1584, +1520,1584,1519, +1584,1520,1585, +1521,1585,1520, +1585,1521,1586, +1522,1586,1521, +1586,1522,1587, +1523,1587,1522, +1587,1523,1588, +1524,1588,1523, +1588,1524,1589, +1525,1589,1524, +1589,1525,1590, +1526,1590,1525, +1590,1526,1591, +1527,1591,1526, +1591,1527,1592, +1528,1592,1527, +1592,1528,1593, +1529,1593,1528, +1593,1529,1594, +1530,1594,1529, +1594,1530,1595, +1531,1595,1530, +1595,1531,1596, +1532,1596,1531, +1596,1532,1597, +1533,1597,1532, +1597,1533,1598, +1534,1598,1533, +1598,1534,1599, +1535,1599,1534, +1600,1536,1601, +1537,1601,1536, +1601,1537,1602, +1538,1602,1537, +1602,1538,1603, +1539,1603,1538, +1603,1539,1604, +1540,1604,1539, +1604,1540,1605, +1541,1605,1540, +1605,1541,1606, +1542,1606,1541, +1606,1542,1607, +1543,1607,1542, +1607,1543,1608, +1544,1608,1543, +1608,1544,1609, +1545,1609,1544, +1609,1545,1610, +1546,1610,1545, +1610,1546,1611, +1547,1611,1546, +1611,1547,1612, +1548,1612,1547, +1612,1548,1613, +1549,1613,1548, +1613,1549,1614, +1550,1614,1549, +1614,1550,1615, +1551,1615,1550, +1615,1551,1616, +1552,1616,1551, +1616,1552,1617, +1553,1617,1552, +1617,1553,1618, +1554,1618,1553, +1618,1554,1619, +1555,1619,1554, +1619,1555,1620, +1556,1620,1555, +1620,1556,1621, +1557,1621,1556, +1621,1557,1622, +1558,1622,1557, +1622,1558,1623, +1559,1623,1558, +1623,1559,1624, +1560,1624,1559, +1624,1560,1625, +1561,1625,1560, +1625,1561,1626, +1562,1626,1561, +1626,1562,1627, +1563,1627,1562, +1627,1563,1628, +1564,1628,1563, +1628,1564,1629, +1565,1629,1564, +1629,1565,1630, +1566,1630,1565, +1630,1566,1631, +1567,1631,1566, +1631,1567,1632, +1568,1632,1567, +1632,1568,1633, +1569,1633,1568, +1633,1569,1634, +1570,1634,1569, +1634,1570,1635, +1571,1635,1570, +1635,1571,1636, +1572,1636,1571, +1636,1572,1637, +1573,1637,1572, +1637,1573,1638, +1574,1638,1573, +1638,1574,1639, +1575,1639,1574, +1639,1575,1640, +1576,1640,1575, +1640,1576,1641, +1577,1641,1576, +1641,1577,1642, +1578,1642,1577, +1642,1578,1643, +1579,1643,1578, +1643,1579,1644, +1580,1644,1579, +1644,1580,1645, +1581,1645,1580, +1645,1581,1646, +1582,1646,1581, +1646,1582,1647, +1583,1647,1582, +1647,1583,1648, +1584,1648,1583, +1648,1584,1649, +1585,1649,1584, +1649,1585,1650, +1586,1650,1585, +1650,1586,1651, +1587,1651,1586, +1651,1587,1652, +1588,1652,1587, +1652,1588,1653, +1589,1653,1588, +1653,1589,1654, +1590,1654,1589, +1654,1590,1655, +1591,1655,1590, +1655,1591,1656, +1592,1656,1591, +1656,1592,1657, +1593,1657,1592, +1657,1593,1658, +1594,1658,1593, +1658,1594,1659, +1595,1659,1594, +1659,1595,1660, +1596,1660,1595, +1660,1596,1661, +1597,1661,1596, +1661,1597,1662, +1598,1662,1597, +1662,1598,1663, +1599,1663,1598, +1664,1600,1665, +1601,1665,1600, +1665,1601,1666, +1602,1666,1601, +1666,1602,1667, +1603,1667,1602, +1667,1603,1668, +1604,1668,1603, +1668,1604,1669, +1605,1669,1604, +1669,1605,1670, +1606,1670,1605, +1670,1606,1671, +1607,1671,1606, +1671,1607,1672, +1608,1672,1607, +1672,1608,1673, +1609,1673,1608, +1673,1609,1674, +1610,1674,1609, +1674,1610,1675, +1611,1675,1610, +1675,1611,1676, +1612,1676,1611, +1676,1612,1677, +1613,1677,1612, +1677,1613,1678, +1614,1678,1613, +1678,1614,1679, +1615,1679,1614, +1679,1615,1680, +1616,1680,1615, +1680,1616,1681, +1617,1681,1616, +1681,1617,1682, +1618,1682,1617, +1682,1618,1683, +1619,1683,1618, +1683,1619,1684, +1620,1684,1619, +1684,1620,1685, +1621,1685,1620, +1685,1621,1686, +1622,1686,1621, +1686,1622,1687, +1623,1687,1622, +1687,1623,1688, +1624,1688,1623, +1688,1624,1689, +1625,1689,1624, +1689,1625,1690, +1626,1690,1625, +1690,1626,1691, +1627,1691,1626, +1691,1627,1692, +1628,1692,1627, +1692,1628,1693, +1629,1693,1628, +1693,1629,1694, +1630,1694,1629, +1694,1630,1695, +1631,1695,1630, +1695,1631,1696, +1632,1696,1631, +1696,1632,1697, +1633,1697,1632, +1697,1633,1698, +1634,1698,1633, +1698,1634,1699, +1635,1699,1634, +1699,1635,1700, +1636,1700,1635, +1700,1636,1701, +1637,1701,1636, +1701,1637,1702, +1638,1702,1637, +1702,1638,1703, +1639,1703,1638, +1703,1639,1704, +1640,1704,1639, +1704,1640,1705, +1641,1705,1640, +1705,1641,1706, +1642,1706,1641, +1706,1642,1707, +1643,1707,1642, +1707,1643,1708, +1644,1708,1643, +1708,1644,1709, +1645,1709,1644, +1709,1645,1710, +1646,1710,1645, +1710,1646,1711, +1647,1711,1646, +1711,1647,1712, +1648,1712,1647, +1712,1648,1713, +1649,1713,1648, +1713,1649,1714, +1650,1714,1649, +1714,1650,1715, +1651,1715,1650, +1715,1651,1716, +1652,1716,1651, +1716,1652,1717, +1653,1717,1652, +1717,1653,1718, +1654,1718,1653, +1718,1654,1719, +1655,1719,1654, +1719,1655,1720, +1656,1720,1655, +1720,1656,1721, +1657,1721,1656, +1721,1657,1722, +1658,1722,1657, +1722,1658,1723, +1659,1723,1658, +1723,1659,1724, +1660,1724,1659, +1724,1660,1725, +1661,1725,1660, +1725,1661,1726, +1662,1726,1661, +1726,1662,1727, +1663,1727,1662, +1728,1664,1729, +1665,1729,1664, +1729,1665,1730, +1666,1730,1665, +1730,1666,1731, +1667,1731,1666, +1731,1667,1732, +1668,1732,1667, +1732,1668,1733, +1669,1733,1668, +1733,1669,1734, +1670,1734,1669, +1734,1670,1735, +1671,1735,1670, +1735,1671,1736, +1672,1736,1671, +1736,1672,1737, +1673,1737,1672, +1737,1673,1738, +1674,1738,1673, +1738,1674,1739, +1675,1739,1674, +1739,1675,1740, +1676,1740,1675, +1740,1676,1741, +1677,1741,1676, +1741,1677,1742, +1678,1742,1677, +1742,1678,1743, +1679,1743,1678, +1743,1679,1744, +1680,1744,1679, +1744,1680,1745, +1681,1745,1680, +1745,1681,1746, +1682,1746,1681, +1746,1682,1747, +1683,1747,1682, +1747,1683,1748, +1684,1748,1683, +1748,1684,1749, +1685,1749,1684, +1749,1685,1750, +1686,1750,1685, +1750,1686,1751, +1687,1751,1686, +1751,1687,1752, +1688,1752,1687, +1752,1688,1753, +1689,1753,1688, +1753,1689,1754, +1690,1754,1689, +1754,1690,1755, +1691,1755,1690, +1755,1691,1756, +1692,1756,1691, +1756,1692,1757, +1693,1757,1692, +1757,1693,1758, +1694,1758,1693, +1758,1694,1759, +1695,1759,1694, +1759,1695,1760, +1696,1760,1695, +1760,1696,1761, +1697,1761,1696, +1761,1697,1762, +1698,1762,1697, +1762,1698,1763, +1699,1763,1698, +1763,1699,1764, +1700,1764,1699, +1764,1700,1765, +1701,1765,1700, +1765,1701,1766, +1702,1766,1701, +1766,1702,1767, +1703,1767,1702, +1767,1703,1768, +1704,1768,1703, +1768,1704,1769, +1705,1769,1704, +1769,1705,1770, +1706,1770,1705, +1770,1706,1771, +1707,1771,1706, +1771,1707,1772, +1708,1772,1707, +1772,1708,1773, +1709,1773,1708, +1773,1709,1774, +1710,1774,1709, +1774,1710,1775, +1711,1775,1710, +1775,1711,1776, +1712,1776,1711, +1776,1712,1777, +1713,1777,1712, +1777,1713,1778, +1714,1778,1713, +1778,1714,1779, +1715,1779,1714, +1779,1715,1780, +1716,1780,1715, +1780,1716,1781, +1717,1781,1716, +1781,1717,1782, +1718,1782,1717, +1782,1718,1783, +1719,1783,1718, +1783,1719,1784, +1720,1784,1719, +1784,1720,1785, +1721,1785,1720, +1785,1721,1786, +1722,1786,1721, +1786,1722,1787, +1723,1787,1722, +1787,1723,1788, +1724,1788,1723, +1788,1724,1789, +1725,1789,1724, +1789,1725,1790, +1726,1790,1725, +1790,1726,1791, +1727,1791,1726, +1792,1728,1793, +1729,1793,1728, +1793,1729,1794, +1730,1794,1729, +1794,1730,1795, +1731,1795,1730, +1795,1731,1796, +1732,1796,1731, +1796,1732,1797, +1733,1797,1732, +1797,1733,1798, +1734,1798,1733, +1798,1734,1799, +1735,1799,1734, +1799,1735,1800, +1736,1800,1735, +1800,1736,1801, +1737,1801,1736, +1801,1737,1802, +1738,1802,1737, +1802,1738,1803, +1739,1803,1738, +1803,1739,1804, +1740,1804,1739, +1804,1740,1805, +1741,1805,1740, +1805,1741,1806, +1742,1806,1741, +1806,1742,1807, +1743,1807,1742, +1807,1743,1808, +1744,1808,1743, +1808,1744,1809, +1745,1809,1744, +1809,1745,1810, +1746,1810,1745, +1810,1746,1811, +1747,1811,1746, +1811,1747,1812, +1748,1812,1747, +1812,1748,1813, +1749,1813,1748, +1813,1749,1814, +1750,1814,1749, +1814,1750,1815, +1751,1815,1750, +1815,1751,1816, +1752,1816,1751, +1816,1752,1817, +1753,1817,1752, +1817,1753,1818, +1754,1818,1753, +1818,1754,1819, +1755,1819,1754, +1819,1755,1820, +1756,1820,1755, +1820,1756,1821, +1757,1821,1756, +1821,1757,1822, +1758,1822,1757, +1822,1758,1823, +1759,1823,1758, +1823,1759,1824, +1760,1824,1759, +1824,1760,1825, +1761,1825,1760, +1825,1761,1826, +1762,1826,1761, +1826,1762,1827, +1763,1827,1762, +1827,1763,1828, +1764,1828,1763, +1828,1764,1829, +1765,1829,1764, +1829,1765,1830, +1766,1830,1765, +1830,1766,1831, +1767,1831,1766, +1831,1767,1832, +1768,1832,1767, +1832,1768,1833, +1769,1833,1768, +1833,1769,1834, +1770,1834,1769, +1834,1770,1835, +1771,1835,1770, +1835,1771,1836, +1772,1836,1771, +1836,1772,1837, +1773,1837,1772, +1837,1773,1838, +1774,1838,1773, +1838,1774,1839, +1775,1839,1774, +1839,1775,1840, +1776,1840,1775, +1840,1776,1841, +1777,1841,1776, +1841,1777,1842, +1778,1842,1777, +1842,1778,1843, +1779,1843,1778, +1843,1779,1844, +1780,1844,1779, +1844,1780,1845, +1781,1845,1780, +1845,1781,1846, +1782,1846,1781, +1846,1782,1847, +1783,1847,1782, +1847,1783,1848, +1784,1848,1783, +1848,1784,1849, +1785,1849,1784, +1849,1785,1850, +1786,1850,1785, +1850,1786,1851, +1787,1851,1786, +1851,1787,1852, +1788,1852,1787, +1852,1788,1853, +1789,1853,1788, +1853,1789,1854, +1790,1854,1789, +1854,1790,1855, +1791,1855,1790, +1856,1792,1857, +1793,1857,1792, +1857,1793,1858, +1794,1858,1793, +1858,1794,1859, +1795,1859,1794, +1859,1795,1860, +1796,1860,1795, +1860,1796,1861, +1797,1861,1796, +1861,1797,1862, +1798,1862,1797, +1862,1798,1863, +1799,1863,1798, +1863,1799,1864, +1800,1864,1799, +1864,1800,1865, +1801,1865,1800, +1865,1801,1866, +1802,1866,1801, +1866,1802,1867, +1803,1867,1802, +1867,1803,1868, +1804,1868,1803, +1868,1804,1869, +1805,1869,1804, +1869,1805,1870, +1806,1870,1805, +1870,1806,1871, +1807,1871,1806, +1871,1807,1872, +1808,1872,1807, +1872,1808,1873, +1809,1873,1808, +1873,1809,1874, +1810,1874,1809, +1874,1810,1875, +1811,1875,1810, +1875,1811,1876, +1812,1876,1811, +1876,1812,1877, +1813,1877,1812, +1877,1813,1878, +1814,1878,1813, +1878,1814,1879, +1815,1879,1814, +1879,1815,1880, +1816,1880,1815, +1880,1816,1881, +1817,1881,1816, +1881,1817,1882, +1818,1882,1817, +1882,1818,1883, +1819,1883,1818, +1883,1819,1884, +1820,1884,1819, +1884,1820,1885, +1821,1885,1820, +1885,1821,1886, +1822,1886,1821, +1886,1822,1887, +1823,1887,1822, +1887,1823,1888, +1824,1888,1823, +1888,1824,1889, +1825,1889,1824, +1889,1825,1890, +1826,1890,1825, +1890,1826,1891, +1827,1891,1826, +1891,1827,1892, +1828,1892,1827, +1892,1828,1893, +1829,1893,1828, +1893,1829,1894, +1830,1894,1829, +1894,1830,1895, +1831,1895,1830, +1895,1831,1896, +1832,1896,1831, +1896,1832,1897, +1833,1897,1832, +1897,1833,1898, +1834,1898,1833, +1898,1834,1899, +1835,1899,1834, +1899,1835,1900, +1836,1900,1835, +1900,1836,1901, +1837,1901,1836, +1901,1837,1902, +1838,1902,1837, +1902,1838,1903, +1839,1903,1838, +1903,1839,1904, +1840,1904,1839, +1904,1840,1905, +1841,1905,1840, +1905,1841,1906, +1842,1906,1841, +1906,1842,1907, +1843,1907,1842, +1907,1843,1908, +1844,1908,1843, +1908,1844,1909, +1845,1909,1844, +1909,1845,1910, +1846,1910,1845, +1910,1846,1911, +1847,1911,1846, +1911,1847,1912, +1848,1912,1847, +1912,1848,1913, +1849,1913,1848, +1913,1849,1914, +1850,1914,1849, +1914,1850,1915, +1851,1915,1850, +1915,1851,1916, +1852,1916,1851, +1916,1852,1917, +1853,1917,1852, +1917,1853,1918, +1854,1918,1853, +1918,1854,1919, +1855,1919,1854, +1920,1856,1921, +1857,1921,1856, +1921,1857,1922, +1858,1922,1857, +1922,1858,1923, +1859,1923,1858, +1923,1859,1924, +1860,1924,1859, +1924,1860,1925, +1861,1925,1860, +1925,1861,1926, +1862,1926,1861, +1926,1862,1927, +1863,1927,1862, +1927,1863,1928, +1864,1928,1863, +1928,1864,1929, +1865,1929,1864, +1929,1865,1930, +1866,1930,1865, +1930,1866,1931, +1867,1931,1866, +1931,1867,1932, +1868,1932,1867, +1932,1868,1933, +1869,1933,1868, +1933,1869,1934, +1870,1934,1869, +1934,1870,1935, +1871,1935,1870, +1935,1871,1936, +1872,1936,1871, +1936,1872,1937, +1873,1937,1872, +1937,1873,1938, +1874,1938,1873, +1938,1874,1939, +1875,1939,1874, +1939,1875,1940, +1876,1940,1875, +1940,1876,1941, +1877,1941,1876, +1941,1877,1942, +1878,1942,1877, +1942,1878,1943, +1879,1943,1878, +1943,1879,1944, +1880,1944,1879, +1944,1880,1945, +1881,1945,1880, +1945,1881,1946, +1882,1946,1881, +1946,1882,1947, +1883,1947,1882, +1947,1883,1948, +1884,1948,1883, +1948,1884,1949, +1885,1949,1884, +1949,1885,1950, +1886,1950,1885, +1950,1886,1951, +1887,1951,1886, +1951,1887,1952, +1888,1952,1887, +1952,1888,1953, +1889,1953,1888, +1953,1889,1954, +1890,1954,1889, +1954,1890,1955, +1891,1955,1890, +1955,1891,1956, +1892,1956,1891, +1956,1892,1957, +1893,1957,1892, +1957,1893,1958, +1894,1958,1893, +1958,1894,1959, +1895,1959,1894, +1959,1895,1960, +1896,1960,1895, +1960,1896,1961, +1897,1961,1896, +1961,1897,1962, +1898,1962,1897, +1962,1898,1963, +1899,1963,1898, +1963,1899,1964, +1900,1964,1899, +1964,1900,1965, +1901,1965,1900, +1965,1901,1966, +1902,1966,1901, +1966,1902,1967, +1903,1967,1902, +1967,1903,1968, +1904,1968,1903, +1968,1904,1969, +1905,1969,1904, +1969,1905,1970, +1906,1970,1905, +1970,1906,1971, +1907,1971,1906, +1971,1907,1972, +1908,1972,1907, +1972,1908,1973, +1909,1973,1908, +1973,1909,1974, +1910,1974,1909, +1974,1910,1975, +1911,1975,1910, +1975,1911,1976, +1912,1976,1911, +1976,1912,1977, +1913,1977,1912, +1977,1913,1978, +1914,1978,1913, +1978,1914,1979, +1915,1979,1914, +1979,1915,1980, +1916,1980,1915, +1980,1916,1981, +1917,1981,1916, +1981,1917,1982, +1918,1982,1917, +1982,1918,1983, +1919,1983,1918, +1984,1920,1985, +1921,1985,1920, +1985,1921,1986, +1922,1986,1921, +1986,1922,1987, +1923,1987,1922, +1987,1923,1988, +1924,1988,1923, +1988,1924,1989, +1925,1989,1924, +1989,1925,1990, +1926,1990,1925, +1990,1926,1991, +1927,1991,1926, +1991,1927,1992, +1928,1992,1927, +1992,1928,1993, +1929,1993,1928, +1993,1929,1994, +1930,1994,1929, +1994,1930,1995, +1931,1995,1930, +1995,1931,1996, +1932,1996,1931, +1996,1932,1997, +1933,1997,1932, +1997,1933,1998, +1934,1998,1933, +1998,1934,1999, +1935,1999,1934, +1999,1935,2000, +1936,2000,1935, +2000,1936,2001, +1937,2001,1936, +2001,1937,2002, +1938,2002,1937, +2002,1938,2003, +1939,2003,1938, +2003,1939,2004, +1940,2004,1939, +2004,1940,2005, +1941,2005,1940, +2005,1941,2006, +1942,2006,1941, +2006,1942,2007, +1943,2007,1942, +2007,1943,2008, +1944,2008,1943, +2008,1944,2009, +1945,2009,1944, +2009,1945,2010, +1946,2010,1945, +2010,1946,2011, +1947,2011,1946, +2011,1947,2012, +1948,2012,1947, +2012,1948,2013, +1949,2013,1948, +2013,1949,2014, +1950,2014,1949, +2014,1950,2015, +1951,2015,1950, +2015,1951,2016, +1952,2016,1951, +2016,1952,2017, +1953,2017,1952, +2017,1953,2018, +1954,2018,1953, +2018,1954,2019, +1955,2019,1954, +2019,1955,2020, +1956,2020,1955, +2020,1956,2021, +1957,2021,1956, +2021,1957,2022, +1958,2022,1957, +2022,1958,2023, +1959,2023,1958, +2023,1959,2024, +1960,2024,1959, +2024,1960,2025, +1961,2025,1960, +2025,1961,2026, +1962,2026,1961, +2026,1962,2027, +1963,2027,1962, +2027,1963,2028, +1964,2028,1963, +2028,1964,2029, +1965,2029,1964, +2029,1965,2030, +1966,2030,1965, +2030,1966,2031, +1967,2031,1966, +2031,1967,2032, +1968,2032,1967, +2032,1968,2033, +1969,2033,1968, +2033,1969,2034, +1970,2034,1969, +2034,1970,2035, +1971,2035,1970, +2035,1971,2036, +1972,2036,1971, +2036,1972,2037, +1973,2037,1972, +2037,1973,2038, +1974,2038,1973, +2038,1974,2039, +1975,2039,1974, +2039,1975,2040, +1976,2040,1975, +2040,1976,2041, +1977,2041,1976, +2041,1977,2042, +1978,2042,1977, +2042,1978,2043, +1979,2043,1978, +2043,1979,2044, +1980,2044,1979, +2044,1980,2045, +1981,2045,1980, +2045,1981,2046, +1982,2046,1981, +2046,1982,2047, +1983,2047,1982, +2048,1984,2049, +1985,2049,1984, +2049,1985,2050, +1986,2050,1985, +2050,1986,2051, +1987,2051,1986, +2051,1987,2052, +1988,2052,1987, +2052,1988,2053, +1989,2053,1988, +2053,1989,2054, +1990,2054,1989, +2054,1990,2055, +1991,2055,1990, +2055,1991,2056, +1992,2056,1991, +2056,1992,2057, +1993,2057,1992, +2057,1993,2058, +1994,2058,1993, +2058,1994,2059, +1995,2059,1994, +2059,1995,2060, +1996,2060,1995, +2060,1996,2061, +1997,2061,1996, +2061,1997,2062, +1998,2062,1997, +2062,1998,2063, +1999,2063,1998, +2063,1999,2064, +2000,2064,1999, +2064,2000,2065, +2001,2065,2000, +2065,2001,2066, +2002,2066,2001, +2066,2002,2067, +2003,2067,2002, +2067,2003,2068, +2004,2068,2003, +2068,2004,2069, +2005,2069,2004, +2069,2005,2070, +2006,2070,2005, +2070,2006,2071, +2007,2071,2006, +2071,2007,2072, +2008,2072,2007, +2072,2008,2073, +2009,2073,2008, +2073,2009,2074, +2010,2074,2009, +2074,2010,2075, +2011,2075,2010, +2075,2011,2076, +2012,2076,2011, +2076,2012,2077, +2013,2077,2012, +2077,2013,2078, +2014,2078,2013, +2078,2014,2079, +2015,2079,2014, +2079,2015,2080, +2016,2080,2015, +2080,2016,2081, +2017,2081,2016, +2081,2017,2082, +2018,2082,2017, +2082,2018,2083, +2019,2083,2018, +2083,2019,2084, +2020,2084,2019, +2084,2020,2085, +2021,2085,2020, +2085,2021,2086, +2022,2086,2021, +2086,2022,2087, +2023,2087,2022, +2087,2023,2088, +2024,2088,2023, +2088,2024,2089, +2025,2089,2024, +2089,2025,2090, +2026,2090,2025, +2090,2026,2091, +2027,2091,2026, +2091,2027,2092, +2028,2092,2027, +2092,2028,2093, +2029,2093,2028, +2093,2029,2094, +2030,2094,2029, +2094,2030,2095, +2031,2095,2030, +2095,2031,2096, +2032,2096,2031, +2096,2032,2097, +2033,2097,2032, +2097,2033,2098, +2034,2098,2033, +2098,2034,2099, +2035,2099,2034, +2099,2035,2100, +2036,2100,2035, +2100,2036,2101, +2037,2101,2036, +2101,2037,2102, +2038,2102,2037, +2102,2038,2103, +2039,2103,2038, +2103,2039,2104, +2040,2104,2039, +2104,2040,2105, +2041,2105,2040, +2105,2041,2106, +2042,2106,2041, +2106,2042,2107, +2043,2107,2042, +2107,2043,2108, +2044,2108,2043, +2108,2044,2109, +2045,2109,2044, +2109,2045,2110, +2046,2110,2045, +2110,2046,2111, +2047,2111,2046, +2112,2048,2113, +2049,2113,2048, +2113,2049,2114, +2050,2114,2049, +2114,2050,2115, +2051,2115,2050, +2115,2051,2116, +2052,2116,2051, +2116,2052,2117, +2053,2117,2052, +2117,2053,2118, +2054,2118,2053, +2118,2054,2119, +2055,2119,2054, +2119,2055,2120, +2056,2120,2055, +2120,2056,2121, +2057,2121,2056, +2121,2057,2122, +2058,2122,2057, +2122,2058,2123, +2059,2123,2058, +2123,2059,2124, +2060,2124,2059, +2124,2060,2125, +2061,2125,2060, +2125,2061,2126, +2062,2126,2061, +2126,2062,2127, +2063,2127,2062, +2127,2063,2128, +2064,2128,2063, +2128,2064,2129, +2065,2129,2064, +2129,2065,2130, +2066,2130,2065, +2130,2066,2131, +2067,2131,2066, +2131,2067,2132, +2068,2132,2067, +2132,2068,2133, +2069,2133,2068, +2133,2069,2134, +2070,2134,2069, +2134,2070,2135, +2071,2135,2070, +2135,2071,2136, +2072,2136,2071, +2136,2072,2137, +2073,2137,2072, +2137,2073,2138, +2074,2138,2073, +2138,2074,2139, +2075,2139,2074, +2139,2075,2140, +2076,2140,2075, +2140,2076,2141, +2077,2141,2076, +2141,2077,2142, +2078,2142,2077, +2142,2078,2143, +2079,2143,2078, +2143,2079,2144, +2080,2144,2079, +2144,2080,2145, +2081,2145,2080, +2145,2081,2146, +2082,2146,2081, +2146,2082,2147, +2083,2147,2082, +2147,2083,2148, +2084,2148,2083, +2148,2084,2149, +2085,2149,2084, +2149,2085,2150, +2086,2150,2085, +2150,2086,2151, +2087,2151,2086, +2151,2087,2152, +2088,2152,2087, +2152,2088,2153, +2089,2153,2088, +2153,2089,2154, +2090,2154,2089, +2154,2090,2155, +2091,2155,2090, +2155,2091,2156, +2092,2156,2091, +2156,2092,2157, +2093,2157,2092, +2157,2093,2158, +2094,2158,2093, +2158,2094,2159, +2095,2159,2094, +2159,2095,2160, +2096,2160,2095, +2160,2096,2161, +2097,2161,2096, +2161,2097,2162, +2098,2162,2097, +2162,2098,2163, +2099,2163,2098, +2163,2099,2164, +2100,2164,2099, +2164,2100,2165, +2101,2165,2100, +2165,2101,2166, +2102,2166,2101, +2166,2102,2167, +2103,2167,2102, +2167,2103,2168, +2104,2168,2103, +2168,2104,2169, +2105,2169,2104, +2169,2105,2170, +2106,2170,2105, +2170,2106,2171, +2107,2171,2106, +2171,2107,2172, +2108,2172,2107, +2172,2108,2173, +2109,2173,2108, +2173,2109,2174, +2110,2174,2109, +2174,2110,2175, +2111,2175,2110, +2176,2112,2177, +2113,2177,2112, +2177,2113,2178, +2114,2178,2113, +2178,2114,2179, +2115,2179,2114, +2179,2115,2180, +2116,2180,2115, +2180,2116,2181, +2117,2181,2116, +2181,2117,2182, +2118,2182,2117, +2182,2118,2183, +2119,2183,2118, +2183,2119,2184, +2120,2184,2119, +2184,2120,2185, +2121,2185,2120, +2185,2121,2186, +2122,2186,2121, +2186,2122,2187, +2123,2187,2122, +2187,2123,2188, +2124,2188,2123, +2188,2124,2189, +2125,2189,2124, +2189,2125,2190, +2126,2190,2125, +2190,2126,2191, +2127,2191,2126, +2191,2127,2192, +2128,2192,2127, +2192,2128,2193, +2129,2193,2128, +2193,2129,2194, +2130,2194,2129, +2194,2130,2195, +2131,2195,2130, +2195,2131,2196, +2132,2196,2131, +2196,2132,2197, +2133,2197,2132, +2197,2133,2198, +2134,2198,2133, +2198,2134,2199, +2135,2199,2134, +2199,2135,2200, +2136,2200,2135, +2200,2136,2201, +2137,2201,2136, +2201,2137,2202, +2138,2202,2137, +2202,2138,2203, +2139,2203,2138, +2203,2139,2204, +2140,2204,2139, +2204,2140,2205, +2141,2205,2140, +2205,2141,2206, +2142,2206,2141, +2206,2142,2207, +2143,2207,2142, +2207,2143,2208, +2144,2208,2143, +2208,2144,2209, +2145,2209,2144, +2209,2145,2210, +2146,2210,2145, +2210,2146,2211, +2147,2211,2146, +2211,2147,2212, +2148,2212,2147, +2212,2148,2213, +2149,2213,2148, +2213,2149,2214, +2150,2214,2149, +2214,2150,2215, +2151,2215,2150, +2215,2151,2216, +2152,2216,2151, +2216,2152,2217, +2153,2217,2152, +2217,2153,2218, +2154,2218,2153, +2218,2154,2219, +2155,2219,2154, +2219,2155,2220, +2156,2220,2155, +2220,2156,2221, +2157,2221,2156, +2221,2157,2222, +2158,2222,2157, +2222,2158,2223, +2159,2223,2158, +2223,2159,2224, +2160,2224,2159, +2224,2160,2225, +2161,2225,2160, +2225,2161,2226, +2162,2226,2161, +2226,2162,2227, +2163,2227,2162, +2227,2163,2228, +2164,2228,2163, +2228,2164,2229, +2165,2229,2164, +2229,2165,2230, +2166,2230,2165, +2230,2166,2231, +2167,2231,2166, +2231,2167,2232, +2168,2232,2167, +2232,2168,2233, +2169,2233,2168, +2233,2169,2234, +2170,2234,2169, +2234,2170,2235, +2171,2235,2170, +2235,2171,2236, +2172,2236,2171, +2236,2172,2237, +2173,2237,2172, +2237,2173,2238, +2174,2238,2173, +2238,2174,2239, +2175,2239,2174, +}; + +#define Landscape08VtxCount 2178 +#define Landscape08IdxCount 12480 + +btScalar Landscape08Vtx[] = { +-250.0f,30.98f,-128.906f, +-250.0f,31.4025f,-125.0f, +-246.094f,31.7629f,-128.906f, +-246.094f,31.4165f,-125.0f, +-242.188f,32.5689f,-128.906f, +-242.188f,32.314f,-125.0f, +-238.281f,32.9125f,-128.906f, +-238.281f,32.9822f,-125.0f, +-234.375f,32.5915f,-128.906f, +-234.375f,32.6962f,-125.0f, +-230.469f,31.2708f,-128.906f, +-230.469f,31.3632f,-125.0f, +-226.563f,30.5212f,-128.906f, +-226.563f,29.4391f,-125.0f, +-222.656f,30.2031f,-128.906f, +-222.656f,29.519f,-125.0f, +-218.75f,30.4582f,-128.906f, +-218.75f,29.4481f,-125.0f, +-214.844f,30.6941f,-128.906f, +-214.844f,29.8481f,-125.0f, +-210.938f,30.5035f,-128.906f, +-210.938f,30.408f,-125.0f, +-207.031f,30.2726f,-128.906f, +-207.031f,30.291f,-125.0f, +-203.125f,29.38f,-128.906f, +-203.125f,28.7473f,-125.0f, +-199.219f,28.6973f,-128.906f, +-199.219f,28.1816f,-125.0f, +-195.313f,27.9768f,-128.906f, +-195.313f,27.2839f,-125.0f, +-191.406f,26.1169f,-128.906f, +-191.406f,25.7018f,-125.0f, +-187.5f,23.8648f,-128.906f, +-187.5f,23.2882f,-125.0f, +-183.594f,21.95f,-128.906f, +-183.594f,22.1614f,-125.0f, +-179.688f,19.6798f,-128.906f, +-179.688f,20.658f,-125.0f, +-175.781f,17.3507f,-128.906f, +-175.781f,18.8433f,-125.0f, +-171.875f,15.7914f,-128.906f, +-171.875f,16.364f,-125.0f, +-167.969f,14.3745f,-128.906f, +-167.969f,14.7298f,-125.0f, +-164.063f,12.4911f,-128.906f, +-164.063f,12.9859f,-125.0f, +-160.156f,11.0533f,-128.906f, +-160.156f,11.3306f,-125.0f, +-156.25f,9.15062f,-128.906f, +-156.25f,10.1916f,-125.0f, +-152.344f,6.68059f,-128.906f, +-152.344f,8.3967f,-125.0f, +-148.438f,5.57112f,-128.906f, +-148.438f,6.23292f,-125.0f, +-144.531f,5.2271f,-128.906f, +-144.531f,5.48985f,-125.0f, +-140.625f,5.87576f,-128.906f, +-140.625f,5.18276f,-125.0f, +-136.719f,6.85614f,-128.906f, +-136.719f,5.56059f,-125.0f, +-132.813f,6.86087f,-128.906f, +-132.813f,5.75157f,-125.0f, +-128.906f,7.10341f,-128.906f, +-128.906f,5.32154f,-125.0f, +-125.0f,7.54727f,-128.906f, +-125.0f,6.15672f,-125.0f, +-121.094f,8.02225f,-128.906f, +-121.094f,7.53373f,-125.0f, +-117.188f,8.70065f,-128.906f, +-117.188f,8.38676f,-125.0f, +-113.281f,9.39689f,-128.906f, +-113.281f,8.64274f,-125.0f, +-109.375f,8.80449f,-128.906f, +-109.375f,8.49941f,-125.0f, +-105.469f,9.43366f,-128.906f, +-105.469f,9.24481f,-125.0f, +-101.563f,10.868f,-128.906f, +-101.563f,11.5178f,-125.0f, +-97.6563f,12.8404f,-128.906f, +-97.6563f,13.4113f,-125.0f, +-93.75f,14.8214f,-128.906f, +-93.75f,15.4997f,-125.0f, +-89.8438f,16.618f,-128.906f, +-89.8438f,17.3502f,-125.0f, +-85.9375f,20.2496f,-128.906f, +-85.9375f,20.8168f,-125.0f, +-82.0313f,23.697f,-128.906f, +-82.0313f,24.9405f,-125.0f, +-78.125f,26.4451f,-128.906f, +-78.125f,27.8681f,-125.0f, +-74.2188f,28.7901f,-128.906f, +-74.2188f,30.1495f,-125.0f, +-70.3125f,31.4052f,-128.906f, +-70.3125f,32.4402f,-125.0f, +-66.4063f,33.3106f,-128.906f, +-66.4063f,34.2537f,-125.0f, +-62.5f,35.8538f,-128.906f, +-62.5f,36.5623f,-125.0f, +-58.5938f,37.9798f,-128.906f, +-58.5938f,38.9027f,-125.0f, +-54.6875f,39.4006f,-128.906f, +-54.6875f,40.1192f,-125.0f, +-50.7813f,40.6584f,-128.906f, +-50.7813f,41.9393f,-125.0f, +-46.875f,40.8896f,-128.906f, +-46.875f,41.8765f,-125.0f, +-42.9688f,39.9544f,-128.906f, +-42.9688f,41.6371f,-125.0f, +-39.0625f,40.0893f,-128.906f, +-39.0625f,41.6432f,-125.0f, +-35.1563f,39.3183f,-128.906f, +-35.1563f,41.2852f,-125.0f, +-31.25f,39.8575f,-128.906f, +-31.25f,41.5629f,-125.0f, +-27.3438f,41.5378f,-128.906f, +-27.3438f,42.2956f,-125.0f, +-23.4375f,44.0561f,-128.906f, +-23.4375f,43.9719f,-125.0f, +-19.5313f,45.4298f,-128.906f, +-19.5313f,46.2232f,-125.0f, +-15.625f,47.4474f,-128.906f, +-15.625f,47.3104f,-125.0f, +-11.7188f,48.0018f,-128.906f, +-11.7188f,47.5943f,-125.0f, +-7.8125f,48.0717f,-128.906f, +-7.8125f,49.1192f,-125.0f, +-3.90625f,48.7253f,-128.906f, +-3.90625f,49.6341f,-125.0f, +0.0f,49.8f,-128.906f, +0.0f,50.3481f,-125.0f, +3.90625f,50.4716f,-128.906f, +3.90625f,50.3021f,-125.0f, +-250.0f,31.1145f,-132.813f, +-246.094f,31.857f,-132.813f, +-242.188f,32.7446f,-132.813f, +-238.281f,33.1734f,-132.813f, +-234.375f,32.1952f,-132.813f, +-230.469f,31.8959f,-132.813f, +-226.563f,32.1326f,-132.813f, +-222.656f,32.1631f,-132.813f, +-218.75f,31.3795f,-132.813f, +-214.844f,30.9888f,-132.813f, +-210.938f,30.5577f,-132.813f, +-207.031f,30.1392f,-132.813f, +-203.125f,29.8482f,-132.813f, +-199.219f,28.5903f,-132.813f, +-195.313f,27.4671f,-132.813f, +-191.406f,25.5032f,-132.813f, +-187.5f,23.2799f,-132.813f, +-183.594f,21.2846f,-132.813f, +-179.688f,19.3954f,-132.813f, +-175.781f,18.1112f,-132.813f, +-171.875f,16.3831f,-132.813f, +-167.969f,14.5038f,-132.813f, +-164.063f,12.8109f,-132.813f, +-160.156f,10.386f,-132.813f, +-156.25f,7.93486f,-132.813f, +-152.344f,7.25449f,-132.813f, +-148.438f,6.19974f,-132.813f, +-144.531f,5.89578f,-132.813f, +-140.625f,6.61884f,-132.813f, +-136.719f,7.53382f,-132.813f, +-132.813f,8.21024f,-132.813f, +-128.906f,8.74115f,-132.813f, +-125.0f,8.97047f,-132.813f, +-121.094f,9.41307f,-132.813f, +-117.188f,10.0468f,-132.813f, +-113.281f,9.47404f,-132.813f, +-109.375f,9.418f,-132.813f, +-105.469f,10.3176f,-132.813f, +-101.563f,11.3001f,-132.813f, +-97.6563f,12.5318f,-132.813f, +-93.75f,14.6986f,-132.813f, +-89.8438f,16.6495f,-132.813f, +-85.9375f,19.1906f,-132.813f, +-82.0313f,23.4349f,-132.813f, +-78.125f,26.1629f,-132.813f, +-74.2188f,28.739f,-132.813f, +-70.3125f,31.1271f,-132.813f, +-66.4063f,32.2452f,-132.813f, +-62.5f,34.0303f,-132.813f, +-58.5938f,36.1234f,-132.813f, +-54.6875f,38.3054f,-132.813f, +-50.7813f,38.7936f,-132.813f, +-46.875f,39.1319f,-132.813f, +-42.9688f,39.1462f,-132.813f, +-39.0625f,38.4732f,-132.813f, +-35.1563f,38.3061f,-132.813f, +-31.25f,39.4999f,-132.813f, +-27.3438f,41.8953f,-132.813f, +-23.4375f,43.2645f,-132.813f, +-19.5313f,44.7736f,-132.813f, +-15.625f,46.2491f,-132.813f, +-11.7188f,47.4527f,-132.813f, +-7.8125f,47.1407f,-132.813f, +-3.90625f,48.0628f,-132.813f, +0.0f,48.5651f,-132.813f, +3.90625f,49.1054f,-132.813f, +-250.0f,30.7461f,-136.719f, +-246.094f,30.8483f,-136.719f, +-242.188f,32.188f,-136.719f, +-238.281f,33.149f,-136.719f, +-234.375f,32.3165f,-136.719f, +-230.469f,32.613f,-136.719f, +-226.563f,33.3246f,-136.719f, +-222.656f,32.6429f,-136.719f, +-218.75f,31.8882f,-136.719f, +-214.844f,31.5125f,-136.719f, +-210.938f,30.2065f,-136.719f, +-207.031f,30.0024f,-136.719f, +-203.125f,29.5699f,-136.719f, +-199.219f,28.1245f,-136.719f, +-195.313f,26.764f,-136.719f, +-191.406f,24.8025f,-136.719f, +-187.5f,22.7863f,-136.719f, +-183.594f,21.0979f,-136.719f, +-179.688f,19.5742f,-136.719f, +-175.781f,17.9263f,-136.719f, +-171.875f,16.0908f,-136.719f, +-167.969f,14.6542f,-136.719f, +-164.063f,12.4534f,-136.719f, +-160.156f,9.93763f,-136.719f, +-156.25f,7.87486f,-136.719f, +-152.344f,7.06627f,-136.719f, +-148.438f,6.22453f,-136.719f, +-144.531f,6.39864f,-136.719f, +-140.625f,7.02103f,-136.719f, +-136.719f,7.85488f,-136.719f, +-132.813f,9.33235f,-136.719f, +-128.906f,10.546f,-136.719f, +-125.0f,10.1958f,-136.719f, +-121.094f,9.85385f,-136.719f, +-117.188f,10.2437f,-136.719f, +-113.281f,9.95341f,-136.719f, +-109.375f,9.05387f,-136.719f, +-105.469f,10.3384f,-136.719f, +-101.563f,11.2859f,-136.719f, +-97.6563f,12.3544f,-136.719f, +-93.75f,14.0582f,-136.719f, +-89.8438f,15.9772f,-136.719f, +-85.9375f,18.8673f,-136.719f, +-82.0313f,22.2278f,-136.719f, +-78.125f,25.0468f,-136.719f, +-74.2188f,27.6452f,-136.719f, +-70.3125f,29.155f,-136.719f, +-66.4063f,30.7457f,-136.719f, +-62.5f,32.6722f,-136.719f, +-58.5938f,34.5222f,-136.719f, +-54.6875f,36.3904f,-136.719f, +-50.7813f,36.1946f,-136.719f, +-46.875f,36.5194f,-136.719f, +-42.9688f,36.2715f,-136.719f, +-39.0625f,36.4185f,-136.719f, +-35.1563f,37.1668f,-136.719f, +-31.25f,38.3933f,-136.719f, +-27.3438f,40.8416f,-136.719f, +-23.4375f,42.7243f,-136.719f, +-19.5313f,43.7567f,-136.719f, +-15.625f,44.7705f,-136.719f, +-11.7188f,45.3267f,-136.719f, +-7.8125f,46.433f,-136.719f, +-3.90625f,47.3134f,-136.719f, +0.0f,48.4146f,-136.719f, +3.90625f,47.9f,-136.719f, +-250.0f,29.1575f,-140.625f, +-246.094f,30.5173f,-140.625f, +-242.188f,31.576f,-140.625f, +-238.281f,31.6992f,-140.625f, +-234.375f,32.9063f,-140.625f, +-230.469f,33.2752f,-140.625f, +-226.563f,32.8003f,-140.625f, +-222.656f,33.133f,-140.625f, +-218.75f,32.0543f,-140.625f, +-214.844f,31.2672f,-140.625f, +-210.938f,30.2378f,-140.625f, +-207.031f,29.601f,-140.625f, +-203.125f,28.4643f,-140.625f, +-199.219f,26.8711f,-140.625f, +-195.313f,24.936f,-140.625f, +-191.406f,22.9115f,-140.625f, +-187.5f,21.8507f,-140.625f, +-183.594f,20.4435f,-140.625f, +-179.688f,18.4455f,-140.625f, +-175.781f,17.1667f,-140.625f, +-171.875f,15.2077f,-140.625f, +-167.969f,13.4799f,-140.625f, +-164.063f,11.7723f,-140.625f, +-160.156f,9.26955f,-140.625f, +-156.25f,7.56528f,-140.625f, +-152.344f,6.4244f,-140.625f, +-148.438f,6.60539f,-140.625f, +-144.531f,6.44163f,-140.625f, +-140.625f,6.55017f,-140.625f, +-136.719f,7.62805f,-140.625f, +-132.813f,9.20726f,-140.625f, +-128.906f,10.5063f,-140.625f, +-125.0f,10.6867f,-140.625f, +-121.094f,9.3702f,-140.625f, +-117.188f,9.53484f,-140.625f, +-113.281f,8.855f,-140.625f, +-109.375f,9.3082f,-140.625f, +-105.469f,9.67718f,-140.625f, +-101.563f,10.5233f,-140.625f, +-97.6563f,11.8026f,-140.625f, +-93.75f,13.1675f,-140.625f, +-89.8438f,15.253f,-140.625f, +-85.9375f,18.1074f,-140.625f, +-82.0313f,20.8004f,-140.625f, +-78.125f,23.7651f,-140.625f, +-74.2188f,25.7067f,-140.625f, +-70.3125f,27.5126f,-140.625f, +-66.4063f,29.8191f,-140.625f, +-62.5f,31.7367f,-140.625f, +-58.5938f,32.8891f,-140.625f, +-54.6875f,34.0989f,-140.625f, +-50.7813f,34.6645f,-140.625f, +-46.875f,34.0325f,-140.625f, +-42.9688f,33.7773f,-140.625f, +-39.0625f,34.1723f,-140.625f, +-35.1563f,36.0861f,-140.625f, +-31.25f,38.8562f,-140.625f, +-27.3438f,40.5684f,-140.625f, +-23.4375f,42.6832f,-140.625f, +-19.5313f,43.505f,-140.625f, +-15.625f,43.7197f,-140.625f, +-11.7188f,43.8656f,-140.625f, +-7.8125f,45.6272f,-140.625f, +-3.90625f,46.7713f,-140.625f, +0.0f,47.1255f,-140.625f, +3.90625f,47.2681f,-140.625f, +-250.0f,28.3388f,-144.531f, +-246.094f,29.5689f,-144.531f, +-242.188f,30.0422f,-144.531f, +-238.281f,30.6319f,-144.531f, +-234.375f,32.5914f,-144.531f, +-230.469f,33.306f,-144.531f, +-226.563f,32.9265f,-144.531f, +-222.656f,32.5363f,-144.531f, +-218.75f,31.8845f,-144.531f, +-214.844f,31.7429f,-144.531f, +-210.938f,29.6521f,-144.531f, +-207.031f,28.3301f,-144.531f, +-203.125f,26.8166f,-144.531f, +-199.219f,25.0756f,-144.531f, +-195.313f,23.0988f,-144.531f, +-191.406f,21.2037f,-144.531f, +-187.5f,20.271f,-144.531f, +-183.594f,18.4189f,-144.531f, +-179.688f,16.2352f,-144.531f, +-175.781f,14.734f,-144.531f, +-171.875f,13.9522f,-144.531f, +-167.969f,12.543f,-144.531f, +-164.063f,10.6335f,-144.531f, +-160.156f,8.53885f,-144.531f, +-156.25f,7.32299f,-144.531f, +-152.344f,6.69849f,-144.531f, +-148.438f,5.37792f,-144.531f, +-144.531f,5.52557f,-144.531f, +-140.625f,5.94721f,-144.531f, +-136.719f,7.15949f,-144.531f, +-132.813f,8.5533f,-144.531f, +-128.906f,9.68048f,-144.531f, +-125.0f,9.80421f,-144.531f, +-121.094f,9.67052f,-144.531f, +-117.188f,9.82889f,-144.531f, +-113.281f,9.40895f,-144.531f, +-109.375f,9.53728f,-144.531f, +-105.469f,9.89567f,-144.531f, +-101.563f,10.4472f,-144.531f, +-97.6563f,11.3813f,-144.531f, +-93.75f,13.6687f,-144.531f, +-89.8438f,15.6897f,-144.531f, +-85.9375f,17.6694f,-144.531f, +-82.0313f,20.0542f,-144.531f, +-78.125f,22.2881f,-144.531f, +-74.2188f,24.021f,-144.531f, +-70.3125f,26.6221f,-144.531f, +-66.4063f,28.7647f,-144.531f, +-62.5f,31.0025f,-144.531f, +-58.5938f,31.9212f,-144.531f, +-54.6875f,32.1124f,-144.531f, +-50.7813f,33.4656f,-144.531f, +-46.875f,33.5412f,-144.531f, +-42.9688f,33.5562f,-144.531f, +-39.0625f,34.3563f,-144.531f, +-35.1563f,36.2482f,-144.531f, +-31.25f,37.99f,-144.531f, +-27.3438f,40.3527f,-144.531f, +-23.4375f,42.4204f,-144.531f, +-19.5313f,44.0f,-144.531f, +-15.625f,44.183f,-144.531f, +-11.7188f,44.0185f,-144.531f, +-7.8125f,45.08f,-144.531f, +-3.90625f,45.5784f,-144.531f, +0.0f,44.8122f,-144.531f, +3.90625f,45.2398f,-144.531f, +-250.0f,27.5165f,-148.438f, +-246.094f,28.4707f,-148.438f, +-242.188f,28.8693f,-148.438f, +-238.281f,29.8936f,-148.438f, +-234.375f,30.9982f,-148.438f, +-230.469f,31.9158f,-148.438f, +-226.563f,33.0887f,-148.438f, +-222.656f,32.141f,-148.438f, +-218.75f,31.0388f,-148.438f, +-214.844f,30.5599f,-148.438f, +-210.938f,29.1269f,-148.438f, +-207.031f,26.6179f,-148.438f, +-203.125f,25.2859f,-148.438f, +-199.219f,23.1182f,-148.438f, +-195.313f,21.139f,-148.438f, +-191.406f,19.7044f,-148.438f, +-187.5f,18.4387f,-148.438f, +-183.594f,17.6363f,-148.438f, +-179.688f,15.8724f,-148.438f, +-175.781f,14.454f,-148.438f, +-171.875f,13.2052f,-148.438f, +-167.969f,11.7702f,-148.438f, +-164.063f,10.4965f,-148.438f, +-160.156f,8.29165f,-148.438f, +-156.25f,7.24803f,-148.438f, +-152.344f,6.79621f,-148.438f, +-148.438f,5.48372f,-148.438f, +-144.531f,4.11362f,-148.438f, +-140.625f,4.6586f,-148.438f, +-136.719f,6.20081f,-148.438f, +-132.813f,7.67687f,-148.438f, +-128.906f,9.0742f,-148.438f, +-125.0f,8.8028f,-148.438f, +-121.094f,9.309f,-148.438f, +-117.188f,9.26616f,-148.438f, +-113.281f,9.88711f,-148.438f, +-109.375f,9.19023f,-148.438f, +-105.469f,9.46828f,-148.438f, +-101.563f,10.1584f,-148.438f, +-97.6563f,11.2649f,-148.438f, +-93.75f,13.476f,-148.438f, +-89.8438f,15.8318f,-148.438f, +-85.9375f,17.6136f,-148.438f, +-82.0313f,18.7495f,-148.438f, +-78.125f,20.5385f,-148.438f, +-74.2188f,23.5666f,-148.438f, +-70.3125f,26.2836f,-148.438f, +-66.4063f,28.729f,-148.438f, +-62.5f,30.3854f,-148.438f, +-58.5938f,30.9909f,-148.438f, +-54.6875f,31.4288f,-148.438f, +-50.7813f,31.916f,-148.438f, +-46.875f,32.4745f,-148.438f, +-42.9688f,32.0881f,-148.438f, +-39.0625f,34.0231f,-148.438f, +-35.1563f,35.6432f,-148.438f, +-31.25f,37.6278f,-148.438f, +-27.3438f,39.652f,-148.438f, +-23.4375f,42.3336f,-148.438f, +-19.5313f,43.3336f,-148.438f, +-15.625f,43.9329f,-148.438f, +-11.7188f,43.8742f,-148.438f, +-7.8125f,44.336f,-148.438f, +-3.90625f,44.2738f,-148.438f, +0.0f,42.6429f,-148.438f, +3.90625f,43.4167f,-148.438f, +-250.0f,27.7654f,-152.344f, +-246.094f,28.2588f,-152.344f, +-242.188f,28.0365f,-152.344f, +-238.281f,29.4531f,-152.344f, +-234.375f,31.8507f,-152.344f, +-230.469f,31.9987f,-152.344f, +-226.563f,32.2635f,-152.344f, +-222.656f,32.4573f,-152.344f, +-218.75f,30.3791f,-152.344f, +-214.844f,29.1133f,-152.344f, +-210.938f,27.6466f,-152.344f, +-207.031f,25.5524f,-152.344f, +-203.125f,23.857f,-152.344f, +-199.219f,21.724f,-152.344f, +-195.313f,19.9592f,-152.344f, +-191.406f,18.6648f,-152.344f, +-187.5f,17.3913f,-152.344f, +-183.594f,17.3113f,-152.344f, +-179.688f,15.8776f,-152.344f, +-175.781f,13.7968f,-152.344f, +-171.875f,11.9961f,-152.344f, +-167.969f,10.9315f,-152.344f, +-164.063f,9.24337f,-152.344f, +-160.156f,7.95749f,-152.344f, +-156.25f,6.95525f,-152.344f, +-152.344f,6.523f,-152.344f, +-148.438f,5.62313f,-152.344f, +-144.531f,4.31939f,-152.344f, +-140.625f,3.1203f,-152.344f, +-136.719f,4.98713f,-152.344f, +-132.813f,6.64544f,-152.344f, +-128.906f,7.48658f,-152.344f, +-125.0f,8.08424f,-152.344f, +-121.094f,8.96562f,-152.344f, +-117.188f,9.10159f,-152.344f, +-113.281f,9.38004f,-152.344f, +-109.375f,8.97581f,-152.344f, +-105.469f,8.78511f,-152.344f, +-101.563f,9.76846f,-152.344f, +-97.6563f,10.4299f,-152.344f, +-93.75f,13.6059f,-152.344f, +-89.8438f,16.3193f,-152.344f, +-85.9375f,17.6959f,-152.344f, +-82.0313f,18.5545f,-152.344f, +-78.125f,20.1179f,-152.344f, +-74.2188f,22.929f,-152.344f, +-70.3125f,25.8413f,-152.344f, +-66.4063f,28.4214f,-152.344f, +-62.5f,30.0187f,-152.344f, +-58.5938f,30.4285f,-152.344f, +-54.6875f,30.9236f,-152.344f, +-50.7813f,31.3519f,-152.344f, +-46.875f,31.0939f,-152.344f, +-42.9688f,30.2517f,-152.344f, +-39.0625f,32.8953f,-152.344f, +-35.1563f,34.6998f,-152.344f, +-31.25f,36.8107f,-152.344f, +-27.3438f,38.8491f,-152.344f, +-23.4375f,41.3749f,-152.344f, +-19.5313f,42.0838f,-152.344f, +-15.625f,42.3106f,-152.344f, +-11.7188f,43.9654f,-152.344f, +-7.8125f,44.3642f,-152.344f, +-3.90625f,43.1787f,-152.344f, +0.0f,41.875f,-152.344f, +3.90625f,42.7212f,-152.344f, +-250.0f,27.3076f,-156.25f, +-246.094f,27.8739f,-156.25f, +-242.188f,27.7337f,-156.25f, +-238.281f,28.4499f,-156.25f, +-234.375f,30.5068f,-156.25f, +-230.469f,31.1326f,-156.25f, +-226.563f,32.3149f,-156.25f, +-222.656f,31.2724f,-156.25f, +-218.75f,29.5487f,-156.25f, +-214.844f,26.8408f,-156.25f, +-210.938f,25.2503f,-156.25f, +-207.031f,24.2811f,-156.25f, +-203.125f,23.8635f,-156.25f, +-199.219f,22.2573f,-156.25f, +-195.313f,20.6368f,-156.25f, +-191.406f,19.4922f,-156.25f, +-187.5f,18.0281f,-156.25f, +-183.594f,15.4098f,-156.25f, +-179.688f,13.9176f,-156.25f, +-175.781f,11.8192f,-156.25f, +-171.875f,9.31112f,-156.25f, +-167.969f,8.81167f,-156.25f, +-164.063f,8.04908f,-156.25f, +-160.156f,6.4764f,-156.25f, +-156.25f,5.83656f,-156.25f, +-152.344f,5.70173f,-156.25f, +-148.438f,6.05686f,-156.25f, +-144.531f,3.98364f,-156.25f, +-140.625f,2.80636f,-156.25f, +-136.719f,3.53326f,-156.25f, +-132.813f,4.97177f,-156.25f, +-128.906f,6.71319f,-156.25f, +-125.0f,8.26478f,-156.25f, +-121.094f,9.00909f,-156.25f, +-117.188f,8.8849f,-156.25f, +-113.281f,9.50654f,-156.25f, +-109.375f,9.16878f,-156.25f, +-105.469f,8.84796f,-156.25f, +-101.563f,9.78015f,-156.25f, +-97.6563f,11.1536f,-156.25f, +-93.75f,13.416f,-156.25f, +-89.8438f,15.8674f,-156.25f, +-85.9375f,17.2814f,-156.25f, +-82.0313f,18.1958f,-156.25f, +-78.125f,19.5037f,-156.25f, +-74.2188f,22.0147f,-156.25f, +-70.3125f,24.3288f,-156.25f, +-66.4063f,26.5193f,-156.25f, +-62.5f,27.9571f,-156.25f, +-58.5938f,28.8524f,-156.25f, +-54.6875f,30.6249f,-156.25f, +-50.7813f,30.9824f,-156.25f, +-46.875f,31.0372f,-156.25f, +-42.9688f,30.2189f,-156.25f, +-39.0625f,32.0632f,-156.25f, +-35.1563f,34.0061f,-156.25f, +-31.25f,35.3975f,-156.25f, +-27.3438f,37.8006f,-156.25f, +-23.4375f,40.1384f,-156.25f, +-19.5313f,40.5455f,-156.25f, +-15.625f,41.6044f,-156.25f, +-11.7188f,43.1078f,-156.25f, +-7.8125f,43.5927f,-156.25f, +-3.90625f,43.0245f,-156.25f, +0.0f,41.3824f,-156.25f, +3.90625f,41.7368f,-156.25f, +-250.0f,27.1128f,-160.156f, +-246.094f,26.9845f,-160.156f, +-242.188f,26.7433f,-160.156f, +-238.281f,27.3777f,-160.156f, +-234.375f,29.1743f,-160.156f, +-230.469f,31.0712f,-160.156f, +-226.563f,31.3707f,-160.156f, +-222.656f,30.2327f,-160.156f, +-218.75f,27.897f,-160.156f, +-214.844f,26.4218f,-160.156f, +-210.938f,24.0007f,-160.156f, +-207.031f,23.6445f,-160.156f, +-203.125f,23.6467f,-160.156f, +-199.219f,22.8576f,-160.156f, +-195.313f,20.6778f,-160.156f, +-191.406f,19.3331f,-160.156f, +-187.5f,17.8893f,-160.156f, +-183.594f,14.3376f,-160.156f, +-179.688f,11.9084f,-160.156f, +-175.781f,9.60285f,-160.156f, +-171.875f,7.78231f,-160.156f, +-167.969f,8.15369f,-160.156f, +-164.063f,7.46984f,-160.156f, +-160.156f,6.48522f,-160.156f, +-156.25f,5.27847f,-160.156f, +-152.344f,4.69473f,-160.156f, +-148.438f,5.14018f,-160.156f, +-144.531f,3.26777f,-160.156f, +-140.625f,3.33507f,-160.156f, +-136.719f,2.47156f,-160.156f, +-132.813f,4.15824f,-160.156f, +-128.906f,6.45432f,-160.156f, +-125.0f,7.99373f,-160.156f, +-121.094f,8.38925f,-160.156f, +-117.188f,8.59802f,-160.156f, +-113.281f,9.4891f,-160.156f, +-109.375f,9.20323f,-160.156f, +-105.469f,8.27038f,-160.156f, +-101.563f,9.71848f,-160.156f, +-97.6563f,11.8577f,-160.156f, +-93.75f,14.596f,-160.156f, +-89.8438f,16.1058f,-160.156f, +-85.9375f,17.6531f,-160.156f, +-82.0313f,18.2123f,-160.156f, +-78.125f,18.7175f,-160.156f, +-74.2188f,20.7283f,-160.156f, +-70.3125f,23.5217f,-160.156f, +-66.4063f,26.4239f,-160.156f, +-62.5f,27.757f,-160.156f, +-58.5938f,28.1862f,-160.156f, +-54.6875f,28.9075f,-160.156f, +-50.7813f,29.5287f,-160.156f, +-46.875f,29.3972f,-160.156f, +-42.9688f,29.568f,-160.156f, +-39.0625f,30.605f,-160.156f, +-35.1563f,33.0369f,-160.156f, +-31.25f,34.749f,-160.156f, +-27.3438f,37.4864f,-160.156f, +-23.4375f,39.2291f,-160.156f, +-19.5313f,39.6275f,-160.156f, +-15.625f,39.865f,-160.156f, +-11.7188f,41.1833f,-160.156f, +-7.8125f,41.7789f,-160.156f, +-3.90625f,41.6972f,-160.156f, +0.0f,40.379f,-160.156f, +3.90625f,40.4755f,-160.156f, +-250.0f,26.3982f,-164.063f, +-246.094f,26.3606f,-164.063f, +-242.188f,26.6508f,-164.063f, +-238.281f,27.2228f,-164.063f, +-234.375f,29.1682f,-164.063f, +-230.469f,30.116f,-164.063f, +-226.563f,30.3591f,-164.063f, +-222.656f,28.8713f,-164.063f, +-218.75f,26.8459f,-164.063f, +-214.844f,24.9771f,-164.063f, +-210.938f,24.4581f,-164.063f, +-207.031f,23.6584f,-164.063f, +-203.125f,22.7316f,-164.063f, +-199.219f,21.1836f,-164.063f, +-195.313f,19.6131f,-164.063f, +-191.406f,18.5182f,-164.063f, +-187.5f,16.824f,-164.063f, +-183.594f,13.8772f,-164.063f, +-179.688f,10.3923f,-164.063f, +-175.781f,7.50643f,-164.063f, +-171.875f,6.58466f,-164.063f, +-167.969f,6.81413f,-164.063f, +-164.063f,6.88249f,-164.063f, +-160.156f,6.78655f,-164.063f, +-156.25f,5.18348f,-164.063f, +-152.344f,4.44173f,-164.063f, +-148.438f,4.56392f,-164.063f, +-144.531f,3.00722f,-164.063f, +-140.625f,2.88808f,-164.063f, +-136.719f,2.58477f,-164.063f, +-132.813f,3.20911f,-164.063f, +-128.906f,5.33043f,-164.063f, +-125.0f,6.73698f,-164.063f, +-121.094f,7.71971f,-164.063f, +-117.188f,8.44689f,-164.063f, +-113.281f,9.05366f,-164.063f, +-109.375f,8.81111f,-164.063f, +-105.469f,7.75706f,-164.063f, +-101.563f,11.1131f,-164.063f, +-97.6563f,12.8283f,-164.063f, +-93.75f,14.7771f,-164.063f, +-89.8438f,16.181f,-164.063f, +-85.9375f,17.4228f,-164.063f, +-82.0313f,18.5185f,-164.063f, +-78.125f,19.3122f,-164.063f, +-74.2188f,20.1572f,-164.063f, +-70.3125f,22.741f,-164.063f, +-66.4063f,24.5911f,-164.063f, +-62.5f,26.3846f,-164.063f, +-58.5938f,26.7315f,-164.063f, +-54.6875f,27.0842f,-164.063f, +-50.7813f,28.7654f,-164.063f, +-46.875f,28.7233f,-164.063f, +-42.9688f,29.2872f,-164.063f, +-39.0625f,29.4838f,-164.063f, +-35.1563f,32.7848f,-164.063f, +-31.25f,34.771f,-164.063f, +-27.3438f,36.568f,-164.063f, +-23.4375f,37.5518f,-164.063f, +-19.5313f,38.4106f,-164.063f, +-15.625f,39.2979f,-164.063f, +-11.7188f,39.3573f,-164.063f, +-7.8125f,40.0034f,-164.063f, +-3.90625f,39.5971f,-164.063f, +0.0f,38.8676f,-164.063f, +3.90625f,38.8633f,-164.063f, +-250.0f,25.2893f,-167.969f, +-246.094f,25.108f,-167.969f, +-242.188f,25.5028f,-167.969f, +-238.281f,26.6095f,-167.969f, +-234.375f,28.3221f,-167.969f, +-230.469f,28.5453f,-167.969f, +-226.563f,28.2595f,-167.969f, +-222.656f,26.8423f,-167.969f, +-218.75f,25.0092f,-167.969f, +-214.844f,24.2925f,-167.969f, +-210.938f,23.8404f,-167.969f, +-207.031f,22.7515f,-167.969f, +-203.125f,22.5332f,-167.969f, +-199.219f,20.3284f,-167.969f, +-195.313f,18.8238f,-167.969f, +-191.406f,17.0096f,-167.969f, +-187.5f,14.7741f,-167.969f, +-183.594f,12.4233f,-167.969f, +-179.688f,9.35872f,-167.969f, +-175.781f,6.39156f,-167.969f, +-171.875f,4.97533f,-167.969f, +-167.969f,4.85484f,-167.969f, +-164.063f,5.54727f,-167.969f, +-160.156f,5.08595f,-167.969f, +-156.25f,3.82379f,-167.969f, +-152.344f,3.95751f,-167.969f, +-148.438f,4.60866f,-167.969f, +-144.531f,3.48771f,-167.969f, +-140.625f,3.26748f,-167.969f, +-136.719f,1.87672f,-167.969f, +-132.813f,2.70232f,-167.969f, +-128.906f,4.51339f,-167.969f, +-125.0f,6.0309f,-167.969f, +-121.094f,7.41076f,-167.969f, +-117.188f,7.44121f,-167.969f, +-113.281f,7.50774f,-167.969f, +-109.375f,6.89121f,-167.969f, +-105.469f,8.13035f,-167.969f, +-101.563f,11.7503f,-167.969f, +-97.6563f,14.1358f,-167.969f, +-93.75f,15.4553f,-167.969f, +-89.8438f,16.6233f,-167.969f, +-85.9375f,16.9002f,-167.969f, +-82.0313f,18.4951f,-167.969f, +-78.125f,19.0947f,-167.969f, +-74.2188f,20.0506f,-167.969f, +-70.3125f,20.9426f,-167.969f, +-66.4063f,22.9738f,-167.969f, +-62.5f,24.6229f,-167.969f, +-58.5938f,26.446f,-167.969f, +-54.6875f,26.6448f,-167.969f, +-50.7813f,26.7349f,-167.969f, +-46.875f,28.1266f,-167.969f, +-42.9688f,29.6034f,-167.969f, +-39.0625f,30.3572f,-167.969f, +-35.1563f,31.5467f,-167.969f, +-31.25f,33.6878f,-167.969f, +-27.3438f,35.587f,-167.969f, +-23.4375f,36.0939f,-167.969f, +-19.5313f,37.5008f,-167.969f, +-15.625f,38.2137f,-167.969f, +-11.7188f,38.0843f,-167.969f, +-7.8125f,38.5726f,-167.969f, +-3.90625f,38.3565f,-167.969f, +0.0f,37.8848f,-167.969f, +3.90625f,37.2199f,-167.969f, +-250.0f,24.1398f,-171.875f, +-246.094f,23.8227f,-171.875f, +-242.188f,24.7818f,-171.875f, +-238.281f,26.1053f,-171.875f, +-234.375f,26.9542f,-171.875f, +-230.469f,26.4956f,-171.875f, +-226.563f,25.4866f,-171.875f, +-222.656f,24.7397f,-171.875f, +-218.75f,23.4337f,-171.875f, +-214.844f,23.2342f,-171.875f, +-210.938f,22.1055f,-171.875f, +-207.031f,20.7279f,-171.875f, +-203.125f,20.7273f,-171.875f, +-199.219f,19.1302f,-171.875f, +-195.313f,16.3679f,-171.875f, +-191.406f,14.4548f,-171.875f, +-187.5f,12.5085f,-171.875f, +-183.594f,10.0081f,-171.875f, +-179.688f,7.8572f,-171.875f, +-175.781f,4.38151f,-171.875f, +-171.875f,3.2342f,-171.875f, +-167.969f,3.37553f,-171.875f, +-164.063f,3.90509f,-171.875f, +-160.156f,3.26335f,-171.875f, +-156.25f,2.88438f,-171.875f, +-152.344f,4.22045f,-171.875f, +-148.438f,3.83297f,-171.875f, +-144.531f,2.98648f,-171.875f, +-140.625f,2.83916f,-171.875f, +-136.719f,1.97368f,-171.875f, +-132.813f,1.85909f,-171.875f, +-128.906f,3.2051f,-171.875f, +-125.0f,5.12684f,-171.875f, +-121.094f,5.86909f,-171.875f, +-117.188f,6.45429f,-171.875f, +-113.281f,6.28889f,-171.875f, +-109.375f,7.53536f,-171.875f, +-105.469f,9.44844f,-171.875f, +-101.563f,11.4162f,-171.875f, +-97.6563f,13.7412f,-171.875f, +-93.75f,14.8315f,-171.875f, +-89.8438f,15.4968f,-171.875f, +-85.9375f,16.3468f,-171.875f, +-82.0313f,18.2605f,-171.875f, +-78.125f,18.0829f,-171.875f, +-74.2188f,18.1489f,-171.875f, +-70.3125f,20.6678f,-171.875f, +-66.4063f,23.1234f,-171.875f, +-62.5f,24.4247f,-171.875f, +-58.5938f,26.5223f,-171.875f, +-54.6875f,26.4286f,-171.875f, +-50.7813f,26.7163f,-171.875f, +-46.875f,28.0436f,-171.875f, +-42.9688f,29.6821f,-171.875f, +-39.0625f,30.721f,-171.875f, +-35.1563f,31.1869f,-171.875f, +-31.25f,32.2507f,-171.875f, +-27.3438f,33.3898f,-171.875f, +-23.4375f,33.9008f,-171.875f, +-19.5313f,34.8028f,-171.875f, +-15.625f,35.7178f,-171.875f, +-11.7188f,35.7796f,-171.875f, +-7.8125f,35.6384f,-171.875f, +-3.90625f,35.5122f,-171.875f, +0.0f,35.5973f,-171.875f, +3.90625f,35.3898f,-171.875f, +-250.0f,23.4472f,-175.781f, +-246.094f,24.0295f,-175.781f, +-242.188f,25.0451f,-175.781f, +-238.281f,25.8985f,-175.781f, +-234.375f,26.561f,-175.781f, +-230.469f,25.8342f,-175.781f, +-226.563f,24.8466f,-175.781f, +-222.656f,24.9204f,-175.781f, +-218.75f,23.1933f,-175.781f, +-214.844f,22.3916f,-175.781f, +-210.938f,20.9595f,-175.781f, +-207.031f,19.4013f,-175.781f, +-203.125f,18.3359f,-175.781f, +-199.219f,16.2135f,-175.781f, +-195.313f,14.3022f,-175.781f, +-191.406f,12.4792f,-175.781f, +-187.5f,10.1621f,-175.781f, +-183.594f,7.8368f,-175.781f, +-179.688f,5.59407f,-175.781f, +-175.781f,3.47332f,-175.781f, +-171.875f,2.4167f,-175.781f, +-167.969f,2.13794f,-175.781f, +-164.063f,2.36632f,-175.781f, +-160.156f,2.44955f,-175.781f, +-156.25f,2.40042f,-175.781f, +-152.344f,3.0142f,-175.781f, +-148.438f,2.58304f,-175.781f, +-144.531f,3.06221f,-175.781f, +-140.625f,2.8937f,-175.781f, +-136.719f,2.59115f,-175.781f, +-132.813f,2.27806f,-175.781f, +-128.906f,3.67695f,-175.781f, +-125.0f,5.23254f,-175.781f, +-121.094f,6.12339f,-175.781f, +-117.188f,6.24689f,-175.781f, +-113.281f,6.79282f,-175.781f, +-109.375f,7.83542f,-175.781f, +-105.469f,9.33972f,-175.781f, +-101.563f,11.2701f,-175.781f, +-97.6563f,13.0689f,-175.781f, +-93.75f,13.927f,-175.781f, +-89.8438f,14.9788f,-175.781f, +-85.9375f,15.6647f,-175.781f, +-82.0313f,16.3833f,-175.781f, +-78.125f,16.1061f,-175.781f, +-74.2188f,17.7393f,-175.781f, +-70.3125f,19.8808f,-175.781f, +-66.4063f,22.2751f,-175.781f, +-62.5f,23.8491f,-175.781f, +-58.5938f,25.3344f,-175.781f, +-54.6875f,26.6818f,-175.781f, +-50.7813f,27.9151f,-175.781f, +-46.875f,28.5054f,-175.781f, +-42.9688f,29.7057f,-175.781f, +-39.0625f,30.623f,-175.781f, +-35.1563f,31.5341f,-175.781f, +-31.25f,31.663f,-175.781f, +-27.3438f,31.1886f,-175.781f, +-23.4375f,31.5377f,-175.781f, +-19.5313f,31.9508f,-175.781f, +-15.625f,32.9549f,-175.781f, +-11.7188f,33.7731f,-175.781f, +-7.8125f,33.8023f,-175.781f, +-3.90625f,34.5283f,-175.781f, +0.0f,34.7929f,-175.781f, +3.90625f,34.823f,-175.781f, +-250.0f,22.2698f,-179.688f, +-246.094f,23.7669f,-179.688f, +-242.188f,24.59f,-179.688f, +-238.281f,26.1637f,-179.688f, +-234.375f,25.5266f,-179.688f, +-230.469f,24.4911f,-179.688f, +-226.563f,24.894f,-179.688f, +-222.656f,23.7469f,-179.688f, +-218.75f,22.9663f,-179.688f, +-214.844f,20.6574f,-179.688f, +-210.938f,19.2502f,-179.688f, +-207.031f,17.3967f,-179.688f, +-203.125f,15.9684f,-179.688f, +-199.219f,13.2948f,-179.688f, +-195.313f,11.9318f,-179.688f, +-191.406f,9.64213f,-179.688f, +-187.5f,7.9435f,-179.688f, +-183.594f,6.1917f,-179.688f, +-179.688f,4.0394f,-179.688f, +-175.781f,1.9267f,-179.688f, +-171.875f,1.73477f,-179.688f, +-167.969f,0.994442f,-179.688f, +-164.063f,0.99617f,-179.688f, +-160.156f,1.00048f,-179.688f, +-156.25f,1.54446f,-179.688f, +-152.344f,0.849521f,-179.688f, +-148.438f,1.3046f,-179.688f, +-144.531f,1.38519f,-179.688f, +-140.625f,0.916628f,-179.688f, +-136.719f,1.39685f,-179.688f, +-132.813f,2.17945f,-179.688f, +-128.906f,4.01973f,-179.688f, +-125.0f,5.72989f,-179.688f, +-121.094f,7.24268f,-179.688f, +-117.188f,7.06199f,-179.688f, +-113.281f,7.91292f,-179.688f, +-109.375f,7.8138f,-179.688f, +-105.469f,10.102f,-179.688f, +-101.563f,11.8106f,-179.688f, +-97.6563f,12.9642f,-179.688f, +-93.75f,13.5879f,-179.688f, +-89.8438f,13.4552f,-179.688f, +-85.9375f,14.1844f,-179.688f, +-82.0313f,14.3802f,-179.688f, +-78.125f,15.3847f,-179.688f, +-74.2188f,17.2288f,-179.688f, +-70.3125f,18.9285f,-179.688f, +-66.4063f,20.0035f,-179.688f, +-62.5f,22.2672f,-179.688f, +-58.5938f,25.1262f,-179.688f, +-54.6875f,27.2745f,-179.688f, +-50.7813f,28.2648f,-179.688f, +-46.875f,29.3825f,-179.688f, +-42.9688f,30.2137f,-179.688f, +-39.0625f,31.3826f,-179.688f, +-35.1563f,31.25f,-179.688f, +-31.25f,31.0392f,-179.688f, +-27.3438f,30.3369f,-179.688f, +-23.4375f,30.5503f,-179.688f, +-19.5313f,30.9715f,-179.688f, +-15.625f,31.8287f,-179.688f, +-11.7188f,32.1393f,-179.688f, +-7.8125f,32.0725f,-179.688f, +-3.90625f,32.6574f,-179.688f, +0.0f,32.8889f,-179.688f, +3.90625f,32.9461f,-179.688f, +-250.0f,22.3874f,-183.594f, +-246.094f,22.8072f,-183.594f, +-242.188f,23.1353f,-183.594f, +-238.281f,24.0949f,-183.594f, +-234.375f,24.0026f,-183.594f, +-230.469f,23.458f,-183.594f, +-226.563f,23.872f,-183.594f, +-222.656f,22.969f,-183.594f, +-218.75f,21.8375f,-183.594f, +-214.844f,19.9316f,-183.594f, +-210.938f,16.812f,-183.594f, +-207.031f,15.1789f,-183.594f, +-203.125f,13.7876f,-183.594f, +-199.219f,11.6818f,-183.594f, +-195.313f,9.75291f,-183.594f, +-191.406f,7.08878f,-183.594f, +-187.5f,6.43001f,-183.594f, +-183.594f,5.15238f,-183.594f, +-179.688f,3.77653f,-183.594f, +-175.781f,3.01737f,-183.594f, +-171.875f,1.46355f,-183.594f, +-167.969f,0.767798f,-183.594f, +-164.063f,1.98474f,-183.594f, +-160.156f,1.09473f,-183.594f, +-156.25f,1.29857f,-183.594f, +-152.344f,-0.203491f,-183.594f, +-148.438f,-0.506199f,-183.594f, +-144.531f,-0.678603f,-183.594f, +-140.625f,0.165814f,-183.594f, +-136.719f,1.44759f,-183.594f, +-132.813f,1.43337f,-183.594f, +-128.906f,3.23614f,-183.594f, +-125.0f,4.8541f,-183.594f, +-121.094f,6.64038f,-183.594f, +-117.188f,7.96432f,-183.594f, +-113.281f,8.52594f,-183.594f, +-109.375f,7.78399f,-183.594f, +-105.469f,9.45422f,-183.594f, +-101.563f,11.3198f,-183.594f, +-97.6563f,12.2369f,-183.594f, +-93.75f,12.7733f,-183.594f, +-89.8438f,12.9184f,-183.594f, +-85.9375f,12.958f,-183.594f, +-82.0313f,13.3326f,-183.594f, +-78.125f,14.3984f,-183.594f, +-74.2188f,16.2737f,-183.594f, +-70.3125f,17.9981f,-183.594f, +-66.4063f,19.5314f,-183.594f, +-62.5f,21.4039f,-183.594f, +-58.5938f,24.8945f,-183.594f, +-54.6875f,26.9904f,-183.594f, +-50.7813f,28.6222f,-183.594f, +-46.875f,30.2128f,-183.594f, +-42.9688f,30.5142f,-183.594f, +-39.0625f,30.7026f,-183.594f, +-35.1563f,30.6413f,-183.594f, +-31.25f,29.7659f,-183.594f, +-27.3438f,30.2613f,-183.594f, +-23.4375f,31.0694f,-183.594f, +-19.5313f,31.0437f,-183.594f, +-15.625f,30.9824f,-183.594f, +-11.7188f,30.4648f,-183.594f, +-7.8125f,30.0916f,-183.594f, +-3.90625f,30.0801f,-183.594f, +0.0f,29.9992f,-183.594f, +3.90625f,30.0027f,-183.594f, +-250.0f,22.2829f,-187.5f, +-246.094f,23.1567f,-187.5f, +-242.188f,23.2229f,-187.5f, +-238.281f,23.6644f,-187.5f, +-234.375f,23.5148f,-187.5f, +-230.469f,22.8756f,-187.5f, +-226.563f,22.2471f,-187.5f, +-222.656f,21.4292f,-187.5f, +-218.75f,20.4108f,-187.5f, +-214.844f,18.2601f,-187.5f, +-210.938f,16.3575f,-187.5f, +-207.031f,13.0762f,-187.5f, +-203.125f,11.5916f,-187.5f, +-199.219f,9.81885f,-187.5f, +-195.313f,8.57193f,-187.5f, +-191.406f,5.93865f,-187.5f, +-187.5f,5.15801f,-187.5f, +-183.594f,3.89597f,-187.5f, +-179.688f,4.52236f,-187.5f, +-175.781f,4.21162f,-187.5f, +-171.875f,2.62521f,-187.5f, +-167.969f,1.85733f,-187.5f, +-164.063f,2.14119f,-187.5f, +-160.156f,2.60992f,-187.5f, +-156.25f,1.99742f,-187.5f, +-152.344f,0.836315f,-187.5f, +-148.438f,-0.122141f,-187.5f, +-144.531f,-1.21041f,-187.5f, +-140.625f,0.620409f,-187.5f, +-136.719f,2.20372f,-187.5f, +-132.813f,2.55457f,-187.5f, +-128.906f,3.09944f,-187.5f, +-125.0f,4.76219f,-187.5f, +-121.094f,6.5939f,-187.5f, +-117.188f,7.40657f,-187.5f, +-113.281f,8.17096f,-187.5f, +-109.375f,8.8965f,-187.5f, +-105.469f,9.54116f,-187.5f, +-101.563f,10.8183f,-187.5f, +-97.6563f,12.2345f,-187.5f, +-93.75f,11.945f,-187.5f, +-89.8438f,12.3063f,-187.5f, +-85.9375f,12.7736f,-187.5f, +-82.0313f,13.2581f,-187.5f, +-78.125f,14.2241f,-187.5f, +-74.2188f,15.1957f,-187.5f, +-70.3125f,17.7241f,-187.5f, +-66.4063f,21.0931f,-187.5f, +-62.5f,23.7741f,-187.5f, +-58.5938f,24.8775f,-187.5f, +-54.6875f,26.5924f,-187.5f, +-50.7813f,28.0699f,-187.5f, +-46.875f,30.1552f,-187.5f, +-42.9688f,30.8508f,-187.5f, +-39.0625f,30.7935f,-187.5f, +-35.1563f,30.3224f,-187.5f, +-31.25f,28.8455f,-187.5f, +-27.3438f,30.2059f,-187.5f, +-23.4375f,31.5456f,-187.5f, +-19.5313f,31.0657f,-187.5f, +-15.625f,30.5686f,-187.5f, +-11.7188f,29.9754f,-187.5f, +-7.8125f,28.7754f,-187.5f, +-3.90625f,28.2457f,-187.5f, +0.0f,27.4045f,-187.5f, +3.90625f,27.6405f,-187.5f, +-250.0f,21.5096f,-191.406f, +-246.094f,22.1931f,-191.406f, +-242.188f,22.416f,-191.406f, +-238.281f,22.619f,-191.406f, +-234.375f,22.9242f,-191.406f, +-230.469f,22.6042f,-191.406f, +-226.563f,21.5344f,-191.406f, +-222.656f,20.226f,-191.406f, +-218.75f,19.6198f,-191.406f, +-214.844f,18.0849f,-191.406f, +-210.938f,15.9896f,-191.406f, +-207.031f,12.7402f,-191.406f, +-203.125f,9.98899f,-191.406f, +-199.219f,7.38602f,-191.406f, +-195.313f,6.23078f,-191.406f, +-191.406f,4.8714f,-191.406f, +-187.5f,4.87792f,-191.406f, +-183.594f,4.53381f,-191.406f, +-179.688f,5.23517f,-191.406f, +-175.781f,4.22349f,-191.406f, +-171.875f,3.46214f,-191.406f, +-167.969f,3.62202f,-191.406f, +-164.063f,3.07142f,-191.406f, +-160.156f,3.69893f,-191.406f, +-156.25f,4.20827f,-191.406f, +-152.344f,2.23654f,-191.406f, +-148.438f,0.582121f,-191.406f, +-144.531f,0.44941f,-191.406f, +-140.625f,2.42446f,-191.406f, +-136.719f,3.54807f,-191.406f, +-132.813f,3.58143f,-191.406f, +-128.906f,4.42162f,-191.406f, +-125.0f,5.24153f,-191.406f, +-121.094f,6.55792f,-191.406f, +-117.188f,6.93471f,-191.406f, +-113.281f,7.73309f,-191.406f, +-109.375f,8.04468f,-191.406f, +-105.469f,9.15528f,-191.406f, +-101.563f,10.9583f,-191.406f, +-97.6563f,12.1897f,-191.406f, +-93.75f,11.6481f,-191.406f, +-89.8438f,11.6514f,-191.406f, +-85.9375f,12.4326f,-191.406f, +-82.0313f,13.3808f,-191.406f, +-78.125f,14.386f,-191.406f, +-74.2188f,16.182f,-191.406f, +-70.3125f,18.9931f,-191.406f, +-66.4063f,22.8308f,-191.406f, +-62.5f,25.3868f,-191.406f, +-58.5938f,26.1484f,-191.406f, +-54.6875f,25.6258f,-191.406f, +-50.7813f,26.9464f,-191.406f, +-46.875f,29.0075f,-191.406f, +-42.9688f,29.8523f,-191.406f, +-39.0625f,30.1236f,-191.406f, +-35.1563f,29.7557f,-191.406f, +-31.25f,28.4913f,-191.406f, +-27.3438f,29.5389f,-191.406f, +-23.4375f,30.4685f,-191.406f, +-19.5313f,30.3743f,-191.406f, +-15.625f,30.3762f,-191.406f, +-11.7188f,29.0099f,-191.406f, +-7.8125f,28.1952f,-191.406f, +-3.90625f,26.135f,-191.406f, +0.0f,25.2418f,-191.406f, +3.90625f,25.3652f,-191.406f, +-250.0f,20.78f,-195.313f, +-246.094f,20.8279f,-195.313f, +-242.188f,21.2199f,-195.313f, +-238.281f,22.0652f,-195.313f, +-234.375f,22.2095f,-195.313f, +-230.469f,22.1372f,-195.313f, +-226.563f,21.0165f,-195.313f, +-222.656f,19.4174f,-195.313f, +-218.75f,17.7927f,-195.313f, +-214.844f,16.6172f,-195.313f, +-210.938f,14.7065f,-195.313f, +-207.031f,11.8095f,-195.313f, +-203.125f,9.63824f,-195.313f, +-199.219f,6.4991f,-195.313f, +-195.313f,6.23707f,-195.313f, +-191.406f,6.60374f,-195.313f, +-187.5f,6.22557f,-195.313f, +-183.594f,5.47951f,-195.313f, +-179.688f,5.16851f,-195.313f, +-175.781f,4.83538f,-195.313f, +-171.875f,4.16992f,-195.313f, +-167.969f,5.40533f,-195.313f, +-164.063f,5.01562f,-195.313f, +-160.156f,4.58978f,-195.313f, +-156.25f,4.73252f,-195.313f, +-152.344f,3.14586f,-195.313f, +-148.438f,1.16894f,-195.313f, +-144.531f,2.4916f,-195.313f, +-140.625f,3.98933f,-195.313f, +-136.719f,5.16861f,-195.313f, +-132.813f,5.68931f,-195.313f, +-128.906f,5.45815f,-195.313f, +-125.0f,5.15506f,-195.313f, +-121.094f,6.46153f,-195.313f, +-117.188f,7.36577f,-195.313f, +-113.281f,8.13491f,-195.313f, +-109.375f,7.50896f,-195.313f, +-105.469f,8.93662f,-195.313f, +-101.563f,10.6513f,-195.313f, +-97.6563f,10.6255f,-195.313f, +-93.75f,10.5332f,-195.313f, +-89.8438f,11.5758f,-195.313f, +-85.9375f,11.568f,-195.313f, +-82.0313f,14.2419f,-195.313f, +-78.125f,16.1272f,-195.313f, +-74.2188f,17.0994f,-195.313f, +-70.3125f,20.4651f,-195.313f, +-66.4063f,23.534f,-195.313f, +-62.5f,25.1181f,-195.313f, +-58.5938f,25.9427f,-195.313f, +-54.6875f,25.5166f,-195.313f, +-50.7813f,25.1027f,-195.313f, +-46.875f,27.2281f,-195.313f, +-42.9688f,28.7319f,-195.313f, +-39.0625f,28.8984f,-195.313f, +-35.1563f,28.3307f,-195.313f, +-31.25f,27.4754f,-195.313f, +-27.3438f,27.8763f,-195.313f, +-23.4375f,28.1023f,-195.313f, +-19.5313f,28.9815f,-195.313f, +-15.625f,28.5849f,-195.313f, +-11.7188f,27.2687f,-195.313f, +-7.8125f,26.8112f,-195.313f, +-3.90625f,25.3636f,-195.313f, +0.0f,23.2134f,-195.313f, +3.90625f,23.0993f,-195.313f, +-250.0f,20.2026f,-199.219f, +-246.094f,19.5895f,-199.219f, +-242.188f,20.3489f,-199.219f, +-238.281f,21.0293f,-199.219f, +-234.375f,21.5343f,-199.219f, +-230.469f,20.6859f,-199.219f, +-226.563f,19.9279f,-199.219f, +-222.656f,18.7217f,-199.219f, +-218.75f,17.4818f,-199.219f, +-214.844f,15.0438f,-199.219f, +-210.938f,13.4082f,-199.219f, +-207.031f,10.7188f,-199.219f, +-203.125f,8.32176f,-199.219f, +-199.219f,7.30407f,-199.219f, +-195.313f,7.02569f,-199.219f, +-191.406f,7.38826f,-199.219f, +-187.5f,6.94954f,-199.219f, +-183.594f,6.62067f,-199.219f, +-179.688f,6.55308f,-199.219f, +-175.781f,6.3403f,-199.219f, +-171.875f,5.0001f,-199.219f, +-167.969f,6.51564f,-199.219f, +-164.063f,6.69774f,-199.219f, +-160.156f,5.67189f,-199.219f, +-156.25f,4.8973f,-199.219f, +-152.344f,3.43798f,-199.219f, +-148.438f,2.08531f,-199.219f, +-144.531f,3.86643f,-199.219f, +-140.625f,6.0862f,-199.219f, +-136.719f,6.99995f,-199.219f, +-132.813f,8.32808f,-199.219f, +-128.906f,8.55809f,-199.219f, +-125.0f,8.26904f,-199.219f, +-121.094f,8.63733f,-199.219f, +-117.188f,9.11106f,-199.219f, +-113.281f,9.73154f,-199.219f, +-109.375f,9.14108f,-199.219f, +-105.469f,9.3525f,-199.219f, +-101.563f,9.56281f,-199.219f, +-97.6563f,9.74866f,-199.219f, +-93.75f,10.9852f,-199.219f, +-89.8438f,12.3926f,-199.219f, +-85.9375f,13.6407f,-199.219f, +-82.0313f,15.9886f,-199.219f, +-78.125f,17.7913f,-199.219f, +-74.2188f,18.8352f,-199.219f, +-70.3125f,20.2718f,-199.219f, +-66.4063f,23.501f,-199.219f, +-62.5f,24.6073f,-199.219f, +-58.5938f,25.3028f,-199.219f, +-54.6875f,25.2244f,-199.219f, +-50.7813f,23.9922f,-199.219f, +-46.875f,24.6425f,-199.219f, +-42.9688f,26.6199f,-199.219f, +-39.0625f,27.5474f,-199.219f, +-35.1563f,27.4672f,-199.219f, +-31.25f,27.2906f,-199.219f, +-27.3438f,26.489f,-199.219f, +-23.4375f,26.3554f,-199.219f, +-19.5313f,26.1787f,-199.219f, +-15.625f,26.2538f,-199.219f, +-11.7188f,25.7694f,-199.219f, +-7.8125f,25.2691f,-199.219f, +-3.90625f,23.3867f,-199.219f, +0.0f,22.5717f,-199.219f, +3.90625f,21.5827f,-199.219f, +-250.0f,19.3526f,-203.125f, +-246.094f,19.2964f,-203.125f, +-242.188f,19.226f,-203.125f, +-238.281f,19.4274f,-203.125f, +-234.375f,19.4317f,-203.125f, +-230.469f,19.3079f,-203.125f, +-226.563f,18.212f,-203.125f, +-222.656f,17.8371f,-203.125f, +-218.75f,16.8642f,-203.125f, +-214.844f,14.8539f,-203.125f, +-210.938f,12.425f,-203.125f, +-207.031f,10.0369f,-203.125f, +-203.125f,9.00151f,-203.125f, +-199.219f,8.61334f,-203.125f, +-195.313f,8.09586f,-203.125f, +-191.406f,8.18143f,-203.125f, +-187.5f,7.75345f,-203.125f, +-183.594f,7.72772f,-203.125f, +-179.688f,7.71649f,-203.125f, +-175.781f,7.72935f,-203.125f, +-171.875f,6.70116f,-203.125f, +-167.969f,6.58828f,-203.125f, +-164.063f,6.47975f,-203.125f, +-160.156f,5.96451f,-203.125f, +-156.25f,5.85253f,-203.125f, +-152.344f,5.14982f,-203.125f, +-148.438f,4.60646f,-203.125f, +-144.531f,6.3659f,-203.125f, +-140.625f,7.66587f,-203.125f, +-136.719f,8.68095f,-203.125f, +-132.813f,9.86922f,-203.125f, +-128.906f,9.93481f,-203.125f, +-125.0f,10.9585f,-203.125f, +-121.094f,10.9271f,-203.125f, +-117.188f,11.4348f,-203.125f, +-113.281f,11.0548f,-203.125f, +-109.375f,11.2501f,-203.125f, +-105.469f,11.7673f,-203.125f, +-101.563f,10.8899f,-203.125f, +-97.6563f,11.3791f,-203.125f, +-93.75f,12.168f,-203.125f, +-89.8438f,12.7667f,-203.125f, +-85.9375f,15.2415f,-203.125f, +-82.0313f,17.9783f,-203.125f, +-78.125f,19.6193f,-203.125f, +-74.2188f,19.6343f,-203.125f, +-70.3125f,19.7814f,-203.125f, +-66.4063f,21.45f,-203.125f, +-62.5f,24.1224f,-203.125f, +-58.5938f,24.9145f,-203.125f, +-54.6875f,24.2614f,-203.125f, +-50.7813f,24.025f,-203.125f, +-46.875f,23.1092f,-203.125f, +-42.9688f,24.0294f,-203.125f, +-39.0625f,25.4744f,-203.125f, +-35.1563f,25.9477f,-203.125f, +-31.25f,25.5895f,-203.125f, +-27.3438f,25.0752f,-203.125f, +-23.4375f,24.6537f,-203.125f, +-19.5313f,25.0025f,-203.125f, +-15.625f,25.211f,-203.125f, +-11.7188f,24.2103f,-203.125f, +-7.8125f,23.1363f,-203.125f, +-3.90625f,21.4314f,-203.125f, +0.0f,20.8784f,-203.125f, +3.90625f,20.3179f,-203.125f, +-250.0f,18.4857f,-207.031f, +-246.094f,18.9103f,-207.031f, +-242.188f,17.7666f,-207.031f, +-238.281f,18.3803f,-207.031f, +-234.375f,17.7746f,-207.031f, +-230.469f,18.1956f,-207.031f, +-226.563f,17.4596f,-207.031f, +-222.656f,16.5346f,-207.031f, +-218.75f,15.3933f,-207.031f, +-214.844f,14.0342f,-207.031f, +-210.938f,11.5492f,-207.031f, +-207.031f,10.8526f,-207.031f, +-203.125f,10.5164f,-207.031f, +-199.219f,10.4957f,-207.031f, +-195.313f,9.57889f,-207.031f, +-191.406f,9.42031f,-207.031f, +-187.5f,9.08544f,-207.031f, +-183.594f,8.10082f,-207.031f, +-179.688f,8.5632f,-207.031f, +-175.781f,8.74392f,-207.031f, +-171.875f,8.56175f,-207.031f, +-167.969f,7.13665f,-207.031f, +-164.063f,6.99003f,-207.031f, +-160.156f,7.1192f,-207.031f, +-156.25f,6.173f,-207.031f, +-152.344f,6.44193f,-207.031f, +-148.438f,7.15583f,-207.031f, +-144.531f,7.74526f,-207.031f, +-140.625f,9.38846f,-207.031f, +-136.719f,10.1943f,-207.031f, +-132.813f,10.5195f,-207.031f, +-128.906f,11.4457f,-207.031f, +-125.0f,12.4233f,-207.031f, +-121.094f,12.8633f,-207.031f, +-117.188f,13.4045f,-207.031f, +-113.281f,12.9134f,-207.031f, +-109.375f,12.9203f,-207.031f, +-105.469f,13.2173f,-207.031f, +-101.563f,12.9065f,-207.031f, +-97.6563f,12.9327f,-207.031f, +-93.75f,13.5926f,-207.031f, +-89.8438f,14.5472f,-207.031f, +-85.9375f,16.41f,-207.031f, +-82.0313f,19.1484f,-207.031f, +-78.125f,20.5688f,-207.031f, +-74.2188f,20.1464f,-207.031f, +-70.3125f,19.9352f,-207.031f, +-66.4063f,20.4543f,-207.031f, +-62.5f,22.0083f,-207.031f, +-58.5938f,23.2866f,-207.031f, +-54.6875f,23.3242f,-207.031f, +-50.7813f,23.0127f,-207.031f, +-46.875f,23.4455f,-207.031f, +-42.9688f,23.4808f,-207.031f, +-39.0625f,24.4622f,-207.031f, +-35.1563f,25.1122f,-207.031f, +-31.25f,25.3818f,-207.031f, +-27.3438f,24.0051f,-207.031f, +-23.4375f,22.3971f,-207.031f, +-19.5313f,23.4811f,-207.031f, +-15.625f,23.8447f,-207.031f, +-11.7188f,22.3912f,-207.031f, +-7.8125f,21.7286f,-207.031f, +-3.90625f,20.1632f,-207.031f, +0.0f,18.6587f,-207.031f, +3.90625f,18.3149f,-207.031f, +-250.0f,17.6517f,-210.938f, +-246.094f,17.8132f,-210.938f, +-242.188f,17.4894f,-210.938f, +-238.281f,16.7087f,-210.938f, +-234.375f,15.9111f,-210.938f, +-230.469f,16.6733f,-210.938f, +-226.563f,16.6911f,-210.938f, +-222.656f,14.6177f,-210.938f, +-218.75f,13.6959f,-210.938f, +-214.844f,12.227f,-210.938f, +-210.938f,11.5376f,-210.938f, +-207.031f,11.7259f,-210.938f, +-203.125f,11.4804f,-210.938f, +-199.219f,11.8728f,-210.938f, +-195.313f,11.7357f,-210.938f, +-191.406f,10.6319f,-210.938f, +-187.5f,10.7016f,-210.938f, +-183.594f,9.53811f,-210.938f, +-179.688f,9.65149f,-210.938f, +-175.781f,9.45993f,-210.938f, +-171.875f,9.4427f,-210.938f, +-167.969f,8.02525f,-210.938f, +-164.063f,6.71089f,-210.938f, +-160.156f,7.22567f,-210.938f, +-156.25f,7.52391f,-210.938f, +-152.344f,8.46765f,-210.938f, +-148.438f,8.60801f,-210.938f, +-144.531f,9.89046f,-210.938f, +-140.625f,10.9163f,-210.938f, +-136.719f,11.445f,-210.938f, +-132.813f,12.6949f,-210.938f, +-128.906f,13.3645f,-210.938f, +-125.0f,14.5389f,-210.938f, +-121.094f,14.7689f,-210.938f, +-117.188f,15.8285f,-210.938f, +-113.281f,15.5058f,-210.938f, +-109.375f,14.3542f,-210.938f, +-105.469f,14.9928f,-210.938f, +-101.563f,14.9601f,-210.938f, +-97.6563f,15.1602f,-210.938f, +-93.75f,15.1589f,-210.938f, +-89.8438f,16.5401f,-210.938f, +-85.9375f,18.2407f,-210.938f, +-82.0313f,19.8006f,-210.938f, +-78.125f,20.9223f,-210.938f, +-74.2188f,20.5615f,-210.938f, +-70.3125f,21.0505f,-210.938f, +-66.4063f,21.024f,-210.938f, +-62.5f,21.7216f,-210.938f, +-58.5938f,22.8737f,-210.938f, +-54.6875f,23.631f,-210.938f, +-50.7813f,23.6265f,-210.938f, +-46.875f,23.5636f,-210.938f, +-42.9688f,24.1299f,-210.938f, +-39.0625f,24.6395f,-210.938f, +-35.1563f,25.3237f,-210.938f, +-31.25f,24.7459f,-210.938f, +-27.3438f,22.2327f,-210.938f, +-23.4375f,21.6309f,-210.938f, +-19.5313f,22.3059f,-210.938f, +-15.625f,22.1894f,-210.938f, +-11.7188f,21.2088f,-210.938f, +-7.8125f,20.3383f,-210.938f, +-3.90625f,18.4799f,-210.938f, +0.0f,17.18f,-210.938f, +3.90625f,16.2147f,-210.938f, +-250.0f,17.6547f,-214.844f, +-246.094f,17.1845f,-214.844f, +-242.188f,17.6913f,-214.844f, +-238.281f,16.8842f,-214.844f, +-234.375f,14.7169f,-214.844f, +-230.469f,15.4287f,-214.844f, +-226.563f,14.5659f,-214.844f, +-222.656f,13.1756f,-214.844f, +-218.75f,12.021f,-214.844f, +-214.844f,11.9663f,-214.844f, +-210.938f,12.535f,-214.844f, +-207.031f,12.5802f,-214.844f, +-203.125f,12.7437f,-214.844f, +-199.219f,12.9859f,-214.844f, +-195.313f,12.7714f,-214.844f, +-191.406f,11.9783f,-214.844f, +-187.5f,11.9282f,-214.844f, +-183.594f,10.7633f,-214.844f, +-179.688f,10.3463f,-214.844f, +-175.781f,10.1867f,-214.844f, +-171.875f,10.378f,-214.844f, +-167.969f,8.81572f,-214.844f, +-164.063f,7.29133f,-214.844f, +-160.156f,8.45242f,-214.844f, +-156.25f,9.77224f,-214.844f, +-152.344f,10.4567f,-214.844f, +-148.438f,11.0484f,-214.844f, +-144.531f,12.1985f,-214.844f, +-140.625f,13.766f,-214.844f, +-136.719f,14.9123f,-214.844f, +-132.813f,15.4577f,-214.844f, +-128.906f,16.3401f,-214.844f, +-125.0f,16.5963f,-214.844f, +-121.094f,16.9605f,-214.844f, +-117.188f,16.548f,-214.844f, +-113.281f,16.701f,-214.844f, +-109.375f,16.6987f,-214.844f, +-105.469f,16.1393f,-214.844f, +-101.563f,15.4379f,-214.844f, +-97.6563f,15.9931f,-214.844f, +-93.75f,16.7962f,-214.844f, +-89.8438f,18.5464f,-214.844f, +-85.9375f,20.2834f,-214.844f, +-82.0313f,20.8463f,-214.844f, +-78.125f,21.263f,-214.844f, +-74.2188f,22.137f,-214.844f, +-70.3125f,22.1614f,-214.844f, +-66.4063f,21.7706f,-214.844f, +-62.5f,23.0496f,-214.844f, +-58.5938f,23.0762f,-214.844f, +-54.6875f,24.2163f,-214.844f, +-50.7813f,23.9415f,-214.844f, +-46.875f,23.115f,-214.844f, +-42.9688f,24.4371f,-214.844f, +-39.0625f,25.7433f,-214.844f, +-35.1563f,24.6385f,-214.844f, +-31.25f,23.2822f,-214.844f, +-27.3438f,21.8583f,-214.844f, +-23.4375f,21.2352f,-214.844f, +-19.5313f,21.3084f,-214.844f, +-15.625f,20.7264f,-214.844f, +-11.7188f,19.67f,-214.844f, +-7.8125f,18.8192f,-214.844f, +-3.90625f,16.6504f,-214.844f, +0.0f,14.8779f,-214.844f, +3.90625f,14.284f,-214.844f, +-250.0f,17.1549f,-218.75f, +-246.094f,16.6295f,-218.75f, +-242.188f,17.7459f,-218.75f, +-238.281f,17.3894f,-218.75f, +-234.375f,15.2738f,-218.75f, +-230.469f,13.3984f,-218.75f, +-226.563f,12.8639f,-218.75f, +-222.656f,12.3225f,-218.75f, +-218.75f,12.1914f,-218.75f, +-214.844f,12.4104f,-218.75f, +-210.938f,12.9278f,-218.75f, +-207.031f,13.387f,-218.75f, +-203.125f,13.4342f,-218.75f, +-199.219f,12.7445f,-218.75f, +-195.313f,12.543f,-218.75f, +-191.406f,12.1437f,-218.75f, +-187.5f,12.3491f,-218.75f, +-183.594f,11.2334f,-218.75f, +-179.688f,11.4016f,-218.75f, +-175.781f,11.2455f,-218.75f, +-171.875f,10.3681f,-218.75f, +-167.969f,9.23056f,-218.75f, +-164.063f,8.35869f,-218.75f, +-160.156f,10.3612f,-218.75f, +-156.25f,11.8429f,-218.75f, +-152.344f,13.2154f,-218.75f, +-148.438f,13.6238f,-218.75f, +-144.531f,14.8343f,-218.75f, +-140.625f,15.5549f,-218.75f, +-136.719f,16.9496f,-218.75f, +-132.813f,17.9187f,-218.75f, +-128.906f,17.7467f,-218.75f, +-125.0f,17.8229f,-218.75f, +-121.094f,17.4408f,-218.75f, +-117.188f,17.3929f,-218.75f, +-113.281f,17.9861f,-218.75f, +-109.375f,18.0206f,-218.75f, +-105.469f,17.6787f,-218.75f, +-101.563f,17.3769f,-218.75f, +-97.6563f,17.5683f,-218.75f, +-93.75f,18.0067f,-218.75f, +-89.8438f,18.9639f,-218.75f, +-85.9375f,20.8377f,-218.75f, +-82.0313f,22.207f,-218.75f, +-78.125f,23.1239f,-218.75f, +-74.2188f,22.384f,-218.75f, +-70.3125f,22.2939f,-218.75f, +-66.4063f,21.8208f,-218.75f, +-62.5f,22.9458f,-218.75f, +-58.5938f,24.2547f,-218.75f, +-54.6875f,24.5855f,-218.75f, +-50.7813f,23.9529f,-218.75f, +-46.875f,22.9226f,-218.75f, +-42.9688f,25.1015f,-218.75f, +-39.0625f,25.1591f,-218.75f, +-35.1563f,23.6146f,-218.75f, +-31.25f,21.7924f,-218.75f, +-27.3438f,20.3147f,-218.75f, +-23.4375f,19.9227f,-218.75f, +-19.5313f,20.3267f,-218.75f, +-15.625f,19.1903f,-218.75f, +-11.7188f,17.3132f,-218.75f, +-7.8125f,16.5145f,-218.75f, +-3.90625f,15.5991f,-218.75f, +0.0f,13.7865f,-218.75f, +3.90625f,13.272f,-218.75f, +-250.0f,16.7536f,-222.656f, +-246.094f,16.7692f,-222.656f, +-242.188f,17.6216f,-222.656f, +-238.281f,17.7524f,-222.656f, +-234.375f,15.7102f,-222.656f, +-230.469f,13.9934f,-222.656f, +-226.563f,13.1311f,-222.656f, +-222.656f,13.6218f,-222.656f, +-218.75f,13.8812f,-222.656f, +-214.844f,13.6928f,-222.656f, +-210.938f,13.2498f,-222.656f, +-207.031f,13.9199f,-222.656f, +-203.125f,14.8224f,-222.656f, +-199.219f,14.7821f,-222.656f, +-195.313f,14.4118f,-222.656f, +-191.406f,13.2421f,-222.656f, +-187.5f,13.1953f,-222.656f, +-183.594f,11.9441f,-222.656f, +-179.688f,11.8006f,-222.656f, +-175.781f,11.2509f,-222.656f, +-171.875f,9.7863f,-222.656f, +-167.969f,8.85086f,-222.656f, +-164.063f,10.6896f,-222.656f, +-160.156f,12.9132f,-222.656f, +-156.25f,13.602f,-222.656f, +-152.344f,15.3711f,-222.656f, +-148.438f,16.1768f,-222.656f, +-144.531f,16.9203f,-222.656f, +-140.625f,17.0404f,-222.656f, +-136.719f,18.4968f,-222.656f, +-132.813f,18.8222f,-222.656f, +-128.906f,19.2736f,-222.656f, +-125.0f,19.1956f,-222.656f, +-121.094f,18.5998f,-222.656f, +-117.188f,18.5054f,-222.656f, +-113.281f,19.68f,-222.656f, +-109.375f,19.5038f,-222.656f, +-105.469f,19.4749f,-222.656f, +-101.563f,18.7504f,-222.656f, +-97.6563f,18.6121f,-222.656f, +-93.75f,19.1119f,-222.656f, +-89.8438f,20.5347f,-222.656f, +-85.9375f,21.4412f,-222.656f, +-82.0313f,22.187f,-222.656f, +-78.125f,22.9384f,-222.656f, +-74.2188f,22.5226f,-222.656f, +-70.3125f,22.7323f,-222.656f, +-66.4063f,23.4931f,-222.656f, +-62.5f,24.6895f,-222.656f, +-58.5938f,24.9745f,-222.656f, +-54.6875f,24.801f,-222.656f, +-50.7813f,23.2235f,-222.656f, +-46.875f,22.4973f,-222.656f, +-42.9688f,23.9826f,-222.656f, +-39.0625f,23.4458f,-222.656f, +-35.1563f,22.66f,-222.656f, +-31.25f,20.8011f,-222.656f, +-27.3438f,18.877f,-222.656f, +-23.4375f,17.9999f,-222.656f, +-19.5313f,18.2206f,-222.656f, +-15.625f,17.8501f,-222.656f, +-11.7188f,16.2125f,-222.656f, +-7.8125f,15.4897f,-222.656f, +-3.90625f,14.2048f,-222.656f, +0.0f,13.1443f,-222.656f, +3.90625f,13.0199f,-222.656f, +-250.0f,15.9959f,-226.563f, +-246.094f,16.3902f,-226.563f, +-242.188f,17.2433f,-226.563f, +-238.281f,16.8903f,-226.563f, +-234.375f,16.2616f,-226.563f, +-230.469f,16.3335f,-226.563f, +-226.563f,15.3662f,-226.563f, +-222.656f,14.6429f,-226.563f, +-218.75f,15.2987f,-226.563f, +-214.844f,15.1249f,-226.563f, +-210.938f,14.6321f,-226.563f, +-207.031f,15.402f,-226.563f, +-203.125f,15.5803f,-226.563f, +-199.219f,15.8024f,-226.563f, +-195.313f,14.9564f,-226.563f, +-191.406f,14.7272f,-226.563f, +-187.5f,14.0749f,-226.563f, +-183.594f,12.2838f,-226.563f, +-179.688f,12.0268f,-226.563f, +-175.781f,10.904f,-226.563f, +-171.875f,10.0049f,-226.563f, +-167.969f,9.85558f,-226.563f, +-164.063f,11.873f,-226.563f, +-160.156f,14.0684f,-226.563f, +-156.25f,15.4765f,-226.563f, +-152.344f,16.7458f,-226.563f, +-148.438f,17.9359f,-226.563f, +-144.531f,18.4507f,-226.563f, +-140.625f,18.3457f,-226.563f, +-136.719f,20.0059f,-226.563f, +-132.813f,20.3125f,-226.563f, +-128.906f,19.751f,-226.563f, +-125.0f,19.8084f,-226.563f, +-121.094f,19.9091f,-226.563f, +-117.188f,20.3401f,-226.563f, +-113.281f,20.8121f,-226.563f, +-109.375f,20.5705f,-226.563f, +-105.469f,20.9909f,-226.563f, +-101.563f,20.4171f,-226.563f, +-97.6563f,19.834f,-226.563f, +-93.75f,19.9289f,-226.563f, +-89.8438f,20.4305f,-226.563f, +-85.9375f,21.4097f,-226.563f, +-82.0313f,21.9666f,-226.563f, +-78.125f,22.5232f,-226.563f, +-74.2188f,22.2049f,-226.563f, +-70.3125f,22.7045f,-226.563f, +-66.4063f,23.7933f,-226.563f, +-62.5f,24.5938f,-226.563f, +-58.5938f,24.6161f,-226.563f, +-54.6875f,23.6008f,-226.563f, +-50.7813f,21.9411f,-226.563f, +-46.875f,21.6164f,-226.563f, +-42.9688f,22.5551f,-226.563f, +-39.0625f,22.5032f,-226.563f, +-35.1563f,21.5165f,-226.563f, +-31.25f,19.8362f,-226.563f, +-27.3438f,17.5967f,-226.563f, +-23.4375f,15.6932f,-226.563f, +-19.5313f,15.7774f,-226.563f, +-15.625f,15.6405f,-226.563f, +-11.7188f,14.7549f,-226.563f, +-7.8125f,14.3205f,-226.563f, +-3.90625f,13.2947f,-226.563f, +0.0f,11.9266f,-226.563f, +3.90625f,11.9733f,-226.563f, +-250.0f,15.2423f,-230.469f, +-246.094f,16.2143f,-230.469f, +-242.188f,17.2462f,-230.469f, +-238.281f,17.7941f,-230.469f, +-234.375f,18.4029f,-230.469f, +-230.469f,18.5726f,-230.469f, +-226.563f,17.4729f,-230.469f, +-222.656f,15.9467f,-230.469f, +-218.75f,15.5021f,-230.469f, +-214.844f,15.7096f,-230.469f, +-210.938f,15.6276f,-230.469f, +-207.031f,15.7025f,-230.469f, +-203.125f,14.8851f,-230.469f, +-199.219f,14.87f,-230.469f, +-195.313f,14.3971f,-230.469f, +-191.406f,14.5771f,-230.469f, +-187.5f,13.8163f,-230.469f, +-183.594f,12.7605f,-230.469f, +-179.688f,12.587f,-230.469f, +-175.781f,11.0727f,-230.469f, +-171.875f,10.0166f,-230.469f, +-167.969f,12.5787f,-230.469f, +-164.063f,13.3613f,-230.469f, +-160.156f,14.7537f,-230.469f, +-156.25f,15.9879f,-230.469f, +-152.344f,17.6792f,-230.469f, +-148.438f,18.5224f,-230.469f, +-144.531f,18.5026f,-230.469f, +-140.625f,19.4852f,-230.469f, +-136.719f,20.3222f,-230.469f, +-132.813f,20.2809f,-230.469f, +-128.906f,21.0408f,-230.469f, +-125.0f,20.4729f,-230.469f, +-121.094f,20.8829f,-230.469f, +-117.188f,21.532f,-230.469f, +-113.281f,21.3373f,-230.469f, +-109.375f,22.0014f,-230.469f, +-105.469f,22.1484f,-230.469f, +-101.563f,21.7053f,-230.469f, +-97.6563f,20.5255f,-230.469f, +-93.75f,19.6269f,-230.469f, +-89.8438f,20.0012f,-230.469f, +-85.9375f,21.0697f,-230.469f, +-82.0313f,21.8192f,-230.469f, +-78.125f,22.7525f,-230.469f, +-74.2188f,22.3932f,-230.469f, +-70.3125f,22.0383f,-230.469f, +-66.4063f,22.5989f,-230.469f, +-62.5f,23.0428f,-230.469f, +-58.5938f,22.4512f,-230.469f, +-54.6875f,21.5848f,-230.469f, +-50.7813f,20.085f,-230.469f, +-46.875f,19.9106f,-230.469f, +-42.9688f,20.5256f,-230.469f, +-39.0625f,20.2072f,-230.469f, +-35.1563f,18.9414f,-230.469f, +-31.25f,17.9342f,-230.469f, +-27.3438f,15.3472f,-230.469f, +-23.4375f,13.2173f,-230.469f, +-19.5313f,13.1448f,-230.469f, +-15.625f,13.7506f,-230.469f, +-11.7188f,12.7439f,-230.469f, +-7.8125f,12.5338f,-230.469f, +-3.90625f,12.0435f,-230.469f, +0.0f,11.0483f,-230.469f, +3.90625f,10.4619f,-230.469f, +-250.0f,15.6879f,-234.375f, +-246.094f,17.6667f,-234.375f, +-242.188f,18.8427f,-234.375f, +-238.281f,19.6527f,-234.375f, +-234.375f,19.7979f,-234.375f, +-230.469f,19.8698f,-234.375f, +-226.563f,19.1736f,-234.375f, +-222.656f,16.9995f,-234.375f, +-218.75f,15.4573f,-234.375f, +-214.844f,15.6294f,-234.375f, +-210.938f,15.4315f,-234.375f, +-207.031f,15.1239f,-234.375f, +-203.125f,14.669f,-234.375f, +-199.219f,14.4586f,-234.375f, +-195.313f,14.1329f,-234.375f, +-191.406f,14.0558f,-234.375f, +-187.5f,13.3746f,-234.375f, +-183.594f,13.2348f,-234.375f, +-179.688f,13.3354f,-234.375f, +-175.781f,12.1532f,-234.375f, +-171.875f,11.4785f,-234.375f, +-167.969f,12.7174f,-234.375f, +-164.063f,14.0617f,-234.375f, +-160.156f,15.3367f,-234.375f, +-156.25f,16.6196f,-234.375f, +-152.344f,17.6677f,-234.375f, +-148.438f,18.475f,-234.375f, +-144.531f,19.8205f,-234.375f, +-140.625f,19.6973f,-234.375f, +-136.719f,20.5952f,-234.375f, +-132.813f,20.3507f,-234.375f, +-128.906f,20.8729f,-234.375f, +-125.0f,21.9377f,-234.375f, +-121.094f,21.8916f,-234.375f, +-117.188f,21.9614f,-234.375f, +-113.281f,22.1752f,-234.375f, +-109.375f,22.2881f,-234.375f, +-105.469f,23.1063f,-234.375f, +-101.563f,23.4826f,-234.375f, +-97.6563f,22.5968f,-234.375f, +-93.75f,21.3142f,-234.375f, +-89.8438f,19.9609f,-234.375f, +-85.9375f,21.4353f,-234.375f, +-82.0313f,21.9716f,-234.375f, +-78.125f,22.6918f,-234.375f, +-74.2188f,21.9561f,-234.375f, +-70.3125f,21.3085f,-234.375f, +-66.4063f,21.4104f,-234.375f, +-62.5f,21.4904f,-234.375f, +-58.5938f,20.2467f,-234.375f, +-54.6875f,19.1535f,-234.375f, +-50.7813f,17.9598f,-234.375f, +-46.875f,18.0449f,-234.375f, +-42.9688f,18.3612f,-234.375f, +-39.0625f,17.5008f,-234.375f, +-35.1563f,16.7819f,-234.375f, +-31.25f,15.4328f,-234.375f, +-27.3438f,13.9747f,-234.375f, +-23.4375f,12.1868f,-234.375f, +-19.5313f,12.0847f,-234.375f, +-15.625f,11.926f,-234.375f, +-11.7188f,11.3058f,-234.375f, +-7.8125f,11.0187f,-234.375f, +-3.90625f,10.1275f,-234.375f, +0.0f,9.73133f,-234.375f, +3.90625f,8.85224f,-234.375f, +-250.0f,16.6463f,-238.281f, +-246.094f,18.8582f,-238.281f, +-242.188f,19.6269f,-238.281f, +-238.281f,20.3222f,-238.281f, +-234.375f,20.8316f,-238.281f, +-230.469f,20.6072f,-238.281f, +-226.563f,19.2331f,-238.281f, +-222.656f,18.0021f,-238.281f, +-218.75f,16.4891f,-238.281f, +-214.844f,15.7845f,-238.281f, +-210.938f,15.4622f,-238.281f, +-207.031f,14.3459f,-238.281f, +-203.125f,14.6544f,-238.281f, +-199.219f,13.7779f,-238.281f, +-195.313f,13.4199f,-238.281f, +-191.406f,13.2089f,-238.281f, +-187.5f,12.5036f,-238.281f, +-183.594f,12.6398f,-238.281f, +-179.688f,13.015f,-238.281f, +-175.781f,12.659f,-238.281f, +-171.875f,13.2801f,-238.281f, +-167.969f,13.9547f,-238.281f, +-164.063f,14.8792f,-238.281f, +-160.156f,16.4144f,-238.281f, +-156.25f,17.1062f,-238.281f, +-152.344f,17.9028f,-238.281f, +-148.438f,19.1823f,-238.281f, +-144.531f,20.6903f,-238.281f, +-140.625f,19.9053f,-238.281f, +-136.719f,20.8795f,-238.281f, +-132.813f,21.7034f,-238.281f, +-128.906f,21.8373f,-238.281f, +-125.0f,22.5134f,-238.281f, +-121.094f,22.7918f,-238.281f, +-117.188f,23.1126f,-238.281f, +-113.281f,23.0308f,-238.281f, +-109.375f,23.7212f,-238.281f, +-105.469f,24.6127f,-238.281f, +-101.563f,24.5942f,-238.281f, +-97.6563f,24.0315f,-238.281f, +-93.75f,23.2191f,-238.281f, +-89.8438f,21.3372f,-238.281f, +-85.9375f,20.6395f,-238.281f, +-82.0313f,22.2808f,-238.281f, +-78.125f,22.2977f,-238.281f, +-74.2188f,21.5802f,-238.281f, +-70.3125f,20.5131f,-238.281f, +-66.4063f,20.0882f,-238.281f, +-62.5f,19.9865f,-238.281f, +-58.5938f,19.1423f,-238.281f, +-54.6875f,16.917f,-238.281f, +-50.7813f,16.0256f,-238.281f, +-46.875f,15.4122f,-238.281f, +-42.9688f,15.0531f,-238.281f, +-39.0625f,15.8819f,-238.281f, +-35.1563f,14.3724f,-238.281f, +-31.25f,12.993f,-238.281f, +-27.3438f,11.8948f,-238.281f, +-23.4375f,10.1339f,-238.281f, +-19.5313f,10.4205f,-238.281f, +-15.625f,10.7339f,-238.281f, +-11.7188f,9.86852f,-238.281f, +-7.8125f,8.89818f,-238.281f, +-3.90625f,8.20848f,-238.281f, +0.0f,7.89095f,-238.281f, +3.90625f,7.99527f,-238.281f, +-250.0f,16.461f,-242.188f, +-246.094f,18.8623f,-242.188f, +-242.188f,19.6097f,-242.188f, +-238.281f,20.8167f,-242.188f, +-234.375f,21.0667f,-242.188f, +-230.469f,20.3337f,-242.188f, +-226.563f,18.9993f,-242.188f, +-222.656f,17.8141f,-242.188f, +-218.75f,17.3651f,-242.188f, +-214.844f,16.1703f,-242.188f, +-210.938f,15.3612f,-242.188f, +-207.031f,14.5062f,-242.188f, +-203.125f,14.0333f,-242.188f, +-199.219f,13.0731f,-242.188f, +-195.313f,13.0716f,-242.188f, +-191.406f,12.2773f,-242.188f, +-187.5f,12.1599f,-242.188f, +-183.594f,12.0841f,-242.188f, +-179.688f,11.1979f,-242.188f, +-175.781f,11.7767f,-242.188f, +-171.875f,13.5192f,-242.188f, +-167.969f,13.6117f,-242.188f, +-164.063f,14.5377f,-242.188f, +-160.156f,16.1128f,-242.188f, +-156.25f,17.0591f,-242.188f, +-152.344f,18.0547f,-242.188f, +-148.438f,19.9927f,-242.188f, +-144.531f,20.5592f,-242.188f, +-140.625f,20.5602f,-242.188f, +-136.719f,20.6585f,-242.188f, +-132.813f,22.6924f,-242.188f, +-128.906f,23.4786f,-242.188f, +-125.0f,23.9921f,-242.188f, +-121.094f,24.3221f,-242.188f, +-117.188f,24.7845f,-242.188f, +-113.281f,24.0995f,-242.188f, +-109.375f,25.5836f,-242.188f, +-105.469f,25.1932f,-242.188f, +-101.563f,25.0022f,-242.188f, +-97.6563f,24.569f,-242.188f, +-93.75f,24.5749f,-242.188f, +-89.8438f,22.6678f,-242.188f, +-85.9375f,20.6652f,-242.188f, +-82.0313f,21.1719f,-242.188f, +-78.125f,21.9102f,-242.188f, +-74.2188f,20.9512f,-242.188f, +-70.3125f,19.1099f,-242.188f, +-66.4063f,18.2366f,-242.188f, +-62.5f,16.9751f,-242.188f, +-58.5938f,16.938f,-242.188f, +-54.6875f,16.3692f,-242.188f, +-50.7813f,14.5702f,-242.188f, +-46.875f,13.5527f,-242.188f, +-42.9688f,13.0169f,-242.188f, +-39.0625f,11.9599f,-242.188f, +-35.1563f,11.4675f,-242.188f, +-31.25f,10.1264f,-242.188f, +-27.3438f,9.05124f,-242.188f, +-23.4375f,8.17722f,-242.188f, +-19.5313f,8.42066f,-242.188f, +-15.625f,8.13199f,-242.188f, +-11.7188f,7.70744f,-242.188f, +-7.8125f,7.06448f,-242.188f, +-3.90625f,6.2428f,-242.188f, +0.0f,6.35893f,-242.188f, +3.90625f,6.40337f,-242.188f, +-250.0f,16.6546f,-246.094f, +-246.094f,17.6689f,-246.094f, +-242.188f,18.7575f,-246.094f, +-238.281f,20.3967f,-246.094f, +-234.375f,20.3065f,-246.094f, +-230.469f,20.2082f,-246.094f, +-226.563f,19.5383f,-246.094f, +-222.656f,17.7409f,-246.094f, +-218.75f,16.6708f,-246.094f, +-214.844f,15.9584f,-246.094f, +-210.938f,14.8412f,-246.094f, +-207.031f,14.5591f,-246.094f, +-203.125f,13.9049f,-246.094f, +-199.219f,12.4723f,-246.094f, +-195.313f,11.7361f,-246.094f, +-191.406f,11.5463f,-246.094f, +-187.5f,10.9687f,-246.094f, +-183.594f,10.6795f,-246.094f, +-179.688f,10.6856f,-246.094f, +-175.781f,10.6342f,-246.094f, +-171.875f,12.061f,-246.094f, +-167.969f,12.3131f,-246.094f, +-164.063f,13.8453f,-246.094f, +-160.156f,15.3522f,-246.094f, +-156.25f,16.575f,-246.094f, +-152.344f,17.953f,-246.094f, +-148.438f,18.9271f,-246.094f, +-144.531f,19.6463f,-246.094f, +-140.625f,20.0348f,-246.094f, +-136.719f,20.8966f,-246.094f, +-132.813f,22.7081f,-246.094f, +-128.906f,24.2289f,-246.094f, +-125.0f,24.3296f,-246.094f, +-121.094f,25.513f,-246.094f, +-117.188f,26.0616f,-246.094f, +-113.281f,25.9026f,-246.094f, +-109.375f,25.3793f,-246.094f, +-105.469f,26.0086f,-246.094f, +-101.563f,25.9668f,-246.094f, +-97.6563f,25.4377f,-246.094f, +-93.75f,24.6398f,-246.094f, +-89.8438f,22.6277f,-246.094f, +-85.9375f,20.9377f,-246.094f, +-82.0313f,20.5815f,-246.094f, +-78.125f,20.2521f,-246.094f, +-74.2188f,19.1439f,-246.094f, +-70.3125f,17.8492f,-246.094f, +-66.4063f,16.6347f,-246.094f, +-62.5f,15.9154f,-246.094f, +-58.5938f,14.2098f,-246.094f, +-54.6875f,13.5957f,-246.094f, +-50.7813f,12.5676f,-246.094f, +-46.875f,11.2422f,-246.094f, +-42.9688f,10.426f,-246.094f, +-39.0625f,10.1665f,-246.094f, +-35.1563f,9.19605f,-246.094f, +-31.25f,7.36042f,-246.094f, +-27.3438f,5.74959f,-246.094f, +-23.4375f,5.41512f,-246.094f, +-19.5313f,6.03312f,-246.094f, +-15.625f,5.93285f,-246.094f, +-11.7188f,5.3331f,-246.094f, +-7.8125f,5.48059f,-246.094f, +-3.90625f,4.92566f,-246.094f, +0.0f,5.05645f,-246.094f, +3.90625f,6.09425f,-246.094f, +-250.0f,17.2418f,-250.0f, +-246.094f,17.9679f,-250.0f, +-242.188f,19.359f,-250.0f, +-238.281f,19.3277f,-250.0f, +-234.375f,20.1575f,-250.0f, +-230.469f,19.8999f,-250.0f, +-226.563f,18.9681f,-250.0f, +-222.656f,17.7696f,-250.0f, +-218.75f,15.6199f,-250.0f, +-214.844f,14.6555f,-250.0f, +-210.938f,13.0514f,-250.0f, +-207.031f,13.6029f,-250.0f, +-203.125f,13.1455f,-250.0f, +-199.219f,12.0056f,-250.0f, +-195.313f,11.1773f,-250.0f, +-191.406f,10.7263f,-250.0f, +-187.5f,10.2543f,-250.0f, +-183.594f,9.76389f,-250.0f, +-179.688f,9.00623f,-250.0f, +-175.781f,9.47424f,-250.0f, +-171.875f,10.8011f,-250.0f, +-167.969f,12.4395f,-250.0f, +-164.063f,13.7736f,-250.0f, +-160.156f,14.0938f,-250.0f, +-156.25f,15.8447f,-250.0f, +-152.344f,17.1975f,-250.0f, +-148.438f,17.963f,-250.0f, +-144.531f,19.3662f,-250.0f, +-140.625f,20.309f,-250.0f, +-136.719f,21.9063f,-250.0f, +-132.813f,22.8363f,-250.0f, +-128.906f,24.0073f,-250.0f, +-125.0f,25.2989f,-250.0f, +-121.094f,26.2944f,-250.0f, +-117.188f,27.4482f,-250.0f, +-113.281f,27.4823f,-250.0f, +-109.375f,27.2835f,-250.0f, +-105.469f,27.4754f,-250.0f, +-101.563f,27.7731f,-250.0f, +-97.6563f,26.6981f,-250.0f, +-93.75f,24.4699f,-250.0f, +-89.8438f,22.81f,-250.0f, +-85.9375f,21.6739f,-250.0f, +-82.0313f,19.8713f,-250.0f, +-78.125f,18.5848f,-250.0f, +-74.2188f,17.7134f,-250.0f, +-70.3125f,15.5276f,-250.0f, +-66.4063f,14.6805f,-250.0f, +-62.5f,14.0332f,-250.0f, +-58.5938f,12.1429f,-250.0f, +-54.6875f,10.3027f,-250.0f, +-50.7813f,9.68001f,-250.0f, +-46.875f,8.12561f,-250.0f, +-42.9688f,8.26581f,-250.0f, +-39.0625f,7.98056f,-250.0f, +-35.1563f,7.43215f,-250.0f, +-31.25f,6.33038f,-250.0f, +-27.3438f,4.62549f,-250.0f, +-23.4375f,3.83616f,-250.0f, +-19.5313f,4.24597f,-250.0f, +-15.625f,3.79997f,-250.0f, +-11.7188f,3.74461f,-250.0f, +-7.8125f,3.79853f,-250.0f, +-3.90625f,3.95418f,-250.0f, +0.0f,5.70623f,-250.0f, +3.90625f,6.31953f,-250.0f, +}; + +btScalar Landscape08Nml[] = { +-0.193879f,0.980285f,-0.0381128f, +-0.101407f,0.994799f,-0.00961843f, +-0.17812f,0.983422f,0.0339701f, +-0.107869f,0.990758f,0.0822321f, +-0.150224f,0.986838f,0.0598614f, +-0.176421f,0.983338f,0.0438458f, +0.00771709f,0.999873f,0.0139132f, +-0.0458501f,0.998747f,-0.0200731f, +0.170866f,0.984802f,-0.0311488f, +0.198428f,0.979783f,-0.0255296f, +0.223966f,0.969797f,0.0966125f, +0.319719f,0.946459f,0.0446654f, +0.155788f,0.942148f,0.296794f, +0.226142f,0.945324f,0.234996f, +0.0234229f,0.954977f,0.295752f, +-0.0213542f,0.981077f,0.192434f, +-0.0320299f,0.976907f,0.211248f, +-0.0305686f,0.97015f,0.240572f, +-0.00290395f,0.990031f,0.14082f, +-0.0740282f,0.98339f,0.165723f, +0.0359831f,0.998663f,0.0371117f, +-0.048977f,0.998654f,0.0171003f, +0.119085f,0.992879f,0.00312204f, +0.163687f,0.985928f,0.0339365f, +0.233927f,0.967265f,0.0983717f, +0.258555f,0.954734f,0.147076f, +0.185228f,0.98177f,0.0426319f, +0.171781f,0.975163f,0.139813f, +0.312497f,0.949826f,0.0132586f, +0.315278f,0.937034f,0.150223f, +0.455936f,0.889912f,-0.0133666f, +0.444363f,0.88993f,0.102789f, +0.477095f,0.878821f,-0.00729384f, +0.442265f,0.892911f,0.0843273f, +0.441901f,0.89445f,-0.0684218f, +0.356563f,0.929766f,-0.091634f, +0.46452f,0.88048f,-0.0947459f, +0.399286f,0.883106f,-0.246362f, +0.430625f,0.899506f,-0.073831f, +0.418125f,0.862027f,-0.286498f, +0.390492f,0.919986f,-0.0337736f, +0.451928f,0.884249f,-0.117748f, +0.389473f,0.920638f,-0.0271218f, +0.401911f,0.911214f,-0.0903147f, +0.411594f,0.910246f,-0.0451926f, +0.385985f,0.916603f,-0.104187f, +0.406515f,0.904587f,-0.128329f, +0.375686f,0.920382f,-0.108425f, +0.421893f,0.886378f,-0.190632f, +0.362475f,0.891842f,-0.270609f, +0.382406f,0.917607f,-0.108459f, +0.380095f,0.864773f,-0.32817f, +0.206545f,0.977978f,-0.0299668f, +0.319336f,0.938074f,-0.134321f, +-0.0276167f,0.998803f,0.0403598f, +0.0724517f,0.997355f,-0.00577643f, +-0.170399f,0.974366f,0.146884f, +-0.0444923f,0.976538f,0.210699f, +-0.123713f,0.961736f,0.244457f, +-0.0585476f,0.950932f,0.303809f, +-0.0436638f,0.948824f,0.312774f, +-0.0108452f,0.950133f,0.311655f, +-0.0562151f,0.924389f,0.377285f, +-0.024656f,0.918307f,0.3951f, +-0.11936f,0.930674f,0.345831f, +-0.21058f,0.936144f,0.281584f, +-0.166672f,0.952976f,0.253095f, +-0.262868f,0.958623f,0.109278f, +-0.138859f,0.97532f,0.171667f, +-0.166823f,0.980233f,0.106364f, +-0.016911f,0.994026f,0.107828f, +0.014088f,0.986713f,0.161858f, +-0.0269312f,0.989998f,0.138489f, +-0.0681193f,0.995186f,0.0704648f, +-0.241507f,0.962694f,0.122045f, +-0.306148f,0.951983f,0.00131283f, +-0.400562f,0.916076f,-0.0188573f, +-0.46755f,0.872686f,-0.140772f, +-0.451983f,0.886731f,-0.0970551f, +-0.445163f,0.885181f,-0.135217f, +-0.440559f,0.893764f,-0.0842181f, +-0.44058f,0.883958f,-0.156548f, +-0.530573f,0.842324f,-0.094771f, +-0.559377f,0.815929f,-0.14614f, +-0.675146f,0.724837f,-0.137074f, +-0.671227f,0.729467f,-0.131655f, +-0.627673f,0.767191f,-0.132076f, +-0.630683f,0.736819f,-0.243592f, +-0.548071f,0.819689f,-0.166518f, +-0.526895f,0.799727f,-0.287781f, +-0.521779f,0.83885f,-0.155167f, +-0.501504f,0.822365f,-0.268719f, +-0.465479f,0.867433f,-0.175756f, +-0.453816f,0.862676f,-0.223251f, +-0.458424f,0.854844f,-0.243083f, +-0.470698f,0.860374f,-0.195446f, +-0.485669f,0.830839f,-0.27172f, +-0.494445f,0.85319f,-0.166102f, +-0.418394f,0.865747f,-0.274642f, +-0.405345f,0.892443f,-0.198093f, +-0.287108f,0.926134f,-0.244631f, +-0.325256f,0.923685f,-0.202519f, +-0.192384f,0.91848f,-0.345518f, +-0.208186f,0.935081f,-0.28685f, +0.0681073f,0.948251f,-0.310131f, +0.077158f,0.955715f,-0.283998f, +0.102278f,0.947499f,-0.302962f, +0.02043f,0.921087f,-0.388821f, +0.0627177f,0.929646f,-0.363077f, +0.0629047f,0.918578f,-0.390202f, +-0.00415691f,0.947597f,-0.31944f, +-0.00512929f,0.899538f,-0.436812f, +-0.271944f,0.935195f,-0.226842f, +-0.177509f,0.92231f,-0.343271f, +-0.413186f,0.904845f,-0.102632f, +-0.338265f,0.931446f,-0.13411f, +-0.418276f,0.90315f,-0.0967731f, +-0.404177f,0.914278f,-0.0271442f, +-0.400569f,0.902696f,-0.157112f, +-0.429625f,0.894308f,-0.125039f, +-0.29004f,0.948484f,-0.127491f, +-0.188203f,0.980777f,0.0515283f, +-0.0585039f,0.997556f,-0.0381961f, +-0.133431f,0.99094f,0.0152943f, +-0.143343f,0.971126f,-0.1907f, +-0.24516f,0.938627f,-0.242644f, +-0.188833f,0.958258f,-0.214673f, +-0.174705f,0.963776f,-0.201528f, +-0.196517f,0.95296f,-0.230756f, +-0.128653f,0.987396f,-0.0921772f, +-0.120365f,0.975049f,-0.186527f, +0.0117596f,0.998991f,0.0433545f, +-0.146882f,0.98666f,-0.0701983f, +-0.218442f,0.971087f,-0.0962923f, +-0.179096f,0.983284f,-0.0328244f, +0.0658277f,0.997324f,0.0318063f, +0.120963f,0.992647f,0.00454206f, +0.0263542f,0.988052f,0.151849f, +0.0179305f,0.957276f,0.288619f, +0.0987151f,0.955923f,0.276526f, +0.113577f,0.970939f,0.210662f, +0.111989f,0.989066f,0.0959572f, +0.0937332f,0.995324f,-0.0233266f, +0.0889156f,0.995493f,-0.0329669f, +0.214527f,0.976717f,-0.0013568f, +0.281036f,0.957864f,-0.0592866f, +0.349427f,0.927689f,-0.131507f, +0.460507f,0.876585f,-0.139754f, +0.465208f,0.877856f,-0.1138f, +0.432422f,0.897621f,-0.0853653f, +0.392928f,0.918987f,-0.032723f, +0.389134f,0.920603f,0.0326418f, +0.40247f,0.914003f,0.0511488f, +0.41651f,0.90858f,0.031652f, +0.468908f,0.883168f,-0.0118055f, +0.497957f,0.862594f,-0.0892785f, +0.342146f,0.929254f,-0.139366f, +0.262957f,0.964807f,-0.00115352f, +0.156573f,0.98302f,0.095691f, +-0.0479214f,0.988417f,0.143995f, +-0.198695f,0.970386f,0.13737f, +-0.222539f,0.963461f,0.14906f, +-0.145574f,0.943362f,0.298121f, +-0.065459f,0.922659f,0.380021f, +-0.0644219f,0.950539f,0.303852f, +-0.126762f,0.967843f,0.217283f, +-0.017815f,0.980142f,0.197496f, +0.0660407f,0.994277f,0.0839804f, +-0.101583f,0.994471f,0.0266049f, +-0.224345f,0.969139f,0.102176f, +-0.280297f,0.958092f,0.0591033f, +-0.402555f,0.91416f,-0.047541f, +-0.458467f,0.883974f,-0.0916445f, +-0.50134f,0.862765f,-0.0655406f, +-0.644808f,0.754744f,-0.12077f, +-0.636358f,0.756299f,-0.151855f, +-0.556238f,0.818404f,-0.144268f, +-0.504016f,0.849904f,-0.153725f, +-0.404172f,0.887071f,-0.223046f, +-0.360363f,0.894242f,-0.265463f, +-0.432057f,0.840836f,-0.326069f, +-0.4393f,0.818603f,-0.370006f, +-0.249988f,0.890718f,-0.379642f, +-0.114697f,0.874572f,-0.471135f, +-0.0301956f,0.870113f,-0.491927f, +0.0871874f,0.907337f,-0.411263f, +0.0509325f,0.923392f,-0.380464f, +-0.106299f,0.953821f,-0.280938f, +-0.389809f,0.901657f,-0.187255f, +-0.420279f,0.904001f,-0.0784108f, +-0.360569f,0.922439f,-0.138186f, +-0.332116f,0.91853f,-0.214478f, +-0.305854f,0.899541f,-0.311896f, +-0.11957f,0.95083f,-0.285701f, +-0.0843961f,0.977455f,-0.193542f, +-0.186555f,0.968589f,-0.164414f, +-0.1142f,0.975963f,-0.185618f, +-0.138309f,0.943055f,-0.30252f, +-0.101226f,0.981339f,-0.163482f, +-0.184633f,0.97099f,-0.151951f, +-0.239394f,0.95355f,-0.182845f, +-0.0575173f,0.989733f,-0.130847f, +0.0688205f,0.993792f,0.0874178f, +-0.0714424f,0.990397f,0.118361f, +-0.0225247f,0.994972f,0.0975878f, +0.167362f,0.976776f,0.133786f, +0.156506f,0.98511f,0.0711603f, +0.198564f,0.979194f,0.0418473f, +0.173408f,0.984455f,-0.0278778f, +0.108869f,0.989375f,-0.0963545f, +0.224679f,0.96015f,-0.166226f, +0.339104f,0.91731f,-0.208688f, +0.367935f,0.88797f,-0.275922f, +0.418707f,0.869398f,-0.262357f, +0.420889f,0.892687f,-0.161129f, +0.397172f,0.910077f,-0.118378f, +0.374326f,0.920598f,-0.11126f, +0.397932f,0.911721f,-0.102056f, +0.386888f,0.911258f,-0.141166f, +0.41482f,0.902273f,-0.117593f, +0.501715f,0.859192f,-0.100356f, +0.491949f,0.863362f,-0.112214f, +0.357466f,0.931719f,-0.0641779f, +0.171333f,0.982821f,-0.068616f, +0.100623f,0.994346f,0.0339287f, +-0.0698557f,0.996834f,0.0379692f, +-0.194026f,0.980994f,0.00220452f, +-0.288205f,0.957419f,0.0169548f, +-0.304635f,0.947239f,0.0996808f, +-0.10216f,0.973655f,0.20386f, +0.100532f,0.974742f,0.199427f, +-0.0238908f,0.99964f,0.0121747f, +-0.00850096f,0.997624f,-0.0683673f, +0.116859f,0.992157f,-0.044359f, +-0.0433286f,0.998946f,-0.0151181f, +-0.258294f,0.961617f,-0.0926162f, +-0.256378f,0.96262f,-0.0873673f, +-0.327211f,0.940376f,-0.0928767f, +-0.431734f,0.888327f,-0.15646f, +-0.514253f,0.844258f,-0.150905f, +-0.599748f,0.789083f,-0.132858f, +-0.620824f,0.749219f,-0.230756f, +-0.533018f,0.803035f,-0.266508f, +-0.441513f,0.840682f,-0.313561f, +-0.38701f,0.854241f,-0.347124f, +-0.380219f,0.879441f,-0.286385f, +-0.39628f,0.874175f,-0.280679f, +-0.390488f,0.846052f,-0.362926f, +-0.205032f,0.876667f,-0.435221f, +-0.00372872f,0.883142f,-0.46909f, +-0.0083869f,0.837348f,-0.546606f, +-0.00127167f,0.831923f,-0.55489f, +-0.11424f,0.875282f,-0.469926f, +-0.256213f,0.933918f,-0.249305f, +-0.393049f,0.915109f,-0.0899313f, +-0.484342f,0.863396f,-0.141282f, +-0.32612f,0.940905f,-0.0913441f, +-0.240051f,0.956808f,-0.163992f, +-0.189326f,0.934609f,-0.301099f, +-0.228613f,0.900757f,-0.369288f, +-0.206601f,0.953154f,-0.220936f, +-0.220523f,0.958575f,-0.180285f, +-0.0691943f,0.98249f,-0.172992f, +0.0652464f,0.984331f,-0.163816f, +-0.308082f,0.909128f,-0.280306f, +-0.234588f,0.948864f,-0.211249f, +-0.164432f,0.95809f,-0.234578f, +-0.206026f,0.945244f,-0.253116f, +-0.143287f,0.989535f,-0.0170174f, +0.0124441f,0.996035f,0.0880878f, +0.00356068f,0.999352f,-0.0358152f, +0.110457f,0.993318f,-0.0334531f, +0.202646f,0.978802f,0.0296789f, +0.245502f,0.969355f,0.00893075f, +0.235742f,0.966989f,-0.096741f, +0.211469f,0.957228f,-0.197474f, +0.297424f,0.906479f,-0.299724f, +0.384843f,0.8614f,-0.331489f, +0.405425f,0.833969f,-0.374335f, +0.330388f,0.8594f,-0.390224f, +0.318232f,0.891429f,-0.32262f, +0.388106f,0.870631f,-0.302284f, +0.354731f,0.863719f,-0.357989f, +0.344798f,0.878386f,-0.330988f, +0.405293f,0.884611f,-0.230654f, +0.388923f,0.889959f,-0.23814f, +0.464087f,0.861962f,-0.20407f, +0.454884f,0.878774f,-0.144348f, +0.334448f,0.940492f,-0.0601651f, +0.155367f,0.984248f,-0.0843604f, +0.0216917f,0.991768f,-0.126198f, +-0.0136477f,0.995915f,-0.089255f, +-0.167328f,0.979282f,-0.114052f, +-0.307453f,0.946588f,-0.0971837f, +-0.335506f,0.9366f,-0.101072f, +-0.175739f,0.978185f,-0.110768f, +0.119064f,0.992411f,-0.0307238f, +0.11077f,0.993829f,0.00590121f, +0.0501349f,0.998052f,-0.0371321f, +0.0267572f,0.997581f,-0.0641572f, +-0.0614311f,0.997945f,0.0181992f, +-0.171984f,0.984492f,-0.0345973f, +-0.25243f,0.961435f,-0.109187f, +-0.338599f,0.935923f,-0.0969507f, +-0.406007f,0.913202f,-0.0349361f, +-0.506218f,0.860674f,-0.0546185f, +-0.568342f,0.8123f,-0.130983f, +-0.570141f,0.791669f,-0.219544f, +-0.495272f,0.816181f,-0.297581f, +-0.441753f,0.829099f,-0.342707f, +-0.433015f,0.854206f,-0.287802f, +-0.452692f,0.8617f,-0.229223f, +-0.349843f,0.914647f,-0.202562f, +-0.26556f,0.912134f,-0.312233f, +-0.238012f,0.870367f,-0.431058f, +0.0104117f,0.943359f,-0.331612f, +0.0744935f,0.949145f,-0.305899f, +-0.0305186f,0.956187f,-0.291161f, +-0.253914f,0.939488f,-0.229978f, +-0.449831f,0.878563f,-0.160557f, +-0.46937f,0.880955f,-0.0600792f, +-0.456075f,0.88917f,-0.0370459f, +-0.35963f,0.932902f,-0.0189682f, +-0.136797f,0.989932f,0.0363352f, +-0.0613131f,0.996495f,-0.0569106f, +-0.21207f,0.964351f,-0.158282f, +-0.303853f,0.931291f,-0.200924f, +-0.14101f,0.957182f,-0.252823f, +-0.0888984f,0.919027f,-0.384041f, +0.0067746f,0.936029f,-0.351857f, +-0.277531f,0.936633f,-0.213766f, +-0.206375f,0.947006f,-0.246148f, +-0.159145f,0.94264f,-0.293433f, +-0.254895f,0.932893f,-0.254437f, +-0.289527f,0.928279f,-0.233391f, +-0.0765713f,0.988951f,-0.126934f, +0.118605f,0.992812f,0.0160497f, +0.122094f,0.985714f,-0.116021f, +0.123131f,0.980876f,-0.150734f, +0.257926f,0.962137f,-0.0881221f, +0.397575f,0.90803f,-0.131971f, +0.301628f,0.898949f,-0.317666f, +0.360055f,0.863992f,-0.351962f, +0.391486f,0.830925f,-0.39535f, +0.399022f,0.829333f,-0.391136f, +0.323505f,0.871183f,-0.369302f, +0.290418f,0.885393f,-0.362955f, +0.422788f,0.860776f,-0.283398f, +0.400499f,0.876008f,-0.26872f, +0.272367f,0.912425f,-0.305444f, +0.289824f,0.919053f,-0.267101f, +0.375469f,0.907173f,-0.189898f, +0.450189f,0.881784f,-0.140667f, +0.386895f,0.914552f,-0.117932f, +0.236065f,0.970562f,-0.0477698f, +0.25497f,0.966484f,0.0299776f, +0.147152f,0.978905f,-0.141747f, +-0.0638684f,0.954892f,-0.290005f, +-0.198781f,0.952653f,-0.230082f, +-0.310279f,0.934977f,-0.171888f, +-0.315284f,0.933842f,-0.168923f, +-0.14676f,0.971582f,-0.185715f, +-0.0201641f,0.976785f,-0.213271f, +0.0408109f,0.997823f,-0.0518006f, +-0.000100141f,1.0f,-0.000656924f, +0.0713875f,0.992775f,0.096444f, +-0.0699693f,0.997522f,-0.0073179f, +-0.120441f,0.992484f,-0.0216487f, +-0.200799f,0.979135f,-0.0312183f, +-0.379156f,0.923729f,-0.0544518f, +-0.468756f,0.883079f,0.0209709f, +-0.451556f,0.890079f,0.0621062f, +-0.476504f,0.87674f,-0.0653536f, +-0.492274f,0.840855f,-0.22501f, +-0.481358f,0.828756f,-0.285409f, +-0.474733f,0.852404f,-0.219173f, +-0.502016f,0.852123f,-0.147874f, +-0.474734f,0.870513f,-0.12975f, +-0.344408f,0.92173f,-0.178317f, +-0.150823f,0.963991f,-0.21903f, +-0.180013f,0.935609f,-0.303696f, +-0.154788f,0.929555f,-0.334617f, +0.0226749f,0.973389f,-0.228036f, +-0.128469f,0.975007f,-0.181264f, +-0.302747f,0.952293f,-0.0385077f, +-0.427741f,0.902872f,-0.0431169f, +-0.47673f,0.871329f,-0.116249f, +-0.489254f,0.866227f,-0.101399f, +-0.407231f,0.911582f,-0.0564075f, +-0.202058f,0.978968f,-0.0281862f, +-0.00674228f,0.999486f,0.0313481f, +-0.103136f,0.994637f,-0.00773474f, +-0.196734f,0.967877f,-0.156554f, +0.0323675f,0.951182f,-0.306928f, +0.00132526f,0.886111f,-0.463472f, +-0.0819618f,0.88666f,-0.4551f, +-0.207835f,0.973361f,-0.0968142f, +-0.157163f,0.972283f,-0.173105f, +-0.187284f,0.955049f,-0.229797f, +-0.285445f,0.950862f,-0.119931f, +-0.25293f,0.964263f,-0.078892f, +-0.219599f,0.957265f,-0.188204f, +-0.0108412f,0.995374f,-0.0954668f, +0.265678f,0.963807f,-0.0221529f, +0.203794f,0.959343f,-0.195266f, +0.214345f,0.928921f,-0.301932f, +0.439386f,0.868442f,-0.22967f, +0.401404f,0.868685f,-0.290278f, +0.386804f,0.861005f,-0.330232f, +0.428054f,0.836263f,-0.342686f, +0.371108f,0.864198f,-0.339765f, +0.321515f,0.897421f,-0.302098f, +0.213518f,0.927633f,-0.306443f, +0.325579f,0.933219f,-0.151988f, +0.403183f,0.912352f,-0.0711129f, +0.337076f,0.932606f,-0.128942f, +0.295377f,0.932293f,-0.208765f, +0.330751f,0.922115f,-0.200767f, +0.392168f,0.906602f,-0.155808f, +0.373592f,0.925323f,-0.0648487f, +0.191498f,0.98018f,-0.0507507f, +0.210624f,0.977447f,-0.015309f, +0.322948f,0.945895f,0.0314047f, +0.111956f,0.981203f,-0.157186f, +-0.247376f,0.91284f,-0.32485f, +-0.344293f,0.903462f,-0.255381f, +-0.317143f,0.916625f,-0.243348f, +-0.146502f,0.958945f,-0.242819f, +-0.0529375f,0.980235f,-0.19062f, +-0.0439655f,0.993569f,-0.104344f, +-0.0681441f,0.993007f,-0.0964036f, +0.0333119f,0.999062f,-0.0276811f, +0.0418264f,0.997289f,-0.0605344f, +-0.133447f,0.982771f,-0.127878f, +-0.204776f,0.9734f,-0.102754f, +-0.405337f,0.909688f,-0.0903804f, +-0.513852f,0.857872f,0.00340788f, +-0.448907f,0.892038f,0.0524446f, +-0.345596f,0.938383f,0.000245611f, +-0.371875f,0.917654f,-0.14007f, +-0.507047f,0.834221f,-0.216744f, +-0.563482f,0.814021f,-0.140919f, +-0.549501f,0.831415f,-0.0824446f, +-0.452205f,0.89061f,-0.0482179f, +-0.283377f,0.952701f,-0.109812f, +-0.141817f,0.97445f,-0.174169f, +-0.1066f,0.981505f,-0.159008f, +-0.128743f,0.958435f,-0.254611f, +0.00656601f,0.946015f,-0.324056f, +-0.2018f,0.913066f,-0.354384f, +-0.37997f,0.904414f,-0.19406f, +-0.423353f,0.890783f,-0.165163f, +-0.446411f,0.883929f,-0.139235f, +-0.512365f,0.844229f,-0.157352f, +-0.38243f,0.91272f,-0.143839f, +-0.20154f,0.953013f,-0.226157f, +-0.104673f,0.977037f,-0.185586f, +-0.0458745f,0.998873f,-0.0121567f, +-0.0345945f,0.993617f,-0.107371f, +0.172752f,0.948616f,-0.265111f, +0.0733608f,0.946968f,-0.312842f, +-0.16546f,0.93251f,-0.321012f, +-0.129843f,0.991294f,-0.0218587f, +-0.0514732f,0.996939f,-0.0588533f, +-0.139666f,0.979954f,-0.142066f, +-0.409538f,0.893138f,-0.185964f, +-0.25948f,0.963277f,-0.0690542f, +-0.106228f,0.993322f,-0.0450175f, +-0.047863f,0.993002f,-0.107966f, +0.238746f,0.962198f,-0.131057f, +0.395076f,0.900486f,-0.181771f, +0.285693f,0.874669f,-0.391577f, +0.358513f,0.848133f,-0.39005f, +0.400938f,0.884343f,-0.239137f, +0.415724f,0.899223f,-0.136277f, +0.438653f,0.894164f,-0.0897495f, +0.361082f,0.930821f,-0.0565009f, +0.321158f,0.946416f,-0.0339725f, +0.242073f,0.961641f,-0.129024f, +0.199607f,0.93926f,-0.279192f, +0.404284f,0.887623f,-0.220636f, +0.424881f,0.860893f,-0.279892f, +0.291182f,0.870529f,-0.396727f, +0.302468f,0.897545f,-0.320822f, +0.33835f,0.898885f,-0.278433f, +0.289098f,0.929341f,-0.229667f, +0.170367f,0.971163f,-0.166783f, +0.129237f,0.986609f,-0.0995005f, +0.305057f,0.951694f,0.0349234f, +0.306439f,0.951736f,-0.0171507f, +-0.0808802f,0.976235f,-0.201056f, +-0.37625f,0.871862f,-0.313516f, +-0.307717f,0.906797f,-0.28815f, +-0.221648f,0.946026f,-0.236446f, +-0.153972f,0.983161f,-0.0984244f, +-0.108206f,0.992418f,-0.0582996f, +-0.0581427f,0.997361f,-0.0434687f, +0.00296039f,0.999365f,-0.0355116f, +0.0891034f,0.995894f,-0.0160169f, +-0.110645f,0.991801f,-0.0639364f, +-0.218461f,0.975223f,-0.0348525f, +-0.395365f,0.918398f,-0.0152307f, +-0.576836f,0.816159f,-0.0338453f, +-0.444941f,0.895556f,-0.00249309f, +-0.286239f,0.957764f,-0.0274641f, +-0.294715f,0.953259f,-0.0666355f, +-0.477956f,0.87064f,-0.116377f, +-0.574643f,0.800737f,-0.169131f, +-0.54804f,0.808388f,-0.214852f, +-0.442187f,0.863382f,-0.242986f, +-0.246722f,0.934143f,-0.257887f, +-0.157124f,0.964153f,-0.213827f, +-0.112706f,0.987993f,-0.10568f, +-0.0332674f,0.993709f,-0.106936f, +0.112688f,0.981964f,-0.151814f, +-0.167f,0.962022f,-0.215928f, +-0.466198f,0.854366f,-0.229606f, +-0.414399f,0.885329f,-0.210869f, +-0.461383f,0.855213f,-0.236084f, +-0.488245f,0.847976f,-0.206287f, +-0.351309f,0.900136f,-0.257559f, +-0.14601f,0.942734f,-0.29989f, +-0.222931f,0.937875f,-0.265879f, +-0.195469f,0.970505f,-0.141106f, +0.07525f,0.994532f,-0.0724173f, +0.279727f,0.951429f,-0.128592f, +0.077712f,0.980159f,-0.182341f, +-0.20264f,0.956685f,-0.209022f, +-0.0986596f,0.987061f,-0.126403f, +-0.0477559f,0.985147f,-0.164941f, +-0.0669351f,0.983547f,-0.167793f, +-0.331517f,0.915331f,-0.228616f, +-0.350669f,0.900109f,-0.258526f, +-0.179805f,0.971282f,-0.155824f, +0.0156578f,0.989915f,-0.140797f, +0.301547f,0.9226f,-0.240579f, +0.457383f,0.852861f,-0.25185f, +0.449776f,0.84917f,-0.276789f, +0.26609f,0.885033f,-0.381984f, +0.182331f,0.952085f,-0.245538f, +0.260541f,0.964562f,-0.0416928f, +0.408684f,0.907067f,0.101033f, +0.342263f,0.936545f,0.0757594f, +0.318298f,0.944991f,0.0753604f, +0.467785f,0.882822f,0.0424513f, +0.409568f,0.864687f,-0.290809f, +0.379738f,0.82358f,-0.421325f, +0.451329f,0.792384f,-0.410402f, +0.275091f,0.868881f,-0.411547f, +0.161796f,0.92881f,-0.333367f, +0.286521f,0.932696f,-0.219053f, +0.272475f,0.944744f,-0.182252f, +0.119383f,0.965719f,-0.230508f, +-0.0212448f,0.971989f,-0.234063f, +0.226311f,0.969491f,-0.094178f, +0.326176f,0.942844f,-0.068215f, +0.104404f,0.994209f,-0.0254499f, +-0.295807f,0.921372f,-0.252133f, +-0.383855f,0.886842f,-0.257228f, +-0.359597f,0.921141f,-0.148961f, +-0.240318f,0.969399f,-0.0501282f, +-0.0922578f,0.994071f,-0.0575481f, +-0.0797027f,0.995693f,-0.047355f, +-0.026569f,0.999636f,0.00472767f, +0.105393f,0.994402f,0.00758912f, +-0.0968377f,0.99427f,-0.0452707f, +-0.304918f,0.952227f,0.0169656f, +-0.404524f,0.901318f,0.154875f, +-0.513873f,0.850873f,0.109318f, +-0.450348f,0.892744f,-0.0139455f, +-0.274075f,0.961559f,-0.0169546f, +-0.246789f,0.966677f,-0.068048f, +-0.421796f,0.89143f,-0.165651f, +-0.530762f,0.820949f,-0.210556f, +-0.518596f,0.828643f,-0.210734f, +-0.419929f,0.882924f,-0.210013f, +-0.267086f,0.925885f,-0.26721f, +-0.260528f,0.916111f,-0.304739f, +-0.212437f,0.941505f,-0.261606f, +-0.048105f,0.973033f,-0.225594f, +0.0765563f,0.979806f,-0.184712f, +-0.093108f,0.98921f,-0.113109f, +-0.45825f,0.862094f,-0.216335f, +-0.388948f,0.902314f,-0.185873f, +-0.448149f,0.871913f,-0.197307f, +-0.488741f,0.854988f,-0.173574f, +-0.313337f,0.916762f,-0.247724f, +-0.157546f,0.938004f,-0.308753f, +-0.267357f,0.911027f,-0.313926f, +-0.236818f,0.920159f,-0.311809f, +0.000164176f,0.954985f,-0.296656f, +0.271822f,0.944232f,-0.185848f, +0.151331f,0.970946f,-0.185371f, +-0.118147f,0.962507f,-0.244174f, +0.026977f,0.993643f,-0.109301f, +0.00824696f,0.988318f,-0.152184f, +-0.049843f,0.98983f,-0.133236f, +-0.292853f,0.946012f,-0.138915f, +-0.402779f,0.899681f,-0.168355f, +-0.216565f,0.962959f,-0.160656f, +0.0811851f,0.971223f,-0.223909f, +0.376654f,0.888442f,-0.262304f, +0.412611f,0.862287f,-0.293621f, +0.420494f,0.885689f,-0.196825f, +0.303261f,0.948914f,-0.0871512f, +0.0927021f,0.987654f,-0.12628f, +0.131263f,0.975894f,-0.174359f, +0.34789f,0.928255f,-0.131586f, +0.388684f,0.916314f,-0.0964015f, +0.334363f,0.935247f,-0.116251f, +0.500896f,0.857152f,-0.119971f, +0.598542f,0.784881f,-0.160341f, +0.47847f,0.803478f,-0.354245f, +0.40143f,0.813052f,-0.421663f, +0.177917f,0.923323f,-0.340324f, +0.0444056f,0.967329f,-0.249605f, +0.182957f,0.975679f,-0.12074f, +0.298547f,0.954355f,0.00877178f, +0.20958f,0.975318f,-0.0695111f, +0.014388f,0.988042f,-0.153512f, +0.159715f,0.970499f,-0.180618f, +0.22067f,0.966546f,-0.130745f, +0.121564f,0.992499f,-0.0129668f, +-0.106928f,0.989668f,-0.0955226f, +-0.432009f,0.877086f,-0.209972f, +-0.412195f,0.894243f,-0.174429f, +-0.247992f,0.954923f,-0.163162f, +-0.103668f,0.985418f,-0.134925f, +-0.118626f,0.990103f,-0.0749928f, +-0.0679366f,0.995617f,-0.0642786f, +0.157737f,0.986207f,-0.0501565f, +-0.132086f,0.989105f,-0.064997f, +-0.385668f,0.914108f,0.125169f, +-0.489653f,0.859555f,0.146305f, +-0.451033f,0.881762f,0.138074f, +-0.379544f,0.923663f,0.0528468f, +-0.267976f,0.962936f,0.0307148f, +-0.154653f,0.986101f,0.0607174f, +-0.285519f,0.958009f,-0.0264139f, +-0.517333f,0.83498f,-0.187551f, +-0.544673f,0.81339f,-0.204273f, +-0.443255f,0.872475f,-0.205697f, +-0.212541f,0.959106f,-0.18693f, +-0.144834f,0.956217f,-0.254307f, +-0.219765f,0.912031f,-0.346271f, +-0.054698f,0.959311f,-0.277002f, +-0.0226538f,0.964658f,-0.262528f, +-0.09277f,0.980401f,-0.173803f, +-0.427129f,0.87184f,-0.2397f, +-0.458168f,0.877303f,-0.142906f, +-0.456008f,0.884075f,-0.102317f, +-0.457836f,0.873049f,-0.167843f, +-0.276231f,0.922652f,-0.269091f, +-0.0986428f,0.965162f,-0.242345f, +-0.166497f,0.944239f,-0.284061f, +-0.221568f,0.881867f,-0.416194f, +-0.047486f,0.902488f,-0.428089f, +0.159799f,0.906084f,-0.391761f, +0.154437f,0.936571f,-0.314616f, +-0.0388024f,0.943344f,-0.329539f, +0.0179311f,0.971802f,-0.235116f, +-0.0317957f,0.972144f,-0.232219f, +-0.108238f,0.982139f,-0.153906f, +-0.294778f,0.950488f,-0.098378f, +-0.31352f,0.940894f,-0.128155f, +-0.158161f,0.944104f,-0.289226f, +0.136392f,0.925587f,-0.353108f, +0.369725f,0.858345f,-0.355736f, +0.408427f,0.863142f,-0.296941f, +0.264495f,0.934318f,-0.238939f, +0.231394f,0.968992f,-0.0866717f, +0.180537f,0.980662f,-0.0755592f, +0.289728f,0.94884f,-0.125539f, +0.338081f,0.901985f,-0.268559f, +0.344111f,0.905129f,-0.249658f, +0.337921f,0.897299f,-0.284014f, +0.46242f,0.831252f,-0.308526f, +0.625979f,0.756355f,-0.18994f, +0.59942f,0.766009f,-0.232218f, +0.396651f,0.850096f,-0.346416f, +0.113051f,0.922761f,-0.368417f, +-0.0568672f,0.928859f,-0.366041f, +0.0370994f,0.962262f,-0.269583f, +0.21844f,0.959083f,-0.180121f, +0.248457f,0.958661f,-0.138705f, +0.0562715f,0.995806f,-0.072134f, +0.151796f,0.987439f,-0.0438309f, +0.213126f,0.976907f,0.0151789f, +0.0825188f,0.995896f,-0.0371849f, +-0.0293603f,0.995761f,-0.0871655f, +-0.339382f,0.929166f,-0.146528f, +-0.407976f,0.887929f,-0.212458f, +-0.300706f,0.928797f,-0.216592f, +-0.171876f,0.971688f,-0.162117f, +-0.133134f,0.975354f,-0.175954f, +-0.0436112f,0.969589f,-0.240823f, +0.0955252f,0.97277f,-0.211171f, +-0.222971f,0.974797f,-0.00733171f, +-0.502187f,0.842082f,0.19674f, +-0.406382f,0.878535f,0.251057f, +-0.403841f,0.907763f,0.113486f, +-0.295941f,0.954472f,0.0374491f, +-0.309098f,0.948653f,-0.0672074f, +-0.212726f,0.977025f,0.0130525f, +-0.199979f,0.978912f,0.0417118f, +-0.374584f,0.922961f,-0.0884893f, +-0.481248f,0.836641f,-0.261597f, +-0.419239f,0.839768f,-0.345005f, +-0.269419f,0.905569f,-0.327654f, +-0.084614f,0.973021f,-0.214643f, +-0.193736f,0.935164f,-0.296537f, +-0.190273f,0.932167f,-0.307995f, +-0.0917672f,0.986648f,-0.134552f, +-0.101923f,0.994749f,0.009248f, +-0.329353f,0.943234f,-0.0428565f, +-0.527408f,0.832391f,-0.170191f, +-0.427451f,0.895563f,-0.123505f, +-0.337252f,0.917187f,-0.212202f, +-0.254472f,0.911026f,-0.324462f, +-0.191138f,0.941948f,-0.276043f, +-0.0895186f,0.969134f,-0.229708f, +-0.115141f,0.935532f,-0.33395f, +-0.0316994f,0.925937f,-0.376346f, +0.117945f,0.920189f,-0.373285f, +0.121803f,0.934924f,-0.333287f, +-0.0046923f,0.925271f,-0.379279f, +0.0524128f,0.95708f,-0.285046f, +-0.0476851f,0.956392f,-0.288167f, +-0.185718f,0.956668f,-0.224263f, +-0.292875f,0.939689f,-0.176661f, +-0.212138f,0.937073f,-0.277295f, +0.00215598f,0.9095f,-0.415698f, +0.155074f,0.855231f,-0.494501f, +0.3372f,0.836708f,-0.431528f, +0.272726f,0.886233f,-0.374449f, +0.193484f,0.944931f,-0.263949f, +0.192169f,0.938969f,-0.285322f, +0.141281f,0.932743f,-0.331708f, +0.278032f,0.931044f,-0.236339f, +0.426985f,0.871432f,-0.241434f, +0.368362f,0.861689f,-0.349f, +0.400587f,0.825418f,-0.397762f, +0.451323f,0.785144f,-0.424095f, +0.523643f,0.765884f,-0.373121f, +0.603289f,0.753586f,-0.261056f, +0.44978f,0.832328f,-0.323928f, +0.156509f,0.915232f,-0.371289f, +-0.0704135f,0.915939f,-0.395092f, +-0.00319557f,0.926331f,-0.376696f, +0.166676f,0.911893f,-0.37506f, +0.102989f,0.962696f,-0.250219f, +-0.0387958f,0.995347f,-0.0881961f, +0.0653507f,0.992864f,-0.0997527f, +0.179449f,0.98367f,-0.0138117f, +0.177828f,0.983985f,0.012264f, +0.0645076f,0.995168f,-0.0740203f, +-0.292502f,0.938695f,-0.182468f, +-0.400433f,0.889464f,-0.220243f, +-0.318802f,0.923541f,-0.213161f, +-0.169897f,0.961934f,-0.214052f, +-0.0267051f,0.972116f,-0.232975f, +-0.00536052f,0.964395f,-0.264412f, +-0.100769f,0.988596f,-0.111905f, +-0.404303f,0.910751f,0.0840968f, +-0.594207f,0.803932f,0.0247338f, +-0.396136f,0.914658f,0.0804795f, +-0.304433f,0.952514f,0.00620435f, +-0.201276f,0.977901f,-0.0565476f, +-0.264949f,0.959844f,-0.0922019f, +-0.227773f,0.971084f,-0.0715179f, +-0.172114f,0.969698f,-0.173387f, +-0.26936f,0.945102f,-0.185006f, +-0.392685f,0.904465f,-0.166556f, +-0.407044f,0.896103f,-0.176958f, +-0.40747f,0.889993f,-0.204647f, +-0.189782f,0.978511f,-0.0806113f, +-0.0480587f,0.996223f,-0.0723184f, +-0.217275f,0.958525f,-0.184451f, +-0.306094f,0.944116f,-0.122276f, +-0.254593f,0.966558f,0.0308049f, +-0.20196f,0.972664f,0.114613f, +-0.409794f,0.899925f,-0.14901f, +-0.415034f,0.857771f,-0.303274f, +-0.263165f,0.89665f,-0.356039f, +-0.215387f,0.884962f,-0.412857f, +-0.225079f,0.887943f,-0.401119f, +-0.0773061f,0.916142f,-0.393328f, +-0.0308036f,0.905486f,-0.423257f, +-0.0371917f,0.883129f,-0.467653f, +0.0716369f,0.893813f,-0.442681f, +0.12997f,0.919319f,-0.371429f, +0.119867f,0.921216f,-0.370126f, +0.0228827f,0.984493f,-0.173923f, +-0.0834452f,0.988816f,-0.123614f, +-0.247718f,0.964917f,-0.0870125f, +-0.254118f,0.961997f,-0.0999321f, +-0.0671834f,0.977202f,-0.201403f, +0.157483f,0.940773f,-0.300243f, +0.164503f,0.92764f,-0.335294f, +0.27582f,0.929794f,-0.243733f, +0.209142f,0.946949f,-0.244024f, +0.183638f,0.949161f,-0.255677f, +0.277174f,0.906106f,-0.319605f, +0.178788f,0.896597f,-0.405153f, +0.185529f,0.860132f,-0.475134f, +0.438868f,0.800307f,-0.408538f, +0.441024f,0.788796f,-0.428135f, +0.397261f,0.791714f,-0.464083f, +0.440809f,0.77176f,-0.458338f, +0.455755f,0.768172f,-0.449666f, +0.535299f,0.762932f,-0.362477f, +0.450448f,0.842352f,-0.295872f, +0.136515f,0.937333f,-0.320579f, +-0.0637901f,0.937145f,-0.343061f, +-0.0112309f,0.935306f,-0.353662f, +0.108413f,0.948157f,-0.298738f, +-0.0660356f,0.972239f,-0.224477f, +-0.07256f,0.985988f,-0.150208f, +0.0814078f,0.980504f,-0.178842f, +0.133209f,0.989139f,-0.0621265f, +0.112681f,0.993117f,-0.0319677f, +0.144875f,0.987157f,0.0673239f, +-0.178705f,0.983714f,-0.0192655f, +-0.383305f,0.919432f,-0.0878717f, +-0.311703f,0.944518f,-0.103569f, +-0.170547f,0.974222f,-0.147663f, +-0.0584686f,0.987712f,-0.144938f, +-0.130239f,0.988008f,-0.0829397f, +-0.30957f,0.949755f,0.0461837f, +-0.426068f,0.896859f,0.118784f, +-0.505712f,0.862298f,-0.0263905f, +-0.384432f,0.913927f,-0.130189f, +-0.233817f,0.957708f,-0.167708f, +-0.196686f,0.961804f,-0.190386f, +-0.272431f,0.94059f,-0.202662f, +-0.180772f,0.950727f,-0.251872f, +-0.0565853f,0.956064f,-0.287647f, +-0.288561f,0.926858f,-0.240141f, +-0.491099f,0.856076f,-0.161104f, +-0.419638f,0.904096f,-0.0807095f, +-0.388583f,0.916169f,-0.0981701f, +-0.261262f,0.961028f,-0.0903754f, +-0.0632456f,0.997064f,0.0431658f, +-0.169715f,0.97859f,0.116442f, +-0.344027f,0.938297f,0.0352825f, +-0.314669f,0.949192f,0.00417096f, +-0.192981f,0.980434f,0.0388389f, +-0.184602f,0.98279f,-0.00683269f, +-0.246496f,0.934378f,-0.25725f, +-0.19921f,0.861846f,-0.466409f, +-0.140436f,0.848535f,-0.510163f, +-0.20288f,0.807079f,-0.554493f, +-0.11519f,0.832336f,-0.542169f, +0.00924053f,0.875455f,-0.483211f, +-0.00888073f,0.876341f,-0.48161f, +0.00107193f,0.907613f,-0.419807f, +0.021101f,0.930448f,-0.365817f, +0.0745313f,0.948396f,-0.308205f, +-0.200438f,0.964136f,-0.17397f, +-0.166231f,0.985214f,-0.0414839f, +-0.252324f,0.967639f,-0.00281073f, +-0.16447f,0.986195f,-0.0192238f, +0.0101706f,0.983613f,-0.180006f, +0.16229f,0.966979f,-0.196502f, +0.152128f,0.981833f,-0.113406f, +0.194455f,0.973444f,-0.120809f, +0.334057f,0.938492f,-0.0874058f, +0.243016f,0.928299f,-0.281434f, +0.337071f,0.885295f,-0.320369f, +0.298461f,0.876938f,-0.376698f, +0.311828f,0.819683f,-0.480502f, +0.369257f,0.755567f,-0.54108f, +0.401798f,0.784012f,-0.473163f, +0.404891f,0.784738f,-0.469309f, +0.444437f,0.782155f,-0.436702f, +0.466084f,0.794919f,-0.388419f, +0.447341f,0.805216f,-0.389247f, +0.362297f,0.887389f,-0.285098f, +0.179937f,0.962799f,-0.201595f, +0.000795301f,0.958246f,-0.285946f, +-0.0439986f,0.938528f,-0.342389f, +0.000314903f,0.959745f,-0.280871f, +-0.0200826f,0.975564f,-0.218794f, +-0.0669112f,0.936012f,-0.345551f, +0.0051897f,0.948012f,-0.318192f, +0.0134178f,0.970832f,-0.239387f, +0.036317f,0.978504f,-0.203005f, +0.0625457f,0.996542f,-0.0547064f, +-0.151505f,0.986626f,0.0601296f, +-0.354535f,0.929709f,0.0997293f, +-0.323458f,0.940866f,0.100727f, +-0.112965f,0.981029f,0.157548f, +-0.108156f,0.989168f,0.0992381f, +-0.141093f,0.979303f,0.145114f, +-0.335564f,0.940028f,0.061184f, +-0.404784f,0.910739f,0.081883f, +-0.415621f,0.909054f,0.0296628f, +-0.326024f,0.941449f,-0.0859172f, +-0.204455f,0.961807f,-0.182004f, +-0.198427f,0.946732f,-0.253624f, +-0.160629f,0.949f,-0.27129f, +-0.122223f,0.918206f,-0.376775f, +-0.161284f,0.939678f,-0.301651f, +-0.374966f,0.911783f,-0.167489f, +-0.467696f,0.856498f,-0.218336f, +-0.443475f,0.843003f,-0.304427f, +-0.385194f,0.898165f,-0.211955f, +-0.377418f,0.917998f,-0.121804f, +-0.264639f,0.962925f,0.0523651f, +-0.211739f,0.961017f,0.177801f, +-0.229995f,0.957255f,0.175401f, +-0.280377f,0.956102f,0.0851875f, +-0.20016f,0.97825f,0.0544282f, +-0.10573f,0.994257f,-0.0165441f, +0.0203896f,0.991211f,-0.130708f, +-0.0236073f,0.94884f,-0.314873f, +-0.0941765f,0.92043f,-0.379394f, +-0.167941f,0.897458f,-0.407879f, +-0.187085f,0.877031f,-0.442511f, +-0.0729267f,0.89358f,-0.44294f, +-0.0781669f,0.903365f,-0.421688f, +-0.0898224f,0.927661f,-0.362461f, +-0.0306254f,0.944826f,-0.326139f, +0.00767666f,0.952077f,-0.305762f, +-0.288656f,0.939633f,-0.183761f, +-0.235623f,0.952993f,-0.190489f, +-0.273085f,0.931861f,-0.238874f, +-0.0949222f,0.974332f,-0.204123f, +0.149266f,0.955245f,-0.255397f, +0.0666117f,0.957576f,-0.280376f, +0.127398f,0.979355f,-0.156952f, +0.209457f,0.954497f,-0.21228f, +0.367092f,0.913409f,-0.175864f, +0.415953f,0.865553f,-0.278928f, +0.34245f,0.832959f,-0.434635f, +0.340781f,0.830404f,-0.440793f, +0.395293f,0.802521f,-0.446882f, +0.405952f,0.792834f,-0.454552f, +0.385024f,0.788348f,-0.479858f, +0.365166f,0.783008f,-0.503539f, +0.371074f,0.838688f,-0.39863f, +0.42233f,0.859897f,-0.286732f, +0.440629f,0.882917f,-0.162183f, +0.299827f,0.949298f,-0.0945333f, +0.141695f,0.979344f,-0.144247f, +0.039666f,0.992248f,-0.117771f, +0.021245f,0.997585f,-0.0661304f, +-0.0594041f,0.983411f,-0.17139f, +0.0611812f,0.981318f,-0.182404f, +0.0186916f,0.932529f,-0.360611f, +-0.0300853f,0.91754f,-0.396504f, +-0.00135599f,0.922081f,-0.386995f, +-0.0351954f,0.956784f,-0.28866f, +-0.108108f,0.976189f,-0.188065f, +-0.279221f,0.950183f,-0.13852f, +-0.398641f,0.914814f,-0.0648175f, +-0.383626f,0.922668f,-0.0389249f, +-0.188191f,0.977628f,0.0939533f, +-0.083441f,0.973103f,0.21473f, +-0.0631642f,0.980575f,0.185698f, +-0.269017f,0.963031f,0.0141438f, +-0.4376f,0.89917f,-0.000301879f, +-0.339736f,0.940513f,0.00384959f, +-0.235638f,0.967987f,-0.0864624f, +-0.0773761f,0.988655f,-0.128744f, +-0.0852549f,0.968269f,-0.234917f, +-0.114948f,0.939941f,-0.3214f, +-0.156571f,0.928217f,-0.337488f, +-0.29563f,0.924155f,-0.241951f, +-0.401682f,0.899225f,-0.173337f, +-0.351799f,0.915761f,-0.193956f, +-0.391021f,0.882077f,-0.262761f, +-0.525453f,0.810665f,-0.258305f, +-0.504092f,0.859496f,-0.0846014f, +-0.362403f,0.931317f,0.0362275f, +-0.27912f,0.954258f,0.107159f, +-0.207619f,0.961802f,0.178414f, +-0.228638f,0.970139f,0.0809669f, +-0.12077f,0.992669f,0.00484841f, +0.0304882f,0.99448f,-0.100401f, +0.0674392f,0.979801f,-0.18826f, +0.0351304f,0.9953f,-0.090241f, +-0.0704736f,0.995263f,-0.0669708f, +-0.129706f,0.981562f,-0.1404f, +-0.122442f,0.956888f,-0.263387f, +-0.0356665f,0.922731f,-0.38379f, +-0.0454106f,0.896226f,-0.441267f, +-0.0870705f,0.865568f,-0.493164f, +-0.0312927f,0.854755f,-0.518087f, +-0.0110302f,0.85359f,-0.520829f, +-0.135251f,0.990349f,0.0302781f, +-0.120846f,0.991438f,-0.049458f, +-0.156404f,0.974115f,-0.163209f, +-0.121903f,0.951948f,-0.280952f, +0.0966131f,0.959924f,-0.263082f, +0.0624341f,0.96714f,-0.24646f, +0.0557469f,0.94749f,-0.31489f, +0.245712f,0.928812f,-0.27737f, +0.339947f,0.895451f,-0.28741f, +0.505833f,0.828917f,-0.238808f, +0.492153f,0.815708f,-0.303985f, +0.325713f,0.824266f,-0.463138f, +0.357884f,0.8174f,-0.451416f, +0.423911f,0.828952f,-0.364879f, +0.465983f,0.818349f,-0.3364f, +0.340136f,0.856815f,-0.387524f, +0.250037f,0.902839f,-0.349804f, +0.270063f,0.93551f,-0.227788f, +0.268197f,0.961943f,0.0523086f, +0.314452f,0.921737f,0.226982f, +0.230483f,0.962611f,0.142328f, +-0.0337231f,0.996519f,0.0762456f, +-0.0478467f,0.987694f,0.1489f, +0.0777224f,0.977564f,0.195776f, +0.137813f,0.987309f,0.0789204f, +0.213773f,0.976881f,-0.00209812f, +0.0678985f,0.982243f,-0.174896f, +-0.118448f,0.956882f,-0.26523f, +-0.229961f,0.9707f,-0.0697049f, +-0.144208f,0.98561f,0.0881926f, +-0.198479f,0.979386f,0.0375393f, +-0.401292f,0.909987f,-0.104347f, +-0.400254f,0.91005f,-0.107726f, +-0.346067f,0.932825f,-0.100374f, +-0.193125f,0.981161f,0.00517742f, +-0.0334943f,0.995589f,0.0876359f, +-0.09901f,0.987334f,0.12397f, +-0.411919f,0.909058f,-0.0627387f, +-0.33988f,0.934279f,-0.107727f, +-0.163445f,0.980417f,-0.109859f, +-0.094399f,0.976137f,-0.195566f, +-0.0281723f,0.98965f,-0.140708f, +-0.0765865f,0.985816f,-0.149338f, +-0.168645f,0.974838f,-0.145776f, +-0.316363f,0.934327f,-0.164156f, +-0.429172f,0.879196f,-0.206943f, +-0.428946f,0.898522f,-0.0930795f, +-0.397223f,0.909843f,0.12f, +-0.511164f,0.850782f,0.12199f, +-0.553545f,0.831305f,-0.0501975f, +-0.425265f,0.901367f,-0.0817687f, +-0.377377f,0.925701f,-0.0257517f, +-0.226427f,0.969468f,0.0941363f, +-0.0709665f,0.993431f,0.0897693f, +-0.0343935f,0.997803f,-0.0566276f, +0.136725f,0.981098f,-0.136942f, +-0.000388307f,0.974615f,-0.223888f, +-0.143125f,0.988947f,-0.0387096f, +-0.0654844f,0.993475f,0.0933713f, +0.0107967f,0.999865f,0.0124207f, +0.0463655f,0.990074f,-0.132676f, +0.111072f,0.958636f,-0.262069f, +0.052211f,0.918497f,-0.391967f, +0.014765f,0.869476f,-0.493754f, +-0.00446669f,0.826302f,-0.56321f, +-0.00312167f,0.829643f,-0.558286f, +-0.205328f,0.971118f,-0.121531f, +-0.107279f,0.990692f,-0.0837913f, +-0.0655817f,0.993795f,-0.089834f, +-0.0669083f,0.985851f,-0.15369f, +0.0877486f,0.98832f,-0.124596f, +0.169572f,0.978484f,-0.117533f, +0.160152f,0.950603f,-0.265903f, +0.208233f,0.926f,-0.314903f, +0.349792f,0.904675f,-0.243329f, +0.449891f,0.870303f,-0.200426f, +0.566229f,0.816333f,-0.113956f, +0.48817f,0.833849f,-0.257655f, +0.363235f,0.831342f,-0.420631f, +0.324206f,0.826771f,-0.459718f, +0.3997f,0.840833f,-0.365021f, +0.353025f,0.906211f,-0.232714f, +0.219616f,0.962891f,-0.156874f, +0.0720827f,0.994934f,-0.0700696f, +0.045678f,0.994046f,0.0989266f, +0.213575f,0.964796f,0.153475f, +0.24905f,0.930442f,0.268798f, +0.0777133f,0.945053f,0.317546f, +-0.128028f,0.977296f,0.168824f, +0.0217263f,0.951068f,0.308215f, +0.207313f,0.918764f,0.335998f, +0.282654f,0.924456f,0.255906f, +0.201157f,0.96204f,0.184429f, +-0.110233f,0.981395f,0.157205f, +-0.355659f,0.909169f,0.216606f, +-0.21295f,0.947904f,0.236917f, +-0.107393f,0.959263f,0.261306f, +-0.278087f,0.947596f,0.157257f, +-0.393558f,0.918794f,0.0304824f, +-0.302068f,0.952957f,-0.0250724f, +-0.213276f,0.970666f,-0.110997f, +-0.166999f,0.978773f,-0.118807f, +-0.142246f,0.989828f,0.00258048f, +-0.283745f,0.958854f,0.0093455f, +-0.336957f,0.941016f,-0.0308147f, +-0.113565f,0.9931f,-0.02925f, +-0.0231129f,0.991621f,-0.127093f, +-0.107284f,0.981887f,-0.156166f, +-0.121783f,0.990389f,-0.0655664f, +-0.179469f,0.983757f,0.00373427f, +-0.267261f,0.963295f,0.0251965f, +-0.419417f,0.907445f,0.0251735f, +-0.582729f,0.80835f,0.0836507f, +-0.554692f,0.78035f,0.288741f, +-0.368624f,0.840437f,0.397218f, +-0.336016f,0.929619f,0.151335f, +-0.379048f,0.912637f,-0.153022f, +-0.410461f,0.89244f,-0.187275f, +-0.310698f,0.938768f,-0.148932f, +-0.0772428f,0.993562f,-0.0828798f, +0.0559112f,0.996518f,-0.0618564f, +0.218481f,0.971621f,-0.090653f, +0.0070055f,0.988587f,-0.150488f, +-0.287385f,0.949521f,-0.125778f, +-0.0963797f,0.992515f,-0.0749989f, +0.0940601f,0.994076f,-0.0544632f, +0.147534f,0.985277f,-0.0863886f, +0.20617f,0.964455f,-0.165287f, +0.228919f,0.941159f,-0.248628f, +0.142687f,0.889558f,-0.433967f, +0.0525074f,0.86193f,-0.5043f, +-0.0400559f,0.852931f,-0.520485f, +-0.12929f,0.965503f,-0.226025f, +-0.12119f,0.954637f,-0.271994f, +-0.0677494f,0.970158f,-0.232815f, +-0.0658176f,0.978188f,-0.197017f, +0.00868199f,0.985201f,-0.171183f, +0.183883f,0.977449f,-0.103828f, +0.283397f,0.948052f,-0.144513f, +0.244002f,0.935244f,-0.256481f, +0.251457f,0.918413f,-0.305429f, +0.421894f,0.885288f,-0.195626f, +0.539016f,0.82675f,-0.161076f, +0.595125f,0.795068f,-0.117014f, +0.542945f,0.81823f,-0.188971f, +0.36087f,0.878337f,-0.313523f, +0.249934f,0.94591f,-0.206849f, +0.203095f,0.978645f,0.0317209f, +0.0808087f,0.992314f,0.0937131f, +0.015528f,0.990219f,0.138653f, +0.01799f,0.994881f,0.09944f, +0.195411f,0.975412f,0.101915f, +0.0694818f,0.977162f,0.200816f, +0.0667035f,0.917371f,0.392404f, +-0.00815505f,0.942331f,0.334582f, +-0.124548f,0.965608f,0.228228f, +0.172601f,0.943034f,0.284421f, +0.392995f,0.877789f,0.273937f, +0.148864f,0.962548f,0.226586f, +-0.160978f,0.90924f,0.383887f, +-0.338041f,0.865118f,0.370538f, +-0.158685f,0.913484f,0.374654f, +-0.085827f,0.934088f,0.346573f, +-0.160284f,0.956319f,0.244467f, +-0.286424f,0.955431f,0.0715057f, +-0.239888f,0.970684f,0.0150701f, +-0.160609f,0.986985f,0.00807186f, +-0.109896f,0.993313f,-0.0353894f, +-0.197211f,0.969041f,-0.148551f, +-0.329877f,0.939761f,-0.0896172f, +-0.308832f,0.948199f,-0.0744408f, +-0.098416f,0.980296f,-0.171271f, +0.0274733f,0.990192f,-0.136989f, +-0.0841565f,0.99088f,-0.105235f, +-0.256459f,0.960709f,-0.106143f, +-0.249667f,0.95978f,0.128406f, +-0.305999f,0.931391f,0.197168f, +-0.484241f,0.852569f,0.196565f, +-0.610379f,0.753144f,0.245383f, +-0.585787f,0.783089f,0.208867f, +-0.367515f,0.91758f,0.151588f, +-0.0411995f,0.989239f,0.140389f, +-0.109078f,0.987353f,-0.115051f, +-0.380949f,0.866858f,-0.321615f, +-0.342318f,0.88779f,-0.307647f, +-0.12792f,0.955198f,-0.266896f, +0.0278952f,0.967981f,-0.249469f, +0.188442f,0.9544f,-0.231539f, +0.052008f,0.978364f,-0.200246f, +-0.225418f,0.931417f,-0.285742f, +-0.134566f,0.926089f,-0.352493f, +0.0345745f,0.959769f,-0.278653f, +0.174695f,0.953806f,-0.24441f, +0.227273f,0.930386f,-0.287627f, +0.325716f,0.918321f,-0.224934f, +0.329407f,0.888239f,-0.32019f, +0.0905336f,0.875389f,-0.474867f, +-0.0331275f,0.86706f,-0.497102f, +0.0288126f,0.978255f,-0.205394f, +-0.0838329f,0.954569f,-0.285956f, +-0.140323f,0.954698f,-0.262415f, +-0.112432f,0.972197f,-0.205408f, +0.0092799f,0.981035f,-0.193608f, +0.142017f,0.962963f,-0.229203f, +0.310781f,0.933484f,-0.17895f, +0.359578f,0.919553f,-0.158514f, +0.334745f,0.907674f,-0.253129f, +0.345814f,0.873436f,-0.342815f, +0.500723f,0.821828f,-0.271799f, +0.538977f,0.812424f,-0.22242f, +0.523422f,0.839245f,-0.147303f, +0.340441f,0.940266f,0.000412888f, +0.0152874f,0.997305f,0.0717554f, +0.0533145f,0.966764f,0.250049f, +0.112464f,0.954457f,0.276338f, +0.109039f,0.955163f,0.275271f, +0.0445431f,0.979533f,0.196291f, +0.165433f,0.962373f,0.21557f, +-0.0715535f,0.977821f,0.196841f, +-0.0891149f,0.939351f,0.331178f, +0.117094f,0.910023f,0.397676f, +0.030807f,0.968216f,0.248212f, +0.157233f,0.982334f,0.101481f, +0.403254f,0.903723f,0.143774f, +0.0482774f,0.97679f,0.208689f, +-0.297552f,0.88274f,0.363639f, +-0.30014f,0.861944f,0.408619f, +-0.211374f,0.886111f,0.412466f, +-0.03076f,0.854928f,0.517834f, +0.0282722f,0.878122f,0.477601f, +-0.13332f,0.93673f,0.32367f, +-0.256519f,0.940042f,0.224764f, +-0.183801f,0.953616f,0.238397f, +-0.0194462f,0.968434f,0.24851f, +-0.0907191f,0.988269f,0.122863f, +-0.322189f,0.946234f,-0.028899f, +-0.20601f,0.965456f,-0.159543f, +-0.0654489f,0.973414f,-0.219504f, +-0.113732f,0.990052f,-0.0828341f, +-0.135223f,0.986029f,0.0972711f, +-0.295266f,0.944373f,0.144834f, +-0.450404f,0.860579f,0.237781f, +-0.30004f,0.881766f,0.363958f, +-0.429075f,0.860577f,0.274411f, +-0.624789f,0.771784f,0.118272f, +-0.497638f,0.864372f,0.0722275f, +-0.313601f,0.946808f,-0.0721819f, +-0.057809f,0.993544f,-0.0976184f, +0.13458f,0.987765f,-0.078798f, +-0.184662f,0.92514f,-0.331688f, +-0.385787f,0.812528f,-0.436996f, +-0.187957f,0.911737f,-0.36525f, +0.0316981f,0.954599f,-0.296202f, +0.147926f,0.956328f,-0.252101f, +0.104858f,0.974711f,-0.197342f, +-0.0836115f,0.931387f,-0.354298f, +-0.111379f,0.87594f,-0.469386f, +-0.0328315f,0.880204f,-0.473458f, +0.162025f,0.887756f,-0.430856f, +0.205253f,0.903446f,-0.376373f, +0.237481f,0.902569f,-0.359125f, +0.385116f,0.876359f,-0.289276f, +0.249914f,0.920198f,-0.301294f, +0.0143883f,0.906805f,-0.421304f, +0.1198f,0.98226f,-0.14427f, +-0.009516f,0.980934f,-0.194106f, +-0.149357f,0.951394f,-0.269335f, +-0.133007f,0.936454f,-0.324597f, +0.034566f,0.948692f,-0.314306f, +0.178184f,0.929444f,-0.323086f, +0.219637f,0.922638f,-0.317015f, +0.296463f,0.935411f,-0.192652f, +0.416664f,0.902617f,-0.108048f, +0.442812f,0.876638f,-0.188209f, +0.465688f,0.849444f,-0.248152f, +0.511879f,0.84424f,-0.158868f, +0.360617f,0.931627f,-0.0450278f, +0.228988f,0.955033f,0.188354f, +-0.00280316f,0.974776f,0.223168f, +0.00899431f,0.980078f,0.198407f, +0.0845579f,0.975657f,0.202347f, +0.0600237f,0.962271f,0.265389f, +0.0344627f,0.950379f,0.309181f, +0.173636f,0.921696f,0.346881f, +-0.00190385f,0.960894f,0.276909f, +-0.186383f,0.97431f,0.126416f, +0.101162f,0.98048f,0.168596f, +0.181976f,0.961147f,0.207559f, +0.220019f,0.957024f,0.188939f, +0.310192f,0.917199f,0.250053f, +-0.02225f,0.932984f,0.359229f, +-0.395015f,0.837639f,0.377259f, +-0.325443f,0.861588f,0.389554f, +-0.255559f,0.880464f,0.39934f, +-0.151471f,0.886274f,0.437693f, +-0.0211154f,0.863177f,0.50446f, +0.00094362f,0.808505f,0.588488f, +-0.114242f,0.850647f,0.513176f, +-0.11027f,0.888828f,0.444776f, +-0.0310984f,0.926772f,0.374335f, +0.036991f,0.899416f,0.435525f, +-0.0593828f,0.941327f,0.33223f, +-0.108182f,0.990534f,0.0844942f, +-0.153469f,0.985899f,0.066708f, +-0.257292f,0.956946f,0.134368f, +-0.339432f,0.926138f,0.164482f, +-0.361227f,0.853531f,0.3755f, +-0.433268f,0.811828f,0.391425f, +-0.292152f,0.883075f,0.367186f, +-0.254971f,0.931997f,0.257627f, +-0.51111f,0.857028f,-0.0653379f, +-0.482419f,0.859823f,-0.167263f, +-0.240122f,0.964988f,-0.105544f, +-0.0637549f,0.987476f,-0.144314f, +0.14266f,0.980144f,-0.137714f, +0.096896f,0.982614f,-0.158371f, +-0.287298f,0.856944f,-0.42791f, +-0.299829f,0.819408f,-0.488542f, +-0.0881013f,0.911449f,-0.40187f, +0.0509938f,0.949808f,-0.308649f, +0.13334f,0.962273f,-0.237174f, +0.0865622f,0.946427f,-0.311099f, +0.0118172f,0.924665f,-0.380599f, +-0.0178448f,0.910652f,-0.412789f, +0.073892f,0.906856f,-0.414913f, +0.15114f,0.90612f,-0.395099f, +0.255577f,0.878518f,-0.403593f, +0.278013f,0.865146f,-0.417411f, +0.239832f,0.923443f,-0.299555f, +0.188412f,0.940744f,-0.281961f, +-0.0158305f,0.982567f,-0.185231f, +0.0666038f,0.988337f,-0.136945f, +-0.0538402f,0.959334f,-0.277092f, +-0.0212127f,0.945816f,-0.324009f, +-0.0150833f,0.913689f,-0.406133f, +0.15601f,0.93774f,-0.310331f, +0.182702f,0.936618f,-0.298942f, +0.189924f,0.93758f,-0.29133f, +0.333869f,0.91329f,-0.233307f, +0.499532f,0.857573f,-0.122619f, +0.46551f,0.873216f,-0.144201f, +0.373694f,0.926999f,0.0320189f, +0.203779f,0.950539f,0.234414f, +0.13831f,0.928366f,0.344974f, +0.0515931f,0.949665f,0.30899f, +0.0310079f,0.96445f,0.262439f, +0.0853119f,0.968829f,0.232577f, +-0.00103764f,0.981733f,0.190261f, +-0.00365072f,0.967667f,0.252206f, +0.10066f,0.945677f,0.309134f, +0.178572f,0.914026f,0.364237f, +-0.0213985f,0.991455f,0.128684f, +0.0498313f,0.996519f,0.0668339f, +0.120586f,0.983203f,0.137006f, +0.0910496f,0.981472f,0.16859f, +0.13401f,0.919805f,0.368783f, +-0.0801133f,0.861028f,0.502208f, +-0.337717f,0.841946f,0.420801f, +-0.27627f,0.878916f,0.388821f, +-0.2301f,0.91025f,0.344237f, +-0.177792f,0.940411f,0.289857f, +-0.131507f,0.928729f,0.346652f, +-0.0961971f,0.892019f,0.441642f, +-0.0639687f,0.872394f,0.4846f, +-0.0102449f,0.879124f,0.476482f, +-0.00257342f,0.917704f,0.397258f, +-0.0554909f,0.910659f,0.409416f, +0.0291401f,0.896118f,0.442858f, +0.0220451f,0.91331f,0.406668f, +-0.138595f,0.921526f,0.362741f, +-0.186305f,0.924786f,0.331755f, +-0.347011f,0.903153f,0.25278f, +-0.513046f,0.817508f,0.261656f, +-0.445268f,0.835978f,0.320745f, +-0.177443f,0.933005f,0.313074f, +-0.0397144f,0.982015f,0.184579f, +-0.223543f,0.974128f,-0.0332155f, +-0.4666f,0.831165f,-0.302406f, +-0.335541f,0.890675f,-0.306773f, +-0.0318096f,0.973987f,-0.224358f, +0.0953506f,0.970682f,-0.220646f, +0.134482f,0.984534f,-0.112281f, +-0.0162953f,0.992479f,-0.121323f, +-0.284204f,0.902721f,-0.322992f, +-0.211997f,0.906314f,-0.365585f, +-0.016875f,0.958349f,-0.285101f, +0.129044f,0.959618f,-0.24996f, +0.151996f,0.928771f,-0.338057f, +-0.0199776f,0.904327f,-0.426372f, +-0.0559071f,0.940256f,-0.335846f, +0.108952f,0.945546f,-0.306712f, +0.215589f,0.905767f,-0.364838f, +0.293281f,0.878158f,-0.377921f, +0.279356f,0.877367f,-0.390112f, +0.127912f,0.886694f,-0.444312f, +0.153161f,0.902051f,-0.403541f, +-0.0890667f,0.969622f,-0.227816f, +0.0791521f,0.98141f,-0.174841f, +0.0791423f,0.971591f,-0.22304f, +0.0168825f,0.939671f,-0.341662f, +-0.00465273f,0.922224f,-0.386629f, +0.0341103f,0.949158f,-0.312946f, +0.243022f,0.94331f,-0.226069f, +0.218985f,0.910646f,-0.350386f, +0.282576f,0.88974f,-0.358487f, +0.398347f,0.877162f,-0.268155f, +0.330147f,0.941044f,-0.073754f, +0.178397f,0.970659f,0.16123f, +0.0525065f,0.954596f,0.293241f, +0.0945297f,0.914894f,0.392472f, +0.13661f,0.905749f,0.401193f, +0.0406243f,0.947359f,0.317587f, +0.163762f,0.925717f,0.340926f, +0.040504f,0.970394f,0.238108f, +-0.0543453f,0.975142f,0.214812f, +2.68223e-005f,0.976435f,0.215812f, +0.209407f,0.932778f,0.293383f, +0.184464f,0.966229f,0.179928f, +-0.0113387f,0.999016f,0.0428878f, +0.079177f,0.981677f,0.173323f, +0.0362262f,0.968187f,0.24759f, +-0.0723427f,0.93572f,0.345245f, +-0.135834f,0.890086f,0.435082f, +-0.264248f,0.873681f,0.408479f, +-0.262216f,0.89706f,0.355706f, +-0.164052f,0.919196f,0.358002f, +-0.167176f,0.924403f,0.342829f, +-0.200682f,0.904947f,0.375229f, +-0.158624f,0.899685f,0.406701f, +-0.112022f,0.891533f,0.438886f, +-0.00921475f,0.869473f,0.493894f, +0.0802624f,0.881225f,0.465833f, +-0.0504548f,0.922517f,0.382645f, +-0.0121989f,0.918687f,0.394797f, +0.0440736f,0.891185f,0.451494f, +-0.0756766f,0.900734f,0.427728f, +-0.202037f,0.909488f,0.363335f, +-0.295423f,0.866009f,0.403428f, +-0.471319f,0.827048f,0.30635f, +-0.443758f,0.874939f,0.193806f, +-0.125026f,0.977756f,0.168412f, +0.0442668f,0.987172f,0.153403f, +-0.0338798f,0.987768f,0.152205f, +-0.259589f,0.965039f,-0.0362462f, +-0.35784f,0.903258f,-0.236805f, +-0.167942f,0.956248f,-0.239554f, +0.0460995f,0.994911f,-0.0895878f, +-0.00166787f,0.99811f,-0.0614342f, +-0.0336402f,0.998923f,0.0319432f, +-0.139942f,0.989786f,0.0271849f, +-0.21913f,0.971861f,-0.0864193f, +-0.083914f,0.990307f,-0.110685f, +0.180721f,0.971397f,-0.154041f, +0.29639f,0.913592f,-0.278393f, +0.0452233f,0.94418f,-0.326312f, +-0.13463f,0.924181f,-0.357441f, +0.11753f,0.929423f,-0.349798f, +0.238754f,0.909243f,-0.340989f, +0.272577f,0.899491f,-0.341494f, +0.343945f,0.879082f,-0.330025f, +0.202726f,0.889055f,-0.410468f, +0.0880936f,0.876474f,-0.473321f, +-0.000386659f,0.989518f,-0.144407f, +-0.0138532f,0.983228f,-0.181856f, +0.165824f,0.98552f,-0.0353913f, +0.196669f,0.963831f,-0.179867f, +0.00115533f,0.93443f,-0.356144f, +-0.0579019f,0.928374f,-0.36711f, +0.234096f,0.913194f,-0.333581f, +0.311749f,0.881031f,-0.355805f, +0.243154f,0.902483f,-0.355529f, +0.214274f,0.956658f,-0.197209f, +0.120355f,0.990537f,0.0659672f, +0.0219689f,0.979298f,0.201227f, +-0.0108785f,0.963809f,0.266373f, +-0.016985f,0.957116f,0.289205f, +0.15437f,0.922679f,0.353316f, +0.0959731f,0.93811f,0.332776f, +0.138832f,0.935317f,0.325434f, +0.133758f,0.941295f,0.309956f, +-0.00148525f,0.972503f,0.232885f, +0.00817406f,0.979885f,0.199396f, +0.180862f,0.960033f,0.213602f, +0.330054f,0.924212f,0.192085f, +0.039978f,0.994865f,0.0929833f, +-0.118088f,0.976595f,0.179768f, +-0.100092f,0.923425f,0.370498f, +-0.117559f,0.88568f,0.449166f, +-0.170937f,0.879572f,0.443997f, +-0.244838f,0.844603f,0.47613f, +-0.196312f,0.844324f,0.498577f, +-0.188529f,0.85759f,0.478535f, +-0.188501f,0.839785f,0.509145f, +-0.185899f,0.842964f,0.50483f, +-0.154293f,0.872091f,0.464382f, +-0.115474f,0.894542f,0.431811f, +-0.0887035f,0.930393f,0.35567f, +0.133188f,0.884773f,0.446583f, +0.0484666f,0.90226f,0.42846f, +-0.0427135f,0.946807f,0.318954f, +-0.0239721f,0.952831f,0.302554f, +-0.0435714f,0.926502f,0.373759f, +-0.182333f,0.899048f,0.398079f, +-0.323546f,0.846433f,0.422929f, +-0.334412f,0.852971f,0.40076f, +-0.325744f,0.921829f,0.210052f, +-0.140593f,0.980752f,0.135497f, +-0.000911154f,0.974293f,0.225285f, +-0.0250989f,0.969759f,0.242771f, +-0.116671f,0.973198f,0.198177f, +-0.222025f,0.967605f,0.12019f, +-0.252573f,0.967519f,-0.0106675f, +-0.0639595f,0.99456f,0.0822198f, +0.0427289f,0.995551f,0.0839736f, +-0.103724f,0.994603f,-0.00239601f, +-0.143088f,0.981404f,0.127957f, +-0.10974f,0.986771f,0.119333f, +0.0104156f,0.996494f,-0.083017f, +0.293943f,0.936018f,-0.193565f, +0.319276f,0.921897f,-0.219472f, +0.0381885f,0.98033f,-0.193638f, +-0.0675527f,0.960756f,-0.269042f, +0.11652f,0.926645f,-0.357425f, +0.2292f,0.915276f,-0.331265f, +0.30797f,0.891339f,-0.33267f, +0.348546f,0.853103f,-0.38824f, +0.249601f,0.874176f,-0.416553f, +0.18778f,0.887174f,-0.421499f, +0.122671f,0.990262f,-0.0658213f, +-0.0435566f,0.992887f,-0.11081f, +0.0494387f,0.998572f,0.0202637f, +0.34574f,0.93458f,0.0838063f, +0.205482f,0.970541f,-0.125808f, +0.00807532f,0.928646f,-0.370879f, +0.212354f,0.896105f,-0.389746f, +0.285287f,0.924061f,-0.254407f, +0.130923f,0.978283f,-0.160691f, +-0.0198715f,0.999555f,-0.0222427f, +-0.0516664f,0.987583f,0.148362f, +-0.0269196f,0.97761f,0.208697f, +-0.00903021f,0.979554f,0.200976f, +-0.00834551f,0.993685f,0.111894f, +0.110842f,0.987362f,0.113269f, +0.106874f,0.976878f,0.185167f, +0.141547f,0.968321f,0.205716f, +0.174972f,0.958256f,0.22612f, +0.054828f,0.97071f,0.233913f, +0.0299952f,0.981566f,0.188753f, +0.154988f,0.980787f,0.118472f, +0.340268f,0.925521f,0.166219f, +0.0136729f,0.972695f,0.231683f, +-0.270301f,0.899629f,0.342937f, +-0.212226f,0.859098f,0.465736f, +-0.140535f,0.846284f,0.513861f, +-0.175101f,0.833937f,0.523345f, +-0.270288f,0.821688f,0.501769f, +-0.282918f,0.830124f,0.48047f, +-0.174774f,0.812594f,0.556008f, +-0.140913f,0.828898f,0.541361f, +-0.117146f,0.878471f,0.463211f, +-0.0728003f,0.920501f,0.383899f, +-0.00293246f,0.948861f,0.315679f, +-0.025836f,0.967046f,0.253289f, +-0.00528251f,0.957042f,0.289901f, +0.088837f,0.914901f,0.393781f, +0.103014f,0.924276f,0.367561f, +0.00437406f,0.95596f,0.293464f, +-0.1442f,0.952275f,0.269032f, +-0.25396f,0.922416f,0.290951f, +-0.3894f,0.883133f,0.261618f, +-0.283615f,0.906122f,0.313857f, +-0.158058f,0.930594f,0.330171f, +-0.134893f,0.961854f,0.237993f, +-0.0720522f,0.980808f,0.181173f, +0.0349752f,0.985618f,0.16533f, +-0.115886f,0.987377f,0.107965f, +-0.182211f,0.968171f,0.171592f, +-0.154769f,0.971197f,0.181169f, +-0.0833304f,0.991727f,0.0976435f, +0.136344f,0.989699f,0.0436644f, +-0.106946f,0.993768f,-0.0314277f, +-0.261215f,0.963441f,0.0595659f, +0.0120329f,0.999596f,0.0257635f, +0.254582f,0.953185f,-0.163178f, +0.299581f,0.899014f,-0.319413f, +0.266729f,0.9307f,-0.250307f, +0.0579078f,0.977779f,-0.201483f, +0.0590491f,0.968354f,-0.242494f, +0.196887f,0.912909f,-0.357536f, +0.211047f,0.877381f,-0.430885f, +0.301745f,0.869054f,-0.39204f, +0.422629f,0.852977f,-0.306291f, +0.252055f,0.896241f,-0.364994f, +0.158615f,0.91987f,-0.35872f, +0.099088f,0.991841f,-0.0802016f, +-0.0649468f,0.996188f,-0.0582405f, +-0.09006f,0.995865f,-0.0119566f, +0.299186f,0.949686f,0.0926523f, +0.448961f,0.886032f,0.115674f, +0.225408f,0.968479f,-0.106019f, +0.110364f,0.983262f,-0.144965f, +0.0982296f,0.994337f,0.0405443f, +0.03386f,0.98307f,0.180072f, +-0.0548904f,0.982813f,0.176255f, +-0.131535f,0.986412f,0.0984329f, +-0.0772354f,0.9803f,0.181787f, +0.0556449f,0.958844f,0.278429f, +0.08308f,0.969903f,0.228882f, +0.0990101f,0.980512f,0.169685f, +0.044494f,0.989611f,0.136713f, +0.124145f,0.981303f,0.14708f, +0.126925f,0.98249f,0.136391f, +0.0289993f,0.988064f,0.151292f, +0.146433f,0.982737f,0.113073f, +0.210582f,0.977005f,-0.0334257f, +0.179552f,0.980748f,0.0767724f, +-0.0986728f,0.925956f,0.364513f, +-0.333893f,0.835984f,0.435484f, +-0.316161f,0.849609f,0.422146f, +-0.184942f,0.836066f,0.516517f, +-0.165011f,0.827696f,0.536368f, +-0.1919f,0.849729f,0.491054f, +-0.260791f,0.881445f,0.393754f, +-0.244518f,0.891442f,0.3815f, +-0.101674f,0.91665f,0.386543f, +-0.0135975f,0.926806f,0.375295f, +0.0383624f,0.948469f,0.31454f, +0.0311937f,0.973858f,0.225008f, +-0.0712105f,0.966505f,0.24657f, +-0.0567001f,0.939446f,0.337973f, +0.028793f,0.937988f,0.345471f, +0.0944493f,0.922855f,0.373388f, +0.0339618f,0.928396f,0.370037f, +-0.0877384f,0.940895f,0.327137f, +-0.18953f,0.934542f,0.301182f, +-0.32638f,0.91712f,0.22884f, +-0.359606f,0.925931f,0.115484f, +-0.250341f,0.958991f,0.132911f, +-0.0188851f,0.981881f,0.188556f, +0.0444017f,0.992958f,0.109832f, +0.0292244f,0.992914f,0.115188f, +-0.0809364f,0.975181f,0.206087f, +-0.271318f,0.947628f,0.168488f, +-0.147667f,0.972329f,0.181027f, +0.0428511f,0.996597f,0.0704105f, +0.186761f,0.979997f,-0.0687482f, +-0.111624f,0.989428f,-0.0925828f, +-0.210799f,0.973161f,-0.0923101f, +0.115063f,0.969975f,-0.214262f, +0.376036f,0.900817f,-0.217086f, +0.373114f,0.884398f,-0.280403f, +0.226074f,0.905778f,-0.358407f, +0.0100432f,0.919347f,-0.393319f, +0.0770135f,0.93428f,-0.348124f, +0.321395f,0.895396f,-0.308175f, +0.278274f,0.88968f,-0.361984f, +0.208857f,0.897848f,-0.387619f, +0.325776f,0.898072f,-0.295527f, +0.259741f,0.94586f,-0.194637f, +0.133572f,0.977992f,-0.160282f, +-0.0277257f,0.992037f,-0.122857f, +-0.0924217f,0.994571f,-0.0478129f, +-0.116438f,0.990661f,-0.0709396f, +0.19557f,0.979919f,-0.0388625f, +0.381806f,0.908869f,0.167871f, +0.299282f,0.900933f,0.314247f, +0.0638964f,0.963274f,0.260808f, +-0.0731879f,0.961388f,0.265284f, +0.00180295f,0.933351f,0.35896f, +0.0655899f,0.939022f,0.337544f, +-0.0612046f,0.96894f,0.239602f, +-0.166052f,0.961913f,0.217141f, +-0.0893118f,0.965245f,0.245614f, +0.0820047f,0.941494f,0.326902f, +0.146932f,0.937808f,0.314527f, +0.136588f,0.939539f,0.314023f, +0.166222f,0.964584f,0.204811f, +0.17109f,0.976368f,0.132039f, +0.0961069f,0.992806f,0.0714098f, +0.21778f,0.975905f,-0.013487f, +0.251597f,0.967828f,-0.00281592f, +-0.0966896f,0.992674f,0.0724564f, +-0.377842f,0.87018f,0.316262f, +-0.323773f,0.853386f,0.408537f, +-0.278729f,0.867238f,0.412564f, +-0.286188f,0.874143f,0.392391f, +-0.157911f,0.873337f,0.46081f, +-0.102832f,0.901917f,0.419488f, +-0.202979f,0.914239f,0.350665f, +-0.202531f,0.912766f,0.354739f, +-0.0843061f,0.956165f,0.28043f, +-0.032801f,0.972626f,0.23005f, +0.0558474f,0.961664f,0.268485f, +0.0617913f,0.944956f,0.321309f, +-0.110343f,0.937288f,0.330629f, +-0.100375f,0.942449f,0.318927f, +0.00551388f,0.94452f,0.328408f, +0.0918462f,0.918926f,0.383587f, +0.101653f,0.927592f,0.3595f, +-0.0426308f,0.960188f,0.276083f, +-0.204594f,0.956809f,0.206539f, +-0.269971f,0.94929f,0.161132f, +-0.226691f,0.969699f,0.0910768f, +-0.201053f,0.979426f,-0.0173973f, +-0.0500104f,0.996428f,-0.0680439f, +0.0272717f,0.999341f,-0.0239459f, +-0.123434f,0.99095f,0.0527561f, +-0.192945f,0.962627f,0.190054f, +-0.168165f,0.969015f,0.180916f, +-0.018086f,0.998622f,0.0492547f, +0.193647f,0.975713f,-0.102395f, +0.238523f,0.949336f,-0.204618f, +-0.0631885f,0.979427f,-0.191649f, +-0.143153f,0.951631f,-0.271858f, +0.148284f,0.940281f,-0.306403f, +0.321113f,0.91022f,-0.261508f, +0.430557f,0.873923f,-0.225566f, +0.33081f,0.885978f,-0.324974f, +0.0651303f,0.881392f,-0.467874f, +0.0061581f,0.870221f,-0.492623f, +0.228459f,0.886891f,-0.401535f, +0.271547f,0.915184f,-0.297827f, +0.234822f,0.937165f,-0.258033f, +0.27549f,0.92259f,-0.270061f, +0.15924f,0.956523f,-0.244348f, +0.0559303f,0.980799f,-0.186831f, +-0.135424f,0.978967f,-0.152593f, +-0.15029f,0.985676f,-0.0765294f, +-0.0914165f,0.995631f,-0.0190383f, +0.0718608f,0.995714f,0.0582141f, +0.110439f,0.955564f,0.273313f, +0.150494f,0.878589f,0.453246f, +0.206788f,0.864483f,0.458157f, +0.00161058f,0.957582f,0.288156f, +-0.0606597f,0.978401f,0.197616f, +0.0692656f,0.9636f,0.25822f, +-0.0150286f,0.961837f,0.273212f, +-0.0821089f,0.979895f,0.181835f, +-0.0658015f,0.997594f,0.0218166f, +0.0735253f,0.997209f,0.0129617f, +0.108564f,0.993746f,0.0261473f, +0.141903f,0.981669f,0.127241f, +0.25029f,0.961471f,0.113707f, +0.225135f,0.967003f,0.119246f, +0.180078f,0.979492f,0.0903737f, +0.237995f,0.971216f,-0.00990333f, +0.0690008f,0.993039f,0.0954582f, +-0.15301f,0.921345f,0.357369f, +-0.436898f,0.858127f,0.2697f, +-0.402318f,0.892319f,0.204714f, +-0.306797f,0.913547f,0.267033f, +-0.291188f,0.917032f,0.272509f, +-0.177835f,0.951614f,0.250608f, +-0.0915363f,0.968867f,0.230039f, +-0.166531f,0.945303f,0.280483f, +-0.214524f,0.956179f,0.199251f, +-0.012479f,0.976094f,0.216991f, +0.0485598f,0.972045f,0.22972f, +-0.0252191f,0.985709f,0.166561f, +-0.0505751f,0.962642f,0.266012f, +-0.0744793f,0.942362f,0.3262f, +-0.0759606f,0.964725f,0.252062f, +-0.0161104f,0.954528f,0.297687f, +0.0264811f,0.949176f,0.313631f, +0.160628f,0.931063f,0.327597f, +0.0783265f,0.972396f,0.219798f, +-0.0844827f,0.993769f,0.0727062f, +-0.216702f,0.975588f,-0.035603f, +-0.195742f,0.979732f,-0.0425419f, +-0.158684f,0.986912f,-0.0287187f, +-0.0351752f,0.999203f,-0.0188605f, +0.0075235f,0.998877f,-0.0467686f, +-0.172586f,0.978556f,-0.112436f, +-0.211691f,0.968971f,-0.127601f, +-0.0966389f,0.974492f,-0.202552f, +0.105494f,0.955113f,-0.276822f, +0.276059f,0.900517f,-0.335947f, +0.219894f,0.907239f,-0.358557f, +-0.0517693f,0.940977f,-0.334489f, +-0.112634f,0.913693f,-0.390485f, +0.139923f,0.91136f,-0.387097f, +0.277005f,0.880398f,-0.384926f, +0.432717f,0.843875f,-0.317222f, +0.433921f,0.823502f,-0.365455f, +0.17364f,0.848637f,-0.499665f, +-0.015678f,0.850557f,-0.525649f, +0.122709f,0.874405f,-0.469423f, +0.164019f,0.896294f,-0.412014f, +0.166557f,0.925047f,-0.34139f, +0.280426f,0.925939f,-0.25298f, +0.167623f,0.949542f,-0.265088f, +-0.00102675f,0.947405f,-0.320035f, +-0.299103f,0.954018f,0.0196808f, +-0.231787f,0.963234f,0.135851f, +-0.196753f,0.961454f,0.192081f, +-0.100151f,0.951932f,0.289472f, +-0.0563981f,0.925245f,0.375154f, +0.0944709f,0.906549f,0.411394f, +0.305132f,0.862547f,0.403618f, +0.241596f,0.931691f,0.271261f, +-0.00370494f,0.998524f,0.0541932f, +-0.000261525f,0.998839f,0.0481646f, +0.0260826f,0.996855f,0.0748309f, +0.0599122f,0.998202f,-0.00179631f, +0.0800977f,0.992669f,-0.0905174f, +0.0495455f,0.986325f,-0.157186f, +0.0563113f,0.99071f,-0.123787f, +0.0832843f,0.991933f,-0.095561f, +0.195142f,0.979158f,-0.0563024f, +0.166634f,0.980307f,0.105976f, +0.195862f,0.965878f,0.169461f, +0.284001f,0.943304f,0.171815f, +-0.127388f,0.981047f,0.146008f, +-0.325222f,0.907949f,0.264311f, +-0.283635f,0.916157f,0.28321f, +-0.335047f,0.926228f,0.17276f, +-0.335005f,0.934046f,0.123816f, +-0.290471f,0.951826f,0.098256f, +-0.155538f,0.980437f,0.120632f, +-0.103955f,0.982905f,0.151957f, +-0.195165f,0.971298f,0.135979f, +-0.117017f,0.988828f,0.0923353f, +-0.0942839f,0.995508f,0.00860997f, +-0.0378307f,0.988218f,0.148301f, +0.011735f,0.964206f,0.264893f, +-0.104568f,0.970188f,0.218634f, +-0.0628876f,0.976435f,0.206445f, +-0.0629747f,0.98253f,0.175127f, +-0.0956593f,0.974263f,0.204109f, +0.00313264f,0.95614f,0.292895f, +0.184054f,0.913334f,0.363241f, +0.234886f,0.917194f,0.321843f, +0.0818984f,0.986888f,0.139086f, +-0.195667f,0.979747f,-0.0425424f, +-0.217661f,0.976006f,-0.00606019f, +-0.197993f,0.980131f,-0.011927f, +-0.0476541f,0.998861f,-0.00224411f, +0.0987461f,0.994341f,-0.039179f, +-0.0376594f,0.985822f,-0.163515f, +-0.127665f,0.950129f,-0.284528f, +0.022229f,0.926621f,-0.37534f, +0.1509f,0.867911f,-0.473243f, +0.251356f,0.84329f,-0.475061f, +0.180391f,0.877498f,-0.44436f, +-0.0381311f,0.903323f,-0.427263f, +-0.0302687f,0.878817f,-0.476199f, +0.151045f,0.843437f,-0.515557f, +0.243043f,0.829132f,-0.503459f, +0.361214f,0.815934f,-0.451416f, +0.469501f,0.80804f,-0.355866f, +0.232058f,0.89573f,-0.379233f, +-0.0406313f,0.902008f,-0.429803f, +0.0570971f,0.896722f,-0.438895f, +0.139199f,0.907425f,-0.396488f, +0.0981956f,0.909915f,-0.403003f, +0.173099f,0.913856f,-0.367293f, +0.208242f,0.936494f,-0.28216f, +0.104323f,0.936228f,-0.335549f, +-0.455877f,0.874672f,0.164697f, +-0.324643f,0.906811f,0.268889f, +-0.22917f,0.934048f,0.273927f, +-0.11917f,0.945648f,0.302569f, +-0.0303449f,0.953424f,0.300104f, +0.0953211f,0.968161f,0.231468f, +0.307551f,0.928088f,0.209914f, +0.396906f,0.882705f,0.251588f, +0.154339f,0.98019f,0.124127f, +0.00614755f,0.999958f,0.00674104f, +0.0862143f,0.995356f,-0.0428297f, +0.0605751f,0.988948f,-0.135323f, +0.116851f,0.991236f,-0.0616197f, +0.0626175f,0.989161f,-0.132815f, +0.0598334f,0.989391f,-0.132381f, +0.0870904f,0.982628f,-0.163882f, +0.0967617f,0.982554f,-0.15882f, +0.0255981f,0.999032f,-0.0357718f, +0.114826f,0.99101f,0.0686587f, +0.196799f,0.954402f,0.22447f, +-0.0385546f,0.932725f,0.358521f, +-0.332784f,0.924223f,0.18726f, +-0.304588f,0.936692f,0.172726f, +-0.293315f,0.937819f,0.185638f, +-0.274742f,0.953043f,0.127381f, +-0.263119f,0.962853f,0.0606766f, +-0.268024f,0.959606f,0.0855591f, +-0.0879001f,0.973995f,0.208824f, +-0.133948f,0.986848f,0.0904876f, +-0.113332f,0.988235f,0.102703f, +-0.0299834f,0.985262f,0.168402f, +-0.19277f,0.976736f,0.0939502f, +-0.0881002f,0.973369f,0.211639f, +-0.024161f,0.965814f,0.258109f, +-0.0447814f,0.977625f,0.205534f, +-0.0454862f,0.975256f,0.216349f, +-0.133105f,0.964838f,0.22665f, +-0.114579f,0.956534f,0.268169f, +0.0712671f,0.941693f,0.328841f, +0.238728f,0.884921f,0.399904f, +0.297664f,0.869038f,0.395183f, +-0.00961778f,0.988677f,0.149748f, +-0.265709f,0.963666f,-0.0273077f, +-0.143358f,0.988736f,0.0430136f, +-0.00534208f,0.998711f,-0.0504723f, +0.174549f,0.979244f,-0.103024f, +0.0753759f,0.97722f,-0.198391f, +-0.0309169f,0.954209f,-0.297538f, +0.114484f,0.932628f,-0.342197f, +0.277629f,0.881086f,-0.382896f, +0.233881f,0.840787f,-0.488238f, +0.145974f,0.866169f,-0.477957f, +-0.0214889f,0.855591f,-0.517207f, +0.015747f,0.850281f,-0.526094f, +0.181736f,0.859322f,-0.478056f, +0.233268f,0.832868f,-0.501913f, +0.278912f,0.819449f,-0.500711f, +0.37496f,0.838284f,-0.395834f, +0.211098f,0.909912f,-0.357069f, +0.0173895f,0.949305f,-0.313875f, +0.0778513f,0.935569f,-0.344455f, +0.13573f,0.919161f,-0.369756f, +0.128317f,0.903382f,-0.40919f, +0.134873f,0.894846f,-0.425512f, +0.140765f,0.922098f,-0.360446f, +0.195779f,0.941368f,-0.274766f, +-0.498792f,0.861228f,0.0974355f, +-0.334273f,0.933116f,0.132498f, +-0.209899f,0.97009f,0.121936f, +-0.146122f,0.979163f,0.141027f, +-0.00844043f,0.991347f,0.130997f, +0.183871f,0.98064f,0.0673491f, +0.295623f,0.955305f,0.000649681f, +0.325261f,0.940591f,0.0974362f, +0.279972f,0.936209f,0.212435f, +0.117319f,0.989809f,0.0807136f, +0.167452f,0.985876f,0.00303625f, +0.0997326f,0.991951f,-0.0780129f, +0.0970545f,0.989541f,-0.106723f, +0.122983f,0.982138f,-0.14241f, +0.0889416f,0.984545f,-0.150867f, +0.0922265f,0.975522f,-0.199627f, +0.0767647f,0.98447f,-0.15788f, +-0.0166949f,0.981051f,-0.193027f, +-0.0192651f,0.97159f,-0.235885f, +-0.0430007f,0.99834f,-0.038322f, +-0.1057f,0.976121f,0.189775f, +-0.21501f,0.968939f,0.122177f, +-0.312622f,0.947332f,0.0695023f, +-0.268759f,0.958656f,0.0935212f, +-0.210053f,0.974561f,0.0781578f, +-0.280996f,0.956877f,0.0736733f, +-0.29425f,0.945004f,0.142776f, +-0.103752f,0.988352f,0.111339f, +-0.0179991f,0.994529f,0.102897f, +-0.257355f,0.965403f,0.0420096f, +-0.105403f,0.956057f,0.273578f, +-0.10459f,0.942017f,0.318851f, +-0.129983f,0.956026f,0.262903f, +-0.0671262f,0.95499f,0.288944f, +-0.00387184f,0.948915f,0.315508f, +-0.104327f,0.957897f,0.267486f, +-0.136557f,0.931775f,0.336375f, +-0.0981417f,0.964639f,0.24462f, +0.0564237f,0.977306f,0.204178f, +0.151449f,0.955346f,0.253725f, +0.313069f,0.882901f,0.349962f, +0.317375f,0.903515f,0.287983f, +-0.14146f,0.988238f,-0.0580959f, +-0.183704f,0.977531f,-0.10337f, +0.0729777f,0.993775f,-0.0841813f, +0.241185f,0.959561f,-0.145165f, +0.180872f,0.946861f,-0.26597f, +0.0759246f,0.918564f,-0.387911f, +0.0834031f,0.881426f,-0.4649f, +0.312989f,0.886301f,-0.341334f, +0.345782f,0.8869f,-0.306339f, +0.190174f,0.893803f,-0.40614f, +0.0967003f,0.870562f,-0.482463f, +-0.011292f,0.813313f,-0.581716f, +0.104307f,0.818569f,-0.564858f, +0.278742f,0.804599f,-0.524332f, +0.252871f,0.80123f,-0.542298f, +0.288393f,0.816691f,-0.499846f, +0.158986f,0.877853f,-0.451771f, +-0.0422089f,0.892803f,-0.448466f, +0.0676213f,0.902423f,-0.425511f, +0.196008f,0.897779f,-0.394428f, +0.174291f,0.88488f,-0.431984f, +0.107973f,0.893114f,-0.43668f, +0.0286973f,0.916566f,-0.398853f, +0.0334026f,0.935074f,-0.352875f, +-0.456752f,0.886621f,-0.0726759f, +-0.35821f,0.92461f,-0.129546f, +-0.255187f,0.962466f,-0.0924034f, +-0.153659f,0.987984f,-0.0166497f, +0.0326193f,0.998752f,-0.0378261f, +0.219848f,0.975435f,-0.0138776f, +0.325192f,0.945498f,0.0168406f, +0.223054f,0.973348f,-0.0532875f, +0.221049f,0.975263f,0.000679153f, +0.242907f,0.969656f,0.0276409f, +0.175892f,0.983375f,-0.0451076f, +0.180873f,0.98342f,0.0130764f, +0.169259f,0.981997f,-0.0838673f, +0.138819f,0.973225f,-0.183198f, +0.0923263f,0.975478f,-0.199795f, +0.109785f,0.97291f,-0.203452f, +0.048887f,0.975403f,-0.214938f, +0.0862303f,0.974446f,-0.207409f, +0.0239822f,0.965181f,-0.260482f, +-0.234299f,0.93066f,-0.281028f, +-0.183154f,0.968628f,-0.167974f, +-0.163946f,0.9725f,-0.165423f, +-0.29935f,0.945623f,-0.127226f, +-0.309491f,0.943295f,-0.120043f, +-0.244588f,0.967669f,-0.0615978f, +-0.316375f,0.948228f,-0.0277512f, +-0.278706f,0.959538f,-0.0401272f, +-0.112855f,0.98959f,-0.0893067f, +-0.0120823f,0.999804f,0.015665f, +-0.269265f,0.962743f,0.0249422f, +-0.319779f,0.940968f,0.110998f, +-0.127925f,0.957822f,0.257316f, +-0.134411f,0.958853f,0.250069f, +-0.0963489f,0.939739f,0.328035f, +0.013379f,0.931979f,0.362265f, +-0.059723f,0.950577f,0.304692f, +-0.140375f,0.96932f,0.201776f, +0.0285405f,0.975242f,0.219289f, +0.0759984f,0.981739f,0.174395f, +0.082912f,0.985645f,0.14707f, +0.244118f,0.959921f,0.137686f, +0.433469f,0.888297f,0.151764f, +0.159753f,0.986026f,0.0472448f, +-0.155828f,0.965805f,-0.207217f, +0.0529598f,0.961817f,-0.268522f, +0.302231f,0.91749f,-0.258588f, +0.300969f,0.905771f,-0.298324f, +0.219954f,0.902269f,-0.370851f, +0.168125f,0.874674f,-0.45462f, +0.0852064f,0.832228f,-0.547846f, +0.293285f,0.876411f,-0.381953f, +0.299707f,0.878674f,-0.371628f, +0.169625f,0.87124f,-0.460618f, +0.152784f,0.862886f,-0.481751f, +0.140952f,0.826781f,-0.544578f, +0.216806f,0.796193f,-0.564865f, +0.252088f,0.778347f,-0.575003f, +0.184028f,0.779276f,-0.599052f, +0.07662f,0.847353f,-0.525474f, +-0.000576164f,0.875581f,-0.483072f, +0.0676453f,0.855821f,-0.51283f, +0.10935f,0.864233f,-0.491064f, +0.170357f,0.902391f,-0.395814f, +0.0783522f,0.922085f,-0.378973f, +-0.0376769f,0.945309f,-0.323992f, +-0.0145087f,0.973617f,-0.227725f, +-0.23379f,0.969091f,0.0787691f, +-0.308611f,0.949667f,-0.0537712f, +-0.26795f,0.959457f,-0.087437f, +-0.196118f,0.96672f,-0.16429f, +0.0184009f,0.993828f,-0.109391f, +0.124962f,0.988681f,-0.0830367f, +0.297057f,0.954812f,-0.00955538f, +0.355506f,0.934478f,-0.0191401f, +0.206845f,0.957298f,-0.201981f, +0.24827f,0.946264f,-0.207234f, +0.137685f,0.959548f,-0.245584f, +0.129837f,0.983718f,-0.124261f, +0.240211f,0.966075f,-0.0948542f, +0.253383f,0.959847f,-0.120381f, +0.101386f,0.970431f,-0.219056f, +0.110568f,0.971775f,-0.208395f, +0.09998f,0.968593f,-0.227667f, +0.051279f,0.9528f,-0.299236f, +0.0182953f,0.960636f,-0.277207f, +-0.177379f,0.948528f,-0.262356f, +-0.248744f,0.930203f,-0.269905f, +-0.201336f,0.9681f,-0.14915f, +-0.308378f,0.940105f,-0.145279f, +-0.337871f,0.915739f,-0.217407f, +-0.303349f,0.940151f,-0.155226f, +-0.267648f,0.955794f,-0.121746f, +-0.256838f,0.946595f,-0.194914f, +-0.151848f,0.978969f,-0.136244f, +-0.166527f,0.98578f,-0.0225025f, +-0.271416f,0.956933f,0.103014f, +-0.388293f,0.921445f,0.0129329f, +-0.211649f,0.973838f,0.0827345f, +-0.164151f,0.971899f,0.168719f, +-0.20343f,0.950968f,0.232971f, +-0.0501604f,0.944198f,0.325535f, +0.0851988f,0.916779f,0.390203f, +-0.0675238f,0.966737f,0.246698f, +-0.050967f,0.964665f,0.258503f, +0.0897532f,0.945965f,0.311599f, +0.203817f,0.954291f,0.218604f, +0.298323f,0.9542f,0.0224806f, +0.409994f,0.911395f,0.0355409f, +0.297451f,0.952362f,0.0673044f, +0.087158f,0.982486f,-0.164695f, +0.130693f,0.926163f,-0.353753f, +0.287973f,0.877932f,-0.3825f, +0.285473f,0.870692f,-0.400501f, +0.210236f,0.894171f,-0.395297f, +0.291478f,0.889926f,-0.350816f, +0.238796f,0.833f,-0.499086f, +0.156519f,0.786723f,-0.597134f, +0.265294f,0.807831f,-0.526334f, +0.196683f,0.821511f,-0.535197f, +0.111545f,0.852981f,-0.509883f, +0.148451f,0.876975f,-0.457031f, +0.27925f,0.865803f,-0.415216f, +0.364812f,0.845771f,-0.389337f, +0.213362f,0.862896f,-0.458135f, +-0.014091f,0.870788f,-0.491456f, +-0.0389733f,0.872117f,-0.487742f, +0.0697073f,0.876793f,-0.475789f, +0.0500075f,0.893805f,-0.445659f, +0.0507492f,0.920605f,-0.387184f, +0.00717016f,0.971083f,-0.238636f, +-0.12982f,0.987525f,-0.0891113f, +-0.196671f,0.977747f,-0.0730188f, +-0.180786f,0.972597f,0.146192f, +-0.276836f,0.956623f,0.0907445f, +-0.145247f,0.980389f,0.133193f, +-0.201228f,0.967008f,-0.156214f, +-0.0137179f,0.995281f,-0.0960578f, +0.139707f,0.987867f,-0.0678349f, +0.246306f,0.96116f,-0.124516f, +0.421865f,0.906227f,-0.0279788f, +0.299255f,0.934152f,-0.194439f, +0.288356f,0.912569f,-0.289945f, +0.0853497f,0.915952f,-0.392106f, +0.039019f,0.957394f,-0.286136f, +0.208597f,0.95771f,-0.198188f, +0.25753f,0.95731f,-0.131287f, +0.153643f,0.978938f,-0.134439f, +0.0994252f,0.976974f,-0.188775f, +0.12654f,0.974603f,-0.184759f, +0.142684f,0.966335f,-0.214099f, +-0.00843645f,0.93512f,-0.354231f, +-0.17704f,0.933769f,-0.311017f, +-0.343277f,0.895674f,-0.282717f, +-0.276715f,0.959562f,-0.0516624f, +-0.215753f,0.976427f,-0.00633257f, +-0.305134f,0.926522f,-0.220112f, +-0.33388f,0.920497f,-0.203001f, +-0.259644f,0.948413f,-0.181927f, +-0.268974f,0.938104f,-0.218205f, +-0.245938f,0.962991f,-0.110289f, +-0.275564f,0.96071f,0.0331654f, +-0.258271f,0.944524f,0.202903f, +-0.309053f,0.947461f,0.0824847f, +-0.320335f,0.94673f,-0.0329778f, +-0.208609f,0.963472f,0.167941f, +-0.270763f,0.941796f,0.199269f, +-0.104692f,0.947993f,0.30058f, +0.0304241f,0.930802f,0.364255f, +0.0189457f,0.906511f,0.421757f, +-0.0823065f,0.924037f,0.373337f, +0.102263f,0.911082f,0.39934f, +0.325851f,0.888801f,0.322263f, +0.371159f,0.927767f,0.0385981f, +0.355076f,0.934525f,0.0241533f, +0.375158f,0.916478f,0.139015f, +0.286108f,0.953917f,-0.0904664f, +0.199009f,0.919897f,-0.337913f, +0.358636f,0.872243f,-0.332523f, +0.268543f,0.846175f,-0.460296f, +0.182977f,0.871041f,-0.455858f, +0.289295f,0.860781f,-0.418765f, +0.382576f,0.820168f,-0.425393f, +0.183794f,0.780369f,-0.597699f, +0.239111f,0.770893f,-0.590381f, +0.11759f,0.781853f,-0.612273f, +0.0625615f,0.849006f,-0.524666f, +0.09237f,0.869569f,-0.485096f, +0.210947f,0.881757f,-0.421908f, +0.36331f,0.890409f,-0.274185f, +0.280816f,0.923638f,-0.260836f, +0.0186632f,0.936387f,-0.350473f, +-0.00764646f,0.914133f,-0.405343f, +0.0383964f,0.885647f,-0.462769f, +0.0296537f,0.913944f,-0.404755f, +-0.02984f,0.920171f,-0.390377f, +-0.172982f,0.943792f,-0.281663f, +-0.19032f,0.979403f,0.0674393f, +-0.205961f,0.972526f,0.108505f, +}; + +btScalar Landscape08Tex[] = { +0.0f,0.757813f, +0.0f,0.75f, +0.0078125f,0.757813f, +0.0078125f,0.75f, +0.015625f,0.757813f, +0.015625f,0.75f, +0.0234375f,0.757813f, +0.0234375f,0.75f, +0.03125f,0.757813f, +0.03125f,0.75f, +0.0390625f,0.757813f, +0.0390625f,0.75f, +0.046875f,0.757813f, +0.046875f,0.75f, +0.0546875f,0.757813f, +0.0546875f,0.75f, +0.0625f,0.757813f, +0.0625f,0.75f, +0.0703125f,0.757813f, +0.0703125f,0.75f, +0.078125f,0.757813f, +0.078125f,0.75f, +0.0859375f,0.757813f, +0.0859375f,0.75f, +0.09375f,0.757813f, +0.09375f,0.75f, +0.101563f,0.757813f, +0.101563f,0.75f, +0.109375f,0.757813f, +0.109375f,0.75f, +0.117188f,0.757813f, +0.117188f,0.75f, +0.125f,0.757813f, +0.125f,0.75f, +0.132813f,0.757813f, +0.132813f,0.75f, +0.140625f,0.757813f, +0.140625f,0.75f, +0.148438f,0.757813f, +0.148438f,0.75f, +0.15625f,0.757813f, +0.15625f,0.75f, +0.164063f,0.757813f, +0.164063f,0.75f, +0.171875f,0.757813f, +0.171875f,0.75f, +0.179688f,0.757813f, +0.179688f,0.75f, +0.1875f,0.757813f, +0.1875f,0.75f, +0.195313f,0.757813f, +0.195313f,0.75f, +0.203125f,0.757813f, +0.203125f,0.75f, +0.210938f,0.757813f, +0.210938f,0.75f, +0.21875f,0.757813f, +0.21875f,0.75f, +0.226563f,0.757813f, +0.226563f,0.75f, +0.234375f,0.757813f, +0.234375f,0.75f, +0.242188f,0.757813f, +0.242188f,0.75f, +0.25f,0.757813f, +0.25f,0.75f, +0.257813f,0.757813f, +0.257813f,0.75f, +0.265625f,0.757813f, +0.265625f,0.75f, +0.273438f,0.757813f, +0.273438f,0.75f, +0.28125f,0.757813f, +0.28125f,0.75f, +0.289063f,0.757813f, +0.289063f,0.75f, +0.296875f,0.757813f, +0.296875f,0.75f, +0.304688f,0.757813f, +0.304688f,0.75f, +0.3125f,0.757813f, +0.3125f,0.75f, +0.320313f,0.757813f, +0.320313f,0.75f, +0.328125f,0.757813f, +0.328125f,0.75f, +0.335938f,0.757813f, +0.335938f,0.75f, +0.34375f,0.757813f, +0.34375f,0.75f, +0.351563f,0.757813f, +0.351563f,0.75f, +0.359375f,0.757813f, +0.359375f,0.75f, +0.367188f,0.757813f, +0.367188f,0.75f, +0.375f,0.757813f, +0.375f,0.75f, +0.382813f,0.757813f, +0.382813f,0.75f, +0.390625f,0.757813f, +0.390625f,0.75f, +0.398438f,0.757813f, +0.398438f,0.75f, +0.40625f,0.757813f, +0.40625f,0.75f, +0.414063f,0.757813f, +0.414063f,0.75f, +0.421875f,0.757813f, +0.421875f,0.75f, +0.429688f,0.757813f, +0.429688f,0.75f, +0.4375f,0.757813f, +0.4375f,0.75f, +0.445313f,0.757813f, +0.445313f,0.75f, +0.453125f,0.757813f, +0.453125f,0.75f, +0.460938f,0.757813f, +0.460938f,0.75f, +0.46875f,0.757813f, +0.46875f,0.75f, +0.476563f,0.757813f, +0.476563f,0.75f, +0.484375f,0.757813f, +0.484375f,0.75f, +0.492188f,0.757813f, +0.492188f,0.75f, +0.5f,0.757813f, +0.5f,0.75f, +0.507813f,0.757813f, +0.507813f,0.75f, +0.0f,0.765625f, +0.0078125f,0.765625f, +0.015625f,0.765625f, +0.0234375f,0.765625f, +0.03125f,0.765625f, +0.0390625f,0.765625f, +0.046875f,0.765625f, +0.0546875f,0.765625f, +0.0625f,0.765625f, +0.0703125f,0.765625f, +0.078125f,0.765625f, +0.0859375f,0.765625f, +0.09375f,0.765625f, +0.101563f,0.765625f, +0.109375f,0.765625f, +0.117188f,0.765625f, +0.125f,0.765625f, +0.132813f,0.765625f, +0.140625f,0.765625f, +0.148438f,0.765625f, +0.15625f,0.765625f, +0.164063f,0.765625f, +0.171875f,0.765625f, +0.179688f,0.765625f, +0.1875f,0.765625f, +0.195313f,0.765625f, +0.203125f,0.765625f, +0.210938f,0.765625f, +0.21875f,0.765625f, +0.226563f,0.765625f, +0.234375f,0.765625f, +0.242188f,0.765625f, +0.25f,0.765625f, +0.257813f,0.765625f, +0.265625f,0.765625f, +0.273438f,0.765625f, +0.28125f,0.765625f, +0.289063f,0.765625f, +0.296875f,0.765625f, +0.304688f,0.765625f, +0.3125f,0.765625f, +0.320313f,0.765625f, +0.328125f,0.765625f, +0.335938f,0.765625f, +0.34375f,0.765625f, +0.351563f,0.765625f, +0.359375f,0.765625f, +0.367188f,0.765625f, +0.375f,0.765625f, +0.382813f,0.765625f, +0.390625f,0.765625f, +0.398438f,0.765625f, +0.40625f,0.765625f, +0.414063f,0.765625f, +0.421875f,0.765625f, +0.429688f,0.765625f, +0.4375f,0.765625f, +0.445313f,0.765625f, +0.453125f,0.765625f, +0.460938f,0.765625f, +0.46875f,0.765625f, +0.476563f,0.765625f, +0.484375f,0.765625f, +0.492188f,0.765625f, +0.5f,0.765625f, +0.507813f,0.765625f, +0.0f,0.773438f, +0.0078125f,0.773438f, +0.015625f,0.773438f, +0.0234375f,0.773438f, +0.03125f,0.773438f, +0.0390625f,0.773438f, +0.046875f,0.773438f, +0.0546875f,0.773438f, +0.0625f,0.773438f, +0.0703125f,0.773438f, +0.078125f,0.773438f, +0.0859375f,0.773438f, +0.09375f,0.773438f, +0.101563f,0.773438f, +0.109375f,0.773438f, +0.117188f,0.773438f, +0.125f,0.773438f, +0.132813f,0.773438f, +0.140625f,0.773438f, +0.148438f,0.773438f, +0.15625f,0.773438f, +0.164063f,0.773438f, +0.171875f,0.773438f, +0.179688f,0.773438f, +0.1875f,0.773438f, +0.195313f,0.773438f, +0.203125f,0.773438f, +0.210938f,0.773438f, +0.21875f,0.773438f, +0.226563f,0.773438f, +0.234375f,0.773438f, +0.242188f,0.773438f, +0.25f,0.773438f, +0.257813f,0.773438f, +0.265625f,0.773438f, +0.273438f,0.773438f, +0.28125f,0.773438f, +0.289063f,0.773438f, +0.296875f,0.773438f, +0.304688f,0.773438f, +0.3125f,0.773438f, +0.320313f,0.773438f, +0.328125f,0.773438f, +0.335938f,0.773438f, +0.34375f,0.773438f, +0.351563f,0.773438f, +0.359375f,0.773438f, +0.367188f,0.773438f, +0.375f,0.773438f, +0.382813f,0.773438f, +0.390625f,0.773438f, +0.398438f,0.773438f, +0.40625f,0.773438f, +0.414063f,0.773438f, +0.421875f,0.773438f, +0.429688f,0.773438f, +0.4375f,0.773438f, +0.445313f,0.773438f, +0.453125f,0.773438f, +0.460938f,0.773438f, +0.46875f,0.773438f, +0.476563f,0.773438f, +0.484375f,0.773438f, +0.492188f,0.773438f, +0.5f,0.773438f, +0.507813f,0.773438f, +0.0f,0.78125f, +0.0078125f,0.78125f, +0.015625f,0.78125f, +0.0234375f,0.78125f, +0.03125f,0.78125f, +0.0390625f,0.78125f, +0.046875f,0.78125f, +0.0546875f,0.78125f, +0.0625f,0.78125f, +0.0703125f,0.78125f, +0.078125f,0.78125f, +0.0859375f,0.78125f, +0.09375f,0.78125f, +0.101563f,0.78125f, +0.109375f,0.78125f, +0.117188f,0.78125f, +0.125f,0.78125f, +0.132813f,0.78125f, +0.140625f,0.78125f, +0.148438f,0.78125f, +0.15625f,0.78125f, +0.164063f,0.78125f, +0.171875f,0.78125f, +0.179688f,0.78125f, +0.1875f,0.78125f, +0.195313f,0.78125f, +0.203125f,0.78125f, +0.210938f,0.78125f, +0.21875f,0.78125f, +0.226563f,0.78125f, +0.234375f,0.78125f, +0.242188f,0.78125f, +0.25f,0.78125f, +0.257813f,0.78125f, +0.265625f,0.78125f, +0.273438f,0.78125f, +0.28125f,0.78125f, +0.289063f,0.78125f, +0.296875f,0.78125f, +0.304688f,0.78125f, +0.3125f,0.78125f, +0.320313f,0.78125f, +0.328125f,0.78125f, +0.335938f,0.78125f, +0.34375f,0.78125f, +0.351563f,0.78125f, +0.359375f,0.78125f, +0.367188f,0.78125f, +0.375f,0.78125f, +0.382813f,0.78125f, +0.390625f,0.78125f, +0.398438f,0.78125f, +0.40625f,0.78125f, +0.414063f,0.78125f, +0.421875f,0.78125f, +0.429688f,0.78125f, +0.4375f,0.78125f, +0.445313f,0.78125f, +0.453125f,0.78125f, +0.460938f,0.78125f, +0.46875f,0.78125f, +0.476563f,0.78125f, +0.484375f,0.78125f, +0.492188f,0.78125f, +0.5f,0.78125f, +0.507813f,0.78125f, +0.0f,0.789063f, +0.0078125f,0.789063f, +0.015625f,0.789063f, +0.0234375f,0.789063f, +0.03125f,0.789063f, +0.0390625f,0.789063f, +0.046875f,0.789063f, +0.0546875f,0.789063f, +0.0625f,0.789063f, +0.0703125f,0.789063f, +0.078125f,0.789063f, +0.0859375f,0.789063f, +0.09375f,0.789063f, +0.101563f,0.789063f, +0.109375f,0.789063f, +0.117188f,0.789063f, +0.125f,0.789063f, +0.132813f,0.789063f, +0.140625f,0.789063f, +0.148438f,0.789063f, +0.15625f,0.789063f, +0.164063f,0.789063f, +0.171875f,0.789063f, +0.179688f,0.789063f, +0.1875f,0.789063f, +0.195313f,0.789063f, +0.203125f,0.789063f, +0.210938f,0.789063f, +0.21875f,0.789063f, +0.226563f,0.789063f, +0.234375f,0.789063f, +0.242188f,0.789063f, +0.25f,0.789063f, +0.257813f,0.789063f, +0.265625f,0.789063f, +0.273438f,0.789063f, +0.28125f,0.789063f, +0.289063f,0.789063f, +0.296875f,0.789063f, +0.304688f,0.789063f, +0.3125f,0.789063f, +0.320313f,0.789063f, +0.328125f,0.789063f, +0.335938f,0.789063f, +0.34375f,0.789063f, +0.351563f,0.789063f, +0.359375f,0.789063f, +0.367188f,0.789063f, +0.375f,0.789063f, +0.382813f,0.789063f, +0.390625f,0.789063f, +0.398438f,0.789063f, +0.40625f,0.789063f, +0.414063f,0.789063f, +0.421875f,0.789063f, +0.429688f,0.789063f, +0.4375f,0.789063f, +0.445313f,0.789063f, +0.453125f,0.789063f, +0.460938f,0.789063f, +0.46875f,0.789063f, +0.476563f,0.789063f, +0.484375f,0.789063f, +0.492188f,0.789063f, +0.5f,0.789063f, +0.507813f,0.789063f, +0.0f,0.796875f, +0.0078125f,0.796875f, +0.015625f,0.796875f, +0.0234375f,0.796875f, +0.03125f,0.796875f, +0.0390625f,0.796875f, +0.046875f,0.796875f, +0.0546875f,0.796875f, +0.0625f,0.796875f, +0.0703125f,0.796875f, +0.078125f,0.796875f, +0.0859375f,0.796875f, +0.09375f,0.796875f, +0.101563f,0.796875f, +0.109375f,0.796875f, +0.117188f,0.796875f, +0.125f,0.796875f, +0.132813f,0.796875f, +0.140625f,0.796875f, +0.148438f,0.796875f, +0.15625f,0.796875f, +0.164063f,0.796875f, +0.171875f,0.796875f, +0.179688f,0.796875f, +0.1875f,0.796875f, +0.195313f,0.796875f, +0.203125f,0.796875f, +0.210938f,0.796875f, +0.21875f,0.796875f, +0.226563f,0.796875f, +0.234375f,0.796875f, +0.242188f,0.796875f, +0.25f,0.796875f, +0.257813f,0.796875f, +0.265625f,0.796875f, +0.273438f,0.796875f, +0.28125f,0.796875f, +0.289063f,0.796875f, +0.296875f,0.796875f, +0.304688f,0.796875f, +0.3125f,0.796875f, +0.320313f,0.796875f, +0.328125f,0.796875f, +0.335938f,0.796875f, +0.34375f,0.796875f, +0.351563f,0.796875f, +0.359375f,0.796875f, +0.367188f,0.796875f, +0.375f,0.796875f, +0.382813f,0.796875f, +0.390625f,0.796875f, +0.398438f,0.796875f, +0.40625f,0.796875f, +0.414063f,0.796875f, +0.421875f,0.796875f, +0.429688f,0.796875f, +0.4375f,0.796875f, +0.445313f,0.796875f, +0.453125f,0.796875f, +0.460938f,0.796875f, +0.46875f,0.796875f, +0.476563f,0.796875f, +0.484375f,0.796875f, +0.492188f,0.796875f, +0.5f,0.796875f, +0.507813f,0.796875f, +0.0f,0.804688f, +0.0078125f,0.804688f, +0.015625f,0.804688f, +0.0234375f,0.804688f, +0.03125f,0.804688f, +0.0390625f,0.804688f, +0.046875f,0.804688f, +0.0546875f,0.804688f, +0.0625f,0.804688f, +0.0703125f,0.804688f, +0.078125f,0.804688f, +0.0859375f,0.804688f, +0.09375f,0.804688f, +0.101563f,0.804688f, +0.109375f,0.804688f, +0.117188f,0.804688f, +0.125f,0.804688f, +0.132813f,0.804688f, +0.140625f,0.804688f, +0.148438f,0.804688f, +0.15625f,0.804688f, +0.164063f,0.804688f, +0.171875f,0.804688f, +0.179688f,0.804688f, +0.1875f,0.804688f, +0.195313f,0.804688f, +0.203125f,0.804688f, +0.210938f,0.804688f, +0.21875f,0.804688f, +0.226563f,0.804688f, +0.234375f,0.804688f, +0.242188f,0.804688f, +0.25f,0.804688f, +0.257813f,0.804688f, +0.265625f,0.804688f, +0.273438f,0.804688f, +0.28125f,0.804688f, +0.289063f,0.804688f, +0.296875f,0.804688f, +0.304688f,0.804688f, +0.3125f,0.804688f, +0.320313f,0.804688f, +0.328125f,0.804688f, +0.335938f,0.804688f, +0.34375f,0.804688f, +0.351563f,0.804688f, +0.359375f,0.804688f, +0.367188f,0.804688f, +0.375f,0.804688f, +0.382813f,0.804688f, +0.390625f,0.804688f, +0.398438f,0.804688f, +0.40625f,0.804688f, +0.414063f,0.804688f, +0.421875f,0.804688f, +0.429688f,0.804688f, +0.4375f,0.804688f, +0.445313f,0.804688f, +0.453125f,0.804688f, +0.460938f,0.804688f, +0.46875f,0.804688f, +0.476563f,0.804688f, +0.484375f,0.804688f, +0.492188f,0.804688f, +0.5f,0.804688f, +0.507813f,0.804688f, +0.0f,0.8125f, +0.0078125f,0.8125f, +0.015625f,0.8125f, +0.0234375f,0.8125f, +0.03125f,0.8125f, +0.0390625f,0.8125f, +0.046875f,0.8125f, +0.0546875f,0.8125f, +0.0625f,0.8125f, +0.0703125f,0.8125f, +0.078125f,0.8125f, +0.0859375f,0.8125f, +0.09375f,0.8125f, +0.101563f,0.8125f, +0.109375f,0.8125f, +0.117188f,0.8125f, +0.125f,0.8125f, +0.132813f,0.8125f, +0.140625f,0.8125f, +0.148438f,0.8125f, +0.15625f,0.8125f, +0.164063f,0.8125f, +0.171875f,0.8125f, +0.179688f,0.8125f, +0.1875f,0.8125f, +0.195313f,0.8125f, +0.203125f,0.8125f, +0.210938f,0.8125f, +0.21875f,0.8125f, +0.226563f,0.8125f, +0.234375f,0.8125f, +0.242188f,0.8125f, +0.25f,0.8125f, +0.257813f,0.8125f, +0.265625f,0.8125f, +0.273438f,0.8125f, +0.28125f,0.8125f, +0.289063f,0.8125f, +0.296875f,0.8125f, +0.304688f,0.8125f, +0.3125f,0.8125f, +0.320313f,0.8125f, +0.328125f,0.8125f, +0.335938f,0.8125f, +0.34375f,0.8125f, +0.351563f,0.8125f, +0.359375f,0.8125f, +0.367188f,0.8125f, +0.375f,0.8125f, +0.382813f,0.8125f, +0.390625f,0.8125f, +0.398438f,0.8125f, +0.40625f,0.8125f, +0.414063f,0.8125f, +0.421875f,0.8125f, +0.429688f,0.8125f, +0.4375f,0.8125f, +0.445313f,0.8125f, +0.453125f,0.8125f, +0.460938f,0.8125f, +0.46875f,0.8125f, +0.476563f,0.8125f, +0.484375f,0.8125f, +0.492188f,0.8125f, +0.5f,0.8125f, +0.507813f,0.8125f, +0.0f,0.820313f, +0.0078125f,0.820313f, +0.015625f,0.820313f, +0.0234375f,0.820313f, +0.03125f,0.820313f, +0.0390625f,0.820313f, +0.046875f,0.820313f, +0.0546875f,0.820313f, +0.0625f,0.820313f, +0.0703125f,0.820313f, +0.078125f,0.820313f, +0.0859375f,0.820313f, +0.09375f,0.820313f, +0.101563f,0.820313f, +0.109375f,0.820313f, +0.117188f,0.820313f, +0.125f,0.820313f, +0.132813f,0.820313f, +0.140625f,0.820313f, +0.148438f,0.820313f, +0.15625f,0.820313f, +0.164063f,0.820313f, +0.171875f,0.820313f, +0.179688f,0.820313f, +0.1875f,0.820313f, +0.195313f,0.820313f, +0.203125f,0.820313f, +0.210938f,0.820313f, +0.21875f,0.820313f, +0.226563f,0.820313f, +0.234375f,0.820313f, +0.242188f,0.820313f, +0.25f,0.820313f, +0.257813f,0.820313f, +0.265625f,0.820313f, +0.273438f,0.820313f, +0.28125f,0.820313f, +0.289063f,0.820313f, +0.296875f,0.820313f, +0.304688f,0.820313f, +0.3125f,0.820313f, +0.320313f,0.820313f, +0.328125f,0.820313f, +0.335938f,0.820313f, +0.34375f,0.820313f, +0.351563f,0.820313f, +0.359375f,0.820313f, +0.367188f,0.820313f, +0.375f,0.820313f, +0.382813f,0.820313f, +0.390625f,0.820313f, +0.398438f,0.820313f, +0.40625f,0.820313f, +0.414063f,0.820313f, +0.421875f,0.820313f, +0.429688f,0.820313f, +0.4375f,0.820313f, +0.445313f,0.820313f, +0.453125f,0.820313f, +0.460938f,0.820313f, +0.46875f,0.820313f, +0.476563f,0.820313f, +0.484375f,0.820313f, +0.492188f,0.820313f, +0.5f,0.820313f, +0.507813f,0.820313f, +0.0f,0.828125f, +0.0078125f,0.828125f, +0.015625f,0.828125f, +0.0234375f,0.828125f, +0.03125f,0.828125f, +0.0390625f,0.828125f, +0.046875f,0.828125f, +0.0546875f,0.828125f, +0.0625f,0.828125f, +0.0703125f,0.828125f, +0.078125f,0.828125f, +0.0859375f,0.828125f, +0.09375f,0.828125f, +0.101563f,0.828125f, +0.109375f,0.828125f, +0.117188f,0.828125f, +0.125f,0.828125f, +0.132813f,0.828125f, +0.140625f,0.828125f, +0.148438f,0.828125f, +0.15625f,0.828125f, +0.164063f,0.828125f, +0.171875f,0.828125f, +0.179688f,0.828125f, +0.1875f,0.828125f, +0.195313f,0.828125f, +0.203125f,0.828125f, +0.210938f,0.828125f, +0.21875f,0.828125f, +0.226563f,0.828125f, +0.234375f,0.828125f, +0.242188f,0.828125f, +0.25f,0.828125f, +0.257813f,0.828125f, +0.265625f,0.828125f, +0.273438f,0.828125f, +0.28125f,0.828125f, +0.289063f,0.828125f, +0.296875f,0.828125f, +0.304688f,0.828125f, +0.3125f,0.828125f, +0.320313f,0.828125f, +0.328125f,0.828125f, +0.335938f,0.828125f, +0.34375f,0.828125f, +0.351563f,0.828125f, +0.359375f,0.828125f, +0.367188f,0.828125f, +0.375f,0.828125f, +0.382813f,0.828125f, +0.390625f,0.828125f, +0.398438f,0.828125f, +0.40625f,0.828125f, +0.414063f,0.828125f, +0.421875f,0.828125f, +0.429688f,0.828125f, +0.4375f,0.828125f, +0.445313f,0.828125f, +0.453125f,0.828125f, +0.460938f,0.828125f, +0.46875f,0.828125f, +0.476563f,0.828125f, +0.484375f,0.828125f, +0.492188f,0.828125f, +0.5f,0.828125f, +0.507813f,0.828125f, +0.0f,0.835938f, +0.0078125f,0.835938f, +0.015625f,0.835938f, +0.0234375f,0.835938f, +0.03125f,0.835938f, +0.0390625f,0.835938f, +0.046875f,0.835938f, +0.0546875f,0.835938f, +0.0625f,0.835938f, +0.0703125f,0.835938f, +0.078125f,0.835938f, +0.0859375f,0.835938f, +0.09375f,0.835938f, +0.101563f,0.835938f, +0.109375f,0.835938f, +0.117188f,0.835938f, +0.125f,0.835938f, +0.132813f,0.835938f, +0.140625f,0.835938f, +0.148438f,0.835938f, +0.15625f,0.835938f, +0.164063f,0.835938f, +0.171875f,0.835938f, +0.179688f,0.835938f, +0.1875f,0.835938f, +0.195313f,0.835938f, +0.203125f,0.835938f, +0.210938f,0.835938f, +0.21875f,0.835938f, +0.226563f,0.835938f, +0.234375f,0.835938f, +0.242188f,0.835938f, +0.25f,0.835938f, +0.257813f,0.835938f, +0.265625f,0.835938f, +0.273438f,0.835938f, +0.28125f,0.835938f, +0.289063f,0.835938f, +0.296875f,0.835938f, +0.304688f,0.835938f, +0.3125f,0.835938f, +0.320313f,0.835938f, +0.328125f,0.835938f, +0.335938f,0.835938f, +0.34375f,0.835938f, +0.351563f,0.835938f, +0.359375f,0.835938f, +0.367188f,0.835938f, +0.375f,0.835938f, +0.382813f,0.835938f, +0.390625f,0.835938f, +0.398438f,0.835938f, +0.40625f,0.835938f, +0.414063f,0.835938f, +0.421875f,0.835938f, +0.429688f,0.835938f, +0.4375f,0.835938f, +0.445313f,0.835938f, +0.453125f,0.835938f, +0.460938f,0.835938f, +0.46875f,0.835938f, +0.476563f,0.835938f, +0.484375f,0.835938f, +0.492188f,0.835938f, +0.5f,0.835938f, +0.507813f,0.835938f, +0.0f,0.84375f, +0.0078125f,0.84375f, +0.015625f,0.84375f, +0.0234375f,0.84375f, +0.03125f,0.84375f, +0.0390625f,0.84375f, +0.046875f,0.84375f, +0.0546875f,0.84375f, +0.0625f,0.84375f, +0.0703125f,0.84375f, +0.078125f,0.84375f, +0.0859375f,0.84375f, +0.09375f,0.84375f, +0.101563f,0.84375f, +0.109375f,0.84375f, +0.117188f,0.84375f, +0.125f,0.84375f, +0.132813f,0.84375f, +0.140625f,0.84375f, +0.148438f,0.84375f, +0.15625f,0.84375f, +0.164063f,0.84375f, +0.171875f,0.84375f, +0.179688f,0.84375f, +0.1875f,0.84375f, +0.195313f,0.84375f, +0.203125f,0.84375f, +0.210938f,0.84375f, +0.21875f,0.84375f, +0.226563f,0.84375f, +0.234375f,0.84375f, +0.242188f,0.84375f, +0.25f,0.84375f, +0.257813f,0.84375f, +0.265625f,0.84375f, +0.273438f,0.84375f, +0.28125f,0.84375f, +0.289063f,0.84375f, +0.296875f,0.84375f, +0.304688f,0.84375f, +0.3125f,0.84375f, +0.320313f,0.84375f, +0.328125f,0.84375f, +0.335938f,0.84375f, +0.34375f,0.84375f, +0.351563f,0.84375f, +0.359375f,0.84375f, +0.367188f,0.84375f, +0.375f,0.84375f, +0.382813f,0.84375f, +0.390625f,0.84375f, +0.398438f,0.84375f, +0.40625f,0.84375f, +0.414063f,0.84375f, +0.421875f,0.84375f, +0.429688f,0.84375f, +0.4375f,0.84375f, +0.445313f,0.84375f, +0.453125f,0.84375f, +0.460938f,0.84375f, +0.46875f,0.84375f, +0.476563f,0.84375f, +0.484375f,0.84375f, +0.492188f,0.84375f, +0.5f,0.84375f, +0.507813f,0.84375f, +0.0f,0.851563f, +0.0078125f,0.851563f, +0.015625f,0.851563f, +0.0234375f,0.851563f, +0.03125f,0.851563f, +0.0390625f,0.851563f, +0.046875f,0.851563f, +0.0546875f,0.851563f, +0.0625f,0.851563f, +0.0703125f,0.851563f, +0.078125f,0.851563f, +0.0859375f,0.851563f, +0.09375f,0.851563f, +0.101563f,0.851563f, +0.109375f,0.851563f, +0.117188f,0.851563f, +0.125f,0.851563f, +0.132813f,0.851563f, +0.140625f,0.851563f, +0.148438f,0.851563f, +0.15625f,0.851563f, +0.164063f,0.851563f, +0.171875f,0.851563f, +0.179688f,0.851563f, +0.1875f,0.851563f, +0.195313f,0.851563f, +0.203125f,0.851563f, +0.210938f,0.851563f, +0.21875f,0.851563f, +0.226563f,0.851563f, +0.234375f,0.851563f, +0.242188f,0.851563f, +0.25f,0.851563f, +0.257813f,0.851563f, +0.265625f,0.851563f, +0.273438f,0.851563f, +0.28125f,0.851563f, +0.289063f,0.851563f, +0.296875f,0.851563f, +0.304688f,0.851563f, +0.3125f,0.851563f, +0.320313f,0.851563f, +0.328125f,0.851563f, +0.335938f,0.851563f, +0.34375f,0.851563f, +0.351563f,0.851563f, +0.359375f,0.851563f, +0.367188f,0.851563f, +0.375f,0.851563f, +0.382813f,0.851563f, +0.390625f,0.851563f, +0.398438f,0.851563f, +0.40625f,0.851563f, +0.414063f,0.851563f, +0.421875f,0.851563f, +0.429688f,0.851563f, +0.4375f,0.851563f, +0.445313f,0.851563f, +0.453125f,0.851563f, +0.460938f,0.851563f, +0.46875f,0.851563f, +0.476563f,0.851563f, +0.484375f,0.851563f, +0.492188f,0.851563f, +0.5f,0.851563f, +0.507813f,0.851563f, +0.0f,0.859375f, +0.0078125f,0.859375f, +0.015625f,0.859375f, +0.0234375f,0.859375f, +0.03125f,0.859375f, +0.0390625f,0.859375f, +0.046875f,0.859375f, +0.0546875f,0.859375f, +0.0625f,0.859375f, +0.0703125f,0.859375f, +0.078125f,0.859375f, +0.0859375f,0.859375f, +0.09375f,0.859375f, +0.101563f,0.859375f, +0.109375f,0.859375f, +0.117188f,0.859375f, +0.125f,0.859375f, +0.132813f,0.859375f, +0.140625f,0.859375f, +0.148438f,0.859375f, +0.15625f,0.859375f, +0.164063f,0.859375f, +0.171875f,0.859375f, +0.179688f,0.859375f, +0.1875f,0.859375f, +0.195313f,0.859375f, +0.203125f,0.859375f, +0.210938f,0.859375f, +0.21875f,0.859375f, +0.226563f,0.859375f, +0.234375f,0.859375f, +0.242188f,0.859375f, +0.25f,0.859375f, +0.257813f,0.859375f, +0.265625f,0.859375f, +0.273438f,0.859375f, +0.28125f,0.859375f, +0.289063f,0.859375f, +0.296875f,0.859375f, +0.304688f,0.859375f, +0.3125f,0.859375f, +0.320313f,0.859375f, +0.328125f,0.859375f, +0.335938f,0.859375f, +0.34375f,0.859375f, +0.351563f,0.859375f, +0.359375f,0.859375f, +0.367188f,0.859375f, +0.375f,0.859375f, +0.382813f,0.859375f, +0.390625f,0.859375f, +0.398438f,0.859375f, +0.40625f,0.859375f, +0.414063f,0.859375f, +0.421875f,0.859375f, +0.429688f,0.859375f, +0.4375f,0.859375f, +0.445313f,0.859375f, +0.453125f,0.859375f, +0.460938f,0.859375f, +0.46875f,0.859375f, +0.476563f,0.859375f, +0.484375f,0.859375f, +0.492188f,0.859375f, +0.5f,0.859375f, +0.507813f,0.859375f, +0.0f,0.867188f, +0.0078125f,0.867188f, +0.015625f,0.867188f, +0.0234375f,0.867188f, +0.03125f,0.867188f, +0.0390625f,0.867188f, +0.046875f,0.867188f, +0.0546875f,0.867188f, +0.0625f,0.867188f, +0.0703125f,0.867188f, +0.078125f,0.867188f, +0.0859375f,0.867188f, +0.09375f,0.867188f, +0.101563f,0.867188f, +0.109375f,0.867188f, +0.117188f,0.867188f, +0.125f,0.867188f, +0.132813f,0.867188f, +0.140625f,0.867188f, +0.148438f,0.867188f, +0.15625f,0.867188f, +0.164063f,0.867188f, +0.171875f,0.867188f, +0.179688f,0.867188f, +0.1875f,0.867188f, +0.195313f,0.867188f, +0.203125f,0.867188f, +0.210938f,0.867188f, +0.21875f,0.867188f, +0.226563f,0.867188f, +0.234375f,0.867188f, +0.242188f,0.867188f, +0.25f,0.867188f, +0.257813f,0.867188f, +0.265625f,0.867188f, +0.273438f,0.867188f, +0.28125f,0.867188f, +0.289063f,0.867188f, +0.296875f,0.867188f, +0.304688f,0.867188f, +0.3125f,0.867188f, +0.320313f,0.867188f, +0.328125f,0.867188f, +0.335938f,0.867188f, +0.34375f,0.867188f, +0.351563f,0.867188f, +0.359375f,0.867188f, +0.367188f,0.867188f, +0.375f,0.867188f, +0.382813f,0.867188f, +0.390625f,0.867188f, +0.398438f,0.867188f, +0.40625f,0.867188f, +0.414063f,0.867188f, +0.421875f,0.867188f, +0.429688f,0.867188f, +0.4375f,0.867188f, +0.445313f,0.867188f, +0.453125f,0.867188f, +0.460938f,0.867188f, +0.46875f,0.867188f, +0.476563f,0.867188f, +0.484375f,0.867188f, +0.492188f,0.867188f, +0.5f,0.867188f, +0.507813f,0.867188f, +0.0f,0.875f, +0.0078125f,0.875f, +0.015625f,0.875f, +0.0234375f,0.875f, +0.03125f,0.875f, +0.0390625f,0.875f, +0.046875f,0.875f, +0.0546875f,0.875f, +0.0625f,0.875f, +0.0703125f,0.875f, +0.078125f,0.875f, +0.0859375f,0.875f, +0.09375f,0.875f, +0.101563f,0.875f, +0.109375f,0.875f, +0.117188f,0.875f, +0.125f,0.875f, +0.132813f,0.875f, +0.140625f,0.875f, +0.148438f,0.875f, +0.15625f,0.875f, +0.164063f,0.875f, +0.171875f,0.875f, +0.179688f,0.875f, +0.1875f,0.875f, +0.195313f,0.875f, +0.203125f,0.875f, +0.210938f,0.875f, +0.21875f,0.875f, +0.226563f,0.875f, +0.234375f,0.875f, +0.242188f,0.875f, +0.25f,0.875f, +0.257813f,0.875f, +0.265625f,0.875f, +0.273438f,0.875f, +0.28125f,0.875f, +0.289063f,0.875f, +0.296875f,0.875f, +0.304688f,0.875f, +0.3125f,0.875f, +0.320313f,0.875f, +0.328125f,0.875f, +0.335938f,0.875f, +0.34375f,0.875f, +0.351563f,0.875f, +0.359375f,0.875f, +0.367188f,0.875f, +0.375f,0.875f, +0.382813f,0.875f, +0.390625f,0.875f, +0.398438f,0.875f, +0.40625f,0.875f, +0.414063f,0.875f, +0.421875f,0.875f, +0.429688f,0.875f, +0.4375f,0.875f, +0.445313f,0.875f, +0.453125f,0.875f, +0.460938f,0.875f, +0.46875f,0.875f, +0.476563f,0.875f, +0.484375f,0.875f, +0.492188f,0.875f, +0.5f,0.875f, +0.507813f,0.875f, +0.0f,0.882813f, +0.0078125f,0.882813f, +0.015625f,0.882813f, +0.0234375f,0.882813f, +0.03125f,0.882813f, +0.0390625f,0.882813f, +0.046875f,0.882813f, +0.0546875f,0.882813f, +0.0625f,0.882813f, +0.0703125f,0.882813f, +0.078125f,0.882813f, +0.0859375f,0.882813f, +0.09375f,0.882813f, +0.101563f,0.882813f, +0.109375f,0.882813f, +0.117188f,0.882813f, +0.125f,0.882813f, +0.132813f,0.882813f, +0.140625f,0.882813f, +0.148438f,0.882813f, +0.15625f,0.882813f, +0.164063f,0.882813f, +0.171875f,0.882813f, +0.179688f,0.882813f, +0.1875f,0.882813f, +0.195313f,0.882813f, +0.203125f,0.882813f, +0.210938f,0.882813f, +0.21875f,0.882813f, +0.226563f,0.882813f, +0.234375f,0.882813f, +0.242188f,0.882813f, +0.25f,0.882813f, +0.257813f,0.882813f, +0.265625f,0.882813f, +0.273438f,0.882813f, +0.28125f,0.882813f, +0.289063f,0.882813f, +0.296875f,0.882813f, +0.304688f,0.882813f, +0.3125f,0.882813f, +0.320313f,0.882813f, +0.328125f,0.882813f, +0.335938f,0.882813f, +0.34375f,0.882813f, +0.351563f,0.882813f, +0.359375f,0.882813f, +0.367188f,0.882813f, +0.375f,0.882813f, +0.382813f,0.882813f, +0.390625f,0.882813f, +0.398438f,0.882813f, +0.40625f,0.882813f, +0.414063f,0.882813f, +0.421875f,0.882813f, +0.429688f,0.882813f, +0.4375f,0.882813f, +0.445313f,0.882813f, +0.453125f,0.882813f, +0.460938f,0.882813f, +0.46875f,0.882813f, +0.476563f,0.882813f, +0.484375f,0.882813f, +0.492188f,0.882813f, +0.5f,0.882813f, +0.507813f,0.882813f, +0.0f,0.890625f, +0.0078125f,0.890625f, +0.015625f,0.890625f, +0.0234375f,0.890625f, +0.03125f,0.890625f, +0.0390625f,0.890625f, +0.046875f,0.890625f, +0.0546875f,0.890625f, +0.0625f,0.890625f, +0.0703125f,0.890625f, +0.078125f,0.890625f, +0.0859375f,0.890625f, +0.09375f,0.890625f, +0.101563f,0.890625f, +0.109375f,0.890625f, +0.117188f,0.890625f, +0.125f,0.890625f, +0.132813f,0.890625f, +0.140625f,0.890625f, +0.148438f,0.890625f, +0.15625f,0.890625f, +0.164063f,0.890625f, +0.171875f,0.890625f, +0.179688f,0.890625f, +0.1875f,0.890625f, +0.195313f,0.890625f, +0.203125f,0.890625f, +0.210938f,0.890625f, +0.21875f,0.890625f, +0.226563f,0.890625f, +0.234375f,0.890625f, +0.242188f,0.890625f, +0.25f,0.890625f, +0.257813f,0.890625f, +0.265625f,0.890625f, +0.273438f,0.890625f, +0.28125f,0.890625f, +0.289063f,0.890625f, +0.296875f,0.890625f, +0.304688f,0.890625f, +0.3125f,0.890625f, +0.320313f,0.890625f, +0.328125f,0.890625f, +0.335938f,0.890625f, +0.34375f,0.890625f, +0.351563f,0.890625f, +0.359375f,0.890625f, +0.367188f,0.890625f, +0.375f,0.890625f, +0.382813f,0.890625f, +0.390625f,0.890625f, +0.398438f,0.890625f, +0.40625f,0.890625f, +0.414063f,0.890625f, +0.421875f,0.890625f, +0.429688f,0.890625f, +0.4375f,0.890625f, +0.445313f,0.890625f, +0.453125f,0.890625f, +0.460938f,0.890625f, +0.46875f,0.890625f, +0.476563f,0.890625f, +0.484375f,0.890625f, +0.492188f,0.890625f, +0.5f,0.890625f, +0.507813f,0.890625f, +0.0f,0.898438f, +0.0078125f,0.898438f, +0.015625f,0.898438f, +0.0234375f,0.898438f, +0.03125f,0.898438f, +0.0390625f,0.898438f, +0.046875f,0.898438f, +0.0546875f,0.898438f, +0.0625f,0.898438f, +0.0703125f,0.898438f, +0.078125f,0.898438f, +0.0859375f,0.898438f, +0.09375f,0.898438f, +0.101563f,0.898438f, +0.109375f,0.898438f, +0.117188f,0.898438f, +0.125f,0.898438f, +0.132813f,0.898438f, +0.140625f,0.898438f, +0.148438f,0.898438f, +0.15625f,0.898438f, +0.164063f,0.898438f, +0.171875f,0.898438f, +0.179688f,0.898438f, +0.1875f,0.898438f, +0.195313f,0.898438f, +0.203125f,0.898438f, +0.210938f,0.898438f, +0.21875f,0.898438f, +0.226563f,0.898438f, +0.234375f,0.898438f, +0.242188f,0.898438f, +0.25f,0.898438f, +0.257813f,0.898438f, +0.265625f,0.898438f, +0.273438f,0.898438f, +0.28125f,0.898438f, +0.289063f,0.898438f, +0.296875f,0.898438f, +0.304688f,0.898438f, +0.3125f,0.898438f, +0.320313f,0.898438f, +0.328125f,0.898438f, +0.335938f,0.898438f, +0.34375f,0.898438f, +0.351563f,0.898438f, +0.359375f,0.898438f, +0.367188f,0.898438f, +0.375f,0.898438f, +0.382813f,0.898438f, +0.390625f,0.898438f, +0.398438f,0.898438f, +0.40625f,0.898438f, +0.414063f,0.898438f, +0.421875f,0.898438f, +0.429688f,0.898438f, +0.4375f,0.898438f, +0.445313f,0.898438f, +0.453125f,0.898438f, +0.460938f,0.898438f, +0.46875f,0.898438f, +0.476563f,0.898438f, +0.484375f,0.898438f, +0.492188f,0.898438f, +0.5f,0.898438f, +0.507813f,0.898438f, +0.0f,0.90625f, +0.0078125f,0.90625f, +0.015625f,0.90625f, +0.0234375f,0.90625f, +0.03125f,0.90625f, +0.0390625f,0.90625f, +0.046875f,0.90625f, +0.0546875f,0.90625f, +0.0625f,0.90625f, +0.0703125f,0.90625f, +0.078125f,0.90625f, +0.0859375f,0.90625f, +0.09375f,0.90625f, +0.101563f,0.90625f, +0.109375f,0.90625f, +0.117188f,0.90625f, +0.125f,0.90625f, +0.132813f,0.90625f, +0.140625f,0.90625f, +0.148438f,0.90625f, +0.15625f,0.90625f, +0.164063f,0.90625f, +0.171875f,0.90625f, +0.179688f,0.90625f, +0.1875f,0.90625f, +0.195313f,0.90625f, +0.203125f,0.90625f, +0.210938f,0.90625f, +0.21875f,0.90625f, +0.226563f,0.90625f, +0.234375f,0.90625f, +0.242188f,0.90625f, +0.25f,0.90625f, +0.257813f,0.90625f, +0.265625f,0.90625f, +0.273438f,0.90625f, +0.28125f,0.90625f, +0.289063f,0.90625f, +0.296875f,0.90625f, +0.304688f,0.90625f, +0.3125f,0.90625f, +0.320313f,0.90625f, +0.328125f,0.90625f, +0.335938f,0.90625f, +0.34375f,0.90625f, +0.351563f,0.90625f, +0.359375f,0.90625f, +0.367188f,0.90625f, +0.375f,0.90625f, +0.382813f,0.90625f, +0.390625f,0.90625f, +0.398438f,0.90625f, +0.40625f,0.90625f, +0.414063f,0.90625f, +0.421875f,0.90625f, +0.429688f,0.90625f, +0.4375f,0.90625f, +0.445313f,0.90625f, +0.453125f,0.90625f, +0.460938f,0.90625f, +0.46875f,0.90625f, +0.476563f,0.90625f, +0.484375f,0.90625f, +0.492188f,0.90625f, +0.5f,0.90625f, +0.507813f,0.90625f, +0.0f,0.914063f, +0.0078125f,0.914063f, +0.015625f,0.914063f, +0.0234375f,0.914063f, +0.03125f,0.914063f, +0.0390625f,0.914063f, +0.046875f,0.914063f, +0.0546875f,0.914063f, +0.0625f,0.914063f, +0.0703125f,0.914063f, +0.078125f,0.914063f, +0.0859375f,0.914063f, +0.09375f,0.914063f, +0.101563f,0.914063f, +0.109375f,0.914063f, +0.117188f,0.914063f, +0.125f,0.914063f, +0.132813f,0.914063f, +0.140625f,0.914063f, +0.148438f,0.914063f, +0.15625f,0.914063f, +0.164063f,0.914063f, +0.171875f,0.914063f, +0.179688f,0.914063f, +0.1875f,0.914063f, +0.195313f,0.914063f, +0.203125f,0.914063f, +0.210938f,0.914063f, +0.21875f,0.914063f, +0.226563f,0.914063f, +0.234375f,0.914063f, +0.242188f,0.914063f, +0.25f,0.914063f, +0.257813f,0.914063f, +0.265625f,0.914063f, +0.273438f,0.914063f, +0.28125f,0.914063f, +0.289063f,0.914063f, +0.296875f,0.914063f, +0.304688f,0.914063f, +0.3125f,0.914063f, +0.320313f,0.914063f, +0.328125f,0.914063f, +0.335938f,0.914063f, +0.34375f,0.914063f, +0.351563f,0.914063f, +0.359375f,0.914063f, +0.367188f,0.914063f, +0.375f,0.914063f, +0.382813f,0.914063f, +0.390625f,0.914063f, +0.398438f,0.914063f, +0.40625f,0.914063f, +0.414063f,0.914063f, +0.421875f,0.914063f, +0.429688f,0.914063f, +0.4375f,0.914063f, +0.445313f,0.914063f, +0.453125f,0.914063f, +0.460938f,0.914063f, +0.46875f,0.914063f, +0.476563f,0.914063f, +0.484375f,0.914063f, +0.492188f,0.914063f, +0.5f,0.914063f, +0.507813f,0.914063f, +0.0f,0.921875f, +0.0078125f,0.921875f, +0.015625f,0.921875f, +0.0234375f,0.921875f, +0.03125f,0.921875f, +0.0390625f,0.921875f, +0.046875f,0.921875f, +0.0546875f,0.921875f, +0.0625f,0.921875f, +0.0703125f,0.921875f, +0.078125f,0.921875f, +0.0859375f,0.921875f, +0.09375f,0.921875f, +0.101563f,0.921875f, +0.109375f,0.921875f, +0.117188f,0.921875f, +0.125f,0.921875f, +0.132813f,0.921875f, +0.140625f,0.921875f, +0.148438f,0.921875f, +0.15625f,0.921875f, +0.164063f,0.921875f, +0.171875f,0.921875f, +0.179688f,0.921875f, +0.1875f,0.921875f, +0.195313f,0.921875f, +0.203125f,0.921875f, +0.210938f,0.921875f, +0.21875f,0.921875f, +0.226563f,0.921875f, +0.234375f,0.921875f, +0.242188f,0.921875f, +0.25f,0.921875f, +0.257813f,0.921875f, +0.265625f,0.921875f, +0.273438f,0.921875f, +0.28125f,0.921875f, +0.289063f,0.921875f, +0.296875f,0.921875f, +0.304688f,0.921875f, +0.3125f,0.921875f, +0.320313f,0.921875f, +0.328125f,0.921875f, +0.335938f,0.921875f, +0.34375f,0.921875f, +0.351563f,0.921875f, +0.359375f,0.921875f, +0.367188f,0.921875f, +0.375f,0.921875f, +0.382813f,0.921875f, +0.390625f,0.921875f, +0.398438f,0.921875f, +0.40625f,0.921875f, +0.414063f,0.921875f, +0.421875f,0.921875f, +0.429688f,0.921875f, +0.4375f,0.921875f, +0.445313f,0.921875f, +0.453125f,0.921875f, +0.460938f,0.921875f, +0.46875f,0.921875f, +0.476563f,0.921875f, +0.484375f,0.921875f, +0.492188f,0.921875f, +0.5f,0.921875f, +0.507813f,0.921875f, +0.0f,0.929688f, +0.0078125f,0.929688f, +0.015625f,0.929688f, +0.0234375f,0.929688f, +0.03125f,0.929688f, +0.0390625f,0.929688f, +0.046875f,0.929688f, +0.0546875f,0.929688f, +0.0625f,0.929688f, +0.0703125f,0.929688f, +0.078125f,0.929688f, +0.0859375f,0.929688f, +0.09375f,0.929688f, +0.101563f,0.929688f, +0.109375f,0.929688f, +0.117188f,0.929688f, +0.125f,0.929688f, +0.132813f,0.929688f, +0.140625f,0.929688f, +0.148438f,0.929688f, +0.15625f,0.929688f, +0.164063f,0.929688f, +0.171875f,0.929688f, +0.179688f,0.929688f, +0.1875f,0.929688f, +0.195313f,0.929688f, +0.203125f,0.929688f, +0.210938f,0.929688f, +0.21875f,0.929688f, +0.226563f,0.929688f, +0.234375f,0.929688f, +0.242188f,0.929688f, +0.25f,0.929688f, +0.257813f,0.929688f, +0.265625f,0.929688f, +0.273438f,0.929688f, +0.28125f,0.929688f, +0.289063f,0.929688f, +0.296875f,0.929688f, +0.304688f,0.929688f, +0.3125f,0.929688f, +0.320313f,0.929688f, +0.328125f,0.929688f, +0.335938f,0.929688f, +0.34375f,0.929688f, +0.351563f,0.929688f, +0.359375f,0.929688f, +0.367188f,0.929688f, +0.375f,0.929688f, +0.382813f,0.929688f, +0.390625f,0.929688f, +0.398438f,0.929688f, +0.40625f,0.929688f, +0.414063f,0.929688f, +0.421875f,0.929688f, +0.429688f,0.929688f, +0.4375f,0.929688f, +0.445313f,0.929688f, +0.453125f,0.929688f, +0.460938f,0.929688f, +0.46875f,0.929688f, +0.476563f,0.929688f, +0.484375f,0.929688f, +0.492188f,0.929688f, +0.5f,0.929688f, +0.507813f,0.929688f, +0.0f,0.9375f, +0.0078125f,0.9375f, +0.015625f,0.9375f, +0.0234375f,0.9375f, +0.03125f,0.9375f, +0.0390625f,0.9375f, +0.046875f,0.9375f, +0.0546875f,0.9375f, +0.0625f,0.9375f, +0.0703125f,0.9375f, +0.078125f,0.9375f, +0.0859375f,0.9375f, +0.09375f,0.9375f, +0.101563f,0.9375f, +0.109375f,0.9375f, +0.117188f,0.9375f, +0.125f,0.9375f, +0.132813f,0.9375f, +0.140625f,0.9375f, +0.148438f,0.9375f, +0.15625f,0.9375f, +0.164063f,0.9375f, +0.171875f,0.9375f, +0.179688f,0.9375f, +0.1875f,0.9375f, +0.195313f,0.9375f, +0.203125f,0.9375f, +0.210938f,0.9375f, +0.21875f,0.9375f, +0.226563f,0.9375f, +0.234375f,0.9375f, +0.242188f,0.9375f, +0.25f,0.9375f, +0.257813f,0.9375f, +0.265625f,0.9375f, +0.273438f,0.9375f, +0.28125f,0.9375f, +0.289063f,0.9375f, +0.296875f,0.9375f, +0.304688f,0.9375f, +0.3125f,0.9375f, +0.320313f,0.9375f, +0.328125f,0.9375f, +0.335938f,0.9375f, +0.34375f,0.9375f, +0.351563f,0.9375f, +0.359375f,0.9375f, +0.367188f,0.9375f, +0.375f,0.9375f, +0.382813f,0.9375f, +0.390625f,0.9375f, +0.398438f,0.9375f, +0.40625f,0.9375f, +0.414063f,0.9375f, +0.421875f,0.9375f, +0.429688f,0.9375f, +0.4375f,0.9375f, +0.445313f,0.9375f, +0.453125f,0.9375f, +0.460938f,0.9375f, +0.46875f,0.9375f, +0.476563f,0.9375f, +0.484375f,0.9375f, +0.492188f,0.9375f, +0.5f,0.9375f, +0.507813f,0.9375f, +0.0f,0.945313f, +0.0078125f,0.945313f, +0.015625f,0.945313f, +0.0234375f,0.945313f, +0.03125f,0.945313f, +0.0390625f,0.945313f, +0.046875f,0.945313f, +0.0546875f,0.945313f, +0.0625f,0.945313f, +0.0703125f,0.945313f, +0.078125f,0.945313f, +0.0859375f,0.945313f, +0.09375f,0.945313f, +0.101563f,0.945313f, +0.109375f,0.945313f, +0.117188f,0.945313f, +0.125f,0.945313f, +0.132813f,0.945313f, +0.140625f,0.945313f, +0.148438f,0.945313f, +0.15625f,0.945313f, +0.164063f,0.945313f, +0.171875f,0.945313f, +0.179688f,0.945313f, +0.1875f,0.945313f, +0.195313f,0.945313f, +0.203125f,0.945313f, +0.210938f,0.945313f, +0.21875f,0.945313f, +0.226563f,0.945313f, +0.234375f,0.945313f, +0.242188f,0.945313f, +0.25f,0.945313f, +0.257813f,0.945313f, +0.265625f,0.945313f, +0.273438f,0.945313f, +0.28125f,0.945313f, +0.289063f,0.945313f, +0.296875f,0.945313f, +0.304688f,0.945313f, +0.3125f,0.945313f, +0.320313f,0.945313f, +0.328125f,0.945313f, +0.335938f,0.945313f, +0.34375f,0.945313f, +0.351563f,0.945313f, +0.359375f,0.945313f, +0.367188f,0.945313f, +0.375f,0.945313f, +0.382813f,0.945313f, +0.390625f,0.945313f, +0.398438f,0.945313f, +0.40625f,0.945313f, +0.414063f,0.945313f, +0.421875f,0.945313f, +0.429688f,0.945313f, +0.4375f,0.945313f, +0.445313f,0.945313f, +0.453125f,0.945313f, +0.460938f,0.945313f, +0.46875f,0.945313f, +0.476563f,0.945313f, +0.484375f,0.945313f, +0.492188f,0.945313f, +0.5f,0.945313f, +0.507813f,0.945313f, +0.0f,0.953125f, +0.0078125f,0.953125f, +0.015625f,0.953125f, +0.0234375f,0.953125f, +0.03125f,0.953125f, +0.0390625f,0.953125f, +0.046875f,0.953125f, +0.0546875f,0.953125f, +0.0625f,0.953125f, +0.0703125f,0.953125f, +0.078125f,0.953125f, +0.0859375f,0.953125f, +0.09375f,0.953125f, +0.101563f,0.953125f, +0.109375f,0.953125f, +0.117188f,0.953125f, +0.125f,0.953125f, +0.132813f,0.953125f, +0.140625f,0.953125f, +0.148438f,0.953125f, +0.15625f,0.953125f, +0.164063f,0.953125f, +0.171875f,0.953125f, +0.179688f,0.953125f, +0.1875f,0.953125f, +0.195313f,0.953125f, +0.203125f,0.953125f, +0.210938f,0.953125f, +0.21875f,0.953125f, +0.226563f,0.953125f, +0.234375f,0.953125f, +0.242188f,0.953125f, +0.25f,0.953125f, +0.257813f,0.953125f, +0.265625f,0.953125f, +0.273438f,0.953125f, +0.28125f,0.953125f, +0.289063f,0.953125f, +0.296875f,0.953125f, +0.304688f,0.953125f, +0.3125f,0.953125f, +0.320313f,0.953125f, +0.328125f,0.953125f, +0.335938f,0.953125f, +0.34375f,0.953125f, +0.351563f,0.953125f, +0.359375f,0.953125f, +0.367188f,0.953125f, +0.375f,0.953125f, +0.382813f,0.953125f, +0.390625f,0.953125f, +0.398438f,0.953125f, +0.40625f,0.953125f, +0.414063f,0.953125f, +0.421875f,0.953125f, +0.429688f,0.953125f, +0.4375f,0.953125f, +0.445313f,0.953125f, +0.453125f,0.953125f, +0.460938f,0.953125f, +0.46875f,0.953125f, +0.476563f,0.953125f, +0.484375f,0.953125f, +0.492188f,0.953125f, +0.5f,0.953125f, +0.507813f,0.953125f, +0.0f,0.960938f, +0.0078125f,0.960938f, +0.015625f,0.960938f, +0.0234375f,0.960938f, +0.03125f,0.960938f, +0.0390625f,0.960938f, +0.046875f,0.960938f, +0.0546875f,0.960938f, +0.0625f,0.960938f, +0.0703125f,0.960938f, +0.078125f,0.960938f, +0.0859375f,0.960938f, +0.09375f,0.960938f, +0.101563f,0.960938f, +0.109375f,0.960938f, +0.117188f,0.960938f, +0.125f,0.960938f, +0.132813f,0.960938f, +0.140625f,0.960938f, +0.148438f,0.960938f, +0.15625f,0.960938f, +0.164063f,0.960938f, +0.171875f,0.960938f, +0.179688f,0.960938f, +0.1875f,0.960938f, +0.195313f,0.960938f, +0.203125f,0.960938f, +0.210938f,0.960938f, +0.21875f,0.960938f, +0.226563f,0.960938f, +0.234375f,0.960938f, +0.242188f,0.960938f, +0.25f,0.960938f, +0.257813f,0.960938f, +0.265625f,0.960938f, +0.273438f,0.960938f, +0.28125f,0.960938f, +0.289063f,0.960938f, +0.296875f,0.960938f, +0.304688f,0.960938f, +0.3125f,0.960938f, +0.320313f,0.960938f, +0.328125f,0.960938f, +0.335938f,0.960938f, +0.34375f,0.960938f, +0.351563f,0.960938f, +0.359375f,0.960938f, +0.367188f,0.960938f, +0.375f,0.960938f, +0.382813f,0.960938f, +0.390625f,0.960938f, +0.398438f,0.960938f, +0.40625f,0.960938f, +0.414063f,0.960938f, +0.421875f,0.960938f, +0.429688f,0.960938f, +0.4375f,0.960938f, +0.445313f,0.960938f, +0.453125f,0.960938f, +0.460938f,0.960938f, +0.46875f,0.960938f, +0.476563f,0.960938f, +0.484375f,0.960938f, +0.492188f,0.960938f, +0.5f,0.960938f, +0.507813f,0.960938f, +0.0f,0.96875f, +0.0078125f,0.96875f, +0.015625f,0.96875f, +0.0234375f,0.96875f, +0.03125f,0.96875f, +0.0390625f,0.96875f, +0.046875f,0.96875f, +0.0546875f,0.96875f, +0.0625f,0.96875f, +0.0703125f,0.96875f, +0.078125f,0.96875f, +0.0859375f,0.96875f, +0.09375f,0.96875f, +0.101563f,0.96875f, +0.109375f,0.96875f, +0.117188f,0.96875f, +0.125f,0.96875f, +0.132813f,0.96875f, +0.140625f,0.96875f, +0.148438f,0.96875f, +0.15625f,0.96875f, +0.164063f,0.96875f, +0.171875f,0.96875f, +0.179688f,0.96875f, +0.1875f,0.96875f, +0.195313f,0.96875f, +0.203125f,0.96875f, +0.210938f,0.96875f, +0.21875f,0.96875f, +0.226563f,0.96875f, +0.234375f,0.96875f, +0.242188f,0.96875f, +0.25f,0.96875f, +0.257813f,0.96875f, +0.265625f,0.96875f, +0.273438f,0.96875f, +0.28125f,0.96875f, +0.289063f,0.96875f, +0.296875f,0.96875f, +0.304688f,0.96875f, +0.3125f,0.96875f, +0.320313f,0.96875f, +0.328125f,0.96875f, +0.335938f,0.96875f, +0.34375f,0.96875f, +0.351563f,0.96875f, +0.359375f,0.96875f, +0.367188f,0.96875f, +0.375f,0.96875f, +0.382813f,0.96875f, +0.390625f,0.96875f, +0.398438f,0.96875f, +0.40625f,0.96875f, +0.414063f,0.96875f, +0.421875f,0.96875f, +0.429688f,0.96875f, +0.4375f,0.96875f, +0.445313f,0.96875f, +0.453125f,0.96875f, +0.460938f,0.96875f, +0.46875f,0.96875f, +0.476563f,0.96875f, +0.484375f,0.96875f, +0.492188f,0.96875f, +0.5f,0.96875f, +0.507813f,0.96875f, +0.0f,0.976563f, +0.0078125f,0.976563f, +0.015625f,0.976563f, +0.0234375f,0.976563f, +0.03125f,0.976563f, +0.0390625f,0.976563f, +0.046875f,0.976563f, +0.0546875f,0.976563f, +0.0625f,0.976563f, +0.0703125f,0.976563f, +0.078125f,0.976563f, +0.0859375f,0.976563f, +0.09375f,0.976563f, +0.101563f,0.976563f, +0.109375f,0.976563f, +0.117188f,0.976563f, +0.125f,0.976563f, +0.132813f,0.976563f, +0.140625f,0.976563f, +0.148438f,0.976563f, +0.15625f,0.976563f, +0.164063f,0.976563f, +0.171875f,0.976563f, +0.179688f,0.976563f, +0.1875f,0.976563f, +0.195313f,0.976563f, +0.203125f,0.976563f, +0.210938f,0.976563f, +0.21875f,0.976563f, +0.226563f,0.976563f, +0.234375f,0.976563f, +0.242188f,0.976563f, +0.25f,0.976563f, +0.257813f,0.976563f, +0.265625f,0.976563f, +0.273438f,0.976563f, +0.28125f,0.976563f, +0.289063f,0.976563f, +0.296875f,0.976563f, +0.304688f,0.976563f, +0.3125f,0.976563f, +0.320313f,0.976563f, +0.328125f,0.976563f, +0.335938f,0.976563f, +0.34375f,0.976563f, +0.351563f,0.976563f, +0.359375f,0.976563f, +0.367188f,0.976563f, +0.375f,0.976563f, +0.382813f,0.976563f, +0.390625f,0.976563f, +0.398438f,0.976563f, +0.40625f,0.976563f, +0.414063f,0.976563f, +0.421875f,0.976563f, +0.429688f,0.976563f, +0.4375f,0.976563f, +0.445313f,0.976563f, +0.453125f,0.976563f, +0.460938f,0.976563f, +0.46875f,0.976563f, +0.476563f,0.976563f, +0.484375f,0.976563f, +0.492188f,0.976563f, +0.5f,0.976563f, +0.507813f,0.976563f, +0.0f,0.984375f, +0.0078125f,0.984375f, +0.015625f,0.984375f, +0.0234375f,0.984375f, +0.03125f,0.984375f, +0.0390625f,0.984375f, +0.046875f,0.984375f, +0.0546875f,0.984375f, +0.0625f,0.984375f, +0.0703125f,0.984375f, +0.078125f,0.984375f, +0.0859375f,0.984375f, +0.09375f,0.984375f, +0.101563f,0.984375f, +0.109375f,0.984375f, +0.117188f,0.984375f, +0.125f,0.984375f, +0.132813f,0.984375f, +0.140625f,0.984375f, +0.148438f,0.984375f, +0.15625f,0.984375f, +0.164063f,0.984375f, +0.171875f,0.984375f, +0.179688f,0.984375f, +0.1875f,0.984375f, +0.195313f,0.984375f, +0.203125f,0.984375f, +0.210938f,0.984375f, +0.21875f,0.984375f, +0.226563f,0.984375f, +0.234375f,0.984375f, +0.242188f,0.984375f, +0.25f,0.984375f, +0.257813f,0.984375f, +0.265625f,0.984375f, +0.273438f,0.984375f, +0.28125f,0.984375f, +0.289063f,0.984375f, +0.296875f,0.984375f, +0.304688f,0.984375f, +0.3125f,0.984375f, +0.320313f,0.984375f, +0.328125f,0.984375f, +0.335938f,0.984375f, +0.34375f,0.984375f, +0.351563f,0.984375f, +0.359375f,0.984375f, +0.367188f,0.984375f, +0.375f,0.984375f, +0.382813f,0.984375f, +0.390625f,0.984375f, +0.398438f,0.984375f, +0.40625f,0.984375f, +0.414063f,0.984375f, +0.421875f,0.984375f, +0.429688f,0.984375f, +0.4375f,0.984375f, +0.445313f,0.984375f, +0.453125f,0.984375f, +0.460938f,0.984375f, +0.46875f,0.984375f, +0.476563f,0.984375f, +0.484375f,0.984375f, +0.492188f,0.984375f, +0.5f,0.984375f, +0.507813f,0.984375f, +0.0f,0.992188f, +0.0078125f,0.992188f, +0.015625f,0.992188f, +0.0234375f,0.992188f, +0.03125f,0.992188f, +0.0390625f,0.992188f, +0.046875f,0.992188f, +0.0546875f,0.992188f, +0.0625f,0.992188f, +0.0703125f,0.992188f, +0.078125f,0.992188f, +0.0859375f,0.992188f, +0.09375f,0.992188f, +0.101563f,0.992188f, +0.109375f,0.992188f, +0.117188f,0.992188f, +0.125f,0.992188f, +0.132813f,0.992188f, +0.140625f,0.992188f, +0.148438f,0.992188f, +0.15625f,0.992188f, +0.164063f,0.992188f, +0.171875f,0.992188f, +0.179688f,0.992188f, +0.1875f,0.992188f, +0.195313f,0.992188f, +0.203125f,0.992188f, +0.210938f,0.992188f, +0.21875f,0.992188f, +0.226563f,0.992188f, +0.234375f,0.992188f, +0.242188f,0.992188f, +0.25f,0.992188f, +0.257813f,0.992188f, +0.265625f,0.992188f, +0.273438f,0.992188f, +0.28125f,0.992188f, +0.289063f,0.992188f, +0.296875f,0.992188f, +0.304688f,0.992188f, +0.3125f,0.992188f, +0.320313f,0.992188f, +0.328125f,0.992188f, +0.335938f,0.992188f, +0.34375f,0.992188f, +0.351563f,0.992188f, +0.359375f,0.992188f, +0.367188f,0.992188f, +0.375f,0.992188f, +0.382813f,0.992188f, +0.390625f,0.992188f, +0.398438f,0.992188f, +0.40625f,0.992188f, +0.414063f,0.992188f, +0.421875f,0.992188f, +0.429688f,0.992188f, +0.4375f,0.992188f, +0.445313f,0.992188f, +0.453125f,0.992188f, +0.460938f,0.992188f, +0.46875f,0.992188f, +0.476563f,0.992188f, +0.484375f,0.992188f, +0.492188f,0.992188f, +0.5f,0.992188f, +0.507813f,0.992188f, +0.0f,1.0f, +0.0078125f,1.0f, +0.015625f,1.0f, +0.0234375f,1.0f, +0.03125f,1.0f, +0.0390625f,1.0f, +0.046875f,1.0f, +0.0546875f,1.0f, +0.0625f,1.0f, +0.0703125f,1.0f, +0.078125f,1.0f, +0.0859375f,1.0f, +0.09375f,1.0f, +0.101563f,1.0f, +0.109375f,1.0f, +0.117188f,1.0f, +0.125f,1.0f, +0.132813f,1.0f, +0.140625f,1.0f, +0.148438f,1.0f, +0.15625f,1.0f, +0.164063f,1.0f, +0.171875f,1.0f, +0.179688f,1.0f, +0.1875f,1.0f, +0.195313f,1.0f, +0.203125f,1.0f, +0.210938f,1.0f, +0.21875f,1.0f, +0.226563f,1.0f, +0.234375f,1.0f, +0.242188f,1.0f, +0.25f,1.0f, +0.257813f,1.0f, +0.265625f,1.0f, +0.273438f,1.0f, +0.28125f,1.0f, +0.289063f,1.0f, +0.296875f,1.0f, +0.304688f,1.0f, +0.3125f,1.0f, +0.320313f,1.0f, +0.328125f,1.0f, +0.335938f,1.0f, +0.34375f,1.0f, +0.351563f,1.0f, +0.359375f,1.0f, +0.367188f,1.0f, +0.375f,1.0f, +0.382813f,1.0f, +0.390625f,1.0f, +0.398438f,1.0f, +0.40625f,1.0f, +0.414063f,1.0f, +0.421875f,1.0f, +0.429688f,1.0f, +0.4375f,1.0f, +0.445313f,1.0f, +0.453125f,1.0f, +0.460938f,1.0f, +0.46875f,1.0f, +0.476563f,1.0f, +0.484375f,1.0f, +0.492188f,1.0f, +0.5f,1.0f, +0.507813f,1.0f, +}; + +unsigned short Landscape08Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +126,127,128, +129,128,127, +128,129,130, +131,130,129, +132,0,133, +2,133,0, +133,2,134, +4,134,2, +134,4,135, +6,135,4, +135,6,136, +8,136,6, +136,8,137, +10,137,8, +137,10,138, +12,138,10, +138,12,139, +14,139,12, +139,14,140, +16,140,14, +140,16,141, +18,141,16, +141,18,142, +20,142,18, +142,20,143, +22,143,20, +143,22,144, +24,144,22, +144,24,145, +26,145,24, +145,26,146, +28,146,26, +146,28,147, +30,147,28, +147,30,148, +32,148,30, +148,32,149, +34,149,32, +149,34,150, +36,150,34, +150,36,151, +38,151,36, +151,38,152, +40,152,38, +152,40,153, +42,153,40, +153,42,154, +44,154,42, +154,44,155, +46,155,44, +155,46,156, +48,156,46, +156,48,157, +50,157,48, +157,50,158, +52,158,50, +158,52,159, +54,159,52, +159,54,160, +56,160,54, +160,56,161, +58,161,56, +161,58,162, +60,162,58, +162,60,163, +62,163,60, +163,62,164, +64,164,62, +164,64,165, +66,165,64, +165,66,166, +68,166,66, +166,68,167, +70,167,68, +167,70,168, +72,168,70, +168,72,169, +74,169,72, +169,74,170, +76,170,74, +170,76,171, +78,171,76, +171,78,172, +80,172,78, +172,80,173, +82,173,80, +173,82,174, +84,174,82, +174,84,175, +86,175,84, +175,86,176, +88,176,86, +176,88,177, +90,177,88, +177,90,178, +92,178,90, +178,92,179, +94,179,92, +179,94,180, +96,180,94, +180,96,181, +98,181,96, +181,98,182, +100,182,98, +182,100,183, +102,183,100, +183,102,184, +104,184,102, +184,104,185, +106,185,104, +185,106,186, +108,186,106, +186,108,187, +110,187,108, +187,110,188, +112,188,110, +188,112,189, +114,189,112, +189,114,190, +116,190,114, +190,116,191, +118,191,116, +191,118,192, +120,192,118, +192,120,193, +122,193,120, +193,122,194, +124,194,122, +194,124,195, +126,195,124, +195,126,196, +128,196,126, +196,128,197, +130,197,128, +198,132,199, +133,199,132, +199,133,200, +134,200,133, +200,134,201, +135,201,134, +201,135,202, +136,202,135, +202,136,203, +137,203,136, +203,137,204, +138,204,137, +204,138,205, +139,205,138, +205,139,206, +140,206,139, +206,140,207, +141,207,140, +207,141,208, +142,208,141, +208,142,209, +143,209,142, +209,143,210, +144,210,143, +210,144,211, +145,211,144, +211,145,212, +146,212,145, +212,146,213, +147,213,146, +213,147,214, +148,214,147, +214,148,215, +149,215,148, +215,149,216, +150,216,149, +216,150,217, +151,217,150, +217,151,218, +152,218,151, +218,152,219, +153,219,152, +219,153,220, +154,220,153, +220,154,221, +155,221,154, +221,155,222, +156,222,155, +222,156,223, +157,223,156, +223,157,224, +158,224,157, +224,158,225, +159,225,158, +225,159,226, +160,226,159, +226,160,227, +161,227,160, +227,161,228, +162,228,161, +228,162,229, +163,229,162, +229,163,230, +164,230,163, +230,164,231, +165,231,164, +231,165,232, +166,232,165, +232,166,233, +167,233,166, +233,167,234, +168,234,167, +234,168,235, +169,235,168, +235,169,236, +170,236,169, +236,170,237, +171,237,170, +237,171,238, +172,238,171, +238,172,239, +173,239,172, +239,173,240, +174,240,173, +240,174,241, +175,241,174, +241,175,242, +176,242,175, +242,176,243, +177,243,176, +243,177,244, +178,244,177, +244,178,245, +179,245,178, +245,179,246, +180,246,179, +246,180,247, +181,247,180, +247,181,248, +182,248,181, +248,182,249, +183,249,182, +249,183,250, +184,250,183, +250,184,251, +185,251,184, +251,185,252, +186,252,185, +252,186,253, +187,253,186, +253,187,254, +188,254,187, +254,188,255, +189,255,188, +255,189,256, +190,256,189, +256,190,257, +191,257,190, +257,191,258, +192,258,191, +258,192,259, +193,259,192, +259,193,260, +194,260,193, +260,194,261, +195,261,194, +261,195,262, +196,262,195, +262,196,263, +197,263,196, +264,198,265, +199,265,198, +265,199,266, +200,266,199, +266,200,267, +201,267,200, +267,201,268, +202,268,201, +268,202,269, +203,269,202, +269,203,270, +204,270,203, +270,204,271, +205,271,204, +271,205,272, +206,272,205, +272,206,273, +207,273,206, +273,207,274, +208,274,207, +274,208,275, +209,275,208, +275,209,276, +210,276,209, +276,210,277, +211,277,210, +277,211,278, +212,278,211, +278,212,279, +213,279,212, +279,213,280, +214,280,213, +280,214,281, +215,281,214, +281,215,282, +216,282,215, +282,216,283, +217,283,216, +283,217,284, +218,284,217, +284,218,285, +219,285,218, +285,219,286, +220,286,219, +286,220,287, +221,287,220, +287,221,288, +222,288,221, +288,222,289, +223,289,222, +289,223,290, +224,290,223, +290,224,291, +225,291,224, +291,225,292, +226,292,225, +292,226,293, +227,293,226, +293,227,294, +228,294,227, +294,228,295, +229,295,228, +295,229,296, +230,296,229, +296,230,297, +231,297,230, +297,231,298, +232,298,231, +298,232,299, +233,299,232, +299,233,300, +234,300,233, +300,234,301, +235,301,234, +301,235,302, +236,302,235, +302,236,303, +237,303,236, +303,237,304, +238,304,237, +304,238,305, +239,305,238, +305,239,306, +240,306,239, +306,240,307, +241,307,240, +307,241,308, +242,308,241, +308,242,309, +243,309,242, +309,243,310, +244,310,243, +310,244,311, +245,311,244, +311,245,312, +246,312,245, +312,246,313, +247,313,246, +313,247,314, +248,314,247, +314,248,315, +249,315,248, +315,249,316, +250,316,249, +316,250,317, +251,317,250, +317,251,318, +252,318,251, +318,252,319, +253,319,252, +319,253,320, +254,320,253, +320,254,321, +255,321,254, +321,255,322, +256,322,255, +322,256,323, +257,323,256, +323,257,324, +258,324,257, +324,258,325, +259,325,258, +325,259,326, +260,326,259, +326,260,327, +261,327,260, +327,261,328, +262,328,261, +328,262,329, +263,329,262, +330,264,331, +265,331,264, +331,265,332, +266,332,265, +332,266,333, +267,333,266, +333,267,334, +268,334,267, +334,268,335, +269,335,268, +335,269,336, +270,336,269, +336,270,337, +271,337,270, +337,271,338, +272,338,271, +338,272,339, +273,339,272, +339,273,340, +274,340,273, +340,274,341, +275,341,274, +341,275,342, +276,342,275, +342,276,343, +277,343,276, +343,277,344, +278,344,277, +344,278,345, +279,345,278, +345,279,346, +280,346,279, +346,280,347, +281,347,280, +347,281,348, +282,348,281, +348,282,349, +283,349,282, +349,283,350, +284,350,283, +350,284,351, +285,351,284, +351,285,352, +286,352,285, +352,286,353, +287,353,286, +353,287,354, +288,354,287, +354,288,355, +289,355,288, +355,289,356, +290,356,289, +356,290,357, +291,357,290, +357,291,358, +292,358,291, +358,292,359, +293,359,292, +359,293,360, +294,360,293, +360,294,361, +295,361,294, +361,295,362, +296,362,295, +362,296,363, +297,363,296, +363,297,364, +298,364,297, +364,298,365, +299,365,298, +365,299,366, +300,366,299, +366,300,367, +301,367,300, +367,301,368, +302,368,301, +368,302,369, +303,369,302, +369,303,370, +304,370,303, +370,304,371, +305,371,304, +371,305,372, +306,372,305, +372,306,373, +307,373,306, +373,307,374, +308,374,307, +374,308,375, +309,375,308, +375,309,376, +310,376,309, +376,310,377, +311,377,310, +377,311,378, +312,378,311, +378,312,379, +313,379,312, +379,313,380, +314,380,313, +380,314,381, +315,381,314, +381,315,382, +316,382,315, +382,316,383, +317,383,316, +383,317,384, +318,384,317, +384,318,385, +319,385,318, +385,319,386, +320,386,319, +386,320,387, +321,387,320, +387,321,388, +322,388,321, +388,322,389, +323,389,322, +389,323,390, +324,390,323, +390,324,391, +325,391,324, +391,325,392, +326,392,325, +392,326,393, +327,393,326, +393,327,394, +328,394,327, +394,328,395, +329,395,328, +396,330,397, +331,397,330, +397,331,398, +332,398,331, +398,332,399, +333,399,332, +399,333,400, +334,400,333, +400,334,401, +335,401,334, +401,335,402, +336,402,335, +402,336,403, +337,403,336, +403,337,404, +338,404,337, +404,338,405, +339,405,338, +405,339,406, +340,406,339, +406,340,407, +341,407,340, +407,341,408, +342,408,341, +408,342,409, +343,409,342, +409,343,410, +344,410,343, +410,344,411, +345,411,344, +411,345,412, +346,412,345, +412,346,413, +347,413,346, +413,347,414, +348,414,347, +414,348,415, +349,415,348, +415,349,416, +350,416,349, +416,350,417, +351,417,350, +417,351,418, +352,418,351, +418,352,419, +353,419,352, +419,353,420, +354,420,353, +420,354,421, +355,421,354, +421,355,422, +356,422,355, +422,356,423, +357,423,356, +423,357,424, +358,424,357, +424,358,425, +359,425,358, +425,359,426, +360,426,359, +426,360,427, +361,427,360, +427,361,428, +362,428,361, +428,362,429, +363,429,362, +429,363,430, +364,430,363, +430,364,431, +365,431,364, +431,365,432, +366,432,365, +432,366,433, +367,433,366, +433,367,434, +368,434,367, +434,368,435, +369,435,368, +435,369,436, +370,436,369, +436,370,437, +371,437,370, +437,371,438, +372,438,371, +438,372,439, +373,439,372, +439,373,440, +374,440,373, +440,374,441, +375,441,374, +441,375,442, +376,442,375, +442,376,443, +377,443,376, +443,377,444, +378,444,377, +444,378,445, +379,445,378, +445,379,446, +380,446,379, +446,380,447, +381,447,380, +447,381,448, +382,448,381, +448,382,449, +383,449,382, +449,383,450, +384,450,383, +450,384,451, +385,451,384, +451,385,452, +386,452,385, +452,386,453, +387,453,386, +453,387,454, +388,454,387, +454,388,455, +389,455,388, +455,389,456, +390,456,389, +456,390,457, +391,457,390, +457,391,458, +392,458,391, +458,392,459, +393,459,392, +459,393,460, +394,460,393, +460,394,461, +395,461,394, +462,396,463, +397,463,396, +463,397,464, +398,464,397, +464,398,465, +399,465,398, +465,399,466, +400,466,399, +466,400,467, +401,467,400, +467,401,468, +402,468,401, +468,402,469, +403,469,402, +469,403,470, +404,470,403, +470,404,471, +405,471,404, +471,405,472, +406,472,405, +472,406,473, +407,473,406, +473,407,474, +408,474,407, +474,408,475, +409,475,408, +475,409,476, +410,476,409, +476,410,477, +411,477,410, +477,411,478, +412,478,411, +478,412,479, +413,479,412, +479,413,480, +414,480,413, +480,414,481, +415,481,414, +481,415,482, +416,482,415, +482,416,483, +417,483,416, +483,417,484, +418,484,417, +484,418,485, +419,485,418, +485,419,486, +420,486,419, +486,420,487, +421,487,420, +487,421,488, +422,488,421, +488,422,489, +423,489,422, +489,423,490, +424,490,423, +490,424,491, +425,491,424, +491,425,492, +426,492,425, +492,426,493, +427,493,426, +493,427,494, +428,494,427, +494,428,495, +429,495,428, +495,429,496, +430,496,429, +496,430,497, +431,497,430, +497,431,498, +432,498,431, +498,432,499, +433,499,432, +499,433,500, +434,500,433, +500,434,501, +435,501,434, +501,435,502, +436,502,435, +502,436,503, +437,503,436, +503,437,504, +438,504,437, +504,438,505, +439,505,438, +505,439,506, +440,506,439, +506,440,507, +441,507,440, +507,441,508, +442,508,441, +508,442,509, +443,509,442, +509,443,510, +444,510,443, +510,444,511, +445,511,444, +511,445,512, +446,512,445, +512,446,513, +447,513,446, +513,447,514, +448,514,447, +514,448,515, +449,515,448, +515,449,516, +450,516,449, +516,450,517, +451,517,450, +517,451,518, +452,518,451, +518,452,519, +453,519,452, +519,453,520, +454,520,453, +520,454,521, +455,521,454, +521,455,522, +456,522,455, +522,456,523, +457,523,456, +523,457,524, +458,524,457, +524,458,525, +459,525,458, +525,459,526, +460,526,459, +526,460,527, +461,527,460, +528,462,529, +463,529,462, +529,463,530, +464,530,463, +530,464,531, +465,531,464, +531,465,532, +466,532,465, +532,466,533, +467,533,466, +533,467,534, +468,534,467, +534,468,535, +469,535,468, +535,469,536, +470,536,469, +536,470,537, +471,537,470, +537,471,538, +472,538,471, +538,472,539, +473,539,472, +539,473,540, +474,540,473, +540,474,541, +475,541,474, +541,475,542, +476,542,475, +542,476,543, +477,543,476, +543,477,544, +478,544,477, +544,478,545, +479,545,478, +545,479,546, +480,546,479, +546,480,547, +481,547,480, +547,481,548, +482,548,481, +548,482,549, +483,549,482, +549,483,550, +484,550,483, +550,484,551, +485,551,484, +551,485,552, +486,552,485, +552,486,553, +487,553,486, +553,487,554, +488,554,487, +554,488,555, +489,555,488, +555,489,556, +490,556,489, +556,490,557, +491,557,490, +557,491,558, +492,558,491, +558,492,559, +493,559,492, +559,493,560, +494,560,493, +560,494,561, +495,561,494, +561,495,562, +496,562,495, +562,496,563, +497,563,496, +563,497,564, +498,564,497, +564,498,565, +499,565,498, +565,499,566, +500,566,499, +566,500,567, +501,567,500, +567,501,568, +502,568,501, +568,502,569, +503,569,502, +569,503,570, +504,570,503, +570,504,571, +505,571,504, +571,505,572, +506,572,505, +572,506,573, +507,573,506, +573,507,574, +508,574,507, +574,508,575, +509,575,508, +575,509,576, +510,576,509, +576,510,577, +511,577,510, +577,511,578, +512,578,511, +578,512,579, +513,579,512, +579,513,580, +514,580,513, +580,514,581, +515,581,514, +581,515,582, +516,582,515, +582,516,583, +517,583,516, +583,517,584, +518,584,517, +584,518,585, +519,585,518, +585,519,586, +520,586,519, +586,520,587, +521,587,520, +587,521,588, +522,588,521, +588,522,589, +523,589,522, +589,523,590, +524,590,523, +590,524,591, +525,591,524, +591,525,592, +526,592,525, +592,526,593, +527,593,526, +594,528,595, +529,595,528, +595,529,596, +530,596,529, +596,530,597, +531,597,530, +597,531,598, +532,598,531, +598,532,599, +533,599,532, +599,533,600, +534,600,533, +600,534,601, +535,601,534, +601,535,602, +536,602,535, +602,536,603, +537,603,536, +603,537,604, +538,604,537, +604,538,605, +539,605,538, +605,539,606, +540,606,539, +606,540,607, +541,607,540, +607,541,608, +542,608,541, +608,542,609, +543,609,542, +609,543,610, +544,610,543, +610,544,611, +545,611,544, +611,545,612, +546,612,545, +612,546,613, +547,613,546, +613,547,614, +548,614,547, +614,548,615, +549,615,548, +615,549,616, +550,616,549, +616,550,617, +551,617,550, +617,551,618, +552,618,551, +618,552,619, +553,619,552, +619,553,620, +554,620,553, +620,554,621, +555,621,554, +621,555,622, +556,622,555, +622,556,623, +557,623,556, +623,557,624, +558,624,557, +624,558,625, +559,625,558, +625,559,626, +560,626,559, +626,560,627, +561,627,560, +627,561,628, +562,628,561, +628,562,629, +563,629,562, +629,563,630, +564,630,563, +630,564,631, +565,631,564, +631,565,632, +566,632,565, +632,566,633, +567,633,566, +633,567,634, +568,634,567, +634,568,635, +569,635,568, +635,569,636, +570,636,569, +636,570,637, +571,637,570, +637,571,638, +572,638,571, +638,572,639, +573,639,572, +639,573,640, +574,640,573, +640,574,641, +575,641,574, +641,575,642, +576,642,575, +642,576,643, +577,643,576, +643,577,644, +578,644,577, +644,578,645, +579,645,578, +645,579,646, +580,646,579, +646,580,647, +581,647,580, +647,581,648, +582,648,581, +648,582,649, +583,649,582, +649,583,650, +584,650,583, +650,584,651, +585,651,584, +651,585,652, +586,652,585, +652,586,653, +587,653,586, +653,587,654, +588,654,587, +654,588,655, +589,655,588, +655,589,656, +590,656,589, +656,590,657, +591,657,590, +657,591,658, +592,658,591, +658,592,659, +593,659,592, +660,594,661, +595,661,594, +661,595,662, +596,662,595, +662,596,663, +597,663,596, +663,597,664, +598,664,597, +664,598,665, +599,665,598, +665,599,666, +600,666,599, +666,600,667, +601,667,600, +667,601,668, +602,668,601, +668,602,669, +603,669,602, +669,603,670, +604,670,603, +670,604,671, +605,671,604, +671,605,672, +606,672,605, +672,606,673, +607,673,606, +673,607,674, +608,674,607, +674,608,675, +609,675,608, +675,609,676, +610,676,609, +676,610,677, +611,677,610, +677,611,678, +612,678,611, +678,612,679, +613,679,612, +679,613,680, +614,680,613, +680,614,681, +615,681,614, +681,615,682, +616,682,615, +682,616,683, +617,683,616, +683,617,684, +618,684,617, +684,618,685, +619,685,618, +685,619,686, +620,686,619, +686,620,687, +621,687,620, +687,621,688, +622,688,621, +688,622,689, +623,689,622, +689,623,690, +624,690,623, +690,624,691, +625,691,624, +691,625,692, +626,692,625, +692,626,693, +627,693,626, +693,627,694, +628,694,627, +694,628,695, +629,695,628, +695,629,696, +630,696,629, +696,630,697, +631,697,630, +697,631,698, +632,698,631, +698,632,699, +633,699,632, +699,633,700, +634,700,633, +700,634,701, +635,701,634, +701,635,702, +636,702,635, +702,636,703, +637,703,636, +703,637,704, +638,704,637, +704,638,705, +639,705,638, +705,639,706, +640,706,639, +706,640,707, +641,707,640, +707,641,708, +642,708,641, +708,642,709, +643,709,642, +709,643,710, +644,710,643, +710,644,711, +645,711,644, +711,645,712, +646,712,645, +712,646,713, +647,713,646, +713,647,714, +648,714,647, +714,648,715, +649,715,648, +715,649,716, +650,716,649, +716,650,717, +651,717,650, +717,651,718, +652,718,651, +718,652,719, +653,719,652, +719,653,720, +654,720,653, +720,654,721, +655,721,654, +721,655,722, +656,722,655, +722,656,723, +657,723,656, +723,657,724, +658,724,657, +724,658,725, +659,725,658, +726,660,727, +661,727,660, +727,661,728, +662,728,661, +728,662,729, +663,729,662, +729,663,730, +664,730,663, +730,664,731, +665,731,664, +731,665,732, +666,732,665, +732,666,733, +667,733,666, +733,667,734, +668,734,667, +734,668,735, +669,735,668, +735,669,736, +670,736,669, +736,670,737, +671,737,670, +737,671,738, +672,738,671, +738,672,739, +673,739,672, +739,673,740, +674,740,673, +740,674,741, +675,741,674, +741,675,742, +676,742,675, +742,676,743, +677,743,676, +743,677,744, +678,744,677, +744,678,745, +679,745,678, +745,679,746, +680,746,679, +746,680,747, +681,747,680, +747,681,748, +682,748,681, +748,682,749, +683,749,682, +749,683,750, +684,750,683, +750,684,751, +685,751,684, +751,685,752, +686,752,685, +752,686,753, +687,753,686, +753,687,754, +688,754,687, +754,688,755, +689,755,688, +755,689,756, +690,756,689, +756,690,757, +691,757,690, +757,691,758, +692,758,691, +758,692,759, +693,759,692, +759,693,760, +694,760,693, +760,694,761, +695,761,694, +761,695,762, +696,762,695, +762,696,763, +697,763,696, +763,697,764, +698,764,697, +764,698,765, +699,765,698, +765,699,766, +700,766,699, +766,700,767, +701,767,700, +767,701,768, +702,768,701, +768,702,769, +703,769,702, +769,703,770, +704,770,703, +770,704,771, +705,771,704, +771,705,772, +706,772,705, +772,706,773, +707,773,706, +773,707,774, +708,774,707, +774,708,775, +709,775,708, +775,709,776, +710,776,709, +776,710,777, +711,777,710, +777,711,778, +712,778,711, +778,712,779, +713,779,712, +779,713,780, +714,780,713, +780,714,781, +715,781,714, +781,715,782, +716,782,715, +782,716,783, +717,783,716, +783,717,784, +718,784,717, +784,718,785, +719,785,718, +785,719,786, +720,786,719, +786,720,787, +721,787,720, +787,721,788, +722,788,721, +788,722,789, +723,789,722, +789,723,790, +724,790,723, +790,724,791, +725,791,724, +792,726,793, +727,793,726, +793,727,794, +728,794,727, +794,728,795, +729,795,728, +795,729,796, +730,796,729, +796,730,797, +731,797,730, +797,731,798, +732,798,731, +798,732,799, +733,799,732, +799,733,800, +734,800,733, +800,734,801, +735,801,734, +801,735,802, +736,802,735, +802,736,803, +737,803,736, +803,737,804, +738,804,737, +804,738,805, +739,805,738, +805,739,806, +740,806,739, +806,740,807, +741,807,740, +807,741,808, +742,808,741, +808,742,809, +743,809,742, +809,743,810, +744,810,743, +810,744,811, +745,811,744, +811,745,812, +746,812,745, +812,746,813, +747,813,746, +813,747,814, +748,814,747, +814,748,815, +749,815,748, +815,749,816, +750,816,749, +816,750,817, +751,817,750, +817,751,818, +752,818,751, +818,752,819, +753,819,752, +819,753,820, +754,820,753, +820,754,821, +755,821,754, +821,755,822, +756,822,755, +822,756,823, +757,823,756, +823,757,824, +758,824,757, +824,758,825, +759,825,758, +825,759,826, +760,826,759, +826,760,827, +761,827,760, +827,761,828, +762,828,761, +828,762,829, +763,829,762, +829,763,830, +764,830,763, +830,764,831, +765,831,764, +831,765,832, +766,832,765, +832,766,833, +767,833,766, +833,767,834, +768,834,767, +834,768,835, +769,835,768, +835,769,836, +770,836,769, +836,770,837, +771,837,770, +837,771,838, +772,838,771, +838,772,839, +773,839,772, +839,773,840, +774,840,773, +840,774,841, +775,841,774, +841,775,842, +776,842,775, +842,776,843, +777,843,776, +843,777,844, +778,844,777, +844,778,845, +779,845,778, +845,779,846, +780,846,779, +846,780,847, +781,847,780, +847,781,848, +782,848,781, +848,782,849, +783,849,782, +849,783,850, +784,850,783, +850,784,851, +785,851,784, +851,785,852, +786,852,785, +852,786,853, +787,853,786, +853,787,854, +788,854,787, +854,788,855, +789,855,788, +855,789,856, +790,856,789, +856,790,857, +791,857,790, +858,792,859, +793,859,792, +859,793,860, +794,860,793, +860,794,861, +795,861,794, +861,795,862, +796,862,795, +862,796,863, +797,863,796, +863,797,864, +798,864,797, +864,798,865, +799,865,798, +865,799,866, +800,866,799, +866,800,867, +801,867,800, +867,801,868, +802,868,801, +868,802,869, +803,869,802, +869,803,870, +804,870,803, +870,804,871, +805,871,804, +871,805,872, +806,872,805, +872,806,873, +807,873,806, +873,807,874, +808,874,807, +874,808,875, +809,875,808, +875,809,876, +810,876,809, +876,810,877, +811,877,810, +877,811,878, +812,878,811, +878,812,879, +813,879,812, +879,813,880, +814,880,813, +880,814,881, +815,881,814, +881,815,882, +816,882,815, +882,816,883, +817,883,816, +883,817,884, +818,884,817, +884,818,885, +819,885,818, +885,819,886, +820,886,819, +886,820,887, +821,887,820, +887,821,888, +822,888,821, +888,822,889, +823,889,822, +889,823,890, +824,890,823, +890,824,891, +825,891,824, +891,825,892, +826,892,825, +892,826,893, +827,893,826, +893,827,894, +828,894,827, +894,828,895, +829,895,828, +895,829,896, +830,896,829, +896,830,897, +831,897,830, +897,831,898, +832,898,831, +898,832,899, +833,899,832, +899,833,900, +834,900,833, +900,834,901, +835,901,834, +901,835,902, +836,902,835, +902,836,903, +837,903,836, +903,837,904, +838,904,837, +904,838,905, +839,905,838, +905,839,906, +840,906,839, +906,840,907, +841,907,840, +907,841,908, +842,908,841, +908,842,909, +843,909,842, +909,843,910, +844,910,843, +910,844,911, +845,911,844, +911,845,912, +846,912,845, +912,846,913, +847,913,846, +913,847,914, +848,914,847, +914,848,915, +849,915,848, +915,849,916, +850,916,849, +916,850,917, +851,917,850, +917,851,918, +852,918,851, +918,852,919, +853,919,852, +919,853,920, +854,920,853, +920,854,921, +855,921,854, +921,855,922, +856,922,855, +922,856,923, +857,923,856, +924,858,925, +859,925,858, +925,859,926, +860,926,859, +926,860,927, +861,927,860, +927,861,928, +862,928,861, +928,862,929, +863,929,862, +929,863,930, +864,930,863, +930,864,931, +865,931,864, +931,865,932, +866,932,865, +932,866,933, +867,933,866, +933,867,934, +868,934,867, +934,868,935, +869,935,868, +935,869,936, +870,936,869, +936,870,937, +871,937,870, +937,871,938, +872,938,871, +938,872,939, +873,939,872, +939,873,940, +874,940,873, +940,874,941, +875,941,874, +941,875,942, +876,942,875, +942,876,943, +877,943,876, +943,877,944, +878,944,877, +944,878,945, +879,945,878, +945,879,946, +880,946,879, +946,880,947, +881,947,880, +947,881,948, +882,948,881, +948,882,949, +883,949,882, +949,883,950, +884,950,883, +950,884,951, +885,951,884, +951,885,952, +886,952,885, +952,886,953, +887,953,886, +953,887,954, +888,954,887, +954,888,955, +889,955,888, +955,889,956, +890,956,889, +956,890,957, +891,957,890, +957,891,958, +892,958,891, +958,892,959, +893,959,892, +959,893,960, +894,960,893, +960,894,961, +895,961,894, +961,895,962, +896,962,895, +962,896,963, +897,963,896, +963,897,964, +898,964,897, +964,898,965, +899,965,898, +965,899,966, +900,966,899, +966,900,967, +901,967,900, +967,901,968, +902,968,901, +968,902,969, +903,969,902, +969,903,970, +904,970,903, +970,904,971, +905,971,904, +971,905,972, +906,972,905, +972,906,973, +907,973,906, +973,907,974, +908,974,907, +974,908,975, +909,975,908, +975,909,976, +910,976,909, +976,910,977, +911,977,910, +977,911,978, +912,978,911, +978,912,979, +913,979,912, +979,913,980, +914,980,913, +980,914,981, +915,981,914, +981,915,982, +916,982,915, +982,916,983, +917,983,916, +983,917,984, +918,984,917, +984,918,985, +919,985,918, +985,919,986, +920,986,919, +986,920,987, +921,987,920, +987,921,988, +922,988,921, +988,922,989, +923,989,922, +990,924,991, +925,991,924, +991,925,992, +926,992,925, +992,926,993, +927,993,926, +993,927,994, +928,994,927, +994,928,995, +929,995,928, +995,929,996, +930,996,929, +996,930,997, +931,997,930, +997,931,998, +932,998,931, +998,932,999, +933,999,932, +999,933,1000, +934,1000,933, +1000,934,1001, +935,1001,934, +1001,935,1002, +936,1002,935, +1002,936,1003, +937,1003,936, +1003,937,1004, +938,1004,937, +1004,938,1005, +939,1005,938, +1005,939,1006, +940,1006,939, +1006,940,1007, +941,1007,940, +1007,941,1008, +942,1008,941, +1008,942,1009, +943,1009,942, +1009,943,1010, +944,1010,943, +1010,944,1011, +945,1011,944, +1011,945,1012, +946,1012,945, +1012,946,1013, +947,1013,946, +1013,947,1014, +948,1014,947, +1014,948,1015, +949,1015,948, +1015,949,1016, +950,1016,949, +1016,950,1017, +951,1017,950, +1017,951,1018, +952,1018,951, +1018,952,1019, +953,1019,952, +1019,953,1020, +954,1020,953, +1020,954,1021, +955,1021,954, +1021,955,1022, +956,1022,955, +1022,956,1023, +957,1023,956, +1023,957,1024, +958,1024,957, +1024,958,1025, +959,1025,958, +1025,959,1026, +960,1026,959, +1026,960,1027, +961,1027,960, +1027,961,1028, +962,1028,961, +1028,962,1029, +963,1029,962, +1029,963,1030, +964,1030,963, +1030,964,1031, +965,1031,964, +1031,965,1032, +966,1032,965, +1032,966,1033, +967,1033,966, +1033,967,1034, +968,1034,967, +1034,968,1035, +969,1035,968, +1035,969,1036, +970,1036,969, +1036,970,1037, +971,1037,970, +1037,971,1038, +972,1038,971, +1038,972,1039, +973,1039,972, +1039,973,1040, +974,1040,973, +1040,974,1041, +975,1041,974, +1041,975,1042, +976,1042,975, +1042,976,1043, +977,1043,976, +1043,977,1044, +978,1044,977, +1044,978,1045, +979,1045,978, +1045,979,1046, +980,1046,979, +1046,980,1047, +981,1047,980, +1047,981,1048, +982,1048,981, +1048,982,1049, +983,1049,982, +1049,983,1050, +984,1050,983, +1050,984,1051, +985,1051,984, +1051,985,1052, +986,1052,985, +1052,986,1053, +987,1053,986, +1053,987,1054, +988,1054,987, +1054,988,1055, +989,1055,988, +1056,990,1057, +991,1057,990, +1057,991,1058, +992,1058,991, +1058,992,1059, +993,1059,992, +1059,993,1060, +994,1060,993, +1060,994,1061, +995,1061,994, +1061,995,1062, +996,1062,995, +1062,996,1063, +997,1063,996, +1063,997,1064, +998,1064,997, +1064,998,1065, +999,1065,998, +1065,999,1066, +1000,1066,999, +1066,1000,1067, +1001,1067,1000, +1067,1001,1068, +1002,1068,1001, +1068,1002,1069, +1003,1069,1002, +1069,1003,1070, +1004,1070,1003, +1070,1004,1071, +1005,1071,1004, +1071,1005,1072, +1006,1072,1005, +1072,1006,1073, +1007,1073,1006, +1073,1007,1074, +1008,1074,1007, +1074,1008,1075, +1009,1075,1008, +1075,1009,1076, +1010,1076,1009, +1076,1010,1077, +1011,1077,1010, +1077,1011,1078, +1012,1078,1011, +1078,1012,1079, +1013,1079,1012, +1079,1013,1080, +1014,1080,1013, +1080,1014,1081, +1015,1081,1014, +1081,1015,1082, +1016,1082,1015, +1082,1016,1083, +1017,1083,1016, +1083,1017,1084, +1018,1084,1017, +1084,1018,1085, +1019,1085,1018, +1085,1019,1086, +1020,1086,1019, +1086,1020,1087, +1021,1087,1020, +1087,1021,1088, +1022,1088,1021, +1088,1022,1089, +1023,1089,1022, +1089,1023,1090, +1024,1090,1023, +1090,1024,1091, +1025,1091,1024, +1091,1025,1092, +1026,1092,1025, +1092,1026,1093, +1027,1093,1026, +1093,1027,1094, +1028,1094,1027, +1094,1028,1095, +1029,1095,1028, +1095,1029,1096, +1030,1096,1029, +1096,1030,1097, +1031,1097,1030, +1097,1031,1098, +1032,1098,1031, +1098,1032,1099, +1033,1099,1032, +1099,1033,1100, +1034,1100,1033, +1100,1034,1101, +1035,1101,1034, +1101,1035,1102, +1036,1102,1035, +1102,1036,1103, +1037,1103,1036, +1103,1037,1104, +1038,1104,1037, +1104,1038,1105, +1039,1105,1038, +1105,1039,1106, +1040,1106,1039, +1106,1040,1107, +1041,1107,1040, +1107,1041,1108, +1042,1108,1041, +1108,1042,1109, +1043,1109,1042, +1109,1043,1110, +1044,1110,1043, +1110,1044,1111, +1045,1111,1044, +1111,1045,1112, +1046,1112,1045, +1112,1046,1113, +1047,1113,1046, +1113,1047,1114, +1048,1114,1047, +1114,1048,1115, +1049,1115,1048, +1115,1049,1116, +1050,1116,1049, +1116,1050,1117, +1051,1117,1050, +1117,1051,1118, +1052,1118,1051, +1118,1052,1119, +1053,1119,1052, +1119,1053,1120, +1054,1120,1053, +1120,1054,1121, +1055,1121,1054, +1122,1056,1123, +1057,1123,1056, +1123,1057,1124, +1058,1124,1057, +1124,1058,1125, +1059,1125,1058, +1125,1059,1126, +1060,1126,1059, +1126,1060,1127, +1061,1127,1060, +1127,1061,1128, +1062,1128,1061, +1128,1062,1129, +1063,1129,1062, +1129,1063,1130, +1064,1130,1063, +1130,1064,1131, +1065,1131,1064, +1131,1065,1132, +1066,1132,1065, +1132,1066,1133, +1067,1133,1066, +1133,1067,1134, +1068,1134,1067, +1134,1068,1135, +1069,1135,1068, +1135,1069,1136, +1070,1136,1069, +1136,1070,1137, +1071,1137,1070, +1137,1071,1138, +1072,1138,1071, +1138,1072,1139, +1073,1139,1072, +1139,1073,1140, +1074,1140,1073, +1140,1074,1141, +1075,1141,1074, +1141,1075,1142, +1076,1142,1075, +1142,1076,1143, +1077,1143,1076, +1143,1077,1144, +1078,1144,1077, +1144,1078,1145, +1079,1145,1078, +1145,1079,1146, +1080,1146,1079, +1146,1080,1147, +1081,1147,1080, +1147,1081,1148, +1082,1148,1081, +1148,1082,1149, +1083,1149,1082, +1149,1083,1150, +1084,1150,1083, +1150,1084,1151, +1085,1151,1084, +1151,1085,1152, +1086,1152,1085, +1152,1086,1153, +1087,1153,1086, +1153,1087,1154, +1088,1154,1087, +1154,1088,1155, +1089,1155,1088, +1155,1089,1156, +1090,1156,1089, +1156,1090,1157, +1091,1157,1090, +1157,1091,1158, +1092,1158,1091, +1158,1092,1159, +1093,1159,1092, +1159,1093,1160, +1094,1160,1093, +1160,1094,1161, +1095,1161,1094, +1161,1095,1162, +1096,1162,1095, +1162,1096,1163, +1097,1163,1096, +1163,1097,1164, +1098,1164,1097, +1164,1098,1165, +1099,1165,1098, +1165,1099,1166, +1100,1166,1099, +1166,1100,1167, +1101,1167,1100, +1167,1101,1168, +1102,1168,1101, +1168,1102,1169, +1103,1169,1102, +1169,1103,1170, +1104,1170,1103, +1170,1104,1171, +1105,1171,1104, +1171,1105,1172, +1106,1172,1105, +1172,1106,1173, +1107,1173,1106, +1173,1107,1174, +1108,1174,1107, +1174,1108,1175, +1109,1175,1108, +1175,1109,1176, +1110,1176,1109, +1176,1110,1177, +1111,1177,1110, +1177,1111,1178, +1112,1178,1111, +1178,1112,1179, +1113,1179,1112, +1179,1113,1180, +1114,1180,1113, +1180,1114,1181, +1115,1181,1114, +1181,1115,1182, +1116,1182,1115, +1182,1116,1183, +1117,1183,1116, +1183,1117,1184, +1118,1184,1117, +1184,1118,1185, +1119,1185,1118, +1185,1119,1186, +1120,1186,1119, +1186,1120,1187, +1121,1187,1120, +1188,1122,1189, +1123,1189,1122, +1189,1123,1190, +1124,1190,1123, +1190,1124,1191, +1125,1191,1124, +1191,1125,1192, +1126,1192,1125, +1192,1126,1193, +1127,1193,1126, +1193,1127,1194, +1128,1194,1127, +1194,1128,1195, +1129,1195,1128, +1195,1129,1196, +1130,1196,1129, +1196,1130,1197, +1131,1197,1130, +1197,1131,1198, +1132,1198,1131, +1198,1132,1199, +1133,1199,1132, +1199,1133,1200, +1134,1200,1133, +1200,1134,1201, +1135,1201,1134, +1201,1135,1202, +1136,1202,1135, +1202,1136,1203, +1137,1203,1136, +1203,1137,1204, +1138,1204,1137, +1204,1138,1205, +1139,1205,1138, +1205,1139,1206, +1140,1206,1139, +1206,1140,1207, +1141,1207,1140, +1207,1141,1208, +1142,1208,1141, +1208,1142,1209, +1143,1209,1142, +1209,1143,1210, +1144,1210,1143, +1210,1144,1211, +1145,1211,1144, +1211,1145,1212, +1146,1212,1145, +1212,1146,1213, +1147,1213,1146, +1213,1147,1214, +1148,1214,1147, +1214,1148,1215, +1149,1215,1148, +1215,1149,1216, +1150,1216,1149, +1216,1150,1217, +1151,1217,1150, +1217,1151,1218, +1152,1218,1151, +1218,1152,1219, +1153,1219,1152, +1219,1153,1220, +1154,1220,1153, +1220,1154,1221, +1155,1221,1154, +1221,1155,1222, +1156,1222,1155, +1222,1156,1223, +1157,1223,1156, +1223,1157,1224, +1158,1224,1157, +1224,1158,1225, +1159,1225,1158, +1225,1159,1226, +1160,1226,1159, +1226,1160,1227, +1161,1227,1160, +1227,1161,1228, +1162,1228,1161, +1228,1162,1229, +1163,1229,1162, +1229,1163,1230, +1164,1230,1163, +1230,1164,1231, +1165,1231,1164, +1231,1165,1232, +1166,1232,1165, +1232,1166,1233, +1167,1233,1166, +1233,1167,1234, +1168,1234,1167, +1234,1168,1235, +1169,1235,1168, +1235,1169,1236, +1170,1236,1169, +1236,1170,1237, +1171,1237,1170, +1237,1171,1238, +1172,1238,1171, +1238,1172,1239, +1173,1239,1172, +1239,1173,1240, +1174,1240,1173, +1240,1174,1241, +1175,1241,1174, +1241,1175,1242, +1176,1242,1175, +1242,1176,1243, +1177,1243,1176, +1243,1177,1244, +1178,1244,1177, +1244,1178,1245, +1179,1245,1178, +1245,1179,1246, +1180,1246,1179, +1246,1180,1247, +1181,1247,1180, +1247,1181,1248, +1182,1248,1181, +1248,1182,1249, +1183,1249,1182, +1249,1183,1250, +1184,1250,1183, +1250,1184,1251, +1185,1251,1184, +1251,1185,1252, +1186,1252,1185, +1252,1186,1253, +1187,1253,1186, +1254,1188,1255, +1189,1255,1188, +1255,1189,1256, +1190,1256,1189, +1256,1190,1257, +1191,1257,1190, +1257,1191,1258, +1192,1258,1191, +1258,1192,1259, +1193,1259,1192, +1259,1193,1260, +1194,1260,1193, +1260,1194,1261, +1195,1261,1194, +1261,1195,1262, +1196,1262,1195, +1262,1196,1263, +1197,1263,1196, +1263,1197,1264, +1198,1264,1197, +1264,1198,1265, +1199,1265,1198, +1265,1199,1266, +1200,1266,1199, +1266,1200,1267, +1201,1267,1200, +1267,1201,1268, +1202,1268,1201, +1268,1202,1269, +1203,1269,1202, +1269,1203,1270, +1204,1270,1203, +1270,1204,1271, +1205,1271,1204, +1271,1205,1272, +1206,1272,1205, +1272,1206,1273, +1207,1273,1206, +1273,1207,1274, +1208,1274,1207, +1274,1208,1275, +1209,1275,1208, +1275,1209,1276, +1210,1276,1209, +1276,1210,1277, +1211,1277,1210, +1277,1211,1278, +1212,1278,1211, +1278,1212,1279, +1213,1279,1212, +1279,1213,1280, +1214,1280,1213, +1280,1214,1281, +1215,1281,1214, +1281,1215,1282, +1216,1282,1215, +1282,1216,1283, +1217,1283,1216, +1283,1217,1284, +1218,1284,1217, +1284,1218,1285, +1219,1285,1218, +1285,1219,1286, +1220,1286,1219, +1286,1220,1287, +1221,1287,1220, +1287,1221,1288, +1222,1288,1221, +1288,1222,1289, +1223,1289,1222, +1289,1223,1290, +1224,1290,1223, +1290,1224,1291, +1225,1291,1224, +1291,1225,1292, +1226,1292,1225, +1292,1226,1293, +1227,1293,1226, +1293,1227,1294, +1228,1294,1227, +1294,1228,1295, +1229,1295,1228, +1295,1229,1296, +1230,1296,1229, +1296,1230,1297, +1231,1297,1230, +1297,1231,1298, +1232,1298,1231, +1298,1232,1299, +1233,1299,1232, +1299,1233,1300, +1234,1300,1233, +1300,1234,1301, +1235,1301,1234, +1301,1235,1302, +1236,1302,1235, +1302,1236,1303, +1237,1303,1236, +1303,1237,1304, +1238,1304,1237, +1304,1238,1305, +1239,1305,1238, +1305,1239,1306, +1240,1306,1239, +1306,1240,1307, +1241,1307,1240, +1307,1241,1308, +1242,1308,1241, +1308,1242,1309, +1243,1309,1242, +1309,1243,1310, +1244,1310,1243, +1310,1244,1311, +1245,1311,1244, +1311,1245,1312, +1246,1312,1245, +1312,1246,1313, +1247,1313,1246, +1313,1247,1314, +1248,1314,1247, +1314,1248,1315, +1249,1315,1248, +1315,1249,1316, +1250,1316,1249, +1316,1250,1317, +1251,1317,1250, +1317,1251,1318, +1252,1318,1251, +1318,1252,1319, +1253,1319,1252, +1320,1254,1321, +1255,1321,1254, +1321,1255,1322, +1256,1322,1255, +1322,1256,1323, +1257,1323,1256, +1323,1257,1324, +1258,1324,1257, +1324,1258,1325, +1259,1325,1258, +1325,1259,1326, +1260,1326,1259, +1326,1260,1327, +1261,1327,1260, +1327,1261,1328, +1262,1328,1261, +1328,1262,1329, +1263,1329,1262, +1329,1263,1330, +1264,1330,1263, +1330,1264,1331, +1265,1331,1264, +1331,1265,1332, +1266,1332,1265, +1332,1266,1333, +1267,1333,1266, +1333,1267,1334, +1268,1334,1267, +1334,1268,1335, +1269,1335,1268, +1335,1269,1336, +1270,1336,1269, +1336,1270,1337, +1271,1337,1270, +1337,1271,1338, +1272,1338,1271, +1338,1272,1339, +1273,1339,1272, +1339,1273,1340, +1274,1340,1273, +1340,1274,1341, +1275,1341,1274, +1341,1275,1342, +1276,1342,1275, +1342,1276,1343, +1277,1343,1276, +1343,1277,1344, +1278,1344,1277, +1344,1278,1345, +1279,1345,1278, +1345,1279,1346, +1280,1346,1279, +1346,1280,1347, +1281,1347,1280, +1347,1281,1348, +1282,1348,1281, +1348,1282,1349, +1283,1349,1282, +1349,1283,1350, +1284,1350,1283, +1350,1284,1351, +1285,1351,1284, +1351,1285,1352, +1286,1352,1285, +1352,1286,1353, +1287,1353,1286, +1353,1287,1354, +1288,1354,1287, +1354,1288,1355, +1289,1355,1288, +1355,1289,1356, +1290,1356,1289, +1356,1290,1357, +1291,1357,1290, +1357,1291,1358, +1292,1358,1291, +1358,1292,1359, +1293,1359,1292, +1359,1293,1360, +1294,1360,1293, +1360,1294,1361, +1295,1361,1294, +1361,1295,1362, +1296,1362,1295, +1362,1296,1363, +1297,1363,1296, +1363,1297,1364, +1298,1364,1297, +1364,1298,1365, +1299,1365,1298, +1365,1299,1366, +1300,1366,1299, +1366,1300,1367, +1301,1367,1300, +1367,1301,1368, +1302,1368,1301, +1368,1302,1369, +1303,1369,1302, +1369,1303,1370, +1304,1370,1303, +1370,1304,1371, +1305,1371,1304, +1371,1305,1372, +1306,1372,1305, +1372,1306,1373, +1307,1373,1306, +1373,1307,1374, +1308,1374,1307, +1374,1308,1375, +1309,1375,1308, +1375,1309,1376, +1310,1376,1309, +1376,1310,1377, +1311,1377,1310, +1377,1311,1378, +1312,1378,1311, +1378,1312,1379, +1313,1379,1312, +1379,1313,1380, +1314,1380,1313, +1380,1314,1381, +1315,1381,1314, +1381,1315,1382, +1316,1382,1315, +1382,1316,1383, +1317,1383,1316, +1383,1317,1384, +1318,1384,1317, +1384,1318,1385, +1319,1385,1318, +1386,1320,1387, +1321,1387,1320, +1387,1321,1388, +1322,1388,1321, +1388,1322,1389, +1323,1389,1322, +1389,1323,1390, +1324,1390,1323, +1390,1324,1391, +1325,1391,1324, +1391,1325,1392, +1326,1392,1325, +1392,1326,1393, +1327,1393,1326, +1393,1327,1394, +1328,1394,1327, +1394,1328,1395, +1329,1395,1328, +1395,1329,1396, +1330,1396,1329, +1396,1330,1397, +1331,1397,1330, +1397,1331,1398, +1332,1398,1331, +1398,1332,1399, +1333,1399,1332, +1399,1333,1400, +1334,1400,1333, +1400,1334,1401, +1335,1401,1334, +1401,1335,1402, +1336,1402,1335, +1402,1336,1403, +1337,1403,1336, +1403,1337,1404, +1338,1404,1337, +1404,1338,1405, +1339,1405,1338, +1405,1339,1406, +1340,1406,1339, +1406,1340,1407, +1341,1407,1340, +1407,1341,1408, +1342,1408,1341, +1408,1342,1409, +1343,1409,1342, +1409,1343,1410, +1344,1410,1343, +1410,1344,1411, +1345,1411,1344, +1411,1345,1412, +1346,1412,1345, +1412,1346,1413, +1347,1413,1346, +1413,1347,1414, +1348,1414,1347, +1414,1348,1415, +1349,1415,1348, +1415,1349,1416, +1350,1416,1349, +1416,1350,1417, +1351,1417,1350, +1417,1351,1418, +1352,1418,1351, +1418,1352,1419, +1353,1419,1352, +1419,1353,1420, +1354,1420,1353, +1420,1354,1421, +1355,1421,1354, +1421,1355,1422, +1356,1422,1355, +1422,1356,1423, +1357,1423,1356, +1423,1357,1424, +1358,1424,1357, +1424,1358,1425, +1359,1425,1358, +1425,1359,1426, +1360,1426,1359, +1426,1360,1427, +1361,1427,1360, +1427,1361,1428, +1362,1428,1361, +1428,1362,1429, +1363,1429,1362, +1429,1363,1430, +1364,1430,1363, +1430,1364,1431, +1365,1431,1364, +1431,1365,1432, +1366,1432,1365, +1432,1366,1433, +1367,1433,1366, +1433,1367,1434, +1368,1434,1367, +1434,1368,1435, +1369,1435,1368, +1435,1369,1436, +1370,1436,1369, +1436,1370,1437, +1371,1437,1370, +1437,1371,1438, +1372,1438,1371, +1438,1372,1439, +1373,1439,1372, +1439,1373,1440, +1374,1440,1373, +1440,1374,1441, +1375,1441,1374, +1441,1375,1442, +1376,1442,1375, +1442,1376,1443, +1377,1443,1376, +1443,1377,1444, +1378,1444,1377, +1444,1378,1445, +1379,1445,1378, +1445,1379,1446, +1380,1446,1379, +1446,1380,1447, +1381,1447,1380, +1447,1381,1448, +1382,1448,1381, +1448,1382,1449, +1383,1449,1382, +1449,1383,1450, +1384,1450,1383, +1450,1384,1451, +1385,1451,1384, +1452,1386,1453, +1387,1453,1386, +1453,1387,1454, +1388,1454,1387, +1454,1388,1455, +1389,1455,1388, +1455,1389,1456, +1390,1456,1389, +1456,1390,1457, +1391,1457,1390, +1457,1391,1458, +1392,1458,1391, +1458,1392,1459, +1393,1459,1392, +1459,1393,1460, +1394,1460,1393, +1460,1394,1461, +1395,1461,1394, +1461,1395,1462, +1396,1462,1395, +1462,1396,1463, +1397,1463,1396, +1463,1397,1464, +1398,1464,1397, +1464,1398,1465, +1399,1465,1398, +1465,1399,1466, +1400,1466,1399, +1466,1400,1467, +1401,1467,1400, +1467,1401,1468, +1402,1468,1401, +1468,1402,1469, +1403,1469,1402, +1469,1403,1470, +1404,1470,1403, +1470,1404,1471, +1405,1471,1404, +1471,1405,1472, +1406,1472,1405, +1472,1406,1473, +1407,1473,1406, +1473,1407,1474, +1408,1474,1407, +1474,1408,1475, +1409,1475,1408, +1475,1409,1476, +1410,1476,1409, +1476,1410,1477, +1411,1477,1410, +1477,1411,1478, +1412,1478,1411, +1478,1412,1479, +1413,1479,1412, +1479,1413,1480, +1414,1480,1413, +1480,1414,1481, +1415,1481,1414, +1481,1415,1482, +1416,1482,1415, +1482,1416,1483, +1417,1483,1416, +1483,1417,1484, +1418,1484,1417, +1484,1418,1485, +1419,1485,1418, +1485,1419,1486, +1420,1486,1419, +1486,1420,1487, +1421,1487,1420, +1487,1421,1488, +1422,1488,1421, +1488,1422,1489, +1423,1489,1422, +1489,1423,1490, +1424,1490,1423, +1490,1424,1491, +1425,1491,1424, +1491,1425,1492, +1426,1492,1425, +1492,1426,1493, +1427,1493,1426, +1493,1427,1494, +1428,1494,1427, +1494,1428,1495, +1429,1495,1428, +1495,1429,1496, +1430,1496,1429, +1496,1430,1497, +1431,1497,1430, +1497,1431,1498, +1432,1498,1431, +1498,1432,1499, +1433,1499,1432, +1499,1433,1500, +1434,1500,1433, +1500,1434,1501, +1435,1501,1434, +1501,1435,1502, +1436,1502,1435, +1502,1436,1503, +1437,1503,1436, +1503,1437,1504, +1438,1504,1437, +1504,1438,1505, +1439,1505,1438, +1505,1439,1506, +1440,1506,1439, +1506,1440,1507, +1441,1507,1440, +1507,1441,1508, +1442,1508,1441, +1508,1442,1509, +1443,1509,1442, +1509,1443,1510, +1444,1510,1443, +1510,1444,1511, +1445,1511,1444, +1511,1445,1512, +1446,1512,1445, +1512,1446,1513, +1447,1513,1446, +1513,1447,1514, +1448,1514,1447, +1514,1448,1515, +1449,1515,1448, +1515,1449,1516, +1450,1516,1449, +1516,1450,1517, +1451,1517,1450, +1518,1452,1519, +1453,1519,1452, +1519,1453,1520, +1454,1520,1453, +1520,1454,1521, +1455,1521,1454, +1521,1455,1522, +1456,1522,1455, +1522,1456,1523, +1457,1523,1456, +1523,1457,1524, +1458,1524,1457, +1524,1458,1525, +1459,1525,1458, +1525,1459,1526, +1460,1526,1459, +1526,1460,1527, +1461,1527,1460, +1527,1461,1528, +1462,1528,1461, +1528,1462,1529, +1463,1529,1462, +1529,1463,1530, +1464,1530,1463, +1530,1464,1531, +1465,1531,1464, +1531,1465,1532, +1466,1532,1465, +1532,1466,1533, +1467,1533,1466, +1533,1467,1534, +1468,1534,1467, +1534,1468,1535, +1469,1535,1468, +1535,1469,1536, +1470,1536,1469, +1536,1470,1537, +1471,1537,1470, +1537,1471,1538, +1472,1538,1471, +1538,1472,1539, +1473,1539,1472, +1539,1473,1540, +1474,1540,1473, +1540,1474,1541, +1475,1541,1474, +1541,1475,1542, +1476,1542,1475, +1542,1476,1543, +1477,1543,1476, +1543,1477,1544, +1478,1544,1477, +1544,1478,1545, +1479,1545,1478, +1545,1479,1546, +1480,1546,1479, +1546,1480,1547, +1481,1547,1480, +1547,1481,1548, +1482,1548,1481, +1548,1482,1549, +1483,1549,1482, +1549,1483,1550, +1484,1550,1483, +1550,1484,1551, +1485,1551,1484, +1551,1485,1552, +1486,1552,1485, +1552,1486,1553, +1487,1553,1486, +1553,1487,1554, +1488,1554,1487, +1554,1488,1555, +1489,1555,1488, +1555,1489,1556, +1490,1556,1489, +1556,1490,1557, +1491,1557,1490, +1557,1491,1558, +1492,1558,1491, +1558,1492,1559, +1493,1559,1492, +1559,1493,1560, +1494,1560,1493, +1560,1494,1561, +1495,1561,1494, +1561,1495,1562, +1496,1562,1495, +1562,1496,1563, +1497,1563,1496, +1563,1497,1564, +1498,1564,1497, +1564,1498,1565, +1499,1565,1498, +1565,1499,1566, +1500,1566,1499, +1566,1500,1567, +1501,1567,1500, +1567,1501,1568, +1502,1568,1501, +1568,1502,1569, +1503,1569,1502, +1569,1503,1570, +1504,1570,1503, +1570,1504,1571, +1505,1571,1504, +1571,1505,1572, +1506,1572,1505, +1572,1506,1573, +1507,1573,1506, +1573,1507,1574, +1508,1574,1507, +1574,1508,1575, +1509,1575,1508, +1575,1509,1576, +1510,1576,1509, +1576,1510,1577, +1511,1577,1510, +1577,1511,1578, +1512,1578,1511, +1578,1512,1579, +1513,1579,1512, +1579,1513,1580, +1514,1580,1513, +1580,1514,1581, +1515,1581,1514, +1581,1515,1582, +1516,1582,1515, +1582,1516,1583, +1517,1583,1516, +1584,1518,1585, +1519,1585,1518, +1585,1519,1586, +1520,1586,1519, +1586,1520,1587, +1521,1587,1520, +1587,1521,1588, +1522,1588,1521, +1588,1522,1589, +1523,1589,1522, +1589,1523,1590, +1524,1590,1523, +1590,1524,1591, +1525,1591,1524, +1591,1525,1592, +1526,1592,1525, +1592,1526,1593, +1527,1593,1526, +1593,1527,1594, +1528,1594,1527, +1594,1528,1595, +1529,1595,1528, +1595,1529,1596, +1530,1596,1529, +1596,1530,1597, +1531,1597,1530, +1597,1531,1598, +1532,1598,1531, +1598,1532,1599, +1533,1599,1532, +1599,1533,1600, +1534,1600,1533, +1600,1534,1601, +1535,1601,1534, +1601,1535,1602, +1536,1602,1535, +1602,1536,1603, +1537,1603,1536, +1603,1537,1604, +1538,1604,1537, +1604,1538,1605, +1539,1605,1538, +1605,1539,1606, +1540,1606,1539, +1606,1540,1607, +1541,1607,1540, +1607,1541,1608, +1542,1608,1541, +1608,1542,1609, +1543,1609,1542, +1609,1543,1610, +1544,1610,1543, +1610,1544,1611, +1545,1611,1544, +1611,1545,1612, +1546,1612,1545, +1612,1546,1613, +1547,1613,1546, +1613,1547,1614, +1548,1614,1547, +1614,1548,1615, +1549,1615,1548, +1615,1549,1616, +1550,1616,1549, +1616,1550,1617, +1551,1617,1550, +1617,1551,1618, +1552,1618,1551, +1618,1552,1619, +1553,1619,1552, +1619,1553,1620, +1554,1620,1553, +1620,1554,1621, +1555,1621,1554, +1621,1555,1622, +1556,1622,1555, +1622,1556,1623, +1557,1623,1556, +1623,1557,1624, +1558,1624,1557, +1624,1558,1625, +1559,1625,1558, +1625,1559,1626, +1560,1626,1559, +1626,1560,1627, +1561,1627,1560, +1627,1561,1628, +1562,1628,1561, +1628,1562,1629, +1563,1629,1562, +1629,1563,1630, +1564,1630,1563, +1630,1564,1631, +1565,1631,1564, +1631,1565,1632, +1566,1632,1565, +1632,1566,1633, +1567,1633,1566, +1633,1567,1634, +1568,1634,1567, +1634,1568,1635, +1569,1635,1568, +1635,1569,1636, +1570,1636,1569, +1636,1570,1637, +1571,1637,1570, +1637,1571,1638, +1572,1638,1571, +1638,1572,1639, +1573,1639,1572, +1639,1573,1640, +1574,1640,1573, +1640,1574,1641, +1575,1641,1574, +1641,1575,1642, +1576,1642,1575, +1642,1576,1643, +1577,1643,1576, +1643,1577,1644, +1578,1644,1577, +1644,1578,1645, +1579,1645,1578, +1645,1579,1646, +1580,1646,1579, +1646,1580,1647, +1581,1647,1580, +1647,1581,1648, +1582,1648,1581, +1648,1582,1649, +1583,1649,1582, +1650,1584,1651, +1585,1651,1584, +1651,1585,1652, +1586,1652,1585, +1652,1586,1653, +1587,1653,1586, +1653,1587,1654, +1588,1654,1587, +1654,1588,1655, +1589,1655,1588, +1655,1589,1656, +1590,1656,1589, +1656,1590,1657, +1591,1657,1590, +1657,1591,1658, +1592,1658,1591, +1658,1592,1659, +1593,1659,1592, +1659,1593,1660, +1594,1660,1593, +1660,1594,1661, +1595,1661,1594, +1661,1595,1662, +1596,1662,1595, +1662,1596,1663, +1597,1663,1596, +1663,1597,1664, +1598,1664,1597, +1664,1598,1665, +1599,1665,1598, +1665,1599,1666, +1600,1666,1599, +1666,1600,1667, +1601,1667,1600, +1667,1601,1668, +1602,1668,1601, +1668,1602,1669, +1603,1669,1602, +1669,1603,1670, +1604,1670,1603, +1670,1604,1671, +1605,1671,1604, +1671,1605,1672, +1606,1672,1605, +1672,1606,1673, +1607,1673,1606, +1673,1607,1674, +1608,1674,1607, +1674,1608,1675, +1609,1675,1608, +1675,1609,1676, +1610,1676,1609, +1676,1610,1677, +1611,1677,1610, +1677,1611,1678, +1612,1678,1611, +1678,1612,1679, +1613,1679,1612, +1679,1613,1680, +1614,1680,1613, +1680,1614,1681, +1615,1681,1614, +1681,1615,1682, +1616,1682,1615, +1682,1616,1683, +1617,1683,1616, +1683,1617,1684, +1618,1684,1617, +1684,1618,1685, +1619,1685,1618, +1685,1619,1686, +1620,1686,1619, +1686,1620,1687, +1621,1687,1620, +1687,1621,1688, +1622,1688,1621, +1688,1622,1689, +1623,1689,1622, +1689,1623,1690, +1624,1690,1623, +1690,1624,1691, +1625,1691,1624, +1691,1625,1692, +1626,1692,1625, +1692,1626,1693, +1627,1693,1626, +1693,1627,1694, +1628,1694,1627, +1694,1628,1695, +1629,1695,1628, +1695,1629,1696, +1630,1696,1629, +1696,1630,1697, +1631,1697,1630, +1697,1631,1698, +1632,1698,1631, +1698,1632,1699, +1633,1699,1632, +1699,1633,1700, +1634,1700,1633, +1700,1634,1701, +1635,1701,1634, +1701,1635,1702, +1636,1702,1635, +1702,1636,1703, +1637,1703,1636, +1703,1637,1704, +1638,1704,1637, +1704,1638,1705, +1639,1705,1638, +1705,1639,1706, +1640,1706,1639, +1706,1640,1707, +1641,1707,1640, +1707,1641,1708, +1642,1708,1641, +1708,1642,1709, +1643,1709,1642, +1709,1643,1710, +1644,1710,1643, +1710,1644,1711, +1645,1711,1644, +1711,1645,1712, +1646,1712,1645, +1712,1646,1713, +1647,1713,1646, +1713,1647,1714, +1648,1714,1647, +1714,1648,1715, +1649,1715,1648, +1716,1650,1717, +1651,1717,1650, +1717,1651,1718, +1652,1718,1651, +1718,1652,1719, +1653,1719,1652, +1719,1653,1720, +1654,1720,1653, +1720,1654,1721, +1655,1721,1654, +1721,1655,1722, +1656,1722,1655, +1722,1656,1723, +1657,1723,1656, +1723,1657,1724, +1658,1724,1657, +1724,1658,1725, +1659,1725,1658, +1725,1659,1726, +1660,1726,1659, +1726,1660,1727, +1661,1727,1660, +1727,1661,1728, +1662,1728,1661, +1728,1662,1729, +1663,1729,1662, +1729,1663,1730, +1664,1730,1663, +1730,1664,1731, +1665,1731,1664, +1731,1665,1732, +1666,1732,1665, +1732,1666,1733, +1667,1733,1666, +1733,1667,1734, +1668,1734,1667, +1734,1668,1735, +1669,1735,1668, +1735,1669,1736, +1670,1736,1669, +1736,1670,1737, +1671,1737,1670, +1737,1671,1738, +1672,1738,1671, +1738,1672,1739, +1673,1739,1672, +1739,1673,1740, +1674,1740,1673, +1740,1674,1741, +1675,1741,1674, +1741,1675,1742, +1676,1742,1675, +1742,1676,1743, +1677,1743,1676, +1743,1677,1744, +1678,1744,1677, +1744,1678,1745, +1679,1745,1678, +1745,1679,1746, +1680,1746,1679, +1746,1680,1747, +1681,1747,1680, +1747,1681,1748, +1682,1748,1681, +1748,1682,1749, +1683,1749,1682, +1749,1683,1750, +1684,1750,1683, +1750,1684,1751, +1685,1751,1684, +1751,1685,1752, +1686,1752,1685, +1752,1686,1753, +1687,1753,1686, +1753,1687,1754, +1688,1754,1687, +1754,1688,1755, +1689,1755,1688, +1755,1689,1756, +1690,1756,1689, +1756,1690,1757, +1691,1757,1690, +1757,1691,1758, +1692,1758,1691, +1758,1692,1759, +1693,1759,1692, +1759,1693,1760, +1694,1760,1693, +1760,1694,1761, +1695,1761,1694, +1761,1695,1762, +1696,1762,1695, +1762,1696,1763, +1697,1763,1696, +1763,1697,1764, +1698,1764,1697, +1764,1698,1765, +1699,1765,1698, +1765,1699,1766, +1700,1766,1699, +1766,1700,1767, +1701,1767,1700, +1767,1701,1768, +1702,1768,1701, +1768,1702,1769, +1703,1769,1702, +1769,1703,1770, +1704,1770,1703, +1770,1704,1771, +1705,1771,1704, +1771,1705,1772, +1706,1772,1705, +1772,1706,1773, +1707,1773,1706, +1773,1707,1774, +1708,1774,1707, +1774,1708,1775, +1709,1775,1708, +1775,1709,1776, +1710,1776,1709, +1776,1710,1777, +1711,1777,1710, +1777,1711,1778, +1712,1778,1711, +1778,1712,1779, +1713,1779,1712, +1779,1713,1780, +1714,1780,1713, +1780,1714,1781, +1715,1781,1714, +1782,1716,1783, +1717,1783,1716, +1783,1717,1784, +1718,1784,1717, +1784,1718,1785, +1719,1785,1718, +1785,1719,1786, +1720,1786,1719, +1786,1720,1787, +1721,1787,1720, +1787,1721,1788, +1722,1788,1721, +1788,1722,1789, +1723,1789,1722, +1789,1723,1790, +1724,1790,1723, +1790,1724,1791, +1725,1791,1724, +1791,1725,1792, +1726,1792,1725, +1792,1726,1793, +1727,1793,1726, +1793,1727,1794, +1728,1794,1727, +1794,1728,1795, +1729,1795,1728, +1795,1729,1796, +1730,1796,1729, +1796,1730,1797, +1731,1797,1730, +1797,1731,1798, +1732,1798,1731, +1798,1732,1799, +1733,1799,1732, +1799,1733,1800, +1734,1800,1733, +1800,1734,1801, +1735,1801,1734, +1801,1735,1802, +1736,1802,1735, +1802,1736,1803, +1737,1803,1736, +1803,1737,1804, +1738,1804,1737, +1804,1738,1805, +1739,1805,1738, +1805,1739,1806, +1740,1806,1739, +1806,1740,1807, +1741,1807,1740, +1807,1741,1808, +1742,1808,1741, +1808,1742,1809, +1743,1809,1742, +1809,1743,1810, +1744,1810,1743, +1810,1744,1811, +1745,1811,1744, +1811,1745,1812, +1746,1812,1745, +1812,1746,1813, +1747,1813,1746, +1813,1747,1814, +1748,1814,1747, +1814,1748,1815, +1749,1815,1748, +1815,1749,1816, +1750,1816,1749, +1816,1750,1817, +1751,1817,1750, +1817,1751,1818, +1752,1818,1751, +1818,1752,1819, +1753,1819,1752, +1819,1753,1820, +1754,1820,1753, +1820,1754,1821, +1755,1821,1754, +1821,1755,1822, +1756,1822,1755, +1822,1756,1823, +1757,1823,1756, +1823,1757,1824, +1758,1824,1757, +1824,1758,1825, +1759,1825,1758, +1825,1759,1826, +1760,1826,1759, +1826,1760,1827, +1761,1827,1760, +1827,1761,1828, +1762,1828,1761, +1828,1762,1829, +1763,1829,1762, +1829,1763,1830, +1764,1830,1763, +1830,1764,1831, +1765,1831,1764, +1831,1765,1832, +1766,1832,1765, +1832,1766,1833, +1767,1833,1766, +1833,1767,1834, +1768,1834,1767, +1834,1768,1835, +1769,1835,1768, +1835,1769,1836, +1770,1836,1769, +1836,1770,1837, +1771,1837,1770, +1837,1771,1838, +1772,1838,1771, +1838,1772,1839, +1773,1839,1772, +1839,1773,1840, +1774,1840,1773, +1840,1774,1841, +1775,1841,1774, +1841,1775,1842, +1776,1842,1775, +1842,1776,1843, +1777,1843,1776, +1843,1777,1844, +1778,1844,1777, +1844,1778,1845, +1779,1845,1778, +1845,1779,1846, +1780,1846,1779, +1846,1780,1847, +1781,1847,1780, +1848,1782,1849, +1783,1849,1782, +1849,1783,1850, +1784,1850,1783, +1850,1784,1851, +1785,1851,1784, +1851,1785,1852, +1786,1852,1785, +1852,1786,1853, +1787,1853,1786, +1853,1787,1854, +1788,1854,1787, +1854,1788,1855, +1789,1855,1788, +1855,1789,1856, +1790,1856,1789, +1856,1790,1857, +1791,1857,1790, +1857,1791,1858, +1792,1858,1791, +1858,1792,1859, +1793,1859,1792, +1859,1793,1860, +1794,1860,1793, +1860,1794,1861, +1795,1861,1794, +1861,1795,1862, +1796,1862,1795, +1862,1796,1863, +1797,1863,1796, +1863,1797,1864, +1798,1864,1797, +1864,1798,1865, +1799,1865,1798, +1865,1799,1866, +1800,1866,1799, +1866,1800,1867, +1801,1867,1800, +1867,1801,1868, +1802,1868,1801, +1868,1802,1869, +1803,1869,1802, +1869,1803,1870, +1804,1870,1803, +1870,1804,1871, +1805,1871,1804, +1871,1805,1872, +1806,1872,1805, +1872,1806,1873, +1807,1873,1806, +1873,1807,1874, +1808,1874,1807, +1874,1808,1875, +1809,1875,1808, +1875,1809,1876, +1810,1876,1809, +1876,1810,1877, +1811,1877,1810, +1877,1811,1878, +1812,1878,1811, +1878,1812,1879, +1813,1879,1812, +1879,1813,1880, +1814,1880,1813, +1880,1814,1881, +1815,1881,1814, +1881,1815,1882, +1816,1882,1815, +1882,1816,1883, +1817,1883,1816, +1883,1817,1884, +1818,1884,1817, +1884,1818,1885, +1819,1885,1818, +1885,1819,1886, +1820,1886,1819, +1886,1820,1887, +1821,1887,1820, +1887,1821,1888, +1822,1888,1821, +1888,1822,1889, +1823,1889,1822, +1889,1823,1890, +1824,1890,1823, +1890,1824,1891, +1825,1891,1824, +1891,1825,1892, +1826,1892,1825, +1892,1826,1893, +1827,1893,1826, +1893,1827,1894, +1828,1894,1827, +1894,1828,1895, +1829,1895,1828, +1895,1829,1896, +1830,1896,1829, +1896,1830,1897, +1831,1897,1830, +1897,1831,1898, +1832,1898,1831, +1898,1832,1899, +1833,1899,1832, +1899,1833,1900, +1834,1900,1833, +1900,1834,1901, +1835,1901,1834, +1901,1835,1902, +1836,1902,1835, +1902,1836,1903, +1837,1903,1836, +1903,1837,1904, +1838,1904,1837, +1904,1838,1905, +1839,1905,1838, +1905,1839,1906, +1840,1906,1839, +1906,1840,1907, +1841,1907,1840, +1907,1841,1908, +1842,1908,1841, +1908,1842,1909, +1843,1909,1842, +1909,1843,1910, +1844,1910,1843, +1910,1844,1911, +1845,1911,1844, +1911,1845,1912, +1846,1912,1845, +1912,1846,1913, +1847,1913,1846, +1914,1848,1915, +1849,1915,1848, +1915,1849,1916, +1850,1916,1849, +1916,1850,1917, +1851,1917,1850, +1917,1851,1918, +1852,1918,1851, +1918,1852,1919, +1853,1919,1852, +1919,1853,1920, +1854,1920,1853, +1920,1854,1921, +1855,1921,1854, +1921,1855,1922, +1856,1922,1855, +1922,1856,1923, +1857,1923,1856, +1923,1857,1924, +1858,1924,1857, +1924,1858,1925, +1859,1925,1858, +1925,1859,1926, +1860,1926,1859, +1926,1860,1927, +1861,1927,1860, +1927,1861,1928, +1862,1928,1861, +1928,1862,1929, +1863,1929,1862, +1929,1863,1930, +1864,1930,1863, +1930,1864,1931, +1865,1931,1864, +1931,1865,1932, +1866,1932,1865, +1932,1866,1933, +1867,1933,1866, +1933,1867,1934, +1868,1934,1867, +1934,1868,1935, +1869,1935,1868, +1935,1869,1936, +1870,1936,1869, +1936,1870,1937, +1871,1937,1870, +1937,1871,1938, +1872,1938,1871, +1938,1872,1939, +1873,1939,1872, +1939,1873,1940, +1874,1940,1873, +1940,1874,1941, +1875,1941,1874, +1941,1875,1942, +1876,1942,1875, +1942,1876,1943, +1877,1943,1876, +1943,1877,1944, +1878,1944,1877, +1944,1878,1945, +1879,1945,1878, +1945,1879,1946, +1880,1946,1879, +1946,1880,1947, +1881,1947,1880, +1947,1881,1948, +1882,1948,1881, +1948,1882,1949, +1883,1949,1882, +1949,1883,1950, +1884,1950,1883, +1950,1884,1951, +1885,1951,1884, +1951,1885,1952, +1886,1952,1885, +1952,1886,1953, +1887,1953,1886, +1953,1887,1954, +1888,1954,1887, +1954,1888,1955, +1889,1955,1888, +1955,1889,1956, +1890,1956,1889, +1956,1890,1957, +1891,1957,1890, +1957,1891,1958, +1892,1958,1891, +1958,1892,1959, +1893,1959,1892, +1959,1893,1960, +1894,1960,1893, +1960,1894,1961, +1895,1961,1894, +1961,1895,1962, +1896,1962,1895, +1962,1896,1963, +1897,1963,1896, +1963,1897,1964, +1898,1964,1897, +1964,1898,1965, +1899,1965,1898, +1965,1899,1966, +1900,1966,1899, +1966,1900,1967, +1901,1967,1900, +1967,1901,1968, +1902,1968,1901, +1968,1902,1969, +1903,1969,1902, +1969,1903,1970, +1904,1970,1903, +1970,1904,1971, +1905,1971,1904, +1971,1905,1972, +1906,1972,1905, +1972,1906,1973, +1907,1973,1906, +1973,1907,1974, +1908,1974,1907, +1974,1908,1975, +1909,1975,1908, +1975,1909,1976, +1910,1976,1909, +1976,1910,1977, +1911,1977,1910, +1977,1911,1978, +1912,1978,1911, +1978,1912,1979, +1913,1979,1912, +1980,1914,1981, +1915,1981,1914, +1981,1915,1982, +1916,1982,1915, +1982,1916,1983, +1917,1983,1916, +1983,1917,1984, +1918,1984,1917, +1984,1918,1985, +1919,1985,1918, +1985,1919,1986, +1920,1986,1919, +1986,1920,1987, +1921,1987,1920, +1987,1921,1988, +1922,1988,1921, +1988,1922,1989, +1923,1989,1922, +1989,1923,1990, +1924,1990,1923, +1990,1924,1991, +1925,1991,1924, +1991,1925,1992, +1926,1992,1925, +1992,1926,1993, +1927,1993,1926, +1993,1927,1994, +1928,1994,1927, +1994,1928,1995, +1929,1995,1928, +1995,1929,1996, +1930,1996,1929, +1996,1930,1997, +1931,1997,1930, +1997,1931,1998, +1932,1998,1931, +1998,1932,1999, +1933,1999,1932, +1999,1933,2000, +1934,2000,1933, +2000,1934,2001, +1935,2001,1934, +2001,1935,2002, +1936,2002,1935, +2002,1936,2003, +1937,2003,1936, +2003,1937,2004, +1938,2004,1937, +2004,1938,2005, +1939,2005,1938, +2005,1939,2006, +1940,2006,1939, +2006,1940,2007, +1941,2007,1940, +2007,1941,2008, +1942,2008,1941, +2008,1942,2009, +1943,2009,1942, +2009,1943,2010, +1944,2010,1943, +2010,1944,2011, +1945,2011,1944, +2011,1945,2012, +1946,2012,1945, +2012,1946,2013, +1947,2013,1946, +2013,1947,2014, +1948,2014,1947, +2014,1948,2015, +1949,2015,1948, +2015,1949,2016, +1950,2016,1949, +2016,1950,2017, +1951,2017,1950, +2017,1951,2018, +1952,2018,1951, +2018,1952,2019, +1953,2019,1952, +2019,1953,2020, +1954,2020,1953, +2020,1954,2021, +1955,2021,1954, +2021,1955,2022, +1956,2022,1955, +2022,1956,2023, +1957,2023,1956, +2023,1957,2024, +1958,2024,1957, +2024,1958,2025, +1959,2025,1958, +2025,1959,2026, +1960,2026,1959, +2026,1960,2027, +1961,2027,1960, +2027,1961,2028, +1962,2028,1961, +2028,1962,2029, +1963,2029,1962, +2029,1963,2030, +1964,2030,1963, +2030,1964,2031, +1965,2031,1964, +2031,1965,2032, +1966,2032,1965, +2032,1966,2033, +1967,2033,1966, +2033,1967,2034, +1968,2034,1967, +2034,1968,2035, +1969,2035,1968, +2035,1969,2036, +1970,2036,1969, +2036,1970,2037, +1971,2037,1970, +2037,1971,2038, +1972,2038,1971, +2038,1972,2039, +1973,2039,1972, +2039,1973,2040, +1974,2040,1973, +2040,1974,2041, +1975,2041,1974, +2041,1975,2042, +1976,2042,1975, +2042,1976,2043, +1977,2043,1976, +2043,1977,2044, +1978,2044,1977, +2044,1978,2045, +1979,2045,1978, +2046,1980,2047, +1981,2047,1980, +2047,1981,2048, +1982,2048,1981, +2048,1982,2049, +1983,2049,1982, +2049,1983,2050, +1984,2050,1983, +2050,1984,2051, +1985,2051,1984, +2051,1985,2052, +1986,2052,1985, +2052,1986,2053, +1987,2053,1986, +2053,1987,2054, +1988,2054,1987, +2054,1988,2055, +1989,2055,1988, +2055,1989,2056, +1990,2056,1989, +2056,1990,2057, +1991,2057,1990, +2057,1991,2058, +1992,2058,1991, +2058,1992,2059, +1993,2059,1992, +2059,1993,2060, +1994,2060,1993, +2060,1994,2061, +1995,2061,1994, +2061,1995,2062, +1996,2062,1995, +2062,1996,2063, +1997,2063,1996, +2063,1997,2064, +1998,2064,1997, +2064,1998,2065, +1999,2065,1998, +2065,1999,2066, +2000,2066,1999, +2066,2000,2067, +2001,2067,2000, +2067,2001,2068, +2002,2068,2001, +2068,2002,2069, +2003,2069,2002, +2069,2003,2070, +2004,2070,2003, +2070,2004,2071, +2005,2071,2004, +2071,2005,2072, +2006,2072,2005, +2072,2006,2073, +2007,2073,2006, +2073,2007,2074, +2008,2074,2007, +2074,2008,2075, +2009,2075,2008, +2075,2009,2076, +2010,2076,2009, +2076,2010,2077, +2011,2077,2010, +2077,2011,2078, +2012,2078,2011, +2078,2012,2079, +2013,2079,2012, +2079,2013,2080, +2014,2080,2013, +2080,2014,2081, +2015,2081,2014, +2081,2015,2082, +2016,2082,2015, +2082,2016,2083, +2017,2083,2016, +2083,2017,2084, +2018,2084,2017, +2084,2018,2085, +2019,2085,2018, +2085,2019,2086, +2020,2086,2019, +2086,2020,2087, +2021,2087,2020, +2087,2021,2088, +2022,2088,2021, +2088,2022,2089, +2023,2089,2022, +2089,2023,2090, +2024,2090,2023, +2090,2024,2091, +2025,2091,2024, +2091,2025,2092, +2026,2092,2025, +2092,2026,2093, +2027,2093,2026, +2093,2027,2094, +2028,2094,2027, +2094,2028,2095, +2029,2095,2028, +2095,2029,2096, +2030,2096,2029, +2096,2030,2097, +2031,2097,2030, +2097,2031,2098, +2032,2098,2031, +2098,2032,2099, +2033,2099,2032, +2099,2033,2100, +2034,2100,2033, +2100,2034,2101, +2035,2101,2034, +2101,2035,2102, +2036,2102,2035, +2102,2036,2103, +2037,2103,2036, +2103,2037,2104, +2038,2104,2037, +2104,2038,2105, +2039,2105,2038, +2105,2039,2106, +2040,2106,2039, +2106,2040,2107, +2041,2107,2040, +2107,2041,2108, +2042,2108,2041, +2108,2042,2109, +2043,2109,2042, +2109,2043,2110, +2044,2110,2043, +2110,2044,2111, +2045,2111,2044, +2112,2046,2113, +2047,2113,2046, +2113,2047,2114, +2048,2114,2047, +2114,2048,2115, +2049,2115,2048, +2115,2049,2116, +2050,2116,2049, +2116,2050,2117, +2051,2117,2050, +2117,2051,2118, +2052,2118,2051, +2118,2052,2119, +2053,2119,2052, +2119,2053,2120, +2054,2120,2053, +2120,2054,2121, +2055,2121,2054, +2121,2055,2122, +2056,2122,2055, +2122,2056,2123, +2057,2123,2056, +2123,2057,2124, +2058,2124,2057, +2124,2058,2125, +2059,2125,2058, +2125,2059,2126, +2060,2126,2059, +2126,2060,2127, +2061,2127,2060, +2127,2061,2128, +2062,2128,2061, +2128,2062,2129, +2063,2129,2062, +2129,2063,2130, +2064,2130,2063, +2130,2064,2131, +2065,2131,2064, +2131,2065,2132, +2066,2132,2065, +2132,2066,2133, +2067,2133,2066, +2133,2067,2134, +2068,2134,2067, +2134,2068,2135, +2069,2135,2068, +2135,2069,2136, +2070,2136,2069, +2136,2070,2137, +2071,2137,2070, +2137,2071,2138, +2072,2138,2071, +2138,2072,2139, +2073,2139,2072, +2139,2073,2140, +2074,2140,2073, +2140,2074,2141, +2075,2141,2074, +2141,2075,2142, +2076,2142,2075, +2142,2076,2143, +2077,2143,2076, +2143,2077,2144, +2078,2144,2077, +2144,2078,2145, +2079,2145,2078, +2145,2079,2146, +2080,2146,2079, +2146,2080,2147, +2081,2147,2080, +2147,2081,2148, +2082,2148,2081, +2148,2082,2149, +2083,2149,2082, +2149,2083,2150, +2084,2150,2083, +2150,2084,2151, +2085,2151,2084, +2151,2085,2152, +2086,2152,2085, +2152,2086,2153, +2087,2153,2086, +2153,2087,2154, +2088,2154,2087, +2154,2088,2155, +2089,2155,2088, +2155,2089,2156, +2090,2156,2089, +2156,2090,2157, +2091,2157,2090, +2157,2091,2158, +2092,2158,2091, +2158,2092,2159, +2093,2159,2092, +2159,2093,2160, +2094,2160,2093, +2160,2094,2161, +2095,2161,2094, +2161,2095,2162, +2096,2162,2095, +2162,2096,2163, +2097,2163,2096, +2163,2097,2164, +2098,2164,2097, +2164,2098,2165, +2099,2165,2098, +2165,2099,2166, +2100,2166,2099, +2166,2100,2167, +2101,2167,2100, +2167,2101,2168, +2102,2168,2101, +2168,2102,2169, +2103,2169,2102, +2169,2103,2170, +2104,2170,2103, +2170,2104,2171, +2105,2171,2104, +2171,2105,2172, +2106,2172,2105, +2172,2106,2173, +2107,2173,2106, +2173,2107,2174, +2108,2174,2107, +2174,2108,2175, +2109,2175,2108, +2175,2109,2176, +2110,2176,2109, +2176,2110,2177, +2111,2177,2110, +}; + +#define Landscape01VtxCount 2048 +#define Landscape01IdxCount 11718 + +btScalar Landscape01Vtx[] = { +3.90626f,0.452911f,246.094f, +3.90626f,1.52302f,250.0f, +7.8125f,1.18238f,246.094f, +7.81251f,1.7549f,250.0f, +11.7188f,2.12911f,246.094f, +11.7188f,2.62454f,250.0f, +15.625f,3.01456f,246.094f, +15.625f,3.22814f,250.0f, +19.5313f,3.97431f,246.094f, +19.5313f,3.63231f,250.0f, +23.4375f,4.08741f,246.094f, +23.4375f,4.24097f,250.0f, +27.3438f,5.8163f,246.094f, +27.3438f,5.93409f,250.0f, +31.25f,6.86809f,246.094f, +31.25f,7.34105f,250.0f, +35.1563f,8.25405f,246.094f, +35.1563f,8.62507f,250.0f, +39.0625f,8.38601f,246.094f, +39.0625f,8.68483f,250.0f, +42.9688f,6.94797f,246.094f, +42.9688f,7.71847f,250.0f, +46.875f,4.60698f,246.094f, +46.875f,6.12159f,250.0f, +50.7813f,3.6429f,246.094f, +50.7813f,5.13002f,250.0f, +54.6875f,4.01945f,246.094f, +54.6875f,5.50476f,250.0f, +58.5938f,4.05996f,246.094f, +58.5938f,5.31917f,250.0f, +62.5f,3.98995f,246.094f, +62.5f,5.51823f,250.0f, +66.4063f,5.44402f,246.094f, +66.4063f,6.80029f,250.0f, +70.3125f,6.03873f,246.094f, +70.3125f,7.41783f,250.0f, +74.2188f,6.37187f,246.094f, +74.2188f,8.16051f,250.0f, +78.125f,6.74414f,246.094f, +78.125f,8.72099f,250.0f, +82.0313f,7.37958f,246.094f, +82.0313f,10.1125f,250.0f, +85.9375f,8.97782f,246.094f, +85.9375f,10.4624f,250.0f, +89.8438f,11.0829f,246.094f, +89.8438f,11.6403f,250.0f, +93.75f,12.3286f,246.094f, +93.75f,13.1378f,250.0f, +97.6563f,13.5966f,246.094f, +97.6563f,14.2949f,250.0f, +101.563f,15.5602f,246.094f, +101.563f,16.9487f,250.0f, +105.469f,16.9944f,246.094f, +105.469f,18.1946f,250.0f, +109.375f,17.886f,246.094f, +109.375f,19.5101f,250.0f, +113.281f,18.9289f,246.094f, +113.281f,20.9286f,250.0f, +117.188f,18.9873f,246.094f, +117.188f,20.0636f,250.0f, +121.094f,18.4954f,246.094f, +121.094f,20.5657f,250.0f, +125.0f,20.1484f,246.094f, +125.0f,21.1466f,250.0f, +128.906f,20.5032f,246.094f, +128.906f,22.3026f,250.0f, +132.813f,21.212f,246.094f, +132.813f,22.9139f,250.0f, +136.719f,22.289f,246.094f, +136.719f,24.4671f,250.0f, +140.625f,23.2441f,246.094f, +140.625f,24.3276f,250.0f, +144.531f,22.4971f,246.094f, +144.531f,24.3128f,250.0f, +148.438f,22.6347f,246.094f, +148.438f,23.8291f,250.0f, +152.344f,23.5767f,246.094f, +152.344f,24.1369f,250.0f, +156.25f,25.193f,246.094f, +156.25f,24.9132f,250.0f, +160.156f,25.2521f,246.094f, +160.156f,24.7251f,250.0f, +164.063f,25.7424f,246.094f, +164.063f,24.1169f,250.0f, +167.969f,24.3269f,246.094f, +167.969f,24.6092f,250.0f, +171.875f,25.0479f,246.094f, +171.875f,24.967f,250.0f, +175.781f,25.0107f,246.094f, +175.781f,24.7879f,250.0f, +179.688f,23.583f,246.094f, +179.688f,22.6841f,250.0f, +183.594f,20.958f,246.094f, +183.594f,20.6584f,250.0f, +187.5f,19.7535f,246.094f, +187.5f,20.0313f,250.0f, +191.406f,20.4707f,246.094f, +191.406f,20.3896f,250.0f, +195.313f,19.7551f,246.094f, +195.313f,21.5643f,250.0f, +199.219f,19.698f,246.094f, +199.219f,21.5733f,250.0f, +203.125f,20.0732f,246.094f, +203.125f,20.38f,250.0f, +207.031f,19.8667f,246.094f, +207.031f,19.3779f,250.0f, +210.938f,19.4501f,246.094f, +210.938f,19.5994f,250.0f, +214.844f,19.2918f,246.094f, +214.844f,19.0966f,250.0f, +218.75f,18.7652f,246.094f, +218.75f,19.9256f,250.0f, +222.656f,18.8129f,246.094f, +222.656f,19.8704f,250.0f, +226.563f,18.3547f,246.094f, +226.563f,18.8671f,250.0f, +230.469f,16.9801f,246.094f, +230.469f,17.4931f,250.0f, +234.375f,15.6173f,246.094f, +234.375f,16.1699f,250.0f, +238.281f,15.549f,246.094f, +238.281f,15.3704f,250.0f, +242.188f,15.2468f,246.094f, +242.188f,15.0306f,250.0f, +246.094f,14.1325f,246.094f, +246.094f,14.2622f,250.0f, +250.0f,14.4063f,246.094f, +250.0f,14.3657f,250.0f, +3.90626f,2.21488f,242.188f, +7.81252f,2.28606f,242.188f, +11.7188f,3.88428f,242.188f, +15.625f,3.39117f,242.188f, +19.5313f,3.64824f,242.188f, +23.4375f,4.14072f,242.188f, +27.3438f,5.74104f,242.188f, +31.25f,6.66142f,242.188f, +35.1563f,7.31371f,242.188f, +39.0625f,7.68371f,242.188f, +42.9688f,6.99041f,242.188f, +46.875f,4.89778f,242.188f, +50.7813f,2.64913f,242.188f, +54.6875f,2.76175f,242.188f, +58.5938f,3.10499f,242.188f, +62.5f,4.61915f,242.188f, +66.4063f,5.36769f,242.188f, +70.3125f,5.41759f,242.188f, +74.2188f,5.42279f,242.188f, +78.125f,5.53934f,242.188f, +82.0313f,5.38421f,242.188f, +85.9375f,7.77227f,242.188f, +89.8438f,9.40622f,242.188f, +93.75f,11.2904f,242.188f, +97.6563f,12.0748f,242.188f, +101.563f,14.1058f,242.188f, +105.469f,15.1513f,242.188f, +109.375f,15.9477f,242.188f, +113.281f,16.843f,242.188f, +117.188f,17.2117f,242.188f, +121.094f,18.2641f,242.188f, +125.0f,18.8672f,242.188f, +128.906f,19.3239f,242.188f, +132.813f,20.1067f,242.188f, +136.719f,20.8307f,242.188f, +140.625f,21.3646f,242.188f, +144.531f,21.6047f,242.188f, +148.438f,22.2456f,242.188f, +152.344f,23.5103f,242.188f, +156.25f,24.8533f,242.188f, +160.156f,25.4504f,242.188f, +164.063f,25.9357f,242.188f, +167.969f,24.8535f,242.188f, +171.875f,25.3099f,242.188f, +175.781f,25.3494f,242.188f, +179.688f,24.2229f,242.188f, +183.594f,21.0829f,242.188f, +187.5f,19.574f,242.188f, +191.406f,19.9835f,242.188f, +195.313f,19.6061f,242.188f, +199.219f,18.9509f,242.188f, +203.125f,20.1818f,242.188f, +207.031f,19.2962f,242.188f, +210.938f,18.8908f,242.188f, +214.844f,18.7996f,242.188f, +218.75f,18.7982f,242.188f, +222.656f,18.3283f,242.188f, +226.563f,17.7287f,242.188f, +230.469f,15.6882f,242.188f, +234.375f,15.2468f,242.188f, +238.281f,15.2703f,242.188f, +242.188f,14.4812f,242.188f, +246.094f,14.5597f,242.188f, +250.0f,14.178f,242.188f, +3.90626f,3.04396f,238.281f, +7.81252f,3.88428f,238.281f, +11.7188f,4.51367f,238.281f, +15.625f,4.1993f,238.281f, +19.5313f,4.48585f,238.281f, +23.4375f,5.11452f,238.281f, +27.3438f,4.98441f,238.281f, +31.25f,5.77536f,238.281f, +35.1563f,5.42743f,238.281f, +39.0625f,6.4581f,238.281f, +42.9688f,5.55272f,238.281f, +46.875f,3.69555f,238.281f, +50.7813f,3.08321f,238.281f, +54.6875f,2.96664f,238.281f, +58.5938f,3.94595f,238.281f, +62.5f,4.71605f,238.281f, +66.4063f,5.07906f,238.281f, +70.3125f,5.39291f,238.281f, +74.2188f,4.29289f,238.281f, +78.125f,4.20855f,238.281f, +82.0313f,5.10829f,238.281f, +85.9375f,5.48654f,238.281f, +89.8438f,7.06082f,238.281f, +93.75f,8.6827f,238.281f, +97.6563f,9.99779f,238.281f, +101.563f,11.9757f,238.281f, +105.469f,12.9031f,238.281f, +109.375f,13.7947f,238.281f, +113.281f,13.6154f,238.281f, +117.188f,15.9897f,238.281f, +121.094f,18.0884f,238.281f, +125.0f,18.714f,238.281f, +128.906f,19.1457f,238.281f, +132.813f,20.0791f,238.281f, +136.719f,20.3929f,238.281f, +140.625f,20.8277f,238.281f, +144.531f,21.2111f,238.281f, +148.438f,22.5091f,238.281f, +152.344f,23.9188f,238.281f, +156.25f,25.0278f,238.281f, +160.156f,25.8335f,238.281f, +164.063f,25.6558f,238.281f, +167.969f,24.3663f,238.281f, +171.875f,30.6775f,238.281f, +175.781f,30.89f,238.281f, +179.688f,29.2543f,238.281f, +183.594f,26.6241f,238.281f, +187.5f,24.7124f,238.281f, +191.406f,23.7048f,238.281f, +195.313f,23.3839f,238.281f, +199.219f,23.312f,238.281f, +203.125f,17.5221f,238.281f, +207.031f,17.418f,238.281f, +210.938f,17.5259f,238.281f, +214.844f,18.2392f,238.281f, +218.75f,18.6793f,238.281f, +222.656f,18.3701f,238.281f, +226.563f,17.2487f,238.281f, +230.469f,16.4f,238.281f, +234.375f,15.4998f,238.281f, +238.281f,14.6207f,238.281f, +242.188f,14.3055f,238.281f, +246.094f,14.2255f,238.281f, +250.0f,14.1326f,238.281f, +3.90626f,5.19166f,234.375f, +7.81252f,4.93292f,234.375f, +11.7188f,4.03413f,234.375f, +15.625f,3.70957f,234.375f, +19.5313f,4.44484f,234.375f, +23.4375f,5.12277f,234.375f, +27.3438f,4.60029f,234.375f, +31.25f,4.55048f,234.375f, +35.1563f,4.78512f,234.375f, +39.0625f,4.94627f,234.375f, +42.9688f,5.03351f,234.375f, +46.875f,3.08166f,234.375f, +50.7813f,2.57752f,234.375f, +54.6875f,3.08533f,234.375f, +58.5938f,4.0254f,234.375f, +62.5f,4.57575f,234.375f, +66.4063f,4.67125f,234.375f, +70.3125f,4.5612f,234.375f, +74.2188f,4.232f,234.375f, +78.125f,4.1571f,234.375f, +82.0313f,4.20157f,234.375f, +85.9375f,4.29102f,234.375f, +89.8438f,5.54826f,234.375f, +93.75f,7.06094f,234.375f, +97.6563f,8.27366f,234.375f, +101.563f,9.83852f,234.375f, +105.469f,10.9262f,234.375f, +109.375f,11.7812f,234.375f, +113.281f,13.8453f,234.375f, +117.188f,15.5538f,234.375f, +121.094f,16.8977f,234.375f, +125.0f,18.2996f,234.375f, +128.906f,19.6512f,234.375f, +132.813f,19.411f,234.375f, +136.719f,19.3317f,234.375f, +140.625f,20.656f,234.375f, +144.531f,21.6048f,234.375f, +148.438f,22.2246f,234.375f, +152.344f,23.6649f,234.375f, +156.25f,24.8772f,234.375f, +160.156f,27.6423f,234.375f, +164.063f,29.4442f,234.375f, +167.969f,29.6691f,234.375f, +171.875f,30.0772f,234.375f, +175.781f,30.3189f,234.375f, +179.688f,28.7319f,234.375f, +183.594f,26.6952f,234.375f, +187.5f,25.3375f,234.375f, +191.406f,24.1666f,234.375f, +195.313f,22.5458f,234.375f, +199.219f,22.2182f,234.375f, +203.125f,22.2413f,234.375f, +207.031f,21.8533f,234.375f, +210.938f,17.4596f,234.375f, +214.844f,17.2677f,234.375f, +218.75f,16.9584f,234.375f, +222.656f,16.6188f,234.375f, +226.563f,17.4388f,234.375f, +230.469f,16.936f,234.375f, +234.375f,15.6181f,234.375f, +238.281f,15.8373f,234.375f, +242.188f,15.0881f,234.375f, +246.094f,14.2247f,234.375f, +250.0f,14.111f,234.375f, +3.90626f,5.885f,230.469f, +7.81251f,5.4786f,230.469f, +11.7188f,5.0584f,230.469f, +15.625f,4.10283f,230.469f, +19.5313f,4.10569f,230.469f, +23.4375f,4.42202f,230.469f, +27.3438f,4.27849f,230.469f, +31.25f,4.25612f,230.469f, +35.1563f,3.83542f,230.469f, +39.0625f,3.37515f,230.469f, +42.9688f,4.16288f,230.469f, +46.875f,2.84197f,230.469f, +50.7813f,2.83467f,230.469f, +54.6875f,3.07874f,230.469f, +58.5938f,3.37745f,230.469f, +62.5f,4.09612f,230.469f, +66.4063f,4.65777f,230.469f, +70.3125f,4.45712f,230.469f, +74.2188f,3.89296f,230.469f, +78.125f,3.87471f,230.469f, +82.0313f,4.64568f,230.469f, +85.9375f,5.82987f,230.469f, +89.8438f,6.40084f,230.469f, +93.75f,7.65914f,230.469f, +97.6563f,8.07052f,230.469f, +101.563f,9.86632f,230.469f, +105.469f,11.8636f,230.469f, +109.375f,12.9547f,230.469f, +113.281f,14.2745f,230.469f, +117.188f,15.6876f,230.469f, +121.094f,17.2089f,230.469f, +125.0f,18.1267f,230.469f, +128.906f,19.379f,230.469f, +132.813f,19.2097f,230.469f, +136.719f,18.9335f,230.469f, +140.625f,19.9763f,230.469f, +144.531f,21.5401f,230.469f, +148.438f,21.7302f,230.469f, +152.344f,23.0108f,230.469f, +156.25f,28.7387f,230.469f, +160.156f,28.4179f,230.469f, +164.063f,28.6483f,230.469f, +167.969f,29.5567f,230.469f, +171.875f,29.589f,230.469f, +175.781f,29.7943f,230.469f, +179.688f,28.0587f,230.469f, +183.594f,27.6387f,230.469f, +187.5f,26.92f,230.469f, +191.406f,25.7995f,230.469f, +195.313f,23.8573f,230.469f, +199.219f,22.1543f,230.469f, +203.125f,21.8606f,230.469f, +207.031f,21.7644f,230.469f, +210.938f,22.284f,230.469f, +214.844f,22.465f,230.469f, +218.75f,16.4018f,230.469f, +222.656f,16.1053f,230.469f, +226.563f,16.9553f,230.469f, +230.469f,16.9851f,230.469f, +234.375f,16.0967f,230.469f, +238.281f,15.9758f,230.469f, +242.188f,15.3258f,230.469f, +246.094f,15.2909f,230.469f, +250.0f,14.7208f,230.469f, +3.90626f,6.89682f,226.563f, +7.81251f,6.58742f,226.563f, +11.7188f,6.03516f,226.563f, +15.625f,4.72243f,226.563f, +19.5313f,3.6445f,226.563f, +23.4375f,4.35761f,226.563f, +27.3438f,4.11714f,226.563f, +31.25f,4.31125f,226.563f, +35.1563f,3.42415f,226.563f, +39.0625f,2.29216f,226.563f, +42.9688f,2.47915f,226.563f, +46.875f,2.26767f,226.563f, +50.7813f,1.11914f,226.563f, +54.6875f,2.43266f,226.563f, +58.5938f,3.88718f,226.563f, +62.5f,3.9963f,226.563f, +66.4063f,4.30547f,226.563f, +70.3125f,4.43739f,226.563f, +74.2188f,3.89069f,226.563f, +78.125f,4.12082f,226.563f, +82.0313f,5.53252f,226.563f, +85.9375f,6.38493f,226.563f, +89.8438f,6.79959f,226.563f, +93.75f,8.29598f,226.563f, +97.6563f,8.48723f,226.563f, +101.563f,9.93554f,226.563f, +105.469f,11.5657f,226.563f, +109.375f,13.0486f,226.563f, +113.281f,13.8621f,226.563f, +117.188f,14.9688f,226.563f, +121.094f,16.3799f,226.563f, +125.0f,17.1973f,226.563f, +128.906f,17.376f,226.563f, +132.813f,18.1073f,226.563f, +136.719f,18.6844f,226.563f, +140.625f,18.5161f,226.563f, +144.531f,20.7617f,226.563f, +148.438f,21.0578f,226.563f, +152.344f,26.44f,226.563f, +156.25f,27.1807f,226.563f, +160.156f,27.2962f,226.563f, +164.063f,28.0507f,226.563f, +167.969f,28.6572f,226.563f, +171.875f,28.3487f,226.563f, +175.781f,23.7294f,226.563f, +179.688f,23.1113f,226.563f, +183.594f,22.5708f,226.563f, +187.5f,22.6165f,226.563f, +191.406f,21.8697f,226.563f, +195.313f,19.9841f,226.563f, +199.219f,22.9835f,226.563f, +203.125f,22.0743f,226.563f, +207.031f,22.4886f,226.563f, +210.938f,22.2516f,226.563f, +214.844f,22.3739f,226.563f, +218.75f,22.7815f,226.563f, +222.656f,17.0366f,226.563f, +226.563f,16.1334f,226.563f, +230.469f,16.9265f,226.563f, +234.375f,17.1793f,226.563f, +238.281f,17.3365f,226.563f, +242.188f,16.1971f,226.563f, +246.094f,15.2775f,226.563f, +250.0f,15.1313f,226.563f, +3.90626f,6.81349f,222.656f, +7.81251f,7.23848f,222.656f, +11.7188f,6.09864f,222.656f, +15.625f,4.9545f,222.656f, +19.5313f,3.88133f,222.656f, +23.4375f,4.06964f,222.656f, +27.3438f,3.90589f,222.656f, +31.25f,4.08304f,222.656f, +35.1563f,3.26204f,222.656f, +39.0625f,1.53457f,222.656f, +42.9688f,1.90835f,222.656f, +46.875f,1.98509f,222.656f, +50.7813f,2.14652f,222.656f, +54.6875f,2.7418f,222.656f, +58.5938f,3.74695f,222.656f, +62.5f,4.00354f,222.656f, +66.4063f,4.38792f,222.656f, +70.3125f,3.93121f,222.656f, +74.2188f,3.42647f,222.656f, +78.125f,5.0562f,222.656f, +82.0313f,5.98572f,222.656f, +85.9375f,6.52919f,222.656f, +89.8438f,6.83394f,222.656f, +93.75f,7.48974f,222.656f, +97.6563f,8.19267f,222.656f, +101.563f,9.33438f,222.656f, +105.469f,11.8423f,222.656f, +109.375f,13.1158f,222.656f, +113.281f,13.8944f,222.656f, +117.188f,14.8014f,222.656f, +121.094f,15.4129f,222.656f, +125.0f,15.6942f,222.656f, +128.906f,16.2049f,222.656f, +132.813f,17.0318f,222.656f, +136.719f,18.5423f,222.656f, +140.625f,18.8685f,222.656f, +144.531f,19.4529f,222.656f, +148.438f,25.9153f,222.656f, +152.344f,25.6773f,222.656f, +156.25f,26.0432f,222.656f, +160.156f,26.3016f,222.656f, +164.063f,27.084f,222.656f, +167.969f,27.1073f,222.656f, +171.875f,22.7536f,222.656f, +175.781f,23.3785f,222.656f, +179.688f,23.0862f,222.656f, +183.594f,22.5993f,222.656f, +187.5f,22.0197f,222.656f, +191.406f,21.8352f,222.656f, +195.313f,20.0501f,222.656f, +199.219f,18.5797f,222.656f, +203.125f,18.2905f,222.656f, +207.031f,22.7876f,222.656f, +210.938f,21.9787f,222.656f, +214.844f,21.4782f,222.656f, +218.75f,21.5786f,222.656f, +222.656f,21.6231f,222.656f, +226.563f,17.8058f,222.656f, +230.469f,17.6169f,222.656f, +234.375f,18.3242f,222.656f, +238.281f,18.4847f,222.656f, +242.188f,17.3189f,222.656f, +246.094f,16.7726f,222.656f, +250.0f,16.587f,222.656f, +3.90627f,8.02546f,218.75f, +7.81251f,8.24803f,218.75f, +11.7188f,6.92174f,218.75f, +15.625f,5.86085f,218.75f, +19.5313f,4.56603f,218.75f, +23.4375f,3.6909f,218.75f, +27.3438f,4.26522f,218.75f, +31.25f,3.37783f,218.75f, +35.1563f,1.72339f,218.75f, +39.0625f,2.22205f,218.75f, +42.9688f,2.71848f,218.75f, +46.875f,3.1467f,218.75f, +50.7813f,3.05327f,218.75f, +54.6875f,3.19537f,218.75f, +58.5938f,3.68243f,218.75f, +62.5f,3.35279f,218.75f, +66.4063f,4.00402f,218.75f, +70.3125f,2.9244f,218.75f, +74.2188f,4.39027f,218.75f, +78.125f,5.55878f,218.75f, +82.0313f,6.38772f,218.75f, +85.9375f,6.34964f,218.75f, +89.8438f,6.80441f,218.75f, +93.75f,6.5829f,218.75f, +97.6563f,7.27657f,218.75f, +101.563f,9.67388f,218.75f, +105.469f,10.833f,218.75f, +109.375f,12.1666f,218.75f, +113.281f,13.2095f,218.75f, +117.188f,14.2491f,218.75f, +121.094f,14.6953f,218.75f, +125.0f,14.2707f,218.75f, +128.906f,15.9556f,218.75f, +132.813f,16.7068f,218.75f, +136.719f,17.6679f,218.75f, +140.625f,18.8257f,218.75f, +144.531f,24.2255f,218.75f, +148.438f,25.0749f,218.75f, +152.344f,25.9271f,218.75f, +156.25f,26.2032f,218.75f, +160.156f,24.5168f,218.75f, +164.063f,26.2403f,218.75f, +167.969f,26.6223f,218.75f, +171.875f,22.4271f,218.75f, +175.781f,23.7925f,218.75f, +179.688f,23.3478f,218.75f, +183.594f,22.2279f,218.75f, +187.5f,22.2148f,218.75f, +191.406f,20.7538f,218.75f, +195.313f,19.5131f,218.75f, +199.219f,19.4834f,218.75f, +203.125f,18.3756f,218.75f, +207.031f,18.1034f,218.75f, +210.938f,20.0003f,218.75f, +214.844f,22.2111f,218.75f, +218.75f,21.6123f,218.75f, +222.656f,22.5943f,218.75f, +226.563f,24.3115f,218.75f, +230.469f,19.0536f,218.75f, +234.375f,18.6613f,218.75f, +238.281f,18.7675f,218.75f, +242.188f,18.3163f,218.75f, +246.094f,16.7013f,218.75f, +250.0f,17.0786f,218.75f, +3.90627f,9.25513f,214.844f, +7.81251f,9.67426f,214.844f, +11.7188f,8.92139f,214.844f, +15.625f,6.90738f,214.844f, +19.5313f,6.12616f,214.844f, +23.4375f,4.98302f,214.844f, +27.3438f,3.63786f,214.844f, +31.25f,2.52097f,214.844f, +35.1563f,3.30816f,214.844f, +39.0625f,4.04406f,214.844f, +42.9688f,4.48446f,214.844f, +46.875f,4.40695f,214.844f, +50.7813f,3.7693f,214.844f, +54.6875f,2.85523f,214.844f, +58.5938f,2.56849f,214.844f, +62.5f,2.56561f,214.844f, +66.4063f,2.82937f,214.844f, +70.3125f,2.75221f,214.844f, +74.2188f,5.02974f,214.844f, +78.125f,5.7988f,214.844f, +82.0313f,6.03219f,214.844f, +85.9375f,6.27423f,214.844f, +89.8438f,6.1671f,214.844f, +93.75f,6.86893f,214.844f, +97.6563f,7.94747f,214.844f, +101.563f,9.13548f,214.844f, +105.469f,9.63636f,214.844f, +109.375f,10.3351f,214.844f, +113.281f,12.4028f,214.844f, +117.188f,13.0321f,214.844f, +121.094f,13.6284f,214.844f, +125.0f,14.3167f,214.844f, +128.906f,15.0573f,214.844f, +132.813f,16.2022f,214.844f, +136.719f,17.7526f,214.844f, +140.625f,23.7093f,214.844f, +144.531f,24.3603f,214.844f, +148.438f,24.9195f,214.844f, +152.344f,25.198f,214.844f, +156.25f,20.8225f,214.844f, +160.156f,24.5918f,214.844f, +164.063f,25.1404f,214.844f, +167.969f,26.0659f,214.844f, +171.875f,22.1485f,214.844f, +175.781f,27.7236f,214.844f, +179.688f,27.4914f,214.844f, +183.594f,26.6606f,214.844f, +187.5f,26.623f,214.844f, +191.406f,26.3244f,214.844f, +195.313f,24.8535f,214.844f, +199.219f,23.6373f,214.844f, +203.125f,21.1881f,214.844f, +207.031f,19.7509f,214.844f, +210.938f,22.3046f,214.844f, +214.844f,22.5297f,214.844f, +218.75f,22.9498f,214.844f, +222.656f,23.2271f,214.844f, +226.563f,24.89f,214.844f, +230.469f,23.5226f,214.844f, +234.375f,19.0463f,214.844f, +238.281f,17.96f,214.844f, +242.188f,18.8106f,214.844f, +246.094f,17.3168f,214.844f, +250.0f,16.7955f,214.844f, +3.90627f,10.5728f,210.938f, +7.81251f,9.81018f,210.938f, +11.7188f,9.69715f,210.938f, +15.625f,8.42137f,210.938f, +19.5313f,7.09174f,210.938f, +23.4375f,6.45357f,210.938f, +27.3438f,4.58257f,210.938f, +31.25f,4.31044f,210.938f, +35.1563f,4.23584f,210.938f, +39.0625f,4.77527f,210.938f, +42.9688f,5.51217f,210.938f, +46.875f,5.48962f,210.938f, +50.7813f,4.50211f,210.938f, +54.6875f,4.06287f,210.938f, +58.5938f,3.43161f,210.938f, +62.5f,3.43195f,210.938f, +66.4063f,3.64204f,210.938f, +70.3125f,5.16151f,210.938f, +74.2188f,6.72853f,210.938f, +78.125f,7.43878f,210.938f, +82.0313f,7.30716f,210.938f, +85.9375f,6.54327f,210.938f, +89.8438f,5.96003f,210.938f, +93.75f,6.45099f,210.938f, +97.6563f,8.32748f,210.938f, +101.563f,8.85186f,210.938f, +105.469f,9.64058f,210.938f, +109.375f,10.4181f,210.938f, +113.281f,11.6911f,210.938f, +117.188f,12.0508f,210.938f, +121.094f,13.1004f,210.938f, +125.0f,14.4899f,210.938f, +128.906f,15.1295f,210.938f, +132.813f,15.6195f,210.938f, +136.719f,16.9219f,210.938f, +140.625f,23.4614f,210.938f, +144.531f,24.6763f,210.938f, +148.438f,26.12f,210.938f, +152.344f,21.7533f,210.938f, +156.25f,20.7448f,210.938f, +160.156f,24.1481f,210.938f, +164.063f,26.0464f,210.938f, +167.969f,25.1633f,210.938f, +171.875f,20.8056f,210.938f, +175.781f,26.3651f,210.938f, +179.688f,25.5322f,210.938f, +183.594f,26.3828f,210.938f, +187.5f,26.3586f,210.938f, +191.406f,26.1714f,210.938f, +195.313f,25.9695f,210.938f, +199.219f,24.3505f,210.938f, +203.125f,23.872f,210.938f, +207.031f,23.0401f,210.938f, +210.938f,22.3904f,210.938f, +214.844f,22.7647f,210.938f, +218.75f,23.266f,210.938f, +222.656f,23.8563f,210.938f, +226.563f,24.6635f,210.938f, +230.469f,24.3846f,210.938f, +234.375f,18.3213f,210.938f, +238.281f,17.6531f,210.938f, +242.188f,17.8854f,210.938f, +246.094f,17.1692f,210.938f, +250.0f,16.127f,210.938f, +3.90626f,10.4539f,207.031f, +7.81251f,10.0241f,207.031f, +11.7188f,10.3861f,207.031f, +15.625f,8.84417f,207.031f, +19.5313f,8.35477f,207.031f, +23.4375f,6.48112f,207.031f, +27.3438f,6.10753f,207.031f, +31.25f,6.13796f,207.031f, +35.1563f,6.51045f,207.031f, +39.0625f,6.65278f,207.031f, +42.9688f,6.27698f,207.031f, +46.875f,5.80577f,207.031f, +50.7813f,5.90354f,207.031f, +54.6875f,5.66137f,207.031f, +58.5938f,4.67472f,207.031f, +62.5f,4.81103f,207.031f, +66.4063f,6.06764f,207.031f, +70.3125f,7.61387f,207.031f, +74.2188f,8.72682f,207.031f, +78.125f,9.33231f,207.031f, +82.0313f,8.49751f,207.031f, +85.9375f,7.85293f,207.031f, +89.8438f,7.37573f,207.031f, +93.75f,7.4561f,207.031f, +97.6563f,7.76623f,207.031f, +101.563f,8.68264f,207.031f, +105.469f,10.4373f,207.031f, +109.375f,10.4722f,207.031f, +113.281f,11.4418f,207.031f, +117.188f,12.3081f,207.031f, +121.094f,12.9224f,207.031f, +125.0f,14.3204f,207.031f, +128.906f,15.1746f,207.031f, +132.813f,14.4847f,207.031f, +136.719f,20.974f,207.031f, +140.625f,23.4669f,207.031f, +144.531f,24.9918f,207.031f, +148.438f,25.7345f,207.031f, +152.344f,21.4943f,207.031f, +156.25f,22.169f,207.031f, +160.156f,24.9739f,207.031f, +164.063f,26.4423f,207.031f, +167.969f,25.8928f,207.031f, +171.875f,20.5408f,207.031f, +175.781f,24.2294f,207.031f, +179.688f,24.4008f,207.031f, +183.594f,25.2809f,207.031f, +187.5f,25.8589f,207.031f, +191.406f,26.3716f,207.031f, +195.313f,26.0525f,207.031f, +199.219f,24.6109f,207.031f, +203.125f,24.1128f,207.031f, +207.031f,23.4731f,207.031f, +210.938f,22.6487f,207.031f, +214.844f,22.7977f,207.031f, +218.75f,18.4754f,207.031f, +222.656f,23.1848f,207.031f, +226.563f,23.1818f,207.031f, +230.469f,22.9194f,207.031f, +234.375f,19.8052f,207.031f, +238.281f,16.8602f,207.031f, +242.188f,17.1047f,207.031f, +246.094f,16.1145f,207.031f, +250.0f,15.0049f,207.031f, +3.90626f,11.4706f,203.125f, +7.81251f,11.0922f,203.125f, +11.7188f,11.454f,203.125f, +15.625f,10.399f,203.125f, +19.5313f,8.89365f,203.125f, +23.4375f,7.52605f,203.125f, +27.3438f,7.07779f,203.125f, +31.25f,7.98082f,203.125f, +35.1563f,8.78342f,203.125f, +39.0625f,8.87165f,203.125f, +42.9688f,8.39122f,203.125f, +46.875f,7.48032f,203.125f, +50.7813f,6.77944f,203.125f, +54.6875f,7.14862f,203.125f, +58.5938f,6.46173f,203.125f, +62.5f,6.73824f,203.125f, +66.4063f,7.64505f,203.125f, +70.3125f,9.22763f,203.125f, +74.2188f,9.87781f,203.125f, +78.125f,10.1574f,203.125f, +82.0313f,9.81606f,203.125f, +85.9375f,9.8669f,203.125f, +89.8438f,10.0032f,203.125f, +93.75f,9.76597f,203.125f, +97.6563f,9.2129f,203.125f, +101.563f,8.89917f,203.125f, +105.469f,9.85112f,203.125f, +109.375f,11.4827f,203.125f, +113.281f,11.8911f,203.125f, +117.188f,12.3305f,203.125f, +121.094f,13.6098f,203.125f, +125.0f,14.1477f,203.125f, +128.906f,14.7928f,203.125f, +132.813f,16.3422f,203.125f, +136.719f,22.7583f,203.125f, +140.625f,24.5881f,203.125f, +144.531f,25.3565f,203.125f, +148.438f,21.7799f,203.125f, +152.344f,24.1222f,203.125f, +156.25f,26.6774f,203.125f, +160.156f,25.7031f,203.125f, +164.063f,26.9766f,203.125f, +167.969f,25.936f,203.125f, +171.875f,19.7727f,203.125f, +175.781f,19.3015f,203.125f, +179.688f,19.2421f,203.125f, +183.594f,24.8014f,203.125f, +187.5f,25.3041f,203.125f, +191.406f,25.3226f,203.125f, +195.313f,20.0369f,203.125f, +199.219f,19.4927f,203.125f, +203.125f,23.4349f,203.125f, +207.031f,22.748f,203.125f, +210.938f,22.4583f,203.125f, +214.844f,18.8936f,203.125f, +218.75f,17.4565f,203.125f, +222.656f,18.8235f,203.125f, +226.563f,21.4749f,203.125f, +230.469f,21.7691f,203.125f, +234.375f,21.1398f,203.125f, +238.281f,15.9012f,203.125f, +242.188f,15.9735f,203.125f, +246.094f,15.2287f,203.125f, +250.0f,13.5655f,203.125f, +3.90626f,12.1184f,199.219f, +7.81251f,12.3652f,199.219f, +11.7188f,12.1177f,199.219f, +15.625f,11.107f,199.219f, +19.5313f,9.91183f,199.219f, +23.4375f,8.6581f,199.219f, +27.3438f,7.98212f,199.219f, +31.25f,9.14995f,199.219f, +35.1563f,10.2879f,199.219f, +39.0625f,10.2569f,199.219f, +42.9688f,9.58908f,199.219f, +46.875f,8.1296f,199.219f, +50.7813f,7.81944f,199.219f, +54.6875f,8.54521f,199.219f, +58.5938f,8.14627f,199.219f, +62.5f,8.60974f,199.219f, +66.4063f,9.63518f,199.219f, +70.3125f,10.5321f,199.219f, +74.2188f,10.3348f,199.219f, +78.125f,11.2806f,199.219f, +82.0313f,11.3874f,199.219f, +85.9375f,11.6949f,199.219f, +89.8438f,12.3833f,199.219f, +93.75f,12.4654f,199.219f, +97.6563f,11.369f,199.219f, +101.563f,10.2737f,199.219f, +105.469f,10.4291f,199.219f, +109.375f,11.0962f,199.219f, +113.281f,12.1388f,199.219f, +117.188f,12.5535f,199.219f, +121.094f,13.2826f,199.219f, +125.0f,15.1899f,199.219f, +128.906f,16.3486f,199.219f, +132.813f,17.6147f,199.219f, +136.719f,23.878f,199.219f, +140.625f,24.5901f,199.219f, +144.531f,26.2181f,199.219f, +148.438f,21.847f,199.219f, +152.344f,26.5018f,199.219f, +156.25f,26.2772f,199.219f, +160.156f,26.4621f,199.219f, +164.063f,26.1902f,199.219f, +167.969f,26.1086f,199.219f, +171.875f,20.7414f,199.219f, +175.781f,20.393f,199.219f, +179.688f,19.7885f,199.219f, +183.594f,20.9687f,199.219f, +187.5f,23.8625f,199.219f, +191.406f,24.0825f,199.219f, +195.313f,19.4921f,199.219f, +199.219f,20.8763f,199.219f, +203.125f,21.987f,199.219f, +207.031f,21.9212f,199.219f, +210.938f,20.0341f,199.219f, +214.844f,15.7998f,199.219f, +218.75f,15.7759f,199.219f, +222.656f,15.8963f,199.219f, +226.563f,19.8168f,199.219f, +230.469f,19.9894f,199.219f, +234.375f,19.4382f,199.219f, +238.281f,14.2335f,199.219f, +242.188f,14.9225f,199.219f, +246.094f,13.5857f,199.219f, +250.0f,11.7225f,199.219f, +3.90626f,13.8013f,195.313f, +7.81251f,13.8046f,195.313f, +11.7188f,13.1462f,195.313f, +15.625f,12.2626f,195.313f, +19.5313f,10.67f,195.313f, +23.4375f,10.0372f,195.313f, +27.3438f,9.3255f,195.313f, +31.25f,10.5057f,195.313f, +35.1563f,11.0615f,195.313f, +39.0625f,11.2421f,195.313f, +42.9688f,10.4767f,195.313f, +46.875f,9.03042f,195.313f, +50.7813f,9.47397f,195.313f, +54.6875f,9.65703f,195.313f, +58.5938f,9.6345f,195.313f, +62.5f,9.9552f,195.313f, +66.4063f,10.8427f,195.313f, +70.3125f,11.7912f,195.313f, +74.2188f,11.5822f,195.313f, +78.125f,13.07f,195.313f, +82.0313f,13.803f,195.313f, +85.9375f,12.9764f,195.313f, +89.8438f,14.639f,195.313f, +93.75f,14.6139f,195.313f, +97.6563f,13.3162f,195.313f, +101.563f,12.7402f,195.313f, +105.469f,12.8061f,195.313f, +109.375f,12.1167f,195.313f, +113.281f,12.705f,195.313f, +117.188f,12.4568f,195.313f, +121.094f,13.5698f,195.313f, +125.0f,15.1843f,195.313f, +128.906f,16.7529f,195.313f, +132.813f,19.1744f,195.313f, +136.719f,23.9261f,195.313f, +140.625f,25.9824f,195.313f, +144.531f,26.1631f,195.313f, +148.438f,21.4735f,195.313f, +152.344f,25.5313f,195.313f, +156.25f,27.0098f,195.313f, +160.156f,27.5776f,195.313f, +164.063f,27.0858f,195.313f, +167.969f,26.3007f,195.313f, +171.875f,23.4599f,195.313f, +175.781f,26.4252f,195.313f, +179.688f,21.1453f,195.313f, +183.594f,21.1021f,195.313f, +187.5f,25.1644f,195.313f, +191.406f,24.8681f,195.313f, +195.313f,24.1757f,195.313f, +199.219f,20.0013f,195.313f, +203.125f,23.6085f,195.313f, +207.031f,22.7043f,195.313f, +210.938f,17.4097f,195.313f, +214.844f,16.8216f,195.313f, +218.75f,16.2595f,195.313f, +222.656f,15.547f,195.313f, +226.563f,20.5074f,195.313f, +230.469f,20.0296f,195.313f, +234.375f,19.4594f,195.313f, +238.281f,14.3376f,195.313f, +242.188f,13.8667f,195.313f, +246.094f,12.7786f,195.313f, +250.0f,12.669f,195.313f, +3.90626f,14.3936f,191.406f, +7.81251f,14.3324f,191.406f, +11.7188f,13.5165f,191.406f, +15.625f,12.3486f,191.406f, +19.5313f,10.8996f,191.406f, +23.4375f,10.767f,191.406f, +27.3438f,12.0663f,191.406f, +31.25f,12.0032f,191.406f, +35.1563f,12.6763f,191.406f, +39.0625f,12.4746f,191.406f, +42.9688f,10.9305f,191.406f, +46.875f,11.0794f,191.406f, +50.7813f,11.2588f,191.406f, +54.6875f,11.0855f,191.406f, +58.5938f,10.1448f,191.406f, +62.5f,11.1184f,191.406f, +66.4063f,12.2266f,191.406f, +70.3125f,12.3132f,191.406f, +74.2188f,13.6918f,191.406f, +78.125f,14.4314f,191.406f, +82.0313f,14.6924f,191.406f, +85.9375f,15.6669f,191.406f, +89.8438f,16.085f,191.406f, +93.75f,16.2697f,191.406f, +97.6563f,16.3584f,191.406f, +101.563f,15.6226f,191.406f, +105.469f,14.7096f,191.406f, +109.375f,14.172f,191.406f, +113.281f,13.6538f,191.406f, +117.188f,14.6791f,191.406f, +121.094f,15.1835f,191.406f, +125.0f,16.4947f,191.406f, +128.906f,17.5173f,191.406f, +132.813f,22.4657f,191.406f, +136.719f,25.2206f,191.406f, +140.625f,26.6814f,191.406f, +144.531f,27.4657f,191.406f, +148.438f,22.8092f,191.406f, +152.344f,22.336f,191.406f, +156.25f,29.0833f,191.406f, +160.156f,29.5204f,191.406f, +164.063f,29.4008f,191.406f, +167.969f,28.5038f,191.406f, +171.875f,27.7213f,191.406f, +175.781f,27.6884f,191.406f, +179.688f,25.8434f,191.406f, +183.594f,23.3048f,191.406f, +187.5f,27.635f,191.406f, +191.406f,26.1341f,191.406f, +195.313f,26.6792f,191.406f, +199.219f,22.747f,191.406f, +203.125f,22.8472f,191.406f, +207.031f,21.8628f,191.406f, +210.938f,20.5896f,191.406f, +214.844f,20.683f,191.406f, +218.75f,15.9904f,191.406f, +222.656f,16.3766f,191.406f, +226.563f,21.611f,191.406f, +230.469f,20.8727f,191.406f, +234.375f,20.2044f,191.406f, +238.281f,15.3358f,191.406f, +242.188f,14.7065f,191.406f, +246.094f,14.4372f,191.406f, +250.0f,14.1124f,191.406f, +3.90626f,14.1738f,187.5f, +7.81252f,14.5502f,187.5f, +11.7188f,13.6083f,187.5f, +15.625f,12.2654f,187.5f, +19.5313f,11.7405f,187.5f, +23.4375f,12.3756f,187.5f, +27.3438f,14.0775f,187.5f, +31.25f,13.9675f,187.5f, +35.1563f,14.3286f,187.5f, +39.0625f,13.1055f,187.5f, +42.9688f,13.0413f,187.5f, +46.875f,13.318f,187.5f, +50.7813f,12.9383f,187.5f, +54.6875f,12.9366f,187.5f, +58.5938f,12.1308f,187.5f, +62.5f,12.8501f,187.5f, +66.4063f,13.0312f,187.5f, +70.3125f,13.1657f,187.5f, +74.2188f,14.6177f,187.5f, +78.125f,16.1865f,187.5f, +82.0313f,16.3194f,187.5f, +85.9375f,16.9023f,187.5f, +89.8438f,17.5469f,187.5f, +93.75f,18.1166f,187.5f, +97.6563f,18.7398f,187.5f, +101.563f,18.2643f,187.5f, +105.469f,17.5115f,187.5f, +109.375f,16.8559f,187.5f, +113.281f,15.8332f,187.5f, +117.188f,16.4429f,187.5f, +121.094f,17.0698f,187.5f, +125.0f,18.0389f,187.5f, +128.906f,19.8697f,187.5f, +132.813f,24.8511f,187.5f, +136.719f,26.6838f,187.5f, +140.625f,28.5323f,187.5f, +144.531f,28.756f,187.5f, +148.438f,25.5762f,187.5f, +152.344f,25.8993f,187.5f, +156.25f,29.0469f,187.5f, +160.156f,32.1254f,187.5f, +164.063f,32.1318f,187.5f, +167.969f,31.7887f,187.5f, +171.875f,30.3727f,187.5f, +175.781f,30.1222f,187.5f, +179.688f,30.3556f,187.5f, +183.594f,30.49f,187.5f, +187.5f,29.3956f,187.5f, +191.406f,30.6569f,187.5f, +195.313f,30.8632f,187.5f, +199.219f,26.1118f,187.5f, +203.125f,25.5008f,187.5f, +207.031f,24.7878f,187.5f, +210.938f,27.5453f,187.5f, +214.844f,25.5271f,187.5f, +218.75f,20.2295f,187.5f, +222.656f,17.2785f,187.5f, +226.563f,22.0337f,187.5f, +230.469f,22.1938f,187.5f, +234.375f,21.6646f,187.5f, +238.281f,16.8654f,187.5f, +242.188f,15.704f,187.5f, +246.094f,15.9973f,187.5f, +250.0f,15.209f,187.5f, +3.90626f,13.9878f,183.594f, +7.81252f,14.3413f,183.594f, +11.7188f,13.1779f,183.594f, +15.625f,12.8538f,183.594f, +19.5313f,13.9436f,183.594f, +23.4375f,14.716f,183.594f, +27.3438f,14.991f,183.594f, +31.25f,15.4235f,183.594f, +35.1563f,15.3865f,183.594f, +39.0625f,14.2459f,183.594f, +42.9688f,15.2992f,183.594f, +46.875f,16.0599f,183.594f, +50.7813f,14.8603f,183.594f, +54.6875f,14.9726f,183.594f, +58.5938f,13.6053f,183.594f, +62.5f,13.057f,183.594f, +66.4063f,13.4201f,183.594f, +70.3125f,14.0782f,183.594f, +74.2188f,15.3178f,183.594f, +78.125f,16.3995f,183.594f, +82.0313f,17.4379f,183.594f, +85.9375f,17.9502f,183.594f, +89.8438f,18.4811f,183.594f, +93.75f,19.4227f,183.594f, +97.6563f,20.1694f,183.594f, +101.563f,20.1609f,183.594f, +105.469f,19.5537f,183.594f, +109.375f,19.039f,183.594f, +113.281f,18.2247f,183.594f, +117.188f,18.6643f,183.594f, +121.094f,19.2334f,183.594f, +125.0f,20.4158f,183.594f, +128.906f,21.1136f,183.594f, +132.813f,25.6638f,183.594f, +136.719f,27.4642f,183.594f, +140.625f,29.0749f,183.594f, +144.531f,30.6966f,183.594f, +148.438f,26.933f,183.594f, +152.344f,27.9984f,183.594f, +156.25f,28.4094f,183.594f, +160.156f,33.857f,183.594f, +164.063f,34.6528f,183.594f, +167.969f,33.405f,183.594f, +171.875f,31.8412f,183.594f, +175.781f,31.8788f,183.594f, +179.688f,32.395f,183.594f, +183.594f,32.8498f,183.594f, +187.5f,28.7385f,183.594f, +191.406f,33.6253f,183.594f, +195.313f,32.9673f,183.594f, +199.219f,31.8413f,183.594f, +203.125f,26.491f,183.594f, +207.031f,29.4589f,183.594f, +210.938f,28.7843f,183.594f, +214.844f,26.577f,183.594f, +218.75f,25.0304f,183.594f, +222.656f,18.7948f,183.594f, +226.563f,23.1467f,183.594f, +230.469f,22.3329f,183.594f, +234.375f,21.6877f,183.594f, +238.281f,16.4114f,183.594f, +242.188f,16.4672f,183.594f, +246.094f,16.3324f,183.594f, +250.0f,16.0497f,183.594f, +3.90626f,14.6785f,179.688f, +7.81252f,14.4582f,179.688f, +11.7188f,13.7379f,179.688f, +15.625f,13.9816f,179.688f, +19.5313f,14.9647f,179.688f, +23.4375f,15.3633f,179.688f, +27.3438f,16.1346f,179.688f, +31.25f,16.4088f,179.688f, +35.1563f,16.195f,179.688f, +39.0625f,16.1785f,179.688f, +42.9688f,17.2534f,179.688f, +46.875f,17.329f,179.688f, +50.7813f,16.0096f,179.688f, +54.6875f,15.4766f,179.688f, +58.5938f,14.0828f,179.688f, +62.5f,12.8927f,179.688f, +66.4063f,14.1195f,179.688f, +70.3125f,14.9421f,179.688f, +74.2188f,15.9015f,179.688f, +78.125f,17.3756f,179.688f, +82.0313f,18.6339f,179.688f, +85.9375f,19.7602f,179.688f, +89.8438f,19.8522f,179.688f, +93.75f,20.5838f,179.688f, +97.6563f,21.2938f,179.688f, +101.563f,21.1808f,179.688f, +105.469f,21.4575f,179.688f, +109.375f,21.1629f,179.688f, +113.281f,20.4789f,179.688f, +117.188f,20.5729f,179.688f, +121.094f,20.3917f,179.688f, +125.0f,21.8501f,179.688f, +128.906f,22.6846f,179.688f, +132.813f,23.4145f,179.688f, +136.719f,28.3033f,179.688f, +140.625f,30.5638f,179.688f, +144.531f,32.761f,179.688f, +148.438f,29.4434f,179.688f, +152.344f,30.346f,179.688f, +156.25f,31.7037f,179.688f, +160.156f,36.287f,179.688f, +164.063f,36.7423f,179.688f, +167.969f,35.7482f,179.688f, +171.875f,30.0008f,179.688f, +175.781f,29.6748f,179.688f, +179.688f,34.5316f,179.688f, +183.594f,34.4476f,179.688f, +187.5f,34.3489f,179.688f, +191.406f,33.4208f,179.688f, +195.313f,29.5511f,179.688f, +199.219f,28.9653f,179.688f, +203.125f,28.1749f,179.688f, +207.031f,30.5574f,179.688f, +210.938f,28.6513f,179.688f, +214.844f,27.1867f,179.688f, +218.75f,20.8455f,179.688f, +222.656f,20.3256f,179.688f, +226.563f,24.3717f,179.688f, +230.469f,23.2197f,179.688f, +234.375f,21.6566f,179.688f, +238.281f,16.2487f,179.688f, +242.188f,16.7759f,179.688f, +246.094f,16.5259f,179.688f, +250.0f,15.8782f,179.688f, +3.90626f,15.2963f,175.781f, +7.81252f,15.075f,175.781f, +11.7188f,14.8069f,175.781f, +15.625f,14.4469f,175.781f, +19.5313f,15.8073f,175.781f, +23.4375f,16.5419f,175.781f, +27.3438f,16.7791f,175.781f, +31.25f,17.1945f,175.781f, +35.1563f,16.9974f,175.781f, +39.0625f,16.9655f,175.781f, +42.9688f,17.7583f,175.781f, +46.875f,18.115f,175.781f, +50.7813f,16.6524f,175.781f, +54.6875f,15.897f,175.781f, +58.5938f,15.4613f,175.781f, +62.5f,14.3684f,175.781f, +66.4063f,15.0403f,175.781f, +70.3125f,15.9604f,175.781f, +74.2188f,16.9477f,175.781f, +78.125f,18.0563f,175.781f, +82.0313f,18.8971f,175.781f, +85.9375f,20.1037f,175.781f, +89.8438f,20.3627f,175.781f, +93.75f,20.0215f,175.781f, +97.6563f,20.8917f,175.781f, +101.563f,21.8702f,175.781f, +105.469f,22.7304f,175.781f, +109.375f,22.6873f,175.781f, +113.281f,21.4896f,175.781f, +117.188f,21.3864f,175.781f, +121.094f,22.4194f,175.781f, +125.0f,23.5751f,175.781f, +128.906f,23.9616f,175.781f, +132.813f,24.6066f,175.781f, +136.719f,30.8792f,175.781f, +140.625f,31.6572f,175.781f, +144.531f,34.2264f,175.781f, +148.438f,30.9611f,175.781f, +152.344f,35.8851f,175.781f, +156.25f,38.6379f,175.781f, +160.156f,39.1098f,175.781f, +164.063f,39.046f,175.781f, +167.969f,38.0327f,175.781f, +171.875f,36.6611f,175.781f, +175.781f,36.0664f,175.781f, +179.688f,36.1227f,175.781f, +183.594f,36.0705f,175.781f, +187.5f,35.9099f,175.781f, +191.406f,30.4106f,175.781f, +195.313f,30.0475f,175.781f, +199.219f,28.9213f,175.781f, +203.125f,32.8995f,175.781f, +207.031f,31.2376f,175.781f, +210.938f,30.0194f,175.781f, +214.844f,23.402f,175.781f, +218.75f,21.7271f,175.781f, +222.656f,20.0594f,175.781f, +226.563f,25.2266f,175.781f, +230.469f,24.1549f,175.781f, +234.375f,22.0418f,175.781f, +238.281f,15.6301f,175.781f, +242.188f,15.4767f,175.781f, +246.094f,15.8876f,175.781f, +250.0f,15.1339f,175.781f, +3.90626f,16.0791f,171.875f, +7.81251f,16.012f,171.875f, +11.7188f,15.027f,171.875f, +15.625f,15.1362f,171.875f, +19.5313f,16.3622f,171.875f, +23.4375f,16.7304f,171.875f, +27.3438f,17.228f,171.875f, +31.25f,16.4882f,171.875f, +35.1563f,16.5399f,171.875f, +39.0625f,17.5505f,171.875f, +42.9688f,17.6944f,171.875f, +46.875f,17.7481f,171.875f, +50.7813f,17.4568f,171.875f, +54.6875f,16.5655f,171.875f, +58.5938f,15.4313f,171.875f, +62.5f,14.962f,171.875f, +66.4063f,15.2516f,171.875f, +70.3125f,16.3088f,171.875f, +74.2188f,17.5354f,171.875f, +78.125f,18.5759f,171.875f, +82.0313f,19.1666f,171.875f, +85.9375f,19.8244f,171.875f, +89.8438f,20.6303f,171.875f, +93.75f,20.5635f,171.875f, +97.6563f,20.5768f,171.875f, +101.563f,21.542f,171.875f, +105.469f,22.5605f,171.875f, +109.375f,23.0118f,171.875f, +113.281f,22.6086f,171.875f, +117.188f,22.8502f,171.875f, +121.094f,23.2278f,171.875f, +125.0f,24.368f,171.875f, +128.906f,25.5759f,171.875f, +132.813f,27.7217f,171.875f, +136.719f,33.4581f,171.875f, +140.625f,33.4128f,171.875f, +144.531f,34.9465f,171.875f, +148.438f,31.4923f,171.875f, +152.344f,38.6707f,171.875f, +156.25f,40.2713f,171.875f, +160.156f,40.4155f,171.875f, +164.063f,41.0232f,171.875f, +167.969f,39.781f,171.875f, +171.875f,37.8376f,171.875f, +175.781f,38.0559f,171.875f, +179.688f,32.0147f,171.875f, +183.594f,35.2298f,171.875f, +187.5f,34.7221f,171.875f, +191.406f,31.5516f,171.875f, +195.313f,28.9984f,171.875f, +199.219f,29.8767f,171.875f, +203.125f,32.6404f,171.875f, +207.031f,31.3413f,171.875f, +210.938f,28.4132f,171.875f, +214.844f,22.9909f,171.875f, +218.75f,21.3955f,171.875f, +222.656f,25.3135f,171.875f, +226.563f,25.1463f,171.875f, +230.469f,23.4716f,171.875f, +234.375f,22.494f,171.875f, +238.281f,15.9351f,171.875f, +242.188f,15.2882f,171.875f, +246.094f,14.8463f,171.875f, +250.0f,14.5269f,171.875f, +3.90626f,17.1455f,167.969f, +7.81251f,16.6981f,167.969f, +11.7188f,16.5681f,167.969f, +15.625f,16.1667f,167.969f, +19.5313f,16.3523f,167.969f, +23.4375f,16.5389f,167.969f, +27.3438f,16.8075f,167.969f, +31.25f,17.1987f,167.969f, +35.1563f,17.86f,167.969f, +39.0625f,18.5438f,167.969f, +42.9688f,18.6718f,167.969f, +46.875f,17.9387f,167.969f, +50.7813f,17.5403f,167.969f, +54.6875f,17.4895f,167.969f, +58.5938f,16.9679f,167.969f, +62.5f,16.2192f,167.969f, +66.4063f,15.5699f,167.969f, +70.3125f,17.0017f,167.969f, +74.2188f,18.0147f,167.969f, +78.125f,18.9836f,167.969f, +82.0313f,19.8197f,167.969f, +85.9375f,19.8969f,167.969f, +89.8438f,20.6411f,167.969f, +93.75f,20.9768f,167.969f, +97.6563f,21.1498f,167.969f, +101.563f,21.3269f,167.969f, +105.469f,22.1153f,167.969f, +109.375f,22.208f,167.969f, +113.281f,23.2278f,167.969f, +117.188f,24.5722f,167.969f, +121.094f,25.3921f,167.969f, +125.0f,26.2683f,167.969f, +128.906f,28.138f,167.969f, +132.813f,29.9483f,167.969f, +136.719f,34.7607f,167.969f, +140.625f,35.3745f,167.969f, +144.531f,36.1401f,167.969f, +148.438f,38.0587f,167.969f, +152.344f,40.0092f,167.969f, +156.25f,40.9205f,167.969f, +160.156f,41.4664f,167.969f, +164.063f,41.8834f,167.969f, +167.969f,40.2863f,167.969f, +171.875f,38.4111f,167.969f, +175.781f,37.4971f,167.969f, +179.688f,32.0995f,167.969f, +183.594f,36.4852f,167.969f, +187.5f,34.5523f,167.969f, +191.406f,34.4101f,167.969f, +195.313f,29.577f,167.969f, +199.219f,33.7462f,167.969f, +203.125f,33.0191f,167.969f, +207.031f,31.6651f,167.969f, +210.938f,24.6623f,167.969f, +214.844f,22.6532f,167.969f, +218.75f,21.898f,167.969f, +222.656f,26.1764f,167.969f, +226.563f,24.7619f,167.969f, +230.469f,22.6772f,167.969f, +234.375f,17.6202f,167.969f, +238.281f,16.1581f,167.969f, +242.188f,14.7308f,167.969f, +246.094f,14.294f,167.969f, +250.0f,13.1169f,167.969f, +3.90627f,16.4621f,164.063f, +7.81251f,17.581f,164.063f, +11.7188f,17.7296f,164.063f, +15.625f,17.126f,164.063f, +19.5313f,17.3484f,164.063f, +23.4375f,17.9863f,164.063f, +27.3438f,18.6623f,164.063f, +31.25f,18.7934f,164.063f, +35.1563f,18.8245f,164.063f, +39.0625f,18.9554f,164.063f, +42.9688f,19.3152f,164.063f, +46.875f,18.5996f,164.063f, +50.7813f,18.0094f,164.063f, +54.6875f,17.5702f,164.063f, +58.5938f,17.5846f,164.063f, +62.5f,17.3718f,164.063f, +66.4063f,17.7189f,164.063f, +70.3125f,17.9805f,164.063f, +74.2188f,18.2986f,164.063f, +78.125f,18.9566f,164.063f, +82.0313f,20.4142f,164.063f, +85.9375f,20.5066f,164.063f, +89.8438f,20.7654f,164.063f, +93.75f,20.9457f,164.063f, +97.6563f,21.1078f,164.063f, +101.563f,20.7505f,164.063f, +105.469f,21.4615f,164.063f, +109.375f,22.8061f,164.063f, +113.281f,24.2655f,164.063f, +117.188f,24.815f,164.063f, +121.094f,26.3141f,164.063f, +125.0f,28.393f,164.063f, +128.906f,30.0565f,164.063f, +132.813f,31.4858f,164.063f, +136.719f,31.6549f,164.063f, +140.625f,37.0597f,164.063f, +144.531f,37.7613f,164.063f, +148.438f,38.9888f,164.063f, +152.344f,39.1482f,164.063f, +156.25f,36.6367f,164.063f, +160.156f,41.2606f,164.063f, +164.063f,42.2366f,164.063f, +167.969f,40.9757f,164.063f, +171.875f,33.9016f,164.063f, +175.781f,34.1798f,164.063f, +179.688f,33.0682f,164.063f, +183.594f,35.2269f,164.063f, +187.5f,35.1129f,164.063f, +191.406f,34.7006f,164.063f, +195.313f,30.1221f,164.063f, +199.219f,34.6592f,164.063f, +203.125f,33.6195f,164.063f, +207.031f,30.0546f,164.063f, +210.938f,24.8295f,164.063f, +214.844f,23.0298f,164.063f, +218.75f,26.5636f,164.063f, +222.656f,25.7973f,164.063f, +226.563f,23.7612f,164.063f, +230.469f,22.3646f,164.063f, +234.375f,16.1956f,164.063f, +238.281f,14.863f,164.063f, +242.188f,13.95f,164.063f, +246.094f,14.1968f,164.063f, +250.0f,13.2951f,164.063f, +3.90627f,16.628f,160.156f, +7.81251f,17.4268f,160.156f, +11.7188f,18.0363f,160.156f, +15.625f,18.1287f,160.156f, +19.5313f,18.6222f,160.156f, +23.4375f,18.2801f,160.156f, +27.3438f,18.5912f,160.156f, +31.25f,18.8635f,160.156f, +35.1563f,19.2193f,160.156f, +39.0625f,18.8821f,160.156f, +42.9688f,19.0078f,160.156f, +46.875f,19.3506f,160.156f, +50.7813f,17.8504f,160.156f, +54.6875f,18.5322f,160.156f, +58.5938f,18.2223f,160.156f, +62.5f,18.032f,160.156f, +66.4063f,18.574f,160.156f, +70.3125f,18.3835f,160.156f, +74.2188f,18.0842f,160.156f, +78.125f,19.8632f,160.156f, +82.0313f,20.9487f,160.156f, +85.9375f,20.6197f,160.156f, +89.8438f,20.5117f,160.156f, +93.75f,20.4182f,160.156f, +97.6563f,19.8654f,160.156f, +101.563f,20.1971f,160.156f, +105.469f,22.0419f,160.156f, +109.375f,23.4698f,160.156f, +113.281f,24.6461f,160.156f, +117.188f,26.2207f,160.156f, +121.094f,28.1249f,160.156f, +125.0f,29.8102f,160.156f, +128.906f,31.7349f,160.156f, +132.813f,32.4376f,160.156f, +136.719f,33.2795f,160.156f, +140.625f,37.4588f,160.156f, +144.531f,38.8195f,160.156f, +148.438f,39.9622f,160.156f, +152.344f,41.6752f,160.156f, +156.25f,37.6576f,160.156f, +160.156f,41.4722f,160.156f, +164.063f,41.8372f,160.156f, +167.969f,40.7289f,160.156f, +171.875f,35.5243f,160.156f, +175.781f,34.1726f,160.156f, +179.688f,33.9628f,160.156f, +183.594f,33.3012f,160.156f, +187.5f,37.6064f,160.156f, +191.406f,36.2987f,160.156f, +195.313f,32.9836f,160.156f, +199.219f,34.2771f,160.156f, +203.125f,33.5607f,160.156f, +207.031f,26.9351f,160.156f, +210.938f,24.3584f,160.156f, +214.844f,25.5428f,160.156f, +218.75f,26.0054f,160.156f, +222.656f,24.092f,160.156f, +226.563f,22.8948f,160.156f, +230.469f,17.1899f,160.156f, +234.375f,15.0552f,160.156f, +238.281f,14.2468f,160.156f, +242.188f,13.7862f,160.156f, +246.094f,14.5132f,160.156f, +250.0f,14.3684f,160.156f, +3.90627f,16.9346f,156.25f, +7.81251f,18.2437f,156.25f, +11.7188f,18.3869f,156.25f, +15.625f,18.1055f,156.25f, +19.5313f,18.7445f,156.25f, +23.4375f,18.9235f,156.25f, +27.3438f,18.455f,156.25f, +31.25f,18.6644f,156.25f, +35.1563f,18.9448f,156.25f, +39.0625f,18.9971f,156.25f, +42.9688f,18.8628f,156.25f, +46.875f,18.6886f,156.25f, +50.7813f,18.8494f,156.25f, +54.6875f,19.4408f,156.25f, +58.5938f,18.7384f,156.25f, +62.5f,17.473f,156.25f, +66.4063f,18.5906f,156.25f, +70.3125f,18.7252f,156.25f, +74.2188f,19.5013f,156.25f, +78.125f,19.8221f,156.25f, +82.0313f,19.8648f,156.25f, +85.9375f,19.8955f,156.25f, +89.8438f,19.4401f,156.25f, +93.75f,18.7973f,156.25f, +97.6563f,18.8923f,156.25f, +101.563f,20.6151f,156.25f, +105.469f,22.9824f,156.25f, +109.375f,25.2251f,156.25f, +113.281f,26.7829f,156.25f, +117.188f,27.8131f,156.25f, +121.094f,29.6707f,156.25f, +125.0f,31.4614f,156.25f, +128.906f,32.8387f,156.25f, +132.813f,33.7834f,156.25f, +136.719f,34.3986f,156.25f, +140.625f,35.1609f,156.25f, +144.531f,40.0963f,156.25f, +148.438f,41.0412f,156.25f, +152.344f,42.0325f,156.25f, +156.25f,42.1696f,156.25f, +160.156f,41.9265f,156.25f, +164.063f,43.279f,156.25f, +167.969f,42.5995f,156.25f, +171.875f,36.6937f,156.25f, +175.781f,34.8393f,156.25f, +179.688f,34.7157f,156.25f, +183.594f,34.0579f,156.25f, +187.5f,33.7647f,156.25f, +191.406f,33.2242f,156.25f, +195.313f,32.1053f,156.25f, +199.219f,30.6563f,156.25f, +203.125f,33.623f,156.25f, +207.031f,28.0199f,156.25f, +210.938f,30.5092f,156.25f, +214.844f,29.3828f,156.25f, +218.75f,27.3486f,156.25f, +222.656f,25.8671f,156.25f, +226.563f,24.1209f,156.25f, +230.469f,17.9979f,156.25f, +234.375f,16.1304f,156.25f, +238.281f,14.8281f,156.25f, +242.188f,13.097f,156.25f, +246.094f,13.3642f,156.25f, +250.0f,13.6085f,156.25f, +3.90627f,17.6952f,152.344f, +7.81251f,19.1063f,152.344f, +11.7188f,19.6398f,152.344f, +15.625f,19.8626f,152.344f, +19.5313f,19.1453f,152.344f, +23.4375f,19.4932f,152.344f, +27.3438f,19.3908f,152.344f, +31.25f,18.6492f,152.344f, +35.1563f,18.3861f,152.344f, +39.0625f,18.198f,152.344f, +42.9688f,18.4497f,152.344f, +46.875f,17.8083f,152.344f, +50.7813f,18.5296f,152.344f, +54.6875f,19.8096f,152.344f, +58.5938f,19.3324f,152.344f, +62.5f,18.1507f,152.344f, +66.4063f,17.7998f,152.344f, +70.3125f,17.9266f,152.344f, +74.2188f,18.569f,152.344f, +78.125f,19.5043f,152.344f, +82.0313f,20.0768f,152.344f, +85.9375f,19.5187f,152.344f, +89.8438f,20.2592f,152.344f, +93.75f,19.2159f,152.344f, +97.6563f,20.1174f,152.344f, +101.563f,21.9257f,152.344f, +105.469f,23.9219f,152.344f, +109.375f,25.8476f,152.344f, +113.281f,27.9183f,152.344f, +117.188f,29.2798f,152.344f, +121.094f,30.2289f,152.344f, +125.0f,31.7495f,152.344f, +128.906f,33.1684f,152.344f, +132.813f,34.4626f,152.344f, +136.719f,35.9981f,152.344f, +140.625f,36.5168f,152.344f, +144.531f,35.9325f,152.344f, +148.438f,41.231f,152.344f, +152.344f,42.7257f,152.344f, +156.25f,43.5162f,152.344f, +160.156f,44.357f,152.344f, +164.063f,44.2347f,152.344f, +167.969f,40.2679f,152.344f, +171.875f,36.2109f,152.344f, +175.781f,36.3906f,152.344f, +179.688f,35.227f,152.344f, +183.594f,34.7006f,152.344f, +187.5f,34.7763f,152.344f, +191.406f,34.0912f,152.344f, +195.313f,32.201f,152.344f, +199.219f,30.6601f,152.344f, +203.125f,28.7526f,152.344f, +207.031f,33.0587f,152.344f, +210.938f,31.7955f,152.344f, +214.844f,29.893f,152.344f, +218.75f,27.5989f,152.344f, +222.656f,26.1347f,152.344f, +226.563f,19.6378f,152.344f, +230.469f,18.6596f,152.344f, +234.375f,17.3965f,152.344f, +238.281f,15.5807f,152.344f, +242.188f,13.4071f,152.344f, +246.094f,12.7989f,152.344f, +250.0f,12.5897f,152.344f, +3.90626f,18.4109f,148.438f, +7.81251f,18.8163f,148.438f, +11.7188f,20.7396f,148.438f, +15.625f,21.7833f,148.438f, +19.5313f,20.6586f,148.438f, +23.4375f,19.8597f,148.438f, +27.3438f,20.0951f,148.438f, +31.25f,18.7811f,148.438f, +35.1563f,18.123f,148.438f, +39.0625f,17.773f,148.438f, +42.9688f,18.0095f,148.438f, +46.875f,17.694f,148.438f, +50.7813f,17.1666f,148.438f, +54.6875f,18.3484f,148.438f, +58.5938f,18.5612f,148.438f, +62.5f,18.1324f,148.438f, +66.4063f,17.4119f,148.438f, +70.3125f,17.2873f,148.438f, +74.2188f,17.6855f,148.438f, +78.125f,18.6618f,148.438f, +82.0313f,19.6447f,148.438f, +85.9375f,19.4743f,148.438f, +89.8438f,20.2887f,148.438f, +93.75f,20.2469f,148.438f, +97.6563f,21.1802f,148.438f, +101.563f,23.2002f,148.438f, +105.469f,24.8874f,148.438f, +109.375f,26.5433f,148.438f, +113.281f,28.653f,148.438f, +117.188f,30.2347f,148.438f, +121.094f,31.6949f,148.438f, +125.0f,33.2452f,148.438f, +128.906f,34.3964f,148.438f, +132.813f,35.2835f,148.438f, +136.719f,36.7099f,148.438f, +140.625f,37.1893f,148.438f, +144.531f,36.5212f,148.438f, +148.438f,36.7413f,148.438f, +152.344f,43.9965f,148.438f, +156.25f,44.9543f,148.438f, +160.156f,44.8078f,148.438f, +164.063f,45.09f,148.438f, +167.969f,43.0871f,148.438f, +171.875f,42.2067f,148.438f, +175.781f,40.5399f,148.438f, +179.688f,35.9902f,148.438f, +183.594f,34.4093f,148.438f, +187.5f,35.1087f,148.438f, +191.406f,34.3372f,148.438f, +195.313f,35.6724f,148.438f, +199.219f,34.961f,148.438f, +203.125f,34.4106f,148.438f, +207.031f,32.0028f,148.438f, +210.938f,31.3925f,148.438f, +214.844f,29.3539f,148.438f, +218.75f,27.6213f,148.438f, +222.656f,21.6694f,148.438f, +226.563f,20.356f,148.438f, +230.469f,19.6202f,148.438f, +234.375f,17.6247f,148.438f, +238.281f,16.5152f,148.438f, +242.188f,14.901f,148.438f, +246.094f,12.7994f,148.438f, +250.0f,12.2743f,148.438f, +3.90626f,17.8758f,144.531f, +7.81251f,19.3177f,144.531f, +11.7188f,20.9214f,144.531f, +15.625f,21.8589f,144.531f, +19.5313f,21.2904f,144.531f, +23.4375f,19.9784f,144.531f, +27.3438f,19.6359f,144.531f, +31.25f,19.4398f,144.531f, +35.1563f,18.6596f,144.531f, +39.0625f,17.1967f,144.531f, +42.9688f,16.797f,144.531f, +46.875f,16.4099f,144.531f, +50.7813f,16.54f,144.531f, +54.6875f,16.811f,144.531f, +58.5938f,17.31f,144.531f, +62.5f,17.5358f,144.531f, +66.4063f,16.8495f,144.531f, +70.3125f,17.2148f,144.531f, +74.2188f,16.6285f,144.531f, +78.125f,17.7911f,144.531f, +82.0313f,18.6054f,144.531f, +85.9375f,18.787f,144.531f, +89.8438f,20.4804f,144.531f, +93.75f,21.0544f,144.531f, +97.6563f,20.9487f,144.531f, +101.563f,23.1098f,144.531f, +105.469f,25.2196f,144.531f, +109.375f,27.0389f,144.531f, +113.281f,29.4971f,144.531f, +117.188f,31.0049f,144.531f, +121.094f,33.086f,144.531f, +125.0f,34.6611f,144.531f, +128.906f,35.8626f,144.531f, +132.813f,36.8672f,144.531f, +136.719f,37.5515f,144.531f, +140.625f,37.6433f,144.531f, +144.531f,37.8923f,144.531f, +148.438f,37.1277f,144.531f, +152.344f,40.0287f,144.531f, +156.25f,44.9863f,144.531f, +160.156f,45.0845f,144.531f, +164.063f,44.7823f,144.531f, +167.969f,42.5338f,144.531f, +171.875f,41.7912f,144.531f, +175.781f,41.5762f,144.531f, +179.688f,41.3242f,144.531f, +183.594f,39.6796f,144.531f, +187.5f,39.4704f,144.531f, +191.406f,38.5401f,144.531f, +195.313f,37.3853f,144.531f, +199.219f,35.4345f,144.531f, +203.125f,34.2437f,144.531f, +207.031f,31.8218f,144.531f, +210.938f,30.6041f,144.531f, +214.844f,26.9001f,144.531f, +218.75f,22.3094f,144.531f, +222.656f,21.4446f,144.531f, +226.563f,20.6643f,144.531f, +230.469f,20.3246f,144.531f, +234.375f,18.0382f,144.531f, +238.281f,15.7854f,144.531f, +242.188f,14.3314f,144.531f, +246.094f,12.4723f,144.531f, +250.0f,12.5491f,144.531f, +3.90626f,18.5798f,140.625f, +7.81251f,19.7271f,140.625f, +11.7188f,20.8566f,140.625f, +15.625f,21.6914f,140.625f, +19.5313f,20.9288f,140.625f, +23.4375f,20.0531f,140.625f, +27.3438f,19.1655f,140.625f, +31.25f,18.7947f,140.625f, +35.1563f,18.2984f,140.625f, +39.0625f,17.3295f,140.625f, +42.9688f,16.5557f,140.625f, +46.875f,16.1679f,140.625f, +50.7813f,16.0262f,140.625f, +54.6875f,16.1659f,140.625f, +58.5938f,16.459f,140.625f, +62.5f,17.0307f,140.625f, +66.4063f,17.6303f,140.625f, +70.3125f,16.7576f,140.625f, +74.2188f,16.9614f,140.625f, +78.125f,17.3439f,140.625f, +82.0313f,17.7742f,140.625f, +85.9375f,19.0774f,140.625f, +89.8438f,20.0724f,140.625f, +93.75f,21.5734f,140.625f, +97.6563f,21.4923f,140.625f, +101.563f,24.2474f,140.625f, +105.469f,25.9666f,140.625f, +109.375f,27.8803f,140.625f, +113.281f,29.6397f,140.625f, +117.188f,32.0374f,140.625f, +121.094f,34.014f,140.625f, +125.0f,35.1589f,140.625f, +128.906f,36.2526f,140.625f, +132.813f,37.5386f,140.625f, +136.719f,38.1647f,140.625f, +140.625f,37.9014f,140.625f, +144.531f,39.0558f,140.625f, +148.438f,38.1493f,140.625f, +152.344f,39.5967f,140.625f, +156.25f,40.3409f,140.625f, +160.156f,39.4778f,140.625f, +164.063f,43.7911f,140.625f, +167.969f,42.7467f,140.625f, +171.875f,41.4394f,140.625f, +175.781f,41.222f,140.625f, +179.688f,40.9501f,140.625f, +183.594f,40.2741f,140.625f, +187.5f,40.5011f,140.625f, +191.406f,39.8634f,140.625f, +195.313f,37.8944f,140.625f, +199.219f,35.6917f,140.625f, +203.125f,33.0921f,140.625f, +207.031f,30.7497f,140.625f, +210.938f,24.355f,140.625f, +214.844f,23.6102f,140.625f, +218.75f,23.2298f,140.625f, +222.656f,21.8035f,140.625f, +226.563f,21.0813f,140.625f, +230.469f,20.4423f,140.625f, +234.375f,19.372f,140.625f, +238.281f,16.9074f,140.625f, +242.188f,15.6931f,140.625f, +246.094f,14.0046f,140.625f, +250.0f,12.7719f,140.625f, +3.90626f,19.7224f,136.719f, +7.81251f,20.3645f,136.719f, +11.7188f,20.1938f,136.719f, +15.625f,20.0122f,136.719f, +19.5313f,20.9204f,136.719f, +23.4375f,20.2208f,136.719f, +27.3438f,19.3419f,136.719f, +31.25f,18.2059f,136.719f, +35.1563f,17.6089f,136.719f, +39.0625f,17.131f,136.719f, +42.9688f,16.8349f,136.719f, +46.875f,16.3462f,136.719f, +50.7813f,15.4488f,136.719f, +54.6875f,15.7887f,136.719f, +58.5938f,16.431f,136.719f, +62.5f,16.3378f,136.719f, +66.4063f,17.4585f,136.719f, +70.3125f,17.5113f,136.719f, +74.2188f,17.6407f,136.719f, +78.125f,17.0887f,136.719f, +82.0313f,17.2555f,136.719f, +85.9375f,18.6283f,136.719f, +89.8438f,19.6874f,136.719f, +93.75f,21.0963f,136.719f, +97.6563f,21.5582f,136.719f, +101.563f,24.9129f,136.719f, +105.469f,27.5761f,136.719f, +109.375f,28.7426f,136.719f, +113.281f,31.0958f,136.719f, +117.188f,33.7564f,136.719f, +121.094f,34.6927f,136.719f, +125.0f,35.0503f,136.719f, +128.906f,36.0657f,136.719f, +132.813f,37.2001f,136.719f, +136.719f,38.5625f,136.719f, +140.625f,38.8809f,136.719f, +144.531f,39.3646f,136.719f, +148.438f,38.919f,136.719f, +152.344f,39.5251f,136.719f, +156.25f,39.5392f,136.719f, +160.156f,39.7011f,136.719f, +164.063f,38.4043f,136.719f, +167.969f,37.7232f,136.719f, +171.875f,37.8418f,136.719f, +175.781f,41.0576f,136.719f, +179.688f,40.6804f,136.719f, +183.594f,40.6431f,136.719f, +187.5f,41.2286f,136.719f, +191.406f,40.221f,136.719f, +195.313f,37.9197f,136.719f, +199.219f,30.9591f,136.719f, +203.125f,28.2027f,136.719f, +207.031f,25.2338f,136.719f, +210.938f,24.1525f,136.719f, +214.844f,23.6344f,136.719f, +218.75f,22.6246f,136.719f, +222.656f,21.3675f,136.719f, +226.563f,21.0207f,136.719f, +230.469f,20.2558f,136.719f, +234.375f,18.3661f,136.719f, +238.281f,16.7584f,136.719f, +242.188f,16.2723f,136.719f, +246.094f,14.7268f,136.719f, +250.0f,13.5973f,136.719f, +3.90626f,19.9574f,132.813f, +7.8125f,21.126f,132.813f, +11.7188f,20.9977f,132.813f, +15.625f,21.2478f,132.813f, +19.5313f,21.5981f,132.813f, +23.4375f,20.0536f,132.813f, +27.3438f,18.6025f,132.813f, +31.25f,18.166f,132.813f, +35.1563f,17.207f,132.813f, +39.0625f,17.3703f,132.813f, +42.9688f,16.3317f,132.813f, +46.875f,15.4769f,132.813f, +50.7813f,14.7771f,132.813f, +54.6875f,14.8038f,132.813f, +58.5938f,15.7291f,132.813f, +62.5f,16.2292f,132.813f, +66.4063f,17.1488f,132.813f, +70.3125f,17.5027f,132.813f, +74.2188f,16.9736f,132.813f, +78.125f,16.4014f,132.813f, +82.0313f,16.7581f,132.813f, +85.9375f,18.1894f,132.813f, +89.8438f,20.0178f,132.813f, +93.75f,20.5813f,132.813f, +97.6563f,22.5893f,132.813f, +101.563f,25.6741f,132.813f, +105.469f,28.0908f,132.813f, +109.375f,29.1124f,132.813f, +113.281f,31.4752f,132.813f, +117.188f,33.2328f,132.813f, +121.094f,34.3747f,132.813f, +125.0f,34.8849f,132.813f, +128.906f,36.3771f,132.813f, +132.813f,37.3154f,132.813f, +136.719f,38.6196f,132.813f, +140.625f,39.1474f,132.813f, +144.531f,39.5395f,132.813f, +148.438f,38.9241f,132.813f, +152.344f,39.6801f,132.813f, +156.25f,39.7675f,132.813f, +160.156f,39.4464f,132.813f, +164.063f,38.2967f,132.813f, +167.969f,37.3679f,132.813f, +171.875f,36.5147f,132.813f, +175.781f,35.9217f,132.813f, +179.688f,35.6874f,132.813f, +183.594f,36.0348f,132.813f, +187.5f,36.167f,132.813f, +191.406f,34.7462f,132.813f, +195.313f,32.5911f,132.813f, +199.219f,30.8509f,132.813f, +203.125f,27.889f,132.813f, +207.031f,25.0869f,132.813f, +210.938f,23.713f,132.813f, +214.844f,23.4714f,132.813f, +218.75f,22.2633f,132.813f, +222.656f,21.1409f,132.813f, +226.563f,20.2725f,132.813f, +230.469f,19.4678f,132.813f, +234.375f,18.4511f,132.813f, +238.281f,18.0306f,132.813f, +242.188f,17.5677f,132.813f, +246.094f,16.403f,132.813f, +250.0f,14.7316f,132.813f, +3.90626f,20.0876f,128.906f, +7.81252f,21.0764f,128.906f, +11.7188f,21.4076f,128.906f, +15.625f,22.6299f,128.906f, +19.5313f,22.1174f,128.906f, +23.4375f,20.3977f,128.906f, +27.3438f,18.7343f,128.906f, +31.25f,17.9144f,128.906f, +35.1563f,17.2941f,128.906f, +39.0625f,16.5386f,128.906f, +42.9688f,15.6892f,128.906f, +46.875f,14.6414f,128.906f, +50.7813f,14.3505f,128.906f, +54.6875f,14.1604f,128.906f, +58.5938f,14.517f,128.906f, +62.5f,15.1057f,128.906f, +66.4063f,16.0684f,128.906f, +70.3125f,16.6251f,128.906f, +74.2188f,15.9689f,128.906f, +78.125f,16.0234f,128.906f, +82.0313f,16.205f,128.906f, +85.9375f,18.8167f,128.906f, +89.8438f,19.6433f,128.906f, +93.75f,20.2916f,128.906f, +97.6563f,23.2308f,128.906f, +101.563f,25.882f,128.906f, +105.469f,27.5736f,128.906f, +109.375f,28.9662f,128.906f, +113.281f,30.5702f,128.906f, +117.188f,31.8627f,128.906f, +121.094f,32.5216f,128.906f, +125.0f,34.1918f,128.906f, +128.906f,37.0161f,128.906f, +132.813f,38.5084f,128.906f, +136.719f,39.1631f,128.906f, +140.625f,39.0529f,128.906f, +144.531f,38.9229f,128.906f, +148.438f,38.4312f,128.906f, +152.344f,39.1086f,128.906f, +156.25f,39.7022f,128.906f, +160.156f,39.3007f,128.906f, +164.063f,38.2318f,128.906f, +167.969f,36.7493f,128.906f, +171.875f,35.9781f,128.906f, +175.781f,35.7712f,128.906f, +179.688f,35.6247f,128.906f, +183.594f,35.4808f,128.906f, +187.5f,35.6102f,128.906f, +191.406f,34.0305f,128.906f, +195.313f,32.0227f,128.906f, +199.219f,29.7666f,128.906f, +203.125f,27.3968f,128.906f, +207.031f,25.1642f,128.906f, +210.938f,24.279f,128.906f, +214.844f,22.4357f,128.906f, +218.75f,21.7754f,128.906f, +222.656f,19.6381f,128.906f, +226.563f,19.78f,128.906f, +230.469f,20.0349f,128.906f, +234.375f,19.1534f,128.906f, +238.281f,17.863f,128.906f, +242.188f,17.658f,128.906f, +246.094f,16.951f,128.906f, +250.0f,16.2961f,128.906f, +}; + +btScalar Landscape01Nml[] = { +-0.145347f,0.988603f,0.0392193f, +-0.118578f,0.971903f,-0.203332f, +-0.210348f,0.975548f,0.0637181f, +-0.143154f,0.979915f,-0.138828f, +-0.186466f,0.976661f,0.106602f, +-0.200996f,0.973874f,-0.105691f, +-0.200019f,0.979742f,-0.00987837f, +-0.162567f,0.986516f,-0.0189093f, +-0.128872f,0.991658f,-0.00262187f, +-0.0972065f,0.993702f,0.0557464f, +-0.232168f,0.972676f,8.39761e-005f, +-0.280715f,0.959127f,-0.0356947f, +-0.328537f,0.944066f,-0.0283446f, +-0.348021f,0.936189f,-0.0493126f, +-0.28502f,0.953899f,-0.0940249f, +-0.329197f,0.938125f,-0.107479f, +-0.186873f,0.969867f,-0.15632f, +-0.168074f,0.98179f,-0.088542f, +0.138723f,0.984643f,-0.105994f, +0.139713f,0.984758f,-0.103594f, +0.415149f,0.907443f,-0.0647914f, +0.335594f,0.916204f,-0.218967f, +0.391251f,0.906316f,-0.159731f, +0.297117f,0.890775f,-0.343864f, +0.0782406f,0.948307f,-0.307558f, +0.0742546f,0.932023f,-0.354711f, +-0.0593029f,0.94484f,-0.322118f, +-0.035102f,0.9388f,-0.342668f, +-0.0398386f,0.972105f,-0.231139f, +0.0142535f,0.946652f,-0.321942f, +-0.149407f,0.982239f,-0.113505f, +-0.186817f,0.918353f,-0.348895f, +-0.227035f,0.95418f,-0.194923f, +-0.217455f,0.921613f,-0.32147f, +-0.104683f,0.961425f,-0.254368f, +-0.137473f,0.92562f,-0.352602f, +-0.0889131f,0.942391f,-0.322479f, +-0.137942f,0.895959f,-0.422173f, +-0.0994313f,0.915873f,-0.38896f, +-0.177412f,0.858967f,-0.480312f, +-0.28046f,0.843765f,-0.457605f, +-0.23875f,0.832625f,-0.499733f, +-0.35769f,0.865922f,-0.349624f, +-0.239679f,0.924761f,-0.295585f, +-0.367472f,0.894137f,-0.255898f, +-0.306721f,0.940051f,-0.149083f, +-0.29191f,0.929123f,-0.226977f, +-0.3205f,0.928892f,-0.185579f, +-0.367832f,0.894452f,-0.254274f, +-0.393375f,0.898238f,-0.196023f, +-0.386104f,0.869165f,-0.308993f, +-0.416765f,0.860247f,-0.293737f, +-0.257238f,0.898443f,-0.355849f, +-0.273377f,0.911812f,-0.306372f, +-0.228654f,0.889208f,-0.396265f, +-0.28545f,0.876522f,-0.387592f, +-0.142316f,0.885962f,-0.441381f, +-0.101084f,0.908701f,-0.405025f, +0.035618f,0.945519f,-0.323614f, +0.103277f,0.941647f,-0.320368f, +-0.120589f,0.957422f,-0.262302f, +-0.186114f,0.894712f,-0.40602f, +-0.202962f,0.931974f,-0.300385f, +-0.162074f,0.943023f,-0.290584f, +-0.152017f,0.933176f,-0.325688f, +-0.202811f,0.891764f,-0.404505f, +-0.195614f,0.919053f,-0.342165f, +-0.221332f,0.883262f,-0.413352f, +-0.230949f,0.883479f,-0.407587f, +-0.202664f,0.884798f,-0.419595f, +-0.013827f,0.935183f,-0.353894f, +0.0613953f,0.949306f,-0.308299f, +0.0379666f,0.956996f,-0.287605f, +0.0239474f,0.920688f,-0.389564f, +-0.124568f,0.971246f,-0.20289f, +-0.0173673f,0.966674f,-0.255421f, +-0.280608f,0.954174f,-0.103981f, +-0.188825f,0.978003f,-0.0886339f, +-0.193278f,0.981044f,-0.0139968f, +-0.089832f,0.992161f,0.0868734f, +-0.0617809f,0.994525f,0.0842802f, +0.0316335f,0.979002f,0.20138f, +0.126601f,0.973442f,0.190743f, +0.126356f,0.954056f,0.271683f, +0.0296197f,0.996225f,0.0816031f, +-0.130879f,0.990212f,-0.0484936f, +-0.0775613f,0.996382f,0.0347567f, +-0.0318445f,0.999049f,0.0297665f, +0.174213f,0.981835f,0.0751658f, +0.230898f,0.968544f,0.0927823f, +0.477724f,0.867555f,0.138304f, +0.489512f,0.856269f,0.164868f, +0.425011f,0.903484f,0.0555235f, +0.345126f,0.937885f,0.0355011f, +0.051136f,0.997417f,-0.0504465f, +0.0111243f,0.99878f,-0.0481145f, +0.00085351f,0.998643f,-0.0520782f, +-0.0736129f,0.992491f,-0.0976874f, +0.0605446f,0.978416f,-0.197578f, +-0.1248f,0.898669f,-0.420499f, +-0.068151f,0.956411f,-0.28396f, +0.0502596f,0.934397f,-0.35267f, +0.0492358f,0.99416f,-0.096025f, +0.22311f,0.97441f,-0.0273246f, +0.104257f,0.993921f,-0.0353788f, +0.135731f,0.987345f,0.0820234f, +0.0508084f,0.996415f,-0.0676404f, +0.013783f,0.999772f,-0.0162859f, +0.0814861f,0.996154f,-0.0322044f, +0.0451487f,0.998313f,-0.0365194f, +0.035547f,0.992801f,-0.114375f, +-0.0977551f,0.955799f,-0.277294f, +0.0588118f,0.977967f,-0.200303f, +0.0956551f,0.968682f,-0.229142f, +0.255494f,0.951171f,-0.173197f, +0.287347f,0.949686f,-0.124613f, +0.300983f,0.934694f,-0.189092f, +0.326044f,0.937015f,-0.125296f, +0.170234f,0.979103f,-0.111255f, +0.217643f,0.971688f,-0.0919459f, +0.0857423f,0.995f,-0.0512173f, +0.141055f,0.988855f,0.0476293f, +0.141065f,0.98942f,-0.0338874f, +0.161562f,0.986303f,0.0332183f, +0.113059f,0.993231f,0.0266602f, +0.073071f,0.997081f,-0.0221543f, +-0.0590251f,0.997651f,-0.034775f, +-0.0264959f,0.999595f,0.0103962f, +-0.0628475f,0.932757f,0.354985f, +-0.188464f,0.930547f,0.31395f, +-0.11595f,0.95582f,0.270118f, +-0.0150745f,0.981122f,0.192801f, +-0.121292f,0.98854f,0.0898753f, +-0.191875f,0.979293f,0.0645635f, +-0.302211f,0.947932f,-0.100469f, +-0.168835f,0.972187f,-0.162321f, +-0.165107f,0.942083f,-0.291925f, +0.0524842f,0.966783f,-0.250151f, +0.334898f,0.925425f,-0.177288f, +0.453352f,0.888614f,-0.0695481f, +0.212879f,0.976177f,-0.0419751f, +-0.0859137f,0.991174f,-0.100958f, +-0.19247f,0.980365f,-0.0428897f, +-0.217979f,0.975456f,0.0311624f, +-0.130678f,0.991292f,-0.0162531f, +0.0105625f,0.994964f,-0.0996785f, +-0.0191557f,0.967247f,-0.253114f, +-0.034833f,0.962122f,-0.270385f, +-0.195874f,0.937997f,-0.285996f, +-0.397161f,0.831379f,-0.388681f, +-0.379064f,0.825916f,-0.417342f, +-0.284483f,0.874083f,-0.393762f, +-0.320157f,0.86551f,-0.385217f, +-0.327447f,0.85814f,-0.395442f, +-0.219114f,0.871062f,-0.439592f, +-0.161876f,0.861769f,-0.480781f, +-0.18946f,0.845726f,-0.498852f, +-0.191307f,0.924603f,-0.32941f, +-0.159365f,0.982225f,-0.0991764f, +-0.164558f,0.975832f,-0.143777f, +-0.155521f,0.974006f,-0.164699f, +-0.172244f,0.972979f,-0.153766f, +-0.162541f,0.961346f,-0.222247f, +-0.11171f,0.955927f,-0.271523f, +-0.101714f,0.980079f,-0.170586f, +-0.223397f,0.974336f,-0.0276274f, +-0.300622f,0.953413f,0.0251167f, +-0.254202f,0.967133f,-0.00586307f, +-0.0994566f,0.994394f,0.0359007f, +0.078652f,0.996758f,-0.0169243f, +-0.0552979f,0.987555f,0.147234f, +-0.0666628f,0.864508f,0.498179f, +0.131082f,0.854494f,0.502651f, +0.414695f,0.764646f,0.4933f, +0.432926f,0.790826f,0.432632f, +0.126593f,0.91514f,0.382744f, +-0.0157552f,0.943082f,0.332186f, +0.122694f,0.924647f,0.36052f, +0.0975822f,0.984244f,0.147447f, +-0.026294f,0.960938f,-0.275512f, +0.1231f,0.958251f,-0.258072f, +0.037902f,0.976085f,-0.214059f, +-0.000148888f,0.992562f,-0.121742f, +0.0716429f,0.997173f,-0.0226693f, +0.135484f,0.989193f,-0.0560393f, +0.275603f,0.956281f,-0.0978236f, +0.283097f,0.956822f,-0.0659346f, +0.109624f,0.991403f,-0.0714361f, +0.084436f,0.990816f,-0.105609f, +0.0791881f,0.990931f,-0.108558f, +0.0674956f,0.997569f,-0.0173508f, +0.0556006f,0.998429f,0.00688119f, +-0.144974f,0.947519f,0.28494f, +-0.110826f,0.961365f,0.251981f, +-0.0669451f,0.996693f,0.0460586f, +-0.00516145f,0.998802f,0.0486696f, +-0.116537f,0.988089f,0.100498f, +-0.0456605f,0.993379f,0.105422f, +-0.110131f,0.987256f,-0.114879f, +-0.0746162f,0.968429f,-0.237861f, +-0.0785155f,0.952358f,-0.294703f, +-0.0192369f,0.946876f,-0.321024f, +0.320056f,0.920022f,-0.226108f, +0.288692f,0.932613f,-0.216541f, +0.123147f,0.991593f,-0.0397145f, +-0.113817f,0.992375f,0.0473138f, +-0.192042f,0.9774f,0.0883642f, +-0.156949f,0.987573f,0.00819321f, +-0.0848586f,0.992344f,-0.0897344f, +0.0818673f,0.992357f,-0.0923282f, +0.113464f,0.986976f,-0.114035f, +-0.0777263f,0.979155f,-0.187653f, +-0.11587f,0.975173f,-0.188711f, +-0.26618f,0.902421f,-0.338799f, +-0.343104f,0.842974f,-0.414336f, +-0.318919f,0.837107f,-0.444457f, +-0.324821f,0.839352f,-0.435867f, +-0.312979f,0.836318f,-0.45013f, +-0.203015f,0.862499f,-0.463553f, +-0.14187f,0.900483f,-0.411101f, +-0.22968f,0.933243f,-0.276233f, +-0.413973f,0.871187f,-0.263932f, +-0.305656f,0.93798f,-0.163607f, +-0.161875f,0.985861f,-0.0433003f, +-0.135788f,0.990721f,0.00582442f, +-0.138617f,0.984876f,-0.103942f, +-0.135024f,0.980056f,-0.145806f, +-0.124871f,0.989793f,-0.068687f, +-0.182018f,0.982992f,-0.024403f, +-0.309743f,0.950592f,-0.0208625f, +-0.30492f,0.95221f,0.0178823f, +-0.299424f,0.951826f,0.066125f, +-0.120448f,0.944431f,0.305848f, +0.118213f,0.907792f,0.402418f, +-0.261318f,0.917154f,0.300902f, +-0.411401f,0.860866f,0.299431f, +0.15139f,0.91772f,0.367249f, +0.409879f,0.832051f,0.373752f, +0.446772f,0.77668f,0.44403f, +0.301572f,0.80653f,0.508491f, +0.168293f,0.89172f,0.420135f, +0.0587854f,0.961406f,0.26878f, +0.30067f,0.896979f,0.324077f, +0.282217f,0.935284f,0.213535f, +0.148185f,0.986837f,0.0647602f, +-0.0572401f,0.974528f,-0.216838f, +-0.0945497f,0.96665f,-0.238009f, +-0.000668496f,0.9725f,-0.232902f, +0.125989f,0.980136f,-0.15317f, +0.218059f,0.975888f,-0.00959987f, +0.265461f,0.958501f,0.103951f, +0.173443f,0.98019f,0.0956349f, +0.133691f,0.987754f,0.0804258f, +0.0900836f,0.995272f,0.0363034f, +0.0177237f,0.999106f,-0.0383914f, +0.042211f,0.998744f,-0.0269875f, +0.0720539f,0.94434f,0.320982f, +0.0948772f,0.964987f,0.244537f, +0.123635f,0.987961f,0.0929884f, +-0.0283728f,0.998997f,-0.0346279f, +-0.152337f,0.985597f,-0.0734363f, +-0.0291778f,0.996634f,-0.0766092f, +0.0594392f,0.995285f,-0.0766423f, +-0.027888f,0.982723f,-0.182971f, +-0.0125244f,0.971758f,-0.235647f, +-0.0767296f,0.943557f,-0.322201f, +0.2299f,0.955601f,-0.184318f, +0.271645f,0.9586f,-0.0854157f, +0.0112173f,0.999015f,-0.0429278f, +-0.142475f,0.989464f,-0.02574f, +-0.192441f,0.979224f,-0.0639254f, +-0.103523f,0.99301f,-0.0567016f, +-0.00378459f,0.998834f,-0.0481324f, +0.0499927f,0.992415f,-0.112309f, +0.0737699f,0.994576f,-0.0733206f, +-0.0190206f,0.999623f,-0.0197948f, +-0.0783652f,0.99692f,0.00307073f, +-0.152226f,0.987897f,0.0297819f, +-0.333638f,0.940154f,-0.069252f, +-0.307736f,0.941909f,-0.134557f, +-0.334924f,0.918699f,-0.209327f, +-0.35357f,0.914459f,-0.19686f, +-0.243406f,0.963329f,-0.112917f, +-0.31479f,0.943784f,-0.100892f, +-0.368184f,0.929745f,0.00391099f, +-0.386308f,0.922293f,-0.0119138f, +-0.337617f,0.936762f,-0.0921568f, +-0.305867f,0.947033f,-0.0978487f, +-0.109063f,0.994026f,0.00418869f, +0.00976093f,0.996792f,-0.0794369f, +-0.152053f,0.972765f,-0.17495f, +-0.268682f,0.956747f,-0.111559f, +-0.16583f,0.986099f,0.0104333f, +-0.26795f,0.960138f,-0.0796053f, +-0.428361f,0.903607f,0.000904858f, +-0.364896f,0.884093f,0.291943f, +-0.411739f,0.889329f,0.19891f, +-0.213918f,0.942658f,0.256194f, +-0.0353818f,0.912316f,0.407955f, +-0.234679f,0.972031f,0.0090071f, +0.164799f,0.976041f,-0.142074f, +0.378329f,0.920537f,-0.0973577f, +0.389048f,0.913009f,0.122701f, +0.312785f,0.918579f,0.241617f, +0.331426f,0.913352f,0.236529f, +0.235473f,0.970893f,0.043811f, +0.0409183f,0.988429f,-0.14606f, +0.183882f,0.951979f,0.244794f, +0.256685f,0.844334f,0.470333f, +0.243297f,0.84406f,0.47788f, +0.178194f,0.957255f,0.227835f, +0.0574376f,0.965885f,-0.252523f, +-0.0590426f,0.961892f,-0.266977f, +0.0063288f,0.996614f,-0.081983f, +0.221194f,0.97242f,0.0739783f, +0.131016f,0.988415f,0.0766141f, +0.0953963f,0.986256f,0.134901f, +0.160579f,0.972927f,0.166216f, +0.109946f,0.983906f,0.14086f, +0.027673f,0.996741f,0.0757784f, +0.095102f,0.971229f,0.218334f, +0.102357f,0.973251f,0.205684f, +0.193741f,0.956416f,0.218477f, +0.132416f,0.984788f,0.112512f, +-0.0766537f,0.99488f,-0.0658589f, +-0.0304197f,0.995587f,-0.0887742f, +0.0261631f,0.997431f,-0.0666789f, +0.0720508f,0.996334f,-0.0461268f, +0.110802f,0.979106f,-0.170512f, +-0.036534f,0.946972f,-0.319234f, +0.0562543f,0.953438f,-0.296297f, +0.21433f,0.964539f,-0.154036f, +-0.0463138f,0.986383f,-0.157808f, +-0.114222f,0.99275f,-0.0374399f, +-0.129535f,0.99146f,-0.0150624f, +-0.148036f,0.985214f,-0.0862475f, +-0.0412316f,0.997863f,-0.050697f, +0.0938182f,0.995513f,-0.0123356f, +0.0585542f,0.997889f,-0.0281043f, +-0.11195f,0.993633f,0.0126653f, +-0.208443f,0.969116f,0.131782f, +-0.178284f,0.959747f,0.217024f, +-0.249524f,0.951637f,0.179236f, +-0.204568f,0.966799f,0.153139f, +-0.277831f,0.959694f,0.042405f, +-0.421523f,0.906804f,-0.00501147f, +-0.349246f,0.93481f,0.0644755f, +-0.271825f,0.953501f,0.130185f, +-0.341243f,0.939899f,0.0119564f, +-0.356048f,0.93224f,-0.0644791f, +-0.286188f,0.955628f,-0.0697892f, +-0.248084f,0.956522f,-0.153364f, +-0.154022f,0.960443f,-0.232007f, +0.032406f,0.989794f,-0.138774f, +-0.0622078f,0.991529f,-0.114016f, +-0.335467f,0.915845f,-0.220659f, +-0.194821f,0.973732f,-0.117857f, +-0.29903f,0.953799f,-0.0291431f, +-0.514277f,0.834668f,0.197101f, +-0.344769f,0.927072f,0.147212f, +-0.0936834f,0.993837f,0.0592615f, +-0.181141f,0.974379f,-0.133321f, +-0.0841805f,0.983933f,-0.157447f, +0.0661375f,0.94785f,-0.31178f, +0.143104f,0.856028f,-0.496726f, +0.226417f,0.827547f,-0.513714f, +0.178899f,0.912784f,-0.367179f, +0.234616f,0.943911f,-0.232351f, +0.346693f,0.91935f,-0.186008f, +0.307074f,0.943627f,-0.123586f, +0.214863f,0.970065f,0.113171f, +0.0234555f,0.999712f,0.00506759f, +-0.0206358f,0.99868f,0.047041f, +0.0320247f,0.946177f,0.322062f, +0.23638f,0.837444f,0.492759f, +0.410368f,0.848265f,0.33473f, +-0.0124285f,0.999913f,-0.00451951f, +-0.13197f,0.981357f,-0.139724f, +0.0888915f,0.995883f,0.0177605f, +0.12955f,0.973581f,0.188033f, +0.100974f,0.97841f,0.18033f, +0.116628f,0.987352f,0.107396f, +0.0879041f,0.989191f,0.117361f, +0.114472f,0.980893f,0.157306f, +0.0306685f,0.986407f,0.161431f, +0.128704f,0.972047f,0.196366f, +0.21783f,0.966546f,0.135421f, +0.280184f,0.953049f,0.114866f, +0.0272615f,0.999564f,-0.0113551f, +-0.0491486f,0.997279f,-0.0549472f, +0.00337261f,0.998977f,-0.0450999f, +0.0913253f,0.995457f,-0.0269266f, +0.252481f,0.964775f,-0.0739122f, +0.0897947f,0.975122f,-0.202665f, +-0.0238258f,0.968534f,-0.247739f, +0.162662f,0.981573f,-0.10028f, +-0.0276113f,0.997652f,-0.0626774f, +-0.289082f,0.95335f,-0.0869268f, +-0.160594f,0.986876f,0.0169191f, +-0.0752137f,0.997117f,0.00999502f, +-0.0455931f,0.997939f,-0.0451647f, +0.0616976f,0.995202f,-0.0759372f, +-0.00353073f,0.999867f,-0.0159004f, +-0.177748f,0.976224f,0.124065f, +-0.247702f,0.959217f,0.136188f, +-0.164797f,0.981869f,0.0936766f, +-0.214718f,0.976098f,0.0335935f, +-0.211552f,0.977318f,-0.00980662f, +-0.200169f,0.979677f,0.0128577f, +-0.39928f,0.916411f,-0.027687f, +-0.374531f,0.927212f,0.0022105f, +-0.268102f,0.963363f,0.00736207f, +-0.247283f,0.968232f,-0.0371081f, +-0.289483f,0.949449f,-0.121432f, +-0.253482f,0.93971f,-0.229547f, +-0.132892f,0.950758f,-0.279997f, +-0.140676f,0.931036f,-0.336723f, +-0.161496f,0.9509f,-0.264023f, +-0.0403886f,0.9973f,-0.0613364f, +-0.215095f,0.96767f,-0.131717f, +-0.434628f,0.895597f,-0.0948964f, +-0.381939f,0.886142f,0.262442f, +-0.43994f,0.880276f,0.177672f, +-0.252792f,0.948954f,-0.188633f, +-0.0941535f,0.957693f,-0.271953f, +-0.13352f,0.964535f,-0.227692f, +0.0341173f,0.927935f,-0.371176f, +0.348577f,0.799586f,-0.489036f, +0.387188f,0.819484f,-0.42253f, +0.14352f,0.883544f,-0.445815f, +0.0762879f,0.891752f,-0.446047f, +0.0742711f,0.875908f,-0.476728f, +0.300515f,0.871535f,-0.38745f, +0.0625809f,0.886656f,-0.458175f, +-0.0365474f,0.9191f,-0.392325f, +-0.0762363f,0.966891f,-0.243538f, +0.0117284f,0.995382f,0.0952715f, +0.0102532f,0.999347f,-0.0346391f, +-0.059511f,0.989492f,-0.131776f, +0.349383f,0.904972f,0.24281f, +0.425179f,0.763732f,0.485732f, +-0.0166138f,0.992406f,0.121875f, +-0.122272f,0.990094f,0.0690156f, +-0.015652f,0.970579f,0.240273f, +0.124649f,0.94771f,0.293785f, +0.220282f,0.938434f,0.266116f, +0.102745f,0.973801f,0.202865f, +0.0640356f,0.977435f,0.201297f, +-0.0952943f,0.987515f,0.125435f, +0.114947f,0.977151f,0.178783f, +0.258472f,0.957495f,0.128042f, +0.282157f,0.951094f,0.125728f, +0.142066f,0.986542f,0.0809464f, +-0.0434313f,0.998053f,-0.0447576f, +0.0347776f,0.999239f,-0.0176595f, +0.102204f,0.984881f,-0.139871f, +0.245582f,0.958619f,-0.144014f, +0.135608f,0.990697f,0.0113886f, +-0.0626335f,0.997441f,0.0344788f, +-0.0132478f,0.995736f,0.0912912f, +-0.039638f,0.981575f,0.186922f, +-0.205229f,0.973473f,0.10115f, +-0.153245f,0.987696f,-0.0311751f, +-0.0852914f,0.993336f,-0.0775215f, +0.0304281f,0.997751f,-0.0597208f, +0.0412582f,0.993049f,-0.110237f, +-0.115798f,0.992196f,0.0462328f, +-0.265664f,0.954942f,0.132323f, +-0.179634f,0.978355f,0.102729f, +-0.122093f,0.992469f,0.00988423f, +-0.0976525f,0.994936f,-0.0237989f, +-0.19391f,0.963376f,-0.185219f, +-0.249328f,0.960076f,-0.126845f, +-0.386054f,0.920896f,-0.0539736f, +-0.40236f,0.909842f,-0.101455f, +-0.264839f,0.959901f,-0.091928f, +-0.215529f,0.973573f,-0.0755211f, +-0.190591f,0.977631f,-0.0889496f, +-0.114636f,0.971653f,-0.20676f, +-0.147698f,0.942871f,-0.29863f, +-0.153003f,0.970479f,-0.186443f, +-0.259911f,0.94737f,-0.186912f, +-0.218176f,0.967871f,-0.124997f, +-0.218418f,0.965394f,0.142507f, +-0.497944f,0.825767f,0.264878f, +-0.394522f,0.874216f,0.283017f, +-0.174161f,0.980284f,0.0933364f, +-0.0291225f,0.984908f,-0.170609f, +-0.149188f,0.939649f,-0.307902f, +-0.109448f,0.970586f,-0.214438f, +0.391051f,0.895182f,-0.213842f, +0.237246f,0.888641f,-0.392468f, +0.104812f,0.984981f,-0.137213f, +0.1294f,0.991592f,-0.000205693f, +0.119158f,0.992497f,-0.0274125f, +0.117487f,0.990494f,-0.071548f, +0.234708f,0.962187f,-0.138234f, +0.347721f,0.937443f,-0.017023f, +0.135989f,0.962379f,-0.235229f, +-0.193384f,0.875532f,-0.442772f, +-0.209357f,0.905544f,-0.368998f, +0.0641865f,0.982942f,-0.172352f, +0.0534516f,0.998302f,-0.023133f, +-0.0579793f,0.992675f,-0.105989f, +0.299444f,0.827258f,0.475371f, +0.320901f,0.752799f,0.574731f, +-0.0625162f,0.964286f,0.257381f, +-0.0931157f,0.981324f,0.168322f, +0.0981691f,0.975509f,0.19684f, +0.238911f,0.944952f,0.223577f, +0.0852945f,0.980047f,0.179533f, +0.0437708f,0.96942f,0.241474f, +-0.0654565f,0.948925f,0.308637f, +0.105877f,0.941798f,0.319071f, +0.298409f,0.90697f,0.29725f, +0.267454f,0.931587f,0.246198f, +0.257873f,0.930012f,0.261877f, +0.0608152f,0.99476f,0.0821851f, +0.0682325f,0.995644f,-0.0635329f, +0.204976f,0.974836f,-0.0876375f, +0.100643f,0.994422f,0.031559f, +-0.0498971f,0.971595f,0.231328f, +-0.0948982f,0.951903f,0.291332f, +-0.0140779f,0.962693f,0.270229f, +0.0194699f,0.983768f,0.178386f, +-0.0700516f,0.997536f,0.00373294f, +-0.0458738f,0.991776f,-0.119485f, +-0.0457685f,0.983541f,-0.17479f, +0.031836f,0.984739f,-0.171101f, +-0.0846163f,0.991107f,-0.102703f, +-0.250146f,0.959975f,0.125993f, +-0.240823f,0.966766f,0.0858408f, +-0.110771f,0.993685f,0.0178603f, +-0.0536647f,0.99805f,-0.0318645f, +-0.0537905f,0.996775f,-0.0595505f, +-0.0979926f,0.994498f,-0.0370296f, +-0.317761f,0.946482f,-0.0565711f, +-0.353331f,0.932392f,-0.0761719f, +-0.315921f,0.918114f,-0.23929f, +-0.304095f,0.907663f,-0.289264f, +-0.232301f,0.951296f,-0.202665f, +-0.181242f,0.959764f,-0.214488f, +-0.0415921f,0.982269f,-0.182804f, +-0.134113f,0.976644f,-0.16787f, +-0.266673f,0.950383f,-0.160182f, +-0.233335f,0.968889f,-0.0825141f, +-0.383896f,0.923094f,0.0228394f, +-0.46523f,0.826401f,0.317211f, +-0.448022f,0.824389f,0.345917f, +-0.335673f,0.941977f,-0.00160348f, +0.00939714f,0.9768f,-0.213948f, +0.0525806f,0.945774f,-0.320541f, +-0.0139338f,0.984205f,-0.176483f, +-0.233879f,0.941098f,-0.244203f, +0.35813f,0.924476f,-0.13072f, +0.148621f,0.988076f,0.040214f, +-0.0873945f,0.896884f,0.433546f, +0.16715f,0.882598f,0.43941f, +0.105867f,0.92276f,0.370549f, +0.162793f,0.877156f,0.451769f, +0.26606f,0.895485f,0.356818f, +0.178343f,0.923603f,0.339339f, +0.205659f,0.876785f,0.434686f, +0.164046f,0.939287f,0.301379f, +-0.304778f,0.94913f,-0.0791393f, +-0.351721f,0.931897f,-0.088655f, +-0.137155f,0.986834f,0.0857151f, +-0.0493791f,0.984585f,0.167793f, +-0.29261f,0.942092f,0.163834f, +0.175576f,0.863797f,0.472257f, +0.388427f,0.769345f,0.507181f, +0.0396361f,0.995255f,0.0888612f, +0.000897162f,0.999738f,-0.022857f, +0.263974f,0.951061f,0.160623f, +0.140984f,0.987533f,0.0700142f, +-0.0604349f,0.998129f,-0.00925637f, +-0.0323604f,0.969904f,0.241328f, +0.0249905f,0.978924f,0.202689f, +0.301944f,0.900385f,0.313268f, +0.302439f,0.903212f,0.304531f, +0.227241f,0.927301f,0.297445f, +0.295557f,0.903047f,0.311692f, +0.215996f,0.968849f,0.121149f, +0.0543993f,0.994951f,0.0843384f, +-0.108272f,0.967731f,0.227539f, +-0.144218f,0.941468f,0.304694f, +-0.0465574f,0.94074f,0.335917f, +0.0834793f,0.95338f,0.289996f, +0.159412f,0.96437f,0.211135f, +0.125672f,0.984055f,0.125864f, +0.0125305f,0.999902f,-0.00630946f, +-0.0213081f,0.999771f,-0.00209364f, +-0.0845682f,0.99631f,0.014661f, +-0.191644f,0.962461f,0.192203f, +-0.326186f,0.912172f,0.248084f, +-0.125723f,0.965189f,0.229357f, +-0.0487346f,0.993706f,0.100859f, +0.0069351f,0.999976f,0.00057427f, +-0.0853775f,0.991791f,-0.0951918f, +-0.217561f,0.97582f,-0.0210368f, +-0.247132f,0.964013f,0.0979986f, +-0.253847f,0.965546f,-0.0573009f, +-0.17269f,0.977352f,-0.122318f, +-0.308873f,0.930936f,-0.19482f, +-0.274273f,0.935966f,-0.220775f, +-0.176582f,0.954344f,-0.240926f, +-0.17678f,0.967725f,-0.179601f, +-0.142126f,0.989789f,-0.0108556f, +-0.241082f,0.966299f,-0.0902532f, +-0.303483f,0.94088f,-0.150476f, +-0.634535f,0.768468f,-0.082594f, +-0.47113f,0.814002f,0.339761f, +-0.289984f,0.937003f,0.194769f, +0.025067f,0.999685f,-0.000862102f, +0.289006f,0.893747f,-0.343064f, +0.00615404f,0.935866f,-0.352301f, +-0.338901f,0.929111f,-0.147984f, +-0.164518f,0.985591f,-0.0393034f, +0.290961f,0.935697f,-0.199533f, +-0.0876053f,0.971539f,-0.220083f, +-0.32548f,0.935239f,0.139248f, +0.0766933f,0.974848f,0.20926f, +0.108828f,0.917507f,0.382541f, +0.0350786f,0.924503f,0.379557f, +0.162845f,0.883516f,0.439183f, +0.280718f,0.786151f,0.550603f, +0.282161f,0.80649f,0.519575f, +0.319525f,0.746566f,0.583561f, +-0.0912168f,0.872752f,0.479567f, +-0.288082f,0.924626f,0.249148f, +-0.142667f,0.981082f,0.130856f, +-0.066753f,0.9808f,0.183236f, +-0.230244f,0.961075f,0.152718f, +-0.067082f,0.99457f,0.0795691f, +0.611911f,0.730537f,0.303119f, +0.451199f,0.889041f,0.077617f, +0.0130284f,0.992329f,-0.12294f, +0.0930856f,0.993052f,-0.0719959f, +0.26722f,0.962884f,0.0380388f, +0.075301f,0.995117f,-0.0638176f, +0.167918f,0.972374f,0.162147f, +0.0578882f,0.993576f,0.0972437f, +0.196869f,0.968468f,0.152684f, +0.304163f,0.924874f,0.228237f, +0.255006f,0.935584f,0.244244f, +0.260728f,0.944471f,0.199987f, +0.218361f,0.924111f,0.313587f, +0.0535174f,0.911234f,0.408398f, +-0.0710624f,0.921034f,0.382946f, +-0.130246f,0.949543f,0.285314f, +-0.0655027f,0.977569f,0.200169f, +0.0903252f,0.974724f,0.204338f, +0.155207f,0.949154f,0.273892f, +0.153701f,0.938218f,0.310037f, +0.0621551f,0.960028f,0.272917f, +-0.0534301f,0.951765f,0.30214f, +-0.196733f,0.911558f,0.361052f, +-0.281614f,0.838193f,0.46704f, +-0.263195f,0.866235f,0.424694f, +-0.0481024f,0.917426f,0.394989f, +0.0935627f,0.945047f,0.31326f, +0.130693f,0.965135f,0.226792f, +0.00742185f,0.989033f,0.14751f, +-0.243053f,0.969364f,0.0354789f, +-0.273599f,0.961363f,-0.0304179f, +-0.215123f,0.976563f,-0.00682047f, +-0.164989f,0.983922f,0.068385f, +-0.241802f,0.97031f,0.00552545f, +-0.241315f,0.967202f,-0.0792945f, +-0.169018f,0.981272f,-0.0923975f, +-0.282714f,0.953981f,-0.0999632f, +-0.234963f,0.971912f,-0.0134244f, +-0.109087f,0.993838f,-0.0196489f, +-0.369236f,0.9273f,-0.0614783f, +-0.551241f,0.800465f,0.235349f, +-0.62344f,0.781571f,-0.0216512f, +-0.285923f,0.957424f,0.0398505f, +0.246101f,0.967083f,0.064696f, +0.379822f,0.894837f,-0.234526f, +-0.124179f,0.991035f,0.0492959f, +-0.55499f,0.830986f,0.0380685f, +-0.0883601f,0.986961f,0.13454f, +0.492332f,0.870217f,0.0182045f, +-0.0249785f,0.975709f,-0.217643f, +-0.368665f,0.864796f,-0.340902f, +-0.0172444f,0.938433f,-0.345031f, +-0.0663306f,0.97669f,-0.204147f, +0.00514992f,0.997132f,-0.0755029f, +0.0570337f,0.998371f,-0.00125828f, +0.249285f,0.962439f,0.107557f, +0.242481f,0.961206f,0.131476f, +0.205153f,0.940815f,0.269776f, +0.193253f,0.908579f,0.370322f, +-0.0564604f,0.989265f,0.134783f, +0.0286103f,0.993761f,-0.107795f, +-0.22802f,0.927614f,-0.29587f, +-0.141654f,0.989087f,-0.0405023f, +-0.0918591f,0.979413f,-0.179757f, +0.474817f,0.877478f,-0.067685f, +0.562064f,0.827022f,0.0108876f, +0.0667731f,0.98619f,-0.151561f, +0.0478258f,0.978171f,-0.202223f, +0.240461f,0.955483f,-0.170967f, +0.22331f,0.956303f,-0.188725f, +0.105513f,0.987685f,0.115519f, +0.0191904f,0.988704f,0.148645f, +0.138326f,0.966121f,0.217888f, +0.261136f,0.942738f,0.207491f, +0.283954f,0.937656f,0.20043f, +0.227821f,0.960294f,0.161036f, +0.0632997f,0.956465f,0.284901f, +-0.0487147f,0.902832f,0.427225f, +-0.0448066f,0.869805f,0.491357f, +0.0191513f,0.881775f,0.471282f, +0.0794772f,0.93047f,0.357644f, +0.0542875f,0.971817f,0.2294f, +0.0315472f,0.963796f,0.264769f, +0.140004f,0.919916f,0.36627f, +0.0838185f,0.924915f,0.370818f, +-0.147814f,0.916849f,0.370861f, +-0.285354f,0.864307f,0.414182f, +-0.277978f,0.859855f,0.428226f, +-0.199243f,0.910371f,0.362666f, +0.00801534f,0.941586f,0.336678f, +0.134574f,0.9298f,0.342582f, +0.118153f,0.909557f,0.398429f, +0.0557977f,0.896269f,0.439987f, +-0.0363608f,0.927402f,0.372294f, +-0.166377f,0.978738f,0.119962f, +-0.285966f,0.957794f,-0.0292047f, +-0.233552f,0.97096f,0.0518564f, +-0.131443f,0.981568f,0.138735f, +-0.225195f,0.974079f,0.0213645f, +-0.190643f,0.980844f,0.0400016f, +-0.234677f,0.970688f,0.051878f, +-0.269033f,0.961888f,-0.0489107f, +-0.0845976f,0.996159f,0.0225919f, +-0.404645f,0.907558f,0.112255f, +-0.609864f,0.674076f,0.416758f, +-0.498816f,0.848126f,0.178504f, +-0.144072f,0.987953f,-0.0565038f, +0.166758f,0.948601f,-0.268974f, +0.264567f,0.924612f,0.274038f, +-0.242512f,0.859891f,0.449195f, +-0.469649f,0.864648f,0.178364f, +-0.10506f,0.987899f,0.114094f, +0.522959f,0.850167f,0.0610757f, +0.207342f,0.943984f,-0.256717f, +-0.370985f,0.736513f,-0.565613f, +-0.196204f,0.840957f,-0.504277f, +-0.176697f,0.964208f,-0.197689f, +-0.102305f,0.980589f,-0.167266f, +0.103476f,0.966902f,-0.233225f, +0.176136f,0.882185f,-0.436721f, +0.1356f,0.926363f,-0.351374f, +0.144454f,0.987968f,-0.0552396f, +0.173673f,0.98445f,-0.0263929f, +0.186245f,0.978364f,-0.0900963f, +0.313839f,0.899877f,-0.302865f, +0.0432774f,0.865555f,-0.498941f, +-0.311487f,0.833772f,-0.45585f, +-0.00804547f,0.940342f,-0.340136f, +0.304128f,0.919914f,-0.247515f, +0.693924f,0.703662f,0.152743f, +0.239861f,0.957303f,-0.161363f, +0.0838446f,0.969769f,-0.229169f, +0.258925f,0.935636f,-0.239881f, +0.257223f,0.918931f,-0.299002f, +0.0548176f,0.967903f,0.245271f, +0.0212885f,0.963347f,0.267412f, +0.0818858f,0.973102f,0.215332f, +0.303912f,0.917546f,0.25641f, +0.304793f,0.927062f,0.218307f, +0.238677f,0.941098f,0.239517f, +-0.064428f,0.967965f,0.242677f, +-0.187169f,0.922119f,0.338622f, +-0.088608f,0.904799f,0.416518f, +0.0498324f,0.910793f,0.409846f, +0.176362f,0.913248f,0.367253f, +0.168717f,0.938419f,0.301504f, +0.00502329f,0.962305f,0.271928f, +0.0457173f,0.940418f,0.336934f, +0.0516487f,0.913931f,0.402569f, +-0.133343f,0.891616f,0.432713f, +-0.271457f,0.878825f,0.392399f, +-0.232052f,0.920355f,0.3148f, +-0.147635f,0.961854f,0.230305f, +-0.0156622f,0.96416f,0.264858f, +0.0430262f,0.93984f,0.338894f, +-0.0165403f,0.899263f,0.437095f, +0.0174547f,0.845985f,0.53292f, +0.0913065f,0.841589f,0.532345f, +0.0967863f,0.903784f,0.416901f, +-0.0948439f,0.973273f,0.209153f, +-0.30724f,0.95163f,-0.00197291f, +-0.219507f,0.974242f,0.051671f, +-0.123616f,0.986822f,0.104414f, +-0.209302f,0.977457f,0.0277521f, +-0.245642f,0.966973f,0.0679884f, +-0.189013f,0.970874f,0.147233f, +-0.260969f,0.955926f,0.134541f, +-0.586593f,0.772947f,0.241789f, +-0.622505f,0.744412f,0.241534f, +-0.343069f,0.923585f,0.171158f, +0.270136f,0.949637f,0.158794f, +-0.0270125f,0.976583f,-0.213437f, +-0.293688f,0.905533f,0.306199f, +-0.165876f,0.923469f,0.345963f, +-0.101353f,0.963266f,0.248689f, +-0.0607966f,0.998139f,0.00473307f, +0.571806f,0.81892f,0.04908f, +0.496821f,0.86721f,0.0334054f, +-0.0103979f,0.971297f,-0.237642f, +-0.296903f,0.868994f,-0.395851f, +-0.405401f,0.821757f,-0.400457f, +-0.0724266f,0.96927f,-0.235097f, +0.416989f,0.879556f,-0.229132f, +0.361436f,0.845922f,-0.392148f, +-0.194841f,0.930819f,-0.309213f, +-0.180426f,0.920987f,-0.345297f, +0.16396f,0.957989f,-0.235318f, +0.390246f,0.873397f,-0.291351f, +0.368832f,0.745912f,-0.554597f, +0.0989123f,0.900328f,-0.423823f, +-0.474178f,0.712544f,-0.517143f, +-0.225662f,0.862106f,-0.453707f, +0.0544551f,0.930953f,-0.361055f, +0.547706f,0.827837f,-0.121263f, +0.394416f,0.886974f,-0.240235f, +0.0920684f,0.955894f,-0.278909f, +0.287609f,0.908713f,-0.302524f, +0.34308f,0.875033f,-0.341487f, +-0.0471282f,0.962572f,0.266897f, +0.0309198f,0.953932f,0.298424f, +0.131633f,0.963671f,0.232402f, +0.278528f,0.937297f,0.209515f, +0.282669f,0.933258f,0.221646f, +0.232384f,0.927485f,0.292863f, +-0.0647083f,0.957687f,0.280443f, +-0.249973f,0.928177f,0.275683f, +-0.129841f,0.953629f,0.271538f, +0.0843284f,0.953748f,0.288536f, +0.245794f,0.935145f,0.255127f, +0.172562f,0.957759f,0.230042f, +-0.0230052f,0.954645f,0.296857f, +-0.041189f,0.951248f,0.305663f, +0.00483043f,0.930995f,0.364999f, +-0.165245f,0.915404f,0.367054f, +-0.220878f,0.904299f,0.365316f, +-0.0993279f,0.939818f,0.326919f, +-0.130653f,0.959943f,0.247869f, +-0.122986f,0.930904f,0.343936f, +-0.00592517f,0.911134f,0.412068f, +-0.1345f,0.9137f,0.383488f, +-0.0693903f,0.866333f,0.494623f, +0.121472f,0.852483f,0.508447f, +0.210048f,0.85163f,0.480215f, +0.0819942f,0.889969f,0.448588f, +-0.0885916f,0.940837f,0.327072f, +-0.228328f,0.96901f,0.0942702f, +-0.142437f,0.987843f,0.0622738f, +-0.157298f,0.987135f,0.0286638f, +-0.320718f,0.947161f,0.00499032f, +-0.336449f,0.936473f,0.0990975f, +-0.304779f,0.919932f,0.246646f, +-0.589969f,0.761912f,0.267259f, +-0.577652f,0.799842f,0.163009f, +-0.2738f,0.948238f,0.160868f, +0.240449f,0.968762f,0.0607085f, +-0.0196269f,0.999224f,-0.0341484f, +-0.384279f,0.908117f,0.166292f, +-0.0937293f,0.985711f,0.139963f, +0.0542133f,0.980144f,0.190731f, +0.0177665f,0.999043f,0.039964f, +0.448192f,0.892243f,0.0550135f, +0.417622f,0.800327f,0.430197f, +0.199972f,0.838529f,0.506833f, +-0.0526069f,0.975321f,0.214434f, +-0.547935f,0.818163f,-0.174291f, +-0.280437f,0.954205f,-0.10415f, +0.341739f,0.938698f,0.0453871f, +0.346269f,0.925369f,0.15424f, +-0.319444f,0.944119f,0.0812127f, +-0.192857f,0.977783f,0.0821343f, +0.335818f,0.935599f,-0.108997f, +0.474712f,0.785031f,-0.397964f, +0.373974f,0.907089f,-0.193218f, +0.0523306f,0.977738f,-0.203201f, +-0.41385f,0.870502f,-0.266372f, +-0.377073f,0.911356f,-0.165066f, +0.0445989f,0.977381f,-0.206731f, +0.525837f,0.831576f,-0.178819f, +0.378975f,0.901633f,-0.208411f, +0.088353f,0.958416f,-0.271353f, +0.309469f,0.925076f,-0.220144f, +0.420279f,0.904173f,-0.0763995f, +0.00329705f,0.962532f,0.271149f, +0.0784063f,0.967252f,0.241403f, +0.186812f,0.966508f,0.175965f, +0.294591f,0.944303f,0.146656f, +0.242144f,0.958708f,0.149151f, +0.122249f,0.946777f,0.297772f, +-0.0273117f,0.906407f,0.421521f, +-0.206066f,0.9181f,0.338568f, +-0.0954796f,0.950658f,0.295183f, +0.102184f,0.964671f,0.242834f, +0.213961f,0.952875f,0.215059f, +0.119187f,0.935673f,0.33213f, +-0.0431159f,0.926594f,0.373584f, +-0.0072858f,0.954565f,0.297913f, +-0.0455381f,0.966183f,0.253806f, +-0.154593f,0.937454f,0.311898f, +-0.199077f,0.936411f,0.288969f, +-0.136466f,0.95497f,0.263457f, +-0.127877f,0.920831f,0.3684f, +-0.229636f,0.912787f,0.337767f, +-0.0324452f,0.91205f,0.408794f, +-0.100812f,0.892675f,0.439282f, +-0.166782f,0.900555f,0.401477f, +0.102011f,0.876619f,0.470247f, +0.195025f,0.830402f,0.521918f, +0.0914158f,0.843587f,0.529154f, +0.0626366f,0.873316f,0.48311f, +-0.00226622f,0.929744f,0.3682f, +-0.0934177f,0.966149f,0.240479f, +-0.109555f,0.963702f,0.243468f, +-0.302241f,0.931855f,0.200739f, +-0.368178f,0.918352f,0.145171f, +-0.476623f,0.864028f,0.162128f, +-0.569304f,0.726984f,0.383911f, +-0.64096f,0.755201f,0.137264f, +-0.241026f,0.942011f,0.233501f, +0.376487f,0.905115f,0.197547f, +0.13011f,0.991259f,-0.0218225f, +-0.643013f,0.733979f,-0.218653f, +-0.19089f,0.942227f,0.275264f, +-0.00867818f,0.931663f,0.363219f, +0.146287f,0.916711f,0.371809f, +0.32054f,0.88208f,0.345239f, +0.0976689f,0.827123f,0.55347f, +0.0475977f,0.818583f,0.572413f, +0.312042f,0.775215f,0.549246f, +-0.398647f,0.872033f,0.283969f, +-0.297551f,0.880657f,0.368657f, +0.0684096f,0.950263f,0.303844f, +0.473417f,0.718991f,0.50885f, +-0.0712795f,0.964076f,0.255885f, +-0.187608f,0.981414f,0.0403824f, +0.441688f,0.892595f,0.090477f, +0.402228f,0.910874f,0.0923076f, +0.356001f,0.889285f,0.287114f, +0.109119f,0.990916f,0.0786044f, +-0.366364f,0.926283f,0.0881909f, +-0.361407f,0.913864f,0.185034f, +0.114451f,0.98516f,0.127909f, +0.511212f,0.854805f,0.0892759f, +0.488262f,0.865451f,0.112231f, +0.135362f,0.990178f,0.0350016f, +0.158924f,0.983832f,0.0825671f, +0.139428f,0.973099f,0.183407f, +-0.0124598f,0.997106f,0.0750005f, +0.111778f,0.989445f,0.0922193f, +0.245419f,0.967744f,0.0569325f, +0.2823f,0.95863f,0.0365395f, +0.172017f,0.973333f,0.151766f, +-0.129296f,0.953534f,0.27213f, +-0.0899396f,0.877846f,0.470422f, +-0.0963581f,0.899855f,0.425413f, +-0.0212856f,0.934761f,0.354638f, +0.147549f,0.94824f,0.281195f, +0.129526f,0.93959f,0.316849f, +0.0223606f,0.903767f,0.427441f, +-0.0124316f,0.909175f,0.41623f, +0.115235f,0.910193f,0.397831f, +-0.0283739f,0.950232f,0.310248f, +-0.203804f,0.932573f,0.297946f, +-0.13899f,0.955458f,0.260347f, +-0.204301f,0.958838f,0.197208f, +-0.229868f,0.915186f,0.331053f, +-0.132513f,0.91447f,0.38234f, +-0.151493f,0.940711f,0.3035f, +-0.124022f,0.907796f,0.400656f, +-0.112999f,0.914934f,0.387462f, +-0.039891f,0.908327f,0.416355f, +0.0930682f,0.835427f,0.541664f, +0.161351f,0.801381f,0.575981f, +0.131487f,0.83942f,0.527339f, +0.132693f,0.857332f,0.497367f, +-0.0832448f,0.920852f,0.380923f, +-0.145993f,0.894645f,0.422252f, +-0.213236f,0.888697f,0.405893f, +-0.293641f,0.888131f,0.353551f, +-0.525155f,0.788991f,0.318912f, +-0.588027f,0.679363f,0.438964f, +-0.478637f,0.812929f,0.331743f, +-0.264049f,0.917426f,0.297671f, +0.302963f,0.900818f,0.31103f, +0.420369f,0.80167f,0.424988f, +-0.470879f,0.867699f,0.159284f, +-0.530406f,0.817263f,0.225279f, +-0.0411983f,0.860627f,0.507566f, +0.103255f,0.833118f,0.543372f, +0.186539f,0.814428f,0.549463f, +0.132619f,0.779192f,0.612594f, +0.0761138f,0.83531f,0.544485f, +0.378863f,0.611781f,0.694397f, +-0.172003f,0.719417f,0.672944f, +-0.295852f,0.804769f,0.514605f, +0.0593285f,0.827842f,0.557814f, +0.323809f,0.743921f,0.584575f, +0.339913f,0.758357f,0.556197f, +-0.00694706f,0.946602f,0.322331f, +0.188872f,0.934445f,0.301895f, +0.251044f,0.713229f,0.654432f, +0.351195f,0.638214f,0.685087f, +0.295602f,0.899369f,0.322109f, +-0.450583f,0.880167f,0.14927f, +-0.375985f,0.904392f,0.201769f, +0.158376f,0.94847f,0.274448f, +0.500024f,0.831884f,0.240719f, +0.503159f,0.8293f,0.243089f, +0.0889199f,0.964326f,0.249335f, +0.108789f,0.932871f,0.34339f, +0.066105f,0.944864f,0.320722f, +-0.09433f,0.994124f,-0.0530892f, +0.0903529f,0.995715f,-0.0196726f, +0.246451f,0.969124f,-0.00783612f, +0.17532f,0.977334f,0.118663f, +0.0145033f,0.945036f,0.326645f, +-0.208385f,0.89773f,0.388145f, +-0.186403f,0.920929f,0.342264f, +-0.0196042f,0.920127f,0.391129f, +0.088861f,0.938743f,0.332966f, +0.0904885f,0.955513f,0.280725f, +0.00776342f,0.887041f,0.461625f, +0.0357997f,0.855618f,0.516368f, +0.0251977f,0.899984f,0.435195f, +0.113155f,0.898436f,0.424273f, +0.0488401f,0.928538f,0.36801f, +-0.122117f,0.962671f,0.241562f, +-0.0832756f,0.977563f,0.193483f, +-0.182752f,0.960599f,0.209407f, +-0.340533f,0.923546f,0.176353f, +-0.207225f,0.949201f,0.236801f, +-0.0875863f,0.939463f,0.331268f, +-0.156293f,0.945917f,0.284277f, +-0.15128f,0.944026f,0.293135f, +-0.133917f,0.921967f,0.363377f, +-0.0187779f,0.901995f,0.431337f, +0.137151f,0.859664f,0.492105f, +0.151864f,0.841546f,0.518398f, +0.169983f,0.832825f,0.526791f, +0.0329472f,0.8585f,0.511754f, +-0.148058f,0.877168f,0.456787f, +-0.179554f,0.872912f,0.453636f, +-0.29061f,0.863835f,0.411502f, +-0.582219f,0.748049f,0.318501f, +-0.586418f,0.753548f,0.297117f, +-0.423744f,0.867437f,0.260755f, +-0.266814f,0.914007f,0.305617f, +0.297036f,0.879751f,0.371224f, +0.301464f,0.846429f,0.438951f, +-0.267915f,0.8201f,0.505626f, +-0.708126f,0.705156f,0.0362171f, +-0.280503f,0.856013f,0.434234f, +0.0634361f,0.843315f,0.533662f, +0.203328f,0.848496f,0.488581f, +0.157757f,0.86266f,0.480552f, +-0.0108627f,0.875364f,0.483343f, +-0.00732908f,0.804113f,0.594431f, +0.217513f,0.756413f,0.616869f, +-0.242879f,0.903897f,0.352108f, +-0.0770731f,0.775477f,0.626654f, +0.238061f,0.731126f,0.639361f, +0.459013f,0.658034f,0.596908f, +0.0332364f,0.855326f,0.517022f, +-0.132848f,0.766918f,0.627844f, +-0.0252308f,0.840734f,0.54086f, +0.442735f,0.688282f,0.574677f, +0.624206f,0.545029f,0.559742f, +-0.216833f,0.89857f,0.381516f, +-0.428783f,0.890698f,0.151005f, +0.076598f,0.986116f,0.147334f, +0.479671f,0.865386f,0.144994f, +0.542246f,0.827427f,0.146065f, +0.100899f,0.969794f,0.222079f, +0.0591096f,0.972132f,0.226859f, +0.163564f,0.950136f,0.265495f, +-0.0539816f,0.998166f,0.0273959f, +0.085626f,0.996323f,0.00278248f, +0.159482f,0.986364f,0.0406345f, +-0.0565903f,0.982572f,0.177057f, +-0.167853f,0.932231f,0.320579f, +-0.135579f,0.92648f,0.351075f, +-0.12175f,0.950039f,0.287407f, +-0.0275f,0.960651f,0.276393f, +0.0945575f,0.956567f,0.27575f, +0.0118837f,0.934274f,0.356358f, +-0.160104f,0.889888f,0.42716f, +0.0609856f,0.903744f,0.423707f, +0.121664f,0.922268f,0.366906f, +0.148425f,0.946235f,0.287418f, +0.23463f,0.944122f,0.231479f, +-0.0440541f,0.996345f,0.0731815f, +-0.127251f,0.98255f,0.135658f, +-0.207412f,0.958865f,0.1938f, +-0.296871f,0.939382f,0.171549f, +-0.278192f,0.946498f,0.163558f, +-0.178451f,0.945897f,0.270988f, +-0.115294f,0.937073f,0.329548f, +-0.175206f,0.945254f,0.275312f, +-0.191323f,0.939359f,0.284604f, +-0.0822793f,0.949627f,0.302389f, +0.0583847f,0.93226f,0.357046f, +0.125066f,0.884667f,0.449136f, +0.147347f,0.866347f,0.477213f, +0.0545541f,0.865292f,0.49829f, +-0.098516f,0.887377f,0.450395f, +-0.209769f,0.897417f,0.388122f, +-0.210182f,0.881546f,0.422729f, +-0.451263f,0.852365f,0.264264f, +-0.650724f,0.758775f,-0.0286192f, +-0.407582f,0.890583f,0.201838f, +-0.388367f,0.887583f,0.247725f, +0.193188f,0.884808f,0.424019f, +0.215311f,0.880386f,0.422566f, +-0.165147f,0.855262f,0.491176f, +-0.520864f,0.795129f,0.310596f, +-0.488998f,0.786967f,0.37625f, +0.0562235f,0.868104f,0.493187f, +0.400928f,0.84731f,0.348313f, +0.199813f,0.978725f,-0.0465961f, +-0.198621f,0.97682f,0.0798329f, +-0.0891351f,0.888352f,0.450429f, +0.204835f,0.834736f,0.511135f, +-0.0720813f,0.941881f,0.328121f, +-0.196291f,0.972713f,0.123691f, +0.179787f,0.980826f,-0.0752149f, +0.511674f,0.853811f,0.0958982f, +0.0191479f,0.909767f,0.414677f, +-0.125562f,0.89333f,0.431505f, +0.22305f,0.943278f,0.245918f, +0.527748f,0.84488f,0.0875187f, +0.598212f,0.799615f,-0.0525252f, +0.0107332f,0.903361f,0.428747f, +-0.300811f,0.914951f,0.269032f, +0.179787f,0.975264f,0.128593f, +0.519301f,0.854591f,0.00126655f, +0.419398f,0.906587f,-0.0469514f, +0.0522982f,0.994257f,0.0933686f, +0.0513278f,0.996267f,0.0694112f, +0.103651f,0.993237f,0.0523089f, +0.0555975f,0.984758f,0.164805f, +0.0862163f,0.988349f,0.12543f, +0.0909734f,0.981273f,0.169784f, +-0.14512f,0.970727f,0.191388f, +-0.180918f,0.953611f,0.240612f, +-0.140102f,0.96533f,0.22025f, +-0.119189f,0.970295f,0.210526f, +-0.0126783f,0.974075f,0.225869f, +0.0237961f,0.97809f,0.20682f, +-0.0862872f,0.95413f,0.286688f, +-0.14433f,0.944949f,0.293667f, +0.132869f,0.954959f,0.265329f, +0.22733f,0.94991f,0.214458f, +0.185536f,0.968744f,0.164655f, +0.30218f,0.927213f,0.221277f, +-0.010566f,0.987352f,0.158194f, +-0.227641f,0.957817f,0.175404f, +-0.212635f,0.950922f,0.224799f, +-0.288872f,0.93765f,0.193302f, +-0.303211f,0.936666f,0.175273f, +-0.283958f,0.943546f,0.170553f, +-0.13575f,0.960553f,0.242714f, +-0.0816944f,0.973992f,0.211345f, +-0.191701f,0.977982f,0.0824724f, +-0.110352f,0.986199f,0.123427f, +-0.0409453f,0.971384f,0.233958f, +0.0185038f,0.933683f,0.357621f, +0.13477f,0.907601f,0.397615f, +0.0792432f,0.925049f,0.371489f, +-0.0350852f,0.929789f,0.366418f, +-0.159548f,0.910971f,0.380363f, +-0.245138f,0.905643f,0.346003f, +-0.179352f,0.926492f,0.330825f, +-0.589052f,0.80668f,0.0478056f, +-0.578625f,0.779472f,0.240033f, +-0.471687f,0.839166f,0.270762f, +0.0987404f,0.916105f,0.388589f, +0.173592f,0.831445f,0.527792f, +-0.220086f,0.704489f,0.674728f, +-0.395802f,0.62503f,0.672813f, +-0.417304f,0.755058f,0.505712f, +0.0513487f,0.865997f,0.497406f, +0.431689f,0.734124f,0.524124f, +0.359032f,0.884637f,0.297512f, +-0.308259f,0.930686f,0.196975f, +-0.34698f,0.877125f,0.332049f, +0.00851592f,0.919266f,0.393545f, +0.326193f,0.840272f,0.433061f, +0.261231f,0.960149f,-0.0993615f, +0.388612f,0.889039f,-0.242053f, +0.0354931f,0.979528f,-0.198152f, +0.0485316f,0.907873f,0.416427f, +-0.0781845f,0.964592f,0.251892f, +0.47974f,0.876345f,0.0432286f, +0.568817f,0.783907f,-0.248873f, +0.483889f,0.834837f,-0.262485f, +-0.220496f,0.975376f,0.00471288f, +-0.25449f,0.933474f,0.252706f, +0.326168f,0.921789f,0.209569f, +0.609761f,0.790958f,0.0507595f, +0.419183f,0.900774f,-0.11354f, +-0.0389936f,0.992704f,-0.114095f, +0.112818f,0.992086f,-0.0551048f, +0.140261f,0.98577f,-0.0926471f, +0.0460285f,0.981507f,0.185811f, +0.0839854f,0.981486f,0.172137f, +0.0780195f,0.983837f,0.161178f, +-0.135272f,0.977846f,0.159743f, +-0.233239f,0.960885f,0.149328f, +-0.119476f,0.978748f,0.166665f, +-0.0623017f,0.991047f,0.118089f, +-0.0310067f,0.999432f,0.0132292f, +-0.0037253f,0.997112f,0.0758502f, +-0.0758016f,0.98526f,0.153355f, +-0.143296f,0.988211f,0.0539015f, +0.103486f,0.991653f,0.076914f, +0.266632f,0.947722f,0.175298f, +0.164045f,0.978994f,0.121078f, +0.196418f,0.969063f,0.149458f, +0.0648458f,0.968138f,0.241876f, +-0.21695f,0.963194f,0.158716f, +-0.238014f,0.956133f,0.17076f, +-0.251543f,0.948014f,0.194926f, +-0.241597f,0.958745f,0.149794f, +-0.248822f,0.966568f,0.0619263f, +-0.195635f,0.9804f,0.0233089f, +0.00681016f,0.994726f,0.102342f, +-0.0728308f,0.997328f,0.00570638f, +-0.223928f,0.970021f,-0.0944255f, +-0.201047f,0.979434f,0.0169867f, +-0.100278f,0.986057f,0.132801f, +0.129703f,0.962794f,0.237074f, +0.129196f,0.949613f,0.28556f, +-0.100355f,0.959332f,0.263838f, +-0.226831f,0.927446f,0.297306f, +-0.211803f,0.921673f,0.325051f, +-0.16781f,0.90652f,0.387378f, +-0.507141f,0.76624f,0.394569f, +-0.499456f,0.740703f,0.449336f, +-0.375574f,0.865361f,0.331805f, +0.0665425f,0.96722f,0.245068f, +-0.127974f,0.946728f,0.295513f, +-0.531445f,0.627941f,0.568557f, +-0.268657f,0.746051f,0.609287f, +-0.123398f,0.84105f,0.526695f, +0.113268f,0.868801f,0.482033f, +0.278975f,0.860996f,0.425274f, +0.256512f,0.783766f,0.565608f, +0.24637f,0.788587f,0.563411f, +-0.207735f,0.977522f,-0.036006f, +0.0390118f,0.996098f,0.0791601f, +0.408253f,0.910351f,0.0677493f, +0.466297f,0.863647f,-0.191525f, +0.226125f,0.967725f,-0.111247f, +-0.24034f,0.965221f,0.102887f, +-0.130757f,0.944853f,0.300258f, +0.283435f,0.943407f,0.172188f, +0.590839f,0.8059f,-0.0378747f, +0.573782f,0.756596f,-0.313587f, +0.355206f,0.926281f,0.12583f, +-0.219704f,0.910923f,0.349212f, +-0.277723f,0.959254f,0.051969f, +0.340807f,0.938572f,0.0541606f, +0.677372f,0.729826f,0.0923128f, +0.49544f,0.867668f,-0.0411347f, +-0.024834f,0.981688f,-0.188872f, +0.050519f,0.974996f,-0.216403f, +0.180767f,0.970256f,-0.161015f, +0.0401148f,0.977494f,0.207113f, +0.106256f,0.969045f,0.222848f, +0.0969035f,0.97128f,0.217314f, +-0.118574f,0.978564f,0.16838f, +-0.194437f,0.978726f,0.0655019f, +-0.11441f,0.993427f,0.0037257f, +0.00229181f,0.999514f,0.0311045f, +0.0309142f,0.998007f,0.0550047f, +-0.113357f,0.989867f,0.085516f, +-0.111292f,0.980012f,0.164894f, +-0.0212066f,0.993646f,0.110539f, +0.0241257f,0.999577f,-0.0162417f, +0.157698f,0.982481f,0.0993122f, +0.222931f,0.950361f,0.21706f, +0.18078f,0.964986f,0.190052f, +0.0702985f,0.98108f,0.180387f, +-0.190259f,0.977665f,0.089291f, +-0.268574f,0.956136f,0.116926f, +-0.267756f,0.955804f,0.121429f, +-0.211446f,0.969418f,0.124579f, +-0.14687f,0.983484f,0.105776f, +-0.198985f,0.979945f,-0.0106117f, +-0.0887412f,0.995564f,0.0312775f, +0.0104704f,0.992989f,0.117739f, +-0.125001f,0.9915f,0.0360868f, +-0.238906f,0.968221f,-0.0739686f, +-0.167029f,0.981518f,-0.0933989f, +-0.0351406f,0.998931f,-0.030045f, +0.0130186f,0.974123f,0.225643f, +-0.0745329f,0.922898f,0.377762f, +-0.18971f,0.916591f,0.351953f, +-0.286917f,0.902381f,0.321538f, +-0.328487f,0.84853f,0.414841f, +-0.591704f,0.685127f,0.424839f, +-0.448564f,0.796089f,0.406241f, +-0.170353f,0.888356f,0.426384f, +-0.00830475f,0.908708f,0.417349f, +-0.140027f,0.883683f,0.446651f, +-0.599598f,0.727182f,0.334197f, +-0.234879f,0.924162f,0.301258f, +-0.0954672f,0.951872f,0.291248f, +0.100155f,0.948228f,0.301383f, +0.352663f,0.898478f,0.261471f, +0.217902f,0.956165f,0.19562f, +0.428441f,0.89557f,0.119967f, +0.0504867f,0.972497f,-0.227379f, +-0.160086f,0.98254f,-0.0948013f, +0.319131f,0.945228f,-0.0685555f, +0.64992f,0.715088f,0.257397f, +0.0361031f,0.995429f,0.0884124f, +-0.2599f,0.897768f,0.355618f, +-0.17567f,0.983498f,0.0432638f, +0.53944f,0.841427f,-0.0317039f, +0.60742f,0.697232f,-0.380669f, +0.609044f,0.790595f,-0.063438f, +-0.195234f,0.980448f,0.0245981f, +-0.224173f,0.885759f,0.406419f, +0.0964403f,0.992198f,0.0790071f, +0.380926f,0.892571f,-0.241272f, +0.532566f,0.777301f,-0.334927f, +0.58332f,0.811668f,0.0305478f, +0.122052f,0.989417f,-0.0784701f, +0.094933f,0.975516f,-0.198385f, +0.104703f,0.956209f,-0.273317f, +0.0116109f,0.989434f,0.144515f, +0.0514824f,0.974923f,0.216505f, +0.096067f,0.950842f,0.294399f, +0.00976988f,0.964716f,0.263111f, +-0.0931121f,0.98126f,0.168699f, +-0.0745948f,0.982842f,0.168693f, +-0.083139f,0.982475f,0.166825f, +-0.0763046f,0.97088f,0.22709f, +-0.130809f,0.960701f,0.244832f, +-0.117161f,0.974629f,0.190711f, +0.0735371f,0.976475f,0.202706f, +0.123062f,0.984428f,0.125529f, +0.0660058f,0.995943f,0.0611663f, +0.0811078f,0.98996f,0.115763f, +0.156048f,0.953727f,0.257008f, +0.12971f,0.935453f,0.32879f, +-0.0928149f,0.955298f,0.280698f, +-0.264252f,0.949049f,0.171686f, +-0.241724f,0.966072f,0.0909662f, +-0.244999f,0.96713f,0.0680795f, +-0.106995f,0.982895f,0.149898f, +-0.106861f,0.990227f,0.089616f, +-0.133621f,0.990932f,0.0141138f, +-0.0517957f,0.998024f,0.0355675f, +-0.0225779f,0.998718f,0.0453005f, +-0.144281f,0.986502f,-0.0774439f, +-0.157036f,0.983398f,-0.0909287f, +-0.161108f,0.986936f,-0.00118469f, +-0.22235f,0.965394f,0.136287f, +-0.250578f,0.942366f,0.221715f, +-0.217658f,0.901831f,0.373264f, +-0.29708f,0.848133f,0.438651f, +-0.36269f,0.819581f,0.443558f, +-0.534096f,0.793842f,0.290785f, +-0.584404f,0.811192f,0.0209707f, +-0.1404f,0.905222f,0.401075f, +-0.307079f,0.89418f,0.325797f, +-0.27164f,0.834087f,0.480115f, +-0.322843f,0.946322f,0.0157466f, +-0.301281f,0.933652f,-0.193713f, +-0.127165f,0.985755f,0.11007f, +0.121812f,0.97858f,0.165962f, +0.500139f,0.864928f,0.0419482f, +0.30357f,0.892132f,-0.334582f, +0.443241f,0.85073f,-0.282481f, +0.0967978f,0.993781f,0.0550442f, +-0.201565f,0.978713f,0.0386423f, +0.209591f,0.974539f,0.0796601f, +0.481917f,0.851558f,0.20641f, +-0.0224044f,0.977009f,0.212016f, +-0.238315f,0.88567f,0.398491f, +0.220358f,0.960844f,0.167992f, +0.601263f,0.791797f,-0.107428f, +0.618362f,0.741713f,-0.25979f, +0.284452f,0.956119f,0.0701626f, +-0.201478f,0.913131f,0.3544f, +-0.20526f,0.978252f,0.0298624f, +0.352634f,0.929538f,-0.107737f, +0.649062f,0.752634f,-0.110725f, +0.490387f,0.729272f,-0.477162f, +0.431974f,0.874843f,-0.219197f, +0.184608f,0.975155f,-0.122446f, +0.192786f,0.978517f,-0.0730681f, +0.240097f,0.966116f,-0.094733f, +-0.255309f,0.963455f,-0.0810722f, +-0.124334f,0.990531f,0.0582188f, +0.042075f,0.979967f,0.194667f, +0.0324324f,0.965776f,0.25734f, +-0.0760147f,0.965606f,0.248649f, +-0.138926f,0.972343f,0.187746f, +-0.0932442f,0.974882f,0.202264f, +-0.0380092f,0.975147f,0.218276f, +-0.0242537f,0.984345f,0.174576f, +-0.0724602f,0.995976f,0.0527463f, +0.0175716f,0.997526f,0.068069f, +0.191598f,0.97051f,0.146287f, +0.0888492f,0.992747f,0.0809944f, +0.0509079f,0.989914f,0.132209f, +0.0413152f,0.988953f,0.142354f, +-0.00590782f,0.97647f,0.215574f, +-0.0327876f,0.94937f,0.312443f, +-0.0862721f,0.978712f,0.186225f, +-0.179337f,0.981669f,0.0645377f, +-0.255621f,0.960924f,0.106226f, +-0.157413f,0.981394f,0.109943f, +-0.0325878f,0.996293f,0.0796149f, +-0.0627116f,0.997982f,-0.00999288f, +-0.0263234f,0.995733f,-0.0884504f, +0.00359159f,0.990572f,-0.136946f, +-0.0963f,0.991181f,-0.0910356f, +-0.255814f,0.966717f,-0.00409974f, +-0.292954f,0.950051f,0.107618f, +-0.259513f,0.946888f,0.189886f, +-0.274998f,0.934354f,0.226623f, +-0.37248f,0.885745f,0.276974f, +-0.384203f,0.849481f,0.361622f, +-0.326853f,0.86434f,0.382208f, +-0.213332f,0.922586f,0.321442f, +-0.528611f,0.848285f,0.0313709f, +-0.466119f,0.869006f,0.166018f, +-0.226659f,0.921685f,0.314837f, +-0.225942f,0.929604f,0.291181f, +0.262979f,0.943638f,0.200972f, +-0.158823f,0.970135f,-0.183342f, +-0.433654f,0.893597f,-0.115884f, +0.0458639f,0.99877f,-0.0188405f, +0.612149f,0.789064f,0.0514904f, +0.423383f,0.878106f,-0.222881f, +0.0967751f,0.930754f,-0.352606f, +0.0811144f,0.996202f,0.0316668f, +-0.413686f,0.895072f,-0.166465f, +0.148131f,0.951189f,0.270735f, +0.436798f,0.864787f,0.247692f, +0.0437864f,0.959427f,0.278536f, +-0.28501f,0.956226f,0.0663364f, +0.510274f,0.859616f,0.0260981f, +0.648806f,0.686419f,-0.328451f, +0.586912f,0.808674f,0.0397475f, +-0.0852935f,0.966768f,0.241009f, +-0.148057f,0.961052f,0.233361f, +0.164136f,0.983527f,-0.0757203f, +0.450314f,0.849987f,-0.273386f, +0.550526f,0.728504f,-0.407679f, +0.58281f,0.780161f,-0.227338f, +0.258267f,0.941325f,-0.21727f, +0.0807909f,0.98982f,-0.117172f, +0.0801488f,0.996327f,0.0301511f, +0.239863f,0.961671f,0.132871f, +-0.229647f,0.969202f,0.0889415f, +-0.172859f,0.981826f,0.0783421f, +-0.0626565f,0.996388f,0.0573105f, +-0.0572909f,0.992727f,0.105883f, +-0.0279351f,0.983375f,0.179427f, +-0.00285096f,0.99214f,0.125102f, +-0.084025f,0.99632f,-0.0168937f, +-0.0732377f,0.997041f,-0.0233556f, +-0.0045065f,0.999839f,0.0173404f, +0.0203121f,0.999722f,0.0119547f, +-0.0506539f,0.996487f,-0.0666886f, +0.119651f,0.992498f,0.0251293f, +0.0686084f,0.989615f,0.126312f, +0.000108814f,0.982339f,0.187109f, +0.0874025f,0.98865f,0.122196f, +-0.0625717f,0.997577f,0.0304034f, +-0.0486926f,0.992353f,0.113426f, +0.0140738f,0.989644f,0.142855f, +-0.151919f,0.980609f,0.123804f, +-0.280176f,0.959074f,0.0409668f, +-0.112828f,0.992642f,-0.0439511f, +0.0530002f,0.995827f,-0.0742939f, +0.0297885f,0.985001f,-0.169959f, +0.0528437f,0.970999f,-0.233169f, +-0.0380639f,0.977109f,-0.209305f, +-0.249056f,0.968138f,-0.0260696f, +-0.370842f,0.913812f,0.165599f, +-0.310025f,0.907402f,0.283736f, +-0.313659f,0.908343f,0.276641f, +-0.360766f,0.88042f,0.307747f, +-0.383668f,0.851108f,0.358349f, +-0.392242f,0.857478f,0.332984f, +-0.296931f,0.900087f,0.318865f, +-0.199402f,0.936164f,0.289543f, +-0.412291f,0.885214f,0.215434f, +-0.62242f,0.781068f,-0.0502514f, +-0.272781f,0.928261f,0.252828f, +-0.317665f,0.921151f,0.224876f, +0.0813846f,0.925309f,0.370378f, +0.00278871f,0.889899f,0.45615f, +-0.460626f,0.879338f,0.120782f, +0.0601251f,0.985077f,0.161272f, +0.599887f,0.787248f,0.142742f, +0.617017f,0.753279f,0.227729f, +0.13665f,0.981422f,0.134675f, +0.136502f,0.974756f,0.176687f, +-0.27066f,0.954113f,-0.128105f, +-0.13295f,0.980241f,-0.146465f, +0.409773f,0.909514f,-0.0697851f, +0.339811f,0.93455f,0.10557f, +-0.243979f,0.943604f,-0.223798f, +0.572252f,0.820076f,0.00181093f, +0.58136f,0.813444f,0.0181706f, +0.213313f,0.927464f,0.307095f, +-0.0427767f,0.853854f,0.518751f, +0.0717407f,0.97577f,0.206702f, +0.349298f,0.936925f,0.0127626f, +0.643074f,0.765767f,0.00757208f, +0.584117f,0.763349f,-0.275872f, +0.414478f,0.906497f,-0.0804466f, +0.213842f,0.975055f,-0.0594842f, +-0.00469446f,0.990505f,-0.137399f, +-0.0685672f,0.992236f,-0.103764f, +0.0844774f,0.996384f,-0.00904741f, +-0.320391f,0.938064f,0.131853f, +-0.173519f,0.96335f,0.204565f, +-0.0123366f,0.973468f,0.228492f, +-0.018009f,0.983892f,0.177855f, +-0.10447f,0.992257f,0.0671745f, +0.0409931f,0.988078f,0.148399f, +0.0370075f,0.994865f,0.0941976f, +-0.0471895f,0.997972f,-0.0427132f, +-0.0371271f,0.993135f,-0.110921f, +0.0109117f,0.996203f,-0.0863686f, +0.0455917f,0.995961f,-0.0773449f, +-0.0321894f,0.986545f,-0.160288f, +-0.0649603f,0.996397f,0.0545189f, +0.00369488f,0.985567f,0.169244f, +0.226168f,0.962189f,0.151787f, +0.029392f,0.999567f,0.00117257f, +-0.13579f,0.984206f,-0.113581f, +-0.10103f,0.992288f,-0.0718192f, +-0.125171f,0.991084f,0.0456533f, +-0.108309f,0.993989f,0.015999f, +-0.0231464f,0.995269f,-0.0943563f, +0.0270486f,0.99325f,-0.112795f, +0.141677f,0.989359f,-0.0331051f, +0.0268575f,0.994547f,-0.100767f, +-0.194101f,0.980932f,0.009818f, +-0.41139f,0.899763f,0.145547f, +-0.482013f,0.8562f,0.185973f, +-0.415606f,0.872343f,0.257468f, +-0.291757f,0.884021f,0.365218f, +-0.316561f,0.886381f,0.337814f, +-0.406f,0.884827f,0.22857f, +-0.363525f,0.905831f,0.217534f, +-0.301242f,0.93366f,0.193734f, +-0.208193f,0.941974f,0.263325f, +-0.164184f,0.932027f,0.323063f, +-0.4694f,0.88027f,-0.0691917f, +-0.525104f,0.840943f,-0.130688f, +-0.256903f,0.950739f,0.17348f, +-0.180022f,0.968548f,0.171775f, +0.0734506f,0.860739f,0.50372f, +-0.205317f,0.895889f,0.393991f, +0.0472127f,0.984089f,0.171289f, +0.492639f,0.869295f,-0.040419f, +0.615313f,0.776504f,0.135761f, +0.240143f,0.940103f,0.241946f, +0.0961855f,0.982412f,0.160044f, +0.107308f,0.976554f,0.186622f, +-0.0192621f,0.988216f,-0.151846f, +0.243819f,0.934285f,-0.260122f, +0.363158f,0.92047f,-0.144401f, +-0.0181857f,0.911833f,-0.410158f, +0.13216f,0.935755f,-0.326948f, +0.234069f,0.876493f,0.42068f, +-0.0429998f,0.864233f,0.501251f, +0.30178f,0.838678f,0.453374f, +0.334916f,0.905993f,0.258858f, +0.486799f,0.865003f,0.121641f, +0.551114f,0.813232f,-0.186886f, +0.639118f,0.75121f,0.164956f, +0.383938f,0.890692f,0.243432f, +0.354878f,0.921145f,0.159855f, +0.162961f,0.98584f,-0.0395363f, +-0.0637937f,0.974986f,-0.212914f, +-0.0365262f,0.968846f,-0.244954f, +-0.281965f,0.951785f,0.120834f, +-0.274882f,0.955225f,0.109473f, +-0.104135f,0.948711f,0.298502f, +0.0826411f,0.912269f,0.401168f, +0.0342531f,0.97031f,0.239425f, +-0.0365634f,0.991589f,0.124154f, +0.134024f,0.975461f,0.174679f, +0.109589f,0.99345f,0.032348f, +0.0453955f,0.994687f,-0.0923934f, +-0.0149079f,0.988982f,-0.147281f, +0.0512217f,0.992549f,-0.110554f, +0.0167819f,0.988638f,-0.149377f, +-0.222271f,0.949144f,-0.222982f, +-0.0921327f,0.987637f,-0.126823f, +0.189567f,0.98184f,-0.00744372f, +0.205171f,0.976356f,0.0680753f, +-0.00982996f,0.993812f,-0.110639f, +-0.0883427f,0.978311f,-0.18736f, +-0.198236f,0.955921f,-0.216604f, +-0.180283f,0.972159f,-0.149685f, +0.0029493f,0.99947f,-0.0324137f, +-0.0433514f,0.998534f,-0.0324142f, +0.0405175f,0.99421f,0.0995223f, +0.00286263f,0.981263f,0.19265f, +-0.296663f,0.921382f,0.251091f, +-0.412123f,0.867858f,0.277446f, +-0.439996f,0.871969f,0.214648f, +-0.457669f,0.875232f,0.156552f, +-0.384822f,0.899193f,0.208242f, +-0.276213f,0.916653f,0.288882f, +-0.314226f,0.91283f,0.260774f, +-0.345662f,0.91535f,0.206522f, +-0.311859f,0.934366f,0.17235f, +-0.323293f,0.931681f,0.165688f, +-0.218081f,0.943645f,0.248946f, +0.00414662f,0.967721f,0.251991f, +-0.350612f,0.910773f,-0.218092f, +-0.590427f,0.768592f,-0.246296f, +-0.263693f,0.937904f,0.225393f, +-0.149885f,0.945975f,0.287518f, +-0.0723712f,0.947676f,0.310922f, +0.303995f,0.902765f,0.304306f, +0.615729f,0.768916f,0.172179f, +0.376573f,0.870472f,0.316971f, +0.258103f,0.862435f,0.435417f, +0.208037f,0.965523f,0.156476f, +0.041711f,0.997309f,0.0602974f, +0.0896451f,0.984172f,0.152868f, +0.200861f,0.950569f,0.236798f, +0.331115f,0.861074f,0.385894f, +0.343908f,0.839357f,0.420961f, +-0.162885f,0.985003f,0.0568977f, +-0.0608521f,0.991774f,0.112611f, +0.279417f,0.937386f,0.207929f, +0.438178f,0.898268f,0.033396f, +0.516016f,0.854846f,-0.0544561f, +0.550254f,0.781096f,-0.295143f, +0.499018f,0.830127f,-0.248738f, +0.421585f,0.905472f,0.0488414f, +0.355515f,0.918443f,0.173411f, +0.416018f,0.882036f,0.221226f, +0.346021f,0.922667f,0.170161f, +0.0862406f,0.994799f,-0.0542001f, +0.0251294f,0.989963f,-0.139071f, +-0.167311f,0.982002f,0.0876306f, +-0.296088f,0.953872f,0.0496014f, +-0.309819f,0.944071f,0.112878f, +0.0107419f,0.974593f,0.223724f, +0.235566f,0.938548f,0.252263f, +0.0528759f,0.995406f,0.0798236f, +0.106055f,0.992977f,0.0524375f, +0.227694f,0.967451f,0.110427f, +0.15013f,0.988604f,0.0110517f, +0.0292872f,0.989448f,-0.141897f, +0.0113647f,0.978518f,-0.205848f, +0.0966514f,0.981912f,-0.162811f, +-0.0834695f,0.969158f,-0.231875f, +-0.173766f,0.92349f,-0.34201f, +0.0289323f,0.967596f,-0.250839f, +0.166759f,0.980973f,-0.0994165f, +0.0796755f,0.992423f,-0.0935347f, +-0.0109031f,0.993494f,-0.113363f, +-0.181202f,0.957527f,-0.224295f, +-0.231371f,0.948894f,-0.214636f, +-0.0963906f,0.978232f,-0.183771f, +-0.0964169f,0.992283f,-0.0779687f, +-0.114591f,0.992373f,0.045429f, +-0.0476997f,0.984744f,0.167343f, +-0.353531f,0.929974f,0.100818f, +-0.42903f,0.892447f,0.139543f, +-0.399459f,0.902474f,0.161164f, +-0.44275f,0.883954f,0.150326f, +-0.416721f,0.891582f,0.177271f, +-0.364313f,0.907101f,0.210818f, +-0.329954f,0.890729f,0.312622f, +-0.308128f,0.891277f,0.33269f, +-0.248313f,0.912421f,0.325314f, +-0.264673f,0.92449f,0.274348f, +-0.221501f,0.958108f,0.181568f, +-0.00722143f,0.985032f,0.17222f, +0.0811419f,0.973825f,0.212324f, +-0.519461f,0.82914f,-0.206608f, +-0.561212f,0.816969f,-0.132674f, +-0.10198f,0.978452f,0.179533f, +-0.0294922f,0.994047f,0.104885f, +0.212965f,0.975972f,0.0461033f, +0.39072f,0.902699f,0.180202f, +0.284816f,0.877828f,0.385096f, +0.371584f,0.726424f,0.578129f, +0.415725f,0.734903f,0.535809f, +0.0647658f,0.913533f,0.401575f, +0.0316961f,0.895539f,0.443852f, +-0.0215836f,0.930013f,0.366891f, +0.0389377f,0.900411f,0.433293f, +0.182398f,0.888094f,0.421923f, +0.319795f,0.864372f,0.388061f, +0.179682f,0.983355f,0.0269752f, +0.358016f,0.913314f,-0.19412f, +0.445422f,0.82688f,-0.343321f, +0.564533f,0.736553f,-0.372547f, +0.511683f,0.792162f,-0.332656f, +0.362215f,0.931906f,0.0187495f, +0.332114f,0.925718f,0.180958f, +0.376936f,0.924108f,0.0628019f, +0.34207f,0.939661f,0.00505146f, +0.432513f,0.89733f,0.0879243f, +0.250624f,0.96783f,0.022189f, +0.113333f,0.993448f,0.0146943f, +-0.330108f,0.943938f,0.00323688f, +-0.32108f,0.944743f,0.0660874f, +-0.312445f,0.949733f,0.0196284f, +-0.0425447f,0.998988f,-0.0145795f, +0.234895f,0.971633f,0.0274452f, +0.205978f,0.978297f,0.0225396f, +0.0556133f,0.99289f,-0.10525f, +0.149272f,0.988455f,-0.0259672f, +0.25486f,0.966188f,0.0390683f, +0.206371f,0.977859f,-0.0346908f, +0.0798975f,0.983688f,-0.161166f, +0.0387149f,0.980238f,-0.193996f, +-0.0261652f,0.985317f,-0.168719f, +-0.115457f,0.963019f,-0.243441f, +-0.0914394f,0.962229f,-0.256427f, +0.0382488f,0.992063f,-0.119784f, +0.0800161f,0.996698f,-0.0137989f, +0.0187475f,0.998138f,-0.0580508f, +-0.073595f,0.994051f,-0.0802936f, +-0.224165f,0.957926f,-0.179241f, +-0.16346f,0.967941f,-0.190711f, +-0.19173f,0.978244f,-0.0792358f, +-0.275576f,0.961029f,-0.0219235f, +-0.0407932f,0.98802f,0.148838f, +-0.278629f,0.956556f,0.085827f, +-0.465684f,0.878931f,0.103047f, +-0.438529f,0.89146f,0.11398f, +-0.455089f,0.880964f,0.129601f, +-0.457802f,0.879895f,0.127287f, +-0.406331f,0.89051f,0.204664f, +-0.386395f,0.891456f,0.236654f, +-0.321818f,0.921226f,0.218577f, +-0.271011f,0.935727f,0.22576f, +-0.198383f,0.944022f,0.263564f, +-0.105727f,0.975806f,0.191373f, +-0.0832756f,0.987941f,0.130528f, +0.0931562f,0.956641f,0.27597f, +-0.216408f,0.96162f,0.168686f, +-0.648586f,0.688743f,-0.323988f, +-0.276841f,0.843915f,-0.459527f, +-0.060911f,0.935148f,-0.348981f, +0.243821f,0.963831f,-0.107611f, +0.35478f,0.93349f,-0.0522288f, +0.124674f,0.987025f,-0.101179f, +0.106145f,0.993646f,0.0374371f, +0.264307f,0.911176f,0.316069f, +0.180037f,0.821936f,0.540378f, +0.0976487f,0.839888f,0.533903f, +0.242869f,0.82432f,0.511381f, +0.296956f,0.900742f,0.316987f, +0.37446f,0.92343f,0.0840066f, +0.38614f,0.913414f,-0.128727f, +0.497691f,0.838063f,-0.223505f, +0.399217f,0.778523f,-0.484281f, +0.607215f,0.684189f,-0.403949f, +0.455879f,0.835157f,-0.307715f, +0.317815f,0.943806f,-0.0906903f, +0.166917f,0.983806f,0.0653043f, +0.277188f,0.953387f,0.119249f, +0.491287f,0.85011f,0.189606f, +0.3858f,0.919271f,0.0780984f, +0.390109f,0.91635f,0.0900968f, +0.247947f,0.964668f,0.0890966f, +0.0188396f,0.999506f,0.0251451f, +-0.249227f,0.949063f,0.192782f, +-0.24873f,0.963608f,0.0979465f, +-0.225537f,0.968208f,-0.108193f, +-0.0586638f,0.984304f,-0.166448f, +0.193919f,0.980395f,-0.0349386f, +0.232927f,0.972341f,0.0172453f, +0.165218f,0.985248f,-0.0445953f, +0.10666f,0.982482f,-0.152814f, +0.176402f,0.976328f,-0.125164f, +0.217875f,0.975941f,-0.00837002f, +0.138055f,0.990338f,0.0130638f, +0.0914598f,0.995289f,-0.0321788f, +-0.014672f,0.992233f,-0.123523f, +-0.0701479f,0.990985f,-0.114142f, +-0.0940689f,0.987781f,-0.124254f, +-0.152176f,0.977744f,-0.144426f, +0.043676f,0.996991f,0.0640382f, +0.0457416f,0.996307f,0.07266f, +-0.0198973f,0.997072f,0.0738311f, +-0.119455f,0.990174f,-0.0727032f, +-0.224875f,0.962572f,-0.151282f, +-0.250045f,0.966903f,-0.0507448f, +-0.319974f,0.944248f,-0.0775328f, +-0.16005f,0.987102f,-0.00365841f, +-0.307005f,0.947659f,0.0876954f, +-0.490256f,0.846833f,0.206209f, +-0.400386f,0.879926f,0.255778f, +-0.427515f,0.880624f,0.204282f, +-0.477897f,0.856347f,0.195663f, +-0.43217f,0.864768f,0.255745f, +-0.342474f,0.92438f,0.16803f, +-0.284468f,0.956998f,0.0568588f, +-0.290121f,0.956708f,0.023234f, +-0.249156f,0.966838f,0.0560771f, +-0.0655515f,0.986836f,0.147842f, +-0.100568f,0.984251f,0.145384f, +-0.0191778f,0.985445f,0.168911f, +-0.0443403f,0.97787f,0.204462f, +-0.28653f,0.957033f,-0.044587f, +-0.127864f,0.901634f,-0.413166f, +-0.0930849f,0.861283f,-0.499526f, +-0.10032f,0.791759f,-0.60254f, +0.277857f,0.863349f,-0.421218f, +0.0733471f,0.944573f,-0.320003f, +0.0656198f,0.995434f,-0.0693225f, +0.0994234f,0.993172f,-0.0610351f, +0.0758799f,0.991718f,0.103618f, +0.0755546f,0.978148f,0.193698f, +0.318521f,0.931105f,0.177731f, +0.532035f,0.846717f,0.00302226f, +0.479952f,0.801468f,-0.356785f, +0.444207f,0.753204f,-0.485143f, +0.599635f,0.661874f,-0.449845f, +0.467802f,0.782561f,-0.410805f, +0.194572f,0.899472f,-0.391269f, +0.334078f,0.938895f,-0.0828733f, +0.236858f,0.971355f,0.0191963f, +0.177255f,0.983392f,0.0389945f, +0.22691f,0.973661f,-0.0222777f, +0.408661f,0.912593f,0.013075f, +0.394434f,0.908333f,0.139114f, +0.34039f,0.913901f,0.221176f, +0.340162f,0.904445f,0.257428f, +0.21637f,0.954077f,0.207173f, +-0.190356f,0.960699f,0.202044f, +-0.0745122f,0.978557f,0.192026f, +-0.0103556f,0.997337f,0.0721953f, +-0.102208f,0.994222f,-0.0328074f, +0.0538732f,0.998534f,0.00527007f, +0.220064f,0.97523f,-0.0223306f, +0.22889f,0.972208f,-0.0492086f, +0.203387f,0.976813f,-0.0668524f, +0.112155f,0.987122f,-0.114071f, +0.137033f,0.989998f,-0.0335468f, +0.125928f,0.990544f,-0.0544465f, +0.164164f,0.983484f,-0.0762248f, +0.056178f,0.987899f,-0.14457f, +-0.125491f,0.977887f,-0.167299f, +-0.0763702f,0.993552f,-0.0837951f, +-0.140516f,0.986451f,-0.0846751f, +-0.138825f,0.988035f,-0.0671838f, +0.0272382f,0.998662f,0.0439583f, +0.051406f,0.998673f,0.00322772f, +0.0131796f,0.996364f,-0.0841692f, +-0.197723f,0.973335f,-0.116299f, +-0.315939f,0.94482f,-0.0865842f, +-0.273936f,0.961179f,-0.0330844f, +-0.278588f,0.957771f,-0.0711653f, +-0.371629f,0.922753f,0.102078f, +-0.589295f,0.797687f,0.128167f, +-0.394808f,0.893641f,0.213383f, +-0.419749f,0.89327f,0.160869f, +-0.503386f,0.848953f,0.160878f, +-0.392151f,0.910681f,0.129912f, +-0.194389f,0.97789f,0.0771005f, +-0.210697f,0.97754f,0.00473511f, +-0.261758f,0.965059f,0.0120029f, +-0.306606f,0.951531f,-0.0240962f, +-0.191391f,0.98062f,0.0418887f, +-0.0805366f,0.9875f,0.135492f, +-0.0197042f,0.996843f,0.0769187f, +-0.0102082f,0.996001f,0.0887568f, +-0.106967f,0.993499f,0.0389638f, +-0.0299932f,0.997488f,-0.0641764f, +0.166392f,0.98551f,-0.0329295f, +0.122834f,0.919366f,-0.373736f, +0.0989442f,0.860803f,-0.499228f, +-0.16483f,0.786842f,-0.594736f, +-0.139994f,0.854441f,-0.500331f, +0.037386f,0.884593f,-0.464864f, +-0.0340706f,0.910599f,-0.411885f, +0.0643546f,0.934103f,-0.351155f, +0.330549f,0.864687f,-0.378225f, +0.61879f,0.706641f,-0.343158f, +0.664468f,0.668218f,-0.334614f, +0.535603f,0.737564f,-0.411252f, +0.392926f,0.807647f,-0.439677f, +0.299634f,0.936543f,-0.181953f, +0.20385f,0.978529f,-0.030423f, +0.255219f,0.962099f,-0.0960637f, +0.218057f,0.97044f,-0.103423f, +0.152183f,0.981776f,-0.113823f, +0.287579f,0.953452f,-0.0907011f, +0.354102f,0.933846f,-0.0504376f, +0.271766f,0.955964f,0.110796f, +0.254566f,0.942907f,0.214762f, +0.330431f,0.909031f,0.253925f, +0.276649f,0.934017f,0.226003f, +-0.276078f,0.960525f,0.0342386f, +-0.126608f,0.988039f,0.088024f, +-0.0433883f,0.982429f,0.181523f, +-0.0351658f,0.95918f,0.280603f, +0.130316f,0.978179f,0.161815f, +0.34012f,0.939563f,0.0392436f, +0.225269f,0.971719f,-0.0708295f, +0.186144f,0.981343f,-0.0481244f, +0.117145f,0.991402f,-0.0582961f, +0.122374f,0.988553f,-0.0882497f, +0.217284f,0.968092f,-0.124844f, +0.168939f,0.967628f,-0.1875f, +0.0966952f,0.983818f,-0.150838f, +-0.108071f,0.971789f,-0.209635f, +-0.167419f,0.956466f,-0.239047f, +-0.15925f,0.972646f,-0.169115f, +-0.169755f,0.972705f,-0.158205f, +0.0352685f,0.991682f,-0.123784f, +0.0984439f,0.980655f,-0.169186f, +0.0318934f,0.989724f,-0.139387f, +-0.246309f,0.963763f,-0.102435f, +-0.355567f,0.934631f,-0.00599911f, +-0.265814f,0.963735f,-0.0236194f, +-0.351588f,0.935043f,-0.0456126f, +-0.494494f,0.858936f,0.133056f, +-0.559402f,0.824266f,0.0874941f, +-0.405326f,0.914016f,0.0169127f, +-0.376559f,0.926338f,0.010028f, +-0.448864f,0.890609f,-0.0730511f, +-0.3487f,0.913403f,-0.210007f, +-0.225518f,0.948441f,-0.222713f, +-0.278172f,0.957801f,-0.0723737f, +-0.296428f,0.947861f,0.117f, +-0.260326f,0.954501f,0.14546f, +-0.208806f,0.976306f,0.0568064f, +-0.0937503f,0.995595f,-0.00141652f, +0.0211825f,0.998587f,-0.0487327f, +-0.0203898f,0.998016f,-0.0595622f, +-0.117256f,0.992273f,-0.0405676f, +0.0346735f,0.999272f,0.0158994f, +0.165596f,0.985653f,-0.0326431f, +0.277068f,0.959929f,-0.0420538f, +0.211278f,0.971116f,-0.110882f, +0.138826f,0.972226f,-0.188423f, +0.0186164f,0.920791f,-0.389612f, +0.00693313f,0.891348f,-0.453267f, +-0.0471378f,0.869656f,-0.491403f, +0.135484f,0.84445f,-0.518217f, +0.351566f,0.784405f,-0.510988f, +0.399468f,0.772299f,-0.493943f, +0.574953f,0.790421f,-0.211338f, +0.577809f,0.813449f,-0.0666111f, +0.451377f,0.892327f,0.00336233f, +0.237932f,0.970883f,-0.0278435f, +0.170635f,0.975266f,-0.140498f, +0.305065f,0.94416f,-0.124487f, +0.219111f,0.958291f,-0.183492f, +0.160317f,0.981326f,-0.106286f, +0.222178f,0.974771f,-0.021419f, +0.23168f,0.971792f,0.0441002f, +0.140177f,0.984507f,0.105338f, +0.184383f,0.966339f,0.179422f, +0.307531f,0.911743f,0.272303f, +0.342083f,0.879118f,0.331859f, +-0.245266f,0.968917f,0.0323163f, +-0.176433f,0.984311f,-0.00156667f, +-0.164847f,0.983548f,0.0738887f, +-0.0271087f,0.959686f,0.279762f, +0.210185f,0.960158f,0.18417f, +0.386525f,0.917795f,0.0908302f, +0.288585f,0.956426f,0.04436f, +0.157424f,0.986731f,-0.0397454f, +0.194229f,0.980956f,0.000793421f, +0.143953f,0.978f,-0.150974f, +0.243865f,0.955091f,-0.168319f, +0.151307f,0.968911f,-0.195749f, +0.0861511f,0.987302f,-0.133462f, +-0.0343302f,0.988258f,-0.148887f, +-0.149683f,0.954065f,-0.259529f, +-0.180054f,0.943807f,-0.277143f, +-0.182632f,0.946912f,-0.26458f, +0.0250152f,0.97257f,-0.23126f, +0.0655433f,0.96826f,-0.241197f, +0.00940225f,0.990707f,-0.135685f, +-0.313822f,0.94168f,-0.121471f, +-0.325919f,0.940955f,0.0915474f, +-0.245857f,0.968763f,-0.0324418f, +-0.38384f,0.920444f,-0.0738245f, +-0.542624f,0.834584f,0.0950211f, +-0.496894f,0.865347f,0.0653522f, +-0.40471f,0.910862f,-0.0808731f, +-0.336326f,0.940002f,-0.0572751f, +-0.384947f,0.90765f,-0.167296f, +-0.26052f,0.919475f,-0.294439f, +-0.278076f,0.879766f,-0.385599f, +-0.415096f,0.880667f,-0.2283f, +-0.411169f,0.907675f,0.0840562f, +-0.22106f,0.940981f,0.256296f, +-0.105371f,0.978797f,0.175653f, +-0.0100537f,0.999811f,0.0166273f, +0.0459065f,0.991326f,-0.123151f, +-0.0151969f,0.991011f,-0.132912f, +-0.164041f,0.976761f,-0.137947f, +0.00793599f,0.998771f,-0.0489272f, +0.178958f,0.98335f,-0.031577f, +0.314466f,0.949045f,-0.0206086f, +0.240757f,0.963062f,-0.120617f, +0.126531f,0.982046f,-0.139911f, +0.0695074f,0.9956f,-0.062839f, +0.0427419f,0.998852f,-0.02164f, +-0.0292495f,0.993565f,-0.109419f, +0.176081f,0.974549f,-0.138744f, +0.405406f,0.900659f,-0.156393f, +0.48202f,0.865956f,-0.133334f, +0.477566f,0.852664f,-0.211881f, +0.526274f,0.839922f,-0.132537f, +0.390331f,0.920621f,-0.0098857f, +0.349443f,0.931118f,0.104442f, +0.205374f,0.96487f,-0.163851f, +0.359411f,0.921384f,-0.147904f, +0.161592f,0.938137f,-0.306246f, +0.0124614f,0.982178f,-0.187542f, +0.143914f,0.986786f,0.0744463f, +0.270333f,0.949018f,0.162126f, +0.132f,0.991194f,0.0105184f, +0.131712f,0.991267f,0.00644011f, +0.199003f,0.974024f,0.108048f, +0.274163f,0.928953f,0.248757f, +}; + +btScalar Landscape01Tex[] = { +0.507813f,0.0078125f, +0.507813f,0.0f, +0.515625f,0.0078125f, +0.515625f,0.0f, +0.523438f,0.0078125f, +0.523438f,0.0f, +0.53125f,0.0078125f, +0.53125f,0.0f, +0.539063f,0.0078125f, +0.539063f,0.0f, +0.546875f,0.0078125f, +0.546875f,0.0f, +0.554688f,0.0078125f, +0.554688f,0.0f, +0.5625f,0.0078125f, +0.5625f,0.0f, +0.570313f,0.0078125f, +0.570313f,0.0f, +0.578125f,0.0078125f, +0.578125f,0.0f, +0.585938f,0.0078125f, +0.585938f,0.0f, +0.59375f,0.0078125f, +0.59375f,0.0f, +0.601563f,0.0078125f, +0.601563f,0.0f, +0.609375f,0.0078125f, +0.609375f,0.0f, +0.617188f,0.0078125f, +0.617188f,0.0f, +0.625f,0.0078125f, +0.625f,0.0f, +0.632813f,0.0078125f, +0.632813f,0.0f, +0.640625f,0.0078125f, +0.640625f,0.0f, +0.648438f,0.0078125f, +0.648438f,0.0f, +0.65625f,0.0078125f, +0.65625f,0.0f, +0.664063f,0.0078125f, +0.664063f,0.0f, +0.671875f,0.0078125f, +0.671875f,0.0f, +0.679688f,0.0078125f, +0.679688f,0.0f, +0.6875f,0.0078125f, +0.6875f,0.0f, +0.695313f,0.0078125f, +0.695313f,0.0f, +0.703125f,0.0078125f, +0.703125f,0.0f, +0.710938f,0.0078125f, +0.710938f,0.0f, +0.71875f,0.0078125f, +0.71875f,0.0f, +0.726563f,0.0078125f, +0.726563f,0.0f, +0.734375f,0.0078125f, +0.734375f,0.0f, +0.742188f,0.0078125f, +0.742188f,0.0f, +0.75f,0.0078125f, +0.75f,0.0f, +0.757813f,0.0078125f, +0.757813f,0.0f, +0.765625f,0.0078125f, +0.765625f,0.0f, +0.773438f,0.0078125f, +0.773438f,0.0f, +0.78125f,0.0078125f, +0.78125f,0.0f, +0.789063f,0.0078125f, +0.789063f,0.0f, +0.796875f,0.0078125f, +0.796875f,0.0f, +0.804688f,0.0078125f, +0.804688f,0.0f, +0.8125f,0.0078125f, +0.8125f,0.0f, +0.820313f,0.0078125f, +0.820313f,0.0f, +0.828125f,0.0078125f, +0.828125f,0.0f, +0.835938f,0.0078125f, +0.835938f,0.0f, +0.84375f,0.0078125f, +0.84375f,0.0f, +0.851563f,0.0078125f, +0.851563f,0.0f, +0.859375f,0.0078125f, +0.859375f,0.0f, +0.867188f,0.0078125f, +0.867188f,0.0f, +0.875f,0.0078125f, +0.875f,0.0f, +0.882813f,0.0078125f, +0.882813f,0.0f, +0.890625f,0.0078125f, +0.890625f,0.0f, +0.898438f,0.0078125f, +0.898438f,0.0f, +0.90625f,0.0078125f, +0.90625f,0.0f, +0.914063f,0.0078125f, +0.914063f,0.0f, +0.921875f,0.0078125f, +0.921875f,0.0f, +0.929688f,0.0078125f, +0.929688f,0.0f, +0.9375f,0.0078125f, +0.9375f,0.0f, +0.945313f,0.0078125f, +0.945313f,0.0f, +0.953125f,0.0078125f, +0.953125f,0.0f, +0.960938f,0.0078125f, +0.960938f,0.0f, +0.96875f,0.0078125f, +0.96875f,0.0f, +0.976563f,0.0078125f, +0.976563f,0.0f, +0.984375f,0.0078125f, +0.984375f,0.0f, +0.992188f,0.0078125f, +0.992188f,0.0f, +1.0f,0.0078125f, +1.0f,0.0f, +0.507813f,0.015625f, +0.515625f,0.015625f, +0.523438f,0.015625f, +0.53125f,0.015625f, +0.539063f,0.015625f, +0.546875f,0.015625f, +0.554688f,0.015625f, +0.5625f,0.015625f, +0.570313f,0.015625f, +0.578125f,0.015625f, +0.585938f,0.015625f, +0.59375f,0.015625f, +0.601563f,0.015625f, +0.609375f,0.015625f, +0.617188f,0.015625f, +0.625f,0.015625f, +0.632813f,0.015625f, +0.640625f,0.015625f, +0.648438f,0.015625f, +0.65625f,0.015625f, +0.664063f,0.015625f, +0.671875f,0.015625f, +0.679688f,0.015625f, +0.6875f,0.015625f, +0.695313f,0.015625f, +0.703125f,0.015625f, +0.710938f,0.015625f, +0.71875f,0.015625f, +0.726563f,0.015625f, +0.734375f,0.015625f, +0.742188f,0.015625f, +0.75f,0.015625f, +0.757813f,0.015625f, +0.765625f,0.015625f, +0.773438f,0.015625f, +0.78125f,0.015625f, +0.789063f,0.015625f, +0.796875f,0.015625f, +0.804688f,0.015625f, +0.8125f,0.015625f, +0.820313f,0.015625f, +0.828125f,0.015625f, +0.835938f,0.015625f, +0.84375f,0.015625f, +0.851563f,0.015625f, +0.859375f,0.015625f, +0.867188f,0.015625f, +0.875f,0.015625f, +0.882813f,0.015625f, +0.890625f,0.015625f, +0.898438f,0.015625f, +0.90625f,0.015625f, +0.914063f,0.015625f, +0.921875f,0.015625f, +0.929688f,0.015625f, +0.9375f,0.015625f, +0.945313f,0.015625f, +0.953125f,0.015625f, +0.960938f,0.015625f, +0.96875f,0.015625f, +0.976563f,0.015625f, +0.984375f,0.015625f, +0.992188f,0.015625f, +1.0f,0.015625f, +0.507813f,0.0234375f, +0.515625f,0.0234375f, +0.523438f,0.0234375f, +0.53125f,0.0234375f, +0.539063f,0.0234375f, +0.546875f,0.0234375f, +0.554688f,0.0234375f, +0.5625f,0.0234375f, +0.570313f,0.0234375f, +0.578125f,0.0234375f, +0.585938f,0.0234375f, +0.59375f,0.0234375f, +0.601563f,0.0234375f, +0.609375f,0.0234375f, +0.617188f,0.0234375f, +0.625f,0.0234375f, +0.632813f,0.0234375f, +0.640625f,0.0234375f, +0.648438f,0.0234375f, +0.65625f,0.0234375f, +0.664063f,0.0234375f, +0.671875f,0.0234375f, +0.679688f,0.0234375f, +0.6875f,0.0234375f, +0.695313f,0.0234375f, +0.703125f,0.0234375f, +0.710938f,0.0234375f, +0.71875f,0.0234375f, +0.726563f,0.0234375f, +0.734375f,0.0234375f, +0.742188f,0.0234375f, +0.75f,0.0234375f, +0.757813f,0.0234375f, +0.765625f,0.0234375f, +0.773438f,0.0234375f, +0.78125f,0.0234375f, +0.789063f,0.0234375f, +0.796875f,0.0234375f, +0.804688f,0.0234375f, +0.8125f,0.0234375f, +0.820313f,0.0234375f, +0.828125f,0.0234375f, +0.835938f,0.0234375f, +0.84375f,0.0234375f, +0.851563f,0.0234375f, +0.859375f,0.0234375f, +0.867188f,0.0234375f, +0.875f,0.0234375f, +0.882813f,0.0234375f, +0.890625f,0.0234375f, +0.898438f,0.0234375f, +0.90625f,0.0234375f, +0.914063f,0.0234375f, +0.921875f,0.0234375f, +0.929688f,0.0234375f, +0.9375f,0.0234375f, +0.945313f,0.0234375f, +0.953125f,0.0234375f, +0.960938f,0.0234375f, +0.96875f,0.0234375f, +0.976563f,0.0234375f, +0.984375f,0.0234375f, +0.992188f,0.0234375f, +1.0f,0.0234375f, +0.507813f,0.03125f, +0.515625f,0.03125f, +0.523438f,0.03125f, +0.53125f,0.03125f, +0.539063f,0.03125f, +0.546875f,0.03125f, +0.554688f,0.03125f, +0.5625f,0.03125f, +0.570313f,0.03125f, +0.578125f,0.03125f, +0.585938f,0.03125f, +0.59375f,0.03125f, +0.601563f,0.03125f, +0.609375f,0.03125f, +0.617188f,0.03125f, +0.625f,0.03125f, +0.632813f,0.03125f, +0.640625f,0.03125f, +0.648438f,0.03125f, +0.65625f,0.03125f, +0.664063f,0.03125f, +0.671875f,0.03125f, +0.679688f,0.03125f, +0.6875f,0.03125f, +0.695313f,0.03125f, +0.703125f,0.03125f, +0.710938f,0.03125f, +0.71875f,0.03125f, +0.726563f,0.03125f, +0.734375f,0.03125f, +0.742188f,0.03125f, +0.75f,0.03125f, +0.757813f,0.03125f, +0.765625f,0.03125f, +0.773438f,0.03125f, +0.78125f,0.03125f, +0.789063f,0.03125f, +0.796875f,0.03125f, +0.804688f,0.03125f, +0.8125f,0.03125f, +0.820313f,0.03125f, +0.828125f,0.03125f, +0.835938f,0.03125f, +0.84375f,0.03125f, +0.851563f,0.03125f, +0.859375f,0.03125f, +0.867188f,0.03125f, +0.875f,0.03125f, +0.882813f,0.03125f, +0.890625f,0.03125f, +0.898438f,0.03125f, +0.90625f,0.03125f, +0.914063f,0.03125f, +0.921875f,0.03125f, +0.929688f,0.03125f, +0.9375f,0.03125f, +0.945313f,0.03125f, +0.953125f,0.03125f, +0.960938f,0.03125f, +0.96875f,0.03125f, +0.976563f,0.03125f, +0.984375f,0.03125f, +0.992188f,0.03125f, +1.0f,0.03125f, +0.507813f,0.0390625f, +0.515625f,0.0390625f, +0.523438f,0.0390625f, +0.53125f,0.0390625f, +0.539063f,0.0390625f, +0.546875f,0.0390625f, +0.554688f,0.0390625f, +0.5625f,0.0390625f, +0.570313f,0.0390625f, +0.578125f,0.0390625f, +0.585938f,0.0390625f, +0.59375f,0.0390625f, +0.601563f,0.0390625f, +0.609375f,0.0390625f, +0.617188f,0.0390625f, +0.625f,0.0390625f, +0.632813f,0.0390625f, +0.640625f,0.0390625f, +0.648438f,0.0390625f, +0.65625f,0.0390625f, +0.664063f,0.0390625f, +0.671875f,0.0390625f, +0.679688f,0.0390625f, +0.6875f,0.0390625f, +0.695313f,0.0390625f, +0.703125f,0.0390625f, +0.710938f,0.0390625f, +0.71875f,0.0390625f, +0.726563f,0.0390625f, +0.734375f,0.0390625f, +0.742188f,0.0390625f, +0.75f,0.0390625f, +0.757813f,0.0390625f, +0.765625f,0.0390625f, +0.773438f,0.0390625f, +0.78125f,0.0390625f, +0.789063f,0.0390625f, +0.796875f,0.0390625f, +0.804688f,0.0390625f, +0.8125f,0.0390625f, +0.820313f,0.0390625f, +0.828125f,0.0390625f, +0.835938f,0.0390625f, +0.84375f,0.0390625f, +0.851563f,0.0390625f, +0.859375f,0.0390625f, +0.867188f,0.0390625f, +0.875f,0.0390625f, +0.882813f,0.0390625f, +0.890625f,0.0390625f, +0.898438f,0.0390625f, +0.90625f,0.0390625f, +0.914063f,0.0390625f, +0.921875f,0.0390625f, +0.929688f,0.0390625f, +0.9375f,0.0390625f, +0.945313f,0.0390625f, +0.953125f,0.0390625f, +0.960938f,0.0390625f, +0.96875f,0.0390625f, +0.976563f,0.0390625f, +0.984375f,0.0390625f, +0.992188f,0.0390625f, +1.0f,0.0390625f, +0.507813f,0.046875f, +0.515625f,0.046875f, +0.523438f,0.046875f, +0.53125f,0.046875f, +0.539063f,0.046875f, +0.546875f,0.046875f, +0.554688f,0.046875f, +0.5625f,0.046875f, +0.570313f,0.046875f, +0.578125f,0.046875f, +0.585938f,0.046875f, +0.59375f,0.046875f, +0.601563f,0.046875f, +0.609375f,0.046875f, +0.617188f,0.046875f, +0.625f,0.046875f, +0.632813f,0.046875f, +0.640625f,0.046875f, +0.648438f,0.046875f, +0.65625f,0.046875f, +0.664063f,0.046875f, +0.671875f,0.046875f, +0.679688f,0.046875f, +0.6875f,0.046875f, +0.695313f,0.046875f, +0.703125f,0.046875f, +0.710938f,0.046875f, +0.71875f,0.046875f, +0.726563f,0.046875f, +0.734375f,0.046875f, +0.742188f,0.046875f, +0.75f,0.046875f, +0.757813f,0.046875f, +0.765625f,0.046875f, +0.773438f,0.046875f, +0.78125f,0.046875f, +0.789063f,0.046875f, +0.796875f,0.046875f, +0.804688f,0.046875f, +0.8125f,0.046875f, +0.820313f,0.046875f, +0.828125f,0.046875f, +0.835938f,0.046875f, +0.84375f,0.046875f, +0.851563f,0.046875f, +0.859375f,0.046875f, +0.867188f,0.046875f, +0.875f,0.046875f, +0.882813f,0.046875f, +0.890625f,0.046875f, +0.898438f,0.046875f, +0.90625f,0.046875f, +0.914063f,0.046875f, +0.921875f,0.046875f, +0.929688f,0.046875f, +0.9375f,0.046875f, +0.945313f,0.046875f, +0.953125f,0.046875f, +0.960938f,0.046875f, +0.96875f,0.046875f, +0.976563f,0.046875f, +0.984375f,0.046875f, +0.992188f,0.046875f, +1.0f,0.046875f, +0.507813f,0.0546875f, +0.515625f,0.0546875f, +0.523438f,0.0546875f, +0.53125f,0.0546875f, +0.539063f,0.0546875f, +0.546875f,0.0546875f, +0.554688f,0.0546875f, +0.5625f,0.0546875f, +0.570313f,0.0546875f, +0.578125f,0.0546875f, +0.585938f,0.0546875f, +0.59375f,0.0546875f, +0.601563f,0.0546875f, +0.609375f,0.0546875f, +0.617188f,0.0546875f, +0.625f,0.0546875f, +0.632813f,0.0546875f, +0.640625f,0.0546875f, +0.648438f,0.0546875f, +0.65625f,0.0546875f, +0.664063f,0.0546875f, +0.671875f,0.0546875f, +0.679688f,0.0546875f, +0.6875f,0.0546875f, +0.695313f,0.0546875f, +0.703125f,0.0546875f, +0.710938f,0.0546875f, +0.71875f,0.0546875f, +0.726563f,0.0546875f, +0.734375f,0.0546875f, +0.742188f,0.0546875f, +0.75f,0.0546875f, +0.757813f,0.0546875f, +0.765625f,0.0546875f, +0.773438f,0.0546875f, +0.78125f,0.0546875f, +0.789063f,0.0546875f, +0.796875f,0.0546875f, +0.804688f,0.0546875f, +0.8125f,0.0546875f, +0.820313f,0.0546875f, +0.828125f,0.0546875f, +0.835938f,0.0546875f, +0.84375f,0.0546875f, +0.851563f,0.0546875f, +0.859375f,0.0546875f, +0.867188f,0.0546875f, +0.875f,0.0546875f, +0.882813f,0.0546875f, +0.890625f,0.0546875f, +0.898438f,0.0546875f, +0.90625f,0.0546875f, +0.914063f,0.0546875f, +0.921875f,0.0546875f, +0.929688f,0.0546875f, +0.9375f,0.0546875f, +0.945313f,0.0546875f, +0.953125f,0.0546875f, +0.960938f,0.0546875f, +0.96875f,0.0546875f, +0.976563f,0.0546875f, +0.984375f,0.0546875f, +0.992188f,0.0546875f, +1.0f,0.0546875f, +0.507813f,0.0625f, +0.515625f,0.0625f, +0.523438f,0.0625f, +0.53125f,0.0625f, +0.539063f,0.0625f, +0.546875f,0.0625f, +0.554688f,0.0625f, +0.5625f,0.0625f, +0.570313f,0.0625f, +0.578125f,0.0625f, +0.585938f,0.0625f, +0.59375f,0.0625f, +0.601563f,0.0625f, +0.609375f,0.0625f, +0.617188f,0.0625f, +0.625f,0.0625f, +0.632813f,0.0625f, +0.640625f,0.0625f, +0.648438f,0.0625f, +0.65625f,0.0625f, +0.664063f,0.0625f, +0.671875f,0.0625f, +0.679688f,0.0625f, +0.6875f,0.0625f, +0.695313f,0.0625f, +0.703125f,0.0625f, +0.710938f,0.0625f, +0.71875f,0.0625f, +0.726563f,0.0625f, +0.734375f,0.0625f, +0.742188f,0.0625f, +0.75f,0.0625f, +0.757813f,0.0625f, +0.765625f,0.0625f, +0.773438f,0.0625f, +0.78125f,0.0625f, +0.789063f,0.0625f, +0.796875f,0.0625f, +0.804688f,0.0625f, +0.8125f,0.0625f, +0.820313f,0.0625f, +0.828125f,0.0625f, +0.835938f,0.0625f, +0.84375f,0.0625f, +0.851563f,0.0625f, +0.859375f,0.0625f, +0.867188f,0.0625f, +0.875f,0.0625f, +0.882813f,0.0625f, +0.890625f,0.0625f, +0.898438f,0.0625f, +0.90625f,0.0625f, +0.914063f,0.0625f, +0.921875f,0.0625f, +0.929688f,0.0625f, +0.9375f,0.0625f, +0.945313f,0.0625f, +0.953125f,0.0625f, +0.960938f,0.0625f, +0.96875f,0.0625f, +0.976563f,0.0625f, +0.984375f,0.0625f, +0.992188f,0.0625f, +1.0f,0.0625f, +0.507813f,0.0703125f, +0.515625f,0.0703125f, +0.523438f,0.0703125f, +0.53125f,0.0703125f, +0.539063f,0.0703125f, +0.546875f,0.0703125f, +0.554688f,0.0703125f, +0.5625f,0.0703125f, +0.570313f,0.0703125f, +0.578125f,0.0703125f, +0.585938f,0.0703125f, +0.59375f,0.0703125f, +0.601563f,0.0703125f, +0.609375f,0.0703125f, +0.617188f,0.0703125f, +0.625f,0.0703125f, +0.632813f,0.0703125f, +0.640625f,0.0703125f, +0.648438f,0.0703125f, +0.65625f,0.0703125f, +0.664063f,0.0703125f, +0.671875f,0.0703125f, +0.679688f,0.0703125f, +0.6875f,0.0703125f, +0.695313f,0.0703125f, +0.703125f,0.0703125f, +0.710938f,0.0703125f, +0.71875f,0.0703125f, +0.726563f,0.0703125f, +0.734375f,0.0703125f, +0.742188f,0.0703125f, +0.75f,0.0703125f, +0.757813f,0.0703125f, +0.765625f,0.0703125f, +0.773438f,0.0703125f, +0.78125f,0.0703125f, +0.789063f,0.0703125f, +0.796875f,0.0703125f, +0.804688f,0.0703125f, +0.8125f,0.0703125f, +0.820313f,0.0703125f, +0.828125f,0.0703125f, +0.835938f,0.0703125f, +0.84375f,0.0703125f, +0.851563f,0.0703125f, +0.859375f,0.0703125f, +0.867188f,0.0703125f, +0.875f,0.0703125f, +0.882813f,0.0703125f, +0.890625f,0.0703125f, +0.898438f,0.0703125f, +0.90625f,0.0703125f, +0.914063f,0.0703125f, +0.921875f,0.0703125f, +0.929688f,0.0703125f, +0.9375f,0.0703125f, +0.945313f,0.0703125f, +0.953125f,0.0703125f, +0.960938f,0.0703125f, +0.96875f,0.0703125f, +0.976563f,0.0703125f, +0.984375f,0.0703125f, +0.992188f,0.0703125f, +1.0f,0.0703125f, +0.507813f,0.078125f, +0.515625f,0.078125f, +0.523438f,0.078125f, +0.53125f,0.078125f, +0.539063f,0.078125f, +0.546875f,0.078125f, +0.554688f,0.078125f, +0.5625f,0.078125f, +0.570313f,0.078125f, +0.578125f,0.078125f, +0.585938f,0.078125f, +0.59375f,0.078125f, +0.601563f,0.078125f, +0.609375f,0.078125f, +0.617188f,0.078125f, +0.625f,0.078125f, +0.632813f,0.078125f, +0.640625f,0.078125f, +0.648438f,0.078125f, +0.65625f,0.078125f, +0.664063f,0.078125f, +0.671875f,0.078125f, +0.679688f,0.078125f, +0.6875f,0.078125f, +0.695313f,0.078125f, +0.703125f,0.078125f, +0.710938f,0.078125f, +0.71875f,0.078125f, +0.726563f,0.078125f, +0.734375f,0.078125f, +0.742188f,0.078125f, +0.75f,0.078125f, +0.757813f,0.078125f, +0.765625f,0.078125f, +0.773438f,0.078125f, +0.78125f,0.078125f, +0.789063f,0.078125f, +0.796875f,0.078125f, +0.804688f,0.078125f, +0.8125f,0.078125f, +0.820313f,0.078125f, +0.828125f,0.078125f, +0.835938f,0.078125f, +0.84375f,0.078125f, +0.851563f,0.078125f, +0.859375f,0.078125f, +0.867188f,0.078125f, +0.875f,0.078125f, +0.882813f,0.078125f, +0.890625f,0.078125f, +0.898438f,0.078125f, +0.90625f,0.078125f, +0.914063f,0.078125f, +0.921875f,0.078125f, +0.929688f,0.078125f, +0.9375f,0.078125f, +0.945313f,0.078125f, +0.953125f,0.078125f, +0.960938f,0.078125f, +0.96875f,0.078125f, +0.976563f,0.078125f, +0.984375f,0.078125f, +0.992188f,0.078125f, +1.0f,0.078125f, +0.507813f,0.0859375f, +0.515625f,0.0859375f, +0.523438f,0.0859375f, +0.53125f,0.0859375f, +0.539063f,0.0859375f, +0.546875f,0.0859375f, +0.554688f,0.0859375f, +0.5625f,0.0859375f, +0.570313f,0.0859375f, +0.578125f,0.0859375f, +0.585938f,0.0859375f, +0.59375f,0.0859375f, +0.601563f,0.0859375f, +0.609375f,0.0859375f, +0.617188f,0.0859375f, +0.625f,0.0859375f, +0.632813f,0.0859375f, +0.640625f,0.0859375f, +0.648438f,0.0859375f, +0.65625f,0.0859375f, +0.664063f,0.0859375f, +0.671875f,0.0859375f, +0.679688f,0.0859375f, +0.6875f,0.0859375f, +0.695313f,0.0859375f, +0.703125f,0.0859375f, +0.710938f,0.0859375f, +0.71875f,0.0859375f, +0.726563f,0.0859375f, +0.734375f,0.0859375f, +0.742188f,0.0859375f, +0.75f,0.0859375f, +0.757813f,0.0859375f, +0.765625f,0.0859375f, +0.773438f,0.0859375f, +0.78125f,0.0859375f, +0.789063f,0.0859375f, +0.796875f,0.0859375f, +0.804688f,0.0859375f, +0.8125f,0.0859375f, +0.820313f,0.0859375f, +0.828125f,0.0859375f, +0.835938f,0.0859375f, +0.84375f,0.0859375f, +0.851563f,0.0859375f, +0.859375f,0.0859375f, +0.867188f,0.0859375f, +0.875f,0.0859375f, +0.882813f,0.0859375f, +0.890625f,0.0859375f, +0.898438f,0.0859375f, +0.90625f,0.0859375f, +0.914063f,0.0859375f, +0.921875f,0.0859375f, +0.929688f,0.0859375f, +0.9375f,0.0859375f, +0.945313f,0.0859375f, +0.953125f,0.0859375f, +0.960938f,0.0859375f, +0.96875f,0.0859375f, +0.976563f,0.0859375f, +0.984375f,0.0859375f, +0.992188f,0.0859375f, +1.0f,0.0859375f, +0.507813f,0.09375f, +0.515625f,0.09375f, +0.523438f,0.09375f, +0.53125f,0.09375f, +0.539063f,0.09375f, +0.546875f,0.09375f, +0.554688f,0.09375f, +0.5625f,0.09375f, +0.570313f,0.09375f, +0.578125f,0.09375f, +0.585938f,0.09375f, +0.59375f,0.09375f, +0.601563f,0.09375f, +0.609375f,0.09375f, +0.617188f,0.09375f, +0.625f,0.09375f, +0.632813f,0.09375f, +0.640625f,0.09375f, +0.648438f,0.09375f, +0.65625f,0.09375f, +0.664063f,0.09375f, +0.671875f,0.09375f, +0.679688f,0.09375f, +0.6875f,0.09375f, +0.695313f,0.09375f, +0.703125f,0.09375f, +0.710938f,0.09375f, +0.71875f,0.09375f, +0.726563f,0.09375f, +0.734375f,0.09375f, +0.742188f,0.09375f, +0.75f,0.09375f, +0.757813f,0.09375f, +0.765625f,0.09375f, +0.773438f,0.09375f, +0.78125f,0.09375f, +0.789063f,0.09375f, +0.796875f,0.09375f, +0.804688f,0.09375f, +0.8125f,0.09375f, +0.820313f,0.09375f, +0.828125f,0.09375f, +0.835938f,0.09375f, +0.84375f,0.09375f, +0.851563f,0.09375f, +0.859375f,0.09375f, +0.867188f,0.09375f, +0.875f,0.09375f, +0.882813f,0.09375f, +0.890625f,0.09375f, +0.898438f,0.09375f, +0.90625f,0.09375f, +0.914063f,0.09375f, +0.921875f,0.09375f, +0.929688f,0.09375f, +0.9375f,0.09375f, +0.945313f,0.09375f, +0.953125f,0.09375f, +0.960938f,0.09375f, +0.96875f,0.09375f, +0.976563f,0.09375f, +0.984375f,0.09375f, +0.992188f,0.09375f, +1.0f,0.09375f, +0.507813f,0.101563f, +0.515625f,0.101563f, +0.523438f,0.101563f, +0.53125f,0.101563f, +0.539063f,0.101563f, +0.546875f,0.101563f, +0.554688f,0.101563f, +0.5625f,0.101563f, +0.570313f,0.101563f, +0.578125f,0.101563f, +0.585938f,0.101563f, +0.59375f,0.101563f, +0.601563f,0.101563f, +0.609375f,0.101563f, +0.617188f,0.101563f, +0.625f,0.101563f, +0.632813f,0.101563f, +0.640625f,0.101563f, +0.648438f,0.101563f, +0.65625f,0.101563f, +0.664063f,0.101563f, +0.671875f,0.101563f, +0.679688f,0.101563f, +0.6875f,0.101563f, +0.695313f,0.101563f, +0.703125f,0.101563f, +0.710938f,0.101563f, +0.71875f,0.101563f, +0.726563f,0.101563f, +0.734375f,0.101563f, +0.742188f,0.101563f, +0.75f,0.101563f, +0.757813f,0.101563f, +0.765625f,0.101563f, +0.773438f,0.101563f, +0.78125f,0.101563f, +0.789063f,0.101563f, +0.796875f,0.101563f, +0.804688f,0.101563f, +0.8125f,0.101563f, +0.820313f,0.101563f, +0.828125f,0.101563f, +0.835938f,0.101563f, +0.84375f,0.101563f, +0.851563f,0.101563f, +0.859375f,0.101563f, +0.867188f,0.101563f, +0.875f,0.101563f, +0.882813f,0.101563f, +0.890625f,0.101563f, +0.898438f,0.101563f, +0.90625f,0.101563f, +0.914063f,0.101563f, +0.921875f,0.101563f, +0.929688f,0.101563f, +0.9375f,0.101563f, +0.945313f,0.101563f, +0.953125f,0.101563f, +0.960938f,0.101563f, +0.96875f,0.101563f, +0.976563f,0.101563f, +0.984375f,0.101563f, +0.992188f,0.101563f, +1.0f,0.101563f, +0.507813f,0.109375f, +0.515625f,0.109375f, +0.523438f,0.109375f, +0.53125f,0.109375f, +0.539063f,0.109375f, +0.546875f,0.109375f, +0.554688f,0.109375f, +0.5625f,0.109375f, +0.570313f,0.109375f, +0.578125f,0.109375f, +0.585938f,0.109375f, +0.59375f,0.109375f, +0.601563f,0.109375f, +0.609375f,0.109375f, +0.617188f,0.109375f, +0.625f,0.109375f, +0.632813f,0.109375f, +0.640625f,0.109375f, +0.648438f,0.109375f, +0.65625f,0.109375f, +0.664063f,0.109375f, +0.671875f,0.109375f, +0.679688f,0.109375f, +0.6875f,0.109375f, +0.695313f,0.109375f, +0.703125f,0.109375f, +0.710938f,0.109375f, +0.71875f,0.109375f, +0.726563f,0.109375f, +0.734375f,0.109375f, +0.742188f,0.109375f, +0.75f,0.109375f, +0.757813f,0.109375f, +0.765625f,0.109375f, +0.773438f,0.109375f, +0.78125f,0.109375f, +0.789063f,0.109375f, +0.796875f,0.109375f, +0.804688f,0.109375f, +0.8125f,0.109375f, +0.820313f,0.109375f, +0.828125f,0.109375f, +0.835938f,0.109375f, +0.84375f,0.109375f, +0.851563f,0.109375f, +0.859375f,0.109375f, +0.867188f,0.109375f, +0.875f,0.109375f, +0.882813f,0.109375f, +0.890625f,0.109375f, +0.898438f,0.109375f, +0.90625f,0.109375f, +0.914063f,0.109375f, +0.921875f,0.109375f, +0.929688f,0.109375f, +0.9375f,0.109375f, +0.945313f,0.109375f, +0.953125f,0.109375f, +0.960938f,0.109375f, +0.96875f,0.109375f, +0.976563f,0.109375f, +0.984375f,0.109375f, +0.992188f,0.109375f, +1.0f,0.109375f, +0.507813f,0.117188f, +0.515625f,0.117188f, +0.523438f,0.117188f, +0.53125f,0.117188f, +0.539063f,0.117188f, +0.546875f,0.117188f, +0.554688f,0.117188f, +0.5625f,0.117188f, +0.570313f,0.117188f, +0.578125f,0.117188f, +0.585938f,0.117188f, +0.59375f,0.117188f, +0.601563f,0.117188f, +0.609375f,0.117188f, +0.617188f,0.117188f, +0.625f,0.117188f, +0.632813f,0.117188f, +0.640625f,0.117188f, +0.648438f,0.117188f, +0.65625f,0.117188f, +0.664063f,0.117188f, +0.671875f,0.117188f, +0.679688f,0.117188f, +0.6875f,0.117188f, +0.695313f,0.117188f, +0.703125f,0.117188f, +0.710938f,0.117188f, +0.71875f,0.117188f, +0.726563f,0.117188f, +0.734375f,0.117188f, +0.742188f,0.117188f, +0.75f,0.117188f, +0.757813f,0.117188f, +0.765625f,0.117188f, +0.773438f,0.117188f, +0.78125f,0.117188f, +0.789063f,0.117188f, +0.796875f,0.117188f, +0.804688f,0.117188f, +0.8125f,0.117188f, +0.820313f,0.117188f, +0.828125f,0.117188f, +0.835938f,0.117188f, +0.84375f,0.117188f, +0.851563f,0.117188f, +0.859375f,0.117188f, +0.867188f,0.117188f, +0.875f,0.117188f, +0.882813f,0.117188f, +0.890625f,0.117188f, +0.898438f,0.117188f, +0.90625f,0.117188f, +0.914063f,0.117188f, +0.921875f,0.117188f, +0.929688f,0.117188f, +0.9375f,0.117188f, +0.945313f,0.117188f, +0.953125f,0.117188f, +0.960938f,0.117188f, +0.96875f,0.117188f, +0.976563f,0.117188f, +0.984375f,0.117188f, +0.992188f,0.117188f, +1.0f,0.117188f, +0.507813f,0.125f, +0.515625f,0.125f, +0.523438f,0.125f, +0.53125f,0.125f, +0.539063f,0.125f, +0.546875f,0.125f, +0.554688f,0.125f, +0.5625f,0.125f, +0.570313f,0.125f, +0.578125f,0.125f, +0.585938f,0.125f, +0.59375f,0.125f, +0.601563f,0.125f, +0.609375f,0.125f, +0.617188f,0.125f, +0.625f,0.125f, +0.632813f,0.125f, +0.640625f,0.125f, +0.648438f,0.125f, +0.65625f,0.125f, +0.664063f,0.125f, +0.671875f,0.125f, +0.679688f,0.125f, +0.6875f,0.125f, +0.695313f,0.125f, +0.703125f,0.125f, +0.710938f,0.125f, +0.71875f,0.125f, +0.726563f,0.125f, +0.734375f,0.125f, +0.742188f,0.125f, +0.75f,0.125f, +0.757813f,0.125f, +0.765625f,0.125f, +0.773438f,0.125f, +0.78125f,0.125f, +0.789063f,0.125f, +0.796875f,0.125f, +0.804688f,0.125f, +0.8125f,0.125f, +0.820313f,0.125f, +0.828125f,0.125f, +0.835938f,0.125f, +0.84375f,0.125f, +0.851563f,0.125f, +0.859375f,0.125f, +0.867188f,0.125f, +0.875f,0.125f, +0.882813f,0.125f, +0.890625f,0.125f, +0.898438f,0.125f, +0.90625f,0.125f, +0.914063f,0.125f, +0.921875f,0.125f, +0.929688f,0.125f, +0.9375f,0.125f, +0.945313f,0.125f, +0.953125f,0.125f, +0.960938f,0.125f, +0.96875f,0.125f, +0.976563f,0.125f, +0.984375f,0.125f, +0.992188f,0.125f, +1.0f,0.125f, +0.507813f,0.132813f, +0.515625f,0.132813f, +0.523438f,0.132813f, +0.53125f,0.132813f, +0.539063f,0.132813f, +0.546875f,0.132813f, +0.554688f,0.132813f, +0.5625f,0.132813f, +0.570313f,0.132813f, +0.578125f,0.132813f, +0.585938f,0.132813f, +0.59375f,0.132813f, +0.601563f,0.132813f, +0.609375f,0.132813f, +0.617188f,0.132813f, +0.625f,0.132813f, +0.632813f,0.132813f, +0.640625f,0.132813f, +0.648438f,0.132813f, +0.65625f,0.132813f, +0.664063f,0.132813f, +0.671875f,0.132813f, +0.679688f,0.132813f, +0.6875f,0.132813f, +0.695313f,0.132813f, +0.703125f,0.132813f, +0.710938f,0.132813f, +0.71875f,0.132813f, +0.726563f,0.132813f, +0.734375f,0.132813f, +0.742188f,0.132813f, +0.75f,0.132813f, +0.757813f,0.132813f, +0.765625f,0.132813f, +0.773438f,0.132813f, +0.78125f,0.132813f, +0.789063f,0.132813f, +0.796875f,0.132813f, +0.804688f,0.132813f, +0.8125f,0.132813f, +0.820313f,0.132813f, +0.828125f,0.132813f, +0.835938f,0.132813f, +0.84375f,0.132813f, +0.851563f,0.132813f, +0.859375f,0.132813f, +0.867188f,0.132813f, +0.875f,0.132813f, +0.882813f,0.132813f, +0.890625f,0.132813f, +0.898438f,0.132813f, +0.90625f,0.132813f, +0.914063f,0.132813f, +0.921875f,0.132813f, +0.929688f,0.132813f, +0.9375f,0.132813f, +0.945313f,0.132813f, +0.953125f,0.132813f, +0.960938f,0.132813f, +0.96875f,0.132813f, +0.976563f,0.132813f, +0.984375f,0.132813f, +0.992188f,0.132813f, +1.0f,0.132813f, +0.507813f,0.140625f, +0.515625f,0.140625f, +0.523438f,0.140625f, +0.53125f,0.140625f, +0.539063f,0.140625f, +0.546875f,0.140625f, +0.554688f,0.140625f, +0.5625f,0.140625f, +0.570313f,0.140625f, +0.578125f,0.140625f, +0.585938f,0.140625f, +0.59375f,0.140625f, +0.601563f,0.140625f, +0.609375f,0.140625f, +0.617188f,0.140625f, +0.625f,0.140625f, +0.632813f,0.140625f, +0.640625f,0.140625f, +0.648438f,0.140625f, +0.65625f,0.140625f, +0.664063f,0.140625f, +0.671875f,0.140625f, +0.679688f,0.140625f, +0.6875f,0.140625f, +0.695313f,0.140625f, +0.703125f,0.140625f, +0.710938f,0.140625f, +0.71875f,0.140625f, +0.726563f,0.140625f, +0.734375f,0.140625f, +0.742188f,0.140625f, +0.75f,0.140625f, +0.757813f,0.140625f, +0.765625f,0.140625f, +0.773438f,0.140625f, +0.78125f,0.140625f, +0.789063f,0.140625f, +0.796875f,0.140625f, +0.804688f,0.140625f, +0.8125f,0.140625f, +0.820313f,0.140625f, +0.828125f,0.140625f, +0.835938f,0.140625f, +0.84375f,0.140625f, +0.851563f,0.140625f, +0.859375f,0.140625f, +0.867188f,0.140625f, +0.875f,0.140625f, +0.882813f,0.140625f, +0.890625f,0.140625f, +0.898438f,0.140625f, +0.90625f,0.140625f, +0.914063f,0.140625f, +0.921875f,0.140625f, +0.929688f,0.140625f, +0.9375f,0.140625f, +0.945313f,0.140625f, +0.953125f,0.140625f, +0.960938f,0.140625f, +0.96875f,0.140625f, +0.976563f,0.140625f, +0.984375f,0.140625f, +0.992188f,0.140625f, +1.0f,0.140625f, +0.507813f,0.148438f, +0.515625f,0.148438f, +0.523438f,0.148438f, +0.53125f,0.148438f, +0.539063f,0.148438f, +0.546875f,0.148438f, +0.554688f,0.148438f, +0.5625f,0.148438f, +0.570313f,0.148438f, +0.578125f,0.148438f, +0.585938f,0.148438f, +0.59375f,0.148438f, +0.601563f,0.148438f, +0.609375f,0.148438f, +0.617188f,0.148438f, +0.625f,0.148438f, +0.632813f,0.148438f, +0.640625f,0.148438f, +0.648438f,0.148438f, +0.65625f,0.148438f, +0.664063f,0.148438f, +0.671875f,0.148438f, +0.679688f,0.148438f, +0.6875f,0.148438f, +0.695313f,0.148438f, +0.703125f,0.148438f, +0.710938f,0.148438f, +0.71875f,0.148438f, +0.726563f,0.148438f, +0.734375f,0.148438f, +0.742188f,0.148438f, +0.75f,0.148438f, +0.757813f,0.148438f, +0.765625f,0.148438f, +0.773438f,0.148438f, +0.78125f,0.148438f, +0.789063f,0.148438f, +0.796875f,0.148438f, +0.804688f,0.148438f, +0.8125f,0.148438f, +0.820313f,0.148438f, +0.828125f,0.148438f, +0.835938f,0.148438f, +0.84375f,0.148438f, +0.851563f,0.148438f, +0.859375f,0.148438f, +0.867188f,0.148438f, +0.875f,0.148438f, +0.882813f,0.148438f, +0.890625f,0.148438f, +0.898438f,0.148438f, +0.90625f,0.148438f, +0.914063f,0.148438f, +0.921875f,0.148438f, +0.929688f,0.148438f, +0.9375f,0.148438f, +0.945313f,0.148438f, +0.953125f,0.148438f, +0.960938f,0.148438f, +0.96875f,0.148438f, +0.976563f,0.148438f, +0.984375f,0.148438f, +0.992188f,0.148438f, +1.0f,0.148438f, +0.507813f,0.15625f, +0.515625f,0.15625f, +0.523438f,0.15625f, +0.53125f,0.15625f, +0.539063f,0.15625f, +0.546875f,0.15625f, +0.554688f,0.15625f, +0.5625f,0.15625f, +0.570313f,0.15625f, +0.578125f,0.15625f, +0.585938f,0.15625f, +0.59375f,0.15625f, +0.601563f,0.15625f, +0.609375f,0.15625f, +0.617188f,0.15625f, +0.625f,0.15625f, +0.632813f,0.15625f, +0.640625f,0.15625f, +0.648438f,0.15625f, +0.65625f,0.15625f, +0.664063f,0.15625f, +0.671875f,0.15625f, +0.679688f,0.15625f, +0.6875f,0.15625f, +0.695313f,0.15625f, +0.703125f,0.15625f, +0.710938f,0.15625f, +0.71875f,0.15625f, +0.726563f,0.15625f, +0.734375f,0.15625f, +0.742188f,0.15625f, +0.75f,0.15625f, +0.757813f,0.15625f, +0.765625f,0.15625f, +0.773438f,0.15625f, +0.78125f,0.15625f, +0.789063f,0.15625f, +0.796875f,0.15625f, +0.804688f,0.15625f, +0.8125f,0.15625f, +0.820313f,0.15625f, +0.828125f,0.15625f, +0.835938f,0.15625f, +0.84375f,0.15625f, +0.851563f,0.15625f, +0.859375f,0.15625f, +0.867188f,0.15625f, +0.875f,0.15625f, +0.882813f,0.15625f, +0.890625f,0.15625f, +0.898438f,0.15625f, +0.90625f,0.15625f, +0.914063f,0.15625f, +0.921875f,0.15625f, +0.929688f,0.15625f, +0.9375f,0.15625f, +0.945313f,0.15625f, +0.953125f,0.15625f, +0.960938f,0.15625f, +0.96875f,0.15625f, +0.976563f,0.15625f, +0.984375f,0.15625f, +0.992188f,0.15625f, +1.0f,0.15625f, +0.507813f,0.164063f, +0.515625f,0.164063f, +0.523438f,0.164063f, +0.53125f,0.164063f, +0.539063f,0.164063f, +0.546875f,0.164063f, +0.554688f,0.164063f, +0.5625f,0.164063f, +0.570313f,0.164063f, +0.578125f,0.164063f, +0.585938f,0.164063f, +0.59375f,0.164063f, +0.601563f,0.164063f, +0.609375f,0.164063f, +0.617188f,0.164063f, +0.625f,0.164063f, +0.632813f,0.164063f, +0.640625f,0.164063f, +0.648438f,0.164063f, +0.65625f,0.164063f, +0.664063f,0.164063f, +0.671875f,0.164063f, +0.679688f,0.164063f, +0.6875f,0.164063f, +0.695313f,0.164063f, +0.703125f,0.164063f, +0.710938f,0.164063f, +0.71875f,0.164063f, +0.726563f,0.164063f, +0.734375f,0.164063f, +0.742188f,0.164063f, +0.75f,0.164063f, +0.757813f,0.164063f, +0.765625f,0.164063f, +0.773438f,0.164063f, +0.78125f,0.164063f, +0.789063f,0.164063f, +0.796875f,0.164063f, +0.804688f,0.164063f, +0.8125f,0.164063f, +0.820313f,0.164063f, +0.828125f,0.164063f, +0.835938f,0.164063f, +0.84375f,0.164063f, +0.851563f,0.164063f, +0.859375f,0.164063f, +0.867188f,0.164063f, +0.875f,0.164063f, +0.882813f,0.164063f, +0.890625f,0.164063f, +0.898438f,0.164063f, +0.90625f,0.164063f, +0.914063f,0.164063f, +0.921875f,0.164063f, +0.929688f,0.164063f, +0.9375f,0.164063f, +0.945313f,0.164063f, +0.953125f,0.164063f, +0.960938f,0.164063f, +0.96875f,0.164063f, +0.976563f,0.164063f, +0.984375f,0.164063f, +0.992188f,0.164063f, +1.0f,0.164063f, +0.507813f,0.171875f, +0.515625f,0.171875f, +0.523438f,0.171875f, +0.53125f,0.171875f, +0.539063f,0.171875f, +0.546875f,0.171875f, +0.554688f,0.171875f, +0.5625f,0.171875f, +0.570313f,0.171875f, +0.578125f,0.171875f, +0.585938f,0.171875f, +0.59375f,0.171875f, +0.601563f,0.171875f, +0.609375f,0.171875f, +0.617188f,0.171875f, +0.625f,0.171875f, +0.632813f,0.171875f, +0.640625f,0.171875f, +0.648438f,0.171875f, +0.65625f,0.171875f, +0.664063f,0.171875f, +0.671875f,0.171875f, +0.679688f,0.171875f, +0.6875f,0.171875f, +0.695313f,0.171875f, +0.703125f,0.171875f, +0.710938f,0.171875f, +0.71875f,0.171875f, +0.726563f,0.171875f, +0.734375f,0.171875f, +0.742188f,0.171875f, +0.75f,0.171875f, +0.757813f,0.171875f, +0.765625f,0.171875f, +0.773438f,0.171875f, +0.78125f,0.171875f, +0.789063f,0.171875f, +0.796875f,0.171875f, +0.804688f,0.171875f, +0.8125f,0.171875f, +0.820313f,0.171875f, +0.828125f,0.171875f, +0.835938f,0.171875f, +0.84375f,0.171875f, +0.851563f,0.171875f, +0.859375f,0.171875f, +0.867188f,0.171875f, +0.875f,0.171875f, +0.882813f,0.171875f, +0.890625f,0.171875f, +0.898438f,0.171875f, +0.90625f,0.171875f, +0.914063f,0.171875f, +0.921875f,0.171875f, +0.929688f,0.171875f, +0.9375f,0.171875f, +0.945313f,0.171875f, +0.953125f,0.171875f, +0.960938f,0.171875f, +0.96875f,0.171875f, +0.976563f,0.171875f, +0.984375f,0.171875f, +0.992188f,0.171875f, +1.0f,0.171875f, +0.507813f,0.179688f, +0.515625f,0.179688f, +0.523438f,0.179688f, +0.53125f,0.179688f, +0.539063f,0.179688f, +0.546875f,0.179688f, +0.554688f,0.179688f, +0.5625f,0.179688f, +0.570313f,0.179688f, +0.578125f,0.179688f, +0.585938f,0.179688f, +0.59375f,0.179688f, +0.601563f,0.179688f, +0.609375f,0.179688f, +0.617188f,0.179688f, +0.625f,0.179688f, +0.632813f,0.179688f, +0.640625f,0.179688f, +0.648438f,0.179688f, +0.65625f,0.179688f, +0.664063f,0.179688f, +0.671875f,0.179688f, +0.679688f,0.179688f, +0.6875f,0.179688f, +0.695313f,0.179688f, +0.703125f,0.179688f, +0.710938f,0.179688f, +0.71875f,0.179688f, +0.726563f,0.179688f, +0.734375f,0.179688f, +0.742188f,0.179688f, +0.75f,0.179688f, +0.757813f,0.179688f, +0.765625f,0.179688f, +0.773438f,0.179688f, +0.78125f,0.179688f, +0.789063f,0.179688f, +0.796875f,0.179688f, +0.804688f,0.179688f, +0.8125f,0.179688f, +0.820313f,0.179688f, +0.828125f,0.179688f, +0.835938f,0.179688f, +0.84375f,0.179688f, +0.851563f,0.179688f, +0.859375f,0.179688f, +0.867188f,0.179688f, +0.875f,0.179688f, +0.882813f,0.179688f, +0.890625f,0.179688f, +0.898438f,0.179688f, +0.90625f,0.179688f, +0.914063f,0.179688f, +0.921875f,0.179688f, +0.929688f,0.179688f, +0.9375f,0.179688f, +0.945313f,0.179688f, +0.953125f,0.179688f, +0.960938f,0.179688f, +0.96875f,0.179688f, +0.976563f,0.179688f, +0.984375f,0.179688f, +0.992188f,0.179688f, +1.0f,0.179688f, +0.507813f,0.1875f, +0.515625f,0.1875f, +0.523438f,0.1875f, +0.53125f,0.1875f, +0.539063f,0.1875f, +0.546875f,0.1875f, +0.554688f,0.1875f, +0.5625f,0.1875f, +0.570313f,0.1875f, +0.578125f,0.1875f, +0.585938f,0.1875f, +0.59375f,0.1875f, +0.601563f,0.1875f, +0.609375f,0.1875f, +0.617188f,0.1875f, +0.625f,0.1875f, +0.632813f,0.1875f, +0.640625f,0.1875f, +0.648438f,0.1875f, +0.65625f,0.1875f, +0.664063f,0.1875f, +0.671875f,0.1875f, +0.679688f,0.1875f, +0.6875f,0.1875f, +0.695313f,0.1875f, +0.703125f,0.1875f, +0.710938f,0.1875f, +0.71875f,0.1875f, +0.726563f,0.1875f, +0.734375f,0.1875f, +0.742188f,0.1875f, +0.75f,0.1875f, +0.757813f,0.1875f, +0.765625f,0.1875f, +0.773438f,0.1875f, +0.78125f,0.1875f, +0.789063f,0.1875f, +0.796875f,0.1875f, +0.804688f,0.1875f, +0.8125f,0.1875f, +0.820313f,0.1875f, +0.828125f,0.1875f, +0.835938f,0.1875f, +0.84375f,0.1875f, +0.851563f,0.1875f, +0.859375f,0.1875f, +0.867188f,0.1875f, +0.875f,0.1875f, +0.882813f,0.1875f, +0.890625f,0.1875f, +0.898438f,0.1875f, +0.90625f,0.1875f, +0.914063f,0.1875f, +0.921875f,0.1875f, +0.929688f,0.1875f, +0.9375f,0.1875f, +0.945313f,0.1875f, +0.953125f,0.1875f, +0.960938f,0.1875f, +0.96875f,0.1875f, +0.976563f,0.1875f, +0.984375f,0.1875f, +0.992188f,0.1875f, +1.0f,0.1875f, +0.507813f,0.195313f, +0.515625f,0.195313f, +0.523438f,0.195313f, +0.53125f,0.195313f, +0.539063f,0.195313f, +0.546875f,0.195313f, +0.554688f,0.195313f, +0.5625f,0.195313f, +0.570313f,0.195313f, +0.578125f,0.195313f, +0.585938f,0.195313f, +0.59375f,0.195313f, +0.601563f,0.195313f, +0.609375f,0.195313f, +0.617188f,0.195313f, +0.625f,0.195313f, +0.632813f,0.195313f, +0.640625f,0.195313f, +0.648438f,0.195313f, +0.65625f,0.195313f, +0.664063f,0.195313f, +0.671875f,0.195313f, +0.679688f,0.195313f, +0.6875f,0.195313f, +0.695313f,0.195313f, +0.703125f,0.195313f, +0.710938f,0.195313f, +0.71875f,0.195313f, +0.726563f,0.195313f, +0.734375f,0.195313f, +0.742188f,0.195313f, +0.75f,0.195313f, +0.757813f,0.195313f, +0.765625f,0.195313f, +0.773438f,0.195313f, +0.78125f,0.195313f, +0.789063f,0.195313f, +0.796875f,0.195313f, +0.804688f,0.195313f, +0.8125f,0.195313f, +0.820313f,0.195313f, +0.828125f,0.195313f, +0.835938f,0.195313f, +0.84375f,0.195313f, +0.851563f,0.195313f, +0.859375f,0.195313f, +0.867188f,0.195313f, +0.875f,0.195313f, +0.882813f,0.195313f, +0.890625f,0.195313f, +0.898438f,0.195313f, +0.90625f,0.195313f, +0.914063f,0.195313f, +0.921875f,0.195313f, +0.929688f,0.195313f, +0.9375f,0.195313f, +0.945313f,0.195313f, +0.953125f,0.195313f, +0.960938f,0.195313f, +0.96875f,0.195313f, +0.976563f,0.195313f, +0.984375f,0.195313f, +0.992188f,0.195313f, +1.0f,0.195313f, +0.507813f,0.203125f, +0.515625f,0.203125f, +0.523438f,0.203125f, +0.53125f,0.203125f, +0.539063f,0.203125f, +0.546875f,0.203125f, +0.554688f,0.203125f, +0.5625f,0.203125f, +0.570313f,0.203125f, +0.578125f,0.203125f, +0.585938f,0.203125f, +0.59375f,0.203125f, +0.601563f,0.203125f, +0.609375f,0.203125f, +0.617188f,0.203125f, +0.625f,0.203125f, +0.632813f,0.203125f, +0.640625f,0.203125f, +0.648438f,0.203125f, +0.65625f,0.203125f, +0.664063f,0.203125f, +0.671875f,0.203125f, +0.679688f,0.203125f, +0.6875f,0.203125f, +0.695313f,0.203125f, +0.703125f,0.203125f, +0.710938f,0.203125f, +0.71875f,0.203125f, +0.726563f,0.203125f, +0.734375f,0.203125f, +0.742188f,0.203125f, +0.75f,0.203125f, +0.757813f,0.203125f, +0.765625f,0.203125f, +0.773438f,0.203125f, +0.78125f,0.203125f, +0.789063f,0.203125f, +0.796875f,0.203125f, +0.804688f,0.203125f, +0.8125f,0.203125f, +0.820313f,0.203125f, +0.828125f,0.203125f, +0.835938f,0.203125f, +0.84375f,0.203125f, +0.851563f,0.203125f, +0.859375f,0.203125f, +0.867188f,0.203125f, +0.875f,0.203125f, +0.882813f,0.203125f, +0.890625f,0.203125f, +0.898438f,0.203125f, +0.90625f,0.203125f, +0.914063f,0.203125f, +0.921875f,0.203125f, +0.929688f,0.203125f, +0.9375f,0.203125f, +0.945313f,0.203125f, +0.953125f,0.203125f, +0.960938f,0.203125f, +0.96875f,0.203125f, +0.976563f,0.203125f, +0.984375f,0.203125f, +0.992188f,0.203125f, +1.0f,0.203125f, +0.507813f,0.210938f, +0.515625f,0.210938f, +0.523438f,0.210938f, +0.53125f,0.210938f, +0.539063f,0.210938f, +0.546875f,0.210938f, +0.554688f,0.210938f, +0.5625f,0.210938f, +0.570313f,0.210938f, +0.578125f,0.210938f, +0.585938f,0.210938f, +0.59375f,0.210938f, +0.601563f,0.210938f, +0.609375f,0.210938f, +0.617188f,0.210938f, +0.625f,0.210938f, +0.632813f,0.210938f, +0.640625f,0.210938f, +0.648438f,0.210938f, +0.65625f,0.210938f, +0.664063f,0.210938f, +0.671875f,0.210938f, +0.679688f,0.210938f, +0.6875f,0.210938f, +0.695313f,0.210938f, +0.703125f,0.210938f, +0.710938f,0.210938f, +0.71875f,0.210938f, +0.726563f,0.210938f, +0.734375f,0.210938f, +0.742188f,0.210938f, +0.75f,0.210938f, +0.757813f,0.210938f, +0.765625f,0.210938f, +0.773438f,0.210938f, +0.78125f,0.210938f, +0.789063f,0.210938f, +0.796875f,0.210938f, +0.804688f,0.210938f, +0.8125f,0.210938f, +0.820313f,0.210938f, +0.828125f,0.210938f, +0.835938f,0.210938f, +0.84375f,0.210938f, +0.851563f,0.210938f, +0.859375f,0.210938f, +0.867188f,0.210938f, +0.875f,0.210938f, +0.882813f,0.210938f, +0.890625f,0.210938f, +0.898438f,0.210938f, +0.90625f,0.210938f, +0.914063f,0.210938f, +0.921875f,0.210938f, +0.929688f,0.210938f, +0.9375f,0.210938f, +0.945313f,0.210938f, +0.953125f,0.210938f, +0.960938f,0.210938f, +0.96875f,0.210938f, +0.976563f,0.210938f, +0.984375f,0.210938f, +0.992188f,0.210938f, +1.0f,0.210938f, +0.507813f,0.21875f, +0.515625f,0.21875f, +0.523438f,0.21875f, +0.53125f,0.21875f, +0.539063f,0.21875f, +0.546875f,0.21875f, +0.554688f,0.21875f, +0.5625f,0.21875f, +0.570313f,0.21875f, +0.578125f,0.21875f, +0.585938f,0.21875f, +0.59375f,0.21875f, +0.601563f,0.21875f, +0.609375f,0.21875f, +0.617188f,0.21875f, +0.625f,0.21875f, +0.632813f,0.21875f, +0.640625f,0.21875f, +0.648438f,0.21875f, +0.65625f,0.21875f, +0.664063f,0.21875f, +0.671875f,0.21875f, +0.679688f,0.21875f, +0.6875f,0.21875f, +0.695313f,0.21875f, +0.703125f,0.21875f, +0.710938f,0.21875f, +0.71875f,0.21875f, +0.726563f,0.21875f, +0.734375f,0.21875f, +0.742188f,0.21875f, +0.75f,0.21875f, +0.757813f,0.21875f, +0.765625f,0.21875f, +0.773438f,0.21875f, +0.78125f,0.21875f, +0.789063f,0.21875f, +0.796875f,0.21875f, +0.804688f,0.21875f, +0.8125f,0.21875f, +0.820313f,0.21875f, +0.828125f,0.21875f, +0.835938f,0.21875f, +0.84375f,0.21875f, +0.851563f,0.21875f, +0.859375f,0.21875f, +0.867188f,0.21875f, +0.875f,0.21875f, +0.882813f,0.21875f, +0.890625f,0.21875f, +0.898438f,0.21875f, +0.90625f,0.21875f, +0.914063f,0.21875f, +0.921875f,0.21875f, +0.929688f,0.21875f, +0.9375f,0.21875f, +0.945313f,0.21875f, +0.953125f,0.21875f, +0.960938f,0.21875f, +0.96875f,0.21875f, +0.976563f,0.21875f, +0.984375f,0.21875f, +0.992188f,0.21875f, +1.0f,0.21875f, +0.507813f,0.226563f, +0.515625f,0.226563f, +0.523438f,0.226563f, +0.53125f,0.226563f, +0.539063f,0.226563f, +0.546875f,0.226563f, +0.554688f,0.226563f, +0.5625f,0.226563f, +0.570313f,0.226563f, +0.578125f,0.226563f, +0.585938f,0.226563f, +0.59375f,0.226563f, +0.601563f,0.226563f, +0.609375f,0.226563f, +0.617188f,0.226563f, +0.625f,0.226563f, +0.632813f,0.226563f, +0.640625f,0.226563f, +0.648438f,0.226563f, +0.65625f,0.226563f, +0.664063f,0.226563f, +0.671875f,0.226563f, +0.679688f,0.226563f, +0.6875f,0.226563f, +0.695313f,0.226563f, +0.703125f,0.226563f, +0.710938f,0.226563f, +0.71875f,0.226563f, +0.726563f,0.226563f, +0.734375f,0.226563f, +0.742188f,0.226563f, +0.75f,0.226563f, +0.757813f,0.226563f, +0.765625f,0.226563f, +0.773438f,0.226563f, +0.78125f,0.226563f, +0.789063f,0.226563f, +0.796875f,0.226563f, +0.804688f,0.226563f, +0.8125f,0.226563f, +0.820313f,0.226563f, +0.828125f,0.226563f, +0.835938f,0.226563f, +0.84375f,0.226563f, +0.851563f,0.226563f, +0.859375f,0.226563f, +0.867188f,0.226563f, +0.875f,0.226563f, +0.882813f,0.226563f, +0.890625f,0.226563f, +0.898438f,0.226563f, +0.90625f,0.226563f, +0.914063f,0.226563f, +0.921875f,0.226563f, +0.929688f,0.226563f, +0.9375f,0.226563f, +0.945313f,0.226563f, +0.953125f,0.226563f, +0.960938f,0.226563f, +0.96875f,0.226563f, +0.976563f,0.226563f, +0.984375f,0.226563f, +0.992188f,0.226563f, +1.0f,0.226563f, +0.507813f,0.234375f, +0.515625f,0.234375f, +0.523438f,0.234375f, +0.53125f,0.234375f, +0.539063f,0.234375f, +0.546875f,0.234375f, +0.554688f,0.234375f, +0.5625f,0.234375f, +0.570313f,0.234375f, +0.578125f,0.234375f, +0.585938f,0.234375f, +0.59375f,0.234375f, +0.601563f,0.234375f, +0.609375f,0.234375f, +0.617188f,0.234375f, +0.625f,0.234375f, +0.632813f,0.234375f, +0.640625f,0.234375f, +0.648438f,0.234375f, +0.65625f,0.234375f, +0.664063f,0.234375f, +0.671875f,0.234375f, +0.679688f,0.234375f, +0.6875f,0.234375f, +0.695313f,0.234375f, +0.703125f,0.234375f, +0.710938f,0.234375f, +0.71875f,0.234375f, +0.726563f,0.234375f, +0.734375f,0.234375f, +0.742188f,0.234375f, +0.75f,0.234375f, +0.757813f,0.234375f, +0.765625f,0.234375f, +0.773438f,0.234375f, +0.78125f,0.234375f, +0.789063f,0.234375f, +0.796875f,0.234375f, +0.804688f,0.234375f, +0.8125f,0.234375f, +0.820313f,0.234375f, +0.828125f,0.234375f, +0.835938f,0.234375f, +0.84375f,0.234375f, +0.851563f,0.234375f, +0.859375f,0.234375f, +0.867188f,0.234375f, +0.875f,0.234375f, +0.882813f,0.234375f, +0.890625f,0.234375f, +0.898438f,0.234375f, +0.90625f,0.234375f, +0.914063f,0.234375f, +0.921875f,0.234375f, +0.929688f,0.234375f, +0.9375f,0.234375f, +0.945313f,0.234375f, +0.953125f,0.234375f, +0.960938f,0.234375f, +0.96875f,0.234375f, +0.976563f,0.234375f, +0.984375f,0.234375f, +0.992188f,0.234375f, +1.0f,0.234375f, +0.507813f,0.242188f, +0.515625f,0.242188f, +0.523438f,0.242188f, +0.53125f,0.242188f, +0.539063f,0.242188f, +0.546875f,0.242188f, +0.554688f,0.242188f, +0.5625f,0.242188f, +0.570313f,0.242188f, +0.578125f,0.242188f, +0.585938f,0.242188f, +0.59375f,0.242188f, +0.601563f,0.242188f, +0.609375f,0.242188f, +0.617188f,0.242188f, +0.625f,0.242188f, +0.632813f,0.242188f, +0.640625f,0.242188f, +0.648438f,0.242188f, +0.65625f,0.242188f, +0.664063f,0.242188f, +0.671875f,0.242188f, +0.679688f,0.242188f, +0.6875f,0.242188f, +0.695313f,0.242188f, +0.703125f,0.242188f, +0.710938f,0.242188f, +0.71875f,0.242188f, +0.726563f,0.242188f, +0.734375f,0.242188f, +0.742188f,0.242188f, +0.75f,0.242188f, +0.757813f,0.242188f, +0.765625f,0.242188f, +0.773438f,0.242188f, +0.78125f,0.242188f, +0.789063f,0.242188f, +0.796875f,0.242188f, +0.804688f,0.242188f, +0.8125f,0.242188f, +0.820313f,0.242188f, +0.828125f,0.242188f, +0.835938f,0.242188f, +0.84375f,0.242188f, +0.851563f,0.242188f, +0.859375f,0.242188f, +0.867188f,0.242188f, +0.875f,0.242188f, +0.882813f,0.242188f, +0.890625f,0.242188f, +0.898438f,0.242188f, +0.90625f,0.242188f, +0.914063f,0.242188f, +0.921875f,0.242188f, +0.929688f,0.242188f, +0.9375f,0.242188f, +0.945313f,0.242188f, +0.953125f,0.242188f, +0.960938f,0.242188f, +0.96875f,0.242188f, +0.976563f,0.242188f, +0.984375f,0.242188f, +0.992188f,0.242188f, +1.0f,0.242188f, +}; + +unsigned short Landscape01Idx[] = { +0,1,2, +3,2,1, +2,3,4, +5,4,3, +4,5,6, +7,6,5, +6,7,8, +9,8,7, +8,9,10, +11,10,9, +10,11,12, +13,12,11, +12,13,14, +15,14,13, +14,15,16, +17,16,15, +16,17,18, +19,18,17, +18,19,20, +21,20,19, +20,21,22, +23,22,21, +22,23,24, +25,24,23, +24,25,26, +27,26,25, +26,27,28, +29,28,27, +28,29,30, +31,30,29, +30,31,32, +33,32,31, +32,33,34, +35,34,33, +34,35,36, +37,36,35, +36,37,38, +39,38,37, +38,39,40, +41,40,39, +40,41,42, +43,42,41, +42,43,44, +45,44,43, +44,45,46, +47,46,45, +46,47,48, +49,48,47, +48,49,50, +51,50,49, +50,51,52, +53,52,51, +52,53,54, +55,54,53, +54,55,56, +57,56,55, +56,57,58, +59,58,57, +58,59,60, +61,60,59, +60,61,62, +63,62,61, +62,63,64, +65,64,63, +64,65,66, +67,66,65, +66,67,68, +69,68,67, +68,69,70, +71,70,69, +70,71,72, +73,72,71, +72,73,74, +75,74,73, +74,75,76, +77,76,75, +76,77,78, +79,78,77, +78,79,80, +81,80,79, +80,81,82, +83,82,81, +82,83,84, +85,84,83, +84,85,86, +87,86,85, +86,87,88, +89,88,87, +88,89,90, +91,90,89, +90,91,92, +93,92,91, +92,93,94, +95,94,93, +94,95,96, +97,96,95, +96,97,98, +99,98,97, +98,99,100, +101,100,99, +100,101,102, +103,102,101, +102,103,104, +105,104,103, +104,105,106, +107,106,105, +106,107,108, +109,108,107, +108,109,110, +111,110,109, +110,111,112, +113,112,111, +112,113,114, +115,114,113, +114,115,116, +117,116,115, +116,117,118, +119,118,117, +118,119,120, +121,120,119, +120,121,122, +123,122,121, +122,123,124, +125,124,123, +124,125,126, +127,126,125, +128,0,129, +2,129,0, +129,2,130, +4,130,2, +130,4,131, +6,131,4, +131,6,132, +8,132,6, +132,8,133, +10,133,8, +133,10,134, +12,134,10, +134,12,135, +14,135,12, +135,14,136, +16,136,14, +136,16,137, +18,137,16, +137,18,138, +20,138,18, +138,20,139, +22,139,20, +139,22,140, +24,140,22, +140,24,141, +26,141,24, +141,26,142, +28,142,26, +142,28,143, +30,143,28, +143,30,144, +32,144,30, +144,32,145, +34,145,32, +145,34,146, +36,146,34, +146,36,147, +38,147,36, +147,38,148, +40,148,38, +148,40,149, +42,149,40, +149,42,150, +44,150,42, +150,44,151, +46,151,44, +151,46,152, +48,152,46, +152,48,153, +50,153,48, +153,50,154, +52,154,50, +154,52,155, +54,155,52, +155,54,156, +56,156,54, +156,56,157, +58,157,56, +157,58,158, +60,158,58, +158,60,159, +62,159,60, +159,62,160, +64,160,62, +160,64,161, +66,161,64, +161,66,162, +68,162,66, +162,68,163, +70,163,68, +163,70,164, +72,164,70, +164,72,165, +74,165,72, +165,74,166, +76,166,74, +166,76,167, +78,167,76, +167,78,168, +80,168,78, +168,80,169, +82,169,80, +169,82,170, +84,170,82, +170,84,171, +86,171,84, +171,86,172, +88,172,86, +172,88,173, +90,173,88, +173,90,174, +92,174,90, +174,92,175, +94,175,92, +175,94,176, +96,176,94, +176,96,177, +98,177,96, +177,98,178, +100,178,98, +178,100,179, +102,179,100, +179,102,180, +104,180,102, +180,104,181, +106,181,104, +181,106,182, +108,182,106, +182,108,183, +110,183,108, +183,110,184, +112,184,110, +184,112,185, +114,185,112, +185,114,186, +116,186,114, +186,116,187, +118,187,116, +187,118,188, +120,188,118, +188,120,189, +122,189,120, +189,122,190, +124,190,122, +190,124,191, +126,191,124, +192,128,193, +129,193,128, +193,129,194, +130,194,129, +194,130,195, +131,195,130, +195,131,196, +132,196,131, +196,132,197, +133,197,132, +197,133,198, +134,198,133, +198,134,199, +135,199,134, +199,135,200, +136,200,135, +200,136,201, +137,201,136, +201,137,202, +138,202,137, +202,138,203, +139,203,138, +203,139,204, +140,204,139, +204,140,205, +141,205,140, +205,141,206, +142,206,141, +206,142,207, +143,207,142, +207,143,208, +144,208,143, +208,144,209, +145,209,144, +209,145,210, +146,210,145, +210,146,211, +147,211,146, +211,147,212, +148,212,147, +212,148,213, +149,213,148, +213,149,214, +150,214,149, +214,150,215, +151,215,150, +215,151,216, +152,216,151, +216,152,217, +153,217,152, +217,153,218, +154,218,153, +218,154,219, +155,219,154, +219,155,220, +156,220,155, +220,156,221, +157,221,156, +221,157,222, +158,222,157, +222,158,223, +159,223,158, +223,159,224, +160,224,159, +224,160,225, +161,225,160, +225,161,226, +162,226,161, +226,162,227, +163,227,162, +227,163,228, +164,228,163, +228,164,229, +165,229,164, +229,165,230, +166,230,165, +230,166,231, +167,231,166, +231,167,232, +168,232,167, +232,168,233, +169,233,168, +233,169,234, +170,234,169, +234,170,235, +171,235,170, +235,171,236, +172,236,171, +236,172,237, +173,237,172, +237,173,238, +174,238,173, +238,174,239, +175,239,174, +239,175,240, +176,240,175, +240,176,241, +177,241,176, +241,177,242, +178,242,177, +242,178,243, +179,243,178, +243,179,244, +180,244,179, +244,180,245, +181,245,180, +245,181,246, +182,246,181, +246,182,247, +183,247,182, +247,183,248, +184,248,183, +248,184,249, +185,249,184, +249,185,250, +186,250,185, +250,186,251, +187,251,186, +251,187,252, +188,252,187, +252,188,253, +189,253,188, +253,189,254, +190,254,189, +254,190,255, +191,255,190, +256,192,257, +193,257,192, +257,193,258, +194,258,193, +258,194,259, +195,259,194, +259,195,260, +196,260,195, +260,196,261, +197,261,196, +261,197,262, +198,262,197, +262,198,263, +199,263,198, +263,199,264, +200,264,199, +264,200,265, +201,265,200, +265,201,266, +202,266,201, +266,202,267, +203,267,202, +267,203,268, +204,268,203, +268,204,269, +205,269,204, +269,205,270, +206,270,205, +270,206,271, +207,271,206, +271,207,272, +208,272,207, +272,208,273, +209,273,208, +273,209,274, +210,274,209, +274,210,275, +211,275,210, +275,211,276, +212,276,211, +276,212,277, +213,277,212, +277,213,278, +214,278,213, +278,214,279, +215,279,214, +279,215,280, +216,280,215, +280,216,281, +217,281,216, +281,217,282, +218,282,217, +282,218,283, +219,283,218, +283,219,284, +220,284,219, +284,220,285, +221,285,220, +285,221,286, +222,286,221, +286,222,287, +223,287,222, +287,223,288, +224,288,223, +288,224,289, +225,289,224, +289,225,290, +226,290,225, +290,226,291, +227,291,226, +291,227,292, +228,292,227, +292,228,293, +229,293,228, +293,229,294, +230,294,229, +294,230,295, +231,295,230, +295,231,296, +232,296,231, +296,232,297, +233,297,232, +297,233,298, +234,298,233, +298,234,299, +235,299,234, +299,235,300, +236,300,235, +300,236,301, +237,301,236, +301,237,302, +238,302,237, +302,238,303, +239,303,238, +303,239,304, +240,304,239, +304,240,305, +241,305,240, +305,241,306, +242,306,241, +306,242,307, +243,307,242, +307,243,308, +244,308,243, +308,244,309, +245,309,244, +309,245,310, +246,310,245, +310,246,311, +247,311,246, +311,247,312, +248,312,247, +312,248,313, +249,313,248, +313,249,314, +250,314,249, +314,250,315, +251,315,250, +315,251,316, +252,316,251, +316,252,317, +253,317,252, +317,253,318, +254,318,253, +318,254,319, +255,319,254, +320,256,321, +257,321,256, +321,257,322, +258,322,257, +322,258,323, +259,323,258, +323,259,324, +260,324,259, +324,260,325, +261,325,260, +325,261,326, +262,326,261, +326,262,327, +263,327,262, +327,263,328, +264,328,263, +328,264,329, +265,329,264, +329,265,330, +266,330,265, +330,266,331, +267,331,266, +331,267,332, +268,332,267, +332,268,333, +269,333,268, +333,269,334, +270,334,269, +334,270,335, +271,335,270, +335,271,336, +272,336,271, +336,272,337, +273,337,272, +337,273,338, +274,338,273, +338,274,339, +275,339,274, +339,275,340, +276,340,275, +340,276,341, +277,341,276, +341,277,342, +278,342,277, +342,278,343, +279,343,278, +343,279,344, +280,344,279, +344,280,345, +281,345,280, +345,281,346, +282,346,281, +346,282,347, +283,347,282, +347,283,348, +284,348,283, +348,284,349, +285,349,284, +349,285,350, +286,350,285, +350,286,351, +287,351,286, +351,287,352, +288,352,287, +352,288,353, +289,353,288, +353,289,354, +290,354,289, +354,290,355, +291,355,290, +355,291,356, +292,356,291, +356,292,357, +293,357,292, +357,293,358, +294,358,293, +358,294,359, +295,359,294, +359,295,360, +296,360,295, +360,296,361, +297,361,296, +361,297,362, +298,362,297, +362,298,363, +299,363,298, +363,299,364, +300,364,299, +364,300,365, +301,365,300, +365,301,366, +302,366,301, +366,302,367, +303,367,302, +367,303,368, +304,368,303, +368,304,369, +305,369,304, +369,305,370, +306,370,305, +370,306,371, +307,371,306, +371,307,372, +308,372,307, +372,308,373, +309,373,308, +373,309,374, +310,374,309, +374,310,375, +311,375,310, +375,311,376, +312,376,311, +376,312,377, +313,377,312, +377,313,378, +314,378,313, +378,314,379, +315,379,314, +379,315,380, +316,380,315, +380,316,381, +317,381,316, +381,317,382, +318,382,317, +382,318,383, +319,383,318, +384,320,385, +321,385,320, +385,321,386, +322,386,321, +386,322,387, +323,387,322, +387,323,388, +324,388,323, +388,324,389, +325,389,324, +389,325,390, +326,390,325, +390,326,391, +327,391,326, +391,327,392, +328,392,327, +392,328,393, +329,393,328, +393,329,394, +330,394,329, +394,330,395, +331,395,330, +395,331,396, +332,396,331, +396,332,397, +333,397,332, +397,333,398, +334,398,333, +398,334,399, +335,399,334, +399,335,400, +336,400,335, +400,336,401, +337,401,336, +401,337,402, +338,402,337, +402,338,403, +339,403,338, +403,339,404, +340,404,339, +404,340,405, +341,405,340, +405,341,406, +342,406,341, +406,342,407, +343,407,342, +407,343,408, +344,408,343, +408,344,409, +345,409,344, +409,345,410, +346,410,345, +410,346,411, +347,411,346, +411,347,412, +348,412,347, +412,348,413, +349,413,348, +413,349,414, +350,414,349, +414,350,415, +351,415,350, +415,351,416, +352,416,351, +416,352,417, +353,417,352, +417,353,418, +354,418,353, +418,354,419, +355,419,354, +419,355,420, +356,420,355, +420,356,421, +357,421,356, +421,357,422, +358,422,357, +422,358,423, +359,423,358, +423,359,424, +360,424,359, +424,360,425, +361,425,360, +425,361,426, +362,426,361, +426,362,427, +363,427,362, +427,363,428, +364,428,363, +428,364,429, +365,429,364, +429,365,430, +366,430,365, +430,366,431, +367,431,366, +431,367,432, +368,432,367, +432,368,433, +369,433,368, +433,369,434, +370,434,369, +434,370,435, +371,435,370, +435,371,436, +372,436,371, +436,372,437, +373,437,372, +437,373,438, +374,438,373, +438,374,439, +375,439,374, +439,375,440, +376,440,375, +440,376,441, +377,441,376, +441,377,442, +378,442,377, +442,378,443, +379,443,378, +443,379,444, +380,444,379, +444,380,445, +381,445,380, +445,381,446, +382,446,381, +446,382,447, +383,447,382, +448,384,449, +385,449,384, +449,385,450, +386,450,385, +450,386,451, +387,451,386, +451,387,452, +388,452,387, +452,388,453, +389,453,388, +453,389,454, +390,454,389, +454,390,455, +391,455,390, +455,391,456, +392,456,391, +456,392,457, +393,457,392, +457,393,458, +394,458,393, +458,394,459, +395,459,394, +459,395,460, +396,460,395, +460,396,461, +397,461,396, +461,397,462, +398,462,397, +462,398,463, +399,463,398, +463,399,464, +400,464,399, +464,400,465, +401,465,400, +465,401,466, +402,466,401, +466,402,467, +403,467,402, +467,403,468, +404,468,403, +468,404,469, +405,469,404, +469,405,470, +406,470,405, +470,406,471, +407,471,406, +471,407,472, +408,472,407, +472,408,473, +409,473,408, +473,409,474, +410,474,409, +474,410,475, +411,475,410, +475,411,476, +412,476,411, +476,412,477, +413,477,412, +477,413,478, +414,478,413, +478,414,479, +415,479,414, +479,415,480, +416,480,415, +480,416,481, +417,481,416, +481,417,482, +418,482,417, +482,418,483, +419,483,418, +483,419,484, +420,484,419, +484,420,485, +421,485,420, +485,421,486, +422,486,421, +486,422,487, +423,487,422, +487,423,488, +424,488,423, +488,424,489, +425,489,424, +489,425,490, +426,490,425, +490,426,491, +427,491,426, +491,427,492, +428,492,427, +492,428,493, +429,493,428, +493,429,494, +430,494,429, +494,430,495, +431,495,430, +495,431,496, +432,496,431, +496,432,497, +433,497,432, +497,433,498, +434,498,433, +498,434,499, +435,499,434, +499,435,500, +436,500,435, +500,436,501, +437,501,436, +501,437,502, +438,502,437, +502,438,503, +439,503,438, +503,439,504, +440,504,439, +504,440,505, +441,505,440, +505,441,506, +442,506,441, +506,442,507, +443,507,442, +507,443,508, +444,508,443, +508,444,509, +445,509,444, +509,445,510, +446,510,445, +510,446,511, +447,511,446, +512,448,513, +449,513,448, +513,449,514, +450,514,449, +514,450,515, +451,515,450, +515,451,516, +452,516,451, +516,452,517, +453,517,452, +517,453,518, +454,518,453, +518,454,519, +455,519,454, +519,455,520, +456,520,455, +520,456,521, +457,521,456, +521,457,522, +458,522,457, +522,458,523, +459,523,458, +523,459,524, +460,524,459, +524,460,525, +461,525,460, +525,461,526, +462,526,461, +526,462,527, +463,527,462, +527,463,528, +464,528,463, +528,464,529, +465,529,464, +529,465,530, +466,530,465, +530,466,531, +467,531,466, +531,467,532, +468,532,467, +532,468,533, +469,533,468, +533,469,534, +470,534,469, +534,470,535, +471,535,470, +535,471,536, +472,536,471, +536,472,537, +473,537,472, +537,473,538, +474,538,473, +538,474,539, +475,539,474, +539,475,540, +476,540,475, +540,476,541, +477,541,476, +541,477,542, +478,542,477, +542,478,543, +479,543,478, +543,479,544, +480,544,479, +544,480,545, +481,545,480, +545,481,546, +482,546,481, +546,482,547, +483,547,482, +547,483,548, +484,548,483, +548,484,549, +485,549,484, +549,485,550, +486,550,485, +550,486,551, +487,551,486, +551,487,552, +488,552,487, +552,488,553, +489,553,488, +553,489,554, +490,554,489, +554,490,555, +491,555,490, +555,491,556, +492,556,491, +556,492,557, +493,557,492, +557,493,558, +494,558,493, +558,494,559, +495,559,494, +559,495,560, +496,560,495, +560,496,561, +497,561,496, +561,497,562, +498,562,497, +562,498,563, +499,563,498, +563,499,564, +500,564,499, +564,500,565, +501,565,500, +565,501,566, +502,566,501, +566,502,567, +503,567,502, +567,503,568, +504,568,503, +568,504,569, +505,569,504, +569,505,570, +506,570,505, +570,506,571, +507,571,506, +571,507,572, +508,572,507, +572,508,573, +509,573,508, +573,509,574, +510,574,509, +574,510,575, +511,575,510, +576,512,577, +513,577,512, +577,513,578, +514,578,513, +578,514,579, +515,579,514, +579,515,580, +516,580,515, +580,516,581, +517,581,516, +581,517,582, +518,582,517, +582,518,583, +519,583,518, +583,519,584, +520,584,519, +584,520,585, +521,585,520, +585,521,586, +522,586,521, +586,522,587, +523,587,522, +587,523,588, +524,588,523, +588,524,589, +525,589,524, +589,525,590, +526,590,525, +590,526,591, +527,591,526, +591,527,592, +528,592,527, +592,528,593, +529,593,528, +593,529,594, +530,594,529, +594,530,595, +531,595,530, +595,531,596, +532,596,531, +596,532,597, +533,597,532, +597,533,598, +534,598,533, +598,534,599, +535,599,534, +599,535,600, +536,600,535, +600,536,601, +537,601,536, +601,537,602, +538,602,537, +602,538,603, +539,603,538, +603,539,604, +540,604,539, +604,540,605, +541,605,540, +605,541,606, +542,606,541, +606,542,607, +543,607,542, +607,543,608, +544,608,543, +608,544,609, +545,609,544, +609,545,610, +546,610,545, +610,546,611, +547,611,546, +611,547,612, +548,612,547, +612,548,613, +549,613,548, +613,549,614, +550,614,549, +614,550,615, +551,615,550, +615,551,616, +552,616,551, +616,552,617, +553,617,552, +617,553,618, +554,618,553, +618,554,619, +555,619,554, +619,555,620, +556,620,555, +620,556,621, +557,621,556, +621,557,622, +558,622,557, +622,558,623, +559,623,558, +623,559,624, +560,624,559, +624,560,625, +561,625,560, +625,561,626, +562,626,561, +626,562,627, +563,627,562, +627,563,628, +564,628,563, +628,564,629, +565,629,564, +629,565,630, +566,630,565, +630,566,631, +567,631,566, +631,567,632, +568,632,567, +632,568,633, +569,633,568, +633,569,634, +570,634,569, +634,570,635, +571,635,570, +635,571,636, +572,636,571, +636,572,637, +573,637,572, +637,573,638, +574,638,573, +638,574,639, +575,639,574, +640,576,641, +577,641,576, +641,577,642, +578,642,577, +642,578,643, +579,643,578, +643,579,644, +580,644,579, +644,580,645, +581,645,580, +645,581,646, +582,646,581, +646,582,647, +583,647,582, +647,583,648, +584,648,583, +648,584,649, +585,649,584, +649,585,650, +586,650,585, +650,586,651, +587,651,586, +651,587,652, +588,652,587, +652,588,653, +589,653,588, +653,589,654, +590,654,589, +654,590,655, +591,655,590, +655,591,656, +592,656,591, +656,592,657, +593,657,592, +657,593,658, +594,658,593, +658,594,659, +595,659,594, +659,595,660, +596,660,595, +660,596,661, +597,661,596, +661,597,662, +598,662,597, +662,598,663, +599,663,598, +663,599,664, +600,664,599, +664,600,665, +601,665,600, +665,601,666, +602,666,601, +666,602,667, +603,667,602, +667,603,668, +604,668,603, +668,604,669, +605,669,604, +669,605,670, +606,670,605, +670,606,671, +607,671,606, +671,607,672, +608,672,607, +672,608,673, +609,673,608, +673,609,674, +610,674,609, +674,610,675, +611,675,610, +675,611,676, +612,676,611, +676,612,677, +613,677,612, +677,613,678, +614,678,613, +678,614,679, +615,679,614, +679,615,680, +616,680,615, +680,616,681, +617,681,616, +681,617,682, +618,682,617, +682,618,683, +619,683,618, +683,619,684, +620,684,619, +684,620,685, +621,685,620, +685,621,686, +622,686,621, +686,622,687, +623,687,622, +687,623,688, +624,688,623, +688,624,689, +625,689,624, +689,625,690, +626,690,625, +690,626,691, +627,691,626, +691,627,692, +628,692,627, +692,628,693, +629,693,628, +693,629,694, +630,694,629, +694,630,695, +631,695,630, +695,631,696, +632,696,631, +696,632,697, +633,697,632, +697,633,698, +634,698,633, +698,634,699, +635,699,634, +699,635,700, +636,700,635, +700,636,701, +637,701,636, +701,637,702, +638,702,637, +702,638,703, +639,703,638, +704,640,705, +641,705,640, +705,641,706, +642,706,641, +706,642,707, +643,707,642, +707,643,708, +644,708,643, +708,644,709, +645,709,644, +709,645,710, +646,710,645, +710,646,711, +647,711,646, +711,647,712, +648,712,647, +712,648,713, +649,713,648, +713,649,714, +650,714,649, +714,650,715, +651,715,650, +715,651,716, +652,716,651, +716,652,717, +653,717,652, +717,653,718, +654,718,653, +718,654,719, +655,719,654, +719,655,720, +656,720,655, +720,656,721, +657,721,656, +721,657,722, +658,722,657, +722,658,723, +659,723,658, +723,659,724, +660,724,659, +724,660,725, +661,725,660, +725,661,726, +662,726,661, +726,662,727, +663,727,662, +727,663,728, +664,728,663, +728,664,729, +665,729,664, +729,665,730, +666,730,665, +730,666,731, +667,731,666, +731,667,732, +668,732,667, +732,668,733, +669,733,668, +733,669,734, +670,734,669, +734,670,735, +671,735,670, +735,671,736, +672,736,671, +736,672,737, +673,737,672, +737,673,738, +674,738,673, +738,674,739, +675,739,674, +739,675,740, +676,740,675, +740,676,741, +677,741,676, +741,677,742, +678,742,677, +742,678,743, +679,743,678, +743,679,744, +680,744,679, +744,680,745, +681,745,680, +745,681,746, +682,746,681, +746,682,747, +683,747,682, +747,683,748, +684,748,683, +748,684,749, +685,749,684, +749,685,750, +686,750,685, +750,686,751, +687,751,686, +751,687,752, +688,752,687, +752,688,753, +689,753,688, +753,689,754, +690,754,689, +754,690,755, +691,755,690, +755,691,756, +692,756,691, +756,692,757, +693,757,692, +757,693,758, +694,758,693, +758,694,759, +695,759,694, +759,695,760, +696,760,695, +760,696,761, +697,761,696, +761,697,762, +698,762,697, +762,698,763, +699,763,698, +763,699,764, +700,764,699, +764,700,765, +701,765,700, +765,701,766, +702,766,701, +766,702,767, +703,767,702, +768,704,769, +705,769,704, +769,705,770, +706,770,705, +770,706,771, +707,771,706, +771,707,772, +708,772,707, +772,708,773, +709,773,708, +773,709,774, +710,774,709, +774,710,775, +711,775,710, +775,711,776, +712,776,711, +776,712,777, +713,777,712, +777,713,778, +714,778,713, +778,714,779, +715,779,714, +779,715,780, +716,780,715, +780,716,781, +717,781,716, +781,717,782, +718,782,717, +782,718,783, +719,783,718, +783,719,784, +720,784,719, +784,720,785, +721,785,720, +785,721,786, +722,786,721, +786,722,787, +723,787,722, +787,723,788, +724,788,723, +788,724,789, +725,789,724, +789,725,790, +726,790,725, +790,726,791, +727,791,726, +791,727,792, +728,792,727, +792,728,793, +729,793,728, +793,729,794, +730,794,729, +794,730,795, +731,795,730, +795,731,796, +732,796,731, +796,732,797, +733,797,732, +797,733,798, +734,798,733, +798,734,799, +735,799,734, +799,735,800, +736,800,735, +800,736,801, +737,801,736, +801,737,802, +738,802,737, +802,738,803, +739,803,738, +803,739,804, +740,804,739, +804,740,805, +741,805,740, +805,741,806, +742,806,741, +806,742,807, +743,807,742, +807,743,808, +744,808,743, +808,744,809, +745,809,744, +809,745,810, +746,810,745, +810,746,811, +747,811,746, +811,747,812, +748,812,747, +812,748,813, +749,813,748, +813,749,814, +750,814,749, +814,750,815, +751,815,750, +815,751,816, +752,816,751, +816,752,817, +753,817,752, +817,753,818, +754,818,753, +818,754,819, +755,819,754, +819,755,820, +756,820,755, +820,756,821, +757,821,756, +821,757,822, +758,822,757, +822,758,823, +759,823,758, +823,759,824, +760,824,759, +824,760,825, +761,825,760, +825,761,826, +762,826,761, +826,762,827, +763,827,762, +827,763,828, +764,828,763, +828,764,829, +765,829,764, +829,765,830, +766,830,765, +830,766,831, +767,831,766, +832,768,833, +769,833,768, +833,769,834, +770,834,769, +834,770,835, +771,835,770, +835,771,836, +772,836,771, +836,772,837, +773,837,772, +837,773,838, +774,838,773, +838,774,839, +775,839,774, +839,775,840, +776,840,775, +840,776,841, +777,841,776, +841,777,842, +778,842,777, +842,778,843, +779,843,778, +843,779,844, +780,844,779, +844,780,845, +781,845,780, +845,781,846, +782,846,781, +846,782,847, +783,847,782, +847,783,848, +784,848,783, +848,784,849, +785,849,784, +849,785,850, +786,850,785, +850,786,851, +787,851,786, +851,787,852, +788,852,787, +852,788,853, +789,853,788, +853,789,854, +790,854,789, +854,790,855, +791,855,790, +855,791,856, +792,856,791, +856,792,857, +793,857,792, +857,793,858, +794,858,793, +858,794,859, +795,859,794, +859,795,860, +796,860,795, +860,796,861, +797,861,796, +861,797,862, +798,862,797, +862,798,863, +799,863,798, +863,799,864, +800,864,799, +864,800,865, +801,865,800, +865,801,866, +802,866,801, +866,802,867, +803,867,802, +867,803,868, +804,868,803, +868,804,869, +805,869,804, +869,805,870, +806,870,805, +870,806,871, +807,871,806, +871,807,872, +808,872,807, +872,808,873, +809,873,808, +873,809,874, +810,874,809, +874,810,875, +811,875,810, +875,811,876, +812,876,811, +876,812,877, +813,877,812, +877,813,878, +814,878,813, +878,814,879, +815,879,814, +879,815,880, +816,880,815, +880,816,881, +817,881,816, +881,817,882, +818,882,817, +882,818,883, +819,883,818, +883,819,884, +820,884,819, +884,820,885, +821,885,820, +885,821,886, +822,886,821, +886,822,887, +823,887,822, +887,823,888, +824,888,823, +888,824,889, +825,889,824, +889,825,890, +826,890,825, +890,826,891, +827,891,826, +891,827,892, +828,892,827, +892,828,893, +829,893,828, +893,829,894, +830,894,829, +894,830,895, +831,895,830, +896,832,897, +833,897,832, +897,833,898, +834,898,833, +898,834,899, +835,899,834, +899,835,900, +836,900,835, +900,836,901, +837,901,836, +901,837,902, +838,902,837, +902,838,903, +839,903,838, +903,839,904, +840,904,839, +904,840,905, +841,905,840, +905,841,906, +842,906,841, +906,842,907, +843,907,842, +907,843,908, +844,908,843, +908,844,909, +845,909,844, +909,845,910, +846,910,845, +910,846,911, +847,911,846, +911,847,912, +848,912,847, +912,848,913, +849,913,848, +913,849,914, +850,914,849, +914,850,915, +851,915,850, +915,851,916, +852,916,851, +916,852,917, +853,917,852, +917,853,918, +854,918,853, +918,854,919, +855,919,854, +919,855,920, +856,920,855, +920,856,921, +857,921,856, +921,857,922, +858,922,857, +922,858,923, +859,923,858, +923,859,924, +860,924,859, +924,860,925, +861,925,860, +925,861,926, +862,926,861, +926,862,927, +863,927,862, +927,863,928, +864,928,863, +928,864,929, +865,929,864, +929,865,930, +866,930,865, +930,866,931, +867,931,866, +931,867,932, +868,932,867, +932,868,933, +869,933,868, +933,869,934, +870,934,869, +934,870,935, +871,935,870, +935,871,936, +872,936,871, +936,872,937, +873,937,872, +937,873,938, +874,938,873, +938,874,939, +875,939,874, +939,875,940, +876,940,875, +940,876,941, +877,941,876, +941,877,942, +878,942,877, +942,878,943, +879,943,878, +943,879,944, +880,944,879, +944,880,945, +881,945,880, +945,881,946, +882,946,881, +946,882,947, +883,947,882, +947,883,948, +884,948,883, +948,884,949, +885,949,884, +949,885,950, +886,950,885, +950,886,951, +887,951,886, +951,887,952, +888,952,887, +952,888,953, +889,953,888, +953,889,954, +890,954,889, +954,890,955, +891,955,890, +955,891,956, +892,956,891, +956,892,957, +893,957,892, +957,893,958, +894,958,893, +958,894,959, +895,959,894, +960,896,961, +897,961,896, +961,897,962, +898,962,897, +962,898,963, +899,963,898, +963,899,964, +900,964,899, +964,900,965, +901,965,900, +965,901,966, +902,966,901, +966,902,967, +903,967,902, +967,903,968, +904,968,903, +968,904,969, +905,969,904, +969,905,970, +906,970,905, +970,906,971, +907,971,906, +971,907,972, +908,972,907, +972,908,973, +909,973,908, +973,909,974, +910,974,909, +974,910,975, +911,975,910, +975,911,976, +912,976,911, +976,912,977, +913,977,912, +977,913,978, +914,978,913, +978,914,979, +915,979,914, +979,915,980, +916,980,915, +980,916,981, +917,981,916, +981,917,982, +918,982,917, +982,918,983, +919,983,918, +983,919,984, +920,984,919, +984,920,985, +921,985,920, +985,921,986, +922,986,921, +986,922,987, +923,987,922, +987,923,988, +924,988,923, +988,924,989, +925,989,924, +989,925,990, +926,990,925, +990,926,991, +927,991,926, +991,927,992, +928,992,927, +992,928,993, +929,993,928, +993,929,994, +930,994,929, +994,930,995, +931,995,930, +995,931,996, +932,996,931, +996,932,997, +933,997,932, +997,933,998, +934,998,933, +998,934,999, +935,999,934, +999,935,1000, +936,1000,935, +1000,936,1001, +937,1001,936, +1001,937,1002, +938,1002,937, +1002,938,1003, +939,1003,938, +1003,939,1004, +940,1004,939, +1004,940,1005, +941,1005,940, +1005,941,1006, +942,1006,941, +1006,942,1007, +943,1007,942, +1007,943,1008, +944,1008,943, +1008,944,1009, +945,1009,944, +1009,945,1010, +946,1010,945, +1010,946,1011, +947,1011,946, +1011,947,1012, +948,1012,947, +1012,948,1013, +949,1013,948, +1013,949,1014, +950,1014,949, +1014,950,1015, +951,1015,950, +1015,951,1016, +952,1016,951, +1016,952,1017, +953,1017,952, +1017,953,1018, +954,1018,953, +1018,954,1019, +955,1019,954, +1019,955,1020, +956,1020,955, +1020,956,1021, +957,1021,956, +1021,957,1022, +958,1022,957, +1022,958,1023, +959,1023,958, +1024,960,1025, +961,1025,960, +1025,961,1026, +962,1026,961, +1026,962,1027, +963,1027,962, +1027,963,1028, +964,1028,963, +1028,964,1029, +965,1029,964, +1029,965,1030, +966,1030,965, +1030,966,1031, +967,1031,966, +1031,967,1032, +968,1032,967, +1032,968,1033, +969,1033,968, +1033,969,1034, +970,1034,969, +1034,970,1035, +971,1035,970, +1035,971,1036, +972,1036,971, +1036,972,1037, +973,1037,972, +1037,973,1038, +974,1038,973, +1038,974,1039, +975,1039,974, +1039,975,1040, +976,1040,975, +1040,976,1041, +977,1041,976, +1041,977,1042, +978,1042,977, +1042,978,1043, +979,1043,978, +1043,979,1044, +980,1044,979, +1044,980,1045, +981,1045,980, +1045,981,1046, +982,1046,981, +1046,982,1047, +983,1047,982, +1047,983,1048, +984,1048,983, +1048,984,1049, +985,1049,984, +1049,985,1050, +986,1050,985, +1050,986,1051, +987,1051,986, +1051,987,1052, +988,1052,987, +1052,988,1053, +989,1053,988, +1053,989,1054, +990,1054,989, +1054,990,1055, +991,1055,990, +1055,991,1056, +992,1056,991, +1056,992,1057, +993,1057,992, +1057,993,1058, +994,1058,993, +1058,994,1059, +995,1059,994, +1059,995,1060, +996,1060,995, +1060,996,1061, +997,1061,996, +1061,997,1062, +998,1062,997, +1062,998,1063, +999,1063,998, +1063,999,1064, +1000,1064,999, +1064,1000,1065, +1001,1065,1000, +1065,1001,1066, +1002,1066,1001, +1066,1002,1067, +1003,1067,1002, +1067,1003,1068, +1004,1068,1003, +1068,1004,1069, +1005,1069,1004, +1069,1005,1070, +1006,1070,1005, +1070,1006,1071, +1007,1071,1006, +1071,1007,1072, +1008,1072,1007, +1072,1008,1073, +1009,1073,1008, +1073,1009,1074, +1010,1074,1009, +1074,1010,1075, +1011,1075,1010, +1075,1011,1076, +1012,1076,1011, +1076,1012,1077, +1013,1077,1012, +1077,1013,1078, +1014,1078,1013, +1078,1014,1079, +1015,1079,1014, +1079,1015,1080, +1016,1080,1015, +1080,1016,1081, +1017,1081,1016, +1081,1017,1082, +1018,1082,1017, +1082,1018,1083, +1019,1083,1018, +1083,1019,1084, +1020,1084,1019, +1084,1020,1085, +1021,1085,1020, +1085,1021,1086, +1022,1086,1021, +1086,1022,1087, +1023,1087,1022, +1088,1024,1089, +1025,1089,1024, +1089,1025,1090, +1026,1090,1025, +1090,1026,1091, +1027,1091,1026, +1091,1027,1092, +1028,1092,1027, +1092,1028,1093, +1029,1093,1028, +1093,1029,1094, +1030,1094,1029, +1094,1030,1095, +1031,1095,1030, +1095,1031,1096, +1032,1096,1031, +1096,1032,1097, +1033,1097,1032, +1097,1033,1098, +1034,1098,1033, +1098,1034,1099, +1035,1099,1034, +1099,1035,1100, +1036,1100,1035, +1100,1036,1101, +1037,1101,1036, +1101,1037,1102, +1038,1102,1037, +1102,1038,1103, +1039,1103,1038, +1103,1039,1104, +1040,1104,1039, +1104,1040,1105, +1041,1105,1040, +1105,1041,1106, +1042,1106,1041, +1106,1042,1107, +1043,1107,1042, +1107,1043,1108, +1044,1108,1043, +1108,1044,1109, +1045,1109,1044, +1109,1045,1110, +1046,1110,1045, +1110,1046,1111, +1047,1111,1046, +1111,1047,1112, +1048,1112,1047, +1112,1048,1113, +1049,1113,1048, +1113,1049,1114, +1050,1114,1049, +1114,1050,1115, +1051,1115,1050, +1115,1051,1116, +1052,1116,1051, +1116,1052,1117, +1053,1117,1052, +1117,1053,1118, +1054,1118,1053, +1118,1054,1119, +1055,1119,1054, +1119,1055,1120, +1056,1120,1055, +1120,1056,1121, +1057,1121,1056, +1121,1057,1122, +1058,1122,1057, +1122,1058,1123, +1059,1123,1058, +1123,1059,1124, +1060,1124,1059, +1124,1060,1125, +1061,1125,1060, +1125,1061,1126, +1062,1126,1061, +1126,1062,1127, +1063,1127,1062, +1127,1063,1128, +1064,1128,1063, +1128,1064,1129, +1065,1129,1064, +1129,1065,1130, +1066,1130,1065, +1130,1066,1131, +1067,1131,1066, +1131,1067,1132, +1068,1132,1067, +1132,1068,1133, +1069,1133,1068, +1133,1069,1134, +1070,1134,1069, +1134,1070,1135, +1071,1135,1070, +1135,1071,1136, +1072,1136,1071, +1136,1072,1137, +1073,1137,1072, +1137,1073,1138, +1074,1138,1073, +1138,1074,1139, +1075,1139,1074, +1139,1075,1140, +1076,1140,1075, +1140,1076,1141, +1077,1141,1076, +1141,1077,1142, +1078,1142,1077, +1142,1078,1143, +1079,1143,1078, +1143,1079,1144, +1080,1144,1079, +1144,1080,1145, +1081,1145,1080, +1145,1081,1146, +1082,1146,1081, +1146,1082,1147, +1083,1147,1082, +1147,1083,1148, +1084,1148,1083, +1148,1084,1149, +1085,1149,1084, +1149,1085,1150, +1086,1150,1085, +1150,1086,1151, +1087,1151,1086, +1152,1088,1153, +1089,1153,1088, +1153,1089,1154, +1090,1154,1089, +1154,1090,1155, +1091,1155,1090, +1155,1091,1156, +1092,1156,1091, +1156,1092,1157, +1093,1157,1092, +1157,1093,1158, +1094,1158,1093, +1158,1094,1159, +1095,1159,1094, +1159,1095,1160, +1096,1160,1095, +1160,1096,1161, +1097,1161,1096, +1161,1097,1162, +1098,1162,1097, +1162,1098,1163, +1099,1163,1098, +1163,1099,1164, +1100,1164,1099, +1164,1100,1165, +1101,1165,1100, +1165,1101,1166, +1102,1166,1101, +1166,1102,1167, +1103,1167,1102, +1167,1103,1168, +1104,1168,1103, +1168,1104,1169, +1105,1169,1104, +1169,1105,1170, +1106,1170,1105, +1170,1106,1171, +1107,1171,1106, +1171,1107,1172, +1108,1172,1107, +1172,1108,1173, +1109,1173,1108, +1173,1109,1174, +1110,1174,1109, +1174,1110,1175, +1111,1175,1110, +1175,1111,1176, +1112,1176,1111, +1176,1112,1177, +1113,1177,1112, +1177,1113,1178, +1114,1178,1113, +1178,1114,1179, +1115,1179,1114, +1179,1115,1180, +1116,1180,1115, +1180,1116,1181, +1117,1181,1116, +1181,1117,1182, +1118,1182,1117, +1182,1118,1183, +1119,1183,1118, +1183,1119,1184, +1120,1184,1119, +1184,1120,1185, +1121,1185,1120, +1185,1121,1186, +1122,1186,1121, +1186,1122,1187, +1123,1187,1122, +1187,1123,1188, +1124,1188,1123, +1188,1124,1189, +1125,1189,1124, +1189,1125,1190, +1126,1190,1125, +1190,1126,1191, +1127,1191,1126, +1191,1127,1192, +1128,1192,1127, +1192,1128,1193, +1129,1193,1128, +1193,1129,1194, +1130,1194,1129, +1194,1130,1195, +1131,1195,1130, +1195,1131,1196, +1132,1196,1131, +1196,1132,1197, +1133,1197,1132, +1197,1133,1198, +1134,1198,1133, +1198,1134,1199, +1135,1199,1134, +1199,1135,1200, +1136,1200,1135, +1200,1136,1201, +1137,1201,1136, +1201,1137,1202, +1138,1202,1137, +1202,1138,1203, +1139,1203,1138, +1203,1139,1204, +1140,1204,1139, +1204,1140,1205, +1141,1205,1140, +1205,1141,1206, +1142,1206,1141, +1206,1142,1207, +1143,1207,1142, +1207,1143,1208, +1144,1208,1143, +1208,1144,1209, +1145,1209,1144, +1209,1145,1210, +1146,1210,1145, +1210,1146,1211, +1147,1211,1146, +1211,1147,1212, +1148,1212,1147, +1212,1148,1213, +1149,1213,1148, +1213,1149,1214, +1150,1214,1149, +1214,1150,1215, +1151,1215,1150, +1216,1152,1217, +1153,1217,1152, +1217,1153,1218, +1154,1218,1153, +1218,1154,1219, +1155,1219,1154, +1219,1155,1220, +1156,1220,1155, +1220,1156,1221, +1157,1221,1156, +1221,1157,1222, +1158,1222,1157, +1222,1158,1223, +1159,1223,1158, +1223,1159,1224, +1160,1224,1159, +1224,1160,1225, +1161,1225,1160, +1225,1161,1226, +1162,1226,1161, +1226,1162,1227, +1163,1227,1162, +1227,1163,1228, +1164,1228,1163, +1228,1164,1229, +1165,1229,1164, +1229,1165,1230, +1166,1230,1165, +1230,1166,1231, +1167,1231,1166, +1231,1167,1232, +1168,1232,1167, +1232,1168,1233, +1169,1233,1168, +1233,1169,1234, +1170,1234,1169, +1234,1170,1235, +1171,1235,1170, +1235,1171,1236, +1172,1236,1171, +1236,1172,1237, +1173,1237,1172, +1237,1173,1238, +1174,1238,1173, +1238,1174,1239, +1175,1239,1174, +1239,1175,1240, +1176,1240,1175, +1240,1176,1241, +1177,1241,1176, +1241,1177,1242, +1178,1242,1177, +1242,1178,1243, +1179,1243,1178, +1243,1179,1244, +1180,1244,1179, +1244,1180,1245, +1181,1245,1180, +1245,1181,1246, +1182,1246,1181, +1246,1182,1247, +1183,1247,1182, +1247,1183,1248, +1184,1248,1183, +1248,1184,1249, +1185,1249,1184, +1249,1185,1250, +1186,1250,1185, +1250,1186,1251, +1187,1251,1186, +1251,1187,1252, +1188,1252,1187, +1252,1188,1253, +1189,1253,1188, +1253,1189,1254, +1190,1254,1189, +1254,1190,1255, +1191,1255,1190, +1255,1191,1256, +1192,1256,1191, +1256,1192,1257, +1193,1257,1192, +1257,1193,1258, +1194,1258,1193, +1258,1194,1259, +1195,1259,1194, +1259,1195,1260, +1196,1260,1195, +1260,1196,1261, +1197,1261,1196, +1261,1197,1262, +1198,1262,1197, +1262,1198,1263, +1199,1263,1198, +1263,1199,1264, +1200,1264,1199, +1264,1200,1265, +1201,1265,1200, +1265,1201,1266, +1202,1266,1201, +1266,1202,1267, +1203,1267,1202, +1267,1203,1268, +1204,1268,1203, +1268,1204,1269, +1205,1269,1204, +1269,1205,1270, +1206,1270,1205, +1270,1206,1271, +1207,1271,1206, +1271,1207,1272, +1208,1272,1207, +1272,1208,1273, +1209,1273,1208, +1273,1209,1274, +1210,1274,1209, +1274,1210,1275, +1211,1275,1210, +1275,1211,1276, +1212,1276,1211, +1276,1212,1277, +1213,1277,1212, +1277,1213,1278, +1214,1278,1213, +1278,1214,1279, +1215,1279,1214, +1280,1216,1281, +1217,1281,1216, +1281,1217,1282, +1218,1282,1217, +1282,1218,1283, +1219,1283,1218, +1283,1219,1284, +1220,1284,1219, +1284,1220,1285, +1221,1285,1220, +1285,1221,1286, +1222,1286,1221, +1286,1222,1287, +1223,1287,1222, +1287,1223,1288, +1224,1288,1223, +1288,1224,1289, +1225,1289,1224, +1289,1225,1290, +1226,1290,1225, +1290,1226,1291, +1227,1291,1226, +1291,1227,1292, +1228,1292,1227, +1292,1228,1293, +1229,1293,1228, +1293,1229,1294, +1230,1294,1229, +1294,1230,1295, +1231,1295,1230, +1295,1231,1296, +1232,1296,1231, +1296,1232,1297, +1233,1297,1232, +1297,1233,1298, +1234,1298,1233, +1298,1234,1299, +1235,1299,1234, +1299,1235,1300, +1236,1300,1235, +1300,1236,1301, +1237,1301,1236, +1301,1237,1302, +1238,1302,1237, +1302,1238,1303, +1239,1303,1238, +1303,1239,1304, +1240,1304,1239, +1304,1240,1305, +1241,1305,1240, +1305,1241,1306, +1242,1306,1241, +1306,1242,1307, +1243,1307,1242, +1307,1243,1308, +1244,1308,1243, +1308,1244,1309, +1245,1309,1244, +1309,1245,1310, +1246,1310,1245, +1310,1246,1311, +1247,1311,1246, +1311,1247,1312, +1248,1312,1247, +1312,1248,1313, +1249,1313,1248, +1313,1249,1314, +1250,1314,1249, +1314,1250,1315, +1251,1315,1250, +1315,1251,1316, +1252,1316,1251, +1316,1252,1317, +1253,1317,1252, +1317,1253,1318, +1254,1318,1253, +1318,1254,1319, +1255,1319,1254, +1319,1255,1320, +1256,1320,1255, +1320,1256,1321, +1257,1321,1256, +1321,1257,1322, +1258,1322,1257, +1322,1258,1323, +1259,1323,1258, +1323,1259,1324, +1260,1324,1259, +1324,1260,1325, +1261,1325,1260, +1325,1261,1326, +1262,1326,1261, +1326,1262,1327, +1263,1327,1262, +1327,1263,1328, +1264,1328,1263, +1328,1264,1329, +1265,1329,1264, +1329,1265,1330, +1266,1330,1265, +1330,1266,1331, +1267,1331,1266, +1331,1267,1332, +1268,1332,1267, +1332,1268,1333, +1269,1333,1268, +1333,1269,1334, +1270,1334,1269, +1334,1270,1335, +1271,1335,1270, +1335,1271,1336, +1272,1336,1271, +1336,1272,1337, +1273,1337,1272, +1337,1273,1338, +1274,1338,1273, +1338,1274,1339, +1275,1339,1274, +1339,1275,1340, +1276,1340,1275, +1340,1276,1341, +1277,1341,1276, +1341,1277,1342, +1278,1342,1277, +1342,1278,1343, +1279,1343,1278, +1344,1280,1345, +1281,1345,1280, +1345,1281,1346, +1282,1346,1281, +1346,1282,1347, +1283,1347,1282, +1347,1283,1348, +1284,1348,1283, +1348,1284,1349, +1285,1349,1284, +1349,1285,1350, +1286,1350,1285, +1350,1286,1351, +1287,1351,1286, +1351,1287,1352, +1288,1352,1287, +1352,1288,1353, +1289,1353,1288, +1353,1289,1354, +1290,1354,1289, +1354,1290,1355, +1291,1355,1290, +1355,1291,1356, +1292,1356,1291, +1356,1292,1357, +1293,1357,1292, +1357,1293,1358, +1294,1358,1293, +1358,1294,1359, +1295,1359,1294, +1359,1295,1360, +1296,1360,1295, +1360,1296,1361, +1297,1361,1296, +1361,1297,1362, +1298,1362,1297, +1362,1298,1363, +1299,1363,1298, +1363,1299,1364, +1300,1364,1299, +1364,1300,1365, +1301,1365,1300, +1365,1301,1366, +1302,1366,1301, +1366,1302,1367, +1303,1367,1302, +1367,1303,1368, +1304,1368,1303, +1368,1304,1369, +1305,1369,1304, +1369,1305,1370, +1306,1370,1305, +1370,1306,1371, +1307,1371,1306, +1371,1307,1372, +1308,1372,1307, +1372,1308,1373, +1309,1373,1308, +1373,1309,1374, +1310,1374,1309, +1374,1310,1375, +1311,1375,1310, +1375,1311,1376, +1312,1376,1311, +1376,1312,1377, +1313,1377,1312, +1377,1313,1378, +1314,1378,1313, +1378,1314,1379, +1315,1379,1314, +1379,1315,1380, +1316,1380,1315, +1380,1316,1381, +1317,1381,1316, +1381,1317,1382, +1318,1382,1317, +1382,1318,1383, +1319,1383,1318, +1383,1319,1384, +1320,1384,1319, +1384,1320,1385, +1321,1385,1320, +1385,1321,1386, +1322,1386,1321, +1386,1322,1387, +1323,1387,1322, +1387,1323,1388, +1324,1388,1323, +1388,1324,1389, +1325,1389,1324, +1389,1325,1390, +1326,1390,1325, +1390,1326,1391, +1327,1391,1326, +1391,1327,1392, +1328,1392,1327, +1392,1328,1393, +1329,1393,1328, +1393,1329,1394, +1330,1394,1329, +1394,1330,1395, +1331,1395,1330, +1395,1331,1396, +1332,1396,1331, +1396,1332,1397, +1333,1397,1332, +1397,1333,1398, +1334,1398,1333, +1398,1334,1399, +1335,1399,1334, +1399,1335,1400, +1336,1400,1335, +1400,1336,1401, +1337,1401,1336, +1401,1337,1402, +1338,1402,1337, +1402,1338,1403, +1339,1403,1338, +1403,1339,1404, +1340,1404,1339, +1404,1340,1405, +1341,1405,1340, +1405,1341,1406, +1342,1406,1341, +1406,1342,1407, +1343,1407,1342, +1408,1344,1409, +1345,1409,1344, +1409,1345,1410, +1346,1410,1345, +1410,1346,1411, +1347,1411,1346, +1411,1347,1412, +1348,1412,1347, +1412,1348,1413, +1349,1413,1348, +1413,1349,1414, +1350,1414,1349, +1414,1350,1415, +1351,1415,1350, +1415,1351,1416, +1352,1416,1351, +1416,1352,1417, +1353,1417,1352, +1417,1353,1418, +1354,1418,1353, +1418,1354,1419, +1355,1419,1354, +1419,1355,1420, +1356,1420,1355, +1420,1356,1421, +1357,1421,1356, +1421,1357,1422, +1358,1422,1357, +1422,1358,1423, +1359,1423,1358, +1423,1359,1424, +1360,1424,1359, +1424,1360,1425, +1361,1425,1360, +1425,1361,1426, +1362,1426,1361, +1426,1362,1427, +1363,1427,1362, +1427,1363,1428, +1364,1428,1363, +1428,1364,1429, +1365,1429,1364, +1429,1365,1430, +1366,1430,1365, +1430,1366,1431, +1367,1431,1366, +1431,1367,1432, +1368,1432,1367, +1432,1368,1433, +1369,1433,1368, +1433,1369,1434, +1370,1434,1369, +1434,1370,1435, +1371,1435,1370, +1435,1371,1436, +1372,1436,1371, +1436,1372,1437, +1373,1437,1372, +1437,1373,1438, +1374,1438,1373, +1438,1374,1439, +1375,1439,1374, +1439,1375,1440, +1376,1440,1375, +1440,1376,1441, +1377,1441,1376, +1441,1377,1442, +1378,1442,1377, +1442,1378,1443, +1379,1443,1378, +1443,1379,1444, +1380,1444,1379, +1444,1380,1445, +1381,1445,1380, +1445,1381,1446, +1382,1446,1381, +1446,1382,1447, +1383,1447,1382, +1447,1383,1448, +1384,1448,1383, +1448,1384,1449, +1385,1449,1384, +1449,1385,1450, +1386,1450,1385, +1450,1386,1451, +1387,1451,1386, +1451,1387,1452, +1388,1452,1387, +1452,1388,1453, +1389,1453,1388, +1453,1389,1454, +1390,1454,1389, +1454,1390,1455, +1391,1455,1390, +1455,1391,1456, +1392,1456,1391, +1456,1392,1457, +1393,1457,1392, +1457,1393,1458, +1394,1458,1393, +1458,1394,1459, +1395,1459,1394, +1459,1395,1460, +1396,1460,1395, +1460,1396,1461, +1397,1461,1396, +1461,1397,1462, +1398,1462,1397, +1462,1398,1463, +1399,1463,1398, +1463,1399,1464, +1400,1464,1399, +1464,1400,1465, +1401,1465,1400, +1465,1401,1466, +1402,1466,1401, +1466,1402,1467, +1403,1467,1402, +1467,1403,1468, +1404,1468,1403, +1468,1404,1469, +1405,1469,1404, +1469,1405,1470, +1406,1470,1405, +1470,1406,1471, +1407,1471,1406, +1472,1408,1473, +1409,1473,1408, +1473,1409,1474, +1410,1474,1409, +1474,1410,1475, +1411,1475,1410, +1475,1411,1476, +1412,1476,1411, +1476,1412,1477, +1413,1477,1412, +1477,1413,1478, +1414,1478,1413, +1478,1414,1479, +1415,1479,1414, +1479,1415,1480, +1416,1480,1415, +1480,1416,1481, +1417,1481,1416, +1481,1417,1482, +1418,1482,1417, +1482,1418,1483, +1419,1483,1418, +1483,1419,1484, +1420,1484,1419, +1484,1420,1485, +1421,1485,1420, +1485,1421,1486, +1422,1486,1421, +1486,1422,1487, +1423,1487,1422, +1487,1423,1488, +1424,1488,1423, +1488,1424,1489, +1425,1489,1424, +1489,1425,1490, +1426,1490,1425, +1490,1426,1491, +1427,1491,1426, +1491,1427,1492, +1428,1492,1427, +1492,1428,1493, +1429,1493,1428, +1493,1429,1494, +1430,1494,1429, +1494,1430,1495, +1431,1495,1430, +1495,1431,1496, +1432,1496,1431, +1496,1432,1497, +1433,1497,1432, +1497,1433,1498, +1434,1498,1433, +1498,1434,1499, +1435,1499,1434, +1499,1435,1500, +1436,1500,1435, +1500,1436,1501, +1437,1501,1436, +1501,1437,1502, +1438,1502,1437, +1502,1438,1503, +1439,1503,1438, +1503,1439,1504, +1440,1504,1439, +1504,1440,1505, +1441,1505,1440, +1505,1441,1506, +1442,1506,1441, +1506,1442,1507, +1443,1507,1442, +1507,1443,1508, +1444,1508,1443, +1508,1444,1509, +1445,1509,1444, +1509,1445,1510, +1446,1510,1445, +1510,1446,1511, +1447,1511,1446, +1511,1447,1512, +1448,1512,1447, +1512,1448,1513, +1449,1513,1448, +1513,1449,1514, +1450,1514,1449, +1514,1450,1515, +1451,1515,1450, +1515,1451,1516, +1452,1516,1451, +1516,1452,1517, +1453,1517,1452, +1517,1453,1518, +1454,1518,1453, +1518,1454,1519, +1455,1519,1454, +1519,1455,1520, +1456,1520,1455, +1520,1456,1521, +1457,1521,1456, +1521,1457,1522, +1458,1522,1457, +1522,1458,1523, +1459,1523,1458, +1523,1459,1524, +1460,1524,1459, +1524,1460,1525, +1461,1525,1460, +1525,1461,1526, +1462,1526,1461, +1526,1462,1527, +1463,1527,1462, +1527,1463,1528, +1464,1528,1463, +1528,1464,1529, +1465,1529,1464, +1529,1465,1530, +1466,1530,1465, +1530,1466,1531, +1467,1531,1466, +1531,1467,1532, +1468,1532,1467, +1532,1468,1533, +1469,1533,1468, +1533,1469,1534, +1470,1534,1469, +1534,1470,1535, +1471,1535,1470, +1536,1472,1537, +1473,1537,1472, +1537,1473,1538, +1474,1538,1473, +1538,1474,1539, +1475,1539,1474, +1539,1475,1540, +1476,1540,1475, +1540,1476,1541, +1477,1541,1476, +1541,1477,1542, +1478,1542,1477, +1542,1478,1543, +1479,1543,1478, +1543,1479,1544, +1480,1544,1479, +1544,1480,1545, +1481,1545,1480, +1545,1481,1546, +1482,1546,1481, +1546,1482,1547, +1483,1547,1482, +1547,1483,1548, +1484,1548,1483, +1548,1484,1549, +1485,1549,1484, +1549,1485,1550, +1486,1550,1485, +1550,1486,1551, +1487,1551,1486, +1551,1487,1552, +1488,1552,1487, +1552,1488,1553, +1489,1553,1488, +1553,1489,1554, +1490,1554,1489, +1554,1490,1555, +1491,1555,1490, +1555,1491,1556, +1492,1556,1491, +1556,1492,1557, +1493,1557,1492, +1557,1493,1558, +1494,1558,1493, +1558,1494,1559, +1495,1559,1494, +1559,1495,1560, +1496,1560,1495, +1560,1496,1561, +1497,1561,1496, +1561,1497,1562, +1498,1562,1497, +1562,1498,1563, +1499,1563,1498, +1563,1499,1564, +1500,1564,1499, +1564,1500,1565, +1501,1565,1500, +1565,1501,1566, +1502,1566,1501, +1566,1502,1567, +1503,1567,1502, +1567,1503,1568, +1504,1568,1503, +1568,1504,1569, +1505,1569,1504, +1569,1505,1570, +1506,1570,1505, +1570,1506,1571, +1507,1571,1506, +1571,1507,1572, +1508,1572,1507, +1572,1508,1573, +1509,1573,1508, +1573,1509,1574, +1510,1574,1509, +1574,1510,1575, +1511,1575,1510, +1575,1511,1576, +1512,1576,1511, +1576,1512,1577, +1513,1577,1512, +1577,1513,1578, +1514,1578,1513, +1578,1514,1579, +1515,1579,1514, +1579,1515,1580, +1516,1580,1515, +1580,1516,1581, +1517,1581,1516, +1581,1517,1582, +1518,1582,1517, +1582,1518,1583, +1519,1583,1518, +1583,1519,1584, +1520,1584,1519, +1584,1520,1585, +1521,1585,1520, +1585,1521,1586, +1522,1586,1521, +1586,1522,1587, +1523,1587,1522, +1587,1523,1588, +1524,1588,1523, +1588,1524,1589, +1525,1589,1524, +1589,1525,1590, +1526,1590,1525, +1590,1526,1591, +1527,1591,1526, +1591,1527,1592, +1528,1592,1527, +1592,1528,1593, +1529,1593,1528, +1593,1529,1594, +1530,1594,1529, +1594,1530,1595, +1531,1595,1530, +1595,1531,1596, +1532,1596,1531, +1596,1532,1597, +1533,1597,1532, +1597,1533,1598, +1534,1598,1533, +1598,1534,1599, +1535,1599,1534, +1600,1536,1601, +1537,1601,1536, +1601,1537,1602, +1538,1602,1537, +1602,1538,1603, +1539,1603,1538, +1603,1539,1604, +1540,1604,1539, +1604,1540,1605, +1541,1605,1540, +1605,1541,1606, +1542,1606,1541, +1606,1542,1607, +1543,1607,1542, +1607,1543,1608, +1544,1608,1543, +1608,1544,1609, +1545,1609,1544, +1609,1545,1610, +1546,1610,1545, +1610,1546,1611, +1547,1611,1546, +1611,1547,1612, +1548,1612,1547, +1612,1548,1613, +1549,1613,1548, +1613,1549,1614, +1550,1614,1549, +1614,1550,1615, +1551,1615,1550, +1615,1551,1616, +1552,1616,1551, +1616,1552,1617, +1553,1617,1552, +1617,1553,1618, +1554,1618,1553, +1618,1554,1619, +1555,1619,1554, +1619,1555,1620, +1556,1620,1555, +1620,1556,1621, +1557,1621,1556, +1621,1557,1622, +1558,1622,1557, +1622,1558,1623, +1559,1623,1558, +1623,1559,1624, +1560,1624,1559, +1624,1560,1625, +1561,1625,1560, +1625,1561,1626, +1562,1626,1561, +1626,1562,1627, +1563,1627,1562, +1627,1563,1628, +1564,1628,1563, +1628,1564,1629, +1565,1629,1564, +1629,1565,1630, +1566,1630,1565, +1630,1566,1631, +1567,1631,1566, +1631,1567,1632, +1568,1632,1567, +1632,1568,1633, +1569,1633,1568, +1633,1569,1634, +1570,1634,1569, +1634,1570,1635, +1571,1635,1570, +1635,1571,1636, +1572,1636,1571, +1636,1572,1637, +1573,1637,1572, +1637,1573,1638, +1574,1638,1573, +1638,1574,1639, +1575,1639,1574, +1639,1575,1640, +1576,1640,1575, +1640,1576,1641, +1577,1641,1576, +1641,1577,1642, +1578,1642,1577, +1642,1578,1643, +1579,1643,1578, +1643,1579,1644, +1580,1644,1579, +1644,1580,1645, +1581,1645,1580, +1645,1581,1646, +1582,1646,1581, +1646,1582,1647, +1583,1647,1582, +1647,1583,1648, +1584,1648,1583, +1648,1584,1649, +1585,1649,1584, +1649,1585,1650, +1586,1650,1585, +1650,1586,1651, +1587,1651,1586, +1651,1587,1652, +1588,1652,1587, +1652,1588,1653, +1589,1653,1588, +1653,1589,1654, +1590,1654,1589, +1654,1590,1655, +1591,1655,1590, +1655,1591,1656, +1592,1656,1591, +1656,1592,1657, +1593,1657,1592, +1657,1593,1658, +1594,1658,1593, +1658,1594,1659, +1595,1659,1594, +1659,1595,1660, +1596,1660,1595, +1660,1596,1661, +1597,1661,1596, +1661,1597,1662, +1598,1662,1597, +1662,1598,1663, +1599,1663,1598, +1664,1600,1665, +1601,1665,1600, +1665,1601,1666, +1602,1666,1601, +1666,1602,1667, +1603,1667,1602, +1667,1603,1668, +1604,1668,1603, +1668,1604,1669, +1605,1669,1604, +1669,1605,1670, +1606,1670,1605, +1670,1606,1671, +1607,1671,1606, +1671,1607,1672, +1608,1672,1607, +1672,1608,1673, +1609,1673,1608, +1673,1609,1674, +1610,1674,1609, +1674,1610,1675, +1611,1675,1610, +1675,1611,1676, +1612,1676,1611, +1676,1612,1677, +1613,1677,1612, +1677,1613,1678, +1614,1678,1613, +1678,1614,1679, +1615,1679,1614, +1679,1615,1680, +1616,1680,1615, +1680,1616,1681, +1617,1681,1616, +1681,1617,1682, +1618,1682,1617, +1682,1618,1683, +1619,1683,1618, +1683,1619,1684, +1620,1684,1619, +1684,1620,1685, +1621,1685,1620, +1685,1621,1686, +1622,1686,1621, +1686,1622,1687, +1623,1687,1622, +1687,1623,1688, +1624,1688,1623, +1688,1624,1689, +1625,1689,1624, +1689,1625,1690, +1626,1690,1625, +1690,1626,1691, +1627,1691,1626, +1691,1627,1692, +1628,1692,1627, +1692,1628,1693, +1629,1693,1628, +1693,1629,1694, +1630,1694,1629, +1694,1630,1695, +1631,1695,1630, +1695,1631,1696, +1632,1696,1631, +1696,1632,1697, +1633,1697,1632, +1697,1633,1698, +1634,1698,1633, +1698,1634,1699, +1635,1699,1634, +1699,1635,1700, +1636,1700,1635, +1700,1636,1701, +1637,1701,1636, +1701,1637,1702, +1638,1702,1637, +1702,1638,1703, +1639,1703,1638, +1703,1639,1704, +1640,1704,1639, +1704,1640,1705, +1641,1705,1640, +1705,1641,1706, +1642,1706,1641, +1706,1642,1707, +1643,1707,1642, +1707,1643,1708, +1644,1708,1643, +1708,1644,1709, +1645,1709,1644, +1709,1645,1710, +1646,1710,1645, +1710,1646,1711, +1647,1711,1646, +1711,1647,1712, +1648,1712,1647, +1712,1648,1713, +1649,1713,1648, +1713,1649,1714, +1650,1714,1649, +1714,1650,1715, +1651,1715,1650, +1715,1651,1716, +1652,1716,1651, +1716,1652,1717, +1653,1717,1652, +1717,1653,1718, +1654,1718,1653, +1718,1654,1719, +1655,1719,1654, +1719,1655,1720, +1656,1720,1655, +1720,1656,1721, +1657,1721,1656, +1721,1657,1722, +1658,1722,1657, +1722,1658,1723, +1659,1723,1658, +1723,1659,1724, +1660,1724,1659, +1724,1660,1725, +1661,1725,1660, +1725,1661,1726, +1662,1726,1661, +1726,1662,1727, +1663,1727,1662, +1728,1664,1729, +1665,1729,1664, +1729,1665,1730, +1666,1730,1665, +1730,1666,1731, +1667,1731,1666, +1731,1667,1732, +1668,1732,1667, +1732,1668,1733, +1669,1733,1668, +1733,1669,1734, +1670,1734,1669, +1734,1670,1735, +1671,1735,1670, +1735,1671,1736, +1672,1736,1671, +1736,1672,1737, +1673,1737,1672, +1737,1673,1738, +1674,1738,1673, +1738,1674,1739, +1675,1739,1674, +1739,1675,1740, +1676,1740,1675, +1740,1676,1741, +1677,1741,1676, +1741,1677,1742, +1678,1742,1677, +1742,1678,1743, +1679,1743,1678, +1743,1679,1744, +1680,1744,1679, +1744,1680,1745, +1681,1745,1680, +1745,1681,1746, +1682,1746,1681, +1746,1682,1747, +1683,1747,1682, +1747,1683,1748, +1684,1748,1683, +1748,1684,1749, +1685,1749,1684, +1749,1685,1750, +1686,1750,1685, +1750,1686,1751, +1687,1751,1686, +1751,1687,1752, +1688,1752,1687, +1752,1688,1753, +1689,1753,1688, +1753,1689,1754, +1690,1754,1689, +1754,1690,1755, +1691,1755,1690, +1755,1691,1756, +1692,1756,1691, +1756,1692,1757, +1693,1757,1692, +1757,1693,1758, +1694,1758,1693, +1758,1694,1759, +1695,1759,1694, +1759,1695,1760, +1696,1760,1695, +1760,1696,1761, +1697,1761,1696, +1761,1697,1762, +1698,1762,1697, +1762,1698,1763, +1699,1763,1698, +1763,1699,1764, +1700,1764,1699, +1764,1700,1765, +1701,1765,1700, +1765,1701,1766, +1702,1766,1701, +1766,1702,1767, +1703,1767,1702, +1767,1703,1768, +1704,1768,1703, +1768,1704,1769, +1705,1769,1704, +1769,1705,1770, +1706,1770,1705, +1770,1706,1771, +1707,1771,1706, +1771,1707,1772, +1708,1772,1707, +1772,1708,1773, +1709,1773,1708, +1773,1709,1774, +1710,1774,1709, +1774,1710,1775, +1711,1775,1710, +1775,1711,1776, +1712,1776,1711, +1776,1712,1777, +1713,1777,1712, +1777,1713,1778, +1714,1778,1713, +1778,1714,1779, +1715,1779,1714, +1779,1715,1780, +1716,1780,1715, +1780,1716,1781, +1717,1781,1716, +1781,1717,1782, +1718,1782,1717, +1782,1718,1783, +1719,1783,1718, +1783,1719,1784, +1720,1784,1719, +1784,1720,1785, +1721,1785,1720, +1785,1721,1786, +1722,1786,1721, +1786,1722,1787, +1723,1787,1722, +1787,1723,1788, +1724,1788,1723, +1788,1724,1789, +1725,1789,1724, +1789,1725,1790, +1726,1790,1725, +1790,1726,1791, +1727,1791,1726, +1792,1728,1793, +1729,1793,1728, +1793,1729,1794, +1730,1794,1729, +1794,1730,1795, +1731,1795,1730, +1795,1731,1796, +1732,1796,1731, +1796,1732,1797, +1733,1797,1732, +1797,1733,1798, +1734,1798,1733, +1798,1734,1799, +1735,1799,1734, +1799,1735,1800, +1736,1800,1735, +1800,1736,1801, +1737,1801,1736, +1801,1737,1802, +1738,1802,1737, +1802,1738,1803, +1739,1803,1738, +1803,1739,1804, +1740,1804,1739, +1804,1740,1805, +1741,1805,1740, +1805,1741,1806, +1742,1806,1741, +1806,1742,1807, +1743,1807,1742, +1807,1743,1808, +1744,1808,1743, +1808,1744,1809, +1745,1809,1744, +1809,1745,1810, +1746,1810,1745, +1810,1746,1811, +1747,1811,1746, +1811,1747,1812, +1748,1812,1747, +1812,1748,1813, +1749,1813,1748, +1813,1749,1814, +1750,1814,1749, +1814,1750,1815, +1751,1815,1750, +1815,1751,1816, +1752,1816,1751, +1816,1752,1817, +1753,1817,1752, +1817,1753,1818, +1754,1818,1753, +1818,1754,1819, +1755,1819,1754, +1819,1755,1820, +1756,1820,1755, +1820,1756,1821, +1757,1821,1756, +1821,1757,1822, +1758,1822,1757, +1822,1758,1823, +1759,1823,1758, +1823,1759,1824, +1760,1824,1759, +1824,1760,1825, +1761,1825,1760, +1825,1761,1826, +1762,1826,1761, +1826,1762,1827, +1763,1827,1762, +1827,1763,1828, +1764,1828,1763, +1828,1764,1829, +1765,1829,1764, +1829,1765,1830, +1766,1830,1765, +1830,1766,1831, +1767,1831,1766, +1831,1767,1832, +1768,1832,1767, +1832,1768,1833, +1769,1833,1768, +1833,1769,1834, +1770,1834,1769, +1834,1770,1835, +1771,1835,1770, +1835,1771,1836, +1772,1836,1771, +1836,1772,1837, +1773,1837,1772, +1837,1773,1838, +1774,1838,1773, +1838,1774,1839, +1775,1839,1774, +1839,1775,1840, +1776,1840,1775, +1840,1776,1841, +1777,1841,1776, +1841,1777,1842, +1778,1842,1777, +1842,1778,1843, +1779,1843,1778, +1843,1779,1844, +1780,1844,1779, +1844,1780,1845, +1781,1845,1780, +1845,1781,1846, +1782,1846,1781, +1846,1782,1847, +1783,1847,1782, +1847,1783,1848, +1784,1848,1783, +1848,1784,1849, +1785,1849,1784, +1849,1785,1850, +1786,1850,1785, +1850,1786,1851, +1787,1851,1786, +1851,1787,1852, +1788,1852,1787, +1852,1788,1853, +1789,1853,1788, +1853,1789,1854, +1790,1854,1789, +1854,1790,1855, +1791,1855,1790, +1856,1792,1857, +1793,1857,1792, +1857,1793,1858, +1794,1858,1793, +1858,1794,1859, +1795,1859,1794, +1859,1795,1860, +1796,1860,1795, +1860,1796,1861, +1797,1861,1796, +1861,1797,1862, +1798,1862,1797, +1862,1798,1863, +1799,1863,1798, +1863,1799,1864, +1800,1864,1799, +1864,1800,1865, +1801,1865,1800, +1865,1801,1866, +1802,1866,1801, +1866,1802,1867, +1803,1867,1802, +1867,1803,1868, +1804,1868,1803, +1868,1804,1869, +1805,1869,1804, +1869,1805,1870, +1806,1870,1805, +1870,1806,1871, +1807,1871,1806, +1871,1807,1872, +1808,1872,1807, +1872,1808,1873, +1809,1873,1808, +1873,1809,1874, +1810,1874,1809, +1874,1810,1875, +1811,1875,1810, +1875,1811,1876, +1812,1876,1811, +1876,1812,1877, +1813,1877,1812, +1877,1813,1878, +1814,1878,1813, +1878,1814,1879, +1815,1879,1814, +1879,1815,1880, +1816,1880,1815, +1880,1816,1881, +1817,1881,1816, +1881,1817,1882, +1818,1882,1817, +1882,1818,1883, +1819,1883,1818, +1883,1819,1884, +1820,1884,1819, +1884,1820,1885, +1821,1885,1820, +1885,1821,1886, +1822,1886,1821, +1886,1822,1887, +1823,1887,1822, +1887,1823,1888, +1824,1888,1823, +1888,1824,1889, +1825,1889,1824, +1889,1825,1890, +1826,1890,1825, +1890,1826,1891, +1827,1891,1826, +1891,1827,1892, +1828,1892,1827, +1892,1828,1893, +1829,1893,1828, +1893,1829,1894, +1830,1894,1829, +1894,1830,1895, +1831,1895,1830, +1895,1831,1896, +1832,1896,1831, +1896,1832,1897, +1833,1897,1832, +1897,1833,1898, +1834,1898,1833, +1898,1834,1899, +1835,1899,1834, +1899,1835,1900, +1836,1900,1835, +1900,1836,1901, +1837,1901,1836, +1901,1837,1902, +1838,1902,1837, +1902,1838,1903, +1839,1903,1838, +1903,1839,1904, +1840,1904,1839, +1904,1840,1905, +1841,1905,1840, +1905,1841,1906, +1842,1906,1841, +1906,1842,1907, +1843,1907,1842, +1907,1843,1908, +1844,1908,1843, +1908,1844,1909, +1845,1909,1844, +1909,1845,1910, +1846,1910,1845, +1910,1846,1911, +1847,1911,1846, +1911,1847,1912, +1848,1912,1847, +1912,1848,1913, +1849,1913,1848, +1913,1849,1914, +1850,1914,1849, +1914,1850,1915, +1851,1915,1850, +1915,1851,1916, +1852,1916,1851, +1916,1852,1917, +1853,1917,1852, +1917,1853,1918, +1854,1918,1853, +1918,1854,1919, +1855,1919,1854, +1920,1856,1921, +1857,1921,1856, +1921,1857,1922, +1858,1922,1857, +1922,1858,1923, +1859,1923,1858, +1923,1859,1924, +1860,1924,1859, +1924,1860,1925, +1861,1925,1860, +1925,1861,1926, +1862,1926,1861, +1926,1862,1927, +1863,1927,1862, +1927,1863,1928, +1864,1928,1863, +1928,1864,1929, +1865,1929,1864, +1929,1865,1930, +1866,1930,1865, +1930,1866,1931, +1867,1931,1866, +1931,1867,1932, +1868,1932,1867, +1932,1868,1933, +1869,1933,1868, +1933,1869,1934, +1870,1934,1869, +1934,1870,1935, +1871,1935,1870, +1935,1871,1936, +1872,1936,1871, +1936,1872,1937, +1873,1937,1872, +1937,1873,1938, +1874,1938,1873, +1938,1874,1939, +1875,1939,1874, +1939,1875,1940, +1876,1940,1875, +1940,1876,1941, +1877,1941,1876, +1941,1877,1942, +1878,1942,1877, +1942,1878,1943, +1879,1943,1878, +1943,1879,1944, +1880,1944,1879, +1944,1880,1945, +1881,1945,1880, +1945,1881,1946, +1882,1946,1881, +1946,1882,1947, +1883,1947,1882, +1947,1883,1948, +1884,1948,1883, +1948,1884,1949, +1885,1949,1884, +1949,1885,1950, +1886,1950,1885, +1950,1886,1951, +1887,1951,1886, +1951,1887,1952, +1888,1952,1887, +1952,1888,1953, +1889,1953,1888, +1953,1889,1954, +1890,1954,1889, +1954,1890,1955, +1891,1955,1890, +1955,1891,1956, +1892,1956,1891, +1956,1892,1957, +1893,1957,1892, +1957,1893,1958, +1894,1958,1893, +1958,1894,1959, +1895,1959,1894, +1959,1895,1960, +1896,1960,1895, +1960,1896,1961, +1897,1961,1896, +1961,1897,1962, +1898,1962,1897, +1962,1898,1963, +1899,1963,1898, +1963,1899,1964, +1900,1964,1899, +1964,1900,1965, +1901,1965,1900, +1965,1901,1966, +1902,1966,1901, +1966,1902,1967, +1903,1967,1902, +1967,1903,1968, +1904,1968,1903, +1968,1904,1969, +1905,1969,1904, +1969,1905,1970, +1906,1970,1905, +1970,1906,1971, +1907,1971,1906, +1971,1907,1972, +1908,1972,1907, +1972,1908,1973, +1909,1973,1908, +1973,1909,1974, +1910,1974,1909, +1974,1910,1975, +1911,1975,1910, +1975,1911,1976, +1912,1976,1911, +1976,1912,1977, +1913,1977,1912, +1977,1913,1978, +1914,1978,1913, +1978,1914,1979, +1915,1979,1914, +1979,1915,1980, +1916,1980,1915, +1980,1916,1981, +1917,1981,1916, +1981,1917,1982, +1918,1982,1917, +1982,1918,1983, +1919,1983,1918, +1984,1920,1985, +1921,1985,1920, +1985,1921,1986, +1922,1986,1921, +1986,1922,1987, +1923,1987,1922, +1987,1923,1988, +1924,1988,1923, +1988,1924,1989, +1925,1989,1924, +1989,1925,1990, +1926,1990,1925, +1990,1926,1991, +1927,1991,1926, +1991,1927,1992, +1928,1992,1927, +1992,1928,1993, +1929,1993,1928, +1993,1929,1994, +1930,1994,1929, +1994,1930,1995, +1931,1995,1930, +1995,1931,1996, +1932,1996,1931, +1996,1932,1997, +1933,1997,1932, +1997,1933,1998, +1934,1998,1933, +1998,1934,1999, +1935,1999,1934, +1999,1935,2000, +1936,2000,1935, +2000,1936,2001, +1937,2001,1936, +2001,1937,2002, +1938,2002,1937, +2002,1938,2003, +1939,2003,1938, +2003,1939,2004, +1940,2004,1939, +2004,1940,2005, +1941,2005,1940, +2005,1941,2006, +1942,2006,1941, +2006,1942,2007, +1943,2007,1942, +2007,1943,2008, +1944,2008,1943, +2008,1944,2009, +1945,2009,1944, +2009,1945,2010, +1946,2010,1945, +2010,1946,2011, +1947,2011,1946, +2011,1947,2012, +1948,2012,1947, +2012,1948,2013, +1949,2013,1948, +2013,1949,2014, +1950,2014,1949, +2014,1950,2015, +1951,2015,1950, +2015,1951,2016, +1952,2016,1951, +2016,1952,2017, +1953,2017,1952, +2017,1953,2018, +1954,2018,1953, +2018,1954,2019, +1955,2019,1954, +2019,1955,2020, +1956,2020,1955, +2020,1956,2021, +1957,2021,1956, +2021,1957,2022, +1958,2022,1957, +2022,1958,2023, +1959,2023,1958, +2023,1959,2024, +1960,2024,1959, +2024,1960,2025, +1961,2025,1960, +2025,1961,2026, +1962,2026,1961, +2026,1962,2027, +1963,2027,1962, +2027,1963,2028, +1964,2028,1963, +2028,1964,2029, +1965,2029,1964, +2029,1965,2030, +1966,2030,1965, +2030,1966,2031, +1967,2031,1966, +2031,1967,2032, +1968,2032,1967, +2032,1968,2033, +1969,2033,1968, +2033,1969,2034, +1970,2034,1969, +2034,1970,2035, +1971,2035,1970, +2035,1971,2036, +1972,2036,1971, +2036,1972,2037, +1973,2037,1972, +2037,1973,2038, +1974,2038,1973, +2038,1974,2039, +1975,2039,1974, +2039,1975,2040, +1976,2040,1975, +2040,1976,2041, +1977,2041,1976, +2041,1977,2042, +1978,2042,1977, +2042,1978,2043, +1979,2043,1978, +2043,1979,2044, +1980,2044,1979, +2044,1980,2045, +1981,2045,1980, +2045,1981,2046, +1982,2046,1981, +2046,1982,2047, +1983,2047,1982, +}; + diff --git a/Demos/Benchmarks/main.cpp b/Demos/Benchmarks/main.cpp new file mode 100644 index 0000000..78c05e5 --- /dev/null +++ b/Demos/Benchmarks/main.cpp @@ -0,0 +1,89 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BenchmarkDemo.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" +#include + +#ifdef USE_GRAPHICAL_BENCHMARK + #include "GlutStuff.h" + #include "GLDebugDrawer.h" + GLDebugDrawer gDebugDrawer; +#define benchmarkDemo benchmarkDemo2 +#endif //USE_GRAPHICAL_BENCHMARK + + +#define NUM_DEMOS 7 +#define NUM_TESTS 200 + +extern bool gDisableDeactivation; + +int main(int argc,char** argv) +{ + gDisableDeactivation = true; + + BenchmarkDemo1 benchmarkDemo1; + BenchmarkDemo2 benchmarkDemo2; + BenchmarkDemo3 benchmarkDemo3; + BenchmarkDemo4 benchmarkDemo4; + BenchmarkDemo5 benchmarkDemo5; + BenchmarkDemo6 benchmarkDemo6; + BenchmarkDemo7 benchmarkDemo7; + + BenchmarkDemo* demoArray[NUM_DEMOS] = {&benchmarkDemo1,&benchmarkDemo2,&benchmarkDemo3,&benchmarkDemo4,&benchmarkDemo5,&benchmarkDemo6,&benchmarkDemo7}; + const char* demoNames[NUM_DEMOS] = {"3000 fall", "1000 stack", "136 ragdolls","1000 convex", "prim-trimesh", "convex-trimesh","raytests"}; + float totalTime[NUM_DEMOS] = {0.f,0.f,0.f,0.f,0.f,0.f,0.f}; + +#ifdef USE_GRAPHICAL_BENCHMARK + benchmarkDemo.initPhysics(); + benchmarkDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + benchmarkDemo.setDebugMode(benchmarkDemo.getDebugMode() | btIDebugDraw::DBG_NoDeactivation); + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&benchmarkDemo); + +#else //USE_GRAPHICAL_BENCHMARK + int d; + + for (d=0;dinitPhysics(); + + + for (int i=0;iclientMoveAndDisplay(); + float frameTime = CProfileManager::Get_Time_Since_Reset(); + if ((i % 25)==0) + { + printf("BenchmarkDemo: %s, Frame %d, Duration (ms): %f\n",demoNames[d],i,frameTime); + } + totalTime[d] += frameTime; + if (i==NUM_TESTS-1) + CProfileManager::dumpAll(); + + + } + demoArray[d]->exitPhysics(); + } + + for (d=0;d //printf debugging + + +void Box2dDemo::clientMoveAndDisplay() +{ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + if (m_dialogDynamicsWorld) + m_dialogDynamicsWorld->draw(ms / 1000000.f); + + glFlush(); + + swapBuffers(); + +} + + + +void Box2dDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + if (m_dialogDynamicsWorld) + m_dialogDynamicsWorld->draw(0.f); + + glFlush(); + swapBuffers(); +} + + + +void Box2dDemo::reshape(int w, int h) +{ + if (m_dialogDynamicsWorld) + m_dialogDynamicsWorld->setScreenSize(w,h); + PlatformDemoApplication::reshape(w,h); +} + +void Box2dDemo::initPhysics() +{ + + m_dialogDynamicsWorld = new GL_DialogDynamicsWorld(); + + //m_dialogDynamicsWorld->createDialog(100,110,200,50); + //m_dialogDynamicsWorld->createDialog(100,00,100,100); + //m_dialogDynamicsWorld->createDialog(0,0,100,100); + GL_DialogWindow* settings = m_dialogDynamicsWorld->createDialog(50,0,200,120,"Settings"); + GL_ToggleControl* toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 1"); + toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 2"); + toggle ->m_active = true; + toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 3"); + //GL_SliderControl* slider = m_dialogDynamicsWorld->createSlider(settings,"Slider"); + + GL_DialogWindow* dialog = m_dialogDynamicsWorld->createDialog(0,200,420,300,"Help"); + GL_TextControl* txt = new GL_TextControl; + dialog->addControl(txt); + txt->m_textLines.push_back("Mouse to move"); + txt->m_textLines.push_back("Test 2"); + txt->m_textLines.push_back("mouse to interact"); + txt->m_textLines.push_back("ALT + mouse to move camera"); + txt->m_textLines.push_back("space to reset"); + txt->m_textLines.push_back("cursor keys and z,x to navigate"); + txt->m_textLines.push_back("i to toggle simulation, s single step"); + txt->m_textLines.push_back("q to quit"); + txt->m_textLines.push_back(". to shoot box"); + txt->m_textLines.push_back("d to toggle deactivation"); + txt->m_textLines.push_back("g to toggle mesh animation (ConcaveDemo)"); + txt->m_textLines.push_back("h to toggle help text"); + txt->m_textLines.push_back("o to toggle orthogonal/perspective view"); + //txt->m_textLines.push_back("+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); + + + + setTexturing(true); + setShadows(true); + + setCameraDistance(btScalar(SCALING*50.)); + m_cameraTargetPosition.setValue(0,0,0);//0, ARRAY_SIZE_Y, 0); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + btVoronoiSimplexSolver* simplex = new btVoronoiSimplexSolver(); + btMinkowskiPenetrationDepthSolver* pdSolver = new btMinkowskiPenetrationDepthSolver(); + + + btConvex2dConvex2dAlgorithm::CreateFunc* convexAlgo2d = new btConvex2dConvex2dAlgorithm::CreateFunc(simplex,pdSolver); + + m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d); + m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d); + m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,convexAlgo2d); + m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,new btBox2dBox2dCollisionAlgorithm::CreateFunc()); + + m_broadphase = new btDbvtBroadphase(); + //m_broadphase = new btSimpleBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + //m_dynamicsWorld->getSolverInfo().m_erp = 1.f; + //m_dynamicsWorld->getSolverInfo().m_numIterations = 4; + + + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.),btScalar(50.),btScalar(150.))); +// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-43,0)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + btScalar u= btScalar(1*SCALING-0.04); + btVector3 points[3] = {btVector3(0,u,0),btVector3(-u,-u,0),btVector3(u,-u,0)}; + btConvexShape* childShape0 = new btBoxShape(btVector3(btScalar(SCALING*1),btScalar(SCALING*1),btScalar(0.04))); + btConvexShape* colShape= new btConvex2dShape(childShape0); + //btCollisionShape* colShape = new btBox2dShape(btVector3(SCALING*1,SCALING*1,0.04)); + btConvexShape* childShape1 = new btConvexHullShape(&points[0].getX(),3); + btConvexShape* colShape2= new btConvex2dShape(childShape1); + btConvexShape* childShape2 = new btCylinderShapeZ(btVector3(btScalar(SCALING*1),btScalar(SCALING*1),btScalar(0.04))); + btConvexShape* colShape3= new btConvex2dShape(childShape2); + + + m_collisionShapes.push_back(colShape); + m_collisionShapes.push_back(colShape2); + m_collisionShapes.push_back(colShape3); + + m_collisionShapes.push_back(childShape0); + m_collisionShapes.push_back(childShape1); + m_collisionShapes.push_back(childShape2); + + + //btUniformScalingShape* colShape = new btUniformScalingShape(convexColShape,1.f); + colShape->setMargin(btScalar(0.03)); + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); + +// float start_x = START_POS_X - ARRAY_SIZE_X/2; +// float start_y = START_POS_Y; +// float start_z = START_POS_Z - ARRAY_SIZE_Z/2; + + btVector3 x(-ARRAY_SIZE_X, 8.0f,-20.f); + btVector3 y; + btVector3 deltaX(SCALING*1, SCALING*2,0.f); + btVector3 deltaY(SCALING*2, 0.0f,0.f); + + for (int i = 0; i < ARRAY_SIZE_X; ++i) + { + y = x; + + for (int j = i; j < ARRAY_SIZE_Y; ++j) + { + startTransform.setOrigin(y-btVector3(-10,0,0)); + + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(0,0,0); + switch (j%3) + { +#if 1 + case 0: + rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape,localInertia); + break; + case 1: + rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape3,localInertia); + break; +#endif + default: + rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape2,localInertia); + } + btRigidBody* body = new btRigidBody(rbInfo); + //body->setContactProcessingThreshold(colShape->getContactBreakingThreshold()); + body->setActivationState(ISLAND_SLEEPING); + body->setLinearFactor(btVector3(1,1,0)); + body->setAngularFactor(btVector3(0,0,1)); + + m_dynamicsWorld->addRigidBody(body); + body->setActivationState(ISLAND_SLEEPING); + + + // y += -0.8*deltaY; + y += deltaY; + } + + x += deltaX; + } + + } + + + clientResetScene(); +} + + +void Box2dDemo::exitPhysics() +{ + delete m_dialogDynamicsWorld; + m_dialogDynamicsWorld = 0; + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + if (m_dynamicsWorld) + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jmouseFunc(button,state,x,y)) + { + DemoApplication::mouseFunc(button,state,x,y); + } +} + +void Box2dDemo::mouseMotionFunc(int x,int y) +{ + m_dialogDynamicsWorld->mouseMotionFunc(x,y); + DemoApplication::mouseMotionFunc(x,y); +} + diff --git a/Demos/Box2dDemo/Box2dDemo.h b/Demos/Box2dDemo/Box2dDemo.h new file mode 100644 index 0000000..02d4cc6 --- /dev/null +++ b/Demos/Box2dDemo/Box2dDemo.h @@ -0,0 +1,89 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BOX2D_DEMO_H +#define BOX2D_DEMO_H + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +#include "LinearMath/btAlignedObjectArray.h" + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; +class GL_DialogDynamicsWorld; + +///Box2dDemo is good starting point for learning the code base and porting. +class Box2dDemo : public PlatformDemoApplication +{ + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + GL_DialogDynamicsWorld* m_dialogDynamicsWorld; + + public: + + Box2dDemo() : m_dialogDynamicsWorld(0) + { + } + virtual ~Box2dDemo() + { + exitPhysics(); + } + + virtual void reshape(int w, int h); + + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + Box2dDemo* demo = new Box2dDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + virtual void mouseFunc(int button, int state, int x, int y); + virtual void mouseMotionFunc(int x,int y); + + +}; + +#endif //BOX2D_DEMO_H + diff --git a/Demos/Box2dDemo/CMakeLists.txt b/Demos/Box2dDemo/CMakeLists.txt new file mode 100644 index 0000000..0d40f7f --- /dev/null +++ b/Demos/Box2dDemo/CMakeLists.txt @@ -0,0 +1,75 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppBox2dDemo + main.cpp + Box2dDemo.cpp + Box2dDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppBox2dDemo + main.cpp + Box2dDemo.cpp + Box2dDemo.h + ) + ENDIF() + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBox2dDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBox2dDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + ENDIF(WIN32) +ELSE (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppBox2dDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32Box2dDemo.cpp + Box2dDemo.cpp + Box2dDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppBox2dDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppBox2dDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppBox2dDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + diff --git a/Demos/Box2dDemo/Win32Box2dDemo.cpp b/Demos/Box2dDemo/Win32Box2dDemo.cpp new file mode 100644 index 0000000..fb43906 --- /dev/null +++ b/Demos/Box2dDemo/Win32Box2dDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2dDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new Box2dDemo(); +} + +#endif diff --git a/Demos/Box2dDemo/main.cpp b/Demos/Box2dDemo/main.cpp new file mode 100644 index 0000000..1b0651c --- /dev/null +++ b/Demos/Box2dDemo/main.cpp @@ -0,0 +1,61 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2dDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + +class OurValue + { + int m_uid; + + public: + OurValue(const btVector3& initialPos) + :m_position(initialPos) + { + static int gUid=0; + m_uid=gUid; + gUid++; + } + + btVector3 m_position; + int getUid() const + { + return m_uid; + } + }; + + +int main(int argc,char** argv) +{ + GLDebugDrawer gDebugDrawer; + + Box2dDemo ccdDemo; + ccdDemo.initPhysics(); + ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/BspDemo/BspConverter.cpp b/Demos/BspDemo/BspConverter.cpp new file mode 100644 index 0000000..8d750c3 --- /dev/null +++ b/Demos/BspDemo/BspConverter.cpp @@ -0,0 +1,207 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BspConverter.h" +#include "BspLoader.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btGeometryUtil.h" +#include +#include + + +void BspConverter::convertBsp(BspLoader& bspLoader,float scaling) +{ + { + + float playstartf[3] = {0,0,100}; + + if (bspLoader.findVectorByName(&playstartf[0],"info_player_start")) + { + printf("found playerstart\n"); + } + else + { + if (bspLoader.findVectorByName(&playstartf[0],"info_player_deathmatch")) + { + printf("found deatchmatch start\n"); + } + } + + btVector3 playerStart (playstartf[0],playstartf[1],playstartf[2]); + + + playerStart[2] += 20.f; //start a bit higher + + playerStart *= scaling; + + + + //progressBegin("Loading bsp"); + + for (int i=0;i planeEquations; + + int brushid = bspLoader.m_dleafbrushes[leaf.firstLeafBrush+b]; + + BSPBrush& brush = bspLoader.m_dbrushes[brushid]; + if (brush.shaderNum!=-1) + { + if (bspLoader.m_dshaders[ brush.shaderNum ].contentFlags & BSPCONTENTS_SOLID) + { + brush.shaderNum = -1; + + for (int p=0;p vertices; + btGeometryUtil::getVerticesFromPlaneEquations(planeEquations,vertices); + + bool isEntity = false; + btVector3 entityTarget(0.f,0.f,0.f); + addConvexVerticesCollider(vertices,isEntity,entityTarget); + + } + } + } + } + } + +#define USE_ENTITIES +#ifdef USE_ENTITIES + + + { + int i; + for (i=0;i=0) && (modelnr < bspLoader.m_nummodels)) + { + const BSPModel& model = bspLoader.m_dmodels[modelnr]; + for (int n=0;n planeEquations; + bool isValidBrush = false; + + //convert brush + const BSPBrush& brush = bspLoader.m_dbrushes[model.firstBrush+n]; + { + for (int p=0;p vertices; + btGeometryUtil::getVerticesFromPlaneEquations(planeEquations,vertices); + + bool isEntity=true; + addConvexVerticesCollider(vertices,isEntity,targetLocation); + + } + } + + } + } + } + else + { + printf("unsupported trigger_push model, md3 ?\n"); + } + } + + } + } + } + } + +#endif //USE_ENTITIES + + + + //progressEnd(); + } + + } + + + + + + diff --git a/Demos/BspDemo/BspConverter.h b/Demos/BspDemo/BspConverter.h new file mode 100644 index 0000000..aca44db --- /dev/null +++ b/Demos/BspDemo/BspConverter.h @@ -0,0 +1,39 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BSP_CONVERTER_H +#define BSP_CONVERTER_H + +class BspLoader; +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedObjectArray.h" + +///BspConverter turns a loaded bsp level into convex parts (vertices) +class BspConverter +{ + public: + + void convertBsp(BspLoader& bspLoader,float scaling); + virtual ~BspConverter() + { + } + + ///this callback is called for each brush that succesfully converted into vertices + virtual void addConvexVerticesCollider(btAlignedObjectArray& vertices, bool isEntity, const btVector3& entityTargetLocation) = 0; + +}; + +#endif //BSP_CONVERTER_H + diff --git a/Demos/BspDemo/BspDemo.cpp b/Demos/BspDemo/BspDemo.cpp new file mode 100644 index 0000000..8301eac --- /dev/null +++ b/Demos/BspDemo/BspDemo.cpp @@ -0,0 +1,321 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" + +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btIDebugDraw.h" + +#include "GLDebugDrawer.h" + + +#define QUAKE_BSP_IMPORTING 1 + +#ifdef QUAKE_BSP_IMPORTING +#include "BspLoader.h" +#include "BspConverter.h" +#endif //QUAKE_BSP_IMPORTING + + +#include //printf debugging + + +#include "BspDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + + + + +#define CUBE_HALF_EXTENTS 1 +#define EXTRA_HEIGHT -20.f + + + +///BspToBulletConverter extends the BspConverter to convert to Bullet datastructures +class BspToBulletConverter : public BspConverter +{ + BspDemo* m_demoApp; + +public: + + BspToBulletConverter(BspDemo* demoApp) + :m_demoApp(demoApp) + { + } + + virtual void addConvexVerticesCollider(btAlignedObjectArray& vertices, bool isEntity, const btVector3& entityTargetLocation) + { + ///perhaps we can do something special with entities (isEntity) + ///like adding a collision Triggering (as example) + + if (vertices.size() > 0) + { + float mass = 0.f; + btTransform startTransform; + //can use a shift + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,0,-10.f)); + //this create an internal copy of the vertices + + btCollisionShape* shape = new btConvexHullShape(&(vertices[0].getX()),vertices.size()); + m_demoApp->m_collisionShapes.push_back(shape); + + //btRigidBody* body = m_demoApp->localCreateRigidBody(mass, startTransform,shape); + m_demoApp->localCreateRigidBody(mass, startTransform,shape); + } + } +}; + + + + + +//////////////////////////////////// + + + + + + + +BspDemo::~BspDemo() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jsetGravity(-m_cameraUp * 10); + + +#ifdef QUAKE_BSP_IMPORTING + + void* memoryBuffer = 0; + + FILE* file = fopen(bspfilename,"r"); + if (!file) + { + //try again other path, + //sight... visual studio leaves the current working directory in the projectfiles folder + //instead of executable folder. who wants this default behaviour?!? + bspfilename = "../../BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + if (!file) + { + + //try again other path, cmake needs 4 levels deep back... + bspfilename = "../../../../BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + if (!file) + { + //try again other path, + //sight... visual studio leaves the current working directory in the projectfiles folder + //instead of executable folder. who wants this default behaviour?!? + bspfilename = "BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + + if (file) + { + BspLoader bspLoader; + int size=0; + if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ + printf("Error: cannot get filesize from %s\n", bspfilename); + } else + { + //how to detect file size? + memoryBuffer = malloc(size+1); + fread(memoryBuffer,1,size,file); + bspLoader.loadBSPFile( memoryBuffer); + + BspToBulletConverter bsp2bullet(this); + float bspScaling = 0.1f; + bsp2bullet.convertBsp(bspLoader,bspScaling); + + } + fclose(file); + } + +#endif + + + + + clientResetScene(); + +} + + +void BspDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + glutSwapBuffers(); + +} + + + +void BspDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + glutSwapBuffers(); +} + + + + + + +//some code that de-mangles the windows filename passed in as argument +char cleaned_filename[512]; +char* getLastFileName() +{ + return cleaned_filename; +} +char* makeExeToBspFilename(const char* lpCmdLine) +{ + + + // We might get a windows-style path on the command line, this can mess up the DOM which expects + // all paths to be URI's. This block of code does some conversion to try and make the input + // compliant without breaking the ability to accept a properly formatted URI. Right now this only + // displays the first filename + const char *in = lpCmdLine; + char* out = cleaned_filename; + *out = '\0'; + // If the first character is a ", skip it (filenames with spaces in them are quoted) + if(*in == '\"') + { + in++; + } + int i; + for(i =0; i<512; i++) + { + //if we get '.' we stop as well, unless it's the first character. Then we add .bsp as extension + // If we hit a null or a quote, stop copying. This will get just the first filename. + if(i && (in[0] == '.') && (in[1] == 'e') && (in[2] == 'x') && (in[3] == 'e')) + break; + + // If we hit a null or a quote, stop copying. This will get just the first filename. + if(*in == '\0' || *in == '\"') + break; + // Copy while swapping backslashes for forward ones + if(*in == '\\') + { + *out = '/'; + } + else + { + *out = *in; + } + in++; + out++; + } + *(out++) = '.'; + *(out++) = 'b'; + *(out++) = 's'; + *(out++) = 'p'; + *(out++) = 0; + + return cleaned_filename; +} diff --git a/Demos/BspDemo/BspDemo.h b/Demos/BspDemo/BspDemo.h new file mode 100644 index 0000000..d2f5d7a --- /dev/null +++ b/Demos/BspDemo/BspDemo.h @@ -0,0 +1,71 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BSP_DEMO_H +#define BSP_DEMO_H + +#include "GlutDemoApplication.h" +#include "LinearMath/btAlignedObjectArray.h" + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; + + +///BspDemo shows the convex collision detection, by converting a Quake BSP file into convex objects and allowing interaction with boxes. +class BspDemo : public GlutDemoApplication +{ + public: + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + + + + virtual ~BspDemo(); + + virtual void initPhysics(); + + void initPhysics(const char* bspfilename); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + BspDemo* demo = new BspDemo; + demo->myinit(); + demo->initPhysics("BspDemo.bsp"); + return demo; + } + +}; + +#endif //BSP_DEMO_H + + diff --git a/Demos/BspDemo/BspLoader.cpp b/Demos/BspDemo/BspLoader.cpp new file mode 100644 index 0000000..0572463 --- /dev/null +++ b/Demos/BspDemo/BspLoader.cpp @@ -0,0 +1,730 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU bteral Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU bteral Public License for more details. + +You should have received a copy of the GNU bteral Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + + +#include "BspLoader.h" +#include +#include + +typedef struct +{ + char filename[1024]; + char *buffer,*script_p,*end_p; + int line; +} BSPScript; + +#define MAX_INCLUDES 8 +BSPScript scriptstack[MAX_INCLUDES]; +BSPScript *script; +int scriptline; + +char token[BSPMAXTOKEN]; +bool endofscript; +bool tokenready; // only true if UnGetToken was just called + +// +//loadBSPFile +// + +int extrasize = 100; + +BspLoader::BspLoader() + :m_num_entities(0) +{ + m_Endianness = getMachineEndianness(); + if (m_Endianness == BSP_BIG_ENDIAN) + { + printf("Machine is BIG_ENDIAN\n"); + } else + { + printf("Machine is Little Endian\n"); + } +} + + +bool BspLoader::loadBSPFile( void* memoryBuffer) { + + BSPHeader *header = (BSPHeader*) memoryBuffer; + + // load the file header + if (header) + { + // swap the header + swapBlock( (int *)header, sizeof(*header) ); + + int length = (header->lumps[BSPLUMP_SHADERS].filelen) / sizeof(BSPShader); + m_dshaders.resize(length+extrasize); + m_numShaders = copyLump( header, BSPLUMP_SHADERS, &m_dshaders[0], sizeof(BSPShader) ); + + length = (header->lumps[LUMP_MODELS].filelen) / sizeof(BSPModel); + m_dmodels.resize(length+extrasize); + m_nummodels = copyLump( header, LUMP_MODELS, &m_dmodels[0], sizeof(BSPModel) ); + + length = (header->lumps[BSPLUMP_PLANES].filelen) / sizeof(BSPPlane); + m_dplanes.resize(length+extrasize); + m_numplanes = copyLump( header, BSPLUMP_PLANES, &m_dplanes[0], sizeof(BSPPlane) ); + + length = (header->lumps[BSPLUMP_LEAFS].filelen) / sizeof(BSPLeaf); + m_dleafs.resize(length+extrasize); + m_numleafs = copyLump( header, BSPLUMP_LEAFS, &m_dleafs[0], sizeof(BSPLeaf) ); + + length = (header->lumps[BSPLUMP_NODES].filelen) / sizeof(BSPNode); + m_dnodes.resize(length+extrasize); + m_numnodes = copyLump( header, BSPLUMP_NODES, &m_dnodes[0], sizeof(BSPNode) ); + + length = (header->lumps[BSPLUMP_LEAFSURFACES].filelen) / sizeof(m_dleafsurfaces[0]); + m_dleafsurfaces.resize(length+extrasize); + m_numleafsurfaces = copyLump( header, BSPLUMP_LEAFSURFACES, &m_dleafsurfaces[0], sizeof(m_dleafsurfaces[0]) ); + + length = (header->lumps[BSPLUMP_LEAFBRUSHES].filelen) / sizeof(m_dleafbrushes[0]) ; + m_dleafbrushes.resize(length+extrasize); + m_numleafbrushes = copyLump( header, BSPLUMP_LEAFBRUSHES, &m_dleafbrushes[0], sizeof(m_dleafbrushes[0]) ); + + length = (header->lumps[LUMP_BRUSHES].filelen) / sizeof(BSPBrush); + m_dbrushes.resize(length+extrasize); + m_numbrushes = copyLump( header, LUMP_BRUSHES, &m_dbrushes[0], sizeof(BSPBrush) ); + + + length = (header->lumps[LUMP_BRUSHSIDES].filelen) / sizeof(BSPBrushSide); + m_dbrushsides.resize(length+extrasize); + m_numbrushsides = copyLump( header, LUMP_BRUSHSIDES, &m_dbrushsides[0], sizeof(BSPBrushSide) ); + + + length = (header->lumps[LUMP_SURFACES].filelen) / sizeof(BSPSurface); + m_drawSurfaces.resize(length+extrasize); + m_numDrawSurfaces = copyLump( header, LUMP_SURFACES, &m_drawSurfaces[0], sizeof(BSPSurface) ); + + + length = (header->lumps[LUMP_DRAWINDEXES].filelen) / sizeof(m_drawIndexes[0]); + m_drawIndexes.resize(length+extrasize); + m_numDrawIndexes = copyLump( header, LUMP_DRAWINDEXES, &m_drawIndexes[0], sizeof(m_drawIndexes[0]) ); + + length = (header->lumps[LUMP_VISIBILITY].filelen) / 1; + m_visBytes.resize(length+extrasize); + m_numVisBytes = copyLump( header, LUMP_VISIBILITY, &m_visBytes[0], 1 ); + + length = (header->lumps[LUMP_LIGHTMAPS].filelen) / 1; + m_lightBytes.resize(length+extrasize); + m_numLightBytes = copyLump( header, LUMP_LIGHTMAPS, &m_lightBytes[0], 1 ); + + length = (header->lumps[BSPLUMP_ENTITIES].filelen) / 1; + m_dentdata.resize(length+extrasize); + m_entdatasize = copyLump( header, BSPLUMP_ENTITIES, &m_dentdata[0], 1); + + length = (header->lumps[LUMP_LIGHTGRID].filelen) / 1; + m_gridData.resize(length+extrasize); + m_numGridPoints = copyLump( header, LUMP_LIGHTGRID, &m_gridData[0], 8 ); + + // swap everything + swapBSPFile(); + + return true; + + } + return false; +} + + + +const char* BspLoader::getValueForKey( const BSPEntity* ent, const char* key ) const { + + const BSPKeyValuePair* ep; + + for (ep=ent->epairs ; ep ; ep=ep->next) { + if (!strcmp(ep->key, key) ) { + return ep->value; + } + } + return ""; +} + +float BspLoader::getFloatForKey( const BSPEntity *ent, const char *key ) { + const char *k; + + k = getValueForKey( ent, key ); + return float(atof(k)); +} + +bool BspLoader::getVectorForKey( const BSPEntity *ent, const char *key, BSPVector3 vec ) { + + const char *k; + k = getValueForKey (ent, key); + if (strcmp(k, "")) + { + sscanf (k, "%f %f %f", &vec[0], &vec[1], &vec[2]); + return true; + } + return false; +} + + + + +/* +============== +parseFromMemory +============== +*/ +void BspLoader::parseFromMemory (char *buffer, int size) +{ + script = scriptstack; + script++; + if (script == &scriptstack[MAX_INCLUDES]) + { + //printf("script file exceeded MAX_INCLUDES"); + } + strcpy (script->filename, "memory buffer" ); + + script->buffer = buffer; + script->line = 1; + script->script_p = script->buffer; + script->end_p = script->buffer + size; + + endofscript = false; + tokenready = false; +} + + +bool BspLoader::isEndOfScript (bool crossline) +{ + if (!crossline) + //printf("Line %i is incomplete\n",scriptline); + + if (!strcmp (script->filename, "memory buffer")) + { + endofscript = true; + return false; + } + + //free (script->buffer); + if (script == scriptstack+1) + { + endofscript = true; + return false; + } + script--; + scriptline = script->line; + //printf ("returning to %s\n", script->filename); + return getToken (crossline); +} + +/* + +============== +getToken +============== +*/ +bool BspLoader::getToken (bool crossline) +{ + char *token_p; + + if (tokenready) // is a token allready waiting? + { + tokenready = false; + return true; + } + + if (script->script_p >= script->end_p) + return isEndOfScript (crossline); + +// +// skip space +// +skipspace: + while (*script->script_p <= 32) + { + if (script->script_p >= script->end_p) + return isEndOfScript (crossline); + if (*script->script_p++ == '\n') + { + if (!crossline) + { + //printf("Line %i is incomplete\n",scriptline); + } + scriptline = script->line++; + } + } + + if (script->script_p >= script->end_p) + return isEndOfScript (crossline); + + // ; # // comments + if (*script->script_p == ';' || *script->script_p == '#' + || ( script->script_p[0] == '/' && script->script_p[1] == '/') ) + { + if (!crossline) + { + //printf("Line %i is incomplete\n",scriptline); + } + while (*script->script_p++ != '\n') + if (script->script_p >= script->end_p) + return isEndOfScript (crossline); + scriptline = script->line++; + goto skipspace; + } + + // /* */ comments + if (script->script_p[0] == '/' && script->script_p[1] == '*') + { + if (!crossline) + { + //printf("Line %i is incomplete\n",scriptline); + } + script->script_p+=2; + while (script->script_p[0] != '*' && script->script_p[1] != '/') + { + if ( *script->script_p == '\n' ) { + scriptline = script->line++; + } + script->script_p++; + if (script->script_p >= script->end_p) + return isEndOfScript (crossline); + } + script->script_p += 2; + goto skipspace; + } + +// +// copy token +// + token_p = token; + + if (*script->script_p == '"') + { + // quoted token + script->script_p++; + while (*script->script_p != '"') + { + *token_p++ = *script->script_p++; + if (script->script_p == script->end_p) + break; + if (token_p == &token[BSPMAXTOKEN]) + { + //printf ("Token too large on line %i\n",scriptline); + } + } + script->script_p++; + } + else // regular token + while ( *script->script_p > 32 && *script->script_p != ';') + { + *token_p++ = *script->script_p++; + if (script->script_p == script->end_p) + break; + if (token_p == &token[BSPMAXTOKEN]) + { + //printf ("Token too large on line %i\n",scriptline); + } + } + + *token_p = 0; + + if (!strcmp (token, "$include")) + { + //getToken (false); + //AddScriptToStack (token); + return false;//getToken (crossline); + } + + return true; +} + +char *BspLoader::copystring(const char *s) +{ + char *b; + b = (char*) malloc( strlen(s)+1); + strcpy (b, s); + return b; +} + +void BspLoader::stripTrailing( char *e ) { + char *s; + + s = e + strlen(e)-1; + while (s >= e && *s <= 32) + { + *s = 0; + s--; + } +} +/* +================= +parseEpair +================= +*/ +BSPKeyValuePair *BspLoader::parseEpair( void ) { + BSPKeyValuePair *e; + + e = (struct BSPPair*) malloc( sizeof(BSPKeyValuePair)); + memset( e, 0, sizeof(BSPKeyValuePair) ); + + if ( strlen(token) >= BSPMAX_KEY-1 ) { + //printf ("ParseEpar: token too long"); + } + e->key = copystring( token ); + getToken( false ); + if ( strlen(token) >= BSPMAX_VALUE-1 ) { + + //printf ("ParseEpar: token too long"); + } + e->value = copystring( token ); + + // strip trailing spaces that sometimes get accidentally + // added in the editor + stripTrailing( e->key ); + stripTrailing( e->value ); + + return e; +} + + +/* +================ +parseEntity +================ +*/ +bool BspLoader::parseEntity( void ) { + BSPKeyValuePair *e; + BSPEntity *mapent; + + if ( !getToken (true) ) { + return false; + } + + if ( strcmp (token, "{") ) { + + //printf ("parseEntity: { not found"); + } + + BSPEntity bla; + bla.brushes = 0; + bla.epairs = 0; + bla.firstDrawSurf = 0; + bla.origin[0] = 0.f; + bla.origin[1] = 0.f; + bla.origin[2] = 0.f; + bla.patches = 0; + + m_entities.push_back(bla); + mapent = &m_entities[m_entities.size()-1]; + m_num_entities++; + + do { + if ( !getToken (true) ) { + //printf("parseEntity: EOF without closing brace"); + } + if ( !strcmp (token, "}") ) { + break; + } + e = (struct BSPPair*)parseEpair (); + e->next = mapent->epairs; + mapent->epairs = e; + } while (1); + + return true; +} + +/* +================ +parseEntities + +Parses the dentdata string into entities +================ +*/ +void BspLoader::parseEntities( void ) { + m_num_entities = 0; + m_entities.clear(); + + parseFromMemory( &m_dentdata[0], m_entdatasize ); + + while ( parseEntity () ) { + } +} + + + +int BspLoader::getMachineEndianness() +{ + long int i = 1; + const char *p = (const char *) &i; + if (p[0] == 1) // Lowest address contains the least significant byte + return BSP_LITTLE_ENDIAN; + else + return BSP_BIG_ENDIAN; +} + +short BspLoader::isLittleShort (short l) +{ + if (machineEndianness() == BSP_BIG_ENDIAN) + { + unsigned char b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; + } + //little endian + return l; +} + +short BspLoader::isBigShort (short l) +{ + if (machineEndianness() == BSP_BIG_ENDIAN) + { + return l; + } + + unsigned char b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; + + + +} + + +int BspLoader::isLittleLong (int l) +{ + if (machineEndianness() == BSP_BIG_ENDIAN) + { + unsigned char b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; + } + + //little endian + return l; + +} + +int BspLoader::isBigLong (int l) +{ + if (machineEndianness() == BSP_BIG_ENDIAN) + { + return l; + } + + + unsigned char b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; + +} + + +float BspLoader::isLittleFloat (float l) +{ + if (machineEndianness() == BSP_BIG_ENDIAN) + { + union {unsigned char b[4]; float f;} in, out; + + in.f = l; + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + + return out.f; + } + + //little endian + return l; +} + +float BspLoader::isBigFloat (float l) +{ + if (machineEndianness() == BSP_BIG_ENDIAN) + { + return l; + } + //little endian + union {unsigned char b[4]; float f;} in, out; + + in.f = l; + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + + return out.f; +} + + + + + + +// +// swapBlock +// If all values are 32 bits, this can be used to swap everything +// + +void BspLoader::swapBlock( int *block, int sizeOfBlock ) { + int i; + + sizeOfBlock >>= 2; + for ( i = 0 ; i < sizeOfBlock ; i++ ) { + block[i] = isLittleLong( block[i] ); + } +} + +// +// copyLump +// + +int BspLoader::copyLump( BSPHeader *header, int lump, void *dest, int size ) { + int length, ofs; + + length = header->lumps[lump].filelen; + ofs = header->lumps[lump].fileofs; + + //if ( length % size ) { + // printf ("loadBSPFile: odd lump size"); + //} + + memcpy( dest, (unsigned char *)header + ofs, length ); + + return length / size; +} + + + + +// +// swapBSPFile +// + +void BspLoader::swapBSPFile( void ) { + int i; + + // models + swapBlock( (int *) &m_dmodels[0], m_nummodels * sizeof( m_dmodels[0] ) ); + + // shaders (don't swap the name) + for ( i = 0 ; i < m_numShaders ; i++ ) { + m_dshaders[i].contentFlags = isLittleLong( m_dshaders[i].contentFlags ); + m_dshaders[i].surfaceFlags = isLittleLong( m_dshaders[i].surfaceFlags ); + } + + // planes + swapBlock( (int *)&m_dplanes[0], m_numplanes * sizeof( m_dplanes[0] ) ); + + // nodes + swapBlock( (int *)&m_dnodes[0], m_numnodes * sizeof( m_dnodes[0] ) ); + + // leafs + swapBlock( (int *)&m_dleafs[0], m_numleafs * sizeof( m_dleafs[0] ) ); + + // leaffaces + swapBlock( (int *)&m_dleafsurfaces[0], m_numleafsurfaces * sizeof( m_dleafsurfaces[0] ) ); + + // leafbrushes + swapBlock( (int *)&m_dleafbrushes[0], m_numleafbrushes * sizeof( m_dleafbrushes[0] ) ); + + // brushes + swapBlock( (int *)&m_dbrushes[0], m_numbrushes * sizeof( m_dbrushes[0] ) ); + + // brushsides + swapBlock( (int *)&m_dbrushsides[0], m_numbrushsides * sizeof( m_dbrushsides[0] ) ); + + // vis + ((int *)&m_visBytes)[0] = isLittleLong( ((int *)&m_visBytes)[0] ); + ((int *)&m_visBytes)[1] = isLittleLong( ((int *)&m_visBytes)[1] ); + + + // drawindexes + swapBlock( (int *)&m_drawIndexes[0], m_numDrawIndexes * sizeof( m_drawIndexes[0] ) ); + + // drawsurfs + swapBlock( (int *)&m_drawSurfaces[0], m_numDrawSurfaces * sizeof( m_drawSurfaces[0] ) ); + +} + + + + + +bool BspLoader::findVectorByName(float* outvec,const char* name) +{ + const char *cl; + BSPVector3 origin; + + bool found = false; + + parseEntities(); + + for ( int i = 1; i < m_num_entities; i++ ) { + cl = getValueForKey (&m_entities[i], "classname"); + if ( !strcmp( cl, "info_player_start" ) ) { + getVectorForKey( &m_entities[i], "origin", origin ); + found = true; + break; + } + if ( !strcmp( cl, "info_player_deathmatch" ) ) { + getVectorForKey( &m_entities[i], "origin", origin ); + found = true; + break; + } + } + + if (found) + { + outvec[0] = origin[0]; + outvec[1] = origin[1]; + outvec[2] = origin[2]; + } + return found; +} + + + +const BSPEntity * BspLoader::getEntityByValue( const char* name, const char* value) +{ + const BSPEntity* entity = NULL; + + for ( int i = 1; i < m_num_entities; i++ ) { + + const BSPEntity& ent = m_entities[i]; + + const char* cl = getValueForKey (&m_entities[i], name); + if ( !strcmp( cl, value ) ) { + entity = &ent; + break; + } + } + return entity; +} + diff --git a/Demos/BspDemo/BspLoader.h b/Demos/BspDemo/BspLoader.h new file mode 100644 index 0000000..b7fc302 --- /dev/null +++ b/Demos/BspDemo/BspLoader.h @@ -0,0 +1,295 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU bteral Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU bteral Public License for more details. + +You should have received a copy of the GNU bteral Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + + + +#ifndef BSP_LOADER_H +#define BSP_LOADER_H + +#include "LinearMath/btAlignedObjectArray.h" + +#define BSPMAXTOKEN 1024 +#define BSPMAX_KEY 32 +#define BSPMAX_VALUE 1024 +#define BSPCONTENTS_SOLID 1 +#define BSPCONTENTS_AREAPORTAL 0x8000 +#define BSPLUMP_ENTITIES 0 +#define BSPLUMP_SHADERS 1 +#define BSPLUMP_PLANES 2 +#define BSPLUMP_NODES 3 +#define BSPLUMP_LEAFS 4 +#define BSPLUMP_LEAFSURFACES 5 +#define BSPLUMP_LEAFBRUSHES 6 +#define LUMP_MODELS 7 +#define LUMP_BRUSHES 8 +#define LUMP_BRUSHSIDES 9 +#define LUMP_DRAWVERTS 10 +#define LUMP_DRAWINDEXES 11 +#define LUMP_SURFACES 13 +#define LUMP_LIGHTMAPS 14 +#define LUMP_LIGHTGRID 15 +#define LUMP_VISIBILITY 16 +#define HEADER_LUMPS 17 +#define MAX_QPATH 64 + + + +typedef struct { + int fileofs, filelen; +} BSPLump; + +typedef float BSPVector3[3]; + +typedef struct { + int ident; + int version; + + BSPLump lumps[HEADER_LUMPS]; +} BSPHeader; + + +typedef struct { + float mins[3], maxs[3]; + int firstSurface, numSurfaces; + int firstBrush, numBrushes; +} BSPModel; + +typedef struct { + char shader[MAX_QPATH]; + int surfaceFlags; + int contentFlags; +} BSPShader; + +typedef struct { + float normal[3]; + float dist; +} BSPPlane; + +typedef struct { + int planeNum; + int children[2]; + int mins[3]; + int maxs[3]; +} BSPNode; + +typedef struct { + int cluster; + int area; + + int mins[3]; + int maxs[3]; + + int firstLeafSurface; + int numLeafSurfaces; + + int firstLeafBrush; + int numLeafBrushes; +} BSPLeaf; + +typedef struct { + int planeNum; + int shaderNum; +} BSPBrushSide; + +typedef struct { + int firstSide; + int numSides; + int shaderNum; +} BSPBrush; + + + + +typedef struct BSPPair { + struct BSPPair *next; + char *key; + char *value; +} BSPKeyValuePair; + +typedef struct { + BSPVector3 origin; + struct bspbrush_s *brushes; + struct parseMesh_s *patches; + int firstDrawSurf; + BSPKeyValuePair *epairs; +} BSPEntity; + +typedef enum { + MST_BAD, + MST_PLANAR, + MST_PATCH, + MST_TRIANGLE_SOUP, + MST_FLARE +} BSPMapSurface; + +typedef struct { + int shaderNum; + int fogNum; + int surfaceType; + + int firstVert; + int numVerts; + + int firstIndex; + int numIndexes; + + int lightmapNum; + int lightmapX, lightmapY; + int lightmapWidth, lightmapHeight; + + BSPVector3 lightmapOrigin; + BSPVector3 lightmapVecs[3]; + + int patchWidth; + int patchHeight; +} BSPSurface; + + + +///GPL code from IdSofware to parse a Quake 3 BSP file +///check that your platform define __BIG_ENDIAN__ correctly (in BspLoader.cpp) +class BspLoader +{ + int m_Endianness; + + public: + + BspLoader(); + + bool loadBSPFile( void* memoryBuffer); + + const char* getValueForKey( const BSPEntity *ent, const char *key ) const; + + bool getVectorForKey( const BSPEntity *ent, const char *key, BSPVector3 vec ); + + float getFloatForKey( const BSPEntity *ent, const char *key ); + + void parseEntities( void ); + + bool findVectorByName(float* outvec,const char* name); + + const BSPEntity * getEntityByValue( const char* name, const char* value); + + + protected: + + void parseFromMemory (char *buffer, int size); + + + + bool isEndOfScript (bool crossline); + + bool getToken (bool crossline); + + char *copystring(const char *s); + + void stripTrailing( char *e ); + + BSPKeyValuePair * parseEpair( void ); + + bool parseEntity( void ); + + short isLittleShort (short l); + int isLittleLong (int l); + float isLittleFloat (float l); + + int isBigLong (int l); + short isBigShort (short l); + float isBigFloat (float l); + + void swapBlock( int *block, int sizeOfBlock ); + + int copyLump( BSPHeader *header, int lump, void *dest, int size ); + + void swapBSPFile( void ); + + + + + public: //easier for conversion + int m_num_entities; + btAlignedObjectArray m_entities; + + int m_nummodels; + btAlignedObjectArray m_dmodels; + + int m_numShaders; + btAlignedObjectArray m_dshaders; + + int m_entdatasize; + btAlignedObjectArray m_dentdata; + + int m_numleafs; + btAlignedObjectArray m_dleafs; + + int m_numplanes; + btAlignedObjectArray m_dplanes; + + int m_numnodes; + btAlignedObjectArray m_dnodes; + + int m_numleafsurfaces; + btAlignedObjectArray m_dleafsurfaces; + + int m_numleafbrushes; + btAlignedObjectArray m_dleafbrushes; + + int m_numbrushes; + btAlignedObjectArray m_dbrushes; + + int m_numbrushsides; + btAlignedObjectArray m_dbrushsides; + + int m_numLightBytes; + btAlignedObjectArray m_lightBytes; + + int m_numGridPoints; + btAlignedObjectArray m_gridData; + + int m_numVisBytes; + btAlignedObjectArray m_visBytes; + + + int m_numDrawIndexes; + btAlignedObjectArray m_drawIndexes; + + int m_numDrawSurfaces; + btAlignedObjectArray m_drawSurfaces; + + enum + { + BSP_LITTLE_ENDIAN = 0, + BSP_BIG_ENDIAN = 1 + }; + + //returns machines big endian / little endian + // + int getMachineEndianness(); + + inline int machineEndianness() + { + return m_Endianness; + } + +}; + +#endif //BSP_LOADER_H diff --git a/Demos/BspDemo/CMakeLists.txt b/Demos/BspDemo/CMakeLists.txt new file mode 100644 index 0000000..6105a18 --- /dev/null +++ b/Demos/BspDemo/CMakeLists.txt @@ -0,0 +1,60 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppBspPhysicsDemo + main.cpp + BspDemo.cpp + BspLoader.cpp + BspConverter.cpp +) + + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBspPhysicsDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBspPhysicsDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + + + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( + TARGET AppBspPhysicsDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/BspDemo.bsp ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppBspPhysicsDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppBspPhysicsDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppBspPhysicsDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/BspDemo/main.cpp b/Demos/BspDemo/main.cpp new file mode 100644 index 0000000..e957fa1 --- /dev/null +++ b/Demos/BspDemo/main.cpp @@ -0,0 +1,59 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "BspDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +char* makeExeToBspFilename(const char* lpCmdLine); +char* getLastFileName(); + + +int main(int argc,char** argv) +{ + + BspDemo* bspDemo = new BspDemo(); + + const char* bspfilename = "BspDemo.bsp"; + + printf("argc=%i\n",argc); + { + for (int i=0;i1) + { + bspfilename = argv[1]; + } + + GLDebugDrawer gDebugDrawer; + + // Enrico: TODO: Should change parameter type of initPhysics() to std::string or at least const char * + bspDemo->initPhysics((char*)bspfilename); + + bspDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + + + return glutmain(argc, argv,640,480,"Bullet Quake BSP Physics Viewer http://bulletphysics.org",bspDemo); +} + diff --git a/Demos/BulletDinoDemo/BulletDino.c b/Demos/BulletDinoDemo/BulletDino.c new file mode 100644 index 0000000..146f28d --- /dev/null +++ b/Demos/BulletDinoDemo/BulletDino.c @@ -0,0 +1,996 @@ + +/* This demo has been modified to use the Bullet C-API. + The C-API is minimal, and will develop based on developer feedback. + The C++ API is recommended, and compatible with the C-API. +*/ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +/* Example for PC game developers to show how to *combine* texturing, + reflections, and projected shadows all in real-time with OpenGL. + Robust reflections use stenciling. Robust projected shadows + use both stenciling and polygon offset. PC game programmers + should realize that neither stenciling nor polygon offset are + supported by Direct3D, so these real-time rendering algorithms + are only really viable with OpenGL. + + The program has modes for disabling the stenciling and polygon + offset uses. It is worth running this example with these features + toggled off so you can see the sort of artifacts that result. + + Notice that the floor texturing, reflections, and shadowing + all co-exist properly. */ + +/* When you run this program: Left mouse button controls the + view. Middle mouse button controls light position (left & + right rotates light around dino; up & down moves light + position up and down). Right mouse button pops up menu. */ + +/* Check out the comments in the "redraw" routine to see how the + reflection blending and surface stenciling is done. You can + also see in "redraw" how the projected shadows are rendered, + including the use of stenciling and polygon offset. */ + +/* This program is derived from glutdino.c */ + +/* Compile: cc -o dinoshade dinoshade.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */ + +#include +#include +#include +#include /* for cos(), sin(), and sqrt() */ +#ifdef WIN32//for glut.h +#include +#endif + +#ifndef WIN32 +#ifndef CALLBACK +#define CALLBACK +#endif +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#define GLVOIDPTR GLvoid(*)() +#else +#include +#include +#define GLVOIDPTR void(CALLBACK*)() +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265 +#endif + + +//#include "../../include/Bullet-C-Api.h" +#include "Bullet-C-Api.h" + + + +plPhysicsSdkHandle physicsSdk=0; +plDynamicsWorldHandle dynamicsWorld=0; +plRigidBodyHandle floorRigidBody; +plRigidBodyHandle dinoRigidBody; + +/* Variable controlling various rendering modes. */ +static int stencilReflection = 1, stencilShadow = 1, offsetShadow = 1; +static int renderShadow = 1, renderDinosaur = 1, renderReflection = 1; +static int linearFiltering = 0, useMipmaps = 0, useTexture = 1; +static int reportSpeed = 0; +static int animation = 1; +static GLboolean lightSwitch = GL_TRUE; +static int directionalLight = 1; +static int forceExtension = 0; + +/* Time varying or user-controled variables. */ +static float jump = 0.0; +static float lightAngle = 0.0, lightHeight = 20; +GLfloat angle = -150; /* in degrees */ +GLfloat angle2 = 30; /* in degrees */ + +int moving, startx, starty; +int lightMoving = 0, lightStartX, lightStartY; + +enum { + MISSING, EXTENSION, ONE_DOT_ONE +}; +int polygonOffsetVersion; + +static GLdouble bodyWidth = 3.0; +/* *INDENT-OFF* */ +static GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5}, + {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16}, + {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2}, + {1, 2} }; +static GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9}, + {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10}, + {13, 9}, {11, 11}, {9, 11} }; +static GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0}, + {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} }; +static GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15}, + {9.6, 15.25}, {9, 15.25} }; +static GLfloat lightPosition[4]; +static GLfloat lightColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */ +static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0}; +/* *INDENT-ON* */ + +/* Nice floor texture tiling pattern. */ +static char *circles[] = { + "....xxxx........", + "..xxxxxxxx......", + ".xxxxxxxxxx.....", + ".xxx....xxx.....", + "xxx......xxx....", + "xxx......xxx....", + "xxx......xxx....", + "xxx......xxx....", + ".xxx....xxx.....", + ".xxxxxxxxxx.....", + "..xxxxxxxx......", + "....xxxx........", + "................", + "................", + "................", + "................", +}; + +static void +makeFloorTexture(void) +{ + GLubyte floorTexture[16][16][3]; + GLubyte *loc; + int s, t; + loc=0; + + /* Setup RGB image for the texture. */ + loc = (GLubyte*) floorTexture; + for (t = 0; t < 16; t++) { + for (s = 0; s < 16; s++) { + if (circles[t][s] == 'x') { + /* Nice green. */ + loc[0] = 0x1f; + loc[1] = 0x8f; + loc[2] = 0x1f; + } else { + /* Light gray. */ + loc[0] = 0xaa; + loc[1] = 0xaa; + loc[2] = 0xaa; + } + loc += 3; + } + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + if (useMipmaps) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 16, 16, + GL_RGB, GL_UNSIGNED_BYTE, floorTexture); + } else { + if (linearFiltering) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0, + GL_RGB, GL_UNSIGNED_BYTE, floorTexture); + } +} + +enum { + X, Y, Z, W +}; +enum { + A, B, C, D +}; + +/* Create a matrix that will project the desired shadow. */ +void +shadowMatrix(GLfloat shadowMat[4][4], + GLfloat groundplane[4], + GLfloat lightpos[4]) +{ + GLfloat dot; + + /* Find dot product between light position vector and ground plane normal. */ + dot = groundplane[X] * lightpos[X] + + groundplane[Y] * lightpos[Y] + + groundplane[Z] * lightpos[Z] + + groundplane[W] * lightpos[W]; + + shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; + shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; + shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; + shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; + + shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; + shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; + shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; + shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; + + shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; + shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; + shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; + shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; + + shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; + shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; + shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; + shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; + +} + +/* Find the plane equation given 3 points. */ +void +findPlane(GLfloat plane[4], + GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) +{ + GLfloat vec0[3], vec1[3]; + + /* Need 2 vectors to find cross product. */ + vec0[X] = v1[X] - v0[X]; + vec0[Y] = v1[Y] - v0[Y]; + vec0[Z] = v1[Z] - v0[Z]; + + vec1[X] = v2[X] - v0[X]; + vec1[Y] = v2[Y] - v0[Y]; + vec1[Z] = v2[Z] - v0[Z]; + + /* find cross product to get A, B, and C of plane equation */ + plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; + plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); + plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; + + plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); +} + +void +extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, + GLdouble thickness, GLuint side, GLuint edge, GLuint whole) +{ + static GLUtriangulatorObj *tobj = NULL; + GLdouble vertex[3], dx, dy, len; + int i; + int count = dataSize / (2 * sizeof(GLfloat)); + + if (tobj == NULL) { + tobj = gluNewTess(); /* create and initialize a GLU + polygon * * tesselation object */ + gluTessCallback(tobj, (GLenum)GLU_BEGIN, (GLVOIDPTR)glBegin); + gluTessCallback(tobj, (GLenum)GLU_VERTEX, (GLVOIDPTR)glVertex2fv); /* semi-tricky */ + gluTessCallback(tobj, (GLenum)GLU_END, (GLVOIDPTR)glEnd); + } + glNewList(side, GL_COMPILE); + glShadeModel(GL_SMOOTH); /* smooth minimizes seeing + tessellation */ + gluBeginPolygon(tobj); + for (i = 0; i < count; i++) { + vertex[0] = data[i][0]; + vertex[1] = data[i][1]; + vertex[2] = 0; + gluTessVertex(tobj, vertex, data[i]); + } + gluEndPolygon(tobj); + glEndList(); + glNewList(edge, GL_COMPILE); + glShadeModel(GL_FLAT); /* flat shade keeps angular hands + from being "smoothed" */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= count; i++) { + /* mod function handles closing the edge */ + glVertex3f(data[i % count][0], data[i % count][1], 0.0); + glVertex3f(data[i % count][0], data[i % count][1], thickness); + /* Calculate a unit normal by dividing by Euclidean + distance. We * could be lazy and use + glEnable(GL_NORMALIZE) so we could pass in * arbitrary + normals for a very slight performance hit. */ + dx = data[(i + 1) % count][1] - data[i % count][1]; + dy = data[i % count][0] - data[(i + 1) % count][0]; + len = sqrt(dx * dx + dy * dy); + glNormal3f(dx / len, dy / len, 0.0); + } + glEnd(); + glEndList(); + glNewList(whole, GL_COMPILE); + glFrontFace(GL_CW); + glCallList(edge); + glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */ + glCallList(side); + glPushMatrix(); + glTranslatef(0.0, 0.0, thickness); + glFrontFace(GL_CCW); + glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */ + glCallList(side); + glPopMatrix(); + glEndList(); +} + +/* Enumerants for refering to display lists. */ +typedef enum { + RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE, + LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE +} displayLists; + +static void +makeDinosaur(void) +{ + extrudeSolidFromPolygon(body, sizeof(body), bodyWidth, + BODY_SIDE, BODY_EDGE, BODY_WHOLE); + extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4, + ARM_SIDE, ARM_EDGE, ARM_WHOLE); + extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2, + LEG_SIDE, LEG_EDGE, LEG_WHOLE); + extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2, + EYE_SIDE, EYE_EDGE, EYE_WHOLE); +} + +static void +drawDinosaur(void) + +{ + plReal matrix[16]; + + glPushMatrix(); + /* Translate the dinosaur to be at (0,8,0). */ + + plGetOpenGLMatrix(dinoRigidBody,matrix); +// plGetPosition(dinoRigidBody,dinoWorldPos); + // glTranslatef(-8, 0, -bodyWidth / 2); + //glTranslatef(0.0, jump, 0.0); +// glTranslatef(dinoWorldPos[0],dinoWorldPos[1],dinoWorldPos[2]); + +#ifdef BT_USE_DOUBLE_PRECISION + glMultMatrixd(matrix); +#else + glMultMatrixf(matrix); +#endif +// glutSolidCube(15); + glTranslatef(-8.5, -8.5, 0); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); + glCallList(BODY_WHOLE); + glTranslatef(0.0, 0.0, bodyWidth); + glCallList(ARM_WHOLE); + glCallList(LEG_WHOLE); + glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4); + glCallList(ARM_WHOLE); + glTranslatef(0.0, 0.0, -bodyWidth / 4); + glCallList(LEG_WHOLE); + glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1); + glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor); + glCallList(EYE_WHOLE); + + + glPopMatrix(); +} + +static GLfloat floorVertices[4][3] = { + { -20.0, 0.0, 20.0 }, + { 20.0, 0.0, 20.0 }, + { 20.0, 0.0, -20.0 }, + { -20.0, 0.0, -20.0 }, +}; + +/* Draw a floor (possibly textured). */ +static void +drawFloor(void) +{ + glDisable(GL_LIGHTING); + + if (useTexture) { + glEnable(GL_TEXTURE_2D); + } + + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); + glVertex3fv(floorVertices[0]); + glTexCoord2f(0.0, 16.0); + glVertex3fv(floorVertices[1]); + glTexCoord2f(16.0, 16.0); + glVertex3fv(floorVertices[2]); + glTexCoord2f(16.0, 0.0); + glVertex3fv(floorVertices[3]); + glEnd(); + + if (useTexture) { + glDisable(GL_TEXTURE_2D); + } + + glEnable(GL_LIGHTING); +} + +static GLfloat floorPlane[4]; +static GLfloat floorShadow[4][4]; + +static void +redraw(void) +{ + int start = 0, end = 0 ; + + if (reportSpeed) { + start = glutGet(GLUT_ELAPSED_TIME); + } + + /* Clear; default stencil clears to zero. */ + if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow)) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } else { + /* Avoid clearing stencil when not using it. */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + /* Reposition the light source. */ + lightPosition[0] = 12*cos(lightAngle); + lightPosition[1] = lightHeight; + lightPosition[2] = 12*sin(lightAngle); + if (directionalLight) { + lightPosition[3] = 0.0; + } else { + lightPosition[3] = 1.0; + } + + shadowMatrix(floorShadow, floorPlane, lightPosition); + + glPushMatrix(); + /* Perform scene rotations based on user mouse input. */ + glRotatef(angle2, 1.0, 0.0, 0.0); + glRotatef(angle, 0.0, 1.0, 0.0); + + /* Tell GL new light source position. */ + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + + if (renderReflection) { + if (stencilReflection) { + /* We can eliminate the visual "artifact" of seeing the "flipped" + dinosaur underneath the floor by using stencil. The idea is + draw the floor without color or depth update but so that + a stencil value of one is where the floor will be. Later when + rendering the dinosaur reflection, we will only update pixels + with a stencil value of 1 to make sure the reflection only + lives on the floor, not below the floor. */ + + /* Don't update color or depth. */ + glDisable(GL_DEPTH_TEST); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + /* Draw 1 into the stencil buffer. */ + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + glStencilFunc(GL_ALWAYS, 1, 0xffffffff); + + /* Now render floor; floor pixels just get their stencil set to 1. */ + drawFloor(); + + /* Re-enable update of color and depth. */ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glEnable(GL_DEPTH_TEST); + + /* Now, only render where stencil is set to 1. */ + glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */ + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + } + + glPushMatrix(); + + /* The critical reflection step: Reflect dinosaur through the floor + (the Y=0 plane) to make a relection. */ + glScalef(1.0, -1.0, 1.0); + + /* Reflect the light position. */ + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + + /* To avoid our normals getting reversed and hence botched lighting + on the reflection, turn on normalize. */ + glEnable(GL_NORMALIZE); + glCullFace(GL_FRONT); + + /* Draw the reflected dinosaur. */ + drawDinosaur(); + + /* Disable noramlize again and re-enable back face culling. */ + glDisable(GL_NORMALIZE); + glCullFace(GL_BACK); + + glPopMatrix(); + + /* Switch back to the unreflected light position. */ + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + + if (stencilReflection) { + glDisable(GL_STENCIL_TEST); + } + } + + /* Back face culling will get used to only draw either the top or the + bottom floor. This let's us get a floor with two distinct + appearances. The top floor surface is reflective and kind of red. + The bottom floor surface is not reflective and blue. */ + + /* Draw "bottom" of floor in blue. */ + glFrontFace(GL_CW); /* Switch face orientation. */ + glColor4f(0.1, 0.1, 0.7, 1.0); + drawFloor(); + glFrontFace(GL_CCW); + + if (renderShadow) { + if (stencilShadow) { + /* Draw the floor with stencil value 3. This helps us only + draw the shadow once per floor pixel (and only on the + floor pixels). */ + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 3, 0xffffffff); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } + } + + /* Draw "top" of floor. Use blending to blend in reflection. */ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.7, 0.0, 0.0, 0.3); + glColor4f(1.0, 1.0, 1.0, 0.3); + drawFloor(); + glDisable(GL_BLEND); + + if (renderDinosaur) { + /* Draw "actual" dinosaur, not its reflection. */ + drawDinosaur(); + } + + if (renderShadow) { + + /* Render the projected shadow. */ + + if (stencilShadow) { + + /* Now, only render where stencil is set above 2 (ie, 3 where + the top floor is). Update stencil with 2 where the shadow + gets drawn so we don't redraw (and accidently reblend) the + shadow). */ + glStencilFunc(GL_LESS, 2, 0xffffffff); /* draw if ==1 */ + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + } + + /* To eliminate depth buffer artifacts, we use polygon offset + to raise the depth of the projected shadow slightly so + that it does not depth buffer alias with the floor. */ + if (offsetShadow) { + switch (polygonOffsetVersion) { + case EXTENSION: +#ifdef GL_VERSION_1_1 + case ONE_DOT_ONE: + glEnable(GL_POLYGON_OFFSET_FILL); + break; +#endif + case MISSING: + /* Oh well. */ + break; + } + } + + /* Render 50% black shadow color on top of whatever the + floor appareance is. */ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_LIGHTING); /* Force the 50% black. */ + glColor4f(0.0, 0.0, 0.0, 0.5); + + glPushMatrix(); + /* Project the shadow. */ + glMultMatrixf((GLfloat *) floorShadow); + drawDinosaur(); + glPopMatrix(); + + glDisable(GL_BLEND); + glEnable(GL_LIGHTING); + + if (offsetShadow) { + switch (polygonOffsetVersion) { +#ifdef GL_VERSION_1_1 + case ONE_DOT_ONE: + glDisable(GL_POLYGON_OFFSET_FILL); + break; +#endif + case MISSING: + /* Oh well. */ + break; + } + } + if (stencilShadow) { + glDisable(GL_STENCIL_TEST); + } + } + + glPushMatrix(); + glDisable(GL_LIGHTING); + glColor3f(1.0, 1.0, 0.0); + if (directionalLight) { + /* Draw an arrowhead. */ + glDisable(GL_CULL_FACE); + glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); + glRotatef(lightAngle * -180.0 / M_PI, 0, 1, 0); + glRotatef(atan(lightHeight/12) * 180.0 / M_PI, 0, 0, 1); + glBegin(GL_TRIANGLE_FAN); + glVertex3f(0, 0, 0); + glVertex3f(2, 1, 1); + glVertex3f(2, -1, 1); + glVertex3f(2, -1, -1); + glVertex3f(2, 1, -1); + glVertex3f(2, 1, 1); + glEnd(); + /* Draw a white line from light direction. */ + glColor3f(1.0, 1.0, 1.0); + glBegin(GL_LINES); + glVertex3f(0, 0, 0); + glVertex3f(5, 0, 0); + glEnd(); + glEnable(GL_CULL_FACE); + } else { + /* Draw a yellow ball at the light source. */ + glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); + glutSolidSphere(1.0, 5, 5); + } + glEnable(GL_LIGHTING); + glPopMatrix(); + + glPopMatrix(); + + if (reportSpeed) { + glFinish(); + end = glutGet(GLUT_ELAPSED_TIME); + printf("Speed %.3g frames/sec (%d ms)\n", 1000.0/(end-start), end-start); + } + + glutSwapBuffers(); +} + +/* ARGSUSED2 */ +static void +mouse(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON) { + if (state == GLUT_DOWN) { + moving = 1; + startx = x; + starty = y; + } + if (state == GLUT_UP) { + moving = 0; + } + } + if (button == GLUT_MIDDLE_BUTTON) { + if (state == GLUT_DOWN) { + lightMoving = 1; + lightStartX = x; + lightStartY = y; + } + if (state == GLUT_UP) { + lightMoving = 0; + } + } +} + +/* ARGSUSED1 */ +static void +motion(int x, int y) +{ + if (moving) { + angle = angle + (x - startx); + angle2 = angle2 + (y - starty); + startx = x; + starty = y; + glutPostRedisplay(); + } + if (0){//lightMoving) { + lightAngle += (x - lightStartX)/40.0; + lightHeight += (lightStartY - y)/20.0; + lightStartX = x; + lightStartY = y; + glutPostRedisplay(); + } +} + +/* Advance time varying state when idle callback registered. */ +static void +idle(void) +{ + static float time = 0.0; + static float prevtime = 0.0; + float dtime; + prevtime = time; + + time = glutGet(GLUT_ELAPSED_TIME) / 500.0; + dtime = time - prevtime; + + jump = 4.0 * fabs(sin(time)*0.5); + if (!lightMoving) { + lightAngle = time; + } + + if (dynamicsWorld) + plStepSimulation(dynamicsWorld,dtime); + + glutPostRedisplay(); +} + +enum { + M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_DINOSAUR, + M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW, + M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE +}; + +static void +controlLights(int value) +{ + switch (value) { + case M_NONE: + return; + case M_MOTION: + animation = 1 - animation; + if (animation) { + glutIdleFunc(idle); + } else { + glutIdleFunc(NULL); + } + break; + case M_LIGHT: + lightSwitch = !lightSwitch; + if (lightSwitch) { + glEnable(GL_LIGHT0); + } else { + glDisable(GL_LIGHT0); + } + break; + case M_TEXTURE: + useTexture = !useTexture; + break; + case M_SHADOWS: + renderShadow = 1 - renderShadow; + break; + case M_REFLECTION: + renderReflection = 1 - renderReflection; + break; + case M_DINOSAUR: + renderDinosaur = 1 - renderDinosaur; + break; + case M_STENCIL_REFLECTION: + stencilReflection = 1 - stencilReflection; + break; + case M_STENCIL_SHADOW: + stencilShadow = 1 - stencilShadow; + break; + case M_OFFSET_SHADOW: + offsetShadow = 1 - offsetShadow; + break; + case M_POSITIONAL: + directionalLight = 0; + break; + case M_DIRECTIONAL: + directionalLight = 1; + break; + case M_PERFORMANCE: + reportSpeed = 1 - reportSpeed; + break; + } + glutPostRedisplay(); +} + +/* When not visible, stop animating. Restart when visible again. */ +static void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) { + if (animation) + glutIdleFunc(idle); + } else { + if (!animation) + glutIdleFunc(NULL); + } +} + +/* Press any key to redraw; good when motion stopped and + performance reporting on. */ +/* ARGSUSED */ +static void +key(unsigned char c, int x, int y) +{ + if (c == 27) { + exit(0); /* IRIS GLism, Escape quits. */ + } + glutPostRedisplay(); +} + +/* Press any key to redraw; good when motion stopped and + performance reporting on. */ +/* ARGSUSED */ +static void +special(int k, int x, int y) +{ + glutPostRedisplay(); +} + +static int +supportsOneDotOne(void) +{ + const char *version; + int major, minor; + + version = (char *) glGetString(GL_VERSION); + if (sscanf(version, "%d.%d", &major, &minor) == 2) + return ((major > 1) || (major >= 1 && minor >= 1)); + return 0; /* OpenGL version string malformed! */ +} + + +int +main(int argc, char **argv) +{ + int i; + plCollisionShapeHandle floorShape; + plCollisionShapeHandle dinoShape,dinoChildShape; + plVector3 floorPos,childPos; + plVector3 dinoPos; + plQuaternion childOrn,dinoOrient; + + void* user_data=NULL; + + physicsSdk = plNewBulletSdk(); + dynamicsWorld = plCreateDynamicsWorld(physicsSdk); + + //create ground plane + + floorShape = plNewConvexHullShape(); + + for (i=0;i<4;i++) + { +// floorVertices + plAddVertex(floorShape,floorVertices[i][0],floorVertices[i][1],floorVertices[i][2]); + } + + + floorShape = plNewBoxShape(120,0,120); + + floorRigidBody = plCreateRigidBody(user_data,0.f,floorShape); + floorPos[0] = 0; + floorPos[1] = 0; + floorPos[2] = 0; + + plSetPosition(floorRigidBody,floorPos); + plAddRigidBody(dynamicsWorld,floorRigidBody); + + //create dino rigidbody + dinoChildShape = plNewBoxShape(8.5,8.5,8.5); + dinoShape = plNewCompoundShape(); + childPos[0] = 0; + childPos[1] = 0; + childPos[2] = 0; + childOrn[0] = 0; + childOrn[1] = 0; + childOrn[2] = 0; + childOrn[3] = 1; + + plAddChildShape(dinoShape,dinoChildShape,childPos,childOrn); + + dinoPos[0] = -10; dinoPos[1] = 28; dinoPos[2] = 0; + dinoRigidBody = plCreateRigidBody(0,1.0,dinoShape); + plSetPosition(dinoRigidBody,dinoPos); + plSetEuler(0,0,3.15*0.20,dinoOrient); + plSetOrientation(dinoRigidBody,dinoOrient); + + plAddRigidBody(dynamicsWorld,dinoRigidBody); + + printf("BulletDino\n"); + glutInit(&argc, argv); + + for (i=1; i=2 rgb double depth"); +#endif + + glutCreateWindow("Shadowy Leapin' Lizards"); + + if (glutGet(GLUT_WINDOW_STENCIL_SIZE) <= 1) { + printf("dinoshade: Sorry, I need at least 2 bits of stencil.\n"); + exit(1); + } + + /* Register GLUT callbacks. */ + glutDisplayFunc(redraw); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutVisibilityFunc(visible); + glutKeyboardFunc(key); + glutSpecialFunc(special); + + glutCreateMenu(controlLights); + + glutAddMenuEntry("Toggle motion", M_MOTION); + glutAddMenuEntry("-----------------------", M_NONE); + glutAddMenuEntry("Toggle light", M_LIGHT); + glutAddMenuEntry("Toggle texture", M_TEXTURE); + glutAddMenuEntry("Toggle shadows", M_SHADOWS); + glutAddMenuEntry("Toggle reflection", M_REFLECTION); + glutAddMenuEntry("Toggle dinosaur", M_DINOSAUR); + glutAddMenuEntry("-----------------------", M_NONE); + glutAddMenuEntry("Toggle reflection stenciling", M_STENCIL_REFLECTION); + glutAddMenuEntry("Toggle shadow stenciling", M_STENCIL_SHADOW); + glutAddMenuEntry("Toggle shadow offset", M_OFFSET_SHADOW); + glutAddMenuEntry("----------------------", M_NONE); + glutAddMenuEntry("Positional light", M_POSITIONAL); + glutAddMenuEntry("Directional light", M_DIRECTIONAL); + glutAddMenuEntry("-----------------------", M_NONE); + glutAddMenuEntry("Toggle performance", M_PERFORMANCE); + glutAttachMenu(GLUT_RIGHT_BUTTON); + makeDinosaur(); + +#ifdef GL_VERSION_1_1 + if (supportsOneDotOne() && !forceExtension) { + polygonOffsetVersion = ONE_DOT_ONE; + glPolygonOffset(-2.0, -1.0); + } else +#endif + { + { + polygonOffsetVersion = MISSING; + printf("\ndinoshine: Missing polygon offset.\n"); + printf(" Expect shadow depth aliasing artifacts.\n\n"); + } + } + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glLineWidth(3.0); + + glMatrixMode(GL_PROJECTION); + gluPerspective( /* field of view in degree */ 40.0, + /* aspect ratio */ 1.0, + /* Z near */ 20.0, /* Z far */ 100.0); + glMatrixMode(GL_MODELVIEW); + gluLookAt(0.0, 8.0, 60.0, /* eye is at (0,0,30) */ + 0.0, 8.0, 0.0, /* center is at (0,0,0) */ + 0.0, 1.0, 0.); /* up is in postivie Y direction */ + + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + + makeFloorTexture(); + + /* Setup floor plane for projected shadow calculations. */ + findPlane(floorPlane, floorVertices[1], floorVertices[2], floorVertices[3]); + + glutMainLoop(); + + plDeleteDynamicsWorld(dynamicsWorld); + plDeletePhysicsSdk(physicsSdk); + + + return 0; /* ANSI C requires main to return int. */ +} diff --git a/Demos/BulletDinoDemo/CMakeLists.txt b/Demos/BulletDinoDemo/CMakeLists.txt new file mode 100644 index 0000000..04ac642 --- /dev/null +++ b/Demos/BulletDinoDemo/CMakeLists.txt @@ -0,0 +1,61 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + + +# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system +# This should be the case. +INCLUDE (${CMAKE_ROOT}/Modules/FindGLU.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindGLUT.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindOpenGL.cmake) + + +IF (WIN32) + # This is the Windows code for which Opengl, and Glut are not properly installed + # since I can't install them I must cheat and copy libraries around + INCLUDE_DIRECTORIES(${GLUT_ROOT}) + # LINK_DIRECTORIES(${GLUT_ROOT}\\lib) + IF (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") + SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib) + # LINK_LIBRARIES(${GLUT_ROOT}\\lib\\glut32 ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) + # TARGET_LINK_LIBRARIES(table ${GLUT_ROOT}\\lib\\glut32) +# +# ADD_CUSTOM_COMMAND(TARGET table POST_BUILD COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2005\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2003\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs6\\Debug) + ELSE (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# LINK_LIBRARIES(${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY}) + ENDIF(${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# TARGET_LINK_LIBRARIES(table ${OPENGL_gl_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${OPENGL_glu_LIBRARY}) +ELSE (WIN32) + # This is the lines for linux. This should always work if everything is installed and working fine. +# SET(CMAKE_BUILD_TYPE Debug) +# SET(CMAKE_CXX_FLAGS_DEBUG "-g") + INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +ENDIF (WIN32) + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY} +) + +ADD_EXECUTABLE(BulletDino + BulletDino.c +) + diff --git a/Demos/BulletXmlImportDemo/BulletXmlImportDemo.cpp b/Demos/BulletXmlImportDemo/BulletXmlImportDemo.cpp new file mode 100644 index 0000000..2487749 --- /dev/null +++ b/Demos/BulletXmlImportDemo/BulletXmlImportDemo.cpp @@ -0,0 +1,180 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "BulletXmlImportDemo.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btSerializer.h" +#include "btBulletFile.h" +#include "btBulletWorldImporter.h" +#include "btBulletXmlWorldImporter.h" + +#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" +#include //printf debugging + + + +#include "GLDebugDrawer.h" +GLDebugDrawer gDebugDrawer; + + +void BulletXmlImportDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + + + setupEmptyDynamicsWorld(); + + + m_dynamicsWorld->setDebugDrawer(&gDebugDrawer); + + + btBulletXmlWorldImporter* importer = new btBulletXmlWorldImporter(m_dynamicsWorld); + importer->loadFile("bullet_basic.xml"); +// importer->loadFile("bulletser.xml"); +// importer->loadFile("bullet_constraints.xml"); + +} + +void BulletXmlImportDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + + + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + glFlush(); + + swapBuffers(); + +} + + + +void BulletXmlImportDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + + +void BulletXmlImportDemo::setupEmptyDynamicsWorld() +{ + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + btGImpactCollisionAlgorithm::registerAlgorithm(m_dispatcher); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + + //btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher()); + + + +} + + + + +BulletXmlImportDemo::~BulletXmlImportDemo() +{ + m_fileLoader->deleteAllData(); + delete m_fileLoader; + exitPhysics(); +} + +void BulletXmlImportDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} + + +void BulletXmlImportDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + class btBulletWorldImporter* m_fileLoader; + + public: + + BulletXmlImportDemo() + { + //m_idle=true; + setCameraDistance(btScalar(30.)); + } + virtual ~BulletXmlImportDemo(); + + virtual void clientResetScene(); + + void initPhysics(); + + void setupEmptyDynamicsWorld(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + BulletXmlImportDemo* demo = new BulletXmlImportDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //SERIALIZE_DEMO_H + diff --git a/Demos/BulletXmlImportDemo/CMakeLists.txt b/Demos/BulletXmlImportDemo/CMakeLists.txt new file mode 100644 index 0000000..8d8eb41 --- /dev/null +++ b/Demos/BulletXmlImportDemo/CMakeLists.txt @@ -0,0 +1,94 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletXmlWorldImporter +) + +ADD_DEFINITIONS(-DDESERIALIZE_SOFT_BODIES) + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletXmlWorldImporter BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppBulletXmlImportDemo + main.cpp + BulletXmlImportDemo.cpp + BulletXmlImportDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppBulletXmlImportDemo + main.cpp + BulletXmlImportDemo.cpp + BulletXmlImportDemo.h + ) + ENDIF() + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (WIN32) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBulletXmlImportDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppBulletXmlImportDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF(WIN32) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + +ELSE (USE_GLUT) + + LINK_LIBRARIES( + OpenGLSupport BulletXmlWorldImporter BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletFileLoader LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppBulletXmlImportDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32BulletXmlImportDemo.cpp + BulletXmlImportDemo.cpp + BulletXmlImportDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ENDIF (USE_GLUT) + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES AND NOT INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) + ADD_CUSTOM_COMMAND( + TARGET AppBulletXmlImportDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/BulletXmlImportDemo/bullet_basic.xml ${CMAKE_CURRENT_BINARY_DIR}/bullet_basic.xml + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/BulletXmlImportDemo/bullet_basic.xml ${CMAKE_CURRENT_BINARY_DIR}/Debug/bullet_basic.xml + ) +ENDIF () + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppBulletXmlImportDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppBulletXmlImportDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppBulletXmlImportDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + + diff --git a/Demos/BulletXmlImportDemo/Win32BulletXmlImportDemo.cpp b/Demos/BulletXmlImportDemo/Win32BulletXmlImportDemo.cpp new file mode 100644 index 0000000..097bbcb --- /dev/null +++ b/Demos/BulletXmlImportDemo/Win32BulletXmlImportDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletXmlImportDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new BulletXmlImportDemo(); +} + +#endif diff --git a/Demos/BulletXmlImportDemo/bullet_basic.xml b/Demos/BulletXmlImportDemo/bullet_basic.xml new file mode 100644 index 0000000..14ab0fa --- /dev/null +++ b/Demos/BulletXmlImportDemo/bullet_basic.xml @@ -0,0 +1,668 @@ + + + + + 0.600000 + 1.000000 + 0.300000 + 0.016667 + 0.000000 + 20.000000 + 1.000000 + 0.200000 + 0.800000 + 0.000000 + -0.040000 + 0.100000 + 0.000000 + 0.850000 + 100.000000 + 1000000015047466200000000000000.000000 + 10 + 260 + 2 + 128 + 1 + 0 0 0 0 + + + 0.000000 -10.000000 0.000000 0.000000 + + + + + 0 + 3 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + 0.000000 -50.000000 0.000000 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + -431602080.000000 + 0.000000 + 1.000000 + 0.000000 + 0.000000 + 0 + 1 + -1 + -2 + 2 + 2 + 0 + -51 -51 -51 -51 + + + + 0.000000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 5 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 14.166666 -3.000000 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 14.166666 -3.000000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + -431602080.000000 + 0.000000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 4 + -1 + 1 + 2 + 0 + -51 -51 -51 -51 + + + + 1.500000 0.000000 0.000000 0.000000 + 0.000000 1.500000 0.000000 0.000000 + 0.000000 0.000000 1.500000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.500000 1.500000 1.500000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 5 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 16.166668 -3.000000 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 16.166668 -3.000000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + -431602080.000000 + 0.000000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 4 + -1 + 1 + 2 + 0 + -51 -51 -51 -51 + + + + 1.500000 0.000000 0.000000 0.000000 + 0.000000 1.500000 0.000000 0.000000 + 0.000000 0.000000 1.500000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.500000 1.500000 1.500000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 5 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 18.166668 -3.000000 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 18.166668 -3.000000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + -431602080.000000 + 0.000000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 4 + -1 + 1 + 2 + 0 + -51 -51 -51 -51 + + + + 1.500000 0.000000 0.000000 0.000000 + 0.000000 1.500000 0.000000 0.000000 + 0.000000 0.000000 1.500000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.500000 1.500000 1.500000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 5 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 20.166668 -3.000000 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 20.166668 -3.000000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + -431602080.000000 + 0.000000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 4 + -1 + 1 + 2 + 0 + -51 -51 -51 -51 + + + + 1.500000 0.000000 0.000000 0.000000 + 0.000000 1.500000 0.000000 0.000000 + 0.000000 0.000000 1.500000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.500000 1.500000 1.500000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 5 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 22.166668 -3.000000 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -5.000000 22.166668 -3.000000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + -431602080.000000 + 0.000000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 4 + -1 + 1 + 2 + 0 + -51 -51 -51 -51 + + + + 1.500000 0.000000 0.000000 0.000000 + 0.000000 1.500000 0.000000 0.000000 + 0.000000 0.000000 1.500000 0.000000 + + + + 0.000000 -4.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.500000 1.500000 1.500000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 0 + -51 -51 -51 -51 + + + 1.000000 1.000000 1.000000 0.000000 + + + 49.959999 49.959999 49.959999 0.000000 + + 0.040000 + -842150451 + + + + 0 + 0 + -51 -51 -51 -51 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.960000 0.960000 0.960000 0.000000 + + 0.040000 + -842150451 + + diff --git a/Demos/BulletXmlImportDemo/bulletser.xml b/Demos/BulletXmlImportDemo/bulletser.xml new file mode 100644 index 0000000..211d7bf --- /dev/null +++ b/Demos/BulletXmlImportDemo/bulletser.xml @@ -0,0 +1,24344 @@ + + + + + 0 + 2 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + 0.000000 -7.000000 0.000000 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + 0.000000 -7.000000 0.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.000000 + 1.000000 + 0.000000 + 0.000000 + 0 + 1 + -1 + -2 + 2 + 2 + 0 + + + + 0.000000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 4 + 0 + 0 + + + + 0.264808 0.292382 0.918907 0.000000 + 0.957898 0.029880 -0.285551 0.000000 + -0.110947 0.955835 -0.272160 0.000000 + + + + -10.018404 16.045120 -1.137200 0.000000 + + + + + + 0.264808 0.292382 0.918907 0.000000 + 0.957898 0.029880 -0.285551 0.000000 + -0.110947 0.955835 -0.272160 0.000000 + + + + -10.018404 16.045120 -1.137200 0.000000 + + + + 0.000313 -3.168241 0.001859 0.000000 + + + -0.000187 0.000277 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.678407 -0.015449 -0.076281 0.000000 + -0.015449 0.658463 -0.002496 0.000000 + -0.076281 -0.002496 0.450866 0.000000 + + + + 0.000313 -3.168241 0.001859 0.000000 + + + -0.000187 0.000277 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.654481 0.427455 0.705801 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 6 + 0 + 0 + + + + 0.242979 0.250713 0.937072 0.000000 + 0.965499 0.030774 -0.258584 0.000000 + -0.093668 0.967572 -0.234586 0.000000 + + + + -11.238498 15.694831 0.166336 0.000000 + + + + + + 0.242979 0.250713 0.937072 0.000000 + 0.965499 0.030774 -0.258584 0.000000 + -0.093668 0.967572 -0.234586 0.000000 + + + + -11.238498 15.694831 0.166336 0.000000 + + + + 0.000846 -3.168296 0.002338 0.000000 + + + -0.000171 0.000315 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.860338 0.016671 -0.009542 0.000000 + 0.016671 0.925339 -0.007493 0.000000 + -0.009542 -0.007493 0.828272 0.000000 + + + + 0.000846 -3.168296 0.002338 0.000000 + + + -0.000171 0.000315 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.930261 0.825561 0.858127 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 8 + 0 + 0 + + + + 0.275672 0.264634 0.924107 0.000000 + 0.958897 -0.008466 -0.283626 0.000000 + -0.067234 0.964312 -0.256090 0.000000 + + + + -2.524789 11.367409 -1.009499 0.000000 + + + + + + 0.275672 0.264634 0.924107 0.000000 + 0.958897 -0.008466 -0.283626 0.000000 + -0.067234 0.964312 -0.256090 0.000000 + + + + -2.524789 11.367409 -1.009499 0.000000 + + + + 0.001664 -3.165827 0.000217 0.000000 + + + -0.000169 0.000337 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.894856 -0.056095 -0.064263 0.000000 + -0.056095 0.732659 0.016010 0.000000 + -0.064263 0.016010 0.680254 0.000000 + + + + 0.001664 -3.165827 0.000217 0.000000 + + + -0.000169 0.000337 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.715410 0.662478 0.929882 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 10 + 0 + 0 + + + + 0.257979 0.278814 0.925046 0.000000 + 0.962798 0.005503 -0.270166 0.000000 + -0.080417 0.960330 -0.267021 0.000000 + + + + -9.919354 17.980125 -0.555819 0.000000 + + + + + + 0.257979 0.278814 0.925046 0.000000 + 0.962798 0.005503 -0.270166 0.000000 + -0.080417 0.960330 -0.267021 0.000000 + + + + -9.919354 17.980125 -0.555819 0.000000 + + + + -0.000078 -3.168092 0.001480 0.000000 + + + -0.000177 0.000339 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.393794 0.005861 -0.002142 0.000000 + 0.005861 0.414610 -0.001863 0.000000 + -0.002142 -0.001863 0.387164 0.000000 + + + + -0.000078 -3.168092 0.001480 0.000000 + + + -0.000177 0.000339 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.416336 0.386531 0.392701 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 12 + 0 + 0 + + + + 0.248511 0.279020 0.927572 0.000000 + 0.965454 0.006127 -0.260503 0.000000 + -0.078369 0.960266 -0.267858 0.000000 + + + + -8.410973 14.244036 -0.442220 0.000000 + + + + + + 0.248511 0.279020 0.927572 0.000000 + 0.965454 0.006127 -0.260503 0.000000 + -0.078369 0.960266 -0.267858 0.000000 + + + + -8.410973 14.244036 -0.442220 0.000000 + + + + 0.001032 -3.167562 0.001671 0.000000 + + + -0.000182 0.000329 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.589460 0.021100 0.021100 0.000000 + 0.021100 0.658852 -0.006107 0.000000 + 0.021100 -0.006107 0.656448 0.000000 + + + + 0.001032 -3.167562 0.001671 0.000000 + + + -0.000182 0.000329 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.664779 0.662540 0.577441 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 14 + 0 + 0 + + + + 0.247185 0.280090 0.927604 0.000000 + 0.958474 0.069834 -0.276497 0.000000 + -0.142222 0.957430 -0.251197 0.000000 + + + + 1.130368 22.070639 -4.238024 0.000000 + + + + + + 0.247185 0.280090 0.927604 0.000000 + 0.958474 0.069834 -0.276497 0.000000 + -0.142222 0.957430 -0.251197 0.000000 + + + + 1.130368 22.070639 -4.238024 0.000000 + + + + -0.002590 -3.165485 -0.002949 0.000000 + + + -0.000169 0.000332 0.000293 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.466322 0.006449 -0.034802 0.000000 + 0.006449 0.507692 -0.013464 0.000000 + -0.034802 -0.013464 0.360131 0.000000 + + + + -0.002590 -3.165485 -0.002949 0.000000 + + + -0.000169 0.000332 0.000293 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.511353 0.348968 0.473824 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 16 + 0 + 0 + + + + 0.266485 0.246893 0.931681 0.000000 + 0.959592 0.022678 -0.280478 0.000000 + -0.090377 0.968777 -0.230873 0.000000 + + + + -9.872525 21.078518 0.099456 0.000000 + + + + + + 0.266485 0.246893 0.931681 0.000000 + 0.959592 0.022678 -0.280478 0.000000 + -0.090377 0.968777 -0.230873 0.000000 + + + + -9.872525 21.078518 0.099456 0.000000 + + + + -0.000733 -3.168016 0.000908 0.000000 + + + -0.000170 0.000350 0.000271 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.339247 -0.021719 -0.005950 0.000000 + -0.021719 0.269707 0.006570 0.000000 + -0.005950 0.006570 0.315268 0.000000 + + + + -0.000733 -3.168016 0.000908 0.000000 + + + -0.000170 0.000350 0.000271 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.263057 0.313905 0.347260 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 18 + 0 + 0 + + + + 0.276870 0.268336 0.922680 0.000000 + 0.955658 0.023338 -0.293552 0.000000 + -0.100304 0.963043 -0.249976 0.000000 + + + + -4.702626 11.224889 -1.168015 0.000000 + + + + + + 0.276870 0.268336 0.922680 0.000000 + 0.955658 0.023338 -0.293552 0.000000 + -0.100304 0.963043 -0.249976 0.000000 + + + + -4.702626 11.224889 -1.168015 0.000000 + + + + 0.001675 -3.166511 0.000977 0.000000 + + + -0.000171 0.000335 0.000309 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.197971 0.007453 0.003046 0.000000 + 0.007453 0.220187 -0.002334 0.000000 + 0.003046 -0.002334 0.208758 0.000000 + + + + 0.001675 -3.166511 0.000977 0.000000 + + + -0.000171 0.000335 0.000309 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.222592 0.209550 0.194775 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 20 + 0 + 0 + + + + 0.283593 0.280329 0.917055 0.000000 + 0.951274 0.038476 -0.305936 0.000000 + -0.121047 0.959132 -0.255759 0.000000 + + + + -10.550672 14.599033 0.296376 0.000000 + + + + + + 0.283593 0.280329 0.917055 0.000000 + 0.951274 0.038476 -0.305936 0.000000 + -0.121047 0.959132 -0.255759 0.000000 + + + + -10.550672 14.599033 0.296376 0.000000 + + + + 0.001169 -3.168065 0.002311 0.000000 + + + -0.000193 0.000324 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 1.236007 0.043334 -0.045267 0.000000 + 0.043334 1.384638 -0.024602 0.000000 + -0.045267 -0.024602 1.101292 0.000000 + + + + 0.001169 -3.168065 0.002311 0.000000 + + + -0.000193 0.000324 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.400687 1.087075 1.234175 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 22 + 0 + 0 + + + + 0.272907 0.234561 0.933007 0.000000 + 0.959242 0.007573 -0.282485 0.000000 + -0.073325 0.972072 -0.222934 0.000000 + + + + 1.922308 18.900015 -3.260913 0.000000 + + + + + + 0.272907 0.234561 0.933007 0.000000 + 0.959242 0.007573 -0.282485 0.000000 + -0.073325 0.972072 -0.222934 0.000000 + + + + 1.922308 18.900015 -3.260913 0.000000 + + + + -0.001330 -3.165045 -0.002655 0.000000 + + + -0.000171 0.000335 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.325534 -0.006948 0.015560 0.000000 + -0.006948 0.299091 0.002383 0.000000 + 0.015560 0.002383 0.386022 0.000000 + + + + -0.001330 -3.165045 -0.002655 0.000000 + + + -0.000171 0.000335 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.296932 0.389795 0.323920 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 24 + 0 + 0 + + + + 0.274333 0.300222 0.913569 0.000000 + 0.961129 -0.054803 -0.270606 0.000000 + -0.031176 0.952294 -0.303587 0.000000 + + + + 0.144925 11.882150 -3.524450 0.000000 + + + + + + 0.274333 0.300222 0.913569 0.000000 + 0.961129 -0.054803 -0.270606 0.000000 + -0.031176 0.952294 -0.303587 0.000000 + + + + 0.144925 11.882150 -3.524450 0.000000 + + + + 0.000599 -3.165483 -0.000786 0.000000 + + + -0.000173 0.000347 0.000287 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.570005 0.021714 0.010805 0.000000 + 0.021714 0.638505 -0.004648 0.000000 + 0.010805 -0.004648 0.596642 0.000000 + + + + 0.000599 -3.165483 -0.000786 0.000000 + + + -0.000173 0.000347 0.000287 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.644854 0.600315 0.559982 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 26 + 0 + 0 + + + + 0.259535 0.269832 0.927271 0.000000 + 0.960981 0.022978 -0.275656 0.000000 + -0.095688 0.962633 -0.253340 0.000000 + + + + -8.745180 13.411012 0.804027 0.000000 + + + + + + 0.259535 0.269832 0.927271 0.000000 + 0.960981 0.022978 -0.275656 0.000000 + -0.095688 0.962633 -0.253340 0.000000 + + + + -8.745180 13.411012 0.804027 0.000000 + + + + 0.001708 -3.167436 0.001931 0.000000 + + + -0.000179 0.000338 0.000311 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.549220 -0.025285 -0.045189 0.000000 + -0.025285 0.479570 0.004850 0.000000 + -0.045189 0.004850 0.398405 0.000000 + + + + 0.001708 -3.167436 0.001931 0.000000 + + + -0.000179 0.000338 0.000311 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.472259 0.385854 0.569083 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 28 + 0 + 0 + + + + 0.243210 0.295166 0.923973 0.000000 + 0.968147 -0.015434 -0.249907 0.000000 + -0.059503 0.955321 -0.289518 0.000000 + + + + -9.695178 19.994808 0.607097 0.000000 + + + + + + 0.243210 0.295166 0.923973 0.000000 + 0.968147 -0.015434 -0.249907 0.000000 + -0.059503 0.955321 -0.289518 0.000000 + + + + -9.695178 19.994808 0.607097 0.000000 + + + + -0.000250 -3.167815 0.001025 0.000000 + + + -0.000188 0.000356 0.000290 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.418109 -0.011465 0.005721 0.000000 + -0.011465 0.374105 0.002523 0.000000 + 0.005721 0.002523 0.435498 0.000000 + + + + -0.000250 -3.167815 0.001025 0.000000 + + + -0.000188 0.000356 0.000290 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.371069 0.437225 0.419418 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 30 + 0 + 0 + + + + 0.266779 0.290382 0.918971 0.000000 + 0.959454 0.009993 -0.281689 0.000000 + -0.090980 0.956859 -0.275942 0.000000 + + + + -9.310074 14.486863 -0.889529 0.000000 + + + + + + 0.266779 0.290382 0.918971 0.000000 + 0.959454 0.009993 -0.281689 0.000000 + -0.090980 0.956859 -0.275942 0.000000 + + + + -9.310074 14.486863 -0.889529 0.000000 + + + + 0.000829 -3.167903 0.001926 0.000000 + + + -0.000175 0.000334 0.000298 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.601416 0.069075 0.034001 0.000000 + 0.069075 0.816951 -0.022019 0.000000 + 0.034001 -0.022019 0.705745 0.000000 + + + + 0.000829 -3.167903 0.001926 0.000000 + + + -0.000175 0.000334 0.000298 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.838246 0.715833 0.570033 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 32 + 0 + 0 + + + + 0.275035 0.243113 0.930189 0.000000 + 0.958017 0.012202 -0.286452 0.000000 + -0.080990 0.969921 -0.229551 0.000000 + + + + -1.096564 13.172791 -2.039617 0.000000 + + + + + + 0.275035 0.243113 0.930189 0.000000 + 0.958017 0.012202 -0.286452 0.000000 + -0.080990 0.969921 -0.229551 0.000000 + + + + -1.096564 13.172791 -2.039617 0.000000 + + + + 0.000771 -3.165606 -0.000599 0.000000 + + + -0.000181 0.000348 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.534793 0.008557 -0.019153 0.000000 + 0.008557 0.567485 -0.003512 0.000000 + -0.019153 -0.003512 0.463653 0.000000 + + + + 0.000771 -3.165606 -0.000599 0.000000 + + + -0.000181 0.000348 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.570238 0.458809 0.536884 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 34 + 0 + 0 + + + + 0.272922 0.269009 0.923660 0.000000 + 0.958389 0.007495 -0.285367 0.000000 + -0.083689 0.963108 -0.255770 0.000000 + + + + -5.976898 12.528832 -0.221821 0.000000 + + + + + + 0.272922 0.269009 0.923660 0.000000 + 0.958389 0.007495 -0.285367 0.000000 + -0.083689 0.963108 -0.255770 0.000000 + + + + -5.976898 12.528832 -0.221821 0.000000 + + + + 0.001635 -3.166748 0.001185 0.000000 + + + -0.000178 0.000312 0.000312 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.316995 0.001262 -0.016360 0.000000 + 0.001262 0.326006 -0.000878 0.000000 + -0.016360 -0.000878 0.263034 0.000000 + + + + 0.001635 -3.166748 0.001185 0.000000 + + + -0.000178 0.000312 0.000312 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.326442 0.258458 0.321136 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 36 + 0 + 0 + + + + 0.263349 0.270617 0.925967 0.000000 + 0.961822 0.000445 -0.273677 0.000000 + -0.074474 0.962687 -0.260168 0.000000 + + + + -10.960040 18.021080 0.939480 0.000000 + + + + + + 0.263349 0.270617 0.925967 0.000000 + 0.961822 0.000445 -0.273677 0.000000 + -0.074474 0.962687 -0.260168 0.000000 + + + + -10.960040 18.021080 0.939480 0.000000 + + + + 0.000421 -3.168117 0.001832 0.000000 + + + -0.000176 0.000334 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.486755 -0.008641 -0.007840 0.000000 + -0.008640 0.459969 0.002428 0.000000 + -0.007840 0.002428 0.461054 0.000000 + + + + 0.000421 -3.168117 0.001832 0.000000 + + + -0.000176 0.000334 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.457415 0.458851 0.491512 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 38 + 0 + 0 + + + + 0.266744 0.253792 0.929751 0.000000 + 0.960598 0.008160 -0.277821 0.000000 + -0.078096 0.967224 -0.241616 0.000000 + + + + -11.098556 16.231737 0.987424 0.000000 + + + + + + 0.266744 0.253792 0.929751 0.000000 + 0.960598 0.008160 -0.277821 0.000000 + -0.078096 0.967224 -0.241616 0.000000 + + + + -11.098556 16.231737 0.987424 0.000000 + + + + 0.000970 -3.168130 0.002216 0.000000 + + + -0.000185 0.000342 0.000276 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.585797 -0.030939 0.003375 0.000000 + -0.030939 0.482723 0.009088 0.000000 + 0.003375 0.009088 0.596704 0.000000 + + + + 0.000970 -3.168130 0.002216 0.000000 + + + -0.000185 0.000342 0.000276 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.473392 0.597666 0.594164 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 40 + 0 + 0 + + + + 0.269143 0.210785 0.939751 0.000000 + 0.962592 -0.027180 -0.269588 0.000000 + -0.031283 0.977154 -0.210215 0.000000 + + + + 0.026031 13.865726 -2.003178 0.000000 + + + + + + 0.269143 0.210785 0.939751 0.000000 + 0.962592 -0.027180 -0.269588 0.000000 + -0.031283 0.977154 -0.210215 0.000000 + + + + 0.026031 13.865726 -2.003178 0.000000 + + + + 0.000572 -3.165297 -0.001108 0.000000 + + + -0.000180 0.000344 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.603775 -0.031062 -0.006832 0.000000 + -0.031062 0.502313 0.004648 0.000000 + -0.006832 0.004648 0.577712 0.000000 + + + + 0.000572 -3.165297 -0.001108 0.000000 + + + -0.000180 0.000344 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.493477 0.576109 0.614214 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 42 + 0 + 0 + + + + 0.283737 0.215623 0.934345 0.000000 + 0.956772 0.001251 -0.290836 0.000000 + -0.063879 0.976476 -0.205947 0.000000 + + + + 0.178605 13.075008 -1.375758 0.000000 + + + + + + 0.283737 0.215623 0.934345 0.000000 + 0.956772 0.001251 -0.290836 0.000000 + -0.063879 0.976476 -0.205947 0.000000 + + + + 0.178605 13.075008 -1.375758 0.000000 + + + + 0.001017 -3.165117 -0.001027 0.000000 + + + -0.000176 0.000351 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 2.338381 -0.177631 -0.146997 0.000000 + -0.177631 1.827779 0.039024 0.000000 + -0.146997 0.039024 1.704065 0.000000 + + + + 0.001017 -3.165117 -0.001027 0.000000 + + + -0.000176 0.000351 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.772496 1.671656 2.426074 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 44 + 0 + 0 + + + + 0.259117 0.262494 0.929492 0.000000 + 0.959188 0.042868 -0.279501 0.000000 + -0.113213 0.963981 -0.240673 0.000000 + + + + 0.062176 11.969648 -1.848458 0.000000 + + + + + + 0.259117 0.262494 0.929492 0.000000 + 0.959188 0.042868 -0.279501 0.000000 + -0.113213 0.963981 -0.240673 0.000000 + + + + 0.062176 11.969648 -1.848458 0.000000 + + + + 0.001145 -3.165230 -0.000781 0.000000 + + + -0.000170 0.000345 0.000284 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.684872 -0.006403 -0.006127 0.000000 + -0.006403 0.665760 0.001546 0.000000 + -0.006127 0.001546 0.662925 0.000000 + + + + 0.001145 -3.165230 -0.000781 0.000000 + + + -0.000170 0.000345 0.000284 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.663848 0.661325 0.688384 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 46 + 0 + 0 + + + + 0.250381 0.269174 0.929976 0.000000 + 0.966033 -0.006013 -0.258349 0.000000 + -0.063949 0.963073 -0.261536 0.000000 + + + + -1.106317 12.913932 -1.058279 0.000000 + + + + + + 0.250381 0.269174 0.929976 0.000000 + 0.966033 -0.006013 -0.258349 0.000000 + -0.063949 0.963073 -0.261536 0.000000 + + + + -1.106317 12.913932 -1.058279 0.000000 + + + + 0.001200 -3.165425 -0.000550 0.000000 + + + -0.000177 0.000359 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 1.543157 0.090421 -0.089587 0.000000 + 0.090421 1.890073 -0.021093 0.000000 + -0.089587 -0.021093 1.245511 0.000000 + + + + 0.001200 -3.165425 -0.000550 0.000000 + + + -0.000177 0.000359 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.914905 1.220603 1.543232 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 48 + 0 + 0 + + + + 0.267856 0.275219 0.923313 0.000000 + 0.959776 0.007491 -0.280667 0.000000 + -0.084162 0.961352 -0.262142 0.000000 + + + + -1.124454 23.155754 -1.647149 0.000000 + + + + + + 0.267856 0.275219 0.923313 0.000000 + 0.959776 0.007491 -0.280667 0.000000 + -0.084162 0.961352 -0.262142 0.000000 + + + + -1.124454 23.155754 -1.647149 0.000000 + + + + -0.002031 -3.165764 -0.002409 0.000000 + + + -0.000171 0.000322 0.000302 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.357407 0.019838 -0.019681 0.000000 + 0.019838 0.428544 -0.006765 0.000000 + -0.019681 -0.006765 0.294889 0.000000 + + + + -0.002031 -3.165764 -0.002409 0.000000 + + + -0.000171 0.000322 0.000302 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.434674 0.289202 0.356964 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 50 + 0 + 0 + + + + 0.304517 0.278124 0.910998 0.000000 + 0.952197 -0.064487 -0.298601 0.000000 + -0.024301 0.958378 -0.284466 0.000000 + + + + -7.906496 15.780626 -1.263670 0.000000 + + + + + + 0.304517 0.278124 0.910998 0.000000 + 0.952197 -0.064487 -0.298601 0.000000 + -0.024301 0.958378 -0.284466 0.000000 + + + + -7.906496 15.780626 -1.263670 0.000000 + + + + 0.000297 -3.167574 0.001238 0.000000 + + + -0.000196 0.000328 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.649328 0.001596 0.025461 0.000000 + 0.001596 0.651618 -0.006188 0.000000 + 0.025461 -0.006188 0.728887 0.000000 + + + + 0.000297 -3.167574 0.001238 0.000000 + + + -0.000196 0.000328 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.652287 0.736692 0.640855 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 52 + 0 + 0 + + + + 0.263972 0.247827 0.932148 0.000000 + 0.960098 0.025030 -0.278542 0.000000 + -0.092362 0.968481 -0.231331 0.000000 + + + + -8.914278 23.222511 -0.677441 0.000000 + + + + + + 0.263972 0.247827 0.932148 0.000000 + 0.960098 0.025030 -0.278542 0.000000 + -0.092362 0.968481 -0.231331 0.000000 + + + + -8.914278 23.222511 -0.677441 0.000000 + + + + -0.001617 -3.167928 0.000177 0.000000 + + + -0.000181 0.000355 0.000284 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.177730 -0.004872 0.000719 0.000000 + -0.004872 0.161264 0.001732 0.000000 + 0.000719 0.001732 0.179820 0.000000 + + + + -0.001617 -3.167928 0.000177 0.000000 + + + -0.000181 0.000355 0.000284 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.159758 0.180048 0.179007 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 54 + 0 + 0 + + + + 0.260971 0.245743 0.933544 0.000000 + 0.963806 -0.011706 -0.266349 0.000000 + -0.054526 0.969264 -0.239903 0.000000 + + + + -9.322986 15.480569 1.086315 0.000000 + + + + + + 0.260971 0.245743 0.933544 0.000000 + 0.963806 -0.011706 -0.266349 0.000000 + -0.054526 0.969264 -0.239903 0.000000 + + + + -9.322986 15.480569 1.086315 0.000000 + + + + 0.001184 -3.167588 0.001755 0.000000 + + + -0.000179 0.000337 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.858383 0.031085 -0.077081 0.000000 + 0.031085 0.980720 -0.002714 0.000000 + -0.077081 -0.002714 0.572388 0.000000 + + + + 0.001184 -3.167588 0.001755 0.000000 + + + -0.000179 0.000337 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.989290 0.552878 0.869323 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 56 + 0 + 0 + + + + 0.230733 0.267495 0.935526 0.000000 + 0.970522 0.005541 -0.240949 0.000000 + -0.069637 0.963543 -0.258332 0.000000 + + + + -9.812456 19.797951 -1.139824 0.000000 + + + + + + 0.230733 0.267495 0.935526 0.000000 + 0.970522 0.005541 -0.240949 0.000000 + -0.069637 0.963543 -0.258332 0.000000 + + + + -9.812456 19.797951 -1.139824 0.000000 + + + + -0.000819 -3.168171 0.001123 0.000000 + + + -0.000177 0.000343 0.000289 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.424625 0.016657 -0.019142 0.000000 + 0.016657 0.496117 -0.005430 0.000000 + -0.019142 -0.005430 0.361365 0.000000 + + + + -0.000819 -3.168171 0.001123 0.000000 + + + -0.000177 0.000343 0.000289 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.500467 0.356020 0.425621 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 58 + 0 + 0 + + + + 0.265756 0.244547 0.932508 0.000000 + 0.962682 -0.015986 -0.270163 0.000000 + -0.051161 0.969505 -0.239670 0.000000 + + + + -2.932368 10.656281 -1.757161 0.000000 + + + + + + 0.265756 0.244547 0.932508 0.000000 + 0.962682 -0.015986 -0.270163 0.000000 + -0.051161 0.969505 -0.239670 0.000000 + + + + -2.932368 10.656281 -1.757161 0.000000 + + + + 0.001641 -3.166028 0.000483 0.000000 + + + -0.000164 0.000315 0.000319 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.591222 0.006645 -0.014575 0.000000 + 0.006645 0.616250 -0.000304 0.000000 + -0.014575 -0.000304 0.536678 0.000000 + + + + 0.001641 -3.166028 0.000483 0.000000 + + + -0.000164 0.000315 0.000319 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.618101 0.533007 0.593043 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 60 + 0 + 0 + + + + 0.271211 0.256094 0.927826 0.000000 + 0.959765 0.000928 -0.280803 0.000000 + -0.072773 0.966651 -0.245538 0.000000 + + + + -3.117821 13.220895 -2.660358 0.000000 + + + + + + 0.271211 0.256094 0.927826 0.000000 + 0.959765 0.000928 -0.280803 0.000000 + -0.072773 0.966651 -0.245538 0.000000 + + + + -3.117821 13.220895 -2.660358 0.000000 + + + + 0.000551 -3.166315 0.000111 0.000000 + + + -0.000163 0.000370 0.000299 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.570054 -0.007811 -0.024397 0.000000 + -0.007811 0.551317 0.001999 0.000000 + -0.024397 0.001999 0.484399 0.000000 + + + + 0.000551 -3.166315 0.000111 0.000000 + + + -0.000163 0.000370 0.000299 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.548958 0.477938 0.578874 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 62 + 0 + 0 + + + + 0.281732 0.243452 0.928094 0.000000 + 0.952933 0.041925 -0.300270 0.000000 + -0.112011 0.969006 -0.220182 0.000000 + + + + 0.631069 12.861382 -2.330191 0.000000 + + + + + + 0.281732 0.243452 0.928094 0.000000 + 0.952933 0.041925 -0.300270 0.000000 + -0.112011 0.969006 -0.220182 0.000000 + + + + 0.631069 12.861382 -2.330191 0.000000 + + + + 0.000720 -3.165162 -0.001135 0.000000 + + + -0.000171 0.000345 0.000287 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.741244 -0.047747 -0.045102 0.000000 + -0.047747 0.612900 0.009426 0.000000 + -0.045102 0.009426 0.564426 0.000000 + + + + 0.000720 -3.165162 -0.001135 0.000000 + + + -0.000171 0.000345 0.000287 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.597675 0.553502 0.767391 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 64 + 0 + 0 + + + + 0.267312 0.248245 0.931085 0.000000 + 0.959302 0.022712 -0.281468 0.000000 + -0.091020 0.968431 -0.232071 0.000000 + + + + 0.543064 13.186378 -3.114460 0.000000 + + + + + + 0.267312 0.248245 0.931085 0.000000 + 0.959302 0.022712 -0.281468 0.000000 + -0.091020 0.968431 -0.232071 0.000000 + + + + 0.543064 13.186378 -3.114460 0.000000 + + + + 0.000359 -3.165322 -0.001161 0.000000 + + + -0.000175 0.000346 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.954923 -0.055351 -0.110718 0.000000 + -0.055351 0.810104 0.007337 0.000000 + -0.110718 0.007337 0.546145 0.000000 + + + + 0.000359 -3.165322 -0.001161 0.000000 + + + -0.000175 0.000346 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.793984 0.517936 0.999252 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 66 + 0 + 0 + + + + 0.271468 0.255952 0.927790 0.000000 + 0.958176 0.018848 -0.285559 0.000000 + -0.090577 0.966506 -0.240130 0.000000 + + + + -0.965391 13.097441 -3.100339 0.000000 + + + + + + 0.271468 0.255952 0.927790 0.000000 + 0.958176 0.018848 -0.285559 0.000000 + -0.090577 0.966506 -0.240130 0.000000 + + + + -0.965391 13.097441 -3.100339 0.000000 + + + + 0.000405 -3.165745 -0.000620 0.000000 + + + -0.000176 0.000338 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.391987 0.029349 -0.014953 0.000000 + 0.029349 0.491234 -0.010767 0.000000 + -0.014953 -0.010767 0.341856 0.000000 + + + + 0.000405 -3.165745 -0.000620 0.000000 + + + -0.000176 0.000338 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.500567 0.337686 0.386824 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 68 + 0 + 0 + + + + 0.251400 0.233070 0.939402 0.000000 + 0.963943 0.027199 -0.264716 0.000000 + -0.087248 0.972079 -0.217829 0.000000 + + + + -9.529333 19.458237 0.711732 0.000000 + + + + + + 0.251400 0.233070 0.939402 0.000000 + 0.963943 0.027199 -0.264716 0.000000 + -0.087248 0.972079 -0.217829 0.000000 + + + + -9.529333 19.458237 0.711732 0.000000 + + + + -0.000064 -3.167744 0.001072 0.000000 + + + -0.000185 0.000349 0.000292 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.477585 -0.007613 -0.008849 0.000000 + -0.007613 0.453581 0.001439 0.000000 + -0.008849 0.001439 0.441871 0.000000 + + + + -0.000064 -3.167744 0.001072 0.000000 + + + -0.000185 0.000349 0.000292 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.451465 0.439789 0.481782 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 70 + 0 + 0 + + + + 0.280082 0.276048 0.919430 0.000000 + 0.954961 0.017658 -0.296207 0.000000 + -0.098002 0.960982 -0.258669 0.000000 + + + + -6.334208 11.489948 -1.055669 0.000000 + + + + + + 0.280082 0.276048 0.919430 0.000000 + 0.954961 0.017658 -0.296207 0.000000 + -0.098002 0.960982 -0.258669 0.000000 + + + + -6.334208 11.489948 -1.055669 0.000000 + + + + 0.001657 -3.166995 0.001468 0.000000 + + + -0.000181 0.000326 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.318873 0.005114 0.009139 0.000000 + 0.005114 0.331497 -0.001110 0.000000 + 0.009139 -0.001110 0.348409 0.000000 + + + + 0.001657 -3.166995 0.001468 0.000000 + + + -0.000181 0.000326 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.333111 0.351013 0.314654 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 72 + 0 + 0 + + + + 0.266364 0.282788 0.921456 0.000000 + 0.960521 0.001775 -0.278201 0.000000 + -0.080307 0.959181 -0.271151 0.000000 + + + + -6.095496 12.996134 -1.462297 0.000000 + + + + + + 0.266364 0.282788 0.921456 0.000000 + 0.960521 0.001775 -0.278201 0.000000 + -0.080307 0.959181 -0.271151 0.000000 + + + + -6.095496 12.996134 -1.462297 0.000000 + + + + 0.001075 -3.167000 0.001139 0.000000 + + + -0.000152 0.000297 0.000313 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.555805 -0.039464 -0.001863 0.000000 + -0.039464 0.425993 0.011863 0.000000 + -0.001863 0.011863 0.549767 0.000000 + + + + 0.001075 -3.167000 0.001139 0.000000 + + + -0.000152 0.000297 0.000313 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.414057 0.549239 0.568268 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 74 + 0 + 0 + + + + 0.263759 0.273029 0.925141 0.000000 + 0.960030 0.018832 -0.279263 0.000000 + -0.093669 0.961822 -0.257149 0.000000 + + + + 0.555015 22.981026 -2.500042 0.000000 + + + + + + 0.263759 0.273029 0.925141 0.000000 + 0.960030 0.018832 -0.279263 0.000000 + -0.093669 0.961822 -0.257149 0.000000 + + + + 0.555015 22.981026 -2.500042 0.000000 + + + + -0.002286 -3.165403 -0.002924 0.000000 + + + -0.000175 0.000328 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.367031 -0.000089 -0.019040 0.000000 + -0.000089 0.373354 -0.001412 0.000000 + -0.019040 -0.001412 0.305384 0.000000 + + + + -0.002286 -3.165403 -0.002924 0.000000 + + + -0.000175 0.000328 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.373467 0.299951 0.372350 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 76 + 0 + 0 + + + + 0.266485 0.263046 0.927250 0.000000 + 0.960338 0.009457 -0.278677 0.000000 + -0.082074 0.964737 -0.250093 0.000000 + + + + 2.009061 15.789817 -3.737069 0.000000 + + + + + + 0.266485 0.263046 0.927250 0.000000 + 0.960338 0.009457 -0.278677 0.000000 + -0.082074 0.964737 -0.250093 0.000000 + + + + 2.009061 15.789817 -3.737069 0.000000 + + + + -0.000597 -3.165054 -0.002139 0.000000 + + + -0.000180 0.000334 0.000282 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.230768 0.000958 0.005683 0.000000 + 0.000958 0.232198 -0.000071 0.000000 + 0.005683 -0.000071 0.250097 0.000000 + + + + -0.000597 -3.165054 -0.002139 0.000000 + + + -0.000180 0.000334 0.000282 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.232470 0.251646 0.228947 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 78 + 0 + 0 + + + + 0.278133 0.300327 0.912385 0.000000 + 0.953948 0.024746 -0.298949 0.000000 + -0.112360 0.953515 -0.279614 0.000000 + + + + -1.537477 11.377494 -2.709434 0.000000 + + + + + + 0.278133 0.300327 0.912385 0.000000 + 0.953948 0.024746 -0.298949 0.000000 + -0.112360 0.953515 -0.279614 0.000000 + + + + -1.537477 11.377494 -2.709434 0.000000 + + + + 0.001066 -3.165801 -0.000131 0.000000 + + + -0.000177 0.000406 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.587764 -0.026011 -0.019809 0.000000 + -0.026011 0.515125 0.008390 0.000000 + -0.019809 0.008390 0.528749 0.000000 + + + + 0.001066 -3.165801 -0.000131 0.000000 + + + -0.000177 0.000406 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.506553 0.522728 0.602357 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 80 + 0 + 0 + + + + 0.288211 0.211865 0.933835 0.000000 + 0.955584 -0.000916 -0.294716 0.000000 + -0.061585 0.977298 -0.202719 0.000000 + + + + -11.153685 15.238323 -0.176678 0.000000 + + + + + + 0.288211 0.211865 0.933835 0.000000 + 0.955584 -0.000916 -0.294716 0.000000 + -0.061585 0.977298 -0.202719 0.000000 + + + + -11.153685 15.238323 -0.176678 0.000000 + + + + 0.000851 -3.168326 0.002377 0.000000 + + + -0.000190 0.000330 0.000314 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.718333 0.064361 0.033177 0.000000 + 0.064361 0.904328 -0.013921 0.000000 + 0.033177 -0.013921 0.863890 0.000000 + + + + 0.000851 -3.168326 0.002377 0.000000 + + + -0.000190 0.000330 0.000314 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.924637 0.871096 0.690819 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 82 + 0 + 0 + + + + 0.255828 0.249914 0.933860 0.000000 + 0.962706 0.022106 -0.269646 0.000000 + -0.088033 0.968016 -0.234938 0.000000 + + + + 2.395922 17.278748 -2.422043 0.000000 + + + + + + 0.255828 0.249914 0.933860 0.000000 + 0.962706 0.022106 -0.269646 0.000000 + -0.088033 0.968016 -0.234938 0.000000 + + + + 2.395922 17.278748 -2.422043 0.000000 + + + + -0.000575 -3.164746 -0.002537 0.000000 + + + -0.000173 0.000338 0.000284 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.401404 -0.006928 -0.030805 0.000000 + -0.006928 0.387717 -0.000638 0.000000 + -0.030805 -0.000638 0.289440 0.000000 + + + + -0.000575 -3.164746 -0.002537 0.000000 + + + -0.000173 0.000338 0.000284 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.385935 0.281473 0.411154 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 84 + 0 + 0 + + + + 0.286062 0.271376 0.918980 0.000000 + 0.954436 0.004349 -0.298383 0.000000 + -0.084971 0.962464 -0.257767 0.000000 + + + + -8.576577 15.730978 0.142786 0.000000 + + + + + + 0.286062 0.271376 0.918980 0.000000 + 0.954436 0.004349 -0.298383 0.000000 + -0.084971 0.962464 -0.257767 0.000000 + + + + -8.576577 15.730978 0.142786 0.000000 + + + + 0.000782 -3.167524 0.001452 0.000000 + + + -0.000186 0.000328 0.000303 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.918569 0.013301 -0.029362 0.000000 + 0.013301 0.967286 -0.004440 0.000000 + -0.029362 -0.004440 0.822946 0.000000 + + + + 0.000782 -3.167524 0.001452 0.000000 + + + -0.000186 0.000328 0.000303 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.971668 0.814647 0.922486 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 86 + 0 + 0 + + + + 0.293470 0.270392 0.916932 0.000000 + 0.953699 -0.016758 -0.300296 0.000000 + -0.065832 0.962605 -0.262790 0.000000 + + + + -3.529477 12.837772 -1.574597 0.000000 + + + + + + 0.293470 0.270392 0.916932 0.000000 + 0.953699 -0.016758 -0.300296 0.000000 + -0.065832 0.962605 -0.262790 0.000000 + + + + -3.529477 12.837772 -1.574597 0.000000 + + + + 0.001049 -3.166231 0.000334 0.000000 + + + -0.000192 0.000335 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.633052 -0.034856 0.018469 0.000000 + -0.034856 0.526830 0.006759 0.000000 + 0.018469 0.006759 0.695892 0.000000 + + + + 0.001049 -3.166231 0.000334 0.000000 + + + -0.000192 0.000335 0.000291 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.515637 0.700962 0.639175 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 88 + 0 + 0 + + + + 0.279608 0.266419 0.922410 0.000000 + 0.948137 0.074659 -0.308970 0.000000 + -0.151182 0.960962 -0.231726 0.000000 + + + + -0.734770 11.378308 -1.685973 0.000000 + + + + + + 0.279608 0.266419 0.922410 0.000000 + 0.948137 0.074659 -0.308970 0.000000 + -0.151182 0.960962 -0.231726 0.000000 + + + + -0.734770 11.378308 -1.685973 0.000000 + + + + 0.001410 -3.165412 -0.000409 0.000000 + + + -0.000168 0.000348 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.908387 -0.055531 -0.027766 0.000000 + -0.055531 0.754402 0.018369 0.000000 + -0.027766 0.018369 0.798944 0.000000 + + + + 0.001410 -3.165412 -0.000409 0.000000 + + + -0.000168 0.000348 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.735096 0.792673 0.933963 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 90 + 0 + 0 + + + + 0.273991 0.286075 0.918199 0.000000 + 0.956963 0.013872 -0.289880 0.000000 + -0.095665 0.958107 -0.269962 0.000000 + + + + -10.326201 16.496368 -0.103978 0.000000 + + + + + + 0.273991 0.286075 0.918199 0.000000 + 0.956963 0.013872 -0.289880 0.000000 + -0.095665 0.958107 -0.269962 0.000000 + + + + -10.326201 16.496368 -0.103978 0.000000 + + + + 0.000523 -3.168090 0.001913 0.000000 + + + -0.000193 0.000329 0.000292 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.681288 -0.003437 0.017528 0.000000 + -0.003437 0.664360 0.002119 0.000000 + 0.017528 0.002119 0.734561 0.000000 + + + + 0.000523 -3.168090 0.001913 0.000000 + + + -0.000193 0.000329 0.000292 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.663164 0.739825 0.677219 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 92 + 0 + 0 + + + + 0.253137 0.305463 0.917940 0.000000 + 0.956732 0.061679 -0.284359 0.000000 + -0.143479 0.950204 -0.276633 0.000000 + + + + -8.583277 13.501283 -1.313118 0.000000 + + + + + + 0.253137 0.305463 0.917940 0.000000 + 0.956732 0.061679 -0.284359 0.000000 + -0.143479 0.950204 -0.276633 0.000000 + + + + -8.583277 13.501283 -1.313118 0.000000 + + + + 0.000982 -3.167748 0.001865 0.000000 + + + -0.000172 0.000330 0.000312 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.594244 0.000140 -0.046838 0.000000 + 0.000140 0.619611 -0.011147 0.000000 + -0.046838 -0.011147 0.464354 0.000000 + + + + 0.000982 -3.167748 0.001865 0.000000 + + + -0.000172 0.000330 0.000312 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.621320 0.448574 0.608316 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 94 + 0 + 0 + + + + 0.261394 0.195782 0.945168 0.000000 + 0.963575 0.004427 -0.267401 0.000000 + -0.056536 0.980637 -0.187493 0.000000 + + + + -10.865542 14.610499 -0.832829 0.000000 + + + + + + 0.261394 0.195782 0.945168 0.000000 + 0.963575 0.004427 -0.267401 0.000000 + -0.056536 0.980637 -0.187493 0.000000 + + + + -10.865542 14.610499 -0.832829 0.000000 + + + + 0.000814 -3.168353 0.002402 0.000000 + + + -0.000190 0.000321 0.000281 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.537418 0.001708 -0.028606 0.000000 + 0.001708 0.549376 -0.001042 0.000000 + -0.028606 -0.001042 0.399892 0.000000 + + + + 0.000814 -3.168353 0.002402 0.000000 + + + -0.000190 0.000321 0.000281 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.549900 0.394176 0.542610 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 96 + 0 + 0 + + + + 0.262078 0.251424 0.931720 0.000000 + 0.961679 0.012545 -0.273890 0.000000 + -0.080551 0.967796 -0.238501 0.000000 + + + + -5.880309 22.535719 -1.172234 0.000000 + + + + + + 0.262078 0.251424 0.931720 0.000000 + 0.961679 0.012545 -0.273890 0.000000 + -0.080551 0.967796 -0.238501 0.000000 + + + + -5.880309 22.535719 -1.172234 0.000000 + + + + -0.001632 -3.167109 -0.000744 0.000000 + + + -0.000175 0.000332 0.000290 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.539629 -0.010172 -0.007735 0.000000 + -0.010172 0.507677 0.002664 0.000000 + -0.007735 0.002664 0.511324 0.000000 + + + + -0.001632 -3.167109 -0.000744 0.000000 + + + -0.000175 0.000332 0.000290 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.504682 0.509349 0.544599 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 98 + 0 + 0 + + + + 0.253657 0.276427 0.926955 0.000000 + 0.962288 0.025257 -0.270857 0.000000 + -0.098284 0.960703 -0.259596 0.000000 + + + + -0.765661 23.249353 -3.015953 0.000000 + + + + + + 0.253657 0.276427 0.926955 0.000000 + 0.962288 0.025257 -0.270857 0.000000 + -0.098284 0.960703 -0.259596 0.000000 + + + + -0.765661 23.249353 -3.015953 0.000000 + + + + -0.002528 -3.165864 -0.002533 0.000000 + + + -0.000165 0.000329 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.317900 0.025521 0.017053 0.000000 + 0.025521 0.400578 -0.007897 0.000000 + 0.017053 -0.007897 0.374801 0.000000 + + + + -0.002528 -3.165864 -0.002533 0.000000 + + + -0.000165 0.000329 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.408112 0.379500 0.305667 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 100 + 0 + 0 + + + + 0.275954 0.273218 0.921521 0.000000 + 0.952351 0.051862 -0.300563 0.000000 + -0.129911 0.960553 -0.245888 0.000000 + + + + -6.764637 23.863518 -1.478289 0.000000 + + + + + + 0.275954 0.273218 0.921521 0.000000 + 0.952351 0.051862 -0.300563 0.000000 + -0.129911 0.960553 -0.245888 0.000000 + + + + -6.764637 23.863518 -1.478289 0.000000 + + + + -0.002145 -3.167443 -0.000690 0.000000 + + + -0.000188 0.000352 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.275604 -0.009430 -0.017239 0.000000 + -0.009430 0.253972 0.000481 0.000000 + -0.017239 0.000481 0.218083 0.000000 + + + + -0.002145 -3.167443 -0.000690 0.000000 + + + -0.000188 0.000352 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.251174 0.213206 0.283279 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 102 + 0 + 0 + + + + 0.307184 0.279937 0.909546 0.000000 + 0.949373 -0.024065 -0.313228 0.000000 + -0.065796 0.959717 -0.273157 0.000000 + + + + -2.548520 24.746481 -2.059655 0.000000 + + + + + + 0.307184 0.279937 0.909546 0.000000 + 0.949373 -0.024065 -0.313228 0.000000 + -0.065796 0.959717 -0.273157 0.000000 + + + + -2.548520 24.746481 -2.059655 0.000000 + + + + -0.002639 -3.166269 -0.002207 0.000000 + + + -0.000177 0.000315 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.336702 -0.017753 -0.008861 0.000000 + -0.017753 0.289803 0.004726 0.000000 + -0.008861 0.004726 0.310554 0.000000 + + + + -0.002639 -3.166269 -0.002207 0.000000 + + + -0.000177 0.000315 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.283731 0.307851 0.345477 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 104 + 0 + 0 + + + + 0.270584 0.262477 0.926224 0.000000 + 0.954163 0.054695 -0.294246 0.000000 + -0.127893 0.963387 -0.235646 0.000000 + + + + -10.263887 15.183156 1.194660 0.000000 + + + + + + 0.270584 0.262477 0.926224 0.000000 + 0.954163 0.054695 -0.294246 0.000000 + -0.127893 0.963387 -0.235646 0.000000 + + + + -10.263887 15.183156 1.194660 0.000000 + + + + 0.001319 -3.167841 0.002134 0.000000 + + + -0.000192 0.000351 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 1.005904 0.086390 -0.082662 0.000000 + 0.086390 1.317417 -0.057426 0.000000 + -0.082662 -0.057426 0.746288 0.000000 + + + + 0.001319 -3.167841 0.002134 0.000000 + + + -0.000192 0.000351 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 1.349612 0.720506 0.999490 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 106 + 0 + 0 + + + + 0.273492 0.245503 0.930016 0.000000 + 0.959489 -0.001580 -0.281742 0.000000 + -0.067699 0.969394 -0.235990 0.000000 + + + + -10.835474 19.140160 0.045569 0.000000 + + + + + + 0.273492 0.245503 0.930016 0.000000 + 0.959489 -0.001580 -0.281742 0.000000 + -0.067699 0.969394 -0.235990 0.000000 + + + + -10.835474 19.140160 0.045569 0.000000 + + + + -0.000200 -3.168237 0.001590 0.000000 + + + -0.000182 0.000350 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.428329 -0.030176 0.006413 0.000000 + -0.030176 0.330002 0.007440 0.000000 + 0.006413 0.007440 0.452232 0.000000 + + + + -0.000200 -3.168237 0.001590 0.000000 + + + -0.000182 0.000350 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.320876 0.453844 0.435843 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 108 + 0 + 0 + + + + 0.276657 0.248175 0.928370 0.000000 + 0.956198 0.025056 -0.291647 0.000000 + -0.095641 0.968391 -0.230372 0.000000 + + + + 2.141578 17.485554 -3.835118 0.000000 + + + + + + 0.276657 0.248175 0.928370 0.000000 + 0.956198 0.025056 -0.291647 0.000000 + -0.095641 0.968391 -0.230372 0.000000 + + + + 2.141578 17.485554 -3.835118 0.000000 + + + + -0.001111 -3.165064 -0.002480 0.000000 + + + -0.000171 0.000339 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.328809 0.003394 -0.001809 0.000000 + 0.003394 0.340048 -0.001334 0.000000 + -0.001809 -0.001334 0.322590 0.000000 + + + + -0.001111 -3.165064 -0.002480 0.000000 + + + -0.000171 0.000339 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.341163 0.322092 0.328191 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 110 + 0 + 0 + + + + 0.277013 0.279371 0.919356 0.000000 + 0.955605 0.019887 -0.293979 0.000000 + -0.100412 0.959977 -0.261459 0.000000 + + + + 0.366417 13.577110 -3.965630 0.000000 + + + + + + 0.277013 0.279371 0.919356 0.000000 + 0.955605 0.019887 -0.293979 0.000000 + -0.100412 0.959977 -0.261459 0.000000 + + + + 0.366417 13.577110 -3.965630 0.000000 + + + + -0.000046 -3.165520 -0.001177 0.000000 + + + -0.000178 0.000332 0.000272 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.725660 -0.047109 -0.067738 0.000000 + -0.047109 0.602552 0.011369 0.000000 + -0.067738 0.011369 0.509023 0.000000 + + + + -0.000046 -3.165520 -0.001177 0.000000 + + + -0.000178 0.000332 0.000272 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.587701 0.489545 0.759988 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 112 + 0 + 0 + + + + 0.266045 0.254641 0.929719 0.000000 + 0.960020 0.017125 -0.279406 0.000000 + -0.087070 0.966884 -0.239905 0.000000 + + + + 0.419757 16.287697 -2.909253 0.000000 + + + + + + 0.266045 0.254641 0.929719 0.000000 + 0.960020 0.017125 -0.279406 0.000000 + -0.087070 0.966884 -0.239905 0.000000 + + + + 0.419757 16.287697 -2.909253 0.000000 + + + + -0.000435 -3.165362 -0.001679 0.000000 + + + -0.000182 0.000342 0.000276 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.367256 0.034700 0.025560 0.000000 + 0.034700 0.473648 -0.009263 0.000000 + 0.025560 -0.009263 0.460074 0.000000 + + + + -0.000435 -3.165362 -0.001679 0.000000 + + + -0.000182 0.000342 0.000276 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.484105 0.466641 0.350232 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 114 + 0 + 0 + + + + 0.283997 0.280445 0.916895 0.000000 + 0.954494 0.008096 -0.298119 0.000000 + -0.091029 0.959836 -0.265384 0.000000 + + + + -5.006969 24.920004 -1.445974 0.000000 + + + + + + 0.283997 0.280445 0.916895 0.000000 + 0.954494 0.008096 -0.298119 0.000000 + -0.091029 0.959836 -0.265384 0.000000 + + + + -5.006969 24.920004 -1.445974 0.000000 + + + + -0.002488 -3.166935 -0.001467 0.000000 + + + -0.000173 0.000360 0.000279 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.291709 0.005933 0.020432 0.000000 + 0.005933 0.303217 -0.001239 0.000000 + 0.020432 -0.001239 0.355850 0.000000 + + + + -0.002488 -3.166935 -0.001467 0.000000 + + + -0.000173 0.000360 0.000279 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.305101 0.361810 0.283866 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 116 + 0 + 0 + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + -4.086954 -6.994352 1.661670 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 1 + -1 + -2 + 2 + 2 + 0 + + + + 0.000000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 118 + 0 + 0 + + + + 0.282709 0.266868 0.921334 0.000000 + 0.956434 -0.005457 -0.291899 0.000000 + -0.072871 0.963718 -0.256784 0.000000 + + + + -6.690329 22.841635 -0.064674 0.000000 + + + + + + 0.282709 0.266868 0.921334 0.000000 + 0.956434 -0.005457 -0.291899 0.000000 + -0.072871 0.963718 -0.256784 0.000000 + + + + -6.690329 22.841635 -0.064674 0.000000 + + + + -0.001309 -3.167142 -0.000531 0.000000 + + + -0.000175 0.000343 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.363364 0.005830 -0.011844 0.000000 + 0.005830 0.384322 -0.001253 0.000000 + -0.011844 -0.001253 0.323746 0.000000 + + + + -0.001309 -3.167142 -0.000531 0.000000 + + + -0.000175 0.000343 0.000294 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.386140 0.320474 0.364818 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 120 + 0 + 0 + + + + 0.269730 0.272314 0.923629 0.000000 + 0.958694 0.013996 -0.284097 0.000000 + -0.090291 0.962107 -0.257291 0.000000 + + + + -2.238892 10.446442 -1.914610 0.000000 + + + + + + 0.269730 0.272314 0.923629 0.000000 + 0.958694 0.013996 -0.284097 0.000000 + -0.090291 0.962107 -0.257291 0.000000 + + + + -2.238892 10.446442 -1.914610 0.000000 + + + + 0.001609 -3.165849 0.000284 0.000000 + + + -0.000182 0.000330 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.685166 -0.028362 -0.004088 0.000000 + -0.028362 0.594566 0.009114 0.000000 + -0.004088 0.009114 0.670291 0.000000 + + + + 0.001609 -3.165849 0.000284 0.000000 + + + -0.000182 0.000330 0.000301 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.585728 0.669266 0.695029 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 122 + 0 + 0 + + + + 0.266424 0.246170 0.931890 0.000000 + 0.959362 0.025527 -0.281021 0.000000 + -0.092967 0.968890 -0.229366 0.000000 + + + + -9.230621 16.392509 -0.261454 0.000000 + + + + + + 0.266424 0.246170 0.931890 0.000000 + 0.959362 0.025527 -0.281021 0.000000 + -0.092967 0.968890 -0.229366 0.000000 + + + + -9.230621 16.392509 -0.261454 0.000000 + + + + 0.000451 -3.167827 0.001564 0.000000 + + + -0.000184 0.000284 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.638536 0.026139 0.057842 0.000000 + 0.026139 0.704992 -0.002323 0.000000 + 0.057842 -0.002323 0.854270 0.000000 + + + + 0.000451 -3.167827 0.001564 0.000000 + + + -0.000184 0.000284 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.712477 0.868905 0.616416 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 124 + 0 + 0 + + + + 0.280871 0.270439 0.920855 0.000000 + 0.957483 -0.013109 -0.288193 0.000000 + -0.065867 0.962648 -0.262622 0.000000 + + + + -4.216679 11.550082 -2.446970 0.000000 + + + + + + 0.280871 0.270439 0.920855 0.000000 + 0.957483 -0.013109 -0.288193 0.000000 + -0.065867 0.962648 -0.262622 0.000000 + + + + -4.216679 11.550082 -2.446970 0.000000 + + + + 0.001164 -3.166569 0.000757 0.000000 + + + -0.000173 0.000330 0.000290 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.687466 -0.014084 -0.050529 0.000000 + -0.014084 0.655845 0.005966 0.000000 + -0.050529 0.005966 0.522564 0.000000 + + + + 0.001164 -3.166569 0.000757 0.000000 + + + -0.000173 0.000330 0.000290 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.651303 0.508288 0.706284 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 126 + 0 + 0 + + + + 0.261877 0.272530 0.925823 0.000000 + 0.960583 0.019108 -0.277334 0.000000 + -0.093273 0.961958 -0.256784 0.000000 + + + + 1.679321 22.410299 -3.022897 0.000000 + + + + + + 0.261877 0.272530 0.925823 0.000000 + 0.960583 0.019108 -0.277334 0.000000 + -0.093273 0.961958 -0.256784 0.000000 + + + + 1.679321 22.410299 -3.022897 0.000000 + + + + -0.002298 -3.165136 -0.003193 0.000000 + + + -0.000173 0.000330 0.000298 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.463526 0.009845 -0.015818 0.000000 + 0.009845 0.502138 -0.004652 0.000000 + -0.015818 -0.004652 0.412956 0.000000 + + + + -0.002298 -3.165136 -0.003193 0.000000 + + + -0.000173 0.000330 0.000298 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.505274 0.408383 0.464964 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 128 + 0 + 0 + + + + 0.273401 0.252818 0.928081 0.000000 + 0.958752 0.006378 -0.284174 0.000000 + -0.077763 0.967493 -0.240646 0.000000 + + + + 0.670923 21.478176 -2.130810 0.000000 + + + + + + 0.273401 0.252818 0.928081 0.000000 + 0.958752 0.006378 -0.284174 0.000000 + -0.077763 0.967493 -0.240646 0.000000 + + + + 0.670923 21.478176 -2.130810 0.000000 + + + + -0.001698 -3.165273 -0.002678 0.000000 + + + -0.000166 0.000319 0.000302 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.350099 -0.005389 -0.010238 0.000000 + -0.005389 0.335750 0.001244 0.000000 + -0.010238 0.001244 0.313451 0.000000 + + + + -0.001698 -3.165273 -0.002678 0.000000 + + + -0.000166 0.000319 0.000302 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.334113 0.310784 0.354403 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 130 + 0 + 0 + + + + 0.254240 0.276170 0.926872 0.000000 + 0.962169 0.024828 -0.271320 0.000000 + -0.097943 0.960788 -0.259410 0.000000 + + + + 0.817258 20.765602 -2.848148 0.000000 + + + + + + 0.254240 0.276170 0.926872 0.000000 + 0.962169 0.024828 -0.271320 0.000000 + -0.097943 0.960788 -0.259410 0.000000 + + + + 0.817258 20.765602 -2.848148 0.000000 + + + + -0.001720 -3.165330 -0.002601 0.000000 + + + -0.000159 0.000323 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.332454 -0.014740 0.005360 0.000000 + -0.014740 0.279118 0.006063 0.000000 + 0.005360 0.006063 0.348079 0.000000 + + + + -0.001720 -3.165330 -0.002601 0.000000 + + + -0.000159 0.000323 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.274606 0.349776 0.335268 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 132 + 0 + 0 + + + + 0.291108 0.281970 0.914193 0.000000 + 0.952135 0.007754 -0.305581 0.000000 + -0.093253 0.959392 -0.266216 0.000000 + + + + -6.037422 24.456434 -0.454460 0.000000 + + + + + + 0.291108 0.281970 0.914193 0.000000 + 0.952135 0.007754 -0.305581 0.000000 + -0.093253 0.959392 -0.266216 0.000000 + + + + -6.037422 24.456434 -0.454460 0.000000 + + + + -0.001985 -3.167069 -0.001045 0.000000 + + + -0.000140 0.000332 0.000282 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.461956 -0.026666 -0.025547 0.000000 + -0.026666 0.391830 0.007695 0.000000 + -0.025547 0.007695 0.381746 0.000000 + + + + -0.001985 -3.167069 -0.001045 0.000000 + + + -0.000140 0.000332 0.000282 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.382924 0.374300 0.478309 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 134 + 0 + 0 + + + + 0.282443 0.276804 0.918480 0.000000 + 0.955446 0.004391 -0.295134 0.000000 + -0.085727 0.960916 -0.263231 0.000000 + + + + 0.750912 14.822566 -2.498849 0.000000 + + + + + + 0.282443 0.276804 0.918480 0.000000 + 0.955446 0.004391 -0.295134 0.000000 + -0.085727 0.960916 -0.263231 0.000000 + + + + 0.750912 14.822566 -2.498849 0.000000 + + + + 0.000112 -3.165181 -0.001530 0.000000 + + + -0.000175 0.000346 0.000279 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.314363 0.005554 -0.004282 0.000000 + 0.005554 0.332651 -0.001751 0.000000 + -0.004282 -0.001751 0.300829 0.000000 + + + + 0.000112 -3.165181 -0.001530 0.000000 + + + -0.000175 0.000346 0.000279 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.334450 0.299587 0.313805 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 136 + 0 + 0 + + + + 0.251660 0.268205 0.929911 0.000000 + 0.964375 0.011455 -0.264291 0.000000 + -0.081536 0.963294 -0.255767 0.000000 + + + + 2.279323 20.056404 -3.510723 0.000000 + + + + + + 0.251660 0.268205 0.929911 0.000000 + 0.964375 0.011455 -0.264291 0.000000 + -0.081536 0.963294 -0.255767 0.000000 + + + + 2.279323 20.056404 -3.510723 0.000000 + + + + -0.001768 -3.164999 -0.002980 0.000000 + + + -0.000168 0.000332 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.302863 0.000459 -0.008528 0.000000 + 0.000459 0.307219 -0.000544 0.000000 + -0.008528 -0.000544 0.274635 0.000000 + + + + -0.001768 -3.164999 -0.002980 0.000000 + + + -0.000168 0.000332 0.000300 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.307385 0.272254 0.305078 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 138 + 0 + 0 + + + + 0.242261 0.206779 0.947920 0.000000 + 0.965595 0.043814 -0.256335 0.000000 + -0.094537 0.977406 -0.189050 0.000000 + + + + -0.215132 14.671159 -1.805316 0.000000 + + + + + + 0.242261 0.206779 0.947920 0.000000 + 0.965595 0.043814 -0.256335 0.000000 + -0.094537 0.977406 -0.189050 0.000000 + + + + -0.215132 14.671159 -1.805316 0.000000 + + + + 0.000416 -3.165317 -0.001170 0.000000 + + + -0.000177 0.000348 0.000285 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.577963 0.026100 -0.006581 0.000000 + 0.026100 0.676926 -0.011105 0.000000 + -0.006581 -0.011105 0.554275 0.000000 + + + + 0.000416 -3.165317 -0.001170 0.000000 + + + -0.000177 0.000348 0.000285 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.684562 0.552385 0.572218 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 140 + 0 + 0 + + + + 0.304548 0.275685 0.911728 0.000000 + 0.951993 -0.119219 -0.281949 0.000000 + 0.030967 0.953826 -0.298758 0.000000 + + + + -3.571203 10.602681 -3.091400 0.000000 + + + + + + 0.304548 0.275685 0.911728 0.000000 + 0.951993 -0.119219 -0.281949 0.000000 + 0.030967 0.953826 -0.298758 0.000000 + + + + -3.571203 10.602681 -3.091400 0.000000 + + + + 0.001238 -3.166449 0.000694 0.000000 + + + -0.000162 0.000318 0.000318 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.692087 -0.012773 -0.075099 0.000000 + -0.012773 0.647636 0.029922 0.000000 + -0.075099 0.029922 0.463226 0.000000 + + + + 0.001238 -3.166449 0.000694 0.000000 + + + -0.000162 0.000318 0.000318 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.644523 0.437780 0.720645 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 142 + 0 + 0 + + + + 0.287046 0.259887 0.921989 0.000000 + 0.953841 0.011150 -0.300105 0.000000 + -0.088273 0.965575 -0.244690 0.000000 + + + + -2.225920 12.455692 -3.315838 0.000000 + + + + + + 0.287046 0.259887 0.921989 0.000000 + 0.953841 0.011150 -0.300105 0.000000 + -0.088273 0.965575 -0.244690 0.000000 + + + + -2.225920 12.455692 -3.315838 0.000000 + + + + 0.000524 -3.166133 -0.000055 0.000000 + + + -0.000191 0.000405 0.000272 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.923296 0.006944 -0.088225 0.000000 + 0.006944 0.970838 -0.006200 0.000000 + -0.088225 -0.006200 0.619623 0.000000 + + + + 0.000524 -3.166133 -0.000055 0.000000 + + + -0.000191 0.000405 0.000272 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.973501 0.595806 0.944450 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 144 + 0 + 0 + + + + 0.268226 0.224188 0.936907 0.000000 + 0.960055 0.018231 -0.279216 0.000000 + -0.079678 0.974375 -0.210343 0.000000 + + + + -9.112514 17.757938 0.199737 0.000000 + + + + + + 0.268226 0.224188 0.936907 0.000000 + 0.960055 0.018231 -0.279216 0.000000 + -0.079678 0.974375 -0.210343 0.000000 + + + + -9.112514 17.757938 0.199737 0.000000 + + + + 0.000255 -3.167715 0.001250 0.000000 + + + -0.000188 0.000352 0.000287 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.374337 0.023469 0.015617 0.000000 + 0.023469 0.446691 -0.005448 0.000000 + 0.015617 -0.005448 0.440627 0.000000 + + + + 0.000255 -3.167715 0.001250 0.000000 + + + -0.000188 0.000352 0.000287 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.453700 0.444118 0.363836 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 146 + 0 + 0 + + + + 0.272262 0.275121 0.922053 0.000000 + 0.958384 0.007979 -0.285370 0.000000 + -0.085868 0.961377 -0.261499 0.000000 + + + + -8.206606 11.824456 -0.271219 0.000000 + + + + + + 0.272262 0.275121 0.922053 0.000000 + 0.958384 0.007979 -0.285370 0.000000 + -0.085868 0.961377 -0.261499 0.000000 + + + + -8.206606 11.824456 -0.271219 0.000000 + + + + 0.001826 -3.167458 0.002030 0.000000 + + + -0.000174 0.000334 0.000304 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.358441 -0.029307 0.005791 0.000000 + -0.029307 0.262614 0.009343 0.000000 + 0.005791 0.009343 0.376092 0.000000 + + + + 0.001826 -3.167458 0.002030 0.000000 + + + -0.000174 0.000334 0.000304 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.253451 0.377827 0.365870 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 148 + 0 + 0 + + + + 0.266603 0.261177 0.927744 0.000000 + 0.958254 0.031346 -0.284195 0.000000 + -0.103306 0.964782 -0.241918 0.000000 + + + + -8.307735 22.773829 0.525339 0.000000 + + + + + + 0.266603 0.261177 0.927744 0.000000 + 0.958254 0.031346 -0.284195 0.000000 + -0.103306 0.964782 -0.241918 0.000000 + + + + -8.307735 22.773829 0.525339 0.000000 + + + + -0.001083 -3.167543 0.000048 0.000000 + + + -0.000168 0.000346 0.000316 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.580518 0.020111 -0.046532 0.000000 + 0.020111 0.663768 -0.013655 0.000000 + -0.046532 -0.013655 0.424085 0.000000 + + + + -0.001083 -3.167543 0.000048 0.000000 + + + -0.000168 0.000346 0.000316 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.670836 0.411045 0.586491 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 150 + 0 + 0 + + + + 0.241777 0.253009 0.936766 0.000000 + 0.966434 0.023662 -0.255825 0.000000 + -0.086892 0.967174 -0.238796 0.000000 + + + + -0.112271 22.069670 -3.606622 0.000000 + + + + + + 0.241777 0.253009 0.936766 0.000000 + 0.966434 0.023662 -0.255825 0.000000 + -0.086892 0.967174 -0.238796 0.000000 + + + + -0.112271 22.069670 -3.606622 0.000000 + + + + -0.002379 -3.165752 -0.002538 0.000000 + + + -0.000170 0.000324 0.000298 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.434495 -0.003448 -0.005632 0.000000 + -0.003448 0.423656 0.000633 0.000000 + -0.005632 0.000633 0.414102 0.000000 + + + + -0.002379 -3.165752 -0.002538 0.000000 + + + -0.000170 0.000324 0.000298 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.422736 0.412644 0.436873 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 152 + 0 + 0 + + + + 0.254328 0.271086 0.928348 0.000000 + 0.965174 -0.010306 -0.261407 0.000000 + -0.061296 0.962500 -0.264266 0.000000 + + + + -10.277276 17.783934 0.780533 0.000000 + + + + + + 0.254328 0.271086 0.928348 0.000000 + 0.965174 -0.010306 -0.261407 0.000000 + -0.061296 0.962500 -0.264266 0.000000 + + + + -10.277276 17.783934 0.780533 0.000000 + + + + 0.000444 -3.167942 0.001646 0.000000 + + + -0.000178 0.000344 0.000303 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.737092 0.038964 0.029305 0.000000 + 0.038964 0.866952 -0.010682 0.000000 + 0.029305 -0.010682 0.831291 0.000000 + + + + 0.000444 -3.167942 0.001646 0.000000 + + + -0.000178 0.000344 0.000303 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.877898 0.839660 0.717778 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 154 + 0 + 0 + + + + 0.299216 0.226625 0.926882 0.000000 + 0.950806 0.010861 -0.309595 0.000000 + -0.080229 0.973922 -0.212226 0.000000 + + + + -2.472811 23.386496 -2.742500 0.000000 + + + + + + 0.299216 0.226625 0.926882 0.000000 + 0.950806 0.010861 -0.309595 0.000000 + -0.080229 0.973922 -0.212226 0.000000 + + + + -2.472811 23.386496 -2.742500 0.000000 + + + + -0.002451 -3.166363 -0.002020 0.000000 + + + -0.000166 0.000317 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.274777 0.018970 0.005428 0.000000 + 0.018970 0.327233 -0.004729 0.000000 + 0.005428 -0.004729 0.297802 0.000000 + + + + -0.002451 -3.166363 -0.002020 0.000000 + + + -0.000166 0.000317 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.333602 0.299013 0.267198 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 156 + 0 + 0 + + + + 0.315779 0.242121 0.917421 0.000000 + 0.945339 0.002614 -0.326078 0.000000 + -0.081349 0.970243 -0.228061 0.000000 + + + + -3.610549 23.389378 -1.669634 0.000000 + + + + + + 0.315779 0.242121 0.917421 0.000000 + 0.945339 0.002614 -0.326078 0.000000 + -0.081349 0.970243 -0.228061 0.000000 + + + + -3.610549 23.389378 -1.669634 0.000000 + + + + -0.002088 -3.166511 -0.001661 0.000000 + + + -0.000172 0.000344 0.000299 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.394054 -0.004516 0.031684 0.000000 + -0.004516 0.374011 0.001523 0.000000 + 0.031684 0.001523 0.513060 0.000000 + + + + -0.002088 -3.166511 -0.001661 0.000000 + + + -0.000172 0.000344 0.000299 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.372371 0.520971 0.387783 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 158 + 0 + 0 + + + + 0.272245 0.253314 0.928286 0.000000 + 0.960007 -0.005993 -0.279912 0.000000 + -0.065343 0.967366 -0.244815 0.000000 + + + + -11.480623 17.341631 -0.277955 0.000000 + + + + + + 0.272245 0.253314 0.928286 0.000000 + 0.960007 -0.005993 -0.279912 0.000000 + -0.065343 0.967366 -0.244815 0.000000 + + + + -11.480623 17.341631 -0.277955 0.000000 + + + + 0.000203 -3.168483 0.002119 0.000000 + + + -0.000183 0.000323 0.000285 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.456758 0.005744 0.021015 0.000000 + 0.005744 0.470209 -0.001917 0.000000 + 0.021015 -0.001917 0.531361 0.000000 + + + + 0.000203 -3.168483 0.002119 0.000000 + + + -0.000183 0.000323 0.000285 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.471969 0.536875 0.449483 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 160 + 0 + 0 + + + + 0.288222 0.274237 0.917454 0.000000 + 0.954227 -0.002342 -0.299075 0.000000 + -0.079869 0.961659 -0.262359 0.000000 + + + + -8.022085 13.911036 0.167906 0.000000 + + + + + + 0.288222 0.274237 0.917454 0.000000 + 0.954227 -0.002342 -0.299075 0.000000 + -0.079869 0.961659 -0.262359 0.000000 + + + + -8.022085 13.911036 0.167906 0.000000 + + + + 0.001331 -3.167321 0.001599 0.000000 + + + -0.000180 0.000334 0.000310 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.350486 -0.013354 0.000530 0.000000 + -0.013354 0.310473 0.003706 0.000000 + 0.000530 0.003706 0.352315 0.000000 + + + + 0.001331 -3.167321 0.001599 0.000000 + + + -0.000180 0.000334 0.000310 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.306129 0.352457 0.354688 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 162 + 0 + 0 + + + + 0.258442 0.351774 0.899702 0.000000 + 0.965628 -0.067303 -0.251064 0.000000 + -0.027765 0.933662 -0.357076 0.000000 + + + + -8.393955 20.474304 -0.927764 0.000000 + + + + + + 0.258442 0.351774 0.899702 0.000000 + 0.965628 -0.067303 -0.251064 0.000000 + -0.027765 0.933662 -0.357076 0.000000 + + + + -8.393955 20.474304 -0.927764 0.000000 + + + + -0.000941 -3.167741 0.000495 0.000000 + + + -0.000181 0.000346 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.373811 0.005516 -0.002104 0.000000 + 0.005516 0.393163 -0.000204 0.000000 + -0.002104 -0.000204 0.367949 0.000000 + + + + -0.000941 -3.167741 0.000495 0.000000 + + + -0.000181 0.000346 0.000288 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.394645 0.367171 0.373107 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 164 + 0 + 0 + + + + 0.278631 0.201994 0.938916 0.000000 + 0.959357 -0.013024 -0.281895 0.000000 + -0.044712 0.979300 -0.197414 0.000000 + + + + -10.886441 20.601580 0.028054 0.000000 + + + + + + 0.278631 0.201994 0.938916 0.000000 + 0.959357 -0.013024 -0.281895 0.000000 + -0.044712 0.979300 -0.197414 0.000000 + + + + -10.886441 20.601580 0.028054 0.000000 + + + + -0.000615 -3.168304 0.001342 0.000000 + + + -0.000174 0.000343 0.000275 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.237972 0.016787 0.017304 0.000000 + 0.016787 0.287938 -0.003899 0.000000 + 0.017304 -0.003899 0.317162 0.000000 + + + + -0.000615 -3.168304 0.001342 0.000000 + + + -0.000174 0.000343 0.000275 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.292996 0.320783 0.229294 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 166 + 0 + 0 + + + + 0.260586 0.226656 0.938468 0.000000 + 0.963287 0.003997 -0.268443 0.000000 + -0.064596 0.973967 -0.217294 0.000000 + + + + 0.396177 18.553259 -2.599638 0.000000 + + + + + + 0.260586 0.226656 0.938468 0.000000 + 0.963287 0.003997 -0.268443 0.000000 + -0.064596 0.973967 -0.217294 0.000000 + + + + 0.396177 18.553259 -2.599638 0.000000 + + + + -0.000977 -3.165363 -0.002078 0.000000 + + + -0.000177 0.000331 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.359976 0.003616 0.026764 0.000000 + 0.003616 0.365703 -0.000393 0.000000 + 0.026764 -0.000393 0.468821 0.000000 + + + + -0.000977 -3.165363 -0.002078 0.000000 + + + -0.000177 0.000331 0.000283 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.366707 0.475048 0.352745 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 168 + 0 + 0 + + + + 0.303373 0.291774 0.907101 0.000000 + 0.949547 -0.013113 -0.313351 0.000000 + -0.079533 0.956398 -0.281031 0.000000 + + + + -9.927484 14.747825 0.034541 0.000000 + + + + + + 0.303373 0.291774 0.907101 0.000000 + 0.949547 -0.013113 -0.313351 0.000000 + -0.079533 0.956398 -0.281031 0.000000 + + + + -9.927484 14.747825 0.034541 0.000000 + + + + 0.001051 -3.167932 0.002079 0.000000 + + + -0.000195 0.000333 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.673907 0.080193 0.073487 0.000000 + 0.080193 0.877934 -0.024921 0.000000 + 0.073487 -0.024921 0.888422 0.000000 + + + + 0.001051 -3.167932 0.002079 0.000000 + + + -0.000195 0.000333 0.000297 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.905643 0.911182 0.623437 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 170 + 0 + 0 + + + + 0.271995 0.282809 0.919803 0.000000 + 0.960321 -0.018521 -0.278282 0.000000 + -0.061665 0.958998 -0.276625 0.000000 + + + + 1.777066 14.335148 -3.082107 0.000000 + + + + + + 0.271995 0.282809 0.919803 0.000000 + 0.960321 -0.018521 -0.278282 0.000000 + -0.061665 0.958998 -0.276625 0.000000 + + + + 1.777066 14.335148 -3.082107 0.000000 + + + + 0.000037 -3.164991 -0.001789 0.000000 + + + -0.000173 0.000342 0.000278 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.330301 0.026053 0.032641 0.000000 + 0.026053 0.406972 -0.008307 0.000000 + 0.032641 -0.008307 0.429494 0.000000 + + + + 0.000037 -3.164991 -0.001789 0.000000 + + + -0.000173 0.000342 0.000278 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.414884 0.439280 0.312602 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 172 + 0 + 0 + + + + 0.273325 0.268440 0.923706 0.000000 + 0.958168 0.008775 -0.286072 0.000000 + -0.084899 0.963256 -0.254812 0.000000 + + + + -2.715794 13.233632 -1.192465 0.000000 + + + + + + 0.273325 0.268440 0.923706 0.000000 + 0.958168 0.008775 -0.286072 0.000000 + -0.084899 0.963256 -0.254812 0.000000 + + + + -2.715794 13.233632 -1.192465 0.000000 + + + + 0.001070 -3.165934 -0.000031 0.000000 + + + -0.000167 0.000358 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.394029 0.012621 0.002867 0.000000 + 0.012621 0.433447 -0.003779 0.000000 + 0.002867 -0.003779 0.403964 0.000000 + + + + 0.001070 -3.165934 -0.000031 0.000000 + + + -0.000167 0.000358 0.000295 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.437382 0.404729 0.389330 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 0 + 174 + 0 + 0 + + + + 0.291331 0.271931 0.917159 0.000000 + 0.952633 0.004998 -0.304082 0.000000 + -0.087273 0.962304 -0.257594 0.000000 + + + + -9.943352 13.049049 -0.094216 0.000000 + + + + + + 0.291331 0.271931 0.917159 0.000000 + 0.952633 0.004998 -0.304082 0.000000 + -0.087273 0.962304 -0.257594 0.000000 + + + + -9.943352 13.049049 -0.094216 0.000000 + + + + 0.001521 -3.167956 0.002386 0.000000 + + + -0.000172 0.000324 0.000303 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + 999999984306749440.000000 + 0.000000 + 0.500000 + 0.100000 + 1.000000 + 0.000000 + 0.000000 + 0 + 0 + 84 + -1 + 1 + 2 + 1 + + + + 0.541295 -0.040699 -0.003333 0.000000 + -0.040699 0.422760 0.012051 0.000000 + -0.003333 0.012051 0.529632 0.000000 + + + + 0.001521 -3.167956 0.002386 0.000000 + + + -0.000172 0.000324 0.000303 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.000000 -10.000000 0.000000 0.000000 + + + 0.409209 0.528753 0.555725 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1.000000 + 0.000000 + 0.000000 + 0.005000 + 0.010000 + 0.010000 + 0.010000 + 0.800000 + 1.000000 + 0 + + + + 71 + 147 + 0 + 6 + -1 + -1 + 0 + 0.398739 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999825 -0.015506 0.010442 0.000000 + 0.015509 0.999880 -0.000183 0.000000 + -0.010438 0.000345 0.999945 0.000000 + + + + -1.148605 0.407813 -0.909073 0.000000 + + + + + + 0.999989 -0.004721 0.000164 0.000000 + 0.004721 0.999988 0.001398 0.000000 + -0.000171 -0.001398 0.999999 0.000000 + + + + -0.879751 0.179427 1.106070 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 81 + 95 + 0 + 6 + -1 + -1 + 0 + -0.154912 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999928 0.000549 0.011972 0.000000 + -0.000801 0.999779 0.020995 0.000000 + -0.011958 -0.021003 0.999708 0.000000 + + + + 0.130261 -0.280198 0.534541 0.000000 + + + + + + 0.999832 0.001246 -0.018271 0.000000 + -0.001189 0.999994 0.003157 0.000000 + 0.018275 -0.003135 0.999828 0.000000 + + + + 0.609493 0.303517 -0.029588 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 77 + 109 + 0 + 6 + -1 + -1 + 0 + -0.254296 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999994 -0.001953 -0.002959 0.000000 + 0.001987 0.999934 0.011345 0.000000 + 0.002937 -0.011351 0.999931 0.000000 + + + + 1.505062 -1.204177 -0.708804 0.000000 + + + + + + 0.999862 -0.012593 0.010844 0.000000 + 0.012679 0.999889 -0.007881 0.000000 + -0.010743 0.008017 0.999910 0.000000 + + + + -0.160763 -1.154789 -0.404381 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 107 + 165 + 0 + 6 + -1 + -1 + 0 + 0.195486 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999972 -0.001225 0.007369 0.000000 + 0.001210 0.999997 0.002116 0.000000 + -0.007372 -0.002107 0.999971 0.000000 + + + + 0.126838 1.149777 -0.642064 0.000000 + + + + + + 0.999714 0.022761 0.007321 0.000000 + -0.022465 0.999012 -0.038348 0.000000 + -0.008186 0.038172 0.999238 0.000000 + + + + -1.234870 1.214337 -0.139222 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 107 + 159 + 0 + 6 + -1 + -1 + 0 + 0.714112 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999972 -0.001225 0.007369 0.000000 + 0.001210 0.999997 0.002116 0.000000 + -0.007372 -0.002107 0.999971 0.000000 + + + + -0.798123 -1.531303 0.605195 0.000000 + + + + + + 0.999987 0.000688 0.005104 0.000000 + -0.000733 0.999959 0.008980 0.000000 + -0.005098 -0.008984 0.999947 0.000000 + + + + 1.078496 -1.061508 0.632784 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 75 + 127 + 0 + 6 + -1 + -1 + 0 + -0.039352 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999992 -0.002750 -0.002877 0.000000 + 0.002758 0.999993 0.002669 0.000000 + 0.002870 -0.002677 0.999992 0.000000 + + + + 0.945728 -1.136918 -0.004621 0.000000 + + + + + + 0.999985 -0.002735 -0.004700 0.000000 + 0.002745 0.999994 0.002207 0.000000 + 0.004694 -0.002220 0.999987 0.000000 + + + + 1.151271 -0.929153 -1.336886 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 99 + 103 + 0 + 6 + -1 + -1 + 0 + -0.406892 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999887 -0.009273 -0.011833 0.000000 + 0.009287 0.999956 0.001103 0.000000 + 0.011822 -0.001213 0.999929 0.000000 + + + + 1.565424 1.236504 -0.716268 0.000000 + + + + + + 0.998740 0.038313 0.032400 0.000000 + -0.038899 0.999087 0.017672 0.000000 + -0.031694 -0.018910 0.999319 0.000000 + + + + 0.776975 0.767613 1.544399 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 99 + 75 + 0 + 6 + -1 + -1 + 0 + 0.541433 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999887 -0.009273 -0.011833 0.000000 + 0.009287 0.999956 0.001103 0.000000 + 0.011822 -0.001213 0.999929 0.000000 + + + + 1.010527 -0.312474 1.047620 0.000000 + + + + + + 0.999992 -0.002750 -0.002877 0.000000 + 0.002758 0.999993 0.002669 0.000000 + 0.002870 -0.002677 0.999992 0.000000 + + + + 0.976103 -1.173144 -0.122854 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 43 + 41 + 0 + 6 + -1 + -1 + 0 + 0.000064 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999671 0.022995 0.011362 0.000000 + -0.022373 0.998392 -0.052082 0.000000 + -0.012541 0.051811 0.998578 0.000000 + + + + 0.547733 0.364076 0.024028 0.000000 + + + + + + 0.998622 0.051113 -0.011898 0.000000 + -0.051637 0.997462 -0.049015 0.000000 + 0.009363 0.049562 0.998727 0.000000 + + + + -0.181741 1.015347 0.260045 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 115 + 103 + 0 + 6 + -1 + -1 + 0 + 0.398816 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999854 0.007988 0.015077 0.000000 + -0.008209 0.999859 0.014645 0.000000 + -0.014958 -0.014767 0.999779 0.000000 + + + + -0.544667 -1.603396 1.544737 0.000000 + + + + + + 0.998740 0.038313 0.032400 0.000000 + -0.038899 0.999087 0.017672 0.000000 + -0.031694 -0.018910 0.999319 0.000000 + + + + -1.197697 -1.679137 -0.898750 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 113 + 77 + 0 + 6 + -1 + -1 + 0 + -0.366810 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999974 -0.006829 -0.002456 0.000000 + 0.006831 0.999976 0.000691 0.000000 + 0.002451 -0.000708 0.999997 0.000000 + + + + 0.245624 -1.559062 0.712341 0.000000 + + + + + + 0.999994 -0.001953 -0.002959 0.000000 + 0.001987 0.999934 0.011345 0.000000 + 0.002937 -0.011351 0.999931 0.000000 + + + + 0.223766 -1.167623 -1.090824 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 129 + 131 + 0 + 6 + -1 + -1 + 0 + 0.040231 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999985 0.004147 0.003719 0.000000 + -0.004153 0.999990 0.001576 0.000000 + -0.003712 -0.001592 0.999992 0.000000 + + + + -0.516964 0.990952 0.901215 0.000000 + + + + + + 0.999737 -0.020466 -0.010354 0.000000 + 0.020667 0.999592 0.019718 0.000000 + 0.009946 -0.019927 0.999752 0.000000 + + + + 0.024732 1.660541 0.360760 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 31 + 93 + 0 + 6 + -1 + -1 + 0 + -0.111936 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999902 0.013490 -0.003659 0.000000 + -0.013487 0.999909 0.000807 0.000000 + 0.003670 -0.000758 0.999993 0.000000 + + + + -1.181128 -0.261032 -0.365489 0.000000 + + + + + + 0.999190 -0.040157 -0.002590 0.000000 + 0.040164 0.999189 0.002843 0.000000 + 0.002473 -0.002945 0.999993 0.000000 + + + + -0.467074 -0.083943 -1.427529 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 101 + 115 + 0 + 6 + -1 + -1 + 0 + 1.536227 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999443 -0.028229 0.017782 0.000000 + 0.028344 0.999579 -0.006224 0.000000 + -0.017598 0.006724 0.999822 0.000000 + + + + 1.871074 0.120632 -0.165374 0.000000 + + + + + + 0.999854 0.007988 0.015077 0.000000 + -0.008209 0.999859 0.014645 0.000000 + -0.014958 -0.014767 0.999779 0.000000 + + + + 0.371448 -0.503327 -1.444950 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 61 + 33 + 0 + 6 + -1 + -1 + 0 + -0.585814 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999989 0.004199 -0.002231 0.000000 + -0.004190 0.999982 0.004222 0.000000 + 0.002248 -0.004212 0.999989 0.000000 + + + + 1.178923 0.330306 0.853489 0.000000 + + + + + + 0.999992 0.000088 0.004020 0.000000 + -0.000043 0.999937 -0.011226 0.000000 + -0.004020 0.011225 0.999929 0.000000 + + + + 0.722433 -0.760042 -0.903138 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 87 + 61 + 0 + 6 + -1 + -1 + 0 + -3.175179 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999592 0.022966 0.016977 0.000000 + -0.023176 0.999656 0.012290 0.000000 + -0.016688 -0.012679 0.999780 0.000000 + + + + -0.058689 -1.275792 -0.502480 0.000000 + + + + + + 0.999989 0.004199 -0.002231 0.000000 + -0.004190 0.999982 0.004222 0.000000 + 0.002248 -0.004212 0.999989 0.000000 + + + + -0.588453 -0.318871 -1.069428 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 13 + 161 + 0 + 6 + -1 + -1 + 0 + 0.304131 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999305 0.001210 -0.037243 0.000000 + -0.000641 0.999883 0.015283 0.000000 + 0.037257 -0.015249 0.999189 0.000000 + + + + -0.603564 0.251886 -0.558628 0.000000 + + + + + + 0.999941 0.010428 0.003191 0.000000 + -0.010465 0.999876 0.011748 0.000000 + -0.003068 -0.011780 0.999926 0.000000 + + + + -0.369211 -0.434017 -0.829002 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 35 + 87 + 0 + 6 + -1 + -1 + 0 + 0.573876 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 1.000000 0.000429 -0.000126 0.000000 + -0.000428 0.999991 0.004252 0.000000 + 0.000128 -0.004252 0.999991 0.000000 + + + + 0.668413 0.555253 1.563411 0.000000 + + + + + + 0.999592 0.022966 0.016977 0.000000 + -0.023176 0.999656 0.012290 0.000000 + -0.016688 -0.012679 0.999780 0.000000 + + + + -0.396940 1.203964 -0.959884 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 167 + 131 + 0 + 6 + -1 + -1 + 0 + -0.177745 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999813 0.013677 -0.013690 0.000000 + -0.013995 0.999629 -0.023374 0.000000 + 0.013366 0.023561 0.999633 0.000000 + + + + 1.101216 -1.519549 -0.208364 0.000000 + + + + + + 0.999737 -0.020466 -0.010354 0.000000 + 0.020667 0.999592 0.019718 0.000000 + 0.009946 -0.019927 0.999752 0.000000 + + + + -1.109613 -1.421741 -0.000889 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 167 + 113 + 0 + 6 + -1 + -1 + 0 + 0.177712 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999813 0.013677 -0.013690 0.000000 + -0.013995 0.999629 -0.023374 0.000000 + 0.013366 0.023561 0.999633 0.000000 + + + + -1.140611 0.683941 0.340254 0.000000 + + + + + + 0.999974 -0.006829 -0.002456 0.000000 + 0.006831 0.999976 0.000691 0.000000 + 0.002451 -0.000708 0.999997 0.000000 + + + + 0.991228 1.000827 -0.392762 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 157 + 155 + 0 + 6 + -1 + -1 + 0 + 0.147908 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999025 -0.003424 0.044024 0.000000 + 0.003940 0.999925 -0.011635 0.000000 + -0.043981 0.011797 0.998963 0.000000 + + + + -0.762092 0.160179 1.350998 0.000000 + + + + + + 0.999594 -0.007832 0.027388 0.000000 + 0.008676 0.999487 -0.030844 0.000000 + -0.027133 0.031069 0.999149 0.000000 + + + + -1.208668 0.920593 0.058037 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 31 + 5 + 0 + 6 + -1 + -1 + 0 + -0.142490 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999902 0.013490 -0.003660 0.000000 + -0.013487 0.999909 0.000807 0.000000 + 0.003670 -0.000758 0.999993 0.000000 + + + + 0.064520 -0.979395 -0.312057 0.000000 + + + + + + 0.999984 -0.005549 0.001266 0.000000 + 0.005545 0.999981 0.002810 0.000000 + -0.001282 -0.002803 0.999995 0.000000 + + + + -1.250101 -0.577753 0.715910 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 127 + 137 + 0 + 6 + -1 + -1 + 0 + -0.035165 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999985 -0.002735 -0.004700 0.000000 + 0.002745 0.999994 0.002207 0.000000 + 0.004694 -0.002220 0.999987 0.000000 + + + + -0.678187 -0.758855 1.211484 0.000000 + + + + + + 0.999816 0.005765 -0.018303 0.000000 + -0.005765 0.999983 0.000035 0.000000 + 0.018303 0.000070 0.999833 0.000000 + + + + 1.378594 -0.419746 -0.104451 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 23 + 83 + 0 + 6 + -1 + -1 + 0 + -0.176209 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999920 0.012504 0.001622 0.000000 + -0.012480 0.999819 -0.014376 0.000000 + -0.001802 0.014355 0.999895 0.000000 + + + + 0.135392 0.605935 1.521100 0.000000 + + + + + + 0.999914 -0.006125 -0.011598 0.000000 + 0.006091 0.999977 -0.003025 0.000000 + 0.011617 0.002954 0.999928 0.000000 + + + + 1.617340 -0.268658 0.832913 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 153 + 37 + 0 + 6 + -1 + -1 + 0 + -0.820308 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999873 0.004799 -0.015190 0.000000 + -0.004741 0.999981 0.003909 0.000000 + 0.015208 -0.003837 0.999877 0.000000 + + + + 0.741776 0.952270 -0.603444 0.000000 + + + + + + 0.999984 -0.005219 -0.002192 0.000000 + 0.005223 0.999985 0.001494 0.000000 + 0.002184 -0.001505 0.999996 0.000000 + + + + 0.689913 0.994789 0.126445 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 165 + 57 + 0 + 6 + -1 + -1 + 0 + 1.265434 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999700 0.023651 0.006386 0.000000 + -0.023400 0.999045 -0.036891 0.000000 + -0.007252 0.036730 0.999299 0.000000 + + + + -0.440566 -1.433525 0.316210 0.000000 + + + + + + 0.999292 -0.013129 -0.035244 0.000000 + 0.013967 0.999623 0.023642 0.000000 + 0.034920 -0.024117 0.999099 0.000000 + + + + 0.047603 -0.582398 -1.113613 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 97 + 119 + 0 + 6 + -1 + -1 + 0 + 0.982118 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999969 -0.000079 -0.007920 0.000000 + 0.000040 0.999988 -0.004880 0.000000 + 0.007920 0.004880 0.999957 0.000000 + + + + 0.040992 1.011433 -0.026501 0.000000 + + + + + + 0.999866 0.013991 0.008538 0.000000 + -0.014118 0.999788 0.014996 0.000000 + -0.008326 -0.015115 0.999851 0.000000 + + + + 0.075087 0.157909 1.074155 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 67 + 65 + 0 + 6 + -1 + -1 + 0 + 0.167513 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999968 -0.007428 0.003032 0.000000 + 0.007429 0.999972 -0.000233 0.000000 + -0.003030 0.000255 0.999995 0.000000 + + + + 1.425411 -0.011601 0.011769 0.000000 + + + + + + 0.999960 -0.008821 -0.001079 0.000000 + 0.008811 0.999920 -0.009119 0.000000 + 0.001159 0.009109 0.999958 0.000000 + + + + 0.935354 -0.372748 -1.365238 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 23 + 131 + 0 + 6 + -1 + -1 + 0 + 0.138032 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999972 0.007345 0.001594 0.000000 + -0.007310 0.999748 -0.021209 0.000000 + -0.001749 0.021197 0.999774 0.000000 + + + + 1.056650 1.701536 -0.117703 0.000000 + + + + + + 0.999719 -0.021348 -0.010282 0.000000 + 0.021503 0.999654 0.015141 0.000000 + 0.009955 -0.015358 0.999833 0.000000 + + + + -0.463922 1.587691 1.470158 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 157 + 97 + 0 + 6 + -1 + -1 + 0 + 0.372702 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998833 0.012154 0.046733 0.000000 + -0.011597 0.999859 -0.012160 0.000000 + -0.046875 0.011604 0.998833 0.000000 + + + + -1.046819 0.502274 -0.762776 0.000000 + + + + + + 0.999969 -0.000079 -0.007920 0.000000 + 0.000040 0.999988 -0.004880 0.000000 + 0.007920 0.004880 0.999957 0.000000 + + + + 0.446679 0.584710 1.177444 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 129 + 49 + 0 + 6 + -1 + -1 + 0 + -0.040112 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999988 0.003329 0.003678 0.000000 + -0.003318 0.999990 -0.003002 0.000000 + -0.003688 0.002990 0.999989 0.000000 + + + + -0.267122 0.512280 -1.373376 0.000000 + + + + + + 0.999992 -0.003974 -0.000028 0.000000 + 0.003974 0.999840 0.017462 0.000000 + -0.000041 -0.017462 0.999848 0.000000 + + + + -1.354793 0.496778 0.870278 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 157 + 49 + 0 + 6 + -1 + -1 + 0 + -0.529262 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998833 0.012154 0.046733 0.000000 + -0.011597 0.999859 -0.012160 0.000000 + -0.046875 0.011604 0.998833 0.000000 + + + + 0.004832 1.287365 0.982306 0.000000 + + + + + + 0.999992 -0.003974 -0.000028 0.000000 + 0.003974 0.999840 0.017462 0.000000 + -0.000041 -0.017462 0.999848 0.000000 + + + + -0.500239 0.615772 -1.413696 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 33 + 67 + 0 + 6 + -1 + -1 + 0 + -0.405770 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999992 0.001099 0.003746 0.000000 + -0.001058 0.999940 -0.010940 0.000000 + -0.003758 0.010936 0.999933 0.000000 + + + + 0.776240 -0.720229 -0.808953 0.000000 + + + + + + 0.999968 -0.007428 0.003032 0.000000 + 0.007429 0.999972 -0.000233 0.000000 + -0.003030 0.000255 0.999995 0.000000 + + + + 0.724390 0.274628 -1.199862 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 77 + 171 + 0 + 6 + -1 + -1 + 0 + -0.039446 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999993 0.001110 -0.003564 0.000000 + -0.001103 0.999998 0.001799 0.000000 + 0.003566 -0.001795 0.999992 0.000000 + + + + -1.571034 -0.854730 0.213210 0.000000 + + + + + + 0.999741 0.022445 -0.003802 0.000000 + -0.022323 0.999317 0.029431 0.000000 + 0.004460 -0.029339 0.999560 0.000000 + + + + -0.088246 -1.404151 0.224946 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 37 + 39 + 0 + 6 + -1 + -1 + 0 + 0.133219 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999957 0.005323 -0.007536 0.000000 + -0.005220 0.999895 0.013512 0.000000 + 0.007608 -0.013472 0.999880 0.000000 + + + + -0.943738 0.880049 0.847125 0.000000 + + + + + + 0.999985 0.002943 -0.004713 0.000000 + -0.002973 0.999975 -0.006451 0.000000 + 0.004694 0.006465 0.999968 0.000000 + + + + 0.815253 0.861530 0.512363 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 39 + 105 + 0 + 6 + -1 + -1 + 0 + 0.110181 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999985 0.002943 -0.004713 0.000000 + -0.002973 0.999975 -0.006451 0.000000 + 0.004694 0.006465 0.999968 0.000000 + + + + 0.333353 1.013113 0.551395 0.000000 + + + + + + 0.998895 -0.045145 0.013071 0.000000 + 0.045290 0.998913 -0.011021 0.000000 + -0.012559 0.011601 0.999854 0.000000 + + + + 1.094530 0.664131 -0.482392 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 93 + 175 + 0 + 6 + -1 + -1 + 0 + -0.000073 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998314 -0.057878 -0.004438 0.000000 + 0.057971 0.998010 0.024815 0.000000 + 0.002993 -0.025030 0.999682 0.000000 + + + + -0.788371 -0.323563 -1.463284 0.000000 + + + + + + 0.999823 0.004551 0.018255 0.000000 + -0.004673 0.999967 0.006651 0.000000 + -0.018224 -0.006736 0.999811 0.000000 + + + + 0.096754 -1.048344 -0.026887 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 17 + 53 + 0 + 6 + -1 + -1 + 0 + -0.983829 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999956 -0.009421 -0.000064 0.000000 + 0.009419 0.999845 -0.014858 0.000000 + 0.000204 0.014857 0.999890 0.000000 + + + + 1.164370 0.400812 -1.268687 0.000000 + + + + + + 0.999926 -0.011592 -0.003692 0.000000 + 0.011537 0.999827 -0.014605 0.000000 + 0.003861 0.014562 0.999887 0.000000 + + + + -1.217212 0.862043 -1.742996 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 93 + 71 + 0 + 6 + -1 + -1 + 0 + 0.066129 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998314 -0.057878 -0.004438 0.000000 + 0.057971 0.998010 0.024815 0.000000 + 0.002993 -0.025030 0.999682 0.000000 + + + + -1.421421 -0.579937 0.842680 0.000000 + + + + + + 0.999921 -0.008590 0.009135 0.000000 + 0.008521 0.999935 0.007569 0.000000 + -0.009199 -0.007491 0.999930 0.000000 + + + + -0.122090 -1.353865 -1.745057 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 31 + 13 + 0 + 6 + -1 + -1 + 0 + 0.127278 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999982 -0.004243 -0.004327 0.000000 + 0.004340 0.999730 0.022847 0.000000 + 0.004229 -0.022865 0.999730 0.000000 + + + + 0.841270 -0.274391 0.756510 0.000000 + + + + + + 0.999657 0.003157 -0.025989 0.000000 + -0.002843 0.999923 0.012120 0.000000 + 0.026026 -0.012042 0.999589 0.000000 + + + + 0.868942 -0.966759 -0.005924 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 161 + 73 + 0 + 6 + -1 + -1 + 0 + 0.694567 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999818 0.012503 0.014420 0.000000 + -0.012626 0.999884 0.008474 0.000000 + -0.014312 -0.008655 0.999860 0.000000 + + + + 0.701325 -1.004728 1.100832 0.000000 + + + + + + 0.999970 0.004018 -0.006552 0.000000 + -0.003931 0.999903 0.013335 0.000000 + 0.006604 -0.013308 0.999890 0.000000 + + + + 0.920021 0.022569 -1.349704 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 37 + 107 + 0 + 6 + -1 + -1 + 0 + -0.674791 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999957 0.005323 -0.007536 0.000000 + -0.005220 0.999895 0.013512 0.000000 + 0.007608 -0.013472 0.999880 0.000000 + + + + 1.079500 0.698007 -0.583321 0.000000 + + + + + + 0.999884 0.015223 0.000784 0.000000 + -0.015215 0.999837 -0.009739 0.000000 + -0.000932 0.009726 0.999952 0.000000 + + + + -0.085087 1.541600 -0.589792 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 83 + 109 + 0 + 6 + -1 + -1 + 0 + -0.177075 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999894 -0.007480 -0.012518 0.000000 + 0.007294 0.999864 -0.014825 0.000000 + 0.012627 0.014732 0.999812 0.000000 + + + + 1.514431 -0.339333 0.950581 0.000000 + + + + + + 0.999902 -0.009403 0.010338 0.000000 + 0.009582 0.999802 -0.017435 0.000000 + -0.010172 0.017532 0.999795 0.000000 + + + + 1.274038 1.088178 0.885551 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 13 + 85 + 0 + 6 + -1 + -1 + 0 + -0.022617 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999657 0.003157 -0.025989 0.000000 + -0.002843 0.999923 0.012120 0.000000 + 0.026026 -0.012042 0.999589 0.000000 + + + + 0.758274 0.681199 0.001532 0.000000 + + + + + + 0.999888 0.006632 0.013414 0.000000 + -0.006699 0.999965 0.004927 0.000000 + -0.013381 -0.005016 0.999898 0.000000 + + + + -0.561571 0.153719 0.723050 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 87 + 173 + 0 + 6 + -1 + -1 + 0 + 2.378793 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999476 0.027828 0.016561 0.000000 + -0.027985 0.999565 0.009327 0.000000 + -0.016294 -0.009786 0.999819 0.000000 + + + + 0.863280 0.062484 0.354611 0.000000 + + + + + + 0.999996 0.000418 0.002760 0.000000 + -0.000419 1.000000 0.000416 0.000000 + -0.002759 -0.000417 0.999996 0.000000 + + + + 0.287416 -0.510340 -0.172879 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 107 + 29 + 0 + 6 + -1 + -1 + 0 + -1.595709 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999884 0.015223 0.000784 0.000000 + -0.015215 0.999837 -0.009739 0.000000 + -0.000932 0.009726 0.999952 0.000000 + + + + 0.865269 -0.229341 0.735999 0.000000 + + + + + + 0.999345 0.016246 -0.032349 0.000000 + -0.014821 0.998930 0.043805 0.000000 + 0.033026 -0.043296 0.998516 0.000000 + + + + -0.230945 -1.048352 0.097483 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 161 + 27 + 0 + 6 + -1 + -1 + 0 + -0.042971 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999818 0.012503 0.014420 0.000000 + -0.012626 0.999884 0.008474 0.000000 + -0.014312 -0.008655 0.999860 0.000000 + + + + 0.355256 1.050246 -0.689039 0.000000 + + + + + + 0.999897 -0.010279 -0.009988 0.000000 + 0.010249 0.999943 -0.003062 0.000000 + 0.010019 0.002959 0.999945 0.000000 + + + + 1.076603 0.660442 0.025604 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 5 + 123 + 0 + 6 + -1 + -1 + 0 + -0.710271 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999727 -0.023384 0.000179 0.000000 + 0.023372 0.999418 0.024833 0.000000 + -0.000759 -0.024822 0.999692 0.000000 + + + + 0.476363 0.152431 0.833646 0.000000 + + + + + + 0.999976 -0.005905 -0.003552 0.000000 + 0.005839 0.999812 -0.018503 0.000000 + 0.003660 0.018482 0.999822 0.000000 + + + + 0.013903 -0.944748 0.405447 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 159 + 11 + 0 + 6 + -1 + -1 + 0 + -0.023756 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999852 0.017109 -0.001503 0.000000 + -0.017113 0.999849 -0.002862 0.000000 + 0.001454 0.002887 0.999995 0.000000 + + + + 0.969475 -1.028847 0.855172 0.000000 + + + + + + 0.999930 -0.002280 -0.011649 0.000000 + 0.002508 0.999804 0.019636 0.000000 + 0.011602 -0.019664 0.999739 0.000000 + + + + -0.060030 -1.163552 -0.458388 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 113 + 135 + 0 + 6 + -1 + -1 + 0 + -0.120716 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999988 -0.003752 -0.003019 0.000000 + 0.003725 0.999954 -0.008833 0.000000 + 0.003052 0.008821 0.999956 0.000000 + + + + -1.697575 -0.423645 -0.324618 0.000000 + + + + + + 0.999911 0.001812 0.013243 0.000000 + -0.002034 0.999856 0.016827 0.000000 + -0.013211 -0.016852 0.999771 0.000000 + + + + -0.363410 -0.901576 -0.914864 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 165 + 17 + 0 + 6 + -1 + -1 + 0 + -1.021723 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999231 0.039200 0.000453 0.000000 + -0.039129 0.997981 -0.050031 0.000000 + -0.002414 0.049974 0.998748 0.000000 + + + + 1.113746 -1.206181 0.514244 0.000000 + + + + + + 0.999956 -0.009421 -0.000064 0.000000 + 0.009419 0.999845 -0.014858 0.000000 + 0.000204 0.014857 0.999890 0.000000 + + + + 0.448129 -1.464164 -0.238204 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 35 + 161 + 0 + 6 + -1 + -1 + 0 + 0.346120 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999986 0.005243 -0.000475 0.000000 + -0.005242 0.999985 0.001281 0.000000 + 0.000482 -0.001278 0.999999 0.000000 + + + + 0.287570 0.799899 -1.552757 0.000000 + + + + + + 0.999818 0.012503 0.014420 0.000000 + -0.012626 0.999884 0.008474 0.000000 + -0.014312 -0.008655 0.999860 0.000000 + + + + -0.426237 0.974539 0.829051 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 113 + 41 + 0 + 6 + -1 + -1 + 0 + -0.025021 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999988 -0.003752 -0.003019 0.000000 + 0.003725 0.999954 -0.008833 0.000000 + 0.003052 0.008821 0.999956 0.000000 + + + + -1.775705 -0.220237 -1.017524 0.000000 + + + + + + 0.998616 0.050560 -0.014507 0.000000 + -0.051100 0.997906 -0.039648 0.000000 + 0.012472 0.040334 0.999108 0.000000 + + + + 0.691801 -0.960003 -1.132915 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 153 + 91 + 0 + 6 + -1 + -1 + 0 + 0.063031 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999672 0.015495 -0.020412 0.000000 + -0.015170 0.999757 0.015980 0.000000 + 0.020654 -0.015665 0.999664 0.000000 + + + + -0.983500 0.299771 0.718049 0.000000 + + + + + + 0.999900 -0.011554 0.008154 0.000000 + 0.011351 0.999634 0.024572 0.000000 + -0.008435 -0.024477 0.999665 0.000000 + + + + 0.189642 1.154552 0.176793 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 93 + 147 + 0 + 6 + -1 + -1 + 0 + -0.407922 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998314 -0.057878 -0.004438 0.000000 + 0.057971 0.998010 0.024815 0.000000 + 0.002993 -0.025030 0.999682 0.000000 + + + + -1.397458 -0.462519 0.122354 0.000000 + + + + + + 0.999997 0.002275 -0.001059 0.000000 + -0.002266 0.999955 0.009164 0.000000 + 0.001080 -0.009161 0.999957 0.000000 + + + + 0.172993 -1.474296 -0.434893 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 49 + 75 + 0 + 6 + -1 + -1 + 0 + -0.574933 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999999 -0.000094 -0.001220 0.000000 + 0.000109 0.999924 0.012312 0.000000 + 0.001218 -0.012312 0.999923 0.000000 + + + + 0.232985 0.893101 1.614673 0.000000 + + + + + + 0.999944 -0.010230 -0.002669 0.000000 + 0.010246 0.999929 0.006130 0.000000 + 0.002606 -0.006157 0.999978 0.000000 + + + + -0.133558 1.251653 -0.202133 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 125 + 19 + 0 + 6 + -1 + -1 + 0 + 1.652194 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999702 0.024139 0.003589 0.000000 + -0.024185 0.999619 0.013316 0.000000 + -0.003267 -0.013399 0.999905 0.000000 + + + + -1.204425 -0.262825 -0.500958 0.000000 + + + + + + 0.999923 -0.009091 0.008416 0.000000 + 0.009090 0.999959 0.000161 0.000000 + -0.008417 -0.000085 0.999965 0.000000 + + + + -0.623731 -1.391303 0.174927 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 19 + 9 + 0 + 6 + -1 + -1 + 0 + 1.308758 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999923 -0.009091 0.008416 0.000000 + 0.009090 0.999959 0.000161 0.000000 + -0.008417 -0.000085 0.999965 0.000000 + + + + 0.299810 1.438023 0.926680 0.000000 + + + + + + 0.999776 0.021146 -0.000676 0.000000 + -0.021141 0.999752 0.007014 0.000000 + 0.000824 -0.006998 0.999975 0.000000 + + + + -0.387944 0.705266 -1.009258 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 119 + 149 + 0 + 6 + -1 + -1 + 0 + 0.972415 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999769 0.020538 0.006346 0.000000 + -0.020586 0.999759 0.007559 0.000000 + -0.006190 -0.007688 0.999951 0.000000 + + + + -0.611347 0.190139 -0.383555 0.000000 + + + + + + 0.999910 -0.013206 -0.002402 0.000000 + 0.013185 0.999878 -0.008398 0.000000 + 0.002513 0.008366 0.999962 0.000000 + + + + -0.057306 0.031083 1.238600 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 79 + 143 + 0 + 6 + -1 + -1 + 0 + -0.160719 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999861 -0.016105 0.004259 0.000000 + 0.016099 0.999869 0.001505 0.000000 + -0.004283 -0.001436 0.999990 0.000000 + + + + -0.351740 -0.952579 -0.281047 0.000000 + + + + + + 0.999914 0.011723 0.005899 0.000000 + -0.011515 0.999351 -0.034132 0.000000 + -0.006295 0.034061 0.999400 0.000000 + + + + -1.261499 -0.180052 0.495457 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 141 + 59 + 0 + 6 + -1 + -1 + 0 + 0.000048 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.995579 0.093802 -0.004761 0.000000 + -0.093633 0.995210 0.028099 0.000000 + 0.007374 -0.027529 0.999594 0.000000 + + + + 0.951686 0.465828 0.364875 0.000000 + + + + + + 0.999769 0.003920 -0.021119 0.000000 + -0.004650 0.999389 -0.034648 0.000000 + 0.020970 0.034738 0.999176 0.000000 + + + + 0.747476 -0.923579 0.149383 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 95 + 21 + 0 + 6 + -1 + -1 + 0 + -0.014669 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999451 0.028966 -0.016092 0.000000 + -0.029936 0.997518 -0.063731 0.000000 + 0.014206 0.064178 0.997837 0.000000 + + + + -0.698994 0.602673 0.670300 0.000000 + + + + + + 0.999314 -0.028105 0.024099 0.000000 + 0.027876 0.999564 0.009760 0.000000 + -0.024363 -0.009082 0.999662 0.000000 + + + + -0.649031 -0.558438 0.649866 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 81 + 7 + 0 + 6 + -1 + -1 + 0 + -0.500172 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999441 0.030294 0.014130 0.000000 + -0.029616 0.998506 -0.045917 0.000000 + -0.015500 0.045473 0.998845 0.000000 + + + + -0.478968 0.925546 -0.117188 0.000000 + + + + + + 0.999725 -0.007598 -0.022193 0.000000 + 0.007220 0.999828 -0.017060 0.000000 + 0.022319 0.016895 0.999608 0.000000 + + + + -0.897503 0.576177 0.114841 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 65 + 63 + 0 + 6 + -1 + -1 + 0 + 0.010938 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999995 -0.003125 -0.001068 0.000000 + 0.003105 0.999820 -0.018705 0.000000 + 0.001127 0.018702 0.999824 0.000000 + + + + -0.981236 0.433616 0.665279 0.000000 + + + + + + 0.999617 -0.019834 0.019313 0.000000 + 0.020387 0.999376 -0.028843 0.000000 + -0.018729 0.029226 0.999397 0.000000 + + + + -0.602147 -0.357662 0.682560 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 169 + 21 + 0 + 6 + -1 + -1 + 0 + 0.016487 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999349 0.016561 0.032043 0.000000 + -0.017674 0.999239 0.034771 0.000000 + -0.031443 -0.035315 0.998881 0.000000 + + + + -0.818487 -0.229377 0.087430 0.000000 + + + + + + 0.999314 -0.028105 0.024099 0.000000 + 0.027876 0.999564 0.009760 0.000000 + -0.024363 -0.009082 0.999662 0.000000 + + + + -0.458102 -0.339242 0.667569 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 145 + 69 + 0 + 6 + -1 + -1 + 0 + 1.610953 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999934 0.009728 0.006086 0.000000 + -0.009444 0.998941 -0.045029 0.000000 + -0.006518 0.044969 0.998967 0.000000 + + + + 0.353925 1.134289 -0.751691 0.000000 + + + + + + 0.999957 -0.000818 -0.009275 0.000000 + 0.000464 0.999274 -0.038108 0.000000 + 0.009299 0.038102 0.999231 0.000000 + + + + -1.136587 0.686161 0.199615 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 111 + 113 + 0 + 6 + -1 + -1 + 0 + -0.035771 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999881 -0.010253 0.011513 0.000000 + 0.010100 0.999861 0.013299 0.000000 + -0.011648 -0.013181 0.999845 0.000000 + + + + 0.638979 -0.155035 -1.375884 0.000000 + + + + + + 0.999995 -0.000321 -0.003271 0.000000 + 0.000286 0.999942 -0.010812 0.000000 + 0.003275 0.010811 0.999936 0.000000 + + + + -1.866807 -1.210397 -0.408328 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 115 + 133 + 0 + 6 + -1 + -1 + 0 + 1.096859 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999883 0.002853 0.015028 0.000000 + -0.003137 0.999816 0.018933 0.000000 + -0.014971 -0.018977 0.999708 0.000000 + + + + 0.412565 0.015143 -1.515353 0.000000 + + + + + + 0.999718 -0.001123 0.023733 0.000000 + 0.000721 0.999856 0.016954 0.000000 + -0.023748 -0.016932 0.999575 0.000000 + + + + 1.236128 -0.644280 -0.454261 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 153 + 11 + 0 + 6 + -1 + -1 + 0 + 0.139258 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999539 0.021759 -0.021153 0.000000 + -0.021494 0.999688 0.012695 0.000000 + 0.021422 -0.012235 0.999696 0.000000 + + + + -0.664246 -1.042966 0.120270 0.000000 + + + + + + 0.999916 0.003976 -0.012336 0.000000 + -0.003774 0.999860 0.016315 0.000000 + 0.012399 -0.016267 0.999791 0.000000 + + + + -1.032116 0.131022 -0.505006 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 135 + 77 + 0 + 6 + -1 + -1 + 0 + 0.075870 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999902 0.005280 0.012980 0.000000 + -0.005472 0.999875 0.014850 0.000000 + -0.012900 -0.014920 0.999805 0.000000 + + + + 1.180767 0.484837 0.495352 0.000000 + + + + + + 0.999982 0.004582 -0.003781 0.000000 + -0.004583 0.999990 -0.000191 0.000000 + 0.003780 0.000209 0.999993 0.000000 + + + + -0.194403 1.332391 -0.684163 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 111 + 67 + 0 + 6 + -1 + -1 + 0 + 0.023904 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999881 -0.010253 0.011513 0.000000 + 0.010100 0.999861 0.013299 0.000000 + -0.011648 -0.013181 0.999845 0.000000 + + + + -0.676625 -0.597386 -0.791770 0.000000 + + + + + + 0.999994 -0.001683 0.003030 0.000000 + 0.001713 0.999950 -0.009815 0.000000 + -0.003013 0.009820 0.999947 0.000000 + + + + 0.224800 -1.058920 0.495595 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 111 + 65 + 0 + 6 + -1 + -1 + 0 + 0.047915 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999881 -0.010253 0.011513 0.000000 + 0.010100 0.999861 0.013299 0.000000 + -0.011648 -0.013181 0.999845 0.000000 + + + + 0.534215 0.354962 -1.213605 0.000000 + + + + + + 0.999995 -0.003125 -0.001068 0.000000 + 0.003105 0.999820 -0.018705 0.000000 + 0.001127 0.018702 0.999824 0.000000 + + + + 0.956890 -0.469586 -1.271772 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 101 + 133 + 0 + 6 + -1 + -1 + 0 + -1.106969 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999288 -0.033392 0.017579 0.000000 + 0.033431 0.999439 -0.001954 0.000000 + -0.017504 0.002540 0.999844 0.000000 + + + + 0.498038 1.302521 -1.614984 0.000000 + + + + + + 0.999718 -0.001123 0.023733 0.000000 + 0.000721 0.999856 0.016954 0.000000 + -0.023748 -0.016932 0.999575 0.000000 + + + + -0.148963 0.081156 -1.856099 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 41 + 33 + 0 + 6 + -1 + -1 + 0 + -0.024351 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998429 0.054042 -0.014813 0.000000 + -0.054616 0.997641 -0.041583 0.000000 + 0.012531 0.042327 0.999025 0.000000 + + + + -0.602355 0.436298 -0.680222 0.000000 + + + + + + 0.999970 0.006829 0.003744 0.000000 + -0.006751 0.999767 -0.020524 0.000000 + -0.003883 0.020498 0.999782 0.000000 + + + + 0.336238 0.709238 0.159118 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 101 + 97 + 0 + 6 + -1 + -1 + 0 + -0.394603 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999288 -0.033392 0.017579 0.000000 + 0.033431 0.999439 -0.001954 0.000000 + -0.017504 0.002540 0.999844 0.000000 + + + + -0.910687 -0.564842 1.090239 0.000000 + + + + + + 0.999930 0.006370 -0.009993 0.000000 + -0.006493 0.999903 -0.012329 0.000000 + 0.009913 0.012393 0.999874 0.000000 + + + + 0.108746 -1.031685 -0.056167 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 151 + 137 + 0 + 6 + -1 + -1 + 0 + -0.000108 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999611 -0.006978 -0.027020 0.000000 + 0.006593 0.999876 -0.014328 0.000000 + 0.027117 0.014144 0.999532 0.000000 + + + + -1.467359 -0.847947 1.149774 0.000000 + + + + + + 0.999826 0.000774 -0.018626 0.000000 + -0.000697 0.999991 0.004161 0.000000 + 0.018629 -0.004147 0.999818 0.000000 + + + + -0.116462 -1.526084 -1.554153 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 73 + 125 + 0 + 6 + -1 + -1 + 0 + -0.640455 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999968 0.005839 -0.005517 0.000000 + -0.005731 0.999796 0.019373 0.000000 + 0.005629 -0.019340 0.999797 0.000000 + + + + 0.076073 -0.909683 1.153965 0.000000 + + + + + + 0.999702 0.024139 0.003589 0.000000 + -0.024185 0.999619 0.013316 0.000000 + -0.003267 -0.013399 0.999905 0.000000 + + + + 0.861644 -0.503119 -1.258545 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 15 + 127 + 0 + 6 + -1 + -1 + 0 + 0.003999 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998236 -0.059059 -0.006014 0.000000 + 0.059061 0.998254 0.000125 0.000000 + 0.005996 -0.000480 0.999982 0.000000 + + + + -0.350008 0.268479 1.228509 0.000000 + + + + + + 0.999957 -0.007775 -0.005052 0.000000 + 0.007807 0.999950 0.006300 0.000000 + 0.005003 -0.006339 0.999967 0.000000 + + + + -0.691931 -1.031878 1.125067 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 87 + 73 + 0 + 6 + -1 + -1 + 0 + -0.410369 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999411 0.029728 0.017152 0.000000 + -0.029961 0.999460 0.013502 0.000000 + -0.016741 -0.014008 0.999762 0.000000 + + + + -0.498200 0.618621 -1.134893 0.000000 + + + + + + 0.999968 0.005839 -0.005517 0.000000 + -0.005731 0.999796 0.019373 0.000000 + 0.005629 -0.019340 0.999797 0.000000 + + + + 0.053165 1.219834 1.288397 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 25 + 111 + 0 + 6 + -1 + -1 + 0 + 0.036186 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998354 0.056381 -0.010478 0.000000 + -0.055721 0.996921 0.055171 0.000000 + 0.013556 -0.054496 0.998422 0.000000 + + + + 0.918613 -0.963300 -0.545922 0.000000 + + + + + + 0.999881 -0.010253 0.011513 0.000000 + 0.010100 0.999861 0.013299 0.000000 + -0.011648 -0.013181 0.999845 0.000000 + + + + -0.760561 -0.550512 -0.427465 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 105 + 169 + 0 + 6 + -1 + -1 + 0 + 0.246104 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999169 -0.038782 0.012527 0.000000 + 0.038961 0.999138 -0.014362 0.000000 + -0.011959 0.014838 0.999818 0.000000 + + + + 0.652899 -0.348363 0.603762 0.000000 + + + + + + 0.999349 0.016561 0.032043 0.000000 + -0.017674 0.999239 0.034771 0.000000 + -0.031443 -0.035315 0.998881 0.000000 + + + + 0.861060 0.648370 -0.158040 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 71 + 19 + 0 + 6 + -1 + -1 + 0 + -0.342478 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999911 -0.006889 0.011396 0.000000 + 0.006776 0.999928 0.009948 0.000000 + -0.011463 -0.009870 0.999886 0.000000 + + + + -0.431657 1.608635 0.186081 0.000000 + + + + + + 0.999923 -0.009091 0.008416 0.000000 + 0.009090 0.999959 0.000161 0.000000 + -0.008417 -0.000085 0.999965 0.000000 + + + + -0.646625 1.282563 -1.411759 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 135 + 65 + 0 + 6 + -1 + -1 + 0 + -0.166824 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999902 0.005280 0.012980 0.000000 + -0.005472 0.999875 0.014850 0.000000 + -0.012900 -0.014920 0.999805 0.000000 + + + + -0.560084 -0.953440 0.200688 0.000000 + + + + + + 0.999995 -0.003125 -0.001068 0.000000 + 0.003105 0.999820 -0.018705 0.000000 + 0.001127 0.018702 0.999824 0.000000 + + + + 1.015613 -0.279369 -0.249187 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 173 + 61 + 0 + 6 + -1 + -1 + 0 + 2.371180 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999992 0.002393 0.003226 0.000000 + -0.002408 0.999986 0.004625 0.000000 + -0.003215 -0.004633 0.999984 0.000000 + + + + 0.417097 -0.665503 0.015037 0.000000 + + + + + + 0.999937 0.010877 -0.002591 0.000000 + -0.010890 0.999928 -0.005063 0.000000 + 0.002535 0.005091 0.999984 0.000000 + + + + 0.424694 0.839560 0.025363 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 5 + 169 + 0 + 6 + -1 + -1 + 0 + -0.226500 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999762 -0.021698 0.002428 0.000000 + 0.021622 0.999380 0.027802 0.000000 + -0.003030 -0.027743 0.999610 0.000000 + + + + -0.752462 0.404144 -0.218184 0.000000 + + + + + + 0.999349 0.016561 0.032043 0.000000 + -0.017674 0.999239 0.034771 0.000000 + -0.031443 -0.035315 0.998881 0.000000 + + + + 0.557696 -0.728009 -0.359226 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 5 + 81 + 0 + 6 + -1 + -1 + 0 + -0.743296 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999762 -0.021698 0.002428 0.000000 + 0.021622 0.999380 0.027802 0.000000 + -0.003030 -0.027743 0.999610 0.000000 + + + + -0.306596 -0.179920 -1.347529 0.000000 + + + + + + 0.999441 0.030294 0.014130 0.000000 + -0.029616 0.998506 -0.045917 0.000000 + -0.015500 0.045473 0.998845 0.000000 + + + + 0.827304 -0.765847 -0.336876 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 91 + 123 + 0 + 6 + -1 + -1 + 0 + 1.714060 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999958 -0.005185 0.007504 0.000000 + 0.005025 0.999761 0.021277 0.000000 + -0.007613 -0.021238 0.999745 0.000000 + + + + 0.177877 1.136742 0.360921 0.000000 + + + + + + 0.999990 -0.004234 -0.001164 0.000000 + 0.004202 0.999636 -0.026654 0.000000 + 0.001276 0.026649 0.999644 0.000000 + + + + -0.032812 1.009118 -0.666950 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 13 + 93 + 0 + 6 + -1 + -1 + 0 + 0.000474 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999677 0.005076 -0.024895 0.000000 + -0.004682 0.999863 0.015851 0.000000 + 0.024972 -0.015729 0.999564 0.000000 + + + + -0.880761 -0.066487 -0.499819 0.000000 + + + + + + 0.998425 -0.056040 -0.002472 0.000000 + 0.056087 0.998042 0.027673 0.000000 + 0.000916 -0.027768 0.999614 0.000000 + + + + -0.257100 0.799081 -0.771685 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 123 + 85 + 0 + 6 + -1 + -1 + 0 + -0.834739 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999990 -0.004234 -0.001164 0.000000 + 0.004202 0.999636 -0.026654 0.000000 + 0.001276 0.026649 0.999644 0.000000 + + + + 0.533919 0.370623 0.493564 0.000000 + + + + + + 0.999851 0.008368 0.015124 0.000000 + -0.008493 0.999930 0.008240 0.000000 + -0.015054 -0.008368 0.999852 0.000000 + + + + 1.025450 -0.185496 -0.223309 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 85 + 31 + 0 + 6 + -1 + -1 + 0 + 0.137636 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999851 0.008368 0.015124 0.000000 + -0.008493 0.999930 0.008240 0.000000 + -0.015054 -0.008368 0.999852 0.000000 + + + + -0.431496 -0.772591 0.153700 0.000000 + + + + + + 0.999995 -0.002508 -0.002061 0.000000 + 0.002560 0.999667 0.025681 0.000000 + 0.001996 -0.025686 0.999668 0.000000 + + + + 0.869588 0.437810 0.198101 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 35 + 73 + 0 + 6 + -1 + -1 + 0 + -0.903984 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999975 0.007121 0.000055 0.000000 + -0.007121 0.999960 0.005419 0.000000 + -0.000017 -0.005419 0.999985 0.000000 + + + + -0.259993 -0.770097 -1.092074 0.000000 + + + + + + 0.999968 0.005839 -0.005517 0.000000 + -0.005731 0.999796 0.019373 0.000000 + 0.005629 -0.019340 0.999797 0.000000 + + + + -0.775571 0.444842 -1.179768 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 91 + 5 + 0 + 6 + -1 + -1 + 0 + -1.642532 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999958 -0.005185 0.007504 0.000000 + 0.005025 0.999761 0.021277 0.000000 + -0.007613 -0.021238 0.999745 0.000000 + + + + -0.295292 -0.989206 -0.495621 0.000000 + + + + + + 0.999762 -0.021698 0.002428 0.000000 + 0.021622 0.999380 0.027802 0.000000 + -0.003030 -0.027743 0.999610 0.000000 + + + + -0.041721 -0.095044 -1.188069 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 171 + 65 + 0 + 6 + -1 + -1 + 0 + -0.039558 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999656 0.025923 -0.004058 0.000000 + -0.025802 0.999291 0.027434 0.000000 + 0.004767 -0.027320 0.999615 0.000000 + + + + -1.044801 -0.411434 0.531493 0.000000 + + + + + + 0.999995 -0.003125 -0.001068 0.000000 + 0.003105 0.999820 -0.018705 0.000000 + 0.001127 0.018702 0.999824 0.000000 + + + + 0.398721 -0.102370 1.332800 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 27 + 55 + 0 + 6 + -1 + -1 + 0 + -0.042197 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999927 -0.007291 -0.009620 0.000000 + 0.007299 0.999973 0.000787 0.000000 + 0.009614 -0.000857 0.999953 0.000000 + + + + 0.848515 0.635854 -0.521518 0.000000 + + + + + + 0.999287 0.033006 -0.018307 0.000000 + -0.033254 0.999357 -0.013383 0.000000 + 0.017854 0.013982 0.999743 0.000000 + + + + -0.949702 0.501865 0.654394 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 139 + 47 + 0 + 6 + -1 + -1 + 0 + 0.088238 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999603 -0.012740 -0.025112 0.000000 + 0.011063 0.997769 -0.065836 0.000000 + 0.025895 0.065532 0.997514 0.000000 + + + + -0.974469 0.315338 -0.860540 0.000000 + + + + + + 0.999510 0.018154 -0.025483 0.000000 + -0.017908 0.999791 0.009873 0.000000 + 0.025657 -0.009412 0.999627 0.000000 + + + + 1.002713 -0.209325 -0.311700 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 133 + 157 + 0 + 6 + -1 + -1 + 0 + 0.003812 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999726 0.000607 0.023384 0.000000 + -0.000968 0.999880 0.015435 0.000000 + -0.023372 -0.015454 0.999607 0.000000 + + + + -0.692457 0.741643 1.716321 0.000000 + + + + + + 0.998795 0.020783 0.044467 0.000000 + -0.019886 0.999591 -0.020539 0.000000 + -0.044875 0.019630 0.998800 0.000000 + + + + -0.496974 1.280787 -1.096491 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 123 + 145 + 0 + 6 + -1 + -1 + 0 + 1.290125 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999994 -0.002886 -0.001801 0.000000 + 0.002836 0.999622 -0.027332 0.000000 + 0.001879 0.027327 0.999625 0.000000 + + + + 0.643378 0.381964 0.456922 0.000000 + + + + + + 0.999939 0.010625 -0.003000 0.000000 + -0.010740 0.999091 -0.041248 0.000000 + 0.002559 0.041278 0.999144 0.000000 + + + + -0.657001 -0.138330 0.833549 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 173 + 47 + 0 + 6 + -1 + -1 + 0 + -0.022925 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999989 0.003857 0.002800 0.000000 + -0.003870 0.999982 0.004549 0.000000 + -0.002782 -0.004560 0.999986 0.000000 + + + + -0.506900 0.861696 0.806145 0.000000 + + + + + + 0.999510 0.018154 -0.025483 0.000000 + -0.017908 0.999791 0.009873 0.000000 + 0.025657 -0.009412 0.999627 0.000000 + + + + -0.602095 0.309121 -0.757164 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 63 + 45 + 0 + 6 + -1 + -1 + 0 + -0.018773 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999652 -0.018125 0.019165 0.000000 + 0.018687 0.999389 -0.029527 0.000000 + -0.018618 0.029875 0.999380 0.000000 + + + + -1.053370 -0.135942 0.423892 0.000000 + + + + + + 0.999679 -0.025107 -0.003287 0.000000 + 0.025070 0.999628 -0.010782 0.000000 + 0.003556 0.010696 0.999936 0.000000 + + + + -0.004460 -0.411844 0.798038 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 67 + 45 + 0 + 6 + -1 + -1 + 0 + 0.018657 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999996 0.000089 0.002806 0.000000 + -0.000060 0.999947 -0.010302 0.000000 + -0.002806 0.010302 0.999943 0.000000 + + + + -1.035719 0.934667 0.515754 0.000000 + + + + + + 0.999679 -0.025107 -0.003287 0.000000 + 0.025070 0.999628 -0.010782 0.000000 + 0.003556 0.010696 0.999936 0.000000 + + + + -0.104925 -0.520005 -0.459737 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 173 + 33 + 0 + 6 + -1 + -1 + 0 + 0.000680 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999989 0.003857 0.002800 0.000000 + -0.003870 0.999982 0.004549 0.000000 + -0.002782 -0.004560 0.999986 0.000000 + + + + 1.042834 0.183749 1.036114 0.000000 + + + + + + 0.999956 0.008606 0.003609 0.000000 + -0.008528 0.999742 -0.021062 0.000000 + -0.003789 0.021030 0.999772 0.000000 + + + + 0.590740 0.581877 -0.678716 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 53 + 149 + 0 + 6 + -1 + -1 + 0 + -0.976079 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999978 -0.003666 -0.005578 0.000000 + 0.003549 0.999775 -0.020924 0.000000 + 0.005654 0.020904 0.999766 0.000000 + + + + 1.426453 1.328977 0.330063 0.000000 + + + + + + 0.999926 -0.011917 -0.002602 0.000000 + 0.011892 0.999886 -0.009354 0.000000 + 0.002714 0.009322 0.999953 0.000000 + + + + 1.803313 0.040098 -0.091152 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 155 + 99 + 0 + 6 + -1 + -1 + 0 + 0.138542 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999480 0.016230 0.027865 0.000000 + -0.015115 0.999095 -0.039754 0.000000 + -0.028485 0.039312 0.998821 0.000000 + + + + 1.653289 -0.494682 0.618810 0.000000 + + + + + + 0.999848 -0.012318 -0.012339 0.000000 + 0.012378 0.999912 0.004782 0.000000 + 0.012279 -0.004934 0.999912 0.000000 + + + + 1.310703 -0.621363 -0.984140 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 33 + 47 + 0 + 6 + -1 + -1 + 0 + -0.065432 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999956 0.008606 0.003609 0.000000 + -0.008528 0.999742 -0.021062 0.000000 + -0.003789 0.021030 0.999772 0.000000 + + + + -0.725962 0.755379 0.359052 0.000000 + + + + + + 0.999510 0.018154 -0.025483 0.000000 + -0.017908 0.999791 0.009873 0.000000 + 0.025657 -0.009412 0.999627 0.000000 + + + + -0.413559 -0.171502 0.513204 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 113 + 139 + 0 + 6 + -1 + -1 + 0 + 0.224433 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999994 0.001269 -0.003301 0.000000 + -0.001308 0.999932 -0.011618 0.000000 + 0.003286 0.011622 0.999927 0.000000 + + + + -1.508416 0.093455 -0.933949 0.000000 + + + + + + 0.999603 -0.012740 -0.025112 0.000000 + 0.011063 0.997769 -0.065836 0.000000 + 0.025895 0.065532 0.997514 0.000000 + + + + 0.330823 -0.752074 -0.564528 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 87 + 125 + 0 + 6 + -1 + -1 + 0 + 1.796692 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999392 0.030344 0.017156 0.000000 + -0.030577 0.999442 0.013467 0.000000 + -0.016738 -0.013984 0.999762 0.000000 + + + + -0.216676 -1.226292 -1.074611 0.000000 + + + + + + 0.999674 0.025470 0.001886 0.000000 + -0.025480 0.999662 0.005088 0.000000 + -0.001755 -0.005134 0.999985 0.000000 + + + + 1.171028 -0.221550 -1.044196 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 137 + 15 + 0 + 6 + -1 + -1 + 0 + 0.004222 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999817 0.002760 -0.018943 0.000000 + -0.002700 0.999991 0.003190 0.000000 + 0.018952 -0.003139 0.999815 0.000000 + + + + 0.286095 -1.551816 -1.191771 0.000000 + + + + + + 0.998349 -0.057092 -0.006238 0.000000 + 0.057088 0.998369 -0.000868 0.000000 + 0.006278 0.000511 0.999980 0.000000 + + + + -1.387041 -0.650972 0.238991 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 25 + 67 + 0 + 6 + -1 + -1 + 0 + -0.036246 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998257 0.058057 -0.010605 0.000000 + -0.057397 0.996860 0.054544 0.000000 + 0.013738 -0.053841 0.998455 0.000000 + + + + 0.854138 -1.017775 -0.823246 0.000000 + + + + + + 0.999996 0.000089 0.002806 0.000000 + -0.000060 0.999947 -0.010302 0.000000 + -0.002806 0.010302 0.999943 0.000000 + + + + 0.072217 -1.059843 0.581106 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 59 + 125 + 0 + 6 + -1 + -1 + 0 + 0.459085 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999340 0.031378 -0.018317 0.000000 + -0.031738 0.999302 -0.019702 0.000000 + 0.017686 0.020270 0.999638 0.000000 + + + + 1.010491 -0.503666 -0.328882 0.000000 + + + + + + 0.999674 0.025470 0.001886 0.000000 + -0.025480 0.999662 0.005088 0.000000 + -0.001755 -0.005134 0.999985 0.000000 + + + + 0.472327 0.521937 0.923435 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 67 + 143 + 0 + 6 + -1 + -1 + 0 + 0.414236 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999996 0.000089 0.002806 0.000000 + -0.000060 0.999947 -0.010302 0.000000 + -0.002806 0.010302 0.999943 0.000000 + + + + -0.441509 -1.028411 -0.056791 0.000000 + + + + + + 0.999816 0.008327 0.017292 0.000000 + -0.008141 0.999908 -0.010816 0.000000 + -0.017381 0.010673 0.999792 0.000000 + + + + 0.507258 -0.486087 0.869517 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 59 + 121 + 0 + 6 + -1 + -1 + 0 + -0.458958 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999340 0.031378 -0.018317 0.000000 + -0.031738 0.999302 -0.019702 0.000000 + 0.017686 0.020270 0.999638 0.000000 + + + + -0.068167 -0.817373 1.016800 0.000000 + + + + + + 0.999998 -0.000484 -0.002106 0.000000 + 0.000489 0.999997 0.002340 0.000000 + 0.002104 -0.002341 0.999995 0.000000 + + + + -0.035808 -0.840368 0.291712 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 153 + 55 + 0 + 6 + -1 + -1 + 0 + 0.604775 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999485 0.023126 -0.022233 0.000000 + -0.022914 0.999690 0.009765 0.000000 + 0.022451 -0.009250 0.999705 0.000000 + + + + -0.784411 1.066980 0.390953 0.000000 + + + + + + 0.999287 0.033006 -0.018307 0.000000 + -0.033254 0.999357 -0.013383 0.000000 + 0.017854 0.013982 0.999743 0.000000 + + + + 1.213310 0.500232 -1.009990 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 23 + 137 + 0 + 6 + -1 + -1 + 0 + 0.039629 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999869 0.016193 0.000128 0.000000 + -0.016183 0.999448 -0.029020 0.000000 + -0.000598 0.029015 0.999579 0.000000 + + + + 0.634799 -1.533541 -1.499307 0.000000 + + + + + + 0.999817 0.002760 -0.018943 0.000000 + -0.002700 0.999991 0.003190 0.000000 + 0.018952 -0.003139 0.999815 0.000000 + + + + -0.543082 -1.440917 -1.526497 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 85 + 55 + 0 + 6 + -1 + -1 + 0 + -0.996048 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999847 0.009780 0.014486 0.000000 + -0.009888 0.999924 0.007382 0.000000 + -0.014413 -0.007524 0.999868 0.000000 + + + + -0.798323 0.967909 0.349607 0.000000 + + + + + + 0.999287 0.033006 -0.018307 0.000000 + -0.033254 0.999357 -0.013383 0.000000 + 0.017854 0.013982 0.999743 0.000000 + + + + -0.299313 0.245975 1.199606 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 105 + 55 + 0 + 6 + -1 + -1 + 0 + -0.128150 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999235 -0.037225 0.012002 0.000000 + 0.037422 0.999160 -0.016677 0.000000 + -0.011371 0.017113 0.999789 0.000000 + + + + -0.691672 0.405592 0.723570 0.000000 + + + + + + 0.999287 0.033006 -0.018307 0.000000 + -0.033254 0.999357 -0.013383 0.000000 + 0.017854 0.013982 0.999743 0.000000 + + + + -1.220983 0.331820 -0.122910 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 57 + 17 + 0 + 6 + -1 + -1 + 0 + 0.020521 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999055 0.009567 -0.042389 0.000000 + -0.009401 0.999947 0.004098 0.000000 + 0.042426 -0.003696 0.999093 0.000000 + + + + 1.518001 -0.341384 -0.762734 0.000000 + + + + + + 0.999997 -0.001474 -0.001951 0.000000 + 0.001433 0.999775 -0.021174 0.000000 + 0.001982 0.021171 0.999774 0.000000 + + + + 0.384535 -1.510486 -0.131125 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 69 + 29 + 0 + 6 + -1 + -1 + 0 + 1.608307 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999826 0.000238 -0.018625 0.000000 + -0.000886 0.999395 -0.034779 0.000000 + 0.018605 0.034790 0.999221 0.000000 + + + + -0.549585 0.572513 -1.341193 0.000000 + + + + + + 0.999122 0.024040 -0.034307 0.000000 + -0.022760 0.999047 0.037239 0.000000 + 0.035169 -0.036426 0.998717 0.000000 + + + + -1.003116 0.637012 -1.126825 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 79 + 89 + 0 + 6 + -1 + -1 + 0 + 0.213800 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999720 -0.018640 0.014590 0.000000 + 0.018153 0.999296 0.032820 0.000000 + -0.015192 -0.032546 0.999355 0.000000 + + + + 0.275675 1.078840 -0.317842 0.000000 + + + + + + 0.998037 -0.056356 0.027333 0.000000 + 0.056880 0.998204 -0.018783 0.000000 + -0.026225 0.020301 0.999450 0.000000 + + + + 0.160671 -0.092306 -0.767547 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 79 + 9 + 0 + 6 + -1 + -1 + 0 + -1.311379 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999720 -0.018640 0.014590 0.000000 + 0.018153 0.999296 0.032820 0.000000 + -0.015192 -0.032546 0.999355 0.000000 + + + + -0.394871 0.722561 -0.817239 0.000000 + + + + + + 0.999737 0.022915 -0.001317 0.000000 + -0.022916 0.999737 -0.000521 0.000000 + 0.001305 0.000551 0.999999 0.000000 + + + + 0.043577 -0.613353 0.541286 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 121 + 79 + 0 + 6 + -1 + -1 + 0 + -0.480381 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999998 -0.000190 -0.002053 0.000000 + 0.000197 0.999994 0.003537 0.000000 + 0.002052 -0.003537 0.999992 0.000000 + + + + 0.067992 -0.697016 0.595567 0.000000 + + + + + + 0.999720 -0.018640 0.014590 0.000000 + 0.018153 0.999296 0.032820 0.000000 + -0.015192 -0.032546 0.999355 0.000000 + + + + -1.084769 -0.158835 0.027893 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 123 + 55 + 0 + 6 + -1 + -1 + 0 + 0.559885 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999994 -0.002760 -0.002020 0.000000 + 0.002705 0.999637 -0.026810 0.000000 + 0.002093 0.026805 0.999638 0.000000 + + + + -0.834968 0.769494 -0.279048 0.000000 + + + + + + 0.999278 0.033193 -0.018458 0.000000 + -0.033448 0.999347 -0.013654 0.000000 + 0.017993 0.014262 0.999736 0.000000 + + + + 0.174020 -0.500104 -0.136622 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 67 + 89 + 0 + 6 + -1 + -1 + 0 + -0.214666 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999996 0.000931 0.002529 0.000000 + -0.000904 0.999945 -0.010481 0.000000 + -0.002539 0.010479 0.999942 0.000000 + + + + -1.184629 0.855819 0.449632 0.000000 + + + + + + 0.998037 -0.056356 0.027333 0.000000 + 0.056880 0.998204 -0.018783 0.000000 + -0.026225 0.020301 0.999450 0.000000 + + + + 0.560713 -0.503984 0.067069 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 159 + 7 + 0 + 6 + -1 + -1 + 0 + 0.476677 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999677 0.025179 -0.003513 0.000000 + -0.025210 0.999639 -0.009304 0.000000 + 0.003277 0.009389 0.999951 0.000000 + + + + -1.031419 -0.198710 0.163638 0.000000 + + + + + + 0.999657 -0.006302 -0.025418 0.000000 + 0.005793 0.999782 -0.020059 0.000000 + 0.025539 0.019905 0.999476 0.000000 + + + + 0.547859 -0.668573 -0.407400 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 33 + 139 + 0 + 6 + -1 + -1 + 0 + -0.136029 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999950 0.009457 0.003363 0.000000 + -0.009384 0.999730 -0.021252 0.000000 + -0.003563 0.021220 0.999768 0.000000 + + + + 1.236913 -0.226451 -0.551620 0.000000 + + + + + + 0.999607 -0.011977 -0.025333 0.000000 + 0.010283 0.997768 -0.065982 0.000000 + 0.026067 0.065695 0.997499 0.000000 + + + + -0.382169 -0.654208 -0.931227 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 67 + 79 + 0 + 6 + -1 + -1 + 0 + -0.826043 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999996 0.000974 0.002457 0.000000 + -0.000947 0.999938 -0.011058 0.000000 + -0.002468 0.011055 0.999936 0.000000 + + + + -1.505095 0.542423 0.900927 0.000000 + + + + + + 0.999717 -0.018723 0.014667 0.000000 + 0.018233 0.999294 0.032850 0.000000 + -0.015272 -0.032574 0.999353 0.000000 + + + + 0.340514 0.396384 1.011295 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 163 + 97 + 0 + 6 + -1 + -1 + 0 + 0.970185 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.997605 0.062113 -0.030440 0.000000 + -0.058457 0.992320 0.109011 0.000000 + 0.036977 -0.106970 0.993574 0.000000 + + + + 1.476443 0.486329 0.913734 0.000000 + + + + + + 0.999910 0.008640 -0.010282 0.000000 + -0.008786 0.999860 -0.014238 0.000000 + 0.010158 0.014327 0.999846 0.000000 + + + + -1.182305 0.021136 -0.893970 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 159 + 37 + 0 + 6 + -1 + -1 + 0 + 0.266430 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999704 0.024114 -0.003331 0.000000 + -0.024143 0.999671 -0.008677 0.000000 + 0.003121 0.008755 0.999957 0.000000 + + + + 0.000383 0.217391 0.660933 0.000000 + + + + + + 0.999871 0.013062 -0.009312 0.000000 + -0.012995 0.999890 0.007150 0.000000 + 0.009404 -0.007028 0.999931 0.000000 + + + + -0.705906 -1.085847 0.679040 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 143 + 61 + 0 + 6 + -1 + -1 + 0 + 0.188686 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999826 0.007522 0.017041 0.000000 + -0.007393 0.999944 -0.007605 0.000000 + -0.017097 0.007477 0.999826 0.000000 + + + + 0.225340 -0.211301 -0.771730 0.000000 + + + + + + 0.999874 0.015442 -0.003740 0.000000 + -0.015468 0.999855 -0.007127 0.000000 + 0.003629 0.007183 0.999968 0.000000 + + + + -0.204876 -0.630318 0.438494 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 63 + 135 + 0 + 6 + -1 + -1 + 0 + 0.029585 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999649 -0.018581 0.018902 0.000000 + 0.019148 0.999359 -0.030263 0.000000 + -0.018327 0.030614 0.999363 0.000000 + + + + 0.560866 0.853232 0.509590 0.000000 + + + + + + 0.999897 0.007362 0.012319 0.000000 + -0.007525 0.999884 0.013219 0.000000 + -0.012221 -0.013311 0.999837 0.000000 + + + + -1.342288 0.980490 0.900231 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 57 + 11 + 0 + 6 + -1 + -1 + 0 + -0.449149 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999049 0.008960 -0.042662 0.000000 + -0.008848 0.999957 0.002812 0.000000 + 0.042685 -0.002432 0.999086 0.000000 + + + + -0.991636 0.441656 1.038285 0.000000 + + + + + + 0.999897 0.005133 -0.013414 0.000000 + -0.004951 0.999896 0.013546 0.000000 + 0.013482 -0.013479 0.999818 0.000000 + + + + 0.862090 -0.070671 0.825420 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 57 + 145 + 0 + 6 + -1 + -1 + 0 + 0.656874 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999050 0.008719 -0.042702 0.000000 + -0.008611 0.999959 0.002706 0.000000 + 0.042724 -0.002335 0.999084 0.000000 + + + + -0.840727 0.586269 1.087485 0.000000 + + + + + + 0.999958 0.008634 -0.003026 0.000000 + -0.008756 0.999047 -0.042765 0.000000 + 0.002654 0.042789 0.999081 0.000000 + + + + 1.078610 -0.895109 0.204945 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 159 + 39 + 0 + 6 + -1 + -1 + 0 + -0.014030 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999721 0.023373 -0.003271 0.000000 + -0.023400 0.999690 -0.008475 0.000000 + 0.003071 0.008550 0.999959 0.000000 + + + + -0.633000 0.660746 -0.496322 0.000000 + + + + + + 0.999930 0.009915 -0.006511 0.000000 + -0.009995 0.999874 -0.012334 0.000000 + 0.006388 0.012398 0.999903 0.000000 + + + + 0.423656 -0.657524 -0.853168 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 31 + 51 + 0 + 6 + -1 + -1 + 0 + 0.272670 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999987 -0.004228 -0.002975 0.000000 + 0.004302 0.999667 0.025433 0.000000 + 0.002867 -0.025445 0.999672 0.000000 + + + + 1.010839 -0.391663 0.631610 0.000000 + + + + + + 0.997428 0.069505 0.017479 0.000000 + -0.070065 0.996972 0.033730 0.000000 + -0.015081 -0.034868 0.999278 0.000000 + + + + -0.677447 -0.408883 -0.381499 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 11 + 145 + 0 + 6 + -1 + -1 + 0 + -0.327312 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999903 0.003826 -0.013390 0.000000 + -0.003636 0.999893 0.014160 0.000000 + 0.013442 -0.014109 0.999810 0.000000 + + + + 0.450811 1.150341 -0.303628 0.000000 + + + + + + 0.999966 0.007632 -0.003111 0.000000 + -0.007759 0.999037 -0.043180 0.000000 + 0.002778 0.043203 0.999062 0.000000 + + + + 0.508511 0.249434 -0.899110 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 93 + 95 + 0 + 6 + -1 + -1 + 0 + 0.228531 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.998301 -0.058241 -0.001840 0.000000 + 0.058269 0.997981 0.025274 0.000000 + 0.000364 -0.025339 0.999679 0.000000 + + + + -0.077853 -0.699305 -1.383325 0.000000 + + + + + + 0.999460 0.027820 -0.017473 0.000000 + -0.028941 0.997294 -0.067582 0.000000 + 0.015545 0.068051 0.997561 0.000000 + + + + -0.557222 -0.587851 1.100715 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 5 + 51 + 0 + 6 + -1 + -1 + 0 + -0.121320 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.999704 -0.024277 0.001611 0.000000 + 0.024235 0.999453 0.022485 0.000000 + -0.002156 -0.022440 0.999746 0.000000 + + + + -0.031808 -0.020050 1.339074 0.000000 + + + + + + 0.997428 0.069505 0.017479 0.000000 + -0.070065 0.996972 0.033730 0.000000 + -0.015081 -0.034868 0.999278 0.000000 + + + + -0.408879 -0.482817 -0.699488 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 51 + 13 + 0 + 6 + -1 + -1 + 0 + 0.151669 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.997418 0.069685 0.017351 0.000000 + -0.070246 0.996946 0.034118 0.000000 + -0.014920 -0.035249 0.999267 0.000000 + + + + -0.846216 0.300711 0.466160 0.000000 + + + + + + 0.999694 0.003390 -0.024494 0.000000 + -0.003026 0.999885 0.014888 0.000000 + 0.024542 -0.014810 0.999589 0.000000 + + + + 0.790366 -0.405384 0.724201 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 57 + 163 + 0 + 6 + -1 + -1 + 0 + -0.039658 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.371027 0.917910 -0.140645 0.000000 + -0.399368 0.020991 -0.916551 0.000000 + -0.838358 0.396234 0.374372 0.000000 + + + + 0.214166 0.225124 0.783153 0.000000 + + + + + + 0.337445 0.924316 -0.178245 0.000000 + -0.501924 0.016481 -0.864755 0.000000 + -0.796369 0.381273 0.469498 0.000000 + + + + -0.774225 -0.357658 -0.276467 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 109 + 113 + 0 + 6 + -1 + -1 + 0 + -0.084688 + 0.300000 + 1 + 100 + 45.000000 + 1 + + + + + 0.331731 0.937140 -0.108269 0.000000 + -0.373095 0.024918 -0.927459 0.000000 + -0.866461 0.348062 0.357908 0.000000 + + + + 0.115618 -1.142983 -0.887744 0.000000 + + + + + + 0.339873 0.933090 -0.117597 0.000000 + -0.382533 0.022927 -0.923658 0.000000 + -0.859160 0.358911 0.364730 0.000000 + + + + 1.807837 -1.587922 0.609291 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 1 + 1 + + + + 0 + 28 + 0 0 0 0 + + + 0.000000 0.000000 0.000000 0.000000 + + + 0.000000 1.000000 0.000000 0.000000 + + 0.000000 + 0 0 0 0 + + + + 0 + 31 + 0 0 0 0 + + 315 + 1 + 0.000000 + + + + + + 0.737321 -0.000198 -0.675542 0.000000 + 0.097020 0.989664 0.105602 0.000000 + 0.668539 -0.143404 0.729720 0.000000 + + + + -0.074712 -0.143958 0.022858 0.000000 + + + 316 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 317 + 0 + 42 + 0 0 0 0 + + + 0.596313 -0.309567 1.106486 0.000000 + 0.643806 -0.177254 0.154638 0.000000 + 0.831410 -0.111997 1.007067 0.000000 + 0.423118 -0.382422 1.138688 0.000000 + 0.150360 -0.364670 0.035505 0.000000 + 0.089922 -0.518111 1.205917 0.000000 + -0.065866 -0.529368 1.207362 0.000000 + -0.378625 -0.386715 -0.076780 0.000000 + -0.445276 -0.552009 1.217677 0.000000 + -0.550605 -0.527907 1.203142 0.000000 + -0.643938 -0.442624 0.842944 0.000000 + -0.891385 -0.241135 -0.171223 0.000000 + -0.871448 -0.287719 0.015864 0.000000 + -0.920838 -0.231840 -0.195754 0.000000 + -1.080077 0.054311 -0.869217 0.000000 + -1.098567 0.076301 -0.851978 0.000000 + -1.075426 0.079097 -0.896598 0.000000 + -0.747485 -0.100814 -0.991281 0.000000 + -0.531135 -0.203898 -1.081084 0.000000 + -0.237642 -0.264237 -1.169412 0.000000 + 0.099648 -0.328022 -1.275779 0.000000 + 0.282612 -0.317081 -1.315009 0.000000 + 0.437516 -0.317272 -1.348398 0.000000 + 0.626668 -0.308415 -1.242323 0.000000 + 0.725284 -0.269717 -1.155176 0.000000 + 1.036329 -0.138061 -0.892418 0.000000 + 1.058200 0.070749 0.027147 0.000000 + 1.146224 -0.027736 -0.746670 0.000000 + 1.202566 0.018216 -0.681935 0.000000 + 1.012291 0.091243 0.263587 0.000000 + 0.858097 -0.091489 0.997485 0.000000 + 1.015917 0.069825 0.561513 0.000000 + -1.057152 0.124347 -0.849862 0.000000 + -0.588774 0.532716 0.321014 0.000000 + -0.491743 0.619486 0.232160 0.000000 + -0.964025 0.211063 -0.835323 0.000000 + -0.500202 0.338036 0.751803 0.000000 + 0.029345 0.625646 0.615315 0.000000 + -0.062352 0.681505 0.446670 0.000000 + 0.924138 0.155257 -0.706661 0.000000 + 0.246133 0.002639 -1.183328 0.000000 + 0.763646 0.183583 0.840469 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 318 + 1 + 0.000000 + + + + + + 0.499110 -0.493079 0.712575 0.000000 + 0.604727 0.787168 0.121126 0.000000 + -0.620641 0.370458 0.691061 0.000000 + + + + 0.089376 0.104299 -0.078941 0.000000 + + + 319 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.831410 -0.111997 1.007067 0.000000 + + 0.040000 + 0 + + 320 + 0 + 32 + 0 0 0 0 + + + 0.410384 -0.291683 -0.422583 0.000000 + -0.146526 0.204817 -0.657320 0.000000 + 0.401662 -0.101049 -0.427067 0.000000 + -0.312712 -1.072996 -0.211322 0.000000 + -0.301037 -1.013021 -0.256365 0.000000 + -0.280210 -1.045215 -0.231604 0.000000 + -0.299865 -0.860814 -0.333081 0.000000 + -0.081437 -0.971186 -0.265043 0.000000 + -0.302923 -0.334494 -0.592421 0.000000 + 0.281833 -0.840598 -0.319615 0.000000 + 0.402071 -0.793700 -0.310932 0.000000 + -0.302138 -0.291562 -0.602830 0.000000 + 0.400089 -0.699885 -0.327678 0.000000 + -0.300214 -0.046996 -0.660726 0.000000 + -0.289753 0.302915 -0.678564 0.000000 + -0.294456 0.355784 -0.676432 0.000000 + -0.286270 0.878632 -0.562647 0.000000 + 0.159255 0.626722 -0.509626 0.000000 + -0.282738 0.971590 -0.546108 0.000000 + -0.294065 0.959934 -0.553997 0.000000 + -0.310502 0.956176 -0.546933 0.000000 + 0.331063 0.856657 -0.332182 0.000000 + 0.379740 0.492353 -0.408213 0.000000 + 0.361112 0.855564 -0.315227 0.000000 + 0.388935 0.416179 -0.423057 0.000000 + -0.253115 0.538029 0.782402 0.000000 + -0.244842 0.555385 0.803444 0.000000 + -0.242751 0.540194 0.816696 0.000000 + -0.305532 -0.994030 0.179649 0.000000 + 0.232044 -0.695319 0.519626 0.000000 + 0.121245 0.501817 0.939261 0.000000 + -0.258828 0.525195 0.777583 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 321 + 1 + 0.000000 + + + + + + 0.961986 -0.038364 0.270391 0.000000 + 0.099073 0.971660 -0.214618 0.000000 + -0.254494 0.233248 0.938524 0.000000 + + + + 0.197784 0.147631 0.070011 0.000000 + + + 322 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.402071 -0.793700 -0.310932 0.000000 + + 0.040000 + 0 + + 323 + 0 + 35 + 0 0 0 0 + + + 0.072488 0.292632 -1.317285 0.000000 + -0.022874 0.592725 0.512022 0.000000 + 0.481618 0.584783 0.315911 0.000000 + 0.119963 0.291453 -1.329191 0.000000 + -0.402954 0.282573 -1.215855 0.000000 + -0.462269 0.265744 -1.184262 0.000000 + -0.494933 0.435279 0.725359 0.000000 + -0.871796 0.129517 -0.982222 0.000000 + -1.001108 0.036240 -0.870254 0.000000 + -0.914152 0.091316 -0.445417 0.000000 + -0.948729 0.073766 -0.911174 0.000000 + -0.689950 0.298907 0.834273 0.000000 + -0.407252 0.455154 0.969429 0.000000 + -0.642434 0.290991 1.045011 0.000000 + -0.353105 0.490766 0.958187 0.000000 + 0.091857 0.637451 0.860874 0.000000 + 0.185402 0.665258 0.845027 0.000000 + 0.530930 0.643942 0.585995 0.000000 + 0.381991 0.674682 0.810246 0.000000 + 0.579489 0.635245 0.514021 0.000000 + 0.822559 0.469336 0.162319 0.000000 + 0.591319 0.171601 -1.312346 0.000000 + 0.820254 0.478071 0.160854 0.000000 + 0.602482 0.172085 -1.321233 0.000000 + 0.184474 -0.661480 -0.445488 0.000000 + 0.293513 -0.869981 0.136834 0.000000 + -0.335577 -0.647084 0.459345 0.000000 + -0.966679 0.001816 -0.820019 0.000000 + 0.500563 -0.242168 -0.901465 0.000000 + 0.418675 -0.818617 0.202325 0.000000 + 0.264394 -0.221569 0.970405 0.000000 + -0.414372 -0.167564 1.081723 0.000000 + 0.531432 -0.550742 0.538466 0.000000 + 0.631008 -0.209819 0.580920 0.000000 + 0.393338 -0.028316 0.913643 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 324 + 1 + 0.000000 + + + + + + 0.747553 0.454401 -0.484443 0.000000 + -0.169682 0.835810 0.522139 0.000000 + 0.642163 -0.308125 0.701916 0.000000 + + + + -0.065133 -0.040087 -0.017158 0.000000 + + + 325 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.481618 0.584783 0.315911 0.000000 + + 0.040000 + 0 + + 326 + 0 + 39 + 0 0 0 0 + + + -0.022812 -0.844826 -0.904981 0.000000 + -0.004545 -0.837416 -0.897980 0.000000 + 0.126167 -0.856493 -0.745248 0.000000 + 0.032309 -0.965994 -0.569593 0.000000 + -0.121244 -0.969102 -0.699102 0.000000 + 0.168920 -0.864897 -0.696896 0.000000 + 0.495179 -0.747109 -0.360836 0.000000 + 0.396296 -0.834006 -0.191573 0.000000 + 0.541746 -0.727914 -0.317078 0.000000 + 0.827435 -0.456875 -0.070349 0.000000 + 0.653225 -0.572473 0.206293 0.000000 + 0.905384 -0.380840 -0.008586 0.000000 + 1.213429 0.105673 0.171303 0.000000 + 0.861436 -0.194963 0.447960 0.000000 + 1.102831 -0.057057 0.123691 0.000000 + 0.772408 -0.266654 0.522845 0.000000 + 0.573509 -0.612860 0.779051 0.000000 + 0.530352 -0.714906 0.692592 0.000000 + 0.474164 -0.858053 0.581661 0.000000 + 0.309231 -1.024483 0.347799 0.000000 + 0.355206 -0.990911 0.456376 0.000000 + 0.238919 -1.084627 0.154403 0.000000 + -0.010663 -1.146148 -0.191940 0.000000 + -0.093528 -1.166744 -0.301615 0.000000 + -0.252390 -1.170646 -0.422473 0.000000 + -0.054475 1.345767 -0.277811 0.000000 + 0.874494 0.734852 0.003788 0.000000 + 1.164669 0.501073 0.005933 0.000000 + 0.806737 0.612274 -0.397654 0.000000 + -0.140870 1.417651 -0.279713 0.000000 + -0.077231 1.395026 0.120023 0.000000 + -0.664740 0.201212 0.952238 0.000000 + -0.712390 0.574783 -0.573177 0.000000 + -1.054371 -0.205300 0.155014 0.000000 + -0.775000 0.459809 -0.611802 0.000000 + -1.064406 -0.217065 0.140009 0.000000 + -0.435366 -0.006186 0.939490 0.000000 + -0.538975 -0.956918 -0.153960 0.000000 + 0.039522 -0.886270 0.435089 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 327 + 1 + 0.000000 + + + + + + 0.728556 -0.436749 0.527690 0.000000 + 0.683375 0.516242 -0.516229 0.000000 + -0.046954 0.736712 0.674574 0.000000 + + + + 0.234213 -0.012225 -0.237108 0.000000 + + + 328 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.126167 -0.856493 -0.745248 0.000000 + + 0.040000 + 0 + + 329 + 0 + 26 + 0 0 0 0 + + + -0.249704 -0.586694 1.038860 0.000000 + -0.212097 -0.590698 1.040961 0.000000 + -0.224462 -0.497632 1.049651 0.000000 + -0.233574 -0.592160 1.039131 0.000000 + -0.230562 -0.550755 1.035753 0.000000 + -0.227830 -0.480073 1.049466 0.000000 + 0.142967 0.483213 1.150505 0.000000 + 0.125713 0.480541 1.164587 0.000000 + 0.115695 0.489935 1.142920 0.000000 + -0.052507 0.474350 1.271099 0.000000 + -0.008301 0.248330 1.179300 0.000000 + -0.049945 0.518983 1.290845 0.000000 + -0.225766 -0.441146 1.049085 0.000000 + -0.152542 -0.338777 1.040126 0.000000 + 0.578306 0.116731 -1.072736 0.000000 + 0.712743 0.143241 -0.921227 0.000000 + 0.607236 -0.016820 -0.982974 0.000000 + 0.512924 0.063280 -1.114486 0.000000 + 0.768596 0.303741 0.170359 0.000000 + 0.297529 -0.552953 0.316760 0.000000 + 0.426291 -0.357225 -0.587797 0.000000 + -0.292565 -0.037558 -1.147663 0.000000 + -0.464113 0.186177 -0.972360 0.000000 + -0.317455 -0.033122 -1.142580 0.000000 + -0.858239 0.030396 -0.796152 0.000000 + -0.813362 0.253130 -0.739476 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 330 + 1 + 0.000000 + + + + + + 0.819801 -0.395231 0.414390 0.000000 + 0.078724 0.794551 0.602072 0.000000 + -0.567212 -0.460957 0.682488 0.000000 + + + + -0.164444 -0.053678 -0.029805 0.000000 + + + 331 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + -0.008301 0.248330 1.179300 0.000000 + + 0.040000 + 0 + + 332 + 0 + 35 + 0 0 0 0 + + + -0.838835 -0.335560 0.968081 0.000000 + -0.900231 -0.418889 0.784926 0.000000 + 0.660936 -0.319713 0.481776 0.000000 + -0.318237 -0.311157 0.837381 0.000000 + -0.943584 -0.445233 0.618130 0.000000 + 0.504457 -0.397544 -0.030751 0.000000 + -1.041692 -0.496189 0.266098 0.000000 + -1.068753 -0.469685 0.109274 0.000000 + 0.325966 -0.307600 -0.533932 0.000000 + -1.139169 -0.402216 -0.255887 0.000000 + -1.046948 0.002858 -0.890883 0.000000 + -1.176697 -0.022363 -0.853741 0.000000 + -1.188264 0.028638 -0.913991 0.000000 + -0.292307 -0.126541 -0.868619 0.000000 + -1.183270 -0.146076 -0.730737 0.000000 + -0.097789 -0.148950 -0.847233 0.000000 + -1.150027 -0.328068 -0.397508 0.000000 + 0.185765 -0.181383 -0.816098 0.000000 + 0.633829 -0.220064 -0.751005 0.000000 + 0.803826 -0.226333 -0.728650 0.000000 + 1.232373 -0.193782 -0.588524 0.000000 + 1.548316 -0.163189 -0.488908 0.000000 + 1.765561 -0.091394 -0.354719 0.000000 + 2.005334 0.005697 -0.142536 0.000000 + 1.910449 -0.043788 -0.265710 0.000000 + 1.730707 0.031243 0.208917 0.000000 + 2.067529 0.090444 0.006800 0.000000 + 2.094359 0.110454 0.059536 0.000000 + 2.085881 0.116583 0.081784 0.000000 + 0.697276 -0.276455 0.608629 0.000000 + -0.438373 0.833122 0.188403 0.000000 + -0.980885 0.371680 -0.460290 0.000000 + -0.718668 0.613059 0.369079 0.000000 + 1.969284 0.113278 -0.014365 0.000000 + 1.256720 0.390482 0.096433 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 333 + 1 + 0.000000 + + + + + + 0.919658 0.024893 -0.391930 0.000000 + 0.182755 0.856216 0.483214 0.000000 + 0.347605 -0.516019 0.782876 0.000000 + + + + 0.081378 0.250998 -0.138542 0.000000 + + + 334 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 1.765561 -0.091394 -0.354719 0.000000 + + 0.040000 + 0 + + 335 + 0 + 45 + 0 0 0 0 + + + -0.905591 1.085954 -0.329751 0.000000 + 0.772413 0.962819 -0.815490 0.000000 + -0.612763 0.904455 -0.681011 0.000000 + -1.341478 1.245149 0.216855 0.000000 + -1.370582 1.223408 0.194309 0.000000 + -1.360537 1.234686 0.261273 0.000000 + 0.569831 0.512615 1.306878 0.000000 + 0.539956 0.568212 1.285468 0.000000 + 0.547653 0.578372 1.274587 0.000000 + 0.539520 0.639112 1.197901 0.000000 + 0.385020 0.699279 1.179960 0.000000 + 0.548479 0.910185 0.852451 0.000000 + 0.034416 0.950114 0.982318 0.000000 + 0.560991 0.943540 0.759017 0.000000 + -0.368353 1.101061 0.751281 0.000000 + 0.631771 1.098259 0.306833 0.000000 + -0.592088 1.178041 0.629515 0.000000 + 0.645986 1.100642 0.244087 0.000000 + -1.243901 1.242112 0.258964 0.000000 + 0.781722 1.113668 -0.297624 0.000000 + -1.269762 1.239667 0.251355 0.000000 + 0.783409 1.112138 -0.305127 0.000000 + -1.020337 1.123779 -0.180305 0.000000 + 0.811987 1.089488 -0.392653 0.000000 + 0.856364 0.973603 -0.783216 0.000000 + 0.904851 0.996527 -0.677906 0.000000 + 0.845737 0.967444 -0.808646 0.000000 + 0.656856 0.767934 -1.147639 0.000000 + 0.598883 0.697747 -1.247072 0.000000 + -0.388254 0.757393 -0.956428 0.000000 + 0.595622 0.700043 -1.247532 0.000000 + -0.226888 0.597363 -1.133648 0.000000 + 0.111025 0.207949 -1.503598 0.000000 + 0.342077 0.257149 -1.556253 0.000000 + 0.229209 -0.055964 -1.653649 0.000000 + 0.047925 0.304673 -1.445027 0.000000 + 0.358591 0.286515 -1.545565 0.000000 + 1.008512 -0.550796 0.757363 0.000000 + 0.778659 -0.298028 1.443483 0.000000 + -0.558342 -1.254844 0.691743 0.000000 + 0.209110 -1.563367 -0.551456 0.000000 + -1.116206 -0.730147 0.369149 0.000000 + -1.016754 -1.066245 0.330725 0.000000 + -1.029452 -1.067330 0.418921 0.000000 + 0.041044 -1.496372 -1.068261 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 336 + 1 + 0.000000 + + + + + + 0.530805 0.632459 0.564129 0.000000 + -0.581363 0.756069 -0.300627 0.000000 + -0.616655 -0.168390 0.769014 0.000000 + + + + -0.042381 0.288483 0.147835 0.000000 + + + 337 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + -0.612763 0.904455 -0.681011 0.000000 + + 0.040000 + 0 + + 338 + 0 + 64 + 0 0 0 0 + + + 0.067742 0.614521 -1.807078 0.000000 + 0.058145 0.579170 -1.807656 0.000000 + 0.081315 0.611910 -1.798810 0.000000 + 0.000677 0.441834 -1.816566 0.000000 + -1.136187 0.272400 0.063542 0.000000 + 0.032415 0.844738 -1.529120 0.000000 + -0.004395 0.439362 -1.814491 0.000000 + -1.180055 -0.267324 0.064113 0.000000 + -0.123189 -0.111188 -1.691315 0.000000 + -0.129784 -0.185122 -1.653621 0.000000 + -1.070628 -0.792870 0.135631 0.000000 + -0.138130 -0.658336 -1.421795 0.000000 + 0.602283 -1.792770 0.170117 0.000000 + 0.618022 -1.786751 0.149875 0.000000 + 0.266350 -1.770968 0.215472 0.000000 + 0.438803 -1.755706 -0.060574 0.000000 + 0.138518 -1.742832 0.260242 0.000000 + 0.319667 -1.660930 -0.268029 0.000000 + -0.151241 -1.683233 0.356161 0.000000 + -0.357199 -1.594713 0.286550 0.000000 + 0.157071 -1.523885 -0.564409 0.000000 + -0.380220 -1.576996 0.280600 0.000000 + 0.041439 -1.311278 -0.828139 0.000000 + -0.799769 -1.248970 0.209001 0.000000 + -0.041727 -1.145463 -1.033553 0.000000 + -0.800745 -1.247844 0.207497 0.000000 + -0.115142 -0.796250 -1.311188 0.000000 + -0.858290 -1.174411 0.211325 0.000000 + -1.110417 -0.790874 0.251095 0.000000 + -1.126215 -0.764269 0.259586 0.000000 + -1.290206 -0.278773 0.407073 0.000000 + -1.317537 -0.193808 0.438989 0.000000 + -1.305070 0.217277 0.516601 0.000000 + -1.329803 -0.031292 0.512076 0.000000 + -1.326800 0.130272 0.554476 0.000000 + -1.279383 0.326351 0.468783 0.000000 + -1.063478 0.747482 0.385196 0.000000 + -0.943379 0.773407 0.133951 0.000000 + -1.031066 0.810479 0.375526 0.000000 + -0.710795 1.181516 0.426151 0.000000 + -0.620589 1.186641 0.268407 0.000000 + -0.679022 1.218088 0.434566 0.000000 + -0.299899 1.480570 0.615484 0.000000 + -0.199490 1.471696 0.453712 0.000000 + -0.278427 1.499645 0.622866 0.000000 + -0.275123 1.498555 0.624233 0.000000 + 0.077679 1.550048 0.549979 0.000000 + 0.425994 1.626017 0.275395 0.000000 + 0.295812 1.567526 -0.003211 0.000000 + 0.132464 1.570540 0.522198 0.000000 + 0.198198 1.525905 -0.229293 0.000000 + 0.130530 1.416040 -0.499135 0.000000 + 0.047844 1.268527 -0.861603 0.000000 + 0.039824 1.172333 -1.016727 0.000000 + 0.024553 0.884544 -1.483214 0.000000 + 1.362316 0.025138 0.458217 0.000000 + 1.391814 -0.115812 0.370119 0.000000 + 0.781498 0.533932 -0.770093 0.000000 + 0.811746 1.179605 0.228606 0.000000 + -0.165785 1.068714 1.027354 0.000000 + -0.201009 0.466143 1.402669 0.000000 + 0.187913 -0.023863 1.381222 0.000000 + -1.278330 0.117882 0.602969 0.000000 + 0.190660 -1.281242 0.747143 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 339 + 1 + 0.000000 + + + + + + 0.982456 0.020968 0.185312 0.000000 + 0.010904 0.985502 -0.169316 0.000000 + -0.186175 0.168366 0.967983 0.000000 + + + + -0.185187 0.007059 0.060775 0.000000 + + + 340 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + -1.110417 -0.790874 0.251095 0.000000 + + 0.040000 + 0 + + 341 + 0 + 24 + 0 0 0 0 + + + -0.137758 -0.545029 -0.530415 0.000000 + -0.392292 -0.494327 -0.359440 0.000000 + -0.119579 -0.473242 -0.564437 0.000000 + -0.794579 -0.212278 -0.178904 0.000000 + -0.064762 -0.283993 -0.669716 0.000000 + -0.824116 -0.429000 -0.084139 0.000000 + -0.761597 -0.064285 -0.199468 0.000000 + 0.131194 0.100433 -0.791804 0.000000 + -0.680362 0.325083 -0.242895 0.000000 + 0.171524 0.186000 -0.818187 0.000000 + 0.178711 0.181401 -0.828878 0.000000 + 0.177418 0.197450 -0.824325 0.000000 + -0.627766 0.480442 -0.214916 0.000000 + -0.306044 0.500301 -0.402022 0.000000 + -0.569314 0.697320 -0.166838 0.000000 + -0.365284 0.387573 0.563555 0.000000 + -0.067261 0.779914 0.491815 0.000000 + -0.567313 0.694537 -0.167826 0.000000 + 1.193845 0.205441 0.124108 0.000000 + -0.543830 -0.367646 0.604430 0.000000 + -0.471569 -0.492462 0.584267 0.000000 + 0.625885 -0.694403 0.275877 0.000000 + 1.192557 0.169848 0.123098 0.000000 + -0.584045 -0.475939 0.587582 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 342 + 1 + 0.000000 + + + + + + 0.930531 0.247449 -0.269964 0.000000 + -0.317436 0.912601 -0.257671 0.000000 + 0.182609 0.325467 0.927753 0.000000 + + + + -0.067546 -0.072300 -0.147572 0.000000 + + + 343 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 344 + 0 + 55 + 0 0 0 0 + + + -0.589175 -1.681216 -0.026649 0.000000 + 0.622146 -1.552234 -1.114926 0.000000 + -0.325464 -1.712240 0.440229 0.000000 + -0.588194 -1.681474 -0.024965 0.000000 + -0.778786 -1.510182 -0.429829 0.000000 + -0.157427 -1.532325 -0.734341 0.000000 + -0.582683 -1.685705 -0.023038 0.000000 + 0.528499 -1.563314 -1.076542 0.000000 + 0.609699 -1.578101 -1.073618 0.000000 + 0.626630 -1.580517 -1.075327 0.000000 + 0.621743 -1.574369 -1.079746 0.000000 + 0.833847 -1.601727 -1.075196 0.000000 + 0.796654 -1.585065 -0.934152 0.000000 + 0.720810 -1.625968 -0.526065 0.000000 + 0.669690 -1.605643 -0.278770 0.000000 + -0.051958 -1.583488 0.889158 0.000000 + 0.560422 -1.541519 0.321837 0.000000 + 0.382728 -1.018645 1.425591 0.000000 + 0.233476 -1.310434 1.250354 0.000000 + 0.421455 -1.291051 1.058200 0.000000 + 0.234953 -1.312063 1.248880 0.000000 + 0.454438 -1.354897 0.875893 0.000000 + 0.156642 -1.385360 1.168042 0.000000 + -0.088185 -1.611074 0.913546 0.000000 + -0.102445 -1.617852 0.904768 0.000000 + -0.428196 -1.742037 0.549171 0.000000 + -0.416095 -1.745433 0.577901 0.000000 + -0.436854 -1.749164 0.502167 0.000000 + 0.364414 1.087661 1.350821 0.000000 + 0.365757 1.091566 1.364830 0.000000 + 0.384857 0.998929 1.413931 0.000000 + 0.384909 1.175386 1.258777 0.000000 + 0.333517 1.154089 1.336514 0.000000 + 0.336462 1.161510 1.332712 0.000000 + 0.464479 1.428211 0.820902 0.000000 + 0.164881 1.445534 1.028258 0.000000 + 0.514364 1.563687 0.574164 0.000000 + 0.124094 1.510482 0.959129 0.000000 + 0.579591 1.674026 0.215222 0.000000 + -0.103476 1.676056 0.622100 0.000000 + 0.669837 1.809876 -0.247049 0.000000 + -0.163855 1.716569 0.537681 0.000000 + 0.701558 1.826957 -0.422140 0.000000 + -0.433089 1.746542 0.196194 0.000000 + 0.427207 1.846154 -0.674949 0.000000 + -0.501966 1.752096 0.113651 0.000000 + 0.755425 1.858850 -0.657234 0.000000 + 0.250349 1.807633 -0.688835 0.000000 + -0.796469 1.638165 -0.209584 0.000000 + -0.383333 1.669415 -0.645800 0.000000 + -0.856993 1.613633 -0.271282 0.000000 + -0.198856 1.701392 -0.737480 0.000000 + -0.973063 1.519535 -0.361555 0.000000 + -1.199485 0.325709 -0.242378 0.000000 + -1.199692 -0.609640 -0.235665 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 345 + 1 + 0.000000 + + + + + + 0.779733 -0.449930 -0.435406 0.000000 + 0.186959 0.831001 -0.523911 0.000000 + 0.597547 0.327108 0.732078 0.000000 + + + + 0.152066 -0.033652 -0.085371 0.000000 + + + 346 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 347 + 0 + 39 + 0 0 0 0 + + + -0.678987 0.950257 -0.004246 0.000000 + -0.723739 0.928023 0.002351 0.000000 + -0.842150 0.679654 0.091838 0.000000 + -0.085393 0.448462 0.301492 0.000000 + 0.016743 0.937829 0.093149 0.000000 + -0.623377 0.968589 -0.004370 0.000000 + -0.921804 0.519193 0.149229 0.000000 + -1.013530 0.185026 0.172006 0.000000 + -0.181771 -0.082624 0.345611 0.000000 + -1.070066 -0.010470 0.181675 0.000000 + -1.071637 -0.056811 0.187948 0.000000 + -0.973966 -0.353476 0.150379 0.000000 + -0.262946 -0.603359 0.221219 0.000000 + -0.915306 -0.534265 0.126836 0.000000 + -0.574565 -0.971686 -0.029474 0.000000 + -0.320969 -1.062716 -0.059432 0.000000 + -0.523576 -1.037867 -0.054490 0.000000 + -0.301452 -1.199726 -0.160903 0.000000 + 0.113226 -1.266457 -0.145075 0.000000 + -0.044699 -1.387033 -0.297808 0.000000 + 0.216271 -1.203223 -0.054173 0.000000 + 0.441939 -0.958155 0.115435 0.000000 + 0.574658 -0.818196 0.208392 0.000000 + 0.723482 -0.553548 0.273045 0.000000 + 0.844323 -0.345486 0.320493 0.000000 + 0.924811 -0.073240 0.296959 0.000000 + 1.000211 0.169726 0.272575 0.000000 + 0.855562 0.500854 0.168560 0.000000 + 1.000503 0.205573 0.265232 0.000000 + 0.742765 0.733131 0.095077 0.000000 + 0.080273 1.133654 -0.056768 0.000000 + 0.636348 0.864103 0.026069 0.000000 + 0.237313 1.144394 -0.094870 0.000000 + -0.391857 1.021474 -0.013494 0.000000 + 0.124240 0.440167 -0.461686 0.000000 + -0.017631 0.775251 -0.399957 0.000000 + 0.207261 -0.277685 -0.472078 0.000000 + -0.679019 0.895345 -0.036482 0.000000 + -0.674231 0.892256 -0.040329 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 348 + 1 + 0.000000 + + + + + + 0.864969 -0.375837 -0.332528 0.000000 + 0.442403 0.883880 0.151777 0.000000 + 0.236871 -0.278394 0.930800 0.000000 + + + + -0.008220 0.154810 -0.080662 0.000000 + + + 349 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 350 + 0 + 48 + 0 0 0 0 + + + 0.367213 0.148594 1.615108 0.000000 + 0.728751 0.302705 -0.336181 0.000000 + -0.149120 0.311165 1.617608 0.000000 + 1.139599 -0.022407 -0.200441 0.000000 + 0.242805 0.478229 -0.497682 0.000000 + -0.944674 0.274399 0.411716 0.000000 + -0.800202 0.311926 0.640390 0.000000 + -0.270680 0.486888 -0.669141 0.000000 + -0.701809 0.368814 -0.817876 0.000000 + -0.556540 0.380274 1.038423 0.000000 + -0.468864 0.372451 1.154210 0.000000 + -0.142225 0.341866 1.587671 0.000000 + -0.103506 0.335237 1.631650 0.000000 + -0.100985 0.326332 1.643176 0.000000 + 0.331774 0.164050 1.729523 0.000000 + 0.131486 0.212627 1.894735 0.000000 + 0.364427 0.157615 1.705929 0.000000 + 0.495180 0.089092 1.571802 0.000000 + 1.066541 0.009438 0.083025 0.000000 + 0.620628 0.040819 1.453516 0.000000 + 1.145972 0.005019 -0.199272 0.000000 + 1.162076 0.005911 -0.223981 0.000000 + 1.159161 -0.017216 -0.217251 0.000000 + 1.154873 -0.009767 -0.225897 0.000000 + 0.880113 0.263330 -0.518966 0.000000 + 0.839221 0.302458 -0.567503 0.000000 + 0.553457 0.424447 -0.869416 0.000000 + 0.464812 0.459904 -0.968814 0.000000 + 0.192228 0.458669 -1.202212 0.000000 + 0.268664 0.460065 -1.170504 0.000000 + 0.028714 0.459158 -1.269780 0.000000 + -0.653121 0.349698 -0.978629 0.000000 + -0.461034 0.297749 -1.448044 0.000000 + -0.505347 0.271872 -1.471375 0.000000 + -0.681393 0.361966 -0.883241 0.000000 + -0.309348 0.349792 -1.390633 0.000000 + 0.542870 -0.371357 -0.858684 0.000000 + 0.634069 -0.349370 -0.768210 0.000000 + -0.254698 -0.752137 -0.475346 0.000000 + -0.203351 -0.670420 -0.833507 0.000000 + -0.228225 -0.665934 -0.830626 0.000000 + -0.200935 -0.673472 -0.830074 0.000000 + 0.356900 -0.198761 -1.048574 0.000000 + -0.263250 -0.430430 -1.042565 0.000000 + 0.144197 -0.152625 -1.139141 0.000000 + -0.510137 0.293268 -1.467469 0.000000 + 0.143527 -0.152366 1.627247 0.000000 + -0.474328 -0.708844 0.374591 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 351 + 1 + 0.000000 + + + + + + 0.739048 -0.645267 0.193488 0.000000 + 0.641477 0.586392 -0.494623 0.000000 + 0.205704 0.489668 0.847296 0.000000 + + + + -0.124277 -0.023173 0.170248 0.000000 + + + 352 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 353 + 0 + 48 + 0 0 0 0 + + + 0.310740 0.173688 -1.427836 0.000000 + 0.301504 0.196937 -1.411331 0.000000 + 0.044736 -0.183332 -1.698743 0.000000 + -0.403801 0.247752 -1.754959 0.000000 + 0.310589 0.173968 -1.427606 0.000000 + 0.312311 0.170235 -1.432035 0.000000 + 0.786542 0.250579 1.030478 0.000000 + 0.749602 0.252288 1.032364 0.000000 + 0.530442 0.310772 1.103972 0.000000 + 1.265245 0.094259 0.915635 0.000000 + 1.070183 0.204192 0.872194 0.000000 + 1.356999 0.045825 0.885360 0.000000 + 1.167832 0.182622 0.732024 0.000000 + 1.500589 0.061683 0.469560 0.000000 + 1.378757 0.139413 0.411338 0.000000 + 1.425505 0.012925 0.867270 0.000000 + 1.507434 0.051160 0.385635 0.000000 + 1.371228 0.129659 0.234009 0.000000 + 1.541470 0.027422 0.053130 0.000000 + 1.518725 0.033428 -0.069547 0.000000 + 1.347312 0.112042 -0.164073 0.000000 + 1.416996 0.032901 -0.265866 0.000000 + 1.151233 0.116368 -0.508072 0.000000 + 1.199793 0.017302 -0.683715 0.000000 + 0.977696 0.124612 -0.798916 0.000000 + 0.878889 -0.025162 -1.047996 0.000000 + 0.704468 -0.052461 -1.244501 0.000000 + 0.101343 -0.164999 -1.680452 0.000000 + 0.080782 -0.169414 -1.695011 0.000000 + 0.004266 -0.185581 -1.727811 0.000000 + -0.488317 0.230507 -1.786013 0.000000 + -0.486126 0.220293 -1.784639 0.000000 + 0.008097 -0.184651 -1.731731 0.000000 + -0.521790 0.280427 -1.789951 0.000000 + -0.207104 0.438369 1.224314 0.000000 + -0.200260 0.385594 1.261435 0.000000 + -0.213820 0.409690 1.239112 0.000000 + -0.134194 0.399099 1.224648 0.000000 + -0.823245 0.384976 1.174485 0.000000 + -0.731372 0.440952 1.313073 0.000000 + -0.680994 0.471689 1.328272 0.000000 + -0.821139 0.443082 0.830387 0.000000 + -0.897150 0.405217 -0.333533 0.000000 + -1.006110 0.068798 0.716692 0.000000 + -0.728798 -0.621059 0.450526 0.000000 + -0.364004 -0.563509 0.880516 0.000000 + -0.660224 -0.558163 0.071638 0.000000 + 1.399200 -0.071769 0.833307 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 354 + 1 + 0.000000 + + + + + + 0.900044 0.292528 -0.323028 0.000000 + -0.268001 0.956036 0.119044 0.000000 + 0.343650 -0.020573 0.938872 0.000000 + + + + 0.089682 -0.043406 -0.115440 0.000000 + + + 355 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 356 + 0 + 34 + 0 0 0 0 + + + 1.086981 -0.108901 0.530724 0.000000 + 1.092456 -0.100113 0.524267 0.000000 + 1.204011 -0.100275 0.082502 0.000000 + 1.216415 -0.091105 0.073867 0.000000 + 1.061298 -0.141051 0.548676 0.000000 + 0.884996 -0.461846 0.373327 0.000000 + 1.021122 -0.379231 0.078440 0.000000 + 0.841265 -0.503608 0.345795 0.000000 + 0.883440 -0.501543 0.045681 0.000000 + 0.513185 -0.800225 0.165475 0.000000 + 0.606088 -0.743616 -0.030415 0.000000 + 0.451220 -0.827505 0.143265 0.000000 + 0.472942 -0.800858 -0.086505 0.000000 + 0.026950 -1.005994 0.010090 0.000000 + 0.142197 -0.938077 -0.236247 0.000000 + 0.033253 -0.943587 -0.290070 0.000000 + -0.033683 -1.012441 -0.001534 0.000000 + -0.415280 -1.050627 -0.040138 0.000000 + 0.040952 -0.944491 -0.296411 0.000000 + -0.976315 0.769998 0.196800 0.000000 + -0.958188 0.784896 0.216957 0.000000 + -0.973784 0.788619 0.162836 0.000000 + 0.316278 0.842509 -0.300423 0.000000 + -0.027504 1.087879 -0.025507 0.000000 + 0.714170 0.604680 0.163373 0.000000 + 0.861004 0.481852 -0.073676 0.000000 + 1.079172 0.195468 -0.117920 0.000000 + 0.418572 0.423209 -0.601001 0.000000 + -1.075786 0.032172 -0.174645 0.000000 + -1.148976 0.146783 -0.085874 0.000000 + -0.020288 -0.037661 -0.688980 0.000000 + -1.183380 0.015807 -0.125330 0.000000 + -1.166252 -0.560474 0.113515 0.000000 + -0.936595 0.188994 0.480457 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 357 + 1 + 0.000000 + + + + + + 0.888870 0.064878 0.453542 0.000000 + -0.268007 0.876514 0.399869 0.000000 + -0.371593 -0.476984 0.796495 0.000000 + + + + -0.143654 0.052339 -0.171384 0.000000 + + + 358 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 359 + 0 + 36 + 0 0 0 0 + + + 1.187243 0.019130 -0.351717 0.000000 + 1.282576 -0.056208 -0.104277 0.000000 + 1.180459 -0.087498 -0.459568 0.000000 + 1.034073 0.373494 -0.056431 0.000000 + 1.069783 0.376232 0.141309 0.000000 + 1.008755 0.428900 -0.012864 0.000000 + 0.720331 0.716060 0.249294 0.000000 + 0.711490 0.719803 0.246073 0.000000 + 0.703251 0.718574 0.156737 0.000000 + 0.697880 0.729064 0.156381 0.000000 + 0.935285 0.511907 0.214585 0.000000 + 1.109265 0.378253 0.181932 0.000000 + 1.129668 0.361517 0.182798 0.000000 + 1.448681 -0.018517 0.173042 0.000000 + 1.540971 -0.129544 0.176462 0.000000 + 1.333197 -0.328612 -0.231476 0.000000 + 1.583823 -0.207402 0.181146 0.000000 + 1.631535 -0.281671 0.182320 0.000000 + 1.179415 -0.152520 -0.529054 0.000000 + 1.267509 -0.346214 -0.463971 0.000000 + -1.116167 0.387351 -0.353853 0.000000 + -0.815099 0.523657 -0.649009 0.000000 + -0.774750 0.289625 -0.880800 0.000000 + -1.159987 0.198644 -0.442763 0.000000 + -0.281502 -0.042556 -1.015794 0.000000 + 0.000282 -0.493305 -0.837839 0.000000 + -1.083275 -0.564602 0.184617 0.000000 + -1.048609 -0.555738 0.299706 0.000000 + -0.920149 0.274062 0.413812 0.000000 + -0.562492 -0.467994 0.874497 0.000000 + 0.071592 -0.401081 0.820363 0.000000 + -0.438872 -0.257916 1.001974 0.000000 + -0.441326 -0.187810 0.993439 0.000000 + -0.582116 0.273338 0.815449 0.000000 + 0.126496 0.479737 0.676944 0.000000 + 0.134916 0.482792 0.672993 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 360 + 1 + 0.000000 + + + + + + 0.815991 0.396335 -0.420806 0.000000 + -0.281474 0.908245 0.309617 0.000000 + 0.504907 -0.134199 0.852678 0.000000 + + + + 0.063921 0.174658 -0.301427 0.000000 + + + 361 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 362 + 0 + 57 + 0 0 0 0 + + + 1.292580 -0.115704 0.009470 0.000000 + 0.974122 -0.285433 -1.507742 0.000000 + 0.744918 0.171449 -1.330760 0.000000 + 0.956607 0.224854 0.262013 0.000000 + 0.380450 0.526946 -1.147946 0.000000 + 0.536850 0.420917 0.541426 0.000000 + -0.083697 0.746285 -0.977165 0.000000 + 0.074319 0.453253 0.820400 0.000000 + -0.602182 0.807959 -0.835121 0.000000 + -0.385756 0.318609 1.071640 0.000000 + 1.051911 -0.280325 -1.315669 0.000000 + 1.308896 -0.121441 -0.025152 0.000000 + 0.988113 -0.308404 -1.535603 0.000000 + 1.008096 -0.319606 -1.681336 0.000000 + 0.998576 -0.279923 -1.672951 0.000000 + 0.984966 -0.209834 -1.677387 0.000000 + 0.797147 0.179019 -1.616773 0.000000 + 0.745341 0.280812 -1.603805 0.000000 + 0.467931 0.558497 -1.485869 0.000000 + 0.377633 0.646412 -1.450918 0.000000 + 0.014921 0.809628 -1.277358 0.000000 + -0.083519 0.852582 -1.233115 0.000000 + -0.531822 0.876351 -1.001438 0.000000 + -0.594738 0.878943 -0.970911 0.000000 + -0.907888 0.755625 -0.733545 0.000000 + -0.796814 0.818777 -0.855896 0.000000 + -1.045216 0.691382 -0.571286 0.000000 + -1.065892 0.672111 -0.541139 0.000000 + -0.798334 0.030069 1.270533 0.000000 + -1.307643 0.338300 -0.015336 0.000000 + -1.226961 0.522056 -0.354918 0.000000 + -1.412855 -0.218606 0.727936 0.000000 + -1.347150 -0.212395 0.832119 0.000000 + -1.405229 -0.204596 0.693008 0.000000 + -1.195771 -0.191193 1.044187 0.000000 + -1.351749 0.089292 0.317046 0.000000 + -1.013899 -0.164241 1.303339 0.000000 + -0.987963 -0.157637 1.308225 0.000000 + -0.719712 0.027371 1.393309 0.000000 + -0.674874 0.049246 1.409343 0.000000 + -0.162188 0.253703 1.490315 0.000000 + -0.002252 0.310390 1.518627 0.000000 + 0.400666 0.377104 1.526753 0.000000 + 0.684432 0.418160 1.536481 0.000000 + 0.938493 0.398201 1.504649 0.000000 + 1.276271 0.365664 1.460806 0.000000 + 1.269883 0.374821 1.464324 0.000000 + 1.365162 0.316487 1.346818 0.000000 + 1.600548 0.180653 1.057031 0.000000 + 1.674734 0.070846 0.917121 0.000000 + 1.416240 -0.074612 0.186077 0.000000 + 1.688425 0.070463 0.901666 0.000000 + 0.124827 -0.548140 0.981170 0.000000 + 1.242119 -0.075159 1.173470 0.000000 + -0.494108 -0.896256 -0.766273 0.000000 + -0.971111 0.297295 -0.690120 0.000000 + -0.451181 -0.889747 -0.862521 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 363 + 1 + 0.000000 + + + + + + 0.785128 -0.081658 0.613927 0.000000 + 0.298411 0.918494 -0.259458 0.000000 + -0.542701 0.386911 0.745503 0.000000 + + + + -0.216586 0.091476 0.004375 0.000000 + + + 364 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 365 + 0 + 38 + 0 0 0 0 + + + 1.195942 0.549982 0.304843 0.000000 + 0.239964 0.504323 -0.422600 0.000000 + 0.181247 0.895236 -0.052628 0.000000 + 0.997960 0.760891 0.381421 0.000000 + 1.430483 0.300799 0.221726 0.000000 + 1.450415 0.164075 0.160962 0.000000 + 0.230527 0.021489 -0.667568 0.000000 + 1.484562 0.228170 0.207222 0.000000 + 1.318951 -0.126407 -0.067262 0.000000 + 1.139842 -0.384197 -0.201322 0.000000 + 0.153839 -0.505966 -0.763472 0.000000 + 0.981585 -0.617242 -0.315812 0.000000 + 0.836927 -0.779382 -0.357367 0.000000 + 0.141973 -0.568063 -0.764562 0.000000 + -0.277533 -0.489293 -0.855172 0.000000 + -0.270327 -0.491854 -0.848462 0.000000 + -0.243402 -0.399464 -0.858042 0.000000 + -0.211930 0.043006 -0.787086 0.000000 + -0.208924 0.146419 -0.769906 0.000000 + -0.283485 0.543212 -0.598528 0.000000 + -0.311770 0.664885 -0.545312 0.000000 + -0.465347 0.967434 -0.312897 0.000000 + -0.541858 1.104750 -0.206451 0.000000 + -0.361260 1.218351 0.147178 0.000000 + -0.730441 1.288714 0.035284 0.000000 + -0.744688 1.304793 0.053327 0.000000 + -0.736647 1.329441 0.086846 0.000000 + 0.102133 1.085102 0.225580 0.000000 + 0.688517 0.885159 0.331115 0.000000 + 0.969431 0.790572 0.381531 0.000000 + -1.136817 -0.731172 0.523415 0.000000 + -0.079314 -0.911225 0.630027 0.000000 + -0.005421 -0.831913 0.649318 0.000000 + -1.135210 -0.732283 0.510967 0.000000 + -1.244566 0.225538 0.300180 0.000000 + -1.215663 -0.606890 0.105025 0.000000 + -0.849533 1.207208 0.111158 0.000000 + 1.103697 0.130132 0.537789 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 366 + 1 + 0.000000 + + + + + + 0.713805 0.101503 -0.692950 0.000000 + -0.511430 0.751509 -0.416742 0.000000 + 0.478457 0.651868 0.588342 0.000000 + + + + 0.268277 0.029150 -0.011397 0.000000 + + + 367 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 368 + 0 + 34 + 0 0 0 0 + + + 0.128394 1.176994 -0.441059 0.000000 + 0.098214 1.151236 -0.402748 0.000000 + 0.134951 1.183831 -0.444649 0.000000 + -0.160291 1.064528 -0.174482 0.000000 + 0.004258 0.916231 -0.635623 0.000000 + -0.213827 1.025438 -0.146394 0.000000 + -0.038984 0.739644 -0.707105 0.000000 + -0.507647 0.697976 0.088562 0.000000 + 0.059488 -1.234180 0.227541 0.000000 + 0.005222 -1.177801 0.237457 0.000000 + 0.039349 -1.173727 0.083600 0.000000 + -0.296628 -0.919909 0.339273 0.000000 + -0.001441 -1.060277 -0.280854 0.000000 + -0.409246 -0.764078 0.389441 0.000000 + 0.000238 -0.800541 -0.813677 0.000000 + 0.005604 -0.816285 -0.808160 0.000000 + -0.692650 -0.366077 0.524488 0.000000 + -0.033292 -0.720673 -0.853919 0.000000 + -0.720979 -0.289458 0.545914 0.000000 + -0.116137 -0.291324 -0.915225 0.000000 + -0.829266 0.146927 0.566317 0.000000 + -0.133623 -0.187988 -0.931137 0.000000 + -0.856830 0.060573 0.649244 0.000000 + -0.817702 0.169745 0.538756 0.000000 + -0.126025 0.237664 -0.873836 0.000000 + -0.591201 0.604809 0.162798 0.000000 + -0.121004 0.375738 -0.856283 0.000000 + 0.248754 1.122530 -0.288475 0.000000 + 0.600111 0.933161 0.211528 0.000000 + 0.665948 0.356586 0.199588 0.000000 + 0.711288 -0.647272 0.297557 0.000000 + 0.754156 -0.560644 0.225295 0.000000 + 0.553490 0.889259 0.292133 0.000000 + 0.381045 0.529562 0.614608 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 369 + 1 + 0.000000 + + + + + + 0.970878 0.012669 -0.239241 0.000000 + 0.151980 0.739376 0.655915 0.000000 + 0.185199 -0.673173 0.715919 0.000000 + + + + 0.011299 0.150707 -0.040963 0.000000 + + + 370 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 371 + 0 + 30 + 0 0 0 0 + + + 0.967211 0.201787 0.902247 0.000000 + 1.004035 0.155460 0.903515 0.000000 + 0.962719 0.206682 0.898613 0.000000 + 0.554646 0.303098 0.837760 0.000000 + 0.912140 0.170859 0.974814 0.000000 + 0.040943 0.481274 0.749247 0.000000 + 0.085009 0.392637 0.873834 0.000000 + 0.910007 0.167580 0.978980 0.000000 + 0.057614 0.180545 1.054639 0.000000 + 0.561804 -0.081028 1.237848 0.000000 + 0.090315 -0.419733 1.424731 0.000000 + 0.146924 -0.378857 1.399054 0.000000 + -0.099214 -0.260534 1.327379 0.000000 + -0.169985 -0.360238 1.393910 0.000000 + 0.490353 -0.134448 1.291185 0.000000 + 0.024850 -0.025665 1.229300 0.000000 + 0.334969 -0.035991 -1.633820 0.000000 + 0.193410 -0.037825 -1.688709 0.000000 + 0.095701 0.065032 -1.661043 0.000000 + 0.066007 0.135321 -1.619091 0.000000 + 0.433953 0.011840 -1.573868 0.000000 + 0.247106 -0.099367 -1.711073 0.000000 + -0.925452 -0.189043 0.331781 0.000000 + -0.866400 -0.209760 0.469362 0.000000 + -0.919222 -0.164535 0.333173 0.000000 + -0.662544 -0.277456 -0.209166 0.000000 + -0.639755 0.604901 -0.126571 0.000000 + 0.667175 -0.008054 -1.258123 0.000000 + 0.265088 -0.279857 -1.539216 0.000000 + 0.006318 -0.470845 -0.969060 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 372 + 1 + 0.000000 + + + + + + 0.901322 -0.432537 0.023026 0.000000 + 0.432500 0.901608 0.006806 0.000000 + -0.023705 0.003824 0.999712 0.000000 + + + + -0.032484 0.144918 -0.056613 0.000000 + + + 373 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 374 + 0 + 28 + 0 0 0 0 + + + 0.667295 0.018419 0.204851 0.000000 + -0.075664 0.334666 -0.251745 0.000000 + 0.574943 0.014786 0.461512 0.000000 + 0.534099 0.004755 -0.269947 0.000000 + 0.180997 0.120487 -0.677388 0.000000 + 0.658997 0.001131 0.035171 0.000000 + 0.442657 0.022291 -0.496467 0.000000 + 0.240653 -0.009396 -0.862078 0.000000 + 0.138159 0.149690 -0.784455 0.000000 + 0.244462 -0.008211 -0.901247 0.000000 + 0.113805 0.180245 -0.765815 0.000000 + -0.184082 0.402577 -0.496244 0.000000 + -0.241617 0.442113 -0.448967 0.000000 + -0.291341 0.391197 0.092428 0.000000 + -0.354840 0.478066 -0.350381 0.000000 + -0.273771 0.363887 0.219914 0.000000 + 0.486726 0.006920 0.714143 0.000000 + -0.263924 0.351972 0.252142 0.000000 + 0.298868 -0.039106 0.904741 0.000000 + 0.014443 -0.025382 0.986683 0.000000 + -0.199121 0.050266 0.879472 0.000000 + -0.191527 0.030245 0.934408 0.000000 + 0.189130 -0.066944 1.027128 0.000000 + -0.430003 -0.413723 -0.023263 0.000000 + -0.406044 -0.030135 -0.328967 0.000000 + 0.081573 -0.303177 -0.786088 0.000000 + 0.067714 -0.306557 -0.780664 0.000000 + -0.390512 -0.373926 0.174964 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 375 + 1 + 0.000000 + + + + + + 0.662539 0.441647 0.604970 0.000000 + -0.669354 0.711585 0.213570 0.000000 + -0.336165 -0.546438 0.767071 0.000000 + + + + 0.070972 0.054560 -0.024852 0.000000 + + + 376 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 377 + 0 + 40 + 0 0 0 0 + + + -0.088406 -0.746036 0.553685 0.000000 + -0.161188 -0.792723 0.336471 0.000000 + -0.081333 -0.789196 0.517614 0.000000 + -0.119487 -0.290303 0.789070 0.000000 + -0.321428 -0.276799 0.374327 0.000000 + -0.121194 -0.181620 0.847019 0.000000 + -0.064081 0.230345 0.954555 0.000000 + -0.324257 0.264337 0.354563 0.000000 + -0.073376 0.328319 0.919312 0.000000 + -0.060040 0.283634 0.975345 0.000000 + -0.165138 0.746752 0.367449 0.000000 + -0.169455 0.777648 0.279137 0.000000 + -0.169033 0.768359 0.339542 0.000000 + -0.165264 0.822067 0.245440 0.000000 + -0.269964 0.964468 -0.452466 0.000000 + -0.116198 1.057284 -0.156666 0.000000 + -0.361948 0.848046 -0.465335 0.000000 + -0.295038 0.961240 -0.491270 0.000000 + -0.460459 0.527335 -0.417358 0.000000 + -0.519384 0.330172 -0.392084 0.000000 + -0.516603 -0.025874 -0.367185 0.000000 + -0.513636 -0.217606 -0.357655 0.000000 + -0.399925 -0.574104 -0.360515 0.000000 + -0.344961 -0.741599 -0.365501 0.000000 + -0.059089 -1.162660 -0.437808 0.000000 + -0.029695 -1.190270 -0.414905 0.000000 + -0.062313 -1.175166 -0.421218 0.000000 + -0.064346 -1.094503 -0.195891 0.000000 + -0.122701 -1.059807 -0.398026 0.000000 + -0.073705 -0.956976 0.293718 0.000000 + -0.053468 -0.887624 0.439363 0.000000 + 0.506267 0.352525 0.271127 0.000000 + 0.607984 0.345720 0.150343 0.000000 + 0.583021 0.392246 0.137949 0.000000 + 0.616593 0.068044 0.019096 0.000000 + 0.370081 -0.239295 -0.577478 0.000000 + 0.114158 0.625388 -0.563271 0.000000 + 0.307069 0.764414 -0.144518 0.000000 + 0.303113 -0.687910 0.062508 0.000000 + 0.021761 -1.106929 -0.443784 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 378 + 1 + 0.000000 + + + + + + 0.984043 0.120661 -0.130767 0.000000 + -0.091149 0.973027 0.211920 0.000000 + 0.152811 -0.196619 0.968499 0.000000 + + + + -0.159084 0.029071 -0.041940 0.000000 + + + 379 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 380 + 0 + 30 + 0 0 0 0 + + + 1.098363 -0.101743 -0.555502 0.000000 + 1.023508 -0.112730 -0.625956 0.000000 + 0.984159 -0.123254 -0.619511 0.000000 + 1.096733 -0.142445 -0.555964 0.000000 + -0.705796 0.368336 -0.522399 0.000000 + -0.693682 0.361968 -0.555772 0.000000 + -0.737362 0.360500 -0.513959 0.000000 + -0.256369 0.152801 0.692986 0.000000 + -0.200673 0.154549 0.707612 0.000000 + -0.794949 0.293954 -0.003754 0.000000 + -0.834566 0.207963 0.233481 0.000000 + 0.141284 0.194665 0.797051 0.000000 + 0.238922 0.242341 0.687935 0.000000 + -0.786325 0.321424 -0.085329 0.000000 + 0.299714 0.249010 0.622115 0.000000 + -0.604417 0.361951 -0.527873 0.000000 + 0.618033 0.274352 0.296653 0.000000 + -0.572890 0.361962 -0.531569 0.000000 + 0.651633 0.262961 0.262412 0.000000 + 0.014152 0.245700 -0.572075 0.000000 + 0.913722 0.143007 -0.118528 0.000000 + 0.240663 0.198261 -0.590106 0.000000 + 0.831613 0.200105 0.090252 0.000000 + 0.922159 0.128211 -0.146535 0.000000 + 0.577619 0.056648 -0.600754 0.000000 + 0.344897 -0.242230 0.685577 0.000000 + 0.860845 -0.139625 0.134773 0.000000 + -0.137329 -0.319997 0.551323 0.000000 + -0.708922 -0.422151 0.018401 0.000000 + -0.624287 -0.402131 -0.412611 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 381 + 1 + 0.000000 + + + + + + 0.917718 -0.322024 0.232582 0.000000 + 0.302404 0.946021 0.116603 0.000000 + -0.257577 -0.036675 0.965562 0.000000 + + + + -0.087164 0.225096 0.037935 0.000000 + + + 382 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 383 + 0 + 62 + 0 0 0 0 + + + 0.643738 0.639166 -1.358966 0.000000 + -0.538551 0.585390 0.034366 0.000000 + -0.081856 0.664968 0.313477 0.000000 + 1.159965 0.547453 -1.224739 0.000000 + 0.367820 0.575621 0.601102 0.000000 + 0.112842 0.588945 -1.432605 0.000000 + 0.161376 0.595085 -1.432893 0.000000 + 0.114319 0.593970 -1.429238 0.000000 + -0.957605 0.344759 -0.208941 0.000000 + -0.443446 0.352496 -1.378106 0.000000 + -0.526210 0.290692 -1.358806 0.000000 + -1.298076 -0.033335 -0.392681 0.000000 + -0.912830 -0.024746 -1.283083 0.000000 + -1.040937 -0.203128 -1.233444 0.000000 + -1.526719 -0.511910 -0.498917 0.000000 + -1.050743 -0.194492 -1.233564 0.000000 + -1.477140 -0.467504 -0.620930 0.000000 + -1.551668 -0.517928 -0.490746 0.000000 + -1.908717 -0.625636 -0.137600 0.000000 + -1.924144 -0.604424 -0.108243 0.000000 + -1.857751 -0.635290 -0.192441 0.000000 + -2.014129 -0.496989 0.010643 0.000000 + -1.993541 -0.425951 0.021415 0.000000 + -1.891185 -0.195371 0.078286 0.000000 + -1.778020 0.060861 0.147519 0.000000 + -1.634565 0.238975 0.247095 0.000000 + -1.465759 0.448654 0.371032 0.000000 + -1.295986 0.561677 0.501986 0.000000 + -1.087416 0.699510 0.669986 0.000000 + -0.906622 0.740229 0.819854 0.000000 + -0.680053 0.789001 1.015072 0.000000 + -0.503831 0.754921 1.170519 0.000000 + -0.283481 0.708490 1.372540 0.000000 + -0.127464 0.602135 1.519574 0.000000 + 0.766448 0.325998 0.869089 0.000000 + 0.014062 0.522393 1.650561 0.000000 + 0.089087 0.489158 1.633807 0.000000 + 0.660329 0.143402 1.412458 0.000000 + 1.074956 -0.059541 1.091178 0.000000 + 0.855831 0.021619 1.337288 0.000000 + 1.185339 -0.256829 1.139320 0.000000 + 1.600877 -0.660624 0.559772 0.000000 + 1.448892 -0.590110 0.875169 0.000000 + 1.474034 -0.622010 0.847704 0.000000 + 1.703614 -0.690889 0.343357 0.000000 + 1.723596 -0.529470 0.206129 0.000000 + 1.402342 -0.513000 0.945075 0.000000 + 1.700277 -0.307604 -0.011190 0.000000 + 1.671593 -0.045524 -0.278285 0.000000 + 1.613359 0.070201 -0.425283 0.000000 + 1.476213 0.337802 -0.777916 0.000000 + 1.434798 0.370666 -0.837099 0.000000 + 1.209443 0.546758 -1.163756 0.000000 + 1.146926 0.592115 -1.249351 0.000000 + 1.140779 0.591296 -1.263831 0.000000 + 0.692818 0.670651 -1.444118 0.000000 + 0.977499 0.635703 -1.423367 0.000000 + 0.659686 0.674462 -1.448477 0.000000 + 0.712300 -0.723450 -0.347969 0.000000 + 0.127928 -0.282281 -1.173243 0.000000 + -1.490653 -0.448808 0.447973 0.000000 + -1.304486 -0.566463 0.371529 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 384 + 1 + 0.000000 + + + + + + 0.699535 0.535495 -0.473177 0.000000 + -0.170938 0.768329 0.616807 0.000000 + 0.693853 -0.350594 0.629009 0.000000 + + + + -0.348556 -0.075106 -0.244480 0.000000 + + + 385 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 386 + 0 + 33 + 0 0 0 0 + + + 0.169403 -0.156645 0.601578 0.000000 + 0.184314 0.338458 -0.877206 0.000000 + 0.175227 0.751586 -0.528150 0.000000 + -0.004271 0.234643 0.932228 0.000000 + 0.178385 -0.586350 0.273142 0.000000 + 0.187633 0.243141 -0.892030 0.000000 + 0.095985 -0.157018 -0.930066 0.000000 + 0.251620 0.376636 -0.902758 0.000000 + 0.261348 0.410481 -0.911562 0.000000 + 0.322578 0.867467 -0.799338 0.000000 + 0.339670 0.998540 -0.773659 0.000000 + 0.266964 1.155527 -0.630778 0.000000 + 0.116340 0.929578 -0.365721 0.000000 + 0.055824 0.803848 0.175256 0.000000 + -0.174792 0.425034 1.148190 0.000000 + 0.063565 0.167379 1.117319 0.000000 + -0.157660 0.449884 1.110537 0.000000 + 0.124609 0.083653 1.126787 0.000000 + 0.295312 -0.277935 1.042525 0.000000 + 0.376010 -0.456061 1.005735 0.000000 + 0.396181 -0.636651 0.897784 0.000000 + 0.383237 -0.669342 0.821567 0.000000 + 0.348600 -0.773511 0.590322 0.000000 + 0.116168 -0.800621 0.061528 0.000000 + 0.066272 -0.227409 -0.948002 0.000000 + 0.067770 -0.867356 -0.177804 0.000000 + 0.056397 -0.868594 -0.226364 0.000000 + -0.020424 -0.640769 -0.679579 0.000000 + 0.074932 -0.244798 -0.940421 0.000000 + -0.210965 0.266701 0.898836 0.000000 + -0.366291 -0.159608 -0.077443 0.000000 + -0.336196 -0.141493 -0.403037 0.000000 + -0.170505 -0.350167 -0.665908 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 387 + 1 + 0.000000 + + + + + + 0.875996 -0.480893 -0.037042 0.000000 + 0.370485 0.720070 -0.586720 0.000000 + 0.308822 0.500241 0.808942 0.000000 + + + + -0.271513 -0.011639 -0.019090 0.000000 + + + 388 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 389 + 0 + 78 + 0 0 0 0 + + + -1.176981 -0.258271 -1.622161 0.000000 + 1.330066 -0.324723 -1.032338 0.000000 + 1.154358 -0.768169 -0.775819 0.000000 + -1.373209 -0.590517 -1.242126 0.000000 + 0.933711 -1.095073 -0.404649 0.000000 + -1.546295 -0.784337 -0.766981 0.000000 + 0.689762 -1.273394 0.044771 0.000000 + -1.679279 -0.820762 -0.243325 0.000000 + 0.446429 -1.285685 0.528367 0.000000 + -1.759144 -0.696283 0.277508 0.000000 + 0.227560 -1.130803 0.998738 0.000000 + -0.976853 0.179833 -1.869815 0.000000 + 1.443611 0.191776 -1.149063 0.000000 + 2.167277 -0.314605 -0.511947 0.000000 + 2.224947 -0.089990 -0.559020 0.000000 + 2.022953 -0.586939 -0.381707 0.000000 + 1.930259 -0.763731 -0.292654 0.000000 + 1.724313 -0.980918 -0.090655 0.000000 + 1.615080 -1.096309 0.021433 0.000000 + 1.359210 -1.226225 0.285210 0.000000 + 1.252544 -1.279506 0.399631 0.000000 + 0.966646 -1.292793 0.706029 0.000000 + 0.878201 -1.295169 0.804856 0.000000 + 0.590045 -1.170748 1.125421 0.000000 + 0.528793 -1.141657 1.197324 0.000000 + 0.271932 -0.872836 1.496084 0.000000 + 0.054579 -0.824000 1.409815 0.000000 + 0.238617 -0.833975 1.538508 0.000000 + 0.048063 -0.434062 1.776189 0.000000 + -0.055604 -0.395396 1.721389 0.000000 + 0.036156 -0.402258 1.794921 0.000000 + -0.058246 0.092306 1.935928 0.000000 + -0.092246 0.113003 1.903032 0.000000 + -0.058692 0.111184 1.941367 0.000000 + -0.063929 0.340389 1.927455 0.000000 + -0.041821 0.369738 1.954292 0.000000 + -0.279295 0.200027 1.841074 0.000000 + -0.366734 0.150667 1.804315 0.000000 + -0.778925 -0.035460 1.546930 0.000000 + -1.139953 -0.188694 1.320897 0.000000 + -1.322223 -0.240860 1.174725 0.000000 + -1.693763 -0.461128 0.767292 0.000000 + -1.574798 -0.314065 0.972750 0.000000 + -1.698882 -0.466023 0.755505 0.000000 + -1.745684 -0.502810 0.655519 0.000000 + -1.911291 -0.626117 0.295017 0.000000 + -1.934099 -0.636703 0.251527 0.000000 + -1.972883 -0.642322 0.147820 0.000000 + -1.897133 -0.730918 -0.194835 0.000000 + -1.884693 -0.745886 -0.256665 0.000000 + -1.747371 -0.721365 -0.732779 0.000000 + -1.733942 -0.716545 -0.785148 0.000000 + -1.578747 -0.538677 -1.221750 0.000000 + -1.564548 -0.517932 -1.266807 0.000000 + -1.307955 -0.248165 -1.617642 0.000000 + -1.518837 -0.448218 -1.359869 0.000000 + -1.289879 -0.228660 -1.640567 0.000000 + -0.956118 0.155674 -1.879847 0.000000 + -0.957089 0.157185 -1.879356 0.000000 + -0.907064 0.233847 -1.889333 0.000000 + -0.632872 0.628947 -1.921805 0.000000 + -0.198236 0.654646 -1.750920 0.000000 + -0.615165 0.649589 -1.917594 0.000000 + -0.565986 0.736407 -1.898146 0.000000 + 1.453238 0.293086 -1.150534 0.000000 + 1.798943 0.252460 -0.927155 0.000000 + 2.202348 0.191011 -0.672175 0.000000 + 2.193498 0.203675 -0.680712 0.000000 + 2.200179 0.192311 -0.679179 0.000000 + 2.226665 -0.084731 -0.561765 0.000000 + 0.655804 1.017345 1.218964 0.000000 + 0.316049 1.390524 1.250108 0.000000 + 0.185969 0.807285 1.739262 0.000000 + -0.620302 1.507975 0.084228 0.000000 + 0.262739 1.545859 1.030975 0.000000 + -1.912498 -0.403370 0.139556 0.000000 + -1.696216 0.051530 0.431992 0.000000 + 1.896509 0.294417 -0.195375 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 390 + 1 + 0.000000 + + + + + + 0.832957 0.089344 0.546077 0.000000 + 0.008210 0.984775 -0.173642 0.000000 + -0.553276 0.149119 0.819542 0.000000 + + + + 0.045315 0.135490 -0.031806 0.000000 + + + 391 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 392 + 0 + 43 + 0 0 0 0 + + + 0.733411 0.178117 -0.724698 0.000000 + 1.353613 0.240968 -0.490448 0.000000 + 1.114084 0.185023 -0.687794 0.000000 + -1.101936 0.186372 -0.587406 0.000000 + 0.034246 0.158851 -0.780649 0.000000 + -1.066547 0.057555 -0.788646 0.000000 + -1.117995 0.232991 -0.453099 0.000000 + 0.426009 0.272176 -0.375788 0.000000 + 0.401750 0.175101 -0.758490 0.000000 + -1.172722 0.366221 -0.052088 0.000000 + -1.176072 0.368859 0.026658 0.000000 + 0.447756 0.281025 0.164923 0.000000 + -1.207800 0.376381 0.503996 0.000000 + -1.206012 0.373113 0.518549 0.000000 + 0.465975 0.122296 0.681914 0.000000 + -0.968235 0.279969 0.776330 0.000000 + -0.175829 0.193985 0.771070 0.000000 + -1.205360 0.380050 0.517556 0.000000 + 0.472662 0.105220 0.740920 0.000000 + 0.790756 0.114673 0.773153 0.000000 + 0.897318 0.158144 0.717278 0.000000 + 0.832601 0.120015 0.782204 0.000000 + 1.118213 0.254903 0.439043 0.000000 + 1.281921 0.320070 0.239712 0.000000 + 1.420473 0.318490 0.020189 0.000000 + 1.478972 0.317119 -0.253704 0.000000 + 1.465272 0.324246 -0.052798 0.000000 + 1.449682 0.269959 -0.414310 0.000000 + 1.466310 0.293103 -0.333297 0.000000 + -0.855011 -0.410211 0.155135 0.000000 + -0.942679 -0.227879 0.303842 0.000000 + -1.016229 -0.302941 0.121810 0.000000 + -0.999124 -0.385601 0.024875 0.000000 + -0.989106 -0.388179 -0.282946 0.000000 + 0.109668 -0.607663 0.078208 0.000000 + 0.093032 -0.607251 0.065168 0.000000 + 0.582378 -0.511801 0.027468 0.000000 + 0.960469 -0.383706 -0.059715 0.000000 + 1.062073 -0.334049 -0.011273 0.000000 + 1.061977 -0.320138 0.079176 0.000000 + 1.026306 -0.323907 0.134298 0.000000 + 0.853637 -0.140074 0.537872 0.000000 + 1.360918 0.165732 -0.323681 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 393 + 1 + 0.000000 + + + + + + 0.919434 -0.058025 0.388940 0.000000 + -0.172248 0.829703 0.530965 0.000000 + -0.353514 -0.555181 0.752863 0.000000 + + + + -0.027422 -0.159819 -0.044034 0.000000 + + + 394 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 395 + 0 + 46 + 0 0 0 0 + + + -0.075691 -0.299810 -0.396426 0.000000 + 1.479205 -0.562648 0.518706 0.000000 + -0.288447 -0.363354 0.097036 0.000000 + 0.127904 -0.073585 -0.843965 0.000000 + 1.825405 -0.360531 0.155105 0.000000 + 0.714150 -0.554509 0.646254 0.000000 + 1.468206 -0.576710 0.450146 0.000000 + 0.352594 -0.464924 0.722466 0.000000 + -0.489552 -0.258092 0.588142 0.000000 + -0.054681 -0.357127 0.815224 0.000000 + -0.649535 -0.066407 0.921865 0.000000 + -1.143344 0.102349 1.030694 0.000000 + -1.157280 0.086170 1.010287 0.000000 + -1.024335 0.056143 0.996426 0.000000 + -1.334945 -0.053972 0.825788 0.000000 + -0.835215 -0.022922 0.963053 0.000000 + -1.331719 -0.059924 0.829003 0.000000 + -1.403091 -0.164751 0.621652 0.000000 + -1.520370 -0.328768 0.289910 0.000000 + -1.534008 -0.354947 0.163192 0.000000 + -1.587397 -0.440018 -0.277077 0.000000 + -1.577992 -0.433675 -0.344123 0.000000 + -1.525492 -0.380155 -0.810224 0.000000 + -1.501609 -0.355683 -0.862727 0.000000 + -0.950132 -0.162206 -1.117666 0.000000 + -1.440892 -0.284102 -1.024570 0.000000 + 0.260150 0.170811 -1.123713 0.000000 + 0.168487 0.174692 -1.165509 0.000000 + 1.900764 -0.006410 -0.271410 0.000000 + 1.017332 0.116829 -0.764675 0.000000 + 1.903765 0.056889 -0.322719 0.000000 + 1.891536 -0.043930 -0.232878 0.000000 + 1.823830 -0.338607 0.082545 0.000000 + 1.807939 -0.399535 0.148294 0.000000 + 1.810844 -0.397085 0.153926 0.000000 + 1.455810 -0.574062 0.458510 0.000000 + 1.725918 -0.523948 0.377917 0.000000 + 1.462811 -0.572318 0.457565 0.000000 + -0.092734 0.659690 0.166770 0.000000 + -0.875569 0.488733 0.369118 0.000000 + -1.086648 0.227556 0.862928 0.000000 + -1.101646 0.154232 1.011800 0.000000 + 0.017740 0.433879 0.662739 0.000000 + 1.749252 0.142338 -0.158663 0.000000 + 0.009158 0.656018 0.085799 0.000000 + 1.484543 0.056381 0.326930 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 396 + 1 + 0.000000 + + + + + + 0.917693 0.194250 -0.346563 0.000000 + -0.051730 0.923316 0.380542 0.000000 + 0.393907 -0.331293 0.857369 0.000000 + + + + 0.000230 -0.275686 -0.191821 0.000000 + + + 397 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 398 + 0 + 34 + 0 0 0 0 + + + 0.091387 -0.662306 0.745082 0.000000 + -1.321391 0.066409 -0.130603 0.000000 + -1.230051 -0.403146 -0.384562 0.000000 + 0.256730 -0.830594 0.779423 0.000000 + -0.309824 -0.226896 0.667617 0.000000 + -0.762830 0.980845 0.383458 0.000000 + -0.721412 0.987693 0.383581 0.000000 + -0.666217 1.067370 0.392464 0.000000 + -0.821295 0.904870 0.352548 0.000000 + -0.704905 0.841005 0.419471 0.000000 + -1.125490 0.514045 0.182602 0.000000 + -0.646762 0.400093 0.531140 0.000000 + -1.137528 0.484277 0.166297 0.000000 + -0.507400 0.134041 0.587484 0.000000 + -1.304525 0.083318 -0.071113 0.000000 + -1.320742 0.031156 -0.093434 0.000000 + -1.318919 0.037512 -0.094515 0.000000 + -1.295887 -0.381590 -0.435953 0.000000 + -1.294529 -0.396933 -0.453718 0.000000 + -1.156937 -0.547626 -0.504937 0.000000 + -1.231572 -0.533423 -0.601607 0.000000 + -0.358198 -0.760135 0.132897 0.000000 + 0.446312 -0.991004 0.786639 0.000000 + 0.439998 -0.977195 0.804186 0.000000 + 0.652636 0.870619 -0.378446 0.000000 + -0.466363 1.143433 0.355625 0.000000 + 0.800511 0.289668 0.439985 0.000000 + 1.084311 0.487178 -0.200927 0.000000 + 1.073563 0.093290 -0.372396 0.000000 + 1.015846 0.024265 -0.434592 0.000000 + 0.518456 0.379177 -0.689895 0.000000 + 1.042365 -0.154547 -0.395450 0.000000 + 0.944207 -0.553462 -0.318626 0.000000 + -0.603298 -0.430267 -0.811780 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 399 + 1 + 0.000000 + + + + + + 0.771723 -0.054771 -0.633596 0.000000 + 0.316118 0.897522 0.307447 0.000000 + 0.551827 -0.437555 0.709953 0.000000 + + + + -0.195184 0.092964 0.271780 0.000000 + + + 400 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 401 + 0 + 36 + 0 0 0 0 + + + -0.110244 -0.681566 -0.169558 0.000000 + -0.130993 -0.697144 -0.138046 0.000000 + 0.421997 -0.704116 -0.225047 0.000000 + -0.135600 -0.676478 -0.175327 0.000000 + -1.030294 -0.476982 -0.303595 0.000000 + -0.972444 -0.662867 -0.114907 0.000000 + -1.133237 -0.188770 -0.592948 0.000000 + -1.156586 -0.068968 -0.669875 0.000000 + 0.104707 -0.272228 -0.375954 0.000000 + -1.040094 0.243293 -0.857217 0.000000 + -1.215713 0.179528 -0.846093 0.000000 + -0.932362 0.275778 -0.843362 0.000000 + 0.330728 0.212691 -0.455984 0.000000 + -0.328597 0.496962 -0.746030 0.000000 + 0.244300 0.691684 -0.512127 0.000000 + 0.524988 0.710213 -0.370358 0.000000 + 0.395533 0.745147 -0.448664 0.000000 + 0.445044 0.757189 -0.426155 0.000000 + 0.511927 0.698773 -0.396143 0.000000 + 0.553790 0.669927 -0.399180 0.000000 + 0.602824 0.642411 -0.393781 0.000000 + 1.259117 0.171707 -0.385501 0.000000 + 1.418568 -0.189672 -0.427255 0.000000 + 1.346673 0.106963 -0.397182 0.000000 + 1.436626 -0.127874 -0.423248 0.000000 + 1.373105 -0.263549 -0.417174 0.000000 + 1.145808 -0.658043 -0.350580 0.000000 + 1.070236 -0.736686 -0.308157 0.000000 + -0.465530 0.349308 0.879251 0.000000 + -0.559980 0.305782 0.840188 0.000000 + -0.560599 0.142914 0.873297 0.000000 + -0.590753 -0.190672 0.845287 0.000000 + 0.495052 -0.313362 0.556197 0.000000 + 0.581593 -0.108775 0.553999 0.000000 + 0.315384 0.406003 0.683372 0.000000 + 0.059321 0.551732 0.775153 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 402 + 1 + 0.000000 + + + + + + 0.929846 0.085890 -0.357783 0.000000 + 0.068264 0.915224 0.397120 0.000000 + 0.361561 -0.393684 0.845155 0.000000 + + + + 0.152447 -0.083367 0.065429 0.000000 + + + 403 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 404 + 0 + 28 + 0 0 0 0 + + + -0.965185 -0.324997 0.699940 0.000000 + -0.551598 -0.557510 0.676434 0.000000 + 0.422027 -0.613911 0.749660 0.000000 + -0.891925 -0.251457 0.720188 0.000000 + 0.059430 0.749184 0.574228 0.000000 + 0.567510 0.708667 0.612143 0.000000 + 0.533225 0.762875 0.576792 0.000000 + 0.241047 0.775975 0.560087 0.000000 + -0.238712 0.644858 0.604717 0.000000 + 0.754591 0.313665 0.769814 0.000000 + 0.753641 0.336774 0.766399 0.000000 + -0.201994 0.698003 0.590708 0.000000 + -0.466253 0.308553 0.728702 0.000000 + 0.748090 0.198976 0.812878 0.000000 + -0.544967 0.201624 0.731296 0.000000 + 0.717816 -0.223615 0.839441 0.000000 + -0.852081 -0.202198 0.735823 0.000000 + 0.712352 -0.344901 0.845087 0.000000 + 0.702196 -0.641023 0.778920 0.000000 + -0.370125 0.293194 -0.914388 0.000000 + 0.274760 -0.029110 -1.660554 0.000000 + 0.332864 -0.178322 -1.691820 0.000000 + -0.846362 -0.396682 -0.100623 0.000000 + -1.059504 -0.280834 0.135599 0.000000 + -0.763770 0.259370 -0.395873 0.000000 + -0.601143 0.481985 -0.418804 0.000000 + -0.520184 0.536041 -0.248763 0.000000 + 0.747902 -0.424688 -0.424819 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 405 + 1 + 0.000000 + + + + + + 0.897721 0.124076 -0.422733 0.000000 + -0.040159 0.978575 0.201938 0.000000 + 0.438731 -0.164308 0.883469 0.000000 + + + + 0.016324 -0.032739 0.138042 0.000000 + + + 406 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 407 + 0 + 16 + 0 0 0 0 + + + -0.175556 -0.303342 0.823609 0.000000 + 0.621782 -0.232306 0.857367 0.000000 + -0.381914 -0.074407 0.899159 0.000000 + 0.629961 0.118219 1.000258 0.000000 + -0.560798 0.117145 0.966333 0.000000 + 0.837780 -0.235573 0.875601 0.000000 + 0.567755 0.221514 1.007220 0.000000 + 0.282129 0.256646 1.002692 0.000000 + -0.687347 0.197809 0.978880 0.000000 + 0.538174 0.280398 1.017275 0.000000 + -0.761827 -0.261494 -0.251489 0.000000 + -1.036651 0.150086 0.176199 0.000000 + 0.051882 0.174715 -1.484893 0.000000 + 0.228906 -0.054630 -1.776645 0.000000 + 0.522259 0.238139 -0.222647 0.000000 + 0.710587 -0.093672 -0.808784 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 408 + 1 + 0.000000 + + + + + + 0.879846 0.191164 0.435119 0.000000 + -0.113692 0.973616 -0.197852 0.000000 + -0.461461 0.124610 0.878366 0.000000 + + + + -0.062500 -0.049358 0.038841 0.000000 + + + 409 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 410 + 0 + 59 + 0 0 0 0 + + + 1.484298 -0.339551 0.624772 0.000000 + 1.387102 -0.430738 0.631886 0.000000 + 0.821126 -0.640081 -0.088698 0.000000 + 1.545708 -0.207358 0.487775 0.000000 + 1.098601 -0.592297 0.645706 0.000000 + 0.419872 -0.885095 0.179201 0.000000 + 0.808097 -0.750585 0.665562 0.000000 + 0.328152 -0.871292 0.690973 0.000000 + -0.046435 -0.974024 0.439142 0.000000 + 0.169027 -0.909405 0.701631 0.000000 + 0.016772 -0.910111 0.706103 0.000000 + -0.311918 -0.947780 0.542429 0.000000 + -1.435894 -0.751078 -0.022004 0.000000 + -1.365506 -0.740407 0.079727 0.000000 + -1.573847 -0.593009 0.046203 0.000000 + -1.291336 -0.916124 -0.118849 0.000000 + -1.206676 -0.842429 0.134724 0.000000 + -1.226688 -0.958530 -0.162595 0.000000 + -0.998070 -1.005243 -0.090157 0.000000 + -0.682175 -0.959609 0.358084 0.000000 + -0.760742 -1.063600 -0.005244 0.000000 + -0.601837 -0.972908 0.397736 0.000000 + -0.318402 -1.072205 0.036459 0.000000 + -0.178510 -1.074680 0.046540 0.000000 + 0.261299 -0.969949 -0.052509 0.000000 + 0.339985 -0.950794 -0.073437 0.000000 + 0.682991 -0.742570 -0.306495 0.000000 + 0.744141 -0.704162 -0.353322 0.000000 + 0.934561 -0.444461 -0.659439 0.000000 + 1.118126 -0.263026 -0.338355 0.000000 + 1.018611 -0.349891 -0.654332 0.000000 + 0.933573 -0.452787 -0.648805 0.000000 + 1.192367 0.076961 -0.728471 0.000000 + 1.281889 0.209160 -0.545378 0.000000 + 1.223581 0.157752 -0.744995 0.000000 + 1.304778 0.344246 -0.574523 0.000000 + 1.235775 0.208443 -0.761164 0.000000 + 1.610330 0.594323 -0.216114 0.000000 + 1.669829 0.549261 -0.107617 0.000000 + 1.714953 0.370946 0.033990 0.000000 + 1.721212 0.514021 -0.023565 0.000000 + 1.671329 0.172510 0.163851 0.000000 + 1.616247 -0.080651 0.337373 0.000000 + -1.859060 0.461401 0.163869 0.000000 + -1.864201 0.448778 0.146188 0.000000 + -1.129940 0.796332 -0.263465 0.000000 + -1.157794 0.736437 -0.352662 0.000000 + -1.301263 0.810681 0.496864 0.000000 + -0.642749 1.126462 0.192090 0.000000 + 1.040400 0.519062 0.533907 0.000000 + 0.996190 0.669232 0.416424 0.000000 + 0.050519 1.060526 0.188626 0.000000 + -0.991297 0.659631 0.594029 0.000000 + 1.380482 0.220948 0.605431 0.000000 + 1.378598 0.214316 0.608635 0.000000 + -0.481901 0.156853 0.714236 0.000000 + 1.579948 0.505926 0.196055 0.000000 + -0.035936 0.038739 -1.119773 0.000000 + -0.082255 -0.165237 -1.064396 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 411 + 1 + 0.000000 + + + + + + 0.896168 -0.296522 0.330087 0.000000 + 0.420098 0.806472 -0.416077 0.000000 + -0.142830 0.511544 0.847303 0.000000 + + + + -0.264679 0.322185 0.215149 0.000000 + + + 412 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 413 + 0 + 51 + 0 0 0 0 + + + -0.591463 0.668254 -0.719167 0.000000 + -0.558506 0.732132 -0.433716 0.000000 + 0.596248 0.234408 -0.169544 0.000000 + -0.561464 0.631422 -0.779014 0.000000 + -0.542974 0.721974 -0.266322 0.000000 + 0.424087 0.282633 0.341183 0.000000 + -0.517753 0.694822 0.127475 0.000000 + -0.513459 0.615462 0.340406 0.000000 + 0.208684 0.169576 0.824430 0.000000 + -0.514914 0.491938 0.663822 0.000000 + -0.530883 0.308939 0.906141 0.000000 + -0.028890 -0.093642 1.232977 0.000000 + -0.550441 0.142757 1.122433 0.000000 + -0.649602 -0.421595 1.492206 0.000000 + -0.481829 -0.367185 1.474463 0.000000 + -0.620917 -0.318722 1.457819 0.000000 + -0.387189 -0.358648 1.461035 0.000000 + -0.595027 -0.163450 1.346491 0.000000 + -0.290269 -0.319652 1.453788 0.000000 + -0.221664 -0.311028 1.432029 0.000000 + 0.141312 -0.201332 1.439714 0.000000 + 0.203703 -0.215095 1.435517 0.000000 + 0.389705 -0.163496 1.436579 0.000000 + 0.704263 -0.052103 1.342492 0.000000 + 0.421663 -0.127296 1.433265 0.000000 + 1.016943 0.025193 1.244867 0.000000 + 1.132184 0.049792 1.117509 0.000000 + 1.379666 0.097286 0.852920 0.000000 + 1.398348 0.092688 0.684116 0.000000 + 1.450250 0.075201 0.300097 0.000000 + 1.323695 0.015034 -0.063951 0.000000 + 0.708298 0.029534 -0.657796 0.000000 + 1.219151 -0.041274 -0.371895 0.000000 + 0.722311 -0.236718 -1.066747 0.000000 + -0.026423 -0.484226 -1.581535 0.000000 + -0.011689 -0.496347 -1.574147 0.000000 + -0.042785 -0.416039 -1.549753 0.000000 + 0.093317 -0.451772 -1.523294 0.000000 + -0.162480 -0.107439 -1.406826 0.000000 + 0.709581 -0.235183 -1.086084 0.000000 + -0.265304 0.138521 -1.291172 0.000000 + 0.708241 -0.242780 -1.084766 0.000000 + -0.360038 0.315126 -1.133525 0.000000 + -0.292292 0.187754 -1.250043 0.000000 + -0.495089 0.558266 -0.909623 0.000000 + -0.703171 -0.137829 -0.201144 0.000000 + -0.588328 -0.521964 -0.363525 0.000000 + -0.611493 -0.540093 -0.244344 0.000000 + -0.718029 -0.488745 0.920023 0.000000 + -0.264125 -0.480870 -1.091281 0.000000 + -0.661318 -0.425477 1.490594 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 414 + 1 + 0.000000 + + + + + + 0.831239 -0.549884 -0.081660 0.000000 + 0.553267 0.832625 0.025106 0.000000 + 0.054187 -0.066049 0.996344 0.000000 + + + + -0.104222 -0.404259 -0.018270 0.000000 + + + 415 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 416 + 0 + 62 + 0 0 0 0 + + + -0.689265 -0.674771 -1.726225 0.000000 + -0.531362 -0.955883 -1.619304 0.000000 + -0.644704 -0.916288 0.172335 0.000000 + -0.736340 -0.585339 -1.685104 0.000000 + -0.475063 -1.013165 -1.584436 0.000000 + -0.246899 -1.280554 0.126552 0.000000 + -0.150243 -1.320172 -1.412766 0.000000 + -0.046270 -1.371114 -1.362762 0.000000 + 0.244429 -1.503700 0.085038 0.000000 + 0.326429 -1.542426 -1.201335 0.000000 + 0.615163 -1.562466 0.065909 0.000000 + 0.404628 -1.560089 -1.168981 0.000000 + 0.641514 -1.666511 0.827425 0.000000 + 0.722249 -1.680196 0.797925 0.000000 + 0.391300 -1.648191 0.933383 0.000000 + 0.185601 -1.561899 1.040444 0.000000 + -0.066527 -1.452741 1.178622 0.000000 + -0.209217 -1.321901 1.276772 0.000000 + -0.427611 -1.116184 1.435302 0.000000 + -0.508008 -0.964019 1.516759 0.000000 + -0.909968 -0.446502 0.217904 0.000000 + -0.656809 -0.671736 1.678276 0.000000 + -0.681539 -0.516799 1.739138 0.000000 + -1.016631 0.082816 0.258794 0.000000 + -0.698170 -0.461913 1.760667 0.000000 + -0.769185 -0.162578 1.692084 0.000000 + -0.766417 0.075676 1.602167 0.000000 + -0.954179 0.619799 0.290995 0.000000 + -0.755409 0.419029 1.478350 0.000000 + -0.662574 0.725335 1.322345 0.000000 + -0.728697 1.111798 0.311347 0.000000 + -0.585539 0.964731 1.203518 0.000000 + -0.366134 1.290425 0.981467 0.000000 + -0.362279 1.510564 0.317853 0.000000 + -0.275710 1.420187 0.894509 0.000000 + 0.083525 1.695700 0.624612 0.000000 + 0.109136 1.777009 0.309878 0.000000 + 0.143639 1.740011 0.581787 0.000000 + 0.624267 1.891312 0.298661 0.000000 + 0.639311 1.885044 0.288205 0.000000 + 0.630989 1.892463 0.296228 0.000000 + 0.736341 1.885409 0.248897 0.000000 + 0.704377 1.885903 -0.040836 0.000000 + 0.789617 1.884602 0.232103 0.000000 + 0.644171 1.884482 -0.278203 0.000000 + 0.346034 1.806480 -0.462572 0.000000 + 0.606962 1.873311 -0.427069 0.000000 + 0.163899 1.766672 -0.489967 0.000000 + -0.125433 1.597871 -0.580018 0.000000 + -0.301228 1.492394 -0.640074 0.000000 + -0.501574 1.263471 -0.757228 0.000000 + -0.655634 1.082658 -0.854252 0.000000 + -0.758254 0.839238 -0.975736 0.000000 + -0.864238 0.577991 -1.111389 0.000000 + -0.882474 0.364177 -1.215870 0.000000 + -0.906569 0.028455 -1.386091 0.000000 + -0.872405 -0.122641 -1.458208 0.000000 + -0.778947 -0.511503 -1.651251 0.000000 + 1.121062 0.680787 0.493626 0.000000 + 0.725760 0.178593 -1.258817 0.000000 + 0.954721 -0.679871 1.042161 0.000000 + 0.665940 -0.038261 -1.366480 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 417 + 1 + 0.000000 + + + + + + 0.959431 -0.281037 0.022600 0.000000 + 0.258872 0.909842 0.324304 0.000000 + -0.111704 -0.305297 0.945683 0.000000 + + + + 0.026292 0.055128 0.086320 0.000000 + + + 418 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 419 + 0 + 41 + 0 0 0 0 + + + 0.437044 -0.403504 0.139787 0.000000 + 0.821422 -0.023322 -1.233648 0.000000 + 0.656485 0.058833 0.314964 0.000000 + -0.425812 -0.770565 -1.379036 0.000000 + -0.389198 -1.013894 -0.154863 0.000000 + -0.442141 -1.041268 -0.175585 0.000000 + -0.419941 -0.778799 -1.388801 0.000000 + -0.028235 -0.684936 -1.385644 0.000000 + 0.053565 -0.641204 -1.382383 0.000000 + 0.076758 -0.773131 -0.022098 0.000000 + 0.477247 -0.405564 -1.374681 0.000000 + 0.483420 -0.400493 -1.373080 0.000000 + 0.545909 -0.333739 -1.370248 0.000000 + 0.894671 -0.044129 -1.355968 0.000000 + 0.943000 -0.001595 -1.358071 0.000000 + 1.063542 0.275787 -1.203827 0.000000 + 0.992706 0.308123 -1.057853 0.000000 + 0.970888 0.033788 -1.351943 0.000000 + 0.968419 0.320379 -0.795972 0.000000 + 0.712394 0.446485 0.464612 0.000000 + 0.770299 0.244639 1.365449 0.000000 + 0.734179 0.444739 0.737325 0.000000 + 0.718161 0.490008 1.452689 0.000000 + 0.753155 0.078427 1.308405 0.000000 + 0.712540 -0.271874 1.195628 0.000000 + 0.646707 -0.415375 1.143939 0.000000 + 0.491337 -0.744516 1.033420 0.000000 + 0.382470 -0.860708 0.988793 0.000000 + 0.128356 -1.127082 0.894682 0.000000 + -0.004274 -1.198079 0.856390 0.000000 + 0.008875 -1.196519 0.862632 0.000000 + -0.331696 -1.303735 0.604561 0.000000 + -0.445220 -1.315276 0.528673 0.000000 + -0.601373 0.783112 -1.201987 0.000000 + -0.593652 0.773850 -1.217983 0.000000 + -0.629350 0.914135 -1.093755 0.000000 + -0.586458 0.875145 -1.153129 0.000000 + 0.181047 0.693225 1.492035 0.000000 + -0.731279 1.015391 0.811173 0.000000 + -0.560520 -0.386857 1.016168 0.000000 + -0.431199 -0.350845 1.103222 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 420 + 1 + 0.000000 + + + + + + 0.911589 0.252273 0.324596 0.000000 + 0.021386 0.759406 -0.650265 0.000000 + -0.410545 0.599717 0.686872 0.000000 + + + + 0.021492 0.023872 -0.099277 0.000000 + + + 421 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 422 + 0 + 41 + 0 0 0 0 + + + -0.115949 0.838655 -0.852883 0.000000 + -0.147595 0.874069 -0.792474 0.000000 + -0.058899 0.825366 -0.848055 0.000000 + -0.285400 1.008722 -0.530031 0.000000 + 0.607405 0.624805 -0.773034 0.000000 + -0.630129 1.346149 0.129570 0.000000 + -0.658581 1.332318 0.102671 0.000000 + -0.624731 1.339519 0.115020 0.000000 + -0.636335 1.342207 0.125797 0.000000 + -0.552953 1.301923 0.320252 0.000000 + -0.763624 1.373555 0.284331 0.000000 + -0.208008 1.126492 0.422778 0.000000 + 1.416758 0.235304 -0.521626 0.000000 + -0.112834 1.052599 0.453391 0.000000 + 1.588503 -0.026475 -0.079740 0.000000 + 0.357692 0.653156 0.641259 0.000000 + 0.824782 -0.658028 1.104976 0.000000 + 1.053789 -0.524522 0.932984 0.000000 + 0.861584 -0.452757 1.037362 0.000000 + 0.826569 -0.650579 1.088462 0.000000 + 1.143695 -0.466327 0.822506 0.000000 + 0.808539 -0.221218 0.960173 0.000000 + 1.470392 -0.262638 0.417129 0.000000 + 0.726254 0.108635 0.853189 0.000000 + 1.487325 -0.248731 0.379493 0.000000 + 0.517599 0.422987 0.728869 0.000000 + 1.600622 -0.160136 0.127180 0.000000 + 1.671008 -0.079970 -0.149637 0.000000 + 1.678740 -0.077224 -0.185991 0.000000 + 1.649775 0.011928 -0.640054 0.000000 + 1.687345 -0.012559 -0.640051 0.000000 + 1.576891 0.098565 -0.653714 0.000000 + 1.291866 0.315654 -0.694267 0.000000 + 0.842738 0.546903 -0.752189 0.000000 + -1.521762 0.143826 0.535681 0.000000 + -1.548223 -0.142353 0.399494 0.000000 + -1.567568 -0.025633 0.572453 0.000000 + -1.062891 -1.074963 -0.805812 0.000000 + -0.842852 -1.151767 -0.779717 0.000000 + 0.650864 -0.728922 1.061503 0.000000 + -0.059857 -0.496149 0.923290 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 423 + 1 + 0.000000 + + + + + + 0.793384 -0.604082 -0.075010 0.000000 + 0.452510 0.667712 -0.591097 0.000000 + 0.407156 0.435024 0.803105 0.000000 + + + + -0.132915 -0.335763 -0.166737 0.000000 + + + 424 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 425 + 0 + 46 + 0 0 0 0 + + + 0.510189 1.251719 0.525931 0.000000 + 1.149163 0.864849 0.542527 0.000000 + 0.652889 1.284477 0.431469 0.000000 + 0.140270 1.133938 0.666841 0.000000 + 0.872593 0.470803 0.790631 0.000000 + -0.107205 1.059703 0.754592 0.000000 + -0.404941 0.949222 0.787403 0.000000 + 0.554114 0.041640 0.878256 0.000000 + -0.753743 0.825333 0.820325 0.000000 + -0.945197 0.743983 0.789542 0.000000 + 0.224954 -0.380561 0.796849 0.000000 + -1.294023 0.557851 0.719616 0.000000 + -1.243039 0.618046 0.742597 0.000000 + -1.350589 0.476070 0.671475 0.000000 + -0.082626 -0.754429 0.554450 0.000000 + -1.579260 0.164303 0.476114 0.000000 + -1.614739 0.113144 0.416456 0.000000 + -0.338510 -1.043367 0.174880 0.000000 + -1.809940 -0.144693 0.094281 0.000000 + -1.889803 -0.236736 -0.119534 0.000000 + -0.817356 -0.971415 -0.181583 0.000000 + -1.824378 -0.166462 0.046316 0.000000 + -0.493921 -1.197324 -0.202005 0.000000 + 0.277202 -1.788251 -0.227733 0.000000 + 0.556587 -2.032052 -0.237363 0.000000 + 0.605677 -1.960606 -0.084746 0.000000 + 0.653801 -1.846946 0.041722 0.000000 + 0.773034 -1.589290 0.322654 0.000000 + 0.841016 -1.356164 0.455151 0.000000 + 0.929921 -1.072098 0.612019 0.000000 + 1.008909 -0.692783 0.701483 0.000000 + 1.060888 -0.458753 0.753542 0.000000 + 1.132301 0.054615 0.738029 0.000000 + 1.152739 0.190496 0.732017 0.000000 + 1.179826 0.791482 0.563562 0.000000 + 1.188330 0.723513 0.578615 0.000000 + 1.175985 0.822093 0.557227 0.000000 + 1.154123 0.921970 0.511885 0.000000 + 1.000733 1.402297 0.163013 0.000000 + 1.037111 1.382060 0.156728 0.000000 + 1.016109 1.392217 0.174002 0.000000 + 0.496107 0.867261 -1.402322 0.000000 + -0.213098 0.666537 -1.067715 0.000000 + 0.510810 0.899124 -1.343082 0.000000 + 0.625133 0.113958 -1.133389 0.000000 + -1.531398 0.270051 -0.448948 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 426 + 1 + 0.000000 + + + + + + 0.935698 0.163039 -0.312871 0.000000 + -0.247472 0.935365 -0.252687 0.000000 + 0.251450 0.313865 0.915566 0.000000 + + + + 0.011121 0.035538 -0.125123 0.000000 + + + 427 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 428 + 0 + 44 + 0 0 0 0 + + + -0.901689 -0.317766 0.551212 0.000000 + -0.890235 -0.287110 0.560222 0.000000 + -0.886745 -0.258437 0.573579 0.000000 + -0.908564 -0.324079 0.539379 0.000000 + -0.960304 -0.585590 0.357839 0.000000 + -0.716724 -0.760265 0.424027 0.000000 + -0.620979 -0.751328 0.487485 0.000000 + -0.979851 -0.544250 0.369155 0.000000 + -0.690450 -0.779759 0.431297 0.000000 + -0.430308 -0.942329 0.400857 0.000000 + -0.208112 -1.078095 0.363030 0.000000 + 0.699793 -0.784189 0.750839 0.000000 + 0.684517 -0.736426 0.804459 0.000000 + -0.192890 -1.084557 0.347211 0.000000 + 0.632866 -0.538212 0.939315 0.000000 + 0.580033 -0.330287 1.080123 0.000000 + 0.566686 -0.274395 1.102134 0.000000 + 0.502693 -0.080465 1.151047 0.000000 + 0.404624 0.240495 1.231047 0.000000 + 0.385023 0.434385 1.230846 0.000000 + -0.720911 0.258191 0.677584 0.000000 + 0.225122 0.706454 1.169327 0.000000 + -0.689794 0.356419 0.696872 0.000000 + 0.361182 0.701264 1.241057 0.000000 + -0.571694 0.778361 0.651048 0.000000 + -0.542488 0.808342 0.654607 0.000000 + -0.558541 0.782327 0.660068 0.000000 + -0.180639 0.274264 -1.288936 0.000000 + 0.023425 0.583088 -1.088209 0.000000 + 0.419563 0.182869 -1.189120 0.000000 + 0.110226 0.181227 -1.266771 0.000000 + -0.239190 -0.464314 -1.028048 0.000000 + -0.143807 -0.715896 -0.855425 0.000000 + -0.245095 -0.793676 -0.741757 0.000000 + -0.287631 -0.760590 -0.749607 0.000000 + 0.892706 -0.273192 -0.808488 0.000000 + -0.245167 -0.211528 -1.165718 0.000000 + 0.882372 -0.078131 -0.921616 0.000000 + -0.316044 0.187575 -1.266209 0.000000 + -0.703312 0.339427 -0.642704 0.000000 + -0.534664 0.877169 -0.089143 0.000000 + -0.035716 0.926678 -0.563042 0.000000 + 0.559760 0.824530 0.222029 0.000000 + 0.412392 0.704825 1.173786 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 429 + 1 + 0.000000 + + + + + + 0.763743 0.510824 0.394658 0.000000 + -0.642568 0.660017 0.389209 0.000000 + -0.061663 -0.550851 0.832323 0.000000 + + + + 0.096002 -0.002419 0.008226 0.000000 + + + 430 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 431 + 0 + 29 + 0 0 0 0 + + + -0.274533 -0.226825 -0.516238 0.000000 + -0.081623 0.120424 -0.638691 0.000000 + 0.192503 -0.096106 -0.627173 0.000000 + -0.428379 -0.278867 -0.472457 0.000000 + -1.087089 0.313972 -0.108503 0.000000 + -1.047543 0.287272 -0.122238 0.000000 + -1.052484 0.262206 -0.134383 0.000000 + -0.626026 0.244980 -0.436641 0.000000 + -0.938719 -0.143448 -0.280587 0.000000 + -0.569635 0.239986 -0.460680 0.000000 + -0.836686 -0.339155 -0.309184 0.000000 + -0.804241 -0.416185 -0.320341 0.000000 + -0.225676 0.213055 -0.605018 0.000000 + -0.003975 0.194047 -0.655712 0.000000 + 0.032386 0.197646 -0.658341 0.000000 + 0.497783 -0.032116 -0.622938 0.000000 + 0.789214 0.178371 -0.631500 0.000000 + 0.904648 0.177092 -0.602933 0.000000 + 1.054275 0.032093 -0.504068 0.000000 + 0.423390 -0.047477 -0.624112 0.000000 + 0.628408 0.177443 -0.640412 0.000000 + 0.374164 -0.313891 0.608221 0.000000 + 1.079536 0.060847 -0.306485 0.000000 + 0.993461 0.200740 -0.251395 0.000000 + -0.113432 0.381134 0.908619 0.000000 + -0.124665 0.421445 0.896728 0.000000 + 0.039297 -0.478774 0.457660 0.000000 + 0.329549 -0.439057 0.537424 0.000000 + 1.097749 0.011632 -0.410750 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 432 + 1 + 0.000000 + + + + + + 0.923753 -0.006910 0.382927 0.000000 + 0.127618 0.948250 -0.290749 0.000000 + -0.361101 0.317449 0.876831 0.000000 + + + + -0.245008 0.135135 0.094641 0.000000 + + + 433 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 434 + 0 + 62 + 0 0 0 0 + + + 1.244997 0.499785 -0.331313 0.000000 + -0.501347 0.361940 -1.255064 0.000000 + -0.683510 0.612217 -0.811107 0.000000 + 1.203233 0.580091 0.202393 0.000000 + -0.887361 0.701972 -0.317728 0.000000 + 1.143924 0.491916 0.733286 0.000000 + -1.092945 0.622325 0.176774 0.000000 + 1.072872 0.243819 1.209339 0.000000 + -1.280114 0.380998 0.623938 0.000000 + 0.997039 -0.139936 1.583864 0.000000 + -1.430515 0.001590 0.979910 0.000000 + 1.265137 0.258954 -0.815580 0.000000 + -0.689871 0.368553 -1.377696 0.000000 + -0.654855 0.315489 -1.420315 0.000000 + -0.913806 0.571257 -1.058859 0.000000 + -0.968590 0.616076 -0.985973 0.000000 + -1.199257 0.683798 -0.643927 0.000000 + -1.225718 0.694474 -0.601691 0.000000 + -1.252452 0.702819 -0.544762 0.000000 + -1.406056 0.641806 -0.144820 0.000000 + -1.449352 0.623544 -0.038849 0.000000 + -1.582384 0.427743 0.342686 0.000000 + -1.614438 0.381486 0.427845 0.000000 + -1.711591 0.061727 0.750602 0.000000 + -1.712742 0.025971 0.809925 0.000000 + -1.719645 0.041123 0.789403 0.000000 + -1.477307 -0.346418 1.184450 0.000000 + -1.319186 -0.482977 1.280151 0.000000 + -1.382456 -0.464629 1.266102 0.000000 + -1.365118 -0.488970 1.279703 0.000000 + -1.071437 -0.453814 1.327359 0.000000 + -1.403973 -0.446839 1.252898 0.000000 + -0.041602 -0.307990 1.475834 0.000000 + 0.979273 -0.165256 1.622624 0.000000 + 1.192240 -0.144443 1.588237 0.000000 + 1.377288 -0.139551 1.553655 0.000000 + 1.354490 -0.140765 1.565616 0.000000 + 1.468145 0.139974 1.260744 0.000000 + 1.497556 0.203118 1.192453 0.000000 + 1.567481 0.404241 0.805546 0.000000 + 1.586844 0.449677 0.711767 0.000000 + 1.597014 0.529111 0.281703 0.000000 + 1.601778 0.545142 0.180270 0.000000 + 1.548926 0.492776 -0.266181 0.000000 + 1.541006 0.480572 -0.350710 0.000000 + 1.490358 0.402134 -0.529920 0.000000 + 1.239058 0.286509 -0.805000 0.000000 + 1.240997 0.286536 -0.803534 0.000000 + 1.235399 0.293468 -0.803785 0.000000 + 0.369627 -0.312745 -1.569647 0.000000 + 0.452403 -0.294960 -1.526613 0.000000 + 0.410107 -0.340378 -1.573770 0.000000 + -0.188591 0.007650 -1.554294 0.000000 + 0.687711 -0.062601 -1.338288 0.000000 + -0.239503 0.031346 -1.545851 0.000000 + -0.353923 0.081473 -1.527063 0.000000 + -0.583142 0.209915 -1.513041 0.000000 + 0.974903 -0.628371 -0.734242 0.000000 + 0.558943 -0.772023 -1.205394 0.000000 + -0.576044 -0.745336 -0.473335 0.000000 + -1.078675 -0.126341 -0.716136 0.000000 + -1.024586 -0.157788 -0.797457 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 435 + 1 + 0.000000 + + + + + + 0.895498 0.046515 0.442629 0.000000 + -0.086380 0.993777 0.070324 0.000000 + -0.436604 -0.101209 0.893943 0.000000 + + + + -0.145894 0.152615 -0.092442 0.000000 + + + 436 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 437 + 0 + 30 + 0 0 0 0 + + + -0.739473 0.255969 0.677363 0.000000 + 0.715281 -0.091271 0.396035 0.000000 + 0.631143 0.401185 0.188565 0.000000 + -0.741927 0.257363 0.675755 0.000000 + -0.723985 0.138033 0.729400 0.000000 + 0.282655 -0.116279 0.539983 0.000000 + 0.746199 -0.293460 0.414973 0.000000 + 1.148251 -0.214828 0.445820 0.000000 + 1.153989 -0.227810 0.426978 0.000000 + 1.119634 -0.257876 0.448146 0.000000 + 1.118267 -0.056406 0.411128 0.000000 + 1.023952 0.300729 0.261956 0.000000 + 0.990497 0.438022 0.202471 0.000000 + 0.904340 0.735834 -0.045777 0.000000 + 0.903316 0.724905 -0.048609 0.000000 + 0.894014 0.744438 -0.063001 0.000000 + 0.558748 0.691289 -0.042640 0.000000 + -0.823968 0.664606 0.317804 0.000000 + -0.137963 0.713294 0.102751 0.000000 + -0.844706 0.726164 0.222712 0.000000 + -0.814495 0.628273 0.351123 0.000000 + -0.767103 0.186294 -0.558907 0.000000 + 0.112936 0.114755 -0.794722 0.000000 + -0.148179 -0.630994 -0.491719 0.000000 + -0.525385 -0.292826 -0.484876 0.000000 + -0.012838 -1.108225 -0.032050 0.000000 + -0.258106 -0.954092 0.055703 0.000000 + -0.697469 -0.129883 0.566793 0.000000 + -0.846610 0.320962 -0.354983 0.000000 + 0.905016 0.540833 -0.322842 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 438 + 1 + 0.000000 + + + + + + 0.987847 -0.137056 -0.073301 0.000000 + 0.150935 0.958477 0.241950 0.000000 + 0.037096 -0.250074 0.967516 0.000000 + + + + -0.169946 -0.052140 -0.216687 0.000000 + + + 439 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 440 + 0 + 47 + 0 0 0 0 + + + 0.343690 -0.098558 -0.983514 0.000000 + 0.452219 -0.053161 -0.568965 0.000000 + 0.293101 -0.560761 -0.667055 0.000000 + 0.227051 -0.456681 -1.062475 0.000000 + 0.390263 0.054232 -0.952822 0.000000 + 0.389654 0.417265 -0.859206 0.000000 + 0.454380 0.463415 -0.408519 0.000000 + 0.386424 0.585311 -0.819048 0.000000 + 0.295150 0.860550 -0.736651 0.000000 + 0.277495 0.899677 -0.713187 0.000000 + 0.299356 0.938493 -0.201387 0.000000 + 0.230237 1.053273 -0.607175 0.000000 + -0.043567 1.443446 -0.333823 0.000000 + -0.071454 1.407111 0.031021 0.000000 + -0.001358 1.335622 -0.004276 0.000000 + -0.063273 1.435949 -0.334827 0.000000 + -0.001495 1.336132 -0.005377 0.000000 + 0.019212 1.330318 -0.407777 0.000000 + 0.009865 1.320453 -0.001577 0.000000 + 0.382891 0.918394 0.015025 0.000000 + 0.446224 0.849123 0.023524 0.000000 + 0.685491 0.463961 0.133382 0.000000 + 0.831242 0.228145 0.208618 0.000000 + 0.925105 -0.003941 0.316334 0.000000 + 1.084222 -0.355358 0.486050 0.000000 + 1.056752 -0.370289 0.440355 0.000000 + 0.960161 -0.443090 0.303925 0.000000 + 0.610138 -0.717885 -0.157320 0.000000 + 0.144963 -0.988678 -0.536139 0.000000 + -0.007446 -1.009787 -0.693196 0.000000 + 0.066600 -1.034842 -0.598126 0.000000 + -0.077724 -1.107469 -0.674536 0.000000 + -0.082583 -1.099341 -0.684451 0.000000 + -0.164163 -0.961677 -1.142528 0.000000 + -0.087147 -0.897222 -1.137233 0.000000 + -0.168815 -0.970178 -1.154585 0.000000 + 0.135367 -0.589001 -1.082914 0.000000 + -0.398266 -0.518853 1.145867 0.000000 + 0.066229 -0.329544 1.302787 0.000000 + -0.155122 -0.129202 1.307134 0.000000 + -0.297392 -0.142714 1.267387 0.000000 + -0.293176 0.903744 0.619213 0.000000 + -0.527971 0.316583 0.910087 0.000000 + -0.728133 -0.179420 0.617536 0.000000 + -0.467402 -0.579279 1.042774 0.000000 + -0.702989 -0.184911 -0.890960 0.000000 + -0.215236 0.989130 -0.641092 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 441 + 1 + 0.000000 + + + + + + 0.931990 0.256164 -0.256467 0.000000 + 0.005519 0.697416 0.716645 0.000000 + 0.362443 -0.669322 0.648571 0.000000 + + + + 0.033228 0.075070 -0.125018 0.000000 + + + 442 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 443 + 0 + 32 + 0 0 0 0 + + + -0.093006 1.040401 0.079177 0.000000 + -0.217994 0.926018 0.139593 0.000000 + 0.503525 0.704430 0.350234 0.000000 + 0.542765 0.810371 0.290349 0.000000 + -0.284791 0.847354 0.154635 0.000000 + 0.421552 0.390191 0.443755 0.000000 + -0.592099 0.494623 0.213419 0.000000 + 0.375378 0.194606 0.499929 0.000000 + -0.628757 0.435664 0.205129 0.000000 + 0.316157 -0.156256 0.492743 0.000000 + -0.801350 0.167800 0.164541 0.000000 + -0.786681 0.019495 0.163672 0.000000 + 0.288506 -0.347109 0.487358 0.000000 + -0.767228 -0.063437 0.149555 0.000000 + 0.260392 -0.700145 0.370509 0.000000 + -0.669773 -0.552863 0.039332 0.000000 + 0.251392 -0.867659 0.313863 0.000000 + -0.601229 -0.681875 0.004630 0.000000 + 0.259924 -1.184585 0.090450 0.000000 + -0.638189 -0.655797 0.005565 0.000000 + 0.144098 -1.243303 -0.004254 0.000000 + 0.267633 -1.316116 -0.003439 0.000000 + 0.264395 -1.314534 0.005338 0.000000 + 0.257233 -1.316364 -0.003854 0.000000 + 0.452113 -0.395618 -0.430689 0.000000 + 0.527914 -0.396326 -0.393395 0.000000 + 0.282482 -1.259545 -0.061975 0.000000 + 0.315014 -1.255707 -0.032392 0.000000 + 0.598056 0.467574 -0.123584 0.000000 + -0.134640 0.404194 -0.575192 0.000000 + -0.051194 0.606508 -0.470300 0.000000 + -0.619608 0.016244 -0.257740 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 444 + 1 + 0.000000 + + + + + + 0.918580 -0.244373 -0.310633 0.000000 + 0.133411 0.931528 -0.338316 0.000000 + 0.372039 0.269328 0.888285 0.000000 + + + + -0.019495 -0.161241 0.078680 0.000000 + + + 445 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 446 + 0 + 22 + 0 0 0 0 + + + -0.449587 0.866284 0.115949 0.000000 + -0.189065 0.938321 -0.197181 0.000000 + -0.485269 0.793924 0.127053 0.000000 + -0.742894 -0.741241 -0.353734 0.000000 + -0.300416 -0.232555 -0.703931 0.000000 + 0.359335 1.189322 -0.368605 0.000000 + 0.254940 1.173011 -0.320156 0.000000 + 0.057862 1.165141 0.001682 0.000000 + 0.445132 1.196383 -0.291751 0.000000 + 0.429883 1.196779 -0.319314 0.000000 + 0.651508 0.470893 -0.213048 0.000000 + 0.202840 -0.354012 -0.565737 0.000000 + 0.164368 0.645694 -0.524450 0.000000 + -0.221739 1.064320 0.254419 0.000000 + -0.661554 -0.003049 0.558106 0.000000 + -0.780800 -0.886053 -0.262795 0.000000 + 0.408592 -1.113863 -0.053406 0.000000 + 0.880738 -0.710016 0.472894 0.000000 + -0.351888 0.178011 0.828943 0.000000 + -0.177440 -0.169268 -0.741916 0.000000 + 0.196924 -0.382239 -0.572933 0.000000 + 0.771551 0.285865 -0.009266 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 447 + 1 + 0.000000 + + + + + + 0.986782 -0.105394 0.123100 0.000000 + 0.092483 0.990027 0.106273 0.000000 + -0.133073 -0.093483 0.986688 0.000000 + + + + -0.106155 -0.088984 0.098369 0.000000 + + + 448 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 449 + 0 + 56 + 0 0 0 0 + + + -1.143335 -0.555845 0.354111 0.000000 + 0.079167 -0.479360 -1.422292 0.000000 + -0.671304 -0.708402 0.570784 0.000000 + 0.456416 -0.637847 -1.067891 0.000000 + -0.183797 -0.693270 0.805367 0.000000 + 0.849176 -0.628642 -0.695635 0.000000 + 0.271475 -0.512025 1.034896 0.000000 + 1.219011 -0.452743 -0.341957 0.000000 + 0.650014 -0.182482 1.236930 0.000000 + 1.529768 -0.127440 -0.041429 0.000000 + -1.143672 -0.620333 0.647803 0.000000 + -0.761116 -0.753969 0.903249 0.000000 + -1.214561 -0.594536 0.602902 0.000000 + -1.444354 -0.425464 0.456138 0.000000 + -1.397221 -0.386605 0.229164 0.000000 + -0.991963 0.020974 -0.979166 0.000000 + -0.903767 0.014209 -1.085197 0.000000 + -1.089230 -0.079995 -0.709433 0.000000 + -0.459956 -0.037561 -1.638421 0.000000 + -0.330302 -0.188294 -1.605168 0.000000 + -1.281258 -0.273662 -0.187745 0.000000 + -0.313582 -0.200992 -1.599751 0.000000 + -0.110301 -0.336220 -1.549688 0.000000 + 0.147704 -0.489829 -1.483204 0.000000 + 0.176151 -0.500041 -1.480682 0.000000 + 0.245189 -0.531197 -1.456741 0.000000 + 0.573319 -0.653141 -1.214224 0.000000 + 0.617995 -0.666131 -1.184962 0.000000 + 0.974033 -0.659555 -0.859623 0.000000 + 1.023441 -0.656241 -0.818519 0.000000 + 1.323956 -0.500453 -0.478710 0.000000 + 1.363100 -0.479015 -0.438309 0.000000 + 1.513434 -0.177304 -0.045621 0.000000 + 1.546085 -0.240610 -0.164932 0.000000 + 1.511781 -0.173463 -0.038551 0.000000 + 1.503898 -0.172366 -0.020705 0.000000 + 1.088687 0.267446 1.172420 0.000000 + 1.068876 0.256359 1.170825 0.000000 + 1.290975 0.248085 0.841544 0.000000 + 1.274276 0.266317 0.896449 0.000000 + 1.019128 0.199523 1.176507 0.000000 + 0.702981 -0.151527 1.216769 0.000000 + 0.657243 -0.205183 1.227495 0.000000 + 0.653937 -0.204157 1.230953 0.000000 + 0.266300 -0.505562 1.260033 0.000000 + 0.196903 -0.555273 1.268790 0.000000 + -0.188670 -0.702499 1.276537 0.000000 + -0.292801 -0.743729 1.221533 0.000000 + -0.208657 -0.715343 1.275781 0.000000 + -0.656239 -0.752836 0.972209 0.000000 + -0.599073 0.761202 1.061983 0.000000 + -0.605883 0.747634 1.059722 0.000000 + 0.016914 0.944702 -0.761855 0.000000 + -0.329077 0.965425 -0.350787 0.000000 + 0.080546 0.819561 -1.010278 0.000000 + -0.239214 0.171157 -1.574760 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 450 + 1 + 0.000000 + + + + + + 0.783777 0.471682 0.403993 0.000000 + -0.111896 0.747116 -0.655208 0.000000 + -0.610879 0.468331 0.638351 0.000000 + + + + -0.039315 -0.008027 0.136791 0.000000 + + + 451 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 452 + 0 + 39 + 0 0 0 0 + + + -1.177451 -0.313997 0.398915 0.000000 + 1.069377 -0.273921 -0.523248 0.000000 + 1.099364 -0.308527 0.016317 0.000000 + 1.205500 -0.280144 -0.506242 0.000000 + 1.033586 -0.267031 -0.626097 0.000000 + 1.257766 -0.274035 -0.473626 0.000000 + 1.720857 -0.206347 -0.039977 0.000000 + 1.723996 -0.209033 0.023886 0.000000 + 1.721644 -0.206591 0.022695 0.000000 + 1.712949 -0.208441 -0.048878 0.000000 + 1.085854 -0.234643 0.423262 0.000000 + -0.240920 -0.030513 1.070469 0.000000 + -0.242437 -0.029997 1.067079 0.000000 + -0.038843 -0.054866 0.967434 0.000000 + -0.819129 -0.213945 0.848268 0.000000 + 0.853961 -0.213723 0.548869 0.000000 + -0.766477 -0.202092 0.884569 0.000000 + -0.843363 -0.222128 0.822072 0.000000 + -1.069507 -0.292303 0.583940 0.000000 + -1.214553 -0.330926 0.418689 0.000000 + -1.226373 -0.329786 0.409193 0.000000 + -1.343912 -0.308975 0.232126 0.000000 + -1.263346 -0.312783 -0.048927 0.000000 + -1.241174 -0.308194 -0.115690 0.000000 + -1.235872 -0.311703 -0.118241 0.000000 + 0.569251 -0.159613 -0.826739 0.000000 + -0.979217 -0.108974 -0.676434 0.000000 + 0.409288 -0.122225 -0.896048 0.000000 + -0.357106 0.016686 -0.956639 0.000000 + -0.918653 -0.045722 -0.770318 0.000000 + -0.848913 0.029849 -0.897381 0.000000 + 0.008915 0.004008 -1.005342 0.000000 + 0.371068 0.496971 -0.047765 0.000000 + -0.782643 0.367820 -0.219686 0.000000 + 0.186511 0.527309 0.401285 0.000000 + 0.590390 0.541594 0.152680 0.000000 + -1.205573 -0.059776 0.155390 0.000000 + -0.914495 0.335600 -0.278430 0.000000 + 1.711193 -0.197795 0.001132 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 453 + 1 + 0.000000 + + + + + + 0.748207 -0.095848 0.656506 0.000000 + -0.024094 0.984932 0.171257 0.000000 + -0.663028 -0.143953 0.734623 0.000000 + + + + 0.175614 -0.023224 0.070981 0.000000 + + + 454 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 455 + 0 + 42 + 0 0 0 0 + + + -0.232008 0.786908 -0.581310 0.000000 + -0.245557 0.545708 -0.061556 0.000000 + -0.071333 0.946874 0.053434 0.000000 + -0.338798 0.676917 -1.035415 0.000000 + -0.363636 0.610379 -1.240564 0.000000 + -0.316829 0.018889 -0.161453 0.000000 + -0.415561 0.524915 -1.557534 0.000000 + -0.413449 0.271415 -1.530556 0.000000 + -0.390057 0.524544 -1.522201 0.000000 + -0.414366 0.262839 -1.530434 0.000000 + -0.417505 0.269341 -1.527066 0.000000 + -0.219813 -0.506735 -0.244552 0.000000 + -0.311331 -0.285834 -1.523597 0.000000 + -0.293328 -0.322972 -1.523170 0.000000 + 0.036032 -0.979805 -0.302730 0.000000 + -0.137933 -0.662406 -1.550398 0.000000 + -0.047074 -0.872130 -0.770390 0.000000 + 0.008648 -0.988882 -0.293445 0.000000 + 0.029886 -1.460439 0.681473 0.000000 + 0.013041 -1.420257 0.675050 0.000000 + -0.251196 -1.171317 0.711211 0.000000 + -0.322382 -1.045766 0.731377 0.000000 + -0.515986 -0.697976 0.796099 0.000000 + -0.538459 -0.589712 0.816495 0.000000 + -0.620613 -0.171995 0.906790 0.000000 + -0.610528 -0.081958 0.925727 0.000000 + -0.555019 0.355300 1.032466 0.000000 + -0.517819 0.435890 1.051430 0.000000 + -0.073334 0.970407 0.120551 0.000000 + -0.325682 0.832545 1.160869 0.000000 + -0.072177 0.983728 0.155982 0.000000 + 0.048634 1.205099 0.929450 0.000000 + 0.027296 1.134353 0.698874 0.000000 + -0.253995 0.908577 1.181628 0.000000 + -0.021243 1.173851 1.271407 0.000000 + -0.123833 0.325919 -1.599604 0.000000 + 0.310910 0.181372 -1.377184 0.000000 + -0.045008 -0.417501 -1.581051 0.000000 + 0.379663 -0.826482 0.845420 0.000000 + 0.508052 -0.553732 0.878099 0.000000 + 0.490111 -0.488900 0.924566 0.000000 + 0.612158 0.347292 -0.533400 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 456 + 1 + 0.000000 + + + + + + 0.919872 -0.392053 -0.011445 0.000000 + 0.372815 0.864926 0.336023 0.000000 + -0.121840 -0.313365 0.941784 0.000000 + + + + 0.444965 -0.098839 -0.131652 0.000000 + + + 457 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 458 + 0 + 65 + 0 0 0 0 + + + -0.732271 -1.121580 0.351624 0.000000 + -0.372324 -1.036392 -0.221393 0.000000 + -0.584317 -1.130237 0.444061 0.000000 + -1.037894 -0.992018 0.175606 0.000000 + -0.851435 -0.858197 -0.399534 0.000000 + -1.173164 -0.933476 0.102031 0.000000 + -1.444036 -0.697600 -0.028888 0.000000 + -1.267234 -0.533624 -0.520711 0.000000 + -1.556901 -0.598563 -0.079202 0.000000 + -1.992917 1.151808 0.011664 0.000000 + -1.974217 1.147596 0.000232 0.000000 + -2.056253 0.896159 -0.025782 0.000000 + -2.038560 0.907586 -0.078316 0.000000 + -2.043211 0.734905 -0.063577 0.000000 + -2.030230 0.737337 -0.111616 0.000000 + -2.006030 0.360509 -0.157852 0.000000 + -2.011899 0.369378 -0.174034 0.000000 + -1.942862 0.242611 -0.196979 0.000000 + -1.962668 0.215200 -0.177119 0.000000 + -1.729480 -0.139386 -0.331237 0.000000 + -1.845919 -0.149627 -0.174334 0.000000 + -1.674456 -0.188886 -0.353500 0.000000 + -1.762142 -0.280072 -0.149744 0.000000 + -1.320810 -0.500744 -0.498887 0.000000 + -1.267538 -0.550520 -0.523433 0.000000 + -1.264001 -0.549165 -0.527152 0.000000 + -0.837638 -0.764510 -0.664692 0.000000 + -0.759284 -0.799319 -0.693009 0.000000 + -0.349934 -0.866876 -0.793777 0.000000 + -0.180283 -0.890109 -0.839294 0.000000 + 0.167501 -0.847887 -0.902350 0.000000 + 0.123204 -1.050672 -0.003704 0.000000 + 0.415769 -0.812880 -0.951672 0.000000 + 0.679806 -0.702398 -0.981596 0.000000 + 0.586596 -0.899558 0.232217 0.000000 + 0.935616 -0.591484 -1.000279 0.000000 + 0.920152 -0.604885 -1.009505 0.000000 + 1.102144 -0.465651 -0.857737 0.000000 + 0.972414 -0.597804 0.463251 0.000000 + 1.304456 -0.307790 -0.689172 0.000000 + 1.431648 -0.104474 -0.538402 0.000000 + 1.242811 -0.174962 0.666743 0.000000 + 1.554261 0.096428 -0.396554 0.000000 + 1.642559 0.873698 -0.053167 0.000000 + 1.598010 0.847851 0.082810 0.000000 + 1.632632 0.884597 -0.046668 0.000000 + 1.495575 0.793193 0.459369 0.000000 + 1.444146 0.363587 0.599831 0.000000 + 1.660255 0.581480 -0.151263 0.000000 + 1.428840 0.322255 0.612799 0.000000 + 1.613538 0.363368 -0.258438 0.000000 + 1.318561 0.034419 0.707176 0.000000 + 1.188359 -0.188509 0.775084 0.000000 + 1.165529 -0.214600 0.788541 0.000000 + 0.761895 -0.594683 0.917347 0.000000 + 0.655344 -0.686977 0.954346 0.000000 + 0.292579 -0.889905 0.989269 0.000000 + 0.355278 -0.858631 1.014562 0.000000 + 0.160515 -0.990609 0.914154 0.000000 + -0.129993 -1.095962 0.749266 0.000000 + 0.000850 -1.051586 0.844186 0.000000 + -0.277375 -1.144423 0.645158 0.000000 + 0.183605 -0.829677 0.993231 0.000000 + -1.301946 1.020850 0.427710 0.000000 + 0.568956 1.044166 -0.559733 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 459 + 1 + 0.000000 + + + + + + 0.821778 -0.130051 -0.554768 0.000000 + -0.115772 0.915190 -0.386036 0.000000 + 0.557922 0.381462 0.737027 0.000000 + + + + 0.085235 -0.220548 -0.156015 0.000000 + + + 460 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 461 + 0 + 62 + 0 0 0 0 + + + 1.142647 0.095341 1.823756 0.000000 + 1.047178 0.151866 1.849189 0.000000 + 0.061126 -0.135755 1.390421 0.000000 + 1.204931 -0.076810 1.666355 0.000000 + -0.095627 0.254574 1.557935 0.000000 + 0.975572 0.193933 1.856255 0.000000 + -1.400775 0.090275 1.414492 0.000000 + -0.692472 0.198865 1.502443 0.000000 + -1.392342 0.143955 1.424873 0.000000 + -1.414755 0.038019 1.392333 0.000000 + -1.459643 -0.162768 1.319843 0.000000 + -1.420806 -0.420513 1.211747 0.000000 + -1.414204 -0.437428 1.199382 0.000000 + 0.251981 -0.519617 1.060223 0.000000 + -1.309864 -0.822075 0.867811 0.000000 + -1.297587 -0.843003 0.835611 0.000000 + 0.441893 -0.773488 0.621586 0.000000 + -1.177648 -1.088639 0.417893 0.000000 + -1.157490 -1.103104 0.355265 0.000000 + 0.612269 -0.872440 0.117388 0.000000 + -1.036981 -1.194280 -0.094401 0.000000 + -1.009500 -1.183810 -0.189251 0.000000 + 0.746410 -0.806692 -0.403020 0.000000 + -0.901553 -1.128466 -0.619356 0.000000 + -0.870385 -1.074141 -0.736659 0.000000 + 0.831152 -0.582609 -0.888646 0.000000 + -0.784621 -0.897216 -1.105769 0.000000 + -0.755699 -0.786636 -1.225722 0.000000 + 0.858170 -0.222099 -1.291871 0.000000 + -0.697704 -0.522763 -1.505890 0.000000 + -0.677833 -0.354658 -1.603098 0.000000 + 0.824802 0.239522 -1.573140 0.000000 + -0.649404 -0.041574 -1.780221 0.000000 + -0.706784 0.695925 -1.889415 0.000000 + -0.658730 0.736592 -1.883874 0.000000 + -0.668648 0.702570 -1.892432 0.000000 + -0.100404 0.565887 -1.825600 0.000000 + -0.644519 0.499174 -1.901571 0.000000 + 0.212390 0.502190 -1.757227 0.000000 + -0.644645 0.172593 -1.829515 0.000000 + 0.788018 0.386174 -1.630899 0.000000 + 1.087587 0.339670 -1.471147 0.000000 + 1.239714 0.326819 -1.383692 0.000000 + 1.384714 0.052221 -1.121465 0.000000 + 1.327545 0.318017 -1.324946 0.000000 + 1.411868 -0.057374 -1.039913 0.000000 + 1.452614 -0.298540 -0.722123 0.000000 + 1.471876 -0.393372 -0.590052 0.000000 + 1.478366 -0.523403 -0.237484 0.000000 + 1.484768 -0.586998 -0.051838 0.000000 + 1.461820 -0.608890 0.286399 0.000000 + 1.449411 -0.619469 0.521562 0.000000 + 1.406423 -0.554605 0.804053 0.000000 + 1.369441 -0.488085 1.073717 0.000000 + 1.318295 -0.371251 1.274975 0.000000 + 1.252839 -0.206338 1.550646 0.000000 + -1.326723 0.788308 0.629516 0.000000 + -0.547117 1.095874 0.376454 0.000000 + -0.835057 0.862115 -1.273128 0.000000 + 0.986839 0.848904 1.028268 0.000000 + -1.455220 0.306201 1.219645 0.000000 + 1.021477 0.641703 1.298926 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 462 + 1 + 0.000000 + + + + + + 0.938503 0.047552 0.341982 0.000000 + 0.014153 0.984340 -0.175712 0.000000 + -0.344982 0.169746 0.923133 0.000000 + + + + 0.080155 0.054204 -0.163570 0.000000 + + + 463 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 464 + 0 + 63 + 0 0 0 0 + + + 0.277823 -0.285000 1.764780 0.000000 + 0.829025 -0.476250 0.751562 0.000000 + 0.295033 -0.003830 1.782071 0.000000 + 0.192192 -0.569704 1.688796 0.000000 + 0.591329 -0.962859 0.752211 0.000000 + 0.117148 -0.802808 1.628212 0.000000 + 0.113019 -0.825623 1.617186 0.000000 + 0.030347 -1.121243 1.315380 0.000000 + 0.226404 -1.357818 0.688461 0.000000 + -0.009718 -1.266838 1.167570 0.000000 + -0.214970 -1.608657 0.626656 0.000000 + -0.229942 -1.622457 0.566583 0.000000 + -0.223041 -1.620510 0.607648 0.000000 + -0.256950 -1.647968 0.528992 0.000000 + -0.831342 -1.893828 -0.712825 0.000000 + -0.762390 -1.854807 -0.422287 0.000000 + -0.975064 -1.883385 -0.772467 0.000000 + -0.997731 -1.878594 -0.743098 0.000000 + -0.517298 -1.938460 -0.656856 0.000000 + -0.598509 -1.837816 -0.135878 0.000000 + -0.305009 -1.904092 -0.634057 0.000000 + 0.014972 -1.849767 -0.606395 0.000000 + 0.204001 -1.755319 -0.604667 0.000000 + 0.500960 -1.604356 -0.608794 0.000000 + 0.648304 -1.463501 -0.626760 0.000000 + 0.893057 -1.226308 -0.663808 0.000000 + 0.986883 -1.057165 -0.697829 0.000000 + 1.152861 -0.752724 -0.766034 0.000000 + 1.188615 -0.574997 -0.810948 0.000000 + 0.916155 0.054318 0.686562 0.000000 + 1.254984 -0.230088 -0.905431 0.000000 + 1.235082 -0.062433 -0.955371 0.000000 + 0.844166 0.576824 0.563581 0.000000 + 1.189574 0.290349 -1.068310 0.000000 + 1.122238 0.432494 -1.117520 0.000000 + 0.620126 1.040037 0.394680 0.000000 + 0.963248 0.757672 -1.238703 0.000000 + 0.860659 0.863563 -1.282225 0.000000 + 0.266035 1.398565 0.196427 0.000000 + 0.598331 1.126325 -1.399949 0.000000 + 0.474343 1.190429 -1.434138 0.000000 + -0.183362 1.617311 -0.011739 0.000000 + 0.130542 1.360499 -1.536331 0.000000 + -0.638990 1.660686 -0.328929 0.000000 + -0.538602 1.588623 -0.754152 0.000000 + -0.768453 1.619767 -0.478412 0.000000 + -0.623658 1.661613 -0.305640 0.000000 + -0.102670 1.434913 -1.287104 0.000000 + -0.549692 1.665724 -0.189776 0.000000 + 0.105063 1.371101 -1.541985 0.000000 + -0.331040 1.667656 0.164684 0.000000 + -0.297769 1.666359 0.230229 0.000000 + -0.126105 1.558148 0.658707 0.000000 + -0.064309 1.514112 0.831334 0.000000 + 0.008968 1.351776 1.172409 0.000000 + 0.059544 1.224009 1.442449 0.000000 + 0.069169 1.081139 1.636377 0.000000 + 0.069061 1.090273 1.635370 0.000000 + 0.200902 0.807145 1.733675 0.000000 + 0.250816 0.566695 1.762658 0.000000 + 0.306579 0.269753 1.801043 0.000000 + -1.341094 0.558346 0.031408 0.000000 + -0.761021 0.562735 0.961962 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 465 + 1 + 0.000000 + + + + + + 0.941790 -0.040058 0.333808 0.000000 + 0.039058 0.999190 0.009709 0.000000 + -0.333926 0.003894 0.942591 0.000000 + + + + 0.031305 -0.016677 -0.006595 0.000000 + + + 466 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 467 + 0 + 35 + 0 0 0 0 + + + -1.201609 0.142060 -0.057478 0.000000 + 0.336939 0.338295 -0.478657 0.000000 + 0.213421 -0.036319 -0.849649 0.000000 + -1.273085 0.022821 -0.158440 0.000000 + -1.051429 0.398358 0.169487 0.000000 + -0.965094 0.476922 0.304840 0.000000 + 0.483291 0.573792 -0.013617 0.000000 + 0.182487 0.583012 0.089605 0.000000 + -0.941927 0.506761 0.348854 0.000000 + 0.499299 0.587885 0.022975 0.000000 + 0.791912 0.576340 -0.020251 0.000000 + 1.132900 0.579375 -0.083564 0.000000 + 1.168749 0.584655 -0.057860 0.000000 + 0.812455 0.406553 -0.421125 0.000000 + 0.719968 0.353829 -0.520649 0.000000 + 0.319813 0.009938 -0.839530 0.000000 + 0.295506 -0.012487 -0.859510 0.000000 + 0.168015 -0.123002 -0.909364 0.000000 + 0.206661 -0.100426 -0.907625 0.000000 + -0.429301 -0.441167 -0.832261 0.000000 + -0.459290 -0.450795 -0.816228 0.000000 + -0.445223 -0.427166 -0.834358 0.000000 + -0.969750 -0.179341 -0.431228 0.000000 + -1.305217 -0.017710 -0.185601 0.000000 + -1.298895 -0.055481 -0.197154 0.000000 + 1.125881 -0.126009 0.473700 0.000000 + 0.786736 -0.265305 0.616088 0.000000 + 0.475403 -0.424066 0.620849 0.000000 + 0.437978 -0.589021 0.297946 0.000000 + 0.801686 -0.396725 0.256333 0.000000 + 0.376039 -0.347536 0.751687 0.000000 + -0.784215 -0.019602 0.716260 0.000000 + -0.880708 -0.059803 0.547260 0.000000 + 0.430129 -0.589027 0.291514 0.000000 + -1.307274 -0.003833 -0.234572 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 468 + 1 + 0.000000 + + + + + + 0.906315 -0.079412 0.415075 0.000000 + -0.142047 0.867795 0.476187 0.000000 + -0.398016 -0.490535 0.775215 0.000000 + + + + -0.139952 -0.270917 -0.072032 0.000000 + + + 469 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 470 + 0 + 48 + 0 0 0 0 + + + -0.760568 -1.455847 -0.189445 0.000000 + -0.656653 -1.383128 -0.323220 0.000000 + -0.304131 -1.358251 -0.245512 0.000000 + -0.757263 -1.456110 -0.175972 0.000000 + -0.596520 -1.317091 -0.394496 0.000000 + 0.829258 -1.077000 -0.287166 0.000000 + 0.836435 -1.079528 -0.285402 0.000000 + -0.374871 -1.044484 -0.679372 0.000000 + 0.825387 -1.053671 -0.317215 0.000000 + -0.310772 -0.907750 -0.754972 0.000000 + 0.738012 -0.681304 -0.598446 0.000000 + -0.174367 -0.589526 -0.927940 0.000000 + 0.720674 -0.598865 -0.658412 0.000000 + -0.134992 -0.397948 -0.970856 0.000000 + 0.628182 -0.212684 -0.795733 0.000000 + -0.074920 -0.062971 -1.044347 0.000000 + 0.597036 -0.072207 -0.843132 0.000000 + -0.076471 0.151001 -1.034130 0.000000 + 0.507150 0.296408 -0.851606 0.000000 + -0.086361 0.483360 -1.017038 0.000000 + 0.466594 0.474438 -0.852889 0.000000 + -0.130696 0.682983 -0.951964 0.000000 + 0.384749 0.803563 -0.748136 0.000000 + -0.207603 0.995631 -0.848634 0.000000 + 0.342171 0.987127 -0.686585 0.000000 + -0.283855 1.150454 -0.743397 0.000000 + 0.272480 1.259997 -0.481171 0.000000 + -0.324650 1.248305 -0.686191 0.000000 + -0.237404 1.404422 -0.525568 0.000000 + 0.236017 1.415273 -0.360592 0.000000 + -0.141226 1.547767 -0.276150 0.000000 + 0.182472 1.615206 -0.063096 0.000000 + -0.039070 1.708693 0.010027 0.000000 + 0.158594 1.716681 0.092924 0.000000 + 0.133683 1.819989 0.431612 0.000000 + 0.046807 1.803313 0.381146 0.000000 + 0.149124 1.813067 0.426021 0.000000 + 0.050300 1.826158 0.439668 0.000000 + 0.059231 1.828584 0.445975 0.000000 + 0.582870 -0.138539 0.917726 0.000000 + 0.588429 -0.464624 1.012976 0.000000 + 0.668024 -0.479153 0.953664 0.000000 + -0.727033 0.170223 -0.018104 0.000000 + -0.365486 0.621320 0.863522 0.000000 + -0.143631 1.333779 0.609216 0.000000 + -0.776226 0.091212 -0.119933 0.000000 + -0.183468 -0.586849 1.201847 0.000000 + -0.348894 0.498193 0.904857 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 471 + 1 + 0.000000 + + + + + + 0.885320 -0.362470 0.291247 0.000000 + 0.419982 0.892165 -0.166302 0.000000 + -0.199561 0.269549 0.942082 0.000000 + + + + -0.051448 0.157000 0.135060 0.000000 + + + 472 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 473 + 0 + 43 + 0 0 0 0 + + + 0.069365 -1.403164 0.255719 0.000000 + 0.099274 -1.402098 0.236415 0.000000 + 0.037814 -1.419637 0.169482 0.000000 + 0.071556 -1.403279 0.252333 0.000000 + 0.262540 -1.222400 0.573208 0.000000 + 0.298547 -1.170923 0.646701 0.000000 + 0.242826 -1.113383 0.671359 0.000000 + 0.308578 -1.157994 0.665752 0.000000 + 0.531881 -0.803572 0.956404 0.000000 + 0.435664 -0.716624 0.985402 0.000000 + 0.549735 -0.779668 0.974647 0.000000 + 0.812658 -0.379591 1.114363 0.000000 + 0.658902 -0.250675 1.147712 0.000000 + 0.841195 -0.341051 1.125972 0.000000 + 1.114190 0.061045 1.109543 0.000000 + 0.890659 0.238793 1.142339 0.000000 + 1.154270 0.114673 1.104777 0.000000 + 1.413472 0.517246 0.946792 0.000000 + 1.290839 0.526497 0.968765 0.000000 + 1.384464 0.490584 0.955891 0.000000 + 1.059801 0.580019 1.026499 0.000000 + 1.322147 0.363925 1.003928 0.000000 + 0.066768 0.786023 0.960219 0.000000 + -0.930502 1.002348 0.882254 0.000000 + -1.204062 1.058915 0.844374 0.000000 + -1.158202 0.575324 0.887565 0.000000 + -1.242758 1.085025 0.851969 0.000000 + -1.127038 0.444134 0.869757 0.000000 + -1.023012 -0.058001 0.782322 0.000000 + -0.956379 -0.273495 0.687149 0.000000 + -0.853897 -0.623690 0.522881 0.000000 + -0.750136 -0.866448 0.313109 0.000000 + -0.667463 -1.065589 0.134762 0.000000 + -0.131337 -1.503188 -0.280024 0.000000 + -0.482084 -1.340001 -0.343584 0.000000 + -0.417937 -1.375910 -0.531897 0.000000 + -0.217065 -1.474183 -0.704194 0.000000 + -0.124086 -1.499123 -0.257256 0.000000 + -0.537850 -1.256602 -0.194159 0.000000 + 0.331969 -0.155722 -1.554628 0.000000 + 0.360862 0.608573 -1.804501 0.000000 + 0.787956 0.533029 -1.380197 0.000000 + -0.661318 0.865988 -0.979590 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 474 + 1 + 0.000000 + + + + + + 0.960485 0.181201 -0.211271 0.000000 + -0.127903 0.961510 0.243187 0.000000 + 0.247205 -0.206555 0.946691 0.000000 + + + + 0.073211 -0.023462 -0.040671 0.000000 + + + 475 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 476 + 0 + 46 + 0 0 0 0 + + + 0.481752 0.110122 1.382887 0.000000 + 0.566068 -0.091272 1.172183 0.000000 + 0.756601 -0.100826 1.154291 0.000000 + 0.219779 0.328488 1.513632 0.000000 + 0.022601 0.305199 1.452190 0.000000 + 0.270485 0.282767 1.494840 0.000000 + -0.765993 0.215654 1.240275 0.000000 + -0.753754 0.221656 1.222889 0.000000 + 0.304591 0.259182 1.486437 0.000000 + -0.706677 0.026426 1.053668 0.000000 + -0.661015 -0.184540 0.866895 0.000000 + -0.658490 -0.312110 0.646731 0.000000 + 0.638656 -0.362576 0.709202 0.000000 + -0.661542 -0.464133 0.378687 0.000000 + -0.694417 -0.512748 0.162113 0.000000 + 0.699834 -0.476849 0.183522 0.000000 + -0.755373 -0.589507 -0.193682 0.000000 + -0.799181 -0.579726 -0.348879 0.000000 + 0.743615 -0.422973 -0.353335 0.000000 + -0.868581 -0.578996 -0.604792 0.000000 + -0.762402 -0.557041 -0.708768 0.000000 + 0.241819 0.091323 -1.377565 0.000000 + 0.144822 0.081690 -1.405500 0.000000 + 0.195385 0.158645 -1.440702 0.000000 + 0.336888 0.015989 -1.261353 0.000000 + -0.072330 -0.116272 -1.253343 0.000000 + 0.674832 -0.239984 -0.854446 0.000000 + -0.295545 -0.310014 -1.101575 0.000000 + 0.683273 -0.244061 -0.842014 0.000000 + -0.643589 -0.499386 -0.804514 0.000000 + 0.725920 -0.262007 -0.781531 0.000000 + 0.843931 -0.321743 -0.615468 0.000000 + 0.892046 -0.401875 -0.408899 0.000000 + 0.905007 -0.418191 -0.362572 0.000000 + 0.979168 -0.448856 0.090451 0.000000 + 0.995176 -0.451749 0.171290 0.000000 + 1.040282 -0.346121 0.592222 0.000000 + 1.054061 -0.317725 0.694293 0.000000 + 0.799513 -0.128233 1.097689 0.000000 + 1.053961 -0.287258 0.766578 0.000000 + 0.668016 0.430127 -0.441199 0.000000 + 0.149137 0.661585 -1.201420 0.000000 + 0.455430 0.563474 -0.158629 0.000000 + 0.165057 0.667857 -1.195568 0.000000 + 0.756708 0.316409 -0.356091 0.000000 + -1.116300 0.308661 0.054726 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 477 + 1 + 0.000000 + + + + + + 0.995299 -0.074969 -0.061317 0.000000 + 0.082247 0.988568 0.126368 0.000000 + 0.051143 -0.130817 0.990086 0.000000 + + + + 0.009026 -0.253688 0.115282 0.000000 + + + 478 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 479 + 0 + 76 + 0 0 0 0 + + + 0.154058 -1.071807 -0.073258 0.000000 + -1.503407 -0.913743 -0.231005 0.000000 + 0.165981 -0.643423 -0.403491 0.000000 + 0.193077 -0.134755 -0.585589 0.000000 + -1.269717 0.004743 -0.724808 0.000000 + 0.232694 0.404471 -0.601799 0.000000 + -1.372918 -0.496667 -0.549954 0.000000 + 1.680033 -0.726625 -0.738037 0.000000 + 0.158481 -1.377983 0.372883 0.000000 + -1.648436 -1.205668 0.200913 0.000000 + -1.203879 0.541469 -0.738522 0.000000 + 0.280962 0.921573 -0.450557 0.000000 + 0.957009 1.451256 -0.164515 0.000000 + 0.333163 1.366023 -0.146624 0.000000 + 0.384199 1.694359 0.280340 0.000000 + 0.476951 1.686623 0.218534 0.000000 + 1.006360 1.428794 -0.203547 0.000000 + 1.006757 1.331799 -0.305686 0.000000 + 1.030944 1.104464 -0.471480 0.000000 + 1.061277 0.874359 -0.636949 0.000000 + 1.112899 0.671442 -0.711421 0.000000 + 1.204595 0.338458 -0.831286 0.000000 + 1.253418 0.207123 -0.840928 0.000000 + 1.422570 -0.222862 -0.869562 0.000000 + 1.444202 -0.268386 -0.859700 0.000000 + 1.611888 -0.598095 -0.784296 0.000000 + 1.683901 -0.740775 -0.765612 0.000000 + 1.693457 -0.751143 -0.763862 0.000000 + 1.701716 -0.781745 -0.756889 0.000000 + 1.708896 -1.139066 -0.465326 0.000000 + 1.711343 -1.173814 -0.438866 0.000000 + 1.708401 -1.171178 -0.445872 0.000000 + 1.702939 -1.481848 0.012648 0.000000 + 1.692782 -1.511080 0.076485 0.000000 + 1.510123 -1.560880 0.320515 0.000000 + 1.143568 -1.506028 0.336214 0.000000 + 1.696939 -1.496911 0.057556 0.000000 + 0.158678 -1.396424 0.365023 0.000000 + -0.177019 -1.375559 0.369776 0.000000 + -1.544274 -1.297932 0.392041 0.000000 + -1.612818 -1.232806 0.214829 0.000000 + -1.634164 -1.217414 0.163159 0.000000 + -1.641243 -1.212166 0.162848 0.000000 + -1.840775 -0.931778 -0.325488 0.000000 + -1.898149 -0.856266 -0.448237 0.000000 + -1.920678 -0.584396 -0.682887 0.000000 + -1.940839 -0.753316 -0.552959 0.000000 + -1.901427 -0.428428 -0.808104 0.000000 + -1.860161 -0.136116 -0.918734 0.000000 + -1.834071 0.081570 -0.999248 0.000000 + -1.809392 0.239870 -1.009722 0.000000 + -1.695276 0.366806 -0.966552 0.000000 + -1.600168 0.471103 -0.934531 0.000000 + -1.513831 0.553868 -0.900144 0.000000 + -1.148348 0.870389 -0.653404 0.000000 + -0.973725 1.024648 -0.591016 0.000000 + -0.898023 1.086267 -0.542169 0.000000 + -0.506180 1.439177 -0.244769 0.000000 + -0.239477 1.610882 0.010512 0.000000 + -0.399770 1.521495 -0.137532 0.000000 + -0.021091 1.732805 0.212691 0.000000 + 0.359344 1.723705 0.312107 0.000000 + 0.186608 1.808640 0.463858 0.000000 + 0.440407 1.699052 0.240052 0.000000 + -1.860851 -0.238882 -0.394427 0.000000 + -1.862012 -0.236567 -0.396398 0.000000 + -1.858142 -0.224919 -0.391540 0.000000 + -0.559822 0.457445 0.864663 0.000000 + -1.510746 -0.505040 0.478557 0.000000 + -1.480789 -0.611584 0.569311 0.000000 + -1.377970 0.638620 -0.676452 0.000000 + -1.800541 0.173125 -0.787956 0.000000 + 0.026790 1.105804 1.045175 0.000000 + 0.512564 0.474904 0.867363 0.000000 + 1.539099 0.057740 -0.267894 0.000000 + 1.245122 0.879672 -0.166033 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 480 + 1 + 0.000000 + + + + + + 0.895167 0.432078 -0.109476 0.000000 + -0.405676 0.891526 0.201515 0.000000 + 0.184671 -0.135978 0.973348 0.000000 + + + + 0.139111 -0.321140 0.290806 0.000000 + + + 481 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 482 + 0 + 64 + 0 0 0 0 + + + -0.111250 1.727903 0.890612 0.000000 + -0.292561 1.749827 0.369965 0.000000 + -0.246195 1.731091 0.934322 0.000000 + 0.242517 1.602990 0.773879 0.000000 + 0.166971 1.582117 0.137734 0.000000 + 0.379309 1.552541 0.732283 0.000000 + 0.675238 1.323227 0.641284 0.000000 + 0.558088 1.263410 -0.059093 0.000000 + 0.799544 1.224684 0.606764 0.000000 + 1.011598 0.918585 0.548869 0.000000 + 0.842424 0.824918 -0.201211 0.000000 + 1.108159 0.776542 0.526397 0.000000 + 1.220148 0.427311 0.505257 0.000000 + 0.992091 0.309631 -0.274680 0.000000 + 1.274890 0.252210 0.499065 0.000000 + 1.281320 -0.104325 0.514538 0.000000 + 0.992425 -0.231924 -0.272301 0.000000 + 1.283528 -0.296753 0.527401 0.000000 + 1.189242 -0.626325 0.575887 0.000000 + 0.843428 -0.746654 -0.194325 0.000000 + 1.133483 -0.816505 0.608538 0.000000 + 0.952159 -1.089589 0.683671 0.000000 + 0.559755 -1.184127 -0.048422 0.000000 + 0.839715 -1.256287 0.734438 0.000000 + 0.591480 -1.450260 0.828029 0.000000 + 0.169259 -1.501530 0.151085 0.000000 + 0.431108 -1.573345 0.892733 0.000000 + 0.139761 -1.673285 0.995772 0.000000 + -0.289774 -1.667857 0.384634 0.000000 + -0.022646 -1.725899 1.031465 0.000000 + -0.004533 -1.731742 1.050568 0.000000 + -0.562120 -1.683133 0.505647 0.000000 + -0.865572 -1.719988 0.213151 0.000000 + -0.713655 -1.718585 0.050529 0.000000 + -0.600462 -1.721877 -0.083767 0.000000 + -0.410173 -1.634008 -0.345103 0.000000 + -0.282591 -1.570861 -0.529451 0.000000 + -0.161533 -1.420524 -0.741644 0.000000 + -0.046126 -1.268668 -0.956119 0.000000 + 0.012060 -1.090964 -1.109082 0.000000 + 0.085894 -0.845320 -1.321931 0.000000 + 0.093624 -0.667805 -1.416299 0.000000 + 0.100846 -0.342665 -1.591221 0.000000 + 0.072343 -0.183455 -1.634364 0.000000 + -0.002308 0.189915 -1.738006 0.000000 + -0.054252 0.321680 -1.740031 0.000000 + -0.179090 0.644718 -1.751080 0.000000 + -0.179706 0.671228 -1.729701 0.000000 + -0.181039 0.817904 -1.571142 0.000000 + -0.199936 1.152866 -1.208065 0.000000 + -0.247525 1.354026 -0.863603 0.000000 + -0.293292 1.519641 -0.577558 0.000000 + -0.420223 1.695667 -0.024500 0.000000 + -0.450710 1.734382 0.099566 0.000000 + -0.593957 1.762032 0.554035 0.000000 + -0.683867 1.749734 0.806823 0.000000 + -0.623958 1.733617 1.066197 0.000000 + -0.706862 1.719299 1.014510 0.000000 + -0.715334 1.729674 0.896981 0.000000 + -0.751649 1.715869 0.974978 0.000000 + -0.650247 1.732154 1.075709 0.000000 + -1.174250 -0.572103 0.115811 0.000000 + -1.169212 -0.641891 0.059691 0.000000 + -1.107324 -0.943645 0.118092 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 483 + 1 + 0.000000 + + + + + + 1.000000 0.000000 0.000000 0.000000 + 0.000000 1.000000 0.000000 0.000000 + 0.000000 0.000000 1.000000 0.000000 + + + + 0.000000 0.000000 0.000000 0.000000 + + + 484 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 485 + 0 + 8 + 0 0 0 0 + + + -17.020262 -1.407098 13.169413 0.000000 + 17.020262 -1.407098 13.169413 0.000000 + -17.020262 1.407098 13.169413 0.000000 + 17.020262 1.407098 13.169413 0.000000 + -17.020262 1.407098 -13.169413 0.000000 + 17.020262 1.407098 -13.169413 0.000000 + -17.020262 -1.407098 -13.169413 0.000000 + 17.020262 -1.407098 -13.169413 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 486 + 1 + 0.000000 + + + + + + 0.780502 -0.501667 0.373024 0.000000 + 0.382838 0.855276 0.349196 0.000000 + -0.494218 -0.129741 0.859602 0.000000 + + + + 0.213697 0.164281 -0.102246 0.000000 + + + 487 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 488 + 0 + 50 + 0 0 0 0 + + + -1.048270 -0.003646 0.367004 0.000000 + -1.004334 0.578821 -0.385466 0.000000 + -1.399631 0.213131 -0.436926 0.000000 + -1.300280 0.056219 -0.056548 0.000000 + -0.700763 -0.090131 0.951035 0.000000 + -0.689995 -0.114464 0.967955 0.000000 + -0.678243 -0.088534 1.008855 0.000000 + -0.670743 -0.096060 1.031832 0.000000 + -0.394537 -0.142089 1.544629 0.000000 + -0.190932 0.086846 1.023797 0.000000 + -0.299137 -0.141722 1.751979 0.000000 + -0.282042 -0.137113 1.751617 0.000000 + 0.037914 -0.059728 1.622470 0.000000 + 0.347592 0.138322 1.011600 0.000000 + 0.271742 -0.007074 1.531072 0.000000 + 0.780866 0.039435 1.091981 0.000000 + 0.872910 0.034847 0.932520 0.000000 + 0.839792 0.043716 1.041657 0.000000 + 0.955329 0.040704 0.883105 0.000000 + 1.591628 -0.316762 -0.841206 0.000000 + 1.530222 -0.207937 -0.784693 0.000000 + 1.539774 -0.210945 -0.577598 0.000000 + 1.591407 -0.295206 -0.857023 0.000000 + 1.404037 0.065640 -0.635279 0.000000 + 1.491666 -0.117054 -0.212907 0.000000 + 1.277571 0.198894 -0.561575 0.000000 + 1.294731 -0.012812 0.324674 0.000000 + 1.051268 0.433426 -0.438693 0.000000 + 1.245646 0.005750 0.457789 0.000000 + 0.903060 0.515266 -0.395471 0.000000 + 0.582233 0.690192 -0.310681 0.000000 + 0.448766 0.720439 -0.296601 0.000000 + 0.043086 0.810860 -0.263746 0.000000 + -0.042700 0.806901 -0.267530 0.000000 + -0.513204 0.783766 -0.302398 0.000000 + -0.534390 0.776923 -0.305370 0.000000 + -0.744473 0.706892 -0.354967 0.000000 + -1.040455 0.630257 -0.414915 0.000000 + -1.068376 0.623358 -0.425477 0.000000 + -1.471988 0.388540 -0.573985 0.000000 + -1.486879 0.385082 -0.577024 0.000000 + -1.493587 0.344201 -0.570897 0.000000 + -1.504660 0.077443 -0.493200 0.000000 + -1.537829 0.090871 -0.516564 0.000000 + -1.385776 0.069694 -0.238754 0.000000 + 1.027518 -0.455593 -0.770992 0.000000 + -0.421382 -0.684209 0.066134 0.000000 + -0.930391 -0.516950 -0.631769 0.000000 + -1.304484 0.064361 -0.728171 0.000000 + -1.341581 -0.166663 -0.687520 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 489 + 1 + 0.000000 + + + + + + 0.810132 0.479821 0.336834 0.000000 + -0.320998 0.843836 -0.430002 0.000000 + -0.490557 0.240236 0.837640 0.000000 + + + + 0.060836 0.167956 0.071016 0.000000 + + + 490 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 491 + 0 + 29 + 0 0 0 0 + + + -0.243518 -0.458576 -0.976009 0.000000 + -0.313628 0.196007 0.457069 0.000000 + -0.174062 -0.176103 -1.324129 0.000000 + -0.222905 -0.574481 -0.700884 0.000000 + -0.221927 -0.276309 0.705720 0.000000 + -0.186586 -0.740334 -0.320933 0.000000 + 0.087762 -0.923172 0.666392 0.000000 + -0.013105 -0.742476 0.801916 0.000000 + 0.019950 -0.904871 0.465991 0.000000 + -0.020820 -0.724443 0.811285 0.000000 + -0.040739 -0.857592 0.243644 0.000000 + -0.051138 -0.650887 0.850078 0.000000 + -0.165379 -0.155788 0.981801 0.000000 + -0.177862 -0.067972 1.007458 0.000000 + -0.192252 0.414295 1.023354 0.000000 + -0.193943 0.401391 1.026099 0.000000 + -0.205604 0.470608 0.938893 0.000000 + -0.195970 0.753440 0.515222 0.000000 + -0.236340 0.663884 0.195525 0.000000 + -0.192703 0.802807 0.443602 0.000000 + -0.166072 0.866314 0.325827 0.000000 + -0.180060 0.805218 0.103235 0.000000 + -0.066101 0.313981 -1.052562 0.000000 + -0.149068 -0.090187 -1.436364 0.000000 + -0.032039 0.134172 -1.509359 0.000000 + -0.088127 0.023357 -1.495727 0.000000 + 0.206604 0.593221 0.481284 0.000000 + 0.598444 0.109619 -0.008264 0.000000 + -0.028259 0.132205 -1.463063 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 492 + 1 + 0.000000 + + + + + + 0.860363 -0.506807 0.054068 0.000000 + 0.458324 0.815709 0.352929 0.000000 + -0.222970 -0.278866 0.934087 0.000000 + + + + -0.024495 -0.107537 0.018802 0.000000 + + + 493 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 494 + 0 + 33 + 0 0 0 0 + + + 0.647772 -0.095041 0.602946 0.000000 + 0.555914 -0.342086 0.529317 0.000000 + 0.628928 -0.388792 0.502723 0.000000 + 0.657172 -0.071779 0.616564 0.000000 + 0.417475 -0.421678 0.489845 0.000000 + 0.606498 -0.639547 0.317255 0.000000 + 0.020220 -0.641997 0.381850 0.000000 + 0.590270 -0.873674 0.138884 0.000000 + -0.042105 -0.647094 0.371671 0.000000 + 0.487028 -1.069881 -0.117089 0.000000 + 0.572297 -0.995592 -0.010911 0.000000 + -0.200238 -0.658255 0.347187 0.000000 + -0.437094 -0.839413 0.093466 0.000000 + 0.381704 -1.164026 -0.248773 0.000000 + -0.565294 -0.780612 0.267912 0.000000 + -0.594369 -0.799080 0.273259 0.000000 + -0.619102 -0.798885 0.279664 0.000000 + -0.416320 -0.845085 0.118061 0.000000 + -0.301971 -0.901501 0.035876 0.000000 + 0.281033 -1.208845 -0.400076 0.000000 + -0.211275 1.123779 -0.205747 0.000000 + -0.244592 1.170771 -0.029992 0.000000 + 0.150454 1.157113 -0.205534 0.000000 + -0.256118 1.174050 -0.027927 0.000000 + 0.676304 1.017611 0.185525 0.000000 + 0.651342 1.100414 -0.223374 0.000000 + 0.231108 -0.935590 -0.578631 0.000000 + -0.816789 0.236220 -0.369256 0.000000 + 0.592372 0.096259 -0.398043 0.000000 + -0.912500 0.184577 -0.210463 0.000000 + -0.813188 0.518488 0.147904 0.000000 + -0.900642 -0.469737 0.321829 0.000000 + -0.853290 -0.134833 0.392557 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 495 + 1 + 0.000000 + + + + + + 0.962658 -0.085875 0.256738 0.000000 + 0.033146 0.978609 0.203043 0.000000 + -0.268683 -0.186951 0.944912 0.000000 + + + + 0.243952 -0.167843 -0.107657 0.000000 + + + 496 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 497 + 0 + 43 + 0 0 0 0 + + + 1.039976 -0.108249 -0.169325 0.000000 + 0.905066 -0.319821 0.050472 0.000000 + 0.794078 -0.303017 -0.216702 0.000000 + 1.039528 -0.097062 -0.191442 0.000000 + 0.853159 -0.404392 0.141926 0.000000 + 0.646718 -0.606430 0.465508 0.000000 + 0.304618 -0.532170 -0.243587 0.000000 + 0.499191 -0.740690 0.686869 0.000000 + 0.511045 -0.742476 0.680184 0.000000 + 0.278546 -0.780029 0.729074 0.000000 + -0.231940 -0.602574 -0.235285 0.000000 + -0.024052 -0.832709 0.794098 0.000000 + -0.703880 -0.522510 -0.216837 0.000000 + -0.014991 -0.837833 0.791266 0.000000 + -1.302165 0.002468 -0.784536 0.000000 + -1.314230 0.000256 -0.757004 0.000000 + -1.272623 -0.022456 -0.766681 0.000000 + -1.252216 -0.025885 -0.763960 0.000000 + -1.158700 -0.132309 -0.811803 0.000000 + -1.161573 -0.144658 -0.708667 0.000000 + -0.836069 -0.297143 -0.891389 0.000000 + -0.745842 -0.499192 -0.282004 0.000000 + -0.673481 -0.376057 -0.934647 0.000000 + -0.739967 -0.504005 -0.266646 0.000000 + -0.337627 -0.431707 -0.987744 0.000000 + -0.131165 -0.461975 -1.023902 0.000000 + 0.177349 -0.419102 -1.048308 0.000000 + 0.415054 -0.382052 -1.070911 0.000000 + 0.665611 -0.264492 -1.069008 0.000000 + 0.872487 -0.178494 -0.966309 0.000000 + 0.760375 -0.224303 -1.069039 0.000000 + 1.107037 0.010239 -0.687306 0.000000 + 1.114994 0.017549 -0.673707 0.000000 + 1.111975 0.006293 -0.685023 0.000000 + 0.056356 0.295370 1.364438 0.000000 + -0.140872 -0.026765 1.403259 0.000000 + -0.111233 -0.076802 1.412362 0.000000 + 0.013543 -0.015142 1.412095 0.000000 + 0.113506 0.473936 1.269224 0.000000 + -0.016960 0.848783 0.746618 0.000000 + -1.033109 0.285337 0.039500 0.000000 + 0.396809 0.690147 -0.776451 0.000000 + 0.494986 0.758336 -0.670775 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 498 + 1 + 0.000000 + + + + + + 0.697870 0.210095 0.684717 0.000000 + -0.214436 0.973445 -0.080131 0.000000 + -0.683370 -0.090908 0.724391 0.000000 + + + + -0.125315 -0.183984 0.084187 0.000000 + + + 499 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 500 + 0 + 34 + 0 0 0 0 + + + -1.184960 0.576836 0.275827 0.000000 + 0.337760 0.605606 0.386486 0.000000 + 0.194225 1.046593 0.106815 0.000000 + -1.195611 0.751712 0.168237 0.000000 + -1.172156 0.280085 0.452807 0.000000 + -1.146518 0.095373 0.499298 0.000000 + 0.466276 0.094776 0.512405 0.000000 + -1.104714 -0.248312 0.580897 0.000000 + -1.066889 -0.429834 0.568661 0.000000 + 0.567170 -0.435812 0.472212 0.000000 + -0.999886 -0.782050 0.540261 0.000000 + -0.943182 -1.012559 0.452262 0.000000 + -0.471797 -0.913392 0.422315 0.000000 + -0.952233 -0.949512 0.471323 0.000000 + 0.605057 -0.716851 0.374971 0.000000 + 1.632071 -0.429464 0.037709 0.000000 + 2.010179 -0.347214 -0.061042 0.000000 + 1.971534 -0.192664 0.004115 0.000000 + 1.840365 0.004848 0.056239 0.000000 + 1.652602 0.295126 0.125626 0.000000 + 1.353084 0.546963 0.139195 0.000000 + 1.131104 0.735987 0.144561 0.000000 + 0.564056 1.028715 0.072283 0.000000 + 0.456121 1.084747 0.056772 0.000000 + 0.110322 1.184487 -0.028509 0.000000 + -0.864847 0.958895 0.006729 0.000000 + -0.143829 1.214627 -0.113674 0.000000 + -1.190741 0.793487 0.136273 0.000000 + -1.072256 0.889853 0.049593 0.000000 + -0.462825 -0.498466 -0.851359 0.000000 + -0.336014 -0.213396 -0.886964 0.000000 + 1.154708 -0.375943 -0.386440 0.000000 + -0.772446 -0.638158 -0.594604 0.000000 + -0.371101 -0.013886 -0.801080 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 501 + 1 + 0.000000 + + + + + + 0.699558 -0.557454 0.447061 0.000000 + 0.404350 0.824645 0.395552 0.000000 + -0.589169 -0.095942 0.802294 0.000000 + + + + -0.025514 0.253344 -0.170900 0.000000 + + + 502 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 503 + 0 + 51 + 0 0 0 0 + + + 1.082339 -0.155548 0.781795 0.000000 + 0.564684 0.009453 1.015651 0.000000 + 0.555036 -0.363211 1.315045 0.000000 + 1.292523 -0.082644 0.565195 0.000000 + 1.286599 0.063480 0.332471 0.000000 + 0.481343 0.350320 0.603464 0.000000 + 1.353016 -0.060145 0.484241 0.000000 + 1.220246 0.219009 0.166790 0.000000 + 1.093918 0.343546 -0.082102 0.000000 + 0.329570 0.551425 0.124464 0.000000 + 0.999589 0.435832 -0.275998 0.000000 + 0.847683 0.468344 -0.540159 0.000000 + 0.124256 0.593175 -0.374444 0.000000 + 0.734184 0.489786 -0.744904 0.000000 + 0.572815 0.427637 -0.996073 0.000000 + -0.114495 0.471571 -0.844464 0.000000 + 0.449980 0.375526 -1.194066 0.000000 + 0.296360 0.227957 -1.405764 0.000000 + -0.363332 0.198571 -1.239668 0.000000 + 0.174810 0.104160 -1.579481 0.000000 + 0.044452 -0.109388 -1.731248 0.000000 + -0.597940 -0.199107 -1.521465 0.000000 + -0.064344 -0.297760 -1.863348 0.000000 + -0.592661 -0.270997 -1.571095 0.000000 + -0.089363 -0.352450 -1.893898 0.000000 + -0.595877 -0.412681 -1.661463 0.000000 + -0.601846 -0.177429 -1.530514 0.000000 + -0.606275 -0.171318 -1.524506 0.000000 + -0.622496 0.233904 -1.233457 0.000000 + -0.630721 0.324230 -1.164358 0.000000 + -0.638255 0.564286 -0.859220 0.000000 + -0.647323 0.694326 -0.688902 0.000000 + -0.648228 0.799962 -0.418142 0.000000 + -0.654473 0.903386 -0.145560 0.000000 + -0.650907 0.915699 0.074351 0.000000 + -0.651427 0.932212 0.412223 0.000000 + -0.644686 0.881362 0.587195 0.000000 + -0.638392 0.779198 0.930702 0.000000 + -0.628670 0.674913 1.072232 0.000000 + -0.616547 0.459496 1.360758 0.000000 + -0.603375 0.294222 1.470767 0.000000 + 0.530680 -0.372351 1.334433 0.000000 + -0.587985 0.003253 1.661526 0.000000 + 0.524610 -0.375012 1.339161 0.000000 + -0.420921 -0.320529 1.679014 0.000000 + -0.571005 -0.235829 1.724407 0.000000 + -0.572777 -0.296984 1.747690 0.000000 + 0.335598 -0.440747 1.436121 0.000000 + 0.224059 -0.482836 -1.299346 0.000000 + -0.562317 -0.808284 0.010329 0.000000 + -0.557747 -0.804363 0.417170 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 504 + 1 + 0.000000 + + + + + + 0.769113 0.194984 0.608643 0.000000 + 0.230726 0.803394 -0.548930 0.000000 + -0.596013 0.562619 0.572913 0.000000 + + + + -0.296284 0.293714 0.154533 0.000000 + + + 505 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 506 + 0 + 69 + 0 0 0 0 + + + 0.630671 1.490238 0.952471 0.000000 + 0.610549 1.505064 0.878866 0.000000 + 0.118578 1.682096 0.683647 0.000000 + 0.518016 1.504643 1.036335 0.000000 + 0.557648 1.570285 0.643020 0.000000 + -0.003910 1.730709 0.586645 0.000000 + 0.492715 1.552012 0.297891 0.000000 + -0.262744 1.723123 0.080301 0.000000 + -0.274061 1.780008 0.366679 0.000000 + 0.459023 1.538694 0.100418 0.000000 + 0.415150 1.396583 -0.233717 0.000000 + -0.227180 1.486225 -0.405136 0.000000 + 0.397498 1.325455 -0.394012 0.000000 + 0.382516 1.076484 -0.661660 0.000000 + -0.230697 1.113391 -0.797438 0.000000 + 0.379114 0.951554 -0.791721 0.000000 + 0.708405 -1.521566 -0.613645 0.000000 + 0.742246 -1.363709 -0.760519 0.000000 + 0.783562 -1.500659 -0.684655 0.000000 + -0.527381 -1.692602 0.862963 0.000000 + -0.523885 -1.691407 0.852578 0.000000 + -0.532458 -1.682369 0.853229 0.000000 + -0.857521 -1.638953 0.460547 0.000000 + -0.319297 -1.778731 0.476163 0.000000 + -0.743257 -1.653824 0.672590 0.000000 + -0.857755 -1.638990 0.458385 0.000000 + -0.103977 -1.773179 0.192035 0.000000 + -0.900218 -1.617804 0.385224 0.000000 + -0.861644 -1.600916 0.348748 0.000000 + -0.870638 -1.628285 0.434611 0.000000 + -0.517322 -1.609668 -0.025373 0.000000 + 0.086663 -1.766907 -0.047918 0.000000 + -0.425765 -1.571702 -0.132068 0.000000 + 0.509619 -1.624046 -0.469202 0.000000 + -0.134993 -1.430227 -0.493347 0.000000 + 0.560699 -1.607731 -0.510712 0.000000 + -0.031781 -1.282568 -0.646884 0.000000 + 0.711896 -1.273906 -0.836678 0.000000 + 0.104351 -1.073917 -0.859178 0.000000 + 0.709193 -1.261424 -0.846238 0.000000 + 0.139725 -0.853224 -0.961291 0.000000 + 0.603603 -0.821272 -1.035691 0.000000 + 0.177544 -0.575958 -1.087295 0.000000 + 0.579267 -0.710322 -1.082120 0.000000 + 0.144727 -0.366588 -1.112163 0.000000 + 0.511076 -0.338458 -1.128561 0.000000 + 0.077296 0.015209 -1.155292 0.000000 + 0.474667 -0.119138 -1.153666 0.000000 + 0.026264 0.140953 -1.135897 0.000000 + 0.438398 0.159301 -1.106829 0.000000 + -0.186987 0.641292 -1.055960 0.000000 + 0.405696 0.453683 -1.053572 0.000000 + -0.194148 0.652964 -1.051126 0.000000 + 0.392636 0.645554 -0.954872 0.000000 + -0.230721 0.706430 -1.027865 0.000000 + -0.451754 1.088528 -0.901025 0.000000 + -0.499108 1.160064 -0.876414 0.000000 + -0.753777 1.441818 -0.679385 0.000000 + -0.876841 1.568428 -0.588885 0.000000 + -0.668309 1.710359 -0.201936 0.000000 + -0.889644 1.586838 -0.585134 0.000000 + -0.583134 1.761533 -0.051919 0.000000 + -0.413492 1.787600 0.251395 0.000000 + 0.742051 -0.146358 0.706092 0.000000 + 0.802135 -0.268486 0.512915 0.000000 + 0.791094 0.055048 0.699333 0.000000 + 0.189881 -0.186233 1.107006 0.000000 + -0.161853 -1.061794 1.016209 0.000000 + 0.483701 -0.321197 0.872791 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 507 + 1 + 0.000000 + + + + + + 0.977161 -0.204508 -0.057733 0.000000 + 0.211052 0.965664 0.151492 0.000000 + 0.024769 -0.160217 0.986771 0.000000 + + + + 0.020288 0.143868 0.269107 0.000000 + + + 508 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 509 + 0 + 50 + 0 0 0 0 + + + 0.098246 0.888906 -0.461909 0.000000 + 0.628068 0.539523 1.583877 0.000000 + 1.103100 0.380538 1.378689 0.000000 + 0.420872 0.617405 -0.801526 0.000000 + -0.269227 0.360981 -2.116015 0.000000 + 0.637346 0.220506 -1.099581 0.000000 + 0.726409 -0.262929 -1.326841 0.000000 + 0.174896 -0.009716 -1.847626 0.000000 + -0.270872 0.364642 -2.121370 0.000000 + -0.366337 0.609225 -2.042734 0.000000 + -0.358747 0.606602 -2.049167 0.000000 + -0.280008 0.710842 -1.746109 0.000000 + -0.183274 0.838432 -1.400839 0.000000 + -0.124953 0.946266 -0.830807 0.000000 + -0.112774 0.973203 -0.688523 0.000000 + -0.161249 0.974688 -0.198338 0.000000 + -0.193477 0.969053 0.032989 0.000000 + -0.577930 0.503593 1.510417 0.000000 + -0.574498 0.497611 1.512572 0.000000 + -0.750501 0.562479 1.209197 0.000000 + -0.761740 0.560755 1.214207 0.000000 + -0.451309 0.516960 1.535276 0.000000 + -0.559693 0.712604 0.942880 0.000000 + 0.074091 0.591355 1.637260 0.000000 + -0.425039 0.821585 0.743187 0.000000 + 0.098345 0.589570 1.639088 0.000000 + -0.212611 0.954025 0.114220 0.000000 + 0.291646 0.570415 1.657514 0.000000 + 0.630252 0.543701 1.692436 0.000000 + 0.666725 0.537614 1.699057 0.000000 + 1.060967 0.404892 1.596751 0.000000 + 1.010035 0.417975 1.697043 0.000000 + 1.106634 0.396910 1.516780 0.000000 + 1.183286 0.349212 1.301541 0.000000 + 1.307904 0.205011 0.837074 0.000000 + 1.312982 0.155608 0.714958 0.000000 + 1.336169 -0.096904 0.177503 0.000000 + 1.283994 -0.266928 -0.103973 0.000000 + 1.219791 -0.480551 -0.439784 0.000000 + 0.947759 -0.872231 -1.012235 0.000000 + 0.969719 -0.907903 -0.953261 0.000000 + 0.976218 -0.912878 -0.963251 0.000000 + 0.872552 -0.757480 -1.143367 0.000000 + 1.046921 -0.774908 -0.797412 0.000000 + 0.727368 -0.538367 -1.394960 0.000000 + 0.374239 -0.189106 -1.689678 0.000000 + -0.639907 -1.149648 0.869428 0.000000 + -0.671292 -1.210605 0.802031 0.000000 + -1.454164 -0.216953 -0.251262 0.000000 + -0.709922 0.324521 -1.714827 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 510 + 1 + 0.000000 + + + + + + 0.795920 0.448524 0.406618 0.000000 + -0.135227 0.786394 -0.602743 0.000000 + -0.590106 0.424749 0.686559 0.000000 + + + + -0.066894 0.293589 0.139174 0.000000 + + + 511 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 512 + 0 + 45 + 0 0 0 0 + + + -1.264341 0.725895 0.109276 0.000000 + -1.258929 0.715984 0.144787 0.000000 + -1.555965 0.332206 -0.333987 0.000000 + -1.652693 0.312398 0.055866 0.000000 + -1.245621 0.742661 0.109765 0.000000 + -1.233649 0.744727 0.120237 0.000000 + -0.407910 1.226950 0.306139 0.000000 + -0.902632 0.781026 -0.257657 0.000000 + 0.119559 1.529972 0.433871 0.000000 + 0.296075 1.591529 0.466466 0.000000 + -0.482430 0.705470 -0.590458 0.000000 + 0.280661 1.607435 0.474334 0.000000 + 0.592817 1.510389 0.188076 0.000000 + 1.136956 0.384267 -0.496115 0.000000 + 1.160482 0.508223 -0.464142 0.000000 + 1.155063 0.330660 -0.523008 0.000000 + 0.950217 0.599272 -0.508421 0.000000 + 1.182972 0.808930 -0.341800 0.000000 + 0.707667 0.665473 -0.525386 0.000000 + 1.055923 1.217680 -0.096817 0.000000 + 1.166519 1.122605 -0.143504 0.000000 + 0.306888 0.767466 -0.556733 0.000000 + 0.999589 1.269964 -0.074576 0.000000 + 0.141458 0.750585 -0.569250 0.000000 + 0.670240 1.463649 0.134839 0.000000 + -0.420940 0.706319 -0.600754 0.000000 + -0.370242 0.702629 -0.606743 0.000000 + -0.493834 0.713443 -0.592536 0.000000 + -0.496683 0.709480 -0.594489 0.000000 + -0.988756 0.596034 -0.512683 0.000000 + -1.082678 0.569169 -0.500273 0.000000 + -1.461672 0.348556 -0.419498 0.000000 + -1.528307 0.321995 -0.410653 0.000000 + 0.683371 0.881755 0.664051 0.000000 + 0.511524 0.044609 0.721060 0.000000 + 0.733898 0.852955 0.620265 0.000000 + -0.153728 -1.201054 0.674258 0.000000 + 0.422486 -1.762130 0.001609 0.000000 + 0.161031 -1.356732 0.793581 0.000000 + 0.132460 -1.561977 -0.221053 0.000000 + 0.431533 -1.769562 -0.012377 0.000000 + -0.762575 -0.795223 0.450709 0.000000 + 0.098195 -1.487586 -0.383624 0.000000 + 0.666139 -1.663858 -0.458812 0.000000 + 0.848540 -1.065640 -0.561610 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 513 + 1 + 0.000000 + + + + + + 0.666992 0.337554 -0.664213 0.000000 + -0.443753 0.896095 0.009788 0.000000 + 0.598502 0.288218 0.747479 0.000000 + + + + 0.053015 -0.300733 0.024304 0.000000 + + + 514 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 515 + 0 + 62 + 0 0 0 0 + + + -0.015088 -1.485293 -1.024312 0.000000 + -0.042853 -1.490780 -0.489220 0.000000 + -0.177322 -1.535921 -1.064891 0.000000 + 0.294294 -1.267201 -0.957367 0.000000 + 0.388256 -1.184417 -0.373801 0.000000 + 0.422585 -1.174492 -0.932911 0.000000 + 0.649423 -0.868436 -0.903073 0.000000 + 0.702128 -0.756133 -0.267983 0.000000 + 0.743399 -0.738492 -0.894274 0.000000 + 0.862645 -0.384171 -0.903744 0.000000 + 0.867947 -0.247840 -0.182142 0.000000 + 0.915752 -0.220096 -0.912215 0.000000 + 0.920776 0.133103 -0.932814 0.000000 + 0.869403 0.290664 -0.124701 0.000000 + 0.921655 0.029687 -0.940914 0.000000 + 0.920184 0.319376 -0.918133 0.000000 + 0.812618 0.666570 -0.915375 0.000000 + 0.706316 0.806585 -0.101298 0.000000 + 0.756106 0.842396 -0.917975 0.000000 + 0.551578 1.137378 -0.948062 0.000000 + 0.394664 1.249331 -0.114230 0.000000 + 0.442113 1.291613 -0.968142 0.000000 + 0.168228 1.502979 -1.025925 0.000000 + -0.034985 1.575500 -0.162227 0.000000 + 0.009206 1.622809 -1.063685 0.000000 + -0.390682 1.745963 -0.619509 0.000000 + -0.540486 1.753144 -0.240575 0.000000 + -0.027034 1.648800 -1.072632 0.000000 + -0.489854 1.773580 -0.496882 0.000000 + -0.696502 1.771100 -0.245787 0.000000 + -0.724241 1.707255 0.115185 0.000000 + -0.808580 1.754511 -0.118081 0.000000 + -0.675577 1.674469 0.272076 0.000000 + -0.513013 1.497960 0.710879 0.000000 + -0.400275 1.363620 1.035044 0.000000 + -0.310121 1.201693 1.263621 0.000000 + -0.165032 0.925297 1.651043 0.000000 + -0.129452 0.822868 1.731485 0.000000 + -0.087485 0.701202 1.827628 0.000000 + 0.039275 0.445907 1.895170 0.000000 + 0.059329 0.379324 1.898303 0.000000 + 0.182944 -0.084847 1.929127 0.000000 + 0.184973 -0.135252 1.922108 0.000000 + 0.182367 -0.626562 1.867977 0.000000 + 0.175133 -0.659683 1.856525 0.000000 + 0.037855 -1.126697 1.717785 0.000000 + 0.027538 -1.146379 1.705435 0.000000 + -0.120837 -1.476971 1.248736 0.000000 + 0.004404 -1.207921 1.674783 0.000000 + -0.170809 -1.528912 1.068131 0.000000 + -0.344058 -1.681007 0.525269 0.000000 + -0.533893 -1.706445 -0.061669 0.000000 + -0.548928 -1.645298 -0.602937 0.000000 + -0.612891 -1.715115 -0.295501 0.000000 + -0.735482 -1.656263 -0.665344 0.000000 + -0.789087 -1.660130 -0.824473 0.000000 + -0.617942 -1.650838 -1.023159 0.000000 + -0.517185 -1.641532 -1.062068 0.000000 + -0.596731 -1.652480 -1.048799 0.000000 + -0.290701 -1.573756 -1.092181 0.000000 + -0.144428 -0.049661 -1.249842 0.000000 + -0.355512 -0.998288 -1.187238 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 516 + 1 + 0.000000 + + + + + + 0.727518 0.297961 -0.618010 0.000000 + 0.299931 0.672017 0.677077 0.000000 + 0.617056 -0.677947 0.399537 0.000000 + + + + -0.153050 0.197006 -0.151022 0.000000 + + + 517 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 518 + 0 + 40 + 0 0 0 0 + + + 0.484764 0.181296 -0.431911 0.000000 + -0.956799 0.246973 0.141485 0.000000 + 0.737998 0.156741 0.045559 0.000000 + -0.814631 0.227478 0.663133 0.000000 + 0.986265 -0.033143 0.487277 0.000000 + 1.314449 0.343740 -0.351688 0.000000 + 1.311504 0.261583 -0.141509 0.000000 + 1.172099 0.355423 -0.596860 0.000000 + 1.124849 0.359951 -0.681455 0.000000 + 0.996397 0.328552 -0.741791 0.000000 + 0.449784 0.130030 -0.914930 0.000000 + 0.251314 0.038193 -0.898450 0.000000 + 0.357021 0.094970 -0.945544 0.000000 + 0.169068 -0.014348 -0.981409 0.000000 + -0.413599 -0.225829 -1.164273 0.000000 + -0.825318 -0.198007 -0.994493 0.000000 + -0.835356 -0.187595 -0.947374 0.000000 + -0.335441 -0.213641 -1.138808 0.000000 + -0.863504 -0.111353 -0.817892 0.000000 + -0.958379 0.124820 -0.404117 0.000000 + -0.960602 0.134003 -0.372553 0.000000 + -0.984554 0.194179 -0.135932 0.000000 + -1.026298 0.296302 0.130189 0.000000 + -1.033667 0.294350 0.145538 0.000000 + -1.027759 0.302127 0.141241 0.000000 + -0.864019 0.268264 0.637688 0.000000 + -0.856531 0.265952 0.665408 0.000000 + -0.737556 0.171842 0.861000 0.000000 + -0.787622 0.198790 0.850319 0.000000 + -0.331099 0.059018 0.990464 0.000000 + 0.645572 -0.176680 0.921041 0.000000 + -0.107941 -0.042786 1.036322 0.000000 + 0.160125 -0.144744 1.101258 0.000000 + 1.147285 -0.213381 0.734486 0.000000 + 1.269692 0.032865 0.367315 0.000000 + 1.138742 -0.208288 0.747512 0.000000 + 1.316243 0.102002 0.249545 0.000000 + -0.828755 -0.092702 0.673475 0.000000 + -0.824820 -0.091211 0.683182 0.000000 + -0.062964 -0.207829 -1.008848 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 519 + 1 + 0.000000 + + + + + + 0.697191 0.452889 0.555713 0.000000 + -0.528603 0.848399 -0.028240 0.000000 + -0.484255 -0.274063 0.830895 0.000000 + + + + 0.159321 0.103551 0.096018 0.000000 + + + 520 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 521 + 0 + 30 + 0 0 0 0 + + + -0.143671 -0.304132 1.240610 0.000000 + -0.391904 -0.087774 -1.166004 0.000000 + 0.121734 -0.215051 -1.051097 0.000000 + -0.551143 0.031323 -1.346195 0.000000 + -0.305006 -0.026335 -1.503399 0.000000 + -0.606002 0.009318 -1.207839 0.000000 + -0.203617 -0.044507 -1.571527 0.000000 + 0.116059 -0.077849 -1.695069 0.000000 + 0.174139 -0.101576 -1.632220 0.000000 + 0.281748 -0.149504 -1.534060 0.000000 + 0.608516 -0.216632 -0.933590 0.000000 + 0.643697 -0.174654 -0.913029 0.000000 + 0.614179 -0.217285 -0.923858 0.000000 + 0.620969 -0.220862 -0.892005 0.000000 + 0.932765 -0.080453 0.334333 0.000000 + 0.790601 -0.119102 0.458098 0.000000 + 0.414857 -0.268864 0.814926 0.000000 + 0.333476 -0.277942 0.883037 0.000000 + -0.043162 -0.318891 1.199858 0.000000 + -0.150224 -0.321484 1.283096 0.000000 + -0.133291 -0.337127 1.270088 0.000000 + -0.121263 -0.332881 1.271122 0.000000 + -0.337973 -0.293819 1.189977 0.000000 + -0.642209 -0.213021 1.055077 0.000000 + -0.734097 -0.033053 -0.127078 0.000000 + -0.661911 -0.203365 1.036168 0.000000 + -0.863831 -0.075234 0.887690 0.000000 + 0.263399 0.491845 0.693106 0.000000 + -0.120624 0.267785 -0.964763 0.000000 + 0.217403 0.515874 0.663400 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 522 + 1 + 0.000000 + + + + + + 0.940066 -0.069037 -0.333930 0.000000 + 0.025310 0.990716 -0.133570 0.000000 + 0.340051 0.117113 0.933086 0.000000 + + + + -0.170465 -0.144877 -0.006843 0.000000 + + + 523 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 524 + 0 + 29 + 0 0 0 0 + + + 1.141971 -0.319053 0.250459 0.000000 + -0.429467 -0.343152 0.022254 0.000000 + -0.127644 -0.325591 -0.426649 0.000000 + 1.187009 -0.314567 0.183315 0.000000 + 0.900493 -0.331889 0.636481 0.000000 + 0.800675 -0.300756 0.722653 0.000000 + -0.727121 -0.192908 0.448709 0.000000 + 0.485023 -0.187868 1.008461 0.000000 + 0.099788 0.027701 1.208152 0.000000 + -0.869761 0.045006 0.830858 0.000000 + -0.859930 0.079537 0.849466 0.000000 + 0.281353 -0.073851 1.109129 0.000000 + -0.880816 0.000662 0.718571 0.000000 + -0.936371 -0.207721 0.298407 0.000000 + -0.953086 -0.243782 0.209851 0.000000 + -1.001377 -0.373760 -0.322605 0.000000 + -1.018208 -0.436524 -0.528351 0.000000 + -1.020391 -0.432271 -0.529372 0.000000 + -0.812913 -0.420760 -0.765924 0.000000 + -0.669621 -0.409987 -0.934816 0.000000 + -0.663858 -0.415802 -0.938647 0.000000 + 0.146934 -0.185973 -0.798530 0.000000 + 1.319125 -0.138257 -0.309786 0.000000 + 0.206638 -0.179937 -0.792019 0.000000 + 1.304934 0.073834 -0.640283 0.000000 + 1.296476 -0.168107 -0.230905 0.000000 + -0.723939 0.482305 -0.304083 0.000000 + 0.409357 0.607186 -0.248312 0.000000 + -0.835975 0.427140 -0.203366 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 525 + 1 + 0.000000 + + + + + + 0.709605 -0.648802 0.274803 0.000000 + 0.440886 0.713083 0.545098 0.000000 + -0.549618 -0.265647 0.792055 0.000000 + + + + -0.091277 0.142486 -0.005874 0.000000 + + + 526 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 527 + 0 + 50 + 0 0 0 0 + + + -0.742900 0.548696 0.562127 0.000000 + 0.211123 0.044223 0.420503 0.000000 + -0.619780 0.937982 0.490058 0.000000 + -0.792283 0.401834 0.543681 0.000000 + -0.075894 -0.410754 0.363466 0.000000 + -0.926897 0.032941 0.491525 0.000000 + -0.986365 -0.118971 0.417612 0.000000 + -0.337107 -0.830054 0.143118 0.000000 + -1.018587 -0.471856 0.260191 0.000000 + -0.984026 -0.131441 0.421104 0.000000 + -1.014383 -0.712112 0.058646 0.000000 + -0.547000 -1.172715 -0.218995 0.000000 + -1.014235 -0.933402 -0.133083 0.000000 + -1.007884 -1.032952 -0.253487 0.000000 + -0.562332 -1.176898 -0.192572 0.000000 + -0.471142 -1.242999 -0.165440 0.000000 + 0.002640 -1.581739 -0.045896 0.000000 + -0.004310 -1.576374 -0.087033 0.000000 + 0.250290 -1.584576 0.080235 0.000000 + 0.292989 -1.586159 0.109512 0.000000 + 0.371555 -1.528669 0.207931 0.000000 + 0.396673 -1.417139 0.294361 0.000000 + 0.440279 -1.241361 0.363430 0.000000 + 0.535123 -0.898257 0.495283 0.000000 + 0.615245 -0.636215 0.514520 0.000000 + 0.709175 -0.349219 0.532897 0.000000 + 0.823580 -0.030176 0.455601 0.000000 + 0.495897 0.490420 0.308610 0.000000 + 0.901757 0.175989 0.403067 0.000000 + 1.034921 0.493132 0.204249 0.000000 + 0.750583 0.884203 0.038653 0.000000 + 1.093902 0.625598 0.118315 0.000000 + 1.186575 0.790063 -0.062296 0.000000 + 0.821166 0.989093 -0.061385 0.000000 + 0.120916 1.379235 -0.018407 0.000000 + 0.162745 1.412331 -0.047343 0.000000 + -0.034824 1.286290 0.158890 0.000000 + -0.242834 1.161334 0.291487 0.000000 + -0.518770 1.002129 0.460097 0.000000 + -0.616785 0.943152 0.493147 0.000000 + 0.348761 -1.540481 0.188254 0.000000 + 0.339028 -1.559854 0.105078 0.000000 + 0.379115 -1.488374 -0.044736 0.000000 + 0.543042 -1.161242 -0.139833 0.000000 + -0.515420 1.034410 -0.306691 0.000000 + -0.492806 1.058179 -0.329897 0.000000 + -0.531057 0.344067 -0.618160 0.000000 + -0.675642 0.073386 -0.551393 0.000000 + 0.961354 -0.065827 -0.445498 0.000000 + -0.656673 0.928239 0.142077 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 528 + 1 + 0.000000 + + + + + + 0.924541 -0.032198 -0.379719 0.000000 + -0.183508 0.835671 -0.517667 0.000000 + 0.333988 0.548286 0.766704 0.000000 + + + + 0.057490 0.080270 -0.032472 0.000000 + + + 529 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 530 + 0 + 53 + 0 0 0 0 + + + -0.303040 -0.349334 1.257611 0.000000 + -0.560185 -0.698504 0.454506 0.000000 + -0.229958 -1.067541 0.673707 0.000000 + -0.129696 -0.691120 1.235242 0.000000 + -0.402293 -0.141443 1.273601 0.000000 + -0.474982 0.166974 1.242628 0.000000 + -0.741636 -0.263259 0.188128 0.000000 + -0.534490 0.442132 1.218192 0.000000 + -0.527505 0.694160 1.152012 0.000000 + -0.756507 0.195520 -0.099308 0.000000 + -0.514237 1.002175 1.075003 0.000000 + -0.450036 1.189594 0.989054 0.000000 + -0.603353 0.632849 -0.379621 0.000000 + -0.344625 1.484429 0.858461 0.000000 + -0.240788 1.609699 0.762612 0.000000 + -0.297227 1.005864 -0.625331 0.000000 + -0.090947 1.798774 0.625243 0.000000 + -0.073202 1.793410 0.572363 0.000000 + 0.121768 1.332376 -0.721725 0.000000 + 0.214115 1.644362 -0.262825 0.000000 + 0.355095 1.533163 -0.570785 0.000000 + 0.106736 1.314578 -0.732677 0.000000 + 0.077782 1.713092 0.121229 0.000000 + 0.060186 1.258475 -0.767438 0.000000 + -0.203078 0.855284 -0.982519 0.000000 + -0.264252 0.748191 -1.042202 0.000000 + -0.410108 0.321650 -1.214394 0.000000 + -0.485883 0.083803 -1.321858 0.000000 + -0.500617 0.074361 -1.315706 0.000000 + -0.561444 -0.163097 -1.212026 0.000000 + -0.629731 -0.400744 -1.110817 0.000000 + -0.620175 -0.646126 -0.989858 0.000000 + -0.606801 -0.894630 -0.872103 0.000000 + -0.517537 -1.115066 -0.751938 0.000000 + -0.419439 -1.349424 -0.629145 0.000000 + -0.262955 -1.525232 -0.520888 0.000000 + -0.086164 -1.720611 -0.405748 0.000000 + 0.103425 -1.692890 -0.034874 0.000000 + 0.216639 -1.334211 0.824257 0.000000 + 0.032398 -1.800549 -0.352133 0.000000 + 0.218452 -1.530143 0.486449 0.000000 + 0.316483 -1.369146 0.855923 0.000000 + 0.319395 -1.202126 1.075523 0.000000 + 0.389426 -1.256537 1.051428 0.000000 + 0.256970 -1.152383 1.106455 0.000000 + -0.030193 -0.816213 1.199411 0.000000 + 0.488830 -0.327370 -0.977278 0.000000 + 0.611731 1.107533 -0.566427 0.000000 + 0.973802 0.175013 0.309435 0.000000 + 0.993975 0.057333 0.357415 0.000000 + 0.559331 -0.666944 -0.808820 0.000000 + 0.922787 0.243158 0.349601 0.000000 + 0.991635 0.037713 0.365930 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 531 + 1 + 0.000000 + + + + + + 0.998862 -0.041799 0.022972 0.000000 + 0.045531 0.979103 -0.198201 0.000000 + -0.014207 0.199021 0.979892 0.000000 + + + + -0.311999 0.143146 0.171851 0.000000 + + + 532 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 533 + 0 + 50 + 0 0 0 0 + + + -1.159148 0.455282 -0.240084 0.000000 + 0.152039 0.400769 1.032666 0.000000 + 0.451766 0.552115 0.608325 0.000000 + -0.983073 0.430428 -0.751259 0.000000 + 0.775596 0.536143 0.174968 0.000000 + -0.814641 0.239719 -1.229061 0.000000 + 1.091840 0.354319 -0.224987 0.000000 + -0.670355 -0.098257 -1.626672 0.000000 + 1.369519 0.024361 -0.552345 0.000000 + -1.325635 0.311946 0.254429 0.000000 + -0.519799 -0.248415 1.499730 0.000000 + -0.525137 -0.255221 1.489452 0.000000 + -0.865977 -0.105583 1.164668 0.000000 + 0.021006 0.302729 1.147025 0.000000 + -0.223100 0.127568 1.300114 0.000000 + 0.164230 0.418113 1.061149 0.000000 + 0.178622 0.425899 1.056043 0.000000 + 0.561734 0.577574 0.813845 0.000000 + 0.628478 0.600647 0.776072 0.000000 + 0.985424 0.606346 0.551679 0.000000 + 1.098976 0.605822 0.484966 0.000000 + 1.405664 0.493567 0.292999 0.000000 + 1.544174 0.441425 0.211108 0.000000 + 1.786496 0.237510 0.059997 0.000000 + 1.920874 0.123834 -0.018970 0.000000 + 1.846856 -0.222495 -0.413771 0.000000 + 2.089611 -0.149403 -0.123790 0.000000 + 2.160202 -0.219473 -0.154037 0.000000 + 1.517400 -0.234720 -0.710097 0.000000 + -0.022092 -0.323349 -1.520360 0.000000 + -0.418302 -0.347456 -1.739985 0.000000 + -0.613561 -0.109290 -1.646987 0.000000 + -0.649733 -0.057468 -1.625553 0.000000 + -0.652820 -0.063115 -1.625019 0.000000 + -0.984147 0.251943 -1.293498 0.000000 + -1.019500 0.277812 -1.261753 0.000000 + -1.265290 0.442081 -0.874083 0.000000 + -1.313592 0.468732 -0.803732 0.000000 + -1.468477 0.490448 -0.391147 0.000000 + -1.507411 0.492998 -0.295734 0.000000 + -1.533028 0.364997 0.139525 0.000000 + -1.520591 0.466083 -0.193502 0.000000 + -1.536387 0.342106 0.217117 0.000000 + -1.419831 0.086858 0.630057 0.000000 + -1.495856 0.125695 0.568533 0.000000 + -1.323543 0.064301 0.736923 0.000000 + -0.251476 0.105858 1.318964 0.000000 + -1.443371 0.068535 0.504817 0.000000 + -0.963311 -0.528363 0.289228 0.000000 + -0.284447 -0.551269 1.360752 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 534 + 1 + 0.000000 + + + + + + 0.983455 0.178784 0.029208 0.000000 + -0.155868 0.917274 -0.366488 0.000000 + -0.092314 0.355872 0.929964 0.000000 + + + + -0.302572 -0.071095 0.018698 0.000000 + + + 535 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 536 + 0 + 51 + 0 0 0 0 + + + -1.276630 -0.347839 0.081864 0.000000 + -0.884273 -0.381309 -0.263622 0.000000 + -1.266424 -0.424532 0.375883 0.000000 + -1.209098 -0.075261 -0.466148 0.000000 + -1.141381 -0.025963 -0.580262 0.000000 + -1.202490 -0.045317 -0.523565 0.000000 + -1.158157 0.055071 -0.664326 0.000000 + -1.141982 0.112000 -0.783389 0.000000 + -0.893136 0.125658 -1.324272 0.000000 + -0.780420 0.012970 -1.412421 0.000000 + -0.766555 -0.012693 -1.431778 0.000000 + -0.670765 -0.254565 -1.327464 0.000000 + -0.574555 -0.378096 -1.242722 0.000000 + -0.368539 -0.632143 -1.071738 0.000000 + -0.249336 -0.706124 -0.983404 0.000000 + -0.541125 -0.597088 0.094703 0.000000 + 0.028967 -0.872159 -0.787495 0.000000 + 0.161801 -0.896610 -0.701087 0.000000 + -0.145451 -0.652138 0.459695 0.000000 + 0.482773 -0.951338 -0.502542 0.000000 + 0.620713 -0.925712 -0.423212 0.000000 + 0.264063 -0.540989 0.795645 0.000000 + 0.948548 -0.862132 -0.244668 0.000000 + 1.884000 0.048945 0.106722 0.000000 + 1.803628 -0.041864 0.123393 0.000000 + 1.822964 -0.062263 0.114024 0.000000 + 1.621836 -0.188562 0.235859 0.000000 + 1.737695 -0.229124 0.094476 0.000000 + 1.326778 -0.300891 0.384249 0.000000 + 1.496918 -0.488573 0.007336 0.000000 + 0.951111 -0.436081 0.576863 0.000000 + 1.380900 -0.613321 -0.038977 0.000000 + 0.782195 -0.454858 0.651666 0.000000 + 1.081636 -0.785983 -0.178411 0.000000 + 0.355294 -0.501617 0.841153 0.000000 + 0.111918 -0.517119 0.945977 0.000000 + -0.050151 -0.517774 1.021439 0.000000 + -0.777688 -0.480378 1.318155 0.000000 + -0.940595 -0.481975 1.388363 0.000000 + -1.109222 -0.517840 1.260888 0.000000 + -1.178014 -0.514759 1.156037 0.000000 + -1.170528 -0.518503 1.200749 0.000000 + -1.257939 -0.508500 0.722169 0.000000 + 1.884392 0.381726 0.036714 0.000000 + -0.195730 0.477912 -1.187114 0.000000 + -0.401393 0.546656 -1.113659 0.000000 + -0.344617 1.061243 0.404696 0.000000 + -0.274614 1.122430 0.624410 0.000000 + 1.178238 0.629746 0.253628 0.000000 + -0.365505 0.906619 0.840276 0.000000 + -0.808766 0.057044 1.215537 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 537 + 1 + 0.000000 + + + + + + 0.859792 -0.134780 0.492536 0.000000 + 0.206668 0.973859 -0.094277 0.000000 + -0.466954 0.182849 0.865171 0.000000 + + + + 0.005828 0.161011 0.074764 0.000000 + + + 538 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 539 + 0 + 23 + 0 0 0 0 + + + 0.576709 0.779019 0.201091 0.000000 + 0.622014 0.769384 0.152621 0.000000 + 0.213249 0.837096 -0.138389 0.000000 + 0.156826 0.843684 0.130754 0.000000 + 0.733182 0.755958 0.040641 0.000000 + 1.093614 0.583411 -0.257817 0.000000 + 0.860520 0.652537 -0.229249 0.000000 + 0.983991 0.627756 -0.193781 0.000000 + 0.238287 0.823146 -0.225899 0.000000 + -0.205618 0.922249 -0.222440 0.000000 + -0.594757 1.012577 -0.182463 0.000000 + -0.613356 1.012343 -0.229797 0.000000 + -0.594453 1.008775 -0.001495 0.000000 + 0.324479 -1.111246 -0.221902 0.000000 + 1.292363 -0.119134 -0.247719 0.000000 + 0.887928 -0.429701 0.254754 0.000000 + 0.621701 -0.154591 0.454370 0.000000 + -0.936082 -0.313478 0.314019 0.000000 + -0.846277 -1.075228 -0.211507 0.000000 + -1.045215 -0.123371 -0.201052 0.000000 + -1.114715 0.407163 0.099400 0.000000 + -1.114476 0.403216 0.037218 0.000000 + -0.756090 0.846390 -0.221430 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 540 + 1 + 0.000000 + + + + + + 0.825115 0.470222 0.313171 0.000000 + -0.536547 0.825794 0.173728 0.000000 + -0.176924 -0.311376 0.933672 0.000000 + + + + -0.170513 -0.184021 0.245260 0.000000 + + + 541 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 542 + 0 + 49 + 0 0 0 0 + + + 0.128328 -0.468416 -0.867718 0.000000 + -0.379797 -1.105786 0.592634 0.000000 + -0.392544 -0.332163 -0.920980 0.000000 + -0.864320 -0.923939 0.434906 0.000000 + -0.859548 -0.090803 -0.876810 0.000000 + -1.302165 -0.611998 0.374733 0.000000 + -0.858236 -0.090551 -0.877796 0.000000 + -0.852047 -0.089755 -0.881862 0.000000 + -0.453613 -0.252381 -1.169863 0.000000 + -0.363846 -0.285216 -1.237381 0.000000 + -0.019513 -0.322638 -1.413021 0.000000 + 0.179285 -0.339244 -1.517977 0.000000 + 0.447237 -0.294359 -1.605294 0.000000 + 0.657987 -0.444861 -0.759496 0.000000 + 0.726381 -0.242561 -1.700161 0.000000 + 0.705445 -0.262690 -1.702564 0.000000 + 0.957603 -0.221284 -1.345359 0.000000 + 1.144620 -0.263715 -0.606871 0.000000 + 1.148461 -0.193993 -1.085021 0.000000 + 1.459949 -0.048625 -0.432567 0.000000 + 1.606111 0.490230 0.827580 0.000000 + 1.537909 0.279210 0.804319 0.000000 + 1.613522 0.306784 0.498975 0.000000 + 1.453419 0.010846 0.803500 0.000000 + 1.623096 0.217235 0.308655 0.000000 + 1.311361 -0.210287 0.793691 0.000000 + 1.509032 -0.021187 -0.309516 0.000000 + 1.119420 -0.500964 0.786176 0.000000 + 1.504421 -0.022618 -0.332135 0.000000 + 0.980876 -0.621492 0.776329 0.000000 + 0.662619 -0.892785 0.760535 0.000000 + 0.575296 -0.931927 0.753732 0.000000 + 0.128560 -1.126910 0.729095 0.000000 + 0.121764 -1.128079 0.727219 0.000000 + 0.023452 -1.136625 0.722623 0.000000 + -0.439140 -1.213339 0.694247 0.000000 + -0.501990 -1.222288 0.695892 0.000000 + -0.957520 -1.146138 0.664692 0.000000 + -1.080796 -1.125237 0.661117 0.000000 + -1.409481 -0.917355 0.637240 0.000000 + -1.539550 -0.835592 0.631607 0.000000 + -1.694118 -0.606287 0.618593 0.000000 + -1.585614 -0.281760 0.379242 0.000000 + -1.335728 0.174582 -0.487030 0.000000 + -1.581107 -0.164099 0.232417 0.000000 + -1.501231 0.359797 -0.298854 0.000000 + -1.238057 0.118349 -0.566602 0.000000 + -0.000050 1.258564 0.716904 0.000000 + -0.667967 1.181175 -0.122934 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 543 + 1 + 0.000000 + + + + + + 0.954362 0.282772 -0.096087 0.000000 + -0.292493 0.949986 -0.109425 0.000000 + 0.060339 0.132536 0.989340 0.000000 + + + + -0.104428 0.232843 -0.144961 0.000000 + + + 544 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 545 + 0 + 68 + 0 0 0 0 + + + -0.800600 -0.565477 -0.251842 0.000000 + -0.497804 -0.311604 1.142815 0.000000 + -0.881692 -0.038647 -0.343886 0.000000 + -0.573369 0.219860 1.076226 0.000000 + -0.804488 0.475269 -0.494106 0.000000 + -0.480124 0.747226 0.999891 0.000000 + -0.576489 0.926038 -0.687837 0.000000 + -0.227134 1.218948 0.921267 0.000000 + -0.219923 1.269557 -0.906153 0.000000 + -0.931362 -0.536345 -0.440012 0.000000 + -1.000391 -0.090271 -0.521433 0.000000 + -0.917860 -0.623807 -0.427656 0.000000 + -0.750821 -1.031460 -0.441462 0.000000 + -0.569152 -1.053750 -0.226960 0.000000 + -0.709839 -1.131820 -0.448757 0.000000 + -0.476788 -1.453790 -0.545100 0.000000 + -0.209944 -1.455753 -0.271678 0.000000 + -0.396871 -1.564333 -0.582608 0.000000 + -0.135583 -1.776899 -0.736654 0.000000 + 0.241950 -1.732171 -0.381647 0.000000 + -0.087557 -1.822431 -0.760692 0.000000 + -0.000802 -1.851324 -0.747088 0.000000 + 0.375960 -1.781680 -0.402691 0.000000 + 0.097334 -1.871017 -0.729627 0.000000 + 0.871911 -1.746296 0.191247 0.000000 + 0.892561 -1.731697 0.188123 0.000000 + 0.866308 -1.735463 0.204645 0.000000 + 0.865758 -1.746578 0.216680 0.000000 + 0.640594 -1.652905 0.349421 0.000000 + 0.416553 -1.578376 0.499417 0.000000 + 0.257626 -1.456448 0.623175 0.000000 + 0.005988 -1.256439 0.827659 0.000000 + -0.056447 -1.165161 0.889142 0.000000 + -0.298530 -0.797846 1.140449 0.000000 + -0.298702 -0.799704 1.139076 0.000000 + -0.298476 -0.788586 1.145964 0.000000 + -0.515135 -0.364219 1.400352 0.000000 + -0.561970 -0.266147 1.462864 0.000000 + -0.610492 0.043227 1.588542 0.000000 + -0.622391 0.039620 1.589250 0.000000 + -0.630872 0.236986 1.481109 0.000000 + -0.538434 0.663763 1.226588 0.000000 + -0.518253 0.751762 1.176146 0.000000 + -0.244252 1.215348 0.887533 0.000000 + -0.245094 1.213004 0.889951 0.000000 + -0.246213 1.217924 0.879725 0.000000 + 0.112727 1.562429 0.658951 0.000000 + 0.724116 1.623129 -0.798852 0.000000 + 0.674761 1.601916 -0.854772 0.000000 + 0.648306 1.646106 -0.517305 0.000000 + 0.264738 1.521082 -0.915377 0.000000 + 0.466820 1.718875 0.181156 0.000000 + 0.625453 1.587894 -0.914157 0.000000 + 0.224273 1.502348 -0.915067 0.000000 + 0.144914 1.578561 0.644910 0.000000 + 0.372019 1.703300 0.560327 0.000000 + -0.100646 1.343263 -0.924061 0.000000 + -0.255709 1.270675 -0.928635 0.000000 + -0.268402 1.260711 -0.934395 0.000000 + -0.691134 0.910329 -0.961146 0.000000 + -0.778731 0.833561 -0.972642 0.000000 + -0.914832 0.500015 -0.773257 0.000000 + -0.790270 0.820386 -0.972916 0.000000 + -0.949315 0.416268 -0.720846 0.000000 + -0.992213 -0.007557 -0.550990 0.000000 + -0.023868 -0.757414 -1.147498 0.000000 + 0.323925 0.574197 1.204287 0.000000 + -0.011655 -1.171299 -1.030583 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 546 + 1 + 0.000000 + + + + + + 0.942931 0.220595 0.249439 0.000000 + -0.332396 0.668234 0.665564 0.000000 + -0.019864 -0.710494 0.703423 0.000000 + + + + 0.195386 -0.115327 -0.053679 0.000000 + + + 547 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 548 + 0 + 48 + 0 0 0 0 + + + 1.100199 -0.935313 0.052735 0.000000 + 0.773318 -1.044099 0.032065 0.000000 + 1.110535 -0.842562 -0.010848 0.000000 + 1.057109 -1.058943 0.176922 0.000000 + 0.825111 -1.184578 0.214970 0.000000 + 0.393602 -1.367210 0.176137 0.000000 + 0.511180 -1.387091 0.260046 0.000000 + 0.252987 -1.356288 0.064716 0.000000 + -0.067017 -1.278883 -0.102076 0.000000 + 0.599575 -0.662863 -0.310729 0.000000 + -0.333849 -1.217594 -0.233420 0.000000 + -0.575441 -1.129668 -0.294719 0.000000 + 0.386470 -0.205614 -0.507325 0.000000 + -0.950793 -0.997615 -0.383183 0.000000 + -1.043439 -0.897772 -0.380416 0.000000 + 0.154868 0.282876 -0.538385 0.000000 + -0.956823 -0.993963 -0.384756 0.000000 + -1.183169 -0.553576 -0.412342 0.000000 + -1.033686 -0.902456 -0.387705 0.000000 + -1.161046 -0.646447 -0.407054 0.000000 + -1.197682 -0.345615 -0.374479 0.000000 + -0.072534 0.754732 -0.400804 0.000000 + -1.230650 0.034773 -0.296725 0.000000 + -1.220221 0.167197 -0.241141 0.000000 + -1.147838 0.354508 -0.173761 0.000000 + -0.273437 1.163684 -0.108032 0.000000 + -1.016327 0.695036 -0.056522 0.000000 + -0.391015 1.394653 0.165351 0.000000 + -0.769924 1.145937 0.186503 0.000000 + 0.452779 1.559618 0.127336 0.000000 + 0.402348 1.619962 0.198454 0.000000 + 0.554856 1.466913 -0.011513 0.000000 + 0.709398 1.223087 -0.190893 0.000000 + 0.807636 1.073093 -0.297988 0.000000 + 0.926210 0.774781 -0.387753 0.000000 + 1.003720 0.587524 -0.441075 0.000000 + 1.079038 0.248380 -0.434066 0.000000 + 1.124281 0.056938 -0.427130 0.000000 + 1.146115 -0.310068 -0.310290 0.000000 + 1.157603 -0.467632 -0.257232 0.000000 + 0.156912 -1.159198 0.377441 0.000000 + -0.317935 -0.366284 0.646069 0.000000 + -0.720539 -0.132222 0.532117 0.000000 + -0.800416 -0.191312 0.423810 0.000000 + -0.966988 -0.727795 -0.109011 0.000000 + -0.933673 -0.901434 -0.218781 0.000000 + 0.503533 0.316772 0.557133 0.000000 + -0.972246 -0.947865 -0.361680 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 549 + 1 + 0.000000 + + + + + + 0.878246 0.087909 -0.470059 0.000000 + -0.371678 0.743977 -0.555297 0.000000 + 0.300897 0.662398 0.686069 0.000000 + + + + -0.037943 -0.044133 0.237014 0.000000 + + + 550 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 551 + 0 + 42 + 0 0 0 0 + + + 0.633521 0.183424 -0.990686 0.000000 + 0.639099 0.161025 -0.998118 0.000000 + 0.709876 0.147113 -0.914807 0.000000 + 0.634765 0.180284 -0.991924 0.000000 + 0.239208 0.230928 -1.300519 0.000000 + 0.157520 0.269694 -1.219436 0.000000 + 0.204177 0.232332 -1.330611 0.000000 + -0.267655 0.241119 -1.379831 0.000000 + -0.276395 0.251348 -1.350028 0.000000 + 0.088514 0.207205 -1.405644 0.000000 + -0.582645 1.104368 -0.074375 0.000000 + -0.375749 0.449126 -1.063716 0.000000 + -0.772573 1.119840 0.020651 0.000000 + -0.512470 1.089614 -0.089268 0.000000 + -0.019303 0.991417 -0.156471 0.000000 + 0.092643 0.946425 -0.142037 0.000000 + 0.491983 0.787795 -0.073661 0.000000 + 0.596472 0.717618 -0.015832 0.000000 + 0.924670 0.127022 -0.539188 0.000000 + 0.735880 0.135758 -0.890825 0.000000 + 0.900864 0.513546 0.165843 0.000000 + 0.982735 0.125886 -0.431085 0.000000 + 0.961713 0.441358 0.247254 0.000000 + 1.139882 -0.009062 -0.086209 0.000000 + 1.167057 0.195625 0.538504 0.000000 + 1.225945 -0.086232 0.099467 0.000000 + 1.181930 0.147764 0.603654 0.000000 + 1.288483 -0.254911 0.306905 0.000000 + 1.284330 -0.242676 0.265905 0.000000 + 1.320162 -0.318661 0.531800 0.000000 + 1.196044 0.106641 0.659123 0.000000 + 1.275915 -0.138934 0.792536 0.000000 + -0.611655 -1.169266 -0.022215 0.000000 + -0.740167 -0.885372 0.401419 0.000000 + -0.863277 -0.601892 0.236392 0.000000 + -0.654454 -1.057410 -0.429086 0.000000 + -0.341001 -0.000809 1.469067 0.000000 + -0.376455 0.079820 1.423622 0.000000 + -0.962245 0.849325 0.525148 0.000000 + -0.316973 -0.555834 -1.324781 0.000000 + -0.154788 -0.439990 -1.346467 0.000000 + 0.743854 -0.150717 -0.779679 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 552 + 1 + 0.000000 + + + + + + 0.938923 -0.044744 -0.341207 0.000000 + -0.093401 0.921158 -0.377815 0.000000 + 0.331211 0.386608 0.860717 0.000000 + + + + 0.329255 -0.070790 0.019341 0.000000 + + + 553 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 554 + 0 + 64 + 0 0 0 0 + + + -1.475359 -0.026420 0.712867 0.000000 + -0.030086 -0.002383 0.414181 0.000000 + -1.497253 0.498422 0.583796 0.000000 + 0.008839 -0.540087 0.369511 0.000000 + 1.541383 -0.329451 0.504200 0.000000 + 1.426667 0.197836 0.542209 0.000000 + -0.077886 0.522028 0.290464 0.000000 + -1.572028 0.515303 0.660199 0.000000 + -1.463929 0.573963 0.557707 0.000000 + -1.509556 0.549709 0.606988 0.000000 + -1.628390 0.486753 0.706604 0.000000 + -1.817869 0.269459 0.877802 0.000000 + -1.689512 0.153550 0.827519 0.000000 + -1.781889 0.360978 0.829865 0.000000 + -1.558086 0.030919 0.785391 0.000000 + -1.437254 -0.068433 0.721316 0.000000 + -0.938416 -0.529506 0.589783 0.000000 + -0.636403 -0.797703 0.420930 0.000000 + 0.035082 -1.038534 0.160775 0.000000 + -0.382694 -1.029893 0.271815 0.000000 + 0.078829 -1.431264 -0.165367 0.000000 + 0.431538 -1.450973 -0.196732 0.000000 + 0.092937 -1.440118 -0.168585 0.000000 + 0.207784 -1.564829 -0.351599 0.000000 + 0.609048 -1.364138 -0.091187 0.000000 + 0.090235 -1.441486 -0.174153 0.000000 + 0.944337 -1.115059 0.112783 0.000000 + 1.310150 -0.844848 0.325384 0.000000 + 1.381373 -0.759696 0.363572 0.000000 + 1.564254 -0.548323 0.443970 0.000000 + 1.636649 -0.330819 0.563841 0.000000 + 1.617000 -0.510172 0.489512 0.000000 + 1.645107 -0.288418 0.583054 0.000000 + 1.495955 0.172664 0.591524 0.000000 + 1.646164 -0.210930 0.597553 0.000000 + 1.483951 0.207567 0.590953 0.000000 + 1.300602 0.681857 0.434375 0.000000 + 1.291514 0.707932 0.427322 0.000000 + 1.289406 0.703637 0.431890 0.000000 + -0.129889 0.981915 0.010468 0.000000 + 1.029434 1.134522 0.139311 0.000000 + 1.206297 0.947601 0.281209 0.000000 + 0.995831 1.159123 0.120479 0.000000 + 0.378781 1.258861 -0.145532 0.000000 + -0.181016 1.332335 -0.398467 0.000000 + -0.097848 1.336717 -0.349794 0.000000 + -0.204434 1.343972 -0.392467 0.000000 + -0.331937 1.351815 -0.370735 0.000000 + -0.286854 1.373107 -0.419944 0.000000 + -0.401628 1.326348 -0.310888 0.000000 + -0.760794 1.111920 0.012653 0.000000 + -1.029853 0.953143 0.234871 0.000000 + -0.992754 0.973466 0.221430 0.000000 + -1.164574 0.836393 0.335211 0.000000 + -1.191355 0.809784 0.365655 0.000000 + -1.213196 -0.211504 -0.094926 0.000000 + -0.264951 1.273449 -0.479218 0.000000 + 0.137994 0.640049 -0.744855 0.000000 + -0.192501 -1.161880 -0.704940 0.000000 + 1.177905 0.830009 -0.010880 0.000000 + 1.341988 0.659921 0.133373 0.000000 + 1.589268 -0.045317 0.434319 0.000000 + -1.793112 0.278874 0.852973 0.000000 + -1.764328 0.345578 0.867408 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 555 + 1 + 0.000000 + + + + + + 0.764303 -0.638838 0.087907 0.000000 + 0.564996 0.729107 0.386243 0.000000 + -0.310840 -0.245539 0.918199 0.000000 + + + + -0.205517 -0.199284 -0.195520 0.000000 + + + 556 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 557 + 0 + 45 + 0 0 0 0 + + + 1.181983 0.552373 0.035903 0.000000 + 0.381589 1.116737 -0.324949 0.000000 + 0.577716 1.408105 0.087273 0.000000 + 1.007469 0.998786 0.184119 0.000000 + 1.311750 0.219075 -0.066106 0.000000 + 1.359606 -0.067451 -0.125095 0.000000 + 0.105717 0.747543 -0.609394 0.000000 + 1.440876 -0.545747 -0.215798 0.000000 + 1.428915 -0.680463 -0.224457 0.000000 + -0.222858 0.336719 -0.738162 0.000000 + 1.397413 -1.053471 -0.247961 0.000000 + 1.334148 -1.134941 -0.255838 0.000000 + 1.294799 -1.168566 -0.255982 0.000000 + -0.571915 -0.075452 -0.698639 0.000000 + 0.932676 -1.502363 -0.232912 0.000000 + 0.888163 -1.529164 -0.218552 0.000000 + -0.907232 -0.448566 -0.494738 0.000000 + 0.497225 -1.786025 -0.060401 0.000000 + 0.445347 -1.805189 -0.027610 0.000000 + -1.195955 -0.746074 -0.146501 0.000000 + -0.647333 -1.242478 -0.008816 0.000000 + 0.184587 -1.917532 0.158764 0.000000 + -1.216707 -0.768258 -0.116931 0.000000 + -1.286736 -0.717052 -0.132576 0.000000 + -1.284578 -0.707248 -0.143039 0.000000 + -1.287348 -0.683768 -0.164569 0.000000 + -1.225819 -0.299062 -0.445896 0.000000 + -1.215811 -0.218988 -0.498961 0.000000 + -1.100098 0.163264 -0.643770 0.000000 + -1.063440 0.295436 -0.689579 0.000000 + -0.911996 0.646338 -0.711544 0.000000 + -0.845378 0.809142 -0.718423 0.000000 + -0.672821 1.109395 -0.632482 0.000000 + -0.582972 1.272304 -0.583300 0.000000 + -0.400442 1.507911 -0.401684 0.000000 + -0.301612 1.640349 -0.297655 0.000000 + -0.118448 1.797526 -0.028269 0.000000 + -0.028369 1.877903 0.110938 0.000000 + 0.644074 1.574994 0.449633 0.000000 + 0.125073 1.939917 0.420675 0.000000 + 0.648169 1.575263 0.444641 0.000000 + 0.917936 1.144578 0.243090 0.000000 + -0.496499 0.088300 0.931861 0.000000 + -0.645940 -0.281239 0.978794 0.000000 + 0.193168 -1.755548 0.326007 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 558 + 1 + 0.000000 + + + + + + 0.916068 -0.218120 0.336515 0.000000 + 0.337244 0.873073 -0.352150 0.000000 + -0.216992 0.436081 0.873354 0.000000 + + + + 0.346012 0.201864 0.146039 0.000000 + + + 559 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 560 + 0 + 55 + 0 0 0 0 + + + 0.913889 0.134685 -0.523483 0.000000 + -0.506515 0.743886 -0.373394 0.000000 + 1.181734 0.554721 -0.312447 0.000000 + 0.662240 -0.341322 -0.575696 0.000000 + -0.687918 0.237751 -0.433029 0.000000 + 0.451371 -0.826773 -0.464028 0.000000 + -0.874585 -0.258080 -0.323918 0.000000 + 0.301879 -1.274240 -0.199409 0.000000 + -1.048278 -0.695167 -0.056742 0.000000 + -0.348106 1.210859 -0.150794 0.000000 + 1.145620 0.595448 -0.320108 0.000000 + 1.100821 0.958784 -0.018817 0.000000 + 1.153149 0.557632 -0.355049 0.000000 + 1.157897 0.554041 -0.350851 0.000000 + 1.162062 0.073649 -0.634579 0.000000 + 1.167859 -0.032492 -0.692725 0.000000 + 1.108688 -0.413753 -0.780108 0.000000 + 1.083847 -0.604670 -0.821778 0.000000 + 0.985027 -0.891708 -0.769560 0.000000 + 0.914658 -1.109167 -0.729371 0.000000 + 0.771840 -1.339381 -0.550784 0.000000 + 0.675349 -1.502012 -0.424619 0.000000 + 0.449979 -1.691908 -0.043583 0.000000 + 0.228378 -1.639996 0.192326 0.000000 + 0.387090 -1.747034 0.067076 0.000000 + 0.174686 -1.795873 0.490910 0.000000 + -0.465252 -1.459176 0.424322 0.000000 + 0.145996 -1.826162 0.541893 0.000000 + -1.080828 -1.107818 0.313169 0.000000 + -1.079924 -1.084336 0.317237 0.000000 + -1.080995 -1.068668 0.301512 0.000000 + -1.099026 -0.933520 0.181838 0.000000 + -1.140921 -0.693350 -0.076030 0.000000 + -1.149473 -0.662535 -0.104978 0.000000 + -1.182219 -0.264329 -0.353315 0.000000 + -1.195629 -0.151796 -0.419595 0.000000 + -1.205623 0.206747 -0.517801 0.000000 + -1.215829 0.412480 -0.571094 0.000000 + -1.209423 0.701895 -0.559394 0.000000 + -1.208196 0.974863 -0.545746 0.000000 + -1.107728 1.160235 -0.453232 0.000000 + -1.196279 1.108840 -0.505275 0.000000 + -0.821127 1.338392 -0.295535 0.000000 + -0.189169 1.563385 0.164446 0.000000 + -0.171591 1.571361 0.173793 0.000000 + 1.092618 1.031568 0.043146 0.000000 + -0.169841 1.571389 0.166810 0.000000 + 0.999487 1.270672 0.373991 0.000000 + 0.820268 1.440327 0.522429 0.000000 + 0.955702 1.386121 0.539092 0.000000 + 0.109304 1.627674 0.400454 0.000000 + 0.959417 1.402776 0.541321 0.000000 + -1.121305 0.665171 -0.147029 0.000000 + -1.076138 -0.091795 0.254991 0.000000 + -0.657830 0.721025 0.282129 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 561 + 1 + 0.000000 + + + + + + 0.767560 -0.579668 0.273564 0.000000 + 0.639597 0.720643 -0.267562 0.000000 + -0.042045 0.380340 0.923890 0.000000 + + + + 0.185066 0.047493 0.038386 0.000000 + + + 562 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 563 + 0 + 24 + 0 0 0 0 + + + 0.284491 0.907433 0.162430 0.000000 + 0.404171 0.758380 0.252137 0.000000 + 0.854629 0.002870 -0.069283 0.000000 + 0.858963 -0.013644 -0.072574 0.000000 + 0.196581 0.931783 -0.114824 0.000000 + 0.268571 0.279541 0.448452 0.000000 + 0.291838 -0.249552 0.494597 0.000000 + -0.499476 0.784866 0.089121 0.000000 + 0.042008 0.930302 -0.256645 0.000000 + -0.468686 0.825800 -0.157590 0.000000 + -0.514453 0.781575 0.085161 0.000000 + 0.835088 -0.186876 -0.198010 0.000000 + 0.637815 -0.348697 -0.459502 0.000000 + 0.655548 -0.368789 -0.442311 0.000000 + -1.039429 0.402392 -0.089813 0.000000 + -0.254721 -0.929726 -0.136291 0.000000 + -0.084560 -0.949206 -0.133243 0.000000 + 0.101412 -0.797558 0.253739 0.000000 + 0.045989 -0.725413 0.414541 0.000000 + -0.516225 -0.757414 0.173555 0.000000 + 0.619084 -0.371760 -0.450748 0.000000 + 0.587299 -0.398389 -0.445627 0.000000 + -0.379718 -0.695011 -0.248250 0.000000 + -1.075852 0.188489 -0.094027 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 564 + 1 + 0.000000 + + + + + + 0.754245 0.637955 0.155329 0.000000 + -0.602854 0.766590 -0.221147 0.000000 + -0.260156 0.073159 0.962791 0.000000 + + + + 0.079015 0.068228 0.175201 0.000000 + + + 565 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 566 + 0 + 46 + 0 0 0 0 + + + 0.531421 0.007053 0.996946 0.000000 + -0.674661 -0.701075 0.512324 0.000000 + -0.311453 -1.100321 0.557064 0.000000 + 0.562924 -0.269839 0.963250 0.000000 + 0.492873 0.406051 1.042528 0.000000 + 0.479104 0.584497 1.017352 0.000000 + -0.956403 -0.280202 0.320475 0.000000 + 0.450706 1.050606 0.949599 0.000000 + 0.448826 1.065736 0.944070 0.000000 + 0.439562 1.090179 0.908293 0.000000 + -1.129060 0.121032 0.000335 0.000000 + 0.225088 1.368225 0.605963 0.000000 + -0.045528 1.679910 -0.393805 0.000000 + 0.039605 1.765956 -0.387829 0.000000 + 0.045562 1.777409 -0.407731 0.000000 + -0.479949 1.212106 -0.370161 0.000000 + 0.061817 1.649412 0.027565 0.000000 + -1.127630 0.508076 -0.343944 0.000000 + 0.072034 1.618731 0.139976 0.000000 + -1.144489 0.485418 -0.343642 0.000000 + 0.193380 1.413929 0.519624 0.000000 + -1.172724 0.447128 -0.343919 0.000000 + -1.418739 -0.081669 -0.358808 0.000000 + -1.427247 -0.071608 -0.362429 0.000000 + -1.412618 -0.165176 -0.271665 0.000000 + -1.283637 -0.487829 -0.024399 0.000000 + -1.247448 -0.580579 0.042272 0.000000 + -1.003706 -0.880458 0.218493 0.000000 + -1.072985 -0.836997 0.167616 0.000000 + -0.917525 -0.934591 0.286731 0.000000 + -0.425413 -1.142898 0.489149 0.000000 + -0.521181 -1.119559 0.445427 0.000000 + -0.385853 -1.152491 0.507846 0.000000 + -0.167989 -1.190590 0.546561 0.000000 + 0.681391 -1.075136 0.604212 0.000000 + 0.355303 -1.255953 0.539293 0.000000 + 0.742111 -1.305396 0.438334 0.000000 + 0.654007 -0.909902 0.718498 0.000000 + 0.279442 -1.252770 0.552398 0.000000 + 0.600510 -0.558643 0.855076 0.000000 + 0.767240 0.304527 -0.771744 0.000000 + 0.906041 -1.065992 -0.865495 0.000000 + 0.863969 -1.037394 -0.980606 0.000000 + 0.494267 -0.993090 -0.890498 0.000000 + -0.233610 -0.812883 -0.708247 0.000000 + 0.658246 1.219690 -0.621077 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 567 + 1 + 0.000000 + + + + + + 0.747144 0.622311 -0.233465 0.000000 + -0.470538 0.743308 0.475486 0.000000 + 0.469436 -0.245402 0.848179 0.000000 + + + + -0.175003 0.061738 0.331545 0.000000 + + + 568 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 569 + 0 + 42 + 0 0 0 0 + + + -0.106896 0.178809 -0.868863 0.000000 + 0.386692 0.177782 -0.470750 0.000000 + 0.133414 0.087588 -0.841142 0.000000 + -0.395516 0.245881 -0.848626 0.000000 + 0.079224 0.377130 -0.072806 0.000000 + -0.835435 0.341101 -0.821188 0.000000 + -0.933051 0.343117 -0.793492 0.000000 + -0.226492 0.413946 0.372043 0.000000 + -1.463297 0.347225 -0.649309 0.000000 + -1.456282 0.350006 -0.652366 0.000000 + -0.500561 0.284558 0.820319 0.000000 + -1.582961 0.296795 -0.564010 0.000000 + -1.472136 0.342809 -0.644101 0.000000 + -1.585528 0.314371 -0.585795 0.000000 + -1.663349 0.224306 -0.191853 0.000000 + -0.550000 0.274186 0.853375 0.000000 + -0.559048 0.258219 0.853621 0.000000 + -1.663559 0.238788 -0.205812 0.000000 + -0.464724 0.318378 0.825888 0.000000 + -0.442789 0.324859 0.825422 0.000000 + 0.109575 0.530009 0.661502 0.000000 + 0.311900 0.599272 0.608346 0.000000 + 0.670110 0.647765 0.503057 0.000000 + 1.082986 0.699543 0.389115 0.000000 + 1.153816 0.690621 0.345094 0.000000 + 1.135513 0.703681 0.367638 0.000000 + 1.419652 0.532018 0.030331 0.000000 + 1.524713 -0.040828 -0.451811 0.000000 + 1.588289 0.032330 -0.415045 0.000000 + 1.595638 -0.030244 -0.453261 0.000000 + 0.786735 -0.079354 -0.704701 0.000000 + 1.590063 0.158704 -0.335582 0.000000 + 0.707735 -0.086440 -0.726252 0.000000 + 1.440071 0.483809 -0.020061 0.000000 + 0.644299 -0.097780 -0.743861 0.000000 + 0.550001 -0.080459 -0.797359 0.000000 + -0.029135 -0.688865 0.501187 0.000000 + -0.222268 -0.855866 0.191240 0.000000 + 0.077261 -0.842336 0.102765 0.000000 + 0.376073 -0.779665 0.111294 0.000000 + -0.075790 -0.387320 0.716212 0.000000 + -1.253373 -0.167542 -0.172561 0.000000 + + + + 0 + 31 + 0 0 0 0 + + 570 + 1 + 0.000000 + + + + + + 0.930797 0.238516 -0.276998 0.000000 + -0.031286 0.806984 0.589744 0.000000 + 0.364196 -0.540266 0.758600 0.000000 + + + + 0.000300 0.113718 0.053941 0.000000 + + + 571 + 4 + 0.040000 + + + + + 0 + 4 + 0 0 0 0 + + + 1.000000 1.000000 1.000000 0.000000 + + + 0.000000 0.000000 0.000000 0.000000 + + 0.040000 + 0 + + 572 + 0 + 45 + 0 0 0 0 + + + -0.239485 0.631381 -0.880147 0.000000 + -0.469398 0.275618 -0.418576 0.000000 + -0.216857 0.756212 -0.798697 0.000000 + -0.220138 0.386933 -0.978611 0.000000 + -0.228720 0.190010 -0.986072 0.000000 + -0.370678 -0.166610 -0.715236 0.000000 + -0.238359 0.060458 -0.990861 0.000000 + -0.142911 -0.576634 -0.938825 0.000000 + -0.117681 -0.586604 -0.945207 0.000000 + -0.141236 -0.582379 -0.938705 0.000000 + -0.123693 -0.620712 -0.930405 0.000000 + 0.021149 -0.884440 -0.862653 0.000000 + -0.111716 -1.228824 -0.279913 0.000000 + -0.138804 -1.307093 -0.166289 0.000000 + -0.235212 -1.214336 -0.105601 0.000000 + -0.376023 -1.011232 0.047684 0.000000 + -0.497863 -0.834056 0.187362 0.000000 + -0.553773 -0.617830 0.365070 0.000000 + -0.602779 -0.420846 0.533205 0.000000 + -0.572144 -0.213391 0.716414 0.000000 + -0.404148 0.696723 -0.084312 0.000000 + -0.539734 -0.015287 0.897962 0.000000 + -0.430025 0.163585 1.068178 0.000000 + -0.181341 1.055415 0.254782 0.000000 + -0.315075 0.342853 1.245844 0.000000 + -0.349645 0.322184 1.232351 0.000000 + -0.215438 1.046666 0.241660 0.000000 + -0.205031 1.067584 0.203107 0.000000 + -0.176364 1.097938 0.151595 0.000000 + -0.085042 1.194936 -0.481343 0.000000 + 0.013113 1.358308 -0.348913 0.000000 + 0.022136 1.370047 -0.310225 0.000000 + -0.149062 1.088434 -0.587032 0.000000 + 0.571393 -0.513192 0.629367 0.000000 + 0.674420 -0.231618 0.203329 0.000000 + 0.733457 0.190523 0.169219 0.000000 + 0.557589 -0.239996 0.872670 0.000000 + 0.634786 -0.205571 -0.088319 0.000000 + 0.723132 0.445694 -0.100759 0.000000 + 0.195901 -0.638044 -0.771981 0.000000 + 0.311710 0.010452 -0.712688 0.000000 + 0.384439 0.115093 -0.603964 0.000000 + 0.720511 0.455386 -0.105697 0.000000 + 0.547331 0.705756 -0.204312 0.000000 + -0.034983 1.378438 -0.337384 0.000000 + + diff --git a/Demos/BulletXmlImportDemo/main.cpp b/Demos/BulletXmlImportDemo/main.cpp new file mode 100644 index 0000000..b20ff81 --- /dev/null +++ b/Demos/BulletXmlImportDemo/main.cpp @@ -0,0 +1,107 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletXmlImportDemo.h" +#include "GlutStuff.h" + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + + +#ifdef USE_AMD_OPENCL + + + +#include "btOpenCLUtils.h" + +#include + +cl_context g_cxMainContext; +cl_device_id g_cdDevice; +cl_command_queue g_cqCommandQue; + + +// Returns true if OpenCL is initialized properly, false otherwise. +bool initCL( void* glCtx, void* glDC ) +{ + const char* vendorSDK = btOpenCLUtils::getSdkVendorName(); + printf("This program was compiled using the %s OpenCL SDK\n",vendorSDK); + + int ciErrNum = 0; + +#ifdef BT_USE_CLEW + ciErrNum = clewInit( "OpenCL.dll" ); + if ( ciErrNum != CLEW_SUCCESS ) { + return false; + } +#endif + +#if defined(CL_PLATFORM_MINI_CL) + cl_device_type deviceType = CL_DEVICE_TYPE_CPU; +#elif defined(CL_PLATFORM_AMD) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#elif defined(CL_PLATFORM_NVIDIA) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#else + cl_device_type deviceType = CL_DEVICE_TYPE_CPU; +#endif + + g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext); + if (!numDev) + return false; + + g_cdDevice = btOpenCLUtils::getDevice(g_cxMainContext,0); + + btOpenCLDeviceInfo clInfo; + btOpenCLUtils::getDeviceInfo(g_cdDevice,clInfo); + btOpenCLUtils::printDeviceInfo(g_cdDevice); + + // create a command-queue + g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_cdDevice, 0, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + return true; +} + +#endif //#ifdef USE_AMD_OPENCL + + +int main(int argc,char** argv) +{ + +#ifdef USE_AMD_OPENCL + + bool initialized = initCL(0,0); + btAssert(initialized); +#endif //USE_AMD_OPENCL + + + BulletXmlImportDemo serializeDemo; + serializeDemo.initPhysics(); + + +#ifdef CHECK_MEMORY_LEAKS + serializeDemo.exitPhysics(); +#else + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.org",&serializeDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/CMakeLists.txt b/Demos/CMakeLists.txt new file mode 100644 index 0000000..7bc210c --- /dev/null +++ b/Demos/CMakeLists.txt @@ -0,0 +1,67 @@ + +IF (USE_DX11 AND BUILD_MULTITHREADING) + SUBDIRS(DX11ClothDemo) +ENDIF() + +SUBDIRS( HelloWorld ) + + +IF (USE_GLUT) + IF (GLUT_FOUND) + IF(BUILD_CPU_DEMOS) + SET(SharedDemoSubdirs + OpenGL AllBulletDemos ConvexDecompositionDemo + CcdPhysicsDemo BulletXmlImportDemo ConstraintDemo SliderConstraintDemo GenericJointDemo Raytracer + RagdollDemo ForkLiftDemo BasicDemo RollingFrictionDemo RaytestDemo VoronoiFractureDemo + GyroscopicDemo FractureDemo Box2dDemo BspDemo MovingConcaveDemo VehicleDemo + UserCollisionAlgorithm CharacterDemo SoftDemo + CollisionInterfaceDemo ConcaveConvexcastDemo SimplexDemo DynamicControlDemo + ConvexHullDistance + DoublePrecisionDemo ConcaveDemo CollisionDemo + ContinuousConvexCollision ConcaveRaycastDemo GjkConvexCastDemo + MultiMaterialDemo SerializeDemo InternalEdgeDemo + ) + ELSE() + SET(SharedDemoSubdirs OpenGL ) + ENDIF(BUILD_CPU_DEMOS) + + IF(BUILD_MULTITHREADING) + SUBDIRS( MultiThreadedDemo ParticlesOpenCL OpenCLClothDemo ) + ENDIF(BUILD_MULTITHREADING) + + SUBDIRS( + ${SharedDemoSubdirs} + Benchmarks + ) + + IF(BUILD_MULTITHREADING) + SUBDIRS( ThreadingDemo VectorAdd_OpenCL ) + ENDIF() + + ENDIF(GLUT_FOUND) +ELSE (USE_GLUT) + IF (WIN32) + SUBDIRS( + OpenGL + BasicDemo + RaytestDemo + FractureDemo + Benchmarks + Box2dDemo + CollisionInterfaceDemo + ConcaveDemo + ConstraintDemo + RollingFrictionDemo + ConvexDecompositionDemo + InternalEdgeDemo + GimpactTestDemo + GyroscopicDemo + GenericJointDemo + SerializeDemo + SoftDemo + VectorAdd_OpenCL + VoronoiFractureDemo + ) + ENDIF(WIN32) +ENDIF (USE_GLUT) + diff --git a/Demos/CcdPhysicsDemo/CMakeLists.txt b/Demos/CcdPhysicsDemo/CMakeLists.txt new file mode 100644 index 0000000..ea8d451 --- /dev/null +++ b/Demos/CcdPhysicsDemo/CMakeLists.txt @@ -0,0 +1,59 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +IF (WIN32) + ADD_EXECUTABLE(AppCcdPhysicsDemo + main.cpp + CcdPhysicsDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppCcdPhysicsDemo + main.cpp + CcdPhysicsDemo.cpp + ) +ENDIF() + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCcdPhysicsDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCcdPhysicsDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}/Debug + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppCcdPhysicsDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppCcdPhysicsDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppCcdPhysicsDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp new file mode 100644 index 0000000..c0acf65 --- /dev/null +++ b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp @@ -0,0 +1,424 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#define CUBE_HALF_EXTENTS 1 + +#define EXTRA_HEIGHT 1.f + +#include "CcdPhysicsDemo.h" +#include "GlutStuff.h" +#include "GLDebugFont.h" + +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" + +#include //printf debugging +#include "GLDebugDrawer.h" + +#if 0 +extern btAlignedObjectArray debugContacts; +extern btAlignedObjectArray debugNormals; +#endif + +static GLDebugDrawer sDebugDrawer; + + +CcdPhysicsDemo::CcdPhysicsDemo() +:m_ccdMode(USE_CCD) +{ + setDebugMode(btIDebugDraw::DBG_DrawText+btIDebugDraw::DBG_NoHelpText); + setCameraDistance(btScalar(40.)); +} + + +void CcdPhysicsDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + //float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(1./60.,0);//ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + displayText(); +#if 0 + for (int i=0;igetDebugDrawer()->drawContactPoint(debugContacts[i],debugNormals[i],0,0,btVector3(1,0,0)); + } +#endif + + glFlush(); + + swapBuffers(); + +} + + +void CcdPhysicsDemo::displayText() +{ + int lineWidth=440; + int xStart = m_glutScreenWidth - lineWidth; + int yStart = 20; + + if((getDebugMode() & btIDebugDraw::DBG_DrawText)!=0) + { + setOrthographicProjection(); + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + char buf[124]; + + glRasterPos3f(xStart, yStart, 0); + switch (m_ccdMode) + { + case USE_CCD: + { + sprintf(buf,"Predictive contacts and motion clamping"); + break; + } + case USE_NO_CCD: + { + sprintf(buf,"CCD handling disabled"); + break; + } + default: + { + sprintf(buf,"unknown CCD setting"); + }; + }; + + GLDebugDrawString(xStart,20,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"Press 'p' to change CCD mode"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"Press '.' or right mouse to shoot bullets"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"space to restart, h(elp), t(ext), w(ire)"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + + resetPerspectiveProjection(); + glEnable(GL_LIGHTING); + } + +} + + + +void CcdPhysicsDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + displayText(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + { + m_dynamicsWorld->debugDrawWorld(); + } +#if 0 + for (int i=0;igetDebugDrawer()->drawContactPoint(debugContacts[i],debugNormals[i],0,0,btVector3(1,0,0)); + } +#endif + + glFlush(); + swapBuffers(); +} + + + + + +void CcdPhysicsDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + m_ShootBoxInitialSpeed = 4000.f; + + m_defaultContactProcessingThreshold = 0.f; + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btDefaultCollisionConfiguration(); +// m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + //m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,m_collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,CONVEX_SHAPE_PROXYTYPE)); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld->getSolverInfo().m_solverMode |=SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_RANDMIZE_ORDER; + + + + m_dynamicsWorld ->setDebugDrawer(&sDebugDrawer); + + //m_dynamicsWorld->getSolverInfo().m_splitImpulse=false; + + + + if (m_ccdMode==USE_CCD) + { + m_dynamicsWorld->getDispatchInfo().m_useContinuous=true; + } else + { + m_dynamicsWorld->getDispatchInfo().m_useContinuous=false; + } + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + ///create a few basic rigid bodies + btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.))); +// box->initializePolyhedralFeatures(); + btCollisionShape* groundShape = box; + +// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + + m_collisionShapes.push_back(groundShape); + //m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); + m_collisionShapes.push_back(new btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); + + btTransform groundTransform; + groundTransform.setIdentity(); + //groundTransform.setOrigin(btVector3(5,5,5)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(0.5); + //body->setRollingFriction(0.3); + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); + + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(colShape); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); + + int gNumObjects = 120;//120; + int i; + for (i=0;i3) + { + col=11; + row2 |=1; + } + + btVector3 pos(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, + row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); + + trans.setOrigin(pos); + + float mass = 1.f; + + btRigidBody* body = localCreateRigidBody(mass,trans,shape); + body->setAnisotropicFriction(shape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + body->setFriction(0.5); + + //body->setRollingFriction(.3); + ///when using m_ccdMode + if (m_ccdMode==USE_CCD) + { + body->setCcdMotionThreshold(CUBE_HALF_EXTENTS); + body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS); + } + } + } + +} + +void CcdPhysicsDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} + +void CcdPhysicsDemo::keyboardCallback(unsigned char key, int x, int y) +{ + if (key=='p') + { + switch (m_ccdMode) + { + case USE_CCD: + { + m_ccdMode = USE_NO_CCD; + break; + } + case USE_NO_CCD: + default: + { + m_ccdMode = USE_CCD; + } + }; + clientResetScene(); + } else + { + DemoApplication::keyboardCallback(key,x,y); + } +} + + +void CcdPhysicsDemo::shootBox(const btVector3& destination) +{ + + if (m_dynamicsWorld) + { + float mass = 1.f; + btTransform startTransform; + startTransform.setIdentity(); + btVector3 camPos = getCameraPosition(); + startTransform.setOrigin(camPos); + + setShootBoxShape (); + + + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape); + body->setLinearFactor(btVector3(1,1,1)); + //body->setRestitution(1); + + btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed; + + body->getWorldTransform().setOrigin(camPos); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + body->setContactProcessingThreshold(1e30); + + ///when using m_ccdMode, disable regular CCD + if (m_ccdMode==USE_CCD) + { + body->setCcdMotionThreshold(CUBE_HALF_EXTENTS); + body->setCcdSweptSphereRadius(0.4f); + } + + } +} + + + + +void CcdPhysicsDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + enum + { + USE_CCD=1, + USE_NO_CCD + }; + int m_ccdMode; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + public: + + CcdPhysicsDemo(); + + virtual ~CcdPhysicsDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + void displayText(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + virtual void displayCallback(); + virtual void shootBox(const btVector3& destination); + virtual void clientResetScene(); + + + static DemoApplication* Create() + { + CcdPhysicsDemo* demo = new CcdPhysicsDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //BT_CCD_PHYSICS_DEMO_H + diff --git a/Demos/CcdPhysicsDemo/Makefile.am b/Demos/CcdPhysicsDemo/Makefile.am new file mode 100644 index 0000000..b7c6968 --- /dev/null +++ b/Demos/CcdPhysicsDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=CcdPhysicsDemo + +CcdPhysicsDemo_SOURCES=CcdPhysicsDemo.cpp CcdPhysicsDemo.h main.cpp +CcdPhysicsDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +CcdPhysicsDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/CcdPhysicsDemo/Makefile.in b/Demos/CcdPhysicsDemo/Makefile.in new file mode 100644 index 0000000..a807d28 --- /dev/null +++ b/Demos/CcdPhysicsDemo/Makefile.in @@ -0,0 +1,519 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = CcdPhysicsDemo$(EXEEXT) +subdir = Demos/CcdPhysicsDemo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_CcdPhysicsDemo_OBJECTS = CcdPhysicsDemo-CcdPhysicsDemo.$(OBJEXT) \ + CcdPhysicsDemo-main.$(OBJEXT) +CcdPhysicsDemo_OBJECTS = $(am_CcdPhysicsDemo_OBJECTS) +CcdPhysicsDemo_DEPENDENCIES = +CcdPhysicsDemo_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(CcdPhysicsDemo_SOURCES) +DIST_SOURCES = $(CcdPhysicsDemo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +CcdPhysicsDemo_SOURCES = CcdPhysicsDemo.cpp CcdPhysicsDemo.h main.cpp +CcdPhysicsDemo_CXXFLAGS = -I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +CcdPhysicsDemo_LDADD = -L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/CcdPhysicsDemo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/CcdPhysicsDemo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +CcdPhysicsDemo$(EXEEXT): $(CcdPhysicsDemo_OBJECTS) $(CcdPhysicsDemo_DEPENDENCIES) + @rm -f CcdPhysicsDemo$(EXEEXT) + $(CcdPhysicsDemo_LINK) $(CcdPhysicsDemo_OBJECTS) $(CcdPhysicsDemo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CcdPhysicsDemo-CcdPhysicsDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CcdPhysicsDemo-main.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +CcdPhysicsDemo-CcdPhysicsDemo.o: CcdPhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -MT CcdPhysicsDemo-CcdPhysicsDemo.o -MD -MP -MF $(DEPDIR)/CcdPhysicsDemo-CcdPhysicsDemo.Tpo -c -o CcdPhysicsDemo-CcdPhysicsDemo.o `test -f 'CcdPhysicsDemo.cpp' || echo '$(srcdir)/'`CcdPhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CcdPhysicsDemo-CcdPhysicsDemo.Tpo $(DEPDIR)/CcdPhysicsDemo-CcdPhysicsDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='CcdPhysicsDemo.cpp' object='CcdPhysicsDemo-CcdPhysicsDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -c -o CcdPhysicsDemo-CcdPhysicsDemo.o `test -f 'CcdPhysicsDemo.cpp' || echo '$(srcdir)/'`CcdPhysicsDemo.cpp + +CcdPhysicsDemo-CcdPhysicsDemo.obj: CcdPhysicsDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -MT CcdPhysicsDemo-CcdPhysicsDemo.obj -MD -MP -MF $(DEPDIR)/CcdPhysicsDemo-CcdPhysicsDemo.Tpo -c -o CcdPhysicsDemo-CcdPhysicsDemo.obj `if test -f 'CcdPhysicsDemo.cpp'; then $(CYGPATH_W) 'CcdPhysicsDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/CcdPhysicsDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CcdPhysicsDemo-CcdPhysicsDemo.Tpo $(DEPDIR)/CcdPhysicsDemo-CcdPhysicsDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='CcdPhysicsDemo.cpp' object='CcdPhysicsDemo-CcdPhysicsDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -c -o CcdPhysicsDemo-CcdPhysicsDemo.obj `if test -f 'CcdPhysicsDemo.cpp'; then $(CYGPATH_W) 'CcdPhysicsDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/CcdPhysicsDemo.cpp'; fi` + +CcdPhysicsDemo-main.o: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -MT CcdPhysicsDemo-main.o -MD -MP -MF $(DEPDIR)/CcdPhysicsDemo-main.Tpo -c -o CcdPhysicsDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CcdPhysicsDemo-main.Tpo $(DEPDIR)/CcdPhysicsDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='CcdPhysicsDemo-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -c -o CcdPhysicsDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp + +CcdPhysicsDemo-main.obj: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -MT CcdPhysicsDemo-main.obj -MD -MP -MF $(DEPDIR)/CcdPhysicsDemo-main.Tpo -c -o CcdPhysicsDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CcdPhysicsDemo-main.Tpo $(DEPDIR)/CcdPhysicsDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='CcdPhysicsDemo-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CcdPhysicsDemo_CXXFLAGS) $(CXXFLAGS) -c -o CcdPhysicsDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/CcdPhysicsDemo/main.cpp b/Demos/CcdPhysicsDemo/main.cpp new file mode 100644 index 0000000..3d0955a --- /dev/null +++ b/Demos/CcdPhysicsDemo/main.cpp @@ -0,0 +1,49 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "CcdPhysicsDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" +#ifdef __DEBUG_FPU_ISSUES +#define _GNU_SOURCE +#include +#endif + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + CcdPhysicsDemo* ccdDemo = new CcdPhysicsDemo(); + +#ifdef __DEBUG_FPU_ISSUES +// feenableexcept (FE_DIVBYZERO); +// feenableexcept (FE_INEXACT); +// feenableexcept (FE_INVALID); +// feenableexcept (FE_OVERFLOW|FE_DIVBYZERO|FE_UNDERFLOW); +// feenableexcept (FE_UNDERFLOW); +#endif + + ccdDemo->initPhysics(); + ccdDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + + glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",ccdDemo); + + delete ccdDemo; + return 0; + +} diff --git a/Demos/CellSpuDemo/BasicDemo2.cpp b/Demos/CellSpuDemo/BasicDemo2.cpp new file mode 100644 index 0000000..2af2b80 --- /dev/null +++ b/Demos/CellSpuDemo/BasicDemo2.cpp @@ -0,0 +1,277 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +//#define USE_GROUND_BOX 1 +#define PRINT_CONTACT_STATISTICS 1 +#define USE_PARALLEL_DISPATCHER 1 + + +//#define USE_SIMPLE_DYNAMICS_WORLD 1 + +int gNumObjects = 5; +#define HALF_EXTENTS btScalar(1.) +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h" +#include "LinearMath/btIDebugDraw.h" +#include //printf debugging +btScalar deltaTime = btScalar(1./60.); +btScalar gCollisionMargin = btScalar(0.05); +#include "BasicDemo2.h" + +#ifdef USE_PARALLEL_DISPATCHER +#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#include "BulletMultiThreaded/Win32ThreadSupport.h" +#include "BulletMultiThreaded/SpuLibspe2Support.h" +#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#endif//USE_PARALLEL_DISPATCHER + + +#include + +//////////////////////////////////// + + + + +int main(int argc,char** argv) +{ + + BasicDemo ccdDemo; + ccdDemo.initPhysics(); + + int i; + for (i=0;i<5;i++) + ccdDemo.clientMoveAndDisplay(); + ccdDemo.exitPhysics(); + + return 0; +} + + + +extern int gNumManifold; + +void BasicDemo::clientMoveAndDisplay() +{ + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = m_clock.getTimeMicroseconds(); + m_clock.reset(); + float minFPS = 1000000.f/60.f; + if (ms > minFPS) + ms = minFPS; + + if (m_dynamicsWorld) + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + + //some additional debugging info +#ifdef PRINT_CONTACT_STATISTICS + printf("num contact manifolds: %i\n",gNumManifold); + int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds(); + for (int i=0;igetDispatcher()->getManifoldByIndexInternal(i); + btCollisionObject* obA = static_cast(contactManifold->getBody0()); + btCollisionObject* obB = static_cast(contactManifold->getBody1()); + + int numContacts = contactManifold->getNumContacts(); + for (int j=0;jgetContactPoint(j); + btVector3 ptA = pt.getPositionWorldOnA(); + btVector3 ptB = pt.getPositionWorldOnB(); + printf("contact manifold[%d],pointA[%d]=(%f,%f,%f)\n",i,j,ptA[0],ptA[1],ptA[2]); + } + } +#endif //PRINT_CONTACT_STATISTICS + + +} + + + + + +void BasicDemo::initPhysics() +{ + + btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + +#ifdef USE_PARALLEL_DISPATCHER + + int maxNumOutstandingTasks = 1;//number of maximum outstanding tasks +#ifdef USE_WIN32_THREADING + + Win32ThreadSupport* threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( + "collision", + processCollisionTask, + createCollisionLocalStoreMemory, + maxNumOutstandingTasks)); +#else + + spe_program_handle_t * program_handle; +#ifndef USE_CESOF + char* spuFileName = "../../../src/BulletMultiThreaded/out/spuCollision.elf"; + + program_handle = spe_image_open (spuFileName); + if (program_handle == NULL) + { + printf( "SPU OPEN IMAGE ERROR:%s\n",spuFileName); + exit(0); + } + else + { + printf( "IMAGE OPENED:%s\n",spuFileName); + } +#else + extern spe_program_handle_t spu_program; + program_handle = &spu_program; +#endif + SpuLibspe2Support* threadSupport = new SpuLibspe2Support( program_handle, maxNumOutstandingTasks); + +#endif // WIN32 + + + m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,collisionConfiguration); +#else + m_dispatcher = new btCollisionDispatcher(collisionConfiguration); +#endif //USE_PARALLEL_DISPATCHER + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + +#define USE_SWEEP_AND_PRUNE 1 +#ifdef USE_SWEEP_AND_PRUNE +#define maxProxies 8192 + btVector3 worldAabbMin(-10000,-10000,-10000); + btVector3 worldAabbMax(10000,10000,10000); + m_overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); + //m_overlappingPairCache = new btMultiSapBroadphase(); + + +#else + m_overlappingPairCache = new btSimpleBroadphase; +#endif //USE_SWEEP_AND_PRUNE + + + + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver,m_collisionConfiguration); + m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + + ///create a few basic rigid bodies + + + //static ground +#ifdef USE_GROUND_BOX + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); +#else + btCollisionShape* groundShape = new btSphereShape(btScalar(50.)); +#endif//USE_GROUND_BOX + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + localCreateRigidBody(btScalar(0.),groundTransform,groundShape); + + //create a few dynamic sphere rigidbodies (re-using the same sphere shape) + //btCollisionShape* sphereShape = new btBoxShape(btVector3(1,1,1)); + btCollisionShape* sphereShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(sphereShape); + + int i; + for (i=0;isetMargin(gCollisionMargin); + btTransform trans; + trans.setIdentity(); + //stack them + int colsize = 2; + int row = (int)((i*HALF_EXTENTS*2)/(colsize*2*HALF_EXTENTS)); + int row2 = row; + int col = (i)%(colsize)-colsize/2; + btVector3 pos(col*2*HALF_EXTENTS + (row2%2)*HALF_EXTENTS, + row*2*HALF_EXTENTS+HALF_EXTENTS,0); + + trans.setOrigin(pos); + //btRigidBody* body = localCreateRigidBody(btScalar(1.),trans,sphereShape); + localCreateRigidBody(btScalar(1.),trans,sphereShape); + } + + //clientResetScene(); +} + +btRigidBody* BasicDemo::localCreateRigidBody(btScalar mass,const btTransform& startTrans,btCollisionShape* colShape) +{ +btVector3 inertia(0,0,0); +if (mass) + colShape->calculateLocalInertia(mass,inertia); + btRigidBody::btRigidBodyConstructionInfo rbci(mass,0,colShape,inertia); + rbci.m_startWorldTransform = startTrans; + +btRigidBody* body = new btRigidBody(rbci); + m_dynamicsWorld->addRigidBody(body); +return body; + +} +void BasicDemo::exitPhysics() +{ + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_overlappingPairCache; + + btCollisionDispatcher* m_dispatcher; + btDefaultCollisionConfiguration* m_collisionConfiguration; + btConstraintSolver* m_solver; + btDiscreteDynamicsWorld* m_dynamicsWorld; + + btCollisionAlgorithmCreateFunc* m_sphereSphereCF; + btCollisionAlgorithmCreateFunc* m_sphereBoxCF; + btCollisionAlgorithmCreateFunc* m_boxSphereCF; + + btRigidBody* localCreateRigidBody(btScalar mass,const btTransform& startTrans,btCollisionShape* colShape); + + + public: + + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + + +}; + +#endif //BASIC_DEMO_H + diff --git a/Demos/CharacterDemo/CMakeLists.txt b/Demos/CharacterDemo/CMakeLists.txt new file mode 100644 index 0000000..d0cda1b --- /dev/null +++ b/Demos/CharacterDemo/CMakeLists.txt @@ -0,0 +1,75 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) +SET(CharacterDemo_SRCS + + DynamicCharacterController.cpp + DynamicCharacterController.h + CharacterDemo.cpp + CharacterDemo.h + ../BspDemo/BspConverter.cpp + ../BspDemo/BspConverter.h + ../BspDemo/BspLoader.cpp + ../BspDemo/BspLoader.h + main.cpp +) + +IF (WIN32) + ADD_EXECUTABLE(AppCharacterDemo + ${CharacterDemo_SRCS} + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppCharacterDemo + ${CharacterDemo_SRCS} + ) +ENDIF() + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCharacterDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCharacterDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( + TARGET AppCharacterDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/BspDemo.bsp ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppCharacterDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppCharacterDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppCharacterDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/CharacterDemo/CharacterDemo.cpp b/Demos/CharacterDemo/CharacterDemo.cpp new file mode 100644 index 0000000..085a583 --- /dev/null +++ b/Demos/CharacterDemo/CharacterDemo.cpp @@ -0,0 +1,531 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" +#include "BulletCollision/CollisionDispatch/btGhostObject.h" + +#include "GLDebugDrawer.h" +#include //printf debugging + +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" +#include "CharacterDemo.h" +#ifdef DYNAMIC_CHARACTER_CONTROLLER +#include "DynamicCharacterController.h" +#else +#include "BulletDynamics/Character/btKinematicCharacterController.h" +#endif + +const int maxProxies = 32766; +const int maxOverlap = 65535; + +static int gForward = 0; +static int gBackward = 0; +static int gLeft = 0; +static int gRight = 0; +static int gJump = 0; + + + + +CharacterDemo::CharacterDemo() +: +m_indexVertexArrays(0), +m_vertices(0), +m_cameraHeight(4.f), +m_minCameraDistance(3.f), +m_maxCameraDistance(10.f) +{ + m_character = 0; + m_cameraPosition = btVector3(30,30,30); +} + + +void CharacterDemo::initPhysics() +{ + btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); + m_collisionShapes.push_back(groundShape); + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + btAxisSweep3* sweepBP = new btAxisSweep3(worldMin,worldMax); + m_overlappingPairCache = sweepBP; + + m_constraintSolver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); + m_dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration=0.0001f; + +#ifdef DYNAMIC_CHARACTER_CONTROLLER + m_character = new DynamicCharacterController (); +#else + + btTransform startTransform; + startTransform.setIdentity (); + //startTransform.setOrigin (btVector3(0.0, 4.0, 0.0)); + startTransform.setOrigin (btVector3(10.210098,-1.6433364,16.453260)); + + + m_ghostObject = new btPairCachingGhostObject(); + m_ghostObject->setWorldTransform(startTransform); + sweepBP->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback()); + btScalar characterHeight=1.75; + btScalar characterWidth =1.75; + btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight); + m_ghostObject->setCollisionShape (capsule); + m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT); + + btScalar stepHeight = btScalar(0.35); + m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight); +#endif + + //////////////// + + /// Create some basic environment from a Quake level + + //m_dynamicsWorld->setGravity(btVector3(0,0,0)); + btTransform tr; + tr.setIdentity(); + + const char* bspfilename = "BspDemo.bsp"; + void* memoryBuffer = 0; + + FILE* file = fopen(bspfilename,"r"); + if (!file) + { + //cmake generated visual studio projects need 4 levels back + bspfilename = "../../../../BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + if (!file) + { + //visual studio leaves the current working directory in the projectfiles folder + bspfilename = "../../BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + if (!file) + { + //visual studio leaves the current working directory in the projectfiles folder + bspfilename = "BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + + if (file) + { + BspLoader bspLoader; + int size=0; + if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ + printf("Error: cannot get filesize from %s\n", bspfilename); + } else + { + //how to detect file size? + memoryBuffer = malloc(size+1); + fread(memoryBuffer,1,size,file); + bspLoader.loadBSPFile( memoryBuffer); + + BspToBulletConverter bsp2bullet(this); + float bspScaling = 0.1f; + bsp2bullet.convertBsp(bspLoader,bspScaling); + + } + fclose(file); + } + + ///only collide with static for now (no interaction with dynamic objects) + m_dynamicsWorld->addCollisionObject(m_ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter); + + m_dynamicsWorld->addAction(m_character); + + + /////////////// + + clientResetScene(); + + setCameraDistance(56.f); + +} + + +//to be implemented by the demo +void CharacterDemo::renderme() +{ + updateCamera(); + + DemoApplication::renderme(); +} + + + +void CharacterDemo::debugDrawContacts() +{ +// printf("numPairs = %d\n",m_customPairCallback->getOverlappingPairArray().size()); + { + btManifoldArray manifoldArray; + btBroadphasePairArray& pairArray = m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray(); + int numPairs = pairArray.size(); + + for (int i=0;igetOverlappingPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1); + if (!collisionPair) + continue; + + if (collisionPair->m_algorithm) + collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); + + for (int j=0;jgetNumContacts();p++) + { + const btManifoldPoint&pt = manifold->getContactPoint(p); + + btVector3 color(255,255,255); + m_dynamicsWorld->getDebugDrawer()->drawContactPoint(pt.getPositionWorldOnB(),pt.m_normalWorldOnB,pt.getDistance(),pt.getLifeTime(),color); + } + } + } + } + +} + +void CharacterDemo::clientMoveAndDisplay() +{ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + /* Character stuff &*/ + if (m_character) + { + + } + + debugDrawContacts(); + + + if (m_dynamicsWorld) + { + //during idle mode, just run 1 simulation step maximum + int maxSimSubSteps = m_idle ? 1 : 2; + if (m_idle) + dt = 1.0/420.f; + + ///set walkDirection for our character + btTransform xform; + xform = m_ghostObject->getWorldTransform (); + + btVector3 forwardDir = xform.getBasis()[2]; + // printf("forwardDir=%f,%f,%f\n",forwardDir[0],forwardDir[1],forwardDir[2]); + btVector3 upDir = xform.getBasis()[1]; + btVector3 strafeDir = xform.getBasis()[0]; + forwardDir.normalize (); + upDir.normalize (); + strafeDir.normalize (); + + btVector3 walkDirection = btVector3(0.0, 0.0, 0.0); + btScalar walkVelocity = btScalar(1.1) * 4.0; // 4 km/h -> 1.1 m/s + btScalar walkSpeed = walkVelocity * dt; + + //rotate view + if (gLeft) + { + btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis(); + orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),0.01)); + m_ghostObject->getWorldTransform ().setBasis(orn); + } + + if (gRight) + { + btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis(); + orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),-0.01)); + m_ghostObject->getWorldTransform ().setBasis(orn); + } + + if (gForward) + walkDirection += forwardDir; + + if (gBackward) + walkDirection -= forwardDir; + + + m_character->setWalkDirection(walkDirection*walkSpeed); + + + int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + +//#define VERBOSE_FEEDBACK +#ifdef VERBOSE_FEEDBACK + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } +#endif //VERBOSE_FEEDBACK + + } + + + + + + + +#ifdef USE_QUICKPROF + btProfiler::beginBlock("render"); +#endif //USE_QUICKPROF + + + renderme(); + +#ifdef USE_QUICKPROF + btProfiler::endBlock("render"); +#endif + + + glFlush(); + glutSwapBuffers(); + +} + + + +void CharacterDemo::displayCallback(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + debugDrawContacts(); + + glFlush(); + glutSwapBuffers(); +} + +void CharacterDemo::clientResetScene() +{ + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_ghostObject->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + + m_character->reset (); + ///WTF + m_character->warp (btVector3(10.210001,-2.0306311,16.576973)); + +} + +void CharacterDemo::specialKeyboardUp(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP: + { + gForward = 0; + } + break; + case GLUT_KEY_DOWN: + { + gBackward = 0; + } + break; + case GLUT_KEY_LEFT: + { + gLeft = 0; + } + break; + case GLUT_KEY_RIGHT: + { + gRight = 0; + } + break; + default: + DemoApplication::specialKeyboardUp(key,x,y); + break; + } +} + + +void CharacterDemo::specialKeyboard(int key, int x, int y) +{ + +// printf("key = %i x=%i y=%i\n",key,x,y); + + switch (key) + { + case GLUT_KEY_UP: + { + gForward = 1; + } + break; + case GLUT_KEY_DOWN: + { + gBackward = 1; + } + break; + case GLUT_KEY_LEFT: + { + gLeft = 1; + } + break; + case GLUT_KEY_RIGHT: + { + gRight = 1; + } + break; + case GLUT_KEY_F1: + { + if (m_character && m_character->canJump()) + gJump = 1; + } + break; + default: + DemoApplication::specialKeyboard(key,x,y); + break; + } + +// glutPostRedisplay(); + + +} + +void CharacterDemo::updateCamera() +{ + +//#define DISABLE_CAMERA 1 +#ifdef DISABLE_CAMERA + DemoApplication::updateCamera(); + return; +#endif //DISABLE_CAMERA + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + btTransform characterWorldTrans; + + //look at the vehicle + characterWorldTrans = m_ghostObject->getWorldTransform(); + btVector3 up = characterWorldTrans.getBasis()[1]; + btVector3 backward = -characterWorldTrans.getBasis()[2]; + up.normalize (); + backward.normalize (); + + m_cameraTargetPosition = characterWorldTrans.getOrigin(); + m_cameraPosition = m_cameraTargetPosition + up * 10.0 + backward * 12.0; + + //use the convex sweep test to find a safe position for the camera (not blocked by static geometry) + btSphereShape cameraSphere(0.2f); + btTransform cameraFrom,cameraTo; + cameraFrom.setIdentity(); + cameraFrom.setOrigin(characterWorldTrans.getOrigin()); + cameraTo.setIdentity(); + cameraTo.setOrigin(m_cameraPosition); + + btCollisionWorld::ClosestConvexResultCallback cb( characterWorldTrans.getOrigin(), cameraTo.getOrigin() ); + cb.m_collisionFilterMask = btBroadphaseProxy::StaticFilter; + + m_dynamicsWorld->convexSweepTest(&cameraSphere,cameraFrom,cameraTo,cb); + if (cb.hasHit()) + { + + btScalar minFraction = cb.m_closestHitFraction;//btMax(btScalar(0.3),cb.m_closestHitFraction); + m_cameraPosition.setInterpolate3(cameraFrom.getOrigin(),cameraTo.getOrigin(),minFraction); + } + + + + + //update OpenGL camera settings + glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + gluLookAt(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2], + m_cameraTargetPosition[0],m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + + + +} + + +CharacterDemo::~CharacterDemo() +{ + //cleanup in the reverse order of creation/initialization + if (m_character) + { + m_dynamicsWorld->removeCollisionObject(m_ghostObject); + } + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + class btBroadphaseInterface* m_overlappingPairCache; + + class btCollisionDispatcher* m_dispatcher; + + class btConstraintSolver* m_constraintSolver; + + class btDefaultCollisionConfiguration* m_collisionConfiguration; + + class btTriangleIndexVertexArray* m_indexVertexArrays; + + btVector3* m_vertices; + + void debugDrawContacts(); + + float m_cameraHeight; + + float m_minCameraDistance; + float m_maxCameraDistance; + + + CharacterDemo(); + + virtual ~CharacterDemo(); + + virtual void clientMoveAndDisplay(); + + virtual void clientResetScene(); + + virtual void displayCallback(); + + ///a very basic camera following the character + virtual void updateCamera(); + + virtual void specialKeyboard(int key, int x, int y); + + virtual void specialKeyboardUp(int key, int x, int y); + + void renderme(); + + void initPhysics(); + + static DemoApplication* Create() + { + CharacterDemo* demo = new CharacterDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + + + +#define QUAKE_BSP_IMPORTING 1 +#ifdef QUAKE_BSP_IMPORTING +#include "../BspDemo/BspLoader.h" +#include "../BspDemo/BspConverter.h" + + + + +class BspToBulletConverter : public BspConverter +{ + CharacterDemo* m_demoApp; + +public: + + BspToBulletConverter(CharacterDemo* demoApp) + :m_demoApp(demoApp) + { + } + + virtual void addConvexVerticesCollider(btAlignedObjectArray& vertices, bool isEntity, const btVector3& entityTargetLocation) + { + ///perhaps we can do something special with entities (isEntity) + ///like adding a collision Triggering (as example) + + if (vertices.size() > 0) + { + float mass = 0.f; + btTransform startTransform; + //can use a shift + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-10.0f,0.0f)); + //this create an internal copy of the vertices + for (int i = 0; i < vertices.size(); i++) + { + vertices[i] *= btScalar(0.5); + float t = vertices[i].getZ() * btScalar(0.75); + vertices[i].setZ(-vertices[i].getY()); + vertices[i].setY(t); + } + + btCollisionShape* shape = new btConvexHullShape(&(vertices[0].getX()),vertices.size()); + m_demoApp->m_collisionShapes.push_back(shape); + + //btRigidBody* body = m_demoApp->localCreateRigidBody(mass, startTransform,shape); + m_demoApp->localCreateRigidBody(mass, startTransform,shape); + } + } +}; +#endif //QUAKE_BSP_IMPORTING + + +#endif //CHARACTER_DEMO_H + + diff --git a/Demos/CharacterDemo/DynamicCharacterController.cpp b/Demos/CharacterDemo/DynamicCharacterController.cpp new file mode 100644 index 0000000..452d86b --- /dev/null +++ b/Demos/CharacterDemo/DynamicCharacterController.cpp @@ -0,0 +1,204 @@ +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "LinearMath/btDefaultMotionState.h" +#include "DynamicCharacterController.h" + +DynamicCharacterController::DynamicCharacterController () +{ + m_rayLambda[0] = 1.0; + m_rayLambda[1] = 1.0; + m_halfHeight = 1.0; + m_turnAngle = 0.0; + m_maxLinearVelocity = 10.0; + m_walkVelocity = 8.0; // meters/sec + m_turnVelocity = 1.0; // radians/sec + m_shape = NULL; + m_rigidBody = NULL; +} + +DynamicCharacterController::~DynamicCharacterController () +{ +} + +void DynamicCharacterController::setup (btScalar height, btScalar width, btScalar stepHeight) +{ + btVector3 spherePositions[2]; + btScalar sphereRadii[2]; + + sphereRadii[0] = width; + sphereRadii[1] = width; + spherePositions[0] = btVector3 (0.0, (height/btScalar(2.0) - width), 0.0); + spherePositions[1] = btVector3 (0.0, (-height/btScalar(2.0) + width), 0.0); + + m_halfHeight = height/btScalar(2.0); + + m_shape = new btMultiSphereShape (&spherePositions[0], &sphereRadii[0], 2); + + btTransform startTransform; + startTransform.setIdentity (); + startTransform.setOrigin (btVector3(0.0, 2.0, 0.0)); + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo cInfo(1.0, myMotionState, m_shape); + m_rigidBody = new btRigidBody(cInfo); + // kinematic vs. static doesn't work + //m_rigidBody->setCollisionFlags( m_rigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + m_rigidBody->setSleepingThresholds (0.0, 0.0); + m_rigidBody->setAngularFactor (0.0); + +} + +void DynamicCharacterController::destroy () +{ + if (m_shape) + { + delete m_shape; + } + + if (m_rigidBody) + { + delete m_rigidBody; + m_rigidBody = 0; + } +} + +btCollisionObject* DynamicCharacterController::getCollisionObject () +{ + return m_rigidBody; +} + +void DynamicCharacterController::preStep (const btCollisionWorld* collisionWorld) +{ + btTransform xform; + m_rigidBody->getMotionState()->getWorldTransform (xform); + btVector3 down = -xform.getBasis()[1]; + btVector3 forward = xform.getBasis()[2]; + down.normalize (); + forward.normalize(); + + m_raySource[0] = xform.getOrigin(); + m_raySource[1] = xform.getOrigin(); + + m_rayTarget[0] = m_raySource[0] + down * m_halfHeight * btScalar(1.1); + m_rayTarget[1] = m_raySource[1] + forward * m_halfHeight * btScalar(1.1); + + class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback + { + public: + ClosestNotMe (btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + { + m_me = me; + } + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) + { + if (rayResult.m_collisionObject == m_me) + return 1.0; + + return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace + ); + } + protected: + btRigidBody* m_me; + }; + + ClosestNotMe rayCallback(m_rigidBody); + + int i = 0; + for (i = 0; i < 2; i++) + { + rayCallback.m_closestHitFraction = 1.0; + collisionWorld->rayTest (m_raySource[i], m_rayTarget[i], rayCallback); + if (rayCallback.hasHit()) + { + m_rayLambda[i] = rayCallback.m_closestHitFraction; + } else { + m_rayLambda[i] = 1.0; + } + } +} + +void DynamicCharacterController::playerStep (const btCollisionWorld* dynaWorld,btScalar dt, + int forward, + int backward, + int left, + int right, + int jump) +{ + btTransform xform; + m_rigidBody->getMotionState()->getWorldTransform (xform); + + /* Handle turning */ + if (left) + m_turnAngle -= dt * m_turnVelocity; + if (right) + m_turnAngle += dt * m_turnVelocity; + + xform.setRotation (btQuaternion (btVector3(0.0, 1.0, 0.0), m_turnAngle)); + + btVector3 linearVelocity = m_rigidBody->getLinearVelocity(); + btScalar speed = m_rigidBody->getLinearVelocity().length(); + + btVector3 forwardDir = xform.getBasis()[2]; + forwardDir.normalize (); + btVector3 walkDirection = btVector3(0.0, 0.0, 0.0); + btScalar walkSpeed = m_walkVelocity * dt; + + if (forward) + walkDirection += forwardDir; + if (backward) + walkDirection -= forwardDir; + + + + if (!forward && !backward && onGround()) + { + /* Dampen when on the ground and not being moved by the player */ + linearVelocity *= btScalar(0.2); + m_rigidBody->setLinearVelocity (linearVelocity); + } else { + if (speed < m_maxLinearVelocity) + { + btVector3 velocity = linearVelocity + walkDirection * walkSpeed; + m_rigidBody->setLinearVelocity (velocity); + } + } + + m_rigidBody->getMotionState()->setWorldTransform (xform); + m_rigidBody->setCenterOfMassTransform (xform); +} + +bool DynamicCharacterController::canJump () const +{ + return onGround(); +} + +void DynamicCharacterController::jump () +{ + if (!canJump()) + return; + + btTransform xform; + m_rigidBody->getMotionState()->getWorldTransform (xform); + btVector3 up = xform.getBasis()[1]; + up.normalize (); + btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0); + m_rigidBody->applyCentralImpulse (up * magnitude); +} + +bool DynamicCharacterController::onGround () const +{ + return m_rayLambda[0] < btScalar(1.0); +} + +void DynamicCharacterController::reset () +{ +} +void DynamicCharacterController::warp (const btVector3& origin) +{ +} +void DynamicCharacterController::registerPairCacheAndDispatcher (btOverlappingPairCache* pairCache, btCollisionDispatcher* dispatcher) +{ + +} + diff --git a/Demos/CharacterDemo/DynamicCharacterController.h b/Demos/CharacterDemo/DynamicCharacterController.h new file mode 100644 index 0000000..241aaea --- /dev/null +++ b/Demos/CharacterDemo/DynamicCharacterController.h @@ -0,0 +1,55 @@ +#ifndef CHARACTER_CONTROLLER_H +#define CHARACTER_CONTROLLER_H + +#include "LinearMath/btVector3.h" + +#include "BulletDynamics/Character/btCharacterControllerInterface.h" + +class btCollisionShape; +class btRigidBody; +class btCollisionWorld; + +///DynamicCharacterController is obsolete/unsupported at the moment +class DynamicCharacterController : public btCharacterControllerInterface +{ +protected: + btScalar m_halfHeight; + btCollisionShape* m_shape; + btRigidBody* m_rigidBody; + + btVector3 m_raySource[2]; + btVector3 m_rayTarget[2]; + btScalar m_rayLambda[2]; + btVector3 m_rayNormal[2]; + + btScalar m_turnAngle; + + btScalar m_maxLinearVelocity; + btScalar m_walkVelocity; + btScalar m_turnVelocity; +public: + DynamicCharacterController (); + ~DynamicCharacterController (); + void setup (btScalar height = 2.0, btScalar width = 0.25, btScalar stepHeight = 0.25); + void destroy (); + + virtual void reset (); + virtual void warp (const btVector3& origin); + virtual void registerPairCacheAndDispatcher (btOverlappingPairCache* pairCache, btCollisionDispatcher* dispatcher); + + btCollisionObject* getCollisionObject (); + + void preStep (const btCollisionWorld* collisionWorld); + void playerStep (const btCollisionWorld* collisionWorld,btScalar dt, + int forward, + int backward, + int left, + int right, + int jump); + bool canJump () const; + void jump (); + + bool onGround () const; +}; + +#endif diff --git a/Demos/CharacterDemo/main.cpp b/Demos/CharacterDemo/main.cpp new file mode 100644 index 0000000..080eb86 --- /dev/null +++ b/Demos/CharacterDemo/main.cpp @@ -0,0 +1,19 @@ + +#include "CharacterDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + CharacterDemo* characterDemo = new CharacterDemo; + + characterDemo->initPhysics(); + characterDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + return glutmain(argc, argv,640,480,"Bullet Character Demo. http://www.continuousphysics.com/Bullet/phpBB2/", characterDemo); +} + diff --git a/Demos/CollisionDemo/CMakeLists.txt b/Demos/CollisionDemo/CMakeLists.txt new file mode 100644 index 0000000..0d6843f --- /dev/null +++ b/Demos/CollisionDemo/CMakeLists.txt @@ -0,0 +1,54 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +IF (WIN32) + ADD_EXECUTABLE(AppCollisionDemo + CollisionDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppCollisionDemo + CollisionDemo.cpp + ) +ENDIF() + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCollisionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCollisionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppCollisionDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppCollisionDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppCollisionDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/CollisionDemo/CollisionDemo.cpp b/Demos/CollisionDemo/CollisionDemo.cpp new file mode 100644 index 0000000..3f4b050 --- /dev/null +++ b/Demos/CollisionDemo/CollisionDemo.cpp @@ -0,0 +1,380 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +/// +/// Collision Demo shows a degenerate case, where the Simplex solver has to deal with near-affine dependent cases +/// See the define CATCH_DEGENERATE_TETRAHEDRON in Bullet's btVoronoiSimplexSolver.cpp +/// + + +//#define CHECK_GENSHER_TRIANGLE_CASE 1 + + +///This low-level internal demo does intentionally NOT use the btBulletCollisionCommon.h header +///It needs internal access +#include "GL_Simplex1to4.h" +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "LinearMath/btTransformUtil.h" + +#include "CollisionDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" +#include "LinearMath/btIDebugDraw.h" +#include "../OpenGL/GLDebugDrawer.h" +GLDebugDrawer debugDrawer; + + +float yaw=0.f,pitch=0.f,roll=0.f; +const int maxNumObjects = 4; +const int numObjects = 2; + +GL_Simplex1to4 simplex; + +btPolyhedralConvexShape* shapePtr[maxNumObjects]; + +btTransform tr[numObjects]; +int screenWidth = 640; +int screenHeight = 480; + +void DrawRasterizerLine(float const* , float const*, int) +{ + +} + +int main(int argc,char** argv) +{ + CollisionDemo* colDemo = new CollisionDemo(); + +#ifdef CHECK_GENSHER_TRIANGLE_CASE + colDemo->setCameraDistance(8.f); +#else + colDemo->setCameraDistance(4.f); + +#endif // + colDemo->initPhysics(); + + + + return glutmain(argc, argv,screenWidth,screenHeight,"Collision Demo",colDemo); +} + +void CollisionDemo::initPhysics() +{ + setTexturing(false); + setShadows(false); + + //m_debugMode |= btIDebugDraw::DBG_DrawWireframe; +#ifdef CHECK_GENSHER_TRIANGLE_CASE + m_azi = 140.f; +#else + m_azi = 250.f; +#endif + m_ele = 25.f; + + m_azi = 0; + m_ele = 0; + m_cameraTargetPosition.setValue(8.12,0.39,0); + + tr[0].setIdentity(); + tr[0].setOrigin(btVector3(10,0,0)); + tr[1].setIdentity(); + tr[1].setOrigin(btVector3(0,0,0)); + + +#ifdef CHECK_GENSHER_TRIANGLE_CASE + tr[0].setIdentity(); + tr[1].setIdentity(); +#endif //CHECK_GENSHER_TRIANGLE_CASE + + btVector3 boxHalfExtentsA(1,1,1);//1.0000004768371582f,1.0000004768371582f,1.0000001192092896f); + btVector3 boxHalfExtentsB(4,4,4);//3.2836332321166992f,3.2836332321166992f,3.2836320400238037f); + +#ifndef CHECK_GENSHER_TRIANGLE_CASE + btBoxShape* boxA = new btBoxShape(boxHalfExtentsA); + btBoxShape* boxB = new btBoxShape(boxHalfExtentsB); +#endif + + + + + + +#ifdef CHECK_GENSHER_TRIANGLE_CASE + shapePtr[0] = trishapeA; + shapePtr[1] = trishapeB; +#else + shapePtr[0] = boxA; + shapePtr[1] = boxB; +#endif + +} + +void CollisionDemo::clientMoveAndDisplay() +{ + + displayCallback(); +} + + +static btVoronoiSimplexSolver sGjkSimplexSolver; +btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver; + +static btScalar gContactBreakingThreshold=.02f; +int myiter = 1; +int mystate = 2; + +int checkPerturbation = 1; +int numPerturbationIterations = 20; +void CollisionDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + + btVoronoiSimplexSolver sGjkSimplexSolver; + btGjkEpaPenetrationDepthSolver epaSolver; + btPointCollector gjkOutput; + btVector3 worldBoundsMin(-1000,-1000,-1000); + btVector3 worldBoundsMax(1000,1000,1000); + { + btGjkPairDetector convexConvex(shapePtr[0],shapePtr[1],&sGjkSimplexSolver,&epaSolver); + + btGjkPairDetector::ClosestPointInput input; + input.m_transformA = tr[0]; + input.m_transformB = tr[1]; + + + convexConvex.getClosestPoints(input, gjkOutput, 0); + } + + ATTRIBUTE_ALIGNED16(btScalar) m[16]; + int i; + + //m_ele = 21.2; + //m_azi = -56.6; + + + + + for (i=0;idrawOpenGL(m,shapePtr[i],btVector3(119./255.,147./255.,60./255.),btIDebugDraw::DBG_FastWireframe,worldBoundsMin,worldBoundsMax); + m_shapeDrawer->drawOpenGL(m,shapePtr[i],btVector3(0.6,0.6,0.6),btIDebugDraw::DBG_FastWireframe,worldBoundsMin,worldBoundsMax); + } + + if (gjkOutput.m_hasResult) + { + printf("original distance: %10.4f\n", gjkOutput.m_distance); + btVector3 endPt = gjkOutput.m_pointInWorld + + gjkOutput.m_normalOnBInWorld*gjkOutput.m_distance; + + debugDrawer.drawLine(gjkOutput.m_pointInWorld,endPt,btVector3(0,0,0)); + debugDrawer.drawSphere(gjkOutput.m_pointInWorld,0.05,btVector3(0,0,0)); + debugDrawer.drawSphere(endPt,0.05,btVector3(0,0,0)); + + bool perturbeA = false;//true; + const btScalar angleLimit = 0.125f * SIMD_PI; + btScalar perturbeAngle; + btScalar radiusA = shapePtr[0]->getAngularMotionDisc(); + btScalar radiusB = shapePtr[1]->getAngularMotionDisc(); + + if (radiusA < radiusB) + { + perturbeAngle = gContactBreakingThreshold /radiusA; + perturbeA = true; + } else + { + perturbeAngle = gContactBreakingThreshold / radiusB; + perturbeA = false; + } + if ( perturbeAngle > angleLimit ) + perturbeAngle = angleLimit; + + perturbeAngle*=5; + + btVector3 v0,v1; + btPlaneSpace1(gjkOutput.m_normalOnBInWorld,v0,v1); + + glLineWidth(5); + int i; + i=0; + if (myiter>=numPerturbationIterations) + myiter=0; + if (mystate<2) + { + i= myiter; + } + + for ( ;idrawOpenGL(m,shapePtr[0],btVector3(108./255.,131./255.,158./255),btIDebugDraw::DBG_FastWireframe,worldBoundsMin,worldBoundsMax); + m_shapeDrawer->drawOpenGL(m,shapePtr[0],btVector3(0.3,0.3,1),btIDebugDraw::DBG_FastWireframe,worldBoundsMin,worldBoundsMax); + + } + + if (1)//gjkOutput.m_hasResult) + { + + printf("perturbed distance: %10.4f\n", gjkOutput.m_distance); + btVector3 startPt,endPt; + btScalar depth = 0; + if (perturbeA) + { + btVector3 endPtOrg = gjkOutput.m_pointInWorld + gjkOutput.m_normalOnBInWorld*gjkOutput.m_distance; + endPt = (tr[0]*input.m_transformA.inverse())(endPtOrg); + depth = (endPt - gjkOutput.m_pointInWorld).dot(gjkOutput.m_normalOnBInWorld); + startPt = endPt-gjkOutput.m_normalOnBInWorld*depth; + } else + { + endPt = gjkOutput.m_pointInWorld + gjkOutput.m_normalOnBInWorld*gjkOutput.m_distance; + startPt = (tr[1]*input.m_transformB.inverse())(gjkOutput.m_pointInWorld); + depth = (endPt - startPt).dot(gjkOutput.m_normalOnBInWorld); + } + + printf("corrected distance: %10.4f\n", depth); + + + + debugDrawer.drawLine(startPt,endPt,btVector3(1,0,0)); + debugDrawer.drawSphere(startPt,0.05,btVector3(0,1,0)); + debugDrawer.drawSphere(endPt,0.05,btVector3(0,0,1)); + } + if (mystate<2) + break; + if (mystate==2 && i>myiter) + break; + } + + + } + + static int looper = 0; + if (looper++>10) + { + looper =0; + checkPerturbation++; + if (checkPerturbation>numPerturbationIterations) + checkPerturbation=0; + } + + GL_ShapeDrawer::drawCoordSystem(); + + + + if (mystate==1 || mystate==2) + { + static int count = 10; + count--; + if (count<0) + { + count=10; + myiter++; + } + } + + btQuaternion orn; + orn.setEuler(yaw,pitch,roll); + //let it rotate + //tr[0].setRotation(orn); + + pitch += 0.005f; + yaw += 0.01f; + + glFlush(); + glutSwapBuffers(); +} + + +void CollisionDemo::specialKeyboard(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_DOWN: + case GLUT_KEY_UP: + { + break; + } + default: + DemoApplication::specialKeyboard(key,x,y); + break; + } + +} + +void CollisionDemo::specialKeyboardUp(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP : + { + myiter++; + break; + } + + case GLUT_KEY_DOWN: + { + mystate++; + if (mystate>1) + myiter=0; + if (mystate>=4) + mystate = 0; + break; + } + default: + DemoApplication::specialKeyboardUp(key,x,y); + break; + } +} diff --git a/Demos/CollisionDemo/CollisionDemo.h b/Demos/CollisionDemo/CollisionDemo.h new file mode 100644 index 0000000..487250a --- /dev/null +++ b/Demos/CollisionDemo/CollisionDemo.h @@ -0,0 +1,38 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef COLLISION_DEMO_H +#define COLLISION_DEMO_H + +#include "GlutDemoApplication.h" + +///CollisionDemo shows the low-level direct access to GJK +class CollisionDemo : public GlutDemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void specialKeyboardUp(int key, int x, int y); + + virtual void specialKeyboard(int key, int x, int y); + +}; + +#endif //COLLISION_DEMO_H + diff --git a/Demos/CollisionInterfaceDemo/CMakeLists.txt b/Demos/CollisionInterfaceDemo/CMakeLists.txt new file mode 100644 index 0000000..82e2ca6 --- /dev/null +++ b/Demos/CollisionInterfaceDemo/CMakeLists.txt @@ -0,0 +1,77 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +IF (USE_GLUT) + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppCollisionInterfaceDemo + CollisionInterfaceDemo.cpp + CollisionInterfaceDemo.h + main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppCollisionInterfaceDemo + CollisionInterfaceDemo.cpp + CollisionInterfaceDemo.h + main.cpp + ) + ENDIF() + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCollisionInterfaceDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppCollisionInterfaceDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) +ELSE (USE_GLUT) + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppCollisionInterfaceDemo + WIN32 + CollisionInterfaceDemo.cpp + CollisionInterfaceDemo.h + Win32CollisionInterfaceDemo.cpp + ../OpenGL/Win32AppMain.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ENDIF (USE_GLUT) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppCollisionInterfaceDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppCollisionInterfaceDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppCollisionInterfaceDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp new file mode 100644 index 0000000..c44d9a5 --- /dev/null +++ b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp @@ -0,0 +1,292 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +/// +/// CollisionInterfaceDemo shows high level usage of the Collision Detection. +/// +#define TEST_NOT_ADDING_OBJECTS_TO_WORLD + +#include "GL_Simplex1to4.h" + +//include common Bullet Collision Detection headerfiles +#include "btBulletCollisionCommon.h" + +#include "LinearMath/btIDebugDraw.h" +#include "GL_ShapeDrawer.h" +#include "CollisionInterfaceDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" + +btScalar yaw=0.f,pitch=0.f,roll=0.f; +const int maxNumObjects = 4; +const int numObjects = 2; + +GL_Simplex1to4 simplex; + +btCollisionObject objects[maxNumObjects]; +btCollisionWorld* collisionWorld = 0; + +GLDebugDrawer debugDrawer; + + +void CollisionInterfaceDemo::initPhysics() +{ + + m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + + btMatrix3x3 basisA; + basisA.setIdentity(); + + btMatrix3x3 basisB; + basisB.setIdentity(); + + objects[0].getWorldTransform().setBasis(basisA); + objects[1].getWorldTransform().setBasis(basisB); + + btBoxShape* boxA = new btBoxShape(btVector3(1,1,1)); + boxA->setMargin(0.f); + + btBoxShape* boxB = new btBoxShape(btVector3(0.5,0.5,0.5)); + boxB->setMargin(0.f); + //ConvexHullShape hullA(points0,3); + //hullA.setLocalScaling(btVector3(3,3,3)); + //ConvexHullShape hullB(points1,4); + //hullB.setLocalScaling(btVector3(4,4,4)); + + objects[0].setCollisionShape(boxA);//&hullA; + objects[1].setCollisionShape(boxB);//&hullB; + + btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); + btVector3 worldAabbMin(-1000,-1000,-1000); + btVector3 worldAabbMax(1000,1000,1000); + + btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax); + + //SimpleBroadphase is a brute force alternative, performing N^2 aabb overlap tests + //SimpleBroadphase* broadphase = new btSimpleBroadphase; + + collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration); + collisionWorld->setDebugDrawer(&debugDrawer); + +#ifdef TEST_NOT_ADDING_OBJECTS_TO_WORLD +// collisionWorld->addCollisionObject(&objects[0]); + collisionWorld->addCollisionObject(&objects[1]); +#endif //TEST_NOT_ADDING_OBJECTS_TO_WORLD + +} + + +//to be implemented by the demo + +void CollisionInterfaceDemo::clientMoveAndDisplay() +{ + + displayCallback(); +} + + +static btVoronoiSimplexSolver sGjkSimplexSolver; +btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver; + +struct btDrawingResult : public btCollisionWorld::ContactResultCallback +{ + virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) + { + + glBegin(GL_LINES); + glColor3f(0, 0, 0); + + btVector3 ptA = cp.getPositionWorldOnA(); + btVector3 ptB = cp.getPositionWorldOnB(); + + glVertex3d(ptA.x(),ptA.y(),ptA.z()); + glVertex3d(ptB.x(),ptB.y(),ptB.z()); + glEnd(); + + return 0; + } +}; + +void CollisionInterfaceDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + + btScalar m[16]; + + btVector3 worldBoundsMin,worldBoundsMax; + collisionWorld->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); + + + int i; + for (i=0;idrawOpenGL(m,objects[i].getCollisionShape(),btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax); + } + + collisionWorld->getDispatchInfo().m_debugDraw = &debugDrawer; + + if (collisionWorld) + collisionWorld->performDiscreteCollisionDetection(); + + + + + +#ifndef TEST_NOT_ADDING_OBJECTS_TO_WORLD + + collisionWorld->debugDrawWorld(); + ///one way to draw all the contact points is iterating over contact manifolds in the dispatcher: + + int numManifolds = collisionWorld->getDispatcher()->getNumManifolds(); + for (i=0;igetDispatcher()->getManifoldByIndexInternal(i); + btCollisionObject* obA = static_cast(contactManifold->getBody0()); + btCollisionObject* obB = static_cast(contactManifold->getBody1()); + + int numContacts = contactManifold->getNumContacts(); + for (int j=0;jgetContactPoint(j); + + glBegin(GL_LINES); + glColor3f(0, 0, 0); + + btVector3 ptA = pt.getPositionWorldOnA(); + btVector3 ptB = pt.getPositionWorldOnB(); + + glVertex3d(ptA.x(),ptA.y(),ptA.z()); + glVertex3d(ptB.x(),ptB.y(),ptB.z()); + glEnd(); + } + + //you can un-comment out this line, and then all points are removed + //contactManifold->clearManifold(); + } +#else + + + glDisable(GL_TEXTURE_2D); + for (i=0;idebugDrawObject(objects[i].getWorldTransform(),objects[i].getCollisionShape(), btVector3(1,1,0)); + } + + btDrawingResult renderCallback; + + //collisionWorld->contactPairTest(&objects[0],&objects[1], renderCallback); + collisionWorld->contactTest(&objects[0],renderCallback); + +#if 0 + + //another way is to directly query the dispatcher for both objects. The objects don't need to be inserted into the world + + btCollisionAlgorithm* algo = collisionWorld->getDispatcher()->findAlgorithm(&objects[0],&objects[1]); + btManifoldResult contactPointResult(&objects[0],&objects[1]); + algo->processCollision(&objects[0],&objects[1],collisionWorld->getDispatchInfo(),&contactPointResult); + + btManifoldArray manifoldArray; + algo->getAllContactManifolds(manifoldArray); + + int numManifolds = manifoldArray.size(); + for (i=0;i(contactManifold->getBody0()); + // btCollisionObject* obB = static_cast(contactManifold->getBody1()); + + glDisable(GL_DEPTH_TEST); + int numContacts = contactManifold->getNumContacts(); + bool swap = obA == &objects[0]; + + for (int j=0;jgetContactPoint(j); + + glBegin(GL_LINES); + glColor3f(0, 0, 0); + + btVector3 ptA = swap ?pt.getPositionWorldOnA():pt.getPositionWorldOnB(); + btVector3 ptB = swap ? pt.getPositionWorldOnB():pt.getPositionWorldOnA(); + + glVertex3d(ptA.x(),ptA.y(),ptA.z()); + glVertex3d(ptB.x(),ptB.y(),ptB.z()); + glEnd(); + } + + //you can un-comment out this line, and then all points are removed + //contactManifold->clearManifold(); + } +#endif + + +#endif + + + + + + //GL_ShapeDrawer::drawCoordSystem(); + + +// btQuaternion qA = objects[0].getWorldTransform().getRotation(); +// btQuaternion qB = objects[1].getWorldTransform().getRotation(); + + + if (!m_idle) + { + + + btScalar timeInSeconds = getDeltaTimeMicroseconds()/1000.f; + + btQuaternion orn; + + objects[0].getWorldTransform().getBasis().getEulerYPR(yaw,pitch,roll); + pitch += 0.00005f*timeInSeconds; + yaw += 0.0001f*timeInSeconds; + objects[0].getWorldTransform().getBasis().setEulerYPR(yaw,pitch,roll); + + orn.setEuler(yaw,pitch,roll); + objects[1].getWorldTransform().setOrigin(objects[1].getWorldTransform().getOrigin()+btVector3(0,-0.00001*timeInSeconds,0)); + + //objects[0].getWorldTransform().setRotation(orn); + + + + } + + glFlush(); + swapBuffers(); +} + +void CollisionInterfaceDemo::clientResetScene() +{ + objects[0].getWorldTransform().setOrigin(btVector3(0.0f,3.f,0.f)); + + btQuaternion rotA(0.739f,-0.204f,0.587f,0.257f); + rotA.normalize(); + + objects[0].getWorldTransform().setRotation(rotA); + + objects[1].getWorldTransform().setOrigin(btVector3(0.0f,4.248f,0.f)); + +} + + diff --git a/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h new file mode 100644 index 0000000..9c0d611 --- /dev/null +++ b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h @@ -0,0 +1,42 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef COLLISION_INTERFACE_DEMO_H +#define COLLISION_INTERFACE_DEMO_H + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +///CollisionInterfaceDemo shows how to use the collision detection without dynamics (btCollisionWorld/CollisionObject) +class CollisionInterfaceDemo : public PlatformDemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene(); + +}; + +#endif //COLLISION_INTERFACE_DEMO_H + diff --git a/Demos/CollisionInterfaceDemo/Win32CollisionInterfaceDemo.cpp b/Demos/CollisionInterfaceDemo/Win32CollisionInterfaceDemo.cpp new file mode 100644 index 0000000..c2f5906 --- /dev/null +++ b/Demos/CollisionInterfaceDemo/Win32CollisionInterfaceDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "CollisionInterfaceDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new CollisionInterfaceDemo(); +} + +#endif diff --git a/Demos/CollisionInterfaceDemo/main.cpp b/Demos/CollisionInterfaceDemo/main.cpp new file mode 100644 index 0000000..f8cbb77 --- /dev/null +++ b/Demos/CollisionInterfaceDemo/main.cpp @@ -0,0 +1,19 @@ + +#include "CollisionInterfaceDemo.h" +#include "GlutStuff.h" +#include "btBulletDynamicsCommon.h" + +int screenWidth = 640; +int screenHeight = 480; + + +int main(int argc,char** argv) +{ + CollisionInterfaceDemo* collisionInterfaceDemo = new CollisionInterfaceDemo(); + + collisionInterfaceDemo->initPhysics(); + + collisionInterfaceDemo->clientResetScene(); + + return glutmain(argc, argv,screenWidth,screenHeight,"Collision Interface Demo",collisionInterfaceDemo); +} diff --git a/Demos/ConcaveConvexcastDemo/CMakeLists.txt b/Demos/ConcaveConvexcastDemo/CMakeLists.txt new file mode 100644 index 0000000..bf0c2bc --- /dev/null +++ b/Demos/ConcaveConvexcastDemo/CMakeLists.txt @@ -0,0 +1,48 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppConcaveConvexCastDemo + ConcaveConvexcastDemo.cpp + main.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConcaveConvexCastDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConcaveConvexCastDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppConcaveConvexCastDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppConcaveConvexCastDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppConcaveConvexCastDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp b/Demos/ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp new file mode 100644 index 0000000..8faf62a --- /dev/null +++ b/Demos/ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp @@ -0,0 +1,516 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "GLDebugDrawer.h" +#include "ConcaveConvexcastDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +#define NUM_DYNAMIC_BOXES_X 30 +#define NUM_DYNAMIC_BOXES_Y 30 + +static btVector3* gVertices=0; +static int* gIndices=0; +static btBvhTriangleMeshShape* trimeshShape =0; +static btRigidBody* staticBody = 0; +static float waveheight = 5.f; + +const float TRIANGLE_SIZE=8.f; + + +/* Scrolls back and forth over terrain */ +#define NUMRAYS_IN_BAR 100 +class btConvexcastBatch +{ +public: + btVector3 source[NUMRAYS_IN_BAR]; + btVector3 dest[NUMRAYS_IN_BAR]; + btVector3 direction[NUMRAYS_IN_BAR]; + btVector3 hit_com[NUMRAYS_IN_BAR]; + btVector3 hit_surface[NUMRAYS_IN_BAR]; + btScalar hit_fraction[NUMRAYS_IN_BAR]; + btVector3 normal[NUMRAYS_IN_BAR]; + + int frame_counter; + int ms; + int sum_ms; + int sum_ms_samples; + int min_ms; + int max_ms; + +#ifdef USE_BT_CLOCK + btClock frame_timer; +#endif //USE_BT_CLOCK + + btScalar dx; + btScalar min_x; + btScalar max_x; + btScalar min_y; + btScalar max_y; + btScalar sign; + + btVector3 boxShapeHalfExtents; + btBoxShape boxShape; + + btConvexcastBatch () : boxShape(btVector3(0.0, 0.0, 0.0)) + { + ms = 0; + max_ms = 0; + min_ms = 9999.0; + sum_ms_samples = 0; + sum_ms = 0; + } + + btConvexcastBatch (bool unused, btScalar ray_length, btScalar min_z, btScalar max_z, btScalar min_y , btScalar max_y ) : boxShape(btVector3(0.0, 0.0, 0.0)) + { + boxShapeHalfExtents = btVector3(1.0, 1.0, 1.0); + boxShape = btBoxShape(boxShapeHalfExtents); + frame_counter = 0; + ms = 0; + max_ms = 0; + min_ms = 9999.0; + sum_ms_samples = 0; + sum_ms = 0; + dx = 10.0; + min_x = -40; + max_x = 20; + this->min_y = min_y; + this->max_y = max_y; + sign = 1.0; + // btScalar dalpha = 2*SIMD_2_PI/NUMRAYS_IN_BAR; + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + btScalar z = (max_z-min_z)/NUMRAYS_IN_BAR * i + min_z; + source[i] = btVector3(min_x, max_y, z); + dest[i] = btVector3(min_x + ray_length, min_y, z); + normal[i] = btVector3(1.0, 0.0, 0.0); + } + } + + btConvexcastBatch (btScalar ray_length, btScalar z, btScalar min_y = -1000, btScalar max_y = 10) : boxShape(btVector3(0.0, 0.0, 0.0)) + { + boxShapeHalfExtents = btVector3(1.0, 1.0, 1.0); + boxShape = btBoxShape(boxShapeHalfExtents); + frame_counter = 0; + ms = 0; + max_ms = 0; + min_ms = 9999.0; + sum_ms_samples = 0; + sum_ms = 0; + dx = 10.0; + min_x = -40; + max_x = 20; + this->min_y = min_y; + this->max_y = max_y; + sign = 1.0; + btScalar dalpha = btScalar(2)*SIMD_2_PI/btScalar(NUMRAYS_IN_BAR); + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + btScalar alpha = dalpha * btScalar(i); + // rotate around by alpha degrees y + btTransform tr(btQuaternion(btVector3(0.0, 1.0, 0.0), alpha)); + direction[i] = btVector3(1.0, 0.0, 0.0); + direction[i] = tr * direction[i]; + source[i] = btVector3(min_x, max_y, z); + dest[i] = source[i] + direction[i] * ray_length; + dest[i][1] = min_y; + normal[i] = btVector3(1.0, 0.0, 0.0); + } + } + + void move (btScalar dt) + { + if (dt > (1.0/60.0)) + dt = 1.0/60.0; + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + source[i][0] += dx * dt * sign; + dest[i][0] += dx * dt * sign; + } + if (source[0][0] < min_x) + sign = 1.0; + else if (source[0][0] > max_x) + sign = -1.0; + } + + void cast (btCollisionWorld* cw) + { +#ifdef USE_BT_CLOCK + frame_timer.reset (); +#endif //USE_BT_CLOCK + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + btCollisionWorld::ClosestConvexResultCallback cb(source[i], dest[i]); + btQuaternion qFrom; + btQuaternion qTo; + qFrom.setRotation (btVector3(1.0, 0.0, 0.0), 0.0); + qTo.setRotation (btVector3(1.0, 0.0, 0.0), 0.7); + btTransform from(qFrom, source[i]); + btTransform to(qTo, dest[i]); + cw->convexSweepTest (&boxShape, from, to, cb); + if (cb.hasHit ()) + { + hit_surface[i] = cb.m_hitPointWorld; + hit_com[i].setInterpolate3(source[i], dest[i], cb.m_closestHitFraction); + hit_fraction[i] = cb.m_closestHitFraction; + normal[i] = cb.m_hitNormalWorld; + normal[i].normalize (); + } else { + hit_com[i] = dest[i]; + hit_surface[i] = dest[i]; + hit_fraction[i] = 1.0f; + normal[i] = btVector3(1.0, 0.0, 0.0); + } + + } +#ifdef USE_BT_CLOCK + ms += frame_timer.getTimeMilliseconds (); +#endif //USE_BT_CLOCK + frame_counter++; + if (frame_counter > 50) + { + min_ms = ms < min_ms ? ms : min_ms; + max_ms = ms > max_ms ? ms : max_ms; + sum_ms += ms; + sum_ms_samples++; + btScalar mean_ms = (btScalar)sum_ms/(btScalar)sum_ms_samples; + printf("%d rays in %d ms %d %d %f\n", NUMRAYS_IN_BAR * frame_counter, ms, min_ms, max_ms, mean_ms); + ms = 0; + frame_counter = 0; + } + } + + + void drawCube (const btTransform& T) + { + ATTRIBUTE_ALIGNED16(btScalar) m[16]; + T.getOpenGLMatrix (&m[0]); + glPushMatrix (); +#ifdef BT_USE_DOUBLE_PRECISION + glMultMatrixd (&m[0]); + glScaled (2.0 * boxShapeHalfExtents[0], 2.0 * boxShapeHalfExtents[1], 2.0 * boxShapeHalfExtents[2]); +#else + glMultMatrixf (&m[0]); + glScalef (2.0 * boxShapeHalfExtents[0], 2.0 * boxShapeHalfExtents[1], 2.0 * boxShapeHalfExtents[2]); +#endif //BT_USE_DOUBLE_PRECISION + glutSolidCube (1.0); + glPopMatrix (); + } + + void draw () + { + glDisable (GL_LIGHTING); + glColor3f (0.0, 1.0, 0.0); + glBegin (GL_LINES); + int i; + for (i = 0; i < NUMRAYS_IN_BAR; i++) + { + glVertex3f (source[i][0], source[i][1], source[i][2]); + glVertex3f (hit_com[i][0], hit_com[i][1], hit_com[i][2]); + } + glColor3f (1.0, 1.0, 1.0); + glBegin (GL_LINES); + btScalar normal_scale = 10.0; // easier to see if this is big + for (i = 0; i < NUMRAYS_IN_BAR; i++) + { + glVertex3f (hit_surface[i][0], hit_surface[i][1], hit_surface[i][2]); + glVertex3f (hit_surface[i][0] + normal_scale * normal[i][0], hit_surface[i][1] + normal_scale * normal[i][1], hit_surface[i][2] + normal_scale * normal[i][2]); + } + glEnd (); + glColor3f (0.0, 1.0, 1.0); + btQuaternion qFrom; + btQuaternion qTo; + qFrom.setRotation (btVector3(1.0, 0.0, 0.0), 0.0); + qTo.setRotation (btVector3(1.0, 0.0, 0.0), 0.7); + for ( i = 0; i < NUMRAYS_IN_BAR; i++) + { + btTransform from(qFrom, source[i]); + btTransform to(qTo, dest[i]); + btVector3 linVel, angVel; + btTransformUtil::calculateVelocity (from, to, 1.0, linVel, angVel); + btTransform T; + btTransformUtil::integrateTransform (from, linVel, angVel, hit_fraction[i], T); + drawCube (T); + } + glEnable (GL_LIGHTING); + } +}; + + +static btConvexcastBatch convexcastBatch; + + + + + +const int NUM_VERTS_X = 30; +const int NUM_VERTS_Y = 30; +const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + +void ConcaveConvexcastDemo::setVertexPositions(float waveheight, float offset) +{ + int i; + int j; + + for ( i=0;isetCollisionFlags( staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->setActivationState(DISABLE_DEACTIVATION); + } else + { + staticBody->setCollisionFlags( staticBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->forceActivationState(ACTIVE_TAG); + } + } + + DemoApplication::keyboardCallback(key,x,y); + +} + +void ConcaveConvexcastDemo::initPhysics() +{ + #define TRISIZE 10.f + + setCameraDistance(100.f); + + + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + + + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + + gVertices = new btVector3[totalVerts]; + gIndices = new int[totalTriangles*3]; + + int i; + + + setVertexPositions(waveheight,0.f); + + int index=0; + for ( i=0;isetCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); + + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + convexcastBatch = btConvexcastBatch (40.0, 0.0, -10.0,80.0); + //convexcastBatch = btConvexcastBatch (true, 40.0, -50.0, 50.0); +} + +void ConcaveConvexcastDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_animatedMesh) + { + static float offset=0.f; + offset+=0.01f; + + + + int i; + int j; + btVector3 aabbMin(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + btVector3 aabbMax(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + + for ( i=NUM_VERTS_X/2-3;ipartialRefitTree(aabbMin,aabbMax); + + + //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + } + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + convexcastBatch.move (dt); + convexcastBatch.cast (m_dynamicsWorld); + renderme(); + convexcastBatch.draw (); + glFlush(); + glutSwapBuffers(); + +} + + + + +void ConcaveConvexcastDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + convexcastBatch.draw (); + glFlush(); + glutSwapBuffers(); +} + + + +void ConcaveConvexcastDemo::exitPhysics() +{ + + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btTriangleIndexVertexArray* m_indexVertexArrays; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + bool m_animatedMesh; + + public: + + ConcaveConvexcastDemo() : m_animatedMesh(true) + { + + } + void initPhysics(); + + void exitPhysics(); + + virtual ~ConcaveConvexcastDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + //to show refit works + void setVertexPositions(float waveheight, float offset); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + ConcaveConvexcastDemo* demo = new ConcaveConvexcastDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + }; +}; + +#endif //CONCAVE_CONVEXCAST_DEMO_H + diff --git a/Demos/ConcaveConvexcastDemo/main.cpp b/Demos/ConcaveConvexcastDemo/main.cpp new file mode 100644 index 0000000..6f405b6 --- /dev/null +++ b/Demos/ConcaveConvexcastDemo/main.cpp @@ -0,0 +1,15 @@ + +#include "ConcaveConvexcastDemo.h" +#include "GlutStuff.h" + + +int main(int argc,char** argv) +{ + + ConcaveConvexcastDemo* concaveConvexcastDemo = new ConcaveConvexcastDemo(); + concaveConvexcastDemo->initPhysics(); + concaveConvexcastDemo->setCameraDistance(30.f); + + return glutmain(argc, argv,640,480,"Concave Convexcast Demo",concaveConvexcastDemo); +} + diff --git a/Demos/ConcaveDemo/CMakeLists.txt b/Demos/ConcaveDemo/CMakeLists.txt new file mode 100644 index 0000000..a269bbd --- /dev/null +++ b/Demos/ConcaveDemo/CMakeLists.txt @@ -0,0 +1,80 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + + +# You shouldn't have to modify anything below this line +######################################################## + +IF (USE_GLUT) + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter + ) + + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppConcaveDemo + ConcavePhysicsDemo.cpp + main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppConcaveDemo + ConcavePhysicsDemo.cpp + main.cpp + ) + ENDIF() + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConcaveDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConcaveDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) +ELSE (USE_GLUT) + + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter + ) + + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppConcaveDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + ConcavePhysicsDemo.cpp + ConcaveDemo.h + Win32ConcaveDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppConcaveDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppConcaveDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppConcaveDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ConcaveDemo/ConcaveDemo.h b/Demos/ConcaveDemo/ConcaveDemo.h new file mode 100644 index 0000000..86144c7 --- /dev/null +++ b/Demos/ConcaveDemo/ConcaveDemo.h @@ -0,0 +1,91 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONCAVE_DEMO_H +#define CONCAVE_DEMO_H + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +#include "LinearMath/btAlignedObjectArray.h" + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; +class btTriangleIndexVertexArray; + +///ConcaveDemo shows usage of static concave triangle meshes +///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback +class ConcaveDemo : public PlatformDemoApplication +{ + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btTriangleIndexVertexArray* m_indexVertexArrays; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + bool m_animatedMesh; + + public: + + ConcaveDemo() : m_animatedMesh(true) + { + + } + void initPhysics(); + + void exitPhysics(); + + virtual ~ConcaveDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + //to show refit works + void setVertexPositions(float waveheight, float offset); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + ConcaveDemo* demo = new ConcaveDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + }; +}; + +#endif //CONCAVE_DEMO_H + diff --git a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp new file mode 100644 index 0000000..e261662 --- /dev/null +++ b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp @@ -0,0 +1,474 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" +#include "GLDebugDrawer.h" +#include "ConcaveDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +#define SERIALIZE_TO_DISK 1 + +#ifndef SERIALIZE_TO_DISK +#include "btBulletWorldImporter.h" +#endif //SERIALIZE_TO_DISK + +//by default, the sample only (de)serializes the BVH to disk. +//If you enable the SERIALIZE_SHAPE define then it will serialize the entire collision shape +//then the animation will not play, because it is using the deserialized vertices +//#define SERIALIZE_SHAPE + + + + +//#define USE_PARALLEL_DISPATCHER 1 +#ifdef USE_PARALLEL_DISPATCHER +#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#include "../../Extras/BulletMultiThreaded/Win32ThreadSupport.h" +#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#endif//USE_PARALLEL_DISPATCHER + + + + +static btVector3* gVertices=0; +static int* gIndices=0; +static btBvhTriangleMeshShape* trimeshShape =0; +static btRigidBody* staticBody = 0; +static float waveheight = 5.f; + +const float TRIANGLE_SIZE=8.f; + + + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(float friction0,float friction1) +{ + btScalar friction = friction0 * friction1; + + const btScalar MAX_FRICTION = 10.f; + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(float restitution0,float restitution1) +{ + return restitution0 * restitution1; +} + + + +static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) +{ + + float friction0 = colObj0Wrap->getCollisionObject()->getFriction(); + float friction1 = colObj1Wrap->getCollisionObject()->getFriction(); + float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution(); + float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution(); + + if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + friction0 = 1.0;//partId0,index0 + restitution0 = 0.f; + } + if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + if (index1&1) + { + friction1 = 1.0f;//partId1,index1 + } else + { + friction1 = 0.f; + } + restitution1 = 0.f; + } + + cp.m_combinedFriction = calculateCombinedFriction(friction0,friction1); + cp.m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); + + //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction + return true; +} + +extern ContactAddedCallback gContactAddedCallback; + + const int NUM_VERTS_X = 30; + const int NUM_VERTS_Y = 30; + const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + +void ConcaveDemo::setVertexPositions(float waveheight, float offset) +{ + int i; + int j; + + for ( i=0;isetCollisionFlags( staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->setActivationState(DISABLE_DEACTIVATION); + } else + { + staticBody->setCollisionFlags( staticBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->forceActivationState(ACTIVE_TAG); + } + } + + DemoApplication::keyboardCallback(key,x,y); + +} + +void ConcaveDemo::initPhysics() +{ + + setTexturing(true); + setShadows(false);//true); + + #define TRISIZE 10.f + + gContactAddedCallback = CustomMaterialCombinerCallback; + +#define USE_TRIMESH_SHAPE 1 +#ifdef USE_TRIMESH_SHAPE + + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + + + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + + gVertices = new btVector3[totalVerts]; + gIndices = new int[totalTriangles*3]; + + int i; + + + setVertexPositions(waveheight,0.f); + + int index=0; + for ( i=0;isetSerializationFlags(BT_SERIALIZE_NO_BVH);// or BT_SERIALIZE_NO_TRIANGLEINFOMAP + serializer->startSerialization(); + //registering a name is optional, it allows you to retrieve the shape by name + //serializer->registerNameForPointer(trimeshShape,"mymesh"); +#ifdef SERIALIZE_SHAPE + trimeshShape->serializeSingleShape(serializer); +#else + trimeshShape->serializeSingleBvh(serializer); +#endif + serializer->finishSerialization(); + FILE* f2 = fopen("myShape.bullet","wb"); + fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); + fclose(f2); + +#else + btBulletWorldImporter import(0);//don't store info into the world + if (import.loadFile("myShape.bullet")) + { + int numBvh = import.getNumBvhs(); + if (numBvh) + { + btOptimizedBvh* bvh = import.getBvhByIndex(0); + btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000); + + trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax,false); + trimeshShape->setOptimizedBvh(bvh); + //trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax); + //trimeshShape->setOptimizedBvh(bvh); + + } + int numShape = import.getNumCollisionShapes(); + if (numShape) + { + trimeshShape = (btBvhTriangleMeshShape*)import.getCollisionShapeByIndex(0); + + //if you know the name, you can also try to get the shape by name: + const char* meshName = import.getNameForPointer(trimeshShape); + if (meshName) + trimeshShape = (btBvhTriangleMeshShape*)import.getCollisionShapeByName(meshName); + + } + } + + +#endif + + btCollisionShape* groundShape = trimeshShape; + +#else + btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); + m_collisionShapes.push_back(groundShape); + +#endif //USE_TRIMESH_SHAPE + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + +#ifdef USE_PARALLEL_DISPATCHER + +#ifdef USE_WIN32_THREADING + + int maxNumOutstandingTasks = 4;//number of maximum outstanding tasks + Win32ThreadSupport* threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( + "collision", + processCollisionTask, + createCollisionLocalStoreMemory, + maxNumOutstandingTasks)); +#else +///@todo show other platform threading +///Playstation 3 SPU (SPURS) version is available through PS3 Devnet +///Libspe2 SPU support will be available soon +///pthreads version +///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface +#endif + + m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,m_collisionConfiguration); +#else + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#endif//USE_PARALLEL_DISPATCHER + + + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + m_broadphase = new btAxisSweep3(worldMin,worldMax); + m_solver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); +#ifdef USE_PARALLEL_DISPATCHER + m_dynamicsWorld->getDispatchInfo().m_enableSPU=true; +#endif //USE_PARALLEL_DISPATCHER + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-2,0)); + +#ifdef USE_BOX_SHAPE + btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); +#else + + btCompoundShape* colShape = new btCompoundShape; + btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(4,1,1)); + btCollisionShape* boxShape = new btBoxShape(btVector3(4,1,1)); + btTransform localTransform; + localTransform.setIdentity(); + colShape->addChildShape(localTransform,boxShape); + btQuaternion orn(SIMD_HALF_PI,0,0); + localTransform.setRotation(orn); + colShape->addChildShape(localTransform,cylinderShape); + +#endif //USE_BOX_SHAPE + + + m_collisionShapes.push_back(colShape); + + { + for (int i=0;i<10;i++) + { + startTransform.setOrigin(btVector3(2,10+i*2,1)); + localCreateRigidBody(1, startTransform,colShape); + } + } + + startTransform.setIdentity(); + staticBody = localCreateRigidBody(mass, startTransform,groundShape); + + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);//STATIC_OBJECT); + + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + + + +} + +void ConcaveDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_animatedMesh) + { + static float offset=0.f; + offset+=dt; + + // setVertexPositions(waveheight,offset); + + int i; + int j; + btVector3 aabbMin(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + btVector3 aabbMax(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + + for ( i=NUM_VERTS_X/2-3;ipartialRefitTree(aabbMin,aabbMax); + + //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + } + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + + renderme(); + + glFlush(); + swapBuffers(); + +} + + + + +void ConcaveDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + + glFlush(); + swapBuffers(); +} + + + +void ConcaveDemo::exitPhysics() +{ + + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jinitPhysics(); + concaveDemo->setCameraDistance(30.f); + concaveDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + return glutmain(argc, argv,640,480,"Static Concave Mesh Demo",concaveDemo); +} + diff --git a/Demos/ConcaveRaycastDemo/CMakeLists.txt b/Demos/ConcaveRaycastDemo/CMakeLists.txt new file mode 100644 index 0000000..ae1a458 --- /dev/null +++ b/Demos/ConcaveRaycastDemo/CMakeLists.txt @@ -0,0 +1,57 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +IF (WIN32) + ADD_EXECUTABLE(AppConcaveRayCastDemo + ConcaveRaycastDemo.cpp + main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppConcaveRayCastDemo + ConcaveRaycastDemo.cpp + main.cpp + ) +ENDIF() + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConcaveRayCastDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConcaveRayCastDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppConcaveRayCastDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppConcaveRayCastDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppConcaveRayCastDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp b/Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp new file mode 100644 index 0000000..25242b7 --- /dev/null +++ b/Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp @@ -0,0 +1,490 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" +#include "GLDebugDrawer.h" +#include "ConcaveRaycastDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +static GLDebugDrawer sDebugDraw; + +static btVector3* gVertices=0; +static int* gIndices=0; +static btBvhTriangleMeshShape* trimeshShape =0; +static btRigidBody* staticBody = 0; +static float waveheight = 5.f; + +const float TRIANGLE_SIZE=8.f; + + +/* Scrolls back and forth over terrain */ +#define NUMRAYS_IN_BAR 100 +class btRaycastBar +{ +public: + btVector3 source[NUMRAYS_IN_BAR]; + btVector3 dest[NUMRAYS_IN_BAR]; + btVector3 direction[NUMRAYS_IN_BAR]; + btVector3 hit[NUMRAYS_IN_BAR]; + btVector3 normal[NUMRAYS_IN_BAR]; + + int frame_counter; + int ms; + int sum_ms; + int sum_ms_samples; + int min_ms; + int max_ms; + +#ifdef USE_BT_CLOCK + btClock frame_timer; +#endif //USE_BT_CLOCK + + btScalar dx; + btScalar min_x; + btScalar max_x; + btScalar min_y; + btScalar max_y; + btScalar sign; + + btRaycastBar () + { + ms = 0; + max_ms = 0; + min_ms = 9999.0; + sum_ms_samples = 0; + sum_ms = 0; + } + + btRaycastBar (bool unused, btScalar ray_length, btScalar min_z, btScalar max_z, btScalar min_y = -10, btScalar max_y = 10) + { + frame_counter = 0; + ms = 0; + max_ms = 0; + min_ms = 9999.0; + sum_ms_samples = 0; + sum_ms = 0; + dx = 10.0; + min_x = -40; + max_x = 20; + this->min_y = min_y; + this->max_y = max_y; + sign = 1.0; + // btScalar dalpha = 2*SIMD_2_PI/NUMRAYS_IN_BAR; + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + btScalar z = (max_z-min_z)/btScalar(NUMRAYS_IN_BAR) * btScalar(i) + min_z; + source[i] = btVector3(min_x, max_y, z); + dest[i] = btVector3(min_x + ray_length, min_y, z); + normal[i] = btVector3(1.0, 0.0, 0.0); + } + } + + btRaycastBar (btScalar ray_length, btScalar z, btScalar min_y = -1000, btScalar max_y = 10) + { + frame_counter = 0; + ms = 0; + max_ms = 0; + min_ms = 9999.0; + sum_ms_samples = 0; + sum_ms = 0; + dx = 10.0; + min_x = -40; + max_x = 20; + this->min_y = min_y; + this->max_y = max_y; + sign = 1.0; + btScalar dalpha = 2*SIMD_2_PI/NUMRAYS_IN_BAR; + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + btScalar alpha = dalpha * i; + // rotate around by alpha degrees y + btTransform tr (btQuaternion (btVector3(0.0, 1.0, 0.0), alpha)); + direction[i] = btVector3(1.0, 0.0, 0.0); + direction[i] = tr* direction[i]; + direction[i] = direction[i] * ray_length; + source[i] = btVector3(min_x, max_y, z); + dest[i] = source[i] + direction[i]; + dest[i][1] = min_y; + normal[i] = btVector3(1.0, 0.0, 0.0); + } + } + + void move (btScalar dt) + { + if (dt > (1.0/60.0)) + dt = 1.0/60.0; + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + source[i][0] += dx * dt * sign; + dest[i][0] += dx * dt * sign; + } + if (source[0][0] < min_x) + sign = 1.0; + else if (source[0][0] > max_x) + sign = -1.0; + } + + void cast (btCollisionWorld* cw) + { +#ifdef USE_BT_CLOCK + frame_timer.reset (); +#endif //USE_BT_CLOCK + +#ifdef BATCH_RAYCASTER + if (!gBatchRaycaster) + return; + + gBatchRaycaster->clearRays (); + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + gBatchRaycaster->addRay (source[i], dest[i]); + } + gBatchRaycaster->performBatchRaycast (); + for (int i = 0; i < gBatchRaycaster->getNumRays (); i++) + { + const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i]; + hit[i].setInterpolate3(source[i],dest[i],out.hitFraction); + normal[i] = out.hitNormal; + normal[i].normalize (); + } +#else + for (int i = 0; i < NUMRAYS_IN_BAR; i++) + { + btCollisionWorld::ClosestRayResultCallback cb(source[i], dest[i]); + + cw->rayTest (source[i], dest[i], cb); + if (cb.hasHit ()) + { + hit[i] = cb.m_hitPointWorld; + normal[i] = cb.m_hitNormalWorld; + normal[i].normalize (); + } else { + hit[i] = dest[i]; + normal[i] = btVector3(1.0, 0.0, 0.0); + } + + } +#ifdef USE_BT_CLOCK + ms += frame_timer.getTimeMilliseconds (); +#endif //USE_BT_CLOCK + frame_counter++; + if (frame_counter > 50) + { + min_ms = ms < min_ms ? ms : min_ms; + max_ms = ms > max_ms ? ms : max_ms; + sum_ms += ms; + sum_ms_samples++; + btScalar mean_ms = (btScalar)sum_ms/(btScalar)sum_ms_samples; + printf("%d rays in %d ms %d %d %f\n", NUMRAYS_IN_BAR * frame_counter, ms, min_ms, max_ms, mean_ms); + ms = 0; + frame_counter = 0; + } +#endif + } + + void draw () + { + glDisable (GL_LIGHTING); + glColor3f (0.0, 1.0, 0.0); + glBegin (GL_LINES); + int i; + + for (i = 0; i < NUMRAYS_IN_BAR; i++) + { + glVertex3f (source[i][0], source[i][1], source[i][2]); + glVertex3f (hit[i][0], hit[i][1], hit[i][2]); + } + glEnd (); + glColor3f (1.0, 1.0, 1.0); + glBegin (GL_LINES); + for (i = 0; i < NUMRAYS_IN_BAR; i++) + { + glVertex3f (hit[i][0], hit[i][1], hit[i][2]); + glVertex3f (hit[i][0] + normal[i][0], hit[i][1] + normal[i][1], hit[i][2] + normal[i][2]); + } + glEnd (); + glColor3f (0.0, 1.0, 1.0); + glBegin (GL_POINTS); + for ( i = 0; i < NUMRAYS_IN_BAR; i++) + { + glVertex3f (hit[i][0], hit[i][1], hit[i][2]); + } + glEnd (); + glEnable (GL_LIGHTING); + } +}; + + +static btRaycastBar raycastBar; + + +const int NUM_VERTS_X = 30; +const int NUM_VERTS_Y = 30; +const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + +void ConcaveRaycastDemo::setVertexPositions(float waveheight, float offset) +{ + int i; + int j; + + for ( i=0;isetCollisionFlags( staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->setActivationState(DISABLE_DEACTIVATION); + } else + { + staticBody->setCollisionFlags( staticBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->forceActivationState(ACTIVE_TAG); + } + } + + DemoApplication::keyboardCallback(key,x,y); + +} + +void ConcaveRaycastDemo::initPhysics() +{ + + #define TRISIZE 10.f + + + + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + + + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + + gVertices = new btVector3[totalVerts]; + gIndices = new int[totalTriangles*3]; + + int i; + + + setVertexPositions(waveheight,0.f); + + int index=0; + for ( i=0;igetSolverInfo().m_splitImpulse=true; + m_dynamicsWorld->setDebugDrawer(&sDebugDraw); + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-2,0)); + + btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); + m_collisionShapes.push_back(colShape); + + { + for (int i=0;i<10;i++) + { + //btCollisionShape* colShape = new btCapsuleShape(0.5,2.0);//boxShape = new btSphereShape(1.f); + startTransform.setOrigin(btVector3(2*i,10,1)); + localCreateRigidBody(1, startTransform,colShape); + } + } + + startTransform.setIdentity(); + staticBody = localCreateRigidBody(mass, startTransform,groundShape); + + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); + +#ifdef BATCH_RAYCASTER +int maxNumOutstandingTasks = 4; + +#ifdef USE_WIN32_THREADING + Win32ThreadSupport::Win32ThreadConstructionInfo tci("batch raycast", + processRaycastTask, + createRaycastLocalStoreMemory, + maxNumOutstandingTasks); + m_threadSupportRaycast = new Win32ThreadSupport(tci); + printf("m_threadSupportRaycast = %p\n", m_threadSupportRaycast); +#endif + + gBatchRaycaster = new SpuBatchRaycaster (m_threadSupportRaycast, maxNumOutstandingTasks, m_dynamicsWorld->getCollisionObjectArray(), m_dynamicsWorld->getNumCollisionObjects()); +#endif + + raycastBar = btRaycastBar (4000.0, 0.0); + //raycastBar = btRaycastBar (true, 40.0, -50.0, 50.0); + + + + + +} + +void ConcaveRaycastDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_animatedMesh) + { + static float offset=0.f; + offset+=0.01f; + + setVertexPositions(waveheight,offset); + + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + + trimeshShape->refitTree(worldMin,worldMax); + + //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + } + + m_dynamicsWorld->stepSimulation(1./60.,0); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + raycastBar.move (dt); + raycastBar.cast (m_dynamicsWorld); + renderme(); + raycastBar.draw (); + glFlush(); + glutSwapBuffers(); + +} + + + + +void ConcaveRaycastDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + raycastBar.draw (); + glFlush(); + glutSwapBuffers(); +} + + + +void ConcaveRaycastDemo::exitPhysics() +{ + + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btTriangleIndexVertexArray* m_indexVertexArrays; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + class btThreadSupportInterface* m_threadSupportRaycast; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + bool m_animatedMesh; + + public: + + ConcaveRaycastDemo() : m_animatedMesh(false) + { + + } + void initPhysics(); + + void exitPhysics(); + + virtual ~ConcaveRaycastDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + //to show refit works + void setVertexPositions(float waveheight, float offset); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + ConcaveRaycastDemo* demo = new ConcaveRaycastDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + }; +}; + +#endif //CONCAVE_RAYCAST_DEMO_H + diff --git a/Demos/ConcaveRaycastDemo/main.cpp b/Demos/ConcaveRaycastDemo/main.cpp new file mode 100644 index 0000000..03fe36f --- /dev/null +++ b/Demos/ConcaveRaycastDemo/main.cpp @@ -0,0 +1,15 @@ + +#include "ConcaveRaycastDemo.h" +#include "GlutStuff.h" + + +int main(int argc,char** argv) +{ + + ConcaveRaycastDemo* concaveRaycastDemo = new ConcaveRaycastDemo(); + concaveRaycastDemo->initPhysics(); + concaveRaycastDemo->setCameraDistance(30.f); + + return glutmain(argc, argv,640,480,"Concave Raycast Demo",concaveRaycastDemo); +} + diff --git a/Demos/ConstraintDemo/CMakeLists.txt b/Demos/ConstraintDemo/CMakeLists.txt new file mode 100644 index 0000000..8357694 --- /dev/null +++ b/Demos/ConstraintDemo/CMakeLists.txt @@ -0,0 +1,71 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppConstraintDemo + ConstraintDemo.cpp + ConstraintDemo.h + main.cpp + ) + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConstraintDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConstraintDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}/Debug + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) +ELSE (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppConstraintDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32ConstraintDemo.cpp + ConstraintDemo.cpp + ConstraintDemo.h + ) +ENDIF (USE_GLUT) + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppConstraintDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppConstraintDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppConstraintDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ConstraintDemo/ConstraintDemo.cpp b/Demos/ConstraintDemo/ConstraintDemo.cpp new file mode 100644 index 0000000..74ee927 --- /dev/null +++ b/Demos/ConstraintDemo/ConstraintDemo.cpp @@ -0,0 +1,820 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" + +#include "GLDebugDrawer.h" + +#include "GLDebugFont.h" +#include //printf debugging + +#include "ConstraintDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +#include "GLDebugDrawer.h" +static GLDebugDrawer gDebugDrawer; + + + +const int numObjects = 3; + +#define ENABLE_ALL_DEMOS 1 + +#define CUBE_HALF_EXTENTS 1.f + +#define SIMD_PI_2 ((SIMD_PI)*0.5f) +#define SIMD_PI_4 ((SIMD_PI)*0.25f) + + + + +btTransform sliderTransform; +btVector3 lowerSliderLimit = btVector3(-10,0,0); +btVector3 hiSliderLimit = btVector3(10,0,0); + +btRigidBody* d6body0 =0; + +btHingeConstraint* spDoorHinge = NULL; +btHingeConstraint* spHingeDynAB = NULL; +btGeneric6DofConstraint* spSlider6Dof = NULL; + +static bool s_bTestConeTwistMotor = false; + + + +void drawLimit() +{ + btVector3 from = sliderTransform*lowerSliderLimit; + btVector3 to = sliderTransform*hiSliderLimit; + btVector3 color(255,0,0); + glBegin(GL_LINES); + glColor3f(color.getX(), color.getY(), color.getZ()); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + if (d6body0) + { + from = d6body0->getWorldTransform().getOrigin(); + to = from + d6body0->getWorldTransform().getBasis() * btVector3(0,0,10); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + } + glEnd(); +} + + +void ConstraintDemo::setupEmptyDynamicsWorld() +{ + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_overlappingPairCache = new btDbvtBroadphase(); + m_constraintSolver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); + +} + +void ConstraintDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} +void ConstraintDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + setCameraDistance(26.f); + m_Time = 0; + + setupEmptyDynamicsWorld(); + + m_dynamicsWorld->setDebugDrawer(&gDebugDrawer); + + + //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(40.),btScalar(50.))); + btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),40); + + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-56,0)); + btRigidBody* groundBody; + groundBody= localCreateRigidBody(0, groundTransform, groundShape); + + + + btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); + m_collisionShapes.push_back(shape); + btTransform trans; + trans.setIdentity(); + trans.setOrigin(btVector3(0,20,0)); + + float mass = 1.f; + +#if ENABLE_ALL_DEMOS +///gear constraint demo + +#define THETA SIMD_PI/4.f +#define L_1 (2 - tan(THETA)) +#define L_2 (1 / cos(THETA)) +#define RATIO L_2 / L_1 + + btRigidBody* bodyA=0; + btRigidBody* bodyB=0; + + { + btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.25,0.2)); + btCollisionShape* cylB = new btCylinderShape(btVector3(L_1,0.025,L_1)); + btCompoundShape* cyl0 = new btCompoundShape(); + cyl0->addChildShape(btTransform::getIdentity(),cylA); + cyl0->addChildShape(btTransform::getIdentity(),cylB); + + btScalar mass = 6.28; + btVector3 localInertia; + cyl0->calculateLocalInertia(mass,localInertia); + btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia); + ci.m_startWorldTransform.setOrigin(btVector3(-8,1,-8)); + + btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia); + m_dynamicsWorld->addRigidBody(body); + body->setLinearFactor(btVector3(0,0,0)); + body->setAngularFactor(btVector3(0,1,0)); + bodyA = body; + } + + { + btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.26,0.2)); + btCollisionShape* cylB = new btCylinderShape(btVector3(L_2,0.025,L_2)); + btCompoundShape* cyl0 = new btCompoundShape(); + cyl0->addChildShape(btTransform::getIdentity(),cylA); + cyl0->addChildShape(btTransform::getIdentity(),cylB); + + btScalar mass = 6.28; + btVector3 localInertia; + cyl0->calculateLocalInertia(mass,localInertia); + btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia); + ci.m_startWorldTransform.setOrigin(btVector3(-10,2,-8)); + + + btQuaternion orn(btVector3(0,0,1),-THETA); + ci.m_startWorldTransform.setRotation(orn); + + btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia); + body->setLinearFactor(btVector3(0,0,0)); + btHingeConstraint* hinge = new btHingeConstraint(*body,btVector3(0,0,0),btVector3(0,1,0),true); + m_dynamicsWorld->addConstraint(hinge); + bodyB= body; + body->setAngularVelocity(btVector3(0,3,0)); + + m_dynamicsWorld->addRigidBody(body); + } + + btVector3 axisA(0,1,0); + btVector3 axisB(0,1,0); + btQuaternion orn(btVector3(0,0,1),-THETA); + btMatrix3x3 mat(orn); + axisB = mat.getRow(1); + + btGearConstraint* gear = new btGearConstraint(*bodyA,*bodyB, axisA,axisB,RATIO); + m_dynamicsWorld->addConstraint(gear,true); + + +#endif + + +#if ENABLE_ALL_DEMOS + //point to point constraint with a breaking threshold + { + trans.setIdentity(); + trans.setOrigin(btVector3(1,30,-5)); + localCreateRigidBody( mass,trans,shape); + trans.setOrigin(btVector3(0,0,-5)); + + btRigidBody* body0 = localCreateRigidBody( mass,trans,shape); + trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0)); + mass = 1.f; + // btRigidBody* body1 = 0;//localCreateRigidBody( mass,trans,shape); + btVector3 pivotInA(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,0); + btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA); + m_dynamicsWorld->addConstraint(p2p); + p2p ->setBreakingImpulseThreshold(10.2); + p2p->setDbgDrawSize(btScalar(5.f)); + } +#endif + + + +#if ENABLE_ALL_DEMOS + //point to point constraint (ball socket) + { + btRigidBody* body0 = localCreateRigidBody( mass,trans,shape); + trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0)); + + mass = 1.f; +// btRigidBody* body1 = 0;//localCreateRigidBody( mass,trans,shape); +// btRigidBody* body1 = localCreateRigidBody( 0.0,trans,0); + //body1->setActivationState(DISABLE_DEACTIVATION); + //body1->setDamping(0.3,0.3); + + btVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS); + btVector3 axisInA(0,0,1); + + // btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA; +// btVector3 axisInB = body1? +// (body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) : + body0->getCenterOfMassTransform().getBasis() * axisInA; + +#define P2P +#ifdef P2P + btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA); + //btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB); + //btTypedConstraint* hinge = new btHingeConstraint(*body0,*body1,pivotInA,pivotInB,axisInA,axisInB); + m_dynamicsWorld->addConstraint(p2p); + p2p->setDbgDrawSize(btScalar(5.f)); +#else + btHingeConstraint* hinge = new btHingeConstraint(*body0,pivotInA,axisInA); + + //use zero targetVelocity and a small maxMotorImpulse to simulate joint friction + //float targetVelocity = 0.f; + //float maxMotorImpulse = 0.01; + float targetVelocity = 1.f; + float maxMotorImpulse = 1.0f; + hinge->enableAngularMotor(true,targetVelocity,maxMotorImpulse); + m_dynamicsWorld->addConstraint(hinge); + hinge->setDbgDrawSize(btScalar(5.f)); +#endif //P2P + + + + + } +#endif + +#if ENABLE_ALL_DEMOS + //create a slider, using the generic D6 constraint + { + mass = 1.f; + btVector3 sliderWorldPos(0,10,0); + btVector3 sliderAxis(1,0,0); + btScalar angle=0.f;//SIMD_RADS_PER_DEG * 10.f; + btMatrix3x3 sliderOrientation(btQuaternion(sliderAxis ,angle)); + trans.setIdentity(); + trans.setOrigin(sliderWorldPos); + //trans.setBasis(sliderOrientation); + sliderTransform = trans; + + d6body0 = localCreateRigidBody( mass,trans,shape); + d6body0->setActivationState(DISABLE_DEACTIVATION); + btRigidBody* fixedBody1 = localCreateRigidBody(0,trans,0); + m_dynamicsWorld->addRigidBody(fixedBody1); + + btTransform frameInA, frameInB; + frameInA = btTransform::getIdentity(); + frameInB = btTransform::getIdentity(); + frameInA.setOrigin(btVector3(0., 5., 0.)); + frameInB.setOrigin(btVector3(0., 5., 0.)); + +// bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits + bool useLinearReferenceFrameA = true;//use fixed frame A for linear llimits + spSlider6Dof = new btGeneric6DofConstraint(*fixedBody1, *d6body0,frameInA,frameInB,useLinearReferenceFrameA); + spSlider6Dof->setLinearLowerLimit(lowerSliderLimit); + spSlider6Dof->setLinearUpperLimit(hiSliderLimit); + + //range should be small, otherwise singularities will 'explode' the constraint +// spSlider6Dof->setAngularLowerLimit(btVector3(-1.5,0,0)); +// spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0)); +// spSlider6Dof->setAngularLowerLimit(btVector3(0,0,0)); +// spSlider6Dof->setAngularUpperLimit(btVector3(0,0,0)); + spSlider6Dof->setAngularLowerLimit(btVector3(-SIMD_PI,0,0)); + spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0)); + + spSlider6Dof->getTranslationalLimitMotor()->m_enableMotor[0] = true; + spSlider6Dof->getTranslationalLimitMotor()->m_targetVelocity[0] = -5.0f; + spSlider6Dof->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f; + + + m_dynamicsWorld->addConstraint(spSlider6Dof); + spSlider6Dof->setDbgDrawSize(btScalar(5.f)); + + } +#endif +#if ENABLE_ALL_DEMOS + { // create a door using hinge constraint attached to the world + btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f)); + m_collisionShapes.push_back(pDoorShape); + btTransform doorTrans; + doorTrans.setIdentity(); + doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f)); + btRigidBody* pDoorBody = localCreateRigidBody( 1.0, doorTrans, pDoorShape); + pDoorBody->setActivationState(DISABLE_DEACTIVATION); + const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside + btVector3 btAxisA( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis + + spDoorHinge = new btHingeConstraint( *pDoorBody, btPivotA, btAxisA ); + +// spDoorHinge->setLimit( 0.0f, SIMD_PI_2 ); + // test problem values +// spDoorHinge->setLimit( -SIMD_PI, SIMD_PI*0.8f); + +// spDoorHinge->setLimit( 1.f, -1.f); +// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI); +// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.3f, 0.0f); +// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.01f, 0.0f); // "sticky limits" + spDoorHinge->setLimit( -SIMD_PI * 0.25f, SIMD_PI * 0.25f ); +// spDoorHinge->setLimit( 0.0f, 0.0f ); + m_dynamicsWorld->addConstraint(spDoorHinge); + spDoorHinge->setDbgDrawSize(btScalar(5.f)); + + //doorTrans.setOrigin(btVector3(-5.0f, 2.0f, 0.0f)); + //btRigidBody* pDropBody = localCreateRigidBody( 10.0, doorTrans, shape); + } +#endif +#if ENABLE_ALL_DEMOS + { // create a generic 6DOF constraint + + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(10.), btScalar(6.), btScalar(0.))); + tr.getBasis().setEulerZYX(0,0,0); +// btRigidBody* pBodyA = localCreateRigidBody( mass, tr, shape); + btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape); +// btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, 0); + pBodyA->setActivationState(DISABLE_DEACTIVATION); + + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(0.), btScalar(6.), btScalar(0.))); + tr.getBasis().setEulerZYX(0,0,0); + btRigidBody* pBodyB = localCreateRigidBody(mass, tr, shape); +// btRigidBody* pBodyB = localCreateRigidBody(0.f, tr, shape); + pBodyB->setActivationState(DISABLE_DEACTIVATION); + + btTransform frameInA, frameInB; + frameInA = btTransform::getIdentity(); + frameInA.setOrigin(btVector3(btScalar(-5.), btScalar(0.), btScalar(0.))); + frameInB = btTransform::getIdentity(); + frameInB.setOrigin(btVector3(btScalar(5.), btScalar(0.), btScalar(0.))); + + btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true); +// btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false); + pGen6DOF->setLinearLowerLimit(btVector3(-10., -2., -1.)); + pGen6DOF->setLinearUpperLimit(btVector3(10., 2., 1.)); +// pGen6DOF->setLinearLowerLimit(btVector3(-10., 0., 0.)); +// pGen6DOF->setLinearUpperLimit(btVector3(10., 0., 0.)); +// pGen6DOF->setLinearLowerLimit(btVector3(0., 0., 0.)); +// pGen6DOF->setLinearUpperLimit(btVector3(0., 0., 0.)); + +// pGen6DOF->getTranslationalLimitMotor()->m_enableMotor[0] = true; +// pGen6DOF->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f; +// pGen6DOF->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f; + + +// pGen6DOF->setAngularLowerLimit(btVector3(0., SIMD_HALF_PI*0.9, 0.)); +// pGen6DOF->setAngularUpperLimit(btVector3(0., -SIMD_HALF_PI*0.9, 0.)); +// pGen6DOF->setAngularLowerLimit(btVector3(0., 0., -SIMD_HALF_PI)); +// pGen6DOF->setAngularUpperLimit(btVector3(0., 0., SIMD_HALF_PI)); + + pGen6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI * 0.5f, -0.75, -SIMD_HALF_PI * 0.8f)); + pGen6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI * 0.5f, 0.75, SIMD_HALF_PI * 0.8f)); +// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -0.75, SIMD_HALF_PI * 0.8f)); +// pGen6DOF->setAngularUpperLimit(btVector3(0.f, 0.75, -SIMD_HALF_PI * 0.8f)); +// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI * 0.8f, SIMD_HALF_PI * 1.98f)); +// pGen6DOF->setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI * 0.8f, -SIMD_HALF_PI * 1.98f)); + + + +// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,-0.5, -0.5)); +// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0.5, 0.5)); +// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,0., 0.)); +// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0., 0.)); +// pGen6DOF->setAngularLowerLimit(btVector3(0., -0.7,0.)); +// pGen6DOF->setAngularUpperLimit(btVector3(0., 0.7, 0.)); +// pGen6DOF->setAngularLowerLimit(btVector3(-1., 0.,0.)); +// pGen6DOF->setAngularUpperLimit(btVector3(1., 0., 0.)); + + m_dynamicsWorld->addConstraint(pGen6DOF, true); + pGen6DOF->setDbgDrawSize(btScalar(5.f)); + } +#endif +#if ENABLE_ALL_DEMOS + { // create a ConeTwist constraint + + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-10.), btScalar(5.), btScalar(0.))); + tr.getBasis().setEulerZYX(0,0,0); + btRigidBody* pBodyA = localCreateRigidBody( 1.0, tr, shape); +// btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape); + pBodyA->setActivationState(DISABLE_DEACTIVATION); + + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-10.), btScalar(-5.), btScalar(0.))); + tr.getBasis().setEulerZYX(0,0,0); + btRigidBody* pBodyB = localCreateRigidBody(0.0, tr, shape); +// btRigidBody* pBodyB = localCreateRigidBody(1.0, tr, shape); + + btTransform frameInA, frameInB; + frameInA = btTransform::getIdentity(); + frameInA.getBasis().setEulerZYX(0, 0, SIMD_PI_2); + frameInA.setOrigin(btVector3(btScalar(0.), btScalar(-5.), btScalar(0.))); + frameInB = btTransform::getIdentity(); + frameInB.getBasis().setEulerZYX(0,0, SIMD_PI_2); + frameInB.setOrigin(btVector3(btScalar(0.), btScalar(5.), btScalar(0.))); + + m_ctc = new btConeTwistConstraint(*pBodyA, *pBodyB, frameInA, frameInB); +// m_ctc->setLimit(btScalar(SIMD_PI_4), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f); +// m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 1.0f); // soft limit == hard limit + m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 0.5f); + m_dynamicsWorld->addConstraint(m_ctc, true); + m_ctc->setDbgDrawSize(btScalar(5.f)); + // s_bTestConeTwistMotor = true; // use only with old solver for now + s_bTestConeTwistMotor = false; + } +#endif +#if ENABLE_ALL_DEMOS + { // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver) + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(0.), btScalar(0.), btScalar(0.))); + btRigidBody* pBody = localCreateRigidBody( 1.0, tr, shape); + pBody->setActivationState(DISABLE_DEACTIVATION); + const btVector3 btPivotA( 10.0f, 0.0f, 0.0f ); + btVector3 btAxisA( 0.0f, 0.0f, 1.0f ); + + btHingeConstraint* pHinge = new btHingeConstraint( *pBody, btPivotA, btAxisA ); +// pHinge->enableAngularMotor(true, -1.0, 0.165); // use for the old solver + pHinge->enableAngularMotor(true, -1.0f, 1.65f); // use for the new SIMD solver + m_dynamicsWorld->addConstraint(pHinge); + pHinge->setDbgDrawSize(btScalar(5.f)); + } +#endif + +#if ENABLE_ALL_DEMOS + { + // create a universal joint using generic 6DOF constraint + // create two rigid bodies + // static bodyA (parent) on top: + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(20.), btScalar(4.), btScalar(0.))); + btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape); + pBodyA->setActivationState(DISABLE_DEACTIVATION); + // dynamic bodyB (child) below it : + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(20.), btScalar(0.), btScalar(0.))); + btRigidBody* pBodyB = localCreateRigidBody(1.0, tr, shape); + pBodyB->setActivationState(DISABLE_DEACTIVATION); + // add some (arbitrary) data to build constraint frames + btVector3 parentAxis(1.f, 0.f, 0.f); + btVector3 childAxis(0.f, 0.f, 1.f); + btVector3 anchor(20.f, 2.f, 0.f); + + btUniversalConstraint* pUniv = new btUniversalConstraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis); + pUniv->setLowerLimit(-SIMD_HALF_PI * 0.5f, -SIMD_HALF_PI * 0.5f); + pUniv->setUpperLimit(SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f); + // add constraint to world + m_dynamicsWorld->addConstraint(pUniv, true); + // draw constraint frames and limits for debugging + pUniv->setDbgDrawSize(btScalar(5.f)); + } +#endif + +#if ENABLE_ALL_DEMOS + { // create a generic 6DOF constraint with springs + + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-20.), btScalar(16.), btScalar(0.))); + tr.getBasis().setEulerZYX(0,0,0); + btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape); + pBodyA->setActivationState(DISABLE_DEACTIVATION); + + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-10.), btScalar(16.), btScalar(0.))); + tr.getBasis().setEulerZYX(0,0,0); + btRigidBody* pBodyB = localCreateRigidBody(1.0, tr, shape); + pBodyB->setActivationState(DISABLE_DEACTIVATION); + + btTransform frameInA, frameInB; + frameInA = btTransform::getIdentity(); + frameInA.setOrigin(btVector3(btScalar(10.), btScalar(0.), btScalar(0.))); + frameInB = btTransform::getIdentity(); + frameInB.setOrigin(btVector3(btScalar(0.), btScalar(0.), btScalar(0.))); + + btGeneric6DofSpringConstraint* pGen6DOFSpring = new btGeneric6DofSpringConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true); + pGen6DOFSpring->setLinearUpperLimit(btVector3(5., 0., 0.)); + pGen6DOFSpring->setLinearLowerLimit(btVector3(-5., 0., 0.)); + + pGen6DOFSpring->setAngularLowerLimit(btVector3(0.f, 0.f, -1.5f)); + pGen6DOFSpring->setAngularUpperLimit(btVector3(0.f, 0.f, 1.5f)); + + m_dynamicsWorld->addConstraint(pGen6DOFSpring, true); + pGen6DOFSpring->setDbgDrawSize(btScalar(5.f)); + + pGen6DOFSpring->enableSpring(0, true); + pGen6DOFSpring->setStiffness(0, 39.478f); + pGen6DOFSpring->setDamping(0, 0.5f); + pGen6DOFSpring->enableSpring(5, true); + pGen6DOFSpring->setStiffness(5, 39.478f); + pGen6DOFSpring->setDamping(0, 0.3f); + pGen6DOFSpring->setEquilibriumPoint(); + } +#endif +#if ENABLE_ALL_DEMOS + { + // create a Hinge2 joint + // create two rigid bodies + // static bodyA (parent) on top: + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-20.), btScalar(4.), btScalar(0.))); + btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape); + pBodyA->setActivationState(DISABLE_DEACTIVATION); + // dynamic bodyB (child) below it : + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-20.), btScalar(0.), btScalar(0.))); + btRigidBody* pBodyB = localCreateRigidBody(1.0, tr, shape); + pBodyB->setActivationState(DISABLE_DEACTIVATION); + // add some data to build constraint frames + btVector3 parentAxis(0.f, 1.f, 0.f); + btVector3 childAxis(1.f, 0.f, 0.f); + btVector3 anchor(-20.f, 0.f, 0.f); + btHinge2Constraint* pHinge2 = new btHinge2Constraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis); + pHinge2->setLowerLimit(-SIMD_HALF_PI * 0.5f); + pHinge2->setUpperLimit( SIMD_HALF_PI * 0.5f); + // add constraint to world + m_dynamicsWorld->addConstraint(pHinge2, true); + // draw constraint frames and limits for debugging + pHinge2->setDbgDrawSize(btScalar(5.f)); + } +#endif +#if ENABLE_ALL_DEMOS + { + // create a Hinge joint between two dynamic bodies + // create two rigid bodies + // static bodyA (parent) on top: + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-20.), btScalar(-2.), btScalar(0.))); + btRigidBody* pBodyA = localCreateRigidBody( 1.0f, tr, shape); + pBodyA->setActivationState(DISABLE_DEACTIVATION); + // dynamic bodyB: + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-30.), btScalar(-2.), btScalar(0.))); + btRigidBody* pBodyB = localCreateRigidBody(10.0, tr, shape); + pBodyB->setActivationState(DISABLE_DEACTIVATION); + // add some data to build constraint frames + btVector3 axisA(0.f, 1.f, 0.f); + btVector3 axisB(0.f, 1.f, 0.f); + btVector3 pivotA(-5.f, 0.f, 0.f); + btVector3 pivotB( 5.f, 0.f, 0.f); + spHingeDynAB = new btHingeConstraint(*pBodyA, *pBodyB, pivotA, pivotB, axisA, axisB); + spHingeDynAB->setLimit(-SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f); + // add constraint to world + m_dynamicsWorld->addConstraint(spHingeDynAB, true); + // draw constraint frames and limits for debugging + spHingeDynAB->setDbgDrawSize(btScalar(5.f)); + } +#endif + +#if ENABLE_ALL_DEMOS + { // 6DOF connected to the world, with motor + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(10.), btScalar(-15.), btScalar(0.))); + btRigidBody* pBody = localCreateRigidBody( 1.0, tr, shape); + pBody->setActivationState(DISABLE_DEACTIVATION); + btTransform frameB; + frameB.setIdentity(); + btGeneric6DofConstraint* pGen6Dof = new btGeneric6DofConstraint( *pBody, frameB, false ); + m_dynamicsWorld->addConstraint(pGen6Dof); + pGen6Dof->setDbgDrawSize(btScalar(5.f)); + + pGen6Dof->setAngularLowerLimit(btVector3(0,0,0)); + pGen6Dof->setAngularUpperLimit(btVector3(0,0,0)); + pGen6Dof->setLinearLowerLimit(btVector3(-10., 0, 0)); + pGen6Dof->setLinearUpperLimit(btVector3(10., 0, 0)); + + pGen6Dof->getTranslationalLimitMotor()->m_enableMotor[0] = true; + pGen6Dof->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f; + pGen6Dof->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f; + } +#endif + + + +} + +void ConstraintDemo::exitPhysics() +{ + + int i; + + //removed/delete constraints + for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--) + { + btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); + m_dynamicsWorld->removeConstraint(constraint); + delete constraint; + } + m_ctc = NULL; + + //remove the rigidbodies from the dynamics world and delete them + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + + + + //delete collision shapes + for (int j=0;jenableMotor(true); + m_ctc->setMotorTargetInConstraintSpace(q1); + } + + { + static bool once = true; + if ( m_dynamicsWorld->getDebugDrawer() && once) + { + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits); + once=false; + } + } + + + { + //during idle mode, just run 1 simulation step maximum + int maxSimSubSteps = m_idle ? 1 : 1; + if (m_idle) + dt = 1.0f/420.f; + + int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + bool verbose = false; + if (verbose) + { + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } + } + } + renderme(); + +// drawLimit(); + + glFlush(); + swapBuffers(); +} + + + + +void ConstraintDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + +// drawLimit(); + + renderme(); + + glFlush(); + swapBuffers(); +} + + +void ConstraintDemo::keyboardCallback(unsigned char key, int x, int y) +{ + (void)x; + (void)y; + switch (key) + { + case 'O' : + { + bool offectOnOff; + if(spDoorHinge) + { + offectOnOff = spDoorHinge->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spDoorHinge->setUseFrameOffset(offectOnOff); + printf("DoorHinge %s frame offset\n", offectOnOff ? "uses" : "does not use"); + } + if(spHingeDynAB) + { + offectOnOff = spHingeDynAB->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spHingeDynAB->setUseFrameOffset(offectOnOff); + printf("HingeDynAB %s frame offset\n", offectOnOff ? "uses" : "does not use"); + } + if(spSlider6Dof) + { + offectOnOff = spSlider6Dof->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spSlider6Dof->setUseFrameOffset(offectOnOff); + printf("Slider6Dof %s frame offset\n", offectOnOff ? "uses" : "does not use"); + } + } + break; + default : + { + DemoApplication::keyboardCallback(key, x, y); + } + break; + } +} diff --git a/Demos/ConstraintDemo/ConstraintDemo.h b/Demos/ConstraintDemo/ConstraintDemo.h new file mode 100644 index 0000000..5037cb9 --- /dev/null +++ b/Demos/ConstraintDemo/ConstraintDemo.h @@ -0,0 +1,75 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONSTRAINT_DEMO_H +#define CONSTRAINT_DEMO_H + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +///ConstraintDemo shows how to create a constraint, like Hinge or btGenericD6constraint +class ConstraintDemo : public PlatformDemoApplication +{ + //keep track of variables to delete memory at the end + btAlignedObjectArray m_collisionShapes; + + class btBroadphaseInterface* m_overlappingPairCache; + + class btCollisionDispatcher* m_dispatcher; + + class btConstraintSolver* m_constraintSolver; + + class btDefaultCollisionConfiguration* m_collisionConfiguration; + + void setupEmptyDynamicsWorld(); + + void clientResetScene(); + + + public: + + + virtual ~ConstraintDemo(); + + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + ConstraintDemo* demo = new ConstraintDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } + + virtual void keyboardCallback(unsigned char key, int x, int y); + + // for cone-twist motor driving + float m_Time; + class btConeTwistConstraint* m_ctc; + +}; + +#endif //CONSTRAINT_DEMO_H + diff --git a/Demos/ConstraintDemo/Win32ConstraintDemo.cpp b/Demos/ConstraintDemo/Win32ConstraintDemo.cpp new file mode 100644 index 0000000..552c263 --- /dev/null +++ b/Demos/ConstraintDemo/Win32ConstraintDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "ConstraintDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new ConstraintDemo(); +} + +#endif diff --git a/Demos/ConstraintDemo/main.cpp b/Demos/ConstraintDemo/main.cpp new file mode 100644 index 0000000..0cec5f6 --- /dev/null +++ b/Demos/ConstraintDemo/main.cpp @@ -0,0 +1,20 @@ +#include "ConstraintDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" + +#include "btBulletDynamicsCommon.h" + +int main(int argc,char** argv) +{ + + + + ConstraintDemo* constraintDemo = new ConstraintDemo(); + + + constraintDemo->initPhysics(); + constraintDemo->setDebugMode(btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits); + + return glutmain(argc, argv,640,480,"Constraint Demo. http://www.continuousphysics.com/Bullet/phpBB2/",constraintDemo); +} + diff --git a/Demos/ContinuousConvexCollision/CMakeLists.txt b/Demos/ContinuousConvexCollision/CMakeLists.txt new file mode 100644 index 0000000..bca9750 --- /dev/null +++ b/Demos/ContinuousConvexCollision/CMakeLists.txt @@ -0,0 +1,47 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppContinuousConvexCollisionDemo + ContinuousConvexCollisionDemo.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppContinuousConvexCollisionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppContinuousConvexCollisionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppContinuousConvexCollisionDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppContinuousConvexCollisionDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppContinuousConvexCollisionDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ContinuousConvexCollision/ContinuousConvexCollision.h b/Demos/ContinuousConvexCollision/ContinuousConvexCollision.h new file mode 100644 index 0000000..3f08900 --- /dev/null +++ b/Demos/ContinuousConvexCollision/ContinuousConvexCollision.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONTINUOUS_CONVEX_COLLISION_DEMO_H +#define CONTINUOUS_CONVEX_COLLISION_DEMO_H + + + +///ContinuousConvexCollisionDemo shows the working of the continuous collision detection, including linear and angular motion +#include "GlutDemoApplication.h" +class btContinuousConvexCollisionDemo : public GlutDemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + +}; + +#endif //CONTINUOUS_CONVEX_COLLISION_DEMO_H + diff --git a/Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp b/Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp new file mode 100644 index 0000000..9324845 --- /dev/null +++ b/Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + + +/* + Continuous Convex Collision Demo demonstrates an efficient continuous collision detection algorithm. + Both linear and angular velocities are supported. Convex Objects are sampled using Supporting Vertex. + Motion using Exponential Map. + Future ideas: Comparison with Screwing Motion. + Also comparision with Algebraic CCD and Interval Arithmetic methods (Stephane Redon) +*/ + + +///This low level demo need internal access, and intentionally doesn't include the btBulletCollisionCommon.h headerfile +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" + +#include "LinearMath/btTransformUtil.h" +#include "DebugCastResult.h" + +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" + +#include "GL_ShapeDrawer.h" +#include "ContinuousConvexCollision.h" +#include "GlutStuff.h" + + +float yaw=0.f,pitch=0.f,roll=0.f; +const int maxNumObjects = 4; +const int numObjects = 2; + +btVector3 angVels[numObjects]; +btVector3 linVels[numObjects]; + +btPolyhedralConvexShape* shapePtr[maxNumObjects]; + + +btTransform fromTrans[maxNumObjects]; +btTransform toTrans[maxNumObjects]; + + +int screenWidth = 640; +int screenHeight = 480; + + +int main(int argc,char** argv) +{ + btContinuousConvexCollisionDemo* ccdDemo = new btContinuousConvexCollisionDemo(); + + ccdDemo->setCameraDistance(40.f); + + ccdDemo->initPhysics(); + + return glutmain(argc, argv,screenWidth,screenHeight,"Continuous Convex Collision Demo",ccdDemo); +} + + +void btContinuousConvexCollisionDemo::initPhysics() +{ + fromTrans[0].setOrigin(btVector3(0,10,20)); + toTrans[0].setOrigin(btVector3(0,10,-20)); + fromTrans[1].setOrigin(btVector3(-2,7,0)); + toTrans[1].setOrigin(btVector3(-2,10,0)); + + btMatrix3x3 identBasis; + identBasis.setIdentity(); + + btMatrix3x3 basisA; + basisA.setIdentity(); + basisA.setEulerZYX(0.f,-SIMD_HALF_PI,0.f); + + fromTrans[0].setBasis(identBasis); + toTrans[0].setBasis(basisA); + + fromTrans[1].setBasis(identBasis); + toTrans[1].setBasis(identBasis); + + toTrans[1].setBasis(identBasis); + btVector3 boxHalfExtentsA(10,1,1); + btVector3 boxHalfExtentsB(1.1f,1.1f,1.1f); + btBoxShape* boxA = new btBoxShape(boxHalfExtentsA); +// btBU_Simplex1to4* boxA = new btBU_Simplex1to4(btVector3(-2,0,-2),btVector3(2,0,-2),btVector3(0,0,2),btVector3(0,2,0)); +// btBU_Simplex1to4* boxA = new btBU_Simplex1to4(btVector3(-12,0,0),btVector3(12,0,0)); + + + btBoxShape* boxB = new btBoxShape(boxHalfExtentsB); + + shapePtr[0] = boxA; + shapePtr[1] = boxB; + + shapePtr[0]->setMargin(0.01f); + shapePtr[1]->setMargin(0.01f); + + for (int i=0;idrawOpenGL(m,shapePtr[i],btVector3(1,0,1),getDebugMode(),worldBoundsMin,worldBoundsMax); + } + } + } + + + btMatrix3x3 mat; + mat.setEulerZYX(yaw,pitch,roll); + btQuaternion orn; + mat.getRotation(orn); + orn.setEuler(yaw,pitch,roll); + fromTrans[1].setRotation(orn); + toTrans[1].setRotation(orn); + + + if (m_stepping || m_singleStep) + { + m_singleStep = false; + pitch += 0.005f; +// yaw += 0.01f; + } +// btVector3 fromA(-25,11,0); +// btVector3 toA(-15,11,0); + +// btQuaternion ornFromA(0.f,0.f,0.f,1.f); +// btQuaternion ornToA(0.f,0.f,0.f,1.f); + +// btTransform rayFromWorld(ornFromA,fromA); +// btTransform rayToWorld(ornToA,toA); + + btTransform rayFromWorld = fromTrans[0]; + btTransform rayToWorld = toTrans[0]; + + + if (drawLine) + { + glBegin(GL_LINES); + glColor3f(0, 0, 1); + glVertex3d(rayFromWorld.getOrigin().x(), rayFromWorld.getOrigin().y(),rayFromWorld.getOrigin().z()); + glVertex3d(rayToWorld.getOrigin().x(),rayToWorld.getOrigin().y(),rayToWorld.getOrigin().z()); + glEnd(); + } + + //now perform a raycast on the shapes, in local (shape) space + gGjkSimplexSolver.reset(); + + //choose one of the following lines + + + for (i=0;idrawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax); + } + + btDebugCastResult rayResult1(fromTrans[0],shapePtr[0],linVels[0],angVels[0],m_shapeDrawer); + + + for (i=1;im_fraction,hitTrans); + + hitTrans.getOpenGLMatrix(m); + m_shapeDrawer->drawOpenGL(m,shapePtr[0],btVector3(0,1,0),getDebugMode(),worldBoundsMin,worldBoundsMax); + + btTransformUtil::integrateTransform(fromTrans[i],linVels[i],angVels[i],rayResultPtr->m_fraction,hitTrans); + + hitTrans.getOpenGLMatrix(m); + m_shapeDrawer->drawOpenGL(m,shapePtr[i],btVector3(0,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax); + + + } + } + + swapBuffers(); +} + + diff --git a/Demos/ConvexDecompositionDemo/CMakeLists.txt b/Demos/ConvexDecompositionDemo/CMakeLists.txt new file mode 100644 index 0000000..ba8ee3b --- /dev/null +++ b/Demos/ConvexDecompositionDemo/CMakeLists.txt @@ -0,0 +1,83 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${BULLET_PHYSICS_SOURCE_DIR}/Extras/HACD +${BULLET_PHYSICS_SOURCE_DIR}/Extras/ConvexDecomposition +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +) + +IF (USE_GLUT) + + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader HACD ConvexDecomposition ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppConvexDecompositionDemo + main.cpp + ConvexDecompositionDemo.cpp + ConvexDecompositionDemo.h + ) + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConvexDecompositionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppConvexDecompositionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) +ELSE (USE_GLUT) + +LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader HACD ConvexDecomposition ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppConvexDecompositionDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + ConvexDecompositionDemo.cpp + ConvexDecompositionDemo.h + Win32ConvexDecompositionDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + +ENDIF (USE_GLUT) + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( + TARGET AppConvexDecompositionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SerializeDemo/testFile.bullet ${CMAKE_CURRENT_BINARY_DIR}/testFile.bullet + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/file.obj ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppConvexDecompositionDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppConvexDecompositionDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppConvexDecompositionDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp new file mode 100644 index 0000000..58b6f8c --- /dev/null +++ b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp @@ -0,0 +1,741 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "hacdCircularList.h" +#include "hacdVector.h" +#include "hacdICHull.h" +#include "hacdGraph.h" +#include "hacdHACD.h" + +#include "cd_wavefront.h" +#include "ConvexBuilder.h" + +#include "btBulletDynamicsCommon.h" + +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btGeometryUtil.h" +#include "BulletCollision/CollisionShapes/btShapeHull.h" + +//#define TEST_SERIALIZATION +//#define NO_OBJ_TO_BULLET + +#ifdef TEST_SERIALIZATION +#include "LinearMath/btSerializer.h" +#include "btBulletFile.h" +#include "btBulletWorldImporter.h" +#endif + +//#define USE_PARALLEL_DISPATCHER 1 +#ifdef USE_PARALLEL_DISPATCHER +#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#include "../../Extras/BulletMultiThreaded/Win32ThreadSupport.h" +#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#endif//USE_PARALLEL_DISPATCHER + + + + + +#include "GLDebugFont.h" +#include //printf debugging + + +#include "ConvexDecompositionDemo.h" +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" + + +btVector3 centroid=btVector3(0,0,0); +btVector3 convexDecompositionObjectOffset(10,0,0); + +#define CUBE_HALF_EXTENTS 4 + + +//////////////////////////////////// + +unsigned int tcount = 0; + + +void ConvexDecompositionDemo::initPhysics() +{ + initPhysics("file.obj"); +} + + + +///MyContactCallback is just an example to show how to get access to the child shape that collided +bool MyContactCallback ( + btManifoldPoint& cp, + const btCollisionObjectWrapper* colObj0Wrap, + int partId0, + int index0, + const btCollisionObjectWrapper* colObj1Wrap, + int partId1, + int index1) +{ + + if (colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) + { + btCompoundShape* compound = (btCompoundShape*)colObj0Wrap->getCollisionObject()->getCollisionShape(); + btCollisionShape* childShape; + childShape = compound->getChildShape(index0); + } + + if (colObj1Wrap->getCollisionObject()->getCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) + { + btCompoundShape* compound = (btCompoundShape*)colObj1Wrap->getCollisionObject()->getCollisionShape(); + btCollisionShape* childShape; + childShape = compound->getChildShape(index1); + } + + return true; +} + + +void ConvexDecompositionDemo::setupEmptyDynamicsWorld() +{ +m_collisionConfiguration = new btDefaultCollisionConfiguration(); + +#ifdef USE_PARALLEL_DISPATCHER +#ifdef USE_WIN32_THREADING + + int maxNumOutstandingTasks = 4;//number of maximum outstanding tasks + Win32ThreadSupport* threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( + "collision", + processCollisionTask, + createCollisionLocalStoreMemory, + maxNumOutstandingTasks)); +#else +///@todo other platform threading +///Playstation 3 SPU (SPURS) version is available through PS3 Devnet +///Libspe2 SPU support will be available soon +///pthreads version +///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface +#endif + + m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,m_collisionConfiguration); +#else + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#endif//USE_PARALLEL_DISPATCHER + + + convexDecompositionObjectOffset.setValue(10,0,0); + + btVector3 worldAabbMin(-10000,-10000,-10000); + btVector3 worldAabbMax(10000,10000,10000); + + m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax); + //m_broadphase = new btSimpleBroadphase(); + + m_solver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + +#ifdef USE_PARALLEL_DISPATCHER + m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; +#endif //USE_PARALLEL_DISPATCHER + +} + +void ConvexDecompositionDemo::initPhysics(const char* filename) +{ + + + gContactAddedCallback = &MyContactCallback; + + setupEmptyDynamicsWorld(); + + setTexturing(true); + setShadows(true); + + setCameraDistance(26.f); + + +#ifndef NO_OBJ_TO_BULLET + + ConvexDecomposition::WavefrontObj wo; + + tcount = wo.loadObj(filename); + + if (!tcount) + { + //when running this app from visual studio, the default starting folder is different, so make a second attempt... + tcount = wo.loadObj("../../file.obj"); + } + if (!tcount) + { + //cmake generated msvc files need 4 levels deep back... so make a 3rd attempt... + tcount = wo.loadObj("../../../../file.obj"); + } + + + + + + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-4.5,0)); + + btCollisionShape* boxShape = new btBoxShape(btVector3(30,2,30)); + m_collisionShapes.push_back(boxShape); + localCreateRigidBody(0.f,startTransform,boxShape); + + class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface + { + ConvexDecompositionDemo* m_convexDemo; + + public: + + btAlignedObjectArray m_convexShapes; + btAlignedObjectArray m_convexCentroids; + + MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo) + :m_convexDemo(demo), + mBaseCount(0), + mHullCount(0), + mOutputFile(outputFile) + + { + } + + virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result) + { + + btTriangleMesh* trimesh = new btTriangleMesh(); + m_convexDemo->m_trimeshes.push_back(trimesh); + + btVector3 localScaling(6.f,6.f,6.f); + + //export data to .obj + printf("ConvexResult. "); + if (mOutputFile) + { + fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount ); + + fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount); + fprintf(mOutputFile,"o Object%i\r\n",mBaseCount); + + for (unsigned int i=0; i vertices; + if ( 1 ) + { + //const unsigned int *src = result.mHullIndices; + for (unsigned int i=0; iaddTriangle(vertex0,vertex1,vertex2); + + index0+=mBaseCount; + index1+=mBaseCount; + index2+=mBaseCount; + + fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 ); + } + } + + // float mass = 1.f; + + +//this is a tools issue: due to collision margin, convex objects overlap, compensate for it here: +//#define SHRINK_OBJECT_INWARDS 1 +#ifdef SHRINK_OBJECT_INWARDS + + float collisionMargin = 0.01f; + + btAlignedObjectArray planeEquations; + btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations); + + btAlignedObjectArray shiftedPlaneEquations; + for (int p=0;p shiftedVertices; + btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices); + + + btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size()); + +#else //SHRINK_OBJECT_INWARDS + + btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size()); +#endif + + convexShape->setMargin(0.01f); + m_convexShapes.push_back(convexShape); + m_convexCentroids.push_back(centroid); + m_convexDemo->m_collisionShapes.push_back(convexShape); + mBaseCount+=result.mHullVcount; // advance the 'base index' counter. + + + } + } + + int mBaseCount; + int mHullCount; + FILE* mOutputFile; + + }; + + if (tcount) + { + btTriangleMesh* trimesh = new btTriangleMesh(); + m_trimeshes.push_back(trimesh); + + btVector3 localScaling(6.f,6.f,6.f); + + int i; + for ( i=0;iaddTriangle(vertex0,vertex1,vertex2); + } + + + btConvexShape* tmpConvexShape = new btConvexTriangleMeshShape(trimesh); + + printf("old numTriangles= %d\n",wo.mTriCount); + printf("old numIndices = %d\n",wo.mTriCount*3); + printf("old numVertices = %d\n",wo.mVertexCount); + + printf("reducing vertices by creating a convex hull\n"); + + //create a hull approximation + btShapeHull* hull = new btShapeHull(tmpConvexShape); + btScalar margin = tmpConvexShape->getMargin(); + hull->buildHull(margin); + tmpConvexShape->setUserPointer(hull); + + + printf("new numTriangles = %d\n", hull->numTriangles ()); + printf("new numIndices = %d\n", hull->numIndices ()); + printf("new numVertices = %d\n", hull->numVertices ()); + + btConvexHullShape* convexShape = new btConvexHullShape(); + for (i=0;inumVertices();i++) + { + convexShape->addPoint(hull->getVertexPointer()[i]); + } + + delete tmpConvexShape; + delete hull; + + + + m_collisionShapes.push_back(convexShape); + + float mass = 1.f; + + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,2,14)); + + localCreateRigidBody(mass, startTransform,convexShape); + + bool useQuantization = true; + btCollisionShape* concaveShape = new btBvhTriangleMeshShape(trimesh,useQuantization); + startTransform.setOrigin(convexDecompositionObjectOffset); + localCreateRigidBody(0.f,startTransform,concaveShape); + + m_collisionShapes.push_back (concaveShape); + + } + + + if (tcount) + { + //----------------------------------- + // Bullet Convex Decomposition + //----------------------------------- + + char outputFileName[512]; + strcpy(outputFileName,filename); + char *dot = strstr(outputFileName,"."); + if ( dot ) + *dot = 0; + strcat(outputFileName,"_convex.obj"); + FILE* outputFile = fopen(outputFileName,"wb"); + + unsigned int depth = 5; + float cpercent = 5; + float ppercent = 15; + unsigned int maxv = 16; + float skinWidth = 0.0; + + printf("WavefrontObj num triangles read %i\n",tcount); + ConvexDecomposition::DecompDesc desc; + desc.mVcount = wo.mVertexCount; + desc.mVertices = wo.mVertices; + desc.mTcount = wo.mTriCount; + desc.mIndices = (unsigned int *)wo.mIndices; + desc.mDepth = depth; + desc.mCpercent = cpercent; + desc.mPpercent = ppercent; + desc.mMaxVertices = maxv; + desc.mSkinWidth = skinWidth; + + MyConvexDecomposition convexDecomposition(outputFile,this); + desc.mCallback = &convexDecomposition; + + + //----------------------------------------------- + // HACD + //----------------------------------------------- + + std::vector< HACD::Vec3 > points; + std::vector< HACD::Vec3 > triangles; + + for(int i=0; i vertex(wo.mVertices[index], wo.mVertices[index+1],wo.mVertices[index+2]); + points.push_back(vertex); + } + + for(int i=0;i triangle(wo.mIndices[index], wo.mIndices[index+1], wo.mIndices[index+2]); + triangles.push_back(triangle); + } + + + HACD::HACD myHACD; + myHACD.SetPoints(&points[0]); + myHACD.SetNPoints(points.size()); + myHACD.SetTriangles(&triangles[0]); + myHACD.SetNTriangles(triangles.size()); + myHACD.SetCompacityWeight(0.1); + myHACD.SetVolumeWeight(0.0); + + // HACD parameters + // Recommended parameters: 2 100 0 0 0 0 + size_t nClusters = 2; + double concavity = 100; + bool invert = false; + bool addExtraDistPoints = false; + bool addNeighboursDistPoints = false; + bool addFacesPoints = false; + + myHACD.SetNClusters(nClusters); // minimum number of clusters + myHACD.SetNVerticesPerCH(100); // max of 100 vertices per convex-hull + myHACD.SetConcavity(concavity); // maximum concavity + myHACD.SetAddExtraDistPoints(addExtraDistPoints); + myHACD.SetAddNeighboursDistPoints(addNeighboursDistPoints); + myHACD.SetAddFacesPoints(addFacesPoints); + + myHACD.Compute(); + nClusters = myHACD.GetNClusters(); + + myHACD.Save("output.wrl", false); + + + //convexDecomposition.performConvexDecomposition(desc); + +// ConvexBuilder cb(desc.mCallback); +// cb.process(desc); + //now create some bodies + + if (1) + { + btCompoundShape* compound = new btCompoundShape(); + m_collisionShapes.push_back (compound); + + btTransform trans; + trans.setIdentity(); + + for (int c=0;c * pointsCH = new HACD::Vec3[nPoints]; + HACD::Vec3 * trianglesCH = new HACD::Vec3[nTriangles]; + myHACD.GetCH(c, pointsCH, trianglesCH); + + // points + for(size_t v = 0; v < nPoints; v++) + { + vertices[3*v] = pointsCH[v].X(); + vertices[3*v+1] = pointsCH[v].Y(); + vertices[3*v+2] = pointsCH[v].Z(); + } + // triangles + for(size_t f = 0; f < nTriangles; f++) + { + triangles[3*f] = trianglesCH[f].X(); + triangles[3*f+1] = trianglesCH[f].Y(); + triangles[3*f+2] = trianglesCH[f].Z(); + } + + delete [] pointsCH; + delete [] trianglesCH; + + ConvexResult r(nPoints, vertices, nTriangles, triangles); + convexDecomposition.ConvexDecompResult(r); + } + + for (int i=0;iaddChildShape(trans,convexShape); + + btRigidBody* body; + body = localCreateRigidBody( 1.0, trans,convexShape); + } +/* for (int i=0;iaddChildShape(trans,convexShape); + + btRigidBody* body; + body = localCreateRigidBody( 1.0, trans,convexShape); + }*/ + +#if 1 + btScalar mass=10.f; + trans.setOrigin(-convexDecompositionObjectOffset); + btRigidBody* body = localCreateRigidBody( mass, trans,compound); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + convexDecompositionObjectOffset.setZ(6); + trans.setOrigin(-convexDecompositionObjectOffset); + body = localCreateRigidBody( mass, trans,compound); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + convexDecompositionObjectOffset.setZ(-6); + trans.setOrigin(-convexDecompositionObjectOffset); + body = localCreateRigidBody( mass, trans,compound); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); +#endif + } + + + if (outputFile) + fclose(outputFile); + + + } + + + +#ifdef TEST_SERIALIZATION + //test serializing this + + int maxSerializeBufferSize = 1024*1024*5; + + btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); + m_dynamicsWorld->serialize(serializer); + + FILE* f2 = fopen("testFile.bullet","wb"); + fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); + fclose(f2); + + exitPhysics(); + + //now try again from the loaded file + setupEmptyDynamicsWorld(); +#endif //TEST_SERIALIZATION + +#endif //NO_OBJ_TO_BULLET + +#ifdef TEST_SERIALIZATION + + btBulletWorldImporter* fileLoader = new btBulletWorldImporter(m_dynamicsWorld); + //fileLoader->setVerboseMode(true); + + fileLoader->loadFile("testFile.bullet"); + //fileLoader->loadFile("testFile64Double.bullet"); + //fileLoader->loadFile("testFile64Single.bullet"); + //fileLoader->loadFile("testFile32Single.bullet"); + + + + +#endif //TEST_SERIALIZATION + +} + +void ConvexDecompositionDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + swapBuffers(); + +} + + + +void ConvexDecompositionDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + + glFlush(); + swapBuffers(); +} + + + + +void ConvexDecompositionDemo::exitPhysics() +{ + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (i=0;i m_collisionShapes; + + btAlignedObjectArray m_trimeshes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + + virtual void initPhysics(); + + void initPhysics(const char* filename); + + void exitPhysics(); + + virtual ~ConvexDecompositionDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + ConvexDecompositionDemo* demo = new ConvexDecompositionDemo(); + demo->myinit(); + demo->initPhysics("file.obj"); + return demo; + } + + +}; + +#endif //CONVEX_DECOMPOSITION_DEMO_H + + diff --git a/Demos/ConvexDecompositionDemo/Win32ConvexDecompositionDemo.cpp b/Demos/ConvexDecompositionDemo/Win32ConvexDecompositionDemo.cpp new file mode 100644 index 0000000..d04e1d3 --- /dev/null +++ b/Demos/ConvexDecompositionDemo/Win32ConvexDecompositionDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "ConvexDecompositionDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new ConvexDecompositionDemo(); +} + +#endif diff --git a/Demos/ConvexDecompositionDemo/main.cpp b/Demos/ConvexDecompositionDemo/main.cpp new file mode 100644 index 0000000..b8f3a65 --- /dev/null +++ b/Demos/ConvexDecompositionDemo/main.cpp @@ -0,0 +1,32 @@ + + +#include "ConvexDecompositionDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + const char* filename = "file.obj"; + + + ConvexDecompositionDemo* convexDecompDemo = new ConvexDecompositionDemo(); + + convexDecompDemo->initPhysics(filename); + + convexDecompDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + + convexDecompDemo->clientResetScene(); + + + + glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/",convexDecompDemo); + + delete convexDecompDemo; + + return 0; +} diff --git a/Demos/ConvexDecompositionDemo/testFile32Single.bullet b/Demos/ConvexDecompositionDemo/testFile32Single.bullet new file mode 100644 index 0000000000000000000000000000000000000000..b946379739fca1bcdbd185eb00d3a423fe5e86e8 GIT binary patch literal 67844 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 +#endif +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#else +#include +#endif +#include "GlutStuff.h" + + +float yaw=0.f,pitch=0.f,roll=0.f; +const int maxNumObjects = 4; +const int numObjects = 2; + +GL_Simplex1to4 simplex; + +btConvexShape* shapePtr[maxNumObjects]; + +btTransform tr[numObjects]; +int screenWidth = 640.f; +int screenHeight = 480.f; + +void clientResetScene() +{ + tr[0].setOrigin(btVector3(0.0f,3.f,7.f)); + tr[1].setOrigin(btVector3(0.0f,9.f,2.f)); +} + +int debugMode = btIDebugDraw::DBG_DrawWireframe; +GL_ShapeDrawer shapeDrawer; +int m_glutScreenWidth=0; +int m_glutScreenHeight=0; +float m_frustumZNear = 1.f; +float m_frustumZFar = 10000.f; +bool m_ortho = false; + +int myglutmain(int argc, char **argv,int width,int height,const char* title); + + +void updateCamera() { + + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + btScalar rele = 0; + btScalar razi = 0; + btVector3 m_cameraUp(0,1,0); + btScalar m_cameraDistance = 10.f; + btVector3 m_cameraPosition; + + + btVector3 m_cameraTargetPosition = (tr[0].getOrigin()+tr[1].getOrigin())*0.5; + + + btQuaternion rot(m_cameraUp,razi); + + + int m_forwardAxis = 2; + + btVector3 eyePos(0,0,0); + eyePos[m_forwardAxis] = -m_cameraDistance; + + btVector3 forward(eyePos[0],eyePos[1],eyePos[2]); + if (forward.length2() < SIMD_EPSILON) + { + forward.setValue(1.f,0.f,0.f); + } + btVector3 right = m_cameraUp.cross(forward); + btQuaternion roll(right,-rele); + + eyePos = btMatrix3x3(rot) * btMatrix3x3(roll) * eyePos; + + m_cameraPosition[0] = eyePos.getX(); + m_cameraPosition[1] = eyePos.getY(); + m_cameraPosition[2] = eyePos.getZ(); + m_cameraPosition += m_cameraTargetPosition; + + if (m_glutScreenWidth == 0 && m_glutScreenHeight == 0) + return; + + btScalar aspect; + btVector3 extents; + + if (m_glutScreenWidth > m_glutScreenHeight) + { + aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; + extents.setValue(aspect * 1.0f, 1.0f,0); + } else + { + aspect = m_glutScreenHeight / (btScalar)m_glutScreenWidth; + extents.setValue(1.0f, aspect*1.f,0); + } + + + if (m_ortho) + { + // reset matrix + glLoadIdentity(); + + + extents *= m_cameraDistance; + btVector3 lower = m_cameraTargetPosition - extents; + btVector3 upper = m_cameraTargetPosition + extents; + //gluOrtho2D(lower.x, upper.x, lower.y, upper.y); + glOrtho(lower.getX(), upper.getX(), lower.getY(), upper.getY(),-1000,1000); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + //glTranslatef(100,210,0); + } else + { + if (m_glutScreenWidth > m_glutScreenHeight) + { +// glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0); + glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar); + } else + { +// glFrustum (-1.0, 1.0, -aspect, aspect, 1.0, 10000.0); + glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar); + } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(m_cameraPosition[0], m_cameraPosition[1], m_cameraPosition[2], + m_cameraTargetPosition[0], m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + } + +} + + +int main(int argc,char** argv) +{ + clientResetScene(); + + btMatrix3x3 basisA; + basisA.setIdentity(); + + btMatrix3x3 basisB; + basisB.setIdentity(); + + tr[0].setBasis(basisA); + tr[1].setBasis(basisB); + + btVector3 points0[3]={btVector3(1,0,0),btVector3(0,1,0),btVector3(0,0,1)}; + //btVector3 points1[5]={btVector3(1,0,0),btVector3(0,1,0),btVector3(0,0,1),btVector3(0,0,-1),btVector3(-1,-1,0)}; + + btConvexHullShape hullA(&points0[0].getX(),3); + btConvexHullShape hullB(TaruVtx,TaruVtxCount,3*sizeof(btScalar)); + + shapePtr[0] = &hullA; + shapePtr[1] = &hullB; + + + btTransform tr; + tr.setIdentity(); + + + return myglutmain(argc, argv,screenWidth,screenHeight,"Convex Hull Distance Demo"); +} + + +static btVoronoiSimplexSolver sGjkSimplexSolver; +btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver; + +#include + + +void clientDisplay(void) { + + + updateCamera(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + + //GL_ShapeDrawer::drawCoordSystem(); + + ATTRIBUTE_ALIGNED16(btScalar) m[16]; + int i; +#ifdef USE_GJK + btGjkEpaPenetrationDepthSolver epa; + btGjkPairDetector convexConvex(shapePtr[0],shapePtr[1],&sGjkSimplexSolver,&epa); + + btVector3 seperatingAxis(0.00000000f,0.059727669f,0.29259586f); + convexConvex.setCachedSeperatingAxis(seperatingAxis); + + btPointCollector gjkOutput; + btGjkPairDetector::ClosestPointInput input; + input.m_transformA = tr[0]; + input.m_transformB = tr[1]; + + convexConvex.getClosestPoints(input ,gjkOutput,0); + + if (gjkOutput.m_hasResult) + { + btVector3 endPt = gjkOutput.m_pointInWorld + + gjkOutput.m_normalOnBInWorld*gjkOutput.m_distance; + + glBegin(GL_LINES); + glColor3f(1, 0, 0); + glVertex3d(gjkOutput.m_pointInWorld.x(), gjkOutput.m_pointInWorld.y(),gjkOutput.m_pointInWorld.z()); + glVertex3d(endPt.x(),endPt.y(),endPt.z()); + glEnd(); + + } +#else //USE_GJK + + + struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback + { + virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) + { + glBegin(GL_LINES); + glColor3f(1, 0, 0); + + glVertex3d(cp.m_positionWorldOnA.getX(),cp.m_positionWorldOnA.getY(),cp.m_positionWorldOnA.getZ()); + glVertex3d(cp.m_positionWorldOnB.getX(),cp.m_positionWorldOnB.getY(),cp.m_positionWorldOnB.getZ()); + glEnd(); + + return 1.f; + } + }; + + btDefaultCollisionConfiguration collisionConfiguration; + btCollisionDispatcher dispatcher(&collisionConfiguration); + btDbvtBroadphase pairCache; + btCollisionWorld world (&dispatcher,&pairCache,&collisionConfiguration); + world.getDispatchInfo().m_convexMaxDistanceUseCPT = true; + MyContactResultCallback result; + btCollisionObject obA; + obA.setCollisionShape(shapePtr[0]); + obA.setWorldTransform(tr[0]); + btCollisionObject obB; + obB.setCollisionShape(shapePtr[1]); + obB.setWorldTransform(tr[1]); + world.contactPairTest(&obA,&obB,result); + +#endif//USE_GJK + + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + + for (i=0;iisPolyhedral()) + { + if (!shapePtr[i]->getUserPointer()) + { + btConvexHullComputer* convexUtil = new btConvexHullComputer(); + shapePtr[i]->setUserPointer(convexUtil); + + btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shapePtr[i]; + + btAlignedObjectArray vertices; + vertices.resize(polyshape->getNumVertices()); + for (int i=0;igetNumVertices();i++) + { + polyshape->getVertex(i,vertices[i]); + } + + bool useDoublePrecision = false; + convexUtil->compute(&vertices[0].getX(),sizeof(btVector3), polyshape->getNumVertices(),0,0); + } + + if (shapePtr[i]->getUserPointer()) + { + btConvexHullComputer* convexUtil = (btConvexHullComputer*)shapePtr[i]->getUserPointer(); + //printf("num faces = %d\n",convexUtil->faces.size()); + for (int j=0;jfaces.size();j++) + { + int face = convexUtil->faces[j]; + //printf("face=%d\n",face); + const btConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face]; + const btConvexHullComputer::Edge* edge = firstEdge; + + do + { + int src = edge->getSourceVertex(); + int targ = edge->getTargetVertex(); + //printf("src=%d target = %d\n", src,targ); + + btVector3 wa = tr[i] * convexUtil->vertices[src]; + btVector3 wb = tr[i] * convexUtil->vertices[targ]; + + glBegin(GL_LINES); + glColor3f(1, 1, 1); + glVertex3f(wa.getX(),wa.getY(),wa.getZ()); + glVertex3f(wb.getX(),wb.getY(),wb.getZ()); + glEnd(); + + edge = edge->getNextEdgeOfFace(); + } while (edge!=firstEdge); + + } + } + } + } else + { + shapeDrawer.drawOpenGL(m,shapePtr[i],btVector3(1,1,1),debugMode, worldMin, worldMax); + } + + + } + + simplex.setSimplexSolver(&sGjkSimplexSolver); + btVector3 ybuf[4],pbuf[4],qbuf[4]; + int numpoints = sGjkSimplexSolver.getSimplex(pbuf,qbuf,ybuf); + simplex.reset(); + + for (i=0;i +char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N]; + +#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))) +#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) +#endif + +//-------------------------------------------------------------------------------------- +// Thread safety +//-------------------------------------------------------------------------------------- +CRITICAL_SECTION g_cs; +bool g_bThreadSafe = true; + + +//-------------------------------------------------------------------------------------- +// Automatically enters & leaves the CS upon object creation/deletion +//-------------------------------------------------------------------------------------- +class DXUTLock +{ +public: + inline DXUTLock() { if( g_bThreadSafe ) EnterCriticalSection( &g_cs ); } + inline ~DXUTLock() { if( g_bThreadSafe ) LeaveCriticalSection( &g_cs ); } +}; + +//-------------------------------------------------------------------------------------- +// Helper macros to build member functions that access member variables with thread safety +//-------------------------------------------------------------------------------------- +#define SET_ACCESSOR( x, y ) inline void Set##y( x t ) { DXUTLock l; m_state.m_##y = t; }; +#define GET_ACCESSOR( x, y ) inline x Get##y() { DXUTLock l; return m_state.m_##y; }; +#define GET_SET_ACCESSOR( x, y ) SET_ACCESSOR( x, y ) GET_ACCESSOR( x, y ) + +#define SETP_ACCESSOR( x, y ) inline void Set##y( x* t ) { DXUTLock l; m_state.m_##y = *t; }; +#define GETP_ACCESSOR( x, y ) inline x* Get##y() { DXUTLock l; return &m_state.m_##y; }; +#define GETP_SETP_ACCESSOR( x, y ) SETP_ACCESSOR( x, y ) GETP_ACCESSOR( x, y ) + + +//-------------------------------------------------------------------------------------- +// Stores timer callback info +//-------------------------------------------------------------------------------------- +struct DXUT_TIMER +{ + LPDXUTCALLBACKTIMER pCallbackTimer; + void* pCallbackUserContext; + float fTimeoutInSecs; + float fCountdown; + bool bEnabled; + UINT nID; +}; + + + +//-------------------------------------------------------------------------------------- +// Stores DXUT state and data access is done with thread safety (if g_bThreadSafe==true) +//-------------------------------------------------------------------------------------- +class DXUTState +{ +protected: + struct STATE + { + // D3D9 specific + IDirect3D9* m_D3D9; // the main D3D9 object + IDirect3DDevice9* m_D3D9Device; // the D3D9 rendering device + DXUTDeviceSettings* m_CurrentDeviceSettings; // current device settings + D3DSURFACE_DESC m_BackBufferSurfaceDesc9; // D3D9 back buffer surface description + D3DCAPS9 m_Caps; // D3D caps for current device + + // D3D11 specific + IDXGIFactory1* m_DXGIFactory; // DXGI Factory object + IDXGIAdapter1* m_DXGIAdapter; // The DXGI adapter object for the D3D11 device + IDXGIOutput** m_DXGIOutputArray; // The array of output obj for the D3D11 adapter obj + UINT m_DXGIOutputArraySize; // Number of elements in m_D3D11OutputArray + IDXGISwapChain* m_DXGISwapChain; // the D3D11 swapchain + DXGI_SURFACE_DESC m_BackBufferSurfaceDescDXGI; // D3D11 back buffer surface description + bool m_RenderingOccluded; // Rendering is occluded by another window + bool m_DoNotStoreBufferSize; // Do not store the buffer size on WM_SIZE messages + + // D3D11 specific + bool m_D3D11Available; // if true, then D3D11 is available + ID3D11Device* m_D3D11Device; // the D3D11 rendering device + ID3D11DeviceContext* m_D3D11DeviceContext; // the D3D11 immediate device context + D3D_FEATURE_LEVEL m_D3D11FeatureLevel; // the D3D11 feature level that this device supports + ID3D11Texture2D* m_D3D11DepthStencil; // the D3D11 depth stencil texture (optional) + ID3D11DepthStencilView* m_D3D11DepthStencilView; // the D3D11 depth stencil view (optional) + ID3D11RenderTargetView* m_D3D11RenderTargetView; // the D3D11 render target view + ID3D11RasterizerState* m_D3D11RasterizerState; // the D3D11 Rasterizer state + + // General + HWND m_HWNDFocus; // the main app focus window + HWND m_HWNDDeviceFullScreen; // the main app device window in fullscreen mode + HWND m_HWNDDeviceWindowed; // the main app device window in windowed mode + HMONITOR m_AdapterMonitor; // the monitor of the adapter + HMENU m_Menu; // handle to menu + + UINT m_FullScreenBackBufferWidthAtModeChange; // back buffer size of fullscreen mode right before switching to windowed mode. Used to restore to same resolution when toggling back to fullscreen + UINT m_FullScreenBackBufferHeightAtModeChange; // back buffer size of fullscreen mode right before switching to windowed mode. Used to restore to same resolution when toggling back to fullscreen + UINT m_WindowBackBufferWidthAtModeChange; // back buffer size of windowed mode right before switching to fullscreen mode. Used to restore to same resolution when toggling back to windowed mode + UINT m_WindowBackBufferHeightAtModeChange; // back buffer size of windowed mode right before switching to fullscreen mode. Used to restore to same resolution when toggling back to windowed mode + DWORD m_WindowedStyleAtModeChange; // window style + WINDOWPLACEMENT m_WindowedPlacement;// record of windowed HWND position/show state/etc + bool m_TopmostWhileWindowed; // if true, the windowed HWND is topmost + bool m_Minimized; // if true, the HWND is minimized + bool m_Maximized; // if true, the HWND is maximized + bool m_MinimizedWhileFullscreen; // if true, the HWND is minimized due to a focus switch away when fullscreen mode + bool m_IgnoreSizeChange; // if true, DXUT won't reset the device upon HWND size change + + double m_Time; // current time in seconds + double m_AbsoluteTime; // absolute time in seconds + float m_ElapsedTime; // time elapsed since last frame + + HINSTANCE m_HInstance; // handle to the app instance + double m_LastStatsUpdateTime; // last time the stats were updated + DWORD m_LastStatsUpdateFrames; // frames count since last time the stats were updated + float m_FPS; // frames per second + int m_CurrentFrameNumber; // the current frame number + HHOOK m_KeyboardHook; // handle to keyboard hook + bool m_AllowShortcutKeysWhenFullscreen; // if true, when fullscreen enable shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut) + bool m_AllowShortcutKeysWhenWindowed; // if true, when windowed enable shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut) + bool m_AllowShortcutKeys; // if true, then shortcut keys are currently disabled (Windows key, etc) + bool m_CallDefWindowProc; // if true, DXUTStaticWndProc will call DefWindowProc for unhandled messages. Applications rendering to a dialog may need to set this to false. + STICKYKEYS m_StartupStickyKeys; // StickyKey settings upon startup so they can be restored later + TOGGLEKEYS m_StartupToggleKeys; // ToggleKey settings upon startup so they can be restored later + FILTERKEYS m_StartupFilterKeys; // FilterKey settings upon startup so they can be restored later + + bool m_AppSupportsD3D9Override; // true if app sets via DXUTSetD3DVersionSupport() + bool m_AppSupportsD3D11Override; // true if app sets via DXUTSetD3DVersionSupport() + bool m_UseD3DVersionOverride; // true if the app ever calls DXUTSetD3DVersionSupport() + + bool m_HandleEscape; // if true, then DXUT will handle escape to quit + bool m_HandleAltEnter; // if true, then DXUT will handle alt-enter to toggle fullscreen + bool m_HandlePause; // if true, then DXUT will handle pause to toggle time pausing + bool m_ShowMsgBoxOnError; // if true, then msgboxes are displayed upon errors + bool m_NoStats; // if true, then DXUTGetFrameStats() and DXUTGetDeviceStats() will return blank strings + bool m_ClipCursorWhenFullScreen; // if true, then DXUT will keep the cursor from going outside the window when full screen + bool m_ShowCursorWhenFullScreen; // if true, then DXUT will show a cursor when full screen + bool m_ConstantFrameTime; // if true, then elapsed frame time will always be 0.05f seconds which is good for debugging or automated capture + float m_TimePerFrame; // the constant time per frame in seconds, only valid if m_ConstantFrameTime==true + bool m_WireframeMode; // if true, then D3DRS_FILLMODE==D3DFILL_WIREFRAME else D3DRS_FILLMODE==D3DFILL_SOLID + bool m_AutoChangeAdapter; // if true, then the adapter will automatically change if the window is different monitor + bool m_WindowCreatedWithDefaultPositions; // if true, then CW_USEDEFAULT was used and the window should be moved to the right adapter + int m_ExitCode; // the exit code to be returned to the command line + + bool m_DXUTInited; // if true, then DXUTInit() has succeeded + bool m_WindowCreated; // if true, then DXUTCreateWindow() or DXUTSetWindow() has succeeded + bool m_DeviceCreated; // if true, then DXUTCreateDevice() or DXUTSetD3D*Device() has succeeded + + bool m_DXUTInitCalled; // if true, then DXUTInit() was called + bool m_WindowCreateCalled; // if true, then DXUTCreateWindow() or DXUTSetWindow() was called + bool m_DeviceCreateCalled; // if true, then DXUTCreateDevice() or DXUTSetD3D*Device() was called + + bool m_DeviceObjectsCreated; // if true, then DeviceCreated callback has been called (if non-NULL) + bool m_DeviceObjectsReset; // if true, then DeviceReset callback has been called (if non-NULL) + bool m_InsideDeviceCallback; // if true, then the framework is inside an app device callback + bool m_InsideMainloop; // if true, then the framework is inside the main loop + bool m_Active; // if true, then the app is the active top level window + bool m_TimePaused; // if true, then time is paused + bool m_RenderingPaused; // if true, then rendering is paused + int m_PauseRenderingCount; // pause rendering ref count + int m_PauseTimeCount; // pause time ref count + bool m_DeviceLost; // if true, then the device is lost and needs to be reset + bool m_NotifyOnMouseMove; // if true, include WM_MOUSEMOVE in mousecallback + bool m_Automation; // if true, automation is enabled + bool m_InSizeMove; // if true, app is inside a WM_ENTERSIZEMOVE + UINT m_TimerLastID; // last ID of the DXUT timer + bool m_MessageWhenD3D11NotAvailable; + + D3D_FEATURE_LEVEL m_OverrideForceFeatureLevel; // if != -1, then overrid to use a featurelevel + WCHAR m_ScreenShotName[256]; // command line screen shot name + bool m_SaveScreenShot; // command line save screen shot + bool m_ExitAfterScreenShot; // command line exit after screen shot + + int m_OverrideForceAPI; // if != -1, then override to use this Direct3D API version + int m_OverrideAdapterOrdinal; // if != -1, then override to use this adapter ordinal + bool m_OverrideWindowed; // if true, then force to start windowed + int m_OverrideOutput; // if != -1, then override to use the particular output on the adapter + bool m_OverrideFullScreen; // if true, then force to start full screen + int m_OverrideStartX; // if != -1, then override to this X position of the window + int m_OverrideStartY; // if != -1, then override to this Y position of the window + int m_OverrideWidth; // if != 0, then override to this width + int m_OverrideHeight; // if != 0, then override to this height + bool m_OverrideForceHAL; // if true, then force to HAL device (failing if one doesn't exist) + bool m_OverrideForceREF; // if true, then force to REF device (failing if one doesn't exist) + bool m_OverrideConstantFrameTime; // if true, then force to constant frame time + float m_OverrideConstantTimePerFrame; // the constant time per frame in seconds if m_OverrideConstantFrameTime==true + int m_OverrideQuitAfterFrame; // if != 0, then it will force the app to quit after that frame + int m_OverrideForceVsync; // if == 0, then it will force the app to use D3DPRESENT_INTERVAL_IMMEDIATE, if == 1 force use of D3DPRESENT_INTERVAL_DEFAULT + bool m_OverrideRelaunchMCE; // if true, then force relaunch of MCE at exit + bool m_AppCalledWasKeyPressed; // true if the app ever calls DXUTWasKeyPressed(). Allows for optimzation + bool m_ReleasingSwapChain; // if true, the app is releasing its swapchain + bool m_IsInGammaCorrectMode; // Tell DXUTRes and DXUTMisc that we are in gamma correct mode + + LPDXUTCALLBACKMODIFYDEVICESETTINGS m_ModifyDeviceSettingsFunc; // modify Direct3D device settings callback + LPDXUTCALLBACKDEVICEREMOVED m_DeviceRemovedFunc; // Direct3D device removed callback + LPDXUTCALLBACKFRAMEMOVE m_FrameMoveFunc; // frame move callback + LPDXUTCALLBACKKEYBOARD m_KeyboardFunc; // keyboard callback + LPDXUTCALLBACKMOUSE m_MouseFunc; // mouse callback + LPDXUTCALLBACKMSGPROC m_WindowMsgFunc; // window messages callback + + LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE m_IsD3D9DeviceAcceptableFunc; // D3D9 is device acceptable callback + LPDXUTCALLBACKD3D9DEVICECREATED m_D3D9DeviceCreatedFunc; // D3D9 device created callback + LPDXUTCALLBACKD3D9DEVICERESET m_D3D9DeviceResetFunc; // D3D9 device reset callback + LPDXUTCALLBACKD3D9DEVICELOST m_D3D9DeviceLostFunc; // D3D9 device lost callback + LPDXUTCALLBACKD3D9DEVICEDESTROYED m_D3D9DeviceDestroyedFunc; // D3D9 device destroyed callback + LPDXUTCALLBACKD3D9FRAMERENDER m_D3D9FrameRenderFunc; // D3D9 frame render callback + + LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE m_IsD3D11DeviceAcceptableFunc; // D3D11 is device acceptable callback + LPDXUTCALLBACKD3D11DEVICECREATED m_D3D11DeviceCreatedFunc; // D3D11 device created callback + LPDXUTCALLBACKD3D11SWAPCHAINRESIZED m_D3D11SwapChainResizedFunc; // D3D11 SwapChain reset callback + LPDXUTCALLBACKD3D11SWAPCHAINRELEASING m_D3D11SwapChainReleasingFunc; // D3D11 SwapChain lost callback + LPDXUTCALLBACKD3D11DEVICEDESTROYED m_D3D11DeviceDestroyedFunc; // D3D11 device destroyed callback + LPDXUTCALLBACKD3D11FRAMERENDER m_D3D11FrameRenderFunc; // D3D11 frame render callback + + + void* m_ModifyDeviceSettingsFuncUserContext; // user context for modify Direct3D device settings callback + void* m_DeviceRemovedFuncUserContext; // user context for Direct3D device removed callback + void* m_FrameMoveFuncUserContext; // user context for frame move callback + void* m_KeyboardFuncUserContext; // user context for keyboard callback + void* m_MouseFuncUserContext; // user context for mouse callback + void* m_WindowMsgFuncUserContext; // user context for window messages callback + + void* m_IsD3D9DeviceAcceptableFuncUserContext; // user context for is D3D9 device acceptable callback + void* m_D3D9DeviceCreatedFuncUserContext; // user context for D3D9 device created callback + void* m_D3D9DeviceResetFuncUserContext; // user context for D3D9 device reset callback + void* m_D3D9DeviceLostFuncUserContext; // user context for D3D9 device lost callback + void* m_D3D9DeviceDestroyedFuncUserContext; // user context for D3D9 device destroyed callback + void* m_D3D9FrameRenderFuncUserContext; // user context for D3D9 frame render callback + + void* m_IsD3D11DeviceAcceptableFuncUserContext; // user context for is D3D11 device acceptable callback + void* m_D3D11DeviceCreatedFuncUserContext; // user context for D3D11 device created callback + void* m_D3D11SwapChainResizedFuncUserContext; // user context for D3D11 SwapChain resized callback + void* m_D3D11SwapChainReleasingFuncUserContext; // user context for D3D11 SwapChain releasing callback + void* m_D3D11DeviceDestroyedFuncUserContext; // user context for D3D11 device destroyed callback + void* m_D3D11FrameRenderFuncUserContext; // user context for D3D11 frame render callback + + bool m_Keys[256]; // array of key state + bool m_LastKeys[256]; // array of last key state + bool m_MouseButtons[5]; // array of mouse states + + CGrowableArray* m_TimerList; // list of DXUT_TIMER structs + WCHAR m_StaticFrameStats[256]; // static part of frames stats + WCHAR m_FPSStats[64]; // fps stats + WCHAR m_FrameStats[256]; // frame stats (fps, width, etc) + WCHAR m_DeviceStats[256]; // device stats (description, device type, etc) + WCHAR m_WindowTitle[256]; // window title + }; + + STATE m_state; + +public: + DXUTState() { Create(); } + ~DXUTState() { Destroy(); } + + void Create() + { + g_bThreadSafe = true; + InitializeCriticalSectionAndSpinCount( &g_cs, 1000 ); + + ZeroMemory( &m_state, sizeof( STATE ) ); + m_state.m_OverrideStartX = -1; + m_state.m_OverrideStartY = -1; + m_state.m_OverrideForceFeatureLevel = (D3D_FEATURE_LEVEL)0; + m_state.m_ScreenShotName[0] = 0; + m_state.m_SaveScreenShot = false; + m_state.m_ExitAfterScreenShot = false; + m_state.m_OverrideForceAPI = -1; + m_state.m_OverrideAdapterOrdinal = -1; + m_state.m_OverrideOutput = -1; + m_state.m_OverrideForceVsync = -1; + m_state.m_AutoChangeAdapter = true; + m_state.m_ShowMsgBoxOnError = true; + m_state.m_AllowShortcutKeysWhenWindowed = true; + m_state.m_Active = true; + m_state.m_CallDefWindowProc = true; + m_state.m_HandleEscape = true; + m_state.m_HandleAltEnter = true; + m_state.m_HandlePause = true; + m_state.m_IsInGammaCorrectMode = true; + m_state.m_FPS = 1.0f; + m_state.m_MessageWhenD3D11NotAvailable = true; + } + + void Destroy() + { + SAFE_DELETE( m_state.m_TimerList ); + DXUTShutdown(); + DeleteCriticalSection( &g_cs ); + } + + // Macros to define access functions for thread safe access into m_state + GET_SET_ACCESSOR( DXUTDeviceSettings*, CurrentDeviceSettings ); + + // D3D9 specific + GET_SET_ACCESSOR( IDirect3D9*, D3D9 ); + GET_SET_ACCESSOR( IDirect3DDevice9*, D3D9Device ); + GETP_SETP_ACCESSOR( D3DSURFACE_DESC, BackBufferSurfaceDesc9 ); + GETP_SETP_ACCESSOR( D3DCAPS9, Caps ); + + // D3D11 specific + GET_SET_ACCESSOR( IDXGIFactory1*, DXGIFactory ); + GET_SET_ACCESSOR( IDXGIAdapter1*, DXGIAdapter ); + GET_SET_ACCESSOR( IDXGIOutput**, DXGIOutputArray ); + GET_SET_ACCESSOR( UINT, DXGIOutputArraySize ); + GET_SET_ACCESSOR( IDXGISwapChain*, DXGISwapChain ); + GETP_SETP_ACCESSOR( DXGI_SURFACE_DESC, BackBufferSurfaceDescDXGI ); + GET_SET_ACCESSOR( bool, RenderingOccluded ); + GET_SET_ACCESSOR( bool, DoNotStoreBufferSize ); + + // D3D11 specific + GET_SET_ACCESSOR( bool, D3D11Available ); + GET_SET_ACCESSOR( ID3D11Device*, D3D11Device ); + GET_SET_ACCESSOR( ID3D11DeviceContext*, D3D11DeviceContext ); + GET_SET_ACCESSOR( D3D_FEATURE_LEVEL, D3D11FeatureLevel ); + GET_SET_ACCESSOR( ID3D11Texture2D*, D3D11DepthStencil ); + GET_SET_ACCESSOR( ID3D11DepthStencilView*, D3D11DepthStencilView ); + GET_SET_ACCESSOR( ID3D11RenderTargetView*, D3D11RenderTargetView ); + GET_SET_ACCESSOR( ID3D11RasterizerState*, D3D11RasterizerState ); + + + GET_SET_ACCESSOR( HWND, HWNDFocus ); + GET_SET_ACCESSOR( HWND, HWNDDeviceFullScreen ); + GET_SET_ACCESSOR( HWND, HWNDDeviceWindowed ); + GET_SET_ACCESSOR( HMONITOR, AdapterMonitor ); + GET_SET_ACCESSOR( HMENU, Menu ); + + + GET_SET_ACCESSOR( UINT, FullScreenBackBufferWidthAtModeChange ); + GET_SET_ACCESSOR( UINT, FullScreenBackBufferHeightAtModeChange ); + GET_SET_ACCESSOR( UINT, WindowBackBufferWidthAtModeChange ); + GET_SET_ACCESSOR( UINT, WindowBackBufferHeightAtModeChange ); + GETP_SETP_ACCESSOR( WINDOWPLACEMENT, WindowedPlacement ); + GET_SET_ACCESSOR( DWORD, WindowedStyleAtModeChange ); + GET_SET_ACCESSOR( bool, TopmostWhileWindowed ); + GET_SET_ACCESSOR( bool, Minimized ); + GET_SET_ACCESSOR( bool, Maximized ); + GET_SET_ACCESSOR( bool, MinimizedWhileFullscreen ); + GET_SET_ACCESSOR( bool, IgnoreSizeChange ); + + GET_SET_ACCESSOR( double, Time ); + GET_SET_ACCESSOR( double, AbsoluteTime ); + GET_SET_ACCESSOR( float, ElapsedTime ); + + GET_SET_ACCESSOR( HINSTANCE, HInstance ); + GET_SET_ACCESSOR( double, LastStatsUpdateTime ); + GET_SET_ACCESSOR( DWORD, LastStatsUpdateFrames ); + GET_SET_ACCESSOR( float, FPS ); + GET_SET_ACCESSOR( int, CurrentFrameNumber ); + GET_SET_ACCESSOR( HHOOK, KeyboardHook ); + GET_SET_ACCESSOR( bool, AllowShortcutKeysWhenFullscreen ); + GET_SET_ACCESSOR( bool, AllowShortcutKeysWhenWindowed ); + GET_SET_ACCESSOR( bool, AllowShortcutKeys ); + GET_SET_ACCESSOR( bool, CallDefWindowProc ); + GET_SET_ACCESSOR( STICKYKEYS, StartupStickyKeys ); + GET_SET_ACCESSOR( TOGGLEKEYS, StartupToggleKeys ); + GET_SET_ACCESSOR( FILTERKEYS, StartupFilterKeys ); + + GET_SET_ACCESSOR( bool, AppSupportsD3D9Override ); + GET_SET_ACCESSOR( bool, AppSupportsD3D11Override ); + GET_SET_ACCESSOR( bool, UseD3DVersionOverride ); + + GET_SET_ACCESSOR( bool, HandleEscape ); + GET_SET_ACCESSOR( bool, HandleAltEnter ); + GET_SET_ACCESSOR( bool, HandlePause ); + GET_SET_ACCESSOR( bool, ShowMsgBoxOnError ); + GET_SET_ACCESSOR( bool, NoStats ); + GET_SET_ACCESSOR( bool, ClipCursorWhenFullScreen ); + GET_SET_ACCESSOR( bool, ShowCursorWhenFullScreen ); + GET_SET_ACCESSOR( bool, ConstantFrameTime ); + GET_SET_ACCESSOR( float, TimePerFrame ); + GET_SET_ACCESSOR( bool, WireframeMode ); + GET_SET_ACCESSOR( bool, AutoChangeAdapter ); + GET_SET_ACCESSOR( bool, WindowCreatedWithDefaultPositions ); + GET_SET_ACCESSOR( int, ExitCode ); + + GET_SET_ACCESSOR( bool, DXUTInited ); + GET_SET_ACCESSOR( bool, WindowCreated ); + GET_SET_ACCESSOR( bool, DeviceCreated ); + GET_SET_ACCESSOR( bool, DXUTInitCalled ); + GET_SET_ACCESSOR( bool, WindowCreateCalled ); + GET_SET_ACCESSOR( bool, DeviceCreateCalled ); + GET_SET_ACCESSOR( bool, InsideDeviceCallback ); + GET_SET_ACCESSOR( bool, InsideMainloop ); + GET_SET_ACCESSOR( bool, DeviceObjectsCreated ); + GET_SET_ACCESSOR( bool, DeviceObjectsReset ); + GET_SET_ACCESSOR( bool, Active ); + GET_SET_ACCESSOR( bool, RenderingPaused ); + GET_SET_ACCESSOR( bool, TimePaused ); + GET_SET_ACCESSOR( int, PauseRenderingCount ); + GET_SET_ACCESSOR( int, PauseTimeCount ); + GET_SET_ACCESSOR( bool, DeviceLost ); + GET_SET_ACCESSOR( bool, NotifyOnMouseMove ); + GET_SET_ACCESSOR( bool, Automation ); + GET_SET_ACCESSOR( bool, InSizeMove ); + GET_SET_ACCESSOR( UINT, TimerLastID ); + GET_SET_ACCESSOR( bool, MessageWhenD3D11NotAvailable ); + GET_SET_ACCESSOR( bool, AppCalledWasKeyPressed ); + + GET_SET_ACCESSOR( D3D_FEATURE_LEVEL, OverrideForceFeatureLevel ); + GET_ACCESSOR( WCHAR*, ScreenShotName ); + GET_SET_ACCESSOR( bool, SaveScreenShot ); + GET_SET_ACCESSOR( bool, ExitAfterScreenShot ); + + + GET_SET_ACCESSOR( int, OverrideForceAPI ); + GET_SET_ACCESSOR( int, OverrideAdapterOrdinal ); + GET_SET_ACCESSOR( bool, OverrideWindowed ); + GET_SET_ACCESSOR( int, OverrideOutput ); + GET_SET_ACCESSOR( bool, OverrideFullScreen ); + GET_SET_ACCESSOR( int, OverrideStartX ); + GET_SET_ACCESSOR( int, OverrideStartY ); + GET_SET_ACCESSOR( int, OverrideWidth ); + GET_SET_ACCESSOR( int, OverrideHeight ); + GET_SET_ACCESSOR( bool, OverrideForceHAL ); + GET_SET_ACCESSOR( bool, OverrideForceREF ); + GET_SET_ACCESSOR( bool, OverrideConstantFrameTime ); + GET_SET_ACCESSOR( float, OverrideConstantTimePerFrame ); + GET_SET_ACCESSOR( int, OverrideQuitAfterFrame ); + GET_SET_ACCESSOR( int, OverrideForceVsync ); + GET_SET_ACCESSOR( bool, OverrideRelaunchMCE ); + GET_SET_ACCESSOR( bool, ReleasingSwapChain ); + GET_SET_ACCESSOR( bool, IsInGammaCorrectMode ); + + GET_SET_ACCESSOR( LPDXUTCALLBACKMODIFYDEVICESETTINGS, ModifyDeviceSettingsFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICEREMOVED, DeviceRemovedFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKFRAMEMOVE, FrameMoveFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKKEYBOARD, KeyboardFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKMOUSE, MouseFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKMSGPROC, WindowMsgFunc ); + + GET_SET_ACCESSOR( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE, IsD3D9DeviceAcceptableFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D9DEVICECREATED, D3D9DeviceCreatedFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D9DEVICERESET, D3D9DeviceResetFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D9DEVICELOST, D3D9DeviceLostFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D9DEVICEDESTROYED, D3D9DeviceDestroyedFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D9FRAMERENDER, D3D9FrameRenderFunc ); + + GET_SET_ACCESSOR( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE, IsD3D11DeviceAcceptableFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D11DEVICECREATED, D3D11DeviceCreatedFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D11SWAPCHAINRESIZED, D3D11SwapChainResizedFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D11SWAPCHAINRELEASING, D3D11SwapChainReleasingFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D11DEVICEDESTROYED, D3D11DeviceDestroyedFunc ); + GET_SET_ACCESSOR( LPDXUTCALLBACKD3D11FRAMERENDER, D3D11FrameRenderFunc ); + + GET_SET_ACCESSOR( void*, ModifyDeviceSettingsFuncUserContext ); + GET_SET_ACCESSOR( void*, DeviceRemovedFuncUserContext ); + GET_SET_ACCESSOR( void*, FrameMoveFuncUserContext ); + GET_SET_ACCESSOR( void*, KeyboardFuncUserContext ); + GET_SET_ACCESSOR( void*, MouseFuncUserContext ); + GET_SET_ACCESSOR( void*, WindowMsgFuncUserContext ); + + GET_SET_ACCESSOR( void*, IsD3D9DeviceAcceptableFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D9DeviceCreatedFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D9DeviceResetFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D9DeviceLostFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D9DeviceDestroyedFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D9FrameRenderFuncUserContext ); + + GET_SET_ACCESSOR( void*, IsD3D11DeviceAcceptableFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D11DeviceCreatedFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D11DeviceDestroyedFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D11SwapChainResizedFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D11SwapChainReleasingFuncUserContext ); + GET_SET_ACCESSOR( void*, D3D11FrameRenderFuncUserContext ); + + GET_SET_ACCESSOR( CGrowableArray*, TimerList ); + GET_ACCESSOR( bool*, Keys ); + GET_ACCESSOR( bool*, LastKeys ); + GET_ACCESSOR( bool*, MouseButtons ); + GET_ACCESSOR( WCHAR*, StaticFrameStats ); + GET_ACCESSOR( WCHAR*, FPSStats ); + GET_ACCESSOR( WCHAR*, FrameStats ); + GET_ACCESSOR( WCHAR*, DeviceStats ); + GET_ACCESSOR( WCHAR*, WindowTitle ); +}; + + +//-------------------------------------------------------------------------------------- +// Global state +//-------------------------------------------------------------------------------------- +DXUTState* g_pDXUTState = NULL; + +HRESULT WINAPI DXUTCreateState() +{ + if( g_pDXUTState == NULL ) + { + g_pDXUTState = new DXUTState; + if( NULL == g_pDXUTState ) + return E_OUTOFMEMORY; + } + return S_OK; +} + +void WINAPI DXUTDestroyState() +{ + SAFE_DELETE( g_pDXUTState ); +} + +class DXUTMemoryHelper +{ +public: + DXUTMemoryHelper() { DXUTCreateState(); } + ~DXUTMemoryHelper() { DXUTDestroyState(); } +}; + + +DXUTState& GetDXUTState() +{ + // This class will auto create the memory when its first accessed and delete it after the program exits WinMain. + // However the application can also call DXUTCreateState() & DXUTDestroyState() independantly if its wants + static DXUTMemoryHelper memory; + + return *g_pDXUTState; +} + + +//-------------------------------------------------------------------------------------- +// Internal functions forward declarations +//-------------------------------------------------------------------------------------- +void DXUTParseCommandLine( __inout WCHAR* strCommandLine, + bool bIgnoreFirstCommand = true ); +bool DXUTIsNextArg( __inout WCHAR*& strCmdLine, + __inout WCHAR* strArg ); +bool DXUTGetCmdParam( __inout WCHAR*& strCmdLine, + __inout_ecount(MAX_PATH) WCHAR* strFlag ); +void DXUTAllowShortcutKeys( bool bAllowKeys ); +void DXUTUpdateStaticFrameStats(); +void DXUTUpdateFrameStats(); + +LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); +void DXUTHandleTimers(); +void DXUTDisplayErrorMessage( HRESULT hr ); +int DXUTMapButtonToArrayIndex( BYTE vButton ); + +HRESULT DXUTChangeDevice( DXUTDeviceSettings* pNewDeviceSettings, + IDirect3DDevice9* pd3d9DeviceFromApp, + ID3D11Device* pd3d11DeviceFromApp, + bool bForceRecreate, + bool bClipWindowToSingleAdapter ); + +bool DXUTCanDeviceBeReset( DXUTDeviceSettings* pOldDeviceSettings, + DXUTDeviceSettings* pNewDeviceSettings, + IDirect3DDevice9* pd3d9DeviceFromApp, + ID3D11Device* pd3d11DeviceFromApp ); + + +HRESULT DXUTDelayLoadDXGI(); +HRESULT DXUTDelayLoadD3D9(); +HRESULT DXUTSnapDeviceSettingsToEnumDevice( DXUTDeviceSettings* pDeviceSettings, bool forceEnum, D3D_FEATURE_LEVEL forceFL = D3D_FEATURE_LEVEL(0) ); +void DXUTUpdateDeviceSettingsWithOverrides( DXUTDeviceSettings* pDeviceSettings ); +void DXUTCheckForDXGIFullScreenSwitch(); +void DXUTResizeDXGIBuffers( UINT Width, UINT Height, BOOL bFullscreen ); +void DXUTCheckForDXGIBufferChange(); +void DXUTCheckForWindowSizeChange(); +void DXUTCheckForWindowChangingMonitors(); +void DXUTCleanup3DEnvironment( bool bReleaseSettings ); +HMONITOR DXUTGetMonitorFromAdapter( DXUTDeviceSettings* pDeviceSettings ); +HRESULT DXUTGetAdapterOrdinalFromMonitor( HMONITOR hMonitor, UINT* pAdapterOrdinal ); +HRESULT DXUTGetOutputOrdinalFromMonitor( HMONITOR hMonitor, UINT* pOutputOrdinal ); +HRESULT DXUTHandleDeviceRemoved(); +void DXUTUpdateBackBufferDesc(); +void DXUTSetupCursor(); + +// Direct3D 9 +HRESULT DXUTCreate3DEnvironment9( IDirect3DDevice9* pd3dDeviceFromApp ); +HRESULT DXUTReset3DEnvironment9(); +void DXUTRender3DEnvironment9(); +void DXUTCleanup3DEnvironment9( bool bReleaseSettings = true ); +HRESULT DXUTSetD3D9DeviceCursor( IDirect3DDevice9* pd3dDevice, HCURSOR hCursor, bool bAddWatermark ); +void DXUTUpdateD3D9DeviceStats( D3DDEVTYPE DeviceType, DWORD BehaviorFlags, + D3DADAPTER_IDENTIFIER9* pAdapterIdentifier ); +HRESULT DXUTFindD3D9AdapterFormat( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT BackBufferFormat, + BOOL Windowed, D3DFORMAT* pAdapterFormat ); + +// Direct3D 11 +HRESULT DXUTCreateD3D11Views( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDeviceContext, DXUTDeviceSettings* pDeviceSettings ); +HRESULT DXUTCreate3DEnvironment11( ID3D11Device* pd3dDeviceFromApp ); +HRESULT DXUTReset3DEnvironment11(); +void DXUTRender3DEnvironment11(); +void DXUTCleanup3DEnvironment11( bool bReleaseSettings = true ); +void DXUTUpdateD3D11DeviceStats( D3D_DRIVER_TYPE DeviceType, DXGI_ADAPTER_DESC* pAdapterDesc ); + + +//-------------------------------------------------------------------------------------- +// Internal helper functions +//-------------------------------------------------------------------------------------- +bool DXUTIsD3D9( DXUTDeviceSettings* pDeviceSettings ) { return (pDeviceSettings && pDeviceSettings->ver == DXUT_D3D9_DEVICE ); }; +bool DXUTIsCurrentDeviceD3D9() { DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); return DXUTIsD3D9(pDeviceSettings); }; +UINT DXUTGetBackBufferWidthFromDS( DXUTDeviceSettings* pNewDeviceSettings ) +{ + if( DXUTIsD3D9( pNewDeviceSettings ) ) + return pNewDeviceSettings->d3d9.pp.BackBufferWidth; + else + return pNewDeviceSettings->d3d11.sd.BufferDesc.Width; +} +UINT DXUTGetBackBufferHeightFromDS( DXUTDeviceSettings* pNewDeviceSettings ) +{ + if( DXUTIsD3D9(pNewDeviceSettings) ) + return pNewDeviceSettings->d3d9.pp.BackBufferHeight; + else + return pNewDeviceSettings->d3d11.sd.BufferDesc.Height; +} +bool DXUTGetIsWindowedFromDS( DXUTDeviceSettings* pNewDeviceSettings ) +{ + if (!pNewDeviceSettings) + return true; + + if( DXUTIsD3D9(pNewDeviceSettings) ) + return pNewDeviceSettings->d3d9.pp.Windowed ? true : false; + else + return pNewDeviceSettings->d3d11.sd.Windowed ? true : false; +} + + +//-------------------------------------------------------------------------------------- +// External state access functions +//-------------------------------------------------------------------------------------- +BOOL WINAPI DXUTGetMSAASwapChainCreated() { + DXUTDeviceSettings *psettings = GetDXUTState().GetCurrentDeviceSettings(); + if (psettings->ver == DXUT_D3D11_DEVICE) { + return psettings->d3d11.sd.SampleDesc.Count > 1; + }else if (psettings->ver == DXUT_D3D9_DEVICE) { + return (psettings->d3d9.pp.MultiSampleType >= D3DMULTISAMPLE_2_SAMPLES); + } + else return false; +} +IDirect3DDevice9* WINAPI DXUTGetD3D9Device() { return GetDXUTState().GetD3D9Device(); } +const D3DSURFACE_DESC* WINAPI DXUTGetD3D9BackBufferSurfaceDesc() { return GetDXUTState().GetBackBufferSurfaceDesc9(); } +const D3DCAPS9* WINAPI DXUTGetD3D9DeviceCaps() { return GetDXUTState().GetCaps(); } +ID3D11Device* WINAPI DXUTGetD3D11Device() { return GetDXUTState().GetD3D11Device(); } +D3D_FEATURE_LEVEL WINAPI DXUTGetD3D11DeviceFeatureLevel() { return GetDXUTState().GetD3D11FeatureLevel(); } +ID3D11DeviceContext* WINAPI DXUTGetD3D11DeviceContext() { return GetDXUTState().GetD3D11DeviceContext(); } +IDXGISwapChain* WINAPI DXUTGetDXGISwapChain() { return GetDXUTState().GetDXGISwapChain(); } +ID3D11RenderTargetView* WINAPI DXUTGetD3D11RenderTargetView() { return GetDXUTState().GetD3D11RenderTargetView(); } +ID3D11DepthStencilView* WINAPI DXUTGetD3D11DepthStencilView() { return GetDXUTState().GetD3D11DepthStencilView(); } +const DXGI_SURFACE_DESC* WINAPI DXUTGetDXGIBackBufferSurfaceDesc() { return GetDXUTState().GetBackBufferSurfaceDescDXGI(); } +HINSTANCE WINAPI DXUTGetHINSTANCE() { return GetDXUTState().GetHInstance(); } +HWND WINAPI DXUTGetHWND() { return DXUTIsWindowed() ? GetDXUTState().GetHWNDDeviceWindowed() : GetDXUTState().GetHWNDDeviceFullScreen(); } +HWND WINAPI DXUTGetHWNDFocus() { return GetDXUTState().GetHWNDFocus(); } +HWND WINAPI DXUTGetHWNDDeviceFullScreen() { return GetDXUTState().GetHWNDDeviceFullScreen(); } +HWND WINAPI DXUTGetHWNDDeviceWindowed() { return GetDXUTState().GetHWNDDeviceWindowed(); } +RECT WINAPI DXUTGetWindowClientRect() { RECT rc; GetClientRect( DXUTGetHWND(), &rc ); return rc; } +LONG WINAPI DXUTGetWindowWidth() { RECT rc = DXUTGetWindowClientRect(); return ((LONG)rc.right - rc.left); } +LONG WINAPI DXUTGetWindowHeight() { RECT rc = DXUTGetWindowClientRect(); return ((LONG)rc.bottom - rc.top); } +RECT WINAPI DXUTGetWindowClientRectAtModeChange() { RECT rc = { 0, 0, GetDXUTState().GetWindowBackBufferWidthAtModeChange(), GetDXUTState().GetWindowBackBufferHeightAtModeChange() }; return rc; } +RECT WINAPI DXUTGetFullsceenClientRectAtModeChange() { RECT rc = { 0, 0, GetDXUTState().GetFullScreenBackBufferWidthAtModeChange(), GetDXUTState().GetFullScreenBackBufferHeightAtModeChange() }; return rc; } +double WINAPI DXUTGetTime() { return GetDXUTState().GetTime(); } +float WINAPI DXUTGetElapsedTime() { return GetDXUTState().GetElapsedTime(); } +float WINAPI DXUTGetFPS() { return GetDXUTState().GetFPS(); } +LPCWSTR WINAPI DXUTGetWindowTitle() { return GetDXUTState().GetWindowTitle(); } +LPCWSTR WINAPI DXUTGetDeviceStats() { return GetDXUTState().GetDeviceStats(); } +bool WINAPI DXUTIsRenderingPaused() { return GetDXUTState().GetPauseRenderingCount() > 0; } +bool WINAPI DXUTIsTimePaused() { return GetDXUTState().GetPauseTimeCount() > 0; } +bool WINAPI DXUTIsActive() { return GetDXUTState().GetActive(); } +int WINAPI DXUTGetExitCode() { return GetDXUTState().GetExitCode(); } +bool WINAPI DXUTGetShowMsgBoxOnError() { return GetDXUTState().GetShowMsgBoxOnError(); } +bool WINAPI DXUTGetAutomation() { return GetDXUTState().GetAutomation(); } +bool WINAPI DXUTIsWindowed() { return DXUTGetIsWindowedFromDS( GetDXUTState().GetCurrentDeviceSettings() ); } +bool WINAPI DXUTIsInGammaCorrectMode() { return GetDXUTState().GetIsInGammaCorrectMode(); } +IDirect3D9* WINAPI DXUTGetD3D9Object() { DXUTDelayLoadD3D9(); return GetDXUTState().GetD3D9(); } +IDXGIFactory1* WINAPI DXUTGetDXGIFactory() { DXUTDelayLoadDXGI(); return GetDXUTState().GetDXGIFactory(); } +bool WINAPI DXUTIsD3D11Available() { DXUTDelayLoadDXGI(); return GetDXUTState().GetD3D11Available(); } +bool WINAPI DXUTIsAppRenderingWithD3D9() { return (GetDXUTState().GetD3D9Device() != NULL); } +bool WINAPI DXUTIsAppRenderingWithD3D11() { return (GetDXUTState().GetD3D11Device() != NULL); } + +//-------------------------------------------------------------------------------------- +// External callback setup functions +//-------------------------------------------------------------------------------------- + +// General callbacks +void WINAPI DXUTSetCallbackDeviceChanging( LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallback, void* pUserContext ) { GetDXUTState().SetModifyDeviceSettingsFunc( pCallback ); GetDXUTState().SetModifyDeviceSettingsFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackDeviceRemoved( LPDXUTCALLBACKDEVICEREMOVED pCallback, void* pUserContext ) { GetDXUTState().SetDeviceRemovedFunc( pCallback ); GetDXUTState().SetDeviceRemovedFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackFrameMove( LPDXUTCALLBACKFRAMEMOVE pCallback, void* pUserContext ) { GetDXUTState().SetFrameMoveFunc( pCallback ); GetDXUTState().SetFrameMoveFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackKeyboard( LPDXUTCALLBACKKEYBOARD pCallback, void* pUserContext ) { GetDXUTState().SetKeyboardFunc( pCallback ); GetDXUTState().SetKeyboardFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackMouse( LPDXUTCALLBACKMOUSE pCallback, bool bIncludeMouseMove, void* pUserContext ) { GetDXUTState().SetMouseFunc( pCallback ); GetDXUTState().SetNotifyOnMouseMove( bIncludeMouseMove ); GetDXUTState().SetMouseFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallback, void* pUserContext ) { GetDXUTState().SetWindowMsgFunc( pCallback ); GetDXUTState().SetWindowMsgFuncUserContext( pUserContext ); } + +// Direct3D 9 callbacks +void WINAPI DXUTSetCallbackD3D9DeviceAcceptable( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE pCallback, void* pUserContext ) { GetDXUTState().SetIsD3D9DeviceAcceptableFunc( pCallback ); GetDXUTState().SetIsD3D9DeviceAcceptableFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D9DeviceCreated( LPDXUTCALLBACKD3D9DEVICECREATED pCallback, void* pUserContext ) { GetDXUTState().SetD3D9DeviceCreatedFunc( pCallback ); GetDXUTState().SetD3D9DeviceCreatedFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D9DeviceReset( LPDXUTCALLBACKD3D9DEVICERESET pCallback, void* pUserContext ) { GetDXUTState().SetD3D9DeviceResetFunc( pCallback ); GetDXUTState().SetD3D9DeviceResetFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D9DeviceLost( LPDXUTCALLBACKD3D9DEVICELOST pCallback, void* pUserContext ) { GetDXUTState().SetD3D9DeviceLostFunc( pCallback ); GetDXUTState().SetD3D9DeviceLostFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D9DeviceDestroyed( LPDXUTCALLBACKD3D9DEVICEDESTROYED pCallback, void* pUserContext ) { GetDXUTState().SetD3D9DeviceDestroyedFunc( pCallback ); GetDXUTState().SetD3D9DeviceDestroyedFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D9FrameRender( LPDXUTCALLBACKD3D9FRAMERENDER pCallback, void* pUserContext ) { GetDXUTState().SetD3D9FrameRenderFunc( pCallback ); GetDXUTState().SetD3D9FrameRenderFuncUserContext( pUserContext ); } +void DXUTGetCallbackD3D9DeviceAcceptable( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE* ppCallback, void** ppUserContext ) { *ppCallback = GetDXUTState().GetIsD3D9DeviceAcceptableFunc(); *ppUserContext = GetDXUTState().GetIsD3D9DeviceAcceptableFuncUserContext(); } + +// Direct3D 11 callbacks +void WINAPI DXUTSetCallbackD3D11DeviceAcceptable( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE pCallback, void* pUserContext ) { GetDXUTState().SetIsD3D11DeviceAcceptableFunc( pCallback ); GetDXUTState().SetIsD3D11DeviceAcceptableFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D11DeviceCreated( LPDXUTCALLBACKD3D11DEVICECREATED pCallback, void* pUserContext ) { GetDXUTState().SetD3D11DeviceCreatedFunc( pCallback ); GetDXUTState().SetD3D11DeviceCreatedFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D11SwapChainResized( LPDXUTCALLBACKD3D11SWAPCHAINRESIZED pCallback, void* pUserContext ) { GetDXUTState().SetD3D11SwapChainResizedFunc( pCallback ); GetDXUTState().SetD3D11SwapChainResizedFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D11FrameRender( LPDXUTCALLBACKD3D11FRAMERENDER pCallback, void* pUserContext ) { GetDXUTState().SetD3D11FrameRenderFunc( pCallback ); GetDXUTState().SetD3D11FrameRenderFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D11SwapChainReleasing( LPDXUTCALLBACKD3D11SWAPCHAINRELEASING pCallback, void* pUserContext ) { GetDXUTState().SetD3D11SwapChainReleasingFunc( pCallback ); GetDXUTState().SetD3D11SwapChainReleasingFuncUserContext( pUserContext ); } +void WINAPI DXUTSetCallbackD3D11DeviceDestroyed( LPDXUTCALLBACKD3D11DEVICEDESTROYED pCallback, void* pUserContext ) { GetDXUTState().SetD3D11DeviceDestroyedFunc( pCallback ); GetDXUTState().SetD3D11DeviceDestroyedFuncUserContext( pUserContext ); } +void DXUTGetCallbackD3D11DeviceAcceptable( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE* ppCallback, void** ppUserContext ) { *ppCallback = GetDXUTState().GetIsD3D11DeviceAcceptableFunc(); *ppUserContext = GetDXUTState().GetIsD3D11DeviceAcceptableFuncUserContext(); } + + +//-------------------------------------------------------------------------------------- +// Optionally parses the command line and sets if default hotkeys are handled +// +// Possible command line parameters are: +// -forcefeaturelevel:fl forces app to use a specified direct3D11 feature level +// -screenshotexit:filename save a screenshot to the filename.bmp and exit. +// -forceapi:# forces app to use specified Direct3D API version (fails if the application doesn't support this API or if no device is found) +// -adapter:# forces app to use this adapter # (fails if the adapter doesn't exist) +// -output:# [D3D11 only] forces app to use a particular output on the adapter (fails if the output doesn't exist) +// -windowed forces app to start windowed +// -fullscreen forces app to start full screen +// -forcehal forces app to use HAL (fails if HAL doesn't exist) +// -forceref forces app to use REF (fails if REF doesn't exist) +// -forcepurehwvp [D3D9 only] forces app to use pure HWVP (fails if device doesn't support it) +// -forcehwvp [D3D9 only] forces app to use HWVP (fails if device doesn't support it) +// -forceswvp [D3D9 only] forces app to use SWVP +// -forcevsync:# if # is 0, then vsync is disabled +// -width:# forces app to use # for width. for full screen, it will pick the closest possible supported mode +// -height:# forces app to use # for height. for full screen, it will pick the closest possible supported mode +// -startx:# forces app to use # for the x coord of the window position for windowed mode +// -starty:# forces app to use # for the y coord of the window position for windowed mode +// -constantframetime:# forces app to use constant frame time, where # is the time/frame in seconds +// -quitafterframe:x forces app to quit after # frames +// -noerrormsgboxes prevents the display of message boxes generated by the framework so the application can be run without user interaction +// -nostats prevents the display of the stats +// -relaunchmce re-launches the MCE UI after the app exits +// -automation a hint to other components that automation is active +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTInit( bool bParseCommandLine, + bool bShowMsgBoxOnError, + __in_opt WCHAR* strExtraCommandLineParams, + bool bThreadSafeDXUT ) +{ + g_bThreadSafe = bThreadSafeDXUT; + + GetDXUTState().SetDXUTInitCalled( true ); + + // Not always needed, but lets the app create GDI dialogs + InitCommonControls(); + + // Save the current sticky/toggle/filter key settings so DXUT can restore them later + STICKYKEYS sk = {sizeof(STICKYKEYS), 0}; + SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &sk, 0); + GetDXUTState().SetStartupStickyKeys( sk ); + + TOGGLEKEYS tk = {sizeof(TOGGLEKEYS), 0}; + SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tk, 0); + GetDXUTState().SetStartupToggleKeys( tk ); + + FILTERKEYS fk = {sizeof(FILTERKEYS), 0}; + SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &fk, 0); + GetDXUTState().SetStartupFilterKeys( fk ); + + GetDXUTState().SetShowMsgBoxOnError( bShowMsgBoxOnError ); + + if( bParseCommandLine ) + DXUTParseCommandLine( GetCommandLine() ); + if( strExtraCommandLineParams ) + DXUTParseCommandLine( strExtraCommandLineParams, false ); + + // Reset the timer + DXUTGetGlobalTimer()->Reset(); + + GetDXUTState().SetDXUTInited( true ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Parses the command line for parameters. See DXUTInit() for list +//-------------------------------------------------------------------------------------- +void DXUTParseCommandLine(__inout WCHAR* strCommandLine, + bool bIgnoreFirstCommand ) +{ + WCHAR* strCmdLine; + WCHAR strFlag[MAX_PATH]; + + int nNumArgs; + LPWSTR* pstrArgList = CommandLineToArgvW( strCommandLine, &nNumArgs ); + int iArgStart = 0; + if( bIgnoreFirstCommand ) + iArgStart = 1; + for( int iArg = iArgStart; iArg < nNumArgs; iArg++ ) + { + strCmdLine = pstrArgList[iArg]; + + // Handle flag args + if( *strCmdLine == L'/' || *strCmdLine == L'-' ) + { + strCmdLine++; + + if( DXUTIsNextArg( strCmdLine, L"forcefeaturelevel" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + if (_wcsnicmp( strFlag, L"D3D_FEATURE_LEVEL_11_0", MAX_PATH) == 0 ) { + GetDXUTState().SetOverrideForceFeatureLevel(D3D_FEATURE_LEVEL_11_0); + }else if (_wcsnicmp( strFlag, L"D3D_FEATURE_LEVEL_10_1", MAX_PATH) == 0 ) { + GetDXUTState().SetOverrideForceFeatureLevel(D3D_FEATURE_LEVEL_10_1); + }else if (_wcsnicmp( strFlag, L"D3D_FEATURE_LEVEL_10_0", MAX_PATH) == 0 ) { + GetDXUTState().SetOverrideForceFeatureLevel(D3D_FEATURE_LEVEL_10_0); + }else if (_wcsnicmp( strFlag, L"D3D_FEATURE_LEVEL_9_3", MAX_PATH) == 0 ) { + GetDXUTState().SetOverrideForceFeatureLevel(D3D_FEATURE_LEVEL_9_3); + }else if (_wcsnicmp( strFlag, L"D3D_FEATURE_LEVEL_9_2", MAX_PATH) == 0 ) { + GetDXUTState().SetOverrideForceFeatureLevel(D3D_FEATURE_LEVEL_9_2); + }else if (_wcsnicmp( strFlag, L"D3D_FEATURE_LEVEL_9_1", MAX_PATH) == 0 ) { + GetDXUTState().SetOverrideForceFeatureLevel(D3D_FEATURE_LEVEL_9_1); + } + + + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"forceapi" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nAPIVersion = _wtoi( strFlag ); + GetDXUTState().SetOverrideForceAPI( nAPIVersion ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"adapter" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nAdapter = _wtoi( strFlag ); + GetDXUTState().SetOverrideAdapterOrdinal( nAdapter ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"windowed" ) ) + { + GetDXUTState().SetOverrideWindowed( true ); + continue; + } + + if( DXUTIsNextArg( strCmdLine, L"output" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int Output = _wtoi( strFlag ); + GetDXUTState().SetOverrideOutput( Output ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"fullscreen" ) ) + { + GetDXUTState().SetOverrideFullScreen( true ); + continue; + } + + if( DXUTIsNextArg( strCmdLine, L"forcehal" ) ) + { + GetDXUTState().SetOverrideForceHAL( true ); + continue; + } + if( DXUTIsNextArg( strCmdLine, L"screenshotexit" ) ) { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + GetDXUTState().SetExitAfterScreenShot( true ); + GetDXUTState().SetSaveScreenShot( true ); + swprintf_s( GetDXUTState().GetScreenShotName(), 256, L"%s.bmp", strFlag ); + continue; + } + } + if( DXUTIsNextArg( strCmdLine, L"forceref" ) ) + { + GetDXUTState().SetOverrideForceREF( true ); + continue; + } + + if( DXUTIsNextArg( strCmdLine, L"forcevsync" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nOn = _wtoi( strFlag ); + GetDXUTState().SetOverrideForceVsync( nOn ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"width" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nWidth = _wtoi( strFlag ); + GetDXUTState().SetOverrideWidth( nWidth ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"height" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nHeight = _wtoi( strFlag ); + GetDXUTState().SetOverrideHeight( nHeight ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"startx" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nX = _wtoi( strFlag ); + GetDXUTState().SetOverrideStartX( nX ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"starty" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nY = _wtoi( strFlag ); + GetDXUTState().SetOverrideStartY( nY ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"constantframetime" ) ) + { + float fTimePerFrame; + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + fTimePerFrame = ( float )wcstod( strFlag, NULL ); + else + fTimePerFrame = 0.0333f; + GetDXUTState().SetOverrideConstantFrameTime( true ); + GetDXUTState().SetOverrideConstantTimePerFrame( fTimePerFrame ); + DXUTSetConstantFrameTime( true, fTimePerFrame ); + continue; + } + + if( DXUTIsNextArg( strCmdLine, L"quitafterframe" ) ) + { + if( DXUTGetCmdParam( strCmdLine, strFlag ) ) + { + int nFrame = _wtoi( strFlag ); + GetDXUTState().SetOverrideQuitAfterFrame( nFrame ); + continue; + } + } + + if( DXUTIsNextArg( strCmdLine, L"noerrormsgboxes" ) ) + { + GetDXUTState().SetShowMsgBoxOnError( false ); + continue; + } + + if( DXUTIsNextArg( strCmdLine, L"nostats" ) ) + { + GetDXUTState().SetNoStats( true ); + continue; + } + + if( DXUTIsNextArg( strCmdLine, L"relaunchmce" ) ) + { + GetDXUTState().SetOverrideRelaunchMCE( true ); + continue; + } + + if( DXUTIsNextArg( strCmdLine, L"automation" ) ) + { + GetDXUTState().SetAutomation( true ); + continue; + } + } + + // Unrecognized flag + wcscpy_s( strFlag, 256, strCmdLine ); + WCHAR* strSpace = strFlag; + while( *strSpace && ( *strSpace > L' ' ) ) + strSpace++; + *strSpace = 0; + + DXUTOutputDebugString( L"Unrecognized flag: %s", strFlag ); + strCmdLine += wcslen( strFlag ); + } + + LocalFree( pstrArgList ); +} + + +//-------------------------------------------------------------------------------------- +// Helper function for DXUTParseCommandLine +//-------------------------------------------------------------------------------------- +bool DXUTIsNextArg( __inout WCHAR*& strCmdLine, + __inout WCHAR* strArg ) +{ + int nArgLen = ( int )wcslen( strArg ); + int nCmdLen = ( int )wcslen( strCmdLine ); + + if( nCmdLen >= nArgLen && + _wcsnicmp( strCmdLine, strArg, nArgLen ) == 0 && + ( strCmdLine[nArgLen] == 0 || strCmdLine[nArgLen] == L':' ) ) + { + strCmdLine += nArgLen; + return true; + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +// Helper function for DXUTParseCommandLine. Updates strCmdLine and strFlag +// Example: if strCmdLine=="-width:1024 -forceref" +// then after: strCmdLine==" -forceref" and strFlag=="1024" +//-------------------------------------------------------------------------------------- +bool DXUTGetCmdParam( __inout WCHAR*& strCmdLine, + __inout_ecount(MAX_PATH) WCHAR* strFlag ) +{ + if( *strCmdLine == L':' ) + { + strCmdLine++; // Skip ':' + + // Place NULL terminator in strFlag after current token + wcscpy_s( strFlag, 256, strCmdLine ); + WCHAR* strSpace = strFlag; + while( *strSpace && ( *strSpace > L' ' ) ) + strSpace++; + *strSpace = 0; + + // Update strCmdLine + strCmdLine += wcslen( strFlag ); + return true; + } + else + { + strFlag[0] = 0; + return false; + } +} + + +//-------------------------------------------------------------------------------------- +// Creates a window with the specified window title, icon, menu, and +// starting position. If DXUTInit() has not already been called, it will +// call it with the default parameters. Instead of calling this, you can +// call DXUTSetWindow() to use an existing window. +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateWindow( const WCHAR* strWindowTitle, HINSTANCE hInstance, + HICON hIcon, HMENU hMenu, int x, int y ) +{ + HRESULT hr; + + // Not allowed to call this from inside the device callbacks + if( GetDXUTState().GetInsideDeviceCallback() ) + return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL ); + + GetDXUTState().SetWindowCreateCalled( true ); + + if( !GetDXUTState().GetDXUTInited() ) + { + // If DXUTInit() was already called and failed, then fail. + // DXUTInit() must first succeed for this function to succeed + if( GetDXUTState().GetDXUTInitCalled() ) + return E_FAIL; + + // If DXUTInit() hasn't been called, then automatically call it + // with default params + hr = DXUTInit(); + if( FAILED( hr ) ) + return hr; + } + + if( DXUTGetHWNDFocus() == NULL ) + { + if( hInstance == NULL ) + hInstance = ( HINSTANCE )GetModuleHandle( NULL ); + GetDXUTState().SetHInstance( hInstance ); + + WCHAR szExePath[MAX_PATH]; + GetModuleFileName( NULL, szExePath, MAX_PATH ); + if( hIcon == NULL ) // If the icon is NULL, then use the first one found in the exe + hIcon = ExtractIcon( hInstance, szExePath, 0 ); + + // Register the windows class + WNDCLASS wndClass; + wndClass.style = CS_DBLCLKS; + wndClass.lpfnWndProc = DXUTStaticWndProc; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = hInstance; + wndClass.hIcon = hIcon; + wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); + wndClass.hbrBackground = ( HBRUSH )GetStockObject( BLACK_BRUSH ); + wndClass.lpszMenuName = NULL; + wndClass.lpszClassName = L"Direct3DWindowClass"; + + if( !RegisterClass( &wndClass ) ) + { + DWORD dwError = GetLastError(); + if( dwError != ERROR_CLASS_ALREADY_EXISTS ) + return DXUT_ERR_MSGBOX( L"RegisterClass", HRESULT_FROM_WIN32(dwError) ); + } + + // Override the window's initial & size position if there were cmd line args + if( GetDXUTState().GetOverrideStartX() != -1 ) + x = GetDXUTState().GetOverrideStartX(); + if( GetDXUTState().GetOverrideStartY() != -1 ) + y = GetDXUTState().GetOverrideStartY(); + + GetDXUTState().SetWindowCreatedWithDefaultPositions( false ); + if( x == CW_USEDEFAULT && y == CW_USEDEFAULT ) + GetDXUTState().SetWindowCreatedWithDefaultPositions( true ); + + // Find the window's initial size, but it might be changed later + int nDefaultWidth = 640; + int nDefaultHeight = 480; + if( GetDXUTState().GetOverrideWidth() != 0 ) + nDefaultWidth = GetDXUTState().GetOverrideWidth(); + if( GetDXUTState().GetOverrideHeight() != 0 ) + nDefaultHeight = GetDXUTState().GetOverrideHeight(); + + RECT rc; + SetRect( &rc, 0, 0, nDefaultWidth, nDefaultHeight ); + AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, ( hMenu != NULL ) ? true : false ); + + WCHAR* strCachedWindowTitle = GetDXUTState().GetWindowTitle(); + wcscpy_s( strCachedWindowTitle, 256, strWindowTitle ); + + // Create the render window + HWND hWnd = CreateWindow( L"Direct3DWindowClass", strWindowTitle, WS_OVERLAPPEDWINDOW, + x, y, ( rc.right - rc.left ), ( rc.bottom - rc.top ), 0, + hMenu, hInstance, 0 ); + if( hWnd == NULL ) + { + DWORD dwError = GetLastError(); + return DXUT_ERR_MSGBOX( L"CreateWindow", HRESULT_FROM_WIN32(dwError) ); + } + + GetDXUTState().SetWindowCreated( true ); + GetDXUTState().SetHWNDFocus( hWnd ); + GetDXUTState().SetHWNDDeviceFullScreen( hWnd ); + GetDXUTState().SetHWNDDeviceWindowed( hWnd ); + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Sets a previously created window for the framework to use. If DXUTInit() +// has not already been called, it will call it with the default parameters. +// Instead of calling this, you can call DXUTCreateWindow() to create a new window. +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTSetWindow( HWND hWndFocus, HWND hWndDeviceFullScreen, HWND hWndDeviceWindowed, bool bHandleMessages ) +{ + HRESULT hr; + + // Not allowed to call this from inside the device callbacks + if( GetDXUTState().GetInsideDeviceCallback() ) + return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL ); + + GetDXUTState().SetWindowCreateCalled( true ); + + // To avoid confusion, we do not allow any HWND to be NULL here. The + // caller must pass in valid HWND for all three parameters. The same + // HWND may be used for more than one parameter. + if( hWndFocus == NULL || hWndDeviceFullScreen == NULL || hWndDeviceWindowed == NULL ) + return DXUT_ERR_MSGBOX( L"DXUTSetWindow", E_INVALIDARG ); + + // If subclassing the window, set the pointer to the local window procedure + if( bHandleMessages ) + { + // Switch window procedures +#ifdef _WIN64 + LONG_PTR nResult = SetWindowLongPtr( hWndFocus, GWLP_WNDPROC, (LONG_PTR)DXUTStaticWndProc ); +#else + LONG_PTR nResult = SetWindowLongPtr( hWndFocus, GWLP_WNDPROC, ( LONG )( LONG_PTR )DXUTStaticWndProc ); +#endif + + DWORD dwError = GetLastError(); + if( nResult == 0 ) + return DXUT_ERR_MSGBOX( L"SetWindowLongPtr", HRESULT_FROM_WIN32(dwError) ); + } + + if( !GetDXUTState().GetDXUTInited() ) + { + // If DXUTInit() was already called and failed, then fail. + // DXUTInit() must first succeed for this function to succeed + if( GetDXUTState().GetDXUTInitCalled() ) + return E_FAIL; + + // If DXUTInit() hasn't been called, then automatically call it + // with default params + hr = DXUTInit(); + if( FAILED( hr ) ) + return hr; + } + + WCHAR* strCachedWindowTitle = GetDXUTState().GetWindowTitle(); + GetWindowText( hWndFocus, strCachedWindowTitle, 255 ); + strCachedWindowTitle[255] = 0; + + HINSTANCE hInstance = ( HINSTANCE )( LONG_PTR )GetWindowLongPtr( hWndFocus, GWLP_HINSTANCE ); + GetDXUTState().SetHInstance( hInstance ); + GetDXUTState().SetWindowCreatedWithDefaultPositions( false ); + GetDXUTState().SetWindowCreated( true ); + GetDXUTState().SetHWNDFocus( hWndFocus ); + GetDXUTState().SetHWNDDeviceFullScreen( hWndDeviceFullScreen ); + GetDXUTState().SetHWNDDeviceWindowed( hWndDeviceWindowed ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Handles window messages +//-------------------------------------------------------------------------------------- +LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + + // Consolidate the keyboard messages and pass them to the app's keyboard callback + if( uMsg == WM_KEYDOWN || + uMsg == WM_SYSKEYDOWN || + uMsg == WM_KEYUP || + uMsg == WM_SYSKEYUP ) + { + bool bKeyDown = ( uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN ); + DWORD dwMask = ( 1 << 29 ); + bool bAltDown = ( ( lParam & dwMask ) != 0 ); + + bool* bKeys = GetDXUTState().GetKeys(); + bKeys[ ( BYTE )( wParam & 0xFF ) ] = bKeyDown; + + LPDXUTCALLBACKKEYBOARD pCallbackKeyboard = GetDXUTState().GetKeyboardFunc(); + if( pCallbackKeyboard ) + pCallbackKeyboard( ( UINT )wParam, bKeyDown, bAltDown, GetDXUTState().GetKeyboardFuncUserContext() ); + } + + // Consolidate the mouse button messages and pass them to the app's mouse callback + if( uMsg == WM_LBUTTONDOWN || + uMsg == WM_LBUTTONUP || + uMsg == WM_LBUTTONDBLCLK || + uMsg == WM_MBUTTONDOWN || + uMsg == WM_MBUTTONUP || + uMsg == WM_MBUTTONDBLCLK || + uMsg == WM_RBUTTONDOWN || + uMsg == WM_RBUTTONUP || + uMsg == WM_RBUTTONDBLCLK || + uMsg == WM_XBUTTONDOWN || + uMsg == WM_XBUTTONUP || + uMsg == WM_XBUTTONDBLCLK || + uMsg == WM_MOUSEWHEEL || + ( GetDXUTState().GetNotifyOnMouseMove() && uMsg == WM_MOUSEMOVE ) ) + { + int xPos = ( short )LOWORD( lParam ); + int yPos = ( short )HIWORD( lParam ); + + if( uMsg == WM_MOUSEWHEEL ) + { + // WM_MOUSEWHEEL passes screen mouse coords + // so convert them to client coords + POINT pt; + pt.x = xPos; pt.y = yPos; + ScreenToClient( hWnd, &pt ); + xPos = pt.x; yPos = pt.y; + } + + int nMouseWheelDelta = 0; + if( uMsg == WM_MOUSEWHEEL ) + nMouseWheelDelta = ( short )HIWORD( wParam ); + + int nMouseButtonState = LOWORD( wParam ); + bool bLeftButton = ( ( nMouseButtonState & MK_LBUTTON ) != 0 ); + bool bRightButton = ( ( nMouseButtonState & MK_RBUTTON ) != 0 ); + bool bMiddleButton = ( ( nMouseButtonState & MK_MBUTTON ) != 0 ); + bool bSideButton1 = ( ( nMouseButtonState & MK_XBUTTON1 ) != 0 ); + bool bSideButton2 = ( ( nMouseButtonState & MK_XBUTTON2 ) != 0 ); + + bool* bMouseButtons = GetDXUTState().GetMouseButtons(); + bMouseButtons[0] = bLeftButton; + bMouseButtons[1] = bMiddleButton; + bMouseButtons[2] = bRightButton; + bMouseButtons[3] = bSideButton1; + bMouseButtons[4] = bSideButton2; + + LPDXUTCALLBACKMOUSE pCallbackMouse = GetDXUTState().GetMouseFunc(); + if( pCallbackMouse ) + pCallbackMouse( bLeftButton, bRightButton, bMiddleButton, bSideButton1, bSideButton2, nMouseWheelDelta, + xPos, yPos, GetDXUTState().GetMouseFuncUserContext() ); + } + + // Pass all messages to the app's MsgProc callback, and don't + // process further messages if the apps says not to. + LPDXUTCALLBACKMSGPROC pCallbackMsgProc = GetDXUTState().GetWindowMsgFunc(); + if( pCallbackMsgProc ) + { + bool bNoFurtherProcessing = false; + LRESULT nResult = pCallbackMsgProc( hWnd, uMsg, wParam, lParam, &bNoFurtherProcessing, + GetDXUTState().GetWindowMsgFuncUserContext() ); + if( bNoFurtherProcessing ) + return nResult; + } + + switch( uMsg ) + { + case WM_PAINT: + { + + // Handle paint messages when the app is paused + if( DXUTIsRenderingPaused() && + GetDXUTState().GetDeviceObjectsCreated() && GetDXUTState().GetDeviceObjectsReset() ) + { + HRESULT hr; + double fTime = DXUTGetTime(); + float fElapsedTime = DXUTGetElapsedTime(); + + if( DXUTIsCurrentDeviceD3D9() ) + { + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + if( pd3dDevice ) + { + LPDXUTCALLBACKD3D9FRAMERENDER pCallbackFrameRender = GetDXUTState().GetD3D9FrameRenderFunc(); + if( pCallbackFrameRender != NULL ) + pCallbackFrameRender( pd3dDevice, fTime, fElapsedTime, + GetDXUTState().GetD3D9FrameRenderFuncUserContext() ); + + hr = pd3dDevice->Present( NULL, NULL, NULL, NULL ); + if( D3DERR_DEVICELOST == hr ) + { + GetDXUTState().SetDeviceLost( true ); + } + else if( D3DERR_DRIVERINTERNALERROR == hr ) + { + // When D3DERR_DRIVERINTERNALERROR is returned from Present(), + // the application can do one of the following: + // + // - End, with the pop-up window saying that the application cannot continue + // because of problems in the display adapter and that the user should + // contact the adapter manufacturer. + // + // - Attempt to restart by calling IDirect3DDevice9::Reset, which is essentially the same + // path as recovering from a lost device. If IDirect3DDevice9::Reset fails with + // D3DERR_DRIVERINTERNALERROR, the application should end immediately with the message + // that the user should contact the adapter manufacturer. + // + // The framework attempts the path of resetting the device + // + GetDXUTState().SetDeviceLost( true ); + } + } + } + else + { + ID3D11Device* pd3dDevice = DXUTGetD3D11Device(); + ID3D11DeviceContext *pDeferred = DXUTGetD3D11DeviceContext(); + if( pd3dDevice ) + { + LPDXUTCALLBACKD3D11FRAMERENDER pCallbackFrameRender = GetDXUTState().GetD3D11FrameRenderFunc(); + if( pCallbackFrameRender != NULL && + !GetDXUTState().GetRenderingOccluded() ) + { + pCallbackFrameRender( pd3dDevice,pDeferred, fTime, fElapsedTime, + GetDXUTState().GetD3D11FrameRenderFuncUserContext() ); + } + + DWORD dwFlags = 0; + if( GetDXUTState().GetRenderingOccluded() ) + dwFlags = DXGI_PRESENT_TEST; + else + dwFlags = GetDXUTState().GetCurrentDeviceSettings()->d3d11.PresentFlags; + + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + hr = pSwapChain->Present( 0, GetDXUTState().GetCurrentDeviceSettings()->d3d11.PresentFlags ); + if( DXGI_STATUS_OCCLUDED == hr ) + { + // There is a window covering our entire rendering area. + // Don't render until we're visible again. + GetDXUTState().SetRenderingOccluded( true ); + } + else if( SUCCEEDED( hr ) ) + { + if( GetDXUTState().GetRenderingOccluded() ) + { + // Now that we're no longer occluded + // allow us to render again + GetDXUTState().SetRenderingOccluded( false ); + } + } + } + } + } + break; + } + + case WM_SIZE: + + if( SIZE_MINIMIZED == wParam ) + { + DXUTPause( true, true ); // Pause while we're minimized + + GetDXUTState().SetMinimized( true ); + GetDXUTState().SetMaximized( false ); + } + else + { + RECT rcCurrentClient; + GetClientRect( DXUTGetHWND(), &rcCurrentClient ); + if( rcCurrentClient.top == 0 && rcCurrentClient.bottom == 0 ) + { + // Rapidly clicking the task bar to minimize and restore a window + // can cause a WM_SIZE message with SIZE_RESTORED when + // the window has actually become minimized due to rapid change + // so just ignore this message + } + else if( SIZE_MAXIMIZED == wParam ) + { + if( GetDXUTState().GetMinimized() ) + DXUTPause( false, false ); // Unpause since we're no longer minimized + GetDXUTState().SetMinimized( false ); + GetDXUTState().SetMaximized( true ); + DXUTCheckForWindowSizeChange(); + DXUTCheckForWindowChangingMonitors(); + } + else if( SIZE_RESTORED == wParam ) + { + //DXUTCheckForDXGIFullScreenSwitch(); + if( GetDXUTState().GetMaximized() ) + { + GetDXUTState().SetMaximized( false ); + DXUTCheckForWindowSizeChange(); + DXUTCheckForWindowChangingMonitors(); + } + else if( GetDXUTState().GetMinimized() ) + { + DXUTPause( false, false ); // Unpause since we're no longer minimized + GetDXUTState().SetMinimized( false ); + DXUTCheckForWindowSizeChange(); + DXUTCheckForWindowChangingMonitors(); + } + else if( GetDXUTState().GetInSizeMove() ) + { + // If we're neither maximized nor minimized, the window size + // is changing by the user dragging the window edges. In this + // case, we don't reset the device yet -- we wait until the + // user stops dragging, and a WM_EXITSIZEMOVE message comes. + } + else + { + // This WM_SIZE come from resizing the window via an API like SetWindowPos() so + // resize and reset the device now. + DXUTCheckForWindowSizeChange(); + DXUTCheckForWindowChangingMonitors(); + } + } + } + + break; + + + case WM_GETMINMAXINFO: + ( ( MINMAXINFO* )lParam )->ptMinTrackSize.x = DXUT_MIN_WINDOW_SIZE_X; + ( ( MINMAXINFO* )lParam )->ptMinTrackSize.y = DXUT_MIN_WINDOW_SIZE_Y; + break; + + case WM_ENTERSIZEMOVE: + // Halt frame movement while the app is sizing or moving + DXUTPause( true, true ); + GetDXUTState().SetInSizeMove( true ); + break; + + case WM_EXITSIZEMOVE: + DXUTPause( false, false ); + DXUTCheckForWindowSizeChange(); + DXUTCheckForWindowChangingMonitors(); + GetDXUTState().SetInSizeMove( false ); + break; + + case WM_MOUSEMOVE: + if( DXUTIsActive() && !DXUTIsWindowed() ) + { + if( DXUTIsCurrentDeviceD3D9() ) + { + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + if( pd3dDevice ) + { + POINT ptCursor; + GetCursorPos( &ptCursor ); + pd3dDevice->SetCursorPosition( ptCursor.x, ptCursor.y, 0 ); + } + } + else + { + // For D3D11, no processing is necessary. D3D11 cursor + // is handled in the traditional Windows manner. + } + } + break; + + case WM_SETCURSOR: + if( DXUTIsActive() && !DXUTIsWindowed() ) + { + if( DXUTIsCurrentDeviceD3D9() ) + { + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + if( pd3dDevice && GetDXUTState().GetShowCursorWhenFullScreen() ) + pd3dDevice->ShowCursor( true ); + } + else + { + if( !GetDXUTState().GetShowCursorWhenFullScreen() ) + SetCursor( NULL ); + } + + return true; // prevent Windows from setting cursor to window class cursor + } + break; + + case WM_ACTIVATEAPP: + if( wParam == TRUE && !DXUTIsActive() ) // Handle only if previously not active + { + GetDXUTState().SetActive( true ); + + // Enable controller rumble & input when activating app + DXUTEnableXInput( true ); + + // The GetMinimizedWhileFullscreen() varible is used instead of !DXUTIsWindowed() + // to handle the rare case toggling to windowed mode while the fullscreen application + // is minimized and thus making the pause count wrong + if( GetDXUTState().GetMinimizedWhileFullscreen() ) + { + if( DXUTIsD3D9( GetDXUTState().GetCurrentDeviceSettings() ) ) + DXUTPause( false, false ); // Unpause since we're no longer minimized + GetDXUTState().SetMinimizedWhileFullscreen( false ); + + if( DXUTIsAppRenderingWithD3D11() ) + { + DXUTToggleFullScreen(); + } + } + + // Upon returning to this app, potentially disable shortcut keys + // (Windows key, accessibility shortcuts) + DXUTAllowShortcutKeys( ( DXUTIsWindowed() ) ? GetDXUTState().GetAllowShortcutKeysWhenWindowed() : + GetDXUTState().GetAllowShortcutKeysWhenFullscreen() ); + + } + else if( wParam == FALSE && DXUTIsActive() ) // Handle only if previously active + { + GetDXUTState().SetActive( false ); + + // Disable any controller rumble & input when de-activating app + DXUTEnableXInput( false ); + + if( !DXUTIsWindowed() ) + { + // Going from full screen to a minimized state + ClipCursor( NULL ); // don't limit the cursor anymore + if( DXUTIsD3D9( GetDXUTState().GetCurrentDeviceSettings() ) ) + DXUTPause( true, true ); // Pause while we're minimized (take care not to pause twice by handling this message twice) + GetDXUTState().SetMinimizedWhileFullscreen( true ); + } + + // Restore shortcut keys (Windows key, accessibility shortcuts) to original state + // + // This is important to call here if the shortcuts are disabled, + // because if this is not done then the Windows key will continue to + // be disabled while this app is running which is very bad. + // If the app crashes, the Windows key will return to normal. + DXUTAllowShortcutKeys( true ); + } + break; + + case WM_ENTERMENULOOP: + // Pause the app when menus are displayed + DXUTPause( true, true ); + break; + + case WM_EXITMENULOOP: + DXUTPause( false, false ); + break; + + case WM_MENUCHAR: + // A menu is active and the user presses a key that does not correspond to any mnemonic or accelerator key + // So just ignore and don't beep + return MAKELRESULT( 0, MNC_CLOSE ); + break; + + case WM_NCHITTEST: + // Prevent the user from selecting the menu in full screen mode + if( !DXUTIsWindowed() ) + return HTCLIENT; + break; + + case WM_POWERBROADCAST: + switch( wParam ) + { +#ifndef PBT_APMQUERYSUSPEND +#define PBT_APMQUERYSUSPEND 0x0000 +#endif + case PBT_APMQUERYSUSPEND: + // At this point, the app should save any data for open + // network connections, files, etc., and prepare to go into + // a suspended mode. The app can use the MsgProc callback + // to handle this if desired. + return true; + +#ifndef PBT_APMRESUMESUSPEND +#define PBT_APMRESUMESUSPEND 0x0007 +#endif + case PBT_APMRESUMESUSPEND: + // At this point, the app should recover any data, network + // connections, files, etc., and resume running from when + // the app was suspended. The app can use the MsgProc callback + // to handle this if desired. + + // QPC may lose consistency when suspending, so reset the timer + // upon resume. + DXUTGetGlobalTimer()->Reset(); + GetDXUTState().SetLastStatsUpdateTime( 0 ); + return true; + } + break; + + case WM_SYSCOMMAND: + // Prevent moving/sizing in full screen mode + switch( ( wParam & 0xFFF0 ) ) + { + case SC_MOVE: + case SC_SIZE: + case SC_MAXIMIZE: + case SC_KEYMENU: + if( !DXUTIsWindowed() ) + return 0; + break; + } + break; + + case WM_SYSKEYDOWN: + { + switch( wParam ) + { + case VK_RETURN: + { + if( GetDXUTState().GetHandleAltEnter() && DXUTIsAppRenderingWithD3D9() ) + { + // Toggle full screen upon alt-enter + DWORD dwMask = ( 1 << 29 ); + if( ( lParam & dwMask ) != 0 ) // Alt is down also + { + // Toggle the full screen/window mode + DXUTPause( true, true ); + DXUTToggleFullScreen(); + DXUTPause( false, false ); + return 0; + } + } + + } + } + break; + } + + case WM_KEYDOWN: + { + switch( wParam ) + { + case VK_ESCAPE: + { + if( GetDXUTState().GetHandleEscape() ) + SendMessage( hWnd, WM_CLOSE, 0, 0 ); + break; + } + + case VK_PAUSE: + { + if( GetDXUTState().GetHandlePause() ) + { + bool bTimePaused = DXUTIsTimePaused(); + bTimePaused = !bTimePaused; + if( bTimePaused ) + DXUTPause( true, false ); + else + DXUTPause( false, false ); + } + break; + } + } + break; + } + + case WM_CLOSE: + { + HMENU hMenu; + hMenu = GetMenu( hWnd ); + if( hMenu != NULL ) + DestroyMenu( hMenu ); + DestroyWindow( hWnd ); + UnregisterClass( L"Direct3DWindowClass", NULL ); + GetDXUTState().SetHWNDFocus( NULL ); + GetDXUTState().SetHWNDDeviceFullScreen( NULL ); + GetDXUTState().SetHWNDDeviceWindowed( NULL ); + return 0; + } + + case WM_DESTROY: + PostQuitMessage( 0 ); + break; + } + + // Don't allow the F10 key to act as a shortcut to the menu bar + // by not passing these messages to the DefWindowProc only when + // there's no menu present + if( !GetDXUTState().GetCallDefWindowProc() || GetDXUTState().GetMenu() == NULL && + ( uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP ) && wParam == VK_F10 ) + return 0; + else + return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} + + +//-------------------------------------------------------------------------------------- +// Handles app's message loop and rendering when idle. If DXUTCreateDevice() or DXUTSetD3D*Device() +// has not already been called, it will call DXUTCreateWindow() with the default parameters. +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTMainLoop( HACCEL hAccel ) +{ + HRESULT hr; + + // Not allowed to call this from inside the device callbacks or reenter + if( GetDXUTState().GetInsideDeviceCallback() || GetDXUTState().GetInsideMainloop() ) + { + if( ( GetDXUTState().GetExitCode() == 0 ) || ( GetDXUTState().GetExitCode() == 10 ) ) + GetDXUTState().SetExitCode( 1 ); + return DXUT_ERR_MSGBOX( L"DXUTMainLoop", E_FAIL ); + } + + GetDXUTState().SetInsideMainloop( true ); + + // If DXUTCreateDevice() or DXUTSetD3D*Device() has not already been called, + // then call DXUTCreateDevice() with the default parameters. + if( !GetDXUTState().GetDeviceCreated() ) + { + if( GetDXUTState().GetDeviceCreateCalled() ) + { + if( ( GetDXUTState().GetExitCode() == 0 ) || ( GetDXUTState().GetExitCode() == 10 ) ) + GetDXUTState().SetExitCode( 1 ); + return E_FAIL; // DXUTCreateDevice() must first succeed for this function to succeed + } + + hr = DXUTCreateDevice(D3D_FEATURE_LEVEL_10_0, true, 640, 480); + if( FAILED( hr ) ) + { + if( ( GetDXUTState().GetExitCode() == 0 ) || ( GetDXUTState().GetExitCode() == 10 ) ) + GetDXUTState().SetExitCode( 1 ); + return hr; + } + } + + HWND hWnd = DXUTGetHWND(); + + // DXUTInit() must have been called and succeeded for this function to proceed + // DXUTCreateWindow() or DXUTSetWindow() must have been called and succeeded for this function to proceed + // DXUTCreateDevice() or DXUTCreateDeviceFromSettings() or DXUTSetD3D*Device() must have been called and succeeded for this function to proceed + if( !GetDXUTState().GetDXUTInited() || !GetDXUTState().GetWindowCreated() || !GetDXUTState().GetDeviceCreated() ) + { + if( ( GetDXUTState().GetExitCode() == 0 ) || ( GetDXUTState().GetExitCode() == 10 ) ) + GetDXUTState().SetExitCode( 1 ); + return DXUT_ERR_MSGBOX( L"DXUTMainLoop", E_FAIL ); + } + + // Now we're ready to receive and process Windows messages. + bool bGotMsg; + MSG msg; + msg.message = WM_NULL; + PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE ); + + while( WM_QUIT != msg.message ) + { + // Use PeekMessage() so we can use idle time to render the scene. + bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 ); + + if( bGotMsg ) + { + // Translate and dispatch the message + if( hAccel == NULL || hWnd == NULL || + 0 == TranslateAccelerator( hWnd, hAccel, &msg ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + } + else + { + // Render a frame during idle time (no messages are waiting) + DXUTRender3DEnvironment(); + } + } + + // Cleanup the accelerator table + if( hAccel != NULL ) + DestroyAcceleratorTable( hAccel ); + + GetDXUTState().SetInsideMainloop( false ); + + return S_OK; +} + + +//====================================================================================== +//====================================================================================== +// Direct3D section +//====================================================================================== +//====================================================================================== +HRESULT WINAPI DXUTCreateDevice(D3D_FEATURE_LEVEL reqFL, bool bWindowed, int nSuggestedWidth, int nSuggestedHeight) { + HRESULT hr = S_OK; + + + // Not allowed to call this from inside the device callbacks + if( GetDXUTState().GetInsideDeviceCallback() ) + return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL ); + + GetDXUTState().SetDeviceCreateCalled( true ); + + // If DXUTCreateWindow() or DXUTSetWindow() has not already been called, + // then call DXUTCreateWindow() with the default parameters. + if( !GetDXUTState().GetWindowCreated() ) + { + // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail. + // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed + if( GetDXUTState().GetWindowCreateCalled() ) + return E_FAIL; + + // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then + // automatically call DXUTCreateWindow() with default params + hr = DXUTCreateWindow(); + if( FAILED( hr ) ) + return hr; + } + + DXUTDeviceSettings deviceSettings ; + DXUTApplyDefaultDeviceSettings(&deviceSettings); + deviceSettings.MinimumFeatureLevel = reqFL; + deviceSettings.d3d11.sd.BufferDesc.Width = nSuggestedWidth; + deviceSettings.d3d11.sd.BufferDesc.Height = nSuggestedHeight; + + deviceSettings.d3d9.pp.BackBufferWidth= nSuggestedWidth; + deviceSettings.d3d9.pp.BackBufferHeight = nSuggestedHeight; + + + //deviceSettings.d3d11.sd.BufferDesc.Width = 480; + + bool bAppSupportsD3D9 = DXUTDoesAppSupportD3D9(); + bool bAppSupportsD3D11 = DXUTDoesAppSupportD3D11(); + + if (bAppSupportsD3D11) { + deviceSettings.ver = DXUT_D3D11_DEVICE; + } + else if (bAppSupportsD3D9) { + deviceSettings.ver = DXUT_D3D9_DEVICE; + } + + DXUTUpdateDeviceSettingsWithOverrides(&deviceSettings); + + + // Change to a Direct3D device created from the new device settings. + // If there is an existing device, then either reset or recreated the scene + hr = DXUTChangeDevice( &deviceSettings, NULL, NULL, false, true ); + + if ( hr == DXUTERR_NODIRECT3D11 && GetDXUTState().GetMessageWhenD3D11NotAvailable() ) { + + OSVERSIONINFOEX osv; + memset( &osv, 0, sizeof(osv) ); + osv.dwOSVersionInfoSize = sizeof(osv); + GetVersionEx( (LPOSVERSIONINFO)&osv ); + + + if ( ( osv.dwMajorVersion > 6 ) + || ( osv.dwMajorVersion == 6 && osv.dwMinorVersion >= 1 ) + || ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0 && osv.dwBuildNumber > 6002 ) ) + { + + MessageBox( 0, L"Direct3D 11 components were not found.", L"Error", MB_ICONEXCLAMATION ); + // This should not happen, but is here for completeness as the system could be + // corrupted or some future OS version could pull D3D11.DLL for some reason + } + else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0 && osv.dwBuildNumber == 6002 ) + { + + MessageBox( 0, L"Direct3D 11 components were not found, but are available for"\ + L" this version of Windows.\n"\ + L"For details see Microsoft Knowledge Base Article #971644\n"\ + L"http://go.microsoft.com/fwlink/?LinkId=160189", L"Error", MB_ICONEXCLAMATION ); + + } + else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0 ) + { + MessageBox( 0, L"Direct3D 11 components were not found. Please install the latest Service Pack.\n"\ + L"For details see Microsoft Knowledge Base Article #935791\n"\ + L"http://support.microsoft.com/kb/935791/", L"Error", MB_ICONEXCLAMATION ); + + } + else + { + MessageBox( 0, L"Direct3D 11 is not supported on this OS.", L"Error", MB_ICONEXCLAMATION ); + } + + + + } + + + if( FAILED( hr ) ) + return hr; + + return hr; +} + +//-------------------------------------------------------------------------------------- +// Tells the framework to change to a device created from the passed in device settings +// If DXUTCreateWindow() has not already been called, it will call it with the +// default parameters. Instead of calling this, you can call DXUTCreateDevice() +// or DXUTSetD3D*Device() +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateDeviceFromSettings( DXUTDeviceSettings* pDeviceSettings, bool bPreserveInput, + bool bClipWindowToSingleAdapter ) +{ + HRESULT hr; + + GetDXUTState().SetDeviceCreateCalled( true ); + + // If DXUTCreateWindow() or DXUTSetWindow() has not already been called, + // then call DXUTCreateWindow() with the default parameters. + if( !GetDXUTState().GetWindowCreated() ) + { + // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail. + // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed + if( GetDXUTState().GetWindowCreateCalled() ) + return E_FAIL; + + // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then + // automatically call DXUTCreateWindow() with default params + hr = DXUTCreateWindow(); + if( FAILED( hr ) ) + return hr; + } + DXUTUpdateDeviceSettingsWithOverrides(pDeviceSettings); + + + // Change to a Direct3D device created from the new device settings. + // If there is an existing device, then either reset or recreate the scene + hr = DXUTChangeDevice( pDeviceSettings, NULL, NULL, false, bClipWindowToSingleAdapter ); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// All device changes are sent to this function. It looks at the current +// device (if any) and the new device and determines the best course of action. It +// also remembers and restores the window state if toggling between windowed and fullscreen +// as well as sets the proper window and system state for switching to the new device. +//-------------------------------------------------------------------------------------- +HRESULT DXUTChangeDevice( DXUTDeviceSettings* pNewDeviceSettings, + IDirect3DDevice9* pd3d9DeviceFromApp, + ID3D11Device* pd3d11DeviceFromApp, + bool bForceRecreate, bool bClipWindowToSingleAdapter ) +{ + HRESULT hr = S_OK; + DXUTDeviceSettings* pOldDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + + if( !pNewDeviceSettings ) + return S_FALSE; + + + + if ( pNewDeviceSettings->ver == DXUT_D3D11_DEVICE ) { + hr = DXUTDelayLoadDXGI(); + } + + + if ( pNewDeviceSettings->ver == DXUT_D3D9_DEVICE || + ( FAILED( hr ) && DXUTDoesAppSupportD3D9() ) ) { + hr = DXUTDelayLoadD3D9(); + pNewDeviceSettings->ver = DXUT_D3D9_DEVICE; + if ( !FAILED( hr ) ) { + pNewDeviceSettings->ver = DXUT_D3D9_DEVICE; + } + } + + if( FAILED( hr ) ) + return hr; + + // Make a copy of the pNewDeviceSettings on the heap + DXUTDeviceSettings* pNewDeviceSettingsOnHeap = new DXUTDeviceSettings; + if( pNewDeviceSettingsOnHeap == NULL ) + return E_OUTOFMEMORY; + memcpy( pNewDeviceSettingsOnHeap, pNewDeviceSettings, sizeof( DXUTDeviceSettings ) ); + pNewDeviceSettings = pNewDeviceSettingsOnHeap; + + + GetDXUTState().SetCurrentDeviceSettings(pNewDeviceSettingsOnHeap); + DXUTSnapDeviceSettingsToEnumDevice(pNewDeviceSettingsOnHeap, false); + + if( FAILED( hr ) ) // the call will fail if no valid devices were found + { + DXUTDisplayErrorMessage( hr ); + return DXUT_ERR( L"DXUTFindValidDeviceSettings", hr ); + } + + // If the ModifyDeviceSettings callback is non-NULL, then call it to let the app + // change the settings or reject the device change by returning false. + LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings = GetDXUTState().GetModifyDeviceSettingsFunc(); + if( pCallbackModifyDeviceSettings && pd3d9DeviceFromApp == NULL ) + { + bool bContinue = pCallbackModifyDeviceSettings( pNewDeviceSettings, + GetDXUTState().GetModifyDeviceSettingsFuncUserContext() ); + if( !bContinue ) + { + // The app rejected the device change by returning false, so just use the current device if there is one. + if( pOldDeviceSettings == NULL ) + DXUTDisplayErrorMessage( DXUTERR_NOCOMPATIBLEDEVICES ); + SAFE_DELETE( pNewDeviceSettings ); + return E_ABORT; + } + if( GetDXUTState().GetD3D9() == NULL && GetDXUTState().GetDXGIFactory() == NULL ) // if DXUTShutdown() was called in the modify callback, just return + { + SAFE_DELETE( pNewDeviceSettings ); + return S_FALSE; + } + DXUTSnapDeviceSettingsToEnumDevice(pNewDeviceSettingsOnHeap, false); // modify the app specified settings to the closed enumerated settigns + + if( FAILED( hr ) ) // the call will fail if no valid devices were found + { + DXUTDisplayErrorMessage( hr ); + return DXUT_ERR( L"DXUTFindValidDeviceSettings", hr ); + } + + } + + GetDXUTState().SetCurrentDeviceSettings( pNewDeviceSettingsOnHeap ); + + DXUTPause( true, true ); + + // When a WM_SIZE message is received, it calls DXUTCheckForWindowSizeChange(). + // A WM_SIZE message might be sent when adjusting the window, so tell + // DXUTCheckForWindowSizeChange() to ignore size changes temporarily + if( DXUTIsCurrentDeviceD3D9() ) + GetDXUTState().SetIgnoreSizeChange( true ); + + + // Take note if the backbuffer width & height are 0 now as they will change after pd3dDevice->Reset() + bool bKeepCurrentWindowSize = false; + if( DXUTGetBackBufferWidthFromDS( pNewDeviceSettings ) == 0 && + DXUTGetBackBufferHeightFromDS( pNewDeviceSettings ) == 0 ) + bKeepCurrentWindowSize = true; + + ////////////////////////// + // Before reset + ///////////////////////// + + // If we are using D3D9, adjust window style when switching from windowed to fullscreen and + // vice versa. Note that this is not necessary in D3D11 because DXGI handles this. If both + // DXUT and DXGI handle this, incorrect behavior would result. + if( DXUTIsCurrentDeviceD3D9() ) + { + if( DXUTGetIsWindowedFromDS( pNewDeviceSettings ) ) + { + // Going to windowed mode + + if( pOldDeviceSettings && !DXUTGetIsWindowedFromDS( pOldDeviceSettings ) ) + { + // Going from fullscreen -> windowed + GetDXUTState().SetFullScreenBackBufferWidthAtModeChange( DXUTGetBackBufferWidthFromDS( + pOldDeviceSettings ) ); + GetDXUTState().SetFullScreenBackBufferHeightAtModeChange( DXUTGetBackBufferHeightFromDS( + pOldDeviceSettings ) ); + + // Restore windowed mode style + SetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE, GetDXUTState().GetWindowedStyleAtModeChange() ); + } + + // If different device windows are used for windowed mode and fullscreen mode, + // hide the fullscreen window so that it doesn't obscure the screen. + if( DXUTGetHWNDDeviceFullScreen() != DXUTGetHWNDDeviceWindowed() ) + ShowWindow( DXUTGetHWNDDeviceFullScreen(), SW_HIDE ); + + // If using the same window for windowed and fullscreen mode, reattach menu if one exists + if( DXUTGetHWNDDeviceFullScreen() == DXUTGetHWNDDeviceWindowed() ) + { + if( GetDXUTState().GetMenu() != NULL ) + SetMenu( DXUTGetHWNDDeviceWindowed(), GetDXUTState().GetMenu() ); + } + } + else + { + // Going to fullscreen mode + + if( pOldDeviceSettings == NULL || ( pOldDeviceSettings && DXUTGetIsWindowedFromDS( pOldDeviceSettings ) ) ) + { + // Transistioning to full screen mode from a standard window so + // save current window position/size/style now in case the user toggles to windowed mode later + WINDOWPLACEMENT* pwp = GetDXUTState().GetWindowedPlacement(); + ZeroMemory( pwp, sizeof( WINDOWPLACEMENT ) ); + pwp->length = sizeof( WINDOWPLACEMENT ); + GetWindowPlacement( DXUTGetHWNDDeviceWindowed(), pwp ); + bool bIsTopmost = ( ( GetWindowLong( DXUTGetHWNDDeviceWindowed(), + GWL_EXSTYLE ) & WS_EX_TOPMOST ) != 0 ); + GetDXUTState().SetTopmostWhileWindowed( bIsTopmost ); + DWORD dwStyle = GetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE ); + dwStyle &= ~WS_MAXIMIZE & ~WS_MINIMIZE; // remove minimize/maximize style + GetDXUTState().SetWindowedStyleAtModeChange( dwStyle ); + if( pOldDeviceSettings ) + { + GetDXUTState().SetWindowBackBufferWidthAtModeChange( DXUTGetBackBufferWidthFromDS( + pOldDeviceSettings ) ); + GetDXUTState().SetWindowBackBufferHeightAtModeChange( DXUTGetBackBufferHeightFromDS( + pOldDeviceSettings ) ); + } + } + + // Hide the window to avoid animation of blank windows + ShowWindow( DXUTGetHWNDDeviceFullScreen(), SW_HIDE ); + + // Set FS window style + SetWindowLong( DXUTGetHWNDDeviceFullScreen(), GWL_STYLE, WS_POPUP | WS_SYSMENU ); + + // If using the same window for windowed and fullscreen mode, save and remove menu + if( DXUTGetHWNDDeviceFullScreen() == DXUTGetHWNDDeviceWindowed() ) + { + HMENU hMenu = GetMenu( DXUTGetHWNDDeviceFullScreen() ); + GetDXUTState().SetMenu( hMenu ); + SetMenu( DXUTGetHWNDDeviceFullScreen(), NULL ); + } + + WINDOWPLACEMENT wpFullscreen; + ZeroMemory( &wpFullscreen, sizeof( WINDOWPLACEMENT ) ); + wpFullscreen.length = sizeof( WINDOWPLACEMENT ); + GetWindowPlacement( DXUTGetHWNDDeviceFullScreen(), &wpFullscreen ); + if( ( wpFullscreen.flags & WPF_RESTORETOMAXIMIZED ) != 0 ) + { + // Restore the window to normal if the window was maximized then minimized. This causes the + // WPF_RESTORETOMAXIMIZED flag to be set which will cause SW_RESTORE to restore the + // window from minimized to maxmized which isn't what we want + wpFullscreen.flags &= ~WPF_RESTORETOMAXIMIZED; + wpFullscreen.showCmd = SW_RESTORE; + SetWindowPlacement( DXUTGetHWNDDeviceFullScreen(), &wpFullscreen ); + } + } + } + else + { + if( DXUTGetIsWindowedFromDS( pNewDeviceSettings ) ) + { + // Going to windowed mode + if( pOldDeviceSettings && !DXUTGetIsWindowedFromDS( pOldDeviceSettings ) ) + { + // Going from fullscreen -> windowed + GetDXUTState().SetFullScreenBackBufferWidthAtModeChange( DXUTGetBackBufferWidthFromDS( + pOldDeviceSettings ) ); + GetDXUTState().SetFullScreenBackBufferHeightAtModeChange( DXUTGetBackBufferHeightFromDS( + pOldDeviceSettings ) ); + //DXGI should handle this, but in the case where switching from d3d9 full screen to windowed d3d11 it does not. + SetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE, GetDXUTState().GetWindowedStyleAtModeChange() ); + + } + } + else + { + // Going to fullscreen mode + if( pOldDeviceSettings == NULL || ( pOldDeviceSettings && DXUTGetIsWindowedFromDS( pOldDeviceSettings ) ) ) + { + // Transistioning to full screen mode from a standard window so + if( pOldDeviceSettings ) + { + GetDXUTState().SetWindowBackBufferWidthAtModeChange( DXUTGetBackBufferWidthFromDS( + pOldDeviceSettings ) ); + GetDXUTState().SetWindowBackBufferHeightAtModeChange( DXUTGetBackBufferHeightFromDS( + pOldDeviceSettings ) ); + } + } + } + } + + if( pOldDeviceSettings ) + DXUTCleanup3DEnvironment( false ); + + // Create the D3D device and call the app's device callbacks + if( DXUTIsD3D9( pNewDeviceSettings ) ) { + hr = DXUTCreate3DEnvironment9( pd3d9DeviceFromApp ); + } + else { + hr = DXUTCreate3DEnvironment11( pd3d11DeviceFromApp ); + } + if( FAILED( hr ) ) + { + SAFE_DELETE( pOldDeviceSettings ); + DXUTCleanup3DEnvironment( true ); + DXUTDisplayErrorMessage( hr ); + DXUTPause( false, false ); + GetDXUTState().SetIgnoreSizeChange( false ); + return hr; + } + + // Enable/disable StickKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut, and Windows key + // to prevent accidental task switching + DXUTAllowShortcutKeys( ( DXUTGetIsWindowedFromDS( pNewDeviceSettings ) ) ? + GetDXUTState().GetAllowShortcutKeysWhenWindowed() : + GetDXUTState().GetAllowShortcutKeysWhenFullscreen() ); + + HMONITOR hAdapterMonitor = DXUTGetMonitorFromAdapter( pNewDeviceSettings ); + GetDXUTState().SetAdapterMonitor( hAdapterMonitor ); + + // Update the device stats text + DXUTUpdateStaticFrameStats(); + + if( pOldDeviceSettings && !DXUTGetIsWindowedFromDS( pOldDeviceSettings ) && + DXUTGetIsWindowedFromDS( pNewDeviceSettings ) ) + { + // Going from fullscreen -> windowed + + // Restore the show state, and positions/size of the window to what it was + // It is important to adjust the window size + // after resetting the device rather than beforehand to ensure + // that the monitor resolution is correct and does not limit the size of the new window. + WINDOWPLACEMENT* pwp = GetDXUTState().GetWindowedPlacement(); + SetWindowPlacement( DXUTGetHWNDDeviceWindowed(), pwp ); + + // Also restore the z-order of window to previous state + HWND hWndInsertAfter = GetDXUTState().GetTopmostWhileWindowed() ? HWND_TOPMOST : HWND_NOTOPMOST; + SetWindowPos( DXUTGetHWNDDeviceWindowed(), hWndInsertAfter, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE ); + } + + // Check to see if the window needs to be resized. + // Handle cases where the window is minimized and maxmimized as well. + + bool bNeedToResize = false; + if( DXUTGetIsWindowedFromDS( pNewDeviceSettings ) && // only resize if in windowed mode + !bKeepCurrentWindowSize ) // only resize if pp.BackbufferWidth/Height were not 0 + { + UINT nClientWidth; + UINT nClientHeight; + if( IsIconic( DXUTGetHWNDDeviceWindowed() ) ) + { + // Window is currently minimized. To tell if it needs to resize, + // get the client rect of window when its restored the + // hard way using GetWindowPlacement() + WINDOWPLACEMENT wp; + ZeroMemory( &wp, sizeof( WINDOWPLACEMENT ) ); + wp.length = sizeof( WINDOWPLACEMENT ); + GetWindowPlacement( DXUTGetHWNDDeviceWindowed(), &wp ); + + if( ( wp.flags & WPF_RESTORETOMAXIMIZED ) != 0 && wp.showCmd == SW_SHOWMINIMIZED ) + { + // WPF_RESTORETOMAXIMIZED means that when the window is restored it will + // be maximized. So maximize the window temporarily to get the client rect + // when the window is maximized. GetSystemMetrics( SM_CXMAXIMIZED ) will give this + // information if the window is on the primary but this will work on multimon. + ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_RESTORE ); + RECT rcClient; + GetClientRect( DXUTGetHWNDDeviceWindowed(), &rcClient ); + nClientWidth = ( UINT )( rcClient.right - rcClient.left ); + nClientHeight = ( UINT )( rcClient.bottom - rcClient.top ); + ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_MINIMIZE ); + } + else + { + // Use wp.rcNormalPosition to get the client rect, but wp.rcNormalPosition + // includes the window frame so subtract it + RECT rcFrame = {0}; + AdjustWindowRect( &rcFrame, GetDXUTState().GetWindowedStyleAtModeChange(), GetDXUTState().GetMenu() != NULL ); + LONG nFrameWidth = rcFrame.right - rcFrame.left; + LONG nFrameHeight = rcFrame.bottom - rcFrame.top; + nClientWidth = ( UINT )( wp.rcNormalPosition.right - wp.rcNormalPosition.left - nFrameWidth ); + nClientHeight = ( UINT )( wp.rcNormalPosition.bottom - wp.rcNormalPosition.top - nFrameHeight ); + } + } + else + { + // Window is restored or maximized so just get its client rect + RECT rcClient; + GetClientRect( DXUTGetHWNDDeviceWindowed(), &rcClient ); + nClientWidth = ( UINT )( rcClient.right - rcClient.left ); + nClientHeight = ( UINT )( rcClient.bottom - rcClient.top ); + } + + // Now that we know the client rect, compare it against the back buffer size + // to see if the client rect is already the right size + if( nClientWidth != DXUTGetBackBufferWidthFromDS( pNewDeviceSettings ) || + nClientHeight != DXUTGetBackBufferHeightFromDS( pNewDeviceSettings ) ) + { + bNeedToResize = true; + } + + if( bClipWindowToSingleAdapter && !IsIconic( DXUTGetHWNDDeviceWindowed() ) ) + { + // Get the rect of the monitor attached to the adapter + MONITORINFO miAdapter; + miAdapter.cbSize = sizeof( MONITORINFO ); + HMONITOR hAdapterMonitor = DXUTGetMonitorFromAdapter( pNewDeviceSettings ); + DXUTGetMonitorInfo( hAdapterMonitor, &miAdapter ); + HMONITOR hWindowMonitor = DXUTMonitorFromWindow( DXUTGetHWND(), MONITOR_DEFAULTTOPRIMARY ); + + // Get the rect of the window + RECT rcWindow; + GetWindowRect( DXUTGetHWNDDeviceWindowed(), &rcWindow ); + + // Check if the window rect is fully inside the adapter's vitural screen rect + if( ( rcWindow.left < miAdapter.rcWork.left || + rcWindow.right > miAdapter.rcWork.right || + rcWindow.top < miAdapter.rcWork.top || + rcWindow.bottom > miAdapter.rcWork.bottom ) ) + { + if( hWindowMonitor == hAdapterMonitor && IsZoomed( DXUTGetHWNDDeviceWindowed() ) ) + { + // If the window is maximized and on the same monitor as the adapter, then + // no need to clip to single adapter as the window is already clipped + // even though the rcWindow rect is outside of the miAdapter.rcWork + } + else + { + bNeedToResize = true; + } + } + } + } + + // Only resize window if needed + + if( bNeedToResize ) + { + // Need to resize, so if window is maximized or minimized then restore the window + if( IsIconic( DXUTGetHWNDDeviceWindowed() ) ) + ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_RESTORE ); + if( IsZoomed( DXUTGetHWNDDeviceWindowed() ) ) // doing the IsIconic() check first also handles the WPF_RESTORETOMAXIMIZED case + ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_RESTORE ); + + if( bClipWindowToSingleAdapter ) + { + // Get the rect of the monitor attached to the adapter + MONITORINFO miAdapter; + miAdapter.cbSize = sizeof( MONITORINFO ); + HMONITOR hAdapterMonitor = DXUTGetMonitorFromAdapter( pNewDeviceSettings ); + DXUTGetMonitorInfo( hAdapterMonitor, &miAdapter ); + + // Get the rect of the monitor attached to the window + MONITORINFO miWindow; + miWindow.cbSize = sizeof( MONITORINFO ); + DXUTGetMonitorInfo( DXUTMonitorFromWindow( DXUTGetHWND(), MONITOR_DEFAULTTOPRIMARY ), &miWindow ); + + // Do something reasonable if the BackBuffer size is greater than the monitor size + int nAdapterMonitorWidth = miAdapter.rcWork.right - miAdapter.rcWork.left; + int nAdapterMonitorHeight = miAdapter.rcWork.bottom - miAdapter.rcWork.top; + + int nClientWidth = DXUTGetBackBufferWidthFromDS( pNewDeviceSettings ); + int nClientHeight = DXUTGetBackBufferHeightFromDS( pNewDeviceSettings ); + + // Get the rect of the window + RECT rcWindow; + GetWindowRect( DXUTGetHWNDDeviceWindowed(), &rcWindow ); + + // Make a window rect with a client rect that is the same size as the backbuffer + RECT rcResizedWindow; + rcResizedWindow.left = 0; + rcResizedWindow.right = nClientWidth; + rcResizedWindow.top = 0; + rcResizedWindow.bottom = nClientHeight; + AdjustWindowRect( &rcResizedWindow, GetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE ), + GetDXUTState().GetMenu() != NULL ); + + int nWindowWidth = rcResizedWindow.right - rcResizedWindow.left; + int nWindowHeight = rcResizedWindow.bottom - rcResizedWindow.top; + + if( nWindowWidth > nAdapterMonitorWidth ) + nWindowWidth = nAdapterMonitorWidth; + if( nWindowHeight > nAdapterMonitorHeight ) + nWindowHeight = nAdapterMonitorHeight; + + if( rcResizedWindow.left < miAdapter.rcWork.left || + rcResizedWindow.top < miAdapter.rcWork.top || + rcResizedWindow.right > miAdapter.rcWork.right || + rcResizedWindow.bottom > miAdapter.rcWork.bottom ) + { + int nWindowOffsetX = ( nAdapterMonitorWidth - nWindowWidth ) / 2; + int nWindowOffsetY = ( nAdapterMonitorHeight - nWindowHeight ) / 2; + + rcResizedWindow.left = miAdapter.rcWork.left + nWindowOffsetX; + rcResizedWindow.top = miAdapter.rcWork.top + nWindowOffsetY; + rcResizedWindow.right = miAdapter.rcWork.left + nWindowOffsetX + nWindowWidth; + rcResizedWindow.bottom = miAdapter.rcWork.top + nWindowOffsetY + nWindowHeight; + } + + // Resize the window. It is important to adjust the window size + // after resetting the device rather than beforehand to ensure + // that the monitor resolution is correct and does not limit the size of the new window. + SetWindowPos( DXUTGetHWNDDeviceWindowed(), 0, rcResizedWindow.left, rcResizedWindow.top, nWindowWidth, + nWindowHeight, SWP_NOZORDER ); + } + else + { + // Make a window rect with a client rect that is the same size as the backbuffer + RECT rcWindow = {0}; + rcWindow.right = (long)( DXUTGetBackBufferWidthFromDS(pNewDeviceSettings) ); + rcWindow.bottom = (long)( DXUTGetBackBufferHeightFromDS(pNewDeviceSettings) ); + AdjustWindowRect( &rcWindow, GetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE ), GetDXUTState().GetMenu() != NULL ); + + // Resize the window. It is important to adjust the window size + // after resetting the device rather than beforehand to ensure + // that the monitor resolution is correct and does not limit the size of the new window. + int cx = ( int )( rcWindow.right - rcWindow.left ); + int cy = ( int )( rcWindow.bottom - rcWindow.top ); + SetWindowPos( DXUTGetHWNDDeviceWindowed(), 0, 0, 0, cx, cy, SWP_NOZORDER | SWP_NOMOVE ); + } + + // Its possible that the new window size is not what we asked for. + // No window can be sized larger than the desktop, so see if the Windows OS resized the + // window to something smaller to fit on the desktop. Also if WM_GETMINMAXINFO + // will put a limit on the smallest/largest window size. + RECT rcClient; + GetClientRect( DXUTGetHWNDDeviceWindowed(), &rcClient ); + UINT nClientWidth = ( UINT )( rcClient.right - rcClient.left ); + UINT nClientHeight = ( UINT )( rcClient.bottom - rcClient.top ); + if( nClientWidth != DXUTGetBackBufferWidthFromDS( pNewDeviceSettings ) || + nClientHeight != DXUTGetBackBufferHeightFromDS( pNewDeviceSettings ) ) + { + // If its different, then resize the backbuffer again. This time create a backbuffer that matches the + // client rect of the current window w/o resizing the window. + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + if( DXUTIsD3D9( &deviceSettings ) ) deviceSettings.d3d9.pp.BackBufferWidth = 0; else deviceSettings.d3d11.sd.BufferDesc.Width = 0; + if( DXUTIsD3D9( &deviceSettings ) ) deviceSettings.d3d9.pp.BackBufferHeight = 0; else deviceSettings.d3d11.sd.BufferDesc.Height = 0; + + hr = DXUTChangeDevice( &deviceSettings, NULL, NULL, false, bClipWindowToSingleAdapter ); + if( FAILED( hr ) ) + { + SAFE_DELETE( pOldDeviceSettings ); + DXUTCleanup3DEnvironment( true ); + DXUTPause( false, false ); + GetDXUTState().SetIgnoreSizeChange( false ); + return hr; + } + } + } + + //if (DXUTGetIsWindowedFromDS( pNewDeviceSettings )) { + // RECT rcFrame = {0}; + // AdjustWindowRect( &rcFrame, GetDXUTState().GetWindowedStyleAtModeChange(), GetDXUTState().GetMenu() != NULL ); + // } + + // Make the window visible + if( !IsWindowVisible( DXUTGetHWND() ) ) + ShowWindow( DXUTGetHWND(), SW_SHOW ); + + // Ensure that the display doesn't power down when fullscreen but does when windowed + if( !DXUTIsWindowed() ) + SetThreadExecutionState( ES_DISPLAY_REQUIRED | ES_CONTINUOUS ); + else + SetThreadExecutionState( ES_CONTINUOUS ); + + SAFE_DELETE( pOldDeviceSettings ); + GetDXUTState().SetIgnoreSizeChange( false ); + DXUTPause( false, false ); + GetDXUTState().SetDeviceCreated( true ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Creates a DXGI factory object if one has not already been created +//-------------------------------------------------------------------------------------- +HRESULT DXUTDelayLoadDXGI() +{ + IDXGIFactory1* pDXGIFactory = GetDXUTState().GetDXGIFactory(); + if( pDXGIFactory == NULL ) + { + DXUT_Dynamic_CreateDXGIFactory1( __uuidof( IDXGIFactory1 ), ( LPVOID* )&pDXGIFactory ); + GetDXUTState().SetDXGIFactory( pDXGIFactory ); + if( pDXGIFactory == NULL ) + { + // If still NULL, then DXGI is not availible + GetDXUTState().SetD3D11Available( false ); + return DXUTERR_NODIRECT3D11; + } + + // TODO: check for D3D11 support + GetDXUTState().SetD3D11Available( true ); + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Creates a Direct3D object if one has not already been created +//-------------------------------------------------------------------------------------- +HRESULT DXUTDelayLoadD3D9() +{ + IDirect3D9* pD3D = GetDXUTState().GetD3D9(); + if( pD3D == NULL ) + { + // This may fail if Direct3D 9 isn't installed + // This may also fail if the Direct3D headers are somehow out of sync with the installed Direct3D DLLs + pD3D = DXUT_Dynamic_Direct3DCreate9( D3D_SDK_VERSION ); + if( pD3D == NULL ) + { + // If still NULL, then D3D9 is not availible + return DXUTERR_NODIRECT3D; + } + + GetDXUTState().SetD3D9( pD3D ); + } + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +// Updates the device settings with default values.. +//-------------------------------------------------------------------------------------- +void DXUTUpdateDeviceSettingsWithOverrides( DXUTDeviceSettings* pDeviceSettings ) +{ + // Override with settings from the command line + if( GetDXUTState().GetOverrideWidth() != 0 ) + { + pDeviceSettings->d3d9.pp.BackBufferWidth = GetDXUTState().GetOverrideWidth(); + pDeviceSettings->d3d11.sd.BufferDesc.Width = GetDXUTState().GetOverrideWidth(); + } + if( GetDXUTState().GetOverrideHeight() != 0 ) + { + pDeviceSettings->d3d9.pp.BackBufferHeight = GetDXUTState().GetOverrideHeight(); + pDeviceSettings->d3d11.sd.BufferDesc.Height = GetDXUTState().GetOverrideHeight(); + } + + if( GetDXUTState().GetOverrideAdapterOrdinal() != -1 ) + { + pDeviceSettings->d3d9.AdapterOrdinal = GetDXUTState().GetOverrideAdapterOrdinal(); + pDeviceSettings->d3d11.AdapterOrdinal = GetDXUTState().GetOverrideAdapterOrdinal(); + } + + if( GetDXUTState().GetOverrideFullScreen() ) + { + pDeviceSettings->d3d9.pp.Windowed = FALSE; + pDeviceSettings->d3d11.sd.Windowed = FALSE; + } + + if( GetDXUTState().GetOverrideWindowed() ) { + pDeviceSettings->d3d9.pp.Windowed = TRUE; + pDeviceSettings->d3d11.sd.Windowed = TRUE; + } + + if( GetDXUTState().GetOverrideForceHAL() ) + { + pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_HAL; + pDeviceSettings->d3d11.DriverType = D3D_DRIVER_TYPE_HARDWARE; + } + + if( GetDXUTState().GetOverrideForceREF() ) + { + pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF; + pDeviceSettings->d3d11.DriverType = D3D_DRIVER_TYPE_REFERENCE; + } + + if( GetDXUTState().GetOverrideForceVsync() == 0 ) + { + pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + pDeviceSettings->d3d11.SyncInterval = 0; + } + else if( GetDXUTState().GetOverrideForceVsync() == 1 ) + { + pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + pDeviceSettings->d3d11.SyncInterval = 1; + } + + if( GetDXUTState().GetOverrideForceAPI() != -1 ) + { + if( GetDXUTState().GetOverrideForceAPI() == 9 ) + { + pDeviceSettings->ver = DXUT_D3D9_DEVICE; + } + else if( GetDXUTState().GetOverrideForceAPI() == 11 ) + { + pDeviceSettings->ver = DXUT_D3D11_DEVICE; + } + } + + if (GetDXUTState().GetOverrideForceFeatureLevel() != 0) { + pDeviceSettings->d3d11.DeviceFeatureLevel = (D3D_FEATURE_LEVEL)GetDXUTState().GetOverrideForceFeatureLevel(); + } +} + + +//-------------------------------------------------------------------------------------- +// Allows the app to explictly state if it supports D3D9 or D3D11. Typically +// calling this is not needed as DXUT will auto-detect this based on the callbacks set. +//-------------------------------------------------------------------------------------- +void WINAPI DXUTSetD3DVersionSupport( bool bAppCanUseD3D9, bool bAppCanUseD3D11 ) +{ + GetDXUTState().SetUseD3DVersionOverride( true ); + GetDXUTState().SetAppSupportsD3D9Override( bAppCanUseD3D9 ); + GetDXUTState().SetAppSupportsD3D11Override( bAppCanUseD3D11 ); +} + + +//-------------------------------------------------------------------------------------- +// Returns true if app has registered any D3D9 callbacks or +// used the DXUTSetD3DVersionSupport API and passed true for bAppCanUseD3D9 +//-------------------------------------------------------------------------------------- +bool WINAPI DXUTDoesAppSupportD3D9() +{ + if( GetDXUTState().GetUseD3DVersionOverride() ) + return GetDXUTState().GetAppSupportsD3D9Override(); + else + return GetDXUTState().GetIsD3D9DeviceAcceptableFunc() || + GetDXUTState().GetD3D9DeviceCreatedFunc() || + GetDXUTState().GetD3D9DeviceResetFunc() || + GetDXUTState().GetD3D9DeviceLostFunc() || + GetDXUTState().GetD3D9DeviceDestroyedFunc() || + GetDXUTState().GetD3D9FrameRenderFunc(); +} + + +//-------------------------------------------------------------------------------------- +// Returns true if app has registered any D3D11 callbacks or +// used the DXUTSetD3DVersionSupport API and passed true for bAppCanUseD3D11 +//-------------------------------------------------------------------------------------- +bool WINAPI DXUTDoesAppSupportD3D11() +{ + if( GetDXUTState().GetUseD3DVersionOverride() ) + return GetDXUTState().GetAppSupportsD3D11Override(); + else + return GetDXUTState().GetIsD3D11DeviceAcceptableFunc() || + GetDXUTState().GetD3D11DeviceCreatedFunc() || + GetDXUTState().GetD3D11SwapChainResizedFunc() || + GetDXUTState().GetD3D11FrameRenderFunc() || + GetDXUTState().GetD3D11SwapChainReleasingFunc() || + GetDXUTState().GetD3D11DeviceDestroyedFunc(); +} + + +//====================================================================================== +//====================================================================================== +// Direct3D 9 section +//====================================================================================== +//====================================================================================== + + +//-------------------------------------------------------------------------------------- +// Passes a previously created Direct3D9 device for use by the framework. +// If DXUTCreateWindow() has not already been called, it will call it with the +// default parameters. Instead of calling this, you can call DXUTCreateDevice() or +// DXUTCreateDeviceFromSettings() +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTSetD3D9Device( IDirect3DDevice9* pd3dDevice ) +{ + HRESULT hr; + + if( pd3dDevice == NULL ) + return DXUT_ERR_MSGBOX( L"DXUTSetD3D9Device", E_INVALIDARG ); + + // Not allowed to call this from inside the device callbacks + if( GetDXUTState().GetInsideDeviceCallback() ) + return DXUT_ERR_MSGBOX( L"DXUTSetD3D9Device", E_FAIL ); + + GetDXUTState().SetDeviceCreateCalled( true ); + + // If DXUTCreateWindow() or DXUTSetWindow() has not already been called, + // then call DXUTCreateWindow() with the default parameters. + if( !GetDXUTState().GetWindowCreated() ) + { + // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail. + // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed + if( GetDXUTState().GetWindowCreateCalled() ) + return E_FAIL; + + // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then + // automatically call DXUTCreateWindow() with default params + hr = DXUTCreateWindow(); + if( FAILED( hr ) ) + return hr; + } + + DXUTDeviceSettings DeviceSettings; + ZeroMemory( &DeviceSettings, sizeof( DXUTDeviceSettings ) ); + DeviceSettings.ver = DXUT_D3D9_DEVICE; + + // Get the present params from the swap chain + IDirect3DSurface9* pBackBuffer = NULL; + hr = pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); + if( SUCCEEDED( hr ) ) + { + IDirect3DSwapChain9* pSwapChain = NULL; + hr = pBackBuffer->GetContainer( IID_IDirect3DSwapChain9, ( void** )&pSwapChain ); + if( SUCCEEDED( hr ) ) + { + pSwapChain->GetPresentParameters( &DeviceSettings.d3d9.pp ); + SAFE_RELEASE( pSwapChain ); + } + + SAFE_RELEASE( pBackBuffer ); + } + + D3DDEVICE_CREATION_PARAMETERS d3dCreationParams; + pd3dDevice->GetCreationParameters( &d3dCreationParams ); + + // Fill out the rest of the device settings struct + DeviceSettings.d3d9.AdapterOrdinal = d3dCreationParams.AdapterOrdinal; + DeviceSettings.d3d9.DeviceType = d3dCreationParams.DeviceType; + DXUTFindD3D9AdapterFormat( DeviceSettings.d3d9.AdapterOrdinal, DeviceSettings.d3d9.DeviceType, + DeviceSettings.d3d9.pp.BackBufferFormat, DeviceSettings.d3d9.pp.Windowed, + &DeviceSettings.d3d9.AdapterFormat ); + DeviceSettings.d3d9.BehaviorFlags = d3dCreationParams.BehaviorFlags; + + // Change to the Direct3D device passed in + hr = DXUTChangeDevice( &DeviceSettings, pd3dDevice, NULL, false, false ); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Creates the 3D environment +//-------------------------------------------------------------------------------------- +HRESULT DXUTCreate3DEnvironment9( IDirect3DDevice9* pd3dDeviceFromApp ) +{ + HRESULT hr = S_OK; + + IDirect3DDevice9* pd3dDevice = NULL; + DXUTDeviceSettings* pNewDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + + // Only create a Direct3D device if one hasn't been supplied by the app + if( pd3dDeviceFromApp == NULL ) + { + // Try to create the device with the chosen settings + IDirect3D9* pD3D = DXUTGetD3D9Object(); + hr = pD3D->CreateDevice( pNewDeviceSettings->d3d9.AdapterOrdinal, pNewDeviceSettings->d3d9.DeviceType, + DXUTGetHWNDFocus(), pNewDeviceSettings->d3d9.BehaviorFlags, + &pNewDeviceSettings->d3d9.pp, &pd3dDevice ); + if( hr == D3DERR_DEVICELOST ) + { + GetDXUTState().SetDeviceLost( true ); + return S_OK; + } + else if( FAILED( hr ) ) + { + DXUT_ERR( L"CreateDevice", hr ); + return DXUTERR_CREATINGDEVICE; + } + } + else + { + pd3dDeviceFromApp->AddRef(); + pd3dDevice = pd3dDeviceFromApp; + } + + GetDXUTState().SetD3D9Device( pd3dDevice ); + + // If switching to REF, set the exit code to 10. If switching to HAL and exit code was 10, then set it back to 0. + if( pNewDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF && GetDXUTState().GetExitCode() == 0 ) + GetDXUTState().SetExitCode( 10 ); + else if( pNewDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_HAL && GetDXUTState().GetExitCode() == 10 ) + GetDXUTState().SetExitCode( 0 ); + + // Update back buffer desc before calling app's device callbacks + DXUTUpdateBackBufferDesc(); + + // Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state) + DXUTSetupCursor(); + + // Update GetDXUTState()'s copy of D3D caps + D3DCAPS9* pd3dCaps = GetDXUTState().GetCaps(); + DXUTGetD3D9Device()->GetDeviceCaps( pd3dCaps ); + + // Update the device stats text + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration(); + CD3D9EnumAdapterInfo* pAdapterInfo = pd3dEnum->GetAdapterInfo( pNewDeviceSettings->d3d9.AdapterOrdinal ); + DXUTUpdateD3D9DeviceStats( pNewDeviceSettings->d3d9.DeviceType, + pNewDeviceSettings->d3d9.BehaviorFlags, + &pAdapterInfo->AdapterIdentifier ); + + // Call the app's device created callback if non-NULL + const D3DSURFACE_DESC* pBackBufferSurfaceDesc = DXUTGetD3D9BackBufferSurfaceDesc(); + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D9DEVICECREATED pCallbackDeviceCreated = GetDXUTState().GetD3D9DeviceCreatedFunc(); + hr = S_OK; + if( pCallbackDeviceCreated != NULL ) + hr = pCallbackDeviceCreated( DXUTGetD3D9Device(), pBackBufferSurfaceDesc, + GetDXUTState().GetD3D9DeviceCreatedFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + if( DXUTGetD3D9Device() == NULL ) // Handle DXUTShutdown from inside callback + return E_FAIL; + if( FAILED( hr ) ) + { + DXUT_ERR( L"DeviceCreated callback", hr ); + return ( hr == DXUTERR_MEDIANOTFOUND ) ? DXUTERR_MEDIANOTFOUND : DXUTERR_CREATINGDEVICEOBJECTS; + } + GetDXUTState().SetDeviceObjectsCreated( true ); + + // Call the app's device reset callback if non-NULL + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D9DEVICERESET pCallbackDeviceReset = GetDXUTState().GetD3D9DeviceResetFunc(); + hr = S_OK; + if( pCallbackDeviceReset != NULL ) + hr = pCallbackDeviceReset( DXUTGetD3D9Device(), pBackBufferSurfaceDesc, + GetDXUTState().GetD3D9DeviceResetFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + if( DXUTGetD3D9Device() == NULL ) // Handle DXUTShutdown from inside callback + return E_FAIL; + if( FAILED( hr ) ) + { + DXUT_ERR( L"DeviceReset callback", hr ); + return ( hr == DXUTERR_MEDIANOTFOUND ) ? DXUTERR_MEDIANOTFOUND : DXUTERR_RESETTINGDEVICEOBJECTS; + } + GetDXUTState().SetDeviceObjectsReset( true ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Resets the 3D environment by: +// - Calls the device lost callback +// - Resets the device +// - Stores the back buffer description +// - Sets up the full screen Direct3D cursor if requested +// - Calls the device reset callback +//-------------------------------------------------------------------------------------- +HRESULT DXUTReset3DEnvironment9() +{ + HRESULT hr; + + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + assert( pd3dDevice != NULL ); + + // Call the app's device lost callback + if( GetDXUTState().GetDeviceObjectsReset() == true ) + { + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D9DEVICELOST pCallbackDeviceLost = GetDXUTState().GetD3D9DeviceLostFunc(); + if( pCallbackDeviceLost != NULL ) + pCallbackDeviceLost( GetDXUTState().GetD3D9DeviceLostFuncUserContext() ); + GetDXUTState().SetDeviceObjectsReset( false ); + GetDXUTState().SetInsideDeviceCallback( false ); + } + + // Reset the device + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + hr = pd3dDevice->Reset( &pDeviceSettings->d3d9.pp ); + if( FAILED( hr ) ) + { + if( hr == D3DERR_DEVICELOST ) + return D3DERR_DEVICELOST; // Reset could legitimately fail if the device is lost + else + return DXUT_ERR( L"Reset", DXUTERR_RESETTINGDEVICE ); + } + + // Update back buffer desc before calling app's device callbacks + DXUTUpdateBackBufferDesc(); + + // Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state) + DXUTSetupCursor(); + + // Call the app's OnDeviceReset callback + GetDXUTState().SetInsideDeviceCallback( true ); + const D3DSURFACE_DESC* pBackBufferSurfaceDesc = DXUTGetD3D9BackBufferSurfaceDesc(); + LPDXUTCALLBACKD3D9DEVICERESET pCallbackDeviceReset = GetDXUTState().GetD3D9DeviceResetFunc(); + hr = S_OK; + if( pCallbackDeviceReset != NULL ) + hr = pCallbackDeviceReset( pd3dDevice, pBackBufferSurfaceDesc, + GetDXUTState().GetD3D9DeviceResetFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + if( FAILED( hr ) ) + { + // If callback failed, cleanup + DXUT_ERR( L"DeviceResetCallback", hr ); + if( hr != DXUTERR_MEDIANOTFOUND ) + hr = DXUTERR_RESETTINGDEVICEOBJECTS; + + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D9DEVICELOST pCallbackDeviceLost = GetDXUTState().GetD3D9DeviceLostFunc(); + if( pCallbackDeviceLost != NULL ) + pCallbackDeviceLost( GetDXUTState().GetD3D9DeviceLostFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + return hr; + } + + // Success + GetDXUTState().SetDeviceObjectsReset( true ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Render the 3D environment by: +// - Checking if the device is lost and trying to reset it if it is +// - Get the elapsed time since the last frame +// - Calling the app's framemove and render callback +// - Calling Present() +//-------------------------------------------------------------------------------------- +void DXUTRender3DEnvironment9() +{ + HRESULT hr; + + if( GetDXUTState().GetDeviceLost() || DXUTIsRenderingPaused() || !DXUTIsActive() ) + { + // Window is minimized or paused so yield CPU time to other processes + Sleep( 50 ); + } + + // If no device created yet because device was lost (ie. another fullscreen exclusive device exists), + // then wait and try to create every so often. + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + if( NULL == pd3dDevice ) + { + if( GetDXUTState().GetDeviceLost() ) + { + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + DXUTChangeDevice( &deviceSettings, NULL, NULL, false, true ); + } + + return; + } + + if( GetDXUTState().GetDeviceLost() && !GetDXUTState().GetRenderingPaused() ) + { + // Test the cooperative level to see if it's okay to render. + if( FAILED( hr = pd3dDevice->TestCooperativeLevel() ) ) + { + if( D3DERR_DEVICELOST == hr ) + { + // The device has been lost but cannot be reset at this time. + // So wait until it can be reset. + return; + } + + // If we are windowed, read the desktop format and + // ensure that the Direct3D device is using the same format + // since the user could have changed the desktop bitdepth + if( DXUTIsWindowed() ) + { + D3DDISPLAYMODE adapterDesktopDisplayMode; + IDirect3D9* pD3D = DXUTGetD3D9Object(); + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + pD3D->GetAdapterDisplayMode( pDeviceSettings->d3d9.AdapterOrdinal, &adapterDesktopDisplayMode ); + if( pDeviceSettings->d3d9.AdapterFormat != adapterDesktopDisplayMode.Format ) + { + + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + deviceSettings.d3d9.AdapterFormat = adapterDesktopDisplayMode.Format; + + hr = DXUTSnapDeviceSettingsToEnumDevice(&deviceSettings, false); + if( FAILED( hr ) ) // the call will fail if no valid devices were found + { + DXUTDisplayErrorMessage( DXUTERR_NOCOMPATIBLEDEVICES ); + DXUTShutdown(); + } + + // Change to a Direct3D device created from the new device settings. + // If there is an existing device, then either reset or recreate the scene + hr = DXUTChangeDevice( &deviceSettings, NULL, NULL, false, false ); + if( FAILED( hr ) ) + { + // If this fails, try to go fullscreen and if this fails also shutdown. + if( FAILED( DXUTToggleFullScreen() ) ) + DXUTShutdown(); + } + + return; + } + } + + // Try to reset the device + if( FAILED( hr = DXUTReset3DEnvironment9() ) ) + { + if( D3DERR_DEVICELOST == hr ) + { + // The device was lost again, so continue waiting until it can be reset. + return; + } + else if( DXUTERR_RESETTINGDEVICEOBJECTS == hr || + DXUTERR_MEDIANOTFOUND == hr ) + { + DXUTDisplayErrorMessage( hr ); + DXUTShutdown(); + return; + } + else + { + // Reset failed, but the device wasn't lost so something bad happened, + // so recreate the device to try to recover + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + if( FAILED( DXUTChangeDevice( pDeviceSettings, NULL, NULL, true, false ) ) ) + { + DXUTShutdown(); + return; + } + } + } + } + + GetDXUTState().SetDeviceLost( false ); + } + + // Get the app's time, in seconds. Skip rendering if no time elapsed + double fTime, fAbsTime; float fElapsedTime; + DXUTGetGlobalTimer()->GetTimeValues( &fTime, &fAbsTime, &fElapsedTime ); + + // Store the time for the app + if( GetDXUTState().GetConstantFrameTime() ) + { + fElapsedTime = GetDXUTState().GetTimePerFrame(); + fTime = DXUTGetTime() + fElapsedTime; + } + + GetDXUTState().SetTime( fTime ); + GetDXUTState().SetAbsoluteTime( fAbsTime ); + GetDXUTState().SetElapsedTime( fElapsedTime ); + + // Update the FPS stats + DXUTUpdateFrameStats(); + + DXUTHandleTimers(); + + // Animate the scene by calling the app's frame move callback + LPDXUTCALLBACKFRAMEMOVE pCallbackFrameMove = GetDXUTState().GetFrameMoveFunc(); + if( pCallbackFrameMove != NULL ) + { + pCallbackFrameMove( fTime, fElapsedTime, GetDXUTState().GetFrameMoveFuncUserContext() ); + pd3dDevice = DXUTGetD3D9Device(); + if( NULL == pd3dDevice ) // Handle DXUTShutdown from inside callback + return; + } + + if( !GetDXUTState().GetRenderingPaused() ) + { + // Render the scene by calling the app's render callback + LPDXUTCALLBACKD3D9FRAMERENDER pCallbackFrameRender = GetDXUTState().GetD3D9FrameRenderFunc(); + if( pCallbackFrameRender != NULL ) + { + pCallbackFrameRender( pd3dDevice, fTime, fElapsedTime, + GetDXUTState().GetD3D9FrameRenderFuncUserContext() ); + pd3dDevice = DXUTGetD3D9Device(); + if( NULL == pd3dDevice ) // Handle DXUTShutdown from inside callback + return; + } + +#if defined(DEBUG) || defined(_DEBUG) + // The back buffer should always match the client rect + // if the Direct3D backbuffer covers the entire window + RECT rcClient; + GetClientRect( DXUTGetHWND(), &rcClient ); + if( !IsIconic( DXUTGetHWND() ) ) + { + GetClientRect( DXUTGetHWND(), &rcClient ); + assert( DXUTGetD3D9BackBufferSurfaceDesc()->Width == (UINT)rcClient.right ); + assert( DXUTGetD3D9BackBufferSurfaceDesc()->Height == (UINT)rcClient.bottom ); + } +#endif + + // Show the frame on the primary surface. + hr = pd3dDevice->Present( NULL, NULL, NULL, NULL ); + if( FAILED( hr ) ) + { + if( D3DERR_DEVICELOST == hr ) + { + GetDXUTState().SetDeviceLost( true ); + } + else if( D3DERR_DRIVERINTERNALERROR == hr ) + { + // When D3DERR_DRIVERINTERNALERROR is returned from Present(), + // the application can do one of the following: + // + // - End, with the pop-up window saying that the application cannot continue + // because of problems in the display adapter and that the user should + // contact the adapter manufacturer. + // + // - Attempt to restart by calling IDirect3DDevice9::Reset, which is essentially the same + // path as recovering from a lost device. If IDirect3DDevice9::Reset fails with + // D3DERR_DRIVERINTERNALERROR, the application should end immediately with the message + // that the user should contact the adapter manufacturer. + // + // The framework attempts the path of resetting the device + // + GetDXUTState().SetDeviceLost( true ); + } + } + } + + // If the app called DXUTWasKeyPressed() then do the work + // to store the current state of the keys in bLastKeys + if( GetDXUTState().GetAppCalledWasKeyPressed() ) + { + bool* bLastKeys = GetDXUTState().GetLastKeys(); + bool* bKeys = GetDXUTState().GetKeys(); + memcpy( bLastKeys, bKeys, sizeof( bool ) * 256 ); + } + + // Update current frame # + int nFrame = GetDXUTState().GetCurrentFrameNumber(); + nFrame++; + GetDXUTState().SetCurrentFrameNumber( nFrame ); + + // Check to see if the app should shutdown due to cmdline + if( GetDXUTState().GetOverrideQuitAfterFrame() != 0 ) + { + if( nFrame > GetDXUTState().GetOverrideQuitAfterFrame() ) + DXUTShutdown(); + } + + return; +} + + +//-------------------------------------------------------------------------------------- +// Cleans up the 3D environment by: +// - Calls the device lost callback +// - Calls the device destroyed callback +// - Releases the D3D device +//-------------------------------------------------------------------------------------- +void DXUTCleanup3DEnvironment9( bool bReleaseSettings ) +{ + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + if( pd3dDevice != NULL ) + { + GetDXUTState().SetInsideDeviceCallback( true ); + + // Call the app's device lost callback + if( GetDXUTState().GetDeviceObjectsReset() == true ) + { + LPDXUTCALLBACKD3D9DEVICELOST pCallbackDeviceLost = GetDXUTState().GetD3D9DeviceLostFunc(); + if( pCallbackDeviceLost != NULL ) + pCallbackDeviceLost( GetDXUTState().GetD3D9DeviceLostFuncUserContext() ); + GetDXUTState().SetDeviceObjectsReset( false ); + } + + // Call the app's device destroyed callback + if( GetDXUTState().GetDeviceObjectsCreated() == true ) + { + LPDXUTCALLBACKD3D9DEVICEDESTROYED pCallbackDeviceDestroyed = GetDXUTState().GetD3D9DeviceDestroyedFunc(); + if( pCallbackDeviceDestroyed != NULL ) + pCallbackDeviceDestroyed( GetDXUTState().GetD3D9DeviceDestroyedFuncUserContext() ); + GetDXUTState().SetDeviceObjectsCreated( false ); + } + + GetDXUTState().SetInsideDeviceCallback( false ); + + // Release the D3D device and in debug configs, displays a message box if there + // are unrelease objects. + if( pd3dDevice ) + { + UINT references = pd3dDevice->Release(); + if( references > 0 ) + { + DXUTDisplayErrorMessage( DXUTERR_NONZEROREFCOUNT ); + DXUT_ERR( L"DXUTCleanup3DEnvironment", DXUTERR_NONZEROREFCOUNT ); + } + } + GetDXUTState().SetD3D9Device( NULL ); + + if( bReleaseSettings ) + { + DXUTDeviceSettings* pOldDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + SAFE_DELETE(pOldDeviceSettings); + GetDXUTState().SetCurrentDeviceSettings( NULL ); + } + + D3DSURFACE_DESC* pBackBufferSurfaceDesc = GetDXUTState().GetBackBufferSurfaceDesc9(); + ZeroMemory( pBackBufferSurfaceDesc, sizeof( D3DSURFACE_DESC ) ); + + D3DCAPS9* pd3dCaps = GetDXUTState().GetCaps(); + ZeroMemory( pd3dCaps, sizeof( D3DCAPS9 ) ); + + GetDXUTState().SetDeviceCreated( false ); + } +} + + +//-------------------------------------------------------------------------------------- +// Gives the D3D device a cursor with image and hotspot from hCursor. +//-------------------------------------------------------------------------------------- +HRESULT DXUTSetD3D9DeviceCursor( IDirect3DDevice9* pd3dDevice, HCURSOR hCursor, bool bAddWatermark ) +{ + HRESULT hr = E_FAIL; + ICONINFO iconinfo; + bool bBWCursor = false; + LPDIRECT3DSURFACE9 pCursorSurface = NULL; + HDC hdcColor = NULL; + HDC hdcMask = NULL; + HDC hdcScreen = NULL; + BITMAP bm; + DWORD dwWidth = 0; + DWORD dwHeightSrc = 0; + DWORD dwHeightDest = 0; + COLORREF crColor; + COLORREF crMask; + UINT x; + UINT y; + BITMAPINFO bmi; + COLORREF* pcrArrayColor = NULL; + COLORREF* pcrArrayMask = NULL; + DWORD* pBitmap; + HGDIOBJ hgdiobjOld; + + ZeroMemory( &iconinfo, sizeof( iconinfo ) ); + if( !GetIconInfo( hCursor, &iconinfo ) ) + goto End; + + if( 0 == GetObject( ( HGDIOBJ )iconinfo.hbmMask, sizeof( BITMAP ), ( LPVOID )&bm ) ) + goto End; + dwWidth = bm.bmWidth; + dwHeightSrc = bm.bmHeight; + + if( iconinfo.hbmColor == NULL ) + { + bBWCursor = TRUE; + dwHeightDest = dwHeightSrc / 2; + } + else + { + bBWCursor = FALSE; + dwHeightDest = dwHeightSrc; + } + + // Create a surface for the fullscreen cursor + if( FAILED( hr = pd3dDevice->CreateOffscreenPlainSurface( dwWidth, dwHeightDest, + D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCursorSurface, + NULL ) ) ) + { + goto End; + } + + pcrArrayMask = new DWORD[dwWidth * dwHeightSrc]; + + ZeroMemory( &bmi, sizeof( bmi ) ); + bmi.bmiHeader.biSize = sizeof( bmi.bmiHeader ); + bmi.bmiHeader.biWidth = dwWidth; + bmi.bmiHeader.biHeight = dwHeightSrc; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + hdcScreen = GetDC( NULL ); + hdcMask = CreateCompatibleDC( hdcScreen ); + if( hdcMask == NULL ) + { + hr = E_FAIL; + goto End; + } + hgdiobjOld = SelectObject( hdcMask, iconinfo.hbmMask ); + GetDIBits( hdcMask, iconinfo.hbmMask, 0, dwHeightSrc, + pcrArrayMask, &bmi, DIB_RGB_COLORS ); + SelectObject( hdcMask, hgdiobjOld ); + + if( !bBWCursor ) + { + pcrArrayColor = new DWORD[dwWidth * dwHeightDest]; + hdcColor = CreateCompatibleDC( hdcScreen ); + if( hdcColor == NULL ) + { + hr = E_FAIL; + goto End; + } + SelectObject( hdcColor, iconinfo.hbmColor ); + GetDIBits( hdcColor, iconinfo.hbmColor, 0, dwHeightDest, + pcrArrayColor, &bmi, DIB_RGB_COLORS ); + } + + // Transfer cursor image into the surface + D3DLOCKED_RECT lr; + pCursorSurface->LockRect( &lr, NULL, 0 ); + pBitmap = ( DWORD* )lr.pBits; + for( y = 0; y < dwHeightDest; y++ ) + { + for( x = 0; x < dwWidth; x++ ) + { + if( bBWCursor ) + { + crColor = pcrArrayMask[dwWidth * ( dwHeightDest - 1 - y ) + x]; + crMask = pcrArrayMask[dwWidth * ( dwHeightSrc - 1 - y ) + x]; + } + else + { + crColor = pcrArrayColor[dwWidth * ( dwHeightDest - 1 - y ) + x]; + crMask = pcrArrayMask[dwWidth * ( dwHeightDest - 1 - y ) + x]; + } + if( crMask == 0 ) + pBitmap[dwWidth * y + x] = 0xff000000 | crColor; + else + pBitmap[dwWidth * y + x] = 0x00000000; + + // It may be helpful to make the D3D cursor look slightly + // different from the Windows cursor so you can distinguish + // between the two when developing/testing code. When + // bAddWatermark is TRUE, the following code adds some + // small grey "D3D" characters to the upper-left corner of + // the D3D cursor image. + if( bAddWatermark && x < 12 && y < 5 ) + { + // 11.. 11.. 11.. .... CCC0 + // 1.1. ..1. 1.1. .... A2A0 + // 1.1. .1.. 1.1. .... A4A0 + // 1.1. ..1. 1.1. .... A2A0 + // 11.. 11.. 11.. .... CCC0 + + const WORD wMask[5] = { 0xccc0, 0xa2a0, 0xa4a0, 0xa2a0, 0xccc0 }; + if( wMask[y] & (1 << (15 - x)) ) + { + pBitmap[dwWidth*y + x] |= 0xff808080; + } + } + } + } + pCursorSurface->UnlockRect(); + + // Set the device cursor + if( FAILED( hr = pd3dDevice->SetCursorProperties( iconinfo.xHotspot, + iconinfo.yHotspot, pCursorSurface ) ) ) + { + goto End; + } + + hr = S_OK; + +End: + if( iconinfo.hbmMask != NULL ) + DeleteObject( iconinfo.hbmMask ); + if( iconinfo.hbmColor != NULL ) + DeleteObject( iconinfo.hbmColor ); + if( hdcScreen != NULL ) + ReleaseDC( NULL, hdcScreen ); + if( hdcColor != NULL ) + DeleteDC( hdcColor ); + if( hdcMask != NULL ) + DeleteDC( hdcMask ); + SAFE_DELETE_ARRAY( pcrArrayColor ); + SAFE_DELETE_ARRAY( pcrArrayMask ); + SAFE_RELEASE( pCursorSurface ); + return hr; +} + + +//-------------------------------------------------------------------------------------- +// Internal helper function to return the adapter format from the first device settings +// combo that matches the passed adapter ordinal, device type, backbuffer format, and windowed. +//-------------------------------------------------------------------------------------- +HRESULT DXUTFindD3D9AdapterFormat( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT BackBufferFormat, + BOOL Windowed, D3DFORMAT* pAdapterFormat ) +{ + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration( false ); + CD3D9EnumDeviceInfo* pDeviceInfo = pd3dEnum->GetDeviceInfo( AdapterOrdinal, DeviceType ); + if( pDeviceInfo ) + { + for( int iDeviceCombo = 0; iDeviceCombo < pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ ) + { + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt( + iDeviceCombo ); + if( pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat && + pDeviceSettingsCombo->Windowed == Windowed ) + { + // Return the adapter format from the first match + *pAdapterFormat = pDeviceSettingsCombo->AdapterFormat; + return S_OK; + } + } + } + + *pAdapterFormat = BackBufferFormat; + return E_FAIL; +} + +//-------------------------------------------------------------------------------------- +// Sets the viewport, render target view, and depth stencil view. +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTSetupD3D11Views( ID3D11DeviceContext* pd3dDeviceContext ) +{ + HRESULT hr = S_OK; + + // Setup the viewport to match the backbuffer + D3D11_VIEWPORT vp; + vp.Width = (FLOAT)DXUTGetDXGIBackBufferSurfaceDesc()->Width; + vp.Height = (FLOAT)DXUTGetDXGIBackBufferSurfaceDesc()->Height; + vp.MinDepth = 0; + vp.MaxDepth = 1; + vp.TopLeftX = 0; + vp.TopLeftY = 0; + pd3dDeviceContext->RSSetViewports( 1, &vp ); + + // Set the render targets + ID3D11RenderTargetView* pRTV = GetDXUTState().GetD3D11RenderTargetView(); + ID3D11DepthStencilView* pDSV = GetDXUTState().GetD3D11DepthStencilView(); + pd3dDeviceContext->OMSetRenderTargets( 1, &pRTV, pDSV ); + + return hr; +} + + +//-------------------------------------------------------------------------------------- +// Creates a render target view, and depth stencil texture and view. +//-------------------------------------------------------------------------------------- +HRESULT DXUTCreateD3D11Views( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, + DXUTDeviceSettings* pDeviceSettings ) +{ + HRESULT hr = S_OK; + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + ID3D11DepthStencilView* pDSV = NULL; + ID3D11RenderTargetView* pRTV = NULL; + + // Get the back buffer and desc + ID3D11Texture2D* pBackBuffer; + hr = pSwapChain->GetBuffer( 0, __uuidof( *pBackBuffer ), ( LPVOID* )&pBackBuffer ); + if( FAILED( hr ) ) + return hr; + D3D11_TEXTURE2D_DESC backBufferSurfaceDesc; + pBackBuffer->GetDesc( &backBufferSurfaceDesc ); + + // Create the render target view + hr = pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &pRTV ); + SAFE_RELEASE( pBackBuffer ); + if( FAILED( hr ) ) + return hr; + GetDXUTState().SetD3D11RenderTargetView( pRTV ); + + if( pDeviceSettings->d3d11.AutoCreateDepthStencil ) + { + // Create depth stencil texture + ID3D11Texture2D* pDepthStencil = NULL; + D3D11_TEXTURE2D_DESC descDepth; + descDepth.Width = backBufferSurfaceDesc.Width; + descDepth.Height = backBufferSurfaceDesc.Height; + descDepth.MipLevels = 1; + descDepth.ArraySize = 1; + descDepth.Format = pDeviceSettings->d3d11.AutoDepthStencilFormat; + descDepth.SampleDesc.Count = pDeviceSettings->d3d11.sd.SampleDesc.Count; + descDepth.SampleDesc.Quality = pDeviceSettings->d3d11.sd.SampleDesc.Quality; + descDepth.Usage = D3D11_USAGE_DEFAULT; + descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; + descDepth.CPUAccessFlags = 0; + descDepth.MiscFlags = 0; + hr = pd3dDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); + if( FAILED( hr ) ) + return hr; + GetDXUTState().SetD3D11DepthStencil( pDepthStencil ); + + // Create the depth stencil view + D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; + descDSV.Format = descDepth.Format; + descDSV.Flags = 0; + if( descDepth.SampleDesc.Count > 1 ) + descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + else + descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + descDSV.Texture2D.MipSlice = 0; + hr = pd3dDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &pDSV ); + if( FAILED( hr ) ) + return hr; + GetDXUTState().SetD3D11DepthStencilView( pDSV ); + } + + hr = DXUTSetupD3D11Views( pd3dImmediateContext ); + if( FAILED( hr ) ) + return hr; + + return hr; +} + + +//-------------------------------------------------------------------------------------- +// Creates the 3D environment +//-------------------------------------------------------------------------------------- +HRESULT DXUTCreate3DEnvironment11( ID3D11Device* pd3d11DeviceFromApp ) +{ + HRESULT hr = S_OK; + + ID3D11Device* pd3d11Device = NULL; + ID3D11DeviceContext* pd3dImmediateContext = NULL; + D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_0; + + IDXGISwapChain* pSwapChain = NULL; + DXUTDeviceSettings* pNewDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + + IDXGIFactory1* pDXGIFactory = DXUTGetDXGIFactory(); + hr = pDXGIFactory->MakeWindowAssociation( DXUTGetHWND(), 0 ); + + // Only create a Direct3D device if one hasn't been supplied by the app + if( pd3d11DeviceFromApp == NULL ) + { + // Try to create the device with the chosen settings + IDXGIAdapter1* pAdapter = NULL; + + hr = S_OK; + D3D_DRIVER_TYPE ddt = pNewDeviceSettings->d3d11.DriverType; + if( pNewDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_HARDWARE ) + { + hr = pDXGIFactory->EnumAdapters1( pNewDeviceSettings->d3d11.AdapterOrdinal, &pAdapter ); + if ( FAILED( hr) ) + { + return E_FAIL; + } + ddt = D3D_DRIVER_TYPE_UNKNOWN; + } + else if (pNewDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_WARP) + { + ddt = D3D_DRIVER_TYPE_WARP; + pAdapter = NULL; + } + else if (pNewDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE) + { + ddt = D3D_DRIVER_TYPE_REFERENCE; + pAdapter = NULL; + } + + if( SUCCEEDED( hr ) ) + { + + hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter, + ddt, + ( HMODULE )0, + pNewDeviceSettings->d3d11.CreateFlags, + &pNewDeviceSettings->d3d11.DeviceFeatureLevel, + 1, + D3D11_SDK_VERSION, + &pd3d11Device, + &FeatureLevel, + &pd3dImmediateContext + ); + + if ( FAILED( hr ) ) { + pAdapter = NULL; + // Remote desktop does not allow you to enumerate the adapter. In this case, we let D3D11 do the enumeration. + if ( ddt == D3D_DRIVER_TYPE_UNKNOWN ) { + hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter, + D3D_DRIVER_TYPE_HARDWARE, + ( HMODULE )0, + pNewDeviceSettings->d3d11.CreateFlags, + &pNewDeviceSettings->d3d11.DeviceFeatureLevel, + 1, + D3D11_SDK_VERSION, + &pd3d11Device, + &FeatureLevel, + &pd3dImmediateContext + ); + } + if ( FAILED ( hr ) ) { + DXUT_ERR( L"D3D11CreateDevice", hr ); + return DXUTERR_CREATINGDEVICE; + } + } + } + + if( SUCCEEDED( hr ) ) + { + IDXGIDevice1* pDXGIDev = NULL; + hr = pd3d11Device->QueryInterface( __uuidof( IDXGIDevice1 ), ( LPVOID* )&pDXGIDev ); + if( SUCCEEDED( hr ) && pDXGIDev ) + { + if ( pAdapter == NULL ) + { + IDXGIAdapter *pTempAdapter; + pDXGIDev->GetAdapter( &pTempAdapter ); + V_RETURN( pTempAdapter->QueryInterface( __uuidof( IDXGIAdapter1 ), (LPVOID*) &pAdapter ) ); + V_RETURN( pAdapter->GetParent( __uuidof( IDXGIFactory1 ), (LPVOID*) &pDXGIFactory ) ); + SAFE_RELEASE ( pTempAdapter ); + GetDXUTState().SetDXGIFactory( pDXGIFactory ); + } + } + SAFE_RELEASE( pDXGIDev ); + GetDXUTState().SetDXGIAdapter( pAdapter ); + } + + // set default render state to msaa enabled + D3D11_RASTERIZER_DESC drd = { + D3D11_FILL_SOLID, //D3D11_FILL_MODE FillMode; + D3D11_CULL_BACK,//D3D11_CULL_MODE CullMode; + FALSE, //BOOL FrontCounterClockwise; + 0, //INT DepthBias; + 0.0f,//FLOAT DepthBiasClamp; + 0.0f,//FLOAT SlopeScaledDepthBias; + TRUE,//BOOL DepthClipEnable; + FALSE,//BOOL ScissorEnable; + TRUE,//BOOL MultisampleEnable; + FALSE//BOOL AntialiasedLineEnable; + }; + if( FAILED( hr ) ) + { + DXUT_ERR( L"D3D11CreateDevice", hr ); + return DXUTERR_CREATINGDEVICE; + } + ID3D11RasterizerState* pRS = NULL; + pd3d11Device->CreateRasterizerState(&drd, &pRS); + GetDXUTState().SetD3D11RasterizerState(pRS); + pd3dImmediateContext->RSSetState(pRS); + + + + + // Enumerate its outputs. + UINT OutputCount, iOutput; + for( OutputCount = 0; ; ++OutputCount ) + { + IDXGIOutput* pOutput; + if( FAILED( pAdapter->EnumOutputs( OutputCount, &pOutput ) ) ) + break; + SAFE_RELEASE( pOutput ); + } + IDXGIOutput** ppOutputArray = new IDXGIOutput*[OutputCount]; + if( !ppOutputArray ) + return E_OUTOFMEMORY; + for( iOutput = 0; iOutput < OutputCount; ++iOutput ) + pAdapter->EnumOutputs( iOutput, ppOutputArray + iOutput ); + GetDXUTState().SetDXGIOutputArray( ppOutputArray ); + GetDXUTState().SetDXGIOutputArraySize( OutputCount ); + + // Create the swapchain + + hr = pDXGIFactory->CreateSwapChain( pd3d11Device, &pNewDeviceSettings->d3d11.sd, &pSwapChain ); + + if( FAILED( hr ) ) + { + DXUT_ERR( L"CreateSwapChain", hr ); + return DXUTERR_CREATINGDEVICE; + } + } + else + { + pd3d11DeviceFromApp->AddRef(); + pd3d11Device = pd3d11DeviceFromApp; + } + + GetDXUTState().SetD3D11Device( pd3d11Device ); + GetDXUTState().SetD3D11DeviceContext( pd3dImmediateContext ); + GetDXUTState().SetD3D11FeatureLevel( FeatureLevel ); + GetDXUTState().SetDXGISwapChain( pSwapChain ); + + // If switching to REF, set the exit code to 11. If switching to HAL and exit code was 11, then set it back to 0. + if( pNewDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE && GetDXUTState().GetExitCode() == 0 ) + GetDXUTState().SetExitCode( 10 ); + else if( pNewDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_HARDWARE && GetDXUTState().GetExitCode() == 10 ) + GetDXUTState().SetExitCode( 0 ); + + // Update back buffer desc before calling app's device callbacks + DXUTUpdateBackBufferDesc(); + + // Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state) + DXUTSetupCursor(); + + // Update the device stats text + CD3D11Enumeration* pd3dEnum = DXUTGetD3D11Enumeration(); + CD3D11EnumAdapterInfo* pAdapterInfo = pd3dEnum->GetAdapterInfo( pNewDeviceSettings->d3d11.AdapterOrdinal ); + DXUTUpdateD3D11DeviceStats( pNewDeviceSettings->d3d11.DriverType, &pAdapterInfo->AdapterDesc ); + + // Call the app's device created callback if non-NULL + const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc = DXUTGetDXGIBackBufferSurfaceDesc(); + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D11DEVICECREATED pCallbackDeviceCreated = GetDXUTState().GetD3D11DeviceCreatedFunc(); + hr = S_OK; + if( pCallbackDeviceCreated != NULL ) + hr = pCallbackDeviceCreated( DXUTGetD3D11Device(), pBackBufferSurfaceDesc, + GetDXUTState().GetD3D11DeviceCreatedFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + if( DXUTGetD3D11Device() == NULL ) // Handle DXUTShutdown from inside callback + return E_FAIL; + if( FAILED( hr ) ) + { + DXUT_ERR( L"DeviceCreated callback", hr ); + return ( hr == DXUTERR_MEDIANOTFOUND ) ? DXUTERR_MEDIANOTFOUND : DXUTERR_CREATINGDEVICEOBJECTS; + } + GetDXUTState().SetDeviceObjectsCreated( true ); + + // Setup the render target view and viewport + hr = DXUTCreateD3D11Views( pd3d11Device, pd3dImmediateContext, pNewDeviceSettings ); + if( FAILED( hr ) ) + { + DXUT_ERR( L"DXUTCreateD3D11Views", hr ); + return DXUTERR_CREATINGDEVICEOBJECTS; + } + + // Create performance counters + //DXUTCreateD3D11Counters( pd3d11Device ); + + // Call the app's swap chain reset callback if non-NULL + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D11SWAPCHAINRESIZED pCallbackSwapChainResized = GetDXUTState().GetD3D11SwapChainResizedFunc(); + hr = S_OK; + if( pCallbackSwapChainResized != NULL ) + hr = pCallbackSwapChainResized( DXUTGetD3D11Device(), pSwapChain, pBackBufferSurfaceDesc, + GetDXUTState().GetD3D11SwapChainResizedFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + if( DXUTGetD3D11Device() == NULL ) // Handle DXUTShutdown from inside callback + return E_FAIL; + if( FAILED( hr ) ) + { + DXUT_ERR( L"DeviceReset callback", hr ); + return ( hr == DXUTERR_MEDIANOTFOUND ) ? DXUTERR_MEDIANOTFOUND : DXUTERR_RESETTINGDEVICEOBJECTS; + } + GetDXUTState().SetDeviceObjectsReset( true ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Resets the 3D environment by: +// - Calls the device lost callback +// - Resets the device +// - Stores the back buffer description +// - Sets up the full screen Direct3D cursor if requested +// - Calls the device reset callback +//-------------------------------------------------------------------------------------- +HRESULT DXUTReset3DEnvironment11() +{ + HRESULT hr; + + GetDXUTState().SetDeviceObjectsReset( false ); + DXUTPause( true, true ); + + bool bDeferredDXGIAction = false; + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + + DXGI_SWAP_CHAIN_DESC SCDesc; + pSwapChain->GetDesc( &SCDesc ); + + // Resize backbuffer and target of the swapchain in case they have changed. + // For windowed mode, use the client rect as the desired size. Unlike D3D9, + // we can't use 0 for width or height. Therefore, fill in the values from + // the window size. For fullscreen mode, the width and height should have + // already been filled with the desktop resolution, so don't change it. + if( pDeviceSettings->d3d11.sd.Windowed && SCDesc.Windowed ) + { + RECT rcWnd; + GetClientRect( DXUTGetHWND(), &rcWnd ); + pDeviceSettings->d3d11.sd.BufferDesc.Width = rcWnd.right - rcWnd.left; + pDeviceSettings->d3d11.sd.BufferDesc.Height = rcWnd.bottom - rcWnd.top; + } + + // If the app wants to switch from windowed to fullscreen or vice versa, + // call the swapchain's SetFullscreenState + // mode. + if( SCDesc.Windowed != pDeviceSettings->d3d11.sd.Windowed ) + { + // Set the fullscreen state + if( pDeviceSettings->d3d11.sd.Windowed ) + { + V_RETURN( pSwapChain->SetFullscreenState( FALSE, NULL ) ); + bDeferredDXGIAction = true; + } + else + { + // Set fullscreen state by setting the display mode to fullscreen, then changing the resolution + // to the desired value. + + // SetFullscreenState causes a WM_SIZE message to be sent to the window. The WM_SIZE message calls + // DXUTCheckForDXGIBufferChange which normally stores the new height and width in + // pDeviceSettings->d3d11.sd.BufferDesc. SetDoNotStoreBufferSize tells DXUTCheckForDXGIBufferChange + // not to store the height and width so that we have the correct values when calling ResizeTarget. + + GetDXUTState().SetDoNotStoreBufferSize( true ); + V_RETURN( pSwapChain->SetFullscreenState( TRUE, NULL ) ); + GetDXUTState().SetDoNotStoreBufferSize( false ); + + V_RETURN( pSwapChain->ResizeTarget( &pDeviceSettings->d3d11.sd.BufferDesc ) ); + bDeferredDXGIAction = true; + } + } + else + { + if( pDeviceSettings->d3d11.sd.BufferDesc.Width == SCDesc.BufferDesc.Width && + pDeviceSettings->d3d11.sd.BufferDesc.Height == SCDesc.BufferDesc.Height && + pDeviceSettings->d3d11.sd.BufferDesc.Format != SCDesc.BufferDesc.Format ) + { + DXUTResizeDXGIBuffers( 0, 0, !pDeviceSettings->d3d11.sd.Windowed ); + bDeferredDXGIAction = true; + } + else if( pDeviceSettings->d3d11.sd.BufferDesc.Width != SCDesc.BufferDesc.Width || + pDeviceSettings->d3d11.sd.BufferDesc.Height != SCDesc.BufferDesc.Height ) + { + V_RETURN( pSwapChain->ResizeTarget( &pDeviceSettings->d3d11.sd.BufferDesc ) ); + bDeferredDXGIAction = true; + } + } + + // If no deferred DXGI actions are to take place, mark the device as reset. + // If there is a deferred DXGI action, then the device isn't reset until DXGI sends us a + // window message. Only then can we mark the device as reset. + if( !bDeferredDXGIAction ) + GetDXUTState().SetDeviceObjectsReset( true ); + DXUTPause( false, false ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Render the 3D environment by: +// - Checking if the device is lost and trying to reset it if it is +// - Get the elapsed time since the last frame +// - Calling the app's framemove and render callback +// - Calling Present() +//-------------------------------------------------------------------------------------- +void DXUTRender3DEnvironment11() +{ + HRESULT hr; + + ID3D11Device* pd3dDevice = DXUTGetD3D11Device(); + if( NULL == pd3dDevice ) + return; + + ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); + if( NULL == pd3dImmediateContext ) + return; + + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + if( NULL == pSwapChain ) + return; + + if( DXUTIsRenderingPaused() || !DXUTIsActive() || GetDXUTState().GetRenderingOccluded() ) + { + // Window is minimized/paused/occluded/or not exclusive so yield CPU time to other processes + Sleep( 50 ); + } + + // Get the app's time, in seconds. Skip rendering if no time elapsed + double fTime, fAbsTime; float fElapsedTime; + DXUTGetGlobalTimer()->GetTimeValues( &fTime, &fAbsTime, &fElapsedTime ); + + // Store the time for the app + if( GetDXUTState().GetConstantFrameTime() ) + { + fElapsedTime = GetDXUTState().GetTimePerFrame(); + fTime = DXUTGetTime() + fElapsedTime; + } + + GetDXUTState().SetTime( fTime ); + GetDXUTState().SetAbsoluteTime( fAbsTime ); + GetDXUTState().SetElapsedTime( fElapsedTime ); + + // Start Performance Counters + + // Update the FPS stats + DXUTUpdateFrameStats(); + + DXUTHandleTimers(); + + // Animate the scene by calling the app's frame move callback + LPDXUTCALLBACKFRAMEMOVE pCallbackFrameMove = GetDXUTState().GetFrameMoveFunc(); + if( pCallbackFrameMove != NULL ) + { + pCallbackFrameMove( fTime, fElapsedTime, GetDXUTState().GetFrameMoveFuncUserContext() ); + pd3dDevice = DXUTGetD3D11Device(); + if( NULL == pd3dDevice ) // Handle DXUTShutdown from inside callback + return; + } + + if( !GetDXUTState().GetRenderingPaused() ) + { + // Render the scene by calling the app's render callback + LPDXUTCALLBACKD3D11FRAMERENDER pCallbackFrameRender = GetDXUTState().GetD3D11FrameRenderFunc(); + if( pCallbackFrameRender != NULL && !GetDXUTState().GetRenderingOccluded() ) + { + pCallbackFrameRender( pd3dDevice, pd3dImmediateContext, fTime, fElapsedTime, + GetDXUTState().GetD3D11FrameRenderFuncUserContext() ); + + pd3dDevice = DXUTGetD3D11Device(); + if( NULL == pd3dDevice ) // Handle DXUTShutdown from inside callback + return; + } + +#if defined(DEBUG) || defined(_DEBUG) + // The back buffer should always match the client rect + // if the Direct3D backbuffer covers the entire window + RECT rcClient; + GetClientRect( DXUTGetHWND(), &rcClient ); + if( !IsIconic( DXUTGetHWND() ) ) + { + GetClientRect( DXUTGetHWND(), &rcClient ); + + assert( DXUTGetDXGIBackBufferSurfaceDesc()->Width == (UINT)rcClient.right ); + assert( DXUTGetDXGIBackBufferSurfaceDesc()->Height == (UINT)rcClient.bottom ); + } +#endif + } + + if ( GetDXUTState().GetSaveScreenShot() ) { + DXUTSnapD3D11Screenshot( GetDXUTState().GetScreenShotName(), D3DX11_IFF_BMP ); + } + if ( GetDXUTState().GetExitAfterScreenShot() ) { + DXUTShutdown(); + return; + } + + DWORD dwFlags = 0; + if( GetDXUTState().GetRenderingOccluded() ) + dwFlags = DXGI_PRESENT_TEST; + else + dwFlags = GetDXUTState().GetCurrentDeviceSettings()->d3d11.PresentFlags; + UINT SyncInterval = GetDXUTState().GetCurrentDeviceSettings()->d3d11.SyncInterval; + + // Show the frame on the primary surface. + hr = pSwapChain->Present( SyncInterval, dwFlags ); + if( DXGI_STATUS_OCCLUDED == hr ) + { + // There is a window covering our entire rendering area. + // Don't render until we're visible again. + GetDXUTState().SetRenderingOccluded( true ); + } + else if( DXGI_ERROR_DEVICE_RESET == hr ) + { + // If a mode change happened, we must reset the device + if( FAILED( hr = DXUTReset3DEnvironment11() ) ) + { + if( DXUTERR_RESETTINGDEVICEOBJECTS == hr || + DXUTERR_MEDIANOTFOUND == hr ) + { + DXUTDisplayErrorMessage( hr ); + DXUTShutdown(); + return; + } + else + { + // Reset failed, but the device wasn't lost so something bad happened, + // so recreate the device to try to recover + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + if( FAILED( DXUTChangeDevice( pDeviceSettings, NULL, NULL, true, false ) ) ) + { + DXUTShutdown(); + return; + } + + // TODO: Handle display orientation changes in full-screen mode. + } + } + } + else if( DXGI_ERROR_DEVICE_REMOVED == hr ) + { + // Use a callback to ask the app if it would like to find a new device. + // If no device removed callback is set, then look for a new device + if( FAILED( DXUTHandleDeviceRemoved() ) ) + { + // TODO: use pD3DDevice->GetDeviceRemovedReason() + DXUTDisplayErrorMessage( DXUTERR_DEVICEREMOVED ); + DXUTShutdown(); + return; + } + } + else if( SUCCEEDED( hr ) ) + { + if( GetDXUTState().GetRenderingOccluded() ) + { + // Now that we're no longer occluded + // allow us to render again + GetDXUTState().SetRenderingOccluded( false ); + } + } + + // Update current frame # + int nFrame = GetDXUTState().GetCurrentFrameNumber(); + nFrame++; + GetDXUTState().SetCurrentFrameNumber( nFrame ); + + + // Update the D3D11 counter stats + //DXUTUpdateD3D11CounterStats(); + + // Check to see if the app should shutdown due to cmdline + if( GetDXUTState().GetOverrideQuitAfterFrame() != 0 ) + { + if( nFrame > GetDXUTState().GetOverrideQuitAfterFrame() ) + DXUTShutdown(); + } + + return; +} + +void ClearD3D11DeviceContext( ID3D11DeviceContext* pd3dDeviceContext ) +{ + // Unbind all objects from the immediate context + if (pd3dDeviceContext == NULL) return; + + ID3D11ShaderResourceView* pSRVs[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + ID3D11RenderTargetView* pRTVs[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + ID3D11DepthStencilView* pDSV = NULL; + ID3D11Buffer* pBuffers[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + ID3D11SamplerState* pSamplers[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + UINT StrideOffset[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + + // Shaders + pd3dDeviceContext->VSSetShader( NULL, NULL, 0 ); + pd3dDeviceContext->HSSetShader( NULL, NULL, 0 ); + pd3dDeviceContext->DSSetShader( NULL, NULL, 0 ); + pd3dDeviceContext->GSSetShader( NULL, NULL, 0 ); + pd3dDeviceContext->PSSetShader( NULL, NULL, 0 ); + + // IA clear + pd3dDeviceContext->IASetVertexBuffers( 0, 16, pBuffers, StrideOffset, StrideOffset ); + pd3dDeviceContext->IASetIndexBuffer( NULL, DXGI_FORMAT_R16_UINT, 0 ); + pd3dDeviceContext->IASetInputLayout( NULL ); + + // Constant buffers + pd3dDeviceContext->VSSetConstantBuffers( 0, 14, pBuffers ); + pd3dDeviceContext->HSSetConstantBuffers( 0, 14, pBuffers ); + pd3dDeviceContext->DSSetConstantBuffers( 0, 14, pBuffers ); + pd3dDeviceContext->GSSetConstantBuffers( 0, 14, pBuffers ); + pd3dDeviceContext->PSSetConstantBuffers( 0, 14, pBuffers ); + + // Resources + pd3dDeviceContext->VSSetShaderResources( 0, 16, pSRVs ); + pd3dDeviceContext->HSSetShaderResources( 0, 16, pSRVs ); + pd3dDeviceContext->DSSetShaderResources( 0, 16, pSRVs ); + pd3dDeviceContext->GSSetShaderResources( 0, 16, pSRVs ); + pd3dDeviceContext->PSSetShaderResources( 0, 16, pSRVs ); + + // Samplers + pd3dDeviceContext->VSSetSamplers( 0, 16, pSamplers ); + pd3dDeviceContext->HSSetSamplers( 0, 16, pSamplers ); + pd3dDeviceContext->DSSetSamplers( 0, 16, pSamplers ); + pd3dDeviceContext->GSSetSamplers( 0, 16, pSamplers ); + pd3dDeviceContext->PSSetSamplers( 0, 16, pSamplers ); + + // Render targets + pd3dDeviceContext->OMSetRenderTargets( 8, pRTVs, pDSV ); + + // States + FLOAT blendFactor[4] = { 0,0,0,0 }; + pd3dDeviceContext->OMSetBlendState( NULL, blendFactor, 0xFFFFFFFF ); + pd3dDeviceContext->OMSetDepthStencilState( NULL, 0 ); + pd3dDeviceContext->RSSetState( NULL ); +} + +//-------------------------------------------------------------------------------------- +// Cleans up the 3D environment by: +// - Calls the device lost callback +// - Calls the device destroyed callback +// - Releases the D3D device +//-------------------------------------------------------------------------------------- +void DXUTCleanup3DEnvironment11( bool bReleaseSettings ) +{ + ID3D11Device* pd3dDevice = DXUTGetD3D11Device(); + + if( pd3dDevice != NULL ) + { + if (GetDXUTState().GetD3D11RasterizerState()!= NULL ) + GetDXUTState().GetD3D11RasterizerState()->Release(); + + // Call ClearState to avoid tons of messy debug spew telling us that we're deleting bound objects + ID3D11DeviceContext* pImmediateContext = DXUTGetD3D11DeviceContext(); + ClearD3D11DeviceContext( pImmediateContext ); + + // Clear state and flush + pImmediateContext->ClearState(); + pImmediateContext->Flush(); + + // Call the app's SwapChain lost callback + GetDXUTState().SetInsideDeviceCallback( true ); + if( GetDXUTState().GetDeviceObjectsReset() ) + { + LPDXUTCALLBACKD3D11SWAPCHAINRELEASING pCallbackSwapChainReleasing = + GetDXUTState().GetD3D11SwapChainReleasingFunc(); + if( pCallbackSwapChainReleasing != NULL ) + pCallbackSwapChainReleasing( GetDXUTState().GetD3D11SwapChainReleasingFuncUserContext() ); + GetDXUTState().SetDeviceObjectsReset( false ); + } + + // Release our old depth stencil texture and view + ID3D11Texture2D* pDS = GetDXUTState().GetD3D11DepthStencil(); + SAFE_RELEASE( pDS ); + GetDXUTState().SetD3D11DepthStencil( NULL ); + ID3D11DepthStencilView* pDSV = GetDXUTState().GetD3D11DepthStencilView(); + SAFE_RELEASE( pDSV ); + GetDXUTState().SetD3D11DepthStencilView( NULL ); + + // Cleanup the render target view + ID3D11RenderTargetView* pRTV = GetDXUTState().GetD3D11RenderTargetView(); + SAFE_RELEASE( pRTV ); + GetDXUTState().SetD3D11RenderTargetView( NULL ); + + // Call the app's device destroyed callback + if( GetDXUTState().GetDeviceObjectsCreated() ) + { + LPDXUTCALLBACKD3D11DEVICEDESTROYED pCallbackDeviceDestroyed = GetDXUTState().GetD3D11DeviceDestroyedFunc(); + if( pCallbackDeviceDestroyed != NULL ) + pCallbackDeviceDestroyed( GetDXUTState().GetD3D11DeviceDestroyedFuncUserContext() ); + GetDXUTState().SetDeviceObjectsCreated( false ); + } + + GetDXUTState().SetInsideDeviceCallback( false ); + + // Release the swap chain + GetDXUTState().SetReleasingSwapChain( true ); + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + if( pSwapChain ) + { + pSwapChain->SetFullscreenState( FALSE, 0 ); + } + SAFE_RELEASE( pSwapChain ); + GetDXUTState().SetDXGISwapChain( NULL ); + GetDXUTState().SetReleasingSwapChain( false ); + + // Release the outputs. + IDXGIOutput** ppOutputArray = GetDXUTState().GetDXGIOutputArray(); + UINT OutputCount = GetDXUTState().GetDXGIOutputArraySize(); + for( UINT o = 0; o < OutputCount; ++o ) + SAFE_RELEASE( ppOutputArray[o] ); + delete[] ppOutputArray; + GetDXUTState().SetDXGIOutputArray( NULL ); + GetDXUTState().SetDXGIOutputArraySize( 0 ); + + // Release the D3D adapter. + IDXGIAdapter* pAdapter = GetDXUTState().GetDXGIAdapter(); + SAFE_RELEASE( pAdapter ); + GetDXUTState().SetDXGIAdapter( NULL ); + + // Release the counters + //DXUTDestroyD3D11Counters(); + + // Release the D3D11 immediate context (if it exists) because it has a extra ref count on it + ID3D11DeviceContext* pd3d11DeviceContext = GetDXUTState().GetD3D11DeviceContext(); + SAFE_RELEASE( pd3d11DeviceContext ); + GetDXUTState().SetD3D11DeviceContext( NULL ); + + // Release the D3D device and in debug configs, displays a message box if there + // are unrelease objects. + if( pd3dDevice ) + { + UINT references = pd3dDevice->Release(); + if( references > 0 ) + { + DXUTDisplayErrorMessage( DXUTERR_NONZEROREFCOUNT ); + DXUT_ERR( L"DXUTCleanup3DEnvironment", DXUTERR_NONZEROREFCOUNT ); + } + } + GetDXUTState().SetD3D11Device( NULL ); + + if( bReleaseSettings ) + { + DXUTDeviceSettings* pOldDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + SAFE_DELETE(pOldDeviceSettings); + GetDXUTState().SetCurrentDeviceSettings( NULL ); + } + + DXGI_SURFACE_DESC* pBackBufferSurfaceDesc = GetDXUTState().GetBackBufferSurfaceDescDXGI(); + ZeroMemory( pBackBufferSurfaceDesc, sizeof( DXGI_SURFACE_DESC ) ); + + GetDXUTState().SetDeviceCreated( false ); + } +} + + +//-------------------------------------------------------------------------------------- +// Low level keyboard hook to disable Windows key to prevent accidental task switching. +//-------------------------------------------------------------------------------------- +LRESULT CALLBACK DXUTLowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + if( nCode < 0 || nCode != HC_ACTION ) // do not process message + return CallNextHookEx( GetDXUTState().GetKeyboardHook(), nCode, wParam, lParam ); + + bool bEatKeystroke = false; + KBDLLHOOKSTRUCT* p = ( KBDLLHOOKSTRUCT* )lParam; + switch( wParam ) + { + case WM_KEYDOWN: + case WM_KEYUP: + { + bEatKeystroke = ( !GetDXUTState().GetAllowShortcutKeys() && + ( p->vkCode == VK_LWIN || p->vkCode == VK_RWIN ) ); + break; + } + } + + if( bEatKeystroke ) + return 1; + else + return CallNextHookEx( GetDXUTState().GetKeyboardHook(), nCode, wParam, lParam ); +} + + + +//-------------------------------------------------------------------------------------- +// Controls how DXUT behaves when fullscreen and windowed mode with regard to +// shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut) +//-------------------------------------------------------------------------------------- +void WINAPI DXUTSetShortcutKeySettings( bool bAllowWhenFullscreen, bool bAllowWhenWindowed ) +{ + GetDXUTState().SetAllowShortcutKeysWhenWindowed( bAllowWhenWindowed ); + GetDXUTState().SetAllowShortcutKeysWhenFullscreen( bAllowWhenFullscreen ); + + // DXUTInit() records initial accessibility states so don't change them until then + if( GetDXUTState().GetDXUTInited() ) + { + if( DXUTIsWindowed() ) + DXUTAllowShortcutKeys( GetDXUTState().GetAllowShortcutKeysWhenWindowed() ); + else + DXUTAllowShortcutKeys( GetDXUTState().GetAllowShortcutKeysWhenFullscreen() ); + } +} + + +//-------------------------------------------------------------------------------------- +// Enables/disables Windows keys, and disables or restores the StickyKeys/ToggleKeys/FilterKeys +// shortcut to help prevent accidental task switching +//-------------------------------------------------------------------------------------- +void DXUTAllowShortcutKeys( bool bAllowKeys ) +{ + GetDXUTState().SetAllowShortcutKeys( bAllowKeys ); + + if( bAllowKeys ) + { + // Restore StickyKeys/etc to original state and enable Windows key + STICKYKEYS sk = GetDXUTState().GetStartupStickyKeys(); + TOGGLEKEYS tk = GetDXUTState().GetStartupToggleKeys(); + FILTERKEYS fk = GetDXUTState().GetStartupFilterKeys(); + + SystemParametersInfo( SPI_SETSTICKYKEYS, sizeof( STICKYKEYS ), &sk, 0 ); + SystemParametersInfo( SPI_SETTOGGLEKEYS, sizeof( TOGGLEKEYS ), &tk, 0 ); + SystemParametersInfo( SPI_SETFILTERKEYS, sizeof( FILTERKEYS ), &fk, 0 ); + + // Remove the keyboard hoook when it isn't needed to prevent any slow down of other apps + if( GetDXUTState().GetKeyboardHook() ) + { + UnhookWindowsHookEx( GetDXUTState().GetKeyboardHook() ); + GetDXUTState().SetKeyboardHook( NULL ); + } + } + else + { + // Set low level keyboard hook if haven't already + if( GetDXUTState().GetKeyboardHook() == NULL ) + { + // Set the low-level hook procedure. Only works on Windows 2000 and above + OSVERSIONINFO OSVersionInfo; + OSVersionInfo.dwOSVersionInfoSize = sizeof( OSVersionInfo ); + GetVersionEx( &OSVersionInfo ); + if( OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && OSVersionInfo.dwMajorVersion > 4 ) + { + HHOOK hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, DXUTLowLevelKeyboardProc, + GetModuleHandle( NULL ), 0 ); + GetDXUTState().SetKeyboardHook( hKeyboardHook ); + } + } + + // Disable StickyKeys/etc shortcuts but if the accessibility feature is on, + // then leave the settings alone as its probably being usefully used + + STICKYKEYS skOff = GetDXUTState().GetStartupStickyKeys(); + if( ( skOff.dwFlags & SKF_STICKYKEYSON ) == 0 ) + { + // Disable the hotkey and the confirmation + skOff.dwFlags &= ~SKF_HOTKEYACTIVE; + skOff.dwFlags &= ~SKF_CONFIRMHOTKEY; + + SystemParametersInfo( SPI_SETSTICKYKEYS, sizeof( STICKYKEYS ), &skOff, 0 ); + } + + TOGGLEKEYS tkOff = GetDXUTState().GetStartupToggleKeys(); + if( ( tkOff.dwFlags & TKF_TOGGLEKEYSON ) == 0 ) + { + // Disable the hotkey and the confirmation + tkOff.dwFlags &= ~TKF_HOTKEYACTIVE; + tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY; + + SystemParametersInfo( SPI_SETTOGGLEKEYS, sizeof( TOGGLEKEYS ), &tkOff, 0 ); + } + + FILTERKEYS fkOff = GetDXUTState().GetStartupFilterKeys(); + if( ( fkOff.dwFlags & FKF_FILTERKEYSON ) == 0 ) + { + // Disable the hotkey and the confirmation + fkOff.dwFlags &= ~FKF_HOTKEYACTIVE; + fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY; + + SystemParametersInfo( SPI_SETFILTERKEYS, sizeof( FILTERKEYS ), &fkOff, 0 ); + } + } +} + + +//-------------------------------------------------------------------------------------- +// Pauses time or rendering. Keeps a ref count so pausing can be layered +//-------------------------------------------------------------------------------------- +void WINAPI DXUTPause( bool bPauseTime, bool bPauseRendering ) +{ + int nPauseTimeCount = GetDXUTState().GetPauseTimeCount(); + if( bPauseTime ) nPauseTimeCount++; + else + nPauseTimeCount--; + if( nPauseTimeCount < 0 ) nPauseTimeCount = 0; + GetDXUTState().SetPauseTimeCount( nPauseTimeCount ); + + int nPauseRenderingCount = GetDXUTState().GetPauseRenderingCount(); + if( bPauseRendering ) nPauseRenderingCount++; + else + nPauseRenderingCount--; + if( nPauseRenderingCount < 0 ) nPauseRenderingCount = 0; + GetDXUTState().SetPauseRenderingCount( nPauseRenderingCount ); + + if( nPauseTimeCount > 0 ) + { + // Stop the scene from animating + DXUTGetGlobalTimer()->Stop(); + } + else + { + // Restart the timer + DXUTGetGlobalTimer()->Start(); + } + + GetDXUTState().SetRenderingPaused( nPauseRenderingCount > 0 ); + GetDXUTState().SetTimePaused( nPauseTimeCount > 0 ); +} + + +//-------------------------------------------------------------------------------------- +// Starts a user defined timer callback +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTSetTimer( LPDXUTCALLBACKTIMER pCallbackTimer, float fTimeoutInSecs, UINT* pnIDEvent, + void* pCallbackUserContext ) +{ + if( pCallbackTimer == NULL ) + return DXUT_ERR_MSGBOX( L"DXUTSetTimer", E_INVALIDARG ); + + HRESULT hr; + DXUT_TIMER DXUTTimer; + DXUTTimer.pCallbackTimer = pCallbackTimer; + DXUTTimer.pCallbackUserContext = pCallbackUserContext; + DXUTTimer.fTimeoutInSecs = fTimeoutInSecs; + DXUTTimer.fCountdown = fTimeoutInSecs; + DXUTTimer.bEnabled = true; + DXUTTimer.nID = GetDXUTState().GetTimerLastID() + 1; + GetDXUTState().SetTimerLastID( DXUTTimer.nID ); + + CGrowableArray * pTimerList = GetDXUTState().GetTimerList(); + if( pTimerList == NULL ) + { + pTimerList = new CGrowableArray ; + if( pTimerList == NULL ) + return E_OUTOFMEMORY; + GetDXUTState().SetTimerList( pTimerList ); + } + + if( FAILED( hr = pTimerList->Add( DXUTTimer ) ) ) + return hr; + + if( pnIDEvent ) + *pnIDEvent = DXUTTimer.nID; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Stops a user defined timer callback +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTKillTimer( UINT nIDEvent ) +{ + CGrowableArray * pTimerList = GetDXUTState().GetTimerList(); + if( pTimerList == NULL ) + return S_FALSE; + + bool bFound = false; + + for( int i = 0; i < pTimerList->GetSize(); i++ ) + { + DXUT_TIMER DXUTTimer = pTimerList->GetAt( i ); + if( DXUTTimer.nID == nIDEvent ) + { + DXUTTimer.bEnabled = false; + pTimerList->SetAt( i, DXUTTimer ); + bFound = true; + break; + } + } + + if( !bFound ) + return DXUT_ERR_MSGBOX( L"DXUTKillTimer", E_INVALIDARG ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Internal helper function to handle calling the user defined timer callbacks +//-------------------------------------------------------------------------------------- +void DXUTHandleTimers() +{ + float fElapsedTime = DXUTGetElapsedTime(); + + CGrowableArray * pTimerList = GetDXUTState().GetTimerList(); + if( pTimerList == NULL ) + return; + + // Walk through the list of timer callbacks + for( int i = 0; i < pTimerList->GetSize(); i++ ) + { + DXUT_TIMER DXUTTimer = pTimerList->GetAt( i ); + if( DXUTTimer.bEnabled ) + { + DXUTTimer.fCountdown -= fElapsedTime; + + // Call the callback if count down expired + if( DXUTTimer.fCountdown < 0 ) + { + DXUTTimer.pCallbackTimer( DXUTTimer.nID, DXUTTimer.pCallbackUserContext ); + // The callback my have changed the timer. + DXUTTimer = pTimerList->GetAt( i ); + DXUTTimer.fCountdown = DXUTTimer.fTimeoutInSecs; + } + pTimerList->SetAt( i, DXUTTimer ); + } + } +} + + +//-------------------------------------------------------------------------------------- +// Display an custom error msg box +//-------------------------------------------------------------------------------------- +void DXUTDisplayErrorMessage( HRESULT hr ) +{ + WCHAR strBuffer[512]; + + int nExitCode; + bool bFound = true; + switch( hr ) + { + case DXUTERR_NODIRECT3D: + { + nExitCode = 2; + if( DXUTDoesAppSupportD3D11() && !DXUTDoesAppSupportD3D9() ) + wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"Could not initialize Direct3D 11. " ); + else + wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"Could not initialize Direct3D 9. Check that the latest version of DirectX is correctly installed on your system. Also make sure that this program was compiled with header files that match the installed DirectX DLLs." ); + break; + } + case DXUTERR_NOCOMPATIBLEDEVICES: + nExitCode = 3; + if( GetSystemMetrics(0x1000) != 0 ) // SM_REMOTESESSION + wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"Direct3D does not work over a remote session." ); + else + wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"Could not find any compatible Direct3D devices." ); + break; + case DXUTERR_MEDIANOTFOUND: nExitCode = 4; wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"Could not find required media." ); break; + case DXUTERR_NONZEROREFCOUNT: nExitCode = 5; wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"The Direct3D device has a non-zero reference count, meaning some objects were not released." ); break; + case DXUTERR_CREATINGDEVICE: nExitCode = 6; wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"Failed creating the Direct3D device." ); break; + case DXUTERR_RESETTINGDEVICE: nExitCode = 7; wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"Failed resetting the Direct3D device." ); break; + case DXUTERR_CREATINGDEVICEOBJECTS: nExitCode = 8; wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"An error occurred in the device create callback function." ); break; + case DXUTERR_RESETTINGDEVICEOBJECTS: nExitCode = 9; wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"An error occurred in the device reset callback function." ); break; + // nExitCode 10 means the app exited using a REF device + case DXUTERR_DEVICEREMOVED: nExitCode = 11; wcscpy_s( strBuffer, ARRAYSIZE(strBuffer), L"The Direct3D device was removed." ); break; + default: bFound = false; nExitCode = 1; break; // nExitCode 1 means the API was incorrectly called + + } + + GetDXUTState().SetExitCode(nExitCode); + + bool bShowMsgBoxOnError = GetDXUTState().GetShowMsgBoxOnError(); + if( bFound && bShowMsgBoxOnError ) + { + if( DXUTGetWindowTitle()[0] == 0 ) + MessageBox( DXUTGetHWND(), strBuffer, L"DXUT Application", MB_ICONERROR | MB_OK ); + else + MessageBox( DXUTGetHWND(), strBuffer, DXUTGetWindowTitle(), MB_ICONERROR | MB_OK ); + } +} + + +//-------------------------------------------------------------------------------------- +// Internal function to map MK_* to an array index +//-------------------------------------------------------------------------------------- +int DXUTMapButtonToArrayIndex( BYTE vButton ) +{ + switch( vButton ) + { + case MK_LBUTTON: + return 0; + case VK_MBUTTON: + case MK_MBUTTON: + return 1; + case MK_RBUTTON: + return 2; + case VK_XBUTTON1: + case MK_XBUTTON1: + return 3; + case VK_XBUTTON2: + case MK_XBUTTON2: + return 4; + } + + return 0; +} + + + +//-------------------------------------------------------------------------------------- +// Toggle between full screen and windowed +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTToggleFullScreen() +{ + HRESULT hr; + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + DXUTDeviceSettings orginalDeviceSettings = DXUTGetDeviceSettings(); + + if (deviceSettings.ver == DXUT_D3D11_DEVICE) { + deviceSettings.d3d11.sd.Windowed = !deviceSettings.d3d11.sd.Windowed; // datut + if (!deviceSettings.d3d11.sd.Windowed) { + DXGI_MODE_DESC adapterDesktopDisplayMode = + { + 800, 600, { 60, 1 }, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB + }; + DXUTGetD3D11AdapterDisplayMode( deviceSettings.d3d11.AdapterOrdinal, 0, &adapterDesktopDisplayMode ); + + + deviceSettings.d3d11.sd.BufferDesc = adapterDesktopDisplayMode; + }else { + RECT r = DXUTGetWindowClientRectAtModeChange(); + deviceSettings.d3d11.sd.BufferDesc.Height = r.bottom; + deviceSettings.d3d11.sd.BufferDesc.Width = r.right; + } + }else if (deviceSettings.ver == DXUT_D3D9_DEVICE){ + deviceSettings.d3d9.pp.Windowed = !deviceSettings.d3d9.pp.Windowed; + if (!deviceSettings.d3d9.pp.Windowed) { + D3DDISPLAYMODE adapterDesktopDisplayMode; + IDirect3D9* pD3D = DXUTGetD3D9Object(); + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + pD3D->GetAdapterDisplayMode( pDeviceSettings->d3d9.AdapterOrdinal, &adapterDesktopDisplayMode ); + deviceSettings.d3d9.pp.BackBufferWidth = adapterDesktopDisplayMode.Width; + deviceSettings.d3d9.pp.BackBufferHeight = adapterDesktopDisplayMode.Height; + deviceSettings.d3d9.pp.BackBufferFormat = adapterDesktopDisplayMode.Format; + } else { + RECT r = DXUTGetWindowClientRectAtModeChange(); + deviceSettings.d3d9.pp.BackBufferHeight= r.bottom; + deviceSettings.d3d9.pp.FullScreen_RefreshRateInHz = 0; + deviceSettings.d3d9.pp.BackBufferWidth = r.right; + } + } + + hr = DXUTChangeDevice( &deviceSettings, NULL, NULL, false, false ); + + // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback so nothing changed + if( FAILED( hr ) && ( hr != E_ABORT ) ) + { + // Failed creating device, try to switch back. + HRESULT hr2 = DXUTChangeDevice( &orginalDeviceSettings, NULL, NULL, false, false ); + if( FAILED( hr2 ) ) + { + // If this failed, then shutdown + DXUTShutdown(); + } + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +// Toggle between HAL and WARP +//-------------------------------------------------------------------------------------- + +HRESULT WINAPI DXUTToggleWARP () { + HRESULT hr; + + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + DXUTDeviceSettings orginalDeviceSettings = DXUTGetDeviceSettings(); + + // Toggle between REF & HAL + if( DXUTIsCurrentDeviceD3D9() ) + { + + } + else + { + ID3D11SwitchToRef* pD3D11STR = NULL; + hr = DXUTGetD3D11Device()->QueryInterface( __uuidof( *pD3D11STR ), ( LPVOID* )&pD3D11STR ); + if( SUCCEEDED( hr ) ) + { + pD3D11STR->SetUseRef( pD3D11STR->GetUseRef() ? FALSE : TRUE ); + SAFE_RELEASE( pD3D11STR ); + return S_OK; + } + + if( deviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_HARDWARE || deviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) + deviceSettings.d3d11.DriverType = D3D_DRIVER_TYPE_WARP; + else if( deviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE || deviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_WARP ) + deviceSettings.d3d11.DriverType = D3D_DRIVER_TYPE_HARDWARE; + } + + hr = DXUTSnapDeviceSettingsToEnumDevice(&deviceSettings, false); + if( SUCCEEDED( hr ) ) + { + // Create a Direct3D device using the new device settings. + // If there is an existing device, then it will either reset or recreate the scene. + hr = DXUTChangeDevice( &deviceSettings, NULL, NULL, false, false ); + + // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback so nothing changed + if( FAILED( hr ) && ( hr != E_ABORT ) ) + { + // Failed creating device, try to switch back. + HRESULT hr2 = DXUTChangeDevice( &orginalDeviceSettings, NULL, NULL, false, false ); + if( FAILED( hr2 ) ) + { + // If this failed, then shutdown + DXUTShutdown(); + } + } + } + + return hr; +} +//-------------------------------------------------------------------------------------- +// Toggle between HAL and REF +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTToggleREF() +{ + HRESULT hr; + + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + DXUTDeviceSettings orginalDeviceSettings = DXUTGetDeviceSettings(); + + // Toggle between REF & HAL + if( DXUTIsCurrentDeviceD3D9() ) + { + if( deviceSettings.d3d9.DeviceType == D3DDEVTYPE_HAL ) + deviceSettings.d3d9.DeviceType = D3DDEVTYPE_REF; + else if( deviceSettings.d3d9.DeviceType == D3DDEVTYPE_REF ) + deviceSettings.d3d9.DeviceType = D3DDEVTYPE_HAL; + } + else + { + ID3D11SwitchToRef* pD3D11STR = NULL; + hr = DXUTGetD3D11Device()->QueryInterface( __uuidof( *pD3D11STR ), ( LPVOID* )&pD3D11STR ); + if( SUCCEEDED( hr ) ) + { + pD3D11STR->SetUseRef( pD3D11STR->GetUseRef() ? FALSE : TRUE ); + SAFE_RELEASE( pD3D11STR ); + return S_OK; + } + + if( deviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_HARDWARE ) + deviceSettings.d3d11.DriverType = D3D_DRIVER_TYPE_REFERENCE; + else if( deviceSettings.d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) + deviceSettings.d3d11.DriverType = D3D_DRIVER_TYPE_HARDWARE; + } + + hr = DXUTSnapDeviceSettingsToEnumDevice(&deviceSettings, false); + if( SUCCEEDED( hr ) ) + { + // Create a Direct3D device using the new device settings. + // If there is an existing device, then it will either reset or recreate the scene. + hr = DXUTChangeDevice( &deviceSettings, NULL, NULL, false, false ); + + // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback so nothing changed + if( FAILED( hr ) && ( hr != E_ABORT ) ) + { + // Failed creating device, try to switch back. + HRESULT hr2 = DXUTChangeDevice( &orginalDeviceSettings, NULL, NULL, false, false ); + if( FAILED( hr2 ) ) + { + // If this failed, then shutdown + DXUTShutdown(); + } + } + } + + return hr; +} + +//-------------------------------------------------------------------------------------- +// Checks to see if DXGI has switched us out of fullscreen or windowed mode +//-------------------------------------------------------------------------------------- +void DXUTCheckForDXGIFullScreenSwitch() +{ + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + if( !DXUTIsD3D9( pDeviceSettings ) ) + { + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + DXGI_SWAP_CHAIN_DESC SCDesc; + pSwapChain->GetDesc( &SCDesc ); + + BOOL bIsWindowed = ( BOOL )DXUTIsWindowed(); + if( bIsWindowed != SCDesc.Windowed ) + { + pDeviceSettings->d3d11.sd.Windowed = SCDesc.Windowed; + + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + + if( bIsWindowed ) + { + GetDXUTState().SetWindowBackBufferWidthAtModeChange( deviceSettings.d3d11.sd.BufferDesc.Width ); + GetDXUTState().SetWindowBackBufferHeightAtModeChange( deviceSettings.d3d11.sd.BufferDesc.Height ); + } + else + { + GetDXUTState().SetFullScreenBackBufferWidthAtModeChange( deviceSettings.d3d11.sd.BufferDesc.Width ); + GetDXUTState().SetFullScreenBackBufferHeightAtModeChange( deviceSettings.d3d11.sd.BufferDesc.Height ); + } + } + } +} + +void DXUTResizeDXGIBuffers( UINT Width, UINT Height, BOOL bFullScreen ) +{ + HRESULT hr = S_OK; + RECT rcCurrentClient; + GetClientRect( DXUTGetHWND(), &rcCurrentClient ); + + DXUTDeviceSettings* pDevSettings = GetDXUTState().GetCurrentDeviceSettings(); + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + + ID3D11Device* pd3dDevice = DXUTGetD3D11Device(); + ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); + + // Determine if we're fullscreen + pDevSettings->d3d11.sd.Windowed = !bFullScreen; + + // Call releasing + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D11SWAPCHAINRELEASING pCallbackSwapChainReleasing = GetDXUTState().GetD3D11SwapChainReleasingFunc + (); + if( pCallbackSwapChainReleasing != NULL ) + pCallbackSwapChainReleasing( GetDXUTState().GetD3D11SwapChainResizedFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + + // Release our old depth stencil texture and view + ID3D11Texture2D* pDS = GetDXUTState().GetD3D11DepthStencil(); + SAFE_RELEASE( pDS ); + GetDXUTState().SetD3D11DepthStencil( NULL ); + ID3D11DepthStencilView* pDSV = GetDXUTState().GetD3D11DepthStencilView(); + SAFE_RELEASE( pDSV ); + GetDXUTState().SetD3D11DepthStencilView( NULL ); + + // Release our old render target view + ID3D11RenderTargetView* pRTV = GetDXUTState().GetD3D11RenderTargetView(); + SAFE_RELEASE( pRTV ); + GetDXUTState().SetD3D11RenderTargetView( NULL ); + + // Alternate between 0 and DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH when resizing buffers. + // When in windowed mode, we want 0 since this allows the app to change to the desktop + // resolution from windowed mode during alt+enter. However, in fullscreen mode, we want + // the ability to change display modes from the Device Settings dialog. Therefore, we + // want to set the DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH flag. + UINT Flags = 0; + if( bFullScreen ) + Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + // ResizeBuffers + V( pSwapChain->ResizeBuffers( pDevSettings->d3d11.sd.BufferCount, + Width, + Height, + pDevSettings->d3d11.sd.BufferDesc.Format, + Flags ) ); + + if( !GetDXUTState().GetDoNotStoreBufferSize() ) + { + pDevSettings->d3d11.sd.BufferDesc.Width = ( UINT )rcCurrentClient.right; + pDevSettings->d3d11.sd.BufferDesc.Height = ( UINT )rcCurrentClient.bottom; + } + + // Save off backbuffer desc + DXUTUpdateBackBufferDesc(); + + // Update the device stats text + DXUTUpdateStaticFrameStats(); + + // Setup the render target view and viewport + hr = DXUTCreateD3D11Views( pd3dDevice, pd3dImmediateContext, pDevSettings ); + if( FAILED( hr ) ) + { + DXUT_ERR( L"DXUTCreateD3D11Views", hr ); + return; + } + + // Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state) + DXUTSetupCursor(); + + // Call the app's SwapChain reset callback + GetDXUTState().SetInsideDeviceCallback( true ); + const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc = DXUTGetDXGIBackBufferSurfaceDesc(); + LPDXUTCALLBACKD3D11SWAPCHAINRESIZED pCallbackSwapChainResized = GetDXUTState().GetD3D11SwapChainResizedFunc(); + hr = S_OK; + if( pCallbackSwapChainResized != NULL ) + hr = pCallbackSwapChainResized( pd3dDevice, pSwapChain, pBackBufferSurfaceDesc, + GetDXUTState().GetD3D11SwapChainResizedFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + if( FAILED( hr ) ) + { + // If callback failed, cleanup + DXUT_ERR( L"DeviceResetCallback", hr ); + if( hr != DXUTERR_MEDIANOTFOUND ) + hr = DXUTERR_RESETTINGDEVICEOBJECTS; + + GetDXUTState().SetInsideDeviceCallback( true ); + LPDXUTCALLBACKD3D11SWAPCHAINRELEASING pCallbackSwapChainReleasing = + GetDXUTState().GetD3D11SwapChainReleasingFunc(); + if( pCallbackSwapChainReleasing != NULL ) + pCallbackSwapChainReleasing( GetDXUTState().GetD3D11SwapChainResizedFuncUserContext() ); + GetDXUTState().SetInsideDeviceCallback( false ); + DXUTPause( false, false ); + PostQuitMessage( 0 ); + } + else + { + GetDXUTState().SetDeviceObjectsReset( true ); + DXUTPause( false, false ); + } +} + +//-------------------------------------------------------------------------------------- +// Checks if DXGI buffers need to change +//-------------------------------------------------------------------------------------- +void DXUTCheckForDXGIBufferChange() +{ + if(DXUTGetDXGISwapChain() != NULL && !GetDXUTState().GetReleasingSwapChain() ) + { + //DXUTgetdxgi + IDXGISwapChain* pSwapChain = DXUTGetDXGISwapChain(); + + // Determine if we're fullscreen + BOOL bFullScreen; + pSwapChain->GetFullscreenState( &bFullScreen, NULL ); + + DXUTResizeDXGIBuffers( 0, 0, bFullScreen ); + + ShowWindow( DXUTGetHWND(), SW_SHOW ); + } +} + +//-------------------------------------------------------------------------------------- +// Checks if the window client rect has changed and if it has, then reset the device +//-------------------------------------------------------------------------------------- +void DXUTCheckForWindowSizeChange() +{ + // Skip the check for various reasons + + if( GetDXUTState().GetIgnoreSizeChange() || !GetDXUTState().GetDeviceCreated() || + ( DXUTIsCurrentDeviceD3D9() && !DXUTIsWindowed() ) ) + return; + + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + if( DXUTIsD3D9( &deviceSettings ) ) + { + RECT rcCurrentClient; + GetClientRect( DXUTGetHWND(), &rcCurrentClient ); + + if( ( UINT )rcCurrentClient.right != DXUTGetBackBufferWidthFromDS( &deviceSettings ) || + ( UINT )rcCurrentClient.bottom != DXUTGetBackBufferHeightFromDS( &deviceSettings ) ) + { + // A new window size will require a new backbuffer size size + // Tell DXUTChangeDevice and D3D to size according to the HWND's client rect + if( DXUTIsD3D9( &deviceSettings ) ) deviceSettings.d3d9.pp.BackBufferWidth = 0; else deviceSettings.d3d11.sd.BufferDesc.Width = 0; + if( DXUTIsD3D9( &deviceSettings ) ) deviceSettings.d3d9.pp.BackBufferHeight = 0; else deviceSettings.d3d11.sd.BufferDesc.Height = 0; + + DXUTChangeDevice( &deviceSettings, NULL, NULL, false, false ); + } + } + else + { + DXUTCheckForDXGIBufferChange(); + } +} + + +//-------------------------------------------------------------------------------------- +// Checks to see if the HWND changed monitors, and if it did it creates a device +// from the monitor's adapter and recreates the scene. +//-------------------------------------------------------------------------------------- +void DXUTCheckForWindowChangingMonitors() +{ + // Skip this check for various reasons + if( !GetDXUTState().GetAutoChangeAdapter() || + GetDXUTState().GetIgnoreSizeChange() || !GetDXUTState().GetDeviceCreated() || !DXUTIsWindowed() ) + return; + + HRESULT hr; + HMONITOR hWindowMonitor = DXUTMonitorFromWindow( DXUTGetHWND(), MONITOR_DEFAULTTOPRIMARY ); + HMONITOR hAdapterMonitor = GetDXUTState().GetAdapterMonitor(); + if( hWindowMonitor != hAdapterMonitor ) + { + UINT newOrdinal; + if( SUCCEEDED( DXUTGetAdapterOrdinalFromMonitor( hWindowMonitor, &newOrdinal ) ) ) + { + // Find the closest valid device settings with the new ordinal + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + if( DXUTIsD3D9( &deviceSettings ) ) + { + deviceSettings.d3d9.AdapterOrdinal = newOrdinal; + } + else + { + deviceSettings.d3d11.AdapterOrdinal = newOrdinal; + UINT newOutput; + if( SUCCEEDED( DXUTGetOutputOrdinalFromMonitor( hWindowMonitor, &newOutput ) ) ) + deviceSettings.d3d11.Output = newOutput; + } + + hr = DXUTSnapDeviceSettingsToEnumDevice( &deviceSettings, false ); + if( SUCCEEDED( hr ) ) + { + // Create a Direct3D device using the new device settings. + // If there is an existing device, then it will either reset or recreate the scene. + hr = DXUTChangeDevice( &deviceSettings, NULL, NULL, false, false ); + + // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback + if( hr == E_ABORT ) + { + // so nothing changed and keep from attempting to switch adapters next time + GetDXUTState().SetAutoChangeAdapter( false ); + } + else if( FAILED( hr ) ) + { + DXUTShutdown(); + DXUTPause( false, false ); + return; + } + } + } + } +} + + +//-------------------------------------------------------------------------------------- +// Renders the scene using either D3D9 or D3D11 +//-------------------------------------------------------------------------------------- +void WINAPI DXUTRender3DEnvironment() +{ + if( DXUTIsCurrentDeviceD3D9() ) + DXUTRender3DEnvironment9(); + else + DXUTRender3DEnvironment11(); +} + + +//-------------------------------------------------------------------------------------- +// Cleans up both the D3D9 and D3D11 3D environment (but only one should be active at a time) +//-------------------------------------------------------------------------------------- +void DXUTCleanup3DEnvironment( bool bReleaseSettings ) +{ + if( DXUTGetD3D9Device() ) + DXUTCleanup3DEnvironment9( bReleaseSettings ); + if( DXUTGetD3D11Device() ) + DXUTCleanup3DEnvironment11( bReleaseSettings ); +} + + +//-------------------------------------------------------------------------------------- +// Returns the HMONITOR attached to an adapter/output +//-------------------------------------------------------------------------------------- +HMONITOR DXUTGetMonitorFromAdapter( DXUTDeviceSettings* pDeviceSettings ) +{ + if( pDeviceSettings->ver == DXUT_D3D9_DEVICE ) + { + IDirect3D9* pD3D = DXUTGetD3D9Object(); + return pD3D->GetAdapterMonitor( pDeviceSettings->d3d9.AdapterOrdinal ); + } + else if( pDeviceSettings->ver == DXUT_D3D11_DEVICE ) + { + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + CD3D11EnumOutputInfo* pOutputInfo = pD3DEnum->GetOutputInfo( pDeviceSettings->d3d11.AdapterOrdinal, + pDeviceSettings->d3d11.Output ); + if( !pOutputInfo ) + return 0; + return DXUTMonitorFromRect( &pOutputInfo->Desc.DesktopCoordinates, MONITOR_DEFAULTTONEAREST ); + } + + return 0; +} + + +//-------------------------------------------------------------------------------------- +// Look for an adapter ordinal that is tied to a HMONITOR +//-------------------------------------------------------------------------------------- +HRESULT DXUTGetAdapterOrdinalFromMonitor( HMONITOR hMonitor, UINT* pAdapterOrdinal ) +{ + *pAdapterOrdinal = 0; + + if( DXUTIsCurrentDeviceD3D9() ) + { + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration(); + IDirect3D9* pD3D = DXUTGetD3D9Object(); + + CGrowableArray * pAdapterList = pd3dEnum->GetAdapterInfoList(); + for( int iAdapter = 0; iAdapter < pAdapterList->GetSize(); iAdapter++ ) + { + CD3D9EnumAdapterInfo* pAdapterInfo = pAdapterList->GetAt( iAdapter ); + HMONITOR hAdapterMonitor = pD3D->GetAdapterMonitor( pAdapterInfo->AdapterOrdinal ); + if( hAdapterMonitor == hMonitor ) + { + *pAdapterOrdinal = pAdapterInfo->AdapterOrdinal; + return S_OK; + } + } + } + else + { + // Get the monitor handle information + MONITORINFOEX mi; + mi.cbSize = sizeof( MONITORINFOEX ); + DXUTGetMonitorInfo( hMonitor, &mi ); + + // Search for this monitor in our enumeration hierarchy. + CD3D11Enumeration* pd3dEnum = DXUTGetD3D11Enumeration(); + CGrowableArray * pAdapterList = pd3dEnum->GetAdapterInfoList(); + for( int iAdapter = 0; iAdapter < pAdapterList->GetSize(); ++iAdapter ) + { + CD3D11EnumAdapterInfo* pAdapterInfo = pAdapterList->GetAt( iAdapter ); + for( int o = 0; o < pAdapterInfo->outputInfoList.GetSize(); ++o ) + { + CD3D11EnumOutputInfo* pOutputInfo = pAdapterInfo->outputInfoList.GetAt( o ); + // Convert output device name from MBCS to Unicode + if( wcsncmp( pOutputInfo->Desc.DeviceName, mi.szDevice, sizeof( mi.szDevice ) / sizeof + ( mi.szDevice[0] ) ) == 0 ) + { + *pAdapterOrdinal = pAdapterInfo->AdapterOrdinal; + return S_OK; + } + } + } + } + + return E_FAIL; +} + +//-------------------------------------------------------------------------------------- +// Look for a monitor ordinal that is tied to a HMONITOR (D3D11-only) +//-------------------------------------------------------------------------------------- +HRESULT DXUTGetOutputOrdinalFromMonitor( HMONITOR hMonitor, UINT* pOutputOrdinal ) +{ + // Get the monitor handle information + MONITORINFOEX mi; + mi.cbSize = sizeof( MONITORINFOEX ); + DXUTGetMonitorInfo( hMonitor, &mi ); + + // Search for this monitor in our enumeration hierarchy. + CD3D11Enumeration* pd3dEnum = DXUTGetD3D11Enumeration(); + CGrowableArray * pAdapterList = pd3dEnum->GetAdapterInfoList(); + for( int iAdapter = 0; iAdapter < pAdapterList->GetSize(); ++iAdapter ) + { + CD3D11EnumAdapterInfo* pAdapterInfo = pAdapterList->GetAt( iAdapter ); + for( int o = 0; o < pAdapterInfo->outputInfoList.GetSize(); ++o ) + { + CD3D11EnumOutputInfo* pOutputInfo = pAdapterInfo->outputInfoList.GetAt( o ); + DXGI_OUTPUT_DESC Desc; + pOutputInfo->m_pOutput->GetDesc( &Desc ); + + if( hMonitor == Desc.Monitor ) + { + *pOutputOrdinal = pOutputInfo->Output; + return S_OK; + } + } + } + + return E_FAIL; +} + +//-------------------------------------------------------------------------------------- +// This method is called when D3DERR_DEVICEREMOVED is returned from an API. DXUT +// calls the application's DeviceRemoved callback to inform it of the event. The +// application returns true if it wants DXUT to look for a closest device to run on. +// If no device is found, or the app returns false, DXUT shuts down. +//-------------------------------------------------------------------------------------- +HRESULT DXUTHandleDeviceRemoved() +{ + HRESULT hr = S_OK; + + // Device has been removed. Call the application's callback if set. If no callback + // has been set, then just look for a new device + bool bLookForNewDevice = true; + LPDXUTCALLBACKDEVICEREMOVED pDeviceRemovedFunc = GetDXUTState().GetDeviceRemovedFunc(); + if( pDeviceRemovedFunc ) + bLookForNewDevice = pDeviceRemovedFunc( GetDXUTState().GetDeviceRemovedFuncUserContext() ); + + if( bLookForNewDevice ) + { + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + + + hr = DXUTSnapDeviceSettingsToEnumDevice( pDeviceSettings, false); + if( SUCCEEDED( hr ) ) + { + // Change to a Direct3D device created from the new device settings + // that is compatible with the removed device. + hr = DXUTChangeDevice( pDeviceSettings, NULL, NULL, true, false ); + if( SUCCEEDED( hr ) ) + return S_OK; + } + } + + // The app does not wish to continue or continuing is not possible. + return DXUTERR_DEVICEREMOVED; +} + + +//-------------------------------------------------------------------------------------- +// Stores back buffer surface desc in GetDXUTState().GetBackBufferSurfaceDesc10() +//-------------------------------------------------------------------------------------- +void DXUTUpdateBackBufferDesc() +{ + if( DXUTIsCurrentDeviceD3D9() ) + { + HRESULT hr; + IDirect3DSurface9* pBackBuffer; + hr = GetDXUTState().GetD3D9Device()->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); + D3DSURFACE_DESC* pBBufferSurfaceDesc = GetDXUTState().GetBackBufferSurfaceDesc9(); + ZeroMemory( pBBufferSurfaceDesc, sizeof( D3DSURFACE_DESC ) ); + if( SUCCEEDED( hr ) ) + { + pBackBuffer->GetDesc( pBBufferSurfaceDesc ); + SAFE_RELEASE( pBackBuffer ); + } + } + else + { + HRESULT hr; + ID3D11Texture2D* pBackBuffer; + hr = GetDXUTState().GetDXGISwapChain()->GetBuffer( 0, __uuidof( *pBackBuffer ), ( LPVOID* )&pBackBuffer ); + DXGI_SURFACE_DESC* pBBufferSurfaceDesc = GetDXUTState().GetBackBufferSurfaceDescDXGI(); + ZeroMemory( pBBufferSurfaceDesc, sizeof( DXGI_SURFACE_DESC ) ); + if( SUCCEEDED( hr ) ) + { + D3D11_TEXTURE2D_DESC TexDesc; + pBackBuffer->GetDesc( &TexDesc ); + pBBufferSurfaceDesc->Width = ( UINT )TexDesc.Width; + pBBufferSurfaceDesc->Height = ( UINT )TexDesc.Height; + pBBufferSurfaceDesc->Format = TexDesc.Format; + pBBufferSurfaceDesc->SampleDesc = TexDesc.SampleDesc; + SAFE_RELEASE( pBackBuffer ); + } + } +} + + +//-------------------------------------------------------------------------------------- +// Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state) +//-------------------------------------------------------------------------------------- +void DXUTSetupCursor() +{ + if( DXUTIsCurrentDeviceD3D9() ) + { + // Show the cursor again if returning to fullscreen + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + if( !DXUTIsWindowed() && pd3dDevice ) + { + if( GetDXUTState().GetShowCursorWhenFullScreen() ) + { + SetCursor( NULL ); // Turn off Windows cursor in full screen mode + HCURSOR hCursor = ( HCURSOR )( ULONG_PTR )GetClassLongPtr( DXUTGetHWNDDeviceFullScreen(), + GCLP_HCURSOR ); + DXUTSetD3D9DeviceCursor( pd3dDevice, hCursor, false ); + DXUTGetD3D9Device()->ShowCursor( true ); + } + else + { + SetCursor( NULL ); // Turn off Windows cursor in full screen mode + DXUTGetD3D9Device()->ShowCursor( false ); + } + } + + // Clip cursor if requested + if( !DXUTIsWindowed() && GetDXUTState().GetClipCursorWhenFullScreen() ) + { + // Confine cursor to full screen window + RECT rcWindow; + GetWindowRect( DXUTGetHWNDDeviceFullScreen(), &rcWindow ); + ClipCursor( &rcWindow ); + } + else + { + ClipCursor( NULL ); + } + } + else + { + // Clip cursor if requested + if( !DXUTIsWindowed() && GetDXUTState().GetClipCursorWhenFullScreen() ) + { + // Confine cursor to full screen window + RECT rcWindow; + GetWindowRect( DXUTGetHWNDDeviceFullScreen(), &rcWindow ); + ClipCursor( &rcWindow ); + } + else + { + ClipCursor( NULL ); + } + } +} + + +//-------------------------------------------------------------------------------------- +// Updates the static part of the frame stats so it doesn't have be generated every frame +//-------------------------------------------------------------------------------------- +void DXUTUpdateStaticFrameStats() +{ + if( GetDXUTState().GetNoStats() ) + return; + + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + if( NULL == pDeviceSettings ) + return; + + if( DXUTIsD3D9( pDeviceSettings ) ) + { + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration(); + if( NULL == pd3dEnum ) + return; + + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = pd3dEnum->GetDeviceSettingsCombo( + pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, + pDeviceSettings->d3d9.AdapterFormat, pDeviceSettings->d3d9.pp.BackBufferFormat, + pDeviceSettings->d3d9.pp.Windowed ); + if( NULL == pDeviceSettingsCombo ) + return; + + WCHAR strFmt[100]; + D3DPRESENT_PARAMETERS* pPP = &pDeviceSettings->d3d9.pp; + + if( pDeviceSettingsCombo->AdapterFormat == pDeviceSettingsCombo->BackBufferFormat ) + { + wcscpy_s( strFmt, 100, DXUTD3DFormatToString( pDeviceSettingsCombo->AdapterFormat, false ) ); + } + else + { + swprintf_s( strFmt, 100, L"backbuf %s, adapter %s", + DXUTD3DFormatToString( pDeviceSettingsCombo->BackBufferFormat, false ), + DXUTD3DFormatToString( pDeviceSettingsCombo->AdapterFormat, false ) ); + } + + WCHAR strDepthFmt[100]; + if( pPP->EnableAutoDepthStencil ) + { + swprintf_s( strDepthFmt, 100, L" (%s)", DXUTD3DFormatToString( pPP->AutoDepthStencilFormat, false ) ); + } + else + { + // No depth buffer + strDepthFmt[0] = 0; + } + + WCHAR strMultiSample[100]; + switch( pPP->MultiSampleType ) + { + case D3DMULTISAMPLE_NONMASKABLE: + wcscpy_s( strMultiSample, 100, L" (Nonmaskable Multisample)" ); break; + case D3DMULTISAMPLE_NONE: + wcscpy_s( strMultiSample, 100, L"" ); break; + default: + swprintf_s( strMultiSample, 100, L" (%dx Multisample)", pPP->MultiSampleType ); break; + } + + WCHAR* pstrStaticFrameStats = GetDXUTState().GetStaticFrameStats(); + swprintf_s( pstrStaticFrameStats, 256, L"D3D9 %%sVsync %s (%dx%d), %s%s%s", + ( pPP->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE ) ? L"off" : L"on", + pPP->BackBufferWidth, pPP->BackBufferHeight, + strFmt, strDepthFmt, strMultiSample ); + } + else + { + // D3D11 + CD3D11Enumeration* pd3dEnum = DXUTGetD3D11Enumeration(); + if( NULL == pd3dEnum ) + return; + + CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo = pd3dEnum->GetDeviceSettingsCombo( + pDeviceSettings->d3d11.AdapterOrdinal, pDeviceSettings->d3d11.DriverType, pDeviceSettings->d3d11.Output, + pDeviceSettings->d3d11.sd.BufferDesc.Format, pDeviceSettings->d3d11.sd.Windowed ); + if( NULL == pDeviceSettingsCombo ) + return; + + WCHAR strFmt[100]; + + wcscpy_s( strFmt, 100, DXUTDXGIFormatToString( pDeviceSettingsCombo->BackBufferFormat, false ) ); + + WCHAR strMultiSample[100]; + swprintf_s( strMultiSample, 100, L" (MS%u, Q%u)", pDeviceSettings->d3d11.sd.SampleDesc.Count, + pDeviceSettings->d3d11.sd.SampleDesc.Quality ); + + WCHAR* pstrStaticFrameStats = GetDXUTState().GetStaticFrameStats(); + swprintf_s( pstrStaticFrameStats, 256, L"D3D11 %%sVsync %s (%dx%d), %s%s", + ( pDeviceSettings->d3d11.SyncInterval == 0 ) ? L"off" : L"on", + pDeviceSettings->d3d11.sd.BufferDesc.Width, pDeviceSettings->d3d11.sd.BufferDesc.Height, + strFmt, strMultiSample ); + } +} + + +//-------------------------------------------------------------------------------------- +// Updates the frames/sec stat once per second +//-------------------------------------------------------------------------------------- +void DXUTUpdateFrameStats() +{ + if( GetDXUTState().GetNoStats() ) + return; + + // Keep track of the frame count + double fLastTime = GetDXUTState().GetLastStatsUpdateTime(); + DWORD dwFrames = GetDXUTState().GetLastStatsUpdateFrames(); + double fAbsTime = GetDXUTState().GetAbsoluteTime(); + dwFrames++; + GetDXUTState().SetLastStatsUpdateFrames( dwFrames ); + + // Update the scene stats once per second + if( fAbsTime - fLastTime > 1.0f ) + { + float fFPS = ( float )( dwFrames / ( fAbsTime - fLastTime ) ); + GetDXUTState().SetFPS( fFPS ); + GetDXUTState().SetLastStatsUpdateTime( fAbsTime ); + GetDXUTState().SetLastStatsUpdateFrames( 0 ); + + WCHAR* pstrFPS = GetDXUTState().GetFPSStats(); + swprintf_s( pstrFPS, 64, L"%0.2f fps ", fFPS ); + } +} + +//-------------------------------------------------------------------------------------- +// Returns a string describing the current device. If bShowFPS is true, then +// the string contains the frames/sec. If "-nostats" was used in +// the command line, the string will be blank +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTGetFrameStats( bool bShowFPS ) +{ + WCHAR* pstrFrameStats = GetDXUTState().GetFrameStats(); + WCHAR* pstrFPS = ( bShowFPS ) ? GetDXUTState().GetFPSStats() : L""; + swprintf_s( pstrFrameStats, 256, GetDXUTState().GetStaticFrameStats(), pstrFPS ); + return pstrFrameStats; +} + + +//-------------------------------------------------------------------------------------- +// Updates the string which describes the device +//-------------------------------------------------------------------------------------- +void DXUTUpdateD3D9DeviceStats( D3DDEVTYPE DeviceType, DWORD BehaviorFlags, + D3DADAPTER_IDENTIFIER9* pAdapterIdentifier ) +{ + if( GetDXUTState().GetNoStats() ) + return; + + // Store device description + WCHAR* pstrDeviceStats = GetDXUTState().GetDeviceStats(); + if( DeviceType == D3DDEVTYPE_REF ) + wcscpy_s( pstrDeviceStats, 256, L"REF" ); + else if( DeviceType == D3DDEVTYPE_HAL ) + wcscpy_s( pstrDeviceStats, 256, L"HAL" ); + else if( DeviceType == D3DDEVTYPE_SW ) + wcscpy_s( pstrDeviceStats, 256, L"SW" ); + + if( DeviceType == D3DDEVTYPE_HAL ) + { + // Be sure not to overflow m_strDeviceStats when appending the adapter + // description, since it can be long. + wcscat_s( pstrDeviceStats, 256, L": " ); + + // Try to get a unique description from the CD3D9EnumDeviceSettingsCombo + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + if( !pDeviceSettings ) + return; + + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration(); + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = pd3dEnum->GetDeviceSettingsCombo( + pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, + pDeviceSettings->d3d9.AdapterFormat, pDeviceSettings->d3d9.pp.BackBufferFormat, + pDeviceSettings->d3d9.pp.Windowed ); + if( pDeviceSettingsCombo ) + { + wcscat_s( pstrDeviceStats, 256, pDeviceSettingsCombo->pAdapterInfo->szUniqueDescription ); + } + else + { + const int cchDesc = sizeof( pAdapterIdentifier->Description ); + WCHAR szDescription[cchDesc]; + MultiByteToWideChar( CP_ACP, 0, pAdapterIdentifier->Description, -1, szDescription, cchDesc ); + szDescription[cchDesc - 1] = 0; + wcscat_s( pstrDeviceStats, 256, szDescription ); + } + } +} + + +//-------------------------------------------------------------------------------------- +// Updates the string which describes the device +//-------------------------------------------------------------------------------------- +void DXUTUpdateD3D11DeviceStats( D3D_DRIVER_TYPE DeviceType, DXGI_ADAPTER_DESC* pAdapterDesc ) +{ + if( GetDXUTState().GetNoStats() ) + return; + + // Store device description + WCHAR* pstrDeviceStats = GetDXUTState().GetDeviceStats(); + if( DeviceType == D3D_DRIVER_TYPE_REFERENCE ) + wcscpy_s( pstrDeviceStats, 256, L"REFERENCE" ); + else if( DeviceType == D3D_DRIVER_TYPE_HARDWARE ) + wcscpy_s( pstrDeviceStats, 256, L"HARDWARE" ); + else if( DeviceType == D3D_DRIVER_TYPE_SOFTWARE ) + wcscpy_s( pstrDeviceStats, 256, L"SOFTWARE" ); + else if( DeviceType == D3D_DRIVER_TYPE_WARP ) + wcscpy_s( pstrDeviceStats, 256, L"WARP" ); + + if( DeviceType == D3D_DRIVER_TYPE_HARDWARE ) + { + // Be sure not to overflow m_strDeviceStats when appending the adapter + // description, since it can be long. + wcscat_s( pstrDeviceStats, 256, L": " ); + + // Try to get a unique description from the CD3D11EnumDeviceSettingsCombo + DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings(); + if( !pDeviceSettings ) + return; + + CD3D11Enumeration* pd3dEnum = DXUTGetD3D11Enumeration(); + CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo = pd3dEnum->GetDeviceSettingsCombo( + pDeviceSettings->d3d11.AdapterOrdinal, pDeviceSettings->d3d11.DriverType, pDeviceSettings->d3d11.Output, + pDeviceSettings->d3d11.sd.BufferDesc.Format, pDeviceSettings->d3d11.sd.Windowed ); + if( pDeviceSettingsCombo ) + wcscat_s( pstrDeviceStats, 256, pDeviceSettingsCombo->pAdapterInfo->szUniqueDescription ); + else + wcscat_s( pstrDeviceStats, 256, pAdapterDesc->Description ); + } +} + + +//-------------------------------------------------------------------------------------- +// Misc functions +//-------------------------------------------------------------------------------------- +DXUTDeviceSettings WINAPI DXUTGetDeviceSettings() +{ + // Return a copy of device settings of the current device. If no device exists yet, then + // return a blank device settings struct + DXUTDeviceSettings* pDS = GetDXUTState().GetCurrentDeviceSettings(); + if( pDS ) + { + return *pDS; + } + else + { + DXUTDeviceSettings ds; + ZeroMemory( &ds, sizeof( DXUTDeviceSettings ) ); + return ds; + } +} + +D3DPRESENT_PARAMETERS WINAPI DXUTGetD3D9PresentParameters() +{ + // Return a copy of the present params of the current device. If no device exists yet, then + // return blank present params + DXUTDeviceSettings* pDS = GetDXUTState().GetCurrentDeviceSettings(); + if( pDS ) + { + return pDS->d3d9.pp; + } + else + { + D3DPRESENT_PARAMETERS pp; + ZeroMemory( &pp, sizeof( D3DPRESENT_PARAMETERS ) ); + return pp; + } +} + +bool WINAPI DXUTIsVsyncEnabled() +{ + DXUTDeviceSettings* pDS = GetDXUTState().GetCurrentDeviceSettings(); + if( pDS ) + { + if( DXUTIsD3D9( pDS ) ) + return ( pDS->d3d9.pp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE ); + else + return ( pDS->d3d11.SyncInterval == 0 ); + } + else + { + return true; + } +}; + +HRESULT WINAPI DXUTGetD3D9DeviceCaps( DXUTDeviceSettings* pDeviceSettings, D3DCAPS9* pCaps ) +{ + IDirect3D9* pD3D = DXUTGetD3D9Object(); + return pD3D->GetDeviceCaps( pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, pCaps ); +} + + +bool WINAPI DXUTIsKeyDown( BYTE vKey ) +{ + bool* bKeys = GetDXUTState().GetKeys(); + if( vKey >= 0xA0 && vKey <= 0xA5 ) // VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU, VK_RMENU + return GetAsyncKeyState( vKey ) != 0; // these keys only are tracked via GetAsyncKeyState() + else if( vKey >= 0x01 && vKey <= 0x06 && vKey != 0x03 ) // mouse buttons (VK_*BUTTON) + return DXUTIsMouseButtonDown( vKey ); + else + return bKeys[vKey]; +} + +bool WINAPI DXUTWasKeyPressed( BYTE vKey ) +{ + bool* bLastKeys = GetDXUTState().GetLastKeys(); + bool* bKeys = GetDXUTState().GetKeys(); + GetDXUTState().SetAppCalledWasKeyPressed( true ); + return ( !bLastKeys[vKey] && bKeys[vKey] ); +} + +bool WINAPI DXUTIsMouseButtonDown( BYTE vButton ) +{ + bool* bMouseButtons = GetDXUTState().GetMouseButtons(); + int nIndex = DXUTMapButtonToArrayIndex( vButton ); + return bMouseButtons[nIndex]; +} + +void WINAPI DXUTSetMultimonSettings( bool bAutoChangeAdapter ) +{ + GetDXUTState().SetAutoChangeAdapter( bAutoChangeAdapter ); +} + +void WINAPI DXUTSetHotkeyHandling( bool bAltEnterToToggleFullscreen, bool bEscapeToQuit, bool bPauseToToggleTimePause ) +{ + GetDXUTState().SetHandleEscape( bEscapeToQuit ); + GetDXUTState().SetHandleAltEnter( bAltEnterToToggleFullscreen ); + GetDXUTState().SetHandlePause( bPauseToToggleTimePause ); +} + +void WINAPI DXUTSetCursorSettings( bool bShowCursorWhenFullScreen, bool bClipCursorWhenFullScreen ) +{ + GetDXUTState().SetClipCursorWhenFullScreen( bClipCursorWhenFullScreen ); + GetDXUTState().SetShowCursorWhenFullScreen( bShowCursorWhenFullScreen ); + DXUTSetupCursor(); +} + +void WINAPI DXUTSetWindowSettings( bool bCallDefWindowProc ) +{ + GetDXUTState().SetCallDefWindowProc( bCallDefWindowProc ); +} + +void WINAPI DXUTSetConstantFrameTime( bool bEnabled, float fTimePerFrame ) +{ + if( GetDXUTState().GetOverrideConstantFrameTime() ) + { + bEnabled = GetDXUTState().GetOverrideConstantFrameTime(); + fTimePerFrame = GetDXUTState().GetOverrideConstantTimePerFrame(); + } + GetDXUTState().SetConstantFrameTime( bEnabled ); + GetDXUTState().SetTimePerFrame( fTimePerFrame ); +} + + +//-------------------------------------------------------------------------------------- +// Resets the state associated with DXUT +//-------------------------------------------------------------------------------------- +void WINAPI DXUTResetFrameworkState() +{ + GetDXUTState().Destroy(); + GetDXUTState().Create(); +} + + +//-------------------------------------------------------------------------------------- +// Closes down the window. When the window closes, it will cleanup everything +//-------------------------------------------------------------------------------------- +void WINAPI DXUTShutdown( int nExitCode ) +{ + HWND hWnd = DXUTGetHWND(); + if( hWnd != NULL ) + SendMessage( hWnd, WM_CLOSE, 0, 0 ); + + GetDXUTState().SetExitCode( nExitCode ); + + DXUTCleanup3DEnvironment( true ); + + // Restore shortcut keys (Windows key, accessibility shortcuts) to original state + // This is important to call here if the shortcuts are disabled, + // because accessibility setting changes are permanent. + // This means that if this is not done then the accessibility settings + // might not be the same as when the app was started. + // If the app crashes without restoring the settings, this is also true so it + // would be wise to backup/restore the settings from a file so they can be + // restored when the crashed app is run again. + DXUTAllowShortcutKeys( true ); + + // Shutdown D3D9 + IDirect3D9* pD3D = GetDXUTState().GetD3D9(); + SAFE_RELEASE( pD3D ); + GetDXUTState().SetD3D9( NULL ); + + // Shutdown D3D11 + IDXGIFactory1* pDXGIFactory = GetDXUTState().GetDXGIFactory(); + SAFE_RELEASE( pDXGIFactory ); + GetDXUTState().SetDXGIFactory( NULL ); + + if( GetDXUTState().GetOverrideRelaunchMCE() ) + DXUTReLaunchMediaCenter(); +} + +//-------------------------------------------------------------------------------------- +// Tells DXUT whether to operate in gamma correct mode +//-------------------------------------------------------------------------------------- +void WINAPI DXUTSetIsInGammaCorrectMode( bool bGammaCorrect ) +{ + GetDXUTState().SetIsInGammaCorrectMode( bGammaCorrect ); +} + + +void DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings) { + ZeroMemory( modifySettings, sizeof( DXUTDeviceSettings ) ); + + + modifySettings->ver = DXUT_D3D11_DEVICE; + modifySettings->d3d11.AdapterOrdinal = 0; + modifySettings->d3d11.AutoCreateDepthStencil = true; + modifySettings->d3d11.AutoDepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; +#if defined(DEBUG) || defined(_DEBUG) + modifySettings->d3d11.CreateFlags |= D3D10_CREATE_DEVICE_DEBUG; +#else + modifySettings->d3d11.CreateFlags = 0; +#endif + modifySettings->d3d11.DriverType = D3D_DRIVER_TYPE_HARDWARE; + modifySettings->d3d11.Output = 0; + modifySettings->d3d11.PresentFlags = 0; + modifySettings->d3d11.sd.BufferCount = 2; + modifySettings->d3d11.sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + modifySettings->d3d11.sd.BufferDesc.Height = 480; + modifySettings->d3d11.sd.BufferDesc.RefreshRate.Numerator = 60; + modifySettings->d3d11.sd.BufferDesc.RefreshRate.Denominator = 1; + modifySettings->d3d11.sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + modifySettings->d3d11.sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + modifySettings->d3d11.sd.BufferDesc.Width = 640; + modifySettings->d3d11.sd.BufferUsage = 32; + modifySettings->d3d11.sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ; + modifySettings->d3d11.sd.OutputWindow = DXUTGetHWND(); + modifySettings->d3d11.sd.SampleDesc.Count = 1; + modifySettings->d3d11.sd.SampleDesc.Quality = 0; + modifySettings->d3d11.sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + modifySettings->d3d11.sd.Windowed = 1; + modifySettings->d3d11.SyncInterval = 0; + + modifySettings->d3d9.AdapterFormat = D3DFMT_X8R8G8B8; + modifySettings->d3d9.AdapterOrdinal = 0; + modifySettings->d3d9.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; + modifySettings->d3d9.DeviceType = D3DDEVTYPE_HAL; + modifySettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24X8; + modifySettings->d3d9.pp.BackBufferCount = 1; + modifySettings->d3d9.pp.BackBufferFormat = D3DFMT_X8R8G8B8; + modifySettings->d3d9.pp.BackBufferHeight = 480; + modifySettings->d3d9.pp.BackBufferWidth = 640; + modifySettings->d3d9.pp.EnableAutoDepthStencil = 1; + modifySettings->d3d9.pp.Flags = 2; + modifySettings->d3d9.pp.FullScreen_RefreshRateInHz = 0; + modifySettings->d3d9.pp.hDeviceWindow = DXUTGetHWND(); + modifySettings->d3d9.pp.MultiSampleQuality = 0; + modifySettings->d3d9.pp.MultiSampleType = D3DMULTISAMPLE_NONE; + modifySettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + modifySettings->d3d9.pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + modifySettings->d3d9.pp.Windowed = 1; +} + + + +//-------------------------------------------------------------------------------------- +// Update settings based on what is enumeratabled +//-------------------------------------------------------------------------------------- +HRESULT DXUTSnapDeviceSettingsToEnumDevice( DXUTDeviceSettings* pDeviceSettings, bool forceEnum, D3D_FEATURE_LEVEL forceFL ) { + bool bAppSupportsD3D9 = DXUTDoesAppSupportD3D9(); + bool bAppSupportsD3D11 = DXUTDoesAppSupportD3D11(); + + if( GetSystemMetrics(0x1000) != 0 ) {// SM_REMOTESESSION + pDeviceSettings->d3d11.sd.Windowed = 1; + pDeviceSettings->d3d9.pp.Windowed = 1; + } + int bestModeIndex=0; + int bestMSAAIndex=0; + + + //DXUTSetDefaultDeviceSettings + if (bAppSupportsD3D11 && pDeviceSettings->ver == DXUT_D3D11_DEVICE ) { + CD3D11Enumeration *pEnum = NULL; + + + pEnum = DXUTGetD3D11Enumeration( forceEnum, false, forceFL); + + CD3D11EnumAdapterInfo* pAdapterInfo = NULL; + CGrowableArray * pAdapterList = pEnum->GetAdapterInfoList(); + CD3D11EnumAdapterInfo* tempAdapterInfo = pAdapterList->GetAt( 0 ); + for( int iAdapter = 0; iAdapter < pAdapterList->GetSize(); iAdapter++ ) + { + tempAdapterInfo = pAdapterList->GetAt( iAdapter ); + if (tempAdapterInfo->AdapterOrdinal == pDeviceSettings->d3d11.AdapterOrdinal) pAdapterInfo = tempAdapterInfo; + } + if (pAdapterInfo == NULL) return E_FAIL; // no adapters found. + CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo = NULL; + float biggestScore = 0; + + int combo = 0; + for( int iDeviceCombo = 0; iDeviceCombo < pAdapterInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ ) + { + CD3D11EnumDeviceSettingsCombo* tempDeviceSettingsCombo = pAdapterInfo->deviceSettingsComboList.GetAt( iDeviceCombo ); + + DXGI_MODE_DESC adapterDisplayMode; + DXUTGetD3D11AdapterDisplayMode( pAdapterInfo->AdapterOrdinal, 0, &adapterDisplayMode ); + + int bestMode; + int bestMSAA; + float score = DXUTRankD3D11DeviceCombo(tempDeviceSettingsCombo, &(pDeviceSettings->d3d11), &adapterDisplayMode, bestMode, bestMSAA ); + if (score > biggestScore) { + combo = iDeviceCombo; + biggestScore = score; + pDeviceSettingsCombo = tempDeviceSettingsCombo; + bestModeIndex = bestMode; + bestMSAAIndex = bestMSAA; + } + + } + if (NULL == pDeviceSettingsCombo ) { + return E_FAIL; // no settigns found. + } + + pDeviceSettings->d3d11.AdapterOrdinal = pDeviceSettingsCombo->AdapterOrdinal; + pDeviceSettings->d3d11.DriverType = pDeviceSettingsCombo->DeviceType; + pDeviceSettings->d3d11.Output = pDeviceSettingsCombo->Output; + + pDeviceSettings->d3d11.sd.Windowed = pDeviceSettingsCombo->Windowed; + if( GetSystemMetrics(0x1000) != 0 ) {// SM_REMOTESESSION + pDeviceSettings->d3d11.sd.Windowed = 1; + } + if (pDeviceSettingsCombo->pOutputInfo != NULL) { + DXGI_MODE_DESC bestDisplayMode; + bestDisplayMode = pDeviceSettingsCombo->pOutputInfo->displayModeList.GetAt(bestModeIndex); + if (!pDeviceSettingsCombo->Windowed) { + + pDeviceSettings->d3d11.sd.BufferDesc.Height = bestDisplayMode.Height; + pDeviceSettings->d3d11.sd.BufferDesc.Width = bestDisplayMode.Width; + pDeviceSettings->d3d11.sd.BufferDesc.RefreshRate.Numerator = bestDisplayMode.RefreshRate.Numerator; + pDeviceSettings->d3d11.sd.BufferDesc.RefreshRate.Denominator = bestDisplayMode.RefreshRate.Denominator; + pDeviceSettings->d3d11.sd.BufferDesc.Scaling = bestDisplayMode.Scaling; + pDeviceSettings->d3d11.sd.BufferDesc.ScanlineOrdering = bestDisplayMode.ScanlineOrdering; + } + } + if (pDeviceSettings->d3d11.DeviceFeatureLevel == 0) + pDeviceSettings->d3d11.DeviceFeatureLevel = pDeviceSettingsCombo->pDeviceInfo->SelectedLevel; + + + + + pDeviceSettings->d3d11.sd.SampleDesc.Count = pDeviceSettingsCombo->multiSampleCountList.GetAt(bestMSAAIndex); + if (pDeviceSettings->d3d11.sd.SampleDesc.Quality > pDeviceSettingsCombo->multiSampleQualityList.GetAt(bestMSAAIndex) - 1) + pDeviceSettings->d3d11.sd.SampleDesc.Quality = pDeviceSettingsCombo->multiSampleQualityList.GetAt(bestMSAAIndex) - 1; + + pDeviceSettings->d3d11.sd.BufferDesc.Format = pDeviceSettingsCombo->BackBufferFormat; + + return S_OK; + } + // didn't find a D3D11 adapter. + if (bAppSupportsD3D9) { + // Find the best combination of: + // Adapter Ordinal + // Device Type + // Adapter Format + // Back Buffer Format + // Windowed + // given what's available on the system and the match options combined with the device settings input. + // This combination of settings is encapsulated by the CD3D9EnumDeviceSettingsCombo class. + float fBestRanking = -1.0f; + CD3D9EnumDeviceSettingsCombo* pBestDeviceSettingsCombo = NULL; + D3DDISPLAYMODE adapterDesktopDisplayMode; + + IDirect3D9* pD3D = DXUTGetD3D9Object(); + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration( forceEnum ); + CGrowableArray * pAdapterList = pd3dEnum->GetAdapterInfoList(); + for( int iAdapter = 0; iAdapter < pAdapterList->GetSize(); iAdapter++ ) + { + CD3D9EnumAdapterInfo* pAdapterInfo = pAdapterList->GetAt( iAdapter ); + + // Get the desktop display mode of adapter + pD3D->GetAdapterDisplayMode( pAdapterInfo->AdapterOrdinal, &adapterDesktopDisplayMode ); + + // Enum all the device types supported by this adapter to find the best device settings + for( int iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ ) + { + CD3D9EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( iDeviceInfo ); + + // Enum all the device settings combinations. A device settings combination is + // a unique set of an adapter format, back buffer format, and IsWindowed. + for( int iDeviceCombo = 0; iDeviceCombo < pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ ) + { + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt( + iDeviceCombo ); + + // If windowed mode the adapter format has to be the same as the desktop + // display mode format so skip any that don't match + if( pDeviceSettingsCombo->Windowed && + ( pDeviceSettingsCombo->AdapterFormat != adapterDesktopDisplayMode.Format ) ) + continue; + + // Skip any combo that doesn't meet the preserve match options + int bestMode; + int bestMSAA; + + // Get a ranking number that describes how closely this device combo matches the optimal combo + float fCurRanking = DXUTRankD3D9DeviceCombo( pDeviceSettingsCombo, + &(pDeviceSettings->d3d9), &adapterDesktopDisplayMode, bestMode, bestMSAA ); + + // If this combo better matches the input device settings then save it + if( fCurRanking > fBestRanking ) + { + pBestDeviceSettingsCombo = pDeviceSettingsCombo; + fBestRanking = fCurRanking; + bestModeIndex = bestMode; + bestMSAAIndex = bestMSAA; + } + } + } + } + + // If no best device combination was found then fail + if( pBestDeviceSettingsCombo == NULL ) + return DXUTERR_NOCOMPATIBLEDEVICES; + + // Using the best device settings combo found, build valid device settings taking heed of + // the match options and the input device settings + pDeviceSettings->d3d9.AdapterFormat = pBestDeviceSettingsCombo->AdapterFormat;//D3DFMT_X8R8G8B8; + pDeviceSettings->d3d9.AdapterOrdinal = pBestDeviceSettingsCombo->AdapterOrdinal ;//0; + pDeviceSettings->d3d9.DeviceType = pBestDeviceSettingsCombo->DeviceType; + pDeviceSettings->d3d9.pp.BackBufferFormat = pBestDeviceSettingsCombo->BackBufferFormat;//D3DFMT_X8R8G8B8; + if( GetSystemMetrics(0x1000) != 0 ) {// SM_REMOTESESSION + pDeviceSettings->d3d9.pp.Windowed = 1; + } + if (!pBestDeviceSettingsCombo->Windowed) { + D3DDISPLAYMODE displayMode = pBestDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( bestModeIndex ); + pDeviceSettings->d3d9.pp.BackBufferHeight = displayMode.Height; + pDeviceSettings->d3d9.pp.BackBufferWidth = displayMode.Width; + pDeviceSettings->d3d9.pp.FullScreen_RefreshRateInHz = displayMode.RefreshRate; + } + pDeviceSettings->d3d9.pp.hDeviceWindow = pBestDeviceSettingsCombo->Windowed ? DXUTGetHWNDDeviceWindowed() : DXUTGetHWNDDeviceFullScreen(); + if (pDeviceSettings->d3d9.pp.MultiSampleQuality > pBestDeviceSettingsCombo->multiSampleQualityList.GetAt(bestMSAAIndex) - 1) + pDeviceSettings->d3d9.pp.MultiSampleQuality = pBestDeviceSettingsCombo->multiSampleQualityList.GetAt( bestMSAAIndex )-1; + + pDeviceSettings->d3d9.pp.MultiSampleType = pBestDeviceSettingsCombo->multiSampleTypeList.GetAt( bestMSAAIndex );; + pDeviceSettings->d3d9.pp.Windowed = pBestDeviceSettingsCombo->Windowed; + return S_OK; + } + return E_FAIL; +} diff --git a/Demos/DX11ClothDemo/DXUT/Core/DXUT.h b/Demos/DX11ClothDemo/DXUT/Core/DXUT.h new file mode 100644 index 0000000..2d52b8d --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/DXUT.h @@ -0,0 +1,378 @@ +//-------------------------------------------------------------------------------------- +// File: DXUT.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_H +#define DXUT_H + +#ifndef UNICODE +#error "DXUT requires a Unicode build. See the nearby comments for details" +// +// If you are using Microsoft Visual C++ .NET, under the General tab of the project +// properties change the Character Set to 'Use Unicode Character Set'. +// +// Windows XP and later are native Unicode so Unicode applications will perform better. +// For Windows 98 and Windows Me support, consider using the Microsoft Layer for Unicode (MSLU). +// +// To use MSLU, link against a set of libraries similar to this +// /nod:kernel32.lib /nod:advapi32.lib /nod:user32.lib /nod:gdi32.lib /nod:shell32.lib /nod:comdlg32.lib /nod:version.lib /nod:mpr.lib /nod:rasapi32.lib /nod:winmm.lib /nod:winspool.lib /nod:vfw32.lib /nod:secur32.lib /nod:oleacc.lib /nod:oledlg.lib /nod:sensapi.lib UnicoWS.lib kernel32.lib advapi32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib version.lib mpr.lib rasapi32.lib winmm.lib winspool.lib vfw32.lib secur32.lib oleacc.lib oledlg.lib sensapi.lib dxerr.lib dxguid.lib d3dx9d.lib d3d9.lib comctl32.lib +// and put the unicows.dll (available for download from msdn.microsoft.com) in the exe's folder. +// +// For more details see the MSDN article titled: +// "MSLU: Develop Unicode Applications for Windows 9x Platforms with the Microsoft Layer for Unicode" +// at http://msdn.microsoft.com/msdnmag/issues/01/10/MSLU/default.aspx +// +#endif + +#include "dxsdkver.h" +#if ( _DXSDK_PRODUCT_MAJOR < 9 || _DXSDK_BUILD_MAJOR < 1455 ) +#error The installed DXSDK is out of date. +#endif + +#ifndef STRICT +#define STRICT +#endif + +// If app hasn't choosen, set to work with Windows 98, Windows Me, Windows 2000, Windows XP and beyond +#ifndef WINVER +#define WINVER 0x0500 +#endif +#ifndef _WIN32_WINDOWS +#define _WIN32_WINDOWS 0x0500 +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 +#endif + +// #define DXUT_AUTOLIB to automatically include the libs needed for DXUT +#ifdef DXUT_AUTOLIB +#pragma comment( lib, "dxerr.lib" ) +#pragma comment( lib, "dxguid.lib" ) +#pragma comment( lib, "d3d9.lib" ) +#if defined(DEBUG) || defined(_DEBUG) +#pragma comment( lib, "d3dx9d.lib" ) +#else +#pragma comment( lib, "d3dx9.lib" ) +#endif +#pragma comment( lib, "winmm.lib" ) +#pragma comment( lib, "comctl32.lib" ) +#endif + +#pragma warning( disable : 4100 ) // disable unreference formal parameter warnings for /W4 builds + +// Enable extra D3D debugging in debug builds if using the debug DirectX runtime. +// This makes D3D objects work well in the debugger watch window, but slows down +// performance slightly. +#if defined(DEBUG) || defined(_DEBUG) +#ifndef D3D_DEBUG_INFO +#define D3D_DEBUG_INFO +#endif +#endif + +// Standard Windows includes +#include +#include +#include +#include +#include +#include // for InitCommonControls() +#include // for ExtractIcon() +#include // for placement new +#include +#include +#include +#include + +// CRT's memory leak detection +#if defined(DEBUG) || defined(_DEBUG) +#include +#endif + +// Direct3D9 includes +#include +#include + + +// Direct3D11 includes +#include +#include +#include +#include + +// XInput includes +#include + +// HRESULT translation for Direct3D10 and other APIs +#include + + +#if defined(DEBUG) || defined(_DEBUG) +#ifndef V +#define V(x) { hr = (x); if( FAILED(hr) ) { DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, true ); } } +#endif +#ifndef V_RETURN +#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, true ); } } +#endif +#else +#ifndef V +#define V(x) { hr = (x); } +#endif +#ifndef V_RETURN +#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return hr; } } +#endif +#endif + +#ifndef SAFE_DELETE +#define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } } +#endif +#ifndef SAFE_DELETE_ARRAY +#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p)=NULL; } } +#endif +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } +#endif + + + +//-------------------------------------------------------------------------------------- +// Structs +//-------------------------------------------------------------------------------------- +struct DXUTD3D9DeviceSettings +{ + UINT AdapterOrdinal; + D3DDEVTYPE DeviceType; + D3DFORMAT AdapterFormat; + DWORD BehaviorFlags; + D3DPRESENT_PARAMETERS pp; +}; + +struct DXUTD3D11DeviceSettings +{ + UINT AdapterOrdinal; + D3D_DRIVER_TYPE DriverType; + UINT Output; + DXGI_SWAP_CHAIN_DESC sd; + UINT32 CreateFlags; + UINT32 SyncInterval; + DWORD PresentFlags; + bool AutoCreateDepthStencil; // DXUT will create the depth stencil resource and view if true + DXGI_FORMAT AutoDepthStencilFormat; + D3D_FEATURE_LEVEL DeviceFeatureLevel; +}; + +enum DXUTDeviceVersion +{ + DXUT_D3D9_DEVICE, + DXUT_D3D11_DEVICE +}; + +struct DXUTDeviceSettings +{ + DXUTDeviceVersion ver; + D3D_FEATURE_LEVEL MinimumFeatureLevel; + DXUTD3D9DeviceSettings d3d9; // only valid if ver == DXUT_D3D9_DEVICE + DXUTD3D11DeviceSettings d3d11; // only valid if ver == DXUT_D3D11_DEVICE +}; + + +//-------------------------------------------------------------------------------------- +// Error codes +//-------------------------------------------------------------------------------------- +#define DXUTERR_NODIRECT3D MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0901) +#define DXUTERR_NOCOMPATIBLEDEVICES MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0902) +#define DXUTERR_MEDIANOTFOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0903) +#define DXUTERR_NONZEROREFCOUNT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0904) +#define DXUTERR_CREATINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0905) +#define DXUTERR_RESETTINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0906) +#define DXUTERR_CREATINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0907) +#define DXUTERR_RESETTINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0908) +#define DXUTERR_DEVICEREMOVED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x090A) +#define DXUTERR_NODIRECT3D11 MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x090) + +//-------------------------------------------------------------------------------------- +// Callback registration +//-------------------------------------------------------------------------------------- + +// General callbacks +typedef void (CALLBACK *LPDXUTCALLBACKFRAMEMOVE)( double fTime, float fElapsedTime, void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKKEYBOARD)( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKMOUSE)( bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, bool bSideButton1Down, bool bSideButton2Down, int nMouseWheelDelta, int xPos, int yPos, void* pUserContext ); +typedef LRESULT (CALLBACK *LPDXUTCALLBACKMSGPROC)( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKTIMER)( UINT idEvent, void* pUserContext ); +typedef bool (CALLBACK *LPDXUTCALLBACKMODIFYDEVICESETTINGS)( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ); +typedef bool (CALLBACK *LPDXUTCALLBACKDEVICEREMOVED)( void* pUserContext ); + +// Direct3D 9 callbacks +typedef bool (CALLBACK *LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE)( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext ); +typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D9DEVICECREATED)( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); +typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D9DEVICERESET)( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKD3D9FRAMERENDER)( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKD3D9DEVICELOST)( void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKD3D9DEVICEDESTROYED)( void* pUserContext ); + +class CD3D11EnumAdapterInfo; +class CD3D11EnumDeviceInfo; +// Direct3D 11 callbacks +typedef bool (CALLBACK *LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE)( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext ); +typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D11DEVICECREATED)( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); +typedef HRESULT (CALLBACK *LPDXUTCALLBACKD3D11SWAPCHAINRESIZED)( ID3D11Device* pd3dDevice, IDXGISwapChain *pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKD3D11FRAMERENDER)( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, float fElapsedTime, void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKD3D11SWAPCHAINRELEASING)( void* pUserContext ); +typedef void (CALLBACK *LPDXUTCALLBACKD3D11DEVICEDESTROYED)( void* pUserContext ); + +// General callbacks +void WINAPI DXUTSetCallbackFrameMove( LPDXUTCALLBACKFRAMEMOVE pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackKeyboard( LPDXUTCALLBACKKEYBOARD pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackMouse( LPDXUTCALLBACKMOUSE pCallback, bool bIncludeMouseMove = false, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackDeviceChanging( LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackDeviceRemoved( LPDXUTCALLBACKDEVICEREMOVED pCallback, void* pUserContext = NULL ); + +// Direct3D 9 callbacks +void WINAPI DXUTSetCallbackD3D9DeviceAcceptable( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D9DeviceCreated( LPDXUTCALLBACKD3D9DEVICECREATED pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D9DeviceReset( LPDXUTCALLBACKD3D9DEVICERESET pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D9FrameRender( LPDXUTCALLBACKD3D9FRAMERENDER pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D9DeviceLost( LPDXUTCALLBACKD3D9DEVICELOST pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D9DeviceDestroyed( LPDXUTCALLBACKD3D9DEVICEDESTROYED pCallback, void* pUserContext = NULL ); + +// Direct3D 11 callbacks +void WINAPI DXUTSetCallbackD3D11DeviceAcceptable( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D11DeviceCreated( LPDXUTCALLBACKD3D11DEVICECREATED pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D11SwapChainResized( LPDXUTCALLBACKD3D11SWAPCHAINRESIZED pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D11FrameRender( LPDXUTCALLBACKD3D11FRAMERENDER pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D11SwapChainReleasing( LPDXUTCALLBACKD3D11SWAPCHAINRELEASING pCallback, void* pUserContext = NULL ); +void WINAPI DXUTSetCallbackD3D11DeviceDestroyed( LPDXUTCALLBACKD3D11DEVICEDESTROYED pCallback, void* pUserContext = NULL ); + + +//-------------------------------------------------------------------------------------- +// Initialization +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTInit( bool bParseCommandLine = true, + bool bShowMsgBoxOnError = true, + __in_opt WCHAR* strExtraCommandLineParams = NULL, + bool bThreadSafeDXUT = false ); + +// Choose either DXUTCreateWindow or DXUTSetWindow. If using DXUTSetWindow, consider using DXUTStaticWndProc +HRESULT WINAPI DXUTCreateWindow( const WCHAR* strWindowTitle = L"Direct3D Window", + HINSTANCE hInstance = NULL, HICON hIcon = NULL, HMENU hMenu = NULL, + int x = CW_USEDEFAULT, int y = CW_USEDEFAULT ); +HRESULT WINAPI DXUTSetWindow( HWND hWndFocus, HWND hWndDeviceFullScreen, HWND hWndDeviceWindowed, bool bHandleMessages = true ); +LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +// Choose either DXUTCreateDevice or DXUTSetD3D*Device or DXUTCreateD3DDeviceFromSettings + +HRESULT WINAPI DXUTCreateDevice(D3D_FEATURE_LEVEL reqFL, bool bWindowed= true, int nSuggestedWidth =0, int nSuggestedHeight =0 ); +HRESULT WINAPI DXUTCreateDeviceFromSettings( DXUTDeviceSettings* pDeviceSettings, bool bPreserveInput = false, bool bClipWindowToSingleAdapter = true ); +HRESULT WINAPI DXUTSetD3D9Device( IDirect3DDevice9* pd3dDevice ); +HRESULT WINAPI DXUTSetD3D11Device( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain ); + +// Choose either DXUTMainLoop or implement your own main loop +HRESULT WINAPI DXUTMainLoop( HACCEL hAccel = NULL ); + +// If not using DXUTMainLoop consider using DXUTRender3DEnvironment +void WINAPI DXUTRender3DEnvironment(); + + +//-------------------------------------------------------------------------------------- +// Common Tasks +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTToggleFullScreen(); +HRESULT WINAPI DXUTToggleREF(); +HRESULT WINAPI DXUTToggleWARP(); +void WINAPI DXUTPause( bool bPauseTime, bool bPauseRendering ); +void WINAPI DXUTSetConstantFrameTime( bool bConstantFrameTime, float fTimePerFrame = 0.0333f ); +void WINAPI DXUTSetCursorSettings( bool bShowCursorWhenFullScreen = false, bool bClipCursorWhenFullScreen = false ); +void WINAPI DXUTSetD3DVersionSupport( bool bAppCanUseD3D9 = true, bool bAppCanUseD3D11 = true ); +void WINAPI DXUTSetHotkeyHandling( bool bAltEnterToToggleFullscreen = true, bool bEscapeToQuit = true, bool bPauseToToggleTimePause = true ); +void WINAPI DXUTSetMultimonSettings( bool bAutoChangeAdapter = true ); +void WINAPI DXUTSetShortcutKeySettings( bool bAllowWhenFullscreen = false, bool bAllowWhenWindowed = true ); // Controls the Windows key, and accessibility shortcut keys +void WINAPI DXUTSetWindowSettings( bool bCallDefWindowProc = true ); +HRESULT WINAPI DXUTSetTimer( LPDXUTCALLBACKTIMER pCallbackTimer, float fTimeoutInSecs = 1.0f, UINT* pnIDEvent = NULL, void* pCallbackUserContext = NULL ); +HRESULT WINAPI DXUTKillTimer( UINT nIDEvent ); +void WINAPI DXUTResetFrameworkState(); +void WINAPI DXUTShutdown( int nExitCode = 0 ); +void WINAPI DXUTSetIsInGammaCorrectMode( bool bGammaCorrect ); +BOOL WINAPI DXUTGetMSAASwapChainCreated(); + +//-------------------------------------------------------------------------------------- +// State Retrieval +//-------------------------------------------------------------------------------------- + +// Direct3D 9 +IDirect3D9* WINAPI DXUTGetD3D9Object(); // Does not addref unlike typical Get* APIs +IDirect3DDevice9* WINAPI DXUTGetD3D9Device(); // Does not addref unlike typical Get* APIs +D3DPRESENT_PARAMETERS WINAPI DXUTGetD3D9PresentParameters(); +const D3DSURFACE_DESC* WINAPI DXUTGetD3D9BackBufferSurfaceDesc(); +const D3DCAPS9* WINAPI DXUTGetD3D9DeviceCaps(); +HRESULT WINAPI DXUTGetD3D9DeviceCaps( DXUTDeviceSettings* pDeviceSettings, D3DCAPS9* pCaps ); +bool WINAPI DXUTDoesAppSupportD3D9(); +bool WINAPI DXUTIsAppRenderingWithD3D9(); + + +// Direct3D 11 +IDXGIFactory1* WINAPI DXUTGetDXGIFactory(); // Does not addref unlike typical Get* APIs +IDXGISwapChain* WINAPI DXUTGetDXGISwapChain(); // Does not addref unlike typical Get* APIs +const DXGI_SURFACE_DESC* WINAPI DXUTGetDXGIBackBufferSurfaceDesc(); +bool WINAPI DXUTIsD3D11Available(); // If D3D11 APIs are availible +ID3D11Device* WINAPI DXUTGetD3D11Device(); // Does not addref unlike typical Get* APIs +ID3D11DeviceContext* WINAPI DXUTGetD3D11DeviceContext(); // Does not addref unlike typical Get* APIs +HRESULT WINAPI DXUTSetupD3D11Views( ID3D11DeviceContext* pd3dDeviceContext ); // Supports immediate or deferred context +D3D_FEATURE_LEVEL WINAPI DXUTGetD3D11DeviceFeatureLevel(); // Returns the D3D11 devices current feature level +ID3D11RenderTargetView* WINAPI DXUTGetD3D11RenderTargetView(); // Does not addref unlike typical Get* APIs +ID3D11DepthStencilView* WINAPI DXUTGetD3D11DepthStencilView(); // Does not addref unlike typical Get* APIs +bool WINAPI DXUTDoesAppSupportD3D11(); +bool WINAPI DXUTIsAppRenderingWithD3D11(); + + +// General +DXUTDeviceSettings WINAPI DXUTGetDeviceSettings(); +HINSTANCE WINAPI DXUTGetHINSTANCE(); +HWND WINAPI DXUTGetHWND(); +HWND WINAPI DXUTGetHWNDFocus(); +HWND WINAPI DXUTGetHWNDDeviceFullScreen(); +HWND WINAPI DXUTGetHWNDDeviceWindowed(); +RECT WINAPI DXUTGetWindowClientRect(); +LONG WINAPI DXUTGetWindowWidth(); +LONG WINAPI DXUTGetWindowHeight(); +RECT WINAPI DXUTGetWindowClientRectAtModeChange(); // Useful for returning to windowed mode with the same resolution as before toggle to full screen mode +RECT WINAPI DXUTGetFullsceenClientRectAtModeChange(); // Useful for returning to full screen mode with the same resolution as before toggle to windowed mode +double WINAPI DXUTGetTime(); +float WINAPI DXUTGetElapsedTime(); +bool WINAPI DXUTIsWindowed(); +bool WINAPI DXUTIsInGammaCorrectMode(); +float WINAPI DXUTGetFPS(); +LPCWSTR WINAPI DXUTGetWindowTitle(); +LPCWSTR WINAPI DXUTGetFrameStats( bool bIncludeFPS = false ); +LPCWSTR WINAPI DXUTGetDeviceStats(); + +bool WINAPI DXUTIsVsyncEnabled(); +bool WINAPI DXUTIsRenderingPaused(); +bool WINAPI DXUTIsTimePaused(); +bool WINAPI DXUTIsActive(); +int WINAPI DXUTGetExitCode(); +bool WINAPI DXUTGetShowMsgBoxOnError(); +bool WINAPI DXUTGetAutomation(); // Returns true if -automation parameter is used to launch the app +bool WINAPI DXUTIsKeyDown( BYTE vKey ); // Pass a virtual-key code, ex. VK_F1, 'A', VK_RETURN, VK_LSHIFT, etc +bool WINAPI DXUTWasKeyPressed( BYTE vKey ); // Like DXUTIsKeyDown() but return true only if the key was just pressed +bool WINAPI DXUTIsMouseButtonDown( BYTE vButton ); // Pass a virtual-key code: VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_XBUTTON1, VK_XBUTTON2 +HRESULT WINAPI DXUTCreateState(); // Optional method to create DXUT's memory. If its not called by the application it will be automatically called when needed +void WINAPI DXUTDestroyState(); // Optional method to destroy DXUT's memory. If its not called by the application it will be automatically called after the application exits WinMain + +//-------------------------------------------------------------------------------------- +// DXUT core layer includes +//-------------------------------------------------------------------------------------- +#include "DXUTmisc.h" +#include "DXUTDevice9.h" +#include "DXUTDevice11.h" + + + + +#endif + + + + diff --git a/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.cpp b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.cpp new file mode 100644 index 0000000..7eaff55 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.cpp @@ -0,0 +1,1154 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTDevice11.cpp +// +// Enumerates D3D adapters, devices, modes, etc. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#undef min // use __min instead +#undef max // use __max instead + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- +extern void DXUTGetCallbackD3D11DeviceAcceptable( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE* ppCallbackIsDeviceAcceptable, void** ppUserContext ); + +static int __cdecl SortModesCallback( const void* arg1, const void* arg2 ); + +CD3D11Enumeration* g_pDXUTD3D11Enumeration = NULL; + + + + +HRESULT WINAPI DXUTCreateD3D11Enumeration() +{ + if( g_pDXUTD3D11Enumeration == NULL ) + { + g_pDXUTD3D11Enumeration = new CD3D11Enumeration(); + if( NULL == g_pDXUTD3D11Enumeration ) + return E_OUTOFMEMORY; + } + return S_OK; +} + +void WINAPI DXUTDestroyD3D11Enumeration() +{ + SAFE_DELETE( g_pDXUTD3D11Enumeration ); +} + +class DXUTMemoryHelperD3D11Enum +{ +public: +DXUTMemoryHelperD3D11Enum() +{ + DXUTCreateD3D11Enumeration(); +} +~DXUTMemoryHelperD3D11Enum() +{ + DXUTDestroyD3D11Enumeration(); +} +}; + + +//-------------------------------------------------------------------------------------- +CD3D11Enumeration* WINAPI DXUTGetD3D11Enumeration( bool bForceEnumerate, bool bEnumerateAllAdapterFormats, D3D_FEATURE_LEVEL forceFL ) +{ + // Using an static class with accessor function to allow control of the construction order + static DXUTMemoryHelperD3D11Enum d3d11enumMemory; + if( g_pDXUTD3D11Enumeration && ( !g_pDXUTD3D11Enumeration->HasEnumerated() || bForceEnumerate ) ) + { + g_pDXUTD3D11Enumeration->SetEnumerateAllAdapterFormats( bEnumerateAllAdapterFormats ); + LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE pCallbackIsDeviceAcceptable; + void* pUserContext; + DXUTGetCallbackD3D11DeviceAcceptable( &pCallbackIsDeviceAcceptable, &pUserContext ); + g_pDXUTD3D11Enumeration->SetForceFeatureLevel(forceFL); + + g_pDXUTD3D11Enumeration->Enumerate( pCallbackIsDeviceAcceptable, pUserContext ); + } + + return g_pDXUTD3D11Enumeration; +} + + +//-------------------------------------------------------------------------------------- +CD3D11Enumeration::CD3D11Enumeration() +{ + m_bHasEnumerated = false; + m_IsD3D11DeviceAcceptableFunc = NULL; + m_pIsD3D11DeviceAcceptableFuncUserContext = NULL; + + m_nMinWidth = 640; + m_nMinHeight = 480; + m_nMaxWidth = UINT_MAX; + m_nMaxHeight = UINT_MAX; + m_bEnumerateAllAdapterFormats = false; + + m_nRefreshMin = 0; + m_nRefreshMax = UINT_MAX; + + ResetPossibleDepthStencilFormats(); +} + + +//-------------------------------------------------------------------------------------- +CD3D11Enumeration::~CD3D11Enumeration() +{ + ClearAdapterInfoList(); +} + + +//-------------------------------------------------------------------------------------- +// Enumerate for each adapter all of the supported display modes, +// device types, adapter formats, back buffer formats, window/full screen support, +// depth stencil formats, multisampling types/qualities, and presentations intervals. +// +// For each combination of device type (HAL/REF), adapter format, back buffer format, and +// IsWindowed it will call the app's ConfirmDevice callback. This allows the app +// to reject or allow that combination based on its caps/etc. It also allows the +// app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP +// if supported otherwise it will default to SWVP, however the app can change this +// through the ConfirmDevice callback. +//-------------------------------------------------------------------------------------- +HRESULT CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc, + void* pIsD3D11DeviceAcceptableFuncUserContext ) +{ + CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" ); + HRESULT hr; + IDXGIFactory1* pFactory = DXUTGetDXGIFactory(); + if( pFactory == NULL ) + return E_FAIL; + + m_bHasEnumerated = true; + m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc; + m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext; + + ClearAdapterInfoList(); + + for( int index = 0; ; ++index ) + { + IDXGIAdapter* pAdapter = NULL; + hr = pFactory->EnumAdapters( index, &pAdapter ); + if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit + break; + + CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo; + if( !pAdapterInfo ) + { + SAFE_RELEASE( pAdapter ); + return E_OUTOFMEMORY; + } + ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) ); + pAdapterInfo->AdapterOrdinal = index; + pAdapter->GetDesc( &pAdapterInfo->AdapterDesc ); + pAdapterInfo->m_pAdapter = pAdapter; + + // Enumerate the device driver types on the adapter. + hr = EnumerateDevices( pAdapterInfo ); + if( FAILED( hr ) ) + { + delete pAdapterInfo; + continue; + } + + hr = EnumerateOutputs( pAdapterInfo ); + if( FAILED( hr ) || pAdapterInfo->outputInfoList.GetSize() <= 0 ) + { + delete pAdapterInfo; + continue; + } + + // Get info for each devicecombo on this device + if( FAILED( hr = EnumerateDeviceCombos( pFactory, pAdapterInfo ) ) ) + { + delete pAdapterInfo; + continue; + } + + hr = m_AdapterInfoList.Add( pAdapterInfo ); + if( FAILED( hr ) ) + { + delete pAdapterInfo; + return hr; + } + } + + + // If we did not get an adapter then we should still enumerate WARP and Ref. + if (m_AdapterInfoList.GetSize() == 0) { + + + CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo; + if( !pAdapterInfo ) + { + return E_OUTOFMEMORY; + } + ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) ); + pAdapterInfo->bAdapterUnavailable = true; + + hr = EnumerateDevices( pAdapterInfo ); + + // Get info for each devicecombo on this device + if( FAILED( hr = EnumerateDeviceCombosNoAdapter( pAdapterInfo ) ) ) + { + delete pAdapterInfo; + } + + if (!FAILED(hr)) hr = m_AdapterInfoList.Add( pAdapterInfo ); + } + + // + // Check for 2 or more adapters with the same name. Append the name + // with some instance number if that's the case to help distinguish + // them. + // + bool bUniqueDesc = true; + CD3D11EnumAdapterInfo* pAdapterInfo; + for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) + { + CD3D11EnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt( i ); + + for( int j = i + 1; j < m_AdapterInfoList.GetSize(); j++ ) + { + CD3D11EnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt( j ); + if( wcsncmp( pAdapterInfo1->AdapterDesc.Description, + pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 ) + { + bUniqueDesc = false; + break; + } + } + + if( !bUniqueDesc ) + break; + } + + for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) + { + pAdapterInfo = m_AdapterInfoList.GetAt( i ); + + wcscpy_s( pAdapterInfo->szUniqueDescription, 100, pAdapterInfo->AdapterDesc.Description ); + if( !bUniqueDesc ) + { + WCHAR sz[100]; + swprintf_s( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal ); + wcscat_s( pAdapterInfo->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz ); + } + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CD3D11Enumeration::EnumerateOutputs( CD3D11EnumAdapterInfo* pAdapterInfo ) +{ + HRESULT hr; + IDXGIOutput* pOutput; + + for( int iOutput = 0; ; ++iOutput ) + { + pOutput = NULL; + hr = pAdapterInfo->m_pAdapter->EnumOutputs( iOutput, &pOutput ); + if( DXGI_ERROR_NOT_FOUND == hr ) + { + return S_OK; + } + else if( FAILED( hr ) ) + { + return hr; //Something bad happened. + } + else //Success! + { + CD3D11EnumOutputInfo* pOutputInfo = new CD3D11EnumOutputInfo; + if( !pOutputInfo ) + { + SAFE_RELEASE( pOutput ); + return E_OUTOFMEMORY; + } + ZeroMemory( pOutputInfo, sizeof( CD3D11EnumOutputInfo ) ); + pOutput->GetDesc( &pOutputInfo->Desc ); + pOutputInfo->Output = iOutput; + pOutputInfo->m_pOutput = pOutput; + + EnumerateDisplayModes( pOutputInfo ); + if( pOutputInfo->displayModeList.GetSize() <= 0 ) + { + // If this output has no valid display mode, do not save it. + delete pOutputInfo; + continue; + } + + hr = pAdapterInfo->outputInfoList.Add( pOutputInfo ); + if( FAILED( hr ) ) + { + delete pOutputInfo; + return hr; + } + } + } +} + + +//-------------------------------------------------------------------------------------- +HRESULT CD3D11Enumeration::EnumerateDisplayModes( CD3D11EnumOutputInfo* pOutputInfo ) +{ + HRESULT hr = S_OK; + DXGI_FORMAT allowedAdapterFormatArray[] = + { + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, //This is DXUT's preferred mode + + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R10G10B10A2_UNORM + }; + int allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof( allowedAdapterFormatArray[0] ); + + // Swap perferred modes for apps running in linear space + DXGI_FORMAT RemoteMode = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + if( !DXUTIsInGammaCorrectMode() ) + { + allowedAdapterFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + allowedAdapterFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + RemoteMode = DXGI_FORMAT_R8G8B8A8_UNORM; + } + + // The fast path only enumerates R8G8B8A8_UNORM_SRGB modes + if( !m_bEnumerateAllAdapterFormats ) + allowedAdapterFormatArrayCount = 1; + + for( int f = 0; f < allowedAdapterFormatArrayCount; ++f ) + { + // Fast-path: Try to grab at least 512 modes. + // This is to avoid calling GetDisplayModeList more times than necessary. + // GetDisplayModeList is an expensive call. + UINT NumModes = 512; + DXGI_MODE_DESC* pDesc = new DXGI_MODE_DESC[ NumModes ]; + assert( pDesc ); + if( !pDesc ) + return E_OUTOFMEMORY; + + hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f], + DXGI_ENUM_MODES_SCALING, + &NumModes, + pDesc ); + if( DXGI_ERROR_NOT_FOUND == hr ) + { + SAFE_DELETE_ARRAY( pDesc ); + NumModes = 0; + break; + } + else if( MAKE_DXGI_HRESULT( 34 ) == hr && RemoteMode == allowedAdapterFormatArray[f] ) + { + // DXGI cannot enumerate display modes over a remote session. Therefore, create a fake display + // mode for the current screen resolution for the remote session. + if( 0 != GetSystemMetrics( 0x1000 ) ) // SM_REMOTESESSION + { + DEVMODE DevMode; + DevMode.dmSize = sizeof( DEVMODE ); + if( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &DevMode ) ) + { + NumModes = 1; + pDesc[0].Width = DevMode.dmPelsWidth; + pDesc[0].Height = DevMode.dmPelsHeight; + pDesc[0].Format = DXGI_FORMAT_R8G8B8A8_UNORM; + pDesc[0].RefreshRate.Numerator = 60; + pDesc[0].RefreshRate.Denominator = 1; + pDesc[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; + pDesc[0].Scaling = DXGI_MODE_SCALING_CENTERED; + hr = S_OK; + } + } + } + else if( DXGI_ERROR_MORE_DATA == hr ) + { + // Slow path. There were more than 512 modes. + SAFE_DELETE_ARRAY( pDesc ); + hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f], + DXGI_ENUM_MODES_SCALING, + &NumModes, + NULL ); + if( FAILED( hr ) ) + { + NumModes = 0; + break; + } + + pDesc = new DXGI_MODE_DESC[ NumModes ]; + assert( pDesc ); + if( !pDesc ) + return E_OUTOFMEMORY; + + hr = pOutputInfo->m_pOutput->GetDisplayModeList( allowedAdapterFormatArray[f], + DXGI_ENUM_MODES_SCALING, + &NumModes, + pDesc ); + if( FAILED( hr ) ) + { + SAFE_DELETE_ARRAY( pDesc ); + NumModes = 0; + break; + } + + } + + if( 0 == NumModes && 0 == f ) + { + // No R8G8B8A8_UNORM_SRGB modes! + // Abort the fast-path if we're on it + allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof + ( allowedAdapterFormatArray[0] ); + SAFE_DELETE_ARRAY( pDesc ); + continue; + } + + if( SUCCEEDED( hr ) ) + { + for( UINT m = 0; m < NumModes; m++ ) + { + pOutputInfo->displayModeList.Add( pDesc[m] ); + } + } + + SAFE_DELETE_ARRAY( pDesc ); + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CD3D11Enumeration::EnumerateDevices( CD3D11EnumAdapterInfo* pAdapterInfo ) +{ + HRESULT hr; + DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings(); + const D3D_DRIVER_TYPE devTypeArray[] = + { + D3D_DRIVER_TYPE_HARDWARE, + D3D_DRIVER_TYPE_WARP, + D3D_DRIVER_TYPE_REFERENCE + }; + const UINT devTypeArrayCount = sizeof( devTypeArray ) / sizeof( devTypeArray[0] ); + + // Enumerate each Direct3D device type + for( UINT iDeviceType = 0; iDeviceType < devTypeArrayCount; iDeviceType++ ) + { + CD3D11EnumDeviceInfo* pDeviceInfo = new CD3D11EnumDeviceInfo; + if( pDeviceInfo == NULL ) + return E_OUTOFMEMORY; + + // Fill struct w/ AdapterOrdinal and D3DX10_DRIVER_TYPE + pDeviceInfo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal; + pDeviceInfo->DeviceType = devTypeArray[iDeviceType]; + + D3D_FEATURE_LEVEL FeatureLevels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; + UINT NumFeatureLevels = ARRAYSIZE( FeatureLevels ); + + // Call D3D11CreateDevice to ensure that this is a D3D11 device. + ID3D11Device* pd3dDevice = NULL; + ID3D11DeviceContext* pd3dDeviceContext = NULL; + IDXGIAdapter* pAdapter = NULL; + //if( devTypeArray[iDeviceType] == D3D_DRIVER_TYPE_HARDWARE ) + // pAdapter = pAdapterInfo->m_pAdapter; + hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter, + devTypeArray[iDeviceType], + ( HMODULE )0, + 0, + FeatureLevels, + NumFeatureLevels, + D3D11_SDK_VERSION, + &pd3dDevice, + &pDeviceInfo->MaxLevel, + &pd3dDeviceContext ); + if( FAILED( hr ) || pDeviceInfo->MaxLevel < deviceSettings.MinimumFeatureLevel) + { + delete pDeviceInfo; + continue; + } + + if (g_forceFL == 0 || g_forceFL == pDeviceInfo->MaxLevel) { + pDeviceInfo->SelectedLevel = pDeviceInfo->MaxLevel; + } + else if (g_forceFL > pDeviceInfo->MaxLevel) { + delete pDeviceInfo; + SAFE_RELEASE( pd3dDevice ); + SAFE_RELEASE( pd3dDeviceContext ); + continue; + } else { + // A device was created with a higher feature level that the user-specified feature level. + SAFE_RELEASE( pd3dDevice ); + SAFE_RELEASE( pd3dDeviceContext ); + D3D_FEATURE_LEVEL rtFL; + hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter, + devTypeArray[iDeviceType], + ( HMODULE )0, + 0, + &g_forceFL, + 1, + D3D11_SDK_VERSION, + &pd3dDevice, + &rtFL, + &pd3dDeviceContext ); + + if( !FAILED( hr ) && rtFL == g_forceFL ) { + + pDeviceInfo->SelectedLevel = g_forceFL; + }else { + delete pDeviceInfo; + SAFE_RELEASE( pd3dDevice ); + SAFE_RELEASE( pd3dDeviceContext ); + continue; + } + } + + IDXGIDevice1* pDXGIDev = NULL; + hr = pd3dDevice->QueryInterface( __uuidof( IDXGIDevice1 ), ( LPVOID* )&pDXGIDev ); + if( SUCCEEDED( hr ) && pDXGIDev ) + { + SAFE_RELEASE( pAdapterInfo->m_pAdapter ); + pDXGIDev->GetAdapter( &pAdapterInfo->m_pAdapter ); + } + SAFE_RELEASE( pDXGIDev ); + + + D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS ho; + pd3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &ho, sizeof(ho)); + pDeviceInfo->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = ho.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; + SAFE_RELEASE( pd3dDeviceContext ); + SAFE_RELEASE( pd3dDevice ); + pAdapterInfo->deviceInfoList.Add( pDeviceInfo ); + } + + return S_OK; +} + + +HRESULT CD3D11Enumeration::EnumerateDeviceCombosNoAdapter( CD3D11EnumAdapterInfo* pAdapterInfo ) +{ + // Iterate through each combination of device driver type, output, + // adapter format, and backbuffer format to build the adapter's device combo list. + // + + for( int device = 0; device < pAdapterInfo->deviceInfoList.GetSize(); ++device ) + { + CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( device ); + + DXGI_FORMAT BufferFormatArray[] = + { + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, //This is DXUT's preferred mode + + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R10G10B10A2_UNORM + }; + const UINT BufferFormatArrayCount = sizeof( BufferFormatArray ) / sizeof + ( BufferFormatArray[0] ); + + // Swap perferred modes for apps running in linear space + if( !DXUTIsInGammaCorrectMode() ) + { + BufferFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + BufferFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + } + + for( UINT iBufferFormat = 0; iBufferFormat < BufferFormatArrayCount; iBufferFormat++ ) + { + DXGI_FORMAT BufferFormat = BufferFormatArray[iBufferFormat]; + + + + // determine if there are any modes for this particular format + + + // If an application callback function has been provided, make sure this device + // is acceptable to the app. + if( m_IsD3D11DeviceAcceptableFunc != NULL ) + { + if( !m_IsD3D11DeviceAcceptableFunc( pAdapterInfo, + 0, + pDeviceInfo, + BufferFormat, + TRUE, + m_pIsD3D11DeviceAcceptableFuncUserContext ) ) + continue; + } + + // At this point, we have an adapter/device/backbufferformat/iswindowed + // DeviceCombo that is supported by the system. We still + // need to find one or more suitable depth/stencil buffer format, + // multisample type, and present interval. + CD3D11EnumDeviceSettingsCombo* pDeviceCombo = new CD3D11EnumDeviceSettingsCombo; + if( pDeviceCombo == NULL ) + return E_OUTOFMEMORY; + + pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal; + pDeviceCombo->DeviceType = pDeviceInfo->DeviceType; + pDeviceCombo->BackBufferFormat = BufferFormat; + pDeviceCombo->Windowed = TRUE; + pDeviceCombo->Output = 0; + pDeviceCombo->pAdapterInfo = pAdapterInfo; + pDeviceCombo->pDeviceInfo = pDeviceInfo; + pDeviceCombo->pOutputInfo = NULL; + + BuildMultiSampleQualityList( BufferFormat, pDeviceCombo ); + + if( FAILED( pAdapterInfo->deviceSettingsComboList.Add( pDeviceCombo ) ) ) + delete pDeviceCombo; + } + + } + + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CD3D11Enumeration::EnumerateDeviceCombos( IDXGIFactory1* pFactory, CD3D11EnumAdapterInfo* pAdapterInfo ) +{ + // Iterate through each combination of device driver type, output, + // adapter format, and backbuffer format to build the adapter's device combo list. + // + + for( int output = 0; output < pAdapterInfo->outputInfoList.GetSize(); ++output ) + { + CD3D11EnumOutputInfo* pOutputInfo = pAdapterInfo->outputInfoList.GetAt( output ); + + for( int device = 0; device < pAdapterInfo->deviceInfoList.GetSize(); ++device ) + { + CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( device ); + + DXGI_FORMAT backBufferFormatArray[] = + { + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, //This is DXUT's preferred mode + + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R10G10B10A2_UNORM + }; + const UINT backBufferFormatArrayCount = sizeof( backBufferFormatArray ) / sizeof + ( backBufferFormatArray[0] ); + + // Swap perferred modes for apps running in linear space + if( !DXUTIsInGammaCorrectMode() ) + { + backBufferFormatArray[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + backBufferFormatArray[1] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + } + + for( UINT iBackBufferFormat = 0; iBackBufferFormat < backBufferFormatArrayCount; iBackBufferFormat++ ) + { + DXGI_FORMAT backBufferFormat = backBufferFormatArray[iBackBufferFormat]; + + for( int nWindowed = 0; nWindowed < 2; nWindowed++ ) + { + if( !nWindowed && pOutputInfo->displayModeList.GetSize() == 0 ) + continue; + + // determine if there are any modes for this particular format + UINT iModes = 0; + for( int i = 0; i < pOutputInfo->displayModeList.GetSize(); i++ ) + { + if( backBufferFormat == pOutputInfo->displayModeList.GetAt( i ).Format ) + iModes ++; + } + if( 0 == iModes ) + continue; + + // If an application callback function has been provided, make sure this device + // is acceptable to the app. + if( m_IsD3D11DeviceAcceptableFunc != NULL ) + { + if( !m_IsD3D11DeviceAcceptableFunc( pAdapterInfo, output, + pDeviceInfo, backBufferFormat, + FALSE != nWindowed, + m_pIsD3D11DeviceAcceptableFuncUserContext ) ) + continue; + } + + // At this point, we have an adapter/device/backbufferformat/iswindowed + // DeviceCombo that is supported by the system. We still + // need to find one or more suitable depth/stencil buffer format, + // multisample type, and present interval. + CD3D11EnumDeviceSettingsCombo* pDeviceCombo = new CD3D11EnumDeviceSettingsCombo; + if( pDeviceCombo == NULL ) + return E_OUTOFMEMORY; + + pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal; + pDeviceCombo->DeviceType = pDeviceInfo->DeviceType; + pDeviceCombo->BackBufferFormat = backBufferFormat; + pDeviceCombo->Windowed = ( nWindowed != 0 ); + pDeviceCombo->Output = pOutputInfo->Output; + pDeviceCombo->pAdapterInfo = pAdapterInfo; + pDeviceCombo->pDeviceInfo = pDeviceInfo; + pDeviceCombo->pOutputInfo = pOutputInfo; + + BuildMultiSampleQualityList( backBufferFormat, pDeviceCombo ); + + if( FAILED( pAdapterInfo->deviceSettingsComboList.Add( pDeviceCombo ) ) ) + delete pDeviceCombo; + } + } + } + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Release all the allocated CD3D11EnumAdapterInfo objects and empty the list +//-------------------------------------------------------------------------------------- +void CD3D11Enumeration::ClearAdapterInfoList() +{ + CD3D11EnumAdapterInfo* pAdapterInfo; + for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) + { + pAdapterInfo = m_AdapterInfoList.GetAt( i ); + delete pAdapterInfo; + } + + m_AdapterInfoList.RemoveAll(); +} + + +//-------------------------------------------------------------------------------------- +void CD3D11Enumeration::ResetPossibleDepthStencilFormats() +{ + m_DepthStencilPossibleList.RemoveAll(); + m_DepthStencilPossibleList.Add( DXGI_FORMAT_D32_FLOAT_S8X24_UINT ); + m_DepthStencilPossibleList.Add( DXGI_FORMAT_D32_FLOAT ); + m_DepthStencilPossibleList.Add( DXGI_FORMAT_D24_UNORM_S8_UINT ); + m_DepthStencilPossibleList.Add( DXGI_FORMAT_D16_UNORM ); +} + +//-------------------------------------------------------------------------------------- +void CD3D11Enumeration::SetEnumerateAllAdapterFormats( bool bEnumerateAllAdapterFormats ) +{ + m_bEnumerateAllAdapterFormats = bEnumerateAllAdapterFormats; +} + + +//-------------------------------------------------------------------------------------- +void CD3D11Enumeration::BuildMultiSampleQualityList( DXGI_FORMAT fmt, CD3D11EnumDeviceSettingsCombo* pDeviceCombo ) +{ + ID3D11Device* pd3dDevice = NULL; + ID3D11DeviceContext* pd3dDeviceContext = NULL; + IDXGIAdapter* pAdapter = NULL; + + //if( pDeviceCombo->DeviceType == D3D_DRIVER_TYPE_HARDWARE ) + // DXUTGetDXGIFactory()->EnumAdapters( pDeviceCombo->pAdapterInfo->AdapterOrdinal, &pAdapter ); + + //DXGI_ADAPTER_DESC dad; + //pAdapter->GetDesc(&dad); + + D3D_FEATURE_LEVEL *FeatureLevels = &(pDeviceCombo->pDeviceInfo->SelectedLevel); + D3D_FEATURE_LEVEL returnedFeatureLevel; + + UINT NumFeatureLevels = 1; + + HRESULT hr = DXUT_Dynamic_D3D11CreateDevice( pAdapter, + pDeviceCombo->DeviceType, + ( HMODULE )0, + 0, + FeatureLevels, + NumFeatureLevels, + D3D11_SDK_VERSION, + &pd3dDevice, + &returnedFeatureLevel, + &pd3dDeviceContext ) ; + + if( FAILED( hr)) return; + + if (returnedFeatureLevel != pDeviceCombo->pDeviceInfo->SelectedLevel) return; + + for( int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++i ) + { + UINT Quality; + if( SUCCEEDED( pd3dDevice->CheckMultisampleQualityLevels( fmt, i, &Quality ) ) && Quality > 0 ) + { + //From D3D10 docs: When multisampling a texture, the number of quality levels available for an adapter is dependent on the texture + //format used and the number of samples requested. The maximum sample count is defined by + //D3D10_MAX_MULTISAMPLE_SAMPLE_COUNT in d3d10.h. If the returned value of pNumQualityLevels is 0, + //the format and sample count combination is not supported for the installed adapter. + + if (Quality != 0) { + pDeviceCombo->multiSampleCountList.Add( i ); + pDeviceCombo->multiSampleQualityList.Add( Quality ); + } + } + } + + SAFE_RELEASE( pAdapter ); + SAFE_RELEASE( pd3dDevice ); + SAFE_RELEASE (pd3dDeviceContext); +} + + +//-------------------------------------------------------------------------------------- +// Call GetAdapterInfoList() after Enumerate() to get a STL vector of +// CD3D11EnumAdapterInfo* +//-------------------------------------------------------------------------------------- +CGrowableArray * CD3D11Enumeration::GetAdapterInfoList() +{ + return &m_AdapterInfoList; +} + + +//-------------------------------------------------------------------------------------- +CD3D11EnumAdapterInfo* CD3D11Enumeration::GetAdapterInfo( UINT AdapterOrdinal ) +{ + for( int iAdapter = 0; iAdapter < m_AdapterInfoList.GetSize(); iAdapter++ ) + { + CD3D11EnumAdapterInfo* pAdapterInfo = m_AdapterInfoList.GetAt( iAdapter ); + if( pAdapterInfo->AdapterOrdinal == AdapterOrdinal ) + return pAdapterInfo; + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +CD3D11EnumDeviceInfo* CD3D11Enumeration::GetDeviceInfo( UINT AdapterOrdinal, D3D_DRIVER_TYPE DeviceType ) +{ + CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal ); + if( pAdapterInfo ) + { + for( int iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ ) + { + CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( iDeviceInfo ); + if( pDeviceInfo->DeviceType == DeviceType ) + return pDeviceInfo; + } + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +CD3D11EnumOutputInfo* CD3D11Enumeration::GetOutputInfo( UINT AdapterOrdinal, UINT Output ) +{ + CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal ); + if( pAdapterInfo && pAdapterInfo->outputInfoList.GetSize() > int( Output ) ) + { + return pAdapterInfo->outputInfoList.GetAt( Output ); + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +CD3D11EnumDeviceSettingsCombo* CD3D11Enumeration::GetDeviceSettingsCombo( UINT AdapterOrdinal, + D3D_DRIVER_TYPE DeviceType, UINT Output, + DXGI_FORMAT BackBufferFormat, BOOL Windowed ) +{ + CD3D11EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal ); + if( pAdapterInfo ) + { + for( int iDeviceCombo = 0; iDeviceCombo < pAdapterInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ ) + { + CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo = pAdapterInfo->deviceSettingsComboList.GetAt( + iDeviceCombo ); + if( pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat && + pDeviceSettingsCombo->Windowed == Windowed ) + return pDeviceSettingsCombo; + } + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +CD3D11EnumOutputInfo::~CD3D11EnumOutputInfo( void ) +{ + SAFE_RELEASE( m_pOutput ); + displayModeList.RemoveAll(); +} + + +//-------------------------------------------------------------------------------------- +CD3D11EnumDeviceInfo::~CD3D11EnumDeviceInfo() +{ +} + + +//-------------------------------------------------------------------------------------- +CD3D11EnumAdapterInfo::~CD3D11EnumAdapterInfo( void ) +{ + for( int i = 0; i < outputInfoList.GetSize(); i++ ) + { + CD3D11EnumOutputInfo* pOutputInfo = outputInfoList.GetAt( i ); + delete pOutputInfo; + } + outputInfoList.RemoveAll(); + + for( int i = 0; i < deviceInfoList.GetSize(); ++i ) + { + CD3D11EnumDeviceInfo* pDeviceInfo = deviceInfoList.GetAt( i ); + delete pDeviceInfo; + } + deviceInfoList.RemoveAll(); + + for( int i = 0; i < deviceSettingsComboList.GetSize(); ++i ) + { + CD3D11EnumDeviceSettingsCombo* pDeviceCombo = deviceSettingsComboList.GetAt( i ); + delete pDeviceCombo; + } + deviceSettingsComboList.RemoveAll(); + + SAFE_RELEASE( m_pAdapter ); +} + +//-------------------------------------------------------------------------------------- +// Returns the number of color channel bits in the specified DXGI_FORMAT +//-------------------------------------------------------------------------------------- +UINT WINAPI DXUTGetDXGIColorChannelBits( DXGI_FORMAT fmt ) +{ + switch( fmt ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 32; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + return 16; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + return 10; + + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + return 8; + + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + return 5; + + default: + return 0; + } +} + +//-------------------------------------------------------------------------------------- +// Returns a ranking number that describes how closely this device +// combo matches the optimal combo based on the match options and the optimal device settings +//-------------------------------------------------------------------------------------- +float DXUTRankD3D11DeviceCombo( CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo, + DXUTD3D11DeviceSettings* pOptimalDeviceSettings, + DXGI_MODE_DESC* pAdapterDisplayMode, + int &bestModeIndex, + int &bestMSAAIndex + ) +{ + float fCurRanking = 0.0f; + + // Arbitrary weights. Gives preference to the ordinal, device type, and windowed + const float fAdapterOrdinalWeight = 1000.0f; + const float fAdapterOutputWeight = 500.0f; + const float fDeviceTypeWeight = 100.0f; + const float fWARPOverRefWeight = 80.0f; + + const float fWindowWeight = 10.0f; + const float fResolutionWeight = 1.0f; + const float fBackBufferFormatWeight = 1.0f; + const float fMultiSampleWeight = 1.0f; + const float fRefreshRateWeight = 1.0f; + + //--------------------- + // Adapter ordinal + //--------------------- + if( pDeviceSettingsCombo->AdapterOrdinal == pOptimalDeviceSettings->AdapterOrdinal ) + fCurRanking += fAdapterOrdinalWeight; + + //--------------------- + // Adapter ordinal + //--------------------- + if( pDeviceSettingsCombo->Output == pOptimalDeviceSettings->Output ) + fCurRanking += fAdapterOutputWeight; + + //--------------------- + // Device type + //--------------------- + if( pDeviceSettingsCombo->DeviceType == pOptimalDeviceSettings->DriverType ) + fCurRanking += fDeviceTypeWeight; + else if (pDeviceSettingsCombo->DeviceType == D3D_DRIVER_TYPE_WARP && pOptimalDeviceSettings->DriverType == D3D_DRIVER_TYPE_HARDWARE) { + fCurRanking += fWARPOverRefWeight; + } + + // Slightly prefer HAL + if( pDeviceSettingsCombo->DeviceType == D3DDEVTYPE_HAL ) + fCurRanking += 0.1f; + + //--------------------- + // Windowed + //--------------------- + if( pDeviceSettingsCombo->Windowed == pOptimalDeviceSettings->sd.Windowed ) + fCurRanking += fWindowWeight; + + //--------------------- + // Resolution + //--------------------- + bool bResolutionFound = false; + unsigned int best = 0xffffffff; + bestModeIndex=0; + for( int idm = 0; pDeviceSettingsCombo->pOutputInfo != NULL && idm < pDeviceSettingsCombo->pOutputInfo->displayModeList.GetSize() && !bResolutionFound; idm++ ) + { + DXGI_MODE_DESC displayMode = pDeviceSettingsCombo->pOutputInfo->displayModeList.GetAt( idm ); + if( displayMode.Width == pOptimalDeviceSettings->sd.BufferDesc.Width && + displayMode.Height == pOptimalDeviceSettings->sd.BufferDesc.Height ) + bResolutionFound = true; + + unsigned int current = + (UINT) abs ((int)displayMode.Width - (int)pOptimalDeviceSettings->sd.BufferDesc.Width) + + (UINT) abs ((int)displayMode.Height - (int)pOptimalDeviceSettings->sd.BufferDesc.Height ); + + if (current < best) { + best = current; + bestModeIndex= idm; + + } + + } + if( bResolutionFound ) + fCurRanking += fResolutionWeight; + + //--------------------- + // Back buffer format + //--------------------- + if( pDeviceSettingsCombo->BackBufferFormat == pOptimalDeviceSettings->sd.BufferDesc.Format ) + { + fCurRanking += fBackBufferFormatWeight; + } + else + { + int nBitDepthDelta = abs( ( long )DXUTGetDXGIColorChannelBits( pDeviceSettingsCombo->BackBufferFormat ) - + ( long )DXUTGetDXGIColorChannelBits( + pOptimalDeviceSettings->sd.BufferDesc.Format ) ); + float fScale = __max( 0.9f - ( float )nBitDepthDelta * 0.2f, 0.0f ); + fCurRanking += fScale * fBackBufferFormatWeight; + } + + //--------------------- + // Back buffer count + //--------------------- + // No caps for the back buffer count + + //--------------------- + // Multisample + //--------------------- + bool bMultiSampleFound = false; + bestMSAAIndex = 0; + for( int i = 0; i < pDeviceSettingsCombo->multiSampleCountList.GetSize(); i++ ) + { + UINT Count = pDeviceSettingsCombo->multiSampleCountList.GetAt( i ); + + if( Count == pOptimalDeviceSettings->sd.SampleDesc.Count ) + { + bestMSAAIndex = i; + bMultiSampleFound = true; + break; + } + } + if( bMultiSampleFound ) + fCurRanking += fMultiSampleWeight; + + //--------------------- + // Swap effect + //--------------------- + // No caps for swap effects + + //--------------------- + // Depth stencil + //--------------------- + // No caps for swap effects + + //--------------------- + // Present flags + //--------------------- + // No caps for the present flags + + //--------------------- + // Refresh rate + //--------------------- + bool bRefreshFound = false; + for( int idm = 0; pDeviceSettingsCombo->pOutputInfo != NULL && idm < pDeviceSettingsCombo->pOutputInfo->displayModeList.GetSize(); idm++ ) + { + DXGI_MODE_DESC displayMode = pDeviceSettingsCombo->pOutputInfo->displayModeList.GetAt( idm ); + if( fabs( float( displayMode.RefreshRate.Numerator ) / displayMode.RefreshRate.Denominator - + float( pOptimalDeviceSettings->sd.BufferDesc.RefreshRate.Numerator ) / + pOptimalDeviceSettings->sd.BufferDesc.RefreshRate.Denominator ) < 0.1f ) + bRefreshFound = true; + } + if( bRefreshFound ) + fCurRanking += fRefreshRateWeight; + + //--------------------- + // Present interval + //--------------------- + // No caps for the present flags + + return fCurRanking; +} + + +//-------------------------------------------------------------------------------------- +// Returns the DXGI_MODE_DESC struct for a given adapter and output +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTGetD3D11AdapterDisplayMode( UINT AdapterOrdinal, UINT nOutput, DXGI_MODE_DESC* pModeDesc ) +{ + if( !pModeDesc ) + return E_INVALIDARG; + + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + CD3D11EnumOutputInfo* pOutputInfo = pD3DEnum->GetOutputInfo( AdapterOrdinal, nOutput ); + if( pOutputInfo ) + { + pModeDesc->Width = 640; + pModeDesc->Height = 480; + pModeDesc->RefreshRate.Numerator = 60; + pModeDesc->RefreshRate.Denominator = 1; + pModeDesc->Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + pModeDesc->Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + pModeDesc->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + + DXGI_OUTPUT_DESC Desc; + pOutputInfo->m_pOutput->GetDesc( &Desc ); + pModeDesc->Width = Desc.DesktopCoordinates.right - Desc.DesktopCoordinates.left; + pModeDesc->Height = Desc.DesktopCoordinates.bottom - Desc.DesktopCoordinates.top; + } + + // TODO: verify this is needed + if( pModeDesc->Format == DXGI_FORMAT_B8G8R8A8_UNORM ) + pModeDesc->Format = DXGI_FORMAT_R8G8B8A8_UNORM; + + return S_OK; +} diff --git a/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.h b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.h new file mode 100644 index 0000000..c15c571 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice11.h @@ -0,0 +1,210 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTDevice11.h +// +// Enumerates D3D adapters, devices, modes, etc. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_DEVICE11_H +#define DXUT_DEVICE11_H + +void DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings); + +//-------------------------------------------------------------------------------------- +// Functions to get bit depth from formats +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTGetD3D11AdapterDisplayMode( UINT AdapterOrdinal, UINT Output, DXGI_MODE_DESC* pModeDesc ); + + + + +//-------------------------------------------------------------------------------------- +// Optional memory create/destory functions. If not call, these will be called automatically +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateD3D11Enumeration(); +void WINAPI DXUTDestroyD3D11Enumeration(); + + + + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- +class CD3D11EnumAdapterInfo; +class CD3D11EnumDeviceInfo; +class CD3D11EnumOutputInfo; +struct CD3D11EnumDeviceSettingsCombo; + + + +//-------------------------------------------------------------------------------------- +// Enumerates available Direct3D10 adapters, devices, modes, etc. +// Use DXUTGetD3D9Enumeration() to access global instance +//-------------------------------------------------------------------------------------- +class CD3D11Enumeration +{ +public: + // These should be called before Enumerate(). + // + // Use these calls and the IsDeviceAcceptable to control the contents of + // the enumeration object, which affects the device selection and the device settings dialog. + void SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight, UINT nMaxWidth, UINT nMaxHeight ); + void SetRefreshMinMax( UINT nMin, UINT nMax ); + void SetForceFeatureLevel( D3D_FEATURE_LEVEL forceFL) { + g_forceFL = forceFL; + }; + void SetMultisampleQualityMax( UINT nMax ); + CGrowableArray* GetPossibleDepthStencilFormatList(); + void ResetPossibleDepthStencilFormats(); + void SetEnumerateAllAdapterFormats( bool bEnumerateAllAdapterFormats ); + + // Call Enumerate() to enumerate available D3D11 adapters, devices, modes, etc. + bool HasEnumerated() { return m_bHasEnumerated; } + HRESULT Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc, + void* pIsD3D11DeviceAcceptableFuncUserContext ); + + // These should be called after Enumerate() is called + CGrowableArray* GetAdapterInfoList(); + CD3D11EnumAdapterInfo* GetAdapterInfo( UINT AdapterOrdinal ); + CD3D11EnumDeviceInfo* GetDeviceInfo( UINT AdapterOrdinal, D3D_DRIVER_TYPE DeviceType ); + CD3D11EnumOutputInfo* GetOutputInfo( UINT AdapterOrdinal, UINT Output ); + CD3D11EnumDeviceSettingsCombo* GetDeviceSettingsCombo( DXUTD3D11DeviceSettings* pDeviceSettings ) { return GetDeviceSettingsCombo( pDeviceSettings->AdapterOrdinal, pDeviceSettings->DriverType, pDeviceSettings->Output, pDeviceSettings->sd.BufferDesc.Format, pDeviceSettings->sd.Windowed ); } + CD3D11EnumDeviceSettingsCombo* GetDeviceSettingsCombo( UINT AdapterOrdinal, D3D_DRIVER_TYPE DeviceType, UINT Output, DXGI_FORMAT BackBufferFormat, BOOL Windowed ); + + ~CD3D11Enumeration(); + +private: + friend HRESULT WINAPI DXUTCreateD3D11Enumeration(); + + // Use DXUTGetD3D11Enumeration() to access global instance + CD3D11Enumeration(); + + bool m_bHasEnumerated; + LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE m_IsD3D11DeviceAcceptableFunc; + void* m_pIsD3D11DeviceAcceptableFuncUserContext; + + CGrowableArray m_DepthStencilPossibleList; + + UINT m_nMinWidth; + UINT m_nMaxWidth; + UINT m_nMinHeight; + UINT m_nMaxHeight; + UINT m_nRefreshMin; + UINT m_nRefreshMax; + UINT m_nMultisampleQualityMax; + bool m_bEnumerateAllAdapterFormats; + D3D_FEATURE_LEVEL g_forceFL; + + // Array of CD3D9EnumAdapterInfo* with unique AdapterOrdinals + CGrowableArray m_AdapterInfoList; + + HRESULT EnumerateOutputs( CD3D11EnumAdapterInfo *pAdapterInfo ); + HRESULT EnumerateDevices( CD3D11EnumAdapterInfo *pAdapterInfo ); + HRESULT EnumerateDeviceCombos( IDXGIFactory1 *pFactory, CD3D11EnumAdapterInfo* pAdapterInfo ); + HRESULT EnumerateDeviceCombosNoAdapter( CD3D11EnumAdapterInfo* pAdapterInfo ); + + HRESULT EnumerateDisplayModes( CD3D11EnumOutputInfo *pOutputInfo ); + void BuildMultiSampleQualityList( DXGI_FORMAT fmt, CD3D11EnumDeviceSettingsCombo* pDeviceCombo ); + void ClearAdapterInfoList(); +}; + +CD3D11Enumeration* WINAPI DXUTGetD3D11Enumeration(bool bForceEnumerate = false, bool EnumerateAllAdapterFormats = false, D3D_FEATURE_LEVEL forceFL = ((D3D_FEATURE_LEVEL )0) ); + + +#define DXGI_MAX_DEVICE_IDENTIFIER_STRING 128 + +//-------------------------------------------------------------------------------------- +// A class describing an adapter which contains a unique adapter ordinal +// that is installed on the system +//-------------------------------------------------------------------------------------- +class CD3D11EnumAdapterInfo +{ + const CD3D11EnumAdapterInfo &operator = ( const CD3D11EnumAdapterInfo &rhs ); + +public: + ~CD3D11EnumAdapterInfo(); + + UINT AdapterOrdinal; + DXGI_ADAPTER_DESC AdapterDesc; + WCHAR szUniqueDescription[DXGI_MAX_DEVICE_IDENTIFIER_STRING]; + IDXGIAdapter *m_pAdapter; + bool bAdapterUnavailable; + + CGrowableArray outputInfoList; // Array of CD3D11EnumOutputInfo* + CGrowableArray deviceInfoList; // Array of CD3D11EnumDeviceInfo* + // List of CD3D11EnumDeviceSettingsCombo* with a unique set + // of BackBufferFormat, and Windowed + CGrowableArray deviceSettingsComboList; +}; + + +class CD3D11EnumOutputInfo +{ + const CD3D11EnumOutputInfo &operator = ( const CD3D11EnumOutputInfo &rhs ); + +public: + ~CD3D11EnumOutputInfo(); + + UINT AdapterOrdinal; + UINT Output; + IDXGIOutput* m_pOutput; + DXGI_OUTPUT_DESC Desc; + + CGrowableArray displayModeList; // Array of supported D3DDISPLAYMODEs +}; + + +//-------------------------------------------------------------------------------------- +// A class describing a Direct3D10 device that contains a +// unique supported driver type +//-------------------------------------------------------------------------------------- +class CD3D11EnumDeviceInfo +{ + const CD3D11EnumDeviceInfo& operator =( const CD3D11EnumDeviceInfo& rhs ); + +public: + ~CD3D11EnumDeviceInfo(); + + UINT AdapterOrdinal; + D3D_DRIVER_TYPE DeviceType; + D3D_FEATURE_LEVEL SelectedLevel; + D3D_FEATURE_LEVEL MaxLevel; + BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; +}; + + +//-------------------------------------------------------------------------------------- +// A struct describing device settings that contains a unique combination of +// adapter format, back buffer format, and windowed that is compatible with a +// particular Direct3D device and the app. +//-------------------------------------------------------------------------------------- +struct CD3D11EnumDeviceSettingsCombo +{ + UINT AdapterOrdinal; + D3D_DRIVER_TYPE DeviceType; + DXGI_FORMAT BackBufferFormat; + BOOL Windowed; + UINT Output; + + CGrowableArray multiSampleCountList; // List of valid sampling counts (multisampling) + CGrowableArray multiSampleQualityList; // List of number of quality levels for each multisample count + + CD3D11EnumAdapterInfo* pAdapterInfo; + CD3D11EnumDeviceInfo* pDeviceInfo; + CD3D11EnumOutputInfo* pOutputInfo; +}; + +float DXUTRankD3D11DeviceCombo( CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo, + DXUTD3D11DeviceSettings* pOptimalDeviceSettings, + DXGI_MODE_DESC* pAdapterDisplayMode, + int &bestModeIndex, + int &bestMSAAIndex + ); + + + + +#endif + + diff --git a/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.cpp b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.cpp new file mode 100644 index 0000000..a1d12e3 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.cpp @@ -0,0 +1,1177 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTDevice9.cpp +// +// Enumerates D3D adapters, devices, modes, etc. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#undef min // use __min instead +#undef max // use __max instead + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- +extern void DXUTGetCallbackD3D9DeviceAcceptable( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE* ppCallbackIsDeviceAcceptable, void** ppUserContext ); + + + + +static int __cdecl SortModesCallback( const void* arg1, const void* arg2 ); + + +CD3D9Enumeration* g_pDXUTD3D9Enumeration = NULL; + +HRESULT WINAPI DXUTCreateD3D9Enumeration() +{ + if( g_pDXUTD3D9Enumeration == NULL ) + { + g_pDXUTD3D9Enumeration = new CD3D9Enumeration(); + if( NULL == g_pDXUTD3D9Enumeration ) + return E_OUTOFMEMORY; + } + return S_OK; +} + +void WINAPI DXUTDestroyD3D9Enumeration() +{ + SAFE_DELETE( g_pDXUTD3D9Enumeration ); +} + +class DXUTMemoryHelperD3D9Enum +{ +public: +DXUTMemoryHelperD3D9Enum() +{ + DXUTCreateD3D9Enumeration(); +} +~DXUTMemoryHelperD3D9Enum() +{ + DXUTDestroyD3D9Enumeration(); +} +}; + +//-------------------------------------------------------------------------------------- +CD3D9Enumeration* WINAPI DXUTGetD3D9Enumeration( bool bForceEnumerate ) +{ + // Using an static class with accessor function to allow control of the construction order + static DXUTMemoryHelperD3D9Enum d3d9enumMemory; + + if( g_pDXUTD3D9Enumeration && ( !g_pDXUTD3D9Enumeration->HasEnumerated() || bForceEnumerate ) ) + { + LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE pCallbackIsDeviceAcceptable; + void* pUserContext; + DXUTGetCallbackD3D9DeviceAcceptable( &pCallbackIsDeviceAcceptable, &pUserContext ); + g_pDXUTD3D9Enumeration->Enumerate( pCallbackIsDeviceAcceptable, pUserContext ); + } + + return g_pDXUTD3D9Enumeration; +} + + +//-------------------------------------------------------------------------------------- +CD3D9Enumeration::CD3D9Enumeration() +{ + m_bHasEnumerated = false; + m_pD3D = NULL; + m_IsD3D9DeviceAcceptableFunc = NULL; + m_pIsD3D9DeviceAcceptableFuncUserContext = NULL; + m_bRequirePostPixelShaderBlending = true; + + m_nMinWidth = 640; + m_nMinHeight = 480; + m_nMaxWidth = UINT_MAX; + m_nMaxHeight = UINT_MAX; + + m_nRefreshMin = 0; + m_nRefreshMax = UINT_MAX; + + m_nMultisampleQualityMax = 0xFFFF; + + ResetPossibleDepthStencilFormats(); + ResetPossibleMultisampleTypeList(); + ResetPossiblePresentIntervalList(); + SetPossibleVertexProcessingList( true, true, true, false ); +} + + +//-------------------------------------------------------------------------------------- +CD3D9Enumeration::~CD3D9Enumeration() +{ + ClearAdapterInfoList(); +} + + + +//-------------------------------------------------------------------------------------- +// Enumerate for each adapter all of the supported display modes, +// device types, adapter formats, back buffer formats, window/full screen support, +// depth stencil formats, multisampling types/qualities, and presentations intervals. +// +// For each combination of device type (HAL/REF), adapter format, back buffer format, and +// IsWindowed it will call the app's ConfirmDevice callback. This allows the app +// to reject or allow that combination based on its caps/etc. It also allows the +// app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP +// if supported otherwise it will default to SWVP, however the app can change this +// through the ConfirmDevice callback. +//-------------------------------------------------------------------------------------- +HRESULT CD3D9Enumeration::Enumerate( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE IsD3D9DeviceAcceptableFunc, + void* pIsD3D9DeviceAcceptableFuncUserContext ) +{ + CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D9 Enumeration" ); + IDirect3D9* pD3D = DXUTGetD3D9Object(); + if( pD3D == NULL ) + { + pD3D = DXUTGetD3D9Object(); + if( pD3D == NULL ) + return DXUTERR_NODIRECT3D; + } + + m_bHasEnumerated = true; + m_pD3D = pD3D; + m_IsD3D9DeviceAcceptableFunc = IsD3D9DeviceAcceptableFunc; + m_pIsD3D9DeviceAcceptableFuncUserContext = pIsD3D9DeviceAcceptableFuncUserContext; + + HRESULT hr; + ClearAdapterInfoList(); + CGrowableArray adapterFormatList; + + const D3DFORMAT allowedAdapterFormatArray[] = + { + D3DFMT_X8R8G8B8, + D3DFMT_X1R5G5B5, + D3DFMT_R5G6B5, + D3DFMT_A2R10G10B10 + }; + const UINT allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof + ( allowedAdapterFormatArray[0] ); + + UINT numAdapters = pD3D->GetAdapterCount(); + for( UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++ ) + { + CD3D9EnumAdapterInfo* pAdapterInfo = new CD3D9EnumAdapterInfo; + if( pAdapterInfo == NULL ) + return E_OUTOFMEMORY; + + pAdapterInfo->AdapterOrdinal = adapterOrdinal; + pD3D->GetAdapterIdentifier( adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier ); + + // Get list of all display modes on this adapter. + // Also build a temporary list of all display adapter formats. + adapterFormatList.RemoveAll(); + + for( UINT iFormatList = 0; iFormatList < allowedAdapterFormatArrayCount; iFormatList++ ) + { + D3DFORMAT allowedAdapterFormat = allowedAdapterFormatArray[iFormatList]; + UINT numAdapterModes = pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat ); + for( UINT mode = 0; mode < numAdapterModes; mode++ ) + { + D3DDISPLAYMODE displayMode; + pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode ); + + if( displayMode.Width < m_nMinWidth || + displayMode.Height < m_nMinHeight || + displayMode.Width > m_nMaxWidth || + displayMode.Height > m_nMaxHeight || + displayMode.RefreshRate < m_nRefreshMin || + displayMode.RefreshRate > m_nRefreshMax ) + { + continue; + } + + pAdapterInfo->displayModeList.Add( displayMode ); + + if( !adapterFormatList.Contains( displayMode.Format ) ) + adapterFormatList.Add( displayMode.Format ); + } + + } + + D3DDISPLAYMODE displayMode; + pD3D->GetAdapterDisplayMode( adapterOrdinal, &displayMode ); + if( !adapterFormatList.Contains( displayMode.Format ) ) + adapterFormatList.Add( displayMode.Format ); + + // Sort displaymode list + qsort( pAdapterInfo->displayModeList.GetData(), + pAdapterInfo->displayModeList.GetSize(), sizeof( D3DDISPLAYMODE ), + SortModesCallback ); + + // Get info for each device on this adapter + if( FAILED( EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) ) + { + delete pAdapterInfo; + continue; + } + + // If at least one device on this adapter is available and compatible + // with the app, add the adapterInfo to the list + if( pAdapterInfo->deviceInfoList.GetSize() > 0 ) + { + hr = m_AdapterInfoList.Add( pAdapterInfo ); + if( FAILED( hr ) ) + return hr; + } + else + delete pAdapterInfo; + } + + // + // Check for 2 or more adapters with the same name. Append the name + // with some instance number if that's the case to help distinguish + // them. + // + bool bUniqueDesc = true; + CD3D9EnumAdapterInfo* pAdapterInfo; + for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) + { + CD3D9EnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt( i ); + + for( int j = i + 1; j < m_AdapterInfoList.GetSize(); j++ ) + { + CD3D9EnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt( j ); + if( _stricmp( pAdapterInfo1->AdapterIdentifier.Description, + pAdapterInfo2->AdapterIdentifier.Description ) == 0 ) + { + bUniqueDesc = false; + break; + } + } + + if( !bUniqueDesc ) + break; + } + + for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) + { + pAdapterInfo = m_AdapterInfoList.GetAt( i ); + + MultiByteToWideChar( CP_ACP, 0, + pAdapterInfo->AdapterIdentifier.Description, -1, + pAdapterInfo->szUniqueDescription, 100 ); + pAdapterInfo->szUniqueDescription[100] = 0; + + if( !bUniqueDesc ) + { + WCHAR sz[100]; + swprintf_s( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal ); + wcscat_s( pAdapterInfo->szUniqueDescription, 256, sz ); + + } + } + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +// Enumerates D3D devices for a particular adapter. +//-------------------------------------------------------------------------------------- +HRESULT CD3D9Enumeration::EnumerateDevices( CD3D9EnumAdapterInfo* pAdapterInfo, + CGrowableArray * pAdapterFormatList ) +{ + HRESULT hr; + + const D3DDEVTYPE devTypeArray[] = + { + D3DDEVTYPE_HAL, + D3DDEVTYPE_SW, + D3DDEVTYPE_REF + }; + const UINT devTypeArrayCount = sizeof( devTypeArray ) / sizeof( devTypeArray[0] ); + + // Enumerate each Direct3D device type + for( UINT iDeviceType = 0; iDeviceType < devTypeArrayCount; iDeviceType++ ) + { + CD3D9EnumDeviceInfo* pDeviceInfo = new CD3D9EnumDeviceInfo; + if( pDeviceInfo == NULL ) + return E_OUTOFMEMORY; + + // Fill struct w/ AdapterOrdinal and D3DDEVTYPE + pDeviceInfo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal; + pDeviceInfo->DeviceType = devTypeArray[iDeviceType]; + + // Store device caps + if( FAILED( hr = m_pD3D->GetDeviceCaps( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, + &pDeviceInfo->Caps ) ) ) + { + delete pDeviceInfo; + continue; + } + + if( pDeviceInfo->DeviceType != D3DDEVTYPE_HAL ) + { + // Create a temp device to verify that it is really possible to create a REF device + // [the developer DirectX redist has to be installed] + D3DDISPLAYMODE Mode; + m_pD3D->GetAdapterDisplayMode( 0, &Mode ); + D3DPRESENT_PARAMETERS pp; + ZeroMemory( &pp, sizeof( D3DPRESENT_PARAMETERS ) ); + pp.BackBufferWidth = 1; + pp.BackBufferHeight = 1; + pp.BackBufferFormat = Mode.Format; + pp.BackBufferCount = 1; + pp.SwapEffect = D3DSWAPEFFECT_COPY; + pp.Windowed = TRUE; + pp.hDeviceWindow = DXUTGetHWNDFocus(); + IDirect3DDevice9* pDevice = NULL; + if( FAILED( hr = m_pD3D->CreateDevice( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, + DXUTGetHWNDFocus(), + D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &pp, + &pDevice ) ) ) + { + delete pDeviceInfo; + continue; + } + SAFE_RELEASE( pDevice ); + } + + // Get info for each devicecombo on this device + if( FAILED( hr = EnumerateDeviceCombos( pAdapterInfo, pDeviceInfo, pAdapterFormatList ) ) ) + { + delete pDeviceInfo; + continue; + } + + // If at least one devicecombo for this device is found, + // add the deviceInfo to the list + if( pDeviceInfo->deviceSettingsComboList.GetSize() > 0 ) + pAdapterInfo->deviceInfoList.Add( pDeviceInfo ); + else + delete pDeviceInfo; + } + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +// Enumerates DeviceCombos for a particular device. +//-------------------------------------------------------------------------------------- +HRESULT CD3D9Enumeration::EnumerateDeviceCombos( CD3D9EnumAdapterInfo* pAdapterInfo, CD3D9EnumDeviceInfo* pDeviceInfo, + CGrowableArray * pAdapterFormatList ) +{ + const D3DFORMAT backBufferFormatArray[] = + { + D3DFMT_A8R8G8B8, + D3DFMT_X8R8G8B8, + D3DFMT_A2R10G10B10, + D3DFMT_R5G6B5, + D3DFMT_A1R5G5B5, + D3DFMT_X1R5G5B5 + }; + const UINT backBufferFormatArrayCount = sizeof( backBufferFormatArray ) / sizeof( backBufferFormatArray[0] ); + + // See which adapter formats are supported by this device + for( int iFormat = 0; iFormat < pAdapterFormatList->GetSize(); iFormat++ ) + { + D3DFORMAT adapterFormat = pAdapterFormatList->GetAt( iFormat ); + + for( UINT iBackBufferFormat = 0; iBackBufferFormat < backBufferFormatArrayCount; iBackBufferFormat++ ) + { + D3DFORMAT backBufferFormat = backBufferFormatArray[iBackBufferFormat]; + + for( int nWindowed = 0; nWindowed < 2; nWindowed++ ) + { + if( !nWindowed && pAdapterInfo->displayModeList.GetSize() == 0 ) + continue; + + if( FAILED( m_pD3D->CheckDeviceType( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, + adapterFormat, backBufferFormat, nWindowed ) ) ) + { + continue; + } + + if( m_bRequirePostPixelShaderBlending ) + { + // If the backbuffer format doesn't support D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING + // then alpha test, pixel fog, render-target blending, color write enable, and dithering. + // are not supported. + if( FAILED( m_pD3D->CheckDeviceFormat( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, + adapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, + D3DRTYPE_TEXTURE, backBufferFormat ) ) ) + { + continue; + } + } + + // If an application callback function has been provided, make sure this device + // is acceptable to the app. + if( m_IsD3D9DeviceAcceptableFunc != NULL ) + { + if( !m_IsD3D9DeviceAcceptableFunc( &pDeviceInfo->Caps, adapterFormat, backBufferFormat, + FALSE != nWindowed, m_pIsD3D9DeviceAcceptableFuncUserContext ) ) + continue; + } + + // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed + // DeviceCombo that is supported by the system and acceptable to the app. We still + // need to find one or more suitable depth/stencil buffer format, + // multisample type, and present interval. + CD3D9EnumDeviceSettingsCombo* pDeviceCombo = new CD3D9EnumDeviceSettingsCombo; + if( pDeviceCombo == NULL ) + return E_OUTOFMEMORY; + + pDeviceCombo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal; + pDeviceCombo->DeviceType = pDeviceInfo->DeviceType; + pDeviceCombo->AdapterFormat = adapterFormat; + pDeviceCombo->BackBufferFormat = backBufferFormat; + pDeviceCombo->Windowed = ( nWindowed != 0 ); + + BuildDepthStencilFormatList( pDeviceCombo ); + BuildMultiSampleTypeList( pDeviceCombo ); + if( pDeviceCombo->multiSampleTypeList.GetSize() == 0 ) + { + delete pDeviceCombo; + continue; + } + BuildDSMSConflictList( pDeviceCombo ); + BuildPresentIntervalList( pDeviceInfo, pDeviceCombo ); + pDeviceCombo->pAdapterInfo = pAdapterInfo; + pDeviceCombo->pDeviceInfo = pDeviceInfo; + + if( FAILED( pDeviceInfo->deviceSettingsComboList.Add( pDeviceCombo ) ) ) + delete pDeviceCombo; + } + } + } + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +// Adds all depth/stencil formats that are compatible with the device +// and app to the given D3DDeviceCombo. +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::BuildDepthStencilFormatList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo ) +{ + D3DFORMAT depthStencilFmt; + for( int idsf = 0; idsf < m_DepthStencilPossibleList.GetSize(); idsf++ ) + { + depthStencilFmt = m_DepthStencilPossibleList.GetAt( idsf ); + if( SUCCEEDED( m_pD3D->CheckDeviceFormat( pDeviceCombo->AdapterOrdinal, + pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat, + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFmt ) ) ) + { + if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( pDeviceCombo->AdapterOrdinal, + pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat, + pDeviceCombo->BackBufferFormat, depthStencilFmt ) ) ) + { + pDeviceCombo->depthStencilFormatList.Add( depthStencilFmt ); + } + } + } +} + + + + +//-------------------------------------------------------------------------------------- +// Adds all multisample types that are compatible with the device and app to +// the given D3DDeviceCombo. +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::BuildMultiSampleTypeList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo ) +{ + D3DMULTISAMPLE_TYPE msType; + DWORD msQuality; + for( int imst = 0; imst < m_MultiSampleTypeList.GetSize(); imst++ ) + { + msType = m_MultiSampleTypeList.GetAt( imst ); + if( SUCCEEDED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, + pDeviceCombo->DeviceType, pDeviceCombo->BackBufferFormat, + pDeviceCombo->Windowed, msType, &msQuality ) ) ) + { + pDeviceCombo->multiSampleTypeList.Add( msType ); + if( msQuality > m_nMultisampleQualityMax + 1 ) + msQuality = m_nMultisampleQualityMax + 1; + pDeviceCombo->multiSampleQualityList.Add( msQuality ); + } + } +} + + + + +//-------------------------------------------------------------------------------------- +// Find any conflicts between the available depth/stencil formats and +// multisample types. +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::BuildDSMSConflictList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo ) +{ + CD3D9EnumDSMSConflict DSMSConflict; + + for( int iDS = 0; iDS < pDeviceCombo->depthStencilFormatList.GetSize(); iDS++ ) + { + D3DFORMAT dsFmt = pDeviceCombo->depthStencilFormatList.GetAt( iDS ); + + for( int iMS = 0; iMS < pDeviceCombo->multiSampleTypeList.GetSize(); iMS++ ) + { + D3DMULTISAMPLE_TYPE msType = pDeviceCombo->multiSampleTypeList.GetAt( iMS ); + + if( FAILED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, pDeviceCombo->DeviceType, + dsFmt, pDeviceCombo->Windowed, msType, NULL ) ) ) + { + DSMSConflict.DSFormat = dsFmt; + DSMSConflict.MSType = msType; + pDeviceCombo->DSMSConflictList.Add( DSMSConflict ); + } + } + } +} + + +//-------------------------------------------------------------------------------------- +// Adds all present intervals that are compatible with the device and app +// to the given D3DDeviceCombo. +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::BuildPresentIntervalList( CD3D9EnumDeviceInfo* pDeviceInfo, + CD3D9EnumDeviceSettingsCombo* pDeviceCombo ) +{ + UINT pi; + for( int ipi = 0; ipi < m_PresentIntervalList.GetSize(); ipi++ ) + { + pi = m_PresentIntervalList.GetAt( ipi ); + if( pDeviceCombo->Windowed ) + { + if( pi == D3DPRESENT_INTERVAL_TWO || + pi == D3DPRESENT_INTERVAL_THREE || + pi == D3DPRESENT_INTERVAL_FOUR ) + { + // These intervals are not supported in windowed mode. + continue; + } + } + // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you + // can't do a caps check for it -- it is always available. + if( pi == D3DPRESENT_INTERVAL_DEFAULT || + ( pDeviceInfo->Caps.PresentationIntervals & pi ) ) + { + pDeviceCombo->presentIntervalList.Add( pi ); + } + } +} + + + +//-------------------------------------------------------------------------------------- +// Release all the allocated CD3D9EnumAdapterInfo objects and empty the list +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::ClearAdapterInfoList() +{ + CD3D9EnumAdapterInfo* pAdapterInfo; + for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) + { + pAdapterInfo = m_AdapterInfoList.GetAt( i ); + delete pAdapterInfo; + } + + m_AdapterInfoList.RemoveAll(); +} + + + +//-------------------------------------------------------------------------------------- +// Call GetAdapterInfoList() after Enumerate() to get a STL vector of +// CD3D9EnumAdapterInfo* +//-------------------------------------------------------------------------------------- +CGrowableArray * CD3D9Enumeration::GetAdapterInfoList() +{ + return &m_AdapterInfoList; +} + + + +//-------------------------------------------------------------------------------------- +CD3D9EnumAdapterInfo* CD3D9Enumeration::GetAdapterInfo( UINT AdapterOrdinal ) +{ + for( int iAdapter = 0; iAdapter < m_AdapterInfoList.GetSize(); iAdapter++ ) + { + CD3D9EnumAdapterInfo* pAdapterInfo = m_AdapterInfoList.GetAt( iAdapter ); + if( pAdapterInfo->AdapterOrdinal == AdapterOrdinal ) + return pAdapterInfo; + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +CD3D9EnumDeviceInfo* CD3D9Enumeration::GetDeviceInfo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType ) +{ + CD3D9EnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal ); + if( pAdapterInfo ) + { + for( int iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ ) + { + CD3D9EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( iDeviceInfo ); + if( pDeviceInfo->DeviceType == DeviceType ) + return pDeviceInfo; + } + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------- +CD3D9EnumDeviceSettingsCombo* CD3D9Enumeration::GetDeviceSettingsCombo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, + D3DFORMAT AdapterFormat, + D3DFORMAT BackBufferFormat, BOOL bWindowed ) +{ + CD3D9EnumDeviceInfo* pDeviceInfo = GetDeviceInfo( AdapterOrdinal, DeviceType ); + if( pDeviceInfo ) + { + for( int iDeviceCombo = 0; iDeviceCombo < pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ ) + { + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt( + iDeviceCombo ); + if( pDeviceSettingsCombo->AdapterFormat == AdapterFormat && + pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat && + pDeviceSettingsCombo->Windowed == bWindowed ) + return pDeviceSettingsCombo; + } + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +// Returns the number of color channel bits in the specified D3DFORMAT +//-------------------------------------------------------------------------------------- +UINT WINAPI DXUTGetD3D9ColorChannelBits( D3DFORMAT fmt ) +{ + switch( fmt ) + { + case D3DFMT_R8G8B8: + return 8; + case D3DFMT_A8R8G8B8: + return 8; + case D3DFMT_X8R8G8B8: + return 8; + case D3DFMT_R5G6B5: + return 5; + case D3DFMT_X1R5G5B5: + return 5; + case D3DFMT_A1R5G5B5: + return 5; + case D3DFMT_A4R4G4B4: + return 4; + case D3DFMT_R3G3B2: + return 2; + case D3DFMT_A8R3G3B2: + return 2; + case D3DFMT_X4R4G4B4: + return 4; + case D3DFMT_A2B10G10R10: + return 10; + case D3DFMT_A8B8G8R8: + return 8; + case D3DFMT_A2R10G10B10: + return 10; + case D3DFMT_A16B16G16R16: + return 16; + default: + return 0; + } +} + + +//-------------------------------------------------------------------------------------- +// Returns the number of alpha channel bits in the specified D3DFORMAT +//-------------------------------------------------------------------------------------- +UINT WINAPI DXUTGetAlphaChannelBits( D3DFORMAT fmt ) +{ + switch( fmt ) + { + case D3DFMT_R8G8B8: + return 0; + case D3DFMT_A8R8G8B8: + return 8; + case D3DFMT_X8R8G8B8: + return 0; + case D3DFMT_R5G6B5: + return 0; + case D3DFMT_X1R5G5B5: + return 0; + case D3DFMT_A1R5G5B5: + return 1; + case D3DFMT_A4R4G4B4: + return 4; + case D3DFMT_R3G3B2: + return 0; + case D3DFMT_A8R3G3B2: + return 8; + case D3DFMT_X4R4G4B4: + return 0; + case D3DFMT_A2B10G10R10: + return 2; + case D3DFMT_A8B8G8R8: + return 8; + case D3DFMT_A2R10G10B10: + return 2; + case D3DFMT_A16B16G16R16: + return 16; + default: + return 0; + } +} + + +//-------------------------------------------------------------------------------------- +// Returns the number of depth bits in the specified D3DFORMAT +//-------------------------------------------------------------------------------------- +UINT WINAPI DXUTGetDepthBits( D3DFORMAT fmt ) +{ + switch( fmt ) + { + case D3DFMT_D32F_LOCKABLE: + case D3DFMT_D32: + return 32; + + case D3DFMT_D24X8: + case D3DFMT_D24S8: + case D3DFMT_D24X4S4: + case D3DFMT_D24FS8: + return 24; + + case D3DFMT_D16_LOCKABLE: + case D3DFMT_D16: + return 16; + + case D3DFMT_D15S1: + return 15; + + default: + return 0; + } +} + + + + +//-------------------------------------------------------------------------------------- +// Returns the number of stencil bits in the specified D3DFORMAT +//-------------------------------------------------------------------------------------- +UINT WINAPI DXUTGetStencilBits( D3DFORMAT fmt ) +{ + switch( fmt ) + { + case D3DFMT_D16_LOCKABLE: + case D3DFMT_D16: + case D3DFMT_D32F_LOCKABLE: + case D3DFMT_D32: + case D3DFMT_D24X8: + return 0; + + case D3DFMT_D15S1: + return 1; + + case D3DFMT_D24X4S4: + return 4; + + case D3DFMT_D24S8: + case D3DFMT_D24FS8: + return 8; + + default: + return 0; + } +} + + + +//-------------------------------------------------------------------------------------- +// Used to sort D3DDISPLAYMODEs +//-------------------------------------------------------------------------------------- +static int __cdecl SortModesCallback( const void* arg1, const void* arg2 ) +{ + D3DDISPLAYMODE* pdm1 = ( D3DDISPLAYMODE* )arg1; + D3DDISPLAYMODE* pdm2 = ( D3DDISPLAYMODE* )arg2; + + if( pdm1->Width > pdm2->Width ) + return 1; + if( pdm1->Width < pdm2->Width ) + return -1; + if( pdm1->Height > pdm2->Height ) + return 1; + if( pdm1->Height < pdm2->Height ) + return -1; + if( pdm1->Format > pdm2->Format ) + return 1; + if( pdm1->Format < pdm2->Format ) + return -1; + if( pdm1->RefreshRate > pdm2->RefreshRate ) + return 1; + if( pdm1->RefreshRate < pdm2->RefreshRate ) + return -1; + return 0; +} + + + +//-------------------------------------------------------------------------------------- +CD3D9EnumAdapterInfo::~CD3D9EnumAdapterInfo( void ) +{ + CD3D9EnumDeviceInfo* pDeviceInfo; + for( int i = 0; i < deviceInfoList.GetSize(); i++ ) + { + pDeviceInfo = deviceInfoList.GetAt( i ); + delete pDeviceInfo; + } + deviceInfoList.RemoveAll(); +} + + + + +//-------------------------------------------------------------------------------------- +CD3D9EnumDeviceInfo::~CD3D9EnumDeviceInfo( void ) +{ + CD3D9EnumDeviceSettingsCombo* pDeviceCombo; + for( int i = 0; i < deviceSettingsComboList.GetSize(); i++ ) + { + pDeviceCombo = deviceSettingsComboList.GetAt( i ); + delete pDeviceCombo; + } + deviceSettingsComboList.RemoveAll(); +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::ResetPossibleDepthStencilFormats() +{ + m_DepthStencilPossibleList.RemoveAll(); + m_DepthStencilPossibleList.Add( D3DFMT_D16 ); + m_DepthStencilPossibleList.Add( D3DFMT_D15S1 ); + m_DepthStencilPossibleList.Add( D3DFMT_D24X8 ); + m_DepthStencilPossibleList.Add( D3DFMT_D24S8 ); + m_DepthStencilPossibleList.Add( D3DFMT_D24X4S4 ); + m_DepthStencilPossibleList.Add( D3DFMT_D32 ); +} + + +//-------------------------------------------------------------------------------------- +CGrowableArray * CD3D9Enumeration::GetPossibleDepthStencilFormatList() +{ + return &m_DepthStencilPossibleList; +} + + +//-------------------------------------------------------------------------------------- +CGrowableArray * CD3D9Enumeration::GetPossibleMultisampleTypeList() +{ + return &m_MultiSampleTypeList; +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::ResetPossibleMultisampleTypeList() +{ + m_MultiSampleTypeList.RemoveAll(); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONE ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONMASKABLE ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_2_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_3_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_4_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_5_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_6_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_7_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_8_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_9_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_10_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_11_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_12_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_13_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_14_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_15_SAMPLES ); + m_MultiSampleTypeList.Add( D3DMULTISAMPLE_16_SAMPLES ); +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::GetPossibleVertexProcessingList( bool* pbSoftwareVP, bool* pbHardwareVP, bool* pbPureHarewareVP, + bool* pbMixedVP ) +{ + *pbSoftwareVP = m_bSoftwareVP; + *pbHardwareVP = m_bHardwareVP; + *pbPureHarewareVP = m_bPureHarewareVP; + *pbMixedVP = m_bMixedVP; +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::SetPossibleVertexProcessingList( bool bSoftwareVP, bool bHardwareVP, bool bPureHarewareVP, + bool bMixedVP ) +{ + m_bSoftwareVP = bSoftwareVP; + m_bHardwareVP = bHardwareVP; + m_bPureHarewareVP = bPureHarewareVP; + m_bMixedVP = bMixedVP; +} + + +//-------------------------------------------------------------------------------------- +CGrowableArray * CD3D9Enumeration::GetPossiblePresentIntervalList() +{ + return &m_PresentIntervalList; +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::ResetPossiblePresentIntervalList() +{ + m_PresentIntervalList.RemoveAll(); + m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_IMMEDIATE ); + m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_DEFAULT ); + m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_ONE ); + m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_TWO ); + m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_THREE ); + m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_FOUR ); +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight, + UINT nMaxWidth, UINT nMaxHeight ) +{ + m_nMinWidth = nMinWidth; + m_nMinHeight = nMinHeight; + m_nMaxWidth = nMaxWidth; + m_nMaxHeight = nMaxHeight; +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::SetRefreshMinMax( UINT nMin, UINT nMax ) +{ + m_nRefreshMin = nMin; + m_nRefreshMax = nMax; +} + + +//-------------------------------------------------------------------------------------- +void CD3D9Enumeration::SetMultisampleQualityMax( UINT nMax ) +{ + if( nMax > 0xFFFF ) + nMax = 0xFFFF; + m_nMultisampleQualityMax = nMax; +} + + + +//-------------------------------------------------------------------------------------- +// Returns a ranking number that describes how closely this device +// combo matches the optimal combo based on the match options and the optimal device settings +//-------------------------------------------------------------------------------------- +float DXUTRankD3D9DeviceCombo( CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo, + DXUTD3D9DeviceSettings* pOptimalDeviceSettings, + D3DDISPLAYMODE* pAdapterDesktopDisplayMode, + int &bestModeIndex, + int &bestMSAAIndex + ) +{ + float fCurRanking = 0.0f; + + // Arbitrary weights. Gives preference to the ordinal, device type, and windowed + const float fAdapterOrdinalWeight = 1000.0f; + const float fDeviceTypeWeight = 100.0f; + const float fWindowWeight = 10.0f; + const float fAdapterFormatWeight = 1.0f; + const float fVertexProcessingWeight = 1.0f; + const float fResolutionWeight = 1.0f; + const float fBackBufferFormatWeight = 1.0f; + const float fMultiSampleWeight = 1.0f; + const float fDepthStencilWeight = 1.0f; + const float fRefreshRateWeight = 1.0f; + const float fPresentIntervalWeight = 1.0f; + + //--------------------- + // Adapter ordinal + //--------------------- + if( pDeviceSettingsCombo->AdapterOrdinal == pOptimalDeviceSettings->AdapterOrdinal ) + fCurRanking += fAdapterOrdinalWeight; + + //--------------------- + // Device type + //--------------------- + if( pDeviceSettingsCombo->DeviceType == pOptimalDeviceSettings->DeviceType ) + fCurRanking += fDeviceTypeWeight; + // Slightly prefer HAL + if( pDeviceSettingsCombo->DeviceType == D3DDEVTYPE_HAL ) + fCurRanking += 0.1f; + + //--------------------- + // Windowed + //--------------------- + if( pDeviceSettingsCombo->Windowed == pOptimalDeviceSettings->pp.Windowed ) + fCurRanking += fWindowWeight; + + //--------------------- + // Adapter format + //--------------------- + if( pDeviceSettingsCombo->AdapterFormat == pOptimalDeviceSettings->AdapterFormat ) + { + fCurRanking += fAdapterFormatWeight; + } + else + { + int nBitDepthDelta = abs( ( long )DXUTGetD3D9ColorChannelBits( pDeviceSettingsCombo->AdapterFormat ) - + ( long )DXUTGetD3D9ColorChannelBits( pOptimalDeviceSettings->AdapterFormat ) ); + float fScale = __max( 0.9f - ( float )nBitDepthDelta * 0.2f, 0.0f ); + fCurRanking += fScale * fAdapterFormatWeight; + } + + if( !pDeviceSettingsCombo->Windowed ) + { + // Slightly prefer when it matches the desktop format or is D3DFMT_X8R8G8B8 + bool bAdapterOptimalMatch; + if( DXUTGetD3D9ColorChannelBits( pAdapterDesktopDisplayMode->Format ) >= 8 ) + bAdapterOptimalMatch = ( pDeviceSettingsCombo->AdapterFormat == pAdapterDesktopDisplayMode->Format ); + else + bAdapterOptimalMatch = ( pDeviceSettingsCombo->AdapterFormat == D3DFMT_X8R8G8B8 ); + + if( bAdapterOptimalMatch ) + fCurRanking += 0.1f; + } + + //--------------------- + // Vertex processing + //--------------------- + if( ( pOptimalDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING ) != 0 || + ( pOptimalDeviceSettings->BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING ) != 0 ) + { + if( ( pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) != 0 ) + fCurRanking += fVertexProcessingWeight; + } + // Slightly prefer HW T&L + if( ( pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) != 0 ) + fCurRanking += 0.1f; + + //--------------------- + // Resolution + //--------------------- + bool bResolutionFound = false; + unsigned int best = 0xffffffff; + bestModeIndex=0; + + + + + + for( int idm = 0; idm < pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); idm++ ) + { + D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( idm ); + if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat ) + continue; + if( displayMode.Width == pOptimalDeviceSettings->pp.BackBufferWidth && + displayMode.Height == pOptimalDeviceSettings->pp.BackBufferHeight ) + bResolutionFound = true; + + unsigned int current = + (UINT) abs ((int)displayMode.Width - (int)pOptimalDeviceSettings->pp.BackBufferWidth) + + (UINT) abs ((int)displayMode.Height - (int)pOptimalDeviceSettings->pp.BackBufferHeight ); + if (current < best) { + best = current; + bestModeIndex= idm; + + } + + + } + if( bResolutionFound ) + fCurRanking += fResolutionWeight; + + //--------------------- + // Back buffer format + //--------------------- + if( pDeviceSettingsCombo->BackBufferFormat == pOptimalDeviceSettings->pp.BackBufferFormat ) + { + fCurRanking += fBackBufferFormatWeight; + } + else + { + int nBitDepthDelta = abs( ( long )DXUTGetD3D9ColorChannelBits( pDeviceSettingsCombo->BackBufferFormat ) - + ( long )DXUTGetD3D9ColorChannelBits( pOptimalDeviceSettings->pp.BackBufferFormat ) ); + float fScale = __max( 0.9f - ( float )nBitDepthDelta * 0.2f, 0.0f ); + fCurRanking += fScale * fBackBufferFormatWeight; + } + + // Check if this back buffer format is the same as + // the adapter format since this is preferred. + bool bAdapterMatchesBB = ( pDeviceSettingsCombo->BackBufferFormat == pDeviceSettingsCombo->AdapterFormat ); + if( bAdapterMatchesBB ) + fCurRanking += 0.1f; + + //--------------------- + // Back buffer count + //--------------------- + // No caps for the back buffer count + + //--------------------- + // Multisample + //--------------------- + bool bMultiSampleFound = false; + for( int i = 0; i < pDeviceSettingsCombo->multiSampleTypeList.GetSize(); i++ ) + { + D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt( i ); + DWORD msQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt( i ); + + if( msType == pOptimalDeviceSettings->pp.MultiSampleType && + msQuality > pOptimalDeviceSettings->pp.MultiSampleQuality ) + { + bMultiSampleFound = true; + bestMSAAIndex = i; + break; + } + } + if( bMultiSampleFound ) + fCurRanking += fMultiSampleWeight; + + //--------------------- + // Swap effect + //--------------------- + // No caps for swap effects + + //--------------------- + // Depth stencil + //--------------------- + if( pDeviceSettingsCombo->depthStencilFormatList.Contains( pOptimalDeviceSettings->pp.AutoDepthStencilFormat ) ) + fCurRanking += fDepthStencilWeight; + + //--------------------- + // Present flags + //--------------------- + // No caps for the present flags + + //--------------------- + // Refresh rate + //--------------------- + bool bRefreshFound = false; + for( int idm = 0; idm < pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); idm++ ) + { + D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( idm ); + if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat ) + continue; + if( displayMode.RefreshRate == pOptimalDeviceSettings->pp.FullScreen_RefreshRateInHz ) + bRefreshFound = true; + } + if( bRefreshFound ) + fCurRanking += fRefreshRateWeight; + + //--------------------- + // Present interval + //--------------------- + // If keep present interval then check that the present interval is supported by this combo + if( pDeviceSettingsCombo->presentIntervalList.Contains( pOptimalDeviceSettings->pp.PresentationInterval ) ) + fCurRanking += fPresentIntervalWeight; + + return fCurRanking; +} + diff --git a/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.h b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.h new file mode 100644 index 0000000..c5ee6db --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/DXUTDevice9.h @@ -0,0 +1,207 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTDevice9.h +// +// Enumerates D3D adapters, devices, modes, etc. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_DEVICE9_H +#define DXUT_DEVICE9_H + +//void DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings); + +//-------------------------------------------------------------------------------------- +// Functions to get bit depth from formats +//-------------------------------------------------------------------------------------- +UINT WINAPI DXUTGetD3D9ColorChannelBits( D3DFORMAT fmt ); +UINT WINAPI DXUTGetAlphaChannelBits( D3DFORMAT fmt ); +UINT WINAPI DXUTGetStencilBits( D3DFORMAT fmt ); +UINT WINAPI DXUTGetDepthBits( D3DFORMAT fmt ); +UINT WINAPI DXUTGetDXGIColorChannelBits( DXGI_FORMAT fmt ); + + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- + +class CD3D9EnumAdapterInfo; +class CD3D9EnumDeviceInfo; +struct CD3D9EnumDeviceSettingsCombo; +struct CD3D9EnumDSMSConflict; + + + + + +//-------------------------------------------------------------------------------------- +// Optional memory create/destory functions. If not call, these will be called automatically +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateD3D9Enumeration(); +void WINAPI DXUTDestroyD3D9Enumeration(); + + + +//-------------------------------------------------------------------------------------- +// Enumerates available Direct3D9 adapters, devices, modes, etc. +// Use DXUTGetD3D9Enumeration() to access global instance +//-------------------------------------------------------------------------------------- +class CD3D9Enumeration +{ +public: + // These should be called before Enumerate(). + // + // Use these calls and the IsDeviceAcceptable to control the contents of + // the enumeration object, which affects the device selection and the device settings dialog. + void SetRequirePostPixelShaderBlending( bool bRequire ) { m_bRequirePostPixelShaderBlending = bRequire; } + void SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight, UINT nMaxWidth, UINT nMaxHeight ); + void SetRefreshMinMax( UINT nMin, UINT nMax ); + void SetMultisampleQualityMax( UINT nMax ); + void GetPossibleVertexProcessingList( bool* pbSoftwareVP, bool* pbHardwareVP, bool* pbPureHarewareVP, bool* pbMixedVP ); + void SetPossibleVertexProcessingList( bool bSoftwareVP, bool bHardwareVP, bool bPureHarewareVP, bool bMixedVP ); + CGrowableArray* GetPossibleDepthStencilFormatList(); + CGrowableArray* GetPossibleMultisampleTypeList(); + CGrowableArray* GetPossiblePresentIntervalList(); + void ResetPossibleDepthStencilFormats(); + void ResetPossibleMultisampleTypeList(); + void ResetPossiblePresentIntervalList(); + + // Call Enumerate() to enumerate available D3D adapters, devices, modes, etc. + bool HasEnumerated() { return m_bHasEnumerated; } + HRESULT Enumerate( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE IsD3D9DeviceAcceptableFunc = NULL, + void* pIsD3D9DeviceAcceptableFuncUserContext = NULL ); + + // These should be called after Enumerate() is called + CGrowableArray* GetAdapterInfoList(); + CD3D9EnumAdapterInfo* GetAdapterInfo( UINT AdapterOrdinal ); + CD3D9EnumDeviceInfo* GetDeviceInfo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType ); + CD3D9EnumDeviceSettingsCombo* GetDeviceSettingsCombo( DXUTD3D9DeviceSettings* pD3D9DeviceSettings ) { return GetDeviceSettingsCombo( pD3D9DeviceSettings->AdapterOrdinal, pD3D9DeviceSettings->DeviceType, pD3D9DeviceSettings->AdapterFormat, pD3D9DeviceSettings->pp.BackBufferFormat, pD3D9DeviceSettings->pp.Windowed ); } + CD3D9EnumDeviceSettingsCombo* GetDeviceSettingsCombo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL Windowed ); + + ~CD3D9Enumeration(); + +private: + friend HRESULT WINAPI DXUTCreateD3D9Enumeration(); + + // Use DXUTGetD3D9Enumeration() to access global instance + CD3D9Enumeration(); + + bool m_bHasEnumerated; + IDirect3D9* m_pD3D; + LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE m_IsD3D9DeviceAcceptableFunc; + void* m_pIsD3D9DeviceAcceptableFuncUserContext; + bool m_bRequirePostPixelShaderBlending; + CGrowableArray m_DepthStencilPossibleList; + CGrowableArray m_MultiSampleTypeList; + CGrowableArray m_PresentIntervalList; + + bool m_bSoftwareVP; + bool m_bHardwareVP; + bool m_bPureHarewareVP; + bool m_bMixedVP; + + UINT m_nMinWidth; + UINT m_nMaxWidth; + UINT m_nMinHeight; + UINT m_nMaxHeight; + UINT m_nRefreshMin; + UINT m_nRefreshMax; + UINT m_nMultisampleQualityMax; + + // Array of CD3D9EnumAdapterInfo* with unique AdapterOrdinals + CGrowableArray m_AdapterInfoList; + + HRESULT EnumerateDevices( CD3D9EnumAdapterInfo* pAdapterInfo, CGrowableArray* pAdapterFormatList ); + HRESULT EnumerateDeviceCombos( CD3D9EnumAdapterInfo* pAdapterInfo, CD3D9EnumDeviceInfo* pDeviceInfo, CGrowableArray* pAdapterFormatList ); + void BuildDepthStencilFormatList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo ); + void BuildMultiSampleTypeList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo ); + void BuildDSMSConflictList( CD3D9EnumDeviceSettingsCombo* pDeviceCombo ); + void BuildPresentIntervalList( CD3D9EnumDeviceInfo* pDeviceInfo, CD3D9EnumDeviceSettingsCombo* pDeviceCombo ); + void ClearAdapterInfoList(); +}; + +CD3D9Enumeration* WINAPI DXUTGetD3D9Enumeration( bool bForceEnumerate = false ); + + +//-------------------------------------------------------------------------------------- +// A class describing an adapter which contains a unique adapter ordinal +// that is installed on the system +//-------------------------------------------------------------------------------------- +class CD3D9EnumAdapterInfo +{ +public: + ~CD3D9EnumAdapterInfo(); + + UINT AdapterOrdinal; + D3DADAPTER_IDENTIFIER9 AdapterIdentifier; + WCHAR szUniqueDescription[256]; + + CGrowableArray displayModeList; // Array of supported D3DDISPLAYMODEs + CGrowableArray deviceInfoList; // Array of CD3D9EnumDeviceInfo* with unique supported DeviceTypes +}; + + +//-------------------------------------------------------------------------------------- +// A class describing a Direct3D device that contains a +// unique supported device type +//-------------------------------------------------------------------------------------- +class CD3D9EnumDeviceInfo +{ +public: + ~CD3D9EnumDeviceInfo(); + + UINT AdapterOrdinal; + D3DDEVTYPE DeviceType; + D3DCAPS9 Caps; + + // List of CD3D9EnumDeviceSettingsCombo* with a unique set + // of AdapterFormat, BackBufferFormat, and Windowed + CGrowableArray deviceSettingsComboList; +}; + + +//-------------------------------------------------------------------------------------- +// A struct describing device settings that contains a unique combination of +// adapter format, back buffer format, and windowed that is compatible with a +// particular Direct3D device and the app. +//-------------------------------------------------------------------------------------- +struct CD3D9EnumDeviceSettingsCombo +{ + UINT AdapterOrdinal; + D3DDEVTYPE DeviceType; + D3DFORMAT AdapterFormat; + D3DFORMAT BackBufferFormat; + BOOL Windowed; + + CGrowableArray depthStencilFormatList; // List of D3DFORMATs + CGrowableArray multiSampleTypeList; // List of D3DMULTISAMPLE_TYPEs + CGrowableArray multiSampleQualityList; // List of number of quality levels for each multisample type + CGrowableArray presentIntervalList; // List of D3DPRESENT flags + CGrowableArray DSMSConflictList; // List of CD3D9EnumDSMSConflict + + CD3D9EnumAdapterInfo* pAdapterInfo; + CD3D9EnumDeviceInfo* pDeviceInfo; +}; + + +//-------------------------------------------------------------------------------------- +// A depth/stencil buffer format that is incompatible with a +// multisample type. +//-------------------------------------------------------------------------------------- +struct CD3D9EnumDSMSConflict +{ + D3DFORMAT DSFormat; + D3DMULTISAMPLE_TYPE MSType; +}; + + + +float DXUTRankD3D9DeviceCombo( CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo, + DXUTD3D9DeviceSettings* pOptimalDeviceSettings, + D3DDISPLAYMODE* pAdapterDesktopDisplayMode, + int &bestModeIndex, + int &bestMSAAIndex + ); + + +#endif diff --git a/Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.cpp b/Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.cpp new file mode 100644 index 0000000..f60c5f4 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.cpp @@ -0,0 +1,1785 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTMisc.cpp +// +// Shortcut macros and functions for using DX objects +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#include "dxut.h" +#include +#define DXUT_GAMEPAD_TRIGGER_THRESHOLD 30 +#undef min // use __min instead +#undef max // use __max instead + +CDXUTTimer* WINAPI DXUTGetGlobalTimer() +{ + // Using an accessor function gives control of the construction order + static CDXUTTimer timer; + return &timer; +} + + +//-------------------------------------------------------------------------------------- +CDXUTTimer::CDXUTTimer() +{ + m_bTimerStopped = true; + m_llQPFTicksPerSec = 0; + + m_llStopTime = 0; + m_llLastElapsedTime = 0; + m_llBaseTime = 0; + + // Use QueryPerformanceFrequency to get the frequency of the counter + LARGE_INTEGER qwTicksPerSec = { 0 }; + QueryPerformanceFrequency( &qwTicksPerSec ); + m_llQPFTicksPerSec = qwTicksPerSec.QuadPart; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Reset() +{ + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + m_llBaseTime = qwTime.QuadPart; + m_llLastElapsedTime = qwTime.QuadPart; + m_llStopTime = 0; + m_bTimerStopped = FALSE; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Start() +{ + // Get the current time + LARGE_INTEGER qwTime = { 0 }; + QueryPerformanceCounter( &qwTime ); + + if( m_bTimerStopped ) + m_llBaseTime += qwTime.QuadPart - m_llStopTime; + m_llStopTime = 0; + m_llLastElapsedTime = qwTime.QuadPart; + m_bTimerStopped = FALSE; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Stop() +{ + if( !m_bTimerStopped ) + { + LARGE_INTEGER qwTime = { 0 }; + QueryPerformanceCounter( &qwTime ); + m_llStopTime = qwTime.QuadPart; + m_llLastElapsedTime = qwTime.QuadPart; + m_bTimerStopped = TRUE; + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Advance() +{ + m_llStopTime += m_llQPFTicksPerSec / 10; +} + + +//-------------------------------------------------------------------------------------- +double CDXUTTimer::GetAbsoluteTime() +{ + LARGE_INTEGER qwTime = { 0 }; + QueryPerformanceCounter( &qwTime ); + + double fTime = qwTime.QuadPart / ( double )m_llQPFTicksPerSec; + + return fTime; +} + + +//-------------------------------------------------------------------------------------- +double CDXUTTimer::GetTime() +{ + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + double fAppTime = ( double )( qwTime.QuadPart - m_llBaseTime ) / ( double )m_llQPFTicksPerSec; + + return fAppTime; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::GetTimeValues( double* pfTime, double* pfAbsoluteTime, float* pfElapsedTime ) +{ + assert( pfTime && pfAbsoluteTime && pfElapsedTime ); + + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + float fElapsedTime = (float) ((double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec); + m_llLastElapsedTime = qwTime.QuadPart; + + // Clamp the timer to non-negative values to ensure the timer is accurate. + // fElapsedTime can be outside this range if processor goes into a + // power save mode or we somehow get shuffled to another processor. + // However, the main thread should call SetThreadAffinityMask to ensure that + // we don't get shuffled to another processor. Other worker threads should NOT call + // SetThreadAffinityMask, but use a shared copy of the timer data gathered from + // the main thread. + if( fElapsedTime < 0.0f ) + fElapsedTime = 0.0f; + + *pfAbsoluteTime = qwTime.QuadPart / ( double )m_llQPFTicksPerSec; + *pfTime = ( qwTime.QuadPart - m_llBaseTime ) / ( double )m_llQPFTicksPerSec; + *pfElapsedTime = fElapsedTime; +} + + +//-------------------------------------------------------------------------------------- +float CDXUTTimer::GetElapsedTime() +{ + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + double fElapsedTime = (float) ((double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec); + m_llLastElapsedTime = qwTime.QuadPart; + + // See the explanation about clamping in CDXUTTimer::GetTimeValues() + if( fElapsedTime < 0.0f ) + fElapsedTime = 0.0f; + + return ( float )fElapsedTime; +} + + +//-------------------------------------------------------------------------------------- +// If stopped, returns time when stopped otherwise returns current time +//-------------------------------------------------------------------------------------- +LARGE_INTEGER CDXUTTimer::GetAdjustedCurrentTime() +{ + LARGE_INTEGER qwTime; + if( m_llStopTime != 0 ) + qwTime.QuadPart = m_llStopTime; + else + QueryPerformanceCounter( &qwTime ); + return qwTime; +} + +//-------------------------------------------------------------------------------------- +bool CDXUTTimer::IsStopped() +{ + return m_bTimerStopped; +} + +//-------------------------------------------------------------------------------------- +// Limit the current thread to one processor (the current one). This ensures that timing code +// runs on only one processor, and will not suffer any ill effects from power management. +// See "Game Timing and Multicore Processors" for more details +//-------------------------------------------------------------------------------------- +void CDXUTTimer::LimitThreadAffinityToCurrentProc() +{ + HANDLE hCurrentProcess = GetCurrentProcess(); + + // Get the processor affinity mask for this process + DWORD_PTR dwProcessAffinityMask = 0; + DWORD_PTR dwSystemAffinityMask = 0; + + if( GetProcessAffinityMask( hCurrentProcess, &dwProcessAffinityMask, &dwSystemAffinityMask ) != 0 && + dwProcessAffinityMask ) + { + // Find the lowest processor that our process is allows to run against + DWORD_PTR dwAffinityMask = ( dwProcessAffinityMask & ( ( ~dwProcessAffinityMask ) + 1 ) ); + + // Set this as the processor that our thread must always run against + // This must be a subset of the process affinity mask + HANDLE hCurrentThread = GetCurrentThread(); + if( INVALID_HANDLE_VALUE != hCurrentThread ) + { + SetThreadAffinityMask( hCurrentThread, dwAffinityMask ); + CloseHandle( hCurrentThread ); + } + } + + CloseHandle( hCurrentProcess ); +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given D3DFORMAT. +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTD3DFormatToString( D3DFORMAT format, bool bWithPrefix ) +{ + WCHAR* pstr = NULL; + switch( format ) + { + case D3DFMT_UNKNOWN: + pstr = L"D3DFMT_UNKNOWN"; break; + case D3DFMT_R8G8B8: + pstr = L"D3DFMT_R8G8B8"; break; + case D3DFMT_A8R8G8B8: + pstr = L"D3DFMT_A8R8G8B8"; break; + case D3DFMT_X8R8G8B8: + pstr = L"D3DFMT_X8R8G8B8"; break; + case D3DFMT_R5G6B5: + pstr = L"D3DFMT_R5G6B5"; break; + case D3DFMT_X1R5G5B5: + pstr = L"D3DFMT_X1R5G5B5"; break; + case D3DFMT_A1R5G5B5: + pstr = L"D3DFMT_A1R5G5B5"; break; + case D3DFMT_A4R4G4B4: + pstr = L"D3DFMT_A4R4G4B4"; break; + case D3DFMT_R3G3B2: + pstr = L"D3DFMT_R3G3B2"; break; + case D3DFMT_A8: + pstr = L"D3DFMT_A8"; break; + case D3DFMT_A8R3G3B2: + pstr = L"D3DFMT_A8R3G3B2"; break; + case D3DFMT_X4R4G4B4: + pstr = L"D3DFMT_X4R4G4B4"; break; + case D3DFMT_A2B10G10R10: + pstr = L"D3DFMT_A2B10G10R10"; break; + case D3DFMT_A8B8G8R8: + pstr = L"D3DFMT_A8B8G8R8"; break; + case D3DFMT_X8B8G8R8: + pstr = L"D3DFMT_X8B8G8R8"; break; + case D3DFMT_G16R16: + pstr = L"D3DFMT_G16R16"; break; + case D3DFMT_A2R10G10B10: + pstr = L"D3DFMT_A2R10G10B10"; break; + case D3DFMT_A16B16G16R16: + pstr = L"D3DFMT_A16B16G16R16"; break; + case D3DFMT_A8P8: + pstr = L"D3DFMT_A8P8"; break; + case D3DFMT_P8: + pstr = L"D3DFMT_P8"; break; + case D3DFMT_L8: + pstr = L"D3DFMT_L8"; break; + case D3DFMT_A8L8: + pstr = L"D3DFMT_A8L8"; break; + case D3DFMT_A4L4: + pstr = L"D3DFMT_A4L4"; break; + case D3DFMT_V8U8: + pstr = L"D3DFMT_V8U8"; break; + case D3DFMT_L6V5U5: + pstr = L"D3DFMT_L6V5U5"; break; + case D3DFMT_X8L8V8U8: + pstr = L"D3DFMT_X8L8V8U8"; break; + case D3DFMT_Q8W8V8U8: + pstr = L"D3DFMT_Q8W8V8U8"; break; + case D3DFMT_V16U16: + pstr = L"D3DFMT_V16U16"; break; + case D3DFMT_A2W10V10U10: + pstr = L"D3DFMT_A2W10V10U10"; break; + case D3DFMT_UYVY: + pstr = L"D3DFMT_UYVY"; break; + case D3DFMT_YUY2: + pstr = L"D3DFMT_YUY2"; break; + case D3DFMT_DXT1: + pstr = L"D3DFMT_DXT1"; break; + case D3DFMT_DXT2: + pstr = L"D3DFMT_DXT2"; break; + case D3DFMT_DXT3: + pstr = L"D3DFMT_DXT3"; break; + case D3DFMT_DXT4: + pstr = L"D3DFMT_DXT4"; break; + case D3DFMT_DXT5: + pstr = L"D3DFMT_DXT5"; break; + case D3DFMT_D16_LOCKABLE: + pstr = L"D3DFMT_D16_LOCKABLE"; break; + case D3DFMT_D32: + pstr = L"D3DFMT_D32"; break; + case D3DFMT_D15S1: + pstr = L"D3DFMT_D15S1"; break; + case D3DFMT_D24S8: + pstr = L"D3DFMT_D24S8"; break; + case D3DFMT_D24X8: + pstr = L"D3DFMT_D24X8"; break; + case D3DFMT_D24X4S4: + pstr = L"D3DFMT_D24X4S4"; break; + case D3DFMT_D16: + pstr = L"D3DFMT_D16"; break; + case D3DFMT_L16: + pstr = L"D3DFMT_L16"; break; + case D3DFMT_VERTEXDATA: + pstr = L"D3DFMT_VERTEXDATA"; break; + case D3DFMT_INDEX16: + pstr = L"D3DFMT_INDEX16"; break; + case D3DFMT_INDEX32: + pstr = L"D3DFMT_INDEX32"; break; + case D3DFMT_Q16W16V16U16: + pstr = L"D3DFMT_Q16W16V16U16"; break; + case D3DFMT_MULTI2_ARGB8: + pstr = L"D3DFMT_MULTI2_ARGB8"; break; + case D3DFMT_R16F: + pstr = L"D3DFMT_R16F"; break; + case D3DFMT_G16R16F: + pstr = L"D3DFMT_G16R16F"; break; + case D3DFMT_A16B16G16R16F: + pstr = L"D3DFMT_A16B16G16R16F"; break; + case D3DFMT_R32F: + pstr = L"D3DFMT_R32F"; break; + case D3DFMT_G32R32F: + pstr = L"D3DFMT_G32R32F"; break; + case D3DFMT_A32B32G32R32F: + pstr = L"D3DFMT_A32B32G32R32F"; break; + case D3DFMT_CxV8U8: + pstr = L"D3DFMT_CxV8U8"; break; + default: + pstr = L"Unknown format"; break; + } + if( bWithPrefix || wcsstr( pstr, L"D3DFMT_" ) == NULL ) + return pstr; + else + return pstr + lstrlen( L"D3DFMT_" ); +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given DXGI_FORMAT. +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTDXGIFormatToString( DXGI_FORMAT format, bool bWithPrefix ) +{ + WCHAR* pstr = NULL; + switch( format ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + pstr = L"DXGI_FORMAT_R32G32B32A32_TYPELESS"; break; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + pstr = L"DXGI_FORMAT_R32G32B32A32_FLOAT"; break; + case DXGI_FORMAT_R32G32B32A32_UINT: + pstr = L"DXGI_FORMAT_R32G32B32A32_UINT"; break; + case DXGI_FORMAT_R32G32B32A32_SINT: + pstr = L"DXGI_FORMAT_R32G32B32A32_SINT"; break; + case DXGI_FORMAT_R32G32B32_TYPELESS: + pstr = L"DXGI_FORMAT_R32G32B32_TYPELESS"; break; + case DXGI_FORMAT_R32G32B32_FLOAT: + pstr = L"DXGI_FORMAT_R32G32B32_FLOAT"; break; + case DXGI_FORMAT_R32G32B32_UINT: + pstr = L"DXGI_FORMAT_R32G32B32_UINT"; break; + case DXGI_FORMAT_R32G32B32_SINT: + pstr = L"DXGI_FORMAT_R32G32B32_SINT"; break; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + pstr = L"DXGI_FORMAT_R16G16B16A16_TYPELESS"; break; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + pstr = L"DXGI_FORMAT_R16G16B16A16_FLOAT"; break; + case DXGI_FORMAT_R16G16B16A16_UNORM: + pstr = L"DXGI_FORMAT_R16G16B16A16_UNORM"; break; + case DXGI_FORMAT_R16G16B16A16_UINT: + pstr = L"DXGI_FORMAT_R16G16B16A16_UINT"; break; + case DXGI_FORMAT_R16G16B16A16_SNORM: + pstr = L"DXGI_FORMAT_R16G16B16A16_SNORM"; break; + case DXGI_FORMAT_R16G16B16A16_SINT: + pstr = L"DXGI_FORMAT_R16G16B16A16_SINT"; break; + case DXGI_FORMAT_R32G32_TYPELESS: + pstr = L"DXGI_FORMAT_R32G32_TYPELESS"; break; + case DXGI_FORMAT_R32G32_FLOAT: + pstr = L"DXGI_FORMAT_R32G32_FLOAT"; break; + case DXGI_FORMAT_R32G32_UINT: + pstr = L"DXGI_FORMAT_R32G32_UINT"; break; + case DXGI_FORMAT_R32G32_SINT: + pstr = L"DXGI_FORMAT_R32G32_SINT"; break; + case DXGI_FORMAT_R32G8X24_TYPELESS: + pstr = L"DXGI_FORMAT_R32G8X24_TYPELESS"; break; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + pstr = L"DXGI_FORMAT_D32_FLOAT_S8X24_UINT"; break; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + pstr = L"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS"; break; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + pstr = L"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT"; break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + pstr = L"DXGI_FORMAT_R10G10B10A2_TYPELESS"; break; + case DXGI_FORMAT_R10G10B10A2_UNORM: + pstr = L"DXGI_FORMAT_R10G10B10A2_UNORM"; break; + case DXGI_FORMAT_R10G10B10A2_UINT: + pstr = L"DXGI_FORMAT_R10G10B10A2_UINT"; break; + case DXGI_FORMAT_R11G11B10_FLOAT: + pstr = L"DXGI_FORMAT_R11G11B10_FLOAT"; break; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + pstr = L"DXGI_FORMAT_R8G8B8A8_TYPELESS"; break; + case DXGI_FORMAT_R8G8B8A8_UNORM: + pstr = L"DXGI_FORMAT_R8G8B8A8_UNORM"; break; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + pstr = L"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB"; break; + case DXGI_FORMAT_R8G8B8A8_UINT: + pstr = L"DXGI_FORMAT_R8G8B8A8_UINT"; break; + case DXGI_FORMAT_R8G8B8A8_SNORM: + pstr = L"DXGI_FORMAT_R8G8B8A8_SNORM"; break; + case DXGI_FORMAT_R8G8B8A8_SINT: + pstr = L"DXGI_FORMAT_R8G8B8A8_SINT"; break; + case DXGI_FORMAT_R16G16_TYPELESS: + pstr = L"DXGI_FORMAT_R16G16_TYPELESS"; break; + case DXGI_FORMAT_R16G16_FLOAT: + pstr = L"DXGI_FORMAT_R16G16_FLOAT"; break; + case DXGI_FORMAT_R16G16_UNORM: + pstr = L"DXGI_FORMAT_R16G16_UNORM"; break; + case DXGI_FORMAT_R16G16_UINT: + pstr = L"DXGI_FORMAT_R16G16_UINT"; break; + case DXGI_FORMAT_R16G16_SNORM: + pstr = L"DXGI_FORMAT_R16G16_SNORM"; break; + case DXGI_FORMAT_R16G16_SINT: + pstr = L"DXGI_FORMAT_R16G16_SINT"; break; + case DXGI_FORMAT_R32_TYPELESS: + pstr = L"DXGI_FORMAT_R32_TYPELESS"; break; + case DXGI_FORMAT_D32_FLOAT: + pstr = L"DXGI_FORMAT_D32_FLOAT"; break; + case DXGI_FORMAT_R32_FLOAT: + pstr = L"DXGI_FORMAT_R32_FLOAT"; break; + case DXGI_FORMAT_R32_UINT: + pstr = L"DXGI_FORMAT_R32_UINT"; break; + case DXGI_FORMAT_R32_SINT: + pstr = L"DXGI_FORMAT_R32_SINT"; break; + case DXGI_FORMAT_R24G8_TYPELESS: + pstr = L"DXGI_FORMAT_R24G8_TYPELESS"; break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + pstr = L"DXGI_FORMAT_D24_UNORM_S8_UINT"; break; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + pstr = L"DXGI_FORMAT_R24_UNORM_X8_TYPELESS"; break; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + pstr = L"DXGI_FORMAT_X24_TYPELESS_G8_UINT"; break; + case DXGI_FORMAT_R8G8_TYPELESS: + pstr = L"DXGI_FORMAT_R8G8_TYPELESS"; break; + case DXGI_FORMAT_R8G8_UNORM: + pstr = L"DXGI_FORMAT_R8G8_UNORM"; break; + case DXGI_FORMAT_R8G8_UINT: + pstr = L"DXGI_FORMAT_R8G8_UINT"; break; + case DXGI_FORMAT_R8G8_SNORM: + pstr = L"DXGI_FORMAT_R8G8_SNORM"; break; + case DXGI_FORMAT_R8G8_SINT: + pstr = L"DXGI_FORMAT_R8G8_SINT"; break; + case DXGI_FORMAT_R16_TYPELESS: + pstr = L"DXGI_FORMAT_R16_TYPELESS"; break; + case DXGI_FORMAT_R16_FLOAT: + pstr = L"DXGI_FORMAT_R16_FLOAT"; break; + case DXGI_FORMAT_D16_UNORM: + pstr = L"DXGI_FORMAT_D16_UNORM"; break; + case DXGI_FORMAT_R16_UNORM: + pstr = L"DXGI_FORMAT_R16_UNORM"; break; + case DXGI_FORMAT_R16_UINT: + pstr = L"DXGI_FORMAT_R16_UINT"; break; + case DXGI_FORMAT_R16_SNORM: + pstr = L"DXGI_FORMAT_R16_SNORM"; break; + case DXGI_FORMAT_R16_SINT: + pstr = L"DXGI_FORMAT_R16_SINT"; break; + case DXGI_FORMAT_R8_TYPELESS: + pstr = L"DXGI_FORMAT_R8_TYPELESS"; break; + case DXGI_FORMAT_R8_UNORM: + pstr = L"DXGI_FORMAT_R8_UNORM"; break; + case DXGI_FORMAT_R8_UINT: + pstr = L"DXGI_FORMAT_R8_UINT"; break; + case DXGI_FORMAT_R8_SNORM: + pstr = L"DXGI_FORMAT_R8_SNORM"; break; + case DXGI_FORMAT_R8_SINT: + pstr = L"DXGI_FORMAT_R8_SINT"; break; + case DXGI_FORMAT_A8_UNORM: + pstr = L"DXGI_FORMAT_A8_UNORM"; break; + case DXGI_FORMAT_R1_UNORM: + pstr = L"DXGI_FORMAT_R1_UNORM"; break; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + pstr = L"DXGI_FORMAT_R9G9B9E5_SHAREDEXP"; break; + case DXGI_FORMAT_R8G8_B8G8_UNORM: + pstr = L"DXGI_FORMAT_R8G8_B8G8_UNORM"; break; + case DXGI_FORMAT_G8R8_G8B8_UNORM: + pstr = L"DXGI_FORMAT_G8R8_G8B8_UNORM"; break; + case DXGI_FORMAT_BC1_TYPELESS: + pstr = L"DXGI_FORMAT_BC1_TYPELESS"; break; + case DXGI_FORMAT_BC1_UNORM: + pstr = L"DXGI_FORMAT_BC1_UNORM"; break; + case DXGI_FORMAT_BC1_UNORM_SRGB: + pstr = L"DXGI_FORMAT_BC1_UNORM_SRGB"; break; + case DXGI_FORMAT_BC2_TYPELESS: + pstr = L"DXGI_FORMAT_BC2_TYPELESS"; break; + case DXGI_FORMAT_BC2_UNORM: + pstr = L"DXGI_FORMAT_BC2_UNORM"; break; + case DXGI_FORMAT_BC2_UNORM_SRGB: + pstr = L"DXGI_FORMAT_BC2_UNORM_SRGB"; break; + case DXGI_FORMAT_BC3_TYPELESS: + pstr = L"DXGI_FORMAT_BC3_TYPELESS"; break; + case DXGI_FORMAT_BC3_UNORM: + pstr = L"DXGI_FORMAT_BC3_UNORM"; break; + case DXGI_FORMAT_BC3_UNORM_SRGB: + pstr = L"DXGI_FORMAT_BC3_UNORM_SRGB"; break; + case DXGI_FORMAT_BC4_TYPELESS: + pstr = L"DXGI_FORMAT_BC4_TYPELESS"; break; + case DXGI_FORMAT_BC4_UNORM: + pstr = L"DXGI_FORMAT_BC4_UNORM"; break; + case DXGI_FORMAT_BC4_SNORM: + pstr = L"DXGI_FORMAT_BC4_SNORM"; break; + case DXGI_FORMAT_BC5_TYPELESS: + pstr = L"DXGI_FORMAT_BC5_TYPELESS"; break; + case DXGI_FORMAT_BC5_UNORM: + pstr = L"DXGI_FORMAT_BC5_UNORM"; break; + case DXGI_FORMAT_BC5_SNORM: + pstr = L"DXGI_FORMAT_BC5_SNORM"; break; + case DXGI_FORMAT_B5G6R5_UNORM: + pstr = L"DXGI_FORMAT_B5G6R5_UNORM"; break; + case DXGI_FORMAT_B5G5R5A1_UNORM: + pstr = L"DXGI_FORMAT_B5G5R5A1_UNORM"; break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + pstr = L"DXGI_FORMAT_B8G8R8A8_UNORM"; break; + default: + pstr = L"Unknown format"; break; + } + if( bWithPrefix || wcsstr( pstr, L"DXGI_FORMAT_" ) == NULL ) + return pstr; + else + return pstr + lstrlen( L"DXGI_FORMAT_" ); +} + + +//-------------------------------------------------------------------------------------- +// Outputs to the debug stream a formatted Unicode string with a variable-argument list. +//-------------------------------------------------------------------------------------- +VOID WINAPI DXUTOutputDebugStringW( LPCWSTR strMsg, ... ) +{ +#if defined(DEBUG) || defined(_DEBUG) + WCHAR strBuffer[512]; + + va_list args; + va_start(args, strMsg); + vswprintf_s( strBuffer, 512, strMsg, args ); + strBuffer[511] = L'\0'; + va_end(args); + + OutputDebugString( strBuffer ); +#else + UNREFERENCED_PARAMETER( strMsg ); +#endif +} + + +//-------------------------------------------------------------------------------------- +// Outputs to the debug stream a formatted MBCS string with a variable-argument list. +//-------------------------------------------------------------------------------------- +VOID WINAPI DXUTOutputDebugStringA( LPCSTR strMsg, ... ) +{ +#if defined(DEBUG) || defined(_DEBUG) + CHAR strBuffer[512]; + + va_list args; + va_start(args, strMsg); + sprintf_s( strBuffer, 512, strMsg, args ); + strBuffer[511] = '\0'; + va_end(args); + + OutputDebugStringA( strBuffer ); +#else + UNREFERENCED_PARAMETER( strMsg ); +#endif +} + + +//-------------------------------------------------------------------------------------- +// Direct3D9 dynamic linking support -- calls top-level D3D9 APIs with graceful +// failure if APIs are not present. +//-------------------------------------------------------------------------------------- + +// Function prototypes +typedef IDirect3D9* (WINAPI * LPDIRECT3DCREATE9) (UINT); +typedef INT (WINAPI * LPD3DPERF_BEGINEVENT)(D3DCOLOR, LPCWSTR); +typedef INT (WINAPI * LPD3DPERF_ENDEVENT)(void); +typedef VOID (WINAPI * LPD3DPERF_SETMARKER)(D3DCOLOR, LPCWSTR); +typedef VOID (WINAPI * LPD3DPERF_SETREGION)(D3DCOLOR, LPCWSTR); +typedef BOOL (WINAPI * LPD3DPERF_QUERYREPEATFRAME)(void); +typedef VOID (WINAPI * LPD3DPERF_SETOPTIONS)( DWORD dwOptions ); +typedef DWORD (WINAPI * LPD3DPERF_GETSTATUS)( void ); +typedef HRESULT (WINAPI * LPCREATEDXGIFACTORY)(REFIID, void ** ); +typedef HRESULT (WINAPI * LPD3D11CREATEDEVICE)( IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL*, UINT, UINT32, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext** ); + +// Module and function pointers +static HMODULE s_hModD3D9 = NULL; +static LPDIRECT3DCREATE9 s_DynamicDirect3DCreate9 = NULL; +static LPD3DPERF_BEGINEVENT s_DynamicD3DPERF_BeginEvent = NULL; +static LPD3DPERF_ENDEVENT s_DynamicD3DPERF_EndEvent = NULL; +static LPD3DPERF_SETMARKER s_DynamicD3DPERF_SetMarker = NULL; +static LPD3DPERF_SETREGION s_DynamicD3DPERF_SetRegion = NULL; +static LPD3DPERF_QUERYREPEATFRAME s_DynamicD3DPERF_QueryRepeatFrame = NULL; +static LPD3DPERF_SETOPTIONS s_DynamicD3DPERF_SetOptions = NULL; +static LPD3DPERF_GETSTATUS s_DynamicD3DPERF_GetStatus = NULL; +static HMODULE s_hModDXGI = NULL; +static LPCREATEDXGIFACTORY s_DynamicCreateDXGIFactory = NULL; +static HMODULE s_hModD3D11 = NULL; +static LPD3D11CREATEDEVICE s_DynamicD3D11CreateDevice = NULL; + +// Ensure function pointers are initialized +static bool DXUT_EnsureD3D9APIs( void ) +{ + // If the module is non-NULL, this function has already been called. Note + // that this doesn't guarantee that all ProcAddresses were found. + if( s_hModD3D9 != NULL ) + return true; + + // This may fail if Direct3D 9 isn't installed + s_hModD3D9 = LoadLibrary( L"d3d9.dll" ); + if( s_hModD3D9 != NULL ) + { + s_DynamicDirect3DCreate9 = (LPDIRECT3DCREATE9)GetProcAddress( s_hModD3D9, "Direct3DCreate9" ); + s_DynamicD3DPERF_BeginEvent = (LPD3DPERF_BEGINEVENT)GetProcAddress( s_hModD3D9, "D3DPERF_BeginEvent" ); + s_DynamicD3DPERF_EndEvent = (LPD3DPERF_ENDEVENT)GetProcAddress( s_hModD3D9, "D3DPERF_EndEvent" ); + s_DynamicD3DPERF_SetMarker = (LPD3DPERF_SETMARKER)GetProcAddress( s_hModD3D9, "D3DPERF_SetMarker" ); + s_DynamicD3DPERF_SetRegion = (LPD3DPERF_SETREGION)GetProcAddress( s_hModD3D9, "D3DPERF_SetRegion" ); + s_DynamicD3DPERF_QueryRepeatFrame = (LPD3DPERF_QUERYREPEATFRAME)GetProcAddress( s_hModD3D9, "D3DPERF_QueryRepeatFrame" ); + s_DynamicD3DPERF_SetOptions = (LPD3DPERF_SETOPTIONS)GetProcAddress( s_hModD3D9, "D3DPERF_SetOptions" ); + s_DynamicD3DPERF_GetStatus = (LPD3DPERF_GETSTATUS)GetProcAddress( s_hModD3D9, "D3DPERF_GetStatus" ); + } + + return s_hModD3D9 != NULL; +} + +bool DXUT_EnsureD3D11APIs( void ) +{ + // If both modules are non-NULL, this function has already been called. Note + // that this doesn't guarantee that all ProcAddresses were found. + if( s_hModD3D11 != NULL && s_hModDXGI != NULL ) + return true; + + // This may fail if Direct3D 11 isn't installed + s_hModD3D11 = LoadLibrary( L"d3d11.dll" ); + if( s_hModD3D11 != NULL ) + { + s_DynamicD3D11CreateDevice = ( LPD3D11CREATEDEVICE )GetProcAddress( s_hModD3D11, "D3D11CreateDevice" ); + } + + if( !s_DynamicCreateDXGIFactory ) + { + s_hModDXGI = LoadLibrary( L"dxgi.dll" ); + if( s_hModDXGI ) + { + s_DynamicCreateDXGIFactory = ( LPCREATEDXGIFACTORY )GetProcAddress( s_hModDXGI, "CreateDXGIFactory1" ); + } + + return ( s_hModDXGI != NULL ) && ( s_hModD3D11 != NULL ); + } + + return ( s_hModD3D11 != NULL ); +} + +IDirect3D9* WINAPI DXUT_Dynamic_Direct3DCreate9( UINT SDKVersion ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicDirect3DCreate9 != NULL ) + return s_DynamicDirect3DCreate9( SDKVersion ); + else + return NULL; +} + +int WINAPI DXUT_Dynamic_D3DPERF_BeginEvent( D3DCOLOR col, LPCWSTR wszName ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_BeginEvent != NULL ) + return s_DynamicD3DPERF_BeginEvent( col, wszName ); + else + return -1; +} + +int WINAPI DXUT_Dynamic_D3DPERF_EndEvent( void ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_EndEvent != NULL ) + return s_DynamicD3DPERF_EndEvent(); + else + return -1; +} + +void WINAPI DXUT_Dynamic_D3DPERF_SetMarker( D3DCOLOR col, LPCWSTR wszName ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_SetMarker != NULL ) + s_DynamicD3DPERF_SetMarker( col, wszName ); +} + +void WINAPI DXUT_Dynamic_D3DPERF_SetRegion( D3DCOLOR col, LPCWSTR wszName ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_SetRegion != NULL ) + s_DynamicD3DPERF_SetRegion( col, wszName ); +} + +BOOL WINAPI DXUT_Dynamic_D3DPERF_QueryRepeatFrame( void ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_QueryRepeatFrame != NULL ) + return s_DynamicD3DPERF_QueryRepeatFrame(); + else + return FALSE; +} + +void WINAPI DXUT_Dynamic_D3DPERF_SetOptions( DWORD dwOptions ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_SetOptions != NULL ) + s_DynamicD3DPERF_SetOptions( dwOptions ); +} + +DWORD WINAPI DXUT_Dynamic_D3DPERF_GetStatus( void ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_GetStatus != NULL ) + return s_DynamicD3DPERF_GetStatus(); + else + return 0; +} + +HRESULT WINAPI DXUT_Dynamic_CreateDXGIFactory1( REFIID rInterface, void** ppOut ) +{ + if( DXUT_EnsureD3D11APIs() && s_DynamicCreateDXGIFactory != NULL ) + return s_DynamicCreateDXGIFactory( rInterface, ppOut ); + else + return DXUTERR_NODIRECT3D11; +} + + + +HRESULT WINAPI DXUT_Dynamic_D3D11CreateDevice( IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT32 Flags, + D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT32 SDKVersion, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext ) +{ + if( DXUT_EnsureD3D11APIs() && s_DynamicD3D11CreateDevice != NULL ) + return s_DynamicD3D11CreateDevice( pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, + SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext ); + else + return DXUTERR_NODIRECT3D11; +} + +//-------------------------------------------------------------------------------------- +// Trace a string description of a decl +//-------------------------------------------------------------------------------------- +void WINAPI DXUTTraceDecl( D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE] ) +{ + int iDecl = 0; + for( iDecl = 0; iDecl < MAX_FVF_DECL_SIZE; iDecl++ ) + { + if( decl[iDecl].Stream == 0xFF ) + break; + + DXUTOutputDebugString( L"decl[%d]=Stream:%d, Offset:%d, %s, %s, %s, UsageIndex:%d\n", iDecl, + decl[iDecl].Stream, + decl[iDecl].Offset, + DXUTTraceD3DDECLTYPEtoString( decl[iDecl].Type ), + DXUTTraceD3DDECLMETHODtoString( decl[iDecl].Method ), + DXUTTraceD3DDECLUSAGEtoString( decl[iDecl].Usage ), + decl[iDecl].UsageIndex ); + } + + DXUTOutputDebugString( L"decl[%d]=D3DDECL_END\n", iDecl ); +} + +#define TRACE_ID(iD) case iD: return L#iD; + +//-------------------------------------------------------------------------------------- +WCHAR* WINAPI DXUTTraceWindowsMessage( UINT uMsg ) +{ + switch( uMsg ) + { + TRACE_ID(WM_NULL); + TRACE_ID(WM_CREATE); + TRACE_ID(WM_DESTROY); + TRACE_ID(WM_MOVE); + TRACE_ID(WM_SIZE); + TRACE_ID(WM_ACTIVATE); + TRACE_ID(WM_SETFOCUS); + TRACE_ID(WM_KILLFOCUS); + TRACE_ID(WM_ENABLE); + TRACE_ID(WM_SETREDRAW); + TRACE_ID(WM_SETTEXT); + TRACE_ID(WM_GETTEXT); + TRACE_ID(WM_GETTEXTLENGTH); + TRACE_ID(WM_PAINT); + TRACE_ID(WM_CLOSE); + TRACE_ID(WM_QUERYENDSESSION); + TRACE_ID(WM_QUERYOPEN); + TRACE_ID(WM_ENDSESSION); + TRACE_ID(WM_QUIT); + TRACE_ID(WM_ERASEBKGND); + TRACE_ID(WM_SYSCOLORCHANGE); + TRACE_ID(WM_SHOWWINDOW); + TRACE_ID(WM_WININICHANGE); + TRACE_ID(WM_DEVMODECHANGE); + TRACE_ID(WM_ACTIVATEAPP); + TRACE_ID(WM_FONTCHANGE); + TRACE_ID(WM_TIMECHANGE); + TRACE_ID(WM_CANCELMODE); + TRACE_ID(WM_SETCURSOR); + TRACE_ID(WM_MOUSEACTIVATE); + TRACE_ID(WM_CHILDACTIVATE); + TRACE_ID(WM_QUEUESYNC); + TRACE_ID(WM_GETMINMAXINFO); + TRACE_ID(WM_PAINTICON); + TRACE_ID(WM_ICONERASEBKGND); + TRACE_ID(WM_NEXTDLGCTL); + TRACE_ID(WM_SPOOLERSTATUS); + TRACE_ID(WM_DRAWITEM); + TRACE_ID(WM_MEASUREITEM); + TRACE_ID(WM_DELETEITEM); + TRACE_ID(WM_VKEYTOITEM); + TRACE_ID(WM_CHARTOITEM); + TRACE_ID(WM_SETFONT); + TRACE_ID(WM_GETFONT); + TRACE_ID(WM_SETHOTKEY); + TRACE_ID(WM_GETHOTKEY); + TRACE_ID(WM_QUERYDRAGICON); + TRACE_ID(WM_COMPAREITEM); + TRACE_ID(WM_GETOBJECT); + TRACE_ID(WM_COMPACTING); + TRACE_ID(WM_COMMNOTIFY); + TRACE_ID(WM_WINDOWPOSCHANGING); + TRACE_ID(WM_WINDOWPOSCHANGED); + TRACE_ID(WM_POWER); + TRACE_ID(WM_COPYDATA); + TRACE_ID(WM_CANCELJOURNAL); + TRACE_ID(WM_NOTIFY); + TRACE_ID(WM_INPUTLANGCHANGEREQUEST); + TRACE_ID(WM_INPUTLANGCHANGE); + TRACE_ID(WM_TCARD); + TRACE_ID(WM_HELP); + TRACE_ID(WM_USERCHANGED); + TRACE_ID(WM_NOTIFYFORMAT); + TRACE_ID(WM_CONTEXTMENU); + TRACE_ID(WM_STYLECHANGING); + TRACE_ID(WM_STYLECHANGED); + TRACE_ID(WM_DISPLAYCHANGE); + TRACE_ID(WM_GETICON); + TRACE_ID(WM_SETICON); + TRACE_ID(WM_NCCREATE); + TRACE_ID(WM_NCDESTROY); + TRACE_ID(WM_NCCALCSIZE); + TRACE_ID(WM_NCHITTEST); + TRACE_ID(WM_NCPAINT); + TRACE_ID(WM_NCACTIVATE); + TRACE_ID(WM_GETDLGCODE); + TRACE_ID(WM_SYNCPAINT); + TRACE_ID(WM_NCMOUSEMOVE); + TRACE_ID(WM_NCLBUTTONDOWN); + TRACE_ID(WM_NCLBUTTONUP); + TRACE_ID(WM_NCLBUTTONDBLCLK); + TRACE_ID(WM_NCRBUTTONDOWN); + TRACE_ID(WM_NCRBUTTONUP); + TRACE_ID(WM_NCRBUTTONDBLCLK); + TRACE_ID(WM_NCMBUTTONDOWN); + TRACE_ID(WM_NCMBUTTONUP); + TRACE_ID(WM_NCMBUTTONDBLCLK); + TRACE_ID(WM_NCXBUTTONDOWN); + TRACE_ID(WM_NCXBUTTONUP); + TRACE_ID(WM_NCXBUTTONDBLCLK); + TRACE_ID(WM_INPUT); + TRACE_ID(WM_KEYDOWN); + TRACE_ID(WM_KEYUP); + TRACE_ID(WM_CHAR); + TRACE_ID(WM_DEADCHAR); + TRACE_ID(WM_SYSKEYDOWN); + TRACE_ID(WM_SYSKEYUP); + TRACE_ID(WM_SYSCHAR); + TRACE_ID(WM_SYSDEADCHAR); + TRACE_ID(WM_UNICHAR); + TRACE_ID(WM_IME_STARTCOMPOSITION); + TRACE_ID(WM_IME_ENDCOMPOSITION); + TRACE_ID(WM_IME_COMPOSITION); + TRACE_ID(WM_INITDIALOG); + TRACE_ID(WM_COMMAND); + TRACE_ID(WM_SYSCOMMAND); + TRACE_ID(WM_TIMER); + TRACE_ID(WM_HSCROLL); + TRACE_ID(WM_VSCROLL); + TRACE_ID(WM_INITMENU); + TRACE_ID(WM_INITMENUPOPUP); + TRACE_ID(WM_MENUSELECT); + TRACE_ID(WM_MENUCHAR); + TRACE_ID(WM_ENTERIDLE); + TRACE_ID(WM_MENURBUTTONUP); + TRACE_ID(WM_MENUDRAG); + TRACE_ID(WM_MENUGETOBJECT); + TRACE_ID(WM_UNINITMENUPOPUP); + TRACE_ID(WM_MENUCOMMAND); + TRACE_ID(WM_CHANGEUISTATE); + TRACE_ID(WM_UPDATEUISTATE); + TRACE_ID(WM_QUERYUISTATE); + TRACE_ID(WM_CTLCOLORMSGBOX); + TRACE_ID(WM_CTLCOLOREDIT); + TRACE_ID(WM_CTLCOLORLISTBOX); + TRACE_ID(WM_CTLCOLORBTN); + TRACE_ID(WM_CTLCOLORDLG); + TRACE_ID(WM_CTLCOLORSCROLLBAR); + TRACE_ID(WM_CTLCOLORSTATIC); + TRACE_ID(MN_GETHMENU); + TRACE_ID(WM_MOUSEMOVE); + TRACE_ID(WM_LBUTTONDOWN); + TRACE_ID(WM_LBUTTONUP); + TRACE_ID(WM_LBUTTONDBLCLK); + TRACE_ID(WM_RBUTTONDOWN); + TRACE_ID(WM_RBUTTONUP); + TRACE_ID(WM_RBUTTONDBLCLK); + TRACE_ID(WM_MBUTTONDOWN); + TRACE_ID(WM_MBUTTONUP); + TRACE_ID(WM_MBUTTONDBLCLK); + TRACE_ID(WM_MOUSEWHEEL); + TRACE_ID(WM_XBUTTONDOWN); + TRACE_ID(WM_XBUTTONUP); + TRACE_ID(WM_XBUTTONDBLCLK); + TRACE_ID(WM_PARENTNOTIFY); + TRACE_ID(WM_ENTERMENULOOP); + TRACE_ID(WM_EXITMENULOOP); + TRACE_ID(WM_NEXTMENU); + TRACE_ID(WM_SIZING); + TRACE_ID(WM_CAPTURECHANGED); + TRACE_ID(WM_MOVING); + TRACE_ID(WM_POWERBROADCAST); + TRACE_ID(WM_DEVICECHANGE); + TRACE_ID(WM_MDICREATE); + TRACE_ID(WM_MDIDESTROY); + TRACE_ID(WM_MDIACTIVATE); + TRACE_ID(WM_MDIRESTORE); + TRACE_ID(WM_MDINEXT); + TRACE_ID(WM_MDIMAXIMIZE); + TRACE_ID(WM_MDITILE); + TRACE_ID(WM_MDICASCADE); + TRACE_ID(WM_MDIICONARRANGE); + TRACE_ID(WM_MDIGETACTIVE); + TRACE_ID(WM_MDISETMENU); + TRACE_ID(WM_ENTERSIZEMOVE); + TRACE_ID(WM_EXITSIZEMOVE); + TRACE_ID(WM_DROPFILES); + TRACE_ID(WM_MDIREFRESHMENU); + TRACE_ID(WM_IME_SETCONTEXT); + TRACE_ID(WM_IME_NOTIFY); + TRACE_ID(WM_IME_CONTROL); + TRACE_ID(WM_IME_COMPOSITIONFULL); + TRACE_ID(WM_IME_SELECT); + TRACE_ID(WM_IME_CHAR); + TRACE_ID(WM_IME_REQUEST); + TRACE_ID(WM_IME_KEYDOWN); + TRACE_ID(WM_IME_KEYUP); + TRACE_ID(WM_MOUSEHOVER); + TRACE_ID(WM_MOUSELEAVE); + TRACE_ID(WM_NCMOUSEHOVER); + TRACE_ID(WM_NCMOUSELEAVE); + TRACE_ID(WM_WTSSESSION_CHANGE); + TRACE_ID(WM_TABLET_FIRST); + TRACE_ID(WM_TABLET_LAST); + TRACE_ID(WM_CUT); + TRACE_ID(WM_COPY); + TRACE_ID(WM_PASTE); + TRACE_ID(WM_CLEAR); + TRACE_ID(WM_UNDO); + TRACE_ID(WM_RENDERFORMAT); + TRACE_ID(WM_RENDERALLFORMATS); + TRACE_ID(WM_DESTROYCLIPBOARD); + TRACE_ID(WM_DRAWCLIPBOARD); + TRACE_ID(WM_PAINTCLIPBOARD); + TRACE_ID(WM_VSCROLLCLIPBOARD); + TRACE_ID(WM_SIZECLIPBOARD); + TRACE_ID(WM_ASKCBFORMATNAME); + TRACE_ID(WM_CHANGECBCHAIN); + TRACE_ID(WM_HSCROLLCLIPBOARD); + TRACE_ID(WM_QUERYNEWPALETTE); + TRACE_ID(WM_PALETTEISCHANGING); + TRACE_ID(WM_PALETTECHANGED); + TRACE_ID(WM_HOTKEY); + TRACE_ID(WM_PRINT); + TRACE_ID(WM_PRINTCLIENT); + TRACE_ID(WM_APPCOMMAND); + TRACE_ID(WM_THEMECHANGED); + TRACE_ID(WM_HANDHELDFIRST); + TRACE_ID(WM_HANDHELDLAST); + TRACE_ID(WM_AFXFIRST); + TRACE_ID(WM_AFXLAST); + TRACE_ID(WM_PENWINFIRST); + TRACE_ID(WM_PENWINLAST); + TRACE_ID(WM_APP); + default: + return L"Unknown"; + } +} + + +//-------------------------------------------------------------------------------------- +WCHAR* WINAPI DXUTTraceD3DDECLTYPEtoString( BYTE t ) +{ + switch( t ) + { + case D3DDECLTYPE_FLOAT1: + return L"D3DDECLTYPE_FLOAT1"; + case D3DDECLTYPE_FLOAT2: + return L"D3DDECLTYPE_FLOAT2"; + case D3DDECLTYPE_FLOAT3: + return L"D3DDECLTYPE_FLOAT3"; + case D3DDECLTYPE_FLOAT4: + return L"D3DDECLTYPE_FLOAT4"; + case D3DDECLTYPE_D3DCOLOR: + return L"D3DDECLTYPE_D3DCOLOR"; + case D3DDECLTYPE_UBYTE4: + return L"D3DDECLTYPE_UBYTE4"; + case D3DDECLTYPE_SHORT2: + return L"D3DDECLTYPE_SHORT2"; + case D3DDECLTYPE_SHORT4: + return L"D3DDECLTYPE_SHORT4"; + case D3DDECLTYPE_UBYTE4N: + return L"D3DDECLTYPE_UBYTE4N"; + case D3DDECLTYPE_SHORT2N: + return L"D3DDECLTYPE_SHORT2N"; + case D3DDECLTYPE_SHORT4N: + return L"D3DDECLTYPE_SHORT4N"; + case D3DDECLTYPE_USHORT2N: + return L"D3DDECLTYPE_USHORT2N"; + case D3DDECLTYPE_USHORT4N: + return L"D3DDECLTYPE_USHORT4N"; + case D3DDECLTYPE_UDEC3: + return L"D3DDECLTYPE_UDEC3"; + case D3DDECLTYPE_DEC3N: + return L"D3DDECLTYPE_DEC3N"; + case D3DDECLTYPE_FLOAT16_2: + return L"D3DDECLTYPE_FLOAT16_2"; + case D3DDECLTYPE_FLOAT16_4: + return L"D3DDECLTYPE_FLOAT16_4"; + case D3DDECLTYPE_UNUSED: + return L"D3DDECLTYPE_UNUSED"; + default: + return L"D3DDECLTYPE Unknown"; + } +} + +WCHAR* WINAPI DXUTTraceD3DDECLMETHODtoString( BYTE m ) +{ + switch( m ) + { + case D3DDECLMETHOD_DEFAULT: + return L"D3DDECLMETHOD_DEFAULT"; + case D3DDECLMETHOD_PARTIALU: + return L"D3DDECLMETHOD_PARTIALU"; + case D3DDECLMETHOD_PARTIALV: + return L"D3DDECLMETHOD_PARTIALV"; + case D3DDECLMETHOD_CROSSUV: + return L"D3DDECLMETHOD_CROSSUV"; + case D3DDECLMETHOD_UV: + return L"D3DDECLMETHOD_UV"; + case D3DDECLMETHOD_LOOKUP: + return L"D3DDECLMETHOD_LOOKUP"; + case D3DDECLMETHOD_LOOKUPPRESAMPLED: + return L"D3DDECLMETHOD_LOOKUPPRESAMPLED"; + default: + return L"D3DDECLMETHOD Unknown"; + } +} + +WCHAR* WINAPI DXUTTraceD3DDECLUSAGEtoString( BYTE u ) +{ + switch( u ) + { + case D3DDECLUSAGE_POSITION: + return L"D3DDECLUSAGE_POSITION"; + case D3DDECLUSAGE_BLENDWEIGHT: + return L"D3DDECLUSAGE_BLENDWEIGHT"; + case D3DDECLUSAGE_BLENDINDICES: + return L"D3DDECLUSAGE_BLENDINDICES"; + case D3DDECLUSAGE_NORMAL: + return L"D3DDECLUSAGE_NORMAL"; + case D3DDECLUSAGE_PSIZE: + return L"D3DDECLUSAGE_PSIZE"; + case D3DDECLUSAGE_TEXCOORD: + return L"D3DDECLUSAGE_TEXCOORD"; + case D3DDECLUSAGE_TANGENT: + return L"D3DDECLUSAGE_TANGENT"; + case D3DDECLUSAGE_BINORMAL: + return L"D3DDECLUSAGE_BINORMAL"; + case D3DDECLUSAGE_TESSFACTOR: + return L"D3DDECLUSAGE_TESSFACTOR"; + case D3DDECLUSAGE_POSITIONT: + return L"D3DDECLUSAGE_POSITIONT"; + case D3DDECLUSAGE_COLOR: + return L"D3DDECLUSAGE_COLOR"; + case D3DDECLUSAGE_FOG: + return L"D3DDECLUSAGE_FOG"; + case D3DDECLUSAGE_DEPTH: + return L"D3DDECLUSAGE_DEPTH"; + case D3DDECLUSAGE_SAMPLE: + return L"D3DDECLUSAGE_SAMPLE"; + default: + return L"D3DDECLUSAGE Unknown"; + } +} + + +//-------------------------------------------------------------------------------------- +// Multimon API handling for OSes with or without multimon API support +//-------------------------------------------------------------------------------------- +#define DXUT_PRIMARY_MONITOR ((HMONITOR)0x12340042) +typedef HMONITOR ( WINAPI* LPMONITORFROMWINDOW )( HWND, DWORD ); +typedef BOOL ( WINAPI* LPGETMONITORINFO )( HMONITOR, LPMONITORINFO ); +typedef HMONITOR ( WINAPI* LPMONITORFROMRECT )( LPCRECT lprcScreenCoords, DWORD dwFlags ); + +BOOL WINAPI DXUTGetMonitorInfo( HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo ) +{ + static bool s_bInited = false; + static LPGETMONITORINFO s_pFnGetMonitorInfo = NULL; + if( !s_bInited ) + { + s_bInited = true; + HMODULE hUser32 = GetModuleHandle( L"USER32" ); + if( hUser32 ) + { + OSVERSIONINFOA osvi = + { + 0 + }; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionExA( ( OSVERSIONINFOA* )&osvi ); + bool bNT = ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId ); + s_pFnGetMonitorInfo = ( LPGETMONITORINFO )( bNT ? GetProcAddress( hUser32, + "GetMonitorInfoW" ) : + GetProcAddress( hUser32, "GetMonitorInfoA" ) ); + } + } + + if( s_pFnGetMonitorInfo ) + return s_pFnGetMonitorInfo( hMonitor, lpMonitorInfo ); + + RECT rcWork; + if( ( hMonitor == DXUT_PRIMARY_MONITOR ) && lpMonitorInfo && ( lpMonitorInfo->cbSize >= sizeof( MONITORINFO ) ) && + SystemParametersInfoA( SPI_GETWORKAREA, 0, &rcWork, 0 ) ) + { + lpMonitorInfo->rcMonitor.left = 0; + lpMonitorInfo->rcMonitor.top = 0; + lpMonitorInfo->rcMonitor.right = GetSystemMetrics( SM_CXSCREEN ); + lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN ); + lpMonitorInfo->rcWork = rcWork; + lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY; + return TRUE; + } + return FALSE; +} + + +HMONITOR WINAPI DXUTMonitorFromWindow( HWND hWnd, DWORD dwFlags ) +{ + static bool s_bInited = false; + static LPMONITORFROMWINDOW s_pFnGetMonitorFromWindow = NULL; + if( !s_bInited ) + { + s_bInited = true; + HMODULE hUser32 = GetModuleHandle( L"USER32" ); + if( hUser32 ) s_pFnGetMonitorFromWindow = ( LPMONITORFROMWINDOW )GetProcAddress( hUser32, + "MonitorFromWindow" ); + } + + if( s_pFnGetMonitorFromWindow ) + return s_pFnGetMonitorFromWindow( hWnd, dwFlags ); + else + return DXUT_PRIMARY_MONITOR; +} + + +HMONITOR WINAPI DXUTMonitorFromRect( LPCRECT lprcScreenCoords, DWORD dwFlags ) +{ + static bool s_bInited = false; + static LPMONITORFROMRECT s_pFnGetMonitorFromRect = NULL; + if( !s_bInited ) + { + s_bInited = true; + HMODULE hUser32 = GetModuleHandle( L"USER32" ); + if( hUser32 ) s_pFnGetMonitorFromRect = ( LPMONITORFROMRECT )GetProcAddress( hUser32, "MonitorFromRect" ); + } + + if( s_pFnGetMonitorFromRect ) + return s_pFnGetMonitorFromRect( lprcScreenCoords, dwFlags ); + else + return DXUT_PRIMARY_MONITOR; +} + + +//-------------------------------------------------------------------------------------- +// Get the desktop resolution of an adapter. This isn't the same as the current resolution +// from GetAdapterDisplayMode since the device might be fullscreen +//-------------------------------------------------------------------------------------- +void WINAPI DXUTGetDesktopResolution( UINT AdapterOrdinal, UINT* pWidth, UINT* pHeight ) +{ + DXUTDeviceSettings DeviceSettings = DXUTGetDeviceSettings(); + + WCHAR strDeviceName[256] = {0}; + DEVMODE devMode; + ZeroMemory( &devMode, sizeof( DEVMODE ) ); + devMode.dmSize = sizeof( DEVMODE ); + if( DeviceSettings.ver == DXUT_D3D9_DEVICE ) + { + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration(); + CD3D9EnumAdapterInfo* pAdapterInfo = pd3dEnum->GetAdapterInfo( AdapterOrdinal ); + if( pAdapterInfo ) + { + MultiByteToWideChar( CP_ACP, 0, pAdapterInfo->AdapterIdentifier.DeviceName, -1, strDeviceName, 256 ); + strDeviceName[255] = 0; + } + } + else + { + CD3D11Enumeration* pd3dEnum = DXUTGetD3D11Enumeration(); + CD3D11EnumOutputInfo* pOutputInfo = pd3dEnum->GetOutputInfo( AdapterOrdinal, DeviceSettings.d3d11.Output ); + if( pOutputInfo ) + { + wcscpy_s( strDeviceName, 256, pOutputInfo->Desc.DeviceName ); + } + } + + EnumDisplaySettings( strDeviceName, ENUM_REGISTRY_SETTINGS, &devMode ); + if( pWidth ) + *pWidth = devMode.dmPelsWidth; + if( pHeight ) + *pHeight = devMode.dmPelsHeight; +} + + +//-------------------------------------------------------------------------------------- +// Display error msg box to help debug +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTTrace( const CHAR* strFile, DWORD dwLine, HRESULT hr, + const WCHAR* strMsg, bool bPopMsgBox ) +{ + bool bShowMsgBoxOnError = DXUTGetShowMsgBoxOnError(); + if( bPopMsgBox && bShowMsgBoxOnError == false ) + bPopMsgBox = false; + + return DXTrace( strFile, dwLine, hr, strMsg, bPopMsgBox ); +} + + +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +void WINAPI DXUTConvertDeviceSettings11to9( DXUTD3D11DeviceSettings* pIn, DXUTD3D9DeviceSettings* pOut ) +{ + pOut->AdapterOrdinal = pIn->AdapterOrdinal; + + if( pIn->DriverType == D3D_DRIVER_TYPE_HARDWARE ) + pOut->DeviceType = D3DDEVTYPE_HAL; + else if( pIn->DriverType == D3D_DRIVER_TYPE_REFERENCE ) + pOut->DeviceType = D3DDEVTYPE_REF; + else if( pIn->DriverType == D3D_DRIVER_TYPE_NULL ) + pOut->DeviceType = D3DDEVTYPE_NULLREF; + + pOut->AdapterFormat = ConvertFormatDXGIToD3D9( pIn->sd.BufferDesc.Format ); + pOut->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; + pOut->pp.BackBufferWidth = pIn->sd.BufferDesc.Width; + pOut->pp.BackBufferHeight = pIn->sd.BufferDesc.Height; + pOut->pp.BackBufferFormat = ConvertFormatDXGIToD3D9( pIn->sd.BufferDesc.Format ); + pOut->pp.BackBufferCount = pIn->sd.BufferCount; + pOut->pp.MultiSampleType = ( D3DMULTISAMPLE_TYPE )pIn->sd.SampleDesc.Count; + pOut->pp.MultiSampleQuality = pIn->sd.SampleDesc.Quality; + pOut->pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + pOut->pp.hDeviceWindow = pIn->sd.OutputWindow; + pOut->pp.Windowed = pIn->sd.Windowed; + pOut->pp.EnableAutoDepthStencil = true; + pOut->pp.AutoDepthStencilFormat = D3DFMT_D24FS8; + pOut->pp.Flags = 0; + if( pIn->sd.BufferDesc.RefreshRate.Denominator == 0 ) + pOut->pp.FullScreen_RefreshRateInHz = 60; + else + pOut->pp.FullScreen_RefreshRateInHz = pIn->sd.BufferDesc.RefreshRate.Numerator / + pIn->sd.BufferDesc.RefreshRate.Denominator; + + switch( pIn->SyncInterval ) + { + case 0: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; break; + case 2: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; break; + case 3: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_THREE; break; + case 4: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR; break; + + case 1: + default: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + break; + } +} + + +//-------------------------------------------------------------------------------------- +void WINAPI DXUTConvertDeviceSettings9to11( DXUTD3D9DeviceSettings* pIn, DXUTD3D11DeviceSettings* pOut ) +{ + pOut->AdapterOrdinal = pIn->AdapterOrdinal; + + if( pIn->DeviceType == D3DDEVTYPE_HAL ) + pOut->DriverType = D3D_DRIVER_TYPE_HARDWARE; + else if( pIn->DeviceType == D3DDEVTYPE_REF ) + pOut->DriverType = D3D_DRIVER_TYPE_REFERENCE; + else if( pIn->DeviceType == D3DDEVTYPE_NULLREF ) + pOut->DriverType = D3D_DRIVER_TYPE_NULL; + + pOut->Output = 0; + + pOut->sd.BufferDesc.Width = pIn->pp.BackBufferWidth; + pOut->sd.BufferDesc.Height = pIn->pp.BackBufferHeight; + pOut->sd.BufferDesc.RefreshRate.Numerator = pIn->pp.FullScreen_RefreshRateInHz; + pOut->sd.BufferDesc.RefreshRate.Denominator = 1; + pOut->sd.BufferDesc.Format = ConvertFormatD3D9ToDXGI( pIn->pp.BackBufferFormat ); + + if( pIn->pp.MultiSampleType == D3DMULTISAMPLE_NONMASKABLE ) + { + pOut->sd.SampleDesc.Count = pIn->pp.MultiSampleQuality; + pOut->sd.SampleDesc.Quality = 0; + } + else + { + pOut->sd.SampleDesc.Count = pIn->pp.MultiSampleType; + pOut->sd.SampleDesc.Quality = pIn->pp.MultiSampleQuality; + } + + pOut->sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + pOut->sd.BufferCount = pIn->pp.BackBufferCount; + pOut->sd.OutputWindow = pIn->pp.hDeviceWindow; + pOut->sd.Windowed = pIn->pp.Windowed; + +#if defined(DEBUG) || defined(_DEBUG) + pOut->CreateFlags = D3D11_CREATE_DEVICE_DEBUG; +#else + pOut->CreateFlags = 0; +#endif + + switch( pIn->pp.PresentationInterval ) + { + case D3DPRESENT_INTERVAL_IMMEDIATE: + pOut->SyncInterval = 0; break; + case D3DPRESENT_INTERVAL_ONE: + pOut->SyncInterval = 1; break; + case D3DPRESENT_INTERVAL_TWO: + pOut->SyncInterval = 2; break; + case D3DPRESENT_INTERVAL_THREE: + pOut->SyncInterval = 3; break; + case D3DPRESENT_INTERVAL_FOUR: + pOut->SyncInterval = 4; break; + + case D3DPRESENT_INTERVAL_DEFAULT: + default: + pOut->SyncInterval = 1; + break; + } + + pOut->PresentFlags = 0; +} + + + +DXGI_FORMAT WINAPI ConvertFormatD3D9ToDXGI( D3DFORMAT fmt ) +{ + switch( fmt ) + { + case D3DFMT_UNKNOWN: + return DXGI_FORMAT_UNKNOWN; + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_R5G6B5: + return DXGI_FORMAT_B5G6R5_UNORM; + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + return DXGI_FORMAT_B5G5R5A1_UNORM; + case D3DFMT_A4R4G4B4: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_R3G3B2: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_A8: + return DXGI_FORMAT_A8_UNORM; + case D3DFMT_A8R3G3B2: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_X4R4G4B4: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_A2B10G10R10: + return DXGI_FORMAT_R10G10B10A2_UNORM; + case D3DFMT_A8B8G8R8: + case D3DFMT_X8B8G8R8: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case D3DFMT_G16R16: + return DXGI_FORMAT_R16G16_UNORM; + case D3DFMT_A2R10G10B10: + return DXGI_FORMAT_R10G10B10A2_UNORM; + case D3DFMT_A16B16G16R16: + return DXGI_FORMAT_R16G16B16A16_UNORM; + case D3DFMT_R16F: + return DXGI_FORMAT_R16_FLOAT; + case D3DFMT_G16R16F: + return DXGI_FORMAT_R16G16_FLOAT; + case D3DFMT_A16B16G16R16F: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case D3DFMT_R32F: + return DXGI_FORMAT_R32_FLOAT; + case D3DFMT_G32R32F: + return DXGI_FORMAT_R32G32_FLOAT; + case D3DFMT_A32B32G32R32F: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + return DXGI_FORMAT_UNKNOWN; +} + + +D3DFORMAT WINAPI ConvertFormatDXGIToD3D9( DXGI_FORMAT fmt ) +{ + switch( fmt ) + { + case DXGI_FORMAT_UNKNOWN: + return D3DFMT_UNKNOWN; + case DXGI_FORMAT_R8G8B8A8_UNORM: + return D3DFMT_A8R8G8B8; + case DXGI_FORMAT_B5G6R5_UNORM: + return D3DFMT_R5G6B5; + case DXGI_FORMAT_B5G5R5A1_UNORM: + return D3DFMT_A1R5G5B5; + case DXGI_FORMAT_A8_UNORM: + return D3DFMT_A8; + case DXGI_FORMAT_R10G10B10A2_UNORM: + return D3DFMT_A2B10G10R10; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return D3DFMT_A8B8G8R8; + case DXGI_FORMAT_R16G16_UNORM: + return D3DFMT_G16R16; + case DXGI_FORMAT_R16G16B16A16_UNORM: + return D3DFMT_A16B16G16R16; + case DXGI_FORMAT_R16_FLOAT: + return D3DFMT_R16F; + case DXGI_FORMAT_R16G16_FLOAT: + return D3DFMT_G16R16F; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return D3DFMT_A16B16G16R16F; + case DXGI_FORMAT_R32_FLOAT: + return D3DFMT_R32F; + case DXGI_FORMAT_R32G32_FLOAT: + return D3DFMT_G32R32F; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return D3DFMT_A32B32G32R32F; + } + return D3DFMT_UNKNOWN; +} + +//-------------------------------------------------------------------------------------- +IDirect3DDevice9* WINAPI DXUTCreateRefDevice9( HWND hWnd, bool bNullRef ) +{ + HRESULT hr; + IDirect3D9* pD3D = DXUT_Dynamic_Direct3DCreate9( D3D_SDK_VERSION ); + if( NULL == pD3D ) + return NULL; + + D3DDISPLAYMODE Mode; + pD3D->GetAdapterDisplayMode( 0, &Mode ); + + D3DPRESENT_PARAMETERS pp; + ZeroMemory( &pp, sizeof( D3DPRESENT_PARAMETERS ) ); + pp.BackBufferWidth = 1; + pp.BackBufferHeight = 1; + pp.BackBufferFormat = Mode.Format; + pp.BackBufferCount = 1; + pp.SwapEffect = D3DSWAPEFFECT_COPY; + pp.Windowed = TRUE; + pp.hDeviceWindow = hWnd; + + IDirect3DDevice9* pd3dDevice = NULL; + hr = pD3D->CreateDevice( D3DADAPTER_DEFAULT, bNullRef ? D3DDEVTYPE_NULLREF : D3DDEVTYPE_REF, + hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &pd3dDevice ); + + SAFE_RELEASE( pD3D ); + return pd3dDevice; +} + + +//-------------------------------------------------------------------------------------- +// Helper function to launch the Media Center UI after the program terminates +//-------------------------------------------------------------------------------------- +bool DXUTReLaunchMediaCenter() +{ + // Get the path to Media Center + WCHAR szExpandedPath[MAX_PATH]; + if( !ExpandEnvironmentStrings( L"%SystemRoot%\\ehome\\ehshell.exe", szExpandedPath, MAX_PATH ) ) + return false; + + // Skip if ehshell.exe doesn't exist + if( GetFileAttributes( szExpandedPath ) == 0xFFFFFFFF ) + return false; + + // Launch ehshell.exe + INT_PTR result = ( INT_PTR )ShellExecute( NULL, TEXT( "open" ), szExpandedPath, NULL, NULL, SW_SHOWNORMAL ); + return ( result > 32 ); +} + +typedef DWORD ( WINAPI* LPXINPUTGETSTATE )( DWORD dwUserIndex, XINPUT_STATE* pState ); +typedef DWORD ( WINAPI* LPXINPUTSETSTATE )( DWORD dwUserIndex, XINPUT_VIBRATION* pVibration ); +typedef DWORD ( WINAPI* LPXINPUTGETCAPABILITIES )( DWORD dwUserIndex, DWORD dwFlags, + XINPUT_CAPABILITIES* pCapabilities ); +typedef void ( WINAPI* LPXINPUTENABLE )( BOOL bEnable ); + +//-------------------------------------------------------------------------------------- +// Does extra processing on XInput data to make it slightly more convenient to use +//-------------------------------------------------------------------------------------- +HRESULT DXUTGetGamepadState( DWORD dwPort, DXUT_GAMEPAD* pGamePad, bool bThumbstickDeadZone, + bool bSnapThumbstickToCardinals ) +{ + if( dwPort >= DXUT_MAX_CONTROLLERS || pGamePad == NULL ) + return E_FAIL; + + static LPXINPUTGETSTATE s_pXInputGetState = NULL; + static LPXINPUTGETCAPABILITIES s_pXInputGetCapabilities = NULL; + if( NULL == s_pXInputGetState || NULL == s_pXInputGetCapabilities ) + { + HINSTANCE hInst = LoadLibrary( XINPUT_DLL ); + if( hInst ) + { + s_pXInputGetState = ( LPXINPUTGETSTATE )GetProcAddress( hInst, "XInputGetState" ); + s_pXInputGetCapabilities = ( LPXINPUTGETCAPABILITIES )GetProcAddress( hInst, "XInputGetCapabilities" ); + } + } + if( s_pXInputGetState == NULL ) + return E_FAIL; + + XINPUT_STATE InputState; + DWORD dwResult = s_pXInputGetState( dwPort, &InputState ); + + // Track insertion and removals + BOOL bWasConnected = pGamePad->bConnected; + pGamePad->bConnected = ( dwResult == ERROR_SUCCESS ); + pGamePad->bRemoved = ( bWasConnected && !pGamePad->bConnected ); + pGamePad->bInserted = ( !bWasConnected && pGamePad->bConnected ); + + // Don't update rest of the state if not connected + if( !pGamePad->bConnected ) + return S_OK; + + // Store the capabilities of the device + if( pGamePad->bInserted ) + { + ZeroMemory( pGamePad, sizeof( DXUT_GAMEPAD ) ); + pGamePad->bConnected = true; + pGamePad->bInserted = true; + if( s_pXInputGetCapabilities ) + s_pXInputGetCapabilities( dwPort, XINPUT_DEVTYPE_GAMEPAD, &pGamePad->caps ); + } + + // Copy gamepad to local structure (assumes that XINPUT_GAMEPAD at the front in CONTROLER_STATE) + memcpy( pGamePad, &InputState.Gamepad, sizeof( XINPUT_GAMEPAD ) ); + + if( bSnapThumbstickToCardinals ) + { + // Apply deadzone to each axis independantly to slightly snap to up/down/left/right + if( pGamePad->sThumbLX < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLX > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) + pGamePad->sThumbLX = 0; + if( pGamePad->sThumbLY < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLY > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) + pGamePad->sThumbLY = 0; + if( pGamePad->sThumbRX < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRX > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) + pGamePad->sThumbRX = 0; + if( pGamePad->sThumbRY < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRY > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) + pGamePad->sThumbRY = 0; + } + else if( bThumbstickDeadZone ) + { + // Apply deadzone if centered + if( ( pGamePad->sThumbLX < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLX > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) && + ( pGamePad->sThumbLY < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLY > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) ) + { + pGamePad->sThumbLX = 0; + pGamePad->sThumbLY = 0; + } + if( ( pGamePad->sThumbRX < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRX > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) && + ( pGamePad->sThumbRY < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRY > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) ) + { + pGamePad->sThumbRX = 0; + pGamePad->sThumbRY = 0; + } + } + + // Convert [-1,+1] range + pGamePad->fThumbLX = pGamePad->sThumbLX / 32767.0f; + pGamePad->fThumbLY = pGamePad->sThumbLY / 32767.0f; + pGamePad->fThumbRX = pGamePad->sThumbRX / 32767.0f; + pGamePad->fThumbRY = pGamePad->sThumbRY / 32767.0f; + + // Get the boolean buttons that have been pressed since the last call. + // Each button is represented by one bit. + pGamePad->wPressedButtons = ( pGamePad->wLastButtons ^ pGamePad->wButtons ) & pGamePad->wButtons; + pGamePad->wLastButtons = pGamePad->wButtons; + + // Figure out if the left trigger has been pressed or released + bool bPressed = ( pGamePad->bLeftTrigger > DXUT_GAMEPAD_TRIGGER_THRESHOLD ); + pGamePad->bPressedLeftTrigger = ( bPressed ) ? !pGamePad->bLastLeftTrigger : false; + pGamePad->bLastLeftTrigger = bPressed; + + // Figure out if the right trigger has been pressed or released + bPressed = ( pGamePad->bRightTrigger > DXUT_GAMEPAD_TRIGGER_THRESHOLD ); + pGamePad->bPressedRightTrigger = ( bPressed ) ? !pGamePad->bLastRightTrigger : false; + pGamePad->bLastRightTrigger = bPressed; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Don't pause the game or deactive the window without first stopping rumble otherwise +// the controller will continue to rumble +//-------------------------------------------------------------------------------------- +void DXUTEnableXInput( bool bEnable ) +{ + static LPXINPUTENABLE s_pXInputEnable = NULL; + if( NULL == s_pXInputEnable ) + { + HINSTANCE hInst = LoadLibrary( XINPUT_DLL ); + if( hInst ) + s_pXInputEnable = ( LPXINPUTENABLE )GetProcAddress( hInst, "XInputEnable" ); + } + + if( s_pXInputEnable ) + s_pXInputEnable( bEnable ); +} + + +//-------------------------------------------------------------------------------------- +// Don't pause the game or deactive the window without first stopping rumble otherwise +// the controller will continue to rumble +//-------------------------------------------------------------------------------------- +HRESULT DXUTStopRumbleOnAllControllers() +{ + static LPXINPUTSETSTATE s_pXInputSetState = NULL; + if( NULL == s_pXInputSetState ) + { + HINSTANCE hInst = LoadLibrary( XINPUT_DLL ); + if( hInst ) + s_pXInputSetState = ( LPXINPUTSETSTATE )GetProcAddress( hInst, "XInputSetState" ); + } + if( s_pXInputSetState == NULL ) + return E_FAIL; + + XINPUT_VIBRATION vibration; + vibration.wLeftMotorSpeed = 0; + vibration.wRightMotorSpeed = 0; + for( int iUserIndex = 0; iUserIndex < DXUT_MAX_CONTROLLERS; iUserIndex++ ) + s_pXInputSetState( iUserIndex, &vibration ); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +// Helper functions to create SRGB formats from typeless formats and vice versa +//-------------------------------------------------------------------------------------- +DXGI_FORMAT MAKE_SRGB( DXGI_FORMAT format ) +{ + if( !DXUTIsInGammaCorrectMode() ) + return format; + + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_UNORM_SRGB; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_UNORM_SRGB; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_UNORM_SRGB; + + }; + + return format; +} + +//-------------------------------------------------------------------------------------- +DXGI_FORMAT MAKE_TYPELESS( DXGI_FORMAT format ) +{ + if( !DXUTIsInGammaCorrectMode() ) + return format; + + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + return DXGI_FORMAT_R8G8B8A8_TYPELESS; + + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_TYPELESS; + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_TYPELESS; + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_TYPELESS; + }; + + return format; +} + +//-------------------------------------------------------------------------------------- +HRESULT DXUTSnapD3D9Screenshot( LPCTSTR szFileName ) +{ + HRESULT hr = S_OK; + IDirect3DDevice9* pDev = DXUTGetD3D9Device(); + if( !pDev ) + return E_FAIL; + + IDirect3DSurface9* pBackBuffer = NULL; + V_RETURN( pDev->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ) ); + + return D3DXSaveSurfaceToFile( szFileName, D3DXIFF_BMP, pBackBuffer, NULL, NULL ); +} + + + + +//-------------------------------------------------------------------------------------- +HRESULT DXUTSnapD3D11Screenshot( LPCTSTR szFileName, D3DX11_IMAGE_FILE_FORMAT iff ) +{ + IDXGISwapChain *pSwap = DXUTGetDXGISwapChain(); + + if (!pSwap) + return E_FAIL; + + ID3D11Texture2D* pBackBuffer; + HRESULT hr = pSwap->GetBuffer( 0, __uuidof( *pBackBuffer ), ( LPVOID* )&pBackBuffer ); + if (hr != S_OK) + return hr; + + ID3D11DeviceContext *dc = DXUTGetD3D11DeviceContext(); + if (!dc) { + SAFE_RELEASE(pBackBuffer); + return E_FAIL; + } + ID3D11Device *pDevice = DXUTGetD3D11Device(); + if (!dc) { + SAFE_RELEASE(pBackBuffer); + return E_FAIL; + } + + D3D11_TEXTURE2D_DESC dsc; + pBackBuffer->GetDesc(&dsc); + D3D11_RESOURCE_DIMENSION dim; + pBackBuffer->GetType(&dim); + // special case msaa textures + ID3D11Texture2D *pCompatableTexture = pBackBuffer; + if ( dsc.SampleDesc.Count > 1) { + D3D11_TEXTURE2D_DESC dsc_new = dsc; + dsc_new.SampleDesc.Count = 1; + dsc_new.SampleDesc.Quality = 0; + dsc_new.Usage = D3D11_USAGE_DEFAULT; + dsc_new.BindFlags = 0; + dsc_new.CPUAccessFlags = 0; + ID3D11Texture2D *resolveTexture; + hr = pDevice->CreateTexture2D(&dsc_new, NULL, &resolveTexture); + dc->ResolveSubresource(resolveTexture, 0, pBackBuffer, 0, dsc.Format); + pCompatableTexture = resolveTexture; + pCompatableTexture->GetDesc(&dsc); + } + + hr = D3DX11SaveTextureToFileW(dc, pCompatableTexture, iff, szFileName); + + + SAFE_RELEASE(pBackBuffer); + SAFE_RELEASE(pCompatableTexture); + + return hr; + +} diff --git a/Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.h b/Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.h new file mode 100644 index 0000000..74ac064 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/DXUTmisc.h @@ -0,0 +1,594 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTMisc.h +// +// Helper functions for Direct3D programming. +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_MISC_H +#define DXUT_MISC_H + +#ifndef MAX_FVF_DECL_SIZE +#define MAX_FVF_DECL_SIZE MAXD3DDECLLENGTH + 1 // +1 for END +#endif + +//-------------------------------------------------------------------------------------- +// XInput helper state/function +// This performs extra processing on XInput gamepad data to make it slightly more convenient to use +// +// Example usage: +// +// DXUT_GAMEPAD gamepad[4]; +// for( DWORD iPort=0; iPort class CGrowableArray +{ +public: + CGrowableArray() { m_pData = NULL; m_nSize = 0; m_nMaxSize = 0; } + CGrowableArray( const CGrowableArray& a ) { for( int i=0; i < a.m_nSize; i++ ) Add( a.m_pData[i] ); } + ~CGrowableArray() { RemoveAll(); } + + const TYPE& operator[]( int nIndex ) const { return GetAt( nIndex ); } + TYPE& operator[]( int nIndex ) { return GetAt( nIndex ); } + + CGrowableArray& operator=( const CGrowableArray& a ) { if( this == &a ) return *this; RemoveAll(); for( int i=0; i < a.m_nSize; i++ ) Add( a.m_pData[i] ); return *this; } + + HRESULT SetSize( int nNewMaxSize ); + HRESULT Add( const TYPE& value ); + HRESULT Insert( int nIndex, const TYPE& value ); + HRESULT SetAt( int nIndex, const TYPE& value ); + TYPE& GetAt( int nIndex ) const { assert( nIndex >= 0 && nIndex < m_nSize ); return m_pData[nIndex]; } + int GetSize() const { return m_nSize; } + TYPE* GetData() { return m_pData; } + bool Contains( const TYPE& value ){ return ( -1 != IndexOf( value ) ); } + + int IndexOf( const TYPE& value ) { return ( m_nSize > 0 ) ? IndexOf( value, 0, m_nSize ) : -1; } + int IndexOf( const TYPE& value, int iStart ) { return IndexOf( value, iStart, m_nSize - iStart ); } + int IndexOf( const TYPE& value, int nIndex, int nNumElements ); + + int LastIndexOf( const TYPE& value ) { return ( m_nSize > 0 ) ? LastIndexOf( value, m_nSize-1, m_nSize ) : -1; } + int LastIndexOf( const TYPE& value, int nIndex ) { return LastIndexOf( value, nIndex, nIndex+1 ); } + int LastIndexOf( const TYPE& value, int nIndex, int nNumElements ); + + HRESULT Remove( int nIndex ); + void RemoveAll() { SetSize(0); } + void Reset() { m_nSize = 0; } + +protected: + TYPE* m_pData; // the actual array of data + int m_nSize; // # of elements (upperBound - 1) + int m_nMaxSize; // max allocated + + HRESULT SetSizeInternal( int nNewMaxSize ); // This version doesn't call ctor or dtor. +}; + + +//-------------------------------------------------------------------------------------- +// Performs timer operations +// Use DXUTGetGlobalTimer() to get the global instance +//-------------------------------------------------------------------------------------- +class CDXUTTimer +{ +public: + CDXUTTimer(); + + void Reset(); // resets the timer + void Start(); // starts the timer + void Stop(); // stop (or pause) the timer + void Advance(); // advance the timer by 0.1 seconds + double GetAbsoluteTime(); // get the absolute system time + double GetTime(); // get the current time + float GetElapsedTime(); // get the time that elapsed between Get*ElapsedTime() calls + void GetTimeValues( double* pfTime, double* pfAbsoluteTime, float* pfElapsedTime ); // get all time values at once + bool IsStopped(); // returns true if timer stopped + + // Limit the current thread to one processor (the current one). This ensures that timing code runs + // on only one processor, and will not suffer any ill effects from power management. + void LimitThreadAffinityToCurrentProc(); + +protected: + LARGE_INTEGER GetAdjustedCurrentTime(); + + bool m_bUsingQPF; + bool m_bTimerStopped; + LONGLONG m_llQPFTicksPerSec; + + LONGLONG m_llStopTime; + LONGLONG m_llLastElapsedTime; + LONGLONG m_llBaseTime; +}; + +CDXUTTimer* WINAPI DXUTGetGlobalTimer(); + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given D3DFORMAT. +// bWithPrefix determines whether the string should include the "D3DFMT_" +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTD3DFormatToString( D3DFORMAT format, bool bWithPrefix ); + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given DXGI_FORMAT. +// bWithPrefix determines whether the string should include the "DXGI_FORMAT_" +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTDXGIFormatToString( DXGI_FORMAT format, bool bWithPrefix ); + + +//-------------------------------------------------------------------------------------- +// Device settings conversion +//-------------------------------------------------------------------------------------- +void WINAPI DXUTConvertDeviceSettings11to9( DXUTD3D11DeviceSettings* pIn, DXUTD3D9DeviceSettings* pOut ); +void WINAPI DXUTConvertDeviceSettings9to11( DXUTD3D9DeviceSettings* pIn, DXUTD3D11DeviceSettings* pOut ); + +DXGI_FORMAT WINAPI ConvertFormatD3D9ToDXGI( D3DFORMAT fmt ); +D3DFORMAT WINAPI ConvertFormatDXGIToD3D9( DXGI_FORMAT fmt ); + + +//-------------------------------------------------------------------------------------- +// Debug printing support +// See dxerr.h for more debug printing support +//-------------------------------------------------------------------------------------- +void WINAPI DXUTOutputDebugStringW( LPCWSTR strMsg, ... ); +void WINAPI DXUTOutputDebugStringA( LPCSTR strMsg, ... ); +HRESULT WINAPI DXUTTrace( const CHAR* strFile, DWORD dwLine, HRESULT hr, const WCHAR* strMsg, bool bPopMsgBox ); +void WINAPI DXUTTraceDecl( D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE] ); +WCHAR* WINAPI DXUTTraceD3DDECLUSAGEtoString( BYTE u ); +WCHAR* WINAPI DXUTTraceD3DDECLMETHODtoString( BYTE m ); +WCHAR* WINAPI DXUTTraceD3DDECLTYPEtoString( BYTE t ); +WCHAR* WINAPI DXUTTraceWindowsMessage( UINT uMsg ); + +#ifdef UNICODE +#define DXUTOutputDebugString DXUTOutputDebugStringW +#else +#define DXUTOutputDebugString DXUTOutputDebugStringA +#endif + +// These macros are very similar to dxerr's but it special cases the HRESULT defined +// by DXUT to pop better message boxes. +#if defined(DEBUG) || defined(_DEBUG) +#define DXUT_ERR(str,hr) DXUTTrace( __FILE__, (DWORD)__LINE__, hr, str, false ) +#define DXUT_ERR_MSGBOX(str,hr) DXUTTrace( __FILE__, (DWORD)__LINE__, hr, str, true ) +#define DXUTTRACE DXUTOutputDebugString +#else +#define DXUT_ERR(str,hr) (hr) +#define DXUT_ERR_MSGBOX(str,hr) (hr) +#define DXUTTRACE (__noop) +#endif + + +//-------------------------------------------------------------------------------------- +// Direct3D9 dynamic linking support -- calls top-level D3D9 APIs with graceful +// failure if APIs are not present. +//-------------------------------------------------------------------------------------- + +IDirect3D9 * WINAPI DXUT_Dynamic_Direct3DCreate9(UINT SDKVersion); +int WINAPI DXUT_Dynamic_D3DPERF_BeginEvent( D3DCOLOR col, LPCWSTR wszName ); +int WINAPI DXUT_Dynamic_D3DPERF_EndEvent( void ); +void WINAPI DXUT_Dynamic_D3DPERF_SetMarker( D3DCOLOR col, LPCWSTR wszName ); +void WINAPI DXUT_Dynamic_D3DPERF_SetRegion( D3DCOLOR col, LPCWSTR wszName ); +BOOL WINAPI DXUT_Dynamic_D3DPERF_QueryRepeatFrame( void ); +void WINAPI DXUT_Dynamic_D3DPERF_SetOptions( DWORD dwOptions ); +DWORD WINAPI DXUT_Dynamic_D3DPERF_GetStatus( void ); +HRESULT WINAPI DXUT_Dynamic_CreateDXGIFactory1( REFIID rInterface, void** ppOut ); + +HRESULT WINAPI DXUT_Dynamic_D3D11CreateDevice( IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT32 Flags, + D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT32 SDKVersion, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext ); + +bool DXUT_EnsureD3D11APIs( void ); + + +//-------------------------------------------------------------------------------------- +// Profiling/instrumentation support +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +// Some D3DPERF APIs take a color that can be used when displaying user events in +// performance analysis tools. The following constants are provided for your +// convenience, but you can use any colors you like. +//-------------------------------------------------------------------------------------- +const D3DCOLOR DXUT_PERFEVENTCOLOR = D3DCOLOR_XRGB( 200, 100, 100 ); +const D3DCOLOR DXUT_PERFEVENTCOLOR2 = D3DCOLOR_XRGB( 100, 200, 100 ); +const D3DCOLOR DXUT_PERFEVENTCOLOR3 = D3DCOLOR_XRGB( 100, 100, 200 ); + +//-------------------------------------------------------------------------------------- +// The following macros provide a convenient way for your code to call the D3DPERF +// functions only when PROFILE is defined. If PROFILE is not defined (as for the final +// release version of a program), these macros evaluate to nothing, so no detailed event +// information is embedded in your shipping program. It is recommended that you create +// and use three build configurations for your projects: +// Debug (nonoptimized code, asserts active, PROFILE defined to assist debugging) +// Profile (optimized code, asserts disabled, PROFILE defined to assist optimization) +// Release (optimized code, asserts disabled, PROFILE not defined) +//-------------------------------------------------------------------------------------- +#ifdef PROFILE +// PROFILE is defined, so these macros call the D3DPERF functions +#define DXUT_BeginPerfEvent( color, pstrMessage ) DXUT_Dynamic_D3DPERF_BeginEvent( color, pstrMessage ) +#define DXUT_EndPerfEvent() DXUT_Dynamic_D3DPERF_EndEvent() +#define DXUT_SetPerfMarker( color, pstrMessage ) DXUT_Dynamic_D3DPERF_SetMarker( color, pstrMessage ) +#else +// PROFILE is not defined, so these macros do nothing +#define DXUT_BeginPerfEvent( color, pstrMessage ) (__noop) +#define DXUT_EndPerfEvent() (__noop) +#define DXUT_SetPerfMarker( color, pstrMessage ) (__noop) +#endif + +//-------------------------------------------------------------------------------------- +// CDXUTPerfEventGenerator is a helper class that makes it easy to attach begin and end +// events to a block of code. Simply define a CDXUTPerfEventGenerator variable anywhere +// in a block of code, and the class's constructor will call DXUT_BeginPerfEvent when +// the block of code begins, and the class's destructor will call DXUT_EndPerfEvent when +// the block ends. +//-------------------------------------------------------------------------------------- +class CDXUTPerfEventGenerator +{ +public: +CDXUTPerfEventGenerator( D3DCOLOR color, LPCWSTR pstrMessage ) +{ + DXUT_BeginPerfEvent( color, pstrMessage ); +} +~CDXUTPerfEventGenerator( void ) +{ + DXUT_EndPerfEvent(); +} +}; + + +//-------------------------------------------------------------------------------------- +// Multimon handling to support OSes with or without multimon API support. +// Purposely avoiding the use of multimon.h so DXUT.lib doesn't require +// COMPILE_MULTIMON_STUBS and cause complication with MFC or other users of multimon.h +//-------------------------------------------------------------------------------------- +#ifndef MONITOR_DEFAULTTOPRIMARY +#define MONITORINFOF_PRIMARY 0x00000001 +#define MONITOR_DEFAULTTONULL 0x00000000 +#define MONITOR_DEFAULTTOPRIMARY 0x00000001 +#define MONITOR_DEFAULTTONEAREST 0x00000002 +typedef struct tagMONITORINFO +{ + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; +} MONITORINFO, *LPMONITORINFO; +typedef struct tagMONITORINFOEXW : public tagMONITORINFO +{ + WCHAR szDevice[CCHDEVICENAME]; +} MONITORINFOEXW, *LPMONITORINFOEXW; +typedef MONITORINFOEXW MONITORINFOEX; +typedef LPMONITORINFOEXW LPMONITORINFOEX; +#endif + +HMONITOR WINAPI DXUTMonitorFromWindow( HWND hWnd, DWORD dwFlags ); +HMONITOR WINAPI DXUTMonitorFromRect( LPCRECT lprcScreenCoords, DWORD dwFlags ); +BOOL WINAPI DXUTGetMonitorInfo( HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo ); +void WINAPI DXUTGetDesktopResolution( UINT AdapterOrdinal, UINT* pWidth, UINT* pHeight ); + + +//-------------------------------------------------------------------------------------- +// Implementation of CGrowableArray +//-------------------------------------------------------------------------------------- + +// This version doesn't call ctor or dtor. +template HRESULT CGrowableArray ::SetSizeInternal( int nNewMaxSize ) +{ + if( nNewMaxSize < 0 || ( nNewMaxSize > INT_MAX / sizeof( TYPE ) ) ) + { + assert( false ); + return E_INVALIDARG; + } + + if( nNewMaxSize == 0 ) + { + // Shrink to 0 size & cleanup + if( m_pData ) + { + free( m_pData ); + m_pData = NULL; + } + + m_nMaxSize = 0; + m_nSize = 0; + } + else if( m_pData == NULL || nNewMaxSize > m_nMaxSize ) + { + // Grow array + int nGrowBy = ( m_nMaxSize == 0 ) ? 16 : m_nMaxSize; + + // Limit nGrowBy to keep m_nMaxSize less than INT_MAX + if( ( UINT )m_nMaxSize + ( UINT )nGrowBy > ( UINT )INT_MAX ) + nGrowBy = INT_MAX - m_nMaxSize; + + nNewMaxSize = __max( nNewMaxSize, m_nMaxSize + nGrowBy ); + + // Verify that (nNewMaxSize * sizeof(TYPE)) is not greater than UINT_MAX or the realloc will overrun + if( sizeof( TYPE ) > UINT_MAX / ( UINT )nNewMaxSize ) + return E_INVALIDARG; + + TYPE* pDataNew = ( TYPE* )realloc( m_pData, nNewMaxSize * sizeof( TYPE ) ); + if( pDataNew == NULL ) + return E_OUTOFMEMORY; + + m_pData = pDataNew; + m_nMaxSize = nNewMaxSize; + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +template HRESULT CGrowableArray ::SetSize( int nNewMaxSize ) +{ + int nOldSize = m_nSize; + + if( nOldSize > nNewMaxSize ) + { + assert( m_pData ); + if( m_pData ) + { + // Removing elements. Call dtor. + + for( int i = nNewMaxSize; i < nOldSize; ++i ) + m_pData[i].~TYPE(); + } + } + + // Adjust buffer. Note that there's no need to check for error + // since if it happens, nOldSize == nNewMaxSize will be true.) + HRESULT hr = SetSizeInternal( nNewMaxSize ); + + if( nOldSize < nNewMaxSize ) + { + assert( m_pData ); + if( m_pData ) + { + // Adding elements. Call ctor. + + for( int i = nOldSize; i < nNewMaxSize; ++i ) + ::new ( &m_pData[i] ) TYPE; + } + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +template HRESULT CGrowableArray ::Add( const TYPE& value ) +{ + HRESULT hr; + if( FAILED( hr = SetSizeInternal( m_nSize + 1 ) ) ) + return hr; + + // Construct the new element + ::new ( &m_pData[m_nSize] ) TYPE; + + // Assign + m_pData[m_nSize] = value; + ++m_nSize; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +template HRESULT CGrowableArray ::Insert( int nIndex, const TYPE& value ) +{ + HRESULT hr; + + // Validate index + if( nIndex < 0 || + nIndex > m_nSize ) + { + assert( false ); + return E_INVALIDARG; + } + + // Prepare the buffer + if( FAILED( hr = SetSizeInternal( m_nSize + 1 ) ) ) + return hr; + + // Shift the array + MoveMemory( &m_pData[nIndex + 1], &m_pData[nIndex], sizeof( TYPE ) * ( m_nSize - nIndex ) ); + + // Construct the new element + ::new ( &m_pData[nIndex] ) TYPE; + + // Set the value and increase the size + m_pData[nIndex] = value; + ++m_nSize; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +template HRESULT CGrowableArray ::SetAt( int nIndex, const TYPE& value ) +{ + // Validate arguments + if( nIndex < 0 || + nIndex >= m_nSize ) + { + assert( false ); + return E_INVALIDARG; + } + + m_pData[nIndex] = value; + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Searches for the specified value and returns the index of the first occurrence +// within the section of the data array that extends from iStart and contains the +// specified number of elements. Returns -1 if value is not found within the given +// section. +//-------------------------------------------------------------------------------------- +template int CGrowableArray ::IndexOf( const TYPE& value, int iStart, int nNumElements ) +{ + // Validate arguments + if( iStart < 0 || + iStart >= m_nSize || + nNumElements < 0 || + iStart + nNumElements > m_nSize ) + { + assert( false ); + return -1; + } + + // Search + for( int i = iStart; i < ( iStart + nNumElements ); i++ ) + { + if( value == m_pData[i] ) + return i; + } + + // Not found + return -1; +} + + +//-------------------------------------------------------------------------------------- +// Searches for the specified value and returns the index of the last occurrence +// within the section of the data array that contains the specified number of elements +// and ends at iEnd. Returns -1 if value is not found within the given section. +//-------------------------------------------------------------------------------------- +template int CGrowableArray ::LastIndexOf( const TYPE& value, int iEnd, int nNumElements ) +{ + // Validate arguments + if( iEnd < 0 || + iEnd >= m_nSize || + nNumElements < 0 || + iEnd - nNumElements < 0 ) + { + assert( false ); + return -1; + } + + // Search + for( int i = iEnd; i > ( iEnd - nNumElements ); i-- ) + { + if( value == m_pData[i] ) + return i; + } + + // Not found + return -1; +} + + + +//-------------------------------------------------------------------------------------- +template HRESULT CGrowableArray ::Remove( int nIndex ) +{ + if( nIndex < 0 || + nIndex >= m_nSize ) + { + assert( false ); + return E_INVALIDARG; + } + + // Destruct the element to be removed + m_pData[nIndex].~TYPE(); + + // Compact the array and decrease the size + MoveMemory( &m_pData[nIndex], &m_pData[nIndex + 1], sizeof( TYPE ) * ( m_nSize - ( nIndex + 1 ) ) ); + --m_nSize; + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +// Creates a REF or NULLREF D3D9 device and returns that device. The caller should call +// Release() when done with the device. +//-------------------------------------------------------------------------------------- +IDirect3DDevice9* WINAPI DXUTCreateRefDevice9( HWND hWnd, bool bNullRef = true ); + +//-------------------------------------------------------------------------------------- +// Creates a REF or NULLREF D3D10 device and returns the device. The caller should call +// Release() when done with the device. +//-------------------------------------------------------------------------------------- +//test d3d10 version ID3D10Device* WINAPI DXUTCreateRefDevice10( bool bNullRef = true ); + +//-------------------------------------------------------------------------------------- +// Helper function to launch the Media Center UI after the program terminates +//-------------------------------------------------------------------------------------- +bool DXUTReLaunchMediaCenter(); + +//-------------------------------------------------------------------------------------- +// Helper functions to create SRGB formats from typeless formats and vice versa +//-------------------------------------------------------------------------------------- +DXGI_FORMAT MAKE_SRGB( DXGI_FORMAT format ); +DXGI_FORMAT MAKE_TYPELESS( DXGI_FORMAT format ); + +#endif diff --git a/Demos/DX11ClothDemo/DXUT/Core/dpiaware.manifest b/Demos/DX11ClothDemo/DXUT/Core/dpiaware.manifest new file mode 100644 index 0000000..3d5eccc --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Core/dpiaware.manifest @@ -0,0 +1,7 @@ + + + + true + + + \ No newline at end of file diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTLockFreePipe.h b/Demos/DX11ClothDemo/DXUT/Optional/DXUTLockFreePipe.h new file mode 100644 index 0000000..ed10747 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTLockFreePipe.h @@ -0,0 +1,227 @@ +//-------------------------------------------------------------------------------------- +// DXUTLockFreePipe.h +// +// See the "Lockless Programming Considerations for Xbox 360 and Microsoft Windows" +// article in the DirectX SDK for more details. +// +// http://msdn2.microsoft.com/en-us/library/bb310595.aspx +// +// XNA Developer Connection +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once + +#include + +#ifdef _XBOX_VER + // Prevent the CPU from rearranging loads + // and stores, sufficiently for read-acquire + // and write-release. + #define DXUTImportBarrier __lwsync + #define DXUTExportBarrier __lwsync +#else + #pragma pack(push) + #pragma pack(8) + #include + #pragma pack (pop) + + extern "C" + void _ReadWriteBarrier(); + #pragma intrinsic(_ReadWriteBarrier) + + // Prevent the compiler from rearranging loads + // and stores, sufficiently for read-acquire + // and write-release. This is sufficient on + // x86 and x64. + #define DXUTImportBarrier _ReadWriteBarrier + #define DXUTExportBarrier _ReadWriteBarrier +#endif + +// +// Pipe class designed for use by at most two threads: one reader, one writer. +// Access by more than two threads isn't guaranteed to be safe. +// +// In order to provide efficient access the size of the buffer is passed +// as a template parameter and restricted to powers of two less than 31. +// + +template class DXUTLockFreePipe +{ +public: + DXUTLockFreePipe() : m_readOffset( 0 ), + m_writeOffset( 0 ) + { + } + + DWORD GetBufferSize() const + { + return c_cbBufferSize; + } + + __forceinline unsigned long BytesAvailable() const + { + return m_writeOffset - m_readOffset; + } + + bool __forceinline Read( void* pvDest, unsigned long cbDest ) + { + // Store the read and write offsets into local variables--this is + // essentially a snapshot of their values so that they stay constant + // for the duration of the function (and so we don't end up with cache + // misses due to false sharing). + DWORD readOffset = m_readOffset; + DWORD writeOffset = m_writeOffset; + + // Compare the two offsets to see if we have anything to read. + // Note that we don't do anything to synchronize the offsets here. + // Really there's not much we *can* do unless we're willing to completely + // synchronize access to the entire object. We have to assume that as we + // read, someone else may be writing, and the write offset we have now + // may be out of date by the time we read it. Fortunately that's not a + // very big deal. We might miss reading some data that was just written. + // But the assumption is that we'll be back before long to grab more data + // anyway. + // + // Note that this comparison works because we're careful to constrain + // the total buffer size to be a power of 2, which means it will divide + // evenly into ULONG_MAX+1. That, and the fact that the offsets are + // unsigned, means that the calculation returns correct results even + // when the values wrap around. + DWORD cbAvailable = writeOffset - readOffset; + if( cbDest > cbAvailable ) + { + return false; + } + + // The data has been made available, but we need to make sure + // that our view on the data is up to date -- at least as up to + // date as the control values we just read. We need to prevent + // the compiler or CPU from moving any of the data reads before + // the control value reads. This import barrier serves this + // purpose, on Xbox 360 and on Windows. + + // Reading a control value and then having a barrier is known + // as a "read-acquire." + DXUTImportBarrier(); + + unsigned char* pbDest = ( unsigned char* )pvDest; + + unsigned long actualReadOffset = readOffset & c_sizeMask; + unsigned long bytesLeft = cbDest; + + // + // Copy from the tail, then the head. Note that there's no explicit + // check to see if the write offset comes between the read offset + // and the end of the buffer--that particular condition is implicitly + // checked by the comparison with AvailableToRead(), above. If copying + // cbDest bytes off the tail would cause us to cross the write offset, + // then the previous comparison would have failed since that would imply + // that there were less than cbDest bytes available to read. + // + unsigned long cbTailBytes = min( bytesLeft, c_cbBufferSize - actualReadOffset ); + memcpy( pbDest, m_pbBuffer + actualReadOffset, cbTailBytes ); + bytesLeft -= cbTailBytes; + + if( bytesLeft ) + { + memcpy( pbDest + cbTailBytes, m_pbBuffer, bytesLeft ); + } + + // When we update the read offset we are, effectively, 'freeing' buffer + // memory so that the writing thread can use it. We need to make sure that + // we don't free the memory before we have finished reading it. That is, + // we need to make sure that the write to m_readOffset can't get reordered + // above the reads of the buffer data. The only way to guarantee this is to + // have an export barrier to prevent both compiler and CPU rearrangements. + DXUTExportBarrier(); + + // Advance the read offset. From the CPUs point of view this is several + // operations--read, modify, store--and we'd normally want to make sure that + // all of the operations happened atomically. But in the case of a single + // reader, only one thread updates this value and so the only operation that + // must be atomic is the store. That's lucky, because 32-bit aligned stores are + // atomic on all modern processors. + // + readOffset += cbDest; + m_readOffset = readOffset; + + return true; + } + + bool __forceinline Write( const void* pvSrc, unsigned long cbSrc ) + { + // Reading the read offset here has the same caveats as reading + // the write offset had in the Read() function above. + DWORD readOffset = m_readOffset; + DWORD writeOffset = m_writeOffset; + + // Compute the available write size. This comparison relies on + // the fact that the buffer size is always a power of 2, and the + // offsets are unsigned integers, so that when the write pointer + // wraps around the subtraction still yields a value (assuming + // we haven't messed up somewhere else) between 0 and c_cbBufferSize - 1. + DWORD cbAvailable = c_cbBufferSize - ( writeOffset - readOffset ); + if( cbSrc > cbAvailable ) + { + return false; + } + + // It is theoretically possible for writes of the data to be reordered + // above the reads to see if the data is available. Improbable perhaps, + // but possible. This barrier guarantees that the reordering will not + // happen. + DXUTImportBarrier(); + + // Write the data + const unsigned char* pbSrc = ( const unsigned char* )pvSrc; + unsigned long actualWriteOffset = writeOffset & c_sizeMask; + unsigned long bytesLeft = cbSrc; + + // See the explanation in the Read() function as to why we don't + // explicitly check against the read offset here. + unsigned long cbTailBytes = min( bytesLeft, c_cbBufferSize - actualWriteOffset ); + memcpy( m_pbBuffer + actualWriteOffset, pbSrc, cbTailBytes ); + bytesLeft -= cbTailBytes; + + if( bytesLeft ) + { + memcpy( m_pbBuffer, pbSrc + cbTailBytes, bytesLeft ); + } + + // Now it's time to update the write offset, but since the updated position + // of the write offset will imply that there's data to be read, we need to + // make sure that the data all actually gets written before the update to + // the write offset. The writes could be reordered by the compiler (on any + // platform) or by the CPU (on Xbox 360). We need a barrier which prevents + // the writes from being reordered past each other. + // + // Having a barrier and then writing a control value is called "write-release." + DXUTExportBarrier(); + + // See comments in Read() as to why this operation isn't interlocked. + writeOffset += cbSrc; + m_writeOffset = writeOffset; + + return true; + } + +private: + // Values derived from the buffer size template parameter + // + const static BYTE c_cbBufferSizeLog2 = min( cbBufferSizeLog2, 31 ); + const static DWORD c_cbBufferSize = ( 1 << c_cbBufferSizeLog2 ); + const static DWORD c_sizeMask = c_cbBufferSize - 1; + + // Leave these private and undefined to prevent their use + DXUTLockFreePipe( const DXUTLockFreePipe& ); + DXUTLockFreePipe& operator =( const DXUTLockFreePipe& ); + + // Member data + // + BYTE m_pbBuffer[c_cbBufferSize]; + // Note that these offsets are not clamped to the buffer size. + // Instead the calculations rely on wrapping at ULONG_MAX+1. + // See the comments in Read() for details. + volatile DWORD __declspec( align( 4 ) ) m_readOffset; + volatile DWORD __declspec( align( 4 ) ) m_writeOffset; +}; \ No newline at end of file diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.cpp b/Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.cpp new file mode 100644 index 0000000..9084926 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.cpp @@ -0,0 +1,5663 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTShapes.cpp +// +// Shape creation functions for DXUT +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#include "DXUTShapes.h" + + +//-------------------------------------------------------------------------------------- +// VERTEX is the vertex layout for all DXUT created shapes +//-------------------------------------------------------------------------------------- +struct VERTEX +{ + D3DXVECTOR3 pos; + D3DXVECTOR3 norm; +}; + +static const D3D10_INPUT_ELEMENT_DESC s_ShapeLayout[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }, +}; + + +//-------------------------------------------------------------------------------------- +static inline void sincosf( float angle, float* psin, float* pcos ) +{ + *psin = sinf( angle ); + *pcos = cosf( angle ); +} + + +//-------------------------------------------------------------------------------------- +// Create D3DX10Mesh from the input vertex and index data +//-------------------------------------------------------------------------------------- +HRESULT CreateShapeMesh( ID3D10Device* pDev10, ID3DX10Mesh** ppMesh, VERTEX* pVertices, UINT NumVertices, + WORD* pIndices, UINT NumIndices ) +{ + HRESULT hr = S_OK; + + // Create the mesh + hr = D3DX10CreateMesh( pDev10, + s_ShapeLayout, + sizeof( s_ShapeLayout ) / sizeof( s_ShapeLayout[0] ), + s_ShapeLayout[0].SemanticName, + NumVertices, + NumIndices / 3, + 0, + ppMesh ); + if( FAILED( hr ) ) + return hr; + + // Set the Vertex Data + ( *ppMesh )->SetVertexData( 0, pVertices ); + + // Set the Index Data + ( *ppMesh )->SetIndexData( pIndices, NumIndices ); + + // Set attributes + DWORD dwNumAttr = 1; + D3DX10_ATTRIBUTE_RANGE* pAttr = new D3DX10_ATTRIBUTE_RANGE[dwNumAttr]; + if( !pAttr ) + return E_OUTOFMEMORY; + + pAttr[0].AttribId = 0; + pAttr[0].FaceStart = 0; + pAttr[0].FaceCount = NumIndices / 3; + pAttr[0].VertexStart = 0; + pAttr[0].VertexCount = NumVertices; + ( *ppMesh )->SetAttributeTable( pAttr, dwNumAttr ); + SAFE_DELETE_ARRAY( pAttr ); + + // Create the internal mesh VBs and IBs + ( *ppMesh )->CommitToDevice(); + + return hr; +} + + +//---------------------------------------------------------------------------- +// Box +//---------------------------------------------------------------------------- +static float cubeN[6][3] = +{ + {-1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, + {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f} +}; + +static WORD cubeF[6][4] = +{ + { 0, 1, 5, 4 }, { 4, 5, 6, 7 }, { 7, 6, 2, 3 }, + { 1, 0, 3, 2 }, { 1, 2, 6, 5 }, { 0, 4, 7, 3 } +}; + +static float cubeV[8][3] = +{ + // Lower tier (lower in y) + {-.5f, -.5f, -.5f}, + {-.5f, -.5f, .5f}, + { .5f, -.5f, .5f}, + { .5f, -.5f, -.5f}, + + // Upper tier + {-.5f, .5f, -.5f}, + {-.5f, .5f, .5f}, + { .5f, .5f, .5f}, + { .5f, .5f, -.5f}, +}; + +static float cubeT[4][2] = +{ + // Lower tier (lower in y) + {0.0f, 0.0f}, + {0.0f, 1.0f}, + {1.0f, 1.0f}, + {1.0f, 0.0f} +}; + +static WORD cubeFT[6][4] = +{ + { 3, 0, 1, 2 }, { 0, 1, 2, 3 }, { 1, 2, 3, 0 }, + { 0, 1, 2, 3 }, { 3, 0, 1, 2 }, { 0, 1, 2, 3 } +}; + + +//-------------------------------------------------------------------------------------- +// MakeBox helper +//-------------------------------------------------------------------------------------- +static void MakeBox( +VERTEX* pVertices, +DWORD* pPointRep, +WORD* pwIndices, +float fWidth, +float fHeight, +float fDepth ) +{ + // Fill in the data + VERTEX* pVertex = pVertices; + WORD* pwFace = pwIndices; + UINT iVertex = 0; + + // i iterates over the faces, 2 triangles per face + for( int i = 0; i < 6; i++ ) + { + for( int j = 0; j < 4; j++ ) + { + pVertex->pos.x = cubeV[cubeF[i][j]][0] * fWidth; + pVertex->pos.y = cubeV[cubeF[i][j]][1] * fHeight; + pVertex->pos.z = cubeV[cubeF[i][j]][2] * fDepth; + + pVertex->norm.x = cubeN[i][0]; + pVertex->norm.y = cubeN[i][1]; + pVertex->norm.z = cubeN[i][2]; + + if( pPointRep != NULL ) + { + *pPointRep = cubeF[i][j]; + pPointRep++; + } + + pVertex++; + } + + pwFace[0] = ( WORD )( iVertex ); + pwFace[1] = ( WORD )( iVertex + 1 ); + pwFace[2] = ( WORD )( iVertex + 2 ); + pwFace += 3; + + pwFace[0] = ( WORD )( iVertex + 2 ); + pwFace[1] = ( WORD )( iVertex + 3 ); + pwFace[2] = ( WORD )( iVertex ); + pwFace += 3; + + iVertex += 4; + } +} + + +//-------------------------------------------------------------------------------------- +// DXUTCreateBox - create a box mesh +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateBox( ID3D10Device* pDevice, float fWidth, float fHeight, float fDepth, ID3DX10Mesh** ppMesh ) +{ + HRESULT hr = S_OK; + + WORD* pwIndices = NULL; + VERTEX* pVertices = NULL; + + // Set up the defaults + if( D3DX_DEFAULT_FLOAT == fWidth ) + fWidth = 1.0f; + if( D3DX_DEFAULT_FLOAT == fHeight ) + fHeight = 1.0f; + if( D3DX_DEFAULT_FLOAT == fDepth ) + fDepth = 1.0f; + + + // Validate parameters + if( !pDevice ) + return D3DERR_INVALIDCALL; + if( !ppMesh ) + return D3DERR_INVALIDCALL; + if( fWidth < 0.0f ) + return D3DERR_INVALIDCALL; + if( fHeight < 0.0f ) + return D3DERR_INVALIDCALL; + if( fDepth < 0.0f ) + return D3DERR_INVALIDCALL; + + // Create the mesh + UINT cFaces = 12; + UINT cVertices = 24; + + // Create enough memory for the vertices and indices + pVertices = new VERTEX[ cVertices ]; + if( !pVertices ) + return E_OUTOFMEMORY; + pwIndices = new WORD[ cFaces * 3 ]; + if( !pwIndices ) + return E_OUTOFMEMORY; + + // Create a box + MakeBox( pVertices, NULL, pwIndices, fWidth, fHeight, fDepth ); + + // Create a mesh + hr = CreateShapeMesh( pDevice, ppMesh, pVertices, cVertices, pwIndices, cFaces * 3 ); + + // Free up the memory + SAFE_DELETE_ARRAY( pVertices ); + SAFE_DELETE_ARRAY( pwIndices ); + + return hr; + +} + +#define CACHE_SIZE 240 + +//---------------------------------------------------------------------------- +// MakeCylinder helper +//---------------------------------------------------------------------------- +static void MakeCylinder( +VERTEX* pVertices, +DWORD* pPointReps, +WORD* pwIndices, +float fRadius1, +float fRadius2, +float fLength, +UINT uSlices, +UINT uStacks ) +{ + UINT i, j; + + // Sin/Cos caches + float sinI[CACHE_SIZE], cosI[CACHE_SIZE]; + + for( i = 0; i < uSlices; i++ ) + sincosf( 2.0f * D3DX_PI * i / uSlices, sinI + i, cosI + i ); + + + // Compute side normal angle + float fDeltaRadius = fRadius2 - fRadius1; + float fSideLength = sqrtf( fDeltaRadius * fDeltaRadius + fLength * fLength ); + + float fNormalXY = ( fSideLength > 0.00001f ) ? ( fLength / fSideLength ) : 1.0f; + float fNormalZ = ( fSideLength > 0.00001f ) ? ( -fDeltaRadius / fSideLength ) : 0.0f; + + + + // Generate vertices + VERTEX* pVertex = pVertices; + float fZ, fRadius; + DWORD iVertex; + + // Base cap (uSlices + 1) + fZ = fLength * -0.5f; + fRadius = fRadius1; + iVertex = 0; + + pVertex->pos = D3DXVECTOR3( 0.0f, 0.0f, fZ ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, -1.0f ); + pVertex++; + if( pPointReps != NULL ) + pPointReps[iVertex] = iVertex; + iVertex++; + + for( i = 0; i < uSlices; i++ ) + { + pVertex->pos = D3DXVECTOR3( fRadius * sinI[i], fRadius * cosI[i], fZ ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, -1.0f ); + pVertex++; + + // link into stack vertices, which follow + if( pPointReps != NULL ) + pPointReps[iVertex] = iVertex + uSlices; + iVertex++; + } + + // Stacks ((uStacks + 1)*uSlices) + for( j = 0; j <= uStacks; j++ ) + { + float f = ( float )j / ( float )uStacks; + + fZ = fLength * ( f - 0.5f ); + fRadius = fRadius1 + f * fDeltaRadius; + + for( i = 0; i < uSlices; i++ ) + { + pVertex->pos = D3DXVECTOR3( fRadius * sinI[i], fRadius * cosI[i], fZ ); + pVertex->norm = D3DXVECTOR3( fNormalXY * sinI[i], fNormalXY * cosI[i], fNormalZ ); + pVertex++; + if( pPointReps != NULL ) + pPointReps[iVertex] = iVertex; + iVertex++; + } + } + + // Top cap (uSlices + 1) + fZ = fLength * 0.5f; + fRadius = fRadius2; + + for( i = 0; i < uSlices; i++ ) + { + pVertex->pos = D3DXVECTOR3( fRadius * sinI[i], fRadius * cosI[i], fZ ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + pVertex++; + + // link into stack vertices, which precede + if( pPointReps != NULL ) + pPointReps[iVertex] = iVertex - uSlices; + iVertex++; + } + + pVertex->pos = D3DXVECTOR3( 0.0f, 0.0f, fZ ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + pVertex++; + if( pPointReps != NULL ) + pPointReps[iVertex] = iVertex; + iVertex++; + + + + // Generate indices + WORD* pwFace = pwIndices; + UINT uRowA, uRowB; + + // Z+ pole (uSlices) + uRowA = 0; + uRowB = 1; + + for( i = 0; i < uSlices - 1; i++ ) + { + pwFace[0] = ( WORD )( uRowA ); + pwFace[1] = ( WORD )( uRowB + i ); + pwFace[2] = ( WORD )( uRowB + i + 1 ); + pwFace += 3; + } + + pwFace[0] = ( WORD )( uRowA ); + pwFace[1] = ( WORD )( uRowB + i ); + pwFace[2] = ( WORD )( uRowB ); + pwFace += 3; + + // Interior stacks (uStacks * uSlices * 2) + for( j = 0; j < uStacks; j++ ) + { + uRowA = 1 + ( j + 1 ) * uSlices; + uRowB = uRowA + uSlices; + + for( i = 0; i < uSlices - 1; i++ ) + { + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowB + i ); + pwFace[2] = ( WORD )( uRowA + i + 1 ); + pwFace += 3; + + pwFace[0] = ( WORD )( uRowA + i + 1 ); + pwFace[1] = ( WORD )( uRowB + i ); + pwFace[2] = ( WORD )( uRowB + i + 1 ); + pwFace += 3; + } + + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowB + i ); + pwFace[2] = ( WORD )( uRowA ); + pwFace += 3; + + pwFace[0] = ( WORD )( uRowA ); + pwFace[1] = ( WORD )( uRowB + i ); + pwFace[2] = ( WORD )( uRowB ); + pwFace += 3; + } + + // Z- pole (uSlices) + uRowA = 1 + ( uStacks + 2 ) * uSlices; + uRowB = uRowA + uSlices; + + for( i = 0; i < uSlices - 1; i++ ) + { + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowB ); + pwFace[2] = ( WORD )( uRowA + i + 1 ); + pwFace += 3; + } + + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowB ); + pwFace[2] = ( WORD )( uRowA ); + pwFace += 3; +} + + +//---------------------------------------------------------------------------- +// DXUTCreateCylinder - create a cylinder mesh +//---------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateCylinder( ID3D10Device* pDevice, float fRadius1, float fRadius2, float fLength, UINT uSlices, + UINT uStacks, ID3DX10Mesh** ppMesh ) +{ + HRESULT hr = S_OK; + + WORD* pwIndices = NULL; + VERTEX* pVertices = NULL; + + // Set up the defaults + if( D3DX_DEFAULT_FLOAT == fRadius1 ) + fRadius1 = 1.0f; + if( D3DX_DEFAULT_FLOAT == fRadius2 ) + fRadius2 = 1.0f; + if( D3DX_DEFAULT_FLOAT == fLength ) + fLength = 1.0f; + if( D3DX_DEFAULT == uSlices ) + uSlices = 8; + if( D3DX_DEFAULT == uStacks ) + uStacks = 8; + + + // Validate parameters + if( !pDevice ) + return D3DERR_INVALIDCALL; + if( !ppMesh ) + return D3DERR_INVALIDCALL; + if( fRadius1 < 0.0f ) + return D3DERR_INVALIDCALL; + if( fRadius2 < 0.0f ) + return D3DERR_INVALIDCALL; + if( fLength < 0.0f ) + return D3DERR_INVALIDCALL; + if( uSlices < 2 ) + return D3DERR_INVALIDCALL; + if( uStacks < 1 ) + return D3DERR_INVALIDCALL; + if( uSlices >= CACHE_SIZE ) + uSlices = CACHE_SIZE - 1; + + // Create the mesh + UINT cFaces = ( uStacks + 1 ) * uSlices * 2; + UINT cVertices = 2 + ( uStacks + 3 ) * uSlices; + + // Create enough memory for the vertices and indices + pVertices = new VERTEX[ cVertices ]; + if( !pVertices ) + return E_OUTOFMEMORY; + pwIndices = new WORD[ cFaces * 3 ]; + if( !pwIndices ) + return E_OUTOFMEMORY; + + // Create a cylinder + MakeCylinder( pVertices, NULL, pwIndices, fRadius1, fRadius2, + fLength, uSlices, uStacks ); + + // Create a mesh + hr = CreateShapeMesh( pDevice, ppMesh, pVertices, cVertices, pwIndices, cFaces * 3 ); + + // Free up the memory + SAFE_DELETE_ARRAY( pVertices ); + SAFE_DELETE_ARRAY( pwIndices ); + + return hr; +} + + +//-------------------------------------------------------------------------------------- +// MakePolygon helper +//-------------------------------------------------------------------------------------- +static void MakePolygon( VERTEX* pVertices, + WORD* pwIndices, + float fLength, + UINT uSides ) +{ + // Calculate the radius + float radius = fLength * 0.5f / sinf( D3DX_PI / ( float )uSides ); + float angle = ( float )( 2.0f * D3DX_PI / ( float )uSides ); + + // Fill in vertices + VERTEX* pVertex = pVertices; + + pVertex->pos = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + pVertex++; + + for( UINT j = 0; j < uSides; j++ ) + { + float s, c; + sincosf( angle * j, &s, &c ); + + pVertex->pos = D3DXVECTOR3( c * radius, s * radius, 0.0f ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + pVertex++; + } + + // Fill in indices + WORD* pwFace = pwIndices; + + UINT iFace; + for( iFace = 0; iFace < uSides - 1; iFace++ ) + { + pwFace[0] = 0; + pwFace[1] = ( WORD )iFace + 1; + pwFace[2] = ( WORD )iFace + 2; + + pwFace += 3; + } + + // handle the wrapping of the last case + pwFace[0] = 0; + pwFace[1] = ( WORD )iFace + 1; + pwFace[2] = 1; +} + + +//---------------------------------------------------------------------------- +// DXUTCreatePolygon - create a polygon mesh +//---------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreatePolygon( ID3D10Device* pDevice, float fLength, UINT uSides, ID3DX10Mesh** ppMesh ) +{ + HRESULT hr = S_OK; + WORD* pwIndices = NULL; + VERTEX* pVertices = NULL; + + // Set up the defaults + if( D3DX_DEFAULT == uSides ) + uSides = 3; + if( D3DX_DEFAULT_FLOAT == fLength ) + fLength = 1.0f; + + + // Validate parameters + if( !pDevice ) + return D3DERR_INVALIDCALL; + if( !ppMesh ) + return D3DERR_INVALIDCALL; + if( fLength < 0.0f ) + return D3DERR_INVALIDCALL; + if( uSides < 3 ) + return D3DERR_INVALIDCALL; + + // Create the mesh + UINT cFaces = uSides; + UINT cVertices = uSides + 1; + + // Create enough memory for the vertices and indices + pVertices = new VERTEX[ cVertices ]; + if( !pVertices ) + return E_OUTOFMEMORY; + pwIndices = new WORD[ cFaces * 3 ]; + if( !pwIndices ) + return E_OUTOFMEMORY; + + // Create a polygon + MakePolygon( pVertices, pwIndices, fLength, uSides ); + + // Create a mesh + hr = CreateShapeMesh( pDevice, ppMesh, pVertices, cVertices, pwIndices, cFaces * 3 ); + + // Free up the memory + SAFE_DELETE_ARRAY( pVertices ); + SAFE_DELETE_ARRAY( pwIndices ); + + return hr; +} + + +//--------------------------------------------------------------------- +// MakeSphere helper +//--------------------------------------------------------------------- +static void MakeSphere( +VERTEX* pVertices, +WORD* pwIndices, +float fRadius, +UINT uSlices, +UINT uStacks ) +{ + UINT i, j; + + + // Sin/Cos caches + float sinI[CACHE_SIZE], cosI[CACHE_SIZE]; + float sinJ[CACHE_SIZE], cosJ[CACHE_SIZE]; + + for( i = 0; i < uSlices; i++ ) + sincosf( 2.0f * D3DX_PI * i / uSlices, sinI + i, cosI + i ); + + for( j = 0; j < uStacks; j++ ) + sincosf( D3DX_PI * j / uStacks, sinJ + j, cosJ + j ); + + + + // Generate vertices + VERTEX* pVertex = pVertices; + + // +Z pole + pVertex->pos = D3DXVECTOR3( 0.0f, 0.0f, fRadius ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + pVertex++; + + // Stacks + for( j = 1; j < uStacks; j++ ) + { + for( i = 0; i < uSlices; i++ ) + { + D3DXVECTOR3 norm( sinI[i]* sinJ[j], cosI[i]* sinJ[j], cosJ[j] ); + + pVertex->pos = norm * fRadius; + pVertex->norm = norm; + + pVertex++; + } + } + + // Z- pole + pVertex->pos = D3DXVECTOR3( 0.0f, 0.0f, -fRadius ); + pVertex->norm = D3DXVECTOR3( 0.0f, 0.0f, -1.0f ); + pVertex++; + + + + // Generate indices + WORD* pwFace = pwIndices; + UINT uRowA, uRowB; + + // Z+ pole + uRowA = 0; + uRowB = 1; + + for( i = 0; i < uSlices - 1; i++ ) + { + pwFace[0] = ( WORD )( uRowA ); + pwFace[1] = ( WORD )( uRowB + i + 1 ); + pwFace[2] = ( WORD )( uRowB + i ); + pwFace += 3; + } + + pwFace[0] = ( WORD )( uRowA ); + pwFace[1] = ( WORD )( uRowB ); + pwFace[2] = ( WORD )( uRowB + i ); + pwFace += 3; + + // Interior stacks + for( j = 1; j < uStacks - 1; j++ ) + { + uRowA = 1 + ( j - 1 ) * uSlices; + uRowB = uRowA + uSlices; + + for( i = 0; i < uSlices - 1; i++ ) + { + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowA + i + 1 ); + pwFace[2] = ( WORD )( uRowB + i ); + pwFace += 3; + + pwFace[0] = ( WORD )( uRowA + i + 1 ); + pwFace[1] = ( WORD )( uRowB + i + 1 ); + pwFace[2] = ( WORD )( uRowB + i ); + pwFace += 3; + } + + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowA ); + pwFace[2] = ( WORD )( uRowB + i ); + pwFace += 3; + + pwFace[0] = ( WORD )( uRowA ); + pwFace[1] = ( WORD )( uRowB ); + pwFace[2] = ( WORD )( uRowB + i ); + pwFace += 3; + } + + // Z- pole + uRowA = 1 + ( uStacks - 2 ) * uSlices; + uRowB = uRowA + uSlices; + + for( i = 0; i < uSlices - 1; i++ ) + { + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowA + i + 1 ); + pwFace[2] = ( WORD )( uRowB ); + pwFace += 3; + } + + pwFace[0] = ( WORD )( uRowA + i ); + pwFace[1] = ( WORD )( uRowA ); + pwFace[2] = ( WORD )( uRowB ); + pwFace += 3; +} + + +//---------------------------------------------------------------------------- +// DXUTCreateSphere - create a sphere mesh +//---------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateSphere( ID3D10Device* pDevice, float fRadius, UINT uSlices, UINT uStacks, + ID3DX10Mesh** ppMesh ) +{ + HRESULT hr = S_OK; + + WORD* pwIndices = NULL; + VERTEX* pVertices = NULL; + + // Set up the defaults + if( D3DX_DEFAULT_FLOAT == fRadius ) + fRadius = 1.0f; + if( D3DX_DEFAULT == uSlices ) + uSlices = 8; + if( D3DX_DEFAULT == uStacks ) + uStacks = 8; + + // Validate parameters + if( !pDevice ) + return D3DERR_INVALIDCALL; + if( !ppMesh ) + return D3DERR_INVALIDCALL; + if( fRadius < 0.0f ) + return D3DERR_INVALIDCALL; + if( uSlices < 2 ) + return D3DERR_INVALIDCALL; + if( uStacks < 2 ) + return D3DERR_INVALIDCALL; + + if( uSlices > CACHE_SIZE ) + uSlices = CACHE_SIZE; + if( uStacks > CACHE_SIZE ) + uStacks = CACHE_SIZE; + + // Create the mesh + UINT cFaces = 2 * ( uStacks - 1 ) * uSlices; + UINT cVertices = ( uStacks - 1 ) * uSlices + 2; + + // Create enough memory for the vertices and indices + pVertices = new VERTEX[ cVertices ]; + if( !pVertices ) + return E_OUTOFMEMORY; + pwIndices = new WORD[ cFaces * 3 ]; + if( !pwIndices ) + return E_OUTOFMEMORY; + + // Create a sphere + MakeSphere( pVertices, pwIndices, fRadius, uSlices, uStacks ); + + // Create a mesh + hr = CreateShapeMesh( pDevice, ppMesh, pVertices, cVertices, pwIndices, cFaces * 3 ); + + // Free up the memory + SAFE_DELETE_ARRAY( pVertices ); + SAFE_DELETE_ARRAY( pwIndices ); + + return hr; +} + + +//--------------------------------------------------------------------- +// MakeTorus helper +//--------------------------------------------------------------------- +static void MakeTorus( +VERTEX* pVertices, +WORD* pwIndices, +float fInnerRadius, +float fOuterRadius, +UINT uSides, +UINT uRings ) +{ + UINT i, j; + + // + // Compute the vertices + // + + VERTEX* pVertex = pVertices; + + for( i = 0; i < uRings; i++ ) + { + float theta = ( float )i * 2.0f * D3DX_PI / ( float )uRings; + float st, ct; + + sincosf( theta, &st, &ct ); + + for( j = 0; j < uSides; j++ ) + { + float phi = ( float )j * 2.0f * D3DX_PI / uSides; + float sp, cp; + + sincosf( phi, &sp, &cp ); + + pVertex->pos.x = ct * ( fOuterRadius + fInnerRadius * cp ); + pVertex->pos.y = -st * ( fOuterRadius + fInnerRadius * cp ); + pVertex->pos.z = sp * fInnerRadius; + + pVertex->norm.x = ct * cp; + pVertex->norm.y = -st * cp; + pVertex->norm.z = sp; + + pVertex++; + } + } + + // + // Compute the indices: + // There are uRings * uSides faces + // Each face has 2 triangles (6 indices) + // + + // Tube i has indices: + // Left Edge: i*(uSides+1) -- i*(uSides+1)+uSides + // Right Edge: (i+1)*(uSides+1) -- (i+1)*(uSides+1)+uSides + // + // Face j on tube i has the 4 indices: + // Left Edge: i*(uSides+1)+j -- i*(uSides+1)+j+1 + // Right Edge: (i+1)*(uSides+1)+j -- (i+1)*(uSides+1)+j+1 + // + WORD* pwFace = pwIndices; + + for( i = 0; i < uRings - 1; i++ ) + { + for( j = 0; j < uSides - 1; j++ ) + { + + // Tri 1 (Top-Left tri, CCW) + pwFace[0] = ( WORD )( i * uSides + j ); + pwFace[1] = ( WORD )( i * uSides + j + 1 ); + pwFace[2] = ( WORD )( ( i + 1 ) * uSides + j ); + pwFace += 3; + + // Tri 2 (Bottom-Right tri, CCW) + pwFace[0] = ( WORD )( ( i + 1 ) * uSides + j ); + pwFace[1] = ( WORD )( i * uSides + j + 1 ); + pwFace[2] = ( WORD )( ( i + 1 ) * uSides + j + 1 ); + pwFace += 3; + } + + // Tri 1 (Top-Left tri, CCW) + pwFace[0] = ( WORD )( i * uSides + j ); + pwFace[1] = ( WORD )( i * uSides ); + pwFace[2] = ( WORD )( ( i + 1 ) * uSides + j ); + pwFace += 3; + + // Tri 2 (Bottom-Right tri, CCW) + pwFace[0] = ( WORD )( ( i + 1 ) * uSides + j ); + pwFace[1] = ( WORD )( i * uSides + 0 ); + pwFace[2] = ( WORD )( ( i + 1 ) * uSides + 0 ); + pwFace += 3; + } + + + // join the two ends of the tube + for( j = 0; j < uSides - 1; j++ ) + { + // Tri 1 (Top-Left tri, CCW) + pwFace[0] = ( WORD )( i * uSides + j ); + pwFace[1] = ( WORD )( i * uSides + j + 1 ); + pwFace[2] = ( WORD )( j ); + pwFace += 3; + + // Tri 2 (Bottom-Right tri, CCW) + pwFace[0] = ( WORD )( j ); + pwFace[1] = ( WORD )( i * uSides + j + 1 ); + pwFace[2] = ( WORD )( j + 1 ); + pwFace += 3; + } + + // Tri 1 (Top-Left tri, CCW) + pwFace[0] = ( WORD )( i * uSides + j ); + pwFace[1] = ( WORD )( i * uSides ); + pwFace[2] = ( WORD )( j ); + pwFace += 3; + + // Tri 2 (Bottom-Right tri, CCW) + pwFace[0] = ( WORD )( j ); + pwFace[1] = ( WORD )( i * uSides ); + pwFace[2] = ( WORD )( 0 ); + pwFace += 3; +} + + +//---------------------------------------------------------------------------- +// DXUTCreateTorus - create a torus mesh +//---------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateTorus( ID3D10Device* pDevice, float fInnerRadius, float fOuterRadius, UINT uSides, + UINT uRings, ID3DX10Mesh** ppMesh ) +{ + HRESULT hr = S_OK; + + WORD* pwIndices = NULL; + VERTEX* pVertices = NULL; + + + // Set up the defaults + if( D3DX_DEFAULT_FLOAT == fInnerRadius ) + fInnerRadius = 1.0f; + if( D3DX_DEFAULT_FLOAT == fOuterRadius ) + fOuterRadius = 2.0f; + if( D3DX_DEFAULT == uSides ) + uSides = 8; + if( D3DX_DEFAULT == uRings ) + uRings = 15; + + // Validate parameters + if( !pDevice ) + return D3DERR_INVALIDCALL; + if( !ppMesh ) + return D3DERR_INVALIDCALL; + if( fInnerRadius < 0.0f ) + return D3DERR_INVALIDCALL; + if( fOuterRadius < 0.0f ) + return D3DERR_INVALIDCALL; + if( uSides < 3 ) + return D3DERR_INVALIDCALL; + if( uRings < 3 ) + return D3DERR_INVALIDCALL; + + // Create the mesh + UINT cFaces = 2 * uSides * uRings; + UINT cVertices = uRings * uSides; + + // Create enough memory for the vertices and indices + pVertices = new VERTEX[ cVertices ]; + if( !pVertices ) + return E_OUTOFMEMORY; + pwIndices = new WORD[ cFaces * 3 ]; + if( !pwIndices ) + return E_OUTOFMEMORY; + + // Create a torus + MakeTorus( pVertices, pwIndices, fInnerRadius, fOuterRadius, + uSides, uRings ); + + // Create a mesh + hr = CreateShapeMesh( pDevice, ppMesh, pVertices, cVertices, pwIndices, cFaces * 3 ); + + // Free up the memory + SAFE_DELETE_ARRAY( pVertices ); + SAFE_DELETE_ARRAY( pwIndices ); + + return hr; +} + + +//---------------------------------------------------------------------------- +// Teapot data +//---------------------------------------------------------------------------- +#define NUMTEAPOTVERTICES 1178 +#define NUMTEAPOTINDICES 6768 + +static float teapotPositionsFloats[NUMTEAPOTVERTICES*3] = +{ + 0.678873f, 0.330678f, 0.000000f, + 0.669556f, 0.358022f, 0.000000f, + 0.671003f, 0.374428f, 0.000000f, + 0.680435f, 0.379897f, 0.000000f, + 0.695077f, 0.374428f, 0.000000f, + 0.712148f, 0.358022f, 0.000000f, + 0.728873f, 0.330678f, 0.000000f, + 0.654243f, 0.330678f, 0.187963f, + 0.645254f, 0.358022f, 0.185461f, + 0.646650f, 0.374428f, 0.185850f, + 0.655751f, 0.379897f, 0.188383f, + 0.669877f, 0.374428f, 0.192314f, + 0.686348f, 0.358022f, 0.196898f, + 0.702484f, 0.330678f, 0.201389f, + 0.584502f, 0.330678f, 0.355704f, + 0.576441f, 0.358022f, 0.350969f, + 0.577693f, 0.374428f, 0.351704f, + 0.585854f, 0.379897f, 0.356498f, + 0.598522f, 0.374428f, 0.363938f, + 0.613292f, 0.358022f, 0.372613f, + 0.627762f, 0.330678f, 0.381111f, + 0.475873f, 0.330678f, 0.497000f, + 0.469258f, 0.358022f, 0.490385f, + 0.470285f, 0.374428f, 0.491412f, + 0.476982f, 0.379897f, 0.498109f, + 0.487377f, 0.374428f, 0.508505f, + 0.499498f, 0.358022f, 0.520626f, + 0.511373f, 0.330678f, 0.532500f, + 0.334576f, 0.330678f, 0.605630f, + 0.329842f, 0.358022f, 0.597569f, + 0.330577f, 0.374428f, 0.598820f, + 0.335370f, 0.379897f, 0.606982f, + 0.342810f, 0.374428f, 0.619649f, + 0.351485f, 0.358022f, 0.634419f, + 0.359984f, 0.330678f, 0.648889f, + 0.166836f, 0.330678f, 0.675370f, + 0.164334f, 0.358022f, 0.666381f, + 0.164722f, 0.374428f, 0.667777f, + 0.167255f, 0.379897f, 0.676878f, + 0.171187f, 0.374428f, 0.691004f, + 0.175771f, 0.358022f, 0.707475f, + 0.180262f, 0.330678f, 0.723611f, + -0.021127f, 0.330678f, 0.700000f, + -0.021127f, 0.358022f, 0.690683f, + -0.021127f, 0.374428f, 0.692130f, + -0.021127f, 0.379897f, 0.701563f, + -0.021127f, 0.374428f, 0.716204f, + -0.021127f, 0.358022f, 0.733276f, + -0.021127f, 0.330678f, 0.750000f, + -0.224715f, 0.330678f, 0.675370f, + -0.215631f, 0.358022f, 0.666381f, + -0.211606f, 0.374428f, 0.667777f, + -0.211463f, 0.379897f, 0.676878f, + -0.214020f, 0.374428f, 0.691004f, + -0.218098f, 0.358022f, 0.707475f, + -0.222516f, 0.330678f, 0.723611f, + -0.396831f, 0.330678f, 0.605630f, + -0.383671f, 0.358022f, 0.597569f, + -0.378758f, 0.374428f, 0.598820f, + -0.380125f, 0.379897f, 0.606982f, + -0.385806f, 0.374428f, 0.619649f, + -0.393832f, 0.358022f, 0.634419f, + -0.402238f, 0.330678f, 0.648889f, + -0.535002f, 0.330678f, 0.497000f, + -0.521278f, 0.358022f, 0.490385f, + -0.517539f, 0.374428f, 0.491412f, + -0.521346f, 0.379897f, 0.498109f, + -0.530257f, 0.374428f, 0.508505f, + -0.541831f, 0.358022f, 0.520626f, + -0.553627f, 0.330678f, 0.532500f, + -0.636757f, 0.330678f, 0.355704f, + -0.624483f, 0.358022f, 0.350969f, + -0.622910f, 0.374428f, 0.351704f, + -0.629359f, 0.379897f, 0.356498f, + -0.641146f, 0.374428f, 0.363938f, + -0.655593f, 0.358022f, 0.372613f, + -0.670016f, 0.330678f, 0.381111f, + -0.699623f, 0.330678f, 0.187963f, + -0.689317f, 0.358022f, 0.185461f, + -0.689830f, 0.374428f, 0.185850f, + -0.698396f, 0.379897f, 0.188382f, + -0.712247f, 0.374428f, 0.192314f, + -0.728617f, 0.358022f, 0.196898f, + -0.744738f, 0.330678f, 0.201389f, + -0.721127f, 0.330678f, 0.000000f, + -0.711810f, 0.358022f, 0.000000f, + -0.713257f, 0.374428f, 0.000000f, + -0.722690f, 0.379897f, 0.000000f, + -0.737331f, 0.374428f, 0.000000f, + -0.754403f, 0.358022f, 0.000000f, + -0.771127f, 0.330678f, 0.000000f, + -0.696498f, 0.330678f, -0.187963f, + -0.687508f, 0.358022f, -0.185461f, + -0.688904f, 0.374428f, -0.185850f, + -0.698005f, 0.379897f, -0.188383f, + -0.712131f, 0.374428f, -0.192314f, + -0.728602f, 0.358022f, -0.196898f, + -0.744738f, 0.330678f, -0.201389f, + -0.626757f, 0.330678f, -0.355704f, + -0.618696f, 0.358022f, -0.350969f, + -0.619948f, 0.374428f, -0.351704f, + -0.628109f, 0.379897f, -0.356498f, + -0.640776f, 0.374428f, -0.363938f, + -0.655546f, 0.358022f, -0.372613f, + -0.670016f, 0.330678f, -0.381111f, + -0.518127f, 0.330678f, -0.497000f, + -0.511512f, 0.358022f, -0.490385f, + -0.512539f, 0.374428f, -0.491412f, + -0.519237f, 0.379897f, -0.498109f, + -0.529632f, 0.374428f, -0.508505f, + -0.541753f, 0.358022f, -0.520626f, + -0.553627f, 0.330678f, -0.532500f, + -0.376831f, 0.330678f, -0.605630f, + -0.372096f, 0.358022f, -0.597569f, + -0.372832f, 0.374428f, -0.598820f, + -0.377625f, 0.379897f, -0.606982f, + -0.385065f, 0.374428f, -0.619649f, + -0.393740f, 0.358022f, -0.634419f, + -0.402238f, 0.330678f, -0.648889f, + -0.209090f, 0.330678f, -0.675370f, + -0.206588f, 0.358022f, -0.666381f, + -0.206977f, 0.374428f, -0.667777f, + -0.209510f, 0.379897f, -0.676878f, + -0.213441f, 0.374428f, -0.691004f, + -0.218025f, 0.358022f, -0.707475f, + -0.222516f, 0.330678f, -0.723611f, + -0.021127f, 0.330678f, -0.700000f, + -0.021127f, 0.358022f, -0.690683f, + -0.021127f, 0.374428f, -0.692130f, + -0.021127f, 0.379897f, -0.701563f, + -0.021127f, 0.374428f, -0.716204f, + -0.021127f, 0.358022f, -0.733276f, + -0.021127f, 0.330678f, -0.750000f, + 0.166836f, 0.330678f, -0.675370f, + 0.164334f, 0.358022f, -0.666381f, + 0.164722f, 0.374428f, -0.667777f, + 0.167255f, 0.379897f, -0.676878f, + 0.171187f, 0.374428f, -0.691004f, + 0.175771f, 0.358022f, -0.707475f, + 0.180262f, 0.330678f, -0.723611f, + 0.334576f, 0.330678f, -0.605630f, + 0.329842f, 0.358022f, -0.597569f, + 0.330577f, 0.374428f, -0.598820f, + 0.335370f, 0.379897f, -0.606982f, + 0.342810f, 0.374428f, -0.619649f, + 0.351485f, 0.358022f, -0.634419f, + 0.359984f, 0.330678f, -0.648889f, + 0.475873f, 0.330678f, -0.497000f, + 0.469258f, 0.358022f, -0.490385f, + 0.470285f, 0.374428f, -0.491412f, + 0.476982f, 0.379897f, -0.498109f, + 0.487377f, 0.374428f, -0.508505f, + 0.499498f, 0.358022f, -0.520626f, + 0.511373f, 0.330678f, -0.532500f, + 0.584502f, 0.330678f, -0.355704f, + 0.576441f, 0.358022f, -0.350969f, + 0.577693f, 0.374428f, -0.351704f, + 0.585854f, 0.379897f, -0.356498f, + 0.598522f, 0.374428f, -0.363938f, + 0.613292f, 0.358022f, -0.372613f, + 0.627762f, 0.330678f, -0.381111f, + 0.654243f, 0.330678f, -0.187963f, + 0.645254f, 0.358022f, -0.185461f, + 0.646650f, 0.374428f, -0.185850f, + 0.655751f, 0.379897f, -0.188382f, + 0.669877f, 0.374428f, -0.192314f, + 0.686348f, 0.358022f, -0.196898f, + 0.702484f, 0.330678f, -0.201389f, + 0.790794f, 0.199602f, 0.000000f, + 0.849243f, 0.069567f, 0.000000f, + 0.900748f, -0.058384f, 0.000000f, + 0.941836f, -0.183211f, 0.000000f, + 0.969035f, -0.303870f, 0.000000f, + 0.978873f, -0.419322f, 0.000000f, + 0.762227f, 0.199602f, 0.218016f, + 0.818619f, 0.069567f, 0.233711f, + 0.868312f, -0.058384f, 0.247541f, + 0.907954f, -0.183211f, 0.258573f, + 0.934196f, -0.303870f, 0.265877f, + 0.943688f, -0.419322f, 0.268519f, + 0.681335f, 0.199602f, 0.412576f, + 0.731904f, 0.069567f, 0.442277f, + 0.776465f, -0.058384f, 0.468449f, + 0.812014f, -0.183211f, 0.489328f, + 0.835546f, -0.303870f, 0.503149f, + 0.844058f, -0.419322f, 0.508148f, + 0.555337f, 0.199602f, 0.576464f, + 0.596836f, 0.069567f, 0.617963f, + 0.633404f, -0.058384f, 0.654531f, + 0.662577f, -0.183211f, 0.683704f, + 0.681888f, -0.303870f, 0.703015f, + 0.688873f, -0.419322f, 0.710000f, + 0.391449f, 0.199602f, 0.702462f, + 0.421150f, 0.069567f, 0.753032f, + 0.447322f, -0.058384f, 0.797593f, + 0.468201f, -0.183211f, 0.833141f, + 0.482022f, -0.303870f, 0.856674f, + 0.487021f, -0.419322f, 0.865185f, + 0.196889f, 0.199602f, 0.783354f, + 0.212583f, 0.069567f, 0.839746f, + 0.226413f, -0.058384f, 0.889439f, + 0.237446f, -0.183211f, 0.929081f, + 0.244750f, -0.303870f, 0.955323f, + 0.247391f, -0.419322f, 0.964815f, + -0.021127f, 0.199602f, 0.811921f, + -0.021127f, 0.069567f, 0.870370f, + -0.021127f, -0.058384f, 0.921875f, + -0.021127f, -0.183211f, 0.962963f, + -0.021127f, -0.303870f, 0.990162f, + -0.021127f, -0.419322f, 1.000000f, + -0.239143f, 0.199602f, 0.783354f, + -0.254838f, 0.069567f, 0.839746f, + -0.268668f, -0.058384f, 0.889439f, + -0.279701f, -0.183211f, 0.929081f, + -0.287004f, -0.303870f, 0.955323f, + -0.289646f, -0.419322f, 0.964815f, + -0.433704f, 0.199602f, 0.702462f, + -0.463404f, 0.069567f, 0.753032f, + -0.489576f, -0.058384f, 0.797593f, + -0.510455f, -0.183211f, 0.833141f, + -0.524276f, -0.303870f, 0.856674f, + -0.529275f, -0.419322f, 0.865185f, + -0.597591f, 0.199602f, 0.576464f, + -0.639090f, 0.069567f, 0.617963f, + -0.675658f, -0.058384f, 0.654531f, + -0.704831f, -0.183211f, 0.683704f, + -0.724142f, -0.303870f, 0.703015f, + -0.731127f, -0.419322f, 0.710000f, + -0.723589f, 0.199602f, 0.412576f, + -0.774159f, 0.069567f, 0.442277f, + -0.818720f, -0.058384f, 0.468449f, + -0.854269f, -0.183211f, 0.489328f, + -0.877801f, -0.303870f, 0.503149f, + -0.886312f, -0.419322f, 0.508148f, + -0.804481f, 0.199602f, 0.218016f, + -0.860873f, 0.069567f, 0.233711f, + -0.910566f, -0.058384f, 0.247540f, + -0.950208f, -0.183211f, 0.258573f, + -0.976450f, -0.303870f, 0.265877f, + -0.985942f, -0.419322f, 0.268518f, + -0.833049f, 0.199602f, 0.000000f, + -0.891498f, 0.069567f, 0.000000f, + -0.943002f, -0.058384f, 0.000000f, + -0.984090f, -0.183211f, 0.000000f, + -1.011289f, -0.303870f, 0.000000f, + -1.021127f, -0.419322f, 0.000000f, + -0.804481f, 0.199602f, -0.218016f, + -0.860873f, 0.069567f, -0.233711f, + -0.910566f, -0.058384f, -0.247541f, + -0.950208f, -0.183211f, -0.258573f, + -0.976450f, -0.303870f, -0.265877f, + -0.985942f, -0.419322f, -0.268519f, + -0.723589f, 0.199602f, -0.412576f, + -0.774159f, 0.069567f, -0.442277f, + -0.818720f, -0.058384f, -0.468449f, + -0.854269f, -0.183211f, -0.489328f, + -0.877801f, -0.303870f, -0.503149f, + -0.886312f, -0.419322f, -0.508148f, + -0.597591f, 0.199602f, -0.576464f, + -0.639090f, 0.069567f, -0.617963f, + -0.675658f, -0.058384f, -0.654531f, + -0.704831f, -0.183211f, -0.683704f, + -0.724142f, -0.303870f, -0.703015f, + -0.731127f, -0.419322f, -0.710000f, + -0.433704f, 0.199602f, -0.702462f, + -0.463404f, 0.069567f, -0.753032f, + -0.489576f, -0.058384f, -0.797593f, + -0.510455f, -0.183211f, -0.833141f, + -0.524276f, -0.303870f, -0.856674f, + -0.529275f, -0.419322f, -0.865185f, + -0.239143f, 0.199602f, -0.783354f, + -0.254838f, 0.069567f, -0.839746f, + -0.268668f, -0.058384f, -0.889439f, + -0.279701f, -0.183211f, -0.929081f, + -0.287004f, -0.303870f, -0.955323f, + -0.289646f, -0.419322f, -0.964815f, + -0.021127f, 0.199602f, -0.811921f, + -0.021127f, 0.069567f, -0.870370f, + -0.021127f, -0.058384f, -0.921875f, + -0.021127f, -0.183211f, -0.962963f, + -0.021127f, -0.303870f, -0.990162f, + -0.021127f, -0.419322f, -1.000000f, + 0.196889f, 0.199602f, -0.783354f, + 0.212583f, 0.069567f, -0.839746f, + 0.226413f, -0.058384f, -0.889439f, + 0.237446f, -0.183211f, -0.929081f, + 0.244750f, -0.303870f, -0.955323f, + 0.247391f, -0.419322f, -0.964815f, + 0.391449f, 0.199602f, -0.702462f, + 0.421150f, 0.069567f, -0.753032f, + 0.447322f, -0.058384f, -0.797593f, + 0.468201f, -0.183211f, -0.833141f, + 0.482022f, -0.303870f, -0.856674f, + 0.487021f, -0.419322f, -0.865185f, + 0.555337f, 0.199602f, -0.576464f, + 0.596836f, 0.069567f, -0.617963f, + 0.633404f, -0.058384f, -0.654531f, + 0.662577f, -0.183211f, -0.683704f, + 0.681888f, -0.303870f, -0.703015f, + 0.688873f, -0.419322f, -0.710000f, + 0.681335f, 0.199602f, -0.412576f, + 0.731904f, 0.069567f, -0.442277f, + 0.776465f, -0.058384f, -0.468449f, + 0.812014f, -0.183211f, -0.489328f, + 0.835546f, -0.303870f, -0.503149f, + 0.844058f, -0.419322f, -0.508148f, + 0.762227f, 0.199602f, -0.218016f, + 0.818619f, 0.069567f, -0.233711f, + 0.868312f, -0.058384f, -0.247540f, + 0.907954f, -0.183211f, -0.258573f, + 0.934196f, -0.303870f, -0.265877f, + 0.943688f, -0.419322f, -0.268518f, + 0.960354f, -0.522620f, 0.000000f, + 0.914058f, -0.608211f, 0.000000f, + 0.853873f, -0.677134f, 0.000000f, + 0.793688f, -0.730433f, 0.000000f, + 0.747391f, -0.769148f, 0.000000f, + 0.728873f, -0.794322f, 0.000000f, + 0.925821f, -0.522620f, 0.263546f, + 0.881153f, -0.608211f, 0.251115f, + 0.823086f, -0.677134f, 0.234954f, + 0.765018f, -0.730433f, 0.218793f, + 0.720351f, -0.769148f, 0.206361f, + 0.702484f, -0.794322f, 0.201389f, + 0.828036f, -0.522620f, 0.498738f, + 0.787981f, -0.608211f, 0.475213f, + 0.735910f, -0.677134f, 0.444630f, + 0.683839f, -0.730433f, 0.414047f, + 0.643784f, -0.769148f, 0.390521f, + 0.627762f, -0.794322f, 0.381111f, + 0.675725f, -0.522620f, 0.696852f, + 0.642854f, -0.608211f, 0.663981f, + 0.600123f, -0.677134f, 0.621250f, + 0.557391f, -0.730433f, 0.578519f, + 0.524521f, -0.769148f, 0.545648f, + 0.511373f, -0.794322f, 0.532500f, + 0.477611f, -0.522620f, 0.849163f, + 0.454085f, -0.608211f, 0.809108f, + 0.423502f, -0.677134f, 0.757037f, + 0.392919f, -0.730433f, 0.704966f, + 0.369394f, -0.769148f, 0.664911f, + 0.359984f, -0.794322f, 0.648889f, + 0.242419f, -0.522620f, 0.946948f, + 0.229987f, -0.608211f, 0.902281f, + 0.213826f, -0.677134f, 0.844213f, + 0.197666f, -0.730433f, 0.786145f, + 0.185234f, -0.769148f, 0.741478f, + 0.180262f, -0.794322f, 0.723611f, + -0.021127f, -0.522620f, 0.981482f, + -0.021127f, -0.608211f, 0.935185f, + -0.021127f, -0.677134f, 0.875000f, + -0.021127f, -0.730433f, 0.814815f, + -0.021127f, -0.769148f, 0.768519f, + -0.021127f, -0.794322f, 0.750000f, + -0.284673f, -0.522620f, 0.946948f, + -0.272242f, -0.608211f, 0.902281f, + -0.256081f, -0.677134f, 0.844213f, + -0.239920f, -0.730433f, 0.786145f, + -0.227489f, -0.769148f, 0.741478f, + -0.222516f, -0.794322f, 0.723611f, + -0.519865f, -0.522620f, 0.849163f, + -0.496340f, -0.608211f, 0.809108f, + -0.465757f, -0.677134f, 0.757037f, + -0.435174f, -0.730433f, 0.704966f, + -0.411649f, -0.769148f, 0.664911f, + -0.402238f, -0.794322f, 0.648889f, + -0.717979f, -0.522620f, 0.696852f, + -0.685109f, -0.608211f, 0.663981f, + -0.642377f, -0.677134f, 0.621250f, + -0.599646f, -0.730433f, 0.578519f, + -0.566775f, -0.769148f, 0.545648f, + -0.553627f, -0.794322f, 0.532500f, + -0.870290f, -0.522620f, 0.498738f, + -0.830236f, -0.608211f, 0.475213f, + -0.778164f, -0.677134f, 0.444630f, + -0.726093f, -0.730433f, 0.414047f, + -0.686038f, -0.769148f, 0.390521f, + -0.670016f, -0.794322f, 0.381111f, + -0.968075f, -0.522620f, 0.263546f, + -0.923408f, -0.608211f, 0.251115f, + -0.865340f, -0.677134f, 0.234954f, + -0.807273f, -0.730433f, 0.218793f, + -0.762605f, -0.769148f, 0.206361f, + -0.744738f, -0.794322f, 0.201389f, + -1.002609f, -0.522620f, 0.000000f, + -0.956312f, -0.608211f, 0.000000f, + -0.896127f, -0.677134f, 0.000000f, + -0.835942f, -0.730433f, 0.000000f, + -0.789646f, -0.769148f, 0.000000f, + -0.771127f, -0.794322f, 0.000000f, + -0.968075f, -0.522620f, -0.263546f, + -0.923408f, -0.608211f, -0.251115f, + -0.865340f, -0.677134f, -0.234954f, + -0.807273f, -0.730433f, -0.218793f, + -0.762605f, -0.769148f, -0.206361f, + -0.744738f, -0.794322f, -0.201389f, + -0.870290f, -0.522620f, -0.498738f, + -0.830236f, -0.608211f, -0.475213f, + -0.778164f, -0.677134f, -0.444630f, + -0.726093f, -0.730433f, -0.414047f, + -0.686038f, -0.769148f, -0.390521f, + -0.670016f, -0.794322f, -0.381111f, + -0.717979f, -0.522620f, -0.696852f, + -0.685109f, -0.608211f, -0.663981f, + -0.642377f, -0.677134f, -0.621250f, + -0.599646f, -0.730433f, -0.578519f, + -0.566775f, -0.769148f, -0.545648f, + -0.553627f, -0.794322f, -0.532500f, + -0.519865f, -0.522620f, -0.849163f, + -0.496340f, -0.608211f, -0.809108f, + -0.465757f, -0.677134f, -0.757037f, + -0.435174f, -0.730433f, -0.704966f, + -0.411648f, -0.769148f, -0.664911f, + -0.402238f, -0.794322f, -0.648889f, + -0.284673f, -0.522620f, -0.946948f, + -0.272242f, -0.608211f, -0.902281f, + -0.256081f, -0.677134f, -0.844213f, + -0.239920f, -0.730433f, -0.786145f, + -0.227489f, -0.769148f, -0.741478f, + -0.222516f, -0.794322f, -0.723611f, + -0.021127f, -0.522620f, -0.981482f, + -0.021127f, -0.608211f, -0.935185f, + -0.021127f, -0.677134f, -0.875000f, + -0.021127f, -0.730433f, -0.814815f, + -0.021127f, -0.769148f, -0.768519f, + -0.021127f, -0.794322f, -0.750000f, + 0.242419f, -0.522620f, -0.946948f, + 0.229987f, -0.608211f, -0.902281f, + 0.213827f, -0.677134f, -0.844213f, + 0.197666f, -0.730433f, -0.786145f, + 0.185234f, -0.769148f, -0.741478f, + 0.180262f, -0.794322f, -0.723611f, + 0.477611f, -0.522620f, -0.849163f, + 0.454085f, -0.608211f, -0.809108f, + 0.423502f, -0.677134f, -0.757037f, + 0.392919f, -0.730433f, -0.704966f, + 0.369394f, -0.769148f, -0.664911f, + 0.359984f, -0.794322f, -0.648889f, + 0.675725f, -0.522620f, -0.696852f, + 0.642854f, -0.608211f, -0.663981f, + 0.600123f, -0.677134f, -0.621250f, + 0.557391f, -0.730433f, -0.578519f, + 0.524521f, -0.769148f, -0.545648f, + 0.511373f, -0.794322f, -0.532500f, + 0.828036f, -0.522620f, -0.498738f, + 0.787981f, -0.608211f, -0.475213f, + 0.735910f, -0.677134f, -0.444630f, + 0.683839f, -0.730433f, -0.414047f, + 0.643784f, -0.769148f, -0.390521f, + 0.627762f, -0.794322f, -0.381111f, + 0.925821f, -0.522620f, -0.263546f, + 0.881153f, -0.608211f, -0.251115f, + 0.823086f, -0.677134f, -0.234954f, + 0.765018f, -0.730433f, -0.218793f, + 0.720351f, -0.769148f, -0.206361f, + 0.702484f, -0.794322f, -0.201389f, + 0.722796f, -0.812898f, 0.000000f, + 0.692762f, -0.830433f, 0.000000f, + 0.621060f, -0.845884f, 0.000000f, + 0.489984f, -0.858211f, 0.000000f, + 0.281824f, -0.866370f, 0.000000f, + -0.021127f, -0.869322f, 0.000000f, + 0.696621f, -0.812898f, 0.199757f, + 0.667643f, -0.830433f, 0.191692f, + 0.598465f, -0.845884f, 0.172439f, + 0.472000f, -0.858211f, 0.137243f, + 0.271165f, -0.866370f, 0.081348f, + 0.622505f, -0.812898f, 0.378023f, + 0.596519f, -0.830433f, 0.362761f, + 0.534484f, -0.845884f, 0.326326f, + 0.421079f, -0.858211f, 0.259720f, + 0.240982f, -0.866370f, 0.153944f, + 0.507059f, -0.812898f, 0.528186f, + 0.485734f, -0.830433f, 0.506861f, + 0.434826f, -0.845884f, 0.455953f, + 0.341762f, -0.858211f, 0.362889f, + 0.193968f, -0.866370f, 0.215095f, + 0.356896f, -0.812898f, 0.643632f, + 0.341634f, -0.830433f, 0.617646f, + 0.305199f, -0.845884f, 0.555611f, + 0.238593f, -0.858211f, 0.442206f, + 0.132817f, -0.866370f, 0.262109f, + 0.178630f, -0.812898f, 0.717749f, + 0.170565f, -0.830433f, 0.688771f, + 0.151312f, -0.845884f, 0.619592f, + 0.116116f, -0.858211f, 0.493128f, + 0.060221f, -0.866370f, 0.292292f, + -0.021127f, -0.812898f, 0.743924f, + -0.021127f, -0.830433f, 0.713889f, + -0.021127f, -0.845884f, 0.642188f, + -0.021127f, -0.858211f, 0.511111f, + -0.021127f, -0.866370f, 0.302951f, + -0.220884f, -0.812898f, 0.717749f, + -0.212820f, -0.830433f, 0.688771f, + -0.193566f, -0.845884f, 0.619592f, + -0.158370f, -0.858211f, 0.493128f, + -0.102475f, -0.866370f, 0.292292f, + -0.399151f, -0.812898f, 0.643632f, + -0.383889f, -0.830433f, 0.617646f, + -0.347454f, -0.845884f, 0.555611f, + -0.280847f, -0.858211f, 0.442206f, + -0.175071f, -0.866370f, 0.262109f, + -0.549313f, -0.812898f, 0.528186f, + -0.527988f, -0.830433f, 0.506861f, + -0.477080f, -0.845884f, 0.455953f, + -0.384016f, -0.858211f, 0.362889f, + -0.236223f, -0.866370f, 0.215095f, + -0.664759f, -0.812898f, 0.378023f, + -0.638773f, -0.830433f, 0.362761f, + -0.576738f, -0.845884f, 0.326326f, + -0.463333f, -0.858211f, 0.259720f, + -0.283236f, -0.866370f, 0.153944f, + -0.738876f, -0.812898f, 0.199757f, + -0.709898f, -0.830433f, 0.191692f, + -0.640719f, -0.845884f, 0.172439f, + -0.514255f, -0.858211f, 0.137243f, + -0.313419f, -0.866370f, 0.081348f, + -0.765051f, -0.812898f, 0.000000f, + -0.735016f, -0.830433f, 0.000000f, + -0.663315f, -0.845884f, 0.000000f, + -0.532238f, -0.858211f, 0.000000f, + -0.324079f, -0.866370f, 0.000000f, + -0.738876f, -0.812898f, -0.199757f, + -0.709898f, -0.830433f, -0.191692f, + -0.640719f, -0.845884f, -0.172439f, + -0.514255f, -0.858211f, -0.137243f, + -0.313419f, -0.866370f, -0.081348f, + -0.664759f, -0.812898f, -0.378023f, + -0.638773f, -0.830433f, -0.362761f, + -0.576738f, -0.845884f, -0.326326f, + -0.463333f, -0.858211f, -0.259720f, + -0.283236f, -0.866370f, -0.153944f, + -0.549313f, -0.812898f, -0.528186f, + -0.527988f, -0.830433f, -0.506861f, + -0.477080f, -0.845884f, -0.455953f, + -0.384016f, -0.858211f, -0.362889f, + -0.236223f, -0.866370f, -0.215095f, + -0.399151f, -0.812898f, -0.643632f, + -0.383889f, -0.830433f, -0.617646f, + -0.347454f, -0.845884f, -0.555611f, + -0.280847f, -0.858211f, -0.442206f, + -0.175071f, -0.866370f, -0.262109f, + -0.220884f, -0.812898f, -0.717749f, + -0.212820f, -0.830433f, -0.688771f, + -0.193566f, -0.845884f, -0.619592f, + -0.158370f, -0.858211f, -0.493128f, + -0.102475f, -0.866370f, -0.292292f, + -0.021127f, -0.812898f, -0.743924f, + -0.021127f, -0.830433f, -0.713889f, + -0.021127f, -0.845884f, -0.642188f, + -0.021127f, -0.858211f, -0.511111f, + -0.021127f, -0.866370f, -0.302951f, + 0.178630f, -0.812898f, -0.717749f, + 0.170565f, -0.830433f, -0.688771f, + 0.151312f, -0.845884f, -0.619592f, + 0.116116f, -0.858211f, -0.493128f, + 0.060221f, -0.866370f, -0.292292f, + 0.356896f, -0.812898f, -0.643632f, + 0.341634f, -0.830433f, -0.617646f, + 0.305199f, -0.845884f, -0.555611f, + 0.238593f, -0.858211f, -0.442206f, + 0.132817f, -0.866370f, -0.262109f, + 0.507059f, -0.812898f, -0.528186f, + 0.485734f, -0.830433f, -0.506861f, + 0.434826f, -0.845884f, -0.455953f, + 0.341762f, -0.858211f, -0.362889f, + 0.193968f, -0.866370f, -0.215095f, + 0.622505f, -0.812898f, -0.378023f, + 0.596519f, -0.830433f, -0.362761f, + 0.534484f, -0.845884f, -0.326326f, + 0.421079f, -0.858211f, -0.259720f, + 0.240982f, -0.866370f, -0.153944f, + 0.696621f, -0.812898f, -0.199757f, + 0.667643f, -0.830433f, -0.191692f, + 0.598465f, -0.845884f, -0.172439f, + 0.472000f, -0.858211f, -0.137243f, + 0.271165f, -0.866370f, -0.081348f, + -0.821127f, 0.143178f, 0.000000f, + -0.983396f, 0.142657f, 0.000000f, + -1.119275f, 0.139012f, 0.000000f, + -1.227377f, 0.129116f, 0.000000f, + -1.306313f, 0.109845f, 0.000000f, + -1.354692f, 0.078074f, 0.000000f, + -1.371127f, 0.030678f, 0.000000f, + -0.817424f, 0.151512f, 0.062500f, + -0.984648f, 0.150952f, 0.062500f, + -1.124351f, 0.147036f, 0.062500f, + -1.235248f, 0.136407f, 0.062500f, + -1.316052f, 0.115709f, 0.062500f, + -1.365477f, 0.081585f, 0.062500f, + -1.382239f, 0.030678f, 0.062500f, + -0.808164f, 0.172345f, 0.100000f, + -0.987777f, 0.171689f, 0.100000f, + -1.137040f, 0.167098f, 0.100000f, + -1.254924f, 0.154637f, 0.100000f, + -1.340400f, 0.130370f, 0.100000f, + -1.392441f, 0.090362f, 0.100000f, + -1.410016f, 0.030678f, 0.100000f, + -0.796127f, 0.199428f, 0.112500f, + -0.991845f, 0.198647f, 0.112500f, + -1.153535f, 0.193178f, 0.112500f, + -1.280502f, 0.178335f, 0.112500f, + -1.372053f, 0.149428f, 0.112500f, + -1.427493f, 0.101772f, 0.112500f, + -1.446127f, 0.030678f, 0.112500f, + -0.784090f, 0.226511f, 0.100000f, + -0.995913f, 0.225605f, 0.100000f, + -1.170030f, 0.219258f, 0.100000f, + -1.306081f, 0.202032f, 0.100000f, + -1.403706f, 0.168487f, 0.100000f, + -1.462545f, 0.113182f, 0.100000f, + -1.482238f, 0.030678f, 0.100000f, + -0.774831f, 0.247345f, 0.062500f, + -0.999042f, 0.246342f, 0.062500f, + -1.182719f, 0.239320f, 0.062500f, + -1.325757f, 0.220261f, 0.062500f, + -1.428054f, 0.183147f, 0.062500f, + -1.489509f, 0.121959f, 0.062500f, + -1.510016f, 0.030678f, 0.062500f, + -0.771127f, 0.255678f, 0.000000f, + -1.000294f, 0.254636f, 0.000000f, + -1.187794f, 0.247345f, 0.000000f, + -1.333627f, 0.227553f, 0.000000f, + -1.437794f, 0.189011f, 0.000000f, + -1.500294f, 0.125470f, 0.000000f, + -1.521127f, 0.030678f, 0.000000f, + -0.774831f, 0.247345f, -0.062500f, + -0.999042f, 0.246342f, -0.062500f, + -1.182719f, 0.239320f, -0.062500f, + -1.325757f, 0.220261f, -0.062500f, + -1.428054f, 0.183147f, -0.062500f, + -1.489509f, 0.121959f, -0.062500f, + -1.510016f, 0.030678f, -0.062500f, + -0.784090f, 0.226511f, -0.100000f, + -0.995913f, 0.225605f, -0.100000f, + -1.170030f, 0.219258f, -0.100000f, + -1.306081f, 0.202032f, -0.100000f, + -1.403706f, 0.168487f, -0.100000f, + -1.462545f, 0.113182f, -0.100000f, + -1.482238f, 0.030678f, -0.100000f, + -0.796127f, 0.199428f, -0.112500f, + -0.991845f, 0.198647f, -0.112500f, + -1.153535f, 0.193178f, -0.112500f, + -1.280502f, 0.178335f, -0.112500f, + -1.372053f, 0.149428f, -0.112500f, + -1.427493f, 0.101772f, -0.112500f, + -1.446127f, 0.030678f, -0.112500f, + -0.808164f, 0.172345f, -0.100000f, + -0.987777f, 0.171689f, -0.100000f, + -1.137040f, 0.167098f, -0.100000f, + -1.254924f, 0.154637f, -0.100000f, + -1.340400f, 0.130370f, -0.100000f, + -1.392441f, 0.090362f, -0.100000f, + -1.410016f, 0.030678f, -0.100000f, + -0.817424f, 0.151512f, -0.062500f, + -0.984648f, 0.150952f, -0.062500f, + -1.124351f, 0.147036f, -0.062500f, + -1.235248f, 0.136407f, -0.062500f, + -1.316052f, 0.115709f, -0.062500f, + -1.365477f, 0.081585f, -0.062500f, + -1.382239f, 0.030678f, -0.062500f, + -1.362563f, -0.033905f, 0.000000f, + -1.335942f, -0.110988f, 0.000000f, + -1.289877f, -0.194322f, 0.000000f, + -1.222979f, -0.277655f, 0.000000f, + -1.133859f, -0.354739f, 0.000000f, + -1.021127f, -0.419322f, 0.000000f, + -1.373219f, -0.037332f, 0.062500f, + -1.345270f, -0.116647f, 0.062500f, + -1.297053f, -0.201440f, 0.062500f, + -1.227232f, -0.285886f, 0.062500f, + -1.134467f, -0.364159f, 0.062500f, + -1.017424f, -0.430433f, 0.062500f, + -1.399861f, -0.045900f, 0.100000f, + -1.368590f, -0.130793f, 0.100000f, + -1.314993f, -0.219235f, 0.100000f, + -1.237862f, -0.306462f, 0.100000f, + -1.135989f, -0.387709f, 0.100000f, + -1.008164f, -0.458211f, 0.100000f, + -1.434495f, -0.057039f, 0.112500f, + -1.398905f, -0.149183f, 0.112500f, + -1.338315f, -0.242369f, 0.112500f, + -1.251683f, -0.333211f, 0.112500f, + -1.137967f, -0.418324f, 0.112500f, + -0.996127f, -0.494322f, 0.112500f, + -1.469130f, -0.068177f, 0.100000f, + -1.429221f, -0.167573f, 0.100000f, + -1.361637f, -0.265502f, 0.100000f, + -1.265503f, -0.359960f, 0.100000f, + -1.139946f, -0.448939f, 0.100000f, + -0.984090f, -0.530433f, 0.100000f, + -1.495772f, -0.076745f, 0.062500f, + -1.452540f, -0.181719f, 0.062500f, + -1.379576f, -0.283298f, 0.062500f, + -1.276134f, -0.380536f, 0.062500f, + -1.141468f, -0.472489f, 0.062500f, + -0.974831f, -0.558211f, 0.062500f, + -1.506428f, -0.080173f, 0.000000f, + -1.461868f, -0.187377f, 0.000000f, + -1.386752f, -0.290416f, 0.000000f, + -1.280387f, -0.388766f, 0.000000f, + -1.142076f, -0.481909f, 0.000000f, + -0.971127f, -0.569322f, 0.000000f, + -1.495772f, -0.076745f, -0.062500f, + -1.452540f, -0.181719f, -0.062500f, + -1.379576f, -0.283298f, -0.062500f, + -1.276134f, -0.380536f, -0.062500f, + -1.141468f, -0.472489f, -0.062500f, + -0.974831f, -0.558211f, -0.062500f, + -1.469130f, -0.068177f, -0.100000f, + -1.429221f, -0.167573f, -0.100000f, + -1.361637f, -0.265502f, -0.100000f, + -1.265503f, -0.359960f, -0.100000f, + -1.139946f, -0.448939f, -0.100000f, + -0.984090f, -0.530433f, -0.100000f, + -1.434495f, -0.057039f, -0.112500f, + -1.398905f, -0.149183f, -0.112500f, + -1.338315f, -0.242369f, -0.112500f, + -1.251683f, -0.333211f, -0.112500f, + -1.137967f, -0.418324f, -0.112500f, + -0.996127f, -0.494322f, -0.112500f, + -1.399861f, -0.045900f, -0.100000f, + -1.368590f, -0.130793f, -0.100000f, + -1.314993f, -0.219235f, -0.100000f, + -1.237862f, -0.306462f, -0.100000f, + -1.135989f, -0.387709f, -0.100000f, + -1.008164f, -0.458211f, -0.100000f, + -1.373219f, -0.037332f, -0.062500f, + -1.345270f, -0.116647f, -0.062500f, + -1.297053f, -0.201440f, -0.062500f, + -1.227232f, -0.285886f, -0.062500f, + -1.134467f, -0.364159f, -0.062500f, + -1.017424f, -0.430433f, -0.062500f, + 0.828873f, -0.156822f, 0.000000f, + 1.008271f, -0.131127f, 0.000000f, + 1.114058f, -0.063766f, 0.000000f, + 1.172623f, 0.030678f, 0.000000f, + 1.210354f, 0.137623f, 0.000000f, + 1.253641f, 0.242484f, 0.000000f, + 1.328873f, 0.330678f, 0.000000f, + 0.828873f, -0.187377f, 0.137500f, + 1.015061f, -0.156719f, 0.131173f, + 1.123935f, -0.083314f, 0.115355f, + 1.183734f, 0.017484f, 0.094792f, + 1.222700f, 0.130318f, 0.074228f, + 1.269073f, 0.239835f, 0.058411f, + 1.351095f, 0.330678f, 0.052083f, + 0.828873f, -0.263766f, 0.220000f, + 1.032036f, -0.220698f, 0.209877f, + 1.148626f, -0.132182f, 0.184568f, + 1.211512f, -0.015502f, 0.151667f, + 1.253564f, 0.112057f, 0.118765f, + 1.307654f, 0.233212f, 0.093457f, + 1.406651f, 0.330678f, 0.083333f, + 0.828873f, -0.363072f, 0.247500f, + 1.054104f, -0.303870f, 0.236111f, + 1.180725f, -0.195711f, 0.207639f, + 1.247623f, -0.058384f, 0.170625f, + 1.293688f, 0.088317f, 0.133611f, + 1.357808f, 0.224602f, 0.105139f, + 1.478873f, 0.330678f, 0.093750f, + 0.828873f, -0.462377f, 0.220000f, + 1.076172f, -0.387043f, 0.209877f, + 1.212823f, -0.259240f, 0.184568f, + 1.283734f, -0.101266f, 0.151667f, + 1.333811f, 0.064577f, 0.118765f, + 1.407962f, 0.215992f, 0.093457f, + 1.551095f, 0.330678f, 0.083333f, + 0.828873f, -0.538766f, 0.137500f, + 1.093148f, -0.451022f, 0.131173f, + 1.237515f, -0.308108f, 0.115355f, + 1.311512f, -0.134252f, 0.094792f, + 1.364675f, 0.046316f, 0.074228f, + 1.446543f, 0.209369f, 0.058410f, + 1.606651f, 0.330678f, 0.052083f, + 0.828873f, -0.569322f, 0.000000f, + 1.099938f, -0.476614f, 0.000000f, + 1.247391f, -0.327655f, 0.000000f, + 1.322623f, -0.147447f, 0.000000f, + 1.377021f, 0.039012f, 0.000000f, + 1.461975f, 0.206720f, 0.000000f, + 1.628873f, 0.330678f, 0.000000f, + 0.828873f, -0.538766f, -0.137500f, + 1.093148f, -0.451022f, -0.131173f, + 1.237515f, -0.308108f, -0.115355f, + 1.311512f, -0.134252f, -0.094792f, + 1.364675f, 0.046316f, -0.074228f, + 1.446543f, 0.209369f, -0.058410f, + 1.606651f, 0.330678f, -0.052083f, + 0.828873f, -0.462377f, -0.220000f, + 1.076172f, -0.387043f, -0.209877f, + 1.212823f, -0.259240f, -0.184568f, + 1.283734f, -0.101266f, -0.151667f, + 1.333811f, 0.064577f, -0.118765f, + 1.407962f, 0.215992f, -0.093457f, + 1.551095f, 0.330678f, -0.083333f, + 0.828873f, -0.363072f, -0.247500f, + 1.054104f, -0.303870f, -0.236111f, + 1.180725f, -0.195711f, -0.207639f, + 1.247623f, -0.058384f, -0.170625f, + 1.293688f, 0.088317f, -0.133611f, + 1.357808f, 0.224602f, -0.105139f, + 1.478873f, 0.330678f, -0.093750f, + 0.828873f, -0.263766f, -0.220000f, + 1.032036f, -0.220698f, -0.209877f, + 1.148626f, -0.132182f, -0.184568f, + 1.211512f, -0.015502f, -0.151667f, + 1.253564f, 0.112057f, -0.118765f, + 1.307654f, 0.233212f, -0.093457f, + 1.406651f, 0.330678f, -0.083333f, + 0.828873f, -0.187377f, -0.137500f, + 1.015061f, -0.156719f, -0.131173f, + 1.123935f, -0.083314f, -0.115355f, + 1.183734f, 0.017484f, -0.094792f, + 1.222700f, 0.130318f, -0.074228f, + 1.269073f, 0.239835f, -0.058410f, + 1.351095f, 0.330678f, -0.052083f, + 1.353410f, 0.346303f, 0.000000f, + 1.375169f, 0.355678f, 0.000000f, + 1.391373f, 0.358803f, 0.000000f, + 1.399243f, 0.355678f, 0.000000f, + 1.396003f, 0.346303f, 0.000000f, + 1.378873f, 0.330678f, 0.000000f, + 1.377077f, 0.346641f, 0.050540f, + 1.398763f, 0.356295f, 0.046682f, + 1.413711f, 0.359584f, 0.041667f, + 1.419477f, 0.356450f, 0.036651f, + 1.413617f, 0.346834f, 0.032793f, + 1.393688f, 0.330678f, 0.031250f, + 1.436244f, 0.347485f, 0.080864f, + 1.457748f, 0.357839f, 0.074691f, + 1.469556f, 0.361538f, 0.066667f, + 1.470060f, 0.358379f, 0.058642f, + 1.457652f, 0.348160f, 0.052469f, + 1.430725f, 0.330678f, 0.050000f, + 1.513161f, 0.348582f, 0.090972f, + 1.534428f, 0.359845f, 0.084028f, + 1.542154f, 0.364077f, 0.075000f, + 1.535817f, 0.360886f, 0.065972f, + 1.514897f, 0.349884f, 0.059028f, + 1.478873f, 0.330678f, 0.056250f, + 1.590078f, 0.349679f, 0.080864f, + 1.611109f, 0.361851f, 0.074691f, + 1.614753f, 0.366616f, 0.066667f, + 1.601575f, 0.363394f, 0.058642f, + 1.572143f, 0.351608f, 0.052469f, + 1.527021f, 0.330678f, 0.050000f, + 1.649245f, 0.350523f, 0.050540f, + 1.670094f, 0.363394f, 0.046682f, + 1.670597f, 0.368569f, 0.041667f, + 1.652158f, 0.365323f, 0.036651f, + 1.616178f, 0.352934f, 0.032793f, + 1.564058f, 0.330678f, 0.031250f, + 1.672912f, 0.350860f, 0.000000f, + 1.693688f, 0.364011f, 0.000000f, + 1.692935f, 0.369350f, 0.000000f, + 1.672391f, 0.366095f, 0.000000f, + 1.633792f, 0.353465f, 0.000000f, + 1.578873f, 0.330678f, 0.000000f, + 1.649245f, 0.350523f, -0.050540f, + 1.670094f, 0.363394f, -0.046682f, + 1.670597f, 0.368569f, -0.041667f, + 1.652158f, 0.365323f, -0.036651f, + 1.616178f, 0.352934f, -0.032793f, + 1.564058f, 0.330678f, -0.031250f, + 1.590078f, 0.349679f, -0.080864f, + 1.611109f, 0.361851f, -0.074691f, + 1.614753f, 0.366616f, -0.066667f, + 1.601575f, 0.363394f, -0.058642f, + 1.572143f, 0.351608f, -0.052469f, + 1.527021f, 0.330678f, -0.050000f, + 1.513161f, 0.348582f, -0.090972f, + 1.534428f, 0.359845f, -0.084028f, + 1.542154f, 0.364077f, -0.075000f, + 1.535817f, 0.360886f, -0.065972f, + 1.514897f, 0.349884f, -0.059028f, + 1.478873f, 0.330678f, -0.056250f, + 1.436244f, 0.347485f, -0.080864f, + 1.457748f, 0.357839f, -0.074691f, + 1.469556f, 0.361538f, -0.066667f, + 1.470060f, 0.358379f, -0.058642f, + 1.457652f, 0.348160f, -0.052469f, + 1.430725f, 0.330678f, -0.050000f, + 1.377077f, 0.346641f, -0.050540f, + 1.398763f, 0.356295f, -0.046682f, + 1.413711f, 0.359584f, -0.041667f, + 1.419477f, 0.356450f, -0.036651f, + 1.413617f, 0.346834f, -0.032793f, + 1.393688f, 0.330678f, -0.031250f, + -0.021127f, 0.705678f, 0.000000f, + 0.118225f, 0.694220f, 0.000000f, + 0.160354f, 0.664011f, 0.000000f, + 0.141373f, 0.621303f, 0.000000f, + 0.097391f, 0.572345f, 0.000000f, + 0.064521f, 0.523386f, 0.000000f, + 0.078873f, 0.480678f, 0.000000f, + 0.113346f, 0.694220f, 0.037539f, + 0.154000f, 0.664011f, 0.048885f, + 0.135681f, 0.621303f, 0.043764f, + 0.093237f, 0.572345f, 0.031902f, + 0.061512f, 0.523386f, 0.023022f, + 0.075354f, 0.480678f, 0.026852f, + 0.099515f, 0.694220f, 0.070966f, + 0.135987f, 0.664011f, 0.092417f, + 0.119549f, 0.621303f, 0.082741f, + 0.081463f, 0.572345f, 0.060324f, + 0.052990f, 0.523386f, 0.043553f, + 0.065391f, 0.480678f, 0.050815f, + 0.077943f, 0.694220f, 0.099070f, + 0.107891f, 0.664011f, 0.129019f, + 0.094388f, 0.621303f, 0.115516f, + 0.063104f, 0.572345f, 0.084231f, + 0.039709f, 0.523386f, 0.060836f, + 0.049873f, 0.480678f, 0.071000f, + 0.049838f, 0.694220f, 0.120642f, + 0.071290f, 0.664011f, 0.157114f, + 0.061614f, 0.621303f, 0.140676f, + 0.039197f, 0.572345f, 0.102590f, + 0.022426f, 0.523386f, 0.074117f, + 0.029688f, 0.480678f, 0.086519f, + 0.016412f, 0.694220f, 0.134473f, + 0.027758f, 0.664011f, 0.175127f, + 0.022637f, 0.621303f, 0.156808f, + 0.010774f, 0.572345f, 0.114364f, + 0.001895f, 0.523386f, 0.082639f, + 0.005725f, 0.480678f, 0.096482f, + -0.021127f, 0.694220f, 0.139352f, + -0.021127f, 0.664011f, 0.181482f, + -0.021127f, 0.621303f, 0.162500f, + -0.021127f, 0.572345f, 0.118519f, + -0.021127f, 0.523386f, 0.085648f, + -0.021127f, 0.480678f, 0.100000f, + -0.058666f, 0.694220f, 0.134473f, + -0.070013f, 0.664011f, 0.175127f, + -0.064892f, 0.621303f, 0.156808f, + -0.053029f, 0.572345f, 0.114364f, + -0.044149f, 0.523386f, 0.082639f, + -0.047979f, 0.480678f, 0.096481f, + -0.092093f, 0.694220f, 0.120642f, + -0.113544f, 0.664011f, 0.157114f, + -0.103868f, 0.621303f, 0.140676f, + -0.081451f, 0.572345f, 0.102590f, + -0.064680f, 0.523386f, 0.074117f, + -0.071942f, 0.480678f, 0.086519f, + -0.120197f, 0.694220f, 0.099070f, + -0.150146f, 0.664011f, 0.129019f, + -0.136643f, 0.621303f, 0.115516f, + -0.105359f, 0.572345f, 0.084231f, + -0.081963f, 0.523386f, 0.060836f, + -0.092127f, 0.480678f, 0.071000f, + -0.141770f, 0.694220f, 0.070966f, + -0.178241f, 0.664011f, 0.092417f, + -0.161803f, 0.621303f, 0.082741f, + -0.123717f, 0.572345f, 0.060324f, + -0.095244f, 0.523386f, 0.043553f, + -0.107646f, 0.480678f, 0.050815f, + -0.155600f, 0.694220f, 0.037539f, + -0.196254f, 0.664011f, 0.048885f, + -0.177936f, 0.621303f, 0.043764f, + -0.135491f, 0.572345f, 0.031902f, + -0.103767f, 0.523386f, 0.023022f, + -0.117609f, 0.480678f, 0.026852f, + -0.160479f, 0.694220f, 0.000000f, + -0.202609f, 0.664011f, 0.000000f, + -0.183627f, 0.621303f, 0.000000f, + -0.139646f, 0.572345f, 0.000000f, + -0.106775f, 0.523386f, 0.000000f, + -0.121127f, 0.480678f, 0.000000f, + -0.155600f, 0.694220f, -0.037539f, + -0.196254f, 0.664011f, -0.048885f, + -0.177936f, 0.621303f, -0.043764f, + -0.135491f, 0.572345f, -0.031902f, + -0.103767f, 0.523386f, -0.023022f, + -0.117609f, 0.480678f, -0.026852f, + -0.141770f, 0.694220f, -0.070966f, + -0.178241f, 0.664011f, -0.092417f, + -0.161803f, 0.621303f, -0.082741f, + -0.123717f, 0.572345f, -0.060324f, + -0.095244f, 0.523386f, -0.043553f, + -0.107646f, 0.480678f, -0.050815f, + -0.120197f, 0.694220f, -0.099070f, + -0.150146f, 0.664011f, -0.129019f, + -0.136643f, 0.621303f, -0.115516f, + -0.105359f, 0.572345f, -0.084231f, + -0.081963f, 0.523386f, -0.060836f, + -0.092127f, 0.480678f, -0.071000f, + -0.092093f, 0.694220f, -0.120642f, + -0.113544f, 0.664011f, -0.157114f, + -0.103868f, 0.621303f, -0.140676f, + -0.081451f, 0.572345f, -0.102590f, + -0.064680f, 0.523386f, -0.074117f, + -0.071942f, 0.480678f, -0.086519f, + -0.058666f, 0.694220f, -0.134473f, + -0.070013f, 0.664011f, -0.175127f, + -0.064892f, 0.621303f, -0.156808f, + -0.053029f, 0.572345f, -0.114364f, + -0.044149f, 0.523386f, -0.082639f, + -0.047979f, 0.480678f, -0.096482f, + -0.021127f, 0.694220f, -0.139352f, + -0.021127f, 0.664011f, -0.181482f, + -0.021127f, 0.621303f, -0.162500f, + -0.021127f, 0.572345f, -0.118519f, + -0.021127f, 0.523386f, -0.085648f, + -0.021127f, 0.480678f, -0.100000f, + 0.016412f, 0.694220f, -0.134473f, + 0.027758f, 0.664011f, -0.175127f, + 0.022637f, 0.621303f, -0.156808f, + 0.010774f, 0.572345f, -0.114364f, + 0.001895f, 0.523386f, -0.082639f, + 0.005725f, 0.480678f, -0.096481f, + 0.049838f, 0.694220f, -0.120642f, + 0.071290f, 0.664011f, -0.157114f, + 0.061614f, 0.621303f, -0.140676f, + 0.039197f, 0.572345f, -0.102590f, + 0.022426f, 0.523386f, -0.074117f, + 0.029688f, 0.480678f, -0.086519f, + 0.077943f, 0.694220f, -0.099070f, + 0.107891f, 0.664011f, -0.129019f, + 0.094388f, 0.621303f, -0.115516f, + 0.063104f, 0.572345f, -0.084231f, + 0.039709f, 0.523386f, -0.060836f, + 0.049873f, 0.480678f, -0.071000f, + 0.099515f, 0.694220f, -0.070966f, + 0.135987f, 0.664011f, -0.092417f, + 0.119549f, 0.621303f, -0.082741f, + 0.081463f, 0.572345f, -0.060324f, + 0.052990f, 0.523386f, -0.043553f, + 0.065391f, 0.480678f, -0.050815f, + 0.113346f, 0.694220f, -0.037539f, + 0.154000f, 0.664011f, -0.048885f, + 0.135681f, 0.621303f, -0.043764f, + 0.093237f, 0.572345f, -0.031902f, + 0.061512f, 0.523386f, -0.023022f, + 0.075354f, 0.480678f, -0.026852f, + 0.154336f, 0.448734f, 0.000000f, + 0.265910f, 0.425123f, 0.000000f, + 0.391373f, 0.405678f, 0.000000f, + 0.508502f, 0.386234f, 0.000000f, + 0.595077f, 0.362623f, 0.000000f, + 0.628873f, 0.330678f, 0.000000f, + 0.148162f, 0.448734f, 0.047115f, + 0.255810f, 0.425123f, 0.077075f, + 0.376859f, 0.405678f, 0.110764f, + 0.489867f, 0.386234f, 0.142215f, + 0.573395f, 0.362623f, 0.165462f, + 0.606002f, 0.330678f, 0.174537f, + 0.130681f, 0.448734f, 0.089161f, + 0.227213f, 0.425123f, 0.145857f, + 0.335762f, 0.405678f, 0.209611f, + 0.437101f, 0.386234f, 0.269130f, + 0.512003f, 0.362623f, 0.313123f, + 0.541243f, 0.330678f, 0.330296f, + 0.103451f, 0.448734f, 0.124579f, + 0.182669f, 0.425123f, 0.203796f, + 0.271748f, 0.405678f, 0.292875f, + 0.354910f, 0.386234f, 0.376037f, + 0.416377f, 0.362623f, 0.437505f, + 0.440373f, 0.330678f, 0.461500f, + 0.068034f, 0.448734f, 0.151808f, + 0.124730f, 0.425123f, 0.248340f, + 0.188484f, 0.405678f, 0.356889f, + 0.248003f, 0.386234f, 0.458228f, + 0.291995f, 0.362623f, 0.533130f, + 0.309169f, 0.330678f, 0.562370f, + 0.025988f, 0.448734f, 0.169289f, + 0.055948f, 0.425123f, 0.276938f, + 0.089637f, 0.405678f, 0.397986f, + 0.121088f, 0.386234f, 0.510995f, + 0.144335f, 0.362623f, 0.594523f, + 0.153410f, 0.330678f, 0.627130f, + -0.021127f, 0.448734f, 0.175463f, + -0.021127f, 0.425123f, 0.287037f, + -0.021127f, 0.405678f, 0.412500f, + -0.021127f, 0.386234f, 0.529630f, + -0.021127f, 0.362623f, 0.616204f, + -0.021127f, 0.330678f, 0.650000f, + -0.068242f, 0.448734f, 0.169289f, + -0.098202f, 0.425123f, 0.276938f, + -0.131891f, 0.405678f, 0.397986f, + -0.163343f, 0.386234f, 0.510995f, + -0.186589f, 0.362623f, 0.594523f, + -0.195664f, 0.330678f, 0.627130f, + -0.110288f, 0.448734f, 0.151808f, + -0.166985f, 0.425123f, 0.248340f, + -0.230738f, 0.405678f, 0.356889f, + -0.290258f, 0.386234f, 0.458228f, + -0.334250f, 0.362623f, 0.533130f, + -0.351424f, 0.330678f, 0.562370f, + -0.145706f, 0.448734f, 0.124579f, + -0.224924f, 0.425123f, 0.203796f, + -0.314002f, 0.405678f, 0.292875f, + -0.397164f, 0.386234f, 0.376037f, + -0.458632f, 0.362623f, 0.437505f, + -0.482627f, 0.330678f, 0.461500f, + -0.172935f, 0.448734f, 0.089161f, + -0.269467f, 0.425123f, 0.145857f, + -0.378016f, 0.405678f, 0.209611f, + -0.479355f, 0.386234f, 0.269130f, + -0.554258f, 0.362623f, 0.313123f, + -0.583498f, 0.330678f, 0.330296f, + -0.190416f, 0.448734f, 0.047115f, + -0.298065f, 0.425123f, 0.077075f, + -0.419113f, 0.405678f, 0.110764f, + -0.532122f, 0.386234f, 0.142215f, + -0.615650f, 0.362623f, 0.165462f, + -0.648257f, 0.330678f, 0.174537f, + -0.196590f, 0.448734f, 0.000000f, + -0.308164f, 0.425123f, 0.000000f, + -0.433627f, 0.405678f, 0.000000f, + -0.550757f, 0.386234f, 0.000000f, + -0.637331f, 0.362623f, 0.000000f, + -0.671127f, 0.330678f, 0.000000f, + -0.190416f, 0.448734f, -0.047115f, + -0.298065f, 0.425123f, -0.077075f, + -0.419113f, 0.405678f, -0.110764f, + -0.532122f, 0.386234f, -0.142215f, + -0.615650f, 0.362623f, -0.165462f, + -0.648257f, 0.330678f, -0.174537f, + -0.172935f, 0.448734f, -0.089161f, + -0.269467f, 0.425123f, -0.145857f, + -0.378016f, 0.405678f, -0.209611f, + -0.479355f, 0.386234f, -0.269130f, + -0.554258f, 0.362623f, -0.313123f, + -0.583498f, 0.330678f, -0.330296f, + -0.145706f, 0.448734f, -0.124579f, + -0.224924f, 0.425123f, -0.203796f, + -0.314002f, 0.405678f, -0.292875f, + -0.397164f, 0.386234f, -0.376037f, + -0.458632f, 0.362623f, -0.437505f, + -0.482627f, 0.330678f, -0.461500f, + -0.110288f, 0.448734f, -0.151808f, + -0.166985f, 0.425123f, -0.248340f, + -0.230738f, 0.405678f, -0.356889f, + -0.290258f, 0.386234f, -0.458228f, + -0.334250f, 0.362623f, -0.533130f, + -0.351424f, 0.330678f, -0.562370f, + -0.068242f, 0.448734f, -0.169289f, + -0.098202f, 0.425123f, -0.276938f, + -0.131891f, 0.405678f, -0.397986f, + -0.163343f, 0.386234f, -0.510995f, + -0.186589f, 0.362623f, -0.594523f, + -0.195664f, 0.330678f, -0.627130f, + -0.021127f, 0.448734f, -0.175463f, + -0.021127f, 0.425123f, -0.287037f, + -0.021127f, 0.405678f, -0.412500f, + -0.021127f, 0.386234f, -0.529630f, + -0.021127f, 0.362623f, -0.616204f, + -0.021127f, 0.330678f, -0.650000f, + 0.025988f, 0.448734f, -0.169289f, + 0.055948f, 0.425123f, -0.276938f, + 0.089637f, 0.405678f, -0.397986f, + 0.121088f, 0.386234f, -0.510995f, + 0.144335f, 0.362623f, -0.594523f, + 0.153410f, 0.330678f, -0.627130f, + 0.068034f, 0.448734f, -0.151808f, + 0.124730f, 0.425123f, -0.248340f, + 0.188484f, 0.405678f, -0.356889f, + 0.248003f, 0.386234f, -0.458228f, + 0.291996f, 0.362623f, -0.533130f, + 0.309169f, 0.330678f, -0.562370f, + 0.103451f, 0.448734f, -0.124579f, + 0.182669f, 0.425123f, -0.203796f, + 0.271748f, 0.405678f, -0.292875f, + 0.354910f, 0.386234f, -0.376037f, + 0.416377f, 0.362623f, -0.437505f, + 0.440373f, 0.330678f, -0.461500f, + 0.130681f, 0.448734f, -0.089161f, + 0.227213f, 0.425123f, -0.145857f, + 0.335762f, 0.405678f, -0.209611f, + 0.437101f, 0.386234f, -0.269130f, + 0.512003f, 0.362623f, -0.313123f, + 0.541243f, 0.330678f, -0.330296f, + 0.148162f, 0.448734f, -0.047115f, + 0.255810f, 0.425123f, -0.077075f, + 0.376859f, 0.405678f, -0.110764f, + 0.489867f, 0.386234f, -0.142215f, + 0.573395f, 0.362623f, -0.165462f, + 0.606002f, 0.330678f, -0.174537f, +}; +static D3DXVECTOR3* teapotPositions = ( D3DXVECTOR3* )teapotPositionsFloats; + +static float teapotNormalsfloats[NUMTEAPOTVERTICES*3] = +{ + -0.945751f, -0.322256f, -0.041309f, + -0.992771f, -0.120019f, -0.001089f, + -0.842751f, 0.538169f, 0.012052f, + -0.083588f, 0.996288f, 0.020560f, + 0.532170f, 0.846603f, 0.007614f, + 0.779300f, 0.626641f, 0.003491f, + 0.879896f, 0.475165f, 0.001103f, + -0.902413f, -0.322783f, -0.285416f, + -0.958558f, -0.120097f, -0.258348f, + -0.816875f, 0.538579f, -0.206514f, + -0.086190f, 0.996277f, -0.001604f, + 0.511484f, 0.846942f, 0.145167f, + 0.751363f, 0.627164f, 0.205227f, + 0.849281f, 0.475682f, 0.229015f, + -0.797449f, -0.323303f, -0.509461f, + -0.858625f, -0.120328f, -0.498282f, + -0.735017f, 0.538957f, -0.411431f, + -0.082580f, 0.996294f, -0.024043f, + 0.455735f, 0.847352f, 0.272581f, + 0.671856f, 0.627868f, 0.392927f, + 0.760399f, 0.476384f, 0.441420f, + -0.639341f, -0.323439f, -0.697589f, + -0.701183f, -0.120461f, -0.702731f, + -0.604040f, 0.539064f, -0.586980f, + -0.073399f, 0.996309f, -0.044511f, + 0.369925f, 0.847499f, 0.380659f, + 0.547722f, 0.628143f, 0.552663f, + 0.620826f, 0.476660f, 0.622391f, + -0.437782f, -0.323142f, -0.839003f, + -0.496373f, -0.120437f, -0.859715f, + -0.432443f, 0.538876f, -0.722914f, + -0.059523f, 0.996312f, -0.061801f, + 0.259388f, 0.847326f, 0.463418f, + 0.386844f, 0.627880f, 0.675366f, + 0.439492f, 0.476398f, 0.761506f, + -0.204681f, -0.322547f, -0.924159f, + -0.256209f, -0.120257f, -0.959112f, + -0.230122f, 0.538458f, -0.810621f, + -0.041668f, 0.996304f, -0.075119f, + 0.130300f, 0.846904f, 0.515534f, + 0.198391f, 0.627182f, 0.753183f, + 0.226852f, 0.475703f, 0.849850f, + 0.035941f, -0.330214f, -0.943221f, + -0.001376f, -0.125569f, -0.992084f, + -0.012701f, 0.535792f, -0.844254f, + -0.020672f, 0.996343f, -0.082901f, + -0.007571f, 0.846427f, 0.532451f, + -0.003482f, 0.626608f, 0.779327f, + -0.001103f, 0.475165f, 0.879896f, + 0.269574f, -0.386954f, -0.881814f, + 0.249993f, -0.181783f, -0.951030f, + 0.211872f, 0.499984f, -0.839718f, + 0.002768f, 0.995768f, -0.091859f, + -0.146446f, 0.844150f, 0.515718f, + -0.205497f, 0.625909f, 0.752335f, + -0.229034f, 0.475536f, 0.849358f, + 0.482854f, -0.445924f, -0.753661f, + 0.483883f, -0.261599f, -0.835118f, + 0.442338f, 0.434016f, -0.784836f, + 0.036680f, 0.993502f, -0.107746f, + -0.278510f, 0.839949f, 0.465746f, + -0.394390f, 0.624142f, 0.674465f, + -0.441541f, 0.475913f, 0.760624f, + 0.669165f, -0.453044f, -0.589041f, + 0.686401f, -0.287530f, -0.667967f, + 0.643212f, 0.404496f, -0.650124f, + 0.074604f, 0.991460f, -0.106959f, + -0.391289f, 0.837987f, 0.380356f, + -0.555484f, 0.623132f, 0.550586f, + -0.622636f, 0.476008f, 0.621080f, + 0.821788f, -0.407716f, -0.398036f, + 0.849894f, -0.244430f, -0.466834f, + 0.778095f, 0.435804f, -0.452374f, + 0.095458f, 0.992115f, -0.081218f, + -0.473659f, 0.839871f, 0.265074f, + -0.678265f, 0.623724f, 0.388490f, + -0.761768f, 0.475842f, 0.439641f, + 0.919150f, -0.348512f, -0.183583f, + 0.956218f, -0.171139f, -0.237398f, + 0.838823f, 0.493898f, -0.229000f, + 0.094322f, 0.994404f, -0.047578f, + -0.520640f, 0.843596f, 0.131452f, + -0.754753f, 0.625180f, 0.198741f, + -0.849997f, 0.475426f, 0.226882f, + 0.945537f, -0.322183f, 0.046446f, + 0.991881f, -0.126966f, 0.007216f, + 0.847572f, 0.530605f, -0.008996f, + 0.087879f, 0.995918f, -0.020615f, + -0.533063f, 0.846041f, -0.007711f, + -0.779612f, 0.626253f, -0.003532f, + -0.879926f, 0.475109f, -0.001109f, + 0.902413f, -0.322783f, 0.285416f, + 0.958558f, -0.120097f, 0.258348f, + 0.816875f, 0.538579f, 0.206514f, + 0.086190f, 0.996277f, 0.001604f, + -0.511484f, 0.846942f, -0.145167f, + -0.751363f, 0.627164f, -0.205227f, + -0.849281f, 0.475682f, -0.229015f, + 0.797449f, -0.323303f, 0.509461f, + 0.858625f, -0.120328f, 0.498282f, + 0.735017f, 0.538957f, 0.411431f, + 0.082580f, 0.996294f, 0.024043f, + -0.455735f, 0.847352f, -0.272581f, + -0.671856f, 0.627868f, -0.392927f, + -0.760399f, 0.476384f, -0.441420f, + 0.639341f, -0.323439f, 0.697589f, + 0.701183f, -0.120461f, 0.702731f, + 0.604040f, 0.539064f, 0.586980f, + 0.073399f, 0.996309f, 0.044511f, + -0.369925f, 0.847499f, -0.380659f, + -0.547722f, 0.628143f, -0.552663f, + -0.620826f, 0.476660f, -0.622391f, + 0.437782f, -0.323142f, 0.839003f, + 0.496373f, -0.120437f, 0.859715f, + 0.432443f, 0.538876f, 0.722914f, + 0.059523f, 0.996312f, 0.061801f, + -0.259388f, 0.847326f, -0.463418f, + -0.386844f, 0.627880f, -0.675366f, + -0.439492f, 0.476398f, -0.761506f, + 0.204681f, -0.322547f, 0.924159f, + 0.256209f, -0.120257f, 0.959112f, + 0.230122f, 0.538458f, 0.810621f, + 0.041668f, 0.996304f, 0.075119f, + -0.130300f, 0.846904f, -0.515534f, + -0.198391f, 0.627182f, -0.753183f, + -0.226852f, 0.475703f, -0.849850f, + -0.041309f, -0.322256f, 0.945751f, + -0.001089f, -0.120019f, 0.992771f, + 0.012052f, 0.538169f, 0.842751f, + 0.020560f, 0.996288f, 0.083588f, + 0.007614f, 0.846603f, -0.532170f, + 0.003491f, 0.626641f, -0.779300f, + 0.001103f, 0.475165f, -0.879896f, + -0.285416f, -0.322783f, 0.902413f, + -0.258348f, -0.120097f, 0.958558f, + -0.206514f, 0.538579f, 0.816875f, + -0.001604f, 0.996277f, 0.086190f, + 0.145167f, 0.846942f, -0.511484f, + 0.205227f, 0.627164f, -0.751363f, + 0.229015f, 0.475682f, -0.849281f, + -0.509461f, -0.323303f, 0.797449f, + -0.498282f, -0.120328f, 0.858625f, + -0.411431f, 0.538957f, 0.735017f, + -0.024043f, 0.996294f, 0.082580f, + 0.272581f, 0.847352f, -0.455735f, + 0.392927f, 0.627868f, -0.671856f, + 0.441420f, 0.476384f, -0.760399f, + -0.697589f, -0.323439f, 0.639341f, + -0.702731f, -0.120461f, 0.701183f, + -0.586980f, 0.539064f, 0.604040f, + -0.044511f, 0.996309f, 0.073399f, + 0.380659f, 0.847499f, -0.369925f, + 0.552663f, 0.628143f, -0.547722f, + 0.622391f, 0.476660f, -0.620826f, + -0.839003f, -0.323142f, 0.437782f, + -0.859715f, -0.120437f, 0.496373f, + -0.722914f, 0.538876f, 0.432443f, + -0.061801f, 0.996312f, 0.059523f, + 0.463418f, 0.847326f, -0.259388f, + 0.675366f, 0.627880f, -0.386844f, + 0.761506f, 0.476398f, -0.439492f, + -0.924159f, -0.322547f, 0.204681f, + -0.959112f, -0.120257f, 0.256209f, + -0.810621f, 0.538458f, 0.230122f, + -0.075119f, 0.996304f, 0.041668f, + 0.515534f, 0.846904f, -0.130300f, + 0.753183f, 0.627182f, -0.198391f, + 0.849850f, 0.475703f, -0.226852f, + 0.908180f, 0.418579f, 0.000170f, + 0.920061f, 0.391776f, 0.000335f, + 0.939254f, 0.343222f, 0.000478f, + 0.963807f, 0.266599f, 0.000552f, + 0.988261f, 0.152772f, 0.000449f, + 0.998933f, -0.046187f, -0.000262f, + 0.876892f, 0.419073f, 0.235451f, + 0.888349f, 0.392247f, 0.238702f, + 0.906891f, 0.343648f, 0.243832f, + 0.930644f, 0.266938f, 0.250291f, + 0.954351f, 0.152959f, 0.256551f, + 0.964867f, -0.046304f, 0.258627f, + 0.785456f, 0.419734f, 0.454843f, + 0.795707f, 0.392883f, 0.460971f, + 0.812334f, 0.344228f, 0.470766f, + 0.833667f, 0.267414f, 0.483207f, + 0.855012f, 0.153250f, 0.495448f, + 0.864663f, -0.046372f, 0.500207f, + 0.641599f, 0.419990f, 0.641841f, + 0.649935f, 0.393130f, 0.650410f, + 0.663494f, 0.344457f, 0.664173f, + 0.680925f, 0.267607f, 0.681710f, + 0.698421f, 0.153377f, 0.699059f, + 0.706532f, -0.046369f, 0.706160f, + 0.454545f, 0.419737f, 0.785627f, + 0.460384f, 0.392890f, 0.796043f, + 0.469929f, 0.344241f, 0.812813f, + 0.482239f, 0.267436f, 0.834220f, + 0.494660f, 0.153286f, 0.855462f, + 0.500666f, -0.046300f, 0.864402f, + 0.235117f, 0.419078f, 0.876980f, + 0.238044f, 0.392258f, 0.888521f, + 0.242894f, 0.343667f, 0.907136f, + 0.249206f, 0.266970f, 0.930926f, + 0.255668f, 0.153012f, 0.954579f, + 0.259142f, -0.046198f, 0.964734f, + -0.000170f, 0.418579f, 0.908181f, + -0.000335f, 0.391776f, 0.920061f, + -0.000478f, 0.343222f, 0.939254f, + -0.000552f, 0.266599f, 0.963807f, + -0.000449f, 0.152772f, 0.988261f, + 0.000262f, -0.046187f, 0.998933f, + -0.235451f, 0.419073f, 0.876892f, + -0.238702f, 0.392247f, 0.888349f, + -0.243832f, 0.343648f, 0.906891f, + -0.250291f, 0.266938f, 0.930644f, + -0.256551f, 0.152959f, 0.954351f, + -0.258627f, -0.046304f, 0.964867f, + -0.454843f, 0.419734f, 0.785456f, + -0.460971f, 0.392883f, 0.795707f, + -0.470766f, 0.344228f, 0.812334f, + -0.483207f, 0.267414f, 0.833667f, + -0.495448f, 0.153250f, 0.855012f, + -0.500207f, -0.046372f, 0.864663f, + -0.641841f, 0.419990f, 0.641599f, + -0.650410f, 0.393130f, 0.649935f, + -0.664173f, 0.344457f, 0.663494f, + -0.681710f, 0.267607f, 0.680925f, + -0.699059f, 0.153377f, 0.698421f, + -0.706160f, -0.046369f, 0.706532f, + -0.785627f, 0.419737f, 0.454545f, + -0.796043f, 0.392890f, 0.460384f, + -0.812813f, 0.344241f, 0.469929f, + -0.834220f, 0.267436f, 0.482239f, + -0.855462f, 0.153286f, 0.494660f, + -0.864402f, -0.046300f, 0.500666f, + -0.876980f, 0.419078f, 0.235117f, + -0.888521f, 0.392258f, 0.238044f, + -0.907136f, 0.343667f, 0.242894f, + -0.930926f, 0.266970f, 0.249206f, + -0.954579f, 0.153012f, 0.255668f, + -0.964734f, -0.046198f, 0.259142f, + -0.908181f, 0.418579f, -0.000170f, + -0.920061f, 0.391776f, -0.000335f, + -0.939254f, 0.343222f, -0.000478f, + -0.963807f, 0.266599f, -0.000552f, + -0.988261f, 0.152772f, -0.000449f, + -0.998933f, -0.046187f, 0.000262f, + -0.876892f, 0.419073f, -0.235451f, + -0.888349f, 0.392247f, -0.238702f, + -0.906891f, 0.343648f, -0.243832f, + -0.930644f, 0.266938f, -0.250291f, + -0.954351f, 0.152959f, -0.256551f, + -0.964867f, -0.046304f, -0.258627f, + -0.785456f, 0.419734f, -0.454843f, + -0.795707f, 0.392883f, -0.460971f, + -0.812334f, 0.344228f, -0.470766f, + -0.833667f, 0.267414f, -0.483207f, + -0.855012f, 0.153250f, -0.495448f, + -0.864663f, -0.046372f, -0.500207f, + -0.641599f, 0.419990f, -0.641841f, + -0.649935f, 0.393130f, -0.650410f, + -0.663494f, 0.344457f, -0.664173f, + -0.680925f, 0.267607f, -0.681710f, + -0.698421f, 0.153377f, -0.699059f, + -0.706532f, -0.046369f, -0.706160f, + -0.454545f, 0.419737f, -0.785627f, + -0.460384f, 0.392890f, -0.796043f, + -0.469929f, 0.344241f, -0.812813f, + -0.482239f, 0.267436f, -0.834220f, + -0.494660f, 0.153286f, -0.855462f, + -0.500666f, -0.046300f, -0.864402f, + -0.235117f, 0.419078f, -0.876980f, + -0.238044f, 0.392258f, -0.888521f, + -0.242894f, 0.343667f, -0.907136f, + -0.249206f, 0.266970f, -0.930926f, + -0.255668f, 0.153012f, -0.954579f, + -0.259142f, -0.046198f, -0.964734f, + 0.000170f, 0.418579f, -0.908181f, + 0.000335f, 0.391776f, -0.920061f, + 0.000478f, 0.343222f, -0.939254f, + 0.000552f, 0.266599f, -0.963807f, + 0.000449f, 0.152772f, -0.988261f, + -0.000262f, -0.046187f, -0.998933f, + 0.235451f, 0.419073f, -0.876892f, + 0.238702f, 0.392247f, -0.888349f, + 0.243832f, 0.343648f, -0.906891f, + 0.250291f, 0.266938f, -0.930644f, + 0.256551f, 0.152959f, -0.954351f, + 0.258627f, -0.046304f, -0.964867f, + 0.454843f, 0.419734f, -0.785456f, + 0.460971f, 0.392883f, -0.795707f, + 0.470766f, 0.344228f, -0.812334f, + 0.483207f, 0.267414f, -0.833667f, + 0.495448f, 0.153250f, -0.855012f, + 0.500207f, -0.046372f, -0.864663f, + 0.641841f, 0.419990f, -0.641599f, + 0.650410f, 0.393130f, -0.649935f, + 0.664173f, 0.344457f, -0.663494f, + 0.681710f, 0.267607f, -0.680925f, + 0.699059f, 0.153377f, -0.698421f, + 0.706160f, -0.046369f, -0.706532f, + 0.785627f, 0.419737f, -0.454545f, + 0.796043f, 0.392890f, -0.460384f, + 0.812813f, 0.344241f, -0.469929f, + 0.834220f, 0.267436f, -0.482239f, + 0.855462f, 0.153286f, -0.494660f, + 0.864402f, -0.046300f, -0.500666f, + 0.876980f, 0.419078f, -0.235117f, + 0.888521f, 0.392258f, -0.238044f, + 0.907136f, 0.343667f, -0.242894f, + 0.930926f, 0.266970f, -0.249206f, + 0.954579f, 0.153012f, -0.255668f, + 0.964734f, -0.046198f, -0.259142f, + 0.943833f, -0.330414f, -0.002283f, + 0.821403f, -0.570341f, -0.002745f, + 0.709541f, -0.704661f, -0.001958f, + 0.652305f, -0.757957f, -0.000466f, + 0.728669f, -0.684856f, 0.003576f, + 0.889124f, -0.457656f, 0.003164f, + 0.912037f, -0.330868f, 0.242313f, + 0.793697f, -0.570897f, 0.210051f, + 0.685340f, -0.705168f, 0.181787f, + 0.629635f, -0.758420f, 0.168401f, + 0.702387f, -0.685364f, 0.192168f, + 0.857690f, -0.458122f, 0.233435f, + 0.817716f, -0.331385f, 0.470664f, + 0.711528f, -0.571608f, 0.408646f, + 0.614071f, -0.705839f, 0.353140f, + 0.563713f, -0.759034f, 0.325721f, + 0.627891f, -0.686037f, 0.367569f, + 0.767411f, -0.458787f, 0.447879f, + 0.668728f, -0.331557f, 0.665486f, + 0.582010f, -0.571874f, 0.578122f, + 0.502096f, -0.706097f, 0.499327f, + 0.460496f, -0.759271f, 0.459838f, + 0.511760f, -0.686297f, 0.516816f, + 0.625950f, -0.459060f, 0.630437f, + 0.474660f, -0.331321f, 0.815429f, + 0.413434f, -0.571590f, 0.708771f, + 0.356547f, -0.705839f, 0.612100f, + 0.326530f, -0.759035f, 0.563244f, + 0.361346f, -0.686040f, 0.631489f, + 0.442349f, -0.458832f, 0.770585f, + 0.246794f, -0.330773f, 0.910869f, + 0.215429f, -0.570870f, 0.792274f, + 0.185619f, -0.705168f, 0.684313f, + 0.169311f, -0.758421f, 0.629390f, + 0.185170f, -0.685368f, 0.704260f, + 0.227231f, -0.458188f, 0.859319f, + 0.002283f, -0.330414f, 0.943833f, + 0.002745f, -0.570341f, 0.821403f, + 0.001958f, -0.704661f, 0.709541f, + 0.000466f, -0.757957f, 0.652305f, + -0.003576f, -0.684856f, 0.728669f, + -0.003164f, -0.457656f, 0.889124f, + -0.242313f, -0.330868f, 0.912037f, + -0.210051f, -0.570897f, 0.793697f, + -0.181787f, -0.705168f, 0.685340f, + -0.168401f, -0.758420f, 0.629635f, + -0.192168f, -0.685364f, 0.702387f, + -0.233435f, -0.458122f, 0.857690f, + -0.470664f, -0.331385f, 0.817716f, + -0.408646f, -0.571608f, 0.711528f, + -0.353140f, -0.705839f, 0.614071f, + -0.325721f, -0.759034f, 0.563713f, + -0.367569f, -0.686037f, 0.627891f, + -0.447879f, -0.458787f, 0.767411f, + -0.665486f, -0.331557f, 0.668728f, + -0.578122f, -0.571874f, 0.582010f, + -0.499327f, -0.706097f, 0.502096f, + -0.459838f, -0.759271f, 0.460496f, + -0.516816f, -0.686297f, 0.511760f, + -0.630437f, -0.459060f, 0.625950f, + -0.815429f, -0.331321f, 0.474660f, + -0.708771f, -0.571590f, 0.413434f, + -0.612100f, -0.705839f, 0.356547f, + -0.563244f, -0.759035f, 0.326530f, + -0.631489f, -0.686040f, 0.361346f, + -0.770585f, -0.458832f, 0.442349f, + -0.910869f, -0.330773f, 0.246794f, + -0.792274f, -0.570870f, 0.215429f, + -0.684313f, -0.705168f, 0.185619f, + -0.629390f, -0.758421f, 0.169311f, + -0.704260f, -0.685368f, 0.185170f, + -0.859319f, -0.458188f, 0.227231f, + -0.943833f, -0.330414f, 0.002283f, + -0.821403f, -0.570341f, 0.002745f, + -0.709541f, -0.704661f, 0.001958f, + -0.652305f, -0.757957f, 0.000466f, + -0.728669f, -0.684856f, -0.003576f, + -0.889124f, -0.457656f, -0.003164f, + -0.912037f, -0.330868f, -0.242313f, + -0.793697f, -0.570897f, -0.210051f, + -0.685340f, -0.705168f, -0.181787f, + -0.629635f, -0.758420f, -0.168401f, + -0.702387f, -0.685364f, -0.192168f, + -0.857690f, -0.458122f, -0.233435f, + -0.817716f, -0.331385f, -0.470664f, + -0.711528f, -0.571608f, -0.408646f, + -0.614071f, -0.705839f, -0.353140f, + -0.563713f, -0.759034f, -0.325721f, + -0.627891f, -0.686037f, -0.367569f, + -0.767411f, -0.458787f, -0.447879f, + -0.668728f, -0.331557f, -0.665486f, + -0.582010f, -0.571874f, -0.578122f, + -0.502096f, -0.706097f, -0.499327f, + -0.460496f, -0.759271f, -0.459838f, + -0.511760f, -0.686297f, -0.516816f, + -0.625950f, -0.459060f, -0.630437f, + -0.474660f, -0.331321f, -0.815429f, + -0.413434f, -0.571590f, -0.708771f, + -0.356547f, -0.705839f, -0.612100f, + -0.326530f, -0.759035f, -0.563244f, + -0.361346f, -0.686040f, -0.631489f, + -0.442349f, -0.458832f, -0.770585f, + -0.246794f, -0.330773f, -0.910869f, + -0.215429f, -0.570870f, -0.792274f, + -0.185619f, -0.705168f, -0.684313f, + -0.169311f, -0.758421f, -0.629390f, + -0.185170f, -0.685368f, -0.704260f, + -0.227231f, -0.458188f, -0.859319f, + -0.002283f, -0.330414f, -0.943833f, + -0.002745f, -0.570341f, -0.821403f, + -0.001958f, -0.704661f, -0.709541f, + -0.000466f, -0.757957f, -0.652305f, + 0.003576f, -0.684856f, -0.728669f, + 0.003164f, -0.457656f, -0.889124f, + 0.242313f, -0.330868f, -0.912037f, + 0.210051f, -0.570897f, -0.793697f, + 0.181787f, -0.705168f, -0.685340f, + 0.168401f, -0.758420f, -0.629635f, + 0.192168f, -0.685364f, -0.702387f, + 0.233435f, -0.458122f, -0.857690f, + 0.470664f, -0.331385f, -0.817716f, + 0.408646f, -0.571608f, -0.711528f, + 0.353140f, -0.705839f, -0.614071f, + 0.325721f, -0.759034f, -0.563713f, + 0.367569f, -0.686037f, -0.627891f, + 0.447879f, -0.458787f, -0.767411f, + 0.665486f, -0.331557f, -0.668728f, + 0.578122f, -0.571874f, -0.582010f, + 0.499327f, -0.706097f, -0.502096f, + 0.459838f, -0.759271f, -0.460496f, + 0.516816f, -0.686297f, -0.511760f, + 0.630437f, -0.459060f, -0.625950f, + 0.815429f, -0.331321f, -0.474660f, + 0.708771f, -0.571590f, -0.413434f, + 0.612100f, -0.705839f, -0.356547f, + 0.563244f, -0.759035f, -0.326530f, + 0.631489f, -0.686040f, -0.361346f, + 0.770585f, -0.458832f, -0.442349f, + 0.910869f, -0.330773f, -0.246794f, + 0.792274f, -0.570870f, -0.215429f, + 0.684313f, -0.705168f, -0.185619f, + 0.629390f, -0.758421f, -0.169311f, + 0.704260f, -0.685368f, -0.185170f, + 0.859319f, -0.458188f, -0.227231f, + 0.777345f, -0.628990f, -0.010332f, + 0.361793f, -0.932236f, -0.006477f, + 0.152402f, -0.988315f, -0.002559f, + 0.066422f, -0.997791f, -0.001190f, + 0.027401f, -0.999624f, -0.001027f, + 0.000000f, -1.000000f, 0.000000f, + 0.753154f, -0.629440f, 0.191218f, + 0.350766f, -0.932386f, 0.087291f, + 0.147688f, -0.988344f, 0.036926f, + 0.064386f, -0.997796f, 0.016021f, + 0.026706f, -0.999625f, 0.006087f, + 0.677297f, -0.629962f, 0.380023f, + 0.315543f, -0.932612f, 0.175124f, + 0.132774f, -0.988389f, 0.073881f, + 0.057900f, -0.997805f, 0.032133f, + 0.024157f, -0.999626f, 0.012794f, + 0.556310f, -0.630147f, 0.541695f, + 0.259523f, -0.932707f, 0.250409f, + 0.109137f, -0.988408f, 0.105540f, + 0.047613f, -0.997809f, 0.045941f, + 0.020018f, -0.999627f, 0.018575f, + 0.398014f, -0.629932f, 0.666911f, + 0.186318f, -0.932635f, 0.308995f, + 0.078296f, -0.988394f, 0.130182f, + 0.034185f, -0.997806f, 0.056696f, + 0.014564f, -0.999627f, 0.023117f, + 0.211443f, -0.629395f, 0.747766f, + 0.099921f, -0.932420f, 0.347287f, + 0.041912f, -0.988352f, 0.146303f, + 0.018338f, -0.997798f, 0.063741f, + 0.008087f, -0.999625f, 0.026150f, + 0.010332f, -0.628990f, 0.777345f, + 0.006477f, -0.932236f, 0.361793f, + 0.002559f, -0.988315f, 0.152402f, + 0.001190f, -0.997791f, 0.066422f, + 0.001027f, -0.999624f, 0.027401f, + -0.191218f, -0.629440f, 0.753154f, + -0.087291f, -0.932386f, 0.350766f, + -0.036926f, -0.988344f, 0.147688f, + -0.016021f, -0.997796f, 0.064386f, + -0.006087f, -0.999625f, 0.026706f, + -0.380023f, -0.629962f, 0.677297f, + -0.175124f, -0.932612f, 0.315543f, + -0.073881f, -0.988389f, 0.132774f, + -0.032133f, -0.997805f, 0.057900f, + -0.012794f, -0.999626f, 0.024157f, + -0.541695f, -0.630147f, 0.556310f, + -0.250409f, -0.932707f, 0.259523f, + -0.105540f, -0.988408f, 0.109137f, + -0.045941f, -0.997809f, 0.047613f, + -0.018575f, -0.999627f, 0.020018f, + -0.666911f, -0.629932f, 0.398014f, + -0.308995f, -0.932635f, 0.186318f, + -0.130182f, -0.988394f, 0.078296f, + -0.056696f, -0.997806f, 0.034185f, + -0.023117f, -0.999627f, 0.014564f, + -0.747766f, -0.629395f, 0.211443f, + -0.347287f, -0.932420f, 0.099921f, + -0.146303f, -0.988352f, 0.041912f, + -0.063741f, -0.997798f, 0.018338f, + -0.026150f, -0.999625f, 0.008087f, + -0.777345f, -0.628990f, 0.010332f, + -0.361793f, -0.932236f, 0.006477f, + -0.152402f, -0.988315f, 0.002559f, + -0.066422f, -0.997791f, 0.001190f, + -0.027401f, -0.999624f, 0.001027f, + -0.753154f, -0.629440f, -0.191218f, + -0.350766f, -0.932386f, -0.087291f, + -0.147688f, -0.988344f, -0.036926f, + -0.064386f, -0.997796f, -0.016021f, + -0.026706f, -0.999625f, -0.006087f, + -0.677297f, -0.629962f, -0.380023f, + -0.315543f, -0.932612f, -0.175124f, + -0.132774f, -0.988389f, -0.073881f, + -0.057900f, -0.997805f, -0.032133f, + -0.024157f, -0.999626f, -0.012794f, + -0.556310f, -0.630147f, -0.541695f, + -0.259523f, -0.932707f, -0.250409f, + -0.109137f, -0.988408f, -0.105540f, + -0.047613f, -0.997809f, -0.045941f, + -0.020018f, -0.999627f, -0.018575f, + -0.398014f, -0.629932f, -0.666911f, + -0.186318f, -0.932635f, -0.308995f, + -0.078296f, -0.988394f, -0.130182f, + -0.034185f, -0.997806f, -0.056696f, + -0.014564f, -0.999627f, -0.023117f, + -0.211443f, -0.629395f, -0.747766f, + -0.099921f, -0.932420f, -0.347287f, + -0.041912f, -0.988352f, -0.146303f, + -0.018338f, -0.997798f, -0.063741f, + -0.008087f, -0.999625f, -0.026150f, + -0.010332f, -0.628990f, -0.777345f, + -0.006477f, -0.932236f, -0.361793f, + -0.002559f, -0.988315f, -0.152402f, + -0.001190f, -0.997791f, -0.066422f, + -0.001027f, -0.999624f, -0.027401f, + 0.191218f, -0.629440f, -0.753154f, + 0.087291f, -0.932386f, -0.350766f, + 0.036926f, -0.988344f, -0.147688f, + 0.016021f, -0.997796f, -0.064386f, + 0.006087f, -0.999625f, -0.026706f, + 0.380023f, -0.629962f, -0.677297f, + 0.175124f, -0.932612f, -0.315543f, + 0.073881f, -0.988389f, -0.132774f, + 0.032133f, -0.997805f, -0.057900f, + 0.012794f, -0.999626f, -0.024157f, + 0.541695f, -0.630147f, -0.556310f, + 0.250409f, -0.932707f, -0.259523f, + 0.105540f, -0.988408f, -0.109137f, + 0.045941f, -0.997809f, -0.047613f, + 0.018575f, -0.999627f, -0.020018f, + 0.666911f, -0.629932f, -0.398014f, + 0.308995f, -0.932635f, -0.186318f, + 0.130182f, -0.988394f, -0.078296f, + 0.056696f, -0.997806f, -0.034185f, + 0.023117f, -0.999627f, -0.014564f, + 0.747766f, -0.629395f, -0.211443f, + 0.347287f, -0.932420f, -0.099921f, + 0.146303f, -0.988352f, -0.041912f, + 0.063741f, -0.997798f, -0.018338f, + 0.026150f, -0.999625f, -0.008087f, + 0.003252f, -0.999017f, 0.044215f, + 0.015240f, -0.999884f, -0.000426f, + 0.059928f, -0.998202f, -0.000876f, + 0.167134f, -0.985934f, -0.001083f, + 0.403838f, -0.914830f, -0.000203f, + 0.792445f, -0.609943f, 0.000242f, + 0.995161f, -0.098254f, -0.001013f, + 0.003195f, -0.927908f, 0.372795f, + 0.015041f, -0.949764f, 0.312606f, + 0.059227f, -0.948266f, 0.311904f, + 0.164453f, -0.933549f, 0.318499f, + 0.388162f, -0.854219f, 0.345890f, + 0.729394f, -0.561905f, 0.390189f, + 0.912351f, -0.095332f, 0.398156f, + 0.002232f, -0.597680f, 0.801731f, + 0.010830f, -0.681497f, 0.731741f, + 0.043613f, -0.679614f, 0.732272f, + 0.120047f, -0.660320f, 0.741327f, + 0.267930f, -0.580441f, 0.768962f, + 0.467285f, -0.367107f, 0.804287f, + 0.584006f, -0.067606f, 0.808929f, + -0.000653f, 0.152635f, 0.988282f, + -0.002559f, 0.000905f, 0.999996f, + -0.007405f, 0.000384f, 0.999972f, + -0.016090f, -0.004746f, 0.999859f, + -0.025703f, -0.019620f, 0.999477f, + -0.020936f, -0.035053f, 0.999166f, + -0.002824f, -0.023899f, 0.999710f, + -0.003296f, 0.756255f, 0.654269f, + -0.015405f, 0.681251f, 0.731887f, + -0.059217f, 0.676283f, 0.734258f, + -0.158438f, 0.643792f, 0.748619f, + -0.334170f, 0.526967f, 0.781432f, + -0.518177f, 0.278028f, 0.808822f, + -0.588929f, 0.016391f, 0.808019f, + -0.004352f, 0.967350f, 0.253408f, + -0.020677f, 0.949300f, 0.313691f, + -0.081844f, 0.945117f, 0.316317f, + -0.226175f, 0.916097f, 0.331076f, + -0.500500f, 0.784289f, 0.366594f, + -0.804374f, 0.439635f, 0.399630f, + -0.916460f, 0.037237f, 0.398390f, + -0.004517f, 0.999011f, -0.044228f, + -0.021584f, 0.999767f, 0.000265f, + -0.086245f, 0.996274f, 0.000157f, + -0.240673f, 0.970606f, -0.000608f, + -0.540280f, 0.841484f, -0.001597f, + -0.877811f, 0.479008f, 0.000390f, + -0.999074f, 0.043021f, 0.000686f, + -0.004094f, 0.927919f, -0.372759f, + -0.019687f, 0.949518f, -0.313093f, + -0.079023f, 0.945545f, -0.315752f, + -0.219600f, 0.917458f, -0.331734f, + -0.488715f, 0.790534f, -0.369071f, + -0.797673f, 0.452036f, -0.399226f, + -0.916555f, 0.045675f, -0.397293f, + -0.002516f, 0.597699f, -0.801716f, + -0.012433f, 0.681272f, -0.731925f, + -0.050950f, 0.677183f, -0.734048f, + -0.140298f, 0.648898f, -0.747829f, + -0.303501f, 0.546934f, -0.780224f, + -0.495541f, 0.315794f, -0.809143f, + -0.586888f, 0.043544f, -0.808497f, + 0.000557f, -0.152599f, -0.988288f, + 0.002074f, -0.000969f, -0.999997f, + 0.005499f, -0.001410f, -0.999984f, + 0.011569f, 0.000546f, -0.999933f, + 0.019331f, 0.010342f, -0.999760f, + 0.017294f, 0.025347f, -0.999529f, + 0.002733f, 0.020710f, -0.999782f, + 0.002668f, -0.756195f, -0.654340f, + 0.012416f, -0.681586f, -0.731633f, + 0.047946f, -0.679845f, -0.731787f, + 0.130533f, -0.659594f, -0.740200f, + 0.293034f, -0.569168f, -0.768231f, + 0.500213f, -0.318883f, -0.805047f, + 0.587808f, -0.026599f, -0.808563f, + 0.003191f, -0.967332f, -0.253494f, + 0.014981f, -0.949482f, -0.313464f, + 0.058954f, -0.947784f, -0.313417f, + 0.164056f, -0.933187f, -0.319761f, + 0.391212f, -0.853217f, -0.344925f, + 0.743675f, -0.542841f, -0.390219f, + 0.913602f, -0.073956f, -0.399828f, + 0.972925f, 0.231121f, -0.000918f, + 0.912330f, 0.409438f, -0.003849f, + 0.828029f, 0.560649f, -0.006408f, + 0.716807f, 0.697239f, -0.006712f, + 0.575989f, 0.817451f, -0.003302f, + 0.495133f, 0.867633f, -0.045350f, + 0.893985f, 0.213142f, 0.394158f, + 0.840605f, 0.383895f, 0.382108f, + 0.768860f, 0.531454f, 0.355543f, + 0.672509f, 0.665677f, 0.323426f, + 0.545610f, 0.779633f, 0.307380f, + 0.479303f, 0.843050f, 0.244000f, + 0.576388f, 0.133958f, 0.806122f, + 0.544470f, 0.253746f, 0.799478f, + 0.508754f, 0.364144f, 0.780108f, + 0.461180f, 0.471780f, 0.751490f, + 0.387281f, 0.561166f, 0.731509f, + 0.371347f, 0.666129f, 0.646818f, + 0.002410f, -0.014515f, 0.999892f, + 0.001301f, -0.016411f, 0.999865f, + 0.000720f, -0.020201f, 0.999796f, + 0.003256f, -0.021359f, 0.999767f, + 0.008876f, -0.013337f, 0.999872f, + 0.072759f, 0.131709f, 0.988615f, + -0.569088f, -0.161451f, 0.806271f, + -0.524317f, -0.294841f, 0.798850f, + -0.472635f, -0.410610f, 0.779754f, + -0.415783f, -0.508606f, 0.753953f, + -0.349674f, -0.579676f, 0.736006f, + -0.279208f, -0.530698f, 0.800252f, + -0.885693f, -0.241406f, 0.396574f, + -0.803204f, -0.449996f, 0.390343f, + -0.697513f, -0.613444f, 0.370354f, + -0.588462f, -0.732277f, 0.342757f, + -0.485206f, -0.813008f, 0.321860f, + -0.425879f, -0.823534f, 0.374725f, + -0.965787f, -0.259335f, 0.000592f, + -0.872611f, -0.488406f, 0.003010f, + -0.748651f, -0.662945f, 0.005037f, + -0.622443f, -0.782648f, 0.005056f, + -0.509112f, -0.860697f, 0.002551f, + -0.455515f, -0.889038f, 0.046023f, + -0.888605f, -0.232245f, -0.395529f, + -0.809378f, -0.443445f, -0.385051f, + -0.704052f, -0.611598f, -0.360913f, + -0.592713f, -0.733528f, -0.332607f, + -0.486334f, -0.814293f, -0.316868f, + -0.441890f, -0.860789f, -0.252538f, + -0.574477f, -0.139332f, -0.806575f, + -0.532235f, -0.275661f, -0.800460f, + -0.480844f, -0.396171f, -0.782201f, + -0.423172f, -0.499323f, -0.756044f, + -0.355443f, -0.574187f, -0.737543f, + -0.348424f, -0.670745f, -0.654753f, + -0.001891f, 0.012937f, -0.999915f, + 0.001397f, 0.011921f, -0.999928f, + 0.005089f, 0.014178f, -0.999887f, + 0.004896f, 0.016722f, -0.999848f, + -0.002003f, 0.012285f, -0.999922f, + -0.068183f, -0.130578f, -0.989091f, + 0.573387f, 0.149188f, -0.805587f, + 0.541227f, 0.266714f, -0.797456f, + 0.503525f, 0.377270f, -0.777258f, + 0.451452f, 0.484144f, -0.749530f, + 0.372386f, 0.571022f, -0.731616f, + 0.289707f, 0.529053f, -0.797604f, + 0.892654f, 0.216131f, -0.395546f, + 0.837234f, 0.384836f, -0.388510f, + 0.763231f, 0.531640f, -0.367202f, + 0.665469f, 0.666102f, -0.336837f, + 0.537995f, 0.781974f, -0.314766f, + 0.455324f, 0.810920f, -0.367545f, + -0.145927f, 0.987044f, 0.066705f, + -0.350253f, 0.936641f, -0.005157f, + -0.710995f, 0.703191f, -0.003047f, + -0.899400f, 0.437101f, 0.004678f, + -0.930238f, 0.366579f, 0.016656f, + -0.845840f, 0.533040f, 0.020564f, + -0.646372f, 0.763018f, 0.002776f, + -0.128906f, 0.841567f, 0.524546f, + -0.292019f, 0.852082f, 0.434375f, + -0.615355f, 0.675119f, 0.406882f, + -0.799678f, 0.453205f, 0.393853f, + -0.814130f, 0.384381f, 0.435251f, + -0.711742f, 0.496654f, 0.496746f, + -0.538718f, 0.683956f, 0.491922f, + -0.054328f, 0.445430f, 0.893667f, + -0.120328f, 0.535740f, 0.835765f, + -0.285367f, 0.495269f, 0.820533f, + -0.427214f, 0.405516f, 0.808112f, + -0.455262f, 0.354182f, 0.816880f, + -0.386518f, 0.375163f, 0.842530f, + -0.289150f, 0.468105f, 0.835027f, + 0.075157f, -0.092491f, 0.992873f, + 0.130249f, 0.040179f, 0.990667f, + 0.205304f, 0.124938f, 0.970691f, + 0.176764f, 0.184322f, 0.966840f, + 0.082193f, 0.182483f, 0.979767f, + 0.009842f, 0.124532f, 0.992167f, + -0.004171f, 0.105296f, 0.994432f, + 0.213849f, -0.587755f, 0.780264f, + 0.361728f, -0.447069f, 0.818097f, + 0.601635f, -0.258541f, 0.755772f, + 0.672221f, -0.099063f, 0.733693f, + 0.583247f, -0.084870f, 0.807849f, + 0.409251f, -0.235708f, 0.881451f, + 0.284284f, -0.385654f, 0.877755f, + 0.302637f, -0.880762f, 0.364237f, + 0.496428f, -0.756105f, 0.426456f, + 0.790450f, -0.487110f, 0.371365f, + 0.895860f, -0.277360f, 0.347141f, + 0.865262f, -0.295907f, 0.404673f, + 0.690272f, -0.542643f, 0.478606f, + 0.467747f, -0.753579f, 0.461879f, + 0.321563f, -0.944505f, -0.067141f, + 0.531566f, -0.847002f, 0.005046f, + 0.833505f, -0.552508f, 0.002163f, + 0.944185f, -0.329343f, -0.006880f, + 0.932318f, -0.361245f, -0.016874f, + 0.768639f, -0.639601f, -0.010215f, + 0.513002f, -0.858387f, 0.000964f, + 0.278331f, -0.809595f, -0.516806f, + 0.491568f, -0.763636f, -0.418594f, + 0.788478f, -0.493107f, -0.367624f, + 0.891089f, -0.275271f, -0.360815f, + 0.856479f, -0.282922f, -0.431739f, + 0.692218f, -0.527331f, -0.492704f, + 0.473487f, -0.749262f, -0.463052f, + 0.166654f, -0.429938f, -0.887344f, + 0.339768f, -0.458348f, -0.821264f, + 0.590160f, -0.276240f, -0.758553f, + 0.668115f, -0.103914f, -0.736766f, + 0.590009f, -0.076740f, -0.803741f, + 0.433287f, -0.219357f, -0.874154f, + 0.299036f, -0.368898f, -0.880052f, + 0.027869f, 0.102187f, -0.994375f, + 0.088152f, 0.031815f, -0.995599f, + 0.174456f, 0.096185f, -0.979956f, + 0.188708f, 0.161291f, -0.968697f, + 0.127686f, 0.175774f, -0.976115f, + 0.054509f, 0.130986f, -0.989885f, + 0.015877f, 0.116730f, -0.993037f, + -0.081072f, 0.607187f, -0.790412f, + -0.164116f, 0.522469f, -0.836715f, + -0.319626f, 0.463405f, -0.826495f, + -0.422971f, 0.383450f, -0.821013f, + -0.424534f, 0.353597f, -0.833511f, + -0.351612f, 0.388106f, -0.851905f, + -0.270475f, 0.475063f, -0.837352f, + -0.133739f, 0.917541f, -0.374476f, + -0.316043f, 0.839490f, -0.442011f, + -0.631181f, 0.656649f, -0.412823f, + -0.807405f, 0.443017f, -0.389658f, + -0.821659f, 0.386229f, -0.419171f, + -0.707748f, 0.517393f, -0.481037f, + -0.526814f, 0.693790f, -0.491043f, + -0.461017f, 0.887371f, -0.005987f, + -0.290675f, 0.956710f, -0.014601f, + 0.085518f, 0.995086f, -0.049913f, + 0.887713f, 0.456166f, -0.062285f, + 0.822992f, -0.567263f, 0.029937f, + 0.659878f, -0.743158f, 0.110798f, + -0.391094f, 0.831360f, 0.394824f, + -0.253310f, 0.936825f, 0.241231f, + 0.015366f, 0.995010f, -0.098588f, + 0.520185f, 0.549881f, -0.653482f, + 0.628856f, -0.382376f, -0.677000f, + 0.578948f, -0.646092f, -0.497378f, + -0.223422f, 0.660928f, 0.716420f, + -0.156131f, 0.874986f, 0.458282f, + -0.036467f, 0.998264f, -0.046261f, + 0.156637f, 0.682491f, -0.713913f, + 0.263632f, 0.005571f, -0.964607f, + 0.312409f, -0.324778f, -0.892704f, + -0.001751f, 0.339383f, 0.940647f, + -0.021119f, 0.759902f, 0.649695f, + -0.044404f, 0.998121f, 0.042219f, + -0.032529f, 0.802862f, -0.595277f, + -0.008745f, 0.371564f, -0.928366f, + 0.042529f, 0.077913f, -0.996053f, + 0.280020f, -0.238192f, 0.929975f, + 0.227305f, 0.491486f, 0.840699f, + -0.003105f, 0.987407f, 0.158172f, + -0.143918f, 0.895866f, -0.420370f, + -0.200177f, 0.683872f, -0.701604f, + -0.187188f, 0.500198f, -0.845437f, + 0.453673f, -0.746835f, 0.486229f, + 0.692158f, -0.080062f, 0.717291f, + 0.185758f, 0.942536f, 0.277704f, + -0.211188f, 0.955274f, -0.207004f, + -0.312961f, 0.881061f, -0.354665f, + -0.336331f, 0.811345f, -0.478122f, + 0.482445f, -0.875816f, -0.013906f, + 0.913013f, -0.405572f, -0.043811f, + 0.506909f, 0.853920f, 0.117742f, + -0.234033f, 0.972124f, 0.014295f, + -0.348033f, 0.937468f, 0.005277f, + -0.384064f, 0.921073f, -0.064185f, + 0.457762f, -0.717668f, -0.524792f, + 0.683347f, -0.063014f, -0.727369f, + 0.357361f, 0.898186f, -0.256038f, + -0.207010f, 0.947863f, 0.242287f, + -0.314387f, 0.872357f, 0.374372f, + -0.361040f, 0.872819f, 0.328385f, + 0.280225f, -0.218552f, -0.934724f, + 0.261124f, 0.434074f, -0.862203f, + 0.060553f, 0.978577f, -0.196775f, + -0.131809f, 0.881094f, 0.454203f, + -0.195016f, 0.658858f, 0.726550f, + -0.247824f, 0.630359f, 0.735684f, + 0.008860f, 0.321862f, -0.946745f, + 0.001382f, 0.733189f, -0.680023f, + -0.012720f, 0.997949f, -0.062734f, + -0.011656f, 0.785221f, 0.619106f, + 0.000967f, 0.344022f, 0.938961f, + -0.037360f, 0.214324f, 0.976048f, + -0.213360f, 0.648838f, -0.730401f, + -0.140052f, 0.865891f, -0.480227f, + -0.000809f, 0.999500f, 0.031611f, + 0.194529f, 0.659081f, 0.726478f, + 0.266832f, -0.005234f, 0.963729f, + 0.219380f, -0.217247f, 0.951145f, + -0.384886f, 0.827121f, -0.409553f, + -0.240915f, 0.932642f, -0.268588f, + 0.065830f, 0.996786f, 0.045658f, + 0.597011f, 0.507703f, 0.621141f, + 0.613004f, -0.369418f, 0.698395f, + 0.486873f, -0.566787f, 0.664610f, + 0.000000f, 1.000000f, 0.000000f, + 0.395791f, 0.918207f, 0.015676f, + 0.964544f, 0.263762f, 0.009177f, + 0.839041f, -0.544056f, -0.003654f, + 0.788969f, -0.614430f, 0.001943f, + 0.991025f, -0.133647f, 0.002953f, + 0.732531f, 0.680606f, -0.013206f, + 0.377669f, 0.918491f, 0.117221f, + 0.929557f, 0.263662f, 0.257694f, + 0.811158f, -0.544801f, 0.212638f, + 0.761156f, -0.615195f, 0.205370f, + 0.956515f, -0.133833f, 0.259168f, + 0.710689f, 0.680955f, 0.176694f, + 0.333696f, 0.918791f, 0.210878f, + 0.830713f, 0.263784f, 0.490239f, + 0.727549f, -0.545809f, 0.415650f, + 0.681011f, -0.616288f, 0.395491f, + 0.856413f, -0.134443f, 0.498480f, + 0.640176f, 0.681271f, 0.355027f, + 0.267591f, 0.918878f, 0.289928f, + 0.675416f, 0.263955f, 0.688579f, + 0.594970f, -0.546203f, 0.589638f, + 0.555330f, -0.616730f, 0.557901f, + 0.698694f, -0.134804f, 0.702606f, + 0.526898f, 0.681345f, 0.508082f, + 0.183499f, 0.918711f, 0.349712f, + 0.474031f, 0.264098f, 0.839969f, + 0.422194f, -0.545768f, 0.723802f, + 0.392296f, -0.616276f, 0.682867f, + 0.493598f, -0.134679f, 0.859199f, + 0.378184f, 0.681197f, 0.626856f, + 0.086498f, 0.918378f, 0.386136f, + 0.239605f, 0.264096f, 0.934261f, + 0.219887f, -0.544743f, 0.809262f, + 0.201667f, -0.615183f, 0.762155f, + 0.253529f, -0.134173f, 0.957977f, + 0.202631f, 0.680866f, 0.703820f, + -0.015676f, 0.918207f, 0.395791f, + -0.009177f, 0.263762f, 0.964544f, + 0.003654f, -0.544057f, 0.839041f, + -0.001943f, -0.614430f, 0.788969f, + -0.002953f, -0.133647f, 0.991025f, + 0.013206f, 0.680606f, 0.732531f, + -0.117221f, 0.918491f, 0.377669f, + -0.257694f, 0.263662f, 0.929557f, + -0.212638f, -0.544801f, 0.811158f, + -0.205370f, -0.615195f, 0.761156f, + -0.259168f, -0.133833f, 0.956515f, + -0.176694f, 0.680955f, 0.710689f, + -0.210878f, 0.918791f, 0.333696f, + -0.490239f, 0.263784f, 0.830713f, + -0.415650f, -0.545809f, 0.727549f, + -0.395491f, -0.616288f, 0.681011f, + -0.498480f, -0.134443f, 0.856413f, + -0.355027f, 0.681271f, 0.640176f, + -0.289928f, 0.918878f, 0.267591f, + -0.688579f, 0.263955f, 0.675416f, + -0.589638f, -0.546203f, 0.594970f, + -0.557901f, -0.616730f, 0.555330f, + -0.702606f, -0.134804f, 0.698694f, + -0.508082f, 0.681345f, 0.526898f, + -0.349712f, 0.918711f, 0.183499f, + -0.839969f, 0.264098f, 0.474031f, + -0.723802f, -0.545768f, 0.422194f, + -0.682867f, -0.616276f, 0.392296f, + -0.859199f, -0.134679f, 0.493598f, + -0.626856f, 0.681197f, 0.378184f, + -0.386136f, 0.918378f, 0.086498f, + -0.934261f, 0.264096f, 0.239605f, + -0.809262f, -0.544743f, 0.219887f, + -0.762155f, -0.615183f, 0.201667f, + -0.957977f, -0.134173f, 0.253529f, + -0.703820f, 0.680866f, 0.202631f, + -0.395791f, 0.918207f, -0.015676f, + -0.964544f, 0.263762f, -0.009177f, + -0.839041f, -0.544057f, 0.003654f, + -0.788969f, -0.614430f, -0.001943f, + -0.991025f, -0.133647f, -0.002953f, + -0.732531f, 0.680606f, 0.013206f, + -0.377669f, 0.918491f, -0.117221f, + -0.929557f, 0.263662f, -0.257694f, + -0.811158f, -0.544801f, -0.212638f, + -0.761156f, -0.615195f, -0.205370f, + -0.956515f, -0.133833f, -0.259168f, + -0.710689f, 0.680955f, -0.176694f, + -0.333696f, 0.918791f, -0.210878f, + -0.830713f, 0.263784f, -0.490239f, + -0.727549f, -0.545809f, -0.415650f, + -0.681011f, -0.616288f, -0.395491f, + -0.856413f, -0.134443f, -0.498480f, + -0.640176f, 0.681271f, -0.355027f, + -0.267591f, 0.918878f, -0.289928f, + -0.675416f, 0.263955f, -0.688579f, + -0.594970f, -0.546203f, -0.589638f, + -0.555330f, -0.616730f, -0.557901f, + -0.698694f, -0.134804f, -0.702606f, + -0.526898f, 0.681345f, -0.508082f, + -0.183499f, 0.918711f, -0.349712f, + -0.474031f, 0.264098f, -0.839969f, + -0.422194f, -0.545768f, -0.723802f, + -0.392296f, -0.616276f, -0.682867f, + -0.493598f, -0.134679f, -0.859199f, + -0.378184f, 0.681197f, -0.626856f, + -0.086498f, 0.918378f, -0.386136f, + -0.239605f, 0.264096f, -0.934261f, + -0.219887f, -0.544743f, -0.809262f, + -0.201667f, -0.615183f, -0.762155f, + -0.253529f, -0.134173f, -0.957977f, + -0.202631f, 0.680866f, -0.703820f, + 0.015676f, 0.918207f, -0.395791f, + 0.009177f, 0.263762f, -0.964544f, + -0.003654f, -0.544057f, -0.839041f, + 0.001943f, -0.614430f, -0.788969f, + 0.002953f, -0.133647f, -0.991025f, + -0.013206f, 0.680606f, -0.732531f, + 0.117221f, 0.918491f, -0.377669f, + 0.257694f, 0.263662f, -0.929557f, + 0.212638f, -0.544801f, -0.811158f, + 0.205370f, -0.615195f, -0.761156f, + 0.259168f, -0.133833f, -0.956515f, + 0.176694f, 0.680955f, -0.710689f, + 0.210878f, 0.918791f, -0.333696f, + 0.490239f, 0.263784f, -0.830713f, + 0.415650f, -0.545809f, -0.727549f, + 0.395491f, -0.616288f, -0.681011f, + 0.498480f, -0.134443f, -0.856413f, + 0.355027f, 0.681271f, -0.640176f, + 0.289928f, 0.918878f, -0.267591f, + 0.688579f, 0.263955f, -0.675416f, + 0.589638f, -0.546203f, -0.594970f, + 0.557901f, -0.616730f, -0.555330f, + 0.702606f, -0.134804f, -0.698694f, + 0.508082f, 0.681345f, -0.526898f, + 0.349712f, 0.918711f, -0.183499f, + 0.839969f, 0.264098f, -0.474031f, + 0.723802f, -0.545768f, -0.422194f, + 0.682867f, -0.616276f, -0.392296f, + 0.859199f, -0.134679f, -0.493598f, + 0.626856f, 0.681197f, -0.378184f, + 0.386136f, 0.918378f, -0.086498f, + 0.934261f, 0.264096f, -0.239605f, + 0.809262f, -0.544743f, -0.219887f, + 0.762155f, -0.615183f, -0.201667f, + 0.957977f, -0.134173f, -0.253529f, + 0.703820f, 0.680866f, -0.202631f, + 0.299763f, 0.954005f, -0.004004f, + 0.180158f, 0.983637f, -0.001176f, + 0.158462f, 0.987365f, 0.000232f, + 0.213709f, 0.976895f, 0.002171f, + 0.489301f, 0.872063f, 0.009504f, + 0.686607f, 0.726410f, -0.029990f, + 0.290238f, 0.954117f, 0.073644f, + 0.174086f, 0.983681f, 0.045452f, + 0.152777f, 0.987401f, 0.041212f, + 0.205547f, 0.976963f, 0.057393f, + 0.469598f, 0.872357f, 0.135911f, + 0.670656f, 0.726754f, 0.148493f, + 0.260698f, 0.954280f, 0.146242f, + 0.156021f, 0.983742f, 0.088932f, + 0.136587f, 0.987448f, 0.079312f, + 0.183282f, 0.977046f, 0.108577f, + 0.417739f, 0.872696f, 0.252776f, + 0.608331f, 0.727460f, 0.317389f, + 0.214008f, 0.954348f, 0.208377f, + 0.127716f, 0.983767f, 0.126063f, + 0.111442f, 0.987466f, 0.111767f, + 0.149005f, 0.977076f, 0.152056f, + 0.338347f, 0.872812f, 0.351738f, + 0.505565f, 0.727811f, 0.463351f, + 0.153158f, 0.954293f, 0.256647f, + 0.090962f, 0.983745f, 0.154830f, + 0.078913f, 0.987448f, 0.136822f, + 0.104831f, 0.977040f, 0.185479f, + 0.236319f, 0.872663f, 0.427333f, + 0.369272f, 0.727651f, 0.578067f, + 0.081449f, 0.954136f, 0.288080f, + 0.047744f, 0.983685f, 0.173450f, + 0.040760f, 0.987400f, 0.152903f, + 0.053164f, 0.976955f, 0.206721f, + 0.117360f, 0.872307f, 0.474665f, + 0.207008f, 0.727038f, 0.654648f, + 0.004004f, 0.954005f, 0.299763f, + 0.001176f, 0.983637f, 0.180158f, + -0.000232f, 0.987365f, 0.158462f, + -0.002171f, 0.976895f, 0.213709f, + -0.009504f, 0.872063f, 0.489301f, + 0.029990f, 0.726410f, 0.686607f, + -0.073644f, 0.954117f, 0.290238f, + -0.045452f, 0.983681f, 0.174086f, + -0.041212f, 0.987401f, 0.152777f, + -0.057393f, 0.976963f, 0.205547f, + -0.135911f, 0.872357f, 0.469598f, + -0.148493f, 0.726754f, 0.670656f, + -0.146242f, 0.954280f, 0.260698f, + -0.088932f, 0.983742f, 0.156021f, + -0.079312f, 0.987448f, 0.136587f, + -0.108577f, 0.977046f, 0.183282f, + -0.252776f, 0.872696f, 0.417739f, + -0.317389f, 0.727460f, 0.608331f, + -0.208377f, 0.954348f, 0.214008f, + -0.126063f, 0.983767f, 0.127716f, + -0.111767f, 0.987466f, 0.111442f, + -0.152056f, 0.977076f, 0.149005f, + -0.351738f, 0.872812f, 0.338347f, + -0.463351f, 0.727811f, 0.505565f, + -0.256647f, 0.954293f, 0.153158f, + -0.154830f, 0.983745f, 0.090962f, + -0.136822f, 0.987448f, 0.078913f, + -0.185479f, 0.977040f, 0.104831f, + -0.427333f, 0.872663f, 0.236319f, + -0.578067f, 0.727651f, 0.369272f, + -0.288080f, 0.954136f, 0.081449f, + -0.173450f, 0.983685f, 0.047744f, + -0.152903f, 0.987400f, 0.040760f, + -0.206721f, 0.976955f, 0.053164f, + -0.474665f, 0.872307f, 0.117360f, + -0.654648f, 0.727038f, 0.207008f, + -0.299763f, 0.954005f, 0.004004f, + -0.180158f, 0.983637f, 0.001176f, + -0.158462f, 0.987365f, -0.000232f, + -0.213709f, 0.976895f, -0.002171f, + -0.489301f, 0.872063f, -0.009504f, + -0.686607f, 0.726410f, 0.029990f, + -0.290238f, 0.954117f, -0.073644f, + -0.174086f, 0.983681f, -0.045452f, + -0.152777f, 0.987401f, -0.041212f, + -0.205547f, 0.976963f, -0.057393f, + -0.469598f, 0.872357f, -0.135911f, + -0.670656f, 0.726754f, -0.148493f, + -0.260698f, 0.954280f, -0.146242f, + -0.156021f, 0.983742f, -0.088932f, + -0.136587f, 0.987448f, -0.079312f, + -0.183282f, 0.977046f, -0.108577f, + -0.417739f, 0.872696f, -0.252776f, + -0.608331f, 0.727460f, -0.317389f, + -0.214008f, 0.954348f, -0.208377f, + -0.127716f, 0.983767f, -0.126063f, + -0.111442f, 0.987466f, -0.111767f, + -0.149005f, 0.977076f, -0.152056f, + -0.338347f, 0.872812f, -0.351738f, + -0.505565f, 0.727811f, -0.463351f, + -0.153158f, 0.954293f, -0.256647f, + -0.090962f, 0.983745f, -0.154830f, + -0.078913f, 0.987448f, -0.136822f, + -0.104831f, 0.977040f, -0.185479f, + -0.236319f, 0.872663f, -0.427333f, + -0.369272f, 0.727651f, -0.578067f, + -0.081449f, 0.954136f, -0.288080f, + -0.047744f, 0.983685f, -0.173450f, + -0.040760f, 0.987400f, -0.152903f, + -0.053164f, 0.976955f, -0.206721f, + -0.117360f, 0.872307f, -0.474665f, + -0.207008f, 0.727038f, -0.654648f, + -0.004004f, 0.954005f, -0.299763f, + -0.001176f, 0.983637f, -0.180158f, + 0.000232f, 0.987365f, -0.158462f, + 0.002171f, 0.976895f, -0.213709f, + 0.009504f, 0.872063f, -0.489301f, + -0.029990f, 0.726410f, -0.686607f, + 0.073644f, 0.954117f, -0.290238f, + 0.045452f, 0.983681f, -0.174086f, + 0.041212f, 0.987401f, -0.152777f, + 0.057393f, 0.976963f, -0.205547f, + 0.135911f, 0.872357f, -0.469598f, + 0.148493f, 0.726754f, -0.670656f, + 0.146242f, 0.954280f, -0.260698f, + 0.088932f, 0.983742f, -0.156021f, + 0.079312f, 0.987448f, -0.136587f, + 0.108577f, 0.977046f, -0.183282f, + 0.252776f, 0.872696f, -0.417739f, + 0.317389f, 0.727460f, -0.608331f, + 0.208377f, 0.954348f, -0.214008f, + 0.126063f, 0.983767f, -0.127716f, + 0.111767f, 0.987466f, -0.111442f, + 0.152056f, 0.977076f, -0.149005f, + 0.351738f, 0.872812f, -0.338347f, + 0.463351f, 0.727811f, -0.505565f, + 0.256647f, 0.954293f, -0.153158f, + 0.154830f, 0.983745f, -0.090962f, + 0.136822f, 0.987448f, -0.078913f, + 0.185479f, 0.977040f, -0.104831f, + 0.427333f, 0.872663f, -0.236319f, + 0.578067f, 0.727651f, -0.369272f, + 0.288080f, 0.954136f, -0.081449f, + 0.173450f, 0.983685f, -0.047744f, + 0.152903f, 0.987400f, -0.040760f, + 0.206721f, 0.976955f, -0.053164f, + 0.474665f, 0.872307f, -0.117360f, + 0.654648f, 0.727038f, -0.207008f, +}; +static D3DXVECTOR3* teapotNormals = ( D3DXVECTOR3* )teapotNormalsfloats; + +static WORD teapotIndices[NUMTEAPOTINDICES] = +{ + 0, 7, 8, + 8, 1, 0, + 1, 8, 9, + 9, 2, 1, + 2, 9, 10, + 10, 3, 2, + 3, 10, 11, + 11, 4, 3, + 4, 11, 12, + 12, 5, 4, + 5, 12, 13, + 13, 6, 5, + 7, 14, 15, + 15, 8, 7, + 8, 15, 16, + 16, 9, 8, + 9, 16, 17, + 17, 10, 9, + 10, 17, 18, + 18, 11, 10, + 11, 18, 19, + 19, 12, 11, + 12, 19, 20, + 20, 13, 12, + 14, 21, 22, + 22, 15, 14, + 15, 22, 23, + 23, 16, 15, + 16, 23, 24, + 24, 17, 16, + 17, 24, 25, + 25, 18, 17, + 18, 25, 26, + 26, 19, 18, + 19, 26, 27, + 27, 20, 19, + 21, 28, 29, + 29, 22, 21, + 22, 29, 30, + 30, 23, 22, + 23, 30, 31, + 31, 24, 23, + 24, 31, 32, + 32, 25, 24, + 25, 32, 33, + 33, 26, 25, + 26, 33, 34, + 34, 27, 26, + 28, 35, 36, + 36, 29, 28, + 29, 36, 37, + 37, 30, 29, + 30, 37, 38, + 38, 31, 30, + 31, 38, 39, + 39, 32, 31, + 32, 39, 40, + 40, 33, 32, + 33, 40, 41, + 41, 34, 33, + 35, 42, 43, + 43, 36, 35, + 36, 43, 44, + 44, 37, 36, + 37, 44, 45, + 45, 38, 37, + 38, 45, 46, + 46, 39, 38, + 39, 46, 47, + 47, 40, 39, + 40, 47, 48, + 48, 41, 40, + 42, 49, 50, + 50, 43, 42, + 43, 50, 51, + 51, 44, 43, + 44, 51, 52, + 52, 45, 44, + 45, 52, 53, + 53, 46, 45, + 46, 53, 54, + 54, 47, 46, + 47, 54, 55, + 55, 48, 47, + 49, 56, 57, + 57, 50, 49, + 50, 57, 58, + 58, 51, 50, + 51, 58, 59, + 59, 52, 51, + 52, 59, 60, + 60, 53, 52, + 53, 60, 61, + 61, 54, 53, + 54, 61, 62, + 62, 55, 54, + 56, 63, 64, + 64, 57, 56, + 57, 64, 65, + 65, 58, 57, + 58, 65, 66, + 66, 59, 58, + 59, 66, 67, + 67, 60, 59, + 60, 67, 68, + 68, 61, 60, + 61, 68, 69, + 69, 62, 61, + 63, 70, 71, + 71, 64, 63, + 64, 71, 72, + 72, 65, 64, + 65, 72, 73, + 73, 66, 65, + 66, 73, 74, + 74, 67, 66, + 67, 74, 75, + 75, 68, 67, + 68, 75, 76, + 76, 69, 68, + 70, 77, 78, + 78, 71, 70, + 71, 78, 79, + 79, 72, 71, + 72, 79, 80, + 80, 73, 72, + 73, 80, 81, + 81, 74, 73, + 74, 81, 82, + 82, 75, 74, + 75, 82, 83, + 83, 76, 75, + 77, 84, 85, + 85, 78, 77, + 78, 85, 86, + 86, 79, 78, + 79, 86, 87, + 87, 80, 79, + 80, 87, 88, + 88, 81, 80, + 81, 88, 89, + 89, 82, 81, + 82, 89, 90, + 90, 83, 82, + 84, 91, 92, + 92, 85, 84, + 85, 92, 93, + 93, 86, 85, + 86, 93, 94, + 94, 87, 86, + 87, 94, 95, + 95, 88, 87, + 88, 95, 96, + 96, 89, 88, + 89, 96, 97, + 97, 90, 89, + 91, 98, 99, + 99, 92, 91, + 92, 99, 100, + 100, 93, 92, + 93, 100, 101, + 101, 94, 93, + 94, 101, 102, + 102, 95, 94, + 95, 102, 103, + 103, 96, 95, + 96, 103, 104, + 104, 97, 96, + 98, 105, 106, + 106, 99, 98, + 99, 106, 107, + 107, 100, 99, + 100, 107, 108, + 108, 101, 100, + 101, 108, 109, + 109, 102, 101, + 102, 109, 110, + 110, 103, 102, + 103, 110, 111, + 111, 104, 103, + 105, 112, 113, + 113, 106, 105, + 106, 113, 114, + 114, 107, 106, + 107, 114, 115, + 115, 108, 107, + 108, 115, 116, + 116, 109, 108, + 109, 116, 117, + 117, 110, 109, + 110, 117, 118, + 118, 111, 110, + 112, 119, 120, + 120, 113, 112, + 113, 120, 121, + 121, 114, 113, + 114, 121, 122, + 122, 115, 114, + 115, 122, 123, + 123, 116, 115, + 116, 123, 124, + 124, 117, 116, + 117, 124, 125, + 125, 118, 117, + 119, 126, 127, + 127, 120, 119, + 120, 127, 128, + 128, 121, 120, + 121, 128, 129, + 129, 122, 121, + 122, 129, 130, + 130, 123, 122, + 123, 130, 131, + 131, 124, 123, + 124, 131, 132, + 132, 125, 124, + 126, 133, 134, + 134, 127, 126, + 127, 134, 135, + 135, 128, 127, + 128, 135, 136, + 136, 129, 128, + 129, 136, 137, + 137, 130, 129, + 130, 137, 138, + 138, 131, 130, + 131, 138, 139, + 139, 132, 131, + 133, 140, 141, + 141, 134, 133, + 134, 141, 142, + 142, 135, 134, + 135, 142, 143, + 143, 136, 135, + 136, 143, 144, + 144, 137, 136, + 137, 144, 145, + 145, 138, 137, + 138, 145, 146, + 146, 139, 138, + 140, 147, 148, + 148, 141, 140, + 141, 148, 149, + 149, 142, 141, + 142, 149, 150, + 150, 143, 142, + 143, 150, 151, + 151, 144, 143, + 144, 151, 152, + 152, 145, 144, + 145, 152, 153, + 153, 146, 145, + 147, 154, 155, + 155, 148, 147, + 148, 155, 156, + 156, 149, 148, + 149, 156, 157, + 157, 150, 149, + 150, 157, 158, + 158, 151, 150, + 151, 158, 159, + 159, 152, 151, + 152, 159, 160, + 160, 153, 152, + 154, 161, 162, + 162, 155, 154, + 155, 162, 163, + 163, 156, 155, + 156, 163, 164, + 164, 157, 156, + 157, 164, 165, + 165, 158, 157, + 158, 165, 166, + 166, 159, 158, + 159, 166, 167, + 167, 160, 159, + 161, 0, 1, + 1, 162, 161, + 162, 1, 2, + 2, 163, 162, + 163, 2, 3, + 3, 164, 163, + 164, 3, 4, + 4, 165, 164, + 165, 4, 5, + 5, 166, 165, + 166, 5, 6, + 6, 167, 166, + 6, 13, 174, + 174, 168, 6, + 168, 174, 175, + 175, 169, 168, + 169, 175, 176, + 176, 170, 169, + 170, 176, 177, + 177, 171, 170, + 171, 177, 178, + 178, 172, 171, + 172, 178, 179, + 179, 173, 172, + 13, 20, 180, + 180, 174, 13, + 174, 180, 181, + 181, 175, 174, + 175, 181, 182, + 182, 176, 175, + 176, 182, 183, + 183, 177, 176, + 177, 183, 184, + 184, 178, 177, + 178, 184, 185, + 185, 179, 178, + 20, 27, 186, + 186, 180, 20, + 180, 186, 187, + 187, 181, 180, + 181, 187, 188, + 188, 182, 181, + 182, 188, 189, + 189, 183, 182, + 183, 189, 190, + 190, 184, 183, + 184, 190, 191, + 191, 185, 184, + 27, 34, 192, + 192, 186, 27, + 186, 192, 193, + 193, 187, 186, + 187, 193, 194, + 194, 188, 187, + 188, 194, 195, + 195, 189, 188, + 189, 195, 196, + 196, 190, 189, + 190, 196, 197, + 197, 191, 190, + 34, 41, 198, + 198, 192, 34, + 192, 198, 199, + 199, 193, 192, + 193, 199, 200, + 200, 194, 193, + 194, 200, 201, + 201, 195, 194, + 195, 201, 202, + 202, 196, 195, + 196, 202, 203, + 203, 197, 196, + 41, 48, 204, + 204, 198, 41, + 198, 204, 205, + 205, 199, 198, + 199, 205, 206, + 206, 200, 199, + 200, 206, 207, + 207, 201, 200, + 201, 207, 208, + 208, 202, 201, + 202, 208, 209, + 209, 203, 202, + 48, 55, 210, + 210, 204, 48, + 204, 210, 211, + 211, 205, 204, + 205, 211, 212, + 212, 206, 205, + 206, 212, 213, + 213, 207, 206, + 207, 213, 214, + 214, 208, 207, + 208, 214, 215, + 215, 209, 208, + 55, 62, 216, + 216, 210, 55, + 210, 216, 217, + 217, 211, 210, + 211, 217, 218, + 218, 212, 211, + 212, 218, 219, + 219, 213, 212, + 213, 219, 220, + 220, 214, 213, + 214, 220, 221, + 221, 215, 214, + 62, 69, 222, + 222, 216, 62, + 216, 222, 223, + 223, 217, 216, + 217, 223, 224, + 224, 218, 217, + 218, 224, 225, + 225, 219, 218, + 219, 225, 226, + 226, 220, 219, + 220, 226, 227, + 227, 221, 220, + 69, 76, 228, + 228, 222, 69, + 222, 228, 229, + 229, 223, 222, + 223, 229, 230, + 230, 224, 223, + 224, 230, 231, + 231, 225, 224, + 225, 231, 232, + 232, 226, 225, + 226, 232, 233, + 233, 227, 226, + 76, 83, 234, + 234, 228, 76, + 228, 234, 235, + 235, 229, 228, + 229, 235, 236, + 236, 230, 229, + 230, 236, 237, + 237, 231, 230, + 231, 237, 238, + 238, 232, 231, + 232, 238, 239, + 239, 233, 232, + 83, 90, 240, + 240, 234, 83, + 234, 240, 241, + 241, 235, 234, + 235, 241, 242, + 242, 236, 235, + 236, 242, 243, + 243, 237, 236, + 237, 243, 244, + 244, 238, 237, + 238, 244, 245, + 245, 239, 238, + 90, 97, 246, + 246, 240, 90, + 240, 246, 247, + 247, 241, 240, + 241, 247, 248, + 248, 242, 241, + 242, 248, 249, + 249, 243, 242, + 243, 249, 250, + 250, 244, 243, + 244, 250, 251, + 251, 245, 244, + 97, 104, 252, + 252, 246, 97, + 246, 252, 253, + 253, 247, 246, + 247, 253, 254, + 254, 248, 247, + 248, 254, 255, + 255, 249, 248, + 249, 255, 256, + 256, 250, 249, + 250, 256, 257, + 257, 251, 250, + 104, 111, 258, + 258, 252, 104, + 252, 258, 259, + 259, 253, 252, + 253, 259, 260, + 260, 254, 253, + 254, 260, 261, + 261, 255, 254, + 255, 261, 262, + 262, 256, 255, + 256, 262, 263, + 263, 257, 256, + 111, 118, 264, + 264, 258, 111, + 258, 264, 265, + 265, 259, 258, + 259, 265, 266, + 266, 260, 259, + 260, 266, 267, + 267, 261, 260, + 261, 267, 268, + 268, 262, 261, + 262, 268, 269, + 269, 263, 262, + 118, 125, 270, + 270, 264, 118, + 264, 270, 271, + 271, 265, 264, + 265, 271, 272, + 272, 266, 265, + 266, 272, 273, + 273, 267, 266, + 267, 273, 274, + 274, 268, 267, + 268, 274, 275, + 275, 269, 268, + 125, 132, 276, + 276, 270, 125, + 270, 276, 277, + 277, 271, 270, + 271, 277, 278, + 278, 272, 271, + 272, 278, 279, + 279, 273, 272, + 273, 279, 280, + 280, 274, 273, + 274, 280, 281, + 281, 275, 274, + 132, 139, 282, + 282, 276, 132, + 276, 282, 283, + 283, 277, 276, + 277, 283, 284, + 284, 278, 277, + 278, 284, 285, + 285, 279, 278, + 279, 285, 286, + 286, 280, 279, + 280, 286, 287, + 287, 281, 280, + 139, 146, 288, + 288, 282, 139, + 282, 288, 289, + 289, 283, 282, + 283, 289, 290, + 290, 284, 283, + 284, 290, 291, + 291, 285, 284, + 285, 291, 292, + 292, 286, 285, + 286, 292, 293, + 293, 287, 286, + 146, 153, 294, + 294, 288, 146, + 288, 294, 295, + 295, 289, 288, + 289, 295, 296, + 296, 290, 289, + 290, 296, 297, + 297, 291, 290, + 291, 297, 298, + 298, 292, 291, + 292, 298, 299, + 299, 293, 292, + 153, 160, 300, + 300, 294, 153, + 294, 300, 301, + 301, 295, 294, + 295, 301, 302, + 302, 296, 295, + 296, 302, 303, + 303, 297, 296, + 297, 303, 304, + 304, 298, 297, + 298, 304, 305, + 305, 299, 298, + 160, 167, 306, + 306, 300, 160, + 300, 306, 307, + 307, 301, 300, + 301, 307, 308, + 308, 302, 301, + 302, 308, 309, + 309, 303, 302, + 303, 309, 310, + 310, 304, 303, + 304, 310, 311, + 311, 305, 304, + 167, 6, 168, + 168, 306, 167, + 306, 168, 169, + 169, 307, 306, + 307, 169, 170, + 170, 308, 307, + 308, 170, 171, + 171, 309, 308, + 309, 171, 172, + 172, 310, 309, + 310, 172, 173, + 173, 311, 310, + 173, 179, 318, + 318, 312, 173, + 312, 318, 319, + 319, 313, 312, + 313, 319, 320, + 320, 314, 313, + 314, 320, 321, + 321, 315, 314, + 315, 321, 322, + 322, 316, 315, + 316, 322, 323, + 323, 317, 316, + 179, 185, 324, + 324, 318, 179, + 318, 324, 325, + 325, 319, 318, + 319, 325, 326, + 326, 320, 319, + 320, 326, 327, + 327, 321, 320, + 321, 327, 328, + 328, 322, 321, + 322, 328, 329, + 329, 323, 322, + 185, 191, 330, + 330, 324, 185, + 324, 330, 331, + 331, 325, 324, + 325, 331, 332, + 332, 326, 325, + 326, 332, 333, + 333, 327, 326, + 327, 333, 334, + 334, 328, 327, + 328, 334, 335, + 335, 329, 328, + 191, 197, 336, + 336, 330, 191, + 330, 336, 337, + 337, 331, 330, + 331, 337, 338, + 338, 332, 331, + 332, 338, 339, + 339, 333, 332, + 333, 339, 340, + 340, 334, 333, + 334, 340, 341, + 341, 335, 334, + 197, 203, 342, + 342, 336, 197, + 336, 342, 343, + 343, 337, 336, + 337, 343, 344, + 344, 338, 337, + 338, 344, 345, + 345, 339, 338, + 339, 345, 346, + 346, 340, 339, + 340, 346, 347, + 347, 341, 340, + 203, 209, 348, + 348, 342, 203, + 342, 348, 349, + 349, 343, 342, + 343, 349, 350, + 350, 344, 343, + 344, 350, 351, + 351, 345, 344, + 345, 351, 352, + 352, 346, 345, + 346, 352, 353, + 353, 347, 346, + 209, 215, 354, + 354, 348, 209, + 348, 354, 355, + 355, 349, 348, + 349, 355, 356, + 356, 350, 349, + 350, 356, 357, + 357, 351, 350, + 351, 357, 358, + 358, 352, 351, + 352, 358, 359, + 359, 353, 352, + 215, 221, 360, + 360, 354, 215, + 354, 360, 361, + 361, 355, 354, + 355, 361, 362, + 362, 356, 355, + 356, 362, 363, + 363, 357, 356, + 357, 363, 364, + 364, 358, 357, + 358, 364, 365, + 365, 359, 358, + 221, 227, 366, + 366, 360, 221, + 360, 366, 367, + 367, 361, 360, + 361, 367, 368, + 368, 362, 361, + 362, 368, 369, + 369, 363, 362, + 363, 369, 370, + 370, 364, 363, + 364, 370, 371, + 371, 365, 364, + 227, 233, 372, + 372, 366, 227, + 366, 372, 373, + 373, 367, 366, + 367, 373, 374, + 374, 368, 367, + 368, 374, 375, + 375, 369, 368, + 369, 375, 376, + 376, 370, 369, + 370, 376, 377, + 377, 371, 370, + 233, 239, 378, + 378, 372, 233, + 372, 378, 379, + 379, 373, 372, + 373, 379, 380, + 380, 374, 373, + 374, 380, 381, + 381, 375, 374, + 375, 381, 382, + 382, 376, 375, + 376, 382, 383, + 383, 377, 376, + 239, 245, 384, + 384, 378, 239, + 378, 384, 385, + 385, 379, 378, + 379, 385, 386, + 386, 380, 379, + 380, 386, 387, + 387, 381, 380, + 381, 387, 388, + 388, 382, 381, + 382, 388, 389, + 389, 383, 382, + 245, 251, 390, + 390, 384, 245, + 384, 390, 391, + 391, 385, 384, + 385, 391, 392, + 392, 386, 385, + 386, 392, 393, + 393, 387, 386, + 387, 393, 394, + 394, 388, 387, + 388, 394, 395, + 395, 389, 388, + 251, 257, 396, + 396, 390, 251, + 390, 396, 397, + 397, 391, 390, + 391, 397, 398, + 398, 392, 391, + 392, 398, 399, + 399, 393, 392, + 393, 399, 400, + 400, 394, 393, + 394, 400, 401, + 401, 395, 394, + 257, 263, 402, + 402, 396, 257, + 396, 402, 403, + 403, 397, 396, + 397, 403, 404, + 404, 398, 397, + 398, 404, 405, + 405, 399, 398, + 399, 405, 406, + 406, 400, 399, + 400, 406, 407, + 407, 401, 400, + 263, 269, 408, + 408, 402, 263, + 402, 408, 409, + 409, 403, 402, + 403, 409, 410, + 410, 404, 403, + 404, 410, 411, + 411, 405, 404, + 405, 411, 412, + 412, 406, 405, + 406, 412, 413, + 413, 407, 406, + 269, 275, 414, + 414, 408, 269, + 408, 414, 415, + 415, 409, 408, + 409, 415, 416, + 416, 410, 409, + 410, 416, 417, + 417, 411, 410, + 411, 417, 418, + 418, 412, 411, + 412, 418, 419, + 419, 413, 412, + 275, 281, 420, + 420, 414, 275, + 414, 420, 421, + 421, 415, 414, + 415, 421, 422, + 422, 416, 415, + 416, 422, 423, + 423, 417, 416, + 417, 423, 424, + 424, 418, 417, + 418, 424, 425, + 425, 419, 418, + 281, 287, 426, + 426, 420, 281, + 420, 426, 427, + 427, 421, 420, + 421, 427, 428, + 428, 422, 421, + 422, 428, 429, + 429, 423, 422, + 423, 429, 430, + 430, 424, 423, + 424, 430, 431, + 431, 425, 424, + 287, 293, 432, + 432, 426, 287, + 426, 432, 433, + 433, 427, 426, + 427, 433, 434, + 434, 428, 427, + 428, 434, 435, + 435, 429, 428, + 429, 435, 436, + 436, 430, 429, + 430, 436, 437, + 437, 431, 430, + 293, 299, 438, + 438, 432, 293, + 432, 438, 439, + 439, 433, 432, + 433, 439, 440, + 440, 434, 433, + 434, 440, 441, + 441, 435, 434, + 435, 441, 442, + 442, 436, 435, + 436, 442, 443, + 443, 437, 436, + 299, 305, 444, + 444, 438, 299, + 438, 444, 445, + 445, 439, 438, + 439, 445, 446, + 446, 440, 439, + 440, 446, 447, + 447, 441, 440, + 441, 447, 448, + 448, 442, 441, + 442, 448, 449, + 449, 443, 442, + 305, 311, 450, + 450, 444, 305, + 444, 450, 451, + 451, 445, 444, + 445, 451, 452, + 452, 446, 445, + 446, 452, 453, + 453, 447, 446, + 447, 453, 454, + 454, 448, 447, + 448, 454, 455, + 455, 449, 448, + 311, 173, 312, + 312, 450, 311, + 450, 312, 313, + 313, 451, 450, + 451, 313, 314, + 314, 452, 451, + 452, 314, 315, + 315, 453, 452, + 453, 315, 316, + 316, 454, 453, + 454, 316, 317, + 317, 455, 454, + 317, 323, 462, + 462, 456, 317, + 456, 462, 463, + 463, 457, 456, + 457, 463, 464, + 464, 458, 457, + 458, 464, 465, + 465, 459, 458, + 459, 465, 466, + 466, 460, 459, + 460, 466, 461, + 323, 329, 467, + 467, 462, 323, + 462, 467, 468, + 468, 463, 462, + 463, 468, 469, + 469, 464, 463, + 464, 469, 470, + 470, 465, 464, + 465, 470, 471, + 471, 466, 465, + 466, 471, 461, + 329, 335, 472, + 472, 467, 329, + 467, 472, 473, + 473, 468, 467, + 468, 473, 474, + 474, 469, 468, + 469, 474, 475, + 475, 470, 469, + 470, 475, 476, + 476, 471, 470, + 471, 476, 461, + 335, 341, 477, + 477, 472, 335, + 472, 477, 478, + 478, 473, 472, + 473, 478, 479, + 479, 474, 473, + 474, 479, 480, + 480, 475, 474, + 475, 480, 481, + 481, 476, 475, + 476, 481, 461, + 341, 347, 482, + 482, 477, 341, + 477, 482, 483, + 483, 478, 477, + 478, 483, 484, + 484, 479, 478, + 479, 484, 485, + 485, 480, 479, + 480, 485, 486, + 486, 481, 480, + 481, 486, 461, + 347, 353, 487, + 487, 482, 347, + 482, 487, 488, + 488, 483, 482, + 483, 488, 489, + 489, 484, 483, + 484, 489, 490, + 490, 485, 484, + 485, 490, 491, + 491, 486, 485, + 486, 491, 461, + 353, 359, 492, + 492, 487, 353, + 487, 492, 493, + 493, 488, 487, + 488, 493, 494, + 494, 489, 488, + 489, 494, 495, + 495, 490, 489, + 490, 495, 496, + 496, 491, 490, + 491, 496, 461, + 359, 365, 497, + 497, 492, 359, + 492, 497, 498, + 498, 493, 492, + 493, 498, 499, + 499, 494, 493, + 494, 499, 500, + 500, 495, 494, + 495, 500, 501, + 501, 496, 495, + 496, 501, 461, + 365, 371, 502, + 502, 497, 365, + 497, 502, 503, + 503, 498, 497, + 498, 503, 504, + 504, 499, 498, + 499, 504, 505, + 505, 500, 499, + 500, 505, 506, + 506, 501, 500, + 501, 506, 461, + 371, 377, 507, + 507, 502, 371, + 502, 507, 508, + 508, 503, 502, + 503, 508, 509, + 509, 504, 503, + 504, 509, 510, + 510, 505, 504, + 505, 510, 511, + 511, 506, 505, + 506, 511, 461, + 377, 383, 512, + 512, 507, 377, + 507, 512, 513, + 513, 508, 507, + 508, 513, 514, + 514, 509, 508, + 509, 514, 515, + 515, 510, 509, + 510, 515, 516, + 516, 511, 510, + 511, 516, 461, + 383, 389, 517, + 517, 512, 383, + 512, 517, 518, + 518, 513, 512, + 513, 518, 519, + 519, 514, 513, + 514, 519, 520, + 520, 515, 514, + 515, 520, 521, + 521, 516, 515, + 516, 521, 461, + 389, 395, 522, + 522, 517, 389, + 517, 522, 523, + 523, 518, 517, + 518, 523, 524, + 524, 519, 518, + 519, 524, 525, + 525, 520, 519, + 520, 525, 526, + 526, 521, 520, + 521, 526, 461, + 395, 401, 527, + 527, 522, 395, + 522, 527, 528, + 528, 523, 522, + 523, 528, 529, + 529, 524, 523, + 524, 529, 530, + 530, 525, 524, + 525, 530, 531, + 531, 526, 525, + 526, 531, 461, + 401, 407, 532, + 532, 527, 401, + 527, 532, 533, + 533, 528, 527, + 528, 533, 534, + 534, 529, 528, + 529, 534, 535, + 535, 530, 529, + 530, 535, 536, + 536, 531, 530, + 531, 536, 461, + 407, 413, 537, + 537, 532, 407, + 532, 537, 538, + 538, 533, 532, + 533, 538, 539, + 539, 534, 533, + 534, 539, 540, + 540, 535, 534, + 535, 540, 541, + 541, 536, 535, + 536, 541, 461, + 413, 419, 542, + 542, 537, 413, + 537, 542, 543, + 543, 538, 537, + 538, 543, 544, + 544, 539, 538, + 539, 544, 545, + 545, 540, 539, + 540, 545, 546, + 546, 541, 540, + 541, 546, 461, + 419, 425, 547, + 547, 542, 419, + 542, 547, 548, + 548, 543, 542, + 543, 548, 549, + 549, 544, 543, + 544, 549, 550, + 550, 545, 544, + 545, 550, 551, + 551, 546, 545, + 546, 551, 461, + 425, 431, 552, + 552, 547, 425, + 547, 552, 553, + 553, 548, 547, + 548, 553, 554, + 554, 549, 548, + 549, 554, 555, + 555, 550, 549, + 550, 555, 556, + 556, 551, 550, + 551, 556, 461, + 431, 437, 557, + 557, 552, 431, + 552, 557, 558, + 558, 553, 552, + 553, 558, 559, + 559, 554, 553, + 554, 559, 560, + 560, 555, 554, + 555, 560, 561, + 561, 556, 555, + 556, 561, 461, + 437, 443, 562, + 562, 557, 437, + 557, 562, 563, + 563, 558, 557, + 558, 563, 564, + 564, 559, 558, + 559, 564, 565, + 565, 560, 559, + 560, 565, 566, + 566, 561, 560, + 561, 566, 461, + 443, 449, 567, + 567, 562, 443, + 562, 567, 568, + 568, 563, 562, + 563, 568, 569, + 569, 564, 563, + 564, 569, 570, + 570, 565, 564, + 565, 570, 571, + 571, 566, 565, + 566, 571, 461, + 449, 455, 572, + 572, 567, 449, + 567, 572, 573, + 573, 568, 567, + 568, 573, 574, + 574, 569, 568, + 569, 574, 575, + 575, 570, 569, + 570, 575, 576, + 576, 571, 570, + 571, 576, 461, + 455, 317, 456, + 456, 572, 455, + 572, 456, 457, + 457, 573, 572, + 573, 457, 458, + 458, 574, 573, + 574, 458, 459, + 459, 575, 574, + 575, 459, 460, + 460, 576, 575, + 576, 460, 461, + 577, 584, 585, + 585, 578, 577, + 578, 585, 586, + 586, 579, 578, + 579, 586, 587, + 587, 580, 579, + 580, 587, 588, + 588, 581, 580, + 581, 588, 589, + 589, 582, 581, + 582, 589, 590, + 590, 583, 582, + 584, 591, 592, + 592, 585, 584, + 585, 592, 593, + 593, 586, 585, + 586, 593, 594, + 594, 587, 586, + 587, 594, 595, + 595, 588, 587, + 588, 595, 596, + 596, 589, 588, + 589, 596, 597, + 597, 590, 589, + 591, 598, 599, + 599, 592, 591, + 592, 599, 600, + 600, 593, 592, + 593, 600, 601, + 601, 594, 593, + 594, 601, 602, + 602, 595, 594, + 595, 602, 603, + 603, 596, 595, + 596, 603, 604, + 604, 597, 596, + 598, 605, 606, + 606, 599, 598, + 599, 606, 607, + 607, 600, 599, + 600, 607, 608, + 608, 601, 600, + 601, 608, 609, + 609, 602, 601, + 602, 609, 610, + 610, 603, 602, + 603, 610, 611, + 611, 604, 603, + 605, 612, 613, + 613, 606, 605, + 606, 613, 614, + 614, 607, 606, + 607, 614, 615, + 615, 608, 607, + 608, 615, 616, + 616, 609, 608, + 609, 616, 617, + 617, 610, 609, + 610, 617, 618, + 618, 611, 610, + 612, 619, 620, + 620, 613, 612, + 613, 620, 621, + 621, 614, 613, + 614, 621, 622, + 622, 615, 614, + 615, 622, 623, + 623, 616, 615, + 616, 623, 624, + 624, 617, 616, + 617, 624, 625, + 625, 618, 617, + 619, 626, 627, + 627, 620, 619, + 620, 627, 628, + 628, 621, 620, + 621, 628, 629, + 629, 622, 621, + 622, 629, 630, + 630, 623, 622, + 623, 630, 631, + 631, 624, 623, + 624, 631, 632, + 632, 625, 624, + 626, 633, 634, + 634, 627, 626, + 627, 634, 635, + 635, 628, 627, + 628, 635, 636, + 636, 629, 628, + 629, 636, 637, + 637, 630, 629, + 630, 637, 638, + 638, 631, 630, + 631, 638, 639, + 639, 632, 631, + 633, 640, 641, + 641, 634, 633, + 634, 641, 642, + 642, 635, 634, + 635, 642, 643, + 643, 636, 635, + 636, 643, 644, + 644, 637, 636, + 637, 644, 645, + 645, 638, 637, + 638, 645, 646, + 646, 639, 638, + 640, 647, 648, + 648, 641, 640, + 641, 648, 649, + 649, 642, 641, + 642, 649, 650, + 650, 643, 642, + 643, 650, 651, + 651, 644, 643, + 644, 651, 652, + 652, 645, 644, + 645, 652, 653, + 653, 646, 645, + 647, 654, 655, + 655, 648, 647, + 648, 655, 656, + 656, 649, 648, + 649, 656, 657, + 657, 650, 649, + 650, 657, 658, + 658, 651, 650, + 651, 658, 659, + 659, 652, 651, + 652, 659, 660, + 660, 653, 652, + 654, 577, 578, + 578, 655, 654, + 655, 578, 579, + 579, 656, 655, + 656, 579, 580, + 580, 657, 656, + 657, 580, 581, + 581, 658, 657, + 658, 581, 582, + 582, 659, 658, + 659, 582, 583, + 583, 660, 659, + 583, 590, 667, + 667, 661, 583, + 661, 667, 668, + 668, 662, 661, + 662, 668, 669, + 669, 663, 662, + 663, 669, 670, + 670, 664, 663, + 664, 670, 671, + 671, 665, 664, + 665, 671, 672, + 672, 666, 665, + 590, 597, 673, + 673, 667, 590, + 667, 673, 674, + 674, 668, 667, + 668, 674, 675, + 675, 669, 668, + 669, 675, 676, + 676, 670, 669, + 670, 676, 677, + 677, 671, 670, + 671, 677, 678, + 678, 672, 671, + 597, 604, 679, + 679, 673, 597, + 673, 679, 680, + 680, 674, 673, + 674, 680, 681, + 681, 675, 674, + 675, 681, 682, + 682, 676, 675, + 676, 682, 683, + 683, 677, 676, + 677, 683, 684, + 684, 678, 677, + 604, 611, 685, + 685, 679, 604, + 679, 685, 686, + 686, 680, 679, + 680, 686, 687, + 687, 681, 680, + 681, 687, 688, + 688, 682, 681, + 682, 688, 689, + 689, 683, 682, + 683, 689, 690, + 690, 684, 683, + 611, 618, 691, + 691, 685, 611, + 685, 691, 692, + 692, 686, 685, + 686, 692, 693, + 693, 687, 686, + 687, 693, 694, + 694, 688, 687, + 688, 694, 695, + 695, 689, 688, + 689, 695, 696, + 696, 690, 689, + 618, 625, 697, + 697, 691, 618, + 691, 697, 698, + 698, 692, 691, + 692, 698, 699, + 699, 693, 692, + 693, 699, 700, + 700, 694, 693, + 694, 700, 701, + 701, 695, 694, + 695, 701, 702, + 702, 696, 695, + 625, 632, 703, + 703, 697, 625, + 697, 703, 704, + 704, 698, 697, + 698, 704, 705, + 705, 699, 698, + 699, 705, 706, + 706, 700, 699, + 700, 706, 707, + 707, 701, 700, + 701, 707, 708, + 708, 702, 701, + 632, 639, 709, + 709, 703, 632, + 703, 709, 710, + 710, 704, 703, + 704, 710, 711, + 711, 705, 704, + 705, 711, 712, + 712, 706, 705, + 706, 712, 713, + 713, 707, 706, + 707, 713, 714, + 714, 708, 707, + 639, 646, 715, + 715, 709, 639, + 709, 715, 716, + 716, 710, 709, + 710, 716, 717, + 717, 711, 710, + 711, 717, 718, + 718, 712, 711, + 712, 718, 719, + 719, 713, 712, + 713, 719, 720, + 720, 714, 713, + 646, 653, 721, + 721, 715, 646, + 715, 721, 722, + 722, 716, 715, + 716, 722, 723, + 723, 717, 716, + 717, 723, 724, + 724, 718, 717, + 718, 724, 725, + 725, 719, 718, + 719, 725, 726, + 726, 720, 719, + 653, 660, 727, + 727, 721, 653, + 721, 727, 728, + 728, 722, 721, + 722, 728, 729, + 729, 723, 722, + 723, 729, 730, + 730, 724, 723, + 724, 730, 731, + 731, 725, 724, + 725, 731, 732, + 732, 726, 725, + 660, 583, 661, + 661, 727, 660, + 727, 661, 662, + 662, 728, 727, + 728, 662, 663, + 663, 729, 728, + 729, 663, 664, + 664, 730, 729, + 730, 664, 665, + 665, 731, 730, + 731, 665, 666, + 666, 732, 731, + 733, 740, 741, + 741, 734, 733, + 734, 741, 742, + 742, 735, 734, + 735, 742, 743, + 743, 736, 735, + 736, 743, 744, + 744, 737, 736, + 737, 744, 745, + 745, 738, 737, + 738, 745, 746, + 746, 739, 738, + 740, 747, 748, + 748, 741, 740, + 741, 748, 749, + 749, 742, 741, + 742, 749, 750, + 750, 743, 742, + 743, 750, 751, + 751, 744, 743, + 744, 751, 752, + 752, 745, 744, + 745, 752, 753, + 753, 746, 745, + 747, 754, 755, + 755, 748, 747, + 748, 755, 756, + 756, 749, 748, + 749, 756, 757, + 757, 750, 749, + 750, 757, 758, + 758, 751, 750, + 751, 758, 759, + 759, 752, 751, + 752, 759, 760, + 760, 753, 752, + 754, 761, 762, + 762, 755, 754, + 755, 762, 763, + 763, 756, 755, + 756, 763, 764, + 764, 757, 756, + 757, 764, 765, + 765, 758, 757, + 758, 765, 766, + 766, 759, 758, + 759, 766, 767, + 767, 760, 759, + 761, 768, 769, + 769, 762, 761, + 762, 769, 770, + 770, 763, 762, + 763, 770, 771, + 771, 764, 763, + 764, 771, 772, + 772, 765, 764, + 765, 772, 773, + 773, 766, 765, + 766, 773, 774, + 774, 767, 766, + 768, 775, 776, + 776, 769, 768, + 769, 776, 777, + 777, 770, 769, + 770, 777, 778, + 778, 771, 770, + 771, 778, 779, + 779, 772, 771, + 772, 779, 780, + 780, 773, 772, + 773, 780, 781, + 781, 774, 773, + 775, 782, 783, + 783, 776, 775, + 776, 783, 784, + 784, 777, 776, + 777, 784, 785, + 785, 778, 777, + 778, 785, 786, + 786, 779, 778, + 779, 786, 787, + 787, 780, 779, + 780, 787, 788, + 788, 781, 780, + 782, 789, 790, + 790, 783, 782, + 783, 790, 791, + 791, 784, 783, + 784, 791, 792, + 792, 785, 784, + 785, 792, 793, + 793, 786, 785, + 786, 793, 794, + 794, 787, 786, + 787, 794, 795, + 795, 788, 787, + 789, 796, 797, + 797, 790, 789, + 790, 797, 798, + 798, 791, 790, + 791, 798, 799, + 799, 792, 791, + 792, 799, 800, + 800, 793, 792, + 793, 800, 801, + 801, 794, 793, + 794, 801, 802, + 802, 795, 794, + 796, 803, 804, + 804, 797, 796, + 797, 804, 805, + 805, 798, 797, + 798, 805, 806, + 806, 799, 798, + 799, 806, 807, + 807, 800, 799, + 800, 807, 808, + 808, 801, 800, + 801, 808, 809, + 809, 802, 801, + 803, 810, 811, + 811, 804, 803, + 804, 811, 812, + 812, 805, 804, + 805, 812, 813, + 813, 806, 805, + 806, 813, 814, + 814, 807, 806, + 807, 814, 815, + 815, 808, 807, + 808, 815, 816, + 816, 809, 808, + 810, 733, 734, + 734, 811, 810, + 811, 734, 735, + 735, 812, 811, + 812, 735, 736, + 736, 813, 812, + 813, 736, 737, + 737, 814, 813, + 814, 737, 738, + 738, 815, 814, + 815, 738, 739, + 739, 816, 815, + 739, 746, 823, + 823, 817, 739, + 817, 823, 824, + 824, 818, 817, + 818, 824, 825, + 825, 819, 818, + 819, 825, 826, + 826, 820, 819, + 820, 826, 827, + 827, 821, 820, + 821, 827, 828, + 828, 822, 821, + 746, 753, 829, + 829, 823, 746, + 823, 829, 830, + 830, 824, 823, + 824, 830, 831, + 831, 825, 824, + 825, 831, 832, + 832, 826, 825, + 826, 832, 833, + 833, 827, 826, + 827, 833, 834, + 834, 828, 827, + 753, 760, 835, + 835, 829, 753, + 829, 835, 836, + 836, 830, 829, + 830, 836, 837, + 837, 831, 830, + 831, 837, 838, + 838, 832, 831, + 832, 838, 839, + 839, 833, 832, + 833, 839, 840, + 840, 834, 833, + 760, 767, 841, + 841, 835, 760, + 835, 841, 842, + 842, 836, 835, + 836, 842, 843, + 843, 837, 836, + 837, 843, 844, + 844, 838, 837, + 838, 844, 845, + 845, 839, 838, + 839, 845, 846, + 846, 840, 839, + 767, 774, 847, + 847, 841, 767, + 841, 847, 848, + 848, 842, 841, + 842, 848, 849, + 849, 843, 842, + 843, 849, 850, + 850, 844, 843, + 844, 850, 851, + 851, 845, 844, + 845, 851, 852, + 852, 846, 845, + 774, 781, 853, + 853, 847, 774, + 847, 853, 854, + 854, 848, 847, + 848, 854, 855, + 855, 849, 848, + 849, 855, 856, + 856, 850, 849, + 850, 856, 857, + 857, 851, 850, + 851, 857, 858, + 858, 852, 851, + 781, 788, 859, + 859, 853, 781, + 853, 859, 860, + 860, 854, 853, + 854, 860, 861, + 861, 855, 854, + 855, 861, 862, + 862, 856, 855, + 856, 862, 863, + 863, 857, 856, + 857, 863, 864, + 864, 858, 857, + 788, 795, 865, + 865, 859, 788, + 859, 865, 866, + 866, 860, 859, + 860, 866, 867, + 867, 861, 860, + 861, 867, 868, + 868, 862, 861, + 862, 868, 869, + 869, 863, 862, + 863, 869, 870, + 870, 864, 863, + 795, 802, 871, + 871, 865, 795, + 865, 871, 872, + 872, 866, 865, + 866, 872, 873, + 873, 867, 866, + 867, 873, 874, + 874, 868, 867, + 868, 874, 875, + 875, 869, 868, + 869, 875, 876, + 876, 870, 869, + 802, 809, 877, + 877, 871, 802, + 871, 877, 878, + 878, 872, 871, + 872, 878, 879, + 879, 873, 872, + 873, 879, 880, + 880, 874, 873, + 874, 880, 881, + 881, 875, 874, + 875, 881, 882, + 882, 876, 875, + 809, 816, 883, + 883, 877, 809, + 877, 883, 884, + 884, 878, 877, + 878, 884, 885, + 885, 879, 878, + 879, 885, 886, + 886, 880, 879, + 880, 886, 887, + 887, 881, 880, + 881, 887, 888, + 888, 882, 881, + 816, 739, 817, + 817, 883, 816, + 883, 817, 818, + 818, 884, 883, + 884, 818, 819, + 819, 885, 884, + 885, 819, 820, + 820, 886, 885, + 886, 820, 821, + 821, 887, 886, + 887, 821, 822, + 822, 888, 887, + 896, 890, 889, + 890, 896, 897, + 897, 891, 890, + 891, 897, 898, + 898, 892, 891, + 892, 898, 899, + 899, 893, 892, + 893, 899, 900, + 900, 894, 893, + 894, 900, 901, + 901, 895, 894, + 902, 896, 889, + 896, 902, 903, + 903, 897, 896, + 897, 903, 904, + 904, 898, 897, + 898, 904, 905, + 905, 899, 898, + 899, 905, 906, + 906, 900, 899, + 900, 906, 907, + 907, 901, 900, + 908, 902, 889, + 902, 908, 909, + 909, 903, 902, + 903, 909, 910, + 910, 904, 903, + 904, 910, 911, + 911, 905, 904, + 905, 911, 912, + 912, 906, 905, + 906, 912, 913, + 913, 907, 906, + 914, 908, 889, + 908, 914, 915, + 915, 909, 908, + 909, 915, 916, + 916, 910, 909, + 910, 916, 917, + 917, 911, 910, + 911, 917, 918, + 918, 912, 911, + 912, 918, 919, + 919, 913, 912, + 920, 914, 889, + 914, 920, 921, + 921, 915, 914, + 915, 921, 922, + 922, 916, 915, + 916, 922, 923, + 923, 917, 916, + 917, 923, 924, + 924, 918, 917, + 918, 924, 925, + 925, 919, 918, + 926, 920, 889, + 920, 926, 927, + 927, 921, 920, + 921, 927, 928, + 928, 922, 921, + 922, 928, 929, + 929, 923, 922, + 923, 929, 930, + 930, 924, 923, + 924, 930, 931, + 931, 925, 924, + 932, 926, 889, + 926, 932, 933, + 933, 927, 926, + 927, 933, 934, + 934, 928, 927, + 928, 934, 935, + 935, 929, 928, + 929, 935, 936, + 936, 930, 929, + 930, 936, 937, + 937, 931, 930, + 938, 932, 889, + 932, 938, 939, + 939, 933, 932, + 933, 939, 940, + 940, 934, 933, + 934, 940, 941, + 941, 935, 934, + 935, 941, 942, + 942, 936, 935, + 936, 942, 943, + 943, 937, 936, + 944, 938, 889, + 938, 944, 945, + 945, 939, 938, + 939, 945, 946, + 946, 940, 939, + 940, 946, 947, + 947, 941, 940, + 941, 947, 948, + 948, 942, 941, + 942, 948, 949, + 949, 943, 942, + 950, 944, 889, + 944, 950, 951, + 951, 945, 944, + 945, 951, 952, + 952, 946, 945, + 946, 952, 953, + 953, 947, 946, + 947, 953, 954, + 954, 948, 947, + 948, 954, 955, + 955, 949, 948, + 956, 950, 889, + 950, 956, 957, + 957, 951, 950, + 951, 957, 958, + 958, 952, 951, + 952, 958, 959, + 959, 953, 952, + 953, 959, 960, + 960, 954, 953, + 954, 960, 961, + 961, 955, 954, + 962, 956, 889, + 956, 962, 963, + 963, 957, 956, + 957, 963, 964, + 964, 958, 957, + 958, 964, 965, + 965, 959, 958, + 959, 965, 966, + 966, 960, 959, + 960, 966, 967, + 967, 961, 960, + 968, 962, 889, + 962, 968, 969, + 969, 963, 962, + 963, 969, 970, + 970, 964, 963, + 964, 970, 971, + 971, 965, 964, + 965, 971, 972, + 972, 966, 965, + 966, 972, 973, + 973, 967, 966, + 974, 968, 889, + 968, 974, 975, + 975, 969, 968, + 969, 975, 976, + 976, 970, 969, + 970, 976, 977, + 977, 971, 970, + 971, 977, 978, + 978, 972, 971, + 972, 978, 979, + 979, 973, 972, + 980, 974, 889, + 974, 980, 981, + 981, 975, 974, + 975, 981, 982, + 982, 976, 975, + 976, 982, 983, + 983, 977, 976, + 977, 983, 984, + 984, 978, 977, + 978, 984, 985, + 985, 979, 978, + 986, 980, 889, + 980, 986, 987, + 987, 981, 980, + 981, 987, 988, + 988, 982, 981, + 982, 988, 989, + 989, 983, 982, + 983, 989, 990, + 990, 984, 983, + 984, 990, 991, + 991, 985, 984, + 992, 986, 889, + 986, 992, 993, + 993, 987, 986, + 987, 993, 994, + 994, 988, 987, + 988, 994, 995, + 995, 989, 988, + 989, 995, 996, + 996, 990, 989, + 990, 996, 997, + 997, 991, 990, + 998, 992, 889, + 992, 998, 999, + 999, 993, 992, + 993, 999, 1000, + 1000, 994, 993, + 994, 1000, 1001, + 1001, 995, 994, + 995, 1001, 1002, + 1002, 996, 995, + 996, 1002, 1003, + 1003, 997, 996, + 1004, 998, 889, + 998, 1004, 1005, + 1005, 999, 998, + 999, 1005, 1006, + 1006, 1000, 999, + 1000, 1006, 1007, + 1007, 1001, 1000, + 1001, 1007, 1008, + 1008, 1002, 1001, + 1002, 1008, 1009, + 1009, 1003, 1002, + 1010, 1004, 889, + 1004, 1010, 1011, + 1011, 1005, 1004, + 1005, 1011, 1012, + 1012, 1006, 1005, + 1006, 1012, 1013, + 1013, 1007, 1006, + 1007, 1013, 1014, + 1014, 1008, 1007, + 1008, 1014, 1015, + 1015, 1009, 1008, + 1016, 1010, 889, + 1010, 1016, 1017, + 1017, 1011, 1010, + 1011, 1017, 1018, + 1018, 1012, 1011, + 1012, 1018, 1019, + 1019, 1013, 1012, + 1013, 1019, 1020, + 1020, 1014, 1013, + 1014, 1020, 1021, + 1021, 1015, 1014, + 1022, 1016, 889, + 1016, 1022, 1023, + 1023, 1017, 1016, + 1017, 1023, 1024, + 1024, 1018, 1017, + 1018, 1024, 1025, + 1025, 1019, 1018, + 1019, 1025, 1026, + 1026, 1020, 1019, + 1020, 1026, 1027, + 1027, 1021, 1020, + 1028, 1022, 889, + 1022, 1028, 1029, + 1029, 1023, 1022, + 1023, 1029, 1030, + 1030, 1024, 1023, + 1024, 1030, 1031, + 1031, 1025, 1024, + 1025, 1031, 1032, + 1032, 1026, 1025, + 1026, 1032, 1033, + 1033, 1027, 1026, + 890, 1028, 889, + 1028, 890, 891, + 891, 1029, 1028, + 1029, 891, 892, + 892, 1030, 1029, + 1030, 892, 893, + 893, 1031, 1030, + 1031, 893, 894, + 894, 1032, 1031, + 1032, 894, 895, + 895, 1033, 1032, + 895, 901, 1040, + 1040, 1034, 895, + 1034, 1040, 1041, + 1041, 1035, 1034, + 1035, 1041, 1042, + 1042, 1036, 1035, + 1036, 1042, 1043, + 1043, 1037, 1036, + 1037, 1043, 1044, + 1044, 1038, 1037, + 1038, 1044, 1045, + 1045, 1039, 1038, + 901, 907, 1046, + 1046, 1040, 901, + 1040, 1046, 1047, + 1047, 1041, 1040, + 1041, 1047, 1048, + 1048, 1042, 1041, + 1042, 1048, 1049, + 1049, 1043, 1042, + 1043, 1049, 1050, + 1050, 1044, 1043, + 1044, 1050, 1051, + 1051, 1045, 1044, + 907, 913, 1052, + 1052, 1046, 907, + 1046, 1052, 1053, + 1053, 1047, 1046, + 1047, 1053, 1054, + 1054, 1048, 1047, + 1048, 1054, 1055, + 1055, 1049, 1048, + 1049, 1055, 1056, + 1056, 1050, 1049, + 1050, 1056, 1057, + 1057, 1051, 1050, + 913, 919, 1058, + 1058, 1052, 913, + 1052, 1058, 1059, + 1059, 1053, 1052, + 1053, 1059, 1060, + 1060, 1054, 1053, + 1054, 1060, 1061, + 1061, 1055, 1054, + 1055, 1061, 1062, + 1062, 1056, 1055, + 1056, 1062, 1063, + 1063, 1057, 1056, + 919, 925, 1064, + 1064, 1058, 919, + 1058, 1064, 1065, + 1065, 1059, 1058, + 1059, 1065, 1066, + 1066, 1060, 1059, + 1060, 1066, 1067, + 1067, 1061, 1060, + 1061, 1067, 1068, + 1068, 1062, 1061, + 1062, 1068, 1069, + 1069, 1063, 1062, + 925, 931, 1070, + 1070, 1064, 925, + 1064, 1070, 1071, + 1071, 1065, 1064, + 1065, 1071, 1072, + 1072, 1066, 1065, + 1066, 1072, 1073, + 1073, 1067, 1066, + 1067, 1073, 1074, + 1074, 1068, 1067, + 1068, 1074, 1075, + 1075, 1069, 1068, + 931, 937, 1076, + 1076, 1070, 931, + 1070, 1076, 1077, + 1077, 1071, 1070, + 1071, 1077, 1078, + 1078, 1072, 1071, + 1072, 1078, 1079, + 1079, 1073, 1072, + 1073, 1079, 1080, + 1080, 1074, 1073, + 1074, 1080, 1081, + 1081, 1075, 1074, + 937, 943, 1082, + 1082, 1076, 937, + 1076, 1082, 1083, + 1083, 1077, 1076, + 1077, 1083, 1084, + 1084, 1078, 1077, + 1078, 1084, 1085, + 1085, 1079, 1078, + 1079, 1085, 1086, + 1086, 1080, 1079, + 1080, 1086, 1087, + 1087, 1081, 1080, + 943, 949, 1088, + 1088, 1082, 943, + 1082, 1088, 1089, + 1089, 1083, 1082, + 1083, 1089, 1090, + 1090, 1084, 1083, + 1084, 1090, 1091, + 1091, 1085, 1084, + 1085, 1091, 1092, + 1092, 1086, 1085, + 1086, 1092, 1093, + 1093, 1087, 1086, + 949, 955, 1094, + 1094, 1088, 949, + 1088, 1094, 1095, + 1095, 1089, 1088, + 1089, 1095, 1096, + 1096, 1090, 1089, + 1090, 1096, 1097, + 1097, 1091, 1090, + 1091, 1097, 1098, + 1098, 1092, 1091, + 1092, 1098, 1099, + 1099, 1093, 1092, + 955, 961, 1100, + 1100, 1094, 955, + 1094, 1100, 1101, + 1101, 1095, 1094, + 1095, 1101, 1102, + 1102, 1096, 1095, + 1096, 1102, 1103, + 1103, 1097, 1096, + 1097, 1103, 1104, + 1104, 1098, 1097, + 1098, 1104, 1105, + 1105, 1099, 1098, + 961, 967, 1106, + 1106, 1100, 961, + 1100, 1106, 1107, + 1107, 1101, 1100, + 1101, 1107, 1108, + 1108, 1102, 1101, + 1102, 1108, 1109, + 1109, 1103, 1102, + 1103, 1109, 1110, + 1110, 1104, 1103, + 1104, 1110, 1111, + 1111, 1105, 1104, + 967, 973, 1112, + 1112, 1106, 967, + 1106, 1112, 1113, + 1113, 1107, 1106, + 1107, 1113, 1114, + 1114, 1108, 1107, + 1108, 1114, 1115, + 1115, 1109, 1108, + 1109, 1115, 1116, + 1116, 1110, 1109, + 1110, 1116, 1117, + 1117, 1111, 1110, + 973, 979, 1118, + 1118, 1112, 973, + 1112, 1118, 1119, + 1119, 1113, 1112, + 1113, 1119, 1120, + 1120, 1114, 1113, + 1114, 1120, 1121, + 1121, 1115, 1114, + 1115, 1121, 1122, + 1122, 1116, 1115, + 1116, 1122, 1123, + 1123, 1117, 1116, + 979, 985, 1124, + 1124, 1118, 979, + 1118, 1124, 1125, + 1125, 1119, 1118, + 1119, 1125, 1126, + 1126, 1120, 1119, + 1120, 1126, 1127, + 1127, 1121, 1120, + 1121, 1127, 1128, + 1128, 1122, 1121, + 1122, 1128, 1129, + 1129, 1123, 1122, + 985, 991, 1130, + 1130, 1124, 985, + 1124, 1130, 1131, + 1131, 1125, 1124, + 1125, 1131, 1132, + 1132, 1126, 1125, + 1126, 1132, 1133, + 1133, 1127, 1126, + 1127, 1133, 1134, + 1134, 1128, 1127, + 1128, 1134, 1135, + 1135, 1129, 1128, + 991, 997, 1136, + 1136, 1130, 991, + 1130, 1136, 1137, + 1137, 1131, 1130, + 1131, 1137, 1138, + 1138, 1132, 1131, + 1132, 1138, 1139, + 1139, 1133, 1132, + 1133, 1139, 1140, + 1140, 1134, 1133, + 1134, 1140, 1141, + 1141, 1135, 1134, + 997, 1003, 1142, + 1142, 1136, 997, + 1136, 1142, 1143, + 1143, 1137, 1136, + 1137, 1143, 1144, + 1144, 1138, 1137, + 1138, 1144, 1145, + 1145, 1139, 1138, + 1139, 1145, 1146, + 1146, 1140, 1139, + 1140, 1146, 1147, + 1147, 1141, 1140, + 1003, 1009, 1148, + 1148, 1142, 1003, + 1142, 1148, 1149, + 1149, 1143, 1142, + 1143, 1149, 1150, + 1150, 1144, 1143, + 1144, 1150, 1151, + 1151, 1145, 1144, + 1145, 1151, 1152, + 1152, 1146, 1145, + 1146, 1152, 1153, + 1153, 1147, 1146, + 1009, 1015, 1154, + 1154, 1148, 1009, + 1148, 1154, 1155, + 1155, 1149, 1148, + 1149, 1155, 1156, + 1156, 1150, 1149, + 1150, 1156, 1157, + 1157, 1151, 1150, + 1151, 1157, 1158, + 1158, 1152, 1151, + 1152, 1158, 1159, + 1159, 1153, 1152, + 1015, 1021, 1160, + 1160, 1154, 1015, + 1154, 1160, 1161, + 1161, 1155, 1154, + 1155, 1161, 1162, + 1162, 1156, 1155, + 1156, 1162, 1163, + 1163, 1157, 1156, + 1157, 1163, 1164, + 1164, 1158, 1157, + 1158, 1164, 1165, + 1165, 1159, 1158, + 1021, 1027, 1166, + 1166, 1160, 1021, + 1160, 1166, 1167, + 1167, 1161, 1160, + 1161, 1167, 1168, + 1168, 1162, 1161, + 1162, 1168, 1169, + 1169, 1163, 1162, + 1163, 1169, 1170, + 1170, 1164, 1163, + 1164, 1170, 1171, + 1171, 1165, 1164, + 1027, 1033, 1172, + 1172, 1166, 1027, + 1166, 1172, 1173, + 1173, 1167, 1166, + 1167, 1173, 1174, + 1174, 1168, 1167, + 1168, 1174, 1175, + 1175, 1169, 1168, + 1169, 1175, 1176, + 1176, 1170, 1169, + 1170, 1176, 1177, + 1177, 1171, 1170, + 1033, 895, 1034, + 1034, 1172, 1033, + 1172, 1034, 1035, + 1035, 1173, 1172, + 1173, 1035, 1036, + 1036, 1174, 1173, + 1174, 1036, 1037, + 1037, 1175, 1174, + 1175, 1037, 1038, + 1038, 1176, 1175, + 1176, 1038, 1039, + 1039, 1177, 1176, +}; + + +//---------------------------------------------------------------------------- +// MakeTeapot Helper +//---------------------------------------------------------------------------- +static void MakeTeapot( +VERTEX* pVertices, +WORD* pwIndices ) +{ + DWORD iVertex; + + // Copy vertices + for( iVertex = 0; iVertex < NUMTEAPOTVERTICES; iVertex++ ) + { + pVertices[iVertex].pos = teapotPositions[iVertex]; + pVertices[iVertex].norm = teapotNormals[iVertex]; + } + + // Copy face indices + WORD* pwFace = pwIndices; + WORD* pwFaceLim = pwFace + NUMTEAPOTINDICES; + WORD* pwTeapotFace = teapotIndices; + + while( pwFace < pwFaceLim ) + { + pwFace[0] = pwTeapotFace[0]; + pwFace[1] = pwTeapotFace[1]; + pwFace[2] = pwTeapotFace[2]; + + pwFace += 3; + pwTeapotFace += 3; + } +} + + +//---------------------------------------------------------------------------- +// DXUTCreateTeapot - createa teapot mesh +//---------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateTeapot( ID3D10Device* pDevice, ID3DX10Mesh** ppMesh ) +{ + HRESULT hr = S_OK; + + WORD* pwIndices = NULL; + VERTEX* pVertices = NULL; + + + // Validate parameters + if( !pDevice ) + return D3DERR_INVALIDCALL; + if( !ppMesh ) + return D3DERR_INVALIDCALL; + + // Create the mesh + UINT cFaces = NUMTEAPOTINDICES / 3; + UINT cVertices = NUMTEAPOTVERTICES; + + // Create enough memory for the vertices and indices + pVertices = new VERTEX[ cVertices ]; + if( !pVertices ) + return E_OUTOFMEMORY; + pwIndices = new WORD[ cFaces * 3 ]; + if( !pwIndices ) + return E_OUTOFMEMORY; + + // Create a teapot + MakeTeapot( pVertices, pwIndices ); + + // Create a mesh + hr = CreateShapeMesh( pDevice, ppMesh, pVertices, cVertices, pwIndices, cFaces * 3 ); + + // Free up the memory + SAFE_DELETE_ARRAY( pVertices ); + SAFE_DELETE_ARRAY( pwIndices ); + + return hr; +} diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.h b/Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.h new file mode 100644 index 0000000..c289231 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTShapes.h @@ -0,0 +1,24 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTShapes.h +// +// Shape creation functions for DXUT +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_SHAPES_H +#define DXUT_SHAPES_H +#include +#include + +HRESULT WINAPI DXUTCreateBox( ID3D10Device* pDevice, float fWidth, float fHeight, float fDepth, ID3DX10Mesh** ppMesh ); +HRESULT WINAPI DXUTCreateCylinder( ID3D10Device* pDevice, float fRadius1, float fRadius2, float fLength, UINT uSlices, + UINT uStacks, ID3DX10Mesh** ppMesh ); +HRESULT WINAPI DXUTCreatePolygon( ID3D10Device* pDevice, float fLength, UINT uSides, ID3DX10Mesh** ppMesh ); +HRESULT WINAPI DXUTCreateSphere( ID3D10Device* pDevice, float fRadius, UINT uSlices, UINT uStacks, + ID3DX10Mesh** ppMesh ); +HRESULT WINAPI DXUTCreateTorus( ID3D10Device* pDevice, float fInnerRadius, float fOuterRadius, UINT uSides, + UINT uRings, ID3DX10Mesh** ppMesh ); +HRESULT WINAPI DXUTCreateTeapot( ID3D10Device* pDevice, ID3DX10Mesh** ppMesh ); + +#endif diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.cpp b/Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.cpp new file mode 100644 index 0000000..8142e7c --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.cpp @@ -0,0 +1,1525 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTcamera.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#include "DXUTcamera.h" +#include "DXUTres.h" +#undef min // use __min instead +#undef max // use __max instead + +//-------------------------------------------------------------------------------------- +CD3DArcBall::CD3DArcBall() +{ + Reset(); + m_vDownPt = D3DXVECTOR3( 0, 0, 0 ); + m_vCurrentPt = D3DXVECTOR3( 0, 0, 0 ); + m_Offset.x = m_Offset.y = 0; + + RECT rc; + GetClientRect( GetForegroundWindow(), &rc ); + SetWindow( rc.right, rc.bottom ); +} + + + + + +//-------------------------------------------------------------------------------------- +void CD3DArcBall::Reset() +{ + D3DXQuaternionIdentity( &m_qDown ); + D3DXQuaternionIdentity( &m_qNow ); + D3DXMatrixIdentity( &m_mRotation ); + D3DXMatrixIdentity( &m_mTranslation ); + D3DXMatrixIdentity( &m_mTranslationDelta ); + m_bDrag = FALSE; + m_fRadiusTranslation = 1.0f; + m_fRadius = 1.0f; +} + + + + +//-------------------------------------------------------------------------------------- +D3DXVECTOR3 CD3DArcBall::ScreenToVector( float fScreenPtX, float fScreenPtY ) +{ + // Scale to screen + FLOAT x = -( fScreenPtX - m_Offset.x - m_nWidth / 2 ) / ( m_fRadius * m_nWidth / 2 ); + FLOAT y = ( fScreenPtY - m_Offset.y - m_nHeight / 2 ) / ( m_fRadius * m_nHeight / 2 ); + + FLOAT z = 0.0f; + FLOAT mag = x * x + y * y; + + if( mag > 1.0f ) + { + FLOAT scale = 1.0f / sqrtf( mag ); + x *= scale; + y *= scale; + } + else + z = sqrtf( 1.0f - mag ); + + // Return vector + return D3DXVECTOR3( x, y, z ); +} + + + + +//-------------------------------------------------------------------------------------- +D3DXQUATERNION CD3DArcBall::QuatFromBallPoints( const D3DXVECTOR3& vFrom, const D3DXVECTOR3& vTo ) +{ + D3DXVECTOR3 vPart; + float fDot = D3DXVec3Dot( &vFrom, &vTo ); + D3DXVec3Cross( &vPart, &vFrom, &vTo ); + + return D3DXQUATERNION( vPart.x, vPart.y, vPart.z, fDot ); +} + + + + +//-------------------------------------------------------------------------------------- +void CD3DArcBall::OnBegin( int nX, int nY ) +{ + // Only enter the drag state if the click falls + // inside the click rectangle. + if( nX >= m_Offset.x && + nX < m_Offset.x + m_nWidth && + nY >= m_Offset.y && + nY < m_Offset.y + m_nHeight ) + { + m_bDrag = true; + m_qDown = m_qNow; + m_vDownPt = ScreenToVector( ( float )nX, ( float )nY ); + } +} + + + + +//-------------------------------------------------------------------------------------- +void CD3DArcBall::OnMove( int nX, int nY ) +{ + if( m_bDrag ) + { + m_vCurrentPt = ScreenToVector( ( float )nX, ( float )nY ); + m_qNow = m_qDown * QuatFromBallPoints( m_vDownPt, m_vCurrentPt ); + } +} + + + + +//-------------------------------------------------------------------------------------- +void CD3DArcBall::OnEnd() +{ + m_bDrag = false; +} + + + + +//-------------------------------------------------------------------------------------- +// Desc: +//-------------------------------------------------------------------------------------- +LRESULT CD3DArcBall::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + // Current mouse position + int iMouseX = ( short )LOWORD( lParam ); + int iMouseY = ( short )HIWORD( lParam ); + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + SetCapture( hWnd ); + OnBegin( iMouseX, iMouseY ); + return TRUE; + + case WM_LBUTTONUP: + ReleaseCapture(); + OnEnd(); + return TRUE; + case WM_CAPTURECHANGED: + if( ( HWND )lParam != hWnd ) + { + ReleaseCapture(); + OnEnd(); + } + return TRUE; + + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + SetCapture( hWnd ); + // Store off the position of the cursor when the button is pressed + m_ptLastMouse.x = iMouseX; + m_ptLastMouse.y = iMouseY; + return TRUE; + + case WM_RBUTTONUP: + case WM_MBUTTONUP: + ReleaseCapture(); + return TRUE; + + case WM_MOUSEMOVE: + if( MK_LBUTTON & wParam ) + { + OnMove( iMouseX, iMouseY ); + } + else if( ( MK_RBUTTON & wParam ) || ( MK_MBUTTON & wParam ) ) + { + // Normalize based on size of window and bounding sphere radius + FLOAT fDeltaX = ( m_ptLastMouse.x - iMouseX ) * m_fRadiusTranslation / m_nWidth; + FLOAT fDeltaY = ( m_ptLastMouse.y - iMouseY ) * m_fRadiusTranslation / m_nHeight; + + if( wParam & MK_RBUTTON ) + { + D3DXMatrixTranslation( &m_mTranslationDelta, -2 * fDeltaX, 2 * fDeltaY, 0.0f ); + D3DXMatrixMultiply( &m_mTranslation, &m_mTranslation, &m_mTranslationDelta ); + } + else // wParam & MK_MBUTTON + { + D3DXMatrixTranslation( &m_mTranslationDelta, 0.0f, 0.0f, 5 * fDeltaY ); + D3DXMatrixMultiply( &m_mTranslation, &m_mTranslation, &m_mTranslationDelta ); + } + + // Store mouse coordinate + m_ptLastMouse.x = iMouseX; + m_ptLastMouse.y = iMouseY; + } + return TRUE; + } + + return FALSE; +} + + + + +//-------------------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------------------- +CBaseCamera::CBaseCamera() +{ + m_cKeysDown = 0; + ZeroMemory( m_aKeys, sizeof( BYTE ) * CAM_MAX_KEYS ); + ZeroMemory( m_GamePad, sizeof( DXUT_GAMEPAD ) * DXUT_MAX_CONTROLLERS ); + + // Set attributes for the view matrix + D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); + D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + + // Setup the view matrix + SetViewParams( &vEyePt, &vLookatPt ); + + // Setup the projection matrix + SetProjParams( D3DX_PI / 4, 1.0f, 1.0f, 1000.0f ); + + GetCursorPos( &m_ptLastMousePosition ); + m_bMouseLButtonDown = false; + m_bMouseMButtonDown = false; + m_bMouseRButtonDown = false; + m_nCurrentButtonMask = 0; + m_nMouseWheelDelta = 0; + + m_fCameraYawAngle = 0.0f; + m_fCameraPitchAngle = 0.0f; + + SetRect( &m_rcDrag, LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX ); + m_vVelocity = D3DXVECTOR3( 0, 0, 0 ); + m_bMovementDrag = false; + m_vVelocityDrag = D3DXVECTOR3( 0, 0, 0 ); + m_fDragTimer = 0.0f; + m_fTotalDragTimeToZero = 0.25; + m_vRotVelocity = D3DXVECTOR2( 0, 0 ); + + m_fRotationScaler = 0.01f; + m_fMoveScaler = 5.0f; + + m_bInvertPitch = false; + m_bEnableYAxisMovement = true; + m_bEnablePositionMovement = true; + + m_vMouseDelta = D3DXVECTOR2( 0, 0 ); + m_fFramesToSmoothMouseData = 2.0f; + + m_bClipToBoundary = false; + m_vMinBoundary = D3DXVECTOR3( -1, -1, -1 ); + m_vMaxBoundary = D3DXVECTOR3( 1, 1, 1 ); + + m_bResetCursorAfterMove = false; +} + + +//-------------------------------------------------------------------------------------- +// Client can call this to change the position and direction of camera +//-------------------------------------------------------------------------------------- +VOID CBaseCamera::SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt ) +{ + if( NULL == pvEyePt || NULL == pvLookatPt ) + return; + + m_vDefaultEye = m_vEye = *pvEyePt; + m_vDefaultLookAt = m_vLookAt = *pvLookatPt; + + // Calc the view matrix + D3DXVECTOR3 vUp( 0,1,0 ); + D3DXMatrixLookAtLH( &m_mView, pvEyePt, pvLookatPt, &vUp ); + + D3DXMATRIX mInvView; + D3DXMatrixInverse( &mInvView, NULL, &m_mView ); + + // The axis basis vectors and camera position are stored inside the + // position matrix in the 4 rows of the camera's world matrix. + // To figure out the yaw/pitch of the camera, we just need the Z basis vector + D3DXVECTOR3* pZBasis = ( D3DXVECTOR3* )&mInvView._31; + + m_fCameraYawAngle = atan2f( pZBasis->x, pZBasis->z ); + float fLen = sqrtf( pZBasis->z * pZBasis->z + pZBasis->x * pZBasis->x ); + m_fCameraPitchAngle = -atan2f( pZBasis->y, fLen ); +} + + + + +//-------------------------------------------------------------------------------------- +// Calculates the projection matrix based on input params +//-------------------------------------------------------------------------------------- +VOID CBaseCamera::SetProjParams( FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane, + FLOAT fFarPlane ) +{ + // Set attributes for the projection matrix + m_fFOV = fFOV; + m_fAspect = fAspect; + m_fNearPlane = fNearPlane; + m_fFarPlane = fFarPlane; + + D3DXMatrixPerspectiveFovLH( &m_mProj, fFOV, fAspect, fNearPlane, fFarPlane ); +} + + + + +//-------------------------------------------------------------------------------------- +// Call this from your message proc so this class can handle window messages +//-------------------------------------------------------------------------------------- +LRESULT CBaseCamera::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + UNREFERENCED_PARAMETER( hWnd ); + UNREFERENCED_PARAMETER( lParam ); + + switch( uMsg ) + { + case WM_KEYDOWN: + { + // Map this key to a D3DUtil_CameraKeys enum and update the + // state of m_aKeys[] by adding the KEY_WAS_DOWN_MASK|KEY_IS_DOWN_MASK mask + // only if the key is not down + D3DUtil_CameraKeys mappedKey = MapKey( ( UINT )wParam ); + if( mappedKey != CAM_UNKNOWN ) + { + if( FALSE == IsKeyDown( m_aKeys[mappedKey] ) ) + { + m_aKeys[ mappedKey ] = KEY_WAS_DOWN_MASK | KEY_IS_DOWN_MASK; + ++m_cKeysDown; + } + } + break; + } + + case WM_KEYUP: + { + // Map this key to a D3DUtil_CameraKeys enum and update the + // state of m_aKeys[] by removing the KEY_IS_DOWN_MASK mask. + D3DUtil_CameraKeys mappedKey = MapKey( ( UINT )wParam ); + if( mappedKey != CAM_UNKNOWN && ( DWORD )mappedKey < 8 ) + { + m_aKeys[ mappedKey ] &= ~KEY_IS_DOWN_MASK; + --m_cKeysDown; + } + break; + } + + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_LBUTTONDOWN: + case WM_RBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_LBUTTONDBLCLK: + { + // Compute the drag rectangle in screen coord. + POINT ptCursor = + { + ( short )LOWORD( lParam ), ( short )HIWORD( lParam ) + }; + + // Update member var state + if( ( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) ) + { + m_bMouseLButtonDown = true; m_nCurrentButtonMask |= MOUSE_LEFT_BUTTON; + } + if( ( uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) ) + { + m_bMouseMButtonDown = true; m_nCurrentButtonMask |= MOUSE_MIDDLE_BUTTON; + } + if( ( uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) ) + { + m_bMouseRButtonDown = true; m_nCurrentButtonMask |= MOUSE_RIGHT_BUTTON; + } + + // Capture the mouse, so if the mouse button is + // released outside the window, we'll get the WM_LBUTTONUP message + SetCapture( hWnd ); + GetCursorPos( &m_ptLastMousePosition ); + return TRUE; + } + + case WM_RBUTTONUP: + case WM_MBUTTONUP: + case WM_LBUTTONUP: + { + // Update member var state + if( uMsg == WM_LBUTTONUP ) + { + m_bMouseLButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_LEFT_BUTTON; + } + if( uMsg == WM_MBUTTONUP ) + { + m_bMouseMButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_MIDDLE_BUTTON; + } + if( uMsg == WM_RBUTTONUP ) + { + m_bMouseRButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_RIGHT_BUTTON; + } + + // Release the capture if no mouse buttons down + if( !m_bMouseLButtonDown && + !m_bMouseRButtonDown && + !m_bMouseMButtonDown ) + { + ReleaseCapture(); + } + break; + } + + case WM_CAPTURECHANGED: + { + if( ( HWND )lParam != hWnd ) + { + if( ( m_nCurrentButtonMask & MOUSE_LEFT_BUTTON ) || + ( m_nCurrentButtonMask & MOUSE_MIDDLE_BUTTON ) || + ( m_nCurrentButtonMask & MOUSE_RIGHT_BUTTON ) ) + { + m_bMouseLButtonDown = false; + m_bMouseMButtonDown = false; + m_bMouseRButtonDown = false; + m_nCurrentButtonMask &= ~MOUSE_LEFT_BUTTON; + m_nCurrentButtonMask &= ~MOUSE_MIDDLE_BUTTON; + m_nCurrentButtonMask &= ~MOUSE_RIGHT_BUTTON; + ReleaseCapture(); + } + } + break; + } + + case WM_MOUSEWHEEL: + // Update member var state + m_nMouseWheelDelta += ( short )HIWORD( wParam ); + break; + } + + return FALSE; +} + +//-------------------------------------------------------------------------------------- +// Figure out the velocity based on keyboard input & drag if any +//-------------------------------------------------------------------------------------- +void CBaseCamera::GetInput( bool bGetKeyboardInput, bool bGetMouseInput, bool bGetGamepadInput, + bool bResetCursorAfterMove ) +{ + m_vKeyboardDirection = D3DXVECTOR3( 0, 0, 0 ); + if( bGetKeyboardInput ) + { + // Update acceleration vector based on keyboard state + if( IsKeyDown( m_aKeys[CAM_MOVE_FORWARD] ) ) + m_vKeyboardDirection.z += 1.0f; + if( IsKeyDown( m_aKeys[CAM_MOVE_BACKWARD] ) ) + m_vKeyboardDirection.z -= 1.0f; + if( m_bEnableYAxisMovement ) + { + if( IsKeyDown( m_aKeys[CAM_MOVE_UP] ) ) + m_vKeyboardDirection.y += 1.0f; + if( IsKeyDown( m_aKeys[CAM_MOVE_DOWN] ) ) + m_vKeyboardDirection.y -= 1.0f; + } + if( IsKeyDown( m_aKeys[CAM_STRAFE_RIGHT] ) ) + m_vKeyboardDirection.x += 1.0f; + if( IsKeyDown( m_aKeys[CAM_STRAFE_LEFT] ) ) + m_vKeyboardDirection.x -= 1.0f; + } + + if( bGetMouseInput ) + { + UpdateMouseDelta(); + } + + if( bGetGamepadInput ) + { + m_vGamePadLeftThumb = D3DXVECTOR3( 0, 0, 0 ); + m_vGamePadRightThumb = D3DXVECTOR3( 0, 0, 0 ); + + // Get controller state + for( DWORD iUserIndex = 0; iUserIndex < DXUT_MAX_CONTROLLERS; iUserIndex++ ) + { + DXUTGetGamepadState( iUserIndex, &m_GamePad[iUserIndex], true, true ); + + // Mark time if the controller is in a non-zero state + if( m_GamePad[iUserIndex].wButtons || + m_GamePad[iUserIndex].sThumbLX || m_GamePad[iUserIndex].sThumbLX || + m_GamePad[iUserIndex].sThumbRX || m_GamePad[iUserIndex].sThumbRY || + m_GamePad[iUserIndex].bLeftTrigger || m_GamePad[iUserIndex].bRightTrigger ) + { + m_GamePadLastActive[iUserIndex] = DXUTGetTime(); + } + } + + // Find out which controller was non-zero last + int iMostRecentlyActive = -1; + double fMostRecentlyActiveTime = 0.0f; + for( DWORD iUserIndex = 0; iUserIndex < DXUT_MAX_CONTROLLERS; iUserIndex++ ) + { + if( m_GamePadLastActive[iUserIndex] > fMostRecentlyActiveTime ) + { + fMostRecentlyActiveTime = m_GamePadLastActive[iUserIndex]; + iMostRecentlyActive = iUserIndex; + } + } + + // Use the most recent non-zero controller if its connected + if( iMostRecentlyActive >= 0 && m_GamePad[iMostRecentlyActive].bConnected ) + { + m_vGamePadLeftThumb.x = m_GamePad[iMostRecentlyActive].fThumbLX; + m_vGamePadLeftThumb.y = 0.0f; + m_vGamePadLeftThumb.z = m_GamePad[iMostRecentlyActive].fThumbLY; + + m_vGamePadRightThumb.x = m_GamePad[iMostRecentlyActive].fThumbRX; + m_vGamePadRightThumb.y = 0.0f; + m_vGamePadRightThumb.z = m_GamePad[iMostRecentlyActive].fThumbRY; + } + } +} + + +//-------------------------------------------------------------------------------------- +// Figure out the mouse delta based on mouse movement +//-------------------------------------------------------------------------------------- +void CBaseCamera::UpdateMouseDelta() +{ + POINT ptCurMouseDelta; + POINT ptCurMousePos; + + // Get current position of mouse + GetCursorPos( &ptCurMousePos ); + + // Calc how far it's moved since last frame + ptCurMouseDelta.x = ptCurMousePos.x - m_ptLastMousePosition.x; + ptCurMouseDelta.y = ptCurMousePos.y - m_ptLastMousePosition.y; + + // Record current position for next time + m_ptLastMousePosition = ptCurMousePos; + + if( m_bResetCursorAfterMove && DXUTIsActive() ) + { + // Set position of camera to center of desktop, + // so it always has room to move. This is very useful + // if the cursor is hidden. If this isn't done and cursor is hidden, + // then invisible cursor will hit the edge of the screen + // and the user can't tell what happened + POINT ptCenter; + + // Get the center of the current monitor + MONITORINFO mi; + mi.cbSize = sizeof( MONITORINFO ); + DXUTGetMonitorInfo( DXUTMonitorFromWindow( DXUTGetHWND(), MONITOR_DEFAULTTONEAREST ), &mi ); + ptCenter.x = ( mi.rcMonitor.left + mi.rcMonitor.right ) / 2; + ptCenter.y = ( mi.rcMonitor.top + mi.rcMonitor.bottom ) / 2; + SetCursorPos( ptCenter.x, ptCenter.y ); + m_ptLastMousePosition = ptCenter; + } + + // Smooth the relative mouse data over a few frames so it isn't + // jerky when moving slowly at low frame rates. + float fPercentOfNew = 1.0f / m_fFramesToSmoothMouseData; + float fPercentOfOld = 1.0f - fPercentOfNew; + m_vMouseDelta.x = m_vMouseDelta.x * fPercentOfOld + ptCurMouseDelta.x * fPercentOfNew; + m_vMouseDelta.y = m_vMouseDelta.y * fPercentOfOld + ptCurMouseDelta.y * fPercentOfNew; + + m_vRotVelocity = m_vMouseDelta * m_fRotationScaler; +} + + + + +//-------------------------------------------------------------------------------------- +// Figure out the velocity based on keyboard input & drag if any +//-------------------------------------------------------------------------------------- +void CBaseCamera::UpdateVelocity( float fElapsedTime ) +{ + D3DXMATRIX mRotDelta; + D3DXVECTOR2 vGamePadRightThumb = D3DXVECTOR2( m_vGamePadRightThumb.x, -m_vGamePadRightThumb.z ); + m_vRotVelocity = m_vMouseDelta * m_fRotationScaler + vGamePadRightThumb * 0.02f; + + D3DXVECTOR3 vAccel = m_vKeyboardDirection + m_vGamePadLeftThumb; + + // Normalize vector so if moving 2 dirs (left & forward), + // the camera doesn't move faster than if moving in 1 dir + D3DXVec3Normalize( &vAccel, &vAccel ); + + // Scale the acceleration vector + vAccel *= m_fMoveScaler; + + if( m_bMovementDrag ) + { + // Is there any acceleration this frame? + if( D3DXVec3LengthSq( &vAccel ) > 0 ) + { + // If so, then this means the user has pressed a movement key\ + // so change the velocity immediately to acceleration + // upon keyboard input. This isn't normal physics + // but it will give a quick response to keyboard input + m_vVelocity = vAccel; + m_fDragTimer = m_fTotalDragTimeToZero; + m_vVelocityDrag = vAccel / m_fDragTimer; + } + else + { + // If no key being pressed, then slowly decrease velocity to 0 + if( m_fDragTimer > 0 ) + { + // Drag until timer is <= 0 + m_vVelocity -= m_vVelocityDrag * fElapsedTime; + m_fDragTimer -= fElapsedTime; + } + else + { + // Zero velocity + m_vVelocity = D3DXVECTOR3( 0, 0, 0 ); + } + } + } + else + { + // No drag, so immediately change the velocity + m_vVelocity = vAccel; + } +} + + + + +//-------------------------------------------------------------------------------------- +// Clamps pV to lie inside m_vMinBoundary & m_vMaxBoundary +//-------------------------------------------------------------------------------------- +void CBaseCamera::ConstrainToBoundary( D3DXVECTOR3* pV ) +{ + // Constrain vector to a bounding box + pV->x = __max( pV->x, m_vMinBoundary.x ); + pV->y = __max( pV->y, m_vMinBoundary.y ); + pV->z = __max( pV->z, m_vMinBoundary.z ); + + pV->x = __min( pV->x, m_vMaxBoundary.x ); + pV->y = __min( pV->y, m_vMaxBoundary.y ); + pV->z = __min( pV->z, m_vMaxBoundary.z ); +} + + + + +//-------------------------------------------------------------------------------------- +// Maps a windows virtual key to an enum +//-------------------------------------------------------------------------------------- +D3DUtil_CameraKeys CBaseCamera::MapKey( UINT nKey ) +{ + // This could be upgraded to a method that's user-definable but for + // simplicity, we'll use a hardcoded mapping. + switch( nKey ) + { + case VK_CONTROL: + return CAM_CONTROLDOWN; + case VK_LEFT: + return CAM_STRAFE_LEFT; + case VK_RIGHT: + return CAM_STRAFE_RIGHT; + case VK_UP: + return CAM_MOVE_FORWARD; + case VK_DOWN: + return CAM_MOVE_BACKWARD; + case VK_PRIOR: + return CAM_MOVE_UP; // pgup + case VK_NEXT: + return CAM_MOVE_DOWN; // pgdn + + case 'A': + return CAM_STRAFE_LEFT; + case 'D': + return CAM_STRAFE_RIGHT; + case 'W': + return CAM_MOVE_FORWARD; + case 'S': + return CAM_MOVE_BACKWARD; + case 'Q': + return CAM_MOVE_DOWN; + case 'E': + return CAM_MOVE_UP; + + case VK_NUMPAD4: + return CAM_STRAFE_LEFT; + case VK_NUMPAD6: + return CAM_STRAFE_RIGHT; + case VK_NUMPAD8: + return CAM_MOVE_FORWARD; + case VK_NUMPAD2: + return CAM_MOVE_BACKWARD; + case VK_NUMPAD9: + return CAM_MOVE_UP; + case VK_NUMPAD3: + return CAM_MOVE_DOWN; + + case VK_HOME: + return CAM_RESET; + } + + return CAM_UNKNOWN; +} + + + + +//-------------------------------------------------------------------------------------- +// Reset the camera's position back to the default +//-------------------------------------------------------------------------------------- +VOID CBaseCamera::Reset() +{ + SetViewParams( &m_vDefaultEye, &m_vDefaultLookAt ); +} + + + + +//-------------------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------------------- +CFirstPersonCamera::CFirstPersonCamera() : m_nActiveButtonMask( 0x07 ) +{ + m_bRotateWithoutButtonDown = false; +} + + + + +//-------------------------------------------------------------------------------------- +// Update the view matrix based on user input & elapsed time +//-------------------------------------------------------------------------------------- +VOID CFirstPersonCamera::FrameMove( FLOAT fElapsedTime ) +{ + if( DXUTGetGlobalTimer()->IsStopped() ) { + if (DXUTGetFPS() == 0.0f) fElapsedTime = 0; + else fElapsedTime = 1.0f / DXUTGetFPS(); + } + + if( IsKeyDown( m_aKeys[CAM_RESET] ) ) + Reset(); + + // Get keyboard/mouse/gamepad input + GetInput( m_bEnablePositionMovement, ( m_nActiveButtonMask & m_nCurrentButtonMask ) || m_bRotateWithoutButtonDown, + true, m_bResetCursorAfterMove ); + + //// Get the mouse movement (if any) if the mouse button are down + //if( (m_nActiveButtonMask & m_nCurrentButtonMask) || m_bRotateWithoutButtonDown ) + // UpdateMouseDelta( fElapsedTime ); + + // Get amount of velocity based on the keyboard input and drag (if any) + UpdateVelocity( fElapsedTime ); + + // Simple euler method to calculate position delta + D3DXVECTOR3 vPosDelta = m_vVelocity * fElapsedTime; + + // If rotating the camera + if( ( m_nActiveButtonMask & m_nCurrentButtonMask ) || + m_bRotateWithoutButtonDown || + m_vGamePadRightThumb.x != 0 || + m_vGamePadRightThumb.z != 0 ) + { + // Update the pitch & yaw angle based on mouse movement + float fYawDelta = m_vRotVelocity.x; + float fPitchDelta = m_vRotVelocity.y; + + // Invert pitch if requested + if( m_bInvertPitch ) + fPitchDelta = -fPitchDelta; + + m_fCameraPitchAngle += fPitchDelta; + m_fCameraYawAngle += fYawDelta; + + // Limit pitch to straight up or straight down + m_fCameraPitchAngle = __max( -D3DX_PI / 2.0f, m_fCameraPitchAngle ); + m_fCameraPitchAngle = __min( +D3DX_PI / 2.0f, m_fCameraPitchAngle ); + } + + // Make a rotation matrix based on the camera's yaw & pitch + D3DXMATRIX mCameraRot; + D3DXMatrixRotationYawPitchRoll( &mCameraRot, m_fCameraYawAngle, m_fCameraPitchAngle, 0 ); + + // Transform vectors based on camera's rotation matrix + D3DXVECTOR3 vWorldUp, vWorldAhead; + D3DXVECTOR3 vLocalUp = D3DXVECTOR3( 0, 1, 0 ); + D3DXVECTOR3 vLocalAhead = D3DXVECTOR3( 0, 0, 1 ); + D3DXVec3TransformCoord( &vWorldUp, &vLocalUp, &mCameraRot ); + D3DXVec3TransformCoord( &vWorldAhead, &vLocalAhead, &mCameraRot ); + + // Transform the position delta by the camera's rotation + D3DXVECTOR3 vPosDeltaWorld; + if( !m_bEnableYAxisMovement ) + { + // If restricting Y movement, do not include pitch + // when transforming position delta vector. + D3DXMatrixRotationYawPitchRoll( &mCameraRot, m_fCameraYawAngle, 0.0f, 0.0f ); + } + D3DXVec3TransformCoord( &vPosDeltaWorld, &vPosDelta, &mCameraRot ); + + // Move the eye position + m_vEye += vPosDeltaWorld; + if( m_bClipToBoundary ) + ConstrainToBoundary( &m_vEye ); + + // Update the lookAt position based on the eye position + m_vLookAt = m_vEye + vWorldAhead; + + // Update the view matrix + D3DXMatrixLookAtLH( &m_mView, &m_vEye, &m_vLookAt, &vWorldUp ); + + D3DXMatrixInverse( &m_mCameraWorld, NULL, &m_mView ); +} + + +//-------------------------------------------------------------------------------------- +// Enable or disable each of the mouse buttons for rotation drag. +//-------------------------------------------------------------------------------------- +void CFirstPersonCamera::SetRotateButtons( bool bLeft, bool bMiddle, bool bRight, bool bRotateWithoutButtonDown ) +{ + m_nActiveButtonMask = ( bLeft ? MOUSE_LEFT_BUTTON : 0 ) | + ( bMiddle ? MOUSE_MIDDLE_BUTTON : 0 ) | + ( bRight ? MOUSE_RIGHT_BUTTON : 0 ); + m_bRotateWithoutButtonDown = bRotateWithoutButtonDown; +} + + +//-------------------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------------------- +CModelViewerCamera::CModelViewerCamera() +{ + D3DXMatrixIdentity( &m_mWorld ); + D3DXMatrixIdentity( &m_mModelRot ); + D3DXMatrixIdentity( &m_mModelLastRot ); + D3DXMatrixIdentity( &m_mCameraRotLast ); + m_vModelCenter = D3DXVECTOR3( 0, 0, 0 ); + m_fRadius = 5.0f; + m_fDefaultRadius = 5.0f; + m_fMinRadius = 1.0f; + m_fMaxRadius = FLT_MAX; + m_bLimitPitch = false; + m_bEnablePositionMovement = false; + m_bAttachCameraToModel = false; + + m_nRotateModelButtonMask = MOUSE_LEFT_BUTTON; + m_nZoomButtonMask = MOUSE_WHEEL; + m_nRotateCameraButtonMask = MOUSE_RIGHT_BUTTON; + m_bDragSinceLastUpdate = true; +} + + + + +//-------------------------------------------------------------------------------------- +// Update the view matrix & the model's world matrix based +// on user input & elapsed time +//-------------------------------------------------------------------------------------- +VOID CModelViewerCamera::FrameMove( FLOAT fElapsedTime ) +{ + if( IsKeyDown( m_aKeys[CAM_RESET] ) ) + Reset(); + + // If no dragged has happend since last time FrameMove is called, + // and no camera key is held down, then no need to handle again. + if( !m_bDragSinceLastUpdate && 0 == m_cKeysDown ) + return; + m_bDragSinceLastUpdate = false; + + //// If no mouse button is held down, + //// Get the mouse movement (if any) if the mouse button are down + //if( m_nCurrentButtonMask != 0 ) + // UpdateMouseDelta( fElapsedTime ); + + GetInput( m_bEnablePositionMovement, m_nCurrentButtonMask != 0, true, false ); + + // Get amount of velocity based on the keyboard input and drag (if any) + UpdateVelocity( fElapsedTime ); + + // Simple euler method to calculate position delta + D3DXVECTOR3 vPosDelta = m_vVelocity * fElapsedTime; + + // Change the radius from the camera to the model based on wheel scrolling + if( m_nMouseWheelDelta && m_nZoomButtonMask == MOUSE_WHEEL ) + m_fRadius -= m_nMouseWheelDelta * m_fRadius * 0.1f / 120.0f; + m_fRadius = __min( m_fMaxRadius, m_fRadius ); + m_fRadius = __max( m_fMinRadius, m_fRadius ); + m_nMouseWheelDelta = 0; + + // Get the inverse of the arcball's rotation matrix + D3DXMATRIX mCameraRot; + D3DXMatrixInverse( &mCameraRot, NULL, m_ViewArcBall.GetRotationMatrix() ); + + // Transform vectors based on camera's rotation matrix + D3DXVECTOR3 vWorldUp, vWorldAhead; + D3DXVECTOR3 vLocalUp = D3DXVECTOR3( 0, 1, 0 ); + D3DXVECTOR3 vLocalAhead = D3DXVECTOR3( 0, 0, 1 ); + D3DXVec3TransformCoord( &vWorldUp, &vLocalUp, &mCameraRot ); + D3DXVec3TransformCoord( &vWorldAhead, &vLocalAhead, &mCameraRot ); + + // Transform the position delta by the camera's rotation + D3DXVECTOR3 vPosDeltaWorld; + D3DXVec3TransformCoord( &vPosDeltaWorld, &vPosDelta, &mCameraRot ); + + // Move the lookAt position + m_vLookAt += vPosDeltaWorld; + if( m_bClipToBoundary ) + ConstrainToBoundary( &m_vLookAt ); + + // Update the eye point based on a radius away from the lookAt position + m_vEye = m_vLookAt - vWorldAhead * m_fRadius; + + // Update the view matrix + D3DXMatrixLookAtLH( &m_mView, &m_vEye, &m_vLookAt, &vWorldUp ); + + D3DXMATRIX mInvView; + D3DXMatrixInverse( &mInvView, NULL, &m_mView ); + mInvView._41 = mInvView._42 = mInvView._43 = 0; + + D3DXMATRIX mModelLastRotInv; + D3DXMatrixInverse( &mModelLastRotInv, NULL, &m_mModelLastRot ); + + // Accumulate the delta of the arcball's rotation in view space. + // Note that per-frame delta rotations could be problematic over long periods of time. + D3DXMATRIX mModelRot; + mModelRot = *m_WorldArcBall.GetRotationMatrix(); + m_mModelRot *= m_mView * mModelLastRotInv * mModelRot * mInvView; + + if( m_ViewArcBall.IsBeingDragged() && m_bAttachCameraToModel && !IsKeyDown( m_aKeys[CAM_CONTROLDOWN] ) ) + { + // Attach camera to model by inverse of the model rotation + D3DXMATRIX mCameraLastRotInv; + D3DXMatrixInverse( &mCameraLastRotInv, NULL, &m_mCameraRotLast ); + D3DXMATRIX mCameraRotDelta = mCameraLastRotInv * mCameraRot; // local to world matrix + m_mModelRot *= mCameraRotDelta; + } + m_mCameraRotLast = mCameraRot; + + m_mModelLastRot = mModelRot; + + // Since we're accumulating delta rotations, we need to orthonormalize + // the matrix to prevent eventual matrix skew + D3DXVECTOR3* pXBasis = ( D3DXVECTOR3* )&m_mModelRot._11; + D3DXVECTOR3* pYBasis = ( D3DXVECTOR3* )&m_mModelRot._21; + D3DXVECTOR3* pZBasis = ( D3DXVECTOR3* )&m_mModelRot._31; + D3DXVec3Normalize( pXBasis, pXBasis ); + D3DXVec3Cross( pYBasis, pZBasis, pXBasis ); + D3DXVec3Normalize( pYBasis, pYBasis ); + D3DXVec3Cross( pZBasis, pXBasis, pYBasis ); + + // Translate the rotation matrix to the same position as the lookAt position + m_mModelRot._41 = m_vLookAt.x; + m_mModelRot._42 = m_vLookAt.y; + m_mModelRot._43 = m_vLookAt.z; + + // Translate world matrix so its at the center of the model + D3DXMATRIX mTrans; + D3DXMatrixTranslation( &mTrans, -m_vModelCenter.x, -m_vModelCenter.y, -m_vModelCenter.z ); + m_mWorld = mTrans * m_mModelRot; +} + + +void CModelViewerCamera::SetDragRect( RECT& rc ) +{ + CBaseCamera::SetDragRect( rc ); + + m_WorldArcBall.SetOffset( rc.left, rc.top ); + m_ViewArcBall.SetOffset( rc.left, rc.top ); + SetWindow( rc.right - rc.left, rc.bottom - rc.top ); +} + + +//-------------------------------------------------------------------------------------- +// Reset the camera's position back to the default +//-------------------------------------------------------------------------------------- +VOID CModelViewerCamera::Reset() +{ + CBaseCamera::Reset(); + + D3DXMatrixIdentity( &m_mWorld ); + D3DXMatrixIdentity( &m_mModelRot ); + D3DXMatrixIdentity( &m_mModelLastRot ); + D3DXMatrixIdentity( &m_mCameraRotLast ); + + m_fRadius = m_fDefaultRadius; + m_WorldArcBall.Reset(); + m_ViewArcBall.Reset(); +} + + +//-------------------------------------------------------------------------------------- +// Override for setting the view parameters +//-------------------------------------------------------------------------------------- +void CModelViewerCamera::SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt ) +{ + CBaseCamera::SetViewParams( pvEyePt, pvLookatPt ); + + // Propogate changes to the member arcball + D3DXQUATERNION quat; + D3DXMATRIXA16 mRotation; + D3DXVECTOR3 vUp( 0,1,0 ); + D3DXMatrixLookAtLH( &mRotation, pvEyePt, pvLookatPt, &vUp ); + D3DXQuaternionRotationMatrix( &quat, &mRotation ); + m_ViewArcBall.SetQuatNow( quat ); + + // Set the radius according to the distance + D3DXVECTOR3 vEyeToPoint; + D3DXVec3Subtract( &vEyeToPoint, pvLookatPt, pvEyePt ); + SetRadius( D3DXVec3Length( &vEyeToPoint ) ); + + // View information changed. FrameMove should be called. + m_bDragSinceLastUpdate = true; +} + + + +//-------------------------------------------------------------------------------------- +// Call this from your message proc so this class can handle window messages +//-------------------------------------------------------------------------------------- +LRESULT CModelViewerCamera::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + CBaseCamera::HandleMessages( hWnd, uMsg, wParam, lParam ); + + if( ( ( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) && m_nRotateModelButtonMask & MOUSE_LEFT_BUTTON ) || + ( ( uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONDBLCLK ) && m_nRotateModelButtonMask & MOUSE_MIDDLE_BUTTON ) || + ( ( uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONDBLCLK ) && m_nRotateModelButtonMask & MOUSE_RIGHT_BUTTON ) ) + { + int iMouseX = ( short )LOWORD( lParam ); + int iMouseY = ( short )HIWORD( lParam ); + m_WorldArcBall.OnBegin( iMouseX, iMouseY ); + } + + if( ( ( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) && m_nRotateCameraButtonMask & MOUSE_LEFT_BUTTON ) || + ( ( uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONDBLCLK ) && + m_nRotateCameraButtonMask & MOUSE_MIDDLE_BUTTON ) || + ( ( uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONDBLCLK ) && m_nRotateCameraButtonMask & MOUSE_RIGHT_BUTTON ) ) + { + int iMouseX = ( short )LOWORD( lParam ); + int iMouseY = ( short )HIWORD( lParam ); + m_ViewArcBall.OnBegin( iMouseX, iMouseY ); + } + + if( uMsg == WM_MOUSEMOVE ) + { + int iMouseX = ( short )LOWORD( lParam ); + int iMouseY = ( short )HIWORD( lParam ); + m_WorldArcBall.OnMove( iMouseX, iMouseY ); + m_ViewArcBall.OnMove( iMouseX, iMouseY ); + } + + if( ( uMsg == WM_LBUTTONUP && m_nRotateModelButtonMask & MOUSE_LEFT_BUTTON ) || + ( uMsg == WM_MBUTTONUP && m_nRotateModelButtonMask & MOUSE_MIDDLE_BUTTON ) || + ( uMsg == WM_RBUTTONUP && m_nRotateModelButtonMask & MOUSE_RIGHT_BUTTON ) ) + { + m_WorldArcBall.OnEnd(); + } + + if( ( uMsg == WM_LBUTTONUP && m_nRotateCameraButtonMask & MOUSE_LEFT_BUTTON ) || + ( uMsg == WM_MBUTTONUP && m_nRotateCameraButtonMask & MOUSE_MIDDLE_BUTTON ) || + ( uMsg == WM_RBUTTONUP && m_nRotateCameraButtonMask & MOUSE_RIGHT_BUTTON ) ) + { + m_ViewArcBall.OnEnd(); + } + + if( uMsg == WM_CAPTURECHANGED ) + { + if( ( HWND )lParam != hWnd ) + { + if( ( m_nRotateModelButtonMask & MOUSE_LEFT_BUTTON ) || + ( m_nRotateModelButtonMask & MOUSE_MIDDLE_BUTTON ) || + ( m_nRotateModelButtonMask & MOUSE_RIGHT_BUTTON ) ) + { + m_WorldArcBall.OnEnd(); + } + + if( ( m_nRotateCameraButtonMask & MOUSE_LEFT_BUTTON ) || + ( m_nRotateCameraButtonMask & MOUSE_MIDDLE_BUTTON ) || + ( m_nRotateCameraButtonMask & MOUSE_RIGHT_BUTTON ) ) + { + m_ViewArcBall.OnEnd(); + } + } + } + + if( uMsg == WM_LBUTTONDOWN || + uMsg == WM_LBUTTONDBLCLK || + uMsg == WM_MBUTTONDOWN || + uMsg == WM_MBUTTONDBLCLK || + uMsg == WM_RBUTTONDOWN || + uMsg == WM_RBUTTONDBLCLK || + uMsg == WM_LBUTTONUP || + uMsg == WM_MBUTTONUP || + uMsg == WM_RBUTTONUP || + uMsg == WM_MOUSEWHEEL || + uMsg == WM_MOUSEMOVE ) + { + m_bDragSinceLastUpdate = true; + } + + return FALSE; +} + + + +//-------------------------------------------------------------------------------------- +// D3D9 +IDirect3DDevice9* CDXUTDirectionWidget::s_pd3d9Device = NULL; +ID3DXEffect* CDXUTDirectionWidget::s_pD3D9Effect = NULL; +ID3DXMesh* CDXUTDirectionWidget::s_pD3D9Mesh = NULL; +D3DXHANDLE CDXUTDirectionWidget::s_hRenderWith1LightNoTexture = NULL; +D3DXHANDLE CDXUTDirectionWidget::s_hMaterialDiffuseColor = NULL; +D3DXHANDLE CDXUTDirectionWidget::s_hLightDir = NULL; +D3DXHANDLE CDXUTDirectionWidget::s_hWorldViewProjection = NULL; +D3DXHANDLE CDXUTDirectionWidget::s_hWorld = NULL; + + +//-------------------------------------------------------------------------------------- +CDXUTDirectionWidget::CDXUTDirectionWidget() +{ + m_fRadius = 1.0f; + m_vDefaultDir = D3DXVECTOR3( 0, 1, 0 ); + m_vCurrentDir = m_vDefaultDir; + m_nRotateMask = MOUSE_RIGHT_BUTTON; + + D3DXMatrixIdentity( &m_mView ); + D3DXMatrixIdentity( &m_mRot ); + D3DXMatrixIdentity( &m_mRotSnapshot ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDirectionWidget::StaticOnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice ) +{ + HRESULT hr; + + s_pd3d9Device = pd3dDevice; + + const char* g_strBuffer = + "float4 g_MaterialDiffuseColor; // Material's diffuse color\r\n" + "float3 g_LightDir; // Light's direction in world space\r\n" + "float4x4 g_mWorld; // World matrix for object\r\n" + "float4x4 g_mWorldViewProjection; // World * View * Projection matrix\r\n" + "\r\n" + "struct VS_OUTPUT\r\n" + "{\r\n" + " float4 Position : POSITION; // vertex position\r\n" + " float4 Diffuse : COLOR0; // vertex diffuse color\r\n" + "};\r\n" + "\r\n" + "VS_OUTPUT RenderWith1LightNoTextureVS( float4 vPos : POSITION,\r\n" + " float3 vNormal : NORMAL )\r\n" + "{\r\n" + " VS_OUTPUT Output;\r\n" + "\r\n" + " // Transform the position from object space to homogeneous projection space\r\n" + " Output.Position = mul(vPos, g_mWorldViewProjection);\r\n" + "\r\n" + " // Transform the normal from object space to world space\r\n" + " float3 vNormalWorldSpace;\r\n" + " vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)\r\n" + "\r\n" + " // Compute simple directional lighting equation\r\n" + " Output.Diffuse.rgb = g_MaterialDiffuseColor * max(0,dot(vNormalWorldSpace, g_LightDir));\r\n" + " Output.Diffuse.a = 1.0f;\r\n" + "\r\n" + " return Output;\r\n" + "}\r\n" + "\r\n" + "float4 RenderWith1LightNoTexturePS( float4 Diffuse : COLOR0 ) : COLOR0\r\n" + "{\r\n" + " return Diffuse;\r\n" + "}\r\n" + "\r\n" + "technique RenderWith1LightNoTexture\r\n" + "{\r\n" + " pass P0\r\n" + " {\r\n" + " VertexShader = compile vs_2_0 RenderWith1LightNoTextureVS();\r\n" + " PixelShader = compile ps_2_0 RenderWith1LightNoTexturePS();\r\n" + " }\r\n" + "}\r\n" + ""; + + UINT dwBufferSize = ( UINT )strlen( g_strBuffer ) + 1; + + V_RETURN( D3DXCreateEffect( s_pd3d9Device, g_strBuffer, dwBufferSize, NULL, NULL, D3DXFX_NOT_CLONEABLE, + NULL, &s_pD3D9Effect, NULL ) ); + + // Save technique handles for use when rendering + s_hRenderWith1LightNoTexture = s_pD3D9Effect->GetTechniqueByName( "RenderWith1LightNoTexture" ); + s_hMaterialDiffuseColor = s_pD3D9Effect->GetParameterByName( NULL, "g_MaterialDiffuseColor" ); + s_hLightDir = s_pD3D9Effect->GetParameterByName( NULL, "g_LightDir" ); + s_hWorld = s_pD3D9Effect->GetParameterByName( NULL, "g_mWorld" ); + s_hWorldViewProjection = s_pD3D9Effect->GetParameterByName( NULL, "g_mWorldViewProjection" ); + + // Load the mesh with D3DX and get back a ID3DXMesh*. For this + // sample we'll ignore the X file's embedded materials since we know + // exactly the model we're loading. See the mesh samples such as + // "OptimizedMesh" for a more generic mesh loading example. + V_RETURN( DXUTCreateArrowMeshFromInternalArray( s_pd3d9Device, &s_pD3D9Mesh ) ); + + // Optimize the mesh for this graphics card's vertex cache + // so when rendering the mesh's triangle list the vertices will + // cache hit more often so it won't have to re-execute the vertex shader + // on those vertices so it will improve perf. + DWORD* rgdwAdjacency = new DWORD[s_pD3D9Mesh->GetNumFaces() * 3]; + if( rgdwAdjacency == NULL ) + return E_OUTOFMEMORY; + V( s_pD3D9Mesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ) ); + V( s_pD3D9Mesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL ) ); + delete []rgdwAdjacency; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDirectionWidget::OnD3D9ResetDevice( const D3DSURFACE_DESC* pBackBufferSurfaceDesc ) +{ + m_ArcBall.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDirectionWidget::StaticOnD3D9LostDevice() +{ + if( s_pD3D9Effect ) + s_pD3D9Effect->OnLostDevice(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDirectionWidget::StaticOnD3D9DestroyDevice() +{ + SAFE_RELEASE( s_pD3D9Effect ); + SAFE_RELEASE( s_pD3D9Mesh ); +} + + +//-------------------------------------------------------------------------------------- +LRESULT CDXUTDirectionWidget::HandleMessages( HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam ) +{ + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + { + if( ( ( m_nRotateMask & MOUSE_LEFT_BUTTON ) != 0 && uMsg == WM_LBUTTONDOWN ) || + ( ( m_nRotateMask & MOUSE_MIDDLE_BUTTON ) != 0 && uMsg == WM_MBUTTONDOWN ) || + ( ( m_nRotateMask & MOUSE_RIGHT_BUTTON ) != 0 && uMsg == WM_RBUTTONDOWN ) ) + { + int iMouseX = ( int )( short )LOWORD( lParam ); + int iMouseY = ( int )( short )HIWORD( lParam ); + m_ArcBall.OnBegin( iMouseX, iMouseY ); + SetCapture( hWnd ); + } + return TRUE; + } + + case WM_MOUSEMOVE: + { + if( m_ArcBall.IsBeingDragged() ) + { + int iMouseX = ( int )( short )LOWORD( lParam ); + int iMouseY = ( int )( short )HIWORD( lParam ); + m_ArcBall.OnMove( iMouseX, iMouseY ); + UpdateLightDir(); + } + return TRUE; + } + + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + { + if( ( ( m_nRotateMask & MOUSE_LEFT_BUTTON ) != 0 && uMsg == WM_LBUTTONUP ) || + ( ( m_nRotateMask & MOUSE_MIDDLE_BUTTON ) != 0 && uMsg == WM_MBUTTONUP ) || + ( ( m_nRotateMask & MOUSE_RIGHT_BUTTON ) != 0 && uMsg == WM_RBUTTONUP ) ) + { + m_ArcBall.OnEnd(); + ReleaseCapture(); + } + + UpdateLightDir(); + return TRUE; + } + + case WM_CAPTURECHANGED: + { + if( ( HWND )lParam != hWnd ) + { + if( ( m_nRotateMask & MOUSE_LEFT_BUTTON ) || + ( m_nRotateMask & MOUSE_MIDDLE_BUTTON ) || + ( m_nRotateMask & MOUSE_RIGHT_BUTTON ) ) + { + m_ArcBall.OnEnd(); + ReleaseCapture(); + } + } + return TRUE; + } + } + + return 0; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDirectionWidget::OnRender9( D3DXCOLOR color, const D3DXMATRIX* pmView, + const D3DXMATRIX* pmProj, const D3DXVECTOR3* pEyePt ) +{ + m_mView = *pmView; + + // Render the light spheres so the user can visually see the light dir + UINT iPass, cPasses; + D3DXMATRIX mRotate; + D3DXMATRIX mScale; + D3DXMATRIX mTrans; + D3DXMATRIXA16 mWorldViewProj; + HRESULT hr; + + V( s_pD3D9Effect->SetTechnique( s_hRenderWith1LightNoTexture ) ); + V( s_pD3D9Effect->SetVector( s_hMaterialDiffuseColor, ( D3DXVECTOR4* )&color ) ); + + D3DXVECTOR3 vEyePt; + D3DXVec3Normalize( &vEyePt, pEyePt ); + V( s_pD3D9Effect->SetValue( s_hLightDir, &vEyePt, sizeof( D3DXVECTOR3 ) ) ); + + // Rotate arrow model to point towards origin + D3DXMATRIX mRotateA, mRotateB; + D3DXVECTOR3 vAt = D3DXVECTOR3( 0, 0, 0 ); + D3DXVECTOR3 vUp = D3DXVECTOR3( 0, 1, 0 ); + D3DXMatrixRotationX( &mRotateB, D3DX_PI ); + D3DXMatrixLookAtLH( &mRotateA, &m_vCurrentDir, &vAt, &vUp ); + D3DXMatrixInverse( &mRotateA, NULL, &mRotateA ); + mRotate = mRotateB * mRotateA; + + D3DXVECTOR3 vL = m_vCurrentDir * m_fRadius * 1.0f; + D3DXMatrixTranslation( &mTrans, vL.x, vL.y, vL.z ); + D3DXMatrixScaling( &mScale, m_fRadius * 0.2f, m_fRadius * 0.2f, m_fRadius * 0.2f ); + + D3DXMATRIX mWorld = mRotate * mScale * mTrans; + mWorldViewProj = mWorld * ( m_mView )*( *pmProj ); + + V( s_pD3D9Effect->SetMatrix( s_hWorldViewProjection, &mWorldViewProj ) ); + V( s_pD3D9Effect->SetMatrix( s_hWorld, &mWorld ) ); + + for( int iSubset = 0; iSubset < 2; iSubset++ ) + { + V( s_pD3D9Effect->Begin( &cPasses, 0 ) ); + for( iPass = 0; iPass < cPasses; iPass++ ) + { + V( s_pD3D9Effect->BeginPass( iPass ) ); + V( s_pD3D9Mesh->DrawSubset( iSubset ) ); + V( s_pD3D9Effect->EndPass() ); + } + V( s_pD3D9Effect->End() ); + } + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDirectionWidget::UpdateLightDir() +{ + D3DXMATRIX mInvView; + D3DXMatrixInverse( &mInvView, NULL, &m_mView ); + mInvView._41 = mInvView._42 = mInvView._43 = 0; + + D3DXMATRIX mLastRotInv; + D3DXMatrixInverse( &mLastRotInv, NULL, &m_mRotSnapshot ); + + D3DXMATRIX mRot = *m_ArcBall.GetRotationMatrix(); + m_mRotSnapshot = mRot; + + // Accumulate the delta of the arcball's rotation in view space. + // Note that per-frame delta rotations could be problematic over long periods of time. + m_mRot *= m_mView * mLastRotInv * mRot * mInvView; + + // Since we're accumulating delta rotations, we need to orthonormalize + // the matrix to prevent eventual matrix skew + D3DXVECTOR3* pXBasis = ( D3DXVECTOR3* )&m_mRot._11; + D3DXVECTOR3* pYBasis = ( D3DXVECTOR3* )&m_mRot._21; + D3DXVECTOR3* pZBasis = ( D3DXVECTOR3* )&m_mRot._31; + D3DXVec3Normalize( pXBasis, pXBasis ); + D3DXVec3Cross( pYBasis, pZBasis, pXBasis ); + D3DXVec3Normalize( pYBasis, pYBasis ); + D3DXVec3Cross( pZBasis, pXBasis, pYBasis ); + + // Transform the default direction vector by the light's rotation matrix + D3DXVec3TransformNormal( &m_vCurrentDir, &m_vDefaultDir, &m_mRot ); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDirectionWidget::StaticOnD3D11CreateDevice( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext ) +{ + + + //s_pd3d10Device = pd3dDevice; + + //const char* g_strBuffer = + // "float4 g_MaterialDiffuseColor; // Material's diffuse color\r\n" + // "float4 g_LightDir; // Light's direction in world space\r\n" + // "float4x4 g_mWorld; // World matrix for object\r\n" + // "float4x4 g_mWorldViewProjection; // World * View * Projection matrix\r\n" + // "\r\n" + // "struct VS_OUTPUT\r\n" + // "{\r\n" + // " float4 Position : SV_POSITION; // vertex position\r\n" + // " float4 Diffuse : COLOR0; // vertex diffuse color\r\n" + // "};\r\n" + // "\r\n" + // "VS_OUTPUT RenderWith1LightNoTextureVS( float3 vPos : POSITION,\r\n" + // " float3 vNormal : NORMAL )\r\n" + // "{\r\n" + // " VS_OUTPUT Output;\r\n" + // "\r\n" + // " // Transform the position from object space to homogeneous projection space\r\n" + // " Output.Position = mul( float4(vPos,1), g_mWorldViewProjection);\r\n" + // "\r\n" + // " // Transform the normal from object space to world space\r\n" + // " float3 vNormalWorldSpace;\r\n" + // " vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)\r\n" + // "\r\n" + // " // Compute simple directional lighting equation\r\n" + // " Output.Diffuse.rgb = g_MaterialDiffuseColor * max(0,dot(vNormalWorldSpace, g_LightDir));\r\n" + // " Output.Diffuse.a = 1.0f;\r\n" + // "\r\n" + // " return Output;\r\n" + // "}\r\n" + // "\r\n" + // "float4 RenderWith1LightNoTexturePS( VS_OUTPUT Input ) : SV_TARGET\r\n" + // "{\r\n" + // " return Input.Diffuse;\r\n" + // "}\r\n" + // "\r\n" + // "technique10 RenderWith1LightNoTexture\r\n" + // "{\r\n" + // " pass p0\r\n" + // " {\r\n" + // " SetVertexShader( CompileShader( vs_4_0, RenderWith1LightNoTextureVS() ) );\r\n" + // " SetGeometryShader( NULL );\r\n" + // " SetPixelShader( CompileShader( ps_4_0, RenderWith1LightNoTexturePS() ) );\r\n" + // " }\r\n" + // "}\r\n" + // ""; + + //UINT dwBufferSize = ( UINT )strlen( g_strBuffer ) + 1; + + //HRESULT hr = D3DX10CreateEffectFromMemory( g_strBuffer, dwBufferSize, "None", NULL, NULL, "fx_4_0", + // D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, + // NULL, &s_pD3D10Effect, NULL, NULL ); + //if( FAILED( hr ) ) + // return hr; + + //s_pRenderTech = s_pD3D10Effect->GetTechniqueByName( "RenderWith1LightNoTexture" ); + //g_pMaterialDiffuseColor = s_pD3D10Effect->GetVariableByName( "g_MaterialDiffuseColor" )->AsVector(); + //g_pLightDir = s_pD3D10Effect->GetVariableByName( "g_LightDir" )->AsVector(); + //g_pmWorld = s_pD3D10Effect->GetVariableByName( "g_mWorld" )->AsMatrix(); + //g_pmWorldViewProjection = s_pD3D10Effect->GetVariableByName( "g_mWorldViewProjection" )->AsMatrix(); + + //const D3D10_INPUT_ELEMENT_DESC layout[] = + //{ + // { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + // { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + //}; + //D3D10_PASS_DESC PassDesc; + //V_RETURN( s_pRenderTech->GetPassByIndex( 0 )->GetDesc( &PassDesc ) ); + //V_RETURN( pd3dDevice->CreateInputLayout( layout, 2, PassDesc.pIAInputSignature, + // PassDesc.IAInputSignatureSize, &s_pVertexLayout ) ); + + //TODO: Add loading code here + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDirectionWidget::OnRender11( D3DXCOLOR color, const D3DXMATRIX* pmView, const D3DXMATRIX* pmProj, + const D3DXVECTOR3* pEyePt ) +{ + // NO D3DX11 YET + // m_mView = *pmView; + + // // Render the light spheres so the user can visually see the light dir + // D3DXMATRIX mRotate; + // D3DXMATRIX mScale; + // D3DXMATRIX mTrans; + // D3DXMATRIXA16 mWorldViewProj; + + // g_pMaterialDiffuseColor->SetFloatVector( ( float* )&color ); + // D3DXVECTOR3 vEyePt; + // D3DXVec3Normalize( &vEyePt, pEyePt ); + // g_pLightDir->SetFloatVector( ( float* )&vEyePt ); + + // // Rotate arrow model to point towards origin + // D3DXMATRIX mRotateA, mRotateB; + // D3DXVECTOR3 vAt = D3DXVECTOR3( 0, 0, 0 ); + // D3DXVECTOR3 vUp = D3DXVECTOR3( 0, 1, 0 ); + // D3DXMatrixRotationX( &mRotateB, D3DX_PI ); + // D3DXMatrixLookAtLH( &mRotateA, &m_vCurrentDir, &vAt, &vUp ); + // D3DXMatrixInverse( &mRotateA, NULL, &mRotateA ); + // mRotate = mRotateB * mRotateA; + + // D3DXVECTOR3 vL = m_vCurrentDir * m_fRadius * 1.0f; + // D3DXMatrixTranslation( &mTrans, vL.x, vL.y, vL.z ); + // D3DXMatrixScaling( &mScale, m_fRadius * 0.2f, m_fRadius * 0.2f, m_fRadius * 0.2f ); + + // D3DXMATRIX mWorld = mRotate * mScale * mTrans; + // mWorldViewProj = mWorld * ( m_mView )*( *pmProj ); + + // g_pmWorldViewProjection->SetMatrix( ( float* )&mWorldViewProj ); + // g_pmWorld->SetMatrix( ( float* )&mWorld ); + + // s_pd3d10Device->IASetInputLayout( s_pVertexLayout ); + + //TODO: Add rendering code here + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +void CDXUTDirectionWidget::StaticOnD3D11DestroyDevice() +{ +// SAFE_RELEASE( s_pVertexLayout ); +// SAFE_RELEASE( s_pD3D11Effect ); +} diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.h b/Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.h new file mode 100644 index 0000000..6325fa8 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTcamera.h @@ -0,0 +1,517 @@ +//-------------------------------------------------------------------------------------- +// File: Camera.h +// +// Helper functions for Direct3D programming. +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef CAMERA_H +#define CAMERA_H + +//-------------------------------------------------------------------------------------- +class CD3DArcBall +{ +public: + CD3DArcBall(); + + // Functions to change behavior + void Reset(); + void SetTranslationRadius( FLOAT fRadiusTranslation ) + { + m_fRadiusTranslation = fRadiusTranslation; + } + void SetWindow( INT nWidth, INT nHeight, FLOAT fRadius = 0.9f ) + { + m_nWidth = nWidth; m_nHeight = nHeight; m_fRadius = fRadius; + m_vCenter = D3DXVECTOR2( m_nWidth / 2.0f, m_nHeight / 2.0f ); + } + void SetOffset( INT nX, INT nY ) + { + m_Offset.x = nX; m_Offset.y = nY; + } + + // Call these from client and use GetRotationMatrix() to read new rotation matrix + void OnBegin( int nX, int nY ); // start the rotation (pass current mouse position) + void OnMove( int nX, int nY ); // continue the rotation (pass current mouse position) + void OnEnd(); // end the rotation + + // Or call this to automatically handle left, middle, right buttons + LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + // Functions to get/set state + const D3DXMATRIX* GetRotationMatrix() + { + return D3DXMatrixRotationQuaternion( &m_mRotation, &m_qNow ); + }; + const D3DXMATRIX* GetTranslationMatrix() const + { + return &m_mTranslation; + } + const D3DXMATRIX* GetTranslationDeltaMatrix() const + { + return &m_mTranslationDelta; + } + bool IsBeingDragged() const + { + return m_bDrag; + } + D3DXQUATERNION GetQuatNow() const + { + return m_qNow; + } + void SetQuatNow( D3DXQUATERNION q ) + { + m_qNow = q; + } + + static D3DXQUATERNION WINAPI QuatFromBallPoints( const D3DXVECTOR3& vFrom, const D3DXVECTOR3& vTo ); + + +protected: + D3DXMATRIXA16 m_mRotation; // Matrix for arc ball's orientation + D3DXMATRIXA16 m_mTranslation; // Matrix for arc ball's position + D3DXMATRIXA16 m_mTranslationDelta; // Matrix for arc ball's position + + POINT m_Offset; // window offset, or upper-left corner of window + INT m_nWidth; // arc ball's window width + INT m_nHeight; // arc ball's window height + D3DXVECTOR2 m_vCenter; // center of arc ball + FLOAT m_fRadius; // arc ball's radius in screen coords + FLOAT m_fRadiusTranslation; // arc ball's radius for translating the target + + D3DXQUATERNION m_qDown; // Quaternion before button down + D3DXQUATERNION m_qNow; // Composite quaternion for current drag + bool m_bDrag; // Whether user is dragging arc ball + + POINT m_ptLastMouse; // position of last mouse point + D3DXVECTOR3 m_vDownPt; // starting point of rotation arc + D3DXVECTOR3 m_vCurrentPt; // current point of rotation arc + + D3DXVECTOR3 ScreenToVector( float fScreenPtX, float fScreenPtY ); +}; + + +//-------------------------------------------------------------------------------------- +// used by CCamera to map WM_KEYDOWN keys +//-------------------------------------------------------------------------------------- +enum D3DUtil_CameraKeys +{ + CAM_STRAFE_LEFT = 0, + CAM_STRAFE_RIGHT, + CAM_MOVE_FORWARD, + CAM_MOVE_BACKWARD, + CAM_MOVE_UP, + CAM_MOVE_DOWN, + CAM_RESET, + CAM_CONTROLDOWN, + CAM_MAX_KEYS, + CAM_UNKNOWN = 0xFF +}; + +#define KEY_WAS_DOWN_MASK 0x80 +#define KEY_IS_DOWN_MASK 0x01 + +#define MOUSE_LEFT_BUTTON 0x01 +#define MOUSE_MIDDLE_BUTTON 0x02 +#define MOUSE_RIGHT_BUTTON 0x04 +#define MOUSE_WHEEL 0x08 + + +//-------------------------------------------------------------------------------------- +// Simple base camera class that moves and rotates. The base class +// records mouse and keyboard input for use by a derived class, and +// keeps common state. +//-------------------------------------------------------------------------------------- +class CBaseCamera +{ +public: + CBaseCamera(); + + // Call these from client and use Get*Matrix() to read new matrices + virtual LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual void FrameMove( FLOAT fElapsedTime ) = 0; + + // Functions to change camera matrices + virtual void Reset(); + virtual void SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt ); + virtual void SetProjParams( FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane, FLOAT fFarPlane ); + + // Functions to change behavior + virtual void SetDragRect( RECT& rc ) + { + m_rcDrag = rc; + } + void SetInvertPitch( bool bInvertPitch ) + { + m_bInvertPitch = bInvertPitch; + } + void SetDrag( bool bMovementDrag, FLOAT fTotalDragTimeToZero = 0.25f ) + { + m_bMovementDrag = bMovementDrag; m_fTotalDragTimeToZero = fTotalDragTimeToZero; + } + void SetEnableYAxisMovement( bool bEnableYAxisMovement ) + { + m_bEnableYAxisMovement = bEnableYAxisMovement; + } + void SetEnablePositionMovement( bool bEnablePositionMovement ) + { + m_bEnablePositionMovement = bEnablePositionMovement; + } + void SetClipToBoundary( bool bClipToBoundary, D3DXVECTOR3* pvMinBoundary, + D3DXVECTOR3* pvMaxBoundary ) + { + m_bClipToBoundary = bClipToBoundary; if( pvMinBoundary ) m_vMinBoundary = *pvMinBoundary; + if( pvMaxBoundary ) m_vMaxBoundary = *pvMaxBoundary; + } + void SetScalers( FLOAT fRotationScaler = 0.01f, FLOAT fMoveScaler = 5.0f ) + { + m_fRotationScaler = fRotationScaler; m_fMoveScaler = fMoveScaler; + } + void SetNumberOfFramesToSmoothMouseData( int nFrames ) + { + if( nFrames > 0 ) m_fFramesToSmoothMouseData = ( float )nFrames; + } + void SetResetCursorAfterMove( bool bResetCursorAfterMove ) + { + m_bResetCursorAfterMove = bResetCursorAfterMove; + } + + // Functions to get state + const D3DXMATRIX* GetViewMatrix() const + { + return &m_mView; + } + const D3DXMATRIX* GetProjMatrix() const + { + return &m_mProj; + } + const D3DXVECTOR3* GetEyePt() const + { + return &m_vEye; + } + const D3DXVECTOR3* GetLookAtPt() const + { + return &m_vLookAt; + } + float GetNearClip() const + { + return m_fNearPlane; + } + float GetFarClip() const + { + return m_fFarPlane; + } + + bool IsBeingDragged() const + { + return ( m_bMouseLButtonDown || m_bMouseMButtonDown || m_bMouseRButtonDown ); + } + bool IsMouseLButtonDown() const + { + return m_bMouseLButtonDown; + } + bool IsMouseMButtonDown() const + { + return m_bMouseMButtonDown; + } + bool IsMouseRButtonDown() const + { + return m_bMouseRButtonDown; + } + +protected: + // Functions to map a WM_KEYDOWN key to a D3DUtil_CameraKeys enum + virtual D3DUtil_CameraKeys MapKey( UINT nKey ); + bool IsKeyDown( BYTE key ) const + { + return( ( key & KEY_IS_DOWN_MASK ) == KEY_IS_DOWN_MASK ); + } + bool WasKeyDown( BYTE key ) const + { + return( ( key & KEY_WAS_DOWN_MASK ) == KEY_WAS_DOWN_MASK ); + } + + void ConstrainToBoundary( D3DXVECTOR3* pV ); + void UpdateMouseDelta(); + void UpdateVelocity( float fElapsedTime ); + void GetInput( bool bGetKeyboardInput, bool bGetMouseInput, bool bGetGamepadInput, + bool bResetCursorAfterMove ); + + D3DXMATRIX m_mView; // View matrix + D3DXMATRIX m_mProj; // Projection matrix + + DXUT_GAMEPAD m_GamePad[DXUT_MAX_CONTROLLERS]; // XInput controller state + D3DXVECTOR3 m_vGamePadLeftThumb; + D3DXVECTOR3 m_vGamePadRightThumb; + double m_GamePadLastActive[DXUT_MAX_CONTROLLERS]; + + int m_cKeysDown; // Number of camera keys that are down. + BYTE m_aKeys[CAM_MAX_KEYS]; // State of input - KEY_WAS_DOWN_MASK|KEY_IS_DOWN_MASK + D3DXVECTOR3 m_vKeyboardDirection; // Direction vector of keyboard input + POINT m_ptLastMousePosition; // Last absolute position of mouse cursor + bool m_bMouseLButtonDown; // True if left button is down + bool m_bMouseMButtonDown; // True if middle button is down + bool m_bMouseRButtonDown; // True if right button is down + int m_nCurrentButtonMask; // mask of which buttons are down + int m_nMouseWheelDelta; // Amount of middle wheel scroll (+/-) + D3DXVECTOR2 m_vMouseDelta; // Mouse relative delta smoothed over a few frames + float m_fFramesToSmoothMouseData; // Number of frames to smooth mouse data over + + D3DXVECTOR3 m_vDefaultEye; // Default camera eye position + D3DXVECTOR3 m_vDefaultLookAt; // Default LookAt position + D3DXVECTOR3 m_vEye; // Camera eye position + D3DXVECTOR3 m_vLookAt; // LookAt position + float m_fCameraYawAngle; // Yaw angle of camera + float m_fCameraPitchAngle; // Pitch angle of camera + + RECT m_rcDrag; // Rectangle within which a drag can be initiated. + D3DXVECTOR3 m_vVelocity; // Velocity of camera + bool m_bMovementDrag; // If true, then camera movement will slow to a stop otherwise movement is instant + D3DXVECTOR3 m_vVelocityDrag; // Velocity drag force + FLOAT m_fDragTimer; // Countdown timer to apply drag + FLOAT m_fTotalDragTimeToZero; // Time it takes for velocity to go from full to 0 + D3DXVECTOR2 m_vRotVelocity; // Velocity of camera + + float m_fFOV; // Field of view + float m_fAspect; // Aspect ratio + float m_fNearPlane; // Near plane + float m_fFarPlane; // Far plane + + float m_fRotationScaler; // Scaler for rotation + float m_fMoveScaler; // Scaler for movement + + bool m_bInvertPitch; // Invert the pitch axis + bool m_bEnablePositionMovement; // If true, then the user can translate the camera/model + bool m_bEnableYAxisMovement; // If true, then camera can move in the y-axis + + bool m_bClipToBoundary; // If true, then the camera will be clipped to the boundary + D3DXVECTOR3 m_vMinBoundary; // Min point in clip boundary + D3DXVECTOR3 m_vMaxBoundary; // Max point in clip boundary + + bool m_bResetCursorAfterMove;// If true, the class will reset the cursor position so that the cursor always has space to move +}; + + +//-------------------------------------------------------------------------------------- +// Simple first person camera class that moves and rotates. +// It allows yaw and pitch but not roll. It uses WM_KEYDOWN and +// GetCursorPos() to respond to keyboard and mouse input and updates the +// view matrix based on input. +//-------------------------------------------------------------------------------------- +class CFirstPersonCamera : public CBaseCamera +{ +public: + CFirstPersonCamera(); + + // Call these from client and use Get*Matrix() to read new matrices + virtual void FrameMove( FLOAT fElapsedTime ); + + // Functions to change behavior + void SetRotateButtons( bool bLeft, bool bMiddle, bool bRight, bool bRotateWithoutButtonDown = false ); + + // Functions to get state + D3DXMATRIX* GetWorldMatrix() + { + return &m_mCameraWorld; + } + + const D3DXVECTOR3* GetWorldRight() const + { + return ( D3DXVECTOR3* )&m_mCameraWorld._11; + } + const D3DXVECTOR3* GetWorldUp() const + { + return ( D3DXVECTOR3* )&m_mCameraWorld._21; + } + const D3DXVECTOR3* GetWorldAhead() const + { + return ( D3DXVECTOR3* )&m_mCameraWorld._31; + } + const D3DXVECTOR3* GetEyePt() const + { + return ( D3DXVECTOR3* )&m_mCameraWorld._41; + } + +protected: + D3DXMATRIX m_mCameraWorld; // World matrix of the camera (inverse of the view matrix) + + int m_nActiveButtonMask; // Mask to determine which button to enable for rotation + bool m_bRotateWithoutButtonDown; +}; + + +//-------------------------------------------------------------------------------------- +// Simple model viewing camera class that rotates around the object. +//-------------------------------------------------------------------------------------- +class CModelViewerCamera : public CBaseCamera +{ +public: + CModelViewerCamera(); + + // Call these from client and use Get*Matrix() to read new matrices + virtual LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual void FrameMove( FLOAT fElapsedTime ); + + + // Functions to change behavior + virtual void SetDragRect( RECT& rc ); + void Reset(); + void SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt ); + void SetButtonMasks( int nRotateModelButtonMask = MOUSE_LEFT_BUTTON, int nZoomButtonMask = MOUSE_WHEEL, + int nRotateCameraButtonMask = MOUSE_RIGHT_BUTTON ) + { + m_nRotateModelButtonMask = nRotateModelButtonMask, m_nZoomButtonMask = nZoomButtonMask; + m_nRotateCameraButtonMask = nRotateCameraButtonMask; + } + void SetAttachCameraToModel( bool bEnable = false ) + { + m_bAttachCameraToModel = bEnable; + } + void SetWindow( int nWidth, int nHeight, float fArcballRadius=0.9f ) + { + m_WorldArcBall.SetWindow( nWidth, nHeight, fArcballRadius ); + m_ViewArcBall.SetWindow( nWidth, nHeight, fArcballRadius ); + } + void SetRadius( float fDefaultRadius=5.0f, float fMinRadius=1.0f, float fMaxRadius=FLT_MAX ) + { + m_fDefaultRadius = m_fRadius = fDefaultRadius; m_fMinRadius = fMinRadius; m_fMaxRadius = fMaxRadius; + m_bDragSinceLastUpdate = true; + } + void SetModelCenter( D3DXVECTOR3 vModelCenter ) + { + m_vModelCenter = vModelCenter; + } + void SetLimitPitch( bool bLimitPitch ) + { + m_bLimitPitch = bLimitPitch; + } + void SetViewQuat( D3DXQUATERNION q ) + { + m_ViewArcBall.SetQuatNow( q ); m_bDragSinceLastUpdate = true; + } + void SetWorldQuat( D3DXQUATERNION q ) + { + m_WorldArcBall.SetQuatNow( q ); m_bDragSinceLastUpdate = true; + } + + // Functions to get state + const D3DXMATRIX* GetWorldMatrix() const + { + return &m_mWorld; + } + void SetWorldMatrix( D3DXMATRIX& mWorld ) + { + m_mWorld = mWorld; m_bDragSinceLastUpdate = true; + } + +protected: + CD3DArcBall m_WorldArcBall; + CD3DArcBall m_ViewArcBall; + D3DXVECTOR3 m_vModelCenter; + D3DXMATRIX m_mModelLastRot; // Last arcball rotation matrix for model + D3DXMATRIX m_mModelRot; // Rotation matrix of model + D3DXMATRIX m_mWorld; // World matrix of model + + int m_nRotateModelButtonMask; + int m_nZoomButtonMask; + int m_nRotateCameraButtonMask; + + bool m_bAttachCameraToModel; + bool m_bLimitPitch; + float m_fRadius; // Distance from the camera to model + float m_fDefaultRadius; // Distance from the camera to model + float m_fMinRadius; // Min radius + float m_fMaxRadius; // Max radius + bool m_bDragSinceLastUpdate; // True if mouse drag has happened since last time FrameMove is called. + + D3DXMATRIX m_mCameraRotLast; + +}; + +//-------------------------------------------------------------------------------------- +// Manages the mesh, direction, mouse events of a directional arrow that +// rotates around a radius controlled by an arcball +//-------------------------------------------------------------------------------------- +class CDXUTDirectionWidget +{ +public: + CDXUTDirectionWidget(); + + static HRESULT WINAPI StaticOnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice ); + HRESULT OnD3D9ResetDevice( const D3DSURFACE_DESC* pBackBufferSurfaceDesc ); + HRESULT OnRender9( D3DXCOLOR color, const D3DXMATRIX* pmView, const D3DXMATRIX* pmProj, + const D3DXVECTOR3* pEyePt ); + LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + static void WINAPI StaticOnD3D9LostDevice(); + static void WINAPI StaticOnD3D9DestroyDevice(); + + static HRESULT WINAPI StaticOnD3D11CreateDevice( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext ); + HRESULT OnRender11( D3DXCOLOR color, const D3DXMATRIX* pmView, const D3DXMATRIX* pmProj, + const D3DXVECTOR3* pEyePt ); + static void WINAPI StaticOnD3D11DestroyDevice(); + + D3DXVECTOR3 GetLightDirection() + { + return m_vCurrentDir; + }; + void SetLightDirection( D3DXVECTOR3 vDir ) + { + m_vDefaultDir = m_vCurrentDir = vDir; + }; + void SetButtonMask( int nRotate = MOUSE_RIGHT_BUTTON ) + { + m_nRotateMask = nRotate; + } + + float GetRadius() + { + return m_fRadius; + }; + void SetRadius( float fRadius ) + { + m_fRadius = fRadius; + }; + + bool IsBeingDragged() + { + return m_ArcBall.IsBeingDragged(); + }; + +protected: + HRESULT UpdateLightDir(); + + // D3D9 objects + static IDirect3DDevice9* s_pd3d9Device; + static ID3DXEffect* s_pD3D9Effect; + static ID3DXMesh* s_pD3D9Mesh; + static D3DXHANDLE s_hRenderWith1LightNoTexture; + static D3DXHANDLE s_hMaterialDiffuseColor; + static D3DXHANDLE s_hLightDir; + static D3DXHANDLE s_hWorldViewProjection; + static D3DXHANDLE s_hWorld; + + // D3D10 objects + //static ID3D10Device* s_pd3d10Device; + //static ID3D10Effect* s_pD3D10Effect; + //TODO: add some sort of d3d10 mesh object here + //static ID3D10InputLayout* s_pVertexLayout; + //static ID3D10EffectTechnique* s_pRenderTech; + //static ID3D10EffectVectorVariable* g_pMaterialDiffuseColor; + //static ID3D10EffectVectorVariable* g_pLightDir; + //static ID3D10EffectMatrixVariable* g_pmWorld; + //static ID3D10EffectMatrixVariable* g_pmWorldViewProjection; + + D3DXMATRIXA16 m_mRot; + D3DXMATRIXA16 m_mRotSnapshot; + float m_fRadius; + int m_nRotateMask; + CD3DArcBall m_ArcBall; + D3DXVECTOR3 m_vDefaultDir; + D3DXVECTOR3 m_vCurrentDir; + D3DXMATRIX m_mView; +}; + + + +#endif diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.cpp b/Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.cpp new file mode 100644 index 0000000..dba0b17 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.cpp @@ -0,0 +1,7241 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTgui.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#include "DXUTgui.h" +#include "DXUTsettingsDlg.h" +#include "DXUTres.h" + +#include "SDKMisc.h" + +#undef min // use __min instead +#undef max // use __max instead + +#ifndef WM_XBUTTONDOWN +#define WM_XBUTTONDOWN 0x020B // (not always defined) +#endif +#ifndef WM_XBUTTONUP +#define WM_XBUTTONUP 0x020C // (not always defined) +#endif +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x020A // (not always defined) +#endif +#ifndef WHEEL_DELTA +#define WHEEL_DELTA 120 // (not always defined) +#endif + +// Minimum scroll bar thumb size +#define SCROLLBAR_MINTHUMBSIZE 8 + +// Delay and repeat period when clicking on the scroll bar arrows +#define SCROLLBAR_ARROWCLICK_DELAY 0.33 +#define SCROLLBAR_ARROWCLICK_REPEAT 0.05 + +#define DXUT_NEAR_BUTTON_DEPTH 0.6f +#define DXUT_FAR_BUTTON_DEPTH 0.8f + +#define DXUT_MAX_GUI_SPRITES 500 + +D3DCOLORVALUE D3DCOLOR_TO_D3DCOLORVALUE( D3DCOLOR c ) +{ + D3DCOLORVALUE cv = + { + ( ( c >> 16 ) & 0xFF ) / 255.0f, + ( ( c >> 8 ) & 0xFF ) / 255.0f, + ( c & 0xFF ) / 255.0f, + ( ( c >> 24 ) & 0xFF ) / 255.0f + }; + return cv; +} + +#define UNISCRIBE_DLLNAME L"usp10.dll" + +#define GETPROCADDRESS( Module, APIName, Temp ) \ + Temp = GetProcAddress( Module, #APIName ); \ + if( Temp ) \ + *(FARPROC*)&_##APIName = Temp + +#define PLACEHOLDERPROC( APIName ) \ + _##APIName = Dummy_##APIName + +#define IMM32_DLLNAME L"imm32.dll" +#define VER_DLLNAME L"version.dll" + +CHAR g_strUIEffectFile[] = \ + "Texture2D g_Texture;"\ + ""\ + "SamplerState Sampler"\ + "{"\ + " Filter = MIN_MAG_MIP_LINEAR;"\ + " AddressU = Wrap;"\ + " AddressV = Wrap;"\ + "};"\ + ""\ + "BlendState UIBlend"\ + "{"\ + " AlphaToCoverageEnable = FALSE;"\ + " BlendEnable[0] = TRUE;"\ + " SrcBlend = SRC_ALPHA;"\ + " DestBlend = INV_SRC_ALPHA;"\ + " BlendOp = ADD;"\ + " SrcBlendAlpha = ONE;"\ + " DestBlendAlpha = ZERO;"\ + " BlendOpAlpha = ADD;"\ + " RenderTargetWriteMask[0] = 0x0F;"\ + "};"\ + ""\ + "BlendState NoBlending"\ + "{"\ + " BlendEnable[0] = FALSE;"\ + " RenderTargetWriteMask[0] = 0x0F;"\ + "};"\ + ""\ + "DepthStencilState DisableDepth"\ + "{"\ + " DepthEnable = false;"\ + "};"\ + "DepthStencilState EnableDepth"\ + "{"\ + " DepthEnable = true;"\ + "};"\ + "struct VS_OUTPUT"\ + "{"\ + " float4 Pos : POSITION;"\ + " float4 Dif : COLOR;"\ + " float2 Tex : TEXCOORD;"\ + "};"\ + ""\ + "VS_OUTPUT VS( float3 vPos : POSITION,"\ + " float4 Dif : COLOR,"\ + " float2 vTexCoord0 : TEXCOORD )"\ + "{"\ + " VS_OUTPUT Output;"\ + ""\ + " Output.Pos = float4( vPos, 1.0f );"\ + " Output.Dif = Dif;"\ + " Output.Tex = vTexCoord0;"\ + ""\ + " return Output;"\ + "}"\ + ""\ + "float4 PS( VS_OUTPUT In ) : SV_Target"\ + "{"\ + " return g_Texture.Sample( Sampler, In.Tex ) * In.Dif;"\ + "}"\ + ""\ + "float4 PSUntex( VS_OUTPUT In ) : SV_Target"\ + "{"\ + " return In.Dif;"\ + "}"\ + ""\ + "technique10 RenderUI"\ + "{"\ + " pass P0"\ + " {"\ + " SetVertexShader( CompileShader( vs_4_0, VS() ) );"\ + " SetGeometryShader( NULL );"\ + " SetPixelShader( CompileShader( ps_4_0, PS() ) );"\ + " SetDepthStencilState( DisableDepth, 0 );"\ + " SetBlendState( UIBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\ + " }"\ + "}"\ + "technique10 RenderUIUntex"\ + "{"\ + " pass P0"\ + " {"\ + " SetVertexShader( CompileShader( vs_4_0, VS() ) );"\ + " SetGeometryShader( NULL );"\ + " SetPixelShader( CompileShader( ps_4_0, PSUntex() ) );"\ + " SetDepthStencilState( DisableDepth, 0 );"\ + " SetBlendState( UIBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\ + " }"\ + "}"\ + "technique10 RestoreState"\ + "{"\ + " pass P0"\ + " {"\ + " SetDepthStencilState( EnableDepth, 0 );"\ + " SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\ + " }"\ + "}"; +const UINT g_uUIEffectFileSize = sizeof( g_strUIEffectFile ); + + +// DXUT_MAX_EDITBOXLENGTH is the maximum string length allowed in edit boxes, +// including the NULL terminator. +// +// Uniscribe does not support strings having bigger-than-16-bits length. +// This means that the string must be less than 65536 characters long, +// including the NULL terminator. +#define DXUT_MAX_EDITBOXLENGTH 0xFFFF + + +double CDXUTDialog::s_fTimeRefresh = 0.0f; +CDXUTControl* CDXUTDialog::s_pControlFocus = NULL; // The control which has focus +CDXUTControl* CDXUTDialog::s_pControlPressed = NULL; // The control currently pressed + + +struct DXUT_SCREEN_VERTEX +{ + float x, y, z, h; + D3DCOLOR color; + float tu, tv; + + static DWORD FVF; +}; +DWORD DXUT_SCREEN_VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1; + + +struct DXUT_SCREEN_VERTEX_UNTEX +{ + float x, y, z, h; + D3DCOLOR color; + + static DWORD FVF; +}; +DWORD DXUT_SCREEN_VERTEX_UNTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE; + + +struct DXUT_SCREEN_VERTEX_10 +{ + float x, y, z; + D3DCOLORVALUE color; + float tu, tv; +}; + + +inline int RectWidth( RECT& rc ) +{ + return ( ( rc ).right - ( rc ).left ); +} +inline int RectHeight( RECT& rc ) +{ + return ( ( rc ).bottom - ( rc ).top ); +} + + +HRESULT InitFont11( ID3D11Device* pd3d11Device, ID3D11InputLayout* pInputLayout ); +void EndFont11(); + +//-------------------------------------------------------------------------------------- +// CDXUTDialog class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTDialog::CDXUTDialog() +{ + m_x = 0; + m_y = 0; + m_width = 0; + m_height = 0; + + m_pManager = NULL; + m_bVisible = true; + m_bCaption = false; + m_bMinimized = false; + m_bDrag = false; + m_wszCaption[0] = L'\0'; + m_nCaptionHeight = 18; + + m_colorTopLeft = 0; + m_colorTopRight = 0; + m_colorBottomLeft = 0; + m_colorBottomRight = 0; + + m_pCallbackEvent = NULL; + m_pCallbackEventUserContext = NULL; + + m_fTimeLastRefresh = 0; + + m_pControlMouseOver = NULL; + + m_pNextDialog = this; + m_pPrevDialog = this; + + m_nDefaultControlID = 0xffff; + m_bNonUserEvents = false; + m_bKeyboardInput = false; + m_bMouseInput = true; +} + + +//-------------------------------------------------------------------------------------- +CDXUTDialog::~CDXUTDialog() +{ + int i = 0; + + RemoveAllControls(); + + m_Fonts.RemoveAll(); + m_Textures.RemoveAll(); + + for( i = 0; i < m_DefaultElements.GetSize(); i++ ) + { + DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); + SAFE_DELETE( pElementHolder ); + } + + m_DefaultElements.RemoveAll(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog ) +{ + m_pManager = pManager; + if( bRegisterDialog ) + pManager->RegisterDialog( this ); + + SetTexture( 0, MAKEINTRESOURCE( 0xFFFF ), ( HMODULE )0xFFFF ); + InitDefaultElements(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, LPCWSTR pszControlTextureFilename ) +{ + m_pManager = pManager; + if( bRegisterDialog ) + pManager->RegisterDialog( this ); + SetTexture( 0, pszControlTextureFilename ); + InitDefaultElements(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, + LPCWSTR szControlTextureResourceName, HMODULE hControlTextureResourceModule ) +{ + m_pManager = pManager; + if( bRegisterDialog ) + pManager->RegisterDialog( this ); + + SetTexture( 0, szControlTextureResourceName, hControlTextureResourceModule ); + InitDefaultElements(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::SetCallback( PCALLBACKDXUTGUIEVENT pCallback, void* pUserContext ) +{ + // If this assert triggers, you need to call CDXUTDialog::Init() first. This change + // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The + // creation and interfacing with CDXUTDialogResourceManager is now the responsibility + // of the application if it wishes to use DXUT's GUI. + assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first. See comments for details." ); + + m_pCallbackEvent = pCallback; + m_pCallbackEventUserContext = pUserContext; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::RemoveControl( int ID ) +{ + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + if( pControl->GetID() == ID ) + { + // Clean focus first + ClearFocus(); + + // Clear references to this control + if( s_pControlFocus == pControl ) + s_pControlFocus = NULL; + if( s_pControlPressed == pControl ) + s_pControlPressed = NULL; + if( m_pControlMouseOver == pControl ) + m_pControlMouseOver = NULL; + + SAFE_DELETE( pControl ); + m_Controls.Remove( i ); + + return; + } + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::RemoveAllControls() +{ + if( s_pControlFocus && s_pControlFocus->m_pDialog == this ) + s_pControlFocus = NULL; + if( s_pControlPressed && s_pControlPressed->m_pDialog == this ) + s_pControlPressed = NULL; + m_pControlMouseOver = NULL; + + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + SAFE_DELETE( pControl ); + } + + m_Controls.RemoveAll(); +} + + +//-------------------------------------------------------------------------------------- +CDXUTDialogResourceManager::CDXUTDialogResourceManager() +{ + // Begin D3D9-specific + m_pd3d9Device = NULL; + m_pStateBlock = NULL; + m_pSprite = NULL; + + // Begin D3D11-specific + // Shaders + m_pVSRenderUI11 = NULL; + m_pPSRenderUI11 = NULL; + m_pPSRenderUIUntex11 = NULL; + + // States + m_pDepthStencilStateUI11 = NULL; + m_pRasterizerStateUI11 = NULL; + m_pBlendStateUI11 = NULL; + m_pSamplerStateUI11 = NULL; + m_pDepthStencilStateStored11 = NULL; + m_pRasterizerStateStored11 = NULL; + m_pBlendStateStored11 = NULL; + m_pSamplerStateStored11 = NULL; + + m_pInputLayout11 = NULL; + m_pVBScreenQuad11 = NULL; + m_pSpriteBuffer11 = NULL; +} + + +//-------------------------------------------------------------------------------------- +CDXUTDialogResourceManager::~CDXUTDialogResourceManager() +{ + int i; + for( i = 0; i < m_FontCache.GetSize(); i++ ) + { + DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); + SAFE_DELETE( pFontNode ); + } + m_FontCache.RemoveAll(); + + for( i = 0; i < m_TextureCache.GetSize(); i++ ) + { + DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); + SAFE_DELETE( pTextureNode ); + } + m_TextureCache.RemoveAll(); + + CUniBuffer::Uninitialize(); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialogResourceManager::OnD3D9CreateDevice( LPDIRECT3DDEVICE9 pd3dDevice ) +{ + HRESULT hr = S_OK; + int i = 0; + + m_pd3d9Device = pd3dDevice; + + for( i = 0; i < m_FontCache.GetSize(); i++ ) + { + hr = CreateFont9( i ); + if( FAILED( hr ) ) + return hr; + } + + for( i = 0; i < m_TextureCache.GetSize(); i++ ) + { + hr = CreateTexture9( i ); + if( FAILED( hr ) ) + return hr; + } + + hr = D3DXCreateSprite( pd3dDevice, &m_pSprite ); + if( FAILED( hr ) ) + return DXUT_ERR( L"D3DXCreateSprite", hr ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialogResourceManager::OnD3D9ResetDevice() +{ + HRESULT hr = S_OK; + + for( int i = 0; i < m_FontCache.GetSize(); i++ ) + { + DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); + + if( pFontNode->pFont9 ) + pFontNode->pFont9->OnResetDevice(); + } + + if( m_pSprite ) + m_pSprite->OnResetDevice(); + + V_RETURN( m_pd3d9Device->CreateStateBlock( D3DSBT_ALL, &m_pStateBlock ) ); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +bool CDXUTDialogResourceManager::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::OnD3D9LostDevice() +{ + for( int i = 0; i < m_FontCache.GetSize(); i++ ) + { + DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); + + if( pFontNode->pFont9 ) + pFontNode->pFont9->OnLostDevice(); + } + + if( m_pSprite ) + m_pSprite->OnLostDevice(); + + SAFE_RELEASE( m_pStateBlock ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::OnD3D9DestroyDevice() +{ + int i = 0; + + m_pd3d9Device = NULL; + + // Release the resources but don't clear the cache, as these will need to be + // recreated if the device is recreated + for( i = 0; i < m_FontCache.GetSize(); i++ ) + { + DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); + SAFE_RELEASE( pFontNode->pFont9 ); + } + + for( i = 0; i < m_TextureCache.GetSize(); i++ ) + { + DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); + SAFE_RELEASE( pTextureNode->pTexture9 ); + } + + SAFE_RELEASE( m_pSprite ); +} + + + +HRESULT CDXUTDialogResourceManager::OnD3D11CreateDevice( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext ) +{ + m_pd3d11Device = pd3dDevice; + m_pd3d11DeviceContext = pd3d11DeviceContext; + + HRESULT hr = S_OK; + + // Compile Shaders + ID3DBlob* pVSBlob = NULL; + ID3DBlob* pPSBlob = NULL; + ID3DBlob* pPSUntexBlob = NULL; + V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "VS", "vs_4_0_level_9_1", + D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pVSBlob, NULL ) ); + V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "PS", "ps_4_0_level_9_1", + D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pPSBlob, NULL ) ); + V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "PSUntex", "ps_4_0_level_9_1", + D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pPSUntexBlob, NULL ) ); +//D3D10_SHADER_ENABLE_STRICTNESS + + // Create Shaders + V_RETURN( pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &m_pVSRenderUI11 ) ); + V_RETURN( pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &m_pPSRenderUI11 ) ); + V_RETURN( pd3dDevice->CreatePixelShader( pPSUntexBlob->GetBufferPointer(), pPSUntexBlob->GetBufferSize(), NULL, &m_pPSRenderUIUntex11 ) ); + + // States + D3D11_DEPTH_STENCIL_DESC DSDesc; + ZeroMemory( &DSDesc, sizeof( D3D11_DEPTH_STENCIL_DESC ) ); + DSDesc.DepthEnable = FALSE; + DSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + DSDesc.DepthFunc = D3D11_COMPARISON_LESS; + DSDesc.StencilEnable = FALSE; + V_RETURN( pd3dDevice->CreateDepthStencilState( &DSDesc, &m_pDepthStencilStateUI11 ) ); + + D3D11_RASTERIZER_DESC RSDesc; + RSDesc.AntialiasedLineEnable = FALSE; + RSDesc.CullMode = D3D11_CULL_BACK; + RSDesc.DepthBias = 0; + RSDesc.DepthBiasClamp = 0.0f; + RSDesc.DepthClipEnable = TRUE; + RSDesc.FillMode = D3D11_FILL_SOLID; + RSDesc.FrontCounterClockwise = FALSE; + RSDesc.MultisampleEnable = TRUE; + RSDesc.ScissorEnable = FALSE; + RSDesc.SlopeScaledDepthBias = 0.0f; + V_RETURN( pd3dDevice->CreateRasterizerState( &RSDesc, &m_pRasterizerStateUI11 ) ); + + D3D11_BLEND_DESC BSDesc; + ZeroMemory( &BSDesc, sizeof( D3D11_BLEND_DESC ) ); + + BSDesc.RenderTarget[0].BlendEnable = TRUE; + BSDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + BSDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + BSDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + BSDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + BSDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + BSDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + BSDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; + + V_RETURN( pd3dDevice->CreateBlendState( &BSDesc, &m_pBlendStateUI11 ) ); + + D3D11_SAMPLER_DESC SSDesc; + ZeroMemory( &SSDesc, sizeof( D3D11_SAMPLER_DESC ) ); + SSDesc.Filter = D3D11_FILTER_ANISOTROPIC ; + SSDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + SSDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + SSDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + SSDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + SSDesc.MaxAnisotropy = 16; + SSDesc.MinLOD = 0; + SSDesc.MaxLOD = D3D11_FLOAT32_MAX; + if ( pd3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3 ) { + SSDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + SSDesc.MaxAnisotropy = 0; + } + V_RETURN( pd3dDevice->CreateSamplerState( &SSDesc, &m_pSamplerStateUI11 ) ); + + // Create the font and texture objects in the cache arrays. + int i = 0; + for( i = 0; i < m_FontCache.GetSize(); i++ ) + { + hr = CreateFont11( i ); + if( FAILED( hr ) ) + return hr; + } + + for( i = 0; i < m_TextureCache.GetSize(); i++ ) + { + hr = CreateTexture11( i ); + if( FAILED( hr ) ) + return hr; + } + + // Create input layout + const D3D11_INPUT_ELEMENT_DESC layout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + V_RETURN( pd3dDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &m_pInputLayout11 ) ); + + // Release the blobs + SAFE_RELEASE( pVSBlob ); + SAFE_RELEASE( pPSBlob ); + SAFE_RELEASE( pPSUntexBlob ); + + // Create a vertex buffer quad for rendering later + D3D11_BUFFER_DESC BufDesc; + BufDesc.ByteWidth = sizeof( DXUT_SCREEN_VERTEX_10 ) * 4; + BufDesc.Usage = D3D11_USAGE_DYNAMIC; + BufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + BufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + BufDesc.MiscFlags = 0; + V_RETURN( pd3dDevice->CreateBuffer( &BufDesc, NULL, &m_pVBScreenQuad11 ) ); + + // Init the D3D11 font + InitFont11( pd3dDevice, m_pInputLayout11 ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialogResourceManager::OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, + const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc ) +{ + HRESULT hr = S_OK; + + m_nBackBufferWidth = pBackBufferSurfaceDesc->Width; + m_nBackBufferHeight = pBackBufferSurfaceDesc->Height; + + return hr; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::OnD3D11ReleasingSwapChain() +{ +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::OnD3D11DestroyDevice() +{ + int i; + + // Release the resources but don't clear the cache, as these will need to be + // recreated if the device is recreated + + for( i = 0; i < m_TextureCache.GetSize(); i++ ) + { + DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); + SAFE_RELEASE( pTextureNode->pTexResView11 ); + SAFE_RELEASE( pTextureNode->pTexture11 ); + } + + // D3D11 + SAFE_RELEASE( m_pVBScreenQuad11 ); + SAFE_RELEASE( m_pSpriteBuffer11 ); + m_SpriteBufferBytes11 = 0; + SAFE_RELEASE( m_pInputLayout11 ); + + // Shaders + SAFE_RELEASE( m_pVSRenderUI11 ); + SAFE_RELEASE( m_pPSRenderUI11 ); + SAFE_RELEASE( m_pPSRenderUIUntex11 ); + + // States + SAFE_RELEASE( m_pDepthStencilStateUI11 ); + SAFE_RELEASE( m_pRasterizerStateUI11 ); + SAFE_RELEASE( m_pBlendStateUI11 ); + SAFE_RELEASE( m_pSamplerStateUI11 ); + + SAFE_RELEASE( m_pDepthStencilStateStored11 ); + SAFE_RELEASE( m_pRasterizerStateStored11 ); + SAFE_RELEASE( m_pBlendStateStored11 ); + SAFE_RELEASE( m_pSamplerStateStored11 ); + + EndFont11(); +} + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::StoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext ) +{ + pd3dImmediateContext->OMGetDepthStencilState( &m_pDepthStencilStateStored11, &m_StencilRefStored11 ); + pd3dImmediateContext->RSGetState( &m_pRasterizerStateStored11 ); + pd3dImmediateContext->OMGetBlendState( &m_pBlendStateStored11, m_BlendFactorStored11, &m_SampleMaskStored11 ); + pd3dImmediateContext->PSGetSamplers( 0, 1, &m_pSamplerStateStored11 ); +} + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::RestoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext ) +{ + pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateStored11, m_StencilRefStored11 ); + pd3dImmediateContext->RSSetState( m_pRasterizerStateStored11 ); + pd3dImmediateContext->OMSetBlendState( m_pBlendStateStored11, m_BlendFactorStored11, m_SampleMaskStored11 ); + pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateStored11 ); + + SAFE_RELEASE( m_pDepthStencilStateStored11 ); + SAFE_RELEASE( m_pRasterizerStateStored11 ); + SAFE_RELEASE( m_pBlendStateStored11 ); + SAFE_RELEASE( m_pSamplerStateStored11 ); +} + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::ApplyRenderUI11( ID3D11DeviceContext* pd3dImmediateContext ) +{ + // Shaders + pd3dImmediateContext->VSSetShader( m_pVSRenderUI11, NULL, 0 ); + pd3dImmediateContext->HSSetShader( NULL, NULL, 0 ); + pd3dImmediateContext->DSSetShader( NULL, NULL, 0 ); + pd3dImmediateContext->GSSetShader( NULL, NULL, 0 ); + pd3dImmediateContext->PSSetShader( m_pPSRenderUI11, NULL, 0 ); + + // States + pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateUI11, 0 ); + pd3dImmediateContext->RSSetState( m_pRasterizerStateUI11 ); + float BlendFactor[4] = { 0, 0, 0, 0 }; + pd3dImmediateContext->OMSetBlendState( m_pBlendStateUI11, BlendFactor, 0xFFFFFFFF ); + pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateUI11 ); +} + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::ApplyRenderUIUntex11( ID3D11DeviceContext* pd3dImmediateContext ) +{ + // Shaders + pd3dImmediateContext->VSSetShader( m_pVSRenderUI11, NULL, 0 ); + pd3dImmediateContext->HSSetShader( NULL, NULL, 0 ); + pd3dImmediateContext->DSSetShader( NULL, NULL, 0 ); + pd3dImmediateContext->GSSetShader( NULL, NULL, 0 ); + pd3dImmediateContext->PSSetShader( m_pPSRenderUIUntex11, NULL, 0 ); + + // States + pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateUI11, 0 ); + pd3dImmediateContext->RSSetState( m_pRasterizerStateUI11 ); + float BlendFactor[4] = { 0, 0, 0, 0 }; + pd3dImmediateContext->OMSetBlendState( m_pBlendStateUI11, BlendFactor, 0xFFFFFFFF ); + pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateUI11 ); +} + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::BeginSprites11( ) +{ + m_SpriteVertices.Reset(); +} + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::EndSprites11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext ) +{ + + // ensure our buffer size can hold our sprites + UINT SpriteDataBytes = m_SpriteVertices.GetSize() * sizeof( DXUTSpriteVertex ); + if( m_SpriteBufferBytes11 < SpriteDataBytes ) + { + SAFE_RELEASE( m_pSpriteBuffer11 ); + m_SpriteBufferBytes11 = SpriteDataBytes; + + D3D11_BUFFER_DESC BufferDesc; + BufferDesc.ByteWidth = m_SpriteBufferBytes11; + BufferDesc.Usage = D3D11_USAGE_DYNAMIC; + BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + BufferDesc.MiscFlags = 0; + + pd3dDevice->CreateBuffer( &BufferDesc, NULL, &m_pSpriteBuffer11 ); + } + + // Copy the sprites over + D3D11_BOX destRegion; + destRegion.left = 0; + destRegion.right = SpriteDataBytes; + destRegion.top = 0; + destRegion.bottom = 1; + destRegion.front = 0; + destRegion.back = 1; + D3D11_MAPPED_SUBRESOURCE MappedResource; + if ( S_OK == pd3dImmediateContext->Map( m_pSpriteBuffer11, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) { + CopyMemory( MappedResource.pData, (void*)m_SpriteVertices.GetData(), SpriteDataBytes ); + pd3dImmediateContext->Unmap(m_pSpriteBuffer11, 0); + } + + // Draw + UINT Stride = sizeof( DXUTSpriteVertex ); + UINT Offset = 0; + pd3dImmediateContext->IASetVertexBuffers( 0, 1, &m_pSpriteBuffer11, &Stride, &Offset ); + pd3dImmediateContext->IASetInputLayout( m_pInputLayout11 ); + pd3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); + pd3dImmediateContext->Draw( m_SpriteVertices.GetSize(), 0 ); + + m_SpriteVertices.Reset(); +} + +//-------------------------------------------------------------------------------------- +bool CDXUTDialogResourceManager::RegisterDialog( CDXUTDialog* pDialog ) +{ + // Check that the dialog isn't already registered. + for( int i = 0; i < m_Dialogs.GetSize(); ++i ) + if( m_Dialogs.GetAt( i ) == pDialog ) + return true; + + // Add to the list. + if( FAILED( m_Dialogs.Add( pDialog ) ) ) + return false; + + // Set up next and prev pointers. + if( m_Dialogs.GetSize() > 1 ) + m_Dialogs[m_Dialogs.GetSize() - 2]->SetNextDialog( pDialog ); + m_Dialogs[m_Dialogs.GetSize() - 1]->SetNextDialog( m_Dialogs[0] ); + + return true; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::UnregisterDialog( CDXUTDialog* pDialog ) +{ + // Search for the dialog in the list. + for( int i = 0; i < m_Dialogs.GetSize(); ++i ) + if( m_Dialogs.GetAt( i ) == pDialog ) + { + m_Dialogs.Remove( i ); + if( m_Dialogs.GetSize() > 0 ) + { + int l, r; + + if( 0 == i ) + l = m_Dialogs.GetSize() - 1; + else + l = i - 1; + + if( m_Dialogs.GetSize() == i ) + r = 0; + else + r = i; + + m_Dialogs[l]->SetNextDialog( m_Dialogs[r] ); + } + return; + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialogResourceManager::EnableKeyboardInputForAllDialogs() +{ + // Enable keyboard input for all registered dialogs + for( int i = 0; i < m_Dialogs.GetSize(); ++i ) + m_Dialogs[i]->EnableKeyboardInput( true ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::Refresh() +{ + if( s_pControlFocus ) + s_pControlFocus->OnFocusOut(); + + if( m_pControlMouseOver ) + m_pControlMouseOver->OnMouseLeave(); + + s_pControlFocus = NULL; + s_pControlPressed = NULL; + m_pControlMouseOver = NULL; + + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + pControl->Refresh(); + } + + if( m_bKeyboardInput ) + FocusDefaultControl(); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::OnRender( float fElapsedTime ) +{ + if( m_pManager->GetD3D9Device() ) + return OnRender9( fElapsedTime ); + else + return OnRender11( fElapsedTime ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::OnRender9( float fElapsedTime ) +{ + // If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside + // the application's device callbacks. See the SDK samples for an example of how to do this. + assert( m_pManager->GetD3D9Device() && m_pManager->m_pStateBlock && + L"To fix hook up CDXUTDialogResourceManager to device callbacks. See comments for details" ); + + // See if the dialog needs to be refreshed + if( m_fTimeLastRefresh < s_fTimeRefresh ) + { + m_fTimeLastRefresh = DXUTGetTime(); + Refresh(); + } + + // For invisible dialog, out now. + if( !m_bVisible || + ( m_bMinimized && !m_bCaption ) ) + return S_OK; + + IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device(); + + // Set up a state block here and restore it when finished drawing all the controls + m_pManager->m_pStateBlock->Capture(); + + //pd3dDevice->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, TRUE); + //pd3dDevice->SetRenderState( D3DRS_SRGBWRITEENABLE, TRUE ); + + pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); + pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); + pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE ); + pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, FALSE ); + pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD ); + pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | + D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED ); + pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); + pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE ); + pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); + pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); + pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_RESULTARG, D3DTA_CURRENT ); + pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); + pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + BOOL bBackgroundIsVisible = ( m_colorTopLeft | m_colorTopRight | m_colorBottomRight | m_colorBottomLeft ) & + 0xff000000; + if( !m_bMinimized && bBackgroundIsVisible ) + { + DXUT_SCREEN_VERTEX_UNTEX vertices[4] = + { + ( float )m_x, ( float )m_y, 0.5f, 1.0f, m_colorTopLeft, + ( float )m_x + m_width, ( float )m_y, 0.5f, 1.0f, m_colorTopRight, + ( float )m_x + m_width, ( float )m_y + m_height, 0.5f, 1.0f, m_colorBottomRight, + ( float )m_x, ( float )m_y + m_height, 0.5f, 1.0f, m_colorBottomLeft, + }; + + pd3dDevice->SetVertexShader( NULL ); + pd3dDevice->SetPixelShader( NULL ); + + pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); + + pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX_UNTEX::FVF ); + pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof( DXUT_SCREEN_VERTEX_UNTEX ) ); + } + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + + pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); + + DXUTTextureNode* pTextureNode = GetTexture( 0 ); + pd3dDevice->SetTexture( 0, pTextureNode->pTexture9 ); + + m_pManager->m_pSprite->Begin( D3DXSPRITE_DONOTSAVESTATE ); + + // Render the caption if it's enabled. + if( m_bCaption ) + { + // DrawSprite will offset the rect down by + // m_nCaptionHeight, so adjust the rect higher + // here to negate the effect. + RECT rc = + { + 0, -m_nCaptionHeight, m_width, 0 + }; + DrawSprite9( &m_CapElement, &rc ); + rc.left += 5; // Make a left margin + WCHAR wszOutput[256]; + wcscpy_s( wszOutput, 256, m_wszCaption ); + if( m_bMinimized ) + wcscat_s( wszOutput, 256, L" (Minimized)" ); + DrawText9( wszOutput, &m_CapElement, &rc, true ); + } + + // If the dialog is minimized, skip rendering + // its controls. + if( !m_bMinimized ) + { + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + + // Focused control is drawn last + if( pControl == s_pControlFocus ) + continue; + + pControl->Render( fElapsedTime ); + } + + if( s_pControlFocus != NULL && s_pControlFocus->m_pDialog == this ) + s_pControlFocus->Render( fElapsedTime ); + } + + m_pManager->m_pSprite->End(); + + m_pManager->m_pStateBlock->Apply(); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::OnRender11( float fElapsedTime ) +{ + // If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside + // the application's device callbacks. See the SDK samples for an example of how to do this. + assert( m_pManager->GetD3D11Device() && + L"To fix hook up CDXUTDialogResourceManager to device callbacks. See comments for details" ); + + // See if the dialog needs to be refreshed + if( m_fTimeLastRefresh < s_fTimeRefresh ) + { + m_fTimeLastRefresh = DXUTGetTime(); + Refresh(); + } + + // For invisible dialog, out now. + if( !m_bVisible || + ( m_bMinimized && !m_bCaption ) ) + return S_OK; + + ID3D11Device* pd3dDevice = m_pManager->GetD3D11Device(); + ID3D11DeviceContext* pd3dDeviceContext = m_pManager->GetD3D11DeviceContext(); + + // Set up a state block here and restore it when finished drawing all the controls + m_pManager->StoreD3D11State( pd3dDeviceContext ); + + BOOL bBackgroundIsVisible = ( m_colorTopLeft | m_colorTopRight | m_colorBottomRight | m_colorBottomLeft ) & + 0xff000000; + if( !m_bMinimized && bBackgroundIsVisible ) + { + // Convert the draw rectangle from screen coordinates to clip space coordinates. + float Left, Right, Top, Bottom; + Left = m_x * 2.0f / m_pManager->m_nBackBufferWidth - 1.0f; + Right = ( m_x + m_width ) * 2.0f / m_pManager->m_nBackBufferWidth - 1.0f; + Top = 1.0f - m_y * 2.0f / m_pManager->m_nBackBufferHeight; + Bottom = 1.0f - ( m_y + m_height ) * 2.0f / m_pManager->m_nBackBufferHeight; + + DXUT_SCREEN_VERTEX_10 vertices[4] = + { + Left, Top, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorTopLeft ), 0.0f, 0.0f, + Right, Top, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorTopRight ), 1.0f, 0.0f, + Left, Bottom, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorBottomLeft ), 0.0f, 1.0f, + Right, Bottom, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorBottomRight ), 1.0f, 1.0f, + }; + + //DXUT_SCREEN_VERTEX_10 *pVB; + D3D11_MAPPED_SUBRESOURCE MappedData; + if( SUCCEEDED( pd3dDeviceContext->Map( m_pManager->m_pVBScreenQuad11, 0, D3D11_MAP_WRITE_DISCARD, + 0, &MappedData ) ) ) + { + CopyMemory( MappedData.pData, vertices, sizeof( vertices ) ); + pd3dDeviceContext->Unmap( m_pManager->m_pVBScreenQuad11, 0 ); + } + + // Set the quad VB as current + UINT stride = sizeof( DXUT_SCREEN_VERTEX_10 ); + UINT offset = 0; + pd3dDeviceContext->IASetVertexBuffers( 0, 1, &m_pManager->m_pVBScreenQuad11, &stride, &offset ); + pd3dDeviceContext->IASetInputLayout( m_pManager->m_pInputLayout11 ); + pd3dDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ); + + // Setup for rendering + m_pManager->ApplyRenderUIUntex11( pd3dDeviceContext ); + pd3dDeviceContext->Draw( 4, 0 ); + } + + DXUTTextureNode* pTextureNode = GetTexture( 0 ); + pd3dDeviceContext->PSSetShaderResources( 0, 1, &pTextureNode->pTexResView11 ); + + // Sort depth back to front + m_pManager->BeginSprites11(); + BeginText11(); + + m_pManager->ApplyRenderUI11( pd3dDeviceContext ); + + // Render the caption if it's enabled. + if( m_bCaption ) + { + // DrawSprite will offset the rect down by + // m_nCaptionHeight, so adjust the rect higher + // here to negate the effect. + RECT rc = { 0, -m_nCaptionHeight, m_width, 0 }; + DrawSprite11( &m_CapElement, &rc, 0.99f ); + rc.left += 5; // Make a left margin + WCHAR wszOutput[256]; + wcscpy_s( wszOutput, 256, m_wszCaption ); + if( m_bMinimized ) + wcscat_s( wszOutput, 256, L" (Minimized)" ); + DrawText11( pd3dDevice, pd3dDeviceContext, wszOutput, &m_CapElement, &rc, true ); + } + + // If the dialog is minimized, skip rendering + // its controls. + if( !m_bMinimized ) + { + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + + // Focused control is drawn last + if( pControl == s_pControlFocus ) + continue; + + pControl->Render( fElapsedTime ); + } + + if( s_pControlFocus != NULL && s_pControlFocus->m_pDialog == this ) + s_pControlFocus->Render( fElapsedTime ); + } + + // End sprites + if( m_bCaption ) + { + m_pManager->EndSprites11( pd3dDevice, pd3dDeviceContext ); + EndText11( pd3dDevice, pd3dDeviceContext ); + } + m_pManager->RestoreD3D11State( pd3dDeviceContext ); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +VOID CDXUTDialog::SendEvent( UINT nEvent, bool bTriggeredByUser, CDXUTControl* pControl ) +{ + // If no callback has been registered there's nowhere to send the event to + if( m_pCallbackEvent == NULL ) + return; + + // Discard events triggered programatically if these types of events haven't been + // enabled + if( !bTriggeredByUser && !m_bNonUserEvents ) + return; + + m_pCallbackEvent( nEvent, pControl->GetID(), pControl, m_pCallbackEventUserContext ); +} + + +//-------------------------------------------------------------------------------------- +int CDXUTDialogResourceManager::AddFont( LPCWSTR strFaceName, LONG height, LONG weight ) +{ + // See if this font already exists + for( int i = 0; i < m_FontCache.GetSize(); i++ ) + { + DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); + size_t nLen = 0; + nLen = wcsnlen( strFaceName, MAX_PATH); + if( 0 == _wcsnicmp( pFontNode->strFace, strFaceName, nLen ) && + pFontNode->nHeight == height && + pFontNode->nWeight == weight ) + { + return i; + } + } + + // Add a new font and try to create it + DXUTFontNode* pNewFontNode = new DXUTFontNode; + if( pNewFontNode == NULL ) + return -1; + + ZeroMemory( pNewFontNode, sizeof( DXUTFontNode ) ); + wcscpy_s( pNewFontNode->strFace, MAX_PATH, strFaceName ); + pNewFontNode->nHeight = height; + pNewFontNode->nWeight = weight; + m_FontCache.Add( pNewFontNode ); + + int iFont = m_FontCache.GetSize() - 1; + + // If a device is available, try to create immediately + if( m_pd3d9Device ) + CreateFont9( iFont ); + + return iFont; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::SetFont( UINT index, LPCWSTR strFaceName, LONG height, LONG weight ) +{ + // If this assert triggers, you need to call CDXUTDialog::Init() first. This change + // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The + // creation and interfacing with CDXUTDialogResourceManager is now the responsibility + // of the application if it wishes to use DXUT's GUI. + assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first. See comments for details." ); + + // Make sure the list is at least as large as the index being set + UINT i; + for( i = m_Fonts.GetSize(); i <= index; i++ ) + { + m_Fonts.Add( -1 ); + } + + int iFont = m_pManager->AddFont( strFaceName, height, weight ); + m_Fonts.SetAt( index, iFont ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +DXUTFontNode* CDXUTDialog::GetFont( UINT index ) +{ + if( NULL == m_pManager ) + return NULL; + return m_pManager->GetFontNode( m_Fonts.GetAt( index ) ); +} + + +//-------------------------------------------------------------------------------------- +int CDXUTDialogResourceManager::AddTexture( LPCWSTR strFilename ) +{ + // See if this texture already exists + for( int i = 0; i < m_TextureCache.GetSize(); i++ ) + { + DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); + size_t nLen = 0; + nLen = wcsnlen( strFilename, MAX_PATH); + if( pTextureNode->bFileSource && // Sources must match + 0 == _wcsnicmp( pTextureNode->strFilename, strFilename, nLen ) ) + { + return i; + } + } + + // Add a new texture and try to create it + DXUTTextureNode* pNewTextureNode = new DXUTTextureNode; + if( pNewTextureNode == NULL ) + return -1; + + ZeroMemory( pNewTextureNode, sizeof( DXUTTextureNode ) ); + pNewTextureNode->bFileSource = true; + wcscpy_s( pNewTextureNode->strFilename, MAX_PATH, strFilename ); + + m_TextureCache.Add( pNewTextureNode ); + + int iTexture = m_TextureCache.GetSize() - 1; + + // If a device is available, try to create immediately + if( m_pd3d9Device ) + CreateTexture9( iTexture ); + + return iTexture; +} + + +//-------------------------------------------------------------------------------------- +int CDXUTDialogResourceManager::AddTexture( LPCWSTR strResourceName, HMODULE hResourceModule ) +{ + // See if this texture already exists + for( int i = 0; i < m_TextureCache.GetSize(); i++ ) + { + DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); + if( !pTextureNode->bFileSource && // Sources must match + pTextureNode->hResourceModule == hResourceModule ) // Module handles must match + { + if( IS_INTRESOURCE( strResourceName ) ) + { + // Integer-based ID + if( ( INT_PTR )strResourceName == pTextureNode->nResourceID ) + return i; + } + else + { + // String-based ID + size_t nLen = 0; + nLen = wcsnlen ( strResourceName, MAX_PATH ); + if( 0 == _wcsnicmp( pTextureNode->strFilename, strResourceName, nLen ) ) + return i; + } + } + } + + // Add a new texture and try to create it + DXUTTextureNode* pNewTextureNode = new DXUTTextureNode; + if( pNewTextureNode == NULL ) + return -1; + + ZeroMemory( pNewTextureNode, sizeof( DXUTTextureNode ) ); + pNewTextureNode->hResourceModule = hResourceModule; + if( IS_INTRESOURCE( strResourceName ) ) + { + pNewTextureNode->nResourceID = ( int )( size_t )strResourceName; + } + else + { + pNewTextureNode->nResourceID = 0; + wcscpy_s( pNewTextureNode->strFilename, MAX_PATH, strResourceName ); + } + + m_TextureCache.Add( pNewTextureNode ); + + int iTexture = m_TextureCache.GetSize() - 1; + + // If a device is available, try to create immediately + if( m_pd3d9Device ) + CreateTexture9( iTexture ); + + return iTexture; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strFilename ) +{ + // If this assert triggers, you need to call CDXUTDialog::Init() first. This change + // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The + // creation and interfacing with CDXUTDialogResourceManager is now the responsibility + // of the application if it wishes to use DXUT's GUI. + assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first. See comments for details." ); + + // Make sure the list is at least as large as the index being set + for( UINT i = m_Textures.GetSize(); i <= index; i++ ) + { + m_Textures.Add( -1 ); + } + + int iTexture = m_pManager->AddTexture( strFilename ); + + m_Textures.SetAt( index, iTexture ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strResourceName, HMODULE hResourceModule ) +{ + // If this assert triggers, you need to call CDXUTDialog::Init() first. This change + // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The + // creation and interfacing with CDXUTDialogResourceManager is now the responsibility + // of the application if it wishes to use DXUT's GUI. + assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first. See comments for details." ); + + // Make sure the list is at least as large as the index being set + for( UINT i = m_Textures.GetSize(); i <= index; i++ ) + { + m_Textures.Add( -1 ); + } + + int iTexture = m_pManager->AddTexture( strResourceName, hResourceModule ); + + m_Textures.SetAt( index, iTexture ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +DXUTTextureNode* CDXUTDialog::GetTexture( UINT index ) +{ + if( NULL == m_pManager ) + return NULL; + return m_pManager->GetTextureNode( m_Textures.GetAt( index ) ); +} + + + +//-------------------------------------------------------------------------------------- +bool CDXUTDialog::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + bool bHandled = false; + + // For invisible dialog, do not handle anything. + if( !m_bVisible ) + return false; + + // If automation command-line switch is on, enable this dialog's keyboard input + // upon any key press or mouse click. + if( DXUTGetAutomation() && + ( WM_LBUTTONDOWN == uMsg || WM_LBUTTONDBLCLK == uMsg || WM_KEYDOWN == uMsg ) ) + { + m_pManager->EnableKeyboardInputForAllDialogs(); + } + + // If caption is enable, check for clicks in the caption area. + if( m_bCaption ) + { + if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) + { + POINT mousePoint = + { + short( LOWORD( lParam ) ), short( HIWORD( lParam ) ) + }; + + if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width && + mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight ) + { + m_bDrag = true; + SetCapture( DXUTGetHWND() ); + return true; + } + } + else if( uMsg == WM_LBUTTONUP && m_bDrag ) + { + POINT mousePoint = + { + short( LOWORD( lParam ) ), short( HIWORD( lParam ) ) + }; + + if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width && + mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight ) + { + ReleaseCapture(); + m_bDrag = false; + m_bMinimized = !m_bMinimized; + return true; + } + } + } + + // If the dialog is minimized, don't send any messages to controls. + if( m_bMinimized ) + return false; + + // If a control is in focus, it belongs to this dialog, and it's enabled, then give + // it the first chance at handling the message. + if( s_pControlFocus && + s_pControlFocus->m_pDialog == this && + s_pControlFocus->GetEnabled() ) + { + // If the control MsgProc handles it, then we don't. + if( s_pControlFocus->MsgProc( uMsg, wParam, lParam ) ) + return true; + } + + switch( uMsg ) + { + case WM_SIZE: + case WM_MOVE: + { + // Handle sizing and moving messages so that in case the mouse cursor is moved out + // of an UI control because of the window adjustment, we can properly + // unhighlight the highlighted control. + POINT pt = + { + -1, -1 + }; + OnMouseMove( pt ); + break; + } + + case WM_ACTIVATEAPP: + // Call OnFocusIn()/OnFocusOut() of the control that currently has the focus + // as the application is activated/deactivated. This matches the Windows + // behavior. + if( s_pControlFocus && + s_pControlFocus->m_pDialog == this && + s_pControlFocus->GetEnabled() ) + { + if( wParam ) + s_pControlFocus->OnFocusIn(); + else + s_pControlFocus->OnFocusOut(); + } + break; + + // Keyboard messages + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + { + // If a control is in focus, it belongs to this dialog, and it's enabled, then give + // it the first chance at handling the message. + if( s_pControlFocus && + s_pControlFocus->m_pDialog == this && + s_pControlFocus->GetEnabled() ) + { + if( s_pControlFocus->HandleKeyboard( uMsg, wParam, lParam ) ) + return true; + } + + // Not yet handled, see if this matches a control's hotkey + // Activate the hotkey if the focus doesn't belong to an + // edit box. + if( uMsg == WM_KEYDOWN && ( !s_pControlFocus || + ( s_pControlFocus->GetType() != DXUT_CONTROL_EDITBOX + && s_pControlFocus->GetType() != DXUT_CONTROL_IMEEDITBOX ) ) ) + { + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + if( pControl->GetHotkey() == wParam ) + { + pControl->OnHotkey(); + return true; + } + } + } + + // Not yet handled, check for focus messages + if( uMsg == WM_KEYDOWN ) + { + // If keyboard input is not enabled, this message should be ignored + if( !m_bKeyboardInput ) + return false; + + switch( wParam ) + { + case VK_RIGHT: + case VK_DOWN: + if( s_pControlFocus != NULL ) + { + return OnCycleFocus( true ); + } + break; + + case VK_LEFT: + case VK_UP: + if( s_pControlFocus != NULL ) + { + return OnCycleFocus( false ); + } + break; + + case VK_TAB: + { + bool bShiftDown = ( ( GetKeyState( VK_SHIFT ) & 0x8000 ) != 0 ); + return OnCycleFocus( !bShiftDown ); + } + } + } + + break; + } + + + // Mouse messages + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_XBUTTONDBLCLK: + case WM_MOUSEWHEEL: + { + // If not accepting mouse input, return false to indicate the message should still + // be handled by the application (usually to move the camera). + if( !m_bMouseInput ) + return false; + + POINT mousePoint = + { + short( LOWORD( lParam ) ), short( HIWORD( lParam ) ) + }; + mousePoint.x -= m_x; + mousePoint.y -= m_y; + + // If caption is enabled, offset the Y coordinate by the negative of its height. + if( m_bCaption ) + mousePoint.y -= m_nCaptionHeight; + + // If a control is in focus, it belongs to this dialog, and it's enabled, then give + // it the first chance at handling the message. + if( s_pControlFocus && + s_pControlFocus->m_pDialog == this && + s_pControlFocus->GetEnabled() ) + { + if( s_pControlFocus->HandleMouse( uMsg, mousePoint, wParam, lParam ) ) + return true; + } + + // Not yet handled, see if the mouse is over any controls + CDXUTControl* pControl = GetControlAtPoint( mousePoint ); + if( pControl != NULL && pControl->GetEnabled() ) + { + bHandled = pControl->HandleMouse( uMsg, mousePoint, wParam, lParam ); + if( bHandled ) + return true; + } + else + { + // Mouse not over any controls in this dialog, if there was a control + // which had focus it just lost it + if( uMsg == WM_LBUTTONDOWN && + s_pControlFocus && + s_pControlFocus->m_pDialog == this ) + { + s_pControlFocus->OnFocusOut(); + s_pControlFocus = NULL; + } + } + + // Still not handled, hand this off to the dialog. Return false to indicate the + // message should still be handled by the application (usually to move the camera). + switch( uMsg ) + { + case WM_MOUSEMOVE: + OnMouseMove( mousePoint ); + return false; + } + + break; + } + + case WM_CAPTURECHANGED: + { + // The application has lost mouse capture. + // The dialog object may not have received + // a WM_MOUSEUP when capture changed. Reset + // m_bDrag so that the dialog does not mistakenly + // think the mouse button is still held down. + if( ( HWND )lParam != hWnd ) + m_bDrag = false; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------- +CDXUTControl* CDXUTDialog::GetControlAtPoint( POINT pt ) +{ + // Search through all child controls for the first one which + // contains the mouse point + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + + if( pControl == NULL ) + { + continue; + } + + // We only return the current control if it is visible + // and enabled. Because GetControlAtPoint() is used to do mouse + // hittest, it makes sense to perform this filtering. + if( pControl->ContainsPoint( pt ) && pControl->GetEnabled() && pControl->GetVisible() ) + { + return pControl; + } + } + + return NULL; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTDialog::GetControlEnabled( int ID ) +{ + CDXUTControl* pControl = GetControl( ID ); + if( pControl == NULL ) + return false; + + return pControl->GetEnabled(); +} + + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::SetControlEnabled( int ID, bool bEnabled ) +{ + CDXUTControl* pControl = GetControl( ID ); + if( pControl == NULL ) + return; + + pControl->SetEnabled( bEnabled ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::OnMouseUp( POINT pt ) +{ + s_pControlPressed = NULL; + m_pControlMouseOver = NULL; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::OnMouseMove( POINT pt ) +{ + // Figure out which control the mouse is over now + CDXUTControl* pControl = GetControlAtPoint( pt ); + + // If the mouse is still over the same control, nothing needs to be done + if( pControl == m_pControlMouseOver ) + return; + + // Handle mouse leaving the old control + if( m_pControlMouseOver ) + m_pControlMouseOver->OnMouseLeave(); + + // Handle mouse entering the new control + m_pControlMouseOver = pControl; + if( pControl != NULL ) + m_pControlMouseOver->OnMouseEnter(); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::SetDefaultElement( UINT nControlType, UINT iElement, CDXUTElement* pElement ) +{ + // If this Element type already exist in the list, simply update the stored Element + for( int i = 0; i < m_DefaultElements.GetSize(); i++ ) + { + DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); + + if( pElementHolder->nControlType == nControlType && + pElementHolder->iElement == iElement ) + { + pElementHolder->Element = *pElement; + return S_OK; + } + } + + // Otherwise, add a new entry + DXUTElementHolder* pNewHolder; + pNewHolder = new DXUTElementHolder; + if( pNewHolder == NULL ) + return E_OUTOFMEMORY; + + pNewHolder->nControlType = nControlType; + pNewHolder->iElement = iElement; + pNewHolder->Element = *pElement; + + HRESULT hr = m_DefaultElements.Add( pNewHolder ); + if( FAILED( hr ) ) + { + delete pNewHolder; + } + return hr; +} + + +//-------------------------------------------------------------------------------------- +CDXUTElement* CDXUTDialog::GetDefaultElement( UINT nControlType, UINT iElement ) +{ + for( int i = 0; i < m_DefaultElements.GetSize(); i++ ) + { + DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); + + if( pElementHolder->nControlType == nControlType && + pElementHolder->iElement == iElement ) + { + return &pElementHolder->Element; + } + } + + return NULL; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddStatic( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, + CDXUTStatic** ppCreated ) +{ + HRESULT hr = S_OK; + + CDXUTStatic* pStatic = new CDXUTStatic( this ); + + if( ppCreated != NULL ) + *ppCreated = pStatic; + + if( pStatic == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pStatic ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and list index + pStatic->SetID( ID ); + pStatic->SetText( strText ); + pStatic->SetLocation( x, y ); + pStatic->SetSize( width, height ); + pStatic->m_bIsDefault = bIsDefault; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddButton( int ID, LPCWSTR strText, int x, int y, int width, int height, UINT nHotkey, + bool bIsDefault, CDXUTButton** ppCreated ) +{ + HRESULT hr = S_OK; + + CDXUTButton* pButton = new CDXUTButton( this ); + + if( ppCreated != NULL ) + *ppCreated = pButton; + + if( pButton == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pButton ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and list index + pButton->SetID( ID ); + pButton->SetText( strText ); + pButton->SetLocation( x, y ); + pButton->SetSize( width, height ); + pButton->SetHotkey( nHotkey ); + pButton->m_bIsDefault = bIsDefault; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddCheckBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bChecked, + UINT nHotkey, bool bIsDefault, CDXUTCheckBox** ppCreated ) +{ + HRESULT hr = S_OK; + + CDXUTCheckBox* pCheckBox = new CDXUTCheckBox( this ); + + if( ppCreated != NULL ) + *ppCreated = pCheckBox; + + if( pCheckBox == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pCheckBox ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and list index + pCheckBox->SetID( ID ); + pCheckBox->SetText( strText ); + pCheckBox->SetLocation( x, y ); + pCheckBox->SetSize( width, height ); + pCheckBox->SetHotkey( nHotkey ); + pCheckBox->m_bIsDefault = bIsDefault; + pCheckBox->SetChecked( bChecked ); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddRadioButton( int ID, UINT nButtonGroup, LPCWSTR strText, int x, int y, int width, int height, + bool bChecked, UINT nHotkey, bool bIsDefault, CDXUTRadioButton** ppCreated ) +{ + HRESULT hr = S_OK; + + CDXUTRadioButton* pRadioButton = new CDXUTRadioButton( this ); + + if( ppCreated != NULL ) + *ppCreated = pRadioButton; + + if( pRadioButton == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pRadioButton ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and list index + pRadioButton->SetID( ID ); + pRadioButton->SetText( strText ); + pRadioButton->SetButtonGroup( nButtonGroup ); + pRadioButton->SetLocation( x, y ); + pRadioButton->SetSize( width, height ); + pRadioButton->SetHotkey( nHotkey ); + pRadioButton->SetChecked( bChecked ); + pRadioButton->m_bIsDefault = bIsDefault; + pRadioButton->SetChecked( bChecked ); + + return S_OK; +} + + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddComboBox( int ID, int x, int y, int width, int height, UINT nHotkey, bool bIsDefault, + CDXUTComboBox** ppCreated ) +{ + HRESULT hr = S_OK; + + CDXUTComboBox* pComboBox = new CDXUTComboBox( this ); + + if( ppCreated != NULL ) + *ppCreated = pComboBox; + + if( pComboBox == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pComboBox ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and list index + pComboBox->SetID( ID ); + pComboBox->SetLocation( x, y ); + pComboBox->SetSize( width, height ); + pComboBox->SetHotkey( nHotkey ); + pComboBox->m_bIsDefault = bIsDefault; + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddSlider( int ID, int x, int y, int width, int height, int min, int max, int value, + bool bIsDefault, CDXUTSlider** ppCreated ) +{ + HRESULT hr = S_OK; + + CDXUTSlider* pSlider = new CDXUTSlider( this ); + + if( ppCreated != NULL ) + *ppCreated = pSlider; + + if( pSlider == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pSlider ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and list index + pSlider->SetID( ID ); + pSlider->SetLocation( x, y ); + pSlider->SetSize( width, height ); + pSlider->m_bIsDefault = bIsDefault; + pSlider->SetRange( min, max ); + pSlider->SetValue( value ); + pSlider->UpdateRects(); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddEditBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, + CDXUTEditBox** ppCreated ) +{ + HRESULT hr = S_OK; + + CDXUTEditBox* pEditBox = new CDXUTEditBox( this ); + + if( ppCreated != NULL ) + *ppCreated = pEditBox; + + if( pEditBox == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pEditBox ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and position + pEditBox->SetID( ID ); + pEditBox->SetLocation( x, y ); + pEditBox->SetSize( width, height ); + pEditBox->m_bIsDefault = bIsDefault; + + if( strText ) + pEditBox->SetText( strText ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddListBox( int ID, int x, int y, int width, int height, DWORD dwStyle, CDXUTListBox** ppCreated ) +{ + HRESULT hr = S_OK; + CDXUTListBox* pListBox = new CDXUTListBox( this ); + + if( ppCreated != NULL ) + *ppCreated = pListBox; + + if( pListBox == NULL ) + return E_OUTOFMEMORY; + + hr = AddControl( pListBox ); + if( FAILED( hr ) ) + return hr; + + // Set the ID and position + pListBox->SetID( ID ); + pListBox->SetLocation( x, y ); + pListBox->SetSize( width, height ); + pListBox->SetStyle( dwStyle ); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::InitControl( CDXUTControl* pControl ) +{ + HRESULT hr; + + if( pControl == NULL ) + return E_INVALIDARG; + + pControl->m_Index = m_Controls.GetSize(); + + // Look for a default Element entries + for( int i = 0; i < m_DefaultElements.GetSize(); i++ ) + { + DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); + if( pElementHolder->nControlType == pControl->GetType() ) + pControl->SetElement( pElementHolder->iElement, &pElementHolder->Element ); + } + + V_RETURN( pControl->OnInit() ); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::AddControl( CDXUTControl* pControl ) +{ + HRESULT hr = S_OK; + + hr = InitControl( pControl ); + if( FAILED( hr ) ) + return DXTRACE_ERR( L"CDXUTDialog::InitControl", hr ); + + // Add to the list + hr = m_Controls.Add( pControl ); + if( FAILED( hr ) ) + { + return DXTRACE_ERR( L"CGrowableArray::Add", hr ); + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +CDXUTControl* CDXUTDialog::GetControl( int ID ) +{ + // Try to find the control with the given ID + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + + if( pControl->GetID() == ID ) + { + return pControl; + } + } + + // Not found + return NULL; +} + + + +//-------------------------------------------------------------------------------------- +CDXUTControl* CDXUTDialog::GetControl( int ID, UINT nControlType ) +{ + // Try to find the control with the given ID + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + + if( pControl->GetID() == ID && pControl->GetType() == nControlType ) + { + return pControl; + } + } + + // Not found + return NULL; +} + + + +//-------------------------------------------------------------------------------------- +CDXUTControl* CDXUTDialog::GetNextControl( CDXUTControl* pControl ) +{ + int index = pControl->m_Index + 1; + + CDXUTDialog* pDialog = pControl->m_pDialog; + + // Cycle through dialogs in the loop to find the next control. Note + // that if only one control exists in all looped dialogs it will + // be the returned 'next' control. + while( index >= ( int )pDialog->m_Controls.GetSize() ) + { + pDialog = pDialog->m_pNextDialog; + index = 0; + } + + return pDialog->m_Controls.GetAt( index ); +} + +//-------------------------------------------------------------------------------------- +CDXUTControl* CDXUTDialog::GetPrevControl( CDXUTControl* pControl ) +{ + int index = pControl->m_Index - 1; + + CDXUTDialog* pDialog = pControl->m_pDialog; + + // Cycle through dialogs in the loop to find the next control. Note + // that if only one control exists in all looped dialogs it will + // be the returned 'previous' control. + while( index < 0 ) + { + pDialog = pDialog->m_pPrevDialog; + if( pDialog == NULL ) + pDialog = pControl->m_pDialog; + + index = pDialog->m_Controls.GetSize() - 1; + } + + return pDialog->m_Controls.GetAt( index ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::ClearRadioButtonGroup( UINT nButtonGroup ) +{ + // Find all radio buttons with the given group number + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + + if( pControl->GetType() == DXUT_CONTROL_RADIOBUTTON ) + { + CDXUTRadioButton* pRadioButton = ( CDXUTRadioButton* )pControl; + + if( pRadioButton->GetButtonGroup() == nButtonGroup ) + pRadioButton->SetChecked( false, false ); + } + } +} + + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::ClearComboBox( int ID ) +{ + CDXUTComboBox* pComboBox = GetComboBox( ID ); + if( pComboBox == NULL ) + return; + + pComboBox->RemoveAllItems(); +} + + + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::RequestFocus( CDXUTControl* pControl ) +{ + if( s_pControlFocus == pControl ) + return; + + if( !pControl->CanHaveFocus() ) + return; + + if( s_pControlFocus ) + s_pControlFocus->OnFocusOut(); + + pControl->OnFocusIn(); + s_pControlFocus = pControl; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawRect( RECT* pRect, D3DCOLOR color ) +{ + if( m_pManager->GetD3D9Device() ) + return DrawRect9( pRect, color ); + return E_FAIL; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawRect9( RECT* pRect, D3DCOLOR color ) +{ + RECT rcScreen = *pRect; + OffsetRect( &rcScreen, m_x, m_y ); + + // If caption is enabled, offset the Y position by its height. + if( m_bCaption ) + OffsetRect( &rcScreen, 0, m_nCaptionHeight ); + + DXUT_SCREEN_VERTEX vertices[4] = + { + ( float )rcScreen.left - 0.5f, ( float )rcScreen.top - 0.5f, 0.5f, 1.0f, color, 0, 0, + ( float )rcScreen.right - 0.5f, ( float )rcScreen.top - 0.5f, 0.5f, 1.0f, color, 0, 0, + ( float )rcScreen.right - 0.5f, ( float )rcScreen.bottom - 0.5f, 0.5f, 1.0f, color, 0, 0, + ( float )rcScreen.left - 0.5f, ( float )rcScreen.bottom - 0.5f, 0.5f, 1.0f, color, 0, 0, + }; + + IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device(); + + // Since we're doing our own drawing here we need to flush the sprites + m_pManager->m_pSprite->Flush(); + IDirect3DVertexDeclaration9* pDecl = NULL; + pd3dDevice->GetVertexDeclaration( &pDecl ); // Preserve the sprite's current vertex decl + pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); + + pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof( DXUT_SCREEN_VERTEX ) ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + + // Restore the vertex decl + pd3dDevice->SetVertexDeclaration( pDecl ); + pDecl->Release(); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawPolyLine( POINT* apPoints, UINT nNumPoints, D3DCOLOR color ) +{ + DXUT_SCREEN_VERTEX* vertices = new DXUT_SCREEN_VERTEX[ nNumPoints ]; + if( vertices == NULL ) + return E_OUTOFMEMORY; + + DXUT_SCREEN_VERTEX* pVertex = vertices; + POINT* pt = apPoints; + for( UINT i = 0; i < nNumPoints; i++ ) + { + pVertex->x = m_x + ( float )pt->x; + pVertex->y = m_y + ( float )pt->y; + pVertex->z = 0.5f; + pVertex->h = 1.0f; + pVertex->color = color; + pVertex->tu = 0.0f; + pVertex->tv = 0.0f; + + pVertex++; + pt++; + } + + IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device(); + + // Since we're doing our own drawing here we need to flush the sprites + m_pManager->m_pSprite->Flush(); + IDirect3DVertexDeclaration9* pDecl = NULL; + pd3dDevice->GetVertexDeclaration( &pDecl ); // Preserve the sprite's current vertex decl + pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); + + pd3dDevice->DrawPrimitiveUP( D3DPT_LINESTRIP, nNumPoints - 1, vertices, sizeof( DXUT_SCREEN_VERTEX ) ); + + pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + + // Restore the vertex decl + pd3dDevice->SetVertexDeclaration( pDecl ); + pDecl->Release(); + + SAFE_DELETE_ARRAY( vertices ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawSprite( CDXUTElement* pElement, RECT* prcDest, float fDepth ) +{ + if( m_pManager->GetD3D9Device() ) + return DrawSprite9( pElement, prcDest ); + else + return DrawSprite11( pElement, prcDest, fDepth ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawSprite9( CDXUTElement* pElement, RECT* prcDest ) +{ + // No need to draw fully transparent layers + if( pElement->TextureColor.Current.a == 0 ) + return S_OK; + + RECT rcTexture = pElement->rcTexture; + + RECT rcScreen = *prcDest; + OffsetRect( &rcScreen, m_x, m_y ); + + // If caption is enabled, offset the Y position by its height. + if( m_bCaption ) + OffsetRect( &rcScreen, 0, m_nCaptionHeight ); + + DXUTTextureNode* pTextureNode = GetTexture( pElement->iTexture ); + if( pTextureNode == NULL ) + return E_FAIL; + + float fScaleX = ( float )RectWidth( rcScreen ) / RectWidth( rcTexture ); + float fScaleY = ( float )RectHeight( rcScreen ) / RectHeight( rcTexture ); + + D3DXMATRIXA16 matTransform; + D3DXMatrixScaling( &matTransform, fScaleX, fScaleY, 1.0f ); + + m_pManager->m_pSprite->SetTransform( &matTransform ); + + D3DXVECTOR3 vPos( ( float )rcScreen.left, ( float )rcScreen.top, 0.0f ); + + vPos.x /= fScaleX; + vPos.y /= fScaleY; + + return m_pManager->m_pSprite->Draw( pTextureNode->pTexture9, &rcTexture, NULL, &vPos, + pElement->TextureColor.Current ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawSprite11( CDXUTElement* pElement, RECT* prcDest, float fDepth ) +{ + // No need to draw fully transparent layers + if( pElement->TextureColor.Current.a == 0 ) + return S_OK; + + RECT rcTexture = pElement->rcTexture; + + RECT rcScreen = *prcDest; + OffsetRect( &rcScreen, m_x, m_y ); + + // If caption is enabled, offset the Y position by its height. + if( m_bCaption ) + OffsetRect( &rcScreen, 0, m_nCaptionHeight ); + + DXUTTextureNode* pTextureNode = GetTexture( pElement->iTexture ); + if( pTextureNode == NULL ) + return E_FAIL; + + float fBBWidth = ( float )m_pManager->m_nBackBufferWidth; + float fBBHeight = ( float )m_pManager->m_nBackBufferHeight; + float fTexWidth = ( float )pTextureNode->dwWidth; + float fTexHeight = ( float )pTextureNode->dwHeight; + + float fRectLeft = rcScreen.left / fBBWidth; + float fRectTop = 1.0f - rcScreen.top / fBBHeight; + float fRectRight = rcScreen.right / fBBWidth; + float fRectBottom = 1.0f - rcScreen.bottom / fBBHeight; + + fRectLeft = fRectLeft * 2.0f - 1.0f; + fRectTop = fRectTop * 2.0f - 1.0f; + fRectRight = fRectRight * 2.0f - 1.0f; + fRectBottom = fRectBottom * 2.0f - 1.0f; + + float fTexLeft = rcTexture.left / fTexWidth; + float fTexTop = rcTexture.top / fTexHeight; + float fTexRight = rcTexture.right / fTexWidth; + float fTexBottom = rcTexture.bottom / fTexHeight; + + // Add 6 sprite vertices + DXUTSpriteVertex SpriteVertex; + + // tri1 + SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectTop, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexTop ); + SpriteVertex.vColor = pElement->TextureColor.Current; + m_pManager->m_SpriteVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); + SpriteVertex.vColor = pElement->TextureColor.Current; + m_pManager->m_SpriteVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); + SpriteVertex.vColor = pElement->TextureColor.Current; + m_pManager->m_SpriteVertices.Add( SpriteVertex ); + + // tri2 + SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); + SpriteVertex.vColor = pElement->TextureColor.Current; + m_pManager->m_SpriteVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectBottom, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexBottom ); + SpriteVertex.vColor = pElement->TextureColor.Current; + m_pManager->m_SpriteVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); + SpriteVertex.vColor = pElement->TextureColor.Current; + m_pManager->m_SpriteVertices.Add( SpriteVertex ); + + // TODO: Why are we drawing the sprite every time? This is very inefficient, but the sprite workaround doesn't have support for sorting now, so we have to + // draw a sprite every time to keep the order correct between sprites and text. + m_pManager->EndSprites11( DXUTGetD3D11Device(), DXUTGetD3D11DeviceContext() ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::CalcTextRect( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, int nCount ) +{ + HRESULT hr = S_OK; + + DXUTFontNode* pFontNode = GetFont( pElement->iFont ); + if( pFontNode == NULL ) + return E_FAIL; + + DWORD dwTextFormat = pElement->dwTextFormat | DT_CALCRECT; + // Since we are only computing the rectangle, we don't need a sprite. + if( pFontNode->pFont9 ) + { + hr = pFontNode->pFont9->DrawText( NULL, strText, nCount, prcDest, dwTextFormat, pElement->FontColor.Current ); + if( FAILED( hr ) ) + return hr; + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawText( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount, bool bCenter ) +{ + if( m_pManager->GetD3D9Device() ) + return DrawText9( strText, pElement, prcDest, bShadow, nCount ); + else + return DrawText11( m_pManager->GetD3D11Device(), m_pManager->GetD3D11DeviceContext(), strText, pElement, prcDest, bShadow, nCount, bCenter ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawText9( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount ) +{ + HRESULT hr = S_OK; + + // No need to draw fully transparent layers + if( pElement->FontColor.Current.a == 0 ) + return S_OK; + + RECT rcScreen = *prcDest; + OffsetRect( &rcScreen, m_x, m_y ); + + // If caption is enabled, offset the Y position by its height. + if( m_bCaption ) + OffsetRect( &rcScreen, 0, m_nCaptionHeight ); + + D3DXMATRIX matTransform; + D3DXMatrixIdentity( &matTransform ); + m_pManager->m_pSprite->SetTransform( &matTransform ); + + DXUTFontNode* pFontNode = GetFont( pElement->iFont ); + + if( bShadow ) + { + RECT rcShadow = rcScreen; + OffsetRect( &rcShadow, 1, 1 ); + hr = pFontNode->pFont9->DrawText( m_pManager->m_pSprite, strText, nCount, &rcShadow, pElement->dwTextFormat, + D3DCOLOR_ARGB( DWORD( pElement->FontColor.Current.a * 255 ), 0, 0, 0 ) ); + if( FAILED( hr ) ) + return hr; + } + + hr = pFontNode->pFont9->DrawText( m_pManager->m_pSprite, strText, nCount, &rcScreen, pElement->dwTextFormat, + pElement->FontColor.Current ); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + +ID3D11Buffer* g_pFontBuffer11 = NULL; +UINT g_FontBufferBytes11 = 0; +CGrowableArray g_FontVertices; +ID3D11ShaderResourceView* g_pFont11 = NULL; +ID3D11InputLayout* g_pInputLayout11 = NULL; +HRESULT InitFont11( ID3D11Device* pd3d11Device, ID3D11InputLayout* pInputLayout ) +{ + HRESULT hr = S_OK; + WCHAR str[MAX_PATH]; + V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"UI\\Font.dds" ) ); + + if (pd3d11Device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0 ) { + + D3DX11_IMAGE_INFO dii; + D3DX11GetImageInfoFromFile( str, NULL, &dii, NULL ); + + D3DX11_IMAGE_LOAD_INFO dili; + dili.BindFlags = D3DX11_DEFAULT; + dili.CpuAccessFlags = D3DX11_DEFAULT; + dili.Depth = D3DX11_DEFAULT; + dili.Filter = D3DX11_DEFAULT; + dili.FirstMipLevel = 0; + dili.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dili.Height = D3DX11_DEFAULT; + dili.MipFilter = D3DX11_DEFAULT; + dili.MipLevels = 1; + dili.MiscFlags = D3DX11_DEFAULT; + dili.pSrcInfo = &dii; + dili.Usage = D3D11_USAGE_DEFAULT ; + dili.Width = D3DX11_DEFAULT; + + V_RETURN( D3DX11CreateShaderResourceViewFromFile( pd3d11Device, str, &dili, NULL, &g_pFont11, &hr) ); + } else { + V_RETURN( D3DX11CreateShaderResourceViewFromFile( pd3d11Device, str, NULL, NULL, &g_pFont11, &hr) ); + + } + + + g_pInputLayout11 = pInputLayout; + return hr; +} + +void EndFont11() +{ + SAFE_RELEASE( g_pFontBuffer11 ); + g_FontBufferBytes11 = 0; + SAFE_RELEASE( g_pFont11 ); +} + +void BeginText11() +{ + g_FontVertices.Reset(); +} + +void DrawText11DXUT( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext, + LPCWSTR strText, RECT rcScreen, D3DXCOLOR vFontColor, + float fBBWidth, float fBBHeight, bool bCenter ) +{ + float fCharTexSizeX = 0.010526315f; + //float fGlyphSizeX = 14.0f / fBBWidth; + //float fGlyphSizeY = 32.0f / fBBHeight; + float fGlyphSizeX = 15.0f / fBBWidth; + float fGlyphSizeY = 42.0f / fBBHeight; + + + float fRectLeft = rcScreen.left / fBBWidth; + float fRectTop = 1.0f - rcScreen.top / fBBHeight; + + fRectLeft = fRectLeft * 2.0f - 1.0f; + fRectTop = fRectTop * 2.0f - 1.0f; + + int NumChars = (int)wcslen( strText ); + if (bCenter) { + float fRectRight = rcScreen.right / fBBWidth; + fRectRight = fRectRight * 2.0f - 1.0f; + float fRectBottom = 1.0f - rcScreen.bottom / fBBHeight; + fRectBottom = fRectBottom * 2.0f - 1.0f; + float fcenterx = ((fRectRight - fRectLeft) - (float)NumChars*fGlyphSizeX) *0.5f; + float fcentery = ((fRectTop - fRectBottom) - (float)1*fGlyphSizeY) *0.5f; + fRectLeft += fcenterx ; + fRectTop -= fcentery; + } + float fOriginalLeft = fRectLeft; + float fTexTop = 0.0f; + float fTexBottom = 1.0f; + + float fDepth = 0.5f; + for( int i=0; i 126 ) + { + continue; + } + + // Add 6 sprite vertices + DXUTSpriteVertex SpriteVertex; + float fRectRight = fRectLeft + fGlyphSizeX; + float fRectBottom = fRectTop - fGlyphSizeY; + float fTexLeft = ( strText[i] - 32 ) * fCharTexSizeX; + float fTexRight = fTexLeft + fCharTexSizeX; + + // tri1 + SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectTop, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexTop ); + SpriteVertex.vColor = vFontColor; + g_FontVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); + SpriteVertex.vColor = vFontColor; + g_FontVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); + SpriteVertex.vColor = vFontColor; + g_FontVertices.Add( SpriteVertex ); + + // tri2 + SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); + SpriteVertex.vColor = vFontColor; + g_FontVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectBottom, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexBottom ); + SpriteVertex.vColor = vFontColor; + g_FontVertices.Add( SpriteVertex ); + + SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); + SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); + SpriteVertex.vColor = vFontColor; + g_FontVertices.Add( SpriteVertex ); + + fRectLeft += fGlyphSizeX; + + } + + // TODO: We have to end text after every line so that rendering order between sprites and fonts is preserved + EndText11( pd3dDevice, pd3d11DeviceContext ); +} + +void EndText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext ) +{ + + // ensure our buffer size can hold our sprites + UINT FontDataBytes = g_FontVertices.GetSize() * sizeof( DXUTSpriteVertex ); + if( g_FontBufferBytes11 < FontDataBytes ) + { + SAFE_RELEASE( g_pFontBuffer11 ); + g_FontBufferBytes11 = FontDataBytes; + + D3D11_BUFFER_DESC BufferDesc; + BufferDesc.ByteWidth = g_FontBufferBytes11; + BufferDesc.Usage = D3D11_USAGE_DYNAMIC; + BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + BufferDesc.MiscFlags = 0; + + pd3dDevice->CreateBuffer( &BufferDesc, NULL, &g_pFontBuffer11 ); + } + + // Copy the sprites over + D3D11_BOX destRegion; + destRegion.left = 0; + destRegion.right = FontDataBytes; + destRegion.top = 0; + destRegion.bottom = 1; + destRegion.front = 0; + destRegion.back = 1; + D3D11_MAPPED_SUBRESOURCE MappedResource; + if ( S_OK == pd3d11DeviceContext->Map( g_pFontBuffer11, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) { + CopyMemory( MappedResource.pData, (void*)g_FontVertices.GetData(), FontDataBytes ); + pd3d11DeviceContext->Unmap(g_pFontBuffer11, 0); + } + + ID3D11ShaderResourceView* pOldTexture = NULL; + pd3d11DeviceContext->PSGetShaderResources( 0, 1, &pOldTexture ); + pd3d11DeviceContext->PSSetShaderResources( 0, 1, &g_pFont11 ); + + // Draw + UINT Stride = sizeof( DXUTSpriteVertex ); + UINT Offset = 0; + pd3d11DeviceContext->IASetVertexBuffers( 0, 1, &g_pFontBuffer11, &Stride, &Offset ); + pd3d11DeviceContext->IASetInputLayout( g_pInputLayout11 ); + pd3d11DeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); + pd3d11DeviceContext->Draw( g_FontVertices.GetSize(), 0 ); + + pd3d11DeviceContext->PSSetShaderResources( 0, 1, &pOldTexture ); + SAFE_RELEASE( pOldTexture ); + + g_FontVertices.Reset(); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialog::DrawText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext, + LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount, bool bCenter ) +{ + //HRESULT hr = S_OK; + + // No need to draw fully transparent layers + if( pElement->FontColor.Current.a == 0 ) + return S_OK; + + RECT rcScreen = *prcDest; + OffsetRect( &rcScreen, m_x, m_y); + + // If caption is enabled, offset the Y position by its height. + if( m_bCaption ) + OffsetRect( &rcScreen, 0, m_nCaptionHeight ); + + float fBBWidth = ( float )m_pManager->m_nBackBufferWidth; + float fBBHeight = ( float )m_pManager->m_nBackBufferHeight; + + if( bShadow ) + { + RECT rcShadow = rcScreen; + OffsetRect( &rcShadow, 1, 1 ); + + D3DXCOLOR vShadowColor( 0,0,0, 1.0f ); + DrawText11DXUT( pd3dDevice, pd3d11DeviceContext, + strText, rcShadow, vShadowColor, + fBBWidth, fBBHeight, bCenter ); + + } + + D3DXCOLOR vFontColor( pElement->FontColor.Current.r, pElement->FontColor.Current.g, pElement->FontColor.Current.b, 1.0f ); + DrawText11DXUT( pd3dDevice, pd3d11DeviceContext, + strText, rcScreen, vFontColor, + fBBWidth, fBBHeight, bCenter ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::SetBackgroundColors( D3DCOLOR colorTopLeft, D3DCOLOR colorTopRight, D3DCOLOR colorBottomLeft, + D3DCOLOR colorBottomRight ) +{ + m_colorTopLeft = colorTopLeft; + m_colorTopRight = colorTopRight; + m_colorBottomLeft = colorBottomLeft; + m_colorBottomRight = colorBottomRight; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::SetNextDialog( CDXUTDialog* pNextDialog ) +{ + if( pNextDialog == NULL ) + pNextDialog = this; + + m_pNextDialog = pNextDialog; + if( pNextDialog ) + m_pNextDialog->m_pPrevDialog = this; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::ClearFocus() +{ + if( s_pControlFocus ) + { + s_pControlFocus->OnFocusOut(); + s_pControlFocus = NULL; + } + + ReleaseCapture(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::FocusDefaultControl() +{ + // Check for default control in this dialog + for( int i = 0; i < m_Controls.GetSize(); i++ ) + { + CDXUTControl* pControl = m_Controls.GetAt( i ); + if( pControl->m_bIsDefault ) + { + // Remove focus from the current control + ClearFocus(); + + // Give focus to the default control + s_pControlFocus = pControl; + s_pControlFocus->OnFocusIn(); + return; + } + } +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTDialog::OnCycleFocus( bool bForward ) +{ + CDXUTControl* pControl = NULL; + CDXUTDialog* pDialog = NULL; // pDialog and pLastDialog are used to track wrapping of + CDXUTDialog* pLastDialog; // focus from first control to last or vice versa. + + if( s_pControlFocus == NULL ) + { + // If s_pControlFocus is NULL, we focus the first control of first dialog in + // the case that bForward is true, and focus the last control of last dialog when + // bForward is false. + // + if( bForward ) + { + // Search for the first control from the start of the dialog + // array. + for( int d = 0; d < m_pManager->m_Dialogs.GetSize(); ++d ) + { + pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt( d ); + if( pDialog && pDialog->m_Controls.GetSize() > 0 ) + { + pControl = pDialog->m_Controls.GetAt( 0 ); + break; + } + } + + if( !pDialog || !pControl ) + { + // No dialog has been registered yet or no controls have been + // added to the dialogs. Cannot proceed. + return true; + } + } + else + { + // Search for the first control from the end of the dialog + // array. + for( int d = m_pManager->m_Dialogs.GetSize() - 1; d >= 0; --d ) + { + pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt( d ); + if( pDialog && pDialog->m_Controls.GetSize() > 0 ) + { + pControl = pDialog->m_Controls.GetAt( pDialog->m_Controls.GetSize() - 1 ); + break; + } + } + + if( !pDialog || !pControl ) + { + // No dialog has been registered yet or no controls have been + // added to the dialogs. Cannot proceed. + return true; + } + } + } + else if( s_pControlFocus->m_pDialog != this ) + { + // If a control belonging to another dialog has focus, let that other + // dialog handle this event by returning false. + // + return false; + } + else + { + // Focused control belongs to this dialog. Cycle to the + // next/previous control. + pLastDialog = s_pControlFocus->m_pDialog; + pControl = ( bForward ) ? GetNextControl( s_pControlFocus ) : GetPrevControl( s_pControlFocus ); + pDialog = pControl->m_pDialog; + } + + for( int i = 0; i < 0xffff; i++ ) + { + // If we just wrapped from last control to first or vice versa, + // set the focused control to NULL. This state, where no control + // has focus, allows the camera to work. + int nLastDialogIndex = m_pManager->m_Dialogs.IndexOf( pLastDialog ); + int nDialogIndex = m_pManager->m_Dialogs.IndexOf( pDialog ); + if( ( !bForward && nLastDialogIndex < nDialogIndex ) || + ( bForward && nDialogIndex < nLastDialogIndex ) ) + { + if( s_pControlFocus ) + s_pControlFocus->OnFocusOut(); + s_pControlFocus = NULL; + return true; + } + + // If we've gone in a full circle then focus doesn't change + if( pControl == s_pControlFocus ) + return true; + + // If the dialog accepts keybord input and the control can have focus then + // move focus + if( pControl->m_pDialog->m_bKeyboardInput && pControl->CanHaveFocus() ) + { + if( s_pControlFocus ) + s_pControlFocus->OnFocusOut(); + s_pControlFocus = pControl; + s_pControlFocus->OnFocusIn(); + return true; + } + + pLastDialog = pDialog; + pControl = ( bForward ) ? GetNextControl( pControl ) : GetPrevControl( pControl ); + pDialog = pControl->m_pDialog; + } + + // If we reached this point, the chain of dialogs didn't form a complete loop + DXTRACE_ERR( L"CDXUTDialog: Multiple dialogs are improperly chained together", E_FAIL ); + return false; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialogResourceManager::CreateFont9( UINT iFont ) +{ + HRESULT hr = S_OK; + + DXUTFontNode* pFontNode = m_FontCache.GetAt( iFont ); + + SAFE_RELEASE( pFontNode->pFont9 ); + + V_RETURN( D3DXCreateFont( m_pd3d9Device, pFontNode->nHeight, 0, pFontNode->nWeight, 1, FALSE, DEFAULT_CHARSET, + OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, + pFontNode->strFace, &pFontNode->pFont9 ) ); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialogResourceManager::CreateFont11( UINT iFont ) +{ + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialogResourceManager::CreateTexture9( UINT iTexture ) +{ + HRESULT hr = S_OK; + + DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( iTexture ); + + + D3DXIMAGE_INFO info; + + if( !pTextureNode->bFileSource ) + { + if( pTextureNode->nResourceID == 0xFFFF && pTextureNode->hResourceModule == ( HMODULE )0xFFFF ) + { + hr = DXUTCreateGUITextureFromInternalArray9( m_pd3d9Device, &pTextureNode->pTexture9, &info ); + if( FAILED( hr ) ) + return DXTRACE_ERR( L"D3DXCreateTextureFromFileInMemoryEx", hr ); + } + else + { + LPCWSTR pID = pTextureNode->nResourceID ? ( LPCWSTR )( size_t )pTextureNode->nResourceID : + pTextureNode->strFilename; + + // Create texture from resource + hr = D3DXCreateTextureFromResourceEx( m_pd3d9Device, pTextureNode->hResourceModule, pID, D3DX_DEFAULT, + D3DX_DEFAULT, + 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, + D3DX_DEFAULT, D3DX_DEFAULT, 0, + &info, NULL, &pTextureNode->pTexture9 ); + if( FAILED( hr ) ) + return DXTRACE_ERR( L"D3DXCreateTextureFromResourceEx", hr ); + } + } + else + { + // Make sure there's a texture to create + if( pTextureNode->strFilename[0] == 0 ) + return S_OK; + + // Create texture from file + hr = D3DXCreateTextureFromFileEx( m_pd3d9Device, pTextureNode->strFilename, D3DX_DEFAULT, D3DX_DEFAULT, + 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, + D3DX_DEFAULT, D3DX_DEFAULT, 0, + &info, NULL, &pTextureNode->pTexture9 ); + if( FAILED( hr ) ) + { + return DXTRACE_ERR( L"D3DXCreateTextureFromFileEx", hr ); + } + } + + // Store dimensions + pTextureNode->dwWidth = info.Width; + pTextureNode->dwHeight = info.Height; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTDialogResourceManager::CreateTexture11( UINT iTexture ) +{ + HRESULT hr = S_OK; + + DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( iTexture ); + + if( !pTextureNode->bFileSource ) + { + if( pTextureNode->nResourceID == 0xFFFF && pTextureNode->hResourceModule == ( HMODULE )0xFFFF ) + { + hr = DXUTCreateGUITextureFromInternalArray11( m_pd3d11Device, &pTextureNode->pTexture11, NULL ); + if( FAILED( hr ) ) + return DXTRACE_ERR( L"D3DX10CreateResourceFromFileInMemory", hr ); + } + //else + //{ + // LPCWSTR pID = pTextureNode->nResourceID ? ( LPCWSTR )( size_t )pTextureNode->nResourceID : + // pTextureNode->strFilename; + + // D3DX10_IMAGE_INFO SrcInfo; + // D3DX10GetImageInfoFromResource( NULL, pID, NULL, &SrcInfo, NULL ); + + // // Create texture from resource + // ID3D10Resource* pRes; + // D3DX10_IMAGE_LOAD_INFO loadInfo; + // loadInfo.Width = D3DX10_DEFAULT; + // loadInfo.Height = D3DX10_DEFAULT; + // loadInfo.Depth = D3DX10_DEFAULT; + // loadInfo.FirstMipLevel = 0; + // loadInfo.MipLevels = 1; + // loadInfo.Usage = D3D10_USAGE_DEFAULT; + // loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE; + // loadInfo.CpuAccessFlags = 0; + // loadInfo.MiscFlags = 0; + // loadInfo.Format = MAKE_TYPELESS( SrcInfo.Format ); + // loadInfo.Filter = D3DX10_FILTER_NONE; + // loadInfo.MipFilter = D3DX10_FILTER_NONE; + // loadInfo.pSrcInfo = &SrcInfo; + + // hr = D3DX10CreateTextureFromResource( m_pd3d10Device, pTextureNode->hResourceModule, pID, &loadInfo, + // NULL, &pRes, NULL ); + // if( FAILED( hr ) ) + // return DXTRACE_ERR( L"D3DX10CreateResourceFromResource", hr ); + // hr = pRes->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&pTextureNode->pTexture10 ); + // SAFE_RELEASE( pRes ); + // if( FAILED( hr ) ) + // return hr; + //} + } + else + { + // + //// Make sure there's a texture to create + //if( pTextureNode->strFilename[0] == 0 ) + // return S_OK; + + //D3DX10_IMAGE_INFO SrcInfo; + //D3DX10GetImageInfoFromFile( pTextureNode->strFilename, NULL, &SrcInfo, NULL ); + + //// Create texture from file + //ID3D10Resource* pRes; + //D3DX10_IMAGE_LOAD_INFO loadInfo; + //loadInfo.Width = D3DX10_DEFAULT; + //loadInfo.Height = D3DX10_DEFAULT; + //loadInfo.Depth = D3DX10_DEFAULT; + //loadInfo.FirstMipLevel = 0; + //loadInfo.MipLevels = 1; + //loadInfo.Usage = D3D10_USAGE_DEFAULT; + //loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE; + //loadInfo.CpuAccessFlags = 0; + //loadInfo.MiscFlags = 0; + //loadInfo.Format = MAKE_TYPELESS( SrcInfo.Format ); + //loadInfo.Filter = D3DX10_FILTER_NONE; + //loadInfo.MipFilter = D3DX10_FILTER_NONE; + //loadInfo.pSrcInfo = &SrcInfo; + //hr = D3DX10CreateTextureFromFile( m_pd3d10Device, pTextureNode->strFilename, &loadInfo, NULL, &pRes, NULL ); + //if( FAILED( hr ) ) + //{ + // return DXTRACE_ERR( L"D3DX10CreateResourceFromFileEx", hr ); + //} + //hr = pRes->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&pTextureNode->pTexture10 ); + //SAFE_RELEASE( pRes ); + //if( FAILED( hr ) ) + // return hr; + // + } + + // Store dimensions + D3D11_TEXTURE2D_DESC desc; + pTextureNode->pTexture11->GetDesc( &desc ); + pTextureNode->dwWidth = desc.Width; + pTextureNode->dwHeight = desc.Height; + + // Create resource view + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Format = MAKE_SRGB( desc.Format ); + SRVDesc.Texture2D.MipLevels = 1; + SRVDesc.Texture2D.MostDetailedMip = 0; + hr = m_pd3d11Device->CreateShaderResourceView( pTextureNode->pTexture11, &SRVDesc, &pTextureNode->pTexResView11 ); + + return hr; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTDialog::InitDefaultElements() +{ + SetFont( 0, L"Arial", 14, FW_NORMAL ); + + CDXUTElement Element; + RECT rcTexture; + + //------------------------------------- + // Element for the caption + //------------------------------------- + m_CapElement.SetFont( 0 ); + SetRect( &rcTexture, 17, 269, 241, 287 ); + m_CapElement.SetTexture( 0, &rcTexture ); + m_CapElement.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + m_CapElement.FontColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + m_CapElement.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER ); + // Pre-blend as we don't need to transition the state + m_CapElement.TextureColor.Blend( DXUT_STATE_NORMAL, 10.0f ); + m_CapElement.FontColor.Blend( DXUT_STATE_NORMAL, 10.0f ); + + //------------------------------------- + // CDXUTStatic + //------------------------------------- + Element.SetFont( 0 ); + Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_STATIC, 0, &Element ); + + + //------------------------------------- + // CDXUTButton - Button + //------------------------------------- + SetRect( &rcTexture, 0, 0, 136, 54 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0 ); + Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); + Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_BUTTON, 0, &Element ); + + + //------------------------------------- + // CDXUTButton - Fill layer + //------------------------------------- + SetRect( &rcTexture, 136, 0, 252, 54 ); + Element.SetTexture( 0, &rcTexture, D3DCOLOR_ARGB( 0, 255, 255, 255 ) ); + Element.TextureColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 160, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 60, 0, 0, 0 ); + Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 30, 255, 255, 255 ); + + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_BUTTON, 1, &Element ); + + + //------------------------------------- + // CDXUTCheckBox - Box + //------------------------------------- + SetRect( &rcTexture, 0, 54, 27, 81 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER ); + Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); + Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_CHECKBOX, 0, &Element ); + + + //------------------------------------- + // CDXUTCheckBox - Check + //------------------------------------- + SetRect( &rcTexture, 27, 54, 54, 81 ); + Element.SetTexture( 0, &rcTexture ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_CHECKBOX, 1, &Element ); + + + //------------------------------------- + // CDXUTRadioButton - Box + //------------------------------------- + SetRect( &rcTexture, 54, 54, 81, 81 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER ); + Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); + Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 0, &Element ); + + + //------------------------------------- + // CDXUTRadioButton - Check + //------------------------------------- + SetRect( &rcTexture, 81, 54, 108, 81 ); + Element.SetTexture( 0, &rcTexture ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 1, &Element ); + + + //------------------------------------- + // CDXUTComboBox - Main + //------------------------------------- + SetRect( &rcTexture, 7, 81, 247, 123 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0 ); + Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 200, 200, 200 ); + Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 170, 230, 230, 230 ); + Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 200, 200, 200 ); + Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); + Element.FontColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); + Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); + + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_COMBOBOX, 0, &Element ); + + + //------------------------------------- + // CDXUTComboBox - Button + //------------------------------------- + SetRect( &rcTexture, 98, 189, 151, 238 ); + Element.SetTexture( 0, &rcTexture ); + Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 150, 150, 150 ); + Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 255, 255, 255 ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_COMBOBOX, 1, &Element ); + + + //------------------------------------- + // CDXUTComboBox - Dropdown + //------------------------------------- + SetRect( &rcTexture, 13, 123, 241, 160 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_COMBOBOX, 2, &Element ); + + + //------------------------------------- + // CDXUTComboBox - Selection + //------------------------------------- + SetRect( &rcTexture, 12, 163, 239, 183 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_TOP ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_COMBOBOX, 3, &Element ); + + + //------------------------------------- + // CDXUTSlider - Track + //------------------------------------- + SetRect( &rcTexture, 1, 187, 93, 228 ); + Element.SetTexture( 0, &rcTexture ); + Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); + Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 255, 255, 255 ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_SLIDER, 0, &Element ); + + //------------------------------------- + // CDXUTSlider - Button + //------------------------------------- + SetRect( &rcTexture, 151, 193, 192, 234 ); + Element.SetTexture( 0, &rcTexture ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_SLIDER, 1, &Element ); + + //------------------------------------- + // CDXUTScrollBar - Track + //------------------------------------- + int nScrollBarStartX = 196; + int nScrollBarStartY = 191; + SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 21, nScrollBarStartX + 22, nScrollBarStartY + 32 ); + Element.SetTexture( 0, &rcTexture ); + Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 0, &Element ); + + //------------------------------------- + // CDXUTScrollBar - Up Arrow + //------------------------------------- + SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 1, nScrollBarStartX + 22, nScrollBarStartY + 21 ); + Element.SetTexture( 0, &rcTexture ); + Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 ); + + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 1, &Element ); + + //------------------------------------- + // CDXUTScrollBar - Down Arrow + //------------------------------------- + SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 32, nScrollBarStartX + 22, nScrollBarStartY + 53 ); + Element.SetTexture( 0, &rcTexture ); + Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 ); + + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 2, &Element ); + + //------------------------------------- + // CDXUTScrollBar - Button + //------------------------------------- + SetRect( &rcTexture, 220, 192, 238, 234 ); + Element.SetTexture( 0, &rcTexture ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 3, &Element ); + + + //------------------------------------- + // CDXUTEditBox + //------------------------------------- + // Element assignment: + // 0 - text area + // 1 - top left border + // 2 - top border + // 3 - top right border + // 4 - left border + // 5 - right border + // 6 - lower left border + // 7 - lower border + // 8 - lower right border + + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP ); + + // Assign the style + SetRect( &rcTexture, 14, 90, 241, 113 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 0, &Element ); + SetRect( &rcTexture, 8, 82, 14, 90 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 1, &Element ); + SetRect( &rcTexture, 14, 82, 241, 90 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 2, &Element ); + SetRect( &rcTexture, 241, 82, 246, 90 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 3, &Element ); + SetRect( &rcTexture, 8, 90, 14, 113 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 4, &Element ); + SetRect( &rcTexture, 241, 90, 246, 113 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 5, &Element ); + SetRect( &rcTexture, 8, 113, 14, 121 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 6, &Element ); + SetRect( &rcTexture, 14, 113, 241, 121 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 7, &Element ); + SetRect( &rcTexture, 241, 113, 246, 121 ); + Element.SetTexture( 0, &rcTexture ); + SetDefaultElement( DXUT_CONTROL_EDITBOX, 8, &Element ); + + //------------------------------------- + // CDXUTListBox - Main + //------------------------------------- + SetRect( &rcTexture, 13, 123, 241, 160 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_LISTBOX, 0, &Element ); + + //------------------------------------- + // CDXUTListBox - Selection + //------------------------------------- + + SetRect( &rcTexture, 16, 166, 240, 183 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_TOP ); + + // Assign the Element + SetDefaultElement( DXUT_CONTROL_LISTBOX, 1, &Element ); +} + + + +//-------------------------------------------------------------------------------------- +// CDXUTControl class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTControl::CDXUTControl( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_BUTTON; + m_pDialog = pDialog; + m_ID = 0; + m_Index = 0; + m_pUserData = NULL; + + m_bEnabled = true; + m_bVisible = true; + m_bMouseOver = false; + m_bHasFocus = false; + m_bIsDefault = false; + + m_pDialog = NULL; + + m_x = 0; + m_y = 0; + m_width = 0; + m_height = 0; + + ZeroMemory( &m_rcBoundingBox, sizeof( m_rcBoundingBox ) ); +} + + +CDXUTControl::~CDXUTControl() +{ + for( int i = 0; i < m_Elements.GetSize(); ++i ) + { + delete m_Elements[i]; + } + m_Elements.RemoveAll(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTControl::SetTextColor( D3DCOLOR Color ) +{ + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + + if( pElement ) + pElement->FontColor.States[DXUT_STATE_NORMAL] = Color; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTControl::SetElement( UINT iElement, CDXUTElement* pElement ) +{ + HRESULT hr = S_OK; + + if( pElement == NULL ) + return E_INVALIDARG; + + // Make certain the array is this large + for( UINT i = m_Elements.GetSize(); i <= iElement; i++ ) + { + CDXUTElement* pNewElement = new CDXUTElement(); + if( pNewElement == NULL ) + return E_OUTOFMEMORY; + + hr = m_Elements.Add( pNewElement ); + if( FAILED( hr ) ) + { + SAFE_DELETE( pNewElement ); + return hr; + } + } + + // Update the data + CDXUTElement* pCurElement = m_Elements.GetAt( iElement ); + *pCurElement = *pElement; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTControl::Refresh() +{ + m_bMouseOver = false; + m_bHasFocus = false; + + for( int i = 0; i < m_Elements.GetSize(); i++ ) + { + CDXUTElement* pElement = m_Elements.GetAt( i ); + pElement->Refresh(); + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTControl::UpdateRects() +{ + SetRect( &m_rcBoundingBox, m_x, m_y, m_x + m_width, m_y + m_height ); +} + + +//-------------------------------------------------------------------------------------- +// CDXUTStatic class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTStatic::CDXUTStatic( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_STATIC; + m_pDialog = pDialog; + + ZeroMemory( &m_strText, sizeof( m_strText ) ); + + for( int i = 0; i < m_Elements.GetSize(); i++ ) + { + CDXUTElement* pElement = m_Elements.GetAt( i ); + SAFE_DELETE( pElement ); + } + + m_Elements.RemoveAll(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTStatic::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + + DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL; + + if( m_bEnabled == false ) + iState = DXUT_STATE_DISABLED; + + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + + pElement->FontColor.Blend( iState, fElapsedTime ); + + m_pDialog->DrawText( m_strText, pElement, &m_rcBoundingBox, false, -1, false); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTStatic::GetTextCopy( __out_ecount(bufferCount) LPWSTR strDest, + UINT bufferCount ) +{ + // Validate incoming parameters + if( strDest == NULL || bufferCount == 0 ) + { + return E_INVALIDARG; + } + + // Copy the window text + wcscpy_s( strDest, bufferCount, m_strText ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTStatic::SetText( LPCWSTR strText ) +{ + if( strText == NULL ) + { + m_strText[0] = 0; + return S_OK; + } + + wcscpy_s( m_strText, MAX_PATH, strText ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// CDXUTButton class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTButton::CDXUTButton( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_BUTTON; + m_pDialog = pDialog; + + m_bPressed = false; + m_nHotkey = 0; +} + +//-------------------------------------------------------------------------------------- +bool CDXUTButton::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_KEYDOWN: + { + switch( wParam ) + { + case VK_SPACE: + m_bPressed = true; + return true; + } + } + + case WM_KEYUP: + { + switch( wParam ) + { + case VK_SPACE: + if( m_bPressed == true ) + { + m_bPressed = false; + m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this ); + } + return true; + } + } + } + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTButton::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + if( ContainsPoint( pt ) ) + { + // Pressed while inside the control + m_bPressed = true; + SetCapture( DXUTGetHWND() ); + + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + return true; + } + + break; + } + + case WM_LBUTTONUP: + { + if( m_bPressed ) + { + m_bPressed = false; + ReleaseCapture(); + + if( !m_pDialog->m_bKeyboardInput ) + m_pDialog->ClearFocus(); + + // Button click + if( ContainsPoint( pt ) ) + m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this ); + + return true; + } + + break; + } + }; + + return false; +} + +//-------------------------------------------------------------------------------------- +void CDXUTButton::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + + int nOffsetX = 0; + int nOffsetY = 0; + + DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL; + + if( m_bVisible == false ) + { + iState = DXUT_STATE_HIDDEN; + } + else if( m_bEnabled == false ) + { + iState = DXUT_STATE_DISABLED; + } + else if( m_bPressed ) + { + iState = DXUT_STATE_PRESSED; + + nOffsetX = 1; + nOffsetY = 2; + } + else if( m_bMouseOver ) + { + iState = DXUT_STATE_MOUSEOVER; + + nOffsetX = -1; + nOffsetY = -2; + } + else if( m_bHasFocus ) + { + iState = DXUT_STATE_FOCUS; + } + + // Background fill layer + //TODO: remove magic numbers + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + + float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f; + + RECT rcWindow = m_rcBoundingBox; + OffsetRect( &rcWindow, nOffsetX, nOffsetY ); + + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate ); + + m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_FAR_BUTTON_DEPTH ); + m_pDialog->DrawText( m_strText, pElement, &rcWindow, false, -1, true ); + + // Main button + pElement = m_Elements.GetAt( 1 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate ); + + m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_NEAR_BUTTON_DEPTH ); + m_pDialog->DrawText( m_strText, pElement, &rcWindow, false, -1, true ); +} + + + +//-------------------------------------------------------------------------------------- +// CDXUTCheckBox class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTCheckBox::CDXUTCheckBox( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_CHECKBOX; + m_pDialog = pDialog; + + m_bChecked = false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTCheckBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_KEYDOWN: + { + switch( wParam ) + { + case VK_SPACE: + m_bPressed = true; + return true; + } + } + + case WM_KEYUP: + { + switch( wParam ) + { + case VK_SPACE: + if( m_bPressed == true ) + { + m_bPressed = false; + SetCheckedInternal( !m_bChecked, true ); + } + return true; + } + } + } + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTCheckBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + if( ContainsPoint( pt ) ) + { + // Pressed while inside the control + m_bPressed = true; + SetCapture( DXUTGetHWND() ); + + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + return true; + } + + break; + } + + case WM_LBUTTONUP: + { + if( m_bPressed ) + { + m_bPressed = false; + ReleaseCapture(); + + // Button click + if( ContainsPoint( pt ) ) + SetCheckedInternal( !m_bChecked, true ); + + return true; + } + + break; + } + }; + + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTCheckBox::SetCheckedInternal( bool bChecked, bool bFromInput ) +{ + m_bChecked = bChecked; + + m_pDialog->SendEvent( EVENT_CHECKBOX_CHANGED, bFromInput, this ); +} + + +//-------------------------------------------------------------------------------------- +BOOL CDXUTCheckBox::ContainsPoint( POINT pt ) +{ + return ( PtInRect( &m_rcBoundingBox, pt ) || + PtInRect( &m_rcButton, pt ) ); +} + + + +//-------------------------------------------------------------------------------------- +void CDXUTCheckBox::UpdateRects() +{ + CDXUTButton::UpdateRects(); + + m_rcButton = m_rcBoundingBox; + m_rcButton.right = m_rcButton.left + RectHeight( m_rcButton ); + + m_rcText = m_rcBoundingBox; + m_rcText.left += ( int )( 1.25f * RectWidth( m_rcButton ) ); +} + + + +//-------------------------------------------------------------------------------------- +void CDXUTCheckBox::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL; + + if( m_bVisible == false ) + iState = DXUT_STATE_HIDDEN; + else if( m_bEnabled == false ) + iState = DXUT_STATE_DISABLED; + else if( m_bPressed ) + iState = DXUT_STATE_PRESSED; + else if( m_bMouseOver ) + iState = DXUT_STATE_MOUSEOVER; + else if( m_bHasFocus ) + iState = DXUT_STATE_FOCUS; + + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + + float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f; + + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate ); + + m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_NEAR_BUTTON_DEPTH ); + m_pDialog->DrawText( m_strText, pElement, &m_rcText, false, -1, false ); + + if( !m_bChecked ) + iState = DXUT_STATE_HIDDEN; + + pElement = m_Elements.GetAt( 1 ); + + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_FAR_BUTTON_DEPTH ); +} + + + + +//-------------------------------------------------------------------------------------- +// CDXUTRadioButton class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTRadioButton::CDXUTRadioButton( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_RADIOBUTTON; + m_pDialog = pDialog; +} + + + +//-------------------------------------------------------------------------------------- +bool CDXUTRadioButton::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_KEYDOWN: + { + switch( wParam ) + { + case VK_SPACE: + m_bPressed = true; + return true; + } + } + + case WM_KEYUP: + { + switch( wParam ) + { + case VK_SPACE: + if( m_bPressed == true ) + { + m_bPressed = false; + + m_pDialog->ClearRadioButtonGroup( m_nButtonGroup ); + m_bChecked = !m_bChecked; + + m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, true, this ); + } + return true; + } + } + } + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTRadioButton::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + if( ContainsPoint( pt ) ) + { + // Pressed while inside the control + m_bPressed = true; + SetCapture( DXUTGetHWND() ); + + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + return true; + } + + break; + } + + case WM_LBUTTONUP: + { + if( m_bPressed ) + { + m_bPressed = false; + ReleaseCapture(); + + // Button click + if( ContainsPoint( pt ) ) + { + m_pDialog->ClearRadioButtonGroup( m_nButtonGroup ); + m_bChecked = !m_bChecked; + + m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, true, this ); + } + + return true; + } + + break; + } + }; + + return false; +} + +//-------------------------------------------------------------------------------------- +void CDXUTRadioButton::SetCheckedInternal( bool bChecked, bool bClearGroup, bool bFromInput ) +{ + if( bChecked && bClearGroup ) + m_pDialog->ClearRadioButtonGroup( m_nButtonGroup ); + + m_bChecked = bChecked; + m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, bFromInput, this ); +} + + + + +//-------------------------------------------------------------------------------------- +// CDXUTComboBox class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTComboBox::CDXUTComboBox( CDXUTDialog* pDialog ) : m_ScrollBar( pDialog ) +{ + m_Type = DXUT_CONTROL_COMBOBOX; + m_pDialog = pDialog; + + m_nDropHeight = 100; + + m_nSBWidth = 16; + m_bOpened = false; + m_iSelected = -1; + m_iFocused = -1; +} + + +//-------------------------------------------------------------------------------------- +CDXUTComboBox::~CDXUTComboBox() +{ + RemoveAllItems(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTComboBox::SetTextColor( D3DCOLOR Color ) +{ + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + + if( pElement ) + pElement->FontColor.States[DXUT_STATE_NORMAL] = Color; + + pElement = m_Elements.GetAt( 2 ); + + if( pElement ) + pElement->FontColor.States[DXUT_STATE_NORMAL] = Color; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTComboBox::UpdateRects() +{ + + CDXUTButton::UpdateRects(); + + m_rcButton = m_rcBoundingBox; + m_rcButton.left = m_rcButton.right - RectHeight( m_rcButton ); + + m_rcText = m_rcBoundingBox; + m_rcText.right = m_rcButton.left; + + m_rcDropdown = m_rcText; + OffsetRect( &m_rcDropdown, 0, ( int )( 0.90f * RectHeight( m_rcText ) ) ); + m_rcDropdown.bottom += m_nDropHeight; + m_rcDropdown.right -= m_nSBWidth; + + m_rcDropdownText = m_rcDropdown; + m_rcDropdownText.left += ( int )( 0.1f * RectWidth( m_rcDropdown ) ); + m_rcDropdownText.right -= ( int )( 0.1f * RectWidth( m_rcDropdown ) ); + m_rcDropdownText.top += ( int )( 0.1f * RectHeight( m_rcDropdown ) ); + m_rcDropdownText.bottom -= ( int )( 0.1f * RectHeight( m_rcDropdown ) ); + + // Update the scrollbar's rects + m_ScrollBar.SetLocation( m_rcDropdown.right, m_rcDropdown.top + 2 ); + m_ScrollBar.SetSize( m_nSBWidth, RectHeight( m_rcDropdown ) - 2 ); + DXUTFontNode* pFontNode = m_pDialog->GetManager()->GetFontNode( m_Elements.GetAt( 2 )->iFont ); + if( pFontNode && pFontNode->nHeight ) + { + m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) / pFontNode->nHeight ); + + // The selected item may have been scrolled off the page. + // Ensure that it is in page again. + m_ScrollBar.ShowItem( m_iSelected ); + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTComboBox::OnFocusOut() +{ + CDXUTButton::OnFocusOut(); + + m_bOpened = false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTComboBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + const DWORD REPEAT_MASK = ( 0x40000000 ); + + if( !m_bEnabled || !m_bVisible ) + return false; + + // Let the scroll bar have a chance to handle it first + if( m_ScrollBar.HandleKeyboard( uMsg, wParam, lParam ) ) + return true; + + switch( uMsg ) + { + case WM_KEYDOWN: + { + switch( wParam ) + { + case VK_RETURN: + if( m_bOpened ) + { + if( m_iSelected != m_iFocused ) + { + m_iSelected = m_iFocused; + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + } + m_bOpened = false; + + if( !m_pDialog->m_bKeyboardInput ) + m_pDialog->ClearFocus(); + + return true; + } + break; + + case VK_F4: + // Filter out auto-repeats + if( lParam & REPEAT_MASK ) + return true; + + m_bOpened = !m_bOpened; + + if( !m_bOpened ) + { + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + + if( !m_pDialog->m_bKeyboardInput ) + m_pDialog->ClearFocus(); + } + + return true; + + case VK_LEFT: + case VK_UP: + if( m_iFocused > 0 ) + { + m_iFocused--; + m_iSelected = m_iFocused; + + if( !m_bOpened ) + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + } + + return true; + + case VK_RIGHT: + case VK_DOWN: + if( m_iFocused + 1 < ( int )GetNumItems() ) + { + m_iFocused++; + m_iSelected = m_iFocused; + + if( !m_bOpened ) + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + } + + return true; + } + break; + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTComboBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + // Let the scroll bar handle it first. + if( m_ScrollBar.HandleMouse( uMsg, pt, wParam, lParam ) ) + return true; + + switch( uMsg ) + { + case WM_MOUSEMOVE: + { + if( m_bOpened && PtInRect( &m_rcDropdown, pt ) ) + { + // Determine which item has been selected + for( int i = 0; i < m_Items.GetSize(); i++ ) + { + DXUTComboBoxItem* pItem = m_Items.GetAt( i ); + if( pItem->bVisible && + PtInRect( &pItem->rcActive, pt ) ) + { + m_iFocused = i; + } + } + return true; + } + break; + } + + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + if( ContainsPoint( pt ) ) + { + // Pressed while inside the control + m_bPressed = true; + SetCapture( DXUTGetHWND() ); + + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + // Toggle dropdown + if( m_bHasFocus ) + { + m_bOpened = !m_bOpened; + + if( !m_bOpened ) + { + if( !m_pDialog->m_bKeyboardInput ) + m_pDialog->ClearFocus(); + } + } + + return true; + } + + // Perhaps this click is within the dropdown + if( m_bOpened && PtInRect( &m_rcDropdown, pt ) ) + { + // Determine which item has been selected + for( int i = m_ScrollBar.GetTrackPos(); i < m_Items.GetSize(); i++ ) + { + DXUTComboBoxItem* pItem = m_Items.GetAt( i ); + if( pItem->bVisible && + PtInRect( &pItem->rcActive, pt ) ) + { + m_iFocused = m_iSelected = i; + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + m_bOpened = false; + + if( !m_pDialog->m_bKeyboardInput ) + m_pDialog->ClearFocus(); + + break; + } + } + + return true; + } + + // Mouse click not on main control or in dropdown, fire an event if needed + if( m_bOpened ) + { + m_iFocused = m_iSelected; + + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + m_bOpened = false; + } + + // Make sure the control is no longer in a pressed state + m_bPressed = false; + + // Release focus if appropriate + if( !m_pDialog->m_bKeyboardInput ) + { + m_pDialog->ClearFocus(); + } + + break; + } + + case WM_LBUTTONUP: + { + if( m_bPressed && ContainsPoint( pt ) ) + { + // Button click + m_bPressed = false; + ReleaseCapture(); + return true; + } + + break; + } + + case WM_MOUSEWHEEL: + { + int zDelta = ( short )HIWORD( wParam ) / WHEEL_DELTA; + if( m_bOpened ) + { + UINT uLines; + SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &uLines, 0 ); + m_ScrollBar.Scroll( -zDelta * uLines ); + } + else + { + if( zDelta > 0 ) + { + if( m_iFocused > 0 ) + { + m_iFocused--; + m_iSelected = m_iFocused; + + if( !m_bOpened ) + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + } + } + else + { + if( m_iFocused + 1 < ( int )GetNumItems() ) + { + m_iFocused++; + m_iSelected = m_iFocused; + + if( !m_bOpened ) + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); + } + } + } + return true; + } + }; + + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTComboBox::OnHotkey() +{ + if( m_bOpened ) + return; + + if( m_iSelected == -1 ) + return; + + if( m_pDialog->IsKeyboardInputEnabled() ) + m_pDialog->RequestFocus( this ); + + m_iSelected++; + + if( m_iSelected >= ( int )m_Items.GetSize() ) + m_iSelected = 0; + + m_iFocused = m_iSelected; + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTComboBox::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL; + + if( !m_bOpened ) + iState = DXUT_STATE_HIDDEN; + + // Dropdown box + CDXUTElement* pElement = m_Elements.GetAt( 2 ); + + // If we have not initialized the scroll bar page size, + // do that now. + static bool bSBInit; + if( !bSBInit ) + { + // Update the page size of the scroll bar + if( m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight ) + m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) / + m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight ); + else + m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) ); + bSBInit = true; + } + + // Scroll bar + if( m_bOpened ) + m_ScrollBar.Render( fElapsedTime ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime ); + pElement->FontColor.Blend( iState, fElapsedTime ); + + m_pDialog->DrawSprite( pElement, &m_rcDropdown, DXUT_NEAR_BUTTON_DEPTH ); + + // Selection outline + CDXUTElement* pSelectionElement = m_Elements.GetAt( 3 ); + pSelectionElement->TextureColor.Current = pElement->TextureColor.Current; + pSelectionElement->FontColor.Current = pSelectionElement->FontColor.States[ DXUT_STATE_NORMAL ]; + + DXUTFontNode* pFont = m_pDialog->GetFont( pElement->iFont ); + if( pFont ) + { + int curY = m_rcDropdownText.top; + int nRemainingHeight = RectHeight( m_rcDropdownText ); + //WCHAR strDropdown[4096] = {0}; + + for( int i = m_ScrollBar.GetTrackPos(); i < m_Items.GetSize(); i++ ) + { + DXUTComboBoxItem* pItem = m_Items.GetAt( i ); + + // Make sure there's room left in the dropdown + nRemainingHeight -= pFont->nHeight; + if( nRemainingHeight < 0 ) + { + pItem->bVisible = false; + continue; + } + + SetRect( &pItem->rcActive, m_rcDropdownText.left, curY, m_rcDropdownText.right, curY + pFont->nHeight ); + curY += pFont->nHeight; + + //debug + //int blue = 50 * i; + //m_pDialog->DrawRect( &pItem->rcActive, 0xFFFF0000 | blue ); + + pItem->bVisible = true; + + if( m_bOpened ) + { + if( ( int )i == m_iFocused ) + { + RECT rc; + SetRect( &rc, m_rcDropdown.left, pItem->rcActive.top - 2, m_rcDropdown.right, + pItem->rcActive.bottom + 2 ); + m_pDialog->DrawSprite( pSelectionElement, &rc, DXUT_NEAR_BUTTON_DEPTH ); + m_pDialog->DrawText( pItem->strText, pSelectionElement, &pItem->rcActive ); + } + else + { + m_pDialog->DrawText( pItem->strText, pElement, &pItem->rcActive ); + } + } + } + } + + int nOffsetX = 0; + int nOffsetY = 0; + + iState = DXUT_STATE_NORMAL; + + if( m_bVisible == false ) + iState = DXUT_STATE_HIDDEN; + else if( m_bEnabled == false ) + iState = DXUT_STATE_DISABLED; + else if( m_bPressed ) + { + iState = DXUT_STATE_PRESSED; + + nOffsetX = 1; + nOffsetY = 2; + } + else if( m_bMouseOver ) + { + iState = DXUT_STATE_MOUSEOVER; + + nOffsetX = -1; + nOffsetY = -2; + } + else if( m_bHasFocus ) + iState = DXUT_STATE_FOCUS; + + float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f; + + // Button + pElement = m_Elements.GetAt( 1 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + + RECT rcWindow = m_rcButton; + OffsetRect( &rcWindow, nOffsetX, nOffsetY ); + m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_FAR_BUTTON_DEPTH ); + + if( m_bOpened ) + iState = DXUT_STATE_PRESSED; + + // Main text box + //TODO: remove magic numbers + pElement = m_Elements.GetAt( 0 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate ); + + m_pDialog->DrawSprite( pElement, &m_rcText, DXUT_NEAR_BUTTON_DEPTH ); + + if( m_iSelected >= 0 && m_iSelected < ( int )m_Items.GetSize() ) + { + DXUTComboBoxItem* pItem = m_Items.GetAt( m_iSelected ); + if( pItem != NULL ) + { + m_pDialog->DrawText( pItem->strText, pElement, &m_rcText, false, -1, true ); + + } + } +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTComboBox::AddItem( const WCHAR* strText, void* pData ) +{ + // Validate parameters + if( strText == NULL ) + { + return E_INVALIDARG; + } + + // Create a new item and set the data + DXUTComboBoxItem* pItem = new DXUTComboBoxItem; + if( pItem == NULL ) + { + return DXTRACE_ERR_MSGBOX( L"new", E_OUTOFMEMORY ); + } + + ZeroMemory( pItem, sizeof( DXUTComboBoxItem ) ); + wcscpy_s( pItem->strText, 256, strText ); + pItem->pData = pData; + + m_Items.Add( pItem ); + + // Update the scroll bar with new range + m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() ); + + // If this is the only item in the list, it's selected + if( GetNumItems() == 1 ) + { + m_iSelected = 0; + m_iFocused = 0; + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this ); + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTComboBox::RemoveItem( UINT index ) +{ + DXUTComboBoxItem* pItem = m_Items.GetAt( index ); + SAFE_DELETE( pItem ); + m_Items.Remove( index ); + m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() ); + if( m_iSelected >= m_Items.GetSize() ) + m_iSelected = m_Items.GetSize() - 1; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTComboBox::RemoveAllItems() +{ + for( int i = 0; i < m_Items.GetSize(); i++ ) + { + DXUTComboBoxItem* pItem = m_Items.GetAt( i ); + SAFE_DELETE( pItem ); + } + + m_Items.RemoveAll(); + m_ScrollBar.SetTrackRange( 0, 1 ); + m_iFocused = m_iSelected = -1; +} + + + +//-------------------------------------------------------------------------------------- +bool CDXUTComboBox::ContainsItem( const WCHAR* strText, UINT iStart ) +{ + return ( -1 != FindItem( strText, iStart ) ); +} + + +//-------------------------------------------------------------------------------------- +int CDXUTComboBox::FindItem( const WCHAR* strText, UINT iStart ) +{ + if( strText == NULL ) + return -1; + + for( int i = iStart; i < m_Items.GetSize(); i++ ) + { + DXUTComboBoxItem* pItem = m_Items.GetAt( i ); + + if( 0 == wcscmp( pItem->strText, strText ) ) + { + return i; + } + } + + return -1; +} + + +//-------------------------------------------------------------------------------------- +void* CDXUTComboBox::GetSelectedData() +{ + if( m_iSelected < 0 ) + return NULL; + + DXUTComboBoxItem* pItem = m_Items.GetAt( m_iSelected ); + return pItem->pData; +} + + +//-------------------------------------------------------------------------------------- +DXUTComboBoxItem* CDXUTComboBox::GetSelectedItem() +{ + if( m_iSelected < 0 ) + return NULL; + + return m_Items.GetAt( m_iSelected ); +} + + +//-------------------------------------------------------------------------------------- +void* CDXUTComboBox::GetItemData( const WCHAR* strText ) +{ + int index = FindItem( strText ); + if( index == -1 ) + { + return NULL; + } + + DXUTComboBoxItem* pItem = m_Items.GetAt( index ); + if( pItem == NULL ) + { + DXTRACE_ERR( L"CGrowableArray::GetAt", E_FAIL ); + return NULL; + } + + return pItem->pData; +} + + +//-------------------------------------------------------------------------------------- +void* CDXUTComboBox::GetItemData( int nIndex ) +{ + if( nIndex < 0 || nIndex >= m_Items.GetSize() ) + return NULL; + + return m_Items.GetAt( nIndex )->pData; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTComboBox::SetSelectedByIndex( UINT index ) +{ + if( index >= GetNumItems() ) + return E_INVALIDARG; + + m_iFocused = m_iSelected = index; + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this ); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTComboBox::SetSelectedByText( const WCHAR* strText ) +{ + if( strText == NULL ) + return E_INVALIDARG; + + int index = FindItem( strText ); + if( index == -1 ) + return E_FAIL; + + m_iFocused = m_iSelected = index; + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this ); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTComboBox::SetSelectedByData( void* pData ) +{ + for( int i = 0; i < m_Items.GetSize(); i++ ) + { + DXUTComboBoxItem* pItem = m_Items.GetAt( i ); + + if( pItem->pData == pData ) + { + m_iFocused = m_iSelected = i; + m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this ); + return S_OK; + } + } + + return E_FAIL; +} + + + +//-------------------------------------------------------------------------------------- +CDXUTSlider::CDXUTSlider( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_SLIDER; + m_pDialog = pDialog; + + m_nMin = 0; + m_nMax = 100; + m_nValue = 50; + + m_bPressed = false; +} + + +//-------------------------------------------------------------------------------------- +BOOL CDXUTSlider::ContainsPoint( POINT pt ) +{ + return ( PtInRect( &m_rcBoundingBox, pt ) || + PtInRect( &m_rcButton, pt ) ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTSlider::UpdateRects() +{ + CDXUTControl::UpdateRects(); + + m_rcButton = m_rcBoundingBox; + m_rcButton.right = m_rcButton.left + RectHeight( m_rcButton ); + OffsetRect( &m_rcButton, -RectWidth( m_rcButton ) / 2, 0 ); + + m_nButtonX = ( int )( ( m_nValue - m_nMin ) * ( float )RectWidth( m_rcBoundingBox ) / ( m_nMax - m_nMin ) ); + OffsetRect( &m_rcButton, m_nButtonX, 0 ); +} + +int CDXUTSlider::ValueFromPos( int x ) +{ + float fValuePerPixel = ( float )( m_nMax - m_nMin ) / RectWidth( m_rcBoundingBox ); + return ( int )( 0.5f + m_nMin + fValuePerPixel * ( x - m_rcBoundingBox.left ) ); +} + +//-------------------------------------------------------------------------------------- +bool CDXUTSlider::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_KEYDOWN: + { + switch( wParam ) + { + case VK_HOME: + SetValueInternal( m_nMin, true ); + return true; + + case VK_END: + SetValueInternal( m_nMax, true ); + return true; + + case VK_LEFT: + case VK_DOWN: + SetValueInternal( m_nValue - 1, true ); + return true; + + case VK_RIGHT: + case VK_UP: + SetValueInternal( m_nValue + 1, true ); + return true; + + case VK_NEXT: + SetValueInternal( m_nValue - ( 10 > ( m_nMax - m_nMin ) / 10 ? 10 : ( m_nMax - m_nMin ) / 10 ), + true ); + return true; + + case VK_PRIOR: + SetValueInternal( m_nValue + ( 10 > ( m_nMax - m_nMin ) / 10 ? 10 : ( m_nMax - m_nMin ) / 10 ), + true ); + return true; + } + break; + } + } + + + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTSlider::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + if( PtInRect( &m_rcButton, pt ) ) + { + // Pressed while inside the control + m_bPressed = true; + SetCapture( DXUTGetHWND() ); + + m_nDragX = pt.x; + //m_nDragY = pt.y; + m_nDragOffset = m_nButtonX - m_nDragX; + + //m_nDragValue = m_nValue; + + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + return true; + } + + if( PtInRect( &m_rcBoundingBox, pt ) ) + { + m_nDragX = pt.x; + m_nDragOffset = 0; + m_bPressed = true; + + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + if( pt.x > m_nButtonX + m_x ) + { + SetValueInternal( m_nValue + 1, true ); + return true; + } + + if( pt.x < m_nButtonX + m_x ) + { + SetValueInternal( m_nValue - 1, true ); + return true; + } + } + + break; + } + + case WM_LBUTTONUP: + { + if( m_bPressed ) + { + m_bPressed = false; + ReleaseCapture(); + m_pDialog->SendEvent( EVENT_SLIDER_VALUE_CHANGED_UP, true, this ); + + return true; + } + + break; + } + + case WM_MOUSEMOVE: + { + if( m_bPressed ) + { + SetValueInternal( ValueFromPos( m_x + pt.x + m_nDragOffset ), true ); + return true; + } + + break; + } + + case WM_MOUSEWHEEL: + { + int nScrollAmount = int( ( short )HIWORD( wParam ) ) / WHEEL_DELTA; + SetValueInternal( m_nValue - nScrollAmount, true ); + return true; + } + }; + + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTSlider::SetRange( int nMin, int nMax ) +{ + m_nMin = nMin; + m_nMax = nMax; + + SetValueInternal( m_nValue, false ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTSlider::SetValueInternal( int nValue, bool bFromInput ) +{ + // Clamp to range + nValue = __max( m_nMin, nValue ); + nValue = __min( m_nMax, nValue ); + + if( nValue == m_nValue ) + return; + + m_nValue = nValue; + UpdateRects(); + + m_pDialog->SendEvent( EVENT_SLIDER_VALUE_CHANGED, bFromInput, this ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTSlider::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + + int nOffsetX = 0; + int nOffsetY = 0; + + DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL; + + if( m_bVisible == false ) + { + iState = DXUT_STATE_HIDDEN; + } + else if( m_bEnabled == false ) + { + iState = DXUT_STATE_DISABLED; + } + else if( m_bPressed ) + { + iState = DXUT_STATE_PRESSED; + + nOffsetX = 1; + nOffsetY = 2; + } + else if( m_bMouseOver ) + { + iState = DXUT_STATE_MOUSEOVER; + + nOffsetX = -1; + nOffsetY = -2; + } + else if( m_bHasFocus ) + { + iState = DXUT_STATE_FOCUS; + } + + float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f; + + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + m_pDialog->DrawSprite( pElement, &m_rcBoundingBox, DXUT_FAR_BUTTON_DEPTH ); + + //TODO: remove magic numbers + pElement = m_Elements.GetAt( 1 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_NEAR_BUTTON_DEPTH ); +} + + +//-------------------------------------------------------------------------------------- +// CDXUTScrollBar class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTScrollBar::CDXUTScrollBar( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_SCROLLBAR; + m_pDialog = pDialog; + + m_bShowThumb = true; + m_bDrag = false; + + SetRect( &m_rcUpButton, 0, 0, 0, 0 ); + SetRect( &m_rcDownButton, 0, 0, 0, 0 ); + SetRect( &m_rcTrack, 0, 0, 0, 0 ); + SetRect( &m_rcThumb, 0, 0, 0, 0 ); + m_nPosition = 0; + m_nPageSize = 1; + m_nStart = 0; + m_nEnd = 1; + m_Arrow = CLEAR; + m_dArrowTS = 0.0; +} + + +//-------------------------------------------------------------------------------------- +CDXUTScrollBar::~CDXUTScrollBar() +{ +} + + +//-------------------------------------------------------------------------------------- +void CDXUTScrollBar::UpdateRects() +{ + CDXUTControl::UpdateRects(); + + // Make the buttons square + + SetRect( &m_rcUpButton, m_rcBoundingBox.left, m_rcBoundingBox.top, + m_rcBoundingBox.right, m_rcBoundingBox.top + RectWidth( m_rcBoundingBox ) ); + SetRect( &m_rcDownButton, m_rcBoundingBox.left, m_rcBoundingBox.bottom - RectWidth( m_rcBoundingBox ), + m_rcBoundingBox.right, m_rcBoundingBox.bottom ); + SetRect( &m_rcTrack, m_rcUpButton.left, m_rcUpButton.bottom, + m_rcDownButton.right, m_rcDownButton.top ); + m_rcThumb.left = m_rcUpButton.left; + m_rcThumb.right = m_rcUpButton.right; + + UpdateThumbRect(); +} + + +//-------------------------------------------------------------------------------------- +// Compute the dimension of the scroll thumb +void CDXUTScrollBar::UpdateThumbRect() +{ + if( m_nEnd - m_nStart > m_nPageSize ) + { + int nThumbHeight = __max( RectHeight( m_rcTrack ) * m_nPageSize / ( m_nEnd - m_nStart ), + SCROLLBAR_MINTHUMBSIZE ); + int nMaxPosition = m_nEnd - m_nStart - m_nPageSize; + m_rcThumb.top = m_rcTrack.top + ( m_nPosition - m_nStart ) * ( RectHeight( m_rcTrack ) - nThumbHeight ) + / nMaxPosition; + m_rcThumb.bottom = m_rcThumb.top + nThumbHeight; + m_bShowThumb = true; + + } + else + { + // No content to scroll + m_rcThumb.bottom = m_rcThumb.top; + m_bShowThumb = false; + } +} + + +//-------------------------------------------------------------------------------------- +// Scroll() scrolls by nDelta items. A positive value scrolls down, while a negative +// value scrolls up. +void CDXUTScrollBar::Scroll( int nDelta ) +{ + // Perform scroll + m_nPosition += nDelta; + + // Cap position + Cap(); + + // Update thumb position + UpdateThumbRect(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTScrollBar::ShowItem( int nIndex ) +{ + // Cap the index + + if( nIndex < 0 ) + nIndex = 0; + + if( nIndex >= m_nEnd ) + nIndex = m_nEnd - 1; + + // Adjust position + + if( m_nPosition > nIndex ) + m_nPosition = nIndex; + else if( m_nPosition + m_nPageSize <= nIndex ) + m_nPosition = nIndex - m_nPageSize + 1; + + UpdateThumbRect(); +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTScrollBar::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTScrollBar::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + static int ThumbOffsetY; + + m_LastMouse = pt; + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + // Check for click on up button + + if( PtInRect( &m_rcUpButton, pt ) ) + { + SetCapture( DXUTGetHWND() ); + if( m_nPosition > m_nStart ) + --m_nPosition; + UpdateThumbRect(); + m_Arrow = CLICKED_UP; + m_dArrowTS = DXUTGetTime(); + return true; + } + + // Check for click on down button + + if( PtInRect( &m_rcDownButton, pt ) ) + { + SetCapture( DXUTGetHWND() ); + if( m_nPosition + m_nPageSize < m_nEnd ) + ++m_nPosition; + UpdateThumbRect(); + m_Arrow = CLICKED_DOWN; + m_dArrowTS = DXUTGetTime(); + return true; + } + + // Check for click on thumb + + if( PtInRect( &m_rcThumb, pt ) ) + { + SetCapture( DXUTGetHWND() ); + m_bDrag = true; + ThumbOffsetY = pt.y - m_rcThumb.top; + return true; + } + + // Check for click on track + + if( m_rcThumb.left <= pt.x && + m_rcThumb.right > pt.x ) + { + SetCapture( DXUTGetHWND() ); + if( m_rcThumb.top > pt.y && + m_rcTrack.top <= pt.y ) + { + Scroll( -( m_nPageSize - 1 ) ); + return true; + } + else if( m_rcThumb.bottom <= pt.y && + m_rcTrack.bottom > pt.y ) + { + Scroll( m_nPageSize - 1 ); + return true; + } + } + + break; + } + + case WM_LBUTTONUP: + { + m_bDrag = false; + ReleaseCapture(); + UpdateThumbRect(); + m_Arrow = CLEAR; + break; + } + + case WM_MOUSEMOVE: + { + if( m_bDrag ) + { + m_rcThumb.bottom += pt.y - ThumbOffsetY - m_rcThumb.top; + m_rcThumb.top = pt.y - ThumbOffsetY; + if( m_rcThumb.top < m_rcTrack.top ) + OffsetRect( &m_rcThumb, 0, m_rcTrack.top - m_rcThumb.top ); + else if( m_rcThumb.bottom > m_rcTrack.bottom ) + OffsetRect( &m_rcThumb, 0, m_rcTrack.bottom - m_rcThumb.bottom ); + + // Compute first item index based on thumb position + + int nMaxFirstItem = m_nEnd - m_nStart - m_nPageSize; // Largest possible index for first item + int nMaxThumb = RectHeight( m_rcTrack ) - RectHeight( m_rcThumb ); // Largest possible thumb position from the top + + m_nPosition = m_nStart + + ( m_rcThumb.top - m_rcTrack.top + + nMaxThumb / ( nMaxFirstItem * 2 ) ) * // Shift by half a row to avoid last row covered by only one pixel + nMaxFirstItem / nMaxThumb; + + return true; + } + + break; + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTScrollBar::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( WM_CAPTURECHANGED == uMsg ) + { + // The application just lost mouse capture. We may not have gotten + // the WM_MOUSEUP message, so reset m_bDrag here. + if( ( HWND )lParam != DXUTGetHWND() ) + m_bDrag = false; + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTScrollBar::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + + // Check if the arrow button has been held for a while. + // If so, update the thumb position to simulate repeated + // scroll. + if( m_Arrow != CLEAR ) + { + double dCurrTime = DXUTGetTime(); + if( PtInRect( &m_rcUpButton, m_LastMouse ) ) + { + switch( m_Arrow ) + { + case CLICKED_UP: + if( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS ) + { + Scroll( -1 ); + m_Arrow = HELD_UP; + m_dArrowTS = dCurrTime; + } + break; + case HELD_UP: + if( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS ) + { + Scroll( -1 ); + m_dArrowTS = dCurrTime; + } + break; + } + } + else if( PtInRect( &m_rcDownButton, m_LastMouse ) ) + { + switch( m_Arrow ) + { + case CLICKED_DOWN: + if( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS ) + { + Scroll( 1 ); + m_Arrow = HELD_DOWN; + m_dArrowTS = dCurrTime; + } + break; + case HELD_DOWN: + if( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS ) + { + Scroll( 1 ); + m_dArrowTS = dCurrTime; + } + break; + } + } + } + + DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL; + + if( m_bVisible == false ) + iState = DXUT_STATE_HIDDEN; + else if( m_bEnabled == false || m_bShowThumb == false ) + iState = DXUT_STATE_DISABLED; + else if( m_bMouseOver ) + iState = DXUT_STATE_MOUSEOVER; + else if( m_bHasFocus ) + iState = DXUT_STATE_FOCUS; + + + float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f; + + // Background track layer + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + m_pDialog->DrawSprite( pElement, &m_rcTrack, DXUT_FAR_BUTTON_DEPTH ); + + // Up Arrow + pElement = m_Elements.GetAt( 1 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + m_pDialog->DrawSprite( pElement, &m_rcUpButton, DXUT_NEAR_BUTTON_DEPTH ); + + // Down Arrow + pElement = m_Elements.GetAt( 2 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + m_pDialog->DrawSprite( pElement, &m_rcDownButton, DXUT_NEAR_BUTTON_DEPTH ); + + // Thumb button + pElement = m_Elements.GetAt( 3 ); + + // Blend current color + pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); + m_pDialog->DrawSprite( pElement, &m_rcThumb, DXUT_NEAR_BUTTON_DEPTH ); + +} + + +//-------------------------------------------------------------------------------------- +void CDXUTScrollBar::SetTrackRange( int nStart, int nEnd ) +{ + m_nStart = nStart; m_nEnd = nEnd; + Cap(); + UpdateThumbRect(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTScrollBar::Cap() // Clips position at boundaries. Ensures it stays within legal range. +{ + if( m_nPosition < m_nStart || + m_nEnd - m_nStart <= m_nPageSize ) + { + m_nPosition = m_nStart; + } + else if( m_nPosition + m_nPageSize > m_nEnd ) + m_nPosition = m_nEnd - m_nPageSize; +} + +//-------------------------------------------------------------------------------------- +// CDXUTListBox class +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTListBox::CDXUTListBox( CDXUTDialog* pDialog ) : m_ScrollBar( pDialog ) +{ + m_Type = DXUT_CONTROL_LISTBOX; + m_pDialog = pDialog; + + m_dwStyle = 0; + m_nSBWidth = 16; + m_nSelected = -1; + m_nSelStart = 0; + m_bDrag = false; + m_nBorder = 6; + m_nMargin = 5; + m_nTextHeight = 0; +} + + +//-------------------------------------------------------------------------------------- +CDXUTListBox::~CDXUTListBox() +{ + RemoveAllItems(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTListBox::UpdateRects() +{ + CDXUTControl::UpdateRects(); + + m_rcSelection = m_rcBoundingBox; + m_rcSelection.right -= m_nSBWidth; + InflateRect( &m_rcSelection, -m_nBorder, -m_nBorder ); + m_rcText = m_rcSelection; + InflateRect( &m_rcText, -m_nMargin, 0 ); + + // Update the scrollbar's rects + m_ScrollBar.SetLocation( m_rcBoundingBox.right - m_nSBWidth, m_rcBoundingBox.top ); + m_ScrollBar.SetSize( m_nSBWidth, m_height ); + DXUTFontNode* pFontNode = m_pDialog->GetManager()->GetFontNode( m_Elements.GetAt( 0 )->iFont ); + if( pFontNode && pFontNode->nHeight ) + { + m_ScrollBar.SetPageSize( RectHeight( m_rcText ) / pFontNode->nHeight ); + + // The selected item may have been scrolled off the page. + // Ensure that it is in page again. + m_ScrollBar.ShowItem( m_nSelected ); + } +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTListBox::AddItem( const WCHAR* wszText, void* pData ) +{ + DXUTListBoxItem* pNewItem = new DXUTListBoxItem; + if( !pNewItem ) + return E_OUTOFMEMORY; + + wcscpy_s( pNewItem->strText, 256, wszText ); + pNewItem->pData = pData; + SetRect( &pNewItem->rcActive, 0, 0, 0, 0 ); + pNewItem->bSelected = false; + + HRESULT hr = m_Items.Add( pNewItem ); + if( FAILED( hr ) ) + { + SAFE_DELETE( pNewItem ); + } + else + { + m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() ); + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTListBox::InsertItem( int nIndex, const WCHAR* wszText, void* pData ) +{ + DXUTListBoxItem* pNewItem = new DXUTListBoxItem; + if( !pNewItem ) + return E_OUTOFMEMORY; + + wcscpy_s( pNewItem->strText, 256, wszText ); + pNewItem->pData = pData; + SetRect( &pNewItem->rcActive, 0, 0, 0, 0 ); + pNewItem->bSelected = false; + + HRESULT hr = m_Items.Insert( nIndex, pNewItem ); + if( SUCCEEDED( hr ) ) + m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() ); + else + SAFE_DELETE( pNewItem ); + + return hr; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTListBox::RemoveItem( int nIndex ) +{ + if( nIndex < 0 || nIndex >= ( int )m_Items.GetSize() ) + return; + + DXUTListBoxItem* pItem = m_Items.GetAt( nIndex ); + + delete pItem; + m_Items.Remove( nIndex ); + m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() ); + if( m_nSelected >= ( int )m_Items.GetSize() ) + m_nSelected = m_Items.GetSize() - 1; + + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); +} + + + + + +//-------------------------------------------------------------------------------------- +void CDXUTListBox::RemoveAllItems() +{ + for( int i = 0; i < m_Items.GetSize(); ++i ) + { + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + delete pItem; + } + + m_Items.RemoveAll(); + m_ScrollBar.SetTrackRange( 0, 1 ); +} + + +//-------------------------------------------------------------------------------------- +DXUTListBoxItem* CDXUTListBox::GetItem( int nIndex ) +{ + if( nIndex < 0 || nIndex >= ( int )m_Items.GetSize() ) + return NULL; + + return m_Items[nIndex]; +} + + +//-------------------------------------------------------------------------------------- +// For single-selection listbox, returns the index of the selected item. +// For multi-selection, returns the first selected item after the nPreviousSelected position. +// To search for the first selected item, the app passes -1 for nPreviousSelected. For +// subsequent searches, the app passes the returned index back to GetSelectedIndex as. +// nPreviousSelected. +// Returns -1 on error or if no item is selected. +int CDXUTListBox::GetSelectedIndex( int nPreviousSelected ) +{ + if( nPreviousSelected < -1 ) + return -1; + + if( m_dwStyle & MULTISELECTION ) + { + // Multiple selection enabled. Search for the next item with the selected flag. + for( int i = nPreviousSelected + 1; i < ( int )m_Items.GetSize(); ++i ) + { + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + + if( pItem->bSelected ) + return i; + } + + return -1; + } + else + { + // Single selection + return m_nSelected; + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTListBox::SelectItem( int nNewIndex ) +{ + // If no item exists, do nothing. + if( m_Items.GetSize() == 0 ) + return; + + int nOldSelected = m_nSelected; + + // Adjust m_nSelected + m_nSelected = nNewIndex; + + // Perform capping + if( m_nSelected < 0 ) + m_nSelected = 0; + if( m_nSelected >= ( int )m_Items.GetSize() ) + m_nSelected = m_Items.GetSize() - 1; + + if( nOldSelected != m_nSelected ) + { + if( m_dwStyle & MULTISELECTION ) + { + m_Items[m_nSelected]->bSelected = true; + } + + // Update selection start + m_nSelStart = m_nSelected; + + // Adjust scroll bar + m_ScrollBar.ShowItem( m_nSelected ); + } + + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTListBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + // Let the scroll bar have a chance to handle it first + if( m_ScrollBar.HandleKeyboard( uMsg, wParam, lParam ) ) + return true; + + switch( uMsg ) + { + case WM_KEYDOWN: + switch( wParam ) + { + case VK_UP: + case VK_DOWN: + case VK_NEXT: + case VK_PRIOR: + case VK_HOME: + case VK_END: + { + // If no item exists, do nothing. + if( m_Items.GetSize() == 0 ) + return true; + + int nOldSelected = m_nSelected; + + // Adjust m_nSelected + switch( wParam ) + { + case VK_UP: + --m_nSelected; break; + case VK_DOWN: + ++m_nSelected; break; + case VK_NEXT: + m_nSelected += m_ScrollBar.GetPageSize() - 1; break; + case VK_PRIOR: + m_nSelected -= m_ScrollBar.GetPageSize() - 1; break; + case VK_HOME: + m_nSelected = 0; break; + case VK_END: + m_nSelected = m_Items.GetSize() - 1; break; + } + + // Perform capping + if( m_nSelected < 0 ) + m_nSelected = 0; + if( m_nSelected >= ( int )m_Items.GetSize() ) + m_nSelected = m_Items.GetSize() - 1; + + if( nOldSelected != m_nSelected ) + { + if( m_dwStyle & MULTISELECTION ) + { + // Multiple selection + + // Clear all selection + for( int i = 0; i < ( int )m_Items.GetSize(); ++i ) + { + DXUTListBoxItem* pItem = m_Items[i]; + pItem->bSelected = false; + } + + if( GetKeyState( VK_SHIFT ) < 0 ) + { + // Select all items from m_nSelStart to + // m_nSelected + int nEnd = __max( m_nSelStart, m_nSelected ); + + for( int n = __min( m_nSelStart, m_nSelected ); n <= nEnd; ++n ) + m_Items[n]->bSelected = true; + } + else + { + m_Items[m_nSelected]->bSelected = true; + + // Update selection start + m_nSelStart = m_nSelected; + } + } + else + m_nSelStart = m_nSelected; + + // Adjust scroll bar + + m_ScrollBar.ShowItem( m_nSelected ); + + // Send notification + + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); + } + return true; + } + + // Space is the hotkey for double-clicking an item. + // + case VK_SPACE: + m_pDialog->SendEvent( EVENT_LISTBOX_ITEM_DBLCLK, true, this ); + return true; + } + break; + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTListBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + // First acquire focus + if( WM_LBUTTONDOWN == uMsg ) + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + // Let the scroll bar handle it first. + if( m_ScrollBar.HandleMouse( uMsg, pt, wParam, lParam ) ) + return true; + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + // Check for clicks in the text area + if( m_Items.GetSize() > 0 && PtInRect( &m_rcSelection, pt ) ) + { + // Compute the index of the clicked item + + int nClicked; + if( m_nTextHeight ) + nClicked = m_ScrollBar.GetTrackPos() + ( pt.y - m_rcText.top ) / m_nTextHeight; + else + nClicked = -1; + + // Only proceed if the click falls on top of an item. + + if( nClicked >= m_ScrollBar.GetTrackPos() && + nClicked < ( int )m_Items.GetSize() && + nClicked < m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() ) + { + SetCapture( DXUTGetHWND() ); + m_bDrag = true; + + // If this is a double click, fire off an event and exit + // since the first click would have taken care of the selection + // updating. + if( uMsg == WM_LBUTTONDBLCLK ) + { + m_pDialog->SendEvent( EVENT_LISTBOX_ITEM_DBLCLK, true, this ); + return true; + } + + m_nSelected = nClicked; + if( !( wParam & MK_SHIFT ) ) + m_nSelStart = m_nSelected; + + // If this is a multi-selection listbox, update per-item + // selection data. + + if( m_dwStyle & MULTISELECTION ) + { + // Determine behavior based on the state of Shift and Ctrl + + DXUTListBoxItem* pSelItem = m_Items.GetAt( m_nSelected ); + if( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) == MK_CONTROL ) + { + // Control click. Reverse the selection of this item. + + pSelItem->bSelected = !pSelItem->bSelected; + } + else if( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) == MK_SHIFT ) + { + // Shift click. Set the selection for all items + // from last selected item to the current item. + // Clear everything else. + + int nBegin = __min( m_nSelStart, m_nSelected ); + int nEnd = __max( m_nSelStart, m_nSelected ); + + for( int i = 0; i < nBegin; ++i ) + { + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + pItem->bSelected = false; + } + + for( int i = nEnd + 1; i < ( int )m_Items.GetSize(); ++i ) + { + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + pItem->bSelected = false; + } + + for( int i = nBegin; i <= nEnd; ++i ) + { + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + pItem->bSelected = true; + } + } + else if( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) == ( MK_SHIFT | MK_CONTROL ) ) + { + // Control-Shift-click. + + // The behavior is: + // Set all items from m_nSelStart to m_nSelected to + // the same state as m_nSelStart, not including m_nSelected. + // Set m_nSelected to selected. + + int nBegin = __min( m_nSelStart, m_nSelected ); + int nEnd = __max( m_nSelStart, m_nSelected ); + + // The two ends do not need to be set here. + + bool bLastSelected = m_Items.GetAt( m_nSelStart )->bSelected; + for( int i = nBegin + 1; i < nEnd; ++i ) + { + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + pItem->bSelected = bLastSelected; + } + + pSelItem->bSelected = true; + + // Restore m_nSelected to the previous value + // This matches the Windows behavior + + m_nSelected = m_nSelStart; + } + else + { + // Simple click. Clear all items and select the clicked + // item. + + + for( int i = 0; i < ( int )m_Items.GetSize(); ++i ) + { + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + pItem->bSelected = false; + } + + pSelItem->bSelected = true; + } + } // End of multi-selection case + + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); + } + + return true; + } + break; + + case WM_LBUTTONUP: + { + ReleaseCapture(); + m_bDrag = false; + + if( m_nSelected != -1 ) + { + // Set all items between m_nSelStart and m_nSelected to + // the same state as m_nSelStart + int nEnd = __max( m_nSelStart, m_nSelected ); + + for( int n = __min( m_nSelStart, m_nSelected ) + 1; n < nEnd; ++n ) + m_Items[n]->bSelected = m_Items[m_nSelStart]->bSelected; + m_Items[m_nSelected]->bSelected = m_Items[m_nSelStart]->bSelected; + + // If m_nSelStart and m_nSelected are not the same, + // the user has dragged the mouse to make a selection. + // Notify the application of this. + if( m_nSelStart != m_nSelected ) + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); + + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION_END, true, this ); + } + return false; + } + + case WM_MOUSEMOVE: + if( m_bDrag ) + { + // Compute the index of the item below cursor + + int nItem; + if( m_nTextHeight ) + nItem = m_ScrollBar.GetTrackPos() + ( pt.y - m_rcText.top ) / m_nTextHeight; + else + nItem = -1; + + // Only proceed if the cursor is on top of an item. + + if( nItem >= ( int )m_ScrollBar.GetTrackPos() && + nItem < ( int )m_Items.GetSize() && + nItem < m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() ) + { + m_nSelected = nItem; + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); + } + else if( nItem < ( int )m_ScrollBar.GetTrackPos() ) + { + // User drags the mouse above window top + m_ScrollBar.Scroll( -1 ); + m_nSelected = m_ScrollBar.GetTrackPos(); + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); + } + else if( nItem >= m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() ) + { + // User drags the mouse below window bottom + m_ScrollBar.Scroll( 1 ); + m_nSelected = __min( ( int )m_Items.GetSize(), m_ScrollBar.GetTrackPos() + + m_ScrollBar.GetPageSize() ) - 1; + m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this ); + } + } + break; + + case WM_MOUSEWHEEL: + { + UINT uLines; + SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &uLines, 0 ); + int nScrollAmount = int( ( short )HIWORD( wParam ) ) / WHEEL_DELTA * uLines; + m_ScrollBar.Scroll( -nScrollAmount ); + return true; + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTListBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( WM_CAPTURECHANGED == uMsg ) + { + // The application just lost mouse capture. We may not have gotten + // the WM_MOUSEUP message, so reset m_bDrag here. + if( ( HWND )lParam != DXUTGetHWND() ) + m_bDrag = false; + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTListBox::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + + CDXUTElement* pElement = m_Elements.GetAt( 0 ); + pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime ); + pElement->FontColor.Blend( DXUT_STATE_NORMAL, fElapsedTime ); + + CDXUTElement* pSelElement = m_Elements.GetAt( 1 ); + pSelElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime ); + pSelElement->FontColor.Blend( DXUT_STATE_NORMAL, fElapsedTime ); + + m_pDialog->DrawSprite( pElement, &m_rcBoundingBox, DXUT_FAR_BUTTON_DEPTH ); + + // Render the text + if( m_Items.GetSize() > 0 ) + { + // Find out the height of a single line of text + RECT rc = m_rcText; + RECT rcSel = m_rcSelection; + rc.bottom = rc.top + m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight; + + // Update the line height formation + m_nTextHeight = rc.bottom - rc.top; + + static bool bSBInit; + if( !bSBInit ) + { + // Update the page size of the scroll bar + if( m_nTextHeight ) + m_ScrollBar.SetPageSize( RectHeight( m_rcText ) / m_nTextHeight ); + else + m_ScrollBar.SetPageSize( RectHeight( m_rcText ) ); + bSBInit = true; + } + + rc.right = m_rcText.right; + for( int i = m_ScrollBar.GetTrackPos(); i < ( int )m_Items.GetSize(); ++i ) + { + if( rc.bottom > m_rcText.bottom ) + break; + + DXUTListBoxItem* pItem = m_Items.GetAt( i ); + + // Determine if we need to render this item with the + // selected element. + bool bSelectedStyle = false; + + if( !( m_dwStyle & MULTISELECTION ) && i == m_nSelected ) + bSelectedStyle = true; + else if( m_dwStyle & MULTISELECTION ) + { + if( m_bDrag && + ( ( i >= m_nSelected && i < m_nSelStart ) || + ( i <= m_nSelected && i > m_nSelStart ) ) ) + bSelectedStyle = m_Items[m_nSelStart]->bSelected; + else if( pItem->bSelected ) + bSelectedStyle = true; + } + + if( bSelectedStyle ) + { + rcSel.top = rc.top; rcSel.bottom = rc.bottom; + m_pDialog->DrawSprite( pSelElement, &rcSel, DXUT_NEAR_BUTTON_DEPTH ); + m_pDialog->DrawText( pItem->strText, pSelElement, &rc ); + } + else + m_pDialog->DrawText( pItem->strText, pElement, &rc ); + + OffsetRect( &rc, 0, m_nTextHeight ); + } + } + + // Render the scroll bar + + m_ScrollBar.Render( fElapsedTime ); +} + + +// Static member initialization +HINSTANCE CUniBuffer::s_hDll = NULL; +HRESULT ( WINAPI*CUniBuffer::_ScriptApplyDigitSubstitution )( const SCRIPT_DIGITSUBSTITUTE*, SCRIPT_CONTROL*, + SCRIPT_STATE* ) = Dummy_ScriptApplyDigitSubstitution; +HRESULT ( WINAPI*CUniBuffer::_ScriptStringAnalyse )( HDC, const void*, int, int, int, DWORD, int, SCRIPT_CONTROL*, + SCRIPT_STATE*, const int*, SCRIPT_TABDEF*, const BYTE*, + SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringAnalyse; +HRESULT ( WINAPI*CUniBuffer::_ScriptStringCPtoX )( SCRIPT_STRING_ANALYSIS, int, BOOL, int* ) = Dummy_ScriptStringCPtoX; +HRESULT ( WINAPI*CUniBuffer::_ScriptStringXtoCP )( SCRIPT_STRING_ANALYSIS, int, int*, int* ) = Dummy_ScriptStringXtoCP; +HRESULT ( WINAPI*CUniBuffer::_ScriptStringFree )( SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringFree; +const SCRIPT_LOGATTR* ( WINAPI*CUniBuffer::_ScriptString_pLogAttr )( SCRIPT_STRING_ANALYSIS ) = + Dummy_ScriptString_pLogAttr; +const int* ( WINAPI*CUniBuffer::_ScriptString_pcOutChars )( SCRIPT_STRING_ANALYSIS ) = + Dummy_ScriptString_pcOutChars; +bool CDXUTEditBox::s_bHideCaret; // If true, we don't render the caret. + + + +//-------------------------------------------------------------------------------------- +// CDXUTEditBox class +//-------------------------------------------------------------------------------------- + +// When scrolling, EDITBOX_SCROLLEXTENT is reciprocal of the amount to scroll. +// If EDITBOX_SCROLLEXTENT = 4, then we scroll 1/4 of the control each time. +#define EDITBOX_SCROLLEXTENT 4 + +//-------------------------------------------------------------------------------------- +CDXUTEditBox::CDXUTEditBox( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_EDITBOX; + m_pDialog = pDialog; + + m_nBorder = 5; // Default border width + m_nSpacing = 4; // Default spacing + + m_bCaretOn = true; + m_dfBlink = GetCaretBlinkTime() * 0.001f; + m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime(); + s_bHideCaret = false; + m_nFirstVisible = 0; + m_TextColor = D3DCOLOR_ARGB( 255, 16, 16, 16 ); + m_SelTextColor = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + m_SelBkColor = D3DCOLOR_ARGB( 255, 40, 50, 92 ); + m_CaretColor = D3DCOLOR_ARGB( 255, 0, 0, 0 ); + m_nCaret = m_nSelStart = 0; + m_bInsertMode = true; + + m_bMouseDrag = false; +} + + +//-------------------------------------------------------------------------------------- +CDXUTEditBox::~CDXUTEditBox() +{ +} + + +//-------------------------------------------------------------------------------------- +// PlaceCaret: Set the caret to a character position, and adjust the scrolling if +// necessary. +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::PlaceCaret( int nCP ) +{ + assert( nCP >= 0 && nCP <= m_Buffer.GetTextSize() ); + m_nCaret = nCP; + + // Obtain the X offset of the character. + int nX1st, nX, nX2; + m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // 1st visible char + m_Buffer.CPtoX( nCP, FALSE, &nX ); // LEAD + // If nCP is the NULL terminator, get the leading edge instead of trailing. + if( nCP == m_Buffer.GetTextSize() ) + nX2 = nX; + else + m_Buffer.CPtoX( nCP, TRUE, &nX2 ); // TRAIL + + // If the left edge of the char is smaller than the left edge of the 1st visible char, + // we need to scroll left until this char is visible. + if( nX < nX1st ) + { + // Simply make the first visible character the char at the new caret position. + m_nFirstVisible = nCP; + } + else // If the right of the character is bigger than the offset of the control's + // right edge, we need to scroll right to this character. + if( nX2 > nX1st + RectWidth( m_rcText ) ) + { + // Compute the X of the new left-most pixel + int nXNewLeft = nX2 - RectWidth( m_rcText ); + + // Compute the char position of this character + int nCPNew1st, nNewTrail; + m_Buffer.XtoCP( nXNewLeft, &nCPNew1st, &nNewTrail ); + + // If this coordinate is not on a character border, + // start from the next character so that the caret + // position does not fall outside the text rectangle. + int nXNew1st; + m_Buffer.CPtoX( nCPNew1st, FALSE, &nXNew1st ); + if( nXNew1st < nXNewLeft ) + ++nCPNew1st; + + m_nFirstVisible = nCPNew1st; + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::ClearText() +{ + m_Buffer.Clear(); + m_nFirstVisible = 0; + PlaceCaret( 0 ); + m_nSelStart = 0; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::SetText( LPCWSTR wszText, bool bSelected ) +{ + assert( wszText != NULL ); + + m_Buffer.SetText( wszText ); + m_nFirstVisible = 0; + // Move the caret to the end of the text + PlaceCaret( m_Buffer.GetTextSize() ); + m_nSelStart = bSelected ? 0 : m_nCaret; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTEditBox::GetTextCopy( __out_ecount(bufferCount) LPWSTR strDest, + UINT bufferCount ) +{ + assert( strDest ); + + wcscpy_s( strDest, bufferCount, m_Buffer.GetBuffer() ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::DeleteSelectionText() +{ + int nFirst = __min( m_nCaret, m_nSelStart ); + int nLast = __max( m_nCaret, m_nSelStart ); + // Update caret and selection + PlaceCaret( nFirst ); + m_nSelStart = m_nCaret; + // Remove the characters + for( int i = nFirst; i < nLast; ++i ) + m_Buffer.RemoveChar( nFirst ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::UpdateRects() +{ + CDXUTControl::UpdateRects(); + + // Update the text rectangle + m_rcText = m_rcBoundingBox; + // First inflate by m_nBorder to compute render rects + InflateRect( &m_rcText, -m_nBorder, -m_nBorder ); + + // Update the render rectangles + m_rcRender[0] = m_rcText; + SetRect( &m_rcRender[1], m_rcBoundingBox.left, m_rcBoundingBox.top, m_rcText.left, m_rcText.top ); + SetRect( &m_rcRender[2], m_rcText.left, m_rcBoundingBox.top, m_rcText.right, m_rcText.top ); + SetRect( &m_rcRender[3], m_rcText.right, m_rcBoundingBox.top, m_rcBoundingBox.right, m_rcText.top ); + SetRect( &m_rcRender[4], m_rcBoundingBox.left, m_rcText.top, m_rcText.left, m_rcText.bottom ); + SetRect( &m_rcRender[5], m_rcText.right, m_rcText.top, m_rcBoundingBox.right, m_rcText.bottom ); + SetRect( &m_rcRender[6], m_rcBoundingBox.left, m_rcText.bottom, m_rcText.left, m_rcBoundingBox.bottom ); + SetRect( &m_rcRender[7], m_rcText.left, m_rcText.bottom, m_rcText.right, m_rcBoundingBox.bottom ); + SetRect( &m_rcRender[8], m_rcText.right, m_rcText.bottom, m_rcBoundingBox.right, m_rcBoundingBox.bottom ); + + // Inflate further by m_nSpacing + InflateRect( &m_rcText, -m_nSpacing, -m_nSpacing ); +} + + +void CDXUTEditBox::CopyToClipboard() +{ + // Copy the selection text to the clipboard + if( m_nCaret != m_nSelStart && OpenClipboard( NULL ) ) + { + EmptyClipboard(); + + HGLOBAL hBlock = GlobalAlloc( GMEM_MOVEABLE, sizeof( WCHAR ) * ( m_Buffer.GetTextSize() + 1 ) ); + if( hBlock ) + { + WCHAR* pwszText = ( WCHAR* )GlobalLock( hBlock ); + if( pwszText ) + { + int nFirst = __min( m_nCaret, m_nSelStart ); + int nLast = __max( m_nCaret, m_nSelStart ); + if( nLast - nFirst > 0 ) + CopyMemory( pwszText, m_Buffer.GetBuffer() + nFirst, ( nLast - nFirst ) * sizeof( WCHAR ) ); + pwszText[nLast - nFirst] = L'\0'; // Terminate it + GlobalUnlock( hBlock ); + } + SetClipboardData( CF_UNICODETEXT, hBlock ); + } + CloseClipboard(); + // We must not free the object until CloseClipboard is called. + if( hBlock ) + GlobalFree( hBlock ); + } +} + + +void CDXUTEditBox::PasteFromClipboard() +{ + DeleteSelectionText(); + + if( OpenClipboard( NULL ) ) + { + HANDLE handle = GetClipboardData( CF_UNICODETEXT ); + if( handle ) + { + // Convert the ANSI string to Unicode, then + // insert to our buffer. + WCHAR* pwszText = ( WCHAR* )GlobalLock( handle ); + if( pwszText ) + { + // Copy all characters up to null. + if( m_Buffer.InsertString( m_nCaret, pwszText ) ) + PlaceCaret( m_nCaret + lstrlenW( pwszText ) ); + m_nSelStart = m_nCaret; + GlobalUnlock( handle ); + } + } + CloseClipboard(); + } +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTEditBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + bool bHandled = false; + + switch( uMsg ) + { + case WM_KEYDOWN: + { + switch( wParam ) + { + case VK_TAB: + // We don't process Tab in case keyboard input is enabled and the user + // wishes to Tab to other controls. + break; + + case VK_HOME: + PlaceCaret( 0 ); + if( GetKeyState( VK_SHIFT ) >= 0 ) + // Shift is not down. Update selection + // start along with the caret. + m_nSelStart = m_nCaret; + ResetCaretBlink(); + bHandled = true; + break; + + case VK_END: + PlaceCaret( m_Buffer.GetTextSize() ); + if( GetKeyState( VK_SHIFT ) >= 0 ) + // Shift is not down. Update selection + // start along with the caret. + m_nSelStart = m_nCaret; + ResetCaretBlink(); + bHandled = true; + break; + + case VK_INSERT: + if( GetKeyState( VK_CONTROL ) < 0 ) + { + // Control Insert. Copy to clipboard + CopyToClipboard(); + } + else if( GetKeyState( VK_SHIFT ) < 0 ) + { + // Shift Insert. Paste from clipboard + PasteFromClipboard(); + } + else + { + // Toggle caret insert mode + m_bInsertMode = !m_bInsertMode; + } + break; + + case VK_DELETE: + // Check if there is a text selection. + if( m_nCaret != m_nSelStart ) + { + DeleteSelectionText(); + m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); + } + else + { + // Deleting one character + if( m_Buffer.RemoveChar( m_nCaret ) ) + m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); + } + ResetCaretBlink(); + bHandled = true; + break; + + case VK_LEFT: + if( GetKeyState( VK_CONTROL ) < 0 ) + { + // Control is down. Move the caret to a new item + // instead of a character. + m_Buffer.GetPriorItemPos( m_nCaret, &m_nCaret ); + PlaceCaret( m_nCaret ); + } + else if( m_nCaret > 0 ) + PlaceCaret( m_nCaret - 1 ); + if( GetKeyState( VK_SHIFT ) >= 0 ) + // Shift is not down. Update selection + // start along with the caret. + m_nSelStart = m_nCaret; + ResetCaretBlink(); + bHandled = true; + break; + + case VK_RIGHT: + if( GetKeyState( VK_CONTROL ) < 0 ) + { + // Control is down. Move the caret to a new item + // instead of a character. + m_Buffer.GetNextItemPos( m_nCaret, &m_nCaret ); + PlaceCaret( m_nCaret ); + } + else if( m_nCaret < m_Buffer.GetTextSize() ) + PlaceCaret( m_nCaret + 1 ); + if( GetKeyState( VK_SHIFT ) >= 0 ) + // Shift is not down. Update selection + // start along with the caret. + m_nSelStart = m_nCaret; + ResetCaretBlink(); + bHandled = true; + break; + + case VK_UP: + case VK_DOWN: + // Trap up and down arrows so that the dialog + // does not switch focus to another control. + bHandled = true; + break; + + default: + bHandled = wParam != VK_ESCAPE; // Let the application handle Esc. + } + } + } + return bHandled; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTEditBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + if( !m_bHasFocus ) + m_pDialog->RequestFocus( this ); + + if( !ContainsPoint( pt ) ) + return false; + + m_bMouseDrag = true; + SetCapture( DXUTGetHWND() ); + // Determine the character corresponding to the coordinates. + int nCP, nTrail, nX1st; + m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // X offset of the 1st visible char + if( SUCCEEDED( m_Buffer.XtoCP( pt.x - m_rcText.left + nX1st, &nCP, &nTrail ) ) ) + { + // Cap at the NULL character. + if( nTrail && nCP < m_Buffer.GetTextSize() ) + PlaceCaret( nCP + 1 ); + else + PlaceCaret( nCP ); + m_nSelStart = m_nCaret; + ResetCaretBlink(); + } + return true; + } + + case WM_LBUTTONUP: + ReleaseCapture(); + m_bMouseDrag = false; + break; + + case WM_MOUSEMOVE: + if( m_bMouseDrag ) + { + // Determine the character corresponding to the coordinates. + int nCP, nTrail, nX1st; + m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // X offset of the 1st visible char + if( SUCCEEDED( m_Buffer.XtoCP( pt.x - m_rcText.left + nX1st, &nCP, &nTrail ) ) ) + { + // Cap at the NULL character. + if( nTrail && nCP < m_Buffer.GetTextSize() ) + PlaceCaret( nCP + 1 ); + else + PlaceCaret( nCP ); + } + } + break; + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::OnFocusIn() +{ + CDXUTControl::OnFocusIn(); + + ResetCaretBlink(); +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + // Make sure that while editing, the keyup and keydown messages associated with + // WM_CHAR messages don't go to any non-focused controls or cameras + case WM_KEYUP: + case WM_KEYDOWN: + return true; + + case WM_CHAR: + { + switch( ( WCHAR )wParam ) + { + // Backspace + case VK_BACK: + { + // If there's a selection, treat this + // like a delete key. + if( m_nCaret != m_nSelStart ) + { + DeleteSelectionText(); + m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); + } + else if( m_nCaret > 0 ) + { + // Move the caret, then delete the char. + PlaceCaret( m_nCaret - 1 ); + m_nSelStart = m_nCaret; + m_Buffer.RemoveChar( m_nCaret ); + m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); + } + ResetCaretBlink(); + break; + } + + case 24: // Ctrl-X Cut + case VK_CANCEL: // Ctrl-C Copy + { + CopyToClipboard(); + + // If the key is Ctrl-X, delete the selection too. + if( ( WCHAR )wParam == 24 ) + { + DeleteSelectionText(); + m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); + } + + break; + } + + // Ctrl-V Paste + case 22: + { + PasteFromClipboard(); + m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); + break; + } + + // Ctrl-A Select All + case 1: + if( m_nSelStart == m_nCaret ) + { + m_nSelStart = 0; + PlaceCaret( m_Buffer.GetTextSize() ); + } + break; + + case VK_RETURN: + // Invoke the callback when the user presses Enter. + m_pDialog->SendEvent( EVENT_EDITBOX_STRING, true, this ); + break; + + // Junk characters we don't want in the string + case 26: // Ctrl Z + case 2: // Ctrl B + case 14: // Ctrl N + case 19: // Ctrl S + case 4: // Ctrl D + case 6: // Ctrl F + case 7: // Ctrl G + case 10: // Ctrl J + case 11: // Ctrl K + case 12: // Ctrl L + case 17: // Ctrl Q + case 23: // Ctrl W + case 5: // Ctrl E + case 18: // Ctrl R + case 20: // Ctrl T + case 25: // Ctrl Y + case 21: // Ctrl U + case 9: // Ctrl I + case 15: // Ctrl O + case 16: // Ctrl P + case 27: // Ctrl [ + case 29: // Ctrl ] + case 28: // Ctrl \ + break; + + default: + { + // If there's a selection and the user + // starts to type, the selection should + // be deleted. + if( m_nCaret != m_nSelStart ) + DeleteSelectionText(); + + // If we are in overwrite mode and there is already + // a char at the caret's position, simply replace it. + // Otherwise, we insert the char as normal. + if( !m_bInsertMode && m_nCaret < m_Buffer.GetTextSize() ) + { + m_Buffer[m_nCaret] = ( WCHAR )wParam; + PlaceCaret( m_nCaret + 1 ); + m_nSelStart = m_nCaret; + } + else + { + // Insert the char + if( m_Buffer.InsertChar( m_nCaret, ( WCHAR )wParam ) ) + { + PlaceCaret( m_nCaret + 1 ); + m_nSelStart = m_nCaret; + } + } + ResetCaretBlink(); + m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); + } + } + return true; + } + } + return false; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + + HRESULT hr; + int nSelStartX = 0, nCaretX = 0; // Left and right X cordinates of the selection region + + CDXUTElement* pElement = GetElement( 0 ); + if( pElement ) + { + m_Buffer.SetFontNode( m_pDialog->GetFont( pElement->iFont ) ); + PlaceCaret( m_nCaret ); // Call PlaceCaret now that we have the font info (node), + // so that scrolling can be handled. + } + + // Render the control graphics + for( int e = 0; e < 9; ++e ) + { + pElement = m_Elements.GetAt( e ); + pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime ); + + m_pDialog->DrawSprite( pElement, &m_rcRender[e], DXUT_FAR_BUTTON_DEPTH ); + } + + // + // Compute the X coordinates of the first visible character. + // + int nXFirst; + m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst ); + + // + // Compute the X coordinates of the selection rectangle + // + hr = m_Buffer.CPtoX( m_nCaret, FALSE, &nCaretX ); + if( m_nCaret != m_nSelStart ) + hr = m_Buffer.CPtoX( m_nSelStart, FALSE, &nSelStartX ); + else + nSelStartX = nCaretX; + + // + // Render the selection rectangle + // + RECT rcSelection; // Make this available for rendering selected text + if( m_nCaret != m_nSelStart ) + { + int nSelLeftX = nCaretX, nSelRightX = nSelStartX; + // Swap if left is bigger than right + if( nSelLeftX > nSelRightX ) + { + int nTemp = nSelLeftX; nSelLeftX = nSelRightX; nSelRightX = nTemp; + } + + SetRect( &rcSelection, nSelLeftX, m_rcText.top, nSelRightX, m_rcText.bottom ); + OffsetRect( &rcSelection, m_rcText.left - nXFirst, 0 ); + IntersectRect( &rcSelection, &m_rcText, &rcSelection ); + + IDirect3DDevice9* pd3dDevice = m_pDialog->GetManager()->GetD3D9Device(); + if( pd3dDevice ) + pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); + m_pDialog->DrawRect( &rcSelection, m_SelBkColor ); + if( pd3dDevice ) + pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); + } + + // + // Render the text + // + // Element 0 for text + m_Elements.GetAt( 0 )->FontColor.Current = m_TextColor; + m_pDialog->DrawText( m_Buffer.GetBuffer() + m_nFirstVisible, m_Elements.GetAt( 0 ), &m_rcText ); + + // Render the selected text + if( m_nCaret != m_nSelStart ) + { + int nFirstToRender = __max( m_nFirstVisible, __min( m_nSelStart, m_nCaret ) ); + int nNumChatToRender = __max( m_nSelStart, m_nCaret ) - nFirstToRender; + m_Elements.GetAt( 0 )->FontColor.Current = m_SelTextColor; + m_pDialog->DrawText( m_Buffer.GetBuffer() + nFirstToRender, + m_Elements.GetAt( 0 ), &rcSelection, false, nNumChatToRender ); + } + + // + // Blink the caret + // + if( DXUTGetGlobalTimer()->GetAbsoluteTime() - m_dfLastBlink >= m_dfBlink ) + { + m_bCaretOn = !m_bCaretOn; + m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime(); + } + + // + // Render the caret if this control has the focus + // + if( m_bHasFocus && m_bCaretOn && !s_bHideCaret ) + { + // Start the rectangle with insert mode caret + RECT rcCaret = + { + m_rcText.left - nXFirst + nCaretX - 1, m_rcText.top, + m_rcText.left - nXFirst + nCaretX + 1, m_rcText.bottom + }; + + // If we are in overwrite mode, adjust the caret rectangle + // to fill the entire character. + if( !m_bInsertMode ) + { + // Obtain the right edge X coord of the current character + int nRightEdgeX; + m_Buffer.CPtoX( m_nCaret, TRUE, &nRightEdgeX ); + rcCaret.right = m_rcText.left - nXFirst + nRightEdgeX; + } + + m_pDialog->DrawRect( &rcCaret, m_CaretColor ); + } +} + + +#define IN_FLOAT_CHARSET( c ) \ + ( (c) == L'-' || (c) == L'.' || ( (c) >= L'0' && (c) <= L'9' ) ) + +void CDXUTEditBox::ParseFloatArray( float* pNumbers, int nCount ) +{ + int nWritten = 0; // Number of floats written + const WCHAR* pToken, *pEnd; + WCHAR wszToken[60]; + + pToken = m_Buffer.GetBuffer(); + while( nWritten < nCount && *pToken != L'\0' ) + { + // Skip leading spaces + while( *pToken == L' ' ) + ++pToken; + + if( *pToken == L'\0' ) + break; + + // Locate the end of number + pEnd = pToken; + while( IN_FLOAT_CHARSET( *pEnd ) ) + ++pEnd; + + // Copy the token to our buffer + int nTokenLen = __min( sizeof( wszToken ) / sizeof( wszToken[0] ) - 1, int( pEnd - pToken ) ); + wcscpy_s( wszToken, nTokenLen, pToken ); + *pNumbers = ( float )wcstod( wszToken, NULL ); + ++nWritten; + ++pNumbers; + pToken = pEnd; + } +} + + +void CDXUTEditBox::SetTextFloatArray( const float* pNumbers, int nCount ) +{ + WCHAR wszBuffer[512] = + { + 0 + }; + WCHAR wszTmp[64]; + + if( pNumbers == NULL ) + return; + + for( int i = 0; i < nCount; ++i ) + { + swprintf_s( wszTmp, 64, L"%.4f ", pNumbers[i] ); + wcscat_s( wszBuffer, 512, wszTmp ); + } + + // Don't want the last space + if( nCount > 0 && wcslen( wszBuffer ) > 0 ) + wszBuffer[wcslen( wszBuffer ) - 1] = 0; + + SetText( wszBuffer ); +} + + + + +//-------------------------------------------------------------------------------------- +void CUniBuffer::Initialize() +{ + if( s_hDll ) // Only need to do once + return; + + s_hDll = LoadLibrary( UNISCRIBE_DLLNAME ); + if( s_hDll ) + { + FARPROC Temp; + GETPROCADDRESS( s_hDll, ScriptApplyDigitSubstitution, Temp ); + GETPROCADDRESS( s_hDll, ScriptStringAnalyse, Temp ); + GETPROCADDRESS( s_hDll, ScriptStringCPtoX, Temp ); + GETPROCADDRESS( s_hDll, ScriptStringXtoCP, Temp ); + GETPROCADDRESS( s_hDll, ScriptStringFree, Temp ); + GETPROCADDRESS( s_hDll, ScriptString_pLogAttr, Temp ); + GETPROCADDRESS( s_hDll, ScriptString_pcOutChars, Temp ); + } +} + + +//-------------------------------------------------------------------------------------- +void CUniBuffer::Uninitialize() +{ + if( s_hDll ) + { + PLACEHOLDERPROC( ScriptApplyDigitSubstitution ); + PLACEHOLDERPROC( ScriptStringAnalyse ); + PLACEHOLDERPROC( ScriptStringCPtoX ); + PLACEHOLDERPROC( ScriptStringXtoCP ); + PLACEHOLDERPROC( ScriptStringFree ); + PLACEHOLDERPROC( ScriptString_pLogAttr ); + PLACEHOLDERPROC( ScriptString_pcOutChars ); + + FreeLibrary( s_hDll ); + s_hDll = NULL; + } +} + + +//-------------------------------------------------------------------------------------- +bool CUniBuffer::SetBufferSize( int nNewSize ) +{ + // If the current size is already the maximum allowed, + // we can't possibly allocate more. + if( m_nBufferSize == DXUT_MAX_EDITBOXLENGTH ) + return false; + + int nAllocateSize = ( nNewSize == -1 || nNewSize < m_nBufferSize * 2 ) ? ( m_nBufferSize ? m_nBufferSize * + 2 : 256 ) : nNewSize * 2; + + // Cap the buffer size at the maximum allowed. + if( nAllocateSize > DXUT_MAX_EDITBOXLENGTH ) + nAllocateSize = DXUT_MAX_EDITBOXLENGTH; + + WCHAR* pTempBuffer = new WCHAR[nAllocateSize]; + if( !pTempBuffer ) + return false; + + ZeroMemory( pTempBuffer, sizeof( WCHAR ) * nAllocateSize ); + + if( m_pwszBuffer ) + { + CopyMemory( pTempBuffer, m_pwszBuffer, m_nBufferSize * sizeof( WCHAR ) ); + delete[] m_pwszBuffer; + } + + m_pwszBuffer = pTempBuffer; + m_nBufferSize = nAllocateSize; + return true; +} + + +//-------------------------------------------------------------------------------------- +// Uniscribe -- Analyse() analyses the string in the buffer +//-------------------------------------------------------------------------------------- +HRESULT CUniBuffer::Analyse() +{ + if( m_Analysis ) + _ScriptStringFree( &m_Analysis ); + + SCRIPT_CONTROL ScriptControl; // For uniscribe + SCRIPT_STATE ScriptState; // For uniscribe + ZeroMemory( &ScriptControl, sizeof( ScriptControl ) ); + ZeroMemory( &ScriptState, sizeof( ScriptState ) ); + _ScriptApplyDigitSubstitution( NULL, &ScriptControl, &ScriptState ); + + if( !m_pFontNode ) + return E_FAIL; + + HDC hDC = + ( m_pFontNode->pFont9 ? m_pFontNode->pFont9->GetDC() : NULL ); + HRESULT hr = _ScriptStringAnalyse( hDC, + m_pwszBuffer, + lstrlenW( m_pwszBuffer ) + 1, // NULL is also analyzed. + lstrlenW( m_pwszBuffer ) * 3 / 2 + 16, + -1, + SSA_BREAK | SSA_GLYPHS | SSA_FALLBACK | SSA_LINK, + 0, + &ScriptControl, + &ScriptState, + NULL, + NULL, + NULL, + &m_Analysis ); + if( SUCCEEDED( hr ) ) + m_bAnalyseRequired = false; // Analysis is up-to-date + return hr; +} + + +//-------------------------------------------------------------------------------------- +CUniBuffer::CUniBuffer( int nInitialSize ) +{ + CUniBuffer::Initialize(); // ensure static vars are properly init'ed first + + m_nBufferSize = 0; + m_pwszBuffer = NULL; + m_bAnalyseRequired = true; + m_Analysis = NULL; + m_pFontNode = NULL; + + if( nInitialSize > 0 ) + SetBufferSize( nInitialSize ); +} + + +//-------------------------------------------------------------------------------------- +CUniBuffer::~CUniBuffer() +{ + delete[] m_pwszBuffer; + if( m_Analysis ) + _ScriptStringFree( &m_Analysis ); +} + + +//-------------------------------------------------------------------------------------- +WCHAR& CUniBuffer::operator[]( int n ) // No param checking +{ + // This version of operator[] is called only + // if we are asking for write access, so + // re-analysis is required. + m_bAnalyseRequired = true; + return m_pwszBuffer[n]; +} + + +//-------------------------------------------------------------------------------------- +void CUniBuffer::Clear() +{ + *m_pwszBuffer = L'\0'; + m_bAnalyseRequired = true; +} + + +//-------------------------------------------------------------------------------------- +// Inserts the char at specified index. +// If nIndex == -1, insert to the end. +//-------------------------------------------------------------------------------------- +bool CUniBuffer::InsertChar( int nIndex, WCHAR wChar ) +{ + assert( nIndex >= 0 ); + + if( nIndex < 0 || nIndex > lstrlenW( m_pwszBuffer ) ) + return false; // invalid index + + // Check for maximum length allowed + if( GetTextSize() + 1 >= DXUT_MAX_EDITBOXLENGTH ) + return false; + + if( lstrlenW( m_pwszBuffer ) + 1 >= m_nBufferSize ) + { + if( !SetBufferSize( -1 ) ) + return false; // out of memory + } + + assert( m_nBufferSize >= 2 ); + + // Shift the characters after the index, start by copying the null terminator + WCHAR* dest = m_pwszBuffer + lstrlenW( m_pwszBuffer ) + 1; + WCHAR* stop = m_pwszBuffer + nIndex; + WCHAR* src = dest - 1; + + while( dest > stop ) + { + *dest-- = *src--; + } + + // Set new character + m_pwszBuffer[ nIndex ] = wChar; + m_bAnalyseRequired = true; + + return true; +} + + +//-------------------------------------------------------------------------------------- +// Removes the char at specified index. +// If nIndex == -1, remove the last char. +//-------------------------------------------------------------------------------------- +bool CUniBuffer::RemoveChar( int nIndex ) +{ + if( !lstrlenW( m_pwszBuffer ) || nIndex < 0 || nIndex >= lstrlenW( m_pwszBuffer ) ) + return false; // Invalid index + + MoveMemory( m_pwszBuffer + nIndex, m_pwszBuffer + nIndex + 1, sizeof( WCHAR ) * + ( lstrlenW( m_pwszBuffer ) - nIndex ) ); + m_bAnalyseRequired = true; + return true; +} + + +//-------------------------------------------------------------------------------------- +// Inserts the first nCount characters of the string pStr at specified index. +// If nCount == -1, the entire string is inserted. +// If nIndex == -1, insert to the end. +//-------------------------------------------------------------------------------------- +bool CUniBuffer::InsertString( int nIndex, const WCHAR* pStr, int nCount ) +{ + assert( nIndex >= 0 ); + if( nIndex < 0 ) + return false; + + if( nIndex > lstrlenW( m_pwszBuffer ) ) + return false; // invalid index + + if( -1 == nCount ) + nCount = lstrlenW( pStr ); + + // Check for maximum length allowed + if( GetTextSize() + nCount >= DXUT_MAX_EDITBOXLENGTH ) + return false; + + if( lstrlenW( m_pwszBuffer ) + nCount >= m_nBufferSize ) + { + if( !SetBufferSize( lstrlenW( m_pwszBuffer ) + nCount + 1 ) ) + return false; // out of memory + } + + MoveMemory( m_pwszBuffer + nIndex + nCount, m_pwszBuffer + nIndex, sizeof( WCHAR ) * + ( lstrlenW( m_pwszBuffer ) - nIndex + 1 ) ); + CopyMemory( m_pwszBuffer + nIndex, pStr, nCount * sizeof( WCHAR ) ); + m_bAnalyseRequired = true; + + return true; +} + + +//-------------------------------------------------------------------------------------- +bool CUniBuffer::SetText( LPCWSTR wszText ) +{ + assert( wszText != NULL ); + + int nRequired = int( wcslen( wszText ) + 1 ); + + // Check for maximum length allowed + if( nRequired >= DXUT_MAX_EDITBOXLENGTH ) + return false; + + while( GetBufferSize() < nRequired ) + if( !SetBufferSize( -1 ) ) + break; + // Check again in case out of memory occurred inside while loop. + if( GetBufferSize() >= nRequired ) + { + wcscpy_s( m_pwszBuffer, GetBufferSize(), wszText ); + m_bAnalyseRequired = true; + return true; + } + else + return false; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CUniBuffer::CPtoX( int nCP, BOOL bTrail, int* pX ) +{ + assert( pX ); + *pX = 0; // Default + + HRESULT hr = S_OK; + if( m_bAnalyseRequired ) + hr = Analyse(); + + if( SUCCEEDED( hr ) ) + hr = _ScriptStringCPtoX( m_Analysis, nCP, bTrail, pX ); + + return hr; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CUniBuffer::XtoCP( int nX, int* pCP, int* pnTrail ) +{ + assert( pCP && pnTrail ); + *pCP = 0; *pnTrail = FALSE; // Default + + HRESULT hr = S_OK; + if( m_bAnalyseRequired ) + hr = Analyse(); + + if( SUCCEEDED( hr ) ) + hr = _ScriptStringXtoCP( m_Analysis, nX, pCP, pnTrail ); + + // If the coordinate falls outside the text region, we + // can get character positions that don't exist. We must + // filter them here and convert them to those that do exist. + if( *pCP == -1 && *pnTrail == TRUE ) + { + *pCP = 0; *pnTrail = FALSE; + } + else if( *pCP > lstrlenW( m_pwszBuffer ) && *pnTrail == FALSE ) + { + *pCP = lstrlenW( m_pwszBuffer ); *pnTrail = TRUE; + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +void CUniBuffer::GetPriorItemPos( int nCP, int* pPrior ) +{ + *pPrior = nCP; // Default is the char itself + + if( m_bAnalyseRequired ) + if( FAILED( Analyse() ) ) + return; + + const SCRIPT_LOGATTR* pLogAttr = _ScriptString_pLogAttr( m_Analysis ); + if( !pLogAttr ) + return; + + if( !_ScriptString_pcOutChars( m_Analysis ) ) + return; + int nInitial = *_ScriptString_pcOutChars( m_Analysis ); + if( nCP - 1 < nInitial ) + nInitial = nCP - 1; + for( int i = nInitial; i > 0; --i ) + if( pLogAttr[i].fWordStop || // Either the fWordStop flag is set + ( !pLogAttr[i].fWhiteSpace && // Or the previous char is whitespace but this isn't. + pLogAttr[i - 1].fWhiteSpace ) ) + { + *pPrior = i; + return; + } + // We have reached index 0. 0 is always a break point, so simply return it. + *pPrior = 0; +} + + +//-------------------------------------------------------------------------------------- +void CUniBuffer::GetNextItemPos( int nCP, int* pPrior ) +{ + *pPrior = nCP; // Default is the char itself + + HRESULT hr = S_OK; + if( m_bAnalyseRequired ) + hr = Analyse(); + if( FAILED( hr ) ) + return; + + const SCRIPT_LOGATTR* pLogAttr = _ScriptString_pLogAttr( m_Analysis ); + if( !pLogAttr ) + return; + + if( !_ScriptString_pcOutChars( m_Analysis ) ) + return; + int nInitial = *_ScriptString_pcOutChars( m_Analysis ); + if( nCP + 1 < nInitial ) + nInitial = nCP + 1; + + int i = nInitial; + int limit = *_ScriptString_pcOutChars( m_Analysis ); + while( limit > 0 && i < limit - 1 ) + { + if( pLogAttr[i].fWordStop ) // Either the fWordStop flag is set + { + *pPrior = i; + return; + } + else if( pLogAttr[i].fWhiteSpace && // Or this whitespace but the next char isn't. + !pLogAttr[i + 1].fWhiteSpace ) + { + *pPrior = i + 1; // The next char is a word stop + return; + } + + ++i; + limit = *_ScriptString_pcOutChars( m_Analysis ); + } + // We have reached the end. It's always a word stop, so simply return it. + *pPrior = *_ScriptString_pcOutChars( m_Analysis ) - 1; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTEditBox::ResetCaretBlink() +{ + m_bCaretOn = true; + m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime(); +} + + +//-------------------------------------------------------------------------------------- +void DXUTBlendColor::Init( D3DCOLOR defaultColor, D3DCOLOR disabledColor, D3DCOLOR hiddenColor ) +{ + for( int i = 0; i < MAX_CONTROL_STATES; i++ ) + { + States[ i ] = defaultColor; + } + + States[ DXUT_STATE_DISABLED ] = disabledColor; + States[ DXUT_STATE_HIDDEN ] = hiddenColor; + Current = hiddenColor; +} + + +//-------------------------------------------------------------------------------------- +void DXUTBlendColor::Blend( UINT iState, float fElapsedTime, float fRate ) +{ + D3DXCOLOR destColor = States[ iState ]; + D3DXColorLerp( &Current, &Current, &destColor, 1.0f - powf( fRate, 30 * fElapsedTime ) ); +} + + + +//-------------------------------------------------------------------------------------- +void CDXUTElement::SetTexture( UINT iTexture, RECT* prcTexture, D3DCOLOR defaultTextureColor ) +{ + this->iTexture = iTexture; + + if( prcTexture ) + rcTexture = *prcTexture; + else + SetRectEmpty( &rcTexture ); + + TextureColor.Init( defaultTextureColor ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTElement::SetFont( UINT iFont, D3DCOLOR defaultFontColor, DWORD dwTextFormat ) +{ + this->iFont = iFont; + this->dwTextFormat = dwTextFormat; + + FontColor.Init( defaultFontColor ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTElement::Refresh() +{ + TextureColor.Current = TextureColor.States[ DXUT_STATE_HIDDEN ]; + FontColor.Current = FontColor.States[ DXUT_STATE_HIDDEN ]; +} + + diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.h b/Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.h new file mode 100644 index 0000000..765020b --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTgui.h @@ -0,0 +1,1383 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTgui.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_GUI_H +#define DXUT_GUI_H + +#include +#include + + +//-------------------------------------------------------------------------------------- +// Defines and macros +//-------------------------------------------------------------------------------------- +#define EVENT_BUTTON_CLICKED 0x0101 +#define EVENT_COMBOBOX_SELECTION_CHANGED 0x0201 +#define EVENT_RADIOBUTTON_CHANGED 0x0301 +#define EVENT_CHECKBOX_CHANGED 0x0401 +#define EVENT_SLIDER_VALUE_CHANGED 0x0501 +#define EVENT_SLIDER_VALUE_CHANGED_UP 0x0502 + +#define EVENT_EDITBOX_STRING 0x0601 +// EVENT_EDITBOX_CHANGE is sent when the listbox content changes +// due to user input. +#define EVENT_EDITBOX_CHANGE 0x0602 +#define EVENT_LISTBOX_ITEM_DBLCLK 0x0701 +// EVENT_LISTBOX_SELECTION is fired off when the selection changes in +// a single selection list box. +#define EVENT_LISTBOX_SELECTION 0x0702 +#define EVENT_LISTBOX_SELECTION_END 0x0703 + + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- +class CDXUTDialogResourceManager; +class CDXUTControl; +class CDXUTButton; +class CDXUTStatic; +class CDXUTCheckBox; +class CDXUTRadioButton; +class CDXUTComboBox; +class CDXUTSlider; +class CDXUTEditBox; +class CDXUTListBox; +class CDXUTScrollBar; +class CDXUTElement; +struct DXUTElementHolder; +struct DXUTTextureNode; +struct DXUTFontNode; +typedef VOID ( CALLBACK*PCALLBACKDXUTGUIEVENT )( UINT nEvent, int nControlID, CDXUTControl* pControl, + void* pUserContext ); + + +//-------------------------------------------------------------------------------------- +// Enums for pre-defined control types +//-------------------------------------------------------------------------------------- +enum DXUT_CONTROL_TYPE +{ + DXUT_CONTROL_BUTTON, + DXUT_CONTROL_STATIC, + DXUT_CONTROL_CHECKBOX, + DXUT_CONTROL_RADIOBUTTON, + DXUT_CONTROL_COMBOBOX, + DXUT_CONTROL_SLIDER, + DXUT_CONTROL_EDITBOX, + DXUT_CONTROL_IMEEDITBOX, + DXUT_CONTROL_LISTBOX, + DXUT_CONTROL_SCROLLBAR, +}; + +enum DXUT_CONTROL_STATE +{ + DXUT_STATE_NORMAL = 0, + DXUT_STATE_DISABLED, + DXUT_STATE_HIDDEN, + DXUT_STATE_FOCUS, + DXUT_STATE_MOUSEOVER, + DXUT_STATE_PRESSED, +}; + +#define MAX_CONTROL_STATES 6 + +struct DXUTBlendColor +{ + void Init( D3DCOLOR defaultColor, D3DCOLOR disabledColor = D3DCOLOR_ARGB( 200, 128, 128, 128 ), + D3DCOLOR hiddenColor = 0 ); + void Blend( UINT iState, float fElapsedTime, float fRate = 0.7f ); + + D3DCOLOR States[ MAX_CONTROL_STATES ]; // Modulate colors for all possible control states + D3DXCOLOR Current; +}; + + +//----------------------------------------------------------------------------- +// Contains all the display tweakables for a sub-control +//----------------------------------------------------------------------------- +class CDXUTElement +{ +public: + void SetTexture( UINT iTexture, RECT* prcTexture, D3DCOLOR defaultTextureColor = D3DCOLOR_ARGB( 255, 255, 255, + 255 ) ); + void SetFont( UINT iFont, D3DCOLOR defaultFontColor = D3DCOLOR_ARGB( 255, 255, 255, + 255 ), DWORD dwTextFormat = DT_CENTER | + DT_VCENTER ); + + void Refresh(); + + UINT iTexture; // Index of the texture for this Element + UINT iFont; // Index of the font for this Element + DWORD dwTextFormat; // The format argument to DrawText + + RECT rcTexture; // Bounding rect of this element on the composite texture + + DXUTBlendColor TextureColor; + DXUTBlendColor FontColor; +}; + + +//----------------------------------------------------------------------------- +// All controls must be assigned to a dialog, which handles +// input and rendering for the controls. +//----------------------------------------------------------------------------- +class CDXUTDialog +{ + friend class CDXUTDialogResourceManager; + +public: + CDXUTDialog(); + ~CDXUTDialog(); + + // Need to call this now + void Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog = true ); + void Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, + LPCWSTR pszControlTextureFilename ); + void Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, + LPCWSTR szControlTextureResourceName, HMODULE hControlTextureResourceModule ); + + // Windows message handler + bool MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + // Control creation + HRESULT AddStatic( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault=false, + CDXUTStatic** ppCreated=NULL ); + HRESULT AddButton( int ID, LPCWSTR strText, int x, int y, int width, int height, UINT nHotkey=0, + bool bIsDefault=false, CDXUTButton** ppCreated=NULL ); + HRESULT AddCheckBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bChecked=false, + UINT nHotkey=0, bool bIsDefault=false, CDXUTCheckBox** ppCreated=NULL ); + HRESULT AddRadioButton( int ID, UINT nButtonGroup, LPCWSTR strText, int x, int y, int width, + int height, bool bChecked=false, UINT nHotkey=0, bool bIsDefault=false, + CDXUTRadioButton** ppCreated=NULL ); + HRESULT AddComboBox( int ID, int x, int y, int width, int height, UINT nHotKey=0, bool bIsDefault= + false, CDXUTComboBox** ppCreated=NULL ); + HRESULT AddSlider( int ID, int x, int y, int width, int height, int min=0, int max=100, int value=50, + bool bIsDefault=false, CDXUTSlider** ppCreated=NULL ); + // AddIMEEditBox has been renamed into DXUTguiIME.cpp as CDXUTIMEEditBox::CreateIMEEditBox + HRESULT AddEditBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault= + false, CDXUTEditBox** ppCreated=NULL ); + HRESULT AddListBox( int ID, int x, int y, int width, int height, DWORD dwStyle=0, + CDXUTListBox** ppCreated=NULL ); + HRESULT AddControl( CDXUTControl* pControl ); + HRESULT InitControl( CDXUTControl* pControl ); + + // Control retrieval + CDXUTStatic* GetStatic( int ID ) + { + return ( CDXUTStatic* )GetControl( ID, DXUT_CONTROL_STATIC ); + } + CDXUTButton* GetButton( int ID ) + { + return ( CDXUTButton* )GetControl( ID, DXUT_CONTROL_BUTTON ); + } + CDXUTCheckBox* GetCheckBox( int ID ) + { + return ( CDXUTCheckBox* )GetControl( ID, DXUT_CONTROL_CHECKBOX ); + } + CDXUTRadioButton* GetRadioButton( int ID ) + { + return ( CDXUTRadioButton* )GetControl( ID, DXUT_CONTROL_RADIOBUTTON ); + } + CDXUTComboBox* GetComboBox( int ID ) + { + return ( CDXUTComboBox* )GetControl( ID, DXUT_CONTROL_COMBOBOX ); + } + CDXUTSlider* GetSlider( int ID ) + { + return ( CDXUTSlider* )GetControl( ID, DXUT_CONTROL_SLIDER ); + } + CDXUTEditBox* GetEditBox( int ID ) + { + return ( CDXUTEditBox* )GetControl( ID, DXUT_CONTROL_EDITBOX ); + } + CDXUTListBox* GetListBox( int ID ) + { + return ( CDXUTListBox* )GetControl( ID, DXUT_CONTROL_LISTBOX ); + } + + CDXUTControl* GetControl( int ID ); + CDXUTControl* GetControl( int ID, UINT nControlType ); + CDXUTControl* GetControlAtPoint( POINT pt ); + + bool GetControlEnabled( int ID ); + void SetControlEnabled( int ID, bool bEnabled ); + + void ClearRadioButtonGroup( UINT nGroup ); + void ClearComboBox( int ID ); + + // Access the default display Elements used when adding new controls + HRESULT SetDefaultElement( UINT nControlType, UINT iElement, CDXUTElement* pElement ); + CDXUTElement* GetDefaultElement( UINT nControlType, UINT iElement ); + + // Methods called by controls + void SendEvent( UINT nEvent, bool bTriggeredByUser, CDXUTControl* pControl ); + void RequestFocus( CDXUTControl* pControl ); + + // Render helpers + HRESULT DrawRect( RECT* pRect, D3DCOLOR color ); + HRESULT DrawRect9( RECT* pRect, D3DCOLOR color ); + HRESULT DrawPolyLine( POINT* apPoints, UINT nNumPoints, D3DCOLOR color ); + HRESULT DrawSprite( CDXUTElement* pElement, RECT* prcDest, float fDepth ); + HRESULT DrawSprite9( CDXUTElement* pElement, RECT* prcDest ); + HRESULT DrawSprite11( CDXUTElement* pElement, RECT* prcDest, float fDepth ); + HRESULT CalcTextRect( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, int nCount = -1 ); + HRESULT DrawText( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow = false, + int nCount = -1, bool bCenter = false ); + HRESULT DrawText9( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow = false, + int nCount = -1 ); + HRESULT DrawText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext, + LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow = false, + int nCount = -1, bool bCenter = false ); + + // Attributes + bool GetVisible() + { + return m_bVisible; + } + void SetVisible( bool bVisible ) + { + m_bVisible = bVisible; + } + bool GetMinimized() + { + return m_bMinimized; + } + void SetMinimized( bool bMinimized ) + { + m_bMinimized = bMinimized; + } + void SetBackgroundColors( D3DCOLOR colorAllCorners ) + { + SetBackgroundColors( colorAllCorners, colorAllCorners, colorAllCorners, colorAllCorners ); + } + void SetBackgroundColors( D3DCOLOR colorTopLeft, D3DCOLOR colorTopRight, D3DCOLOR colorBottomLeft, + D3DCOLOR colorBottomRight ); + void EnableCaption( bool bEnable ) + { + m_bCaption = bEnable; + } + int GetCaptionHeight() const + { + return m_nCaptionHeight; + } + void SetCaptionHeight( int nHeight ) + { + m_nCaptionHeight = nHeight; + } + void SetCaptionText( const WCHAR* pwszText ) + { + wcscpy_s( m_wszCaption, sizeof( m_wszCaption ) / sizeof( m_wszCaption[0] ), pwszText ); + } + void GetLocation( POINT& Pt ) const + { + Pt.x = m_x; Pt.y = m_y; + } + void SetLocation( int x, int y ) + { + m_x = x; m_y = y; + } + void SetSize( int width, int height ) + { + m_width = width; m_height = height; + } + int GetWidth() + { + return m_width; + } + int GetHeight() + { + return m_height; + } + + static void WINAPI SetRefreshTime( float fTime ) + { + s_fTimeRefresh = fTime; + } + + static CDXUTControl* WINAPI GetNextControl( CDXUTControl* pControl ); + static CDXUTControl* WINAPI GetPrevControl( CDXUTControl* pControl ); + + void RemoveControl( int ID ); + void RemoveAllControls(); + + // Sets the callback used to notify the app of control events + void SetCallback( PCALLBACKDXUTGUIEVENT pCallback, void* pUserContext = NULL ); + void EnableNonUserEvents( bool bEnable ) + { + m_bNonUserEvents = bEnable; + } + void EnableKeyboardInput( bool bEnable ) + { + m_bKeyboardInput = bEnable; + } + void EnableMouseInput( bool bEnable ) + { + m_bMouseInput = bEnable; + } + bool IsKeyboardInputEnabled() const + { + return m_bKeyboardInput; + } + + // Device state notification + void Refresh(); + HRESULT OnRender( float fElapsedTime ); + + // Shared resource access. Indexed fonts and textures are shared among + // all the controls. + HRESULT SetFont( UINT index, LPCWSTR strFaceName, LONG height, LONG weight ); + DXUTFontNode* GetFont( UINT index ); + + HRESULT SetTexture( UINT index, LPCWSTR strFilename ); + HRESULT SetTexture( UINT index, LPCWSTR strResourceName, HMODULE hResourceModule ); + DXUTTextureNode* GetTexture( UINT index ); + + CDXUTDialogResourceManager* GetManager() + { + return m_pManager; + } + + static void WINAPI ClearFocus(); + void FocusDefaultControl(); + + bool m_bNonUserEvents; + bool m_bKeyboardInput; + bool m_bMouseInput; + +private: + int m_nDefaultControlID; + + HRESULT OnRender9( float fElapsedTime ); + HRESULT OnRender10( float fElapsedTime ); + HRESULT OnRender11( float fElapsedTime ); + + static double s_fTimeRefresh; + double m_fTimeLastRefresh; + + // Initialize default Elements + void InitDefaultElements(); + + // Windows message handlers + void OnMouseMove( POINT pt ); + void OnMouseUp( POINT pt ); + + void SetNextDialog( CDXUTDialog* pNextDialog ); + + // Control events + bool OnCycleFocus( bool bForward ); + + static CDXUTControl* s_pControlFocus; // The control which has focus + static CDXUTControl* s_pControlPressed; // The control currently pressed + + CDXUTControl* m_pControlMouseOver; // The control which is hovered over + + bool m_bVisible; + bool m_bCaption; + bool m_bMinimized; + bool m_bDrag; + WCHAR m_wszCaption[256]; + + int m_x; + int m_y; + int m_width; + int m_height; + int m_nCaptionHeight; + + D3DCOLOR m_colorTopLeft; + D3DCOLOR m_colorTopRight; + D3DCOLOR m_colorBottomLeft; + D3DCOLOR m_colorBottomRight; + + CDXUTDialogResourceManager* m_pManager; + PCALLBACKDXUTGUIEVENT m_pCallbackEvent; + void* m_pCallbackEventUserContext; + + CGrowableArray m_Textures; // Index into m_TextureCache; + CGrowableArray m_Fonts; // Index into m_FontCache; + + CGrowableArray m_Controls; + CGrowableArray m_DefaultElements; + + CDXUTElement m_CapElement; // Element for the caption + + CDXUTDialog* m_pNextDialog; + CDXUTDialog* m_pPrevDialog; +}; + + +//-------------------------------------------------------------------------------------- +// Structs for shared resources +//-------------------------------------------------------------------------------------- +struct DXUTTextureNode +{ + bool bFileSource; // True if this texture is loaded from a file. False if from resource. + HMODULE hResourceModule; + int nResourceID; // Resource ID. If 0, string-based ID is used and stored in strFilename. + WCHAR strFilename[MAX_PATH]; + DWORD dwWidth; + DWORD dwHeight; + IDirect3DTexture9* pTexture9; + ID3D11Texture2D* pTexture11; + ID3D11ShaderResourceView* pTexResView11; +}; + +struct DXUTFontNode +{ + WCHAR strFace[MAX_PATH]; + LONG nHeight; + LONG nWeight; + ID3DXFont* pFont9; +}; + +struct DXUTSpriteVertex +{ + D3DXVECTOR3 vPos; + D3DXCOLOR vColor; + D3DXVECTOR2 vTex; +}; + +//----------------------------------------------------------------------------- +// Manages shared resources of dialogs +//----------------------------------------------------------------------------- +class CDXUTDialogResourceManager +{ +public: + CDXUTDialogResourceManager(); + ~CDXUTDialogResourceManager(); + + bool MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + // D3D9 specific + HRESULT OnD3D9CreateDevice( LPDIRECT3DDEVICE9 pd3dDevice ); + HRESULT OnD3D9ResetDevice(); + void OnD3D9LostDevice(); + void OnD3D9DestroyDevice(); + IDirect3DDevice9* GetD3D9Device() + { + return m_pd3d9Device; + } + + // D3D11 specific + HRESULT OnD3D11CreateDevice( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext ); + HRESULT OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc ); + void OnD3D11ReleasingSwapChain(); + void OnD3D11DestroyDevice(); + void StoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext ); + void RestoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext ); + void ApplyRenderUI11( ID3D11DeviceContext* pd3dImmediateContext ); + void ApplyRenderUIUntex11( ID3D11DeviceContext* pd3dImmediateContext ); + void BeginSprites11( ); + void EndSprites11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext ); + ID3D11Device* GetD3D11Device() + { + return m_pd3d11Device; + } + ID3D11DeviceContext* GetD3D11DeviceContext() + { + return m_pd3d11DeviceContext; + } + + DXUTFontNode* GetFontNode( int iIndex ) + { + return m_FontCache.GetAt( iIndex ); + }; + DXUTTextureNode* GetTextureNode( int iIndex ) + { + return m_TextureCache.GetAt( iIndex ); + }; + + int AddFont( LPCWSTR strFaceName, LONG height, LONG weight ); + int AddTexture( LPCWSTR strFilename ); + int AddTexture( LPCWSTR strResourceName, HMODULE hResourceModule ); + + bool RegisterDialog( CDXUTDialog* pDialog ); + void UnregisterDialog( CDXUTDialog* pDialog ); + void EnableKeyboardInputForAllDialogs(); + + // Shared between all dialogs + + // D3D9 + IDirect3DStateBlock9* m_pStateBlock; + ID3DXSprite* m_pSprite; // Sprite used for drawing + + // D3D11 + // Shaders + ID3D11VertexShader* m_pVSRenderUI11; + ID3D11PixelShader* m_pPSRenderUI11; + ID3D11PixelShader* m_pPSRenderUIUntex11; + + // States + ID3D11DepthStencilState* m_pDepthStencilStateUI11; + ID3D11RasterizerState* m_pRasterizerStateUI11; + ID3D11BlendState* m_pBlendStateUI11; + ID3D11SamplerState* m_pSamplerStateUI11; + + // Stored states + ID3D11DepthStencilState* m_pDepthStencilStateStored11; + UINT m_StencilRefStored11; + ID3D11RasterizerState* m_pRasterizerStateStored11; + ID3D11BlendState* m_pBlendStateStored11; + float m_BlendFactorStored11[4]; + UINT m_SampleMaskStored11; + ID3D11SamplerState* m_pSamplerStateStored11; + + ID3D11InputLayout* m_pInputLayout11; + ID3D11Buffer* m_pVBScreenQuad11; + + // Sprite workaround + ID3D11Buffer* m_pSpriteBuffer11; + UINT m_SpriteBufferBytes11; + CGrowableArray m_SpriteVertices; + + UINT m_nBackBufferWidth; + UINT m_nBackBufferHeight; + + CGrowableArray m_Dialogs; // Dialogs registered + +protected: + // D3D9 specific + IDirect3DDevice9* m_pd3d9Device; + HRESULT CreateFont9( UINT index ); + HRESULT CreateTexture9( UINT index ); + + // D3D11 specific + ID3D11Device* m_pd3d11Device; + ID3D11DeviceContext* m_pd3d11DeviceContext; + HRESULT CreateFont11( UINT index ); + HRESULT CreateTexture11( UINT index ); + + CGrowableArray m_TextureCache; // Shared textures + CGrowableArray m_FontCache; // Shared fonts +}; + +void BeginText11(); +void DrawText11DXUT( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext, + LPCWSTR strText, RECT rcScreen, D3DXCOLOR vFontColor, + float fBBWidth, float fBBHeight, bool bCenter ); +void EndText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext ); + +//----------------------------------------------------------------------------- +// Base class for controls +//----------------------------------------------------------------------------- +class CDXUTControl +{ +public: + CDXUTControl( CDXUTDialog* pDialog = NULL ); + virtual ~CDXUTControl(); + + virtual HRESULT OnInit() + { + return S_OK; + } + virtual void Refresh(); + virtual void Render( float fElapsedTime ) + { + }; + + // Windows message handler + virtual bool MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ) + { + return false; + } + + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) + { + return false; + } + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) + { + return false; + } + + virtual bool CanHaveFocus() + { + return false; + } + virtual void OnFocusIn() + { + m_bHasFocus = true; + } + virtual void OnFocusOut() + { + m_bHasFocus = false; + } + virtual void OnMouseEnter() + { + m_bMouseOver = true; + } + virtual void OnMouseLeave() + { + m_bMouseOver = false; + } + virtual void OnHotkey() + { + } + + virtual BOOL ContainsPoint( POINT pt ) + { + return PtInRect( &m_rcBoundingBox, pt ); + } + + virtual void SetEnabled( bool bEnabled ) + { + m_bEnabled = bEnabled; + } + virtual bool GetEnabled() + { + return m_bEnabled; + } + virtual void SetVisible( bool bVisible ) + { + m_bVisible = bVisible; + } + virtual bool GetVisible() + { + return m_bVisible; + } + + UINT GetType() const + { + return m_Type; + } + + int GetID() const + { + return m_ID; + } + void SetID( int ID ) + { + m_ID = ID; + } + + void SetLocation( int x, int y ) + { + m_x = x; m_y = y; UpdateRects(); + } + void SetSize( int width, int height ) + { + m_width = width; m_height = height; UpdateRects(); + } + + void SetHotkey( UINT nHotkey ) + { + m_nHotkey = nHotkey; + } + UINT GetHotkey() + { + return m_nHotkey; + } + + void SetUserData( void* pUserData ) + { + m_pUserData = pUserData; + } + void* GetUserData() const + { + return m_pUserData; + } + + virtual void SetTextColor( D3DCOLOR Color ); + CDXUTElement* GetElement( UINT iElement ) + { + return m_Elements.GetAt( iElement ); + } + HRESULT SetElement( UINT iElement, CDXUTElement* pElement ); + + bool m_bVisible; // Shown/hidden flag + bool m_bMouseOver; // Mouse pointer is above control + bool m_bHasFocus; // Control has input focus + bool m_bIsDefault; // Is the default control + + // Size, scale, and positioning members + int m_x, m_y; + int m_width, m_height; + + // These members are set by the container + CDXUTDialog* m_pDialog; // Parent container + UINT m_Index; // Index within the control list + + CGrowableArray m_Elements; // All display elements + +protected: + virtual void UpdateRects(); + + int m_ID; // ID number + DXUT_CONTROL_TYPE m_Type; // Control type, set once in constructor + UINT m_nHotkey; // Virtual key code for this control's hotkey + void* m_pUserData; // Data associated with this control that is set by user. + + bool m_bEnabled; // Enabled/disabled flag + + RECT m_rcBoundingBox; // Rectangle defining the active region of the control +}; + + +//----------------------------------------------------------------------------- +// Contains all the display information for a given control type +//----------------------------------------------------------------------------- +struct DXUTElementHolder +{ + UINT nControlType; + UINT iElement; + + CDXUTElement Element; +}; + + +//----------------------------------------------------------------------------- +// Static control +//----------------------------------------------------------------------------- +class CDXUTStatic : public CDXUTControl +{ +public: + CDXUTStatic( CDXUTDialog* pDialog = NULL ); + + virtual void Render( float fElapsedTime ); + virtual BOOL ContainsPoint( POINT pt ) + { + return false; + } + + HRESULT GetTextCopy( __out_ecount(bufferCount) LPWSTR strDest, + UINT bufferCount ); + LPCWSTR GetText() + { + return m_strText; + } + HRESULT SetText( LPCWSTR strText ); + + +protected: + WCHAR m_strText[MAX_PATH]; // Window text +}; + + +//----------------------------------------------------------------------------- +// Button control +//----------------------------------------------------------------------------- +class CDXUTButton : public CDXUTStatic +{ +public: + CDXUTButton( CDXUTDialog* pDialog = NULL ); + + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual void OnHotkey() + { + if( m_pDialog->IsKeyboardInputEnabled() ) m_pDialog->RequestFocus( this ); + m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this ); + } + + virtual BOOL ContainsPoint( POINT pt ) + { + return PtInRect( &m_rcBoundingBox, pt ); + } + virtual bool CanHaveFocus() + { + return ( m_bVisible && m_bEnabled ); + } + + virtual void Render( float fElapsedTime ); + +protected: + bool m_bPressed; +}; + + +//----------------------------------------------------------------------------- +// CheckBox control +//----------------------------------------------------------------------------- +class CDXUTCheckBox : public CDXUTButton +{ +public: + CDXUTCheckBox( CDXUTDialog* pDialog = NULL ); + + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual void OnHotkey() + { + if( m_pDialog->IsKeyboardInputEnabled() ) m_pDialog->RequestFocus( this ); + SetCheckedInternal( !m_bChecked, true ); + } + + virtual BOOL ContainsPoint( POINT pt ); + virtual void UpdateRects(); + + virtual void Render( float fElapsedTime ); + + bool GetChecked() + { + return m_bChecked; + } + void SetChecked( bool bChecked ) + { + SetCheckedInternal( bChecked, false ); + } + +protected: + virtual void SetCheckedInternal( bool bChecked, bool bFromInput ); + + bool m_bChecked; + RECT m_rcButton; + RECT m_rcText; +}; + + +//----------------------------------------------------------------------------- +// RadioButton control +//----------------------------------------------------------------------------- +class CDXUTRadioButton : public CDXUTCheckBox +{ +public: + CDXUTRadioButton( CDXUTDialog* pDialog = NULL ); + + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual void OnHotkey() + { + if( m_pDialog->IsKeyboardInputEnabled() ) m_pDialog->RequestFocus( this ); + SetCheckedInternal( true, true, true ); + } + + void SetChecked( bool bChecked, bool bClearGroup=true ) + { + SetCheckedInternal( bChecked, bClearGroup, false ); + } + void SetButtonGroup( UINT nButtonGroup ) + { + m_nButtonGroup = nButtonGroup; + } + UINT GetButtonGroup() + { + return m_nButtonGroup; + } + +protected: + virtual void SetCheckedInternal( bool bChecked, bool bClearGroup, bool bFromInput ); + UINT m_nButtonGroup; +}; + + +//----------------------------------------------------------------------------- +// Scrollbar control +//----------------------------------------------------------------------------- +class CDXUTScrollBar : public CDXUTControl +{ +public: + CDXUTScrollBar( CDXUTDialog* pDialog = NULL ); + virtual ~CDXUTScrollBar(); + + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual bool MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ); + + virtual void Render( float fElapsedTime ); + virtual void UpdateRects(); + + void SetTrackRange( int nStart, int nEnd ); + int GetTrackPos() + { + return m_nPosition; + } + void SetTrackPos( int nPosition ) + { + m_nPosition = nPosition; Cap(); UpdateThumbRect(); + } + int GetPageSize() + { + return m_nPageSize; + } + void SetPageSize( int nPageSize ) + { + m_nPageSize = nPageSize; Cap(); UpdateThumbRect(); + } + + void Scroll( int nDelta ); // Scroll by nDelta items (plus or minus) + void ShowItem( int nIndex ); // Ensure that item nIndex is displayed, scroll if necessary + +protected: + // ARROWSTATE indicates the state of the arrow buttons. + // CLEAR No arrow is down. + // CLICKED_UP Up arrow is clicked. + // CLICKED_DOWN Down arrow is clicked. + // HELD_UP Up arrow is held down for sustained period. + // HELD_DOWN Down arrow is held down for sustained period. + enum ARROWSTATE + { + CLEAR, + CLICKED_UP, + CLICKED_DOWN, + HELD_UP, + HELD_DOWN + }; + + void UpdateThumbRect(); + void Cap(); // Clips position at boundaries. Ensures it stays within legal range. + + bool m_bShowThumb; + bool m_bDrag; + RECT m_rcUpButton; + RECT m_rcDownButton; + RECT m_rcTrack; + RECT m_rcThumb; + int m_nPosition; // Position of the first displayed item + int m_nPageSize; // How many items are displayable in one page + int m_nStart; // First item + int m_nEnd; // The index after the last item + POINT m_LastMouse;// Last mouse position + ARROWSTATE m_Arrow; // State of the arrows + double m_dArrowTS; // Timestamp of last arrow event. +}; + + +//----------------------------------------------------------------------------- +// ListBox control +//----------------------------------------------------------------------------- +struct DXUTListBoxItem +{ + WCHAR strText[256]; + void* pData; + + RECT rcActive; + bool bSelected; +}; + +class CDXUTListBox : public CDXUTControl +{ +public: + CDXUTListBox( CDXUTDialog* pDialog = NULL ); + virtual ~CDXUTListBox(); + + virtual HRESULT OnInit() + { + return m_pDialog->InitControl( &m_ScrollBar ); + } + virtual bool CanHaveFocus() + { + return ( m_bVisible && m_bEnabled ); + } + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual bool MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ); + + virtual void Render( float fElapsedTime ); + virtual void UpdateRects(); + + DWORD GetStyle() const + { + return m_dwStyle; + } + int GetSize() const + { + return m_Items.GetSize(); + } + void SetStyle( DWORD dwStyle ) + { + m_dwStyle = dwStyle; + } + int GetScrollBarWidth() const + { + return m_nSBWidth; + } + void SetScrollBarWidth( int nWidth ) + { + m_nSBWidth = nWidth; UpdateRects(); + } + void SetBorder( int nBorder, int nMargin ) + { + m_nBorder = nBorder; m_nMargin = nMargin; + } + HRESULT AddItem( const WCHAR* wszText, void* pData ); + HRESULT InsertItem( int nIndex, const WCHAR* wszText, void* pData ); + void RemoveItem( int nIndex ); + void RemoveAllItems(); + + DXUTListBoxItem* GetItem( int nIndex ); + int GetSelectedIndex( int nPreviousSelected = -1 ); + DXUTListBoxItem* GetSelectedItem( int nPreviousSelected = -1 ) + { + return GetItem( GetSelectedIndex( nPreviousSelected ) ); + } + void SelectItem( int nNewIndex ); + + enum STYLE + { + MULTISELECTION = 1 + }; + +protected: + RECT m_rcText; // Text rendering bound + RECT m_rcSelection; // Selection box bound + CDXUTScrollBar m_ScrollBar; + int m_nSBWidth; + int m_nBorder; + int m_nMargin; + int m_nTextHeight; // Height of a single line of text + DWORD m_dwStyle; // List box style + int m_nSelected; // Index of the selected item for single selection list box + int m_nSelStart; // Index of the item where selection starts (for handling multi-selection) + bool m_bDrag; // Whether the user is dragging the mouse to select + + CGrowableArray m_Items; +}; + + +//----------------------------------------------------------------------------- +// ComboBox control +//----------------------------------------------------------------------------- +struct DXUTComboBoxItem +{ + WCHAR strText[256]; + void* pData; + + RECT rcActive; + bool bVisible; +}; + + +class CDXUTComboBox : public CDXUTButton +{ +public: + CDXUTComboBox( CDXUTDialog* pDialog = NULL ); + virtual ~CDXUTComboBox(); + + virtual void SetTextColor( D3DCOLOR Color ); + virtual HRESULT OnInit() + { + return m_pDialog->InitControl( &m_ScrollBar ); + } + + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual void OnHotkey(); + + virtual bool CanHaveFocus() + { + return ( m_bVisible && m_bEnabled ); + } + virtual void OnFocusOut(); + virtual void Render( float fElapsedTime ); + + virtual void UpdateRects(); + + HRESULT AddItem( const WCHAR* strText, void* pData ); + void RemoveAllItems(); + void RemoveItem( UINT index ); + bool ContainsItem( const WCHAR* strText, UINT iStart=0 ); + int FindItem( const WCHAR* strText, UINT iStart=0 ); + void* GetItemData( const WCHAR* strText ); + void* GetItemData( int nIndex ); + void SetDropHeight( UINT nHeight ) + { + m_nDropHeight = nHeight; UpdateRects(); + } + int GetScrollBarWidth() const + { + return m_nSBWidth; + } + void SetScrollBarWidth( int nWidth ) + { + m_nSBWidth = nWidth; UpdateRects(); + } + + int GetSelectedIndex() const + { + return m_iSelected; + } + void* GetSelectedData(); + DXUTComboBoxItem* GetSelectedItem(); + + UINT GetNumItems() + { + return m_Items.GetSize(); + } + DXUTComboBoxItem* GetItem( UINT index ) + { + return m_Items.GetAt( index ); + } + + HRESULT SetSelectedByIndex( UINT index ); + HRESULT SetSelectedByText( const WCHAR* strText ); + HRESULT SetSelectedByData( void* pData ); + +protected: + int m_iSelected; + int m_iFocused; + int m_nDropHeight; + CDXUTScrollBar m_ScrollBar; + int m_nSBWidth; + + bool m_bOpened; + + RECT m_rcText; + RECT m_rcButton; + RECT m_rcDropdown; + RECT m_rcDropdownText; + + + CGrowableArray m_Items; +}; + + +//----------------------------------------------------------------------------- +// Slider control +//----------------------------------------------------------------------------- +class CDXUTSlider : public CDXUTControl +{ +public: + CDXUTSlider( CDXUTDialog* pDialog = NULL ); + + virtual BOOL ContainsPoint( POINT pt ); + virtual bool CanHaveFocus() + { + return ( m_bVisible && m_bEnabled ); + } + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + + virtual void UpdateRects(); + + virtual void Render( float fElapsedTime ); + + void SetValue( int nValue ) + { + SetValueInternal( nValue, false ); + } + int GetValue() const + { + return m_nValue; + }; + + void GetRange( int& nMin, int& nMax ) const + { + nMin = m_nMin; nMax = m_nMax; + } + void SetRange( int nMin, int nMax ); + +protected: + void SetValueInternal( int nValue, bool bFromInput ); + int ValueFromPos( int x ); + + int m_nValue; + + int m_nMin; + int m_nMax; + + int m_nDragX; // Mouse position at start of drag + int m_nDragOffset; // Drag offset from the center of the button + int m_nButtonX; + + bool m_bPressed; + RECT m_rcButton; +}; + + +//----------------------------------------------------------------------------- +// CUniBuffer class for the edit control +//----------------------------------------------------------------------------- +class CUniBuffer +{ +public: + CUniBuffer( int nInitialSize = 1 ); + ~CUniBuffer(); + + static void WINAPI Initialize(); + static void WINAPI Uninitialize(); + + int GetBufferSize() + { + return m_nBufferSize; + } + bool SetBufferSize( int nSize ); + int GetTextSize() + { + return lstrlenW( m_pwszBuffer ); + } + const WCHAR* GetBuffer() + { + return m_pwszBuffer; + } + const WCHAR& operator[]( int n ) const + { + return m_pwszBuffer[n]; + } + WCHAR& operator[]( int n ); + DXUTFontNode* GetFontNode() + { + return m_pFontNode; + } + void SetFontNode( DXUTFontNode* pFontNode ) + { + m_pFontNode = pFontNode; + } + void Clear(); + + bool InsertChar( int nIndex, WCHAR wChar ); // Inserts the char at specified index. If nIndex == -1, insert to the end. + bool RemoveChar( int nIndex ); // Removes the char at specified index. If nIndex == -1, remove the last char. + bool InsertString( int nIndex, const WCHAR* pStr, int nCount = -1 ); // Inserts the first nCount characters of the string pStr at specified index. If nCount == -1, the entire string is inserted. If nIndex == -1, insert to the end. + bool SetText( LPCWSTR wszText ); + + // Uniscribe + HRESULT CPtoX( int nCP, BOOL bTrail, int* pX ); + HRESULT XtoCP( int nX, int* pCP, int* pnTrail ); + void GetPriorItemPos( int nCP, int* pPrior ); + void GetNextItemPos( int nCP, int* pPrior ); + +private: + HRESULT Analyse(); // Uniscribe -- Analyse() analyses the string in the buffer + + WCHAR* m_pwszBuffer; // Buffer to hold text + int m_nBufferSize; // Size of the buffer allocated, in characters + + // Uniscribe-specific + DXUTFontNode* m_pFontNode; // Font node for the font that this buffer uses + bool m_bAnalyseRequired; // True if the string has changed since last analysis. + SCRIPT_STRING_ANALYSIS m_Analysis; // Analysis for the current string + +private: + // Empty implementation of the Uniscribe API + static HRESULT WINAPI Dummy_ScriptApplyDigitSubstitution( const SCRIPT_DIGITSUBSTITUTE*, SCRIPT_CONTROL*, + SCRIPT_STATE* ) + { + return E_NOTIMPL; + } + static HRESULT WINAPI Dummy_ScriptStringAnalyse( HDC, const void*, int, int, int, DWORD, int, SCRIPT_CONTROL*, + SCRIPT_STATE*, const int*, SCRIPT_TABDEF*, const BYTE*, + SCRIPT_STRING_ANALYSIS* ) + { + return E_NOTIMPL; + } + static HRESULT WINAPI Dummy_ScriptStringCPtoX( SCRIPT_STRING_ANALYSIS, int, BOOL, int* ) + { + return E_NOTIMPL; + } + static HRESULT WINAPI Dummy_ScriptStringXtoCP( SCRIPT_STRING_ANALYSIS, int, int*, int* ) + { + return E_NOTIMPL; + } + static HRESULT WINAPI Dummy_ScriptStringFree( SCRIPT_STRING_ANALYSIS* ) + { + return E_NOTIMPL; + } + static const SCRIPT_LOGATTR* WINAPI Dummy_ScriptString_pLogAttr( SCRIPT_STRING_ANALYSIS ) + { + return NULL; + } + static const int* WINAPI Dummy_ScriptString_pcOutChars( SCRIPT_STRING_ANALYSIS ) + { + return NULL; + } + + // Function pointers + static HRESULT( WINAPI* _ScriptApplyDigitSubstitution )( const SCRIPT_DIGITSUBSTITUTE*, + SCRIPT_CONTROL*, SCRIPT_STATE* ); + static HRESULT( WINAPI* _ScriptStringAnalyse )( HDC, const void*, int, int, int, DWORD, int, + SCRIPT_CONTROL*, SCRIPT_STATE*, const int*, + SCRIPT_TABDEF*, const BYTE*, + SCRIPT_STRING_ANALYSIS* ); + static HRESULT( WINAPI* _ScriptStringCPtoX )( SCRIPT_STRING_ANALYSIS, int, BOOL, int* ); + static HRESULT( WINAPI* _ScriptStringXtoCP )( SCRIPT_STRING_ANALYSIS, int, int*, int* ); + static HRESULT( WINAPI* _ScriptStringFree )( SCRIPT_STRING_ANALYSIS* ); + static const SCRIPT_LOGATTR* ( WINAPI*_ScriptString_pLogAttr )( SCRIPT_STRING_ANALYSIS ); + static const int* ( WINAPI*_ScriptString_pcOutChars )( SCRIPT_STRING_ANALYSIS ); + + static HINSTANCE s_hDll; // Uniscribe DLL handle + +}; + +//----------------------------------------------------------------------------- +// EditBox control +//----------------------------------------------------------------------------- +class CDXUTEditBox : public CDXUTControl +{ +public: + CDXUTEditBox( CDXUTDialog* pDialog = NULL ); + virtual ~CDXUTEditBox(); + + virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual bool MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual void UpdateRects(); + virtual bool CanHaveFocus() + { + return ( m_bVisible && m_bEnabled ); + } + virtual void Render( float fElapsedTime ); + virtual void OnFocusIn(); + + void SetText( LPCWSTR wszText, bool bSelected = false ); + LPCWSTR GetText() + { + return m_Buffer.GetBuffer(); + } + int GetTextLength() + { + return m_Buffer.GetTextSize(); + } // Returns text length in chars excluding NULL. + HRESULT GetTextCopy( __out_ecount(bufferCount) LPWSTR strDest, + UINT bufferCount ); + void ClearText(); + virtual void SetTextColor( D3DCOLOR Color ) + { + m_TextColor = Color; + } // Text color + void SetSelectedTextColor( D3DCOLOR Color ) + { + m_SelTextColor = Color; + } // Selected text color + void SetSelectedBackColor( D3DCOLOR Color ) + { + m_SelBkColor = Color; + } // Selected background color + void SetCaretColor( D3DCOLOR Color ) + { + m_CaretColor = Color; + } // Caret color + void SetBorderWidth( int nBorder ) + { + m_nBorder = nBorder; UpdateRects(); + } // Border of the window + void SetSpacing( int nSpacing ) + { + m_nSpacing = nSpacing; UpdateRects(); + } + void ParseFloatArray( float* pNumbers, int nCount ); + void SetTextFloatArray( const float* pNumbers, int nCount ); + +protected: + void PlaceCaret( int nCP ); + void DeleteSelectionText(); + void ResetCaretBlink(); + void CopyToClipboard(); + void PasteFromClipboard(); + + CUniBuffer m_Buffer; // Buffer to hold text + int m_nBorder; // Border of the window + int m_nSpacing; // Spacing between the text and the edge of border + RECT m_rcText; // Bounding rectangle for the text + RECT m_rcRender[9]; // Convenient rectangles for rendering elements + double m_dfBlink; // Caret blink time in milliseconds + double m_dfLastBlink; // Last timestamp of caret blink + bool m_bCaretOn; // Flag to indicate whether caret is currently visible + int m_nCaret; // Caret position, in characters + bool m_bInsertMode; // If true, control is in insert mode. Else, overwrite mode. + int m_nSelStart; // Starting position of the selection. The caret marks the end. + int m_nFirstVisible;// First visible character in the edit control + D3DCOLOR m_TextColor; // Text color + D3DCOLOR m_SelTextColor; // Selected text color + D3DCOLOR m_SelBkColor; // Selected background color + D3DCOLOR m_CaretColor; // Caret color + + // Mouse-specific + bool m_bMouseDrag; // True to indicate drag in progress + + // Static + static bool s_bHideCaret; // If true, we don't render the caret. +}; + + + + +#endif // DXUT_GUI_H diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.cpp b/Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.cpp new file mode 100644 index 0000000..1196179 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.cpp @@ -0,0 +1,990 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTguiIME.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#include "DXUTgui.h" +#include "DXUTsettingsDlg.h" +#include "DXUTres.h" +#include "DXUTgui.h" +#include "DXUTguiIME.h" + +#undef min // use __min instead +#undef max // use __max instead +#define DXUT_NEAR_BUTTON_DEPTH 0.6f + + +//-------------------------------------------------------------------------------------- +// CDXUTIMEEditBox class +//-------------------------------------------------------------------------------------- +// IME constants + +POINT CDXUTIMEEditBox::s_ptCompString; // Composition string position. Updated every frame. +int CDXUTIMEEditBox::s_nFirstTargetConv; // Index of the first target converted char in comp string. If none, -1. +CUniBuffer CDXUTIMEEditBox::s_CompString = CUniBuffer( 0 ); +DWORD CDXUTIMEEditBox::s_adwCompStringClause[MAX_COMPSTRING_SIZE]; +WCHAR CDXUTIMEEditBox::s_wszReadingString[32]; +CDXUTIMEEditBox::CCandList CDXUTIMEEditBox::s_CandList; // Data relevant to the candidate list +bool CDXUTIMEEditBox::s_bImeFlag = true; + + +#if defined(DEBUG) || defined(_DEBUG) +bool CDXUTIMEEditBox::m_bIMEStaticMsgProcCalled = false; +#endif + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTIMEEditBox::CreateIMEEditBox( CDXUTDialog* pDialog, int ID, LPCWSTR strText, int x, int y, int width, + int height, bool bIsDefault, CDXUTIMEEditBox** ppCreated ) +{ + CDXUTIMEEditBox* pEditBox = new CDXUTIMEEditBox( pDialog ); + + if( ppCreated != NULL ) + *ppCreated = pEditBox; + + if( pEditBox == NULL ) + return E_OUTOFMEMORY; + + // Set the ID and position + pEditBox->SetID( ID ); + pEditBox->SetLocation( x, y ); + pEditBox->SetSize( width, height ); + pEditBox->m_bIsDefault = bIsDefault; + + if( strText ) + pEditBox->SetText( strText ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::InitDefaultElements( CDXUTDialog* pDialog ) +{ + //------------------------------------- + // CDXUTIMEEditBox + //------------------------------------- + + CDXUTElement Element; + RECT rcTexture; + + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP ); + + // Assign the style + SetRect( &rcTexture, 14, 90, 241, 113 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 0, &Element ); + SetRect( &rcTexture, 8, 82, 14, 90 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 1, &Element ); + SetRect( &rcTexture, 14, 82, 241, 90 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 2, &Element ); + SetRect( &rcTexture, 241, 82, 246, 90 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 3, &Element ); + SetRect( &rcTexture, 8, 90, 14, 113 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 4, &Element ); + SetRect( &rcTexture, 241, 90, 246, 113 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 5, &Element ); + SetRect( &rcTexture, 8, 113, 14, 121 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 6, &Element ); + SetRect( &rcTexture, 14, 113, 241, 121 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 7, &Element ); + SetRect( &rcTexture, 241, 113, 246, 121 ); + Element.SetTexture( 0, &rcTexture ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 8, &Element ); + // Element 9 for IME text, and indicator button + SetRect( &rcTexture, 0, 0, 136, 54 ); + Element.SetTexture( 0, &rcTexture ); + Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_CENTER | DT_VCENTER ); + pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 9, &Element ); +} + + +//-------------------------------------------------------------------------------------- +CDXUTIMEEditBox::CDXUTIMEEditBox( CDXUTDialog* pDialog ) +{ + m_Type = DXUT_CONTROL_IMEEDITBOX; + m_pDialog = pDialog; + + m_nIndicatorWidth = 0; + m_ReadingColor = D3DCOLOR_ARGB( 188, 255, 255, 255 ); + m_ReadingWinColor = D3DCOLOR_ARGB( 128, 0, 0, 0 ); + m_ReadingSelColor = D3DCOLOR_ARGB( 255, 255, 0, 0 ); + m_ReadingSelBkColor = D3DCOLOR_ARGB( 128, 80, 80, 80 ); + m_CandidateColor = D3DCOLOR_ARGB( 255, 200, 200, 200 ); + m_CandidateWinColor = D3DCOLOR_ARGB( 128, 0, 0, 0 ); + m_CandidateSelColor = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + m_CandidateSelBkColor = D3DCOLOR_ARGB( 128, 158, 158, 158 ); + m_CompColor = D3DCOLOR_ARGB( 255, 200, 200, 255 ); + m_CompWinColor = D3DCOLOR_ARGB( 198, 0, 0, 0 ); + m_CompCaretColor = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + m_CompTargetColor = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + m_CompTargetBkColor = D3DCOLOR_ARGB( 255, 150, 150, 150 ); + m_CompTargetNonColor = D3DCOLOR_ARGB( 255, 255, 255, 0 ); + m_CompTargetNonBkColor = D3DCOLOR_ARGB( 255, 150, 150, 150 ); + m_IndicatorImeColor = D3DCOLOR_ARGB( 255, 255, 255, 255 ); + m_IndicatorEngColor = D3DCOLOR_ARGB( 255, 0, 0, 0 ); + m_IndicatorBkColor = D3DCOLOR_ARGB( 255, 128, 128, 128 ); +} + + +//-------------------------------------------------------------------------------------- +CDXUTIMEEditBox::~CDXUTIMEEditBox() +{ +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::SendKey( BYTE nVirtKey ) +{ + keybd_event( nVirtKey, 0, 0, 0 ); + keybd_event( nVirtKey, 0, KEYEVENTF_KEYUP, 0 ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::UpdateRects() +{ + // Temporary adjust m_width so that CDXUTEditBox can compute + // the correct rects for its rendering since we need to make space + // for the indicator button + int nWidth = m_width; + m_width -= m_nIndicatorWidth + m_nBorder * 2; // Make room for the indicator button + CDXUTEditBox::UpdateRects(); + m_width = nWidth; // Restore + + // Compute the indicator button rectangle + SetRect( &m_rcIndicator, m_rcBoundingBox.right, m_rcBoundingBox.top, m_x + m_width, m_rcBoundingBox.bottom ); + // InflateRect( &m_rcIndicator, -m_nBorder, -m_nBorder ); + m_rcBoundingBox.right = m_rcBoundingBox.left + m_width; +} + + +//-------------------------------------------------------------------------------------- +// GetImeId( UINT uIndex ) +// returns +// returned value: +// 0: In the following cases +// - Non Chinese IME input locale +// - Older Chinese IME +// - Other error cases +// +// Othewise: +// When uIndex is 0 (default) +// bit 31-24: Major version +// bit 23-16: Minor version +// bit 15-0: Language ID +// When uIndex is 1 +// pVerFixedInfo->dwFileVersionLS +// +// Use IMEID_VER and IMEID_LANG macro to extract version and language information. +// + +// We define the locale-invariant ID ourselves since it doesn't exist prior to WinXP +// For more information, see the CompareString() reference. +#define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) +//-------------------------------------------------------------------------------------- +// Enable/disable the entire IME system. When disabled, the default IME handling +// kicks in. +void CDXUTIMEEditBox::EnableImeSystem( bool bEnable ) +{ + ImeUi_EnableIme( bEnable ); +} + + +//-------------------------------------------------------------------------------------- +// Resets the composition string. +void CDXUTIMEEditBox::ResetCompositionString() +{ + s_CompString.SetText( L"" ); +} + + +//-------------------------------------------------------------------------------------- +// This function is used only briefly in CHT IME handling, +// so accelerator isn't processed. +void CDXUTIMEEditBox::PumpMessage() +{ + MSG msg; + + while( PeekMessageW( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + { + if( !GetMessageW( &msg, NULL, 0, 0 ) ) + { + PostQuitMessage( ( int )msg.wParam ); + return; + } + TranslateMessage( &msg ); + DispatchMessageA( &msg ); + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::OnFocusIn() +{ + ImeUi_EnableIme( s_bImeFlag ); + CDXUTEditBox::OnFocusIn(); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::OnFocusOut() +{ + ImeUi_FinalizeString(); + ImeUi_EnableIme( false ); + CDXUTEditBox::OnFocusOut(); +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTIMEEditBox::StaticMsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + + if( !ImeUi_IsEnabled() ) + return false; + +#if defined(DEBUG) || defined(_DEBUG) + m_bIMEStaticMsgProcCalled = true; +#endif + + switch( uMsg ) + { + case WM_INPUTLANGCHANGE: + DXUTTRACE( L"WM_INPUTLANGCHANGE\n" ); + { + } + return true; + + case WM_IME_SETCONTEXT: + DXUTTRACE( L"WM_IME_SETCONTEXT\n" ); + // + // We don't want anything to display, so we have to clear this + // + lParam = 0; + return false; + + // Handle WM_IME_STARTCOMPOSITION here since + // we do not want the default IME handler to see + // this when our fullscreen app is running. + case WM_IME_STARTCOMPOSITION: + DXUTTRACE( L"WM_IME_STARTCOMPOSITION\n" ); + ResetCompositionString(); + // Since the composition string has its own caret, we don't render + // the edit control's own caret to avoid double carets on screen. + s_bHideCaret = true; + return true; + case WM_IME_ENDCOMPOSITION: + DXUTTRACE( L"WM_IME_ENDCOMPOSITION\n" ); + s_bHideCaret = false; + return false; + case WM_IME_COMPOSITION: + DXUTTRACE( L"WM_IME_COMPOSITION\n" ); + return false; + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTIMEEditBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + + switch( uMsg ) + { + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + DXUTFontNode* pFont = m_pDialog->GetFont( m_Elements.GetAt( 9 )->iFont ); + + // Check if this click is on top of the composition string + int nCompStrWidth; + s_CompString.CPtoX( s_CompString.GetTextSize(), FALSE, &nCompStrWidth ); + + if( s_ptCompString.x <= pt.x && + s_ptCompString.y <= pt.y && + s_ptCompString.x + nCompStrWidth > pt.x && + s_ptCompString.y + pFont->nHeight > pt.y ) + { + int nCharBodyHit, nCharHit; + int nTrail; + + // Determine the character clicked on. + s_CompString.XtoCP( pt.x - s_ptCompString.x, &nCharBodyHit, &nTrail ); + if( nTrail && nCharBodyHit < s_CompString.GetTextSize() ) + nCharHit = nCharBodyHit + 1; + else + nCharHit = nCharBodyHit; + + + switch( GetPrimaryLanguage() ) + { + case LANG_JAPANESE: + // For Japanese, there are two cases. If s_nFirstTargetConv is + // -1, the comp string hasn't been converted yet, and we use + // s_nCompCaret. For any other value of s_nFirstTargetConv, + // the string has been converted, so we use clause information. + + if( s_nFirstTargetConv != -1 ) + { + int nClauseClicked = 0; + while( ( int )s_adwCompStringClause[nClauseClicked + 1] <= nCharBodyHit ) + ++nClauseClicked; + + int nClauseSelected = 0; + while( ( int )s_adwCompStringClause[nClauseSelected + 1] <= s_nFirstTargetConv ) + ++nClauseSelected; + + BYTE nVirtKey = nClauseClicked > nClauseSelected ? VK_RIGHT : VK_LEFT; + int nSendCount = abs( nClauseClicked - nClauseSelected ); + while( nSendCount-- > 0 ) + SendKey( nVirtKey ); + + return true; + } + + // Not converted case. Fall thru to Chinese case. + + case LANG_CHINESE: + { + // For Chinese, use s_nCompCaret. + BYTE nVirtKey = nCharHit > ( int )ImeUi_GetImeCursorChars() ? VK_RIGHT : VK_LEFT; + int nSendCount = abs( nCharHit - ( int )ImeUi_GetImeCursorChars() ); + while( nSendCount-- > 0 ) + SendKey( nVirtKey ); + break; + } + } + + return true; + } + + // Check if the click is on top of the candidate window + if( ImeUi_IsShowCandListWindow() && PtInRect( &s_CandList.rcCandidate, pt ) ) + { + if( ImeUi_IsVerticalCand() ) + { + // Vertical candidate window + + // Compute the row the click is on + int nRow = ( pt.y - s_CandList.rcCandidate.top ) / pFont->nHeight; + + if( nRow < ( int )ImeUi_GetCandidateCount() ) + { + // nRow is a valid entry. + // Now emulate keystrokes to select the candidate at this row. + switch( GetPrimaryLanguage() ) + { + case LANG_CHINESE: + case LANG_KOREAN: + // For Chinese and Korean, simply send the number keystroke. + SendKey( ( BYTE )( '0' + nRow + 1 ) ); + break; + + case LANG_JAPANESE: + // For Japanese, move the selection to the target row, + // then send Right, then send Left. + + BYTE nVirtKey; + if( nRow > ( int )ImeUi_GetCandidateSelection() ) + nVirtKey = VK_DOWN; + else + nVirtKey = VK_UP; + int nNumToHit = abs( int( nRow - ImeUi_GetCandidateSelection() ) ); + for( int nStrike = 0; nStrike < nNumToHit; ++nStrike ) + SendKey( nVirtKey ); + + // Do this to close the candidate window without ending composition. + SendKey( VK_RIGHT ); + SendKey( VK_LEFT ); + + break; + } + } + } + else + { + // Horizontal candidate window + + // Determine which the character the click has hit. + int nCharHit; + int nTrail; + s_CandList.HoriCand.XtoCP( pt.x - s_CandList.rcCandidate.left, &nCharHit, &nTrail ); + + // Determine which candidate string the character belongs to. + int nCandidate = ImeUi_GetCandidateCount() - 1; + + int nEntryStart = 0; + for( UINT i = 0; i < ImeUi_GetCandidateCount(); ++i ) + { + if( nCharHit >= nEntryStart ) + { + // Haven't found it. + nEntryStart += lstrlenW( ImeUi_GetCandidate( i ) ) + 1; // plus space separator + } + else + { + // Found it. This entry starts at the right side of the click point, + // so the char belongs to the previous entry. + nCandidate = i - 1; + break; + } + } + + // Now emulate keystrokes to select the candidate entry. + switch( GetPrimaryLanguage() ) + { + case LANG_CHINESE: + case LANG_KOREAN: + // For Chinese and Korean, simply send the number keystroke. + SendKey( ( BYTE )( '0' + nCandidate + 1 ) ); + break; + } + } + + return true; + } + } + } + + // If we didn't care for the msg, let the parent process it. + return CDXUTEditBox::HandleMouse( uMsg, pt, wParam, lParam ); +} + + +//-------------------------------------------------------------------------------------- +bool CDXUTIMEEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if( !m_bEnabled || !m_bVisible ) + return false; + +#if defined(DEBUG) || defined(_DEBUG) + // DXUT.cpp used to call CDXUTIMEEditBox::StaticMsgProc() so that, but now + // this is the application's responsiblity. To do this, call + // CDXUTDialogResourceManager::MsgProc() before calling this function. + assert( m_bIMEStaticMsgProcCalled && L"To fix, call CDXUTDialogResourceManager::MsgProc() first" ); +#endif + switch( uMsg ) + { + case WM_DESTROY: + ImeUi_Uninitialize(); + break; + } + + bool trappedData; + bool* trapped = &trappedData; + + *trapped = false; + if( !ImeUi_IsEnabled() ) + return CDXUTEditBox::MsgProc( uMsg, wParam, lParam ); + + ImeUi_ProcessMessage( DXUTGetHWND(), uMsg, wParam, lParam, trapped ); + if( *trapped == false ) + CDXUTEditBox::MsgProc( uMsg, wParam, lParam ); + + return *trapped; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::RenderCandidateReadingWindow( float fElapsedTime, bool bReading ) +{ + RECT rc; + UINT nNumEntries = bReading ? 4 : MAX_CANDLIST; + D3DCOLOR TextColor, TextBkColor, SelTextColor, SelBkColor; + int nX, nXFirst, nXComp; + m_Buffer.CPtoX( m_nCaret, FALSE, &nX ); + m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst ); + + if( bReading ) + { + TextColor = m_ReadingColor; + TextBkColor = m_ReadingWinColor; + SelTextColor = m_ReadingSelColor; + SelBkColor = m_ReadingSelBkColor; + } + else + { + TextColor = m_CandidateColor; + TextBkColor = m_CandidateWinColor; + SelTextColor = m_CandidateSelColor; + SelBkColor = m_CandidateSelBkColor; + } + + // For Japanese IME, align the window with the first target converted character. + // For all other IMEs, align with the caret. This is because the caret + // does not move for Japanese IME. + if( GetLanguage() == MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL ) && !GetImeId() ) + nXComp = 0; + else if( GetPrimaryLanguage() == LANG_JAPANESE ) + s_CompString.CPtoX( s_nFirstTargetConv, FALSE, &nXComp ); + else + s_CompString.CPtoX( ImeUi_GetImeCursorChars(), FALSE, &nXComp ); + + // Compute the size of the candidate window + int nWidthRequired = 0; + int nHeightRequired = 0; + int nSingleLineHeight = 0; + + if( ( ImeUi_IsVerticalCand() && !bReading ) || + ( !ImeUi_IsHorizontalReading() && bReading ) ) + { + // Vertical window + for( UINT i = 0; i < nNumEntries; ++i ) + { + if( *( ImeUi_GetCandidate( i ) ) == L'\0' ) + break; + SetRect( &rc, 0, 0, 0, 0 ); + m_pDialog->CalcTextRect( ImeUi_GetCandidate( i ), m_Elements.GetAt( 1 ), &rc ); + nWidthRequired = __max( nWidthRequired, rc.right - rc.left ); + nSingleLineHeight = __max( nSingleLineHeight, rc.bottom - rc.top ); + } + nHeightRequired = nSingleLineHeight * nNumEntries; + } + else + { + // Horizontal window + SetRect( &rc, 0, 0, 0, 0 ); + if( bReading ) + m_pDialog->CalcTextRect( s_wszReadingString, m_Elements.GetAt( 1 ), &rc ); + else + { + + WCHAR wszCand[256] = L""; + + s_CandList.nFirstSelected = 0; + s_CandList.nHoriSelectedLen = 0; + for( UINT i = 0; i < MAX_CANDLIST; ++i ) + { + if( *ImeUi_GetCandidate( i ) == L'\0' ) + break; + + WCHAR wszEntry[32]; + swprintf_s( wszEntry, 32, L"%s ", ImeUi_GetCandidate( i ) ); + // If this is the selected entry, mark its char position. + if( ImeUi_GetCandidateSelection() == i ) + { + s_CandList.nFirstSelected = lstrlen( wszCand ); + s_CandList.nHoriSelectedLen = lstrlen( wszEntry ) - 1; // Minus space + } + wcscat_s( wszCand, 256, wszEntry ); + } + wszCand[lstrlen( wszCand ) - 1] = L'\0'; // Remove the last space + s_CandList.HoriCand.SetText( wszCand ); + + m_pDialog->CalcTextRect( s_CandList.HoriCand.GetBuffer(), m_Elements.GetAt( 1 ), &rc ); + } + nWidthRequired = rc.right - rc.left; + nSingleLineHeight = nHeightRequired = rc.bottom - rc.top; + } + + // Now that we have the dimension, calculate the location for the candidate window. + // We attempt to fit the window in this order: + // bottom, top, right, left. + + bool bHasPosition = false; + + // Bottom + SetRect( &rc, s_ptCompString.x + nXComp, s_ptCompString.y + m_rcText.bottom - m_rcText.top, + s_ptCompString.x + nXComp + nWidthRequired, s_ptCompString.y + m_rcText.bottom - m_rcText.top + + nHeightRequired ); + // if the right edge is cut off, move it left. + if( rc.right > m_pDialog->GetWidth() ) + { + rc.left -= rc.right - m_pDialog->GetWidth(); + rc.right = m_pDialog->GetWidth(); + } + if( rc.bottom <= m_pDialog->GetHeight() ) + bHasPosition = true; + + // Top + if( !bHasPosition ) + { + SetRect( &rc, s_ptCompString.x + nXComp, s_ptCompString.y - nHeightRequired, + s_ptCompString.x + nXComp + nWidthRequired, s_ptCompString.y ); + // if the right edge is cut off, move it left. + if( rc.right > m_pDialog->GetWidth() ) + { + rc.left -= rc.right - m_pDialog->GetWidth(); + rc.right = m_pDialog->GetWidth(); + } + if( rc.top >= 0 ) + bHasPosition = true; + } + + // Right + if( !bHasPosition ) + { + int nXCompTrail; + s_CompString.CPtoX( ImeUi_GetImeCursorChars(), TRUE, &nXCompTrail ); + SetRect( &rc, s_ptCompString.x + nXCompTrail, 0, + s_ptCompString.x + nXCompTrail + nWidthRequired, nHeightRequired ); + if( rc.right <= m_pDialog->GetWidth() ) + bHasPosition = true; + } + + // Left + if( !bHasPosition ) + { + SetRect( &rc, s_ptCompString.x + nXComp - nWidthRequired, 0, + s_ptCompString.x + nXComp, nHeightRequired ); + if( rc.right >= 0 ) + bHasPosition = true; + } + + if( !bHasPosition ) + { + // The dialog is too small for the candidate window. + // Fall back to render at 0, 0. Some part of the window + // will be cut off. + rc.left = 0; + rc.right = nWidthRequired; + } + + // If we are rendering the candidate window, save the position + // so that mouse clicks are checked properly. + if( !bReading ) + s_CandList.rcCandidate = rc; + + // Render the elements + m_pDialog->DrawRect( &rc, TextBkColor ); + if( ( ImeUi_IsVerticalCand() && !bReading ) || + ( !ImeUi_IsHorizontalReading() && bReading ) ) + { + // Vertical candidate window + for( UINT i = 0; i < nNumEntries; ++i ) + { + // Here we are rendering one line at a time + rc.bottom = rc.top + nSingleLineHeight; + // Use a different color for the selected string + if( ImeUi_GetCandidateSelection() == i ) + { + m_pDialog->DrawRect( &rc, SelBkColor ); + m_Elements.GetAt( 1 )->FontColor.Current = SelTextColor; + } + else + m_Elements.GetAt( 1 )->FontColor.Current = TextColor; + + m_pDialog->DrawText( ImeUi_GetCandidate( i ), m_Elements.GetAt( 1 ), &rc ); + + rc.top += nSingleLineHeight; + } + } + else + { + // Horizontal candidate window + m_Elements.GetAt( 1 )->FontColor.Current = TextColor; + if( bReading ) + m_pDialog->DrawText( s_wszReadingString, m_Elements.GetAt( 1 ), &rc ); + else + m_pDialog->DrawText( s_CandList.HoriCand.GetBuffer(), m_Elements.GetAt( 1 ), &rc ); + + // Render the selected entry differently + if( !bReading ) + { + int nXLeft, nXRight; + s_CandList.HoriCand.CPtoX( s_CandList.nFirstSelected, FALSE, &nXLeft ); + s_CandList.HoriCand.CPtoX( s_CandList.nFirstSelected + s_CandList.nHoriSelectedLen, FALSE, &nXRight ); + + rc.right = rc.left + nXRight; + rc.left += nXLeft; + m_pDialog->DrawRect( &rc, SelBkColor ); + m_Elements.GetAt( 1 )->FontColor.Current = SelTextColor; + m_pDialog->DrawText( s_CandList.HoriCand.GetBuffer() + s_CandList.nFirstSelected, + m_Elements.GetAt( 1 ), &rc, false, s_CandList.nHoriSelectedLen ); + } + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::RenderComposition( float fElapsedTime ) +{ + + s_CompString.SetText( ImeUi_GetCompositionString() ); + + RECT rcCaret = + { + 0, 0, 0, 0 + }; + int nX, nXFirst; + m_Buffer.CPtoX( m_nCaret, FALSE, &nX ); + m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst ); + CDXUTElement* pElement = m_Elements.GetAt( 1 ); + + // Get the required width + RECT rc = + { + m_rcText.left + nX - nXFirst, m_rcText.top, + m_rcText.left + nX - nXFirst, m_rcText.bottom + }; + m_pDialog->CalcTextRect( s_CompString.GetBuffer(), pElement, &rc ); + + // If the composition string is too long to fit within + // the text area, move it to below the current line. + // This matches the behavior of the default IME. + if( rc.right > m_rcText.right ) + OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top ); + + // Save the rectangle position for processing highlighted text. + RECT rcFirst = rc; + + // Update s_ptCompString for RenderCandidateReadingWindow(). + s_ptCompString.x = rc.left; s_ptCompString.y = rc.top; + + + D3DCOLOR TextColor = m_CompColor; + // Render the window and string. + // If the string is too long, we must wrap the line. + pElement->FontColor.Current = TextColor; + const WCHAR* pwszComp = s_CompString.GetBuffer(); + int nCharLeft = s_CompString.GetTextSize(); + for(; ; ) + { + // Find the last character that can be drawn on the same line. + int nLastInLine; + int bTrail; + s_CompString.XtoCP( m_rcText.right - rc.left, &nLastInLine, &bTrail ); + int nNumCharToDraw = __min( nCharLeft, nLastInLine ); + m_pDialog->CalcTextRect( pwszComp, pElement, &rc, nNumCharToDraw ); + + // Draw the background + // For Korean IME, blink the composition window background as if it + // is a cursor. + if( GetPrimaryLanguage() == LANG_KOREAN ) + { + if( m_bCaretOn ) + { + m_pDialog->DrawRect( &rc, m_CompWinColor ); + } + else + { + // Not drawing composition string background. We + // use the editbox's text color for composition + // string text. + TextColor = m_Elements.GetAt( 0 )->FontColor.States[DXUT_STATE_NORMAL]; + } + } + else + { + // Non-Korean IME. Always draw composition background. + m_pDialog->DrawRect( &rc, m_CompWinColor ); + } + + // Draw the text + pElement->FontColor.Current = TextColor; + m_pDialog->DrawText( pwszComp, pElement, &rc, false, nNumCharToDraw ); + + // Advance pointer and counter + nCharLeft -= nNumCharToDraw; + pwszComp += nNumCharToDraw; + if( nCharLeft <= 0 ) + break; + + // Advance rectangle coordinates to beginning of next line + OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top ); + } + + // Load the rect for the first line again. + rc = rcFirst; + + // Inspect each character in the comp string. + // For target-converted and target-non-converted characters, + // we display a different background color so they appear highlighted. + int nCharFirst = 0; + nXFirst = 0; + s_nFirstTargetConv = -1; + BYTE* pAttr; + const WCHAR* pcComp; + for( pcComp = s_CompString.GetBuffer(), pAttr = ImeUi_GetCompStringAttr(); + *pcComp != L'\0'; ++pcComp, ++pAttr ) + { + D3DCOLOR bkColor; + + // Render a different background for this character + int nXLeft, nXRight; + s_CompString.CPtoX( int( pcComp - s_CompString.GetBuffer() ), FALSE, &nXLeft ); + s_CompString.CPtoX( int( pcComp - s_CompString.GetBuffer() ), TRUE, &nXRight ); + + // Check if this character is off the right edge and should + // be wrapped to the next line. + if( nXRight - nXFirst > m_rcText.right - rc.left ) + { + // Advance rectangle coordinates to beginning of next line + OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top ); + + // Update the line's first character information + nCharFirst = int( pcComp - s_CompString.GetBuffer() ); + s_CompString.CPtoX( nCharFirst, FALSE, &nXFirst ); + } + + // If the caret is on this character, save the coordinates + // for drawing the caret later. + if( ImeUi_GetImeCursorChars() == ( DWORD )( pcComp - s_CompString.GetBuffer() ) ) + { + rcCaret = rc; + rcCaret.left += nXLeft - nXFirst - 1; + rcCaret.right = rcCaret.left + 2; + } + + // Set up color based on the character attribute + if( *pAttr == ATTR_TARGET_CONVERTED ) + { + pElement->FontColor.Current = m_CompTargetColor; + bkColor = m_CompTargetBkColor; + } + else if( *pAttr == ATTR_TARGET_NOTCONVERTED ) + { + pElement->FontColor.Current = m_CompTargetNonColor; + bkColor = m_CompTargetNonBkColor; + } + else + { + continue; + } + + RECT rcTarget = + { + rc.left + nXLeft - nXFirst, rc.top, rc.left + nXRight - nXFirst, rc.bottom + }; + m_pDialog->DrawRect( &rcTarget, bkColor ); + m_pDialog->DrawText( pcComp, pElement, &rcTarget, false, 1 ); + + // Record the first target converted character's index + if( -1 == s_nFirstTargetConv ) + s_nFirstTargetConv = int( pAttr - ImeUi_GetCompStringAttr() ); + } + + // Render the composition caret + if( m_bCaretOn ) + { + // If the caret is at the very end, its position would not have + // been computed in the above loop. We compute it here. + if( ImeUi_GetImeCursorChars() == ( DWORD )s_CompString.GetTextSize() ) + { + s_CompString.CPtoX( ImeUi_GetImeCursorChars(), FALSE, &nX ); + rcCaret = rc; + rcCaret.left += nX - nXFirst - 1; + rcCaret.right = rcCaret.left + 2; + } + + m_pDialog->DrawRect( &rcCaret, m_CompCaretColor ); + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::RenderIndicator( float fElapsedTime ) +{ + CDXUTElement* pElement = m_Elements.GetAt( 9 ); + pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime ); + + m_pDialog->DrawSprite( pElement, &m_rcIndicator, DXUT_NEAR_BUTTON_DEPTH ); + RECT rc = m_rcIndicator; + InflateRect( &rc, -m_nSpacing, -m_nSpacing ); + + pElement->FontColor.Current = m_IndicatorImeColor; + RECT rcCalc = + { + 0, 0, 0, 0 + }; + // If IME system is off, draw English indicator. + WCHAR* pwszIndicator = ImeUi_IsEnabled() ? ImeUi_GetIndicatior() : L"En"; + + m_pDialog->CalcTextRect( pwszIndicator, pElement, &rcCalc ); + m_pDialog->DrawText( pwszIndicator, pElement, &rc ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::Render( float fElapsedTime ) +{ + if( m_bVisible == false ) + return; + + // If we have not computed the indicator symbol width, + // do it. + if( !m_nIndicatorWidth ) + { + RECT rc = + { + 0, 0, 0, 0 + }; + m_pDialog->CalcTextRect( L"En", m_Elements.GetAt( 9 ), &rc ); + m_nIndicatorWidth = rc.right - rc.left; + + // Update the rectangles now that we have the indicator's width + UpdateRects(); + } + + // Let the parent render first (edit control) + CDXUTEditBox::Render( fElapsedTime ); + + CDXUTElement* pElement = GetElement( 1 ); + if( pElement ) + { + s_CompString.SetFontNode( m_pDialog->GetFont( pElement->iFont ) ); + s_CandList.HoriCand.SetFontNode( m_pDialog->GetFont( pElement->iFont ) ); + } + + // + // Now render the IME elements + // + + ImeUi_RenderUI(); + + if( m_bHasFocus ) + { + // Render the input locale indicator + RenderIndicator( fElapsedTime ); + + // Display the composition string. + // This method should also update s_ptCompString + // for RenderCandidateReadingWindow. + RenderComposition( fElapsedTime ); + + // Display the reading/candidate window. RenderCandidateReadingWindow() + // uses s_ptCompString to position itself. s_ptCompString must have + // been filled in by RenderComposition(). + if( ImeUi_IsShowReadingWindow() ) + // Reading window + RenderCandidateReadingWindow( fElapsedTime, true ); + else if( ImeUi_IsShowCandListWindow() ) + // Candidate list window + RenderCandidateReadingWindow( fElapsedTime, false ); + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::SetImeEnableFlag( bool bFlag ) +{ + s_bImeFlag = bFlag; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTIMEEditBox::Initialize( HWND hWnd ) +{ + ImeUiCallback_DrawRect = NULL; + ImeUiCallback_Malloc = malloc; + ImeUiCallback_Free = free; + ImeUiCallback_DrawFans = NULL; + + ImeUi_Initialize( hWnd ); + + s_CompString.SetBufferSize( MAX_COMPSTRING_SIZE ); + ImeUi_EnableIme( true ); +} + + diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.h b/Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.h new file mode 100644 index 0000000..6739be3 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTguiIME.h @@ -0,0 +1,141 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTguiIME.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_IME_H +#define DXUT_IME_H + +#include +#include +#include + + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- +class CDXUTIMEEditBox; + + +//----------------------------------------------------------------------------- +// IME-enabled EditBox control +//----------------------------------------------------------------------------- +#define MAX_COMPSTRING_SIZE 256 + + +class CDXUTIMEEditBox : public CDXUTEditBox +{ +public: + + static HRESULT CreateIMEEditBox( CDXUTDialog* pDialog, int ID, LPCWSTR strText, int x, int y, int width, + int height, bool bIsDefault=false, CDXUTIMEEditBox** ppCreated=NULL ); + + CDXUTIMEEditBox( CDXUTDialog* pDialog = NULL ); + virtual ~CDXUTIMEEditBox(); + + static void InitDefaultElements( CDXUTDialog* pDialog ); + + static void WINAPI Initialize( HWND hWnd ); + static void WINAPI Uninitialize(); + + static HRESULT WINAPI StaticOnCreateDevice(); + static bool WINAPI StaticMsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + static void WINAPI SetImeEnableFlag( bool bFlag ); + + virtual void Render( float fElapsedTime ); + virtual bool MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ); + virtual bool HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ); + virtual void UpdateRects(); + virtual void OnFocusIn(); + virtual void OnFocusOut(); + + void PumpMessage(); + + virtual void RenderCandidateReadingWindow( float fElapsedTime, bool bReading ); + virtual void RenderComposition( float fElapsedTime ); + virtual void RenderIndicator( float fElapsedTime ); + +protected: + static void WINAPI EnableImeSystem( bool bEnable ); + + static WORD WINAPI GetLanguage() + { + return ImeUi_GetLanguage(); + } + static WORD WINAPI GetPrimaryLanguage() + { + return ImeUi_GetPrimaryLanguage(); + } + static void WINAPI SendKey( BYTE nVirtKey ); + static DWORD WINAPI GetImeId( UINT uIndex = 0 ) + { + return ImeUi_GetImeId( uIndex ); + }; + static void WINAPI CheckInputLocale(); + static void WINAPI CheckToggleState(); + static void WINAPI SetupImeApi(); + static void WINAPI ResetCompositionString(); + + + static void SetupImeUiCallback(); + +protected: + enum + { + INDICATOR_NON_IME, + INDICATOR_CHS, + INDICATOR_CHT, + INDICATOR_KOREAN, + INDICATOR_JAPANESE + }; + + struct CCandList + { + CUniBuffer HoriCand; // Candidate list string (for horizontal candidate window) + int nFirstSelected; // First character position of the selected string in HoriCand + int nHoriSelectedLen; // Length of the selected string in HoriCand + RECT rcCandidate; // Candidate rectangle computed and filled each time before rendered + }; + + static POINT s_ptCompString; // Composition string position. Updated every frame. + static int s_nFirstTargetConv; // Index of the first target converted char in comp string. If none, -1. + static CUniBuffer s_CompString; // Buffer to hold the composition string (we fix its length) + static DWORD s_adwCompStringClause[MAX_COMPSTRING_SIZE]; + static CCandList s_CandList; // Data relevant to the candidate list + static WCHAR s_wszReadingString[32];// Used only with horizontal reading window (why?) + static bool s_bImeFlag; // Is ime enabled + + // Color of various IME elements + D3DCOLOR m_ReadingColor; // Reading string color + D3DCOLOR m_ReadingWinColor; // Reading window color + D3DCOLOR m_ReadingSelColor; // Selected character in reading string + D3DCOLOR m_ReadingSelBkColor; // Background color for selected char in reading str + D3DCOLOR m_CandidateColor; // Candidate string color + D3DCOLOR m_CandidateWinColor; // Candidate window color + D3DCOLOR m_CandidateSelColor; // Selected candidate string color + D3DCOLOR m_CandidateSelBkColor; // Selected candidate background color + D3DCOLOR m_CompColor; // Composition string color + D3DCOLOR m_CompWinColor; // Composition string window color + D3DCOLOR m_CompCaretColor; // Composition string caret color + D3DCOLOR m_CompTargetColor; // Composition string target converted color + D3DCOLOR m_CompTargetBkColor; // Composition string target converted background + D3DCOLOR m_CompTargetNonColor; // Composition string target non-converted color + D3DCOLOR m_CompTargetNonBkColor;// Composition string target non-converted background + D3DCOLOR m_IndicatorImeColor; // Indicator text color for IME + D3DCOLOR m_IndicatorEngColor; // Indicator text color for English + D3DCOLOR m_IndicatorBkColor; // Indicator text background color + + // Edit-control-specific data + int m_nIndicatorWidth; // Width of the indicator symbol + RECT m_rcIndicator; // Rectangle for drawing the indicator button + +#if defined(DEBUG) || defined(_DEBUG) + static bool m_bIMEStaticMsgProcCalled; +#endif +}; + + + +#endif // DXUT_IME_H diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTres.cpp b/Demos/DX11ClothDemo/DXUT/Optional/DXUTres.cpp new file mode 100644 index 0000000..c91080a --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTres.cpp @@ -0,0 +1,8338 @@ +//---------------------------------------------------------------------------- +// File: DXUTRes.cpp +// +// Copyright (c) Microsoft Corp. All rights reserved. +//----------------------------------------------------------------------------- +#include "DXUT.h" +#include "DXUTres.h" + +static const DWORD g_DXUTGUITextureSrcData[] = +{ + 0x20534444, 0x0000007c, 0x00001007, 0x00000100, 0x00000100, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0x00000041, 0x00000000, 0x00000020, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0xff000000, 0x00001002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000400, 0x11000400, 0x11000400, 0x11000400, + 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, 0x11000400, + 0x11000000, 0x00000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000400, 0x22000400, 0x22000400, 0x22000400, + 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, 0x22000400, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x22000000, 0x33000000, 0x44000000, + 0x44000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x66000000, 0x66000000, + 0x66000400, 0x66000400, 0x66000400, 0x66000400, 0x66000000, 0x66000000, 0x661e1e1e, 0x771e1e1e, + 0x771e1c1e, 0x771e1c1e, 0x771e1c1e, 0x771e1c1e, 0x771e1e1e, 0x771e1e1e, 0x771e1e1e, 0x771e1e1e, + 0x771e1c1e, 0x881e1c1e, 0x881e1c1e, 0x881e1c1e, 0x88373937, 0x88373937, 0x881b1c1b, 0x881b1c1b, + 0x881e201e, 0x881e201e, 0x881e201e, 0x881e201e, 0x88313631, 0x88313631, 0x88313631, 0x88191b19, + 0x881b1f1b, 0x881b1f1b, 0x881b1f1b, 0x881b1f1b, 0x881b1e1b, 0x881b1e1b, 0x881b1e1b, 0x88373737, + 0x88313331, 0x88313331, 0x88313331, 0x88313331, 0x881b1f1b, 0x881b1f1b, 0x881b1f1b, 0x881b1f1b, + 0x881b1f1b, 0x881b1f1b, 0x881b1f1b, 0x881b1f1b, 0x88191e19, 0x88191e19, 0x88191e19, 0x77191e19, + 0x77191a19, 0x77191a19, 0x77191a19, 0x77191a19, 0x77191719, 0x77191719, 0x77191719, 0x66191719, + 0x66161616, 0x66161616, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x44000000, 0x44000000, + 0x44000000, 0x33000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x22000400, 0x22000400, 0x333c413c, 0x443c3d3f, 0x443c3d3f, 0x443c3d3f, 0x553c3d3f, + 0x66454145, 0x77454145, 0x77454145, 0x88817d81, 0x99797779, 0x99797779, 0x99797779, 0x99797779, + 0x99797979, 0xaa797979, 0xaa797979, 0xaa797979, 0xbb7e7c7e, 0xcc7e7c7e, 0xbb7e7c7e, 0xbb7e7c7e, + 0xbb7e7f7e, 0xbb7e7f7e, 0xcc7e7f7e, 0xcc7e7f7e, 0xcc7e7f7e, 0xcc7e7f7e, 0xcc7e7f7e, 0xcc7e7f7e, + 0xbb7e7c7e, 0xcc7c7b7d, 0xcc7a7879, 0xbb707071, 0xbb686869, 0xbb5d6060, 0xbb565858, 0xbb4d4f4c, + 0xcc454745, 0xcc3c3b3e, 0x77383838, 0x55393837, 0x55373737, 0x44373737, 0x33373737, 0x33373937, + 0x22000400, 0x22000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, + 0x22000000, 0x33000000, 0x44000000, 0x55000000, 0x55030303, 0x66030303, 0x66050505, 0x66080808, + 0x66101010, 0x77212021, 0x77212021, 0x77313131, 0x88373637, 0x88373637, 0x99525152, 0x99525152, + 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, + 0x995a555a, 0x995a555a, 0x995a555a, 0x995a555a, 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, + 0x995a555a, 0x995a555a, 0x995a555a, 0x995a555a, 0x99525552, 0x99525552, 0x99525552, 0x99525552, + 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, 0x994a514a, 0x994a514a, 0x994a514a, 0x994a514a, + 0x99525552, 0x99525552, 0x99525552, 0x99525552, 0x99525152, 0x99525152, 0x99525152, 0x99525152, + 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x99525552, 0x99525552, 0x99525552, 0x99525552, + 0x99525552, 0x99525552, 0x99525552, 0x99525552, 0x994a514a, 0x994a514a, 0x994a514a, 0x994a514a, + 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x994a454a, 0x994a454a, 0x994a454a, 0x994a454a, + 0x99424142, 0x99424142, 0x99424142, 0x99424142, 0x99424142, 0x99424142, 0x99424142, 0x992c2b2c, + 0x88293129, 0x881b201b, 0x771b201b, 0x771b201b, 0x66101010, 0x66101010, 0x660b0b0b, 0x66050505, + 0x66000400, 0x66000100, 0x55000100, 0x55000000, 0x55000000, 0x44000000, 0x33000000, 0x22000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080708, 0x11100d10, 0x11100d10, 0x22191419, + 0x33212324, 0x55424647, 0x66424647, 0x8863696b, 0x99737473, 0xbb737473, 0xccadaead, 0xeeadaead, + 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5b6bd, 0xffb5b6bd, 0xffb5b6bd, 0xffb5b6bd, + 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, + 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, + 0xffbdbabd, 0xffbcbabd, 0xffbcb8bc, 0xffb6b2b6, 0xffb3afb3, 0xffb0aeaf, 0xffadabaa, 0xffaaa9aa, + 0xffa9a7a8, 0xffa7a7a7, 0xffa6a6a6, 0xffa6a6a5, 0xffa6a6a5, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a2a5, + 0xffa5a2a5, 0xffa5a2a5, 0xeea5a2a5, 0xdd9c9a9c, 0xcc9c9a9c, 0xaa686768, 0x99686768, 0x885a5d5a, + 0x553c3e3c, 0x443c3e3c, 0x331e1f1e, 0x11101010, 0x11101010, 0x110b0b0b, 0x00050505, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000400, 0x33000400, 0x44000400, 0x55000400, + 0x66080808, 0x66080808, 0x663a3a3a, 0x773a3a3a, 0x885a5d5a, 0x886b6f6e, 0x996b6f6e, 0x997b8081, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99797879, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x996b716b, 0x99737773, 0x996b716b, 0x996b716b, + 0x99737173, 0x99797779, 0x99737173, 0x99737173, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x99636563, 0x99636563, 0x99636563, 0x99636563, + 0x99636163, 0x99636163, 0x99636163, 0x99636163, 0x995a5d5a, 0x995a5d5a, 0x995a5d5a, 0x995a5d5a, + 0x995a5552, 0x995a5552, 0x995a5552, 0x995a5552, 0x994a4d50, 0x994a4d50, 0x994a4d50, 0x9931353a, + 0x88313331, 0x88313331, 0x77101010, 0x66101010, 0x66080408, 0x66080408, 0x66080408, 0x55080408, + 0x55000000, 0x44000000, 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11191819, 0x22191819, 0x33191819, 0x66656465, 0x887b7d7b, 0xbba2a5a5, 0xddc8ccce, 0xffc8ccce, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd9d8d9, 0xffd6d2d6, 0xffd6d2d6, 0xffd6cece, 0xffcfcccc, 0xffc8c7c8, 0xffc6c2c3, + 0xffc4c0c2, 0xffc2c0c2, 0xffc5c2c4, 0xffc4c2c5, 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, 0xffbdbebd, + 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffa5a6a5, + 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, 0xee868a86, 0xdd868a86, 0xaa868a86, 0x885a615a, 0x55505250, + 0x33101410, 0x11101410, 0x11101410, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x44000000, 0x55000400, 0x66000400, 0x77343634, 0x77686868, + 0x886b6c6b, 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x998c9294, 0x998c9294, 0x998c9294, 0x998c9294, + 0x998c8e8c, 0x99868786, 0x99868786, 0x99868786, 0x99848384, 0x99848384, 0x99848384, 0x99848384, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x997e7f7e, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x997e7c7e, 0x99848284, + 0x9984827b, 0x9984827b, 0x9984827b, 0x9984827b, 0x99848284, 0x99848284, 0x99848284, 0x997e7c7e, + 0x99848284, 0x997e7c7e, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x997b7c7b, + 0x997e7c7e, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x997b7b7b, 0x99848284, 0x99848284, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99767776, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99737373, 0x997b797b, + 0x99737473, 0x99737473, 0x99737473, 0x99737473, 0x997b797b, 0x997b797b, 0x997b797b, 0x99707070, + 0x9970706e, 0x9970706e, 0x9970706e, 0x9970706e, 0x99636565, 0x99636565, 0x99636565, 0x99636565, + 0x99525652, 0x99525652, 0x99525652, 0x99525652, 0x99504d50, 0x882c282c, 0x772c282c, 0x77080408, + 0x66000000, 0x66000000, 0x55000000, 0x55000000, 0x44000000, 0x22000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x11000000, 0x33525452, 0x77525452, + 0xaab2afb2, 0xddfffbff, 0xfffffbff, 0xfffffbff, 0xffeff3f7, 0xffeff3f7, 0xffeff3f7, 0xffeff3f7, + 0xffefefef, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, + 0xffe1e4e1, 0xffe1e4e1, 0xffe1e4e1, 0xffe1e4e1, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe1e1e1, + 0xffe6e1e6, 0xffe6e1e6, 0xffe6e1e6, 0xffe6e1e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, + 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe1dde1, + 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, + 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3dd, 0xffdee3dd, 0xffdee1de, 0xffdee0db, + 0xffdedbd9, 0xffe2dddc, 0xffdbd9db, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd3d4d3, + 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffcbc9cb, + 0xffcbc9cb, 0xffcbc9cb, 0xffcbc9cb, 0xffb2b2b2, 0xffb2b2b2, 0xffb2b2b2, 0xffb2b2b2, 0xff8f908f, + 0xff8f908f, 0xbb8f908f, 0x88505250, 0x663c3d3c, 0x333c3d3c, 0x11000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x44000000, 0x55000000, 0x77343234, 0x77686868, 0x999c9a9c, 0x999c9a9c, 0x999c9a9c, + 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x998c9294, 0x998c9294, 0x998c9294, 0x998c9294, + 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x997e7f7e, 0x99848684, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, + 0x9984827b, 0x9984827b, 0x9984827b, 0x9984827b, 0x99848284, 0x99848284, 0x997e7c7e, 0x997e7c7e, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x997b7c7b, 0x997b7c7b, + 0x99848284, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x99848284, 0x99848284, 0x997b7b7b, 0x997b7b7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x99737973, 0x99737973, 0x99737973, 0x99737973, 0x99737173, 0x99737173, 0x99504d50, 0x99504d50, + 0x88424142, 0x88212021, 0x77212021, 0x66000000, 0x55000000, 0x55000000, 0x44000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x22000400, 0x66525452, 0xaaa5a7a5, 0xeef7fbf7, 0xfff7fbf7, + 0xfffffbff, 0xfffffbff, 0xfffffbff, 0xfffffbff, 0xffeff3f7, 0xffeff3f7, 0xffeff3f7, 0xffeff3f7, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, + 0xffe6ebe6, 0xffe6ebe6, 0xffe1e4e1, 0xffe1e4e1, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, + 0xffe6e1e6, 0xffe6e1e6, 0xffe6e1e6, 0xffefe7ef, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, + 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffe6e3e6, 0xffe6e3e6, 0xffe1dde1, 0xffe6e3e6, + 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffe6e3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, + 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdee3de, + 0xffe5e2df, 0xffe1e0dd, 0xffdcdbdc, 0xffdddfe0, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffb5b6b5, 0xdd797979, 0xaa797979, 0x663c3d3c, 0x22000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22000000, + 0x55000000, 0x77343234, 0x88686468, 0x999c969c, 0x999c9a9c, 0x999c9a9c, 0x999c9a9c, 0x999c9a9c, + 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x998c9294, 0x998c9294, 0x998c9294, 0x998c9294, + 0x99868786, 0x99868786, 0x99868786, 0x99868786, 0x99848384, 0x99848384, 0x99848384, 0x99848384, + 0x997e807e, 0x997e807e, 0x997e807e, 0x997e807e, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, + 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, + 0x997e7c79, 0x997e7c79, 0x997e7c79, 0x99797776, 0x99797779, 0x99797779, 0x997e7c7e, 0x997e7c7e, + 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997b7c7b, 0x997b7c7b, 0x99737773, 0x997b7c7b, + 0x99797779, 0x997e7c7e, 0x99797779, 0x997e7c7e, 0x997b7b7b, 0x997b7b7b, 0x997b7b7b, 0x997b7b7b, + 0x99767876, 0x99767876, 0x99767876, 0x99767876, 0x99767876, 0x99767876, 0x99767876, 0x99767876, + 0x99767776, 0x997b7d7b, 0x997b7d7b, 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x99737973, 0x99737973, 0x99737973, 0x99737973, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99636163, 0x99636163, 0x99424142, 0x88212021, 0x77191419, 0x66000000, 0x55000000, 0x55000000, + 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x11000400, 0x66797b79, 0xccb5b6b5, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, + 0xfffffbff, 0xfffffbff, 0xfffffbff, 0xfffffbff, 0xffeff3f7, 0xffeff3f7, 0xffeff3f7, 0xffeff3f7, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, + 0xffe1e4e1, 0xffe1e4e1, 0xffe1e4e1, 0xffdbdddb, 0xffe1e1e1, 0xffe1e1e1, 0xffdbdcdb, 0xffe1e1e1, + 0xffdedcde, 0xffdedcde, 0xffdedcde, 0xffdedcde, 0xffe1dde1, 0xffe1dde1, 0xffe1dde1, 0xffe1dde1, + 0xffe1dddb, 0xffe1dddb, 0xffe1dddb, 0xffe1dddb, 0xffe1dde1, 0xffe1dde1, 0xffe1dde1, 0xffe1dde1, + 0xffe1dddb, 0xffe1dddb, 0xffe1dddb, 0xffe1dddb, 0xffdbdddb, 0xffdbdddb, 0xffdbdddb, 0xffdbdddb, + 0xffdbdddb, 0xffdbdddb, 0xffdbdddb, 0xffdbdddb, 0xffdbdcd9, 0xffdbdcd9, 0xffdcdcda, 0xffdcdbda, + 0xffdddadb, 0xffddd9dc, 0xffdad8d9, 0xffd7dadb, 0xffdbdddc, 0xffdddfdd, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xbb737973, + 0x664d524d, 0x11000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080808, 0x00080808, 0x33080808, 0x66080808, + 0x8852555a, 0x99848686, 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, 0x999c9e9c, + 0x99949294, 0x99949294, 0x99949294, 0x99898889, 0x998c8684, 0x998c8684, 0x998c8684, 0x9984807e, + 0x99848284, 0x99848284, 0x99848284, 0x997b7b7e, 0x997b7d7b, 0x997b7d7b, 0x99767876, 0x99767876, + 0x997b797b, 0x997b797b, 0x99767576, 0x99767576, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737473, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99767570, 0x99767570, 0x997b7973, 0x99767570, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99767576, 0x99767576, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7973, 0x9973706e, 0x996b6768, 0x99635d63, 0x994a4a4a, 0x77292b29, 0x66080c08, 0x66080c08, + 0x66000000, 0x33000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x333a393a, 0xbbb2b2b2, 0xeeefefef, 0xffefefef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xfff7f7f7, 0xfff7f7f7, 0xffececec, 0xffececec, 0xffefebe6, 0xffefebe6, 0xffe6e4e1, 0xffe6e4e1, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffdedce1, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd3d7d3, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd3d7d3, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d6d6, 0xffd8d7d6, + 0xffd8d6d7, 0xffd8d3d6, 0xffd8d3d7, 0xffd9d4d8, 0xffd9d6d9, 0xffd8d7d7, 0xffd6d7d6, 0xffd3d7d3, + 0xffd3d7d3, 0xffd3d7d3, 0xffd6dbd6, 0xffd3d7d3, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbde, + 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffd6dbd6, 0xffd0d1ce, 0xffd0d1ce, 0xffc5bebd, 0xffc5c6c5, + 0xee9a9797, 0xaa6e6868, 0x3342393a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080808, 0x33080808, 0x66080808, 0x885a595a, + 0x99848686, 0x99848686, 0x999c9e9c, 0x999c9e9c, 0x99919291, 0x99919291, 0x99919291, 0x99919291, + 0x99898889, 0x99898889, 0x99898889, 0x997e7f7e, 0x9984807e, 0x997b7b79, 0x997b7b79, 0x997b7b79, + 0x997b7b7e, 0x997b7b7e, 0x997b7b7e, 0x99737479, 0x99767876, 0x99767876, 0x99707370, 0x99707370, + 0x99767576, 0x99767576, 0x99767576, 0x99767576, 0x99737573, 0x99737573, 0x99737573, 0x99707370, + 0x99707370, 0x99707370, 0x99707370, 0x99707370, 0x99707370, 0x99707370, 0x99707370, 0x99707370, + 0x996e706e, 0x99707370, 0x99707370, 0x996e706e, 0x99707370, 0x99707370, 0x99707370, 0x996e706e, + 0x996e706e, 0x996e706e, 0x996e706e, 0x996e706e, 0x99707370, 0x996e706e, 0x99707370, 0x99707370, + 0x99737173, 0x99737473, 0x99737373, 0x99737173, 0x99737370, 0x99737370, 0x99737370, 0x99737370, + 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737373, + 0x9970716e, 0x99767570, 0x99767570, 0x99767570, 0x99737573, 0x99737370, 0x99737370, 0x99737370, + 0x99737370, 0x99737573, 0x99737370, 0x99737370, 0x99707370, 0x99707370, 0x99707370, 0x99707370, + 0x99707373, 0x99707373, 0x99707373, 0x99707373, 0x99707370, 0x99707370, 0x99707370, 0x99707370, + 0x99707370, 0x99707370, 0x99707370, 0x99707370, 0x99767576, 0x99767576, 0x99767576, 0x99767576, + 0x99767576, 0x99767576, 0x99767576, 0x99767576, 0x99767876, 0x99767876, 0x99767876, 0x99767876, + 0x997b7973, 0x997b7973, 0x997b7973, 0x9973706e, 0x996b696b, 0x994a4a4a, 0x88292b29, 0x77080c08, + 0x66000000, 0x66000000, 0x33000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x55474847, + 0xddb2b2b2, 0xffefefef, 0xffefefef, 0xffefefef, 0xfff4f3f4, 0xfff4f3f4, 0xfff4f3f4, 0xfff4f3f4, + 0xffececec, 0xffececec, 0xffe1e1e1, 0xffe1e1e1, 0xffe6e4e1, 0xffdedddb, 0xffdedddb, 0xffdedddb, + 0xffdedce1, 0xffdedce1, 0xffdedce1, 0xffd6d5db, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd3d4d3, + 0xffd9d7d9, 0xffd9d7d9, 0xffd9d7d9, 0xffd9d7d9, 0xffd3d7d3, 0xffd3d7d3, 0xffd3d7d3, 0xffd3d7d3, + 0xffd3d7d3, 0xffd3d7d3, 0xffd3d7d3, 0xffd0d2d0, 0xffd3d7d3, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, + 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, + 0xffd3d4d3, 0xffd0d1d0, 0xffd3d4d3, 0xffd0d1d0, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, + 0xffd0d4d0, 0xffd3d5d3, 0xffd0d4d0, 0xffd3d5d3, 0xffd6d4d3, 0xffd6d4d3, 0xffd6d4d3, 0xffd7d4d4, + 0xffd6d2d3, 0xffd5cfd3, 0xffd5d0d4, 0xffd5d3d4, 0xffd5d5d4, 0xffd2d5d3, 0xffd3d4d3, 0xffd3d7d3, + 0xffd3d7d3, 0xffd3d7d3, 0xffd3d7d3, 0xffd0d2d0, 0xffd3d7d3, 0xffd3d7d3, 0xffd0d2d0, 0xffd3d7d9, + 0xffd3d7d9, 0xffd3d7d9, 0xffd3d7d9, 0xffd3d4d3, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, + 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd0d1ce, 0xffc5c6c5, + 0xffc5c6c5, 0xff9a9797, 0xcc9a9797, 0x55313231, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33080808, 0x66080808, 0x995a595a, 0x99848284, + 0x99848686, 0x99848686, 0x99848686, 0x99848686, 0x99919291, 0x99868686, 0x99868686, 0x99868686, + 0x997e7f7e, 0x997e7f7e, 0x99737573, 0x99737573, 0x997b7b79, 0x997b7b79, 0x99737573, 0x99737573, + 0x99737479, 0x99737479, 0x99737479, 0x99737479, 0x99707370, 0x99707370, 0x99707370, 0x99707370, + 0x99707170, 0x99707170, 0x99707170, 0x996b6d6b, 0x996e706e, 0x996e706e, 0x996e706e, 0x996b6d6b, + 0x996e706e, 0x996e706e, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996b6d6b, 0x996e706e, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996e706e, 0x996e706e, 0x996e706e, 0x996b6d6b, 0x996e706e, 0x996e706e, 0x996e706e, 0x996e706e, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x9973706e, 0x9973706e, 0x9973706e, 0x9973706e, + 0x99737073, 0x99737073, 0x99737073, 0x99737373, 0x99737373, 0x99737073, 0x99737073, 0x99737073, + 0x9970716e, 0x9970716e, 0x9970716e, 0x9970716e, 0x9973706e, 0x99737370, 0x9973706e, 0x9973706e, + 0x9973706e, 0x9973706e, 0x99737370, 0x99737370, 0x99707370, 0x99707370, 0x996e706e, 0x996e706e, + 0x996e7073, 0x996e7073, 0x996e7073, 0x996e7073, 0x996e706e, 0x996e706e, 0x996e706e, 0x996e706e, + 0x996e706e, 0x996e706e, 0x996e706e, 0x996e706e, 0x99707170, 0x99707170, 0x99707170, 0x99707170, + 0x99707170, 0x99707170, 0x99707170, 0x99707170, 0x99707370, 0x99707370, 0x99707370, 0x99707370, + 0x997b7973, 0x9973706e, 0x9973706e, 0x9973706e, 0x996b696b, 0x996b696b, 0x994a4a4a, 0x99292b29, + 0x66101010, 0x66000000, 0x66000000, 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66474847, 0xeed6d7d6, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xfff4f3f4, 0xffe9e7e9, 0xffe9e7e9, 0xffe9e7e9, + 0xffe1e1e1, 0xffe1e1e1, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d5db, 0xffd6d5db, 0xffd6d5db, 0xffd6d5db, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, + 0xffd3d2d3, 0xffd3d2d3, 0xffd3d2d3, 0xffcecece, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffcecece, + 0xffd0d2d0, 0xffd0d2d0, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd3d4d3, 0xffd0d1d0, 0xffd0d1d0, + 0xffced2ce, 0xffd0d4d0, 0xffd0d4d0, 0xffced2ce, 0xffd6d1d0, 0xffd6d1d0, 0xffd6d4d3, 0xffd6d2d2, + 0xffd6d2d3, 0xffd4d0d2, 0xffd4d0d3, 0xffd5d2d5, 0xffd6d3d6, 0xffd5d4d5, 0xffd3d4d3, 0xffd0d2d0, + 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d3, + 0xffd0d2d3, 0xffd0d2d3, 0xffd0d2d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, + 0xffd3d4d3, 0xffd9d9d9, 0xffd9d9d9, 0xffd6dbd6, 0xffd0d1ce, 0xffd0d1ce, 0xffd0d1ce, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xff9a9797, 0xdd949694, 0x44313231, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x66080808, 0x995a595a, 0x99848284, 0x99848284, + 0x99848686, 0x99848686, 0x99848686, 0x99848686, 0x99868686, 0x99868686, 0x99868686, 0x997b797b, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x996b6d73, 0x996b6d73, 0x996b6d73, 0x996b6d73, 0x996b6d6b, 0x996b6d6b, 0x99707370, 0x996b6d6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996e706e, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99736d6b, 0x9973706e, 0x9973706e, 0x9973706e, + 0x99737073, 0x99736d73, 0x99737073, 0x99737073, 0x99736d73, 0x99736d73, 0x99736d73, 0x99737073, + 0x996b6d6b, 0x9970716e, 0x9970716e, 0x996b6d6b, 0x99736d6b, 0x99736d6b, 0x99736d6b, 0x99736d6b, + 0x9973706e, 0x9973706e, 0x99736d6b, 0x9973706e, 0x996e706e, 0x99707370, 0x99707370, 0x996b6d6b, + 0x996e7073, 0x996b6d73, 0x996b6d73, 0x996e7073, 0x996e706e, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x99707170, 0x996b6d6b, 0x99707170, 0x996b6d6b, 0x99707370, 0x99707370, 0x996b6d6b, 0x996b6d6b, + 0x9973706e, 0x9973706e, 0x9973706e, 0x9973706e, 0x996b696b, 0x996b696b, 0x996b696b, 0x994a4a4a, + 0x88313131, 0x66101010, 0x66000000, 0x55000000, 0x22000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x44474847, 0xeed6d7d6, 0xffd6d7d6, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffe9e7e9, 0xffe9e7e9, 0xffe9e7e9, 0xffdedbde, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d5db, 0xffceced6, 0xffceced6, 0xffceced6, 0xffcecece, 0xffcecece, 0xffd3d4d3, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffd6d1d0, 0xffd6d1d0, 0xffd6d1d0, 0xffd7d2d2, + 0xffd7d3d5, 0xffd6d1d5, 0xffd6d1d4, 0xffd6d3d5, 0xffd5d4d5, 0xffd1d2d1, 0xffd0d1d0, 0xffd0d2d0, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffd3d4d3, 0xffcecece, 0xffd3d4d3, 0xffcecece, 0xffd3d4d3, + 0xffd3d4d3, 0xffcecece, 0xffcecece, 0xffd0d1ce, 0xffd0d1ce, 0xffd0d1ce, 0xffd0d1ce, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xff949694, 0xcc949694, 0x33313231, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x44000000, 0x884a4542, 0x99737173, 0x99737173, 0x99737173, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99737373, + 0x99737173, 0x99737173, 0x99706f70, 0x99706f70, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x99706d70, 0x99737173, 0x99706d70, 0x99706d70, 0x996b6b6b, 0x996b6c6b, 0x996b6b6b, 0x996b6b6b, + 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, 0x996b6d6b, + 0x996b6d6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, 0x996e6c6e, 0x99706f70, 0x996e6c6e, 0x99706f70, + 0x996b6f6b, 0x996b6d6b, 0x996b6f6b, 0x996b6f6b, 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, + 0x996b7070, 0x996b6f6e, 0x996b6f6e, 0x996b6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, + 0x99736f6e, 0x99737070, 0x99737070, 0x99737070, 0x996e6f6e, 0x99737173, 0x99707070, 0x996e6f6e, + 0x9970706e, 0x9970706e, 0x9970706e, 0x9970706e, 0x996e6f6e, 0x996e6f6e, 0x99707070, 0x996e6f6e, + 0x996b6f70, 0x996b6f70, 0x996b6f70, 0x996b6f70, 0x996e6f6e, 0x99707070, 0x99707070, 0x996e6f6e, + 0x996e6f6e, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x99707070, 0x996e6f6e, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, 0x996b6d6b, 0x996b6c6b, + 0x996b6f70, 0x996b6f70, 0x996b6c6e, 0x996b6c6e, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x99686b6b, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x9963656b, 0x9963656b, 0x995d6065, 0x9952555a, + 0x994a4d4a, 0x881e1f1e, 0x66080808, 0x66080808, 0x44000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11101010, 0xccc5cac5, 0xffc5cac5, 0xffc5cac5, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedbd6, 0xffdedbd6, 0xffdedbd6, 0xffd6d5d3, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d0d3, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecdce, 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffcecdce, 0xffcecece, 0xffcecdce, 0xffcecdce, + 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced0d0, 0xffcecece, 0xffced0d0, + 0xffced0ce, 0xffcecece, 0xffced0ce, 0xffced0ce, 0xffd0ced0, 0xffd0ced0, 0xffd0ced0, 0xffd0ced0, + 0xffced1d3, 0xffced0d0, 0xffced0d0, 0xffced0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, + 0xffd6d0d0, 0xffd6d1d3, 0xffd6d1d3, 0xffd6d1d3, 0xffd0d0d0, 0xffd6d2d6, 0xffd3d1d3, 0xffd1d0d1, + 0xffd5d2d4, 0xffd7d3d6, 0xffd7d3d6, 0xffd6d3d5, 0xffd1d2d3, 0xffcecfce, 0xffcdcece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcbcccb, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcbcacb, 0xffc5cac5, + 0xffc0c4c0, 0xffc0c4c0, 0xffb5b6b5, 0xffa5a6a5, 0xffa5a6a5, 0xaa737473, 0x11101010, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x22000000, 0x661e1e1e, 0x99656263, 0x99737173, 0x99737173, 0x99737173, + 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99737373, 0x99737373, 0x99737373, 0x996b6c6b, + 0x996e6c6e, 0x996e6c6e, 0x99706f70, 0x99706f70, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, + 0x99706d70, 0x99706d70, 0x99706d70, 0x996e696e, 0x996b6b6b, 0x996b6b6b, 0x996b696b, 0x996b6b6b, + 0x996b696b, 0x996b6b6b, 0x996b696b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6d6b, + 0x996b6c6b, 0x996b6b6b, 0x996b6c6b, 0x996b6b6b, 0x996e6c6e, 0x996e6c6e, 0x99706f70, 0x996e6c6e, + 0x996b6f6b, 0x996b6f6b, 0x996b6f6b, 0x996b6f6b, 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, + 0x996b6f6e, 0x996b7070, 0x996b7070, 0x996b6f6e, 0x996e6f6e, 0x99707070, 0x99707070, 0x996e6f6e, + 0x99737070, 0x99737070, 0x99736f6e, 0x99736f6e, 0x996e6f6e, 0x99707070, 0x99737173, 0x996e6f6e, + 0x996e6f68, 0x996e6f68, 0x9970706e, 0x9970706e, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, + 0x996b6f70, 0x996b6f70, 0x996b6f70, 0x996b706e, 0x996e6f6e, 0x99707070, 0x996e6f6e, 0x996e6f6e, + 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, + 0x996b6d6b, 0x996b6c6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, + 0x996b6f70, 0x996b6c6e, 0x996b6c6e, 0x996b6c6e, 0x99686b6b, 0x99686b6b, 0x9965686b, 0x99686b6b, + 0x996b696b, 0x99686768, 0x99686768, 0x99686768, 0x9963656b, 0x995d6065, 0x995d6065, 0x9952555a, + 0x994a4d4a, 0x99343634, 0x77080808, 0x66080808, 0x66000000, 0x22000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x664d4e4d, 0xffc5cac5, 0xffc5cac5, 0xffc5cac5, + 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd6d5d3, 0xffd6d5d3, 0xffced0d0, 0xffced0d0, + 0xffd0cdd0, 0xffd0cdd0, 0xffd3d0d3, 0xffd3d0d3, 0xffcbcdcb, 0xffcbcdcb, 0xffcbcdcb, 0xffcbcdcb, + 0xffcecdce, 0xffced0ce, 0xffced0ce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecace, 0xffcecdce, + 0xffcecace, 0xffcecdce, 0xffcecace, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced0d0, 0xffcecece, + 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffd0ced0, 0xffd0ced0, 0xffd0ced0, 0xffd0ced0, + 0xffced0d0, 0xffced1d3, 0xffced1d3, 0xffced0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, 0xffd0d0d0, + 0xffd6d1d3, 0xffd6d1d3, 0xffd6d0d0, 0xffd6d0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, 0xffd0d0d0, + 0xffd5d2d3, 0xffd6d3d6, 0xffd7d2d5, 0xffd6d1d5, 0xffd6d1d5, 0xffd4cfd3, 0xffd0ced0, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffced2ce, 0xffcecace, 0xffcecece, 0xffcecece, 0xffcbcccb, + 0xffcbcccb, 0xffcbcccb, 0xffcbcccb, 0xffcbcacb, 0xffcbcacb, 0xffcbcacb, 0xffcbcacb, 0xffc5cac5, + 0xffc0c4c0, 0xffc0c4c0, 0xffb5b6b5, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, 0x66424242, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x44000000, 0x883c3b3c, 0x99656263, 0x99656263, 0x99656263, 0x99737173, + 0x99707070, 0x99707070, 0x99707070, 0x99707070, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, + 0x996b696b, 0x996b696b, 0x996e6c6e, 0x996e6c6e, 0x996b6b6b, 0x996b6b6b, 0x996b686b, 0x996b6b6b, + 0x996e696e, 0x996e696e, 0x996e696e, 0x996e696e, 0x996b696b, 0x996b696b, 0x996b6b6b, 0x996b696b, + 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, + 0x996b6b6b, 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, 0x99706f70, 0x99706f70, 0x99706f70, 0x99706f70, + 0x996b6d6b, 0x996b6f6b, 0x996b6f6b, 0x996b6f6b, 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, + 0x996b6f6e, 0x996b6f6e, 0x996b7070, 0x996b7070, 0x99707070, 0x99707070, 0x996e6f6e, 0x99707070, + 0x99736f6e, 0x99737070, 0x99736f6e, 0x99737070, 0x99707070, 0x996e6f6e, 0x99707070, 0x99707070, + 0x9970706e, 0x9970706e, 0x9970706e, 0x9970706e, 0x99707070, 0x996e6f6e, 0x99707070, 0x996e6f6e, + 0x996b706e, 0x996b706e, 0x996b6f70, 0x996b6f70, 0x996e6f6e, 0x99737173, 0x99707070, 0x99707070, + 0x99707070, 0x996e6f6e, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6c6b, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, + 0x996b6c6b, 0x996b6b6b, 0x996b6d6b, 0x996b6c6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, + 0x996b6c6e, 0x996b6c6e, 0x996b6c6e, 0x996b6c6e, 0x9965686b, 0x9965686b, 0x9965686b, 0x9965686b, + 0x99686768, 0x99686768, 0x99656465, 0x99656465, 0x9963656b, 0x995d6065, 0x99585a60, 0x9952555a, + 0x994a4d4a, 0x994a4d4a, 0x881e1f1e, 0x66080808, 0x66000000, 0x44000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0xddc5cac5, 0xffc5cac5, 0xffc5cac5, 0xffc5cac5, + 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffcecece, 0xffced0d0, 0xffced0d0, 0xffced0d0, 0xffc5cace, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcbcdcb, 0xffcbcdcb, 0xffc8ccc8, 0xffcbcdcb, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecdce, 0xffcecace, + 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced1d3, + 0xffcecece, 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffd0ced0, 0xffd0ced0, 0xffd0ced0, 0xffd0ced0, + 0xffced0d0, 0xffced0d0, 0xffced1d3, 0xffced1d3, 0xffd3d1d3, 0xffd6d2d6, 0xffd0d0d0, 0xffd3d1d3, + 0xffd6d0d0, 0xffd6d1d3, 0xffd6d0d0, 0xffd6d1d3, 0xffd3d1d3, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, + 0xffd4d2d2, 0xffd6d2d6, 0xffd6d1d5, 0xffd5d1d5, 0xffd5d2d4, 0xffd2d1d2, 0xffcfcfcf, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcbcccb, + 0xffc8c9c8, 0xffc8c9c8, 0xffc8c9c8, 0xffcbcacb, 0xffc8c6c8, 0xffc8c6c8, 0xffc8c6c8, 0xffc0c4c0, + 0xffc0c4c0, 0xffbabdba, 0xffb5b6b5, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, 0xbb737473, 0x110e0d0e, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x55000000, 0x995a595a, 0x99656263, 0x99656263, 0x99656263, 0x99656263, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b6c6b, 0x996b6c6b, 0x99636563, 0x99636563, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b686b, 0x996b686b, 0x996b686b, 0x996b686b, + 0x996b656b, 0x996e696e, 0x996e696e, 0x996e696e, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, + 0x996b696b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, + 0x996b6b6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, 0x99706f70, 0x99737173, 0x99706f70, 0x99737173, + 0x996b6f6b, 0x996b6f6b, 0x996b6f6b, 0x996b706b, 0x99706d70, 0x996e6d6e, 0x996e6d6e, 0x99706d70, + 0x996b7070, 0x996b7070, 0x996b6f6e, 0x996b6f6e, 0x99707070, 0x99707070, 0x99737173, 0x99707070, + 0x99737070, 0x99737070, 0x99737173, 0x99737173, 0x99707070, 0x99737173, 0x99707070, 0x99707070, + 0x9970706e, 0x9970706e, 0x9970706e, 0x9970706e, 0x99707070, 0x99707070, 0x99707070, 0x99707070, + 0x996b706e, 0x996b706e, 0x996b706e, 0x996b706e, 0x99707070, 0x99707070, 0x99737173, 0x99737173, + 0x99737173, 0x99707070, 0x99707070, 0x996e6f6e, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, 0x996b6d6b, + 0x996b6c6b, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, + 0x996b6c6e, 0x996b696b, 0x996b696b, 0x996b696b, 0x9965686b, 0x9965686b, 0x9963656b, 0x9963656b, + 0x99656465, 0x99656465, 0x99656465, 0x99636163, 0x995d6065, 0x995d6065, 0x99585a60, 0x9952555a, + 0x994a4d4a, 0x994a4d4a, 0x99343634, 0x66080808, 0x66000000, 0x55000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x44313131, 0xffc5cac5, 0xffc5cac5, 0xffc5cac5, 0xffc5cac5, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffc5cace, 0xffc5cace, 0xffc5cace, 0xffc5cace, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffc5cac5, 0xffc5cac5, 0xffc5cac5, 0xffc5cac5, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, + 0xffcecace, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced1d3, 0xffced0d0, 0xffced1d3, + 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced2ce, 0xffd3ced3, 0xffd0ced0, 0xffd0ced0, 0xffd3ced3, + 0xffced1d3, 0xffced1d3, 0xffced0d0, 0xffced0d0, 0xffd3d1d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, + 0xffd6d1d3, 0xffd6d1d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, 0xffd6d2d6, 0xffd3d1d3, 0xffd6d2d6, + 0xffd6d2d6, 0xffd7d2d6, 0xffd5d3d5, 0xffd5d1d5, 0xffd3d1d2, 0xffd0d0d0, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecace, 0xffcecace, 0xffcecace, 0xffc8c9c8, + 0xffc8c9c8, 0xffc8c9c8, 0xffc8c9c8, 0xffc8c6c8, 0xffc8c6c8, 0xffc8c6c8, 0xffc5c2c5, 0xffc0c4c0, + 0xffbabdba, 0xffbabdba, 0xffb5b6b5, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, 0xeea5a6a5, 0x44292829, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x22000400, 0x771e201e, 0x995a595a, 0x99525452, 0x995a5a5a, 0x99636163, 0x99636163, + 0x996b696b, 0x99656568, 0x99656568, 0x99656568, 0x99636563, 0x99636563, 0x99636563, 0x99636563, + 0x99686568, 0x99656565, 0x99656565, 0x99656565, 0x996b6765, 0x996b6765, 0x996b6868, 0x996b6765, + 0x996b676b, 0x996b686b, 0x996b676b, 0x996b686b, 0x996b696b, 0x996b696b, 0x996b6b6b, 0x996b696b, + 0x996b696b, 0x996b696b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, + 0x996e6f6e, 0x996b6d6b, 0x996b6d6b, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, + 0x99737173, 0x99737173, 0x99737173, 0x996e746e, 0x99737173, 0x99737373, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99707173, 0x996e7173, 0x99707173, 0x99707173, + 0x99707070, 0x99707070, 0x996e6f6e, 0x99707070, 0x99736f6e, 0x99737070, 0x99736f6e, 0x99737070, + 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996b6d6b, 0x996b6d6b, + 0x996b6f6e, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x99686868, 0x99656765, 0x99656765, 0x99636563, + 0x99636463, 0x99636463, 0x99636263, 0x99636163, 0x99636163, 0x995d5c5d, 0x995d5c5d, 0x995a595a, + 0x99525552, 0x993f423f, 0x993f423f, 0x77191c19, 0x77000000, 0x66000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x88737173, 0xffbdbabd, 0xffbdbabd, 0xffc5c2c5, 0xffc5c2c5, + 0xffc5cac5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c9c5, 0xffc5c8c5, 0xffc5c9c5, 0xffc5c8c5, 0xffc5c9c5, 0xffc5c9c5, 0xffc5cac5, 0xffc5c9c5, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecdce, 0xffcecace, + 0xffcecace, 0xffcecace, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffd0d0d0, 0xffcecece, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d5d0, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d4d6, + 0xffd6d4d6, 0xffd6d3d6, 0xffd7d1d5, 0xffd5d1d4, 0xffd2d0d2, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, + 0xffd0d0d0, 0xffcecece, 0xffcecece, 0xffced0d0, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecdce, 0xffcecace, 0xffcecace, 0xffc5cac5, + 0xffc5c8c5, 0xffc5c8c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c2bd, + 0xffc0bdbd, 0xffc0bdbd, 0xffbdbabd, 0xffb5b6b5, 0xffadadad, 0xffa5a3a5, 0xff9c9a9c, 0x77585a58, + 0x00000400, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x33000400, 0x883c3d3c, 0x995a595a, 0x99525452, 0x99525452, 0x995a5a5a, 0x99636163, + 0x99656568, 0x99656568, 0x99656568, 0x99656568, 0x99636563, 0x99636463, 0x99636463, 0x99636463, + 0x99656565, 0x99656565, 0x99656565, 0x99656565, 0x996b6765, 0x996b6765, 0x996b6765, 0x996b6765, + 0x996b676b, 0x996b686b, 0x996b686b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b6b6b, + 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, 0x996b6d6b, 0x996b6b6b, 0x996b6d6b, 0x996b6c6b, + 0x996e6f6e, 0x996b6d6b, 0x99707070, 0x99737173, 0x996e6f6e, 0x996e6f6e, 0x99707070, 0x99707070, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737373, 0x99737473, 0x99737373, 0x99737373, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737373, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737373, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99707173, 0x99737173, 0x99737173, 0x99707173, + 0x99707070, 0x99707070, 0x99707070, 0x99707070, 0x99737070, 0x99737070, 0x99737070, 0x99737070, + 0x996e6f6e, 0x99707070, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996b6d6b, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6c6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x99686868, 0x99656765, 0x99656765, 0x99656765, + 0x99636263, 0x99636263, 0x99636263, 0x99636163, 0x99605e60, 0x99605e60, 0x995d5c5d, 0x995a595a, + 0x99525552, 0x993f423f, 0x993f423f, 0x88191c19, 0x77030303, 0x66000000, 0x22000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xddadaaad, 0xffb5b2b5, 0xffbdbabd, 0xffbdbabd, 0xffc5c2c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c8c5, 0xffc5c8c5, 0xffc5c9c5, 0xffc5c8c5, 0xffc5c9c5, 0xffc5c9c5, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcbccc8, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecdce, + 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffd0d0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, 0xffd0d0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d4d6, + 0xffd6d2d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d4d6, + 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d2d6, + 0xffd6d5d6, 0xffd6d4d6, 0xffd6d1d3, 0xffd1d1d1, 0xffd3d1d3, 0xffd3d1d3, 0xffd0d0d0, 0xffd0d0d0, + 0xffd0d0d0, 0xffd0d0d0, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced0d0, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecace, 0xffcecace, 0xffcecace, 0xffc5cac5, + 0xffc5c8c5, 0xffc5c8c5, 0xffc5c8c5, 0xffc5c5c5, 0xffc5c5c5, 0xffc5c5c5, 0xffc5c4c5, 0xffc5c2bd, + 0xffc3c0bd, 0xffc0bdbd, 0xffbdbabd, 0xffb5b6b5, 0xffadadad, 0xffa5a3a5, 0xffa5a3a5, 0xaa585a58, + 0x11000400, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x44000400, 0x993c3d3c, 0x995a595a, 0x994a4d4a, 0x99525452, 0x995a5a5a, 0x99636163, + 0x99606165, 0x99606165, 0x99656568, 0x99656568, 0x99636563, 0x99636263, 0x99636263, 0x99636263, + 0x99686568, 0x99656565, 0x99656565, 0x99656565, 0x996b6765, 0x996b6563, 0x996b6765, 0x996b6868, + 0x996b686b, 0x996b686b, 0x996b686b, 0x996b696b, 0x996b696b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, + 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996e6f6e, 0x996e6f6e, 0x99707070, 0x99737173, 0x99707070, 0x99707070, 0x99707070, 0x99707070, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737573, 0x99737373, 0x99737573, + 0x99737373, 0x99737473, 0x99737373, 0x99737373, 0x99737373, 0x99737473, 0x99737173, 0x99737473, + 0x99737173, 0x99737473, 0x99737373, 0x99737373, 0x99737473, 0x99737373, 0x99737173, 0x99737173, + 0x99737373, 0x99737373, 0x99737473, 0x99737473, 0x99737173, 0x99737373, 0x99737373, 0x99737373, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99707173, 0x99707173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99707070, 0x99707070, 0x99707070, 0x996e6f6e, 0x99707070, 0x99707070, 0x996e6f6e, 0x996e6f6e, + 0x996b7070, 0x996b6f6e, 0x996b6f6e, 0x996b6d6b, 0x996b6d6b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x99656765, 0x99686868, 0x99656765, 0x99656765, + 0x99636463, 0x99636263, 0x99636263, 0x99636163, 0x99605e60, 0x995d5c5d, 0x995d5c5d, 0x995a595a, + 0x99525552, 0x99525552, 0x993f423f, 0x882c2f2c, 0x77050505, 0x66000000, 0x33000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0xffadaaad, 0xffb5b2b5, 0xffb5b2b5, 0xffbdbabd, 0xffc5c2c5, + 0xffc5c2c5, 0xffc5c2c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c5c5, 0xffc5c5c5, 0xffc5c5c5, + 0xffc5c8c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c8c5, 0xffc5c8c5, 0xffc5c6c5, 0xffc5c9c5, 0xffc5cac5, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcbccc8, 0xffcecace, 0xffcecdce, 0xffcecdce, 0xffcecece, + 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffd0d0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd6d2d6, 0xffd3d1d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, + 0xffd6d4d3, 0xffd6d2d6, 0xffd6d4d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d7d6, 0xffd6d4d6, 0xffd6d7d6, + 0xffd6d4d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d4d6, 0xffd6d7d6, + 0xffd6d4d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d4d6, + 0xffd6d5d6, 0xffd6d5d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, 0xffd3d1d3, 0xffd0d0d0, 0xffd3d1d3, + 0xffd3d1d3, 0xffd0d0d0, 0xffd0d0d0, 0xffced1d3, 0xffced0d0, 0xffced0d0, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecace, 0xffcecace, 0xffcecace, 0xffc5c9c5, + 0xffc5cac5, 0xffc5c8c5, 0xffc5c8c5, 0xffc5c6c5, 0xffc5c5c5, 0xffc5c4c5, 0xffc5c2c5, 0xffc5c2bd, + 0xffc0bdbd, 0xffc0bdbd, 0xffbdbabd, 0xffb5b6b5, 0xffadadad, 0xffa5a3a5, 0xffa5a3a5, 0xcc848684, + 0x22000400, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x55000400, 0x993c3d3c, 0x993c3d3c, 0x994a4d4a, 0x99525452, 0x995a5a5a, 0x995a5a5a, + 0x995a5d63, 0x99606165, 0x99606165, 0x99606165, 0x99636163, 0x99636263, 0x99636463, 0x99636263, + 0x99686568, 0x99656565, 0x99656565, 0x99656565, 0x996b6563, 0x996b6868, 0x996b6765, 0x996b6868, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b6b6b, 0x996b6c6b, 0x996b6c6b, + 0x996b6c6b, 0x996b6b6b, 0x996b6c6b, 0x996b6d6b, 0x996b6c6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x996e6f6e, 0x99707070, 0x99737173, 0x99707070, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99707370, 0x99707370, 0x99737173, 0x99707370, 0x99737373, 0x99737473, 0x99737173, 0x99737473, + 0x99737573, 0x99737573, 0x99737373, 0x99737373, 0x99737373, 0x99737473, 0x99737373, 0x99737473, + 0x99737573, 0x99737473, 0x99737473, 0x99737473, 0x99737473, 0x99737473, 0x99737473, 0x99737373, + 0x99737573, 0x99737373, 0x99737473, 0x99737473, 0x99737373, 0x99737573, 0x99737473, 0x99737473, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99707070, 0x99707070, 0x99737173, 0x99737173, 0x99737173, 0x99707070, + 0x996b7070, 0x996b6f6e, 0x996b6f6e, 0x996b6f6e, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6b6b, + 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, 0x99656765, 0x99686868, 0x99656765, + 0x99636463, 0x99636463, 0x99636263, 0x99636163, 0x99605e60, 0x99605e60, 0x995d5c5d, 0x995d5c5d, + 0x99525552, 0x99525552, 0x993f423f, 0x992c2f2c, 0x77080808, 0x77000000, 0x44000000, 0x00000000, + 0x00000000, 0x00000000, 0x443a393a, 0xffadaaad, 0xffadaaad, 0xffb5b2b5, 0xffbdbabd, 0xffbdbabd, + 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c6c5, 0xffc5c4c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c8c5, 0xffc5c6c5, 0xffc5cac5, 0xffc5c9c5, 0xffc5cac5, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecdce, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffd0d0d0, 0xffd3d1d3, 0xffd6d2d6, 0xffd3d1d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d4d3, 0xffd6d4d3, 0xffd6d2d6, 0xffd6d4d3, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d4d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d4d5, + 0xffd6d7d6, 0xffd6d5d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, 0xffced1d3, 0xffced0d0, 0xffced0d0, 0xffced0d0, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffceccce, 0xffc5cac5, + 0xffc5c9c5, 0xffc5cac5, 0xffc5c9c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c2bd, + 0xffc3c0bd, 0xffc0bdbd, 0xffc0bdbd, 0xffb5b6b5, 0xffadadad, 0xffa5a3a5, 0xffa5a3a5, 0xdd848684, + 0x222c2f2c, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x55161716, 0x99424542, 0x99424542, 0x994a4c4a, 0x99525252, 0x995a595a, 0x995a595a, + 0x995d5e5d, 0x995d5e5d, 0x99606060, 0x99606060, 0x99636263, 0x99636263, 0x99636263, 0x99636463, + 0x99636563, 0x99636563, 0x99656765, 0x99636563, 0x996b686b, 0x996b676b, 0x996b686b, 0x996b696b, + 0x996b696b, 0x996b6b6b, 0x996b696b, 0x996b696b, 0x996e6c6e, 0x996e6c6e, 0x996e6c6e, 0x99706f70, + 0x996b6d6b, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x99707070, 0x996e6f6e, 0x99707070, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737373, 0x99737373, 0x99737173, + 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99767776, 0x99767776, 0x99767776, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737473, 0x99737473, 0x99737473, 0x99737373, 0x99737573, 0x99737473, 0x99737473, 0x99737373, + 0x99737373, 0x99737373, 0x99737473, 0x99737373, 0x99737373, 0x99737173, 0x99737173, 0x99737373, + 0x99737373, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99707070, 0x996e6f6e, 0x99707070, 0x996e6f6e, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996b6d6b, + 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b696b, 0x996b6868, 0x996b6765, 0x996b6765, + 0x99656465, 0x99656465, 0x99656465, 0x99636163, 0x99636163, 0x99605e60, 0x995d5c5d, 0x995a595a, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x770b0b0b, 0x77000000, 0x55000000, 0x00000000, + 0x00000000, 0x00000000, 0x44373737, 0xffa5a6a5, 0xffadaaad, 0xffb2b5b8, 0xffb5babd, 0xffb5babd, + 0xffbdc0c0, 0xffbdc0c0, 0xffbdc0c0, 0xffbdc2c5, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c8c5, 0xffc5c6c5, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecccb, + 0xffcecace, 0xffcecdce, 0xffcecace, 0xffcecace, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced0d0, + 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd0d0d0, 0xffd3d1d3, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d4d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d9, 0xffd7d7d7, 0xffd8d7d8, 0xffd6d6d6, 0xffd7d6d6, + 0xffd5d8d9, 0xffd6d8d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, + 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d1d6, 0xffd6d1d6, 0xffd6d1d6, 0xffd6d1d6, 0xffd3d1d3, + 0xffd0d0d0, 0xffd0d0d0, 0xffcecece, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffceccce, 0xffcecccb, + 0xffcec9c8, 0xffcec9c8, 0xffcec9c8, 0xffcbc8cb, 0xffcbc8cb, 0xffc8c5c8, 0xffc8c5c8, 0xffc5c2c5, + 0xffc3c0c3, 0xffc0bdc0, 0xffbdbabd, 0xffb5bab5, 0xffafb2af, 0xffaaaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x44343534, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x55161716, 0x99424542, 0x99424542, 0x99424542, 0x994a4c4a, 0x99525252, 0x995a595a, + 0x995a5d5a, 0x995d5e5d, 0x99636163, 0x99606060, 0x99636263, 0x99636263, 0x99636263, 0x99636463, + 0x99636563, 0x99636563, 0x99636563, 0x99656765, 0x996b676b, 0x996b686b, 0x996b686b, 0x996b696b, + 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996e6c6e, 0x996e6c6e, 0x99706f70, 0x99706f70, + 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x99707070, 0x99707070, 0x99707070, 0x99707070, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737373, + 0x99737373, 0x99737373, 0x99737573, 0x99737473, 0x99737473, 0x99737573, 0x99737473, 0x99737473, + 0x99737573, 0x99737573, 0x99767776, 0x99737573, 0x99737573, 0x99767776, 0x99767776, 0x99767776, + 0x99767776, 0x997b797b, 0x99797879, 0x99767776, 0x99737776, 0x99737776, 0x99737776, 0x99737776, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737473, 0x99737473, 0x99737573, 0x99737573, 0x99737473, 0x99737473, 0x99737473, + 0x99737573, 0x99737573, 0x99737473, 0x99737573, 0x99737473, 0x99737473, 0x99737373, 0x99737473, + 0x99737373, 0x99737473, 0x99737473, 0x99737173, 0x99737373, 0x99737373, 0x99737173, 0x99737173, + 0x99737173, 0x99707070, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996b6d6b, + 0x996b6c6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b6765, + 0x99686768, 0x99656465, 0x99656465, 0x99656465, 0x99636163, 0x99605e60, 0x995d5c5d, 0x995a595a, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x77101010, 0x77000000, 0x55000000, 0x11000000, + 0x00000000, 0x00000000, 0x55373737, 0xffa5a6a5, 0xffadaaad, 0xffafafb2, 0xffb2b5b8, 0xffb5babd, + 0xffbdbebd, 0xffbdc0c0, 0xffbdc2c5, 0xffbdc1c3, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c5c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c9c5, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecccb, + 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffced0d0, 0xffced0d0, + 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, 0xffd6d2d6, 0xffd3d1d3, 0xffd6d2d6, + 0xffd6d4d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d5d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd9d8d9, 0xffd6d7d6, 0xffd6d7d6, 0xffd9d8d6, 0xffdbd9d6, 0xffd9d8d6, + 0xffd6d7d6, 0xffd6dbde, 0xffd6d9db, 0xffd7d9dc, 0xffd9d9d9, 0xffdbd8dc, 0xffdcd8dd, 0xffd9d7da, + 0xffd5d7da, 0xffd5d7d6, 0xffd5d5d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d4d6, 0xffd6d5d6, + 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d1d6, 0xffd0d0d0, + 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffcecece, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecccb, + 0xffcecccb, 0xffcecccb, 0xffcec9c8, 0xffcbc8cb, 0xffc8c5c8, 0xffc8c5c8, 0xffc8c5c8, 0xffc5c2c5, + 0xffc3c0c3, 0xffc0bdc0, 0xffbdbabd, 0xffb5bab5, 0xffafb2af, 0xffaaaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x55343534, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x66161716, 0x99424542, 0x99424542, 0x99424542, 0x994a4c4a, 0x99525252, 0x995a595a, + 0x995a5d5a, 0x995d5e5d, 0x995d5e5d, 0x99636163, 0x99636163, 0x99636263, 0x99636463, 0x99636463, + 0x99636563, 0x99656765, 0x99656765, 0x99656765, 0x996b686b, 0x996b676b, 0x996b686b, 0x996b696b, + 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996e6c6e, 0x99706f70, 0x99737173, 0x99706f70, + 0x996e6f6e, 0x99707070, 0x99707070, 0x99707070, 0x99707070, 0x99707070, 0x99737173, 0x99737173, + 0x99737473, 0x99737573, 0x99737373, 0x99737473, 0x99737373, 0x99737373, 0x99737473, 0x99737573, + 0x99737473, 0x99737473, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99767776, 0x997b797b, 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x997b797b, + 0x99797879, 0x99767776, 0x99767776, 0x99767776, 0x99737776, 0x99737776, 0x99737776, 0x99737776, + 0x99737773, 0x99737573, 0x99737773, 0x99737773, 0x99767773, 0x99767773, 0x99767773, 0x99767773, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737373, 0x99737573, 0x99737373, 0x99737573, 0x99737373, 0x99737473, 0x99737373, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99707070, 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, + 0x996b6d6b, 0x996b6d6b, 0x996b6b6b, 0x996b6b6b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b6868, + 0x99686768, 0x99686768, 0x99656465, 0x99656465, 0x99636163, 0x99605e60, 0x995d5c5d, 0x995d5c5d, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x77101010, 0x77000000, 0x55000000, 0x11000000, + 0x00000000, 0x00000000, 0x66373737, 0xffa5a6a5, 0xffadaaad, 0xffafafb2, 0xffb5babd, 0xffb5babd, + 0xffbdbebd, 0xffbdc0c0, 0xffbdc0c0, 0xffbdc2c5, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c8c5, 0xffc5c9c5, 0xffc5c9c5, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecccb, + 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffced1d3, 0xffced0d0, + 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, 0xffd6d2d6, 0xffd3d1d3, 0xffd3d1d3, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d5d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d9d6, + 0xffd9d8d9, 0xffdbd9db, 0xffd9d8d9, 0xffdbd9db, 0xffdbd9d6, 0xffdbd9d6, 0xffdbd9d6, 0xffdedbd6, + 0xffd6d9db, 0xffd6d8d9, 0xffd6d9db, 0xffd7d8dc, 0xffd9dadb, 0xffdbdadc, 0xffdcd8dc, 0xffdcd8dc, + 0xffdcd7dc, 0xffdad7da, 0xffd8d8d7, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d5d6, + 0xffd6d5d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd3d1d3, + 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecdce, 0xffcecccb, + 0xffcecccb, 0xffcecccb, 0xffcec9c8, 0xffcecace, 0xffcbc8cb, 0xffcbc8cb, 0xffc8c5c8, 0xffc5c2c5, + 0xffc5c2c5, 0xffc0bdc0, 0xffc0bdc0, 0xffb5bab5, 0xffafb2af, 0xffaaaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x55343534, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x66161716, 0x99424542, 0x99424542, 0x99424542, 0x994a4c4a, 0x99525252, 0x995a595a, + 0x995a5d5a, 0x995d5e5d, 0x995d5e5d, 0x99606060, 0x99636163, 0x99636263, 0x99636263, 0x99636463, + 0x99636563, 0x99656765, 0x99686868, 0x99686868, 0x996b686b, 0x996b686b, 0x996b696b, 0x996b696b, + 0x996b6b6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, 0x99706f70, 0x99706f70, 0x99706f70, 0x99706f70, + 0x99707070, 0x99707070, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737473, 0x99737573, 0x99737473, 0x99737373, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99797879, 0x997b797b, 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99797879, 0x99767776, + 0x99767776, 0x99767776, 0x99767776, 0x997b797b, 0x99737776, 0x99737879, 0x99737776, 0x99737776, + 0x99737973, 0x99737773, 0x99737973, 0x99737973, 0x997b7973, 0x99767773, 0x99767773, 0x997b7973, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737573, 0x99737473, 0x99737573, 0x99737473, 0x99737573, 0x99737573, 0x99737373, 0x99737373, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99707070, 0x99707070, 0x996e6f6e, + 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6c6b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, + 0x99686768, 0x99686768, 0x99656465, 0x99656465, 0x99636163, 0x99636163, 0x995d5c5d, 0x995d5c5d, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x77101010, 0x77000000, 0x66000000, 0x11000000, + 0x00000000, 0x00000000, 0x776e6f6e, 0xffa5a6a5, 0xffadaaad, 0xffafafb2, 0xffb2b5b8, 0xffb5babd, + 0xffbdbebd, 0xffbdc0c0, 0xffbdc0c0, 0xffbdc1c3, 0xffc5c4c5, 0xffc5c4c5, 0xffc5c5c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c8c5, 0xffc5cac5, 0xffc5cac5, 0xffcecace, 0xffcecace, 0xffcecccb, 0xffcecccb, + 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced0d0, 0xffced0d0, 0xffced1d3, 0xffced1d3, + 0xffd3d1d3, 0xffd3d1d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d5d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d8d6, + 0xffdbd9db, 0xffdedbde, 0xffdbd9db, 0xffdbd9db, 0xffdbd9d6, 0xffdbd9d6, 0xffdedbd6, 0xffdbd9d6, + 0xffd6d9db, 0xffd6d9db, 0xffd6dadb, 0xffd7dade, 0xffdadbdb, 0xffdbdadc, 0xffdbd8dc, 0xffdcd8dc, + 0xffdcdadc, 0xffd9dad9, 0xffd7d8d7, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d2d6, + 0xffd3d1d3, 0xffd3d1d3, 0xffd0d0d0, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecccb, + 0xffcecccb, 0xffcecccb, 0xffcecccb, 0xffcecace, 0xffcbc8cb, 0xffcbc8cb, 0xffc8c5c8, 0xffc5c2c5, + 0xffc5c2c5, 0xffc0bdc0, 0xffc0bdc0, 0xffb5bab5, 0xffafb2af, 0xffaaaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x66343534, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x66161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x995a595a, 0x995a595a, + 0x995d5c5d, 0x99605e60, 0x99605e60, 0x99605e60, 0x99636163, 0x99636263, 0x99636463, 0x99636563, + 0x996b656b, 0x996b676b, 0x996b686b, 0x996b686b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b6b6b, + 0x996e6c6b, 0x996e6c6b, 0x99706f6b, 0x996e6c6b, 0x996e7070, 0x996e7070, 0x99686f6e, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737373, 0x99737473, 0x99737473, 0x99737473, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99767876, 0x99767876, 0x99767876, 0x99767876, + 0x997b7979, 0x997b7d7b, 0x997b7576, 0x997b7979, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99767876, 0x99797b79, 0x99767876, 0x99767876, + 0x997b787b, 0x997b787b, 0x997b787b, 0x997b787b, 0x99767876, 0x99767876, 0x99767876, 0x99767876, + 0x99767876, 0x99767876, 0x99767876, 0x99767876, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x99767776, 0x99767776, 0x99767776, 0x99737573, 0x99737776, 0x99737573, 0x99737573, 0x99737573, + 0x99737473, 0x99737373, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x996e6f6e, 0x996e6f6e, 0x996e6f6e, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, 0x996b696b, + 0x99656865, 0x99656865, 0x99636563, 0x99636563, 0x99606160, 0x99606160, 0x995d5d5d, 0x995d5d5d, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x77101410, 0x77000000, 0x66000000, 0x11000000, + 0x00000000, 0x00000000, 0x77686968, 0xff9c9e9c, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffb5b7b5, + 0xffbdbebd, 0xffc0c0c0, 0xffc3c1c3, 0xffc3c1c3, 0xffc5c2c5, 0xffc8c5c5, 0xffc8c5c5, 0xffcbc8c5, + 0xffc5c6c5, 0xffc8c9c8, 0xffc8c9c8, 0xffc8c9c8, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecdce, + 0xffcecece, 0xffcecece, 0xffd0d0d0, 0xffcecece, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd3d4d3, + 0xffd6d4d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d8d6, + 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd6dbd6, 0xffd6dbd6, 0xffd9dcd9, 0xffd6dbd6, + 0xffdedbde, 0xffdeddde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedcde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedade, 0xffdcdcdd, 0xffdbdbdc, 0xffdbdbdc, 0xffdbdbdc, 0xffdcdadc, + 0xffdcdadd, 0xffdcdadc, 0xffd9d9d9, 0xffd8d9db, 0xffd9d8d9, 0xffdbd9db, 0xffd9d8d9, 0xffd6d9d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d4d6, + 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d0d0, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecdd0, 0xffceccd3, 0xffcbcccb, 0xffc8c9c8, 0xffc8c9c8, 0xffc5c6c5, 0xffc5c6c5, + 0xffc3c2c3, 0xffc0bec0, 0xffc0bec0, 0xffbdbab5, 0xffb5b2af, 0xffadaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x66343734, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x66161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x99555255, 0x995a595a, + 0x995d5c5d, 0x99605e60, 0x99605e60, 0x99636163, 0x99636263, 0x99636263, 0x99636563, 0x99636563, + 0x996b676b, 0x996b686b, 0x996b676b, 0x996b696b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, 0x996b6b6b, + 0x99706f6b, 0x996e6c6b, 0x99706f6b, 0x99706f6b, 0x996e7070, 0x996e7070, 0x996e7070, 0x996e7070, + 0x99737173, 0x99737373, 0x99737173, 0x99737473, 0x99737373, 0x99737373, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99767876, 0x99767876, 0x99767876, 0x99797b79, + 0x997b7979, 0x997b7979, 0x997b7979, 0x997b7979, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b7b7b, + 0x997b797b, 0x997b797b, 0x997b7b7b, 0x997b7c7b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99797b79, 0x99797b79, 0x99797b79, 0x99797b79, + 0x997b787b, 0x997b787b, 0x997b787b, 0x997b787b, 0x99797b79, 0x99767876, 0x99767876, 0x99797b79, + 0x99797b79, 0x99767876, 0x99767876, 0x99767876, 0x997b797b, 0x99797879, 0x997b797b, 0x99797879, + 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99737776, 0x99737776, 0x99737776, 0x99737573, + 0x99737573, 0x99737573, 0x99737473, 0x99737373, 0x99737173, 0x99737373, 0x99737173, 0x99737173, + 0x99707070, 0x99737173, 0x99707070, 0x996e6f6e, 0x996b6c6b, 0x996b6d6b, 0x996b6c6b, 0x996b6b6b, + 0x99686b68, 0x99656865, 0x99656865, 0x99636563, 0x99636563, 0x99606160, 0x99606160, 0x995a595a, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x77101410, 0x77000000, 0x66000000, 0x11000000, + 0x00000000, 0x00000000, 0x88686968, 0xff9c9e9c, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffb5b7b5, + 0xffbdbebd, 0xffc0c0c0, 0xffc0c0c0, 0xffc5c2c5, 0xffc8c5c5, 0xffc8c5c5, 0xffcbc8c5, 0xffcbc8c5, + 0xffc8c9c8, 0xffc8c9c8, 0xffc8c9c8, 0xffcbcccb, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, + 0xffd0d0d0, 0xffcecece, 0xffd0d0d0, 0xffd0d0d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, + 0xffd6d2d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, + 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd6dbd6, 0xffd9dcd9, 0xffd9dcd9, 0xffd9dcd9, + 0xffdedbde, 0xffdedcde, 0xffdedcde, 0xffdedcde, 0xffdedcde, 0xffdedcde, 0xffdedbde, 0xffdeddde, + 0xffdedcde, 0xffdedcde, 0xffdddddd, 0xffdbdddd, 0xffdbdddc, 0xffdbdddc, 0xffdddbdd, 0xffdedbde, + 0xffdfdbdf, 0xffe0dbdf, 0xffdcdadc, 0xffd7dadc, 0xffd8d9d9, 0xffdad9da, 0xffdbd9db, 0xffd6d9d6, + 0xffd6d9d6, 0xffd6d8d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d4d6, + 0xffd6d5d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, 0xffd0d0d0, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecdd0, 0xffcbcccb, 0xffcbcccb, 0xffc8c9c8, 0xffc5c6c5, 0xffc5c6c5, + 0xffc3c2c3, 0xffc3c2c3, 0xffbdbabd, 0xffbdbab5, 0xffb5b2af, 0xffadaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x66343734, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x77161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x99555255, 0x995a595a, + 0x995d5c5d, 0x99605e60, 0x99636163, 0x99636163, 0x99636463, 0x99636563, 0x99636563, 0x99636563, + 0x996b676b, 0x996b676b, 0x996b696b, 0x996b696b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, 0x996b6d6b, + 0x99706f6b, 0x99706f6b, 0x99706f6b, 0x99706f6b, 0x996e7070, 0x996e7070, 0x99737173, 0x99737173, + 0x99737373, 0x99737373, 0x99737373, 0x99737373, 0x99737473, 0x99737473, 0x99737573, 0x99737573, + 0x99737573, 0x99737573, 0x99737773, 0x99737773, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99767876, 0x99797b79, 0x99797b79, 0x99797b79, + 0x997b7979, 0x997b7979, 0x997b7979, 0x997b7979, 0x997b797b, 0x997b7c7b, 0x997b7c7b, 0x997b7b7b, + 0x997b7b7b, 0x997b7b7b, 0x997b7b7b, 0x997b7c7b, 0x997b7b7b, 0x997b7d7b, 0x997b7c7b, 0x997b7c7b, + 0x997e7c7b, 0x997e7c7b, 0x99817f7b, 0x997e7c7b, 0x99797b79, 0x99797b79, 0x997b7d7b, 0x997b7d7b, + 0x997b7b7b, 0x997b7b7b, 0x997b7b7b, 0x997b7b7b, 0x99797b79, 0x99797b79, 0x99797b79, 0x99797b79, + 0x99797b79, 0x99767876, 0x99797b79, 0x99797b79, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x99767776, 0x99737776, 0x99737776, 0x99737776, 0x99737776, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737373, 0x99737473, 0x99737173, 0x99737173, + 0x99737173, 0x99737173, 0x99707070, 0x99707070, 0x996b6d6b, 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, + 0x99686b68, 0x99656865, 0x99656865, 0x99656865, 0x99636563, 0x99606160, 0x995d5d5d, 0x995d5d5d, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x77101410, 0x77000000, 0x66000000, 0x11000000, + 0x00000000, 0x00000000, 0x99686968, 0xff9c9e9c, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffbdbebd, + 0xffbdbebd, 0xffc0c0c0, 0xffc5c2c5, 0xffc5c2c5, 0xffc8c5c5, 0xffcbc8c5, 0xffcbc8c5, 0xffcbc8c5, + 0xffc8c9c8, 0xffc8c9c8, 0xffcbcccb, 0xffcbcccb, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, + 0xffd0d0d0, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d1d3, 0xffd0d1d0, 0xffd0d1d0, 0xffd3d4d3, 0xffd3d4d3, + 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, + 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, 0xffd9dcd9, 0xffd9dcd9, 0xffd9dcd9, 0xffdbdddb, + 0xffdedcde, 0xffdeddde, 0xffdedcde, 0xffdedcde, 0xffdedcde, 0xffdedfde, 0xffdedfde, 0xffdeddde, + 0xffdeddde, 0xffdeddde, 0xffe1dee1, 0xffdfdedf, 0xffdddfdd, 0xffdddddc, 0xffdddcdd, 0xffdddfe0, + 0xffdfdedf, 0xffdfdcdf, 0xffdfdcdf, 0xffdfdbdf, 0xffdfdbde, 0xffdfdbdf, 0xffdcd9dc, 0xffd6d9d6, + 0xffd6d9d6, 0xffd6d9d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d5d6, + 0xffd6d7d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd3d1d3, 0xffd3d1d3, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecdd0, 0xffcbcccb, 0xffc8c9c8, 0xffc8c9c8, 0xffc8c9c8, 0xffc5c6c5, + 0xffc3c2c3, 0xffc3c2c3, 0xffc0bec0, 0xffbdbab5, 0xffb5b2af, 0xffadaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x66343734, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x77161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x995a595a, 0x995a595a, + 0x99605e60, 0x99605e60, 0x99636163, 0x99636163, 0x99636563, 0x99636563, 0x99636563, 0x99636563, + 0x996b676b, 0x996b686b, 0x996b696b, 0x996b696b, 0x996b6c6b, 0x996b6b6b, 0x996b6c6b, 0x996b6d6b, + 0x99706f6b, 0x99706f6b, 0x99706f6b, 0x9973716b, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99737173, 0x99737473, 0x99737473, 0x99737473, 0x99737473, 0x99737573, 0x99737573, 0x99737573, + 0x99737773, 0x99737773, 0x99737773, 0x99737973, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99797b79, 0x99797b79, 0x99797b79, 0x997b7d7b, + 0x997b7979, 0x997b7d7b, 0x997b7979, 0x997b7d7b, 0x997b7c7b, 0x997b7c7b, 0x997b7c7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997e7c7b, 0x99817f7b, 0x99817f7b, 0x997e7c7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99797b79, + 0x997b7d7b, 0x997b7b7b, 0x997b7d7b, 0x997b7b7b, 0x99797b79, 0x99797b79, 0x99797b79, 0x99797b79, + 0x997b7d7b, 0x99797b79, 0x997b7d7b, 0x99797b79, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x9973797b, 0x99737776, 0x99737776, 0x99737776, + 0x99737573, 0x99737573, 0x99737573, 0x99737473, 0x99737573, 0x99737473, 0x99737373, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99707070, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6b6b, + 0x996b6d6b, 0x99686b68, 0x99656865, 0x99656865, 0x99636563, 0x99606160, 0x99606160, 0x995d5d5d, + 0x995a555a, 0x99524e52, 0x994a484a, 0x99424142, 0x77101410, 0x77000000, 0x66000000, 0x11000000, + 0x00000000, 0x00000000, 0x88686968, 0xff9c9e9c, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffbdbebd, + 0xffc0c0c0, 0xffc0c0c0, 0xffc3c1c3, 0xffc5c2c5, 0xffc8c5c5, 0xffcbc8c5, 0xffcbc8c5, 0xffcbc8c5, + 0xffc8c9c8, 0xffc8c9c8, 0xffcbcccb, 0xffcbcccb, 0xffcecece, 0xffcecdce, 0xffcecece, 0xffcecece, + 0xffd0d0d0, 0xffd3d1d3, 0xffd0d0d0, 0xffd3d1d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, 0xffd3d4d3, + 0xffd6d4d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d9d6, + 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, 0xffd9dcd9, 0xffd9dcd9, 0xffdbdddb, 0xffdedfde, + 0xffdeddde, 0xffdedfde, 0xffdeddde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdfdee0, 0xffe1dfe1, 0xffe2dfe2, 0xffe2dfe2, 0xffe4dfe4, 0xffe2dee1, 0xffdddee2, + 0xffdedddf, 0xffdedcdf, 0xffdedcdf, 0xffdfdedf, 0xffdfdede, 0xffdedede, 0xffdedbde, 0xffd5dbd5, + 0xffd6d9d6, 0xffd6d9d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d5d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecdd0, 0xffcecece, 0xffcbcccb, 0xffcbcccb, 0xffc8c9c8, 0xffc5c6c5, + 0xffc3c2c3, 0xffc3c2c3, 0xffc0bec0, 0xffbdbab5, 0xffb5b2af, 0xffadaaaa, 0xffa5a2a5, 0xff9c9e9c, + 0x66343734, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x66161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x99555255, 0x995a595a, + 0x995a5d5a, 0x995d605d, 0x99606260, 0x99606260, 0x99656465, 0x99686768, 0x99686768, 0x99686768, + 0x996b696b, 0x996b6b6b, 0x996b6b6b, 0x996b6c6b, 0x996b6d6b, 0x996e6f6e, 0x996b6d6b, 0x996e6f6e, + 0x99737173, 0x996e6f73, 0x99707073, 0x99707073, 0x99737373, 0x99737173, 0x99737473, 0x99737473, + 0x99737573, 0x99737573, 0x99737776, 0x99737776, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x997b7876, 0x997b7876, 0x997b7876, 0x997b7876, 0x997b797b, 0x997b797b, 0x997b7b7b, 0x997b797b, + 0x997b7d7b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, + 0x997e807e, 0x99818381, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997e807e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7c7b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99797b79, 0x99767876, 0x99767876, 0x99767876, + 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99737573, 0x99737573, 0x99737573, 0x99737373, + 0x99737373, 0x99737173, 0x99737173, 0x99737173, 0x99707070, 0x99707070, 0x996e6f6e, 0x996e6f6e, + 0x996b6c6b, 0x996b6b6b, 0x996b696b, 0x996b696b, 0x99636563, 0x99606160, 0x995d5d5d, 0x995d5d5d, + 0x995a5552, 0x99524e4d, 0x99424142, 0x99424142, 0x77101010, 0x77000000, 0x66000000, 0x11000000, + 0x00000400, 0x00000400, 0x886e6d6e, 0xffa5a2a5, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffbdbebd, + 0xffc0c1c0, 0xffc0c1c0, 0xffc3c4c3, 0xffc3c4c3, 0xffc5c6c5, 0xffc8c9c8, 0xffc8c9c8, 0xffc8c9c8, + 0xffcecace, 0xffcecdce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced0d0, + 0xffd0d1d6, 0xffd0d1d6, 0xffd0d1d6, 0xffd0d1d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, + 0xffdedbd6, 0xffdedbd6, 0xffdedcd9, 0xffdedcd9, 0xffdedcde, 0xffdedbde, 0xffdeddde, 0xffdedcde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffe1e0e1, 0xffe6e3e6, 0xffe1e0e1, 0xffdedfde, 0xffdedfde, 0xffe1e1e1, 0xffe1e1e1, 0xffdddfdd, + 0xffe1dfe1, 0xffe3e0e3, 0xffe4e1e4, 0xffe3e0e3, 0xffe4e1e4, 0xffe4dfe4, 0xffe5dfe4, 0xffe5dee5, + 0xffe6dfe5, 0xffe6dfe5, 0xffe4dfe3, 0xffe0dee0, 0xffdfdedf, 0xffdfdede, 0xffdededf, 0xffdedcdb, + 0xffdedcdb, 0xffdedcdb, 0xffdedbde, 0xffd9d8d9, 0xffdbd9db, 0xffd9d8d9, 0xffd9d8d9, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd0d1d0, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffcecece, 0xffcecdce, 0xffcecace, 0xffcecace, 0xffc5c6c5, + 0xffc5c6c5, 0xffc0c1c0, 0xffbdbebd, 0xffb5b6b5, 0xffafafaf, 0xffaaa9aa, 0xffa5a2a5, 0xff9c9a9c, + 0x55343334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x66161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x99555255, 0x995a595a, + 0x995a5d5a, 0x995d605d, 0x99606260, 0x99636563, 0x99656465, 0x99656465, 0x99686768, 0x996b696b, + 0x996b6b6b, 0x996b6c6b, 0x996b6c6b, 0x996b6c6b, 0x99737173, 0x99707070, 0x99707070, 0x99737173, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737373, 0x99737373, 0x99737473, 0x99737473, + 0x99737573, 0x99737573, 0x99737776, 0x99737879, 0x99797879, 0x99767776, 0x99767776, 0x99767776, + 0x997b7b79, 0x997b7876, 0x997b7876, 0x997b7876, 0x997b797b, 0x997b797b, 0x997b7c7b, 0x997b7c7b, + 0x997b797b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99817f81, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, + 0x997e807e, 0x997e807e, 0x997b7d7b, 0x997b7d7b, 0x997e7f7e, 0x997e7f7e, 0x99818081, 0x997e7f7e, + 0x99818081, 0x99818081, 0x99848284, 0x99848284, 0x997e807e, 0x997e807e, 0x997e807e, 0x997e807e, + 0x99818081, 0x997e7f7e, 0x997e7f7e, 0x99818081, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, + 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997b7d7b, 0x997e807e, 0x997e807e, 0x997e807e, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7c7b, 0x997b7b7b, 0x997b797b, 0x997b7b7b, 0x99797b79, 0x99797b79, 0x99767876, 0x99767876, + 0x99797879, 0x99767776, 0x99767776, 0x99767776, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737473, 0x99737173, 0x99737173, 0x99737173, 0x99707070, 0x99707070, 0x996e6f6e, 0x996e6f6e, + 0x996b6c6b, 0x996b6c6b, 0x996b6b6b, 0x996b696b, 0x99636563, 0x99636563, 0x99606160, 0x995d5d5d, + 0x995a5552, 0x99524e4d, 0x994a4847, 0x99424142, 0x77101010, 0x77000000, 0x66000000, 0x11000000, + 0x00000400, 0x00000400, 0x776e6d6e, 0xffa5a2a5, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffbdbebd, + 0xffc0c1c0, 0xffc0c1c0, 0xffc3c4c3, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc8c9c8, 0xffcbcccb, + 0xffceccce, 0xffcecdce, 0xffcecece, 0xffcecece, 0xffced1d3, 0xffced1d3, 0xffced1d3, 0xffced2d6, + 0xffd3d4d6, 0xffd3d4d6, 0xffd3d4d6, 0xffd3d4d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, 0xffd6d5d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6dbd6, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, + 0xffdedcd9, 0xffdedcd9, 0xffdedcd9, 0xffdedcd9, 0xffdedcde, 0xffdedcde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdee0de, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffe4e1e4, 0xffe4e1e4, 0xffe1e0e1, 0xffe1e0e1, 0xffe1e1e1, 0xffe1e1e1, 0xffe4e4e4, 0xffe0e0e0, + 0xffe3e0e3, 0xffe3e0e3, 0xffe4e1e4, 0xffe5e2e5, 0xffe4e1e4, 0xffe4dfe4, 0xffe5e0e5, 0xffe5e2e5, + 0xffe6e2e5, 0xffe6e2e5, 0xffe6dfe6, 0xffe0dedf, 0xffdfdedf, 0xffdfdedf, 0xffdfdede, 0xffdfdcdd, + 0xffdedcdb, 0xffdedcdb, 0xffdedbde, 0xffdedbde, 0xffdbd9db, 0xffd9d8d9, 0xffd9d8d9, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d2d6, 0xffd0d1d0, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecace, 0xffc5c6c5, + 0xffc5c6c5, 0xffc0c1c0, 0xffbdbebd, 0xffb5b6b5, 0xffafafaf, 0xffaaa9aa, 0xffa5a2a5, 0xff9c9a9c, + 0x55343334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x66161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x995a595a, 0x995a595a, + 0x995d605d, 0x99606260, 0x99606260, 0x99606260, 0x99656465, 0x99686768, 0x99686768, 0x996b696b, + 0x996b6d6b, 0x996b6d6b, 0x996b6b6b, 0x996b6c6b, 0x996e6f6e, 0x996e6f6e, 0x99707070, 0x99707070, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737373, 0x99737573, 0x99737573, 0x99737573, + 0x99737776, 0x99737776, 0x99737776, 0x9973797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b7b79, 0x997b7b79, 0x997b7b79, 0x997b7d7b, 0x997b7b7b, 0x997b7b7b, 0x997b7c7b, 0x997b7c7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99817f81, 0x99817f81, 0x99817f81, 0x99817f81, + 0x997b7d7b, 0x997e807e, 0x997e807e, 0x997e807e, 0x99818081, 0x99818081, 0x99818081, 0x997e7f7e, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99818381, 0x997e807e, 0x99818381, 0x997e807e, + 0x99848284, 0x99818081, 0x99818081, 0x99818081, 0x99848284, 0x997e7f7e, 0x99818081, 0x99818081, + 0x99818081, 0x997e7f7e, 0x99818081, 0x99818081, 0x997e807e, 0x997e807e, 0x997e807e, 0x997e807e, + 0x997e807e, 0x997e807e, 0x997e807e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7c7b, 0x997b7c7b, 0x997b7c7b, 0x99797b79, 0x99797b79, 0x99797b79, 0x99797b79, + 0x99797879, 0x99767776, 0x99797879, 0x99767776, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737473, 0x99737473, 0x99737373, 0x99737173, 0x99737173, 0x99707070, 0x99707070, 0x996e6f6e, + 0x996b6d6b, 0x996b6d6b, 0x996b6b6b, 0x996b696b, 0x99636563, 0x99636563, 0x995d5d5d, 0x995d5d5d, + 0x995a5552, 0x99524e4d, 0x99424142, 0x99424142, 0x77101010, 0x77000000, 0x66000000, 0x11000000, + 0x00000400, 0x00000400, 0x66373937, 0xffa5a2a5, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffbdbebd, + 0xffc0c1c0, 0xffc3c4c3, 0xffc3c4c3, 0xffc5c6c5, 0xffc5c6c5, 0xffc8c9c8, 0xffc8c9c8, 0xffcbcccb, + 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecece, 0xffced0d0, 0xffced0d0, 0xffced1d3, 0xffced1d3, + 0xffd3d4d6, 0xffd3d4d6, 0xffd3d4d6, 0xffd3d4d6, 0xffd6d5d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, + 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6dbd6, 0xffd9d9d9, 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, + 0xffdedcd9, 0xffdedddb, 0xffdedcd9, 0xffdedfde, 0xffdeddde, 0xffdeddde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdee1de, 0xffdee1de, 0xffdee0de, 0xffdee1de, + 0xffe1e0e1, 0xffe6e3e6, 0xffe6e3e6, 0xffe4e1e4, 0xffe4e4e4, 0xffe3e3e4, 0xffe3e3e3, 0xffe2e3e2, + 0xffe3e3e3, 0xffe4e2e4, 0xffe4e2e4, 0xffe4e2e4, 0xffe5e2e5, 0xffe5e3e5, 0xffe5e2e5, 0xffe5e2e5, + 0xffe5e2e5, 0xffe6e2e5, 0xffe6e3e5, 0xffe3e0e3, 0xffe0dfe0, 0xffe0dfdf, 0xffe0dfdf, 0xffe0dede, + 0xffdfdddd, 0xffdedcdb, 0xffdedcdb, 0xffdedbde, 0xffdbd9db, 0xffdedbde, 0xffdbd9db, 0xffd6d9d6, + 0xffd6d8d6, 0xffd6d8d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd6d4d6, 0xffd3d4d3, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecace, 0xffc5c6c5, + 0xffc5c6c5, 0xffc0c1c0, 0xffbdbebd, 0xffb5b6b5, 0xffafafaf, 0xffa5a2a5, 0xffa5a2a5, 0xff9c9a9c, + 0x55343334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x66161616, 0x99424142, 0x99424142, 0x994a454a, 0x99504c50, 0x99555255, 0x995a595a, + 0x995a5d5a, 0x995d605d, 0x99606260, 0x99606260, 0x99686768, 0x99656465, 0x99686768, 0x996b696b, + 0x996b6b6b, 0x996b6c6b, 0x996b6c6b, 0x996b6d6b, 0x996e6f6e, 0x99707070, 0x99737173, 0x99707070, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737776, 0x99737776, 0x99737776, 0x99737776, 0x99797879, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b7b79, 0x997b7b79, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b827b, 0x99817f81, 0x99817f81, 0x99817f81, 0x99848284, + 0x99818381, 0x99818381, 0x997e807e, 0x99818381, 0x99848284, 0x99848284, 0x99848284, 0x99848284, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99818381, 0x99818381, 0x99818381, 0x99818381, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848684, 0x99818381, 0x99848684, 0x99818381, + 0x99848684, 0x997e807e, 0x997e807e, 0x997e807e, 0x997b7f7b, 0x997b827b, 0x997b7f7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, 0x997b7c7b, 0x99797b79, 0x997b7d7b, 0x99797b79, 0x99767876, + 0x997b797b, 0x997b797b, 0x99797879, 0x99767776, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x99737473, 0x99737473, 0x99737473, 0x99737373, 0x99737173, 0x99737173, 0x99707070, 0x99707070, + 0x996b6d6b, 0x996b6c6b, 0x996b6b6b, 0x996b696b, 0x99636563, 0x99606160, 0x995d5d5d, 0x995a595a, + 0x995a5552, 0x99524e4d, 0x99424142, 0x99424142, 0x77101010, 0x77000000, 0x55000000, 0x11000000, + 0x00000400, 0x00000400, 0x66373937, 0xffa5a2a5, 0xffa5aaa5, 0xffadb1ad, 0xffb5b7b5, 0xffbdbebd, + 0xffc0c1c0, 0xffc0c1c0, 0xffc3c4c3, 0xffc5c6c5, 0xffc8c9c8, 0xffc5c6c5, 0xffc8c9c8, 0xffcbcccb, + 0xffcecdce, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced0d0, 0xffced1d3, 0xffced2d6, 0xffced2d6, + 0xffd3d4d6, 0xffd3d4d6, 0xffd3d4d6, 0xffd3d4d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, + 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, + 0xffdedddb, 0xffdedddb, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdee0de, 0xffdee1de, 0xffdee0de, 0xffdee3de, 0xffdee1de, 0xffdee1de, 0xffdee1de, 0xffdee3de, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe3e4e3, 0xffe3e4e3, 0xffe2e4e2, 0xffe3e4e3, + 0xffe4e4e3, 0xffe4e3e4, 0xffe4e3e4, 0xffe4e4e5, 0xffe5e5e4, 0xffe5e3e5, 0xffe5e3e5, 0xffe5e2e5, + 0xffe6e2e5, 0xffe6e3e5, 0xffe6e3e5, 0xffe6e1e5, 0xffe3e0e3, 0xffe2dfe2, 0xffe0dfdf, 0xffe0dedf, + 0xffe0dfdc, 0xffdedcdc, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdbd9db, 0xffd6d9d6, + 0xffd6d9d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d5d6, 0xffd3d4d3, + 0xffd3d4d3, 0xffd0d1d0, 0xffd0d1d0, 0xffcecece, 0xffcecece, 0xffcecdce, 0xffcecace, 0xffc5c6c5, + 0xffc5c6c5, 0xffc0c1c0, 0xffbdbebd, 0xffb5b6b5, 0xffafafaf, 0xffaaa9aa, 0xffa5a2a5, 0xff9c9a9c, + 0x55343334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x66161616, 0x99424142, 0x99424142, 0x99424542, 0x994a4c4a, 0x99525252, 0x995a595a, + 0x995d5d5d, 0x99606160, 0x99606160, 0x99636563, 0x99656765, 0x99656765, 0x996b696b, 0x996b696b, + 0x996b6b6b, 0x996b6b6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d73, 0x996e7073, 0x99707373, 0x996e7073, + 0x99737373, 0x99737373, 0x99737473, 0x99737573, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x99767776, 0x99767776, 0x997b797b, 0x99797879, 0x997b797b, 0x997b797b, 0x997b7b7b, 0x997b7b7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997e807e, 0x997b7d7b, 0x997e807e, + 0x997e8084, 0x997e8084, 0x997e8084, 0x997e8084, 0x99848284, 0x99848284, 0x99848284, 0x99848384, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848384, 0x99848484, 0x99848484, + 0x99898484, 0x99898484, 0x99898484, 0x99898484, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99898789, 0x99868486, 0x99868486, 0x99868486, 0x99868486, 0x99868486, 0x99848284, 0x99868486, + 0x99848484, 0x99848384, 0x99848384, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848384, + 0x99848384, 0x99848384, 0x99848284, 0x99848284, 0x99818081, 0x997e7f7e, 0x997e7f7e, 0x99818081, + 0x997e7f7e, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, 0x997b7c7b, 0x997b7b7b, 0x997b7c7b, + 0x997b7b7b, 0x997b797b, 0x997b797b, 0x997b797b, 0x99767876, 0x99767876, 0x99767876, 0x99737573, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737373, 0x99737373, 0x99737073, 0x99736d73, + 0x99737173, 0x99706d6e, 0x996e6968, 0x996e6968, 0x99636563, 0x99606060, 0x99606060, 0x995d5a5d, + 0x99525152, 0x99525152, 0x99454345, 0x99454345, 0x77080c08, 0x77000000, 0x55000000, 0x11000000, + 0x00000000, 0x00000000, 0x66373637, 0xffa5a2a5, 0xffadaaad, 0xffadaaad, 0xffb5b2b5, 0xffbdbabd, + 0xffc0bec0, 0xffc3c2c3, 0xffc3c2c3, 0xffc5c6c5, 0xffc8c9c8, 0xffc8c9c8, 0xffcbcccb, 0xffcbcccb, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffd0ced0, 0xffd0ced0, 0xffd3d2d3, 0xffd3d2d3, 0xffd3d2d3, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d9d6, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedcde, 0xffdedcde, 0xffdeddde, 0xffdeddde, + 0xffdedfde, 0xffdedfde, 0xffdee0e1, 0xffdedfde, 0xffdedfde, 0xffe1e1e1, 0xffe1e1e1, 0xffe1e1e1, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e5e6, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe5e3e5, 0xffe4e5e4, 0xffe3e5e3, 0xffe4e5e3, + 0xffe4e6e4, 0xffe5e5e4, 0xffe5e6e5, 0xffe5e7e5, 0xffe5e6e4, 0xffe6e6e5, 0xffe6e6e6, 0xffe6e4e6, + 0xffe6e4e6, 0xffe6e4e6, 0xffe6e4e6, 0xffe6e3e5, 0xffe6e3e5, 0xffe6e1e5, 0xffe5e2e4, 0xffdfdfde, + 0xffdfe1df, 0xffdfdede, 0xffdedfde, 0xffdeddde, 0xffdedcde, 0xffdedcde, 0xffdedbde, 0xffd9d9d9, + 0xffdbdcdb, 0xffd9d9d9, 0xffd9d9d9, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d4d6, + 0xffd6d4d6, 0xffd6d1d6, 0xffd6d1d6, 0xffced2d6, 0xffceced0, 0xffceced0, 0xffcecacb, 0xffc5c6c5, + 0xffc3c2c3, 0xffc3c2c3, 0xffc0bec0, 0xffb5b2b5, 0xffadabad, 0xffa5a5a5, 0xff9c9e9c, 0xff8c8e8c, + 0x442f322f, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x55000000, 0x99424142, 0x99424142, 0x99424542, 0x994a4c4a, 0x99525252, 0x995a595a, + 0x995d5d5d, 0x995d5d5d, 0x99606160, 0x99636563, 0x99636563, 0x99656765, 0x99686868, 0x996b696b, + 0x996b6b6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996e7073, 0x996e7073, 0x996e7073, 0x99707373, + 0x99737473, 0x99737473, 0x99737573, 0x99737573, 0x99767776, 0x99767776, 0x99767776, 0x99767776, + 0x997b797b, 0x99767776, 0x997b797b, 0x997b797b, 0x997b7b7b, 0x997b7b7b, 0x997b7c7b, 0x997b7c7b, + 0x997e7f7e, 0x997b7d7b, 0x997e7f7e, 0x997e7f7e, 0x997b7d7b, 0x997e807e, 0x997e807e, 0x99818381, + 0x997e8084, 0x997e8084, 0x99818384, 0x99818384, 0x99848384, 0x99848384, 0x99848384, 0x99848484, + 0x99868686, 0x99898a89, 0x99848284, 0x99868686, 0x99848684, 0x99848684, 0x99848684, 0x99848484, + 0x99898484, 0x99898484, 0x99898484, 0x99868784, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99898789, 0x99898789, 0x99868486, 0x99898789, 0x99898789, 0x99868486, 0x99868486, 0x99868486, + 0x99848684, 0x99848684, 0x99848484, 0x99848484, 0x99848484, 0x99848384, 0x99848484, 0x99848384, + 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99848284, 0x99818081, 0x99818081, 0x99818081, + 0x99818081, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, 0x997b7c7b, + 0x997b7b7b, 0x997b7b7b, 0x997b7b7b, 0x997b797b, 0x99767876, 0x99767876, 0x99767876, 0x99767876, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737373, 0x99737373, 0x99737373, 0x99737073, + 0x99706d6e, 0x99706d6e, 0x996e6968, 0x996e6968, 0x99636563, 0x99606060, 0x99606060, 0x995d5a5d, + 0x99525152, 0x99525152, 0x99454345, 0x99373637, 0x77050805, 0x77000000, 0x55000000, 0x00000000, + 0x00000000, 0x00000000, 0x33373637, 0xffa5a2a5, 0xffa5a2a5, 0xffadaaad, 0xffb5b2b5, 0xffbdbabd, + 0xffc0bec0, 0xffc3c2c3, 0xffc3c2c3, 0xffc5c6c5, 0xffc5c6c5, 0xffc8c9c8, 0xffcbcccb, 0xffcbcccb, + 0xffcecece, 0xffcecece, 0xffd0ced0, 0xffd3ced3, 0xffd3d2d3, 0xffd3d2d3, 0xffd3d2d3, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedcde, 0xffdeddde, 0xffdeddde, 0xffdedfde, 0xffdedfde, + 0xffdee0e1, 0xffdedfde, 0xffdee0e1, 0xffdee0e1, 0xffe1e1e1, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e4e6, 0xffe6e4e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, + 0xffe6e5e6, 0xffe6e8e6, 0xffe6e5e6, 0xffe6e8e6, 0xffe5e8e5, 0xffe4e7e4, 0xffe3e7e4, 0xffe4e5e4, + 0xffe5e6e5, 0xffe5e6e5, 0xffe5e7e5, 0xffe5e8e6, 0xffe6e7e5, 0xffe6e7e6, 0xffe6e6e6, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e4e6, 0xffe6e4e6, 0xffe6e3e6, 0xffe6e4e5, 0xffe6e3e5, 0xffe6e1e5, 0xffe4e2e3, + 0xffe1e1e1, 0xffdfdfde, 0xffdedfde, 0xffdeddde, 0xffdeddde, 0xffdeddde, 0xffdedbde, 0xffdbdcdb, + 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd6d8d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d4d6, + 0xffd6d4d6, 0xffd6d4d6, 0xffd6d1d6, 0xffceced0, 0xffceced0, 0xffceced0, 0xffcecacb, 0xffc5c6c5, + 0xffc3c2c3, 0xffc3c2c3, 0xffbdbabd, 0xffb5b2b5, 0xffadabad, 0xffa5a5a5, 0xff9c9e9c, 0xee8c8e8c, + 0x332f322f, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x44000000, 0x99424142, 0x99424142, 0x99424542, 0x994a4c4a, 0x99525252, 0x995a595a, + 0x995d5d5d, 0x995d5d5d, 0x99606160, 0x99606160, 0x99636563, 0x99656765, 0x99686868, 0x996b696b, + 0x996b6b6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996e7073, 0x996e7073, 0x996e7073, 0x99707373, + 0x99737473, 0x99737573, 0x99737573, 0x99737573, 0x99767776, 0x99767776, 0x99797879, 0x99797879, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b7c7b, 0x997b7c7b, 0x997b7c7b, 0x997b7d7b, + 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997e807e, 0x99818381, 0x99818381, 0x99818381, + 0x99818384, 0x99818384, 0x99818384, 0x99818384, 0x99848384, 0x99848684, 0x99848684, 0x99848484, + 0x99868686, 0x99868686, 0x99868686, 0x99868686, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99868784, 0x99868784, 0x99868784, 0x99868784, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99898789, 0x99898789, 0x99898789, 0x99898789, 0x998c8a8c, 0x99898789, 0x99898789, 0x99898789, + 0x99848684, 0x99848684, 0x99848684, 0x99848484, 0x99848684, 0x99848484, 0x99848484, 0x99848384, + 0x99848484, 0x99848384, 0x99848384, 0x99848484, 0x99848284, 0x99848284, 0x99818081, 0x99848284, + 0x99818081, 0x99818081, 0x997e7f7e, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, + 0x997b7d7b, 0x997b7b7b, 0x997b7b7b, 0x997b797b, 0x99797b79, 0x99797b79, 0x99767876, 0x99767876, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737373, 0x99737373, 0x99737373, 0x99737073, + 0x99706d6e, 0x99706d6e, 0x996e6968, 0x996b6563, 0x99636563, 0x99606060, 0x995d5a5d, 0x995a555a, + 0x99525152, 0x99454345, 0x99454345, 0x88292829, 0x77030403, 0x77000000, 0x44000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0xffa5a2a5, 0xffa5a2a5, 0xffadaaad, 0xffb5b2b5, 0xffbdbabd, + 0xffc0bec0, 0xffc3c2c3, 0xffc3c2c3, 0xffc3c2c3, 0xffc5c6c5, 0xffc8c9c8, 0xffc8c9c8, 0xffcbcccb, + 0xffcecece, 0xffcecece, 0xffd0ced0, 0xffd3ced3, 0xffd3d2d3, 0xffd3d2d3, 0xffd3d2d3, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6dbd6, 0xffd6dbd6, + 0xffdedbde, 0xffdedcde, 0xffdeddde, 0xffdeddde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdee0e1, 0xffdee0e1, 0xffdee1e4, 0xffdee1e4, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, + 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e5e6, + 0xffe6e5e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe8e9e7, 0xffebeae9, 0xffeeeaed, + 0xffe9e7e8, 0xffe9e8ea, 0xffe6e8e8, 0xffe6e8e6, 0xffe6e9e6, 0xffe6e8e6, 0xffe7e9e7, 0xffe7e7e5, + 0xffe6e6e5, 0xffe7e7e6, 0xffe6e7e6, 0xffe6e4e6, 0xffe6e6e6, 0xffe6e3e5, 0xffe5e3e5, 0xffe5e1e4, + 0xffe1e1e1, 0xffdfe1df, 0xffdee0de, 0xffdedfde, 0xffdeddde, 0xffdeddde, 0xffdedcde, 0xffdbdcdb, + 0xffdbdcdb, 0xffdbdcdb, 0xffd9d9d9, 0xffd6d9d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d7d6, 0xffd6d4d6, + 0xffd6d4d6, 0xffd6d4d6, 0xffd6d4d6, 0xffceced0, 0xffceced0, 0xffceced0, 0xffcecacb, 0xffc5c6c5, + 0xffc3c2c3, 0xffc0bec0, 0xffbdbabd, 0xffb5b2b5, 0xffadabad, 0xffa5a5a5, 0xff9c9e9c, 0xdd8c8e8c, + 0x22000400, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x44000000, 0x882c2b2c, 0x99424142, 0x99424542, 0x99424542, 0x994a4c4a, 0x995a595a, + 0x995a595a, 0x995d5d5d, 0x995d5d5d, 0x99606160, 0x99636563, 0x99656765, 0x996b696b, 0x996b696b, + 0x996b6b6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996e7073, 0x996e7073, 0x99707373, 0x99707373, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99767776, 0x99767776, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997e7f7e, 0x997e7f7e, 0x99818081, 0x99848284, 0x99818381, 0x99818381, 0x99818381, 0x99818381, + 0x99818384, 0x99818384, 0x99818384, 0x99818384, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99868686, 0x99868686, 0x99868686, 0x99868686, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99848a84, 0x99868784, 0x99868784, 0x99848a84, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x998c8a8c, 0x99898789, 0x99898789, 0x998c8a8c, 0x998c8a8c, 0x99898789, 0x99898789, 0x99898789, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99848684, 0x99848684, 0x99848484, 0x99848484, 0x99848284, 0x99848284, 0x99848284, 0x99848284, + 0x997e7f7e, 0x99818081, 0x997e7f7e, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, 0x997b7b7b, 0x99797b79, 0x99797b79, 0x99797b79, 0x99767876, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737373, 0x99737373, 0x99737073, + 0x99706d6e, 0x996e6968, 0x996e6968, 0x996b6563, 0x99606060, 0x99606060, 0x995d5a5d, 0x995a555a, + 0x99525152, 0x99454345, 0x99454345, 0x88292829, 0x77030403, 0x77000000, 0x33000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xdda5a2a5, 0xffa5a2a5, 0xffadaaad, 0xffb5b2b5, 0xffbdbabd, + 0xffbdbabd, 0xffc0bec0, 0xffc3c2c3, 0xffc3c2c3, 0xffc5c6c5, 0xffc8c9c8, 0xffcbcccb, 0xffcbcccb, + 0xffcecece, 0xffd0ced0, 0xffd0ced0, 0xffd0ced0, 0xffd3d2d3, 0xffd3d2d3, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6dbd6, 0xffd6dbd6, + 0xffdedcde, 0xffdeddde, 0xffdeddde, 0xffdeddde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdee0e1, 0xffdee1e4, 0xffdee3e6, 0xffdee3e6, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffe6e7e6, + 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe7e9e7, 0xffe8e8e8, + 0xffeaece9, 0xffe7e9e6, 0xffe6e9e6, 0xffe6ebe6, 0xffe6e9e6, 0xffe7e9e7, 0xffe9e9e9, 0xffe7e7e6, + 0xffe6e6e6, 0xffe6e7e7, 0xffe7e4e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e4e5, 0xffe5e3e5, 0xffe4e1e4, + 0xffe2e1e2, 0xffdfe0df, 0xffdee0de, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdeddde, 0xffdedfde, + 0xffdbdcdb, 0xffdbdcdb, 0xffdbdcdb, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d4d6, 0xffd6d1d6, 0xffceced0, 0xffceced0, 0xffcecacb, 0xffcec6c5, 0xffc3c2c3, + 0xffc3c2c3, 0xffc0bec0, 0xffbdbabd, 0xffb5b2b5, 0xffadabad, 0xff9c9e9c, 0xff9c9e9c, 0xbb5d605d, + 0x22000400, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x22000000, 0x77262826, 0x993a3d3a, 0x99424142, 0x99424142, 0x994d4c4d, 0x99525152, + 0x99525452, 0x995a5a5a, 0x99636163, 0x99636163, 0x99656565, 0x99656565, 0x996b696b, 0x996b696b, + 0x996b6c6e, 0x996b6c6e, 0x996b6f70, 0x996b6f70, 0x99737173, 0x99737173, 0x99737173, 0x99737473, + 0x99737576, 0x99737576, 0x99737576, 0x99737576, 0x99767876, 0x99797b79, 0x99797b79, 0x99797b79, + 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997e7c7e, 0x997b7d7b, 0x997b7d7b, 0x997e807e, 0x997e807e, + 0x99848084, 0x99848084, 0x99848384, 0x99848384, 0x99868486, 0x99868486, 0x99868486, 0x99868486, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99868786, 0x99868786, 0x99868786, 0x99848684, + 0x99868886, 0x99868886, 0x99868886, 0x99868886, 0x99868886, 0x99868886, 0x99868886, 0x99868886, + 0x998c888c, 0x998c888c, 0x998c888c, 0x998c888c, 0x99898a89, 0x99868686, 0x99898a89, 0x99898a89, + 0x998c888c, 0x998c888c, 0x998c888c, 0x998c8b8c, 0x99898b89, 0x99868886, 0x99868886, 0x99868886, + 0x99868786, 0x99868786, 0x99868786, 0x99868786, 0x99868786, 0x99848684, 0x99848684, 0x99868786, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848284, 0x99868686, 0x99848284, 0x99848284, + 0x99848384, 0x99848384, 0x99848284, 0x99848284, 0x997e807e, 0x997e807e, 0x997e807e, 0x997b7d7b, + 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7b7b, 0x997b7b7b, 0x997b797b, 0x997b797b, + 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99737573, 0x99707370, 0x99707370, 0x996e706e, + 0x996b6d6b, 0x99686968, 0x99656565, 0x99656565, 0x99636163, 0x99636163, 0x995d5c5d, 0x99585658, + 0x994a494a, 0x994a494a, 0x994a494a, 0x77191b19, 0x77000000, 0x77000000, 0x22000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xaa736d73, 0xff9fa29f, 0xff9fa29f, 0xffb5b6b5, 0xffb5b6b5, + 0xffbdbabd, 0xffbdbabd, 0xffc5c2c5, 0xffc5c2c5, 0xffc8c6c8, 0xffc8c6c8, 0xffcecace, 0xffcecace, + 0xffd0cdd0, 0xffd0cdd0, 0xffd3d0d3, 0xffd3d0d3, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d4d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d8d6, 0xffd6d8d6, 0xffd6d9d6, 0xffdedbde, 0xffdedcde, 0xffdedcde, 0xffdedcde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffe1e1e1, 0xffe1e1e1, 0xffe1e1e1, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e4e6, 0xffe6e4e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e8e9, 0xffe6e8e9, 0xffe6e7e6, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe6e7e6, + 0xffefebe6, 0xffefebe6, 0xffefebe6, 0xffefebe6, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, + 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffedeaed, 0xffede9ed, + 0xffeae8e9, 0xffe5e7e9, 0xffe8e7e9, 0xffe7e7e6, 0xffe6e6e6, 0xffe6e6e5, 0xffe5e6e5, 0xffe3e4e3, + 0xffe3e3e3, 0xffe1e1e1, 0xffe1e1e1, 0xffe1e0e1, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedddb, + 0xffdedddb, 0xffdedcd9, 0xffdedcd9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd6d7d6, + 0xffd6d7d6, 0xffd3d4d3, 0xffd0d1d0, 0xffcecece, 0xffcecece, 0xffc8cacb, 0xffc3c6c8, 0xffc5c2c5, + 0xffc5c2c5, 0xffbdbcbd, 0xffb5b5b5, 0xffadaead, 0xffadaead, 0xffadaead, 0xff8f908f, 0x774a4d4a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x66131413, 0x993a3d3a, 0x99424142, 0x99424142, 0x99474647, 0x994d4c4d, + 0x99525452, 0x995a5a5a, 0x995a5a5a, 0x99636163, 0x99656565, 0x99656565, 0x99656565, 0x996b696b, + 0x996b6c6e, 0x996b6c6e, 0x996b6f70, 0x996b6f70, 0x99737173, 0x99737173, 0x99737173, 0x99737373, + 0x99737573, 0x99737576, 0x99737576, 0x99737576, 0x99767876, 0x99767876, 0x99767876, 0x99797b79, + 0x997e7c7e, 0x997e7c7e, 0x99817f81, 0x99817f81, 0x997b7d7b, 0x997e807e, 0x997e807e, 0x997e807e, + 0x99848384, 0x99848384, 0x99848384, 0x99848384, 0x99868486, 0x99868486, 0x99868486, 0x99868486, + 0x99868786, 0x99868786, 0x99868786, 0x99868786, 0x99868786, 0x99898889, 0x99868786, 0x99868786, + 0x99868886, 0x99868886, 0x99898b89, 0x99898b89, 0x99868886, 0x99898b89, 0x99898b89, 0x99898b89, + 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x99898a89, 0x99898a89, 0x99898a89, 0x99898a89, + 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x99868886, 0x99898b89, 0x99868886, 0x99868886, + 0x99898889, 0x99898889, 0x99898889, 0x99868786, 0x99868786, 0x99868786, 0x99848684, 0x99868786, + 0x99848684, 0x99868786, 0x99898889, 0x99848684, 0x99868686, 0x99848284, 0x99868686, 0x99868686, + 0x99848384, 0x99848484, 0x99848284, 0x99848384, 0x99818381, 0x997e807e, 0x997e807e, 0x997e807e, + 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, 0x997b7b7b, 0x997b7b7b, + 0x997b797b, 0x99797879, 0x99767776, 0x99767776, 0x99737573, 0x99707370, 0x99707370, 0x996b6d6b, + 0x99686968, 0x99686968, 0x99656565, 0x99636163, 0x99636163, 0x995d5c5d, 0x99585658, 0x99585658, + 0x994a494a, 0x994a494a, 0x99313231, 0x77000400, 0x77000000, 0x66000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x554d494d, 0xff9fa29f, 0xff9fa29f, 0xff9fa29f, 0xffb5b6b5, + 0xffb5b2b5, 0xffbdbabd, 0xffbdbabd, 0xffc5c2c5, 0xffc8c6c8, 0xffc8c6c8, 0xffc8c6c8, 0xffcecace, + 0xffd0cdd0, 0xffd0cdd0, 0xffd3d0d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d4d6, 0xffd6d5d6, + 0xffd6d7d6, 0xffd6d9d6, 0xffd6d9d6, 0xffd6d9d6, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedcde, + 0xffdedfde, 0xffdedfde, 0xffdee0de, 0xffdee0de, 0xffe1e1e1, 0xffe1e1e1, 0xffe1e1e1, 0xffe1e1e1, + 0xffe6e5e6, 0xffe6e4e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, + 0xffe6e9ec, 0xffe6e8e9, 0xffe6e9ec, 0xffe6e9ec, 0xffe9e9e9, 0xffececec, 0xffe9e9e9, 0xffe9e9e9, + 0xffefece9, 0xffefebe6, 0xffefece9, 0xffefece9, 0xffefebef, 0xffefecef, 0xffefecef, 0xffefecef, + 0xffefecef, 0xffefecef, 0xffefecef, 0xffefecef, 0xffefebef, 0xffeeecef, 0xffeeeced, 0xffede9ed, + 0xffede9ed, 0xffede7ec, 0xffece7ec, 0xffeae7ea, 0xffe7e7e7, 0xffe6e6e6, 0xffe5e6e5, 0xffe3e5e3, + 0xffe3e4e3, 0xffe4e4e4, 0xffe1e1e1, 0xffe1e0e1, 0xffe1e0e1, 0xffe1e0e1, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedddb, 0xffdedddb, 0xffdbdcdb, 0xffdbdcdb, 0xffd9d9d9, 0xffd9d9d9, 0xffd6d7d6, + 0xffd3d4d3, 0xffd3d4d3, 0xffd0d1d0, 0xffcecece, 0xffcecece, 0xffc8cacb, 0xffc3c6c8, 0xffc5c2c5, + 0xffbdbcbd, 0xffbdbcbd, 0xffb5b5b5, 0xffadaead, 0xffadaead, 0xffadaead, 0xff8f908f, 0x44313331, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x55000000, 0x993a3d3a, 0x99424142, 0x99424142, 0x99424142, 0x994d4c4d, + 0x99525452, 0x995a5a5a, 0x995a5a5a, 0x995a5a5a, 0x99606160, 0x99606160, 0x99656565, 0x996b696b, + 0x996b696b, 0x996b6c6e, 0x996b6f70, 0x996b6f70, 0x99737173, 0x99737173, 0x99737373, 0x99737373, + 0x99737573, 0x99737576, 0x99737576, 0x99737579, 0x99767876, 0x99767876, 0x99797b79, 0x997b7d7b, + 0x99817f81, 0x997e7c7e, 0x997e7c7e, 0x99817f81, 0x997e807e, 0x997e807e, 0x99818381, 0x99818381, + 0x99848384, 0x99848384, 0x99848384, 0x99848384, 0x99868486, 0x99898789, 0x99868486, 0x99898789, + 0x99868786, 0x99868786, 0x99868786, 0x99868786, 0x99898889, 0x99898889, 0x998c8a8c, 0x99898889, + 0x99898b89, 0x99898b89, 0x99898b89, 0x99898b89, 0x99898b89, 0x99898b89, 0x99898b89, 0x99898b89, + 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x998c8e8c, 0x998c8e8c, 0x99898a89, 0x998c8e8c, 0x99898a89, + 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x99898b89, 0x99898b89, 0x99898b89, 0x99868886, + 0x998c8a8c, 0x998c8a8c, 0x99898889, 0x99868786, 0x998c8a8c, 0x99898889, 0x99868786, 0x99868786, + 0x99868786, 0x99898889, 0x998c8a8c, 0x99868786, 0x99868686, 0x99868686, 0x99868686, 0x99868686, + 0x99848484, 0x99848484, 0x99848484, 0x99848384, 0x99818381, 0x997e807e, 0x997e807e, 0x997e807e, + 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7b7b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x99767776, 0x99767776, 0x99737573, 0x99707370, 0x996e706e, 0x996b6d6b, + 0x99686968, 0x99686968, 0x99656565, 0x99636163, 0x99636163, 0x995d5c5d, 0x99585658, 0x99525152, + 0x994a494a, 0x994a494a, 0x88313231, 0x77000400, 0x77000000, 0x55000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x22262426, 0xee9fa29f, 0xff9fa29f, 0xff9fa29f, 0xff9fa29f, + 0xffb5b2b5, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffc3c2c3, 0xffc3c2c3, 0xffc8c6c8, 0xffcecace, + 0xffcecace, 0xffd0cdd0, 0xffd3d0d3, 0xffd3d0d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d5d6, 0xffd6d5d6, + 0xffd6d8d6, 0xffd6d7d6, 0xffd6d9d6, 0xffd6d9d6, 0xffdedbde, 0xffdedbde, 0xffdedcde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdee0de, 0xffe1e1e1, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, + 0xffe6e4e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e7e6, 0xffe9e8e9, 0xffe6e7e6, 0xffe9e8e9, + 0xffe6e9ec, 0xffe6e9ec, 0xffe6e9ec, 0xffe6e9ec, 0xffececec, 0xffececec, 0xffececec, 0xffececec, + 0xffefedec, 0xffefece9, 0xffefece9, 0xffefece9, 0xffefecef, 0xffefecef, 0xffefedef, 0xffefecef, + 0xffefedef, 0xffefedef, 0xffefedef, 0xffefefef, 0xffefedef, 0xffefedef, 0xffeeecee, 0xffeee9ee, + 0xffede9ed, 0xffedeaec, 0xffeceaec, 0xffe9eae9, 0xffe8e7e8, 0xffe7e7e7, 0xffe7e5e7, 0xffe4e4e4, + 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e1e4, 0xffe4e1e4, 0xffe1e0e1, 0xffe1e0e1, 0xffdedfde, + 0xffdedfde, 0xffdedddb, 0xffdedcd9, 0xffdbdcdb, 0xffdbdcdb, 0xffd9d9d9, 0xffd9d9d9, 0xffd6d7d6, + 0xffd3d4d3, 0xffd0d1d0, 0xffd0d1d0, 0xffcecece, 0xffc8cacb, 0xffc3c6c8, 0xffbdc2c5, 0xffc5c2c5, + 0xffbdbcbd, 0xffb5b5b5, 0xffb5b5b5, 0xffadaead, 0xffadaead, 0xff8f908f, 0xbb707370, 0x11191a19, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x33000000, 0x77131413, 0x99424142, 0x99424142, 0x99424142, 0x99424142, + 0x994a4d4a, 0x99525452, 0x99525452, 0x995a5a5a, 0x995a5d5a, 0x99606160, 0x99656565, 0x99656565, + 0x996b696b, 0x996b6c6e, 0x996b6c6e, 0x996b6f70, 0x99737173, 0x99737173, 0x99737373, 0x99737573, + 0x99737576, 0x99737576, 0x99737576, 0x99737579, 0x99767876, 0x99797b79, 0x997b7d7b, 0x997b7d7b, + 0x99817f81, 0x997e7c7e, 0x99817f81, 0x99848284, 0x997e807e, 0x99818381, 0x99818381, 0x99818381, + 0x99848384, 0x99848684, 0x99848684, 0x99848684, 0x99898789, 0x99898789, 0x99898789, 0x998c8a8c, + 0x99898889, 0x99868786, 0x99898889, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, + 0x99898b89, 0x99898b89, 0x99898b89, 0x998c8e8c, 0x99898b89, 0x998c8e8c, 0x99898b89, 0x998c8e8c, + 0x998c8b8c, 0x998c8e8c, 0x998c8b8c, 0x998c8b8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x998c8b8c, 0x99898b89, 0x998c8e8c, 0x99898b89, 0x99898b89, + 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x99898889, 0x99898889, + 0x99898889, 0x99868786, 0x99868786, 0x99868786, 0x99898a89, 0x99868686, 0x99868686, 0x99868686, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99818381, 0x99818381, 0x99818381, 0x997e807e, + 0x99848284, 0x997e7f7e, 0x99818081, 0x997e7f7e, 0x997b7d7b, 0x997b7d7b, 0x997b7c7b, 0x997b7c7b, + 0x997b797b, 0x99797879, 0x99767776, 0x99767776, 0x99737573, 0x996e706e, 0x996b6d6b, 0x996b6d6b, + 0x99686968, 0x99656565, 0x99636163, 0x99636163, 0x995d5c5d, 0x99585658, 0x99585658, 0x99525152, + 0x994a494a, 0x994a494a, 0x77191b19, 0x77000400, 0x77000000, 0x33000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x99737973, 0xff9fa29f, 0xff9fa29f, 0xff9fa29f, + 0xffadaaad, 0xffb5b2b5, 0xffbdbabd, 0xffbdbabd, 0xffbdbebd, 0xffc3c2c3, 0xffc8c6c8, 0xffc8c6c8, + 0xffcecace, 0xffd0cdd0, 0xffd0cdd0, 0xffd3d0d3, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d5d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d8d6, 0xffd6d9d6, 0xffd6d9d6, 0xffdedbde, 0xffdeddde, 0xffdedfde, 0xffdedfde, + 0xffdee1de, 0xffdedfde, 0xffdee0de, 0xffdee3de, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffe6e7e6, + 0xffe6e5e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe9e8e9, 0xffe9e8e9, 0xffe9e8e9, 0xffefebef, + 0xffe6ebef, 0xffe6e9ec, 0xffe6ebef, 0xffe6ebef, 0xffececec, 0xffececec, 0xffececec, 0xffececec, + 0xffefedec, 0xffefedec, 0xffefefef, 0xffefefef, 0xffefedef, 0xffefefef, 0xffefedef, 0xffefefef, + 0xffefedef, 0xffefefef, 0xffefedef, 0xffefedef, 0xffefedef, 0xffefedef, 0xffeeedef, 0xffeeeded, + 0xffeeebed, 0xffece9eb, 0xffeaeaea, 0xffe8e9e8, 0xffe8e9e8, 0xffe8e9e8, 0xffe6e7e7, 0xffe6e7e6, + 0xffe6e7e6, 0xffe4e4e4, 0xffe4e4e4, 0xffe6e3e6, 0xffe4e1e4, 0xffe6e3e6, 0xffe1e0e1, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdbdcdb, 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffd6d7d6, + 0xffd3d4d3, 0xffd0d1d0, 0xffcecece, 0xffc8cacb, 0xffc3c6c8, 0xffc3c6c8, 0xffbdc2c5, 0xffbdbcbd, + 0xffbdbcbd, 0xffb5b5b5, 0xffadaead, 0xffadaead, 0xffadaead, 0xff8f908f, 0x66525552, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x55080408, 0x882c2b2c, 0x99424142, 0x99424142, 0x99424142, + 0x99424142, 0x994d4e4d, 0x99525552, 0x99525552, 0x995a5a5d, 0x99636163, 0x99636163, 0x99636163, + 0x9968686e, 0x9968686e, 0x996b6d73, 0x996b6d73, 0x99736d6b, 0x9973706e, 0x99737370, 0x99737573, + 0x99737573, 0x99767776, 0x99767776, 0x997b797b, 0x997b797b, 0x997b797b, 0x997e7c7e, 0x997e7c7e, + 0x997b7d7b, 0x997b7d7b, 0x997e807e, 0x99818381, 0x99848284, 0x99848284, 0x99848284, 0x99848284, + 0x99848684, 0x99848684, 0x99848684, 0x99868786, 0x998c8886, 0x998c8886, 0x998c8886, 0x998c8b89, + 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998f8c8f, 0x998f8c8f, 0x998c8a8c, 0x998c8a8c, + 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x998f908f, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x998f8c8f, 0x998c8a8c, 0x998f8c8f, 0x998c8a8c, 0x998c8e8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, + 0x9986888c, 0x9986888c, 0x9986888c, 0x9986888c, 0x998c8886, 0x998c8886, 0x998c8886, 0x998c8886, + 0x99868786, 0x99868786, 0x99848684, 0x99848684, 0x99848684, 0x99848484, 0x99848484, 0x99848384, + 0x99818381, 0x997e807e, 0x997e807e, 0x997e807e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99797b79, + 0x9973797b, 0x9973797b, 0x99737779, 0x99737476, 0x99737173, 0x99737173, 0x996e6d6e, 0x99686968, + 0x9963656b, 0x9963656b, 0x99606065, 0x99606065, 0x995a5d5a, 0x995a5d5a, 0x994a4c4a, 0x994a4c4a, + 0x994a494a, 0x88343234, 0x77080408, 0x77080408, 0x66000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22000400, 0xdda5a2a5, 0xffa5a2a5, 0xffa5a2a5, + 0xffaaa9aa, 0xffafafaf, 0xffb5b6b5, 0xffb5b6b5, 0xffbdbcbd, 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, + 0xffc8cacb, 0xffcbced0, 0xffcbced0, 0xffcbced0, 0xffd6d1d0, 0xffd6d4d3, 0xffd6d4d3, 0xffd6d7d6, + 0xffd6d7d6, 0xffd9d9d9, 0xffd9d9d9, 0xffdbdcdb, 0xffdeddde, 0xffdeddde, 0xffdeddde, 0xffdeddde, + 0xffdedfde, 0xffe1e1e1, 0xffe1e1e1, 0xffe4e4e4, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e5e6, 0xffe6e5e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe9e9e9, 0xffefebe6, 0xffefebe6, 0xffefebe6, 0xffefece9, + 0xffefebef, 0xffefebef, 0xffefebef, 0xffefedf1, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xfff1f2f1, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xfff0efef, 0xfff3f2f2, 0xfff1efef, + 0xfff1eeef, 0xffeeebec, 0xffeeebee, 0xffebe9ea, 0xffe9e9e9, 0xffe6e7e7, 0xffe6e7e6, 0xffe6e8e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe4e4e4, 0xffe4e4e4, 0xffe1e1e1, 0xffe1e1e1, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdbdddb, 0xffd6dbde, 0xffd6dbde, 0xffd6d8db, 0xffd6d5d9, 0xffd6d7de, + 0xffd0d1d6, 0xffd0d1d6, 0xffcbccce, 0xffc5c6c5, 0xffc5c6c5, 0xffc0c2c0, 0xffc0c2c0, 0xffbdbebd, + 0xffb5b5b5, 0xffb5b5b5, 0xffadabad, 0xffa5a6a5, 0xffa5a6a5, 0xcc707170, 0x11080808, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x33000000, 0x66161616, 0x99424142, 0x99424142, 0x99424142, + 0x99424142, 0x99474847, 0x994d4e4d, 0x99525552, 0x995a5a5d, 0x995a5a5d, 0x99636163, 0x99636163, + 0x9968686e, 0x9968686e, 0x9968686e, 0x996b6d73, 0x99736d6b, 0x99737370, 0x99737573, 0x99737573, + 0x99767776, 0x99767776, 0x99767776, 0x997b797b, 0x997e7c7e, 0x99817f81, 0x997e7c7e, 0x99817f81, + 0x997e807e, 0x997e807e, 0x997e807e, 0x997e807e, 0x99848284, 0x99848686, 0x99848686, 0x99848686, + 0x99848684, 0x99868786, 0x99868786, 0x99868786, 0x998c8886, 0x998c8886, 0x998c8b89, 0x998c8b89, + 0x998c8c8f, 0x998c8c8f, 0x998c8a8c, 0x998c8c8f, 0x998f8c8f, 0x99918f91, 0x998f8c8f, 0x99918f91, + 0x998f8f8f, 0x998f8f8f, 0x998f8f8f, 0x998f8f8f, 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, + 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, + 0x998f908f, 0x998f908f, 0x998c8e8c, 0x998f908f, 0x998c8e8c, 0x998f908f, 0x998f908f, 0x998c8e8c, + 0x99918f91, 0x998f8c8f, 0x998f8c8f, 0x998f8c8f, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8a8c, + 0x99898b8c, 0x99898b8c, 0x99898b8c, 0x99898b8c, 0x998c8b89, 0x998c8886, 0x998c8b89, 0x998c8886, + 0x99898889, 0x99868786, 0x99868786, 0x99868786, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99818381, 0x99818381, 0x99818381, 0x997e807e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99797b79, + 0x9973797b, 0x99737779, 0x99737779, 0x99737476, 0x99737173, 0x996e6d6e, 0x99686968, 0x99686968, + 0x9963656b, 0x9963656b, 0x99606065, 0x995d5a60, 0x995a5d5a, 0x995a5d5a, 0x994a4c4a, 0x994a4c4a, + 0x99343234, 0x771e1b1e, 0x77080408, 0x77080408, 0x33000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x55373937, 0xeea5a2a5, 0xffa5a2a5, + 0xffa5a2a5, 0xffaaa9aa, 0xffafafaf, 0xffb5b6b5, 0xffbdbcbd, 0xffbdbcbd, 0xffc5c2c5, 0xffc5c2c5, + 0xffc8cacb, 0xffc8cacb, 0xffc8cacb, 0xffced2d6, 0xffd6d1d0, 0xffd6d4d3, 0xffd6d7d6, 0xffd6d7d6, + 0xffd9d9d9, 0xffd9d9d9, 0xffd9d9d9, 0xffdbdcdb, 0xffdeddde, 0xffdee0de, 0xffdeddde, 0xffdee0de, + 0xffe1e1e1, 0xffe1e1e1, 0xffe4e4e4, 0xffe4e4e4, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e7e6, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffefebe6, 0xffefebe6, 0xffefece9, 0xffefece9, + 0xffefedf1, 0xffefedf1, 0xffefedf1, 0xffefedf1, 0xffefefef, 0xfff1f0f1, 0xffefefef, 0xfff1f0f1, + 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, + 0xfff4f4f4, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, 0xfff4f4f4, 0xfff1f2f1, 0xfff2f2f1, 0xfff1f0f0, + 0xfff1efef, 0xffefeded, 0xffede9ed, 0xffece9ec, 0xffeae9ea, 0xffe9e9e9, 0xffe9e9e9, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdbdddb, 0xffd6dbde, 0xffd6d8db, 0xffd6d8db, 0xffd6d5d9, 0xffd0d1d6, + 0xffd0d1d6, 0xffcbccce, 0xffcbccce, 0xffc5c6c5, 0xffc5c6c5, 0xffc0c2c0, 0xffbabeba, 0xffbdbebd, + 0xffb5b5b5, 0xffb5b5b5, 0xffadabad, 0xffa5a6a5, 0xdda5a6a5, 0x443c3d3c, 0x00080808, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x55000000, 0x77161616, 0x99424142, 0x99424142, + 0x99424142, 0x99424142, 0x99474847, 0x994d4e4d, 0x99525458, 0x995a5a5d, 0x99636163, 0x99636163, + 0x99656268, 0x9968686e, 0x9968686e, 0x996b6d73, 0x9973706e, 0x99737370, 0x99737573, 0x99737573, + 0x99767776, 0x99767776, 0x997b797b, 0x997b797b, 0x99817f81, 0x99817f81, 0x99817f81, 0x99817f81, + 0x997e807e, 0x997e807e, 0x99818381, 0x99818381, 0x99848686, 0x99848686, 0x99848686, 0x99848686, + 0x99868786, 0x99868786, 0x998c8a8c, 0x998c8a8c, 0x998c8b89, 0x998c8b89, 0x998c8b89, 0x998c8b89, + 0x998c8c8f, 0x998c8c8f, 0x998c8c8f, 0x998c8f91, 0x99918f91, 0x99918f91, 0x99949294, 0x99949294, + 0x99919091, 0x99919091, 0x998f8f8f, 0x99919091, 0x998f908f, 0x99919391, 0x998f908f, 0x99919391, + 0x998f908f, 0x998f908f, 0x99919391, 0x998f908f, 0x998f908f, 0x998f908f, 0x99919391, 0x998f908f, + 0x998f908f, 0x998f908f, 0x99919391, 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, 0x998f908f, + 0x99918f91, 0x99918f91, 0x99918f91, 0x99918f91, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x99898b8c, 0x99898b8c, 0x99898b8c, 0x99898b8c, 0x998c8b89, 0x998c8b89, 0x998c8b89, 0x998c8886, + 0x998c8a8c, 0x99868786, 0x99868786, 0x99868786, 0x99848684, 0x99848684, 0x99848684, 0x99848484, + 0x99818381, 0x99818381, 0x99818381, 0x99818381, 0x997b7d7b, 0x997b7d7b, 0x99797b79, 0x99797b79, + 0x99737779, 0x99737779, 0x99737476, 0x99737173, 0x99737173, 0x996e6d6e, 0x99686968, 0x99636563, + 0x9963656b, 0x99606065, 0x99606065, 0x995d5a60, 0x995a5d5a, 0x994a4c4a, 0x994a4c4a, 0x994a4c4a, + 0x771e1b1e, 0x77080408, 0x77080408, 0x55080408, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x886e6d6e, 0xffa5a2a5, + 0xffa5a2a5, 0xffa5a2a5, 0xffaaa9aa, 0xffafafaf, 0xffb5b5b5, 0xffbdbcbd, 0xffc5c2c5, 0xffc5c2c5, + 0xffc5c6c5, 0xffc8cacb, 0xffc8cacb, 0xffcbced0, 0xffd6d1d0, 0xffd6d4d3, 0xffd6d7d6, 0xffd6d7d6, + 0xffd9d9d9, 0xffd9d9d9, 0xffdbdcdb, 0xffdbdcdb, 0xffdee0de, 0xffdee0de, 0xffdee0de, 0xffdee0de, + 0xffe1e1e1, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffe6e5e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe9e9e9, 0xffe9e9e9, 0xffececec, 0xffececec, 0xffefedec, 0xffefece9, 0xffefedec, 0xffefedec, + 0xffefedf1, 0xffefedf1, 0xffefedf1, 0xffeff0f4, 0xfff1f0f1, 0xfff1f0f1, 0xfff4f2f4, 0xfff4f2f4, + 0xfff1f2f1, 0xfff4f4f4, 0xfff1f2f1, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, + 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff2f1f1, + 0xfff0edee, 0xffeceae9, 0xffeae8e7, 0xffeae7ea, 0xffe8e6e8, 0xffeae9ea, 0xffe9e9e9, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe4e4e4, 0xffe4e4e4, 0xffe4e4e4, 0xffdedfde, + 0xffdedfde, 0xffdbdddb, 0xffdbdddb, 0xffd6d8db, 0xffd6d8db, 0xffd6d5d9, 0xffd6d2d6, 0xffd0d1d6, + 0xffcbccce, 0xffcbccce, 0xffc5c6c5, 0xffc5c6c5, 0xffc0c2c0, 0xffbabeba, 0xffbabeba, 0xffb5b5b5, + 0xffb5b5b5, 0xffadabad, 0xffadabad, 0xeea5a6a5, 0x773c3d3c, 0x00080808, 0x00080808, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x55000000, 0x77161616, 0x99424142, + 0x99424142, 0x99424142, 0x99424142, 0x99474847, 0x994a4d52, 0x99525458, 0x995a5a5d, 0x99636163, + 0x99656268, 0x99656268, 0x9968686e, 0x9968686e, 0x99736d6b, 0x9973706e, 0x99737370, 0x99737573, + 0x99737573, 0x99767776, 0x99797879, 0x997b797b, 0x997e7c7e, 0x997e7c7e, 0x99817f81, 0x99848284, + 0x99818381, 0x99818381, 0x99818381, 0x99848684, 0x99848686, 0x99848686, 0x99848686, 0x99848a89, + 0x99898889, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8b89, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x998c8f91, 0x998c8f91, 0x998c8f91, 0x998c9294, 0x99949294, 0x99949294, 0x99949294, 0x99949294, + 0x99949294, 0x99949294, 0x99949294, 0x99949294, 0x99919391, 0x99919391, 0x99919391, 0x99919391, + 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x99919391, + 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x99919391, 0x998f908f, + 0x99949294, 0x99949294, 0x99949294, 0x99949294, 0x998c928c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8b89, 0x998c8b89, 0x998c8b89, 0x998c8b89, + 0x998c8a8c, 0x998c8a8c, 0x99868786, 0x99868786, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99818381, 0x99818381, 0x997e807e, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99797b79, 0x99767876, + 0x99737476, 0x99737476, 0x99737173, 0x99737173, 0x996e6d6e, 0x99686968, 0x99686968, 0x99636563, + 0x99606065, 0x99606065, 0x995d5a60, 0x995a555a, 0x994a4c4a, 0x994a4c4a, 0x994a4c4a, 0x77292829, + 0x77080408, 0x77080408, 0x66080408, 0x11080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x996e6d6e, + 0xeea5a2a5, 0xffa5a2a5, 0xffa5a2a5, 0xffaaa9aa, 0xffadaead, 0xffb5b5b5, 0xffbdbcbd, 0xffc5c2c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc8cacb, 0xffcbced0, 0xffd6d1d0, 0xffd6d1d0, 0xffd6d4d3, 0xffd6d7d6, + 0xffd6d7d6, 0xffd9d9d9, 0xffdbdcdb, 0xffdbdcdb, 0xffdeddde, 0xffdeddde, 0xffdee0de, 0xffdee3de, + 0xffe4e4e4, 0xffe6e7e6, 0xffe4e4e4, 0xffe6e7e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6ebe6, + 0xffececec, 0xffececec, 0xffececec, 0xffececec, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffeff0f4, 0xffeff0f4, 0xffeff0f4, 0xffeff3f7, 0xfff7f3f7, 0xfff7f3f7, 0xfff7f3f7, 0xfff7f3f7, + 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff7f7f7, 0xfff4f4f4, 0xfff4f4f4, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff5f5f4, + 0xffefeeeb, 0xffebe8e8, 0xffe8e5e8, 0xffe7e4e8, 0xffe8e5e8, 0xffeae8ea, 0xffe9e9e9, 0xffe6e9e6, + 0xffe6e9e6, 0xffe6e7e6, 0xffe6e8e6, 0xffe6e7e6, 0xffe4e4e4, 0xffe4e4e4, 0xffe1e1e1, 0xffdedfde, + 0xffdedfde, 0xffdbdddb, 0xffd6dbd6, 0xffd6d8db, 0xffd6d5d9, 0xffd6d2d6, 0xffd6d2d6, 0xffcbccce, + 0xffcbccce, 0xffcbccce, 0xffc5c6c5, 0xffc0c2c0, 0xffc0c2c0, 0xffbabeba, 0xffb5bab5, 0xffb5b5b5, + 0xffb5b5b5, 0xffadabad, 0xeea5a2a5, 0x773c3d3c, 0x11080808, 0x00080808, 0x00080808, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22000000, 0x55000000, 0x77191419, + 0x882f2d2f, 0x99424142, 0x99424142, 0x99424142, 0x993c3b3c, 0x99525152, 0x99525152, 0x99525152, + 0x99636163, 0x99636163, 0x99636163, 0x99636163, 0x99636565, 0x996b7173, 0x996b7173, 0x996b7173, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, + 0x99868886, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998f8f8f, 0x998f8f8f, 0x998f8f8f, 0x998f8f8f, + 0x99949094, 0x99949094, 0x99949094, 0x999c969c, 0x99949694, 0x99949694, 0x99949694, 0x99949694, + 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, + 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, + 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x998f9091, + 0x99949294, 0x99949294, 0x99949294, 0x99949294, 0x998f8c8f, 0x99949294, 0x99949294, 0x99949294, + 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, + 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7973, 0x997b7973, 0x997b7973, 0x997b7973, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x99636563, 0x99636563, 0x99636563, 0x99636563, + 0x99525552, 0x99525552, 0x99525552, 0x99525552, 0x99525152, 0x88373637, 0x771b1b1b, 0x77000000, + 0x77000305, 0x66000000, 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x77686968, 0xdd9c9e9c, 0xff9c9e9c, 0xff9c9e9c, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, + 0xffb8b9b8, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd9dbde, 0xffdee3e6, 0xffdee3e6, 0xffdee3e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, + 0xffe9e9e9, 0xffefefef, 0xffefefef, 0xffefefef, 0xfff1f0ef, 0xfff1f0ef, 0xfff1f0ef, 0xfff1f0ef, + 0xfff1f3f1, 0xfff1f3f1, 0xfff1f3f1, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff6f6f6, + 0xffefefef, 0xffeaeae9, 0xffe6e7e7, 0xffe5e4e5, 0xffe5e3e6, 0xffece9ed, 0xffefebef, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffc8c9c8, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xff9c9e9c, + 0xff9c9e9c, 0xcc9c9e9c, 0x55343534, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22000000, 0x55000000, + 0x66080408, 0x771b181b, 0x99424142, 0x99424142, 0x993c3b3c, 0x993c3b3c, 0x99525152, 0x99525152, + 0x99555555, 0x99555555, 0x99636163, 0x99636163, 0x99636565, 0x99636565, 0x996b7173, 0x996b7173, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848384, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, + 0x998c8e8c, 0x99868886, 0x998c8e8c, 0x998c8e8c, 0x998f8f8f, 0x99949694, 0x998f8f8f, 0x998f8f8f, + 0x99949094, 0x99949094, 0x99949094, 0x99949094, 0x99949694, 0x99949694, 0x99949694, 0x99949694, + 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, + 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, + 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x998f9091, + 0x99949294, 0x99949294, 0x99949294, 0x99949294, 0x99949294, 0x99949294, 0x998f8c8f, 0x99949294, + 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x99868886, + 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x99848384, 0x99848684, 0x99848684, 0x997e7f7e, 0x997e7f7e, + 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x99767576, 0x997b7973, 0x997b7973, 0x9973706e, 0x9973706e, + 0x99737173, 0x99737173, 0x99656465, 0x99656465, 0x99636563, 0x99636563, 0x99636563, 0x99505150, + 0x99525552, 0x99525552, 0x99525552, 0x993a3b3a, 0x771b1b1b, 0x66000000, 0x77000000, 0x77000000, + 0x66000000, 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x33343534, 0x99686968, 0xee9c9e9c, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, + 0xffb8b9b8, 0xffb8b9b8, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c8c3, 0xffc5c8c3, 0xffced2ce, 0xffced2ce, + 0xffd0d1d0, 0xffd0d1d0, 0xffd6dbd6, 0xffd6dbd6, 0xffd9dbde, 0xffd9dbde, 0xffdee3e6, 0xffdee3e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e5e6, 0xffefebef, 0xffefebef, 0xffefebef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xfff1f0ef, 0xfff7f7f7, 0xfff1f0ef, 0xfff1f0ef, + 0xfff1f3f1, 0xfff1f3f1, 0xfff1f3f1, 0xfff1f3f1, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff6f7f6, + 0xfff2f1f1, 0xffebeaea, 0xffe4e5e5, 0xffe3e1e4, 0xffe6e4e7, 0xffedeaed, 0xffefebef, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffced0ce, 0xffd6d7d6, 0xffc8c9c8, 0xffc8c9c8, 0xffc8c9c8, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffb8b7b8, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xdd9c9e9c, + 0x88686968, 0x33343534, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, + 0x44080408, 0x66080408, 0x66080408, 0x771b181b, 0x993c3b3c, 0x993c3b3c, 0x993c3b3c, 0x993c3b3c, + 0x99474947, 0x99555555, 0x99555555, 0x99555555, 0x995a5958, 0x99636565, 0x99636565, 0x99636565, + 0x99686868, 0x996e6f6e, 0x996e6f6e, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x997e7f7e, 0x99848384, 0x99848384, 0x99848384, 0x99848384, + 0x99868886, 0x99868886, 0x99868886, 0x99868886, 0x998f8f8f, 0x99898889, 0x998f8f8f, 0x998f8f8f, + 0x99949094, 0x998c8b8c, 0x99949094, 0x99949094, 0x998f908f, 0x99949694, 0x998f908f, 0x99949694, + 0x998f908f, 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99919291, 0x99919291, 0x99919291, + 0x99949694, 0x99949694, 0x99949694, 0x99949694, 0x99919291, 0x99919291, 0x99919291, 0x99919291, + 0x99949694, 0x9991908f, 0x9991908f, 0x9991908f, 0x998f9091, 0x998f9091, 0x998f9091, 0x998f9091, + 0x998f8e8f, 0x998f8e8f, 0x998f8e8f, 0x99949294, 0x99949294, 0x998f8c8f, 0x998f8c8f, 0x998f8c8f, + 0x998c8e8c, 0x998c8e8c, 0x998c8e8c, 0x99868886, 0x99868886, 0x99868886, 0x99868886, 0x99818381, + 0x99848384, 0x99848384, 0x99848384, 0x99848384, 0x997e7f7e, 0x997e7f7e, 0x99797879, 0x99797879, + 0x99767576, 0x99767576, 0x99767576, 0x99767576, 0x9973706e, 0x9973706e, 0x996b6768, 0x996b6768, + 0x99656465, 0x99656465, 0x99656465, 0x99585658, 0x99505150, 0x99505150, 0x99505150, 0x99505150, + 0x993a3b3a, 0x993a3b3a, 0x77212221, 0x66080808, 0x77000000, 0x77000000, 0x77000000, 0x44000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x44343534, 0xaa7b797b, 0xeeadaaad, 0xffadaaad, 0xffadaaad, + 0xffaaabaa, 0xffaaabaa, 0xffb8b9b8, 0xffb8b9b8, 0xffbdbdb8, 0xffc5c8c3, 0xffc5c8c3, 0xffc5c8c3, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd3d2d6, 0xffd9dbde, 0xffd9dbde, 0xffd9dbde, + 0xffe1e0e1, 0xffe1e0e1, 0xffe1e0e1, 0xffe6e7e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, 0xffe6e5e6, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xfff1f0ef, 0xfff1f0ef, 0xfff1f0ef, 0xfff1f0ef, + 0xfff1f3f1, 0xffecefec, 0xfff1f3f1, 0xfff1f3f1, 0xfff1f3f1, 0xfff7f7f7, 0xfff1f3f1, 0xfff7f7f7, + 0xfff4f3f4, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff4f3f4, 0xfff7f7f7, 0xfff4f3f4, + 0xfff5f5f4, 0xffeeedec, 0xffe4e4e5, 0xffe1e1e2, 0xffe3e1e3, 0xffe5e4e6, 0xffe6e4e6, 0xffe1dfde, + 0xffe1dfde, 0xffe1dfde, 0xffe1dfde, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffced0ce, + 0xffced0ce, 0xffced0ce, 0xffc5c5c5, 0xffc8c9c8, 0xffc8c9c8, 0xffbabcba, 0xffbabcba, 0xffb8b7b8, + 0xffb8b7b8, 0xffb8b7b8, 0xffaaa9aa, 0xffb5b2b5, 0xeeb5b2b5, 0xdd7b7b7e, 0x997b7b7e, 0x33343534, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x22080408, 0x55080408, 0x66080408, 0x66101010, 0x77101010, 0x88262626, 0x883c3b3c, + 0x993a3d3a, 0x993a3d3a, 0x99474947, 0x99474947, 0x99524d4a, 0x99524d4a, 0x995a5958, 0x995a5958, + 0x99636163, 0x99636163, 0x99636163, 0x99686868, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, 0x996b6d6b, + 0x99737173, 0x99737173, 0x99797879, 0x99797879, 0x99737573, 0x997b7c7b, 0x997b7c7b, 0x997b7c7b, + 0x997b7d7b, 0x997b7d7b, 0x99818381, 0x99818381, 0x99848284, 0x99848284, 0x99848284, 0x99848284, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99848684, + 0x99898b89, 0x99848684, 0x99898b89, 0x99898b89, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, + 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, 0x998c8a8c, + 0x998c8684, 0x998c8684, 0x998c8684, 0x998c8684, 0x9984868c, 0x9984868c, 0x9984868c, 0x9984868c, + 0x99848684, 0x99848684, 0x99848684, 0x99848684, 0x99898789, 0x99848284, 0x99848284, 0x99848284, + 0x99818381, 0x997b7d7b, 0x99818381, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, 0x997b7d7b, + 0x997b7c7b, 0x997b7c7b, 0x99737573, 0x99737573, 0x99737173, 0x99737173, 0x99737173, 0x99737173, + 0x99706d70, 0x99706d70, 0x996b656b, 0x996b656b, 0x99635d63, 0x99635d63, 0x99635d63, 0x99635d63, + 0x99585658, 0x99585658, 0x994a494a, 0x994a494a, 0x993c3d3c, 0x993c3d3c, 0x993c3d3c, 0x88292829, + 0x77080808, 0x66080808, 0x77080808, 0x77080808, 0x77000000, 0x55000000, 0x22000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11191819, 0x33191819, 0x664a494a, 0xbb7b797b, + 0xdd9c9e9c, 0xee9c9e9c, 0xffaaabaa, 0xffaaabaa, 0xffb5b2ad, 0xffb5b2ad, 0xffb5b2ad, 0xffbdbdb8, + 0xffc5bec5, 0xffc5bec5, 0xffcbc8cb, 0xffcbc8cb, 0xffcecace, 0xffcecace, 0xffcecace, 0xffd3d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffdbd9db, 0xffdbd9db, 0xffd6dbd6, 0xffd6dbd6, 0xffdee0de, 0xffdee0de, + 0xffdedfde, 0xffdedfde, 0xffe4e4e4, 0xffe4e4e4, 0xffe6e3de, 0xffe6e3de, 0xffece9e6, 0xffece9e6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, + 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, + 0xffefebe6, 0xffeeeae5, 0xffdedfde, 0xffddddde, 0xffdeddde, 0xffd6d7d6, 0xffd6d7d6, 0xffdbd7d6, + 0xffdbd7d6, 0xffdbd7d6, 0xffd6cece, 0xffcecece, 0xffcecece, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c5c5, + 0xffc5c5c5, 0xffc5c5c5, 0xffbdbabd, 0xffbabcba, 0xffadaead, 0xffadaead, 0xffadaead, 0xffaaa9aa, + 0xffaaa9aa, 0xee9c9a9c, 0xdd9c9a9c, 0xaa7b7b7e, 0x55424347, 0x22080c10, 0x11080c10, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x22000000, 0x44000000, 0x55030103, 0x66050305, 0x66080408, + 0x66131213, 0x77131213, 0x88262326, 0x883a353a, 0x88313131, 0x99313131, 0x994a494a, 0x994a494a, + 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, + 0x99636563, 0x99636563, 0x99636563, 0x99636563, 0x996b6d73, 0x996b6d73, 0x996b6d73, 0x996b6d73, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x997b757b, 0x997b757b, 0x997b757b, 0x997b757b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, 0x997b797b, + 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, 0x99737573, + 0x996b716b, 0x996b716b, 0x996b716b, 0x996b716b, 0x996b696b, 0x996b696b, 0x996b696b, 0x996b696b, + 0x99636563, 0x99636563, 0x99636563, 0x99636563, 0x995a595a, 0x995a595a, 0x995a595a, 0x995a595a, + 0x99525152, 0x99525152, 0x99525152, 0x99525152, 0x994a494a, 0x994a494a, 0x994a494a, 0x994a494a, + 0x99313531, 0x99313531, 0x88313531, 0x88212321, 0x77191419, 0x77100d10, 0x66080708, 0x66000000, + 0x77000000, 0x77000000, 0x66000000, 0x55000000, 0x22000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00030403, 0x11080c08, + 0x22000400, 0x442f312f, 0x885d5d5d, 0xbb8c8a8c, 0xdd9c9a9c, 0xdd9c9a9c, 0xee9c9a9c, 0xff9c9a9c, + 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcececd, 0xffcccdce, 0xffcccdcc, + 0xffcbc9cc, 0xffc9c8c9, 0xffc7c4c7, 0xffc2c1c3, 0xffbebdbf, 0xffb6babd, 0xffb5babd, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a2a5, + 0xffa5a2a5, 0xffa5a2a5, 0xffa5a2a5, 0xee9c9a9c, 0xee9c9a9c, 0xdd9c9a9c, 0xdd9c9a9c, 0xbb7b797b, + 0x77525252, 0x44292b29, 0x22000400, 0x11080c08, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x33000000, 0x44000000, + 0x55000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66191819, 0x77191819, 0x77191819, + 0x88313331, 0x88313331, 0x88313331, 0x88313331, 0x993f3d3f, 0x993f3d3f, 0x993f3d3f, 0x993f3d3f, + 0x99424342, 0x99424342, 0x99424342, 0x99424342, 0x99474a4d, 0x99474a4d, 0x99474a4d, 0x99474a4d, + 0x99504d50, 0x99504d50, 0x99504d50, 0x99504d50, 0x99555155, 0x99555155, 0x99555155, 0x99555155, + 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, + 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, + 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, + 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, 0x99555455, + 0x99505150, 0x99505150, 0x99505150, 0x99505150, 0x99505150, 0x99505150, 0x99505150, 0x99505150, + 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x994a4d4a, 0x99474847, 0x99474847, 0x99474847, 0x99474847, + 0x99424342, 0x99424342, 0x99424342, 0x99424342, 0x993c3b3c, 0x993c3b3c, 0x993c3b3c, 0x993c3b3c, + 0x99373737, 0x99373737, 0x88373737, 0x88373737, 0x88313131, 0x88313131, 0x77191819, 0x77191819, + 0x77101210, 0x66000000, 0x66000000, 0x66000000, 0x77000000, 0x77000000, 0x66000000, 0x55000000, + 0x44000000, 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x11000400, 0x11000400, 0x22000400, 0x44343634, 0x77686868, + 0x99797b79, 0xbb797b79, 0xcc797b79, 0xcc797b79, 0xddadaead, 0xeeadaead, 0xeeadaead, 0xeeadaead, + 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcccbcb, 0xffc8c8c9, 0xffc6c5c6, + 0xffb3b2b4, 0xffadadaf, 0xffb0b0b3, 0xffafb1b4, 0xffb1b5b9, 0xffb4b9bc, 0xffb5babd, 0xffadaead, + 0xffadaead, 0xffadaead, 0xeeadaead, 0xeea5a6a5, 0xeea5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xcca5a2a5, + 0xcca5a2a5, 0xbb6e6d6e, 0x886e6d6e, 0x66343334, 0x55343334, 0x22343334, 0x11000000, 0x11000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x22000000, 0x33000000, 0x44000000, 0x55000000, 0x55000000, 0x55000000, 0x66000000, + 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66080408, 0x66080408, 0x77080408, 0x77242024, + 0x77212221, 0x77212221, 0x77212221, 0x88212221, 0x88242726, 0x88242726, 0x88242726, 0x88242726, + 0x882c282c, 0x882c282c, 0x882c282c, 0x882c282c, 0x882f2d2f, 0x882f2d2f, 0x882f2d2f, 0x992f2d2f, + 0x882f2e2f, 0x882f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, + 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, + 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, + 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, 0x992f2e2f, + 0x992c2d2c, 0x992c2d2c, 0x992c2d2c, 0x992c2d2c, 0x992c2d2c, 0x882c2d2c, 0x882c2d2c, 0x882c2d2c, + 0x88292829, 0x88292829, 0x88292829, 0x88292829, 0x88242624, 0x88242624, 0x88242624, 0x88242624, + 0x88212221, 0x88212221, 0x88212221, 0x88212221, 0x771e1e1e, 0x771e1e1e, 0x771e1e1e, 0x771e1e1e, + 0x77000400, 0x66000400, 0x66000400, 0x66000400, 0x66000000, 0x66000000, 0x77000000, 0x77000000, + 0x77000000, 0x66000000, 0x66000000, 0x55000000, 0x44000000, 0x33000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x22000400, 0x443a3d3a, 0x443a3d3a, 0x663a3d3a, + 0x663c3f3c, 0x773c3f3c, 0x88797b79, 0xaa797b79, 0xbb7e7f7e, 0xbb7e7f7e, 0xbb7e7f7e, 0xbb7e7f7e, + 0xcc848684, 0xcc848684, 0xcc848684, 0xcc848684, 0xcc898889, 0xdd898889, 0xdd898889, 0xdd898889, + 0xdd8c8b8c, 0xdd8c8b8c, 0xdd8c8b8c, 0xdd8c8b8c, 0xdd8c8b8c, 0xdd8c8b8c, 0xee8c8b8c, 0xee8c8b8c, + 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, + 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8c8b8c, 0xee8b8b8b, 0xee898989, + 0xee878588, 0xee848285, 0xcc7e7d80, 0xbb7b7c7f, 0xbb797c7e, 0xbb797c7e, 0xaa797c7e, 0xaa737473, + 0x88737473, 0x77737473, 0x663a3a3a, 0x55373a37, 0x44373a37, 0x33373a37, 0x22000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x22000000, + 0x33000000, 0x44000000, 0x44000000, 0x55000000, 0x55080408, 0x55080408, 0x66080408, 0x66080408, + 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000400, 0x66000400, 0x66000400, 0x66000400, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66000400, 0x66000400, 0x66000400, 0x66000400, + 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, + 0x66000400, 0x66000400, 0x66000400, 0x55000400, 0x55000000, 0x44000000, 0x44000000, 0x33000000, + 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, + 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, + 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080408, 0x00080407, + 0x00080408, 0x00060308, 0x00000400, 0x00010100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x22000000, 0x22000000, 0x22000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x44000000, + 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, + 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, + 0x44000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x22000000, 0x22000000, + 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00030403, 0x00030403, + 0x00050505, 0x00050505, 0x00050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00030403, 0x00030403, 0x00030403, + 0x00030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x22000000, 0x22000000, 0x22000000, 0x33000000, 0x33000000, + 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, + 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x22000000, 0x22000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00030403, 0x00050805, 0x11080c08, + 0x22101010, 0x22101010, 0x11101010, 0x11050505, 0x00000400, 0x00000100, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050805, 0x11050805, 0x11080c08, 0x11080c08, + 0x11080808, 0x00030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, + 0x22000000, 0x22000000, 0x22000000, 0x33000000, 0x22000000, 0x22000000, 0x22000000, 0x11000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x55050705, 0xaa101410, 0xcc191819, 0xcc191819, 0xcc191819, 0xcc191819, + 0xcc191c19, 0xcc191c19, 0xcc191c19, 0xcc191c19, 0xcc191c19, 0xcc191c19, 0xcc191c19, 0xcc191c19, + 0xcc191c19, 0xcc191c19, 0xcc191c19, 0xcc191c19, 0xcc191819, 0xcc191819, 0xcc191819, 0xbb191819, + 0x66080808, 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x44050405, 0x66100c10, + 0x99101010, 0xbb191819, 0xcc191819, 0xdd191819, 0xcc191819, 0xbb191819, 0x99101010, 0x77101010, + 0x44080408, 0x22030103, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11080808, 0x55080808, 0xbb4a494a, 0xdd8c8a8c, 0xeea5a6a5, 0xeea5a6a5, 0xeea5a6a5, 0xeea5a6a5, + 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, + 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, 0xeeadaaad, 0xeea5a6a5, 0xeea5a6a5, 0xeea5a6a5, 0xee8c8e8c, + 0xbb3c3b3c, 0x77080808, 0x22080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x00080408, 0x00080408, 0x11080408, 0x33080408, 0x88080408, 0xcc4a464a, 0xee4a464a, + 0xee8c8a8c, 0xffa7a6a7, 0xffa7a6a7, 0xffa7a6a7, 0xffafb3af, 0xff898c89, 0xee898c89, 0xee636563, + 0xcc4a494a, 0x88080408, 0x44080408, 0x22080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x22080808, 0xaa080808, 0xdd8c8a8c, 0xffcecace, 0xffcbcccb, 0xffcbcccb, 0xffcbcccb, 0xffcbcccb, + 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, + 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, 0xffd3d0d3, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffbdbebd, + 0xeea5a2a5, 0xbb080808, 0x33080808, 0x00080808, 0x00000000, 0x110e0d0e, 0x110e0d0e, 0x331b1b1b, + 0x44212021, 0x55212021, 0x44212021, 0x22101010, 0x11100f10, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x110b0b0b, 0x110e0f0e, 0x330e0f0e, 0x441b1e1b, 0x330e0f0e, + 0x220b0b0b, 0x110b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x00080408, 0x11080408, 0x55080408, 0xaa4a464a, 0xee8c888c, 0xff8c888c, 0xffcecace, + 0xffc3c2c3, 0xffc3c2c3, 0xffc3c2c3, 0xffdedfde, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffafb3af, + 0xff8c8e8c, 0xee8c8e8c, 0xbb4a494a, 0x66080408, 0x22000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x22080808, 0xcc080808, 0xee8c8a8c, 0xffcecace, 0xffcbcccb, 0xffcbcccb, 0xffdedfde, 0xffdedfde, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffa5a2a5, 0xdd080808, 0x44080808, 0x00080808, 0x00000000, 0x110e0d0e, 0x331b1b1b, 0x551b1b1b, + 0x77212021, 0x88212021, 0x88212021, 0x55212021, 0x33211e21, 0x11100f10, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x110b0b0b, 0x22161616, 0x441b1e1b, 0x661b1e1b, 0x661b1e1b, 0x551b1e1b, + 0x44161616, 0x220b0b0b, 0x000b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x11080408, 0x66080408, 0xcc3c3b3c, 0xee8c888c, 0xffcecace, 0xffcecace, 0xffcecace, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffced2ce, 0xffced2ce, 0xee8c8e8c, 0xcc4a494a, 0x771b1a1b, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x22080808, 0xcc080808, 0xee8c8a8c, 0xffcecace, 0xffcbcccb, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffa5a2a5, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x220e0d0e, 0x551b1b1b, 0x77292829, + 0x99313131, 0xaa313131, 0xbb313131, 0xaa313131, 0x77312d31, 0x33211e21, 0x11100f10, 0x11000000, + 0x00000000, 0x110b0b0b, 0x22161616, 0x44212021, 0x88292d29, 0x99292d29, 0x99292d29, 0x77292d29, + 0x66212021, 0x33161616, 0x110b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11080408, 0x55080408, 0xcc3c3b3c, 0xffa5aaa5, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xff8c8e8c, 0xcc524d52, 0x771b1a1b, 0x22000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9a9a9a, 0xffdedfde, 0xffd6d7d6, 0xffdedfde, 0xffdedfde, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffecedec, 0xffecedec, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, 0xffe4e5e4, 0xffe4e5e4, 0xffdedfde, 0xffdedfde, + 0xffb5b2b5, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x220e0d0e, 0x551b1b1b, 0x88292829, + 0xaa292d29, 0xbb292d29, 0xcc292d29, 0xcc212321, 0xbb2c2e2c, 0x882c2e2c, 0x442c2e2c, 0x22101010, + 0x11191419, 0x22191419, 0x44292629, 0x99292629, 0xbb292729, 0xbb313131, 0xaa313131, 0x99313131, + 0x77212421, 0x44161816, 0x110b0c0b, 0x00000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x33080808, 0xbb4a4a4a, 0xee8c8c8c, 0xffcecece, 0xffd6d7d6, 0xffd6d7d6, 0xffdeddde, 0xffdeddde, + 0xffdee3de, 0xffe6e9e6, 0xffe6e9e6, 0xffe6e9e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, + 0xffe6e7e6, 0xffdedbde, 0xffdedbde, 0xffd6ced6, 0xee8c8e8c, 0xbb4a494a, 0x55080408, 0x11080408, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080808, 0x00080808, 0x00080808, 0x00080808, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9a9a9a, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffe6e7e6, 0xffe6e7e6, + 0xffecedec, 0xffecedec, 0xfff1f4f1, 0xfff1f4f1, 0xfff1f3f1, 0xfff1f3f1, 0xfff1f3f1, 0xfff1f3f1, + 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xffe9ece9, 0xffe9ece9, 0xffe4e5e4, 0xffdedfde, + 0xffb5b2b5, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x110e0d0e, 0x441b1b1b, 0x88292829, + 0xbb292d29, 0xcc212321, 0xcc212321, 0xdd191a19, 0xdd1e1f1e, 0xcc1e1f1e, 0x992c2e2c, 0x552c2e2c, + 0x33292629, 0x553a373a, 0x993a373a, 0xcc292629, 0xcc211e21, 0xcc292729, 0xbb292729, 0xbb292729, + 0x88212421, 0x33161816, 0x110b0c0b, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x11000000, + 0x88080808, 0xee8c8c8c, 0xffcecece, 0xffcecece, 0xffd6d7d6, 0xffdeddde, 0xffe6e4e6, 0xffe6e4e6, + 0xffe6e9e6, 0xffe6e9e6, 0xffeff0ef, 0xffeff0ef, 0xfff1f2f1, 0xffececec, 0xffececec, 0xffececec, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffdedbde, 0xffced2ce, 0xee8c8e8c, 0x99080408, 0x33080408, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x110e0c0e, 0x11131413, 0x22131413, 0x22131413, 0x22131413, + 0x110e120e, 0x110e120e, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9a9a9a, 0xffdedfde, 0xffdedfde, 0xffe6e7e6, 0xffe6e7e6, 0xffefefef, + 0xfff1f4f1, 0xfff1f4f1, 0xfff1f4f1, 0xfff1f4f1, 0xfff4f7f4, 0xfff4f7f4, 0xfff4f7f4, 0xfff4f7f4, + 0xfff4f6f4, 0xfff4f6f4, 0xfff4f6f4, 0xfff4f6f4, 0xffeff3ef, 0xffe9ece9, 0xffe9ece9, 0xffe4e5e4, + 0xffb5b2b5, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x000e0d0e, 0x221b1b1b, 0x55292829, + 0xaa292d29, 0xcc212321, 0xdd191a19, 0xdd191a19, 0xee101010, 0xdd101010, 0xdd1e1f1e, 0xaa3a3d3a, + 0x774a494a, 0x993a373a, 0xcc292629, 0xdd191419, 0xdd211e21, 0xdd211e21, 0xcc292729, 0xaa292729, + 0x66212421, 0x33161816, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x44050405, + 0xcc4a4a4a, 0xff8c8c8c, 0xffcecece, 0xffcecece, 0xffdeddde, 0xffe6e4e6, 0xffe6e4e6, 0xffefebef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f1, + 0xffeff3ef, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffced2ce, 0xff8c8e8c, 0xcc4a494a, 0x55080408, + 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x110e0c0e, 0x221b181b, 0x441e201e, 0x661e201e, 0x66292d29, 0x66292d29, + 0x551b1f1b, 0x331b1f1b, 0x110e120e, 0x11000400, 0x00030303, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9a9a9a, 0xffdedfde, 0xffdedfde, 0xffe6e7e6, 0xffefefef, 0xffefefef, + 0xfff1f4f1, 0xfff1f4f1, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, + 0xfff7fbf7, 0xfff7fbf7, 0xfff4f6f4, 0xfff4f6f4, 0xffeff3ef, 0xffeff3ef, 0xffe9ece9, 0xffe4e5e4, + 0xffb5b2b5, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x110e0d0e, 0x221b1b1b, + 0x66292d29, 0xbb292d29, 0xdd191a19, 0xee101010, 0xee101010, 0xee101010, 0xee101010, 0xdd1e1f1e, + 0xbb292629, 0xdd292629, 0xee191419, 0xee191419, 0xdd191419, 0xdd191419, 0xcc292729, 0x88313131, + 0x44212421, 0x330b0c0b, 0x22000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x66100c10, + 0xee4a4a4a, 0xffcecece, 0xffcecece, 0xffcecece, 0xffe6e4e6, 0xffe6e4e6, 0xffefebef, 0xffefebef, + 0xffeff0ef, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xffeff3ef, 0xffeff3ef, 0xffe6e7e6, 0xffe6e7e6, 0xffced2ce, 0xffced2ce, 0xee4a494a, 0x88080408, + 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x110e0c0e, 0x331b181b, 0x66292429, 0x88292d29, 0xaa292d29, 0xaa292d29, 0xaa292d29, + 0x99292d29, 0x77292d29, 0x551b1f1b, 0x220e120e, 0x11080808, 0x00030303, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffe6e3e6, 0xffece9ec, 0xfff1f0f1, 0xfff1f0f1, + 0xfff7f7f7, 0xfffafafa, 0xfffcfcfc, 0xfffcfcfc, 0xfffffcff, 0xfffffcff, 0xfffffcff, 0xfffffcff, + 0xfffffcff, 0xfffffcff, 0xfffffbff, 0xfffffbff, 0xfff1f4f1, 0xfff1f4f1, 0xffecedec, 0xffe6e7e6, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00050405, 0x11100c10, + 0x33212321, 0x77313531, 0xbb313531, 0xee101210, 0xee080808, 0xee080808, 0xee080808, 0xee080808, + 0xee100c10, 0xee100c10, 0xee100c10, 0xee100c10, 0xee101010, 0xdd212021, 0xaa313131, 0x55313131, + 0x33101010, 0x33050505, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x11000000, 0x99101310, + 0xee8c8e8c, 0xffc3c4c3, 0xffdedfde, 0xffdedfde, 0xffe6e7e6, 0xffecedec, 0xffecedec, 0xfff1f4f1, + 0xfff7f7f7, 0xfff7f7f7, 0xfffafafa, 0xfffafafa, 0xfffafafa, 0xfffafafa, 0xfffafafa, 0xfff7f7f7, + 0xfffaf6fa, 0xfff4f0f4, 0xfff4f0f4, 0xffefebef, 0xffe6e7e6, 0xffe6e7e6, 0xeea2a3a2, 0xaa191c19, + 0x33000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00030303, + 0x11080808, 0x221e201e, 0x66292d29, 0xaa292d29, 0xbb292d29, 0xcc262726, 0xcc262726, 0xcc262726, + 0xcc262726, 0xbb292d29, 0x88262726, 0x55242224, 0x220b0c0b, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffe6e3e6, 0xffece9ec, 0xfff1f0f1, 0xfff7f7f7, + 0xfff7f7f7, 0xfffcfcfc, 0xfffcfcfc, 0xffffffff, 0xfffffeff, 0xfffffeff, 0xfffffeff, 0xfffffeff, + 0xfffffeff, 0xfffffeff, 0xfffffeff, 0xfffffbff, 0xfff7fbf7, 0xfff1f4f1, 0xfff1f4f1, 0xffe6e7e6, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x11050405, + 0x11101210, 0x33212321, 0x77313531, 0xcc313531, 0xee080808, 0xee080808, 0xff080808, 0xff080808, + 0xff050705, 0xee050705, 0xee0b090b, 0xee100c10, 0xee101010, 0xbb313131, 0x77313131, 0x44212021, + 0x33050505, 0x33000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x22000000, 0xbb191c19, + 0xffa7a9a7, 0xffc3c4c3, 0xffdedfde, 0xffdedfde, 0xffe6e7e6, 0xffecedec, 0xfff1f4f1, 0xfff1f4f1, + 0xfffafafa, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffffbff, 0xfffaf6fa, 0xfff4f0f4, 0xfff4f0f4, 0xffe6e7e6, 0xffe6e7e6, 0xffa2a3a2, 0xcc191c19, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050505, + 0x11131413, 0x551e201e, 0x99292d29, 0xbb292d29, 0xcc242224, 0xcc242224, 0xdd242224, 0xdd242224, + 0xdd242224, 0xcc262726, 0xbb292d29, 0x88262726, 0x33161816, 0x110b0c0b, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffe6e3e6, 0xffece9ec, 0xfff1f0f1, 0xfff7f7f7, + 0xfffafafa, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffeff, 0xfffffcff, 0xfff7fbf7, 0xfff1f4f1, 0xfff1f4f1, 0xffe6e7e6, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x22101210, 0x44212321, 0x88313531, 0xcc2f332f, 0xee080808, 0xff080808, 0xff080808, + 0xff050705, 0xff050705, 0xee0b090b, 0xee100c10, 0xcc212021, 0x99424142, 0x66212021, 0x44101010, + 0x33000000, 0x33000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x22000000, 0xcc191c19, + 0xffa7a9a7, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffecedec, 0xfff1f4f1, 0xfff1f4f1, 0xfff7fbf7, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcfcfc, 0xfffcfcfc, + 0xfffffbff, 0xfffaf6fa, 0xfffaf6fa, 0xfff4f0f4, 0xffe6e7e6, 0xffe6e7e6, 0xffa2a3a2, 0xdd191c19, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080808, + 0x22131413, 0x66292d29, 0xaa292d29, 0xcc1e201e, 0xdd242224, 0xdd242224, 0xdd242224, 0xdd211c21, + 0xdd211c21, 0xcc242224, 0xbb292d29, 0x99292d29, 0x55212421, 0x220b0c0b, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffece9ec, 0xfff1f0f1, 0xfff1f0f1, 0xfff7f7f7, + 0xfffafafa, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffeff, 0xfffffcff, 0xfff7fbf7, 0xfff1f4f1, 0xfff1f4f1, 0xffecedec, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x22101210, 0x55313531, 0x99424942, 0xdd1b1e1b, 0xff080808, 0xff080808, + 0xff000400, 0xff050705, 0xff050705, 0xee100c10, 0xcc313131, 0x99424142, 0x66212021, 0x44101010, + 0x33050505, 0x33000000, 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x33000000, 0xdd191c19, + 0xffa7a9a7, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffecedec, 0xfff1f4f1, 0xfff1f4f1, 0xfff7fbf7, + 0xfffcfcfc, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcfcfc, + 0xfffffbff, 0xfffffbff, 0xfffaf6fa, 0xfff4f0f4, 0xffe6e7e6, 0xffe6e7e6, 0xffa2a3a2, 0xdd191c19, + 0x55000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080808, + 0x33131413, 0x77292d29, 0xbb292d29, 0xcc1e201e, 0xdd211c21, 0xdd242224, 0xdd242224, 0xdd242224, + 0xdd211c21, 0xdd242224, 0xcc292d29, 0xaa292d29, 0x66212421, 0x330b0c0b, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xeea5a2a5, 0xffefebef, 0xffe6e7e6, 0xffececec, 0xfff1f2f1, 0xfff7f7f7, + 0xfff7fbf7, 0xfffafcfa, 0xfffcfefc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffeff, 0xfffffcff, 0xfff7fbf7, 0xfff4f6f4, 0xfff1f0f1, 0xffefebef, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x11080408, 0x22191619, 0x553a393a, 0xaa424542, 0xee1b1c1b, 0xff080808, 0xff080808, + 0xff000400, 0xff000400, 0xff000400, 0xee0e100e, 0xee1e1e1e, 0xbb3a393a, 0x882c2b2c, 0x551e1e1e, + 0x440e0d0e, 0x33000000, 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x22000000, 0xcc191c19, + 0xffb8bab8, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffefefef, 0xfff1f3f1, 0xfff4f7f4, 0xfff7fbf7, + 0xfffffcff, 0xfffffeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xfffcfbfc, 0xfffcfbfc, 0xfffaf7fa, 0xfff7f3f7, 0xffe6e7e6, 0xffe6e7e6, 0xffa2a2a2, 0xdd191819, + 0x55000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080808, + 0x22131713, 0x77292d29, 0xbb292d29, 0xcc1e221e, 0xdd242224, 0xdd242224, 0xdd211c21, 0xdd211c21, + 0xdd191c19, 0xdd1e221e, 0xcc292d29, 0xaa292d29, 0x66292429, 0x330e0c0e, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xeea5a2a5, 0xffefebef, 0xffe6e7e6, 0xffececec, 0xfff1f2f1, 0xfff7f7f7, + 0xfff7fbf7, 0xfffafcfa, 0xfffcfefc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffeff, 0xfffffcff, 0xfff7fbf7, 0xfff4f6f4, 0xfff1f0f1, 0xffefebef, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0x11080408, 0x33292729, 0x773a393a, 0xdd1b1c1b, 0xee080808, 0xff080808, 0xff080808, + 0xff000400, 0xff000400, 0xff000400, 0xee0e100e, 0xee101010, 0xdd1e1e1e, 0xbb3a393a, 0x772c2b2c, + 0x441b1b1b, 0x330e0d0e, 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x22000000, 0xbb191c19, + 0xff919291, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffefefef, 0xfff1f3f1, 0xfff4f7f4, 0xfff7fbf7, + 0xfffffeff, 0xfffffeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xfffcfbfc, 0xfffcfbfc, 0xfffaf7fa, 0xfff7f3f7, 0xffe6e7e6, 0xffe6e7e6, 0xffa2a2a2, 0xcc191819, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050505, + 0x22131713, 0x661e221e, 0xaa292d29, 0xcc292d29, 0xdd242224, 0xdd242224, 0xdd211c21, 0xdd211c21, + 0xdd1e221e, 0xdd242724, 0xcc292d29, 0x99242724, 0x551b181b, 0x330e0c0e, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xeea5a2a5, 0xffefebef, 0xffe6e7e6, 0xffececec, 0xfff1f2f1, 0xfff7f7f7, + 0xfff7fbf7, 0xfffafcfa, 0xfffcfefc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffeff, 0xfffffcff, 0xfff7fbf7, 0xfff4f6f4, 0xfff1f0f1, 0xffefebef, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x00030103, + 0x11080408, 0x22191619, 0x663a393a, 0xcc292729, 0xee080808, 0xff080808, 0xff080808, 0xff080808, + 0xee0e100e, 0xee0e100e, 0xee0e100e, 0xee0e100e, 0xee101010, 0xee101010, 0xdd1e1e1e, 0xaa2c2b2c, + 0x66292829, 0x330e0d0e, 0x220e0d0e, 0x11000000, 0x11000000, 0x00000000, 0x22000000, 0x99101310, + 0xee919291, 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffefefef, 0xfff1f3f1, 0xfff4f7f4, 0xfff7fbf7, + 0xfffffcff, 0xfffffeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xfffcfbfc, 0xfffcfbfc, 0xfffaf7fa, 0xfff7f3f7, 0xffe6e7e6, 0xffe6e7e6, 0xeea2a2a2, 0xaa191819, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00030303, + 0x11080c08, 0x441e221e, 0x88292d29, 0xbb292d29, 0xcc262726, 0xdd242224, 0xdd242224, 0xdd242224, + 0xdd1e221e, 0xcc292d29, 0xbb292d29, 0x88242724, 0x441b181b, 0x330e0c0e, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xeea5a2a5, 0xffefebef, 0xffe6e7e6, 0xffececec, 0xfff1f2f1, 0xfff7f7f7, + 0xfff7fbf7, 0xfffafcfa, 0xfffcfefc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffeff, 0xfffffcff, 0xfff7fbf7, 0xfff4f6f4, 0xfff1f0f1, 0xffefebef, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00030103, 0x00080408, + 0x11191619, 0x44292729, 0xaa3a393a, 0xdd191619, 0xee080808, 0xee080808, 0xee080808, 0xee080808, + 0xdd1b1c1b, 0xdd292829, 0xee0e100e, 0xee0e100e, 0xee101010, 0xee1e1e1e, 0xdd1e1e1e, 0xcc2c2b2c, + 0x99292829, 0x55292829, 0x220e0d0e, 0x11000000, 0x11080908, 0x11000000, 0x11000000, 0x77080908, + 0xee6b696b, 0xffb8bab8, 0xffdee3de, 0xffdee3de, 0xffefefef, 0xfff1f3f1, 0xfff4f7f4, 0xfff7fbf7, + 0xfffffcff, 0xfffffeff, 0xfffffeff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xfffcfbfc, 0xfffaf7fa, 0xfffaf7fa, 0xfff7f3f7, 0xffe6e7e6, 0xffe6e7e6, 0xee5d5d5d, 0x88191819, + 0x33000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11080c08, 0x22131713, 0x661e221e, 0x99292d29, 0xbb292d29, 0xcc292d29, 0xcc262726, 0xcc292d29, + 0xcc292d29, 0xbb292d29, 0x99242724, 0x66191c19, 0x330e0c0e, 0x22000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffe6e9e6, 0xffe6e9e6, 0xffeff0ef, 0xfff7f7f7, + 0xfffaf7fa, 0xfffcfbfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcfcfc, 0xfff7fbf7, 0xfff1f4f1, 0xfff1f4f1, 0xffe6e7e6, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x110b0c0b, + 0x33262826, 0x88313531, 0xdd1b1c1b, 0xee101010, 0xee101010, 0xee101010, 0xee101010, 0xdd1e1e1e, + 0xaa4a454a, 0x994a454a, 0xcc312f31, 0xdd191a19, 0xee191c19, 0xdd191c19, 0xdd212321, 0xcc292a29, + 0xbb262426, 0x88262426, 0x441b181b, 0x22100c10, 0x22080c08, 0x11030403, 0x11000000, 0x44050805, + 0xcc504c50, 0xff979397, 0xffdedbde, 0xffdedbde, 0xffececec, 0xffececec, 0xfff7f7f7, 0xfff7f7f7, + 0xfffafbfa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffcfcfc, 0xfffcfcfc, + 0xfff7f3f7, 0xfff7f3f7, 0xfff7f3f7, 0xfff7f3f7, 0xffdee3de, 0xff979897, 0xcc504e50, 0x66080408, + 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x110b0b0b, 0x33161616, 0x66212021, 0x88292d29, 0xaa292d29, 0xbb292d29, 0xbb292d29, + 0xaa292829, 0x88292829, 0x661b1b1b, 0x440e0d0e, 0x33080408, 0x22030103, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffdee3de, 0xffe6e9e6, 0xffeff0ef, 0xfff7f7f7, + 0xfffaf7fa, 0xfffcfbfc, 0xfffcfbfc, 0xffffffff, 0xfffcfefc, 0xfffcfefc, 0xfffcfefc, 0xfffcfefc, + 0xffffffff, 0xffffffff, 0xfffcfcfc, 0xfffcfcfc, 0xfff7fbf7, 0xfff1f4f1, 0xfff1f4f1, 0xffe6e7e6, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x110b0c0b, 0x22161816, + 0x66262826, 0xbb262826, 0xdd1b1c1b, 0xee101010, 0xee101010, 0xee101010, 0xdd1e1e1e, 0xaa3a393a, + 0x77312f31, 0x77312f31, 0x88312f31, 0xbb312f31, 0xdd212321, 0xdd212321, 0xdd292a29, 0xcc313131, + 0xbb313131, 0x99262426, 0x661b181b, 0x33100c10, 0x33080c08, 0x11030403, 0x00000000, 0x22000000, + 0x88080408, 0xee979397, 0xffdedbde, 0xffdedbde, 0xffececec, 0xffececec, 0xfff7f7f7, 0xfff7f7f7, + 0xfffafbfa, 0xfffafbfa, 0xfffafbfa, 0xfffafbfa, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfff7f3f7, 0xfff7f3f7, 0xfff7f3f7, 0xfff7f3f7, 0xffdee3de, 0xee979897, 0x99080408, 0x44080408, + 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x110b0b0b, 0x33161616, 0x441e1f1e, 0x661e1f1e, 0x77292d29, 0x771e1f1e, + 0x661b1b1b, 0x551b1b1b, 0x440e0d0e, 0x33000000, 0x22030103, 0x22000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffdee3de, 0xffe6e9e6, 0xffeff0ef, 0xffeff0ef, + 0xfffaf7fa, 0xfffaf7fa, 0xfffcfbfc, 0xfffcfbfc, 0xfffafcfa, 0xfffafcfa, 0xfffafcfa, 0xfffafcfa, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffafafa, 0xfff1f4f1, 0xfff1f4f1, 0xffecedec, 0xffe6e7e6, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x00000000, 0x110b0c0b, 0x44212421, + 0x99262826, 0xcc262826, 0xdd1b1c1b, 0xdd1b1c1b, 0xdd101010, 0xdd1e1e1e, 0xbb3a393a, 0x772c2b2c, + 0x66191a19, 0x66191a19, 0x66191a19, 0x88312f31, 0xaa292a29, 0xcc292a29, 0xcc292a29, 0xbb313131, + 0xaa313131, 0x99262426, 0x77262426, 0x441b181b, 0x33050805, 0x22030403, 0x00000000, 0x11000000, + 0x44080408, 0xbb504c50, 0xee979397, 0xffdedbde, 0xffe1e1e1, 0xffececec, 0xffececec, 0xfff7f7f7, + 0xfff4f7f4, 0xfff4f7f4, 0xfffafbfa, 0xfffafbfa, 0xfffafafa, 0xfffafafa, 0xfffafafa, 0xfff7f7f7, + 0xfff7f3f7, 0xfff7f3f7, 0xfff7f3f7, 0xffe1dfe1, 0xee979897, 0xcc504e50, 0x66080408, 0x33080408, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x110b0b0b, 0x22131213, 0x33131213, 0x44131213, 0x44131213, + 0x440e0d0e, 0x330e0d0e, 0x33000000, 0x22000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33101010, 0xcc101010, 0xee9f9f9f, 0xffe6e7e6, 0xffdee3de, 0xffe6e9e6, 0xffeff0ef, 0xffeff0ef, + 0xfff7f3f7, 0xfffaf7fa, 0xfffaf7fa, 0xfffaf7fa, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, + 0xfffafafa, 0xfffafafa, 0xfff7f7f7, 0xfff7f7f7, 0xfff1f4f1, 0xfff1f4f1, 0xffecedec, 0xffe6e7e6, + 0xffbdbabd, 0xdd080808, 0x55080808, 0x00080808, 0x00000000, 0x000b0c0b, 0x22161816, 0x66212421, + 0x99262826, 0xbb262826, 0xcc262826, 0xdd1b1c1b, 0xdd1e1e1e, 0xbb2c2b2c, 0x772c2b2c, 0x551e1e1e, + 0x55000400, 0x55000400, 0x55000400, 0x55191a19, 0x66212321, 0x99292a29, 0xaa292a29, 0xaa292a29, + 0x99313131, 0x88262426, 0x661b181b, 0x441b181b, 0x22050805, 0x22030403, 0x00000000, 0x00000000, + 0x22080408, 0x66080408, 0xcc504c50, 0xff979397, 0xffd6d7d6, 0xffe1e1e1, 0xffececec, 0xffececec, + 0xffeff3ef, 0xfff4f7f4, 0xfff4f7f4, 0xfff4f7f4, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f3f7, 0xfff7f3f7, 0xffe1dfe1, 0xffb5b6b5, 0xdd504e50, 0x88080408, 0x44080408, 0x22080408, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11080408, 0x22080408, 0x22080408, 0x22080408, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33080808, 0xcc080808, 0xee919491, 0xffd6dbd6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, + 0xffa5a6a5, 0xdd080408, 0x55080408, 0x00080408, 0x00000000, 0x110b0b0b, 0x33161616, 0x66212021, + 0x88292829, 0xaa292829, 0xbb292829, 0xcc292829, 0xbb292829, 0x77292829, 0x551b1b1b, 0x550e0d0e, + 0x44030303, 0x44000000, 0x44030303, 0x44080808, 0x440b0b0b, 0x55212021, 0x77212021, 0x88212021, + 0x88212021, 0x77212021, 0x55191819, 0x44101010, 0x22080408, 0x11030103, 0x00000000, 0x00000000, + 0x00000000, 0x22000000, 0x771b1b1b, 0xcc525152, 0xee979397, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffdee3de, 0xffdee3de, 0xff979897, 0xdd504e50, 0x88101410, 0x44000000, 0x22000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x22080808, 0xbb080808, 0xee919491, 0xffd6dbd6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xffefebef, 0xffefebef, 0xffefebef, 0xffefebef, + 0xeea5a6a5, 0xcc080408, 0x44080408, 0x00080408, 0x00000000, 0x110b0b0b, 0x220b0b0b, 0x44161616, + 0x661e1e1e, 0x77292829, 0x88292829, 0x99292829, 0x77292829, 0x551b1b1b, 0x440e0d0e, 0x44000000, + 0x44000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x330b0b0b, 0x44161616, 0x66161616, + 0x66191819, 0x66191819, 0x55101010, 0x33101010, 0x22030103, 0x11030103, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x22000000, 0x771b1b1b, 0xbb504c50, 0xee979397, 0xff979397, 0xffdedbde, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xff979897, 0xee979897, 0xcc504e50, 0x88080408, 0x44000000, 0x22000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11080808, 0x66080808, 0xbb4d4e4d, 0xee919491, 0xeea5a7a5, 0xffa5a7a5, 0xffa5a7a5, 0xffa5a7a5, + 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, + 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, 0xffb2b1b2, 0xffaaa7aa, 0xffaaa7aa, 0xeeaaa7aa, 0xeeaaa7aa, + 0xcc707070, 0x99080408, 0x33080408, 0x00080408, 0x00000000, 0x00000000, 0x110b0b0b, 0x220b0b0b, + 0x33131313, 0x441e1e1e, 0x441e1e1e, 0x441e1e1e, 0x440e0d0e, 0x440e0d0e, 0x44000000, 0x44000000, + 0x33000000, 0x33000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x220b0b0b, 0x330b0b0b, + 0x44101010, 0x44101010, 0x44080808, 0x33080808, 0x11030103, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x22000000, 0x55080408, 0x99080408, 0xcc504c50, 0xee504c50, + 0xeeaaa9aa, 0xffaaa9aa, 0xffaaa9aa, 0xffaaa9aa, 0xffa7a9a7, 0xffa7a9a7, 0xeea7a9a7, 0xee606260, + 0xcc504e50, 0x99080408, 0x66080408, 0x44080408, 0x22000000, 0x11000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080808, 0x22080808, 0x77080808, 0xbb080808, 0xdd212021, 0xdd212021, 0xdd212021, 0xdd212021, + 0xdd292429, 0xdd292429, 0xdd292429, 0xdd292429, 0xdd292429, 0xdd292429, 0xdd292429, 0xdd292429, + 0xdd292429, 0xdd292429, 0xdd292429, 0xdd292429, 0xdd212021, 0xdd212021, 0xdd212021, 0xcc212021, + 0x99080408, 0x44080408, 0x22080408, 0x00080408, 0x00000000, 0x00000000, 0x00000000, 0x110b0b0b, + 0x11080808, 0x11080808, 0x22080808, 0x22080808, 0x33000000, 0x33000000, 0x33000000, 0x33000000, + 0x33000000, 0x22000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x22000000, + 0x22080808, 0x33080808, 0x33080808, 0x22080808, 0x11000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11080408, 0x33080408, 0x55080408, 0x88080408, + 0xaa211c21, 0xcc211c21, 0xdd211c21, 0xdd211c21, 0xdd191c19, 0xcc191c19, 0xaa191c19, 0x88191c19, + 0x66080408, 0x44080408, 0x33080408, 0x22080408, 0x11000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x22000000, 0x33000000, 0x44000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x44000000, + 0x33000000, 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x11000000, 0x11000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x22000000, 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x22000000, 0x22000000, + 0x33000000, 0x44000000, 0x44000000, 0x55000000, 0x55000000, 0x44000000, 0x44000000, 0x33000000, + 0x22000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x33000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, + 0x22000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x22000000, 0x22000000, 0x33000300, 0x33000300, 0x44000400, 0x44000400, + 0x55080808, 0x55101010, 0x66101010, 0x66191819, 0x661b1e1b, 0x661b1e1b, 0x66292d29, 0x66292d29, + 0x77313531, 0x77313531, 0x77313531, 0x77313531, 0x773a3d3a, 0x773a3d3a, 0x773a3d3a, 0x773a3d3a, + 0x77424142, 0x77424142, 0x77424142, 0x77424142, 0x77424542, 0x77424542, 0x77424542, 0x77424542, + 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x88424542, 0x88424542, 0x88424542, 0x88424542, + 0x88424542, 0x88424542, 0x88424542, 0x88424542, 0x88424542, 0x88424542, 0x88424542, 0x88424542, + 0x88424142, 0x88424142, 0x88424142, 0x88424142, 0x88424142, 0x88424142, 0x88424142, 0x88424142, + 0x88424142, 0x88424142, 0x88424142, 0x88424142, 0x883a3d3a, 0x883a3d3a, 0x883a3d3a, 0x883a3d3a, + 0x883a3d3a, 0x883a3d3a, 0x883a3d3a, 0x883a3d3a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, + 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, + 0x88313531, 0x88313531, 0x88313531, 0x88313531, 0x88313131, 0x88313131, 0x88313131, 0x88313131, + 0x88313131, 0x88313131, 0x88313131, 0x88313131, 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, + 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, + 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, + 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, + 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, 0x88292d29, + 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, + 0x88313131, 0x88313131, 0x88313131, 0x88313131, 0x88313131, 0x88313131, 0x88313131, 0x88313131, + 0x88313131, 0x88313131, 0x88313131, 0x88313131, 0x88313531, 0x88313531, 0x88313531, 0x88313531, + 0x88313531, 0x88313531, 0x88313531, 0x88313531, 0x88313531, 0x88313531, 0x88313531, 0x88313531, + 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, + 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, + 0x883a393a, 0x883a393a, 0x883a393a, 0x883a393a, 0x88313531, 0x88313531, 0x88313531, 0x88313531, + 0x88313531, 0x77313531, 0x77313531, 0x88313531, 0x88313131, 0x77313131, 0x77313131, 0x77313131, + 0x77292d29, 0x77292d29, 0x77292d29, 0x77292d29, 0x77292829, 0x77292829, 0x77292829, 0x77292829, + 0x77212021, 0x77212021, 0x77212021, 0x77212021, 0x77191819, 0x77191819, 0x77191819, 0x66101010, + 0x66101010, 0x660b0b0b, 0x660b0b0b, 0x660b0b0b, 0x55080808, 0x55080808, 0x55050505, 0x44050505, + 0x33000400, 0x33000400, 0x22000400, 0x22000300, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080408, 0x22080408, 0x44080408, 0x55080408, + 0x66191419, 0x66191419, 0x77423f42, 0x77423f42, 0x77424542, 0x77424542, 0x77606260, 0x77606260, + 0x77636163, 0x77636163, 0x88636163, 0x88636163, 0x886b696b, 0x886b696b, 0x886b696b, 0x886b696b, + 0x99737173, 0x99737173, 0x99737173, 0x99737173, 0x9973797b, 0x9973797b, 0x9973797b, 0x9973797b, + 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, + 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, + 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, + 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b797b, 0xaa7b7573, 0xaa7b7573, 0xaa7b7573, 0xaa7b7573, + 0xaa737573, 0xaa737573, 0xaa737573, 0xaa737573, 0xaa737573, 0xaa737573, 0xaa737573, 0xaa737573, + 0xaa737573, 0xaa737573, 0xaa737573, 0xaa737573, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, + 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, + 0xaa736d73, 0xaa736d73, 0xaa736d73, 0xaa736d73, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa737573, 0xaa737573, 0xbb737573, 0xbb737573, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, + 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, 0xaa6b696b, 0xaa636563, 0xaa636563, 0xaa636563, 0xaa636563, + 0x995a5d5a, 0x995a5d5a, 0x995a5d5a, 0x995a5d5a, 0x99525552, 0x99525552, 0x99525552, 0x88525552, + 0x88424542, 0x88424542, 0x88424542, 0x88424542, 0x88312d31, 0x88312d31, 0x88312d31, 0x88312d31, + 0x88191c19, 0x77191c19, 0x77191c19, 0x77191c19, 0x66080c08, 0x44080c08, 0x33080c08, 0x22080c08, + 0x11080408, 0x00080408, 0x00080408, 0x00080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x55080408, 0x77343134, 0x88605d60, 0x88605d60, + 0x886b6b6b, 0x886b6b6b, 0x886b6b6b, 0x996b6b6b, 0x997e807e, 0x997e807e, 0xaa7e807e, 0xaa7e807e, + 0xaa898a89, 0xaa898a89, 0xaa898a89, 0xaa898a89, 0xbb8c8f8c, 0xbb8c8f8c, 0xbb8c8f8c, 0xbb8c8f8c, + 0xbb949494, 0xbb949494, 0xbb949494, 0xcc949494, 0xcc949797, 0xcc949797, 0xcc949797, 0xcc949797, + 0xcc979a97, 0xcc979a97, 0xcc979a97, 0xcc979a97, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, + 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, + 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, + 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9b9a, 0xcc9c9b9a, 0xcc9c9b9a, 0xcc9c9b9a, + 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, + 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, + 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, + 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, + 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, + 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, + 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9d9c, + 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9d9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, + 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, + 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, + 0xcc9c9b9c, 0xcc9c9b9c, 0xcc9c9b9c, 0xcc9c9b9c, 0xcc9c9b9c, 0xcc9c9b9c, 0xcc9c9b9c, 0xcc9c9b9c, + 0xcc9f9b9f, 0xcc9f9b9f, 0xcc9f9b9f, 0xcc9f9b9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, 0xcc9f9d9f, + 0xcc9a9d9f, 0xcc9a9d9f, 0xcc9a9d9f, 0xcc9a9d9f, 0xcc9a9a9a, 0xcc9a9a9a, 0xcc9a9a9a, 0xcc9a9a9a, + 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9b9a, 0xcc9a9a9a, 0xcc9a9a9a, 0xcc9a9a9a, 0xcc9a9a9a, + 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, + 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, 0xcc9a979a, 0xcc94979a, 0xcc94979a, 0xcc94979a, 0xcc94979a, + 0xcc979697, 0xcc979697, 0xcc979697, 0xcc979697, 0xcc919291, 0xcc919291, 0xcc919291, 0xcc919291, + 0xcc919291, 0xcc919291, 0xcc919291, 0xcc919291, 0xcc8f908f, 0xcc8f908f, 0xcc8f908f, 0xcc8f908f, + 0xcc8c8b8c, 0xcc8c8b8c, 0xcc8c8b8c, 0xcc8c8b8c, 0xbb848884, 0xbb848884, 0xbb848884, 0xbb848884, + 0xbb7e7d7e, 0xbb7e7d7e, 0xbb7e7d7e, 0xbb7e7d7e, 0xaa737073, 0xaa737073, 0xaa737073, 0xaa737073, + 0xaa6b6b6b, 0x996b6b6b, 0x99424342, 0x99424342, 0x99373937, 0x88373937, 0x77373937, 0x66080c08, + 0x66080408, 0x22080408, 0x00080408, 0x00080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x33000000, 0x77262626, 0x88605d60, 0x88605d60, 0x998c8a8c, 0xaa8c8a8c, + 0xaa949694, 0xaa949694, 0xbb949694, 0xbb949694, 0xbb9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, + 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9ca29c, 0xcc9ca29c, 0xdd9ca29c, 0xdd9ca29c, + 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, + 0xdda5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xdda5aaad, 0xdda5aaad, 0xdda5aaad, 0xdda5aaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, + 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, + 0xdda5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xdd9ca29c, 0xdd9ca29c, 0xdd9ca29c, 0xdd9ca29c, + 0xdd9c9a9c, 0xdd9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc949294, 0xcc949294, 0xcc949294, 0xcc949294, + 0xcc949294, 0xcc949294, 0xcc949294, 0xbb6b6b6b, 0xbb656565, 0xbb656565, 0xaa656565, 0xaa656565, + 0xbb656265, 0x77373337, 0x44080408, 0x11080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x33000000, 0x884d4c4d, 0x99737173, 0xaa8c8a8c, 0xaa8c8a8c, 0xcc8c8a8c, 0xcc8c8a8c, + 0xcc949694, 0xcc949694, 0xdd949694, 0xdd949694, 0xdd9c9e9c, 0xdd9c9e9c, 0xdd9c9e9c, 0xdd9c9e9c, + 0xdd9c9e9c, 0xdd9c9e9c, 0xdd9c9e9c, 0xdd9c9e9c, 0xdd9ca29c, 0xdd9ca29c, 0xdd9ca29c, 0xdd9ca29c, + 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, + 0xdda5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xdda5aaad, 0xdda5aaad, 0xdda5aaad, 0xdda5aaad, + 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xddadaaad, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, + 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, + 0xdda5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xdd9ca29c, 0xdd9ca29c, 0xdd9ca29c, 0xdd9ca29c, + 0xdd9c9a9c, 0xdd9c9a9c, 0xdd9c9a9c, 0xdd9c9a9c, 0xdd949294, 0xdd949294, 0xdd949294, 0xdd949294, + 0xdd949294, 0xdd949294, 0xdd949294, 0xdd949294, 0xdd949294, 0xcc949294, 0xcc949294, 0xcc949294, + 0xee949294, 0xbb656265, 0x99373337, 0x55080408, 0x11080808, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11100c10, 0x773c393a, 0x9994928c, 0xbb94928c, 0xcc8f908f, 0xcc8f908f, 0xdd9ca29c, 0xdd9ca29c, + 0xdda5a1a2, 0xdda5a1a2, 0xdda5a1a2, 0xdda5a1a2, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, + 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a6a7, 0xddb5b2b5, 0xddb5b2b5, 0xdda7a6a7, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddb5aead, 0xddb5aead, 0xddb5aead, 0xddb5aead, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb2b3b2, 0xddb2b3b2, 0xddb2b3b2, 0xddb2b3b2, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xdda7a6a7, + 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, + 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdd9a9a9a, 0xdd9a9a9a, 0xdd9a9a9a, + 0xdd9a9a9a, 0xdd9a9a9a, 0xdd9a9a9a, 0xdd9a9a9a, 0xdd9a979a, 0xdd9a979a, 0xdd9a979a, 0xdd9a979a, + 0xeea5a2a5, 0xdd8c8b8c, 0xbb8c8b8c, 0xaa5a5d5a, 0x662c2d2c, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x44100c10, 0x99686563, 0xbb94928c, 0xcc94928c, 0xdd9ca29c, 0xcc8f908f, 0xdd9ca29c, 0xdd9ca29c, + 0xdda5a1a2, 0xdda5a1a2, 0xdda5a1a2, 0xdda5a1a2, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, + 0xddb5b2b5, 0xddb5b2b5, 0xdda7a6a7, 0xdda7a6a7, 0xddb5b2b5, 0xdda7a6a7, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, + 0xddb5aead, 0xddb5aead, 0xddb5aead, 0xddb5aead, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb2b3b2, 0xddb2b3b2, 0xddb2b3b2, 0xddb2b3b2, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xdda7a6a7, 0xddb5b2b5, + 0xddb5b2b5, 0xddb5b2b5, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, + 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a9a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, + 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdda7a6a7, 0xdd9a9a9a, + 0xdd9a9a9a, 0xdd9a9a9a, 0xdd9a9a9a, 0xdd9a9a9a, 0xdd9a979a, 0xdd9a979a, 0xdd9a979a, 0xdd9a979a, + 0xeea5a2a5, 0xeea5a2a5, 0xdd8c8b8c, 0xcc8c8b8c, 0xbb585958, 0x332c2d2c, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050405, + 0x773c393a, 0xbb94928c, 0xcc94928c, 0xdd94928c, 0xdd9ca29c, 0xdd817f81, 0xff736d73, 0xff817f81, + 0xff847d7b, 0xff948f8f, 0xff948f8f, 0xff948f8f, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c928c, 0xff8c928c, 0xff8c928c, 0xff8c928c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c928c, 0xff8c928c, 0xff8c928c, 0xff8c928c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8a8c, 0xff8c8a8c, 0xff8c8a8c, 0xff8c8a8c, + 0xffa5a2a5, 0xeea5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xdd848684, 0x77585958, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11100c10, + 0x88686563, 0xcc94928c, 0xdd94928c, 0xdd94928c, 0xdd9ca29c, 0xdd817f81, 0xff817f81, 0xff8f908f, + 0xffa5a1a2, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffb5aead, 0xffb5aead, 0xffb5aead, 0xffb5aead, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, + 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, + 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffbdbabd, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, + 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb5bab5, 0xffb2b3b2, 0xffb2b3b2, 0xffb2b3b2, 0xffb2b3b2, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, + 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, + 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffb5b2b5, 0xffa7a5a7, + 0xffa5a2a5, 0xeea5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xdd848684, 0xaa585958, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22191419, + 0x99636163, 0xcc898a89, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda7a6a7, 0xdd949294, 0xff949294, 0xffa7a6a7, + 0xffbdbebd, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffd0d2d0, 0xffd0d2d0, 0xffd0d2d0, 0xffbdbebd, + 0xffb2b2b2, 0xee9c9a9c, 0xdd9c9a9c, 0xdd9c9a9c, 0xdd9c9e9c, 0xbb686968, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33191419, + 0xaa636163, 0xdd898a89, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda7a6a7, 0xdd949294, 0xffa7a6a7, 0xffbababa, + 0xffd0d2d0, 0xffe4e7e4, 0xffe4e7e4, 0xffe4e7e4, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, + 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffeff0ef, 0xffe4e7e4, 0xffe4e7e4, 0xffe4e7e4, 0xffd0d2d0, + 0xffb2b2b2, 0xeea7a6a7, 0xdd9c9a9c, 0xdd9c9a9c, 0xdd9c9e9c, 0xcc686968, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33100d10, + 0xaa636163, 0xdd898a89, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda7a6a7, 0xdd949294, 0xffa7a6a7, 0xffcecece, + 0xffe4e7e4, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xffe4e7e4, + 0xffbdbebd, 0xeea7a6a7, 0xdd9c9a9c, 0xdd9c9a9c, 0xdd9c9e9c, 0xcc686968, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33100d10, + 0xaa636163, 0xdd898a89, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda7a6a7, 0xdd949294, 0xffbababa, 0xffcecece, + 0xffe4e7e4, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7fbf7, 0xfff7fbf7, 0xfff7fbf7, 0xffe4e7e4, + 0xffbdbebd, 0xeea7a6a7, 0xdd9c9a9c, 0xdd9c9a9c, 0xdd9c9e9c, 0xcc9c9e9c, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33101010, + 0xaa4a5152, 0xdd868a89, 0xdda5a6a5, 0xdda5a6a5, 0xddadadad, 0xdd9c9a9c, 0xffadadad, 0xffced2ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffbdbebd, 0xeea7a9a7, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda5aaa5, 0xcc6e736e, 0x00000400, 0x00000300, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22191819, + 0x994a5152, 0xdd868a89, 0xdda5a6a5, 0xdda5a6a5, 0xddadadad, 0xdd9c9a9c, 0xffadadad, 0xffced2ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffbdbebd, 0xeea7a9a7, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda5aaa5, 0xbb6e736e, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101010, + 0x994a5152, 0xcc868a89, 0xdda5a6a5, 0xdda5a6a5, 0xddadadad, 0xdd9c9a9c, 0xffadadad, 0xffced2ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffbdbebd, 0xeea7a9a7, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda5aaa5, 0xbb6e736e, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101010, + 0x994a5152, 0xcc868a89, 0xdda5a6a5, 0xdda5a6a5, 0xddadadad, 0xdd9c9a9c, 0xffadadad, 0xffced2ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffbdbebd, 0xeea7a9a7, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda5aaa5, 0xbb6e736e, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101010, + 0x884a494a, 0xcc868486, 0xdda5a2a5, 0xdda5a2a5, 0xddadaead, 0xdd9c9a9c, 0xffadaead, 0xffced7ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeaaaaaa, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda5aaa5, 0xaa6e716e, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11101010, + 0x884a494a, 0xcc868486, 0xdda5a2a5, 0xdda5a2a5, 0xddadaead, 0xdd9c9a9c, 0xffadaead, 0xffced7ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeaaaaaa, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda5aaa5, 0xaa6e716e, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101010, + 0x884a494a, 0xcca5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xddadaead, 0xdd9c9a9c, 0xffadaead, 0xffced7ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeaaaaaa, 0xdd9c9e9c, 0xdd9c9e9c, 0xdda5aaa5, 0xaa6e716e, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101010, + 0x994a494a, 0xcca5a2a5, 0xdda5a2a5, 0xdda5a2a5, 0xddadaead, 0xdd9c9a9c, 0xffadaead, 0xffced7ce, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeaaaaaa, 0xdd9c9e9c, 0xddaaaaaa, 0xdda5aaa5, 0xaa6e716e, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101310, + 0x995a595a, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xddafaeaf, 0xdd9c9a9c, 0xffafaeaf, 0xffd6d7d6, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeafadaf, 0xdda5a2a5, 0xdda5a2a5, 0xddb5b6b5, 0xbb797b79, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101310, + 0x995a595a, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xddafaeaf, 0xdd9c9a9c, 0xffafaeaf, 0xffd6d7d6, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeafadaf, 0xdda5a2a5, 0xdda5a2a5, 0xddb5b6b5, 0xbb797b79, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101310, + 0xaa5a595a, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xddafaeaf, 0xdd9c9a9c, 0xffafaeaf, 0xffd6d7d6, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeafadaf, 0xdda5a2a5, 0xddafadaf, 0xddb5b6b5, 0xcc797b79, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33101310, + 0xaa737373, 0xdda5a6a5, 0xdda5a6a5, 0xdda5a6a5, 0xddafaeaf, 0xdd9c9a9c, 0xffafaeaf, 0xffd6d7d6, + 0xffe6ebe6, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xffe6ebe6, + 0xffc5c2c5, 0xeeafadaf, 0xdda5a2a5, 0xddafadaf, 0xddb5b6b5, 0xcc797b79, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33101010, + 0xaa606060, 0xddada6ad, 0xddada6ad, 0xddada6ad, 0xddbab7ba, 0xdd949294, 0xffbab7ba, 0xffcecace, + 0xffeff0ef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffeff0ef, + 0xffc5c2c5, 0xeea5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xddadaeb5, 0xcc737479, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33080808, + 0xaa606060, 0xddada6ad, 0xddada6ad, 0xddada6ad, 0xddbab7ba, 0xdd949294, 0xffbab7ba, 0xffcecace, + 0xffeff0ef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffeff0ef, + 0xffc5c2c5, 0xeea5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xddadaeb5, 0xbb737479, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33191819, + 0x99606060, 0xccada6ad, 0xddada6ad, 0xddada6ad, 0xddbab7ba, 0xdd949294, 0xffa7a5a7, 0xffcecace, + 0xffdee1de, 0xffeff0ef, 0xffffffff, 0xffffffff, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, + 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xfff7f8f7, 0xffffffff, 0xffffffff, 0xffeff0ef, 0xffdee1de, + 0xffc5c2c5, 0xeea5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xddadaeb5, 0xbb737479, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22101010, + 0x883a3d3a, 0xbb868386, 0xddada6ad, 0xddada6ad, 0xddbab7ba, 0xdd949294, 0xffa7a5a7, 0xffbab7ba, + 0xffced2ce, 0xffdee1de, 0xffeff0ef, 0xffeff0ef, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffeff0ef, 0xffeff0ef, 0xffdee1de, 0xffced2ce, + 0xffbababa, 0xeea5aaa5, 0xdda5aaa5, 0xdda5aaa5, 0xddadaeb5, 0x99737479, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11080808, + 0x773a3a3a, 0xaa6b6c6b, 0xcc9c9e9c, 0xdd9c9e9c, 0xddadaaad, 0xdd949294, 0xff949294, 0xffadaaad, + 0xffbdbebd, 0xffcecece, 0xffcecece, 0xffcecece, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced0ce, + 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced1d3, 0xffced1d3, 0xffced1d3, 0xffced1d3, + 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, 0xffd0d1d0, + 0xffced1ce, 0xffced1ce, 0xffced1ce, 0xffced1ce, 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced0ce, + 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced0ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, + 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffced2ce, 0xffb8bcb8, + 0xffadaead, 0xeeadaead, 0xddadaead, 0xddadaead, 0xcc848a84, 0x772c2e2c, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x66080808, 0x883a3a3a, 0xaa6b6c6b, 0xcc9c9e9c, 0xddadaaad, 0xccadaaad, 0xddadaaad, 0xddadaaad, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddb2b2b2, 0xddb2b2b2, 0xddb2b2b2, 0xddb2b2b2, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddc3c2c3, 0xddc3c2c3, 0xddc3c2c3, 0xddc3c2c3, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, + 0xddc5c2c5, 0xddc5c2c5, 0xddc8c8c8, 0xddc8c8c8, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, + 0xddc5c6c5, 0xddc5c6c5, 0xddc8cac8, 0xddc8cac8, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, + 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, + 0xddd0d1d0, 0xddd3d0d3, 0xddd0d1d0, 0xddd0d1d0, 0xddd6d2d6, 0xddd6d2d6, 0xddd6d2d6, 0xddd6d2d6, + 0xddd0d4d0, 0xddd0d4d0, 0xddd0d4d0, 0xddd0d4d0, 0xddd0d4d0, 0xddd0d4d0, 0xddd6d7d6, 0xddd6d7d6, + 0xddd3d8d3, 0xddd3d8d3, 0xddd3d8d3, 0xddd3d8d3, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, + 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd3d7d3, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, + 0xddd9d8d9, 0xdddedbde, 0xddd9d8d9, 0xddd9d8d9, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, + 0xdddedbde, 0xdddedbde, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, + 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd3d8d3, 0xddd3d8d3, 0xddd3d8d3, 0xddd3d8d3, + 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd3d5d3, 0xddd3d5d3, 0xddd0d4d0, 0xddd0d4d0, 0xddd0d4d0, + 0xddd3d5d3, 0xddd3d5d3, 0xddced2ce, 0xddced2ce, 0xddd0d1d0, 0xddd0d1d0, 0xddd0d1d0, 0xddd0d1d0, + 0xddcecece, 0xddced0ce, 0xddcecece, 0xddcecece, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, + 0xddcecdce, 0xddcecdce, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, + 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, + 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, + 0xddadadad, 0xddadadad, 0xddadadad, 0xddadadad, 0xdda2a5a2, 0xdda2a5a2, 0xdda2a5a2, 0xdda2a5a2, + 0xeeadaead, 0xeeadaead, 0xcc818381, 0xbb818381, 0xaa585c58, 0x442c2e2c, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33080808, 0x883a3a3a, 0x883a3a3a, 0xaa6b6c6b, 0xcc949294, 0xbb949294, 0xccadaaad, 0xddadaaad, + 0xddadaead, 0xddadaead, 0xddadaead, 0xddadaead, 0xddb2b2b2, 0xddb2b2b2, 0xddb2b2b2, 0xddb2b2b2, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddc3c2c3, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddc3c2c3, 0xddc3c2c3, 0xddc3c2c3, 0xddc3c2c3, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc8c8c8, + 0xddc8c8c8, 0xddc8c8c8, 0xddc8c8c8, 0xddc8c8c8, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc8cac8, + 0xddc8cac8, 0xddc8cac8, 0xddc8cac8, 0xddcbcecb, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, + 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddced0d0, 0xddced0d0, 0xddced0d0, 0xddced2d6, + 0xddced2ce, 0xddd0d1d0, 0xddd0d1d0, 0xddd0d1d0, 0xddd6d2d6, 0xddd6d2d6, 0xddd6d2d6, 0xddd3d4d3, + 0xddd3d5d3, 0xddd3d5d3, 0xddd3d5d3, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, + 0xddd3d8d3, 0xddd3d8d3, 0xddd3d8d3, 0xddd6dbd6, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, + 0xddd9d8d9, 0xddd9d8d9, 0xdddedbde, 0xdddedbde, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd9d8d9, 0xddd9d8d9, + 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd9d8d9, 0xddd3d8d3, 0xddd6dbd6, 0xddd3d8d3, 0xddd6dbd6, + 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd3d5d3, 0xddd3d5d3, 0xddd3d5d3, + 0xddd3d5d3, 0xddd6d7d6, 0xddd3d5d3, 0xddd0d4d0, 0xddd0d1d0, 0xddd0d1d0, 0xddd0d1d0, 0xddd0d1d0, + 0xddced0ce, 0xddced0ce, 0xddced0ce, 0xddced0ce, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, + 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcec6ce, + 0xddc8cac8, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, + 0xddc8c8c8, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, + 0xddc3c5c3, 0xddbfc0bf, 0xddc2c4c2, 0xddbebfbe, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, + 0xddadadad, 0xddadadad, 0xddadadad, 0xddadadad, 0xdda2a5a2, 0xdda2a5a2, 0xdda2a5a2, 0xdda2a5a2, + 0xeeadaead, 0xdd818381, 0xbb818381, 0x99555855, 0x772c2e2c, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11080808, 0x66080808, 0x773a3a3a, 0x773a3a3a, 0x99636163, 0x997b797b, 0xbb949294, 0xbb949294, + 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcc9c9e9c, 0xcca5a2a5, 0xddb2b2b2, 0xddb2b2b2, 0xddb2b2b2, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddc3c2c3, 0xddc3c2c3, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddc3c5c3, 0xddc3c5c3, + 0xddc3c2c3, 0xddc3c2c3, 0xddc3c2c3, 0xddc3c2c3, 0xddc5c2c5, 0xddc8c8c8, 0xddc5c2c5, 0xddc8c8c8, + 0xddc8c8c8, 0xddc8c8c8, 0xddc8c8c8, 0xddc8c8c8, 0xddc8cac8, 0xddc5c6c5, 0xddc8cac8, 0xddcbcecb, + 0xddcbcecb, 0xddc8cac8, 0xddc8cac8, 0xddcbcecb, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, + 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddced0d0, 0xddced1d3, 0xddced1d3, 0xddced2d6, + 0xddced2ce, 0xddced2ce, 0xddced2ce, 0xddced2ce, 0xddd3d4d3, 0xddd3d4d3, 0xddd3d4d3, 0xddd0d5d0, + 0xddd6d7d6, 0xddd3d5d3, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, + 0xddd6dbd6, 0xddd3d8d3, 0xddd6dbd6, 0xddd6dbd6, 0xddd9d8d9, 0xdddedbde, 0xdddedbde, 0xdddedbde, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd9dbd9, 0xdddedfde, 0xdddedfde, 0xddd9dbd9, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd9dbd9, 0xddd9dbd9, 0xdddedfde, 0xdddedfde, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd9dbd9, 0xddd9dbd9, 0xddd9dbd9, 0xdddedfde, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, + 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xdddedbde, 0xddd6dbd6, 0xddd6dbd6, 0xddd3d8d3, 0xddd6dbd6, + 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd6d7d6, 0xddd3d5d3, 0xddd6d7d6, + 0xddd3d5d3, 0xddd6d7d6, 0xddd3d5d3, 0xddd0d4d0, 0xddd6d2d6, 0xddd6d2d6, 0xddd0d1d0, 0xddd0d1d0, + 0xddced2ce, 0xddced1ce, 0xddced0ce, 0xddced0ce, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, + 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecdce, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, + 0xddc8cac8, 0xddc5c6c5, 0xddc8cac8, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, + 0xddc8c8c8, 0xddc8c8c8, 0xddc8c8c8, 0xddc5c3c6, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, + 0xddc4c4c3, 0xddc4c4c3, 0xddc4c4c2, 0xddc1c0c1, 0xddbfc1bf, 0xddbdbebe, 0xddbdbebe, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, 0xddb5bab5, + 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddb5b2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, 0xddadb2b5, + 0xddadadad, 0xddadadad, 0xdd9c9a9c, 0xcc9c9a9c, 0xcca2a5a2, 0xcc8c8e8c, 0xcc8c8e8c, 0xcc8c8e8c, + 0xdd818381, 0xaa555855, 0x77292d29, 0x55292d29, 0x22000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x22000000, 0x77101010, 0x77313131, 0x773f3f3f, 0x773f3f3f, 0x885a5d5a, 0x995a5d5a, + 0x99737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa8c8a8c, 0xbb8c8a8c, 0xbb8c8a8c, 0xbb8c8a8c, + 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcc9c9a9c, 0xcca5a6a5, 0xcca5a6a5, 0xcca5a6a5, 0xcca5a6a5, + 0xccadaead, 0xccadaead, 0xccadaead, 0xccadaead, 0xccb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, + 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, 0xddb5b6b5, + 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbabd, 0xddbdbebd, 0xddbdbebd, 0xddbec0bf, 0xddc0c2c1, + 0xddc7cacc, 0xddc8cccd, 0xddc0c3c5, 0xddc2c6c9, 0xddc3c5c7, 0xddc3c3c4, 0xddc0c3c2, 0xddbfc2c0, + 0xddc3c2c3, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, + 0xddc5cac5, 0xddc5cac5, 0xddc5cac5, 0xddc5cac5, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, + 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, + 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, + 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, 0xddcecece, + 0xddced2ce, 0xddced2ce, 0xddced2ce, 0xddced2ce, 0xddced2ce, 0xddced2ce, 0xddced2ce, 0xddced2ce, + 0xddcecfce, 0xddcfd0cf, 0xddd2d0d0, 0xddd1d3d2, 0xddd7d9d7, 0xddd9dad8, 0xdddbdddb, 0xdddde0de, + 0xdde0e3e2, 0xdde2e2e3, 0xdde2e3e1, 0xdde3e3e4, 0xdde5e3e5, 0xdde4e3e4, 0xdde3e0e2, 0xdddfdcdf, + 0xddd3d1d0, 0xddcecece, 0xddcfd0cf, 0xddd1d0d0, 0xddd5d6d4, 0xddd5d4d5, 0xddd5d4d4, 0xddd2d1d2, + 0xddd0cdd0, 0xddcfccd0, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, 0xddcecace, + 0xddc5cace, 0xddc5cace, 0xddc5cace, 0xddc5cace, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, + 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, + 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddc5c2c5, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, 0xddbdbebd, + 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc5c6c5, 0xddc8c8c9, 0xddc9c8ca, 0xddc9cbcb, 0xddcacdcc, + 0xddc9c7c8, 0xddc8c8c9, 0xddcac8ca, 0xddc8c7c9, 0xddc6c7c6, 0xddc2c6c3, 0xddc2c3c1, 0xddc4c7c3, + 0xddb9bab9, 0xddb8b6b8, 0xddb7b7b7, 0xddbababa, 0xddbcbfbc, 0xddbcc0bc, 0xddbdc2bd, 0xddbdc2bd, + 0xddb5b6b5, 0xddb5b6b5, 0xccb5b6b5, 0xccb5b6b5, 0xccadb2ad, 0xccadb2ad, 0xccadb2ad, 0xccadb2ad, + 0xcca5a6a5, 0xcca5a6a5, 0xcca5a6a5, 0xcca5a6a5, 0xcc9c9a94, 0xcc9c9a94, 0xcc9c9a94, 0xcc9c9a94, + 0xbb84827b, 0xbb84827b, 0xbb84827b, 0xaa84827b, 0xaa6b6d6b, 0xaa6b6d6b, 0x996b6d6b, 0x99474947, + 0xbb524d52, 0x661b1a1b, 0x44000000, 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x22000000, 0x66101010, 0x77242224, 0x663f3f3f, 0x663f3f3f, 0x663f3f3f, + 0x77504e50, 0x77504e50, 0x77504e50, 0x77504e50, 0x88656565, 0x88656565, 0x88656565, 0x99656565, + 0x99767476, 0x99767476, 0x99767476, 0xaa767476, 0xaa7e7f7e, 0xaa7e7f7e, 0xaa7e7f7e, 0xaa7e7f7e, + 0xaa868786, 0xaa868786, 0xbb868786, 0xbb868786, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, + 0xbb949494, 0xbb949494, 0xbb949494, 0xbb949494, 0xcc9c989c, 0xcc9c989c, 0xcc9c989c, 0xcc9c989c, + 0xccb5b6b5, 0xccb5b6b5, 0xccb5b6b5, 0xccb5b6b5, 0xccb5b6b5, 0xccb5b6b5, 0xccb5b6b5, 0xccb5b6b5, + 0xccbdbabd, 0xccbdbabd, 0xccbdbabd, 0xccbdbabd, 0xccbdbebd, 0xccbdbebd, 0xccbcbdbc, 0xccb9baba, + 0xccb1b3b4, 0xccb2b4b4, 0xccb2b5b5, 0xccb3b5b6, 0xccb1b4b6, 0xccb3b5b6, 0xccb4b8b8, 0xccb7b9b9, + 0xccc0c0c2, 0xccc5c2c5, 0xccc5c2c5, 0xccc5c2c5, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, + 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccc5c6c5, 0xccc5c6c5, 0xccc5c6c5, 0xccc5c6c5, + 0xccc5cac5, 0xccc5cac5, 0xccc5cac5, 0xccc5cac5, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, + 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, + 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, + 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, 0xcccecece, + 0xccced2ce, 0xccced2ce, 0xccced2ce, 0xccced2ce, 0xccced2ce, 0xccced2ce, 0xccced2ce, 0xccced2ce, + 0xcccecfce, 0xcccdcecd, 0xcccdcdcd, 0xcccbcbca, 0xccc7c8c7, 0xccc3c5c5, 0xccc3c4c4, 0xccc2c3c2, + 0xccbec1bf, 0xccbbbdbc, 0xccb7b8b6, 0xccb0b2b0, 0xccaeb1af, 0xccb0b1b0, 0xccb5b4b4, 0xccbcbabb, + 0xcca3a6a3, 0xccb8bab7, 0xccc9c9c7, 0xccc9c7c8, 0xccacacac, 0xccb5b3b7, 0xccb8b5b7, 0xccb7b5b5, + 0xccb0aeb1, 0xccb7b6b5, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, 0xcccecace, + 0xccc5cace, 0xccc5cace, 0xccc5cace, 0xccc5cace, 0xccc5c6c5, 0xccc5c6c5, 0xccc5c6c5, 0xccc5c6c5, + 0xccc5c6c5, 0xccc5c6c5, 0xccc5c6c5, 0xccc5c6c5, 0xccc5c2c5, 0xccc5c2c5, 0xccc5c2c5, 0xccc5c2c5, + 0xccc5c2c5, 0xccc5c2c5, 0xccc5c2c5, 0xccc5c2c5, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, + 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, 0xccbdbebd, + 0xccc5c6c5, 0xccc5c6c5, 0xccabaeac, 0xcca5a6a5, 0xcca8a9a8, 0xccaeadac, 0xccaeacab, 0xccb5b5b4, + 0xccbcbdbd, 0xccb0b1b2, 0xcca9a9a9, 0xcca5a4a6, 0xcc9f9fa1, 0xcc9da09f, 0xcc9ca09e, 0xccafb3b1, + 0xccacadab, 0xcca8a9a7, 0xcca0a09f, 0xcc999a99, 0xbb939492, 0xbb8d918e, 0xbb8c908c, 0xbb8c908c, + 0xbb868686, 0xbb868686, 0xbb868686, 0xbb868686, 0xbb7b7f7b, 0xbb7b7f7b, 0xaa7b7f7b, 0xaa7b7f7b, + 0xaa737370, 0xaa737370, 0xaa737370, 0xaa737370, 0x99686763, 0x99686763, 0x99686763, 0x99686763, + 0x995a5955, 0x885a5955, 0x885a5955, 0x8831312f, 0x77242424, 0x77242424, 0x77242424, 0x66242424, + 0x661b1a1b, 0x33000000, 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x44080408, 0x66080408, 0x66242224, 0x66242224, + 0x662c2b2c, 0x662c2b2c, 0x662c2b2c, 0x662c2b2c, 0x663f413f, 0x663f413f, 0x663f413f, 0x663f413f, + 0x77504e50, 0x77504e50, 0x77504e50, 0x77504e50, 0x77585858, 0x77585858, 0x77585858, 0x77585858, + 0x88606060, 0x88606060, 0x88606060, 0x88606060, 0x88636563, 0x88636563, 0x88636563, 0x88636563, + 0x886b6b6b, 0x886b6b6b, 0x996b6b6b, 0x996b6b6b, 0x99736f73, 0x99736f73, 0x99736f73, 0x99736f73, + 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, 0x996e6d6e, 0x996e706e, 0x996e706e, 0x996e706e, 0x996e706e, + 0x99707170, 0x99707170, 0x99707170, 0x99707170, 0xaa767576, 0x99767576, 0xaa767576, 0xaa767576, + 0xaa7b7c7e, 0xaa7b7c7e, 0xaa7b7c7f, 0xaa7d7e80, 0xaa7a7a7c, 0xaa7b7a7c, 0xaa787979, 0xaa777677, + 0xaa797979, 0xaa797979, 0xaa797979, 0xaa797979, 0xaa979694, 0xaa979694, 0xaa979694, 0xaa979694, + 0xaa949694, 0xaa949694, 0xaa949694, 0xaa949694, 0xaa797b79, 0xaa797b79, 0xaa797b79, 0xaa797b79, + 0xaa797979, 0xaa797979, 0xaa797979, 0xaa797979, 0xaa7b7976, 0xaa7b7976, 0xaa7b7976, 0xaa7b7976, + 0xaa767776, 0xaa767776, 0xaa767776, 0xaa767776, 0xaa767776, 0xaa767776, 0xaa767776, 0xaa767776, + 0xaa767576, 0x99767576, 0x99767576, 0x99767576, 0x99767876, 0x99767876, 0x99767876, 0x99767876, + 0x99767576, 0x99767576, 0x99767576, 0x99767576, 0x99767576, 0x99767576, 0x99767576, 0x99767576, + 0x99767776, 0x99767776, 0x99767776, 0x99767776, 0x99707770, 0x99707770, 0x99707770, 0x99707770, + 0x99707370, 0x99707370, 0x99707370, 0x99717571, 0x99787c79, 0x99787d79, 0x99787d79, 0x99797d79, + 0x99787d79, 0x99797d79, 0x99797d78, 0x99797d79, 0x99797c79, 0x99797c79, 0x99797c79, 0x99797c78, + 0x99747672, 0x99727672, 0x99727371, 0x99707371, 0x99797879, 0x99797878, 0x99797879, 0x99787879, + 0x99777577, 0xaa777676, 0xaa767476, 0xaa767476, 0xaa767476, 0xaa767476, 0xaa767476, 0xaa767476, + 0xaa6e7170, 0xaa6e7170, 0xaa6e7170, 0xaa6e7170, 0xaa737373, 0xaa737373, 0xaa737373, 0xaa737373, + 0xaa737373, 0xaa737373, 0xaa737373, 0xaa737373, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, + 0xaa737173, 0xaa737173, 0xaa737173, 0xaa737173, 0xaa707070, 0xaa707070, 0xaa707070, 0xaa707070, + 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, 0xaa6b6d6b, + 0x996e706e, 0xaa6f716f, 0x99747673, 0x99757774, 0x99767676, 0x99777876, 0x99737373, 0x99737272, + 0x99757577, 0x996e6e72, 0x996b6c70, 0x996b6c70, 0x99686c68, 0x99686c68, 0x99686c68, 0x996b6f6b, + 0x99636563, 0x995d5e5d, 0x995d5e5d, 0x995d5e5d, 0x995a5e5a, 0x885a5e5a, 0x885a5e5a, 0x885a5e5a, + 0x88585558, 0x88585558, 0x88585558, 0x88585558, 0x884a4c4a, 0x884a4c4a, 0x884a4c4a, 0x884a4c4a, + 0x77423f3c, 0x77423f3c, 0x77423f3c, 0x77423f3c, 0x77343331, 0x77343331, 0x77343331, 0x77343331, + 0x6631312f, 0x66080808, 0x66080808, 0x66080808, 0x66000000, 0x66000000, 0x55000000, 0x33000000, + 0x44000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080408, 0x11080408, 0x22080408, 0x33080408, + 0x44080808, 0x55080808, 0x55080808, 0x66080808, 0x66191c19, 0x66191c19, 0x66191c19, 0x66191c19, + 0x66292829, 0x66292829, 0x66292829, 0x66292829, 0x66313131, 0x66313131, 0x66313131, 0x66313131, + 0x663a393a, 0x663a393a, 0x663a393a, 0x663a393a, 0x663a3d3a, 0x663a3d3a, 0x663a3d3a, 0x663a3d3a, + 0x66424142, 0x66424142, 0x66424142, 0x66424142, 0x664a454a, 0x664a454a, 0x664a454a, 0x664a454a, + 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, + 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x77525152, 0x77525152, 0x77525152, 0x77525152, + 0x77525152, 0x77525152, 0x77525152, 0x77525152, 0x77525152, 0x77525152, 0x77525152, 0x77525152, + 0x77525552, 0x77525552, 0x77525552, 0x77525552, 0x774a4542, 0x774a4542, 0x774a4542, 0x774a4542, + 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x77525552, 0x77525552, 0x77525552, 0x77525552, + 0x77525152, 0x77525152, 0x77525152, 0x77525152, 0x7752514a, 0x7752514a, 0x7752514a, 0x7752514a, + 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, + 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, 0x774a4d4a, + 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, + 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x77424942, 0x77424942, 0x77424942, 0x77424942, + 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x77424942, 0x77424942, 0x77424942, 0x77424942, + 0x77424942, 0x77424942, 0x77424942, 0x77424942, 0x77424942, 0x77424942, 0x77424942, 0x77424942, + 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, + 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, + 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, + 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, + 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, 0x774a494a, + 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x77424542, + 0x77424542, 0x77424542, 0x77424542, 0x77424542, 0x77424142, 0x77424142, 0x77424142, 0x77424142, + 0x773a3d42, 0x773a3d42, 0x773a3d42, 0x773a3d42, 0x773a3d3a, 0x773a3d3a, 0x773a3d3a, 0x773a3d3a, + 0x66313531, 0x66313531, 0x66313531, 0x66313531, 0x66292d29, 0x66292d29, 0x66292d29, 0x66292d29, + 0x66292429, 0x66292429, 0x66292429, 0x66292429, 0x66191819, 0x66191819, 0x66191819, 0x66191819, + 0x66100c08, 0x66100c08, 0x66100c08, 0x66100c08, 0x66000000, 0x66000000, 0x66000000, 0x66000000, + 0x66080808, 0x66080808, 0x66080808, 0x55080808, 0x44000000, 0x22000000, 0x11000000, 0x11000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x22000000, 0x22000000, 0x33000000, 0x44000000, + 0x44000000, 0x44000000, 0x55000000, 0x55000000, 0x55000400, 0x55000400, 0x55000400, 0x55000400, + 0x55080808, 0x66080808, 0x66080808, 0x66080808, 0x662f2f2f, 0x662f2f2f, 0x662f2f2f, 0x662f2f2f, + 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, + 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, + 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, + 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, + 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, + 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, 0x66312f31, + 0x662f2f2f, 0x662f2f2f, 0x662f2f2f, 0x662f2f2f, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, 0x66080808, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080408, + 0x66080408, 0x66080408, 0x66080408, 0x66080408, 0x66080400, 0x66080400, 0x66080400, 0x66080400, + 0x66000400, 0x66000400, 0x66000400, 0x66000400, 0x66000400, 0x66000400, 0x66000400, 0x66000400, + 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x66000000, + 0x66000000, 0x66000000, 0x66000000, 0x66000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x44000000, 0x44000000, 0x33000000, 0x33000000, + 0x22000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000400, 0x11000400, 0x11000400, 0x22000400, + 0x22080808, 0x22080808, 0x22080808, 0x22080808, 0x33000000, 0x33000000, 0x33000000, 0x33000000, + 0x33000000, 0x33000000, 0x33000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, + 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, + 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x55000000, 0x44000000, 0x44000000, 0x44000000, + 0x44000000, 0x44000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55000000, + 0x55000000, 0x55000000, 0x55000000, 0x55000000, 0x55080808, 0x44080808, 0x44080808, 0x44080808, + 0x55080808, 0x44080808, 0x44080808, 0x55080808, 0x55080808, 0x44080808, 0x44080808, 0x44080808, + 0x44080808, 0x44080808, 0x44080808, 0x44080808, 0x44080808, 0x44080808, 0x44080808, 0x44080808, + 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, + 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, + 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, + 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, + 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, + 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, + 0x44080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, + 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, + 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x55080408, + 0x55080408, 0x55080408, 0x55080408, 0x55080408, 0x44080408, 0x44080408, 0x44080408, 0x44080408, + 0x44080408, 0x44080408, 0x44080408, 0x44080408, 0x44080400, 0x44080400, 0x44080400, 0x44080400, + 0x44000400, 0x44000400, 0x44000400, 0x44000400, 0x44000400, 0x44000400, 0x44000400, 0x44000400, + 0x44000000, 0x44000000, 0x44000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, + 0x33000000, 0x33000000, 0x22000000, 0x22000000, 0x22000000, 0x22000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11080808, 0x11080808, 0x11080808, 0x11080808, + 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, + 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, 0x11080808, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080408, + 0x11080408, 0x11080408, 0x11080408, 0x11080408, 0x11080400, 0x11080400, 0x11080400, 0x11080400, + 0x11000400, 0x11000400, 0x11000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xbb4d4e4d, 0xbb737573, 0xbb737573, + 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, + 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, + 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, + 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, + 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, + 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, + 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, 0xbb948e94, + 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, + 0xbb949294, 0xbb949294, 0xbb949294, 0xbb949294, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, 0xbb8c8e8c, + 0xbb737573, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xcc737573, 0xcc737573, 0xcc737573, + 0xcca5a6a5, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, + 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xccffffff, 0xcca5a6a5, 0xcca5a6a5, + 0xcc737173, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xdd737573, 0xdd737573, 0xddadaead, + 0xdda5a6a5, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, + 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddffffff, 0xddbabcba, 0xdda5a6a5, + 0xddadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xee737573, 0xeeadaead, 0xeeadaead, + 0xeebabcba, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeeffffff, 0xeed0d1d0, 0xeebabcba, + 0xeeadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xee737573, 0xeeadaead, 0xeeadaead, + 0xeed0d1d0, 0xeefffffe, 0xeeffffff, 0xeeffffff, 0xeefefffe, 0xfffefeff, 0xeefffeff, 0xeefefeff, + 0xeefeffff, 0xeefeffff, 0xeeffffff, 0xeefeffff, 0xeeffffff, 0xeefffefe, 0xeefffefe, 0xeefeffff, + 0xfffefefe, 0xeefefffe, 0xeefffffe, 0xeeffffff, 0xfffefffe, 0xeefffefe, 0xeeffffff, 0xeefffffe, + 0xfffefffe, 0xeefffeff, 0xeefeffff, 0xeefffeff, 0xffffffff, 0xeefffffe, 0xfffffefe, 0xfffffeff, + 0xeefeffff, 0xffffffff, 0xfffffffe, 0xeefffeff, 0xeefefffe, 0xffffffff, 0xeefffeff, 0xeefefffe, + 0xeefffffe, 0xeefffeff, 0xeefeffff, 0xeefeffff, 0xeefffffe, 0xeeffffff, 0xeeffffff, 0xeeffffff, + 0xeeffffff, 0xeefffeff, 0xfffeffff, 0xeefffffe, 0xeefffeff, 0xfffefffe, 0xeefffffe, 0xeeffffff, + 0xeefffefe, 0xffffffff, 0xeeffffff, 0xeefefefe, 0xeefefefe, 0xeeffffff, 0xeefffefe, 0xeefeffff, + 0xfffffffe, 0xeefffffe, 0xeefffefe, 0xeeffffff, 0xeefefeff, 0xeefefeff, 0xfffffeff, 0xfffffeff, + 0xffffffff, 0xeefeffff, 0xeefefeff, 0xeefffeff, 0xfffeffff, 0xeefffefe, 0xffffffff, 0xeefffffe, + 0xeeffffff, 0xfffffeff, 0xeefffffe, 0xeeffffff, 0xeefeffff, 0xfffefefe, 0xeefffeff, 0xeefffffe, + 0xeefffefe, 0xeefffeff, 0xfffefefe, 0xfffffffe, 0xeefffeff, 0xeefefeff, 0xeefffefe, 0xeeffffff, + 0xeefffeff, 0xeefefeff, 0xfffefeff, 0xeefefefe, 0xfffffffe, 0xfffefeff, 0xeefefeff, 0xeeffffff, + 0xeefefefe, 0xeefffffe, 0xeefefefe, 0xeefffeff, 0xfffefffe, 0xfffefefe, 0xeefefffe, 0xeefefffe, + 0xfffffffe, 0xffffffff, 0xeefeffff, 0xfffffefe, 0xeefefefe, 0xeefffefe, 0xfffefefe, 0xeefefeff, + 0xfffeffff, 0xeeffffff, 0xfffefefe, 0xfffefefe, 0xeefeffff, 0xeefeffff, 0xfffffefe, 0xeeffffff, + 0xeefffefe, 0xeefefffe, 0xeefefffe, 0xeefffeff, 0xfffffefe, 0xeeffffff, 0xfffefeff, 0xfffffefe, + 0xeefeffff, 0xeefefeff, 0xeefefeff, 0xeefffffe, 0xfffffefe, 0xeefffeff, 0xeefefffe, 0xeefefefe, + 0xeefeffff, 0xeefefefe, 0xeefeffff, 0xeefffeff, 0xeefeffff, 0xeeffffff, 0xfffffeff, 0xeeffffff, + 0xeefefffe, 0xfffefffe, 0xfffefffe, 0xeefffeff, 0xfffffeff, 0xeefefefe, 0xeefefffe, 0xeefefffe, + 0xeefefffe, 0xeefffeff, 0xeefffeff, 0xfffeffff, 0xeefffffe, 0xeeffffff, 0xeefffefe, 0xeefefefe, + 0xeefefeff, 0xeefefefe, 0xeefefeff, 0xeeffffff, 0xeeffffff, 0xfffefffe, 0xfffeffff, 0xeefffefe, + 0xeefffffe, 0xeefefefe, 0xeefffefe, 0xeefeffff, 0xeefffffe, 0xeefefefe, 0xeefefffe, 0xeefeffff, + 0xeefffeff, 0xfffffffe, 0xeefeffff, 0xeefeffff, 0xeefffffe, 0xeefffffe, 0xeefefffe, 0xeefffeff, + 0xeefefeff, 0xfffffffe, 0xeefefeff, 0xeefefffe, 0xeeffffff, 0xeefffefe, 0xeefefeff, 0xeefffffe, + 0xeefefffe, 0xeefffeff, 0xeefefeff, 0xfffeffff, 0xeefefeff, 0xeefffeff, 0xeefffffe, 0xeefffeff, + 0xeefffefe, 0xeefefeff, 0xeefefffe, 0xeefefeff, 0xeefffeff, 0xeefffffe, 0xeefffffe, 0xeefefeff, + 0xeefefefe, 0xfffffeff, 0xeefffefe, 0xeefefeff, 0xeefefefe, 0xfffeffff, 0xeee6e7e6, 0xeed0d1d0, + 0xeeadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848384, 0xffc5c2c5, 0xffc5c2c5, + 0xffdedfde, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefeff, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefffe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefeff, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefffe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, + 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xfffefefe, 0xffe9e9e9, 0xffdedfde, + 0xffdedfde, 0x00060306, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848384, 0xffc5c2c5, 0xffc5c2c5, + 0xffdedfde, 0xfffefdfd, 0xfffdfdfd, 0xfffdfefd, 0xfffdfdfd, 0xfffdfdfe, 0xfffdfdfd, 0xfffefefd, + 0xfffdfefe, 0xfffdfefd, 0xfffefefd, 0xfffefefd, 0xfffefefd, 0xfffdfefd, 0xfffdfdfd, 0xfffdfdfd, + 0xfffefefe, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfe, 0xfffefdfd, 0xfffefefd, 0xfffdfefd, 0xfffdfdfd, + 0xfffdfdfd, 0xfffdfefe, 0xfffdfdfd, 0xfffdfefd, 0xfffdfefe, 0xfffefdfd, 0xfffefdfd, 0xfffdfdfe, + 0xfffdfdfd, 0xfffdfefd, 0xfffdfdfe, 0xfffdfdfd, 0xfffdfdfe, 0xfffdfefd, 0xfffefdfe, 0xfffefdfd, + 0xfffdfefd, 0xfffefdfe, 0xfffefdfd, 0xfffefefd, 0xfffefefe, 0xfffefdfe, 0xfffefefe, 0xfffdfdfd, + 0xfffdfefd, 0xfffdfefd, 0xfffdfdfd, 0xfffdfdfd, 0xfffefdfe, 0xfffdfefe, 0xfffefdfd, 0xfffdfefd, + 0xfffdfdfd, 0xfffdfefe, 0xfffdfefd, 0xfffefdfd, 0xfffdfefe, 0xfffdfdfe, 0xfffdfefd, 0xfffefdfe, + 0xfffdfefd, 0xfffefefd, 0xfffdfefd, 0xfffdfefd, 0xfffdfefd, 0xfffdfefe, 0xfffefdfe, 0xfffdfefd, + 0xfffefefe, 0xfffdfdfe, 0xfffefefd, 0xfffdfdfd, 0xfffefefd, 0xfffefdfe, 0xfffefdfd, 0xfffefefd, + 0xfffdfefd, 0xfffdfefd, 0xfffdfdfe, 0xfffdfdfd, 0xfffefdfe, 0xfffdfefe, 0xfffdfdfd, 0xfffdfefd, + 0xfffdfdfe, 0xfffefdfe, 0xfffdfdfe, 0xfffdfefe, 0xfffefefe, 0xfffefefd, 0xfffefdfe, 0xfffdfdfe, + 0xfffdfdfd, 0xfffdfefd, 0xfffefdfd, 0xfffdfdfd, 0xfffdfdfe, 0xfffdfdfd, 0xfffefefe, 0xfffefdfd, + 0xfffefdfd, 0xfffdfefe, 0xfffdfdfe, 0xfffefdfd, 0xfffefdfd, 0xfffefdfe, 0xfffdfdfd, 0xfffdfdfd, + 0xfffefefe, 0xfffdfefe, 0xfffefdfd, 0xfffefefe, 0xfffdfdfd, 0xfffefdfd, 0xfffdfdfd, 0xfffefdfd, + 0xfffefdfe, 0xfffdfefd, 0xfffdfdfd, 0xfffdfefe, 0xfffdfdfd, 0xfffdfefe, 0xfffdfdfe, 0xfffdfdfd, + 0xfffefefe, 0xfffdfefd, 0xfffdfefe, 0xfffdfdfe, 0xfffdfdfe, 0xfffefefd, 0xfffefdfe, 0xfffdfdfd, + 0xfffdfdfd, 0xfffefefe, 0xfffdfdfe, 0xfffefdfe, 0xfffdfdfd, 0xfffdfefd, 0xfffefefe, 0xfffefdfd, + 0xfffdfefe, 0xfffdfefe, 0xfffefefe, 0xfffdfdfe, 0xfffdfdfd, 0xfffefdfd, 0xfffdfdfd, 0xfffdfdfd, + 0xfffdfdfd, 0xfffdfefd, 0xfffdfdfd, 0xfffefdfd, 0xfffefefe, 0xfffdfefd, 0xfffefdfd, 0xfffdfefe, + 0xfffefdfd, 0xfffefdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffefdfe, 0xfffefdfd, 0xfffefdfd, 0xfffdfefe, + 0xfffdfefd, 0xfffdfefd, 0xfffdfdfd, 0xfffefefe, 0xfffdfefd, 0xfffefdfd, 0xfffdfdfd, 0xfffefefd, + 0xfffefefd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfefd, 0xfffdfdfe, 0xfffefdfe, 0xfffefdfd, + 0xfffdfdfd, 0xfffefefd, 0xfffefefd, 0xfffdfefd, 0xfffefefd, 0xfffefdfd, 0xfffdfefe, 0xfffdfefd, + 0xfffdfdfd, 0xfffdfdfe, 0xfffdfdfe, 0xfffdfdfd, 0xfffdfdfe, 0xfffefdfe, 0xfffefdfd, 0xfffdfefe, + 0xfffdfdfd, 0xfffefefd, 0xfffdfdfd, 0xfffefdfe, 0xfffdfefe, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfe, + 0xfffefdfe, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffefdfe, 0xfffefdfe, 0xfffdfdfd, 0xfffdfdfe, + 0xfffefefd, 0xfffdfdfd, 0xfffefefe, 0xfffdfefd, 0xfffdfdfe, 0xfffdfdfe, 0xfff4f4f4, 0xffdedfde, + 0xffdedfde, 0x00060306, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848384, 0xffc5c2c5, 0xffc5c2c5, + 0xffe9e9e9, 0xfffdfcfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfc, 0xfffcfcfd, 0xfffdfdfd, 0xfffdfdfd, + 0xfffcfdfd, 0xfffdfdfc, 0xfffcfdfd, 0xfffcfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfcfd, 0xfffdfdfc, + 0xfffdfcfd, 0xfffdfcfd, 0xfffdfcfc, 0xfffcfcfc, 0xfffdfcfd, 0xfffdfdfd, 0xfffdfcfd, 0xfffdfdfd, + 0xfffdfdfd, 0xfffdfcfc, 0xfffdfcfd, 0xfffcfcfd, 0xfffdfdfc, 0xfffdfcfd, 0xfffdfdfc, 0xfffdfdfd, + 0xfffdfdfc, 0xfffcfdfd, 0xfffdfdfc, 0xfffdfcfd, 0xfffcfcfd, 0xfffdfdfd, 0xfffdfdfc, 0xfffdfdfd, + 0xfffdfdfd, 0xfffdfdfd, 0xfffcfcfc, 0xfffdfdfd, 0xfffcfdfd, 0xfffdfdfc, 0xfffdfdfc, 0xfffdfcfd, + 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffcfdfd, + 0xfffdfcfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffcfdfd, 0xfffcfcfc, 0xfffcfdfd, 0xfffdfdfc, 0xfffdfcfd, + 0xfffdfcfd, 0xfffdfcfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffcfdfd, 0xfffdfcfd, 0xfffdfdfd, + 0xfffdfdfd, 0xfffdfdfc, 0xfffdfdfd, 0xfffdfcfd, 0xfffcfdfd, 0xfffdfcfc, 0xfffdfcfd, 0xfffdfdfd, + 0xfffcfdfc, 0xfffdfdfd, 0xfffdfcfc, 0xfffdfcfc, 0xfffcfdfc, 0xfffcfdfd, 0xfffdfdfd, 0xfffcfcfd, + 0xfffdfcfd, 0xfffcfcfc, 0xfffdfdfc, 0xfffcfcfd, 0xfffcfdfd, 0xfffdfdfd, 0xfffcfcfd, 0xfffdfdfd, + 0xfffdfcfd, 0xfffcfdfd, 0xfffdfdfd, 0xfffdfdfc, 0xfffcfcfc, 0xfffdfcfd, 0xfffcfdfd, 0xfffdfcfc, + 0xfffcfdfc, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfc, 0xfffdfdfd, 0xfffdfdfd, 0xfffcfcfd, 0xfffdfdfd, + 0xfffdfdfc, 0xfffdfdfd, 0xfffdfdfd, 0xfffcfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfc, 0xfffdfcfd, + 0xfffdfdfd, 0xfffcfcfc, 0xfffdfcfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, + 0xfffdfcfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfcfd, 0xfffdfdfd, + 0xfffdfdfd, 0xfffcfdfd, 0xfffdfcfc, 0xfffcfdfc, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, + 0xfffdfdfd, 0xfffdfcfc, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffcfdfd, 0xfffdfcfd, 0xfffdfdfd, + 0xfffdfdfc, 0xfffdfdfc, 0xfffcfdfd, 0xfffcfdfd, 0xfffdfdfc, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfdfd, + 0xfffdfcfd, 0xfffdfdfd, 0xfffdfdfc, 0xfffdfdfc, 0xfffdfdfc, 0xfffdfdfd, 0xfffcfdfc, 0xfffdfdfd, + 0xfffdfdfd, 0xfffcfcfd, 0xfffdfcfd, 0xfffcfdfc, 0xfffdfcfd, 0xfffcfdfc, 0xfffdfdfd, 0xfffdfdfd, + 0xfffdfcfc, 0xfffdfdfd, 0xfffcfcfd, 0xfffdfdfc, 0xfffdfdfc, 0xfffdfdfc, 0xfffdfcfd, 0xfffdfdfd, + 0xfffcfdfd, 0xfffdfcfd, 0xfffdfcfd, 0xfffdfdfc, 0xfffdfdfd, 0xfffcfdfd, 0xfffdfdfd, 0xfffcfdfd, + 0xfffdfcfd, 0xfffcfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfcfd, 0xfffdfdfd, 0xfffcfdfd, 0xfffdfcfc, + 0xfffcfcfd, 0xfffdfcfd, 0xfffdfdfc, 0xfffcfdfd, 0xfffdfdfd, 0xfffdfdfd, 0xfffdfcfd, 0xfffdfdfc, + 0xfffdfdfd, 0xfffdfdfd, 0xfffdfcfc, 0xfffdfdfd, 0xfffdfcfd, 0xfffcfdfd, 0xfffcfdfc, 0xfffdfdfd, + 0xfffdfdfc, 0xfffdfdfd, 0xfffdfdfd, 0xfffcfdfd, 0xfffcfdfd, 0xfffdfcfd, 0xfff4f4f4, 0xffe9e9e9, + 0xffdedfde, 0x00060306, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848384, 0xffc5c2c5, 0xffc5c2c5, + 0xffe9e9e9, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfbfc, + 0xfffbfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffbfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfbfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfbfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfb, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfb, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfb, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfb, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, + 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfff4f4f4, 0xffe9e9e9, + 0xffdedfde, 0x00060306, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848684, 0xffc5c6c5, 0xffc5c6c5, + 0xffe6ebe6, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, + 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffcfbfb, + 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfbfb, + 0xfffbfcfc, 0xfffcfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfbfc, + 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffcfcfc, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfcfb, 0xfffbfbfb, + 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, + 0xfffcfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffcfbfb, + 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfc, 0xfffbfcfb, 0xfffbfcfb, + 0xfffbfcfc, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfcfb, 0xfffbfbfc, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, + 0xfffcfbfb, 0xfffcfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfc, 0xfffbfbfb, 0xfffbfbfb, + 0xfffbfbfc, 0xfffbfbfb, 0xfffbfcfc, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfb, + 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfb, + 0xfffbfcfb, 0xfffbfcfb, 0xfffcfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfc, 0xfffcfbfb, 0xfffbfbfc, + 0xfffbfbfb, 0xfffcfbfb, 0xfffbfbfc, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, + 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfc, 0xfffcfbfb, + 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfbfb, + 0xfffbfbfc, 0xfffbfbfc, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfc, 0xfffcfbfb, 0xfffbfcfb, + 0xfffbfbfb, 0xfffcfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, + 0xfffbfbfc, 0xfffbfcfc, 0xfffcfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfc, 0xfffbfbfb, + 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, + 0xfffbfcfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfbfc, 0xfffbfcfc, 0xfffbfbfc, 0xfffbfbfb, 0xfffbfcfc, + 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfc, + 0xfffbfcfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffcfbfb, 0xfffbfbfc, 0xfffbfcfc, + 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfc, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfc, 0xfffbfcfb, 0xfffbfbfb, + 0xfffbfbfb, 0xfffbfcfb, 0xfffcfbfb, 0xfffbfbfc, 0xfffbfbfb, 0xfffcfbfb, 0xfffcfbfb, 0xfffbfbfb, + 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfcfb, 0xfffbfbfb, + 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffcfbfb, + 0xfffbfbfc, 0xfffbfcfb, 0xfffbfcfb, 0xfffbfbfb, 0xfffbfbfb, 0xfffbfbfc, 0xfff7f8f7, 0xffe6ebe6, + 0xffdedfde, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848684, 0xffc5c6c5, 0xffc5c6c5, + 0xffe6ebe6, 0xfffafafb, 0xfffafafb, 0xfffafafa, 0xfffafbfa, 0xfffbfafb, 0xfffafafa, 0xfffafafa, + 0xfffafbfa, 0xfffbfafa, 0xfffbfafa, 0xfffafbfa, 0xfffbfafa, 0xfffbfafb, 0xfffafafa, 0xfffbfafa, + 0xfffafafa, 0xfffafafb, 0xfffbfafb, 0xfffafafa, 0xfffbfbfa, 0xfffafafa, 0xfffafbfb, 0xfffafbfb, + 0xfffafbfa, 0xfffafafb, 0xfffafbfa, 0xfffbfafa, 0xfffbfbfa, 0xfffafbfa, 0xfffbfafa, 0xfffafbfa, + 0xfffafafa, 0xfffbfafa, 0xfffafbfa, 0xfffbfafb, 0xfffafafb, 0xfffafafa, 0xfffafbfa, 0xfffbfbfb, + 0xfffafbfa, 0xfffbfafb, 0xfffafafa, 0xfffafbfb, 0xfffafbfa, 0xfffafafa, 0xfffafafb, 0xfffafbfb, + 0xfffbfafa, 0xfffafbfa, 0xfffafafb, 0xfffafafb, 0xfffafafb, 0xfffafafb, 0xfffbfbfb, 0xfffafafa, + 0xfffafafa, 0xfffafafb, 0xfffbfafa, 0xfffafbfa, 0xfffafbfa, 0xfffafbfa, 0xfffafafa, 0xfffbfbfa, + 0xfffafafa, 0xfffbfbfa, 0xfffbfafa, 0xfffbfafb, 0xfffafafa, 0xfffafbfa, 0xfffafafa, 0xfffafbfa, + 0xfffafafa, 0xfffafafa, 0xfffbfafb, 0xfffafafa, 0xfffafbfa, 0xfffafafa, 0xfffafafa, 0xfffafafa, + 0xfffbfbfa, 0xfffafafa, 0xfffbfafa, 0xfffafafb, 0xfffbfbfa, 0xfffafbfa, 0xfffafbfa, 0xfffafafa, + 0xfffafbfb, 0xfffbfbfa, 0xfffafafa, 0xfffafafa, 0xfffbfafb, 0xfffafafb, 0xfffafbfa, 0xfffafbfa, + 0xfffbfbfa, 0xfffbfbfb, 0xfffafbfa, 0xfffafafa, 0xfffbfbfa, 0xfffbfafa, 0xfffafbfa, 0xfffafafa, + 0xfffbfafb, 0xfffafafa, 0xfffbfafb, 0xfffbfbfb, 0xfffbfafb, 0xfffafafa, 0xfffafafa, 0xfffafbfa, + 0xfffafafa, 0xfffafafb, 0xfffafafb, 0xfffafafb, 0xfffbfafb, 0xfffbfafb, 0xfffafbfa, 0xfffbfafa, + 0xfffafafa, 0xfffafbfb, 0xfffbfafa, 0xfffafafb, 0xfffafbfb, 0xfffafbfa, 0xfffafafa, 0xfffbfbfa, + 0xfffafbfa, 0xfffafafa, 0xfffafafb, 0xfffbfafa, 0xfffafafa, 0xfffbfafa, 0xfffbfafb, 0xfffbfafb, + 0xfffafafa, 0xfffafbfa, 0xfffbfbfa, 0xfffafbfa, 0xfffbfbfa, 0xfffafbfa, 0xfffafbfb, 0xfffafbfa, + 0xfffbfbfb, 0xfffafbfb, 0xfffbfafb, 0xfffafafa, 0xfffafafa, 0xfffbfafa, 0xfffbfafa, 0xfffbfafb, + 0xfffbfbfa, 0xfffafbfa, 0xfffafafa, 0xfffafbfa, 0xfffbfafa, 0xfffafafb, 0xfffafbfa, 0xfffafafb, + 0xfffbfbfa, 0xfffbfafa, 0xfffbfbfa, 0xfffbfafb, 0xfffbfafa, 0xfffafafa, 0xfffafafa, 0xfffbfafb, + 0xfffafafa, 0xfffbfbfb, 0xfffbfafb, 0xfffafafb, 0xfffafafa, 0xfffbfafa, 0xfffbfafb, 0xfffbfafb, + 0xfffbfafa, 0xfffafafb, 0xfffbfafa, 0xfffafafb, 0xfffafafa, 0xfffafbfb, 0xfffbfbfa, 0xfffbfafa, + 0xfffafbfa, 0xfffafafa, 0xfffafbfa, 0xfffbfbfa, 0xfffafbfb, 0xfffafbfb, 0xfffbfafb, 0xfffafafa, + 0xfffafbfb, 0xfffafafb, 0xfffbfbfa, 0xfffafafa, 0xfffafafb, 0xfffafafa, 0xfffafafb, 0xfffafbfa, + 0xfffbfafa, 0xfffbfbfb, 0xfffafafb, 0xfffafbfb, 0xfffafbfb, 0xfffbfafa, 0xfffafbfb, 0xfffafafa, + 0xfffafafa, 0xfffafbfa, 0xfffbfafa, 0xfffafbfa, 0xfffbfafa, 0xfffbfafa, 0xfffafbfa, 0xfffbfafb, + 0xfffafbfa, 0xfffafafb, 0xfffbfafa, 0xfffbfafb, 0xfffafbfb, 0xfffbfbfa, 0xfff7f8f7, 0xffe6ebe6, + 0xffdedfde, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848684, 0xffc5c6c5, 0xffc5c6c5, + 0xffe6ebe6, 0xfffafafa, 0xfff9f9fa, 0xfffaf9fa, 0xfff9faf9, 0xfff9faf9, 0xfffafafa, 0xfff9f9f9, + 0xfffaf9f9, 0xfff9f9f9, 0xfff9f9f9, 0xfffaf9f9, 0xfff9fafa, 0xfff9fafa, 0xfff9f9fa, 0xfffafaf9, + 0xfff9faf9, 0xfffafafa, 0xfff9f9fa, 0xfff9f9f9, 0xfff9f9f9, 0xfffaf9fa, 0xfffaf9fa, 0xfff9f9f9, + 0xfffafaf9, 0xfff9f9f9, 0xfff9faf9, 0xfffaf9f9, 0xfffafaf9, 0xfffaf9f9, 0xfff9f9fa, 0xfff9f9f9, + 0xfffafafa, 0xfff9faf9, 0xfff9f9f9, 0xfff9fafa, 0xfffafaf9, 0xfff9f9fa, 0xfffaf9f9, 0xfff9f9fa, + 0xfff9faf9, 0xfffafafa, 0xfffafafa, 0xfffafaf9, 0xfff9faf9, 0xfff9f9f9, 0xfff9fafa, 0xfffafaf9, + 0xfffafaf9, 0xfffafafa, 0xfff9f9fa, 0xfffaf9fa, 0xfffafaf9, 0xfff9f9f9, 0xfffaf9f9, 0xfff9fafa, + 0xfff9fafa, 0xfff9faf9, 0xfffaf9f9, 0xfffaf9fa, 0xfffaf9f9, 0xfff9f9fa, 0xfffaf9f9, 0xfff9f9f9, + 0xfff9faf9, 0xfffaf9fa, 0xfffaf9f9, 0xfffaf9f9, 0xfff9faf9, 0xfffafafa, 0xfff9f9f9, 0xfff9f9fa, + 0xfffafafa, 0xfff9f9f9, 0xfffafaf9, 0xfffaf9f9, 0xfff9faf9, 0xfff9f9f9, 0xfffafaf9, 0xfff9f9fa, + 0xfff9faf9, 0xfff9fafa, 0xfffaf9fa, 0xfffafaf9, 0xfffafaf9, 0xfffaf9fa, 0xfff9f9fa, 0xfffaf9f9, + 0xfffaf9fa, 0xfff9fafa, 0xfffaf9f9, 0xfff9f9f9, 0xfffaf9f9, 0xfff9f9fa, 0xfffafafa, 0xfff9fafa, + 0xfff9f9fa, 0xfffaf9f9, 0xfffafaf9, 0xfffafaf9, 0xfff9faf9, 0xfff9f9fa, 0xfff9fafa, 0xfffaf9fa, + 0xfff9f9fa, 0xfffaf9f9, 0xfffafafa, 0xfff9faf9, 0xfffafaf9, 0xfffaf9f9, 0xfff9faf9, 0xfffaf9fa, + 0xfffafafa, 0xfffafaf9, 0xfff9faf9, 0xfffafaf9, 0xfffafafa, 0xfffafafa, 0xfff9f9f9, 0xfff9f9fa, + 0xfffaf9fa, 0xfff9f9f9, 0xfffafaf9, 0xfffafaf9, 0xfffafaf9, 0xfffaf9f9, 0xfffafafa, 0xfff9f9fa, + 0xfff9fafa, 0xfff9faf9, 0xfffaf9f9, 0xfffaf9fa, 0xfff9f9f9, 0xfff9fafa, 0xfff9f9fa, 0xfff9f9fa, + 0xfff9f9f9, 0xfffafaf9, 0xfff9f9f9, 0xfff9faf9, 0xfff9f9fa, 0xfffaf9fa, 0xfff9faf9, 0xfffafafa, + 0xfff9f9fa, 0xfffaf9fa, 0xfffafaf9, 0xfffaf9f9, 0xfffafafa, 0xfff9f9fa, 0xfffafaf9, 0xfffaf9f9, + 0xfff9faf9, 0xfffafaf9, 0xfff9faf9, 0xfff9f9f9, 0xfff9f9f9, 0xfff9f9f9, 0xfffafaf9, 0xfffaf9fa, + 0xfff9faf9, 0xfffaf9f9, 0xfffafaf9, 0xfffafaf9, 0xfff9fafa, 0xfffafafa, 0xfffaf9f9, 0xfff9fafa, + 0xfff9f9f9, 0xfffafaf9, 0xfffaf9fa, 0xfff9f9f9, 0xfff9faf9, 0xfffafaf9, 0xfff9f9fa, 0xfff9f9fa, + 0xfffafaf9, 0xfffaf9fa, 0xfff9fafa, 0xfff9f9f9, 0xfff9faf9, 0xfff9f9f9, 0xfff9f9fa, 0xfff9fafa, + 0xfff9f9fa, 0xfffafafa, 0xfff9f9fa, 0xfffaf9fa, 0xfff9f9fa, 0xfffafaf9, 0xfff9fafa, 0xfff9f9fa, + 0xfff9faf9, 0xfff9f9fa, 0xfff9fafa, 0xfffaf9f9, 0xfff9f9f9, 0xfffafafa, 0xfff9f9f9, 0xfff9faf9, + 0xfffafaf9, 0xfff9faf9, 0xfff9f9fa, 0xfffaf9f9, 0xfffaf9fa, 0xfff9f9fa, 0xfff9f9f9, 0xfff9fafa, + 0xfffafafa, 0xfffafafa, 0xfff9f9f9, 0xfffafafa, 0xfff9f9f9, 0xfffaf9fa, 0xfff9f9f9, 0xfff9fafa, + 0xfff9f9f9, 0xfff9f9f9, 0xfffaf9fa, 0xfffaf9f9, 0xfffaf9f9, 0xfffaf9f9, 0xfff7f8f7, 0xffe6ebe6, + 0xffdedfde, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff848684, 0xffc5c6c5, 0xffc5c6c5, + 0xffe6ebe6, 0xfff8f9f9, 0xfff9f8f8, 0xfff8f9f9, 0xfff9f8f9, 0xfff8f9f9, 0xfff9f8f9, 0xfff9f8f8, + 0xfff8f8f9, 0xfff9f9f9, 0xfff8f9f9, 0xfff8f8f9, 0xfff8f8f8, 0xfff9f8f8, 0xfff9f9f9, 0xfff9f9f8, + 0xfff9f9f9, 0xfff9f8f9, 0xfff8f9f9, 0xfff8f9f9, 0xfff9f9f8, 0xfff9f8f8, 0xfff8f9f8, 0xfff8f8f9, + 0xfff9f8f9, 0xfff8f9f8, 0xfff9f8f8, 0xfff9f9f8, 0xfff9f8f8, 0xfff9f8f8, 0xfff8f9f9, 0xfff9f9f9, + 0xfff9f8f8, 0xfff8f9f9, 0xfff8f8f9, 0xfff9f8f9, 0xfff9f9f8, 0xfff9f8f8, 0xfff8f9f8, 0xfff8f8f9, + 0xfff9f9f9, 0xfff9f9f9, 0xfff8f9f9, 0xfff8f9f8, 0xfff9f8f9, 0xfff9f9f9, 0xfff8f9f9, 0xfff8f9f8, + 0xfff9f8f9, 0xfff8f8f8, 0xfff8f9f9, 0xfff9f9f9, 0xfff8f8f8, 0xfff9f8f9, 0xfff8f8f8, 0xfff9f9f9, + 0xfff8f9f9, 0xfff8f9f9, 0xfff8f9f9, 0xfff8f9f9, 0xfff8f8f9, 0xfff8f8f9, 0xfff8f9f8, 0xfff8f8f8, + 0xfff9f8f8, 0xfff8f9f9, 0xfff8f9f9, 0xfff8f9f9, 0xfff8f9f9, 0xfff9f9f9, 0xfff9f9f8, 0xfff8f8f8, + 0xfff8f8f8, 0xfff9f9f9, 0xfff9f8f8, 0xfff9f8f8, 0xfff8f8f9, 0xfff9f8f9, 0xfff9f9f9, 0xfff9f9f8, + 0xfff9f8f8, 0xfff8f8f8, 0xfff8f9f9, 0xfff9f9f9, 0xfff8f9f8, 0xfff9f9f8, 0xfff8f9f9, 0xfff8f9f9, + 0xfff9f8f8, 0xfff9f9f9, 0xfff8f8f8, 0xfff8f8f8, 0xfff9f9f8, 0xfff9f9f8, 0xfff9f9f9, 0xfff9f9f8, + 0xfff8f9f9, 0xfff9f8f8, 0xfff8f8f8, 0xfff9f9f8, 0xfff8f8f8, 0xfff8f8f9, 0xfff8f8f9, 0xfff8f9f9, + 0xfff9f9f9, 0xfff9f9f9, 0xfff8f8f9, 0xfff9f8f9, 0xfff8f8f9, 0xfff8f8f9, 0xfff9f8f8, 0xfff9f9f9, + 0xfff9f9f9, 0xfff8f9f9, 0xfff9f9f8, 0xfff9f9f9, 0xfff9f8f8, 0xfff8f8f8, 0xfff9f8f9, 0xfff8f8f8, + 0xfff9f8f9, 0xfff9f8f9, 0xfff9f9f8, 0xfff8f8f8, 0xfff8f8f9, 0xfff9f8f9, 0xfff9f8f9, 0xfff8f8f8, + 0xfff8f8f9, 0xfff9f9f9, 0xfff8f8f8, 0xfff8f9f8, 0xfff9f9f8, 0xfff9f8f8, 0xfff9f8f9, 0xfff9f9f9, + 0xfff9f9f9, 0xfff9f9f8, 0xfff9f8f8, 0xfff9f9f9, 0xfff9f9f9, 0xfff9f8f8, 0xfff8f8f9, 0xfff8f9f8, + 0xfff8f9f8, 0xfff9f8f9, 0xfff9f9f8, 0xfff9f9f8, 0xfff9f8f8, 0xfff8f9f9, 0xfff8f8f9, 0xfff8f8f9, + 0xfff9f8f8, 0xfff9f8f9, 0xfff8f8f9, 0xfff9f9f9, 0xfff9f8f9, 0xfff8f8f8, 0xfff8f9f8, 0xfff9f8f9, + 0xfff9f8f8, 0xfff9f9f9, 0xfff8f8f8, 0xfff9f8f8, 0xfff9f9f9, 0xfff8f9f9, 0xfff8f9f9, 0xfff9f8f8, + 0xfff8f9f9, 0xfff8f9f8, 0xfff8f8f9, 0xfff9f8f8, 0xfff8f8f8, 0xfff9f9f9, 0xfff8f9f8, 0xfff8f9f8, + 0xfff9f8f8, 0xfff8f9f9, 0xfff8f8f8, 0xfff9f9f8, 0xfff9f9f8, 0xfff8f9f8, 0xfff9f8f8, 0xfff8f8f8, + 0xfff9f8f8, 0xfff9f9f9, 0xfff9f9f9, 0xfff9f8f8, 0xfff9f8f8, 0xfff9f9f8, 0xfff8f9f9, 0xfff9f8f9, + 0xfff8f8f9, 0xfff9f9f9, 0xfff9f9f8, 0xfff8f9f9, 0xfff8f9f9, 0xfff9f9f8, 0xfff9f8f9, 0xfff9f9f8, + 0xfff9f9f9, 0xfff9f8f9, 0xfff9f9f9, 0xfff8f8f9, 0xfff9f9f8, 0xfff8f9f9, 0xfff9f8f9, 0xfff9f9f9, + 0xfff9f9f8, 0xfff9f8f9, 0xfff8f8f8, 0xfff9f8f8, 0xfff8f8f9, 0xfff8f9f8, 0xfff8f8f8, 0xfff8f8f9, + 0xfff8f9f9, 0xfff9f9f9, 0xfff9f9f9, 0xfff8f9f8, 0xfff9f9f9, 0xfff9f8f8, 0xfff7f8f7, 0xffe6ebe6, + 0xffdedfde, 0x00000300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797d79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff7f8f7, 0xfff7f7f8, 0xfff8f8f8, 0xfff7f7f7, 0xfff8f7f8, 0xfff7f7f8, 0xfff8f8f8, + 0xfff8f8f8, 0xfff7f8f8, 0xfff7f7f8, 0xfff8f7f8, 0xfff7f8f8, 0xfff8f8f8, 0xfff8f7f7, 0xfff8f8f7, + 0xfff7f8f8, 0xfff7f7f7, 0xfff7f7f8, 0xfff8f7f8, 0xfff8f8f7, 0xfff8f7f7, 0xfff7f8f7, 0xfff8f8f8, + 0xfff8f7f7, 0xfff8f7f8, 0xfff8f7f8, 0xfff8f8f7, 0xfff8f7f7, 0xfff8f8f8, 0xfff7f8f7, 0xfff8f8f7, + 0xfff8f8f7, 0xfff7f8f8, 0xfff7f7f7, 0xfff8f7f8, 0xfff8f7f7, 0xfff7f8f8, 0xfff8f8f8, 0xfff7f7f7, + 0xfff7f8f8, 0xfff7f7f8, 0xfff7f8f8, 0xfff7f8f8, 0xfff7f8f8, 0xfff7f7f8, 0xfff8f8f8, 0xfff7f8f8, + 0xfff7f8f8, 0xfff8f8f8, 0xfff7f8f7, 0xfff8f8f7, 0xfff7f7f7, 0xfff8f8f8, 0xfff7f7f8, 0xfff8f7f7, + 0xfff7f8f7, 0xfff8f8f7, 0xfff7f8f7, 0xfff8f8f8, 0xfff7f7f7, 0xfff8f7f7, 0xfff8f8f7, 0xfff7f8f8, + 0xfff7f8f7, 0xfff8f7f8, 0xfff7f8f8, 0xfff8f8f7, 0xfff7f8f7, 0xfff8f8f7, 0xfff7f7f8, 0xfff8f7f8, + 0xfff8f8f8, 0xfff8f7f8, 0xfff7f8f8, 0xfff7f7f7, 0xfff7f8f7, 0xfff8f8f8, 0xfff7f7f8, 0xfff8f7f8, + 0xfff7f8f8, 0xfff8f8f7, 0xfff8f7f8, 0xfff8f8f8, 0xfff7f8f7, 0xfff8f7f8, 0xfff8f8f7, 0xfff7f8f8, + 0xfff7f7f8, 0xfff8f8f7, 0xfff8f8f7, 0xfff8f7f7, 0xfff7f7f7, 0xfff7f7f8, 0xfff7f8f8, 0xfff8f8f7, + 0xfff7f8f8, 0xfff8f7f8, 0xfff7f8f8, 0xfff8f8f8, 0xfff7f7f7, 0xfff7f8f7, 0xfff8f7f7, 0xfff8f7f8, + 0xfff8f8f7, 0xfff8f7f8, 0xfff8f7f7, 0xfff7f8f8, 0xfff7f7f8, 0xfff7f7f8, 0xfff8f7f8, 0xfff8f7f7, + 0xfff7f7f8, 0xfff8f8f8, 0xfff7f7f8, 0xfff7f7f7, 0xfff8f8f7, 0xfff7f8f8, 0xfff8f7f8, 0xfff7f8f8, + 0xfff8f7f7, 0xfff8f7f8, 0xfff8f8f7, 0xfff7f8f8, 0xfff8f8f7, 0xfff8f8f7, 0xfff7f8f8, 0xfff8f8f7, + 0xfff8f8f8, 0xfff7f7f8, 0xfff7f7f8, 0xfff8f8f8, 0xfff7f7f7, 0xfff8f8f7, 0xfff7f7f8, 0xfff7f8f8, + 0xfff7f7f7, 0xfff7f7f7, 0xfff7f8f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff8f8f8, 0xfff7f7f8, 0xfff8f8f8, + 0xfff7f8f8, 0xfff8f8f8, 0xfff7f8f8, 0xfff7f8f7, 0xfff8f7f8, 0xfff7f8f8, 0xfff8f7f8, 0xfff7f8f7, + 0xfff7f8f7, 0xfff8f8f7, 0xfff8f7f7, 0xfff8f7f8, 0xfff8f7f8, 0xfff7f8f8, 0xfff8f7f7, 0xfff8f8f8, + 0xfff8f7f8, 0xfff8f8f7, 0xfff8f7f8, 0xfff8f7f7, 0xfff7f8f8, 0xfff8f8f7, 0xfff8f7f7, 0xfff8f8f7, + 0xfff7f8f7, 0xfff7f8f8, 0xfff7f8f8, 0xfff8f8f8, 0xfff8f8f7, 0xfff7f8f8, 0xfff7f8f8, 0xfff7f8f7, + 0xfff8f8f8, 0xfff8f8f7, 0xfff8f8f8, 0xfff7f7f7, 0xfff7f7f8, 0xfff8f7f8, 0xfff8f8f8, 0xfff8f7f8, + 0xfff8f8f8, 0xfff7f8f7, 0xfff7f8f7, 0xfff8f7f7, 0xfff8f7f7, 0xfff8f8f8, 0xfff7f7f8, 0xfff8f7f7, + 0xfff8f8f8, 0xfff8f8f7, 0xfff8f7f7, 0xfff7f7f8, 0xfff7f8f8, 0xfff8f7f7, 0xfff8f7f7, 0xfff8f8f7, + 0xfff8f7f7, 0xfff8f8f8, 0xfff8f8f8, 0xfff8f7f7, 0xfff8f8f8, 0xfff7f8f8, 0xfff7f8f8, 0xfff7f7f8, + 0xfff7f8f7, 0xfff7f8f7, 0xfff8f8f7, 0xfff8f8f8, 0xfff8f8f8, 0xfff7f7f8, 0xfff7f8f8, 0xfff8f7f7, + 0xfff7f7f8, 0xfff8f7f7, 0xfff8f8f8, 0xfff7f8f7, 0xfff7f8f7, 0xfff8f8f8, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797d79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff6f7f7, 0xfff7f6f7, 0xfff7f6f7, 0xfff6f7f6, 0xfff7f6f7, 0xfff6f6f7, 0xfff6f7f7, + 0xfff6f6f7, 0xfff7f6f7, 0xfff7f7f7, 0xfff6f7f6, 0xfff7f7f7, 0xfff6f7f7, 0xfff7f6f6, 0xfff7f7f6, + 0xfff6f6f6, 0xfff7f7f7, 0xfff6f6f6, 0xfff6f7f6, 0xfff7f7f6, 0xfff7f7f7, 0xfff6f6f7, 0xfff7f7f6, + 0xfff7f7f7, 0xfff7f7f6, 0xfff6f6f6, 0xfff6f7f6, 0xfff7f7f6, 0xfff7f7f6, 0xfff7f6f7, 0xfff7f6f7, + 0xfff6f7f6, 0xfff6f6f7, 0xfff7f7f7, 0xfff6f6f6, 0xfff6f7f7, 0xfff6f6f6, 0xfff6f7f6, 0xfff6f7f7, + 0xfff7f6f7, 0xfff6f6f6, 0xfff7f7f6, 0xfff6f7f6, 0xfff6f7f7, 0xfff7f7f7, 0xfff7f7f6, 0xfff7f7f7, + 0xfff6f6f6, 0xfff6f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f6f7, 0xfff7f6f7, 0xfff7f7f7, 0xfff6f7f7, + 0xfff6f7f6, 0xfff6f6f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f6f6, 0xfff7f7f6, 0xfff7f7f7, + 0xfff7f7f6, 0xfff6f6f7, 0xfff6f6f7, 0xfff7f7f6, 0xfff7f6f7, 0xfff7f6f6, 0xfff7f7f6, 0xfff6f7f7, + 0xfff7f6f7, 0xfff7f6f7, 0xfff7f6f7, 0xfff6f6f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f6, 0xfff6f6f6, + 0xfff6f7f6, 0xfff6f6f7, 0xfff7f6f7, 0xfff7f7f6, 0xfff6f6f7, 0xfff7f7f7, 0xfff7f6f6, 0xfff7f6f7, + 0xfff6f6f6, 0xfff6f7f7, 0xfff7f6f7, 0xfff7f7f6, 0xfff7f6f7, 0xfff7f6f6, 0xfff7f6f7, 0xfff7f7f6, + 0xfff6f7f7, 0xfff7f6f6, 0xfff7f6f6, 0xfff7f6f6, 0xfff7f6f6, 0xfff6f7f7, 0xfff6f6f7, 0xfff7f6f7, + 0xfff6f7f7, 0xfff6f7f7, 0xfff6f7f6, 0xfff7f6f7, 0xfff7f7f6, 0xfff7f7f6, 0xfff6f7f7, 0xfff7f6f7, + 0xfff7f7f7, 0xfff7f7f6, 0xfff6f6f6, 0xfff7f7f7, 0xfff6f6f7, 0xfff7f7f7, 0xfff6f6f7, 0xfff6f6f6, + 0xfff6f6f7, 0xfff6f6f7, 0xfff7f6f7, 0xfff7f6f6, 0xfff7f6f6, 0xfff7f6f7, 0xfff7f7f6, 0xfff6f6f7, + 0xfff7f7f7, 0xfff6f7f6, 0xfff6f7f6, 0xfff7f7f7, 0xfff7f6f7, 0xfff6f6f6, 0xfff7f7f7, 0xfff7f6f7, + 0xfff7f7f6, 0xfff6f6f7, 0xfff7f6f7, 0xfff6f6f7, 0xfff6f7f6, 0xfff6f7f6, 0xfff6f6f7, 0xfff7f6f7, + 0xfff7f6f6, 0xfff7f6f6, 0xfff6f7f6, 0xfff7f7f7, 0xfff6f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f6f6, + 0xfff6f7f6, 0xfff7f6f6, 0xfff6f7f7, 0xfff6f6f6, 0xfff7f6f7, 0xfff6f7f7, 0xfff7f6f7, 0xfff7f7f7, + 0xfff6f6f6, 0xfff6f6f6, 0xfff6f7f6, 0xfff7f7f6, 0xfff7f6f7, 0xfff6f7f7, 0xfff6f6f6, 0xfff6f6f7, + 0xfff6f6f7, 0xfff6f7f7, 0xfff6f7f7, 0xfff6f7f7, 0xfff6f6f6, 0xfff6f7f7, 0xfff7f6f7, 0xfff7f7f7, + 0xfff6f7f7, 0xfff7f6f7, 0xfff6f6f6, 0xfff7f6f7, 0xfff6f7f6, 0xfff7f6f6, 0xfff6f7f7, 0xfff6f7f7, + 0xfff6f7f7, 0xfff6f7f6, 0xfff6f7f7, 0xfff6f7f7, 0xfff7f7f7, 0xfff7f6f6, 0xfff7f6f6, 0xfff7f6f7, + 0xfff7f7f6, 0xfff7f7f6, 0xfff7f6f7, 0xfff6f6f7, 0xfff7f6f7, 0xfff7f6f6, 0xfff7f7f7, 0xfff7f6f7, + 0xfff6f6f7, 0xfff7f7f6, 0xfff6f7f6, 0xfff6f7f6, 0xfff7f7f7, 0xfff7f6f7, 0xfff6f7f6, 0xfff7f6f6, + 0xfff6f6f7, 0xfff6f7f7, 0xfff7f6f7, 0xfff7f6f6, 0xfff6f6f7, 0xfff7f7f6, 0xfff6f6f7, 0xfff7f6f6, + 0xfff6f6f7, 0xfff6f6f7, 0xfff7f7f6, 0xfff6f7f7, 0xfff7f6f6, 0xfff7f7f7, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797d79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff6f6f6, 0xfff6f6f5, 0xfff6f5f6, 0xfff5f5f6, 0xfff6f5f6, 0xfff6f6f6, 0xfff5f6f5, + 0xfff6f6f5, 0xfff5f6f6, 0xfff6f6f5, 0xfff6f5f6, 0xfff6f5f5, 0xfff6f5f6, 0xfff5f6f6, 0xfff6f5f6, + 0xfff6f5f6, 0xfff5f5f6, 0xfff6f6f6, 0xfff6f5f6, 0xfff5f6f6, 0xfff6f5f5, 0xfff6f6f6, 0xfff6f5f6, + 0xfff6f5f6, 0xfff5f5f6, 0xfff6f6f5, 0xfff5f6f5, 0xfff6f6f6, 0xfff6f5f6, 0xfff6f6f6, 0xfff6f6f5, + 0xfff6f5f5, 0xfff5f5f6, 0xfff5f6f5, 0xfff5f6f5, 0xfff6f6f5, 0xfff5f5f6, 0xfff6f5f6, 0xfff6f6f6, + 0xfff5f6f6, 0xfff6f5f6, 0xfff5f5f6, 0xfff5f6f6, 0xfff5f6f5, 0xfff5f6f5, 0xfff6f6f6, 0xfff6f6f6, + 0xfff5f5f5, 0xfff5f6f6, 0xfff6f6f5, 0xfff5f5f6, 0xfff5f6f5, 0xfff6f6f6, 0xfff6f6f6, 0xfff5f6f6, + 0xfff5f5f6, 0xfff5f6f6, 0xfff5f5f6, 0xfff5f5f5, 0xfff6f5f5, 0xfff6f6f6, 0xfff5f5f5, 0xfff5f6f6, + 0xfff6f5f6, 0xfff6f6f5, 0xfff5f6f5, 0xfff5f6f5, 0xfff6f6f6, 0xfff5f6f6, 0xfff6f5f6, 0xfff5f5f5, + 0xfff6f5f6, 0xfff6f6f6, 0xfff6f6f6, 0xfff5f5f6, 0xfff6f5f6, 0xfff5f6f5, 0xfff6f5f6, 0xfff6f6f5, + 0xfff6f6f6, 0xfff6f5f6, 0xfff6f6f5, 0xfff5f6f6, 0xfff5f6f6, 0xfff5f6f5, 0xfff5f5f5, 0xfff6f6f5, + 0xfff6f6f6, 0xfff6f6f6, 0xfff5f6f5, 0xfff5f6f5, 0xfff5f5f6, 0xfff6f6f5, 0xfff6f5f5, 0xfff6f6f6, + 0xfff5f5f6, 0xfff6f5f6, 0xfff6f5f6, 0xfff6f5f6, 0xfff5f5f6, 0xfff6f6f5, 0xfff6f5f5, 0xfff6f6f5, + 0xfff6f6f6, 0xfff6f5f6, 0xfff5f6f6, 0xfff5f6f5, 0xfff6f6f6, 0xfff6f6f6, 0xfff6f5f6, 0xfff5f5f5, + 0xfff5f6f5, 0xfff5f5f6, 0xfff5f6f5, 0xfff6f6f6, 0xfff5f6f5, 0xfff6f5f5, 0xfff6f6f5, 0xfff6f6f5, + 0xfff5f6f6, 0xfff6f5f5, 0xfff6f6f6, 0xfff6f5f5, 0xfff5f5f6, 0xfff6f6f5, 0xfff5f6f6, 0xfff6f6f6, + 0xfff5f6f5, 0xfff5f5f5, 0xfff5f6f6, 0xfff6f6f6, 0xfff5f6f6, 0xfff6f6f5, 0xfff5f6f6, 0xfff5f6f5, + 0xfff6f5f6, 0xfff6f5f5, 0xfff5f6f6, 0xfff6f6f5, 0xfff5f6f5, 0xfff6f5f5, 0xfff5f5f5, 0xfff6f6f6, + 0xfff5f6f6, 0xfff5f6f5, 0xfff6f6f6, 0xfff5f6f6, 0xfff5f6f6, 0xfff6f5f6, 0xfff5f6f6, 0xfff6f6f6, + 0xfff6f5f5, 0xfff6f6f6, 0xfff6f6f6, 0xfff5f6f5, 0xfff6f6f6, 0xfff6f5f5, 0xfff6f6f5, 0xfff6f5f6, + 0xfff6f6f5, 0xfff5f6f5, 0xfff6f5f6, 0xfff5f6f5, 0xfff6f5f6, 0xfff5f6f5, 0xfff6f6f6, 0xfff6f6f5, + 0xfff6f5f6, 0xfff6f6f6, 0xfff5f6f6, 0xfff5f6f6, 0xfff6f6f5, 0xfff5f5f6, 0xfff5f6f5, 0xfff6f6f6, + 0xfff6f6f6, 0xfff6f6f5, 0xfff6f6f6, 0xfff6f5f6, 0xfff5f6f6, 0xfff5f5f6, 0xfff6f5f5, 0xfff5f6f6, + 0xfff5f6f6, 0xfff6f5f6, 0xfff5f5f5, 0xfff5f5f6, 0xfff5f6f6, 0xfff6f6f5, 0xfff6f6f6, 0xfff5f6f5, + 0xfff5f6f5, 0xfff6f5f6, 0xfff6f5f6, 0xfff6f6f6, 0xfff6f5f6, 0xfff6f6f5, 0xfff6f6f6, 0xfff6f5f6, + 0xfff6f6f5, 0xfff5f5f5, 0xfff5f6f5, 0xfff6f6f6, 0xfff6f5f6, 0xfff6f5f6, 0xfff6f6f5, 0xfff6f6f5, + 0xfff6f6f6, 0xfff5f6f5, 0xfff6f6f5, 0xfff6f6f5, 0xfff6f5f6, 0xfff6f6f6, 0xfff6f6f5, 0xfff5f6f6, + 0xfff6f6f6, 0xfff6f6f5, 0xfff6f5f5, 0xfff6f5f5, 0xfff6f6f6, 0xfff6f6f6, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797d79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff4f4f4, 0xfff5f5f5, 0xfff5f5f4, 0xfff5f4f5, 0xfff5f4f4, 0xfff5f4f4, 0xfff5f4f5, + 0xfff4f5f4, 0xfff4f4f5, 0xfff5f4f4, 0xfff5f4f4, 0xfff4f5f5, 0xfff5f5f4, 0xfff4f5f4, 0xfff4f4f5, + 0xfff5f4f5, 0xfff4f5f5, 0xfff5f4f4, 0xfff5f5f5, 0xfff4f5f5, 0xfff4f5f5, 0xfff4f4f5, 0xfff4f5f4, + 0xfff4f5f4, 0xfff5f5f4, 0xfff5f5f4, 0xfff4f5f4, 0xfff5f4f5, 0xfff5f5f5, 0xfff4f5f5, 0xfff4f5f5, + 0xfff5f5f4, 0xfff4f4f4, 0xfff4f5f4, 0xfff5f5f5, 0xfff5f5f5, 0xfff5f5f5, 0xfff4f5f4, 0xfff5f5f5, + 0xfff4f4f5, 0xfff5f5f5, 0xfff5f5f5, 0xfff4f4f5, 0xfff4f5f4, 0xfff5f5f4, 0xfff5f5f5, 0xfff5f4f4, + 0xfff5f4f5, 0xfff5f4f5, 0xfff4f5f4, 0xfff5f4f5, 0xfff5f5f4, 0xfff5f5f5, 0xfff4f4f5, 0xfff4f5f4, + 0xfff4f4f4, 0xfff4f5f4, 0xfff5f5f4, 0xfff5f5f4, 0xfff4f4f5, 0xfff4f5f5, 0xfff4f5f5, 0xfff4f5f4, + 0xfff5f5f5, 0xfff4f5f5, 0xfff4f5f5, 0xfff5f4f5, 0xfff4f4f5, 0xfff5f4f5, 0xfff4f5f5, 0xfff4f5f4, + 0xfff5f5f5, 0xfff5f5f5, 0xfff5f5f5, 0xfff4f5f5, 0xfff4f4f5, 0xfff4f4f4, 0xfff5f5f5, 0xfff5f5f5, + 0xfff4f5f5, 0xfff5f4f5, 0xfff4f5f5, 0xfff4f5f5, 0xfff5f4f5, 0xfff5f5f5, 0xfff5f4f5, 0xfff4f5f5, + 0xfff5f5f4, 0xfff4f4f4, 0xfff4f5f5, 0xfff4f4f4, 0xfff4f5f5, 0xfff5f5f4, 0xfff5f5f4, 0xfff4f5f5, + 0xfff4f4f4, 0xfff4f5f4, 0xfff4f5f5, 0xfff5f5f4, 0xfff4f5f5, 0xfff4f4f5, 0xfff5f5f4, 0xfff4f4f5, + 0xfff5f5f4, 0xfff4f4f5, 0xfff4f5f5, 0xfff4f5f4, 0xfff5f4f5, 0xfff5f5f5, 0xfff4f4f5, 0xfff5f4f5, + 0xfff5f5f5, 0xfff4f5f4, 0xfff5f5f5, 0xfff5f5f5, 0xfff4f5f5, 0xfff4f5f4, 0xfff4f4f5, 0xfff4f4f5, + 0xfff4f4f5, 0xfff5f4f5, 0xfff4f4f4, 0xfff5f5f5, 0xfff4f4f5, 0xfff5f5f5, 0xfff4f4f5, 0xfff5f4f4, + 0xfff4f4f4, 0xfff5f4f4, 0xfff5f5f5, 0xfff5f5f4, 0xfff5f5f5, 0xfff4f5f4, 0xfff5f5f5, 0xfff4f5f5, + 0xfff4f5f4, 0xfff5f4f4, 0xfff4f4f4, 0xfff5f5f4, 0xfff4f4f5, 0xfff5f4f5, 0xfff5f4f5, 0xfff5f4f5, + 0xfff5f5f5, 0xfff5f4f4, 0xfff4f5f4, 0xfff4f4f5, 0xfff5f5f5, 0xfff5f4f4, 0xfff5f5f5, 0xfff5f4f5, + 0xfff4f5f5, 0xfff4f5f5, 0xfff5f4f4, 0xfff5f5f5, 0xfff5f5f4, 0xfff5f4f4, 0xfff4f5f4, 0xfff5f4f4, + 0xfff5f5f4, 0xfff4f4f5, 0xfff5f4f4, 0xfff5f4f5, 0xfff4f5f5, 0xfff4f5f5, 0xfff5f5f5, 0xfff4f5f5, + 0xfff4f5f4, 0xfff4f5f5, 0xfff5f5f5, 0xfff4f4f5, 0xfff4f5f5, 0xfff4f5f5, 0xfff4f4f5, 0xfff4f5f5, + 0xfff5f4f4, 0xfff5f5f5, 0xfff4f5f4, 0xfff5f5f4, 0xfff5f4f4, 0xfff4f5f5, 0xfff4f5f5, 0xfff5f5f5, + 0xfff4f4f4, 0xfff5f5f5, 0xfff5f5f5, 0xfff4f5f5, 0xfff5f5f5, 0xfff4f4f5, 0xfff5f5f5, 0xfff4f5f5, + 0xfff4f5f4, 0xfff5f5f4, 0xfff5f5f5, 0xfff5f4f5, 0xfff5f4f4, 0xfff4f4f4, 0xfff5f5f4, 0xfff5f5f4, + 0xfff5f4f5, 0xfff5f5f4, 0xfff4f5f4, 0xfff4f5f4, 0xfff5f5f5, 0xfff4f4f5, 0xfff5f4f5, 0xfff4f5f5, + 0xfff5f5f4, 0xfff5f4f5, 0xfff5f5f5, 0xfff4f5f5, 0xfff4f4f5, 0xfff5f4f5, 0xfff4f4f5, 0xfff5f5f4, + 0xfff5f5f5, 0xfff4f5f5, 0xfff4f4f5, 0xfff5f5f5, 0xfff4f5f4, 0xfff4f5f5, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff797c79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff3f4f4, 0xfff4f3f3, 0xfff3f4f4, 0xfff4f4f4, 0xfff3f4f4, 0xfff3f3f4, 0xfff4f3f3, + 0xfff3f3f4, 0xfff3f3f3, 0xfff4f4f4, 0xfff4f4f3, 0xfff3f4f4, 0xfff4f3f4, 0xfff3f4f4, 0xfff3f3f4, + 0xfff3f3f3, 0xfff3f4f3, 0xfff4f4f3, 0xfff4f4f3, 0xfff4f4f4, 0xfff4f4f3, 0xfff4f4f4, 0xfff3f3f4, + 0xfff4f4f4, 0xfff3f3f3, 0xfff3f4f3, 0xfff3f4f3, 0xfff4f4f3, 0xfff3f4f4, 0xfff4f4f4, 0xfff4f4f3, + 0xfff4f4f3, 0xfff3f3f3, 0xfff3f3f4, 0xfff4f3f3, 0xfff4f4f4, 0xfff4f3f4, 0xfff3f3f3, 0xfff4f4f3, + 0xfff4f3f4, 0xfff3f4f3, 0xfff3f4f3, 0xfff4f3f4, 0xfff3f4f3, 0xfff4f4f4, 0xfff4f4f4, 0xfff4f3f4, + 0xfff4f4f4, 0xfff4f4f3, 0xfff4f3f3, 0xfff3f4f3, 0xfff3f4f3, 0xfff4f3f4, 0xfff3f4f4, 0xfff3f4f3, + 0xfff4f3f3, 0xfff4f3f4, 0xfff3f3f4, 0xfff4f4f4, 0xfff3f3f3, 0xfff4f3f3, 0xfff3f3f4, 0xfff3f3f3, + 0xfff4f3f3, 0xfff3f3f4, 0xfff4f3f3, 0xfff3f3f4, 0xfff3f4f4, 0xfff4f3f3, 0xfff3f3f3, 0xfff4f3f4, + 0xfff4f4f4, 0xfff3f4f4, 0xfff4f3f3, 0xfff3f3f4, 0xfff3f3f3, 0xfff4f4f3, 0xfff4f4f4, 0xfff4f3f3, + 0xfff3f4f4, 0xfff3f3f4, 0xfff3f3f4, 0xfff3f4f3, 0xfff3f4f3, 0xfff3f4f4, 0xfff4f3f4, 0xfff4f3f3, + 0xfff4f4f4, 0xfff4f4f4, 0xfff4f4f4, 0xfff3f4f4, 0xfff4f4f4, 0xfff3f4f3, 0xfff4f4f4, 0xfff4f3f4, + 0xfff3f3f3, 0xfff4f3f3, 0xfff4f3f3, 0xfff3f3f3, 0xfff3f4f3, 0xfff4f4f3, 0xfff3f3f3, 0xfff3f3f3, + 0xfff4f4f3, 0xfff3f3f3, 0xfff4f3f3, 0xfff4f4f4, 0xfff4f4f4, 0xfff3f3f4, 0xfff3f4f3, 0xfff4f3f4, + 0xfff4f3f4, 0xfff4f4f4, 0xfff3f3f3, 0xfff4f4f3, 0xfff4f3f3, 0xfff3f3f3, 0xfff4f4f4, 0xfff3f4f4, + 0xfff3f3f4, 0xfff3f3f4, 0xfff4f4f4, 0xfff3f4f4, 0xfff3f3f3, 0xfff4f3f4, 0xfff3f4f4, 0xfff4f4f4, + 0xfff4f4f4, 0xfff3f4f3, 0xfff3f4f4, 0xfff3f4f4, 0xfff3f4f3, 0xfff4f4f4, 0xfff4f4f3, 0xfff3f3f4, + 0xfff4f3f4, 0xfff3f3f3, 0xfff3f3f4, 0xfff4f4f4, 0xfff4f3f4, 0xfff3f3f3, 0xfff3f4f4, 0xfff3f3f3, + 0xfff4f3f4, 0xfff3f4f4, 0xfff4f3f4, 0xfff4f3f4, 0xfff4f4f4, 0xfff3f3f4, 0xfff4f3f3, 0xfff4f4f4, + 0xfff4f3f3, 0xfff3f4f4, 0xfff4f4f4, 0xfff3f4f3, 0xfff4f3f4, 0xfff4f4f4, 0xfff4f3f3, 0xfff3f3f4, + 0xfff4f3f3, 0xfff4f4f3, 0xfff3f4f3, 0xfff3f4f3, 0xfff4f4f3, 0xfff3f4f3, 0xfff4f4f4, 0xfff4f4f3, + 0xfff4f4f4, 0xfff4f4f3, 0xfff4f3f3, 0xfff4f3f4, 0xfff3f3f4, 0xfff3f4f3, 0xfff3f3f3, 0xfff4f4f4, + 0xfff3f3f4, 0xfff4f4f4, 0xfff4f3f3, 0xfff4f4f4, 0xfff4f4f3, 0xfff3f3f3, 0xfff4f4f4, 0xfff3f3f4, + 0xfff4f3f3, 0xfff4f3f3, 0xfff3f4f4, 0xfff3f4f3, 0xfff3f4f3, 0xfff4f4f4, 0xfff3f3f4, 0xfff4f4f3, + 0xfff3f3f4, 0xfff4f3f4, 0xfff3f4f4, 0xfff3f3f3, 0xfff3f3f4, 0xfff3f3f3, 0xfff4f4f4, 0xfff4f4f4, + 0xfff3f3f4, 0xfff3f4f3, 0xfff4f4f3, 0xfff3f4f3, 0xfff3f3f4, 0xfff4f4f4, 0xfff4f4f3, 0xfff3f4f4, + 0xfff3f3f3, 0xfff4f3f4, 0xfff4f3f3, 0xfff3f3f4, 0xfff4f4f3, 0xfff3f4f3, 0xfff3f3f4, 0xfff3f4f3, + 0xfff4f3f4, 0xfff4f3f4, 0xfff4f4f3, 0xfff4f3f3, 0xfff3f4f4, 0xfff3f4f3, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff797c79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff3f3f3, 0xfff2f3f2, 0xfff3f2f3, 0xfff2f3f2, 0xfff2f3f3, 0xfff3f2f2, 0xfff2f3f2, + 0xfff2f3f3, 0xfff3f3f2, 0xfff3f3f2, 0xfff3f2f3, 0xfff2f3f3, 0xfff3f2f3, 0xfff2f2f2, 0xfff2f3f3, + 0xfff2f3f3, 0xfff2f2f2, 0xfff2f3f2, 0xfff2f3f2, 0xfff2f2f3, 0xfff2f3f3, 0xfff2f3f2, 0xfff2f2f3, + 0xfff3f2f3, 0xfff3f2f3, 0xfff3f3f3, 0xfff2f2f2, 0xfff3f3f2, 0xfff3f2f3, 0xfff3f2f3, 0xfff2f2f3, + 0xfff2f3f3, 0xfff3f3f3, 0xfff3f2f3, 0xfff3f3f3, 0xfff2f3f2, 0xfff3f3f3, 0xfff3f2f3, 0xfff3f2f2, + 0xfff2f3f3, 0xfff2f2f3, 0xfff3f3f3, 0xfff2f2f3, 0xfff2f3f2, 0xfff2f2f3, 0xfff2f2f2, 0xfff3f2f3, + 0xfff2f2f3, 0xfff3f2f2, 0xfff2f3f2, 0xfff2f2f2, 0xfff2f3f3, 0xfff2f3f2, 0xfff2f2f3, 0xfff3f2f3, + 0xfff3f2f3, 0xfff2f3f2, 0xfff3f2f2, 0xfff3f2f3, 0xfff2f2f2, 0xfff3f2f2, 0xfff3f3f3, 0xfff3f3f2, + 0xfff2f3f3, 0xfff2f3f2, 0xfff3f3f2, 0xfff3f3f2, 0xfff2f2f2, 0xfff2f3f2, 0xfff2f3f3, 0xfff2f3f3, + 0xfff3f2f2, 0xfff3f2f2, 0xfff3f2f3, 0xfff3f3f3, 0xfff3f2f3, 0xfff2f3f2, 0xfff2f2f3, 0xfff2f2f2, + 0xfff3f3f2, 0xfff2f3f3, 0xfff2f3f3, 0xfff2f3f3, 0xfff3f2f3, 0xfff2f2f3, 0xfff2f2f3, 0xfff2f3f2, + 0xfff2f3f3, 0xfff2f3f2, 0xfff2f3f3, 0xfff3f2f2, 0xfff3f3f3, 0xfff2f2f2, 0xfff2f2f3, 0xfff2f2f3, + 0xfff3f2f2, 0xfff3f3f2, 0xfff3f3f3, 0xfff3f3f3, 0xfff3f3f2, 0xfff2f2f2, 0xfff3f3f3, 0xfff3f2f2, + 0xfff3f2f2, 0xfff2f3f3, 0xfff3f2f3, 0xfff2f3f2, 0xfff2f2f2, 0xfff2f2f2, 0xfff3f3f3, 0xfff3f2f3, + 0xfff3f2f3, 0xfff2f2f3, 0xfff3f2f2, 0xfff3f3f3, 0xfff2f3f3, 0xfff3f2f2, 0xfff3f2f3, 0xfff3f3f3, + 0xfff2f3f3, 0xfff2f2f3, 0xfff2f2f3, 0xfff2f2f2, 0xfff3f3f2, 0xfff3f2f2, 0xfff3f2f2, 0xfff2f2f3, + 0xfff2f3f2, 0xfff2f3f2, 0xfff3f2f3, 0xfff2f2f2, 0xfff3f2f3, 0xfff2f2f3, 0xfff2f3f2, 0xfff3f3f2, + 0xfff2f3f3, 0xfff3f2f3, 0xfff2f2f3, 0xfff3f3f3, 0xfff3f2f2, 0xfff2f2f3, 0xfff3f3f2, 0xfff3f2f2, + 0xfff3f2f3, 0xfff2f2f3, 0xfff3f3f2, 0xfff3f3f2, 0xfff3f2f3, 0xfff2f3f2, 0xfff2f2f2, 0xfff3f2f2, + 0xfff2f3f3, 0xfff3f2f2, 0xfff2f2f3, 0xfff3f3f2, 0xfff3f2f2, 0xfff3f2f2, 0xfff3f3f3, 0xfff2f3f2, + 0xfff2f3f3, 0xfff2f3f3, 0xfff2f3f2, 0xfff3f2f3, 0xfff2f2f2, 0xfff2f3f2, 0xfff2f2f3, 0xfff3f3f3, + 0xfff3f2f3, 0xfff2f3f2, 0xfff3f2f2, 0xfff3f2f2, 0xfff3f2f2, 0xfff3f3f3, 0xfff3f3f3, 0xfff3f3f2, + 0xfff3f3f3, 0xfff3f2f2, 0xfff2f3f2, 0xfff3f2f3, 0xfff3f2f2, 0xfff2f2f3, 0xfff3f2f2, 0xfff3f2f3, + 0xfff2f2f3, 0xfff2f3f3, 0xfff2f2f2, 0xfff2f3f3, 0xfff2f2f3, 0xfff3f3f3, 0xfff2f3f2, 0xfff3f2f2, + 0xfff2f2f2, 0xfff3f2f3, 0xfff3f2f2, 0xfff2f2f3, 0xfff2f2f3, 0xfff3f2f3, 0xfff2f2f3, 0xfff2f3f2, + 0xfff3f3f3, 0xfff3f3f3, 0xfff3f2f2, 0xfff2f2f2, 0xfff2f3f3, 0xfff3f2f3, 0xfff2f3f2, 0xfff3f3f2, + 0xfff2f2f2, 0xfff3f3f2, 0xfff2f2f2, 0xfff2f3f3, 0xfff2f2f3, 0xfff3f2f3, 0xfff3f2f3, 0xfff3f2f3, + 0xfff3f3f2, 0xfff3f3f2, 0xfff3f3f2, 0xfff3f2f3, 0xfff3f2f3, 0xfff2f3f3, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff797c79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff2f1f2, 0xfff1f1f1, 0xfff2f2f1, 0xfff1f2f2, 0xfff2f2f2, 0xfff1f2f1, 0xfff1f1f2, + 0xfff2f2f2, 0xfff1f2f1, 0xfff1f2f2, 0xfff1f2f2, 0xfff1f2f2, 0xfff2f1f1, 0xfff2f1f2, 0xfff1f2f1, + 0xfff2f2f1, 0xfff1f1f1, 0xfff2f2f1, 0xfff1f1f1, 0xfff2f1f1, 0xfff2f1f1, 0xfff1f1f1, 0xfff2f1f2, + 0xfff1f2f2, 0xfff2f1f1, 0xfff1f2f2, 0xfff1f1f2, 0xfff1f1f1, 0xfff1f1f2, 0xfff1f2f1, 0xfff2f1f1, + 0xfff2f2f1, 0xfff1f1f1, 0xfff1f2f2, 0xfff1f2f2, 0xfff1f1f2, 0xfff1f2f2, 0xfff1f2f1, 0xfff1f1f1, + 0xfff1f2f2, 0xfff2f1f1, 0xfff2f2f2, 0xfff1f2f2, 0xfff2f2f1, 0xfff2f1f2, 0xfff2f1f2, 0xfff1f2f1, + 0xfff1f2f2, 0xfff1f1f2, 0xfff2f2f2, 0xfff1f1f2, 0xfff2f2f1, 0xfff1f2f1, 0xfff2f2f1, 0xfff1f2f2, + 0xfff1f2f1, 0xfff2f2f2, 0xfff1f1f1, 0xfff1f1f2, 0xfff1f1f2, 0xfff2f1f2, 0xfff1f1f2, 0xfff2f1f1, + 0xfff1f2f1, 0xfff2f1f1, 0xfff1f2f1, 0xfff1f2f2, 0xfff2f1f2, 0xfff1f1f1, 0xfff2f1f1, 0xfff2f1f2, + 0xfff1f2f1, 0xfff2f2f1, 0xfff2f1f1, 0xfff1f2f2, 0xfff1f1f1, 0xfff1f1f1, 0xfff2f1f2, 0xfff2f1f2, + 0xfff1f2f2, 0xfff1f1f2, 0xfff2f2f2, 0xfff2f1f1, 0xfff2f2f1, 0xfff2f2f1, 0xfff2f1f1, 0xfff1f2f1, + 0xfff2f1f1, 0xfff1f2f1, 0xfff2f1f1, 0xfff2f2f1, 0xfff1f1f2, 0xfff2f1f1, 0xfff2f1f2, 0xfff1f1f1, + 0xfff1f2f1, 0xfff2f1f1, 0xfff1f2f2, 0xfff2f2f2, 0xfff1f1f1, 0xfff1f1f1, 0xfff1f2f1, 0xfff1f1f1, + 0xfff1f1f2, 0xfff1f2f2, 0xfff1f2f1, 0xfff2f1f1, 0xfff1f1f1, 0xfff1f2f1, 0xfff1f1f2, 0xfff1f1f2, + 0xfff2f1f1, 0xfff1f1f1, 0xfff1f2f2, 0xfff1f1f2, 0xfff2f1f1, 0xfff2f2f1, 0xfff2f2f2, 0xfff2f1f1, + 0xfff1f1f1, 0xfff1f1f2, 0xfff1f1f1, 0xfff2f1f2, 0xfff1f1f1, 0xfff1f1f2, 0xfff1f2f1, 0xfff2f1f1, + 0xfff1f2f2, 0xfff1f1f2, 0xfff2f1f2, 0xfff1f1f2, 0xfff2f1f1, 0xfff2f1f1, 0xfff2f2f1, 0xfff1f1f1, + 0xfff2f2f1, 0xfff1f1f1, 0xfff1f2f2, 0xfff2f1f2, 0xfff2f1f1, 0xfff1f1f1, 0xfff1f2f1, 0xfff1f2f1, + 0xfff2f2f1, 0xfff1f1f1, 0xfff2f1f1, 0xfff1f2f2, 0xfff1f1f1, 0xfff1f2f2, 0xfff2f2f2, 0xfff2f1f2, + 0xfff2f1f1, 0xfff2f2f1, 0xfff1f1f2, 0xfff1f2f2, 0xfff2f2f1, 0xfff2f1f2, 0xfff2f1f1, 0xfff1f2f1, + 0xfff1f2f2, 0xfff2f2f1, 0xfff2f2f1, 0xfff2f1f2, 0xfff1f1f2, 0xfff2f2f2, 0xfff1f2f2, 0xfff2f1f2, + 0xfff1f2f1, 0xfff1f2f2, 0xfff1f2f2, 0xfff1f2f1, 0xfff1f2f1, 0xfff1f2f2, 0xfff1f1f1, 0xfff2f2f2, + 0xfff1f1f2, 0xfff2f1f2, 0xfff1f1f1, 0xfff1f2f1, 0xfff1f1f1, 0xfff1f2f1, 0xfff1f2f2, 0xfff2f1f1, + 0xfff2f1f1, 0xfff1f2f2, 0xfff1f2f2, 0xfff2f1f1, 0xfff2f1f2, 0xfff1f2f2, 0xfff2f1f1, 0xfff1f1f1, + 0xfff2f1f1, 0xfff2f1f2, 0xfff2f1f1, 0xfff1f1f2, 0xfff2f2f1, 0xfff1f1f1, 0xfff1f1f2, 0xfff2f1f1, + 0xfff2f1f2, 0xfff2f2f2, 0xfff1f2f2, 0xfff2f2f2, 0xfff1f2f1, 0xfff1f1f2, 0xfff2f2f2, 0xfff1f1f1, + 0xfff1f2f2, 0xfff2f1f1, 0xfff2f1f1, 0xfff2f1f2, 0xfff1f1f2, 0xfff2f1f2, 0xfff1f1f2, 0xfff1f1f1, + 0xfff2f1f2, 0xfff1f2f2, 0xfff1f1f2, 0xfff2f1f1, 0xfff2f1f1, 0xfff2f1f2, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff797c79, 0xffb5bab5, 0xffb5bab5, + 0xffdedbde, 0xfff1f0f0, 0xfff1f1f1, 0xfff1f0f0, 0xfff0f1f0, 0xfff0f0f1, 0xfff1f0f1, 0xfff0f0f1, + 0xfff0f1f1, 0xfff0f1f0, 0xfff1f1f1, 0xfff0f1f1, 0xfff1f1f1, 0xfff1f0f0, 0xfff1f0f0, 0xfff0f1f1, + 0xfff0f0f0, 0xfff0f1f0, 0xfff0f1f0, 0xfff1f1f0, 0xfff0f0f0, 0xfff1f0f0, 0xfff0f1f1, 0xfff1f1f0, + 0xfff0f1f0, 0xfff1f0f1, 0xfff0f1f1, 0xfff1f0f0, 0xfff1f1f1, 0xfff1f0f0, 0xfff1f0f0, 0xfff1f0f1, + 0xfff0f1f1, 0xfff1f1f1, 0xfff1f1f0, 0xfff1f0f1, 0xfff0f0f0, 0xfff1f1f1, 0xfff0f0f1, 0xfff0f1f0, + 0xfff1f1f0, 0xfff0f0f0, 0xfff0f1f1, 0xfff0f1f1, 0xfff1f1f0, 0xfff0f1f1, 0xfff1f1f1, 0xfff1f0f0, + 0xfff1f0f1, 0xfff1f0f1, 0xfff0f0f1, 0xfff1f1f0, 0xfff0f0f0, 0xfff0f1f0, 0xfff1f1f0, 0xfff0f0f1, + 0xfff1f0f0, 0xfff1f1f1, 0xfff1f1f1, 0xfff0f0f0, 0xfff0f0f0, 0xfff1f1f1, 0xfff1f0f0, 0xfff0f1f1, + 0xfff1f1f0, 0xfff1f0f0, 0xfff1f0f0, 0xfff1f0f1, 0xfff0f0f1, 0xfff0f0f1, 0xfff1f0f1, 0xfff1f0f1, + 0xfff1f1f1, 0xfff0f1f1, 0xfff0f0f1, 0xfff1f0f1, 0xfff0f1f1, 0xfff0f0f0, 0xfff1f1f1, 0xfff1f1f0, + 0xfff1f1f1, 0xfff1f0f0, 0xfff0f0f0, 0xfff1f0f1, 0xfff0f0f1, 0xfff0f0f0, 0xfff1f0f1, 0xfff1f1f0, + 0xfff1f0f0, 0xfff1f0f0, 0xfff0f0f0, 0xfff1f1f0, 0xfff0f0f1, 0xfff0f0f1, 0xfff1f0f0, 0xfff1f1f1, + 0xfff1f0f1, 0xfff0f0f1, 0xfff0f0f1, 0xfff0f0f0, 0xfff1f0f0, 0xfff0f0f0, 0xfff0f0f1, 0xfff1f1f1, + 0xfff0f0f0, 0xfff0f1f0, 0xfff0f0f0, 0xfff1f0f1, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f1f0, 0xfff0f1f0, + 0xfff1f1f0, 0xfff1f1f1, 0xfff0f1f1, 0xfff1f0f0, 0xfff0f0f0, 0xfff1f0f0, 0xfff0f0f0, 0xfff0f0f1, + 0xfff0f0f1, 0xfff1f1f1, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f1f0, 0xfff0f1f1, 0xfff1f0f0, 0xfff1f1f1, + 0xfff0f0f0, 0xfff0f1f0, 0xfff0f1f0, 0xfff1f0f0, 0xfff1f0f0, 0xfff0f1f1, 0xfff0f0f1, 0xfff1f0f0, + 0xfff0f0f1, 0xfff0f0f1, 0xfff0f0f1, 0xfff1f1f0, 0xfff1f0f0, 0xfff1f0f0, 0xfff0f1f0, 0xfff0f0f0, + 0xfff0f1f1, 0xfff0f0f0, 0xfff0f1f1, 0xfff0f0f1, 0xfff0f1f1, 0xfff1f1f0, 0xfff1f0f0, 0xfff1f1f0, + 0xfff0f0f0, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f0f1, 0xfff1f0f0, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f1f0, + 0xfff0f1f0, 0xfff0f0f1, 0xfff1f0f1, 0xfff0f1f1, 0xfff1f1f0, 0xfff1f1f1, 0xfff1f0f0, 0xfff0f0f0, + 0xfff0f0f1, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f1f0, 0xfff1f0f1, 0xfff0f1f0, 0xfff0f1f1, 0xfff0f0f0, + 0xfff0f0f0, 0xfff0f0f0, 0xfff1f0f0, 0xfff0f1f1, 0xfff1f1f0, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f0f1, + 0xfff0f0f1, 0xfff1f0f0, 0xfff0f1f1, 0xfff0f1f1, 0xfff1f1f0, 0xfff1f1f0, 0xfff0f1f0, 0xfff1f0f1, + 0xfff0f0f1, 0xfff1f1f0, 0xfff0f0f1, 0xfff0f1f0, 0xfff0f1f1, 0xfff1f0f0, 0xfff0f0f1, 0xfff1f1f0, + 0xfff0f1f0, 0xfff0f0f0, 0xfff0f0f1, 0xfff0f1f1, 0xfff0f0f1, 0xfff1f0f1, 0xfff1f1f0, 0xfff1f0f1, + 0xfff1f0f0, 0xfff0f0f1, 0xfff0f1f0, 0xfff0f0f1, 0xfff1f0f1, 0xfff1f0f0, 0xfff1f0f0, 0xfff0f0f1, + 0xfff0f0f0, 0xfff0f0f1, 0xfff1f0f0, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f1f1, 0xffe9e8e9, 0xffdedbde, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xfff0eff0, 0xffefeff0, 0xfff0f0ef, 0xfff0eff0, 0xfff0eff0, 0xffefefef, 0xffeff0f0, + 0xfff0efef, 0xffefefef, 0xffefefef, 0xfff0efef, 0xffefeff0, 0xfff0efef, 0xffeff0f0, 0xfff0efef, + 0xffefefef, 0xffefefef, 0xffeff0f0, 0xfff0efef, 0xffefefef, 0xffeff0f0, 0xffefeff0, 0xffefefef, + 0xfff0f0f0, 0xfff0eff0, 0xfff0efef, 0xfff0eff0, 0xfff0efef, 0xfff0f0ef, 0xfff0eff0, 0xfff0efef, + 0xffeff0f0, 0xffefeff0, 0xfff0efef, 0xfff0f0ef, 0xffefeff0, 0xffeff0f0, 0xfff0f0f0, 0xfff0efef, + 0xfff0f0ef, 0xffefefef, 0xffeff0f0, 0xfff0f0ef, 0xffefefef, 0xffefefef, 0xffefefef, 0xfff0eff0, + 0xffefefef, 0xffefefef, 0xfff0eff0, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xfff0efef, + 0xfff0efef, 0xfff0f0f0, 0xffeff0ef, 0xffeff0f0, 0xfff0f0f0, 0xffefefef, 0xffefefef, 0xfff0f0f0, + 0xffefefef, 0xffefefef, 0xffefefef, 0xfff0efef, 0xfff0f0f0, 0xfff0f0f0, 0xfff0efef, 0xffeff0f0, + 0xfff0efef, 0xffefeff0, 0xfff0eff0, 0xffeff0ef, 0xfff0eff0, 0xfff0eff0, 0xfff0eff0, 0xffeff0f0, + 0xffeff0ef, 0xfff0eff0, 0xffeff0f0, 0xfff0eff0, 0xffefefef, 0xfff0efef, 0xfff0f0ef, 0xffefefef, + 0xffeff0f0, 0xffeff0ef, 0xffefeff0, 0xffeff0ef, 0xffeff0ef, 0xffefeff0, 0xfff0f0f0, 0xffefefef, + 0xffefeff0, 0xfff0f0ef, 0xfff0efef, 0xfff0efef, 0xffefeff0, 0xfff0f0ef, 0xffeff0ef, 0xffefefef, + 0xfff0efef, 0xffefefef, 0xffefefef, 0xfff0f0f0, 0xfff0f0ef, 0xfff0f0ef, 0xffeff0f0, 0xfff0f0ef, + 0xffefefef, 0xfff0eff0, 0xfff0efef, 0xfff0efef, 0xffefeff0, 0xfff0efef, 0xffeff0f0, 0xfff0f0ef, + 0xffeff0f0, 0xffefefef, 0xffefeff0, 0xfff0eff0, 0xfff0efef, 0xfff0f0f0, 0xfff0efef, 0xfff0f0ef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffeff0f0, 0xfff0eff0, 0xffefeff0, 0xffeff0ef, 0xffefefef, + 0xffeff0f0, 0xffefeff0, 0xffefeff0, 0xffefeff0, 0xffeff0ef, 0xffefeff0, 0xffeff0ef, 0xfff0eff0, + 0xffeff0ef, 0xfff0eff0, 0xfff0efef, 0xfff0f0ef, 0xffeff0f0, 0xfff0efef, 0xffeff0f0, 0xfff0f0ef, + 0xfff0efef, 0xfff0efef, 0xffefefef, 0xffefeff0, 0xffefefef, 0xfff0efef, 0xffefefef, 0xfff0efef, + 0xfff0f0f0, 0xfff0f0ef, 0xfff0efef, 0xfff0eff0, 0xffefeff0, 0xffefefef, 0xffeff0ef, 0xffeff0ef, + 0xffefeff0, 0xffeff0ef, 0xfff0f0ef, 0xfff0efef, 0xffeff0ef, 0xfff0f0f0, 0xfff0f0ef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffeff0ef, 0xfff0f0ef, 0xffefeff0, 0xffefeff0, 0xffefefef, 0xffefefef, + 0xffefeff0, 0xfff0eff0, 0xffeff0f0, 0xffeff0ef, 0xffefefef, 0xffeff0ef, 0xffeff0ef, 0xfff0f0f0, + 0xfff0f0f0, 0xfff0eff0, 0xfff0efef, 0xffefefef, 0xfff0eff0, 0xffeff0f0, 0xffefeff0, 0xffefeff0, + 0xfff0f0ef, 0xfff0f0ef, 0xffefefef, 0xffefeff0, 0xfff0efef, 0xfff0f0f0, 0xfff0efef, 0xffefefef, + 0xfff0eff0, 0xffefefef, 0xffefeff0, 0xffeff0ef, 0xfff0efef, 0xffefefef, 0xffefeff0, 0xffeff0f0, + 0xffeff0ef, 0xfff0f0ef, 0xffeff0ef, 0xffefefef, 0xffefeff0, 0xffefefef, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffefeeee, 0xffeeeeee, 0xffeeefee, 0xffeeeeee, 0xffeeeeef, 0xffeeeeee, 0xffefefee, + 0xffeeefef, 0xffeeefee, 0xffefefee, 0xffefefee, 0xffefefee, 0xffeeefee, 0xffeeeeee, 0xffeeeeee, + 0xffefefef, 0xffeeeeee, 0xffeeeeee, 0xffeeeeef, 0xffefeeee, 0xffefefee, 0xffeeefee, 0xffeeeeee, + 0xffeeeeee, 0xffeeefef, 0xffeeeeee, 0xffeeefee, 0xffeeefef, 0xffefeeee, 0xffefeeee, 0xffeeeeef, + 0xffeeeeee, 0xffeeefee, 0xffeeeeef, 0xffeeeeee, 0xffeeeeef, 0xffeeefee, 0xffefeeef, 0xffefeeee, + 0xffeeefee, 0xffefeeef, 0xffefeeee, 0xffefefee, 0xffefefef, 0xffefeeef, 0xffefefef, 0xffeeeeee, + 0xffeeefee, 0xffeeefee, 0xffeeeeee, 0xffeeeeee, 0xffefeeef, 0xffeeefef, 0xffefeeee, 0xffeeefee, + 0xffeeeeee, 0xffeeefef, 0xffeeefee, 0xffefeeee, 0xffeeefef, 0xffeeeeef, 0xffeeefee, 0xffefeeef, + 0xffeeefee, 0xffefefee, 0xffeeefee, 0xffeeefee, 0xffeeefee, 0xffeeefef, 0xffefeeef, 0xffeeefee, + 0xffefefef, 0xffeeeeef, 0xffefefee, 0xffeeeeee, 0xffefefee, 0xffefeeef, 0xffefeeee, 0xffefefee, + 0xffeeefee, 0xffeeefee, 0xffeeeeef, 0xffeeeeee, 0xffefeeef, 0xffeeeeef, 0xffeeeeee, 0xffeeefee, + 0xffeeeeef, 0xffefeeef, 0xffeeeeef, 0xffeeefef, 0xffefefef, 0xffefefee, 0xffefeeef, 0xffeeeeef, + 0xffeeeeee, 0xffeeefee, 0xffefeeee, 0xffeeeeee, 0xffeeeeef, 0xffeeeeee, 0xffefefef, 0xffefeeee, + 0xffefeeee, 0xffeeefef, 0xffeeeeef, 0xffefeeee, 0xffefeeee, 0xffefeeef, 0xffeeeeee, 0xffeeeeee, + 0xffefefef, 0xffeeefef, 0xffefeeee, 0xffefefef, 0xffeeeeee, 0xffefeeee, 0xffeeeeee, 0xffeeeeee, + 0xffefeeef, 0xffeeefee, 0xffeeeeee, 0xffeeefef, 0xffeeeeee, 0xffeeefef, 0xffeeeeef, 0xffeeeeee, + 0xffefefef, 0xffeeefee, 0xffeeefef, 0xffeeeeef, 0xffeeeeef, 0xffefefee, 0xffefeeef, 0xffeeeeee, + 0xffeeeeee, 0xffefefef, 0xffeeeeef, 0xffefeeef, 0xffeeeeee, 0xffeeefee, 0xffefefef, 0xffefeeee, + 0xffeeefef, 0xffeeefef, 0xffefefef, 0xffeeeeef, 0xffeeeeee, 0xffefeeee, 0xffeeeeee, 0xffeeeeee, + 0xffeeeeee, 0xffeeefee, 0xffeeeeee, 0xffefeeee, 0xffefefef, 0xffeeefee, 0xffefeeee, 0xffeeefef, + 0xffefeeee, 0xffefeeee, 0xffeeeeee, 0xffeeeeee, 0xffefeeef, 0xffefeeee, 0xffefeeee, 0xffeeefef, + 0xffeeefee, 0xffeeefee, 0xffeeeeee, 0xffefefef, 0xffeeefee, 0xffefeeee, 0xffeeeeee, 0xffefefee, + 0xffefefee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeefee, 0xffeeeeef, 0xffefeeef, 0xffefeeee, + 0xffeeeeee, 0xffefefee, 0xffefefee, 0xffeeefee, 0xffefefee, 0xffefeeee, 0xffeeefef, 0xffeeefee, + 0xffeeeeee, 0xffeeeeef, 0xffeeeeef, 0xffeeeeee, 0xffeeeeef, 0xffefeeef, 0xffefeeee, 0xffeeefef, + 0xffeeeeee, 0xffefefee, 0xffeeeeee, 0xffefeeef, 0xffeeefef, 0xffeeeeee, 0xffeeeeee, 0xffeeeeef, + 0xffefeeef, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffefeeef, 0xffefeeef, 0xffeeeeee, 0xffeeeeef, + 0xffefefee, 0xffeeeeee, 0xffefefef, 0xffeeefee, 0xffeeeeef, 0xffeeeeef, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffeeeded, 0xffeeedee, 0xffeeeded, 0xffeeeded, 0xffededed, 0xffedeeed, 0xffedeeed, + 0xffedeeee, 0xffeeeded, 0xffedeeee, 0xffedeeed, 0xffeeedee, 0xffeeeeed, 0xffededed, 0xffeeeded, + 0xffeeeded, 0xffededee, 0xffeeeded, 0xffededed, 0xffededed, 0xffedeeed, 0xffeeedee, 0xffeeeded, + 0xffededee, 0xffeeeded, 0xffededed, 0xffededee, 0xffeeeeed, 0xffededed, 0xffededed, 0xffeeedee, + 0xffeeeded, 0xffedeeed, 0xffedeeed, 0xffededed, 0xffededed, 0xffeeeded, 0xffededed, 0xffededed, + 0xffeeeeed, 0xffedeeed, 0xffededed, 0xffedeeed, 0xffededed, 0xffeeeeed, 0xffeeeded, 0xffeeeded, + 0xffeeeeed, 0xffeeedee, 0xffeeeded, 0xffeeeeee, 0xffedeeed, 0xffeeeded, 0xffedeeee, 0xffededee, + 0xffeeeded, 0xffeeedee, 0xffedeeee, 0xffededee, 0xffededed, 0xffedeeee, 0xffeeeded, 0xffeeedee, + 0xffededed, 0xffeeedee, 0xffedeeee, 0xffeeedee, 0xffeeeeee, 0xffededee, 0xffededee, 0xffeeedee, + 0xffedeeed, 0xffededed, 0xffeeeded, 0xffeeedee, 0xffededee, 0xffeeeded, 0xffededee, 0xffededed, + 0xffedeeed, 0xffedeeed, 0xffededed, 0xffededed, 0xffededed, 0xffededed, 0xffedeeee, 0xffededee, + 0xffeeeded, 0xffededed, 0xffeeeded, 0xffededed, 0xffedeeed, 0xffeeedee, 0xffededed, 0xffedeeed, + 0xffeeedee, 0xffededed, 0xffeeedee, 0xffededed, 0xffededed, 0xffeeedee, 0xffedeeed, 0xffeeeded, + 0xffedeeed, 0xffededee, 0xffeeedee, 0xffeeeeed, 0xffedeeed, 0xffeeeeed, 0xffededee, 0xffededee, + 0xffedeeed, 0xffeeeded, 0xffededed, 0xffedeeed, 0xffeeeeee, 0xffeeeded, 0xffeeeeed, 0xffeeeded, + 0xffeeedee, 0xffededed, 0xffeeeded, 0xffeeeeed, 0xffededee, 0xffeeeeee, 0xffededed, 0xffeeeeed, + 0xffeeeded, 0xffeeedee, 0xffededed, 0xffeeedee, 0xffeeeeed, 0xffedeeee, 0xffeeedee, 0xffededed, + 0xffeeeeed, 0xffededed, 0xffeeeded, 0xffededed, 0xffededee, 0xffedeeed, 0xffeeeeed, 0xffeeeeee, + 0xffedeeee, 0xffededed, 0xffeeeded, 0xffeeeeee, 0xffeeedee, 0xffededed, 0xffeeedee, 0xffedeeed, + 0xffeeeeed, 0xffededed, 0xffededed, 0xffedeeee, 0xffedeeed, 0xffedeeed, 0xffededee, 0xffeeeeee, + 0xffededed, 0xffeeeeee, 0xffedeeed, 0xffeeeded, 0xffeeeeed, 0xffeeeeee, 0xffedeeed, 0xffeeedee, + 0xffedeeee, 0xffededee, 0xffeeeded, 0xffedeeed, 0xffeeeded, 0xffedeeed, 0xffededee, 0xffededee, + 0xffeeeded, 0xffededee, 0xffededed, 0xffeeeded, 0xffedeeed, 0xffeeeeed, 0xffededee, 0xffeeedee, + 0xffededed, 0xffeeedee, 0xffeeedee, 0xffededed, 0xffedeeed, 0xffedeeee, 0xffeeeeee, 0xffededee, + 0xffededee, 0xffedeeed, 0xffeeeeed, 0xffedeeee, 0xffededed, 0xffeeeeed, 0xffedeeed, 0xffededed, + 0xffededee, 0xffeeedee, 0xffeeeeed, 0xffedeeee, 0xffeeedee, 0xffedeeee, 0xffededed, 0xffedeeed, + 0xffedeeed, 0xffededed, 0xffeeeded, 0xffedeeed, 0xffeeeded, 0xffedeeed, 0xffededed, 0xffeeeeed, + 0xffedeeed, 0xffeeeeee, 0xffedeeee, 0xffedeeed, 0xffedeeed, 0xffeeeded, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffecedec, 0xffedeced, 0xffededec, 0xffececec, 0xffedeced, 0xffeceded, 0xffedeced, + 0xffeceded, 0xffededed, 0xffedecec, 0xffecedec, 0xffececec, 0xffeceded, 0xffececec, 0xffededed, + 0xffeceded, 0xffeceded, 0xffededec, 0xffedeced, 0xffedeced, 0xffededec, 0xffedeced, 0xffedeced, + 0xffecedec, 0xffecedec, 0xffececec, 0xffecedec, 0xffededec, 0xffecedec, 0xffececec, 0xffecedec, + 0xffececed, 0xffececec, 0xffededec, 0xffececed, 0xffecedec, 0xffededec, 0xffececed, 0xffedecec, + 0xffececec, 0xffecedec, 0xffededec, 0xffecedec, 0xffeceded, 0xffedecec, 0xffedeced, 0xffececed, + 0xffecedec, 0xffedecec, 0xffeceded, 0xffececec, 0xffededed, 0xffececed, 0xffedecec, 0xffededec, + 0xffeceded, 0xffededed, 0xffededec, 0xffedecec, 0xffececec, 0xffececed, 0xffececed, 0xffeceded, + 0xffededec, 0xffececed, 0xffececec, 0xffecedec, 0xffededec, 0xffecedec, 0xffececed, 0xffededed, + 0xffececec, 0xffececed, 0xffedeced, 0xffececed, 0xffecedec, 0xffedeced, 0xffececed, 0xffecedec, + 0xffececec, 0xffececec, 0xffedecec, 0xffededed, 0xffededec, 0xffececed, 0xffececec, 0xffececed, + 0xffececec, 0xffedeced, 0xffececed, 0xffececed, 0xffececec, 0xffededed, 0xffededed, 0xffedecec, + 0xffedeced, 0xffedecec, 0xffececec, 0xffedecec, 0xffeceded, 0xffedecec, 0xffececed, 0xffeceded, + 0xffececec, 0xffececed, 0xffededec, 0xffeceded, 0xffececed, 0xffececed, 0xffeceded, 0xffededec, + 0xffececed, 0xffeceded, 0xffedecec, 0xffececed, 0xffededec, 0xffecedec, 0xffececec, 0xffedecec, + 0xffedeced, 0xffececec, 0xffedecec, 0xffececed, 0xffededec, 0xffeceded, 0xffededec, 0xffececec, + 0xffedecec, 0xffededec, 0xffededec, 0xffececec, 0xffececed, 0xffecedec, 0xffececec, 0xffecedec, + 0xffececec, 0xffededec, 0xffedeced, 0xffedecec, 0xffececec, 0xffededed, 0xffecedec, 0xffededec, + 0xffedeced, 0xffedeced, 0xffecedec, 0xffecedec, 0xffececec, 0xffececed, 0xffedecec, 0xffececec, + 0xffececec, 0xffedeced, 0xffeceded, 0xffececec, 0xffececec, 0xffececec, 0xffececec, 0xffececec, + 0xffedeced, 0xffececed, 0xffededed, 0xffedeced, 0xffededed, 0xffedecec, 0xffececed, 0xffededed, + 0xffedeced, 0xffececed, 0xffedecec, 0xffececed, 0xffededec, 0xffededed, 0xffededec, 0xffecedec, + 0xffececec, 0xffececed, 0xffececec, 0xffedeced, 0xffededec, 0xffedeced, 0xffedecec, 0xffedeced, + 0xffececed, 0xffededed, 0xffececec, 0xffedeced, 0xffececed, 0xffedeced, 0xffececec, 0xffececed, + 0xffececed, 0xffececec, 0xffededed, 0xffedecec, 0xffecedec, 0xffecedec, 0xffededec, 0xffededed, + 0xffececec, 0xffececec, 0xffedeced, 0xffededec, 0xffececed, 0xffeceded, 0xffeceded, 0xffecedec, + 0xffeceded, 0xffececec, 0xffececec, 0xffedecec, 0xffecedec, 0xffeceded, 0xffececec, 0xffedeced, + 0xffedeced, 0xffecedec, 0xffededed, 0xffededec, 0xffededed, 0xffededed, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffebebeb, 0xffebebec, 0xffecebeb, 0xffebecec, 0xffebecec, 0xffececeb, 0xffebebec, + 0xffebecec, 0xffebebeb, 0xffebecec, 0xffecebec, 0xffecebeb, 0xffebebeb, 0xffecebec, 0xffecebeb, + 0xffebeceb, 0xffebebec, 0xffecebeb, 0xffececeb, 0xffecebeb, 0xffebeceb, 0xffebebec, 0xffebecec, + 0xffebecec, 0xffecebec, 0xffecebec, 0xffecebec, 0xffecebec, 0xffecebeb, 0xffecebec, 0xffecebec, + 0xffecebeb, 0xffebebeb, 0xffebeceb, 0xffececec, 0xffecebeb, 0xffecebec, 0xffebecec, 0xffebeceb, + 0xffebebec, 0xffececec, 0xffecebeb, 0xffecebec, 0xffececeb, 0xffececeb, 0xffebeceb, 0xffebebec, + 0xffececeb, 0xffebebec, 0xffecebec, 0xffececec, 0xffececeb, 0xffebeceb, 0xffebecec, 0xffecebeb, + 0xffebecec, 0xffebecec, 0xffececec, 0xffecebeb, 0xffecebec, 0xffececec, 0xffebecec, 0xffebecec, + 0xffececec, 0xffebebeb, 0xffececeb, 0xffececeb, 0xffecebec, 0xffecebeb, 0xffececeb, 0xffebebec, + 0xffecebec, 0xffececeb, 0xffececec, 0xffebebec, 0xffebebeb, 0xffececec, 0xffebecec, 0xffebebec, + 0xffececec, 0xffebebec, 0xffebecec, 0xffecebec, 0xffebebeb, 0xffecebec, 0xffebebec, 0xffececeb, + 0xffecebeb, 0xffececec, 0xffececeb, 0xffebebeb, 0xffecebeb, 0xffebebec, 0xffebebec, 0xffececeb, + 0xffececeb, 0xffebeceb, 0xffececeb, 0xffececeb, 0xffebebeb, 0xffebebec, 0xffececeb, 0xffebebec, + 0xffececeb, 0xffecebeb, 0xffebebec, 0xffecebec, 0xffecebec, 0xffececec, 0xffebeceb, 0xffececec, + 0xffebebec, 0xffebecec, 0xffebebeb, 0xffecebeb, 0xffebebeb, 0xffececec, 0xffebecec, 0xffececeb, + 0xffececeb, 0xffebecec, 0xffecebec, 0xffececeb, 0xffebeceb, 0xffececeb, 0xffebecec, 0xffecebec, + 0xffebebec, 0xffebecec, 0xffebeceb, 0xffebebeb, 0xffebecec, 0xffecebec, 0xffecebeb, 0xffebeceb, + 0xffebeceb, 0xffecebec, 0xffececec, 0xffecebeb, 0xffececeb, 0xffececeb, 0xffecebec, 0xffecebec, + 0xffebebec, 0xffebecec, 0xffececec, 0xffebebeb, 0xffecebeb, 0xffececeb, 0xffebebec, 0xffebebec, + 0xffecebeb, 0xffebebec, 0xffebebeb, 0xffebebeb, 0xffebecec, 0xffebecec, 0xffebeceb, 0xffececec, + 0xffebeceb, 0xffecebeb, 0xffecebeb, 0xffececec, 0xffebecec, 0xffebecec, 0xffebeceb, 0xffebecec, + 0xffebecec, 0xffebecec, 0xffebebec, 0xffebeceb, 0xffebebeb, 0xffecebeb, 0xffebebec, 0xffebecec, + 0xffececeb, 0xffebebec, 0xffecebec, 0xffebebeb, 0xffececec, 0xffecebeb, 0xffebebec, 0xffebecec, + 0xffebebec, 0xffebebeb, 0xffecebec, 0xffecebeb, 0xffebebeb, 0xffecebec, 0xffebecec, 0xffebebeb, + 0xffebeceb, 0xffececec, 0xffececec, 0xffecebec, 0xffebebec, 0xffececec, 0xffecebeb, 0xffebeceb, + 0xffebebec, 0xffececeb, 0xffebebec, 0xffebecec, 0xffecebec, 0xffebeceb, 0xffebecec, 0xffecebeb, + 0xffecebec, 0xffebeceb, 0xffecebec, 0xffebecec, 0xffebeceb, 0xffebeceb, 0xffecebeb, 0xffececeb, + 0xffebebec, 0xffececec, 0xffececeb, 0xffecebec, 0xffebebeb, 0xffebebec, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffebebeb, 0xffeaebeb, 0xffeaeaea, 0xffebebeb, 0xffebeaeb, 0xffeaeaea, 0xffebeaeb, + 0xffeaebea, 0xffebebea, 0xffebeaea, 0xffeaebea, 0xffebebea, 0xffebeaeb, 0xffeaebea, 0xffebeaea, + 0xffeaebea, 0xffeaeaeb, 0xffebeaeb, 0xffeaeaea, 0xffebebea, 0xffeaebeb, 0xffebebeb, 0xffeaebeb, + 0xffebebeb, 0xffebebeb, 0xffeaebeb, 0xffebeaea, 0xffebebeb, 0xffebebeb, 0xffebebeb, 0xffeaebea, + 0xffeaeaeb, 0xffebebeb, 0xffebebea, 0xffebebeb, 0xffebeaeb, 0xffebebeb, 0xffebebea, 0xffebebeb, + 0xffebebeb, 0xffebebeb, 0xffebeaea, 0xffeaebeb, 0xffeaebea, 0xffeaeaeb, 0xffeaeaeb, 0xffebebeb, + 0xffebeaeb, 0xffebebea, 0xffeaeaeb, 0xffebebeb, 0xffebeaeb, 0xffeaebeb, 0xffebebeb, 0xffebebea, + 0xffeaeaea, 0xffeaeaeb, 0xffebeaeb, 0xffebebeb, 0xffebebea, 0xffebebea, 0xffebeaea, 0xffebebeb, + 0xffeaebeb, 0xffebebea, 0xffebebea, 0xffebeaeb, 0xffeaebea, 0xffebebea, 0xffeaeaea, 0xffeaebea, + 0xffeaebea, 0xffebebea, 0xffebeaeb, 0xffebebeb, 0xffeaebea, 0xffebebea, 0xffeaeaeb, 0xffeaebeb, + 0xffebebeb, 0xffebeaeb, 0xffebeaeb, 0xffeaebeb, 0xffebebea, 0xffeaebea, 0xffebebea, 0xffeaeaeb, + 0xffebebeb, 0xffebebeb, 0xffeaeaea, 0xffeaebeb, 0xffebeaeb, 0xffeaebeb, 0xffeaebeb, 0xffebebeb, + 0xffebebea, 0xffebebeb, 0xffeaebeb, 0xffeaebea, 0xffebebea, 0xffebebeb, 0xffebebeb, 0xffeaebeb, + 0xffebebeb, 0xffebeaeb, 0xffebeaeb, 0xffebebeb, 0xffebeaeb, 0xffeaebea, 0xffeaeaea, 0xffebebea, + 0xffeaeaea, 0xffebebeb, 0xffeaeaeb, 0xffebeaeb, 0xffebeaeb, 0xffebeaeb, 0xffeaebea, 0xffebeaea, + 0xffeaeaea, 0xffebebeb, 0xffebeaea, 0xffeaeaeb, 0xffeaebeb, 0xffeaebea, 0xffeaeaea, 0xffebebea, + 0xffeaebea, 0xffeaebea, 0xffebebeb, 0xffebeaeb, 0xffeaebeb, 0xffebebeb, 0xffebeaeb, 0xffebeaeb, + 0xffeaebeb, 0xffebebea, 0xffebebea, 0xffebebea, 0xffebebea, 0xffebebeb, 0xffeaebeb, 0xffeaebea, + 0xffebebeb, 0xffebebeb, 0xffebeaeb, 0xffeaebea, 0xffebeaeb, 0xffebebea, 0xffebebea, 0xffebebeb, + 0xffebebea, 0xffeaebeb, 0xffebeaeb, 0xffeaebeb, 0xffebeaea, 0xffeaebeb, 0xffeaebea, 0xffeaeaeb, + 0xffebebeb, 0xffebeaea, 0xffebebea, 0xffebeaeb, 0xffebebeb, 0xffebeaea, 0xffeaeaeb, 0xffebeaeb, + 0xffebebea, 0xffebebeb, 0xffebeaeb, 0xffebeaeb, 0xffebeaea, 0xffebeaea, 0xffebeaeb, 0xffebeaeb, + 0xffebeaeb, 0xffeaeaeb, 0xffebeaea, 0xffebeaeb, 0xffeaebeb, 0xffeaebeb, 0xffebebeb, 0xffebebea, + 0xffeaebea, 0xffebeaea, 0xffeaebea, 0xffebebeb, 0xffebebeb, 0xffeaebeb, 0xffebebeb, 0xffeaeaeb, + 0xffeaebeb, 0xffebebeb, 0xffebebeb, 0xffeaebea, 0xffeaebeb, 0xffeaebeb, 0xffebebeb, 0xffeaebeb, + 0xffebebea, 0xffebebeb, 0xffeaeaeb, 0xffebebeb, 0xffebebeb, 0xffebebea, 0xffeaebeb, 0xffeaebea, + 0xffeaeaeb, 0xffebebea, 0xffebeaea, 0xffebebea, 0xffebeaea, 0xffebebea, 0xffebebea, 0xffebebeb, + 0xffebebea, 0xffebebeb, 0xffebebea, 0xffebebeb, 0xffeaebeb, 0xffebebeb, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffe9eae9, 0xffeaeaea, 0xffe9eaea, + 0xffeae9ea, 0xffeaeae9, 0xffeaeae9, 0xffeae9e9, 0xffeaeaea, 0xffeaeaea, 0xffeae9ea, 0xffeaeaea, + 0xffe9eae9, 0xffeaeaea, 0xffe9e9ea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, + 0xffeaeae9, 0xffe9e9e9, 0xffe9eaea, 0xffeae9ea, 0xffeaeaea, 0xffeae9e9, 0xffeae9ea, 0xffe9e9e9, + 0xffeaeaea, 0xffeaeaea, 0xffe9e9ea, 0xffe9eaea, 0xffeaeae9, 0xffeaeaea, 0xffeae9ea, 0xffe9eaea, + 0xffe9eaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffe9eae9, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, + 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeae9ea, 0xffeaeaea, 0xffeae9ea, 0xffeae9ea, 0xffe9eaea, + 0xffeaeaea, 0xffeaeaea, 0xffeae9e9, 0xffeaeaea, 0xffeaeaea, 0xffeae9ea, 0xffeae9e9, 0xffe9eaea, + 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, 0xffeae9e9, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffe9e9ea, + 0xffeaeaea, 0xffeaeae9, 0xffeaeaea, 0xffeae9ea, 0xffe9eaea, 0xffeaeae9, 0xffeaeae9, 0xffeaeaea, + 0xffeaeaea, 0xffe9eaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, 0xffeaeaea, 0xffe9eaea, 0xffeae9ea, + 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, 0xffe9eae9, 0xffeaeaea, 0xffe9eaea, 0xffeaeaea, 0xffeaeaea, + 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, 0xffeaeae9, 0xffe9eaea, 0xffe9eaea, 0xffeaeaea, + 0xffeaeaea, 0xffeae9e9, 0xffeaeaea, 0xffeaeae9, 0xffeaeae9, 0xffeaeaea, 0xffeaeae9, 0xffeaeaea, + 0xffeaeaea, 0xffeaeae9, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, + 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, 0xffeaeaea, 0xffeaeae9, 0xffeaeaea, 0xffeaeaea, 0xffe9eaea, + 0xffeaeaea, 0xffe9eae9, 0xffeaeae9, 0xffeae9ea, 0xffeaeaea, 0xffe9eaea, 0xffe9eaea, 0xffeae9ea, + 0xffeaeae9, 0xffeaeaea, 0xffeae9e9, 0xffeaeaea, 0xffe9eaea, 0xffeae9ea, 0xffeaeaea, 0xffeaeaea, + 0xffe9eaea, 0xffeae9ea, 0xffeaeae9, 0xffeae9e9, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, + 0xffeaeaea, 0xffeaeaea, 0xffe9eaea, 0xffe9e9ea, 0xffe9eae9, 0xffeaeaea, 0xffeaeae9, 0xffeaeaea, + 0xffeaeae9, 0xffeae9ea, 0xffeaeae9, 0xffeaeae9, 0xffe9eaea, 0xffeaeaea, 0xffeaeae9, 0xffe9eaea, + 0xffeaeaea, 0xffeaeae9, 0xffeae9ea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffe9eaea, 0xffeae9ea, + 0xffeaeae9, 0xffeae9ea, 0xffe9eaea, 0xffeaeae9, 0xffeaeae9, 0xffeae9ea, 0xffeaeaea, 0xffe9eaea, + 0xffeaeaea, 0xffeaeaea, 0xffeae9ea, 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, 0xffe9eaea, 0xffe9e9ea, + 0xffeaeaea, 0xffe9e9ea, 0xffe9eaea, 0xffeae9ea, 0xffe9e9e9, 0xffeaeaea, 0xffeaeaea, 0xffeaeae9, + 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeae9ea, 0xffeaeaea, 0xffeaeaea, 0xffe9e9ea, 0xffeaeaea, + 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffeaeaea, 0xffe9eaea, + 0xffeaeaea, 0xffe9eae9, 0xffeaeaea, 0xffeae9ea, 0xffeaeae9, 0xffeaeaea, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffeae9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, + 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe9e9e9, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffe8e8e8, 0xffe8e8e9, 0xffe9e9e9, 0xffe8e8e8, 0xffe9e8e9, 0xffe8e8e9, 0xffe8e8e9, + 0xffe8e8e9, 0xffe8e8e8, 0xffe8e8e9, 0xffe8e8e9, 0xffe8e9e9, 0xffe9e8e8, 0xffe9e8e8, 0xffe8e9e8, + 0xffe8e9e9, 0xffe8e8e8, 0xffe8e8e9, 0xffe9e8e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e9e9, + 0xffe9e8e8, 0xffe8e8e9, 0xffe9e8e9, 0xffe9e9e8, 0xffe9e8e8, 0xffe8e9e8, 0xffe8e9e8, 0xffe8e8e8, + 0xffe8e9e8, 0xffe8e8e9, 0xffe8e8e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e8e9, 0xffe8e9e8, 0xffe8e8e8, + 0xffe8e9e8, 0xffe8e8e8, 0xffe8e9e8, 0xffe8e9e8, 0xffe8e9e9, 0xffe8e8e8, 0xffe9e8e9, 0xffe8e8e8, + 0xffe8e9e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe9e9e8, 0xffe8e8e8, 0xffe8e9e9, 0xffe8e8e9, 0xffe8e8e8, + 0xffe8e9e8, 0xffe9e9e8, 0xffe8e8e8, 0xffe9e9e9, 0xffe8e8e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e8e9, + 0xffe8e9e8, 0xffe8e8e9, 0xffe8e9e9, 0xffe9e8e8, 0xffe8e8e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe9e8e9, + 0xffe8e8e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e9e8, 0xffe9e8e9, 0xffe8e8e8, 0xffe8e8e9, + 0xffe8e8e8, 0xffe9e9e8, 0xffe9e8e9, 0xffe8e8e9, 0xffe8e9e8, 0xffe9e8e9, 0xffe8e9e8, 0xffe8e9e9, + 0xffe8e8e8, 0xffe9e9e8, 0xffe8e9e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e8e9, 0xffe8e9e9, 0xffe8e8e8, + 0xffe8e8e8, 0xffe8e8e9, 0xffe8e9e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe9e8e8, 0xffe8e8e9, + 0xffe8e9e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, + 0xffe8e8e9, 0xffe8e8e9, 0xffe8e8e8, 0xffe8e8e8, 0xffe9e9e8, 0xffe8e9e9, 0xffe8e8e8, 0xffe8e8e8, + 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe9e9e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e9e8, + 0xffe8e8e9, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e9e9, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e9e8, + 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe9e8e8, 0xffe8e8e9, 0xffe9e9e8, + 0xffe8e8e8, 0xffe9e9e8, 0xffe8e9e9, 0xffe8e9e8, 0xffe9e8e9, 0xffe8e9e8, 0xffe8e8e8, 0xffe8e8e8, + 0xffe8e8e8, 0xffe9e8e8, 0xffe9e8e8, 0xffe9e8e9, 0xffe8e8e9, 0xffe8e9e8, 0xffe9e8e8, 0xffe8e9e9, + 0xffe9e8e9, 0xffe9e8e8, 0xffe8e8e9, 0xffe9e8e8, 0xffe8e9e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe9e9e8, + 0xffe8e8e8, 0xffe8e8e9, 0xffe8e9e9, 0xffe8e9e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, + 0xffe8e8e8, 0xffe8e9e8, 0xffe8e9e9, 0xffe8e8e8, 0xffe8e8e9, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e9, + 0xffe8e9e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe8e8e8, + 0xffe9e8e9, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e9e9, 0xffe9e8e8, 0xffe8e8e8, 0xffe9e8e8, + 0xffe9e8e8, 0xffe8e9e8, 0xffe9e8e8, 0xffe8e8e8, 0xffe8e9e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe8e8e8, + 0xffe8e8e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe9e8e9, 0xffe9e9e9, 0xffe8e8e8, 0xffe8e9e9, 0xffe9e8e8, + 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e9e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffe7e8e8, 0xffe8e7e8, 0xffe8e7e8, 0xffe7e8e7, 0xffe8e7e8, 0xffe7e7e8, 0xffe7e8e8, + 0xffe7e7e8, 0xffe8e7e8, 0xffe8e8e8, 0xffe7e8e7, 0xffe8e8e8, 0xffe7e8e8, 0xffe8e7e7, 0xffe8e8e7, + 0xffe7e7e7, 0xffe8e8e8, 0xffe7e7e7, 0xffe7e8e7, 0xffe8e8e7, 0xffe8e8e8, 0xffe7e7e8, 0xffe8e8e7, + 0xffe8e8e8, 0xffe8e8e7, 0xffe7e7e7, 0xffe7e8e7, 0xffe8e8e7, 0xffe8e8e7, 0xffe8e7e8, 0xffe8e7e8, + 0xffe7e8e7, 0xffe7e7e8, 0xffe8e8e8, 0xffe7e7e7, 0xffe7e8e8, 0xffe7e7e7, 0xffe7e8e7, 0xffe7e8e8, + 0xffe8e7e8, 0xffe7e7e7, 0xffe8e8e7, 0xffe7e8e7, 0xffe7e8e8, 0xffe8e8e8, 0xffe8e8e7, 0xffe8e8e8, + 0xffe7e7e7, 0xffe7e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e7e8, 0xffe8e7e8, 0xffe8e8e8, 0xffe7e8e8, + 0xffe7e8e7, 0xffe7e7e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e7e7, 0xffe8e8e7, 0xffe8e8e8, + 0xffe8e8e7, 0xffe7e7e8, 0xffe7e7e8, 0xffe8e8e7, 0xffe8e7e8, 0xffe8e7e7, 0xffe8e8e7, 0xffe7e8e8, + 0xffe8e7e8, 0xffe8e7e8, 0xffe8e7e8, 0xffe7e7e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e8e7, 0xffe7e7e7, + 0xffe7e8e7, 0xffe7e7e8, 0xffe8e7e8, 0xffe8e8e7, 0xffe7e7e8, 0xffe8e8e8, 0xffe8e7e7, 0xffe8e7e8, + 0xffe7e7e7, 0xffe7e8e8, 0xffe8e7e8, 0xffe8e8e7, 0xffe8e7e8, 0xffe8e7e7, 0xffe8e7e8, 0xffe8e8e7, + 0xffe7e8e8, 0xffe8e7e7, 0xffe8e7e7, 0xffe8e7e7, 0xffe8e7e7, 0xffe7e8e8, 0xffe7e7e8, 0xffe8e7e8, + 0xffe7e8e8, 0xffe7e8e8, 0xffe7e8e7, 0xffe8e7e8, 0xffe8e8e7, 0xffe8e8e7, 0xffe7e8e8, 0xffe8e7e8, + 0xffe8e8e8, 0xffe8e8e7, 0xffe7e7e7, 0xffe8e8e8, 0xffe7e7e8, 0xffe8e8e8, 0xffe7e7e8, 0xffe7e7e7, + 0xffe7e7e8, 0xffe7e7e8, 0xffe8e7e8, 0xffe8e7e7, 0xffe8e7e7, 0xffe8e7e8, 0xffe8e8e7, 0xffe7e7e8, + 0xffe8e8e8, 0xffe7e8e7, 0xffe7e8e7, 0xffe8e8e8, 0xffe8e7e8, 0xffe7e7e7, 0xffe8e8e8, 0xffe8e7e8, + 0xffe8e8e7, 0xffe7e7e8, 0xffe8e7e8, 0xffe7e7e8, 0xffe7e8e7, 0xffe7e8e7, 0xffe7e7e8, 0xffe8e7e7, + 0xffe8e7e7, 0xffe8e7e7, 0xffe7e8e7, 0xffe8e8e8, 0xffe7e8e8, 0xffe8e8e8, 0xffe8e8e8, 0xffe8e7e7, + 0xffe7e8e7, 0xffe8e7e7, 0xffe7e8e8, 0xffe7e7e7, 0xffe8e7e8, 0xffe7e8e8, 0xffe8e7e8, 0xffe8e8e8, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e8e7, 0xffe8e8e7, 0xffe8e7e8, 0xffe7e8e8, 0xffe7e7e7, 0xffe7e7e8, + 0xffe7e7e8, 0xffe7e8e8, 0xffe7e8e8, 0xffe7e8e8, 0xffe7e7e7, 0xffe7e8e8, 0xffe8e7e8, 0xffe8e8e8, + 0xffe7e8e8, 0xffe8e7e8, 0xffe7e7e7, 0xffe8e7e8, 0xffe7e8e7, 0xffe8e7e7, 0xffe7e8e8, 0xffe7e8e8, + 0xffe7e8e8, 0xffe7e8e7, 0xffe7e8e8, 0xffe7e8e8, 0xffe8e8e8, 0xffe8e7e7, 0xffe8e7e7, 0xffe8e7e8, + 0xffe8e8e7, 0xffe8e8e7, 0xffe8e7e8, 0xffe7e7e8, 0xffe8e7e8, 0xffe8e7e7, 0xffe8e8e8, 0xffe8e7e8, + 0xffe7e7e8, 0xffe8e8e7, 0xffe7e8e7, 0xffe7e8e7, 0xffe8e8e8, 0xffe8e7e8, 0xffe7e8e7, 0xffe8e7e7, + 0xffe7e7e8, 0xffe7e8e8, 0xffe8e7e8, 0xffe8e7e7, 0xffe7e7e8, 0xffe8e8e7, 0xffe7e7e8, 0xffe8e7e7, + 0xffe7e7e8, 0xffe7e7e8, 0xffe8e8e7, 0xffe7e8e8, 0xffe8e7e7, 0xffe8e8e8, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e6, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e6e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e6e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e6e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e6, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e6, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e6, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe6e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797b79, 0xffb5b6b5, 0xffb5b6b5, + 0xffd6dbd6, 0xffe6e6e6, 0xffe6e7e7, 0xffe6e7e6, 0xffe7e6e7, 0xffe7e6e6, 0xffe7e6e6, 0xffe6e6e7, + 0xffe6e6e6, 0xffe6e6e6, 0xffe7e6e6, 0xffe7e6e6, 0xffe6e7e7, 0xffe7e6e6, 0xffe6e7e6, 0xffe6e6e7, + 0xffe7e6e6, 0xffe6e7e7, 0xffe7e6e6, 0xffe7e7e7, 0xffe6e7e7, 0xffe6e7e7, 0xffe6e6e7, 0xffe6e7e6, + 0xffe6e7e6, 0xffe7e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e6e6, 0xffe6e7e7, 0xffe6e7e7, 0xffe6e7e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe7e7e7, 0xffe7e7e7, 0xffe6e7e6, 0xffe6e6e6, 0xffe7e7e7, + 0xffe6e6e7, 0xffe7e7e7, 0xffe7e6e7, 0xffe6e6e7, 0xffe6e7e6, 0xffe6e6e6, 0xffe7e7e7, 0xffe7e6e6, + 0xffe7e6e7, 0xffe7e6e7, 0xffe6e7e6, 0xffe6e6e7, 0xffe7e7e6, 0xffe7e7e6, 0xffe6e6e7, 0xffe6e7e6, + 0xffe6e6e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe7e6e6, 0xffe6e6e7, 0xffe6e7e7, 0xffe6e7e7, 0xffe6e7e6, + 0xffe6e6e7, 0xffe6e6e7, 0xffe6e6e7, 0xffe6e6e7, 0xffe6e6e7, 0xffe7e6e6, 0xffe6e7e6, 0xffe6e7e6, + 0xffe7e7e7, 0xffe7e7e7, 0xffe7e7e7, 0xffe6e7e7, 0xffe6e6e7, 0xffe6e6e6, 0xffe6e7e7, 0xffe7e7e7, + 0xffe6e7e7, 0xffe7e6e6, 0xffe6e6e7, 0xffe6e7e7, 0xffe7e6e7, 0xffe7e7e7, 0xffe6e6e7, 0xffe6e6e6, + 0xffe7e7e6, 0xffe6e6e6, 0xffe6e7e7, 0xffe6e6e6, 0xffe6e7e6, 0xffe7e7e6, 0xffe7e7e6, 0xffe6e7e7, + 0xffe6e6e6, 0xffe6e7e6, 0xffe6e7e7, 0xffe7e7e6, 0xffe6e7e6, 0xffe6e6e7, 0xffe7e7e6, 0xffe6e6e6, + 0xffe7e7e6, 0xffe6e6e7, 0xffe6e7e7, 0xffe6e7e6, 0xffe7e6e7, 0xffe6e7e7, 0xffe6e6e7, 0xffe7e6e7, + 0xffe6e7e7, 0xffe6e7e6, 0xffe7e7e7, 0xffe7e7e7, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e6e7, 0xffe6e6e7, + 0xffe6e6e6, 0xffe7e6e7, 0xffe6e6e6, 0xffe7e6e7, 0xffe6e6e7, 0xffe7e7e7, 0xffe6e6e7, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe7e6e6, 0xffe7e7e6, 0xffe7e7e7, 0xffe6e6e6, 0xffe7e7e7, 0xffe6e7e7, + 0xffe6e7e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe7e7e6, 0xffe6e6e7, 0xffe7e6e6, 0xffe7e6e7, 0xffe6e6e7, + 0xffe6e7e7, 0xffe7e6e6, 0xffe6e7e6, 0xffe6e6e7, 0xffe7e7e7, 0xffe7e6e6, 0xffe6e7e6, 0xffe7e6e6, + 0xffe6e7e7, 0xffe6e7e7, 0xffe6e6e6, 0xffe7e7e6, 0xffe7e6e6, 0xffe7e6e6, 0xffe6e7e6, 0xffe7e6e6, + 0xffe7e7e6, 0xffe6e6e7, 0xffe6e6e6, 0xffe6e6e7, 0xffe6e7e7, 0xffe6e7e7, 0xffe6e6e7, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e7, 0xffe7e7e7, 0xffe6e6e7, 0xffe6e7e7, 0xffe6e6e7, 0xffe6e6e7, 0xffe6e7e7, + 0xffe7e6e6, 0xffe7e6e7, 0xffe6e6e6, 0xffe7e7e6, 0xffe7e6e6, 0xffe6e7e7, 0xffe6e7e7, 0xffe7e7e7, + 0xffe6e6e6, 0xffe7e7e7, 0xffe7e7e7, 0xffe6e7e6, 0xffe7e7e7, 0xffe6e6e7, 0xffe7e7e7, 0xffe6e6e7, + 0xffe6e7e6, 0xffe7e7e6, 0xffe7e6e7, 0xffe7e6e7, 0xffe7e6e6, 0xffe6e6e6, 0xffe7e7e6, 0xffe6e7e6, + 0xffe7e6e6, 0xffe7e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e6e7, 0xffe7e6e7, 0xffe6e7e7, + 0xffe7e7e6, 0xffe7e6e7, 0xffe7e7e7, 0xffe6e6e6, 0xffe6e6e7, 0xffe7e6e6, 0xffe6e6e7, 0xffe7e7e6, + 0xffe7e7e7, 0xffe6e7e6, 0xffe6e6e7, 0xffe7e6e6, 0xffe6e7e6, 0xffe6e7e7, 0xffe6e8e6, 0xffd6dbd6, + 0xffc5c2c5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797879, 0xffb5b2b5, 0xffb5b2b5, + 0xffd9dbd9, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, + 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6e6e6, 0xffe6ebe6, 0xffd9dbd9, + 0xffbdbebd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797879, 0xffb5b2b5, 0xffb5b2b5, + 0xffd9dbd9, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, + 0xffefefef, 0xffefefef, 0xffefefef, 0xffefefef, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffd9dbd9, + 0xffbdbebd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff797879, 0xffb5b2b5, 0xffb5b2b5, + 0xffcbcacb, 0xffd9dbd9, 0xffe6ebe6, 0xffe6ebe6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, + 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6e8e6, 0xffe6ebe6, 0xffe6ebe6, 0xffd9dbd9, 0xffcbcacb, + 0xffbdbebd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0xff797879, 0xffb5b2b5, + 0xffbdbabd, 0xffcbcacb, 0xffd9dbd9, 0xffd9dbd9, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, + 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd9dbd9, 0xffd9dbd9, 0xffcbcacb, 0xffbdbabd, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff848284, + 0xff9c9f9c, 0xff9c9f9c, 0xff9c9f9c, 0xff9c9f9c, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, + 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xffa2a5a2, 0xff9c9e9c, 0xff9c9e9c, 0xff9c9e9c, 0x00080408, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff848284, 0xffc5c2c5, 0xffc5c2c5, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffbdbebd, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff848284, 0xff848284, 0xffc5c2c5, 0xffe6ebe6, + 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, + 0xffeff3ef, 0xffeff3ef, 0xffeff3ef, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffe6ebe6, 0xffbdbebd, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffc5716b, + 0xffd07770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd6796b, + 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6756b, + 0xffd6756b, 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd6736b, 0xffd6736b, 0xffd6736b, 0xffce7163, + 0xffce7163, 0xffce7063, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6c63, 0xffce6b63, 0xffce6963, 0xffce695a, 0xffce685a, 0xffce675a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5645a, 0xffc5645d, 0xffc56258, 0xffc56258, 0xffc56258, 0xffc56052, + 0xffc56052, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55c52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd5142, 0xffbd5142, 0xffba5042, 0xffba5042, 0xffba4d42, + 0xffb84d42, 0xffb84d42, 0xffb84d42, 0xffb54c3f, 0xffb54a3c, 0xffb54a3c, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5463a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb5433a, 0xffb54237, + 0xffb54237, 0xffb54131, 0xffb54131, 0xffad4131, 0xffad4131, 0xffad3f31, 0xffad3f31, 0xffad3f31, + 0xffad3e31, 0xffad3e31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b2f, + 0xffad3b2f, 0xffad3b2f, 0xffad3a2c, 0xffad392f, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392f, + 0xffad392c, 0xffad392f, 0xffad392f, 0xffad3a2c, 0xffad3a2c, 0xffad3b2f, 0xffad3b2f, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, 0xffad3e31, 0xffad3f31, 0xffad3f31, + 0xffad3f31, 0xffad3f31, 0xffad4131, 0xffb54237, 0xffb54237, 0xffb54237, 0xffb54237, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54a3c, + 0xffb54a3c, 0xffb54c3f, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb84e42, 0xffba5042, 0xffbd5045, + 0xffbd5142, 0xffbd5142, 0xffbd5142, 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd554a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd564a, 0xffc0594d, 0xffc35950, 0xffc35950, 0xffc35950, 0xffc55a52, + 0xffc55d52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc56052, 0xffc56052, 0xffc56152, 0xffc56258, + 0xffc56258, 0xffc56455, 0xffc56455, 0xffcb655a, 0xffcb655a, 0xffcb655a, 0xffcb655a, 0xffce675d, + 0xffce6860, 0xffce6860, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, 0xffce6d63, + 0xffce6f63, 0xffce6f63, 0xffce7063, 0xffd07165, 0xffd07165, 0xffd37168, 0xffd37168, 0xffd6736b, + 0xffd6736b, 0xffd6746b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6776b, + 0xffd6786b, 0xffd6796b, 0xffd6786b, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd67973, + 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd07770, 0xffc5716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffc5716b, + 0xffd07770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd6796b, + 0xffd6796b, 0xffd6796b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6746b, 0xffd6746b, 0xffd6746b, 0xffd6736b, 0xffd6716b, 0xffd6716b, 0xffd6716b, 0xffce7063, + 0xffce7063, 0xffce7063, 0xffce7063, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6c63, 0xffce6b63, 0xffce6b63, 0xffce695a, 0xffce685a, 0xffce685a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5645a, 0xffc56258, 0xffc56258, 0xffc56152, 0xffc56152, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55d52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd594a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd524a, 0xffbd514a, 0xffba5042, 0xffba5042, 0xffba5042, 0xffb54d42, 0xffb84d42, + 0xffb84d42, 0xffb84d42, 0xffb84d42, 0xffb54c3f, 0xffb54a3c, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb5423a, 0xffb54237, + 0xffb54237, 0xffb54131, 0xffb54131, 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3a2c, + 0xffad3b2f, 0xffad3a2c, 0xffad3929, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffad3929, 0xffad3a2c, 0xffad3a2c, 0xffad3b2f, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, 0xffad3f31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffb5413a, 0xffb5413a, 0xffb54237, 0xffb54237, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5493a, + 0xffb54a3c, 0xffb54c3f, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb84e42, 0xffbd4e47, + 0xffbd5045, 0xffbd5045, 0xffbd5142, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd564a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55a52, + 0xffc55d52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56455, 0xffc8655a, 0xffc8655a, 0xffcb655a, 0xffcb655a, 0xffce675d, + 0xffce6860, 0xffce6860, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6c63, 0xffce6d63, + 0xffce6f63, 0xffce6f63, 0xffce6f63, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd37168, 0xffd6716b, + 0xffd6716b, 0xffd6736b, 0xffd6736b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6776b, + 0xffd6776b, 0xffd6786b, 0xffd6786b, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd67973, + 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd07770, 0xffc5716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffc5716b, + 0xffd07770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd6796b, + 0xffd6796b, 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd6736b, 0xffd6716b, 0xffd6716b, 0xffd6716b, 0xffce7063, + 0xffce7063, 0xffce7063, 0xffce7063, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce695a, 0xffce685a, 0xffce685a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5645a, 0xffc56258, 0xffc56258, 0xffc56258, 0xffc56152, 0xffc55e52, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55d52, 0xffc55c52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd594a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd514a, 0xffbd514a, 0xffba5042, 0xffba5042, 0xffba5042, 0xffb84e42, 0xffb84d42, + 0xffb84d42, 0xffb84d42, 0xffb84d42, 0xffb54a3c, 0xffb54a3c, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5433a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb54237, + 0xffb54237, 0xffb54131, 0xffb54131, 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3a2c, + 0xffad3a2c, 0xffad3a2c, 0xffad3a2c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffad3a2c, 0xffad3a2c, 0xffad3a2c, 0xffad3a2c, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffb54237, 0xffb54237, 0xffb54237, 0xffb54237, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5493a, 0xffb54a3c, + 0xffb54a3c, 0xffb54c3f, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffbd4e47, + 0xffbd5045, 0xffbd5045, 0xffbd5142, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd564a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55c52, + 0xffc55c52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc56052, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56258, 0xffc8655a, 0xffcb655a, 0xffc8655a, 0xffcb655a, 0xffce675d, + 0xffce6860, 0xffce6963, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, 0xffce6d63, + 0xffce6f63, 0xffce6f63, 0xffce7063, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd6716b, + 0xffd6736b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6776b, 0xffd6786b, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd67973, + 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd07770, 0xffc5716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffc5716b, + 0xffd07770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd6796e, 0xffd6796b, + 0xffd6796b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6736b, 0xffd6716b, 0xffd6736b, 0xffd6716b, 0xffd6716b, 0xffce7063, + 0xffce7063, 0xffce7063, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce695a, 0xffce695a, 0xffce675a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5625a, 0xffc56258, 0xffc56258, 0xffc56152, 0xffc56152, 0xffc55e52, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55d52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd524a, 0xffbd514a, 0xffba5042, 0xffba5042, 0xffba5042, 0xffb54d42, 0xffb84d42, + 0xffb84d42, 0xffb84d42, 0xffb84d42, 0xffb54c3f, 0xffb5493a, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5463a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb5433a, 0xffb54237, + 0xffb54237, 0xffb54131, 0xffb54131, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3a2c, + 0xffad3a2c, 0xffad3a2c, 0xffad3929, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffad3929, 0xffad3a2c, 0xffad3a2c, 0xffad3b2f, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffb54237, 0xffb54237, 0xffb54237, 0xffb54237, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5493a, + 0xffb54a3c, 0xffb54c3f, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb84e42, 0xffbd4e47, + 0xffbd5045, 0xffbd5045, 0xffbd5142, 0xffbd514a, 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd584a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc55c52, + 0xffc55d52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc56152, 0xffc5615a, + 0xffc5615a, 0xffc56258, 0xffc56258, 0xffc8655a, 0xffc8655a, 0xffcb655a, 0xffcb655a, 0xffce675d, + 0xffce6860, 0xffce6860, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, 0xffce6f63, + 0xffce6f63, 0xffce6f63, 0xffce7063, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd37168, 0xffd6716b, + 0xffd6736b, 0xffd6736b, 0xffd6736b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6776b, 0xffd6786b, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd67973, + 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd67973, 0xffd07770, 0xffc5716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffce716b, + 0xffd37770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd6796b, + 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd67168, 0xffd67168, 0xffd67168, 0xffd67168, 0xffce7063, + 0xffce7063, 0xffce7063, 0xffce7063, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce695a, 0xffce685a, 0xffce675a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5645a, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56155, 0xffc55e52, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55c52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584a, 0xffbd584a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd514a, 0xffbd514a, 0xffba5042, 0xffba5042, 0xffb84e42, 0xffb84e42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb54a3f, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb5423a, 0xffb24137, + 0xffaf4134, 0xffaf4134, 0xffaf4134, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad3a2c, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3a2c, 0xffad3a2c, 0xffad3a2c, 0xffad3a2c, + 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffb54131, 0xffb54131, 0xffb54234, 0xffb54337, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5493a, + 0xffb54a3c, 0xffb54c3f, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffbd4e47, + 0xffbd5045, 0xffbd5045, 0xffbd5142, 0xffbd524a, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd564a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55c52, + 0xffc55d52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56152, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56258, 0xffc8655a, 0xffc8655a, 0xffcb655a, 0xffcb655a, 0xffce685d, + 0xffce685d, 0xffce695a, 0xffce695a, 0xffce6b63, 0xffce6c63, 0xffce6c63, 0xffce6c63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd6716b, + 0xffd6716b, 0xffd6736b, 0xffd6736b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6776b, 0xffd6786b, 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd6796e, 0xffd67970, + 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd37770, 0xffce716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffce716b, + 0xffd37770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd6796b, + 0xffd6796b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd67168, 0xffd67168, 0xffd67168, 0xffd67165, 0xffce7063, + 0xffce7063, 0xffce7063, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6c63, 0xffce6b63, 0xffce6963, 0xffce695a, 0xffce695a, 0xffce675a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5625a, 0xffc56158, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc55e52, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55c52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd544a, 0xffbd524a, 0xffbd514a, 0xffba5042, 0xffba5042, 0xffb84e42, 0xffb54d42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb5493a, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5463a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb5433a, 0xffb24137, + 0xffb24137, 0xffaf4134, 0xffaf4134, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3d31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad3a2c, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3a2c, 0xffad3a2c, 0xffad3b2f, + 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, + 0xffad3e31, 0xffad3f31, 0xffad3f31, 0xffb54131, 0xffb54234, 0xffb54234, 0xffb54337, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5493a, + 0xffb54a3c, 0xffb54c3f, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffbd4e47, + 0xffbd5045, 0xffbd5045, 0xffbd5045, 0xffbd514a, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd554a, 0xffbd564a, 0xffbd564a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55c52, + 0xffc55c52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc5615a, + 0xffc5615a, 0xffc56258, 0xffc56258, 0xffc8655a, 0xffc8655a, 0xffcb655a, 0xffcb655a, 0xffce685d, + 0xffce685d, 0xffce695a, 0xffce685d, 0xffce6b63, 0xffce6c63, 0xffce6c63, 0xffce6d63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd37168, 0xffd6716b, + 0xffd6736b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6786b, 0xffd6786b, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd6796e, + 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd37770, 0xffce716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffce716b, + 0xffd37770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796b, + 0xffd6796b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6756b, 0xffd6746b, 0xffd67168, 0xffd67168, 0xffd67168, 0xffd67168, 0xffce7163, + 0xffce7063, 0xffce7063, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce695a, 0xffce695a, 0xffce675a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5645a, 0xffc56158, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc55e52, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd524a, 0xffbd514a, 0xffba5042, 0xffba5042, 0xffba5042, 0xffb84e42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb54a3f, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb5433a, 0xffb24137, + 0xffaf4134, 0xffaf4134, 0xffaf4134, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad3a2c, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3a2c, 0xffad3a2c, 0xffad3b2f, + 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffb54131, 0xffb54234, 0xffb54234, 0xffb54337, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5493a, + 0xffb54a3c, 0xffb54a3c, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffbd5045, + 0xffbd5045, 0xffbd5045, 0xffbd5142, 0xffbd514a, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd564a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55a52, + 0xffc55d52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56152, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56455, 0xffc8655a, 0xffc8655a, 0xffcb655a, 0xffcb655a, 0xffce685d, + 0xffce685d, 0xffce695a, 0xffce695a, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd37168, 0xffd6716b, + 0xffd6716b, 0xffd6736b, 0xffd6736b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6776b, + 0xffd6756b, 0xffd6786b, 0xffd6786b, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd6796e, + 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd37770, 0xffce716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e3c, 0xffa55d5a, 0xffa55d5a, 0xffce716b, + 0xffd37770, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67970, 0xffd6796b, + 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6786b, 0xffd6756b, 0xffd6776b, 0xffd6756b, 0xffd6756b, + 0xffd6746b, 0xffd6746b, 0xffd6736b, 0xffd67168, 0xffd67168, 0xffd67168, 0xffd67168, 0xffce7063, + 0xffce7063, 0xffce7063, 0xffce7063, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, + 0xffce6b63, 0xffce6b63, 0xffce6963, 0xffce695a, 0xffce685a, 0xffce675a, 0xffce675a, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5645a, 0xffc56158, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55c52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584a, 0xffbd584a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd524a, 0xffbd514a, 0xffba5042, 0xffba5042, 0xffba5042, 0xffb54d42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb54a3f, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5463a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5433a, 0xffb5433a, 0xffb5423a, 0xffb24137, + 0xffaf4134, 0xffaf4134, 0xffaf4134, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b2f, 0xffad3b2f, 0xffad3a2c, 0xffad3a2c, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3929, 0xffad3a2c, 0xffad3a2c, 0xffad3b2f, 0xffad3b2f, + 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffb54131, 0xffb54131, 0xffb54234, 0xffb54234, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5493a, + 0xffb54a3c, 0xffb54a3c, 0xffb54c3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffbd4e47, + 0xffbd5045, 0xffbd5045, 0xffbd5142, 0xffbd524a, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd584a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc55a52, + 0xffc55c52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56152, 0xffc56258, + 0xffc56258, 0xffc56258, 0xffc56455, 0xffc8655a, 0xffc8655a, 0xffcb655a, 0xffcb655a, 0xffce685d, + 0xffce685d, 0xffce695a, 0xffce695a, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd07165, 0xffd6716b, + 0xffd6716b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6786b, 0xffd6776b, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd67970, + 0xffd67970, 0xffd67970, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd37770, 0xffce716b, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd6786b, + 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd37168, 0xffd37168, 0xffd37168, 0xffd07165, 0xffce7063, + 0xffce7063, 0xffce6f63, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c63, 0xffce6960, + 0xffce6960, 0xffce6960, 0xffce695d, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5625a, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55c52, 0xffc55a52, 0xffc55952, 0xffbd594a, + 0xffbd584a, 0xffbd584a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd514a, 0xffbd514a, 0xffb55042, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54d42, + 0xffb54c42, 0xffb54c42, 0xffb54a42, 0xffb5493f, 0xffb5493c, 0xffb5493c, 0xffb5493c, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb24137, + 0xffaf4134, 0xffaf4134, 0xffaf4134, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3d31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3a31, 0xffad3a31, 0xffad3931, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffaa3929, 0xffaa3929, 0xffa73929, 0xffaa3929, 0xffa73929, + 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad3a31, + 0xffad3a31, 0xffad3b31, 0xffad3b31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad4131, 0xffaf4234, 0xffaf4234, 0xffb24337, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54942, + 0xffb54a3c, 0xffb54a3c, 0xffb54a3c, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffba5045, + 0xffba5045, 0xffba5045, 0xffbd5142, 0xffbd514a, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd554a, 0xffbd564a, 0xffbd584a, 0xffbd594d, 0xffbd594d, 0xffbd594d, 0xffbd5950, 0xffc55a52, + 0xffc55a52, 0xffc55c52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc56052, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56258, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffcb685a, + 0xffcb685a, 0xffcb685a, 0xffce695a, 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6f65, 0xffce6f65, 0xffce7068, 0xffce7068, 0xffd6716b, + 0xffd6716b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6786b, 0xffd6786b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd6786b, + 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6736b, 0xffd37168, 0xffd37168, 0xffd37168, 0xffd37168, 0xffce7063, + 0xffce7063, 0xffce6f63, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6c63, 0xffce6b63, 0xffce6960, + 0xffce6960, 0xffce6960, 0xffce695d, 0xffcb685a, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5645a, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55a52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd584a, 0xffbd584a, 0xffbd584a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd524a, 0xffbd514a, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54d42, 0xffb54d42, + 0xffb54c42, 0xffb54c42, 0xffb54c42, 0xffb5493f, 0xffb5493c, 0xffb5493c, 0xffb5493c, 0xffb5483a, + 0xffb5463a, 0xffb5463a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb24137, + 0xffb24137, 0xffaf4134, 0xffaf4134, 0xffad3f31, 0xffad3e31, 0xffad3f31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3a31, 0xffad3a31, 0xffad3931, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffa73929, + 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffad392c, 0xffad392c, 0xffad392f, 0xffad392c, 0xffad3a31, + 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffaf4234, 0xffaf4234, 0xffaf4234, 0xffb24337, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54942, + 0xffb54a3c, 0xffb54a3c, 0xffb54a3c, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb84e47, + 0xffba5045, 0xffba5045, 0xffbd5142, 0xffbd514a, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd564a, 0xffbd594d, 0xffbd594d, 0xffbd594d, 0xffbd5950, 0xffc55a52, + 0xffc55a52, 0xffc55c52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc56152, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56455, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffcb685a, + 0xffcb685a, 0xffcb685a, 0xffce695a, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6f65, 0xffce6f65, 0xffce7068, 0xffce7068, 0xffd6716b, + 0xffd6736b, 0xffd6736b, 0xffd6736b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6776b, + 0xffd6776b, 0xffd6786b, 0xffd6786b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd6796e, 0xffd67970, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6786b, + 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd37168, 0xffd37168, 0xffd37168, 0xffd37168, 0xffce7063, + 0xffce7063, 0xffce6f63, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6c63, 0xffce6c63, 0xffce6960, + 0xffce6960, 0xffce6960, 0xffce695d, 0xffcb685a, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5645a, 0xffc5625a, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55c52, 0xffc55c52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd584a, 0xffbd584a, 0xffbd564a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd544a, 0xffbd524a, 0xffbd514a, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54e42, 0xffb54d42, + 0xffb54d42, 0xffb54c42, 0xffb54a42, 0xffb5493f, 0xffb5493c, 0xffb5493c, 0xffb5493c, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb24137, + 0xffaf4134, 0xffaf4134, 0xffaf4134, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3b31, 0xffad3a31, 0xffad3a31, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffaa3929, + 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffad392c, 0xffad392c, 0xffad392f, 0xffad392c, 0xffad3a31, + 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3f31, + 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad4131, 0xffaf4234, 0xffaf4234, 0xffb24337, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54942, + 0xffb54942, 0xffb54a3c, 0xffb54a3c, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb84e47, + 0xffba5045, 0xffba5045, 0xffbd5142, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd584a, 0xffbd594d, 0xffbd594d, 0xffbd594d, 0xffbd5950, 0xffc55a52, + 0xffc55c52, 0xffc55c52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc56052, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56455, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc8675a, + 0xffcb685a, 0xffcb685a, 0xffce695a, 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6f65, 0xffce7068, 0xffce7068, 0xffce7068, 0xffd6716b, + 0xffd6716b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6776b, + 0xffd6756b, 0xffd6786b, 0xffd6786b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd67970, 0xffd6796e, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd6786b, + 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd37168, 0xffd37168, 0xffd37168, 0xffd37168, 0xffce7063, + 0xffce7063, 0xffce6f63, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6c63, 0xffce6c63, 0xffce6960, + 0xffce6960, 0xffce6960, 0xffce695d, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5645a, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55a52, 0xffc55a52, 0xffc55952, 0xffbd594a, + 0xffbd584a, 0xffbd584a, 0xffbd584a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd524a, 0xffbd514a, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54e42, 0xffb54d42, + 0xffb54c42, 0xffb54c42, 0xffb54c42, 0xffb5493f, 0xffb5493f, 0xffb5493c, 0xffb5493c, 0xffb5483a, + 0xffb5483a, 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb24137, + 0xffb24137, 0xffb24137, 0xffaf4134, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3b31, 0xffad3a31, 0xffad3a31, 0xffad392f, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffaa3929, + 0xffaa3929, 0xffaa3929, 0xffaa3929, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392f, 0xffad3a31, + 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, + 0xffad3f31, 0xffad3f31, 0xffad4131, 0xffaf4234, 0xffaf4234, 0xffaf4234, 0xffaf4234, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54942, + 0xffb54942, 0xffb54a3c, 0xffb54a3c, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffba5045, + 0xffba5045, 0xffba5045, 0xffbd5142, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd584a, 0xffbd594d, 0xffbd594d, 0xffbd594d, 0xffbd5950, 0xffc55a52, + 0xffc55c52, 0xffc55c52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56152, 0xffc5615a, + 0xffc56258, 0xffc56258, 0xffc56258, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffcb685a, + 0xffcb685a, 0xffcb685a, 0xffce695a, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6f65, 0xffce7068, 0xffce7068, 0xffce7068, 0xffd6716b, + 0xffd6716b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6776b, 0xffd6776b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd6796e, 0xffd67970, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd6786b, + 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6736b, 0xffd6736b, 0xffd6736b, 0xffd6716b, 0xffd6716b, 0xffce7063, + 0xffce7063, 0xffce6f63, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c5d, + 0xffce6b60, 0xffce6963, 0xffce6963, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc56158, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55d52, 0xffc55a52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584d, 0xffbd584d, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd544a, 0xffbd524a, 0xffbd514a, 0xffb55042, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb54a3f, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffaf4234, + 0xffaf4234, 0xffaf4234, 0xffad4131, 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3a31, 0xffad3a2c, + 0xffad3a2c, 0xffad3a2c, 0xffad3a2c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffad3931, 0xffad3931, 0xffad3a31, 0xffad3b31, 0xffad3a31, + 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, 0xffad3e37, + 0xffad3f34, 0xffad3f34, 0xffad3f34, 0xffad413a, 0xffad413a, 0xffaf423a, 0xffb2433a, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54a3f, + 0xffb54942, 0xffb54a3f, 0xffb54a3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffba5047, + 0xffba5047, 0xffbd5142, 0xffbd5142, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd564a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55a52, + 0xffc55c52, 0xffc55c52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc5615a, + 0xffc5625a, 0xffc5625a, 0xffc5625a, 0xffc8655a, 0xffc8655a, 0xffc8655a, 0xffc8655a, 0xffce685d, + 0xffce685d, 0xffce685d, 0xffce685d, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce7068, 0xffce7068, 0xffce7068, 0xffce7163, 0xffd6716b, + 0xffd6736b, 0xffd6736b, 0xffd6736b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6776b, 0xffd6786b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd67970, 0xffd6796e, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796b, + 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd6736b, 0xffd6716b, 0xffd6716b, 0xffd6716b, 0xffce7163, + 0xffce7063, 0xffce6f63, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6b60, + 0xffce6b60, 0xffce6b60, 0xffce6963, 0xffcb685a, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55c52, 0xffc55a52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd584d, 0xffbd584d, 0xffbd584d, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd544a, 0xffbd524a, 0xffbd514a, 0xffb55042, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb54a3f, 0xffb54a3f, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5463a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb24337, + 0xffaf4234, 0xffaf4234, 0xffad4131, 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad3e31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3a2c, + 0xffad3a2c, 0xffad3a2c, 0xffad3a2c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, 0xffad392c, + 0xffad392c, 0xffad392c, 0xffad392c, 0xffad3a31, 0xffad3a31, 0xffad3a31, 0xffad3b31, 0xffad3b31, + 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3d31, 0xffad3e31, 0xffad3e31, 0xffad3e31, 0xffad3f34, + 0xffad3f34, 0xffad3f34, 0xffad4131, 0xffaf423a, 0xffaf423a, 0xffaf423a, 0xffb2433a, 0xffb5453a, + 0xffb5453a, 0xffb5453a, 0xffb5463a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54942, + 0xffb54a3f, 0xffb54a3f, 0xffb54a3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffba5047, + 0xffba5047, 0xffba5047, 0xffbd5142, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd554a, + 0xffbd564a, 0xffbd564a, 0xffbd584a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55a52, + 0xffc55c52, 0xffc55c52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc5615a, + 0xffc5625a, 0xffc5625a, 0xffc5645a, 0xffc8655a, 0xffc8655a, 0xffc8655a, 0xffc8655a, 0xffce685d, + 0xffce685d, 0xffce685d, 0xffce695a, 0xffce6963, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce7068, 0xffce7068, 0xffce7068, 0xffce7163, 0xffd6716b, + 0xffd6736b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6776b, 0xffd6786b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd6796e, 0xffd67970, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796e, 0xffd6786b, + 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6786b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6736b, 0xffd6746b, 0xffd6716b, 0xffd6716b, 0xffd6716b, 0xffce7163, + 0xffce7063, 0xffce6f63, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6b60, + 0xffce6b60, 0xffce6b60, 0xffce6963, 0xffce695a, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc56158, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55d52, 0xffc55d52, 0xffc55c52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd584d, 0xffbd584d, 0xffbd584d, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd524a, 0xffbd524a, 0xffbd524a, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54e42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb54a3f, 0xffb5493a, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb24337, + 0xffaf4234, 0xffaf4234, 0xffad4131, 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3b2f, + 0xffad3b2f, 0xffad3a2c, 0xffad3a2c, 0xffad392c, 0xffad392f, 0xffad392c, 0xffad392c, 0xffad392f, + 0xffad392c, 0xffad392f, 0xffad392f, 0xffad3a31, 0xffad3a31, 0xffad3b31, 0xffad3b31, 0xffad3b31, + 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3d31, 0xffad3e31, 0xffad3e31, 0xffad3e31, 0xffad3f34, + 0xffad3f34, 0xffad3f34, 0xffad4131, 0xffad413a, 0xffaf423a, 0xffaf423a, 0xffb2433a, 0xffb5453a, + 0xffb5453a, 0xffb5463a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54942, + 0xffb54942, 0xffb54c3c, 0xffb54a3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffba5047, + 0xffba5047, 0xffba5047, 0xffba5047, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd544a, 0xffbd564a, + 0xffbd564a, 0xffbd564a, 0xffbd584a, 0xffc0594d, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc55a52, + 0xffc55a52, 0xffc55d52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc56152, 0xffc5625a, + 0xffc5625a, 0xffc5645a, 0xffc5645a, 0xffc8655a, 0xffc8655a, 0xffc8655a, 0xffcb655a, 0xffce685d, + 0xffce685d, 0xffce695a, 0xffce695a, 0xffce6b63, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce7068, 0xffce7068, 0xffce7068, 0xffce7068, 0xffd6716b, + 0xffd6736b, 0xffd6736b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6776b, 0xffd6776b, 0xffd6786b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd6796e, 0xffd6796e, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff6e3e37, 0xffa55d52, 0xffa55d52, 0xffc57163, + 0xffd0776e, 0xffd67973, 0xffd67973, 0xffd67970, 0xffd67970, 0xffd6796e, 0xffd6796e, 0xffd6796b, + 0xffd6786b, 0xffd6786b, 0xffd6786b, 0xffd6776b, 0xffd6776b, 0xffd6756b, 0xffd6756b, 0xffd6756b, + 0xffd6756b, 0xffd6746b, 0xffd6746b, 0xffd6736b, 0xffd6736b, 0xffd6716b, 0xffd6716b, 0xffce7163, + 0xffce7063, 0xffce7063, 0xffce6f63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce6c5d, + 0xffce6b60, 0xffce6b60, 0xffce6963, 0xffcb685a, 0xffcb685a, 0xffcb685a, 0xffc8675a, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc56158, 0xffc56158, 0xffc56158, 0xffc56155, 0xffc56052, + 0xffc55e52, 0xffc55e52, 0xffc55e52, 0xffc55c52, 0xffc55c52, 0xffc55a52, 0xffc55a52, 0xffbd594a, + 0xffbd594a, 0xffbd584d, 0xffbd584d, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd554a, 0xffbd544a, + 0xffbd544a, 0xffbd524a, 0xffbd514a, 0xffb55142, 0xffb55042, 0xffb55042, 0xffb54e42, 0xffb54d42, + 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54a3f, 0xffb54a3f, 0xffb54a3f, 0xffb5493a, 0xffb5483a, + 0xffb5483a, 0xffb5483a, 0xffb5463a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb5453a, 0xffb24337, + 0xffaf4234, 0xffaf4234, 0xffaf4234, 0xffad4131, 0xffad3f31, 0xffad3f31, 0xffad3f31, 0xffad3d31, + 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3b31, 0xffad3a2c, + 0xffad3b2f, 0xffad3b2f, 0xffad3b2f, 0xffad392f, 0xffad392f, 0xffad392f, 0xffad392f, 0xffad392f, + 0xffad392f, 0xffad392f, 0xffad392f, 0xffad3a31, 0xffad3a31, 0xffad3b31, 0xffad3b31, 0xffad3b31, + 0xffad3b31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3d31, 0xffad3e31, 0xffad3f31, 0xffad3f34, + 0xffad3f34, 0xffad3f34, 0xffad4131, 0xffaf423a, 0xffb2433a, 0xffb2433a, 0xffb2433a, 0xffb5453a, + 0xffb5453a, 0xffb5463a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb5483a, 0xffb54942, + 0xffb54942, 0xffb54a3f, 0xffb54a3f, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffb54d42, 0xffba5047, + 0xffba5047, 0xffbd5142, 0xffbd5142, 0xffbd524a, 0xffbd544a, 0xffbd544a, 0xffbd554a, 0xffbd564a, + 0xffbd564a, 0xffbd564a, 0xffbd584a, 0xffc0594d, 0xffc0594d, 0xffc35950, 0xffc35950, 0xffc55a52, + 0xffc55c52, 0xffc55c52, 0xffc55d52, 0xffc55e52, 0xffc55e52, 0xffc56052, 0xffc56152, 0xffc5625a, + 0xffc5625a, 0xffc5625a, 0xffc5645a, 0xffc8655a, 0xffc8655a, 0xffc8655a, 0xffc8655a, 0xffce685d, + 0xffce685d, 0xffce685d, 0xffce695a, 0xffce6b63, 0xffce6b63, 0xffce6c63, 0xffce6c63, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffce7068, 0xffce7068, 0xffce7068, 0xffce7068, 0xffd6716b, + 0xffd6716b, 0xffd6746b, 0xffd6746b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6756b, 0xffd6776b, + 0xffd6776b, 0xffd6776b, 0xffd6786b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796b, 0xffd6796e, + 0xffd67970, 0xffd6796e, 0xffd67970, 0xffd67973, 0xffd67973, 0xffd0776e, 0xffc57163, 0xffb5655a, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00100400, 0xff473531, 0xff7e6563, 0xff7e6563, 0xffad655a, + 0xffad7b73, 0xffad7b73, 0xffad7b73, 0xffb57573, 0xffb57573, 0xffb57573, 0xffb57573, 0xffb5756b, + 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5716b, + 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffad716b, + 0xffad716b, 0xffad716b, 0xffad716b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, + 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffb5655a, 0xffb5655a, 0xffb5655a, 0xffb5655a, 0xffb5615a, + 0xffb5615a, 0xffb5615a, 0xffb5615a, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d52, + 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffad5952, 0xffad5952, 0xffad5952, 0xffad5952, 0xffad594a, + 0xffad594a, 0xffad594a, 0xffad594a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad514a, + 0xffad514a, 0xffad514a, 0xffad514a, 0xffa55142, 0xffa55142, 0xffa55142, 0xffa55142, 0xffa54d42, + 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54942, + 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xff9c453a, + 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c413a, + 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, + 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c3d3a, + 0xff9c3d3a, 0xff9c3d3a, 0xff9c3d3a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, + 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c453a, + 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xffa54942, + 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54d42, + 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffad514a, + 0xffad514a, 0xffad514a, 0xffad514a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad554a, + 0xffad554a, 0xffad554a, 0xffad554a, 0xffad5952, 0xffad5952, 0xffad5952, 0xffad5952, 0xffb55952, + 0xffb55952, 0xffb55952, 0xffb55952, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d5a, + 0xffb55d5a, 0xffb55d5a, 0xffb55d5a, 0xffb5615a, 0xffb5615a, 0xffb5615a, 0xffb5615a, 0xffbd655a, + 0xffbd655a, 0xffbd655a, 0xffbd655a, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, + 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad716b, 0xffad716b, 0xffad716b, 0xffad716b, 0xffb5716b, + 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5756b, + 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb57573, + 0xffb57573, 0xffb57573, 0xffb57573, 0xffad7b73, 0xffad7b73, 0xffad7b73, 0xffad655a, 0xff7e6463, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00100400, 0xff473531, 0xff7e6563, 0xff7e6563, 0xffad655a, + 0xffad7b73, 0xffad7b73, 0xffad7b73, 0xffb57573, 0xffb57573, 0xffb57573, 0xffb57573, 0xffb5756b, + 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5716b, + 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffad716b, + 0xffad716b, 0xffad716b, 0xffad716b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, + 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffb5655a, 0xffb5655a, 0xffb5655a, 0xffb5655a, 0xffb5615a, + 0xffb5615a, 0xffb5615a, 0xffb5615a, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d52, + 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffad5952, 0xffad5952, 0xffad5952, 0xffad5952, 0xffad594a, + 0xffad594a, 0xffad594a, 0xffad594a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad514a, + 0xffad514a, 0xffad514a, 0xffad514a, 0xffa55142, 0xffa55142, 0xffa55142, 0xffa55142, 0xffa54d42, + 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54942, + 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xff9c453a, + 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c413a, + 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, + 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c3d3a, + 0xff9c3d3a, 0xff9c3d3a, 0xff9c3d3a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, + 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c413a, 0xff9c453a, + 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xff9c453a, 0xffa54942, + 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54942, 0xffa54d42, + 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffa54d42, 0xffad514a, + 0xffad514a, 0xffad514a, 0xffad514a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad554a, 0xffad554a, + 0xffad554a, 0xffad554a, 0xffad554a, 0xffad5952, 0xffad5952, 0xffad5952, 0xffad5952, 0xffb55952, + 0xffb55952, 0xffb55952, 0xffb55952, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d52, 0xffb55d5a, + 0xffb55d5a, 0xffb55d5a, 0xffb55d5a, 0xffb5615a, 0xffb5615a, 0xffb5615a, 0xffb5615a, 0xffbd655a, + 0xffbd655a, 0xffbd655a, 0xffbd655a, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, + 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad716b, 0xffad716b, 0xffad716b, 0xffad716b, 0xffb5716b, + 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5756b, + 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb57573, + 0xffb57573, 0xffb57573, 0xffb57573, 0xffad7b73, 0xffad7b73, 0xffad7b73, 0xffad655a, 0xff7e6463, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00100400, 0xff7e6563, 0xff7e6563, 0xff7e6563, 0xffad655a, + 0xffad655a, 0xffad7b73, 0xffad7b73, 0xffb57573, 0xffb57573, 0xffb57573, 0xffb57573, 0xffb5756b, + 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5716b, + 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffad716b, + 0xffad716b, 0xffad716b, 0xffad716b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, + 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad7c76, 0xffad7c76, 0xffad7c76, 0xffad7c76, 0xffad7976, + 0xffad7976, 0xffad7976, 0xffad7976, 0xffad7770, 0xffad7770, 0xffad7770, 0xffad7770, 0xffad7870, + 0xffad7870, 0xffad7870, 0xffad7870, 0xffa77570, 0xffa77570, 0xffa77570, 0xffa77570, 0xffa7756b, + 0xffa7756b, 0xffa7756b, 0xffa7756b, 0xffa7736b, 0xffa7736b, 0xffa7736b, 0xffa7736b, 0xffa7706b, + 0xffa7706b, 0xffa7706b, 0xffa7706b, 0xffa27065, 0xffa27065, 0xffa27065, 0xffa27065, 0xffa26d65, + 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26b68, + 0xffa26b68, 0xffa26b68, 0xffa26b68, 0xffa26c68, 0xffa26c68, 0xffa26c68, 0xffa26c68, 0xff9c6963, + 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6763, + 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, + 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6463, + 0xff9c6463, 0xff9c6463, 0xff9c6463, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, + 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6763, 0xff9c6963, + 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xffa26c68, + 0xffa26c68, 0xffa26c68, 0xffa26c68, 0xffa26b68, 0xffa26b68, 0xffa26b68, 0xffa26b68, 0xffa26d65, + 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa26d65, 0xffa7706b, + 0xffa7706b, 0xffa7706b, 0xffa7706b, 0xffa7736b, 0xffa7736b, 0xffa7736b, 0xffa7736b, 0xffa7736b, + 0xffa7736b, 0xffa7736b, 0xffa7736b, 0xffa77570, 0xffa77570, 0xffa77570, 0xffa77570, 0xffad7570, + 0xffad7570, 0xffad7570, 0xffad7570, 0xffad7870, 0xffad7870, 0xffad7870, 0xffad7870, 0xffad7776, + 0xffad7776, 0xffad7776, 0xffad7776, 0xffad7976, 0xffad7976, 0xffad7976, 0xffad7976, 0xffaf7c76, + 0xffaf7c76, 0xffaf7c76, 0xffaf7c76, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, + 0xffad6d6b, 0xffad6d6b, 0xffad6d6b, 0xffad716b, 0xffad716b, 0xffad716b, 0xffad716b, 0xffb5716b, + 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5716b, 0xffb5756b, + 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb5756b, 0xffb57573, + 0xffb57573, 0xffb57573, 0xffb57573, 0xffad7b73, 0xffad7b73, 0xffad655a, 0xffad655a, 0xff7e6463, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00100400, 0xff7e6563, 0xffb59694, 0xffb59694, 0xffada6a5, + 0xffada6a5, 0xffada6a5, 0xffada6a5, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, + 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caeb5, + 0xff9caeb5, 0xff9caeb5, 0xff9caeb5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, + 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, + 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, + 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, + 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, + 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, + 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, + 0xff9cb2b5, 0xff9cb2b5, 0xff9cb2b5, 0xff9caeb5, 0xff9caeb5, 0xff9caeb5, 0xff9caeb5, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, + 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caaad, + 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff9caaad, 0xff94aaad, + 0xff94aaad, 0xff94aaad, 0xff94aaad, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, 0xffadaead, + 0xffadaead, 0xffadaead, 0xffadaead, 0xffada6a5, 0xffada6a5, 0xffada6a5, 0xffada6a5, 0xffbd9694, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff737473, 0xffadaead, 0xffadaead, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffb5b6b5, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, + 0x11000000, 0x22000000, 0x22000000, 0x33000000, 0x44000000, 0x55000000, 0x44000000, 0x33000000, + 0x33000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x22000000, 0x55000000, 0x88000000, 0xbb000000, + 0xdd0e0403, 0xdd0e0403, 0xee100503, 0xee100503, 0xff100503, 0xff100503, 0xff100503, 0xee100503, + 0xee100503, 0xee100503, 0xdd0e0403, 0xaa000000, 0x77000000, 0x44000000, 0x22000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff737573, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, + 0xffa5a6a5, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, + 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffadaaad, 0xffa5a6a5, 0xffa5a6a5, 0xffa5a6a5, + 0xffa5a6a5, 0xff737173, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x33000000, 0x880e0403, 0xcc0e0403, 0xee0e0403, 0xff1b0805, 0xff1b0805, 0xff1b0805, + 0xff1b0805, 0xff1b0805, 0xff210b05, 0xff210b05, 0xff210b05, 0xff210b05, 0xff210b05, 0xff210b05, + 0xff210b05, 0xff210b05, 0xff1b0805, 0xff1b0805, 0xff1b0805, 0xee1b0805, 0xdd0b0403, 0x880b0403, + 0x44000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffadaaad, 0xffdbbeb8, 0xffe9dfdb, 0xffe9dfdb, + 0xffe9dfdb, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, + 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6dbd6, 0xffe6dbd6, 0xffe6dbd6, + 0xffe6dbd6, 0xffa5a6a5, 0x00000000, 0x00000000, 0x00000000, 0x00080000, 0x00080000, 0x11080000, + 0x11080000, 0x22210400, 0x22210400, 0x33210400, 0x33210400, 0x33210400, 0x33210400, 0x33210400, + 0x22210400, 0x11100400, 0x11100400, 0x00100400, 0x00100400, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22000000, 0x66080303, + 0xaa100505, 0xee190808, 0xff1b0805, 0xff1b0805, 0xff290c08, 0xff290c08, 0xff290c08, 0xff290c08, + 0xff290c08, 0xff290c08, 0xff311008, 0xff311008, 0xff311008, 0xff311008, 0xff311008, 0xff311008, + 0xff210b05, 0xff311008, 0xff290c08, 0xff290c08, 0xff290c08, 0xff290c08, 0xff210c08, 0xff210c08, + 0xee160805, 0xaa0b0403, 0x55000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11030303, 0x22030303, 0x22080808, 0x330b0b0b, 0x44101010, 0x33101010, 0x330b0b0b, 0x33080808, + 0x22050505, 0x11030303, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffadaaad, 0xffe9dfdb, 0xfff7ffff, 0xffce9e94, + 0xffce9e94, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffce9e94, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffce968c, 0xffce968c, 0xffce968c, 0xffce968c, 0xffc59284, 0xffc59284, 0xfff7ffff, + 0xffe6dbd6, 0xffa5a6a5, 0x00000000, 0x00000000, 0x00000000, 0x00080000, 0x11080000, 0x22080000, + 0x33080000, 0x66210400, 0x99210400, 0xaa210400, 0xbb210400, 0xbb210400, 0xbb210400, 0xaa210400, + 0x66210400, 0x33100400, 0x22100400, 0x11100400, 0x00100400, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x66190705, 0xcc210808, 0xff340f0e, + 0xff340f0e, 0xff340f0e, 0xff3a1010, 0xff3a1010, 0xff3a1010, 0xff3a1010, 0xff3a1010, 0xff4a1613, + 0xff4a1613, 0xff3a1010, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xff3a1010, 0xff471613, + 0xff3a1010, 0xff3a1010, 0xff311010, 0xff311010, 0xff311010, 0xff311010, 0xff37100b, 0xff37100b, + 0xff290c08, 0xff290c08, 0xee160705, 0xaa160705, 0x33000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00080808, 0x00080808, 0x11080808, 0x55503a37, 0x886b494a, + 0xbb8c6160, 0xddad7976, 0xeead7976, 0xffa57479, 0xffa57479, 0xeea57479, 0xdd9c6163, 0xcc794542, + 0x99794542, 0x663c2421, 0x22000400, 0x11080400, 0x11080400, 0x00080400, 0x00080400, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffadaaad, 0xffe9dfdb, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffce9e94, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffce968c, 0xffce968c, 0xffce968c, 0xffce968c, 0xffc59284, 0xffc59284, 0xffc59284, + 0xffe6dbd6, 0xffa5a6a5, 0x00000000, 0x00000000, 0x00000000, 0x11080000, 0x22080000, 0x44080000, + 0xaa080000, 0xdd55241b, 0xee894537, 0xee894537, 0xee894537, 0xee9f584d, 0xee9f584d, 0xee9f584d, + 0xdd9f584d, 0xbb100400, 0x55100400, 0x22100400, 0x11100400, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x22000000, 0x99190705, 0xee310d0b, 0xff340f0e, 0xff340f0e, + 0xff340f0e, 0xff471613, 0xff471613, 0xff471613, 0xff471613, 0xff471613, 0xff4a1613, 0xff5a1b16, + 0xff4a1613, 0xff5a1b16, 0xff501813, 0xff501813, 0xff501813, 0xff501813, 0xff551b16, 0xff471613, + 0xff471613, 0xff471613, 0xff421613, 0xff421613, 0xff421613, 0xff421613, 0xff37100b, 0xff37100b, + 0xff37100b, 0xff37100b, 0xff2c0d0b, 0xff2c0d0b, 0xcc160705, 0x44000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x33080808, 0x88503a37, 0xcc976c65, 0xffde9e94, 0xffce928c, + 0xffce928c, 0xffce928c, 0xffad7976, 0xffad878f, 0xffad878f, 0xffad878f, 0xffa57479, 0xffb56563, + 0xffb56563, 0xffb56563, 0xdd794542, 0x994a2019, 0x44080400, 0x11080400, 0x11080400, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffadaaad, 0xffe9dfdb, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffce9e94, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffce968c, 0xffce968c, 0xffce968c, 0xffce968c, 0xffc59284, 0xffc59284, 0xffc59284, + 0xffe6dbd6, 0xffa5a6a5, 0x00000000, 0x00000000, 0x00000000, 0x11080000, 0x33080000, 0xaa080000, + 0xee9c3d31, 0xee894537, 0xeebd6552, 0xeebd6552, 0xeebd6552, 0xee9f584d, 0xee9f584d, 0xee9f584d, + 0xeede8273, 0xeed6c2bd, 0xbb100400, 0x33100400, 0x11100400, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x66190705, 0xdd310d0b, 0xff4a1410, 0xff4a1410, 0xff471613, 0xff471613, + 0xff471613, 0xff471613, 0xff551b16, 0xff551b16, 0xff551b16, 0xff551b16, 0xff5a1b16, 0xff5a1b16, + 0xff6b2019, 0xff5a1b16, 0xff5d1c16, 0xff5d1c16, 0xff5d1c16, 0xff5d1c16, 0xff551b16, 0xff551b16, + 0xff551b16, 0xff551b16, 0xff521b16, 0xff421613, 0xff421613, 0xff421613, 0xff45140e, 0xff45140e, + 0xff45140e, 0xff45140e, 0xff421410, 0xff421410, 0xff2c0d0b, 0xdd160705, 0x77000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x22000000, 0x884d3634, 0xdd976c65, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffce928c, + 0xffce928c, 0xffad7976, 0xffad7976, 0xffad878f, 0xffb59aa5, 0xffad878f, 0xffad878f, 0xffb56563, + 0xffb56563, 0xffb56563, 0xffb56563, 0xffce594a, 0xdd8c3d31, 0x994a2019, 0x44080400, 0x11000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00080408, 0xff979697, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9e94, 0xffce9e94, 0xffce9a8f, 0xffce9a8f, 0xffce9a94, 0xffce9a94, 0xffce9a94, + 0xffce9a94, 0xffce968c, 0xffc88f84, 0xffc88f84, 0xffc88f84, 0xffbd8273, 0xffbd8273, 0xffbd8273, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x11000000, 0x22210400, 0x66210400, 0xdd210400, + 0xee945a52, 0xeea5615a, 0xeeaa6d68, 0xeeaa6d68, 0xeeaa6d68, 0xeead6563, 0xeead6563, 0xeeaf6c68, + 0xeeb57973, 0xeea7938f, 0xeeefdbd6, 0x77190400, 0x22190400, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x77190808, 0xee4a1410, 0xff4a1410, 0xff4a1410, 0xff4a1410, 0xff5a1c19, 0xff5a1c19, + 0xff5a1c19, 0xff5a1c19, 0xff632019, 0xff632019, 0xff632019, 0xff632019, 0xff6b2019, 0xff6b2019, + 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff632019, 0xff632019, + 0xff632019, 0xff632019, 0xff632019, 0xff521b16, 0xff521b16, 0xff521b16, 0xff521810, 0xff521810, + 0xff521810, 0xff45140e, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xee290c08, 0x66000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x554d3634, 0xbb9a6c68, 0xffe6a29c, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffce928c, + 0xffce928c, 0xffad7976, 0xffad7976, 0xffad878f, 0xffb59aa5, 0xffb59aa5, 0xffad878f, 0xffb56563, + 0xffb56563, 0xffb56563, 0xffb56563, 0xffce594a, 0xffce594a, 0xffce594a, 0xcc8c3d31, 0x77311010, + 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00080408, 0xff979697, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9a8f, 0xffce9a8f, 0xffce9a8f, 0xffce9689, 0xffce9a94, 0xffdebab8, 0xffdebab8, + 0xffce9a94, 0xffc88f84, 0xffc88f84, 0xffc88f84, 0xffc3887b, 0xffbd8273, 0xffbd8273, 0xffbd8273, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x11000000, 0x33210400, 0x99210400, 0xee945a52, + 0xee945a52, 0xeeaa6d68, 0xeeaf7976, 0xeeaf7976, 0xeeaf7976, 0xeeaf6c68, 0xeeaf6c68, 0xeeaf6c68, + 0xeeb2736e, 0xeea7938f, 0xeeefdbd6, 0xaa190400, 0x33190400, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080000, 0x00080000, + 0x662c0c08, 0xee501810, 0xff521819, 0xff521819, 0xff521819, 0xff631e1b, 0xff631c19, 0xff631c19, + 0xff6e221b, 0xff6e221b, 0xff6b2019, 0xff76241b, 0xff76241b, 0xff76241b, 0xff732421, 0xff732421, + 0xff732421, 0xff732421, 0xff732421, 0xff732421, 0xff732421, 0xff732421, 0xff76241b, 0xff6b2019, + 0xff6b2019, 0xff6b2019, 0xff65201b, 0xff65201b, 0xff65201b, 0xff5a1c19, 0xff581c16, 0xff581c16, + 0xff581c16, 0xff4a1810, 0xff4d1813, 0xff4d1813, 0xff4d1813, 0xff421410, 0xff34120b, 0xdd1e0b05, + 0x55080400, 0x11080400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x775a413a, + 0xddb27f76, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffdb9a91, 0xffd68e8c, + 0xffc07f7e, 0xffaa7070, 0xffaa7070, 0xffaa8e97, 0xffb8a2aa, 0xffb8a2aa, 0xffaa8e97, 0xff94696b, + 0xff9c5e5d, 0xff9c5e5d, 0xffa55450, 0xffbd5142, 0xffbd5142, 0xffbd493c, 0xffbd493c, 0xeeb53929, + 0x9942160e, 0x33080400, 0x11080400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00080408, 0xff979697, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9689, 0xffce9689, 0xffce9689, 0xffce9284, 0xffce9a94, 0xfffffbff, 0xfffffbff, + 0xffce9a94, 0xffc88f84, 0xffc3887b, 0xffc3887b, 0xffc3887b, 0xffbd8273, 0xffbd8273, 0xffbd8273, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x11000000, 0x44210400, 0xbb210400, 0xee945a52, + 0xeece867b, 0xeeaf7976, 0xeeaf7976, 0xeeaf7976, 0xeeaf7976, 0xeeb2736e, 0xeeb2736e, 0xeeaf6c68, + 0xeeb2736e, 0xeea7938f, 0xeeefdbd6, 0xcc604c47, 0x44190400, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080000, 0x55080000, + 0xee501810, 0xff501810, 0xff631e1b, 0xff631e1b, 0xff631e1b, 0xff73231e, 0xff6e221b, 0xff6e221b, + 0xff79271e, 0xff6e221b, 0xff76241b, 0xff76241b, 0xff76241b, 0xff81281e, 0xff792721, 0xff792721, + 0xff792721, 0xff792721, 0xff7b2721, 0xff7b2721, 0xff7b2721, 0xff7b2721, 0xff76241b, 0xff76241b, + 0xff76241b, 0xff76241b, 0xff70241e, 0xff70241e, 0xff70241e, 0xff65201b, 0xff65201b, 0xff65201b, + 0xff581c16, 0xff581c16, 0xff4d1813, 0xff4d1813, 0xff4d1813, 0xff4d1813, 0xff4a1810, 0xff34120b, + 0xcc1e0b05, 0x44080400, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7745312f, 0xeede9e94, + 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffdb9a91, 0xffd9968f, 0xffd68e8c, + 0xffc07f7e, 0xffaa7070, 0xffaa7070, 0xffaa8e97, 0xffb8a2aa, 0xffb8a2aa, 0xffaa8e97, 0xff9c5e5d, + 0xffa55450, 0xffa55450, 0xffa55450, 0xffbd5142, 0xffbd493c, 0xffbd493c, 0xffbd4137, 0xffb53929, + 0xeeb53929, 0x9942160e, 0x33080400, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00080408, 0xff979697, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9689, 0xffce9284, 0xffce9284, 0xffce9284, 0xffdebab8, 0xfffffbff, 0xfffffbff, + 0xffefdbdb, 0xffc3887b, 0xffc3887b, 0xffc3887b, 0xffbd8273, 0xffbd8273, 0xffbd8273, 0xffbd8273, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x55210400, 0xcc210400, 0xeece867b, + 0xeece867b, 0xeeb58684, 0xeeb58684, 0xeeb58684, 0xeeaf7976, 0xeeb57973, 0xeeb57973, 0xeeb2736e, + 0xeeb57973, 0xeea7938f, 0xeea7938f, 0xdda7938f, 0x66190400, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33080000, 0xdd501810, + 0xff732419, 0xff732419, 0xff73231e, 0xff73231e, 0xff73231e, 0xff73231e, 0xff79271e, 0xff79271e, + 0xff79271e, 0xff79271e, 0xff81281e, 0xff81281e, 0xff81281e, 0xff81281e, 0xff7e2a21, 0xff7e2a21, + 0xff7e2a21, 0xff7e2a21, 0xff842a21, 0xff842a21, 0xff842a21, 0xff842a21, 0xff8c2d21, 0xff81281e, + 0xff81281e, 0xff81281e, 0xff7b2821, 0xff70241e, 0xff70241e, 0xff70241e, 0xff732421, 0xff65201b, + 0xff65201b, 0xff581c16, 0xff581c16, 0xff581c16, 0xff4d1813, 0xff4d1813, 0xff4a1810, 0xff4a1810, + 0xff34120b, 0x99080400, 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7745312f, 0xeece928c, 0xffde9e94, + 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffdb9a91, 0xffdb9a91, 0xffd9968f, 0xffd68e8c, + 0xffc07f7e, 0xffaa7070, 0xff946163, 0xff9c7984, 0xffc5b6bd, 0xffc5b6bd, 0xff9c7984, 0xffa55450, + 0xffa55450, 0xffa55450, 0xffad4942, 0xffbd493c, 0xffbd493c, 0xffbd4137, 0xffbd3931, 0xffb53929, + 0xffb53929, 0xeeb53929, 0x9942160e, 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffce9684, 0xffce9684, + 0xffce9684, 0xffce9284, 0xffce9284, 0xffce9284, 0xffce9284, 0xfffffbf7, 0xffffffff, 0xffffffff, + 0xfffffbf7, 0xffd3aaa2, 0xffbd8273, 0xffbd8273, 0xffbd8273, 0xffad796b, 0xffad796b, 0xffad796b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x66190000, 0xdd523331, 0xeec59a94, + 0xeec59a94, 0xeeb88e84, 0xeeb88e84, 0xeeb5867b, 0xeeb5867b, 0xeeaf7c73, 0xeead756b, 0xeead756b, + 0xeead756b, 0xee947168, 0xeecea69c, 0xeecea69c, 0x77210800, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0xaa2c0c08, 0xff732419, + 0xff732419, 0xff732419, 0xff73231e, 0xff73231e, 0xff842821, 0xff842821, 0xff79271e, 0xff842d21, + 0xff842d21, 0xff842d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff842d21, 0xff842d21, + 0xff842d21, 0xff842d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, + 0xff8c2d21, 0xff81281e, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff732421, 0xff732421, + 0xff732421, 0xff65201b, 0xff632019, 0xff581c16, 0xff581c16, 0xff581c16, 0xff4a1810, 0xff4a1810, + 0xff34120b, 0xee1e0b05, 0x66000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x5545312f, 0xddce928c, 0xffce928c, 0xffde9e94, + 0xffde9e94, 0xffde9e94, 0xffde9e94, 0xffdb9a91, 0xffdb9a91, 0xffd9968f, 0xffd6928c, 0xffd68e8c, + 0xffc07f7e, 0xffaa7070, 0xff946163, 0xff9c7984, 0xffc5b6bd, 0xffc5b6bd, 0xff9c7984, 0xffa55450, + 0xffad4942, 0xffad4942, 0xffad4942, 0xffbd493c, 0xffbd4137, 0xffbd3931, 0xffbd3931, 0xffb53929, + 0xffb53929, 0xffb53929, 0xee7b271b, 0x88290c08, 0x33000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffce9684, 0xffce9684, + 0xffce9684, 0xffce9284, 0xffce9284, 0xffce9284, 0xffefdbd6, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffe9d2d0, 0xffbd8273, 0xffbd8273, 0xffbd8273, 0xffad796b, 0xffad796b, 0xffad796b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x77190000, 0xdd523331, 0xeec59a94, + 0xeec59a94, 0xeeba968c, 0xeeb88e84, 0xeeb88e84, 0xeeb5867b, 0xeeb2837b, 0xeeaf7c73, 0xeead756b, + 0xeead756b, 0xee947168, 0xeecea69c, 0xeecea69c, 0x77210800, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x44000000, 0xee6b2021, 0xff762421, + 0xff762421, 0xff762421, 0xff7b2421, 0xff862824, 0xff862824, 0xff912d26, 0xff943121, 0xff943121, + 0xff943121, 0xff943121, 0xff8c3129, 0xff8c3129, 0xff8c3129, 0xff8c3129, 0xff8c3529, 0xff8c3529, + 0xff8c3529, 0xff8c3529, 0xff8c3529, 0xff8c3529, 0xff8c3529, 0xff8c3529, 0xff8c3129, 0xff8c3129, + 0xff8c3129, 0xff8c3129, 0xff7b2d21, 0xff7b2d21, 0xff7b2d21, 0xff7b2d21, 0xff7b2d29, 0xff7b2d29, + 0xff7b2d29, 0xff7b2d29, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff581c16, 0xff4d1813, + 0xff4d1813, 0xff421410, 0xaa000000, 0x33000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x22191419, 0xbb976865, 0xffd6928c, 0xffd6928c, 0xffde9694, + 0xffde9694, 0xffde9694, 0xffde9694, 0xffde9694, 0xffde9694, 0xffdb908c, 0xffdb908c, 0xffd68a7b, + 0xffbd776b, 0xffa5645a, 0xff8c514a, 0xff9a7484, 0xffd6cad6, 0xffd6cad6, 0xff9a7484, 0xffad4942, + 0xffa2423a, 0xffad4942, 0xffad4942, 0xffc54131, 0xffbd3d2f, 0xffb5392c, 0xffb5392c, 0xffaa352c, + 0xffaa352c, 0xffaa352c, 0xff9f3126, 0xdd652216, 0x55080400, 0x22080400, 0x11080400, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffce9684, 0xffce9684, + 0xffce9684, 0xffce9284, 0xffce9284, 0xffdeb6ad, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffffbff, 0xffd3aaa2, 0xffbd8273, 0xffbd8273, 0xffad796b, 0xffad796b, 0xffad796b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x77190000, 0xee8c6763, 0xeec59a94, + 0xeec59a94, 0xeebd9e94, 0xeeba968c, 0xeeb88e84, 0xeeb88e84, 0xeeb2837b, 0xeeb2837b, 0xeeaf7c73, + 0xeead756b, 0xee947168, 0xeecea69c, 0xeecea69c, 0x88210800, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0xaa31100e, 0xff812821, 0xff812821, + 0xff762421, 0xff812821, 0xff862824, 0xff862824, 0xff912d26, 0xff912d26, 0xff943121, 0xff9a746e, + 0xff9c9694, 0xff9c9694, 0xff978481, 0xff978481, 0xff978481, 0xff978481, 0xffa29391, 0xffa29391, + 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29291, 0xffa29291, + 0xffa29291, 0xffa29291, 0xffb2aeaa, 0xffb2aeaa, 0xffb2aeaa, 0xffb2aeaa, 0xffceb6b2, 0xfff7fbf7, + 0xfff7fbf7, 0xfff7fbf7, 0xffbd9694, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff581c16, 0xff581c16, + 0xff4d1813, 0xff4d1813, 0xee2c0d0b, 0x66000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x88583e3f, 0xffd6928c, 0xffd6928c, 0xffd6928c, 0xffdb928f, + 0xffdb928f, 0xffdb928f, 0xffdb928f, 0xffdb908c, 0xffdb908c, 0xffdb908c, 0xffdb908c, 0xffd68a7b, + 0xffbd776b, 0xffa5645a, 0xff8c514a, 0xff9a7484, 0xffd6cad6, 0xffd6cad6, 0xff9a7484, 0xff973b31, + 0xffa2423a, 0xffa2423a, 0xffa2423a, 0xffbd3d2f, 0xffb5392c, 0xffb5392c, 0xffad3529, 0xffaa352c, + 0xffaa352c, 0xff9f3126, 0xff9f3126, 0xff943121, 0xaa37130b, 0x44080400, 0x11080400, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffce9684, 0xffce9684, + 0xffce9684, 0xffce9284, 0xffce9284, 0xffefdbd6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffffbff, 0xfffffbff, 0xffbd8273, 0xffbd8273, 0xffad796b, 0xffad796b, 0xffad796b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x88190000, 0xee8c6763, 0xeec59a94, + 0xeec59a94, 0xeebd9e94, 0xeeba968c, 0xeeba968c, 0xeeb88e84, 0xeeb58a84, 0xeeb2837b, 0xeeaf7c73, + 0xeead756b, 0xee947168, 0xeecea69c, 0xeecea69c, 0x99210800, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x33000000, 0xee63201b, 0xff812821, 0xff812821, + 0xff812821, 0xff8c2d21, 0xff912d26, 0xff912d26, 0xff912d26, 0xff912d26, 0xff943121, 0xff943121, + 0xff9c9694, 0xff9c9694, 0xff978481, 0xff978481, 0xff978481, 0xff9caead, 0xffa29391, 0xffa29391, + 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29391, 0xffa29291, 0xffa29291, + 0xffa29291, 0xffa29291, 0xffb2aeaa, 0xffb2aeaa, 0xffb2aeaa, 0xffb2aeaa, 0xfff7fbf7, 0xfff7fbf7, + 0xfff7fbf7, 0xfff7fbf7, 0xff864842, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff581c16, 0xff581c16, + 0xff581c16, 0xff4d1813, 0xff421410, 0x99000000, 0x33000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x33211413, 0xdd976865, 0xffd6928c, 0xffd6928c, 0xffd6928c, 0xffd98e89, + 0xffd98e89, 0xffd98e89, 0xffd98e89, 0xffdb908c, 0xffdb908c, 0xffd98b84, 0xffd98b84, 0xffd68a7b, + 0xffbd776b, 0xffa5645a, 0xff8c514a, 0xff7b495a, 0xffd6cad6, 0xffd6cad6, 0xff7b495a, 0xff8c3529, + 0xff973b31, 0xff973b31, 0xff973b31, 0xffb5392c, 0xffb5392c, 0xffad3529, 0xffad3529, 0xffaa352c, + 0xff9f3126, 0xff9f3126, 0xff9f3126, 0xff943121, 0xee652216, 0x77080400, 0x33080400, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffc58a7b, 0xffc58a7b, + 0xffc58a7b, 0xffbd8273, 0xffe9d0cb, 0xfffff7f7, 0xfffff7f7, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfff7f3f7, 0xfff7f3f7, 0xffdec9c8, 0xffad756b, 0xffa57163, 0xffa57163, 0xffa57163, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x88190000, 0xee977779, 0xeed6b2b5, + 0xeed6b2b5, 0xeec3a39f, 0xeec09d9a, 0xeebd9694, 0xeebd9694, 0xeeb58b84, 0xeeb5847b, 0xeeb57d73, + 0xeeb57d73, 0xee9a6f68, 0xeecea29c, 0xeecea29c, 0x99310800, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0xff4a464a, 0xff8c888c, 0xff8c888c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff949294, 0xff949294, 0xff9c9a9c, 0xff9c9a9c, + 0xff9c9a9c, 0xff9c9a9c, 0xff9c9a9c, 0xff9c9a9c, 0xff9c9a9c, 0xff9c9a9c, 0xff9c9a9c, 0xff9c9a9c, + 0xff9c9a9c, 0xff9c9a9c, 0xff9c9a9c, 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, + 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, + 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949694, 0xff949294, + 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff949294, + 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff949294, 0xff948e94, + 0xff948e94, 0xff948e94, 0xff948e94, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, + 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff8c8e8c, 0xff949694, + 0xff949694, 0xff949694, 0xff737573, 0xff5d5c5d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7731100e, 0xff943129, 0xff8c2d21, 0xff8c2d21, + 0xff8c2d21, 0xff8c2d21, 0xff912d26, 0xff9c3129, 0xff9c3129, 0xff9c3129, 0xff943121, 0xff943121, + 0xff9a746e, 0xff9c9694, 0xff9caead, 0xff9caead, 0xff9caead, 0xff9caead, 0xffadc2c5, 0xffadc2c5, + 0xffadc2c5, 0xffadc2c5, 0xffadc2c5, 0xffadc2c5, 0xffadc2c5, 0xffadc2c5, 0xffadc2c5, 0xffadc2c5, + 0xffadc2c5, 0xffadc2c5, 0xffb2aeaa, 0xffb2aeaa, 0xffceefef, 0xffceefef, 0xfff7fbf7, 0xfff7fbf7, + 0xfff7fbf7, 0xffa5716e, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff632019, 0xff581c16, + 0xff581c16, 0xff4d1813, 0xff421410, 0xcc160705, 0x44000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x88633d3a, 0xffd6928c, 0xffd6928c, 0xffd6928c, 0xffd6928c, 0xffd98e89, + 0xffd98e89, 0xffd98e89, 0xffd68a84, 0xffd98b84, 0xffd98b84, 0xffd6867b, 0xffd6867b, 0xffbd776b, + 0xffbd776b, 0xffa5645a, 0xff8c514a, 0xff7b495a, 0xffd6cad6, 0xffd6cad6, 0xff7b495a, 0xff8c3529, + 0xff8c3529, 0xff8c3529, 0xff973b31, 0xffb5392c, 0xffad3529, 0xffad3529, 0xffad3529, 0xff9f3126, + 0xff9f3126, 0xff942d21, 0xff942d21, 0xff943121, 0xff943121, 0xbb37130b, 0x44080400, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffc58a7b, 0xffc58a7b, + 0xffc58a7b, 0xffbd8273, 0xffe9d0cb, 0xfffff7f7, 0xfffff7f7, 0xffe6d2ce, 0xffe6d2ce, 0xffe6d2ce, + 0xffe6d2ce, 0xfff7f3f7, 0xfff7f3f7, 0xffdec9c8, 0xffad756b, 0xffa57163, 0xffa57163, 0xffa57163, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x88190000, 0xee977779, 0xeed6b2b5, + 0xeed6b2b5, 0xeec5aaa5, 0xeec3a39f, 0xeebd9694, 0xeebd9694, 0xeeb58b84, 0xeeb5847b, 0xeeb5847b, + 0xeeb57d73, 0xee9a6f68, 0xeecea29c, 0xeecea29c, 0x99310800, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0xff8c888c, 0xff8c888c, 0xffcecace, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, + 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, + 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffc0c0c0, 0xffc0c0c0, 0xffced0ce, 0xffcecdce, + 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcecdce, + 0xffcecdce, 0xffcecdce, 0xffcecdce, 0xffcbc9cb, 0xffcbc9cb, 0xffcbc9cb, 0xffcbc9cb, 0xffc5c9c5, + 0xffc5c9c5, 0xffc5c9c5, 0xffc5c9c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c5c5, + 0xffc5c5c5, 0xffc5c5c5, 0xffc5c5c5, 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, + 0xffc5c2c5, 0xffc5c2c5, 0xffc5c2c5, 0xffc0c2c0, 0xffc0c2c0, 0xffc0c2c0, 0xffc0c2c0, 0xffc0bec0, + 0xffc0bec0, 0xffc0bec0, 0xffc0bec0, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, + 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xffb5b6b5, + 0xffb5b6b5, 0xffb5b6b5, 0xffb5b6b5, 0xff8c8a8c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x11000000, 0xaa31100e, 0xff943129, 0xff8c2d21, 0xff8c2d21, + 0xff912f24, 0xff912f24, 0xff9c3129, 0xff9c3129, 0xffa23329, 0xffa23329, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffb59a9c, 0xffc8b5b5, 0xffc8b5b5, 0xffc8b5b5, 0xffc8b5b5, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffdee3de, 0xffe9ece9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffdbb9b5, 0xff942d21, 0xff812821, 0xff812821, 0xff762421, 0xff6b2021, 0xff682019, 0xff682019, + 0xff5d1c19, 0xff521819, 0xff4a1810, 0xdd190805, 0x66000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0xcc8f514d, 0xffd6867b, 0xffd6867b, 0xffd6867b, 0xffd6867b, 0xffd6827b, + 0xffd6827b, 0xffd6827b, 0xffd6827b, 0xffd6867b, 0xffd6867b, 0xffd6867b, 0xffd07970, 0xffce7573, + 0xffce7573, 0xffb25e5a, 0xff974842, 0xff632d3a, 0xffefefef, 0xffefefef, 0xff632d3a, 0xff862b1e, + 0xff9a3224, 0xff9a3224, 0xffad3929, 0xffad3529, 0xffad3529, 0xff9c3126, 0xff9c3126, 0xff943121, + 0xff892d21, 0xff892d21, 0xff892d21, 0xff7b2821, 0xff7b2821, 0xdd551b16, 0x66080000, 0x22000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffc58a7b, 0xffc58a7b, + 0xffc58a7b, 0xffbd8273, 0xffbd8273, 0xffbd8273, 0xffbd8273, 0xffb5796b, 0xffb5796b, 0xffb5796b, + 0xffb5796b, 0xffad756b, 0xffad756b, 0xffad756b, 0xffad756b, 0xffa57163, 0xffa57163, 0xffa57163, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee977779, 0xeed6b2b5, + 0xeed6b2b5, 0xeec5aaa5, 0xeec3a39f, 0xeec09d9a, 0xeebd9694, 0xeeb58b84, 0xeeb58b84, 0xeeb5847b, + 0xeeb57d73, 0xee9a6f68, 0xeecea29c, 0xeecea29c, 0xaa310800, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0xff8c888c, 0xffcecace, 0xffcecace, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffe6ebe6, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffdee3de, + 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffb5b6b5, 0xff8c8a8c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x22000000, 0xdd63201b, 0xff943129, 0xff912f24, 0xff912f24, + 0xff912f24, 0xff912f24, 0xffa23329, 0xffa23329, 0xffa23329, 0xffa73629, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffaf5950, 0xffc8b5b5, 0xffc8b5b5, 0xffd6dbde, 0xffd6dbde, 0xffe1dfe1, 0xffe1dfe1, + 0xffecebec, 0xffecebec, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, + 0xfff1f0f1, 0xfff1f0f1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffb8736b, 0xff942d21, 0xff8c2d21, 0xff812821, 0xff762421, 0xff762421, 0xff682019, 0xff682019, + 0xff5d1c19, 0xff521819, 0xff4a1810, 0xee31100b, 0x88000000, 0x22000000, 0x00000000, 0x00000000, + 0x00000000, 0x55472826, 0xffd67973, 0xffd37f76, 0xffd37f76, 0xffd37f76, 0xffd37f76, 0xffd6827b, + 0xffd6827b, 0xffd6827b, 0xffd6827b, 0xffd07970, 0xffd07970, 0xffd07970, 0xffd07970, 0xffce7573, + 0xffb25e5a, 0xff974842, 0xff974842, 0xff632d3a, 0xffefefef, 0xffefefef, 0xff632d3a, 0xff732419, + 0xff862b1e, 0xff9a3224, 0xff9a3224, 0xff9c3126, 0xff9c3126, 0xff9c3126, 0xff8c2d24, 0xff892d21, + 0xff892d21, 0xff7e2821, 0xff7e2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0x992f0d0b, 0x33000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffc58a7b, 0xffc58a7b, + 0xffc58a7b, 0xffbd8273, 0xffbd8273, 0xffbd8273, 0xffbd8273, 0xffb5796b, 0xffb5796b, 0xffb5796b, + 0xffb5796b, 0xffad756b, 0xffad756b, 0xffad756b, 0xffad756b, 0xffa57163, 0xffa57163, 0xffa57163, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee977779, 0xeed6b2b5, + 0xeed6b2b5, 0xeec5aaa5, 0xeec5aaa5, 0xeec09d9a, 0xeebd9694, 0xeeb5928c, 0xeeb58b84, 0xeeb5847b, + 0xeeb5847b, 0xee9a6f68, 0xeecea29c, 0xeecea29c, 0xaa310800, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00080408, 0xff8c888c, 0xffcecace, 0xffcecace, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffe6ebe6, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, + 0xffe6e7e6, 0xffe6e7e6, 0xffe6e7e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffe6e3e6, 0xffdee3de, + 0xffdee3de, 0xffdee3de, 0xffdee3de, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedfde, + 0xffdedfde, 0xffdedfde, 0xffdedfde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffdedbde, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6dbd6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffb5b6b5, 0xff8c8a8c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x5531100e, 0xff943129, 0xff943129, 0xff912f24, 0xff912f24, + 0xff973226, 0xff973226, 0xffa23329, 0xffa23329, 0xffa73629, 0xffa73629, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffba8f8c, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffecebec, 0xffecebec, + 0xfff7f7f7, 0xfff7f7f7, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xfff1f0f1, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffdbb9b5, + 0xff942d21, 0xff942d21, 0xff8c2d21, 0xff812821, 0xff812821, 0xff762421, 0xff682019, 0xff682019, + 0xff682019, 0xff5d1c19, 0xff4a1810, 0xff4a1810, 0xaa000000, 0x33000000, 0x00000000, 0x00000000, + 0x00000000, 0x88472826, 0xffd67973, 0xffd07870, 0xffd07870, 0xffd07870, 0xffd07870, 0xffd37b73, + 0xffd37b73, 0xffd37b73, 0xffd0746b, 0xffd07970, 0xffcb6d65, 0xffcb6d65, 0xffcb6d65, 0xffb25e5a, + 0xffb25e5a, 0xff974842, 0xff7b3129, 0xff632d3a, 0xffefefef, 0xffefefef, 0xff632d3a, 0xff732419, + 0xff862b1e, 0xff9a3224, 0xff9a3224, 0xff9c3126, 0xff8c2d24, 0xff8c2d24, 0xff8c2d24, 0xff7e2821, + 0xff7e2821, 0xff7e2821, 0xff732421, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xbb2f0d0b, 0x44000000, + 0x22000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9d5d0, 0xffbd8273, 0xffbd8273, + 0xffbd8273, 0xffad756b, 0xffad756b, 0xffad756b, 0xffad756b, 0xff9c6d63, 0xff9c6d63, 0xff9c6d63, + 0xff9c6d63, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6d63, 0xff9c6d63, 0xff9c6d63, + 0xffdececb, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee97827e, 0xeed6c2bd, + 0xeed6c2bd, 0xeec5b2b5, 0xeec3aaaa, 0xeec0a29f, 0xeebd9a94, 0xeeba8f86, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee976c6b, 0xeec59e9c, 0xeec59e9c, 0xaa3a0808, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0xff7e807e, 0xffbdbebd, 0xffbdbebd, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffd6d7d6, 0xffd6d7d6, + 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d7d6, 0xffd6d2d6, + 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffd6d2d6, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, + 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecece, 0xffcecace, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, 0xffcecace, + 0xffcecace, 0xffcecace, 0xffcecace, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, + 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffc5c6c5, 0xffbdbebd, + 0xffbdbebd, 0xffbdbebd, 0xffbdbebd, 0xff848284, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x7731100e, 0xff943129, 0xff943129, 0xff973226, 0xff973226, + 0xff973226, 0xff973226, 0xffa23329, 0xffa73629, 0xffa73629, 0xffa73629, 0xffad3929, 0xffad3929, + 0xffad3929, 0xffad3929, 0xffad6963, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffecebec, 0xfff7f7f7, + 0xfff7f7f7, 0xfff7f7f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff942d21, + 0xff942d21, 0xff942d21, 0xff8c2d21, 0xff8c2d21, 0xff812821, 0xff812821, 0xff732419, 0xff682019, + 0xff682019, 0xff5d1c19, 0xff4a1810, 0xff4a1810, 0xbb190805, 0x44000000, 0x11000000, 0x00000000, + 0x11000000, 0xaa8f514d, 0xffd67973, 0xffce716b, 0xffce716b, 0xffce716b, 0xffce716b, 0xffce6d63, + 0xffce6d63, 0xffce6d63, 0xffce6d63, 0xffcb6d65, 0xffcb6d65, 0xffc5615a, 0xffc5615a, 0xffb25e5a, + 0xff974842, 0xff974842, 0xff7b3129, 0xff632d3a, 0xffefefef, 0xffefefef, 0xff632d3a, 0xff732419, + 0xff732419, 0xff862b1e, 0xff862b1e, 0xff8c2d24, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff732421, + 0xff732421, 0xff732421, 0xff732421, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xdd551b16, 0x55000000, + 0x22000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9d5d0, 0xffbd8273, 0xffbd8273, + 0xffbd8273, 0xffad756b, 0xffad756b, 0xffad756b, 0xffad756b, 0xff9c6d63, 0xff9c6d63, 0xff9c6d63, + 0xff9c6d63, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6d63, 0xff9c6d63, 0xff9c6d63, + 0xffdececb, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee97827e, 0xeed6c2bd, + 0xeed6c2bd, 0xeec5b2b5, 0xeec3aaaa, 0xeec0a29f, 0xeebd9a94, 0xeebd968c, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee976c6b, 0xeec59e9c, 0xeec59e9c, 0xaa3a0808, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0xff3f423f, 0xff7e807e, 0xff7e807e, 0xff848484, 0xff848484, 0xff848484, 0xff848484, + 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, + 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff8f8f8f, 0xff8f8f8f, + 0xff8f8f8f, 0xff8f8f8f, 0xff8f8f8f, 0xff8f8f8f, 0xff8f8f8f, 0xff8f8f8f, 0xff8f8f8f, 0xff8f8e8f, + 0xff8f8e8f, 0xff8f8e8f, 0xff8f8e8f, 0xff8f8c8f, 0xff8f8c8f, 0xff8f8c8f, 0xff8f8c8f, 0xff898a89, + 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, + 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898a89, 0xff898789, + 0xff898789, 0xff898789, 0xff898789, 0xff898789, 0xff898789, 0xff898789, 0xff898789, 0xff898789, + 0xff898789, 0xff898789, 0xff898789, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, + 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, + 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff848484, 0xff7e7f7e, + 0xff7e7f7e, 0xff7e7f7e, 0xff7e7f7e, 0xff585658, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x8834120e, 0xff9c3529, 0xff9c3529, 0xff9f3229, 0xff9f3229, + 0xff9f3229, 0xffa53529, 0xffaa362f, 0xffaf372c, 0xffaf372c, 0xffaf372c, 0xffb53931, 0xffb53931, + 0xffb83a2f, 0xffb53931, 0xffb53d31, 0xffcba39f, 0xffd6d7d6, 0xffd6d7d6, 0xffe6e3e6, 0xffefefef, + 0xfff7fbf7, 0xfff7fbf7, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffd69e9c, 0xff9c3529, + 0xff9c3529, 0xff9c3529, 0xff942e21, 0xff8c2b21, 0xff8c2b21, 0xff842821, 0xff7b2421, 0xff651f1b, + 0xff651f1b, 0xff5a1c19, 0xff521810, 0xff521810, 0xcc1b0805, 0x55000000, 0x11000000, 0x00000000, + 0x11000000, 0xcc8f4c42, 0xffd67163, 0xffce6963, 0xffce6963, 0xffce6963, 0xffce6963, 0xffc5655a, + 0xffc5655a, 0xffc5655a, 0xffc5655a, 0xffc55952, 0xffc55952, 0xffc55952, 0xffc55952, 0xffbd493a, + 0xffbd493a, 0xff7e3126, 0xff7e3126, 0xff190808, 0xffffffff, 0xffffffff, 0xff190808, 0xff581b16, + 0xff842821, 0xff842821, 0xff842821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff6b2019, + 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xff6b2019, 0xee471610, 0x55000000, + 0x22000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9d5d0, 0xffffffff, 0xffbd8273, + 0xffbd8273, 0xffad756b, 0xffad756b, 0xffad756b, 0xffad756b, 0xff9c6d63, 0xff9c6d63, 0xff9c6d63, + 0xff9c6d63, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6963, 0xff9c6d63, 0xff9c6d63, 0xffffffff, + 0xffdececb, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee97827e, 0xeed6c2bd, + 0xeed6c2bd, 0xeec5b2b5, 0xeec3aaaa, 0xeec0a29f, 0xeebd9a94, 0xeebd968c, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee976c6b, 0xeec59e9c, 0xeec59e9c, 0xaa3a0808, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x9934120e, 0xff9c3529, 0xff9c3529, 0xff9f3229, 0xff9c3129, + 0xffa23329, 0xffa53529, 0xffaf372c, 0xffaf372c, 0xffb53929, 0xffb53929, 0xffb53931, 0xffb83a2f, + 0xffb53931, 0xffb83a2f, 0xffb53d31, 0xffb53d31, 0xffd6d7d6, 0xffd6d7d6, 0xffe6e3e6, 0xffefefef, + 0xffefefef, 0xfff7fbf7, 0xfffcfcfc, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff9c3529, 0xff9c3529, + 0xff9c3529, 0xff9c3529, 0xff942e21, 0xff942e21, 0xff8c2b21, 0xff842821, 0xff7b2421, 0xff70221e, + 0xff651f1b, 0xff5a1c19, 0xff521810, 0xff521810, 0xcc1b0805, 0x55000000, 0x11000000, 0x00000000, + 0x11000000, 0x22000000, 0x44000000, 0x66000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, + 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, + 0x88000000, 0x99000000, 0xaa000000, 0xcc190808, 0xffffffff, 0xffffffff, 0xbb190808, 0xaa000000, + 0x99000000, 0x88000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, + 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x77000000, 0x66000000, 0x44000000, + 0x22000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9d5d0, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffdececb, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee97827e, 0xeed6c2bd, + 0xeed6c2bd, 0xeec5b2b5, 0xeec3aaaa, 0xeec0a29f, 0xeebd9a94, 0xeebd968c, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee976c6b, 0xeec59e9c, 0xeec59e9c, 0xaa3a0808, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, + 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xaa34120e, 0xff9c3529, 0xff9c3529, 0xff9f3229, 0xff9f3229, + 0xffa53529, 0xffa53529, 0xffaf372c, 0xffb53929, 0xffb53929, 0xffb53929, 0xffb83a2f, 0xffb83a2f, + 0xffb83a2f, 0xffb83a2f, 0xffb53d31, 0xffb53d31, 0xffc07068, 0xffd6d7d6, 0xffded7de, 0xffe6e3e6, + 0xffefefef, 0xffefefef, 0xfffafafa, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffc87d76, 0xff9c3529, 0xff9c3529, + 0xff9c3529, 0xff9c3529, 0xff942e21, 0xff942e21, 0xff8c2b21, 0xff842821, 0xff7b2421, 0xff70221e, + 0xff651f1b, 0xff651f1b, 0xff521810, 0xff521810, 0xdd1b0805, 0x66000000, 0x11000000, 0x00000000, + 0x00000000, 0x11000000, 0x22000000, 0x33000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, + 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, + 0x55000000, 0x66000000, 0x88000000, 0xaa190808, 0xffffffff, 0xffffffff, 0xaa190808, 0x88000000, + 0x66000000, 0x55000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, + 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x44000000, 0x33000000, 0x22000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee9c827e, 0xeedec2bd, + 0xeedec2bd, 0xeec5b6b5, 0xeec3aead, 0xeec0a6a5, 0xeebd9e9c, 0xeebd9694, 0xeeba8f8c, 0xeeb88884, + 0xeeb5827b, 0xee9c6d6b, 0xeece9e9c, 0xeece9e9c, 0xaa3a0c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0xbb68231b, 0xff9c3529, 0xff9c3529, 0xffa53529, 0xffa53529, + 0xffa53529, 0xffa53529, 0xffb53929, 0xffb53929, 0xffb53929, 0xffb53929, 0xffb83a2f, 0xffb83a2f, + 0xffba3b2c, 0xffb83a2f, 0xffb53d31, 0xffb53d31, 0xffb53d31, 0xffcba39f, 0xffded7de, 0xffe6e3e6, + 0xffe6e3e6, 0xffefefef, 0xfff7f7f7, 0xfffcfcfc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffe4beba, 0xffad3d31, 0xff9c3529, 0xff9c3529, + 0xff9c3529, 0xff9c3529, 0xff9c3121, 0xff942e21, 0xff8c2b21, 0xff842821, 0xff7b2421, 0xff70221e, + 0xff651f1b, 0xff651f1b, 0xff521810, 0xff521810, 0xdd1b0805, 0x66000000, 0x22000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x22000000, 0x44000000, 0x66000000, 0x99190808, 0xffffffff, 0xffffffff, 0x88190808, 0x66000000, + 0x44000000, 0x22000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee9c827e, 0xeedec2bd, + 0xeedec2bd, 0xeec5b6b5, 0xeec3aead, 0xeec0a6a5, 0xeebd9e9c, 0xeebd9694, 0xeeba8f8c, 0xeeb88884, + 0xeeb5827b, 0xee9c6d6b, 0xeece9e9c, 0xeece9e9c, 0xaa3a0c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x9937120e, 0xffa53529, 0xffa53529, 0xffa53529, 0xffa53529, + 0xffa53529, 0xffaa3729, 0xffb53929, 0xffb53a2c, 0xffb53b2f, 0xffb53b2f, 0xffbd3b31, 0xffbd3b31, + 0xffbd3b31, 0xffbd3b31, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffbd6152, 0xffdedbde, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xfff7f7f7, 0xfff7f7f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffbff, 0xfffffbff, 0xffc87970, 0xffad3929, 0xffa53529, 0xffa53529, + 0xffa53529, 0xff9c3129, 0xff943129, 0xff8f2e26, 0xff892b24, 0xff842821, 0xff732421, 0xff6b221e, + 0xff631f1b, 0xff631f1b, 0xff521c10, 0xff37130b, 0xdd1b0905, 0x66000000, 0x22000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x33000000, 0x55000000, 0x88190808, 0xfffffbff, 0xfffffbff, 0x88190808, 0x55000000, + 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee9c827e, 0xeedec2bd, + 0xeedec2bd, 0xeec5b6b5, 0xeec3aead, 0xeec0a6a5, 0xeebd9e9c, 0xeebd9694, 0xeeba8f8c, 0xeeb88884, + 0xeeb5827b, 0xee9c6d6b, 0xeece9e9c, 0xeece9e9c, 0xaa3a0c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x8837120e, 0xffa53529, 0xffa53529, 0xffa53529, 0xffa53529, + 0xffa73629, 0xffad3929, 0xffb53a2c, 0xffb53a2c, 0xffb53a2c, 0xffb53a2c, 0xffbd3b31, 0xffbd3b31, + 0xffbd3b31, 0xffbd3b31, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffd3a9a7, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffefefef, 0xfff7f7f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffbff, 0xffe4bab8, 0xffad3929, 0xffad3929, 0xffa53529, 0xffa53529, + 0xffa53529, 0xff9c3129, 0xff943129, 0xff8f2e26, 0xff892b24, 0xff842821, 0xff732421, 0xff6b221e, + 0xff631f1b, 0xff5a1c19, 0xff521c10, 0xff37130b, 0xcc1b0905, 0x66000000, 0x22000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x33000000, 0x55000000, 0x88190808, 0xfffffbff, 0xfffffbff, 0x88190808, 0x55000000, + 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee9c827e, 0xeedec2bd, + 0xeedec2bd, 0xeec5b6b5, 0xeec3aead, 0xeec0a6a5, 0xeebd9e9c, 0xeebd9694, 0xeeba8f8c, 0xeeb88884, + 0xeeb5827b, 0xee9c6d6b, 0xeece9e9c, 0xeece9e9c, 0xaa3a0c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x7737120e, 0xffa53529, 0xffa53529, 0xffa73629, 0xffa73629, + 0xffa53529, 0xffad3929, 0xffb53929, 0xffb53a2c, 0xffb53a2c, 0xffb53b2f, 0xffbd3a31, 0xffbd3b31, + 0xffbd3b31, 0xffbd3b31, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffbd453a, 0xffdedbde, + 0xffdedbde, 0xffdedbde, 0xffefefef, 0xfff7f7f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffbff, 0xffad3929, 0xffad3929, 0xffad3929, 0xffa53529, 0xffa53529, + 0xffa53529, 0xff9f3229, 0xff943129, 0xff8f2e26, 0xff892b24, 0xff842821, 0xff732421, 0xff6b221e, + 0xff631f1b, 0xff5a1c19, 0xff521c10, 0xff37130b, 0xcc1b0905, 0x66000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x22000000, 0x44000000, 0x66000000, 0x99190808, 0xfffffbff, 0xfffffbff, 0x99190808, 0x66000000, + 0x44000000, 0x22000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee977f79, 0xeed6beb5, + 0xeed6beb5, 0xeec5b2b5, 0xeec3abaa, 0xeec0a59f, 0xeebd9e94, 0xeebd968c, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee9a6d65, 0xeece9e94, 0xeece9e94, 0xaa310c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x6637120e, 0xffa53529, 0xffa53529, 0xffa53529, 0xffa53529, + 0xffa53529, 0xffaa3729, 0xffb53929, 0xffb53a2c, 0xffb53b2f, 0xffb53b2f, 0xffbd3b31, 0xffbd3b31, + 0xffbd3d31, 0xffbd3b31, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffbd453a, 0xffc87770, + 0xffdedbde, 0xffdedbde, 0xffe6e7e6, 0xfff7f7f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffc87970, 0xffad3929, 0xffad3929, 0xffad3929, 0xffa53529, 0xffa53529, + 0xffa53529, 0xff9f3229, 0xff943129, 0xff8f2e26, 0xff892b24, 0xff842821, 0xff732421, 0xff6b221e, + 0xff631f1b, 0xff5a1c19, 0xff521c10, 0xff37130b, 0xbb000000, 0x55000000, 0x11000000, 0x00000000, + 0x00000000, 0x7745221e, 0xffce655a, 0xffc56152, 0xffc56152, 0xffc56152, 0xffc56152, 0xffc5594a, + 0xffc5594a, 0xffc5594a, 0xffc5594a, 0xffbd5142, 0xffbd5142, 0xffbd5142, 0xffbd5142, 0xffce4531, + 0xff892e21, 0xff892e21, 0xff892e21, 0xff190808, 0xfffffbff, 0xfffffbff, 0xff190808, 0xff581b16, + 0xff581b16, 0xff842821, 0xff842821, 0xff732419, 0xff732419, 0xff732419, 0xff732419, 0xff632019, + 0xff632019, 0xff632019, 0xff632019, 0xff632019, 0xff632019, 0xff632019, 0x88210b08, 0x22000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee977f79, 0xeed6beb5, + 0xeed6beb5, 0xeec5b2b5, 0xeec3abaa, 0xeec0a59f, 0xeebd9e94, 0xeebd968c, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee9a6d65, 0xeece9e94, 0xeece9e94, 0xaa310c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00080000, 0x33080000, 0xee9c3529, 0xff9c3529, 0xffa53529, 0xffa53529, + 0xffa73629, 0xffad3929, 0xffaf392c, 0xffb2392f, 0xffb2392f, 0xffb2392f, 0xffba3b2f, 0xffba3b2f, + 0xffba3b2f, 0xffba3b2f, 0xffba3b31, 0xffb83a31, 0xffba3b31, 0xffba3b31, 0xffb53931, 0xffb53931, + 0xffcba7a5, 0xffd6dfde, 0xffe6e3e6, 0xfff7f6f7, 0xffffffff, 0xffffffff, 0xfffffbff, 0xfffffbff, + 0xfffffbff, 0xfffffbff, 0xffb53d31, 0xffaf372c, 0xffaf372c, 0xffaf372c, 0xffa53529, 0xffa23329, + 0xff9f3229, 0xff9c3129, 0xff943121, 0xff8c2d21, 0xff8c2d21, 0xff842821, 0xff732421, 0xff68201b, + 0xff5d1c16, 0xff5d1c16, 0xff4a1810, 0xff31100b, 0xaa000000, 0x44000000, 0x11000000, 0x00000000, + 0x00000000, 0x55451f1b, 0xffce5d52, 0xffc5594a, 0xffc5594a, 0xffc5594a, 0xffc5594a, 0xffc5554a, + 0xffc5554a, 0xffc04c3f, 0xffc04c3f, 0xffc5453a, 0xffc5453a, 0xffba3e34, 0xffba3e34, 0xffad3529, + 0xffad3529, 0xff76271e, 0xff5a2019, 0xff5a2d3a, 0xffe6e7e6, 0xffe6e7e6, 0xff5a2d3a, 0xff4a1819, + 0xff652019, 0xff652019, 0xff732419, 0xff632019, 0xff632019, 0xff632019, 0xff632019, 0xff632019, + 0xff5d1e16, 0xff5d1e16, 0xff5d1e16, 0xff5a1c19, 0xff5a1c19, 0xff5a1c19, 0x88240908, 0x33000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee977f79, 0xeed6beb5, + 0xeed6beb5, 0xeec5b2b5, 0xeec3abaa, 0xeec0a59f, 0xeebd9e94, 0xeebd968c, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee9a6d65, 0xeece9e94, 0xeece9e94, 0xaa310c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00080000, 0x11080000, 0xcc6b231b, 0xff9c3529, 0xffa53529, 0xffa53529, + 0xffa53529, 0xffaa3729, 0xffaf392c, 0xffb2392f, 0xffb2392f, 0xffb2392f, 0xffb83a2c, 0xffba3b2f, + 0xffba3b2f, 0xffba3b2f, 0xffb83a31, 0xffb83a31, 0xffba3b31, 0xffba3b31, 0xffb53931, 0xffb53931, + 0xffc0706b, 0xffd6dfde, 0xffe6e3e6, 0xfff7f6f7, 0xffffffff, 0xffffffff, 0xfffffbff, 0xfffffbff, + 0xfffffbff, 0xffc87770, 0xffaf372c, 0xffaf372c, 0xffaf372c, 0xffad3529, 0xffa53529, 0xffa23329, + 0xffa23329, 0xff9c3129, 0xff943121, 0xff8c2d21, 0xff8c2d21, 0xff842821, 0xff732421, 0xff68201b, + 0xff5d1c16, 0xff5d1c16, 0xff4a1810, 0xee31100b, 0x99000000, 0x33000000, 0x00000000, 0x00000000, + 0x00000000, 0x22000000, 0xcc893e37, 0xffbd5042, 0xffbd5042, 0xffbd5042, 0xffbd5042, 0xffc04c3f, + 0xffc04c3f, 0xffba4234, 0xffba4234, 0xffba3e34, 0xffba3e34, 0xffaf372f, 0xffaf372f, 0xffad3529, + 0xff912e24, 0xff76271e, 0xff5a2019, 0xff5a2d3a, 0xffe6e7e6, 0xffe6e7e6, 0xff5a2d3a, 0xff4a1819, + 0xff581c19, 0xff652019, 0xff652019, 0xff632019, 0xff632019, 0xff5a1e16, 0xff5a1e16, 0xff581b13, + 0xff581b13, 0xff581b13, 0xff581b13, 0xff5a1c19, 0xff5a1c19, 0xdd3f1310, 0x77080000, 0x44000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x99190000, 0xee977f79, 0xeed6beb5, + 0xeed6beb5, 0xeec3abaa, 0xeec3abaa, 0xeec0a59f, 0xeebd9e94, 0xeebd968c, 0xeeba8f86, 0xeeb88881, + 0xeeb5827b, 0xee9a6d65, 0xeece9e94, 0xeece9e94, 0xaa310c08, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00080000, 0x00080000, 0x993a120e, 0xff9c3529, 0xffa53529, 0xffa53529, + 0xffa53529, 0xffa73629, 0xffaf392c, 0xffaf392c, 0xffb2392f, 0xffb2392f, 0xffb83a2c, 0xffba3b2f, + 0xffb83a2c, 0xffba3b2f, 0xffb83a31, 0xffba3b31, 0xffb83a31, 0xffba3b31, 0xffb53931, 0xffb53931, + 0xffb53931, 0xffcba7a5, 0xffe6e3e6, 0xfff7f6f7, 0xffffffff, 0xffffffff, 0xfffffbff, 0xfffffbff, + 0xffe4b9b8, 0xffad3529, 0xffaf372c, 0xffaf372c, 0xffad3529, 0xffad3529, 0xffa53529, 0xffa23329, + 0xff9f3229, 0xff9c3129, 0xff8c2d21, 0xff8c2d21, 0xff842821, 0xff7b2421, 0xff732421, 0xff68201b, + 0xff5d1c16, 0xff521810, 0xff4a1810, 0xdd190805, 0x77000000, 0x22000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x99451f1b, 0xffbd5042, 0xffb5463a, 0xffb5463a, 0xffb5463a, 0xffba4234, + 0xffba4234, 0xffb53929, 0xffb53929, 0xffaf372f, 0xffaf372f, 0xffaf372f, 0xffaf372f, 0xffad3529, + 0xff912e24, 0xff76271e, 0xff5a2019, 0xff5a2d3a, 0xffe6e7e6, 0xffe6e7e6, 0xff5a2d3a, 0xff4a1819, + 0xff4a1819, 0xff581c19, 0xff652019, 0xff5a1e16, 0xff5a1e16, 0xff521b13, 0xff521b13, 0xff581b13, + 0xff581b13, 0xff581b13, 0xff581b13, 0xff5a1c19, 0xff5a1c19, 0xcc240908, 0x77080000, 0x33000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x33000000, 0x88290400, 0xee977873, 0xeeceb2ad, + 0xeeceb2ad, 0xeec5aead, 0xeec3a6a2, 0xeec09e97, 0xeec09e97, 0xeebd928c, 0xeeba8b84, 0xeeb8847b, + 0xeeb8847b, 0xeeb58a84, 0xeeb58a84, 0xeeb58a84, 0xaa210400, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00080000, 0x00080000, 0x66080000, 0xff9c3529, 0xffa53529, 0xffa53529, + 0xffa53529, 0xffa53529, 0xffaf392c, 0xffaf392c, 0xffaf392c, 0xffb2392f, 0xffb83a2c, 0xffb83a2c, + 0xffb83a2c, 0xffb83a2c, 0xffb53931, 0xffb83a31, 0xffb83a31, 0xffb53931, 0xffb53931, 0xffb53931, + 0xffb53931, 0xffc0706b, 0xffe6e3e6, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffbff, 0xfffffbff, + 0xffc87770, 0xffad3529, 0xffaf372c, 0xffaf372c, 0xffad3529, 0xffad3529, 0xffa53529, 0xffa23329, + 0xff9c3129, 0xff9c3129, 0xff8c2d21, 0xff8c2d21, 0xff842821, 0xff7b2421, 0xff68201b, 0xff5d1c16, + 0xff521810, 0xff521810, 0xff31100b, 0xbb000000, 0x66000000, 0x22000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x44000000, 0xddad3d31, 0xffb5463a, 0xffad3d31, 0xffad3d31, 0xffb53929, + 0xffb53929, 0xffb53929, 0xffb53929, 0xffaf372f, 0xffaf372f, 0xffa53129, 0xffa53129, 0xff912e24, + 0xff912e24, 0xff5a2019, 0xff5a2019, 0xff5a2d3a, 0xffe6e7e6, 0xffe6e7e6, 0xff5a2d3a, 0xff4a1819, + 0xff4a1819, 0xff4a1819, 0xff581c19, 0xff521b13, 0xff521b13, 0xff521b13, 0xff4a1810, 0xff521810, + 0xff521810, 0xff521810, 0xff521810, 0xff5a1c19, 0xee3f1310, 0x99080000, 0x55080000, 0x22000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x88290400, 0xee977873, 0xeeceb2ad, + 0xeeceb2ad, 0xeec3a6a2, 0xeec3a6a2, 0xeec09e97, 0xeebd968c, 0xeebd928c, 0xeeba8b84, 0xeeb8847b, + 0xeeb8847b, 0xeeb58a84, 0xeeb58a84, 0xeeb58a84, 0x99210400, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x22000000, 0xdd6b2019, 0xff9c3129, 0xff9c3129, + 0xff9c3129, 0xff9c3129, 0xffa23329, 0xffa73629, 0xffa73629, 0xffa73629, 0xffb53929, 0xffb53929, + 0xffb53929, 0xffb53929, 0xffaf3729, 0xffb53929, 0xffaf3729, 0xffb53929, 0xffaf3729, 0xffb53929, + 0xffaf3729, 0xffaf3729, 0xffdbb9b5, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfffff7f7, 0xffe1b7b2, + 0xffa53929, 0xffa53929, 0xffa53529, 0xffa53529, 0xffa53529, 0xffa53529, 0xff9c3129, 0xff9c3129, + 0xff9c3129, 0xff942e26, 0xff8c2d21, 0xff8c2d21, 0xff7e271e, 0xff70221b, 0xff632019, 0xff632019, + 0xff471710, 0xff471710, 0xee290c08, 0xaa000000, 0x44000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x99451710, 0xffbd3d31, 0xffbd3d31, 0xffbd3d31, 0xffad3929, + 0xffad3929, 0xffa73629, 0xffa73629, 0xffa53529, 0xffa53529, 0xff9a3126, 0xff9a3126, 0xff842d29, + 0xff762824, 0xff5a2019, 0xff5a2019, 0xff6b495a, 0xffd6cad6, 0xffd6cad6, 0xff6b495a, 0xff4d1c1e, + 0xff4a1410, 0xff4d1c1e, 0xff4d1c1e, 0xff4a1810, 0xff4a1810, 0xff4a1810, 0xff4a1810, 0xff4a1810, + 0xff4a1810, 0xff4a1810, 0xff4a1810, 0xff4a1810, 0xcc190805, 0x77000000, 0x44000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x88290400, 0xee603e3a, 0xeeceb2ad, + 0xeeceb2ad, 0xeec3a6a2, 0xeec09e97, 0xeec09e97, 0xeebd968c, 0xeebd928c, 0xeeba8b84, 0xeeb8847b, + 0xeeb57d73, 0xeeb58a84, 0xeeb58a84, 0xeeb58a84, 0x99210400, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x77240b08, 0xff9c3129, 0xff9c3129, + 0xff9c3129, 0xff9c3129, 0xffa23329, 0xffa23329, 0xffa73629, 0xffa73629, 0xffb53929, 0xffad3629, + 0xffad3629, 0xffad3629, 0xffaf3729, 0xffaf3729, 0xffaf3729, 0xffaf3729, 0xffaf3729, 0xffaf3729, + 0xffaf3729, 0xffaf3729, 0xffa53d31, 0xfff7f7f7, 0xfff7f7f7, 0xfff7f7f7, 0xfffff7f7, 0xffa53929, + 0xffa53929, 0xffa53929, 0xffa53529, 0xffa53529, 0xff9f3329, 0xff9f3329, 0xff9c3129, 0xff9c3129, + 0xff942e26, 0xff942e26, 0xff8c2d21, 0xff8c2d21, 0xff7e271e, 0xff70221b, 0xff632019, 0xff471710, + 0xff471710, 0xff471710, 0xcc0e0403, 0x88000000, 0x33000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x44080400, 0xcc812a21, 0xffbd3d31, 0xffbd3d31, 0xffa73629, + 0xffa73629, 0xffa73629, 0xffa23329, 0xff9a3126, 0xff9a3126, 0xff9a3126, 0xff8f2d24, 0xff762824, + 0xff68241e, 0xff5a2019, 0xff5a2019, 0xff6b495a, 0xffd6cad6, 0xffd6cad6, 0xff6b495a, 0xff4d1c1e, + 0xff4a1410, 0xff4a1410, 0xff4d1c1e, 0xff4a1810, 0xff4a1810, 0xff471710, 0xff471710, 0xff4a1810, + 0xff4a1810, 0xff4a1810, 0xff4a1810, 0xee31100b, 0x99000000, 0x55000000, 0x33000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x77290400, 0xee603e3a, 0xeeceb2ad, + 0xeeceb2ad, 0xeec3a6a2, 0xeec09e97, 0xeebd968c, 0xeebd968c, 0xeeba8b84, 0xeeba8b84, 0xeeb8847b, + 0xeeb57d73, 0xeeb58a84, 0xeeb58a84, 0xeeb58a84, 0x99210400, 0x33000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x22000000, 0xcc6e221e, 0xff9c3129, + 0xff9c3129, 0xff9c3129, 0xff9c3129, 0xffa23329, 0xffa23329, 0xffa73629, 0xffad3629, 0xffad3629, + 0xffad3629, 0xffad3629, 0xffaf3729, 0xffaa3629, 0xffa53529, 0xffaa3629, 0xffa53529, 0xffaf3729, + 0xffaa3629, 0xffa53529, 0xffa53d31, 0xffc07b73, 0xfff7f7f7, 0xfff7f7f7, 0xffc3786e, 0xffa53929, + 0xffa53929, 0xffa53929, 0xff9f3329, 0xff9f3329, 0xff9f3329, 0xff9a3229, 0xff9c3129, 0xff942e26, + 0xff942e26, 0xff942e26, 0xff7e271e, 0xff7e271e, 0xff70221b, 0xff70221b, 0xff632019, 0xff471710, + 0xff471710, 0xee2c0d08, 0xaa000000, 0x55000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11080400, 0x77451710, 0xee812a21, 0xffbd3d31, 0xffa73629, + 0xffa23329, 0xffa23329, 0xffa23329, 0xff9a3126, 0xff9a3126, 0xff8f2d24, 0xff8f2d24, 0xff762824, + 0xff68241e, 0xff5a2019, 0xff68241e, 0xff6b495a, 0xffb29fad, 0xffb29fad, 0xff8f7484, 0xff50242c, + 0xff4a1410, 0xff4a1410, 0xff4a1410, 0xff471710, 0xff471710, 0xff451610, 0xff451610, 0xff4a1810, + 0xff4a1810, 0xff4a1810, 0xee3c130e, 0xbb190805, 0x66000000, 0x44000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9dfdb, 0xfff7ffff, 0xffce9e94, + 0xffce9e94, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffd6a294, 0xffd6a294, + 0xffd39e91, 0xffce9e94, 0xffce9e94, 0xffce988c, 0xffce988c, 0xffc58e7b, 0xffc58e7b, 0xfff7ffff, + 0xffe6d9d3, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x77290400, 0xdd5d3731, 0xeec59e94, + 0xeec59e94, 0xeebd9e9c, 0xeebd9e9c, 0xeeba9794, 0xeeb8908c, 0xeeb58a84, 0xeeb2837b, 0xeeaf7c73, + 0xeeaf7c73, 0xee9c7168, 0xeed6a69c, 0xee9c7168, 0x88290800, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66100408, 0xee6e221e, + 0xff9c3129, 0xff9c3129, 0xff9c3129, 0xff9c3129, 0xff9c3129, 0xffa23329, 0xffa53329, 0xffa53329, + 0xffa53329, 0xffa53329, 0xffa53529, 0xffa53529, 0xffa53529, 0xffa53529, 0xffa53529, 0xffa53529, + 0xffa53529, 0xffa53529, 0xffa53d31, 0xffa53d31, 0xfff7f7f7, 0xfff7f7f7, 0xffa53929, 0xffa53929, + 0xffa53929, 0xffa53929, 0xff9a3229, 0xff9a3229, 0xff943129, 0xff943129, 0xff942e26, 0xff942e26, + 0xff8c2b24, 0xff842821, 0xff7e271e, 0xff70221b, 0xff70221b, 0xff631c19, 0xff471710, 0xff471710, + 0xff471710, 0xdd100400, 0x88000000, 0x33000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11080400, 0x22080400, 0x99451710, 0xee812a21, 0xffa23329, + 0xffa23329, 0xff9c3129, 0xff9c3129, 0xff8f2d24, 0xff8f2d24, 0xff8f2d24, 0xff842821, 0xff68241e, + 0xff68241e, 0xff5a2019, 0xff842d29, 0xff8f7484, 0xffb29fad, 0xffb29fad, 0xff8f7484, 0xff522d3a, + 0xff4d1c1e, 0xff4a1410, 0xff4a1410, 0xff451610, 0xff451610, 0xff451610, 0xff451610, 0xff3c130e, + 0xff3c130e, 0xff3c130e, 0xcc210808, 0x77000000, 0x44000000, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9dfdb, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffd39f91, 0xffd39f91, 0xffd39f91, 0xffd39f91, 0xffd39e91, 0xffd39e91, 0xffd39e91, + 0xffd39e91, 0xffce988c, 0xffce988c, 0xffce988c, 0xffce9384, 0xffc58e7b, 0xffc58e7b, 0xffc58e7b, + 0xffe6d9d3, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x66290400, 0xdd5d3731, 0xeec59e94, + 0xeec59e94, 0xeebd9e9c, 0xeeba9794, 0xeeb8908c, 0xeeb58a84, 0xeeb58a84, 0xeeb2837b, 0xeeaf7c73, + 0xeeaf7c73, 0xee9c7168, 0xeed6a69c, 0xee9c7168, 0x77290800, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0xaa2c0f0b, + 0xff842d21, 0xff842d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff9c3129, 0xff9c3129, + 0xff9c3129, 0xff9c3129, 0xff9a3126, 0xffa53529, 0xff9a3126, 0xff9a3126, 0xff9c3129, 0xff9c3129, + 0xff9c3129, 0xff9c3129, 0xff8c2d21, 0xff8c2d21, 0xffbd6d6b, 0xffbd6d6b, 0xff9c3129, 0xff9c3129, + 0xff9c3129, 0xff9c3129, 0xff9c3121, 0xff9c3121, 0xff912d21, 0xff9c3121, 0xff842d21, 0xff842d21, + 0xff76271e, 0xff76271e, 0xff732421, 0xff732421, 0xff5d1e19, 0xff5d1e19, 0xff421410, 0xff421410, + 0xee2c0d0b, 0xaa000000, 0x55000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x33000000, 0x994a1410, 0xee942d21, + 0xff942d21, 0xff942d21, 0xff942d21, 0xff8c2d21, 0xff8c2d21, 0xff812821, 0xff812821, 0xff632019, + 0xff632019, 0xff632019, 0xff633134, 0xff846573, 0xffa596a5, 0xffa596a5, 0xff846573, 0xff5a3d42, + 0xff4a2221, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xff421410, + 0xff421410, 0xcc160705, 0x77000000, 0x55000000, 0x33000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9dfdb, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffd39f91, 0xffd09d8f, 0xffd09d8f, 0xffd09d8f, 0xffd09a8f, 0xffd09a8f, 0xffd09a8f, + 0xffd09a8f, 0xffce988c, 0xffce9384, 0xffce9384, 0xffce9384, 0xffc58e7b, 0xffc58e7b, 0xffc58e7b, + 0xffe6d9d3, 0xffadaaad, 0x00000000, 0x11000000, 0x22000000, 0x55290400, 0xcc290400, 0xeec59e94, + 0xeec59e94, 0xeeba9794, 0xeeb8908c, 0xeeb8908c, 0xeeb58a84, 0xeeb2837b, 0xeeaf7c73, 0xeeaf7c73, + 0xeead756b, 0xee9c7168, 0xeed6a69c, 0xdd633d34, 0x66290800, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22000000, + 0xbb2c0f0b, 0xff842d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8f2d26, 0xff8f2d26, + 0xff8f2d26, 0xff9c3129, 0xff8f2d24, 0xff9a3126, 0xff9a3126, 0xff9a3126, 0xff942e26, 0xff9c3129, + 0xff942e26, 0xff9c3129, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff942e26, 0xff942e26, + 0xff942e26, 0xff942e26, 0xff9c3121, 0xff912d21, 0xff912d21, 0xff912d21, 0xff842d21, 0xff76271e, + 0xff76271e, 0xff76271e, 0xff732421, 0xff5d1e19, 0xff5d1e19, 0xff471710, 0xff421410, 0xee2c0d0b, + 0xbb000000, 0x77000000, 0x33000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x33000000, 0x99370f0b, + 0xee942d21, 0xff942d21, 0xff942d21, 0xff8c2d21, 0xff812821, 0xff812821, 0xff762421, 0xff632019, + 0xff632019, 0xff632019, 0xff633942, 0xff846573, 0xffa596a5, 0xffa596a5, 0xff846573, 0xff5a3d42, + 0xff4a2221, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xee421410, + 0xcc160705, 0x77000000, 0x55000000, 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe9dfdb, 0xffce9e94, 0xffce9e94, + 0xffce9e94, 0xffd09d8f, 0xffd09d8f, 0xffd09d8f, 0xffce9a8c, 0xffd09a8f, 0xffce968c, 0xffce968c, + 0xffce968c, 0xffce9384, 0xffce9384, 0xffce8e7b, 0xffce8e7b, 0xffc58e7b, 0xffc58e7b, 0xffc58e7b, + 0xffe6d9d3, 0xffadaaad, 0x00000000, 0x00000000, 0x22000000, 0x44290400, 0xbb290400, 0xee916b63, + 0xeec59e94, 0xeeb8908c, 0xeeb8908c, 0xeeb58a84, 0xeeb58a84, 0xeeb2837b, 0xeeaf7c73, 0xeead756b, + 0xeead756b, 0xee9c7168, 0xeed6a69c, 0xcc290800, 0x55290800, 0x22000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x33000000, 0xcc2c0f0b, 0xff76241b, 0xff76241b, 0xff76241b, 0xff76241b, 0xff812824, 0xff812824, + 0xff812824, 0xff812824, 0xff8f2d24, 0xff8f2d24, 0xff8f2d24, 0xff8f2d24, 0xff8c2b24, 0xff8c2b24, + 0xff8c2b24, 0xff8c2b24, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff942e26, 0xff942e26, + 0xff942e26, 0xff942e26, 0xff912d21, 0xff912d21, 0xff862821, 0xff862821, 0xff76271e, 0xff76271e, + 0xff68221b, 0xff68221b, 0xff5d1e19, 0xff5d1e19, 0xff471710, 0xff471710, 0xff2c0d0b, 0xcc000000, + 0x88000000, 0x44000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x33080000, + 0x88370f0b, 0xdd651e16, 0xff942d21, 0xff812821, 0xff812821, 0xff762421, 0xff762421, 0xff632019, + 0xff632019, 0xff632826, 0xff633942, 0xff846573, 0xff947d8c, 0xff947d8c, 0xff846573, 0xff5a3d42, + 0xff4a2221, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xff421410, 0xee2f0d0b, 0xbb160705, + 0x77000000, 0x55000000, 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0xff949694, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9a8c, 0xffce9a8c, 0xffce9a8c, 0xffce9a8c, 0xffce9a8c, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffc58a7b, 0xffc58a7b, 0xffc58a7b, 0xffc58a7b, 0xffb57d73, 0xffb57d73, 0xffb57d73, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x11000000, 0x33190400, 0xaa190400, 0xee91584d, + 0xeece8273, 0xeeb5867b, 0xeeb5867b, 0xeeb5867b, 0xeeb5867b, 0xeead7973, 0xeead7973, 0xeeaa6d65, + 0xeeaa6d65, 0xeeaa7d73, 0xeeefbaad, 0xbb210400, 0x44210400, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x44000000, 0xcc4a1410, 0xff76241b, 0xff76241b, 0xff76241b, 0xff732421, 0xff732421, + 0xff732421, 0xff812824, 0xff842821, 0xff842821, 0xff842821, 0xff842821, 0xff842821, 0xff842821, + 0xff8c2b24, 0xff842821, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2d21, 0xff8c2b24, 0xff8c2b24, + 0xff8c2b24, 0xff842821, 0xff862821, 0xff862821, 0xff862821, 0xff7b2421, 0xff76271e, 0xff68221b, + 0xff68221b, 0xff5a1c19, 0xff5d1e19, 0xff471710, 0xff311008, 0xff311008, 0xdd160705, 0x99000000, + 0x55000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11080000, + 0x33080000, 0x55080000, 0xaa370f0b, 0xee6b2021, 0xff812821, 0xff762421, 0xff762421, 0xff632019, + 0xff632019, 0xff632019, 0xff633134, 0xff734d5a, 0xff846573, 0xff846573, 0xff734d5a, 0xff522f31, + 0xff4a2221, 0xff421410, 0xff421410, 0xff421410, 0xee2f0d0b, 0xcc1b0705, 0x99080000, 0x66000000, + 0x44000000, 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9a8c, 0xffefdbd3, 0xfffffbf7, 0xfffffbf7, 0xffefddd9, 0xffefddd9, 0xffefddd9, + 0xffefddd9, 0xfffffbf7, 0xfffffbf7, 0xffecd5ce, 0xffc58a7b, 0xffb57d73, 0xffb57d73, 0xffb57d73, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x11000000, 0x22190400, 0x77190400, 0xdd552e26, + 0xeece8273, 0xeeaf7165, 0xeeaf7165, 0xeeb5867b, 0xeeaf7165, 0xeead7973, 0xeeaa6d65, 0xeeaa6d65, + 0xeeaa6d65, 0xeeaa7d73, 0xeeaa7d73, 0x88210400, 0x22210400, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x33000000, 0x99210b08, 0xee421610, 0xff632019, 0xff632019, 0xff632019, + 0xff632019, 0xff632019, 0xff732419, 0xff732419, 0xff732419, 0xff732419, 0xff6b221b, 0xff7b2821, + 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, 0xff7b2821, + 0xff7b2821, 0xff7b2821, 0xff7b2421, 0xff7b2421, 0xff7b2421, 0xff7b2421, 0xff6b2019, 0xff6b2019, + 0xff6b2019, 0xff4a1610, 0xff421410, 0xff421410, 0xee2c0d0b, 0xcc000000, 0x99000000, 0x55000000, + 0x22000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x22000000, 0x44000000, 0x771e0908, 0xbb3c1310, 0xdd5a1c19, 0xff5a1c19, 0xff55221b, + 0xff55221b, 0xff55221b, 0xff7b3129, 0xff58373c, 0xff7b4d52, 0xff7b4d52, 0xff58373c, 0xff5a2d29, + 0xff3f1f1b, 0xff24120e, 0xee24120e, 0xcc210808, 0x990b0303, 0x77000000, 0x55000000, 0x44000000, + 0x22000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9a8c, 0xffefdbd3, 0xfffffbf7, 0xfffffbf7, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffffbf7, 0xfffffbf7, 0xffd9afa5, 0xffc58a7b, 0xffb57d73, 0xffb57d73, 0xffb57d73, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x11000000, 0x22190400, 0x44190400, 0xbb190400, + 0xee91584d, 0xeeaa5d50, 0xeeaf7165, 0xeeaf7165, 0xeeaf7165, 0xeeaa6d65, 0xeea76158, 0xeea76158, + 0xeeaa6d65, 0xeeaa7d73, 0xcc210400, 0x55210400, 0x22210400, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11000000, 0x22000000, 0x66000000, 0xcc210b08, 0xff451610, 0xff632019, + 0xff451610, 0xff632019, 0xff5d1c13, 0xff5d1c13, 0xff5d1c13, 0xff5d1c13, 0xff6b221b, 0xff6b221b, + 0xff6b221b, 0xff6b221b, 0xff6e231b, 0xff6e231b, 0xff6e231b, 0xff6e231b, 0xff6e231b, 0xff6e231b, + 0xff6e231b, 0xff6e231b, 0xff651e1b, 0xff7b2421, 0xff651e1b, 0xff651e1b, 0xff6b2019, 0xff4a1610, + 0xff4a1610, 0xff4a1610, 0xff2c0d0b, 0xee160705, 0xbb000000, 0x88000000, 0x55000000, 0x22000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x11000000, 0x33000000, 0x44000000, 0x66000000, 0x991e0908, 0xbb2f130e, + 0xdd2f130e, 0xee55221b, 0xff55221b, 0xff58373c, 0xff58373c, 0xff58373c, 0xee342226, 0xdd3f1f1b, + 0xcc24120e, 0xaa080400, 0x88080400, 0x77000000, 0x55000000, 0x44000000, 0x33000000, 0x11000000, + 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffce9a8c, 0xffce9a8c, + 0xffce9a8c, 0xffce9a8c, 0xffce9a8c, 0xfffffbf7, 0xfffffbf7, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfffffbf7, 0xffecd5ce, 0xffc58a7b, 0xffc58a7b, 0xffb57d73, 0xffb57d73, 0xffb57d73, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x11190400, 0x22190400, 0x77190400, + 0xcc190400, 0xeea5493a, 0xeeaa5d50, 0xeeaa5d50, 0xeeaa5d50, 0xeea76158, 0xeea76158, 0xeea76158, + 0xeea5554a, 0xcc210400, 0x77210400, 0x22210400, 0x11210400, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x44000000, 0x88080000, 0xdd260b08, + 0xee451610, 0xff451610, 0xff47140e, 0xff5d1c13, 0xff5d1c13, 0xff5d1c13, 0xff5a1b16, 0xff5a1b16, + 0xff5a1b16, 0xff5a1b16, 0xff601e16, 0xff601e16, 0xff6e231b, 0xff601e16, 0xff601e16, 0xff601e16, + 0xff601e16, 0xff601e16, 0xff651e1b, 0xff651e1b, 0xff501716, 0xff501716, 0xff4a1610, 0xff4a1610, + 0xff290b08, 0xee290b08, 0xdd000000, 0xaa000000, 0x77000000, 0x44000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x22000000, 0x33000000, 0x55080400, + 0x66080400, 0x77080400, 0x88080400, 0x88100c10, 0x99100c10, 0x99100c10, 0x88100c10, 0x8824120e, + 0x77080400, 0x66080400, 0x55080400, 0x44000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffce9284, 0xffce9284, + 0xffce9284, 0xffc58e7b, 0xffc58e7b, 0xffd9b3a7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffcea9a2, 0xffb57d73, 0xffb57d73, 0xffad756b, 0xffad756b, 0xffad756b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x22000000, + 0x66000000, 0x99210400, 0xaa420800, 0xbb420800, 0xbb630c00, 0xcc520c00, 0xbb520c00, 0xbb370800, + 0x991b0400, 0x66000000, 0x33000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x22080000, 0x44080000, + 0x77080000, 0xbb080000, 0xee310c08, 0xff47140e, 0xff47140e, 0xff47140e, 0xff4a1410, 0xff4a1410, + 0xff5a1b16, 0xff5a1b16, 0xff521810, 0xff521810, 0xff521810, 0xff521810, 0xff521810, 0xff521810, + 0xff521810, 0xff521810, 0xff501716, 0xff501716, 0xff501716, 0xff3a1010, 0xff290b08, 0xee290b08, + 0xcc080000, 0xaa080000, 0x88000000, 0x55000000, 0x33000000, 0x11000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x22080400, + 0x33080400, 0x33080400, 0x44080400, 0x44100c10, 0x55100c10, 0x55100c10, 0x44100c10, 0x44080400, + 0x33080400, 0x33080400, 0x22080400, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffce9284, 0xffce9284, + 0xffce9284, 0xffc58e7b, 0xffc58e7b, 0xffc58e7b, 0xffecd9d3, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffe6d4d0, 0xffb57d73, 0xffb57d73, 0xffb57d73, 0xffad756b, 0xffad756b, 0xffad756b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, + 0x22000000, 0x22000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000, + 0x22000000, 0x22000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, + 0x22000000, 0x44000000, 0x66000000, 0x99000000, 0xbb080303, 0xdd190808, 0xee260b0b, 0xff3a1010, + 0xff3a1010, 0xff3a1010, 0xff3a1410, 0xff3a1410, 0xff3a1410, 0xff3a1410, 0xff4a1410, 0xff4a1410, + 0xff4a1410, 0xff4a1410, 0xff311010, 0xee210b0b, 0xdd100505, 0xcc100505, 0xbb000000, 0x99000000, + 0x77000000, 0x55000000, 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffce9284, 0xffce9284, + 0xffce9284, 0xffc58e7b, 0xffc58e7b, 0xffc58e7b, 0xffd9b3a7, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffcea9a2, 0xffb57d73, 0xffb57d73, 0xffb57d73, 0xffad756b, 0xffad756b, 0xffad756b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x11000000, 0x33000000, 0x44000000, 0x55000000, 0x77000000, 0x88000000, + 0xaa000000, 0xbb000000, 0xcc130705, 0xcc130705, 0xcc130705, 0xdd130705, 0xcc190705, 0xcc190705, + 0xcc000000, 0xbb000000, 0xbb000000, 0x99000000, 0x88000000, 0x66000000, 0x55000000, 0x44000000, + 0x33000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffce9284, 0xffce9284, + 0xffce9284, 0xffc58e7b, 0xffc58e7b, 0xffc58e7b, 0xffc58e7b, 0xffe9d7d3, 0xffffffff, 0xffffffff, + 0xffdec2bd, 0xffb57d73, 0xffb57d73, 0xffb57d73, 0xffb57d73, 0xffad756b, 0xffad756b, 0xffad756b, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11000000, 0x11000000, 0x22000000, 0x22000000, + 0x33000000, 0x44000000, 0x55000000, 0x55000000, 0x55000000, 0x66000000, 0x66000000, 0x66000000, + 0x55000000, 0x55000000, 0x44000000, 0x44000000, 0x33000000, 0x22000000, 0x11000000, 0x11000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffc5867b, 0xffc5867b, + 0xffc5867b, 0xffc58a7b, 0xffbd8376, 0xffbd8376, 0xffbd8376, 0xffc59b8f, 0xfff7e7e6, 0xfff7e7e6, + 0xffc59b8f, 0xffb5796b, 0xffb5796b, 0xffad7568, 0xffad7568, 0xffa56d63, 0xffa56d63, 0xffa56d63, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x11000000, + 0x11000000, 0x11000000, 0x11000000, 0x11000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffc5867b, 0xffc5867b, + 0xffc5867b, 0xffbd8376, 0xffbd8376, 0xffb57c70, 0xffb57c70, 0xffad7563, 0xffdec1ba, 0xffdec1ba, + 0xffad7563, 0xffad7568, 0xffad7568, 0xffa57165, 0xffa57165, 0xffa56d63, 0xffa56d63, 0xffa56d63, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffc5867b, 0xffc5867b, + 0xffc5867b, 0xffbd8376, 0xffb57c70, 0xffb57c70, 0xffb57c70, 0xffad7563, 0xffad7563, 0xffad7563, + 0xffad7563, 0xffa57165, 0xffa57165, 0xffa57165, 0xff9c6d63, 0xffa56d63, 0xffa56d63, 0xffa56d63, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff949694, 0xffe6e3e6, 0xffc5867b, 0xffc5867b, + 0xffc5867b, 0xffb57c70, 0xffb57c70, 0xffad756b, 0xffad756b, 0xffad7563, 0xffad7563, 0xffad7563, + 0xffad7563, 0xff9c6d63, 0xff9c6d63, 0xff9c6d63, 0xff9c6d63, 0xffa56d63, 0xffa56d63, 0xffa56d63, + 0xffe6e3e6, 0xffadaaad, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff8f8f8f, 0xffded4d0, 0xffad7d73, 0xffad7d73, + 0xffad7d73, 0xffa57163, 0xffa57163, 0xffa57163, 0xffa57163, 0xff9c695a, 0xff9c695a, 0xff9c695a, + 0xff9c695a, 0xff94655a, 0xff94655a, 0xff94655a, 0xff94655a, 0xff946d63, 0xff946d63, 0xff946d63, + 0xffdbcecb, 0xffa5a6a5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff8f8f8f, 0xffded4d0, 0xfff7ffff, 0xffad7d73, + 0xffad7d73, 0xffa57163, 0xffa57163, 0xffa57163, 0xffa57163, 0xff9c695a, 0xff9c695a, 0xff9c695a, + 0xff9c695a, 0xff94655a, 0xff94655a, 0xff94655a, 0xff94655a, 0xff946d63, 0xff946d63, 0xffffffff, + 0xffdbcecb, 0xffa5a6a5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff8f8f8f, 0xffded4d0, 0xffded4d0, 0xffded4d0, + 0xffded4d0, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, + 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffd6dbde, 0xffdbcecb, 0xffdbcecb, 0xffdbcecb, + 0xffdbcecb, 0xffa5a6a5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff8f8f8f, 0xffc5a9a2, 0xffc5a9a2, 0xffc5a9a2, + 0xffc5a9a2, 0xffc5b7b5, 0xffc5b7b5, 0xffc5b7b5, 0xffc5b7b5, 0xffc3b5b2, 0xffc3b5b2, 0xffc3b5b2, + 0xffc3b5b2, 0xffc0b3b2, 0xffc0b3b2, 0xffc0b3b2, 0xffc0b3b2, 0xffb89e97, 0xffb89e97, 0xffb89e97, + 0xffb89e97, 0xff6e6f6e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static const UINT g_DXUTGUITextureSrcDataSizeInBytes = 262272; + +static const DWORD g_DXUTArrowMeshSrcData[] = +{ + 0x20666f78, 0x33303330, 0x70697a62, 0x32333030, 0x000030d7, 0x087930c7, 0x59ed4b43, 0xd51c6c5d, + 0x71dbbe15, 0xacbbc1d6, 0xe125d493, 0xc1024e27, 0x7133f9c1, 0xec1098ec, 0x1b1daef1, 0xc6d24eb7, + 0xc713fa10, 0x64866f59, 0xd9aecd95, 0x694304dd, 0x4485686b, 0xad2fb6a5, 0x78df44a8, 0x6cca8828, + 0x20a2895a, 0x2aaf60ef, 0x905215b5, 0x4fa9515a, 0xa45b4d45, 0xa1e09548, 0x9e94d282, 0xcf5df333, + 0x8a3acdf1, 0xec0c5368, 0xbefec6ac, 0xf77ee733, 0xdef73bdc, 0x9d667739, 0x4a65a90a, 0xf27c81a9, + 0x7040d394, 0xba2785e0, 0x7e7e38ff, 0xd5bb0be5, 0xba1f17fa, 0x56a633b0, 0x1546bf79, 0x1d7cec51, + 0x164bef39, 0x8ec9e9f3, 0xb02e0ec9, 0x1fe77ed7, 0xbf399e4f, 0x550707f2, 0x1fceceef, 0x36a1db3e, + 0xdc985b93, 0x316e794e, 0xc415a965, 0x2413551a, 0xf77d749a, 0xc2d993e5, 0x29fcb983, 0xe2d5905f, + 0x61519a86, 0x7a942488, 0x36fb0b90, 0x1df5c9ad, 0x5cc55272, 0x188e559e, 0x4288e08d, 0x1aee41e4, + 0x47c0123e, 0xae72c8b5, 0x189c29ca, 0xbebca648, 0x5a643318, 0xf91567c9, 0x90e1d964, 0x933a2f93, + 0xe963d943, 0x52685394, 0xaeaf8a1d, 0x8bcce8e4, 0x058b45b1, 0xaa87527d, 0x2afedab9, 0x642f72d5, + 0x4daeacb9, 0xfc8fd936, 0x4cc6ae0c, 0x15a5ae77, 0x2018bc05, 0x8feb9b20, 0x2bdd0e02, 0x6172b81f, + 0x50440c73, 0xbadd3f70, 0x31c0a664, 0xadf719f7, 0xf859fa15, 0x3d721e5c, 0xc62ff55f, 0x701d670c, + 0x40b14754, 0x11d86164, 0x903fbd84, 0xbd058b32, 0x97d2ddcc, 0x07f2e4cb, 0x0e711307, 0x1ffd4ffb, + 0x09963e74, 0x6121e6c2, 0x39de5391, 0xee0f8fe6, 0xc779e395, 0x6f94fac9, 0xb4e678d3, 0x664c5c13, + 0xe5244e26, 0x2cfad200, 0xcdf678ff, 0x7e4e75df, 0x20317918, 0x9f274593, 0x6f58664e, 0x8c32319f, + 0x7b94f916, 0x550533c3, 0x761ee44c, 0x300c2e88, 0x5627aea4, 0xa7527098, 0x4a3cc933, 0x4e717354, + 0xf4850ba5, 0x8e6a2d19, 0x1fb81586, 0x74e1d03a, 0x26c1c8a1, 0x06890caa, 0xb1da35be, 0x9a65dc60, + 0x3064ce14, 0x859df497, 0xd5c55639, 0xfb0b9c1f, 0xd25ef2e9, 0x46f1ae81, 0xfebf4f1f, 0x749913d3, + 0xe74c592a, 0x1c8998b2, 0x6ffdd0f0, 0x3f9bfcbc, 0xa9e868fc, 0x3fcf23f3, 0xe7f1da57, 0x3f3c31f9, + 0xcf14f5c9, 0x8fa7c81e, 0x8cc9b3a7, 0x917c919c, 0x983a7507, 0x3fb4b2f5, 0xeb6ac50a, 0xca48c6f7, + 0x07633ac9, 0xb3ea3973, 0xf58d2d2b, 0x352b3f5e, 0x8ecbab65, 0x0119b7ab, 0xf3e78c30, 0xa6af87b9, + 0xfddef7ee, 0xe5551ece, 0xafc27690, 0x65c7aaa8, 0xfbe37375, 0x6f50c91e, 0x773bf939, 0x9bc6f87c, + 0xa35729f6, 0xaef0ae99, 0x256f73b6, 0x00957ff8, 0x7d46b8f8, 0x7e7fc53e, 0x5f343232, 0x75de5ead, + 0xc1ef61ad, 0xf59d3773, 0x3950da6a, 0x35c4aa5e, 0x8a503e1e, 0x3adebfd7, 0xb2c778cb, 0x7f9dfc62, + 0x97c3d8ff, 0x8ef74db6, 0x61ecbaff, 0xd5fa7db5, 0xb2fb7024, 0xd9f6ace2, 0xab34a077, 0xece692cb, + 0x9d93d74c, 0xfe5d9cd0, 0x4757ab7a, 0xe1efef9b, 0xbf4db7f7, 0x68719a4a, 0x498126f6, 0x7c36fe33, + 0x461e3348, 0x68ce20d9, 0x5a338825, 0x568ce209, 0x95a33882, 0x2568ce20, 0x095a3388, 0x82568ce2, + 0xc44d3d38, 0x7104ad19, 0x9c412b46, 0xf4e2269e, 0xa7a71134, 0x67c93889, 0x6bf4f0fe, 0xec3ffb7d, + 0x937ab0db, 0x4e8bbc62, 0x19fabd0b, 0x5b82433a, 0x075e69b0, 0x6132f9ac, 0x9b0c23e3, 0x69b0f5e6, + 0xcd361cbe, 0xf34d83af, 0x8f34d806, 0x1479a6c0, 0x87afcd36, 0x6c18f34d, 0x6360879a, 0x9fa74cde, + 0x1d7c06ca, 0x4af0166c, 0xcd87af83, 0xf0655e02, 0xc059b00d, 0xadf8359f, 0x4dc059b0, 0x360dbf06, + 0x0673f80b, 0x059b08df, 0x6fc1837c, 0x5e02cd87, 0xd816f06d, 0x0635e02c, 0x059b04df, 0xefc1a37c, + 0xbe02cd80, 0xb0ade0c9, 0x1b37c059, 0x166c337c, 0xdf062df0, 0xdc059b02, 0x7166f068, 0xb9d2d6bf, + 0x826dce95, 0x382ede33, 0x19c136e3, 0xe33829df, 0x6e33821d, 0x4ef19c17, 0x087719c1, 0x7053b8ce, + 0x6704bbc6, 0x977825dc, 0x816b5f98, 0x1bbe0b77, 0x9592aa6d, 0x5990fe2f, 0xd25cbcf0, 0xb7df7d78, + 0x9f46a7ec, 0xe17666e9, 0x7dced644, 0xf1995cfb, 0xf6eda1e0, 0x78f667b3, 0x2607facf, 0xf479ee9f, + 0xd5e045bb, 0x6fb686e5, 0xddffb878, 0x7a707746, 0x7f4fc3c4, 0xf4cdd47f, 0xa6930f2a, 0xd0339a4b, + 0x07b34974, 0xda692e9a, 0x26932cd0, 0xd21eeaf0, 0x9369a1b4, 0x9b4d0da6, 0x60448d34, 0x33cc45ca, + 0x6515c7c2, 0x8ae9a15d, 0x83115cba, 0x8b2b622b, 0x5b45bb98, 0x5b46d16c, 0x7d16ddb4, 0xb2be8b62, + 0x98f61f45, 0x5c652f31, 0x1ed4c87b, 0xcc87b532, 0x44c87852, 0x87eedd16, 0x084ce7bd, 0x87e93f65, + 0xdea666f9, 0xb3feed9b, 0x2da69e4b, 0x5f5e2238, 0x448df95e, 0xe783dd58, 0x2758b377, 0x87573af4, + 0xb58c2c35, 0xa4d6396a, 0x513dac06, 0x8c3131ac, 0x135815cd, 0x376e6156, 0x80de8e61, 0x7306b6b9, + 0xfd8c26e6, 0xffef705b, 0xf04675df, 0x0f57b05b, 0xb2a52f7b, 0x5179b5ce, 0xced6ede0, 0xe45895bd, + 0x7c35c54d, 0xeeaea051, 0xd7b8c145, 0x85a12ddf, 0x274a972a, 0x9ec71a13, 0xa10a254f, 0x1c69b7a2, + 0xb89c3b5d, 0xe1e8ba54, 0x24b5cfb3, 0xe3274e7e, 0x08ed917f, 0x413c635d, 0xf5065cbe, 0x4eb5a4bf, + 0xdab38a87, 0xe2e941fe, 0x49fc28ec, 0x742cee63, 0x7dee6348, 0x5cef93e8, 0xc692f516, 0xf57ecfdc, + 0x7db497d3, 0xcf10b492, 0xd17b3a9c, 0xf9d225c3, 0xff8c9d05, 0xc5acfa49, 0x36f924f8, 0xb7bc1952, + 0xc62d62e9, 0xf4e3f75f, 0xc5ece870, 0x93f861f8, 0x9d04a246, 0xbdf18a31, 0x1a4faf92, 0x57a81389, + 0x6fe7db1f, 0x862f0d6d, 0x36a9636b, 0x1c1bfe96, 0xead38f56, 0x9c13f474, 0x1c8a37a3, 0xba39195d, + 0x65727232, 0xc8cae0e4, 0x639195b9, 0x56a7232b, 0x8cad0e46, 0x3919599c, 0x740dceb2, 0xe46edc4e, + 0xd45f3ac0, 0x234eef39, 0xa3f9d607, 0x8c3b79ce, 0x93e7581c, 0x44ede73a, 0x2ef9206e, 0x66e02cd8, + 0x66c17783, 0xf833af01, 0xc059b05d, 0x1bbe0deb, 0x83780b36, 0xcd86efc1, 0xe0d5be02, 0x80b3607b, + 0x3df8336f, 0x1bc059b0, 0x9b0dde0d, 0xc1bb7c05, 0x80b3607b, 0xc36e0c5b, 0x326f0166, 0x166c2f78, + 0x8f061df0, 0xb70166c3, 0x9b013c1a, 0xe0d9bc05, 0xc059b07d, 0x0fde0c5b, 0xd5bc059b, 0xb3617be0, + 0x7c19b780, 0x0679ec40, 0x7c91c7b0, 0x0681ec50, 0xfc91e7b1, 0xba27b15e, 0xc9207b17, 0x691ec487, + 0xf25b6308, 0x79de3176, 0x3a79f4bf, 0xe33820bf, 0xef19c161, 0x7ef19c13, 0x101f19c1, 0x0517f19c, + 0xc125fc67, 0x9c141f19, 0x8ce088f1, 0xf19c13ef, 0x3e3382fd, 0x07e33824, 0x65fc6704, 0x457f19c1, + 0x155fc670, 0x04d7f19c, 0x70587c67, 0x3382a3c6, 0xe338223e, 0x1f19c131, 0x52719c15, 0x7cfa24f0, + 0xd59117d1, 0xfda5d892, 0xe02969e2, 0xb71fbffd, 0xdfebfe5f, 0xe5fede67, 0xbb807a5f, 0x46c64719, + 0x5f9b96ec, 0xf1dc61ec, 0xdafda744, 0xcc66c440, 0xae3399ff, 0xc7eceba3, 0x7971cb98, 0xc98d19e0, + 0xa87daca7, 0xd2cbabac, 0xd26b577f, 0x750eb775, 0xc7573951, 0x7c233c00, 0x2baca2ca, 0x97515d34, + 0x4570622b, 0xf16e1e6c, 0x5b457663, 0x5746d15c, 0x25d75db7, 0xa58f5337, 0xcb78798e, 0xe27adff0, + 0x6fb61ccf, 0x187a67cc, 0x5eedfe1f, 0x0ba97bfb, 0x9be57e1e, 0x193e6c1b, 0x31af8db3, 0xc32e5f66, + 0x5ec16b58, 0x2ff276d6, 0x70d27f6b, 0xdcd90eb5, 0x5f27d093, 0x1a4bd757, 0x84a72f7c, 0x59fdacbd, + 0x46bceb4b, 0x4577d0a7, 0xc788aebd, 0x22ba7115, 0xcbb4577e, 0x093dedd5, 0x8dfd8e7d, 0x3f7afc87, + 0x3ffe2f4e, 0x624b5c0a, 0x2d6c496b, 0xb125ad89, 0xd3f624b5, 0xe95ec49e, 0xd638c743, 0x829fa3a9, + 0x0fb51d0f, 0x9887fe31, 0xb4bfd863, 0x621f847f, 0xdec7c59a, 0xecc3e20d, 0x7511f146, 0xa9e0f893, + 0x156e5c3f, 0xc4db201f, 0x7b8fc5c7, 0xf7e2221b, 0x0000001f +}; + +static const UINT g_DXUTArrowMeshSrcDataSizeInBytes = 2193; + +//----------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateGUITextureFromInternalArray9( LPDIRECT3DDEVICE9 pd3dDevice, IDirect3DTexture9** ppTexture, D3DXIMAGE_INFO* pInfo ) +{ + return D3DXCreateTextureFromFileInMemoryEx( pd3dDevice, g_DXUTGUITextureSrcData, g_DXUTGUITextureSrcDataSizeInBytes, + D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, + D3DX_DEFAULT, D3DX_DEFAULT, 0, pInfo, NULL, ppTexture ); +} + +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateGUITextureFromInternalArray11(ID3D11Device* pd3dDevice, ID3D11Texture2D** ppTexture, D3DX11_IMAGE_INFO* pInfo) +{ + HRESULT hr; + + D3DX11_IMAGE_INFO SrcInfo; + if( !pInfo ) + { + D3DX11GetImageInfoFromMemory( g_DXUTGUITextureSrcData, g_DXUTGUITextureSrcDataSizeInBytes, NULL, &SrcInfo, NULL ); + pInfo = &SrcInfo; + } + + ID3D11Resource *pRes; + D3DX11_IMAGE_LOAD_INFO loadInfo; + loadInfo.Width = D3DX11_DEFAULT; + loadInfo.Height = D3DX11_DEFAULT; + loadInfo.Depth = D3DX11_DEFAULT; + loadInfo.FirstMipLevel = 0; + loadInfo.MipLevels = 1; + loadInfo.Usage = D3D11_USAGE_DEFAULT; + loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE; + loadInfo.CpuAccessFlags = 0; + loadInfo.MiscFlags = 0; + //loadInfo.Format = MAKE_TYPELESS( pInfo->Format ); + loadInfo.Format = MAKE_SRGB( pInfo->Format ); + loadInfo.Filter = D3DX11_FILTER_NONE; + loadInfo.MipFilter = D3DX11_FILTER_NONE; + loadInfo.pSrcInfo = pInfo; + + hr = D3DX11CreateTextureFromMemory( pd3dDevice, g_DXUTGUITextureSrcData, g_DXUTGUITextureSrcDataSizeInBytes, &loadInfo, NULL, &pRes, NULL ); + if( FAILED( hr ) ) + return hr; + hr = pRes->QueryInterface( __uuidof( ID3D11Texture2D ), (LPVOID*)ppTexture ); + SAFE_RELEASE( pRes ); + + return S_OK; +} + +//----------------------------------------------------------------------------- +HRESULT WINAPI DXUTCreateArrowMeshFromInternalArray( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh** ppMesh ) +{ + return D3DXLoadMeshFromXInMemory( g_DXUTArrowMeshSrcData, g_DXUTArrowMeshSrcDataSizeInBytes, + D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, ppMesh ); +} + diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTres.h b/Demos/DX11ClothDemo/DXUT/Optional/DXUTres.h new file mode 100644 index 0000000..beab017 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTres.h @@ -0,0 +1,18 @@ +//---------------------------------------------------------------------------- +// File: dxutres.h +// +// Functions to create DXUT media from arrays in memory +// +// Copyright (c) Microsoft Corp. All rights reserved. +//----------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_RES_H +#define DXUT_RES_H + +HRESULT WINAPI DXUTCreateGUITextureFromInternalArray9( LPDIRECT3DDEVICE9 pd3dDevice, IDirect3DTexture9** ppTexture, + D3DXIMAGE_INFO* pInfo ); +HRESULT WINAPI DXUTCreateGUITextureFromInternalArray11( ID3D11Device* pd3dDevice, ID3D11Texture2D** ppTexture, + D3DX11_IMAGE_INFO* pInfo ); +HRESULT WINAPI DXUTCreateArrowMeshFromInternalArray( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh** ppMesh ); + +#endif diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.cpp b/Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.cpp new file mode 100644 index 0000000..334fa26 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.cpp @@ -0,0 +1,2853 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTSettingsDlg.cpp +// +// Dialog for selection of device settings +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#include "DXUTgui.h" +#include "DXUTsettingsDlg.h" +#undef min // use __min instead +#undef max // use __max instead + + +//-------------------------------------------------------------------------------------- +// Internal functions forward declarations +//-------------------------------------------------------------------------------------- +WCHAR* DXUTAPIVersionToString( DXUTDeviceVersion version ); +WCHAR* DXUTPresentIntervalToString( UINT pi ); +WCHAR* DXUTMultisampleTypeToString( D3DMULTISAMPLE_TYPE MultiSampleType ); +WCHAR* DXUTD3DDeviceTypeToString( D3DDEVTYPE devType ); +WCHAR* DXUTD3DX11DeviceTypeToString( D3D_DRIVER_TYPE devType ); +WCHAR* DXUTVertexProcessingTypeToString( DWORD vpt ); + + +HRESULT DXUTSnapDeviceSettingsToEnumDevice( DXUTDeviceSettings* pDeviceSettings, bool forceEnum, D3D_FEATURE_LEVEL forceFL = D3D_FEATURE_LEVEL(0) ); + +//-------------------------------------------------------------------------------------- +// Global state +//-------------------------------------------------------------------------------------- +DXUTDeviceSettings g_DeviceSettings; + +CD3DSettingsDlg* WINAPI DXUTGetD3DSettingsDialog() +{ + // Using an accessor function gives control of the construction order + static CD3DSettingsDlg dlg; + return &dlg; +} + + +//-------------------------------------------------------------------------------------- +CD3DSettingsDlg::CD3DSettingsDlg() +{ + m_pStateBlock = NULL; + m_bActive = false; + m_pActiveDialog = NULL; + + m_Levels[0] = D3D_FEATURE_LEVEL_9_1; + m_Levels[1] = D3D_FEATURE_LEVEL_9_2; + m_Levels[2] = D3D_FEATURE_LEVEL_9_3; + m_Levels[3] = D3D_FEATURE_LEVEL_10_0; + m_Levels[4] = D3D_FEATURE_LEVEL_10_1; + m_Levels[5] = D3D_FEATURE_LEVEL_11_0; + +} + + +//-------------------------------------------------------------------------------------- +CD3DSettingsDlg::~CD3DSettingsDlg() +{ + // Release the memory used to hold the D3D11 refresh data in the combo box + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); + if( pComboBox ) + for( UINT i = 0; i < pComboBox->GetNumItems(); ++i ) + { + DXGI_RATIONAL* pRate = reinterpret_cast( pComboBox->GetItemData( i ) ); + delete pRate; + } +} + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::Init( CDXUTDialogResourceManager* pManager ) +{ + assert( pManager ); + m_Dialog.Init( pManager, false ); // Don't register this dialog. + m_RevertModeDialog.Init( pManager, false ); // Don't register this dialog. + m_pActiveDialog = &m_Dialog; + CreateControls(); +} + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::Init( CDXUTDialogResourceManager* pManager, LPCWSTR szControlTextureFileName ) +{ + assert( pManager ); + m_Dialog.Init( pManager, false, szControlTextureFileName ); // Don't register this dialog. + m_RevertModeDialog.Init( pManager, false, szControlTextureFileName ); // Don't register this dialog. + m_pActiveDialog = &m_Dialog; + CreateControls(); +} + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::Init( CDXUTDialogResourceManager* pManager, LPCWSTR pszControlTextureResourcename, + HMODULE hModule ) +{ + assert( pManager ); + m_Dialog.Init( pManager, false, pszControlTextureResourcename, hModule ); // Don't register this dialog. + m_RevertModeDialog.Init( pManager, false, pszControlTextureResourcename, hModule ); // Don't register this dialog + m_pActiveDialog = &m_Dialog; + CreateControls(); +} + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::CreateControls() +{ + // Set up main settings dialog + m_Dialog.EnableKeyboardInput( true ); + m_Dialog.SetFont( 0, L"Arial", 15, FW_NORMAL ); + m_Dialog.SetFont( 1, L"Arial", 28, FW_BOLD ); + + // Right-justify static controls + CDXUTElement* pElement = m_Dialog.GetDefaultElement( DXUT_CONTROL_STATIC, 0 ); + if( pElement ) + { + pElement->dwTextFormat = DT_VCENTER | DT_RIGHT; + + // Title + CDXUTStatic* pStatic = NULL; + m_Dialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Direct3D Settings", 10, 5, 400, 50, false, &pStatic ); + pElement = pStatic->GetElement( 0 ); + pElement->iFont = 1; + pElement->dwTextFormat = DT_TOP | DT_LEFT; + } + + // DXUTSETTINGSDLG_API_VERSION + m_Dialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"API Version", 10, 35, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_API_VERSION, 200, 35, 300, 23 ); + + + //DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL_LABEL, L"Feature Level", 10, 60, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL, 200, 60, 300, 23 ); + m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL )->SetDropHeight( 106 ); + + + // DXUTSETTINGSDLG_ADAPTER + m_Dialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Display Adapter", 10, 85, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_ADAPTER, 200, 85, 300, 23 ); + + // DXUTSETTINGSDLG_DEVICE_TYPE + m_Dialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Render Device", 10, 110, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_DEVICE_TYPE, 200, 110, 300, 23 ); + + // DXUTSETTINGSDLG_WINDOWED, DXUTSETTINGSDLG_FULLSCREEN + m_Dialog.AddCheckBox( DXUTSETTINGSDLG_DEVICECLIP, L"Clip to device when window spans across multiple monitors", + 250, 136, 500, 16 ); + m_Dialog.AddRadioButton( DXUTSETTINGSDLG_WINDOWED, DXUTSETTINGSDLG_WINDOWED_GROUP, L"Windowed", + 360, 157, 100, 16 ); + m_Dialog.AddRadioButton( DXUTSETTINGSDLG_FULLSCREEN, DXUTSETTINGSDLG_WINDOWED_GROUP, L"Full Screen", + 220, 157, 100, 16 ); + + // DXUTSETTINGSDLG_ADAPTER_FORMAT + m_Dialog.AddStatic( DXUTSETTINGSDLG_ADAPTER_FORMAT_LABEL, L"Adapter Format", 10, 175, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT, 200, 175, 300, 23 ); + + // DXUTSETTINGSDLG_RESOLUTION + m_Dialog.AddStatic( DXUTSETTINGSDLG_RESOLUTION_LABEL, L"Resolution", 10, 200, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_RESOLUTION, 200, 200, 200, 23 ); + m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION )->SetDropHeight( 106 ); + + // DXUTSETTINGSDLG_RES_SHOW_ALL + m_Dialog.AddCheckBox( DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL, L"Show All Aspect Ratios", 420, 200, 200, 23, false ); + + // DXUTSETTINGSDLG_REFRESH_RATE + m_Dialog.AddStatic( DXUTSETTINGSDLG_REFRESH_RATE_LABEL, L"Refresh Rate", 10, 225, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_REFRESH_RATE, 200, 225, 300, 23 ); + + // DXUTSETTINGSDLG_BACK_BUFFER_FORMAT + m_Dialog.AddStatic( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT_LABEL, L"Back Buffer Format", 10, 260, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT, 200, 260, 300, 23 ); + + // DXUTSETTINGSDLG_DEPTH_STENCIL + m_Dialog.AddStatic( DXUTSETTINGSDLG_DEPTH_STENCIL_LABEL, L"Depth/Stencil Format", 10, 285, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL, 200, 285, 300, 23 ); + + // DXUTSETTINGSDLG_MULTISAMPLE_TYPE + m_Dialog.AddStatic( DXUTSETTINGSDLG_MULTISAMPLE_TYPE_LABEL, L"Multisample Type", 10, 310, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE, 200, 310, 300, 23 ); + + // DXUTSETTINGSDLG_MULTISAMPLE_QUALITY + m_Dialog.AddStatic( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY_LABEL, L"Multisample Quality", 10, 335, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY, 200, 335, 300, 23 ); + + // DXUTSETTINGSDLG_VERTEX_PROCESSING + m_Dialog.AddStatic( DXUTSETTINGSDLG_VERTEX_PROCESSING_LABEL, L"Vertex Processing", 10, 360, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING, 200, 360, 300, 23 ); + + // DXUTSETTINGSDLG_PRESENT_INTERVAL + m_Dialog.AddStatic( DXUTSETTINGSDLG_PRESENT_INTERVAL_LABEL, L"Vertical Sync", 10, 385, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_PRESENT_INTERVAL, 200, 385, 300, 23 ); + + // DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL, L"Adapter Output", 10, 175, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT, 200, 175, 300, 23 ); + + // DXUTSETTINGSDLG_D3D11_RESOLUTION + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL, L"Resolution", 10, 200, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION, 200, 200, 200, 23 ); + m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION )->SetDropHeight( 106 ); + + // DXUTSETTINGSDLG_D3D11_REFRESH_RATE + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL, L"Refresh Rate", 10, 225, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE, 200, 225, 300, 23 ); + + // DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT_LABEL, L"Back Buffer Format", 10, 260, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT, 200, 260, 300, 23 ); + + // DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT_LABEL, L"Multisample Count", 10, 285, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT, 200, 285, 300, 23 ); + + // DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY_LABEL, L"Multisample Quality", 10, 310, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY, 200, 310, 300, 23 ); + + // DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL + m_Dialog.AddStatic( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL_LABEL, L"Vertical Sync", 10, 335, 180, 23 ); + m_Dialog.AddComboBox( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL, 200, 335, 300, 23 ); + + // DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE + m_Dialog.AddCheckBox( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE, L"Create Debug Device", 200, 365, 180, 23 ); + + // DXUTSETTINGSDLG_OK, DXUTSETTINGSDLG_CANCEL + m_Dialog.AddButton( DXUTSETTINGSDLG_OK, L"OK", 230, 440, 73, 31 ); + m_Dialog.AddButton( DXUTSETTINGSDLG_CANCEL, L"Cancel", 315, 440, 73, 31, 0, true ); + + // Set up mode change dialog + m_RevertModeDialog.EnableKeyboardInput( true ); + m_RevertModeDialog.EnableNonUserEvents( true ); + m_RevertModeDialog.SetFont( 0, L"Arial", 15, FW_NORMAL ); + m_RevertModeDialog.SetFont( 1, L"Arial", 28, FW_BOLD ); + + pElement = m_RevertModeDialog.GetDefaultElement( DXUT_CONTROL_STATIC, 0 ); + if( pElement ) + { + pElement->dwTextFormat = DT_VCENTER | DT_RIGHT; + + // Title + CDXUTStatic* pStatic = NULL; + m_RevertModeDialog.AddStatic( DXUTSETTINGSDLG_STATIC, L"Do you want to keep these display settings?", 10, 5, + 640, 50, false, &pStatic ); + pElement = pStatic->GetElement( 0 ); + pElement->iFont = 1; + pElement->dwTextFormat = DT_TOP | DT_LEFT; + + // Timeout static text control + m_RevertModeDialog.AddStatic( DXUTSETTINGSDLG_STATIC_MODE_CHANGE_TIMEOUT, L"", 10, 90, 640, 30, + false, &pStatic ); + pElement = pStatic->GetElement( 0 ); + pElement->iFont = 0; + pElement->dwTextFormat = DT_TOP | DT_LEFT; + } + + // DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT, DXUTSETTINGSDLG_MODE_CHANGE_REVERT + m_RevertModeDialog.AddButton( DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT, L"Yes", 230, 50, 73, 31 ); + m_RevertModeDialog.AddButton( DXUTSETTINGSDLG_MODE_CHANGE_REVERT, L"No", 315, 50, 73, 31, 0, true ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice ) +{ + if( pd3dDevice == NULL ) + return DXUT_ERR_MSGBOX( L"CD3DSettingsDlg::OnCreatedDevice", E_INVALIDARG ); + + // Create the fonts/textures + m_Dialog.SetCallback( StaticOnEvent, ( void* )this ); + m_RevertModeDialog.SetCallback( StaticOnEvent, ( void* )this ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Changes the UI defaults to the current device settings +//-------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::Refresh() +{ + HRESULT hr = S_OK; + + g_DeviceSettings = DXUTGetDeviceSettings(); + + CDXUTComboBox* pAPIComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_API_VERSION ); + pAPIComboBox->RemoveAllItems(); + if( DXUTDoesAppSupportD3D9() ) + { + // Ensure that at least one adapter got enumerated. + CD3D9Enumeration* pD3DEnum = DXUTGetD3D9Enumeration(); + if( pD3DEnum->GetAdapterInfoList()->GetSize() > 0 ) + AddAPIVersion( DXUT_D3D9_DEVICE ); + } + if( DXUTDoesAppSupportD3D11() && DXUTIsD3D11Available() ) + { + // Ensure that at least one adapter got enumerated. + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + if( pD3DEnum->GetAdapterInfoList()->GetSize() > 0 ) + AddAPIVersion( DXUT_D3D11_DEVICE ); + } + + // If no API has been added, something has gone wrong. Exit the dialog. + if( pAPIComboBox->GetNumItems() == 0 ) + { + SetActive( false ); + return S_OK; + } + + pAPIComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.ver ) ); + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + // Show all D3D9-specific controls and hide controls for all other D3D versions. + ShowControlSet( DXUT_D3D9_DEVICE ); + + CD3D9Enumeration* pD3DEnum = DXUTGetD3D9Enumeration(); + + // Fill the UI with the current settings + AddDeviceType( g_DeviceSettings.d3d9.DeviceType ); + SetWindowed( FALSE != g_DeviceSettings.d3d9.pp.Windowed ); + SetDeviceClip( 0 != ( g_DeviceSettings.d3d9.pp.Flags & D3DPRESENTFLAG_DEVICECLIP ) ); + AddAdapterFormat( g_DeviceSettings.d3d9.AdapterFormat ); + AddResolution( g_DeviceSettings.d3d9.pp.BackBufferWidth, g_DeviceSettings.d3d9.pp.BackBufferHeight ); + AddRefreshRate( g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz ); + AddBackBufferFormat( g_DeviceSettings.d3d9.pp.BackBufferFormat ); + AddDepthStencilBufferFormat( g_DeviceSettings.d3d9.pp.AutoDepthStencilFormat ); + AddMultisampleType( g_DeviceSettings.d3d9.pp.MultiSampleType ); + AddMultisampleQuality( g_DeviceSettings.d3d9.pp.MultiSampleQuality ); + + if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_PUREDEVICE ) + AddVertexProcessingType( D3DCREATE_PUREDEVICE ); + else if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING ) + AddVertexProcessingType( D3DCREATE_HARDWARE_VERTEXPROCESSING ); + else if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING ) + AddVertexProcessingType( D3DCREATE_SOFTWARE_VERTEXPROCESSING ); + else if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING ) + AddVertexProcessingType( D3DCREATE_MIXED_VERTEXPROCESSING ); + + CD3D9EnumDeviceSettingsCombo* pBestDeviceSettingsCombo = pD3DEnum->GetDeviceSettingsCombo( + g_DeviceSettings.d3d9.AdapterOrdinal, g_DeviceSettings.d3d9.DeviceType, + g_DeviceSettings.d3d9.AdapterFormat, g_DeviceSettings.d3d9.pp.BackBufferFormat, + ( g_DeviceSettings.d3d9.pp.Windowed != 0 ) ); + if( NULL == pBestDeviceSettingsCombo ) + return DXUT_ERR_MSGBOX( L"GetDeviceSettingsCombo", E_INVALIDARG ); + + // Get the adapters list from CD3D9Enumeration object + CGrowableArray * pAdapterInfoList = pD3DEnum->GetAdapterInfoList(); + + if( pAdapterInfoList->GetSize() == 0 ) + return DXUT_ERR_MSGBOX( L"CD3DSettingsDlg::OnCreatedDevice", DXUTERR_NOCOMPATIBLEDEVICES ); + + CDXUTComboBox* pAdapterCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); + pAdapterCombo->RemoveAllItems(); + + // Add adapters + for( int iAdapter = 0; iAdapter < pAdapterInfoList->GetSize(); iAdapter++ ) + { + CD3D9EnumAdapterInfo* pAdapterInfo = pAdapterInfoList->GetAt( iAdapter ); + AddAdapter( pAdapterInfo->szUniqueDescription, pAdapterInfo->AdapterOrdinal ); + } + + pAdapterCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d9.AdapterOrdinal ) ); + + hr = OnAPIVersionChanged( true ); + if( FAILED( hr ) ) + return hr; + + //m_Dialog.Refresh(); + CDXUTDialog::SetRefreshTime( ( float )DXUTGetTime() ); + break; + } + case DXUT_D3D11_DEVICE: + { + // Show all D3D11-specific controls and hide controls for all other D3D versions. + ShowControlSet( DXUT_D3D11_DEVICE ); + + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + + // Fill the UI with the current settings + AddD3D11DeviceType( g_DeviceSettings.d3d11.DriverType ); + SetWindowed( FALSE != g_DeviceSettings.d3d11.sd.Windowed ); + CD3D11EnumOutputInfo* pOutputInfo = GetCurrentD3D11OutputInfo(); + AddD3D11AdapterOutput( pOutputInfo->Desc.DeviceName, g_DeviceSettings.d3d11.Output ); + + + + AddD3D11Resolution( g_DeviceSettings.d3d11.sd.BufferDesc.Width, + g_DeviceSettings.d3d11.sd.BufferDesc.Height ); + AddD3D11RefreshRate( g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate ); + AddD3D11BackBufferFormat( g_DeviceSettings.d3d11.sd.BufferDesc.Format ); + AddD3D11MultisampleCount( g_DeviceSettings.d3d11.sd.SampleDesc.Count ); + AddD3D11MultisampleQuality( g_DeviceSettings.d3d11.sd.SampleDesc.Quality ); + + CD3D11EnumDeviceSettingsCombo* pBestDeviceSettingsCombo = pD3DEnum->GetDeviceSettingsCombo( + g_DeviceSettings.d3d11.AdapterOrdinal, g_DeviceSettings.d3d11.DriverType, + g_DeviceSettings.d3d11.Output, g_DeviceSettings.d3d11.sd.BufferDesc.Format, + ( g_DeviceSettings.d3d11.sd.Windowed != 0 ) ); + + if( NULL == pBestDeviceSettingsCombo ) + return DXUT_ERR_MSGBOX( L"GetDeviceSettingsCombo", E_INVALIDARG ); + + CDXUTComboBox *pFeatureLevelBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL ); + pFeatureLevelBox->RemoveAllItems(); + for (int fli = 0; fli < TOTAL_FEATURE_LEVLES; fli++) { + if (m_Levels[fli] >= g_DeviceSettings.MinimumFeatureLevel + && m_Levels[fli] <=pBestDeviceSettingsCombo->pDeviceInfo->MaxLevel) { + AddD3D11FeatureLevel( m_Levels[fli] ); + } + } + pFeatureLevelBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.DeviceFeatureLevel ) ); + + + // Get the adapters list from CD3D11Enumeration object + CGrowableArray * pAdapterInfoList = pD3DEnum->GetAdapterInfoList(); + + if( pAdapterInfoList->GetSize() == 0 ) + return DXUT_ERR_MSGBOX( L"CD3DSettingsDlg::OnCreatedDevice", DXUTERR_NOCOMPATIBLEDEVICES ); + + CDXUTComboBox* pAdapterCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); + pAdapterCombo->RemoveAllItems(); + + // Add adapters + for( int iAdapter = 0; iAdapter < pAdapterInfoList->GetSize(); iAdapter++ ) + { + CD3D11EnumAdapterInfo* pAdapterInfo = pAdapterInfoList->GetAt( iAdapter ); + AddAdapter( pAdapterInfo->szUniqueDescription, pAdapterInfo->AdapterOrdinal ); + } + + pAdapterCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.AdapterOrdinal ) ); + + hr = OnAPIVersionChanged( true ); + if( FAILED( hr ) ) + return hr; + + //m_Dialog.Refresh(); + CDXUTDialog::SetRefreshTime( ( float )DXUTGetTime() ); + break; + } + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnD3D9ResetDevice() +{ + const D3DSURFACE_DESC* pDesc = DXUTGetD3D9BackBufferSurfaceDesc(); + m_Dialog.SetLocation( 0, 0 ); + m_Dialog.SetSize( pDesc->Width, pDesc->Height ); + m_Dialog.SetBackgroundColors( D3DCOLOR_ARGB( 255, 98, 138, 206 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 10, 73, 179 ) ); + + m_RevertModeDialog.SetLocation( 0, 0 ); + m_RevertModeDialog.SetSize( pDesc->Width, pDesc->Height ); + m_RevertModeDialog.SetBackgroundColors( D3DCOLOR_ARGB( 255, 98, 138, 206 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 10, 73, 179 ) ); + + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + pd3dDevice->BeginStateBlock(); + pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); + pd3dDevice->EndStateBlock( &m_pStateBlock ); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::SetSelectedD3D11RefreshRate( DXGI_RATIONAL RefreshRate ) +{ + CDXUTComboBox* pRefreshRateComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); + + for( UINT i = 0; i < pRefreshRateComboBox->GetNumItems(); ++i ) + { + DXGI_RATIONAL* pRate = ( DXGI_RATIONAL* )pRefreshRateComboBox->GetItemData( i ); + + if( pRate && pRate->Numerator == RefreshRate.Numerator && pRate->Denominator == RefreshRate.Denominator ) + { + pRefreshRateComboBox->SetSelectedByIndex( i ); + return; + } + } +} + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::OnRender( float fElapsedTime ) +{ + if( DXUTGetD3D11Device() ) + OnRender11( fElapsedTime ); + else + OnRender9( fElapsedTime ); +} + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::OnRender9( float fElapsedTime ) +{ + IDirect3DDevice9* pd3dDevice = DXUTGetD3D9Device(); + + // Clear the render target and the zbuffer + pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00003F3F, 1.0f, 0 ); + + // Render the scene + if( SUCCEEDED( pd3dDevice->BeginScene() ) ) + { + m_pStateBlock->Capture(); + pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); + m_pActiveDialog->OnRender( fElapsedTime ); + m_pStateBlock->Apply(); + pd3dDevice->EndScene(); + } +} + + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::OnRender11( float fElapsedTime ) +{ + // Render the scene + m_pActiveDialog->OnRender( fElapsedTime ); +} + + +//-------------------------------------------------------------------------------------- +LRESULT CD3DSettingsDlg::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + m_pActiveDialog->MsgProc( hWnd, uMsg, wParam, lParam ); + if( uMsg == WM_KEYDOWN && wParam == VK_F2 ) + SetActive( false ); + return 0; +} + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::OnD3D9LostDevice() +{ + SAFE_RELEASE( m_pStateBlock ); +} + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::OnD3D9DestroyDevice() +{ +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnD3D11CreateDevice( ID3D11Device* pd3dDevice ) +{ + //HRESULT hr; + + if( pd3dDevice == NULL ) + return DXUT_ERR_MSGBOX( L"CD3DSettingsDlg::OnCreatedDevice", E_INVALIDARG ); + + // Create the fonts/textures + m_Dialog.SetCallback( StaticOnEvent, ( void* )this ); + m_RevertModeDialog.SetCallback( StaticOnEvent, ( void* )this ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, + const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc ) +{ + m_Dialog.SetLocation( 0, 0 ); + m_Dialog.SetSize( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); + m_Dialog.SetBackgroundColors( D3DCOLOR_ARGB( 255, 98, 138, 206 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 10, 73, 179 ) ); + + m_RevertModeDialog.SetLocation( 0, 0 ); + m_RevertModeDialog.SetSize( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); + m_RevertModeDialog.SetBackgroundColors( D3DCOLOR_ARGB( 255, 98, 138, 206 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 54, 105, 192 ), + D3DCOLOR_ARGB( 255, 10, 73, 179 ) ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::OnD3D11DestroyDevice() +{ + + +} + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::ShowControlSet( DXUTDeviceVersion ver ) +{ + switch( ver ) + { + case DXUT_D3D9_DEVICE: + + m_Dialog.GetControl( DXUTSETTINGSDLG_ADAPTER_FORMAT )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_ADAPTER_FORMAT_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_RESOLUTION )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_RESOLUTION_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_REFRESH_RATE )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_REFRESH_RATE_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_DEPTH_STENCIL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_DEPTH_STENCIL_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_TYPE )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_TYPE_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_VERTEX_PROCESSING )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_VERTEX_PROCESSING_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_PRESENT_INTERVAL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_PRESENT_INTERVAL_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_DEVICECLIP )->SetVisible( true ); + + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_RESOLUTION )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_REFRESH_RATE )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE )->SetVisible( false ); + + break; + + case DXUT_D3D11_DEVICE: + m_Dialog.GetControl( DXUTSETTINGSDLG_ADAPTER_FORMAT )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_ADAPTER_FORMAT_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_RESOLUTION )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_RESOLUTION_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_REFRESH_RATE )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_REFRESH_RATE_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_DEPTH_STENCIL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_DEPTH_STENCIL_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_TYPE )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_TYPE_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_VERTEX_PROCESSING )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_VERTEX_PROCESSING_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_PRESENT_INTERVAL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_PRESENT_INTERVAL_LABEL )->SetVisible( false ); + m_Dialog.GetControl( DXUTSETTINGSDLG_DEVICECLIP )->SetVisible( false ); + + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_RESOLUTION )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_REFRESH_RATE )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL_LABEL )->SetVisible( true ); + m_Dialog.GetControl( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE )->SetVisible( true ); + break; + } +} + + +//-------------------------------------------------------------------------------------- +void WINAPI CD3DSettingsDlg::StaticOnEvent( UINT nEvent, int nControlID, + CDXUTControl* pControl, void* pUserData ) +{ + CD3DSettingsDlg* pD3DSettings = ( CD3DSettingsDlg* )pUserData; + if( pD3DSettings ) + pD3DSettings->OnEvent( nEvent, nControlID, pControl ); +} + +//-------------------------------------------------------------------------------------- +// Name: CD3DSettingsDlg::StaticOnModeChangeTimer() +// Desc: Timer callback registered by a call to DXUTSetTimer. It is called each second +// until mode change timeout limit. +//-------------------------------------------------------------------------------------- +void WINAPI CD3DSettingsDlg::StaticOnModeChangeTimer( UINT nIDEvent, void* pUserContext ) +{ + CD3DSettingsDlg* pD3DSettings = ( CD3DSettingsDlg* )pUserContext; + assert( pD3DSettings ); + assert( pD3DSettings->m_pActiveDialog == &pD3DSettings->m_RevertModeDialog ); + assert( pD3DSettings->m_nIDEvent == nIDEvent ); + + if( 0 == --pD3DSettings->m_nRevertModeTimeout ) + { + CDXUTControl* pControl = pD3DSettings->m_RevertModeDialog.GetControl( DXUTSETTINGSDLG_MODE_CHANGE_REVERT ); + assert( pControl ); + pD3DSettings->m_RevertModeDialog.SendEvent( EVENT_BUTTON_CLICKED, false, pControl ); + } + pD3DSettings->UpdateModeChangeTimeoutText( pD3DSettings->m_nRevertModeTimeout ); +} + +//-------------------------------------------------------------------------------------- +void CD3DSettingsDlg::OnEvent( UINT nEvent, int nControlID, + CDXUTControl* pControl ) +{ + switch( nControlID ) + { + case DXUTSETTINGSDLG_ADAPTER: + OnAdapterChanged(); break; + case DXUTSETTINGSDLG_DEVICE_TYPE: + OnDeviceTypeChanged(); break; + case DXUTSETTINGSDLG_WINDOWED: + OnWindowedFullScreenChanged(); break; + case DXUTSETTINGSDLG_FULLSCREEN: + OnWindowedFullScreenChanged(); break; + case DXUTSETTINGSDLG_ADAPTER_FORMAT: + OnAdapterFormatChanged(); break; + case DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL: + { + if( g_DeviceSettings.ver == DXUT_D3D9_DEVICE ) + { + OnAdapterFormatChanged(); + } + else + { + OnBackBufferFormatChanged(); + } + break; + } + case DXUTSETTINGSDLG_D3D11_RESOLUTION: + OnD3D11ResolutionChanged(); break; + case DXUTSETTINGSDLG_RESOLUTION: + OnResolutionChanged(); break; + case DXUTSETTINGSDLG_REFRESH_RATE: + OnRefreshRateChanged(); break; + case DXUTSETTINGSDLG_BACK_BUFFER_FORMAT: + OnBackBufferFormatChanged(); break; + case DXUTSETTINGSDLG_DEPTH_STENCIL: + OnDepthStencilBufferFormatChanged(); break; + case DXUTSETTINGSDLG_MULTISAMPLE_TYPE: + OnMultisampleTypeChanged(); break; + case DXUTSETTINGSDLG_MULTISAMPLE_QUALITY: + OnMultisampleQualityChanged(); break; + case DXUTSETTINGSDLG_VERTEX_PROCESSING: + OnVertexProcessingChanged(); break; + case DXUTSETTINGSDLG_PRESENT_INTERVAL: + OnPresentIntervalChanged(); break; + case DXUTSETTINGSDLG_DEVICECLIP: + OnDeviceClipChanged(); break; + case DXUTSETTINGSDLG_API_VERSION: + OnAPIVersionChanged(); break; + case DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL: + OnFeatureLevelChanged(); break; + case DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT: + OnAdapterOutputChanged(); break; + case DXUTSETTINGSDLG_D3D11_REFRESH_RATE: + OnRefreshRateChanged(); break; + case DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT: + OnBackBufferFormatChanged(); break; + case DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT: + OnMultisampleTypeChanged(); break; + case DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY: + OnMultisampleQualityChanged(); break; + case DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL: + OnPresentIntervalChanged(); break; + case DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE: + OnDebugDeviceChanged(); break; + + case DXUTSETTINGSDLG_OK: + { + bool bFullScreenModeChange = false; + DXUTDeviceSettings currentSettings = DXUTGetDeviceSettings(); + g_DeviceSettings.MinimumFeatureLevel = currentSettings.MinimumFeatureLevel; + if( g_DeviceSettings.ver == DXUT_D3D9_DEVICE ) + { + if( g_DeviceSettings.d3d9.pp.Windowed ) + { + g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz = 0; + + RECT rcClient; + if( DXUTIsWindowed() ) + GetClientRect( DXUTGetHWND(), &rcClient ); + else + rcClient = DXUTGetWindowClientRectAtModeChange(); + DWORD dwWindowWidth = rcClient.right - rcClient.left; + DWORD dwWindowHeight = rcClient.bottom - rcClient.top; + + g_DeviceSettings.d3d9.pp.BackBufferWidth = dwWindowWidth; + g_DeviceSettings.d3d9.pp.BackBufferHeight = dwWindowHeight; + } + else + { + // Check for fullscreen mode change + bFullScreenModeChange = g_DeviceSettings.d3d9.pp.BackBufferWidth != + currentSettings.d3d9.pp.BackBufferWidth || + g_DeviceSettings.d3d9.pp.BackBufferHeight != currentSettings.d3d9.pp.BackBufferHeight || + g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz != + currentSettings.d3d9.pp.FullScreen_RefreshRateInHz; + } + + if( g_DeviceSettings.d3d9.pp.MultiSampleType != D3DMULTISAMPLE_NONE ) + { + g_DeviceSettings.d3d9.pp.Flags &= ~D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + } + } + else // D3D11 + { + if( g_DeviceSettings.d3d11.sd.Windowed ) + { + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator = + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator = 0; + + RECT rcClient; + if( DXUTIsWindowed() ) + GetClientRect( DXUTGetHWND(), &rcClient ); + else + rcClient = DXUTGetWindowClientRectAtModeChange(); + DWORD dwWindowWidth = rcClient.right - rcClient.left; + DWORD dwWindowHeight = rcClient.bottom - rcClient.top; + + g_DeviceSettings.d3d11.sd.BufferDesc.Width = dwWindowWidth; + g_DeviceSettings.d3d11.sd.BufferDesc.Height = dwWindowHeight; + } + else + { + // Check for fullscreen mode change + bFullScreenModeChange = g_DeviceSettings.d3d11.sd.BufferDesc.Width != + currentSettings.d3d11.sd.BufferDesc.Width || + g_DeviceSettings.d3d11.sd.BufferDesc.Height != currentSettings.d3d11.sd.BufferDesc.Height || + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator != + currentSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator || + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator != + currentSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator; + } + } + + if( bFullScreenModeChange ) + { + // set appropriate global device settings to that of the current device + // settings. These will get set to the user-defined settings once the + // user accepts the mode change + DXUTDeviceSettings tSettings = g_DeviceSettings; + if( g_DeviceSettings.ver == DXUT_D3D9_DEVICE ) + { + g_DeviceSettings.d3d9.pp.BackBufferWidth = + currentSettings.d3d9.pp.BackBufferWidth; + g_DeviceSettings.d3d9.pp.BackBufferHeight = + currentSettings.d3d9.pp.BackBufferHeight; + g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz = + currentSettings.d3d9.pp.FullScreen_RefreshRateInHz; + g_DeviceSettings.d3d9.pp.Windowed = + currentSettings.d3d9.pp.Windowed; + } + else + { + + g_DeviceSettings.d3d11.sd.BufferDesc.Width = + currentSettings.d3d11.sd.BufferDesc.Width; + g_DeviceSettings.d3d11.sd.BufferDesc.Height = + currentSettings.d3d11.sd.BufferDesc.Height; + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator = + currentSettings.d3d11.sd.BufferDesc.RefreshRate.Denominator; + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator = + currentSettings.d3d11.sd.BufferDesc.RefreshRate.Numerator; + g_DeviceSettings.d3d11.sd.Windowed = currentSettings.d3d11.sd.Windowed; + + } + + // apply the user-defined settings + DXUTCreateDeviceFromSettings( &tSettings ); + // create the mode change timeout dialog + m_pActiveDialog = &m_RevertModeDialog; + m_nRevertModeTimeout = 15; + UpdateModeChangeTimeoutText( m_nRevertModeTimeout ); + // activate a timer for 1-second updates + DXUTSetTimer( StaticOnModeChangeTimer, 1.0f, &m_nIDEvent, ( void* )this ); + } + else + { + DXUTCreateDeviceFromSettings( &g_DeviceSettings ); + SetActive( false ); + } + break; + } + + case DXUTSETTINGSDLG_CANCEL: + { + SetActive( false ); + break; + } + + case DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT: + { + DXUTKillTimer( m_nIDEvent ); + g_DeviceSettings = DXUTGetDeviceSettings(); + m_pActiveDialog = &m_Dialog; + SetActive( false ); + break; + } + + case DXUTSETTINGSDLG_MODE_CHANGE_REVERT: + { + DXUTKillTimer( m_nIDEvent ); + m_pActiveDialog = &m_Dialog; + m_nIDEvent = 0; + m_nRevertModeTimeout = 0; + DXUTCreateDeviceFromSettings( &g_DeviceSettings ); + Refresh(); + break; + } + } +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::SetDeviceSettingsFromUI() +{ + CDXUTComboBox* pComboBox; + CDXUTRadioButton* pRadioButton; + + // DXUTSETTINGSDLG_DEVICE_TYPE + pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); + g_DeviceSettings.d3d9.DeviceType = ( D3DDEVTYPE )PtrToUlong( pComboBox->GetSelectedData() ); + + // DXUTSETTINGSDLG_WINDOWED + pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED ); + g_DeviceSettings.d3d9.pp.Windowed = pRadioButton->GetChecked(); + + // DXUTSETTINGSDLG_ADAPTER_FORMAT + pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT ); + g_DeviceSettings.d3d9.AdapterFormat = ( D3DFORMAT )PtrToUlong( pComboBox->GetSelectedData() ); + + if( g_DeviceSettings.d3d9.pp.Windowed ) + { + g_DeviceSettings.d3d9.pp.BackBufferFormat = D3DFMT_UNKNOWN; + g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz = 0; + } + else + { + // DXUTSETTINGSDLG_BACK_BUFFER_FORMAT + pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT ); + g_DeviceSettings.d3d9.pp.BackBufferFormat = ( D3DFORMAT )PtrToUlong( pComboBox->GetSelectedData() ); + + // DXUTSETTINGSDLG_RESOLUTION + pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION ); + DWORD dwResolution = PtrToUlong( pComboBox->GetSelectedData() ); + g_DeviceSettings.d3d9.pp.BackBufferWidth = HIWORD( dwResolution ); + g_DeviceSettings.d3d9.pp.BackBufferHeight = LOWORD( dwResolution ); + + // DXUTSETTINGSDLG_REFRESH_RATE + pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE ); + g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz = PtrToUlong( pComboBox->GetSelectedData() ); + } + + // DXUTSETTINGSDLG_DEPTH_STENCIL + pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL ); + g_DeviceSettings.d3d9.pp.AutoDepthStencilFormat = ( D3DFORMAT )PtrToUlong( pComboBox->GetSelectedData() ); + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +CD3D9EnumAdapterInfo* CD3DSettingsDlg::GetCurrentAdapterInfo() +{ + CD3D9Enumeration* pD3DEnum = DXUTGetD3D9Enumeration(); + return pD3DEnum->GetAdapterInfo( g_DeviceSettings.d3d9.AdapterOrdinal ); +} + + +//------------------------------------------------------------------------------------- +CD3D9EnumDeviceInfo* CD3DSettingsDlg::GetCurrentDeviceInfo() +{ + CD3D9Enumeration* pD3DEnum = DXUTGetD3D9Enumeration(); + return pD3DEnum->GetDeviceInfo( g_DeviceSettings.d3d9.AdapterOrdinal, + g_DeviceSettings.d3d9.DeviceType ); +} + +//------------------------------------------------------------------------------------- +CD3D11EnumAdapterInfo* CD3DSettingsDlg::GetCurrentD3D11AdapterInfo() +{ + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + return pD3DEnum->GetAdapterInfo( g_DeviceSettings.d3d11.AdapterOrdinal ); +} + + +//------------------------------------------------------------------------------------- +CD3D11EnumDeviceInfo* CD3DSettingsDlg::GetCurrentD3D11DeviceInfo() +{ + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + return pD3DEnum->GetDeviceInfo( g_DeviceSettings.d3d11.AdapterOrdinal, + g_DeviceSettings.d3d11.DriverType ); +} + + +//------------------------------------------------------------------------------------- +CD3D11EnumOutputInfo* CD3DSettingsDlg::GetCurrentD3D11OutputInfo() +{ + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + return pD3DEnum->GetOutputInfo( g_DeviceSettings.d3d11.AdapterOrdinal, + g_DeviceSettings.d3d11.Output ); +} + + +//------------------------------------------------------------------------------------- +CD3D9EnumDeviceSettingsCombo* CD3DSettingsDlg::GetCurrentDeviceSettingsCombo() +{ + CD3D9Enumeration* pD3DEnum = DXUTGetD3D9Enumeration(); + return pD3DEnum->GetDeviceSettingsCombo( g_DeviceSettings.d3d9.AdapterOrdinal, + g_DeviceSettings.d3d9.DeviceType, + g_DeviceSettings.d3d9.AdapterFormat, + g_DeviceSettings.d3d9.pp.BackBufferFormat, + ( g_DeviceSettings.d3d9.pp.Windowed == TRUE ) ); +} + +//------------------------------------------------------------------------------------- +CD3D11EnumDeviceSettingsCombo* CD3DSettingsDlg::GetCurrentD3D11DeviceSettingsCombo() +{ + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + return pD3DEnum->GetDeviceSettingsCombo( g_DeviceSettings.d3d11.AdapterOrdinal, + g_DeviceSettings.d3d11.DriverType, + g_DeviceSettings.d3d11.Output, + g_DeviceSettings.d3d11.sd.BufferDesc.Format, + ( g_DeviceSettings.d3d11.sd.Windowed == TRUE ) ); +} + +HRESULT CD3DSettingsDlg::OnD3D11ResolutionChanged () { + DWORD dwWidth, dwHeight; + GetSelectedD3D11Resolution( &dwWidth, &dwHeight ); + g_DeviceSettings.d3d11.sd.BufferDesc.Width= dwWidth; + g_DeviceSettings.d3d11.sd.BufferDesc.Height = dwHeight; + + return S_OK; +} + +HRESULT CD3DSettingsDlg::OnFeatureLevelChanged () { + HRESULT hr = E_FAIL; + if (g_DeviceSettings.ver == DXUT_D3D11_DEVICE) { + if (g_DeviceSettings.d3d11.DeviceFeatureLevel == GetSelectedFeatureLevel()) return S_OK; + //if( !bRefresh ) + //{ + // Obtain a set of valid D3D10 device settings. + UINT CreateFlags = g_DeviceSettings.d3d11.CreateFlags; + ZeroMemory( &g_DeviceSettings, sizeof( g_DeviceSettings ) ); + + DXUTApplyDefaultDeviceSettings(&g_DeviceSettings); + g_DeviceSettings.d3d11.CreateFlags = CreateFlags; + g_DeviceSettings.ver = DXUT_D3D11_DEVICE; + //g_DeviceSettings.d3d11.fl = GetSelectedFeatureLevel(); + hr = DXUTSnapDeviceSettingsToEnumDevice(&g_DeviceSettings, true, GetSelectedFeatureLevel()); + + //} + + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + CGrowableArray * pAdapterInfoList = pD3DEnum->GetAdapterInfoList(); + + CDXUTComboBox* pAdapterComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); + pAdapterComboBox->RemoveAllItems(); + + for( int iAdapter = 0; iAdapter < pAdapterInfoList->GetSize(); ++iAdapter ) + { + CD3D11EnumAdapterInfo* pAdapterInfo = pAdapterInfoList->GetAt( iAdapter ); + AddAdapter( pAdapterInfo->szUniqueDescription, pAdapterInfo->AdapterOrdinal ); + } + + pAdapterComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.AdapterOrdinal ) ); + + CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE ); + pCheckBox->SetChecked( 0 != ( g_DeviceSettings.d3d11.CreateFlags & D3D11_CREATE_DEVICE_DEBUG ) ); + + hr = OnAdapterChanged(); + if( FAILED( hr ) ) + return hr; + } + + return hr; +} + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnAPIVersionChanged( bool bRefresh ) +{ + HRESULT hr; + + // Store the API version + g_DeviceSettings.ver = GetSelectedAPIVersion(); + + // Show/hide appropriate dialog controls based on version. + ShowControlSet( g_DeviceSettings.ver ); + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + if( !bRefresh ) + { + // Obtain a set of valid D3D9 device settings. + UINT CreateFlags = g_DeviceSettings.d3d11.CreateFlags; + ZeroMemory( &g_DeviceSettings, sizeof( g_DeviceSettings ) ); + // We want a specific API version, so set up match option to preserve it. + DXUTApplyDefaultDeviceSettings(&g_DeviceSettings); + g_DeviceSettings.d3d11.CreateFlags = CreateFlags; + g_DeviceSettings.ver = DXUT_D3D9_DEVICE; + DXUTSnapDeviceSettingsToEnumDevice ( &g_DeviceSettings, true); + } + + CD3D9Enumeration* pD3DEnum = DXUTGetD3D9Enumeration(); + CGrowableArray * pAdapterInfoList = pD3DEnum->GetAdapterInfoList(); + + CDXUTComboBox* pAdapterComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); + pAdapterComboBox->RemoveAllItems(); + + for( int iAdapter = 0; iAdapter < pAdapterInfoList->GetSize(); ++iAdapter ) + { + CD3D9EnumAdapterInfo* pAdapterInfo = pAdapterInfoList->GetAt( iAdapter ); + AddAdapter( pAdapterInfo->szUniqueDescription, pAdapterInfo->AdapterOrdinal ); + } + + pAdapterComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d9.AdapterOrdinal ) ); + + hr = OnAdapterChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + + case DXUT_D3D11_DEVICE: + { + if( !bRefresh ) + { + // Obtain a set of valid D3D10 device settings. + UINT CreateFlags = g_DeviceSettings.d3d11.CreateFlags; + ZeroMemory( &g_DeviceSettings, sizeof( g_DeviceSettings ) ); + // We want a specific API version, so set up match option to preserve it. + DXUTApplyDefaultDeviceSettings(&g_DeviceSettings); + g_DeviceSettings.d3d11.CreateFlags = CreateFlags; + g_DeviceSettings.ver = DXUT_D3D11_DEVICE; + DXUTSnapDeviceSettingsToEnumDevice(&g_DeviceSettings, true); + + } + + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + CGrowableArray * pAdapterInfoList = pD3DEnum->GetAdapterInfoList(); + + CDXUTComboBox* pAdapterComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); + pAdapterComboBox->RemoveAllItems(); + + for( int iAdapter = 0; iAdapter < pAdapterInfoList->GetSize(); ++iAdapter ) + { + CD3D11EnumAdapterInfo* pAdapterInfo = pAdapterInfoList->GetAt( iAdapter ); + AddAdapter( pAdapterInfo->szUniqueDescription, pAdapterInfo->AdapterOrdinal ); + } + + pAdapterComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.AdapterOrdinal ) ); + + CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE ); + pCheckBox->SetChecked( 0 != ( g_DeviceSettings.d3d11.CreateFlags & D3D11_CREATE_DEVICE_DEBUG ) ); + + hr = OnAdapterChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnAdapterChanged() +{ + HRESULT hr = S_OK; + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + // Store the adapter index + g_DeviceSettings.d3d9.AdapterOrdinal = GetSelectedAdapter(); + + // DXUTSETTINGSDLG_DEVICE_TYPE + CDXUTComboBox* pDeviceTypeComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); + pDeviceTypeComboBox->RemoveAllItems(); + + CD3D9EnumAdapterInfo* pAdapterInfo = GetCurrentAdapterInfo(); + if( pAdapterInfo == NULL ) + return E_FAIL; + + for( int iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ ) + { + CD3D9EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( iDeviceInfo ); + AddDeviceType( pDeviceInfo->DeviceType ); + } + + pDeviceTypeComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d9.DeviceType ) ); + + hr = OnDeviceTypeChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + + case DXUT_D3D11_DEVICE: + { + // Store the adapter index + g_DeviceSettings.d3d11.AdapterOrdinal = GetSelectedAdapter(); + + // DXUTSETTINGSDLG_DEVICE_TYPE + CDXUTComboBox* pDeviceTypeComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); + pDeviceTypeComboBox->RemoveAllItems(); + + CD3D11EnumAdapterInfo* pAdapterInfo = GetCurrentD3D11AdapterInfo(); + if( pAdapterInfo == NULL ) + return E_FAIL; + + for( int iDeviceInfo = 0; iDeviceInfo < pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ ) + { + CD3D11EnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt( iDeviceInfo ); + AddD3D11DeviceType( pDeviceInfo->DeviceType ); + } + + pDeviceTypeComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.DriverType ) ); + + hr = OnDeviceTypeChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + } + + return S_OK; +} + + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnDeviceTypeChanged() +{ + HRESULT hr = S_OK; + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + g_DeviceSettings.d3d9.DeviceType = GetSelectedDeviceType(); + + // Update windowed/full screen radio buttons + bool bHasWindowedDeviceCombo = false; + bool bHasFullScreenDeviceCombo = false; + + CD3D9EnumDeviceInfo* pDeviceInfo = GetCurrentDeviceInfo(); + if( pDeviceInfo == NULL ) + return E_FAIL; + + for( int idc = 0; idc < pDeviceInfo->deviceSettingsComboList.GetSize(); idc++ ) + { + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt( idc ); + + if( pDeviceSettingsCombo->Windowed ) + bHasWindowedDeviceCombo = true; + else + bHasFullScreenDeviceCombo = true; + } + + // DXUTSETTINGSDLG_WINDOWED, DXUTSETTINGSDLG_FULLSCREEN + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_WINDOWED, bHasWindowedDeviceCombo ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_FULLSCREEN, bHasFullScreenDeviceCombo ); + + SetWindowed( g_DeviceSettings.d3d9.pp.Windowed && bHasWindowedDeviceCombo ); + + hr = OnWindowedFullScreenChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + case DXUT_D3D11_DEVICE: + { + g_DeviceSettings.d3d11.DriverType = GetSelectedD3D11DeviceType(); + + // DXUTSETTINGSDLG_WINDOWED, DXUTSETTINGSDLG_FULLSCREEN + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_WINDOWED, true ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_FULLSCREEN, true ); + + SetWindowed( g_DeviceSettings.d3d11.sd.Windowed != 0 ); + + hr = OnWindowedFullScreenChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + } + + return S_OK; +} + + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnWindowedFullScreenChanged() +{ + HRESULT hr = S_OK; + bool bWindowed = IsWindowed(); + + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_ADAPTER_FORMAT_LABEL, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_RESOLUTION_LABEL, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_REFRESH_RATE_LABEL, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL, !bWindowed ); + + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_ADAPTER_FORMAT, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_RESOLUTION, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_REFRESH_RATE, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_DEVICECLIP, bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_RESOLUTION, !bWindowed ); + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_D3D11_REFRESH_RATE, !bWindowed ); + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + g_DeviceSettings.d3d9.pp.Windowed = bWindowed; + bool bDeviceClip = ( 0x0 != ( g_DeviceSettings.d3d9.pp.Flags & D3DPRESENTFLAG_DEVICECLIP ) ); + + // If windowed, get the appropriate adapter format from Direct3D + if( g_DeviceSettings.d3d9.pp.Windowed ) + { + IDirect3D9* pD3D = DXUTGetD3D9Object(); + if( pD3D == NULL ) + return DXTRACE_ERR( L"DXUTGetD3DObject", E_FAIL ); + + D3DDISPLAYMODE mode; + hr = pD3D->GetAdapterDisplayMode( g_DeviceSettings.d3d9.AdapterOrdinal, &mode ); + if( FAILED( hr ) ) + return DXTRACE_ERR( L"GetAdapterDisplayMode", hr ); + + // Default resolution to the fullscreen res that was last used + RECT rc = DXUTGetFullsceenClientRectAtModeChange(); + if( rc.right == 0 || rc.bottom == 0 ) + { + // If nothing last used, then default to the adapter desktop res + g_DeviceSettings.d3d9.pp.BackBufferWidth = mode.Width; + g_DeviceSettings.d3d9.pp.BackBufferHeight = mode.Height; + } + else + { + g_DeviceSettings.d3d9.pp.BackBufferWidth = rc.right; + g_DeviceSettings.d3d9.pp.BackBufferHeight = rc.bottom; + } + + g_DeviceSettings.d3d9.AdapterFormat = mode.Format; + g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz = mode.RefreshRate; + } + + const D3DFORMAT adapterFormat = g_DeviceSettings.d3d9.AdapterFormat; + const DWORD dwWidth = g_DeviceSettings.d3d9.pp.BackBufferWidth; + const DWORD dwHeight = g_DeviceSettings.d3d9.pp.BackBufferHeight; + const DWORD dwRefreshRate = g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz; + + // DXUTSETTINGSDLG_DEVICECLIP + SetDeviceClip( bDeviceClip ); + + // DXUTSETTINGSDLG_ADAPTER_FORMAT + CDXUTComboBox* pAdapterFormatComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT ); + if( pAdapterFormatComboBox == NULL ) + return E_FAIL; + pAdapterFormatComboBox->RemoveAllItems(); + + CD3D9EnumDeviceInfo* pDeviceInfo = GetCurrentDeviceInfo(); + if( pDeviceInfo == NULL ) + return E_FAIL; + + if( bWindowed ) + { + AddAdapterFormat( adapterFormat ); + } + else + { + for( int iSettingsCombo = 0; iSettingsCombo < pDeviceInfo->deviceSettingsComboList.GetSize(); + iSettingsCombo++ ) + { + CD3D9EnumDeviceSettingsCombo* pSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt( + iSettingsCombo ); + AddAdapterFormat( pSettingsCombo->AdapterFormat ); + } + } + + pAdapterFormatComboBox->SetSelectedByData( ULongToPtr( adapterFormat ) ); + + hr = OnAdapterFormatChanged(); + if( FAILED( hr ) ) + return hr; + + // DXUTSETTINGSDLG_RESOLUTION + CDXUTComboBox* pResolutionComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION ); + + if( bWindowed ) + { + pResolutionComboBox->RemoveAllItems(); + AddResolution( dwWidth, dwHeight ); + } + + pResolutionComboBox->SetSelectedByData( ULongToPtr( MAKELONG( dwWidth, dwHeight ) ) ); + + hr = OnResolutionChanged(); + if( FAILED( hr ) ) + return hr; + + // DXUTSETTINGSDLG_REFRESH_RATE + CDXUTComboBox* pRefreshRateComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE ); + + if( bWindowed ) + { + pRefreshRateComboBox->RemoveAllItems(); + AddRefreshRate( dwRefreshRate ); + } + + pRefreshRateComboBox->SetSelectedByData( ULongToPtr( dwRefreshRate ) ); + + hr = OnRefreshRateChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + + case DXUT_D3D11_DEVICE: + { + g_DeviceSettings.d3d11.sd.Windowed = bWindowed; + + // Get available adapter output + CD3D11Enumeration* pD3DEnum = DXUTGetD3D11Enumeration(); + + CDXUTComboBox* pOutputComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT ); + pOutputComboBox->RemoveAllItems(); + + CD3D11EnumAdapterInfo* pAdapterInfo = pD3DEnum->GetAdapterInfo( g_DeviceSettings.d3d11.AdapterOrdinal ); + for( int ioutput = 0; ioutput < pAdapterInfo->outputInfoList.GetSize(); ++ioutput ) + { + CD3D11EnumOutputInfo* pOutputInfo = pAdapterInfo->outputInfoList.GetAt( ioutput ); + AddD3D11AdapterOutput( pOutputInfo->Desc.DeviceName, pOutputInfo->Output ); + } + + pOutputComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.Output ) ); + + hr = OnAdapterOutputChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnAdapterOutputChanged() +{ + HRESULT hr; + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D11_DEVICE: + { + bool bWindowed = IsWindowed(); + g_DeviceSettings.d3d11.sd.Windowed = bWindowed; + + // If windowed, get the appropriate adapter format from Direct3D + if( g_DeviceSettings.d3d11.sd.Windowed ) + { + DXGI_MODE_DESC mode; + hr = DXUTGetD3D11AdapterDisplayMode( g_DeviceSettings.d3d11.AdapterOrdinal, + g_DeviceSettings.d3d11.Output, &mode ); + if( FAILED( hr ) ) + return DXTRACE_ERR( L"GetD3D11AdapterDisplayMode", hr ); + + // Default resolution to the fullscreen res that was last used + RECT rc = DXUTGetFullsceenClientRectAtModeChange(); + if( rc.right == 0 || rc.bottom == 0 ) + { + // If nothing last used, then default to the adapter desktop res + g_DeviceSettings.d3d11.sd.BufferDesc.Width = mode.Width; + g_DeviceSettings.d3d11.sd.BufferDesc.Height = mode.Height; + } + else + { + g_DeviceSettings.d3d11.sd.BufferDesc.Width = rc.right; + g_DeviceSettings.d3d11.sd.BufferDesc.Height = rc.bottom; + } + + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate = mode.RefreshRate; + } + + const DXGI_RATIONAL RefreshRate = g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate; + + CD3D11EnumAdapterInfo* pAdapterInfo = GetCurrentD3D11AdapterInfo(); + if( pAdapterInfo == NULL ) + return E_FAIL; + + // DXUTSETTINGSDLG_D3D11_RESOLUTION + hr = UpdateD3D11Resolutions(); + if( FAILED( hr ) ) + return hr; + + // DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT + CDXUTComboBox* pBackBufferFormatComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT + ); + pBackBufferFormatComboBox->RemoveAllItems(); + + for( int idc = 0; idc < pAdapterInfo->deviceSettingsComboList.GetSize(); idc++ ) + { + CD3D11EnumDeviceSettingsCombo* pDeviceCombo = pAdapterInfo->deviceSettingsComboList.GetAt( idc ); + if( ( pDeviceCombo->Windowed == TRUE ) == bWindowed ) + { + AddD3D11BackBufferFormat( pDeviceCombo->BackBufferFormat ); + } + } + + pBackBufferFormatComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.sd.BufferDesc.Format ) ); + + hr = OnBackBufferFormatChanged(); + if( FAILED( hr ) ) + return hr; + + // DXUTSETTINGSDLG_D3D11_REFRESH_RATE + if( bWindowed ) + { + CDXUTComboBox* pRefreshRateComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); + for( UINT i = 0; i < pRefreshRateComboBox->GetNumItems(); ++i ) + { + DXGI_RATIONAL* pRefreshRate = reinterpret_cast( + pRefreshRateComboBox->GetItemData( i ) ); + delete pRefreshRate; + } + pRefreshRateComboBox->RemoveAllItems(); + AddD3D11RefreshRate( RefreshRate ); + } + + SetSelectedD3D11RefreshRate( RefreshRate ); + break; + } + }; + + hr = OnRefreshRateChanged(); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnAdapterFormatChanged() +{ + HRESULT hr = S_OK; + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + // DXUTSETTINGSDLG_ADAPTER_FORMAT + D3DFORMAT adapterFormat = GetSelectedAdapterFormat(); + g_DeviceSettings.d3d9.AdapterFormat = adapterFormat; + + // DXUTSETTINGSDLG_RESOLUTION + CDXUTComboBox* pResolutionComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION ); + pResolutionComboBox->RemoveAllItems(); + + CD3D9EnumAdapterInfo* pAdapterInfo = GetCurrentAdapterInfo(); + if( pAdapterInfo == NULL ) + return E_FAIL; + + bool bShowAll = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL )->GetChecked(); + + // Get the desktop aspect ratio + D3DDISPLAYMODE dmDesktop; + DXUTGetDesktopResolution( g_DeviceSettings.d3d9.AdapterOrdinal, &dmDesktop.Width, &dmDesktop.Height ); + float fDesktopAspectRatio = dmDesktop.Width / ( float )dmDesktop.Height; + + for( int idm = 0; idm < pAdapterInfo->displayModeList.GetSize(); idm++ ) + { + D3DDISPLAYMODE DisplayMode = pAdapterInfo->displayModeList.GetAt( idm ); + float fAspect = ( float )DisplayMode.Width / ( float )DisplayMode.Height; + + if( DisplayMode.Format == g_DeviceSettings.d3d9.AdapterFormat ) + { + // If "Show All" is not checked, then hide all resolutions + // that don't match the aspect ratio of the desktop resolution + if( bShowAll || ( !bShowAll && fabsf( fDesktopAspectRatio - fAspect ) < 0.05f ) ) + { + AddResolution( DisplayMode.Width, DisplayMode.Height ); + } + } + } + + const DWORD dwCurResolution = MAKELONG( g_DeviceSettings.d3d9.pp.BackBufferWidth, + g_DeviceSettings.d3d9.pp.BackBufferHeight ); + + pResolutionComboBox->SetSelectedByData( ULongToPtr( dwCurResolution ) ); + + hr = OnResolutionChanged(); + if( FAILED( hr ) ) + return hr; + + // DXUTSETTINGSDLG_BACK_BUFFER_FORMAT + CDXUTComboBox* pBackBufferFormatComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT ); + pBackBufferFormatComboBox->RemoveAllItems(); + + CD3D9EnumDeviceInfo* pDeviceInfo = GetCurrentDeviceInfo(); + if( pDeviceInfo == NULL ) + return E_FAIL; + + const BOOL bWindowed = IsWindowed(); + bool bHasWindowedBackBuffer = false; + + for( int idc = 0; idc < pDeviceInfo->deviceSettingsComboList.GetSize(); idc++ ) + { + CD3D9EnumDeviceSettingsCombo* pDeviceCombo = pDeviceInfo->deviceSettingsComboList.GetAt( idc ); + if( pDeviceCombo->Windowed == bWindowed && + pDeviceCombo->AdapterFormat == g_DeviceSettings.d3d9.AdapterFormat ) + { + AddBackBufferFormat( pDeviceCombo->BackBufferFormat ); + bHasWindowedBackBuffer = true; + } + } + + pBackBufferFormatComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d9.pp.BackBufferFormat ) ); + + hr = OnBackBufferFormatChanged(); + if( FAILED( hr ) ) + return hr; + + if( !bHasWindowedBackBuffer ) + { + m_Dialog.SetControlEnabled( DXUTSETTINGSDLG_WINDOWED, false ); + + if( g_DeviceSettings.d3d9.pp.Windowed ) + { + SetWindowed( false ); + + hr = OnWindowedFullScreenChanged(); + if( FAILED( hr ) ) + return hr; + } + } + + break; + } + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnResolutionChanged() +{ + HRESULT hr = S_OK; + + CD3D9EnumAdapterInfo* pAdapterInfo = GetCurrentAdapterInfo(); + if( pAdapterInfo == NULL ) + return E_FAIL; + + // Set resolution + DWORD dwWidth, dwHeight; + GetSelectedResolution( &dwWidth, &dwHeight ); + g_DeviceSettings.d3d9.pp.BackBufferWidth = dwWidth; + g_DeviceSettings.d3d9.pp.BackBufferHeight = dwHeight; + + DWORD dwRefreshRate = g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz; + + // Update the refresh rate list + CDXUTComboBox* pRefreshRateComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE ); + pRefreshRateComboBox->RemoveAllItems(); + + D3DFORMAT adapterFormat = g_DeviceSettings.d3d9.AdapterFormat; + for( int idm = 0; idm < pAdapterInfo->displayModeList.GetSize(); idm++ ) + { + D3DDISPLAYMODE displayMode = pAdapterInfo->displayModeList.GetAt( idm ); + + if( displayMode.Format == adapterFormat && + displayMode.Width == dwWidth && + displayMode.Height == dwHeight ) + { + AddRefreshRate( displayMode.RefreshRate ); + } + } + + pRefreshRateComboBox->SetSelectedByData( ULongToPtr( dwRefreshRate ) ); + + hr = OnRefreshRateChanged(); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnRefreshRateChanged() +{ + // Set refresh rate + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + g_DeviceSettings.d3d9.pp.FullScreen_RefreshRateInHz = GetSelectedRefreshRate(); + break; + + case DXUT_D3D11_DEVICE: + g_DeviceSettings.d3d11.sd.BufferDesc.RefreshRate = GetSelectedD3D11RefreshRate(); + break; + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnBackBufferFormatChanged() +{ + HRESULT hr = S_OK; + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + g_DeviceSettings.d3d9.pp.BackBufferFormat = GetSelectedBackBufferFormat(); + + D3DFORMAT adapterFormat = g_DeviceSettings.d3d9.AdapterFormat; + D3DFORMAT backBufferFormat = g_DeviceSettings.d3d9.pp.BackBufferFormat; + + CD3D9EnumDeviceInfo* pDeviceInfo = GetCurrentDeviceInfo(); + if( pDeviceInfo == NULL ) + return E_FAIL; + + bool bAllowSoftwareVP, bAllowHardwareVP, bAllowPureHardwareVP, bAllowMixedVP; + DXUTGetD3D9Enumeration()->GetPossibleVertexProcessingList( &bAllowSoftwareVP, &bAllowHardwareVP, + &bAllowPureHardwareVP, &bAllowMixedVP ); + + for( int idc = 0; idc < pDeviceInfo->deviceSettingsComboList.GetSize(); idc++ ) + { + CD3D9EnumDeviceSettingsCombo* pDeviceCombo = pDeviceInfo->deviceSettingsComboList.GetAt( idc ); + + if( pDeviceCombo->Windowed == ( g_DeviceSettings.d3d9.pp.Windowed == TRUE ) && + pDeviceCombo->AdapterFormat == adapterFormat && + pDeviceCombo->BackBufferFormat == backBufferFormat ) + { + CDXUTComboBox* pDepthStencilComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL ); + pDepthStencilComboBox->RemoveAllItems(); + pDepthStencilComboBox->SetEnabled( ( g_DeviceSettings.d3d9.pp.EnableAutoDepthStencil == TRUE ) ); + + if( g_DeviceSettings.d3d9.pp.EnableAutoDepthStencil ) + { + for( int ifmt = 0; ifmt < pDeviceCombo->depthStencilFormatList.GetSize(); ifmt++ ) + { + D3DFORMAT fmt = pDeviceCombo->depthStencilFormatList.GetAt( ifmt ); + + AddDepthStencilBufferFormat( fmt ); + } + + pDepthStencilComboBox->SetSelectedByData( ULongToPtr( + g_DeviceSettings.d3d9.pp.AutoDepthStencilFormat ) ); + } + else + { + if( !pDepthStencilComboBox->ContainsItem( L"(not used)" ) ) + pDepthStencilComboBox->AddItem( L"(not used)", NULL ); + } + + hr = OnDepthStencilBufferFormatChanged(); + if( FAILED( hr ) ) + return hr; + + CDXUTComboBox* pVertexProcessingComboBox = + m_Dialog.GetComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING ); + pVertexProcessingComboBox->RemoveAllItems(); + + // Add valid vertex processing types + if( bAllowSoftwareVP ) + AddVertexProcessingType( D3DCREATE_SOFTWARE_VERTEXPROCESSING ); + + if( bAllowHardwareVP && pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) + AddVertexProcessingType( D3DCREATE_HARDWARE_VERTEXPROCESSING ); + + if( bAllowPureHardwareVP && pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_PUREDEVICE ) + AddVertexProcessingType( D3DCREATE_PUREDEVICE ); + + if( bAllowMixedVP && pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) + AddVertexProcessingType( D3DCREATE_MIXED_VERTEXPROCESSING ); + + if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_PUREDEVICE ) + pVertexProcessingComboBox->SetSelectedByData( ULongToPtr( D3DCREATE_PUREDEVICE ) ); + else if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING ) + pVertexProcessingComboBox->SetSelectedByData( ULongToPtr( + D3DCREATE_SOFTWARE_VERTEXPROCESSING ) ); + else if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING ) + pVertexProcessingComboBox->SetSelectedByData( ULongToPtr( + D3DCREATE_HARDWARE_VERTEXPROCESSING ) ); + else if( g_DeviceSettings.d3d9.BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING ) + pVertexProcessingComboBox->SetSelectedByData( ULongToPtr( D3DCREATE_MIXED_VERTEXPROCESSING ) ); + + hr = OnVertexProcessingChanged(); + if( FAILED( hr ) ) + return hr; + + CDXUTComboBox* pPresentIntervalComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_PRESENT_INTERVAL ); + pPresentIntervalComboBox->RemoveAllItems(); + pPresentIntervalComboBox->AddItem( L"On", ULongToPtr( D3DPRESENT_INTERVAL_DEFAULT ) ); + pPresentIntervalComboBox->AddItem( L"Off", ULongToPtr( D3DPRESENT_INTERVAL_IMMEDIATE ) ); + + pPresentIntervalComboBox->SetSelectedByData( ULongToPtr( + g_DeviceSettings.d3d9.pp.PresentationInterval ) ); + + hr = OnPresentIntervalChanged(); + if( FAILED( hr ) ) + return hr; + } + } + + break; + } + + case DXUT_D3D11_DEVICE: + { + g_DeviceSettings.d3d11.sd.BufferDesc.Format = GetSelectedD3D11BackBufferFormat(); + + DXGI_FORMAT backBufferFormat = g_DeviceSettings.d3d11.sd.BufferDesc.Format; + + CD3D11EnumAdapterInfo* pAdapterInfo = GetCurrentD3D11AdapterInfo(); + if( pAdapterInfo == NULL ) + return E_FAIL; + + for( int idc = 0; idc < pAdapterInfo->deviceSettingsComboList.GetSize(); idc++ ) + { + CD3D11EnumDeviceSettingsCombo* pDeviceCombo = pAdapterInfo->deviceSettingsComboList.GetAt( idc ); + + if( pDeviceCombo->Windowed == ( g_DeviceSettings.d3d11.sd.Windowed == TRUE ) && + pDeviceCombo->BackBufferFormat == backBufferFormat && + pDeviceCombo->DeviceType == g_DeviceSettings.d3d11.DriverType ) + { + CDXUTComboBox* pMultisampleCountCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT + ); + pMultisampleCountCombo->RemoveAllItems(); + for( int i = 0; i < pDeviceCombo->multiSampleCountList.GetSize(); ++i ) + AddD3D11MultisampleCount( pDeviceCombo->multiSampleCountList.GetAt( i ) ); + pMultisampleCountCombo->SetSelectedByData( ULongToPtr( + g_DeviceSettings.d3d11.sd.SampleDesc.Count ) ); + + hr = OnMultisampleTypeChanged(); + if( FAILED( hr ) ) + return hr; + + CDXUTComboBox* pPresentIntervalComboBox = + m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL ); + pPresentIntervalComboBox->RemoveAllItems(); + pPresentIntervalComboBox->AddItem( L"On", ULongToPtr( 1 ) ); + pPresentIntervalComboBox->AddItem( L"Off", ULongToPtr( 0 ) ); + + pPresentIntervalComboBox->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.SyncInterval ) ); + + hr = OnPresentIntervalChanged(); + if( FAILED( hr ) ) + return hr; + + hr = UpdateD3D11Resolutions(); + if( FAILED( hr ) ) + return hr; + } + } + + break; + } + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnDepthStencilBufferFormatChanged() +{ + HRESULT hr = S_OK; + + D3DFORMAT depthStencilBufferFormat = GetSelectedDepthStencilBufferFormat(); + + if( g_DeviceSettings.d3d9.pp.EnableAutoDepthStencil ) + g_DeviceSettings.d3d9.pp.AutoDepthStencilFormat = depthStencilBufferFormat; + + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = GetCurrentDeviceSettingsCombo(); + if( pDeviceSettingsCombo == NULL ) + return E_FAIL; + + CDXUTComboBox* pMultisampleTypeCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE ); + pMultisampleTypeCombo->RemoveAllItems(); + + for( int ims = 0; ims < pDeviceSettingsCombo->multiSampleTypeList.GetSize(); ims++ ) + { + D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt( ims ); + + bool bConflictFound = false; + for( int iConf = 0; iConf < pDeviceSettingsCombo->DSMSConflictList.GetSize(); iConf++ ) + { + CD3D9EnumDSMSConflict DSMSConf = pDeviceSettingsCombo->DSMSConflictList.GetAt( iConf ); + if( DSMSConf.DSFormat == depthStencilBufferFormat && + DSMSConf.MSType == msType ) + { + bConflictFound = true; + break; + } + } + + if( !bConflictFound ) + AddMultisampleType( msType ); + } + + CDXUTComboBox* pMultisampleQualityCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE ); + pMultisampleQualityCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d9.pp.MultiSampleType ) ); + + hr = OnMultisampleTypeChanged(); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnMultisampleTypeChanged() +{ + HRESULT hr = S_OK; + + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + { + D3DMULTISAMPLE_TYPE multisampleType = GetSelectedMultisampleType(); + g_DeviceSettings.d3d9.pp.MultiSampleType = multisampleType; + + CD3D9EnumDeviceSettingsCombo* pDeviceSettingsCombo = GetCurrentDeviceSettingsCombo(); + if( pDeviceSettingsCombo == NULL ) + return E_FAIL; + + DWORD dwMaxQuality = 0; + for( int iType = 0; iType < pDeviceSettingsCombo->multiSampleTypeList.GetSize(); iType++ ) + { + D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt( iType ); + if( msType == multisampleType ) + { + dwMaxQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt( iType ); + break; + } + } + + // DXUTSETTINGSDLG_MULTISAMPLE_QUALITY + CDXUTComboBox* pMultisampleQualityCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY ); + pMultisampleQualityCombo->RemoveAllItems(); + + for( UINT iQuality = 0; iQuality < dwMaxQuality; iQuality++ ) + { + AddMultisampleQuality( iQuality ); + } + + pMultisampleQualityCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d9.pp.MultiSampleQuality ) ); + + hr = OnMultisampleQualityChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + case DXUT_D3D11_DEVICE: + { + UINT multisampleCount = GetSelectedD3D11MultisampleCount(); + g_DeviceSettings.d3d11.sd.SampleDesc.Count = multisampleCount; + + CD3D11EnumDeviceSettingsCombo* pDeviceSettingsCombo = GetCurrentD3D11DeviceSettingsCombo(); + if( pDeviceSettingsCombo == NULL ) + return E_FAIL; + + UINT MaxQuality = 0; + for( int iCount = 0; iCount < pDeviceSettingsCombo->multiSampleCountList.GetSize(); iCount++ ) + { + UINT Count = pDeviceSettingsCombo->multiSampleCountList.GetAt( iCount ); + if( Count == multisampleCount ) + { + MaxQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt( iCount ); + break; + } + } + + // DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY + CDXUTComboBox* pMultisampleQualityCombo = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY + ); + pMultisampleQualityCombo->RemoveAllItems(); + + for( UINT iQuality = 0; iQuality < MaxQuality; iQuality++ ) + { + AddD3D11MultisampleQuality( iQuality ); + } + + pMultisampleQualityCombo->SetSelectedByData( ULongToPtr( g_DeviceSettings.d3d11.sd.SampleDesc.Quality ) ); + + hr = OnMultisampleQualityChanged(); + if( FAILED( hr ) ) + return hr; + + break; + } + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnMultisampleQualityChanged() +{ + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + g_DeviceSettings.d3d9.pp.MultiSampleQuality = GetSelectedMultisampleQuality(); + break; + + case DXUT_D3D11_DEVICE: + g_DeviceSettings.d3d11.sd.SampleDesc.Quality = GetSelectedD3D11MultisampleQuality(); + break; + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnVertexProcessingChanged() +{ + DWORD dwBehavior = g_DeviceSettings.d3d9.BehaviorFlags; + + // Clear vertex processing flags + dwBehavior &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; + dwBehavior &= ~D3DCREATE_SOFTWARE_VERTEXPROCESSING; + dwBehavior &= ~D3DCREATE_MIXED_VERTEXPROCESSING; + dwBehavior &= ~D3DCREATE_PUREDEVICE; + + // Determine new flags + DWORD dwNewFlags = GetSelectedVertexProcessingType(); + if( dwNewFlags & D3DCREATE_PUREDEVICE ) + dwNewFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; + + // Make changes + g_DeviceSettings.d3d9.BehaviorFlags = dwBehavior | dwNewFlags; + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnPresentIntervalChanged() +{ + switch( g_DeviceSettings.ver ) + { + case DXUT_D3D9_DEVICE: + g_DeviceSettings.d3d9.pp.PresentationInterval = GetSelectedPresentInterval(); + break; + + case DXUT_D3D11_DEVICE: + g_DeviceSettings.d3d11.SyncInterval = GetSelectedD3D11PresentInterval(); + break; + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnDebugDeviceChanged() +{ + bool bDebugDevice = GetSelectedDebugDeviceValue(); + + if( bDebugDevice ) + g_DeviceSettings.d3d11.CreateFlags |= D3D11_CREATE_DEVICE_DEBUG; + else + g_DeviceSettings.d3d11.CreateFlags &= ~D3D11_CREATE_DEVICE_DEBUG; + + return S_OK; +} + +//------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::OnDeviceClipChanged() +{ + if( IsDeviceClip() ) + g_DeviceSettings.d3d9.pp.Flags |= D3DPRESENTFLAG_DEVICECLIP; + else + g_DeviceSettings.d3d9.pp.Flags &= ~D3DPRESENTFLAG_DEVICECLIP; + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddAPIVersion( DXUTDeviceVersion version ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_API_VERSION ); + + if( !pComboBox->ContainsItem( DXUTAPIVersionToString( version ) ) ) + pComboBox->AddItem( DXUTAPIVersionToString( version ), ULongToPtr( version ) ); +} + + +//------------------------------------------------------------------------------------- +DXUTDeviceVersion CD3DSettingsDlg::GetSelectedAPIVersion() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_API_VERSION ); + + return ( DXUTDeviceVersion )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddAdapter( const WCHAR* strDescription, UINT iAdapter ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); + + if( !pComboBox->ContainsItem( strDescription ) ) + pComboBox->AddItem( strDescription, ULongToPtr( iAdapter ) ); +} + + +//------------------------------------------------------------------------------------- +UINT CD3DSettingsDlg::GetSelectedAdapter() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); + + return PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddDeviceType( D3DDEVTYPE devType ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); + + if( !pComboBox->ContainsItem( DXUTD3DDeviceTypeToString( devType ) ) ) + pComboBox->AddItem( DXUTD3DDeviceTypeToString( devType ), ULongToPtr( devType ) ); +} + + +//------------------------------------------------------------------------------------- +D3DDEVTYPE CD3DSettingsDlg::GetSelectedDeviceType() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); + + return ( D3DDEVTYPE )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::SetWindowed( bool bWindowed ) +{ + CDXUTRadioButton* pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED ); + pRadioButton->SetChecked( bWindowed ); + + pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_FULLSCREEN ); + pRadioButton->SetChecked( !bWindowed ); +} + + +//------------------------------------------------------------------------------------- +bool CD3DSettingsDlg::IsWindowed() +{ + CDXUTRadioButton* pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED ); + return pRadioButton->GetChecked(); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddAdapterFormat( D3DFORMAT format ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT ); + + if( !pComboBox->ContainsItem( DXUTD3DFormatToString( format, TRUE ) ) ) + pComboBox->AddItem( DXUTD3DFormatToString( format, TRUE ), ULongToPtr( format ) ); +} + + +//------------------------------------------------------------------------------------- +D3DFORMAT CD3DSettingsDlg::GetSelectedAdapterFormat() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT ); + + return ( D3DFORMAT )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddD3D11AdapterOutput( const WCHAR* strName, UINT Output ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT ); + + if( !pComboBox->ContainsItem( strName ) ) + pComboBox->AddItem( strName, ULongToPtr( Output ) ); +} + + +//------------------------------------------------------------------------------------- +UINT CD3DSettingsDlg::GetSelectedD3D11AdapterOutput() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT ); + + return PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddResolution( DWORD dwWidth, DWORD dwHeight ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION ); + + DWORD dwResolutionData; + WCHAR strResolution[50]; + dwResolutionData = MAKELONG( dwWidth, dwHeight ); + swprintf_s( strResolution, 50, L"%d by %d", dwWidth, dwHeight ); + + if( !pComboBox->ContainsItem( strResolution ) ) + pComboBox->AddItem( strResolution, ULongToPtr( dwResolutionData ) ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::GetSelectedResolution( DWORD* pdwWidth, DWORD* pdwHeight ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION ); + + DWORD dwResolution = PtrToUlong( pComboBox->GetSelectedData() ); + + *pdwWidth = LOWORD( dwResolution ); + *pdwHeight = HIWORD( dwResolution ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddD3D11Resolution( DWORD dwWidth, DWORD dwHeight ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION ); + + DWORD dwResolutionData; + WCHAR strResolution[50]; + dwResolutionData = MAKELONG( dwWidth, dwHeight ); + swprintf_s( strResolution, 50, L"%d by %d", dwWidth, dwHeight ); + + if( !pComboBox->ContainsItem( strResolution ) ) + pComboBox->AddItem( strResolution, ULongToPtr( dwResolutionData ) ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::GetSelectedD3D11Resolution( DWORD* pdwWidth, DWORD* pdwHeight ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION ); + + DWORD dwResolution = PtrToUlong( pComboBox->GetSelectedData() ); + + *pdwWidth = LOWORD( dwResolution ); + *pdwHeight = HIWORD( dwResolution ); +} + +void CD3DSettingsDlg::AddD3D11FeatureLevel(D3D_FEATURE_LEVEL fl) { + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL ); + switch( fl ) + { + case D3D_FEATURE_LEVEL_9_1: + { + if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_9_1" ) ) + pComboBox->AddItem( L"D3D_FEATURE_LEVEL_9_1", ULongToPtr( D3D_FEATURE_LEVEL_9_1 ) ); + } + break; + case D3D_FEATURE_LEVEL_9_2: + { + if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_9_2" ) ) + pComboBox->AddItem( L"D3D_FEATURE_LEVEL_9_2", ULongToPtr( D3D_FEATURE_LEVEL_9_2 ) ); + } + break; + case D3D_FEATURE_LEVEL_9_3: + { + if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_9_3" ) ) + pComboBox->AddItem( L"D3D_FEATURE_LEVEL_9_3", ULongToPtr( D3D_FEATURE_LEVEL_9_3 ) ); + } + break; + case D3D_FEATURE_LEVEL_10_0: + { + if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_10_0" ) ) + pComboBox->AddItem( L"D3D_FEATURE_LEVEL_10_0", ULongToPtr( D3D_FEATURE_LEVEL_10_0 ) ); + } + break; + case D3D_FEATURE_LEVEL_10_1: + { + if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_10_1" ) ) + pComboBox->AddItem( L"D3D_FEATURE_LEVEL_10_1", ULongToPtr( D3D_FEATURE_LEVEL_10_1 ) ); + } + break; + case D3D_FEATURE_LEVEL_11_0: + { + if( !pComboBox->ContainsItem( L"D3D_FEATURE_LEVEL_11_0" ) ) + pComboBox->AddItem( L"D3D_FEATURE_LEVEL_11_0", ULongToPtr( D3D_FEATURE_LEVEL_11_0 ) ); + } + break; + } + +} + +D3D_FEATURE_LEVEL CD3DSettingsDlg::GetSelectedFeatureLevel() { + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL ); + + return (D3D_FEATURE_LEVEL)PtrToUlong( pComboBox->GetSelectedData() ); +} +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddRefreshRate( DWORD dwRate ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE ); + + WCHAR strRefreshRate[50]; + + if( dwRate == 0 ) + wcscpy_s( strRefreshRate, 50, L"Default Rate" ); + else + swprintf_s( strRefreshRate, 50, L"%d Hz", dwRate ); + + if( !pComboBox->ContainsItem( strRefreshRate ) ) + pComboBox->AddItem( strRefreshRate, ULongToPtr( dwRate ) ); +} + + +//------------------------------------------------------------------------------------- +DWORD CD3DSettingsDlg::GetSelectedRefreshRate() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE ); + + return PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddD3D11RefreshRate( DXGI_RATIONAL RefreshRate ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); + + WCHAR strRefreshRate[50]; + + if( RefreshRate.Numerator == 0 && RefreshRate.Denominator == 0 ) + wcscpy_s( strRefreshRate, 50, L"Default Rate" ); + else + swprintf_s( strRefreshRate, 50, L"%d Hz", RefreshRate.Numerator / RefreshRate.Denominator ); + + if( !pComboBox->ContainsItem( strRefreshRate ) ) + { + DXGI_RATIONAL* pNewRate = new DXGI_RATIONAL; + if( pNewRate ) + { + *pNewRate = RefreshRate; + pComboBox->AddItem( strRefreshRate, pNewRate ); + } + } +} + + +//------------------------------------------------------------------------------------- +DXGI_RATIONAL CD3DSettingsDlg::GetSelectedD3D11RefreshRate() +{ + DXGI_RATIONAL dxgiR; + dxgiR.Numerator = 0; + dxgiR.Denominator = 1; + + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_REFRESH_RATE ); + + return *reinterpret_cast( pComboBox->GetSelectedData() ); + +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddBackBufferFormat( D3DFORMAT format ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT ); + + if( !pComboBox->ContainsItem( DXUTD3DFormatToString( format, TRUE ) ) ) + pComboBox->AddItem( DXUTD3DFormatToString( format, TRUE ), ULongToPtr( format ) ); +} + + +//------------------------------------------------------------------------------------- +D3DFORMAT CD3DSettingsDlg::GetSelectedBackBufferFormat() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT ); + + return ( D3DFORMAT )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddD3D11BackBufferFormat( DXGI_FORMAT format ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT ); + + if( !pComboBox->ContainsItem( DXUTDXGIFormatToString( format, TRUE ) ) ) + pComboBox->AddItem( DXUTDXGIFormatToString( format, TRUE ), ULongToPtr( format ) ); +} + + +//------------------------------------------------------------------------------------- +DXGI_FORMAT CD3DSettingsDlg::GetSelectedD3D11BackBufferFormat() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT ); + + return ( DXGI_FORMAT )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddDepthStencilBufferFormat( D3DFORMAT format ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL ); + + if( !pComboBox->ContainsItem( DXUTD3DFormatToString( format, TRUE ) ) ) + pComboBox->AddItem( DXUTD3DFormatToString( format, TRUE ), ULongToPtr( format ) ); +} + + +//------------------------------------------------------------------------------------- +D3DFORMAT CD3DSettingsDlg::GetSelectedDepthStencilBufferFormat() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL ); + + return ( D3DFORMAT )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddMultisampleType( D3DMULTISAMPLE_TYPE type ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE ); + + if( !pComboBox->ContainsItem( DXUTMultisampleTypeToString( type ) ) ) + pComboBox->AddItem( DXUTMultisampleTypeToString( type ), ULongToPtr( type ) ); +} + + +//------------------------------------------------------------------------------------- +D3DMULTISAMPLE_TYPE CD3DSettingsDlg::GetSelectedMultisampleType() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE ); + + return ( D3DMULTISAMPLE_TYPE )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddMultisampleQuality( DWORD dwQuality ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY ); + + WCHAR strQuality[50]; + swprintf_s( strQuality, 50, L"%d", dwQuality ); + + if( !pComboBox->ContainsItem( strQuality ) ) + pComboBox->AddItem( strQuality, ULongToPtr( dwQuality ) ); +} + + +//------------------------------------------------------------------------------------- +DWORD CD3DSettingsDlg::GetSelectedMultisampleQuality() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY ); + + return PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddD3D11MultisampleCount( UINT Count ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT ); + + WCHAR str[50]; + swprintf_s( str, 50, L"%u", Count ); + + if( !pComboBox->ContainsItem( str ) ) + pComboBox->AddItem( str, ULongToPtr( Count ) ); +} + + +//------------------------------------------------------------------------------------- +UINT CD3DSettingsDlg::GetSelectedD3D11MultisampleCount() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT ); + + return ( UINT )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddD3D11MultisampleQuality( UINT Quality ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY ); + + WCHAR strQuality[50]; + swprintf_s( strQuality, 50, L"%d", Quality ); + + if( !pComboBox->ContainsItem( strQuality ) ) + pComboBox->AddItem( strQuality, ULongToPtr( Quality ) ); +} + + +//------------------------------------------------------------------------------------- +UINT CD3DSettingsDlg::GetSelectedD3D11MultisampleQuality() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY ); + + return ( UINT )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddVertexProcessingType( DWORD dwType ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING ); + + if( !pComboBox->ContainsItem( DXUTVertexProcessingTypeToString( dwType ) ) ) + pComboBox->AddItem( DXUTVertexProcessingTypeToString( dwType ), ULongToPtr( dwType ) ); +} + + +//------------------------------------------------------------------------------------- +DWORD CD3DSettingsDlg::GetSelectedVertexProcessingType() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING ); + + return PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +DWORD CD3DSettingsDlg::GetSelectedPresentInterval() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_PRESENT_INTERVAL ); + + return PtrToUlong( pComboBox->GetSelectedData() ); +} + + +//------------------------------------------------------------------------------------- +DWORD CD3DSettingsDlg::GetSelectedD3D11PresentInterval() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL ); + + return PtrToUlong( pComboBox->GetSelectedData() ); +} + +//------------------------------------------------------------------------------------- +bool CD3DSettingsDlg::GetSelectedDebugDeviceValue() +{ + CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE ); + + return pCheckBox->GetChecked(); +} + + +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::SetDeviceClip( bool bDeviceClip ) +{ + CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_DEVICECLIP ); + pCheckBox->SetChecked( bDeviceClip ); +} + + +//------------------------------------------------------------------------------------- +bool CD3DSettingsDlg::IsDeviceClip() +{ + CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_DEVICECLIP ); + return pCheckBox->GetChecked(); +} + +//-------------------------------------------------------------------------------------- +// Updates the resolution list for D3D11 +//-------------------------------------------------------------------------------------- +HRESULT CD3DSettingsDlg::UpdateD3D11Resolutions() +{ + + const DWORD dwWidth = g_DeviceSettings.d3d11.sd.BufferDesc.Width; + const DWORD dwHeight = g_DeviceSettings.d3d11.sd.BufferDesc.Height; + + // DXUTSETTINGSDLG_D3D11_RESOLUTION + CDXUTComboBox* pResolutionComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_D3D11_RESOLUTION ); + pResolutionComboBox->RemoveAllItems(); + + CD3D11EnumOutputInfo* pOutputInfo = GetCurrentD3D11OutputInfo(); + if( pOutputInfo == NULL ) + return E_FAIL; + + bool bShowAll = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL )->GetChecked(); + + // Get the desktop aspect ratio + DXGI_MODE_DESC dmDesktop; + DXUTGetDesktopResolution( g_DeviceSettings.d3d11.AdapterOrdinal, &dmDesktop.Width, &dmDesktop.Height ); + float fDesktopAspectRatio = dmDesktop.Width / ( float )dmDesktop.Height; + + for( int idm = 0; idm < pOutputInfo->displayModeList.GetSize(); idm++ ) + { + DXGI_MODE_DESC DisplayMode = pOutputInfo->displayModeList.GetAt( idm ); + float fAspect = ( float )DisplayMode.Width / ( float )DisplayMode.Height; + + if( DisplayMode.Format == g_DeviceSettings.d3d11.sd.BufferDesc.Format ) + { + // If "Show All" is not checked, then hide all resolutions + // that don't match the aspect ratio of the desktop resolution + if( bShowAll || ( !bShowAll && fabsf( fDesktopAspectRatio - fAspect ) < 0.05f ) ) + { + AddD3D11Resolution( DisplayMode.Width, DisplayMode.Height ); + } + } + } + + const DWORD dwCurResolution = MAKELONG( g_DeviceSettings.d3d11.sd.BufferDesc.Width, + g_DeviceSettings.d3d11.sd.BufferDesc.Height ); + + pResolutionComboBox->SetSelectedByData( ULongToPtr( dwCurResolution ) ); + + + bool bWindowed = IsWindowed(); + if( bWindowed ) + { + pResolutionComboBox->RemoveAllItems(); + AddD3D11Resolution( dwWidth, dwHeight ); + + pResolutionComboBox->SetSelectedByData( ULongToPtr( MAKELONG( dwWidth, dwHeight ) ) ); + + + } + + return S_OK; +} + + +// +//------------------------------------------------------------------------------------- +void CD3DSettingsDlg::AddD3D11DeviceType( D3D_DRIVER_TYPE devType ) +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); + + if( !pComboBox->ContainsItem( DXUTD3DX11DeviceTypeToString( devType ) ) ) + pComboBox->AddItem( DXUTD3DX11DeviceTypeToString( devType ), ULongToPtr( devType ) ); +} + + +//------------------------------------------------------------------------------------- +D3D_DRIVER_TYPE CD3DSettingsDlg::GetSelectedD3D11DeviceType() +{ + CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); + + return ( D3D_DRIVER_TYPE )PtrToUlong( pComboBox->GetSelectedData() ); +} + + +void CD3DSettingsDlg::UpdateModeChangeTimeoutText( int nSecRemaining ) +{ + const WCHAR StrTimeout[] = L"Reverting to previous display settings in %d seconds"; + const DWORD CchBuf = sizeof( StrTimeout ) / sizeof( WCHAR ) + 16; + WCHAR buf[CchBuf]; + + swprintf_s( buf, CchBuf, StrTimeout, nSecRemaining ); + + CDXUTStatic* pStatic = m_RevertModeDialog.GetStatic( DXUTSETTINGSDLG_STATIC_MODE_CHANGE_TIMEOUT ); + pStatic->SetText( buf ); +} + +//-------------------------------------------------------------------------------------- +// Returns the string for the given DXUTDeviceVersion. +//-------------------------------------------------------------------------------------- +WCHAR* DXUTAPIVersionToString( DXUTDeviceVersion version ) +{ + switch( version ) + { + case DXUT_D3D9_DEVICE: + return L"Direct3D 9"; + case DXUT_D3D11_DEVICE: + return L"Direct3D 11"; + default: + return L"Unknown version"; + } +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given D3DDEVTYPE. +//-------------------------------------------------------------------------------------- +WCHAR* DXUTD3DDeviceTypeToString( D3DDEVTYPE devType ) +{ + switch( devType ) + { + case D3DDEVTYPE_HAL: + return L"D3DDEVTYPE_HAL"; + case D3DDEVTYPE_SW: + return L"D3DDEVTYPE_SW"; + case D3DDEVTYPE_REF: + return L"D3DDEVTYPE_REF"; + default: + return L"Unknown devType"; + } +} + + + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given D3D_DRIVER_TYPE. +//-------------------------------------------------------------------------------------- +WCHAR* DXUTD3DX11DeviceTypeToString( D3D_DRIVER_TYPE devType ) +{ + switch( devType ) + { + case D3D_DRIVER_TYPE_HARDWARE: + return L"D3D_DRIVER_TYPE_HARDWARE"; + case D3D_DRIVER_TYPE_REFERENCE: + return L"D3D_DRIVER_TYPE_REFERENCE"; + case D3D_DRIVER_TYPE_NULL: + return L"D3D_DRIVER_TYPE_NULL"; + case D3D_DRIVER_TYPE_WARP: + return L"D3D_DRIVER_TYPE_WARP"; + default: + return L"Unknown devType"; + } +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given D3DMULTISAMPLE_TYPE. +//-------------------------------------------------------------------------------------- +WCHAR* DXUTMultisampleTypeToString( D3DMULTISAMPLE_TYPE MultiSampleType ) +{ + switch( MultiSampleType ) + { + case D3DMULTISAMPLE_NONE: + return L"D3DMULTISAMPLE_NONE"; + case D3DMULTISAMPLE_NONMASKABLE: + return L"D3DMULTISAMPLE_NONMASKABLE"; + case D3DMULTISAMPLE_2_SAMPLES: + return L"D3DMULTISAMPLE_2_SAMPLES"; + case D3DMULTISAMPLE_3_SAMPLES: + return L"D3DMULTISAMPLE_3_SAMPLES"; + case D3DMULTISAMPLE_4_SAMPLES: + return L"D3DMULTISAMPLE_4_SAMPLES"; + case D3DMULTISAMPLE_5_SAMPLES: + return L"D3DMULTISAMPLE_5_SAMPLES"; + case D3DMULTISAMPLE_6_SAMPLES: + return L"D3DMULTISAMPLE_6_SAMPLES"; + case D3DMULTISAMPLE_7_SAMPLES: + return L"D3DMULTISAMPLE_7_SAMPLES"; + case D3DMULTISAMPLE_8_SAMPLES: + return L"D3DMULTISAMPLE_8_SAMPLES"; + case D3DMULTISAMPLE_9_SAMPLES: + return L"D3DMULTISAMPLE_9_SAMPLES"; + case D3DMULTISAMPLE_10_SAMPLES: + return L"D3DMULTISAMPLE_10_SAMPLES"; + case D3DMULTISAMPLE_11_SAMPLES: + return L"D3DMULTISAMPLE_11_SAMPLES"; + case D3DMULTISAMPLE_12_SAMPLES: + return L"D3DMULTISAMPLE_12_SAMPLES"; + case D3DMULTISAMPLE_13_SAMPLES: + return L"D3DMULTISAMPLE_13_SAMPLES"; + case D3DMULTISAMPLE_14_SAMPLES: + return L"D3DMULTISAMPLE_14_SAMPLES"; + case D3DMULTISAMPLE_15_SAMPLES: + return L"D3DMULTISAMPLE_15_SAMPLES"; + case D3DMULTISAMPLE_16_SAMPLES: + return L"D3DMULTISAMPLE_16_SAMPLES"; + default: + return L"Unknown Multisample Type"; + } +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given vertex processing type +//-------------------------------------------------------------------------------------- +WCHAR* DXUTVertexProcessingTypeToString( DWORD vpt ) +{ + switch( vpt ) + { + case D3DCREATE_SOFTWARE_VERTEXPROCESSING: + return L"Software vertex processing"; + case D3DCREATE_MIXED_VERTEXPROCESSING: + return L"Mixed vertex processing"; + case D3DCREATE_HARDWARE_VERTEXPROCESSING: + return L"Hardware vertex processing"; + case D3DCREATE_PUREDEVICE: + return L"Pure hardware vertex processing"; + default: + return L"Unknown vertex processing type"; + } +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given present interval. +//-------------------------------------------------------------------------------------- +WCHAR* DXUTPresentIntervalToString( UINT pi ) +{ + switch( pi ) + { + case D3DPRESENT_INTERVAL_IMMEDIATE: + return L"D3DPRESENT_INTERVAL_IMMEDIATE"; + case D3DPRESENT_INTERVAL_DEFAULT: + return L"D3DPRESENT_INTERVAL_DEFAULT"; + case D3DPRESENT_INTERVAL_ONE: + return L"D3DPRESENT_INTERVAL_ONE"; + case D3DPRESENT_INTERVAL_TWO: + return L"D3DPRESENT_INTERVAL_TWO"; + case D3DPRESENT_INTERVAL_THREE: + return L"D3DPRESENT_INTERVAL_THREE"; + case D3DPRESENT_INTERVAL_FOUR: + return L"D3DPRESENT_INTERVAL_FOUR"; + default: + return L"Unknown PresentInterval"; + } +} + + diff --git a/Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.h b/Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.h new file mode 100644 index 0000000..fee91f3 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/DXUTsettingsdlg.h @@ -0,0 +1,248 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTSettingsDlg.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef DXUT_SETTINGS_H +#define DXUT_SETTINGS_H + +//-------------------------------------------------------------------------------------- +// Header Includes +//-------------------------------------------------------------------------------------- +#include "DXUTgui.h" +//-------------------------------------------------------------------------------------- +// Control IDs +//-------------------------------------------------------------------------------------- +#define DXUTSETTINGSDLG_STATIC -1 +#define DXUTSETTINGSDLG_OK 1 +#define DXUTSETTINGSDLG_CANCEL 2 +#define DXUTSETTINGSDLG_ADAPTER 3 +#define DXUTSETTINGSDLG_DEVICE_TYPE 4 +#define DXUTSETTINGSDLG_WINDOWED 5 +#define DXUTSETTINGSDLG_FULLSCREEN 6 +#define DXUTSETTINGSDLG_ADAPTER_FORMAT 7 +#define DXUTSETTINGSDLG_ADAPTER_FORMAT_LABEL 8 +#define DXUTSETTINGSDLG_RESOLUTION 9 +#define DXUTSETTINGSDLG_RESOLUTION_LABEL 10 +#define DXUTSETTINGSDLG_REFRESH_RATE 11 +#define DXUTSETTINGSDLG_REFRESH_RATE_LABEL 12 +#define DXUTSETTINGSDLG_BACK_BUFFER_FORMAT 13 +#define DXUTSETTINGSDLG_BACK_BUFFER_FORMAT_LABEL 14 +#define DXUTSETTINGSDLG_DEPTH_STENCIL 15 +#define DXUTSETTINGSDLG_DEPTH_STENCIL_LABEL 16 +#define DXUTSETTINGSDLG_MULTISAMPLE_TYPE 17 +#define DXUTSETTINGSDLG_MULTISAMPLE_TYPE_LABEL 18 +#define DXUTSETTINGSDLG_MULTISAMPLE_QUALITY 19 +#define DXUTSETTINGSDLG_MULTISAMPLE_QUALITY_LABEL 20 +#define DXUTSETTINGSDLG_VERTEX_PROCESSING 21 +#define DXUTSETTINGSDLG_VERTEX_PROCESSING_LABEL 22 +#define DXUTSETTINGSDLG_PRESENT_INTERVAL 23 +#define DXUTSETTINGSDLG_PRESENT_INTERVAL_LABEL 24 +#define DXUTSETTINGSDLG_DEVICECLIP 25 +#define DXUTSETTINGSDLG_RESOLUTION_SHOW_ALL 26 +#define DXUTSETTINGSDLG_API_VERSION 27 +#define DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT 28 +#define DXUTSETTINGSDLG_D3D11_ADAPTER_OUTPUT_LABEL 29 +#define DXUTSETTINGSDLG_D3D11_RESOLUTION 30 +#define DXUTSETTINGSDLG_D3D11_RESOLUTION_LABEL 31 +#define DXUTSETTINGSDLG_D3D11_REFRESH_RATE 32 +#define DXUTSETTINGSDLG_D3D11_REFRESH_RATE_LABEL 33 +#define DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT 34 +#define DXUTSETTINGSDLG_D3D11_BACK_BUFFER_FORMAT_LABEL 35 +#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT 36 +#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_COUNT_LABEL 37 +#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY 38 +#define DXUTSETTINGSDLG_D3D11_MULTISAMPLE_QUALITY_LABEL 39 +#define DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL 40 +#define DXUTSETTINGSDLG_D3D11_PRESENT_INTERVAL_LABEL 41 +#define DXUTSETTINGSDLG_D3D11_DEBUG_DEVICE 42 +#define DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL 43 +#define DXUTSETTINGSDLG_D3D11_FEATURE_LEVEL_LABEL 44 + +#define DXUTSETTINGSDLG_MODE_CHANGE_ACCEPT 58 +#define DXUTSETTINGSDLG_MODE_CHANGE_REVERT 59 +#define DXUTSETTINGSDLG_STATIC_MODE_CHANGE_TIMEOUT 60 +#define DXUTSETTINGSDLG_WINDOWED_GROUP 0x0100 + +#define TOTAL_FEATURE_LEVLES 6 +//-------------------------------------------------------------------------------------- +// Dialog for selection of device settings +// Use DXUTGetD3DSettingsDialog() to access global instance +// To control the contents of the dialog, use the CD3D9Enumeration class. +//-------------------------------------------------------------------------------------- +class CD3DSettingsDlg +{ +public: + CD3DSettingsDlg(); + ~CD3DSettingsDlg(); + + void Init( CDXUTDialogResourceManager* pManager ); + void Init( CDXUTDialogResourceManager* pManager, LPCWSTR szControlTextureFileName ); + void Init( CDXUTDialogResourceManager* pManager, LPCWSTR pszControlTextureResourcename, + HMODULE hModule ); + + HRESULT Refresh(); + void OnRender( float fElapsedTime ); + void OnRender9( float fElapsedTime ); + void OnRender10( float fElapsedTime ); + void OnRender11( float fElapsedTime ); + + HRESULT OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice ); + HRESULT OnD3D9ResetDevice(); + void OnD3D9LostDevice(); + void OnD3D9DestroyDevice(); + + HRESULT OnD3D11CreateDevice( ID3D11Device* pd3dDevice ); + HRESULT OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, + const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc ); + void OnD3D11DestroyDevice(); + + CDXUTDialog* GetDialogControl() + { + return &m_Dialog; + } + bool IsActive() + { + return m_bActive; + } + void SetActive( bool bActive ) + { + m_bActive = bActive; if( bActive ) Refresh(); + } + void ShowControlSet( DXUTDeviceVersion ver ); + + LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +protected: + friend CD3DSettingsDlg* WINAPI DXUTGetD3DSettingsDialog(); + + void CreateControls(); + HRESULT SetDeviceSettingsFromUI(); + void SetSelectedD3D11RefreshRate( DXGI_RATIONAL RefreshRate ); + HRESULT UpdateD3D11Resolutions(); + + void OnEvent( UINT nEvent, int nControlID, CDXUTControl* pControl ); + static void WINAPI StaticOnEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserData ); + static void WINAPI StaticOnModeChangeTimer( UINT nIDEvent, void* pUserContext ); + + CD3D9EnumAdapterInfo* GetCurrentAdapterInfo(); + CD3D9EnumDeviceInfo* GetCurrentDeviceInfo(); + CD3D9EnumDeviceSettingsCombo* GetCurrentDeviceSettingsCombo(); + + CD3D11EnumAdapterInfo* GetCurrentD3D11AdapterInfo(); + CD3D11EnumDeviceInfo* GetCurrentD3D11DeviceInfo(); + CD3D11EnumOutputInfo* GetCurrentD3D11OutputInfo(); + CD3D11EnumDeviceSettingsCombo* GetCurrentD3D11DeviceSettingsCombo(); + + void AddAPIVersion( DXUTDeviceVersion version ); + DXUTDeviceVersion GetSelectedAPIVersion(); + + void AddAdapter( const WCHAR* strDescription, UINT iAdapter ); + UINT GetSelectedAdapter(); + + void AddDeviceType( D3DDEVTYPE devType ); + D3DDEVTYPE GetSelectedDeviceType(); + + void SetWindowed( bool bWindowed ); + bool IsWindowed(); + + void AddAdapterFormat( D3DFORMAT format ); + D3DFORMAT GetSelectedAdapterFormat(); + + void AddResolution( DWORD dwWidth, DWORD dwHeight ); + void GetSelectedResolution( DWORD* pdwWidth, DWORD* pdwHeight ); + + void AddRefreshRate( DWORD dwRate ); + DWORD GetSelectedRefreshRate(); + + void AddBackBufferFormat( D3DFORMAT format ); + D3DFORMAT GetSelectedBackBufferFormat(); + + void AddDepthStencilBufferFormat( D3DFORMAT format ); + D3DFORMAT GetSelectedDepthStencilBufferFormat(); + + void AddMultisampleType( D3DMULTISAMPLE_TYPE type ); + D3DMULTISAMPLE_TYPE GetSelectedMultisampleType(); + + void AddMultisampleQuality( DWORD dwQuality ); + DWORD GetSelectedMultisampleQuality(); + + void AddVertexProcessingType( DWORD dwType ); + DWORD GetSelectedVertexProcessingType(); + + DWORD GetSelectedPresentInterval(); + + void SetDeviceClip( bool bDeviceClip ); + bool IsDeviceClip(); + + // D3D11 + void AddD3D11DeviceType( D3D_DRIVER_TYPE devType ); + D3D_DRIVER_TYPE GetSelectedD3D11DeviceType(); + + void AddD3D11AdapterOutput( const WCHAR* strName, UINT nOutput ); + UINT GetSelectedD3D11AdapterOutput(); + + void AddD3D11Resolution( DWORD dwWidth, DWORD dwHeight ); + void GetSelectedD3D11Resolution( DWORD* pdwWidth, DWORD* pdwHeight ); + + void AddD3D11FeatureLevel(D3D_FEATURE_LEVEL); + D3D_FEATURE_LEVEL GetSelectedFeatureLevel(); + + void AddD3D11RefreshRate( DXGI_RATIONAL RefreshRate ); + DXGI_RATIONAL GetSelectedD3D11RefreshRate(); + + void AddD3D11BackBufferFormat( DXGI_FORMAT format ); + DXGI_FORMAT GetSelectedD3D11BackBufferFormat(); + + void AddD3D11MultisampleCount( UINT count ); + UINT GetSelectedD3D11MultisampleCount(); + + void AddD3D11MultisampleQuality( UINT Quality ); + UINT GetSelectedD3D11MultisampleQuality(); + + DWORD GetSelectedD3D11PresentInterval(); + bool GetSelectedDebugDeviceValue(); + + + + HRESULT OnD3D11ResolutionChanged (); + HRESULT OnAPIVersionChanged( bool bRefresh=false ); + HRESULT OnFeatureLevelChanged(); + HRESULT OnAdapterChanged(); + HRESULT OnDeviceTypeChanged(); + HRESULT OnWindowedFullScreenChanged(); + HRESULT OnAdapterOutputChanged(); + HRESULT OnAdapterFormatChanged(); + HRESULT OnResolutionChanged(); + HRESULT OnRefreshRateChanged(); + HRESULT OnBackBufferFormatChanged(); + HRESULT OnDepthStencilBufferFormatChanged(); + HRESULT OnMultisampleTypeChanged(); + HRESULT OnMultisampleQualityChanged(); + HRESULT OnVertexProcessingChanged(); + HRESULT OnPresentIntervalChanged(); + HRESULT OnDebugDeviceChanged(); + HRESULT OnDeviceClipChanged(); + + void UpdateModeChangeTimeoutText( int nSecRemaining ); + + IDirect3DStateBlock9* m_pStateBlock; + CDXUTDialog* m_pActiveDialog; + CDXUTDialog m_Dialog; + CDXUTDialog m_RevertModeDialog; + int m_nRevertModeTimeout; + UINT m_nIDEvent; + bool m_bActive; + + D3D_FEATURE_LEVEL m_Levels[TOTAL_FEATURE_LEVLES]; + +}; + + +CD3DSettingsDlg* WINAPI DXUTGetD3DSettingsDialog(); + + + +#endif + diff --git a/Demos/DX11ClothDemo/DXUT/Optional/ImeUi.cpp b/Demos/DX11ClothDemo/DXUT/Optional/ImeUi.cpp new file mode 100644 index 0000000..912c6d6 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/ImeUi.cpp @@ -0,0 +1,3662 @@ +//-------------------------------------------------------------------------------------- +// File: ImeUi.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#include "dxut.h" +#include "ImeUi.h" +#include +#include +#include +#include + +// Ignore typecast warnings +#pragma warning( disable : 4312 ) +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4311 ) + + +#define MAX_CANDIDATE_LENGTH 256 +#define COUNTOF(a) ( sizeof( a ) / sizeof( ( a )[0] ) ) +#define POSITION_UNINITIALIZED ((DWORD)-1) + +#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) +#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) + +#define MAKEIMEVERSION(major,minor) ( (DWORD)( ( (BYTE)( major ) << 24 ) | ( (BYTE)( minor ) << 16 ) ) ) +#define IMEID_VER(dwId) ( ( dwId ) & 0xffff0000 ) +#define IMEID_LANG(dwId) ( ( dwId ) & 0x0000ffff ) + +#define _CHT_HKL_DAYI ( (HKL)0xE0060404 ) // DaYi +#define _CHT_HKL_NEW_PHONETIC ( (HKL)0xE0080404 ) // New Phonetic +#define _CHT_HKL_NEW_CHANG_JIE ( (HKL)0xE0090404 ) // New Chang Jie +#define _CHT_HKL_NEW_QUICK ( (HKL)0xE00A0404 ) // New Quick +#define _CHT_HKL_HK_CANTONESE ( (HKL)0xE00B0404 ) // Hong Kong Cantonese +#define _CHT_IMEFILENAME "TINTLGNT.IME" // New Phonetic +#define _CHT_IMEFILENAME2 "CINTLGNT.IME" // New Chang Jie +#define _CHT_IMEFILENAME3 "MSTCIPHA.IME" // Phonetic 5.1 +#define IMEID_CHT_VER42 ( LANG_CHT | MAKEIMEVERSION( 4, 2 ) ) // New(Phonetic/ChanJie)IME98 : 4.2.x.x // Win98 +#define IMEID_CHT_VER43 ( LANG_CHT | MAKEIMEVERSION( 4, 3 ) ) // New(Phonetic/ChanJie)IME98a : 4.3.x.x // Win2k +#define IMEID_CHT_VER44 ( LANG_CHT | MAKEIMEVERSION( 4, 4 ) ) // New ChanJie IME98b : 4.4.x.x // WinXP +#define IMEID_CHT_VER50 ( LANG_CHT | MAKEIMEVERSION( 5, 0 ) ) // New(Phonetic/ChanJie)IME5.0 : 5.0.x.x // WinME +#define IMEID_CHT_VER51 ( LANG_CHT | MAKEIMEVERSION( 5, 1 ) ) // New(Phonetic/ChanJie)IME5.1 : 5.1.x.x // IME2002(w/OfficeXP) +#define IMEID_CHT_VER52 ( LANG_CHT | MAKEIMEVERSION( 5, 2 ) ) // New(Phonetic/ChanJie)IME5.2 : 5.2.x.x // IME2002a(w/WinXP) +#define IMEID_CHT_VER60 ( LANG_CHT | MAKEIMEVERSION( 6, 0 ) ) // New(Phonetic/ChanJie)IME6.0 : 6.0.x.x // New IME 6.0(web download) +#define IMEID_CHT_VER_VISTA ( LANG_CHT | MAKEIMEVERSION( 7, 0 ) ) // All TSF TIP under Cicero UI-less mode: a hack to make GetImeId() return non-zero value + +#define _CHS_HKL ( (HKL)0xE00E0804 ) // MSPY +#define _CHS_IMEFILENAME "PINTLGNT.IME" // MSPY1.5/2/3 +#define _CHS_IMEFILENAME2 "MSSCIPYA.IME" // MSPY3 for OfficeXP +#define IMEID_CHS_VER41 ( LANG_CHS | MAKEIMEVERSION( 4, 1 ) ) // MSPY1.5 // SCIME97 or MSPY1.5 (w/Win98, Office97) +#define IMEID_CHS_VER42 ( LANG_CHS | MAKEIMEVERSION( 4, 2 ) ) // MSPY2 // Win2k/WinME +#define IMEID_CHS_VER53 ( LANG_CHS | MAKEIMEVERSION( 5, 3 ) ) // MSPY3 // WinXP + +static CHAR signature[] = "%%%IMEUILIB:070111%%%"; + +static IMEUI_APPEARANCE gSkinIME = +{ + 0, // symbolColor; + 0x404040, // symbolColorOff; + 0xff000000, // symbolColorText; + 24, // symbolHeight; + 0xa0, // symbolTranslucence; + 0, // symbolPlacement; + NULL, // symbolFont; + 0xffffffff, // candColorBase; + 0xff000000, // candColorBorder; + 0, // candColorText; + 0x00ffff00, // compColorInput; + 0x000000ff, // compColorTargetConv; + 0x0000ff00, // compColorConverted; + 0x00ff0000, // compColorTargetNotConv; + 0x00ff0000, // compColorInputErr; + 0x80, // compTranslucence; + 0, // compColorText; + 2, // caretWidth; + 1, // caretYMargin; +}; + +struct _SkinCompStr +{ + DWORD colorInput; + DWORD colorTargetConv; + DWORD colorConverted; + DWORD colorTargetNotConv; + DWORD colorInputErr; +}; + +_SkinCompStr gSkinCompStr; + +// Definition from Win98DDK version of IMM.H +typedef struct +tagINPUTCONTEXT2 +{ + HWND hWnd; + BOOL fOpen; + POINT ptStatusWndPos; + POINT ptSoftKbdPos; + DWORD fdwConversion; + DWORD fdwSentence; + union + { + LOGFONTA A; + LOGFONTW W; + } lfFont; + COMPOSITIONFORM cfCompForm; + CANDIDATEFORM cfCandForm[4]; + HIMCC hCompStr; + HIMCC hCandInfo; + HIMCC hGuideLine; + HIMCC hPrivate; + DWORD dwNumMsgBuf; + HIMCC hMsgBuf; + DWORD fdwInit; + DWORD dwReserve[3]; +} +INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, +FAR* LPINPUTCONTEXT2; + + +// Class to disable Cicero in case ImmDisableTextFrameService() doesn't disable it completely +class CDisableCicero +{ +public: + CDisableCicero() : m_ptim( NULL ), + m_bComInit( false ) + { + } + ~CDisableCicero() + { + Uninitialize(); + } + void Initialize() + { + if( m_bComInit ) + { + return; + } + HRESULT hr; + hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); + if( SUCCEEDED( hr ) ) + { + m_bComInit = true; + hr = CoCreateInstance( CLSID_TF_ThreadMgr, + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( ITfThreadMgr ), + ( void** )&m_ptim ); + } + } + void Uninitialize() + { + if( m_ptim ) + { + m_ptim->Release(); + m_ptim = NULL; + } + if( m_bComInit ) + CoUninitialize(); + m_bComInit = false; + } + + void DisableCiceroOnThisWnd( HWND hwnd ) + { + if( m_ptim == NULL ) + return; + ITfDocumentMgr* pdimPrev; // the dim that is associated previously. + // Associate NULL dim to the window. + // When this window gets the focus, Cicero does not work and IMM32 IME + // will be activated. + if( SUCCEEDED( m_ptim->AssociateFocus( hwnd, NULL, &pdimPrev ) ) ) + { + if( pdimPrev ) + pdimPrev->Release(); + } + } +private: + ITfThreadMgr* m_ptim; + bool m_bComInit; +}; +static CDisableCicero g_disableCicero; + +#define _IsLeadByte(x) ( LeadByteTable[(BYTE)( x )] ) +static void _PumpMessage(); +static BYTE LeadByteTable[256]; +#define _ImmGetContext ImmGetContext +#define _ImmReleaseContext ImmReleaseContext +#define _ImmAssociateContext ImmAssociateContext +static LONG ( WINAPI* _ImmGetCompositionString )( HIMC himc, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen ); +#define _ImmGetOpenStatus ImmGetOpenStatus +#define _ImmSetOpenStatus ImmSetOpenStatus +#define _ImmGetConversionStatus ImmGetConversionStatus +static DWORD ( WINAPI* _ImmGetCandidateList )( HIMC himc, DWORD deIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen ); +static LPINPUTCONTEXT2 ( WINAPI* _ImmLockIMC )( HIMC hIMC ); +static BOOL ( WINAPI* _ImmUnlockIMC )( HIMC hIMC ); +static LPVOID ( WINAPI* _ImmLockIMCC )( HIMCC hIMCC ); +static BOOL ( WINAPI* _ImmUnlockIMCC )( HIMCC hIMCC ); +#define _ImmGetDefaultIMEWnd ImmGetDefaultIMEWnd +#define _ImmGetIMEFileNameA ImmGetIMEFileNameA +#define _ImmGetVirtualKey ImmGetVirtualKey +#define _ImmNotifyIME ImmNotifyIME +#define _ImmSetConversionStatus ImmSetConversionStatus +#define _ImmSimulateHotKey ImmSimulateHotKey +#define _ImmIsIME ImmIsIME + +// private API provided by CHT IME. Available on version 6.0 or later. +UINT ( WINAPI*_GetReadingString )( HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, + BOOL* pfIsVertical, PUINT puMaxReadingLen ); +BOOL ( WINAPI*_ShowReadingWindow )( HIMC himc, BOOL bShow ); + +// Callbacks +void ( CALLBACK*ImeUiCallback_DrawRect )( int x1, int y1, int x2, int y2, DWORD color ); +void ( CALLBACK*ImeUiCallback_DrawFans )( const IMEUI_VERTEX* paVertex, UINT uNum ); +void* ( __cdecl*ImeUiCallback_Malloc )( size_t bytes ); +void ( __cdecl*ImeUiCallback_Free )( void* ptr ); +void ( CALLBACK*ImeUiCallback_OnChar )( WCHAR wc ); + +static void (*_SendCompString )(); +static LRESULT ( WINAPI* _SendMessage )( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) = SendMessageA; +static DWORD (* _GetCandidateList )( HIMC himc, DWORD dwIndex, LPCANDIDATELIST* ppCandList ); + +static HWND g_hwndMain; +static HWND g_hwndCurr; +static HIMC g_himcOrg; +static bool g_bImeEnabled = false; +static TCHAR g_szCompositionString[256]; +static BYTE g_szCompAttrString[256]; +static DWORD g_IMECursorBytes = 0; +static DWORD g_IMECursorChars = 0; +static TCHAR g_szCandidate[MAX_CANDLIST][MAX_CANDIDATE_LENGTH]; +static DWORD g_dwSelection, g_dwCount; +static UINT g_uCandPageSize; +static DWORD g_bDisableImeCompletely = false; +static DWORD g_dwIMELevel; +static DWORD g_dwIMELevelSaved; +static TCHAR g_szMultiLineCompString[ 256 *( 3 - sizeof( TCHAR ) ) ]; +static bool g_bReadingWindow = false; +static bool g_bHorizontalReading = false; +static bool g_bVerticalCand = true; +static UINT g_uCaretBlinkTime = 0; +static UINT g_uCaretBlinkLast = 0; +static bool g_bCaretDraw = false; +static bool g_bChineseIME; +static bool g_bInsertMode = true; +static TCHAR g_szReadingString[32]; // Used only in case of horizontal reading window +static int g_iReadingError; // Used only in case of horizontal reading window +static UINT g_screenWidth, g_screenHeight; +static DWORD g_dwPrevFloat; +static bool bIsSendingKeyMessage = false; +static OSVERSIONINFOA g_osi; +static bool g_bInitialized = false; +static bool g_bCandList = false; +static DWORD g_dwCandX, g_dwCandY; +static DWORD g_dwCaretX, g_dwCaretY; +static DWORD g_hCompChar; +static int g_iCandListIndexBase; +static DWORD g_dwImeUiFlags = IMEUI_FLAG_SUPPORT_CARET; +static bool g_bUILessMode = false; +static HMODULE g_hImmDll = NULL; + +#define IsNT() (g_osi.dwPlatformId == VER_PLATFORM_WIN32_NT) + +struct CompStringAttribute +{ + UINT caretX; + UINT caretY; + CImeUiFont_Base* pFont; + DWORD colorComp; + DWORD colorCand; + RECT margins; +}; + +static CompStringAttribute g_CaretInfo; +static DWORD g_dwState = IMEUI_STATE_OFF; +static DWORD swirl = 0; +static double lastSwirl; + +#define INDICATOR_NON_IME 0 +#define INDICATOR_CHS 1 +#define INDICATOR_CHT 2 +#define INDICATOR_KOREAN 3 +#define INDICATOR_JAPANESE 4 + +#define GETLANG() LOWORD(g_hklCurrent) +#define GETPRIMLANG() ((WORD)PRIMARYLANGID(GETLANG())) +#define GETSUBLANG() SUBLANGID(GETLANG()) + +#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) +#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) + +static HKL g_hklCurrent = 0; +static UINT g_uCodePage = 0; +static LPTSTR g_aszIndicator[] = +{ + TEXT( "A" ), +#ifdef UNICODE + L"\x7B80", + L"\x7E41", + L"\xac00", + L"\x3042", +#else + "\xd6\xd0", + "\xa4\xa4", + "\xb0\xa1", + "\x82\xa0", +#endif +}; +static LPTSTR g_pszIndicatior = g_aszIndicator[0]; + +static void GetReadingString( HWND hWnd ); +static DWORD GetImeId( UINT uIndex = 0 ); +static void CheckToggleState(); +static void DrawImeIndicator(); +static void DrawCandidateList(); +static void DrawCompositionString( bool bDrawCompAttr ); +static void GetReadingWindowOrientation( DWORD dwId ); +static void OnInputLangChangeWorker(); +static void OnInputLangChange(); +static void SetImeApi(); +static void CheckInputLocale(); +static void SetSupportLevel( DWORD dwImeLevel ); +void ImeUi_SetSupportLevel( DWORD dwImeLevel ); + + +// +// local helper functions +// +inline LRESULT SendKeyMsg( HWND hwnd, UINT msg, WPARAM wp ) +{ + bIsSendingKeyMessage = true; + LRESULT lRc = _SendMessage( hwnd, msg, wp, 1 ); + bIsSendingKeyMessage = false; + return lRc; +} +#define SendKeyMsg_DOWN(hwnd,vk) SendKeyMsg(hwnd, WM_KEYDOWN, vk) +#define SendKeyMsg_UP(hwnd,vk) SendKeyMsg(hwnd, WM_KEYUP, vk) + +/////////////////////////////////////////////////////////////////////////////// +// +// CTsfUiLessMode +// Handles IME events using Text Service Framework (TSF). Before Vista, +// IMM (Input Method Manager) API has been used to handle IME events and +// inqueries. Some IMM functions lose backward compatibility due to design +// of TSF, so we have to use new TSF interfaces. +// +/////////////////////////////////////////////////////////////////////////////// +class CTsfUiLessMode +{ +protected: + // Sink receives event notifications + class CUIElementSink : public ITfUIElementSink, + public ITfInputProcessorProfileActivationSink, + public ITfCompartmentEventSink + { + public: + CUIElementSink(); + ~CUIElementSink(); + + // IUnknown + STDMETHODIMP QueryInterface( REFIID riid, void** ppvObj ); + STDMETHODIMP_( ULONG ) + AddRef( void ); + STDMETHODIMP_( ULONG ) + Release( void ); + + // ITfUIElementSink + // Notifications for Reading Window events. We could process candidate as well, but we'll use IMM for simplicity sake. + STDMETHODIMP BeginUIElement( DWORD dwUIElementId, BOOL* pbShow ); + STDMETHODIMP UpdateUIElement( DWORD dwUIElementId ); + STDMETHODIMP EndUIElement( DWORD dwUIElementId ); + + // ITfInputProcessorProfileActivationSink + // Notification for keyboard input locale change + STDMETHODIMP OnActivated( DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, + REFGUID guidProfile, HKL hkl, DWORD dwFlags ); + + // ITfCompartmentEventSink + // Notification for open mode (toggle state) change + STDMETHODIMP OnChange( REFGUID rguid ); + + private: + LONG _cRef; + }; + + static void MakeReadingInformationString( ITfReadingInformationUIElement* preading ); + static void MakeCandidateStrings( ITfCandidateListUIElement* pcandidate ); + static ITfUIElement* GetUIElement( DWORD dwUIElementId ); + static BOOL GetCompartments( ITfCompartmentMgr** ppcm, ITfCompartment** ppTfOpenMode, + ITfCompartment** ppTfConvMode ); + static BOOL SetupCompartmentSinks( BOOL bResetOnly = FALSE, ITfCompartment* pTfOpenMode = NULL, + ITfCompartment* ppTfConvMode = NULL ); + + static ITfThreadMgrEx* m_tm; + static DWORD m_dwUIElementSinkCookie; + static DWORD m_dwAlpnSinkCookie; + static DWORD m_dwOpenModeSinkCookie; + static DWORD m_dwConvModeSinkCookie; + static CUIElementSink* m_TsfSink; + static int m_nCandidateRefCount; // Some IME shows multiple candidate lists but the Library doesn't support multiple candidate list. + // So track open / close events to make sure the candidate list opened last is shown. + CTsfUiLessMode() + { + } // this class can't be instanciated + +public: + static BOOL SetupSinks(); + static void ReleaseSinks(); + static BOOL CurrentInputLocaleIsIme(); + static void UpdateImeState( BOOL bResetCompartmentEventSink = FALSE ); + static void EnableUiUpdates( bool bEnable ); +}; + +ITfThreadMgrEx* CTsfUiLessMode::m_tm; +DWORD CTsfUiLessMode::m_dwUIElementSinkCookie = TF_INVALID_COOKIE; +DWORD CTsfUiLessMode::m_dwAlpnSinkCookie = TF_INVALID_COOKIE; +DWORD CTsfUiLessMode::m_dwOpenModeSinkCookie = TF_INVALID_COOKIE; +DWORD CTsfUiLessMode::m_dwConvModeSinkCookie = TF_INVALID_COOKIE; +CTsfUiLessMode::CUIElementSink* CTsfUiLessMode::m_TsfSink = NULL; +int CTsfUiLessMode::m_nCandidateRefCount = NULL; + +static unsigned long _strtoul( LPCSTR psz, LPTSTR*, int ) +{ + if( !psz ) + return 0; + + ULONG ulRet = 0; + if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) ) + { + psz += 2; + ULONG ul = 0; + while( *psz ) + { + if( '0' <= *psz && *psz <= '9' ) + ul = *psz - '0'; + else if( 'A' <= *psz && *psz <= 'F' ) + ul = *psz - 'A' + 10; + else if( 'a' <= *psz && *psz <= 'f' ) + ul = *psz - 'a' + 10; + else + break; + ulRet = ulRet * 16 + ul; + psz++; + } + } + else + { + while( *psz && ( '0' <= *psz && *psz <= '9' ) ) + { + ulRet = ulRet * 10 + ( *psz - '0' ); + psz++; + } + } + return ulRet; +} + +#ifdef UNICODE +#define GetCharCount(psz) lstrlen(psz) +#define GetCharCountFromBytes(psz,iBytes) (iBytes) +static void AW_SendCompString() +{ + int i, iLen; + if ( ImeUiCallback_OnChar ) + { + for ( i = 0; g_szCompositionString[i]; i++ ) + { + ImeUiCallback_OnChar( g_szCompositionString[i] ); + } + return; + } + + BYTE szCompStr[COUNTOF(g_szCompositionString) * 2]; + iLen = WideCharToMultiByte(g_uCodePage, 0, g_szCompositionString, -1, + (LPSTR)szCompStr, COUNTOF(szCompStr), NULL, NULL) - 1; // don't need to send NUL terminator; + for (i = 0; i < iLen; i++) + { + SendKeyMsg(g_hwndCurr, WM_CHAR, szCompStr[i]); + } +} + +// The following AW_Imm* functions are there to support Win95/98 first version. +// They can be deleted if the game doesn't supports them (i.e. games requires Win98 SE or later). +static DWORD AW_GetCandidateList(HIMC himc, DWORD dwIndex, LPCANDIDATELIST* ppCandList) +{ + DWORD dwBufLen = ImmGetCandidateListA( himc, dwIndex, NULL, 0 ); + if (dwBufLen) + { + LPCANDIDATELIST pCandList = (LPCANDIDATELIST)ImeUiCallback_Malloc(dwBufLen); + if (pCandList) { + dwBufLen = ImmGetCandidateListA( himc, dwIndex, pCandList, dwBufLen ); + if (dwBufLen) { + int i; + int wideBufLen = 0; + for (i = 0; i < (int)pCandList->dwCount; i++) { + wideBufLen += MultiByteToWideChar(g_uCodePage, 0, (LPSTR)pCandList + pCandList->dwOffset[i], -1, NULL, 0) * sizeof(WCHAR); + } + wideBufLen += pCandList->dwOffset[0]; + *ppCandList = (LPCANDIDATELIST)ImeUiCallback_Malloc(wideBufLen); + LPCANDIDATELIST pCandListW = *ppCandList; + memcpy(pCandListW, pCandList, pCandList->dwOffset[0]); + LPWSTR pwz = (LPWSTR)((LPSTR)pCandListW + pCandList->dwOffset[0]); + for (i = 0; i < (int)pCandList->dwCount; i++) { + pCandListW->dwOffset[i] = (LPSTR)pwz - (LPSTR)pCandListW; + pwz += MultiByteToWideChar(g_uCodePage, 0, (LPSTR)pCandList + pCandList->dwOffset[i], -1, pwz, 256); + } + dwBufLen = wideBufLen; + } + ImeUiCallback_Free(pCandList); + } + } + return dwBufLen; +} + +static LONG WINAPI AW_ImmGetCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) +{ + char pszMb[COUNTOF(g_szCompositionString) * 2]; + DWORD dwRet = ImmGetCompositionStringA(himc, dwIndex, pszMb, sizeof(pszMb)); + switch (dwIndex) { + case GCS_RESULTSTR: + case GCS_COMPSTR: + if (dwRet) { + pszMb[dwRet] = 0; + dwRet = (DWORD)MultiByteToWideChar(g_uCodePage, 0, pszMb, -1, (LPWSTR)lpBuf, dwBufLen); + if (dwRet) { + // Note that ImmGetCompositionString() returns number of bytes copied, regardless of the width of character. + dwRet = (dwRet - 1) * sizeof(WCHAR); + } + } + break; + case GCS_CURSORPOS: + dwRet /= 2; + break; + case GCS_COMPATTR: { + char pszMb2[COUNTOF(g_szCompositionString) * 2]; + DWORD dwRet2 = ImmGetCompositionStringA(himc, GCS_COMPSTR, pszMb2, sizeof(pszMb2)); + if (!dwRet2) { + dwRet2 = ImmGetCompositionStringA(himc, GCS_RESULTSTR, pszMb2, sizeof(pszMb2)); + if (!dwRet2) { + return 0; + } + } + char* pOut = (char*)lpBuf; + for (DWORD i = 0; i < dwRet; i++) { + *pOut++ = pszMb[i]; // copy attribute + if (_IsLeadByte(pszMb2[i])) + i++; + } + dwRet = pOut - (char*)lpBuf; + } + break; + } + return dwRet; +} + +#else // !UNICODE +// returns number of characters from number of bytes +static int GetCharCountFromBytes( LPCSTR pszString, int iBytes ) +{ + int iCount = 0; + int i; + for( i = 0; pszString[i] && i < iBytes; i++ ) + { + iCount++; + if( _IsLeadByte(pszString[i]) ) + i++; + } + if( i != iBytes ) + iCount = -iCount; // indicate error - iBytes specifies wrong boundary (i.e. the last byte is leadbyte) + return iCount; +} + +static int GetCharCount( LPTSTR psz ) +{ + int i = 0; + while( *psz ) + { + if( _IsLeadByte(*psz) ) + { + psz++; + } + psz++; + i++; + } + return i; +} + +static DWORD WA_GetCandidateList( HIMC himc, DWORD dwIndex, LPCANDIDATELIST* ppCandList ) +{ + DWORD dwBufLen = ImmGetCandidateListW( himc, dwIndex, NULL, 0 ); + if( dwBufLen ) + { + LPCANDIDATELIST pCandList = ( LPCANDIDATELIST )ImeUiCallback_Malloc( dwBufLen ); + if( pCandList ) + { + dwBufLen = ImmGetCandidateListW( himc, dwIndex, pCandList, dwBufLen ); + if( dwBufLen ) + { + int i; + int mbBufLen = 0; + for( i = 0; i < ( int )pCandList->dwCount; i++ ) + { + mbBufLen += WideCharToMultiByte( g_uCodePage, 0, ( LPWSTR )( ( LPSTR )pCandList + + pCandList->dwOffset[i] ), -1, NULL, 0, + NULL, NULL ); + } + mbBufLen += pCandList->dwOffset[0]; + *ppCandList = ( LPCANDIDATELIST )ImeUiCallback_Malloc( mbBufLen ); + LPCANDIDATELIST pCandListA = *ppCandList; + memcpy( pCandListA, pCandList, pCandList->dwOffset[0] ); + LPSTR psz = ( LPSTR )pCandListA + pCandList->dwOffset[0]; + for( i = 0; i < ( int )pCandList->dwCount; i++ ) + { + pCandListA->dwOffset[i] = ( LPSTR )psz - ( LPSTR )pCandListA; + psz += WideCharToMultiByte( g_uCodePage, 0, ( LPWSTR )( ( LPSTR )pCandList + + pCandList->dwOffset[i] ), -1, psz, 256, + NULL, NULL ); + } + dwBufLen = mbBufLen; + } + ImeUiCallback_Free( pCandList ); + } + } + return dwBufLen; +} + +static LONG WINAPI WA_ImmGetCompositionString( HIMC himc, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen ) +{ + WCHAR pwzUc[COUNTOF(g_szCompositionString)]; + DWORD dwRet = ImmGetCompositionStringW( himc, dwIndex, pwzUc, sizeof( pwzUc ) ); + switch( dwIndex ) + { + case GCS_RESULTSTR: + case GCS_COMPSTR: + if( dwRet ) + { + pwzUc[dwRet / sizeof( WCHAR )] = 0; + dwRet = ( DWORD )WideCharToMultiByte( g_uCodePage, 0, pwzUc, -1, ( LPSTR )lpBuf, dwBufLen, NULL, + NULL ); + if( dwRet ) + { + dwRet = dwRet - 1; + } + } + break; + + case GCS_CURSORPOS: + { + WCHAR pwzUc2[COUNTOF(g_szCompositionString)]; + DWORD dwRet2 = ImmGetCompositionStringW( himc, GCS_COMPSTR, pwzUc2, sizeof( pwzUc2 ) ); + if( !dwRet2 ) + { + dwRet2 = ImmGetCompositionStringW( himc, GCS_RESULTSTR, pwzUc2, sizeof( pwzUc2 ) ); + if( !dwRet2 ) + { + return 0; + } + } + dwRet2 /= 2; + //The return value of WideCharToMultiByte() should probably be checked/asserted for success. + //bounds violation (overflow) 'pszMb[iRc]' + const int bufSize = COUNTOF(g_szCompositionString) * 2; + char pszMb[bufSize]; + int iRc = WideCharToMultiByte( g_uCodePage, 0, pwzUc2, dwRet2, pszMb, sizeof( pszMb ), NULL, NULL ); + assert( iRc > 0 ); //WideCharToMultiByte returns 0 if it failed, and it should *never* be negative in the first place + if( iRc >= bufSize ) //if we wrote more bytes than the length of the buffer, we need to terminate it + { + pszMb[ bufSize - 1] = 0; //0 terminate the end of the buffer + } + else + { + pszMb[ iRc ] = 0; + } + char* psz = pszMb; + for( dwRet2 = 0; dwRet2 != dwRet; dwRet2++ ) + { + if( _IsLeadByte( *psz ) ) + psz++; + psz++; + } + dwRet = psz - pszMb; + } + break; + + case GCS_COMPATTR: + { + WCHAR pwzUc2[COUNTOF(g_szCompositionString)]; + DWORD dwRet2 = ImmGetCompositionStringW( himc, GCS_COMPSTR, pwzUc2, sizeof( pwzUc2 ) ); + if( !dwRet2 ) + { + dwRet2 = ImmGetCompositionStringW( himc, GCS_RESULTSTR, pwzUc2, sizeof( pwzUc2 ) ); + if( !dwRet2 ) + { + return 0; + } + } + dwRet2 /= 2; + const int bufSize = COUNTOF(g_szCompositionString) * 2; + char pszMb[bufSize]; + int iRc = WideCharToMultiByte( g_uCodePage, 0, pwzUc2, dwRet2, pszMb, sizeof( pszMb ), NULL, NULL ); + assert( iRc > 0 ); //WideCharToMultiByte returns 0 if it failed, and it should *never* be negative in the first place + if( iRc >= bufSize ) //if we wrote more bytes than the length of the buffer, we need to terminate it + { + pszMb[ bufSize - 1] = 0; //0 terminate the end of the buffer + } + else + { + pszMb[ iRc ] = 0; + } + char* pSrc = ( char* )pwzUc; + char* pOut = ( char* )lpBuf; + for( char* psz = pszMb; *psz; psz++, pSrc++ ) + { + *pOut++ = *pSrc; // copy attribute + if( _IsLeadByte( *psz ) ) + { + *pOut++ = *pSrc; + psz++; + } + // buffer overrun protection, pOut is incremented in the loop, but not part of the + // loop invariant test. To make the code more readable we have a test rather than + // rolling this into the for stmt. + if( ( DWORD )( pOut - ( char* )lpBuf ) >= dwBufLen ) + break; + } + dwRet = pOut - ( char* )lpBuf; + } + break; + } + return dwRet; +} + +#endif // UNICODE + +static void ComposeCandidateLine( int index, LPCTSTR pszCandidate ) +{ + LPTSTR psz = g_szCandidate[index]; + *psz++ = ( TCHAR )( TEXT( '0' ) + ( ( index + g_iCandListIndexBase ) % 10 ) ); + if( g_bVerticalCand ) + { + *psz++ = TEXT( ' ' ); + } + while( *pszCandidate && ( COUNTOF(g_szCandidate[index]) > ( psz - g_szCandidate[index] ) ) ) + { + *psz++ = *pszCandidate++; + } + *psz = 0; +} + +static void SendCompString() +{ + int i, iLen = lstrlen( g_szCompositionString ); + if( ImeUiCallback_OnChar ) + { + LPCWSTR pwz; +#ifdef UNICODE + pwz = g_szCompositionString; +#else + WCHAR szUnicode[COUNTOF( g_szCompositionString ) ]; + pwz = szUnicode; + iLen = MultiByteToWideChar( g_uCodePage, 0, g_szCompositionString, -1, szUnicode, COUNTOF(szUnicode) ) - 1; +#endif + for( i = 0; i < iLen; i++ ) + { + ImeUiCallback_OnChar( pwz[i] ); + } + return; + } + for( i = 0; i < iLen; i++ ) + { + SendKeyMsg( g_hwndCurr, WM_CHAR, +#ifdef UNICODE + (WPARAM)g_szCompositionString[i] +#else + ( WPARAM )( BYTE )g_szCompositionString[i] +#endif + ); + } +} + +static DWORD GetCandidateList( HIMC himc, DWORD dwIndex, LPCANDIDATELIST* ppCandList ) +{ + DWORD dwBufLen = _ImmGetCandidateList( himc, dwIndex, NULL, 0 ); + if( dwBufLen ) + { + *ppCandList = ( LPCANDIDATELIST )ImeUiCallback_Malloc( dwBufLen ); + dwBufLen = _ImmGetCandidateList( himc, dwIndex, *ppCandList, dwBufLen ); + } + return dwBufLen; +} + +static void SendControlKeys( UINT vk, UINT num ) +{ + if( num == 0 ) + return; + for( UINT i = 0; i < num; i++ ) + { + SendKeyMsg_DOWN(g_hwndCurr, vk); + } + SendKeyMsg_UP(g_hwndCurr, vk); +} + +// send key messages to erase composition string. +static void CancelCompString( HWND hwnd, bool bUseBackSpace = true, int iNewStrLen = 0 ) +{ + if( g_dwIMELevel != 3 ) + return; + int cc = GetCharCount( g_szCompositionString ); + int i; + // move caret to the end of composition string + SendControlKeys( VK_RIGHT, cc - g_IMECursorChars ); + + if( bUseBackSpace || g_bInsertMode ) + iNewStrLen = 0; + + // The caller sets bUseBackSpace to false if there's possibility of sending + // new composition string to the app right after this function call. + // + // If the app is in overwriting mode and new comp string is + // shorter than current one, delete previous comp string + // till it's same long as the new one. Then move caret to the beginning of comp string. + // New comp string will overwrite old one. + if( iNewStrLen < cc ) + { + for( i = 0; i < cc - iNewStrLen; i++ ) + { + SendKeyMsg_DOWN(hwnd, VK_BACK); + SendKeyMsg( hwnd, WM_CHAR, 8 ); //Backspace character + } + SendKeyMsg_UP(hwnd, VK_BACK); + } + else + iNewStrLen = cc; + + SendControlKeys( VK_LEFT, iNewStrLen ); +} + +// initialize composition string data. +static void InitCompStringData( void ) +{ + g_IMECursorBytes = 0; + g_IMECursorChars = 0; + memset( &g_szCompositionString, 0, sizeof( g_szCompositionString ) ); + memset( &g_szCompAttrString, 0, sizeof( g_szCompAttrString ) ); +} + +static void DrawCaret( DWORD x, DWORD y, DWORD height ) +{ + if( g_bCaretDraw && ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( x, y + gSkinIME.caretYMargin, x + gSkinIME.caretWidth, + y + height - gSkinIME.caretYMargin, g_CaretInfo.colorComp ); +} + +// +// Apps that draw the composition string on top of composition string attribute +// in level 3 support should call this function twice in rendering a frame. +// // Draw edit box UI; +// ImeUi_RenderUI(true, false); // paint composition string attribute; +// // Draw text in the edit box; +// ImeUi_RenderUi(false, true); // paint the rest of IME UI; +// +void ImeUi_RenderUI( bool bDrawCompAttr, bool bDrawOtherUi ) +{ + if( !g_bInitialized || !g_bImeEnabled || !g_CaretInfo.pFont ) + return; + if( !bDrawCompAttr && !bDrawOtherUi ) + return; // error case + if( g_dwIMELevel == 2 ) + { + if( !bDrawOtherUi ) + return; // 1st call for level 3 support + } + + if( bDrawOtherUi ) + DrawImeIndicator(); + + DrawCompositionString( bDrawCompAttr ); + + if( bDrawOtherUi ) + DrawCandidateList(); +} + +static void DrawImeIndicator() +{ + bool bOn = g_dwState != IMEUI_STATE_OFF; + + IMEUI_VERTEX PieData[17]; + float SizeOfPie = ( float )gSkinIME.symbolHeight; + + memset( PieData, 0, sizeof( PieData ) ); + + switch( gSkinIME.symbolPlacement ) + { + case 0: // vertical centering IME indicator + { + if( SizeOfPie + g_CaretInfo.margins.right + 4 > g_screenWidth ) + { + PieData[0].sx = ( -SizeOfPie / 2 ) + g_CaretInfo.margins.left - 4; + PieData[0].sy = ( float )g_CaretInfo.margins.top + ( g_CaretInfo.margins.bottom - + g_CaretInfo.margins.top ) / 2; + } + else + { + PieData[0].sx = -( SizeOfPie / 2 ) + g_CaretInfo.margins.right + gSkinIME.symbolHeight + 4; + PieData[0].sy = ( float )g_CaretInfo.margins.top + ( g_CaretInfo.margins.bottom - + g_CaretInfo.margins.top ) / 2; + } + break; + } + case 1: // upperleft + PieData[0].sx = 4 + ( SizeOfPie / 2 ); + PieData[0].sy = 4 + ( SizeOfPie / 2 ); + break; + case 2: // upperright + PieData[0].sx = g_screenWidth - ( 4 + ( SizeOfPie / 2 ) ); + PieData[0].sy = 4 + ( SizeOfPie / 2 ); + break; + case 3: // lowerright + PieData[0].sx = g_screenWidth - ( 4 + ( SizeOfPie / 2 ) ); + PieData[0].sy = g_screenHeight - ( 4 + ( SizeOfPie / 2 ) ); + break; + case 4: // lowerleft + PieData[0].sx = 4 + ( SizeOfPie / 2 ); + PieData[0].sy = g_screenHeight - ( 4 + ( SizeOfPie / 2 ) ); + break; + } + PieData[0].rhw = 1.0f; + if( bOn ) + { + if( GetTickCount() - lastSwirl > 250 ) + { + swirl++; + lastSwirl = GetTickCount(); + if( swirl > 13 ) + swirl = 0; + } + } + else + swirl = 0; + for( int t1 = 1; t1 < 16; t1++ ) + { + float radian = 2.0f * 3.1415926f * ( t1 - 1 + ( bOn * swirl ) ) / 14.0f; + PieData[t1].sx = ( float )( PieData[0].sx + SizeOfPie / 2 * cos( radian ) ); + PieData[t1].sy = ( float )( PieData[0].sy + SizeOfPie / 2 * sin( radian ) ); + PieData[t1].rhw = 1.0f; + } + + PieData[0].color = 0xffffff + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + if( !gSkinIME.symbolColor && bOn ) + { + { + PieData[1].color = 0xff0000 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[2].color = 0xff3000 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[3].color = 0xff6000 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[4].color = 0xff9000 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[5].color = 0xffC000 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[6].color = 0xffff00 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[7].color = 0xC0ff00 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[8].color = 0x90ff00 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[9].color = 0x60ff00 + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[10].color = 0x30c0ff + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[11].color = 0x00a0ff + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[12].color = 0x3090ff + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[13].color = 0x6060ff + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[14].color = 0x9030ff + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + PieData[15].color = 0xc000ff + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + } + } + else + { + DWORD dwColor = bOn ? gSkinIME.symbolColor : gSkinIME.symbolColorOff; + for( int t1 = 1; t1 < 16; t1++ ) + { + PieData[t1].color = dwColor + ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ); + } + } + PieData[16] = PieData[1]; + + if( ImeUiCallback_DrawFans ) + ImeUiCallback_DrawFans( PieData, 17 ); + + float fHeight = gSkinIME.symbolHeight * 0.625f; + + // fix for Ent Gen #120 - reduce the height of character when Korean IME is on + if( GETPRIMLANG() == LANG_KOREAN && bOn ) + { + fHeight *= 0.8f; + } + + if( gSkinIME.symbolFont ) + { +#ifdef DS2 + // save the font height here since DS2 shares editbox font and indicator font + DWORD _w, _h; + g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h ); +#endif //DS2 + + // GOS deals height in points that is 1/72nd inch and assumes display device is 96dpi. + fHeight = fHeight * 96 / 72; + gSkinIME.symbolFont->SetHeight( ( UINT )fHeight ); + gSkinIME.symbolFont->SetColor( ( ( ( DWORD )gSkinIME.symbolTranslucence ) << 24 ) | gSkinIME.symbolColorText ); + + // + // draw the proper symbol over the fan + // + DWORD w, h; + LPCTSTR cszSymbol = ( g_dwState == IMEUI_STATE_ON ) ? g_pszIndicatior : g_aszIndicator[0]; + + gSkinIME.symbolFont->GetTextExtent( cszSymbol, &w, &h ); + gSkinIME.symbolFont->SetPosition( ( int )( PieData[0].sx ) - w / 2, ( int )( PieData[0].sy ) - h / 2 ); + gSkinIME.symbolFont->DrawText( cszSymbol ); + +#ifdef DS2 + // revert the height. + g_CaretInfo.pFont->SetHeight( _h ); + + // Double-check: Confirm match by testing a range of font heights to find best fit + DWORD _h2; + g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h2 ); + if ( _h2 < _h ) + { + for ( int i=1; _h2<_h && i<10; i++ ) + { + g_CaretInfo.pFont->SetHeight( _h+i ); + g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h2 ); + } + } + else if ( _h2 > _h ) + { + for ( int i=1; _h2>_h && i<10; i++ ) + { + g_CaretInfo.pFont->SetHeight( _h-i ); + g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h2 ); + } + } +#endif //DS2 + } +} + +static void DrawCompositionString( bool bDrawCompAttr ) +{ + // Process timer for caret blink + UINT uCurrentTime = GetTickCount(); + if( uCurrentTime - g_uCaretBlinkLast > g_uCaretBlinkTime ) + { + g_uCaretBlinkLast = uCurrentTime; + g_bCaretDraw = !g_bCaretDraw; + } + + int i = 0; + + g_CaretInfo.pFont->SetColor( g_CaretInfo.colorComp ); + + DWORD uDummy; + + int len = lstrlen( g_szCompositionString ); + + DWORD bgX = g_CaretInfo.caretX; + DWORD bgY = g_CaretInfo.caretY; + g_dwCaretX = POSITION_UNINITIALIZED; + g_dwCaretY = POSITION_UNINITIALIZED; + DWORD candX = POSITION_UNINITIALIZED; + DWORD candY = 0; + LPTSTR pszMlcs = g_szMultiLineCompString; + + DWORD wCompChar = 0; + DWORD hCompChar = 0; + g_CaretInfo.pFont->GetTextExtent( TEXT( " " ), &uDummy, &hCompChar ); + if( g_dwIMELevel == 3 && g_IMECursorBytes && g_szCompositionString[0] ) + { + // shift starting point of drawing composition string according to the current caret position. + TCHAR temp = g_szCompositionString[g_IMECursorBytes]; + g_szCompositionString[g_IMECursorBytes] = 0; + g_CaretInfo.pFont->GetTextExtent( g_szCompositionString, &wCompChar, &hCompChar ); + g_szCompositionString[g_IMECursorBytes] = temp; + bgX -= wCompChar; + } + + // + // Draw the background colors for IME text nuggets + // + bool saveCandPos = false; + DWORD cType = 1; + LPTSTR pszCurrentCompLine = g_szCompositionString; + DWORD dwCompLineStart = bgX; + DWORD bgXnext = bgX; + + if( GETPRIMLANG() != LANG_KOREAN || g_bCaretDraw ) // Korean uses composition attribute as blinking block caret + for( i = 0; i < len; i += cType ) + { + DWORD bgColor = 0x00000000; + TCHAR szChar[3]; + szChar[0] = g_szCompositionString[i]; + szChar[1] = szChar[2] = 0; +#ifndef UNICODE + cType = 1 + ( ( _IsLeadByte(g_szCompositionString[i]) ) ? 1 : 0 ); + if( cType == 2 && g_szCompositionString[i + 1] ) // in case we have 0 in trailbyte, we don't count it. + szChar[1] = g_szCompositionString[i + 1]; +#endif + bgX = bgXnext; + TCHAR cSave = g_szCompositionString[i + cType]; + g_szCompositionString[i + cType] = 0; + g_CaretInfo.pFont->GetTextExtent( pszCurrentCompLine, &bgXnext, &hCompChar ); + g_szCompositionString[i + cType] = cSave; + bgXnext += dwCompLineStart; + wCompChar = bgXnext - bgX; + + switch( g_szCompAttrString[i] ) + { + case ATTR_INPUT: + bgColor = gSkinCompStr.colorInput; + break; + case ATTR_TARGET_CONVERTED: + bgColor = gSkinCompStr.colorTargetConv; + if( IMEID_LANG( GetImeId() ) != LANG_CHS ) + saveCandPos = true; + break; + case ATTR_CONVERTED: + bgColor = gSkinCompStr.colorConverted; + break; + case ATTR_TARGET_NOTCONVERTED: + // + // This is the one the user is working with currently + // + bgColor = gSkinCompStr.colorTargetNotConv; + break; + case ATTR_INPUT_ERROR: + bgColor = gSkinCompStr.colorInputErr; + break; + default: + // STOP( TEXT( "Attributes on IME characters are wrong" ) ); + break; + } + + if( g_dwIMELevel == 3 && bDrawCompAttr ) + { + if( ( LONG )bgX >= g_CaretInfo.margins.left && ( LONG )bgX <= g_CaretInfo.margins.right ) + { + if( g_dwImeUiFlags & IMEUI_FLAG_SUPPORT_CARET ) + { + if( ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( bgX, bgY, bgX + wCompChar, bgY + hCompChar, bgColor ); + } + else + { + if( ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( bgX - wCompChar, bgY, bgX, bgY + hCompChar, bgColor ); + } + } + } + else if( g_dwIMELevel == 2 ) + { + // make sure enough buffer space (possible space, NUL for current line, possible DBCS, 2 more NUL) + // are available in multiline composition string buffer + bool bWrite = ( pszMlcs - g_szMultiLineCompString < + COUNTOF( g_szMultiLineCompString ) - 5 * ( 3 - sizeof( TCHAR ) ) ); + + if( ( LONG )( bgX + wCompChar ) >= g_CaretInfo.margins.right ) + { + bgX = dwCompLineStart = bgXnext = g_CaretInfo.margins.left; + bgY = bgY + hCompChar; + pszCurrentCompLine = g_szCompositionString + i; + if( bWrite ) + { + if( pszMlcs == g_szMultiLineCompString || pszMlcs[-1] == 0 ) + *pszMlcs++ = ' '; // to avoid zero length line + *pszMlcs++ = 0; + } + } + if( ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( bgX, bgY, bgX + wCompChar, bgY + hCompChar, bgColor ); + if( bWrite ) + { + *pszMlcs++ = g_szCompositionString[i]; +#ifndef UNICODE + if( cType == 2 ) + *pszMlcs++ = g_szCompositionString[i + 1]; +#endif + } + if( ( DWORD )i == g_IMECursorBytes ) + { + g_dwCaretX = bgX; + g_dwCaretY = bgY; + } + } + if( ( saveCandPos && candX == POSITION_UNINITIALIZED ) || + ( IMEID_LANG( GetImeId() ) == LANG_CHS && i / ( 3 - sizeof( TCHAR ) ) == ( int )g_IMECursorChars ) ) + { + candX = bgX; + candY = bgY; + } + saveCandPos = false; + } + + bgX = bgXnext; + if( g_dwIMELevel == 2 ) + { + // in case the caret in composition string is at the end of it, draw it here + if( len != 0 && ( DWORD )i == g_IMECursorBytes ) + { + g_dwCaretX = bgX; + g_dwCaretY = bgY; + } + + // Draw composition string. + //assert(pszMlcs - g_szMultiLineCompString <= + // sizeof(g_szMultiLineCompString) / sizeof(g_szMultiLineCompString[0]) - 2); + *pszMlcs++ = 0; + *pszMlcs++ = 0; + DWORD x, y; + x = g_CaretInfo.caretX; + y = g_CaretInfo.caretY; + pszMlcs = g_szMultiLineCompString; + while( *pszMlcs && + pszMlcs - g_szMultiLineCompString < sizeof( g_szMultiLineCompString ) / sizeof + ( g_szMultiLineCompString[0] ) ) + { + g_CaretInfo.pFont->SetPosition( x, y ); + g_CaretInfo.pFont->DrawText( pszMlcs ); + pszMlcs += lstrlen( pszMlcs ) + 1; + x = g_CaretInfo.margins.left; + y += hCompChar; + } + } + // for changing z-order of caret + if( g_dwCaretX != POSITION_UNINITIALIZED && g_dwCaretY != POSITION_UNINITIALIZED ) + { + DrawCaret( g_dwCaretX, g_dwCaretY, hCompChar ); + } + g_dwCandX = candX; + g_dwCandY = candY; + g_hCompChar = hCompChar; +} + +static void DrawCandidateList() +{ + DWORD candX = g_dwCandX; + DWORD candY = g_dwCandY; + DWORD hCompChar = g_hCompChar; + int i; + + // draw candidate list / reading window + if( !g_dwCount || g_szCandidate[0][0] == 0 ) + { + return; + } + + // If position of candidate list is not initialized yet, set it here. + if( candX == POSITION_UNINITIALIZED ) + { + // CHT IME in Vista doesn't have ATTR_TARGET_CONVERTED attribute while typing, + // so display the candidate list near the caret in the composition string + if( GETLANG() == LANG_CHT && GetImeId() != 0 && g_dwCaretX != POSITION_UNINITIALIZED ) + { + candX = g_dwCaretX; + candY = g_dwCaretY; + } + else + { + candX = g_CaretInfo.caretX; + candY = g_CaretInfo.caretY; + } + } + + SIZE largest = + { + 0,0 + }; + + static DWORD uDigitWidth = 0; + DWORD uSpaceWidth = 0; + static DWORD uDigitWidthList[10]; + static CImeUiFont_Base* pPrevFont = NULL; + // find out the widest width of the digits + if( pPrevFont != g_CaretInfo.pFont ) + { + pPrevFont = g_CaretInfo.pFont; + for( int cnt = 0; cnt <= 9; cnt++ ) + { + DWORD uDW = 0; + DWORD uDH = 0; + TCHAR ss[8]; + swprintf_s( ss, COUNTOF(ss), TEXT( "%d" ), cnt ); + g_CaretInfo.pFont->GetTextExtent( ss, &uDW, &uDH ); + uDigitWidthList[cnt] = uDW; + if( uDW > uDigitWidth ) + uDigitWidth = uDW; + if( ( signed )uDH > largest.cy ) + largest.cy = uDH; + } + } + uSpaceWidth = uDigitWidth; + DWORD dwMarginX = ( uSpaceWidth + 1 ) / 2; + DWORD adwCandWidth[ MAX_CANDLIST ]; + + // Find out the widest width of the candidate strings + DWORD dwCandWidth = 0; + if( g_bReadingWindow && g_bHorizontalReading ) + g_CaretInfo.pFont->GetTextExtent( g_szReadingString, ( DWORD* )&largest.cx, ( DWORD* )&largest.cy ); + else + { + for( i = 0; g_szCandidate[i][0] && i < ( int )g_uCandPageSize; i++ ) + { + DWORD tx = 0; + DWORD ty = 0; + + if( g_bReadingWindow ) + g_CaretInfo.pFont->GetTextExtent( g_szCandidate[i], &tx, &ty ); + else + { + if( g_bVerticalCand ) + g_CaretInfo.pFont->GetTextExtent( g_szCandidate[i] + 2, &tx, &ty ); + else + g_CaretInfo.pFont->GetTextExtent( g_szCandidate[i] + 1, &tx, &ty ); + tx = tx + uDigitWidth + uSpaceWidth; + } + + if( ( signed )tx > largest.cx ) + largest.cx = tx; + if( ( signed )ty > largest.cy ) + largest.cy = ty; + adwCandWidth[ i ] = tx; + dwCandWidth += tx; + } + } + + DWORD slotsUsed; + if( g_bReadingWindow && g_dwCount < g_uCandPageSize ) + slotsUsed = g_dwCount; + else + slotsUsed = g_uCandPageSize; + + // Show candidate list above composition string if there isn't enough room below. + DWORD dwCandHeight; + if( g_bVerticalCand && !( g_bReadingWindow && g_bHorizontalReading ) ) + dwCandHeight = slotsUsed * largest.cy + 2; + else + dwCandHeight = largest.cy + 2; + if( candY + hCompChar + dwCandHeight > g_screenHeight ) + candY -= dwCandHeight; + else + candY += hCompChar; + if( ( int )candY < 0 ) + candY = 0; + + // Move candidate list horizontally to keep it inside of screen + if( !g_bReadingWindow && IMEID_LANG( GetImeId() ) == LANG_CHS ) + dwCandWidth += dwMarginX * ( slotsUsed - 1 ); + else if( g_bReadingWindow && g_bHorizontalReading ) + dwCandWidth = largest.cx + 2 + dwMarginX * 2; + else if( g_bVerticalCand || g_bReadingWindow ) + dwCandWidth = largest.cx + 2 + dwMarginX * 2; + else + dwCandWidth = slotsUsed * ( largest.cx + 1 ) + 1; + if( candX + dwCandWidth > g_screenWidth ) + candX = g_screenWidth - dwCandWidth; + if( ( int )candX < 0 ) + candX = 0; + + // Draw frame and background of candidate list / reading window + int seperateLineX = 0; + int left = candX; + int top = candY; + int right = candX + dwCandWidth; + int bottom = candY + dwCandHeight; + if( ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( left, top, right, bottom, gSkinIME.candColorBorder ); + left++; + top++; + right--; + bottom--; + if( g_bReadingWindow || IMEID_LANG( GetImeId() ) == LANG_CHS ) + { + if( ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( left, top, right, bottom, gSkinIME.candColorBase ); + } + else if( g_bVerticalCand ) + { + // uDigitWidth is the max width of all digits. + if( !g_bReadingWindow ) + { + seperateLineX = left + dwMarginX + uDigitWidth + uSpaceWidth / 2; + if( ImeUiCallback_DrawRect ) + { + ImeUiCallback_DrawRect( left, top, seperateLineX - 1, bottom, gSkinIME.candColorBase ); + ImeUiCallback_DrawRect( seperateLineX, top, right, bottom, gSkinIME.candColorBase ); + } + } + } + else + { + for( i = 0; ( DWORD )i < slotsUsed; i++ ) + { + if( ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( left, top, left + largest.cx, bottom, gSkinIME.candColorBase ); + left += largest.cx + 1; + } + } + + // Draw candidates / reading strings + candX++; + candY++; + if( g_bReadingWindow && g_bHorizontalReading ) + { + int iStart = -1, iEnd = -1, iDummy; + candX += dwMarginX; + + // draw background of error character if it exists + TCHAR szTemp[COUNTOF( g_szReadingString ) ]; + if( g_iReadingError >= 0 ) + { + StringCchCopy( szTemp, COUNTOF(szTemp), g_szReadingString ); + LPTSTR psz = szTemp + g_iReadingError; +#ifdef UNICODE + psz++; +#else + psz += ( _IsLeadByte( szTemp[g_iReadingError] ) ) ? 2 : 1; +#endif + *psz = 0; + g_CaretInfo.pFont->GetTextExtent( szTemp, ( DWORD* )&iEnd, ( DWORD* )&iDummy ); + TCHAR cSave = szTemp[ g_iReadingError ]; + szTemp[g_iReadingError] = 0; + g_CaretInfo.pFont->GetTextExtent( szTemp, ( DWORD* )&iStart, ( DWORD* )&iDummy ); + szTemp[g_iReadingError] = cSave; + if( ImeUiCallback_DrawRect ) + ImeUiCallback_DrawRect( candX + iStart, candY, candX + iEnd, candY + largest.cy, + gSkinIME.candColorBorder ); + } + + g_CaretInfo.pFont->SetPosition( candX, candY ); + g_CaretInfo.pFont->SetColor( g_CaretInfo.colorCand ); + g_CaretInfo.pFont->DrawText( g_szReadingString ); + + // draw error character if it exists + if( iStart >= 0 ) + { + g_CaretInfo.pFont->SetPosition( candX + iStart, candY ); + if( gSkinIME.candColorBase != 0xffffffff || gSkinIME.candColorBorder != 0xff000000 ) + g_CaretInfo.pFont->SetColor( g_CaretInfo.colorCand ); + else + g_CaretInfo.pFont->SetColor( 0xff000000 + ( ~( ( 0x00ffffff ) & g_CaretInfo.colorCand ) ) ); + g_CaretInfo.pFont->DrawText( szTemp + g_iReadingError ); + } + } + else + { + for( i = 0; i < ( int )g_uCandPageSize && ( DWORD )i < g_dwCount; i++ ) + { + if( g_dwSelection == ( DWORD )i ) + { + if( gSkinIME.candColorBase != 0xffffffff || gSkinIME.candColorBorder != 0xff000000 ) + g_CaretInfo.pFont->SetColor( g_CaretInfo.colorCand ); + else + g_CaretInfo.pFont->SetColor( 0xff000000 + ( ~( ( 0x00ffffff ) & g_CaretInfo.colorCand ) ) ); + + if( ImeUiCallback_DrawRect ) + { + if( g_bReadingWindow || g_bVerticalCand ) + ImeUiCallback_DrawRect( candX, candY + i * largest.cy, + candX - 1 + dwCandWidth, candY + ( i + 1 ) * largest.cy, + gSkinIME.candColorBorder ); + else + ImeUiCallback_DrawRect( candX, candY, + candX + adwCandWidth[i], candY + largest.cy, + gSkinIME.candColorBorder ); + } + } + else + g_CaretInfo.pFont->SetColor( g_CaretInfo.colorCand ); + if( g_szCandidate[i][0] != 0 ) + { + if( !g_bReadingWindow && g_bVerticalCand ) + { + TCHAR szOneDigit[2] = + { + g_szCandidate[i][0], 0 + }; + int nOneDigit = g_szCandidate[i][0] - TEXT( '0' ); + TCHAR* szCandidateBody = g_szCandidate[i] + 2; + + int dx = candX + ( seperateLineX - candX - uDigitWidthList[nOneDigit] ) / 2; + int dy = candY + largest.cy * i; + + g_CaretInfo.pFont->SetPosition( dx, dy ); + g_CaretInfo.pFont->DrawText( szOneDigit ); + g_CaretInfo.pFont->SetPosition( seperateLineX + dwMarginX, dy ); + g_CaretInfo.pFont->DrawText( szCandidateBody ); + } + else if( g_bReadingWindow ) + { + g_CaretInfo.pFont->SetPosition( dwMarginX + candX, candY + i * largest.cy ); + g_CaretInfo.pFont->DrawText( g_szCandidate[i] ); + } + else + { + g_CaretInfo.pFont->SetPosition( uSpaceWidth / 2 + candX, candY ); + g_CaretInfo.pFont->DrawText( g_szCandidate[i] ); + } + } + if( !g_bReadingWindow && !g_bVerticalCand ) + { + if( IMEID_LANG( GetImeId() ) == LANG_CHS ) + candX += adwCandWidth[i] + dwMarginX; + else + candX += largest.cx + 1; + } + } + } +} + +static void CloseCandidateList() +{ + g_bCandList = false; + if( !g_bReadingWindow ) // fix for Ent Gen #120. + { + g_dwCount = 0; + memset( &g_szCandidate, 0, sizeof( g_szCandidate ) ); + } +} + +// +// ProcessIMEMessages() +// Processes IME related messages and acquire information +// +LPARAM ImeUi_ProcessMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM& lParam, bool* trapped ) +{ + HIMC himc; + int len; + static LPARAM lAlt = 0x80000000, lCtrl = 0x80000000, lShift = 0x80000000; + + *trapped = false; + if( !g_bInitialized || g_bDisableImeCompletely ) + { + return 0; + } + + switch( uMsg ) + { + // + // IME Handling + // + case WM_INPUTLANGCHANGE: + OnInputLangChange(); + break; + + case WM_IME_SETCONTEXT: + // + // We don't want anything to display, so we have to clear lParam and pass it to DefWindowProc(). + // Expecially important in Vista to receive IMN_CHANGECANDIDATE correctly. + // + lParam = 0; + break; + + case WM_IME_STARTCOMPOSITION: + InitCompStringData(); + *trapped = true; + break; + + case WM_IME_COMPOSITION: + { + LONG lRet; + TCHAR szCompStr[COUNTOF(g_szCompositionString)]; + + *trapped = true; + if( NULL == ( himc = _ImmGetContext( hWnd ) ) ) + { + break; + } + + // ResultStr must be processed before composition string. + if( lParam & GCS_RESULTSTR ) + { + lRet = ( LONG )_ImmGetCompositionString( himc, GCS_RESULTSTR, szCompStr, + COUNTOF( szCompStr ) ) / sizeof( TCHAR ); + szCompStr[lRet] = 0; + CancelCompString( g_hwndCurr, false, GetCharCount( szCompStr ) ); + StringCchCopy( g_szCompositionString, COUNTOF(g_szCompositionString), szCompStr ); + _SendCompString(); + InitCompStringData(); + } + // + // Reads in the composition string. + // + if( lParam & GCS_COMPSTR ) + { + ////////////////////////////////////////////////////// + // Retrieve the latest user-selected IME candidates + lRet = ( LONG )_ImmGetCompositionString( himc, GCS_COMPSTR, szCompStr, + COUNTOF( szCompStr ) ) / sizeof( TCHAR ); + szCompStr[lRet] = 0; + // + // Remove the whole of the string + // + CancelCompString( g_hwndCurr, false, GetCharCount( szCompStr ) ); + + StringCchCopy( g_szCompositionString, COUNTOF(g_szCompositionString), szCompStr ); + lRet = _ImmGetCompositionString( himc, GCS_COMPATTR, g_szCompAttrString, + COUNTOF( g_szCompAttrString ) ); + g_szCompAttrString[lRet] = 0; + // Older CHT IME uses composition string for reading string + if( GETLANG() == LANG_CHT && !GetImeId() ) + { + int i, chars = lstrlen( g_szCompositionString ) / ( 3 - sizeof( TCHAR ) ); + if( chars ) + { + g_dwCount = 4; + g_dwSelection = ( DWORD )-1; // don't select any candidate + + for( i = 3; i >= 0; i-- ) + { + if( i > chars - 1 ) + g_szCandidate[i][0] = 0; + else + { +#ifdef UNICODE + g_szCandidate[i][0] = g_szCompositionString[i]; + g_szCandidate[i][1] = 0; +#else + g_szCandidate[i][0] = g_szCompositionString[i * 2]; + g_szCandidate[i][1] = g_szCompositionString[i * 2 + 1]; + g_szCandidate[i][2] = 0; +#endif + } + } + g_uCandPageSize = MAX_CANDLIST; + memset( g_szCompositionString, 0, 8 ); + g_bReadingWindow = true; + GetReadingWindowOrientation( 0 ); + if( g_bHorizontalReading ) + { + g_iReadingError = -1; + g_szReadingString[0] = 0; + for( i = 0; i < ( int )g_dwCount; i++ ) + { + if( g_dwSelection == ( DWORD )i ) + g_iReadingError = lstrlen( g_szReadingString ); + LPCTSTR pszTmp = g_szCandidate[i]; + wcscat_s( g_szReadingString, COUNTOF(g_szReadingString), pszTmp ); + } + } + } + else + g_dwCount = 0; + } + + // get caret position in composition string + g_IMECursorBytes = _ImmGetCompositionString( himc, GCS_CURSORPOS, NULL, 0 ); + g_IMECursorChars = GetCharCountFromBytes( g_szCompositionString, g_IMECursorBytes ); + + if( g_dwIMELevel == 3 ) + { + // send composition string via WM_CHAR + _SendCompString(); + // move caret to appropreate location + len = GetCharCount( g_szCompositionString + g_IMECursorBytes ); + SendControlKeys( VK_LEFT, len ); + } + } + _ImmReleaseContext( hWnd, himc ); + } + break; + + case WM_IME_ENDCOMPOSITION: + CancelCompString( g_hwndCurr ); + InitCompStringData(); + break; + + case WM_IME_NOTIFY: + switch( wParam ) + { + case IMN_SETCONVERSIONMODE: + { + // Disable CHT IME software keyboard. + static bool bNoReentrance = false; + if( LANG_CHT == GETLANG() && !bNoReentrance ) + { + bNoReentrance = true; + DWORD dwConvMode, dwSentMode; + _ImmGetConversionStatus( g_himcOrg, &dwConvMode, &dwSentMode ); + const DWORD dwFlag = IME_CMODE_SOFTKBD | IME_CMODE_SYMBOL; + if( dwConvMode & dwFlag ) + _ImmSetConversionStatus( g_himcOrg, dwConvMode & ~dwFlag, dwSentMode ); + } + bNoReentrance = false; + } + // fall through + case IMN_SETOPENSTATUS: + if( g_bUILessMode ) + break; + CheckToggleState(); + break; + + case IMN_OPENCANDIDATE: + case IMN_CHANGECANDIDATE: + if( g_bUILessMode ) + { + break; + } + { + g_bCandList = true; + *trapped = true; + if( NULL == ( himc = _ImmGetContext( hWnd ) ) ) + break; + + LPCANDIDATELIST lpCandList; + DWORD dwIndex, dwBufLen; + + g_bReadingWindow = false; + dwIndex = 0; + dwBufLen = _GetCandidateList( himc, dwIndex, &lpCandList ); + + if( dwBufLen ) + { + g_dwSelection = lpCandList->dwSelection; + g_dwCount = lpCandList->dwCount; + + int startOfPage = 0; + if( GETLANG() == LANG_CHS && GetImeId() ) + { + // MSPY (CHS IME) has variable number of candidates in candidate window + // find where current page starts, and the size of current page + const int maxCandChar = 18 * ( 3 - sizeof( TCHAR ) ); + UINT cChars = 0; + UINT i; + for( i = 0; i < g_dwCount; i++ ) + { + UINT uLen = lstrlen( + ( LPTSTR )( ( DWORD )lpCandList + lpCandList->dwOffset[i] ) ) + + ( 3 - sizeof( TCHAR ) ); + if( uLen + cChars > maxCandChar ) + { + if( i > g_dwSelection ) + { + break; + } + startOfPage = i; + cChars = uLen; + } + else + { + cChars += uLen; + } + } + g_uCandPageSize = i - startOfPage; + } + else + { + g_uCandPageSize = min( lpCandList->dwPageSize, MAX_CANDLIST ); + startOfPage = g_bUILessMode ? lpCandList->dwPageStart : + ( g_dwSelection / g_uCandPageSize ) * g_uCandPageSize; + } + + g_dwSelection = ( GETLANG() == LANG_CHS && !GetImeId() ) ? ( DWORD )-1 + : g_dwSelection - startOfPage; + + memset( &g_szCandidate, 0, sizeof( g_szCandidate ) ); + for( UINT i = startOfPage, j = 0; + ( DWORD )i < lpCandList->dwCount && j < g_uCandPageSize; + i++, j++ ) + { + ComposeCandidateLine( j, + ( LPTSTR )( ( DWORD )lpCandList + lpCandList->dwOffset[i] ) ); + } + ImeUiCallback_Free( ( HANDLE )lpCandList ); + _ImmReleaseContext( hWnd, himc ); + + // don't display selection in candidate list in case of Korean and old Chinese IME. + if( GETPRIMLANG() == LANG_KOREAN || + GETLANG() == LANG_CHT && !GetImeId() ) + g_dwSelection = ( DWORD )-1; + } + break; + } + + case IMN_CLOSECANDIDATE: + if( g_bUILessMode ) + { + break; + } + CloseCandidateList(); + *trapped = true; + break; + + // Jun.16,2000 05:21 by yutaka. + case IMN_PRIVATE: + { + if( !g_bCandList ) + { + GetReadingString( hWnd ); + } + // Trap some messages to hide reading window + DWORD dwId = GetImeId(); + switch( dwId ) + { + case IMEID_CHT_VER42: + case IMEID_CHT_VER43: + case IMEID_CHT_VER44: + case IMEID_CHS_VER41: + case IMEID_CHS_VER42: + if( ( lParam == 1 ) || ( lParam == 2 ) ) + { + *trapped = true; + } + break; + case IMEID_CHT_VER50: + case IMEID_CHT_VER51: + case IMEID_CHT_VER52: + case IMEID_CHT_VER60: + case IMEID_CHS_VER53: + if( ( lParam == 16 ) || ( lParam == 17 ) || ( lParam == 26 ) || ( lParam == 27 ) || + ( lParam == 28 ) ) + { + *trapped = true; + } + break; + } + } + break; + + default: + *trapped = true; + break; + } + break; + + // fix for #15386 - When Text Service Framework is installed in Win2K, Alt+Shift and Ctrl+Shift combination (to switch + // input locale / keyboard layout) doesn't send WM_KEYUP message for the key that is released first. We need to check + // if these keys are actually up whenever we receive key up message for other keys. + case WM_KEYUP: + case WM_SYSKEYUP: + if( !( lAlt & 0x80000000 ) && wParam != VK_MENU && ( GetAsyncKeyState( VK_MENU ) & 0x8000 ) == 0 ) + { + PostMessageA( GetFocus(), WM_KEYUP, ( WPARAM )VK_MENU, ( lAlt & 0x01ff0000 ) | 0xC0000001 ); + } + else if( !( lCtrl & 0x80000000 ) && wParam != VK_CONTROL && + ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) == 0 ) + { + PostMessageA( GetFocus(), WM_KEYUP, ( WPARAM )VK_CONTROL, ( lCtrl & 0x01ff0000 ) | 0xC0000001 ); + } + else if( !( lShift & 0x80000000 ) && wParam != VK_SHIFT && ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0 ) + { + PostMessageA( GetFocus(), WM_KEYUP, ( WPARAM )VK_SHIFT, ( lShift & 0x01ff0000 ) | 0xC0000001 ); + } + // fall through WM_KEYDOWN / WM_SYSKEYDOWN + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + switch( wParam ) + { + case VK_MENU: + lAlt = lParam; + break; + case VK_SHIFT: + lShift = lParam; + break; + case VK_CONTROL: + lCtrl = lParam; + break; + } + } + break; + } + return 0; +} + +void ImeUi_SetCaretPosition( UINT x, UINT y ) +{ + if( !g_bInitialized ) + return; + g_CaretInfo.caretX = x; + g_CaretInfo.caretY = y; +} + +void ImeUi_SetCompStringAppearance( CImeUiFont_Base* pFont, DWORD color, const RECT* prc ) +{ + if( !g_bInitialized ) + return; + g_CaretInfo.pFont = pFont; + g_CaretInfo.margins = *prc; + + if( 0 == gSkinIME.candColorText ) + g_CaretInfo.colorCand = color; + else + g_CaretInfo.colorCand = gSkinIME.candColorText; + if( 0 == gSkinIME.compColorText ) + g_CaretInfo.colorComp = color; + else + g_CaretInfo.colorComp = gSkinIME.compColorText; +} + +void ImeUi_SetState( DWORD dwState ) +{ + if( !g_bInitialized ) + return; + HIMC himc; + if( dwState == IMEUI_STATE_ON ) + { + ImeUi_EnableIme( true ); + } + if( NULL != ( himc = _ImmGetContext( g_hwndCurr ) ) ) + { + if( g_bDisableImeCompletely ) + dwState = IMEUI_STATE_OFF; + + bool bOn = dwState == IMEUI_STATE_ON; // for non-Chinese IME + switch( GETPRIMLANG() ) + { + case LANG_CHINESE: + { + // toggle Chinese IME + DWORD dwId; + DWORD dwConvMode = 0, dwSentMode = 0; + if( ( g_bChineseIME && dwState == IMEUI_STATE_OFF ) || + ( !g_bChineseIME && dwState != IMEUI_STATE_OFF ) ) + { + _ImmSimulateHotKey( g_hwndCurr, IME_THOTKEY_IME_NONIME_TOGGLE ); + _PumpMessage(); + } + if( dwState != IMEUI_STATE_OFF ) + { + dwId = GetImeId(); + if( dwId ) + { + _ImmGetConversionStatus( himc, &dwConvMode, &dwSentMode ); + dwConvMode = ( dwState == IMEUI_STATE_ON ) + ? ( dwConvMode | IME_CMODE_NATIVE ) + : ( dwConvMode & ~IME_CMODE_NATIVE ); + _ImmSetConversionStatus( himc, dwConvMode, dwSentMode ); + } + } + break; + } + case LANG_KOREAN: + // toggle Korean IME + if( ( bOn && g_dwState != IMEUI_STATE_ON ) || ( !bOn && g_dwState == IMEUI_STATE_ON ) ) + { + _ImmSimulateHotKey( g_hwndCurr, IME_KHOTKEY_ENGLISH ); + } + break; + case LANG_JAPANESE: + _ImmSetOpenStatus( himc, bOn ); + break; + } + _ImmReleaseContext( g_hwndCurr, himc ); + CheckToggleState(); + } +} + +DWORD ImeUi_GetState() +{ + if( !g_bInitialized ) + return IMEUI_STATE_OFF; + CheckToggleState(); + return g_dwState; +} + +void ImeUi_EnableIme( bool bEnable ) +{ + if( !g_bInitialized || !g_hwndCurr ) + return; + if( g_bDisableImeCompletely ) + bEnable = false; + + if( g_hwndCurr == g_hwndMain ) + { + HIMC himcDbg; + himcDbg = _ImmAssociateContext( g_hwndCurr, bEnable? g_himcOrg : NULL ); + } + g_bImeEnabled = bEnable; + if( bEnable ) + { + CheckToggleState(); + } + CTsfUiLessMode::EnableUiUpdates( bEnable ); +} + +bool ImeUi_IsEnabled( void ) +{ + return g_bImeEnabled; +} + +bool ImeUi_Initialize( HWND hwnd, bool bDisable ) +{ + if( g_bInitialized ) + { + return true; + } + g_hwndMain = hwnd; + g_disableCicero.Initialize(); + + g_osi.dwOSVersionInfoSize = sizeof( OSVERSIONINFOA ); + GetVersionExA( &g_osi ); + + bool bUnicodeImm = false; + // IMM in NT or Win98 supports Unicode + if( g_osi.dwPlatformId == VER_PLATFORM_WIN32_NT || + ( g_osi.dwMajorVersion > 4 ) || + ( g_osi.dwMajorVersion == 4 ) && ( g_osi.dwMinorVersion > 0 ) ) + { + bUnicodeImm = true; + } + + g_hImmDll = LoadLibraryA( "imm32.dll" ); + g_bDisableImeCompletely = false; + + if( g_hImmDll ) + { + _ImmLockIMC = ( LPINPUTCONTEXT2 ( WINAPI* )( HIMC hIMC ) )GetProcAddress( g_hImmDll, "ImmLockIMC" ); + _ImmUnlockIMC = ( BOOL ( WINAPI* )( HIMC hIMC ) )GetProcAddress( g_hImmDll, "ImmUnlockIMC" ); + _ImmLockIMCC = ( LPVOID ( WINAPI* )( HIMCC hIMCC ) )GetProcAddress( g_hImmDll, "ImmLockIMCC" ); + _ImmUnlockIMCC = ( BOOL ( WINAPI* )( HIMCC hIMCC ) )GetProcAddress( g_hImmDll, "ImmUnlockIMCC" ); + BOOL ( WINAPI* _ImmDisableTextFrameService )( DWORD ) = ( BOOL ( WINAPI* )( DWORD ) )GetProcAddress( g_hImmDll, + "ImmDisableTextFrameService" ); + if( _ImmDisableTextFrameService ) + { + _ImmDisableTextFrameService( ( DWORD )-1 ); + } + } + else + { + g_bDisableImeCompletely = true; + return false; + } +#ifdef UNICODE + if ( bUnicodeImm ) + { + _ImmGetCompositionString = ImmGetCompositionStringW; + _ImmGetCandidateList = ImmGetCandidateListW; + _GetCandidateList = GetCandidateList; + } + else + { + _ImmGetCandidateList = ImmGetCandidateListA; + _ImmGetCompositionString = AW_ImmGetCompositionString; + _GetCandidateList = AW_GetCandidateList; + } +#else + if( bUnicodeImm ) + { + _ImmGetCompositionString = WA_ImmGetCompositionString; + _ImmGetCandidateList = ImmGetCandidateListA; + _GetCandidateList = WA_GetCandidateList; + } + else + { + _ImmGetCompositionString = ImmGetCompositionStringA; + _ImmGetCandidateList = ImmGetCandidateListA; + _GetCandidateList = GetCandidateList; + } +#endif + + // There are the following combinations of code config, window type, and the method of sending characters. + // Wnd: Unicode, Code: Unicode, Method: SendMessageW (SendMessageW must be supported since RegisterClassW is successful) + // Wnd: non Uni, Code: Unicode, Method: AW_SendCompString (Send characters in multibyte after W->A conversion) + // Wnd: Unicode, Code: non Uni, Method: SendMessageA (System does A->W conversion) - possible, but unlikely to be used. + // Wnd: non Uni, Code: non Uni, Method: SendMessageA +#ifdef UNICODE + if ( !IsWindowUnicode( hwnd ) ) + { + _SendCompString = AW_SendCompString; + } + else +#endif + { + _SendCompString = SendCompString; +#ifdef UNICODE + _SendMessage = SendMessageW; +#endif + } + + // turn init flag on so that subsequent calls to ImeUi functions work. + g_bInitialized = true; + + ImeUi_SetWindow( g_hwndMain ); + g_himcOrg = _ImmGetContext( g_hwndMain ); + _ImmReleaseContext( g_hwndMain, g_himcOrg ); + + if( !g_himcOrg ) + { + bDisable = true; + } + + // the following pointers to function has to be initialized before this function is called. + if( bDisable || + !ImeUiCallback_Malloc || + !ImeUiCallback_Free + ) + { + g_bDisableImeCompletely = true; + ImeUi_EnableIme( false ); + g_bInitialized = bDisable; + return false; + } + + g_uCaretBlinkTime = GetCaretBlinkTime(); + +#ifndef UNICODE + // Check if system is SBCS system + CPINFO cpi; + BOOL bRc = GetCPInfo( CP_ACP, &cpi ); + if( bRc ) + { + if( cpi.MaxCharSize == 1 ) + { + g_bDisableImeCompletely = true; // SBCS system. Disable IME. + } + } +#endif + + g_CaretInfo.caretX = 0; + g_CaretInfo.caretY = 0; + g_CaretInfo.pFont = 0; + g_CaretInfo.colorComp = 0; + g_CaretInfo.colorCand = 0; + g_CaretInfo.margins.left = 0; + g_CaretInfo.margins.right = 640; + g_CaretInfo.margins.top = 0; + g_CaretInfo.margins.bottom = 480; + + CheckInputLocale(); + OnInputLangChangeWorker(); + ImeUi_SetSupportLevel( 2 ); + + // SetupTSFSinks has to be called before CheckToggleState to make it work correctly. + g_bUILessMode = CTsfUiLessMode::SetupSinks() != FALSE; + CheckToggleState(); + if( g_bUILessMode ) + { + g_bChineseIME = ( GETPRIMLANG() == LANG_CHINESE ) && CTsfUiLessMode::CurrentInputLocaleIsIme(); + CTsfUiLessMode::UpdateImeState(); + } + ImeUi_EnableIme( false ); + + return true; +} + +void ImeUi_Uninitialize() +{ + if( !g_bInitialized ) + { + return; + } + CTsfUiLessMode::ReleaseSinks(); + if( g_hwndMain ) + { + ImmAssociateContext( g_hwndMain, g_himcOrg ); + } + g_hwndMain = NULL; + g_himcOrg = NULL; + if( g_hImmDll ) + { + FreeLibrary( g_hImmDll ); + g_hImmDll = NULL; + } + g_disableCicero.Uninitialize(); + g_bInitialized = false; +} + +// +// GetImeId( UINT uIndex ) +// returns +// returned value: +// 0: In the following cases +// - Non Chinese IME input locale +// - Older Chinese IME +// - Other error cases +// +// Othewise: +// When uIndex is 0 (default) +// bit 31-24: Major version +// bit 23-16: Minor version +// bit 15-0: Language ID +// When uIndex is 1 +// pVerFixedInfo->dwFileVersionLS +// +// Use IMEID_VER and IMEID_LANG macro to extract version and language information. +// +static DWORD GetImeId( UINT uIndex ) +{ + static HKL hklPrev = 0; + static DWORD dwRet[2] = + { + 0, 0 + }; + + DWORD dwVerSize; + DWORD dwVerHandle; + LPVOID lpVerBuffer; + LPVOID lpVerData; + UINT cbVerData; + char szTmp[1024]; + + if( uIndex >= sizeof( dwRet ) / sizeof( dwRet[0] ) ) + return 0; + + HKL kl = g_hklCurrent; + if( hklPrev == kl ) + { + return dwRet[uIndex]; + } + hklPrev = kl; + DWORD dwLang = ( ( DWORD )kl & 0xffff ); + + if( g_bUILessMode && GETLANG() == LANG_CHT ) + { + // In case of Vista, artifitial value is returned so that it's not considered as older IME. + dwRet[0] = IMEID_CHT_VER_VISTA; + dwRet[1] = 0; + return dwRet[0]; + } + + if( kl != _CHT_HKL_NEW_PHONETIC && kl != _CHT_HKL_NEW_CHANG_JIE + && kl != _CHT_HKL_NEW_QUICK && kl != _CHT_HKL_HK_CANTONESE && kl != _CHS_HKL ) + { + goto error; + } + + if( _ImmGetIMEFileNameA( kl, szTmp, sizeof( szTmp ) - 1 ) <= 0 ) + { + goto error; + } + + if( !_GetReadingString ) // IME that doesn't implement private API + { +#define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) + if( ( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, _CHT_IMEFILENAME, -1 ) != 2 ) + && ( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, _CHT_IMEFILENAME2, -1 ) != 2 ) + && ( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, _CHT_IMEFILENAME3, -1 ) != 2 ) + && ( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, _CHS_IMEFILENAME, -1 ) != 2 ) + && ( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, _CHS_IMEFILENAME2, -1 ) != 2 ) + ) + { + goto error; + } + } + + dwVerSize = GetFileVersionInfoSizeA( szTmp, &dwVerHandle ); + if( dwVerSize ) + { + lpVerBuffer = ( LPVOID )ImeUiCallback_Malloc( dwVerSize ); + if( lpVerBuffer ) + { + if( GetFileVersionInfoA( szTmp, dwVerHandle, dwVerSize, lpVerBuffer ) ) + { + if( VerQueryValueA( lpVerBuffer, "\\", &lpVerData, &cbVerData ) ) + { +#define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData) + DWORD dwVer = pVerFixedInfo->dwFileVersionMS; + dwVer = ( dwVer & 0x00ff0000 ) << 8 | ( dwVer & 0x000000ff ) << 16; + if( _GetReadingString || + dwLang == LANG_CHT && ( + dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(4, 3) || + dwVer == MAKEIMEVERSION(4, 4) || + dwVer == MAKEIMEVERSION(5, 0) || + dwVer == MAKEIMEVERSION(5, 1) || + dwVer == MAKEIMEVERSION(5, 2) || + dwVer == MAKEIMEVERSION(6, 0) ) + || + dwLang == LANG_CHS && ( + dwVer == MAKEIMEVERSION(4, 1) || + dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(5, 3) ) ) + { + dwRet[0] = dwVer | dwLang; + dwRet[1] = pVerFixedInfo->dwFileVersionLS; + ImeUiCallback_Free( lpVerBuffer ); + return dwRet[0]; + } +#undef pVerFixedInfo + } + } + } + ImeUiCallback_Free( lpVerBuffer ); + } + + // The flow comes here in the following conditions + // - Non Chinese IME input locale + // - Older Chinese IME + // - Other error cases +error: + dwRet[0] = dwRet[1] = 0; + return dwRet[uIndex]; +} + +static void GetReadingString( HWND hWnd ) +{ + if( g_bUILessMode ) + { + return; + } + DWORD dwId = GetImeId(); + if( !dwId ) + { + return; + } + + HIMC himc; + himc = _ImmGetContext( hWnd ); + if( !himc ) + return; + + DWORD dwlen = 0; + DWORD dwerr = 0; + WCHAR wzBuf[16]; // We believe 16 wchars are big enough to hold reading string after having discussion with CHT IME team. + WCHAR* wstr = wzBuf; + bool unicode = FALSE; + LPINPUTCONTEXT2 lpIMC = NULL; + + if( _GetReadingString ) + { + BOOL bVertical; + UINT uMaxUiLen; + dwlen = _GetReadingString( himc, 0, NULL, ( PINT )&dwerr, &bVertical, &uMaxUiLen ); + if( dwlen ) + { + if( dwlen > COUNTOF(wzBuf) ) + { + dwlen = COUNTOF(wzBuf); + } + dwlen = _GetReadingString( himc, dwlen, wstr, ( PINT )&dwerr, &bVertical, &uMaxUiLen ); + } + + g_bHorizontalReading = bVertical == 0; + unicode = true; + } + else // IMEs that doesn't implement Reading String API + { + lpIMC = _ImmLockIMC( himc ); + + // *** hacking code from Michael Yang *** + + LPBYTE p = 0; + + switch( dwId ) + { + + case IMEID_CHT_VER42: // New(Phonetic/ChanJie)IME98 : 4.2.x.x // Win98 + case IMEID_CHT_VER43: // New(Phonetic/ChanJie)IME98a : 4.3.x.x // WinMe, Win2k + case IMEID_CHT_VER44: // New ChanJie IME98b : 4.4.x.x // WinXP + + p = *( LPBYTE* )( ( LPBYTE )_ImmLockIMCC( lpIMC->hPrivate ) + 24 ); + if( !p ) break; + dwlen = *( DWORD* )( p + 7 * 4 + 32 * 4 ); //m_dwInputReadStrLen + dwerr = *( DWORD* )( p + 8 * 4 + 32 * 4 ); //m_dwErrorReadStrStart + wstr = ( WCHAR* )( p + 56 ); + unicode = TRUE; + break; + + case IMEID_CHT_VER50: // 5.0.x.x // WinME + + p = *( LPBYTE* )( ( LPBYTE )_ImmLockIMCC( lpIMC->hPrivate ) + 3 * 4 ); // PCKeyCtrlManager + if( !p ) break; + p = *( LPBYTE* )( ( LPBYTE )p + 1 * 4 + 5 * 4 + 4 * 2 ); // = PCReading = &STypingInfo + if( !p ) break; + dwlen = *( DWORD* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 ); //m_dwDisplayStringLength; + dwerr = *( DWORD* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 + 1 * 4 ); //m_dwDisplayErrorStart; + wstr = ( WCHAR* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 ); + unicode = FALSE; + break; + + case IMEID_CHT_VER51: // 5.1.x.x // IME2002(w/OfficeXP) + case IMEID_CHT_VER52: // 5.2.x.x // (w/whistler) + case IMEID_CHS_VER53: // 5.3.x.x // SCIME2k or MSPY3 (w/OfficeXP and Whistler) + + p = *( LPBYTE* )( ( LPBYTE )_ImmLockIMCC( lpIMC->hPrivate ) + 4 ); // PCKeyCtrlManager + if( !p ) break; + p = *( LPBYTE* )( ( LPBYTE )p + 1 * 4 + 5 * 4 ); // = PCReading = &STypingInfo + if( !p ) break; + dwlen = *( DWORD* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * 2 ); //m_dwDisplayStringLength; + dwerr = *( DWORD* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * 2 + 1 * 4 ); //m_dwDisplayErrorStart; + wstr = ( WCHAR* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 ); + unicode = TRUE; + break; + + // the code tested only with Win 98 SE (MSPY 1.5/ ver 4.1.0.21) + case IMEID_CHS_VER41: + { + int offset; + offset = ( GetImeId( 1 ) >= 0x00000002 ) ? 8 : 7; + + p = *( LPBYTE* )( ( LPBYTE )_ImmLockIMCC( lpIMC->hPrivate ) + offset * 4 ); + if( !p ) break; + dwlen = *( DWORD* )( p + 7 * 4 + 16 * 2 * 4 ); + dwerr = *( DWORD* )( p + 8 * 4 + 16 * 2 * 4 ); + dwerr = min( dwerr, dwlen ); + wstr = ( WCHAR* )( p + 6 * 4 + 16 * 2 * 1 ); + unicode = TRUE; + break; + } + + case IMEID_CHS_VER42: // 4.2.x.x // SCIME98 or MSPY2 (w/Office2k, Win2k, WinME, etc) + { + int nTcharSize = IsNT() ? sizeof( WCHAR ) : sizeof( char ); + p = *( LPBYTE* )( ( LPBYTE )_ImmLockIMCC( lpIMC->hPrivate ) + 1 * 4 + 1 * 4 + 6 * 4 ); // = PCReading = &STypintInfo + if( !p ) break; + dwlen = *( DWORD* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * nTcharSize ); //m_dwDisplayStringLength; + dwerr = *( DWORD* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * nTcharSize + 1 * 4 ); //m_dwDisplayErrorStart; + wstr = ( WCHAR* )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 ); //m_tszDisplayString + unicode = IsNT() ? TRUE : FALSE; + } + } // switch + + g_szCandidate[0][0] = 0; + g_szCandidate[1][0] = 0; + g_szCandidate[2][0] = 0; + g_szCandidate[3][0] = 0; + } + g_dwCount = dwlen; + g_dwSelection = ( DWORD )-1; // do not select any char + if( unicode ) + { + int i; + for( i = 0; ( DWORD )i < dwlen; i++ ) // dwlen > 0, if known IME : yutakah + { + if( dwerr <= ( DWORD )i && g_dwSelection == ( DWORD )-1 ) + { // select error char + g_dwSelection = i; + } +#ifdef UNICODE + g_szCandidate[i][0] = wstr[i]; + g_szCandidate[i][1] = 0; +#else + char mbc[3]; + mbc[1] = 0; + mbc[2] = 0; + WideCharToMultiByte( g_uCodePage, 0, wstr + i, 1, mbc, sizeof( mbc ), NULL, NULL ); + + g_szCandidate[i][0] = mbc[0]; + g_szCandidate[i][1] = mbc[1]; + g_szCandidate[i][2] = 0; +#endif + } + g_szCandidate[i][0] = 0; + } + else + { + char* p = ( char* )wstr; + int i, j; + for( i = 0, j = 0; ( DWORD )i < dwlen; i++, j++ ) // dwlen > 0, if known IME : yutakah + { + if( dwerr <= ( DWORD )i && g_dwSelection == ( DWORD )-1 ) + { + g_dwSelection = ( DWORD )j; + } +#ifdef UNICODE + MultiByteToWideChar( g_uCodePage, 0, p + i, 1 + ( _IsLeadByte( p[i] ) ? 1 : 0 ), + g_szCandidate[j], 1 ); + if ( _IsLeadByte( p[i] ) ) + { + i++; + } +#else + g_szCandidate[j][0] = p[i]; + g_szCandidate[j][1] = 0; + g_szCandidate[j][2] = 0; + if( _IsLeadByte(p[i]) ) + { + i++; + g_szCandidate[j][1] = p[i]; + } +#endif + } + g_szCandidate[j][0] = 0; + g_dwCount = j; + } + if( !_GetReadingString ) + { + _ImmUnlockIMCC( lpIMC->hPrivate ); + _ImmUnlockIMC( himc ); + GetReadingWindowOrientation( dwId ); + } + _ImmReleaseContext( hWnd, himc ); + + g_bReadingWindow = true; + if( g_bHorizontalReading ) + { + g_iReadingError = -1; + g_szReadingString[0] = 0; + for( UINT i = 0; i < g_dwCount; i++ ) + { + if( g_dwSelection == ( DWORD )i ) + g_iReadingError = lstrlen( g_szReadingString ); + LPCTSTR pszTmp = g_szCandidate[i]; + wcscat_s( g_szReadingString, COUNTOF(g_szReadingString), pszTmp ); + } + } + g_uCandPageSize = MAX_CANDLIST; +} + + +static struct +{ + bool m_bCtrl; + bool m_bShift; + bool m_bAlt; + UINT m_uVk; +} + aHotKeys[] = +{ + false, false, false, VK_APPS, + true, false, false, '8', + true, false, false, 'Y', + true, false, false, VK_DELETE, + true, false, false, VK_F7, + true, false, false, VK_F9, + true, false, false, VK_F10, + true, false, false, VK_F11, + true, false, false, VK_F12, + false, false, false, VK_F2, + false, false, false, VK_F3, + false, false, false, VK_F4, + false, false, false, VK_F5, + false, false, false, VK_F10, + false, true, false, VK_F6, + false, true, false, VK_F7, + false, true, false, VK_F8, + true, true, false, VK_F10, + true, true, false, VK_F11, + true, false, false, VK_CONVERT, + true, false, false, VK_SPACE, + true, false, true, 0xbc, // Alt + Ctrl + ',': SW keyboard for Trad. Chinese IME + true, false, false, VK_TAB, // ATOK2005's Ctrl+TAB +}; + +// +// Ignores specific keys when IME is on. Returns true if the message is a hot key to ignore. +// - Caller doesn't have to check whether IME is on. +// - This function must be called before TranslateMessage() is called. +// +bool ImeUi_IgnoreHotKey( const MSG* pmsg ) +{ + if( !g_bInitialized || !pmsg ) + return false; + + if( pmsg->wParam == VK_PROCESSKEY && ( pmsg->message == WM_KEYDOWN || pmsg->message == WM_SYSKEYDOWN ) ) + { + bool bCtrl, bShift, bAlt; + UINT uVkReal = _ImmGetVirtualKey( pmsg->hwnd ); + // special case #1 - VK_JUNJA toggles half/full width input mode in Korean IME. + // This VK (sent by Alt+'=' combo) is ignored regardless of the modifier state. + if( uVkReal == VK_JUNJA ) + { + return true; + } + // special case #2 - disable right arrow key that switches the candidate list to expanded mode in CHT IME. + if( uVkReal == VK_RIGHT && g_bCandList && GETLANG() == LANG_CHT ) + { + return true; + } +#ifndef ENABLE_HANJA_KEY + // special case #3 - we disable VK_HANJA key because 1. some Korean fonts don't Hanja and 2. to reduce testing cost. + if( uVkReal == VK_HANJA && GETPRIMLANG() == LANG_KOREAN ) + { + return true; + } +#endif + bCtrl = ( GetKeyState( VK_CONTROL ) & 0x8000 ) ? true : false; + bShift = ( GetKeyState( VK_SHIFT ) & 0x8000 ) ? true : false; + bAlt = ( GetKeyState( VK_MENU ) & 0x8000 ) ? true : false; + for( int i = 0; i < COUNTOF(aHotKeys); i++ ) + { + if( aHotKeys[i].m_bCtrl == bCtrl && + aHotKeys[i].m_bShift == bShift && + aHotKeys[i].m_bAlt == bAlt && + aHotKeys[i].m_uVk == uVkReal ) + return true; + } + } + return false; +} + +void ImeUi_FinalizeString( bool bSend ) +{ + HIMC himc; + static bool bProcessing = false; // to avoid infinite recursion + if( !g_bInitialized || bProcessing || NULL == ( himc = _ImmGetContext( g_hwndCurr ) ) ) + return; + bProcessing = true; + + if( g_dwIMELevel == 2 && bSend ) + { + // Send composition string to app. + LONG lRet = lstrlen( g_szCompositionString ); + assert( lRet >= 2 ); + // In case of CHT IME, don't send the trailing double byte space, if it exists. +#ifdef UNICODE + if ( GETLANG() == LANG_CHT && (lRet >= 1) + && g_szCompositionString[lRet - 1] == 0x3000 ) + { + lRet--; + } +#else + if( GETLANG() == LANG_CHT && ( lRet >= 2 ) + && ( BYTE )( g_szCompositionString[lRet - 2] ) == 0xa1 + && ( BYTE )( g_szCompositionString[lRet - 1] ) == 0x40 ) + { + lRet -= 2; + } +#endif + _SendCompString(); + } + + InitCompStringData(); + // clear composition string in IME + _ImmNotifyIME( himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0 ); + if( g_bUILessMode ) + { + // For some reason ImmNotifyIME doesn't work on DaYi and Array CHT IMEs. Cancel composition string by setting zero-length string. + ImmSetCompositionString( himc, SCS_SETSTR, TEXT( "" ), sizeof( TCHAR ), TEXT( "" ), sizeof( TCHAR ) ); + } + // the following line is necessary as Korean IME doesn't close cand list when comp string is cancelled. + _ImmNotifyIME( himc, NI_CLOSECANDIDATE, 0, 0 ); + _ImmReleaseContext( g_hwndCurr, himc ); + // Zooty2 RAID #4759: Sometimes application doesn't receive IMN_CLOSECANDIDATE on Alt+Tab + // So the same code for IMN_CLOSECANDIDATE is replicated here. + CloseCandidateList(); + bProcessing = false; + return; +} + +static void SetCompStringColor() +{ + // change color setting according to current IME level. + DWORD dwTranslucency = ( g_dwIMELevel == 2 ) ? 0xff000000 : ( ( DWORD )gSkinIME.compTranslucence << 24 ); + gSkinCompStr.colorInput = dwTranslucency | gSkinIME.compColorInput; + gSkinCompStr.colorTargetConv = dwTranslucency | gSkinIME.compColorTargetConv; + gSkinCompStr.colorConverted = dwTranslucency | gSkinIME.compColorConverted; + gSkinCompStr.colorTargetNotConv = dwTranslucency | gSkinIME.compColorTargetNotConv; + gSkinCompStr.colorInputErr = dwTranslucency | gSkinIME.compColorInputErr; +} + +static void SetSupportLevel( DWORD dwImeLevel ) +{ + if( dwImeLevel < 2 || 3 < dwImeLevel ) + return; + if( GETPRIMLANG() == LANG_KOREAN ) + { + dwImeLevel = 3; + } + g_dwIMELevel = dwImeLevel; + // cancel current composition string. + ImeUi_FinalizeString(); + SetCompStringColor(); +} + +void ImeUi_SetSupportLevel( DWORD dwImeLevel ) +{ + if( !g_bInitialized ) + return; + g_dwIMELevelSaved = dwImeLevel; + SetSupportLevel( dwImeLevel ); +} + +void ImeUi_SetAppearance( const IMEUI_APPEARANCE* pia ) +{ + if( !g_bInitialized || NULL == pia ) + return; + gSkinIME = *pia; + gSkinIME.symbolColor &= 0xffffff; // mask translucency + gSkinIME.symbolColorOff &= 0xffffff; // mask translucency + gSkinIME.symbolColorText &= 0xffffff; // mask translucency + gSkinIME.compColorInput &= 0xffffff; // mask translucency + gSkinIME.compColorTargetConv &= 0xffffff; // mask translucency + gSkinIME.compColorConverted &= 0xffffff; // mask translucency + gSkinIME.compColorTargetNotConv &= 0xffffff; // mask translucency + gSkinIME.compColorInputErr &= 0xffffff; // mask translucency + SetCompStringColor(); +} + +void ImeUi_GetAppearance( IMEUI_APPEARANCE* pia ) +{ + if( g_bInitialized && pia ) + { + *pia = gSkinIME; + } +} + +static void CheckToggleState() +{ + CheckInputLocale(); + + // In Vista, we have to use TSF since few IMM functions don't work as expected. + // WARNING: Because of timing, g_dwState and g_bChineseIME may not be updated + // immediately after the change on IME states by user. + if( g_bUILessMode ) + { + return; + } + + bool bIme = _ImmIsIME( g_hklCurrent ) != 0 + && ( ( 0xF0000000 & ( DWORD )g_hklCurrent ) == 0xE0000000 ); // Hack to detect IME correctly. When IME is running as TIP, ImmIsIME() returns true for CHT US keyboard. + g_bChineseIME = ( GETPRIMLANG() == LANG_CHINESE ) && bIme; + + HIMC himc; + if( NULL != ( himc = _ImmGetContext( g_hwndCurr ) ) ) + { + if( g_bChineseIME ) + { + DWORD dwConvMode, dwSentMode; + _ImmGetConversionStatus( himc, &dwConvMode, &dwSentMode ); + g_dwState = ( dwConvMode & IME_CMODE_NATIVE ) ? IMEUI_STATE_ON : IMEUI_STATE_ENGLISH; + } + else + { + g_dwState = ( bIme && _ImmGetOpenStatus( himc ) != 0 ) ? IMEUI_STATE_ON : IMEUI_STATE_OFF; + } + _ImmReleaseContext( g_hwndCurr, himc ); + } + else + g_dwState = IMEUI_STATE_OFF; +} + +void ImeUi_SetInsertMode( bool bInsert ) +{ + if( !g_bInitialized ) + return; + g_bInsertMode = bInsert; +} + +bool ImeUi_GetCaretStatus() +{ + return !g_bInitialized || !g_szCompositionString[0]; +} + +void ImeUi_SetScreenDimension( UINT width, UINT height ) +{ + if( !g_bInitialized ) + return; + g_screenWidth = width; + g_screenHeight = height; +} + +// this function is used only in brief time in CHT IME handling, so accelerator isn't processed. +static void _PumpMessage() +{ + MSG msg; + while( PeekMessageA( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + { + if( !GetMessageA( &msg, NULL, 0, 0 ) ) + { + PostQuitMessage( msg.wParam ); + return; + } + // if (0 == TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { + TranslateMessage( &msg ); + DispatchMessageA( &msg ); + // } + } +} + +static void GetReadingWindowOrientation( DWORD dwId ) +{ + g_bHorizontalReading = ( g_hklCurrent == _CHS_HKL ) || ( g_hklCurrent == _CHT_HKL_NEW_CHANG_JIE ) || ( dwId == 0 ); + if( !g_bHorizontalReading && IMEID_LANG( dwId ) == LANG_CHT ) + { + char szRegPath[MAX_PATH]; + HKEY hkey; + DWORD dwVer = IMEID_VER( dwId ); + StringCchCopyA( szRegPath, COUNTOF(szRegPath), "software\\microsoft\\windows\\currentversion\\" ); + strcat_s( szRegPath, COUNTOF(szRegPath), ( dwVer >= MAKEIMEVERSION(5, 1) ) ? "MSTCIPH" : "TINTLGNT" ); + LONG lRc = RegOpenKeyExA( HKEY_CURRENT_USER, szRegPath, 0, KEY_READ, &hkey ); + if( lRc == ERROR_SUCCESS ) + { + DWORD dwSize = sizeof( DWORD ), dwMapping, dwType; + lRc = RegQueryValueExA( hkey, "keyboard mapping", NULL, &dwType, ( PBYTE )&dwMapping, &dwSize ); + if( lRc == ERROR_SUCCESS ) + { + if( + ( dwVer <= MAKEIMEVERSION( 5, 0 ) && + ( ( BYTE )dwMapping == 0x22 || ( BYTE )dwMapping == 0x23 ) + ) || + ( ( dwVer == MAKEIMEVERSION( 5, 1 ) || dwVer == MAKEIMEVERSION( 5, 2 ) ) && + ( ( BYTE )dwMapping >= 0x22 && ( BYTE )dwMapping <= 0x24 ) + ) + ) + { + g_bHorizontalReading = true; + } + } + RegCloseKey( hkey ); + } + } +} + +void ImeUi_ToggleLanguageBar( BOOL bRestore ) +{ + static BOOL prevRestore = TRUE; + bool bCheck = ( prevRestore == TRUE || bRestore == TRUE ); + prevRestore = bRestore; + if( !bCheck ) + return; + + static int iShowStatusWindow = -1; + if( iShowStatusWindow == -1 ) + { + iShowStatusWindow = IsNT() && g_osi.dwMajorVersion >= 5 && + ( g_osi.dwMinorVersion > 1 || ( g_osi.dwMinorVersion == 1 && lstrlenA( g_osi.szCSDVersion ) ) ) ? 1 : 0; + } + HWND hwndImeDef = _ImmGetDefaultIMEWnd( g_hwndCurr ); + if( hwndImeDef && bRestore && iShowStatusWindow ) + SendMessageA( hwndImeDef, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0 ); + HRESULT hr; + hr = CoInitialize( NULL ); + if( SUCCEEDED( hr ) ) + { + ITfLangBarMgr* plbm = NULL; + hr = CoCreateInstance( CLSID_TF_LangBarMgr, NULL, CLSCTX_INPROC_SERVER, __uuidof( ITfLangBarMgr ), + ( void** )&plbm ); + if( SUCCEEDED( hr ) && plbm ) + { + DWORD dwCur; + ULONG uRc; + if( SUCCEEDED( hr ) ) + { + if( bRestore ) + { + if( g_dwPrevFloat ) + hr = plbm->ShowFloating( g_dwPrevFloat ); + } + else + { + hr = plbm->GetShowFloatingStatus( &dwCur ); + if( SUCCEEDED( hr ) ) + g_dwPrevFloat = dwCur; + if( !( g_dwPrevFloat & TF_SFT_DESKBAND ) ) + { + hr = plbm->ShowFloating( TF_SFT_HIDDEN ); + } + } + } + uRc = plbm->Release(); + } + CoUninitialize(); + } + if( hwndImeDef && !bRestore ) + { + // The following OPENSTATUSWINDOW is required to hide ATOK16 toolbar (FS9:#7546) + SendMessageA( hwndImeDef, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0 ); + SendMessageA( hwndImeDef, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0 ); + } +} + +bool ImeUi_IsSendingKeyMessage() +{ + return bIsSendingKeyMessage; +} + +static void OnInputLangChangeWorker() +{ + if( !g_bUILessMode ) + { + g_iCandListIndexBase = ( g_hklCurrent == _CHT_HKL_DAYI ) ? 0 : 1; + } + SetImeApi(); +} + +static void OnInputLangChange() +{ + UINT uLang = GETPRIMLANG(); + CheckToggleState(); + OnInputLangChangeWorker(); + if( uLang != GETPRIMLANG() ) + { + // Korean IME always uses level 3 support. + // Other languages use the level that is specified by ImeUi_SetSupportLevel() + SetSupportLevel( ( GETPRIMLANG() == LANG_KOREAN ) ? 3 : g_dwIMELevelSaved ); + } + HWND hwndImeDef = _ImmGetDefaultIMEWnd( g_hwndCurr ); + if( hwndImeDef ) + { + // Fix for Zooty #3995: prevent CHT IME toobar from showing up + SendMessageA( hwndImeDef, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0 ); + SendMessageA( hwndImeDef, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0 ); + } +} + +static void SetImeApi() +{ + _GetReadingString = NULL; + _ShowReadingWindow = NULL; + if( g_bUILessMode ) + return; + + char szImeFile[MAX_PATH + 1]; + HKL kl = g_hklCurrent; + if( _ImmGetIMEFileNameA( kl, szImeFile, sizeof( szImeFile ) - 1 ) <= 0 ) + return; + HMODULE hIme = LoadLibraryA( szImeFile ); + if( !hIme ) + return; + _GetReadingString = ( UINT ( WINAPI* )( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT ) ) + ( GetProcAddress( hIme, "GetReadingString" ) ); + _ShowReadingWindow = ( BOOL ( WINAPI* )( HIMC himc, BOOL ) ) + ( GetProcAddress( hIme, "ShowReadingWindow" ) ); + if( _ShowReadingWindow ) + { + HIMC himc; + if( NULL != ( himc = _ImmGetContext( g_hwndCurr ) ) ) + { + _ShowReadingWindow( himc, false ); + _ImmReleaseContext( g_hwndCurr, himc ); + } + } +} + +static void CheckInputLocale() +{ + static HKL hklPrev = 0; + g_hklCurrent = GetKeyboardLayout( 0 ); + if( hklPrev == g_hklCurrent ) + { + return; + } + hklPrev = g_hklCurrent; + switch( GETPRIMLANG() ) + { + // Simplified Chinese + case LANG_CHINESE: + g_bVerticalCand = true; + switch( GETSUBLANG() ) + { + case SUBLANG_CHINESE_SIMPLIFIED: + g_pszIndicatior = g_aszIndicator[INDICATOR_CHS]; + //g_bVerticalCand = GetImeId() == 0; + g_bVerticalCand = false; + break; + case SUBLANG_CHINESE_TRADITIONAL: + g_pszIndicatior = g_aszIndicator[INDICATOR_CHT]; + break; + default: // unsupported sub-language + g_pszIndicatior = g_aszIndicator[INDICATOR_NON_IME]; + break; + } + break; + // Korean + case LANG_KOREAN: + g_pszIndicatior = g_aszIndicator[INDICATOR_KOREAN]; + g_bVerticalCand = false; + break; + // Japanese + case LANG_JAPANESE: + g_pszIndicatior = g_aszIndicator[INDICATOR_JAPANESE]; + g_bVerticalCand = true; + break; + default: + g_pszIndicatior = g_aszIndicator[INDICATOR_NON_IME]; + } + char szCodePage[8]; + int iRc = GetLocaleInfoA( MAKELCID( GETLANG(), SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE, szCodePage, + COUNTOF( szCodePage ) ); iRc; + g_uCodePage = _strtoul( szCodePage, NULL, 0 ); + for( int i = 0; i < 256; i++ ) + { + LeadByteTable[i] = ( BYTE )IsDBCSLeadByteEx( g_uCodePage, ( BYTE )i ); + } +} + +void ImeUi_SetWindow( HWND hwnd ) +{ + g_hwndCurr = hwnd; + g_disableCicero.DisableCiceroOnThisWnd( hwnd ); +} + +UINT ImeUi_GetInputCodePage() +{ + return g_uCodePage; +} + +DWORD ImeUi_GetFlags() +{ + return g_dwImeUiFlags; +} + +void ImeUi_SetFlags( DWORD dwFlags, bool bSet ) +{ + if( bSet ) + { + g_dwImeUiFlags |= dwFlags; + } + else + { + g_dwImeUiFlags &= ~dwFlags; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// +// CTsfUiLessMode methods +// +/////////////////////////////////////////////////////////////////////////////// + +// +// SetupSinks() +// Set up sinks. A sink is used to receive a Text Service Framework event. +// CUIElementSink implements multiple sink interfaces to receive few different TSF events. +// +BOOL CTsfUiLessMode::SetupSinks() +{ + // ITfThreadMgrEx is available on Vista or later. + HRESULT hr; + hr = CoCreateInstance( CLSID_TF_ThreadMgr, + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( ITfThreadMgrEx ), + ( void** )&m_tm ); + + if( hr != S_OK ) + { + return FALSE; + } + + // ready to start interacting + TfClientId cid; // not used + if( FAILED( m_tm->ActivateEx( &cid, TF_TMAE_UIELEMENTENABLEDONLY ) ) ) + { + return FALSE; + } + + // Setup sinks + BOOL bRc = FALSE; + m_TsfSink = new CUIElementSink(); + if( m_TsfSink ) + { + ITfSource* srcTm; + if( SUCCEEDED( hr = m_tm->QueryInterface( __uuidof( ITfSource ), ( void** )&srcTm ) ) ) + { + // Sink for reading window change + if( SUCCEEDED( hr = srcTm->AdviseSink( __uuidof( ITfUIElementSink ), ( ITfUIElementSink* )m_TsfSink, + &m_dwUIElementSinkCookie ) ) ) + { + // Sink for input locale change + if( SUCCEEDED( hr = srcTm->AdviseSink( __uuidof( ITfInputProcessorProfileActivationSink ), + ( ITfInputProcessorProfileActivationSink* )m_TsfSink, + &m_dwAlpnSinkCookie ) ) ) + { + if( SetupCompartmentSinks() ) // Setup compartment sinks for the first time + { + bRc = TRUE; + } + } + } + srcTm->Release(); + } + } + return bRc; +} + +void CTsfUiLessMode::ReleaseSinks() +{ + HRESULT hr; + ITfSource* source; + + // Remove all sinks + if( m_tm && SUCCEEDED( m_tm->QueryInterface( __uuidof( ITfSource ), ( void** )&source ) ) ) + { + hr = source->UnadviseSink( m_dwUIElementSinkCookie ); + hr = source->UnadviseSink( m_dwAlpnSinkCookie ); + source->Release(); + SetupCompartmentSinks( TRUE ); // Remove all compartment sinks + m_tm->Deactivate(); + SAFE_RELEASE( m_tm ); + SAFE_RELEASE( m_TsfSink ); + } +} + +CTsfUiLessMode::CUIElementSink::CUIElementSink() +{ + _cRef = 1; +} + + +CTsfUiLessMode::CUIElementSink::~CUIElementSink() +{ +} + +STDAPI CTsfUiLessMode::CUIElementSink::QueryInterface( REFIID riid, void** ppvObj ) +{ + if( ppvObj == NULL ) + return E_INVALIDARG; + + *ppvObj = NULL; + + if( IsEqualIID( riid, IID_IUnknown ) ) + { + *ppvObj = reinterpret_cast( this ); + } + else if( IsEqualIID( riid, __uuidof( ITfUIElementSink ) ) ) + { + *ppvObj = ( ITfUIElementSink* )this; + } + else if( IsEqualIID( riid, __uuidof( ITfInputProcessorProfileActivationSink ) ) ) + { + *ppvObj = ( ITfInputProcessorProfileActivationSink* )this; + } + else if( IsEqualIID( riid, __uuidof( ITfCompartmentEventSink ) ) ) + { + *ppvObj = ( ITfCompartmentEventSink* )this; + } + + if( *ppvObj ) + { + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +STDAPI_( ULONG ) +CTsfUiLessMode::CUIElementSink::AddRef() +{ + return ++_cRef; +} + +STDAPI_( ULONG ) +CTsfUiLessMode::CUIElementSink::Release() +{ + LONG cr = --_cRef; + + if( _cRef == 0 ) + { + delete this; + } + + return cr; +} + +STDAPI CTsfUiLessMode::CUIElementSink::BeginUIElement( DWORD dwUIElementId, BOOL* pbShow ) +{ + ITfUIElement* pElement = GetUIElement( dwUIElementId ); + if( !pElement ) + return E_INVALIDARG; + + ITfReadingInformationUIElement* preading = NULL; + ITfCandidateListUIElement* pcandidate = NULL; + *pbShow = FALSE; + if( !g_bCandList && SUCCEEDED( pElement->QueryInterface( __uuidof( ITfReadingInformationUIElement ), + ( void** )&preading ) ) ) + { + MakeReadingInformationString( preading ); + preading->Release(); + } + else if( SUCCEEDED( pElement->QueryInterface( __uuidof( ITfCandidateListUIElement ), + ( void** )&pcandidate ) ) ) + { + m_nCandidateRefCount++; + MakeCandidateStrings( pcandidate ); + pcandidate->Release(); + } + + pElement->Release(); + return S_OK; +} + +STDAPI CTsfUiLessMode::CUIElementSink::UpdateUIElement( DWORD dwUIElementId ) +{ + ITfUIElement* pElement = GetUIElement( dwUIElementId ); + if( !pElement ) + return E_INVALIDARG; + + ITfReadingInformationUIElement* preading = NULL; + ITfCandidateListUIElement* pcandidate = NULL; + if( !g_bCandList && SUCCEEDED( pElement->QueryInterface( __uuidof( ITfReadingInformationUIElement ), + ( void** )&preading ) ) ) + { + MakeReadingInformationString( preading ); + preading->Release(); + } + else if( SUCCEEDED( pElement->QueryInterface( __uuidof( ITfCandidateListUIElement ), + ( void** )&pcandidate ) ) ) + { + MakeCandidateStrings( pcandidate ); + pcandidate->Release(); + } + + pElement->Release(); + return S_OK; +} + +STDAPI CTsfUiLessMode::CUIElementSink::EndUIElement( DWORD dwUIElementId ) +{ + ITfUIElement* pElement = GetUIElement( dwUIElementId ); + if( !pElement ) + return E_INVALIDARG; + + ITfReadingInformationUIElement* preading = NULL; + if( !g_bCandList && SUCCEEDED( pElement->QueryInterface( __uuidof( ITfReadingInformationUIElement ), + ( void** )&preading ) ) ) + { + g_dwCount = 0; + preading->Release(); + } + + ITfCandidateListUIElement* pcandidate = NULL; + if( SUCCEEDED( pElement->QueryInterface( __uuidof( ITfCandidateListUIElement ), + ( void** )&pcandidate ) ) ) + { + m_nCandidateRefCount--; + if( m_nCandidateRefCount == 0 ) + CloseCandidateList(); + pcandidate->Release(); + } + + pElement->Release(); + return S_OK; +} + +void CTsfUiLessMode::UpdateImeState( BOOL bResetCompartmentEventSink ) +{ + ITfCompartmentMgr* pcm; + ITfCompartment* pTfOpenMode = NULL; + ITfCompartment* pTfConvMode = NULL; + if( GetCompartments( &pcm, &pTfOpenMode, &pTfConvMode ) ) + { + VARIANT valOpenMode; + VARIANT valConvMode; + pTfOpenMode->GetValue( &valOpenMode ); + pTfConvMode->GetValue( &valConvMode ); + if( valOpenMode.vt == VT_I4 ) + { + if( g_bChineseIME ) + { + g_dwState = valOpenMode.lVal != 0 && valConvMode.lVal != 0 ? IMEUI_STATE_ON : IMEUI_STATE_ENGLISH; + } + else + { + g_dwState = valOpenMode.lVal != 0 ? IMEUI_STATE_ON : IMEUI_STATE_OFF; + } + } + VariantClear( &valOpenMode ); + VariantClear( &valConvMode ); + + if( bResetCompartmentEventSink ) + { + SetupCompartmentSinks( FALSE, pTfOpenMode, pTfConvMode ); // Reset compartment sinks + } + pTfOpenMode->Release(); + pTfConvMode->Release(); + pcm->Release(); + } +} + +STDAPI CTsfUiLessMode::CUIElementSink::OnActivated( DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, + REFGUID guidProfile, HKL hkl, DWORD dwFlags ) +{ + static GUID TF_PROFILE_DAYI = + { + 0x037B2C25, 0x480C, 0x4D7F, 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A + }; + g_iCandListIndexBase = IsEqualGUID( TF_PROFILE_DAYI, guidProfile ) ? 0 : 1; + if( IsEqualIID( catid, GUID_TFCAT_TIP_KEYBOARD ) && ( dwFlags & TF_IPSINK_FLAG_ACTIVE ) ) + { + g_bChineseIME = ( dwProfileType & TF_PROFILETYPE_INPUTPROCESSOR ) && langid == LANG_CHT; + if( dwProfileType & TF_PROFILETYPE_INPUTPROCESSOR ) + { + UpdateImeState( TRUE ); + } + else + g_dwState = IMEUI_STATE_OFF; + OnInputLangChange(); + } + return S_OK; +} + +STDAPI CTsfUiLessMode::CUIElementSink::OnChange( REFGUID rguid ) +{ + UpdateImeState(); + return S_OK; +} + +void CTsfUiLessMode::MakeReadingInformationString( ITfReadingInformationUIElement* preading ) +{ + UINT cchMax; + UINT uErrorIndex = 0; + BOOL fVertical; + DWORD dwFlags; + + preading->GetUpdatedFlags( &dwFlags ); + preading->GetMaxReadingStringLength( &cchMax ); + preading->GetErrorIndex( &uErrorIndex ); // errorIndex is zero-based + preading->IsVerticalOrderPreferred( &fVertical ); + g_iReadingError = ( int )uErrorIndex; + g_bHorizontalReading = !fVertical; + g_bReadingWindow = true; + g_uCandPageSize = MAX_CANDLIST; + g_dwSelection = g_iReadingError ? g_iReadingError - 1 : ( DWORD )-1; + g_iReadingError--; // g_iReadingError is used only in horizontal window, and has to be -1 if there's no error. +#ifndef UNICODE + if( g_iReadingError > 0 ) + { + // convert g_iReadingError to byte based + LPCSTR pszNext = g_szReadingString; + for( int i = 0; i < g_iReadingError && pszNext && *pszNext; ++i ) + { + pszNext = CharNext( pszNext ); + } + if( pszNext ) // should be non-NULL, but just in case + { + g_iReadingError = pszNext - g_szReadingString; + } + } +#endif + + BSTR bstr; + if( SUCCEEDED( preading->GetString( &bstr ) ) ) + { + if( bstr ) + { +#ifndef UNICODE + char szStr[COUNTOF(g_szReadingString)*2]; + szStr[0] = 0; + int iRc = WideCharToMultiByte( CP_ACP, 0, bstr, -1, szStr, sizeof( szStr ), NULL, NULL ); + if( iRc >= sizeof( szStr ) ) + { + szStr[sizeof( szStr ) - 1] = 0; + } + StringCchCopy( g_szReadingString, COUNTOF(g_szReadingString), szStr ); +#else + StringCchCopy( g_szReadingString, COUNTOF(g_szReadingString), bstr ); +#endif + g_dwCount = cchMax; + LPCTSTR pszSource = g_szReadingString; + if( fVertical ) + { + // for vertical reading window, copy each character to g_szCandidate array. + for( UINT i = 0; i < cchMax; i++ ) + { + LPTSTR pszDest = g_szCandidate[i]; + if( *pszSource ) + { + LPTSTR pszNextSrc = CharNext( pszSource ); + SIZE_T size = ( LPSTR )pszNextSrc - ( LPSTR )pszSource; + CopyMemory( pszDest, pszSource, size ); + pszSource = pszNextSrc; + pszDest += size; + } + *pszDest = 0; + } + } + else + { + g_szCandidate[0][0] = TEXT( ' ' ); // hack to make rendering happen + } + SysFreeString( bstr ); + } + } +} + +void CTsfUiLessMode::MakeCandidateStrings( ITfCandidateListUIElement* pcandidate ) +{ + UINT uIndex = 0; + UINT uCount = 0; + UINT uCurrentPage = 0; + UINT* IndexList = NULL; + UINT uPageCnt = 0; + DWORD dwPageStart = 0; + DWORD dwPageSize = 0; + BSTR bstr; + + pcandidate->GetSelection( &uIndex ); + pcandidate->GetCount( &uCount ); + pcandidate->GetCurrentPage( &uCurrentPage ); + g_dwSelection = ( DWORD )uIndex; + g_dwCount = ( DWORD )uCount; + g_bCandList = true; + g_bReadingWindow = false; + + pcandidate->GetPageIndex( NULL, 0, &uPageCnt ); + if( uPageCnt > 0 ) + { + IndexList = ( UINT* )ImeUiCallback_Malloc( sizeof( UINT ) * uPageCnt ); + if( IndexList ) + { + pcandidate->GetPageIndex( IndexList, uPageCnt, &uPageCnt ); + dwPageStart = IndexList[uCurrentPage]; + dwPageSize = ( uCurrentPage < uPageCnt - 1 ) ? + min( uCount, IndexList[uCurrentPage + 1] ) - dwPageStart: + uCount - dwPageStart; + } + } + + g_uCandPageSize = min( dwPageSize, MAX_CANDLIST ); + g_dwSelection = g_dwSelection - dwPageStart; + + memset( &g_szCandidate, 0, sizeof( g_szCandidate ) ); + for( UINT i = dwPageStart, j = 0; ( DWORD )i < g_dwCount && j < g_uCandPageSize; i++, j++ ) + { + if( SUCCEEDED( pcandidate->GetString( i, &bstr ) ) ) + { + if( bstr ) + { +#ifndef UNICODE + char szStr[COUNTOF(g_szCandidate[0])*2]; + szStr[0] = 0; + int iRc = WideCharToMultiByte( CP_ACP, 0, bstr, -1, szStr, sizeof( szStr ), NULL, NULL ); + if( iRc >= sizeof( szStr ) ) + { + szStr[sizeof( szStr ) - 1] = 0; + } + ComposeCandidateLine( j, szStr ); +#else + ComposeCandidateLine( j, bstr ); +#endif + SysFreeString( bstr ); + } + } + } + + if( GETPRIMLANG() == LANG_KOREAN ) + { + g_dwSelection = ( DWORD )-1; + } + + if( IndexList ) + { + ImeUiCallback_Free( IndexList ); + } +} + +ITfUIElement* CTsfUiLessMode::GetUIElement( DWORD dwUIElementId ) +{ + ITfUIElementMgr* puiem; + ITfUIElement* pElement = NULL; + + if( SUCCEEDED( m_tm->QueryInterface( __uuidof( ITfUIElementMgr ), ( void** )&puiem ) ) ) + { + puiem->GetUIElement( dwUIElementId, &pElement ); + puiem->Release(); + } + + return pElement; +} + +BOOL CTsfUiLessMode::CurrentInputLocaleIsIme() +{ + BOOL ret = FALSE; + HRESULT hr; + + ITfInputProcessorProfiles* pProfiles; + hr = CoCreateInstance( CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, + __uuidof( ITfInputProcessorProfiles ), ( LPVOID* )&pProfiles ); + if( SUCCEEDED( hr ) ) + { + ITfInputProcessorProfileMgr* pProfileMgr; + hr = pProfiles->QueryInterface( __uuidof( ITfInputProcessorProfileMgr ), ( LPVOID* )&pProfileMgr ); + if( SUCCEEDED( hr ) ) + { + TF_INPUTPROCESSORPROFILE tip; + hr = pProfileMgr->GetActiveProfile( GUID_TFCAT_TIP_KEYBOARD, &tip ); + if( SUCCEEDED( hr ) ) + { + ret = ( tip.dwProfileType & TF_PROFILETYPE_INPUTPROCESSOR ) != 0; + } + pProfileMgr->Release(); + } + pProfiles->Release(); + } + return ret; +} + +// Sets up or removes sink for UI element. +// UI element sink should be removed when IME is disabled, +// otherwise the sink can be triggered when a game has multiple instances of IME UI library. +void CTsfUiLessMode::EnableUiUpdates( bool bEnable ) +{ + if( m_tm == NULL || + ( bEnable && m_dwUIElementSinkCookie != TF_INVALID_COOKIE ) || + ( !bEnable && m_dwUIElementSinkCookie == TF_INVALID_COOKIE ) ) + { + return; + } + ITfSource* srcTm = NULL; + HRESULT hr = E_FAIL; + if( SUCCEEDED( hr = m_tm->QueryInterface( __uuidof( ITfSource ), ( void** )&srcTm ) ) ) + { + if( bEnable ) + { + hr = srcTm->AdviseSink( __uuidof( ITfUIElementSink ), ( ITfUIElementSink* )m_TsfSink, + &m_dwUIElementSinkCookie ); + } + else + { + hr = srcTm->UnadviseSink( m_dwUIElementSinkCookie ); + m_dwUIElementSinkCookie = TF_INVALID_COOKIE; + } + srcTm->Release(); + } +} + +// Returns open mode compartments and compartment manager. +// Function fails if it fails to acquire any of the objects to be returned. +BOOL CTsfUiLessMode::GetCompartments( ITfCompartmentMgr** ppcm, ITfCompartment** ppTfOpenMode, + ITfCompartment** ppTfConvMode ) +{ + ITfCompartmentMgr* pcm = NULL; + ITfCompartment* pTfOpenMode = NULL; + ITfCompartment* pTfConvMode = NULL; + + static GUID _GUID_COMPARTMENT_KEYBOARD_INPUTMODE_CONVERSION = + { + 0xCCF05DD8, 0x4A87, 0x11D7, 0xA6, 0xE2, 0x00, 0x06, 0x5B, 0x84, 0x43, 0x5C + }; + + HRESULT hr; + if( SUCCEEDED( hr = m_tm->QueryInterface( IID_ITfCompartmentMgr, ( void** )&pcm ) ) ) + { + if( SUCCEEDED( hr = pcm->GetCompartment( GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, &pTfOpenMode ) ) ) + { + if( SUCCEEDED( hr = pcm->GetCompartment( _GUID_COMPARTMENT_KEYBOARD_INPUTMODE_CONVERSION, + &pTfConvMode ) ) ) + { + *ppcm = pcm; + *ppTfOpenMode = pTfOpenMode; + *ppTfConvMode = pTfConvMode; + return TRUE; + } + pTfOpenMode->Release(); + } + pcm->Release(); + } + return FALSE; +} + +// There are three ways to call this function: +// SetupCompartmentSinks() : initialization +// SetupCompartmentSinks(FALSE, openmode, convmode) : Resetting sinks. This is necessary as DaYi and Array IME resets compartment on switching input locale +// SetupCompartmentSinks(TRUE) : clean up sinks +BOOL CTsfUiLessMode::SetupCompartmentSinks( BOOL bRemoveOnly, ITfCompartment* pTfOpenMode, + ITfCompartment* pTfConvMode ) +{ + bool bLocalCompartments = false; + ITfCompartmentMgr* pcm = NULL; + BOOL bRc = FALSE; + HRESULT hr = E_FAIL; + + if( !pTfOpenMode && !pTfConvMode ) + { + bLocalCompartments = true; + GetCompartments( &pcm, &pTfOpenMode, &pTfConvMode ); + } + if( !( pTfOpenMode && pTfConvMode ) ) + { + // Invalid parameters or GetCompartments() has failed. + return FALSE; + } + ITfSource* srcOpenMode = NULL; + if( SUCCEEDED( hr = pTfOpenMode->QueryInterface( IID_ITfSource, ( void** )&srcOpenMode ) ) ) + { + // Remove existing sink for open mode + if( m_dwOpenModeSinkCookie != TF_INVALID_COOKIE ) + { + srcOpenMode->UnadviseSink( m_dwOpenModeSinkCookie ); + m_dwOpenModeSinkCookie = TF_INVALID_COOKIE; + } + // Setup sink for open mode (toggle state) change + if( bRemoveOnly || SUCCEEDED( hr = srcOpenMode->AdviseSink( IID_ITfCompartmentEventSink, + ( ITfCompartmentEventSink* )m_TsfSink, + &m_dwOpenModeSinkCookie ) ) ) + { + ITfSource* srcConvMode = NULL; + if( SUCCEEDED( hr = pTfConvMode->QueryInterface( IID_ITfSource, ( void** )&srcConvMode ) ) ) + { + // Remove existing sink for open mode + if( m_dwConvModeSinkCookie != TF_INVALID_COOKIE ) + { + srcConvMode->UnadviseSink( m_dwConvModeSinkCookie ); + m_dwConvModeSinkCookie = TF_INVALID_COOKIE; + } + // Setup sink for open mode (toggle state) change + if( bRemoveOnly || SUCCEEDED( hr = srcConvMode->AdviseSink( IID_ITfCompartmentEventSink, + ( ITfCompartmentEventSink* )m_TsfSink, + &m_dwConvModeSinkCookie ) ) ) + { + bRc = TRUE; + } + srcConvMode->Release(); + } + } + srcOpenMode->Release(); + } + if( bLocalCompartments ) + { + pTfOpenMode->Release(); + pTfConvMode->Release(); + pcm->Release(); + } + return bRc; +} + + +WORD ImeUi_GetPrimaryLanguage() +{ + return GETPRIMLANG(); +}; + +DWORD ImeUi_GetImeId( UINT uIndex ) +{ + return GetImeId( uIndex ); +}; + +WORD ImeUi_GetLanguage() +{ + return GETLANG(); +}; + +PTSTR ImeUi_GetIndicatior() +{ + return g_pszIndicatior; +}; + + +bool ImeUi_IsShowReadingWindow() +{ + return g_bReadingWindow; +}; + +bool ImeUi_IsShowCandListWindow() +{ + return g_bCandList; +}; + +bool ImeUi_IsVerticalCand() +{ + return g_bVerticalCand; +}; + +bool ImeUi_IsHorizontalReading() +{ + return g_bHorizontalReading; +}; + +TCHAR* ImeUi_GetCandidate( UINT idx ) +{ + if( idx < MAX_CANDLIST ) + return g_szCandidate[idx]; + else + return g_szCandidate[0]; +} + +DWORD ImeUi_GetCandidateSelection() +{ + return g_dwSelection; +} + +DWORD ImeUi_GetCandidateCount() +{ + return g_dwCount; +} + +TCHAR* ImeUi_GetCompositionString() +{ + return g_szCompositionString; +} + +BYTE* ImeUi_GetCompStringAttr() +{ + return g_szCompAttrString; +} + +DWORD ImeUi_GetImeCursorChars() +{ + return g_IMECursorChars; +} + diff --git a/Demos/DX11ClothDemo/DXUT/Optional/ImeUi.h b/Demos/DX11ClothDemo/DXUT/Optional/ImeUi.h new file mode 100644 index 0000000..c8d2b2f --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/ImeUi.h @@ -0,0 +1,124 @@ +//-------------------------------------------------------------------------------------- +// File: ImeUi.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#ifndef _IMEUI_H_ +#define _IMEUI_H_ +#if _WIN32_WINNT < 0x0400 +#error IMEUI requires _WIN32_WINNT to be 0x0400 or higher. Please add "_WIN32_WINNT=0x0400" to your project's preprocessor setting. +#endif +#include + +class CImeUiFont_Base +{ +public: + virtual void SetHeight( UINT uHeight ) + { + uHeight; + }; // for backward compatibility + virtual void SetColor( DWORD color ) = 0; + virtual void SetPosition( int x, int y ) = 0; + virtual void GetTextExtent( LPCTSTR szText, DWORD* puWidth, DWORD* puHeight ) = 0; + virtual void DrawText( LPCTSTR pszText ) = 0; +}; + +typedef struct +{ + // symbol (Henkan-kyu) + DWORD symbolColor; + DWORD symbolColorOff; + DWORD symbolColorText; + BYTE symbolHeight; + BYTE symbolTranslucence; + BYTE symbolPlacement; + CImeUiFont_Base* symbolFont; + + // candidate list + DWORD candColorBase; + DWORD candColorBorder; + DWORD candColorText; + + // composition string + DWORD compColorInput; + DWORD compColorTargetConv; + DWORD compColorConverted; + DWORD compColorTargetNotConv; + DWORD compColorInputErr; + BYTE compTranslucence; + DWORD compColorText; + + // caret + BYTE caretWidth; + BYTE caretYMargin; +} IMEUI_APPEARANCE; + +typedef struct // D3DTLVERTEX compatible +{ + float sx; + float sy; + float sz; + float rhw; + DWORD color; + DWORD specular; + float tu; + float tv; +} IMEUI_VERTEX; + +// IME States +#define IMEUI_STATE_OFF 0 +#define IMEUI_STATE_ON 1 +#define IMEUI_STATE_ENGLISH 2 + +// IME const +#define MAX_CANDLIST 10 + +// IME Flags +#define IMEUI_FLAG_SUPPORT_CARET 0x00000001 + +bool ImeUi_Initialize( HWND hwnd, bool bDisable = false ); +void ImeUi_Uninitialize(); +void ImeUi_SetAppearance( const IMEUI_APPEARANCE* pia ); +void ImeUi_GetAppearance( IMEUI_APPEARANCE* pia ); +bool ImeUi_IgnoreHotKey( const MSG* pmsg ); +LPARAM ImeUi_ProcessMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM& lParam, bool* trapped ); +void ImeUi_SetScreenDimension( UINT width, UINT height ); +void ImeUi_RenderUI( bool bDrawCompAttr = true, bool bDrawOtherUi = true ); +void ImeUi_SetCaretPosition( UINT x, UINT y ); +void ImeUi_SetCompStringAppearance( CImeUiFont_Base* pFont, DWORD color, const RECT* prc ); +bool ImeUi_GetCaretStatus(); +void ImeUi_SetInsertMode( bool bInsert ); +void ImeUi_SetState( DWORD dwState ); +DWORD ImeUi_GetState(); +void ImeUi_EnableIme( bool bEnable ); +bool ImeUi_IsEnabled( void ); +void ImeUi_FinalizeString( bool bSend = false ); +void ImeUi_ToggleLanguageBar( BOOL bRestore ); +bool ImeUi_IsSendingKeyMessage(); +void ImeUi_SetWindow( HWND hwnd ); +UINT ImeUi_GetInputCodePage(); +DWORD ImeUi_GetFlags(); +void ImeUi_SetFlags( DWORD dwFlags, bool bSet ); + +WORD ImeUi_GetPrimaryLanguage(); +DWORD ImeUi_GetImeId( UINT uIndex ); +WORD ImeUi_GetLanguage(); +LPTSTR ImeUi_GetIndicatior(); +bool ImeUi_IsShowReadingWindow(); +bool ImeUi_IsShowCandListWindow(); +bool ImeUi_IsVerticalCand(); +bool ImeUi_IsHorizontalReading(); +TCHAR* ImeUi_GetCandidate( UINT idx ); +TCHAR* ImeUi_GetCompositionString(); +DWORD ImeUi_GetCandidateSelection(); +DWORD ImeUi_GetCandidateCount(); +BYTE* ImeUi_GetCompStringAttr(); +DWORD ImeUi_GetImeCursorChars(); + +extern void ( CALLBACK*ImeUiCallback_DrawRect )( int x1, int y1, int x2, int y2, DWORD color ); +extern void* ( __cdecl*ImeUiCallback_Malloc )( size_t bytes ); +extern void ( __cdecl*ImeUiCallback_Free )( void* ptr ); +extern void ( CALLBACK*ImeUiCallback_DrawFans )( const IMEUI_VERTEX* paVertex, UINT uNum ); +extern void ( CALLBACK*ImeUiCallback_OnChar )( WCHAR wc ); + +#endif //_IMEUI_H_ diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.cpp b/Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.cpp new file mode 100644 index 0000000..42bae83 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.cpp @@ -0,0 +1,2348 @@ +//-------------------------------------------------------------------------------------- +// File: SDKMesh.cpp +// +// The SDK Mesh format (.sdkmesh) is not a recommended file format for games. +// It was designed to meet the specific needs of the SDK samples. Any real-world +// applications should avoid this file format in favor of a destination format that +// meets the specific needs of the application. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#include "DXUT.h" +#include "SDKMesh.h" +#include "SDKMisc.h" + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::LoadMaterials( ID3D11Device* pd3dDevice, SDKMESH_MATERIAL* pMaterials, UINT numMaterials, + SDKMESH_CALLBACKS11* pLoaderCallbacks ) +{ + // TODO: D3D11 + char strPath[MAX_PATH]; + + if( pLoaderCallbacks && pLoaderCallbacks->pCreateTextureFromFile ) + { + for( UINT m = 0; m < numMaterials; m++ ) + { + pMaterials[m].pDiffuseTexture11 = NULL; + pMaterials[m].pNormalTexture11 = NULL; + pMaterials[m].pSpecularTexture11 = NULL; + pMaterials[m].pDiffuseRV11 = NULL; + pMaterials[m].pNormalRV11 = NULL; + pMaterials[m].pSpecularRV11 = NULL; + + // load textures + if( pMaterials[m].DiffuseTexture[0] != 0 ) + { + pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice, + pMaterials[m].DiffuseTexture, &pMaterials[m].pDiffuseRV11, + pLoaderCallbacks->pContext ); + } + if( pMaterials[m].NormalTexture[0] != 0 ) + { + pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice, + pMaterials[m].NormalTexture, &pMaterials[m].pNormalRV11, + pLoaderCallbacks->pContext ); + } + if( pMaterials[m].SpecularTexture[0] != 0 ) + { + pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice, + pMaterials[m].SpecularTexture, &pMaterials[m].pSpecularRV11, + pLoaderCallbacks->pContext ); + } + } + } + else + { + for( UINT m = 0; m < numMaterials; m++ ) + { + pMaterials[m].pDiffuseTexture11 = NULL; + pMaterials[m].pNormalTexture11 = NULL; + pMaterials[m].pSpecularTexture11 = NULL; + pMaterials[m].pDiffuseRV11 = NULL; + pMaterials[m].pNormalRV11 = NULL; + pMaterials[m].pSpecularRV11 = NULL; + + // load textures + if( pMaterials[m].DiffuseTexture[0] != 0 ) + { + sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].DiffuseTexture ); + if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(), + strPath, &pMaterials[m].pDiffuseRV11, + true ) ) ) + pMaterials[m].pDiffuseRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE; + + } + if( pMaterials[m].NormalTexture[0] != 0 ) + { + sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].NormalTexture ); + if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(), + strPath, + &pMaterials[m].pNormalRV11 ) ) ) + pMaterials[m].pNormalRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE; + } + if( pMaterials[m].SpecularTexture[0] != 0 ) + { + sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].SpecularTexture ); + if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(), + strPath, + &pMaterials[m].pSpecularRV11 ) ) ) + pMaterials[m].pSpecularRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE; + } + } + } +} + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::LoadMaterials( IDirect3DDevice9* pd3dDevice, SDKMESH_MATERIAL* pMaterials, UINT numMaterials, + SDKMESH_CALLBACKS9* pLoaderCallbacks ) +{ + char strPath[MAX_PATH]; + + if( pLoaderCallbacks && pLoaderCallbacks->pCreateTextureFromFile ) + { + for( UINT m = 0; m < numMaterials; m++ ) + { + pMaterials[m].pDiffuseTexture9 = NULL; + pMaterials[m].pNormalTexture9 = NULL; + pMaterials[m].pSpecularTexture9 = NULL; + + // load textures + if( pMaterials[m].DiffuseTexture[0] != 0 ) + { + pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice, + pMaterials[m].DiffuseTexture, + &pMaterials[m].pDiffuseTexture9, + pLoaderCallbacks->pContext ); + } + if( pMaterials[m].NormalTexture[0] != 0 ) + { + pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice, + pMaterials[m].NormalTexture, &pMaterials[m].pNormalTexture9, + pLoaderCallbacks->pContext ); + } + if( pMaterials[m].SpecularTexture[0] != 0 ) + { + pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice, + pMaterials[m].SpecularTexture, + &pMaterials[m].pSpecularTexture9, + pLoaderCallbacks->pContext ); + } + } + } + else + { + for( UINT m = 0; m < numMaterials; m++ ) + { + pMaterials[m].pDiffuseTexture9 = NULL; + pMaterials[m].pNormalTexture9 = NULL; + pMaterials[m].pSpecularTexture9 = NULL; + pMaterials[m].pDiffuseRV11 = NULL; + pMaterials[m].pNormalRV11 = NULL; + pMaterials[m].pSpecularRV11 = NULL; + + // load textures + if( pMaterials[m].DiffuseTexture[0] != 0 ) + { + sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].DiffuseTexture ); + if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, + strPath, + &pMaterials[m].pDiffuseTexture9 ) ) ) + pMaterials[m].pDiffuseTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE; + } + if( pMaterials[m].NormalTexture[0] != 0 ) + { + sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].NormalTexture ); + if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, + strPath, + &pMaterials[m].pNormalTexture9 ) ) ) + pMaterials[m].pNormalTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE; + } + if( pMaterials[m].SpecularTexture[0] != 0 ) + { + sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].SpecularTexture ); + if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, + strPath, + &pMaterials[m].pSpecularTexture9 ) ) ) + pMaterials[m].pSpecularTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE; + } + + } + } +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::CreateVertexBuffer( ID3D11Device* pd3dDevice, SDKMESH_VERTEX_BUFFER_HEADER* pHeader, + void* pVertices, SDKMESH_CALLBACKS11* pLoaderCallbacks ) +{ + HRESULT hr = S_OK; + pHeader->DataOffset = 0; + //Vertex Buffer + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = ( UINT )( pHeader->SizeBytes ); + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + + if( pLoaderCallbacks && pLoaderCallbacks->pCreateVertexBuffer ) + { + pLoaderCallbacks->pCreateVertexBuffer( pd3dDevice, &pHeader->pVB11, bufferDesc, pVertices, + pLoaderCallbacks->pContext ); + } + else + { + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = pVertices; + hr = pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &pHeader->pVB11 ); + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::CreateIndexBuffer( ID3D11Device* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader, + void* pIndices, SDKMESH_CALLBACKS11* pLoaderCallbacks ) +{ + HRESULT hr = S_OK; + pHeader->DataOffset = 0; + //Index Buffer + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = ( UINT )( pHeader->SizeBytes ); + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + + if( pLoaderCallbacks && pLoaderCallbacks->pCreateIndexBuffer ) + { + pLoaderCallbacks->pCreateIndexBuffer( pd3dDevice, &pHeader->pIB11, bufferDesc, pIndices, + pLoaderCallbacks->pContext ); + } + else + { + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = pIndices; + hr = pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &pHeader->pIB11 ); + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::CreateVertexBuffer( IDirect3DDevice9* pd3dDevice, SDKMESH_VERTEX_BUFFER_HEADER* pHeader, + void* pVertices, SDKMESH_CALLBACKS9* pLoaderCallbacks ) +{ + HRESULT hr = S_OK; + + pHeader->DataOffset = 0; + if( pLoaderCallbacks && pLoaderCallbacks->pCreateVertexBuffer ) + { + pLoaderCallbacks->pCreateVertexBuffer( pd3dDevice, &pHeader->pVB9, ( UINT )pHeader->SizeBytes, + D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, pVertices, + pLoaderCallbacks->pContext ); + } + else + { + hr = pd3dDevice->CreateVertexBuffer( ( UINT )pHeader->SizeBytes, + D3DUSAGE_WRITEONLY, + 0, + D3DPOOL_DEFAULT, + &pHeader->pVB9, + NULL ); + + //lock + if( SUCCEEDED( hr ) ) + { + void* pLockedVerts = NULL; + V_RETURN( pHeader->pVB9->Lock( 0, 0, &pLockedVerts, 0 ) ); + CopyMemory( pLockedVerts, pVertices, ( size_t )pHeader->SizeBytes ); + pHeader->pVB9->Unlock(); + } + } + + return hr; +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::CreateIndexBuffer( IDirect3DDevice9* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader, + void* pIndices, SDKMESH_CALLBACKS9* pLoaderCallbacks ) +{ + HRESULT hr = S_OK; + + pHeader->DataOffset = 0; + + D3DFORMAT ibFormat = D3DFMT_INDEX16; + switch( pHeader->IndexType ) + { + case IT_16BIT: + ibFormat = D3DFMT_INDEX16; + break; + case IT_32BIT: + ibFormat = D3DFMT_INDEX32; + break; + }; + + if( pLoaderCallbacks && pLoaderCallbacks->pCreateIndexBuffer ) + { + pLoaderCallbacks->pCreateIndexBuffer( pd3dDevice, &pHeader->pIB9, ( UINT )pHeader->SizeBytes, + D3DUSAGE_WRITEONLY, ibFormat, D3DPOOL_DEFAULT, pIndices, + pLoaderCallbacks->pContext ); + } + else + { + hr = pd3dDevice->CreateIndexBuffer( ( UINT )( pHeader->SizeBytes ), + D3DUSAGE_WRITEONLY, + ibFormat, + D3DPOOL_DEFAULT, + &pHeader->pIB9, + NULL ); + + if( SUCCEEDED( hr ) ) + { + void* pLockedIndices = NULL; + V_RETURN( pHeader->pIB9->Lock( 0, 0, &pLockedIndices, 0 ) ); + CopyMemory( pLockedIndices, pIndices, ( size_t )( pHeader->SizeBytes ) ); + pHeader->pIB9->Unlock(); + } + } + + return hr; +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::CreateFromFile( ID3D11Device* pDev11, + IDirect3DDevice9* pDev9, + LPCTSTR szFileName, + bool bCreateAdjacencyIndices, + SDKMESH_CALLBACKS11* pLoaderCallbacks11, + SDKMESH_CALLBACKS9* pLoaderCallbacks9 ) +{ + HRESULT hr = S_OK; + + // Find the path for the file + V_RETURN( DXUTFindDXSDKMediaFileCch( m_strPathW, sizeof( m_strPathW ) / sizeof( WCHAR ), szFileName ) ); + + // Open the file + m_hFile = CreateFile( m_strPathW, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, + NULL ); + if( INVALID_HANDLE_VALUE == m_hFile ) + return DXUTERR_MEDIANOTFOUND; + + // Change the path to just the directory + WCHAR* pLastBSlash = wcsrchr( m_strPathW, L'\\' ); + if( pLastBSlash ) + *( pLastBSlash + 1 ) = L'\0'; + else + *m_strPathW = L'\0'; + + WideCharToMultiByte( CP_ACP, 0, m_strPathW, -1, m_strPath, MAX_PATH, NULL, FALSE ); + + // Get the file size + LARGE_INTEGER FileSize; + GetFileSizeEx( m_hFile, &FileSize ); + UINT cBytes = FileSize.LowPart; + + // Allocate memory + m_pStaticMeshData = new BYTE[ cBytes ]; + if( !m_pStaticMeshData ) + { + CloseHandle( m_hFile ); + return E_OUTOFMEMORY; + } + + // Read in the file + DWORD dwBytesRead; + if( !ReadFile( m_hFile, m_pStaticMeshData, cBytes, &dwBytesRead, NULL ) ) + hr = E_FAIL; + + CloseHandle( m_hFile ); + + if( SUCCEEDED( hr ) ) + { + hr = CreateFromMemory( pDev11, + pDev9, + m_pStaticMeshData, + cBytes, + bCreateAdjacencyIndices, + false, + pLoaderCallbacks11, + pLoaderCallbacks9 ); + if( FAILED( hr ) ) + delete []m_pStaticMeshData; + } + + return hr; +} + +HRESULT CDXUTSDKMesh::CreateFromMemory( ID3D11Device* pDev11, + IDirect3DDevice9* pDev9, + BYTE* pData, + UINT DataBytes, + bool bCreateAdjacencyIndices, + bool bCopyStatic, + SDKMESH_CALLBACKS11* pLoaderCallbacks11, + SDKMESH_CALLBACKS9* pLoaderCallbacks9 ) +{ + HRESULT hr = E_FAIL; + D3DXVECTOR3 lower; + D3DXVECTOR3 upper; + + m_pDev9 = pDev9; + m_pDev11 = pDev11; + + // Set outstanding resources to zero + m_NumOutstandingResources = 0; + + if( bCopyStatic ) + { + SDKMESH_HEADER* pHeader = ( SDKMESH_HEADER* )pData; + + SIZE_T StaticSize = ( SIZE_T )( pHeader->HeaderSize + pHeader->NonBufferDataSize ); + m_pHeapData = new BYTE[ StaticSize ]; + if( !m_pHeapData ) + return hr; + + m_pStaticMeshData = m_pHeapData; + + CopyMemory( m_pStaticMeshData, pData, StaticSize ); + } + else + { + m_pHeapData = pData; + m_pStaticMeshData = pData; + } + + // Pointer fixup + m_pMeshHeader = ( SDKMESH_HEADER* )m_pStaticMeshData; + m_pVertexBufferArray = ( SDKMESH_VERTEX_BUFFER_HEADER* )( m_pStaticMeshData + + m_pMeshHeader->VertexStreamHeadersOffset ); + m_pIndexBufferArray = ( SDKMESH_INDEX_BUFFER_HEADER* )( m_pStaticMeshData + + m_pMeshHeader->IndexStreamHeadersOffset ); + m_pMeshArray = ( SDKMESH_MESH* )( m_pStaticMeshData + m_pMeshHeader->MeshDataOffset ); + m_pSubsetArray = ( SDKMESH_SUBSET* )( m_pStaticMeshData + m_pMeshHeader->SubsetDataOffset ); + m_pFrameArray = ( SDKMESH_FRAME* )( m_pStaticMeshData + m_pMeshHeader->FrameDataOffset ); + m_pMaterialArray = ( SDKMESH_MATERIAL* )( m_pStaticMeshData + m_pMeshHeader->MaterialDataOffset ); + + // Setup subsets + for( UINT i = 0; i < m_pMeshHeader->NumMeshes; i++ ) + { + m_pMeshArray[i].pSubsets = ( UINT* )( m_pStaticMeshData + m_pMeshArray[i].SubsetOffset ); + m_pMeshArray[i].pFrameInfluences = ( UINT* )( m_pStaticMeshData + m_pMeshArray[i].FrameInfluenceOffset ); + } + + // error condition + if( m_pMeshHeader->Version != SDKMESH_FILE_VERSION ) + { + hr = E_NOINTERFACE; + goto Error; + } + + // Setup buffer data pointer + BYTE* pBufferData = pData + m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize; + + // Get the start of the buffer data + UINT64 BufferDataStart = m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize; + + // Create VBs + m_ppVertices = new BYTE*[m_pMeshHeader->NumVertexBuffers]; + for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ ) + { + BYTE* pVertices = NULL; + pVertices = ( BYTE* )( pBufferData + ( m_pVertexBufferArray[i].DataOffset - BufferDataStart ) ); + + if( pDev11 ) + CreateVertexBuffer( pDev11, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks11 ); + else if( pDev9 ) + CreateVertexBuffer( pDev9, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks9 ); + + m_ppVertices[i] = pVertices; + } + + // Create IBs + m_ppIndices = new BYTE*[m_pMeshHeader->NumIndexBuffers]; + for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ ) + { + BYTE* pIndices = NULL; + pIndices = ( BYTE* )( pBufferData + ( m_pIndexBufferArray[i].DataOffset - BufferDataStart ) ); + + if( pDev11 ) + CreateIndexBuffer( pDev11, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks11 ); + else if( pDev9 ) + CreateIndexBuffer( pDev9, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks9 ); + + m_ppIndices[i] = pIndices; + } + + // Load Materials + if( pDev11 ) + LoadMaterials( pDev11, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks11 ); + else if( pDev9 ) + LoadMaterials( pDev9, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks9 ); + + // Create a place to store our bind pose frame matrices + m_pBindPoseFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ]; + if( !m_pBindPoseFrameMatrices ) + goto Error; + + // Create a place to store our transformed frame matrices + m_pTransformedFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ]; + if( !m_pTransformedFrameMatrices ) + goto Error; + m_pWorldPoseFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ]; + if( !m_pWorldPoseFrameMatrices ) + goto Error; + + SDKMESH_SUBSET* pSubset = NULL; + D3D11_PRIMITIVE_TOPOLOGY PrimType; + + // update bounding volume + SDKMESH_MESH* currentMesh = &m_pMeshArray[0]; + int tris = 0; + for (UINT meshi=0; meshi < m_pMeshHeader->NumMeshes; ++meshi) { + lower.x = FLT_MAX; lower.y = FLT_MAX; lower.z = FLT_MAX; + upper.x = -FLT_MAX; upper.y = -FLT_MAX; upper.z = -FLT_MAX; + currentMesh = GetMesh( meshi ); + INT indsize; + if (m_pIndexBufferArray[currentMesh->IndexBuffer].IndexType == IT_16BIT ) { + indsize = 2; + }else { + indsize = 4; + } + + for( UINT subset = 0; subset < currentMesh->NumSubsets; subset++ ) + { + pSubset = GetSubset( meshi, subset ); //&m_pSubsetArray[ currentMesh->pSubsets[subset] ]; + + PrimType = GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType ); + assert( PrimType == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );// only triangle lists are handled. + + UINT IndexCount = ( UINT )pSubset->IndexCount; + UINT IndexStart = ( UINT )pSubset->IndexStart; + + /*if( bAdjacent ) + { + IndexCount *= 2; + IndexStart *= 2; + }*/ + + //BYTE* pIndices = NULL; + //m_ppIndices[i] + UINT *ind = ( UINT * )m_ppIndices[currentMesh->IndexBuffer]; + FLOAT *verts = ( FLOAT* )m_ppVertices[currentMesh->VertexBuffers[0]]; + UINT stride = (UINT)m_pVertexBufferArray[currentMesh->VertexBuffers[0]].StrideBytes; + assert (stride % 4 == 0); + stride /=4; + for (UINT vertind = IndexStart; vertind < IndexStart + IndexCount; ++vertind) { //TODO: test 16 bit and 32 bit + UINT current_ind=0; + if (indsize == 2) { + UINT ind_div2 = vertind / 2; + current_ind = ind[ind_div2]; + if (vertind %2 ==0) { + current_ind = current_ind << 16; + current_ind = current_ind >> 16; + }else { + current_ind = current_ind >> 16; + } + }else { + current_ind = ind[vertind]; + } + tris++; + D3DXVECTOR3 *pt = (D3DXVECTOR3*)&(verts[stride * current_ind]); + if (pt->x < lower.x) { + lower.x = pt->x; + } + if (pt->y < lower.y) { + lower.y = pt->y; + } + if (pt->z < lower.z) { + lower.z = pt->z; + } + if (pt->x > upper.x) { + upper.x = pt->x; + } + if (pt->y > upper.y) { + upper.y = pt->y; + } + if (pt->z > upper.z) { + upper.z = pt->z; + } + //BYTE** m_ppVertices; + //BYTE** m_ppIndices; + } + //pd3dDeviceContext->DrawIndexed( IndexCount, IndexStart, VertexStart ); + } + + D3DXVECTOR3 half = upper - lower; + half *=0.5f; + + currentMesh->BoundingBoxCenter = lower + half; + currentMesh->BoundingBoxExtents = half; + + } + // Update + + + + hr = S_OK; +Error: + + if( !pLoaderCallbacks9 ) + { + CheckLoadDone(); + } + + return hr; +} + +//-------------------------------------------------------------------------------------- +// transform bind pose frame using a recursive traversal +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::TransformBindPoseFrame( UINT iFrame, D3DXMATRIX* pParentWorld ) +{ + if( !m_pBindPoseFrameMatrices ) + return; + + // Transform ourselves + D3DXMATRIX LocalWorld; + D3DXMatrixMultiply( &LocalWorld, &m_pFrameArray[iFrame].Matrix, pParentWorld ); + m_pBindPoseFrameMatrices[iFrame] = LocalWorld; + + // Transform our siblings + if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME ) + TransformBindPoseFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld ); + + // Transform our children + if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME ) + TransformBindPoseFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld ); +} + +//-------------------------------------------------------------------------------------- +// transform frame using a recursive traversal +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::TransformFrame( UINT iFrame, D3DXMATRIX* pParentWorld, double fTime ) +{ + // Get the tick data + D3DXMATRIX LocalTransform; + UINT iTick = GetAnimationKeyFromTime( fTime ); + + if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex ) + { + SDKANIMATION_FRAME_DATA* pFrameData = &m_pAnimationFrameData[ m_pFrameArray[iFrame].AnimationDataIndex ]; + SDKANIMATION_DATA* pData = &pFrameData->pAnimationData[ iTick ]; + + // turn it into a matrix (Ignore scaling for now) + D3DXVECTOR3 parentPos = pData->Translation; + D3DXMATRIX mTranslate; + D3DXMatrixTranslation( &mTranslate, parentPos.x, parentPos.y, parentPos.z ); + + D3DXQUATERNION quat; + D3DXMATRIX mQuat; + quat.w = pData->Orientation.w; + quat.x = pData->Orientation.x; + quat.y = pData->Orientation.y; + quat.z = pData->Orientation.z; + if( quat.w == 0 && quat.x == 0 && quat.y == 0 && quat.z == 0 ) + D3DXQuaternionIdentity( &quat ); + D3DXQuaternionNormalize( &quat, &quat ); + D3DXMatrixRotationQuaternion( &mQuat, &quat ); + LocalTransform = ( mQuat * mTranslate ); + } + else + { + LocalTransform = m_pFrameArray[iFrame].Matrix; + } + + // Transform ourselves + D3DXMATRIX LocalWorld; + D3DXMatrixMultiply( &LocalWorld, &LocalTransform, pParentWorld ); + m_pTransformedFrameMatrices[iFrame] = LocalWorld; + m_pWorldPoseFrameMatrices[iFrame] = LocalWorld; + + // Transform our siblings + if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME ) + TransformFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld, fTime ); + + // Transform our children + if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME ) + TransformFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld, fTime ); +} + +//-------------------------------------------------------------------------------------- +// transform frame assuming that it is an absolute transformation +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::TransformFrameAbsolute( UINT iFrame, double fTime ) +{ + D3DXMATRIX mTrans1; + D3DXMATRIX mTrans2; + D3DXMATRIX mRot1; + D3DXMATRIX mRot2; + D3DXQUATERNION quat1; + D3DXQUATERNION quat2; + D3DXMATRIX mTo; + D3DXMATRIX mInvTo; + D3DXMATRIX mFrom; + + UINT iTick = GetAnimationKeyFromTime( fTime ); + + if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex ) + { + SDKANIMATION_FRAME_DATA* pFrameData = &m_pAnimationFrameData[ m_pFrameArray[iFrame].AnimationDataIndex ]; + SDKANIMATION_DATA* pData = &pFrameData->pAnimationData[ iTick ]; + SDKANIMATION_DATA* pDataOrig = &pFrameData->pAnimationData[ 0 ]; + + D3DXMatrixTranslation( &mTrans1, -pDataOrig->Translation.x, + -pDataOrig->Translation.y, + -pDataOrig->Translation.z ); + D3DXMatrixTranslation( &mTrans2, pData->Translation.x, + pData->Translation.y, + pData->Translation.z ); + + quat1.x = pDataOrig->Orientation.x; + quat1.y = pDataOrig->Orientation.y; + quat1.z = pDataOrig->Orientation.z; + quat1.w = pDataOrig->Orientation.w; + D3DXQuaternionInverse( &quat1, &quat1 ); + D3DXMatrixRotationQuaternion( &mRot1, &quat1 ); + mInvTo = mTrans1 * mRot1; + + quat2.x = pData->Orientation.x; + quat2.y = pData->Orientation.y; + quat2.z = pData->Orientation.z; + quat2.w = pData->Orientation.w; + D3DXMatrixRotationQuaternion( &mRot2, &quat2 ); + mFrom = mRot2 * mTrans2; + + D3DXMATRIX mOutput = mInvTo * mFrom; + m_pTransformedFrameMatrices[iFrame] = mOutput; + } +} + +#define MAX_D3D11_VERTEX_STREAMS D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::RenderMesh( UINT iMesh, + bool bAdjacent, + ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot, + UINT iNormalSlot, + UINT iSpecularSlot ) +{ + if( 0 < GetOutstandingBufferResources() ) + return; + + SDKMESH_MESH* pMesh = &m_pMeshArray[iMesh]; + + UINT Strides[MAX_D3D11_VERTEX_STREAMS]; + UINT Offsets[MAX_D3D11_VERTEX_STREAMS]; + ID3D11Buffer* pVB[MAX_D3D11_VERTEX_STREAMS]; + + if( pMesh->NumVertexBuffers > MAX_D3D11_VERTEX_STREAMS ) + return; + + for( UINT64 i = 0; i < pMesh->NumVertexBuffers; i++ ) + { + pVB[i] = m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].pVB11; + Strides[i] = ( UINT )m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].StrideBytes; + Offsets[i] = 0; + } + + SDKMESH_INDEX_BUFFER_HEADER* pIndexBufferArray; + if( bAdjacent ) + pIndexBufferArray = m_pAdjacencyIndexBufferArray; + else + pIndexBufferArray = m_pIndexBufferArray; + + ID3D11Buffer* pIB = pIndexBufferArray[ pMesh->IndexBuffer ].pIB11; + DXGI_FORMAT ibFormat = DXGI_FORMAT_R16_UINT; + switch( pIndexBufferArray[ pMesh->IndexBuffer ].IndexType ) + { + case IT_16BIT: + ibFormat = DXGI_FORMAT_R16_UINT; + break; + case IT_32BIT: + ibFormat = DXGI_FORMAT_R32_UINT; + break; + }; + + pd3dDeviceContext->IASetVertexBuffers( 0, pMesh->NumVertexBuffers, pVB, Strides, Offsets ); + pd3dDeviceContext->IASetIndexBuffer( pIB, ibFormat, 0 ); + + SDKMESH_SUBSET* pSubset = NULL; + SDKMESH_MATERIAL* pMat = NULL; + D3D11_PRIMITIVE_TOPOLOGY PrimType; + + for( UINT subset = 0; subset < pMesh->NumSubsets; subset++ ) + { + pSubset = &m_pSubsetArray[ pMesh->pSubsets[subset] ]; + + PrimType = GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType ); + if( bAdjacent ) + { + switch( PrimType ) + { + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST: + PrimType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ; + break; + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP: + PrimType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ; + break; + case D3D11_PRIMITIVE_TOPOLOGY_LINELIST: + PrimType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; + break; + case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP: + PrimType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ; + break; + } + } + + pd3dDeviceContext->IASetPrimitiveTopology( PrimType ); + + pMat = &m_pMaterialArray[ pSubset->MaterialID ]; + if( iDiffuseSlot != INVALID_SAMPLER_SLOT && !IsErrorResource( pMat->pDiffuseRV11 ) ) + pd3dDeviceContext->PSSetShaderResources( iDiffuseSlot, 1, &pMat->pDiffuseRV11 ); + if( iNormalSlot != INVALID_SAMPLER_SLOT && !IsErrorResource( pMat->pNormalRV11 ) ) + pd3dDeviceContext->PSSetShaderResources( iNormalSlot, 1, &pMat->pNormalRV11 ); + if( iSpecularSlot != INVALID_SAMPLER_SLOT && !IsErrorResource( pMat->pSpecularRV11 ) ) + pd3dDeviceContext->PSSetShaderResources( iSpecularSlot, 1, &pMat->pSpecularRV11 ); + + UINT IndexCount = ( UINT )pSubset->IndexCount; + UINT IndexStart = ( UINT )pSubset->IndexStart; + UINT VertexStart = ( UINT )pSubset->VertexStart; + if( bAdjacent ) + { + IndexCount *= 2; + IndexStart *= 2; + } + + pd3dDeviceContext->DrawIndexed( IndexCount, IndexStart, VertexStart ); + } +} + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::RenderFrame( UINT iFrame, + bool bAdjacent, + ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot, + UINT iNormalSlot, + UINT iSpecularSlot ) +{ + if( !m_pStaticMeshData || !m_pFrameArray ) + return; + + if( m_pFrameArray[iFrame].Mesh != INVALID_MESH ) + { + RenderMesh( m_pFrameArray[iFrame].Mesh, + bAdjacent, + pd3dDeviceContext, + iDiffuseSlot, + iNormalSlot, + iSpecularSlot ); + } + + // Render our children + if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME ) + RenderFrame( m_pFrameArray[iFrame].ChildFrame, bAdjacent, pd3dDeviceContext, iDiffuseSlot, + iNormalSlot, iSpecularSlot ); + + // Render our siblings + if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME ) + RenderFrame( m_pFrameArray[iFrame].SiblingFrame, bAdjacent, pd3dDeviceContext, iDiffuseSlot, + iNormalSlot, iSpecularSlot ); +} + +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::RenderMesh( UINT iMesh, + LPDIRECT3DDEVICE9 pd3dDevice, + LPD3DXEFFECT pEffect, + D3DXHANDLE hTechnique, + D3DXHANDLE htxDiffuse, + D3DXHANDLE htxNormal, + D3DXHANDLE htxSpecular ) +{ + if( 0 < GetOutstandingBufferResources() ) + return; + + SDKMESH_MESH* pMesh = &m_pMeshArray[iMesh]; + + // set vb streams + for( UINT i = 0; i < ( UINT )pMesh->NumVertexBuffers; i++ ) + { + pd3dDevice->SetStreamSource( i, + m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].pVB9, + 0, + ( UINT )m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].StrideBytes ); + } + + // Set our index buffer as well + pd3dDevice->SetIndices( m_pIndexBufferArray[ pMesh->IndexBuffer ].pIB9 ); + + // Render the scene with this technique + pEffect->SetTechnique( hTechnique ); + + SDKMESH_SUBSET* pSubset = NULL; + SDKMESH_MATERIAL* pMat = NULL; + D3DPRIMITIVETYPE PrimType; + UINT cPasses = 0; + pEffect->Begin( &cPasses, 0 ); + + for( UINT p = 0; p < cPasses; ++p ) + { + pEffect->BeginPass( p ); + + for( UINT subset = 0; subset < pMesh->NumSubsets; subset++ ) + { + pSubset = &m_pSubsetArray[ pMesh->pSubsets[subset] ]; + + PrimType = GetPrimitiveType9( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType ); + + if( INVALID_MATERIAL != pSubset->MaterialID && m_pMeshHeader->NumMaterials > 0 ) + { + pMat = &m_pMaterialArray[ pSubset->MaterialID ]; + if( htxDiffuse && !IsErrorResource( pMat->pDiffuseTexture9 ) ) + pEffect->SetTexture( htxDiffuse, pMat->pDiffuseTexture9 ); + if( htxNormal && !IsErrorResource( pMat->pNormalTexture9 ) ) + pEffect->SetTexture( htxNormal, pMat->pNormalTexture9 ); + if( htxSpecular && !IsErrorResource( pMat->pSpecularTexture9 ) ) + pEffect->SetTexture( htxSpecular, pMat->pSpecularTexture9 ); + } + + pEffect->CommitChanges(); + + UINT PrimCount = ( UINT )pSubset->IndexCount; + UINT IndexStart = ( UINT )pSubset->IndexStart; + UINT VertexStart = ( UINT )pSubset->VertexStart; + UINT VertexCount = ( UINT )pSubset->VertexCount; + if( D3DPT_TRIANGLELIST == PrimType ) + PrimCount /= 3; + if( D3DPT_LINELIST == PrimType ) + PrimCount /= 2; + if( D3DPT_TRIANGLESTRIP == PrimType ) + PrimCount = ( PrimCount - 3 ) + 1; + if( D3DPT_LINESTRIP == PrimType ) + PrimCount -= 1; + + pd3dDevice->DrawIndexedPrimitive( PrimType, VertexStart, 0, VertexCount, IndexStart, PrimCount ); + } + + pEffect->EndPass(); + } + + pEffect->End(); +} + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::RenderFrame( UINT iFrame, + LPDIRECT3DDEVICE9 pd3dDevice, + LPD3DXEFFECT pEffect, + D3DXHANDLE hTechnique, + D3DXHANDLE htxDiffuse, + D3DXHANDLE htxNormal, + D3DXHANDLE htxSpecular ) +{ + if( !m_pStaticMeshData || !m_pFrameArray ) + return; + + if( m_pFrameArray[iFrame].Mesh != INVALID_MESH ) + { + RenderMesh( m_pFrameArray[iFrame].Mesh, + pd3dDevice, + pEffect, + hTechnique, + htxDiffuse, + htxNormal, + htxSpecular ); + } + + // Render our children + if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME ) + RenderFrame( m_pFrameArray[iFrame].ChildFrame, pd3dDevice, pEffect, hTechnique, htxDiffuse, htxNormal, + htxSpecular ); + + // Render our siblings + if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME ) + RenderFrame( m_pFrameArray[iFrame].SiblingFrame, pd3dDevice, pEffect, hTechnique, htxDiffuse, htxNormal, + htxSpecular ); +} + + +//-------------------------------------------------------------------------------------- +CDXUTSDKMesh::CDXUTSDKMesh() : m_NumOutstandingResources( 0 ), + m_bLoading( false ), + m_hFile( 0 ), + m_hFileMappingObject( 0 ), + m_pMeshHeader( NULL ), + m_pStaticMeshData( NULL ), + m_pHeapData( NULL ), + m_pAdjacencyIndexBufferArray( NULL ), + m_pAnimationData( NULL ), + m_pAnimationHeader( NULL ), + m_ppVertices( NULL ), + m_ppIndices( NULL ), + m_pBindPoseFrameMatrices( NULL ), + m_pTransformedFrameMatrices( NULL ), + m_pWorldPoseFrameMatrices( NULL ), + m_pDev9( NULL ), + m_pDev11( NULL ) +{ +} + + +//-------------------------------------------------------------------------------------- +CDXUTSDKMesh::~CDXUTSDKMesh() +{ + Destroy(); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::Create( ID3D11Device* pDev11, LPCTSTR szFileName, bool bCreateAdjacencyIndices, + SDKMESH_CALLBACKS11* pLoaderCallbacks ) +{ + return CreateFromFile( pDev11, NULL, szFileName, bCreateAdjacencyIndices, pLoaderCallbacks, NULL ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::Create( IDirect3DDevice9* pDev9, LPCTSTR szFileName, bool bCreateAdjacencyIndices, + SDKMESH_CALLBACKS9* pLoaderCallbacks ) +{ + return CreateFromFile( NULL, pDev9, szFileName, bCreateAdjacencyIndices, NULL, pLoaderCallbacks ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::Create( ID3D11Device* pDev11, BYTE* pData, UINT DataBytes, bool bCreateAdjacencyIndices, + bool bCopyStatic, SDKMESH_CALLBACKS11* pLoaderCallbacks ) +{ + return CreateFromMemory( pDev11, NULL, pData, DataBytes, bCreateAdjacencyIndices, bCopyStatic, + pLoaderCallbacks, NULL ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::Create( IDirect3DDevice9* pDev9, BYTE* pData, UINT DataBytes, bool bCreateAdjacencyIndices, + bool bCopyStatic, SDKMESH_CALLBACKS9* pLoaderCallbacks ) +{ + return CreateFromMemory( NULL, pDev9, pData, DataBytes, bCreateAdjacencyIndices, bCopyStatic, NULL, + pLoaderCallbacks ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTSDKMesh::LoadAnimation( WCHAR* szFileName ) +{ + HRESULT hr = E_FAIL; + DWORD dwBytesRead = 0; + LARGE_INTEGER liMove; + WCHAR strPath[MAX_PATH]; + + // Find the path for the file + V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, szFileName ) ); + + // Open the file + HANDLE hFile = CreateFile( strPath, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, NULL ); + if( INVALID_HANDLE_VALUE == hFile ) + return DXUTERR_MEDIANOTFOUND; + + ///////////////////////// + // Header + SDKANIMATION_FILE_HEADER fileheader; + if( !ReadFile( hFile, &fileheader, sizeof( SDKANIMATION_FILE_HEADER ), &dwBytesRead, NULL ) ) + goto Error; + + //allocate + m_pAnimationData = new BYTE[ ( size_t )( sizeof( SDKANIMATION_FILE_HEADER ) + fileheader.AnimationDataSize ) ]; + if( !m_pAnimationData ) + { + hr = E_OUTOFMEMORY; + goto Error; + } + + // read it all in + liMove.QuadPart = 0; + if( !SetFilePointerEx( hFile, liMove, NULL, FILE_BEGIN ) ) + goto Error; + if( !ReadFile( hFile, m_pAnimationData, ( DWORD )( sizeof( SDKANIMATION_FILE_HEADER ) + + fileheader.AnimationDataSize ), &dwBytesRead, NULL ) ) + goto Error; + + // pointer fixup + m_pAnimationHeader = ( SDKANIMATION_FILE_HEADER* )m_pAnimationData; + m_pAnimationFrameData = ( SDKANIMATION_FRAME_DATA* )( m_pAnimationData + m_pAnimationHeader->AnimationDataOffset ); + + UINT64 BaseOffset = sizeof( SDKANIMATION_FILE_HEADER ); + for( UINT i = 0; i < m_pAnimationHeader->NumFrames; i++ ) + { + m_pAnimationFrameData[i].pAnimationData = ( SDKANIMATION_DATA* )( m_pAnimationData + + m_pAnimationFrameData[i].DataOffset + + BaseOffset ); + SDKMESH_FRAME* pFrame = FindFrame( m_pAnimationFrameData[i].FrameName ); + if( pFrame ) + { + pFrame->AnimationDataIndex = i; + } + } + + hr = S_OK; +Error: + CloseHandle( hFile ); + return hr; +} + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::Destroy() +{ + if( !CheckLoadDone() ) + return; + + if( m_pStaticMeshData ) + { + if( m_pMaterialArray ) + { + for( UINT64 m = 0; m < m_pMeshHeader->NumMaterials; m++ ) + { + if( m_pDev9 ) + { + if( !IsErrorResource( m_pMaterialArray[m].pDiffuseTexture9 ) ) + SAFE_RELEASE( m_pMaterialArray[m].pDiffuseTexture9 ); + if( !IsErrorResource( m_pMaterialArray[m].pNormalTexture9 ) ) + SAFE_RELEASE( m_pMaterialArray[m].pNormalTexture9 ); + if( !IsErrorResource( m_pMaterialArray[m].pSpecularTexture9 ) ) + SAFE_RELEASE( m_pMaterialArray[m].pSpecularTexture9 ); + } + else if( m_pDev11 ) + { + //ID3D11Resource* pRes = NULL; + if( m_pMaterialArray[m].pDiffuseRV11 && !IsErrorResource( m_pMaterialArray[m].pDiffuseRV11 ) ) + { + //m_pMaterialArray[m].pDiffuseRV11->GetResource( &pRes ); + //SAFE_RELEASE( pRes ); + + SAFE_RELEASE( m_pMaterialArray[m].pDiffuseRV11 ); + } + if( m_pMaterialArray[m].pNormalRV11 && !IsErrorResource( m_pMaterialArray[m].pNormalRV11 ) ) + { + //m_pMaterialArray[m].pNormalRV11->GetResource( &pRes ); + //SAFE_RELEASE( pRes ); + + SAFE_RELEASE( m_pMaterialArray[m].pNormalRV11 ); + } + if( m_pMaterialArray[m].pSpecularRV11 && !IsErrorResource( m_pMaterialArray[m].pSpecularRV11 ) ) + { + //m_pMaterialArray[m].pSpecularRV11->GetResource( &pRes ); + //SAFE_RELEASE( pRes ); + + SAFE_RELEASE( m_pMaterialArray[m].pSpecularRV11 ); + } + } + } + } + + for( UINT64 i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ ) + { + if( !IsErrorResource( m_pVertexBufferArray[i].pVB9 ) ) + SAFE_RELEASE( m_pVertexBufferArray[i].pVB9 ); + } + + for( UINT64 i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ ) + { + if( !IsErrorResource( m_pIndexBufferArray[i].pIB9 ) ) + SAFE_RELEASE( m_pIndexBufferArray[i].pIB9 ); + } + } + + if( m_pAdjacencyIndexBufferArray ) + { + for( UINT64 i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ ) + { + SAFE_RELEASE( m_pAdjacencyIndexBufferArray[i].pIB11 ); + } + } + SAFE_DELETE_ARRAY( m_pAdjacencyIndexBufferArray ); + + SAFE_DELETE_ARRAY( m_pHeapData ); + m_pStaticMeshData = NULL; + SAFE_DELETE_ARRAY( m_pAnimationData ); + SAFE_DELETE_ARRAY( m_pBindPoseFrameMatrices ); + SAFE_DELETE_ARRAY( m_pTransformedFrameMatrices ); + SAFE_DELETE_ARRAY( m_pWorldPoseFrameMatrices ); + + SAFE_DELETE_ARRAY( m_ppVertices ); + SAFE_DELETE_ARRAY( m_ppIndices ); + + m_pMeshHeader = NULL; + m_pVertexBufferArray = NULL; + m_pIndexBufferArray = NULL; + m_pMeshArray = NULL; + m_pSubsetArray = NULL; + m_pFrameArray = NULL; + m_pMaterialArray = NULL; + + m_pAnimationHeader = NULL; + m_pAnimationFrameData = NULL; + +} + +//-------------------------------------------------------------------------------------- +// transform the bind pose +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::TransformBindPose( D3DXMATRIX* pWorld ) +{ + TransformBindPoseFrame( 0, pWorld ); +} + +//-------------------------------------------------------------------------------------- +// transform the mesh frames according to the animation for time fTime +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::TransformMesh( D3DXMATRIX* pWorld, double fTime ) +{ + if( m_pAnimationHeader == NULL || FTT_RELATIVE == m_pAnimationHeader->FrameTransformType ) + { + TransformFrame( 0, pWorld, fTime ); + + // For each frame, move the transform to the bind pose, then + // move it to the final position + D3DXMATRIX mInvBindPose; + D3DXMATRIX mFinal; + for( UINT i = 0; i < m_pMeshHeader->NumFrames; i++ ) + { + D3DXMatrixInverse( &mInvBindPose, NULL, &m_pBindPoseFrameMatrices[i] ); + mFinal = mInvBindPose * m_pTransformedFrameMatrices[i]; + m_pTransformedFrameMatrices[i] = mFinal; + } + } + else if( FTT_ABSOLUTE == m_pAnimationHeader->FrameTransformType ) + { + for( UINT i = 0; i < m_pAnimationHeader->NumFrames; i++ ) + TransformFrameAbsolute( i, fTime ); + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::Render( ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot, + UINT iNormalSlot, + UINT iSpecularSlot ) +{ + RenderFrame( 0, false, pd3dDeviceContext, iDiffuseSlot, iNormalSlot, iSpecularSlot ); +} + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::RenderAdjacent( ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot, + UINT iNormalSlot, + UINT iSpecularSlot ) +{ + RenderFrame( 0, true, pd3dDeviceContext, iDiffuseSlot, iNormalSlot, iSpecularSlot ); +} + + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice, + LPD3DXEFFECT pEffect, + D3DXHANDLE hTechnique, + D3DXHANDLE htxDiffuse, + D3DXHANDLE htxNormal, + D3DXHANDLE htxSpecular ) +{ + RenderFrame( 0, pd3dDevice, pEffect, hTechnique, htxDiffuse, htxNormal, htxSpecular ); +} + +//-------------------------------------------------------------------------------------- +D3D11_PRIMITIVE_TOPOLOGY CDXUTSDKMesh::GetPrimitiveType11( SDKMESH_PRIMITIVE_TYPE PrimType ) +{ + D3D11_PRIMITIVE_TOPOLOGY retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + + switch( PrimType ) + { + case PT_TRIANGLE_LIST: + retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + break; + case PT_TRIANGLE_STRIP: + retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + break; + case PT_LINE_LIST: + retType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + break; + case PT_LINE_STRIP: + retType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; + break; + case PT_POINT_LIST: + retType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + break; + case PT_TRIANGLE_LIST_ADJ: + retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ; + break; + case PT_TRIANGLE_STRIP_ADJ: + retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ; + break; + case PT_LINE_LIST_ADJ: + retType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; + break; + case PT_LINE_STRIP_ADJ: + retType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ; + break; + }; + + return retType; +} + +//-------------------------------------------------------------------------------------- +DXGI_FORMAT CDXUTSDKMesh::GetIBFormat11( UINT iMesh ) +{ + switch( m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].IndexType ) + { + case IT_16BIT: + return DXGI_FORMAT_R16_UINT; + case IT_32BIT: + return DXGI_FORMAT_R32_UINT; + }; + return DXGI_FORMAT_R16_UINT; +} + +//-------------------------------------------------------------------------------------- +ID3D11Buffer* CDXUTSDKMesh::GetVB11( UINT iMesh, UINT iVB ) +{ + return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].pVB11; +} + +//-------------------------------------------------------------------------------------- +ID3D11Buffer* CDXUTSDKMesh::GetIB11( UINT iMesh ) +{ + return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB11; +} +SDKMESH_INDEX_TYPE CDXUTSDKMesh::GetIndexType( UINT iMesh ) +{ + return ( SDKMESH_INDEX_TYPE ) m_pIndexBufferArray[m_pMeshArray[ iMesh ].IndexBuffer].IndexType; +} +//-------------------------------------------------------------------------------------- +ID3D11Buffer* CDXUTSDKMesh::GetAdjIB11( UINT iMesh ) +{ + return m_pAdjacencyIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB11; +} + +//-------------------------------------------------------------------------------------- +D3DPRIMITIVETYPE CDXUTSDKMesh::GetPrimitiveType9( SDKMESH_PRIMITIVE_TYPE PrimType ) +{ + D3DPRIMITIVETYPE retType = D3DPT_TRIANGLELIST; + + switch( PrimType ) + { + case PT_TRIANGLE_LIST: + retType = D3DPT_TRIANGLELIST; + break; + case PT_TRIANGLE_STRIP: + retType = D3DPT_TRIANGLESTRIP; + break; + case PT_LINE_LIST: + retType = D3DPT_LINELIST; + break; + case PT_LINE_STRIP: + retType = D3DPT_LINESTRIP; + break; + case PT_POINT_LIST: + retType = D3DPT_POINTLIST; + break; + }; + + return retType; +} + +//-------------------------------------------------------------------------------------- +D3DFORMAT CDXUTSDKMesh::GetIBFormat9( UINT iMesh ) +{ + switch( m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].IndexType ) + { + case IT_16BIT: + return D3DFMT_INDEX16; + case IT_32BIT: + return D3DFMT_INDEX32; + }; + return D3DFMT_INDEX16; +} + +//-------------------------------------------------------------------------------------- +IDirect3DVertexBuffer9* CDXUTSDKMesh::GetVB9( UINT iMesh, UINT iVB ) +{ + return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].pVB9; +} + +//-------------------------------------------------------------------------------------- +IDirect3DIndexBuffer9* CDXUTSDKMesh::GetIB9( UINT iMesh ) +{ + return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB9; +} + +//-------------------------------------------------------------------------------------- +char* CDXUTSDKMesh::GetMeshPathA() +{ + return m_strPath; +} + +//-------------------------------------------------------------------------------------- +WCHAR* CDXUTSDKMesh::GetMeshPathW() +{ + return m_strPathW; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetNumMeshes() +{ + if( !m_pMeshHeader ) + return 0; + return m_pMeshHeader->NumMeshes; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetNumMaterials() +{ + if( !m_pMeshHeader ) + return 0; + return m_pMeshHeader->NumMaterials; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetNumVBs() +{ + if( !m_pMeshHeader ) + return 0; + return m_pMeshHeader->NumVertexBuffers; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetNumIBs() +{ + if( !m_pMeshHeader ) + return 0; + return m_pMeshHeader->NumIndexBuffers; +} + +//-------------------------------------------------------------------------------------- +ID3D11Buffer* CDXUTSDKMesh::GetVB11At( UINT iVB ) +{ + return m_pVertexBufferArray[ iVB ].pVB11; +} + +//-------------------------------------------------------------------------------------- +ID3D11Buffer* CDXUTSDKMesh::GetIB11At( UINT iIB ) +{ + return m_pIndexBufferArray[ iIB ].pIB11; +} + +//-------------------------------------------------------------------------------------- +IDirect3DVertexBuffer9* CDXUTSDKMesh::GetVB9At( UINT iVB ) +{ + return m_pVertexBufferArray[ iVB ].pVB9; +} + +//-------------------------------------------------------------------------------------- +IDirect3DIndexBuffer9* CDXUTSDKMesh::GetIB9At( UINT iIB ) +{ + return m_pIndexBufferArray[ iIB ].pIB9; +} + +//-------------------------------------------------------------------------------------- +BYTE* CDXUTSDKMesh::GetRawVerticesAt( UINT iVB ) +{ + return m_ppVertices[iVB]; +} + +//-------------------------------------------------------------------------------------- +BYTE* CDXUTSDKMesh::GetRawIndicesAt( UINT iIB ) +{ + return m_ppIndices[iIB]; +} + +//-------------------------------------------------------------------------------------- +SDKMESH_MATERIAL* CDXUTSDKMesh::GetMaterial( UINT iMaterial ) +{ + return &m_pMaterialArray[ iMaterial ]; +} + +//-------------------------------------------------------------------------------------- +SDKMESH_MESH* CDXUTSDKMesh::GetMesh( UINT iMesh ) +{ + return &m_pMeshArray[ iMesh ]; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetNumSubsets( UINT iMesh ) +{ + return m_pMeshArray[ iMesh ].NumSubsets; +} + +//-------------------------------------------------------------------------------------- +SDKMESH_SUBSET* CDXUTSDKMesh::GetSubset( UINT iMesh, UINT iSubset ) +{ + return &m_pSubsetArray[ m_pMeshArray[ iMesh ].pSubsets[iSubset] ]; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetVertexStride( UINT iMesh, UINT iVB ) +{ + return ( UINT )m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].StrideBytes; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetNumFrames() +{ + return m_pMeshHeader->NumFrames; +} + +//-------------------------------------------------------------------------------------- +SDKMESH_FRAME* CDXUTSDKMesh::GetFrame( UINT iFrame ) +{ + assert( iFrame < m_pMeshHeader->NumFrames ); + return &m_pFrameArray[ iFrame ]; +} + +//-------------------------------------------------------------------------------------- +SDKMESH_FRAME* CDXUTSDKMesh::FindFrame( char* pszName ) +{ + for( UINT i = 0; i < m_pMeshHeader->NumFrames; i++ ) + { + if( _stricmp( m_pFrameArray[i].Name, pszName ) == 0 ) + { + return &m_pFrameArray[i]; + } + } + return NULL; +} + +//-------------------------------------------------------------------------------------- +UINT64 CDXUTSDKMesh::GetNumVertices( UINT iMesh, UINT iVB ) +{ + return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].NumVertices; +} + +//-------------------------------------------------------------------------------------- +UINT64 CDXUTSDKMesh::GetNumIndices( UINT iMesh ) +{ + return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].NumIndices; +} + +//-------------------------------------------------------------------------------------- +D3DXVECTOR3 CDXUTSDKMesh::GetMeshBBoxCenter( UINT iMesh ) +{ + return m_pMeshArray[iMesh].BoundingBoxCenter; +} + +//-------------------------------------------------------------------------------------- +D3DXVECTOR3 CDXUTSDKMesh::GetMeshBBoxExtents( UINT iMesh ) +{ + return m_pMeshArray[iMesh].BoundingBoxExtents; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetOutstandingResources() +{ + UINT outstandingResources = 0; + if( !m_pMeshHeader ) + return 1; + + outstandingResources += GetOutstandingBufferResources(); + + if( m_pDev11 ) + { + for( UINT i = 0; i < m_pMeshHeader->NumMaterials; i++ ) + { + if( m_pMaterialArray[i].DiffuseTexture[0] != 0 ) + { + if( !m_pMaterialArray[i].pDiffuseRV11 && !IsErrorResource( m_pMaterialArray[i].pDiffuseRV11 ) ) + outstandingResources ++; + } + + if( m_pMaterialArray[i].NormalTexture[0] != 0 ) + { + if( !m_pMaterialArray[i].pNormalRV11 && !IsErrorResource( m_pMaterialArray[i].pNormalRV11 ) ) + outstandingResources ++; + } + + if( m_pMaterialArray[i].SpecularTexture[0] != 0 ) + { + if( !m_pMaterialArray[i].pSpecularRV11 && !IsErrorResource( m_pMaterialArray[i].pSpecularRV11 ) ) + outstandingResources ++; + } + } + } + else + { + for( UINT i = 0; i < m_pMeshHeader->NumMaterials; i++ ) + { + if( m_pMaterialArray[i].DiffuseTexture[0] != 0 ) + { + if( !m_pMaterialArray[i].pDiffuseTexture9 && !IsErrorResource( m_pMaterialArray[i].pDiffuseTexture9 ) ) + outstandingResources ++; + } + + if( m_pMaterialArray[i].NormalTexture[0] != 0 ) + { + if( !m_pMaterialArray[i].pNormalTexture9 && !IsErrorResource( m_pMaterialArray[i].pNormalTexture9 ) ) + outstandingResources ++; + } + + if( m_pMaterialArray[i].SpecularTexture[0] != 0 ) + { + if( !m_pMaterialArray[i].pSpecularTexture9 && + !IsErrorResource( m_pMaterialArray[i].pSpecularTexture9 ) ) + outstandingResources ++; + } + } + } + + return outstandingResources; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetOutstandingBufferResources() +{ + UINT outstandingResources = 0; + if( !m_pMeshHeader ) + return 1; + + for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ ) + { + if( !m_pVertexBufferArray[i].pVB9 && !IsErrorResource( m_pVertexBufferArray[i].pVB9 ) ) + outstandingResources ++; + } + + for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ ) + { + if( !m_pIndexBufferArray[i].pIB9 && !IsErrorResource( m_pIndexBufferArray[i].pIB9 ) ) + outstandingResources ++; + } + + return outstandingResources; +} + +//-------------------------------------------------------------------------------------- +bool CDXUTSDKMesh::CheckLoadDone() +{ + if( 0 == GetOutstandingResources() ) + { + m_bLoading = false; + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------- +bool CDXUTSDKMesh::IsLoaded() +{ + if( m_pStaticMeshData && !m_bLoading ) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------- +bool CDXUTSDKMesh::IsLoading() +{ + return m_bLoading; +} + +//-------------------------------------------------------------------------------------- +void CDXUTSDKMesh::SetLoading( bool bLoading ) +{ + m_bLoading = bLoading; +} + +//-------------------------------------------------------------------------------------- +BOOL CDXUTSDKMesh::HadLoadingError() +{ + if( m_pMeshHeader ) + { + for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ ) + { + if( IsErrorResource( m_pVertexBufferArray[i].pVB9 ) ) + return TRUE; + } + + for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ ) + { + if( IsErrorResource( m_pIndexBufferArray[i].pIB9 ) ) + return TRUE; + } + } + + return FALSE; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetNumInfluences( UINT iMesh ) +{ + return m_pMeshArray[iMesh].NumFrameInfluences; +} + +//-------------------------------------------------------------------------------------- +const D3DXMATRIX* CDXUTSDKMesh::GetMeshInfluenceMatrix( UINT iMesh, UINT iInfluence ) +{ + UINT iFrame = m_pMeshArray[iMesh].pFrameInfluences[ iInfluence ]; + return &m_pTransformedFrameMatrices[iFrame]; +} + +const D3DXMATRIX* CDXUTSDKMesh::GetWorldMatrix( UINT iFrameIndex ) +{ + return &m_pWorldPoseFrameMatrices[iFrameIndex]; +} + +const D3DXMATRIX* CDXUTSDKMesh::GetInfluenceMatrix( UINT iFrameIndex ) +{ + return &m_pTransformedFrameMatrices[iFrameIndex]; +} + +//-------------------------------------------------------------------------------------- +UINT CDXUTSDKMesh::GetAnimationKeyFromTime( double fTime ) +{ + if( m_pAnimationHeader == NULL ) + { + return 0; + } + + UINT iTick = ( UINT )( m_pAnimationHeader->AnimationFPS * fTime ); + + iTick = iTick % ( m_pAnimationHeader->NumAnimationKeys - 1 ); + iTick ++; + + return iTick; +} + +bool CDXUTSDKMesh::GetAnimationProperties( UINT* pNumKeys, FLOAT* pFrameTime ) +{ + if( m_pAnimationHeader == NULL ) + { + return false; + } + + *pNumKeys = m_pAnimationHeader->NumAnimationKeys; + *pFrameTime = 1.0f / (FLOAT)m_pAnimationHeader->AnimationFPS; + + return true; +} + + +//------------------------------------------------------------------------------------- +// CDXUTXFileMesh implementation. +//------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +CDXUTXFileMesh::CDXUTXFileMesh( LPCWSTR strName ) +{ + wcscpy_s( m_strName, 512, strName ); + m_pMesh = NULL; + m_pMaterials = NULL; + m_pTextures = NULL; + m_bUseMaterials = TRUE; + m_pVB = NULL; + m_pIB = NULL; + m_pDecl = NULL; + m_strMaterials = NULL; + m_dwNumMaterials = 0; + m_dwNumVertices = 0; + m_dwNumFaces = 0; + m_dwBytesPerVertex = 0; +} + + + + +//----------------------------------------------------------------------------- +CDXUTXFileMesh::~CDXUTXFileMesh() +{ + Destroy(); +} + + + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename ) +{ + WCHAR strPath[MAX_PATH]; + LPD3DXBUFFER pAdjacencyBuffer = NULL; + LPD3DXBUFFER pMtrlBuffer = NULL; + HRESULT hr; + + // Cleanup previous mesh if any + Destroy(); + + // Find the path for the file, and convert it to ANSI (for the D3DX API) + DXUTFindDXSDKMediaFileCch( strPath, sizeof( strPath ) / sizeof( WCHAR ), strFilename ); + + // Load the mesh + if( FAILED( hr = D3DXLoadMeshFromX( strPath, D3DXMESH_MANAGED, pd3dDevice, + &pAdjacencyBuffer, &pMtrlBuffer, NULL, + &m_dwNumMaterials, &m_pMesh ) ) ) + { + return hr; + } + + // Optimize the mesh for performance + if( FAILED( hr = m_pMesh->OptimizeInplace( + D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, + ( DWORD* )pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) ) + { + SAFE_RELEASE( pAdjacencyBuffer ); + SAFE_RELEASE( pMtrlBuffer ); + return hr; + } + + // Set strPath to the path of the mesh file + WCHAR* pLastBSlash = wcsrchr( strPath, L'\\' ); + if( pLastBSlash ) + *( pLastBSlash + 1 ) = L'\0'; + else + *strPath = L'\0'; + + D3DXMATERIAL* d3dxMtrls = ( D3DXMATERIAL* )pMtrlBuffer->GetBufferPointer(); + hr = CreateMaterials( strPath, pd3dDevice, d3dxMtrls, m_dwNumMaterials ); + + SAFE_RELEASE( pAdjacencyBuffer ); + SAFE_RELEASE( pMtrlBuffer ); + + // Extract data from m_pMesh for easy access + D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE]; + m_dwNumVertices = m_pMesh->GetNumVertices(); + m_dwNumFaces = m_pMesh->GetNumFaces(); + m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex(); + m_pMesh->GetIndexBuffer( &m_pIB ); + m_pMesh->GetVertexBuffer( &m_pVB ); + m_pMesh->GetDeclaration( decl ); + pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl ); + + return hr; +} + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, + LPD3DXFILEDATA pFileData ) +{ + LPD3DXBUFFER pMtrlBuffer = NULL; + LPD3DXBUFFER pAdjacencyBuffer = NULL; + HRESULT hr; + + // Cleanup previous mesh if any + Destroy(); + + // Load the mesh from the DXFILEDATA object + if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_MANAGED, pd3dDevice, + &pAdjacencyBuffer, &pMtrlBuffer, NULL, + &m_dwNumMaterials, &m_pMesh ) ) ) + { + return hr; + } + + // Optimize the mesh for performance + if( FAILED( hr = m_pMesh->OptimizeInplace( + D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, + ( DWORD* )pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) ) + { + SAFE_RELEASE( pAdjacencyBuffer ); + SAFE_RELEASE( pMtrlBuffer ); + return hr; + } + + D3DXMATERIAL* d3dxMtrls = ( D3DXMATERIAL* )pMtrlBuffer->GetBufferPointer(); + hr = CreateMaterials( L"", pd3dDevice, d3dxMtrls, m_dwNumMaterials ); + + SAFE_RELEASE( pAdjacencyBuffer ); + SAFE_RELEASE( pMtrlBuffer ); + + // Extract data from m_pMesh for easy access + D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE]; + m_dwNumVertices = m_pMesh->GetNumVertices(); + m_dwNumFaces = m_pMesh->GetNumFaces(); + m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex(); + m_pMesh->GetIndexBuffer( &m_pIB ); + m_pMesh->GetVertexBuffer( &m_pVB ); + m_pMesh->GetDeclaration( decl ); + pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl ); + + return hr; +} + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh* pInMesh, + D3DXMATERIAL* pd3dxMaterials, DWORD dwMaterials ) +{ + // Cleanup previous mesh if any + Destroy(); + + // Optimize the mesh for performance + DWORD* rgdwAdjacency = NULL; + rgdwAdjacency = new DWORD[pInMesh->GetNumFaces() * 3]; + if( rgdwAdjacency == NULL ) + return E_OUTOFMEMORY; + pInMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ); + + D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE]; + pInMesh->GetDeclaration( decl ); + + DWORD dwOptions = pInMesh->GetOptions(); + dwOptions &= ~( D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM | D3DXMESH_WRITEONLY ); + dwOptions |= D3DXMESH_MANAGED; + dwOptions |= D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE; + + ID3DXMesh* pTempMesh = NULL; + if( FAILED( pInMesh->Optimize( dwOptions, rgdwAdjacency, NULL, NULL, NULL, &pTempMesh ) ) ) + { + SAFE_DELETE_ARRAY( rgdwAdjacency ); + return E_FAIL; + } + + SAFE_DELETE_ARRAY( rgdwAdjacency ); + SAFE_RELEASE( m_pMesh ); + m_pMesh = pTempMesh; + + HRESULT hr; + hr = CreateMaterials( L"", pd3dDevice, pd3dxMaterials, dwMaterials ); + + // Extract data from m_pMesh for easy access + m_dwNumVertices = m_pMesh->GetNumVertices(); + m_dwNumFaces = m_pMesh->GetNumFaces(); + m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex(); + m_pMesh->GetIndexBuffer( &m_pIB ); + m_pMesh->GetVertexBuffer( &m_pVB ); + m_pMesh->GetDeclaration( decl ); + pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl ); + + return hr; +} + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::CreateMaterials( LPCWSTR strPath, IDirect3DDevice9* pd3dDevice, D3DXMATERIAL* d3dxMtrls, + DWORD dwNumMaterials ) +{ + // Get material info for the mesh + // Get the array of materials out of the buffer + m_dwNumMaterials = dwNumMaterials; + if( d3dxMtrls && m_dwNumMaterials > 0 ) + { + // Allocate memory for the materials and textures + m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials]; + if( m_pMaterials == NULL ) + return E_OUTOFMEMORY; + m_pTextures = new LPDIRECT3DBASETEXTURE9[m_dwNumMaterials]; + if( m_pTextures == NULL ) + return E_OUTOFMEMORY; + m_strMaterials = new CHAR[m_dwNumMaterials][MAX_PATH]; + if( m_strMaterials == NULL ) + return E_OUTOFMEMORY; + + // Copy each material and create its texture + for( DWORD i = 0; i < m_dwNumMaterials; i++ ) + { + // Copy the material + m_pMaterials[i] = d3dxMtrls[i].MatD3D; + m_pTextures[i] = NULL; + + // Create a texture + if( d3dxMtrls[i].pTextureFilename ) + { + strcpy_s( m_strMaterials[i], MAX_PATH, d3dxMtrls[i].pTextureFilename ); + + WCHAR strTexture[MAX_PATH]; + WCHAR strTextureTemp[MAX_PATH]; + D3DXIMAGE_INFO ImgInfo; + + // First attempt to look for texture in the same folder as the input folder. + MultiByteToWideChar( CP_ACP, 0, d3dxMtrls[i].pTextureFilename, -1, strTextureTemp, MAX_PATH ); + strTextureTemp[MAX_PATH - 1] = 0; + + wcscpy_s( strTexture, MAX_PATH, strPath ); + wcscat_s( strTexture, MAX_PATH, strTextureTemp ); + + // Inspect the texture file to determine the texture type. + if( FAILED( D3DXGetImageInfoFromFile( strTexture, &ImgInfo ) ) ) + { + // Search the media folder + if( FAILED( DXUTFindDXSDKMediaFileCch( strTexture, MAX_PATH, strTextureTemp ) ) ) + continue; // Can't find. Skip. + + D3DXGetImageInfoFromFile( strTexture, &ImgInfo ); + } + + // Call the appropriate loader according to the texture type. + switch( ImgInfo.ResourceType ) + { + case D3DRTYPE_TEXTURE: + { + IDirect3DTexture9* pTex; + if( SUCCEEDED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &pTex ) ) ) + { + // Obtain the base texture interface + pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] ); + // Release the specialized instance + pTex->Release(); + } + break; + } + case D3DRTYPE_CUBETEXTURE: + { + IDirect3DCubeTexture9* pTex; + if( SUCCEEDED( D3DXCreateCubeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) ) + { + // Obtain the base texture interface + pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] ); + // Release the specialized instance + pTex->Release(); + } + break; + } + case D3DRTYPE_VOLUMETEXTURE: + { + IDirect3DVolumeTexture9* pTex; + if( SUCCEEDED( D3DXCreateVolumeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) ) + { + // Obtain the base texture interface + pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] ); + // Release the specialized instance + pTex->Release(); + } + break; + } + } + } + } + } + return S_OK; +} + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF ) +{ + LPD3DXMESH pTempMesh = NULL; + + if( m_pMesh ) + { + if( FAILED( m_pMesh->CloneMeshFVF( m_pMesh->GetOptions(), dwFVF, + pd3dDevice, &pTempMesh ) ) ) + { + SAFE_RELEASE( pTempMesh ); + return E_FAIL; + } + + DWORD dwOldFVF = 0; + dwOldFVF = m_pMesh->GetFVF(); + SAFE_RELEASE( m_pMesh ); + m_pMesh = pTempMesh; + + // Compute normals if they are being requested and + // the old mesh does not have them. + if( !( dwOldFVF & D3DFVF_NORMAL ) && dwFVF & D3DFVF_NORMAL ) + { + D3DXComputeNormals( m_pMesh, NULL ); + } + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +// Convert the mesh to the format specified by the given vertex declarations. +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9* pDecl, + bool bAutoComputeNormals, bool bAutoComputeTangents, + bool bSplitVertexForOptimalTangents ) +{ + LPD3DXMESH pTempMesh = NULL; + + if( m_pMesh ) + { + if( FAILED( m_pMesh->CloneMesh( m_pMesh->GetOptions(), pDecl, + pd3dDevice, &pTempMesh ) ) ) + { + SAFE_RELEASE( pTempMesh ); + return E_FAIL; + } + } + + + // Check if the old declaration contains a normal. + bool bHadNormal = false; + bool bHadTangent = false; + D3DVERTEXELEMENT9 aOldDecl[MAX_FVF_DECL_SIZE]; + if( m_pMesh && SUCCEEDED( m_pMesh->GetDeclaration( aOldDecl ) ) ) + { + for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index ) + { + if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL ) + { + bHadNormal = true; + } + if( aOldDecl[index].Usage == D3DDECLUSAGE_TANGENT ) + { + bHadTangent = true; + } + } + } + + // Check if the new declaration contains a normal. + bool bHaveNormalNow = false; + bool bHaveTangentNow = false; + D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE]; + if( pTempMesh && SUCCEEDED( pTempMesh->GetDeclaration( aNewDecl ) ) ) + { + for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index ) + { + if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL ) + { + bHaveNormalNow = true; + } + if( aNewDecl[index].Usage == D3DDECLUSAGE_TANGENT ) + { + bHaveTangentNow = true; + } + } + } + + SAFE_RELEASE( m_pMesh ); + + if( pTempMesh ) + { + m_pMesh = pTempMesh; + + if( !bHadNormal && bHaveNormalNow && bAutoComputeNormals ) + { + // Compute normals in case the meshes have them + D3DXComputeNormals( m_pMesh, NULL ); + } + + if( bHaveNormalNow && !bHadTangent && bHaveTangentNow && bAutoComputeTangents ) + { + ID3DXMesh* pNewMesh; + HRESULT hr; + + DWORD* rgdwAdjacency = NULL; + rgdwAdjacency = new DWORD[m_pMesh->GetNumFaces() * 3]; + if( rgdwAdjacency == NULL ) + return E_OUTOFMEMORY; + V( m_pMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ) ); + + float fPartialEdgeThreshold; + float fSingularPointThreshold; + float fNormalEdgeThreshold; + if( bSplitVertexForOptimalTangents ) + { + fPartialEdgeThreshold = 0.01f; + fSingularPointThreshold = 0.25f; + fNormalEdgeThreshold = 0.01f; + } + else + { + fPartialEdgeThreshold = -1.01f; + fSingularPointThreshold = 0.01f; + fNormalEdgeThreshold = -1.01f; + } + + // Compute tangents, which are required for normal mapping + hr = D3DXComputeTangentFrameEx( m_pMesh, + D3DDECLUSAGE_TEXCOORD, 0, + D3DDECLUSAGE_TANGENT, 0, + D3DX_DEFAULT, 0, + D3DDECLUSAGE_NORMAL, 0, + 0, rgdwAdjacency, + fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold, + &pNewMesh, NULL ); + + SAFE_DELETE_ARRAY( rgdwAdjacency ); + if( FAILED( hr ) ) + return hr; + + SAFE_RELEASE( m_pMesh ); + m_pMesh = pNewMesh; + } + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice ) +{ + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::InvalidateDeviceObjects() +{ + SAFE_RELEASE( m_pIB ); + SAFE_RELEASE( m_pVB ); + SAFE_RELEASE( m_pDecl ); + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::Destroy() +{ + InvalidateDeviceObjects(); + for( UINT i = 0; i < m_dwNumMaterials; i++ ) + SAFE_RELEASE( m_pTextures[i] ); + SAFE_DELETE_ARRAY( m_pTextures ); + SAFE_DELETE_ARRAY( m_pMaterials ); + SAFE_DELETE_ARRAY( m_strMaterials ); + + SAFE_RELEASE( m_pMesh ); + + m_dwNumMaterials = 0L; + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets, + bool bDrawAlphaSubsets ) +{ + if( NULL == m_pMesh ) + return E_FAIL; + + // Frist, draw the subsets without alpha + if( bDrawOpaqueSubsets ) + { + for( DWORD i = 0; i < m_dwNumMaterials; i++ ) + { + if( m_bUseMaterials ) + { + if( m_pMaterials[i].Diffuse.a < 1.0f ) + continue; + pd3dDevice->SetMaterial( &m_pMaterials[i] ); + pd3dDevice->SetTexture( 0, m_pTextures[i] ); + } + m_pMesh->DrawSubset( i ); + } + } + + // Then, draw the subsets with alpha + if( bDrawAlphaSubsets && m_bUseMaterials ) + { + for( DWORD i = 0; i < m_dwNumMaterials; i++ ) + { + if( m_pMaterials[i].Diffuse.a == 1.0f ) + continue; + + // Set the material and texture + pd3dDevice->SetMaterial( &m_pMaterials[i] ); + pd3dDevice->SetTexture( 0, m_pTextures[i] ); + m_pMesh->DrawSubset( i ); + } + } + + return S_OK; +} + + + + +//----------------------------------------------------------------------------- +HRESULT CDXUTXFileMesh::Render( ID3DXEffect* pEffect, + D3DXHANDLE hTexture, + D3DXHANDLE hDiffuse, + D3DXHANDLE hAmbient, + D3DXHANDLE hSpecular, + D3DXHANDLE hEmissive, + D3DXHANDLE hPower, + bool bDrawOpaqueSubsets, + bool bDrawAlphaSubsets ) +{ + if( NULL == m_pMesh ) + return E_FAIL; + + UINT cPasses; + // Frist, draw the subsets without alpha + if( bDrawOpaqueSubsets ) + { + pEffect->Begin( &cPasses, 0 ); + for( UINT p = 0; p < cPasses; ++p ) + { + pEffect->BeginPass( p ); + for( DWORD i = 0; i < m_dwNumMaterials; i++ ) + { + if( m_bUseMaterials ) + { + if( m_pMaterials[i].Diffuse.a < 1.0f ) + continue; + if( hTexture ) + pEffect->SetTexture( hTexture, m_pTextures[i] ); + // D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical. + // No conversion is needed. + if( hDiffuse ) + pEffect->SetVector( hDiffuse, ( D3DXVECTOR4* )&m_pMaterials[i].Diffuse ); + if( hAmbient ) + pEffect->SetVector( hAmbient, ( D3DXVECTOR4* )&m_pMaterials[i].Ambient ); + if( hSpecular ) + pEffect->SetVector( hSpecular, ( D3DXVECTOR4* )&m_pMaterials[i].Specular ); + if( hEmissive ) + pEffect->SetVector( hEmissive, ( D3DXVECTOR4* )&m_pMaterials[i].Emissive ); + if( hPower ) + pEffect->SetFloat( hPower, m_pMaterials[i].Power ); + pEffect->CommitChanges(); + } + m_pMesh->DrawSubset( i ); + } + pEffect->EndPass(); + } + pEffect->End(); + } + + // Then, draw the subsets with alpha + if( bDrawAlphaSubsets && m_bUseMaterials ) + { + pEffect->Begin( &cPasses, 0 ); + for( UINT p = 0; p < cPasses; ++p ) + { + pEffect->BeginPass( p ); + for( DWORD i = 0; i < m_dwNumMaterials; i++ ) + { + if( m_bUseMaterials ) + { + if( m_pMaterials[i].Diffuse.a == 1.0f ) + continue; + if( hTexture ) + pEffect->SetTexture( hTexture, m_pTextures[i] ); + // D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical. + // No conversion is needed. + if( hDiffuse ) + pEffect->SetVector( hDiffuse, ( D3DXVECTOR4* )&m_pMaterials[i].Diffuse ); + if( hAmbient ) + pEffect->SetVector( hAmbient, ( D3DXVECTOR4* )&m_pMaterials[i].Ambient ); + if( hSpecular ) + pEffect->SetVector( hSpecular, ( D3DXVECTOR4* )&m_pMaterials[i].Specular ); + if( hEmissive ) + pEffect->SetVector( hEmissive, ( D3DXVECTOR4* )&m_pMaterials[i].Emissive ); + if( hPower ) + pEffect->SetFloat( hPower, m_pMaterials[i].Power ); + pEffect->CommitChanges(); + } + m_pMesh->DrawSubset( i ); + } + pEffect->EndPass(); + } + pEffect->End(); + } + + return S_OK; +} diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.h b/Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.h new file mode 100644 index 0000000..79a41d0 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKmesh.h @@ -0,0 +1,589 @@ +//-------------------------------------------------------------------------------------- +// File: SDKMesh.h +// +// Disclaimer: +// The SDK Mesh format (.sdkmesh) is not a recommended file format for shipping titles. +// It was designed to meet the specific needs of the SDK samples. Any real-world +// applications should avoid this file format in favor of a destination format that +// meets the specific needs of the application. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef _SDKMESH_ +#define _SDKMESH_ + +//-------------------------------------------------------------------------------------- +// Hard Defines for the various structures +//-------------------------------------------------------------------------------------- +#define SDKMESH_FILE_VERSION 101 +#define MAX_VERTEX_ELEMENTS 32 +#define MAX_VERTEX_STREAMS 16 +#define MAX_FRAME_NAME 100 +#define MAX_MESH_NAME 100 +#define MAX_SUBSET_NAME 100 +#define MAX_MATERIAL_NAME 100 +#define MAX_TEXTURE_NAME MAX_PATH +#define MAX_MATERIAL_PATH MAX_PATH +#define INVALID_FRAME ((UINT)-1) +#define INVALID_MESH ((UINT)-1) +#define INVALID_MATERIAL ((UINT)-1) +#define INVALID_SUBSET ((UINT)-1) +#define INVALID_ANIMATION_DATA ((UINT)-1) +#define INVALID_SAMPLER_SLOT ((UINT)-1) +#define ERROR_RESOURCE_VALUE 1 + +template BOOL IsErrorResource( TYPE data ) +{ + if( ( TYPE )ERROR_RESOURCE_VALUE == data ) + return TRUE; + return FALSE; +} +//-------------------------------------------------------------------------------------- +// Enumerated Types. These will have mirrors in both D3D9 and D3D11 +//-------------------------------------------------------------------------------------- +enum SDKMESH_PRIMITIVE_TYPE +{ + PT_TRIANGLE_LIST = 0, + PT_TRIANGLE_STRIP, + PT_LINE_LIST, + PT_LINE_STRIP, + PT_POINT_LIST, + PT_TRIANGLE_LIST_ADJ, + PT_TRIANGLE_STRIP_ADJ, + PT_LINE_LIST_ADJ, + PT_LINE_STRIP_ADJ, + PT_QUAD_PATCH_LIST, + PT_TRIANGLE_PATCH_LIST, +}; + +enum SDKMESH_INDEX_TYPE +{ + IT_16BIT = 0, + IT_32BIT, +}; + +enum FRAME_TRANSFORM_TYPE +{ + FTT_RELATIVE = 0, + FTT_ABSOLUTE, //This is not currently used but is here to support absolute transformations in the future +}; + +//-------------------------------------------------------------------------------------- +// Structures. Unions with pointers are forced to 64bit. +//-------------------------------------------------------------------------------------- +struct SDKMESH_HEADER +{ + //Basic Info and sizes + UINT Version; + BYTE IsBigEndian; + UINT64 HeaderSize; + UINT64 NonBufferDataSize; + UINT64 BufferDataSize; + + //Stats + UINT NumVertexBuffers; + UINT NumIndexBuffers; + UINT NumMeshes; + UINT NumTotalSubsets; + UINT NumFrames; + UINT NumMaterials; + + //Offsets to Data + UINT64 VertexStreamHeadersOffset; + UINT64 IndexStreamHeadersOffset; + UINT64 MeshDataOffset; + UINT64 SubsetDataOffset; + UINT64 FrameDataOffset; + UINT64 MaterialDataOffset; +}; + +struct SDKMESH_VERTEX_BUFFER_HEADER +{ + UINT64 NumVertices; + UINT64 SizeBytes; + UINT64 StrideBytes; + D3DVERTEXELEMENT9 Decl[MAX_VERTEX_ELEMENTS]; + union + { + UINT64 DataOffset; //(This also forces the union to 64bits) + IDirect3DVertexBuffer9* pVB9; + ID3D11Buffer* pVB11; + }; +}; + +struct SDKMESH_INDEX_BUFFER_HEADER +{ + UINT64 NumIndices; + UINT64 SizeBytes; + UINT IndexType; + union + { + UINT64 DataOffset; //(This also forces the union to 64bits) + IDirect3DIndexBuffer9* pIB9; + ID3D11Buffer* pIB11; + }; +}; + +struct SDKMESH_MESH +{ + char Name[MAX_MESH_NAME]; + BYTE NumVertexBuffers; + UINT VertexBuffers[MAX_VERTEX_STREAMS]; + UINT IndexBuffer; + UINT NumSubsets; + UINT NumFrameInfluences; //aka bones + + D3DXVECTOR3 BoundingBoxCenter; + D3DXVECTOR3 BoundingBoxExtents; + + union + { + UINT64 SubsetOffset; //Offset to list of subsets (This also forces the union to 64bits) + UINT* pSubsets; //Pointer to list of subsets + }; + union + { + UINT64 FrameInfluenceOffset; //Offset to list of frame influences (This also forces the union to 64bits) + UINT* pFrameInfluences; //Pointer to list of frame influences + }; +}; + +struct SDKMESH_SUBSET +{ + char Name[MAX_SUBSET_NAME]; + UINT MaterialID; + UINT PrimitiveType; + UINT64 IndexStart; + UINT64 IndexCount; + UINT64 VertexStart; + UINT64 VertexCount; +}; + +struct SDKMESH_FRAME +{ + char Name[MAX_FRAME_NAME]; + UINT Mesh; + UINT ParentFrame; + UINT ChildFrame; + UINT SiblingFrame; + D3DXMATRIX Matrix; + UINT AnimationDataIndex; //Used to index which set of keyframes transforms this frame +}; + +struct SDKMESH_MATERIAL +{ + char Name[MAX_MATERIAL_NAME]; + + // Use MaterialInstancePath + char MaterialInstancePath[MAX_MATERIAL_PATH]; + + // Or fall back to d3d8-type materials + char DiffuseTexture[MAX_TEXTURE_NAME]; + char NormalTexture[MAX_TEXTURE_NAME]; + char SpecularTexture[MAX_TEXTURE_NAME]; + + D3DXVECTOR4 Diffuse; + D3DXVECTOR4 Ambient; + D3DXVECTOR4 Specular; + D3DXVECTOR4 Emissive; + FLOAT Power; + + union + { + UINT64 Force64_1; //Force the union to 64bits + IDirect3DTexture9* pDiffuseTexture9; + ID3D11Texture2D* pDiffuseTexture11; + }; + union + { + UINT64 Force64_2; //Force the union to 64bits + IDirect3DTexture9* pNormalTexture9; + ID3D11Texture2D* pNormalTexture11; + }; + union + { + UINT64 Force64_3; //Force the union to 64bits + IDirect3DTexture9* pSpecularTexture9; + ID3D11Texture2D* pSpecularTexture11; + }; + + union + { + UINT64 Force64_4; //Force the union to 64bits + ID3D11ShaderResourceView* pDiffuseRV11; + }; + union + { + UINT64 Force64_5; //Force the union to 64bits + ID3D11ShaderResourceView* pNormalRV11; + }; + union + { + UINT64 Force64_6; //Force the union to 64bits + ID3D11ShaderResourceView* pSpecularRV11; + }; + +}; + +struct SDKANIMATION_FILE_HEADER +{ + UINT Version; + BYTE IsBigEndian; + UINT FrameTransformType; + UINT NumFrames; + UINT NumAnimationKeys; + UINT AnimationFPS; + UINT64 AnimationDataSize; + UINT64 AnimationDataOffset; +}; + +struct SDKANIMATION_DATA +{ + D3DXVECTOR3 Translation; + D3DXVECTOR4 Orientation; + D3DXVECTOR3 Scaling; +}; + +struct SDKANIMATION_FRAME_DATA +{ + char FrameName[MAX_FRAME_NAME]; + union + { + UINT64 DataOffset; + SDKANIMATION_DATA* pAnimationData; + }; +}; + +#ifndef _CONVERTER_APP_ + +//-------------------------------------------------------------------------------------- +// AsyncLoading callbacks +//-------------------------------------------------------------------------------------- +typedef void ( CALLBACK*LPCREATETEXTUREFROMFILE9 )( IDirect3DDevice9* pDev, char* szFileName, + IDirect3DTexture9** ppTexture, void* pContext ); +typedef void ( CALLBACK*LPCREATEVERTEXBUFFER9 )( IDirect3DDevice9* pDev, IDirect3DVertexBuffer9** ppBuffer, + UINT iSizeBytes, DWORD Usage, DWORD FVF, D3DPOOL Pool, void* pData, + void* pContext ); +typedef void ( CALLBACK*LPCREATEINDEXBUFFER9 )( IDirect3DDevice9* pDev, IDirect3DIndexBuffer9** ppBuffer, + UINT iSizeBytes, DWORD Usage, D3DFORMAT ibFormat, D3DPOOL Pool, + void* pData, void* pContext ); +struct SDKMESH_CALLBACKS9 +{ + LPCREATETEXTUREFROMFILE9 pCreateTextureFromFile; + LPCREATEVERTEXBUFFER9 pCreateVertexBuffer; + LPCREATEINDEXBUFFER9 pCreateIndexBuffer; + void* pContext; +}; + + +typedef void ( CALLBACK*LPCREATETEXTUREFROMFILE11 )( ID3D11Device* pDev, char* szFileName, + ID3D11ShaderResourceView** ppRV, void* pContext ); +typedef void ( CALLBACK*LPCREATEVERTEXBUFFER11 )( ID3D11Device* pDev, ID3D11Buffer** ppBuffer, + D3D11_BUFFER_DESC BufferDesc, void* pData, void* pContext ); +typedef void ( CALLBACK*LPCREATEINDEXBUFFER11 )( ID3D11Device* pDev, ID3D11Buffer** ppBuffer, + D3D11_BUFFER_DESC BufferDesc, void* pData, void* pContext ); +struct SDKMESH_CALLBACKS11 +{ + LPCREATETEXTUREFROMFILE11 pCreateTextureFromFile; + LPCREATEVERTEXBUFFER11 pCreateVertexBuffer; + LPCREATEINDEXBUFFER11 pCreateIndexBuffer; + void* pContext; +}; + +//-------------------------------------------------------------------------------------- +// CDXUTSDKMesh class. This class reads the sdkmesh file format for use by the samples +//-------------------------------------------------------------------------------------- +class CDXUTSDKMesh +{ +private: + UINT m_NumOutstandingResources; + bool m_bLoading; + //BYTE* m_pBufferData; + HANDLE m_hFile; + HANDLE m_hFileMappingObject; + CGrowableArray m_MappedPointers; + IDirect3DDevice9* m_pDev9; + ID3D11Device* m_pDev11; + ID3D11DeviceContext* m_pDevContext11; + +protected: + //These are the pointers to the two chunks of data loaded in from the mesh file + BYTE* m_pStaticMeshData; + BYTE* m_pHeapData; + BYTE* m_pAnimationData; + BYTE** m_ppVertices; + BYTE** m_ppIndices; + + //Keep track of the path + WCHAR m_strPathW[MAX_PATH]; + char m_strPath[MAX_PATH]; + + //General mesh info + SDKMESH_HEADER* m_pMeshHeader; + SDKMESH_VERTEX_BUFFER_HEADER* m_pVertexBufferArray; + SDKMESH_INDEX_BUFFER_HEADER* m_pIndexBufferArray; + SDKMESH_MESH* m_pMeshArray; + SDKMESH_SUBSET* m_pSubsetArray; + SDKMESH_FRAME* m_pFrameArray; + SDKMESH_MATERIAL* m_pMaterialArray; + + // Adjacency information (not part of the m_pStaticMeshData, so it must be created and destroyed separately ) + SDKMESH_INDEX_BUFFER_HEADER* m_pAdjacencyIndexBufferArray; + + //Animation (TODO: Add ability to load/track multiple animation sets) + SDKANIMATION_FILE_HEADER* m_pAnimationHeader; + SDKANIMATION_FRAME_DATA* m_pAnimationFrameData; + D3DXMATRIX* m_pBindPoseFrameMatrices; + D3DXMATRIX* m_pTransformedFrameMatrices; + D3DXMATRIX* m_pWorldPoseFrameMatrices; + +protected: + void LoadMaterials( ID3D11Device* pd3dDevice, SDKMESH_MATERIAL* pMaterials, + UINT NumMaterials, SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL ); + + void LoadMaterials( IDirect3DDevice9* pd3dDevice, SDKMESH_MATERIAL* pMaterials, + UINT NumMaterials, SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL ); + + HRESULT CreateVertexBuffer( ID3D11Device* pd3dDevice, + SDKMESH_VERTEX_BUFFER_HEADER* pHeader, void* pVertices, + SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL ); + HRESULT CreateVertexBuffer( IDirect3DDevice9* pd3dDevice, + SDKMESH_VERTEX_BUFFER_HEADER* pHeader, void* pVertices, + SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL ); + + HRESULT CreateIndexBuffer( ID3D11Device* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader, + void* pIndices, SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL ); + HRESULT CreateIndexBuffer( IDirect3DDevice9* pd3dDevice, + SDKMESH_INDEX_BUFFER_HEADER* pHeader, void* pIndices, + SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL ); + + virtual HRESULT CreateFromFile( ID3D11Device* pDev11, + IDirect3DDevice9* pDev9, + LPCTSTR szFileName, + bool bCreateAdjacencyIndices, + SDKMESH_CALLBACKS11* pLoaderCallbacks11 = NULL, + SDKMESH_CALLBACKS9* pLoaderCallbacks9 = NULL ); + + virtual HRESULT CreateFromMemory( ID3D11Device* pDev11, + IDirect3DDevice9* pDev9, + BYTE* pData, + UINT DataBytes, + bool bCreateAdjacencyIndices, + bool bCopyStatic, + SDKMESH_CALLBACKS11* pLoaderCallbacks11 = NULL, + SDKMESH_CALLBACKS9* pLoaderCallbacks9 = NULL ); + + //frame manipulation + void TransformBindPoseFrame( UINT iFrame, D3DXMATRIX* pParentWorld ); + void TransformFrame( UINT iFrame, D3DXMATRIX* pParentWorld, double fTime ); + void TransformFrameAbsolute( UINT iFrame, double fTime ); + + //Direct3D 11 rendering helpers + void RenderMesh( UINT iMesh, + bool bAdjacent, + ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot, + UINT iNormalSlot, + UINT iSpecularSlot ); + void RenderFrame( UINT iFrame, + bool bAdjacent, + ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot, + UINT iNormalSlot, + UINT iSpecularSlot ); + + + //Direct3D 9 rendering helpers + void RenderMesh( UINT iMesh, + LPDIRECT3DDEVICE9 pd3dDevice, + LPD3DXEFFECT pEffect, + D3DXHANDLE hTechnique, + D3DXHANDLE htxDiffuse, + D3DXHANDLE htxNormal, + D3DXHANDLE htxSpecular ); + void RenderFrame( UINT iFrame, + LPDIRECT3DDEVICE9 pd3dDevice, + LPD3DXEFFECT pEffect, + D3DXHANDLE hTechnique, + D3DXHANDLE htxDiffuse, + D3DXHANDLE htxNormal, + D3DXHANDLE htxSpecular ); + +public: + CDXUTSDKMesh(); + virtual ~CDXUTSDKMesh(); + + virtual HRESULT Create( ID3D11Device* pDev11, LPCTSTR szFileName, bool bCreateAdjacencyIndices= + false, SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL ); + virtual HRESULT Create( IDirect3DDevice9* pDev9, LPCTSTR szFileName, bool bCreateAdjacencyIndices= + false, SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL ); + virtual HRESULT Create( ID3D11Device* pDev11, BYTE* pData, UINT DataBytes, + bool bCreateAdjacencyIndices=false, bool bCopyStatic=false, + SDKMESH_CALLBACKS11* pLoaderCallbacks=NULL ); + virtual HRESULT Create( IDirect3DDevice9* pDev9, BYTE* pData, UINT DataBytes, + bool bCreateAdjacencyIndices=false, bool bCopyStatic=false, + SDKMESH_CALLBACKS9* pLoaderCallbacks=NULL ); + virtual HRESULT LoadAnimation( WCHAR* szFileName ); + virtual void Destroy(); + + //Frame manipulation + void TransformBindPose( D3DXMATRIX* pWorld ); + void TransformMesh( D3DXMATRIX* pWorld, double fTime ); + + + //Direct3D 11 Rendering + virtual void Render( ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot = INVALID_SAMPLER_SLOT, + UINT iNormalSlot = INVALID_SAMPLER_SLOT, + UINT iSpecularSlot = INVALID_SAMPLER_SLOT ); + virtual void RenderAdjacent( ID3D11DeviceContext* pd3dDeviceContext, + UINT iDiffuseSlot = INVALID_SAMPLER_SLOT, + UINT iNormalSlot = INVALID_SAMPLER_SLOT, + UINT iSpecularSlot = INVALID_SAMPLER_SLOT ); + + //Direct3D 9 Rendering + virtual void Render( LPDIRECT3DDEVICE9 pd3dDevice, + LPD3DXEFFECT pEffect, + D3DXHANDLE hTechnique, + D3DXHANDLE htxDiffuse = 0, + D3DXHANDLE htxNormal = 0, + D3DXHANDLE htxSpecular = 0 ); + + //Helpers (D3D11 specific) + static D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveType11( SDKMESH_PRIMITIVE_TYPE PrimType ); + DXGI_FORMAT GetIBFormat11( UINT iMesh ); + ID3D11Buffer* GetVB11( UINT iMesh, UINT iVB ); + ID3D11Buffer* GetIB11( UINT iMesh ); + SDKMESH_INDEX_TYPE GetIndexType( UINT iMesh ); + + ID3D11Buffer* GetAdjIB11( UINT iMesh ); + + //Helpers (D3D9 specific) + static D3DPRIMITIVETYPE GetPrimitiveType9( SDKMESH_PRIMITIVE_TYPE PrimType ); + D3DFORMAT GetIBFormat9( UINT iMesh ); + IDirect3DVertexBuffer9* GetVB9( UINT iMesh, UINT iVB ); + IDirect3DIndexBuffer9* GetIB9( UINT iMesh ); + + //Helpers (general) + char* GetMeshPathA(); + WCHAR* GetMeshPathW(); + UINT GetNumMeshes(); + UINT GetNumMaterials(); + UINT GetNumVBs(); + UINT GetNumIBs(); + + ID3D11Buffer* GetVB11At( UINT iVB ); + ID3D11Buffer* GetIB11At( UINT iIB ); + + IDirect3DVertexBuffer9* GetVB9At( UINT iVB ); + IDirect3DIndexBuffer9* GetIB9At( UINT iIB ); + + BYTE* GetRawVerticesAt( UINT iVB ); + BYTE* GetRawIndicesAt( UINT iIB ); + SDKMESH_MATERIAL* GetMaterial( UINT iMaterial ); + SDKMESH_MESH* GetMesh( UINT iMesh ); + UINT GetNumSubsets( UINT iMesh ); + SDKMESH_SUBSET* GetSubset( UINT iMesh, UINT iSubset ); + UINT GetVertexStride( UINT iMesh, UINT iVB ); + UINT GetNumFrames(); + SDKMESH_FRAME* GetFrame( UINT iFrame ); + SDKMESH_FRAME* FindFrame( char* pszName ); + UINT64 GetNumVertices( UINT iMesh, UINT iVB ); + UINT64 GetNumIndices( UINT iMesh ); + D3DXVECTOR3 GetMeshBBoxCenter( UINT iMesh ); + D3DXVECTOR3 GetMeshBBoxExtents( UINT iMesh ); + UINT GetOutstandingResources(); + UINT GetOutstandingBufferResources(); + bool CheckLoadDone(); + bool IsLoaded(); + bool IsLoading(); + void SetLoading( bool bLoading ); + BOOL HadLoadingError(); + + //Animation + UINT GetNumInfluences( UINT iMesh ); + const D3DXMATRIX* GetMeshInfluenceMatrix( UINT iMesh, UINT iInfluence ); + UINT GetAnimationKeyFromTime( double fTime ); + const D3DXMATRIX* GetWorldMatrix( UINT iFrameIndex ); + const D3DXMATRIX* GetInfluenceMatrix( UINT iFrameIndex ); + bool GetAnimationProperties( UINT* pNumKeys, FLOAT* pFrameTime ); +}; + +//----------------------------------------------------------------------------- +// Name: class CDXUTXFileMesh +// Desc: Class for loading and rendering file-based meshes +//----------------------------------------------------------------------------- +class CDXUTXFileMesh +{ +public: + WCHAR m_strName[512]; + LPD3DXMESH m_pMesh; // Managed mesh + + // Cache of data in m_pMesh for easy access + IDirect3DVertexBuffer9* m_pVB; + IDirect3DIndexBuffer9* m_pIB; + IDirect3DVertexDeclaration9* m_pDecl; + DWORD m_dwNumVertices; + DWORD m_dwNumFaces; + DWORD m_dwBytesPerVertex; + + DWORD m_dwNumMaterials; // Materials for the mesh + D3DMATERIAL9* m_pMaterials; + CHAR (*m_strMaterials )[MAX_PATH]; + IDirect3DBaseTexture9** m_pTextures; + bool m_bUseMaterials; + +public: + // Rendering + HRESULT Render( LPDIRECT3DDEVICE9 pd3dDevice, + bool bDrawOpaqueSubsets = true, + bool bDrawAlphaSubsets = true ); + HRESULT Render( ID3DXEffect* pEffect, + D3DXHANDLE hTexture = NULL, + D3DXHANDLE hDiffuse = NULL, + D3DXHANDLE hAmbient = NULL, + D3DXHANDLE hSpecular = NULL, + D3DXHANDLE hEmissive = NULL, + D3DXHANDLE hPower = NULL, + bool bDrawOpaqueSubsets = true, + bool bDrawAlphaSubsets = true ); + + // Mesh access + LPD3DXMESH GetMesh() + { + return m_pMesh; + } + + // Rendering options + void UseMeshMaterials( bool bFlag ) + { + m_bUseMaterials = bFlag; + } + HRESULT SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF ); + HRESULT SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9* pDecl, + bool bAutoComputeNormals = true, bool bAutoComputeTangents = true, + bool bSplitVertexForOptimalTangents = false ); + + // Initializing + HRESULT RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice ); + HRESULT InvalidateDeviceObjects(); + + // Creation/destruction + HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename ); + HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPD3DXFILEDATA pFileData ); + HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh* pInMesh, D3DXMATERIAL* pd3dxMaterials, + DWORD dwMaterials ); + HRESULT CreateMaterials( LPCWSTR strPath, IDirect3DDevice9* pd3dDevice, D3DXMATERIAL* d3dxMtrls, + DWORD dwNumMaterials ); + HRESULT Destroy(); + + CDXUTXFileMesh( LPCWSTR strName = L"CDXUTXMeshFile_Mesh" ); + virtual ~CDXUTXFileMesh(); +}; + + +#endif + +#endif + diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp b/Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp new file mode 100644 index 0000000..6fcb98f --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp @@ -0,0 +1,1695 @@ +//-------------------------------------------------------------------------------------- +// File: SDKmisc.cpp +// +// Various helper functionality that is shared between SDK samples +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#include "dxut.h" +#include "SDKmisc.h" +#include "DXUTres.h" +#undef min // use __min instead +#undef max // use __max instead + +#include "DXUTGui.h" + +//-------------------------------------------------------------------------------------- +// Global/Static Members +//-------------------------------------------------------------------------------------- +CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache() +{ + // Using an accessor function gives control of the construction order + static CDXUTResourceCache cache; + return cache; +} + + +//-------------------------------------------------------------------------------------- +// Internal functions forward declarations +//-------------------------------------------------------------------------------------- +bool DXUTFindMediaSearchTypicalDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, + int cchSearch, + __in LPCWSTR strLeaf, + __in WCHAR* strExePath, + __in WCHAR* strExeName ); +bool DXUTFindMediaSearchParentDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, + int cchSearch, + __in WCHAR* strStartAt, + __in WCHAR* strLeafName ); +INT_PTR CALLBACK DisplaySwitchToREFWarningProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ); + + +//-------------------------------------------------------------------------------------- +// Shared code for samples to ask user if they want to use a REF device or quit +//-------------------------------------------------------------------------------------- +void WINAPI DXUTDisplaySwitchingToREFWarning( DXUTDeviceVersion ver ) +{ + if( DXUTGetShowMsgBoxOnError() ) + { + DWORD dwSkipWarning = 0, dwRead = 0, dwWritten = 0; + HANDLE hFile = NULL; + + // Read previous user settings + WCHAR strPath[MAX_PATH]; + SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath ); + wcscat_s( strPath, MAX_PATH, L"\\DXUT\\SkipRefWarning.dat" ); + if( ( hFile = CreateFile( strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, + NULL ) ) != INVALID_HANDLE_VALUE ) + { + ReadFile( hFile, &dwSkipWarning, sizeof( DWORD ), &dwRead, NULL ); + CloseHandle( hFile ); + } + + if( dwSkipWarning == 0 ) + { + // Compact code to create a custom dialog box without using a template in a resource file. + // If this dialog were in a .rc file, this would be a lot simpler but every sample calling this function would + // need a copy of the dialog in its own .rc file. Also MessageBox API could be used here instead, but + // the MessageBox API is simpler to call but it can't provide a "Don't show again" checkbox + typedef struct + { + DLGITEMTEMPLATE a; + WORD b; + WORD c; + WORD d; + WORD e; + WORD f; + } DXUT_DLG_ITEM; + typedef struct + { + DLGTEMPLATE a; + WORD b; + WORD c; + WCHAR d[2]; + WORD e; + WCHAR f[16]; + DXUT_DLG_ITEM i1; + DXUT_DLG_ITEM i2; + DXUT_DLG_ITEM i3; + DXUT_DLG_ITEM i4; + DXUT_DLG_ITEM i5; + } DXUT_DLG_DATA; + + DXUT_DLG_DATA dtp = + { + {WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_SYSMENU | DS_ABSALIGN | DS_3DLOOK | DS_SETFONT | + DS_MODALFRAME | DS_CENTER,0,5,0,0,269,82},0,0,L" ",8,L"MS Shell Dlg 2", + { {WS_CHILD | WS_VISIBLE | SS_ICON | SS_CENTERIMAGE,0,7,7,24,24,0x100},0xFFFF,0x0082,0,0,0}, // icon + { {WS_CHILD | WS_VISIBLE,0,40,7,230,25,0x101},0xFFFF,0x0082,0,0,0}, // static text + { {WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,0,80,39,50,14,IDYES},0xFFFF,0x0080,0,0,0}, // Yes button + { {WS_CHILD | WS_VISIBLE | WS_TABSTOP,0,133,39,50,14,IDNO},0xFFFF,0x0080,0,0,0}, // No button + { {WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX,0,7,59,70,16,IDIGNORE},0xFFFF,0x0080,0,0,0}, // checkbox + }; + + LPARAM lParam; + if( ver == DXUT_D3D9_DEVICE ) + lParam = 9; + else + lParam = 11; + int nResult = ( int )DialogBoxIndirectParam( DXUTGetHINSTANCE(), ( DLGTEMPLATE* )&dtp, DXUTGetHWND(), + DisplaySwitchToREFWarningProc, lParam ); + + if( ( nResult & 0x80 ) == 0x80 ) // "Don't show again" checkbox was checked + { + // Save user settings + dwSkipWarning = 1; + SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath ); + wcscat_s( strPath, MAX_PATH, L"\\DXUT" ); + CreateDirectory( strPath, NULL ); + wcscat_s( strPath, MAX_PATH, L"\\SkipRefWarning.dat" ); + if( ( hFile = CreateFile( strPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, + NULL ) ) != INVALID_HANDLE_VALUE ) + { + WriteFile( hFile, &dwSkipWarning, sizeof( DWORD ), &dwWritten, NULL ); + CloseHandle( hFile ); + } + } + + // User choose not to continue + if( ( nResult & 0x0F ) == IDNO ) + DXUTShutdown( 1 ); + } + } +} + + +//-------------------------------------------------------------------------------------- +// MsgProc for DXUTDisplaySwitchingToREFWarning() dialog box +//-------------------------------------------------------------------------------------- +INT_PTR CALLBACK DisplaySwitchToREFWarningProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) +{ + switch( message ) + { + case WM_INITDIALOG: + // Easier to set text here than in the DLGITEMTEMPLATE + SetWindowText( hDlg, DXUTGetWindowTitle() ); + SendMessage( GetDlgItem( hDlg, 0x100 ), STM_SETIMAGE, IMAGE_ICON, ( LPARAM )LoadIcon( 0, IDI_QUESTION ) ); + WCHAR sz[512]; + swprintf_s( sz, 512, + L"This program needs to use the Direct3D %d reference device. This device implements the entire Direct3D %d feature set, but runs very slowly. Do you wish to continue?", lParam, lParam ); + SetDlgItemText( hDlg, 0x101, sz ); + SetDlgItemText( hDlg, IDYES, L"&Yes" ); + SetDlgItemText( hDlg, IDNO, L"&No" ); + SetDlgItemText( hDlg, IDIGNORE, L"&Don't show again" ); + break; + + case WM_COMMAND: + switch( LOWORD( wParam ) ) + { + case IDIGNORE: + CheckDlgButton( hDlg, IDIGNORE, ( IsDlgButtonChecked( hDlg, + IDIGNORE ) == BST_CHECKED ) ? BST_UNCHECKED : + BST_CHECKED ); + EnableWindow( GetDlgItem( hDlg, IDNO ), ( IsDlgButtonChecked( hDlg, IDIGNORE ) != BST_CHECKED ) ); + break; + case IDNO: + EndDialog( hDlg, ( IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED ) ? IDNO | 0x80 : IDNO | + 0x00 ); return TRUE; + case IDCANCEL: + case IDYES: + EndDialog( hDlg, ( IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED ) ? IDYES | 0x80 : IDYES | + 0x00 ); return TRUE; + } + break; + } + return FALSE; +} + + +//-------------------------------------------------------------------------------------- +// Returns pointer to static media search buffer +//-------------------------------------------------------------------------------------- +WCHAR* DXUTMediaSearchPath() +{ + static WCHAR s_strMediaSearchPath[MAX_PATH] = + { + 0 + }; + return s_strMediaSearchPath; + +} + +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTGetMediaSearchPath() +{ + return DXUTMediaSearchPath(); +} + + +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTSetMediaSearchPath( LPCWSTR strPath ) +{ + HRESULT hr; + + WCHAR* s_strSearchPath = DXUTMediaSearchPath(); + + hr = wcscpy_s( s_strSearchPath, MAX_PATH, strPath ); + if( SUCCEEDED( hr ) ) + { + // append slash if needed + size_t ch = 0; + ch = wcsnlen( s_strSearchPath, MAX_PATH); + if( SUCCEEDED( hr ) && s_strSearchPath[ch - 1] != L'\\' ) + { + hr = wcscat_s( s_strSearchPath, MAX_PATH, L"\\" ); + } + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +// Tries to find the location of a SDK media file +// cchDest is the size in WCHARs of strDestPath. Be careful not to +// pass in sizeof(strDest) on UNICODE builds. +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTFindDXSDKMediaFileCch(__in_ecount(cchDest) WCHAR* strDestPath, + int cchDest, + __in LPCWSTR strFilename ) +{ + bool bFound; + WCHAR strSearchFor[MAX_PATH]; + + if( NULL == strFilename || strFilename[0] == 0 || NULL == strDestPath || cchDest < 10 ) + return E_INVALIDARG; + + // Get the exe name, and exe path + WCHAR strExePath[MAX_PATH] = + { + 0 + }; + WCHAR strExeName[MAX_PATH] = + { + 0 + }; + WCHAR* strLastSlash = NULL; + GetModuleFileName( NULL, strExePath, MAX_PATH ); + strExePath[MAX_PATH - 1] = 0; + strLastSlash = wcsrchr( strExePath, TEXT( '\\' ) ); + if( strLastSlash ) + { + wcscpy_s( strExeName, MAX_PATH, &strLastSlash[1] ); + + // Chop the exe name from the exe path + *strLastSlash = 0; + + // Chop the .exe from the exe name + strLastSlash = wcsrchr( strExeName, TEXT( '.' ) ); + if( strLastSlash ) + *strLastSlash = 0; + } + + // Typical directories: + // .\ + // ..\ + // ..\..\ + // %EXE_DIR%\ + // %EXE_DIR%\..\ + // %EXE_DIR%\..\..\ + // %EXE_DIR%\..\%EXE_NAME% + // %EXE_DIR%\..\..\%EXE_NAME% + + // Typical directory search + bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strFilename, strExePath, strExeName ); + if( bFound ) + return S_OK; + + // Typical directory search again, but also look in a subdir called "\media\" + swprintf_s( strSearchFor, MAX_PATH, L"media\\%s", strFilename ); + bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strSearchFor, strExePath, strExeName ); + if( bFound ) + return S_OK; + + WCHAR strLeafName[MAX_PATH] = + { + 0 + }; + + // Search all parent directories starting at .\ and using strFilename as the leaf name + wcscpy_s( strLeafName, MAX_PATH, strFilename ); + bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName ); + if( bFound ) + return S_OK; + + // Search all parent directories starting at the exe's dir and using strFilename as the leaf name + bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName ); + if( bFound ) + return S_OK; + + // Search all parent directories starting at .\ and using "media\strFilename" as the leaf name + swprintf_s( strLeafName, MAX_PATH, L"media\\%s", strFilename ); + bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName ); + if( bFound ) + return S_OK; + + // Search all parent directories starting at the exe's dir and using "media\strFilename" as the leaf name + bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName ); + if( bFound ) + return S_OK; + + // On failure, return the file as the path but also return an error code + wcscpy_s( strDestPath, cchDest, strFilename ); + + return DXUTERR_MEDIANOTFOUND; +} + + +//-------------------------------------------------------------------------------------- +// Search a set of typical directories +//-------------------------------------------------------------------------------------- +bool DXUTFindMediaSearchTypicalDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, + int cchSearch, + __in LPCWSTR strLeaf, + __in WCHAR* strExePath, + __in WCHAR* strExeName ) +{ + // Typical directories: + // .\ + // ..\ + // ..\..\ + // %EXE_DIR%\ + // %EXE_DIR%\..\ + // %EXE_DIR%\..\..\ + // %EXE_DIR%\..\%EXE_NAME% + // %EXE_DIR%\..\..\%EXE_NAME% + // DXSDK media path + + // Search in .\ + wcscpy_s( strSearchPath, cchSearch, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in ..\ + swprintf_s( strSearchPath, cchSearch, L"..\\%s", strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in ..\..\ + swprintf_s( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in ..\..\ + swprintf_s( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in the %EXE_DIR%\ + swprintf_s( strSearchPath, cchSearch, L"%s\\%s", strExePath, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in the %EXE_DIR%\..\ + swprintf_s( strSearchPath, cchSearch, L"%s\\..\\%s", strExePath, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in the %EXE_DIR%\..\..\ + swprintf_s( strSearchPath, cchSearch, L"%s\\..\\..\\%s", strExePath, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in "%EXE_DIR%\..\%EXE_NAME%\". This matches the DirectX SDK layout + swprintf_s( strSearchPath, cchSearch, L"%s\\..\\%s\\%s", strExePath, strExeName, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in "%EXE_DIR%\..\..\%EXE_NAME%\". This matches the DirectX SDK layout + swprintf_s( strSearchPath, cchSearch, L"%s\\..\\..\\%s\\%s", strExePath, strExeName, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in "%EXE_DIR%\Demos\DX11ClothDemo\Media\". This matches the Bullet SDK layout + swprintf_s( strSearchPath, cchSearch, L"%s\\Demos\\DX11ClothDemo\\Media\\%s", strExePath, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + // Search in "%EXE_DIR%\Demos\DX11ClothDemo\". This matches the Bullet SDK layout + swprintf_s( strSearchPath, cchSearch, L"%s\\Demos\\DX11ClothDemo\\%s", strExePath, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + + + // Search in media search dir + WCHAR* s_strSearchPath = DXUTMediaSearchPath(); + if( s_strSearchPath[0] != 0 ) + { + swprintf_s( strSearchPath, cchSearch, L"%s%s", s_strSearchPath, strLeaf ); + if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF ) + return true; + } + + return false; +} + + + +//-------------------------------------------------------------------------------------- +// Search parent directories starting at strStartAt, and appending strLeafName +// at each parent directory. It stops at the root directory. +//-------------------------------------------------------------------------------------- +bool DXUTFindMediaSearchParentDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, + int cchSearch, + __in WCHAR* strStartAt, + __in WCHAR* strLeafName ) +{ + WCHAR strFullPath[MAX_PATH] = + { + 0 + }; + WCHAR strFullFileName[MAX_PATH] = + { + 0 + }; + WCHAR strSearch[MAX_PATH] = + { + 0 + }; + WCHAR* strFilePart = NULL; + + GetFullPathName( strStartAt, MAX_PATH, strFullPath, &strFilePart ); + if( strFilePart == NULL ) + return false; + + while( strFilePart != NULL && *strFilePart != '\0' ) + { + swprintf_s( strFullFileName, MAX_PATH, L"%s\\%s", strFullPath, strLeafName ); + if( GetFileAttributes( strFullFileName ) != 0xFFFFFFFF ) + { + wcscpy_s( strSearchPath, cchSearch, strFullFileName ); + return true; + } + + swprintf_s( strSearch, MAX_PATH, L"%s\\..", strFullPath ); + GetFullPathName( strSearch, MAX_PATH, strFullPath, &strFilePart ); + } + + return false; +} + + +//-------------------------------------------------------------------------------------- +// CDXUTResourceCache +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +CDXUTResourceCache::~CDXUTResourceCache() +{ + OnDestroyDevice(); + + m_TextureCache.RemoveAll(); + m_EffectCache.RemoveAll(); + m_FontCache.RemoveAll(); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture ) +{ + return CreateTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, + 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, + 0, NULL, NULL, ppTexture ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture ) +{ + WCHAR szSrcFile[MAX_PATH]; + MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, szSrcFile, MAX_PATH ); + szSrcFile[MAX_PATH - 1] = 0; + + return CreateTextureFromFile( pDevice, szSrcFile, ppTexture ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCTSTR pSrcFile, + ID3D11ShaderResourceView** ppOutputRV, bool bSRGB ) +{ + return CreateTextureFromFileEx( pDevice, pContext, pSrcFile, NULL, NULL, ppOutputRV, bSRGB ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCSTR pSrcFile, + ID3D11ShaderResourceView** ppOutputRV, bool bSRGB ) +{ + WCHAR szSrcFile[MAX_PATH]; + MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, szSrcFile, MAX_PATH ); + szSrcFile[MAX_PATH - 1] = 0; + + return CreateTextureFromFile( pDevice, pContext, szSrcFile, ppOutputRV, bSRGB ); +} + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width, + UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format, + D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_TextureCache.GetSize(); ++i ) + { + DXUTCache_Texture& Entry = m_TextureCache[i]; + if( Entry.Location == DXUTCACHE_LOCATION_FILE && + !lstrcmpW( Entry.wszSource, pSrcFile ) && + Entry.Width == Width && + Entry.Height == Height && + Entry.MipLevels == MipLevels && + Entry.Usage9 == Usage && + Entry.Format9 == Format && + Entry.Pool9 == Pool && + Entry.Type9 == D3DRTYPE_TEXTURE ) + { + // A match is found. Obtain the IDirect3DTexture9 interface and return that. + return Entry.pTexture9->QueryInterface( IID_IDirect3DTexture9, ( LPVOID* )ppTexture ); + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateTextureFromFileEx( pDevice, pSrcFile, Width, Height, MipLevels, Usage, Format, + Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Texture NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_FILE; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile ); + NewEntry.Width = Width; + NewEntry.Height = Height; + NewEntry.MipLevels = MipLevels; + NewEntry.Usage9 = Usage; + NewEntry.Format9 = Format; + NewEntry.Pool9 = Pool; + NewEntry.Type9 = D3DRTYPE_TEXTURE; + ( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 ); + + m_TextureCache.Add( NewEntry ); + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromFileEx( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, LPCTSTR pSrcFile, + D3DX11_IMAGE_LOAD_INFO* pLoadInfo, ID3DX11ThreadPump* pPump, + ID3D11ShaderResourceView** ppOutputRV, bool bSRGB ) +{ + + bool is10L9 = DXUTGetDeviceSettings().d3d11.DeviceFeatureLevel < D3D_FEATURE_LEVEL_10_0; + HRESULT hr = S_OK; + D3DX11_IMAGE_LOAD_INFO ZeroInfo; //D3DX11_IMAGE_LOAD_INFO has a default constructor + D3DX11_IMAGE_INFO SrcInfo; + + if( !pLoadInfo ) + { + pLoadInfo = &ZeroInfo; + } + + if( !pLoadInfo->pSrcInfo ) + { + D3DX11GetImageInfoFromFile( pSrcFile, NULL, &SrcInfo, NULL ); + pLoadInfo->pSrcInfo = &SrcInfo; + + pLoadInfo->Format = pLoadInfo->pSrcInfo->Format; + } + + // Search the cache for a matching entry. + for( int i = 0; i < m_TextureCache.GetSize(); ++i ) + { + DXUTCache_Texture& Entry = m_TextureCache[i]; + if( Entry.Location == DXUTCACHE_LOCATION_FILE && + !lstrcmpW( Entry.wszSource, pSrcFile ) && + Entry.Width == pLoadInfo->Width && + Entry.Height == pLoadInfo->Height && + Entry.MipLevels == pLoadInfo->MipLevels && + Entry.Usage11 == pLoadInfo->Usage && + Entry.Format == pLoadInfo->Format && + Entry.CpuAccessFlags == pLoadInfo->CpuAccessFlags && + Entry.BindFlags == pLoadInfo->BindFlags && + Entry.MiscFlags == pLoadInfo->MiscFlags ) + { + // A match is found. Obtain the IDirect3DTexture9 interface and return that. + return Entry.pSRV11->QueryInterface( __uuidof( ID3D11ShaderResourceView ), ( LPVOID* )ppOutputRV ); + } + } + + //Ready a new entry to the texture cache + //Do this before creating the texture since pLoadInfo may be volatile + DXUTCache_Texture NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_FILE; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile ); + NewEntry.Width = pLoadInfo->Width; + NewEntry.Height = pLoadInfo->Height; + NewEntry.MipLevels = pLoadInfo->MipLevels; + NewEntry.Usage11 = pLoadInfo->Usage; + // 10L9 can't handle typesless, so we cant make a typesless format + if (is10L9 && bSRGB) { + NewEntry.Format = MAKE_SRGB(pLoadInfo->Format); + }else { + NewEntry.Format = pLoadInfo->Format; + } + NewEntry.CpuAccessFlags = pLoadInfo->CpuAccessFlags; + NewEntry.BindFlags = pLoadInfo->BindFlags; + NewEntry.MiscFlags = pLoadInfo->MiscFlags; + + //Create the rexture + ID3D11Texture2D* pRes = NULL; + hr = D3DX11CreateTextureFromFile( pDevice, pSrcFile, pLoadInfo, pPump, ( ID3D11Resource** )&pRes, NULL ); + + if( FAILED( hr ) ) + return hr; + D3D11_TEXTURE2D_DESC tex_dsc; + pRes->GetDesc(&tex_dsc); + + + + if (bSRGB ) { + // This is a workaround so that we can load linearly, but sample in SRGB. Right now, we can't load + // as linear since D3DX will try to do conversion on load. Loading as TYPELESS doesn't work either, and + // loading as typed _UNORM doesn't allow us to create an SRGB view. + + // on d3d11 featuer levels this is just a copy, but on 10L9 we must use a cpu side copy with 2 staging resources. + ID3D11Texture2D* unormStaging = NULL; + ID3D11Texture2D* srgbStaging = NULL; + + D3D11_TEXTURE2D_DESC CopyDesc; + pRes->GetDesc( &CopyDesc ); + + pLoadInfo->BindFlags = 0; + pLoadInfo->CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; + pLoadInfo->Depth = 0; + pLoadInfo->Filter = D3DX11_FILTER_POINT; + pLoadInfo->FirstMipLevel = 0; + pLoadInfo->Format = CopyDesc.Format; + pLoadInfo->Height = CopyDesc.Height; + pLoadInfo->MipFilter = D3DX11_FILTER_POINT; + pLoadInfo->MiscFlags = CopyDesc.MiscFlags; + pLoadInfo->Usage = D3D11_USAGE_STAGING; + pLoadInfo->Width = CopyDesc.Width; + + CopyDesc.BindFlags = 0; + CopyDesc.Usage = D3D11_USAGE_STAGING; + CopyDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; + CopyDesc.Format = MAKE_SRGB(CopyDesc.Format); + + hr = D3DX11CreateTextureFromFile( pDevice, pSrcFile, pLoadInfo, pPump, ( ID3D11Resource** )&unormStaging, NULL ); + + hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbStaging); + pContext->CopyResource( srgbStaging, unormStaging ); + ID3D11Texture2D* srgbGPU; + + pRes->GetDesc( &CopyDesc ); + CopyDesc.Format = MAKE_SRGB(CopyDesc.Format); + hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbGPU); + pContext->CopyResource( srgbGPU, srgbStaging ); + + SAFE_RELEASE(pRes); + SAFE_RELEASE(srgbStaging); + SAFE_RELEASE(unormStaging); + pRes = srgbGPU; + + } + + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + if( bSRGB ) + SRVDesc.Format = MAKE_SRGB( ZeroInfo.Format ); + else + SRVDesc.Format = ZeroInfo.Format; + if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE1D ) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + SRVDesc.Texture1D.MostDetailedMip = 0; + SRVDesc.Texture1D.MipLevels = pLoadInfo->pSrcInfo->MipLevels; + } + else if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE2D ) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Texture2D.MostDetailedMip = 0; + SRVDesc.Texture2D.MipLevels = pLoadInfo->pSrcInfo->MipLevels; + + if( pLoadInfo->pSrcInfo->MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE ) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + SRVDesc.TextureCube.MostDetailedMip = 0; + SRVDesc.TextureCube.MipLevels = pLoadInfo->pSrcInfo->MipLevels; + } + } + else if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE3D ) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + SRVDesc.Texture3D.MostDetailedMip = 0; + SRVDesc.Texture3D.MipLevels = pLoadInfo->pSrcInfo->MipLevels; + } + if (bSRGB) { + SRVDesc.Format = MAKE_SRGB(tex_dsc.Format); + }else { + SRVDesc.Format = tex_dsc.Format; + } + SRVDesc.Texture2D.MipLevels = tex_dsc.MipLevels; + SRVDesc.Texture2D.MostDetailedMip = 0; + hr = pDevice->CreateShaderResourceView( pRes, &SRVDesc, ppOutputRV ); + pRes->Release(); + if( FAILED( hr ) ) + return hr; + + ( *ppOutputRV )->QueryInterface( __uuidof( ID3D11ShaderResourceView ), ( LPVOID* )&NewEntry.pSRV11 ); + + m_TextureCache.Add( NewEntry ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, LPDIRECT3DTEXTURE9* ppTexture ) +{ + return CreateTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT, + D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, + D3DX_DEFAULT, 0, NULL, NULL, ppTexture ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, UINT Width, UINT Height, UINT MipLevels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE9* ppTexture ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_TextureCache.GetSize(); ++i ) + { + DXUTCache_Texture& Entry = m_TextureCache[i]; + if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE && + Entry.hSrcModule == hSrcModule && + !lstrcmpW( Entry.wszSource, pSrcResource ) && + Entry.Width == Width && + Entry.Height == Height && + Entry.MipLevels == MipLevels && + Entry.Usage9 == Usage && + Entry.Format9 == Format && + Entry.Pool9 == Pool && + Entry.Type9 == D3DRTYPE_TEXTURE ) + { + // A match is found. Obtain the IDirect3DTexture9 interface and return that. + return Entry.pTexture9->QueryInterface( IID_IDirect3DTexture9, ( LPVOID* )ppTexture ); + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Width, Height, MipLevels, Usage, + Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Texture NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE; + NewEntry.hSrcModule = hSrcModule; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource ); + NewEntry.Width = Width; + NewEntry.Height = Height; + NewEntry.MipLevels = MipLevels; + NewEntry.Usage9 = Usage; + NewEntry.Format9 = Format; + NewEntry.Pool9 = Pool; + NewEntry.Type9 = D3DRTYPE_TEXTURE; + ( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 ); + + m_TextureCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateCubeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ) +{ + return CreateCubeTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, 0, + D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, + 0, NULL, NULL, ppCubeTexture ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateCubeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Size, + UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_TextureCache.GetSize(); ++i ) + { + DXUTCache_Texture& Entry = m_TextureCache[i]; + if( Entry.Location == DXUTCACHE_LOCATION_FILE && + !lstrcmpW( Entry.wszSource, pSrcFile ) && + Entry.Width == Size && + Entry.MipLevels == MipLevels && + Entry.Usage9 == Usage && + Entry.Format9 == Format && + Entry.Pool9 == Pool && + Entry.Type9 == D3DRTYPE_CUBETEXTURE ) + { + // A match is found. Obtain the IDirect3DCubeTexture9 interface and return that. + return Entry.pTexture9->QueryInterface( IID_IDirect3DCubeTexture9, ( LPVOID* )ppCubeTexture ); + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateCubeTextureFromFileEx( pDevice, pSrcFile, Size, MipLevels, Usage, Format, Pool, Filter, + MipFilter, ColorKey, pSrcInfo, pPalette, ppCubeTexture ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Texture NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_FILE; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile ); + NewEntry.Width = Size; + NewEntry.MipLevels = MipLevels; + NewEntry.Usage9 = Usage; + NewEntry.Format9 = Format; + NewEntry.Pool9 = Pool; + NewEntry.Type9 = D3DRTYPE_CUBETEXTURE; + ( *ppCubeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 ); + + m_TextureCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateCubeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ) +{ + return CreateCubeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT, + 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, + 0, NULL, NULL, ppCubeTexture ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateCubeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, UINT Size, UINT MipLevels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_TextureCache.GetSize(); ++i ) + { + DXUTCache_Texture& Entry = m_TextureCache[i]; + if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE && + Entry.hSrcModule == hSrcModule && + !lstrcmpW( Entry.wszSource, pSrcResource ) && + Entry.Width == Size && + Entry.MipLevels == MipLevels && + Entry.Usage9 == Usage && + Entry.Format9 == Format && + Entry.Pool9 == Pool && + Entry.Type9 == D3DRTYPE_CUBETEXTURE ) + { + // A match is found. Obtain the IDirect3DCubeTexture9 interface and return that. + return Entry.pTexture9->QueryInterface( IID_IDirect3DCubeTexture9, ( LPVOID* )ppCubeTexture ); + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateCubeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Size, MipLevels, Usage, Format, + Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppCubeTexture ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Texture NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE; + NewEntry.hSrcModule = hSrcModule; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource ); + NewEntry.Width = Size; + NewEntry.MipLevels = MipLevels; + NewEntry.Usage9 = Usage; + NewEntry.Format9 = Format; + NewEntry.Pool9 = Pool; + NewEntry.Type9 = D3DRTYPE_CUBETEXTURE; + ( *ppCubeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 ); + + m_TextureCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateVolumeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture ) +{ + return CreateVolumeTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, + 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, + 0, NULL, NULL, ppVolumeTexture ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateVolumeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width, + UINT Height, UINT Depth, UINT MipLevels, DWORD Usage, + D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppTexture ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_TextureCache.GetSize(); ++i ) + { + DXUTCache_Texture& Entry = m_TextureCache[i]; + if( Entry.Location == DXUTCACHE_LOCATION_FILE && + !lstrcmpW( Entry.wszSource, pSrcFile ) && + Entry.Width == Width && + Entry.Height == Height && + Entry.Depth == Depth && + Entry.MipLevels == MipLevels && + Entry.Usage9 == Usage && + Entry.Format9 == Format && + Entry.Pool9 == Pool && + Entry.Type9 == D3DRTYPE_VOLUMETEXTURE ) + { + // A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that. + return Entry.pTexture9->QueryInterface( IID_IDirect3DVolumeTexture9, ( LPVOID* )ppTexture ); + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateVolumeTextureFromFileEx( pDevice, pSrcFile, Width, Height, Depth, MipLevels, Usage, Format, + Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Texture NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_FILE; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile ); + NewEntry.Width = Width; + NewEntry.Height = Height; + NewEntry.Depth = Depth; + NewEntry.MipLevels = MipLevels; + NewEntry.Usage9 = Usage; + NewEntry.Format9 = Format; + NewEntry.Pool9 = Pool; + NewEntry.Type9 = D3DRTYPE_VOLUMETEXTURE; + ( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 ); + + m_TextureCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateVolumeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture ) +{ + return CreateVolumeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT, + D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, + D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppVolumeTexture ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateVolumeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, UINT Width, UINT Height, + UINT Depth, UINT MipLevels, DWORD Usage, + D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_TextureCache.GetSize(); ++i ) + { + DXUTCache_Texture& Entry = m_TextureCache[i]; + if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE && + Entry.hSrcModule == hSrcModule && + !lstrcmpW( Entry.wszSource, pSrcResource ) && + Entry.Width == Width && + Entry.Height == Height && + Entry.Depth == Depth && + Entry.MipLevels == MipLevels && + Entry.Usage9 == Usage && + Entry.Format9 == Format && + Entry.Pool9 == Pool && + Entry.Type9 == D3DRTYPE_VOLUMETEXTURE ) + { + // A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that. + return Entry.pTexture9->QueryInterface( IID_IDirect3DVolumeTexture9, ( LPVOID* )ppVolumeTexture ); + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateVolumeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Width, Height, Depth, MipLevels, + Usage, + Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, + ppVolumeTexture ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Texture NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE; + NewEntry.hSrcModule = hSrcModule; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource ); + NewEntry.Width = Width; + NewEntry.Height = Height; + NewEntry.Depth = Depth; + NewEntry.MipLevels = MipLevels; + NewEntry.Usage9 = Usage; + NewEntry.Format9 = Format; + NewEntry.Pool9 = Pool; + NewEntry.Type9 = D3DRTYPE_VOLUMETEXTURE; + ( *ppVolumeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 ); + + m_TextureCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateFont( LPDIRECT3DDEVICE9 pDevice, UINT Height, UINT Width, UINT Weight, + UINT MipLevels, BOOL Italic, DWORD CharSet, DWORD OutputPrecision, + DWORD Quality, DWORD PitchAndFamily, LPCTSTR pFacename, LPD3DXFONT* ppFont ) +{ + D3DXFONT_DESCW Desc; + + Desc.Height = Height; + Desc.Width = Width; + Desc.Weight = Weight; + Desc.MipLevels = MipLevels; + Desc.Italic = Italic; + Desc.CharSet = ( BYTE )CharSet; + Desc.OutputPrecision = ( BYTE )OutputPrecision; + Desc.Quality = ( BYTE )Quality; + Desc.PitchAndFamily = ( BYTE )PitchAndFamily; + wcscpy_s( Desc.FaceName, LF_FACESIZE, pFacename ); + + return CreateFontIndirect( pDevice, &Desc, ppFont ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateFontIndirect( LPDIRECT3DDEVICE9 pDevice, CONST D3DXFONT_DESC *pDesc, LPD3DXFONT *ppFont ) + { + // Search the cache for a matching entry. + for( int i = 0; i < m_FontCache.GetSize(); ++i ) + { + DXUTCache_Font &Entry = m_FontCache[i]; + + if( Entry.Width == pDesc->Width && + Entry.Height == pDesc->Height && + Entry.Weight == pDesc->Weight && + Entry.MipLevels == pDesc->MipLevels && + Entry.Italic == pDesc->Italic && + Entry.CharSet == pDesc->CharSet && + Entry.OutputPrecision == pDesc->OutputPrecision && + Entry.Quality == pDesc->Quality && + Entry.PitchAndFamily == pDesc->PitchAndFamily && + CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, + Entry.FaceName, -1, + pDesc->FaceName, -1 ) == CSTR_EQUAL ) + { + // A match is found. Increment the reference and return the ID3DXFont object. + Entry.pFont->AddRef(); + *ppFont = Entry.pFont; + return S_OK; + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateFontIndirect( pDevice, pDesc, ppFont ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Font NewEntry; + ( D3DXFONT_DESC & )NewEntry = *pDesc; + NewEntry.pFont = *ppFont; + NewEntry.pFont->AddRef(); + + m_FontCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateEffectFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + const D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_EffectCache.GetSize(); ++i ) + { + DXUTCache_Effect& Entry = m_EffectCache[i]; + + if( Entry.Location == DXUTCACHE_LOCATION_FILE && + !lstrcmpW( Entry.wszSource, pSrcFile ) && + Entry.dwFlags == Flags ) + { + // A match is found. Increment the ref coutn and return the ID3DXEffect object. + *ppEffect = Entry.pEffect; + ( *ppEffect )->AddRef(); + return S_OK; + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateEffectFromFile( pDevice, pSrcFile, pDefines, pInclude, Flags, pPool, ppEffect, + ppCompilationErrors ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Effect NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_FILE; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile ); + NewEntry.dwFlags = Flags; + NewEntry.pEffect = *ppEffect; + NewEntry.pEffect->AddRef(); + + m_EffectCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::CreateEffectFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, const D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, LPD3DXBUFFER* ppCompilationErrors ) +{ + // Search the cache for a matching entry. + for( int i = 0; i < m_EffectCache.GetSize(); ++i ) + { + DXUTCache_Effect& Entry = m_EffectCache[i]; + + if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE && + Entry.hSrcModule == hSrcModule && + !lstrcmpW( Entry.wszSource, pSrcResource ) && + Entry.dwFlags == Flags ) + { + // A match is found. Increment the ref coutn and return the ID3DXEffect object. + *ppEffect = Entry.pEffect; + ( *ppEffect )->AddRef(); + return S_OK; + } + } + + HRESULT hr; + + // No matching entry. Load the resource and create a new entry. + hr = D3DXCreateEffectFromResource( pDevice, hSrcModule, pSrcResource, pDefines, pInclude, Flags, + pPool, ppEffect, ppCompilationErrors ); + if( FAILED( hr ) ) + return hr; + + DXUTCache_Effect NewEntry; + NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE; + NewEntry.hSrcModule = hSrcModule; + wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource ); + NewEntry.dwFlags = Flags; + NewEntry.pEffect = *ppEffect; + NewEntry.pEffect->AddRef(); + + m_EffectCache.Add( NewEntry ); + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Device event callbacks +//-------------------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::OnCreateDevice( IDirect3DDevice9* pd3dDevice ) +{ + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::OnResetDevice( IDirect3DDevice9* pd3dDevice ) +{ + // Call OnResetDevice on all effect and font objects + for( int i = 0; i < m_EffectCache.GetSize(); ++i ) + m_EffectCache[i].pEffect->OnResetDevice(); + for( int i = 0; i < m_FontCache.GetSize(); ++i ) + m_FontCache[i].pFont->OnResetDevice(); + + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::OnLostDevice() +{ + // Call OnLostDevice on all effect and font objects + for( int i = 0; i < m_EffectCache.GetSize(); ++i ) + m_EffectCache[i].pEffect->OnLostDevice(); + for( int i = 0; i < m_FontCache.GetSize(); ++i ) + m_FontCache[i].pFont->OnLostDevice(); + + // Release all the default pool textures + for( int i = m_TextureCache.GetSize() - 1; i >= 0; --i ) + if( m_TextureCache[i].Pool9 == D3DPOOL_DEFAULT ) + { + SAFE_RELEASE( m_TextureCache[i].pTexture9 ); + m_TextureCache.Remove( i ); // Remove the entry + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTResourceCache::OnDestroyDevice() +{ + // Release all resources + for( int i = m_EffectCache.GetSize() - 1; i >= 0; --i ) + { + SAFE_RELEASE( m_EffectCache[i].pEffect ); + m_EffectCache.Remove( i ); + } + for( int i = m_FontCache.GetSize() - 1; i >= 0; --i ) + { + SAFE_RELEASE( m_FontCache[i].pFont ); + m_FontCache.Remove( i ); + } + for( int i = m_TextureCache.GetSize() - 1; i >= 0; --i ) + { + SAFE_RELEASE( m_TextureCache[i].pTexture9 ); + SAFE_RELEASE( m_TextureCache[i].pSRV11 ); + m_TextureCache.Remove( i ); + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Desc: Returns a view matrix for rendering to a face of a cubemap. +//-------------------------------------------------------------------------------------- +D3DXMATRIX WINAPI DXUTGetCubeMapViewMatrix( DWORD dwFace ) +{ + D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); + D3DXVECTOR3 vLookDir; + D3DXVECTOR3 vUpDir; + + switch( dwFace ) + { + case D3DCUBEMAP_FACE_POSITIVE_X: + vLookDir = D3DXVECTOR3( 1.0f, 0.0f, 0.0f ); + vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); + break; + case D3DCUBEMAP_FACE_NEGATIVE_X: + vLookDir = D3DXVECTOR3( -1.0f, 0.0f, 0.0f ); + vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); + break; + case D3DCUBEMAP_FACE_POSITIVE_Y: + vLookDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); + vUpDir = D3DXVECTOR3( 0.0f, 0.0f, -1.0f ); + break; + case D3DCUBEMAP_FACE_NEGATIVE_Y: + vLookDir = D3DXVECTOR3( 0.0f, -1.0f, 0.0f ); + vUpDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + break; + case D3DCUBEMAP_FACE_POSITIVE_Z: + vLookDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); + vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); + break; + case D3DCUBEMAP_FACE_NEGATIVE_Z: + vLookDir = D3DXVECTOR3( 0.0f, 0.0f, -1.0f ); + vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); + break; + } + + // Set the view transform for this cubemap surface + D3DXMATRIXA16 mView; + D3DXMatrixLookAtLH( &mView, &vEyePt, &vLookDir, &vUpDir ); + return mView; +} + + +//-------------------------------------------------------------------------------------- +CDXUTLineManager::CDXUTLineManager() +{ + m_pd3dDevice = NULL; + m_pD3DXLine = NULL; +} + + +//-------------------------------------------------------------------------------------- +CDXUTLineManager::~CDXUTLineManager() +{ + OnDeletedDevice(); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::OnCreatedDevice( IDirect3DDevice9* pd3dDevice ) +{ + m_pd3dDevice = pd3dDevice; + + HRESULT hr; + hr = D3DXCreateLine( m_pd3dDevice, &m_pD3DXLine ); + if( FAILED( hr ) ) + return hr; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::OnResetDevice() +{ + if( m_pD3DXLine ) + m_pD3DXLine->OnResetDevice(); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::OnRender() +{ + HRESULT hr; + if( NULL == m_pD3DXLine ) + return E_INVALIDARG; + + bool bDrawingHasBegun = false; + float fLastWidth = 0.0f; + bool bLastAntiAlias = false; + + for( int i = 0; i < m_LinesList.GetSize(); i++ ) + { + LINE_NODE* pLineNode = m_LinesList.GetAt( i ); + if( pLineNode ) + { + if( !bDrawingHasBegun || + fLastWidth != pLineNode->fWidth || + bLastAntiAlias != pLineNode->bAntiAlias ) + { + if( bDrawingHasBegun ) + { + hr = m_pD3DXLine->End(); + if( FAILED( hr ) ) + return hr; + } + + m_pD3DXLine->SetWidth( pLineNode->fWidth ); + m_pD3DXLine->SetAntialias( pLineNode->bAntiAlias ); + + fLastWidth = pLineNode->fWidth; + bLastAntiAlias = pLineNode->bAntiAlias; + + hr = m_pD3DXLine->Begin(); + if( FAILED( hr ) ) + return hr; + bDrawingHasBegun = true; + } + + hr = m_pD3DXLine->Draw( pLineNode->pVertexList, pLineNode->dwVertexListCount, pLineNode->Color ); + if( FAILED( hr ) ) + return hr; + } + } + + if( bDrawingHasBegun ) + { + hr = m_pD3DXLine->End(); + if( FAILED( hr ) ) + return hr; + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::OnLostDevice() +{ + if( m_pD3DXLine ) + m_pD3DXLine->OnLostDevice(); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::OnDeletedDevice() +{ + RemoveAllLines(); + SAFE_RELEASE( m_pD3DXLine ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::AddLine( int* pnLineID, D3DXVECTOR2* pVertexList, DWORD dwVertexListCount, D3DCOLOR Color, + float fWidth, float fScaleRatio, bool bAntiAlias ) +{ + if( pVertexList == NULL || dwVertexListCount == 0 ) + return E_INVALIDARG; + + LINE_NODE* pLineNode = new LINE_NODE; + if( pLineNode == NULL ) + return E_OUTOFMEMORY; + ZeroMemory( pLineNode, sizeof( LINE_NODE ) ); + + pLineNode->nLineID = m_LinesList.GetSize(); + pLineNode->Color = Color; + pLineNode->fWidth = fWidth; + pLineNode->bAntiAlias = bAntiAlias; + pLineNode->dwVertexListCount = dwVertexListCount; + + if( pnLineID ) + *pnLineID = pLineNode->nLineID; + + pLineNode->pVertexList = new D3DXVECTOR2[dwVertexListCount]; + if( pLineNode->pVertexList == NULL ) + { + delete pLineNode; + return E_OUTOFMEMORY; + } + for( DWORD i = 0; i < dwVertexListCount; i++ ) + { + pLineNode->pVertexList[i] = pVertexList[i] * fScaleRatio; + } + + m_LinesList.Add( pLineNode ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::AddRect( int* pnLineID, RECT rc, D3DCOLOR Color, float fWidth, float fScaleRatio, + bool bAntiAlias ) +{ + if( fWidth > 2.0f ) + { + D3DXVECTOR2 vertexList[8]; + + vertexList[0].x = ( float )rc.left; + vertexList[0].y = ( float )rc.top - ( fWidth / 2.0f ); + + vertexList[1].x = ( float )rc.left; + vertexList[1].y = ( float )rc.bottom + ( fWidth / 2.0f ); + + vertexList[2].x = ( float )rc.left; + vertexList[2].y = ( float )rc.bottom - 0.5f; + + vertexList[3].x = ( float )rc.right; + vertexList[3].y = ( float )rc.bottom - 0.5f; + + vertexList[4].x = ( float )rc.right; + vertexList[4].y = ( float )rc.bottom + ( fWidth / 2.0f ); + + vertexList[5].x = ( float )rc.right; + vertexList[5].y = ( float )rc.top - ( fWidth / 2.0f ); + + vertexList[6].x = ( float )rc.right; + vertexList[6].y = ( float )rc.top; + + vertexList[7].x = ( float )rc.left; + vertexList[7].y = ( float )rc.top; + + return AddLine( pnLineID, vertexList, 8, Color, fWidth, fScaleRatio, bAntiAlias ); + } + else + { + D3DXVECTOR2 vertexList[5]; + vertexList[0].x = ( float )rc.left; + vertexList[0].y = ( float )rc.top; + + vertexList[1].x = ( float )rc.left; + vertexList[1].y = ( float )rc.bottom; + + vertexList[2].x = ( float )rc.right; + vertexList[2].y = ( float )rc.bottom; + + vertexList[3].x = ( float )rc.right; + vertexList[3].y = ( float )rc.top; + + vertexList[4].x = ( float )rc.left; + vertexList[4].y = ( float )rc.top; + + return AddLine( pnLineID, vertexList, 5, Color, fWidth, fScaleRatio, bAntiAlias ); + } +} + + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::RemoveLine( int nLineID ) +{ + for( int i = 0; i < m_LinesList.GetSize(); i++ ) + { + LINE_NODE* pLineNode = m_LinesList.GetAt( i ); + if( pLineNode && pLineNode->nLineID == nLineID ) + { + SAFE_DELETE_ARRAY( pLineNode->pVertexList ); + delete pLineNode; + m_LinesList.SetAt( i, NULL ); + } + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTLineManager::RemoveAllLines() +{ + for( int i = 0; i < m_LinesList.GetSize(); i++ ) + { + LINE_NODE* pLineNode = m_LinesList.GetAt( i ); + if( pLineNode ) + { + SAFE_DELETE_ARRAY( pLineNode->pVertexList ); + delete pLineNode; + } + } + m_LinesList.RemoveAll(); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +CDXUTTextHelper::CDXUTTextHelper( ID3DXFont* pFont9, ID3DXSprite* pSprite9, int nLineHeight ) +{ + Init( pFont9, pSprite9, nLineHeight ); +} + +CDXUTTextHelper::CDXUTTextHelper( ID3D11Device* pd3d11Device, ID3D11DeviceContext* pd3d11DeviceContext, CDXUTDialogResourceManager* pManager, int nLineHeight ) +{ + Init( NULL, NULL, nLineHeight ); + m_pd3d11Device = pd3d11Device; + m_pd3d11DeviceContext = pd3d11DeviceContext; + m_pManager = pManager; +} +CDXUTTextHelper::~CDXUTTextHelper() +{ + +} + +//-------------------------------------------------------------------------------------- +void CDXUTTextHelper::Init( ID3DXFont* pFont9, ID3DXSprite* pSprite9, + int nLineHeight ) +{ + m_pFont9 = pFont9; + m_pSprite9 = pSprite9; + m_clr = D3DXCOLOR( 1, 1, 1, 1 ); + m_pt.x = 0; + m_pt.y = 0; + m_nLineHeight = nLineHeight; + m_pd3d11Device = NULL; + m_pd3d11DeviceContext = NULL; + m_pManager = NULL; + + // Create a blend state if a sprite is passed in +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTTextHelper::DrawFormattedTextLine( const WCHAR* strMsg, ... ) +{ + WCHAR strBuffer[512]; + + va_list args; + va_start( args, strMsg ); + vswprintf_s( strBuffer, 512, strMsg, args ); + strBuffer[511] = L'\0'; + va_end( args ); + + return DrawTextLine( strBuffer ); +} + + +//-------------------------------------------------------------------------------------- +HRESULT CDXUTTextHelper::DrawTextLine( const WCHAR* strMsg ) +{ + if( NULL == m_pFont9 && NULL == m_pd3d11DeviceContext ) + return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG ); + + HRESULT hr = S_OK; + RECT rc; + SetRect( &rc, m_pt.x, m_pt.y, 0, 0 ); + if( m_pFont9 ) + hr = m_pFont9->DrawText( m_pSprite9, strMsg, -1, &rc, DT_NOCLIP, m_clr ); + else if( m_pd3d11DeviceContext ) + DrawText11DXUT( m_pd3d11Device, m_pd3d11DeviceContext, strMsg, rc, m_clr, + (float)m_pManager->m_nBackBufferWidth, (float)m_pManager->m_nBackBufferHeight, false ); + + if( FAILED( hr ) ) + return DXTRACE_ERR_MSGBOX( L"DrawText", hr ); + + m_pt.y += m_nLineHeight; + + return S_OK; +} + + +HRESULT CDXUTTextHelper::DrawFormattedTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg, ... ) +{ + WCHAR strBuffer[512]; + + va_list args; + va_start( args, strMsg ); + vswprintf_s( strBuffer, 512, strMsg, args ); + strBuffer[511] = L'\0'; + va_end( args ); + + return DrawTextLine( rc, dwFlags, strBuffer ); +} + + +HRESULT CDXUTTextHelper::DrawTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg ) +{ + if( NULL == m_pFont9 && NULL == m_pd3d11DeviceContext ) + return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG ); + + HRESULT hr = S_OK; + if( m_pFont9 ) + hr = m_pFont9->DrawText( m_pSprite9, strMsg, -1, &rc, dwFlags, m_clr ); + else if( m_pd3d11DeviceContext ) + DrawText11DXUT( m_pd3d11Device, m_pd3d11DeviceContext, strMsg, rc, m_clr, + (float)m_pManager->m_nBackBufferWidth, (float)m_pManager->m_nBackBufferHeight, false ); + + if( FAILED( hr ) ) + return DXTRACE_ERR_MSGBOX( L"DrawText", hr ); + + m_pt.y += m_nLineHeight; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTextHelper::Begin() +{ + if( m_pSprite9 ) + m_pSprite9->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE ); + + if( m_pd3d11DeviceContext ) + { + m_pManager->StoreD3D11State( m_pd3d11DeviceContext ); + m_pManager->ApplyRenderUI11( m_pd3d11DeviceContext ); + } + + +} +void CDXUTTextHelper::End() +{ + if( m_pSprite9 ) + m_pSprite9->End(); + + if( m_pd3d11DeviceContext ) + { + m_pManager->RestoreD3D11State( m_pd3d11DeviceContext ); + } +} diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.h b/Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.h new file mode 100644 index 0000000..ac91782 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.h @@ -0,0 +1,368 @@ +//-------------------------------------------------------------------------------------- +// File: SDKMisc.h +// +// Various helper functionality that is shared between SDK samples +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#pragma once +#ifndef SDKMISC_H +#define SDKMISC_H + + +//----------------------------------------------------------------------------- +// Resource cache for textures, fonts, meshs, and effects. +// Use DXUTGetGlobalResourceCache() to access the global cache +//----------------------------------------------------------------------------- + +enum DXUTCACHE_SOURCELOCATION +{ + DXUTCACHE_LOCATION_FILE, + DXUTCACHE_LOCATION_RESOURCE +}; + +struct DXUTCache_Texture +{ + DXUTCACHE_SOURCELOCATION Location; + WCHAR wszSource[MAX_PATH]; + HMODULE hSrcModule; + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + UINT MiscFlags; + union + { + DWORD Usage9; + D3D11_USAGE Usage11; + }; + union + { + D3DFORMAT Format9; + DXGI_FORMAT Format; + }; + union + { + D3DPOOL Pool9; + UINT CpuAccessFlags; + }; + union + { + D3DRESOURCETYPE Type9; + UINT BindFlags; + }; + IDirect3DBaseTexture9* pTexture9; + ID3D11ShaderResourceView* pSRV11; + + DXUTCache_Texture() + { + pTexture9 = NULL; + pSRV11 = NULL; + } +}; + +struct DXUTCache_Font : public D3DXFONT_DESC +{ + ID3DXFont* pFont; +}; + +struct DXUTCache_Effect +{ + DXUTCACHE_SOURCELOCATION Location; + WCHAR wszSource[MAX_PATH]; + HMODULE hSrcModule; + DWORD dwFlags; + ID3DXEffect* pEffect; +}; + + +class CDXUTResourceCache +{ +public: + ~CDXUTResourceCache(); + + HRESULT CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture ); + HRESULT CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture ); + HRESULT CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCTSTR pSrcFile, + ID3D11ShaderResourceView** ppOutputRV, bool bSRGB=false ); + HRESULT CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCSTR pSrcFile, + ID3D11ShaderResourceView** ppOutputRV, bool bSRGB=false ); + HRESULT CreateTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width, + UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format, + D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture ); + HRESULT CreateTextureFromFileEx( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, LPCTSTR pSrcFile, + D3DX11_IMAGE_LOAD_INFO* pLoadInfo, ID3DX11ThreadPump* pPump, + ID3D11ShaderResourceView** ppOutputRV, bool bSRGB ); + HRESULT CreateTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, LPDIRECT3DTEXTURE9* ppTexture ); + HRESULT CreateTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, UINT Width, UINT Height, UINT MipLevels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE9* ppTexture ); + HRESULT CreateCubeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ); + HRESULT CreateCubeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Size, + UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ); + HRESULT CreateCubeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ); + HRESULT CreateCubeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, UINT Size, UINT MipLevels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture ); + HRESULT CreateVolumeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture ); + HRESULT CreateVolumeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width, + UINT Height, UINT Depth, UINT MipLevels, DWORD Usage, + D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppTexture ); + HRESULT CreateVolumeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture ); + HRESULT CreateVolumeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, UINT Width, UINT Height, + UINT Depth, UINT MipLevels, DWORD Usage, + D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, + DWORD MipFilter, D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture ); + HRESULT CreateFont( LPDIRECT3DDEVICE9 pDevice, UINT Height, UINT Width, UINT Weight, + UINT MipLevels, BOOL Italic, DWORD CharSet, DWORD OutputPrecision, + DWORD Quality, DWORD PitchAndFamily, LPCTSTR pFacename, LPD3DXFONT* ppFont ); + HRESULT CreateFontIndirect( LPDIRECT3DDEVICE9 pDevice, CONST D3DXFONT_DESC *pDesc, LPD3DXFONT *ppFont ); + HRESULT CreateEffectFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, + const D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors ); + HRESULT CreateEffectFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, + LPCTSTR pSrcResource, const D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, LPD3DXBUFFER* ppCompilationErrors ); + +public: + HRESULT OnCreateDevice( IDirect3DDevice9* pd3dDevice ); + HRESULT OnResetDevice( IDirect3DDevice9* pd3dDevice ); + HRESULT OnLostDevice(); + HRESULT OnDestroyDevice(); + +protected: + friend CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache(); + friend HRESULT WINAPI DXUTInitialize3DEnvironment(); + friend HRESULT WINAPI DXUTReset3DEnvironment(); + friend void WINAPI DXUTCleanup3DEnvironment( bool bReleaseSettings ); + + CDXUTResourceCache() + { + } + + CGrowableArray m_TextureCache; + CGrowableArray m_EffectCache; + CGrowableArray m_FontCache; +}; + +CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache(); + + +//-------------------------------------------------------------------------------------- +// Manages the insertion point when drawing text +//-------------------------------------------------------------------------------------- +class CDXUTDialogResourceManager; +class CDXUTTextHelper +{ +public: + CDXUTTextHelper( ID3DXFont* pFont9 = NULL, ID3DXSprite* pSprite9 = NULL, + int nLineHeight = 15 ); + CDXUTTextHelper( ID3D11Device* pd3d11Device, ID3D11DeviceContext* pd3dDeviceContext, CDXUTDialogResourceManager* pManager, int nLineHeight ); + ~CDXUTTextHelper(); + + void Init( ID3DXFont* pFont9 = NULL, ID3DXSprite* pSprite9 = NULL, + int nLineHeight = 15 ); + + void SetInsertionPos( int x, int y ) + { + m_pt.x = x; m_pt.y = y; + } + void SetForegroundColor( D3DXCOLOR clr ) + { + m_clr = clr; + } + + void Begin(); + HRESULT DrawFormattedTextLine( const WCHAR* strMsg, ... ); + HRESULT DrawTextLine( const WCHAR* strMsg ); + HRESULT DrawFormattedTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg, ... ); + HRESULT DrawTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg ); + void End(); + +protected: + ID3DXFont* m_pFont9; + ID3DXSprite* m_pSprite9; + D3DXCOLOR m_clr; + POINT m_pt; + int m_nLineHeight; + + // D3D11 font + ID3D11Device* m_pd3d11Device; + ID3D11DeviceContext* m_pd3d11DeviceContext; + CDXUTDialogResourceManager* m_pManager; +}; + + +//-------------------------------------------------------------------------------------- +// Manages a persistent list of lines and draws them using ID3DXLine +//-------------------------------------------------------------------------------------- +class CDXUTLineManager +{ +public: + CDXUTLineManager(); + ~CDXUTLineManager(); + + HRESULT OnCreatedDevice( IDirect3DDevice9* pd3dDevice ); + HRESULT OnResetDevice(); + HRESULT OnRender(); + HRESULT OnLostDevice(); + HRESULT OnDeletedDevice(); + + HRESULT AddLine( int* pnLineID, D3DXVECTOR2* pVertexList, DWORD dwVertexListCount, D3DCOLOR Color, float fWidth, + float fScaleRatio, bool bAntiAlias ); + HRESULT AddRect( int* pnLineID, RECT rc, D3DCOLOR Color, float fWidth, float fScaleRatio, bool bAntiAlias ); + HRESULT RemoveLine( int nLineID ); + HRESULT RemoveAllLines(); + +protected: + struct LINE_NODE + { + int nLineID; + D3DCOLOR Color; + float fWidth; + bool bAntiAlias; + float fScaleRatio; + D3DXVECTOR2* pVertexList; + DWORD dwVertexListCount; + }; + + CGrowableArray m_LinesList; + IDirect3DDevice9* m_pd3dDevice; + ID3DXLine* m_pD3DXLine; +}; + + +//-------------------------------------------------------------------------------------- +// Shared code for samples to ask user if they want to use a REF device or quit +//-------------------------------------------------------------------------------------- +void WINAPI DXUTDisplaySwitchingToREFWarning( DXUTDeviceVersion ver ); + +//-------------------------------------------------------------------------------------- +// Tries to finds a media file by searching in common locations +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTFindDXSDKMediaFileCch( __in_ecount(cchDest) WCHAR* strDestPath, + int cchDest, + __in LPCWSTR strFilename ); +HRESULT WINAPI DXUTSetMediaSearchPath( LPCWSTR strPath ); +LPCWSTR WINAPI DXUTGetMediaSearchPath(); + + +//-------------------------------------------------------------------------------------- +// Returns a view matrix for rendering to a face of a cubemap. +//-------------------------------------------------------------------------------------- +D3DXMATRIX WINAPI DXUTGetCubeMapViewMatrix( DWORD dwFace ); + + +//-------------------------------------------------------------------------------------- +// Simple helper stack class +//-------------------------------------------------------------------------------------- +template class CDXUTStack +{ +private: + UINT m_MemorySize; + UINT m_NumElements; + T* m_pData; + + bool EnsureStackSize( UINT64 iElements ) + { + if( m_MemorySize > iElements ) + return true; + + T* pTemp = new T[ ( size_t )( iElements * 2 + 256 ) ]; + if( !pTemp ) + return false; + + if( m_NumElements ) + { + CopyMemory( pTemp, m_pData, ( size_t )( m_NumElements * sizeof( T ) ) ); + } + + if( m_pData ) delete []m_pData; + m_pData = pTemp; + return true; + } + +public: + CDXUTStack() + { + m_pData = NULL; m_NumElements = 0; m_MemorySize = 0; + } + ~CDXUTStack() + { + if( m_pData ) delete []m_pData; + } + + UINT GetCount() + { + return m_NumElements; + } + T GetAt( UINT i ) + { + return m_pData[i]; + } + T GetTop() + { + if( m_NumElements < 1 ) + return NULL; + + return m_pData[ m_NumElements - 1 ]; + } + + T GetRelative( INT i ) + { + INT64 iVal = m_NumElements - 1 + i; + if( iVal < 0 ) + return NULL; + return m_pData[ iVal ]; + } + + bool Push( T pElem ) + { + if( !EnsureStackSize( m_NumElements + 1 ) ) + return false; + + m_pData[m_NumElements] = pElem; + m_NumElements++; + + return true; + } + + T Pop() + { + if( m_NumElements < 1 ) + return NULL; + + m_NumElements --; + return m_pData[m_NumElements]; + } +}; + + +#endif diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKsound.cpp b/Demos/DX11ClothDemo/DXUT/Optional/SDKsound.cpp new file mode 100644 index 0000000..a1256c7 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKsound.cpp @@ -0,0 +1,1053 @@ +//----------------------------------------------------------------------------- +// File: DXUTsound.cpp +// +// Desc: DirectSound framework classes for playing wav files in DirectSound +// buffers. Feel free to use these classes as a starting point for adding +// extra functionality. +// +// Copyright (c) Microsoft Corp. All rights reserved. +//----------------------------------------------------------------------------- +#define STRICT +#include "DXUT.h" +#include +#include +#include "SDKsound.h" +#include "SDKwavefile.h" +#undef min // use __min instead +#undef max // use __max instead + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::CSoundManager() +// Desc: Constructs the class +//----------------------------------------------------------------------------- +CSoundManager::CSoundManager() +{ + m_pDS = NULL; +} + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::~CSoundManager() +// Desc: Destroys the class +//----------------------------------------------------------------------------- +CSoundManager::~CSoundManager() +{ + SAFE_RELEASE( m_pDS ); +} + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::Initialize() +// Desc: Initializes the IDirectSound object and also sets the primary buffer +// format. This function must be called before any others. +//----------------------------------------------------------------------------- +HRESULT CSoundManager::Initialize( HWND hWnd, + DWORD dwCoopLevel ) +{ + HRESULT hr; + + SAFE_RELEASE( m_pDS ); + + // Create IDirectSound using the primary sound device + if( FAILED( hr = DirectSoundCreate8( NULL, &m_pDS, NULL ) ) ) + return DXUT_ERR( L"DirectSoundCreate8", hr ); + + // Set DirectSound coop level + if( FAILED( hr = m_pDS->SetCooperativeLevel( hWnd, dwCoopLevel ) ) ) + return DXUT_ERR( L"SetCooperativeLevel", hr ); + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::SetPrimaryBufferFormat() +// Desc: Set primary buffer to a specified format +// !WARNING! - Setting the primary buffer format and then using this +// same DirectSound object for DirectMusic messes up +// DirectMusic! +// For example, to set the primary buffer format to 22kHz stereo, 16-bit +// then: dwPrimaryChannels = 2 +// dwPrimaryFreq = 22050, +// dwPrimaryBitRate = 16 +//----------------------------------------------------------------------------- +HRESULT CSoundManager::SetPrimaryBufferFormat( DWORD dwPrimaryChannels, + DWORD dwPrimaryFreq, + DWORD dwPrimaryBitRate ) +{ + HRESULT hr; + LPDIRECTSOUNDBUFFER pDSBPrimary = NULL; + + if( m_pDS == NULL ) + return CO_E_NOTINITIALIZED; + + // Get the primary buffer + DSBUFFERDESC dsbd; + ZeroMemory( &dsbd, sizeof( DSBUFFERDESC ) ); + dsbd.dwSize = sizeof( DSBUFFERDESC ); + dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; + dsbd.dwBufferBytes = 0; + dsbd.lpwfxFormat = NULL; + + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) ) + return DXUT_ERR( L"CreateSoundBuffer", hr ); + + WAVEFORMATEX wfx; + ZeroMemory( &wfx, sizeof( WAVEFORMATEX ) ); + wfx.wFormatTag = ( WORD )WAVE_FORMAT_PCM; + wfx.nChannels = ( WORD )dwPrimaryChannels; + wfx.nSamplesPerSec = ( DWORD )dwPrimaryFreq; + wfx.wBitsPerSample = ( WORD )dwPrimaryBitRate; + wfx.nBlockAlign = ( WORD )( wfx.wBitsPerSample / 8 * wfx.nChannels ); + wfx.nAvgBytesPerSec = ( DWORD )( wfx.nSamplesPerSec * wfx.nBlockAlign ); + + if( FAILED( hr = pDSBPrimary->SetFormat( &wfx ) ) ) + return DXUT_ERR( L"SetFormat", hr ); + + SAFE_RELEASE( pDSBPrimary ); + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::Get3DListenerInterface() +// Desc: Returns the 3D listener interface associated with primary buffer. +//----------------------------------------------------------------------------- +HRESULT CSoundManager::Get3DListenerInterface( LPDIRECTSOUND3DLISTENER* ppDSListener ) +{ + HRESULT hr; + DSBUFFERDESC dsbdesc; + LPDIRECTSOUNDBUFFER pDSBPrimary = NULL; + + if( ppDSListener == NULL ) + return E_INVALIDARG; + if( m_pDS == NULL ) + return CO_E_NOTINITIALIZED; + + *ppDSListener = NULL; + + // Obtain primary buffer, asking it for 3D control + ZeroMemory( &dsbdesc, sizeof( DSBUFFERDESC ) ); + dsbdesc.dwSize = sizeof( DSBUFFERDESC ); + dsbdesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER; + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbdesc, &pDSBPrimary, NULL ) ) ) + return DXUT_ERR( L"CreateSoundBuffer", hr ); + + if( FAILED( hr = pDSBPrimary->QueryInterface( IID_IDirectSound3DListener, + ( VOID** )ppDSListener ) ) ) + { + SAFE_RELEASE( pDSBPrimary ); + return DXUT_ERR( L"QueryInterface", hr ); + } + + // Release the primary buffer, since it is not need anymore + SAFE_RELEASE( pDSBPrimary ); + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::Create() +// Desc: +//----------------------------------------------------------------------------- +HRESULT CSoundManager::Create( CSound** ppSound, + LPWSTR strWaveFileName, + DWORD dwCreationFlags, + GUID guid3DAlgorithm, + DWORD dwNumBuffers ) +{ + HRESULT hr; + HRESULT hrRet = S_OK; + DWORD i; + LPDIRECTSOUNDBUFFER* apDSBuffer = NULL; + DWORD dwDSBufferSize = NULL; + CWaveFile* pWaveFile = NULL; + + if( m_pDS == NULL ) + return CO_E_NOTINITIALIZED; + if( strWaveFileName == NULL || ppSound == NULL || dwNumBuffers < 1 ) + return E_INVALIDARG; + + apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers]; + if( apDSBuffer == NULL ) + { + hr = E_OUTOFMEMORY; + goto LFail; + } + + pWaveFile = new CWaveFile(); + if( pWaveFile == NULL ) + { + hr = E_OUTOFMEMORY; + goto LFail; + } + + pWaveFile->Open( strWaveFileName, NULL, WAVEFILE_READ ); + + if( pWaveFile->GetSize() == 0 ) + { + // Wave is blank, so don't create it. + hr = E_FAIL; + goto LFail; + } + + // Make the DirectSound buffer the same size as the wav file + dwDSBufferSize = pWaveFile->GetSize(); + + // Create the direct sound buffer, and only request the flags needed + // since each requires some overhead and limits if the buffer can + // be hardware accelerated + DSBUFFERDESC dsbd; + ZeroMemory( &dsbd, sizeof( DSBUFFERDESC ) ); + dsbd.dwSize = sizeof( DSBUFFERDESC ); + dsbd.dwFlags = dwCreationFlags; + dsbd.dwBufferBytes = dwDSBufferSize; + dsbd.guid3DAlgorithm = guid3DAlgorithm; + dsbd.lpwfxFormat = pWaveFile->m_pwfx; + + // DirectSound is only guarenteed to play PCM data. Other + // formats may or may not work depending the sound card driver. + hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[0], NULL ); + + // Be sure to return this error code if it occurs so the + // callers knows this happened. + if( hr == DS_NO_VIRTUALIZATION ) + hrRet = DS_NO_VIRTUALIZATION; + + if( FAILED( hr ) ) + { + // DSERR_BUFFERTOOSMALL will be returned if the buffer is + // less than DSBSIZE_FX_MIN and the buffer is created + // with DSBCAPS_CTRLFX. + + // It might also fail if hardware buffer mixing was requested + // on a device that doesn't support it. + DXUT_ERR( L"CreateSoundBuffer", hr ); + + goto LFail; + } + + // Default to use DuplicateSoundBuffer() when created extra buffers since always + // create a buffer that uses the same memory however DuplicateSoundBuffer() will fail if + // DSBCAPS_CTRLFX is used, so use CreateSoundBuffer() instead in this case. + if( ( dwCreationFlags & DSBCAPS_CTRLFX ) == 0 ) + { + for( i = 1; i < dwNumBuffers; i++ ) + { + if( FAILED( hr = m_pDS->DuplicateSoundBuffer( apDSBuffer[0], &apDSBuffer[i] ) ) ) + { + DXUT_ERR( L"DuplicateSoundBuffer", hr ); + goto LFail; + } + } + } + else + { + for( i = 1; i < dwNumBuffers; i++ ) + { + hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[i], NULL ); + if( FAILED( hr ) ) + { + DXUT_ERR( L"CreateSoundBuffer", hr ); + goto LFail; + } + } + } + + // Create the sound + *ppSound = new CSound( apDSBuffer, dwDSBufferSize, dwNumBuffers, pWaveFile, dwCreationFlags ); + + SAFE_DELETE_ARRAY( apDSBuffer ); + return hrRet; + +LFail: + // Cleanup + SAFE_DELETE( pWaveFile ); + SAFE_DELETE_ARRAY( apDSBuffer ); + return hr; +} + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::CreateFromMemory() +// Desc: +//----------------------------------------------------------------------------- +HRESULT CSoundManager::CreateFromMemory( CSound** ppSound, + BYTE* pbData, + ULONG ulDataSize, + LPWAVEFORMATEX pwfx, + DWORD dwCreationFlags, + GUID guid3DAlgorithm, + DWORD dwNumBuffers ) +{ + HRESULT hr; + DWORD i; + LPDIRECTSOUNDBUFFER* apDSBuffer = NULL; + DWORD dwDSBufferSize = NULL; + CWaveFile* pWaveFile = NULL; + + if( m_pDS == NULL ) + return CO_E_NOTINITIALIZED; + if( pbData == NULL || ppSound == NULL || dwNumBuffers < 1 ) + return E_INVALIDARG; + + apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers]; + if( apDSBuffer == NULL ) + { + hr = E_OUTOFMEMORY; + goto LFail; + } + + pWaveFile = new CWaveFile(); + if( pWaveFile == NULL ) + { + hr = E_OUTOFMEMORY; + goto LFail; + } + + pWaveFile->OpenFromMemory( pbData, ulDataSize, pwfx, WAVEFILE_READ ); + + + // Make the DirectSound buffer the same size as the wav file + dwDSBufferSize = ulDataSize; + + // Create the direct sound buffer, and only request the flags needed + // since each requires some overhead and limits if the buffer can + // be hardware accelerated + DSBUFFERDESC dsbd; + ZeroMemory( &dsbd, sizeof( DSBUFFERDESC ) ); + dsbd.dwSize = sizeof( DSBUFFERDESC ); + dsbd.dwFlags = dwCreationFlags; + dsbd.dwBufferBytes = dwDSBufferSize; + dsbd.guid3DAlgorithm = guid3DAlgorithm; + dsbd.lpwfxFormat = pwfx; + + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[0], NULL ) ) ) + { + DXUT_ERR( L"CreateSoundBuffer", hr ); + goto LFail; + } + + // Default to use DuplicateSoundBuffer() when created extra buffers since always + // create a buffer that uses the same memory however DuplicateSoundBuffer() will fail if + // DSBCAPS_CTRLFX is used, so use CreateSoundBuffer() instead in this case. + if( ( dwCreationFlags & DSBCAPS_CTRLFX ) == 0 ) + { + for( i = 1; i < dwNumBuffers; i++ ) + { + if( FAILED( hr = m_pDS->DuplicateSoundBuffer( apDSBuffer[0], &apDSBuffer[i] ) ) ) + { + DXUT_ERR( L"DuplicateSoundBuffer", hr ); + goto LFail; + } + } + } + else + { + for( i = 1; i < dwNumBuffers; i++ ) + { + hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer[i], NULL ); + if( FAILED( hr ) ) + { + DXUT_ERR( L"CreateSoundBuffer", hr ); + goto LFail; + } + } + } + + // Create the sound + *ppSound = new CSound( apDSBuffer, dwDSBufferSize, dwNumBuffers, pWaveFile, dwCreationFlags ); + + SAFE_DELETE_ARRAY( apDSBuffer ); + return S_OK; + +LFail: + // Cleanup + + SAFE_DELETE_ARRAY( apDSBuffer ); + return hr; +} + + +//----------------------------------------------------------------------------- +// Name: CSoundManager::CreateStreaming() +// Desc: +//----------------------------------------------------------------------------- +HRESULT CSoundManager::CreateStreaming( CStreamingSound** ppStreamingSound, + LPWSTR strWaveFileName, + DWORD dwCreationFlags, + GUID guid3DAlgorithm, + DWORD dwNotifyCount, + DWORD dwNotifySize, + HANDLE hNotifyEvent ) +{ + HRESULT hr; + + if( m_pDS == NULL ) + return CO_E_NOTINITIALIZED; + if( strWaveFileName == NULL || ppStreamingSound == NULL || hNotifyEvent == NULL ) + return E_INVALIDARG; + + LPDIRECTSOUNDBUFFER pDSBuffer = NULL; + DWORD dwDSBufferSize = NULL; + CWaveFile* pWaveFile = NULL; + DSBPOSITIONNOTIFY* aPosNotify = NULL; + LPDIRECTSOUNDNOTIFY pDSNotify = NULL; + + pWaveFile = new CWaveFile(); + if( pWaveFile == NULL ) + return E_OUTOFMEMORY; + pWaveFile->Open( strWaveFileName, NULL, WAVEFILE_READ ); + + // Figure out how big the DirectSound buffer should be + dwDSBufferSize = dwNotifySize * dwNotifyCount; + + // Set up the direct sound buffer. Request the NOTIFY flag, so + // that we are notified as the sound buffer plays. Note, that using this flag + // may limit the amount of hardware acceleration that can occur. + DSBUFFERDESC dsbd; + ZeroMemory( &dsbd, sizeof( DSBUFFERDESC ) ); + dsbd.dwSize = sizeof( DSBUFFERDESC ); + dsbd.dwFlags = dwCreationFlags | + DSBCAPS_CTRLPOSITIONNOTIFY | + DSBCAPS_GETCURRENTPOSITION2; + dsbd.dwBufferBytes = dwDSBufferSize; + dsbd.guid3DAlgorithm = guid3DAlgorithm; + dsbd.lpwfxFormat = pWaveFile->m_pwfx; + + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBuffer, NULL ) ) ) + { + // If wave format isn't then it will return + // either DSERR_BADFORMAT or E_INVALIDARG + if( hr == DSERR_BADFORMAT || hr == E_INVALIDARG ) + return DXUT_ERR( L"CreateSoundBuffer", hr ); + + return DXUT_ERR( L"CreateSoundBuffer", hr ); + } + + // Create the notification events, so that we know when to fill + // the buffer as the sound plays. + if( FAILED( hr = pDSBuffer->QueryInterface( IID_IDirectSoundNotify, + ( VOID** )&pDSNotify ) ) ) + { + SAFE_DELETE_ARRAY( aPosNotify ); + return DXUT_ERR( L"QueryInterface", hr ); + } + + aPosNotify = new DSBPOSITIONNOTIFY[ dwNotifyCount ]; + if( aPosNotify == NULL ) + return E_OUTOFMEMORY; + + for( DWORD i = 0; i < dwNotifyCount; i++ ) + { + aPosNotify[i].dwOffset = ( dwNotifySize * i ) + dwNotifySize - 1; + aPosNotify[i].hEventNotify = hNotifyEvent; + } + + // Tell DirectSound when to notify us. The notification will come in the from + // of signaled events that are handled in WinMain() + if( FAILED( hr = pDSNotify->SetNotificationPositions( dwNotifyCount, + aPosNotify ) ) ) + { + SAFE_RELEASE( pDSNotify ); + SAFE_DELETE_ARRAY( aPosNotify ); + return DXUT_ERR( L"SetNotificationPositions", hr ); + } + + SAFE_RELEASE( pDSNotify ); + SAFE_DELETE_ARRAY( aPosNotify ); + + // Create the sound + *ppStreamingSound = new CStreamingSound( pDSBuffer, dwDSBufferSize, pWaveFile, dwNotifySize ); + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CSound::CSound() +// Desc: Constructs the class +//----------------------------------------------------------------------------- +CSound::CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, + DWORD dwNumBuffers, CWaveFile* pWaveFile, DWORD dwCreationFlags ) +{ + DWORD i; + + if( dwNumBuffers <= 0 ) + return; + + m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers]; + if( NULL != m_apDSBuffer ) + { + for( i = 0; i < dwNumBuffers; i++ ) + m_apDSBuffer[i] = apDSBuffer[i]; + + m_dwDSBufferSize = dwDSBufferSize; + m_dwNumBuffers = dwNumBuffers; + m_pWaveFile = pWaveFile; + m_dwCreationFlags = dwCreationFlags; + + FillBufferWithSound( m_apDSBuffer[0], FALSE ); + } +} + + +//----------------------------------------------------------------------------- +// Name: CSound::~CSound() +// Desc: Destroys the class +//----------------------------------------------------------------------------- +CSound::~CSound() +{ + for( DWORD i = 0; i < m_dwNumBuffers; i++ ) + { + SAFE_RELEASE( m_apDSBuffer[i] ); + } + + SAFE_DELETE_ARRAY( m_apDSBuffer ); + SAFE_DELETE( m_pWaveFile ); +} + + +//----------------------------------------------------------------------------- +// Name: CSound::FillBufferWithSound() +// Desc: Fills a DirectSound buffer with a sound file +//----------------------------------------------------------------------------- +HRESULT CSound::FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, BOOL bRepeatWavIfBufferLarger ) +{ + HRESULT hr; + VOID* pDSLockedBuffer = NULL; // Pointer to locked buffer memory + DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer + DWORD dwWavDataRead = 0; // Amount of data read from the wav file + + if( pDSB == NULL ) + return CO_E_NOTINITIALIZED; + + // Make sure we have focus, and we didn't just switch in from + // an app which had a DirectSound device + if( FAILED( hr = RestoreBuffer( pDSB, NULL ) ) ) + return DXUT_ERR( L"RestoreBuffer", hr ); + + // Lock the buffer down + if( FAILED( hr = pDSB->Lock( 0, m_dwDSBufferSize, + &pDSLockedBuffer, &dwDSLockedBufferSize, + NULL, NULL, 0L ) ) ) + return DXUT_ERR( L"Lock", hr ); + + // Reset the wave file to the beginning + m_pWaveFile->ResetFile(); + + if( FAILED( hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer, + dwDSLockedBufferSize, + &dwWavDataRead ) ) ) + return DXUT_ERR( L"Read", hr ); + + if( dwWavDataRead == 0 ) + { + // Wav is blank, so just fill with silence + FillMemory( ( BYTE* )pDSLockedBuffer, + dwDSLockedBufferSize, + ( BYTE )( m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) ); + } + else if( dwWavDataRead < dwDSLockedBufferSize ) + { + // If the wav file was smaller than the DirectSound buffer, + // we need to fill the remainder of the buffer with data + if( bRepeatWavIfBufferLarger ) + { + // Reset the file and fill the buffer with wav data + DWORD dwReadSoFar = dwWavDataRead; // From previous call above. + while( dwReadSoFar < dwDSLockedBufferSize ) + { + // This will keep reading in until the buffer is full + // for very short files + if( FAILED( hr = m_pWaveFile->ResetFile() ) ) + return DXUT_ERR( L"ResetFile", hr ); + + hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer + dwReadSoFar, + dwDSLockedBufferSize - dwReadSoFar, + &dwWavDataRead ); + if( FAILED( hr ) ) + return DXUT_ERR( L"Read", hr ); + + dwReadSoFar += dwWavDataRead; + } + } + else + { + // Don't repeat the wav file, just fill in silence + FillMemory( ( BYTE* )pDSLockedBuffer + dwWavDataRead, + dwDSLockedBufferSize - dwWavDataRead, + ( BYTE )( m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) ); + } + } + + // Unlock the buffer, we don't need it anymore. + pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 ); + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CSound::RestoreBuffer() +// Desc: Restores the lost buffer. *pbWasRestored returns TRUE if the buffer was +// restored. It can also NULL if the information is not needed. +//----------------------------------------------------------------------------- +HRESULT CSound::RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, BOOL* pbWasRestored ) +{ + HRESULT hr; + + if( pDSB == NULL ) + return CO_E_NOTINITIALIZED; + if( pbWasRestored ) + *pbWasRestored = FALSE; + + DWORD dwStatus; + if( FAILED( hr = pDSB->GetStatus( &dwStatus ) ) ) + return DXUT_ERR( L"GetStatus", hr ); + + if( dwStatus & DSBSTATUS_BUFFERLOST ) + { + // Since the app could have just been activated, then + // DirectSound may not be giving us control yet, so + // the restoring the buffer may fail. + // If it does, sleep until DirectSound gives us control. + do + { + hr = pDSB->Restore(); + if( hr == DSERR_BUFFERLOST ) + Sleep( 10 ); + } while( ( hr = pDSB->Restore() ) == DSERR_BUFFERLOST ); + + if( pbWasRestored != NULL ) + *pbWasRestored = TRUE; + + return S_OK; + } + else + { + return S_FALSE; + } +} + + +//----------------------------------------------------------------------------- +// Name: CSound::GetFreeBuffer() +// Desc: Finding the first buffer that is not playing and return a pointer to +// it, or if all are playing return a pointer to a randomly selected buffer. +//----------------------------------------------------------------------------- +LPDIRECTSOUNDBUFFER CSound::GetFreeBuffer() +{ + if( m_apDSBuffer == NULL ) + return FALSE; + + DWORD i; + for( i = 0; i < m_dwNumBuffers; i++ ) + { + if( m_apDSBuffer[i] ) + { + DWORD dwStatus = 0; + m_apDSBuffer[i]->GetStatus( &dwStatus ); + if( ( dwStatus & DSBSTATUS_PLAYING ) == 0 ) + break; + } + } + + if( i != m_dwNumBuffers ) + return m_apDSBuffer[ i ]; + else + return m_apDSBuffer[ rand() % m_dwNumBuffers ]; +} + + +//----------------------------------------------------------------------------- +// Name: CSound::GetBuffer() +// Desc: +//----------------------------------------------------------------------------- +LPDIRECTSOUNDBUFFER CSound::GetBuffer( DWORD dwIndex ) +{ + if( m_apDSBuffer == NULL ) + return NULL; + if( dwIndex >= m_dwNumBuffers ) + return NULL; + + return m_apDSBuffer[dwIndex]; +} + + +//----------------------------------------------------------------------------- +// Name: CSound::Get3DBufferInterface() +// Desc: +//----------------------------------------------------------------------------- +HRESULT CSound::Get3DBufferInterface( DWORD dwIndex, LPDIRECTSOUND3DBUFFER* ppDS3DBuffer ) +{ + if( m_apDSBuffer == NULL ) + return CO_E_NOTINITIALIZED; + if( dwIndex >= m_dwNumBuffers ) + return E_INVALIDARG; + + *ppDS3DBuffer = NULL; + + return m_apDSBuffer[dwIndex]->QueryInterface( IID_IDirectSound3DBuffer, + ( VOID** )ppDS3DBuffer ); +} + + +//----------------------------------------------------------------------------- +// Name: CSound::Play() +// Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING +// in the dwFlags to loop the sound +//----------------------------------------------------------------------------- +HRESULT CSound::Play( DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, LONG lPan ) +{ + HRESULT hr; + BOOL bRestored; + + if( m_apDSBuffer == NULL ) + return CO_E_NOTINITIALIZED; + + LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer(); + + if( pDSB == NULL ) + return DXUT_ERR( L"GetFreeBuffer", E_FAIL ); + + // Restore the buffer if it was lost + if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) ) + return DXUT_ERR( L"RestoreBuffer", hr ); + + if( bRestored ) + { + // The buffer was restored, so we need to fill it with new data + if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) ) + return DXUT_ERR( L"FillBufferWithSound", hr ); + } + + if( m_dwCreationFlags & DSBCAPS_CTRLVOLUME ) + { + pDSB->SetVolume( lVolume ); + } + + if( lFrequency != -1 && + ( m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY ) ) + { + pDSB->SetFrequency( lFrequency ); + } + + if( m_dwCreationFlags & DSBCAPS_CTRLPAN ) + { + pDSB->SetPan( lPan ); + } + + return pDSB->Play( 0, dwPriority, dwFlags ); +} + + +//----------------------------------------------------------------------------- +// Name: CSound::Play3D() +// Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING +// in the dwFlags to loop the sound +//----------------------------------------------------------------------------- +HRESULT CSound::Play3D( LPDS3DBUFFER p3DBuffer, DWORD dwPriority, DWORD dwFlags, LONG lFrequency ) +{ + HRESULT hr; + BOOL bRestored; + DWORD dwBaseFrequency; + + if( m_apDSBuffer == NULL ) + return CO_E_NOTINITIALIZED; + + LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer(); + if( pDSB == NULL ) + return DXUT_ERR( L"GetFreeBuffer", E_FAIL ); + + // Restore the buffer if it was lost + if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) ) + return DXUT_ERR( L"RestoreBuffer", hr ); + + if( bRestored ) + { + // The buffer was restored, so we need to fill it with new data + if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) ) + return DXUT_ERR( L"FillBufferWithSound", hr ); + } + + if( m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY ) + { + pDSB->GetFrequency( &dwBaseFrequency ); + pDSB->SetFrequency( dwBaseFrequency + lFrequency ); + } + + // QI for the 3D buffer + LPDIRECTSOUND3DBUFFER pDS3DBuffer; + hr = pDSB->QueryInterface( IID_IDirectSound3DBuffer, ( VOID** )&pDS3DBuffer ); + if( SUCCEEDED( hr ) ) + { + hr = pDS3DBuffer->SetAllParameters( p3DBuffer, DS3D_IMMEDIATE ); + if( SUCCEEDED( hr ) ) + { + hr = pDSB->Play( 0, dwPriority, dwFlags ); + } + + pDS3DBuffer->Release(); + } + + return hr; +} + + +//----------------------------------------------------------------------------- +// Name: CSound::Stop() +// Desc: Stops the sound from playing +//----------------------------------------------------------------------------- +HRESULT CSound::Stop() +{ + if( m_apDSBuffer == NULL ) + return CO_E_NOTINITIALIZED; + + HRESULT hr = 0; + + for( DWORD i = 0; i < m_dwNumBuffers; i++ ) + hr |= m_apDSBuffer[i]->Stop(); + + return hr; +} + + +//----------------------------------------------------------------------------- +// Name: CSound::Reset() +// Desc: Reset all of the sound buffers +//----------------------------------------------------------------------------- +HRESULT CSound::Reset() +{ + if( m_apDSBuffer == NULL ) + return CO_E_NOTINITIALIZED; + + HRESULT hr = 0; + + for( DWORD i = 0; i < m_dwNumBuffers; i++ ) + hr |= m_apDSBuffer[i]->SetCurrentPosition( 0 ); + + return hr; +} + + +//----------------------------------------------------------------------------- +// Name: CSound::IsSoundPlaying() +// Desc: Checks to see if a buffer is playing and returns TRUE if it is. +//----------------------------------------------------------------------------- +BOOL CSound::IsSoundPlaying() +{ + BOOL bIsPlaying = FALSE; + + if( m_apDSBuffer == NULL ) + return FALSE; + + for( DWORD i = 0; i < m_dwNumBuffers; i++ ) + { + if( m_apDSBuffer[i] ) + { + DWORD dwStatus = 0; + m_apDSBuffer[i]->GetStatus( &dwStatus ); + bIsPlaying |= ( ( dwStatus & DSBSTATUS_PLAYING ) != 0 ); + } + } + + return bIsPlaying; +} + + +//----------------------------------------------------------------------------- +// Name: CStreamingSound::CStreamingSound() +// Desc: Setups up a buffer so data can be streamed from the wave file into +// a buffer. This is very useful for large wav files that would take a +// while to load. The buffer is initially filled with data, then +// as sound is played the notification events are signaled and more data +// is written into the buffer by calling HandleWaveStreamNotification() +//----------------------------------------------------------------------------- +CStreamingSound::CStreamingSound( LPDIRECTSOUNDBUFFER pDSBuffer, DWORD dwDSBufferSize, + CWaveFile* pWaveFile, DWORD dwNotifySize ) : CSound( &pDSBuffer, dwDSBufferSize, 1, + pWaveFile, 0 ) +{ + m_dwLastPlayPos = 0; + m_dwPlayProgress = 0; + m_dwNotifySize = dwNotifySize; + m_dwNextWriteOffset = 0; + m_bFillNextNotificationWithSilence = FALSE; +} + + +//----------------------------------------------------------------------------- +// Name: CStreamingSound::~CStreamingSound() +// Desc: Destroys the class +//----------------------------------------------------------------------------- +CStreamingSound::~CStreamingSound() +{ +} + + +//----------------------------------------------------------------------------- +// Name: CStreamingSound::HandleWaveStreamNotification() +// Desc: Handle the notification that tells us to put more wav data in the +// circular buffer +//----------------------------------------------------------------------------- +HRESULT CStreamingSound::HandleWaveStreamNotification( BOOL bLoopedPlay ) +{ + HRESULT hr; + DWORD dwCurrentPlayPos; + DWORD dwPlayDelta; + DWORD dwBytesWrittenToBuffer; + VOID* pDSLockedBuffer = NULL; + VOID* pDSLockedBuffer2 = NULL; + DWORD dwDSLockedBufferSize; + DWORD dwDSLockedBufferSize2; + + if( m_apDSBuffer == NULL || m_pWaveFile == NULL ) + return CO_E_NOTINITIALIZED; + + // Restore the buffer if it was lost + BOOL bRestored; + if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &bRestored ) ) ) + return DXUT_ERR( L"RestoreBuffer", hr ); + + if( bRestored ) + { + // The buffer was restored, so we need to fill it with new data + if( FAILED( hr = FillBufferWithSound( m_apDSBuffer[0], FALSE ) ) ) + return DXUT_ERR( L"FillBufferWithSound", hr ); + return S_OK; + } + + // Lock the DirectSound buffer + if( FAILED( hr = m_apDSBuffer[0]->Lock( m_dwNextWriteOffset, m_dwNotifySize, + &pDSLockedBuffer, &dwDSLockedBufferSize, + &pDSLockedBuffer2, &dwDSLockedBufferSize2, 0L ) ) ) + return DXUT_ERR( L"Lock", hr ); + + // m_dwDSBufferSize and m_dwNextWriteOffset are both multiples of m_dwNotifySize, + // it should the second buffer, so it should never be valid + if( pDSLockedBuffer2 != NULL ) + return E_UNEXPECTED; + + if( !m_bFillNextNotificationWithSilence ) + { + // Fill the DirectSound buffer with wav data + if( FAILED( hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer, + dwDSLockedBufferSize, + &dwBytesWrittenToBuffer ) ) ) + return DXUT_ERR( L"Read", hr ); + } + else + { + // Fill the DirectSound buffer with silence + FillMemory( pDSLockedBuffer, dwDSLockedBufferSize, + ( BYTE )( m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) ); + dwBytesWrittenToBuffer = dwDSLockedBufferSize; + } + + // If the number of bytes written is less than the + // amount we requested, we have a short file. + if( dwBytesWrittenToBuffer < dwDSLockedBufferSize ) + { + if( !bLoopedPlay ) + { + // Fill in silence for the rest of the buffer. + FillMemory( ( BYTE* )pDSLockedBuffer + dwBytesWrittenToBuffer, + dwDSLockedBufferSize - dwBytesWrittenToBuffer, + ( BYTE )( m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) ); + + // Any future notifications should just fill the buffer with silence + m_bFillNextNotificationWithSilence = TRUE; + } + else + { + // We are looping, so reset the file and fill the buffer with wav data + DWORD dwReadSoFar = dwBytesWrittenToBuffer; // From previous call above. + while( dwReadSoFar < dwDSLockedBufferSize ) + { + // This will keep reading in until the buffer is full (for very short files). + if( FAILED( hr = m_pWaveFile->ResetFile() ) ) + return DXUT_ERR( L"ResetFile", hr ); + + if( FAILED( hr = m_pWaveFile->Read( ( BYTE* )pDSLockedBuffer + dwReadSoFar, + dwDSLockedBufferSize - dwReadSoFar, + &dwBytesWrittenToBuffer ) ) ) + return DXUT_ERR( L"Read", hr ); + + dwReadSoFar += dwBytesWrittenToBuffer; + } + } + } + + // Unlock the DirectSound buffer + m_apDSBuffer[0]->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 ); + + // Figure out how much data has been played so far. When we have played + // past the end of the file, we will either need to start filling the + // buffer with silence or starting reading from the beginning of the file, + // depending if the user wants to loop the sound + if( FAILED( hr = m_apDSBuffer[0]->GetCurrentPosition( &dwCurrentPlayPos, NULL ) ) ) + return DXUT_ERR( L"GetCurrentPosition", hr ); + + // Check to see if the position counter looped + if( dwCurrentPlayPos < m_dwLastPlayPos ) + dwPlayDelta = ( m_dwDSBufferSize - m_dwLastPlayPos ) + dwCurrentPlayPos; + else + dwPlayDelta = dwCurrentPlayPos - m_dwLastPlayPos; + + m_dwPlayProgress += dwPlayDelta; + m_dwLastPlayPos = dwCurrentPlayPos; + + // If we are now filling the buffer with silence, then we have found the end so + // check to see if the entire sound has played, if it has then stop the buffer. + if( m_bFillNextNotificationWithSilence ) + { + // We don't want to cut off the sound before it's done playing. + if( m_dwPlayProgress >= m_pWaveFile->GetSize() ) + { + m_apDSBuffer[0]->Stop(); + } + } + + // Update where the buffer will lock (for next time) + m_dwNextWriteOffset += dwDSLockedBufferSize; + m_dwNextWriteOffset %= m_dwDSBufferSize; // Circular buffer + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CStreamingSound::Reset() +// Desc: Resets the sound so it will begin playing at the beginning +//----------------------------------------------------------------------------- +HRESULT CStreamingSound::Reset() +{ + HRESULT hr; + + if( m_apDSBuffer[0] == NULL || m_pWaveFile == NULL ) + return CO_E_NOTINITIALIZED; + + m_dwLastPlayPos = 0; + m_dwPlayProgress = 0; + m_dwNextWriteOffset = 0; + m_bFillNextNotificationWithSilence = FALSE; + + // Restore the buffer if it was lost + BOOL bRestored; + if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &bRestored ) ) ) + return DXUT_ERR( L"RestoreBuffer", hr ); + + if( bRestored ) + { + // The buffer was restored, so we need to fill it with new data + if( FAILED( hr = FillBufferWithSound( m_apDSBuffer[0], FALSE ) ) ) + return DXUT_ERR( L"FillBufferWithSound", hr ); + } + + m_pWaveFile->ResetFile(); + + return m_apDSBuffer[0]->SetCurrentPosition( 0L ); +} diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKsound.h b/Demos/DX11ClothDemo/DXUT/Optional/SDKsound.h new file mode 100644 index 0000000..b79054a --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKsound.h @@ -0,0 +1,124 @@ +//----------------------------------------------------------------------------- +// File: DXUTsound.h +// +// Copyright (c) Microsoft Corp. All rights reserved. +//----------------------------------------------------------------------------- +#ifndef DXUTSOUND_H +#define DXUTSOUND_H + +//----------------------------------------------------------------------------- +// Header Includes +//----------------------------------------------------------------------------- +#include +#include + +//----------------------------------------------------------------------------- +// Classes used by this header +//----------------------------------------------------------------------------- +class CSoundManager; +class CSound; +class CStreamingSound; +class CWaveFile; + + +//----------------------------------------------------------------------------- +// Typing macros +//----------------------------------------------------------------------------- +#define DXUT_StopSound(s) { if(s) s->Stop(); } +#define DXUT_PlaySound(s) { if(s) s->Play( 0, 0 ); } +#define DXUT_PlaySoundLooping(s) { if(s) s->Play( 0, DSBPLAY_LOOPING ); } + + +//----------------------------------------------------------------------------- +// Name: class CSoundManager +// Desc: +//----------------------------------------------------------------------------- +class CSoundManager +{ +protected: + IDirectSound8* m_pDS; + +public: + CSoundManager(); + ~CSoundManager(); + + HRESULT Initialize( HWND hWnd, DWORD dwCoopLevel ); + inline LPDIRECTSOUND8 GetDirectSound() + { + return m_pDS; + } + HRESULT SetPrimaryBufferFormat( DWORD dwPrimaryChannels, DWORD dwPrimaryFreq, + DWORD dwPrimaryBitRate ); + HRESULT Get3DListenerInterface( LPDIRECTSOUND3DLISTENER* ppDSListener ); + + HRESULT Create( CSound** ppSound, LPWSTR strWaveFileName, DWORD dwCreationFlags = 0, + GUID guid3DAlgorithm = GUID_NULL, DWORD dwNumBuffers = 1 ); + HRESULT CreateFromMemory( CSound** ppSound, BYTE* pbData, ULONG ulDataSize, LPWAVEFORMATEX pwfx, + DWORD dwCreationFlags = 0, GUID guid3DAlgorithm = GUID_NULL, + DWORD dwNumBuffers = 1 ); + HRESULT CreateStreaming( CStreamingSound** ppStreamingSound, LPWSTR strWaveFileName, + DWORD dwCreationFlags, GUID guid3DAlgorithm, DWORD dwNotifyCount, + DWORD dwNotifySize, HANDLE hNotifyEvent ); +}; + + +//----------------------------------------------------------------------------- +// Name: class CSound +// Desc: Encapsulates functionality of a DirectSound buffer. +//----------------------------------------------------------------------------- +class CSound +{ +protected: + LPDIRECTSOUNDBUFFER* m_apDSBuffer; + DWORD m_dwDSBufferSize; + CWaveFile* m_pWaveFile; + DWORD m_dwNumBuffers; + DWORD m_dwCreationFlags; + + HRESULT RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, BOOL* pbWasRestored ); + +public: + CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, DWORD dwNumBuffers, + CWaveFile* pWaveFile, DWORD dwCreationFlags ); + virtual ~CSound(); + + HRESULT Get3DBufferInterface( DWORD dwIndex, LPDIRECTSOUND3DBUFFER* ppDS3DBuffer ); + HRESULT FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, BOOL bRepeatWavIfBufferLarger ); + LPDIRECTSOUNDBUFFER GetFreeBuffer(); + LPDIRECTSOUNDBUFFER GetBuffer( DWORD dwIndex ); + + HRESULT Play( DWORD dwPriority = 0, DWORD dwFlags = 0, LONG lVolume = 0, LONG lFrequency = -1, + LONG lPan = 0 ); + HRESULT Play3D( LPDS3DBUFFER p3DBuffer, DWORD dwPriority = 0, DWORD dwFlags = 0, LONG lFrequency = 0 ); + HRESULT Stop(); + HRESULT Reset(); + BOOL IsSoundPlaying(); +}; + + +//----------------------------------------------------------------------------- +// Name: class CStreamingSound +// Desc: Encapsulates functionality to play a wave file with DirectSound. +// The Create() method loads a chunk of wave file into the buffer, +// and as sound plays more is written to the buffer by calling +// HandleWaveStreamNotification() whenever hNotifyEvent is signaled. +//----------------------------------------------------------------------------- +class CStreamingSound : public CSound +{ +protected: + DWORD m_dwLastPlayPos; + DWORD m_dwPlayProgress; + DWORD m_dwNotifySize; + DWORD m_dwNextWriteOffset; + BOOL m_bFillNextNotificationWithSilence; + +public: + CStreamingSound( LPDIRECTSOUNDBUFFER pDSBuffer, DWORD dwDSBufferSize, CWaveFile* pWaveFile, + DWORD dwNotifySize ); + ~CStreamingSound(); + + HRESULT HandleWaveStreamNotification( BOOL bLoopedPlay ); + HRESULT Reset(); +}; + +#endif // DXUTSOUND_H diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.cpp b/Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.cpp new file mode 100644 index 0000000..fb2725f --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.cpp @@ -0,0 +1,539 @@ +//----------------------------------------------------------------------------- +// File: SDKWaveFile.cpp +// +// Desc: Classes for reading and writing wav files. Feel free to use this class +// as a starting point for adding extra functionality. +// +// XNA Developer Connection +// +// Copyright (c) Microsoft Corp. All rights reserved. +//----------------------------------------------------------------------------- +#define STRICT +#include "DXUT.h" +#include "SDKwavefile.h" +#undef min // use __min instead +#undef max // use __max instead + +//----------------------------------------------------------------------------- +// Name: CWaveFile::CWaveFile() +// Desc: Constructs the class. Call Open() to open a wave file for reading. +// Then call Read() as needed. Calling the destructor or Close() +// will close the file. +//----------------------------------------------------------------------------- +CWaveFile::CWaveFile() +{ + m_pwfx = NULL; + m_hmmio = NULL; + m_pResourceBuffer = NULL; + m_dwSize = 0; + m_bIsReadingFromMemory = FALSE; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::~CWaveFile() +// Desc: Destructs the class +//----------------------------------------------------------------------------- +CWaveFile::~CWaveFile() +{ + Close(); + + if( !m_bIsReadingFromMemory ) + SAFE_DELETE_ARRAY( m_pwfx ); +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::Open() +// Desc: Opens a wave file for reading +//----------------------------------------------------------------------------- +HRESULT CWaveFile::Open( LPWSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags ) +{ + HRESULT hr; + + m_dwFlags = dwFlags; + m_bIsReadingFromMemory = FALSE; + + if( m_dwFlags == WAVEFILE_READ ) + { + if( strFileName == NULL ) + return E_INVALIDARG; + SAFE_DELETE_ARRAY( m_pwfx ); + + m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ ); + + if( NULL == m_hmmio ) + { + HRSRC hResInfo; + HGLOBAL hResData; + DWORD dwSize; + VOID* pvRes; + + // Loading it as a file failed, so try it as a resource + if( NULL == ( hResInfo = FindResource( NULL, strFileName, L"WAVE" ) ) ) + { + if( NULL == ( hResInfo = FindResource( NULL, strFileName, L"WAV" ) ) ) + return DXTRACE_ERR( L"FindResource", E_FAIL ); + } + + if( NULL == ( hResData = LoadResource( GetModuleHandle( NULL ), hResInfo ) ) ) + return DXTRACE_ERR( L"LoadResource", E_FAIL ); + + if( 0 == ( dwSize = SizeofResource( GetModuleHandle( NULL ), hResInfo ) ) ) + return DXTRACE_ERR( L"SizeofResource", E_FAIL ); + + if( NULL == ( pvRes = LockResource( hResData ) ) ) + return DXTRACE_ERR( L"LockResource", E_FAIL ); + + m_pResourceBuffer = new CHAR[ dwSize ]; + if( m_pResourceBuffer == NULL ) + return DXTRACE_ERR( L"new", E_OUTOFMEMORY ); + memcpy( m_pResourceBuffer, pvRes, dwSize ); + + MMIOINFO mmioInfo; + ZeroMemory( &mmioInfo, sizeof( mmioInfo ) ); + mmioInfo.fccIOProc = FOURCC_MEM; + mmioInfo.cchBuffer = dwSize; + mmioInfo.pchBuffer = ( CHAR* )m_pResourceBuffer; + + m_hmmio = mmioOpen( NULL, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ ); + } + + if( FAILED( hr = ReadMMIO() ) ) + { + // ReadMMIO will fail if its an not a wave file + mmioClose( m_hmmio, 0 ); + return DXTRACE_ERR( L"ReadMMIO", hr ); + } + + if( FAILED( hr = ResetFile() ) ) + return DXTRACE_ERR( L"ResetFile", hr ); + + // After the reset, the size of the wav file is m_ck.cksize so store it now + m_dwSize = m_ck.cksize; + } + else + { + m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | + MMIO_READWRITE | + MMIO_CREATE ); + if( NULL == m_hmmio ) + return DXTRACE_ERR( L"mmioOpen", E_FAIL ); + + if( FAILED( hr = WriteMMIO( pwfx ) ) ) + { + mmioClose( m_hmmio, 0 ); + return DXTRACE_ERR( L"WriteMMIO", hr ); + } + + if( FAILED( hr = ResetFile() ) ) + return DXTRACE_ERR( L"ResetFile", hr ); + } + + return hr; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::OpenFromMemory() +// Desc: copy data to CWaveFile member variable from memory +//----------------------------------------------------------------------------- +HRESULT CWaveFile::OpenFromMemory( BYTE* pbData, ULONG ulDataSize, + WAVEFORMATEX* pwfx, DWORD dwFlags ) +{ + m_pwfx = pwfx; + m_ulDataSize = ulDataSize; + m_pbData = pbData; + m_pbDataCur = m_pbData; + m_bIsReadingFromMemory = TRUE; + + if( dwFlags != WAVEFILE_READ ) + return E_NOTIMPL; + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::ReadMMIO() +// Desc: Support function for reading from a multimedia I/O stream. +// m_hmmio must be valid before calling. This function uses it to +// update m_ckRiff, and m_pwfx. +//----------------------------------------------------------------------------- +HRESULT CWaveFile::ReadMMIO() +{ + MMCKINFO ckIn; // chunk info. for general use. + PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in. + + m_pwfx = NULL; + + if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) ) + return DXTRACE_ERR( L"mmioDescend", E_FAIL ); + + // Check to make sure this is a valid wave file + if( ( m_ckRiff.ckid != FOURCC_RIFF ) || + ( m_ckRiff.fccType != mmioFOURCC( 'W', 'A', 'V', 'E' ) ) ) + return DXTRACE_ERR( L"mmioFOURCC", E_FAIL ); + + // Search the input file for for the 'fmt ' chunk. + ckIn.ckid = mmioFOURCC( 'f', 'm', 't', ' ' ); + if( 0 != mmioDescend( m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK ) ) + return DXTRACE_ERR( L"mmioDescend", E_FAIL ); + + // Expect the 'fmt' chunk to be at least as large as ; + // if there are extra parameters at the end, we'll ignore them + if( ckIn.cksize < ( LONG )sizeof( PCMWAVEFORMAT ) ) + return DXTRACE_ERR( L"sizeof(PCMWAVEFORMAT)", E_FAIL ); + + // Read the 'fmt ' chunk into . + if( mmioRead( m_hmmio, ( HPSTR )&pcmWaveFormat, + sizeof( pcmWaveFormat ) ) != sizeof( pcmWaveFormat ) ) + return DXTRACE_ERR( L"mmioRead", E_FAIL ); + + // Allocate the waveformatex, but if its not pcm format, read the next + // word, and thats how many extra bytes to allocate. + if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM ) + { + m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX ) ]; + if( NULL == m_pwfx ) + return DXTRACE_ERR( L"m_pwfx", E_FAIL ); + + // Copy the bytes from the pcm structure to the waveformatex structure + memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) ); + m_pwfx->cbSize = 0; + } + else + { + // Read in length of extra bytes. + WORD cbExtraBytes = 0L; + if( mmioRead( m_hmmio, ( CHAR* )&cbExtraBytes, sizeof( WORD ) ) != sizeof( WORD ) ) + return DXTRACE_ERR( L"mmioRead", E_FAIL ); + + m_pwfx = ( WAVEFORMATEX* )new CHAR[ sizeof( WAVEFORMATEX ) + cbExtraBytes ]; + if( NULL == m_pwfx ) + return DXTRACE_ERR( L"new", E_FAIL ); + + // Copy the bytes from the pcm structure to the waveformatex structure + memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) ); + m_pwfx->cbSize = cbExtraBytes; + + // Now, read those extra bytes into the structure, if cbExtraAlloc != 0. + if( mmioRead( m_hmmio, ( CHAR* )( ( ( BYTE* )&( m_pwfx->cbSize ) ) + sizeof( WORD ) ), + cbExtraBytes ) != cbExtraBytes ) + { + SAFE_DELETE( m_pwfx ); + return DXTRACE_ERR( L"mmioRead", E_FAIL ); + } + } + + // Ascend the input file out of the 'fmt ' chunk. + if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) ) + { + SAFE_DELETE( m_pwfx ); + return DXTRACE_ERR( L"mmioAscend", E_FAIL ); + } + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::GetSize() +// Desc: Retuns the size of the read access wave file +//----------------------------------------------------------------------------- +DWORD CWaveFile::GetSize() +{ + return m_dwSize; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::ResetFile() +// Desc: Resets the internal m_ck pointer so reading starts from the +// beginning of the file again +//----------------------------------------------------------------------------- +HRESULT CWaveFile::ResetFile() +{ + if( m_bIsReadingFromMemory ) + { + m_pbDataCur = m_pbData; + } + else + { + if( m_hmmio == NULL ) + return CO_E_NOTINITIALIZED; + + if( m_dwFlags == WAVEFILE_READ ) + { + // Seek to the data + if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof( FOURCC ), + SEEK_SET ) ) + return DXTRACE_ERR( L"mmioSeek", E_FAIL ); + + // Search the input file for the 'data' chunk. + m_ck.ckid = mmioFOURCC( 'd', 'a', 't', 'a' ); + if( 0 != mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) ) + return DXTRACE_ERR( L"mmioDescend", E_FAIL ); + } + else + { + // Create the 'data' chunk that holds the waveform samples. + m_ck.ckid = mmioFOURCC( 'd', 'a', 't', 'a' ); + m_ck.cksize = 0; + + if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) ) + return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL ); + + if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) ) + return DXTRACE_ERR( L"mmioGetInfo", E_FAIL ); + } + } + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::Read() +// Desc: Reads section of data from a wave file into pBuffer and returns +// how much read in pdwSizeRead, reading not more than dwSizeToRead. +// This uses m_ck to determine where to start reading from. So +// subsequent calls will be continue where the last left off unless +// Reset() is called. +//----------------------------------------------------------------------------- +HRESULT CWaveFile::Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead ) +{ + if( m_bIsReadingFromMemory ) + { + if( m_pbDataCur == NULL ) + return CO_E_NOTINITIALIZED; + if( pdwSizeRead != NULL ) + *pdwSizeRead = 0; + + if( ( BYTE* )( m_pbDataCur + dwSizeToRead ) > + ( BYTE* )( m_pbData + m_ulDataSize ) ) + { + dwSizeToRead = m_ulDataSize - ( DWORD )( m_pbDataCur - m_pbData ); + } + +#pragma warning( disable: 4616 ) // disable warning about warning number '22104' being out of range +#pragma warning( disable: 22104 ) // disable PREfast warning during static code analysis + CopyMemory( pBuffer, m_pbDataCur, dwSizeToRead ); +#pragma warning( default: 22104 ) +#pragma warning( default: 4616 ) + + if( pdwSizeRead != NULL ) + *pdwSizeRead = dwSizeToRead; + + return S_OK; + } + else + { + MMIOINFO mmioinfoIn; // current status of m_hmmio + + if( m_hmmio == NULL ) + return CO_E_NOTINITIALIZED; + if( pBuffer == NULL || pdwSizeRead == NULL ) + return E_INVALIDARG; + + *pdwSizeRead = 0; + + if( 0 != mmioGetInfo( m_hmmio, &mmioinfoIn, 0 ) ) + return DXTRACE_ERR( L"mmioGetInfo", E_FAIL ); + + UINT cbDataIn = dwSizeToRead; + if( cbDataIn > m_ck.cksize ) + cbDataIn = m_ck.cksize; + + m_ck.cksize -= cbDataIn; + + for( DWORD cT = 0; cT < cbDataIn; cT++ ) + { + // Copy the bytes from the io to the buffer. + if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead ) + { + if( 0 != mmioAdvance( m_hmmio, &mmioinfoIn, MMIO_READ ) ) + return DXTRACE_ERR( L"mmioAdvance", E_FAIL ); + + if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead ) + return DXTRACE_ERR( L"mmioinfoIn.pchNext", E_FAIL ); + } + + // Actual copy. + *( ( BYTE* )pBuffer + cT ) = *( ( BYTE* )mmioinfoIn.pchNext ); + mmioinfoIn.pchNext++; + } + + if( 0 != mmioSetInfo( m_hmmio, &mmioinfoIn, 0 ) ) + return DXTRACE_ERR( L"mmioSetInfo", E_FAIL ); + + *pdwSizeRead = cbDataIn; + + return S_OK; + } +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::Close() +// Desc: Closes the wave file +//----------------------------------------------------------------------------- +HRESULT CWaveFile::Close() +{ + if( m_dwFlags == WAVEFILE_READ ) + { + mmioClose( m_hmmio, 0 ); + m_hmmio = NULL; + SAFE_DELETE_ARRAY( m_pResourceBuffer ); + } + else + { + m_mmioinfoOut.dwFlags |= MMIO_DIRTY; + + if( m_hmmio == NULL ) + return CO_E_NOTINITIALIZED; + + if( 0 != mmioSetInfo( m_hmmio, &m_mmioinfoOut, 0 ) ) + return DXTRACE_ERR( L"mmioSetInfo", E_FAIL ); + + // Ascend the output file out of the 'data' chunk -- this will cause + // the chunk size of the 'data' chunk to be written. + if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) ) + return DXTRACE_ERR( L"mmioAscend", E_FAIL ); + + // Do this here instead... + if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) ) + return DXTRACE_ERR( L"mmioAscend", E_FAIL ); + + mmioSeek( m_hmmio, 0, SEEK_SET ); + + if( 0 != ( INT )mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) + return DXTRACE_ERR( L"mmioDescend", E_FAIL ); + + m_ck.ckid = mmioFOURCC( 'f', 'a', 'c', 't' ); + + if( 0 == mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) ) + { + DWORD dwSamples = 0; + mmioWrite( m_hmmio, ( HPSTR )&dwSamples, sizeof( DWORD ) ); + mmioAscend( m_hmmio, &m_ck, 0 ); + } + + // Ascend the output file out of the 'RIFF' chunk -- this will cause + // the chunk size of the 'RIFF' chunk to be written. + if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) ) + return DXTRACE_ERR( L"mmioAscend", E_FAIL ); + + mmioClose( m_hmmio, 0 ); + m_hmmio = NULL; + } + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::WriteMMIO() +// Desc: Support function for reading from a multimedia I/O stream +// pwfxDest is the WAVEFORMATEX for this new wave file. +// m_hmmio must be valid before calling. This function uses it to +// update m_ckRiff, and m_ck. +//----------------------------------------------------------------------------- +HRESULT CWaveFile::WriteMMIO( WAVEFORMATEX* pwfxDest ) +{ + DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile. + MMCKINFO ckOut1; + + dwFactChunk = ( DWORD )-1; + + // Create the output file RIFF chunk of form type 'WAVE'. + m_ckRiff.fccType = mmioFOURCC( 'W', 'A', 'V', 'E' ); + m_ckRiff.cksize = 0; + + if( 0 != mmioCreateChunk( m_hmmio, &m_ckRiff, MMIO_CREATERIFF ) ) + return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL ); + + // We are now descended into the 'RIFF' chunk we just created. + // Now create the 'fmt ' chunk. Since we know the size of this chunk, + // specify it in the MMCKINFO structure so MMIO doesn't have to seek + // back and set the chunk size after ascending from the chunk. + m_ck.ckid = mmioFOURCC( 'f', 'm', 't', ' ' ); + m_ck.cksize = sizeof( PCMWAVEFORMAT ); + + if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) ) + return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL ); + + // Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type. + if( pwfxDest->wFormatTag == WAVE_FORMAT_PCM ) + { + if( mmioWrite( m_hmmio, ( HPSTR )pwfxDest, + sizeof( PCMWAVEFORMAT ) ) != sizeof( PCMWAVEFORMAT ) ) + return DXTRACE_ERR( L"mmioWrite", E_FAIL ); + } + else + { + // Write the variable length size. + if( ( UINT )mmioWrite( m_hmmio, ( HPSTR )pwfxDest, + sizeof( *pwfxDest ) + pwfxDest->cbSize ) != + ( sizeof( *pwfxDest ) + pwfxDest->cbSize ) ) + return DXTRACE_ERR( L"mmioWrite", E_FAIL ); + } + + // Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk. + if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) ) + return DXTRACE_ERR( L"mmioAscend", E_FAIL ); + + // Now create the fact chunk, not required for PCM but nice to have. This is filled + // in when the close routine is called. + ckOut1.ckid = mmioFOURCC( 'f', 'a', 'c', 't' ); + ckOut1.cksize = 0; + + if( 0 != mmioCreateChunk( m_hmmio, &ckOut1, 0 ) ) + return DXTRACE_ERR( L"mmioCreateChunk", E_FAIL ); + + if( mmioWrite( m_hmmio, ( HPSTR )&dwFactChunk, sizeof( dwFactChunk ) ) != + sizeof( dwFactChunk ) ) + return DXTRACE_ERR( L"mmioWrite", E_FAIL ); + + // Now ascend out of the fact chunk... + if( 0 != mmioAscend( m_hmmio, &ckOut1, 0 ) ) + return DXTRACE_ERR( L"mmioAscend", E_FAIL ); + + return S_OK; +} + + +//----------------------------------------------------------------------------- +// Name: CWaveFile::Write() +// Desc: Writes data to the open wave file +//----------------------------------------------------------------------------- +HRESULT CWaveFile::Write( UINT nSizeToWrite, BYTE* pbSrcData, UINT* pnSizeWrote ) +{ + UINT cT; + + if( m_bIsReadingFromMemory ) + return E_NOTIMPL; + if( m_hmmio == NULL ) + return CO_E_NOTINITIALIZED; + if( pnSizeWrote == NULL || pbSrcData == NULL ) + return E_INVALIDARG; + + *pnSizeWrote = 0; + + for( cT = 0; cT < nSizeToWrite; cT++ ) + { + if( m_mmioinfoOut.pchNext == m_mmioinfoOut.pchEndWrite ) + { + m_mmioinfoOut.dwFlags |= MMIO_DIRTY; + if( 0 != mmioAdvance( m_hmmio, &m_mmioinfoOut, MMIO_WRITE ) ) + return DXTRACE_ERR( L"mmioAdvance", E_FAIL ); + } + + *( ( BYTE* )m_mmioinfoOut.pchNext ) = *( ( BYTE* )pbSrcData + cT ); + ( BYTE* )m_mmioinfoOut.pchNext++; + + ( *pnSizeWrote )++; + } + + return S_OK; +} diff --git a/Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.h b/Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.h new file mode 100644 index 0000000..921f1d4 --- /dev/null +++ b/Demos/DX11ClothDemo/DXUT/Optional/SDKwavefile.h @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// File: WaveFile.h +// +// Copyright (c) Microsoft Corp. All rights reserved. +//----------------------------------------------------------------------------- +#ifndef DXUTWAVEFILE_H +#define DXUTWAVEFILE_H + +//----------------------------------------------------------------------------- +// Typing macros +//----------------------------------------------------------------------------- +#define WAVEFILE_READ 1 +#define WAVEFILE_WRITE 2 + +//----------------------------------------------------------------------------- +// Name: class CWaveFile +// Desc: Encapsulates reading or writing sound data to or from a wave file +//----------------------------------------------------------------------------- +class CWaveFile +{ +public: + WAVEFORMATEX* m_pwfx; // Pointer to WAVEFORMATEX structure + HMMIO m_hmmio; // MM I/O handle for the WAVE + MMCKINFO m_ck; // Multimedia RIFF chunk + MMCKINFO m_ckRiff; // Use in opening a WAVE file + DWORD m_dwSize; // The size of the wave file + MMIOINFO m_mmioinfoOut; + DWORD m_dwFlags; + BOOL m_bIsReadingFromMemory; + BYTE* m_pbData; + BYTE* m_pbDataCur; + ULONG m_ulDataSize; + CHAR* m_pResourceBuffer; + +protected: + HRESULT ReadMMIO(); + HRESULT WriteMMIO( WAVEFORMATEX* pwfxDest ); + +public: + CWaveFile(); + ~CWaveFile(); + + HRESULT Open( LPWSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags ); + HRESULT OpenFromMemory( BYTE* pbData, ULONG ulDataSize, WAVEFORMATEX* pwfx, DWORD dwFlags ); + HRESULT Close(); + + HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead ); + HRESULT Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote ); + + DWORD GetSize(); + HRESULT ResetFile(); + WAVEFORMATEX* GetFormat() + { + return m_pwfx; + }; +}; + + +#endif // DXUTWAVEFILE_H diff --git a/Demos/DX11ClothDemo/DXUT/Optional/directx.ico b/Demos/DX11ClothDemo/DXUT/Optional/directx.ico new file mode 100644 index 0000000000000000000000000000000000000000..bc43c1b2085df668dffff26d80adcb0ef73f23a9 GIT binary patch literal 25214 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 literal 0 HcmV?d00001 diff --git a/Demos/DX11ClothDemo/Media/Tiny/tiny.sdkmesh b/Demos/DX11ClothDemo/Media/Tiny/tiny.sdkmesh new file mode 100644 index 0000000000000000000000000000000000000000..c4a14121112c3c486da7ce5b07307ad42245e6f8 GIT binary patch literal 231612 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 LCZ53m{{;RIIudD- literal 0 HcmV?d00001 diff --git a/Demos/DX11ClothDemo/Media/Tiny/tiny.x b/Demos/DX11ClothDemo/Media/Tiny/tiny.x new file mode 100644 index 0000000..17f8d08 --- /dev/null +++ b/Demos/DX11ClothDemo/Media/Tiny/tiny.x @@ -0,0 +1,53984 @@ +xof 0303txt 0032 +template XSkinMeshHeader { + <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> + WORD nMaxSkinWeightsPerVertex; + WORD nMaxSkinWeightsPerFace; + WORD nBones; +} + +template VertexDuplicationIndices { + + DWORD nIndices; + DWORD nOriginalVertices; + array DWORD indices[nIndices]; +} + +template SkinWeights { + <6f0d123b-bad2-4167-a0d0-80224f25fabb> + STRING transformNodeName; + DWORD nWeights; + array DWORD vertexIndices[nWeights]; + array FLOAT weights[nWeights]; + Matrix4x4 matrixOffset; +} + + +Frame Scene_Root { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;; + } + + Frame body { + + + FrameTransformMatrix { + 1.278853,0.000000,-0.000000,0.000000,0.000000,0.000000,1.123165,0.000000,0.000000,-1.470235,0.000000,0.000000,0.135977,2.027985,133.967667,1.000000;; + } + + Frame { + + + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,-0.142114,0.000023,-49.556850,1.000000;; + } + + Mesh { + 4432; + -34.720058;-12.484819;48.088928;, + -25.565304;-9.924385;26.239328;, + -34.612186;-1.674418;34.789925;, + 0.141491;7.622670;25.743210;, + -34.612175;17.843525;39.827816;, + -9.608727;27.597115;38.148296;, + -9.798330;-0.357897;65.599075;, + -34.612179;8.990501;57.540577;, + 0.077733;21.348866;52.164078;, + -11.429913;16.434713;56.577648;, + 0.141490;12.205804;59.792637;, + -17.647087;-15.421692;74.962234;, + 0.139748;-15.745451;70.035706;, + -28.078594;-4.899444;63.550846;, + 0.141491;-27.796947;71.486557;, + -23.021046;8.957323;28.295084;, + 0.141491;-9.487318;27.256748;, + 0.141491;-26.664299;32.989830;, + -11.193695;-27.720463;30.196030;, + -20.920319;-26.441757;33.507900;, + -23.021046;22.545492;38.817097;, + -4.681036;23.543238;52.237732;, + -7.199147;18.381388;29.309721;, + -31.657711;-16.623283;68.586205;, + -7.168321;-28.208626;74.147346;, + -27.854467;-30.229647;72.082443;, + -16.966074;-26.227253;76.131516;, + -33.277031;-27.463528;63.505905;, + -31.930122;-26.942392;51.688797;, + -26.290180;-21.425268;74.259827;, + -32.341526;-14.948000;58.484459;, + -14.724298;0.438756;65.826607;, + -17.688755;-53.253067;77.227638;, + -30.976030;-51.338348;55.580246;, + 0.141491;-50.060425;24.873173;, + -22.127073;-50.465675;31.947027;, + -24.287395;-54.514771;54.652374;, + 0.141374;-56.516960;39.995022;, + 0.141491;-37.227283;70.123970;, + -29.140186;-40.740757;54.994888;, + -18.598015;-63.628139;61.096786;, + -18.580341;-63.659996;42.089684;, + 0.141491;-28.374607;32.989838;, + -11.193696;-29.430769;30.196033;, + -20.920321;-28.152065;33.507904;, + -25.494289;-63.762321;51.551601;, + 0.102538;-63.445549;68.379417;, + 0.102538;-63.638348;37.841175;, + -16.503817;-36.463478;72.030708;, + -24.298424;-39.992043;64.994545;, + -14.590791;-42.557045;68.336487;, + -26.760902;-31.939959;72.082443;, + -16.966076;-27.937576;75.155312;, + -32.183464;-29.173838;63.505913;, + -31.930124;-28.652702;51.688805;, + -19.449144;-51.888283;62.452682;, + -6.438459;-49.943382;70.242874;, + 0.141491;-49.688911;68.965103;, + 0.141491;-29.773867;26.064960;, + -12.711588;-29.992414;25.556252;, + -23.846188;-30.195030;29.093178;, + -32.848045;-32.305534;51.981480;, + -30.142681;-11.598551;37.311020;, + -28.347116;-31.250282;40.537331;, + -26.551552;-50.902012;43.763638;, + -24.332394;-52.295708;66.403946;, + -26.425222;-28.402384;42.598354;, + -32.056793;-28.913269;57.597359;, + -34.612183;9.271671;35.005108;, + -34.612183;13.697768;49.116459;, + -34.666122;-2.091087;56.933292;, + -34.666122;-7.473567;40.417480;, + -33.602604;-10.886051;47.766304;, + -33.245544;-1.592087;55.511299;, + -33.454399;8.516764;56.378914;, + -33.377022;12.971798;48.765106;, + -33.285355;-1.230055;35.845985;, + -33.422455;-6.066209;41.124596;, + -33.326355;16.538502;40.337154;, + -33.380333;8.824398;35.941063;, + 0.141491;-46.403996;39.221611;, + -5.525791;-46.932079;37.824707;, + -10.389103;-46.292725;39.480644;, + -20.399273;-44.550671;45.133575;, + -24.509207;-50.845016;55.877068;, + 0.141491;17.711647;27.783634;, + 0.077734;27.263643;33.720470;, + -5.109205;27.415857;34.161194;, + -9.139874;26.594124;45.452682;, + 0.141491;22.863007;31.002354;, + -6.363874;23.153360;30.623175;, + -9.748887;22.893982;32.226307;, + -13.398946;24.794630;34.246376;, + -16.294899;25.090145;38.449425;, + -18.686239;24.355274;46.119999;, + -13.692654;24.681557;52.324207;, + -8.242743;20.971973;54.090229;, + -3.765221;20.286398;55.975685;, + 0.141491;18.192966;54.231785;, + -10.778057;22.307632;52.895199;, + -8.655515;-23.637917;29.537901;, + -19.722260;-1.585354;65.224693;, + -20.110298;5.311386;60.448208;, + -21.278301;13.060091;57.191551;, + -19.918121;19.050785;53.541157;, + -15.815639;16.328318;56.204815;, + -10.153260;28.853861;37.612610;, + -11.867444;17.503666;57.664883;, + -15.160084;1.466462;66.822762;, + 0.141491;28.542030;33.277145;, + -5.618525;28.677891;33.713886;, + -9.625071;27.664139;46.092670;, + 0.141491;24.137672;30.525173;, + -6.801406;24.428030;30.145996;, + -10.186419;24.168652;31.749128;, + -13.836477;26.069300;33.769196;, + -16.732431;26.364815;37.972244;, + -19.123772;25.424227;46.716579;, + -11.215589;23.376585;53.491779;, + -20.159792;-0.516401;65.821274;, + -20.547831;6.380339;61.044788;, + -21.715834;14.129044;57.788132;, + -20.355654;20.119738;54.137737;, + -16.253172;17.397270;56.801395;, + -29.388227;-40.601273;63.974194;, + -30.997221;-35.165527;63.780437;, + -29.736418;-23.496841;70.352409;, + -30.377008;-28.942865;68.092697;, + -32.118473;-39.484562;59.515316;, + -29.846169;-43.697968;61.553284;, + -28.709795;-30.444099;72.554062;, + -30.243555;-40.815727;64.445816;, + -31.852549;-35.379982;64.252060;, + -30.591745;-23.711294;70.824028;, + -31.232336;-29.157318;68.564316;, + -32.973801;-39.699017;59.986935;, + -30.701496;-43.912422;62.024902;, + 35.004288;-12.484816;48.088928;, + 25.849533;-9.924379;26.239330;, + 34.896416;-1.674414;34.789925;, + 34.896404;17.843529;39.827820;, + 9.931857;27.639982;38.133949;, + 10.079079;-0.357885;66.089737;, + 34.896408;8.990503;57.540577;, + 11.714142;16.434715;57.068302;, + 17.931316;-15.421690;74.962234;, + 28.362823;-4.899441;63.550846;, + 23.305275;8.957328;28.295086;, + 11.477924;-27.720457;30.196030;, + 21.204548;-26.441751;33.507900;, + 23.305275;22.545494;38.817101;, + 4.827426;23.522514;52.188004;, + 7.483376;18.381392;29.309723;, + 31.941940;-16.623281;68.586205;, + 7.452550;-28.208622;74.147346;, + 28.138697;-30.229643;72.082443;, + 17.250303;-26.227251;76.131516;, + 33.561260;-27.463524;63.505905;, + 32.214352;-26.942389;51.688797;, + 26.574409;-21.425266;74.259827;, + 32.625755;-14.947996;58.484459;, + 15.005043;0.438756;66.317261;, + 17.972984;-53.253063;77.227638;, + 31.260260;-51.338341;55.580242;, + 22.411303;-50.465668;31.947027;, + 24.562241;-54.514763;54.652370;, + 29.424416;-40.740753;54.994888;, + 18.770283;-63.633057;61.106705;, + 18.773201;-63.677704;42.028572;, + 11.477925;-29.430763;30.196033;, + 21.204550;-28.152060;33.507904;, + 25.705898;-63.638660;51.490501;, + 16.788046;-36.463474;72.030708;, + 24.582653;-39.992039;64.994545;, + 14.875020;-42.557041;68.336487;, + 27.045132;-31.939955;72.082443;, + 17.250305;-27.937574;75.155312;, + 32.467693;-29.173834;63.505913;, + 32.214352;-28.652699;51.688805;, + 19.723988;-51.888283;62.452682;, + 6.722688;-49.943378;70.242874;, + 12.995817;-29.992407;25.556252;, + 24.130417;-30.195024;29.093178;, + 33.132275;-32.305531;51.981480;, + 30.426910;-11.598546;37.311020;, + 28.631346;-31.250277;40.537331;, + 26.835781;-50.902004;43.763638;, + 24.616623;-52.295704;66.403946;, + 26.709452;-28.402378;42.598354;, + 32.341022;-28.913265;57.597359;, + 34.896412;9.271675;35.005108;, + 34.896412;13.697771;49.116459;, + 34.950352;-2.091084;56.933292;, + 34.950352;-7.473563;40.417480;, + 33.931534;-10.798729;47.691635;, + 33.266479;-1.659648;55.141335;, + 33.733215;8.483885;56.324486;, + 33.578400;13.114620;48.755165;, + 33.395126;-1.314395;35.941048;, + 33.696419;-6.417687;40.866890;, + 33.477127;16.479158;40.343475;, + 33.569466;8.843540;35.935562;, + 5.810019;-46.932072;37.824707;, + 10.673332;-46.292717;39.480644;, + 20.683502;-44.550663;45.133575;, + 24.793436;-50.845009;55.877064;, + 5.227813;27.441788;34.143456;, + 9.646603;26.610264;45.446602;, + 6.648103;23.153364;30.623177;, + 10.033116;22.893986;32.226311;, + 13.683175;24.794634;34.246380;, + 16.579128;25.090147;38.449429;, + 18.970469;24.355276;46.119999;, + 13.976883;24.681559;52.324207;, + 8.526972;20.971975;54.090229;, + 4.049450;20.286400;55.975685;, + 11.062286;22.307634;52.895199;, + 8.939744;-23.637911;29.537901;, + 20.006489;-1.585352;65.224693;, + 20.394527;5.311388;60.448208;, + 21.562531;13.060093;57.191551;, + 20.202351;19.050787;53.541157;, + 16.099869;16.328320;56.204815;, + 10.437490;28.853863;37.612614;, + 12.151673;17.503668;57.664883;, + 15.444313;1.466464;66.822762;, + 5.902754;28.677893;33.713890;, + 9.909300;27.664141;46.092674;, + 7.085635;24.428034;30.145998;, + 10.470648;24.168655;31.749130;, + 14.120707;26.069304;33.769199;, + 17.016661;26.364817;37.972248;, + 19.408001;25.424229;46.716579;, + 11.499818;23.376587;53.491779;, + 20.444021;-0.516399;65.821274;, + 20.832060;6.380341;61.044788;, + 22.000063;14.129045;57.788132;, + 20.639883;20.119740;54.137737;, + 16.537401;17.397272;56.801395;, + 29.672457;-40.601269;63.974190;, + 31.281450;-35.165524;63.780437;, + 30.020647;-23.496838;70.352409;, + 30.661238;-28.942862;68.092697;, + 32.402702;-39.484558;59.515316;, + 30.130398;-43.697964;61.553280;, + 28.994024;-30.444096;72.554062;, + 30.527784;-40.815723;64.445816;, + 32.136776;-35.379978;64.252060;, + 30.875975;-23.711290;70.824028;, + 31.516565;-29.157314;68.564316;, + 33.258030;-39.699013;59.986935;, + 30.985725;-43.912418;62.024899;, + 0.100870;-93.627769;27.356903;, + 0.100870;-80.794510;68.288246;, + -41.760616;-103.151527;46.673916;, + -24.713787;-129.635101;24.771605;, + -18.089975;-112.633553;62.624924;, + 0.100870;-118.350113;30.024460;, + -5.798617;-124.775063;56.960815;, + -25.173319;-90.214371;26.265825;, + -37.889961;-84.783730;46.673920;, + -4.658672;-143.854736;42.160900;, + -33.648396;-119.084198;29.032738;, + -19.782078;-86.427551;62.399220;, + 0.100870;-105.624802;63.766800;, + -33.875122;-127.515556;35.677757;, + -41.014412;-121.305328;41.175835;, + -15.635758;-212.122009;56.766579;, + -11.671675;-229.887054;44.415508;, + -11.967894;-201.991714;48.101704;, + -33.998722;-220.566071;61.510651;, + -39.528782;-322.910553;59.808899;, + -23.342522;-325.221313;36.655556;, + -35.048260;-213.572937;32.058167;, + -43.113548;-194.904678;46.172501;, + -43.619999;-206.619293;50.933479;, + -46.585148;-323.985016;35.078949;, + -34.708954;-324.151184;32.796345;, + -44.766525;-223.910660;41.391571;, + -13.351915;-168.910248;60.740967;, + -8.177140;-173.738678;44.589825;, + -22.042976;-120.057648;62.105083;, + -30.082495;-176.538712;60.086678;, + -23.352434;-144.066956;25.433430;, + -38.057816;-164.488510;57.655933;, + -25.025139;-183.704147;31.840212;, + -41.240711;-158.109726;38.305466;, + -31.089090;-190.013657;63.028923;, + -27.205957;-198.419052;34.729908;, + -35.127117;-120.041656;57.534679;, + -36.447479;-347.590393;81.989037;, + -32.971939;-348.840668;75.068268;, + -30.483822;-349.513580;64.542366;, + -30.277090;-349.285034;45.291451;, + -30.731056;-349.140869;32.597919;, + -50.995792;-347.566376;80.111809;, + -54.063526;-348.805878;72.346741;, + -53.720398;-349.475220;61.544106;, + -49.480873;-349.253357;42.813530;, + -44.998409;-349.114563;30.769142;, + -37.752792;-344.579865;81.882141;, + -33.638000;-341.897522;75.396339;, + -32.718132;-336.016754;68.786903;, + -25.375702;-326.803925;43.166012;, + -50.401588;-344.387238;80.484764;, + -53.600422;-344.479889;72.777603;, + -52.430077;-341.348145;62.750374;, + -52.006966;-325.347748;41.525673;, + -37.431126;-348.022339;28.784142;, + -30.811893;-349.229279;40.184383;, + -47.579365;-349.201599;38.020824;, + -23.738852;-160.860565;27.560469;, + -32.426979;-277.766174;32.203541;, + -24.943554;-117.940918;21.795742;, + -27.146837;-312.724365;57.102558;, + -41.869755;-312.813507;56.621277;, + -19.773428;-311.714844;51.152798;, + -17.516390;-311.220673;43.257233;, + -53.350098;-311.978485;48.287319;, + -24.548374;-311.052429;38.861855;, + -49.043320;-311.481262;40.787697;, + -36.779060;-311.947937;34.579979;, + -13.444867;-241.724686;43.812698;, + -18.083738;-235.404388;32.990765;, + -39.270157;-235.407135;32.086258;, + -18.709482;-278.846039;51.472935;, + -47.800510;-278.654022;48.696930;, + -15.278575;-278.076538;41.723305;, + -42.724228;-277.794373;38.664391;, + -47.843460;-278.215302;43.605659;, + -37.205242;-278.835236;54.105011;, + -21.722435;-277.300140;35.149902;, + -42.656788;-120.929993;49.355263;, + -17.315336;-184.822891;56.888432;, + -37.002441;-178.638748;55.923828;, + -14.539805;-213.740479;34.164742;, + -28.676964;-235.063950;29.100901;, + -26.290127;-159.034851;62.359310;, + -44.822357;-162.486374;47.417561;, + -26.283358;-192.193878;33.507416;, + -27.280354;-203.100555;31.769535;, + -26.421682;-194.991638;31.950752;, + -25.691517;-188.165451;31.257717;, + -32.553154;-207.822937;62.845280;, + -38.257362;-201.972275;59.263458;, + -23.653395;-201.105835;63.411591;, + -25.556084;-324.127594;55.527039;, + -37.508007;-327.823730;63.943375;, + -48.660114;-323.846619;52.634663;, + -43.124073;-327.569916;63.163582;, + -46.985233;-330.924652;60.877213;, + -47.738998;-332.348511;57.905354;, + -48.218380;-333.043976;53.745155;, + -46.926067;-335.870056;46.077358;, + -46.011299;-336.928101;39.876133;, + -39.092888;-333.629852;32.004887;, + -42.781075;-334.302216;33.467194;, + -32.159611;-328.701721;61.163334;, + -32.027699;-330.586823;57.891068;, + -30.829683;-335.353180;51.935188;, + -30.289175;-336.679779;37.674358;, + -33.346500;-333.002716;32.172970;, + -30.620396;-337.228912;46.045479;, + -30.907063;-337.423279;41.478359;, + -30.290890;-334.903290;34.539791;, + -36.497189;-333.552704;31.073109;, + -44.659866;-335.766113;36.478382;, + -37.186310;-327.136566;64.882172;, + -43.760216;-326.861603;63.886238;, + -48.019054;-330.368195;61.125313;, + -48.864738;-331.923981;57.957317;, + -49.377052;-332.709412;53.701771;, + -48.091980;-335.719604;45.783157;, + -47.151276;-336.782074;39.490070;, + -39.525562;-333.437286;30.882923;, + -43.645668;-334.103790;32.636833;, + -31.204782;-328.177948;61.712044;, + -30.816942;-330.532898;57.981380;, + -29.621853;-335.235016;52.022976;, + -29.081070;-336.669037;37.797260;, + -32.739624;-332.828003;31.129665;, + -29.406822;-337.163391;46.021709;, + -29.694448;-337.386993;41.543434;, + -29.145948;-334.835358;34.136993;, + -36.550041;-333.356628;29.870857;, + -45.758202;-335.587708;35.996567;, + -45.427898;-130.595413;48.340775;, + -42.336990;-130.488724;54.945263;, + -37.678047;-130.227783;58.228161;, + -45.523903;-130.013565;42.878948;, + -41.142269;-130.155960;39.554146;, + -24.386381;-143.741119;62.231689;, + -32.621887;-188.625381;36.814716;, + -11.541974;-184.862228;45.883656;, + -41.620197;-179.552460;46.748608;, + -39.826946;-174.615158;38.212673;, + -43.535854;-120.777649;40.070557;, + -22.938877;-119.976494;64.392769;, + -30.902096;-176.652710;61.614151;, + -42.871780;-158.253891;37.723408;, + -36.567158;-119.911232;59.557304;, + -45.200268;-120.584846;49.944744;, + -38.287941;-178.810394;57.081314;, + -27.014326;-159.047546;63.937130;, + -42.580544;-130.073517;38.311958;, + -24.975321;-143.678299;63.863117;, + -43.319576;-179.781570;47.035759;, + -41.500957;-174.797165;37.779552;, + -23.619888;-130.097656;63.516205;, + -38.861588;-164.565750;58.167274;, + -45.622833;-162.561295;47.934299;, + -46.311371;-130.569748;48.698330;, + -38.258266;-130.203033;58.985287;, + -46.929386;-129.807648;42.502537;, + -39.136471;-178.898392;57.512791;, + -43.810833;-129.927979;37.517529;, + -44.150005;-179.891830;47.497341;, + -24.121252;-130.069931;64.903618;, + -43.136353;-130.426819;55.607552;, + -47.307560;-130.516037;48.990032;, + -38.841251;-130.165939;59.846836;, + 0.100870;-113.035980;52.159779;, + -42.175369;-334.770050;70.948944;, + -47.093388;-334.957916;67.363968;, + -35.253540;-336.022400;70.615288;, + -50.392654;-342.841522;46.961720;, + -31.481352;-343.813690;66.423645;, + -14.078679;-70.624992;36.359470;, + 0.100870;-70.522980;34.969410;, + -10.657997;-70.656097;64.141533;, + 0.100870;-70.455383;68.554764;, + -20.407236;-70.663857;37.704983;, + -25.309130;-70.709183;43.680515;, + -20.123388;-70.712914;61.395264;, + -25.333038;-70.735931;56.047955;, + -29.135050;-70.748413;50.137466;, + -3.877978;-63.520813;66.895554;, + -3.855402;-70.482147;66.867348;, + -19.676884;-63.736073;61.580589;, + -19.676886;-63.736065;41.365475;, + -27.052189;-63.743755;51.457161;, + 0.100870;-63.591896;69.324707;, + 0.100870;-63.725189;37.057167;, + -14.884621;-70.698990;35.456879;, + 0.100870;-70.596962;33.974888;, + -11.246261;-70.730103;64.830460;, + 0.100870;-70.535385;69.452461;, + -21.615906;-70.737846;36.711586;, + -26.829739;-70.783180;43.067379;, + -21.313995;-70.786911;61.909431;, + -26.855167;-70.809929;56.221832;, + -30.899126;-70.822411;49.935226;, + -4.034785;-63.594818;67.636086;, + -3.998070;-70.562149;67.711349;, + 0.100870;-63.526737;69.920647;, + 0.100870;-70.464218;70.091736;, + -4.383465;-63.529644;68.232056;, + -4.359452;-70.490974;68.296936;, + -3.386524;-75.591728;67.510147;, + -2.776832;-102.840965;65.045303;, + 0.100870;-80.880516;69.142647;, + 0.100870;-105.710800;64.621178;, + -3.516490;-75.677727;68.364532;, + -2.906797;-102.926964;65.899696;, + -22.798948;-79.832886;31.235064;, + -25.056231;-101.901466;22.759089;, + -26.274025;-98.021988;61.838871;, + -12.963859;-92.037811;25.319746;, + -13.494529;-98.258217;23.341805;, + -14.609492;-108.732101;22.072079;, + -14.476962;-118.111931;22.543592;, + -14.431333;-124.958817;24.257095;, + -14.850490;-137.747299;29.875664;, + -30.438990;-82.029594;36.202908;, + -32.929981;-95.527786;32.765190;, + -12.144010;-151.520721;33.476109;, + -14.428178;-166.866211;34.299915;, + -16.716248;-179.708649;34.860874;, + -32.423717;-145.852829;29.285240;, + -35.720222;-158.855484;33.087280;, + -34.360893;-178.742081;33.996445;, + -9.632311;-81.213554;66.041458;, + -27.866913;-87.057098;57.616055;, + -14.684381;-100.398880;63.420395;, + -19.517466;-85.226929;63.991261;, + -40.065174;-318.672638;64.375366;, + -35.993942;-318.696655;64.690056;, + -31.878841;-318.817719;31.286600;, + -36.170387;-318.762360;30.458429;, + -26.210686;-317.713867;48.030136;, + -25.361750;-319.393433;40.717945;, + -24.732561;-319.150665;36.669399;, + -48.911896;-319.507538;43.118351;, + -47.664860;-317.929291;52.098011;, + -44.133797;-318.262634;57.600853;, + -27.271666;-318.973633;33.779339;, + -40.532146;-318.881866;32.536850;, + -45.276333;-318.965332;34.026871;, + -29.160122;-318.455261;60.501675;, + -26.977306;-318.229187;56.671257;, + -46.791954;-319.251740;38.820690;, + -35.793861;-302.649597;62.947060;, + -26.227007;-302.503235;60.257622;, + -43.178516;-302.253784;56.495960;, + -39.922192;-302.337189;60.689114;, + -44.792736;-300.990540;35.366993;, + -47.422535;-301.286255;40.386948;, + -36.019176;-300.612274;28.811062;, + -32.605831;-300.673798;29.757746;, + -23.851152;-301.120178;37.022240;, + -27.166359;-300.722290;30.436232;, + -23.590527;-301.899200;50.070431;, + -21.858656;-301.316620;40.265823;, + -24.232523;-302.246063;55.899723;, + -48.612350;-301.920135;51.038540;, + -41.315552;-300.854462;32.999699;, + -48.634773;-301.610474;45.850082;, + -40.141144;-255.114700;53.952099;, + -36.110058;-255.272278;56.438984;, + -23.373695;-253.775467;31.533113;, + -30.086535;-252.832504;28.237844;, + -19.459860;-253.800369;31.844227;, + -25.706972;-255.490616;61.349560;, + -17.805582;-255.126160;53.579521;, + -46.995369;-254.835419;49.536797;, + -47.021446;-254.582092;45.376308;, + -46.248730;-254.337875;41.345463;, + -43.542858;-254.140945;38.043243;, + -16.171713;-254.259338;39.300293;, + -14.507923;-254.391815;41.434330;, + -15.366711;-254.579529;44.539597;, + -40.648895;-253.837158;32.980343;, + -36.819706;-253.722290;30.997900;, + -12.445428;-224.292206;47.498665;, + -15.667706;-223.691574;37.720806;, + -18.508575;-223.414154;32.083805;, + -35.438473;-223.276321;30.279057;, + -14.603230;-224.687500;54.050613;, + -24.829622;-225.708954;61.528713;, + -15.676450;-224.947296;58.346878;, + -40.303440;-224.300476;58.010777;, + -46.628914;-224.518768;52.147167;, + -34.276493;-225.076096;60.967789;, + -25.784931;-212.417236;28.070059;, + -27.219553;-222.078049;29.233458;, + -25.575615;-279.096832;57.975468;, + -42.281010;-210.077301;42.464180;, + -12.848580;-215.346298;46.368130;, + -15.573069;-134.748444;59.732529;, + -7.157517;-152.749008;49.893009;, + -23.513350;-142.361069;25.355200;, + -5.245355;-134.035217;49.777805;, + -14.712274;-189.112885;40.448975;, + -16.435289;-199.126770;56.824585;, + 0.100870;-77.831696;33.694950;, + 0.100870;-107.150894;26.804878;, + -13.586044;-80.087227;31.121128;, + 41.958218;-103.151527;46.673912;, + 24.911388;-129.635101;24.771599;, + 18.287577;-112.633553;62.624916;, + 5.996217;-124.775055;56.960815;, + 25.370918;-90.214363;26.265820;, + 38.087563;-84.783722;46.673916;, + 4.856273;-143.854736;42.160900;, + 33.845997;-119.084190;29.032734;, + 19.979677;-86.427544;62.399212;, + 34.072723;-127.515556;35.677750;, + 41.212013;-121.305321;41.175831;, + 15.833360;-212.121994;56.766575;, + 11.869275;-229.887054;44.415504;, + 12.165494;-201.991699;48.101700;, + 34.196323;-220.566040;61.510643;, + 39.726387;-322.910522;59.808895;, + 23.540123;-325.221313;36.655552;, + 35.245861;-213.572937;32.058163;, + 43.311150;-194.904678;46.172497;, + 43.817604;-206.619293;50.933479;, + 46.782749;-323.985016;35.078949;, + 34.906559;-324.151184;32.796345;, + 44.964127;-223.910675;41.391571;, + 13.549516;-168.910248;60.740959;, + 8.374740;-173.738678;44.589821;, + 22.240578;-120.057648;62.105080;, + 30.280094;-176.538696;60.086674;, + 23.550035;-144.066940;25.433426;, + 38.255417;-164.488495;57.655930;, + 25.222740;-183.704147;31.840208;, + 41.438313;-158.109711;38.305462;, + 31.286692;-190.013657;63.028919;, + 27.403559;-198.419037;34.729908;, + 35.324718;-120.041656;57.534676;, + 36.645081;-347.590363;81.989037;, + 33.169540;-348.840668;75.068268;, + 30.681425;-349.513580;64.542366;, + 30.474693;-349.285034;45.291451;, + 30.928658;-349.140839;32.597916;, + 51.193394;-347.566376;80.111809;, + 54.261131;-348.805878;72.346741;, + 53.918003;-349.475220;61.544106;, + 49.678474;-349.253357;42.813526;, + 45.196014;-349.114563;30.769142;, + 37.950394;-344.579834;81.882141;, + 33.835602;-341.897522;75.396339;, + 32.915733;-336.016724;68.786911;, + 25.573301;-326.803894;43.166008;, + 50.599190;-344.387238;80.484764;, + 53.798027;-344.479858;72.777603;, + 52.627678;-341.348145;62.750374;, + 52.204571;-325.347748;41.525669;, + 37.628727;-348.022308;28.784140;, + 31.009497;-349.229279;40.184380;, + 47.776966;-349.201569;38.020821;, + 23.936451;-160.860550;27.560463;, + 32.624580;-277.766174;32.203537;, + 25.141153;-117.940918;21.795738;, + 27.344439;-312.724365;57.102554;, + 42.067356;-312.813507;56.621273;, + 19.971029;-311.714844;51.152798;, + 17.713989;-311.220673;43.257229;, + 53.547699;-311.978485;48.287315;, + 24.745977;-311.052429;38.861851;, + 49.240925;-311.481262;40.787693;, + 36.976662;-311.947937;34.579979;, + 13.642469;-241.724686;43.812695;, + 18.281340;-235.404388;32.990765;, + 39.467758;-235.407135;32.086258;, + 18.907082;-278.846008;51.472931;, + 47.998108;-278.654022;48.696930;, + 15.476175;-278.076508;41.723305;, + 42.921829;-277.794373;38.664387;, + 48.041061;-278.215271;43.605659;, + 37.402847;-278.835236;54.105007;, + 21.920036;-277.300110;35.149902;, + 42.854393;-120.929985;49.355259;, + 17.512936;-184.822891;56.888428;, + 37.200043;-178.638748;55.923824;, + 14.737406;-213.740463;34.164738;, + 28.874565;-235.063934;29.100899;, + 26.487728;-159.034851;62.359303;, + 45.019958;-162.486359;47.417557;, + 26.480961;-192.193863;33.507412;, + 27.477957;-203.100555;31.769531;, + 26.619284;-194.991638;31.950748;, + 25.889118;-188.165451;31.257713;, + 32.750755;-207.822937;62.845276;, + 38.454964;-201.972275;59.263454;, + 23.850996;-201.105820;63.411583;, + 25.753687;-324.127563;55.527039;, + 37.705608;-327.823700;63.943378;, + 48.857719;-323.846619;52.634659;, + 43.321674;-327.569916;63.163586;, + 47.182835;-330.924622;60.877216;, + 47.936604;-332.348511;57.905350;, + 48.415981;-333.043976;53.745152;, + 47.123669;-335.870056;46.077354;, + 46.208900;-336.928101;39.876129;, + 39.290493;-333.629852;32.004887;, + 42.978680;-334.302216;33.467194;, + 32.357216;-328.701721;61.163334;, + 32.225300;-330.586823;57.891064;, + 31.027285;-335.353180;51.935184;, + 30.486776;-336.679749;37.674358;, + 33.544102;-333.002716;32.172966;, + 30.817997;-337.228882;46.045475;, + 31.104664;-337.423279;41.478355;, + 30.488491;-334.903290;34.539787;, + 36.694790;-333.552673;31.073109;, + 44.857464;-335.766083;36.478382;, + 37.383911;-327.136536;64.882172;, + 43.957817;-326.861603;63.886242;, + 48.216656;-330.368195;61.125313;, + 49.062340;-331.923950;57.957314;, + 49.574654;-332.709381;53.701767;, + 48.289585;-335.719604;45.783157;, + 47.348877;-336.782074;39.490070;, + 39.723164;-333.437256;30.882921;, + 43.843269;-334.103760;32.636829;, + 31.402386;-328.177948;61.712044;, + 31.014545;-330.532867;57.981380;, + 29.819454;-335.234985;52.022972;, + 29.278673;-336.669006;37.797256;, + 32.937225;-332.828003;31.129665;, + 29.604424;-337.163391;46.021706;, + 29.892050;-337.386993;41.543430;, + 29.343552;-334.835358;34.136990;, + 36.747643;-333.356598;29.870857;, + 45.955803;-335.587677;35.996567;, + 45.625500;-130.595398;48.340771;, + 42.534595;-130.488724;54.945255;, + 37.875648;-130.227783;58.228153;, + 45.721504;-130.013565;42.878941;, + 41.339870;-130.155960;39.554138;, + 24.583982;-143.741119;62.231686;, + 32.819485;-188.625366;36.814716;, + 11.739574;-184.862213;45.883652;, + 41.817802;-179.552460;46.748608;, + 40.024551;-174.615143;38.212673;, + 43.733459;-120.777641;40.070549;, + 23.136478;-119.976486;64.392761;, + 31.099697;-176.652695;61.614147;, + 43.069382;-158.253876;37.723404;, + 36.764759;-119.911224;59.557301;, + 45.397869;-120.584854;49.944736;, + 38.485538;-178.810379;57.081314;, + 27.211926;-159.047531;63.937126;, + 42.778149;-130.073502;38.311954;, + 25.172922;-143.678284;63.863113;, + 43.517178;-179.781570;47.035755;, + 41.698555;-174.797165;37.779549;, + 23.817490;-130.097641;63.516201;, + 39.059189;-164.565750;58.167271;, + 45.820435;-162.561295;47.934296;, + 46.508972;-130.569733;48.698326;, + 38.455868;-130.203018;58.985283;, + 47.126987;-129.807632;42.502533;, + 39.334072;-178.898392;57.512791;, + 44.008434;-129.927979;37.517525;, + 44.347607;-179.891815;47.497337;, + 24.318851;-130.069931;64.903610;, + 43.333954;-130.426819;55.607544;, + 47.505161;-130.516037;48.990028;, + 39.038853;-130.165924;59.846832;, + 42.372971;-334.770050;70.948944;, + 47.290989;-334.957916;67.363968;, + 35.451141;-336.022369;70.615288;, + 50.590260;-342.841522;46.961720;, + 31.678953;-343.813690;66.423653;, + 14.276281;-70.624985;36.359463;, + 10.855597;-70.656097;64.141525;, + 20.604836;-70.663849;37.704975;, + 25.506731;-70.709175;43.680508;, + 20.320988;-70.712906;61.395260;, + 25.530638;-70.735931;56.047947;, + 29.332651;-70.748413;50.137463;, + 4.075578;-63.520775;66.895554;, + 4.053002;-70.482147;66.867340;, + 19.874485;-63.736065;61.580585;, + 19.874485;-63.736057;41.365467;, + 27.249788;-63.743755;51.457157;, + 15.082223;-70.698982;35.456871;, + 11.443861;-70.730095;64.830460;, + 21.813507;-70.737846;36.711578;, + 27.027336;-70.783173;43.067371;, + 21.511593;-70.786903;61.909428;, + 27.052767;-70.809921;56.221828;, + 31.096729;-70.822411;49.935223;, + 4.232385;-63.594814;67.636078;, + 4.195670;-70.562141;67.711349;, + 4.581065;-63.529640;68.232048;, + 4.557052;-70.490967;68.296928;, + 3.584123;-75.591721;67.510139;, + 2.974431;-102.840958;65.045296;, + 3.714089;-75.677727;68.364525;, + 3.104397;-102.926956;65.899689;, + 22.996550;-79.832886;31.235056;, + 25.253832;-101.901466;22.759085;, + 26.471624;-98.021980;61.838863;, + 13.161459;-92.037811;25.319742;, + 13.692128;-98.258209;23.341801;, + 14.807093;-108.732094;22.072075;, + 14.674563;-118.111923;22.543589;, + 14.628933;-124.958817;24.257090;, + 15.048090;-137.747284;29.875660;, + 30.636589;-82.029587;36.202900;, + 33.127583;-95.527786;32.765182;, + 12.341610;-151.520721;33.476105;, + 14.625778;-166.866196;34.299911;, + 16.913849;-179.708649;34.860870;, + 32.621319;-145.852814;29.285236;, + 35.917824;-158.855484;33.087276;, + 34.558495;-178.742081;33.996445;, + 9.829911;-81.213554;66.041458;, + 28.064514;-87.057091;57.616047;, + 14.881982;-100.398872;63.420387;, + 19.715067;-85.226913;63.991257;, + 40.262775;-318.672607;64.375366;, + 36.191544;-318.696625;64.690056;, + 32.076443;-318.817719;31.286600;, + 36.367989;-318.762360;30.458429;, + 26.408287;-317.713867;48.030132;, + 25.559353;-319.393433;40.717941;, + 24.930161;-319.150635;36.669395;, + 49.109501;-319.507538;43.118351;, + 47.862465;-317.929291;52.098011;, + 44.331398;-318.262634;57.600853;, + 27.469267;-318.973633;33.779335;, + 40.729748;-318.881866;32.536850;, + 45.473934;-318.965332;34.026867;, + 29.357723;-318.455261;60.501675;, + 27.174908;-318.229156;56.671257;, + 46.989555;-319.251740;38.820686;, + 35.991463;-302.649597;62.947060;, + 26.424608;-302.503204;60.257622;, + 43.376122;-302.253784;56.495960;, + 40.119797;-302.337189;60.689114;, + 44.990337;-300.990540;35.366989;, + 47.620136;-301.286255;40.386948;, + 36.216778;-300.612274;28.811060;, + 32.803436;-300.673798;29.757744;, + 24.048756;-301.120178;37.022236;, + 27.363960;-300.722260;30.436230;, + 23.788128;-301.899200;50.070427;, + 22.056257;-301.316620;40.265823;, + 24.430126;-302.246063;55.899719;, + 48.809952;-301.920135;51.038536;, + 41.513157;-300.854462;32.999695;, + 48.832378;-301.610474;45.850079;, + 40.338745;-255.114685;53.952095;, + 36.307659;-255.272247;56.438980;, + 23.571297;-253.775452;31.533110;, + 30.284136;-252.832504;28.237841;, + 19.657463;-253.800369;31.844225;, + 25.904573;-255.490616;61.349560;, + 18.003183;-255.126160;53.579521;, + 47.192974;-254.835419;49.536793;, + 47.219048;-254.582077;45.376305;, + 46.446331;-254.337875;41.345459;, + 43.740459;-254.140930;38.043240;, + 16.369314;-254.259338;39.300289;, + 14.705525;-254.391815;41.434326;, + 15.564311;-254.579514;44.539597;, + 40.846497;-253.837143;32.980343;, + 37.017307;-253.722290;30.997898;, + 12.643028;-224.292191;47.498661;, + 15.865307;-223.691589;37.720802;, + 18.706177;-223.414139;32.083801;, + 35.636074;-223.276321;30.279055;, + 14.800831;-224.687500;54.050610;, + 25.027224;-225.708954;61.528706;, + 15.874051;-224.947296;58.346874;, + 40.501038;-224.300461;58.010777;, + 46.826515;-224.518753;52.147167;, + 34.474094;-225.076096;60.967781;, + 25.982531;-212.417236;28.070055;, + 27.417156;-222.078049;29.233456;, + 25.773218;-279.096802;57.975464;, + 42.478611;-210.077286;42.464176;, + 13.046181;-215.346298;46.368130;, + 15.770669;-134.748428;59.732525;, + 7.355118;-152.749008;49.893005;, + 23.710951;-142.361053;25.355196;, + 5.442955;-134.035202;49.777802;, + 14.909875;-189.112885;40.448971;, + 16.632891;-199.126770;56.824585;, + 13.783645;-80.087219;31.121120;, + -8.380501;25.169817;49.343712;, + 8.527061;25.316885;48.399185;, + 12.786732;-55.480198;44.790428;, + -12.997930;-55.440056;45.084347;, + 60.698940;10.489414;61.040886;, + 59.605530;7.137096;70.365372;, + 36.555004;14.780283;44.255161;, + 50.340195;11.466660;40.450012;, + 77.780144;-0.616348;69.076759;, + 61.100998;-12.097787;52.234310;, + 54.395813;-21.261244;55.889946;, + 42.876431;-10.391958;41.524540;, + 70.006081;2.367340;76.967026;, + 67.389786;-1.205821;78.118034;, + 68.045258;-14.292754;73.173157;, + 78.460449;-9.570584;65.570358;, + 75.694405;-15.631040;66.051804;, + 78.295067;-4.036124;86.370949;, + 87.136154;-19.603304;74.055412;, + 78.082153;2.534071;68.323830;, + 66.419693;-15.575734;72.678177;, + 87.648987;-4.948394;78.487473;, + 77.807617;-19.174520;83.090736;, + 83.368835;-3.849846;82.306015;, + 89.470627;-9.871181;75.022331;, + 69.084702;6.252669;77.456337;, + 64.973396;0.815134;79.337639;, + 80.264275;-7.343033;63.092098;, + 75.774590;-18.309954;63.527412;, + 64.148453;-7.608615;77.332436;, + 73.421997;6.648875;73.774124;, + 83.376282;-20.182905;76.867386;, + 70.002251;-18.073837;68.726471;, + 77.197746;-9.981779;85.393761;, + 80.318741;-7.420647;85.493256;, + 82.789978;-6.610463;83.296829;, + 79.655968;-17.333593;83.765129;, + 79.183868;-11.467402;85.242088;, + 86.196594;-18.624458;77.084518;, + 82.521919;-17.837069;80.497223;, + 86.199554;-6.060757;79.316513;, + 86.261154;-12.489821;78.381943;, + 71.219742;-15.793794;69.989906;, + 66.651627;-8.248512;76.491966;, + 73.890327;2.056242;73.440269;, + 77.791145;1.105025;78.607323;, + 75.326248;1.267426;80.857727;, + 71.689697;-0.853509;83.395920;, + 73.386116;1.385114;82.625687;, + 83.216957;-4.725611;71.840660;, + 84.570229;-9.819118;68.947449;, + 83.728851;-14.435865;68.167923;, + 81.882507;-19.600512;68.102516;, + 77.441238;-19.029276;72.249611;, + 75.713539;-17.538631;74.283043;, + 71.547607;-4.747393;82.232681;, + 71.182411;-7.791823;81.549644;, + 71.304077;-12.113186;80.009758;, + 79.083267;-19.016726;70.790459;, + 80.102303;-1.256049;75.765610;, + 82.761185;-1.128553;73.438354;, + 72.702766;-16.469456;77.320290;, + 98.099678;-15.343760;83.785767;, + 93.154732;-6.980587;90.899246;, + 93.242905;-25.622953;81.159538;, + 114.749481;-29.371605;104.351402;, + 116.328888;-21.406776;103.886078;, + 84.665817;-9.600757;93.965752;, + 92.986916;-29.187506;89.371254;, + 110.432236;-25.897305;108.404945;, + 110.916962;-20.728716;110.111130;, + 87.785217;-19.995790;96.978920;, + 90.982941;-23.993515;93.046989;, + 85.656944;-14.398671;96.109711;, + 93.408386;-29.026354;84.485863;, + 90.449799;-8.323028;93.510162;, + 97.216904;-8.657048;85.987465;, + 97.339188;-20.929985;83.303215;, + 106.770485;-25.673952;93.617485;, + 105.883774;-28.288433;93.625610;, + 107.882225;-22.395979;93.607300;, + 108.385857;-19.427256;94.058815;, + 107.024353;-17.016718;96.046471;, + 102.020210;-15.026966;101.239967;, + 103.800346;-13.394409;100.111961;, + 101.485901;-28.208586;97.676857;, + 103.374771;-29.259912;95.624199;, + 104.934151;-29.521204;94.116104;, + 105.666786;-14.613162;98.028366;, + 100.699852;-25.001989;99.382347;, + 98.765816;-23.374475;101.653488;, + 99.300377;-20.235739;102.128960;, + 99.750626;-17.848330;102.450653;, + 100.601974;-16.327637;102.138657;, + 94.361519;-7.107321;83.677322;, + 90.721161;-5.196348;81.449821;, + 88.812431;-6.982263;88.106316;, + 93.009644;-14.297369;82.089050;, + 45.919392;12.804501;48.821217;, + 67.424805;2.305351;54.072571;, + 51.500221;-7.577340;65.697365;, + 43.626652;11.654449;36.415169;, + 114.547729;-31.794006;101.703148;, + 116.597923;-18.573429;102.008530;, + 106.487419;-27.751755;108.534760;, + 108.661095;-18.210699;110.956673;, + 120.240417;-32.382523;107.405258;, + 120.625252;-22.188108;107.598892;, + 113.002747;-28.165403;111.418968;, + 115.310875;-21.371449;114.672195;, + 128.789810;-29.466074;108.954926;, + 133.926620;-25.436079;121.826721;, + 135.061844;-38.374813;119.353981;, + 132.477707;-23.264696;124.912544;, + 119.123390;-33.322960;112.785774;, + 128.149567;-26.597660;127.790276;, + 118.771370;-29.660498;118.893425;, + 137.268311;-36.747177;118.004539;, + 120.575157;-22.560459;120.307121;, + 119.121994;-28.036406;123.119385;, + 114.274811;-23.003649;117.528297;, + 117.293953;-23.343679;126.162247;, + 115.772141;-28.293201;126.710030;, + 114.847473;-23.354944;126.325142;, + 133.524338;-30.337019;122.600365;, + 131.403183;-26.611431;125.127594;, + 134.824646;-26.838270;122.262741;, + 135.487198;-33.834320;120.160095;, + 130.670029;-24.829245;124.070786;, + 135.851913;-31.051704;118.766632;, + 137.676193;-32.291035;118.807190;, + 136.074463;-28.661200;120.936546;, + 132.979828;-35.570160;121.777008;, + 130.007385;-30.424955;125.430290;, + 128.967941;-28.056011;126.763344;, + 134.236618;-36.868240;120.362709;, + 127.290657;-35.227036;113.798904;, + 123.047722;-33.416660;109.614326;, + 120.623116;-30.226761;117.721672;, + 116.504295;-28.635885;114.683411;, + 129.463760;-23.354002;127.461098;, + 123.396797;-27.431246;121.069450;, + 124.584869;-28.187895;119.902473;, + 121.760422;-25.243605;123.489906;, + 120.613640;-25.185886;123.257240;, + 117.859741;-27.379353;126.710335;, + 116.538414;-28.334110;120.958870;, + 114.465019;-26.505037;126.579056;, + 120.118660;-28.808155;129.262100;, + 115.234482;-28.095364;129.084930;, + 115.773735;-23.653730;128.726898;, + 119.515671;-24.100697;128.185318;, + 117.369904;-31.079527;128.957718;, + 120.607414;-29.430899;132.556305;, + 117.583008;-29.569143;132.374924;, + 118.315994;-26.222034;131.904175;, + 120.763031;-25.726934;131.562943;, + 118.686279;-31.174704;132.509644;, + 120.230301;-29.213165;134.837173;, + 118.653221;-29.758589;134.962555;, + 119.351463;-27.770924;134.521164;, + 120.681877;-27.087921;134.183151;, + 119.078453;-30.474968;135.038971;, + 134.292740;-27.557007;120.420303;, + 133.862167;-25.069214;123.489700;, + 136.922577;-30.224680;119.848274;, + 138.524689;-33.810150;117.661865;, + 131.526566;-21.883783;126.059494;, + 130.900803;-32.067825;124.310493;, + 132.172577;-33.992134;122.873032;, + 132.345215;-26.909451;126.571350;, + 133.379410;-24.327793;126.319145;, + 132.650177;-22.985157;127.267006;, + 130.886734;-24.224178;128.467072;, + 129.605988;-27.135897;128.838928;, + 130.335205;-28.478533;127.891075;, + 133.363693;-27.150629;127.933983;, + 134.300049;-24.941853;127.674355;, + 133.717270;-23.873322;128.430740;, + 132.198166;-25.013567;129.446793;, + 131.015244;-27.552404;129.826096;, + 131.598038;-28.620930;129.069702;, + 134.645630;-27.372400;128.641541;, + 135.366272;-25.452135;128.495346;, + 134.776291;-24.375912;129.259750;, + 133.465668;-25.219961;130.170334;, + 132.745026;-27.140228;130.316544;, + 133.335007;-28.216450;129.552139;, + 135.557129;-28.123676;129.259583;, + 136.419373;-25.779036;129.096115;, + 135.688400;-24.438776;130.044846;, + 134.095200;-25.443157;131.157074;, + 133.232941;-27.787798;131.320541;, + 133.963898;-29.128056;130.371811;, + 136.416260;-29.042286;130.719208;, + 137.311722;-26.758564;130.512604;, + 136.647217;-25.540148;131.375107;, + 135.087219;-26.605450;132.444199;, + 134.191742;-28.889170;132.650787;, + 134.856277;-30.107586;131.788284;, + 137.309525;-29.130545;131.811081;, + 137.970703;-27.438389;131.659988;, + 137.471268;-26.529640;132.306519;, + 136.310669;-27.313053;133.104141;, + 135.649460;-29.005211;133.255219;, + 136.148911;-29.913960;132.608688;, + 138.067566;-29.848610;132.534195;, + 138.751144;-28.014139;132.398666;, + 138.182465;-26.977980;133.135162;, + 136.930222;-27.776287;134.007202;, + 136.246643;-29.610752;134.142715;, + 136.815308;-30.646914;133.406219;, + 138.629425;-30.705997;132.982819;, + 139.286957;-28.643524;132.924973;, + 138.553925;-27.306091;133.874786;, + 137.163391;-28.031139;134.882431;, + 136.505844;-30.093613;134.940262;, + 137.238861;-31.431042;133.990463;, + 139.375854;-31.531094;134.386230;, + 139.871201;-29.845297;134.374817;, + 139.231964;-28.684835;135.201675;, + 138.097382;-29.210182;136.039948;, + 137.602036;-30.895979;136.051376;, + 138.241287;-32.056435;135.224518;, + 140.178970;-31.048899;135.399673;, + 140.418076;-30.152719;135.414230;, + 140.041107;-29.477694;135.899567;, + 139.425034;-29.698851;136.370346;, + 139.185928;-30.595028;136.355789;, + 139.562897;-31.270054;135.870453;, + 140.513062;-30.455763;135.941559;, + 140.258026;-30.001667;136.269287;, + 134.998978;-30.947582;124.347214;, + 136.184570;-27.988020;124.058090;, + 135.348587;-26.448853;125.144691;, + 133.326996;-27.869246;126.520409;, + 131.894867;-31.158863;126.929192;, + 132.730850;-32.698029;125.842598;, + 136.426865;-31.351122;126.151329;, + 137.500275;-28.819027;125.853668;, + 136.832184;-27.594086;126.720772;, + 135.090698;-28.901239;127.885551;, + 134.017303;-31.433332;128.183212;, + 134.685394;-32.658272;127.316093;, + 138.107239;-31.708241;127.158394;, + 138.933365;-29.506886;126.990791;, + 138.257019;-28.273127;127.867088;, + 136.754562;-29.240726;128.910980;, + 135.928421;-31.442081;129.078583;, + 136.604767;-32.675838;128.202286;, + 139.331543;-32.657040;128.033676;, + 140.320007;-29.969194;127.846275;, + 139.482040;-28.432751;128.933884;, + 137.655624;-29.584154;130.208908;, + 136.667160;-32.271999;130.396317;, + 137.505127;-33.808445;129.308701;, + 140.591125;-33.844181;129.962296;, + 141.617676;-31.226170;129.725464;, + 140.855896;-29.829403;130.714218;, + 139.067566;-31.050646;131.939789;, + 138.041000;-33.668652;132.176636;, + 138.802795;-35.065418;131.187897;, + 141.828308;-34.049400;131.412170;, + 142.586258;-32.109543;131.238968;, + 142.013733;-31.067778;131.980133;, + 140.683243;-31.965866;132.894485;, + 139.925278;-33.905720;133.067688;, + 140.497818;-34.947487;132.326523;, + 142.872879;-34.958260;132.404327;, + 143.656509;-32.855263;132.248962;, + 143.004608;-31.667431;133.093292;, + 141.569046;-32.582588;134.092957;, + 140.785416;-34.685585;134.248322;, + 141.437332;-35.873421;133.404007;, + 143.646179;-36.004208;133.038742;, + 144.399963;-33.639832;132.972427;, + 143.559647;-32.106628;134.061264;, + 141.965546;-32.937801;135.216400;, + 141.211761;-35.302185;135.282715;, + 142.052078;-36.835381;134.193878;, + 144.756668;-37.074436;134.884445;, + 145.324524;-35.141872;134.871353;, + 144.591705;-33.811550;135.819244;, + 143.291046;-34.413788;136.780243;, + 142.723190;-36.346355;136.793335;, + 143.456009;-37.676674;135.845428;, + 145.857040;-36.609371;136.213287;, + 146.131134;-35.582005;136.229980;, + 145.699005;-34.808174;136.786362;, + 144.992767;-35.061703;137.326050;, + 144.718674;-36.089062;137.309357;, + 145.150803;-36.862896;136.752975;, + 146.317627;-35.967274;136.906616;, + 146.025253;-35.446705;137.282303;, + 136.889267;-34.388729;121.786079;, + 138.043243;-31.519651;121.509171;, + 137.240128;-30.030424;122.570480;, + 135.283035;-31.410269;123.908699;, + 133.882507;-34.609402;124.305260;, + 134.685638;-36.098633;123.243958;, + 138.202103;-34.760567;123.442123;, + 139.246475;-32.305771;123.156197;, + 138.604645;-31.120579;124.003120;, + 136.918472;-32.390182;125.135963;, + 135.874115;-34.844978;125.421883;, + 136.515945;-36.030170;124.574966;, + 139.771439;-35.090023;124.340836;, + 140.575928;-32.956081;124.181114;, + 139.926163;-31.762369;125.036995;, + 138.471878;-32.702595;126.052612;, + 137.667374;-34.836536;126.212334;, + 138.317154;-36.030251;125.356453;, + 140.906357;-35.995464;125.122398;, + 141.869110;-33.389969;124.944168;, + 141.064072;-31.903385;126.006470;, + 139.296295;-33.022293;127.247002;, + 138.333542;-35.627785;127.425224;, + 139.138565;-37.114368;126.362930;, + 142.050705;-37.125763;126.892921;, + 143.050034;-34.587837;126.666389;, + 142.318192;-33.236397;127.632103;, + 140.587006;-34.422878;128.824356;, + 139.587677;-36.960800;129.050888;, + 140.319519;-38.312241;128.085159;, + 143.191742;-37.308819;128.222427;, + 143.929611;-35.428307;128.056824;, + 143.379562;-34.420353;128.780731;, + 142.091629;-35.292908;129.670227;, + 141.353745;-37.173420;129.835846;, + 141.903809;-38.181374;129.111954;, + 144.154083;-38.176163;129.119446;, + 144.917267;-36.137577;128.971481;, + 144.290955;-34.988300;129.796127;, + 142.901459;-35.877598;130.768753;, + 142.138290;-37.916183;130.916702;, + 142.764603;-39.065464;130.092056;, + 144.865631;-39.179722;129.685654;, + 145.600723;-36.888016;129.624908;, + 144.793411;-35.404579;130.688385;, + 143.251007;-36.212845;131.812622;, + 142.515900;-38.504547;131.873383;, + 143.323227;-39.987988;130.809906;, + 145.871307;-40.198315;131.383316;, + 146.425507;-38.325241;131.373688;, + 145.721451;-37.038101;132.299500;, + 144.463196;-37.624027;133.234940;, + 143.908981;-39.497101;133.244537;, + 144.613022;-40.784241;132.318726;, + 146.890518;-39.734459;132.609009;, + 147.158310;-38.738781;132.626938;, + 146.743103;-37.990078;133.170349;, + 146.060104;-38.237057;133.695831;, + 145.792313;-39.232731;133.677887;, + 146.207520;-39.981438;133.134476;, + 147.317841;-39.106766;133.255463;, + 147.036926;-38.603104;133.622391;, + 138.085999;-37.138863;119.175186;, + 139.090546;-34.734760;118.968651;, + 138.476166;-33.511417;119.918930;, + 136.857193;-34.692177;121.075745;, + 135.606110;-37.426338;121.401924;, + 136.220490;-38.649681;120.451653;, + 139.088989;-37.460236;120.374466;, + 139.994675;-35.402271;120.154755;, + 139.503555;-34.428730;120.913040;, + 138.106750;-35.513153;121.891022;, + 136.954514;-37.901169;122.230385;, + 137.445618;-38.874702;121.472107;, + 140.310577;-37.735165;120.957130;, + 141.014175;-35.948002;120.844086;, + 140.516815;-34.967522;121.610336;, + 139.315872;-35.774200;122.489632;, + 138.612274;-37.561363;122.602676;, + 139.109634;-38.541847;121.836426;, + 141.172485;-38.492016;121.459724;, + 142.015732;-36.310272;121.336426;, + 141.399719;-35.089157;122.287537;, + 139.940460;-36.049793;123.361938;, + 139.097214;-38.231537;123.485237;, + 139.713226;-39.452652;122.534126;, + 142.017715;-39.448486;122.736076;, + 142.888947;-37.322247;122.569550;, + 142.328949;-36.212143;123.434189;, + 140.897690;-37.228283;124.465363;, + 140.026443;-39.354527;124.631889;, + 140.586456;-40.464630;123.767242;, + 142.895447;-39.609592;123.696373;, + 143.538910;-38.034172;123.574936;, + 143.117813;-37.206295;124.223007;, + 142.053253;-37.953835;124.992500;, + 141.409805;-39.529259;125.113930;, + 141.830887;-40.357136;124.465874;, + 143.619232;-40.337288;124.304420;, + 144.287018;-38.630085;124.200493;, + 143.807587;-37.686111;124.938774;, + 142.660355;-38.449345;125.780983;, + 141.992584;-40.156551;125.884911;, + 142.472015;-41.100525;125.146629;, + 144.145706;-41.176258;124.664856;, + 144.796890;-39.259224;124.640663;, + 144.178955;-38.040764;125.592773;, + 142.909821;-38.739342;126.569069;, + 142.258636;-40.656376;126.593254;, + 142.876572;-41.874832;125.641159;, + 144.885223;-42.039631;125.897728;, + 145.379715;-40.473606;125.913101;, + 144.840652;-39.416443;126.741905;, + 143.807114;-39.925308;127.555336;, + 143.312622;-41.491337;127.539970;, + 143.851685;-42.548496;126.711159;, + 145.686615;-41.660812;126.807167;, + 145.927765;-40.828819;126.835564;, + 145.609604;-40.213989;127.321953;, + 145.050308;-40.431152;127.779945;, + 144.809174;-41.263145;127.751549;, + 145.127319;-41.877975;127.265160;, + 146.032715;-41.142326;127.308174;, + 145.817383;-40.728752;127.636574;, + 124.973160;-23.354237;117.701744;, + 130.100662;-32.931473;123.451958;, + 128.472305;-28.867155;125.483269;, + 131.961060;-36.499588;120.635719;, + 130.957870;-35.780834;116.981300;, + 124.282539;-24.769093;125.526192;, + 125.508987;-30.949331;117.392708;, + 127.017143;-25.364244;114.287338;, + 117.540039;-22.350718;100.953659;, + 112.563721;-15.887562;106.469879;, + 110.663788;-31.643456;105.394226;, + 106.306908;-24.835386;110.495728;, + 110.832993;-28.654867;112.050888;, + 110.854927;-23.530939;113.587791;, + 121.598297;-21.157846;106.522896;, + 120.238564;-20.029554;107.979340;, + 114.466507;-18.879122;111.705498;, + 111.886719;-19.639212;113.723465;, + 117.792206;-32.974083;105.142754;, + 119.345352;-28.410704;105.006744;, + 115.554443;-33.065868;107.042320;, + 112.233528;-30.176003;110.656517;, + 33.827938;10.960120;51.807289;, + 39.182789;8.123861;57.134254;, + 39.964428;-10.933758;50.220123;, + 41.310238;-5.151076;57.811226;, + 60.861866;5.824606;48.839558;, + 71.769287;-1.344572;58.966167;, + 52.727615;10.033523;60.222115;, + 48.911415;-16.086357;49.050552;, + 50.863899;-3.190058;44.773193;, + -60.511364;10.489422;61.040886;, + -59.417953;7.137104;70.365372;, + -36.367424;14.780292;44.255165;, + -50.152618;11.466668;40.450016;, + -77.592583;-0.616339;69.076759;, + -60.913422;-12.097776;52.234310;, + -54.208237;-21.261230;55.889942;, + -42.688854;-10.391947;41.524540;, + -69.818512;2.367348;76.967026;, + -67.202217;-1.205813;78.118034;, + -67.857689;-14.292745;73.173157;, + -78.272881;-9.570575;65.570358;, + -75.506836;-15.631029;66.051804;, + -78.107506;-4.036117;86.370941;, + -86.948593;-19.603292;74.055412;, + -77.894592;2.534080;68.323830;, + -66.232124;-15.575725;72.678177;, + -87.461426;-4.948386;78.487473;, + -77.620056;-19.174511;83.090729;, + -83.181274;-3.849838;82.306007;, + -89.283066;-9.871171;75.022331;, + -68.897133;6.252676;77.456337;, + -64.785828;0.815142;79.337639;, + -80.076714;-7.343022;63.092098;, + -75.587021;-18.309942;63.527412;, + -63.960876;-7.608606;77.332436;, + -73.234436;6.648881;73.774124;, + -83.188721;-20.182894;76.867378;, + -69.814682;-18.073826;68.726471;, + -77.010178;-9.981771;85.393753;, + -80.131180;-7.420639;85.493248;, + -82.859459;-6.312282;83.425949;, + -79.468399;-17.333584;83.765121;, + -78.996300;-11.467393;85.242081;, + -86.009033;-18.624449;77.084511;, + -82.334358;-17.837059;80.497215;, + -86.011993;-6.060749;79.316505;, + -86.073555;-12.696040;78.345314;, + -71.032173;-15.793784;69.989906;, + -66.464066;-8.248504;76.491966;, + -73.702766;2.056248;73.440269;, + -77.603577;1.105032;78.607323;, + -75.138687;1.267434;80.857719;, + -71.502121;-0.853501;83.395912;, + -73.198547;1.385122;82.625679;, + -83.029396;-4.725603;71.840660;, + -84.382668;-9.819108;68.947449;, + -83.541290;-14.435856;68.167923;, + -81.694946;-19.600500;68.102516;, + -77.253677;-19.029264;72.249611;, + -75.525970;-17.538622;74.283043;, + -71.360039;-4.747385;82.232674;, + -70.994850;-7.791813;81.549637;, + -71.116508;-12.113177;80.009750;, + -78.895706;-19.016714;70.790459;, + -79.914742;-1.256042;75.765610;, + -82.573624;-1.128545;73.438354;, + -72.515198;-16.469446;77.320282;, + -97.912117;-15.343751;83.785759;, + -92.967171;-6.980580;90.899239;, + -93.055344;-25.622944;81.159531;, + -114.561913;-29.371595;104.351395;, + -116.141319;-21.406767;103.886070;, + -84.478256;-9.600749;93.965744;, + -92.799355;-29.187496;89.371246;, + -110.244675;-25.897297;108.404938;, + -110.729401;-20.728708;110.111122;, + -87.597656;-19.995781;96.978912;, + -90.795380;-23.993507;93.046982;, + -85.469383;-14.398664;96.109703;, + -93.220825;-29.026344;84.485855;, + -90.262238;-8.323020;93.510155;, + -97.029335;-8.657041;85.987457;, + -97.151627;-20.929976;83.303207;, + -106.582924;-25.673943;93.617477;, + -105.696213;-28.288424;93.625603;, + -107.694664;-22.395969;93.607292;, + -108.198296;-19.427246;94.058807;, + -106.836792;-17.016710;96.046463;, + -101.832649;-15.026958;101.239960;, + -103.612785;-13.394403;100.111954;, + -101.298340;-28.208574;97.676849;, + -103.187210;-29.259903;95.624191;, + -104.746590;-29.521194;94.116096;, + -105.479225;-14.613154;98.028358;, + -100.512291;-25.001982;99.382339;, + -98.578255;-23.374466;101.653481;, + -99.112808;-20.235731;102.128952;, + -99.563057;-17.848322;102.450645;, + -100.414413;-16.327629;102.138649;, + -94.173958;-7.107313;83.677315;, + -90.533600;-5.196339;81.449814;, + -88.624870;-6.982255;88.106308;, + -92.822083;-14.297360;82.089043;, + -45.731812;12.804509;48.821217;, + -67.237244;2.305361;54.072567;, + -51.312645;-7.577330;65.697365;, + -43.439075;11.654459;36.415169;, + -114.360168;-31.793995;101.703140;, + -116.410362;-18.573421;102.008522;, + -106.299858;-27.751747;108.534752;, + -108.473534;-18.210691;110.956665;, + -118.763100;-32.416569;106.890343;, + -119.195221;-22.221508;107.119102;, + -112.815208;-28.165394;111.418961;, + -115.208687;-21.985653;115.587814;, + -128.864243;-29.984035;109.850922;, + -133.928619;-25.617853;122.127678;, + -134.985291;-38.562931;119.605125;, + -132.439087;-23.407928;125.120613;, + -118.979370;-33.894085;113.600273;, + -127.981033;-26.736771;127.892494;, + -118.573692;-30.116972;119.482887;, + -137.255630;-36.934776;118.303642;, + -120.451622;-22.976614;120.888481;, + -118.885986;-28.402800;123.534958;, + -114.103012;-23.569595;118.313278;, + -117.037895;-23.683615;126.520027;, + -115.439522;-28.633007;127.009117;, + -114.556931;-23.727386;126.708763;, + -133.461777;-30.497587;122.817970;, + -131.314377;-26.758501;125.303482;, + -134.818481;-26.994595;122.516602;, + -135.449875;-34.009403;120.420280;, + -130.603973;-25.013189;124.323257;, + -135.866348;-31.256813;119.114555;, + -137.701736;-32.465740;119.114777;, + -136.085159;-28.822893;121.211914;, + -132.869873;-35.744339;121.980255;, + -129.858322;-30.577702;125.569275;, + -128.810074;-28.201370;126.883720;, + -134.150055;-37.050697;120.597130;, + -127.220825;-35.652714;114.436562;, + -122.998520;-33.996376;110.515045;, + -120.460487;-30.679323;118.331627;, + -116.345764;-29.216154;115.501526;, + -129.349152;-23.487917;127.596153;, + -123.251488;-27.779137;121.524582;, + -124.463943;-28.541100;120.384758;, + -121.581490;-25.569689;123.884338;, + -120.423470;-25.533827;123.678185;, + -117.563560;-27.690514;126.991264;, + -116.295723;-28.783062;121.501877;, + -114.134766;-26.870768;126.921577;, + -119.802361;-29.029490;129.383438;, + -114.863617;-28.393749;129.288300;, + -115.458870;-23.961578;128.988220;, + -119.253044;-24.363922;128.414917;, + -116.999329;-31.342564;129.104553;, + -120.245399;-29.574646;132.518158;, + -117.182472;-29.760815;132.384308;, + -117.964737;-26.420248;131.961685;, + -120.453552;-25.897451;131.607895;, + -118.282471;-31.343769;132.480225;, + -119.833649;-29.315147;134.705521;, + -118.228737;-29.879900;134.840668;, + -118.961952;-27.895647;134.431473;, + -120.321297;-27.201702;134.097992;, + -118.651398;-30.586836;134.899963;, + -134.298187;-27.758150;120.755005;, + -133.843735;-25.217905;123.721947;, + -136.944122;-30.393238;120.142960;, + -138.562317;-33.993008;117.991791;, + -131.473114;-22.020031;126.245018;, + -130.762848;-32.227257;124.468689;, + -132.052338;-34.158718;123.056244;, + -132.245651;-27.011766;126.667183;, + -133.322495;-24.425945;126.440849;, + -132.583725;-23.077150;127.371544;, + -130.768127;-24.314178;128.528564;, + -129.436584;-27.230442;128.868927;, + -130.175354;-28.579237;127.938255;, + -133.256104;-27.208897;127.952965;, + -134.230194;-24.996719;127.716698;, + -133.639786;-23.923281;128.459366;, + -132.075287;-25.062017;129.438324;, + -130.846466;-27.604633;129.788620;, + -131.436874;-28.678068;129.045944;, + -134.542770;-27.396519;128.609299;, + -135.293900;-25.473001;128.481171;, + -134.696152;-24.391825;129.231689;, + -133.347275;-25.234171;130.110321;, + -132.596161;-27.157688;130.238464;, + -133.193909;-28.238865;129.487946;, + -135.450180;-28.119780;129.179245;, + -136.349197;-25.771114;129.037415;, + -135.608658;-24.424700;129.968933;, + -133.969086;-25.426950;131.042328;, + -133.070053;-27.775614;131.184158;, + -133.810593;-29.122028;130.252640;, + -136.291122;-28.993143;130.552338;, + -137.223816;-26.705677;130.368149;, + -136.550583;-25.481665;131.214996;, + -134.944672;-26.545113;132.246048;, + -134.011978;-28.832579;132.430222;, + -134.685211;-30.056591;131.583374;, + -137.179993;-29.045206;131.582748;, + -137.868683;-27.350267;131.448212;, + -137.362671;-26.437330;132.082977;, + -136.167953;-27.219339;132.852280;, + -135.479263;-28.914282;132.986816;, + -135.985291;-29.827215;132.352036;, + -137.930786;-29.735388;132.255539;, + -138.643372;-27.897797;132.137161;, + -138.067200;-26.856865;132.860275;, + -136.778458;-27.653521;133.701782;, + -136.065872;-29.491106;133.820175;, + -136.642044;-30.532040;133.097046;, + -138.485275;-30.573214;132.667130;, + -139.172653;-28.506882;132.625885;, + -138.429977;-27.163292;133.558441;, + -136.999939;-27.886042;134.532242;, + -136.312576;-29.952375;134.573486;, + -137.055237;-31.295958;133.640945;, + -139.213760;-31.356102;133.989075;, + -139.732437;-29.667019;133.990204;, + -139.084747;-28.501205;134.802032;, + -137.918381;-29.024487;135.612717;, + -137.399704;-30.713572;135.611588;, + -138.047409;-31.879387;134.799774;, + -140.018036;-30.841948;134.952103;, + -140.268936;-29.943945;134.972733;, + -139.886917;-29.265791;135.449203;, + -139.254013;-29.485641;135.905014;, + -139.003113;-30.383642;135.884384;, + -139.385117;-31.061798;135.407928;, + -140.354813;-30.233871;135.472046;, + -140.096344;-29.777664;135.793762;, + -134.925339;-31.048527;124.460655;, + -136.159790;-28.084190;124.201187;, + -135.312897;-26.537964;125.268112;, + -133.231537;-27.956072;126.594505;, + -131.742386;-31.250843;126.968010;, + -132.589279;-32.797073;125.901085;, + -136.342789;-31.392393;126.160988;, + -137.459473;-28.856398;125.890129;, + -136.782639;-27.625828;126.741508;, + -134.989136;-28.931255;127.863777;, + -133.872452;-31.467245;128.134628;, + -134.549286;-32.697823;127.283241;, + -138.027634;-31.702929;127.096672;, + -138.888702;-29.497849;126.949776;, + -138.203445;-28.258413;127.810158;, + -136.657150;-29.224060;128.817413;, + -135.796066;-31.429138;128.964310;, + -136.481308;-32.668583;128.103928;, + -139.246399;-32.613304;127.906013;, + -140.277039;-29.920834;127.743416;, + -139.428085;-28.377333;128.811295;, + -137.548523;-29.526291;130.041809;, + -136.517883;-32.218758;130.204422;, + -137.366837;-33.762257;129.136520;, + -140.483856;-33.738888;129.718903;, + -141.553055;-31.116575;129.507767;, + -140.781296;-29.713392;130.478592;, + -138.940323;-30.932508;131.660553;, + -137.871094;-33.554817;131.871689;, + -138.642868;-34.957996;130.900879;, + -141.714996;-33.895096;131.085495;, + -142.504501;-31.952051;130.931244;, + -141.924408;-30.905476;131.658936;, + -140.554810;-31.801954;132.540863;, + -139.765320;-33.745007;132.695084;, + -140.345413;-34.791569;131.967392;, + -142.750443;-34.765797;132.009415;, + -143.567322;-32.659225;131.873703;, + -142.906815;-31.465914;132.702682;, + -141.429428;-32.379189;133.667358;, + -140.612549;-34.485764;133.803070;, + -141.273041;-35.679066;132.974091;, + -143.514694;-35.784763;132.593597;, + -144.302673;-33.415970;132.546310;, + -143.451279;-31.875710;133.615356;, + -141.811935;-32.704250;134.731705;, + -141.023956;-35.073055;134.778992;, + -141.875320;-36.613304;133.709930;, + -144.603409;-36.797626;134.330566;, + -145.197998;-34.861298;134.331848;, + -144.455490;-33.524841;135.262497;, + -143.118393;-34.124710;136.191864;, + -142.523804;-36.061047;136.190567;, + -143.266312;-37.397495;135.259933;, + -145.704269;-36.289589;135.590790;, + -145.991882;-35.260136;135.614456;, + -145.553955;-34.482719;136.160660;, + -144.828415;-34.734749;136.683197;, + -144.540802;-35.764202;136.659546;, + -144.978714;-36.541618;136.113327;, + -146.167557;-35.627628;136.254303;, + -145.871262;-35.104645;136.623108;, + -136.842163;-34.507912;121.949051;, + -138.043503;-31.634064;121.700676;, + -137.229767;-30.137711;122.742432;, + -135.214676;-31.515200;124.032562;, + -133.758621;-34.719486;124.394966;, + -134.572357;-36.215839;123.353210;, + -138.145432;-34.824940;123.509781;, + -139.231766;-32.366253;123.249680;, + -138.581421;-31.175377;124.080971;, + -136.844757;-32.443195;125.172371;, + -135.758438;-34.901882;125.432487;, + -136.408783;-36.092754;124.601196;, + -139.719559;-35.111778;124.343742;, + -140.557938;-32.974113;124.203918;, + -139.899506;-31.774664;125.043983;, + -138.402664;-32.712887;126.023872;, + -137.564270;-34.850555;126.163696;, + -138.222717;-36.049999;125.323631;, + -140.849487;-35.982155;125.065216;, + -141.853134;-33.372047;124.910805;, + -141.037415;-31.878336;125.953506;, + -139.218048;-32.994740;127.150612;, + -138.214417;-35.604839;127.305016;, + -139.030136;-37.098549;126.262321;, + -141.972977;-37.056030;126.729210;, + -143.013672;-34.513821;126.527390;, + -142.272110;-33.155907;127.475288;, + -140.489838;-34.340195;128.625000;, + -139.449127;-36.882404;128.826813;, + -140.190689;-38.240322;127.878899;, + -143.108612;-37.194061;127.982307;, + -143.877075;-35.310364;127.834953;, + -143.319672;-34.297565;128.545441;, + -141.993790;-35.168465;129.403305;, + -141.225327;-37.052162;129.550674;, + -141.782730;-38.064957;128.840179;, + -144.062485;-38.026543;128.816864;, + -144.857895;-35.984383;128.687775;, + -144.223221;-34.829582;129.497177;, + -142.793137;-35.716938;130.435669;, + -141.997726;-37.759098;130.564743;, + -142.632401;-38.913898;129.755356;, + -144.765549;-39.005554;129.337189;, + -145.533783;-36.709423;129.294647;, + -144.715698;-35.218861;130.338470;, + -143.129379;-36.024429;131.424835;, + -142.361115;-38.320564;131.467377;, + -143.179214;-39.811123;130.423553;, + -145.750641;-39.971535;130.934662;, + -146.330765;-38.094688;130.938782;, + -145.617279;-36.801361;131.847458;, + -144.323669;-37.384869;132.751999;, + -143.743530;-39.261711;132.747849;, + -144.457001;-40.555042;131.839188;, + -146.770706;-39.468060;132.097397;, + -147.051620;-38.470287;132.121964;, + -146.630768;-37.717964;132.655273;, + -145.929031;-37.963417;133.163986;, + -145.648132;-38.961185;133.139404;, + -146.068970;-39.713509;132.606094;, + -147.200821;-38.821938;132.716400;, + -146.916077;-38.315838;133.076492;, + -138.063828;-37.289051;119.406982;, + -139.108231;-34.879868;119.222725;, + -138.484604;-33.648365;120.152847;, + -136.816589;-34.826042;121.267235;, + -135.517487;-37.565662;121.565521;, + -136.141098;-38.797169;120.635399;, + -139.060074;-37.569843;120.535957;, + -140.001053;-35.507759;120.336586;, + -139.502533;-34.527710;121.078781;, + -138.063034;-35.609749;122.020325;, + -136.867325;-38.002270;122.333717;, + -137.365829;-38.982311;121.591530;, + -140.286835;-37.814011;121.073189;, + -141.018921;-36.022858;120.975487;, + -140.514023;-35.035809;121.725449;, + -139.277069;-35.839912;122.573105;, + -138.544998;-37.631069;122.670799;, + -139.049896;-38.618114;121.920837;, + -141.145554;-38.545986;121.533401;, + -142.023148;-36.359291;121.428398;, + -141.397858;-35.130013;122.359329;, + -139.894958;-36.087437;123.395241;, + -139.017365;-38.274132;123.500229;, + -139.642654;-39.503407;122.569305;, + -141.974594;-39.461166;122.731110;, + -142.880615;-37.330349;122.583794;, + -142.312164;-36.212826;123.430077;, + -140.837692;-37.226124;124.423691;, + -139.931671;-39.356945;124.570999;, + -140.500122;-40.474468;123.724709;, + -142.848846;-39.588902;123.635170;, + -143.518021;-38.010078;123.527908;, + -143.090546;-37.176647;124.162201;, + -141.993881;-37.922039;124.903725;, + -141.324722;-39.500870;125.010979;, + -141.752197;-40.334293;124.376701;, + -143.566452;-40.291603;124.198372;, + -144.261322;-38.580566;124.108978;, + -143.774628;-37.630268;124.831566;, + -142.593063;-38.391006;125.643524;, + -141.898178;-40.102051;125.732918;, + -142.384872;-41.052349;125.010338;, + -144.086502;-41.113419;124.526360;, + -144.765533;-39.191589;124.515739;, + -144.138245;-37.964970;125.447609;, + -142.831924;-38.660183;126.390099;, + -142.152893;-40.582008;126.400719;, + -142.780182;-41.808628;125.468857;, + -144.809982;-41.938175;125.684982;, + -145.326218;-40.368050;125.710388;, + -144.778976;-39.303791;126.521545;, + -143.715500;-39.809662;127.307304;, + -143.199249;-41.379795;127.281898;, + -143.746490;-42.444050;126.470741;, + -145.612946;-41.529369;126.547478;, + -145.865082;-40.695091;126.580605;, + -145.542038;-40.076111;127.056602;, + -144.966858;-40.291412;127.499474;, + -144.714737;-41.125694;127.466347;, + -145.037766;-41.744671;126.990349;, + -145.961716;-40.996456;127.027367;, + -145.743073;-40.580086;127.348747;, + -124.935844;-23.758604;118.330032;, + -129.955658;-33.118725;123.649422;, + -128.317764;-29.044809;125.658051;, + -131.844467;-36.710579;120.893005;, + -130.886246;-36.084728;117.422089;, + -124.112961;-25.016518;125.801498;, + -125.407913;-31.335402;117.942909;, + -127.034424;-25.805647;115.016808;, + -117.352478;-22.350708;100.953651;, + -112.376160;-15.887554;106.469872;, + -110.476227;-31.643446;105.394218;, + -106.119347;-24.835379;110.495720;, + -110.645432;-28.654860;112.050880;, + -110.667366;-23.530931;113.587784;, + -120.163315;-21.191313;106.039421;, + -118.809158;-20.062948;107.500015;, + -114.278946;-18.879114;111.705490;, + -111.699158;-19.639204;113.723457;, + -117.604637;-32.974075;105.142746;, + -119.157791;-28.410696;105.006737;, + -115.366882;-33.065861;107.042313;, + -112.045959;-30.175995;110.656509;, + -33.640362;10.960128;51.807285;, + -38.995209;8.123871;57.134251;, + -39.776852;-10.933746;50.220119;, + -41.122662;-5.151066;57.811222;, + -60.674290;5.824616;48.839558;, + -71.581718;-1.344563;58.966167;, + -52.540039;10.033530;60.222115;, + -48.723839;-16.086346;49.050549;, + -50.676323;-3.190047;44.773193;, + -6.262792;13.473364;58.013275;, + 6.173337;13.337016;58.607582;, + -11.545969;16.822830;57.059074;, + 0.138007;12.423479;60.187363;, + 11.825384;16.819580;57.419716;, + -6.266276;13.691039;58.408001;, + 6.169853;13.554691;59.002308;, + 0.057848;95.886368;65.707542;, + 0.057848;97.662560;43.454536;, + 0.057848;90.668213;33.607914;, + 0.057848;73.976425;70.984543;, + 0.057848;63.606403;31.055357;, + 0.057848;99.177589;56.123409;, + 0.057848;84.042374;71.322975;, + 0.057848;75.714500;30.620197;, + 0.057848;53.154804;40.756420;, + -15.043728;50.197842;49.912075;, + -13.469022;92.920013;60.063766;, + -11.461862;93.826927;46.940403;, + -8.418667;86.102859;35.841724;, + -2.182251;64.795692;35.886501;, + -13.655560;74.702049;67.510803;, + -16.338684;73.054062;51.038074;, + -7.371841;73.847633;69.711700;, + -4.494127;83.274292;70.169548;, + -13.097512;71.430748;40.778584;, + -13.263326;61.285336;39.593838;, + -13.865308;81.275604;65.186821;, + -4.402893;95.093262;63.828449;, + -14.668218;94.575356;62.197353;, + -6.418187;97.562218;66.945374;, + -6.403885;85.831749;72.998459;, + -2.904975;98.340385;68.672066;, + -3.096079;86.564301;74.622665;, + -15.709467;82.386459;66.627968;, + -14.238920;86.733635;61.588871;, + -15.816927;87.518616;62.681839;, + -11.518435;84.699326;70.485474;, + -8.635912;82.575844;67.678185;, + -10.775403;96.597122;64.803986;, + -7.852941;94.312172;61.946106;, + -16.338850;66.013954;51.296288;, + -14.718096;68.331589;44.645512;, + -15.784473;69.911873;57.321053;, + -15.528388;63.130802;45.068886;, + -14.675630;70.832016;46.772766;, + -15.347429;57.616409;47.193058;, + -7.149835;52.817856;41.486317;, + -7.580388;47.204636;47.215710;, + -3.355227;56.332371;40.007046;, + -14.710178;77.561653;59.569633;, + -12.242872;104.272034;59.466625;, + -13.871002;106.867241;51.713676;, + -6.555738;100.376198;26.176455;, + -10.330755;93.744308;22.167315;, + -25.391743;66.042480;44.113369;, + -20.371532;85.581749;31.614416;, + -3.509032;68.824097;16.563112;, + -16.921518;68.428406;22.861071;, + -23.283691;91.554054;44.497189;, + -22.312506;78.019226;58.252476;, + -5.355029;81.806320;13.441270;, + -6.858363;107.464165;38.205128;, + -1.630455;58.319656;15.177998;, + -19.439602;55.002464;25.954828;, + -14.163750;71.116005;45.658489;, + -16.339277;34.462788;24.538301;, + -3.199738;106.311531;63.356800;, + -7.285188;105.334877;61.411713;, + -19.911991;74.556313;27.957836;, + -23.002449;68.454033;35.866280;, + -23.994633;83.695297;38.363724;, + -21.688162;63.338444;39.264874;, + -21.994913;54.244259;32.219749;, + -11.261707;52.068916;45.952110;, + -6.553079;49.986835;18.220219;, + -13.583147;45.560303;22.582418;, + -3.504504;39.875324;20.493166;, + -24.415617;69.041245;50.481827;, + -15.101998;82.440125;58.401062;, + -4.228397;103.816078;53.739082;, + -10.791362;101.190048;49.992683;, + -11.328189;101.622627;54.213688;, + -2.042533;104.242516;48.194424;, + -2.467957;102.354828;41.462799;, + -5.581229;102.438309;43.389084;, + -2.102569;101.711769;35.092808;, + -5.357594;98.838608;34.631802;, + -2.575568;97.464630;31.897514;, + -9.509275;96.133217;33.318790;, + -6.373484;96.717354;29.011164;, + -8.609506;92.094917;28.785583;, + -0.961346;89.876480;22.612808;, + -3.750705;87.223274;24.470808;, + -1.293535;83.343231;22.908096;, + -7.475338;76.444283;20.933500;, + -7.155903;71.146484;21.280985;, + -4.020619;75.279213;22.110722;, + -1.186798;66.427330;20.374010;, + -1.050320;61.116470;21.804775;, + -3.120998;63.629890;20.392683;, + -6.236067;57.664822;24.799372;, + -3.291713;57.533966;22.859617;, + -4.431494;55.146961;25.181421;, + -2.515443;47.986980;22.845200;, + -2.247637;45.361992;27.063856;, + -3.458311;46.185818;25.952394;, + -15.542780;91.786743;39.028736;, + -15.098378;89.391930;35.078747;, + -16.682585;85.833199;39.137646;, + -15.960197;80.988068;32.730686;, + -17.451015;78.322830;36.557224;, + -16.864700;74.552986;34.352123;, + -13.662128;75.346954;26.811104;, + -13.099884;69.581734;27.209919;, + -14.475806;72.210419;29.167706;, + -16.048969;64.284309;32.004520;, + -14.420856;61.870514;29.131302;, + -16.221205;60.286003;31.238237;, + -14.534574;44.794735;26.116779;, + -14.848799;44.863647;29.381424;, + -13.599534;41.942635;29.015915;, + -10.621090;54.617325;25.569170;, + -8.996603;52.321831;27.760847;, + -10.189517;51.242924;27.917196;, + -17.834475;94.101349;53.041599;, + -17.518343;94.489967;48.203121;, + -19.293009;90.274719;49.298183;, + -19.945814;88.506752;43.413734;, + -18.563108;84.403915;43.736874;, + -21.033463;85.001541;44.282993;, + -23.027826;71.019249;46.561157;, + -21.556767;69.493790;46.926170;, + -23.674259;69.104668;47.675011;, + -22.533089;73.345596;50.339439;, + -21.038176;75.381149;55.902035;, + -21.679085;72.997261;52.478176;, + -19.307541;61.902699;35.872772;, + -18.916523;58.344765;35.077782;, + -19.290819;59.542400;38.422955;, + -8.277215;99.647781;59.143467;, + -2.250754;97.063629;60.111290;, + -1.262086;99.482384;60.521812;, + -4.202026;99.742661;59.680969;, + -1.779861;73.225479;71.214066;, + -17.854918;48.596111;35.240131;, + -17.187716;41.811371;40.273598;, + 15.159414;50.197842;49.912075;, + 13.584708;92.920013;60.063766;, + 11.577548;93.826927;46.940403;, + 8.534353;86.102859;35.841724;, + 2.297937;64.795692;35.886501;, + 13.771247;74.702049;67.510803;, + 16.454370;73.054062;51.038074;, + 7.487527;73.847633;69.711700;, + 4.609814;83.274292;70.169548;, + 13.213199;71.430748;40.778584;, + 13.379013;61.285336;39.593838;, + 13.980994;81.275604;65.186821;, + 4.518579;95.093262;63.828449;, + 14.783904;94.575356;62.197353;, + 6.533874;97.562218;66.945374;, + 6.519572;85.831749;72.998459;, + 3.020661;98.340385;68.672066;, + 3.211765;86.564301;74.622665;, + 15.825153;82.386459;66.627968;, + 14.354607;86.733635;61.588871;, + 15.932613;87.518616;62.681839;, + 11.634122;84.699326;70.485474;, + 8.751598;82.575844;67.678185;, + 10.891089;96.597122;64.803986;, + 7.968627;94.312172;61.946106;, + 16.454536;66.013954;51.296288;, + 14.833782;68.331589;44.645512;, + 15.900160;69.911873;57.321053;, + 15.644074;63.130802;45.068886;, + 14.791316;70.832016;46.772766;, + 15.463116;57.616409;47.193058;, + 7.265521;52.817856;41.486317;, + 7.696074;47.204636;47.215710;, + 3.470914;56.332371;40.007046;, + 14.825865;77.561653;59.569633;, + 12.358559;104.272034;59.466625;, + 13.986689;106.867241;51.713676;, + 6.671424;100.376198;26.176455;, + 10.446442;93.744308;22.167315;, + 25.507429;66.042480;44.113369;, + 20.487219;85.581749;31.614416;, + 3.624719;68.824097;16.563112;, + 17.037205;68.428406;22.861071;, + 23.399378;91.554054;44.497189;, + 22.428192;78.019226;58.252476;, + 5.470715;81.806320;13.441270;, + 6.974050;107.464165;38.205128;, + 1.746141;58.319656;15.177998;, + 19.555288;55.002464;25.954828;, + 14.279436;71.116005;45.658489;, + 16.454964;34.462788;24.538301;, + 3.315424;106.311531;63.356800;, + 7.400875;105.334877;61.411713;, + 20.027678;74.556313;27.957836;, + 23.118135;68.454033;35.866280;, + 24.110319;83.695297;38.363724;, + 21.803848;63.338444;39.264874;, + 22.110600;54.244255;32.219749;, + 11.377394;52.068913;45.952110;, + 6.668766;49.986835;18.220219;, + 13.698833;45.560303;22.582418;, + 3.620190;39.875320;20.493166;, + 24.531303;69.041245;50.481827;, + 15.217685;82.440125;58.401062;, + 4.344084;103.816078;53.739082;, + 10.907048;101.190048;49.992683;, + 11.443875;101.622627;54.213688;, + 2.158219;104.242516;48.194424;, + 2.583643;102.354828;41.462799;, + 5.696916;102.438309;43.389084;, + 2.218256;101.711769;35.092808;, + 5.473281;98.838608;34.631802;, + 2.691255;97.464630;31.897514;, + 9.624962;96.133217;33.318790;, + 6.489170;96.717354;29.011164;, + 8.725192;92.094917;28.785583;, + 1.077032;89.876480;22.612808;, + 3.866392;87.223274;24.470808;, + 1.409221;83.343231;22.908096;, + 7.591025;76.444283;20.933500;, + 7.271590;71.146484;21.280985;, + 4.136305;75.279213;22.110722;, + 1.302485;66.427330;20.374010;, + 1.166007;61.116470;21.804775;, + 3.236684;63.629890;20.392683;, + 6.351754;57.664822;24.799372;, + 3.407399;57.533966;22.859617;, + 4.547181;55.146961;25.181421;, + 2.631130;47.986980;22.845200;, + 2.363323;45.361992;27.063856;, + 3.573997;46.185818;25.952394;, + 15.658466;91.786743;39.028736;, + 15.214065;89.391930;35.078747;, + 16.798271;85.833199;39.137646;, + 16.075884;80.988068;32.730686;, + 17.566702;78.322830;36.557224;, + 16.980387;74.552986;34.352123;, + 13.777815;75.346954;26.811104;, + 13.215570;69.581734;27.209919;, + 14.591493;72.210419;29.167706;, + 16.164656;64.284309;32.004520;, + 14.536543;61.870514;29.131302;, + 16.336891;60.286003;31.238237;, + 14.650260;44.794735;26.116779;, + 14.964485;44.863644;29.381424;, + 13.715221;41.942635;29.015915;, + 10.736776;54.617321;25.569170;, + 9.112289;52.321831;27.760847;, + 10.305203;51.242924;27.917196;, + 17.950161;94.101349;53.041599;, + 17.634029;94.489967;48.203121;, + 19.408695;90.274719;49.298183;, + 20.061501;88.506752;43.413734;, + 18.678795;84.403915;43.736874;, + 21.149149;85.001541;44.282993;, + 23.143513;71.019249;46.561157;, + 21.672453;69.493790;46.926170;, + 23.789946;69.104668;47.675011;, + 22.648775;73.345596;50.339439;, + 21.153862;75.381149;55.902035;, + 21.794771;72.997261;52.478176;, + 19.423227;61.902699;35.872772;, + 19.032209;58.344765;35.077782;, + 19.406506;59.542400;38.422955;, + 8.392901;99.647781;59.143467;, + 2.366440;97.063629;60.111290;, + 1.377773;99.482384;60.521812;, + 4.317712;99.742661;59.680969;, + 1.895548;73.225479;71.214066;, + 17.970604;48.596111;35.240131;, + 17.303402;41.811371;40.273598;, + 0.438559;57.282112;73.561638;, + 0.736964;56.934887;73.321701;, + 0.356253;56.468140;73.264908;, + -0.240559;56.468140;73.264908;, + -0.621271;56.934887;73.321701;, + -0.322864;57.282112;73.561638;, + -0.248436;71.854645;70.729988;, + 0.364132;71.854645;70.729988;, + 0.758169;70.963852;70.525764;, + 0.451886;70.057053;70.373367;, + -0.336191;70.057053;70.373360;, + -0.642476;70.963852;70.525764;, + 0.364132;73.351379;70.952026;, + -0.248436;73.351379;70.952026;, + 0.455698;61.693325;71.893539;, + 0.836409;60.952618;72.164238;, + 0.438559;60.724323;72.609840;, + -0.322864;60.724323;72.609840;, + -0.720715;60.952618;72.164238;, + -0.340003;61.693325;71.893539;, + -0.322864;59.615437;73.646515;, + 0.438559;59.615437;73.646515;, + 0.438559;58.736450;73.878487;, + -0.322864;58.736450;73.878487;, + -0.945781;48.617813;70.123962;, + -2.236765;48.914082;70.144196;, + -1.083371;49.222790;70.673294;, + -0.230488;49.179218;70.678032;, + 0.346183;49.179218;70.678032;, + 1.199065;49.222790;70.673294;, + 2.352458;48.914082;70.144196;, + 1.061476;48.617813;70.123962;, + 1.061476;46.043205;70.763565;, + 1.061476;45.315922;70.631477;, + -0.945781;45.315922;70.631477;, + -0.945781;46.043205;70.763565;, + -0.230488;50.744427;71.911613;, + 0.346183;50.744427;71.911613;, + 0.346183;50.290668;71.732040;, + -0.230488;50.290668;71.732040;, + 0.681346;41.262371;69.549492;, + 1.304843;39.983742;69.127930;, + 0.681345;39.288811;68.917770;, + -0.565651;39.288811;68.917770;, + -1.189150;39.983742;69.127930;, + -0.565651;41.262371;69.549492;, + -1.460927;43.933510;69.011917;, + -1.841057;44.861637;69.288826;, + -0.945781;45.001892;69.606239;, + 1.061476;45.001892;69.606239;, + 1.956750;44.861637;69.288826;, + 1.576620;43.933510;69.011917;, + 0.681346;43.309490;69.095680;, + -0.565651;43.309490;69.095680;, + 0.346183;51.987255;71.326790;, + 0.346183;51.362129;71.498451;, + -0.230488;51.362129;71.498451;, + -0.230488;51.987255;71.326790;, + -0.230488;53.243740;71.207901;, + -0.693861;53.723915;71.140991;, + -0.405525;54.361668;71.150101;, + 0.521220;54.361668;71.150101;, + 0.809554;53.723915;71.140991;, + 0.346183;53.243740;71.207901;, + -1.009302;55.219082;71.714081;, + -1.025449;55.481266;71.933746;, + -0.720078;55.895855;72.229713;, + -0.240559;56.053364;72.471550;, + 0.356253;56.053364;72.471550;, + 0.835771;55.895855;72.229713;, + 1.141142;55.481266;71.933746;, + 1.124995;55.219086;71.714081;, + 0.521220;55.117058;71.726410;, + -0.405525;55.117058;71.726410;, + -0.565651;38.742027;59.643063;, + 0.681345;38.742027;59.643063;, + 2.217954;38.776661;57.910744;, + 2.867495;39.371185;54.783699;, + 1.330886;37.590916;54.064663;, + -1.215191;37.590916;54.064663;, + -2.751802;39.371185;54.783699;, + -2.102260;38.776661;57.910744;, + -0.510998;50.219196;39.523888;, + 0.626693;50.219196;39.523888;, + -1.873620;26.054764;52.140381;, + -1.215191;29.188606;52.544262;, + 1.330886;29.188606;52.544262;, + 1.989312;26.054764;52.140381;, + 2.234568;33.522697;35.402046;, + 0.565745;37.216824;36.971302;, + -0.450050;37.216824;36.971302;, + -2.118875;33.522697;35.402046;, + -0.565651;37.436687;67.317482;, + 0.681345;37.436687;67.317482;, + 0.681345;37.195446;65.010315;, + -0.565651;37.195446;65.010315;, + -2.538574;41.449165;68.624062;, + -2.951183;40.302361;68.035011;, + -4.628216;39.976799;65.832298;, + -5.649843;41.666725;65.621597;, + -4.822110;42.776821;67.453926;, + -3.387875;42.233704;68.253677;, + -15.066837;51.644341;50.761562;, + -13.959147;50.054565;53.477966;, + -13.171544;47.816036;53.537487;, + -12.819518;47.844864;50.501919;, + -14.464008;51.746117;48.798912;, + -15.310171;52.496346;49.328674;, + -14.314348;64.191902;63.807819;, + -13.928720;63.485863;64.339012;, + -13.572276;62.304844;64.865723;, + -13.167170;61.067101;65.229462;, + -12.962619;58.564976;64.792267;, + -13.533698;58.152863;63.610909;, + -14.547876;60.533600;62.358631;, + -14.767531;62.889500;62.645046;, + -16.389227;56.612152;48.529644;, + -16.521999;56.337196;48.919449;, + -16.561354;57.052597;49.445042;, + -16.542124;57.916912;49.540932;, + -16.326410;58.083145;50.780964;, + -15.837441;56.684170;51.706242;, + -15.670477;54.844639;50.363594;, + -16.045902;55.654251;48.952625;, + -13.866287;76.274246;65.799950;, + -12.180278;74.145042;67.802490;, + -13.091559;73.365410;66.984734;, + -13.743665;72.909081;66.356583;, + -14.234488;73.032753;65.109230;, + -14.186148;74.380287;64.488983;, + -16.565777;71.776100;50.947868;, + -16.808704;72.864502;50.189095;, + -16.304464;72.598770;49.611454;, + -12.345559;69.888283;65.738831;, + -12.326240;69.568321;65.742271;, + -12.347851;69.289749;65.733955;, + -12.479330;68.737000;65.669327;, + -12.625326;68.411827;65.535583;, + -12.699836;68.129967;65.442223;, + -13.074884;67.260254;64.888390;, + -13.514962;67.960876;64.396080;, + -13.290691;70.147194;64.970589;, + -12.663944;70.601143;65.617447;, + -3.217402;61.792000;69.916451;, + -2.825095;61.031200;70.194847;, + -3.213592;59.684910;70.235397;, + -3.662069;58.804951;70.155693;, + -3.857313;58.498222;70.159554;, + -4.142841;58.239128;70.071960;, + -4.253828;58.105072;69.919785;, + -3.673181;58.191391;69.761742;, + -4.503674;59.898464;69.912605;, + -3.921128;61.008068;69.727730;, + -3.192633;55.084583;70.448547;, + -3.111558;54.744785;70.582428;, + -2.385719;54.680038;70.815506;, + -1.792563;54.532791;70.915924;, + -2.092454;53.903660;70.912537;, + -2.919086;53.404095;70.938629;, + -3.321806;54.305473;70.619545;, + -6.250182;49.317669;69.504501;, + -6.446180;48.549271;69.168564;, + -8.014235;48.270035;68.304420;, + -8.714692;50.122650;68.182167;, + -7.801420;51.763470;68.922615;, + -6.904962;50.679249;69.380814;, + -5.370491;51.804302;70.890030;, + -4.524282;52.698963;71.277252;, + -4.071008;51.834652;71.563766;, + -3.656876;50.892254;71.572784;, + -4.722633;50.442741;71.028595;, + -6.934566;47.145229;68.633385;, + -5.329893;47.425457;69.456062;, + -3.966182;46.793549;69.870453;, + -3.938172;46.091690;69.693321;, + -4.855957;46.051064;69.184097;, + -6.488640;46.472694;68.538559;, + -1.098645;50.973583;71.694138;, + -1.950218;51.124405;71.635803;, + -2.407137;52.052967;71.641159;, + -1.563598;52.530037;71.605721;, + -1.096965;52.051891;71.685753;, + -1.088933;51.424000;71.779518;, + -13.021915;53.488663;61.239902;, + -14.041900;55.868359;59.989929;, + -14.138645;57.389984;61.303249;, + -13.118661;55.010292;62.553223;, + -9.482656;49.163662;66.510292;, + -8.739838;47.333950;66.631050;, + -8.364165;46.637093;66.527420;, + -8.016644;45.674202;66.296745;, + -8.580020;44.714546;64.299896;, + -10.489306;46.236229;61.293800;, + -11.341558;48.442810;61.255726;, + -11.017628;49.345627;63.166481;, + -11.104903;50.871937;64.476662;, + -10.609887;51.240044;65.681923;, + -1.474512;58.398350;72.686012;, + -1.812058;58.122028;72.386444;, + -2.271988;58.206673;72.014107;, + -2.493294;58.257072;71.856972;, + -2.453580;58.564266;71.700531;, + -2.337840;58.869293;71.594749;, + -1.884961;59.340534;71.866264;, + -1.441849;59.261425;72.428749;, + -1.509435;57.558842;72.547653;, + -1.134018;57.032932;72.596863;, + -1.626426;56.943577;72.311104;, + -2.118178;57.221329;72.202080;, + -2.053061;57.660461;72.258942;, + -2.506476;58.943634;70.957291;, + -2.665209;58.656223;71.097099;, + -2.901366;58.531845;70.941536;, + -3.059159;58.630623;70.641769;, + -2.838635;58.924690;70.598763;, + -5.702873;55.781525;69.312447;, + -5.801723;57.970192;69.387802;, + -5.111734;58.670830;69.693558;, + -3.983715;58.045750;69.612915;, + -4.088572;57.287357;69.743599;, + -4.068023;56.821293;69.814964;, + -3.812485;56.347786;69.903954;, + -3.917183;55.572304;70.041840;, + -4.834018;54.668350;69.775490;, + -4.255816;56.976295;70.144569;, + -4.259132;57.438969;70.049438;, + -4.196453;57.593311;70.295357;, + -4.135692;57.244923;70.552475;, + -4.206871;56.894928;70.444580;, + -3.591207;57.666695;71.185127;, + -3.783044;57.561813;70.960518;, + -3.836649;57.893749;70.692024;, + -3.568345;58.165226;70.788643;, + -3.408157;58.065258;71.087090;, + -3.712499;55.370281;70.761353;, + -3.470078;55.416473;71.000565;, + -2.839330;55.237701;71.154488;, + -2.822697;54.988895;70.923553;, + -3.522735;55.051468;70.611397;, + -4.155221;56.153671;70.536667;, + -4.015416;55.782383;70.614700;, + -3.834426;55.439445;70.483299;, + -3.917668;55.755974;70.291489;, + -4.162768;56.246273;70.237022;, + -3.360456;57.598080;71.641861;, + -3.439125;57.720852;71.496246;, + -3.251950;58.117050;71.396477;, + -3.021049;58.246376;71.555511;, + -3.085086;57.947788;71.731819;, + -2.968136;57.499275;71.833702;, + -2.706439;57.428493;71.961281;, + -2.801483;56.969940;71.952415;, + -3.146882;56.789368;71.787590;, + -3.226831;57.136875;71.731987;, + -2.680634;56.379002;72.014671;, + -2.158215;56.120026;72.073334;, + -2.463775;55.692970;71.788239;, + -3.104754;55.851723;71.649239;, + -3.019568;56.201847;71.837547;, + -3.854640;56.847206;71.126411;, + -3.682065;56.967865;71.362190;, + -3.578869;56.835163;71.491699;, + -3.497496;56.487053;71.543762;, + -3.592218;56.139133;71.357254;, + -3.813043;56.122169;71.094490;, + -3.932611;56.500839;71.012955;, + -2.244552;60.233025;70.703400;, + -1.543128;60.758423;71.142464;, + -1.905732;59.838963;71.250046;, + -2.362187;59.370174;70.980934;, + -2.702353;59.358711;70.627777;, + -5.869700;72.868355;69.812210;, + -6.693674;72.552437;69.361465;, + -7.883108;73.155823;69.069405;, + -9.038418;73.717834;68.902939;, + -8.692574;68.018349;68.671463;, + -8.338293;68.821220;68.766014;, + -7.113932;68.489220;68.942162;, + -6.934299;67.847763;68.938004;, + -7.729776;67.687729;68.801422;, + -6.369604;71.293625;68.760429;, + -6.266792;70.787079;68.649055;, + -7.456227;71.390457;68.356995;, + -7.559039;71.897003;68.468361;, + -8.883052;64.549225;67.816406;, + -7.739773;64.507843;68.125893;, + -6.938856;64.740326;68.286102;, + -6.703542;64.155365;68.361183;, + -6.983939;63.322628;68.406448;, + -7.766936;63.148247;68.257492;, + -8.915951;63.725613;67.823822;, + -9.511546;64.526329;67.588211;, + -5.015405;68.108635;68.910416;, + -4.548992;67.765022;68.960190;, + -3.810864;67.410515;69.067841;, + -3.841677;66.485794;69.114601;, + -4.796024;65.666992;68.895134;, + -5.041750;66.255524;68.850845;, + -4.661049;66.762360;68.945168;, + -5.034431;67.060791;68.905960;, + -5.210155;67.702225;68.891853;, + -13.971161;79.561020;64.637955;, + -16.624105;67.403618;50.887012;, + -16.565861;68.256042;51.076977;, + -16.246441;65.836792;52.110813;, + -16.461342;64.238647;50.971241;, + -16.518333;64.809113;50.940807;, + -16.347895;65.639847;50.705421;, + -16.240040;66.024963;50.538170;, + -16.346189;66.463646;50.675999;, + -15.224072;69.450462;45.349747;, + -15.760094;69.213470;44.900475;, + -15.382089;67.644539;44.621346;, + -15.250605;71.985199;59.394108;, + -15.298944;70.637657;60.014355;, + -15.658424;68.405617;58.417435;, + -15.881517;67.001724;56.228691;, + -15.969252;67.785751;55.123196;, + -15.787234;65.044144;44.833035;, + -16.311890;64.137360;44.826756;, + -15.985520;62.777939;45.304832;, + -15.565753;61.898857;45.735703;, + -17.476997;71.515564;49.979080;, + -17.666685;72.283302;49.454979;, + -17.496593;72.551018;49.791622;, + -17.235834;71.461693;50.544392;, + -17.321030;70.610649;50.363503;, + -17.721493;64.826424;44.666374;, + -17.617994;63.963326;44.954117;, + -17.641233;62.991528;45.373825;, + -17.702808;62.384628;45.580582;, + -17.503719;62.235477;45.405041;, + -17.214645;62.635960;45.039047;, + -17.454624;64.026939;44.611488;, + -17.486305;67.273705;44.342857;, + -16.981884;68.189659;44.315788;, + -17.319111;69.740105;44.662109;, + -17.795025;70.146683;45.105915;, + -17.665180;69.380302;44.897526;, + -17.693687;68.057755;44.480789;, + -17.367353;55.732864;49.276451;, + -17.603033;56.078396;49.090916;, + -17.605160;56.805744;49.610336;, + -17.369478;56.460213;49.795868;, + -15.472936;71.487747;47.478798;, + -15.202838;70.700668;46.413372;, + -17.537380;72.607475;48.042797;, + -17.718521;72.353806;47.703808;, + -17.632210;72.075851;47.314693;, + -17.704372;71.657677;46.520592;, + -17.298006;71.305359;45.955624;, + -16.765556;71.583923;46.387459;, + -17.031307;72.320404;47.474106;, + -17.602358;59.477318;47.236622;, + -17.394125;59.880875;47.002865;, + -17.477081;61.053162;46.572697;, + -17.674273;61.202515;46.749283;, + -17.736586;60.467724;47.270435;, + -16.183525;61.853733;46.266216;, + -16.565636;61.401821;46.549980;, + -16.432093;60.244560;47.006794;, + -16.018494;59.781609;47.083752;, + -15.774214;60.941624;46.644413;, + -17.282442;56.325546;47.880959;, + -17.057690;55.958496;48.038124;, + -16.647417;56.352184;47.652000;, + -16.585321;57.122021;47.273716;, + -17.001896;57.588127;47.207531;, + -17.288742;57.185337;47.428646;, + -15.462021;56.205631;47.969166;, + -14.615860;55.455399;47.439404;, + -15.475274;59.141663;46.797791;, + -15.730730;57.946342;47.180832;, + -15.798254;57.165806;47.545010;, + -8.445348;40.588070;59.654636;, + -7.278510;39.094028;59.898464;, + -6.654146;38.770531;57.926445;, + -7.458086;40.307079;54.648247;, + -9.828319;42.345741;53.625164;, + -10.191217;42.303234;56.659534;, + -4.566577;37.981155;65.199509;, + -3.095984;38.031998;67.529678;, + -2.411773;37.506966;67.308975;, + -2.439468;37.185844;65.011452;, + -3.987151;37.529453;63.242748;, + -7.714421;47.308811;43.157204;, + -8.049258;44.606380;41.254444;, + -6.923997;49.765636;40.291908;, + -7.906905;51.757496;43.185513;, + -5.034308;41.098293;49.664669;, + -5.924514;37.964451;49.232517;, + -7.618621;39.077587;48.033279;, + -7.929698;44.502201;46.021900;, + -8.122182;48.950886;46.050209;, + -9.087849;46.348259;49.153736;, + -6.570920;44.494156;50.192978;, + -9.377964;32.507309;43.848045;, + -8.752393;35.209740;45.489132;, + -7.924005;29.785124;47.506119;, + -6.942506;32.835922;36.246323;, + -7.997331;36.389206;37.566708;, + -9.269050;31.085709;38.438145;, + -5.026693;51.522896;39.552273;, + -3.825413;48.113850;38.322987;, + -2.217535;51.807980;39.149200;, + -5.770691;27.953976;51.289192;, + -4.258096;26.840841;52.409973;, + -14.393597;77.704041;61.829361;, + -14.713458;75.810089;60.518398;, + -9.962842;51.383026;45.418407;, + -12.572998;52.681652;46.818928;, + -11.410388;71.412788;66.828568;, + -11.823878;72.111282;66.787140;, + -10.865562;72.920639;67.524742;, + -9.757876;72.328529;67.772369;, + -9.662718;71.817146;67.674042;, + -10.356916;71.710754;67.467834;, + -12.698816;64.099892;66.268402;, + -13.037525;65.302979;65.766319;, + -12.597655;66.151749;66.249695;, + -11.851852;65.260712;66.830208;, + -11.350214;64.474258;67.163437;, + -11.757308;64.162216;67.085007;, + -6.766061;66.263695;68.781013;, + -6.216946;66.492447;68.869522;, + -5.420580;66.654190;68.999702;, + -5.795310;66.145882;68.879105;, + -6.606440;65.917046;68.748558;, + -3.320212;69.375824;69.355331;, + -3.709178;68.309135;68.969109;, + -4.438835;68.674232;68.849876;, + -4.890217;69.410423;68.822868;, + -4.989970;69.919693;68.927238;, + -4.149621;70.250198;69.340469;, + -10.614668;69.347672;67.888069;, + -10.116972;69.031830;68.220833;, + -10.474522;68.229591;68.132561;, + -11.167147;67.985580;67.780556;, + -11.836740;68.545883;67.245644;, + -11.641810;69.105743;67.264893;, + -6.151947;45.663696;67.791992;, + -4.526884;45.235153;68.449783;, + -4.146754;44.288376;68.208298;, + -5.771818;44.716919;67.550507;, + -10.450169;70.821953;67.907776;, + -9.765457;70.555244;68.220161;, + -10.446616;70.475075;67.861671;, + -11.461811;70.225883;67.223770;, + -11.484657;70.544380;67.228043;, + -7.470517;71.123924;68.610703;, + -6.279786;70.515015;68.889984;, + -5.857738;69.792030;69.041931;, + -6.325098;70.114395;68.970451;, + -7.503110;70.711578;68.750259;, + -8.226480;70.998123;68.542450;, + -11.757306;66.061752;67.182938;, + -12.601673;66.949631;66.694183;, + -12.539265;67.224754;66.799522;, + -11.842525;66.625931;67.309013;, + -11.209784;66.065163;67.525764;, + -8.280282;65.338531;68.297150;, + -9.418466;65.381676;67.974045;, + -10.128361;65.908348;67.834045;, + -9.527828;65.743866;67.987259;, + -8.435413;65.687355;68.321404;, + -5.819896;67.066292;68.770218;, + -5.441578;66.767700;68.786415;, + -6.236395;66.607925;68.646599;, + -6.614712;66.906517;68.630394;, + -11.348783;70.134789;66.847923;, + -10.339741;70.382629;67.493866;, + -10.382211;70.102104;67.500931;, + -11.391253;69.854263;66.854988;, + -6.542440;69.634361;68.798340;, + -7.746741;69.958893;68.556709;, + -8.281987;70.288345;68.319221;, + -8.238889;70.568634;68.310120;, + -7.507647;70.645966;68.558647;, + -6.346445;70.041153;68.809387;, + -11.501963;67.061974;67.315300;, + -11.152501;66.503914;67.438225;, + -11.688239;66.665207;67.208046;, + -12.363090;67.291313;66.688377;, + -12.188178;67.618729;66.799240;, + -8.220766;66.419502;68.373581;, + -7.848414;66.116623;68.406441;, + -8.381545;65.898521;68.278526;, + -9.477689;65.951813;67.955978;, + -9.894917;66.509720;67.920815;, + -9.171124;66.759315;68.210503;, + -17.429979;70.690262;47.136501;, + -17.300325;71.068329;47.941162;, + -17.023735;70.899750;48.289326;, + -16.861496;70.700005;48.118645;, + -16.944355;70.155487;47.524551;, + -17.236248;69.977158;46.890572;, + -17.226145;68.629349;45.660595;, + -16.823431;68.867996;46.195717;, + -16.729546;68.371811;45.875668;, + -16.873161;67.340813;45.524662;, + -17.105501;66.543564;45.306343;, + -17.364603;67.335907;45.122231;, + -17.210119;64.694969;45.653248;, + -16.824369;65.503990;45.698051;, + -16.693214;64.944427;45.835949;, + -16.865488;63.931744;46.212234;, + -17.217360;63.707901;46.045494;, + -17.257675;62.592293;47.044037;, + -16.951664;62.847736;47.248653;, + -16.837200;62.523624;47.585892;, + -16.968355;61.957218;48.121510;, + -17.261364;61.378471;48.161098;, + -17.422873;61.297504;47.813133;, + -17.417713;61.989571;47.233940;, + -17.641174;59.537712;47.829380;, + -17.572170;59.655956;48.204098;, + -17.551355;59.356380;48.625698;, + -17.610889;58.393185;48.722862;, + -17.640314;57.667088;48.205170;, + -17.649786;58.512043;47.733288;, + -17.048664;58.888443;50.137520;, + -17.266785;59.234547;49.939693;, + -17.237478;60.194298;49.885609;, + -17.031002;61.167274;50.192562;, + -16.847815;61.964878;50.507847;, + -16.794952;61.394268;50.541176;, + -16.881783;59.817486;50.241066;, + -16.520054;67.426628;49.977383;, + -16.340061;67.565254;49.576904;, + -16.329565;67.737488;49.665955;, + -16.615074;68.525681;49.726234;, + -16.931223;69.285706;49.834728;, + -16.825703;68.358887;50.174931;, + -17.551683;71.775742;48.843681;, + -17.362616;71.012024;49.371750;, + -16.936705;70.317307;49.319000;, + -16.958307;70.820000;49.096962;, + -17.196766;71.293510;48.824539;, + -17.364233;71.554535;48.518509;, + -16.104570;66.411118;49.371330;, + -15.935796;66.244766;48.838696;, + -15.850468;66.336823;48.616936;, + -15.866637;66.633751;48.735458;, + -16.035194;66.980598;49.101681;, + -16.187799;66.850029;49.515789;, + -16.126511;65.664818;49.415100;, + -16.190468;65.289612;49.597702;, + -16.041357;65.036949;49.353294;, + -15.899192;65.163132;49.153240;, + -15.851497;65.262131;48.876595;, + -15.929707;65.511154;48.894043;, + -16.490780;64.863365;50.058357;, + -16.720278;64.048309;50.266247;, + -16.791843;63.235886;49.945076;, + -16.568014;63.725044;49.778568;, + -16.373796;64.287704;49.843987;, + -16.368130;64.613602;49.802601;, + -17.217245;60.928139;48.799614;, + -16.907705;61.495392;48.765743;, + -16.815966;61.430393;48.922810;, + -16.765753;61.620747;49.208321;, + -16.750641;62.064793;49.391998;, + -17.015625;61.599758;49.547829;, + -17.299763;60.700314;49.200974;, + -15.614582;65.022964;47.637421;, + -15.567803;65.459961;48.141235;, + -15.567249;65.398903;48.325111;, + -15.481506;65.150154;48.319054;, + -15.194538;65.020020;48.325905;, + -14.993324;64.845505;48.207409;, + -15.239534;64.746971;48.103077;, + -15.478746;64.410210;48.011654;, + -15.595269;64.437210;47.602276;, + -15.577514;66.367973;47.512394;, + -15.587451;66.170380;48.126865;, + -15.597684;65.873161;48.000294;, + -15.594285;65.462585;47.465916;, + -15.623907;65.954384;47.004478;, + -16.163324;69.702736;47.006084;, + -16.325090;70.179176;47.432697;, + -16.250225;70.720009;48.027470;, + -15.931003;70.309883;48.304401;, + -15.873635;69.724388;47.707878;, + -15.683133;67.779671;46.594791;, + -15.731870;67.422462;46.281384;, + -15.854837;66.999779;45.793983;, + -16.054199;66.752342;45.468372;, + -16.222563;67.364136;45.404732;, + -16.119137;68.397461;45.749371;, + -15.815002;68.405243;46.444931;, + -16.121750;63.590012;46.468613;, + -16.268213;63.939720;46.142395;, + -16.091532;64.937843;45.725086;, + -15.811086;65.184181;46.013538;, + -15.725762;64.678902;46.459305;, + -15.859744;64.082863;46.497070;, + -15.926024;62.989491;47.503284;, + -15.843936;62.895470;47.927868;, + -15.889503;62.652355;48.086254;, + -15.987683;62.236328;48.207397;, + -16.216883;61.851406;48.240868;, + -16.364000;61.953060;48.036350;, + -16.214388;62.510639;47.489380;, + -15.595205;68.402351;48.685631;, + -15.764951;68.966614;49.253052;, + -15.941114;69.119171;49.475651;, + -15.975425;68.539047;49.658321;, + -15.736507;67.748260;49.593555;, + -15.532450;67.764122;48.843464;, + -16.346699;71.171959;48.547527;, + -16.586071;71.314072;48.751896;, + -16.308315;70.874519;49.045010;, + -16.068941;70.732407;48.840641;, + -15.518588;67.185043;48.375042;, + -15.668723;67.181129;49.142185;, + -15.708892;66.982887;49.023090;, + -15.584141;66.642441;48.652946;, + -15.499434;66.834618;48.047215;, + -15.092333;64.988647;49.170685;, + -14.719754;65.032219;48.968830;, + -15.088419;65.204224;48.722855;, + -15.558498;65.271629;48.793575;, + -15.560716;65.164146;49.081577;, + -15.725241;64.271202;49.771698;, + -15.177734;64.013451;49.696068;, + -14.787019;64.137657;49.657894;, + -15.119205;64.553688;49.607170;, + -15.572768;64.774559;49.574314;, + -15.788092;64.616272;49.700668;, + -15.866501;61.957813;49.102505;, + -16.104591;61.579231;49.139591;, + -16.162405;61.394108;48.852608;, + -15.924313;61.772690;48.815525;, + -15.717142;63.853062;48.277557;, + -15.248356;64.229958;48.236816;, + -14.928309;64.044220;48.320805;, + -15.315211;63.808681;48.458256;, + -15.750184;63.597157;48.425735;, + -15.838925;62.957794;48.812828;, + -15.734231;63.319706;48.668522;, + -15.316200;63.570396;48.738605;, + -15.018495;63.530445;48.836395;, + -15.316642;63.369987;49.007088;, + -15.719042;63.048027;49.053600;, + -15.980401;62.618446;49.327629;, + -15.722883;62.949089;49.349140;, + -15.299875;63.228001;49.333504;, + -14.944921;63.170467;49.313648;, + -15.276262;63.393970;49.504761;, + -15.797068;63.623280;49.678589;, + -16.084009;63.113098;49.537724;, + -13.713379;64.330490;47.964046;, + -14.052535;64.570992;47.942337;, + -13.642416;64.727051;47.977783;, + -13.303260;64.486542;47.999493;, + -13.622803;64.867424;48.405872;, + -13.966632;65.018639;48.594540;, + -13.617676;64.821175;48.841949;, + -13.268164;64.565086;48.723537;, + -13.279479;64.634613;48.428219;, + -13.639128;64.418907;49.285206;, + -13.985892;64.368164;49.509857;, + -13.685705;63.932621;49.534199;, + -13.345568;63.706188;49.357521;, + -13.317171;63.849289;49.209923;, + -13.310544;64.126472;49.161942;, + -13.407900;63.991501;48.212700;, + -13.378046;63.842590;48.457138;, + -13.448744;63.599464;48.515327;, + -13.854336;63.502201;48.416882;, + -14.191032;63.583447;48.318527;, + -13.815295;63.829620;48.172535;, + -13.448471;63.334648;48.762100;, + -13.445812;63.215389;48.942604;, + -13.849804;63.106457;48.948494;, + -14.219306;63.163155;48.878448;, + -13.859849;63.274899;48.680103;, + -13.760653;63.319157;49.397713;, + -14.160416;63.179287;49.390675;, + -13.826283;62.948902;49.207973;, + -13.426521;63.088772;49.215008;, + -14.635970;54.643333;55.040348;, + -14.147105;54.452450;57.104122;, + -13.158237;52.062576;58.359673;, + -13.383351;51.207062;56.417542;, + -14.475186;52.802021;53.698296;, + -15.304926;68.186958;61.412601;, + -14.881803;70.420540;62.992817;, + -14.420024;70.296165;64.247795;, + -14.572822;68.117760;63.612282;, + -15.007770;66.809219;62.450409;, + -15.942458;60.483253;55.162083;, + -15.911017;62.698605;56.534737;, + -15.702338;64.100548;58.725273;, + -15.429958;62.728092;59.776882;, + -15.204959;60.373241;59.487785;, + -15.173355;58.842800;58.182579;, + -15.579103;59.052357;56.106335;, + -16.138069;62.572739;52.645168;, + -16.264805;60.348454;51.283993;, + -16.459799;60.184284;50.041332;, + -16.446999;61.758488;50.400814;, + -16.268988;63.355892;51.544556;, + -10.984770;59.171497;67.685600;, + -10.020209;59.249851;68.473320;, + -8.955151;58.376186;68.852272;, + -8.749995;56.214470;68.792267;, + -9.638556;54.576092;68.034088;, + -10.808270;56.659454;67.306381;, + -2.919356;66.059219;69.545708;, + -2.935508;67.427605;69.470802;, + -2.918927;68.351173;69.428009;, + -2.480527;69.424149;69.710426;, + -1.804423;69.821587;69.985138;, + -1.545340;68.905617;69.955627;, + -2.229242;66.840546;69.764442;, + -0.336191;68.430237;70.273201;, + 0.451886;68.430237;70.273201;, + 1.170602;66.378647;70.287239;, + 0.776565;65.605095;70.453270;, + -0.660870;65.605095;70.453270;, + -1.054910;66.378647;70.287239;, + -0.340003;62.900276;71.266731;, + -1.058722;62.556232;71.091965;, + -0.660870;63.757217;70.827621;, + 0.776565;63.757217;70.827621;, + 1.174414;62.556232;71.091965;, + 0.455698;62.900276;71.266731;, + -1.167291;72.975906;71.066788;, + -1.561331;72.093285;70.835541;, + -2.229468;71.696121;70.544289;, + -3.073710;72.557281;70.563393;, + -4.494940;62.101410;69.479050;, + -5.105907;62.962933;69.143433;, + -4.820986;63.796482;69.076340;, + -3.863764;64.606781;69.322395;, + -3.894372;63.243977;69.496239;, + -5.328853;60.484348;69.611397;, + -6.107750;61.054867;69.396408;, + -6.771271;62.188259;69.118797;, + -5.982145;62.362251;69.253105;, + -5.354429;61.491180;69.538467;, + -8.287384;62.278648;68.682831;, + -7.628970;61.197292;69.140694;, + -8.336544;60.522438;69.069862;, + -9.515740;61.319351;68.567192;, + -9.953496;62.560196;68.243744;, + -9.432715;62.866348;68.253067;, + -11.047081;62.546486;67.962914;, + -10.617968;61.313049;68.317123;, + -11.533367;61.247047;67.476128;, + -11.962482;62.480480;67.121918;, + 2.654264;41.449165;68.624062;, + 3.503563;42.233704;68.253677;, + 4.937797;42.776821;67.453926;, + 5.765529;41.666725;65.621597;, + 4.743902;39.976799;65.832298;, + 3.066870;40.302361;68.035011;, + 14.579695;51.746113;48.798912;, + 12.935205;47.844864;50.501919;, + 13.287230;47.816036;53.537487;, + 14.074833;50.054565;53.477966;, + 15.182524;51.644341;50.761562;, + 15.425858;52.496346;49.328674;, + 14.663563;60.533600;62.358627;, + 13.649384;58.152863;63.610909;, + 13.078305;58.564976;64.792267;, + 13.282856;61.067101;65.229462;, + 13.687963;62.304844;64.865723;, + 14.044406;63.485863;64.339012;, + 14.430035;64.191902;63.807819;, + 14.883218;62.889500;62.645046;, + 15.786164;54.844639;50.363594;, + 15.953128;56.684170;51.706242;, + 16.442099;58.083145;50.780964;, + 16.657810;57.916912;49.540932;, + 16.677040;57.052597;49.445042;, + 16.637686;56.337196;48.919449;, + 16.504915;56.612152;48.529644;, + 16.161591;55.654251;48.952625;, + 14.350174;73.032753;65.109230;, + 13.859351;72.909081;66.356583;, + 13.207247;73.365410;66.984734;, + 12.295963;74.145042;67.802490;, + 13.981975;76.274246;65.799950;, + 14.301835;74.380287;64.488983;, + 16.420151;72.598770;49.611454;, + 16.924391;72.864502;50.189095;, + 16.681463;71.776100;50.947868;, + 13.406377;70.147194;64.970589;, + 13.630649;67.960876;64.396080;, + 13.190571;67.260254;64.888390;, + 12.815522;68.129967;65.442223;, + 12.741013;68.411827;65.535583;, + 12.595016;68.737000;65.669327;, + 12.463537;69.289749;65.733955;, + 12.441926;69.568321;65.742271;, + 12.461246;69.888283;65.738831;, + 12.779631;70.601143;65.617447;, + 4.619360;59.898464;69.912605;, + 3.914352;58.191391;69.761742;, + 4.369514;58.105072;69.919785;, + 4.258527;58.239124;70.071960;, + 3.973000;58.498222;70.159554;, + 3.777756;58.804951;70.155693;, + 3.329280;59.684910;70.235397;, + 2.940784;61.031204;70.194847;, + 3.333090;61.791996;69.916451;, + 4.036814;61.008068;69.727730;, + 3.034772;53.404091;70.938629;, + 2.208143;53.903660;70.912537;, + 1.908253;54.532791;70.915924;, + 2.501408;54.680038;70.815506;, + 3.227245;54.744785;70.582428;, + 3.308319;55.084583;70.448547;, + 3.437492;54.305473;70.619545;, + 7.917106;51.763470;68.922615;, + 8.830380;50.122650;68.182167;, + 8.129922;48.270035;68.304428;, + 6.561869;48.549271;69.168564;, + 6.365870;49.317665;69.504501;, + 7.020649;50.679249;69.380814;, + 5.486177;51.804302;70.890030;, + 4.838321;50.442738;71.028595;, + 3.772563;50.892250;71.572784;, + 4.186694;51.834652;71.563766;, + 4.639969;52.698963;71.277252;, + 4.971645;46.051064;69.184097;, + 4.053861;46.091690;69.693321;, + 4.081872;46.793549;69.870453;, + 5.445580;47.425457;69.456062;, + 7.050251;47.145229;68.633385;, + 6.604327;46.472694;68.538559;, + 1.214336;50.973583;71.694138;, + 1.204623;51.423996;71.779518;, + 1.212656;52.051891;71.685745;, + 1.679286;52.530037;71.605721;, + 2.522823;52.052967;71.641159;, + 2.065906;51.124401;71.635803;, + 13.137602;53.488663;61.239902;, + 13.234347;55.010292;62.553223;, + 14.254332;57.389984;61.303249;, + 14.157586;55.868359;59.989929;, + 11.220590;50.871937;64.476662;, + 11.133315;49.345627;63.166481;, + 11.457245;48.442810;61.255726;, + 10.604994;46.236229;61.293800;, + 8.695706;44.714546;64.299896;, + 8.132330;45.674198;66.296745;, + 8.479852;46.637093;66.527420;, + 8.855523;47.333950;66.631050;, + 9.598343;49.163662;66.510292;, + 10.725574;51.240044;65.681923;, + 1.590202;58.398350;72.686012;, + 1.557539;59.261425;72.428749;, + 2.000650;59.340534;71.866264;, + 2.453526;58.869293;71.594749;, + 2.569266;58.564266;71.700531;, + 2.608980;58.257072;71.856972;, + 2.387675;58.206673;72.014107;, + 1.927747;58.122028;72.386436;, + 1.625123;57.558842;72.547653;, + 2.168747;57.660461;72.258942;, + 2.233865;57.221329;72.202080;, + 1.742114;56.943577;72.311104;, + 1.249707;57.032932;72.596863;, + 3.174846;58.630623;70.641769;, + 3.017052;58.531845;70.941544;, + 2.780896;58.656223;71.097099;, + 2.622163;58.943634;70.957291;, + 2.954322;58.924690;70.598763;, + 4.032869;55.572304;70.041840;, + 3.928171;56.347786;69.903954;, + 4.183709;56.821293;69.814964;, + 4.204257;57.287357;69.743599;, + 4.099401;58.045750;69.612915;, + 5.227420;58.717506;69.747047;, + 5.917409;57.970192;69.387802;, + 5.818560;55.781525;69.312447;, + 4.949705;54.668350;69.775490;, + 4.251379;57.244923;70.552475;, + 4.312139;57.593311;70.295357;, + 4.374818;57.438969;70.049438;, + 4.371503;56.976295;70.144569;, + 4.322558;56.894928;70.444588;, + 3.706894;57.666695;71.185127;, + 3.523844;58.065258;71.087090;, + 3.684032;58.165226;70.788643;, + 3.952336;57.893749;70.692024;, + 3.898730;57.561813;70.960518;, + 3.828186;55.370281;70.761353;, + 3.638421;55.051468;70.611397;, + 2.938384;54.988895;70.923553;, + 2.955018;55.237701;71.154488;, + 3.585764;55.416473;71.000565;, + 4.270908;56.153671;70.536667;, + 4.278454;56.246273;70.237022;, + 4.033355;55.755974;70.291489;, + 3.950112;55.439445;70.483299;, + 4.131103;55.782383;70.614700;, + 3.476142;57.598080;71.641861;, + 3.200772;57.947784;71.731819;, + 3.136734;58.246376;71.555511;, + 3.367636;58.117046;71.396477;, + 3.554811;57.720852;71.496246;, + 3.262567;56.789368;71.787590;, + 2.917169;56.969940;71.952415;, + 2.822125;57.428493;71.961281;, + 3.083823;57.499275;71.833702;, + 3.342518;57.136875;71.731987;, + 3.220440;55.851723;71.649239;, + 2.579464;55.692970;71.788246;, + 2.273904;56.120026;72.073334;, + 2.796321;56.379002;72.014671;, + 3.135255;56.201847;71.837547;, + 3.928730;56.122169;71.094490;, + 3.707905;56.139133;71.357254;, + 3.613183;56.487053;71.543762;, + 3.694555;56.835163;71.491699;, + 3.797751;56.967865;71.362190;, + 3.970327;56.847206;71.126411;, + 4.048297;56.500839;71.012955;, + 2.477874;59.370174;70.980934;, + 2.021420;59.838963;71.250046;, + 1.658818;60.758423;71.142464;, + 2.360240;60.233025;70.703400;, + 2.818039;59.358707;70.627777;, + 5.985386;72.868355;69.812210;, + 9.154104;73.717827;68.902939;, + 7.998795;73.155823;69.069405;, + 6.809360;72.552437;69.361465;, + 7.049986;67.847763;68.938004;, + 7.229618;68.489220;68.942162;, + 8.453979;68.821220;68.766014;, + 8.808260;68.018349;68.671463;, + 7.845464;67.687729;68.801422;, + 6.485291;71.293625;68.760429;, + 7.674726;71.897003;68.468361;, + 7.571912;71.390457;68.356995;, + 6.382478;70.787079;68.649055;, + 9.031637;63.725613;67.823822;, + 7.882623;63.148247;68.257492;, + 7.099626;63.322628;68.406448;, + 6.819228;64.155365;68.361183;, + 7.054543;64.740326;68.286102;, + 7.855459;64.507843;68.125900;, + 8.998738;64.549225;67.816406;, + 9.627233;64.526329;67.588211;, + 5.131092;68.108627;68.910416;, + 5.325842;67.702225;68.891853;, + 5.150118;67.060791;68.905960;, + 4.776736;66.762360;68.945175;, + 5.157436;66.255524;68.850845;, + 4.911710;65.666992;68.895134;, + 3.957364;66.485794;69.114601;, + 3.926550;67.410515;69.067841;, + 4.664679;67.765022;68.960190;, + 14.086849;79.561020;64.637955;, + 16.739792;67.403618;50.887012;, + 16.461876;66.463646;50.675999;, + 16.355726;66.024963;50.538170;, + 16.463581;65.639847;50.705421;, + 16.634022;64.809120;50.940807;, + 16.577030;64.238647;50.971241;, + 16.362127;65.836792;52.110813;, + 16.681547;68.256050;51.076977;, + 15.875778;69.213470;44.900475;, + 15.339758;69.450462;45.349747;, + 14.734314;69.212395;45.168884;, + 15.497775;67.644539;44.621346;, + 15.366291;71.985199;59.394108;, + 16.084938;67.785751;55.123196;, + 15.997204;67.001724;56.228691;, + 15.774111;68.405617;58.417435;, + 15.414630;70.637657;60.014355;, + 15.681439;61.898857;45.735703;, + 16.101208;62.777939;45.304836;, + 16.427576;64.137360;44.826752;, + 15.902921;65.044144;44.833035;, + 17.351522;71.461693;50.544392;, + 17.612280;72.551018;49.791622;, + 17.782373;72.283302;49.454979;, + 17.592686;71.515564;49.979080;, + 17.436718;70.610649;50.363503;, + 17.837181;64.826424;44.666374;, + 17.570311;64.026939;44.611488;, + 17.330330;62.635960;45.039047;, + 17.619406;62.235477;45.405041;, + 17.818495;62.384628;45.580582;, + 17.756922;62.991528;45.373825;, + 17.733683;63.963326;44.954117;, + 17.780867;69.380302;44.897526;, + 17.910711;70.146683;45.105915;, + 17.434797;69.740105;44.662109;, + 17.097572;68.189659;44.315792;, + 17.601992;67.273705;44.342861;, + 17.809376;68.057755;44.480789;, + 17.720846;56.805744;49.610336;, + 17.718719;56.078396;49.090916;, + 17.483042;55.732864;49.276451;, + 17.485168;56.460213;49.795868;, + 14.713079;70.462608;46.232510;, + 15.318524;70.700668;46.413372;, + 15.588622;71.487747;47.478798;, + 17.653069;72.607475;48.042797;, + 17.146994;72.320404;47.474106;, + 16.881243;71.583923;46.387459;, + 17.413694;71.305359;45.955624;, + 17.820061;71.657677;46.520592;, + 17.747896;72.075859;47.314693;, + 17.834208;72.353806;47.703804;, + 17.718044;59.477318;47.236622;, + 17.852270;60.467724;47.270435;, + 17.789957;61.202515;46.749283;, + 17.592766;61.053162;46.572697;, + 17.509811;59.880875;47.002865;, + 16.299212;61.853733;46.266216;, + 15.889900;60.941624;46.644413;, + 16.134180;59.781609;47.083752;, + 16.547779;60.244560;47.006794;, + 16.681320;61.401821;46.549984;, + 17.117582;57.588127;47.207531;, + 16.701010;57.122021;47.273716;, + 16.763103;56.352184;47.652000;, + 17.173376;55.958496;48.038124;, + 17.398129;56.325546;47.880959;, + 17.404427;57.185337;47.428650;, + 15.577708;56.205627;47.969166;, + 15.913940;57.165806;47.545010;, + 15.846416;57.946342;47.180832;, + 15.590961;59.141663;46.797791;, + 14.731544;55.455399;47.439404;, + 9.944007;42.345741;53.625164;, + 7.573774;40.307079;54.648247;, + 6.769834;38.770535;57.926445;, + 7.394196;39.094028;59.898464;, + 8.561033;40.588070;59.654636;, + 10.306905;42.303234;56.659534;, + 2.555157;37.185844;65.011452;, + 2.527462;37.506966;67.308975;, + 3.211673;38.031998;67.529678;, + 4.682263;37.981155;65.199509;, + 4.102839;37.529453;63.242748;, + 7.830108;47.308811;43.157204;, + 8.022593;51.757496;43.185513;, + 7.039683;49.765636;40.291908;, + 8.164946;44.606380;41.254444;, + 9.203535;46.348259;49.153736;, + 8.237869;48.950886;46.050209;, + 8.045384;44.502201;46.021900;, + 7.734308;39.077587;48.033279;, + 6.040202;37.964451;49.232517;, + 5.149999;41.098293;49.664669;, + 6.686608;44.494156;50.192978;, + 8.039693;29.785124;47.506119;, + 8.868079;35.209740;45.489132;, + 9.493651;32.507309;43.848045;, + 9.384735;31.085709;38.438145;, + 8.113016;36.389206;37.566708;, + 7.058194;32.835922;36.246323;, + 5.142379;51.522896;39.552273;, + 2.333225;51.807980;39.149200;, + 3.941101;48.113850;38.322987;, + 4.373784;26.840841;52.409973;, + 5.886379;27.953976;51.289192;, + 14.509283;77.704041;61.829361;, + 14.829144;75.810089;60.518398;, + 14.457141;70.604607;45.675373;, + 12.688684;52.681652;46.818928;, + 10.078528;51.383022;45.418407;, + 9.778404;71.817146;67.674042;, + 9.873562;72.328529;67.772369;, + 10.981249;72.920631;67.524742;, + 11.939566;72.111282;66.787140;, + 11.526075;71.412788;66.828560;, + 10.472603;71.710754;67.467834;, + 12.814504;64.099892;66.268402;, + 11.872994;64.162216;67.085007;, + 11.465900;64.474258;67.163437;, + 11.967539;65.260712;66.830208;, + 12.713342;66.151749;66.249695;, + 13.153212;65.302979;65.766319;, + 5.910997;66.145882;68.879105;, + 5.536267;66.654190;68.999702;, + 6.332633;66.492447;68.869522;, + 6.881747;66.263695;68.781013;, + 6.722126;65.917046;68.748558;, + 5.105657;69.919693;68.927238;, + 5.005903;69.410423;68.822868;, + 4.554521;68.674232;68.849876;, + 3.824864;68.309135;68.969109;, + 3.435898;69.375824;69.355331;, + 4.265308;70.250198;69.340469;, + 11.952425;68.545883;67.245644;, + 11.282833;67.985580;67.780556;, + 10.590207;68.229599;68.132561;, + 10.232657;69.031830;68.220833;, + 10.730354;69.347672;67.888069;, + 11.757496;69.105743;67.264893;, + 6.267634;45.663696;67.791992;, + 5.887505;44.716919;67.550507;, + 4.262442;44.288372;68.208298;, + 4.642571;45.235153;68.449783;, + 10.565856;70.821953;67.907776;, + 11.600344;70.544380;67.228043;, + 11.577497;70.225883;67.223770;, + 10.562302;70.475075;67.861671;, + 9.881144;70.555244;68.220161;, + 7.618796;70.711578;68.750259;, + 6.440785;70.114388;68.970451;, + 5.973425;69.792030;69.041931;, + 6.395473;70.515007;68.889984;, + 7.586203;71.123924;68.610703;, + 8.342167;70.998123;68.542450;, + 11.872992;66.061752;67.182938;, + 11.325470;66.065163;67.525764;, + 11.958210;66.625931;67.309013;, + 12.654950;67.224754;66.799522;, + 12.717360;66.949631;66.694183;, + 8.395967;65.338531;68.297150;, + 8.551100;65.687355;68.321404;, + 9.643514;65.743866;67.987259;, + 10.244047;65.908348;67.834045;, + 9.534150;65.381676;67.974045;, + 6.352082;66.607925;68.646599;, + 5.557265;66.767700;68.786423;, + 5.935583;67.066292;68.770218;, + 6.730400;66.906517;68.630394;, + 10.497897;70.102104;67.500931;, + 10.455427;70.382629;67.493866;, + 11.464467;70.134789;66.847923;, + 11.506937;69.854263;66.854988;, + 7.623333;70.645973;68.558647;, + 8.354575;70.568634;68.310120;, + 8.397674;70.288345;68.319221;, + 7.862427;69.958893;68.556709;, + 6.658127;69.634361;68.798340;, + 6.462132;70.041153;68.809387;, + 12.478778;67.291313;66.688377;, + 11.803926;66.665207;67.208046;, + 11.268188;66.503914;67.438225;, + 11.617651;67.061974;67.315300;, + 12.303864;67.618729;66.799240;, + 8.336453;66.419510;68.373581;, + 9.286811;66.759315;68.210503;, + 10.010603;66.509720;67.920815;, + 9.593375;65.951813;67.955978;, + 8.497231;65.898521;68.278526;, + 7.964100;66.116623;68.406441;, + 17.060043;70.155487;47.524548;, + 16.977182;70.700005;48.118645;, + 17.139421;70.899750;48.289326;, + 17.416012;71.068329;47.941158;, + 17.545664;70.690262;47.136501;, + 17.351934;69.977158;46.890572;, + 17.221189;66.543564;45.306343;, + 16.988846;67.340813;45.524662;, + 16.845232;68.371811;45.875668;, + 16.939117;68.867996;46.195717;, + 17.341833;68.629349;45.660599;, + 17.480291;67.335907;45.122231;, + 16.981171;63.931744;46.212234;, + 16.808901;64.944427;45.835949;, + 16.940056;65.503990;45.698055;, + 17.325806;64.694969;45.653248;, + 17.333046;63.707901;46.045494;, + 17.373362;62.592293;47.044037;, + 17.533400;61.989571;47.233940;, + 17.538557;61.297504;47.813133;, + 17.377050;61.378471;48.161098;, + 17.084042;61.957218;48.121510;, + 16.952885;62.523624;47.585892;, + 17.067348;62.847736;47.248653;, + 17.756001;57.667091;48.205170;, + 17.726576;58.393188;48.722862;, + 17.667044;59.356384;48.625698;, + 17.687859;59.655956;48.204098;, + 17.756863;59.537712;47.829380;, + 17.765472;58.512043;47.733288;, + 17.164349;58.888443;50.137520;, + 16.997469;59.817486;50.241066;, + 16.910639;61.394268;50.541176;, + 16.963501;61.964878;50.507847;, + 17.146688;61.167274;50.192562;, + 17.353167;60.194298;49.885605;, + 17.382475;59.234547;49.939693;, + 17.046909;69.285706;49.834724;, + 16.730762;68.525681;49.726234;, + 16.445251;67.737488;49.665955;, + 16.455748;67.565254;49.576904;, + 16.635740;67.426628;49.977383;, + 16.941389;68.358887;50.174927;, + 17.667368;71.775742;48.843681;, + 17.479918;71.554535;48.518509;, + 17.312452;71.293510;48.824539;, + 17.073994;70.820007;49.096962;, + 17.052391;70.317307;49.319000;, + 17.478302;71.012024;49.371750;, + 16.150881;66.980598;49.101681;, + 15.982324;66.633751;48.735458;, + 15.966154;66.336823;48.616936;, + 16.051481;66.244766;48.838696;, + 16.220257;66.411118;49.371330;, + 16.303486;66.850029;49.515789;, + 16.242199;65.664818;49.415100;, + 16.045393;65.511154;48.894043;, + 15.967184;65.262131;48.876595;, + 16.014877;65.163132;49.153240;, + 16.157045;65.036949;49.353294;, + 16.306154;65.289612;49.597702;, + 16.606468;64.863365;50.058353;, + 16.483816;64.613602;49.802601;, + 16.489483;64.287704;49.843987;, + 16.683701;63.725044;49.778568;, + 16.907532;63.235886;49.945076;, + 16.835964;64.048317;50.266247;, + 17.332932;60.928143;48.799614;, + 17.415449;60.700314;49.200974;, + 17.131311;61.599758;49.547829;, + 16.866329;62.064793;49.391998;, + 16.881441;61.620750;49.208321;, + 16.931652;61.430393;48.922810;, + 17.023394;61.495392;48.765743;, + 15.594433;64.410210;48.011654;, + 15.355221;64.746971;48.103077;, + 15.109011;64.845505;48.207409;, + 15.310225;65.020020;48.325905;, + 15.597193;65.150154;48.319054;, + 15.682936;65.398903;48.325111;, + 15.683491;65.459961;48.141235;, + 15.730268;65.022964;47.637424;, + 15.710956;64.437210;47.602276;, + 15.693200;66.367973;47.512394;, + 15.739593;65.954384;47.004478;, + 15.709971;65.462585;47.465916;, + 15.713370;65.873161;48.000294;, + 15.703137;66.170380;48.126865;, + 16.046690;70.309875;48.304401;, + 16.365913;70.720009;48.027470;, + 16.440777;70.179176;47.432697;, + 16.279011;69.702744;47.006084;, + 15.989321;69.724388;47.707878;, + 16.234823;68.397461;45.749371;, + 16.338247;67.364136;45.404732;, + 16.169886;66.752342;45.468372;, + 15.970524;66.999779;45.793983;, + 15.847556;67.422462;46.281384;, + 15.798820;67.779671;46.594791;, + 15.930688;68.405243;46.444931;, + 15.841449;64.678902;46.459305;, + 15.926772;65.184181;46.013538;, + 16.207218;64.937843;45.725086;, + 16.383900;63.939720;46.142395;, + 16.237436;63.590012;46.468613;, + 15.975430;64.082863;46.497070;, + 16.041712;62.989491;47.503284;, + 16.330074;62.510639;47.489380;, + 16.479687;61.953060;48.036350;, + 16.332567;61.851406;48.240868;, + 16.103371;62.236324;48.207397;, + 16.005190;62.652355;48.086254;, + 15.959622;62.895470;47.927872;, + 15.710892;68.402351;48.685627;, + 15.648136;67.764122;48.843464;, + 15.852196;67.748260;49.593555;, + 16.091112;68.539047;49.658321;, + 16.056801;69.119179;49.475651;, + 15.880638;68.966606;49.253052;, + 16.424000;70.874527;49.045010;, + 16.701757;71.314072;48.751896;, + 16.462385;71.171959;48.547527;, + 16.184629;70.732407;48.840641;, + 15.699827;66.642441;48.652946;, + 15.824578;66.982887;49.023090;, + 15.784410;67.181129;49.142185;, + 15.634274;67.185043;48.375042;, + 15.615120;66.834618;48.047215;, + 15.674185;65.271629;48.793575;, + 15.204105;65.204224;48.722855;, + 14.835443;65.032219;48.968830;, + 15.208019;64.988647;49.170685;, + 15.676402;65.164146;49.081577;, + 15.688455;64.774559;49.574314;, + 15.234891;64.553688;49.607170;, + 14.902706;64.137657;49.657894;, + 15.293420;64.013451;49.696068;, + 15.840926;64.271202;49.771698;, + 15.903778;64.616272;49.700668;, + 16.278091;61.394108;48.852608;, + 16.220278;61.579231;49.139591;, + 15.982187;61.957813;49.102505;, + 16.039999;61.772690;48.815525;, + 15.430898;63.808681;48.458256;, + 15.043995;64.044220;48.320808;, + 15.364042;64.229958;48.236816;, + 15.832829;63.853062;48.277557;, + 15.865870;63.597157;48.425735;, + 15.954613;62.957794;48.812828;, + 15.834729;63.048027;49.053604;, + 15.432328;63.369987;49.007088;, + 15.134183;63.530445;48.836395;, + 15.431887;63.570396;48.738605;, + 15.849918;63.319706;48.668522;, + 16.096088;62.618446;49.327629;, + 16.199696;63.113098;49.537724;, + 15.912754;63.623280;49.678589;, + 15.391949;63.393970;49.504761;, + 15.060607;63.170467;49.313648;, + 15.415560;63.228004;49.333504;, + 15.838570;62.949089;49.349140;, + 13.758102;64.727051;47.977783;, + 14.168221;64.570992;47.942337;, + 13.829064;64.330490;47.964046;, + 13.418945;64.486542;47.999493;, + 13.383851;64.565086;48.723537;, + 13.733362;64.821175;48.841949;, + 14.082317;65.018639;48.594540;, + 13.738489;64.867424;48.405872;, + 13.395164;64.634613;48.428219;, + 13.432858;63.849289;49.209923;, + 13.461254;63.706188;49.357521;, + 13.801391;63.932621;49.534199;, + 14.101580;64.368164;49.509857;, + 13.754813;64.418907;49.285202;, + 13.426229;64.126465;49.161942;, + 13.523585;63.991501;48.212700;, + 13.930980;63.829620;48.172535;, + 14.306720;63.583447;48.318527;, + 13.970022;63.502201;48.416882;, + 13.564429;63.599464;48.515327;, + 13.493731;63.842590;48.457138;, + 13.564157;63.334648;48.762100;, + 13.975533;63.274899;48.680103;, + 14.334991;63.163155;48.878448;, + 13.965490;63.106457;48.948494;, + 13.561500;63.215389;48.942604;, + 13.941969;62.948902;49.207970;, + 14.276101;63.179287;49.390675;, + 13.876339;63.319157;49.397709;, + 13.542208;63.088772;49.215008;, + 14.751657;54.643333;55.040348;, + 14.590873;52.802021;53.698296;, + 13.499039;51.207058;56.417542;, + 13.273923;52.062576;58.359673;, + 14.262792;54.452450;57.104122;, + 14.688508;68.117760;63.612282;, + 14.535710;70.296165;64.247795;, + 14.997487;70.420540;62.992817;, + 15.420611;68.186958;61.412601;, + 15.123456;66.809219;62.450409;, + 15.289042;58.842800;58.182579;, + 15.320647;60.373241;59.487785;, + 15.545645;62.728092;59.776886;, + 15.818025;64.100548;58.725273;, + 16.026705;62.698605;56.534737;, + 16.058146;60.483253;55.162083;, + 15.694791;59.052357;56.106335;, + 16.253756;62.572739;52.645172;, + 16.384674;63.355892;51.544556;, + 16.562685;61.758488;50.400814;, + 16.575487;60.184284;50.041332;, + 16.380493;60.348454;51.283993;, + 9.754243;54.576092;68.034088;, + 8.865682;56.214470;68.792267;, + 9.070836;58.376186;68.852272;, + 10.135895;59.249851;68.473312;, + 11.100456;59.171497;67.685600;, + 10.923957;56.659454;67.306381;, + 3.035042;66.059219;69.545708;, + 2.344930;66.840546;69.764442;, + 1.661030;68.905617;69.955627;, + 1.920111;69.821587;69.985138;, + 2.596213;69.424149;69.710426;, + 3.034613;68.351173;69.428009;, + 3.051194;67.427612;69.470802;, + 2.345155;71.696121;70.544289;, + 1.677019;72.093285;70.835541;, + 1.282981;72.975906;71.066788;, + 3.189397;72.557281;70.563393;, + 3.979451;64.606781;69.322395;, + 4.936673;63.796482;69.076340;, + 5.221594;62.962933;69.143433;, + 4.610626;62.101410;69.479050;, + 4.010058;63.243977;69.496239;, + 6.097832;62.362251;69.253105;, + 6.886958;62.188259;69.118797;, + 6.223436;61.054867;69.396408;, + 5.444539;60.484348;69.611397;, + 5.470115;61.491180;69.538467;, + 10.069182;62.560196;68.243744;, + 9.631428;61.319351;68.567192;, + 8.452230;60.522438;69.069862;, + 7.744656;61.197292;69.140694;, + 8.403069;62.278648;68.682831;, + 9.548402;62.866348;68.253067;, + 11.649054;61.247047;67.476128;, + 10.733654;61.313049;68.317123;, + 11.162767;62.546486;67.962914;, + 12.078169;62.480480;67.121918;, + -11.134334;90.849747;67.548500;, + 11.278329;90.396461;67.764954;, + 30.643127;-31.721945;45.652527;, + -30.350075;-31.719879;45.630089;, + -25.565304;-9.924385;26.239328;, + -30.142681;-11.598551;37.311020;, + -17.647087;-15.421692;74.962234;, + -17.647087;-15.421692;74.962234;, + 0.141491;-9.487318;27.256748;, + -16.966074;-26.227253;76.131516;, + -33.277031;-27.463528;63.505905;, + -34.720058;-12.484819;48.088928;, + -31.930122;-26.942392;51.688797;, + -34.720058;-12.484819;48.088928;, + -24.287395;-54.514771;54.652374;, + -24.509207;-50.845016;55.877068;, + -25.494289;-63.762321;51.551601;, + -29.140186;-40.740757;54.994888;, + -17.688755;-53.253067;77.227638;, + -26.760902;-31.939959;72.082443;, + -16.966076;-27.937576;75.155312;, + -24.332394;-52.295708;66.403946;, + -32.183464;-29.173838;63.505913;, + -32.056793;-28.913269;57.597359;, + -22.127073;-50.465675;31.947027;, + -20.920321;-28.152065;33.507904;, + -26.425222;-28.402384;42.598354;, + -31.930124;-28.652702;51.688805;, + 0.141491;-50.060425;24.873173;, + -11.193696;-29.430769;30.196033;, + -16.966074;-26.227253;76.131516;, + -30.976030;-51.338348;55.580246;, + -26.551552;-50.902012;43.763638;, + -34.720058;-12.484819;48.088928;, + -26.551552;-50.902012;43.763638;, + -31.930124;-28.652702;51.688805;, + -23.021046;22.545492;38.817097;, + -34.612175;17.843525;39.827816;, + -34.612186;-1.674418;34.789925;, + -34.666122;-7.473567;40.417480;, + -34.612183;9.271671;35.005108;, + 0.141491;-28.374607;32.989838;, + -16.294899;25.090145;38.449425;, + -9.139874;26.594124;45.452682;, + -14.724298;0.438756;65.826607;, + -19.722260;-1.585354;65.224693;, + -13.398946;24.794630;34.246376;, + -16.294899;25.090145;38.449425;, + -18.686239;24.355274;46.119999;, + -19.918121;19.050785;53.541157;, + -9.748887;22.893982;32.226307;, + 0.141491;22.863007;31.002354;, + -6.363874;23.153360;30.623175;, + -10.778057;22.307632;52.895199;, + -11.429913;16.434713;56.577648;, + -11.545969;16.822830;57.059074;, + -20.110298;5.311386;60.448208;, + -21.278301;13.060091;57.191551;, + -15.815639;16.328318;56.204815;, + -30.997221;-35.165527;63.780437;, + -32.118473;-39.484562;59.515316;, + -29.846169;-43.697968;61.553284;, + -29.388227;-40.601273;63.974194;, + -27.854467;-30.229647;72.082443;, + -29.736418;-23.496841;70.352409;, + -30.377008;-28.942865;68.092697;, + 25.849533;-9.924379;26.239330;, + 30.426910;-11.598546;37.311020;, + 17.931316;-15.421690;74.962234;, + 17.931316;-15.421690;74.962234;, + 17.250303;-26.227251;76.131516;, + 33.561260;-27.463524;63.505905;, + 32.214352;-26.942389;51.688797;, + 35.004288;-12.484816;48.088928;, + 24.793436;-50.845009;55.877064;, + 24.562241;-54.514763;54.652370;, + 25.705898;-63.638660;51.490501;, + 29.424416;-40.740753;54.994888;, + 17.972984;-53.253063;77.227638;, + 17.250305;-27.937574;75.155312;, + 27.045132;-31.939955;72.082443;, + 24.616623;-52.295704;66.403946;, + 32.467693;-29.173834;63.505913;, + 32.341022;-28.913265;57.597359;, + 21.204550;-28.152060;33.507904;, + 22.411303;-50.465668;31.947027;, + 26.709452;-28.402378;42.598354;, + 32.214352;-28.652699;51.688805;, + 11.477925;-29.430763;30.196033;, + 17.250303;-26.227251;76.131516;, + 31.260260;-51.338341;55.580242;, + 26.835781;-50.902004;43.763638;, + 35.004288;-12.484816;48.088928;, + 35.004288;-12.484816;48.088928;, + 26.835781;-50.902004;43.763638;, + 32.214352;-28.652699;51.688805;, + 23.305275;22.545494;38.817101;, + 34.896404;17.843529;39.827820;, + 34.896416;-1.674414;34.789925;, + 34.950352;-7.473563;40.417480;, + 34.896412;9.271675;35.005108;, + 16.579128;25.090147;38.449429;, + 15.005043;0.438756;66.317261;, + 20.006489;-1.585352;65.224693;, + 13.683175;24.794634;34.246380;, + 16.579128;25.090147;38.449429;, + 18.970469;24.355276;46.119999;, + 20.202351;19.050787;53.541157;, + 10.033116;22.893986;32.226311;, + 6.648103;23.153364;30.623177;, + 11.062286;22.307634;52.895199;, + 11.714142;16.434715;57.068302;, + 11.825384;16.819580;57.419716;, + 20.394527;5.311388;60.448208;, + 21.562531;13.060093;57.191551;, + 16.099869;16.328320;56.204815;, + 31.281450;-35.165524;63.780437;, + 32.402702;-39.484558;59.515316;, + 30.130398;-43.697964;61.553280;, + 29.672457;-40.601269;63.974190;, + 28.138697;-30.229643;72.082443;, + 30.020647;-23.496838;70.352409;, + 30.661238;-28.942862;68.092697;, + -29.135050;-70.748413;50.137466;, + -37.889961;-84.783730;46.673920;, + -41.760616;-103.151527;46.673916;, + -43.113548;-194.904678;46.172501;, + -8.177140;-173.738678;44.589825;, + -11.967894;-201.991714;48.101704;, + -35.253540;-336.022400;70.615288;, + -37.752792;-344.579865;81.882141;, + -36.447479;-347.590393;81.989037;, + -32.971939;-348.840668;75.068268;, + -30.483822;-349.513580;64.542366;, + -30.277090;-349.285034;45.291451;, + -30.731056;-349.140869;32.597919;, + -44.998409;-349.114563;30.769142;, + -47.579365;-349.201599;38.020824;, + -49.480873;-349.253357;42.813530;, + -53.720398;-349.475220;61.544106;, + -54.063526;-348.805878;72.346741;, + -50.995792;-347.566376;80.111809;, + -50.995792;-347.566376;80.111809;, + -36.447479;-347.590393;81.989037;, + -50.401588;-344.387238;80.484764;, + -30.811893;-349.229279;40.184383;, + -25.375702;-326.803925;43.166012;, + -25.361750;-319.393433;40.717945;, + -48.911896;-319.507538;43.118351;, + -53.350098;-311.978485;48.287319;, + -17.516390;-311.220673;43.257233;, + -4.658672;-143.854736;42.160900;, + 0.100870;-118.350113;30.024460;, + -21.858656;-301.316620;40.265823;, + -48.634773;-301.610474;45.850082;, + -15.366711;-254.579529;44.539597;, + -42.656788;-120.929993;49.355263;, + -12.445428;-224.292206;47.498665;, + -47.093388;-334.957916;67.363968;, + -46.985233;-330.924652;60.877213;, + -52.006966;-325.347748;41.525673;, + -32.159611;-328.701721;61.163334;, + -37.431126;-348.022339;28.784142;, + -37.431126;-348.022339;28.784142;, + -36.497189;-333.552704;31.073109;, + -43.124073;-327.569916;63.163582;, + -37.508007;-327.823730;63.943375;, + -32.027699;-330.586823;57.891068;, + -30.829683;-335.353180;51.935188;, + -30.289175;-336.679779;37.674358;, + -30.290890;-334.903290;34.539791;, + -46.926067;-335.870056;46.077358;, + -48.218380;-333.043976;53.745155;, + -33.346500;-333.002716;32.172970;, + -36.497189;-333.552704;31.073109;, + -32.159611;-328.701721;61.163334;, + -47.738998;-332.348511;57.905354;, + -46.985233;-330.924652;60.877213;, + -39.092888;-333.629852;32.004887;, + -42.781075;-334.302216;33.467194;, + -30.620396;-337.228912;46.045479;, + -44.659866;-335.766113;36.478382;, + -46.011299;-336.928101;39.876133;, + -30.907063;-337.423279;41.478359;, + -11.541974;-184.862228;45.883656;, + -41.620197;-179.552460;46.748608;, + -30.082495;-176.538712;60.086678;, + -26.290127;-159.034851;62.359310;, + -22.042976;-120.057648;62.105083;, + -35.127117;-120.041656;57.534679;, + -24.386381;-143.741119;62.231689;, + -37.002441;-178.638748;55.923828;, + -41.142269;-130.155960;39.554146;, + -41.240711;-158.109726;38.305466;, + -42.656788;-120.929993;49.355263;, + -41.014412;-121.305328;41.175835;, + -41.620197;-179.552460;46.748608;, + -39.826946;-174.615158;38.212673;, + -52.006966;-325.347748;41.525673;, + -25.375702;-326.803925;43.166012;, + -27.052189;-63.743755;51.457161;, + -30.899126;-70.822411;49.935226;, + -3.998070;-70.562149;67.711349;, + -14.078679;-70.624992;36.359470;, + -20.407236;-70.663857;37.704983;, + -25.309130;-70.709183;43.680515;, + -25.333038;-70.735931;56.047955;, + -20.123388;-70.712914;61.395264;, + -29.135050;-70.748413;50.137466;, + -29.135050;-70.748413;50.137466;, + -10.657997;-70.656097;64.141533;, + -18.580341;-63.659996;42.089684;, + 0.102538;-63.638348;37.841175;, + -3.877978;-63.520813;66.895554;, + -18.598015;-63.628139;61.096786;, + -25.494289;-63.762321;51.551601;, + -25.494289;-63.762321;51.551601;, + 0.102538;-63.445549;68.379417;, + -3.877978;-63.520813;66.895554;, + -4.034785;-63.594818;67.636086;, + -3.998070;-70.562149;67.711349;, + 0.100870;-70.535385;69.452461;, + -3.855402;-70.482147;66.867348;, + 0.100870;-80.880516;69.142647;, + 0.100870;-105.710800;64.621178;, + 0.100870;-105.624802;63.766800;, + -15.278575;-278.076538;41.723305;, + -47.843460;-278.215302;43.605659;, + -47.021446;-254.582092;45.376308;, + -44.766525;-223.910660;41.391571;, + -11.671675;-229.887054;44.415508;, + -13.444867;-241.724686;43.812698;, + -12.848580;-215.346298;46.368130;, + -42.281010;-210.077301;42.464180;, + 0.100870;-70.522980;34.969410;, + 38.087563;-84.783722;46.673916;, + 29.332651;-70.748413;50.137463;, + 41.958218;-103.151527;46.673912;, + 43.311150;-194.904678;46.172497;, + 8.374740;-173.738678;44.589821;, + 12.165494;-201.991699;48.101700;, + 35.451141;-336.022369;70.615288;, + 37.950394;-344.579834;81.882141;, + 36.645081;-347.590363;81.989037;, + 33.169540;-348.840668;75.068268;, + 30.681425;-349.513580;64.542366;, + 30.474693;-349.285034;45.291451;, + 30.928658;-349.140839;32.597916;, + 45.196014;-349.114563;30.769142;, + 47.776966;-349.201569;38.020821;, + 49.678474;-349.253357;42.813526;, + 53.918003;-349.475220;61.544106;, + 54.261131;-348.805878;72.346741;, + 51.193394;-347.566376;80.111809;, + 51.193394;-347.566376;80.111809;, + 36.645081;-347.590363;81.989037;, + 50.599190;-344.387238;80.484764;, + 31.009497;-349.229279;40.184380;, + 25.573301;-326.803894;43.166008;, + 25.559353;-319.393433;40.717941;, + 53.547699;-311.978485;48.287315;, + 49.109501;-319.507538;43.118351;, + 17.713989;-311.220673;43.257229;, + 4.856273;-143.854736;42.160900;, + 22.056257;-301.316620;40.265823;, + 48.832378;-301.610474;45.850079;, + 15.564311;-254.579514;44.539597;, + 42.854393;-120.929985;49.355259;, + 12.643028;-224.292191;47.498661;, + 47.290989;-334.957916;67.363968;, + 47.182835;-330.924622;60.877216;, + 52.204571;-325.347748;41.525669;, + 37.628727;-348.022308;28.784140;, + 37.628727;-348.022308;28.784140;, + 36.694790;-333.552673;31.073109;, + 43.321674;-327.569916;63.163586;, + 37.705608;-327.823700;63.943378;, + 32.225300;-330.586823;57.891064;, + 31.027285;-335.353180;51.935184;, + 30.486776;-336.679749;37.674358;, + 30.488491;-334.903290;34.539787;, + 47.123669;-335.870056;46.077354;, + 48.415981;-333.043976;53.745152;, + 33.544102;-333.002716;32.172966;, + 36.694790;-333.552673;31.073109;, + 32.357216;-328.701721;61.163334;, + 47.936604;-332.348511;57.905350;, + 47.182835;-330.924622;60.877216;, + 39.290493;-333.629852;32.004887;, + 42.978680;-334.302216;33.467194;, + 30.817997;-337.228882;46.045475;, + 44.857464;-335.766083;36.478382;, + 46.208900;-336.928101;39.876129;, + 31.104664;-337.423279;41.478355;, + 11.739574;-184.862213;45.883652;, + 41.817802;-179.552460;46.748608;, + 30.280094;-176.538696;60.086674;, + 26.487728;-159.034851;62.359303;, + 22.240578;-120.057648;62.105080;, + 35.324718;-120.041656;57.534676;, + 24.583982;-143.741119;62.231686;, + 37.200043;-178.638748;55.923824;, + 41.339870;-130.155960;39.554138;, + 41.438313;-158.109711;38.305462;, + 42.854393;-120.929985;49.355259;, + 41.212013;-121.305321;41.175831;, + 41.817802;-179.552460;46.748608;, + 40.024551;-174.615143;38.212673;, + 52.204571;-325.347748;41.525669;, + 25.573301;-326.803894;43.166008;, + 32.357216;-328.701721;61.163334;, + 31.096729;-70.822411;49.935223;, + 27.249788;-63.743755;51.457157;, + 4.195670;-70.562141;67.711349;, + 14.276281;-70.624985;36.359463;, + 20.604836;-70.663849;37.704975;, + 25.506731;-70.709175;43.680508;, + 25.530638;-70.735931;56.047947;, + 20.320988;-70.712906;61.395260;, + 29.332651;-70.748413;50.137463;, + 29.332651;-70.748413;50.137463;, + 10.855597;-70.656097;64.141525;, + 18.773201;-63.677704;42.028572;, + 4.075578;-63.520775;66.895554;, + 18.770283;-63.633057;61.106705;, + 25.705898;-63.638660;51.490501;, + 25.705898;-63.638660;51.490501;, + 4.232385;-63.594814;67.636078;, + 4.075578;-63.520775;66.895554;, + 4.195670;-70.562141;67.711349;, + 4.053002;-70.482147;66.867340;, + 15.476175;-278.076508;41.723305;, + 48.041061;-278.215271;43.605659;, + 47.219048;-254.582077;45.376305;, + 44.964127;-223.910675;41.391571;, + 11.869275;-229.887054;44.415504;, + 13.642469;-241.724686;43.812695;, + 13.046181;-215.346298;46.368130;, + 42.478611;-210.077286;42.464176;, + 9.646603;26.610264;45.446602;, + 33.395126;-1.314395;35.941048;, + 42.876431;-10.391958;41.524540;, + 61.100998;-12.097787;52.234310;, + 33.931534;-10.798729;47.691635;, + 33.395126;-1.314395;35.941048;, + 78.460449;-9.570584;65.570358;, + 73.386116;1.385114;82.625687;, + 78.295067;-4.036124;86.370949;, + 81.882507;-19.600512;68.102516;, + 87.136154;-19.603304;74.055412;, + 86.196594;-18.624458;77.084518;, + 80.318741;-7.420647;85.493256;, + 67.389786;-1.205821;78.118034;, + 70.006081;2.367340;76.967026;, + 77.780144;-0.616348;69.076759;, + 78.460449;-9.570584;65.570358;, + 75.694405;-15.631040;66.051804;, + 71.219742;-15.793794;69.989906;, + 68.045258;-14.292754;73.173157;, + 66.651627;-8.248512;76.491966;, + 73.890327;2.056242;73.440269;, + 70.006081;2.367340;76.967026;, + 69.084702;6.252669;77.456337;, + 75.694405;-15.631040;66.051804;, + 75.774590;-18.309954;63.527412;, + 66.651627;-8.248512;76.491966;, + 86.261154;-12.489821;78.381943;, + 82.521919;-17.837069;80.497223;, + 114.749481;-29.371605;104.351402;, + 79.183868;-11.467402;85.242088;, + 79.655968;-17.333593;83.765129;, + 110.916962;-20.728716;110.111130;, + 80.318741;-7.420647;85.493256;, + 86.196594;-18.624458;77.084518;, + 82.789978;-6.610463;83.296829;, + 80.318741;-7.420647;85.493256;, + 84.665817;-9.600757;93.965752;, + 105.883774;-28.288433;93.625610;, + 100.601974;-16.327637;102.138657;, + 93.242905;-25.622953;81.159538;, + 86.196594;-18.624458;77.084518;, + 86.199554;-6.060757;79.316513;, + 51.500221;-7.577340;65.697365;, + 33.477127;16.479158;40.343475;, + 33.578400;13.114620;48.755165;, + 33.569466;8.843540;35.935562;, + 114.749481;-29.371605;104.351402;, + 116.328888;-21.406776;103.886078;, + 114.749481;-29.371605;104.351402;, + 110.432236;-25.897305;108.404945;, + 114.547729;-31.794006;101.703148;, + 110.916962;-20.728716;110.111130;, + 110.916962;-20.728716;110.111130;, + 117.792206;-32.974083;105.142754;, + 120.240417;-32.382523;107.405258;, + 120.240417;-32.382523;107.405258;, + 119.345352;-28.410704;105.006744;, + 120.240417;-32.382523;107.405258;, + 115.310875;-21.371449;114.672195;, + 120.625252;-22.188108;107.598892;, + 128.789810;-29.466074;108.954926;, + 115.310875;-21.371449;114.672195;, + 114.274811;-23.003649;117.528297;, + 117.859741;-27.379353;126.710335;, + 120.613640;-25.185886;123.257240;, + 121.760422;-25.243605;123.489906;, + 114.847473;-23.354944;126.325142;, + 115.773735;-23.653730;128.726898;, + 120.118660;-28.808155;129.262100;, + 118.315994;-26.222034;131.904175;, + 120.118660;-28.808155;129.262100;, + 117.369904;-31.079527;128.957718;, + 118.686279;-31.174704;132.509644;, + 120.607414;-29.430899;132.556305;, + 119.351463;-27.770924;134.521164;, + 120.230301;-29.213165;134.837173;, + 137.268311;-36.747177;118.004539;, + 130.886734;-24.224178;128.467072;, + 129.463760;-23.354002;127.461098;, + 132.345215;-26.909451;126.571350;, + 131.403183;-26.611431;125.127594;, + 132.198166;-25.013567;129.446793;, + 133.363693;-27.150629;127.933983;, + 133.465668;-25.219961;130.170334;, + 134.645630;-27.372400;128.641541;, + 134.095200;-25.443157;131.157074;, + 135.557129;-28.123676;129.259583;, + 135.087219;-26.605450;132.444199;, + 136.416260;-29.042286;130.719208;, + 136.310669;-27.313053;133.104141;, + 137.309525;-29.130545;131.811081;, + 136.930222;-27.776287;134.007202;, + 138.067566;-29.848610;132.534195;, + 137.163391;-28.031139;134.882431;, + 138.629425;-30.705997;132.982819;, + 138.097382;-29.210182;136.039948;, + 139.375854;-31.531094;134.386230;, + 139.425034;-29.698851;136.370346;, + 140.178970;-31.048899;135.399673;, + 140.258026;-30.001667;136.269287;, + 140.513062;-30.455763;135.941559;, + 133.326996;-27.869246;126.520409;, + 134.998978;-30.947582;124.347214;, + 133.524338;-30.337019;122.600365;, + 135.090698;-28.901239;127.885551;, + 136.426865;-31.351122;126.151329;, + 136.754562;-29.240726;128.910980;, + 138.107239;-31.708241;127.158394;, + 137.655624;-29.584154;130.208908;, + 139.331543;-32.657040;128.033676;, + 139.067566;-31.050646;131.939789;, + 140.591125;-33.844181;129.962296;, + 140.683243;-31.965866;132.894485;, + 141.828308;-34.049400;131.412170;, + 141.569046;-32.582588;134.092957;, + 142.872879;-34.958260;132.404327;, + 141.965546;-32.937801;135.216400;, + 143.646179;-36.004208;133.038742;, + 143.291046;-34.413788;136.780243;, + 144.756668;-37.074436;134.884445;, + 144.992767;-35.061703;137.326050;, + 145.857040;-36.609371;136.213287;, + 146.025253;-35.446705;137.282303;, + 146.317627;-35.967274;136.906616;, + 135.283035;-31.410269;123.908699;, + 136.889267;-34.388729;121.786079;, + 135.487198;-33.834320;120.160095;, + 136.918472;-32.390182;125.135963;, + 138.202103;-34.760567;123.442123;, + 138.471878;-32.702595;126.052612;, + 139.771439;-35.090023;124.340836;, + 139.296295;-33.022293;127.247002;, + 140.906357;-35.995464;125.122398;, + 140.587006;-34.422878;128.824356;, + 142.050705;-37.125763;126.892921;, + 142.091629;-35.292908;129.670227;, + 143.191742;-37.308819;128.222427;, + 142.901459;-35.877598;130.768753;, + 144.154083;-38.176163;129.119446;, + 143.251007;-36.212845;131.812622;, + 144.865631;-39.179722;129.685654;, + 144.463196;-37.624027;133.234940;, + 145.871307;-40.198315;131.383316;, + 146.060104;-38.237057;133.695831;, + 146.890518;-39.734459;132.609009;, + 147.036926;-38.603104;133.622391;, + 147.317841;-39.106766;133.255463;, + 136.857193;-34.692177;121.075745;, + 138.085999;-37.138863;119.175186;, + 138.106750;-35.513153;121.891022;, + 139.088989;-37.460236;120.374466;, + 139.315872;-35.774200;122.489632;, + 140.310577;-37.735165;120.957130;, + 139.940460;-36.049793;123.361938;, + 141.172485;-38.492016;121.459724;, + 140.897690;-37.228283;124.465363;, + 142.017715;-39.448486;122.736076;, + 142.053253;-37.953835;124.992500;, + 142.895447;-39.609592;123.696373;, + 142.660355;-38.449345;125.780983;, + 143.619232;-40.337288;124.304420;, + 142.909821;-38.739342;126.569069;, + 144.145706;-41.176258;124.664856;, + 145.379715;-40.473606;125.913101;, + 143.807114;-39.925308;127.555336;, + 144.885223;-42.039631;125.897728;, + 145.050308;-40.431152;127.779945;, + 145.686615;-41.660812;126.807167;, + 145.817383;-40.728752;127.636574;, + 146.032715;-41.142326;127.308174;, + 124.282539;-24.769093;125.526192;, + 108.661095;-18.210699;110.956673;, + 113.002747;-28.165403;111.418968;, + 115.310875;-21.371449;114.672195;, + 111.886719;-19.639212;113.723465;, + 128.789810;-29.466074;108.954926;, + 41.310238;-5.151076;57.811226;, + 33.733215;8.483885;56.324486;, + 33.266479;-1.659648;55.141335;, + 33.266479;-1.659648;55.141335;, + -33.285355;-1.230055;35.845985;, + -60.913422;-12.097776;52.234310;, + -42.688854;-10.391947;41.524540;, + -33.422455;-6.066209;41.124596;, + -33.602604;-10.886051;47.766304;, + -78.272881;-9.570575;65.570358;, + -73.198547;1.385122;82.625679;, + -78.107506;-4.036117;86.370941;, + -86.948593;-19.603292;74.055412;, + -81.694946;-19.600500;68.102516;, + -86.009033;-18.624449;77.084511;, + -80.131180;-7.420639;85.493248;, + -67.202217;-1.205813;78.118034;, + -69.818512;2.367348;76.967026;, + -77.592583;-0.616339;69.076759;, + -78.272881;-9.570575;65.570358;, + -75.506836;-15.631029;66.051804;, + -71.032173;-15.793784;69.989906;, + -67.857689;-14.292745;73.173157;, + -66.464066;-8.248504;76.491966;, + -73.702766;2.056248;73.440269;, + -68.897133;6.252676;77.456337;, + -69.818512;2.367348;76.967026;, + -75.587021;-18.309942;63.527412;, + -75.506836;-15.631029;66.051804;, + -66.464066;-8.248504;76.491966;, + -86.073555;-12.696040;78.345314;, + -82.334358;-17.837059;80.497215;, + -114.561913;-29.371595;104.351395;, + -78.996300;-11.467393;85.242081;, + -79.468399;-17.333584;83.765121;, + -80.131180;-7.420639;85.493248;, + -85.469383;-14.398664;96.109703;, + -78.996300;-11.467393;85.242081;, + -86.009033;-18.624449;77.084511;, + -82.859459;-6.312282;83.425949;, + -99.563057;-17.848322;102.450645;, + -110.729401;-20.728708;110.111122;, + -105.696213;-28.288424;93.625603;, + -93.055344;-25.622944;81.159531;, + -86.009033;-18.624449;77.084511;, + -86.011993;-6.060749;79.316505;, + -51.312645;-7.577330;65.697365;, + -33.326355;16.538502;40.337154;, + -33.377022;12.971798;48.765106;, + -33.380333;8.824398;35.941063;, + -114.561913;-29.371595;104.351395;, + -116.141319;-21.406767;103.886070;, + -114.561913;-29.371595;104.351395;, + -110.244675;-25.897297;108.404938;, + -114.360168;-31.793995;101.703140;, + -110.729401;-20.728708;110.111122;, + -110.729401;-20.728708;110.111122;, + -118.763100;-32.416569;106.890343;, + -117.604637;-32.974075;105.142746;, + -119.195221;-22.221508;107.119102;, + -118.763100;-32.416569;106.890343;, + -118.763100;-32.416569;106.890343;, + -115.208687;-21.985653;115.587814;, + -128.864243;-29.984035;109.850922;, + -115.208687;-21.985653;115.587814;, + -114.103012;-23.569595;118.313278;, + -117.563560;-27.690514;126.991264;, + -120.423470;-25.533827;123.678185;, + -121.581490;-25.569689;123.884338;, + -114.556931;-23.727386;126.708763;, + -115.458870;-23.961578;128.988220;, + -119.802361;-29.029490;129.383438;, + -117.964737;-26.420248;131.961685;, + -120.245399;-29.574646;132.518158;, + -118.961952;-27.895647;134.431473;, + -119.833649;-29.315147;134.705521;, + -137.255630;-36.934776;118.303642;, + -131.314377;-26.758501;125.303482;, + -133.322495;-24.425945;126.440849;, + -129.349152;-23.487917;127.596153;, + -130.768127;-24.314178;128.528564;, + -132.245651;-27.011766;126.667183;, + -132.075287;-25.062017;129.438324;, + -133.256104;-27.208897;127.952965;, + -133.347275;-25.234171;130.110321;, + -134.542770;-27.396519;128.609299;, + -133.969086;-25.426950;131.042328;, + -135.450180;-28.119780;129.179245;, + -134.944672;-26.545113;132.246048;, + -136.291122;-28.993143;130.552338;, + -136.167953;-27.219339;132.852280;, + -137.179993;-29.045206;131.582748;, + -136.778458;-27.653521;133.701782;, + -137.930786;-29.735388;132.255539;, + -136.999939;-27.886042;134.532242;, + -138.485275;-30.573214;132.667130;, + -137.918381;-29.024487;135.612717;, + -139.213760;-31.356102;133.989075;, + -139.254013;-29.485641;135.905014;, + -140.018036;-30.841948;134.952103;, + -140.096344;-29.777664;135.793762;, + -140.354813;-30.233871;135.472046;, + -133.231537;-27.956072;126.594505;, + -134.925339;-31.048527;124.460655;, + -133.461777;-30.497587;122.817970;, + -134.989136;-28.931255;127.863777;, + -136.342789;-31.392393;126.160988;, + -136.657150;-29.224060;128.817413;, + -138.027634;-31.702929;127.096672;, + -137.548523;-29.526291;130.041809;, + -139.246399;-32.613304;127.906013;, + -138.940323;-30.932508;131.660553;, + -140.483856;-33.738888;129.718903;, + -140.554810;-31.801954;132.540863;, + -141.714996;-33.895096;131.085495;, + -141.429428;-32.379189;133.667358;, + -142.750443;-34.765797;132.009415;, + -141.811935;-32.704250;134.731705;, + -143.514694;-35.784763;132.593597;, + -143.118393;-34.124710;136.191864;, + -144.603409;-36.797626;134.330566;, + -144.828415;-34.734749;136.683197;, + -145.704269;-36.289589;135.590790;, + -145.871262;-35.104645;136.623108;, + -146.167557;-35.627628;136.254303;, + -135.214676;-31.515200;124.032562;, + -136.842163;-34.507912;121.949051;, + -135.449875;-34.009403;120.420280;, + -136.844757;-32.443195;125.172371;, + -138.145432;-34.824940;123.509781;, + -138.402664;-32.712887;126.023872;, + -139.719559;-35.111778;124.343742;, + -139.218048;-32.994740;127.150612;, + -140.849487;-35.982155;125.065216;, + -140.489838;-34.340195;128.625000;, + -141.972977;-37.056030;126.729210;, + -141.993790;-35.168465;129.403305;, + -143.108612;-37.194061;127.982307;, + -142.793137;-35.716938;130.435669;, + -144.062485;-38.026543;128.816864;, + -143.129379;-36.024429;131.424835;, + -144.765549;-39.005554;129.337189;, + -144.323669;-37.384869;132.751999;, + -145.750641;-39.971535;130.934662;, + -145.929031;-37.963417;133.163986;, + -146.770706;-39.468060;132.097397;, + -146.916077;-38.315838;133.076492;, + -147.200821;-38.821938;132.716400;, + -136.816589;-34.826042;121.267235;, + -138.063828;-37.289051;119.406982;, + -138.063034;-35.609749;122.020325;, + -139.060074;-37.569843;120.535957;, + -139.277069;-35.839912;122.573105;, + -140.286835;-37.814011;121.073189;, + -139.894958;-36.087437;123.395241;, + -141.145554;-38.545986;121.533401;, + -140.837692;-37.226124;124.423691;, + -141.974594;-39.461166;122.731110;, + -141.993881;-37.922039;124.903725;, + -142.848846;-39.588902;123.635170;, + -142.593063;-38.391006;125.643524;, + -143.566452;-40.291603;124.198372;, + -142.831924;-38.660183;126.390099;, + -144.086502;-41.113419;124.526360;, + -143.715500;-39.809662;127.307304;, + -144.809982;-41.938175;125.684982;, + -144.966858;-40.291412;127.499474;, + -145.612946;-41.529369;126.547478;, + -145.743073;-40.580086;127.348747;, + -145.961716;-40.996456;127.027367;, + -124.112961;-25.016518;125.801498;, + -108.473534;-18.210691;110.956665;, + -112.815208;-28.165394;111.418961;, + -111.699158;-19.639204;113.723457;, + -115.208687;-21.985653;115.587814;, + -41.122662;-5.151066;57.811222;, + -33.454399;8.516764;56.378914;, + -33.245544;-1.592087;55.511299;, + -33.245544;-1.592087;55.511299;, + 33.827938;10.960120;51.807289;, + 33.696419;-6.417687;40.866890;, + -33.285355;-1.230055;35.845985;, + -33.640362;10.960128;51.807285;, + -6.262792;13.473364;58.013275;, + -11.429913;16.434713;56.577648;, + 6.173337;13.337016;58.607582;, + 0.141490;12.205804;59.792637;, + 11.714142;16.434715;57.068302;, + -11.461862;93.826927;46.940403;, + -8.418667;86.102859;35.841724;, + -11.461862;93.826927;46.940403;, + -2.182251;64.795692;35.886501;, + -8.418667;86.102859;35.841724;, + -11.461862;93.826927;46.940403;, + -11.461862;93.826927;46.940403;, + -2.182251;64.795692;35.886501;, + -2.182251;64.795692;35.886501;, + -13.263326;61.285336;39.593838;, + -7.852941;94.312172;61.946106;, + -6.418187;97.562218;66.945374;, + -4.402893;95.093262;63.828449;, + -10.775403;96.597122;64.803986;, + -13.469022;92.920013;60.063766;, + 0.057848;95.886368;65.707542;, + -3.096079;86.564301;74.622665;, + 0.057848;84.042374;71.322975;, + -2.904975;98.340385;68.672066;, + -6.403885;85.831749;72.998459;, + -4.494127;83.274292;70.169548;, + -8.635912;82.575844;67.678185;, + -15.709467;82.386459;66.627968;, + -13.865308;81.275604;65.186821;, + -15.816927;87.518616;62.681839;, + -11.518435;84.699326;70.485474;, + -13.865308;81.275604;65.186821;, + -8.635912;82.575844;67.678185;, + -14.668218;94.575356;62.197353;, + -4.402893;95.093262;63.828449;, + -7.852941;94.312172;61.946106;, + -13.097512;71.430748;40.778584;, + -8.418667;86.102859;35.841724;, + -14.186148;74.380287;64.488983;, + -13.097512;71.430748;40.778584;, + -14.675630;70.832016;46.772766;, + -11.461862;93.826927;46.940403;, + -13.097512;71.430748;40.778584;, + -15.347429;57.616409;47.193058;, + -13.263326;61.285336;39.593838;, + 0.057848;63.606403;31.055357;, + -2.182251;64.795692;35.886501;, + -2.182251;64.795692;35.886501;, + 0.057848;63.606403;31.055357;, + -15.784473;69.911873;57.321053;, + -16.338684;73.054062;51.038074;, + -13.469022;92.920013;60.063766;, + 0.057848;90.668213;33.607914;, + -14.675630;70.832016;46.772766;, + -13.097512;71.430748;40.778584;, + -16.338684;73.054062;51.038074;, + 0.057848;75.714500;30.620197;, + -14.163750;71.116005;45.658489;, + -14.675630;70.832016;46.772766;, + -14.163750;71.116005;45.658489;, + -14.718096;68.331589;44.645512;, + 0.057848;99.177589;56.123409;, + -2.250754;97.063629;60.111290;, + 0.057848;99.177589;56.123409;, + -14.675630;70.832016;46.772766;, + -16.338684;73.054062;51.038074;, + -15.528388;63.130802;45.068886;, + -3.355227;56.332371;40.007046;, + -7.149835;52.817856;41.486317;, + -3.355227;56.332371;40.007046;, + -14.710178;77.561653;59.569633;, + -16.338684;73.054062;51.038074;, + -14.238920;86.733635;61.588871;, + -13.469022;92.920013;60.063766;, + -15.101998;82.440125;58.401062;, + -13.865308;81.275604;65.186821;, + 0.057848;99.177589;56.123409;, + 0.057848;97.662560;43.454536;, + -11.461862;93.826927;46.940403;, + 0.057848;75.714500;30.620197;, + 0.057848;90.668213;33.607914;, + -8.418667;86.102859;35.841724;, + -8.418667;86.102859;35.841724;, + -13.097512;71.430748;40.778584;, + -2.182251;64.795692;35.886501;, + -13.469022;92.920013;60.063766;, + -16.338684;73.054062;51.038074;, + -13.097512;71.430748;40.778584;, + 0.057848;99.177589;56.123409;, + -7.149835;52.817856;41.486317;, + -13.263326;61.285336;39.593838;, + -15.347429;57.616409;47.193058;, + -11.261707;52.068916;45.952110;, + 0.057848;99.177589;56.123409;, + 11.577548;93.826927;46.940403;, + 0.057848;90.668213;33.607914;, + 8.534353;86.102859;35.841724;, + 11.577548;93.826927;46.940403;, + 2.297937;64.795692;35.886501;, + 8.534353;86.102859;35.841724;, + 11.577548;93.826927;46.940403;, + 11.577548;93.826927;46.940403;, + 0.057848;97.662560;43.454536;, + 2.297937;64.795692;35.886501;, + 0.057848;63.606403;31.055357;, + 2.297937;64.795692;35.886501;, + 13.379013;61.285336;39.593838;, + 7.968627;94.312172;61.946106;, + 4.518579;95.093262;63.828449;, + 6.533874;97.562218;66.945374;, + 14.783904;94.575356;62.197353;, + 13.584708;92.920013;60.063766;, + 3.211765;86.564301;74.622665;, + 3.020661;98.340385;68.672066;, + 4.609814;83.274292;70.169548;, + 6.519572;85.831749;72.998459;, + 8.751598;82.575844;67.678185;, + 13.980994;81.275604;65.186821;, + 15.932613;87.518616;62.681839;, + 15.825153;82.386459;66.627968;, + 10.891089;96.597122;64.803986;, + 4.518579;95.093262;63.828449;, + 7.968627;94.312172;61.946106;, + 13.213199;71.430748;40.778584;, + 8.534353;86.102859;35.841724;, + 13.213199;71.430748;40.778584;, + 14.791316;70.832016;46.772766;, + 11.577548;93.826927;46.940403;, + 13.213199;71.430748;40.778584;, + 15.463116;57.616409;47.193058;, + 13.379013;61.285336;39.593838;, + 0.057848;63.606403;31.055357;, + 2.297937;64.795692;35.886501;, + 2.297937;64.795692;35.886501;, + 0.057848;53.154804;40.756420;, + 0.057848;63.606403;31.055357;, + 15.900160;69.911873;57.321053;, + 16.454370;73.054062;51.038074;, + 13.981975;76.274246;65.799950;, + 13.584708;92.920013;60.063766;, + 0.057848;90.668213;33.607914;, + 14.791316;70.832016;46.772766;, + 0.057848;75.714500;30.620197;, + 13.213199;71.430748;40.778584;, + 16.454370;73.054062;51.038074;, + 0.057848;75.714500;30.620197;, + 14.279436;71.116005;45.658489;, + 2.366440;97.063629;60.111290;, + 14.791316;70.832016;46.772766;, + 16.454370;73.054062;51.038074;, + 15.644074;63.130802;45.068886;, + 3.470914;56.332371;40.007046;, + 7.265521;52.817856;41.486317;, + 3.470914;56.332371;40.007046;, + 14.825865;77.561653;59.569633;, + 16.454370;73.054062;51.038074;, + 13.584708;92.920013;60.063766;, + 14.354607;86.733635;61.588871;, + 15.217685;82.440125;58.401062;, + 13.980994;81.275604;65.186821;, + 0.057848;99.177589;56.123409;, + 0.057848;97.662560;43.454536;, + 11.577548;93.826927;46.940403;, + 0.057848;75.714500;30.620197;, + 0.057848;90.668213;33.607914;, + 8.534353;86.102859;35.841724;, + 8.534353;86.102859;35.841724;, + 13.213199;71.430748;40.778584;, + 2.297937;64.795692;35.886501;, + 13.584708;92.920013;60.063766;, + 20.061501;88.506752;43.413734;, + 18.678795;84.403915;43.736874;, + 16.454370;73.054062;51.038074;, + 13.213199;71.430748;40.778584;, + 0.057848;99.177589;56.123409;, + 7.265521;52.817856;41.486317;, + 13.379013;61.285336;39.593838;, + 15.463116;57.616409;47.193058;, + 11.377394;52.068913;45.952110;, + 15.463116;57.616409;47.193058;, + 7.265521;52.817856;41.486317;, + 2.867495;39.371185;54.783699;, + 7.573774;40.307079;54.648247;, + 1.330886;37.590916;54.064663;, + 5.149999;41.098293;49.664669;, + -5.034308;41.098293;49.664669;, + -1.215191;37.590916;54.064663;, + -7.458086;40.307079;54.648247;, + -2.751802;39.371185;54.783699;, + 2.217954;38.776661;57.910744;, + -2.102260;38.776661;57.910744;, + -3.355227;56.332371;40.007046;, + 0.057848;53.154804;40.756420;, + 3.470914;56.332371;40.007046;, + 9.931857;27.639982;38.133949;, + 0.077734;27.263643;33.720470;, + -9.608727;27.597115;38.148296;, + -0.565651;37.436687;67.317482;, + -2.411773;37.506966;67.308975;, + 2.527462;37.506966;67.308975;, + 0.681345;37.436687;67.317482;, + -4.628216;39.976799;65.832298;, + -3.095984;38.031998;67.529678;, + -8.580020;44.714546;64.299896;, + -5.649843;41.666725;65.621597;, + -16.045902;55.654251;48.952625;, + -15.310171;52.496346;49.328674;, + -12.819518;47.844864;50.501919;, + -9.828319;42.345741;53.625164;, + -15.043728;50.197842;49.912075;, + -15.007770;66.809219;62.450409;, + -14.767531;62.889500;62.645046;, + -14.547876;60.533600;62.358631;, + -13.118661;55.010292;62.553223;, + -15.462021;56.205631;47.969166;, + -13.866287;76.274246;65.799950;, + -14.881803;70.420540;62.992817;, + -16.338850;66.013954;51.296288;, + -16.338684;73.054062;51.038074;, + -11.348783;70.134789;66.847923;, + -12.326240;69.568321;65.742271;, + -12.625326;68.411827;65.535583;, + -12.363090;67.291313;66.688377;, + -12.479330;68.737000;65.669327;, + -12.347851;69.289749;65.733955;, + -11.017628;49.345627;63.166481;, + -5.015405;68.108635;68.910416;, + -6.346445;70.041153;68.809387;, + -5.034431;67.060791;68.905960;, + -5.441578;66.767700;68.786415;, + -4.548992;67.765022;68.960190;, + -14.710178;77.561653;59.569633;, + -15.784473;69.911873;57.321053;, + -15.528388;63.130802;45.068886;, + -15.347429;57.616409;47.193058;, + -15.347429;57.616409;47.193058;, + -7.149835;52.817856;41.486317;, + -7.906905;51.757496;43.185513;, + -9.962842;51.383026;45.418407;, + -7.929698;44.502201;46.021900;, + -8.752393;35.209740;45.489132;, + -7.580388;47.204636;47.215710;, + -9.962842;51.383026;45.418407;, + -8.122182;48.950886;46.050209;, + -9.962842;51.383026;45.418407;, + -9.139874;26.594124;45.452682;, + -7.848414;66.116623;68.406441;, + -6.236395;66.607925;68.646599;, + -8.238889;70.568634;68.310120;, + -10.339741;70.382629;67.493866;, + -7.507647;70.645966;68.558647;, + -11.152501;66.503914;67.438225;, + -9.477689;65.951813;67.955978;, + -11.688239;66.665207;67.208046;, + -8.381545;65.898521;68.278526;, + 5.765529;41.666725;65.621597;, + 8.695706;44.714546;64.299896;, + 4.743902;39.976799;65.832298;, + 3.211673;38.031998;67.529678;, + 9.944007;42.345741;53.625164;, + 12.935205;47.844864;50.501919;, + 15.425858;52.496346;49.328674;, + 16.161591;55.654251;48.952625;, + 15.159414;50.197842;49.912075;, + 14.663563;60.533600;62.358627;, + 13.234347;55.010292;62.553223;, + 14.883218;62.889500;62.645046;, + 15.123456;66.809219;62.450409;, + 15.577708;56.205627;47.969166;, + 14.997487;70.420540;62.992817;, + 14.301835;74.380287;64.488983;, + 13.980994;81.275604;65.186821;, + 8.751598;82.575844;67.678185;, + 14.791316;70.832016;46.772766;, + 16.454370;73.054062;51.038074;, + 16.454536;66.013954;51.296288;, + 12.478778;67.291313;66.688377;, + 12.741013;68.411827;65.535583;, + 12.441926;69.568321;65.742271;, + 11.464467;70.134789;66.847923;, + 12.595016;68.737000;65.669327;, + 12.463537;69.289749;65.733955;, + 11.133315;49.345627;63.166481;, + 5.325842;67.702225;68.891853;, + 6.462132;70.041153;68.809387;, + 5.150118;67.060791;68.905960;, + 5.557265;66.767700;68.786423;, + 14.825865;77.561653;59.569633;, + 15.900160;69.911873;57.321053;, + 14.833782;68.331589;44.645512;, + 14.279436;71.116005;45.658489;, + 15.644074;63.130802;45.068886;, + 15.463116;57.616409;47.193058;, + 15.463116;57.616409;47.193058;, + 7.265521;52.817856;41.486317;, + 10.078528;51.383022;45.418407;, + 8.237869;48.950886;46.050209;, + 10.078528;51.383022;45.418407;, + 8.868079;35.209740;45.489132;, + 8.045384;44.502201;46.021900;, + 7.696074;47.204636;47.215710;, + 8.237869;48.950886;46.050209;, + 9.646603;26.610264;45.446602;, + 6.352082;66.607925;68.646599;, + 7.964100;66.116623;68.406441;, + 10.455427;70.382629;67.493866;, + 8.354575;70.568634;68.310120;, + 7.623333;70.645973;68.558647;, + 9.593375;65.951813;67.955978;, + 11.268188;66.503914;67.438225;, + 11.803926;66.665207;67.208046;, + 8.497231;65.898521;68.278526;, + 5.227813;27.441788;34.143456;, + -5.109205;27.415857;34.161194;, + 11.634122;84.699326;70.485474;, + 30.643127;-31.721945;45.652527;, + -30.350075;-31.719879;45.630089;; + 6841; + 3;28,62,1;, + 3;3,16,3420;, + 3;11,23,29;, + 3;104,69,7;, + 3;0,13,70;, + 3;9,97,96;, + 3;3421,71,2;, + 3;15,22,3;, + 3;3420,15,3;, + 3;68,4,15;, + 3;116,111,106;, + 3;3422,12,6;, + 3;6,12,1742;, + 3;24,14,12;, + 3;3423,108,119;, + 3;102,7,13;, + 3;13,30,23;, + 3;3420,2,15;, + 3;115,116,106;, + 3;100,3424,17;, + 3;100,1,3424;, + 3;1,18,19;, + 3;28,1,19;, + 3;104,94,69;, + 3;15,4,20;, + 3;98,8,97;, + 3;115,106,114;, + 3;29,23,126;, + 3;3422,24,12;, + 3;30,0,27;, + 3;26,11,29;, + 3;24,3422,3425;, + 3;27,126,23;, + 3;3426,3427,3428;, + 3;23,11,13;, + 3;13,0,30;, + 3;23,30,27;, + 3;108,107,120;, + 3;31,6,1741;, + 3;25,32,29;, + 3;32,26,29;, + 3;136,132,135;, + 3;32,25,65;, + 3;63,60,35;, + 3;3419,3429,63;, + 3;35,59,34;, + 3;58,59,16;, + 3;41,36,848;, + 3;51,53,49;, + 3;3430,55,49;, + 3;82,848,36;, + 3;24,38,14;, + 3;84,49,53;, + 3;81,82,43;, + 3;83,3431,39;, + 3;41,45,36;, + 3;40,3430,3432;, + 3;41,37,47;, + 3;24,52,48;, + 3;3430,49,84;, + 3;38,48,50;, + 3;38,24,48;, + 3;49,55,50;, + 3;50,51,49;, + 3;55,56,50;, + 3;48,51,50;, + 3;81,43,80;, + 3;67,54,3433;, + 3;39,66,44;, + 3;50,56,38;, + 3;3430,40,55;, + 3;56,57,38;, + 3;55,40,56;, + 3;56,436,57;, + 3;51,48,52;, + 3;3434,3435,3436;, + 3;3437,3438,3435;, + 3;3437,3439,3438;, + 3;33,3439,3437;, + 3;64,3440,3441;, + 3;3442,3443,33;, + 3;3440,3444,3445;, + 3;52,24,3425;, + 3;3434,3436,3446;, + 3;16,59,3420;, + 3;60,3420,59;, + 3;58,34,59;, + 3;60,3421,3420;, + 3;35,60,59;, + 3;61,27,0;, + 3;3447,61,3448;, + 3;28,3449,62;, + 3;3420,3421,2;, + 3;63,3429,3421;, + 3;3419,63,3450;, + 3;63,3421,60;, + 3;33,64,3442;, + 3;3450,63,35;, + 3;65,129,3447;, + 3;3434,3437,3435;, + 3;3444,42,3445;, + 3;3445,3441,3440;, + 3;39,3451,66;, + 3;3441,3442,64;, + 3;53,67,3433;, + 3;33,3443,3439;, + 3;2,68,15;, + 3;3452,3453,69;, + 3;70,13,7;, + 3;3421,3429,71;, + 3;0,70,73;, + 3;73,72,0;, + 3;7,69,75;, + 3;75,74,7;, + 3;3454,3455,77;, + 3;77,76,3454;, + 3;3453,3456,79;, + 3;79,78,3453;, + 3;70,7,74;, + 3;74,73,70;, + 3;69,3453,78;, + 3;78,75,69;, + 3;3456,3454,76;, + 3;76,79,3456;, + 3;3455,0,72;, + 3;72,77,3455;, + 3;80,43,3457;, + 3;43,82,44;, + 3;37,81,80;, + 3;44,82,83;, + 3;81,37,82;, + 3;44,83,39;, + 3;83,82,36;, + 3;3433,84,53;, + 3;83,36,3431;, + 3;3,22,85;, + 3;110,112,113;, + 3;22,89,85;, + 3;110,114,106;, + 3;95,118,111;, + 3;3447,128,61;, + 3;22,90,89;, + 3;110,113,114;, + 3;109,112,110;, + 3;90,22,91;, + 3;15,91,22;, + 3;15,92,91;, + 3;15,20,92;, + 3;92,20,93;, + 3;117,111,116;, + 3;3452,94,3458;, + 3;94,3452,69;, + 3;99,96,21;, + 3;111,117,95;, + 3;9,96,99;, + 3;1739,97,9;, + 3;97,8,21;, + 3;97,21,96;, + 3;10,98,97;, + 3;31,3422,6;, + 3;1741,6,1744;, + 3;88,99,845;, + 3;107,118,95;, + 3;18,100,17;, + 3;18,1,100;, + 3;101,102,13;, + 3;11,101,13;, + 3;119,108,120;, + 3;103,7,102;, + 3;107,121,120;, + 3;95,122,107;, + 3;107,123,121;, + 3;95,117,122;, + 3;107,122,123;, + 3;103,105,104;, + 3;103,104,7;, + 3;3459,5,106;, + 3;106,111,3459;, + 3;3423,3460,108;, + 3;3423,119,3461;, + 3;3462,3463,116;, + 3;116,115,3462;, + 3;3464,3465,122;, + 3;122,117,3464;, + 3;3466,3462,115;, + 3;115,114,3466;, + 3;107,108,3460;, + 3;3467,3468,113;, + 3;113,112,3467;, + 3;3469,3459,111;, + 3;111,118,3469;, + 3;3468,3466,114;, + 3;114,113,3468;, + 3;87,86,109;, + 3;109,110,87;, + 3;3463,3464,117;, + 3;117,116,3463;, + 3;3470,3469,118;, + 3;118,3471,3470;, + 3;3472,3461,119;, + 3;119,120,3472;, + 3;3473,3472,120;, + 3;120,121,3473;, + 3;3474,3473,121;, + 3;121,123,3474;, + 3;3465,3474,123;, + 3;123,122,3465;, + 3;65,25,124;, + 3;130,132,131;, + 3;127,126,27;, + 3;129,128,3447;, + 3;27,125,127;, + 3;29,126,25;, + 3;134,132,130;, + 3;130,133,134;, + 3;125,27,128;, + 3;128,27,61;, + 3;65,124,129;, + 3;131,132,136;, + 3;3475,3476,135;, + 3;135,132,3475;, + 3;3476,3477,136;, + 3;136,135,3476;, + 3;3478,3479,130;, + 3;130,131,3478;, + 3;3480,3481,134;, + 3;134,133,3480;, + 3;3481,3475,132;, + 3;132,134,3481;, + 3;3479,3480,133;, + 3;133,130,3479;, + 3;3477,3478,131;, + 3;131,136,3477;, + 3;158,138,184;, + 3;3,3482,16;, + 3;145,159,153;, + 3;221,143,191;, + 3;137,192,146;, + 3;144,214,215;, + 3;3483,139,193;, + 3;147,3,152;, + 3;3482,3,147;, + 3;190,147,140;, + 3;231,223,227;, + 3;3484,142,12;, + 3;142,1742,12;, + 3;154,12,14;, + 3;3485,234,225;, + 3;219,146,143;, + 3;146,153,160;, + 3;3482,147,139;, + 3;230,223,231;, + 3;217,17,3424;, + 3;217,3424,138;, + 3;138,149,148;, + 3;158,149,138;, + 3;221,191,212;, + 3;147,150,140;, + 3;98,215,8;, + 3;230,229,223;, + 3;159,241,153;, + 3;3484,12,154;, + 3;160,157,137;, + 3;156,159,145;, + 3;154,3486,3484;, + 3;157,153,241;, + 3;3487,3488,3489;, + 3;153,146,145;, + 3;146,160,137;, + 3;153,157,160;, + 3;225,235,224;, + 3;161,1743,142;, + 3;155,159,162;, + 3;162,159,156;, + 3;251,250,247;, + 3;162,187,155;, + 3;185,164,182;, + 3;183,3418,137;, + 3;164,34,181;, + 3;58,16,181;, + 3;168,37,847;, + 3;175,173,177;, + 3;165,173,179;, + 3;203,847,37;, + 3;154,14,38;, + 3;205,177,173;, + 3;202,169,203;, + 3;204,166,3490;, + 3;168,3491,171;, + 3;167,3492,165;, + 3;168,47,37;, + 3;154,172,176;, + 3;165,205,173;, + 3;38,174,172;, + 3;38,172,154;, + 3;173,174,179;, + 3;174,173,175;, + 3;179,174,180;, + 3;172,174,175;, + 3;202,80,169;, + 3;189,3493,178;, + 3;166,170,188;, + 3;174,38,180;, + 3;165,179,167;, + 3;180,38,57;, + 3;179,180,167;, + 3;734,57,46;, + 3;175,176,172;, + 3;3494,3495,3496;, + 3;3497,3496,3498;, + 3;3497,3498,3499;, + 3;163,3497,3499;, + 3;186,3500,3501;, + 3;3502,163,3503;, + 3;3501,3504,3444;, + 3;176,3486,154;, + 3;3494,3505,3495;, + 3;16,3482,181;, + 3;182,181,3482;, + 3;58,181,34;, + 3;182,3482,3483;, + 3;164,181,182;, + 3;183,137,157;, + 3;3506,3507,183;, + 3;158,184,3508;, + 3;3482,139,3483;, + 3;185,3483,3509;, + 3;183,3507,3418;, + 3;185,182,3483;, + 3;163,3502,186;, + 3;3510,164,185;, + 3;187,3506,244;, + 3;3494,3496,3497;, + 3;3444,3504,42;, + 3;3504,3501,3500;, + 3;166,188,3511;, + 3;3500,186,3502;, + 3;177,3493,189;, + 3;163,3499,3503;, + 3;139,147,190;, + 3;3512,191,3513;, + 3;192,143,146;, + 3;3483,193,3509;, + 3;137,195,192;, + 3;195,137,194;, + 3;143,197,191;, + 3;197,143,196;, + 3;3514,199,3515;, + 3;199,3514,198;, + 3;3513,201,3516;, + 3;201,3513,200;, + 3;192,196,143;, + 3;196,192,195;, + 3;191,200,3513;, + 3;200,191,197;, + 3;3516,198,3514;, + 3;198,3516,201;, + 3;3515,194,137;, + 3;194,3515,199;, + 3;80,3457,169;, + 3;169,170,203;, + 3;37,80,202;, + 3;170,204,203;, + 3;202,203,37;, + 3;170,166,204;, + 3;204,3491,203;, + 3;3493,177,205;, + 3;204,3490,3491;, + 3;3,85,152;, + 3;226,228,112;, + 3;152,85,89;, + 3;226,223,229;, + 3;213,227,233;, + 3;3506,183,243;, + 3;152,89,208;, + 3;226,229,228;, + 3;109,226,112;, + 3;208,209,152;, + 3;147,152,209;, + 3;147,209,210;, + 3;147,210,150;, + 3;210,211,150;, + 3;232,231,227;, + 3;3512,3517,212;, + 3;212,191,3512;, + 3;216,151,214;, + 3;227,213,232;, + 3;144,216,214;, + 3;10,1740,215;, + 3;215,151,8;, + 3;215,214,151;, + 3;10,215,98;, + 3;161,142,3484;, + 3;1745,1742,142;, + 3;846,151,216;, + 3;224,213,233;, + 3;148,17,217;, + 3;148,217,138;, + 3;218,146,219;, + 3;145,146,218;, + 3;234,235,225;, + 3;220,219,143;, + 3;224,235,236;, + 3;213,224,237;, + 3;224,236,238;, + 3;213,237,232;, + 3;224,238,237;, + 3;220,221,222;, + 3;220,143,221;, + 3;207,223,141;, + 3;223,207,227;, + 3;3485,225,3518;, + 3;3485,3519,234;, + 3;3520,231,3521;, + 3;231,3520,230;, + 3;3522,237,3523;, + 3;237,3522,232;, + 3;3524,230,3520;, + 3;230,3524,229;, + 3;224,3518,225;, + 3;3467,228,3525;, + 3;228,3467,112;, + 3;141,223,206;, + 3;226,206,223;, + 3;3526,227,207;, + 3;227,3526,233;, + 3;3525,229,3524;, + 3;229,3525,228;, + 3;206,109,86;, + 3;109,206,226;, + 3;3521,232,3522;, + 3;232,3521,231;, + 3;3527,233,3526;, + 3;233,3528,224;, + 3;3529,234,3519;, + 3;234,3529,235;, + 3;3530,235,3529;, + 3;235,3530,236;, + 3;3531,236,3530;, + 3;236,3531,238;, + 3;3523,238,3531;, + 3;238,3523,237;, + 3;187,239,155;, + 3;245,246,247;, + 3;242,157,241;, + 3;244,3506,243;, + 3;157,242,240;, + 3;159,155,241;, + 3;249,245,247;, + 3;245,249,248;, + 3;240,243,157;, + 3;243,183,157;, + 3;187,244,239;, + 3;246,251,247;, + 3;3532,250,3533;, + 3;250,3532,247;, + 3;3533,251,3534;, + 3;251,3533,250;, + 3;3535,245,3536;, + 3;245,3535,246;, + 3;3537,249,3538;, + 3;249,3537,248;, + 3;3538,247,3532;, + 3;247,3538,249;, + 3;3536,248,3537;, + 3;248,3536,245;, + 3;3534,246,3535;, + 3;246,3534,251;, + 3;255,472,550;, + 3;257,258,551;, + 3;252,467,554;, + 3;453,462,446;, + 3;439,447,448;, + 3;265,262,255;, + 3;462,463,460;, + 3;449,438,450;, + 3;439,443,447;, + 3;469,313,465;, + 3;254,289,466;, + 3;466,483,484;, + 3;260,435,432;, + 3;465,468,469;, + 3;260,473,474;, + 3;434,3539,3540;, + 3;259,465,474;, + 3;266,3541,262;, + 3;313,255,262;, + 3;438,449,445;, + 3;459,258,264;, + 3;265,266,262;, + 3;345,287,343;, + 3;486,485,271;, + 3;344,274,275;, + 3;335,534,535;, + 3;273,3542,340;, + 3;279,337,282;, + 3;393,333,269;, + 3;279,333,280;, + 3;3543,476,475;, + 3;397,400,417;, + 3;398,284,402;, + 3;388,284,405;, + 3;342,285,3544;, + 3;399,407,338;, + 3;394,392,3542;, + 3;480,479,285;, + 3;3542,392,342;, + 3;288,340,3542;, + 3;287,333,282;, + 3;344,334,274;, + 3;333,287,345;, + 3;343,275,270;, + 3;3544,285,552;, + 3;340,288,3544;, + 3;399,389,404;, + 3;290,295,296;, + 3;296,291,290;, + 3;291,296,297;, + 3;297,292,291;, + 3;292,297,298;, + 3;298,293,292;, + 3;309,310,299;, + 3;299,294,309;, + 3;300,301,424;, + 3;3545,422,3546;, + 3;301,302,424;, + 3;347,349,422;, + 3;305,423,306;, + 3;271,368,367;, + 3;3547,3548,301;, + 3;301,300,3547;, + 3;301,3549,426;, + 3;3549,301,3548;, + 3;358,426,359;, + 3;3550,359,426;, + 3;360,3551,364;, + 3;272,303,379;, + 3;374,276,277;, + 3;3552,3553,354;, + 3;3554,3555,306;, + 3;425,353,3553;, + 3;3555,3556,305;, + 3;305,306,3555;, + 3;305,3557,304;, + 3;3557,305,3556;, + 3;3558,3559,3546;, + 3;3546,3560,3558;, + 3;380,277,272;, + 3;294,299,308;, + 3;380,384,277;, + 3;3561,362,3550;, + 3;309,293,310;, + 3;310,293,298;, + 3;425,3553,3554;, + 3;518,517,330;, + 3;376,377,3562;, + 3;3543,477,476;, + 3;286,265,478;, + 3;487,277,488;, + 3;324,273,536;, + 3;313,470,255;, + 3;465,313,262;, + 3;502,501,314;, + 3;489,3562,490;, + 3;3563,491,317;, + 3;533,547,537;, + 3;318,492,493;, + 3;494,485,315;, + 3;330,503,504;, + 3;491,272,495;, + 3;495,487,319;, + 3;506,505,320;, + 3;488,277,496;, + 3;496,497,320;, + 3;519,312,520;, + 3;498,346,499;, + 3;499,489,316;, + 3;497,276,500;, + 3;500,3564,3565;, + 3;507,312,508;, + 3;510,509,319;, + 3;323,268,322;, + 3;512,511,3566;, + 3;466,3540,254;, + 3;550,478,255;, + 3;286,478,479;, + 3;410,387,411;, + 3;390,265,286;, + 3;332,289,254;, + 3;289,256,466;, + 3;281,256,289;, + 3;281,258,256;, + 3;279,548,391;, + 3;279,280,549;, + 3;549,280,261;, + 3;311,472,475;, + 3;3567,472,3568;, + 3;335,340,3544;, + 3;519,323,521;, + 3;513,511,325;, + 3;318,503,514;, + 3;3569,509,327;, + 3;515,505,328;, + 3;516,318,514;, + 3;506,3570,329;, + 3;504,501,330;, + 3;522,518,330;, + 3;267,538,539;, + 3;540,275,541;, + 3;526,278,527;, + 3;525,526,329;, + 3;507,321,515;, + 3;528,322,529;, + 3;521,528,331;, + 3;529,322,530;, + 3;502,513,325;, + 3;510,319,508;, + 3;531,328,527;, + 3;324,532,531;, + 3;325,3571,523;, + 3;420,400,418;, + 3;266,3572,3541;, + 3;279,282,333;, + 3;267,269,553;, + 3;414,409,416;, + 3;287,282,334;, + 3;536,544,336;, + 3;268,534,3573;, + 3;520,312,532;, + 3;548,281,391;, + 3;284,398,403;, + 3;410,416,409;, + 3;338,389,399;, + 3;288,341,3544;, + 3;3542,341,288;, + 3;273,340,543;, + 3;3542,339,341;, + 3;341,339,3544;, + 3;339,342,3544;, + 3;3542,342,339;, + 3;343,344,275;, + 3;267,343,270;, + 3;287,344,343;, + 3;287,334,344;, + 3;267,345,343;, + 3;553,345,267;, + 3;486,498,314;, + 3;347,3545,357;, + 3;271,367,346;, + 3;348,368,271;, + 3;493,348,494;, + 3;370,348,371;, + 3;350,3574,349;, + 3;422,3574,3560;, + 3;348,369,368;, + 3;3575,351,306;, + 3;369,348,370;, + 3;348,307,371;, + 3;306,425,3554;, + 3;351,352,306;, + 3;371,307,372;, + 3;354,3553,353;, + 3;384,374,277;, + 3;3576,276,375;, + 3;374,375,276;, + 3;346,376,3562;, + 3;367,376,346;, + 3;3577,302,358;, + 3;3550,426,3549;, + 3;359,3550,362;, + 3;3562,377,378;, + 3;385,373,3576;, + 3;3576,375,385;, + 3;355,3552,356;, + 3;3578,3552,355;, + 3;379,303,382;, + 3;3561,3551,360;, + 3;3551,361,364;, + 3;3551,3579,361;, + 3;378,381,3562;, + 3;3561,363,362;, + 3;360,363,3561;, + 3;383,380,272;, + 3;379,383,272;, + 3;361,3579,365;, + 3;3578,355,3580;, + 3;366,356,3552;, + 3;3552,354,366;, + 3;3581,3582,367;, + 3;367,368,3581;, + 3;3583,3584,378;, + 3;378,377,3583;, + 3;3585,3586,383;, + 3;383,379,3585;, + 3;3587,3588,371;, + 3;371,372,3587;, + 3;3589,3590,384;, + 3;384,380,3589;, + 3;3591,3583,377;, + 3;377,376,3591;, + 3;3582,3591,376;, + 3;376,367,3582;, + 3;3588,3592,370;, + 3;370,371,3588;, + 3;3593,3581,368;, + 3;368,369,3593;, + 3;3592,3593,369;, + 3;369,370,3592;, + 3;3590,3594,374;, + 3;374,384,3590;, + 3;3594,3595,375;, + 3;375,374,3594;, + 3;3584,3596,381;, + 3;381,378,3584;, + 3;3597,3598,373;, + 3;373,385,3597;, + 3;3595,3597,385;, + 3;385,375,3595;, + 3;3599,3585,379;, + 3;379,382,3599;, + 3;3586,3589,380;, + 3;380,383,3586;, + 3;338,386,389;, + 3;409,387,410;, + 3;418,400,401;, + 3;418,401,419;, + 3;409,412,387;, + 3;284,403,405;, + 3;419,401,413;, + 3;413,401,396;, + 3;415,413,396;, + 3;266,265,390;, + 3;405,408,388;, + 3;279,391,337;, + 3;395,479,480;, + 3;392,285,342;, + 3;393,280,333;, + 3;477,3543,3600;, + 3;338,407,406;, + 3;3601,274,334;, + 3;480,285,392;, + 3;395,392,394;, + 3;3602,3603,403;, + 3;403,398,3602;, + 3;3604,3605,400;, + 3;400,397,3604;, + 3;3606,3604,397;, + 3;397,408,3606;, + 3;3607,3602,398;, + 3;398,402,3607;, + 3;3603,3606,405;, + 3;405,403,3603;, + 3;3608,3609,399;, + 3;399,404,3608;, + 3;3605,3610,401;, + 3;401,400,3605;, + 3;3610,3611,396;, + 3;396,401,3610;, + 3;3612,3607,402;, + 3;402,406,3612;, + 3;3611,3608,404;, + 3;404,396,3611;, + 3;3609,3613,407;, + 3;407,399,3609;, + 3;3613,3612,406;, + 3;406,407,3613;, + 3;417,400,420;, + 3;408,405,3606;, + 3;397,417,408;, + 3;402,284,409;, + 3;409,414,402;, + 3;338,406,416;, + 3;416,410,338;, + 3;404,389,413;, + 3;413,415,404;, + 3;386,338,410;, + 3;410,411,386;, + 3;406,402,414;, + 3;414,416,406;, + 3;389,386,411;, + 3;411,413,389;, + 3;284,388,412;, + 3;412,409,284;, + 3;396,404,415;, + 3;388,408,417;, + 3;417,412,388;, + 3;411,387,418;, + 3;418,419,411;, + 3;387,412,420;, + 3;420,418,387;, + 3;413,411,419;, + 3;417,420,412;, + 3;258,421,264;, + 3;421,258,257;, + 3;3598,3576,373;, + 3;354,353,3614;, + 3;3587,372,307;, + 3;362,363,3615;, + 3;3599,382,303;, + 3;381,3596,3562;, + 3;422,349,3574;, + 3;422,3560,3546;, + 3;3575,306,423;, + 3;423,305,304;, + 3;424,302,3577;, + 3;422,3545,347;, + 3;306,352,425;, + 3;352,353,425;, + 3;358,302,426;, + 3;301,426,302;, + 3;444,443,442;, + 3;443,439,442;, + 3;454,457,455;, + 3;438,445,452;, + 3;432,431,464;, + 3;432,473,260;, + 3;263,433,434;, + 3;482,434,3540;, + 3;431,427,464;, + 3;464,427,556;, + 3;448,451,440;, + 3;448,440,439;, + 3;450,3616,3617;, + 3;438,3616,450;, + 3;429,433,263;, + 3;458,481,459;, + 3;452,445,3618;, + 3;454,456,457;, + 3;462,460,446;, + 3;428,3619,443;, + 3;443,444,428;, + 3;3620,3621,448;, + 3;448,447,3620;, + 3;3622,3623,449;, + 3;449,450,3622;, + 3;3619,3620,447;, + 3;447,443,3619;, + 3;3621,3624,451;, + 3;451,448,3621;, + 3;3625,3622,450;, + 3;450,3617,3625;, + 3;3623,3626,445;, + 3;445,449,3623;, + 3;3627,3628,442;, + 3;442,439,3627;, + 3;3629,3630,438;, + 3;438,452,3629;, + 3;3631,3627,439;, + 3;439,440,3631;, + 3;3630,3632,3616;, + 3;3616,438,3630;, + 3;3626,437,3618;, + 3;3618,445,3626;, + 3;3633,3634,3635;, + 3;3635,441,3633;, + 3;3636,3637,455;, + 3;455,457,3636;, + 3;3635,3636,457;, + 3;457,456,3635;, + 3;441,3635,456;, + 3;456,454,441;, + 3;429,458,3638;, + 3;429,481,458;, + 3;256,258,459;, + 3;463,461,460;, + 3;3638,458,462;, + 3;462,453,3638;, + 3;458,459,463;, + 3;463,462,458;, + 3;459,264,461;, + 3;461,463,459;, + 3;253,430,446;, + 3;446,460,253;, + 3;264,253,460;, + 3;3639,3640,3641;, + 3;556,427,554;, + 3;473,259,474;, + 3;3541,474,262;, + 3;259,468,465;, + 3;466,256,483;, + 3;3540,466,482;, + 3;259,467,468;, + 3;464,467,259;, + 3;467,252,468;, + 3;469,555,3568;, + 3;469,468,252;, + 3;470,313,469;, + 3;3568,470,469;, + 3;470,3568,471;, + 3;472,255,471;, + 3;470,471,255;, + 3;3568,472,471;, + 3;311,283,472;, + 3;432,464,473;, + 3;464,259,473;, + 3;474,465,262;, + 3;260,474,3541;, + 3;475,472,3567;, + 3;3543,475,3567;, + 3;476,477,311;, + 3;476,311,475;, + 3;3544,552,3600;, + 3;477,285,311;, + 3;265,255,478;, + 3;478,283,311;, + 3;479,478,311;, + 3;479,311,285;, + 3;395,480,392;, + 3;286,479,395;, + 3;429,263,481;, + 3;481,263,484;, + 3;482,466,484;, + 3;263,434,482;, + 3;483,256,459;, + 3;483,459,484;, + 3;484,459,481;, + 3;482,484,263;, + 3;486,315,485;, + 3;314,315,486;, + 3;319,487,488;, + 3;319,488,321;, + 3;316,489,490;, + 3;316,490,3566;, + 3;3563,272,491;, + 3;303,272,3563;, + 3;493,492,348;, + 3;492,307,348;, + 3;494,271,485;, + 3;348,271,494;, + 3;317,491,495;, + 3;317,495,319;, + 3;495,277,487;, + 3;272,277,495;, + 3;321,488,496;, + 3;321,496,320;, + 3;496,276,497;, + 3;277,276,496;, + 3;314,498,499;, + 3;314,499,316;, + 3;499,3562,489;, + 3;346,3562,499;, + 3;320,497,500;, + 3;320,500,3565;, + 3;500,3576,3564;, + 3;276,3576,500;, + 3;486,346,498;, + 3;271,346,486;, + 3;318,493,494;, + 3;318,494,315;, + 3;502,325,501;, + 3;325,545,501;, + 3;504,503,315;, + 3;503,318,315;, + 3;506,328,505;, + 3;329,328,506;, + 3;321,507,508;, + 3;321,508,319;, + 3;510,331,509;, + 3;331,327,509;, + 3;512,325,511;, + 3;3642,325,512;, + 3;513,3566,511;, + 3;316,3566,513;, + 3;514,503,326;, + 3;503,330,326;, + 3;3569,319,509;, + 3;317,319,3569;, + 3;515,320,505;, + 3;321,320,515;, + 3;3643,516,514;, + 3;3643,514,326;, + 3;506,3565,3570;, + 3;320,3565,506;, + 3;504,314,501;, + 3;315,314,504;, + 3;312,507,515;, + 3;312,515,328;, + 3;502,316,513;, + 3;314,316,502;, + 3;331,510,508;, + 3;331,508,312;, + 3;542,540,517;, + 3;336,519,520;, + 3;323,519,336;, + 3;331,519,521;, + 3;312,519,331;, + 3;538,542,522;, + 3;523,522,325;, + 3;522,545,325;, + 3;326,517,524;, + 3;330,517,326;, + 3;524,3644,326;, + 3;3644,3643,326;, + 3;329,526,527;, + 3;329,527,328;, + 3;525,278,526;, + 3;275,3645,541;, + 3;327,528,529;, + 3;331,528,327;, + 3;521,323,528;, + 3;323,322,528;, + 3;327,529,530;, + 3;3642,3571,325;, + 3;324,531,527;, + 3;324,527,278;, + 3;531,532,328;, + 3;532,312,328;, + 3;539,537,267;, + 3;336,520,532;, + 3;336,532,324;, + 3;267,537,547;, + 3;535,534,323;, + 3;534,268,323;, + 3;546,275,274;, + 3;278,273,324;, + 3;3646,533,537;, + 3;3646,537,3647;, + 3;536,336,324;, + 3;539,538,523;, + 3;538,522,523;, + 3;517,540,541;, + 3;517,541,524;, + 3;541,3644,524;, + 3;536,543,544;, + 3;273,543,536;, + 3;3573,534,335;, + 3;3573,335,3648;, + 3;535,323,336;, + 3;3542,273,3649;, + 3;518,542,517;, + 3;542,275,540;, + 3;270,275,542;, + 3;522,542,518;, + 3;538,267,542;, + 3;267,270,542;, + 3;541,3645,3644;, + 3;539,523,537;, + 3;523,3571,537;, + 3;3571,3647,537;, + 3;543,340,335;, + 3;543,335,535;, + 3;544,543,535;, + 3;544,535,336;, + 3;522,330,545;, + 3;545,330,501;, + 3;3649,273,278;, + 3;3645,275,546;, + 3;3648,335,3544;, + 3;547,269,267;, + 3;279,258,548;, + 3;258,281,548;, + 3;258,549,551;, + 3;279,549,258;, + 3;550,472,283;, + 3;283,478,550;, + 3;551,549,261;, + 3;257,551,261;, + 3;552,285,477;, + 3;552,477,3600;, + 3;553,269,333;, + 3;333,345,553;, + 3;554,427,3650;, + 3;469,252,555;, + 3;467,556,554;, + 3;464,556,467;, + 3;558,840,762;, + 3;257,841,560;, + 3;252,554,757;, + 3;747,446,752;, + 3;737,742,741;, + 3;566,558,564;, + 3;752,460,753;, + 3;743,744,736;, + 3;737,741,739;, + 3;759,755,614;, + 3;557,756,590;, + 3;756,774,773;, + 3;562,730,733;, + 3;755,759,758;, + 3;562,764,763;, + 3;732,3651,3652;, + 3;561,764,755;, + 3;567,564,3653;, + 3;614,564,558;, + 3;736,740,743;, + 3;751,264,560;, + 3;566,564,567;, + 3;646,644,588;, + 3;776,572,775;, + 3;645,576,575;, + 3;636,825,824;, + 3;574,641,3654;, + 3;580,583,638;, + 3;694,570,634;, + 3;580,581,634;, + 3;3655,765,766;, + 3;698,718,701;, + 3;699,703,585;, + 3;689,706,585;, + 3;643,3656,586;, + 3;700,639,708;, + 3;695,3654,693;, + 3;770,586,769;, + 3;3654,643,693;, + 3;589,3654,641;, + 3;588,583,634;, + 3;645,575,635;, + 3;634,646,588;, + 3;644,571,576;, + 3;3656,842,586;, + 3;641,3656,589;, + 3;700,705,690;, + 3;591,597,596;, + 3;597,591,592;, + 3;592,598,597;, + 3;598,592,593;, + 3;593,599,598;, + 3;599,593,594;, + 3;610,600,611;, + 3;600,610,595;, + 3;601,724,602;, + 3;3657,3658,722;, + 3;602,724,603;, + 3;648,722,650;, + 3;606,607,723;, + 3;572,668,669;, + 3;3659,602,3660;, + 3;602,3659,601;, + 3;602,726,3661;, + 3;3661,3660,602;, + 3;659,660,726;, + 3;3662,726,660;, + 3;661,665,3663;, + 3;573,680,604;, + 3;675,578,577;, + 3;3664,655,3665;, + 3;3666,607,3667;, + 3;725,3665,654;, + 3;3667,606,3668;, + 3;606,3667,607;, + 3;606,605,3669;, + 3;3669,3668,606;, + 3;3670,3658,3671;, + 3;3658,3670,3672;, + 3;681,573,578;, + 3;595,609,600;, + 3;681,578,685;, + 3;3673,3662,663;, + 3;610,611,594;, + 3;611,599,594;, + 3;725,3666,3665;, + 3;808,631,807;, + 3;677,3674,678;, + 3;3655,766,767;, + 3;587,768,566;, + 3;777,778,578;, + 3;625,826,574;, + 3;614,558,760;, + 3;755,564,614;, + 3;792,615,791;, + 3;779,780,3674;, + 3;3675,618,781;, + 3;823,827,837;, + 3;619,783,782;, + 3;784,616,775;, + 3;631,794,793;, + 3;781,785,573;, + 3;785,620,777;, + 3;796,621,795;, + 3;778,786,578;, + 3;786,621,787;, + 3;809,810,613;, + 3;788,789,647;, + 3;789,617,779;, + 3;787,790,577;, + 3;790,3676,3677;, + 3;797,798,613;, + 3;800,620,799;, + 3;624,623,569;, + 3;802,3678,801;, + 3;756,557,3651;, + 3;840,558,768;, + 3;587,769,768;, + 3;711,712,688;, + 3;691,587,566;, + 3;633,557,590;, + 3;590,756,559;, + 3;582,590,559;, + 3;582,559,560;, + 3;580,692,838;, + 3;580,839,581;, + 3;839,563,581;, + 3;612,765,762;, + 3;3679,3568,762;, + 3;636,3656,641;, + 3;809,811,624;, + 3;803,626,801;, + 3;619,804,793;, + 3;3680,628,799;, + 3;805,629,795;, + 3;806,804,619;, + 3;796,630,3681;, + 3;794,631,791;, + 3;812,631,808;, + 3;568,829,828;, + 3;830,831,576;, + 3;816,817,579;, + 3;815,630,816;, + 3;797,805,622;, + 3;818,819,623;, + 3;811,632,818;, + 3;819,820,623;, + 3;792,626,803;, + 3;800,798,620;, + 3;821,817,629;, + 3;625,821,822;, + 3;626,813,3682;, + 3;721,719,701;, + 3;567,3653,3683;, + 3;580,634,583;, + 3;568,843,570;, + 3;715,717,710;, + 3;588,635,583;, + 3;826,637,834;, + 3;569,3684,824;, + 3;810,822,613;, + 3;838,692,582;, + 3;585,704,699;, + 3;711,710,717;, + 3;639,700,690;, + 3;589,3656,642;, + 3;3654,589,642;, + 3;574,833,641;, + 3;3654,642,640;, + 3;642,3656,640;, + 3;640,3656,643;, + 3;3654,640,643;, + 3;644,576,645;, + 3;568,571,644;, + 3;588,644,645;, + 3;588,645,635;, + 3;568,644,646;, + 3;843,568,646;, + 3;776,615,788;, + 3;724,658,603;, + 3;572,647,668;, + 3;649,572,669;, + 3;783,784,649;, + 3;671,672,649;, + 3;651,650,3685;, + 3;722,3672,3685;, + 3;649,669,670;, + 3;3686,607,652;, + 3;670,671,649;, + 3;649,672,608;, + 3;607,3666,725;, + 3;652,607,653;, + 3;672,673,608;, + 3;655,654,3665;, + 3;685,578,675;, + 3;3687,676,577;, + 3;675,577,676;, + 3;647,3674,677;, + 3;668,647,677;, + 3;658,659,603;, + 3;3662,3661,726;, + 3;660,663,3662;, + 3;3674,679,678;, + 3;686,3687,674;, + 3;3687,686,676;, + 3;656,657,3664;, + 3;3688,656,3664;, + 3;680,683,604;, + 3;3673,661,3663;, + 3;3663,665,662;, + 3;3663,662,3689;, + 3;679,3674,682;, + 3;3673,663,664;, + 3;661,3673,664;, + 3;684,573,681;, + 3;680,573,684;, + 3;662,666,3689;, + 3;3688,3690,656;, + 3;667,3664,657;, + 3;3664,667,655;, + 3;3691,668,3692;, + 3;668,3691,669;, + 3;3693,679,3694;, + 3;679,3693,678;, + 3;3695,684,3696;, + 3;684,3695,680;, + 3;3697,672,3698;, + 3;672,3697,673;, + 3;3699,685,3700;, + 3;685,3699,681;, + 3;3701,678,3693;, + 3;678,3701,677;, + 3;3692,677,3701;, + 3;677,3692,668;, + 3;3698,671,3702;, + 3;671,3698,672;, + 3;3703,669,3691;, + 3;669,3703,670;, + 3;3702,670,3703;, + 3;670,3702,671;, + 3;3700,675,3704;, + 3;675,3700,685;, + 3;3704,676,3705;, + 3;676,3704,675;, + 3;3694,682,3706;, + 3;682,3694,679;, + 3;3707,674,3708;, + 3;674,3707,686;, + 3;3705,686,3707;, + 3;686,3705,676;, + 3;3709,680,3695;, + 3;680,3709,683;, + 3;3696,681,3699;, + 3;681,3696,684;, + 3;639,690,687;, + 3;710,711,688;, + 3;719,702,701;, + 3;719,720,702;, + 3;710,688,713;, + 3;585,706,704;, + 3;720,714,702;, + 3;714,697,702;, + 3;716,697,714;, + 3;567,691,566;, + 3;706,689,709;, + 3;580,638,692;, + 3;696,770,769;, + 3;693,643,586;, + 3;694,634,581;, + 3;767,3710,3655;, + 3;639,707,708;, + 3;3711,635,575;, + 3;770,693,586;, + 3;696,695,693;, + 3;3712,704,3713;, + 3;704,3712,699;, + 3;3714,701,3715;, + 3;701,3714,698;, + 3;3716,698,3714;, + 3;698,3716,709;, + 3;3717,699,3712;, + 3;699,3717,703;, + 3;3713,706,3716;, + 3;706,3713,704;, + 3;3718,700,3719;, + 3;700,3718,705;, + 3;3715,702,3720;, + 3;702,3715,701;, + 3;3720,697,3721;, + 3;697,3720,702;, + 3;3722,703,3717;, + 3;703,3722,707;, + 3;3721,705,3718;, + 3;705,3721,697;, + 3;3719,708,3723;, + 3;708,3719,700;, + 3;3723,707,3722;, + 3;707,3723,708;, + 3;718,721,701;, + 3;709,3716,706;, + 3;698,709,718;, + 3;703,710,585;, + 3;710,703,715;, + 3;639,717,707;, + 3;717,639,711;, + 3;705,714,690;, + 3;714,705,716;, + 3;687,711,639;, + 3;711,687,712;, + 3;707,715,703;, + 3;715,707,717;, + 3;690,712,687;, + 3;712,690,714;, + 3;585,713,689;, + 3;713,585,710;, + 3;697,716,705;, + 3;689,718,709;, + 3;718,689,713;, + 3;712,719,688;, + 3;719,712,720;, + 3;688,721,713;, + 3;721,688,719;, + 3;714,720,712;, + 3;718,713,721;, + 3;560,264,421;, + 3;421,257,560;, + 3;3708,674,3687;, + 3;655,3724,654;, + 3;3697,608,673;, + 3;663,3725,664;, + 3;3709,604,683;, + 3;682,3674,3706;, + 3;722,3685,650;, + 3;722,3658,3672;, + 3;3686,723,607;, + 3;723,605,606;, + 3;3657,648,3726;, + 3;722,648,3657;, + 3;607,725,653;, + 3;653,725,654;, + 3;659,726,603;, + 3;602,603,726;, + 3;444,442,739;, + 3;739,442,737;, + 3;454,455,749;, + 3;736,746,740;, + 3;730,754,729;, + 3;730,562,763;, + 3;565,732,731;, + 3;772,3651,732;, + 3;729,754,727;, + 3;754,844,727;, + 3;742,738,745;, + 3;742,737,738;, + 3;744,3727,3728;, + 3;736,744,3728;, + 3;728,565,731;, + 3;750,751,771;, + 3;746,3729,740;, + 3;454,749,748;, + 3;752,446,460;, + 3;428,739,3730;, + 3;739,428,444;, + 3;3731,742,3732;, + 3;742,3731,741;, + 3;3733,743,3734;, + 3;743,3733,744;, + 3;3730,741,3731;, + 3;741,3730,739;, + 3;3732,745,3735;, + 3;745,3732,742;, + 3;3736,744,3733;, + 3;744,3736,3727;, + 3;3734,740,3737;, + 3;740,3734,743;, + 3;3738,442,3628;, + 3;442,3738,737;, + 3;3739,736,3740;, + 3;736,3739,746;, + 3;3741,737,3738;, + 3;737,3741,738;, + 3;3740,3728,3742;, + 3;3728,3740,736;, + 3;3737,3729,735;, + 3;3729,3737,740;, + 3;3633,3743,3744;, + 3;3743,3633,441;, + 3;3745,455,3637;, + 3;455,3745,749;, + 3;3743,749,3745;, + 3;749,3743,748;, + 3;441,748,3743;, + 3;748,441,454;, + 3;728,3746,750;, + 3;728,750,771;, + 3;559,751,560;, + 3;753,460,461;, + 3;3746,752,750;, + 3;752,3746,747;, + 3;750,753,751;, + 3;753,750,752;, + 3;751,461,264;, + 3;461,751,753;, + 3;253,446,430;, + 3;446,253,460;, + 3;264,460,253;, + 3;460,264,461;, + 3;844,554,727;, + 3;763,764,561;, + 3;3653,564,764;, + 3;561,755,758;, + 3;756,773,559;, + 3;3651,772,756;, + 3;561,758,757;, + 3;754,561,757;, + 3;757,758,252;, + 3;759,3568,555;, + 3;759,252,758;, + 3;760,759,614;, + 3;3568,759,760;, + 3;760,761,3568;, + 3;762,761,558;, + 3;760,558,761;, + 3;3568,761,762;, + 3;612,762,584;, + 3;730,763,754;, + 3;754,763,561;, + 3;764,564,755;, + 3;562,3653,764;, + 3;765,3679,762;, + 3;3655,3679,765;, + 3;766,612,767;, + 3;766,765,612;, + 3;3656,3710,842;, + 3;767,612,586;, + 3;566,768,558;, + 3;768,612,584;, + 3;769,612,768;, + 3;769,586,612;, + 3;696,693,770;, + 3;587,696,769;, + 3;728,771,565;, + 3;771,774,565;, + 3;772,774,756;, + 3;565,772,732;, + 3;773,751,559;, + 3;773,774,751;, + 3;774,771,751;, + 3;772,565,774;, + 3;776,775,616;, + 3;615,776,616;, + 3;620,778,777;, + 3;620,622,778;, + 3;617,780,779;, + 3;617,3678,780;, + 3;3675,781,573;, + 3;604,3675,573;, + 3;783,649,782;, + 3;782,649,608;, + 3;784,775,572;, + 3;649,784,572;, + 3;618,785,781;, + 3;618,620,785;, + 3;785,777,578;, + 3;573,785,578;, + 3;622,786,778;, + 3;622,621,786;, + 3;786,787,577;, + 3;578,786,577;, + 3;615,789,788;, + 3;615,617,789;, + 3;789,779,3674;, + 3;647,789,3674;, + 3;621,790,787;, + 3;621,3676,790;, + 3;790,3677,3687;, + 3;577,790,3687;, + 3;776,788,647;, + 3;572,776,647;, + 3;619,784,783;, + 3;619,616,784;, + 3;792,791,626;, + 3;626,791,835;, + 3;794,616,793;, + 3;793,616,619;, + 3;796,795,629;, + 3;630,796,629;, + 3;622,798,797;, + 3;622,620,798;, + 3;800,799,632;, + 3;632,799,628;, + 3;802,801,626;, + 3;3747,802,626;, + 3;803,801,3678;, + 3;617,803,3678;, + 3;804,627,793;, + 3;793,627,631;, + 3;3680,799,620;, + 3;618,3680,620;, + 3;805,795,621;, + 3;622,805,621;, + 3;3748,804,806;, + 3;3748,627,804;, + 3;796,3681,3676;, + 3;621,796,3676;, + 3;794,791,615;, + 3;616,794,615;, + 3;613,805,797;, + 3;613,629,805;, + 3;792,803,617;, + 3;615,792,617;, + 3;632,798,800;, + 3;632,613,798;, + 3;832,807,830;, + 3;637,810,809;, + 3;624,637,809;, + 3;632,811,809;, + 3;613,632,809;, + 3;828,812,832;, + 3;813,626,812;, + 3;812,626,835;, + 3;627,814,807;, + 3;631,627,807;, + 3;814,627,3749;, + 3;3749,627,3748;, + 3;630,817,816;, + 3;630,629,817;, + 3;815,816,579;, + 3;576,831,3750;, + 3;628,819,818;, + 3;632,628,818;, + 3;811,818,624;, + 3;624,818,623;, + 3;628,820,819;, + 3;3747,626,3682;, + 3;625,817,821;, + 3;625,579,817;, + 3;821,629,822;, + 3;822,629,613;, + 3;829,568,827;, + 3;637,822,810;, + 3;637,625,822;, + 3;568,837,827;, + 3;825,624,824;, + 3;824,624,569;, + 3;836,575,576;, + 3;579,625,574;, + 3;3751,827,823;, + 3;3751,3752,827;, + 3;826,625,637;, + 3;829,813,828;, + 3;828,813,812;, + 3;807,831,830;, + 3;807,814,831;, + 3;831,814,3749;, + 3;826,834,833;, + 3;574,826,833;, + 3;3684,636,824;, + 3;3684,3753,636;, + 3;825,637,624;, + 3;3654,3754,574;, + 3;808,807,832;, + 3;832,830,576;, + 3;571,832,576;, + 3;812,808,832;, + 3;828,832,568;, + 3;568,832,571;, + 3;831,3749,3750;, + 3;829,827,813;, + 3;813,827,3682;, + 3;3682,827,3752;, + 3;833,636,641;, + 3;833,825,636;, + 3;834,825,833;, + 3;834,637,825;, + 3;812,835,631;, + 3;835,791,631;, + 3;3754,579,574;, + 3;3750,836,576;, + 3;3753,3656,636;, + 3;837,568,570;, + 3;580,838,560;, + 3;560,838,582;, + 3;560,841,839;, + 3;580,560,839;, + 3;840,584,762;, + 3;584,840,768;, + 3;841,563,839;, + 3;257,563,841;, + 3;842,767,586;, + 3;842,3710,767;, + 3;843,634,570;, + 3;634,843,646;, + 3;554,3650,727;, + 3;759,555,252;, + 3;757,554,844;, + 3;754,757,844;, + 3;845,99,21;, + 3;3755,846,216;, + 3;180,734,167;, + 3;180,57,734;, + 3;46,57,436;, + 3;436,56,40;, + 3;203,3491,847;, + 3;168,847,3491;, + 3;82,37,848;, + 3;41,848,37;, + 3;849,1291,850;, + 3;943,852,851;, + 3;849,1290,944;, + 3;1289,854,1293;, + 3;854,1289,944;, + 3;859,888,945;, + 3;855,861,887;, + 3;946,856,3756;, + 3;1292,3757,3758;, + 3;3757,3759,3760;, + 3;852,946,851;, + 3;857,889,849;, + 3;858,857,850;, + 3;850,857,849;, + 3;853,860,1290;, + 3;3761,861,3758;, + 3;3758,861,855;, + 3;887,859,945;, + 3;875,891,890;, + 3;893,892,862;, + 3;894,869,895;, + 3;897,896,863;, + 3;898,876,899;, + 3;900,862,892;, + 3;902,901,874;, + 3;898,877,903;, + 3;868,904,890;, + 3;894,864,905;, + 3;905,864,904;, + 3;896,872,895;, + 3;867,902,906;, + 3;3762,3763,891;, + 3;899,906,865;, + 3;903,3764,3765;, + 3;901,900,874;, + 3;3763,880,868;, + 3;880,3763,879;, + 3;867,882,878;, + 3;882,867,881;, + 3;3765,884,876;, + 3;884,3765,883;, + 3;866,886,869;, + 3;886,866,885;, + 3;868,880,866;, + 3;885,866,880;, + 3;869,3766,863;, + 3;3766,869,886;, + 3;876,881,867;, + 3;881,876,884;, + 3;878,3767,862;, + 3;3767,878,882;, + 3;870,3768,871;, + 3;3768,870,3769;, + 3;872,3770,864;, + 3;3770,872,3771;, + 3;873,3771,872;, + 3;3771,873,3772;, + 3;865,3773,877;, + 3;3773,865,3774;, + 3;871,3775,874;, + 3;3775,871,3768;, + 3;864,3776,875;, + 3;3776,864,3770;, + 3;874,3774,865;, + 3;3774,874,3775;, + 3;875,3777,3778;, + 3;3777,875,3776;, + 3;877,3779,3780;, + 3;3779,877,3773;, + 3;890,891,868;, + 3;868,891,3763;, + 3;892,893,871;, + 3;871,893,870;, + 3;894,895,864;, + 3;864,895,872;, + 3;896,897,872;, + 3;872,897,873;, + 3;898,899,877;, + 3;877,899,865;, + 3;900,892,874;, + 3;874,892,871;, + 3;901,902,878;, + 3;878,902,867;, + 3;898,903,876;, + 3;876,903,3765;, + 3;890,904,875;, + 3;875,904,864;, + 3;894,905,869;, + 3;869,905,866;, + 3;905,904,866;, + 3;866,904,868;, + 3;896,895,863;, + 3;863,895,869;, + 3;906,902,865;, + 3;865,902,874;, + 3;3762,891,3778;, + 3;3778,891,875;, + 3;906,899,867;, + 3;867,899,876;, + 3;3764,903,3780;, + 3;3780,903,877;, + 3;900,901,862;, + 3;862,901,878;, + 3;889,1290,849;, + 3;3781,858,850;, + 3;855,887,945;, + 3;921,939,908;, + 3;942,922,3782;, + 3;923,910,924;, + 3;907,926,925;, + 3;926,927,911;, + 3;929,928,915;, + 3;3783,919,913;, + 3;931,930,913;, + 3;941,920,908;, + 3;931,932,3784;, + 3;929,933,908;, + 3;916,918,3785;, + 3;917,3786,913;, + 3;935,934,914;, + 3;916,935,936;, + 3;937,3787,938;, + 3;3788,3785,918;, + 3;3789,909,919;, + 3;912,3790,3791;, + 3;916,3786,917;, + 3;934,930,914;, + 3;918,3792,3788;, + 3;936,3787,937;, + 3;3783,913,3786;, + 3;932,3793,3784;, + 3;928,3794,915;, + 3;940,908,939;, + 3;907,942,940;, + 3;927,933,911;, + 3;922,3795,3782;, + 3;925,910,923;, + 3;923,924,922;, + 3;922,924,3795;, + 3;925,926,910;, + 3;910,926,911;, + 3;927,926,921;, + 3;921,926,907;, + 3;928,929,920;, + 3;920,929,908;, + 3;930,931,914;, + 3;914,931,3784;, + 3;932,931,919;, + 3;919,931,913;, + 3;933,929,911;, + 3;911,929,915;, + 3;934,935,917;, + 3;917,935,916;, + 3;936,935,3787;, + 3;3787,935,914;, + 3;937,938,918;, + 3;918,938,3792;, + 3;930,934,913;, + 3;913,934,917;, + 3;936,937,916;, + 3;916,937,918;, + 3;3793,932,909;, + 3;909,932,919;, + 3;3794,928,912;, + 3;912,928,920;, + 3;933,927,908;, + 3;908,927,921;, + 3;925,923,907;, + 3;907,923,922;, + 3;912,920,3790;, + 3;3782,3795,3796;, + 3;940,3782,3797;, + 3;941,940,3790;, + 3;907,939,921;, + 3;939,907,940;, + 3;940,3797,3790;, + 3;3790,920,941;, + 3;908,940,941;, + 3;907,922,942;, + 3;942,3782,940;, + 3;3789,919,3783;, + 3;3785,3786,916;, + 3;1289,852,943;, + 3;849,944,1289;, + 3;854,944,1290;, + 3;3798,3781,850;, + 3;3799,3800,851;, + 3;852,856,946;, + 3;946,3801,3799;, + 3;1271,947,3802;, + 3;3802,3803,1271;, + 3;3804,949,3805;, + 3;1273,3804,3806;, + 3;3807,948,3803;, + 3;948,3807,1272;, + 3;1274,950,3808;, + 3;1274,3805,949;, + 3;1275,1276,1274;, + 3;1278,952,1277;, + 3;1279,1280,954;, + 3;1282,951,1281;, + 3;1283,1284,1273;, + 3;1283,3809,3810;, + 3;1008,1270,956;, + 3;955,3811,3812;, + 3;981,957,1267;, + 3;970,1009,973;, + 3;3813,959,953;, + 3;1268,963,988;, + 3;3814,1263,3815;, + 3;959,3813,982;, + 3;973,958,970;, + 3;959,984,953;, + 3;3816,962,957;, + 3;1011,955,974;, + 3;984,3817,953;, + 3;984,965,3817;, + 3;991,961,964;, + 3;1263,963,1012;, + 3;963,3814,3818;, + 3;989,990,964;, + 3;3819,3820,966;, + 3;991,967,992;, + 3;992,965,991;, + 3;3818,966,963;, + 3;966,3818,968;, + 3;961,986,964;, + 3;964,986,3821;, + 3;976,974,1008;, + 3;1009,956,973;, + 3;969,1008,971;, + 3;975,974,972;, + 3;1263,1012,973;, + 3;1270,1263,956;, + 3;955,3815,1270;, + 3;969,976,1008;, + 3;1011,974,975;, + 3;1010,974,976;, + 3;3816,981,982;, + 3;980,1267,957;, + 3;959,982,981;, + 3;3816,982,3813;, + 3;961,991,984;, + 3;959,983,984;, + 3;983,961,984;, + 3;1012,963,985;, + 3;963,1268,985;, + 3;983,986,961;, + 3;983,987,986;, + 3;3820,988,963;, + 3;963,966,3820;, + 3;964,3821,989;, + 3;967,964,990;, + 3;965,984,991;, + 3;964,967,991;, + 3;965,992,3822;, + 3;992,995,3822;, + 3;995,992,994;, + 3;966,993,3819;, + 3;993,966,996;, + 3;967,994,992;, + 3;994,967,997;, + 3;968,996,966;, + 3;996,968,3823;, + 3;990,997,967;, + 3;997,990,3824;, + 3;994,1000,995;, + 3;1000,994,999;, + 3;996,998,993;, + 3;998,996,1001;, + 3;3823,1001,996;, + 3;1001,3823,3825;, + 3;3826,1002,3827;, + 3;3828,3824,3829;, + 3;997,999,994;, + 3;999,997,3828;, + 3;999,1005,1000;, + 3;1005,999,1004;, + 3;1001,1003,998;, + 3;1003,1001,1006;, + 3;3825,1006,1001;, + 3;1006,3825,3830;, + 3;3829,1007,3828;, + 3;1007,3829,3831;, + 3;3828,1004,999;, + 3;1004,3828,1007;, + 3;1007,1005,1004;, + 3;3830,1003,1006;, + 3;3831,1005,1007;, + 3;974,955,1270;, + 3;971,1008,956;, + 3;971,956,1009;, + 3;972,974,1010;, + 3;3832,955,1011;, + 3;958,973,1012;, + 3;1016,1015,970;, + 3;958,1016,970;, + 3;1017,1016,958;, + 3;1012,1017,958;, + 3;1018,1017,1012;, + 3;985,1018,1012;, + 3;1019,3833,3834;, + 3;960,1019,3834;, + 3;1020,1019,960;, + 3;979,1020,960;, + 3;3835,1020,979;, + 3;3836,3835,979;, + 3;1022,1021,1015;, + 3;1016,1022,1015;, + 3;1023,1022,1016;, + 3;1017,1023,1016;, + 3;1024,1023,1017;, + 3;1018,1024,1017;, + 3;1025,3837,3833;, + 3;1019,1025,3833;, + 3;1026,1025,1019;, + 3;1020,1026,1019;, + 3;3838,1026,1020;, + 3;3835,3838,1020;, + 3;1028,1027,1021;, + 3;1022,1028,1021;, + 3;1029,1028,1022;, + 3;1023,1029,1022;, + 3;1030,1029,1023;, + 3;1024,1030,1023;, + 3;1031,3839,3837;, + 3;1025,1031,3837;, + 3;1032,1031,1025;, + 3;1026,1032,1025;, + 3;3840,1032,1026;, + 3;3838,3840,1026;, + 3;1034,1033,1027;, + 3;1028,1034,1027;, + 3;1035,1034,1028;, + 3;1029,1035,1028;, + 3;1036,1035,1029;, + 3;1030,1036,1029;, + 3;1037,3841,3839;, + 3;1031,1037,3839;, + 3;1038,1037,1031;, + 3;1032,1038,1031;, + 3;3842,1038,1032;, + 3;3840,3842,1032;, + 3;1040,1039,1033;, + 3;1034,1040,1033;, + 3;1041,1040,1034;, + 3;1035,1041,1034;, + 3;1042,1041,1035;, + 3;1036,1042,1035;, + 3;1043,3843,3841;, + 3;1037,1043,3841;, + 3;1044,1043,1037;, + 3;1038,1044,1037;, + 3;3844,1044,1038;, + 3;3842,3844,1038;, + 3;1046,1045,1039;, + 3;1040,1046,1039;, + 3;1047,1046,1040;, + 3;1041,1047,1040;, + 3;1048,1047,1041;, + 3;1042,1048,1041;, + 3;1049,3845,3843;, + 3;1043,1049,3843;, + 3;1050,1049,1043;, + 3;1044,1050,1043;, + 3;3846,1050,1044;, + 3;3844,3846,1044;, + 3;1052,1051,1045;, + 3;1046,1052,1045;, + 3;1053,1052,1046;, + 3;1047,1053,1046;, + 3;1054,1053,1047;, + 3;1048,1054,1047;, + 3;1055,3847,3845;, + 3;1049,1055,3845;, + 3;1056,1055,1049;, + 3;1050,1056,1049;, + 3;3848,1056,1050;, + 3;3846,3848,1050;, + 3;1058,1057,1051;, + 3;1052,1058,1051;, + 3;1059,1058,1052;, + 3;1053,1059,1052;, + 3;1060,1059,1053;, + 3;1054,1060,1053;, + 3;1061,3849,3847;, + 3;1055,1061,3847;, + 3;1062,1061,1055;, + 3;1056,1062,1055;, + 3;3850,1062,1056;, + 3;3848,3850,1056;, + 3;1064,1063,1057;, + 3;1058,1064,1057;, + 3;1065,1064,1058;, + 3;1059,1065,1058;, + 3;1066,1065,1059;, + 3;1060,1066,1059;, + 3;1067,3851,3849;, + 3;1061,1067,3849;, + 3;1068,1067,1061;, + 3;1062,1068,1061;, + 3;3852,1068,1062;, + 3;3850,3852,1062;, + 3;1070,1069,1063;, + 3;1064,1070,1063;, + 3;1071,1070,1064;, + 3;1065,1071,1064;, + 3;1072,1071,1065;, + 3;1066,1072,1065;, + 3;1073,3853,3851;, + 3;1067,1073,3851;, + 3;1074,1073,1067;, + 3;1068,1074,1067;, + 3;3854,1074,1068;, + 3;3852,3854,1068;, + 3;1070,1075,1069;, + 3;1071,1076,1070;, + 3;1075,1070,1076;, + 3;1072,1076,1071;, + 3;1073,3855,3853;, + 3;1074,3856,1073;, + 3;3855,1073,3856;, + 3;3854,3856,1074;, + 3;1078,1077,969;, + 3;971,1078,969;, + 3;1079,1078,971;, + 3;1009,1079,971;, + 3;1080,1079,1009;, + 3;970,1080,1009;, + 3;1081,3857,3836;, + 3;978,1081,3836;, + 3;1082,1081,978;, + 3;1013,1082,978;, + 3;3858,1082,1013;, + 3;3859,3858,1013;, + 3;1084,1083,1077;, + 3;1078,1084,1077;, + 3;1085,1084,1078;, + 3;1079,1085,1078;, + 3;1086,1085,1079;, + 3;1080,1086,1079;, + 3;1087,3860,3857;, + 3;1081,1087,3857;, + 3;1088,1087,1081;, + 3;1082,1088,1081;, + 3;3861,1088,1082;, + 3;3858,3861,1082;, + 3;1090,1089,1083;, + 3;1084,1090,1083;, + 3;1091,1090,1084;, + 3;1085,1091,1084;, + 3;1092,1091,1085;, + 3;1086,1092,1085;, + 3;1093,3862,3860;, + 3;1087,1093,3860;, + 3;1094,1093,1087;, + 3;1088,1094,1087;, + 3;3863,1094,1088;, + 3;3861,3863,1088;, + 3;1096,1095,1089;, + 3;1090,1096,1089;, + 3;1097,1096,1090;, + 3;1091,1097,1090;, + 3;1098,1097,1091;, + 3;1092,1098,1091;, + 3;1099,3864,3862;, + 3;1093,1099,3862;, + 3;1100,1099,1093;, + 3;1094,1100,1093;, + 3;3865,1100,1094;, + 3;3863,3865,1094;, + 3;1102,1101,1095;, + 3;1096,1102,1095;, + 3;1103,1102,1096;, + 3;1097,1103,1096;, + 3;1104,1103,1097;, + 3;1098,1104,1097;, + 3;1105,3866,3864;, + 3;1099,1105,3864;, + 3;1106,1105,1099;, + 3;1100,1106,1099;, + 3;3867,1106,1100;, + 3;3865,3867,1100;, + 3;1108,1107,1101;, + 3;1102,1108,1101;, + 3;1109,1108,1102;, + 3;1103,1109,1102;, + 3;1110,1109,1103;, + 3;1104,1110,1103;, + 3;1111,3868,3866;, + 3;1105,1111,3866;, + 3;1112,1111,1105;, + 3;1106,1112,1105;, + 3;3869,1112,1106;, + 3;3867,3869,1106;, + 3;1114,1113,1107;, + 3;1108,1114,1107;, + 3;1115,1114,1108;, + 3;1109,1115,1108;, + 3;1116,1115,1109;, + 3;1110,1116,1109;, + 3;1117,3870,3868;, + 3;1111,1117,3868;, + 3;1118,1117,1111;, + 3;1112,1118,1111;, + 3;3871,1118,1112;, + 3;3869,3871,1112;, + 3;1120,1119,1113;, + 3;1114,1120,1113;, + 3;1121,1120,1114;, + 3;1115,1121,1114;, + 3;1122,1121,1115;, + 3;1116,1122,1115;, + 3;1123,3872,3870;, + 3;1117,1123,3870;, + 3;1124,1123,1117;, + 3;1118,1124,1117;, + 3;3873,1124,1118;, + 3;3871,3873,1118;, + 3;1126,1125,1119;, + 3;1120,1126,1119;, + 3;1127,1126,1120;, + 3;1121,1127,1120;, + 3;1128,1127,1121;, + 3;1122,1128,1121;, + 3;1129,3874,3872;, + 3;1123,1129,3872;, + 3;1130,1129,1123;, + 3;1124,1130,1123;, + 3;3875,1130,1124;, + 3;3873,3875,1124;, + 3;1132,1131,1125;, + 3;1126,1132,1125;, + 3;1133,1132,1126;, + 3;1127,1133,1126;, + 3;1134,1133,1127;, + 3;1128,1134,1127;, + 3;1135,3876,3874;, + 3;1129,1135,3874;, + 3;1136,1135,1129;, + 3;1130,1136,1129;, + 3;3877,1136,1130;, + 3;3875,3877,1130;, + 3;1132,1137,1131;, + 3;1133,1138,1132;, + 3;1137,1132,1138;, + 3;1134,1138,1133;, + 3;1135,3878,3876;, + 3;1136,3879,1135;, + 3;3878,1135,3879;, + 3;3877,3879,1136;, + 3;1140,1139,972;, + 3;1010,1140,972;, + 3;1141,1140,1010;, + 3;976,1141,1010;, + 3;1142,1141,976;, + 3;969,1142,976;, + 3;1143,3880,3859;, + 3;1014,1143,3859;, + 3;1144,1143,1014;, + 3;977,1144,1014;, + 3;3881,1144,977;, + 3;3882,3881,977;, + 3;1146,1145,1139;, + 3;1140,1146,1139;, + 3;1147,1146,1140;, + 3;1141,1147,1140;, + 3;1148,1147,1141;, + 3;1142,1148,1141;, + 3;1149,3883,3880;, + 3;1143,1149,3880;, + 3;1150,1149,1143;, + 3;1144,1150,1143;, + 3;3884,1150,1144;, + 3;3881,3884,1144;, + 3;1152,1151,1145;, + 3;1146,1152,1145;, + 3;1153,1152,1146;, + 3;1147,1153,1146;, + 3;1154,1153,1147;, + 3;1148,1154,1147;, + 3;1155,3885,3883;, + 3;1149,1155,3883;, + 3;1156,1155,1149;, + 3;1150,1156,1149;, + 3;3886,1156,1150;, + 3;3884,3886,1150;, + 3;1158,1157,1151;, + 3;1152,1158,1151;, + 3;1159,1158,1152;, + 3;1153,1159,1152;, + 3;1160,1159,1153;, + 3;1154,1160,1153;, + 3;1161,3887,3885;, + 3;1155,1161,3885;, + 3;1162,1161,1155;, + 3;1156,1162,1155;, + 3;3888,1162,1156;, + 3;3886,3888,1156;, + 3;1164,1163,1157;, + 3;1158,1164,1157;, + 3;1165,1164,1158;, + 3;1159,1165,1158;, + 3;1166,1165,1159;, + 3;1160,1166,1159;, + 3;1167,3889,3887;, + 3;1161,1167,3887;, + 3;1168,1167,1161;, + 3;1162,1168,1161;, + 3;3890,1168,1162;, + 3;3888,3890,1162;, + 3;1170,1169,1163;, + 3;1164,1170,1163;, + 3;1171,1170,1164;, + 3;1165,1171,1164;, + 3;1172,1171,1165;, + 3;1166,1172,1165;, + 3;1173,3891,3889;, + 3;1167,1173,3889;, + 3;1174,1173,1167;, + 3;1168,1174,1167;, + 3;3892,1174,1168;, + 3;3890,3892,1168;, + 3;1176,1175,1169;, + 3;1170,1176,1169;, + 3;1177,1176,1170;, + 3;1171,1177,1170;, + 3;1178,1177,1171;, + 3;1172,1178,1171;, + 3;1179,3893,3891;, + 3;1173,1179,3891;, + 3;1180,1179,1173;, + 3;1174,1180,1173;, + 3;3894,1180,1174;, + 3;3892,3894,1174;, + 3;1182,1181,1175;, + 3;1176,1182,1175;, + 3;1183,1182,1176;, + 3;1177,1183,1176;, + 3;1184,1183,1177;, + 3;1178,1184,1177;, + 3;1185,3895,3893;, + 3;1179,1185,3893;, + 3;1186,1185,1179;, + 3;1180,1186,1179;, + 3;3896,1186,1180;, + 3;3894,3896,1180;, + 3;1188,1187,1181;, + 3;1182,1188,1181;, + 3;1189,1188,1182;, + 3;1183,1189,1182;, + 3;1190,1189,1183;, + 3;1184,1190,1183;, + 3;1191,3897,3895;, + 3;1185,1191,3895;, + 3;1192,1191,1185;, + 3;1186,1192,1185;, + 3;3898,1192,1186;, + 3;3896,3898,1186;, + 3;1194,1193,1187;, + 3;1188,1194,1187;, + 3;1195,1194,1188;, + 3;1189,1195,1188;, + 3;1196,1195,1189;, + 3;1190,1196,1189;, + 3;1197,3899,3897;, + 3;1191,1197,3897;, + 3;1198,1197,1191;, + 3;1192,1198,1191;, + 3;3900,1198,1192;, + 3;3898,3900,1192;, + 3;1194,1199,1193;, + 3;1195,1200,1194;, + 3;1199,1194,1200;, + 3;1196,1200,1195;, + 3;1197,3901,3899;, + 3;1198,3902,1197;, + 3;3901,1197,3902;, + 3;3900,3902,1198;, + 3;1202,1201,3832;, + 3;1011,1202,3832;, + 3;1203,1202,1011;, + 3;975,1203,1011;, + 3;1204,1203,975;, + 3;972,1204,975;, + 3;1205,3903,3882;, + 3;980,1205,3882;, + 3;1206,1205,980;, + 3;957,1206,980;, + 3;3904,1206,957;, + 3;962,3904,957;, + 3;1208,1207,1201;, + 3;1202,1208,1201;, + 3;1209,1208,1202;, + 3;1203,1209,1202;, + 3;1210,1209,1203;, + 3;1204,1210,1203;, + 3;1211,3905,3903;, + 3;1205,1211,3903;, + 3;1212,1211,1205;, + 3;1206,1212,1205;, + 3;3906,1212,1206;, + 3;3904,3906,1206;, + 3;1214,1213,1207;, + 3;1208,1214,1207;, + 3;1215,1214,1208;, + 3;1209,1215,1208;, + 3;1216,1215,1209;, + 3;1210,1216,1209;, + 3;1217,3907,3905;, + 3;1211,1217,3905;, + 3;1218,1217,1211;, + 3;1212,1218,1211;, + 3;3908,1218,1212;, + 3;3906,3908,1212;, + 3;1220,1219,1213;, + 3;1214,1220,1213;, + 3;1221,1220,1214;, + 3;1215,1221,1214;, + 3;1222,1221,1215;, + 3;1216,1222,1215;, + 3;1223,3909,3907;, + 3;1217,1223,3907;, + 3;1224,1223,1217;, + 3;1218,1224,1217;, + 3;3910,1224,1218;, + 3;3908,3910,1218;, + 3;1226,1225,1219;, + 3;1220,1226,1219;, + 3;1227,1226,1220;, + 3;1221,1227,1220;, + 3;1228,1227,1221;, + 3;1222,1228,1221;, + 3;1229,3911,3909;, + 3;1223,1229,3909;, + 3;1230,1229,1223;, + 3;1224,1230,1223;, + 3;3912,1230,1224;, + 3;3910,3912,1224;, + 3;1232,1231,1225;, + 3;1226,1232,1225;, + 3;1233,1232,1226;, + 3;1227,1233,1226;, + 3;1234,1233,1227;, + 3;1228,1234,1227;, + 3;1235,3913,3911;, + 3;1229,1235,3911;, + 3;1236,1235,1229;, + 3;1230,1236,1229;, + 3;3914,1236,1230;, + 3;3912,3914,1230;, + 3;1238,1237,1231;, + 3;1232,1238,1231;, + 3;1239,1238,1232;, + 3;1233,1239,1232;, + 3;1240,1239,1233;, + 3;1234,1240,1233;, + 3;1241,3915,3913;, + 3;1235,1241,3913;, + 3;1242,1241,1235;, + 3;1236,1242,1235;, + 3;3916,1242,1236;, + 3;3914,3916,1236;, + 3;1244,1243,1237;, + 3;1238,1244,1237;, + 3;1245,1244,1238;, + 3;1239,1245,1238;, + 3;1246,1245,1239;, + 3;1240,1246,1239;, + 3;1247,3917,3915;, + 3;1241,1247,3915;, + 3;1248,1247,1241;, + 3;1242,1248,1241;, + 3;3918,1248,1242;, + 3;3916,3918,1242;, + 3;1250,1249,3918;, + 3;1244,3919,1243;, + 3;1251,3919,1244;, + 3;1245,1251,1244;, + 3;1252,1251,1245;, + 3;1246,1252,1245;, + 3;1253,3920,3917;, + 3;1247,1253,3917;, + 3;1254,1253,1247;, + 3;1248,1254,1247;, + 3;1249,1254,1248;, + 3;3918,1249,1248;, + 3;1256,1255,3921;, + 3;3919,1256,3921;, + 3;1257,1256,3919;, + 3;1251,1257,3919;, + 3;1258,1257,1251;, + 3;1252,1258,1251;, + 3;1259,3922,3920;, + 3;1253,1259,3920;, + 3;1260,1259,1253;, + 3;1254,1260,1253;, + 3;3923,1260,1254;, + 3;1249,3923,1254;, + 3;1256,1261,1255;, + 3;1257,1262,1256;, + 3;1261,1256,1262;, + 3;1258,1262,1257;, + 3;1259,3924,3922;, + 3;1260,3925,1259;, + 3;3924,1259,3925;, + 3;3923,3925,1260;, + 3;3814,963,1263;, + 3;1263,973,956;, + 3;981,983,959;, + 3;983,981,1269;, + 3;3859,1264,1014;, + 3;1264,3859,1013;, + 3;3836,1265,978;, + 3;3836,979,1265;, + 3;3882,1266,980;, + 3;1266,3882,977;, + 3;1013,1265,1264;, + 3;1265,1013,978;, + 3;1014,1266,977;, + 3;1266,1014,1264;, + 3;1265,979,960;, + 3;957,981,3816;, + 3;3926,960,3834;, + 3;980,1266,1267;, + 3;1266,1269,1267;, + 3;983,1269,987;, + 3;1267,1269,981;, + 3;1269,1264,987;, + 3;1264,1269,1266;, + 3;1264,1265,987;, + 3;1265,986,987;, + 3;986,1265,960;, + 3;986,960,3926;, + 3;986,3926,3821;, + 3;1270,3815,1263;, + 3;974,1270,1008;, + 3;1277,1282,1271;, + 3;1271,3803,948;, + 3;1279,1278,1272;, + 3;1272,3807,3927;, + 3;949,3804,1273;, + 3;1284,3928,1275;, + 3;3808,3805,1274;, + 3;1276,3929,3930;, + 3;3928,1276,1275;, + 3;3928,3929,1276;, + 3;1274,949,1275;, + 3;1278,1277,948;, + 3;1272,1278,948;, + 3;1272,1280,1279;, + 3;1272,3927,1280;, + 3;1282,1281,947;, + 3;1271,1282,947;, + 3;1271,948,1277;, + 3;3810,1284,1283;, + 3;3810,3928,1284;, + 3;3806,3809,1283;, + 3;1273,3806,1283;, + 3;952,1282,1277;, + 3;952,3931,1282;, + 3;954,1278,1279;, + 3;954,952,1278;, + 3;1284,1275,949;, + 3;1273,1284,949;, + 3;1276,3930,950;, + 3;1274,1276,950;, + 3;1286,943,1285;, + 3;1286,850,1291;, + 3;1287,3759,3757;, + 3;1292,1287,3757;, + 3;1288,3798,1286;, + 3;1286,3798,850;, + 3;855,3932,1287;, + 3;855,945,3932;, + 3;849,1289,943;, + 3;1293,852,1289;, + 3;854,1290,860;, + 3;889,853,1290;, + 3;1286,1291,943;, + 3;849,943,1291;, + 3;855,1287,1292;, + 3;855,1292,3758;, + 3;856,852,1293;, + 3;1293,854,856;, + 3;3933,1286,1285;, + 3;946,3799,851;, + 3;946,3756,3801;, + 3;851,3800,943;, + 3;943,3800,1285;, + 3;3934,1286,3933;, + 3;3934,1288,1286;, + 3;1287,3932,3935;, + 3;1287,3935,3759;, + 3;1294,1295,1736;, + 3;1388,1296,1297;, + 3;1294,1389,1735;, + 3;1734,1738,1299;, + 3;1299,1389,1734;, + 3;1304,1390,1333;, + 3;1300,1332,1306;, + 3;1391,3936,1301;, + 3;1737,3937,3938;, + 3;3938,3939,3940;, + 3;1297,1296,1391;, + 3;1302,1294,1334;, + 3;1303,1295,1302;, + 3;1295,1294,1302;, + 3;1298,1735,1305;, + 3;3941,3937,1306;, + 3;3937,1300,1306;, + 3;1332,1390,1304;, + 3;1320,1335,1336;, + 3;1338,1307,1337;, + 3;1339,1340,1314;, + 3;1342,1308,1341;, + 3;1343,1344,1321;, + 3;1345,1337,1307;, + 3;1347,1319,1346;, + 3;1343,1348,1322;, + 3;1313,1335,1349;, + 3;1339,1350,1309;, + 3;1350,1349,1309;, + 3;1341,1340,1317;, + 3;1312,1351,1347;, + 3;3942,1336,3943;, + 3;1344,1310,1351;, + 3;1348,3944,3945;, + 3;1346,1319,1345;, + 3;3943,1313,1325;, + 3;1325,1324,3943;, + 3;1312,1323,1327;, + 3;1327,1326,1312;, + 3;3944,1321,1329;, + 3;1329,1328,3944;, + 3;1311,1314,1331;, + 3;1331,1330,1311;, + 3;1313,1311,1325;, + 3;1330,1325,1311;, + 3;1314,1308,3946;, + 3;3946,1331,1314;, + 3;1321,1312,1326;, + 3;1326,1329,1321;, + 3;1323,1307,3947;, + 3;3947,1327,1323;, + 3;1315,1316,3948;, + 3;3948,3949,1315;, + 3;1317,1309,3950;, + 3;3950,3951,1317;, + 3;1318,1317,3951;, + 3;3951,3952,1318;, + 3;1310,1322,3953;, + 3;3953,3954,1310;, + 3;1316,1319,3955;, + 3;3955,3948,1316;, + 3;1309,1320,3956;, + 3;3956,3950,1309;, + 3;1319,1310,3954;, + 3;3954,3955,1319;, + 3;1320,3957,3958;, + 3;3958,3956,1320;, + 3;1322,3959,3960;, + 3;3960,3953,1322;, + 3;1335,1313,1336;, + 3;1313,3943,1336;, + 3;1337,1316,1338;, + 3;1316,1315,1338;, + 3;1339,1309,1340;, + 3;1309,1317,1340;, + 3;1341,1317,1342;, + 3;1317,1318,1342;, + 3;1343,1322,1344;, + 3;1322,1310,1344;, + 3;1345,1319,1337;, + 3;1319,1316,1337;, + 3;1346,1323,1347;, + 3;1323,1312,1347;, + 3;1343,1321,1348;, + 3;1321,3944,1348;, + 3;1335,1320,1349;, + 3;1320,1309,1349;, + 3;1339,1314,1350;, + 3;1314,1311,1350;, + 3;1350,1311,1349;, + 3;1311,1313,1349;, + 3;1341,1308,1340;, + 3;1308,1314,1340;, + 3;1351,1310,1347;, + 3;1310,1319,1347;, + 3;3942,3957,1336;, + 3;3957,1320,1336;, + 3;1351,1312,1344;, + 3;1312,1321,1344;, + 3;3945,3959,1348;, + 3;3959,1322,1348;, + 3;1345,1307,1346;, + 3;1307,1323,1346;, + 3;1334,1294,1735;, + 3;3961,1295,1303;, + 3;1300,1390,1332;, + 3;1366,1353,1384;, + 3;1387,3962,1367;, + 3;1368,1369,1355;, + 3;1352,1370,1371;, + 3;1371,1356,1372;, + 3;1374,1360,1373;, + 3;3963,1358,1364;, + 3;1376,1358,1375;, + 3;1386,1353,1365;, + 3;1376,3964,1377;, + 3;1374,1353,1378;, + 3;1361,3965,1363;, + 3;1362,1358,3966;, + 3;1380,1359,1379;, + 3;1361,1381,1380;, + 3;1382,1383,1360;, + 3;3967,3968,3969;, + 3;3970,1364,1354;, + 3;1357,3967,3971;, + 3;1361,1362,3966;, + 3;1379,1359,1375;, + 3;3968,3967,1357;, + 3;1381,3972,3973;, + 3;3963,3966,1358;, + 3;1377,3964,3974;, + 3;1373,1360,1383;, + 3;1385,1384,1353;, + 3;1352,1385,1387;, + 3;1372,1356,1378;, + 3;1367,3962,3975;, + 3;1370,1368,1355;, + 3;1368,1367,1369;, + 3;1367,3975,1369;, + 3;1370,1355,1371;, + 3;1355,1356,1371;, + 3;1372,1366,1371;, + 3;1366,1352,1371;, + 3;1373,1365,1374;, + 3;1365,1353,1374;, + 3;1375,1359,1376;, + 3;1359,3964,1376;, + 3;1377,1364,1376;, + 3;1364,1358,1376;, + 3;1378,1356,1374;, + 3;1356,1360,1374;, + 3;1379,1362,1380;, + 3;1362,1361,1380;, + 3;1381,3973,1380;, + 3;3973,1359,1380;, + 3;1382,3968,1383;, + 3;3968,1357,1383;, + 3;1375,1358,1379;, + 3;1358,1362,1379;, + 3;1381,1361,3972;, + 3;1361,1363,3972;, + 3;3974,1354,1377;, + 3;1354,1364,1377;, + 3;1383,1357,1373;, + 3;1357,1365,1373;, + 3;1378,1353,1372;, + 3;1353,1366,1372;, + 3;1370,1352,1368;, + 3;1352,1367,1368;, + 3;1357,3971,1365;, + 3;1325,1324,1330;, + 3;3962,3976,3975;, + 3;1385,3977,3962;, + 3;1386,3971,1385;, + 3;1352,1366,1384;, + 3;1384,1385,1352;, + 3;1385,3971,3977;, + 3;3971,1386,1365;, + 3;1353,1386,1385;, + 3;1352,1387,1367;, + 3;1387,1385,3962;, + 3;3970,3963,1364;, + 3;3965,1361,3966;, + 3;1734,1388,1297;, + 3;1294,1734,1389;, + 3;1299,1735,1389;, + 3;3978,1295,3961;, + 3;3979,1296,3980;, + 3;1297,1391,1301;, + 3;1391,3979,3981;, + 3;1716,3982,1392;, + 3;3982,1716,3983;, + 3;3984,3985,1394;, + 3;1718,3986,3984;, + 3;3987,3983,1393;, + 3;1393,1717,3987;, + 3;1719,3988,1395;, + 3;1719,1394,3985;, + 3;1720,1719,1721;, + 3;1723,1722,1397;, + 3;1724,1399,1725;, + 3;1727,1726,1396;, + 3;1728,1718,1729;, + 3;1728,3989,3990;, + 3;1453,1401,1715;, + 3;1400,3991,3992;, + 3;1426,1712,1402;, + 3;1415,1418,1454;, + 3;3993,1398,1404;, + 3;1713,1433,1408;, + 3;3994,3991,1708;, + 3;1404,1427,3993;, + 3;1418,1415,1403;, + 3;1404,1398,1429;, + 3;3995,1402,1407;, + 3;1456,1419,1400;, + 3;1429,1398,3996;, + 3;1429,3996,1410;, + 3;1436,1409,1406;, + 3;1708,1457,1408;, + 3;1408,3997,3994;, + 3;1434,1409,1435;, + 3;3998,1411,3999;, + 3;1436,1437,1412;, + 3;1437,1436,1410;, + 3;3997,1408,1411;, + 3;1411,1413,3997;, + 3;1406,1409,1431;, + 3;1409,4000,1431;, + 3;1421,1453,1419;, + 3;1454,1418,1401;, + 3;1414,1416,1453;, + 3;1420,1417,1419;, + 3;1708,1418,1457;, + 3;1715,1401,1708;, + 3;1400,1715,3991;, + 3;1414,1453,1421;, + 3;1456,1420,1419;, + 3;1455,1421,1419;, + 3;3995,1427,1426;, + 3;1425,1402,1712;, + 3;1404,1426,1427;, + 3;3995,3993,1427;, + 3;1406,1429,1436;, + 3;1404,1429,1428;, + 3;1428,1429,1406;, + 3;1457,1430,1408;, + 3;1408,1430,1713;, + 3;1428,1406,1431;, + 3;1428,1431,1432;, + 3;3999,1408,1433;, + 3;1408,3999,1411;, + 3;1409,1434,4000;, + 3;1412,1435,1409;, + 3;1410,1436,1429;, + 3;1409,1436,1412;, + 3;1410,4001,1437;, + 3;1437,4001,1440;, + 3;1440,1439,1437;, + 3;1411,3998,1438;, + 3;1438,1441,1411;, + 3;1412,1437,1439;, + 3;1439,1442,1412;, + 3;1413,1411,1441;, + 3;1441,4002,1413;, + 3;1435,1412,1442;, + 3;1442,4003,1435;, + 3;1439,1440,1445;, + 3;1445,1444,1439;, + 3;1441,1438,1443;, + 3;1443,1446,1441;, + 3;4002,1441,1446;, + 3;1446,4004,4002;, + 3;4003,1442,1447;, + 3;1447,4005,4003;, + 3;1442,1439,1444;, + 3;1444,1447,1442;, + 3;1444,1445,1450;, + 3;1450,1449,1444;, + 3;1446,1443,1448;, + 3;1448,1451,1446;, + 3;4004,1446,1451;, + 3;1451,4006,4004;, + 3;4005,1447,1452;, + 3;1452,4007,4005;, + 3;1447,1444,1449;, + 3;1449,1452,1447;, + 3;1452,1449,1450;, + 3;4006,1451,1448;, + 3;4007,1452,1450;, + 3;1419,1715,1400;, + 3;1416,1401,1453;, + 3;1416,1454,1401;, + 3;1417,1455,1419;, + 3;4008,1456,1400;, + 3;1403,1457,1418;, + 3;1461,4009,1460;, + 3;1403,1415,4010;, + 3;1462,1403,4010;, + 3;1457,1403,1462;, + 3;1463,1457,1462;, + 3;1430,1457,1463;, + 3;1464,4011,4012;, + 3;1405,4011,1464;, + 3;1465,1405,1464;, + 3;1424,1405,1465;, + 3;1460,1424,1465;, + 3;4009,1424,1460;, + 3;1467,4013,1466;, + 3;4010,4013,1467;, + 3;1468,4010,1467;, + 3;1462,4010,1468;, + 3;1469,1462,1468;, + 3;1463,1462,1469;, + 3;1470,4012,4014;, + 3;1464,4012,1470;, + 3;1471,1464,1470;, + 3;1465,1464,1471;, + 3;4015,1465,1471;, + 3;1460,1465,4015;, + 3;1473,1466,1472;, + 3;1467,1466,1473;, + 3;1474,1467,1473;, + 3;1468,1467,1474;, + 3;1475,1468,1474;, + 3;1469,1468,1475;, + 3;1476,4014,4016;, + 3;1470,4014,1476;, + 3;1477,1470,1476;, + 3;1471,1470,1477;, + 3;4017,1471,1477;, + 3;4015,1471,4017;, + 3;1479,1472,1478;, + 3;1473,1472,1479;, + 3;1480,1473,1479;, + 3;1474,1473,1480;, + 3;1481,1474,1480;, + 3;1475,1474,1481;, + 3;1482,4016,4018;, + 3;1476,4016,1482;, + 3;1483,1476,1482;, + 3;1477,1476,1483;, + 3;4019,1477,1483;, + 3;4017,1477,4019;, + 3;1485,1478,1484;, + 3;1479,1478,1485;, + 3;1486,1479,1485;, + 3;1480,1479,1486;, + 3;1487,1480,1486;, + 3;1481,1480,1487;, + 3;1488,4018,4020;, + 3;1482,4018,1488;, + 3;1489,1482,1488;, + 3;1483,1482,1489;, + 3;4021,1483,1489;, + 3;4019,1483,4021;, + 3;1491,1484,1490;, + 3;1485,1484,1491;, + 3;1492,1485,1491;, + 3;1486,1485,1492;, + 3;1493,1486,1492;, + 3;1487,1486,1493;, + 3;1494,4020,4022;, + 3;1488,4020,1494;, + 3;1495,1488,1494;, + 3;1489,1488,1495;, + 3;4023,1489,1495;, + 3;4021,1489,4023;, + 3;1497,1490,1496;, + 3;1491,1490,1497;, + 3;1498,1491,1497;, + 3;1492,1491,1498;, + 3;1499,1492,1498;, + 3;1493,1492,1499;, + 3;1500,4022,4024;, + 3;1494,4022,1500;, + 3;1501,1494,1500;, + 3;1495,1494,1501;, + 3;4025,1495,1501;, + 3;4023,1495,4025;, + 3;1503,1496,1502;, + 3;1497,1496,1503;, + 3;1504,1497,1503;, + 3;1498,1497,1504;, + 3;1505,1498,1504;, + 3;1499,1498,1505;, + 3;1506,4024,4026;, + 3;1500,4024,1506;, + 3;1507,1500,1506;, + 3;1501,1500,1507;, + 3;4027,1501,1507;, + 3;4025,1501,4027;, + 3;1509,1502,1508;, + 3;1503,1502,1509;, + 3;1510,1503,1509;, + 3;1504,1503,1510;, + 3;1511,1504,1510;, + 3;1505,1504,1511;, + 3;1512,4026,4028;, + 3;1506,4026,1512;, + 3;1513,1506,1512;, + 3;1507,1506,1513;, + 3;4029,1507,1513;, + 3;4027,1507,4029;, + 3;1515,1508,1514;, + 3;1509,1508,1515;, + 3;1516,1509,1515;, + 3;1510,1509,1516;, + 3;1517,1510,1516;, + 3;1511,1510,1517;, + 3;1518,4028,4030;, + 3;1512,4028,1518;, + 3;1519,1512,1518;, + 3;1513,1512,1519;, + 3;4031,1513,1519;, + 3;4029,1513,4031;, + 3;1515,1514,1520;, + 3;1516,1515,1521;, + 3;1520,1521,1515;, + 3;1517,1516,1521;, + 3;1518,4030,4032;, + 3;1519,1518,4033;, + 3;4032,4033,1518;, + 3;4031,1519,4033;, + 3;1523,1414,1522;, + 3;1416,1414,1523;, + 3;1524,1416,1523;, + 3;1454,1416,1524;, + 3;1525,1454,1524;, + 3;1415,1454,1525;, + 3;1526,4009,4034;, + 3;1423,4009,1526;, + 3;1527,1423,1526;, + 3;1458,1423,1527;, + 3;4035,1458,1527;, + 3;4036,1458,4035;, + 3;1529,1522,1528;, + 3;1523,1522,1529;, + 3;1530,1523,1529;, + 3;1524,1523,1530;, + 3;1531,1524,1530;, + 3;1525,1524,1531;, + 3;1532,4034,4037;, + 3;1526,4034,1532;, + 3;1533,1526,1532;, + 3;1527,1526,1533;, + 3;4038,1527,1533;, + 3;4035,1527,4038;, + 3;1535,1528,1534;, + 3;1529,1528,1535;, + 3;1536,1529,1535;, + 3;1530,1529,1536;, + 3;1537,1530,1536;, + 3;1531,1530,1537;, + 3;1538,4037,4039;, + 3;1532,4037,1538;, + 3;1539,1532,1538;, + 3;1533,1532,1539;, + 3;4040,1533,1539;, + 3;4038,1533,4040;, + 3;1541,1534,1540;, + 3;1535,1534,1541;, + 3;1542,1535,1541;, + 3;1536,1535,1542;, + 3;1543,1536,1542;, + 3;1537,1536,1543;, + 3;1544,4039,4041;, + 3;1538,4039,1544;, + 3;1545,1538,1544;, + 3;1539,1538,1545;, + 3;4042,1539,1545;, + 3;4040,1539,4042;, + 3;1547,1540,1546;, + 3;1541,1540,1547;, + 3;1548,1541,1547;, + 3;1542,1541,1548;, + 3;1549,1542,1548;, + 3;1543,1542,1549;, + 3;1550,4041,4043;, + 3;1544,4041,1550;, + 3;1551,1544,1550;, + 3;1545,1544,1551;, + 3;4044,1545,1551;, + 3;4042,1545,4044;, + 3;1553,1546,1552;, + 3;1547,1546,1553;, + 3;1554,1547,1553;, + 3;1548,1547,1554;, + 3;1555,1548,1554;, + 3;1549,1548,1555;, + 3;1556,4043,4045;, + 3;1550,4043,1556;, + 3;1557,1550,1556;, + 3;1551,1550,1557;, + 3;4046,1551,1557;, + 3;4044,1551,4046;, + 3;1559,1552,1558;, + 3;1553,1552,1559;, + 3;1560,1553,1559;, + 3;1554,1553,1560;, + 3;1561,1554,1560;, + 3;1555,1554,1561;, + 3;1562,4045,4047;, + 3;1556,4045,1562;, + 3;1563,1556,1562;, + 3;1557,1556,1563;, + 3;4048,1557,1563;, + 3;4046,1557,4048;, + 3;1565,1558,1564;, + 3;1559,1558,1565;, + 3;1566,1559,1565;, + 3;1560,1559,1566;, + 3;1567,1560,1566;, + 3;1561,1560,1567;, + 3;1568,4047,4049;, + 3;1562,4047,1568;, + 3;1569,1562,1568;, + 3;1563,1562,1569;, + 3;4050,1563,1569;, + 3;4048,1563,4050;, + 3;1571,1564,1570;, + 3;1565,1564,1571;, + 3;1572,1565,1571;, + 3;1566,1565,1572;, + 3;1573,1566,1572;, + 3;1567,1566,1573;, + 3;1574,4049,4051;, + 3;1568,4049,1574;, + 3;1575,1568,1574;, + 3;1569,1568,1575;, + 3;4052,1569,1575;, + 3;4050,1569,4052;, + 3;1577,1570,1576;, + 3;1571,1570,1577;, + 3;1578,1571,1577;, + 3;1572,1571,1578;, + 3;1579,1572,1578;, + 3;1573,1572,1579;, + 3;1580,4051,4053;, + 3;1574,4051,1580;, + 3;1581,1574,1580;, + 3;1575,1574,1581;, + 3;4054,1575,1581;, + 3;4052,1575,4054;, + 3;1577,1576,1582;, + 3;1578,1577,1583;, + 3;1582,1583,1577;, + 3;1579,1578,1583;, + 3;1580,4053,4055;, + 3;1581,1580,4056;, + 3;4055,4056,1580;, + 3;4054,1581,4056;, + 3;1585,1417,1584;, + 3;1455,1417,1585;, + 3;1586,1455,1585;, + 3;1421,1455,1586;, + 3;1587,1421,1586;, + 3;1414,1421,1587;, + 3;1588,4036,4057;, + 3;1459,4036,1588;, + 3;1589,1459,1588;, + 3;1422,1459,1589;, + 3;4058,1422,1589;, + 3;4059,1422,4058;, + 3;1591,1584,1590;, + 3;1585,1584,1591;, + 3;1592,1585,1591;, + 3;1586,1585,1592;, + 3;1593,1586,1592;, + 3;1587,1586,1593;, + 3;1594,4057,4060;, + 3;1588,4057,1594;, + 3;1595,1588,1594;, + 3;1589,1588,1595;, + 3;4061,1589,1595;, + 3;4058,1589,4061;, + 3;1597,1590,1596;, + 3;1591,1590,1597;, + 3;1598,1591,1597;, + 3;1592,1591,1598;, + 3;1599,1592,1598;, + 3;1593,1592,1599;, + 3;1600,4060,4062;, + 3;1594,4060,1600;, + 3;1601,1594,1600;, + 3;1595,1594,1601;, + 3;4063,1595,1601;, + 3;4061,1595,4063;, + 3;1603,1596,1602;, + 3;1597,1596,1603;, + 3;1604,1597,1603;, + 3;1598,1597,1604;, + 3;1605,1598,1604;, + 3;1599,1598,1605;, + 3;1606,4062,4064;, + 3;1600,4062,1606;, + 3;1607,1600,1606;, + 3;1601,1600,1607;, + 3;4065,1601,1607;, + 3;4063,1601,4065;, + 3;1609,1602,1608;, + 3;1603,1602,1609;, + 3;1610,1603,1609;, + 3;1604,1603,1610;, + 3;1611,1604,1610;, + 3;1605,1604,1611;, + 3;1612,4064,4066;, + 3;1606,4064,1612;, + 3;1613,1606,1612;, + 3;1607,1606,1613;, + 3;4067,1607,1613;, + 3;4065,1607,4067;, + 3;1615,1608,1614;, + 3;1609,1608,1615;, + 3;1616,1609,1615;, + 3;1610,1609,1616;, + 3;1617,1610,1616;, + 3;1611,1610,1617;, + 3;1618,4066,4068;, + 3;1612,4066,1618;, + 3;1619,1612,1618;, + 3;1613,1612,1619;, + 3;4069,1613,1619;, + 3;4067,1613,4069;, + 3;1621,1614,1620;, + 3;1615,1614,1621;, + 3;1622,1615,1621;, + 3;1616,1615,1622;, + 3;1623,1616,1622;, + 3;1617,1616,1623;, + 3;1624,4068,4070;, + 3;1618,4068,1624;, + 3;1625,1618,1624;, + 3;1619,1618,1625;, + 3;4071,1619,1625;, + 3;4069,1619,4071;, + 3;1627,1620,1626;, + 3;1621,1620,1627;, + 3;1628,1621,1627;, + 3;1622,1621,1628;, + 3;1629,1622,1628;, + 3;1623,1622,1629;, + 3;1630,4070,4072;, + 3;1624,4070,1630;, + 3;1631,1624,1630;, + 3;1625,1624,1631;, + 3;4073,1625,1631;, + 3;4071,1625,4073;, + 3;1633,1626,1632;, + 3;1627,1626,1633;, + 3;1634,1627,1633;, + 3;1628,1627,1634;, + 3;1635,1628,1634;, + 3;1629,1628,1635;, + 3;1636,4072,4074;, + 3;1630,4072,1636;, + 3;1637,1630,1636;, + 3;1631,1630,1637;, + 3;4075,1631,1637;, + 3;4073,1631,4075;, + 3;1639,1632,1638;, + 3;1633,1632,1639;, + 3;1640,1633,1639;, + 3;1634,1633,1640;, + 3;1641,1634,1640;, + 3;1635,1634,1641;, + 3;1642,4074,4076;, + 3;1636,4074,1642;, + 3;1643,1636,1642;, + 3;1637,1636,1643;, + 3;4077,1637,1643;, + 3;4075,1637,4077;, + 3;1639,1638,1644;, + 3;1640,1639,1645;, + 3;1644,1645,1639;, + 3;1641,1640,1645;, + 3;1642,4076,4078;, + 3;1643,1642,4079;, + 3;4078,4079,1642;, + 3;4077,1643,4079;, + 3;1647,4008,1646;, + 3;1456,4008,1647;, + 3;1648,1456,1647;, + 3;1420,1456,1648;, + 3;1649,1420,1648;, + 3;1417,1420,1649;, + 3;1650,4059,4080;, + 3;1425,4059,1650;, + 3;1651,1425,1650;, + 3;1402,1425,1651;, + 3;4081,1402,1651;, + 3;1407,1402,4081;, + 3;1653,1646,1652;, + 3;1647,1646,1653;, + 3;1654,1647,1653;, + 3;1648,1647,1654;, + 3;1655,1648,1654;, + 3;1649,1648,1655;, + 3;1656,4080,4082;, + 3;1650,4080,1656;, + 3;1657,1650,1656;, + 3;1651,1650,1657;, + 3;4083,1651,1657;, + 3;4081,1651,4083;, + 3;1659,1652,1658;, + 3;1653,1652,1659;, + 3;1660,1653,1659;, + 3;1654,1653,1660;, + 3;1661,1654,1660;, + 3;1655,1654,1661;, + 3;1662,4082,4084;, + 3;1656,4082,1662;, + 3;1663,1656,1662;, + 3;1657,1656,1663;, + 3;4085,1657,1663;, + 3;4083,1657,4085;, + 3;1665,1658,1664;, + 3;1659,1658,1665;, + 3;1666,1659,1665;, + 3;1660,1659,1666;, + 3;1667,1660,1666;, + 3;1661,1660,1667;, + 3;1668,4084,4086;, + 3;1662,4084,1668;, + 3;1669,1662,1668;, + 3;1663,1662,1669;, + 3;4087,1663,1669;, + 3;4085,1663,4087;, + 3;1671,1664,1670;, + 3;1665,1664,1671;, + 3;1672,1665,1671;, + 3;1666,1665,1672;, + 3;1673,1666,1672;, + 3;1667,1666,1673;, + 3;1674,4086,4088;, + 3;1668,4086,1674;, + 3;1675,1668,1674;, + 3;1669,1668,1675;, + 3;4089,1669,1675;, + 3;4087,1669,4089;, + 3;1677,1670,1676;, + 3;1671,1670,1677;, + 3;1678,1671,1677;, + 3;1672,1671,1678;, + 3;1679,1672,1678;, + 3;1673,1672,1679;, + 3;1680,4088,4090;, + 3;1674,4088,1680;, + 3;1681,1674,1680;, + 3;1675,1674,1681;, + 3;4091,1675,1681;, + 3;4089,1675,4091;, + 3;1683,1676,1682;, + 3;1677,1676,1683;, + 3;1684,1677,1683;, + 3;1678,1677,1684;, + 3;1685,1678,1684;, + 3;1679,1678,1685;, + 3;1686,4090,4092;, + 3;1680,4090,1686;, + 3;1687,1680,1686;, + 3;1681,1680,1687;, + 3;4093,1681,1687;, + 3;4091,1681,4093;, + 3;1689,1682,1688;, + 3;1683,1682,1689;, + 3;1690,1683,1689;, + 3;1684,1683,1690;, + 3;1691,1684,1690;, + 3;1685,1684,1691;, + 3;1692,4092,4094;, + 3;1686,4092,1692;, + 3;1693,1686,1692;, + 3;1687,1686,1693;, + 3;4095,1687,1693;, + 3;4093,1687,4095;, + 3;1695,1688,1694;, + 3;1689,1688,1695;, + 3;1696,1689,1695;, + 3;1690,1689,1696;, + 3;1697,1690,1696;, + 3;1691,1690,1697;, + 3;1698,4094,4096;, + 3;1692,4094,1698;, + 3;1699,1692,1698;, + 3;1693,1692,1699;, + 3;4097,1693,1699;, + 3;4095,1693,4097;, + 3;1701,1694,1700;, + 3;1695,1694,1701;, + 3;1702,1695,1701;, + 3;1696,1695,1702;, + 3;1703,1696,1702;, + 3;1697,1696,1703;, + 3;1704,4096,4098;, + 3;1698,4096,1704;, + 3;1705,1698,1704;, + 3;1699,1698,1705;, + 3;4099,1699,1705;, + 3;4097,1699,4099;, + 3;1701,1700,1706;, + 3;1702,1701,1707;, + 3;1706,1707,1701;, + 3;1703,1702,1707;, + 3;1704,4098,4100;, + 3;1705,1704,4101;, + 3;4100,4101,1704;, + 3;4099,1705,4101;, + 3;3994,1708,1408;, + 3;1708,1401,1418;, + 3;1426,1404,1428;, + 3;1428,1714,1426;, + 3;4036,1459,1709;, + 3;1709,1458,4036;, + 3;4009,1423,1710;, + 3;4009,1710,1424;, + 3;4059,1425,1711;, + 3;1711,1422,4059;, + 3;1458,1709,1710;, + 3;1710,1423,1458;, + 3;1459,1422,1711;, + 3;1711,1709,1459;, + 3;1710,1405,1424;, + 3;1402,3995,1426;, + 3;4102,4011,1405;, + 3;1425,1712,1711;, + 3;1711,1712,1714;, + 3;1428,1432,1714;, + 3;1712,1426,1714;, + 3;1714,1432,1709;, + 3;1709,1711,1714;, + 3;1709,1432,1710;, + 3;1710,1432,1431;, + 3;1431,1405,1710;, + 3;1431,4102,1405;, + 3;1431,4000,4102;, + 3;1715,1708,3991;, + 3;1419,1453,1715;, + 3;1722,1716,1727;, + 3;1716,1393,3983;, + 3;1724,1717,1723;, + 3;1717,4103,3987;, + 3;1394,1718,3984;, + 3;1729,1720,4104;, + 3;3988,1719,3985;, + 3;1721,4105,4106;, + 3;4104,1720,1721;, + 3;4104,1721,4106;, + 3;1719,1720,1394;, + 3;1723,1393,1722;, + 3;1717,1393,1723;, + 3;1717,1724,1725;, + 3;1717,1725,4103;, + 3;1727,1392,1726;, + 3;1716,1392,1727;, + 3;1716,1722,1393;, + 3;3989,1728,1729;, + 3;3989,1729,4104;, + 3;3986,1728,3990;, + 3;1718,1728,3986;, + 3;1397,1722,1727;, + 3;1397,1727,1396;, + 3;1399,1724,1723;, + 3;1399,1723,1397;, + 3;1729,1394,1720;, + 3;1718,1394,1729;, + 3;1721,1395,4105;, + 3;1719,1395,1721;, + 3;1731,1730,1388;, + 3;1731,1736,1295;, + 3;1732,3938,3940;, + 3;1737,3938,1732;, + 3;1733,1731,3978;, + 3;1731,1295,3978;, + 3;1300,1732,4107;, + 3;1300,4107,1390;, + 3;1294,1388,1734;, + 3;1738,1734,1297;, + 3;1299,1305,1735;, + 3;1334,1735,1298;, + 3;1731,1388,1736;, + 3;1294,1736,1388;, + 3;1300,1737,1732;, + 3;1300,3937,1737;, + 3;1301,1738,1297;, + 3;1738,1301,1299;, + 3;4108,1730,1731;, + 3;1391,1296,3979;, + 3;1391,3981,3936;, + 3;1296,1388,3980;, + 3;1388,1730,3980;, + 3;4109,4108,1731;, + 3;4109,1731,1733;, + 3;1732,4110,4107;, + 3;1732,3940,4110;, + 3;196,4111,197;, + 3;3759,4112,3760;, + 3;3938,4113,3939;, + 3;74,75,4114;, + 3;1744,6,1742;, + 3;10,97,1739;, + 3;1743,1745,142;, + 3;1740,144,215;, + 3;4115,4116,1741;, + 3;1741,1744,4115;, + 3;4117,4118,1742;, + 3;1742,1745,4117;, + 3;4118,4115,1744;, + 3;1744,1742,4118;, + 3;4119,4117,1745;, + 3;1745,1743,4119;, + 3;118,107,3471;, + 3;3460,3471,107;, + 3;233,3527,3528;, + 3;3528,3518,224;, + 3;106,5,87;, + 3;106,87,110;, + 3;1779,1790,1756;, + 3;1757,1819,1751;, + 3;1825,1826,4120;, + 3;1758,1829,1748;, + 3;2386,2124,2140;, + 3;2330,2146,2425;, + 3;1870,1872,1782;, + 3;4121,1846,4122;, + 3;1834,1835,1759;, + 3;2183,2240,2182;, + 3;2698,2714,2138;, + 3;2344,2518,2356;, + 3;4123,1852,4124;, + 3;1761,1865,4125;, + 3;1818,1799,1766;, + 3;2711,2132,2707;, + 3;2288,2450,2748;, + 3;2129,2213,2725;, + 3;2726,2753,2169;, + 3;2461,2471,2433;, + 3;1762,1763,1760;, + 3;1770,1772,1771;, + 3;2214,2022,2040;, + 3;2457,2193,2206;, + 3;2749,2758,2168;, + 3;2184,2176,2239;, + 3;2041,2190,2052;, + 3;2163,2231,2287;, + 3;2739,2284,2036;, + 3;2724,2204,2180;, + 3;2194,2044,2056;, + 3;2185,2196,2175;, + 3;2186,2043,2195;, + 3;2189,2042,2178;, + 3;2205,2188,2179;, + 3;2113,2062,2070;, + 3;2192,2458,2064;, + 3;2075,2198,2074;, + 3;2177,2042,2187;, + 3;2199,2053,2073;, + 3;2191,2065,2051;, + 3;2174,2197,2076;, + 3;2200,2700,2211;, + 3;2712,2202,2131;, + 3;2121,2396,2209;, + 3;2203,2212,2130;, + 3;1833,1800,1831;, + 3;2222,2021,2215;, + 3;2173,2077,2090;, + 3;2221,2037,2034;, + 3;2084,2020,2223;, + 3;2285,2220,2035;, + 3;2723,2181,2232;, + 3;2256,2282,2245;, + 3;2261,2278,2270;, + 3;2251,2281,2257;, + 3;2246,2277,2262;, + 3;2269,2279,2275;, + 3;2164,2249,2230;, + 3;2248,2165,2243;, + 3;2170,2259,2238;, + 3;2258,2171,2255;, + 3;2216,2267,2226;, + 3;2266,2217,2265;, + 3;2081,2254,2172;, + 3;2253,2082,2273;, + 3;2224,2272,2083;, + 3;2271,2225,2268;, + 3;2228,2264,2218;, + 3;2263,2229,2250;, + 3;2236,2242,2166;, + 3;2241,2237,2260;, + 3;2280,2252,2274;, + 3;2276,2247,2244;, + 3;2160,2738,2732;, + 3;2227,2219,2286;, + 3;2143,2159,2429;, + 3;2297,2449,2289;, + 3;2142,2430,2291;, + 3;2309,2469,2495;, + 3;2434,2127,2768;, + 3;2472,2437,2308;, + 3;2477,2302,2444;, + 3;2730,2028,2746;, + 3;4126,1823,1747;, + 3;1769,1778,3416;, + 3;4127,1838,1750;, + 3;1883,1763,1762;, + 3;1765,1856,4128;, + 3;1764,1804,1784;, + 3;1858,1859,4129;, + 3;1777,1760,1763;, + 3;1749,1752,1763;, + 3;1746,1806,1767;, + 3;1773,3416,1775;, + 3;1771,1769,1770;, + 3;4130,4131,4132;, + 3;4133,4134,1768;, + 3;4135,4136,4137;, + 3;4136,4135,4138;, + 3;4137,4139,4140;, + 3;4139,4137,4136;, + 3;4141,4142,4143;, + 3;1776,4140,4139;, + 3;1774,1768,4134;, + 3;4144,4143,4142;, + 3;4132,4138,4135;, + 3;4138,4132,4131;, + 3;4143,4144,1774;, + 3;3416,1773,4145;, + 3;1768,1774,4144;, + 3;4142,4141,1776;, + 3;3416,4145,1770;, + 3;4146,2141,4147;, + 3;4140,1776,4141;, + 3;3416,4148,1775;, + 3;4131,4130,4133;, + 3;4149,1807,4150;, + 3;4134,4133,4130;, + 3;2715,2709,2333;, + 3;2319,2343,2549;, + 3;4151,1849,4152;, + 3;2145,4153,2704;, + 3;2710,2703,2332;, + 3;2524,2523,2346;, + 3;1783,1809,4154;, + 3;2320,2147,2342;, + 3;2335,2352,2329;, + 3;2351,2336,2350;, + 3;2363,2341,2148;, + 3;2367,2328,2353;, + 3;2375,2349,2337;, + 3;2370,2385,2536;, + 3;2537,2360,2135;, + 3;4155,1867,4156;, + 3;2327,2368,2362;, + 3;2513,2512,2355;, + 3;2149,2361,2369;, + 3;2531,2529,2374;, + 3;2348,2376,2372;, + 3;1785,1811,4157;, + 3;2389,2383,2378;, + 3;2381,2134,2357;, + 3;2384,2371,2377;, + 3;2133,2382,2390;, + 3;4158,1877,4159;, + 3;2338,2388,2379;, + 3;2393,2098,2401;, + 3;2392,2397,2115;, + 3;2109,2060,2399;, + 3;2394,2412,2097;, + 3;2411,2395,2122;, + 3;1755,1813,1787;, + 3;2407,2423,2101;, + 3;2422,2408,2415;, + 3;2402,2414,2409;, + 3;2413,2403,2418;, + 3;2419,2417,2404;, + 3;2416,2420,2108;, + 3;2099,2107,2421;, + 3;4160,1840,4161;, + 3;1788,1861,4162;, + 3;1754,1843,4163;, + 3;2102,2096,2406;, + 3;2114,2398,2061;, + 3;2112,2400,2091;, + 3;4164,1873,4165;, + 3;2424,2141,2318;, + 3;1779,1879,1790;, + 3;1756,1790,1879;, + 3;1757,4166,1820;, + 3;1751,1819,4166;, + 3;1825,4167,1827;, + 3;4120,1826,4167;, + 3;1758,1828,1830;, + 3;1748,1829,1828;, + 3;1870,1871,1794;, + 3;1782,1872,1871;, + 3;4121,4168,1847;, + 3;4122,1846,4168;, + 3;1834,1836,1796;, + 3;1759,1835,1753;, + 3;4123,4169,1853;, + 3;4124,1852,4169;, + 3;1761,1864,1866;, + 3;4125,1865,1864;, + 3;4170,1789,1799;, + 3;1766,1799,1789;, + 3;1833,1832,1800;, + 3;1831,1800,1832;, + 3;1824,1822,1801;, + 3;1747,1823,1822;, + 3;4127,4171,1837;, + 3;1750,1837,4171;, + 3;1857,1855,1803;, + 3;4128,1856,1855;, + 3;4154,1781,4172;, + 3;4173,4174,4175;, + 3;1858,1860,1805;, + 3;4129,1859,1786;, + 3;1746,4176,1881;, + 3;1767,1806,1880;, + 3;4149,4177,1807;, + 3;4150,1882,4178;, + 3;4151,1850,1851;, + 3;4152,1849,4179;, + 3;1783,1781,1809;, + 3;4154,1809,1781;, + 3;4155,4180,1868;, + 3;4156,1867,4180;, + 3;1785,4181,1811;, + 3;4157,1811,4181;, + 3;1878,1876,1812;, + 3;4159,1877,1876;, + 3;2410,2426,2405;, + 3;4160,4182,1841;, + 3;4161,1840,4182;, + 3;1788,4183,1862;, + 3;4162,1861,4183;, + 3;1754,4184,1844;, + 3;4163,1843,4184;, + 3;4164,1874,1875;, + 3;4165,1873,4185;, + 3;4186,4187,4188;, + 3;4187,4186,4189;, + 3;4170,1799,1818;, + 3;4187,4189,4190;, + 3;2152,2456,2489;, + 3;2431,2300,2290;, + 3;2156,2126,2435;, + 3;2476,2301,2478;, + 3;2438,2764,2307;, + 3;2501,2485,2296;, + 3;2446,2311,2728;, + 3;2310,2447,2468;, + 3;2155,2436,2473;, + 3;2452,2293,2491;, + 3;2459,2118,2063;, + 3;2150,2465,2428;, + 3;2432,2466,2299;, + 3;2451,2492,2488;, + 3;2467,2448,2298;, + 3;2153,2500,2455;, + 3;2454,2496,2505;, + 3;2453,2506,2292;, + 3;2295,2482,2316;, + 3;2462,2494,2470;, + 3;2493,2463,2487;, + 3;2315,2483,2442;, + 3;2440,2503,2481;, + 3;2502,2441,2484;, + 3;2151,2486,2464;, + 3;2479,2498,2475;, + 3;2497,2480,2504;, + 3;2154,2474,2499;, + 3;2317,2490,2294;, + 3;2507,2366,2354;, + 3;2550,2340,2364;, + 3;2326,2544,2561;, + 3;2345,2519,2517;, + 3;2562,2325,2556;, + 3;2373,2530,2347;, + 3;2568,2324,2563;, + 3;2359,2538,2534;, + 3;2323,2569,2541;, + 3;2535,2380,2358;, + 3;2574,2528,2532;, + 3;2717,2543,2136;, + 3;2620,2599,2606;, + 3;2548,2339,2551;, + 3;2621,2629,2598;, + 3;2508,2555,2365;, + 3;2590,2634,2601;, + 3;2630,2625,2600;, + 3;2613,2589,2612;, + 3;2592,2582,2558;, + 3;2655,2616,2649;, + 3;2615,2656,2654;, + 3;2570,2579,2540;, + 3;2539,2580,2533;, + 3;2583,2567,2557;, + 3;2614,2650,2588;, + 3;2611,2581,2593;, + 3;2610,2594,2602;, + 3;2525,2608,2522;, + 3;2607,2526,2619;, + 3;2514,2596,2511;, + 3;2595,2515,2605;, + 3;2545,2632,2560;, + 3;2631,2546,2624;, + 3;2520,2604,2516;, + 3;2603,2521,2609;, + 3;2564,2645,2573;, + 3;2644,2565,2639;, + 3;2575,2618,2527;, + 3;2617,2576,2648;, + 3;2552,2623,2547;, + 3;2622,2553,2628;, + 3;2509,2627,2554;, + 3;2626,2510,2597;, + 3;2591,2559,2633;, + 3;2661,2647,2577;, + 3;2666,2572,2640;, + 3;2584,2638,2566;, + 3;2683,2676,2671;, + 3;2684,2682,2675;, + 3;2689,2681,2685;, + 3;2680,2690,2697;, + 3;2578,2571,2667;, + 3;2662,2660,2646;, + 3;2657,2687,2653;, + 3;2686,2658,2693;, + 3;2651,2669,2587;, + 3;2668,2652,2688;, + 3;2635,2678,2643;, + 3;2677,2636,2674;, + 3;2641,2695,2665;, + 3;2694,2642,2679;, + 3;2585,2673,2637;, + 3;2672,2586,2670;, + 3;2663,2692,2659;, + 3;2691,2664,2696;, + 3;1819,1791,1821;, + 3;1757,1820,1819;, + 3;2701,2120,2210;, + 3;2119,2702,2139;, + 3;1820,1791,1819;, + 3;1820,1821,1791;, + 3;1819,1821,4166;, + 3;1820,4166,1821;, + 3;1747,1822,4191;, + 3;4126,4191,1822;, + 3;1823,1801,1822;, + 3;1824,1801,1823;, + 3;4126,1822,1824;, + 3;4126,1824,1823;, + 3;4192,4167,1825;, + 3;4192,1825,4120;, + 3;1826,1827,4167;, + 3;1825,1792,1826;, + 3;1825,1827,1792;, + 3;1826,1792,1827;, + 3;1748,1828,4193;, + 3;1758,4193,1828;, + 3;1829,1793,1828;, + 3;1758,1830,1829;, + 3;1830,1793,1829;, + 3;1830,1828,1793;, + 3;4194,1831,4195;, + 3;4195,1831,4196;, + 3;1831,1832,4196;, + 3;4194,4196,1832;, + 3;4194,1832,1833;, + 3;4194,1833,1831;, + 3;4197,1753,1834;, + 3;4197,1834,1759;, + 3;1835,1796,1836;, + 3;1834,1796,1835;, + 3;1835,1836,1753;, + 3;1834,1753,1836;, + 3;1839,1837,1802;, + 3;1750,1838,1837;, + 3;1838,1802,1837;, + 3;1839,1802,1838;, + 3;4127,1837,1839;, + 3;4127,1839,1838;, + 3;1840,1814,1842;, + 3;4160,1841,1840;, + 3;1841,1814,1840;, + 3;1841,1842,1814;, + 3;1840,1842,4182;, + 3;1841,4182,1842;, + 3;1843,1845,4184;, + 3;1754,1844,1843;, + 3;1844,1816,1843;, + 3;1844,4184,1845;, + 3;1844,1845,1816;, + 3;1843,1816,1845;, + 3;1846,1848,4168;, + 3;4121,1847,1846;, + 3;1847,1795,1846;, + 3;1847,4168,1848;, + 3;1847,1848,1795;, + 3;1846,1795,1848;, + 3;1849,1808,1850;, + 3;4151,1851,1849;, + 3;1849,1850,4179;, + 3;4151,4179,1850;, + 3;1851,1808,1849;, + 3;1851,1850,1808;, + 3;1852,1854,4169;, + 3;4123,1853,1852;, + 3;1853,1797,1852;, + 3;1853,4169,1854;, + 3;1853,1854,1797;, + 3;1852,1797,1854;, + 3;4128,1855,4198;, + 3;1765,4198,1855;, + 3;1856,1803,1855;, + 3;1857,1803,1856;, + 3;1765,1855,1857;, + 3;1765,1857,1856;, + 3;4199,1786,1858;, + 3;4199,1858,4129;, + 3;1859,1805,1860;, + 3;1858,1805,1859;, + 3;1859,1860,1786;, + 3;1858,1786,1860;, + 3;1861,1815,1863;, + 3;1788,1862,1861;, + 3;1862,1815,1861;, + 3;1862,1863,1815;, + 3;1861,1863,4183;, + 3;1862,4183,1863;, + 3;4125,1864,4200;, + 3;1761,4200,1864;, + 3;1865,1798,1864;, + 3;1761,1866,1865;, + 3;1866,1798,1865;, + 3;1866,1864,1798;, + 3;1867,1869,4180;, + 3;4155,1868,1867;, + 3;1868,1810,1867;, + 3;1868,4180,1869;, + 3;1868,1869,1810;, + 3;1867,1810,1869;, + 3;4201,1780,1870;, + 3;4201,1870,1782;, + 3;1782,1871,1780;, + 3;1870,1780,1871;, + 3;1872,1794,1871;, + 3;1870,1794,1872;, + 3;1873,1817,1874;, + 3;4164,1875,1873;, + 3;1873,1874,4185;, + 3;4164,4185,1874;, + 3;1875,1817,1873;, + 3;1875,1874,1817;, + 3;4159,1876,4202;, + 3;4158,4202,1876;, + 3;1877,1812,1876;, + 3;1878,1812,1877;, + 3;4158,1876,1878;, + 3;4158,1878,1877;, + 3;1756,1879,4203;, + 3;1779,4203,1879;, + 3;4177,4178,1882;, + 3;1880,1881,4176;, + 3;1746,1881,1806;, + 3;1880,1806,1881;, + 3;4177,1882,1807;, + 3;4150,1807,1882;, + 3;2144,2705,2158;, + 3;2706,2125,2157;, + 3;2699,2201,2713;, + 3;2137,2708,2716;, + 3;2322,2542,2718;, + 3;2321,2719,2334;, + 3;2117,2460,2207;, + 3;2116,2208,2391;, + 3;2306,2759,2756;, + 3;2303,2314,2443;, + 3;2168,2235,2167;, + 3;2445,2729,2747;, + 3;2027,2731,2733;, + 3;2161,2741,2737;, + 3;2162,2283,2740;, + 3;1749,1763,1883;, + 3;2745,2023,2030;, + 3;2313,2304,2751;, + 3;2727,2312,2752;, + 3;2750,2305,2757;, + 3;2761,2722,2233;, + 3;2760,2234,2755;, + 3;2439,2765,2763;, + 3;2766,2721,2762;, + 3;2767,2128,2720;, + 3;4204,1884,4205;, + 3;4206,1885,4207;, + 3;2387,2427,2123;, + 3;1884,4206,4205;, + 3;4204,4206,1884;, + 3;1885,4204,4207;, + 3;4206,4204,1885;, + 3;1910,1887,1921;, + 3;1888,4208,1950;, + 3;1956,4209,1957;, + 3;1889,4210,1960;, + 3;3044,2796,2780;, + 3;2987,3083,2802;, + 3;2001,1913,2003;, + 3;4211,4212,1977;, + 3;1965,1890,1966;, + 3;2839,2838,2896;, + 3;3357,2790,3373;, + 3;3001,3013,3177;, + 3;4213,4214,1983;, + 3;1892,4215,1996;, + 3;1949,1897,1930;, + 3;3369,3366,2788;, + 3;2944,3395,3109;, + 3;2783,3384,2869;, + 3;3385,2825,3400;, + 3;3120,3092,3130;, + 3;1893,1891,1894;, + 3;1901,1902,1903;, + 3;2870,2039,2017;, + 3;3116,2866,2849;, + 3;3399,2816,3405;, + 3;2843,2888,2832;, + 3;2048,2049,2846;, + 3;2821,2943,2887;, + 3;2744,2031,2941;, + 3;3379,2834,2868;, + 3;2850,2055,2045;, + 3;2842,2826,2854;, + 3;2841,2855,2046;, + 3;2847,2836,2047;, + 3;2867,2835,2848;, + 3;2769,2069,2057;, + 3;2844,2067,3119;, + 3;2080,2071,2852;, + 3;2837,2840,2047;, + 3;2851,2072,2054;, + 3;2845,2050,2066;, + 3;2827,2079,2853;, + 3;2856,2861,3360;, + 3;3368,2781,2858;, + 3;2777,2863,3054;, + 3;2857,2782,2860;, + 3;1964,1962,1931;, + 3;2878,2877,2018;, + 3;2828,2089,2078;, + 3;2871,2033,2038;, + 3;2085,2882,2019;, + 3;2940,2032,2872;, + 3;3380,2895,2833;, + 3;2912,2901,2938;, + 3;2917,2926,2935;, + 3;2907,2916,2932;, + 3;2902,2921,2936;, + 3;2922,2931,2934;, + 3;2820,2883,2904;, + 3;2905,2898,2819;, + 3;2831,2889,2914;, + 3;2915,2908,2830;, + 3;2876,2879,2924;, + 3;2925,2918,2875;, + 3;2088,2829,2909;, + 3;2910,2928,2087;, + 3;2881,2086,2929;, + 3;2930,2923,2880;, + 3;2885,2874,2919;, + 3;2920,2903,2884;, + 3;2891,2818,2899;, + 3;2900,2913,2890;, + 3;2933,2927,2911;, + 3;2937,2897,2906;, + 3;2824,3386,2735;, + 3;2886,2939,2873;, + 3;2799,3090,2815;, + 3;2953,2947,3104;, + 3;2800,2945,3089;, + 3;2965,3154,3126;, + 3;3093,3415,2785;, + 3;3131,2964,3096;, + 3;3136,3103,2962;, + 3;3388,3393,2025;, + 3;4216,4217,1954;, + 3;1900,1901,3417;, + 3;4218,4219,1969;, + 3;2014,1893,1894;, + 3;1896,4220,1987;, + 3;1895,1915,1935;, + 3;1989,4221,1990;, + 3;1908,1894,1891;, + 3;1749,1894,1752;, + 3;1746,1898,1937;, + 3;3417,1906,1899;, + 3;1902,1901,1900;, + 3;4222,4223,4224;, + 3;1909,4225,4226;, + 3;4135,4137,4227;, + 3;4227,4228,4135;, + 3;4137,4229,4230;, + 3;4230,4227,4137;, + 3;4231,4232,1904;, + 3;1907,4230,4229;, + 3;1905,4226,4225;, + 3;4233,1904,4232;, + 3;4223,4135,4228;, + 3;4228,4224,4223;, + 3;4232,1905,4233;, + 3;1906,3417,4234;, + 3;4225,4233,1905;, + 3;1904,1907,4231;, + 3;4235,1900,3417;, + 3;2801,1908,1891;, + 3;4229,4231,1907;, + 3;4235,3417,1899;, + 3;4224,1909,4222;, + 3;4236,4237,1938;, + 3;4226,4222,1909;, + 3;3374,2989,3371;, + 3;2975,3208,3000;, + 3;4238,4239,1980;, + 3;2802,3364,2991;, + 3;3370,2990,3365;, + 3;3183,3006,3182;, + 3;1914,4240,1940;, + 3;2982,2996,2805;, + 3;2995,2986,3011;, + 3;3012,3002,2994;, + 3;3021,2804,2997;, + 3;3024,3010,2983;, + 3;3033,2993,3003;, + 3;3028,3195,3043;, + 3;3196,2793,3017;, + 3;4241,4242,1998;, + 3;2984,3019,3023;, + 3;3176,3008,3171;, + 3;2803,3022,3020;, + 3;3194,3029,3185;, + 3;3004,3031,3037;, + 3;1916,4243,1942;, + 3;3046,3035,3039;, + 3;3041,3016,2794;, + 3;3038,3036,3032;, + 3;2795,3045,3040;, + 3;4244,4245,2008;, + 3;2992,3034,3047;, + 3;3051,3059,2093;, + 3;3052,2773,3058;, + 3;2110,3056,2059;, + 3;3050,2094,3070;, + 3;3064,2776,3049;, + 3;1886,1918,1944;, + 3;3068,2104,3080;, + 3;3081,3071,3067;, + 3;3060,3066,3072;, + 3;3073,3074,3063;, + 3;3077,3062,3075;, + 3;3076,2105,3079;, + 3;2100,3078,2106;, + 3;4246,4247,1971;, + 3;1919,4248,1992;, + 3;4249,4250,1974;, + 3;2103,3069,2095;, + 3;2774,2058,3057;, + 3;2111,2092,3055;, + 3;4251,4252,2004;, + 3;3082,2974,4253;, + 3;1910,1921,2010;, + 3;1887,2010,1921;, + 3;1888,1951,4254;, + 3;4208,4254,1950;, + 3;1956,1958,4255;, + 3;4209,4255,1957;, + 3;1889,1961,1959;, + 3;4210,1959,1960;, + 3;2001,1925,2002;, + 3;1913,2002,2003;, + 3;4211,1978,4256;, + 3;4212,4256,1977;, + 3;1965,1927,1967;, + 3;1890,4257,1966;, + 3;4213,1984,4258;, + 3;4214,4258,1983;, + 3;1892,1997,1995;, + 3;4215,1995,1996;, + 3;4259,1930,1920;, + 3;1897,1920,1930;, + 3;1964,1931,1963;, + 3;1962,1963,1931;, + 3;1955,1932,1953;, + 3;4217,1953,1954;, + 3;4218,1968,4260;, + 3;4219,4260,1968;, + 3;1988,1934,1986;, + 3;4220,1986,1987;, + 3;4240,4261,1912;, + 3;3018,2985,3084;, + 3;1989,1936,1991;, + 3;4221,1917,1990;, + 3;1746,2012,4176;, + 3;1898,2011,1937;, + 3;4236,1938,4262;, + 3;4237,4178,2013;, + 3;4238,1982,1981;, + 3;4239,4263,1980;, + 3;1914,1940,1912;, + 3;4240,1912,1940;, + 3;4241,1999,4264;, + 3;4242,4264,1998;, + 3;1916,1942,4265;, + 3;4243,4265,1942;, + 3;2009,1943,2007;, + 3;4245,2007,2008;, + 3;3065,3061,3086;, + 3;4246,1972,4266;, + 3;4247,4266,1971;, + 3;1919,1993,4267;, + 3;4248,4267,1992;, + 3;4249,1975,4268;, + 3;4250,4268,1974;, + 3;4251,2006,2005;, + 3;4252,4269,2004;, + 3;4270,4271,4272;, + 3;4272,4273,4270;, + 3;4259,1949,1930;, + 3;4272,4274,4273;, + 3;2812,3148,3115;, + 3;3088,2946,2954;, + 3;2808,3098,2786;, + 3;3132,3140,2963;, + 3;3095,2957,3411;, + 3;3160,2952,3144;, + 3;3107,3390,2972;, + 3;2973,3127,3106;, + 3;2809,3135,3097;, + 3;3113,3152,2950;, + 3;3118,2068,2770;, + 3;2814,3091,3121;, + 3;3087,2955,3129;, + 3;3114,3145,3151;, + 3;3128,2956,3105;, + 3;2811,3110,3159;, + 3;3111,3162,3158;, + 3;3112,2951,3161;, + 3;2948,2967,3143;, + 3;3124,3125,3149;, + 3;3150,3146,3123;, + 3;2968,3100,3142;, + 3;3102,3137,3164;, + 3;3165,3141,3101;, + 3;2813,3122,3147;, + 3;3139,3133,3156;, + 3;3157,3163,3138;, + 3;2810,3155,3134;, + 3;2966,2949,3153;, + 3;3170,3009,3025;, + 3;3209,3027,2998;, + 3;2976,3220,3207;, + 3;3007,3172,3181;, + 3;3221,3219,2977;, + 3;3030,3005,3184;, + 3;3227,3226,2978;, + 3;3014,3191,3202;, + 3;2979,3199,3232;, + 3;3190,3015,3042;, + 3;3233,3193,3186;, + 3;3377,2792,3197;, + 3;3279,3265,3258;, + 3;3203,3214,2999;, + 3;3284,3254,3288;, + 3;3169,3026,3210;, + 3;3249,3263,3293;, + 3;3292,3264,3280;, + 3;3272,3271,3248;, + 3;3252,3217,3246;, + 3;3314,3308,3276;, + 3;3277,3313,3319;, + 3;3231,3200,3235;, + 3;3201,3192,3234;, + 3;3245,3218,3222;, + 3;3278,3240,3312;, + 3;3266,3251,3247;, + 3;3267,3262,3250;, + 3;3189,3178,3269;, + 3;3270,3273,3188;, + 3;3175,3166,3256;, + 3;3257,3259,3174;, + 3;3206,3215,3290;, + 3;3291,3281,3205;, + 3;3180,3173,3260;, + 3;3261,3268,3179;, + 3;3225,3228,3304;, + 3;3299,3298,3224;, + 3;3239,3187,3274;, + 3;3275,3305,3238;, + 3;3213,3204,3282;, + 3;3283,3285,3212;, + 3;3168,3211,3286;, + 3;3287,3255,3167;, + 3;3253,3289,3216;, + 3;3320,3237,3306;, + 3;3322,3303,3229;, + 3;3244,3223,3294;, + 3;3342,3330,3335;, + 3;3347,3331,3341;, + 3;3348,3346,3336;, + 3;3337,3356,3352;, + 3;3236,3321,3230;, + 3;3326,3307,3315;, + 3;3318,3309,3344;, + 3;3345,3349,3317;, + 3;3311,3241,3328;, + 3;3329,3343,3310;, + 3;3297,3300,3339;, + 3;3340,3332,3296;, + 3;3302,3323,3354;, + 3;3355,3338,3301;, + 3;3243,3295,3333;, + 3;3334,3327,3242;, + 3;3325,3316,3350;, + 3;3351,3353,3324;, + 3;1950,1952,1922;, + 3;1888,1950,1951;, + 3;3359,2862,2778;, + 3;2779,2789,3358;, + 3;1951,1950,1922;, + 3;1951,1922,1952;, + 3;1950,4254,1952;, + 3;1951,1952,4254;, + 3;4217,4275,1953;, + 3;4216,1953,4275;, + 3;1954,1953,1932;, + 3;1955,1954,1932;, + 3;4216,1955,1953;, + 3;4216,1954,1955;, + 3;4276,1956,4255;, + 3;4276,4209,1956;, + 3;1957,4255,1958;, + 3;1956,1957,1923;, + 3;1956,1923,1958;, + 3;1957,1958,1923;, + 3;4210,4277,1959;, + 3;1889,1959,4277;, + 3;1960,1959,1924;, + 3;1889,1960,1961;, + 3;1961,1960,1924;, + 3;1961,1924,1959;, + 3;4278,4279,1962;, + 3;4279,4280,1962;, + 3;1962,4280,1963;, + 3;4278,1963,4280;, + 3;4278,1964,1963;, + 3;4278,1962,1964;, + 3;4281,1965,4257;, + 3;4281,1890,1965;, + 3;1966,1967,1927;, + 3;1965,1966,1927;, + 3;1966,4257,1967;, + 3;1965,1967,4257;, + 3;1970,1933,1968;, + 3;4219,1968,1969;, + 3;1969,1968,1933;, + 3;1970,1969,1933;, + 3;4218,1970,1968;, + 3;4218,1969,1970;, + 3;1971,1973,1945;, + 3;4246,1971,1972;, + 3;1972,1971,1945;, + 3;1972,1945,1973;, + 3;1971,4266,1973;, + 3;1972,1973,4266;, + 3;1974,4268,1976;, + 3;4249,1974,1975;, + 3;1975,1974,1947;, + 3;1975,1976,4268;, + 3;1975,1947,1976;, + 3;1974,1976,1947;, + 3;1977,4256,1979;, + 3;4211,1977,1978;, + 3;1978,1977,1926;, + 3;1978,1979,4256;, + 3;1978,1926,1979;, + 3;1977,1979,1926;, + 3;1980,1981,1939;, + 3;4238,1980,1982;, + 3;1980,4263,1981;, + 3;4238,1981,4263;, + 3;1982,1980,1939;, + 3;1982,1939,1981;, + 3;1983,4258,1985;, + 3;4213,1983,1984;, + 3;1984,1983,1928;, + 3;1984,1985,4258;, + 3;1984,1928,1985;, + 3;1983,1985,1928;, + 3;4220,4282,1986;, + 3;1896,1986,4282;, + 3;1987,1986,1934;, + 3;1988,1987,1934;, + 3;1896,1988,1986;, + 3;1896,1987,1988;, + 3;4283,1989,1917;, + 3;4283,4221,1989;, + 3;1990,1991,1936;, + 3;1989,1990,1936;, + 3;1990,1917,1991;, + 3;1989,1991,1917;, + 3;1992,1994,1946;, + 3;1919,1992,1993;, + 3;1993,1992,1946;, + 3;1993,1946,1994;, + 3;1992,4267,1994;, + 3;1993,1994,4267;, + 3;4215,4284,1995;, + 3;1892,1995,4284;, + 3;1996,1995,1929;, + 3;1892,1996,1997;, + 3;1997,1996,1929;, + 3;1997,1929,1995;, + 3;1998,4264,2000;, + 3;1915,4285,4286;, + 3;1999,1998,1941;, + 3;1999,2000,4264;, + 3;1999,1941,2000;, + 3;1998,2000,1941;, + 3;4287,2001,1911;, + 3;4287,1913,2001;, + 3;1913,1911,2002;, + 3;2001,2002,1911;, + 3;2003,2002,1925;, + 3;2001,2003,1925;, + 3;2004,2005,1948;, + 3;4251,2004,2006;, + 3;2004,4269,2005;, + 3;4251,2005,4269;, + 3;2006,2004,1948;, + 3;2006,1948,2005;, + 3;4245,4288,2007;, + 3;4244,2007,4288;, + 3;2008,2007,1943;, + 3;2009,2008,1943;, + 3;4244,2009,2007;, + 3;4244,2008,2009;, + 3;1887,4289,2010;, + 3;1910,2010,4289;, + 3;4262,2013,4178;, + 3;2011,4176,2012;, + 3;1746,1937,2012;, + 3;2011,2012,1937;, + 3;4262,1938,2013;, + 3;4237,2013,1938;, + 3;2798,2806,3363;, + 3;3362,2807,2787;, + 3;3361,3367,2859;, + 3;2791,3378,3372;, + 3;2980,3376,3198;, + 3;2981,2988,3375;, + 3;2771,2865,3117;, + 3;2772,3053,2864;, + 3;2958,3402,3410;, + 3;2961,3099,2969;, + 3;2893,2817,2892;, + 3;3108,3392,3389;, + 3;2026,2734,3387;, + 3;2823,2736,2742;, + 3;2822,2743,2942;, + 3;1749,2014,1894;, + 3;3394,2029,2024;, + 3;2970,3397,2960;, + 3;3391,3396,2971;, + 3;3398,3401,2959;, + 3;3408,2894,3381;, + 3;3409,3403,2893;, + 3;3094,3406,3414;, + 3;3413,3407,3382;, + 3;3412,3383,2784;, + 3;4290,4291,2015;, + 3;4292,4293,2016;, + 3;3048,2775,3085;, + 3;2015,4291,4294;, + 3;4290,2015,4294;, + 3;2016,4293,4295;, + 3;4292,2016,4295;, + 3;2017,2040,2022;, + 3;2017,2039,2040;, + 3;2018,2870,2017;, + 3;2018,2877,2870;, + 3;2019,2878,2018;, + 3;2019,2882,2878;, + 3;2020,2085,2019;, + 3;2020,2084,2085;, + 3;2021,2223,2020;, + 3;2021,2222,2223;, + 3;2022,2215,2021;, + 3;2022,2214,2215;, + 3;2019,2017,2020;, + 3;2020,2017,2022;, + 3;2020,2022,2021;, + 3;2017,2019,2018;, + 3;2023,2746,2028;, + 3;2023,2745,2746;, + 3;2024,2030,2023;, + 3;2024,2029,2030;, + 3;2025,3394,2024;, + 3;2025,3393,3394;, + 3;2026,3388,2025;, + 3;2026,3387,3388;, + 3;2027,2734,2026;, + 3;2027,2733,2734;, + 3;2028,2731,2027;, + 3;2028,2730,2731;, + 3;2025,2028,2026;, + 3;2026,2028,2027;, + 3;2028,2025,2024;, + 3;2028,2024,2023;, + 3;2029,2014,1749;, + 3;2029,3394,2014;, + 3;1749,2745,2030;, + 3;1749,1883,2745;, + 3;1749,2030,2029;, + 3;2031,2739,2036;, + 3;2031,2744,2739;, + 3;2032,2941,2031;, + 3;2032,2940,2941;, + 3;2033,2872,2032;, + 3;2033,2871,2872;, + 3;2034,2038,2033;, + 3;2034,2037,2038;, + 3;2035,2221,2034;, + 3;2035,2220,2221;, + 3;2036,2285,2035;, + 3;2036,2284,2285;, + 3;2031,2036,2034;, + 3;2031,2034,2033;, + 3;2031,2033,2032;, + 3;2034,2036,2035;, + 3;2037,2214,2040;, + 3;2037,2221,2214;, + 3;2039,2871,2038;, + 3;2039,2870,2871;, + 3;2039,2038,2040;, + 3;2040,2038,2037;, + 3;2041,2049,2048;, + 3;2041,2052,2049;, + 3;2042,2190,2041;, + 3;2042,2189,2190;, + 3;2042,2177,2178;, + 3;2043,2187,2042;, + 3;2043,2186,2187;, + 3;2044,2195,2043;, + 3;2044,2194,2195;, + 3;2045,2056,2044;, + 3;2045,2055,2056;, + 3;2046,2850,2045;, + 3;2046,2855,2850;, + 3;2047,2841,2046;, + 3;2047,2840,2841;, + 3;2047,2836,2837;, + 3;2048,2847,2047;, + 3;2048,2846,2847;, + 3;2045,2044,2048;, + 3;2045,2048,2046;, + 3;2046,2048,2047;, + 3;2048,2044,2041;, + 3;2041,2044,2043;, + 3;2041,2043,2042;, + 3;2050,2846,2049;, + 3;2050,2845,2846;, + 3;2051,2066,2050;, + 3;2051,2065,2066;, + 3;2052,2191,2051;, + 3;2052,2190,2191;, + 3;2050,2049,2051;, + 3;2051,2049,2052;, + 3;2053,2194,2056;, + 3;2053,2199,2194;, + 3;2054,2073,2053;, + 3;2054,2072,2073;, + 3;2055,2851,2054;, + 3;2055,2850,2851;, + 3;2055,2054,2056;, + 3;2056,2054,2053;, + 3;2057,2070,2062;, + 3;2057,2069,2070;, + 3;2058,2769,2057;, + 3;2058,2774,2769;, + 3;2059,3057,2058;, + 3;2059,3056,3057;, + 3;2060,2110,2059;, + 3;2060,2109,2110;, + 3;2061,2399,2060;, + 3;2061,2398,2399;, + 3;2062,2114,2061;, + 3;2062,2113,2114;, + 3;2057,2062,2058;, + 3;2058,2062,2061;, + 3;2058,2061,2059;, + 3;2059,2061,2060;, + 3;2063,2113,2070;, + 3;2063,2118,2113;, + 3;2064,2459,2063;, + 3;2064,2458,2459;, + 3;2065,2192,2064;, + 3;2065,2191,2192;, + 3;2067,2845,2066;, + 3;2067,2844,2845;, + 3;2068,3119,2067;, + 3;2068,3118,3119;, + 3;2069,2770,2068;, + 3;2069,2769,2770;, + 3;2066,2065,2069;, + 3;2066,2069,2068;, + 3;2066,2068,2067;, + 3;2069,2065,2070;, + 3;2070,2065,2063;, + 3;2063,2065,2064;, + 3;2071,2075,2074;, + 3;2071,2080,2075;, + 3;2072,2852,2071;, + 3;2072,2851,2852;, + 3;2074,2199,2073;, + 3;2074,2198,2199;, + 3;2072,2071,2073;, + 3;2073,2071,2074;, + 3;2076,2198,2075;, + 3;2076,2197,2198;, + 3;2077,2174,2076;, + 3;2077,2173,2174;, + 3;2078,2090,2077;, + 3;2078,2089,2090;, + 3;2079,2828,2078;, + 3;2079,2827,2828;, + 3;2080,2853,2079;, + 3;2080,2852,2853;, + 3;2078,2077,2079;, + 3;2079,2077,2076;, + 3;2079,2076,2080;, + 3;2080,2076,2075;, + 3;2081,2173,2090;, + 3;2081,2172,2173;, + 3;2082,2254,2081;, + 3;2082,2253,2254;, + 3;2083,2273,2082;, + 3;2083,2272,2273;, + 3;2084,2224,2083;, + 3;2084,2223,2224;, + 3;2086,2882,2085;, + 3;2086,2881,2882;, + 3;2087,2929,2086;, + 3;2087,2928,2929;, + 3;2088,2910,2087;, + 3;2088,2909,2910;, + 3;2089,2829,2088;, + 3;2089,2828,2829;, + 3;2085,2084,2090;, + 3;2085,2090,2089;, + 3;2085,2089,2086;, + 3;2086,2089,2087;, + 3;2087,2089,2088;, + 3;2090,2084,2083;, + 3;2090,2083,2082;, + 3;2090,2082,2081;, + 3;2091,2401,2098;, + 3;2091,2400,2401;, + 3;2092,2112,2091;, + 3;2092,2111,2112;, + 3;2093,3055,2092;, + 3;2093,3059,3055;, + 3;4296,3051,2093;, + 3;4296,4297,3051;, + 3;4298,3070,2094;, + 3;4298,4299,3070;, + 3;2096,2103,2095;, + 3;2096,2102,2103;, + 3;2097,4300,4301;, + 3;2097,2412,4300;, + 3;2098,4302,4303;, + 3;2098,2393,4302;, + 3;4304,4305,4298;, + 3;4304,4298,2094;, + 3;4298,4305,4301;, + 3;4301,4305,2097;, + 3;2098,2093,2092;, + 3;2098,2092,2091;, + 3;2099,4306,4307;, + 3;2099,2421,4306;, + 3;2100,2107,2099;, + 3;2100,2106,2107;, + 3;4307,3078,2100;, + 3;4307,4308,3078;, + 3;4307,2100,2099;, + 3;2101,21,8;, + 3;2101,2423,21;, + 3;2102,2407,2101;, + 3;2102,2406,2407;, + 3;2104,3069,2103;, + 3;2104,3068,3069;, + 3;8,3080,2104;, + 3;8,151,3080;, + 3;8,2102,2101;, + 3;8,2103,2102;, + 3;8,2104,2103;, + 3;2105,4309,4310;, + 3;2105,3076,4309;, + 3;2106,3079,2105;, + 3;2106,3078,3079;, + 3;2108,2421,2107;, + 3;2108,2420,2421;, + 3;4310,2416,2108;, + 3;4310,4311,2416;, + 3;4310,2106,2105;, + 3;4310,2107,2106;, + 3;4310,2108,2107;, + 3;4312,2400,2112;, + 3;4312,4313,2400;, + 3;2111,4314,4315;, + 3;2111,3055,4314;, + 3;4315,4312,2111;, + 3;2111,4312,2112;, + 3;4316,2398,2114;, + 3;2115,2397,4317;, + 3;2116,2392,2115;, + 3;2116,2391,2392;, + 3;2117,4318,4319;, + 3;2117,2207,4318;, + 3;2118,2460,2117;, + 3;2118,2459,2460;, + 3;2114,2118,2117;, + 3;2114,2117,4316;, + 3;4316,2117,4319;, + 3;2118,2114,2113;, + 3;2119,4320,4321;, + 3;2119,2139,4320;, + 3;2120,2702,2119;, + 3;2120,2701,2702;, + 3;2121,2210,2120;, + 3;2121,2209,2210;, + 3;4322,2396,2121;, + 3;4322,4323,2396;, + 3;1755,2411,2122;, + 3;1755,1787,2411;, + 3;2123,1813,1755;, + 3;2123,2427,1813;, + 3;2124,2387,2123;, + 3;2124,2386,2387;, + 3;1755,2124,2123;, + 3;4324,2119,4321;, + 3;4324,2120,2119;, + 3;4324,2121,2120;, + 3;4324,4322,2121;, + 3;2125,4325,4326;, + 3;2125,2706,4325;, + 3;2126,2157,2125;, + 3;2126,2156,2157;, + 3;2127,2435,2126;, + 3;2127,2434,2435;, + 3;2128,2768,2127;, + 3;2128,2767,2768;, + 3;2129,2720,2128;, + 3;2129,2725,2720;, + 3;2130,2213,2129;, + 3;2130,2212,2213;, + 3;4327,2203,2130;, + 3;2131,2202,4328;, + 3;2132,2712,2131;, + 3;2132,2711,2712;, + 3;4326,2127,2126;, + 3;4326,2126,2125;, + 3;2127,4326,4327;, + 3;2127,4327,2128;, + 3;2128,4327,2130;, + 3;2128,2130,2129;, + 3;2133,4329,4320;, + 3;2133,2390,4329;, + 3;2134,2382,2133;, + 3;2134,2381,2382;, + 3;2135,2357,2134;, + 3;2135,2360,2357;, + 3;2136,2537,2135;, + 3;2136,2543,2537;, + 3;2137,2717,2136;, + 3;2137,2716,2717;, + 3;2138,2708,2137;, + 3;2138,2714,2708;, + 3;2139,2698,2138;, + 3;2139,2702,2698;, + 3;2134,2133,2135;, + 3;2135,2133,4320;, + 3;2135,4320,2136;, + 3;2136,4320,2139;, + 3;2136,2139,2137;, + 3;2137,2139,2138;, + 3;2141,2425,2146;, + 3;2141,2424,2425;, + 3;2141,4146,2318;, + 3;4330,1760,1777;, + 3;2142,1762,1760;, + 3;2142,2291,1762;, + 3;2143,2430,2142;, + 3;2143,2429,2430;, + 3;2144,2159,2143;, + 3;2144,2158,2159;, + 3;2145,2705,2144;, + 3;2145,2704,2705;, + 3;2146,2331,4331;, + 3;2146,2330,2331;, + 3;1760,2143,2142;, + 3;1760,2144,2143;, + 3;1760,2145,2144;, + 3;1760,4330,2145;, + 3;2145,4330,4153;, + 3;2147,4332,4333;, + 3;2147,2320,4332;, + 3;2148,2342,2147;, + 3;2148,2341,2342;, + 3;2149,2363,2148;, + 3;2149,2369,2363;, + 3;4333,2361,2149;, + 3;4333,4173,2361;, + 3;4333,2148,2147;, + 3;4333,2149,2148;, + 3;2150,2429,2159;, + 3;2150,2428,2429;, + 3;2151,2465,2150;, + 3;2151,2464,2465;, + 3;2152,4334,4335;, + 3;2152,2489,4334;, + 3;2153,2456,2152;, + 3;2153,2455,2456;, + 3;4336,2500,2153;, + 3;4336,4337,2500;, + 3;2155,2474,2154;, + 3;2155,2473,2474;, + 3;2156,2436,2155;, + 3;2156,2435,2436;, + 3;2158,2706,2157;, + 3;2158,2705,2706;, + 3;2158,2154,4338;, + 3;2158,4338,4339;, + 3;2158,4339,2151;, + 3;2158,2151,2150;, + 3;2158,2150,2159;, + 3;2154,2158,2155;, + 3;2155,2158,2157;, + 3;2155,2157,2156;, + 3;2160,2726,2169;, + 3;2160,2732,2726;, + 3;2161,2738,2160;, + 3;2161,2737,2738;, + 3;2162,2741,2161;, + 3;2162,2740,2741;, + 3;2163,2283,2162;, + 3;2163,2287,2283;, + 3;2164,2231,2163;, + 3;2164,2230,2231;, + 3;2165,2249,2164;, + 3;2165,2248,2249;, + 3;2166,2243,2165;, + 3;2166,2242,2243;, + 3;2167,2236,2166;, + 3;2167,2235,2236;, + 3;2168,2754,2235;, + 3;2168,2758,2754;, + 3;2169,2749,2168;, + 3;2169,2753,2749;, + 3;2167,2165,2164;, + 3;2167,2164,2163;, + 3;2167,2163,2168;, + 3;2168,2163,2162;, + 3;2168,2162,2169;, + 3;2169,2162,2161;, + 3;2169,2161,2160;, + 3;2165,2167,2166;, + 3;2170,2239,2176;, + 3;2170,2238,2239;, + 3;2171,2259,2170;, + 3;2171,2258,2259;, + 3;2172,2255,2171;, + 3;2172,2254,2255;, + 3;2175,2197,2174;, + 3;2175,2196,2197;, + 3;2176,2185,2175;, + 3;2176,2184,2185;, + 3;2171,2176,2172;, + 3;2172,2176,2174;, + 3;2172,2174,2173;, + 3;2174,2176,2175;, + 3;2176,2171,2170;, + 3;2177,2183,2182;, + 3;2177,2187,2183;, + 3;2179,2189,2178;, + 3;2179,2188,2189;, + 3;2180,2205,2179;, + 3;2180,2204,2205;, + 3;2181,2724,2180;, + 3;2181,2723,2724;, + 3;2182,2232,2181;, + 3;2182,2240,2232;, + 3;2179,2178,2180;, + 3;2180,2178,2177;, + 3;2180,2177,2182;, + 3;2180,2182,2181;, + 3;2184,2240,2183;, + 3;2184,2239,2240;, + 3;2186,2196,2185;, + 3;2186,2195,2196;, + 3;2185,2187,2186;, + 3;2187,2185,2183;, + 3;2183,2185,2184;, + 3;2188,2206,2193;, + 3;2188,2205,2206;, + 3;2193,2458,2192;, + 3;2193,2457,2458;, + 3;2189,2193,2192;, + 3;2189,2192,2190;, + 3;2190,2192,2191;, + 3;2193,2189,2188;, + 3;2199,2195,2194;, + 3;2195,2199,2198;, + 3;2195,2198,2197;, + 3;2195,2197,2196;, + 3;2200,2211,4328;, + 3;2203,4340,2212;, + 3;2201,2700,2200;, + 3;2201,2699,2700;, + 3;2202,2713,2201;, + 3;2202,2712,2713;, + 3;4328,2201,2200;, + 3;2201,4328,2202;, + 3;2204,2725,2213;, + 3;2204,2724,2725;, + 3;2207,2457,2206;, + 3;2207,2460,2457;, + 3;2209,2391,2208;, + 3;2209,2396,2391;, + 3;2211,2701,2210;, + 3;2211,2700,2701;, + 3;2205,2207,2206;, + 3;2207,2205,2204;, + 3;2207,2204,4318;, + 3;4318,2204,4340;, + 3;2208,2211,2209;, + 3;2209,2211,2210;, + 3;4340,2204,2212;, + 3;2212,2204,2213;, + 3;2216,2222,2215;, + 3;2216,2226,2222;, + 3;2217,2267,2216;, + 3;2217,2266,2267;, + 3;2218,2265,2217;, + 3;2218,2264,2265;, + 3;2219,2228,2218;, + 3;2219,2227,2228;, + 3;2220,2286,2219;, + 3;2220,2285,2286;, + 3;2218,2216,2219;, + 3;2219,2216,2220;, + 3;2220,2216,2215;, + 3;2220,2215,2221;, + 3;2221,2215,2214;, + 3;2216,2218,2217;, + 3;2225,2272,2224;, + 3;2225,2271,2272;, + 3;2226,2268,2225;, + 3;2226,2267,2268;, + 3;2222,2226,2225;, + 3;2222,2225,2224;, + 3;2222,2224,2223;, + 3;2227,2287,2231;, + 3;2227,2286,2287;, + 3;2229,2264,2228;, + 3;2229,2263,2264;, + 3;2230,2250,2229;, + 3;2230,2249,2250;, + 3;2227,2231,2228;, + 3;2228,2231,2229;, + 3;2229,2231,2230;, + 3;2233,2723,2232;, + 3;2233,2722,2723;, + 3;2234,2761,2233;, + 3;2234,2760,2761;, + 3;2235,2754,2234;, + 3;2234,2754,2755;, + 3;2237,2242,2236;, + 3;2237,2241,2242;, + 3;2238,2260,2237;, + 3;2238,2259,2260;, + 3;2237,2236,2238;, + 3;2238,2236,2235;, + 3;2238,2235,2239;, + 3;2239,2235,2234;, + 3;2239,2234,2232;, + 3;2239,2232,2240;, + 3;2232,2234,2233;, + 3;2241,2256,2245;, + 3;2241,2260,2256;, + 3;2244,2248,2243;, + 3;2244,2247,2248;, + 3;2245,2276,2244;, + 3;2245,2282,2276;, + 3;2242,2241,2243;, + 3;2243,2241,2244;, + 3;2244,2241,2245;, + 3;2246,2263,2250;, + 3;2246,2262,2263;, + 3;2247,2277,2246;, + 3;2247,2276,2277;, + 3;2246,2250,2247;, + 3;2247,2250,2249;, + 3;2247,2249,2248;, + 3;2251,2258,2255;, + 3;2251,2257,2258;, + 3;2252,2281,2251;, + 3;2252,2280,2281;, + 3;2253,2274,2252;, + 3;2253,2273,2274;, + 3;2255,2252,2251;, + 3;2252,2255,2254;, + 3;2252,2254,2253;, + 3;2257,2282,2256;, + 3;2257,2281,2282;, + 3;2257,2259,2258;, + 3;2259,2257,2256;, + 3;2259,2256,2260;, + 3;2261,2266,2265;, + 3;2261,2270,2266;, + 3;2262,2278,2261;, + 3;2262,2277,2278;, + 3;2265,2263,2262;, + 3;2265,2262,2261;, + 3;2263,2265,2264;, + 3;2269,2271,2268;, + 3;2269,2275,2271;, + 3;2270,2279,2269;, + 3;2270,2278,2279;, + 3;2270,2269,2268;, + 3;2270,2268,2266;, + 3;2266,2268,2267;, + 3;2275,2280,2274;, + 3;2275,2279,2280;, + 3;2275,2273,2271;, + 3;2271,2273,2272;, + 3;2273,2275,2274;, + 3;2279,2278,2280;, + 3;2280,2278,2282;, + 3;2280,2282,2281;, + 3;2282,2278,2276;, + 3;2276,2278,2277;, + 3;2284,2740,2283;, + 3;2284,2739,2740;, + 3;2286,2283,2287;, + 3;2283,2286,2285;, + 3;2283,2285,2284;, + 3;2288,1883,1762;, + 3;2288,2748,1883;, + 3;2289,2450,2288;, + 3;2289,2449,2450;, + 3;2290,2297,2289;, + 3;2290,2300,2297;, + 3;2291,2431,2290;, + 3;2291,2430,2431;, + 3;1762,2289,2288;, + 3;1762,2290,2289;, + 3;1762,2291,2290;, + 3;2292,2501,2296;, + 3;2292,2506,2501;, + 3;2293,2453,2292;, + 3;2293,2452,2453;, + 3;2294,2491,2293;, + 3;2294,2490,2491;, + 3;2295,2317,2294;, + 3;2295,2316,2317;, + 3;2296,2482,2295;, + 3;2296,2485,2482;, + 3;2293,2296,2294;, + 3;2294,2296,2295;, + 3;2296,2293,2292;, + 3;2298,2449,2297;, + 3;2298,2448,2449;, + 3;2299,2467,2298;, + 3;2299,2466,2467;, + 3;2300,2432,2299;, + 3;2300,2431,2432;, + 3;2297,2299,2298;, + 3;2299,2297,2300;, + 3;2301,2472,2308;, + 3;2301,2476,2472;, + 3;2302,2478,2301;, + 3;2302,2477,2478;, + 3;2303,2444,2302;, + 3;2303,2443,2444;, + 3;2304,2314,2303;, + 3;2304,2313,2314;, + 3;2305,2751,2304;, + 3;2305,2750,2751;, + 3;2306,2757,2305;, + 3;2306,2756,2757;, + 3;2307,2759,2306;, + 3;2307,2764,2759;, + 3;2308,2438,2307;, + 3;2308,2437,2438;, + 3;2306,2302,2307;, + 3;2307,2302,2301;, + 3;2307,2301,2308;, + 3;2302,2306,2305;, + 3;2302,2305,2304;, + 3;2302,2304,2303;, + 3;4341,2490,2317;, + 3;4341,4342,2490;, + 3;2310,2469,2309;, + 3;2310,2468,2469;, + 3;2311,2447,2310;, + 3;2311,2446,2447;, + 3;2312,2728,2311;, + 3;2312,2727,2728;, + 3;2313,2752,2312;, + 3;2313,2751,2752;, + 3;2315,2443,2314;, + 3;2315,2442,2443;, + 3;4343,2483,2315;, + 3;2316,2482,4344;, + 3;2312,2315,2314;, + 3;2312,2314,2313;, + 3;2315,2312,2311;, + 3;2315,2311,4343;, + 3;4343,2311,2310;, + 3;2316,4345,2317;, + 3;2317,4345,4341;, + 3;4146,2424,2318;, + 3;4146,4346,2424;, + 3;2319,2544,2326;, + 3;2319,2549,2544;, + 3;2320,2343,2319;, + 3;2320,2342,2343;, + 3;2321,4347,4332;, + 3;2321,2334,4347;, + 3;2322,2719,2321;, + 3;2322,2718,2719;, + 3;2323,2542,2322;, + 3;2323,2541,2542;, + 3;2324,2569,2323;, + 3;2324,2568,2569;, + 3;2325,2563,2324;, + 3;2325,2562,2563;, + 3;2326,2556,2325;, + 3;2326,2561,2556;, + 3;4332,2322,2321;, + 3;4332,2323,2322;, + 3;4332,2324,2323;, + 3;4332,2325,2324;, + 3;4332,2326,2325;, + 3;4332,2319,2326;, + 3;4332,2320,2319;, + 3;4175,2335,2329;, + 3;4175,4348,2335;, + 3;2327,4173,4175;, + 3;2327,2362,4173;, + 3;2328,2368,2327;, + 3;2328,2367,2368;, + 3;2329,2353,2328;, + 3;2329,2352,2353;, + 3;4175,2328,2327;, + 3;4175,2329,2328;, + 3;2330,4346,4347;, + 3;2330,2425,4346;, + 3;2332,4331,2331;, + 3;2332,2703,4331;, + 3;2333,2710,2332;, + 3;2333,2709,2710;, + 3;2334,2715,2333;, + 3;2334,2719,2715;, + 3;4347,2331,2330;, + 3;4347,2332,2331;, + 3;4347,2333,2332;, + 3;4347,2334,2333;, + 3;2336,2352,2335;, + 3;2336,2351,2352;, + 3;2337,2350,2336;, + 3;2337,2349,2350;, + 3;2338,2375,2337;, + 3;2338,2379,2375;, + 3;4348,2388,2338;, + 3;4348,4349,2388;, + 3;4348,2336,2335;, + 3;4348,2337,2336;, + 3;4348,2338,2337;, + 3;2339,2549,2343;, + 3;2339,2548,2549;, + 3;2340,2551,2339;, + 3;2340,2550,2551;, + 3;2341,2364,2340;, + 3;2341,2363,2364;, + 3;2341,2340,2339;, + 3;2341,2339,2342;, + 3;2342,2339,2343;, + 3;2344,2351,2350;, + 3;2344,2356,2351;, + 3;2345,2518,2344;, + 3;2345,2517,2518;, + 3;2346,2519,2345;, + 3;2346,2523,2519;, + 3;2347,2524,2346;, + 3;2347,2530,2524;, + 3;2348,2373,2347;, + 3;2348,2372,2373;, + 3;2349,2376,2348;, + 3;2349,2375,2376;, + 3;2349,2346,2345;, + 3;2349,2345,2350;, + 3;2350,2345,2344;, + 3;2346,2349,2348;, + 3;2346,2348,2347;, + 3;2354,2367,2353;, + 3;2354,2366,2367;, + 3;2355,2507,2354;, + 3;2355,2512,2507;, + 3;2356,2513,2355;, + 3;2356,2518,2513;, + 3;2353,2355,2354;, + 3;2355,2353,2356;, + 3;2356,2353,2352;, + 3;2356,2352,2351;, + 3;2358,2381,2357;, + 3;2358,2380,2381;, + 3;2359,2535,2358;, + 3;2359,2534,2535;, + 3;2360,2538,2359;, + 3;2360,2537,2538;, + 3;2357,2360,2358;, + 3;2358,2360,2359;, + 3;2362,2369,2361;, + 3;2362,2368,2369;, + 3;4173,2362,2361;, + 3;2365,2550,2364;, + 3;2365,2555,2550;, + 3;2366,2508,2365;, + 3;2366,2507,2508;, + 3;2365,2364,2366;, + 3;2366,2364,2369;, + 3;2366,2369,2368;, + 3;2366,2368,2367;, + 3;2369,2364,2363;, + 3;2370,2531,2374;, + 3;2370,2536,2531;, + 3;2371,2385,2370;, + 3;2371,2384,2385;, + 3;2372,2377,2371;, + 3;2372,2376,2377;, + 3;2374,2530,2373;, + 3;2374,2529,2530;, + 3;2374,2373,2372;, + 3;2374,2372,2371;, + 3;2374,2371,2370;, + 3;2378,2384,2377;, + 3;2378,2383,2384;, + 3;2379,2389,2378;, + 3;2379,2388,2389;, + 3;2379,2376,2375;, + 3;2376,2379,2377;, + 3;2377,2379,2378;, + 3;2380,2536,2385;, + 3;2380,2535,2536;, + 3;2383,2390,2382;, + 3;2383,2389,2390;, + 3;2382,2380,2385;, + 3;2382,2385,2383;, + 3;2383,2385,2384;, + 3;2380,2382,2381;, + 3;4350,2427,2387;, + 3;4350,1813,2427;, + 3;4349,2389,2388;, + 3;4349,2390,2389;, + 3;4349,4329,2390;, + 3;4350,2387,2386;, + 3;2393,2397,2392;, + 3;2393,2401,2397;, + 3;2395,2412,2394;, + 3;2395,2411,2412;, + 3;4302,2396,4323;, + 3;2396,4302,2393;, + 3;2396,2393,2391;, + 3;2391,2393,2392;, + 3;4317,2397,4313;, + 3;4313,2397,2400;, + 3;2400,2397,2401;, + 3;2402,2410,2405;, + 3;2402,2409,2410;, + 3;2403,2414,2402;, + 3;2403,2413,2414;, + 3;2404,2418,2403;, + 3;2404,2417,2418;, + 3;4351,2419,2404;, + 3;4351,4306,2419;, + 3;4352,4207,4204;, + 3;4352,4353,4207;, + 3;4351,2402,2405;, + 3;4351,2403,2402;, + 3;4351,2404,2403;, + 3;2408,2423,2407;, + 3;2408,2422,2423;, + 3;4354,2415,2408;, + 3;4354,4355,2415;, + 3;4356,4357,4358;, + 3;1787,1813,4359;, + 3;1787,2412,2411;, + 3;1787,4300,2412;, + 3;4356,2407,2406;, + 3;4356,2408,2407;, + 3;4356,4354,2408;, + 3;4356,4358,4354;, + 3;2413,4311,4360;, + 3;2413,2418,4311;, + 3;88,2422,2415;, + 3;88,21,2422;, + 3;4360,2414,2413;, + 3;88,2415,4355;, + 3;2417,2420,2416;, + 3;2417,2419,2420;, + 3;4311,2418,2416;, + 3;2416,2418,2417;, + 3;4306,2420,2419;, + 3;4306,2421,2420;, + 3;21,2423,2422;, + 3;4346,2425,2424;, + 3;2428,2461,2433;, + 3;2428,2465,2461;, + 3;2433,2466,2432;, + 3;2433,2471,2466;, + 3;2429,2428,2430;, + 3;2430,2428,2433;, + 3;2430,2433,2431;, + 3;2431,2433,2432;, + 3;2434,2765,2439;, + 3;2434,2768,2765;, + 3;2437,2473,2436;, + 3;2437,2472,2473;, + 3;2439,2764,2438;, + 3;2439,2763,2764;, + 3;2436,2435,2437;, + 3;2437,2435,2434;, + 3;2437,2434,2439;, + 3;2437,2439,2438;, + 3;2440,2477,2444;, + 3;2440,2481,2477;, + 3;2441,2503,2440;, + 3;2441,2502,2503;, + 3;2442,2484,2441;, + 3;2442,2483,2484;, + 3;2442,2441,2443;, + 3;2443,2441,2444;, + 3;2444,2441,2440;, + 3;2445,2748,2450;, + 3;2445,2747,2748;, + 3;2446,2729,2445;, + 3;2446,2728,2729;, + 3;2448,2468,2447;, + 3;2448,2467,2468;, + 3;2446,2445,2447;, + 3;2447,2445,2448;, + 3;2448,2445,2449;, + 3;2449,2445,2450;, + 3;2451,2489,2456;, + 3;2451,2488,2489;, + 3;2452,2492,2451;, + 3;2452,2491,2492;, + 3;2454,2506,2453;, + 3;2454,2505,2506;, + 3;2455,2496,2454;, + 3;2455,2500,2496;, + 3;2456,2454,2451;, + 3;2451,2454,2453;, + 3;2451,2453,2452;, + 3;2454,2456,2455;, + 3;2460,2458,2457;, + 3;2458,2460,2459;, + 3;2462,2471,2461;, + 3;2462,2470,2471;, + 3;2463,2494,2462;, + 3;2463,2493,2494;, + 3;2464,2487,2463;, + 3;2464,2486,2487;, + 3;2465,2463,2461;, + 3;2461,2463,2462;, + 3;2463,2465,2464;, + 3;2470,2495,2469;, + 3;2470,2494,2495;, + 3;2467,2469,2468;, + 3;2469,2467,2470;, + 3;2470,2467,2466;, + 3;2470,2466,2471;, + 3;2475,2499,2474;, + 3;2475,2498,2499;, + 3;2476,2479,2475;, + 3;2476,2478,2479;, + 3;2474,2473,2475;, + 3;2475,2473,2472;, + 3;2475,2472,2476;, + 3;2480,2498,2479;, + 3;2480,2497,2498;, + 3;2481,2504,2480;, + 3;2481,2503,2504;, + 3;2478,2480,2479;, + 3;2480,2478,2481;, + 3;2481,2478,2477;, + 3;2485,4361,4362;, + 3;2485,2501,4361;, + 3;2482,4362,4344;, + 3;4362,2482,2485;, + 3;2488,4363,4364;, + 3;2488,2492,4363;, + 3;4334,2489,2488;, + 3;4334,2488,4364;, + 3;4342,4365,2490;, + 3;2490,4365,2491;, + 3;2491,4365,4363;, + 3;2491,4363,2492;, + 3;4366,2505,2496;, + 3;4366,4367,2505;, + 3;4337,4368,2500;, + 3;2500,4368,2496;, + 3;2496,4368,4366;, + 3;4369,2506,4367;, + 3;4367,2506,2505;, + 3;2506,4369,2501;, + 3;2501,4369,4361;, + 3;2509,2555,2508;, + 3;2509,2554,2555;, + 3;2510,2627,2509;, + 3;2510,2626,2627;, + 3;2511,2597,2510;, + 3;2511,2596,2597;, + 3;2512,2514,2511;, + 3;2512,2513,2514;, + 3;2510,2508,2511;, + 3;2511,2508,2507;, + 3;2511,2507,2512;, + 3;2508,2510,2509;, + 3;2515,2596,2514;, + 3;2515,2595,2596;, + 3;2516,2605,2515;, + 3;2516,2604,2605;, + 3;2517,2520,2516;, + 3;2517,2519,2520;, + 3;2516,2513,2518;, + 3;2516,2518,2517;, + 3;2513,2516,2515;, + 3;2513,2515,2514;, + 3;2521,2604,2520;, + 3;2521,2603,2604;, + 3;2522,2609,2521;, + 3;2522,2608,2609;, + 3;2523,2525,2522;, + 3;2523,2524,2525;, + 3;2519,2522,2521;, + 3;2519,2521,2520;, + 3;2522,2519,2523;, + 3;2526,2608,2525;, + 3;2526,2607,2608;, + 3;2527,2619,2526;, + 3;2527,2618,2619;, + 3;2528,2575,2527;, + 3;2528,2574,2575;, + 3;2529,2532,2528;, + 3;2529,2531,2532;, + 3;2527,2526,2528;, + 3;2528,2526,2529;, + 3;2529,2526,2530;, + 3;2530,2526,2525;, + 3;2530,2525,2524;, + 3;2533,2574,2532;, + 3;2533,2580,2574;, + 3;2534,2539,2533;, + 3;2534,2538,2539;, + 3;2536,2534,2531;, + 3;2531,2534,2532;, + 3;2532,2534,2533;, + 3;2534,2536,2535;, + 3;2540,2580,2539;, + 3;2540,2579,2580;, + 3;2541,2570,2540;, + 3;2541,2569,2570;, + 3;2543,2718,2542;, + 3;2543,2717,2718;, + 3;2543,2539,2538;, + 3;2543,2538,2537;, + 3;2539,2543,2540;, + 3;2540,2543,2542;, + 3;2540,2542,2541;, + 3;2545,2561,2544;, + 3;2545,2560,2561;, + 3;2546,2632,2545;, + 3;2546,2631,2632;, + 3;2547,2624,2546;, + 3;2547,2623,2624;, + 3;2548,2552,2547;, + 3;2548,2551,2552;, + 3;2546,2544,2549;, + 3;2546,2549,2547;, + 3;2547,2549,2548;, + 3;2544,2546,2545;, + 3;2553,2623,2552;, + 3;2553,2622,2623;, + 3;2554,2628,2553;, + 3;2554,2627,2628;, + 3;2554,2550,2555;, + 3;2550,2554,2551;, + 3;2551,2554,2553;, + 3;2551,2553,2552;, + 3;2557,2562,2556;, + 3;2557,2567,2562;, + 3;2558,2583,2557;, + 3;2558,2582,2583;, + 3;2559,2592,2558;, + 3;2559,2591,2592;, + 3;2560,2633,2559;, + 3;2560,2632,2633;, + 3;2560,2559,2557;, + 3;2560,2557,2556;, + 3;2560,2556,2561;, + 3;2557,2559,2558;, + 3;2564,2568,2563;, + 3;2564,2573,2568;, + 3;2565,2645,2564;, + 3;2565,2644,2645;, + 3;2566,2639,2565;, + 3;2566,2638,2639;, + 3;2567,2584,2566;, + 3;2567,2583,2584;, + 3;2565,2567,2566;, + 3;2567,2565,2564;, + 3;2567,2564,2562;, + 3;2562,2564,2563;, + 3;2571,2579,2570;, + 3;2571,2578,2579;, + 3;2572,2667,2571;, + 3;2572,2666,2667;, + 3;2573,2640,2572;, + 3;2573,2645,2640;, + 3;2572,2568,2573;, + 3;2568,2572,2569;, + 3;2569,2572,2571;, + 3;2569,2571,2570;, + 3;2576,2618,2575;, + 3;2576,2617,2618;, + 3;2577,2648,2576;, + 3;2577,2647,2648;, + 3;2578,2661,2577;, + 3;2578,2667,2661;, + 3;2576,2580,2577;, + 3;2577,2580,2579;, + 3;2577,2579,2578;, + 3;2580,2576,2574;, + 3;2574,2576,2575;, + 3;2581,2612,2589;, + 3;2581,2611,2612;, + 3;2582,2593,2581;, + 3;2582,2592,2593;, + 3;2585,2638,2584;, + 3;2585,2637,2638;, + 3;2586,2673,2585;, + 3;2586,2672,2673;, + 3;2587,2670,2586;, + 3;2587,2669,2670;, + 3;2588,2651,2587;, + 3;2588,2650,2651;, + 3;2589,2614,2588;, + 3;2589,2613,2614;, + 3;2584,2587,2585;, + 3;2585,2587,2586;, + 3;2587,2584,2582;, + 3;2587,2582,2581;, + 3;2587,2581,2588;, + 3;2588,2581,2589;, + 3;2582,2584,2583;, + 3;2590,2602,2594;, + 3;2590,2601,2602;, + 3;2591,2634,2590;, + 3;2591,2633,2634;, + 3;2594,2611,2593;, + 3;2594,2610,2611;, + 3;2592,2591,2593;, + 3;2593,2591,2590;, + 3;2593,2590,2594;, + 3;2595,2606,2599;, + 3;2595,2605,2606;, + 3;2598,2626,2597;, + 3;2598,2629,2626;, + 3;2599,2621,2598;, + 3;2599,2620,2621;, + 3;2597,2596,2598;, + 3;2598,2596,2599;, + 3;2599,2596,2595;, + 3;2600,2620,2606;, + 3;2600,2625,2620;, + 3;2601,2630,2600;, + 3;2601,2634,2630;, + 3;2603,2610,2602;, + 3;2603,2609,2610;, + 3;2604,2602,2605;, + 3;2605,2602,2601;, + 3;2605,2601,2606;, + 3;2606,2601,2600;, + 3;2602,2604,2603;, + 3;2607,2613,2612;, + 3;2607,2619,2613;, + 3;2609,2608,2610;, + 3;2610,2608,2612;, + 3;2610,2612,2611;, + 3;2612,2608,2607;, + 3;2615,2650,2614;, + 3;2615,2654,2650;, + 3;2616,2656,2615;, + 3;2616,2655,2656;, + 3;2617,2649,2616;, + 3;2617,2648,2649;, + 3;2618,2616,2619;, + 3;2619,2616,2615;, + 3;2619,2615,2614;, + 3;2619,2614,2613;, + 3;2616,2618,2617;, + 3;2622,2629,2621;, + 3;2622,2628,2629;, + 3;2625,2631,2624;, + 3;2625,2630,2631;, + 3;2624,2623,2625;, + 3;2625,2623,2621;, + 3;2625,2621,2620;, + 3;2621,2623,2622;, + 3;2627,2626,2628;, + 3;2628,2626,2629;, + 3;2633,2632,2631;, + 3;2633,2631,2630;, + 3;2633,2630,2634;, + 3;2635,2644,2639;, + 3;2635,2643,2644;, + 3;2636,2678,2635;, + 3;2636,2677,2678;, + 3;2637,2674,2636;, + 3;2637,2673,2674;, + 3;2638,2637,2639;, + 3;2639,2637,2635;, + 3;2635,2637,2636;, + 3;2641,2666,2640;, + 3;2641,2665,2666;, + 3;2642,2695,2641;, + 3;2642,2694,2695;, + 3;2643,2679,2642;, + 3;2643,2678,2679;, + 3;2640,2645,2644;, + 3;2640,2644,2643;, + 3;2640,2643,2641;, + 3;2641,2643,2642;, + 3;2646,2655,2649;, + 3;2646,2660,2655;, + 3;2647,2662,2646;, + 3;2647,2661,2662;, + 3;2648,2647,2649;, + 3;2649,2647,2646;, + 3;2652,2669,2651;, + 3;2652,2668,2669;, + 3;2653,2688,2652;, + 3;2653,2687,2688;, + 3;2654,2657,2653;, + 3;2654,2656,2657;, + 3;2650,2654,2653;, + 3;2650,2653,2651;, + 3;2651,2653,2652;, + 3;2658,2687,2657;, + 3;2658,2686,2687;, + 3;2659,2693,2658;, + 3;2659,2692,2693;, + 3;2660,2663,2659;, + 3;2660,2662,2663;, + 3;2656,2659,2657;, + 3;2657,2659,2658;, + 3;2659,2656,2660;, + 3;2660,2656,2655;, + 3;2664,2692,2663;, + 3;2664,2691,2692;, + 3;2665,2696,2664;, + 3;2665,2695,2696;, + 3;2662,2666,2665;, + 3;2662,2665,2663;, + 3;2663,2665,2664;, + 3;2666,2662,2667;, + 3;2667,2662,2661;, + 3;2668,2683,2671;, + 3;2668,2688,2683;, + 3;2671,2672,2670;, + 3;2671,2676,2672;, + 3;2671,2670,2668;, + 3;2668,2670,2669;, + 3;2675,2677,2674;, + 3;2675,2682,2677;, + 3;2676,2684,2675;, + 3;2676,2683,2684;, + 3;2675,2674,2676;, + 3;2676,2674,2672;, + 3;2672,2674,2673;, + 3;2680,2694,2679;, + 3;2680,2697,2694;, + 3;2681,2690,2680;, + 3;2681,2689,2690;, + 3;2682,2685,2681;, + 3;2682,2684,2685;, + 3;2680,2679,2681;, + 3;2681,2679,2682;, + 3;2682,2679,2677;, + 3;2677,2679,2678;, + 3;2686,2689,2685;, + 3;2686,2693,2689;, + 3;2685,2683,2688;, + 3;2685,2688,2686;, + 3;2686,2688,2687;, + 3;2683,2685,2684;, + 3;2691,2697,2690;, + 3;2691,2696,2697;, + 3;2689,2693,2690;, + 3;2690,2693,2691;, + 3;2691,2693,2692;, + 3;2697,2696,2694;, + 3;2694,2696,2695;, + 3;2699,2714,2698;, + 3;2699,2713,2714;, + 3;2701,2698,2702;, + 3;2698,2701,2699;, + 3;2699,2701,2700;, + 3;2703,2711,2707;, + 3;2703,2710,2711;, + 3;2704,2706,2705;, + 3;2707,4331,2703;, + 3;2706,2704,4325;, + 3;2709,2716,2708;, + 3;2709,2715,2716;, + 3;2709,2712,2711;, + 3;2709,2711,2710;, + 3;2712,2709,2713;, + 3;2713,2709,2714;, + 3;2714,2709,2708;, + 3;2718,2717,2716;, + 3;2718,2716,2719;, + 3;2719,2716,2715;, + 3;2721,2767,2720;, + 3;2721,2766,2767;, + 3;2722,2761,2721;, + 3;2721,2761,2762;, + 3;2722,2721,2720;, + 3;2722,2720,2725;, + 3;2722,2725,2723;, + 3;2723,2725,2724;, + 3;2727,2753,2726;, + 3;2727,2752,2753;, + 3;2730,2747,2729;, + 3;2730,2746,2747;, + 3;2732,2733,2731;, + 3;2732,2738,2733;, + 3;2728,2731,2729;, + 3;2729,2731,2730;, + 3;2731,2728,2727;, + 3;2731,2727,2732;, + 3;2732,2727,2726;, + 3;2735,3387,2734;, + 3;2735,3386,3387;, + 3;2736,2824,2735;, + 3;2736,2823,2824;, + 3;2737,2742,2736;, + 3;2737,2741,2742;, + 3;2734,2733,2735;, + 3;2735,2733,2738;, + 3;2735,2738,2736;, + 3;2736,2738,2737;, + 3;2743,2823,2742;, + 3;2743,2822,2823;, + 3;2744,2942,2743;, + 3;2744,2941,2942;, + 3;2742,2741,2744;, + 3;2742,2744,2743;, + 3;2744,2741,2739;, + 3;2739,2741,2740;, + 3;1883,2746,2745;, + 3;1883,2747,2746;, + 3;1883,2748,2747;, + 3;2750,2758,2749;, + 3;2750,2757,2758;, + 3;2753,2750,2749;, + 3;2750,2753,2751;, + 3;2751,2753,2752;, + 3;2756,2760,2755;, + 3;2756,2759,2760;, + 3;2757,2755,2758;, + 3;2758,2755,2754;, + 3;2755,2757,2756;, + 3;2763,2766,2762;, + 3;2763,2765,2766;, + 3;2759,2762,2761;, + 3;2759,2761,2760;, + 3;2762,2759,2764;, + 3;2762,2764,2763;, + 3;2765,2767,2766;, + 3;2767,2765,2768;, + 3;2771,3118,2770;, + 3;2771,3117,3118;, + 3;4370,2865,2771;, + 3;4370,4371,2865;, + 3;2773,3053,2772;, + 3;2773,3052,3053;, + 3;2774,3057,4372;, + 3;2773,4373,3058;, + 3;2774,2770,2769;, + 3;2770,2774,2771;, + 3;2771,2774,4372;, + 3;2771,4372,4370;, + 3;2775,3044,2780;, + 3;2775,3048,3044;, + 3;1886,3085,2775;, + 3;1886,1944,3085;, + 3;2776,1918,1886;, + 3;2776,3064,1918;, + 3;2777,4374,4375;, + 3;2777,3054,4374;, + 3;2778,2863,2777;, + 3;2778,2862,2863;, + 3;2779,3359,2778;, + 3;2779,3358,3359;, + 3;4376,2789,2779;, + 3;4376,4377,2789;, + 3;4378,2777,4375;, + 3;4378,2778,2777;, + 3;4378,2779,2778;, + 3;4378,4376,2779;, + 3;1886,2775,2780;, + 3;2781,3369,2788;, + 3;2781,3368,3369;, + 3;2782,2857,4379;, + 3;2781,4380,2858;, + 3;2783,2860,2782;, + 3;2783,2869,2860;, + 3;2784,3384,2783;, + 3;2784,3383,3384;, + 3;2785,3412,2784;, + 3;2785,3415,3412;, + 3;2786,3093,2785;, + 3;2786,3098,3093;, + 3;2787,2808,2786;, + 3;2787,2807,2808;, + 3;4381,3362,2787;, + 3;4381,4382,3362;, + 3;4381,2785,4379;, + 3;4379,2785,2784;, + 3;4379,2784,2782;, + 3;2782,2784,2783;, + 3;2785,4381,2786;, + 3;2786,4381,2787;, + 3;2790,3358,2789;, + 3;2790,3357,3358;, + 3;2791,3373,2790;, + 3;2791,3372,3373;, + 3;2792,3378,2791;, + 3;2792,3377,3378;, + 3;2793,3197,2792;, + 3;2793,3196,3197;, + 3;2794,3017,2793;, + 3;2794,3016,3017;, + 3;2795,3041,2794;, + 3;2795,3040,3041;, + 3;4377,3045,2795;, + 3;4377,4383,3045;, + 3;2794,2793,2795;, + 3;2795,2793,4377;, + 3;4377,2793,2792;, + 3;4377,2792,2789;, + 3;2789,2792,2791;, + 3;2789,2791,2790;, + 3;2797,4384,4385;, + 3;2802,2991,2987;, + 3;2798,4384,2797;, + 3;2798,3363,4384;, + 3;2799,2806,2798;, + 3;2799,2815,2806;, + 3;2800,3090,2799;, + 3;2800,3089,3090;, + 3;1891,2945,2800;, + 3;1891,1893,2945;, + 3;4253,4386,4387;, + 3;4253,2974,4386;, + 3;2802,3082,4253;, + 3;2802,3083,3082;, + 3;1891,4385,2801;, + 3;1891,2797,4385;, + 3;1891,2798,2797;, + 3;1891,2799,2798;, + 3;1891,2800,2799;, + 3;2803,4388,4389;, + 3;2803,3020,4388;, + 3;2804,3022,2803;, + 3;2804,3021,3022;, + 3;2805,2997,2804;, + 3;2805,2996,2997;, + 3;4389,2982,2805;, + 3;4389,4390,2982;, + 3;4389,2804,2803;, + 3;4389,2805,2804;, + 3;2807,3363,2806;, + 3;2807,3362,3363;, + 3;2809,3098,2808;, + 3;2809,3097,3098;, + 3;2810,3135,2809;, + 3;2810,3134,3135;, + 3;2811,4391,4392;, + 3;2811,3159,4391;, + 3;2812,3110,2811;, + 3;2812,3115,3110;, + 3;4393,3148,2812;, + 3;4393,4394,3148;, + 3;2814,3122,2813;, + 3;2814,3121,3122;, + 3;2815,3091,2814;, + 3;2815,3090,3091;, + 3;2806,2810,2809;, + 3;2806,2809,2807;, + 3;2807,2809,2808;, + 3;2810,2806,4395;, + 3;4395,2806,4396;, + 3;4396,2806,2813;, + 3;2813,2806,2814;, + 3;2814,2806,2815;, + 3;2816,3400,2825;, + 3;2816,3399,3400;, + 3;2817,3404,2816;, + 3;2816,3404,3405;, + 3;2818,2892,2817;, + 3;2818,2891,2892;, + 3;2819,2899,2818;, + 3;2819,2898,2899;, + 3;2820,2905,2819;, + 3;2820,2904,2905;, + 3;2821,2883,2820;, + 3;2821,2887,2883;, + 3;2822,2943,2821;, + 3;2822,2942,2943;, + 3;2825,3386,2824;, + 3;2825,3385,3386;, + 3;2817,2819,2818;, + 3;2819,2817,2820;, + 3;2820,2817,2821;, + 3;2821,2817,2816;, + 3;2821,2816,2822;, + 3;2822,2816,2825;, + 3;2822,2825,2823;, + 3;2823,2825,2824;, + 3;2826,2843,2832;, + 3;2826,2842,2843;, + 3;2827,2854,2826;, + 3;2827,2853,2854;, + 3;2830,2909,2829;, + 3;2830,2908,2909;, + 3;2831,2915,2830;, + 3;2831,2914,2915;, + 3;2832,2889,2831;, + 3;2832,2888,2889;, + 3;2830,2829,2832;, + 3;2830,2832,2831;, + 3;2832,2829,2827;, + 3;2832,2827,2826;, + 3;2827,2829,2828;, + 3;2833,2896,2838;, + 3;2833,2895,2896;, + 3;2834,3380,2833;, + 3;2834,3379,3380;, + 3;2835,2868,2834;, + 3;2835,2867,2868;, + 3;2836,2848,2835;, + 3;2836,2847,2848;, + 3;2838,2840,2837;, + 3;2838,2839,2840;, + 3;2835,2834,2836;, + 3;2836,2834,2837;, + 3;2837,2834,2838;, + 3;2838,2834,2833;, + 3;2839,2888,2843;, + 3;2839,2896,2888;, + 3;2842,2855,2841;, + 3;2842,2854,2855;, + 3;2842,2840,2839;, + 3;2842,2839,2843;, + 3;2840,2842,2841;, + 3;2844,3116,2849;, + 3;2844,3119,3116;, + 3;2849,2867,2848;, + 3;2849,2866,2867;, + 3;2847,2849,2848;, + 3;2849,2847,2844;, + 3;2844,2847,2846;, + 3;2844,2846,2845;, + 3;2851,2855,2852;, + 3;2852,2855,2853;, + 3;2853,2855,2854;, + 3;2855,2851,2850;, + 3;2856,3361,2859;, + 3;2856,3360,3361;, + 3;4380,2861,2856;, + 3;2857,2860,4397;, + 3;2859,3368,2858;, + 3;2859,3367,3368;, + 3;4380,2856,2859;, + 3;4380,2859,2858;, + 3;2862,3360,2861;, + 3;2862,3359,3360;, + 3;2864,3054,2863;, + 3;2864,3053,3054;, + 3;2866,3117,2865;, + 3;2866,3116,3117;, + 3;2869,3379,2868;, + 3;2869,3384,3379;, + 3;2867,2866,2865;, + 3;2867,2865,2868;, + 3;2868,2865,4371;, + 3;2868,4371,4397;, + 3;2868,4397,2860;, + 3;2868,2860,2869;, + 3;2861,2864,2863;, + 3;2861,2863,2862;, + 3;2873,2940,2872;, + 3;2873,2939,2940;, + 3;2874,2886,2873;, + 3;2874,2885,2886;, + 3;2875,2919,2874;, + 3;2875,2918,2919;, + 3;2876,2925,2875;, + 3;2876,2924,2925;, + 3;2877,2879,2876;, + 3;2877,2878,2879;, + 3;2874,2876,2875;, + 3;2876,2874,2873;, + 3;2876,2873,2872;, + 3;2876,2872,2877;, + 3;2877,2872,2871;, + 3;2877,2871,2870;, + 3;2880,2924,2879;, + 3;2880,2923,2924;, + 3;2881,2930,2880;, + 3;2881,2929,2930;, + 3;2878,2880,2879;, + 3;2880,2878,2881;, + 3;2881,2878,2882;, + 3;2884,2904,2883;, + 3;2884,2903,2904;, + 3;2885,2920,2884;, + 3;2885,2919,2920;, + 3;2887,2939,2886;, + 3;2887,2943,2939;, + 3;2886,2885,2887;, + 3;2887,2885,2884;, + 3;2887,2884,2883;, + 3;2890,2914,2889;, + 3;2890,2913,2914;, + 3;2891,2900,2890;, + 3;2891,2899,2900;, + 3;2893,3404,2817;, + 3;2893,3403,3404;, + 3;2894,3409,2893;, + 3;2894,3408,3409;, + 3;2895,3381,2894;, + 3;2895,3380,3381;, + 3;2890,2889,2891;, + 3;2891,2889,2892;, + 3;2892,2889,2888;, + 3;2892,2888,2893;, + 3;2893,2888,2895;, + 3;2893,2895,2894;, + 3;2895,2888,2896;, + 3;2897,2938,2901;, + 3;2897,2937,2938;, + 3;2898,2906,2897;, + 3;2898,2905,2906;, + 3;2901,2913,2900;, + 3;2901,2912,2913;, + 3;2899,2898,2900;, + 3;2900,2898,2897;, + 3;2900,2897,2901;, + 3;2902,2937,2906;, + 3;2902,2936,2937;, + 3;2903,2921,2902;, + 3;2903,2920,2921;, + 3;2902,2906,2903;, + 3;2903,2906,2904;, + 3;2904,2906,2905;, + 3;2907,2933,2911;, + 3;2907,2932,2933;, + 3;2908,2916,2907;, + 3;2908,2915,2916;, + 3;2911,2928,2910;, + 3;2911,2927,2928;, + 3;2908,2907,2911;, + 3;2908,2911,2909;, + 3;2909,2911,2910;, + 3;2912,2932,2916;, + 3;2912,2938,2932;, + 3;2916,2914,2912;, + 3;2912,2914,2913;, + 3;2914,2916,2915;, + 3;2917,2936,2921;, + 3;2917,2935,2936;, + 3;2918,2926,2917;, + 3;2918,2925,2926;, + 3;2918,2920,2919;, + 3;2920,2918,2921;, + 3;2921,2918,2917;, + 3;2922,2935,2926;, + 3;2922,2934,2935;, + 3;2923,2931,2922;, + 3;2923,2930,2931;, + 3;2926,2923,2922;, + 3;2923,2926,2925;, + 3;2923,2925,2924;, + 3;2927,2934,2931;, + 3;2927,2933,2934;, + 3;2931,2928,2927;, + 3;2928,2931,2930;, + 3;2928,2930,2929;, + 3;2934,2933,2935;, + 3;2935,2933,2938;, + 3;2935,2938,2937;, + 3;2935,2937,2936;, + 3;2938,2933,2932;, + 3;2939,2943,2942;, + 3;2939,2942,2940;, + 3;2940,2942,2941;, + 3;2944,3104,2947;, + 3;2944,3109,3104;, + 3;1893,3395,2944;, + 3;1893,2014,3395;, + 3;2946,3089,2945;, + 3;2946,3088,3089;, + 3;2947,2954,2946;, + 3;2947,2953,2954;, + 3;1893,2946,2945;, + 3;1893,2947,2946;, + 3;1893,2944,2947;, + 3;2948,3144,2952;, + 3;2948,3143,3144;, + 3;2949,2967,2948;, + 3;2949,2966,2967;, + 3;2950,3153,2949;, + 3;2950,3152,3153;, + 3;2951,3113,2950;, + 3;2951,3112,3113;, + 3;2952,3161,2951;, + 3;2952,3160,3161;, + 3;2950,2952,2951;, + 3;2952,2950,2949;, + 3;2952,2949,2948;, + 3;2953,3105,2956;, + 3;2953,3104,3105;, + 3;2955,3088,2954;, + 3;2955,3087,3088;, + 3;2956,3129,2955;, + 3;2956,3128,3129;, + 3;2953,2956,2955;, + 3;2953,2955,2954;, + 3;2957,3096,2964;, + 3;2957,3095,3096;, + 3;2958,3411,2957;, + 3;2958,3410,3411;, + 3;2959,3402,2958;, + 3;2959,3401,3402;, + 3;2960,3398,2959;, + 3;2960,3397,3398;, + 3;2961,2970,2960;, + 3;2961,2969,2970;, + 3;2962,3099,2961;, + 3;2962,3103,3099;, + 3;2963,3136,2962;, + 3;2963,3140,3136;, + 3;2964,3132,2963;, + 3;2964,3131,3132;, + 3;2958,2962,2959;, + 3;2959,2962,2960;, + 3;2960,2962,2961;, + 3;2962,2958,2957;, + 3;2962,2957,2963;, + 3;2963,2957,2964;, + 3;2965,3127,2973;, + 3;2965,3126,3127;, + 3;4398,3154,2965;, + 3;2966,3153,4399;, + 3;2968,3142,4400;, + 3;2967,4401,3143;, + 3;2969,3100,2968;, + 3;2969,3099,3100;, + 3;2971,3397,2970;, + 3;2971,3396,3397;, + 3;2972,3391,2971;, + 3;2972,3390,3391;, + 3;2973,3107,2972;, + 3;2973,3106,3107;, + 3;2971,2968,2972;, + 3;2972,2968,4400;, + 3;2972,4400,2973;, + 3;2973,4400,4398;, + 3;2973,4398,2965;, + 3;2968,2971,2969;, + 3;2969,2971,2970;, + 3;2974,4402,4386;, + 3;2974,3082,4402;, + 3;2975,2996,2982;, + 3;2975,3000,2996;, + 3;2976,3208,2975;, + 3;2976,3207,3208;, + 3;2977,3220,2976;, + 3;2977,3219,3220;, + 3;2978,3221,2977;, + 3;2978,3226,3221;, + 3;2979,3227,2978;, + 3;2979,3232,3227;, + 3;2980,3199,2979;, + 3;2980,3198,3199;, + 3;2981,3376,2980;, + 3;2981,3375,3376;, + 3;4390,2988,2981;, + 3;4390,4403,2988;, + 3;4390,2975,2982;, + 3;4390,2976,2975;, + 3;4390,2977,2976;, + 3;4390,2978,2977;, + 3;4390,2979,2978;, + 3;4390,2980,2979;, + 3;4390,2981,2980;, + 3;2983,3011,2986;, + 3;2983,3010,3011;, + 3;2984,3024,2983;, + 3;2984,3023,3024;, + 3;2985,3019,2984;, + 3;2985,3018,3019;, + 3;4404,3084,2985;, + 3;4404,4405,3084;, + 3;2986,4406,4404;, + 3;2986,2995,4406;, + 3;4404,2983,2986;, + 3;4404,2984,2983;, + 3;4404,2985,2984;, + 3;4403,3083,2987;, + 3;4403,4402,3083;, + 3;2989,3375,2988;, + 3;2989,3374,3375;, + 3;2990,3371,2989;, + 3;2990,3370,3371;, + 3;2991,3365,2990;, + 3;2991,3364,3365;, + 3;4403,2989,2988;, + 3;4403,2990,2989;, + 3;4403,2991,2990;, + 3;4403,2987,2991;, + 3;2992,4407,4406;, + 3;2992,3047,4407;, + 3;2993,3034,2992;, + 3;2993,3033,3034;, + 3;2994,3003,2993;, + 3;2994,3002,3003;, + 3;2995,3012,2994;, + 3;2995,3011,3012;, + 3;4406,2993,2992;, + 3;4406,2994,2993;, + 3;4406,2995,2994;, + 3;2998,3021,2997;, + 3;2998,3027,3021;, + 3;2999,3209,2998;, + 3;2999,3214,3209;, + 3;3000,3203,2999;, + 3;3000,3208,3203;, + 3;2997,2999,2998;, + 3;2999,2997,2996;, + 3;2999,2996,3000;, + 3;3001,3172,3007;, + 3;3001,3177,3172;, + 3;3002,3013,3001;, + 3;3002,3012,3013;, + 3;3004,3033,3003;, + 3;3004,3037,3033;, + 3;3005,3031,3004;, + 3;3005,3030,3031;, + 3;3006,3184,3005;, + 3;3006,3183,3184;, + 3;3007,3182,3006;, + 3;3007,3181,3182;, + 3;3003,3006,3004;, + 3;3004,3006,3005;, + 3;3006,3003,3007;, + 3;3007,3003,3002;, + 3;3007,3002,3001;, + 3;3008,3177,3013;, + 3;3008,3176,3177;, + 3;3009,3171,3008;, + 3;3009,3170,3171;, + 3;3010,3025,3009;, + 3;3010,3024,3025;, + 3;3010,3008,3013;, + 3;3010,3013,3011;, + 3;3011,3013,3012;, + 3;3008,3010,3009;, + 3;3014,3196,3017;, + 3;3014,3202,3196;, + 3;3015,3191,3014;, + 3;3015,3190,3191;, + 3;3016,3042,3015;, + 3;3016,3041,3042;, + 3;3016,3015,3017;, + 3;3017,3015,3014;, + 3;3018,4405,4388;, + 3;3018,3084,4405;, + 3;3020,3023,3019;, + 3;3020,3022,3023;, + 3;4388,3019,3018;, + 3;4388,3020,3019;, + 3;3026,3170,3025;, + 3;3026,3169,3170;, + 3;3027,3210,3026;, + 3;3027,3209,3210;, + 3;3026,3025,3027;, + 3;3027,3025,3022;, + 3;3027,3022,3021;, + 3;3022,3025,3023;, + 3;3023,3025,3024;, + 3;3028,3038,3032;, + 3;3028,3043,3038;, + 3;3029,3195,3028;, + 3;3029,3194,3195;, + 3;3030,3185,3029;, + 3;3030,3184,3185;, + 3;3032,3037,3031;, + 3;3032,3036,3037;, + 3;3029,3031,3030;, + 3;3031,3029,3032;, + 3;3032,3029,3028;, + 3;3035,3047,3034;, + 3;3035,3046,3047;, + 3;3036,3039,3035;, + 3;3036,3038,3039;, + 3;3034,3037,3036;, + 3;3034,3036,3035;, + 3;3037,3034,3033;, + 3;3040,3046,3039;, + 3;3040,3045,3046;, + 3;3043,3190,3042;, + 3;3043,3195,3190;, + 3;3040,3042,3041;, + 3;3042,3040,3043;, + 3;3043,3040,3039;, + 3;3043,3039,3038;, + 3;3048,1944,4408;, + 3;3048,3085,1944;, + 3;4408,3044,3048;, + 3;4407,3045,4383;, + 3;4407,3046,3045;, + 3;4407,3047,3046;, + 3;3050,3064,3049;, + 3;3050,3070,3064;, + 3;3052,3059,3051;, + 3;3052,3058,3059;, + 3;4297,3054,3051;, + 3;3051,3054,3053;, + 3;3051,3053,3052;, + 3;3054,4297,4374;, + 3;4373,4314,3058;, + 3;3058,4314,3055;, + 3;3058,3055,3059;, + 3;3060,3073,3063;, + 3;3060,3072,3073;, + 3;3061,3066,3060;, + 3;3061,3065,3066;, + 3;4409,3086,3061;, + 3;4295,4293,4410;, + 3;3062,4308,4409;, + 3;3062,3077,4308;, + 3;3063,3075,3062;, + 3;3063,3074,3075;, + 3;4409,3063,3062;, + 3;4409,3060,3063;, + 3;4409,3061,3060;, + 3;4411,1944,1918;, + 3;4411,4412,1944;, + 3;3067,4413,4414;, + 3;3067,3071,4413;, + 3;3068,3081,3067;, + 3;3068,3080,3081;, + 3;4415,4414,4416;, + 3;4415,3067,4414;, + 3;4415,3068,3067;, + 3;4415,3069,3068;, + 3;1918,3070,4299;, + 3;1918,3064,3070;, + 3;3071,151,3755;, + 3;3071,3081,151;, + 3;4417,3074,3073;, + 3;4417,4309,3074;, + 3;3755,4413,3071;, + 3;4417,3073,3072;, + 3;3076,3077,3075;, + 3;3076,3079,3077;, + 3;4309,3076,3074;, + 3;3074,3076,3075;, + 3;4308,3079,3078;, + 3;4308,3077,3079;, + 3;151,3081,3080;, + 3;4402,3082,3083;, + 3;3087,3130,3092;, + 3;3087,3129,3130;, + 3;3092,3121,3091;, + 3;3092,3120,3121;, + 3;3090,3089,3091;, + 3;3091,3089,3092;, + 3;3092,3089,3088;, + 3;3092,3088,3087;, + 3;3094,3415,3093;, + 3;3094,3414,3415;, + 3;3095,3406,3094;, + 3;3095,3411,3406;, + 3;3097,3131,3096;, + 3;3097,3135,3131;, + 3;3097,3096,3098;, + 3;3098,3096,3093;, + 3;3093,3096,3094;, + 3;3094,3096,3095;, + 3;3101,3142,3100;, + 3;3101,3141,3142;, + 3;3102,3165,3101;, + 3;3102,3164,3165;, + 3;3103,3137,3102;, + 3;3103,3136,3137;, + 3;3100,3099,3101;, + 3;3101,3099,3103;, + 3;3101,3103,3102;, + 3;3106,3128,3105;, + 3;3106,3127,3128;, + 3;3108,3390,3107;, + 3;3108,3389,3390;, + 3;3109,3392,3108;, + 3;3109,3395,3392;, + 3;3107,3106,3108;, + 3;3108,3106,3105;, + 3;3108,3105,3104;, + 3;3108,3104,3109;, + 3;3111,3159,3110;, + 3;3111,3158,3159;, + 3;3112,3162,3111;, + 3;3112,3161,3162;, + 3;3114,3152,3113;, + 3;3114,3151,3152;, + 3;3115,3145,3114;, + 3;3115,3148,3145;, + 3;3115,3111,3110;, + 3;3111,3115,3114;, + 3;3111,3114,3112;, + 3;3112,3114,3113;, + 3;3117,3119,3118;, + 3;3119,3117,3116;, + 3;3120,3125,3124;, + 3;3120,3130,3125;, + 3;3123,3147,3122;, + 3;3123,3146,3147;, + 3;3124,3150,3123;, + 3;3124,3149,3150;, + 3;3121,3123,3122;, + 3;3123,3121,3120;, + 3;3123,3120,3124;, + 3;3126,3149,3125;, + 3;3126,3154,3149;, + 3;3128,3126,3125;, + 3;3128,3125,3129;, + 3;3129,3125,3130;, + 3;3126,3128,3127;, + 3;3133,3140,3132;, + 3;3133,3139,3140;, + 3;3134,3156,3133;, + 3;3134,3155,3156;, + 3;3134,3133,3135;, + 3;3135,3133,3131;, + 3;3131,3133,3132;, + 3;3138,3164,3137;, + 3;3138,3163,3164;, + 3;3139,3157,3138;, + 3;3139,3156,3157;, + 3;3140,3138,3137;, + 3;3140,3137,3136;, + 3;3138,3140,3139;, + 3;4418,3160,3144;, + 3;4418,4419,3160;, + 3;3143,4401,4418;, + 3;3143,4418,3144;, + 3;4420,3151,3145;, + 3;4420,4421,3151;, + 3;4394,3145,3148;, + 3;3145,4394,4420;, + 3;4399,3153,4422;, + 3;4422,3153,3152;, + 3;4422,3152,4421;, + 3;4421,3152,3151;, + 3;3158,4423,4424;, + 3;3158,3162,4423;, + 3;4391,3159,4425;, + 3;4425,3159,3158;, + 3;4425,3158,4424;, + 3;4426,4423,3161;, + 3;4426,3161,3160;, + 3;4426,3160,4419;, + 3;3161,4423,3162;, + 3;3166,3176,3171;, + 3;3166,3175,3176;, + 3;3167,3256,3166;, + 3;3167,3255,3256;, + 3;3168,3287,3167;, + 3;3168,3286,3287;, + 3;3169,3211,3168;, + 3;3169,3210,3211;, + 3;3167,3169,3168;, + 3;3169,3167,3166;, + 3;3169,3166,3170;, + 3;3170,3166,3171;, + 3;3173,3181,3172;, + 3;3173,3180,3181;, + 3;3174,3260,3173;, + 3;3174,3259,3260;, + 3;3175,3257,3174;, + 3;3175,3256,3257;, + 3;3173,3176,3174;, + 3;3174,3176,3175;, + 3;3176,3173,3177;, + 3;3177,3173,3172;, + 3;3178,3183,3182;, + 3;3178,3189,3183;, + 3;3179,3269,3178;, + 3;3179,3268,3269;, + 3;3180,3261,3179;, + 3;3180,3260,3261;, + 3;3181,3178,3182;, + 3;3178,3181,3179;, + 3;3179,3181,3180;, + 3;3186,3194,3185;, + 3;3186,3193,3194;, + 3;3187,3233,3186;, + 3;3187,3239,3233;, + 3;3188,3274,3187;, + 3;3188,3273,3274;, + 3;3189,3270,3188;, + 3;3189,3269,3270;, + 3;3187,3186,3188;, + 3;3188,3186,3185;, + 3;3188,3185,3184;, + 3;3188,3184,3189;, + 3;3189,3184,3183;, + 3;3192,3202,3191;, + 3;3192,3201,3202;, + 3;3193,3234,3192;, + 3;3193,3233,3234;, + 3;3195,3191,3190;, + 3;3191,3195,3194;, + 3;3191,3194,3193;, + 3;3191,3193,3192;, + 3;3198,3377,3197;, + 3;3198,3376,3377;, + 3;3200,3232,3199;, + 3;3200,3231,3232;, + 3;3201,3235,3200;, + 3;3201,3234,3235;, + 3;3197,3201,3200;, + 3;3197,3200,3198;, + 3;3198,3200,3199;, + 3;3201,3197,3202;, + 3;3202,3197,3196;, + 3;3204,3214,3203;, + 3;3204,3213,3214;, + 3;3205,3282,3204;, + 3;3205,3281,3282;, + 3;3206,3291,3205;, + 3;3206,3290,3291;, + 3;3207,3215,3206;, + 3;3207,3220,3215;, + 3;3205,3207,3206;, + 3;3207,3205,3208;, + 3;3208,3205,3204;, + 3;3208,3204,3203;, + 3;3212,3286,3211;, + 3;3212,3285,3286;, + 3;3213,3283,3212;, + 3;3213,3282,3283;, + 3;3211,3209,3214;, + 3;3211,3214,3212;, + 3;3212,3214,3213;, + 3;3209,3211,3210;, + 3;3216,3290,3215;, + 3;3216,3289,3290;, + 3;3217,3253,3216;, + 3;3217,3252,3253;, + 3;3218,3246,3217;, + 3;3218,3245,3246;, + 3;3219,3222,3218;, + 3;3219,3221,3222;, + 3;3215,3218,3216;, + 3;3216,3218,3217;, + 3;3218,3215,3219;, + 3;3219,3215,3220;, + 3;3223,3245,3222;, + 3;3223,3244,3245;, + 3;3224,3294,3223;, + 3;3224,3298,3294;, + 3;3225,3299,3224;, + 3;3225,3304,3299;, + 3;3226,3228,3225;, + 3;3226,3227,3228;, + 3;3224,3222,3225;, + 3;3225,3222,3221;, + 3;3225,3221,3226;, + 3;3222,3224,3223;, + 3;3229,3304,3228;, + 3;3229,3303,3304;, + 3;3230,3322,3229;, + 3;3230,3321,3322;, + 3;3231,3236,3230;, + 3;3231,3235,3236;, + 3;3229,3228,3227;, + 3;3229,3227,3232;, + 3;3229,3232,3230;, + 3;3230,3232,3231;, + 3;3237,3321,3236;, + 3;3237,3320,3321;, + 3;3238,3306,3237;, + 3;3238,3305,3306;, + 3;3239,3275,3238;, + 3;3239,3274,3275;, + 3;3238,3237,3234;, + 3;3238,3234,3233;, + 3;3238,3233,3239;, + 3;3234,3237,3235;, + 3;3235,3237,3236;, + 3;3240,3272,3248;, + 3;3240,3278,3272;, + 3;3241,3312,3240;, + 3;3241,3311,3312;, + 3;3242,3328,3241;, + 3;3242,3327,3328;, + 3;3243,3334,3242;, + 3;3243,3333,3334;, + 3;3244,3295,3243;, + 3;3244,3294,3295;, + 3;3247,3252,3246;, + 3;3247,3251,3252;, + 3;3248,3266,3247;, + 3;3248,3271,3266;, + 3;3244,3241,3246;, + 3;3244,3246,3245;, + 3;3246,3241,3247;, + 3;3247,3241,3240;, + 3;3247,3240,3248;, + 3;3241,3244,3243;, + 3;3241,3243,3242;, + 3;3249,3289,3253;, + 3;3249,3293,3289;, + 3;3250,3263,3249;, + 3;3250,3262,3263;, + 3;3251,3267,3250;, + 3;3251,3266,3267;, + 3;3252,3251,3253;, + 3;3253,3251,3249;, + 3;3249,3251,3250;, + 3;3254,3279,3258;, + 3;3254,3284,3279;, + 3;3255,3288,3254;, + 3;3255,3287,3288;, + 3;3258,3259,3257;, + 3;3258,3265,3259;, + 3;3255,3254,3256;, + 3;3256,3254,3258;, + 3;3256,3258,3257;, + 3;3262,3268,3261;, + 3;3262,3267,3268;, + 3;3264,3293,3263;, + 3;3264,3292,3293;, + 3;3265,3280,3264;, + 3;3265,3279,3280;, + 3;3260,3259,3262;, + 3;3260,3262,3261;, + 3;3262,3259,3263;, + 3;3263,3259,3265;, + 3;3263,3265,3264;, + 3;3271,3273,3270;, + 3;3271,3272,3273;, + 3;3268,3267,3269;, + 3;3269,3267,3271;, + 3;3269,3271,3270;, + 3;3271,3267,3266;, + 3;3276,3305,3275;, + 3;3276,3308,3305;, + 3;3277,3314,3276;, + 3;3277,3319,3314;, + 3;3278,3313,3277;, + 3;3278,3312,3313;, + 3;3274,3276,3275;, + 3;3276,3274,3273;, + 3;3276,3273,3277;, + 3;3277,3273,3278;, + 3;3278,3273,3272;, + 3;3281,3292,3280;, + 3;3281,3291,3292;, + 3;3284,3285,3283;, + 3;3284,3288,3285;, + 3;3281,3280,3282;, + 3;3282,3280,3284;, + 3;3282,3284,3283;, + 3;3284,3280,3279;, + 3;3286,3285,3287;, + 3;3287,3285,3288;, + 3;3289,3291,3290;, + 3;3291,3289,3292;, + 3;3292,3289,3293;, + 3;3296,3333,3295;, + 3;3296,3332,3333;, + 3;3297,3340,3296;, + 3;3297,3339,3340;, + 3;3298,3300,3297;, + 3;3298,3299,3300;, + 3;3294,3298,3295;, + 3;3295,3298,3297;, + 3;3295,3297,3296;, + 3;3301,3339,3300;, + 3;3301,3338,3339;, + 3;3302,3355,3301;, + 3;3302,3354,3355;, + 3;3303,3323,3302;, + 3;3303,3322,3323;, + 3;3303,3299,3304;, + 3;3299,3303,3300;, + 3;3300,3303,3302;, + 3;3300,3302,3301;, + 3;3307,3320,3306;, + 3;3307,3326,3320;, + 3;3308,3315,3307;, + 3;3308,3314,3315;, + 3;3305,3308,3306;, + 3;3306,3308,3307;, + 3;3309,3319,3313;, + 3;3309,3318,3319;, + 3;3310,3344,3309;, + 3;3310,3343,3344;, + 3;3311,3329,3310;, + 3;3311,3328,3329;, + 3;3312,3309,3313;, + 3;3309,3312,3311;, + 3;3309,3311,3310;, + 3;3316,3326,3315;, + 3;3316,3325,3326;, + 3;3317,3350,3316;, + 3;3317,3349,3350;, + 3;3318,3345,3317;, + 3;3318,3344,3345;, + 3;3319,3316,3315;, + 3;3319,3315,3314;, + 3;3316,3319,3318;, + 3;3316,3318,3317;, + 3;3324,3354,3323;, + 3;3324,3353,3354;, + 3;3325,3351,3324;, + 3;3325,3350,3351;, + 3;3326,3322,3321;, + 3;3326,3321,3320;, + 3;3322,3326,3323;, + 3;3323,3326,3325;, + 3;3323,3325,3324;, + 3;3327,3335,3330;, + 3;3327,3334,3335;, + 3;3330,3343,3329;, + 3;3330,3342,3343;, + 3;3330,3329,3327;, + 3;3327,3329,3328;, + 3;3331,3342,3335;, + 3;3331,3347,3342;, + 3;3332,3341,3331;, + 3;3332,3340,3341;, + 3;3331,3335,3332;, + 3;3332,3335,3334;, + 3;3332,3334,3333;, + 3;3336,3347,3341;, + 3;3336,3346,3347;, + 3;3337,3348,3336;, + 3;3337,3352,3348;, + 3;3338,3356,3337;, + 3;3338,3355,3356;, + 3;3337,3336,3338;, + 3;3338,3336,3341;, + 3;3338,3341,3340;, + 3;3338,3340,3339;, + 3;3346,3349,3345;, + 3;3346,3348,3349;, + 3;3346,3342,3347;, + 3;3342,3346,3343;, + 3;3343,3346,3345;, + 3;3343,3345,3344;, + 3;3352,3353,3351;, + 3;3352,3356,3353;, + 3;3348,3352,3349;, + 3;3349,3352,3351;, + 3;3349,3351,3350;, + 3;3356,3355,3353;, + 3;3353,3355,3354;, + 3;3357,3367,3361;, + 3;3357,3373,3367;, + 3;3359,3357,3361;, + 3;3359,3361,3360;, + 3;3357,3359,3358;, + 3;3366,3370,3365;, + 3;3366,3369,3370;, + 3;4384,3362,4382;, + 3;3365,3364,3366;, + 3;3362,4384,3363;, + 3;3372,3374,3371;, + 3;3372,3378,3374;, + 3;3371,3368,3367;, + 3;3371,3367,3373;, + 3;3371,3373,3372;, + 3;3368,3371,3369;, + 3;3369,3371,3370;, + 3;3376,3378,3377;, + 3;3378,3376,3375;, + 3;3378,3375,3374;, + 3;3382,3408,3381;, + 3;3382,3407,3408;, + 3;3383,3413,3382;, + 3;3383,3412,3413;, + 3;3381,3383,3382;, + 3;3383,3381,3384;, + 3;3384,3381,3380;, + 3;3384,3380,3379;, + 3;3385,3396,3391;, + 3;3385,3400,3396;, + 3;3389,3393,3388;, + 3;3389,3392,3393;, + 3;3390,3389,3387;, + 3;3390,3387,3391;, + 3;3391,3387,3386;, + 3;3391,3386,3385;, + 3;3387,3389,3388;, + 3;2014,3392,3395;, + 3;2014,3393,3392;, + 3;2014,3394,3393;, + 3;3399,3401,3398;, + 3;3399,3405,3401;, + 3;3400,3399,3398;, + 3;3400,3398,3397;, + 3;3400,3397,3396;, + 3;3403,3410,3402;, + 3;3403,3409,3410;, + 3;3401,3405,3403;, + 3;3401,3403,3402;, + 3;3403,3405,3404;, + 3;3407,3414,3406;, + 3;3407,3413,3414;, + 3;3410,3407,3411;, + 3;3411,3407,3406;, + 3;3407,3410,3408;, + 3;3408,3410,3409;, + 3;3414,3413,3412;, + 3;3414,3412,3415;, + 3;21,88,845;, + 3;151,846,3755;, + 3;4310,4309,4427;, + 3;4310,4428,4311;, + 3;1769,3416,1770;, + 3;3416,1778,4148;, + 3;3417,1901,4429;, + 3;4429,4234,3417;, + 3;4430,3510,185;, + 3;4430,185,3509;, + 3;61,4431,3448;, + 3;61,0,4431;; + + MeshNormals { + 4432; + -0.989571;-0.011953;-0.143551;, + -0.433214;-0.193876;-0.880192;, + -0.984781;0.061328;-0.162622;, + -0.000005;0.123093;-0.992395;, + -0.989261;0.138490;-0.046722;, + -0.588256;0.730768;-0.346313;, + 0.077792;0.437259;0.895965;, + -0.812611;0.166144;0.558622;, + -0.008181;0.252116;0.967663;, + 0.485631;0.575618;0.657895;, + 0.055097;0.933688;0.353823;, + -0.093634;0.341116;0.935346;, + -0.006241;0.260589;0.965430;, + -0.649875;0.280683;0.706314;, + 0.000025;-0.011554;0.999933;, + -0.338437;0.350328;-0.873345;, + 0.000004;-0.093947;-0.995577;, + 0.000016;-0.316597;-0.948560;, + -0.015033;-0.328905;-0.944243;, + -0.576566;-0.459455;-0.675627;, + -0.434273;0.868349;-0.239535;, + -0.151234;0.506148;0.849083;, + -0.164626;0.337297;-0.926892;, + -0.802913;0.231146;0.549456;, + 0.210760;-0.136730;0.967928;, + -0.336341;-0.108795;0.935435;, + 0.244564;-0.065106;0.967445;, + -0.963334;-0.094433;0.251137;, + -0.885448;-0.301099;-0.354007;, + -0.495937;0.082114;0.864467;, + -0.957644;0.220431;0.185280;, + 0.693967;0.242883;0.677803;, + 0.527840;-0.168309;0.832500;, + 0.026768;-0.438717;0.898227;, + -0.000016;-0.990834;-0.135089;, + -0.701247;-0.651828;-0.288743;, + -0.982778;-0.084744;-0.164211;, + -0.001279;-0.024600;-0.999697;, + 0.000009;-0.204621;0.978841;, + -0.895650;-0.343271;-0.282799;, + -0.559206;0.508717;0.654596;, + -0.314707;0.781987;-0.538011;, + 0.000005;-0.999974;0.007152;, + 0.114825;-0.948131;-0.296416;, + -0.145665;-0.919602;-0.364848;, + -0.449270;0.893379;-0.005605;, + 0.000168;0.854980;0.518661;, + -0.000538;0.773627;-0.633641;, + -0.027645;-0.423869;0.905301;, + -0.705970;-0.446329;0.549906;, + -0.273835;-0.400153;0.874581;, + 0.233305;-0.886660;0.399253;, + 0.513833;-0.494239;0.701216;, + -0.790963;-0.525076;0.314122;, + 0.174039;-0.984266;0.030518;, + -0.591766;-0.268191;0.760188;, + -0.187456;-0.160792;0.969023;, + 0.000101;-0.114170;0.993461;, + 0.000002;0.058647;-0.998279;, + -0.131625;-0.050608;-0.990007;, + -0.731235;-0.158649;-0.663420;, + -0.974460;-0.127344;-0.184962;, + -0.859652;-0.309116;-0.406751;, + -0.916036;-0.145104;-0.373928;, + -0.817874;-0.539381;-0.200374;, + 0.278233;-0.273728;0.920684;, + 0.854774;-0.403493;0.326429;, + 0.853727;-0.007027;-0.520673;, + -0.977952;0.018441;0.208015;, + -0.951874;0.289606;0.100323;, + -0.979629;0.019166;-0.199899;, + -0.986179;0.140164;0.088351;, + -0.871225;-0.451441;0.192789;, + -0.529409;-0.220751;0.819143;, + -0.944779;0.327439;0.013305;, + -0.881035;0.426148;0.205365;, + -0.957604;-0.179816;-0.225078;, + -0.994196;0.051821;0.094280;, + -0.964421;0.191784;-0.181966;, + -0.980241;-0.139652;0.140090;, + 0.000023;-0.244851;-0.969561;, + -0.048245;-0.332029;-0.942035;, + -0.432334;-0.434648;-0.790043;, + -0.722354;-0.365988;-0.586734;, + -0.957758;-0.287242;0.013841;, + -0.000013;0.370748;-0.928733;, + -0.040453;0.710290;-0.702746;, + 0.313062;0.614710;0.723964;, + -0.460194;0.616751;0.638623;, + 0.000001;0.024616;-0.999697;, + -0.226499;-0.140193;-0.963869;, + -0.457101;-0.023022;-0.889117;, + -0.664851;0.117356;-0.737700;, + -0.897582;0.211412;-0.386848;, + -0.903847;0.420928;-0.076682;, + -0.135198;0.773486;0.619226;, + -0.141004;0.621292;0.770788;, + 0.124490;0.581568;0.803916;, + 0.000876;0.616105;0.787664;, + 0.387797;0.626448;0.676148;, + 0.149512;-0.247279;-0.957340;, + -0.905288;0.176534;0.386380;, + -0.867052;0.137579;0.478846;, + -0.829671;0.408671;0.380308;, + -0.701860;0.270507;0.658953;, + -0.892567;0.378889;-0.244475;, + 0.351384;0.936193;-0.008488;, + 0.237101;0.465138;0.852895;, + 0.221316;0.433286;0.873660;, + 0.000301;0.766126;0.642690;, + -0.037085;0.936295;-0.349251;, + 0.413738;0.852881;0.318456;, + 0.000002;0.301740;-0.953390;, + -0.138062;0.039474;-0.989637;, + -0.439435;0.173212;-0.881416;, + -0.632058;0.089542;-0.769730;, + -0.851652;0.387173;-0.353250;, + -0.886195;0.463152;-0.012222;, + 0.766299;0.388719;0.511550;, + -0.968326;0.059868;0.242406;, + -0.892378;0.166006;0.419647;, + -0.818963;0.564690;-0.102099;, + -0.830607;0.230508;0.506910;, + -0.758821;0.117889;0.640541;, + -0.044908;-0.611148;0.790241;, + -0.886549;0.392710;-0.244562;, + -0.899773;0.187812;0.393873;, + -0.898020;0.299543;-0.322233;, + -0.947696;-0.212901;-0.237792;, + -0.502434;-0.677413;0.537282;, + -0.291292;-0.349896;0.890349;, + -0.057118;-0.609638;0.790619;, + -0.987507;0.156917;-0.014374;, + -0.323785;0.508980;0.797560;, + -0.901688;0.259664;-0.345736;, + -0.805182;0.220087;-0.550676;, + -0.645712;-0.763581;-0.000279;, + 0.990082;-0.015546;-0.139630;, + 0.433214;-0.193877;-0.880192;, + 0.987185;0.081535;-0.137175;, + 0.990910;0.129582;-0.036136;, + 0.260508;0.727642;-0.634565;, + -0.091231;0.428920;0.898724;, + 0.811080;0.164853;0.561224;, + -0.559324;0.693597;0.453961;, + 0.100417;0.338390;0.935633;, + 0.649875;0.280683;0.706314;, + 0.338436;0.350327;-0.873346;, + 0.015042;-0.328899;-0.944245;, + 0.576566;-0.459455;-0.675627;, + 0.434273;0.868349;-0.239535;, + 0.306690;0.520580;0.796830;, + 0.164619;0.337297;-0.926893;, + 0.802913;0.231146;0.549456;, + -0.210733;-0.136750;0.967931;, + 0.336341;-0.108795;0.935435;, + -0.244564;-0.065106;0.967445;, + 0.963334;-0.094433;0.251137;, + 0.885448;-0.301099;-0.354007;, + 0.495937;0.082114;0.864467;, + 0.957644;0.220431;0.185280;, + -0.602846;0.290303;0.743169;, + -0.527840;-0.168309;0.832500;, + -0.026768;-0.438717;0.898227;, + 0.701248;-0.651828;-0.288742;, + 0.982279;-0.089104;-0.164890;, + 0.895650;-0.343271;-0.282799;, + 0.566570;0.495981;0.658028;, + 0.309521;0.783229;-0.539212;, + -0.114791;-0.948135;-0.296417;, + 0.145665;-0.919602;-0.364848;, + 0.481298;0.876550;-0.003471;, + 0.027647;-0.423868;0.905302;, + 0.705254;-0.446887;0.550372;, + 0.273873;-0.400246;0.874527;, + -0.233305;-0.886660;0.399253;, + -0.513833;-0.494239;0.701216;, + 0.790963;-0.525076;0.314122;, + -0.174039;-0.984266;0.030518;, + 0.591063;-0.270370;0.759963;, + 0.187382;-0.161599;0.968903;, + 0.131624;-0.050609;-0.990007;, + 0.731235;-0.158649;-0.663420;, + 0.974460;-0.127344;-0.184962;, + 0.859652;-0.309116;-0.406751;, + 0.916036;-0.145104;-0.373928;, + 0.817874;-0.539381;-0.200374;, + -0.278232;-0.273728;0.920684;, + -0.854773;-0.403493;0.326429;, + -0.853727;-0.007027;-0.520673;, + 0.972307;0.015440;0.233196;, + 0.956394;0.275771;0.096231;, + 0.981505;0.019792;-0.190410;, + 0.972924;0.196620;0.121487;, + 0.955178;-0.252865;0.153929;, + 0.506951;-0.238596;0.828295;, + 0.964289;0.264843;-0.002032;, + 0.916931;0.363083;0.165554;, + 0.987197;-0.118160;-0.107142;, + 0.774218;0.487454;0.403702;, + 0.963480;0.174780;-0.202875;, + 0.970183;-0.159926;0.182121;, + 0.048272;-0.332044;-0.942028;, + 0.430577;-0.435479;-0.790545;, + 0.722112;-0.366391;-0.586781;, + 0.957347;-0.288570;0.014659;, + -0.305307;0.626286;0.717324;, + 0.448693;0.679150;0.580886;, + 0.226504;-0.140193;-0.963868;, + 0.457101;-0.023022;-0.889117;, + 0.664851;0.117356;-0.737700;, + 0.897582;0.211412;-0.386848;, + 0.903847;0.420928;-0.076682;, + 0.135198;0.773486;0.619226;, + 0.122893;0.649057;0.750748;, + -0.142710;0.597235;0.789268;, + -0.439283;0.626634;0.643708;, + -0.149496;-0.247276;-0.957343;, + 0.905288;0.176534;0.386380;, + 0.867052;0.137579;0.478846;, + 0.829671;0.408671;0.380308;, + 0.701860;0.270507;0.658953;, + 0.892567;0.378889;-0.244475;, + -0.362258;0.932010;-0.011212;, + -0.188184;0.477638;0.858166;, + -0.167233;0.445019;0.879768;, + 0.042064;0.935662;-0.350382;, + -0.453111;0.835822;0.309986;, + 0.138068;0.039474;-0.989636;, + 0.439435;0.173212;-0.881416;, + 0.632058;0.089542;-0.769730;, + 0.851652;0.387173;-0.353250;, + 0.886195;0.463152;-0.012222;, + -0.740748;0.411825;0.530746;, + 0.968326;0.059868;0.242406;, + 0.892378;0.166006;0.419647;, + 0.818963;0.564690;-0.102099;, + 0.830607;0.230508;0.506910;, + 0.758821;0.117889;0.640541;, + 0.044907;-0.611148;0.790241;, + 0.886549;0.392710;-0.244561;, + 0.899773;0.187812;0.393873;, + 0.898020;0.299543;-0.322233;, + 0.947696;-0.212901;-0.237792;, + 0.502434;-0.677413;0.537282;, + 0.291292;-0.349896;0.890349;, + 0.057117;-0.609638;0.790619;, + 0.987507;0.156917;-0.014374;, + 0.323785;0.508980;0.797560;, + 0.901688;0.259664;-0.345736;, + 0.805182;0.220087;-0.550676;, + 0.645712;-0.763581;-0.000280;, + -0.000035;0.202257;-0.979333;, + 0.000000;-0.152057;-0.988372;, + -0.986678;0.148934;0.065464;, + -0.248728;-0.201732;-0.947332;, + -0.091949;-0.099791;0.990751;, + -0.000076;-0.461661;-0.887057;, + 0.675377;-0.238040;0.698000;, + -0.372066;0.352850;-0.858524;, + -0.920508;0.371208;0.121944;, + 0.954651;-0.166315;-0.246941;, + -0.770854;-0.091830;-0.630358;, + -0.522907;0.552336;0.649225;, + -0.269360;-0.762341;0.588456;, + -0.705008;-0.050622;-0.707390;, + -0.421748;0.283560;-0.861233;, + 0.643644;-0.015506;0.765168;, + 0.992661;-0.000187;-0.120932;, + 0.935445;-0.035033;-0.351732;, + -0.263483;-0.085234;0.960891;, + -0.344264;0.023341;0.938583;, + 0.887402;-0.082890;-0.453484;, + -0.649836;0.205407;-0.731793;, + -0.872109;0.095397;-0.479922;, + -0.894885;0.082610;0.438584;, + -0.554738;0.084178;-0.827756;, + 0.054057;-0.076987;-0.995566;, + -0.908432;0.107750;-0.403908;, + 0.495001;-0.126597;0.859620;, + 0.968704;-0.213268;-0.126998;, + 0.313056;0.378120;0.871219;, + 0.365426;-0.280297;0.887636;, + 0.067345;-0.084014;-0.994186;, + -0.012682;-0.010483;0.999865;, + 0.064836;-0.191491;-0.979351;, + -0.289534;0.030294;-0.956688;, + -0.200942;0.148449;0.968290;, + 0.020471;-0.061478;-0.997899;, + -0.400237;0.683181;0.610798;, + 0.453303;-0.497746;0.739435;, + 0.521055;-0.809078;0.271835;, + 0.735182;-0.666684;0.122637;, + 0.821914;-0.569537;-0.009215;, + 0.759558;-0.443873;-0.475446;, + -0.572197;-0.246884;0.782073;, + -0.565959;-0.798793;0.204013;, + -0.757874;-0.650275;-0.052618;, + -0.707861;-0.682627;-0.181530;, + -0.657196;-0.390140;-0.644891;, + 0.215407;0.452689;0.865259;, + 0.845085;0.295788;0.445355;, + 0.869444;0.325743;0.371427;, + 0.954242;-0.257523;0.152001;, + -0.520474;0.526586;0.672171;, + -0.936897;0.300664;0.178397;, + -0.940651;0.338859;-0.018731;, + -0.960352;-0.063982;-0.271348;, + 0.059122;-0.098574;-0.993372;, + 0.798460;-0.602012;-0.006594;, + -0.809310;-0.499093;-0.309716;, + 0.179068;-0.150961;-0.972186;, + -0.113992;0.003257;-0.993476;, + -0.245507;-0.085870;-0.965584;, + 0.381448;-0.090026;0.919996;, + -0.473877;0.315534;0.822119;, + 0.834619;-0.338308;0.434694;, + 0.968707;-0.002938;-0.248189;, + -0.984728;-0.003402;0.174069;, + 0.518085;0.053826;-0.853634;, + -0.717724;0.062444;-0.693523;, + -0.172176;-0.025937;-0.984725;, + 0.990528;-0.094784;-0.099347;, + 0.716933;-0.028565;-0.696556;, + -0.638618;0.047039;-0.768085;, + 0.860708;-0.108316;0.497444;, + -0.837234;0.055243;0.544046;, + 0.955485;-0.120740;-0.269203;, + -0.670236;0.022528;-0.741806;, + -0.945620;0.026607;-0.324184;, + -0.472020;0.096403;0.876301;, + 0.537901;-0.058446;-0.840980;, + -0.381353;0.920775;0.082119;, + 0.682106;-0.030649;0.730611;, + -0.557613;-0.562556;0.610408;, + 0.846805;0.072950;-0.526877;, + 0.049962;-0.004893;-0.998739;, + 0.666223;-0.143179;0.731879;, + -0.861291;-0.041597;-0.506406;, + 0.034482;-0.052609;-0.998020;, + 0.068707;0.488169;-0.870040;, + 0.007891;-0.135395;-0.990760;, + -0.145988;-0.211055;-0.966511;, + -0.279880;-0.147467;0.948641;, + -0.762165;0.039662;0.646167;, + 0.389810;-0.013375;0.920798;, + 0.757187;-0.049995;0.651282;, + 0.181561;-0.108135;0.977416;, + -0.887763;0.274320;0.369629;, + -0.354476;-0.066564;0.932693;, + -0.705742;-0.122863;0.697734;, + -0.804425;-0.481755;0.347580;, + -0.911357;-0.405828;0.068791;, + -0.868967;-0.391802;-0.302304;, + -0.955392;-0.286491;-0.071754;, + -0.212265;-0.554761;-0.804478;, + -0.300497;-0.671647;-0.677194;, + 0.566503;-0.333624;0.753505;, + 0.705192;-0.523353;0.478336;, + 0.734833;-0.590132;0.334314;, + 0.703206;-0.672001;-0.232197;, + 0.353830;-0.592859;-0.723410;, + 0.909177;-0.368835;-0.193282;, + 0.738914;-0.651028;0.173689;, + 0.318223;-0.742396;-0.589561;, + 0.039464;-0.745272;-0.665591;, + -0.507519;-0.687744;-0.519069;, + 0.143708;-0.090742;0.985451;, + -0.325692;0.036226;0.944782;, + -0.642110;-0.406225;0.650135;, + -0.726668;-0.619543;0.296850;, + -0.754218;-0.609442;0.244407;, + -0.480671;-0.816061;-0.320936;, + -0.438781;-0.895636;-0.072854;, + -0.216241;-0.550378;-0.806427;, + -0.375817;-0.659247;-0.651272;, + 0.524041;-0.621420;0.582424;, + 0.478543;-0.696415;0.534792;, + 0.479492;-0.729402;0.487915;, + 0.552158;-0.818101;-0.160724;, + 0.216081;-0.555173;-0.803176;, + 0.390037;-0.917415;-0.078869;, + 0.462565;-0.763825;0.450117;, + 0.298517;-0.762623;-0.573840;, + 0.099219;-0.723576;-0.683077;, + -0.363985;-0.781659;-0.506482;, + -0.687634;-0.340006;-0.641526;, + -0.554595;-0.700435;0.449238;, + 0.007793;-0.618390;0.785832;, + -0.700055;-0.676002;-0.230094;, + 0.152980;0.089858;-0.984136;, + 0.639689;-0.061333;0.766183;, + -0.671801;-0.148929;-0.725605;, + 0.982818;-0.144272;-0.115132;, + -0.539943;-0.790977;-0.287777;, + -0.425702;-0.452816;-0.783413;, + -0.120435;0.764300;-0.633515;, + 0.634155;0.239730;0.735103;, + 0.100998;-0.684788;0.721710;, + -0.373807;-0.009779;-0.927455;, + -0.400118;0.694772;0.597660;, + -0.642458;0.753052;0.141985;, + 0.220397;-0.805586;0.549959;, + 0.474612;-0.157723;0.865949;, + 0.286302;-0.330049;-0.899499;, + 0.364402;-0.047676;0.930020;, + -0.153579;-0.916119;-0.370324;, + -0.360583;-0.309427;-0.879906;, + 0.603621;-0.355989;0.713382;, + -0.339341;-0.048326;0.939421;, + -0.969969;-0.035649;-0.240603;, + -0.299431;-0.946414;-0.120998;, + 0.164304;-0.789581;0.591242;, + -0.678182;-0.699706;-0.224678;, + -0.069164;-0.822330;0.564792;, + -0.245535;-0.396112;-0.884764;, + -0.891450;-0.383892;-0.240717;, + 0.072762;-0.780842;0.620477;, + -0.595632;-0.621882;0.508414;, + -0.752466;-0.638225;0.162674;, + -0.299599;-0.795145;0.527243;, + -0.000137;-0.920182;0.391491;, + -0.114339;0.740537;0.662217;, + -0.673865;0.641908;0.365869;, + 0.368870;0.664338;0.650069;, + -0.929837;0.223510;-0.292314;, + 0.987497;0.100828;0.121175;, + -0.037200;-0.353239;-0.934793;, + 0.000005;-0.908853;-0.417117;, + -0.275159;-0.572461;0.772383;, + 1.000000;0.000000;0.000000;, + -0.311030;-0.795975;-0.519312;, + -0.790481;-0.221084;-0.571194;, + -0.264462;-0.862138;0.432178;, + -0.597714;-0.523944;0.606812;, + -0.550598;-0.834581;0.017782;, + -0.162744;0.615741;0.770959;, + -0.877145;-0.439089;0.194469;, + -0.415729;0.666519;0.618807;, + -0.278425;0.851658;-0.444026;, + -0.537797;0.842499;0.031136;, + 0.000014;0.999890;-0.014824;, + -0.000345;0.842160;-0.539228;, + -0.136592;-0.525506;-0.839754;, + 0.000010;-0.577151;-0.816638;, + -0.226785;-0.723353;0.652173;, + 0.000147;-0.426759;0.904366;, + -0.312156;-0.802806;-0.507998;, + -0.702614;-0.504599;-0.501711;, + -0.270629;-0.843099;0.464697;, + -0.618679;-0.620211;0.482259;, + -0.545698;-0.837393;0.031400;, + -0.530614;0.817949;0.222282;, + -0.520441;-0.817752;0.245812;, + 0.000135;0.503934;0.863742;, + 0.000081;-0.865374;0.501127;, + -0.494858;0.862986;0.101841;, + -0.877073;-0.347968;0.331150;, + -0.848954;-0.000633;0.528467;, + -0.435124;-0.365516;0.822840;, + -0.171310;-0.101103;0.980016;, + -0.280330;-0.874167;0.396545;, + -0.857649;-0.059936;0.510730;, + -0.851056;-0.296513;0.433340;, + -0.292987;0.538921;-0.789761;, + -0.385669;0.149737;-0.910405;, + -0.498102;0.070627;0.864237;, + 0.072329;0.379525;-0.922350;, + 0.076379;0.219461;-0.972627;, + 0.202960;-0.006085;-0.979168;, + 0.224477;-0.161615;-0.960984;, + 0.287531;-0.313110;-0.905145;, + 0.508736;-0.187881;-0.840171;, + -0.692298;0.454233;-0.560710;, + -0.793609;0.199236;-0.574882;, + 0.696581;-0.112033;-0.708677;, + 0.671521;-0.145121;-0.726636;, + 0.672596;-0.215313;-0.707993;, + -0.558239;-0.020619;-0.829424;, + -0.534769;-0.089005;-0.840298;, + -0.513705;-0.196613;-0.835135;, + -0.349154;0.242462;0.905154;, + -0.631346;0.402228;0.663035;, + -0.146145;-0.055401;0.987711;, + -0.321667;0.474266;0.819514;, + -0.592931;-0.025934;0.804835;, + 0.232003;0.000577;0.972715;, + 0.340346;0.050732;-0.938931;, + -0.044769;0.183553;-0.981990;, + 0.908812;-0.397053;0.128099;, + 0.918662;-0.341700;0.198244;, + 0.938847;-0.129908;-0.318889;, + -0.995822;0.066694;-0.062372;, + -0.913711;-0.184581;0.362025;, + -0.773515;-0.042525;0.632350;, + 0.562379;0.010758;-0.826809;, + -0.346217;0.118076;-0.930694;, + -0.716207;0.131762;-0.685336;, + 0.723032;0.009740;0.690746;, + 0.936260;-0.073710;0.343489;, + -0.899016;0.099518;-0.426458;, + 0.016111;-0.054691;0.998373;, + 0.652732;-0.056214;0.755500;, + -0.677075;0.091018;0.730264;, + -0.550517;-0.135376;0.823775;, + -0.748083;0.060359;-0.660855;, + -0.891510;0.146220;-0.428753;, + -0.200461;-0.141215;-0.969471;, + 0.229795;-0.207572;-0.950846;, + 0.832397;-0.148190;-0.534000;, + 0.583371;-0.208319;-0.785036;, + 0.980272;0.130639;0.148327;, + 0.965909;-0.084351;-0.244754;, + 0.951984;0.131127;0.276644;, + -0.935643;0.156818;0.316197;, + -0.559482;-0.050274;-0.827317;, + -0.972281;0.214777;-0.092415;, + -0.532795;-0.071842;0.843189;, + -0.476940;-0.083345;0.874975;, + 0.274845;-0.070215;-0.958921;, + 0.028471;-0.057604;-0.997933;, + 0.574856;-0.080803;-0.814255;, + 0.144145;-0.089235;0.985525;, + 0.827608;-0.099104;0.552489;, + -0.876485;-0.009071;0.481344;, + -0.995610;0.037774;-0.085641;, + -0.905860;0.032618;-0.422319;, + -0.808523;0.001652;-0.588462;, + 0.845060;-0.044480;-0.532817;, + 0.979465;-0.039533;-0.197703;, + 0.956895;-0.080204;0.279139;, + -0.691297;-0.047071;-0.721036;, + -0.412896;-0.055933;-0.909059;, + 0.999321;0.028755;-0.023042;, + 0.912214;-0.035085;-0.408209;, + 0.563445;-0.089914;-0.821246;, + -0.351468;0.039937;-0.935348;, + 0.956673;-0.049558;0.286915;, + 0.269123;0.056572;0.961443;, + 0.740501;-0.038151;0.670971;, + -0.562631;0.056481;0.824776;, + -0.925797;0.040436;0.375851;, + -0.315953;0.018351;0.948597;, + 0.056900;0.108101;-0.992510;, + 0.090328;-0.066382;-0.993697;, + 0.226044;-0.018716;0.973937;, + -0.906954;0.117975;-0.404371;, + 0.992970;-0.002293;0.118346;, + 0.263526;0.009804;0.964602;, + 0.960000;-0.111524;0.256830;, + 0.046754;-0.041359;-0.998050;, + 0.975814;-0.094575;0.197085;, + 0.713467;-0.239290;-0.658563;, + 0.796247;0.046297;0.603198;, + -0.000011;0.371222;-0.928544;, + -0.000042;-0.118764;-0.992922;, + 0.045742;0.462090;-0.885653;, + 0.986678;0.148934;0.065464;, + 0.248728;-0.201732;-0.947332;, + 0.091949;-0.099791;0.990751;, + -0.675428;-0.237979;0.697971;, + 0.372066;0.352850;-0.858524;, + 0.920508;0.371208;0.121944;, + -0.954652;-0.166280;-0.246961;, + 0.770854;-0.091830;-0.630359;, + 0.522907;0.552336;0.649225;, + 0.705008;-0.050621;-0.707390;, + 0.421748;0.283560;-0.861233;, + -0.643644;-0.015506;0.765168;, + -0.992661;-0.000187;-0.120933;, + -0.935445;-0.035034;-0.351733;, + 0.263483;-0.085234;0.960891;, + 0.344265;0.023340;0.938582;, + -0.887402;-0.082890;-0.453483;, + 0.649836;0.205407;-0.731793;, + 0.872109;0.095396;-0.479922;, + 0.894885;0.082610;0.438585;, + 0.554737;0.084178;-0.827756;, + -0.054057;-0.076987;-0.995566;, + 0.908432;0.107750;-0.403908;, + -0.495001;-0.126597;0.859620;, + -0.968704;-0.213269;-0.126998;, + -0.313056;0.378120;0.871218;, + -0.365426;-0.280297;0.887636;, + -0.067345;-0.084014;-0.994186;, + 0.012681;-0.010483;0.999865;, + -0.064836;-0.191491;-0.979351;, + 0.289534;0.030294;-0.956688;, + 0.200942;0.148449;0.968290;, + -0.020470;-0.061480;-0.997898;, + 0.400237;0.683181;0.610797;, + -0.453304;-0.497746;0.739435;, + -0.521055;-0.809078;0.271836;, + -0.735182;-0.666684;0.122637;, + -0.821914;-0.569537;-0.009216;, + -0.759558;-0.443871;-0.475447;, + 0.572196;-0.246884;0.782074;, + 0.565958;-0.798793;0.204014;, + 0.757874;-0.650275;-0.052618;, + 0.707861;-0.682627;-0.181531;, + 0.657196;-0.390140;-0.644891;, + -0.215408;0.452689;0.865258;, + -0.845086;0.295787;0.445354;, + -0.869444;0.325743;0.371427;, + -0.954242;-0.257523;0.152001;, + 0.520473;0.526586;0.672172;, + 0.936897;0.300664;0.178397;, + 0.940651;0.338859;-0.018732;, + 0.960352;-0.063982;-0.271348;, + -0.059122;-0.098573;-0.993372;, + -0.798459;-0.602012;-0.006595;, + 0.809310;-0.499092;-0.309716;, + -0.179068;-0.150961;-0.972186;, + 0.113992;0.003257;-0.993476;, + 0.245507;-0.085870;-0.965584;, + -0.381448;-0.090025;0.919996;, + 0.473877;0.315534;0.822118;, + -0.834619;-0.338308;0.434694;, + -0.968707;-0.002938;-0.248190;, + 0.984728;-0.003402;0.174069;, + -0.518085;0.053827;-0.853634;, + 0.717724;0.062444;-0.693523;, + 0.172176;-0.025937;-0.984725;, + -0.990528;-0.094784;-0.099347;, + -0.716933;-0.028565;-0.696556;, + 0.638618;0.047039;-0.768085;, + -0.860708;-0.108316;0.497444;, + 0.837234;0.055243;0.544047;, + -0.955485;-0.120740;-0.269203;, + 0.670236;0.022528;-0.741806;, + 0.945620;0.026607;-0.324184;, + 0.472020;0.096403;0.876301;, + -0.537901;-0.058446;-0.840980;, + 0.381356;0.920774;0.082120;, + -0.682106;-0.030649;0.730611;, + 0.557614;-0.562555;0.610409;, + -0.846805;0.072950;-0.526877;, + -0.049962;-0.004893;-0.998739;, + -0.666223;-0.143179;0.731879;, + 0.861291;-0.041597;-0.506406;, + -0.034481;-0.052611;-0.998020;, + -0.068707;0.488169;-0.870040;, + -0.007891;-0.135398;-0.990760;, + 0.145989;-0.211055;-0.966511;, + 0.279880;-0.147467;0.948642;, + 0.762165;0.039663;0.646167;, + -0.389810;-0.013375;0.920798;, + -0.757187;-0.049996;0.651282;, + -0.181560;-0.108135;0.977416;, + 0.887763;0.274319;0.369629;, + 0.354475;-0.066564;0.932693;, + 0.705738;-0.122868;0.697737;, + 0.804429;-0.481751;0.347578;, + 0.911362;-0.405818;0.068789;, + 0.868969;-0.391799;-0.302303;, + 0.955392;-0.286490;-0.071755;, + 0.212267;-0.554751;-0.804484;, + 0.300504;-0.671641;-0.677197;, + -0.566507;-0.333623;0.753502;, + -0.705199;-0.523347;0.478333;, + -0.734835;-0.590129;0.334313;, + -0.703206;-0.672002;-0.232196;, + -0.353826;-0.592860;-0.723412;, + -0.909176;-0.368837;-0.193284;, + -0.738915;-0.651028;0.173686;, + -0.318224;-0.742397;-0.589560;, + -0.039462;-0.745268;-0.665596;, + 0.507518;-0.687743;-0.519071;, + -0.143709;-0.090742;0.985451;, + 0.325692;0.036224;0.944782;, + 0.642109;-0.406228;0.650135;, + 0.726679;-0.619532;0.296847;, + 0.754223;-0.609436;0.244406;, + 0.480673;-0.816061;-0.320933;, + 0.438780;-0.895636;-0.072859;, + 0.216240;-0.550371;-0.806432;, + 0.375822;-0.659238;-0.651277;, + -0.524041;-0.621421;0.582424;, + -0.478550;-0.696413;0.534789;, + -0.479503;-0.729395;0.487914;, + -0.552157;-0.818101;-0.160725;, + -0.216079;-0.555173;-0.803177;, + -0.390036;-0.917416;-0.078869;, + -0.462568;-0.763826;0.450113;, + -0.298518;-0.762626;-0.573837;, + -0.099215;-0.723576;-0.683077;, + 0.363989;-0.781657;-0.506483;, + 0.687634;-0.340007;-0.641526;, + 0.554595;-0.700435;0.449238;, + -0.007792;-0.618390;0.785833;, + 0.700058;-0.676000;-0.230095;, + -0.152979;0.089859;-0.984136;, + -0.639690;-0.061333;0.766182;, + 0.671802;-0.148929;-0.725605;, + -0.982818;-0.144272;-0.115132;, + 0.539944;-0.790977;-0.287776;, + 0.425700;-0.452817;-0.783413;, + 0.120436;0.764300;-0.633515;, + -0.634158;0.239730;0.735101;, + -0.100997;-0.684786;0.721711;, + 0.373807;-0.009780;-0.927455;, + 0.400118;0.694773;0.597659;, + 0.642459;0.753051;0.141986;, + -0.220398;-0.805586;0.549960;, + -0.474612;-0.157723;0.865949;, + -0.286301;-0.330049;-0.899500;, + -0.364402;-0.047676;0.930020;, + 0.153577;-0.916119;-0.370323;, + 0.360580;-0.309427;-0.879907;, + -0.603625;-0.355989;0.713378;, + 0.339341;-0.048326;0.939421;, + 0.969969;-0.035649;-0.240603;, + 0.299429;-0.946415;-0.121000;, + -0.164303;-0.789579;0.591244;, + 0.678182;-0.699706;-0.224678;, + 0.069165;-0.822329;0.564792;, + 0.245531;-0.396115;-0.884764;, + 0.891451;-0.383891;-0.240714;, + -0.072761;-0.780841;0.620478;, + 0.595631;-0.621884;0.508413;, + 0.752462;-0.638231;0.162672;, + 0.299598;-0.795145;0.527243;, + 0.114341;0.740537;0.662217;, + 0.673864;0.641909;0.365870;, + -0.368870;0.664338;0.650069;, + 0.929837;0.223510;-0.292314;, + -0.987497;0.100827;0.121175;, + 0.037200;-0.353240;-0.934793;, + 0.275160;-0.572458;0.772385;, + 0.311029;-0.795977;-0.519309;, + 0.790480;-0.221084;-0.571194;, + 0.264462;-0.862137;0.432180;, + 0.597714;-0.523943;0.606812;, + 0.550599;-0.834580;0.017784;, + 0.162598;0.616218;0.770608;, + 0.877144;-0.439088;0.194473;, + 0.415142;0.667643;0.617989;, + 0.286302;0.846489;-0.448874;, + 0.557573;0.829476;0.032896;, + 0.136611;-0.525509;-0.839749;, + 0.226786;-0.723350;0.652175;, + 0.312154;-0.802808;-0.507996;, + 0.702613;-0.504600;-0.501711;, + 0.270630;-0.843098;0.464698;, + 0.618680;-0.620209;0.482260;, + 0.545698;-0.837393;0.031400;, + 0.530646;0.817913;0.222337;, + 0.520501;-0.817725;0.245773;, + 0.494932;0.862948;0.101798;, + 0.877148;-0.347914;0.331008;, + 0.848954;-0.000633;0.528467;, + 0.435262;-0.365357;0.822837;, + 0.857736;-0.059938;0.510585;, + 0.851169;-0.296328;0.433244;, + 0.292987;0.538920;-0.789761;, + 0.385669;0.149737;-0.910405;, + 0.498102;0.070626;0.864237;, + -0.072353;0.379524;-0.922348;, + -0.076406;0.219458;-0.972625;, + -0.203011;-0.006085;-0.979158;, + -0.224521;-0.161613;-0.960974;, + -0.287588;-0.313105;-0.905129;, + -0.508756;-0.187868;-0.840163;, + 0.692298;0.454233;-0.560710;, + 0.793609;0.199236;-0.574882;, + -0.696581;-0.112033;-0.708677;, + -0.671520;-0.145121;-0.726636;, + -0.672596;-0.215313;-0.707993;, + 0.558239;-0.020619;-0.829424;, + 0.534769;-0.089005;-0.840298;, + 0.513705;-0.196613;-0.835135;, + 0.349154;0.242462;0.905154;, + 0.631346;0.402228;0.663035;, + 0.146145;-0.055401;0.987711;, + 0.321667;0.474265;0.819514;, + 0.592932;-0.025934;0.804835;, + -0.232003;0.000577;0.972715;, + -0.340346;0.050732;-0.938931;, + 0.044769;0.183553;-0.981990;, + -0.908812;-0.397053;0.128100;, + -0.918662;-0.341700;0.198244;, + -0.938847;-0.129909;-0.318890;, + 0.995822;0.066694;-0.062372;, + 0.913711;-0.184581;0.362025;, + 0.773514;-0.042525;0.632351;, + -0.562379;0.010758;-0.826810;, + 0.346217;0.118076;-0.930694;, + 0.716207;0.131762;-0.685337;, + -0.723032;0.009739;0.690746;, + -0.936259;-0.073710;0.343490;, + 0.899016;0.099517;-0.426458;, + -0.016111;-0.054691;0.998373;, + -0.652733;-0.056213;0.755500;, + 0.677075;0.091018;0.730264;, + 0.550517;-0.135376;0.823775;, + 0.748083;0.060359;-0.660855;, + 0.891510;0.146220;-0.428753;, + 0.200461;-0.141215;-0.969471;, + -0.229795;-0.207571;-0.950846;, + -0.832396;-0.148190;-0.534000;, + -0.583371;-0.208318;-0.785036;, + -0.980272;0.130639;0.148328;, + -0.965909;-0.084351;-0.244754;, + -0.951984;0.131127;0.276643;, + 0.935643;0.156818;0.316197;, + 0.559482;-0.050274;-0.827317;, + 0.972281;0.214776;-0.092415;, + 0.532795;-0.071842;0.843189;, + 0.476940;-0.083345;0.874975;, + -0.274846;-0.070215;-0.958921;, + -0.028471;-0.057604;-0.997933;, + -0.574856;-0.080803;-0.814255;, + -0.144145;-0.089235;0.985525;, + -0.827608;-0.099104;0.552489;, + 0.876485;-0.009071;0.481343;, + 0.995610;0.037774;-0.085641;, + 0.905860;0.032618;-0.422319;, + 0.808523;0.001652;-0.588462;, + -0.845060;-0.044480;-0.532817;, + -0.979465;-0.039533;-0.197703;, + -0.956895;-0.080204;0.279139;, + 0.691297;-0.047071;-0.721036;, + 0.412896;-0.055933;-0.909059;, + -0.999321;0.028755;-0.023042;, + -0.912214;-0.035085;-0.408209;, + -0.563445;-0.089914;-0.821246;, + 0.351468;0.039937;-0.935348;, + -0.956673;-0.049558;0.286915;, + -0.269123;0.056572;0.961443;, + -0.740501;-0.038151;0.670971;, + 0.562631;0.056481;0.824777;, + 0.925797;0.040436;0.375851;, + 0.315953;0.018351;0.948597;, + -0.056900;0.108101;-0.992510;, + -0.090328;-0.066382;-0.993697;, + -0.226043;-0.018716;0.973937;, + 0.906954;0.117975;-0.404371;, + -0.992970;-0.002293;0.118346;, + -0.263526;0.009803;0.964602;, + -0.960000;-0.111524;0.256830;, + -0.046754;-0.041359;-0.998050;, + -0.975831;-0.094528;0.197025;, + -0.713467;-0.239291;-0.658563;, + -0.796247;0.046297;0.603198;, + -0.045755;0.462090;-0.885652;, + -0.120567;0.889102;0.441544;, + 0.089110;0.886500;0.454068;, + 0.495887;0.107622;-0.861692;, + -0.501661;0.110800;-0.857939;, + 0.381150;0.923821;0.035779;, + -0.392218;0.560751;0.729194;, + 0.186388;0.976894;0.104581;, + 0.567905;0.521114;-0.637122;, + -0.473718;0.414055;-0.777271;, + 0.529914;-0.324726;-0.783418;, + -0.226517;-0.970474;0.082885;, + 0.207701;-0.604118;-0.769351;, + -0.527039;0.781296;-0.334374;, + -0.834983;0.264476;-0.482552;, + -0.675963;0.077412;-0.732858;, + -0.160126;0.190092;-0.968620;, + -0.228376;-0.127237;-0.965223;, + 0.068168;0.237165;0.969075;, + 0.657416;-0.744773;-0.114531;, + 0.274099;0.701037;-0.658344;, + -0.876642;-0.442049;-0.189978;, + 0.779259;0.312381;0.543299;, + -0.327724;-0.696016;0.638873;, + 0.594374;0.647132;0.477430;, + 0.984981;0.135781;-0.106662;, + -0.422834;0.836078;-0.349551;, + -0.828790;0.540637;-0.144288;, + 0.034244;0.095893;-0.994802;, + -0.641365;-0.305210;-0.703916;, + -0.923773;-0.052793;0.379284;, + 0.076548;0.939750;-0.333181;, + 0.119540;-0.960477;0.251383;, + -0.669596;-0.615981;-0.414980;, + -0.303029;-0.186091;0.934635;, + -0.234676;0.256475;0.937629;, + 0.295362;0.740439;0.603748;, + -0.353633;-0.752104;0.556133;, + -0.520041;-0.156983;0.839592;, + 0.509538;-0.839165;-0.190193;, + -0.146089;-0.981553;0.123336;, + 0.914801;0.309243;0.259824;, + 0.897041;0.033289;-0.440692;, + -0.839542;-0.269781;-0.471581;, + -0.963227;0.157435;-0.217736;, + -0.259132;0.699308;-0.666197;, + 0.604434;0.762690;0.230139;, + 0.423330;0.778916;0.462689;, + -0.434554;0.075723;0.897457;, + 0.006566;0.677354;0.735628;, + 0.749936;0.407739;-0.520908;, + 0.822491;0.188949;-0.536477;, + 0.756906;-0.145054;-0.637223;, + 0.423190;-0.716621;-0.554404;, + -0.227209;-0.966292;0.121064;, + -0.317550;-0.933835;0.164662;, + -0.496371;-0.182434;0.848725;, + -0.533776;-0.178235;0.826629;, + -0.604641;-0.410889;0.682334;, + -0.097373;-0.993304;-0.062171;, + 0.544150;0.817947;0.186717;, + 0.671652;0.718204;-0.181845;, + -0.520633;-0.800173;0.297766;, + 0.610984;0.085141;-0.787051;, + 0.315955;0.940947;0.121620;, + 0.450770;-0.364624;-0.814773;, + 0.034059;-0.236374;-0.971065;, + 0.126855;0.710394;-0.692277;, + -0.318398;0.686232;0.653995;, + -0.509804;-0.823253;0.249710;, + -0.828231;-0.560343;0.007058;, + -0.898012;0.382182;0.217971;, + -0.638411;-0.335141;0.692901;, + -0.521920;-0.736948;0.429543;, + -0.653621;0.114522;0.748107;, + -0.219228;-0.910600;-0.350351;, + -0.117938;0.862199;0.492649;, + 0.701914;0.653797;-0.282606;, + 0.566939;-0.044140;-0.822576;, + 0.698404;-0.196958;-0.688069;, + 0.634338;-0.406257;-0.657701;, + 0.726870;-0.133185;-0.673737;, + 0.790864;0.239727;-0.563086;, + 0.657555;0.711316;-0.248296;, + -0.154310;0.679156;0.717590;, + 0.231918;0.882106;0.410004;, + -0.412377;-0.755835;0.508585;, + -0.140943;-0.970084;0.197668;, + 0.311225;-0.875510;-0.369624;, + 0.597394;0.775849;-0.202927;, + -0.489055;-0.692585;0.530237;, + -0.491338;-0.534968;0.687311;, + -0.489758;-0.036774;0.871083;, + -0.438815;0.143442;0.887054;, + -0.286418;0.500490;0.816991;, + 0.627373;0.683168;-0.373745;, + 0.326963;0.774904;-0.540942;, + -0.154464;0.954555;0.254884;, + 0.414311;0.073885;-0.907131;, + 0.104101;0.966242;0.235666;, + 0.755011;0.321454;-0.571512;, + -0.578072;-0.401336;0.710466;, + 0.308722;0.426939;-0.849949;, + -0.156866;-0.502085;-0.850473;, + -0.244364;0.495312;-0.833638;, + -0.891274;-0.244321;-0.382017;, + -0.886836;0.434833;0.156336;, + 0.396048;-0.852920;0.340107;, + 0.958459;-0.005318;0.285179;, + -0.727155;-0.559204;0.398166;, + 0.313446;0.294967;0.902633;, + 0.568943;-0.193580;-0.799269;, + 0.540259;0.790932;-0.287309;, + -0.190782;-0.966119;-0.173828;, + 0.699601;0.319552;-0.639097;, + -0.461959;-0.866725;0.188099;, + -0.593538;-0.430185;0.680187;, + -0.129662;-0.954140;0.269823;, + 0.507759;-0.548313;-0.664480;, + -0.102172;0.911919;0.397447;, + 0.280146;-0.794859;0.538254;, + -0.896153;0.443634;0.009920;, + 0.604915;0.795184;0.041942;, + -0.370304;-0.909123;-0.190710;, + -0.469045;0.851012;0.236169;, + 0.715283;-0.213463;0.665435;, + 0.725324;-0.198324;0.659221;, + 0.906461;0.267020;-0.327153;, + 0.730965;-0.293094;0.616268;, + 0.426783;0.803078;-0.415839;, + 0.656180;0.614047;-0.438605;, + 0.414340;0.787894;0.455572;, + 0.387641;0.909810;0.148256;, + 0.067928;-0.995530;0.065615;, + -0.546062;-0.385173;0.743947;, + 0.023950;-0.995082;0.096118;, + -0.517968;-0.562667;0.644294;, + -0.214003;-0.959327;0.184103;, + 0.088411;-0.867050;-0.490314;, + -0.168195;-0.803638;0.570856;, + -0.761202;-0.602561;0.239776;, + -0.362576;0.544444;0.756386;, + -0.135361;-0.825017;0.548656;, + -0.403113;-0.761478;0.507594;, + -0.205138;-0.005818;0.978716;, + 0.500952;0.279713;0.819029;, + 0.826841;-0.523263;-0.206226;, + -0.600234;-0.799045;0.035307;, + -0.970404;-0.229202;0.076040;, + 0.780352;-0.359300;-0.511814;, + -0.914460;-0.230698;0.332477;, + -0.502437;0.667098;0.550034;, + 0.719999;0.682490;-0.125735;, + -0.268806;-0.896766;-0.351502;, + 0.915472;-0.398064;-0.058788;, + -0.888214;-0.136248;0.438762;, + -0.506181;0.569758;0.647422;, + 0.756777;0.576678;0.307785;, + -0.129004;-0.984436;0.119344;, + 0.777616;-0.116615;0.617830;, + -0.770465;-0.143678;0.621080;, + -0.343908;0.401841;0.848676;, + 0.264638;0.646667;0.715394;, + 0.216767;-0.499110;0.838989;, + 0.807418;0.487228;-0.332693;, + 0.374558;0.861007;0.344055;, + 0.808068;0.254617;-0.531221;, + 0.818120;0.339082;-0.464439;, + 0.221900;0.974980;0.013185;, + -0.108706;-0.976161;0.187863;, + -0.368776;-0.455644;0.810181;, + 0.538295;-0.631424;-0.558159;, + 0.867721;0.146537;-0.474959;, + 0.452458;0.832414;0.319950;, + -0.257983;0.544602;0.798031;, + -0.597196;-0.209677;0.774204;, + -0.171970;-0.985088;-0.005321;, + 0.456380;-0.580050;-0.674729;, + 0.769932;0.170761;-0.614854;, + 0.382238;0.901984;0.200798;, + -0.276717;0.544754;0.791625;, + -0.379263;-0.183823;0.906845;, + -0.068508;-0.994742;0.076127;, + 0.314063;-0.536259;-0.783448;, + 0.579129;0.233663;-0.781032;, + 0.240758;0.970584;-0.001211;, + -0.464359;0.605477;0.646350;, + -0.699843;-0.168934;0.694032;, + -0.205561;-0.977861;-0.039144;, + 0.329202;-0.554979;-0.763953;, + 0.738986;0.202412;-0.642596;, + 0.334240;0.935996;0.110429;, + -0.470908;0.619311;0.628251;, + -0.896664;-0.131474;0.422738;, + -0.491550;-0.803875;-0.334908;, + 0.488072;-0.623641;-0.610621;, + 0.885331;0.131251;-0.446051;, + 0.509708;0.786985;0.347638;, + -0.242430;0.521770;0.817914;, + -0.613783;-0.209259;0.761236;, + -0.262272;-0.961626;-0.080548;, + 0.450906;-0.603711;-0.657432;, + 0.828994;0.160795;-0.535644;, + 0.441803;0.858053;0.261828;, + -0.339070;0.554869;0.759705;, + -0.677756;-0.206419;0.705719;, + -0.259052;-0.964613;-0.049126;, + 0.229922;-0.482476;-0.845194;, + 0.778129;0.185891;-0.599966;, + 0.358173;0.924866;0.127809;, + -0.560979;0.636505;0.529305;, + -0.921070;-0.106291;0.374610;, + -0.585179;-0.715104;-0.382351;, + 0.327893;-0.527492;-0.783734;, + 0.868350;0.160550;-0.469245;, + 0.532377;0.790350;0.303185;, + -0.480825;0.612885;0.627040;, + -0.898116;-0.162902;0.408473;, + -0.523134;-0.798786;-0.297106;, + 0.582448;-0.641920;-0.498692;, + 0.908436;0.168554;-0.382535;, + 0.589372;0.731411;0.343042;, + -0.130859;0.472769;0.871416;, + -0.448382;-0.259742;0.855271;, + -0.122373;-0.962341;0.242745;, + 0.738199;-0.672946;-0.046963;, + 0.954319;0.143966;-0.261819;, + 0.684008;0.694622;0.222786;, + 0.114891;0.475550;0.872154;, + 0.045777;-0.249705;0.967239;, + 0.271381;-0.699800;0.660782;, + 0.788837;-0.361752;0.496862;, + 0.654098;0.265568;0.708258;, + 0.497233;-0.613394;-0.613602;, + 0.827960;0.156360;-0.538548;, + 0.441440;0.854796;0.272864;, + -0.263126;0.546005;0.795389;, + -0.560849;-0.216898;0.799002;, + -0.170563;-0.985283;0.011240;, + 0.446317;-0.594873;-0.668526;, + 0.761715;0.172975;-0.624396;, + 0.374777;0.907354;0.190397;, + -0.306469;0.543138;0.781715;, + -0.462053;-0.212056;0.861127;, + -0.101970;-0.991153;0.084961;, + 0.308543;-0.543003;-0.780992;, + 0.601734;0.229221;-0.765097;, + 0.257610;0.966081;0.018033;, + -0.452795;0.600684;0.658905;, + -0.728428;-0.184026;0.659945;, + -0.306842;-0.947200;-0.093060;, + 0.335867;-0.559796;-0.757510;, + 0.736062;0.204405;-0.645315;, + 0.336864;0.934902;0.111722;, + -0.456215;0.614991;0.643159;, + -0.874861;-0.145367;0.462046;, + -0.474606;-0.826156;-0.303671;, + 0.471488;-0.618541;-0.628574;, + 0.864110;0.144078;-0.482240;, + 0.488532;0.813107;0.316535;, + -0.263346;0.532405;0.804484;, + -0.629310;-0.211268;0.747886;, + -0.275179;-0.957479;-0.086667;, + 0.439782;-0.600782;-0.667573;, + 0.813245;0.167489;-0.557296;, + 0.428662;0.870727;0.241007;, + -0.345261;0.558515;0.754225;, + -0.683079;-0.206987;0.700399;, + -0.272796;-0.960329;-0.057884;, + 0.252684;-0.497453;-0.829875;, + 0.769539;0.190134;-0.609638;, + 0.357894;0.925399;0.124696;, + -0.537976;0.628508;0.561747;, + -0.898785;-0.123848;0.420531;, + -0.560059;-0.751673;-0.348312;, + 0.333904;-0.534319;-0.776538;, + 0.850206;0.173471;-0.497050;, + 0.514423;0.813291;0.271896;, + -0.467237;0.607846;0.642038;, + -0.877223;-0.172768;0.447918;, + -0.507195;-0.819398;-0.267097;, + 0.554845;-0.638321;-0.533566;, + 0.886565;0.182189;-0.425217;, + 0.568559;0.763899;0.305283;, + -0.165833;0.490715;0.855393;, + -0.481870;-0.264147;0.835480;, + -0.153896;-0.966580;0.205035;, + 0.701497;-0.701342;-0.126576;, + 0.933336;0.163949;-0.319380;, + 0.662234;0.725654;0.186743;, + 0.068015;0.505465;0.860162;, + -0.023671;-0.259197;0.965534;, + 0.209331;-0.750697;0.626605;, + 0.782976;-0.407275;0.470186;, + 0.636095;0.307826;0.707549;, + 0.501872;-0.611244;-0.611969;, + 0.840103;0.146832;-0.522176;, + 0.462884;0.829633;0.312165;, + -0.265565;0.544402;0.795677;, + -0.559285;-0.215968;0.800349;, + -0.160805;-0.986764;0.020920;, + 0.440673;-0.592878;-0.674020;, + 0.759649;0.173641;-0.626724;, + 0.382754;0.902313;0.198317;, + -0.292472;0.536722;0.791448;, + -0.440960;-0.214732;0.871461;, + -0.091558;-0.991696;0.090310;, + 0.294817;-0.536769;-0.790545;, + 0.589764;0.232855;-0.773277;, + 0.257798;0.966021;0.018516;, + -0.447421;0.598812;0.664258;, + -0.724551;-0.183967;0.664215;, + -0.309688;-0.945740;-0.098333;, + 0.324769;-0.553847;-0.766667;, + 0.732523;0.205397;-0.649017;, + 0.341567;0.932610;0.116491;, + -0.451790;0.613142;0.648030;, + -0.878402;-0.141688;0.456437;, + -0.485264;-0.815031;-0.316611;, + 0.467816;-0.617010;-0.632809;, + 0.867241;0.140845;-0.477553;, + 0.500477;0.800802;0.328997;, + -0.247760;0.524381;0.814641;, + -0.619273;-0.212829;0.755781;, + -0.276709;-0.956627;-0.091087;, + 0.434085;-0.598441;-0.673379;, + 0.814055;0.166484;-0.556415;, + 0.438174;0.862994;0.251485;, + -0.334234;0.553031;0.763180;, + -0.676607;-0.208759;0.706132;, + -0.274057;-0.959798;-0.060661;, + 0.236650;-0.488015;-0.840142;, + 0.767921;0.190323;-0.611616;, + 0.363214;0.922428;0.131159;, + -0.537145;0.628597;0.562442;, + -0.902882;-0.118846;0.413135;, + -0.572783;-0.736091;-0.360680;, + 0.323287;-0.527601;-0.785571;, + 0.852535;0.170393;-0.494115;, + 0.524892;0.802194;0.284559;, + -0.462849;0.606173;0.646780;, + -0.880811;-0.169994;0.441898;, + -0.517099;-0.808991;-0.279539;, + 0.555697;-0.637603;-0.533538;, + 0.890633;0.178263;-0.418325;, + 0.579718;0.749722;0.319132;, + -0.146317;0.479991;0.864985;, + -0.465888;-0.265274;0.844143;, + -0.147113;-0.966458;0.210517;, + 0.709732;-0.695413;-0.112611;, + 0.938240;0.157523;-0.308047;, + 0.672570;0.712761;0.199049;, + 0.090407;0.490418;0.866785;, + 0.003757;-0.259574;0.965716;, + 0.230207;-0.738918;0.633249;, + 0.787167;-0.396002;0.472811;, + 0.646355;0.289593;0.705947;, + 0.516966;-0.608447;-0.602112;, + 0.874128;0.114718;-0.471953;, + 0.517818;0.767923;0.377039;, + -0.212404;0.516342;0.829624;, + -0.588810;-0.221694;0.777274;, + -0.185391;-0.982309;-0.026433;, + 0.400936;-0.557240;-0.727141;, + 0.742127;0.178734;-0.645989;, + 0.419212;0.878727;0.228253;, + -0.215861;0.514387;0.829946;, + -0.329958;-0.208178;0.920755;, + -0.091396;-0.995301;0.031967;, + 0.255763;-0.507343;-0.822915;, + 0.544399;0.251635;-0.800193;, + 0.270805;0.961926;0.036910;, + -0.409694;0.584477;0.700383;, + -0.665604;-0.180080;0.724253;, + -0.229438;-0.970608;-0.072654;, + 0.271222;-0.525963;-0.806102;, + 0.711132;0.211599;-0.670461;, + 0.367730;0.919170;0.141072;, + -0.416769;0.599193;0.683573;, + -0.878049;-0.128957;0.460869;, + -0.529271;-0.771744;-0.352540;, + 0.434921;-0.604440;-0.667455;, + 0.865473;0.129965;-0.483804;, + 0.547625;0.754213;0.362311;, + -0.182521;0.489258;0.852827;, + -0.578412;-0.225413;0.783982;, + -0.294771;-0.948174;-0.118642;, + 0.395442;-0.582473;-0.710176;, + 0.805338;0.164263;-0.569604;, + 0.478885;0.830388;0.284824;, + -0.280896;0.526446;0.802466;, + -0.646450;-0.219247;0.730776;, + -0.290151;-0.953341;-0.083390;, + 0.170371;-0.449244;-0.877014;, + 0.752258;0.192773;-0.630037;, + 0.391734;0.906032;0.160159;, + -0.512610;0.622446;0.591432;, + -0.904174;-0.101462;0.414939;, + -0.620865;-0.680541;-0.389089;, + 0.271016;-0.497964;-0.823761;, + 0.848604;0.160114;-0.504217;, + 0.567325;0.759364;0.318604;, + -0.427834;0.592777;0.682329;, + -0.881165;-0.159727;0.445011;, + -0.558070;-0.768267;-0.313567;, + 0.535967;-0.630109;-0.561873;, + 0.892887;0.164047;-0.419335;, + 0.623516;0.698005;0.352159;, + -0.071795;0.436064;0.897047;, + -0.409232;-0.281070;0.868060;, + -0.136787;-0.970094;0.200516;, + 0.717370;-0.686582;-0.118260;, + 0.944105;0.133893;-0.301228;, + 0.711039;0.665994;0.225558;, + 0.170183;0.433298;0.885037;, + 0.089845;-0.282505;0.955049;, + 0.288287;-0.730355;0.619251;, + 0.804020;-0.394183;0.445166;, + 0.689840;0.223648;0.688551;, + 0.361674;0.913139;-0.188064;, + -0.306548;-0.658610;0.687213;, + -0.365602;-0.684685;0.630508;, + -0.220903;-0.824258;0.521346;, + -0.581318;-0.745933;0.325044;, + -0.588806;0.000143;0.808275;, + -0.496007;-0.714259;0.493772;, + 0.593600;0.707690;-0.383162;, + -0.196206;0.085242;-0.976851;, + -0.140780;0.989203;-0.040729;, + -0.715299;-0.614274;-0.333189;, + -0.975349;0.164237;-0.147377;, + -0.212301;-0.514564;0.830754;, + -0.297653;-0.114959;0.947727;, + 0.980593;0.188926;-0.052382;, + 0.665653;0.649226;0.367983;, + 0.302101;0.824457;0.478545;, + -0.123513;0.634708;0.762817;, + 0.426128;-0.774572;-0.467389;, + 0.781451;-0.186179;-0.595543;, + -0.113738;-0.981032;0.156973;, + -0.125935;-0.756333;0.641950;, + 0.214009;0.839435;0.499548;, + -0.315118;0.517253;0.795707;, + -0.459333;-0.851040;0.254447;, + -0.557305;-0.389761;0.733143;, + 0.644141;0.420432;-0.638999;, + 0.740902;0.430944;-0.515123;, + -0.149490;0.928257;0.340575;, + -0.077287;-0.823913;-0.561422;, + 0.511461;-0.189138;-0.838233;, + -0.381149;0.923821;0.035779;, + 0.392217;0.560751;0.729194;, + -0.184282;0.976156;0.114712;, + -0.567905;0.521114;-0.637122;, + 0.473718;0.414055;-0.777271;, + -0.529914;-0.324726;-0.783418;, + 0.226517;-0.970474;0.082885;, + -0.148924;-0.632604;-0.760022;, + 0.527039;0.781296;-0.334374;, + 0.834983;0.264476;-0.482552;, + 0.675963;0.077412;-0.732859;, + 0.160126;0.190092;-0.968620;, + 0.228376;-0.127237;-0.965223;, + -0.057386;0.245516;0.967692;, + -0.657416;-0.744773;-0.114531;, + -0.274099;0.701037;-0.658344;, + 0.876642;-0.442049;-0.189978;, + -0.779526;0.329121;0.532934;, + 0.327724;-0.696016;0.638873;, + -0.578535;0.674540;0.458576;, + -0.984941;0.135767;-0.107045;, + 0.422834;0.836078;-0.349550;, + 0.828789;0.540638;-0.144288;, + -0.034244;0.095893;-0.994802;, + 0.641365;-0.305210;-0.703916;, + 0.923772;-0.052794;0.379286;, + -0.076548;0.939750;-0.333181;, + -0.119540;-0.960478;0.251382;, + 0.669596;-0.615981;-0.414980;, + 0.303030;-0.186090;0.934635;, + 0.391442;0.389355;0.833772;, + -0.190416;0.835663;0.515178;, + 0.353633;-0.752104;0.556133;, + 0.520040;-0.156982;0.839592;, + -0.509830;-0.838926;-0.190465;, + 0.146090;-0.981553;0.123336;, + -0.607672;0.793048;-0.042537;, + -0.897162;0.033159;-0.440455;, + 0.839542;-0.269781;-0.471581;, + 0.963227;0.157435;-0.217736;, + 0.259132;0.699308;-0.666198;, + -0.604433;0.762690;0.230140;, + -0.423330;0.778916;0.462689;, + 0.434554;0.075722;0.897457;, + -0.006566;0.677353;0.735628;, + -0.749936;0.407739;-0.520908;, + -0.822491;0.188949;-0.536477;, + -0.756906;-0.145054;-0.637223;, + -0.423190;-0.716621;-0.554404;, + 0.227209;-0.966292;0.121063;, + 0.317550;-0.933835;0.164662;, + 0.496370;-0.182435;0.848725;, + 0.533776;-0.178235;0.826629;, + 0.604641;-0.410889;0.682334;, + 0.097373;-0.993304;-0.062171;, + -0.544149;0.817947;0.186718;, + -0.671652;0.718204;-0.181845;, + 0.520633;-0.800173;0.297766;, + -0.610984;0.085141;-0.787051;, + -0.315955;0.940947;0.121620;, + -0.451041;-0.364729;-0.814576;, + -0.034059;-0.236375;-0.971065;, + -0.126856;0.710394;-0.692277;, + 0.329848;0.675467;0.659503;, + 0.509804;-0.823253;0.249710;, + 0.828231;-0.560342;0.007058;, + 0.898012;0.382183;0.217970;, + 0.638411;-0.335141;0.692901;, + 0.521920;-0.736948;0.429544;, + 0.653620;0.114523;0.748107;, + 0.219228;-0.910600;-0.350351;, + 0.106711;0.863012;0.493785;, + -0.701914;0.653797;-0.282606;, + -0.566975;-0.044447;-0.822535;, + -0.698404;-0.196958;-0.688069;, + -0.634338;-0.406257;-0.657701;, + -0.726870;-0.133185;-0.673737;, + -0.790864;0.239728;-0.563085;, + -0.657555;0.711316;-0.248296;, + 0.154310;0.679156;0.717590;, + -0.231918;0.882106;0.410004;, + 0.412377;-0.755835;0.508585;, + 0.140943;-0.970084;0.197668;, + -0.311225;-0.875510;-0.369624;, + -0.597394;0.775849;-0.202926;, + 0.489055;-0.692585;0.530237;, + 0.491338;-0.534968;0.687311;, + 0.489758;-0.036774;0.871083;, + 0.438815;0.143443;0.887054;, + 0.286417;0.500491;0.816991;, + -0.627373;0.683167;-0.373744;, + -0.335799;0.770037;-0.542478;, + 0.129022;0.958535;0.254096;, + -0.414688;0.073903;-0.906958;, + -0.101432;0.966761;0.234701;, + -0.755011;0.321454;-0.571512;, + 0.578072;-0.401336;0.710466;, + -0.311908;0.427644;-0.848430;, + 0.156866;-0.502085;-0.850473;, + 0.197343;0.520839;-0.830532;, + 0.891275;-0.244321;-0.382017;, + 0.886836;0.434833;0.156336;, + -0.667053;-0.649082;0.365696;, + -0.890395;-0.035250;0.453822;, + 0.773169;-0.532910;0.343826;, + -0.301252;0.328615;0.895131;, + -0.552096;-0.122315;-0.824760;, + -0.523265;0.793302;-0.311232;, + 0.178067;-0.970384;-0.163240;, + -0.685065;0.319620;-0.654621;, + 0.472466;-0.858796;0.198106;, + 0.564413;-0.431202;0.703920;, + 0.113817;-0.948975;0.294097;, + -0.499148;-0.545190;-0.673512;, + 0.108599;0.911995;0.395565;, + -0.283846;-0.779062;0.559012;, + 0.894433;0.447026;-0.012553;, + -0.593050;0.804457;0.033773;, + 0.369368;-0.910324;-0.186757;, + 0.475166;0.851493;0.221757;, + -0.703251;-0.226621;0.673855;, + -0.714900;-0.212902;0.666026;, + -0.901123;0.269970;-0.339253;, + -0.721934;-0.308194;0.619538;, + -0.406662;0.800438;-0.440369;, + -0.636644;0.614134;-0.466395;, + -0.410648;0.785543;0.462915;, + -0.378074;0.914236;0.145713;, + -0.082476;-0.992964;0.084972;, + 0.519481;-0.388496;0.761059;, + -0.037907;-0.992141;0.119241;, + 0.491463;-0.565202;0.662579;, + 0.194400;-0.959689;0.202992;, + -0.096513;-0.870901;-0.481889;, + 0.146372;-0.791374;0.593551;, + 0.771799;-0.600975;0.207740;, + 0.351827;0.537583;0.766305;, + 0.117570;-0.811190;0.572842;, + 0.382914;-0.755359;0.531799;, + 0.188469;-0.005536;0.982064;, + -0.489616;0.263036;0.831317;, + -0.823845;-0.530391;-0.199912;, + 0.593325;-0.803737;0.044415;, + 0.971456;-0.226261;0.071272;, + -0.774625;-0.362944;-0.517907;, + 0.910154;-0.232627;0.342788;, + 0.500593;0.666086;0.552935;, + -0.712383;0.688225;-0.137322;, + 0.268876;-0.898540;-0.346889;, + -0.913491;-0.404743;-0.041435;, + 0.880171;-0.136698;0.454546;, + 0.498824;0.566633;0.655822;, + -0.755600;0.570720;0.321476;, + 0.122431;-0.981567;0.146753;, + -0.765877;-0.131961;0.629300;, + 0.760728;-0.149787;0.631552;, + 0.338248;0.393374;0.854895;, + -0.264307;0.634389;0.726424;, + -0.213763;-0.497719;0.840584;, + -0.797886;0.487994;-0.353892;, + -0.371167;0.862227;0.344672;, + -0.796796;0.254304;-0.548129;, + -0.806062;0.342622;-0.482571;, + -0.211446;0.977387;0.002139;, + 0.091470;-0.973373;0.210186;, + 0.342640;-0.450430;0.824445;, + -0.533434;-0.631638;-0.562567;, + -0.857968;0.149295;-0.491531;, + -0.449701;0.833860;0.320073;, + 0.247538;0.533303;0.808896;, + 0.568264;-0.213516;0.794661;, + 0.155037;-0.987820;0.013252;, + -0.447982;-0.577196;-0.682757;, + -0.751659;0.174053;-0.636172;, + -0.374900;0.906643;0.193515;, + 0.266062;0.534893;0.801936;, + 0.351269;-0.182121;0.918391;, + 0.050535;-0.994436;0.092426;, + -0.302952;-0.528059;-0.793330;, + -0.549673;0.237349;-0.800952;, + -0.224332;0.974321;-0.019323;, + 0.457685;0.602796;0.653575;, + 0.684758;-0.171791;0.708233;, + 0.194642;-0.980191;-0.036613;, + -0.320375;-0.545709;-0.774314;, + -0.721049;0.208194;-0.660866;, + -0.322509;0.941211;0.100551;, + 0.464637;0.616931;0.635224;, + 0.890129;-0.133886;0.435598;, + 0.489652;-0.803849;-0.337738;, + -0.482310;-0.621551;-0.617294;, + -0.877595;0.134138;-0.460255;, + -0.508349;0.786638;0.350401;, + 0.231555;0.510140;0.828335;, + 0.589307;-0.209611;0.780244;, + 0.252160;-0.965191;-0.069438;, + -0.443595;-0.600833;-0.664998;, + -0.815942;0.164862;-0.554130;, + -0.437536;0.861083;0.259033;, + 0.330057;0.546220;0.769874;, + 0.657713;-0.211590;0.722941;, + 0.245100;-0.968694;-0.039466;, + -0.218196;-0.468925;-0.855862;, + -0.762091;0.193297;-0.617943;, + -0.349430;0.929707;0.116373;, + 0.557674;0.637189;0.531969;, + 0.917107;-0.107418;0.383895;, + 0.584169;-0.712581;-0.388554;, + -0.320194;-0.517249;-0.793681;, + -0.861337;0.165443;-0.480341;, + -0.529397;0.791179;0.306226;, + 0.475036;0.610817;0.633438;, + 0.891719;-0.164077;0.421801;, + 0.519657;-0.799974;-0.299996;, + -0.579460;-0.642332;-0.501632;, + -0.902703;0.169362;-0.395530;, + -0.586870;0.729783;0.350716;, + 0.120529;0.460012;0.879694;, + 0.424021;-0.257028;0.868414;, + 0.109887;-0.957719;0.265895;, + -0.737915;-0.674242;-0.029655;, + -0.953246;0.142139;-0.266682;, + -0.681447;0.696126;0.225917;, + -0.117801;0.461501;0.879284;, + -0.057760;-0.247480;0.967170;, + -0.276840;-0.682651;0.676274;, + -0.783249;-0.356084;0.509632;, + -0.649761;0.259288;0.714549;, + -0.490701;-0.611734;-0.620479;, + -0.814477;0.160417;-0.557578;, + -0.437465;0.857775;0.269901;, + 0.252546;0.535085;0.806166;, + 0.530851;-0.218848;0.818720;, + 0.153105;-0.987769;0.029507;, + -0.438220;-0.592052;-0.676341;, + -0.742663;0.176560;-0.645971;, + -0.366910;0.912208;0.182358;, + 0.295401;0.533999;0.792201;, + 0.430440;-0.211071;0.877593;, + 0.080883;-0.991491;0.101995;, + -0.297424;-0.534529;-0.791086;, + -0.573038;0.233183;-0.785654;, + -0.241843;0.970315;0.000870;, + 0.445511;0.597421;0.666789;, + 0.711169;-0.187864;0.677455;, + 0.294543;-0.951626;-0.087479;, + -0.326742;-0.550893;-0.767956;, + -0.717174;0.210252;-0.664422;, + -0.325128;0.940226;0.101326;, + 0.449368;0.612043;0.650747;, + 0.866118;-0.148627;0.477232;, + 0.471883;-0.827537;-0.304152;, + -0.465089;-0.615834;-0.635956;, + -0.854249;0.147700;-0.498441;, + -0.486239;0.814255;0.317113;, + 0.252472;0.521534;0.815021;, + 0.604359;-0.212396;0.767879;, + 0.264549;-0.961449;-0.075028;, + -0.432019;-0.597419;-0.675611;, + -0.798667;0.171837;-0.576717;, + -0.423554;0.874399;0.236705;, + 0.335949;0.550139;0.764517;, + 0.662056;-0.212295;0.718758;, + 0.258679;-0.964803;-0.047336;, + -0.240978;-0.484831;-0.840755;, + -0.752439;0.197302;-0.628417;, + -0.348656;0.930401;0.113105;, + 0.533739;0.628202;0.566114;, + 0.892616;-0.126233;0.432784;, + 0.558454;-0.751040;-0.352235;, + -0.325458;-0.524380;-0.786831;, + -0.841062;0.178988;-0.510468;, + -0.510649;0.815434;0.272590;, + 0.460786;0.605148;0.649209;, + 0.868674;-0.174616;0.463589;, + 0.503088;-0.821745;-0.267651;, + -0.550996;-0.638131;-0.537766;, + -0.878623;0.183950;-0.440663;, + -0.565503;0.764222;0.310116;, + 0.154787;0.478816;0.864162;, + 0.455817;-0.261788;0.850704;, + 0.139459;-0.963610;0.228052;, + -0.702169;-0.703184;-0.111764;, + -0.930325;0.163693;-0.328175;, + -0.658831;0.728629;0.187194;, + -0.072427;0.492303;0.867406;, + 0.007565;-0.256091;0.966623;, + -0.219306;-0.733148;0.643738;, + -0.780241;-0.399104;0.481601;, + -0.633977;0.303269;0.711408;, + -0.495277;-0.609732;-0.618812;, + -0.827977;0.150869;-0.540085;, + -0.460415;0.831003;0.312174;, + 0.254891;0.533546;0.806448;, + 0.529349;-0.217483;0.820055;, + 0.143045;-0.988931;0.039412;, + -0.432483;-0.589889;-0.681901;, + -0.740510;0.177313;-0.648232;, + -0.375236;0.907074;0.190826;, + 0.281251;0.527055;0.801942;, + 0.409295;-0.213533;0.887063;, + 0.070334;-0.991770;0.106986;, + -0.283571;-0.527836;-0.800610;, + -0.560679;0.236847;-0.793437;, + -0.241981;0.970280;0.001457;, + 0.440073;0.595333;0.672246;, + 0.707551;-0.187802;0.681250;, + 0.297766;-0.950032;-0.093671;, + -0.315564;-0.544433;-0.777182;, + -0.713702;0.211367;-0.667797;, + -0.330019;0.937937;0.106587;, + 0.444854;0.609993;0.655754;, + 0.870079;-0.144889;0.471136;, + 0.482938;-0.815853;-0.318049;, + -0.461342;-0.614098;-0.640349;, + -0.857754;0.144449;-0.493348;, + -0.498612;0.801373;0.330434;, + 0.236801;0.512915;0.825133;, + 0.594213;-0.213844;0.775359;, + 0.266370;-0.960543;-0.080021;, + -0.426219;-0.594861;-0.681526;, + -0.799637;0.170933;-0.575641;, + -0.433484;0.866383;0.247934;, + 0.324837;0.544170;0.773537;, + 0.655674;-0.214147;0.724039;, + 0.260147;-0.964238;-0.050689;, + -0.224869;-0.474782;-0.850891;, + -0.750921;0.197735;-0.630094;, + -0.354271;0.927410;0.120013;, + 0.532960;0.628250;0.566794;, + 0.897185;-0.121051;0.424742;, + 0.571470;-0.734766;-0.365432;, + -0.314900;-0.517199;-0.795828;, + -0.843867;0.175890;-0.506904;, + -0.521492;0.803821;0.286214;, + 0.456355;0.603310;0.654031;, + 0.872676;-0.171770;0.457090;, + 0.513321;-0.810862;-0.281077;, + -0.551857;-0.637341;-0.537819;, + -0.883114;0.179896;-0.433297;, + -0.576959;0.749316;0.325029;, + 0.135489;0.467543;0.873525;, + 0.440209;-0.262810;0.858573;, + 0.133199;-0.963203;0.233450;, + -0.710203;-0.697232;-0.097362;, + -0.935703;0.156918;-0.315970;, + -0.669545;0.715214;0.200446;, + -0.094199;0.476771;0.873966;, + -0.018339;-0.256626;0.966337;, + -0.238806;-0.721445;0.649991;, + -0.783588;-0.388614;0.484736;, + -0.643422;0.284541;0.710665;, + -0.510465;-0.607468;-0.608611;, + -0.865352;0.117258;-0.487255;, + -0.517106;0.766062;0.381772;, + 0.201577;0.503110;0.840385;, + 0.559705;-0.225972;0.797288;, + 0.169147;-0.985551;-0.008917;, + -0.391192;-0.551987;-0.736396;, + -0.722016;0.183057;-0.667221;, + -0.413059;0.883017;0.222853;, + 0.204883;0.502219;0.840119;, + 0.302341;-0.206622;0.930536;, + 0.074487;-0.996148;0.046270;, + -0.244152;-0.497096;-0.832638;, + -0.514194;0.255863;-0.818620;, + -0.255335;0.966621;0.021159;, + 0.401612;0.579399;0.709228;, + 0.649553;-0.183473;0.737847;, + 0.220057;-0.972841;-0.071803;, + -0.261639;-0.514291;-0.816731;, + -0.692069;0.218095;-0.688095;, + -0.357168;0.924491;0.133220;, + 0.408987;0.594527;0.692291;, + 0.870070;-0.132357;0.474826;, + 0.528108;-0.770628;-0.356699;, + -0.427611;-0.599957;-0.676166;, + -0.856204;0.133913;-0.498980;, + -0.546962;0.752871;0.366086;, + 0.171512;0.475490;0.862840;, + 0.552739;-0.226309;0.802037;, + 0.285690;-0.951981;-0.110058;, + -0.386791;-0.577398;-0.719030;, + -0.790608;0.169376;-0.588431;, + -0.475563;0.832664;0.283745;, + 0.271095;0.515384;0.812949;, + 0.625528;-0.224964;0.747065;, + 0.277394;-0.957771;-0.075676;, + -0.158619;-0.433804;-0.886935;, + -0.735093;0.201108;-0.647452;, + -0.383943;0.910904;0.151136;, + 0.507899;0.621019;0.596970;, + 0.898964;-0.103555;0.425605;, + 0.620222;-0.677171;-0.395935;, + -0.262650;-0.485562;-0.833813;, + -0.840648;0.165742;-0.515597;, + -0.564993;0.759241;0.323012;, + 0.420631;0.588517;0.690447;, + 0.873310;-0.161587;0.459587;, + 0.555273;-0.768494;-0.317946;, + -0.531432;-0.628929;-0.567476;, + -0.885679;0.165648;-0.433744;, + -0.621552;0.695340;0.360798;, + 0.062071;0.421776;0.904573;, + 0.384608;-0.278152;0.880175;, + 0.124293;-0.966893;0.222865;, + -0.717453;-0.688923;-0.103178;, + -0.942100;0.132658;-0.307975;, + -0.709039;0.666859;0.229265;, + -0.171508;0.418312;0.891964;, + -0.099615;-0.279056;0.955094;, + -0.293476;-0.713393;0.636351;, + -0.798889;-0.388529;0.459153;, + -0.684430;0.217897;0.695756;, + -0.341059;0.917128;-0.206289;, + 0.285530;-0.650577;0.703720;, + 0.340151;-0.678735;0.650858;, + 0.201228;-0.818516;0.538087;, + 0.561306;-0.750896;0.347982;, + 0.563755;-0.000870;0.825942;, + 0.476551;-0.712046;0.515644;, + -0.572616;0.710735;-0.408614;, + 0.160884;0.118423;-0.979843;, + 0.092128;0.995149;-0.034495;, + 0.715299;-0.614274;-0.333189;, + 0.975349;0.164237;-0.147377;, + 0.212302;-0.514565;0.830753;, + 0.364121;-0.117457;0.923915;, + -0.972391;0.228560;0.047083;, + -0.721943;0.609310;0.327933;, + -0.355783;0.818541;0.451009;, + 0.166307;0.647301;0.743870;, + -0.492298;-0.784288;-0.377538;, + -0.924095;-0.209976;-0.319310;, + 0.079861;-0.979451;0.185195;, + 0.091672;-0.754828;0.649485;, + -0.169599;0.852875;0.493802;, + 0.305489;0.522454;0.796064;, + 0.451821;-0.854320;0.256893;, + 0.549353;-0.390720;0.738613;, + -0.644141;0.420432;-0.638999;, + -0.740902;0.430944;-0.515123;, + 0.149490;0.928257;0.340575;, + 0.077287;-0.823913;-0.561422;, + -0.511461;-0.189138;-0.838233;, + 0.343698;0.922858;0.173795;, + -0.260653;0.953967;0.148347;, + 0.783381;0.503370;0.364599;, + -0.066996;0.879109;0.471889;, + -0.710934;0.444973;0.544584;, + 0.289636;0.949061;0.124075;, + -0.362112;0.926712;0.100395;, + -0.000001;0.818760;0.574136;, + -0.000000;0.868934;-0.494927;, + -0.000000;0.630324;-0.776332;, + 0.022686;-0.036383;0.999080;, + -0.000000;0.298174;-0.954511;, + -0.000000;0.998500;0.054759;, + -0.000000;-0.444151;0.895952;, + -0.000000;-0.029730;-0.999558;, + -0.142878;-0.121955;-0.982198;, + -0.808123;-0.461550;-0.365936;, + -0.793812;0.600245;-0.097818;, + -0.540286;0.724558;-0.427911;, + -0.496164;0.335976;-0.800588;, + -0.654263;-0.049613;-0.754638;, + -0.660157;-0.104107;0.743878;, + -0.861728;0.431543;-0.266824;, + -0.338650;-0.330283;0.881039;, + -0.231714;-0.275342;0.933003;, + -0.899678;-0.251384;-0.356911;, + -0.563708;-0.395781;-0.724976;, + -0.944986;-0.217661;0.244183;, + -0.232970;0.970399;0.063643;, + -0.886311;0.419497;-0.196151;, + -0.284112;0.944212;0.166567;, + -0.394637;-0.137254;0.908528;, + 0.012819;0.940525;0.339483;, + 0.382016;0.040071;0.923286;, + -0.733140;-0.437535;0.520643;, + -0.879018;0.070016;-0.471619;, + -0.965289;-0.090055;-0.245168;, + -0.404283;-0.450662;0.795902;, + -0.432713;-0.354931;0.828724;, + -0.302341;0.947980;-0.099615;, + -0.235609;0.971832;-0.005539;, + -0.978433;-0.005143;0.206502;, + -0.422789;0.519154;-0.742784;, + -0.929825;-0.231328;0.286203;, + -0.699443;-0.209423;-0.683316;, + -0.534104;0.546724;-0.644846;, + -0.806852;-0.393759;-0.440389;, + -0.691836;-0.542995;-0.475940;, + -0.877724;-0.460197;-0.133489;, + -0.178300;-0.323577;-0.929251;, + -0.937849;0.041613;0.344540;, + 0.109013;0.571900;0.813048;, + -0.863890;0.503678;-0.001488;, + -0.683696;0.235194;-0.690828;, + -0.778100;0.232231;-0.583635;, + -0.438702;-0.571900;-0.693160;, + -0.650020;0.481538;-0.587874;, + 0.244916;-0.017761;-0.969382;, + -0.903353;-0.418768;0.092664;, + -0.958406;0.281953;-0.044275;, + -0.880526;-0.190072;0.434220;, + -0.935327;-0.048151;-0.350493;, + -0.760323;0.281570;-0.585344;, + -0.722182;-0.107325;-0.683326;, + -0.967430;-0.242896;0.071282;, + -0.927251;-0.170149;-0.333550;, + -0.812213;-0.330990;0.480369;, + -0.587234;0.666265;-0.459617;, + 0.466081;0.838695;0.281709;, + -0.994998;-0.099822;0.003920;, + -0.742055;0.487282;0.460338;, + -0.638869;-0.759326;-0.123572;, + -0.715743;0.327208;0.616966;, + 0.371066;-0.555663;-0.744008;, + -0.559606;-0.645175;-0.520183;, + -0.649884;-0.689957;-0.318763;, + 0.681463;-0.724191;0.105620;, + -0.880620;-0.412930;0.232375;, + 0.709052;-0.704833;0.021360;, + -0.701635;0.645253;-0.302255;, + 0.427690;0.903455;0.029168;, + -0.710107;0.193070;-0.677105;, + -0.778125;0.252214;0.575248;, + 0.148716;0.940575;0.305291;, + 0.238521;-0.062437;-0.969128;, + -0.963144;0.085488;-0.255042;, + 0.369513;0.922029;-0.115428;, + -0.958565;-0.067036;-0.276873;, + 0.270983;-0.447194;-0.852400;, + -0.772474;0.623053;0.122835;, + 0.815356;0.157407;-0.557151;, + -0.138796;-0.893977;-0.426076;, + 0.364772;0.804729;-0.468352;, + -0.981550;-0.062615;-0.180661;, + 0.260027;-0.887566;-0.380279;, + -0.491771;0.675224;-0.549758;, + 0.216661;-0.945949;-0.241328;, + 0.945124;0.201537;-0.257146;, + 0.329095;0.723521;-0.606806;, + 0.194660;-0.960634;0.198216;, + -0.996307;-0.033233;-0.079173;, + -0.909493;0.374402;-0.180680;, + 0.854421;0.045584;-0.517577;, + 0.133919;-0.936841;0.323101;, + 0.090562;0.392235;-0.915396;, + -0.081213;-0.839344;0.537500;, + -0.974141;-0.162751;0.156724;, + -0.567495;0.823354;0.006191;, + 0.012874;0.004539;-0.999907;, + -0.920422;-0.390245;0.023083;, + 0.556206;0.718401;-0.417774;, + -0.948091;-0.001386;0.317996;, + -0.050023;-0.977498;-0.204928;, + -0.311902;0.571486;-0.759026;, + -0.196380;-0.929366;-0.312591;, + -0.949563;-0.144224;0.278441;, + -0.792912;0.574314;-0.203603;, + 0.639171;-0.463937;-0.613370;, + -0.225631;-0.823775;0.520082;, + 0.170996;0.152764;-0.973357;, + -0.879432;-0.156838;0.449446;, + 0.524143;-0.666593;0.530026;, + -0.269195;0.577034;-0.771081;, + 0.852228;-0.478675;-0.211134;, + -0.343783;-0.770945;0.536151;, + -0.679363;0.590395;0.435775;, + -0.069213;0.427125;-0.901540;, + -0.757904;-0.558344;-0.337392;, + 0.136274;0.884818;0.445562;, + 0.102555;-0.767205;-0.633151;, + -0.844716;-0.397357;0.358555;, + -0.146612;0.912426;-0.382077;, + 0.511756;-0.836540;-0.195723;, + -0.619780;-0.487134;0.615283;, + -0.387513;0.049103;-0.920555;, + -0.707902;-0.012374;0.706203;, + 0.139613;-0.971369;0.192223;, + -0.431272;0.675463;-0.598125;, + 0.565995;-0.635897;-0.524676;, + -0.798576;-0.307164;0.517617;, + 0.372732;0.864234;-0.337891;, + 0.014166;0.945681;-0.324786;, + 0.287479;0.796616;-0.531751;, + 0.136032;0.650716;-0.747037;, + -0.122359;-0.207776;0.970493;, + -0.744782;-0.430097;-0.510212;, + 0.065371;-0.737389;0.672298;, + 0.825383;-0.420119;-0.377152;, + 0.793812;0.600245;-0.097818;, + 0.540286;0.724558;-0.427911;, + 0.496164;0.335976;-0.800588;, + 0.654263;-0.049613;-0.754638;, + 0.690046;-0.132524;0.711529;, + 0.945515;0.306078;-0.110984;, + 0.329239;-0.308298;0.892499;, + 0.231714;-0.275342;0.933003;, + 0.899678;-0.251384;-0.356911;, + 0.563708;-0.395781;-0.724976;, + 0.930868;-0.256053;0.260617;, + 0.232970;0.970399;0.063643;, + 0.886230;0.418543;-0.198540;, + 0.284111;0.944212;0.166568;, + 0.394636;-0.137254;0.908528;, + -0.012819;0.940525;0.339483;, + -0.382017;0.040070;0.923286;, + 0.732571;-0.437022;0.521873;, + 0.879018;0.070016;-0.471619;, + 0.965023;-0.089095;-0.246563;, + 0.404283;-0.450662;0.795902;, + 0.432713;-0.354931;0.828724;, + 0.302341;0.947980;-0.099615;, + 0.235609;0.971832;-0.005539;, + 0.993793;-0.011471;0.110653;, + 0.629863;0.520365;-0.576622;, + 0.930521;-0.221376;0.291758;, + 0.490285;-0.201883;-0.847858;, + 0.553016;0.656553;-0.512944;, + 0.836668;-0.377812;-0.396542;, + 0.642185;-0.647026;-0.411043;, + 0.872770;-0.467932;-0.138969;, + 0.366430;-0.311048;-0.876914;, + 0.940115;0.027121;0.339777;, + -0.109013;0.571900;0.813048;, + 0.863890;0.503678;-0.001488;, + 0.683696;0.235194;-0.690828;, + 0.778100;0.232231;-0.583635;, + 0.438702;-0.571900;-0.693160;, + 0.650020;0.481538;-0.587874;, + -0.244916;-0.017761;-0.969382;, + 0.903353;-0.418768;0.092664;, + 0.958406;0.281953;-0.044275;, + 0.880526;-0.190072;0.434220;, + 0.935327;-0.048151;-0.350493;, + 0.760323;0.281570;-0.585344;, + 0.722182;-0.107325;-0.683326;, + 0.967430;-0.242896;0.071282;, + 0.932085;0.115972;-0.343175;, + 0.812213;-0.330991;0.480370;, + 0.587234;0.666265;-0.459616;, + -0.466081;0.838695;0.281709;, + 0.994998;-0.099822;0.003920;, + 0.742055;0.487282;0.460338;, + 0.638869;-0.759326;-0.123572;, + 0.715743;0.327208;0.616966;, + -0.371067;-0.555662;-0.744008;, + 0.559606;-0.645176;-0.520182;, + 0.649884;-0.689957;-0.318763;, + -0.681463;-0.724191;0.105620;, + 0.880620;-0.412930;0.232375;, + -0.709052;-0.704833;0.021360;, + 0.701635;0.645253;-0.302255;, + -0.427690;0.903455;0.029168;, + 0.710107;0.193070;-0.677105;, + 0.778125;0.252214;0.575248;, + -0.148717;0.940575;0.305291;, + -0.238521;-0.062437;-0.969128;, + 0.963144;0.085488;-0.255042;, + -0.369513;0.922029;-0.115427;, + 0.958565;-0.067035;-0.276873;, + -0.270983;-0.447194;-0.852400;, + 0.772474;0.623053;0.122835;, + -0.815356;0.157406;-0.557151;, + 0.138796;-0.893977;-0.426076;, + -0.364772;0.804729;-0.468351;, + 0.981550;-0.062615;-0.180662;, + -0.260027;-0.887566;-0.380279;, + 0.491771;0.675224;-0.549757;, + -0.216662;-0.945949;-0.241327;, + -0.945124;0.201537;-0.257145;, + -0.329095;0.723521;-0.606806;, + -0.194660;-0.960634;0.198216;, + 0.996307;-0.033233;-0.079173;, + 0.909493;0.374402;-0.180680;, + -0.854421;0.045584;-0.517577;, + -0.133919;-0.936841;0.323101;, + -0.090562;0.392236;-0.915396;, + 0.081214;-0.839343;0.537501;, + 0.974141;-0.162751;0.156724;, + 0.567495;0.823354;0.006191;, + -0.012874;0.004539;-0.999907;, + 0.920422;-0.390245;0.023083;, + -0.556206;0.718401;-0.417774;, + 0.948091;-0.001386;0.317996;, + 0.050023;-0.977498;-0.204928;, + 0.311902;0.571486;-0.759026;, + 0.196380;-0.929366;-0.312591;, + 0.949563;-0.144224;0.278441;, + 0.792912;0.574314;-0.203603;, + -0.639171;-0.463937;-0.613370;, + 0.225631;-0.823775;0.520082;, + -0.170996;0.152764;-0.973357;, + 0.879431;-0.156838;0.449446;, + -0.524143;-0.666593;0.530026;, + 0.269195;0.577035;-0.771081;, + -0.852228;-0.478675;-0.211134;, + 0.343783;-0.770945;0.536151;, + 0.679363;0.590395;0.435775;, + 0.069213;0.427125;-0.901540;, + 0.757904;-0.558344;-0.337392;, + -0.136274;0.884818;0.445562;, + -0.102555;-0.767205;-0.633151;, + 0.844716;-0.397357;0.358555;, + 0.146612;0.912426;-0.382077;, + -0.511756;-0.836540;-0.195723;, + 0.619780;-0.487134;0.615283;, + 0.387513;0.049103;-0.920555;, + 0.707902;-0.012374;0.706203;, + -0.139613;-0.971369;0.192223;, + 0.431272;0.675463;-0.598125;, + -0.565995;-0.635897;-0.524676;, + 0.798576;-0.307164;0.517617;, + -0.372732;0.864234;-0.337891;, + -0.014166;0.945682;-0.324786;, + -0.287480;0.796615;-0.531751;, + -0.136031;0.650716;-0.747037;, + 0.063281;-0.182379;0.981190;, + 0.744782;-0.430097;-0.510212;, + -0.065371;-0.737389;0.672297;, + 0.242215;-0.246754;0.938320;, + 0.635245;-0.260985;0.726877;, + 0.443696;-0.614785;0.652053;, + -0.265295;-0.652176;0.710130;, + -0.648919;-0.348867;0.676163;, + -0.397813;-0.198937;0.895639;, + 0.049073;-0.204317;0.977674;, + -0.039297;-0.189054;0.981180;, + 0.042148;-0.245267;0.968539;, + 0.122612;-0.131708;0.983676;, + -0.082911;-0.112202;0.990220;, + -0.065750;-0.212323;0.974985;, + -0.107811;-0.124346;0.986365;, + 0.072040;-0.126121;0.989396;, + 0.286232;0.533920;0.795614;, + 0.681710;0.448230;0.578240;, + 0.442638;0.535858;0.718977;, + -0.272537;0.592573;0.758011;, + -0.678219;0.463836;0.569978;, + -0.469139;0.498329;0.729093;, + -0.486813;0.401144;0.775949;, + 0.270328;0.467343;0.841733;, + 0.481839;0.061419;0.874105;, + -0.260992;0.019086;0.965152;, + -0.066960;-0.234819;0.969730;, + -0.176247;-0.368579;0.912736;, + -0.079517;-0.598520;0.797152;, + -0.104641;-0.637894;0.762982;, + 0.096455;-0.656739;0.747924;, + 0.084066;-0.581895;0.808907;, + 0.160432;-0.493238;0.854973;, + 0.092826;-0.336818;0.936983;, + 0.092734;0.032753;0.995152;, + 0.229366;-0.570134;0.788884;, + -0.129323;-0.659103;0.740850;, + -0.183671;-0.023684;0.982702;, + -0.067661;0.044691;0.996707;, + 0.019304;0.109444;0.993806;, + 0.226330;-0.455250;0.861117;, + -0.140511;-0.530214;0.836140;, + 0.173978;0.048446;0.983557;, + 0.259238;-0.273146;0.926384;, + 0.073201;-0.495418;0.865565;, + -0.058649;-0.557668;0.827990;, + -0.219771;-0.310915;0.924680;, + -0.239988;-0.091534;0.966451;, + -0.291412;-0.211959;0.932820;, + -0.286618;-0.466882;0.836583;, + -0.190235;-0.605085;0.773099;, + 0.172409;-0.697401;0.695634;, + 0.280972;-0.565349;0.775523;, + 0.289547;-0.289019;0.912486;, + 0.186923;-0.086989;0.978516;, + -0.151991;-0.014575;0.988274;, + -0.131683;0.178611;0.975068;, + -0.206562;0.358665;0.910325;, + 0.105053;0.413601;0.904377;, + 0.222869;0.170993;0.959735;, + 0.108320;0.139524;0.984276;, + 0.003378;0.187304;0.982296;, + -0.090953;-0.194377;0.976701;, + 0.077236;-0.374250;0.924106;, + 0.038429;0.134035;0.990231;, + -0.111070;0.170840;0.979018;, + -0.204097;-0.632222;0.747422;, + -0.161637;-0.628760;0.760614;, + -0.175808;-0.446894;0.877142;, + -0.281966;-0.632869;0.721091;, + 0.179888;-0.708343;0.682562;, + 0.214505;-0.445287;0.869314;, + 0.152468;-0.594574;0.789453;, + 0.193876;-0.662157;0.723851;, + 0.123846;-0.611873;0.781200;, + -0.079249;-0.616369;0.783460;, + 0.049874;-0.978437;-0.200432;, + -0.035951;-0.982834;-0.180953;, + 0.077777;-0.993666;-0.081114;, + 0.403086;-0.867962;-0.290108;, + 0.558443;-0.699105;0.446535;, + -0.488240;-0.590800;0.642322;, + -0.607999;-0.786791;-0.106285;, + -0.091466;-0.994758;-0.045715;, + 0.256995;0.268178;-0.928458;, + -0.166142;0.251406;-0.953516;, + -0.095345;0.037239;0.994747;, + -0.370667;-0.065770;0.926434;, + 0.280533;-0.103181;0.954282;, + 0.207488;0.068228;0.975855;, + 0.038993;0.114275;-0.992684;, + -0.175719;0.233559;-0.956333;, + 0.165697;0.233366;-0.958167;, + 0.053631;0.218456;-0.974372;, + -0.010918;-0.937228;0.348545;, + 0.014300;-0.847026;0.531360;, + 0.004816;-0.999834;-0.017554;, + 0.002019;-0.991929;-0.126778;, + -0.393237;-0.075695;0.916316;, + -0.593252;-0.198602;0.780134;, + -0.801728;-0.276819;0.529721;, + -0.745782;-0.452954;0.488509;, + -0.649090;-0.376567;0.660969;, + -0.458591;-0.157315;0.874612;, + -0.968072;-0.167164;0.186798;, + -0.934333;-0.238125;0.265177;, + -0.890013;-0.434949;0.136735;, + -0.707919;-0.624087;-0.330705;, + -0.639626;-0.282386;-0.714938;, + -0.856324;-0.247040;-0.453521;, + -0.832452;-0.027354;0.553421;, + -0.841263;0.012869;0.540474;, + -0.853170;-0.076223;0.516034;, + -0.834930;-0.138418;0.532666;, + -0.827207;-0.174679;0.534056;, + -0.881766;-0.204181;0.425205;, + -0.920811;-0.172908;0.349584;, + -0.930713;-0.092278;0.353918;, + 0.122342;-0.917267;-0.379018;, + 0.795254;-0.584691;0.160333;, + 0.561923;-0.336734;0.755548;, + -0.150071;-0.273204;0.950178;, + -0.980461;-0.107800;0.164548;, + -0.960272;-0.212083;0.181378;, + -0.960078;-0.207732;0.187344;, + -0.932337;-0.361278;-0.015029;, + -0.945731;0.117071;0.303128;, + -0.334038;-0.502642;0.797352;, + -0.350540;-0.465852;0.812468;, + -0.651677;-0.366116;0.664286;, + -0.967035;-0.000199;0.254642;, + -0.984181;0.095585;0.149171;, + -0.626720;0.119837;0.769975;, + -0.469079;0.821207;0.324936;, + 0.328196;0.910764;-0.250592;, + -0.727588;-0.072780;0.682143;, + -0.689076;-0.199468;0.696697;, + -0.759279;0.153427;0.632421;, + -0.823955;0.147553;0.547108;, + -0.741015;0.256716;0.620479;, + -0.905729;0.033236;0.422553;, + -0.846614;0.094112;0.523821;, + -0.711348;-0.027696;0.702294;, + -0.628541;-0.139705;0.765127;, + -0.517895;-0.349245;0.780905;, + -0.389382;0.113081;0.914108;, + -0.398643;0.133025;0.907407;, + -0.438066;0.181809;0.880366;, + -0.630900;0.151210;0.760987;, + -0.683144;0.666444;0.298609;, + -0.765711;0.612011;0.197811;, + -0.885977;0.311352;-0.343665;, + -0.882389;0.457062;-0.111735;, + -0.312289;-0.020978;0.949755;, + -0.282556;0.149017;0.947605;, + -0.841467;-0.090092;0.532745;, + -0.788033;-0.596961;0.150471;, + -0.281499;-0.319000;0.904985;, + -0.196716;-0.369433;0.908197;, + -0.161057;0.188926;0.968694;, + -0.117921;0.367554;0.922496;, + -0.165544;0.271340;0.948140;, + -0.448479;-0.324300;0.832884;, + -0.373171;-0.182007;0.909735;, + -0.585369;-0.257475;0.768797;, + -0.646693;-0.180851;0.741000;, + -0.433896;-0.034239;0.900312;, + -0.544015;0.013208;0.838971;, + -0.625281;0.038322;0.779458;, + -0.369810;0.339166;0.864990;, + -0.204468;0.130905;0.970081;, + -0.120885;-0.263543;0.957043;, + -0.337644;-0.437144;0.833607;, + -0.578208;-0.404603;0.708500;, + -0.370647;-0.182064;0.910754;, + -0.290198;-0.101172;0.951603;, + -0.376940;-0.512489;0.771538;, + -0.368633;-0.522608;0.768759;, + -0.486995;-0.560041;0.670216;, + -0.278178;-0.381573;0.881487;, + -0.075087;-0.187485;0.979393;, + -0.067375;0.165266;0.983945;, + -0.074430;0.262323;0.962105;, + 0.123594;0.167946;0.978018;, + 0.073851;0.127234;0.989120;, + -0.922972;-0.305031;0.234690;, + -0.940045;-0.272592;0.204959;, + -0.942479;-0.228737;0.243746;, + -0.916339;-0.265300;0.299899;, + -0.855199;-0.298439;0.423756;, + -0.762216;-0.394376;0.513317;, + -0.591911;-0.483389;0.644962;, + -0.696085;-0.423324;0.579881;, + -0.793967;-0.433457;0.426300;, + -0.881668;-0.367645;0.295802;, + -0.919076;-0.289884;0.266959;, + -0.896238;-0.324230;0.302709;, + -0.875589;-0.290272;0.386116;, + -0.837502;-0.227848;0.496665;, + -0.720126;0.080544;0.689153;, + -0.681826;0.051070;0.729729;, + -0.541528;0.261668;0.798923;, + -0.412827;0.304371;0.858448;, + -0.544132;0.538485;0.643393;, + -0.766691;0.438289;0.469135;, + -0.727958;0.390427;0.563599;, + -0.713113;0.317666;0.624947;, + -0.568038;-0.171249;0.804989;, + -0.614593;-0.512301;0.599852;, + -0.324992;-0.273417;0.905330;, + -0.325078;-0.097406;0.940657;, + -0.427217;0.076319;0.900922;, + -0.776082;0.381416;0.502213;, + -0.672565;0.634444;0.380968;, + -0.608698;0.697609;0.377927;, + -0.527897;0.632893;0.566367;, + -0.603113;0.411655;0.683224;, + -0.313344;0.022068;0.949383;, + -0.231524;-0.066876;0.970528;, + -0.168915;0.015046;0.985516;, + -0.221507;-0.014091;0.975057;, + -0.641279;-0.037093;-0.766410;, + -0.703969;-0.213682;-0.677324;, + -0.536901;-0.391985;-0.747051;, + -0.249177;0.220454;0.943033;, + -0.581291;0.278155;0.764677;, + -0.999289;-0.036353;-0.009963;, + -0.980048;-0.042446;-0.194177;, + -0.915136;0.144087;0.376517;, + -0.891750;0.158913;0.423707;, + -0.938708;0.033166;0.343115;, + -0.828350;0.374825;0.416345;, + -0.780750;0.319185;0.537169;, + -0.755930;0.332141;0.564138;, + -0.617201;0.537677;0.574427;, + -0.677696;0.597263;0.428958;, + -0.719767;-0.501742;0.479782;, + -0.506828;-0.552613;0.661622;, + -0.280970;-0.686116;0.671044;, + -0.292440;-0.656510;0.695323;, + -0.545799;-0.705691;0.451778;, + -0.967562;-0.216680;0.129901;, + -0.902540;-0.358906;0.237926;, + -0.767894;-0.587008;-0.256438;, + -0.649296;-0.476465;-0.592786;, + -0.838696;-0.334311;-0.429913;, + -0.596950;0.129505;0.791757;, + -0.784941;0.297168;0.543653;, + -0.720007;0.579195;0.382260;, + -0.583842;0.689444;0.428713;, + -0.529134;0.371967;0.762664;, + -0.395432;0.106411;0.912310;, + -0.447528;0.159246;0.879977;, + -0.407621;0.029059;0.912689;, + -0.490926;-0.004529;0.871189;, + -0.502973;0.024472;0.863955;, + -0.333013;-0.145713;0.931595;, + -0.207654;-0.252851;0.944958;, + -0.240287;-0.513231;0.823927;, + -0.450979;-0.500707;0.738857;, + -0.471005;-0.228916;0.851911;, + -0.842645;0.074691;0.533264;, + -0.816604;0.149701;0.557447;, + -0.737941;-0.003814;0.674855;, + -0.624475;-0.079418;0.776996;, + -0.702800;-0.238155;0.670339;, + -0.742410;-0.287823;0.604968;, + -0.834300;-0.079963;0.545482;, + -0.604495;0.234318;0.761367;, + -0.597482;0.269303;0.755308;, + -0.733246;0.420582;0.534286;, + -0.770729;0.354878;0.529187;, + -0.633754;0.199721;0.747307;, + -0.297362;-0.358005;0.885104;, + -0.394508;-0.419178;0.817712;, + -0.387859;-0.471158;0.792196;, + -0.360382;-0.488667;0.794563;, + -0.242655;-0.150104;0.958430;, + -0.204607;0.076638;0.975839;, + -0.075224;0.067895;0.994853;, + -0.072401;-0.157753;0.984821;, + -0.133760;-0.197065;0.971223;, + -0.421526;-0.376333;0.825039;, + -0.113815;0.102436;0.988207;, + -0.159036;0.237863;0.958190;, + -0.363394;-0.347889;0.864244;, + -0.340875;-0.250973;0.905990;, + -0.219814;-0.109322;0.969397;, + -0.110721;-0.227332;0.967502;, + -0.265841;0.064822;0.961835;, + -0.260969;0.257763;0.930297;, + -0.225523;0.367916;0.902096;, + -0.204636;0.250687;0.946192;, + -0.308536;-0.035566;0.950548;, + -0.280865;-0.155167;0.947121;, + -0.110123;-0.025715;0.993585;, + -0.225990;0.073774;0.971332;, + -0.317850;0.048584;0.946896;, + -0.286787;0.050884;0.956642;, + -0.135234;-0.128575;0.982436;, + -0.098581;0.034918;0.994516;, + -0.124352;-0.098909;0.987296;, + -0.027583;0.019128;0.999436;, + -0.990331;0.017071;0.137667;, + -0.973450;-0.198124;0.114640;, + -0.717508;-0.023630;0.696149;, + -0.990362;-0.013131;0.137880;, + -0.815899;-0.068843;0.574082;, + -0.919591;0.065600;0.387362;, + -0.964646;0.236442;-0.116421;, + -0.989021;0.026042;-0.145459;, + -0.960207;-0.224177;-0.166577;, + 0.341914;0.604075;-0.719853;, + 0.241749;0.480642;-0.842935;, + 0.136048;0.087503;-0.986830;, + -0.982644;0.096174;0.158626;, + -0.984714;0.084891;0.152090;, + -0.991473;0.037463;0.124814;, + -0.996531;0.005498;0.083044;, + -0.995489;-0.011539;0.094178;, + 0.157896;-0.099878;-0.982391;, + 0.117619;-0.172655;-0.977935;, + -0.023180;-0.471546;-0.881537;, + -0.642136;-0.415229;-0.644396;, + -0.985193;-0.114772;0.127367;, + -0.993842;-0.033310;0.105682;, + -0.840599;0.446641;0.306441;, + -0.751975;0.132709;0.645695;, + -0.940162;-0.115533;0.320542;, + -0.950011;-0.074948;-0.303088;, + -0.993523;-0.078642;0.082022;, + -0.991151;0.039768;-0.126645;, + -0.994943;0.013556;-0.099526;, + -0.485395;-0.513452;-0.707643;, + -0.229693;-0.529630;-0.816537;, + -0.295188;-0.242851;-0.924060;, + -0.210467;-0.041045;-0.976739;, + 0.040312;0.039373;-0.998411;, + -0.151436;0.353247;-0.923192;, + -0.835409;0.275429;-0.475637;, + -0.991667;-0.120179;-0.046409;, + -0.908512;0.062801;-0.413114;, + 0.083516;-0.876226;0.474609;, + -0.924920;-0.380144;0.003835;, + -0.947722;-0.049450;0.315243;, + -0.412440;-0.292679;0.862689;, + 0.402210;0.838808;-0.366918;, + 0.353181;0.729221;-0.586089;, + -0.198901;0.958333;-0.205027;, + -0.944823;0.308675;-0.109675;, + -0.884493;-0.444527;0.141662;, + -0.862185;0.430269;-0.267406;, + 0.013499;0.694024;-0.719825;, + 0.243556;0.731189;-0.637214;, + 0.197513;0.873282;-0.445384;, + -0.894910;-0.105076;-0.433700;, + -0.436112;-0.188372;-0.879956;, + -0.364055;-0.473683;-0.801928;, + -0.948565;-0.199078;-0.246157;, + -0.983673;-0.040697;-0.175301;, + -0.146382;-0.629542;-0.763052;, + 0.096478;-0.559529;-0.823176;, + 0.011927;-0.262782;-0.964781;, + -0.155590;-0.145800;-0.977003;, + -0.465377;-0.324842;-0.823348;, + -0.755154;-0.384266;-0.531113;, + -0.133038;-0.902773;-0.409025;, + 0.312386;-0.697431;-0.644985;, + 0.031574;-0.305537;-0.951657;, + -0.104452;-0.154902;-0.982393;, + -0.562599;-0.284042;-0.776403;, + -0.604821;-0.388772;-0.695017;, + -0.655051;-0.290024;-0.697707;, + -0.745770;-0.205337;-0.633769;, + -0.250413;-0.254174;-0.934178;, + 0.041562;-0.583144;-0.811305;, + -0.805809;-0.543792;0.234439;, + -0.782100;-0.570279;0.251199;, + -0.467073;-0.873594;-0.136662;, + -0.337534;-0.853552;-0.396886;, + -0.531094;-0.706015;-0.468489;, + -0.807521;-0.589785;0.008036;, + -0.602368;-0.756955;0.253322;, + -0.615086;-0.386827;0.687047;, + -0.238496;-0.799571;0.551186;, + -0.108202;-0.994107;-0.006522;, + -0.125377;-0.986922;-0.101321;, + -0.994704;0.028536;-0.098745;, + -0.987761;0.119054;-0.100772;, + -0.795270;0.185639;-0.577134;, + -0.767636;-0.389543;-0.508912;, + -0.833821;-0.284781;0.472909;, + -0.441591;0.115885;0.889701;, + -0.780037;0.083871;0.620087;, + -0.979289;0.016954;0.201754;, + -0.923625;-0.293416;-0.246623;, + -0.398686;-0.661959;-0.634713;, + -0.527934;-0.707186;-0.470290;, + -0.993981;0.072042;0.082538;, + -0.966193;0.076246;0.246286;, + -0.900595;0.023678;0.434013;, + -0.459569;0.109067;-0.881420;, + -0.609266;0.169694;-0.774596;, + -0.918178;0.118657;-0.377982;, + -0.473589;0.230470;-0.850057;, + -0.211760;0.199717;-0.956698;, + 0.270304;0.211165;-0.939332;, + -0.757123;0.021836;0.652907;, + -0.275522;0.128453;0.952674;, + -0.989453;0.037270;0.139976;, + -0.985345;0.075214;0.153095;, + -0.551796;-0.574616;-0.604431;, + -0.618692;-0.292564;-0.729127;, + -0.619769;0.060159;0.782475;, + -0.464479;-0.316670;0.827030;, + -0.372076;-0.368062;0.852109;, + -0.335690;-0.341328;0.877957;, + -0.285852;0.046274;0.957156;, + -0.355919;0.171383;0.918667;, + -0.723480;0.060884;0.687656;, + -0.814232;0.061779;0.577242;, + -0.886198;-0.021061;0.462827;, + -0.574120;-0.035273;0.818011;, + -0.243173;0.255052;0.935850;, + -0.418313;0.238912;0.876319;, + -0.255998;0.077691;0.963550;, + -0.261345;0.340963;0.903019;, + -0.153140;0.531302;0.833226;, + -0.004476;-0.270980;0.962575;, + -0.119564;-0.240178;0.963337;, + -0.327186;-0.256872;0.909377;, + -0.359013;-0.037721;0.932570;, + -0.047590;0.027451;0.998490;, + 0.022833;0.095235;0.995193;, + -0.377306;-0.316942;0.870166;, + -0.316548;-0.333267;0.888105;, + -0.477778;0.346040;0.807456;, + -0.323246;0.228712;0.918261;, + -0.376991;-0.033966;0.925594;, + -0.487857;-0.060488;0.870825;, + -0.761142;0.077824;0.643899;, + -0.720495;0.311094;0.619764;, + -0.524578;-0.521170;0.673201;, + -0.394926;-0.548853;0.736746;, + -0.356540;-0.270657;0.894217;, + -0.495468;-0.323313;0.806213;, + -0.463451;0.231939;0.855229;, + -0.256676;-0.425986;0.867556;, + -0.257064;-0.717534;0.647351;, + -0.264882;-0.777358;0.570571;, + -0.736052;0.062723;0.674013;, + -0.102010;0.499266;0.860423;, + 0.150316;0.449108;0.880743;, + 0.111995;0.138436;0.984019;, + -0.367057;-0.255284;0.894483;, + -0.278556;-0.296929;0.913367;, + -0.225628;0.375599;0.898898;, + -0.508485;-0.316227;0.800902;, + -0.840384;-0.146036;0.521946;, + -0.606247;0.434214;0.666275;, + -0.283006;0.307167;0.908601;, + -0.385943;-0.260360;0.885020;, + -0.221460;-0.237371;0.945839;, + -0.291186;-0.238537;0.926451;, + -0.160623;0.266772;0.950280;, + -0.283084;0.054206;0.957562;, + -0.282781;0.044475;0.958153;, + -0.135725;-0.254987;0.957371;, + -0.205252;0.312404;0.927510;, + -0.246128;0.432303;0.867488;, + -0.112957;-0.187289;0.975789;, + -0.531997;-0.340199;0.775399;, + -0.207669;-0.717728;0.664635;, + -0.470701;0.239290;0.849224;, + -0.660192;0.366644;0.655530;, + -0.098482;0.067836;0.992824;, + -0.227864;0.179884;0.956933;, + -0.333711;0.277181;0.901004;, + -0.304277;-0.311038;0.900372;, + -0.223441;-0.620814;0.751442;, + -0.478361;-0.492783;0.726868;, + -0.524366;-0.091050;0.846611;, + -0.371514;-0.104033;0.922580;, + -0.291101;0.296117;0.909711;, + -0.216517;0.601928;0.768637;, + -0.765717;0.109372;0.633811;, + -0.176319;-0.181296;0.967493;, + -0.237549;0.171176;0.956174;, + -0.290228;0.134824;0.947413;, + -0.292418;0.016174;0.956154;, + -0.352538;-0.172693;0.919725;, + -0.290964;-0.200100;0.935575;, + -0.909284;-0.286981;0.301404;, + -0.860343;-0.416762;0.293459;, + -0.527449;-0.725822;0.441566;, + -0.192717;-0.752991;0.629178;, + -0.413665;-0.662196;0.624803;, + -0.782661;-0.436604;0.443643;, + -0.739736;-0.304424;0.600097;, + -0.419309;-0.612197;0.670369;, + -0.178542;-0.532663;0.827280;, + -0.307625;-0.164296;0.937216;, + -0.692050;0.067912;0.718648;, + -0.773362;-0.044449;0.632405;, + -0.701142;0.222645;0.677370;, + -0.343154;0.141029;0.928631;, + -0.086339;0.227970;0.969832;, + -0.233405;0.474742;0.848612;, + -0.772564;0.372095;0.514481;, + -0.862219;0.333573;0.381192;, + -0.487320;0.574617;0.657522;, + -0.404061;0.641958;0.651632;, + -0.313427;0.711856;0.628510;, + -0.874726;0.363852;0.320104;, + -0.908715;0.258689;0.327593;, + -0.872452;0.309571;0.378146;, + -0.994626;0.037375;0.096552;, + -0.971560;0.138241;0.192251;, + -0.984564;0.133388;0.113322;, + -0.990615;0.053638;0.125719;, + -0.992423;-0.070546;-0.100601;, + -0.981912;-0.082005;-0.170656;, + 0.108071;-0.116143;0.987336;, + -0.797789;0.037538;0.601767;, + -0.920796;0.066458;0.384342;, + -0.928255;0.072027;0.364903;, + -0.930240;0.046030;0.364053;, + -0.415124;-0.114103;0.902581;, + -0.106608;-0.130975;0.985637;, + -0.933404;-0.160810;-0.320776;, + -0.736619;0.210971;-0.642560;, + -0.542357;0.242229;-0.804471;, + -0.523618;-0.179358;-0.832859;, + -0.870587;-0.276500;-0.406972;, + -0.922853;-0.232871;-0.306778;, + -0.901311;-0.421112;-0.101504;, + -0.851667;-0.383724;-0.356959;, + -0.545095;-0.326982;-0.771981;, + -0.333063;-0.417249;-0.845560;, + -0.554572;-0.744477;-0.371758;, + -0.863997;-0.496842;0.081586;, + -0.969478;-0.059688;-0.237801;, + -0.923894;-0.017241;-0.382259;, + -0.945693;-0.072099;-0.316964;, + -0.728538;0.351876;-0.587721;, + -0.723866;0.286506;-0.627640;, + -0.930880;-0.167827;-0.324496;, + -0.959100;-0.011290;-0.282843;, + -0.938731;0.123199;-0.321879;, + -0.709700;-0.318460;-0.628417;, + -0.330597;-0.726300;-0.602656;, + -0.452113;-0.839250;-0.302082;, + -0.857815;-0.222583;-0.463260;, + -0.902102;0.133251;-0.410435;, + -0.961728;0.190595;-0.196857;, + -0.978222;0.168444;-0.121282;, + -0.662740;0.264455;-0.700599;, + -0.476309;0.136397;-0.868634;, + -0.504309;-0.221320;-0.834679;, + -0.901494;0.354920;0.247672;, + -0.525457;0.668071;0.526854;, + -0.431549;0.860523;0.270676;, + -0.461883;0.559990;-0.687804;, + -0.494105;0.296706;-0.817206;, + -0.898829;0.268320;-0.346570;, + -0.941727;0.336079;-0.014200;, + -0.963121;0.021678;0.268195;, + -0.973111;-0.228118;-0.031884;, + -0.919379;-0.216115;-0.328690;, + -0.744589;-0.666942;-0.027853;, + -0.190314;-0.795142;0.575786;, + -0.060500;-0.787818;0.612930;, + -0.441276;-0.350415;0.826126;, + -0.840007;0.268555;0.471451;, + -0.964913;0.106253;0.240112;, + -0.995174;0.032352;0.092644;, + -0.934966;0.248566;-0.253088;, + -0.961037;0.049848;-0.271888;, + -0.998822;0.028759;0.039091;, + -0.990336;-0.002167;0.138672;, + -0.519203;-0.619776;0.588478;, + -0.391770;-0.654128;0.647018;, + -0.304486;-0.716860;0.627216;, + -0.910280;-0.362455;0.200043;, + -0.920418;-0.334077;0.203034;, + -0.988204;-0.086301;0.126514;, + -0.971693;-0.063695;0.227500;, + -0.923098;-0.057285;0.380275;, + -0.488334;0.063730;0.870327;, + -0.231105;-0.031755;0.972411;, + -0.512220;-0.385547;0.767453;, + -0.933438;-0.231048;0.274427;, + -0.473499;0.583805;0.659523;, + -0.308586;0.551748;0.774822;, + -0.255754;0.295329;0.920527;, + -0.877571;0.152218;0.454641;, + -0.979923;0.112462;0.164628;, + -0.889948;0.248106;0.382669;, + -0.883469;0.360672;0.298994;, + -0.946941;0.292536;0.133139;, + -0.962565;0.225045;0.151073;, + -0.879996;0.362170;0.307310;, + -0.453901;0.679771;0.576094;, + -0.231858;0.768436;0.596446;, + -0.521367;0.619633;0.586713;, + -0.987626;-0.156503;0.010098;, + -0.950732;-0.158522;-0.266418;, + -0.559545;-0.268517;-0.784097;, + -0.547278;-0.203637;-0.811799;, + -0.555973;0.130853;-0.820836;, + -0.983075;-0.050169;-0.176203;, + -0.589184;-0.777856;0.218638;, + -0.173867;-0.956818;0.232956;, + -0.412436;-0.546600;-0.728783;, + -0.867346;-0.396857;-0.300360;, + -0.999127;0.006755;-0.041222;, + -0.737443;0.369253;-0.565534;, + -0.294691;0.557341;-0.776227;, + -0.702347;0.471707;-0.533105;, + -0.999253;0.038278;0.005340;, + -0.208681;-0.785150;-0.583088;, + -0.214903;-0.821849;-0.527618;, + -0.174480;-0.970501;-0.166386;, + -0.133487;-0.990413;0.035549;, + -0.146752;-0.878664;-0.454328;, + -0.159714;-0.112935;-0.980682;, + -0.114641;0.109429;-0.987361;, + -0.097975;0.047333;-0.994063;, + -0.155868;-0.350626;-0.923454;, + -0.161498;-0.608488;-0.776956;, + -0.174065;-0.534580;-0.826998;, + -0.963396;0.255594;-0.080872;, + -0.495971;0.499732;-0.710127;, + -0.391198;0.918452;-0.058392;, + -0.910511;0.383051;0.155695;, + -0.801319;0.421929;0.424102;, + -0.173816;0.424341;0.888663;, + 0.132056;0.386729;0.912689;, + -0.059642;0.521187;0.851356;, + -0.717995;0.461191;0.521331;, + -0.963654;0.185646;0.192113;, + -0.826151;0.456218;0.330667;, + -0.202592;0.794997;0.571784;, + 0.122156;0.828715;0.546178;, + -0.156667;0.773674;0.613909;, + -0.783959;0.522880;0.334672;, + -0.247328;0.278644;-0.928001;, + -0.514676;0.484402;-0.707434;, + -0.221209;0.975219;-0.003702;, + 0.152157;0.982339;-0.108898;, + -0.086863;0.565088;-0.820445;, + -0.120370;0.286062;-0.950621;, + -0.217075;0.288626;-0.932509;, + -0.046481;0.258131;0.964991;, + 0.086883;0.146423;0.985399;, + -0.126526;-0.572079;0.810381;, + -0.678205;-0.266807;0.684728;, + -0.390094;-0.893060;0.224213;, + -0.215648;-0.938949;0.268088;, + -0.426159;-0.836851;-0.343610;, + -0.891225;-0.365388;-0.268717;, + -0.922702;-0.380591;0.061411;, + -0.479805;-0.561201;-0.674419;, + -0.263961;-0.572476;-0.776271;, + -0.401044;-0.160466;-0.901895;, + -0.812645;0.076717;-0.577688;, + -0.985268;-0.013185;-0.170509;, + -0.929545;-0.091642;-0.357137;, + -0.706692;0.408356;0.577781;, + -0.971905;0.201947;0.120901;, + -0.780984;0.429796;0.453144;, + -0.101385;0.740749;0.664088;, + 0.112055;0.771742;0.625986;, + -0.063776;0.461704;0.884738;, + -0.644377;0.580936;0.497285;, + -0.726201;0.594292;0.345614;, + -0.064509;0.887130;0.456988;, + 0.151722;0.889454;0.431106;, + 0.004774;0.752502;0.658573;, + -0.180513;0.319591;-0.930202;, + -0.071812;0.376860;-0.923482;, + -0.055318;0.875614;-0.479834;, + -0.604713;0.765248;-0.220720;, + -0.947576;-0.246188;0.203695;, + -0.945100;-0.267159;0.188180;, + -0.929894;-0.301728;0.210374;, + -0.938122;-0.247356;0.242367;, + -0.948037;-0.205364;0.243004;, + -0.982289;0.005861;0.187281;, + -0.970327;0.034796;0.239279;, + -0.821069;-0.164374;0.546650;, + -0.788342;-0.076790;0.610426;, + -0.948825;-0.033448;0.314026;, + -0.984684;-0.100876;0.142201;, + -0.990691;-0.060390;0.122001;, + -0.991477;-0.014669;0.129452;, + -0.977761;-0.074429;0.196069;, + -0.968921;-0.148629;0.197740;, + -0.963259;-0.202188;0.176785;, + -0.965124;-0.190436;0.179640;, + -0.996668;-0.000055;0.081571;, + -0.992952;-0.010172;0.118079;, + -0.653195;-0.150269;0.742129;, + -0.393828;-0.197542;0.897707;, + -0.986199;-0.027926;0.163190;, + -0.698788;-0.183747;0.691326;, + -0.477199;-0.092968;0.873864;, + -0.408888;-0.121595;0.904447;, + -0.383912;-0.053672;0.921808;, + -0.668225;-0.119696;0.734267;, + -0.707558;-0.149489;0.690662;, + -0.333263;0.082750;0.939196;, + -0.380632;0.065214;0.922424;, + -0.424222;0.027945;0.905127;, + -0.344899;-0.178549;0.921501;, + -0.228579;-0.246387;0.941831;, + -0.295296;-0.069069;0.952906;, + -0.351717;0.069372;0.933532;, + -0.150503;0.003474;0.988603;, + 0.100381;-0.018321;0.994780;, + 0.184877;0.074293;0.979949;, + 0.196102;0.167844;0.966112;, + -0.150811;0.174292;0.973077;, + -0.204636;0.123817;0.970976;, + -0.230074;0.372461;0.899077;, + -0.506615;0.220020;0.833626;, + -0.303228;0.319910;0.897613;, + 0.259931;0.297731;0.918581;, + 0.467914;0.186614;0.863847;, + 0.291782;0.351503;0.889555;, + 0.135206;-0.197296;0.970976;, + -0.056462;-0.303649;0.951110;, + -0.259365;-0.317494;0.912101;, + -0.300044;-0.323635;0.897348;, + -0.158828;0.184032;0.970003;, + -0.232666;0.262793;0.936379;, + -0.328859;0.141047;0.933787;, + -0.388761;0.111134;0.914611;, + -0.320469;0.119524;0.939688;, + -0.241856;-0.015663;0.970186;, + -0.206723;0.090179;0.974235;, + -0.214559;0.312331;0.925426;, + -0.214040;0.335101;0.917548;, + -0.175599;0.167179;0.970163;, + -0.207314;0.342570;0.916333;, + -0.204677;0.145172;0.968004;, + -0.267360;0.048646;0.962368;, + -0.242820;0.143189;0.959445;, + -0.216371;0.266677;0.939184;, + -0.191125;0.333044;0.923338;, + -0.546439;0.124024;0.828265;, + -0.421343;0.043606;0.905852;, + -0.710324;-0.088882;0.698241;, + -0.759262;-0.042020;0.649427;, + 0.457664;-0.046073;0.887931;, + 0.415472;-0.131980;0.899980;, + 0.601990;-0.320637;0.731300;, + 0.732447;-0.463382;0.498797;, + 0.796203;-0.311752;0.518528;, + 0.618889;-0.216199;0.755138;, + 0.650858;-0.279521;-0.705870;, + 0.627769;-0.641265;-0.441233;, + 0.881339;-0.465948;0.078326;, + 0.928462;-0.263842;0.261431;, + 0.964094;-0.165413;0.207751;, + 0.924341;-0.229764;-0.304633;, + 0.927430;-0.166498;0.334890;, + 0.883252;-0.199217;0.424473;, + 0.843025;-0.193507;0.501860;, + 0.834563;-0.142862;0.532067;, + 0.847343;-0.090185;0.523332;, + 0.859241;0.003695;0.511557;, + 0.786163;-0.008241;0.617964;, + 0.922761;-0.080766;0.376814;, + 0.964606;-0.206993;0.163368;, + 0.954750;-0.229736;0.188876;, + 0.977642;-0.134009;0.162042;, + 0.556167;-0.235673;0.796955;, + -0.566294;-0.282990;0.774098;, + -0.779621;-0.549588;0.300240;, + -0.453973;-0.875337;-0.166413;, + 0.885166;-0.437540;-0.158241;, + 0.965433;-0.004688;0.260610;, + 0.745205;-0.297817;0.596636;, + 0.383889;-0.464132;0.798255;, + 0.323830;-0.489051;0.809916;, + 0.924672;0.127786;0.358681;, + 0.983531;0.088214;0.157748;, + -0.363776;0.894300;-0.260567;, + 0.270665;0.955941;0.113652;, + 0.641266;0.188129;0.743899;, + 0.616460;-0.165561;0.769783;, + 0.677762;-0.074270;0.731521;, + 0.829313;0.074463;0.553800;, + 0.887257;0.039798;0.459556;, + 0.781695;0.234974;0.577703;, + 0.819624;0.148430;0.553340;, + 0.781224;0.181945;0.597148;, + 0.679518;-0.160347;0.715922;, + 0.771375;-0.034845;0.635426;, + 0.535532;-0.307662;0.786480;, + 0.285775;0.030248;0.957819;, + 0.817277;0.454475;0.354275;, + 0.810140;0.435116;-0.392871;, + 0.839666;0.520528;0.154955;, + 0.709256;0.641012;0.293361;, + 0.614890;0.217033;0.758160;, + 0.420168;0.159950;0.893238;, + 0.483411;0.190762;0.854356;, + 0.360033;0.104427;0.927077;, + 0.286110;0.137586;0.948268;, + 0.070070;0.358867;0.930755;, + 0.165214;0.238175;0.957067;, + 0.196627;-0.192079;0.961480;, + 0.247128;-0.341305;0.906884;, + 0.643177;-0.541832;0.541056;, + 0.809334;-0.483823;-0.333007;, + 0.218364;0.254619;0.942065;, + 0.396152;0.003364;0.918179;, + 0.609373;-0.153995;0.777786;, + 0.663145;-0.277587;0.695115;, + 0.382906;-0.177032;0.906666;, + 0.413901;-0.346606;0.841754;, + 0.585242;-0.040809;0.809831;, + 0.626492;0.149889;0.764880;, + 0.412419;-0.359405;0.837102;, + 0.144547;-0.399892;0.905093;, + 0.214707;0.074209;0.973855;, + 0.235312;0.330449;0.914019;, + 0.402156;-0.544015;0.736423;, + 0.349444;-0.577169;0.738081;, + 0.335755;-0.089838;0.937655;, + 0.309502;-0.188143;0.932100;, + 0.531786;-0.357341;0.767796;, + 0.532413;-0.519111;0.668625;, + 0.198806;-0.407566;0.891272;, + 0.050237;0.021161;0.998513;, + -0.154151;0.164731;0.974218;, + 0.014259;0.242570;0.970029;, + 0.101190;0.244238;0.964421;, + 0.075895;-0.122424;0.989572;, + 0.926394;-0.303016;0.223553;, + 0.916339;-0.265300;0.299899;, + 0.941193;-0.231274;0.246311;, + 0.942736;-0.258883;0.210308;, + 0.872017;-0.277751;0.403040;, + 0.891387;-0.329329;0.311403;, + 0.920623;-0.287190;0.264530;, + 0.888242;-0.359291;0.286246;, + 0.823502;-0.420165;0.381189;, + 0.712448;-0.424274;0.558935;, + 0.572964;-0.461769;0.677112;, + 0.734110;-0.436861;0.519842;, + 0.859424;-0.304858;0.410430;, + 0.820103;-0.223413;0.526800;, + 0.694020;0.045381;0.718524;, + 0.732903;0.294085;0.613487;, + 0.704924;0.372480;0.603606;, + 0.767741;0.423284;0.481046;, + 0.610611;0.550799;0.569012;, + 0.428564;0.378854;0.820246;, + 0.528841;0.287979;0.798370;, + 0.657818;0.087537;0.748073;, + 0.585630;-0.275362;0.762373;, + 0.487759;0.040891;0.872020;, + 0.366793;-0.058552;0.928458;, + 0.300364;-0.225631;0.926754;, + 0.529462;-0.449192;0.719651;, + 0.530125;0.561389;0.635461;, + 0.592261;0.685382;0.423648;, + 0.622463;0.688709;0.371779;, + 0.792469;0.431830;0.430715;, + 0.631199;0.391605;0.669503;, + 0.299096;0.239203;0.923755;, + 0.820659;-0.346212;-0.454594;, + 0.626383;-0.271076;-0.730864;, + 0.638572;-0.117365;-0.760560;, + 0.788158;0.351005;0.505571;, + 0.200084;-0.052108;0.978392;, + 0.246747;-0.051308;0.967721;, + 0.295036;-0.000370;0.955486;, + 0.509111;0.214011;0.833670;, + 0.902799;0.118400;0.413443;, + 0.910089;0.167693;0.378969;, + 0.999735;0.022967;0.001488;, + 0.996072;-0.042387;-0.077740;, + 0.968689;-0.002135;0.248269;, + 0.832590;0.320635;0.451650;, + 0.730488;0.555207;0.397659;, + 0.597202;0.573938;0.560308;, + 0.720968;0.387938;0.574203;, + 0.775558;0.322202;0.542858;, + 0.694246;-0.474535;0.541146;, + 0.644048;-0.677994;0.354297;, + 0.306835;-0.637411;0.706795;, + 0.266653;-0.673114;0.689793;, + 0.448030;-0.595143;0.667138;, + 0.953942;-0.228941;0.193855;, + 0.938814;-0.254695;-0.231861;, + 0.681733;-0.472937;-0.558184;, + 0.645724;-0.571945;-0.505885;, + 0.884756;-0.428469;0.183360;, + 0.649040;0.135351;0.748617;, + 0.529791;0.315074;0.787432;, + 0.553748;0.630029;0.544451;, + 0.678128;0.634870;0.370248;, + 0.796340;0.360973;0.485325;, + 0.510516;-0.005648;0.859850;, + 0.416079;0.034303;0.908681;, + 0.410099;0.086002;0.907977;, + 0.420062;0.136052;0.897239;, + 0.478583;0.042049;0.877035;, + 0.504686;-0.416381;0.756253;, + 0.267406;-0.542263;0.796520;, + 0.189664;-0.341747;0.920454;, + 0.305752;-0.160267;0.938525;, + 0.443105;-0.186385;0.876880;, + 0.785203;-0.238678;0.571392;, + 0.702825;-0.257963;0.662942;, + 0.632744;-0.132306;0.762974;, + 0.707627;-0.023756;0.706187;, + 0.823076;0.132453;0.552270;, + 0.827196;0.109153;0.551210;, + 0.840927;-0.044262;0.539336;, + 0.764042;0.302636;0.569781;, + 0.742909;0.415406;0.524903;, + 0.699619;0.385348;0.601698;, + 0.578906;0.224993;0.783739;, + 0.590168;0.194655;0.783461;, + 0.302061;-0.359334;0.882971;, + 0.349642;-0.508600;0.786814;, + 0.384855;-0.464307;0.797688;, + 0.416260;-0.438975;0.796259;, + 0.099726;-0.233237;0.967293;, + 0.048634;0.031907;0.998307;, + 0.180176;0.105444;0.977966;, + 0.252687;-0.100086;0.962358;, + 0.155669;-0.183842;0.970551;, + 0.411002;-0.338944;0.846282;, + 0.383695;-0.396116;0.834188;, + 0.249542;0.061763;0.966392;, + -0.016457;0.327055;0.944862;, + 0.224850;0.215443;0.950277;, + 0.196803;0.368723;0.908467;, + 0.250180;0.310646;0.917011;, + 0.277343;0.101996;0.955342;, + 0.152847;-0.155989;0.975861;, + 0.195391;-0.110401;0.974492;, + 0.305812;-0.230212;0.923841;, + 0.368641;-0.213324;0.904763;, + 0.330326;-0.205628;0.921196;, + 0.041593;0.020366;0.998927;, + 0.105429;-0.086429;0.990664;, + 0.129328;0.092742;0.987255;, + 0.068386;-0.183487;0.980641;, + 0.278092;0.030516;0.960070;, + 0.303773;0.055120;0.951149;, + 0.271522;0.061913;0.960439;, + 0.081953;0.023311;0.996364;, + 0.990331;0.017071;0.137667;, + 0.953548;-0.160770;0.254755;, + 0.955059;-0.249767;-0.159623;, + 0.989051;-0.010385;-0.147209;, + 0.968564;0.208434;-0.135792;, + 0.962753;0.114072;0.245141;, + 0.744378;-0.064698;0.664617;, + 0.986376;-0.020071;0.163278;, + 0.669899;-0.004795;0.742437;, + -0.235778;0.425628;-0.873642;, + -0.220215;0.603569;-0.766296;, + 0.417851;0.563338;-0.712777;, + -0.117525;0.013779;-0.992974;, + 0.982667;0.097694;0.157550;, + 0.995367;-0.011631;0.095439;, + 0.996248;-0.000196;0.086542;, + 0.993018;0.025522;0.115170;, + 0.985216;0.087350;0.147373;, + 0.723129;-0.344431;-0.598709;, + 0.154335;-0.521647;-0.839086;, + -0.133014;-0.196421;-0.971456;, + -0.156278;-0.099901;-0.982648;, + 0.783722;0.054151;0.618747;, + 0.800117;0.416289;0.431874;, + 0.984353;0.134697;0.113601;, + 0.979461;-0.119954;0.162070;, + 0.979140;-0.146299;0.141004;, + 0.991670;-0.062397;0.112684;, + 0.457966;-0.192146;-0.867956;, + 0.237393;-0.461566;-0.854752;, + 0.286927;-0.568203;-0.771244;, + 0.948440;-0.169360;-0.267917;, + 0.986431;0.066300;-0.150194;, + 0.998816;-0.041285;0.025724;, + 0.997505;-0.067738;-0.019863;, + 0.977410;0.022278;-0.210173;, + 0.251890;0.415533;-0.874004;, + -0.049975;0.093433;-0.994371;, + 0.097770;-0.050793;-0.993912;, + 0.766098;0.059984;-0.639918;, + 0.884732;-0.053391;0.463033;, + 0.961439;-0.267549;0.063666;, + 0.356172;-0.920978;0.157925;, + 0.137541;-0.415914;0.898943;, + 0.601662;0.572761;-0.556730;, + -0.202958;0.734881;-0.647115;, + -0.398591;0.825562;-0.399465;, + 0.467679;0.871282;-0.148809;, + -0.170588;0.897489;-0.406710;, + -0.258260;0.761324;-0.594717;, + -0.103593;0.680661;-0.725237;, + 0.665282;0.581928;-0.467718;, + 0.906891;-0.362904;0.214125;, + 0.986874;0.076429;-0.142259;, + 0.748399;-0.135655;-0.649228;, + 0.972144;-0.068447;-0.224170;, + 0.994963;-0.047062;-0.088507;, + 0.528323;-0.487037;-0.695464;, + 0.335614;-0.233313;-0.912649;, + 0.007851;-0.660221;-0.751031;, + 0.455960;-0.390419;-0.799796;, + 0.279711;-0.160851;-0.946514;, + -0.004749;-0.220237;-0.975435;, + -0.084670;-0.487141;-0.869209;, + 0.247045;-0.169890;-0.953995;, + 0.006335;-0.246126;-0.969217;, + -0.214712;-0.642232;-0.735824;, + -0.275438;-0.893885;-0.353699;, + 0.710787;-0.466778;-0.526214;, + 0.633158;-0.292738;-0.716530;, + 0.618095;-0.351774;-0.703004;, + 0.147006;-0.604143;-0.783199;, + 0.088495;-0.303567;-0.948692;, + 0.682342;-0.196035;-0.704258;, + 0.643874;-0.292915;-0.706843;, + 0.663539;-0.666241;-0.340352;, + 0.373002;-0.795669;-0.477263;, + 0.420448;-0.891526;-0.168539;, + 0.723608;-0.669946;0.166023;, + 0.799573;-0.544703;0.252945;, + 0.813432;-0.577021;0.073316;, + 0.073674;-0.995832;-0.053775;, + 0.193201;-0.890421;0.412097;, + 0.557281;-0.410177;0.721937;, + 0.626008;-0.721638;0.295555;, + 0.253351;-0.965876;-0.053822;, + 0.996795;0.059173;-0.053828;, + 0.870487;-0.276909;-0.406907;, + 0.718742;0.207815;-0.663493;, + 0.972577;0.124346;-0.196549;, + 0.360242;-0.674562;-0.644354;, + 0.831536;-0.420486;-0.362960;, + 0.992970;0.009011;0.118019;, + 0.832630;0.062414;0.550302;, + 0.429350;0.141609;0.891967;, + 0.772381;-0.152248;0.616642;, + 0.619530;-0.709222;-0.336434;, + 0.868190;-0.002769;0.496225;, + 0.955968;0.074254;0.283920;, + 0.993664;0.087718;0.070268;, + 0.944767;0.116170;-0.306464;, + 0.737612;0.161042;-0.655740;, + 0.449994;0.091497;-0.888332;, + 0.445506;0.217708;-0.868405;, + -0.291086;0.220952;-0.930833;, + 0.064085;0.200510;-0.977593;, + 0.166541;0.103506;0.980587;, + 0.694153;0.049571;0.718118;, + 0.988650;0.046011;0.143017;, + 0.984565;0.081079;0.155104;, + 0.893652;0.299498;-0.334196;, + 0.618693;-0.292564;-0.729127;, + 0.551796;-0.574616;-0.604431;, + 0.251449;0.254655;0.933769;, + 0.329189;-0.298075;0.895983;, + 0.374162;-0.369333;0.850644;, + 0.394027;-0.385974;0.834126;, + 0.629716;-0.045172;0.775511;, + 0.414482;0.150122;0.897590;, + 0.752482;0.042277;0.657254;, + 0.497044;0.192697;0.846059;, + 0.233967;0.315946;0.919477;, + 0.509045;0.023685;0.860414;, + 0.837737;-0.103276;0.536219;, + 0.825693;0.084952;0.557686;, + 0.037052;-0.285163;0.957763;, + 0.072545;0.261091;0.962584;, + 0.254955;0.442961;0.859525;, + 0.279810;0.168723;0.945113;, + 0.138900;-0.213260;0.967071;, + 0.368508;-0.334070;0.867525;, + 0.140609;-0.045717;0.989009;, + -0.019079;0.066742;0.997588;, + 0.299362;0.006168;0.954120;, + 0.352172;-0.219694;0.909785;, + 0.309812;-0.324424;0.893737;, + 0.805112;0.138732;0.576669;, + 0.538357;-0.045396;0.841493;, + 0.380736;-0.067302;0.922231;, + 0.328487;0.183332;0.926545;, + 0.432615;0.307403;0.847554;, + 0.653253;0.367666;0.661878;, + 0.492323;-0.585442;0.644108;, + 0.502064;-0.355000;0.788610;, + 0.401739;-0.251939;0.880416;, + 0.376888;-0.493204;0.784032;, + 0.408002;0.182946;0.894464;, + 0.686633;0.144018;0.712597;, + 0.519245;-0.551574;0.652803;, + 0.241814;-0.736624;0.631594;, + 0.189975;-0.684424;0.703898;, + 0.231331;-0.089643;0.968736;, + 0.437328;-0.396663;0.807095;, + -0.019958;0.064292;0.997732;, + -0.162579;0.374547;0.912843;, + 0.021642;0.552809;0.833027;, + 0.240174;0.350884;0.905095;, + 0.590551;-0.317529;0.741907;, + 0.378809;-0.263028;0.887310;, + 0.356270;0.140360;0.923781;, + 0.292827;0.581198;0.759250;, + 0.887962;-0.080435;0.452829;, + 0.232714;-0.268412;0.934772;, + 0.270973;-0.021494;0.962347;, + 0.249117;0.137702;0.958634;, + 0.240587;0.147886;0.959295;, + 0.297294;-0.186777;0.936339;, + 0.218225;0.244375;0.944806;, + 0.222570;0.434020;0.872977;, + 0.144213;-0.238035;0.960491;, + 0.105285;-0.243661;0.964129;, + 0.499498;0.317571;0.806009;, + 0.323872;-0.438181;0.838513;, + 0.358587;-0.591042;0.722554;, + 0.709020;0.269606;0.651616;, + 0.298672;-0.579421;0.758332;, + 0.236939;-0.570878;0.786103;, + 0.348584;0.203164;0.914994;, + 0.260867;0.212941;0.941597;, + 0.097898;0.105821;0.989554;, + 0.377267;-0.289994;0.879530;, + 0.479423;0.478311;0.735780;, + 0.249071;0.370670;0.894744;, + 0.302334;0.087757;0.949154;, + 0.470067;-0.109278;0.875840;, + 0.727706;0.050030;0.684063;, + 0.159681;-0.153441;0.975171;, + 0.267587;-0.200427;0.942457;, + 0.365349;-0.233476;0.901116;, + 0.305557;-0.031119;0.951665;, + 0.278707;0.095201;0.955646;, + 0.291626;0.332066;0.897043;, + 0.501613;-0.618956;0.604382;, + 0.178903;-0.749707;0.637129;, + 0.274708;-0.796173;0.539115;, + 0.841050;-0.462941;0.279859;, + 0.915403;-0.281528;0.287713;, + 0.874537;-0.332222;0.353288;, + 0.799068;0.056915;0.598541;, + 0.406283;-0.083515;0.909923;, + 0.131733;-0.475879;0.869589;, + 0.238303;-0.649785;0.721797;, + 0.701135;-0.368935;0.610161;, + 0.788343;-0.078957;0.610149;, + 0.396116;0.496106;0.772638;, + 0.080690;0.269931;0.959493;, + 0.097838;0.136147;0.985846;, + 0.673078;0.201405;0.711620;, + 0.814615;0.305380;0.493097;, + 0.791616;0.414216;0.449188;, + 0.871315;0.302480;0.386414;, + 0.904561;0.262540;0.335921;, + 0.910079;0.308658;0.276563;, + 0.525509;0.655009;0.542957;, + 0.397477;0.642652;0.654989;, + 0.369469;0.615521;0.696152;, + 0.980166;-0.106355;-0.167220;, + 0.993832;0.046691;0.100592;, + 0.981920;0.086298;0.168479;, + 0.981368;0.156012;0.112144;, + 0.974808;0.085085;0.206180;, + 0.988089;-0.076583;-0.133471;, + 0.233487;-0.090126;0.968174;, + 0.078736;-0.116167;0.990104;, + 0.160509;-0.156800;0.974500;, + 0.853642;0.016690;0.520593;, + 0.939670;0.050263;0.338368;, + 0.923190;0.094626;0.372514;, + 0.862014;0.056065;0.503774;, + 0.936010;-0.253687;-0.243985;, + 0.608655;-0.245946;-0.754353;, + 0.523086;0.163014;-0.836545;, + 0.568395;0.375488;-0.732077;, + 0.917980;-0.141801;-0.370411;, + 0.923300;-0.237465;-0.301874;, + 0.909875;-0.400036;-0.109997;, + 0.906412;-0.421235;0.031280;, + 0.675045;-0.722669;-0.148538;, + 0.309013;-0.470378;-0.826593;, + 0.372917;-0.313993;-0.873122;, + 0.818454;-0.384125;-0.427295;, + 0.810462;0.143367;-0.567977;, + 0.626725;0.447627;-0.637844;, + 0.910464;0.049229;-0.410649;, + 0.935713;-0.058966;-0.347798;, + 0.964018;-0.036088;-0.263376;, + 0.945373;-0.182223;-0.270306;, + 0.963343;0.024740;-0.267130;, + 0.880786;-0.181630;-0.437296;, + 0.650930;-0.680013;-0.337449;, + 0.335037;-0.782036;-0.525518;, + 0.563778;-0.458869;-0.686727;, + 0.913321;0.104053;-0.393723;, + 0.937081;0.163116;-0.308662;, + 0.668251;-0.161916;-0.726102;, + 0.486568;0.053293;-0.872016;, + 0.533594;0.277429;-0.798943;, + 0.928577;0.194671;-0.315987;, + 0.969092;0.183829;-0.164523;, + 0.866079;0.407632;0.289384;, + 0.941173;0.337920;-0.002044;, + 0.938375;0.259917;-0.227806;, + 0.624232;0.279202;-0.729644;, + 0.502694;0.464741;-0.728913;, + 0.436435;0.894881;0.093339;, + 0.353823;0.758467;0.547299;, + 0.933666;0.245227;0.261020;, + 0.535134;-0.219852;0.815657;, + 0.024104;-0.703755;0.710034;, + 0.178308;-0.751297;0.635421;, + 0.602066;-0.782297;0.159777;, + 0.901219;-0.248765;-0.354853;, + 0.961986;-0.258591;-0.087825;, + 0.968198;-0.019433;0.249429;, + 0.974126;0.109867;0.197503;, + 0.998120;0.046379;0.040070;, + 0.989245;0.018948;0.145036;, + 0.998196;0.033204;0.050015;, + 0.987221;0.030678;-0.156373;, + 0.915666;0.230725;-0.329122;, + 0.929875;-0.332924;0.156510;, + 0.548129;-0.661438;0.511912;, + 0.328608;-0.695385;0.639105;, + 0.393459;-0.640623;0.659388;, + 0.887822;-0.363940;0.281637;, + 0.667999;-0.377721;0.641174;, + 0.176666;-0.140491;0.974193;, + 0.341914;0.096830;0.934729;, + 0.887877;-0.038319;0.458482;, + 0.969393;-0.056384;0.238953;, + 0.987385;-0.098273;0.124147;, + 0.957678;-0.180684;0.224067;, + 0.978399;0.092216;0.185021;, + 0.903224;0.146776;0.403292;, + 0.492552;0.233622;0.838340;, + 0.283857;0.492640;0.822637;, + 0.297955;0.637549;0.710460;, + 0.848610;0.319927;0.421318;, + 0.905296;0.318015;0.281611;, + 0.636969;0.566446;0.522885;, + 0.186839;0.733572;0.653424;, + 0.320731;0.757519;0.568591;, + 0.837352;0.395678;0.377200;, + 0.959055;0.246703;0.139112;, + 0.955218;0.282513;0.088003;, + 0.990080;-0.140504;-0.000454;, + 0.987431;-0.083124;-0.134427;, + 0.770556;0.153218;-0.618683;, + 0.514955;-0.136927;-0.846211;, + 0.487689;-0.291792;-0.822810;, + 0.911993;-0.179968;-0.368620;, + 0.554420;-0.498946;-0.666086;, + 0.175684;-0.958552;-0.224307;, + 0.440194;-0.833213;0.334641;, + 0.883002;-0.445236;-0.148568;, + 0.833256;0.378313;-0.403191;, + 0.280903;0.598074;-0.750601;, + 0.607836;0.418934;-0.674559;, + 0.994040;0.019054;-0.107342;, + 0.998649;0.042991;0.029202;, + 0.067520;-0.991070;-0.114981;, + 0.206828;-0.976295;-0.063794;, + 0.201725;-0.842948;-0.498745;, + 0.199110;-0.789128;-0.581061;, + 0.182351;-0.838223;-0.513937;, + 0.179619;-0.612115;-0.770099;, + 0.161976;-0.446886;-0.879805;, + 0.103521;-0.032143;-0.994108;, + 0.083882;0.118846;-0.989363;, + 0.162750;-0.049292;-0.985435;, + 0.155187;-0.395059;-0.905453;, + 0.567095;0.799478;0.198086;, + 0.449374;0.616302;-0.646711;, + 0.849927;0.303096;-0.430996;, + 0.936005;0.320009;0.146594;, + 0.155449;0.563615;0.811279;, + -0.138213;0.387227;0.911566;, + -0.004277;0.391231;0.920283;, + 0.721355;0.437806;0.536631;, + 0.852050;0.350687;0.388626;, + 0.964763;0.203925;0.166276;, + 0.871839;0.392583;0.292873;, + 0.274136;0.799417;0.534586;, + -0.141042;0.765026;0.628365;, + 0.116728;0.857063;0.501815;, + 0.732098;0.530474;0.427353;, + 0.288643;0.263589;-0.920438;, + 0.254733;0.326813;-0.910112;, + 0.156678;0.269554;-0.950154;, + 0.107469;0.490481;-0.864800;, + -0.142335;0.937356;-0.317971;, + 0.076965;0.997000;-0.008263;, + 0.564368;0.602211;-0.564651;, + 0.240721;-0.608347;0.756285;, + -0.073068;-0.148548;0.986202;, + -0.009780;0.272046;0.962235;, + 0.570934;0.068021;0.818174;, + 0.970937;-0.213567;-0.108028;, + 0.499315;-0.779570;-0.378095;, + 0.230800;-0.972814;0.019097;, + 0.323398;-0.895943;0.304467;, + 0.834135;-0.545842;0.079219;, + 0.981707;0.015920;-0.189730;, + 0.949298;0.051192;-0.310183;, + 0.429925;-0.097791;-0.897553;, + 0.244202;-0.464371;-0.851308;, + 0.420516;-0.601479;-0.679256;, + 0.847608;-0.252333;-0.466786;, + 0.842275;0.348065;0.411611;, + 0.123801;0.481601;0.867602;, + -0.131402;0.605188;0.785163;, + 0.049951;0.809325;0.585234;, + 0.649010;0.538182;0.537723;, + 0.974070;0.179720;0.137432;, + 0.810052;0.462959;0.359841;, + 0.071975;0.766775;0.637868;, + -0.167942;0.811266;0.560038;, + -0.017901;0.898223;0.439175;, + 0.575245;0.693252;0.434161;, + 0.126094;0.962221;-0.241310;, + 0.028226;0.494821;-0.868536;, + 0.153941;0.305601;-0.939633;, + 0.584262;0.539674;-0.606128;, + 0.947656;-0.251190;0.197106;, + 0.949985;-0.211068;0.230172;, + 0.940140;-0.240408;0.241536;, + 0.930866;-0.286260;0.227033;, + 0.941418;-0.276414;0.193203;, + 0.845017;-0.054953;0.531908;, + 0.750383;-0.181846;0.635498;, + 0.962843;0.019373;0.269367;, + 0.984408;0.024365;0.174202;, + 0.959207;-0.033141;0.280754;, + 0.962017;-0.206528;0.178519;, + 0.966498;-0.168546;0.193582;, + 0.976406;-0.086182;0.198001;, + 0.987549;-0.026149;0.155126;, + 0.990651;-0.059208;0.122906;, + 0.991572;-0.052289;0.118536;, + 0.967265;-0.179678;0.179202;, + 0.996580;-0.008069;0.082235;, + 0.991472;-0.016919;0.129214;, + 0.747666;-0.139847;0.649183;, + 0.119081;-0.211793;0.970033;, + 0.990935;-0.007248;0.134150;, + 0.721351;-0.142669;0.677715;, + 0.443972;-0.060466;0.893998;, + 0.376067;-0.110373;0.919995;, + 0.434429;-0.090333;0.896165;, + 0.672873;-0.178482;0.717903;, + 0.709868;-0.146248;0.688984;, + 0.362721;0.087395;0.927791;, + 0.374887;0.073105;0.924183;, + 0.312884;-0.023254;0.949507;, + 0.212041;-0.224883;0.951034;, + 0.297241;-0.210499;0.931310;, + 0.417830;-0.014675;0.908406;, + 0.383091;0.055913;0.922017;, + 0.285816;-0.314551;0.905189;, + 0.097390;-0.315817;0.943809;, + -0.106431;-0.217381;0.970267;, + 0.289110;-0.330505;0.898433;, + 0.368538;0.102287;0.923968;, + 0.324933;0.131935;0.936489;, + 0.269458;0.248871;0.930299;, + 0.190265;0.215570;0.957773;, + 0.284323;0.139703;0.948496;, + 0.190706;0.300576;0.934497;, + 0.242287;0.344618;0.906937;, + 0.209863;0.120826;0.970236;, + 0.253672;-0.005589;0.967274;, + 0.192077;0.138798;0.971515;, + 0.242108;0.270614;0.931746;, + 0.243379;0.149539;0.958335;, + 0.258802;0.073888;0.963100;, + 0.212004;0.101858;0.971946;, + 0.216250;0.294970;0.930714;, + 0.145512;0.372407;0.916591;, + 0.741126;-0.084012;0.666089;, + 0.498990;-0.008124;0.866570;, + 0.473728;0.138060;0.869782;, + 0.731146;-0.000413;0.682221;, + -0.631357;0.354670;0.689636;, + 0.632039;0.355130;0.688773;, + 0.914875;-0.152402;-0.373869;, + -0.914875;-0.152402;-0.373869;, + -0.433214;-0.193876;-0.880192;, + -0.859652;-0.309116;-0.406751;, + -0.093634;0.341116;0.935346;, + -0.093634;0.341116;0.935346;, + 0.000004;-0.093947;-0.995577;, + 0.244564;-0.065106;0.967445;, + -0.963334;-0.094433;0.251137;, + -0.989571;-0.011953;-0.143551;, + -0.885448;-0.301099;-0.354007;, + -0.989571;-0.011953;-0.143551;, + -0.982778;-0.084744;-0.164211;, + -0.957758;-0.287242;0.013841;, + -0.449270;0.893379;-0.005605;, + -0.895650;-0.343271;-0.282799;, + 0.527840;-0.168309;0.832500;, + 0.233305;-0.886660;0.399253;, + 0.513833;-0.494239;0.701216;, + 0.278233;-0.273728;0.920684;, + -0.790963;-0.525076;0.314122;, + 0.853727;-0.007027;-0.520673;, + -0.701247;-0.651828;-0.288743;, + -0.145665;-0.919602;-0.364848;, + 0.854774;-0.403493;0.326429;, + 0.174039;-0.984266;0.030518;, + -0.000016;-0.990834;-0.135089;, + 0.114825;-0.948131;-0.296416;, + 0.244564;-0.065106;0.967445;, + 0.026768;-0.438717;0.898227;, + -0.817874;-0.539381;-0.200374;, + -0.989571;-0.011953;-0.143551;, + -0.817874;-0.539381;-0.200374;, + 0.174039;-0.984266;0.030518;, + -0.434273;0.868349;-0.239535;, + -0.989261;0.138490;-0.046722;, + -0.984781;0.061328;-0.162622;, + -0.986179;0.140164;0.088351;, + -0.977952;0.018441;0.208015;, + 0.000005;-0.999974;0.007152;, + -0.897582;0.211412;-0.386848;, + -0.460194;0.616751;0.638623;, + 0.693967;0.242883;0.677803;, + -0.905288;0.176534;0.386380;, + -0.664851;0.117356;-0.737700;, + -0.897582;0.211412;-0.386848;, + -0.903847;0.420928;-0.076682;, + -0.701860;0.270507;0.658953;, + -0.457101;-0.023022;-0.889117;, + 0.000001;0.024616;-0.999697;, + -0.226499;-0.140193;-0.963869;, + 0.387797;0.626448;0.676148;, + 0.485631;0.575618;0.657895;, + 0.783381;0.503370;0.364599;, + -0.867052;0.137579;0.478846;, + -0.829671;0.408671;0.380308;, + -0.892567;0.378889;-0.244475;, + -0.886549;0.392710;-0.244562;, + -0.947696;-0.212901;-0.237792;, + -0.502434;-0.677413;0.537282;, + -0.044908;-0.611148;0.790241;, + -0.336341;-0.108795;0.935435;, + -0.899773;0.187812;0.393873;, + -0.898020;0.299543;-0.322233;, + 0.433214;-0.193877;-0.880192;, + 0.859652;-0.309116;-0.406751;, + 0.100417;0.338390;0.935633;, + 0.100417;0.338390;0.935633;, + -0.244564;-0.065106;0.967445;, + 0.963334;-0.094433;0.251137;, + 0.885448;-0.301099;-0.354007;, + 0.990082;-0.015546;-0.139630;, + 0.957347;-0.288570;0.014659;, + 0.982279;-0.089104;-0.164890;, + 0.481298;0.876550;-0.003471;, + 0.895650;-0.343271;-0.282799;, + -0.527840;-0.168309;0.832500;, + -0.513833;-0.494239;0.701216;, + -0.233305;-0.886660;0.399253;, + -0.278232;-0.273728;0.920684;, + 0.790963;-0.525076;0.314122;, + -0.853727;-0.007027;-0.520673;, + 0.145665;-0.919602;-0.364848;, + 0.701248;-0.651828;-0.288742;, + -0.854773;-0.403493;0.326429;, + -0.174039;-0.984266;0.030518;, + -0.114791;-0.948135;-0.296417;, + -0.244564;-0.065106;0.967445;, + -0.026768;-0.438717;0.898227;, + 0.817874;-0.539381;-0.200374;, + 0.990082;-0.015546;-0.139630;, + 0.990082;-0.015546;-0.139630;, + 0.817874;-0.539381;-0.200374;, + -0.174039;-0.984266;0.030518;, + 0.434273;0.868349;-0.239535;, + 0.990910;0.129582;-0.036136;, + 0.987185;0.081535;-0.137175;, + 0.972924;0.196620;0.121487;, + 0.972307;0.015440;0.233196;, + 0.897582;0.211412;-0.386848;, + -0.602846;0.290303;0.743169;, + 0.905288;0.176534;0.386380;, + 0.664851;0.117356;-0.737700;, + 0.897582;0.211412;-0.386848;, + 0.903847;0.420928;-0.076682;, + 0.701860;0.270507;0.658953;, + 0.457101;-0.023022;-0.889117;, + 0.226504;-0.140193;-0.963868;, + -0.439283;0.626634;0.643708;, + -0.559324;0.693597;0.453961;, + -0.710934;0.444973;0.544584;, + 0.867052;0.137579;0.478846;, + 0.829671;0.408671;0.380308;, + 0.892567;0.378889;-0.244475;, + 0.886549;0.392710;-0.244561;, + 0.947696;-0.212901;-0.237792;, + 0.502434;-0.677413;0.537282;, + 0.044907;-0.611148;0.790241;, + 0.336341;-0.108795;0.935435;, + 0.899773;0.187812;0.393873;, + 0.898020;0.299543;-0.322233;, + -0.550598;-0.834581;0.017782;, + -0.920508;0.371208;0.121944;, + -0.986678;0.148934;0.065464;, + -0.872109;0.095397;-0.479922;, + 0.968704;-0.213268;-0.126998;, + 0.935445;-0.035033;-0.351732;, + 0.368870;0.664338;0.650069;, + 0.215407;0.452689;0.865259;, + 0.453303;-0.497746;0.739435;, + 0.521055;-0.809078;0.271835;, + 0.735182;-0.666684;0.122637;, + 0.821914;-0.569537;-0.009215;, + 0.759558;-0.443873;-0.475446;, + -0.657196;-0.390140;-0.644891;, + -0.809310;-0.499093;-0.309716;, + -0.707861;-0.682627;-0.181530;, + -0.757874;-0.650275;-0.052618;, + -0.565959;-0.798793;0.204013;, + -0.572197;-0.246884;0.782073;, + -0.572197;-0.246884;0.782073;, + 0.453303;-0.497746;0.739435;, + -0.520474;0.526586;0.672171;, + 0.798460;-0.602012;-0.006594;, + 0.954242;-0.257523;0.152001;, + 0.918662;-0.341700;0.198244;, + -0.995822;0.066694;-0.062372;, + -0.984728;-0.003402;0.174069;, + 0.968707;-0.002938;-0.248189;, + 0.954651;-0.166315;-0.246941;, + -0.000076;-0.461661;-0.887057;, + 0.965909;-0.084351;-0.244754;, + -0.972281;0.214777;-0.092415;, + 0.956895;-0.080204;0.279139;, + -0.381353;0.920775;0.082119;, + 0.999321;0.028755;-0.023042;, + -0.673865;0.641908;0.365869;, + -0.705742;-0.122863;0.697734;, + -0.960352;-0.063982;-0.271348;, + 0.566503;-0.333624;0.753505;, + 0.059122;-0.098574;-0.993372;, + 0.059122;-0.098574;-0.993372;, + 0.039464;-0.745272;-0.665591;, + -0.354476;-0.066564;0.932693;, + 0.181561;-0.108135;0.977416;, + 0.705192;-0.523353;0.478336;, + 0.734833;-0.590132;0.334314;, + 0.703206;-0.672001;-0.232197;, + 0.318223;-0.742396;-0.589561;, + -0.868967;-0.391802;-0.302304;, + -0.911357;-0.405828;0.068791;, + 0.353830;-0.592859;-0.723410;, + 0.039464;-0.745272;-0.665591;, + 0.566503;-0.333624;0.753505;, + -0.804425;-0.481755;0.347580;, + -0.705742;-0.122863;0.697734;, + -0.212265;-0.554761;-0.804478;, + -0.300497;-0.671647;-0.677194;, + 0.909177;-0.368835;-0.193282;, + -0.507519;-0.687744;-0.519069;, + -0.955392;-0.286491;-0.071754;, + 0.738914;-0.651028;0.173689;, + 0.982818;-0.144272;-0.115132;, + -0.539943;-0.790977;-0.287777;, + 0.365426;-0.280297;0.887636;, + 0.666223;-0.143179;0.731879;, + 0.313056;0.378120;0.871219;, + -0.400237;0.683181;0.610798;, + 0.639689;-0.061333;0.766183;, + -0.557613;-0.562556;0.610408;, + 0.152980;0.089858;-0.984136;, + -0.289534;0.030294;-0.956688;, + -0.381353;0.920775;0.082119;, + -0.421748;0.283560;-0.861233;, + -0.539943;-0.790977;-0.287777;, + -0.425702;-0.452816;-0.783413;, + -0.960352;-0.063982;-0.271348;, + 0.954242;-0.257523;0.152001;, + -0.537797;0.842499;0.031136;, + -0.545698;-0.837393;0.031400;, + -0.520441;-0.817752;0.245812;, + -0.037200;-0.353239;-0.934793;, + -0.311030;-0.795975;-0.519312;, + -0.790481;-0.221084;-0.571194;, + -0.597714;-0.523944;0.606812;, + -0.264462;-0.862138;0.432178;, + -0.550598;-0.834581;0.017782;, + -0.550598;-0.834581;0.017782;, + -0.275159;-0.572461;0.772383;, + -0.314707;0.781987;-0.538011;, + -0.000538;0.773627;-0.633641;, + -0.162744;0.615741;0.770959;, + -0.559206;0.508717;0.654596;, + -0.449270;0.893379;-0.005605;, + -0.449270;0.893379;-0.005605;, + 0.000168;0.854980;0.518661;, + -0.162744;0.615741;0.770959;, + -0.530614;0.817949;0.222282;, + -0.520441;-0.817752;0.245812;, + 0.000147;-0.426759;0.904366;, + -0.877145;-0.439089;0.194469;, + 1.000000;-0.000000;0.000000;, + 1.000000;-0.000000;0.000000;, + 1.000000;-0.000000;0.000000;, + 0.955485;-0.120740;-0.269203;, + -0.945620;0.026607;-0.324184;, + -0.995610;0.037774;-0.085641;, + -0.908432;0.107750;-0.403908;, + 0.992661;-0.000187;-0.120932;, + 0.990528;-0.094784;-0.099347;, + 0.992970;-0.002293;0.118346;, + -0.906954;0.117975;-0.404371;, + 0.000005;-0.908853;-0.417117;, + 0.920508;0.371208;0.121944;, + 0.550599;-0.834580;0.017784;, + 0.986678;0.148934;0.065464;, + 0.872109;0.095396;-0.479922;, + -0.968704;-0.213269;-0.126998;, + -0.935445;-0.035034;-0.351733;, + -0.368870;0.664338;0.650069;, + -0.215408;0.452689;0.865258;, + -0.453304;-0.497746;0.739435;, + -0.521055;-0.809078;0.271836;, + -0.735182;-0.666684;0.122637;, + -0.821914;-0.569537;-0.009216;, + -0.759558;-0.443871;-0.475447;, + 0.657196;-0.390140;-0.644891;, + 0.809310;-0.499092;-0.309716;, + 0.707861;-0.682627;-0.181531;, + 0.757874;-0.650275;-0.052618;, + 0.565958;-0.798793;0.204014;, + 0.572196;-0.246884;0.782074;, + 0.572196;-0.246884;0.782074;, + -0.453304;-0.497746;0.739435;, + 0.520473;0.526586;0.672172;, + -0.798459;-0.602012;-0.006595;, + -0.954242;-0.257523;0.152001;, + -0.918662;-0.341700;0.198244;, + 0.984728;-0.003402;0.174069;, + 0.995822;0.066694;-0.062372;, + -0.968707;-0.002938;-0.248190;, + -0.954652;-0.166280;-0.246961;, + -0.965909;-0.084351;-0.244754;, + 0.972281;0.214776;-0.092415;, + -0.956895;-0.080204;0.279139;, + 0.381356;0.920774;0.082120;, + -0.999321;0.028755;-0.023042;, + 0.673864;0.641909;0.365870;, + 0.705738;-0.122868;0.697737;, + 0.960352;-0.063982;-0.271348;, + -0.059122;-0.098573;-0.993372;, + -0.059122;-0.098573;-0.993372;, + -0.039462;-0.745268;-0.665596;, + 0.354475;-0.066564;0.932693;, + -0.181560;-0.108135;0.977416;, + -0.705199;-0.523347;0.478333;, + -0.734835;-0.590129;0.334313;, + -0.703206;-0.672002;-0.232196;, + -0.318224;-0.742397;-0.589560;, + 0.868969;-0.391799;-0.302303;, + 0.911362;-0.405818;0.068789;, + -0.353826;-0.592860;-0.723412;, + -0.039462;-0.745268;-0.665596;, + -0.566507;-0.333623;0.753502;, + 0.804429;-0.481751;0.347578;, + 0.705738;-0.122868;0.697737;, + 0.212267;-0.554751;-0.804484;, + 0.300504;-0.671641;-0.677197;, + -0.909176;-0.368837;-0.193284;, + 0.507518;-0.687743;-0.519071;, + 0.955392;-0.286490;-0.071755;, + -0.738915;-0.651028;0.173686;, + -0.982818;-0.144272;-0.115132;, + 0.539944;-0.790977;-0.287776;, + -0.365426;-0.280297;0.887636;, + -0.666223;-0.143179;0.731879;, + -0.313056;0.378120;0.871218;, + 0.400237;0.683181;0.610797;, + -0.639690;-0.061333;0.766182;, + 0.557614;-0.562555;0.610409;, + -0.152979;0.089859;-0.984136;, + 0.289534;0.030294;-0.956688;, + 0.381356;0.920774;0.082120;, + 0.421748;0.283560;-0.861233;, + 0.539944;-0.790977;-0.287776;, + 0.425700;-0.452817;-0.783413;, + 0.960352;-0.063982;-0.271348;, + -0.954242;-0.257523;0.152001;, + -0.566507;-0.333623;0.753502;, + 0.545698;-0.837393;0.031400;, + 0.557573;0.829476;0.032896;, + 0.520501;-0.817725;0.245773;, + 0.037200;-0.353240;-0.934793;, + 0.311029;-0.795977;-0.519309;, + 0.790480;-0.221084;-0.571194;, + 0.597714;-0.523943;0.606812;, + 0.264462;-0.862137;0.432180;, + 0.550599;-0.834580;0.017784;, + 0.550599;-0.834580;0.017784;, + 0.275160;-0.572458;0.772385;, + 0.309521;0.783229;-0.539212;, + 0.162598;0.616218;0.770608;, + 0.566570;0.495981;0.658028;, + 0.481298;0.876550;-0.003471;, + 0.481298;0.876550;-0.003471;, + 0.530646;0.817913;0.222337;, + 0.162598;0.616218;0.770608;, + 0.520501;-0.817725;0.245773;, + 0.877144;-0.439088;0.194473;, + -0.955485;-0.120740;-0.269203;, + 0.945620;0.026607;-0.324184;, + 0.995610;0.037774;-0.085641;, + 0.908432;0.107750;-0.403908;, + -0.992661;-0.000187;-0.120933;, + -0.990528;-0.094784;-0.099347;, + -0.992970;-0.002293;0.118346;, + 0.906954;0.117975;-0.404371;, + 0.448693;0.679150;0.580886;, + 0.987197;-0.118160;-0.107142;, + 0.207701;-0.604118;-0.769351;, + 0.529914;-0.324726;-0.783418;, + 0.955178;-0.252865;0.153929;, + 0.987197;-0.118160;-0.107142;, + -0.160126;0.190092;-0.968620;, + 0.006566;0.677354;0.735628;, + 0.068168;0.237165;0.969075;, + 0.423190;-0.716621;-0.554404;, + 0.657416;-0.744773;-0.114531;, + 0.509538;-0.839165;-0.190193;, + -0.234676;0.256475;0.937629;, + -0.834983;0.264476;-0.482552;, + -0.527039;0.781296;-0.334374;, + -0.473718;0.414055;-0.777271;, + -0.160126;0.190092;-0.968620;, + -0.228376;-0.127237;-0.965223;, + -0.839542;-0.269781;-0.471581;, + -0.675963;0.077412;-0.732858;, + -0.963227;0.157435;-0.217736;, + -0.259132;0.699308;-0.666197;, + -0.527039;0.781296;-0.334374;, + -0.422834;0.836078;-0.349551;, + -0.228376;-0.127237;-0.965223;, + -0.641365;-0.305210;-0.703916;, + -0.963227;0.157435;-0.217736;, + 0.897041;0.033289;-0.440692;, + -0.146089;-0.981553;0.123336;, + 0.034059;-0.236374;-0.971065;, + -0.520041;-0.156983;0.839592;, + -0.353633;-0.752104;0.556133;, + -0.898012;0.382182;0.217971;, + -0.234676;0.256475;0.937629;, + 0.509538;-0.839165;-0.190193;, + 0.295362;0.740439;0.603748;, + -0.234676;0.256475;0.937629;, + -0.318398;0.686232;0.653995;, + 0.634338;-0.406257;-0.657701;, + -0.286418;0.500490;0.816991;, + 0.450770;-0.364624;-0.814773;, + 0.509538;-0.839165;-0.190193;, + 0.914801;0.309243;0.259824;, + -0.578072;-0.401336;0.710466;, + 0.963480;0.174780;-0.202875;, + 0.916931;0.363083;0.165554;, + 0.970183;-0.159926;0.182121;, + 0.034059;-0.236374;-0.971065;, + 0.126855;0.710394;-0.692277;, + 0.034059;-0.236374;-0.971065;, + -0.828231;-0.560343;0.007058;, + -0.156866;-0.502085;-0.850473;, + -0.898012;0.382182;0.217971;, + -0.898012;0.382182;0.217971;, + 0.426128;-0.774572;-0.467389;, + 0.396048;-0.852920;0.340107;, + -0.039929;-0.807710;-0.588227;, + 0.303641;-0.441458;-0.844344;, + -0.039929;-0.807710;-0.588227;, + -0.472468;0.843730;0.254742;, + 0.489036;0.859909;-0.146290;, + 0.568943;-0.193580;-0.799269;, + -0.472468;0.843730;0.254742;, + -0.896153;0.443634;0.009920;, + 0.826841;-0.523263;-0.206226;, + 0.500952;0.279713;0.819029;, + -0.205138;-0.005818;0.978716;, + -0.469045;0.851012;0.236169;, + -0.502437;0.667098;0.550034;, + 0.780352;-0.359300;-0.511814;, + -0.506181;0.569758;0.647422;, + 0.780352;-0.359300;-0.511814;, + -0.268806;-0.896766;-0.351502;, + -0.129004;-0.984436;0.119344;, + 0.915472;-0.398064;-0.058788;, + -0.343908;0.401841;0.848676;, + 0.777616;-0.116615;0.617830;, + 0.507759;-0.548313;-0.664480;, + -0.257983;0.544602;0.798031;, + -0.362576;0.544444;0.756386;, + 0.538295;-0.631424;-0.558159;, + 0.725324;-0.198324;0.659221;, + -0.276717;0.544754;0.791625;, + 0.456380;-0.580050;-0.674729;, + -0.464359;0.605477;0.646350;, + 0.314063;-0.536259;-0.783448;, + -0.470908;0.619311;0.628251;, + 0.329202;-0.554979;-0.763953;, + -0.242430;0.521770;0.817914;, + 0.488072;-0.623641;-0.610621;, + -0.339070;0.554869;0.759705;, + 0.450906;-0.603711;-0.657432;, + -0.560979;0.636505;0.529305;, + 0.229922;-0.482476;-0.845194;, + -0.480825;0.612885;0.627040;, + 0.327893;-0.527492;-0.783734;, + -0.130859;0.472769;0.871416;, + 0.582448;-0.641920;-0.498692;, + 0.114891;0.475550;0.872154;, + 0.738199;-0.672946;-0.046963;, + 0.654098;0.265568;0.708258;, + 0.788837;-0.361752;0.496862;, + -0.263126;0.546005;0.795389;, + 0.497233;-0.613394;-0.613602;, + 0.715283;-0.213463;0.665435;, + -0.306469;0.543138;0.781715;, + 0.446317;-0.594873;-0.668526;, + -0.452795;0.600684;0.658905;, + 0.308543;-0.543003;-0.780992;, + -0.456215;0.614991;0.643159;, + 0.335867;-0.559796;-0.757510;, + -0.263346;0.532405;0.804484;, + 0.471488;-0.618541;-0.628574;, + -0.345261;0.558515;0.754225;, + 0.439782;-0.600782;-0.667573;, + -0.537976;0.628508;0.561747;, + 0.252684;-0.497453;-0.829875;, + -0.467237;0.607846;0.642038;, + 0.333904;-0.534319;-0.776538;, + -0.165833;0.490715;0.855393;, + 0.554845;-0.638321;-0.533566;, + 0.068015;0.505465;0.860162;, + 0.701497;-0.701342;-0.126576;, + 0.636095;0.307826;0.707549;, + 0.782976;-0.407275;0.470186;, + -0.265565;0.544402;0.795677;, + 0.501872;-0.611244;-0.611969;, + 0.730965;-0.293094;0.616268;, + -0.292472;0.536722;0.791448;, + 0.440673;-0.592878;-0.674020;, + -0.447421;0.598812;0.664258;, + 0.294817;-0.536769;-0.790545;, + -0.451790;0.613142;0.648030;, + 0.324769;-0.553847;-0.766667;, + -0.247760;0.524381;0.814641;, + 0.467816;-0.617010;-0.632809;, + -0.334234;0.553031;0.763180;, + 0.434085;-0.598441;-0.673379;, + -0.537145;0.628597;0.562442;, + 0.236650;-0.488015;-0.840142;, + -0.462849;0.606173;0.646780;, + 0.323287;-0.527601;-0.785571;, + -0.146317;0.479991;0.864985;, + 0.555697;-0.637603;-0.533538;, + 0.090407;0.490418;0.866785;, + 0.709732;-0.695413;-0.112611;, + 0.646355;0.289593;0.705947;, + 0.787167;-0.396002;0.472811;, + -0.212404;0.516342;0.829624;, + 0.516966;-0.608447;-0.602112;, + -0.215861;0.514387;0.829946;, + 0.400936;-0.557240;-0.727141;, + -0.409694;0.584477;0.700383;, + 0.255763;-0.507343;-0.822915;, + -0.416769;0.599193;0.683573;, + 0.271222;-0.525963;-0.806102;, + -0.182521;0.489258;0.852827;, + 0.434921;-0.604440;-0.667455;, + -0.280896;0.526446;0.802466;, + 0.395442;-0.582473;-0.710176;, + -0.512610;0.622446;0.591432;, + 0.170371;-0.449244;-0.877014;, + -0.427834;0.592777;0.682329;, + 0.271016;-0.497964;-0.823761;, + 0.892887;0.164047;-0.419335;, + -0.071795;0.436064;0.897047;, + 0.535967;-0.630109;-0.561873;, + 0.170183;0.433298;0.885037;, + 0.717370;-0.686582;-0.118260;, + 0.689840;0.223648;0.688551;, + 0.804020;-0.394183;0.445166;, + -0.588806;0.000143;0.808275;, + -0.886836;0.434833;0.156336;, + 0.226188;-0.397375;0.889344;, + 0.313446;0.294967;0.902633;, + -0.123513;0.634708;0.762817;, + 0.396692;0.282270;-0.873475;, + -0.557305;-0.389761;0.733143;, + 0.964289;0.264843;-0.002032;, + 0.506951;-0.238596;0.828295;, + 0.506951;-0.238596;0.828295;, + -0.957604;-0.179816;-0.225078;, + -0.529914;-0.324726;-0.783418;, + -0.148924;-0.632604;-0.760022;, + -0.994196;0.051821;0.094280;, + -0.871225;-0.451441;0.192789;, + 0.160126;0.190092;-0.968620;, + -0.006566;0.677353;0.735628;, + -0.057386;0.245516;0.967692;, + -0.657416;-0.744773;-0.114531;, + -0.423190;-0.716621;-0.554404;, + -0.509830;-0.838926;-0.190465;, + 0.391442;0.389355;0.833772;, + 0.834983;0.264476;-0.482552;, + 0.527039;0.781296;-0.334374;, + 0.473718;0.414055;-0.777271;, + 0.160126;0.190092;-0.968620;, + 0.228376;-0.127237;-0.965223;, + 0.839542;-0.269781;-0.471581;, + 0.675963;0.077412;-0.732859;, + 0.963227;0.157435;-0.217736;, + 0.259132;0.699308;-0.666198;, + 0.422834;0.836078;-0.349550;, + 0.527039;0.781296;-0.334374;, + 0.641365;-0.305210;-0.703916;, + 0.228376;-0.127237;-0.965223;, + 0.963227;0.157435;-0.217736;, + -0.897162;0.033159;-0.440455;, + 0.146090;-0.981553;0.123336;, + -0.034059;-0.236375;-0.971065;, + 0.520040;-0.156982;0.839592;, + 0.353633;-0.752104;0.556133;, + 0.391442;0.389355;0.833772;, + 0.653620;0.114523;0.748107;, + 0.520040;-0.156982;0.839592;, + -0.509830;-0.838926;-0.190465;, + -0.190416;0.835663;0.515178;, + 0.438815;0.143443;0.887054;, + 0.898012;0.382183;0.217970;, + -0.634338;-0.406257;-0.657701;, + -0.451041;-0.364729;-0.814576;, + -0.509830;-0.838926;-0.190465;, + -0.607672;0.793048;-0.042537;, + 0.578072;-0.401336;0.710466;, + -0.964421;0.191784;-0.181966;, + -0.881035;0.426148;0.205365;, + -0.980241;-0.139652;0.140090;, + -0.034059;-0.236375;-0.971065;, + -0.126856;0.710394;-0.692277;, + -0.034059;-0.236375;-0.971065;, + 0.828231;-0.560342;0.007058;, + 0.156866;-0.502085;-0.850473;, + 0.898012;0.382183;0.217970;, + 0.898012;0.382183;0.217970;, + -0.667053;-0.649082;0.365696;, + -0.492298;-0.784288;-0.377538;, + -0.494156;0.758623;-0.424618;, + 0.063298;-0.757803;-0.649405;, + 0.063298;-0.757803;-0.649405;, + 0.505009;0.836271;0.213581;, + -0.552096;-0.122315;-0.824760;, + 0.505009;0.836271;0.213581;, + 0.894433;0.447026;-0.012553;, + -0.823845;-0.530391;-0.199912;, + -0.489616;0.263036;0.831317;, + 0.188469;-0.005536;0.982064;, + 0.475166;0.851493;0.221757;, + 0.500593;0.666086;0.552935;, + -0.774625;-0.362944;-0.517907;, + 0.498824;0.566633;0.655822;, + -0.913491;-0.404743;-0.041435;, + 0.338248;0.393374;0.854895;, + -0.765877;-0.131961;0.629300;, + -0.499148;-0.545190;-0.673512;, + -0.714900;-0.212902;0.666026;, + -0.857968;0.149295;-0.491531;, + 0.351827;0.537583;0.766305;, + 0.247538;0.533303;0.808896;, + -0.533434;-0.631638;-0.562567;, + 0.266062;0.534893;0.801936;, + -0.447982;-0.577196;-0.682757;, + 0.457685;0.602796;0.653575;, + -0.302952;-0.528059;-0.793330;, + 0.464637;0.616931;0.635224;, + -0.320375;-0.545709;-0.774314;, + 0.231555;0.510140;0.828335;, + -0.482310;-0.621551;-0.617294;, + 0.330057;0.546220;0.769874;, + -0.443595;-0.600833;-0.664998;, + 0.557674;0.637189;0.531969;, + -0.218196;-0.468925;-0.855862;, + 0.475036;0.610817;0.633438;, + -0.320194;-0.517249;-0.793681;, + 0.120529;0.460012;0.879694;, + -0.579460;-0.642332;-0.501632;, + -0.117801;0.461501;0.879284;, + -0.737915;-0.674242;-0.029655;, + -0.649761;0.259288;0.714549;, + -0.783249;-0.356084;0.509632;, + 0.252546;0.535085;0.806166;, + -0.490701;-0.611734;-0.620479;, + -0.703251;-0.226621;0.673855;, + 0.295401;0.533999;0.792201;, + -0.438220;-0.592052;-0.676341;, + 0.445511;0.597421;0.666789;, + -0.297424;-0.534529;-0.791086;, + 0.449368;0.612043;0.650747;, + -0.326742;-0.550893;-0.767956;, + 0.252472;0.521534;0.815021;, + -0.465089;-0.615834;-0.635956;, + 0.335949;0.550139;0.764517;, + -0.432019;-0.597419;-0.675611;, + 0.533739;0.628202;0.566114;, + -0.240978;-0.484831;-0.840755;, + 0.460786;0.605148;0.649209;, + -0.325458;-0.524380;-0.786831;, + 0.154787;0.478816;0.864162;, + -0.550996;-0.638131;-0.537766;, + -0.072427;0.492303;0.867406;, + -0.702169;-0.703184;-0.111764;, + -0.633977;0.303269;0.711408;, + -0.780241;-0.399104;0.481601;, + 0.254891;0.533546;0.806448;, + -0.495277;-0.609732;-0.618812;, + -0.721934;-0.308194;0.619538;, + 0.281251;0.527055;0.801942;, + -0.432483;-0.589889;-0.681901;, + 0.440073;0.595333;0.672246;, + -0.283571;-0.527836;-0.800610;, + 0.444854;0.609993;0.655754;, + -0.315564;-0.544433;-0.777182;, + 0.236801;0.512915;0.825133;, + -0.461342;-0.614098;-0.640349;, + 0.324837;0.544170;0.773537;, + -0.426219;-0.594861;-0.681526;, + 0.532960;0.628250;0.566794;, + -0.224869;-0.474782;-0.850891;, + 0.456355;0.603310;0.654031;, + -0.314900;-0.517199;-0.795828;, + 0.135489;0.467543;0.873525;, + -0.551857;-0.637341;-0.537819;, + -0.094199;0.476771;0.873966;, + -0.710203;-0.697232;-0.097362;, + -0.643422;0.284541;0.710665;, + -0.783588;-0.388614;0.484736;, + 0.201577;0.503110;0.840385;, + -0.510465;-0.607468;-0.608611;, + 0.204883;0.502219;0.840119;, + -0.391192;-0.551987;-0.736396;, + 0.401612;0.579399;0.709228;, + -0.244152;-0.497096;-0.832638;, + 0.408987;0.594527;0.692291;, + -0.261639;-0.514291;-0.816731;, + 0.171512;0.475490;0.862840;, + -0.427611;-0.599957;-0.676166;, + 0.271095;0.515384;0.812949;, + -0.386791;-0.577398;-0.719030;, + 0.507899;0.621019;0.596970;, + -0.158619;-0.433804;-0.886935;, + 0.420631;0.588517;0.690447;, + -0.262650;-0.485562;-0.833813;, + 0.062071;0.421776;0.904573;, + -0.531432;-0.628929;-0.567476;, + -0.171508;0.418312;0.891964;, + -0.717453;-0.688923;-0.103178;, + -0.684430;0.217897;0.695756;, + -0.798889;-0.388529;0.459153;, + 0.563755;-0.000870;0.825942;, + 0.886836;0.434833;0.156336;, + -0.202243;-0.425807;0.881922;, + 0.166307;0.647301;0.743870;, + -0.301252;0.328615;0.895131;, + 0.549353;-0.390720;0.738613;, + -0.944779;0.327439;0.013305;, + -0.529409;-0.220751;0.819143;, + -0.529409;-0.220751;0.819143;, + 0.214009;0.839435;0.499548;, + 0.774218;0.487454;0.403702;, + -0.957604;-0.179816;-0.225078;, + -0.169599;0.852875;0.493802;, + 0.343698;0.922858;0.173795;, + 0.485631;0.575618;0.657895;, + -0.260653;0.953967;0.148347;, + 0.055097;0.933688;0.353823;, + -0.559324;0.693597;0.453961;, + -0.540286;0.724558;-0.427911;, + -0.496164;0.335976;-0.800588;, + -0.540286;0.724558;-0.427911;, + -0.654263;-0.049613;-0.754638;, + -0.496164;0.335976;-0.800588;, + -0.540286;0.724558;-0.427911;, + -0.540286;0.724558;-0.427911;, + -0.654263;-0.049613;-0.754638;, + -0.654263;-0.049613;-0.754638;, + -0.563708;-0.395781;-0.724976;, + -0.235609;0.971832;-0.005539;, + -0.284112;0.944212;0.166567;, + -0.232970;0.970399;0.063643;, + -0.302341;0.947980;-0.099615;, + -0.793812;0.600245;-0.097818;, + -0.000001;0.818760;0.574136;, + 0.382016;0.040071;0.923286;, + -0.000000;-0.444151;0.895952;, + 0.012819;0.940525;0.339483;, + -0.394637;-0.137254;0.908528;, + -0.231714;-0.275342;0.933003;, + -0.432713;-0.354931;0.828724;, + -0.733140;-0.437535;0.520643;, + -0.944986;-0.217661;0.244183;, + -0.965289;-0.090055;-0.245168;, + -0.404283;-0.450662;0.795902;, + -0.944986;-0.217661;0.244183;, + -0.432713;-0.354931;0.828724;, + -0.886311;0.419497;-0.196151;, + -0.232970;0.970399;0.063643;, + -0.235609;0.971832;-0.005539;, + -0.899678;-0.251384;-0.356911;, + -0.496164;0.335976;-0.800588;, + -0.984181;0.095585;0.149171;, + -0.899678;-0.251384;-0.356911;, + -0.534104;0.546724;-0.644846;, + -0.540286;0.724558;-0.427911;, + -0.899678;-0.251384;-0.356911;, + -0.806852;-0.393759;-0.440389;, + -0.563708;-0.395781;-0.724976;, + -0.000000;0.298174;-0.954511;, + -0.654263;-0.049613;-0.754638;, + -0.654263;-0.049613;-0.754638;, + -0.000000;0.298174;-0.954511;, + -0.929825;-0.231328;0.286203;, + -0.861728;0.431543;-0.266824;, + -0.793812;0.600245;-0.097818;, + -0.000000;0.630324;-0.776332;, + -0.534104;0.546724;-0.644846;, + -0.899678;-0.251384;-0.356911;, + -0.861728;0.431543;-0.266824;, + -0.000000;-0.029730;-0.999558;, + -0.927251;-0.170149;-0.333550;, + -0.534104;0.546724;-0.644846;, + -0.927251;-0.170149;-0.333550;, + -0.422789;0.519154;-0.742784;, + -0.000000;0.998500;0.054759;, + 0.014166;0.945681;-0.324786;, + -0.000000;0.998500;0.054759;, + -0.534104;0.546724;-0.644846;, + -0.861728;0.431543;-0.266824;, + -0.699443;-0.209423;-0.683316;, + -0.178300;-0.323577;-0.929251;, + -0.691836;-0.542995;-0.475940;, + -0.178300;-0.323577;-0.929251;, + -0.937849;0.041613;0.344540;, + -0.861728;0.431543;-0.266824;, + -0.879018;0.070016;-0.471619;, + -0.793812;0.600245;-0.097818;, + -0.701635;0.645253;-0.302255;, + -0.944986;-0.217661;0.244183;, + -0.000000;0.998500;0.054759;, + -0.000000;0.868934;-0.494927;, + -0.540286;0.724558;-0.427911;, + -0.000000;-0.029730;-0.999558;, + -0.000000;0.630324;-0.776332;, + -0.496164;0.335976;-0.800588;, + -0.496164;0.335976;-0.800588;, + -0.899678;-0.251384;-0.356911;, + -0.654263;-0.049613;-0.754638;, + -0.793812;0.600245;-0.097818;, + -0.861728;0.431543;-0.266824;, + -0.899678;-0.251384;-0.356911;, + -0.000000;0.998500;0.054759;, + -0.691836;-0.542995;-0.475940;, + -0.563708;-0.395781;-0.724976;, + -0.806852;-0.393759;-0.440389;, + -0.559606;-0.645175;-0.520183;, + -0.000000;0.998500;0.054759;, + 0.540286;0.724558;-0.427911;, + -0.000000;0.630324;-0.776332;, + 0.496164;0.335976;-0.800588;, + 0.540286;0.724558;-0.427911;, + 0.654263;-0.049613;-0.754638;, + 0.496164;0.335976;-0.800588;, + 0.540286;0.724558;-0.427911;, + 0.540286;0.724558;-0.427911;, + -0.000000;0.868934;-0.494927;, + 0.654263;-0.049613;-0.754638;, + -0.000000;0.298174;-0.954511;, + 0.654263;-0.049613;-0.754638;, + 0.563708;-0.395781;-0.724976;, + 0.235609;0.971832;-0.005539;, + 0.232970;0.970399;0.063643;, + 0.284111;0.944212;0.166568;, + 0.886230;0.418543;-0.198540;, + 0.793812;0.600245;-0.097818;, + -0.382017;0.040070;0.923286;, + -0.012819;0.940525;0.339483;, + 0.231714;-0.275342;0.933003;, + 0.394636;-0.137254;0.908528;, + 0.432713;-0.354931;0.828724;, + 0.930868;-0.256053;0.260617;, + 0.965023;-0.089095;-0.246563;, + 0.732571;-0.437022;0.521873;, + 0.302341;0.947980;-0.099615;, + 0.232970;0.970399;0.063643;, + 0.235609;0.971832;-0.005539;, + 0.899678;-0.251384;-0.356911;, + 0.496164;0.335976;-0.800588;, + 0.899678;-0.251384;-0.356911;, + 0.553016;0.656553;-0.512944;, + 0.540286;0.724558;-0.427911;, + 0.899678;-0.251384;-0.356911;, + 0.836668;-0.377812;-0.396542;, + 0.563708;-0.395781;-0.724976;, + -0.000000;0.298174;-0.954511;, + 0.654263;-0.049613;-0.754638;, + 0.654263;-0.049613;-0.754638;, + -0.142878;-0.121955;-0.982198;, + -0.000000;0.298174;-0.954511;, + 0.930521;-0.221376;0.291758;, + 0.945515;0.306078;-0.110984;, + 0.924672;0.127786;0.358681;, + 0.793812;0.600245;-0.097818;, + -0.000000;0.630324;-0.776332;, + 0.553016;0.656553;-0.512944;, + -0.000000;-0.029730;-0.999558;, + 0.899678;-0.251384;-0.356911;, + 0.945515;0.306078;-0.110984;, + -0.000000;-0.029730;-0.999558;, + 0.932085;0.115972;-0.343175;, + -0.014166;0.945682;-0.324786;, + 0.553016;0.656553;-0.512944;, + 0.945515;0.306078;-0.110984;, + 0.490285;-0.201883;-0.847858;, + 0.366430;-0.311048;-0.876914;, + 0.642185;-0.647026;-0.411043;, + 0.366430;-0.311048;-0.876914;, + 0.940115;0.027121;0.339777;, + 0.945515;0.306078;-0.110984;, + 0.793812;0.600245;-0.097818;, + 0.879018;0.070016;-0.471619;, + 0.701635;0.645253;-0.302255;, + 0.930868;-0.256053;0.260617;, + -0.000000;0.998500;0.054759;, + -0.000000;0.868934;-0.494927;, + 0.540286;0.724558;-0.427911;, + -0.000000;-0.029730;-0.999558;, + -0.000000;0.630324;-0.776332;, + 0.496164;0.335976;-0.800588;, + 0.496164;0.335976;-0.800588;, + 0.899678;-0.251384;-0.356911;, + 0.654263;-0.049613;-0.754638;, + 0.793812;0.600245;-0.097818;, + -0.136274;0.884818;0.445562;, + -0.102555;-0.767205;-0.633151;, + 0.945515;0.306078;-0.110984;, + 0.899678;-0.251384;-0.356911;, + -0.000000;0.998500;0.054759;, + 0.642185;-0.647026;-0.411043;, + 0.563708;-0.395781;-0.724976;, + 0.836668;-0.377812;-0.396542;, + 0.559606;-0.645176;-0.520182;, + 0.836668;-0.377812;-0.396542;, + 0.642185;-0.647026;-0.411043;, + 0.403086;-0.867962;-0.290108;, + 0.373002;-0.795669;-0.477263;, + 0.558443;-0.699105;0.446535;, + 0.772381;-0.152248;0.616642;, + -0.833821;-0.284781;0.472909;, + -0.488240;-0.590800;0.642322;, + -0.337534;-0.853552;-0.396886;, + -0.607999;-0.786791;-0.106285;, + 0.077777;-0.993666;-0.081114;, + -0.091466;-0.994758;-0.045715;, + -0.178300;-0.323577;-0.929251;, + -0.142878;-0.121955;-0.982198;, + 0.366430;-0.311048;-0.876914;, + 0.260508;0.727642;-0.634565;, + -0.040453;0.710290;-0.702746;, + -0.588256;0.730768;-0.346313;, + -0.010918;-0.937228;0.348545;, + -0.238496;-0.799571;0.551186;, + 0.193201;-0.890421;0.412097;, + 0.014300;-0.847026;0.531360;, + -0.801728;-0.276819;0.529721;, + -0.615086;-0.386827;0.687047;, + -0.793967;-0.433457;0.426300;, + -0.745782;-0.452954;0.488509;, + -0.932337;-0.361278;-0.015029;, + -0.856324;-0.247040;-0.453521;, + -0.707919;-0.624087;-0.330705;, + -0.531094;-0.706015;-0.468489;, + -0.808123;-0.461550;-0.365936;, + -0.948825;-0.033448;0.314026;, + -0.930713;-0.092278;0.353918;, + -0.920811;-0.172908;0.349584;, + -0.916339;-0.265300;0.299899;, + -0.604821;-0.388772;-0.695017;, + -0.945731;0.117071;0.303128;, + -0.970327;0.034796;0.239279;, + -0.978433;-0.005143;0.206502;, + -0.861728;0.431543;-0.266824;, + -0.531997;-0.340199;0.775399;, + -0.689076;-0.199468;0.696697;, + -0.741015;0.256716;0.620479;, + -0.216517;0.601928;0.768637;, + -0.823955;0.147553;0.547108;, + -0.759279;0.153427;0.632421;, + -0.896238;-0.324230;0.302709;, + -0.280865;-0.155167;0.947121;, + -0.478361;-0.492783;0.726868;, + -0.124352;-0.098909;0.987296;, + -0.205252;0.312404;0.927510;, + -0.110123;-0.025715;0.993585;, + -0.937849;0.041613;0.344540;, + -0.929825;-0.231328;0.286203;, + -0.699443;-0.209423;-0.683316;, + -0.806852;-0.393759;-0.440389;, + -0.806852;-0.393759;-0.440389;, + -0.691836;-0.542995;-0.475940;, + -0.767636;-0.389543;-0.508912;, + -0.551796;-0.574616;-0.604431;, + -0.979289;0.016954;0.201754;, + -0.966193;0.076246;0.246286;, + -0.877724;-0.460197;-0.133489;, + -0.551796;-0.574616;-0.604431;, + -0.923625;-0.293416;-0.246623;, + -0.551796;-0.574616;-0.604431;, + -0.460194;0.616751;0.638623;, + -0.237549;0.171176;0.956174;, + -0.246128;0.432303;0.867488;, + -0.304277;-0.311038;0.900372;, + -0.207669;-0.717728;0.664635;, + -0.223441;-0.620814;0.751442;, + -0.371514;-0.104033;0.922580;, + -0.292418;0.016174;0.956154;, + -0.291101;0.296117;0.909711;, + -0.290228;0.134824;0.947413;, + 0.732447;-0.463382;0.498797;, + 0.823502;-0.420165;0.381189;, + 0.796203;-0.311752;0.518528;, + 0.557281;-0.410177;0.721937;, + 0.663539;-0.666241;-0.340352;, + 0.627769;-0.641265;-0.441233;, + 0.924341;-0.229764;-0.304633;, + 0.885166;-0.437540;-0.158241;, + 0.825383;-0.420119;-0.377152;, + 0.927430;-0.166498;0.334890;, + 0.916339;-0.265300;0.299899;, + 0.922761;-0.080766;0.376814;, + 0.959207;-0.033141;0.280754;, + 0.618095;-0.351774;-0.703004;, + 0.962843;0.019373;0.269367;, + 0.983531;0.088214;0.157748;, + 0.930868;-0.256053;0.260617;, + 0.432713;-0.354931;0.828724;, + 0.553016;0.656553;-0.512944;, + 0.945515;0.306078;-0.110984;, + 0.993793;-0.011471;0.110653;, + 0.479423;0.478311;0.735780;, + 0.781695;0.234974;0.577703;, + 0.679518;-0.160347;0.715922;, + 0.358587;-0.591042;0.722554;, + 0.819624;0.148430;0.553340;, + 0.781224;0.181945;0.597148;, + 0.891387;-0.329329;0.311403;, + 0.041593;0.020366;0.998927;, + 0.377267;-0.289994;0.879530;, + 0.105429;-0.086429;0.990664;, + 0.222570;0.434020;0.872977;, + 0.940115;0.027121;0.339777;, + 0.930521;-0.221376;0.291758;, + 0.629863;0.520365;-0.576622;, + 0.932085;0.115972;-0.343175;, + 0.490285;-0.201883;-0.847858;, + 0.836668;-0.377812;-0.396542;, + 0.836668;-0.377812;-0.396542;, + 0.642185;-0.647026;-0.411043;, + 0.551796;-0.574616;-0.604431;, + 0.831536;-0.420486;-0.362960;, + 0.551796;-0.574616;-0.604431;, + 0.955968;0.074254;0.283920;, + 0.992970;0.009011;0.118019;, + 0.872770;-0.467932;-0.138969;, + 0.831536;-0.420486;-0.362960;, + 0.448693;0.679150;0.580886;, + 0.218225;0.244375;0.944806;, + 0.291626;0.332066;0.897043;, + 0.323872;-0.438181;0.838513;, + 0.236939;-0.570878;0.786103;, + 0.298672;-0.579421;0.758332;, + 0.305557;-0.031119;0.951665;, + 0.302334;0.087757;0.949154;, + 0.249071;0.370670;0.894744;, + 0.278707;0.095201;0.955646;, + -0.305307;0.626286;0.717324;, + 0.313062;0.614710;0.723964;, + 0.404283;-0.450662;0.795902;, + 0.914875;-0.152402;-0.373869;, + -0.914875;-0.152402;-0.373869;; + 6841; + 3;28,62,1;, + 3;3,16,3420;, + 3;11,23,29;, + 3;104,69,7;, + 3;0,13,70;, + 3;9,97,96;, + 3;3421,71,2;, + 3;15,22,3;, + 3;3420,15,3;, + 3;68,4,15;, + 3;116,111,106;, + 3;3422,12,6;, + 3;6,12,1742;, + 3;24,14,12;, + 3;3423,108,119;, + 3;102,7,13;, + 3;13,30,23;, + 3;3420,2,15;, + 3;115,116,106;, + 3;100,3424,17;, + 3;100,1,3424;, + 3;1,18,19;, + 3;28,1,19;, + 3;104,94,69;, + 3;15,4,20;, + 3;98,8,97;, + 3;115,106,114;, + 3;29,23,126;, + 3;3422,24,12;, + 3;30,0,27;, + 3;26,11,29;, + 3;24,3422,3425;, + 3;27,126,23;, + 3;3426,3427,3428;, + 3;23,11,13;, + 3;13,0,30;, + 3;23,30,27;, + 3;108,107,120;, + 3;31,6,1741;, + 3;25,32,29;, + 3;32,26,29;, + 3;136,132,135;, + 3;32,25,65;, + 3;63,60,35;, + 3;3419,3429,63;, + 3;35,59,34;, + 3;58,59,16;, + 3;41,36,848;, + 3;51,53,49;, + 3;3430,55,49;, + 3;82,848,36;, + 3;24,38,14;, + 3;84,49,53;, + 3;81,82,43;, + 3;83,3431,39;, + 3;41,45,36;, + 3;40,3430,3432;, + 3;41,37,47;, + 3;24,52,48;, + 3;3430,49,84;, + 3;38,48,50;, + 3;38,24,48;, + 3;49,55,50;, + 3;50,51,49;, + 3;55,56,50;, + 3;48,51,50;, + 3;81,43,80;, + 3;67,54,3433;, + 3;39,66,44;, + 3;50,56,38;, + 3;3430,40,55;, + 3;56,57,38;, + 3;55,40,56;, + 3;56,436,57;, + 3;51,48,52;, + 3;3434,3435,3436;, + 3;3437,3438,3435;, + 3;3437,3439,3438;, + 3;33,3439,3437;, + 3;64,3440,3441;, + 3;3442,3443,33;, + 3;3440,3444,3445;, + 3;52,24,3425;, + 3;3434,3436,3446;, + 3;16,59,3420;, + 3;60,3420,59;, + 3;58,34,59;, + 3;60,3421,3420;, + 3;35,60,59;, + 3;61,27,0;, + 3;3447,61,3448;, + 3;28,3449,62;, + 3;3420,3421,2;, + 3;63,3429,3421;, + 3;3419,63,3450;, + 3;63,3421,60;, + 3;33,64,3442;, + 3;3450,63,35;, + 3;65,129,3447;, + 3;3434,3437,3435;, + 3;3444,42,3445;, + 3;3445,3441,3440;, + 3;39,3451,66;, + 3;3441,3442,64;, + 3;53,67,3433;, + 3;33,3443,3439;, + 3;2,68,15;, + 3;3452,3453,69;, + 3;70,13,7;, + 3;3421,3429,71;, + 3;0,70,73;, + 3;73,72,0;, + 3;7,69,75;, + 3;75,74,7;, + 3;3454,3455,77;, + 3;77,76,3454;, + 3;3453,3456,79;, + 3;79,78,3453;, + 3;70,7,74;, + 3;74,73,70;, + 3;69,3453,78;, + 3;78,75,69;, + 3;3456,3454,76;, + 3;76,79,3456;, + 3;3455,0,72;, + 3;72,77,3455;, + 3;80,43,3457;, + 3;43,82,44;, + 3;37,81,80;, + 3;44,82,83;, + 3;81,37,82;, + 3;44,83,39;, + 3;83,82,36;, + 3;3433,84,53;, + 3;83,36,3431;, + 3;3,22,85;, + 3;110,112,113;, + 3;22,89,85;, + 3;110,114,106;, + 3;95,118,111;, + 3;3447,128,61;, + 3;22,90,89;, + 3;110,113,114;, + 3;109,112,110;, + 3;90,22,91;, + 3;15,91,22;, + 3;15,92,91;, + 3;15,20,92;, + 3;92,20,93;, + 3;117,111,116;, + 3;3452,94,3458;, + 3;94,3452,69;, + 3;99,96,21;, + 3;111,117,95;, + 3;9,96,99;, + 3;1739,97,9;, + 3;97,8,21;, + 3;97,21,96;, + 3;10,98,97;, + 3;31,3422,6;, + 3;1741,6,1744;, + 3;88,99,845;, + 3;107,118,95;, + 3;18,100,17;, + 3;18,1,100;, + 3;101,102,13;, + 3;11,101,13;, + 3;119,108,120;, + 3;103,7,102;, + 3;107,121,120;, + 3;95,122,107;, + 3;107,123,121;, + 3;95,117,122;, + 3;107,122,123;, + 3;103,105,104;, + 3;103,104,7;, + 3;3459,5,106;, + 3;106,111,3459;, + 3;3423,3460,108;, + 3;3423,119,3461;, + 3;3462,3463,116;, + 3;116,115,3462;, + 3;3464,3465,122;, + 3;122,117,3464;, + 3;3466,3462,115;, + 3;115,114,3466;, + 3;107,108,3460;, + 3;3467,3468,113;, + 3;113,112,3467;, + 3;3469,3459,111;, + 3;111,118,3469;, + 3;3468,3466,114;, + 3;114,113,3468;, + 3;87,86,109;, + 3;109,110,87;, + 3;3463,3464,117;, + 3;117,116,3463;, + 3;3470,3469,118;, + 3;118,3471,3470;, + 3;3472,3461,119;, + 3;119,120,3472;, + 3;3473,3472,120;, + 3;120,121,3473;, + 3;3474,3473,121;, + 3;121,123,3474;, + 3;3465,3474,123;, + 3;123,122,3465;, + 3;65,25,124;, + 3;130,132,131;, + 3;127,126,27;, + 3;129,128,3447;, + 3;27,125,127;, + 3;29,126,25;, + 3;134,132,130;, + 3;130,133,134;, + 3;125,27,128;, + 3;128,27,61;, + 3;65,124,129;, + 3;131,132,136;, + 3;3475,3476,135;, + 3;135,132,3475;, + 3;3476,3477,136;, + 3;136,135,3476;, + 3;3478,3479,130;, + 3;130,131,3478;, + 3;3480,3481,134;, + 3;134,133,3480;, + 3;3481,3475,132;, + 3;132,134,3481;, + 3;3479,3480,133;, + 3;133,130,3479;, + 3;3477,3478,131;, + 3;131,136,3477;, + 3;158,138,184;, + 3;3,3482,16;, + 3;145,159,153;, + 3;221,143,191;, + 3;137,192,146;, + 3;144,214,215;, + 3;3483,139,193;, + 3;147,3,152;, + 3;3482,3,147;, + 3;190,147,140;, + 3;231,223,227;, + 3;3484,142,12;, + 3;142,1742,12;, + 3;154,12,14;, + 3;3485,234,225;, + 3;219,146,143;, + 3;146,153,160;, + 3;3482,147,139;, + 3;230,223,231;, + 3;217,17,3424;, + 3;217,3424,138;, + 3;138,149,148;, + 3;158,149,138;, + 3;221,191,212;, + 3;147,150,140;, + 3;98,215,8;, + 3;230,229,223;, + 3;159,241,153;, + 3;3484,12,154;, + 3;160,157,137;, + 3;156,159,145;, + 3;154,3486,3484;, + 3;157,153,241;, + 3;3487,3488,3489;, + 3;153,146,145;, + 3;146,160,137;, + 3;153,157,160;, + 3;225,235,224;, + 3;161,1743,142;, + 3;155,159,162;, + 3;162,159,156;, + 3;251,250,247;, + 3;162,187,155;, + 3;185,164,182;, + 3;183,3418,137;, + 3;164,34,181;, + 3;58,16,181;, + 3;168,37,847;, + 3;175,173,177;, + 3;165,173,179;, + 3;203,847,37;, + 3;154,14,38;, + 3;205,177,173;, + 3;202,169,203;, + 3;204,166,3490;, + 3;168,3491,171;, + 3;167,3492,165;, + 3;168,47,37;, + 3;154,172,176;, + 3;165,205,173;, + 3;38,174,172;, + 3;38,172,154;, + 3;173,174,179;, + 3;174,173,175;, + 3;179,174,180;, + 3;172,174,175;, + 3;202,80,169;, + 3;189,3493,178;, + 3;166,170,188;, + 3;174,38,180;, + 3;165,179,167;, + 3;180,38,57;, + 3;179,180,167;, + 3;734,57,46;, + 3;175,176,172;, + 3;3494,3495,3496;, + 3;3497,3496,3498;, + 3;3497,3498,3499;, + 3;163,3497,3499;, + 3;186,3500,3501;, + 3;3502,163,3503;, + 3;3501,3504,3444;, + 3;176,3486,154;, + 3;3494,3505,3495;, + 3;16,3482,181;, + 3;182,181,3482;, + 3;58,181,34;, + 3;182,3482,3483;, + 3;164,181,182;, + 3;183,137,157;, + 3;3506,3507,183;, + 3;158,184,3508;, + 3;3482,139,3483;, + 3;185,3483,3509;, + 3;183,3507,3418;, + 3;185,182,3483;, + 3;163,3502,186;, + 3;3510,164,185;, + 3;187,3506,244;, + 3;3494,3496,3497;, + 3;3444,3504,42;, + 3;3504,3501,3500;, + 3;166,188,3511;, + 3;3500,186,3502;, + 3;177,3493,189;, + 3;163,3499,3503;, + 3;139,147,190;, + 3;3512,191,3513;, + 3;192,143,146;, + 3;3483,193,3509;, + 3;137,195,192;, + 3;195,137,194;, + 3;143,197,191;, + 3;197,143,196;, + 3;3514,199,3515;, + 3;199,3514,198;, + 3;3513,201,3516;, + 3;201,3513,200;, + 3;192,196,143;, + 3;196,192,195;, + 3;191,200,3513;, + 3;200,191,197;, + 3;3516,198,3514;, + 3;198,3516,201;, + 3;3515,194,137;, + 3;194,3515,199;, + 3;80,3457,169;, + 3;169,170,203;, + 3;37,80,202;, + 3;170,204,203;, + 3;202,203,37;, + 3;170,166,204;, + 3;204,3491,203;, + 3;3493,177,205;, + 3;204,3490,3491;, + 3;3,85,152;, + 3;226,228,112;, + 3;152,85,89;, + 3;226,223,229;, + 3;213,227,233;, + 3;3506,183,243;, + 3;152,89,208;, + 3;226,229,228;, + 3;109,226,112;, + 3;208,209,152;, + 3;147,152,209;, + 3;147,209,210;, + 3;147,210,150;, + 3;210,211,150;, + 3;232,231,227;, + 3;3512,3517,212;, + 3;212,191,3512;, + 3;216,151,214;, + 3;227,213,232;, + 3;144,216,214;, + 3;10,1740,215;, + 3;215,151,8;, + 3;215,214,151;, + 3;10,215,98;, + 3;161,142,3484;, + 3;1745,1742,142;, + 3;846,151,216;, + 3;224,213,233;, + 3;148,17,217;, + 3;148,217,138;, + 3;218,146,219;, + 3;145,146,218;, + 3;234,235,225;, + 3;220,219,143;, + 3;224,235,236;, + 3;213,224,237;, + 3;224,236,238;, + 3;213,237,232;, + 3;224,238,237;, + 3;220,221,222;, + 3;220,143,221;, + 3;207,223,141;, + 3;223,207,227;, + 3;3485,225,3518;, + 3;3485,3519,234;, + 3;3520,231,3521;, + 3;231,3520,230;, + 3;3522,237,3523;, + 3;237,3522,232;, + 3;3524,230,3520;, + 3;230,3524,229;, + 3;224,3518,225;, + 3;3467,228,3525;, + 3;228,3467,112;, + 3;141,223,206;, + 3;226,206,223;, + 3;3526,227,207;, + 3;227,3526,233;, + 3;3525,229,3524;, + 3;229,3525,228;, + 3;206,109,86;, + 3;109,206,226;, + 3;3521,232,3522;, + 3;232,3521,231;, + 3;3527,233,3526;, + 3;233,3528,224;, + 3;3529,234,3519;, + 3;234,3529,235;, + 3;3530,235,3529;, + 3;235,3530,236;, + 3;3531,236,3530;, + 3;236,3531,238;, + 3;3523,238,3531;, + 3;238,3523,237;, + 3;187,239,155;, + 3;245,246,247;, + 3;242,157,241;, + 3;244,3506,243;, + 3;157,242,240;, + 3;159,155,241;, + 3;249,245,247;, + 3;245,249,248;, + 3;240,243,157;, + 3;243,183,157;, + 3;187,244,239;, + 3;246,251,247;, + 3;3532,250,3533;, + 3;250,3532,247;, + 3;3533,251,3534;, + 3;251,3533,250;, + 3;3535,245,3536;, + 3;245,3535,246;, + 3;3537,249,3538;, + 3;249,3537,248;, + 3;3538,247,3532;, + 3;247,3538,249;, + 3;3536,248,3537;, + 3;248,3536,245;, + 3;3534,246,3535;, + 3;246,3534,251;, + 3;255,472,550;, + 3;257,258,551;, + 3;252,467,554;, + 3;453,462,446;, + 3;439,447,448;, + 3;265,262,255;, + 3;462,463,460;, + 3;449,438,450;, + 3;439,443,447;, + 3;469,313,465;, + 3;254,289,466;, + 3;466,483,484;, + 3;260,435,432;, + 3;465,468,469;, + 3;260,473,474;, + 3;434,3539,3540;, + 3;259,465,474;, + 3;266,3541,262;, + 3;313,255,262;, + 3;438,449,445;, + 3;459,258,264;, + 3;265,266,262;, + 3;345,287,343;, + 3;486,485,271;, + 3;344,274,275;, + 3;335,534,535;, + 3;273,3542,340;, + 3;279,337,282;, + 3;393,333,269;, + 3;279,333,280;, + 3;3543,476,475;, + 3;397,400,417;, + 3;398,284,402;, + 3;388,284,405;, + 3;342,285,3544;, + 3;399,407,338;, + 3;394,392,3542;, + 3;480,479,285;, + 3;3542,392,342;, + 3;288,340,3542;, + 3;287,333,282;, + 3;344,334,274;, + 3;333,287,345;, + 3;343,275,270;, + 3;3544,285,552;, + 3;340,288,3544;, + 3;399,389,404;, + 3;290,295,296;, + 3;296,291,290;, + 3;291,296,297;, + 3;297,292,291;, + 3;292,297,298;, + 3;298,293,292;, + 3;309,310,299;, + 3;299,294,309;, + 3;300,301,424;, + 3;3545,422,3546;, + 3;301,302,424;, + 3;347,349,422;, + 3;305,423,306;, + 3;271,368,367;, + 3;3547,3548,301;, + 3;301,300,3547;, + 3;301,3549,426;, + 3;3549,301,3548;, + 3;358,426,359;, + 3;3550,359,426;, + 3;360,3551,364;, + 3;272,303,379;, + 3;374,276,277;, + 3;3552,3553,354;, + 3;3554,3555,306;, + 3;425,353,3553;, + 3;3555,3556,305;, + 3;305,306,3555;, + 3;305,3557,304;, + 3;3557,305,3556;, + 3;3558,3559,3546;, + 3;3546,3560,3558;, + 3;380,277,272;, + 3;294,299,308;, + 3;380,384,277;, + 3;3561,362,3550;, + 3;309,293,310;, + 3;310,293,298;, + 3;425,3553,3554;, + 3;518,517,330;, + 3;376,377,3562;, + 3;3543,477,476;, + 3;286,265,478;, + 3;487,277,488;, + 3;324,273,536;, + 3;313,470,255;, + 3;465,313,262;, + 3;502,501,314;, + 3;489,3562,490;, + 3;3563,491,317;, + 3;533,547,537;, + 3;318,492,493;, + 3;494,485,315;, + 3;330,503,504;, + 3;491,272,495;, + 3;495,487,319;, + 3;506,505,320;, + 3;488,277,496;, + 3;496,497,320;, + 3;519,312,520;, + 3;498,346,499;, + 3;499,489,316;, + 3;497,276,500;, + 3;500,3564,3565;, + 3;507,312,508;, + 3;510,509,319;, + 3;323,268,322;, + 3;512,511,3566;, + 3;466,3540,254;, + 3;550,478,255;, + 3;286,478,479;, + 3;410,387,411;, + 3;390,265,286;, + 3;332,289,254;, + 3;289,256,466;, + 3;281,256,289;, + 3;281,258,256;, + 3;279,548,391;, + 3;279,280,549;, + 3;549,280,261;, + 3;311,472,475;, + 3;3567,472,3568;, + 3;335,340,3544;, + 3;519,323,521;, + 3;513,511,325;, + 3;318,503,514;, + 3;3569,509,327;, + 3;515,505,328;, + 3;516,318,514;, + 3;506,3570,329;, + 3;504,501,330;, + 3;522,518,330;, + 3;267,538,539;, + 3;540,275,541;, + 3;526,278,527;, + 3;525,526,329;, + 3;507,321,515;, + 3;528,322,529;, + 3;521,528,331;, + 3;529,322,530;, + 3;502,513,325;, + 3;510,319,508;, + 3;531,328,527;, + 3;324,532,531;, + 3;325,3571,523;, + 3;420,400,418;, + 3;266,3572,3541;, + 3;279,282,333;, + 3;267,269,553;, + 3;414,409,416;, + 3;287,282,334;, + 3;536,544,336;, + 3;268,534,3573;, + 3;520,312,532;, + 3;548,281,391;, + 3;284,398,403;, + 3;410,416,409;, + 3;338,389,399;, + 3;288,341,3544;, + 3;3542,341,288;, + 3;273,340,543;, + 3;3542,339,341;, + 3;341,339,3544;, + 3;339,342,3544;, + 3;3542,342,339;, + 3;343,344,275;, + 3;267,343,270;, + 3;287,344,343;, + 3;287,334,344;, + 3;267,345,343;, + 3;553,345,267;, + 3;486,498,314;, + 3;347,3545,357;, + 3;271,367,346;, + 3;348,368,271;, + 3;493,348,494;, + 3;370,348,371;, + 3;350,3574,349;, + 3;422,3574,3560;, + 3;348,369,368;, + 3;3575,351,306;, + 3;369,348,370;, + 3;348,307,371;, + 3;306,425,3554;, + 3;351,352,306;, + 3;371,307,372;, + 3;354,3553,353;, + 3;384,374,277;, + 3;3576,276,375;, + 3;374,375,276;, + 3;346,376,3562;, + 3;367,376,346;, + 3;3577,302,358;, + 3;3550,426,3549;, + 3;359,3550,362;, + 3;3562,377,378;, + 3;385,373,3576;, + 3;3576,375,385;, + 3;355,3552,356;, + 3;3578,3552,355;, + 3;379,303,382;, + 3;3561,3551,360;, + 3;3551,361,364;, + 3;3551,3579,361;, + 3;378,381,3562;, + 3;3561,363,362;, + 3;360,363,3561;, + 3;383,380,272;, + 3;379,383,272;, + 3;361,3579,365;, + 3;3578,355,3580;, + 3;366,356,3552;, + 3;3552,354,366;, + 3;3581,3582,367;, + 3;367,368,3581;, + 3;3583,3584,378;, + 3;378,377,3583;, + 3;3585,3586,383;, + 3;383,379,3585;, + 3;3587,3588,371;, + 3;371,372,3587;, + 3;3589,3590,384;, + 3;384,380,3589;, + 3;3591,3583,377;, + 3;377,376,3591;, + 3;3582,3591,376;, + 3;376,367,3582;, + 3;3588,3592,370;, + 3;370,371,3588;, + 3;3593,3581,368;, + 3;368,369,3593;, + 3;3592,3593,369;, + 3;369,370,3592;, + 3;3590,3594,374;, + 3;374,384,3590;, + 3;3594,3595,375;, + 3;375,374,3594;, + 3;3584,3596,381;, + 3;381,378,3584;, + 3;3597,3598,373;, + 3;373,385,3597;, + 3;3595,3597,385;, + 3;385,375,3595;, + 3;3599,3585,379;, + 3;379,382,3599;, + 3;3586,3589,380;, + 3;380,383,3586;, + 3;338,386,389;, + 3;409,387,410;, + 3;418,400,401;, + 3;418,401,419;, + 3;409,412,387;, + 3;284,403,405;, + 3;419,401,413;, + 3;413,401,396;, + 3;415,413,396;, + 3;266,265,390;, + 3;405,408,388;, + 3;279,391,337;, + 3;395,479,480;, + 3;392,285,342;, + 3;393,280,333;, + 3;477,3543,3600;, + 3;338,407,406;, + 3;3601,274,334;, + 3;480,285,392;, + 3;395,392,394;, + 3;3602,3603,403;, + 3;403,398,3602;, + 3;3604,3605,400;, + 3;400,397,3604;, + 3;3606,3604,397;, + 3;397,408,3606;, + 3;3607,3602,398;, + 3;398,402,3607;, + 3;3603,3606,405;, + 3;405,403,3603;, + 3;3608,3609,399;, + 3;399,404,3608;, + 3;3605,3610,401;, + 3;401,400,3605;, + 3;3610,3611,396;, + 3;396,401,3610;, + 3;3612,3607,402;, + 3;402,406,3612;, + 3;3611,3608,404;, + 3;404,396,3611;, + 3;3609,3613,407;, + 3;407,399,3609;, + 3;3613,3612,406;, + 3;406,407,3613;, + 3;417,400,420;, + 3;408,405,3606;, + 3;397,417,408;, + 3;402,284,409;, + 3;409,414,402;, + 3;338,406,416;, + 3;416,410,338;, + 3;404,389,413;, + 3;413,415,404;, + 3;386,338,410;, + 3;410,411,386;, + 3;406,402,414;, + 3;414,416,406;, + 3;389,386,411;, + 3;411,413,389;, + 3;284,388,412;, + 3;412,409,284;, + 3;396,404,415;, + 3;388,408,417;, + 3;417,412,388;, + 3;411,387,418;, + 3;418,419,411;, + 3;387,412,420;, + 3;420,418,387;, + 3;413,411,419;, + 3;417,420,412;, + 3;258,421,264;, + 3;421,258,257;, + 3;3598,3576,373;, + 3;354,353,3614;, + 3;3587,372,307;, + 3;362,363,3615;, + 3;3599,382,303;, + 3;381,3596,3562;, + 3;422,349,3574;, + 3;422,3560,3546;, + 3;3575,306,423;, + 3;423,305,304;, + 3;424,302,3577;, + 3;422,3545,347;, + 3;306,352,425;, + 3;352,353,425;, + 3;358,302,426;, + 3;301,426,302;, + 3;444,443,442;, + 3;443,439,442;, + 3;454,457,455;, + 3;438,445,452;, + 3;432,431,464;, + 3;432,473,260;, + 3;263,433,434;, + 3;482,434,3540;, + 3;431,427,464;, + 3;464,427,556;, + 3;448,451,440;, + 3;448,440,439;, + 3;450,3616,3617;, + 3;438,3616,450;, + 3;429,433,263;, + 3;458,481,459;, + 3;452,445,3618;, + 3;454,456,457;, + 3;462,460,446;, + 3;428,3619,443;, + 3;443,444,428;, + 3;3620,3621,448;, + 3;448,447,3620;, + 3;3622,3623,449;, + 3;449,450,3622;, + 3;3619,3620,447;, + 3;447,443,3619;, + 3;3621,3624,451;, + 3;451,448,3621;, + 3;3625,3622,450;, + 3;450,3617,3625;, + 3;3623,3626,445;, + 3;445,449,3623;, + 3;3627,3628,442;, + 3;442,439,3627;, + 3;3629,3630,438;, + 3;438,452,3629;, + 3;3631,3627,439;, + 3;439,440,3631;, + 3;3630,3632,3616;, + 3;3616,438,3630;, + 3;3626,437,3618;, + 3;3618,445,3626;, + 3;3633,3634,3635;, + 3;3635,441,3633;, + 3;3636,3637,455;, + 3;455,457,3636;, + 3;3635,3636,457;, + 3;457,456,3635;, + 3;441,3635,456;, + 3;456,454,441;, + 3;429,458,3638;, + 3;429,481,458;, + 3;256,258,459;, + 3;463,461,460;, + 3;3638,458,462;, + 3;462,453,3638;, + 3;458,459,463;, + 3;463,462,458;, + 3;459,264,461;, + 3;461,463,459;, + 3;253,430,446;, + 3;446,460,253;, + 3;264,253,460;, + 3;3639,3640,3641;, + 3;556,427,554;, + 3;473,259,474;, + 3;3541,474,262;, + 3;259,468,465;, + 3;466,256,483;, + 3;3540,466,482;, + 3;259,467,468;, + 3;464,467,259;, + 3;467,252,468;, + 3;469,555,3568;, + 3;469,468,252;, + 3;470,313,469;, + 3;3568,470,469;, + 3;470,3568,471;, + 3;472,255,471;, + 3;470,471,255;, + 3;3568,472,471;, + 3;311,283,472;, + 3;432,464,473;, + 3;464,259,473;, + 3;474,465,262;, + 3;260,474,3541;, + 3;475,472,3567;, + 3;3543,475,3567;, + 3;476,477,311;, + 3;476,311,475;, + 3;3544,552,3600;, + 3;477,285,311;, + 3;265,255,478;, + 3;478,283,311;, + 3;479,478,311;, + 3;479,311,285;, + 3;395,480,392;, + 3;286,479,395;, + 3;429,263,481;, + 3;481,263,484;, + 3;482,466,484;, + 3;263,434,482;, + 3;483,256,459;, + 3;483,459,484;, + 3;484,459,481;, + 3;482,484,263;, + 3;486,315,485;, + 3;314,315,486;, + 3;319,487,488;, + 3;319,488,321;, + 3;316,489,490;, + 3;316,490,3566;, + 3;3563,272,491;, + 3;303,272,3563;, + 3;493,492,348;, + 3;492,307,348;, + 3;494,271,485;, + 3;348,271,494;, + 3;317,491,495;, + 3;317,495,319;, + 3;495,277,487;, + 3;272,277,495;, + 3;321,488,496;, + 3;321,496,320;, + 3;496,276,497;, + 3;277,276,496;, + 3;314,498,499;, + 3;314,499,316;, + 3;499,3562,489;, + 3;346,3562,499;, + 3;320,497,500;, + 3;320,500,3565;, + 3;500,3576,3564;, + 3;276,3576,500;, + 3;486,346,498;, + 3;271,346,486;, + 3;318,493,494;, + 3;318,494,315;, + 3;502,325,501;, + 3;325,545,501;, + 3;504,503,315;, + 3;503,318,315;, + 3;506,328,505;, + 3;329,328,506;, + 3;321,507,508;, + 3;321,508,319;, + 3;510,331,509;, + 3;331,327,509;, + 3;512,325,511;, + 3;3642,325,512;, + 3;513,3566,511;, + 3;316,3566,513;, + 3;514,503,326;, + 3;503,330,326;, + 3;3569,319,509;, + 3;317,319,3569;, + 3;515,320,505;, + 3;321,320,515;, + 3;3643,516,514;, + 3;3643,514,326;, + 3;506,3565,3570;, + 3;320,3565,506;, + 3;504,314,501;, + 3;315,314,504;, + 3;312,507,515;, + 3;312,515,328;, + 3;502,316,513;, + 3;314,316,502;, + 3;331,510,508;, + 3;331,508,312;, + 3;542,540,517;, + 3;336,519,520;, + 3;323,519,336;, + 3;331,519,521;, + 3;312,519,331;, + 3;538,542,522;, + 3;523,522,325;, + 3;522,545,325;, + 3;326,517,524;, + 3;330,517,326;, + 3;524,3644,326;, + 3;3644,3643,326;, + 3;329,526,527;, + 3;329,527,328;, + 3;525,278,526;, + 3;275,3645,541;, + 3;327,528,529;, + 3;331,528,327;, + 3;521,323,528;, + 3;323,322,528;, + 3;327,529,530;, + 3;3642,3571,325;, + 3;324,531,527;, + 3;324,527,278;, + 3;531,532,328;, + 3;532,312,328;, + 3;539,537,267;, + 3;336,520,532;, + 3;336,532,324;, + 3;267,537,547;, + 3;535,534,323;, + 3;534,268,323;, + 3;546,275,274;, + 3;278,273,324;, + 3;3646,533,537;, + 3;3646,537,3647;, + 3;536,336,324;, + 3;539,538,523;, + 3;538,522,523;, + 3;517,540,541;, + 3;517,541,524;, + 3;541,3644,524;, + 3;536,543,544;, + 3;273,543,536;, + 3;3573,534,335;, + 3;3573,335,3648;, + 3;535,323,336;, + 3;3542,273,3649;, + 3;518,542,517;, + 3;542,275,540;, + 3;270,275,542;, + 3;522,542,518;, + 3;538,267,542;, + 3;267,270,542;, + 3;541,3645,3644;, + 3;539,523,537;, + 3;523,3571,537;, + 3;3571,3647,537;, + 3;543,340,335;, + 3;543,335,535;, + 3;544,543,535;, + 3;544,535,336;, + 3;522,330,545;, + 3;545,330,501;, + 3;3649,273,278;, + 3;3645,275,546;, + 3;3648,335,3544;, + 3;547,269,267;, + 3;279,258,548;, + 3;258,281,548;, + 3;258,549,551;, + 3;279,549,258;, + 3;550,472,283;, + 3;283,478,550;, + 3;551,549,261;, + 3;257,551,261;, + 3;552,285,477;, + 3;552,477,3600;, + 3;553,269,333;, + 3;333,345,553;, + 3;554,427,3650;, + 3;469,252,555;, + 3;467,556,554;, + 3;464,556,467;, + 3;558,840,762;, + 3;257,841,560;, + 3;252,554,757;, + 3;747,446,752;, + 3;737,742,741;, + 3;566,558,564;, + 3;752,460,753;, + 3;743,744,736;, + 3;737,741,739;, + 3;759,755,614;, + 3;557,756,590;, + 3;756,774,773;, + 3;562,730,733;, + 3;755,759,758;, + 3;562,764,763;, + 3;732,3651,3652;, + 3;561,764,755;, + 3;567,564,3653;, + 3;614,564,558;, + 3;736,740,743;, + 3;751,264,560;, + 3;566,564,567;, + 3;646,644,588;, + 3;776,572,775;, + 3;645,576,575;, + 3;636,825,824;, + 3;574,641,3654;, + 3;580,583,638;, + 3;694,570,634;, + 3;580,581,634;, + 3;3655,765,766;, + 3;698,718,701;, + 3;699,703,585;, + 3;689,706,585;, + 3;643,3656,586;, + 3;700,639,708;, + 3;695,3654,693;, + 3;770,586,769;, + 3;3654,643,693;, + 3;589,3654,641;, + 3;588,583,634;, + 3;645,575,635;, + 3;634,646,588;, + 3;644,571,576;, + 3;3656,842,586;, + 3;641,3656,589;, + 3;700,705,690;, + 3;591,597,596;, + 3;597,591,592;, + 3;592,598,597;, + 3;598,592,593;, + 3;593,599,598;, + 3;599,593,594;, + 3;610,600,611;, + 3;600,610,595;, + 3;601,724,602;, + 3;3657,3658,722;, + 3;602,724,603;, + 3;648,722,650;, + 3;606,607,723;, + 3;572,668,669;, + 3;3659,602,3660;, + 3;602,3659,601;, + 3;602,726,3661;, + 3;3661,3660,602;, + 3;659,660,726;, + 3;3662,726,660;, + 3;661,665,3663;, + 3;573,680,604;, + 3;675,578,577;, + 3;3664,655,3665;, + 3;3666,607,3667;, + 3;725,3665,654;, + 3;3667,606,3668;, + 3;606,3667,607;, + 3;606,605,3669;, + 3;3669,3668,606;, + 3;3670,3658,3671;, + 3;3658,3670,3672;, + 3;681,573,578;, + 3;595,609,600;, + 3;681,578,685;, + 3;3673,3662,663;, + 3;610,611,594;, + 3;611,599,594;, + 3;725,3666,3665;, + 3;808,631,807;, + 3;677,3674,678;, + 3;3655,766,767;, + 3;587,768,566;, + 3;777,778,578;, + 3;625,826,574;, + 3;614,558,760;, + 3;755,564,614;, + 3;792,615,791;, + 3;779,780,3674;, + 3;3675,618,781;, + 3;823,827,837;, + 3;619,783,782;, + 3;784,616,775;, + 3;631,794,793;, + 3;781,785,573;, + 3;785,620,777;, + 3;796,621,795;, + 3;778,786,578;, + 3;786,621,787;, + 3;809,810,613;, + 3;788,789,647;, + 3;789,617,779;, + 3;787,790,577;, + 3;790,3676,3677;, + 3;797,798,613;, + 3;800,620,799;, + 3;624,623,569;, + 3;802,3678,801;, + 3;756,557,3651;, + 3;840,558,768;, + 3;587,769,768;, + 3;711,712,688;, + 3;691,587,566;, + 3;633,557,590;, + 3;590,756,559;, + 3;582,590,559;, + 3;582,559,560;, + 3;580,692,838;, + 3;580,839,581;, + 3;839,563,581;, + 3;612,765,762;, + 3;3679,3568,762;, + 3;636,3656,641;, + 3;809,811,624;, + 3;803,626,801;, + 3;619,804,793;, + 3;3680,628,799;, + 3;805,629,795;, + 3;806,804,619;, + 3;796,630,3681;, + 3;794,631,791;, + 3;812,631,808;, + 3;568,829,828;, + 3;830,831,576;, + 3;816,817,579;, + 3;815,630,816;, + 3;797,805,622;, + 3;818,819,623;, + 3;811,632,818;, + 3;819,820,623;, + 3;792,626,803;, + 3;800,798,620;, + 3;821,817,629;, + 3;625,821,822;, + 3;626,813,3682;, + 3;721,719,701;, + 3;567,3653,3683;, + 3;580,634,583;, + 3;568,843,570;, + 3;715,717,710;, + 3;588,635,583;, + 3;826,637,834;, + 3;569,3684,824;, + 3;810,822,613;, + 3;838,692,582;, + 3;585,704,699;, + 3;711,710,717;, + 3;639,700,690;, + 3;589,3656,642;, + 3;3654,589,642;, + 3;574,833,641;, + 3;3654,642,640;, + 3;642,3656,640;, + 3;640,3656,643;, + 3;3654,640,643;, + 3;644,576,645;, + 3;568,571,644;, + 3;588,644,645;, + 3;588,645,635;, + 3;568,644,646;, + 3;843,568,646;, + 3;776,615,788;, + 3;724,658,603;, + 3;572,647,668;, + 3;649,572,669;, + 3;783,784,649;, + 3;671,672,649;, + 3;651,650,3685;, + 3;722,3672,3685;, + 3;649,669,670;, + 3;3686,607,652;, + 3;670,671,649;, + 3;649,672,608;, + 3;607,3666,725;, + 3;652,607,653;, + 3;672,673,608;, + 3;655,654,3665;, + 3;685,578,675;, + 3;3687,676,577;, + 3;675,577,676;, + 3;647,3674,677;, + 3;668,647,677;, + 3;658,659,603;, + 3;3662,3661,726;, + 3;660,663,3662;, + 3;3674,679,678;, + 3;686,3687,674;, + 3;3687,686,676;, + 3;656,657,3664;, + 3;3688,656,3664;, + 3;680,683,604;, + 3;3673,661,3663;, + 3;3663,665,662;, + 3;3663,662,3689;, + 3;679,3674,682;, + 3;3673,663,664;, + 3;661,3673,664;, + 3;684,573,681;, + 3;680,573,684;, + 3;662,666,3689;, + 3;3688,3690,656;, + 3;667,3664,657;, + 3;3664,667,655;, + 3;3691,668,3692;, + 3;668,3691,669;, + 3;3693,679,3694;, + 3;679,3693,678;, + 3;3695,684,3696;, + 3;684,3695,680;, + 3;3697,672,3698;, + 3;672,3697,673;, + 3;3699,685,3700;, + 3;685,3699,681;, + 3;3701,678,3693;, + 3;678,3701,677;, + 3;3692,677,3701;, + 3;677,3692,668;, + 3;3698,671,3702;, + 3;671,3698,672;, + 3;3703,669,3691;, + 3;669,3703,670;, + 3;3702,670,3703;, + 3;670,3702,671;, + 3;3700,675,3704;, + 3;675,3700,685;, + 3;3704,676,3705;, + 3;676,3704,675;, + 3;3694,682,3706;, + 3;682,3694,679;, + 3;3707,674,3708;, + 3;674,3707,686;, + 3;3705,686,3707;, + 3;686,3705,676;, + 3;3709,680,3695;, + 3;680,3709,683;, + 3;3696,681,3699;, + 3;681,3696,684;, + 3;639,690,687;, + 3;710,711,688;, + 3;719,702,701;, + 3;719,720,702;, + 3;710,688,713;, + 3;585,706,704;, + 3;720,714,702;, + 3;714,697,702;, + 3;716,697,714;, + 3;567,691,566;, + 3;706,689,709;, + 3;580,638,692;, + 3;696,770,769;, + 3;693,643,586;, + 3;694,634,581;, + 3;767,3710,3655;, + 3;639,707,708;, + 3;3711,635,575;, + 3;770,693,586;, + 3;696,695,693;, + 3;3712,704,3713;, + 3;704,3712,699;, + 3;3714,701,3715;, + 3;701,3714,698;, + 3;3716,698,3714;, + 3;698,3716,709;, + 3;3717,699,3712;, + 3;699,3717,703;, + 3;3713,706,3716;, + 3;706,3713,704;, + 3;3718,700,3719;, + 3;700,3718,705;, + 3;3715,702,3720;, + 3;702,3715,701;, + 3;3720,697,3721;, + 3;697,3720,702;, + 3;3722,703,3717;, + 3;703,3722,707;, + 3;3721,705,3718;, + 3;705,3721,697;, + 3;3719,708,3723;, + 3;708,3719,700;, + 3;3723,707,3722;, + 3;707,3723,708;, + 3;718,721,701;, + 3;709,3716,706;, + 3;698,709,718;, + 3;703,710,585;, + 3;710,703,715;, + 3;639,717,707;, + 3;717,639,711;, + 3;705,714,690;, + 3;714,705,716;, + 3;687,711,639;, + 3;711,687,712;, + 3;707,715,703;, + 3;715,707,717;, + 3;690,712,687;, + 3;712,690,714;, + 3;585,713,689;, + 3;713,585,710;, + 3;697,716,705;, + 3;689,718,709;, + 3;718,689,713;, + 3;712,719,688;, + 3;719,712,720;, + 3;688,721,713;, + 3;721,688,719;, + 3;714,720,712;, + 3;718,713,721;, + 3;560,264,421;, + 3;421,257,560;, + 3;3708,674,3687;, + 3;655,3724,654;, + 3;3697,608,673;, + 3;663,3725,664;, + 3;3709,604,683;, + 3;682,3674,3706;, + 3;722,3685,650;, + 3;722,3658,3672;, + 3;3686,723,607;, + 3;723,605,606;, + 3;3657,648,3726;, + 3;722,648,3657;, + 3;607,725,653;, + 3;653,725,654;, + 3;659,726,603;, + 3;602,603,726;, + 3;444,442,739;, + 3;739,442,737;, + 3;454,455,749;, + 3;736,746,740;, + 3;730,754,729;, + 3;730,562,763;, + 3;565,732,731;, + 3;772,3651,732;, + 3;729,754,727;, + 3;754,844,727;, + 3;742,738,745;, + 3;742,737,738;, + 3;744,3727,3728;, + 3;736,744,3728;, + 3;728,565,731;, + 3;750,751,771;, + 3;746,3729,740;, + 3;454,749,748;, + 3;752,446,460;, + 3;428,739,3730;, + 3;739,428,444;, + 3;3731,742,3732;, + 3;742,3731,741;, + 3;3733,743,3734;, + 3;743,3733,744;, + 3;3730,741,3731;, + 3;741,3730,739;, + 3;3732,745,3735;, + 3;745,3732,742;, + 3;3736,744,3733;, + 3;744,3736,3727;, + 3;3734,740,3737;, + 3;740,3734,743;, + 3;3738,442,3628;, + 3;442,3738,737;, + 3;3739,736,3740;, + 3;736,3739,746;, + 3;3741,737,3738;, + 3;737,3741,738;, + 3;3740,3728,3742;, + 3;3728,3740,736;, + 3;3737,3729,735;, + 3;3729,3737,740;, + 3;3633,3743,3744;, + 3;3743,3633,441;, + 3;3745,455,3637;, + 3;455,3745,749;, + 3;3743,749,3745;, + 3;749,3743,748;, + 3;441,748,3743;, + 3;748,441,454;, + 3;728,3746,750;, + 3;728,750,771;, + 3;559,751,560;, + 3;753,460,461;, + 3;3746,752,750;, + 3;752,3746,747;, + 3;750,753,751;, + 3;753,750,752;, + 3;751,461,264;, + 3;461,751,753;, + 3;253,446,430;, + 3;446,253,460;, + 3;264,460,253;, + 3;460,264,461;, + 3;844,554,727;, + 3;763,764,561;, + 3;3653,564,764;, + 3;561,755,758;, + 3;756,773,559;, + 3;3651,772,756;, + 3;561,758,757;, + 3;754,561,757;, + 3;757,758,252;, + 3;759,3568,555;, + 3;759,252,758;, + 3;760,759,614;, + 3;3568,759,760;, + 3;760,761,3568;, + 3;762,761,558;, + 3;760,558,761;, + 3;3568,761,762;, + 3;612,762,584;, + 3;730,763,754;, + 3;754,763,561;, + 3;764,564,755;, + 3;562,3653,764;, + 3;765,3679,762;, + 3;3655,3679,765;, + 3;766,612,767;, + 3;766,765,612;, + 3;3656,3710,842;, + 3;767,612,586;, + 3;566,768,558;, + 3;768,612,584;, + 3;769,612,768;, + 3;769,586,612;, + 3;696,693,770;, + 3;587,696,769;, + 3;728,771,565;, + 3;771,774,565;, + 3;772,774,756;, + 3;565,772,732;, + 3;773,751,559;, + 3;773,774,751;, + 3;774,771,751;, + 3;772,565,774;, + 3;776,775,616;, + 3;615,776,616;, + 3;620,778,777;, + 3;620,622,778;, + 3;617,780,779;, + 3;617,3678,780;, + 3;3675,781,573;, + 3;604,3675,573;, + 3;783,649,782;, + 3;782,649,608;, + 3;784,775,572;, + 3;649,784,572;, + 3;618,785,781;, + 3;618,620,785;, + 3;785,777,578;, + 3;573,785,578;, + 3;622,786,778;, + 3;622,621,786;, + 3;786,787,577;, + 3;578,786,577;, + 3;615,789,788;, + 3;615,617,789;, + 3;789,779,3674;, + 3;647,789,3674;, + 3;621,790,787;, + 3;621,3676,790;, + 3;790,3677,3687;, + 3;577,790,3687;, + 3;776,788,647;, + 3;572,776,647;, + 3;619,784,783;, + 3;619,616,784;, + 3;792,791,626;, + 3;626,791,835;, + 3;794,616,793;, + 3;793,616,619;, + 3;796,795,629;, + 3;630,796,629;, + 3;622,798,797;, + 3;622,620,798;, + 3;800,799,632;, + 3;632,799,628;, + 3;802,801,626;, + 3;3747,802,626;, + 3;803,801,3678;, + 3;617,803,3678;, + 3;804,627,793;, + 3;793,627,631;, + 3;3680,799,620;, + 3;618,3680,620;, + 3;805,795,621;, + 3;622,805,621;, + 3;3748,804,806;, + 3;3748,627,804;, + 3;796,3681,3676;, + 3;621,796,3676;, + 3;794,791,615;, + 3;616,794,615;, + 3;613,805,797;, + 3;613,629,805;, + 3;792,803,617;, + 3;615,792,617;, + 3;632,798,800;, + 3;632,613,798;, + 3;832,807,830;, + 3;637,810,809;, + 3;624,637,809;, + 3;632,811,809;, + 3;613,632,809;, + 3;828,812,832;, + 3;813,626,812;, + 3;812,626,835;, + 3;627,814,807;, + 3;631,627,807;, + 3;814,627,3749;, + 3;3749,627,3748;, + 3;630,817,816;, + 3;630,629,817;, + 3;815,816,579;, + 3;576,831,3750;, + 3;628,819,818;, + 3;632,628,818;, + 3;811,818,624;, + 3;624,818,623;, + 3;628,820,819;, + 3;3747,626,3682;, + 3;625,817,821;, + 3;625,579,817;, + 3;821,629,822;, + 3;822,629,613;, + 3;829,568,827;, + 3;637,822,810;, + 3;637,625,822;, + 3;568,837,827;, + 3;825,624,824;, + 3;824,624,569;, + 3;836,575,576;, + 3;579,625,574;, + 3;3751,827,823;, + 3;3751,3752,827;, + 3;826,625,637;, + 3;829,813,828;, + 3;828,813,812;, + 3;807,831,830;, + 3;807,814,831;, + 3;831,814,3749;, + 3;826,834,833;, + 3;574,826,833;, + 3;3684,636,824;, + 3;3684,3753,636;, + 3;825,637,624;, + 3;3654,3754,574;, + 3;808,807,832;, + 3;832,830,576;, + 3;571,832,576;, + 3;812,808,832;, + 3;828,832,568;, + 3;568,832,571;, + 3;831,3749,3750;, + 3;829,827,813;, + 3;813,827,3682;, + 3;3682,827,3752;, + 3;833,636,641;, + 3;833,825,636;, + 3;834,825,833;, + 3;834,637,825;, + 3;812,835,631;, + 3;835,791,631;, + 3;3754,579,574;, + 3;3750,836,576;, + 3;3753,3656,636;, + 3;837,568,570;, + 3;580,838,560;, + 3;560,838,582;, + 3;560,841,839;, + 3;580,560,839;, + 3;840,584,762;, + 3;584,840,768;, + 3;841,563,839;, + 3;257,563,841;, + 3;842,767,586;, + 3;842,3710,767;, + 3;843,634,570;, + 3;634,843,646;, + 3;554,3650,727;, + 3;759,555,252;, + 3;757,554,844;, + 3;754,757,844;, + 3;845,99,21;, + 3;3755,846,216;, + 3;180,734,167;, + 3;180,57,734;, + 3;46,57,436;, + 3;436,56,40;, + 3;203,3491,847;, + 3;168,847,3491;, + 3;82,37,848;, + 3;41,848,37;, + 3;849,1291,850;, + 3;943,852,851;, + 3;849,1290,944;, + 3;1289,854,1293;, + 3;854,1289,944;, + 3;859,888,945;, + 3;855,861,887;, + 3;946,856,3756;, + 3;1292,3757,3758;, + 3;3757,3759,3760;, + 3;852,946,851;, + 3;857,889,849;, + 3;858,857,850;, + 3;850,857,849;, + 3;853,860,1290;, + 3;3761,861,3758;, + 3;3758,861,855;, + 3;887,859,945;, + 3;875,891,890;, + 3;893,892,862;, + 3;894,869,895;, + 3;897,896,863;, + 3;898,876,899;, + 3;900,862,892;, + 3;902,901,874;, + 3;898,877,903;, + 3;868,904,890;, + 3;894,864,905;, + 3;905,864,904;, + 3;896,872,895;, + 3;867,902,906;, + 3;3762,3763,891;, + 3;899,906,865;, + 3;903,3764,3765;, + 3;901,900,874;, + 3;3763,880,868;, + 3;880,3763,879;, + 3;867,882,878;, + 3;882,867,881;, + 3;3765,884,876;, + 3;884,3765,883;, + 3;866,886,869;, + 3;886,866,885;, + 3;868,880,866;, + 3;885,866,880;, + 3;869,3766,863;, + 3;3766,869,886;, + 3;876,881,867;, + 3;881,876,884;, + 3;878,3767,862;, + 3;3767,878,882;, + 3;870,3768,871;, + 3;3768,870,3769;, + 3;872,3770,864;, + 3;3770,872,3771;, + 3;873,3771,872;, + 3;3771,873,3772;, + 3;865,3773,877;, + 3;3773,865,3774;, + 3;871,3775,874;, + 3;3775,871,3768;, + 3;864,3776,875;, + 3;3776,864,3770;, + 3;874,3774,865;, + 3;3774,874,3775;, + 3;875,3777,3778;, + 3;3777,875,3776;, + 3;877,3779,3780;, + 3;3779,877,3773;, + 3;890,891,868;, + 3;868,891,3763;, + 3;892,893,871;, + 3;871,893,870;, + 3;894,895,864;, + 3;864,895,872;, + 3;896,897,872;, + 3;872,897,873;, + 3;898,899,877;, + 3;877,899,865;, + 3;900,892,874;, + 3;874,892,871;, + 3;901,902,878;, + 3;878,902,867;, + 3;898,903,876;, + 3;876,903,3765;, + 3;890,904,875;, + 3;875,904,864;, + 3;894,905,869;, + 3;869,905,866;, + 3;905,904,866;, + 3;866,904,868;, + 3;896,895,863;, + 3;863,895,869;, + 3;906,902,865;, + 3;865,902,874;, + 3;3762,891,3778;, + 3;3778,891,875;, + 3;906,899,867;, + 3;867,899,876;, + 3;3764,903,3780;, + 3;3780,903,877;, + 3;900,901,862;, + 3;862,901,878;, + 3;889,1290,849;, + 3;3781,858,850;, + 3;855,887,945;, + 3;921,939,908;, + 3;942,922,3782;, + 3;923,910,924;, + 3;907,926,925;, + 3;926,927,911;, + 3;929,928,915;, + 3;3783,919,913;, + 3;931,930,913;, + 3;941,920,908;, + 3;931,932,3784;, + 3;929,933,908;, + 3;916,918,3785;, + 3;917,3786,913;, + 3;935,934,914;, + 3;916,935,936;, + 3;937,3787,938;, + 3;3788,3785,918;, + 3;3789,909,919;, + 3;912,3790,3791;, + 3;916,3786,917;, + 3;934,930,914;, + 3;918,3792,3788;, + 3;936,3787,937;, + 3;3783,913,3786;, + 3;932,3793,3784;, + 3;928,3794,915;, + 3;940,908,939;, + 3;907,942,940;, + 3;927,933,911;, + 3;922,3795,3782;, + 3;925,910,923;, + 3;923,924,922;, + 3;922,924,3795;, + 3;925,926,910;, + 3;910,926,911;, + 3;927,926,921;, + 3;921,926,907;, + 3;928,929,920;, + 3;920,929,908;, + 3;930,931,914;, + 3;914,931,3784;, + 3;932,931,919;, + 3;919,931,913;, + 3;933,929,911;, + 3;911,929,915;, + 3;934,935,917;, + 3;917,935,916;, + 3;936,935,3787;, + 3;3787,935,914;, + 3;937,938,918;, + 3;918,938,3792;, + 3;930,934,913;, + 3;913,934,917;, + 3;936,937,916;, + 3;916,937,918;, + 3;3793,932,909;, + 3;909,932,919;, + 3;3794,928,912;, + 3;912,928,920;, + 3;933,927,908;, + 3;908,927,921;, + 3;925,923,907;, + 3;907,923,922;, + 3;912,920,3790;, + 3;3782,3795,3796;, + 3;940,3782,3797;, + 3;941,940,3790;, + 3;907,939,921;, + 3;939,907,940;, + 3;940,3797,3790;, + 3;3790,920,941;, + 3;908,940,941;, + 3;907,922,942;, + 3;942,3782,940;, + 3;3789,919,3783;, + 3;3785,3786,916;, + 3;1289,852,943;, + 3;849,944,1289;, + 3;854,944,1290;, + 3;3798,3781,850;, + 3;3799,3800,851;, + 3;852,856,946;, + 3;946,3801,3799;, + 3;1271,947,3802;, + 3;3802,3803,1271;, + 3;3804,949,3805;, + 3;1273,3804,3806;, + 3;3807,948,3803;, + 3;948,3807,1272;, + 3;1274,950,3808;, + 3;1274,3805,949;, + 3;1275,1276,1274;, + 3;1278,952,1277;, + 3;1279,1280,954;, + 3;1282,951,1281;, + 3;1283,1284,1273;, + 3;1283,3809,3810;, + 3;1008,1270,956;, + 3;955,3811,3812;, + 3;981,957,1267;, + 3;970,1009,973;, + 3;3813,959,953;, + 3;1268,963,988;, + 3;3814,1263,3815;, + 3;959,3813,982;, + 3;973,958,970;, + 3;959,984,953;, + 3;3816,962,957;, + 3;1011,955,974;, + 3;984,3817,953;, + 3;984,965,3817;, + 3;991,961,964;, + 3;1263,963,1012;, + 3;963,3814,3818;, + 3;989,990,964;, + 3;3819,3820,966;, + 3;991,967,992;, + 3;992,965,991;, + 3;3818,966,963;, + 3;966,3818,968;, + 3;961,986,964;, + 3;964,986,3821;, + 3;976,974,1008;, + 3;1009,956,973;, + 3;969,1008,971;, + 3;975,974,972;, + 3;1263,1012,973;, + 3;1270,1263,956;, + 3;955,3815,1270;, + 3;969,976,1008;, + 3;1011,974,975;, + 3;1010,974,976;, + 3;3816,981,982;, + 3;980,1267,957;, + 3;959,982,981;, + 3;3816,982,3813;, + 3;961,991,984;, + 3;959,983,984;, + 3;983,961,984;, + 3;1012,963,985;, + 3;963,1268,985;, + 3;983,986,961;, + 3;983,987,986;, + 3;3820,988,963;, + 3;963,966,3820;, + 3;964,3821,989;, + 3;967,964,990;, + 3;965,984,991;, + 3;964,967,991;, + 3;965,992,3822;, + 3;992,995,3822;, + 3;995,992,994;, + 3;966,993,3819;, + 3;993,966,996;, + 3;967,994,992;, + 3;994,967,997;, + 3;968,996,966;, + 3;996,968,3823;, + 3;990,997,967;, + 3;997,990,3824;, + 3;994,1000,995;, + 3;1000,994,999;, + 3;996,998,993;, + 3;998,996,1001;, + 3;3823,1001,996;, + 3;1001,3823,3825;, + 3;3826,1002,3827;, + 3;3828,3824,3829;, + 3;997,999,994;, + 3;999,997,3828;, + 3;999,1005,1000;, + 3;1005,999,1004;, + 3;1001,1003,998;, + 3;1003,1001,1006;, + 3;3825,1006,1001;, + 3;1006,3825,3830;, + 3;3829,1007,3828;, + 3;1007,3829,3831;, + 3;3828,1004,999;, + 3;1004,3828,1007;, + 3;1007,1005,1004;, + 3;3830,1003,1006;, + 3;3831,1005,1007;, + 3;974,955,1270;, + 3;971,1008,956;, + 3;971,956,1009;, + 3;972,974,1010;, + 3;3832,955,1011;, + 3;958,973,1012;, + 3;1016,1015,970;, + 3;958,1016,970;, + 3;1017,1016,958;, + 3;1012,1017,958;, + 3;1018,1017,1012;, + 3;985,1018,1012;, + 3;1019,3833,3834;, + 3;960,1019,3834;, + 3;1020,1019,960;, + 3;979,1020,960;, + 3;3835,1020,979;, + 3;3836,3835,979;, + 3;1022,1021,1015;, + 3;1016,1022,1015;, + 3;1023,1022,1016;, + 3;1017,1023,1016;, + 3;1024,1023,1017;, + 3;1018,1024,1017;, + 3;1025,3837,3833;, + 3;1019,1025,3833;, + 3;1026,1025,1019;, + 3;1020,1026,1019;, + 3;3838,1026,1020;, + 3;3835,3838,1020;, + 3;1028,1027,1021;, + 3;1022,1028,1021;, + 3;1029,1028,1022;, + 3;1023,1029,1022;, + 3;1030,1029,1023;, + 3;1024,1030,1023;, + 3;1031,3839,3837;, + 3;1025,1031,3837;, + 3;1032,1031,1025;, + 3;1026,1032,1025;, + 3;3840,1032,1026;, + 3;3838,3840,1026;, + 3;1034,1033,1027;, + 3;1028,1034,1027;, + 3;1035,1034,1028;, + 3;1029,1035,1028;, + 3;1036,1035,1029;, + 3;1030,1036,1029;, + 3;1037,3841,3839;, + 3;1031,1037,3839;, + 3;1038,1037,1031;, + 3;1032,1038,1031;, + 3;3842,1038,1032;, + 3;3840,3842,1032;, + 3;1040,1039,1033;, + 3;1034,1040,1033;, + 3;1041,1040,1034;, + 3;1035,1041,1034;, + 3;1042,1041,1035;, + 3;1036,1042,1035;, + 3;1043,3843,3841;, + 3;1037,1043,3841;, + 3;1044,1043,1037;, + 3;1038,1044,1037;, + 3;3844,1044,1038;, + 3;3842,3844,1038;, + 3;1046,1045,1039;, + 3;1040,1046,1039;, + 3;1047,1046,1040;, + 3;1041,1047,1040;, + 3;1048,1047,1041;, + 3;1042,1048,1041;, + 3;1049,3845,3843;, + 3;1043,1049,3843;, + 3;1050,1049,1043;, + 3;1044,1050,1043;, + 3;3846,1050,1044;, + 3;3844,3846,1044;, + 3;1052,1051,1045;, + 3;1046,1052,1045;, + 3;1053,1052,1046;, + 3;1047,1053,1046;, + 3;1054,1053,1047;, + 3;1048,1054,1047;, + 3;1055,3847,3845;, + 3;1049,1055,3845;, + 3;1056,1055,1049;, + 3;1050,1056,1049;, + 3;3848,1056,1050;, + 3;3846,3848,1050;, + 3;1058,1057,1051;, + 3;1052,1058,1051;, + 3;1059,1058,1052;, + 3;1053,1059,1052;, + 3;1060,1059,1053;, + 3;1054,1060,1053;, + 3;1061,3849,3847;, + 3;1055,1061,3847;, + 3;1062,1061,1055;, + 3;1056,1062,1055;, + 3;3850,1062,1056;, + 3;3848,3850,1056;, + 3;1064,1063,1057;, + 3;1058,1064,1057;, + 3;1065,1064,1058;, + 3;1059,1065,1058;, + 3;1066,1065,1059;, + 3;1060,1066,1059;, + 3;1067,3851,3849;, + 3;1061,1067,3849;, + 3;1068,1067,1061;, + 3;1062,1068,1061;, + 3;3852,1068,1062;, + 3;3850,3852,1062;, + 3;1070,1069,1063;, + 3;1064,1070,1063;, + 3;1071,1070,1064;, + 3;1065,1071,1064;, + 3;1072,1071,1065;, + 3;1066,1072,1065;, + 3;1073,3853,3851;, + 3;1067,1073,3851;, + 3;1074,1073,1067;, + 3;1068,1074,1067;, + 3;3854,1074,1068;, + 3;3852,3854,1068;, + 3;1070,1075,1069;, + 3;1071,1076,1070;, + 3;1075,1070,1076;, + 3;1072,1076,1071;, + 3;1073,3855,3853;, + 3;1074,3856,1073;, + 3;3855,1073,3856;, + 3;3854,3856,1074;, + 3;1078,1077,969;, + 3;971,1078,969;, + 3;1079,1078,971;, + 3;1009,1079,971;, + 3;1080,1079,1009;, + 3;970,1080,1009;, + 3;1081,3857,3836;, + 3;978,1081,3836;, + 3;1082,1081,978;, + 3;1013,1082,978;, + 3;3858,1082,1013;, + 3;3859,3858,1013;, + 3;1084,1083,1077;, + 3;1078,1084,1077;, + 3;1085,1084,1078;, + 3;1079,1085,1078;, + 3;1086,1085,1079;, + 3;1080,1086,1079;, + 3;1087,3860,3857;, + 3;1081,1087,3857;, + 3;1088,1087,1081;, + 3;1082,1088,1081;, + 3;3861,1088,1082;, + 3;3858,3861,1082;, + 3;1090,1089,1083;, + 3;1084,1090,1083;, + 3;1091,1090,1084;, + 3;1085,1091,1084;, + 3;1092,1091,1085;, + 3;1086,1092,1085;, + 3;1093,3862,3860;, + 3;1087,1093,3860;, + 3;1094,1093,1087;, + 3;1088,1094,1087;, + 3;3863,1094,1088;, + 3;3861,3863,1088;, + 3;1096,1095,1089;, + 3;1090,1096,1089;, + 3;1097,1096,1090;, + 3;1091,1097,1090;, + 3;1098,1097,1091;, + 3;1092,1098,1091;, + 3;1099,3864,3862;, + 3;1093,1099,3862;, + 3;1100,1099,1093;, + 3;1094,1100,1093;, + 3;3865,1100,1094;, + 3;3863,3865,1094;, + 3;1102,1101,1095;, + 3;1096,1102,1095;, + 3;1103,1102,1096;, + 3;1097,1103,1096;, + 3;1104,1103,1097;, + 3;1098,1104,1097;, + 3;1105,3866,3864;, + 3;1099,1105,3864;, + 3;1106,1105,1099;, + 3;1100,1106,1099;, + 3;3867,1106,1100;, + 3;3865,3867,1100;, + 3;1108,1107,1101;, + 3;1102,1108,1101;, + 3;1109,1108,1102;, + 3;1103,1109,1102;, + 3;1110,1109,1103;, + 3;1104,1110,1103;, + 3;1111,3868,3866;, + 3;1105,1111,3866;, + 3;1112,1111,1105;, + 3;1106,1112,1105;, + 3;3869,1112,1106;, + 3;3867,3869,1106;, + 3;1114,1113,1107;, + 3;1108,1114,1107;, + 3;1115,1114,1108;, + 3;1109,1115,1108;, + 3;1116,1115,1109;, + 3;1110,1116,1109;, + 3;1117,3870,3868;, + 3;1111,1117,3868;, + 3;1118,1117,1111;, + 3;1112,1118,1111;, + 3;3871,1118,1112;, + 3;3869,3871,1112;, + 3;1120,1119,1113;, + 3;1114,1120,1113;, + 3;1121,1120,1114;, + 3;1115,1121,1114;, + 3;1122,1121,1115;, + 3;1116,1122,1115;, + 3;1123,3872,3870;, + 3;1117,1123,3870;, + 3;1124,1123,1117;, + 3;1118,1124,1117;, + 3;3873,1124,1118;, + 3;3871,3873,1118;, + 3;1126,1125,1119;, + 3;1120,1126,1119;, + 3;1127,1126,1120;, + 3;1121,1127,1120;, + 3;1128,1127,1121;, + 3;1122,1128,1121;, + 3;1129,3874,3872;, + 3;1123,1129,3872;, + 3;1130,1129,1123;, + 3;1124,1130,1123;, + 3;3875,1130,1124;, + 3;3873,3875,1124;, + 3;1132,1131,1125;, + 3;1126,1132,1125;, + 3;1133,1132,1126;, + 3;1127,1133,1126;, + 3;1134,1133,1127;, + 3;1128,1134,1127;, + 3;1135,3876,3874;, + 3;1129,1135,3874;, + 3;1136,1135,1129;, + 3;1130,1136,1129;, + 3;3877,1136,1130;, + 3;3875,3877,1130;, + 3;1132,1137,1131;, + 3;1133,1138,1132;, + 3;1137,1132,1138;, + 3;1134,1138,1133;, + 3;1135,3878,3876;, + 3;1136,3879,1135;, + 3;3878,1135,3879;, + 3;3877,3879,1136;, + 3;1140,1139,972;, + 3;1010,1140,972;, + 3;1141,1140,1010;, + 3;976,1141,1010;, + 3;1142,1141,976;, + 3;969,1142,976;, + 3;1143,3880,3859;, + 3;1014,1143,3859;, + 3;1144,1143,1014;, + 3;977,1144,1014;, + 3;3881,1144,977;, + 3;3882,3881,977;, + 3;1146,1145,1139;, + 3;1140,1146,1139;, + 3;1147,1146,1140;, + 3;1141,1147,1140;, + 3;1148,1147,1141;, + 3;1142,1148,1141;, + 3;1149,3883,3880;, + 3;1143,1149,3880;, + 3;1150,1149,1143;, + 3;1144,1150,1143;, + 3;3884,1150,1144;, + 3;3881,3884,1144;, + 3;1152,1151,1145;, + 3;1146,1152,1145;, + 3;1153,1152,1146;, + 3;1147,1153,1146;, + 3;1154,1153,1147;, + 3;1148,1154,1147;, + 3;1155,3885,3883;, + 3;1149,1155,3883;, + 3;1156,1155,1149;, + 3;1150,1156,1149;, + 3;3886,1156,1150;, + 3;3884,3886,1150;, + 3;1158,1157,1151;, + 3;1152,1158,1151;, + 3;1159,1158,1152;, + 3;1153,1159,1152;, + 3;1160,1159,1153;, + 3;1154,1160,1153;, + 3;1161,3887,3885;, + 3;1155,1161,3885;, + 3;1162,1161,1155;, + 3;1156,1162,1155;, + 3;3888,1162,1156;, + 3;3886,3888,1156;, + 3;1164,1163,1157;, + 3;1158,1164,1157;, + 3;1165,1164,1158;, + 3;1159,1165,1158;, + 3;1166,1165,1159;, + 3;1160,1166,1159;, + 3;1167,3889,3887;, + 3;1161,1167,3887;, + 3;1168,1167,1161;, + 3;1162,1168,1161;, + 3;3890,1168,1162;, + 3;3888,3890,1162;, + 3;1170,1169,1163;, + 3;1164,1170,1163;, + 3;1171,1170,1164;, + 3;1165,1171,1164;, + 3;1172,1171,1165;, + 3;1166,1172,1165;, + 3;1173,3891,3889;, + 3;1167,1173,3889;, + 3;1174,1173,1167;, + 3;1168,1174,1167;, + 3;3892,1174,1168;, + 3;3890,3892,1168;, + 3;1176,1175,1169;, + 3;1170,1176,1169;, + 3;1177,1176,1170;, + 3;1171,1177,1170;, + 3;1178,1177,1171;, + 3;1172,1178,1171;, + 3;1179,3893,3891;, + 3;1173,1179,3891;, + 3;1180,1179,1173;, + 3;1174,1180,1173;, + 3;3894,1180,1174;, + 3;3892,3894,1174;, + 3;1182,1181,1175;, + 3;1176,1182,1175;, + 3;1183,1182,1176;, + 3;1177,1183,1176;, + 3;1184,1183,1177;, + 3;1178,1184,1177;, + 3;1185,3895,3893;, + 3;1179,1185,3893;, + 3;1186,1185,1179;, + 3;1180,1186,1179;, + 3;3896,1186,1180;, + 3;3894,3896,1180;, + 3;1188,1187,1181;, + 3;1182,1188,1181;, + 3;1189,1188,1182;, + 3;1183,1189,1182;, + 3;1190,1189,1183;, + 3;1184,1190,1183;, + 3;1191,3897,3895;, + 3;1185,1191,3895;, + 3;1192,1191,1185;, + 3;1186,1192,1185;, + 3;3898,1192,1186;, + 3;3896,3898,1186;, + 3;1194,1193,1187;, + 3;1188,1194,1187;, + 3;1195,1194,1188;, + 3;1189,1195,1188;, + 3;1196,1195,1189;, + 3;1190,1196,1189;, + 3;1197,3899,3897;, + 3;1191,1197,3897;, + 3;1198,1197,1191;, + 3;1192,1198,1191;, + 3;3900,1198,1192;, + 3;3898,3900,1192;, + 3;1194,1199,1193;, + 3;1195,1200,1194;, + 3;1199,1194,1200;, + 3;1196,1200,1195;, + 3;1197,3901,3899;, + 3;1198,3902,1197;, + 3;3901,1197,3902;, + 3;3900,3902,1198;, + 3;1202,1201,3832;, + 3;1011,1202,3832;, + 3;1203,1202,1011;, + 3;975,1203,1011;, + 3;1204,1203,975;, + 3;972,1204,975;, + 3;1205,3903,3882;, + 3;980,1205,3882;, + 3;1206,1205,980;, + 3;957,1206,980;, + 3;3904,1206,957;, + 3;962,3904,957;, + 3;1208,1207,1201;, + 3;1202,1208,1201;, + 3;1209,1208,1202;, + 3;1203,1209,1202;, + 3;1210,1209,1203;, + 3;1204,1210,1203;, + 3;1211,3905,3903;, + 3;1205,1211,3903;, + 3;1212,1211,1205;, + 3;1206,1212,1205;, + 3;3906,1212,1206;, + 3;3904,3906,1206;, + 3;1214,1213,1207;, + 3;1208,1214,1207;, + 3;1215,1214,1208;, + 3;1209,1215,1208;, + 3;1216,1215,1209;, + 3;1210,1216,1209;, + 3;1217,3907,3905;, + 3;1211,1217,3905;, + 3;1218,1217,1211;, + 3;1212,1218,1211;, + 3;3908,1218,1212;, + 3;3906,3908,1212;, + 3;1220,1219,1213;, + 3;1214,1220,1213;, + 3;1221,1220,1214;, + 3;1215,1221,1214;, + 3;1222,1221,1215;, + 3;1216,1222,1215;, + 3;1223,3909,3907;, + 3;1217,1223,3907;, + 3;1224,1223,1217;, + 3;1218,1224,1217;, + 3;3910,1224,1218;, + 3;3908,3910,1218;, + 3;1226,1225,1219;, + 3;1220,1226,1219;, + 3;1227,1226,1220;, + 3;1221,1227,1220;, + 3;1228,1227,1221;, + 3;1222,1228,1221;, + 3;1229,3911,3909;, + 3;1223,1229,3909;, + 3;1230,1229,1223;, + 3;1224,1230,1223;, + 3;3912,1230,1224;, + 3;3910,3912,1224;, + 3;1232,1231,1225;, + 3;1226,1232,1225;, + 3;1233,1232,1226;, + 3;1227,1233,1226;, + 3;1234,1233,1227;, + 3;1228,1234,1227;, + 3;1235,3913,3911;, + 3;1229,1235,3911;, + 3;1236,1235,1229;, + 3;1230,1236,1229;, + 3;3914,1236,1230;, + 3;3912,3914,1230;, + 3;1238,1237,1231;, + 3;1232,1238,1231;, + 3;1239,1238,1232;, + 3;1233,1239,1232;, + 3;1240,1239,1233;, + 3;1234,1240,1233;, + 3;1241,3915,3913;, + 3;1235,1241,3913;, + 3;1242,1241,1235;, + 3;1236,1242,1235;, + 3;3916,1242,1236;, + 3;3914,3916,1236;, + 3;1244,1243,1237;, + 3;1238,1244,1237;, + 3;1245,1244,1238;, + 3;1239,1245,1238;, + 3;1246,1245,1239;, + 3;1240,1246,1239;, + 3;1247,3917,3915;, + 3;1241,1247,3915;, + 3;1248,1247,1241;, + 3;1242,1248,1241;, + 3;3918,1248,1242;, + 3;3916,3918,1242;, + 3;1250,1249,3918;, + 3;1244,3919,1243;, + 3;1251,3919,1244;, + 3;1245,1251,1244;, + 3;1252,1251,1245;, + 3;1246,1252,1245;, + 3;1253,3920,3917;, + 3;1247,1253,3917;, + 3;1254,1253,1247;, + 3;1248,1254,1247;, + 3;1249,1254,1248;, + 3;3918,1249,1248;, + 3;1256,1255,3921;, + 3;3919,1256,3921;, + 3;1257,1256,3919;, + 3;1251,1257,3919;, + 3;1258,1257,1251;, + 3;1252,1258,1251;, + 3;1259,3922,3920;, + 3;1253,1259,3920;, + 3;1260,1259,1253;, + 3;1254,1260,1253;, + 3;3923,1260,1254;, + 3;1249,3923,1254;, + 3;1256,1261,1255;, + 3;1257,1262,1256;, + 3;1261,1256,1262;, + 3;1258,1262,1257;, + 3;1259,3924,3922;, + 3;1260,3925,1259;, + 3;3924,1259,3925;, + 3;3923,3925,1260;, + 3;3814,963,1263;, + 3;1263,973,956;, + 3;981,983,959;, + 3;983,981,1269;, + 3;3859,1264,1014;, + 3;1264,3859,1013;, + 3;3836,1265,978;, + 3;3836,979,1265;, + 3;3882,1266,980;, + 3;1266,3882,977;, + 3;1013,1265,1264;, + 3;1265,1013,978;, + 3;1014,1266,977;, + 3;1266,1014,1264;, + 3;1265,979,960;, + 3;957,981,3816;, + 3;3926,960,3834;, + 3;980,1266,1267;, + 3;1266,1269,1267;, + 3;983,1269,987;, + 3;1267,1269,981;, + 3;1269,1264,987;, + 3;1264,1269,1266;, + 3;1264,1265,987;, + 3;1265,986,987;, + 3;986,1265,960;, + 3;986,960,3926;, + 3;986,3926,3821;, + 3;1270,3815,1263;, + 3;974,1270,1008;, + 3;1277,1282,1271;, + 3;1271,3803,948;, + 3;1279,1278,1272;, + 3;1272,3807,3927;, + 3;949,3804,1273;, + 3;1284,3928,1275;, + 3;3808,3805,1274;, + 3;1276,3929,3930;, + 3;3928,1276,1275;, + 3;3928,3929,1276;, + 3;1274,949,1275;, + 3;1278,1277,948;, + 3;1272,1278,948;, + 3;1272,1280,1279;, + 3;1272,3927,1280;, + 3;1282,1281,947;, + 3;1271,1282,947;, + 3;1271,948,1277;, + 3;3810,1284,1283;, + 3;3810,3928,1284;, + 3;3806,3809,1283;, + 3;1273,3806,1283;, + 3;952,1282,1277;, + 3;952,3931,1282;, + 3;954,1278,1279;, + 3;954,952,1278;, + 3;1284,1275,949;, + 3;1273,1284,949;, + 3;1276,3930,950;, + 3;1274,1276,950;, + 3;1286,943,1285;, + 3;1286,850,1291;, + 3;1287,3759,3757;, + 3;1292,1287,3757;, + 3;1288,3798,1286;, + 3;1286,3798,850;, + 3;855,3932,1287;, + 3;855,945,3932;, + 3;849,1289,943;, + 3;1293,852,1289;, + 3;854,1290,860;, + 3;889,853,1290;, + 3;1286,1291,943;, + 3;849,943,1291;, + 3;855,1287,1292;, + 3;855,1292,3758;, + 3;856,852,1293;, + 3;1293,854,856;, + 3;3933,1286,1285;, + 3;946,3799,851;, + 3;946,3756,3801;, + 3;851,3800,943;, + 3;943,3800,1285;, + 3;3934,1286,3933;, + 3;3934,1288,1286;, + 3;1287,3932,3935;, + 3;1287,3935,3759;, + 3;1294,1295,1736;, + 3;1388,1296,1297;, + 3;1294,1389,1735;, + 3;1734,1738,1299;, + 3;1299,1389,1734;, + 3;1304,1390,1333;, + 3;1300,1332,1306;, + 3;1391,3936,1301;, + 3;1737,3937,3938;, + 3;3938,3939,3940;, + 3;1297,1296,1391;, + 3;1302,1294,1334;, + 3;1303,1295,1302;, + 3;1295,1294,1302;, + 3;1298,1735,1305;, + 3;3941,3937,1306;, + 3;3937,1300,1306;, + 3;1332,1390,1304;, + 3;1320,1335,1336;, + 3;1338,1307,1337;, + 3;1339,1340,1314;, + 3;1342,1308,1341;, + 3;1343,1344,1321;, + 3;1345,1337,1307;, + 3;1347,1319,1346;, + 3;1343,1348,1322;, + 3;1313,1335,1349;, + 3;1339,1350,1309;, + 3;1350,1349,1309;, + 3;1341,1340,1317;, + 3;1312,1351,1347;, + 3;3942,1336,3943;, + 3;1344,1310,1351;, + 3;1348,3944,3945;, + 3;1346,1319,1345;, + 3;3943,1313,1325;, + 3;1325,1324,3943;, + 3;1312,1323,1327;, + 3;1327,1326,1312;, + 3;3944,1321,1329;, + 3;1329,1328,3944;, + 3;1311,1314,1331;, + 3;1331,1330,1311;, + 3;1313,1311,1325;, + 3;1330,1325,1311;, + 3;1314,1308,3946;, + 3;3946,1331,1314;, + 3;1321,1312,1326;, + 3;1326,1329,1321;, + 3;1323,1307,3947;, + 3;3947,1327,1323;, + 3;1315,1316,3948;, + 3;3948,3949,1315;, + 3;1317,1309,3950;, + 3;3950,3951,1317;, + 3;1318,1317,3951;, + 3;3951,3952,1318;, + 3;1310,1322,3953;, + 3;3953,3954,1310;, + 3;1316,1319,3955;, + 3;3955,3948,1316;, + 3;1309,1320,3956;, + 3;3956,3950,1309;, + 3;1319,1310,3954;, + 3;3954,3955,1319;, + 3;1320,3957,3958;, + 3;3958,3956,1320;, + 3;1322,3959,3960;, + 3;3960,3953,1322;, + 3;1335,1313,1336;, + 3;1313,3943,1336;, + 3;1337,1316,1338;, + 3;1316,1315,1338;, + 3;1339,1309,1340;, + 3;1309,1317,1340;, + 3;1341,1317,1342;, + 3;1317,1318,1342;, + 3;1343,1322,1344;, + 3;1322,1310,1344;, + 3;1345,1319,1337;, + 3;1319,1316,1337;, + 3;1346,1323,1347;, + 3;1323,1312,1347;, + 3;1343,1321,1348;, + 3;1321,3944,1348;, + 3;1335,1320,1349;, + 3;1320,1309,1349;, + 3;1339,1314,1350;, + 3;1314,1311,1350;, + 3;1350,1311,1349;, + 3;1311,1313,1349;, + 3;1341,1308,1340;, + 3;1308,1314,1340;, + 3;1351,1310,1347;, + 3;1310,1319,1347;, + 3;3942,3957,1336;, + 3;3957,1320,1336;, + 3;1351,1312,1344;, + 3;1312,1321,1344;, + 3;3945,3959,1348;, + 3;3959,1322,1348;, + 3;1345,1307,1346;, + 3;1307,1323,1346;, + 3;1334,1294,1735;, + 3;3961,1295,1303;, + 3;1300,1390,1332;, + 3;1366,1353,1384;, + 3;1387,3962,1367;, + 3;1368,1369,1355;, + 3;1352,1370,1371;, + 3;1371,1356,1372;, + 3;1374,1360,1373;, + 3;3963,1358,1364;, + 3;1376,1358,1375;, + 3;1386,1353,1365;, + 3;1376,3964,1377;, + 3;1374,1353,1378;, + 3;1361,3965,1363;, + 3;1362,1358,3966;, + 3;1380,1359,1379;, + 3;1361,1381,1380;, + 3;1382,1383,1360;, + 3;3967,3968,3969;, + 3;3970,1364,1354;, + 3;1357,3967,3971;, + 3;1361,1362,3966;, + 3;1379,1359,1375;, + 3;3968,3967,1357;, + 3;1381,3972,3973;, + 3;3963,3966,1358;, + 3;1377,3964,3974;, + 3;1373,1360,1383;, + 3;1385,1384,1353;, + 3;1352,1385,1387;, + 3;1372,1356,1378;, + 3;1367,3962,3975;, + 3;1370,1368,1355;, + 3;1368,1367,1369;, + 3;1367,3975,1369;, + 3;1370,1355,1371;, + 3;1355,1356,1371;, + 3;1372,1366,1371;, + 3;1366,1352,1371;, + 3;1373,1365,1374;, + 3;1365,1353,1374;, + 3;1375,1359,1376;, + 3;1359,3964,1376;, + 3;1377,1364,1376;, + 3;1364,1358,1376;, + 3;1378,1356,1374;, + 3;1356,1360,1374;, + 3;1379,1362,1380;, + 3;1362,1361,1380;, + 3;1381,3973,1380;, + 3;3973,1359,1380;, + 3;1382,3968,1383;, + 3;3968,1357,1383;, + 3;1375,1358,1379;, + 3;1358,1362,1379;, + 3;1381,1361,3972;, + 3;1361,1363,3972;, + 3;3974,1354,1377;, + 3;1354,1364,1377;, + 3;1383,1357,1373;, + 3;1357,1365,1373;, + 3;1378,1353,1372;, + 3;1353,1366,1372;, + 3;1370,1352,1368;, + 3;1352,1367,1368;, + 3;1357,3971,1365;, + 3;1325,1324,1330;, + 3;3962,3976,3975;, + 3;1385,3977,3962;, + 3;1386,3971,1385;, + 3;1352,1366,1384;, + 3;1384,1385,1352;, + 3;1385,3971,3977;, + 3;3971,1386,1365;, + 3;1353,1386,1385;, + 3;1352,1387,1367;, + 3;1387,1385,3962;, + 3;3970,3963,1364;, + 3;3965,1361,3966;, + 3;1734,1388,1297;, + 3;1294,1734,1389;, + 3;1299,1735,1389;, + 3;3978,1295,3961;, + 3;3979,1296,3980;, + 3;1297,1391,1301;, + 3;1391,3979,3981;, + 3;1716,3982,1392;, + 3;3982,1716,3983;, + 3;3984,3985,1394;, + 3;1718,3986,3984;, + 3;3987,3983,1393;, + 3;1393,1717,3987;, + 3;1719,3988,1395;, + 3;1719,1394,3985;, + 3;1720,1719,1721;, + 3;1723,1722,1397;, + 3;1724,1399,1725;, + 3;1727,1726,1396;, + 3;1728,1718,1729;, + 3;1728,3989,3990;, + 3;1453,1401,1715;, + 3;1400,3991,3992;, + 3;1426,1712,1402;, + 3;1415,1418,1454;, + 3;3993,1398,1404;, + 3;1713,1433,1408;, + 3;3994,3991,1708;, + 3;1404,1427,3993;, + 3;1418,1415,1403;, + 3;1404,1398,1429;, + 3;3995,1402,1407;, + 3;1456,1419,1400;, + 3;1429,1398,3996;, + 3;1429,3996,1410;, + 3;1436,1409,1406;, + 3;1708,1457,1408;, + 3;1408,3997,3994;, + 3;1434,1409,1435;, + 3;3998,1411,3999;, + 3;1436,1437,1412;, + 3;1437,1436,1410;, + 3;3997,1408,1411;, + 3;1411,1413,3997;, + 3;1406,1409,1431;, + 3;1409,4000,1431;, + 3;1421,1453,1419;, + 3;1454,1418,1401;, + 3;1414,1416,1453;, + 3;1420,1417,1419;, + 3;1708,1418,1457;, + 3;1715,1401,1708;, + 3;1400,1715,3991;, + 3;1414,1453,1421;, + 3;1456,1420,1419;, + 3;1455,1421,1419;, + 3;3995,1427,1426;, + 3;1425,1402,1712;, + 3;1404,1426,1427;, + 3;3995,3993,1427;, + 3;1406,1429,1436;, + 3;1404,1429,1428;, + 3;1428,1429,1406;, + 3;1457,1430,1408;, + 3;1408,1430,1713;, + 3;1428,1406,1431;, + 3;1428,1431,1432;, + 3;3999,1408,1433;, + 3;1408,3999,1411;, + 3;1409,1434,4000;, + 3;1412,1435,1409;, + 3;1410,1436,1429;, + 3;1409,1436,1412;, + 3;1410,4001,1437;, + 3;1437,4001,1440;, + 3;1440,1439,1437;, + 3;1411,3998,1438;, + 3;1438,1441,1411;, + 3;1412,1437,1439;, + 3;1439,1442,1412;, + 3;1413,1411,1441;, + 3;1441,4002,1413;, + 3;1435,1412,1442;, + 3;1442,4003,1435;, + 3;1439,1440,1445;, + 3;1445,1444,1439;, + 3;1441,1438,1443;, + 3;1443,1446,1441;, + 3;4002,1441,1446;, + 3;1446,4004,4002;, + 3;4003,1442,1447;, + 3;1447,4005,4003;, + 3;1442,1439,1444;, + 3;1444,1447,1442;, + 3;1444,1445,1450;, + 3;1450,1449,1444;, + 3;1446,1443,1448;, + 3;1448,1451,1446;, + 3;4004,1446,1451;, + 3;1451,4006,4004;, + 3;4005,1447,1452;, + 3;1452,4007,4005;, + 3;1447,1444,1449;, + 3;1449,1452,1447;, + 3;1452,1449,1450;, + 3;4006,1451,1448;, + 3;4007,1452,1450;, + 3;1419,1715,1400;, + 3;1416,1401,1453;, + 3;1416,1454,1401;, + 3;1417,1455,1419;, + 3;4008,1456,1400;, + 3;1403,1457,1418;, + 3;1461,4009,1460;, + 3;1403,1415,4010;, + 3;1462,1403,4010;, + 3;1457,1403,1462;, + 3;1463,1457,1462;, + 3;1430,1457,1463;, + 3;1464,4011,4012;, + 3;1405,4011,1464;, + 3;1465,1405,1464;, + 3;1424,1405,1465;, + 3;1460,1424,1465;, + 3;4009,1424,1460;, + 3;1467,4013,1466;, + 3;4010,4013,1467;, + 3;1468,4010,1467;, + 3;1462,4010,1468;, + 3;1469,1462,1468;, + 3;1463,1462,1469;, + 3;1470,4012,4014;, + 3;1464,4012,1470;, + 3;1471,1464,1470;, + 3;1465,1464,1471;, + 3;4015,1465,1471;, + 3;1460,1465,4015;, + 3;1473,1466,1472;, + 3;1467,1466,1473;, + 3;1474,1467,1473;, + 3;1468,1467,1474;, + 3;1475,1468,1474;, + 3;1469,1468,1475;, + 3;1476,4014,4016;, + 3;1470,4014,1476;, + 3;1477,1470,1476;, + 3;1471,1470,1477;, + 3;4017,1471,1477;, + 3;4015,1471,4017;, + 3;1479,1472,1478;, + 3;1473,1472,1479;, + 3;1480,1473,1479;, + 3;1474,1473,1480;, + 3;1481,1474,1480;, + 3;1475,1474,1481;, + 3;1482,4016,4018;, + 3;1476,4016,1482;, + 3;1483,1476,1482;, + 3;1477,1476,1483;, + 3;4019,1477,1483;, + 3;4017,1477,4019;, + 3;1485,1478,1484;, + 3;1479,1478,1485;, + 3;1486,1479,1485;, + 3;1480,1479,1486;, + 3;1487,1480,1486;, + 3;1481,1480,1487;, + 3;1488,4018,4020;, + 3;1482,4018,1488;, + 3;1489,1482,1488;, + 3;1483,1482,1489;, + 3;4021,1483,1489;, + 3;4019,1483,4021;, + 3;1491,1484,1490;, + 3;1485,1484,1491;, + 3;1492,1485,1491;, + 3;1486,1485,1492;, + 3;1493,1486,1492;, + 3;1487,1486,1493;, + 3;1494,4020,4022;, + 3;1488,4020,1494;, + 3;1495,1488,1494;, + 3;1489,1488,1495;, + 3;4023,1489,1495;, + 3;4021,1489,4023;, + 3;1497,1490,1496;, + 3;1491,1490,1497;, + 3;1498,1491,1497;, + 3;1492,1491,1498;, + 3;1499,1492,1498;, + 3;1493,1492,1499;, + 3;1500,4022,4024;, + 3;1494,4022,1500;, + 3;1501,1494,1500;, + 3;1495,1494,1501;, + 3;4025,1495,1501;, + 3;4023,1495,4025;, + 3;1503,1496,1502;, + 3;1497,1496,1503;, + 3;1504,1497,1503;, + 3;1498,1497,1504;, + 3;1505,1498,1504;, + 3;1499,1498,1505;, + 3;1506,4024,4026;, + 3;1500,4024,1506;, + 3;1507,1500,1506;, + 3;1501,1500,1507;, + 3;4027,1501,1507;, + 3;4025,1501,4027;, + 3;1509,1502,1508;, + 3;1503,1502,1509;, + 3;1510,1503,1509;, + 3;1504,1503,1510;, + 3;1511,1504,1510;, + 3;1505,1504,1511;, + 3;1512,4026,4028;, + 3;1506,4026,1512;, + 3;1513,1506,1512;, + 3;1507,1506,1513;, + 3;4029,1507,1513;, + 3;4027,1507,4029;, + 3;1515,1508,1514;, + 3;1509,1508,1515;, + 3;1516,1509,1515;, + 3;1510,1509,1516;, + 3;1517,1510,1516;, + 3;1511,1510,1517;, + 3;1518,4028,4030;, + 3;1512,4028,1518;, + 3;1519,1512,1518;, + 3;1513,1512,1519;, + 3;4031,1513,1519;, + 3;4029,1513,4031;, + 3;1515,1514,1520;, + 3;1516,1515,1521;, + 3;1520,1521,1515;, + 3;1517,1516,1521;, + 3;1518,4030,4032;, + 3;1519,1518,4033;, + 3;4032,4033,1518;, + 3;4031,1519,4033;, + 3;1523,1414,1522;, + 3;1416,1414,1523;, + 3;1524,1416,1523;, + 3;1454,1416,1524;, + 3;1525,1454,1524;, + 3;1415,1454,1525;, + 3;1526,4009,4034;, + 3;1423,4009,1526;, + 3;1527,1423,1526;, + 3;1458,1423,1527;, + 3;4035,1458,1527;, + 3;4036,1458,4035;, + 3;1529,1522,1528;, + 3;1523,1522,1529;, + 3;1530,1523,1529;, + 3;1524,1523,1530;, + 3;1531,1524,1530;, + 3;1525,1524,1531;, + 3;1532,4034,4037;, + 3;1526,4034,1532;, + 3;1533,1526,1532;, + 3;1527,1526,1533;, + 3;4038,1527,1533;, + 3;4035,1527,4038;, + 3;1535,1528,1534;, + 3;1529,1528,1535;, + 3;1536,1529,1535;, + 3;1530,1529,1536;, + 3;1537,1530,1536;, + 3;1531,1530,1537;, + 3;1538,4037,4039;, + 3;1532,4037,1538;, + 3;1539,1532,1538;, + 3;1533,1532,1539;, + 3;4040,1533,1539;, + 3;4038,1533,4040;, + 3;1541,1534,1540;, + 3;1535,1534,1541;, + 3;1542,1535,1541;, + 3;1536,1535,1542;, + 3;1543,1536,1542;, + 3;1537,1536,1543;, + 3;1544,4039,4041;, + 3;1538,4039,1544;, + 3;1545,1538,1544;, + 3;1539,1538,1545;, + 3;4042,1539,1545;, + 3;4040,1539,4042;, + 3;1547,1540,1546;, + 3;1541,1540,1547;, + 3;1548,1541,1547;, + 3;1542,1541,1548;, + 3;1549,1542,1548;, + 3;1543,1542,1549;, + 3;1550,4041,4043;, + 3;1544,4041,1550;, + 3;1551,1544,1550;, + 3;1545,1544,1551;, + 3;4044,1545,1551;, + 3;4042,1545,4044;, + 3;1553,1546,1552;, + 3;1547,1546,1553;, + 3;1554,1547,1553;, + 3;1548,1547,1554;, + 3;1555,1548,1554;, + 3;1549,1548,1555;, + 3;1556,4043,4045;, + 3;1550,4043,1556;, + 3;1557,1550,1556;, + 3;1551,1550,1557;, + 3;4046,1551,1557;, + 3;4044,1551,4046;, + 3;1559,1552,1558;, + 3;1553,1552,1559;, + 3;1560,1553,1559;, + 3;1554,1553,1560;, + 3;1561,1554,1560;, + 3;1555,1554,1561;, + 3;1562,4045,4047;, + 3;1556,4045,1562;, + 3;1563,1556,1562;, + 3;1557,1556,1563;, + 3;4048,1557,1563;, + 3;4046,1557,4048;, + 3;1565,1558,1564;, + 3;1559,1558,1565;, + 3;1566,1559,1565;, + 3;1560,1559,1566;, + 3;1567,1560,1566;, + 3;1561,1560,1567;, + 3;1568,4047,4049;, + 3;1562,4047,1568;, + 3;1569,1562,1568;, + 3;1563,1562,1569;, + 3;4050,1563,1569;, + 3;4048,1563,4050;, + 3;1571,1564,1570;, + 3;1565,1564,1571;, + 3;1572,1565,1571;, + 3;1566,1565,1572;, + 3;1573,1566,1572;, + 3;1567,1566,1573;, + 3;1574,4049,4051;, + 3;1568,4049,1574;, + 3;1575,1568,1574;, + 3;1569,1568,1575;, + 3;4052,1569,1575;, + 3;4050,1569,4052;, + 3;1577,1570,1576;, + 3;1571,1570,1577;, + 3;1578,1571,1577;, + 3;1572,1571,1578;, + 3;1579,1572,1578;, + 3;1573,1572,1579;, + 3;1580,4051,4053;, + 3;1574,4051,1580;, + 3;1581,1574,1580;, + 3;1575,1574,1581;, + 3;4054,1575,1581;, + 3;4052,1575,4054;, + 3;1577,1576,1582;, + 3;1578,1577,1583;, + 3;1582,1583,1577;, + 3;1579,1578,1583;, + 3;1580,4053,4055;, + 3;1581,1580,4056;, + 3;4055,4056,1580;, + 3;4054,1581,4056;, + 3;1585,1417,1584;, + 3;1455,1417,1585;, + 3;1586,1455,1585;, + 3;1421,1455,1586;, + 3;1587,1421,1586;, + 3;1414,1421,1587;, + 3;1588,4036,4057;, + 3;1459,4036,1588;, + 3;1589,1459,1588;, + 3;1422,1459,1589;, + 3;4058,1422,1589;, + 3;4059,1422,4058;, + 3;1591,1584,1590;, + 3;1585,1584,1591;, + 3;1592,1585,1591;, + 3;1586,1585,1592;, + 3;1593,1586,1592;, + 3;1587,1586,1593;, + 3;1594,4057,4060;, + 3;1588,4057,1594;, + 3;1595,1588,1594;, + 3;1589,1588,1595;, + 3;4061,1589,1595;, + 3;4058,1589,4061;, + 3;1597,1590,1596;, + 3;1591,1590,1597;, + 3;1598,1591,1597;, + 3;1592,1591,1598;, + 3;1599,1592,1598;, + 3;1593,1592,1599;, + 3;1600,4060,4062;, + 3;1594,4060,1600;, + 3;1601,1594,1600;, + 3;1595,1594,1601;, + 3;4063,1595,1601;, + 3;4061,1595,4063;, + 3;1603,1596,1602;, + 3;1597,1596,1603;, + 3;1604,1597,1603;, + 3;1598,1597,1604;, + 3;1605,1598,1604;, + 3;1599,1598,1605;, + 3;1606,4062,4064;, + 3;1600,4062,1606;, + 3;1607,1600,1606;, + 3;1601,1600,1607;, + 3;4065,1601,1607;, + 3;4063,1601,4065;, + 3;1609,1602,1608;, + 3;1603,1602,1609;, + 3;1610,1603,1609;, + 3;1604,1603,1610;, + 3;1611,1604,1610;, + 3;1605,1604,1611;, + 3;1612,4064,4066;, + 3;1606,4064,1612;, + 3;1613,1606,1612;, + 3;1607,1606,1613;, + 3;4067,1607,1613;, + 3;4065,1607,4067;, + 3;1615,1608,1614;, + 3;1609,1608,1615;, + 3;1616,1609,1615;, + 3;1610,1609,1616;, + 3;1617,1610,1616;, + 3;1611,1610,1617;, + 3;1618,4066,4068;, + 3;1612,4066,1618;, + 3;1619,1612,1618;, + 3;1613,1612,1619;, + 3;4069,1613,1619;, + 3;4067,1613,4069;, + 3;1621,1614,1620;, + 3;1615,1614,1621;, + 3;1622,1615,1621;, + 3;1616,1615,1622;, + 3;1623,1616,1622;, + 3;1617,1616,1623;, + 3;1624,4068,4070;, + 3;1618,4068,1624;, + 3;1625,1618,1624;, + 3;1619,1618,1625;, + 3;4071,1619,1625;, + 3;4069,1619,4071;, + 3;1627,1620,1626;, + 3;1621,1620,1627;, + 3;1628,1621,1627;, + 3;1622,1621,1628;, + 3;1629,1622,1628;, + 3;1623,1622,1629;, + 3;1630,4070,4072;, + 3;1624,4070,1630;, + 3;1631,1624,1630;, + 3;1625,1624,1631;, + 3;4073,1625,1631;, + 3;4071,1625,4073;, + 3;1633,1626,1632;, + 3;1627,1626,1633;, + 3;1634,1627,1633;, + 3;1628,1627,1634;, + 3;1635,1628,1634;, + 3;1629,1628,1635;, + 3;1636,4072,4074;, + 3;1630,4072,1636;, + 3;1637,1630,1636;, + 3;1631,1630,1637;, + 3;4075,1631,1637;, + 3;4073,1631,4075;, + 3;1639,1632,1638;, + 3;1633,1632,1639;, + 3;1640,1633,1639;, + 3;1634,1633,1640;, + 3;1641,1634,1640;, + 3;1635,1634,1641;, + 3;1642,4074,4076;, + 3;1636,4074,1642;, + 3;1643,1636,1642;, + 3;1637,1636,1643;, + 3;4077,1637,1643;, + 3;4075,1637,4077;, + 3;1639,1638,1644;, + 3;1640,1639,1645;, + 3;1644,1645,1639;, + 3;1641,1640,1645;, + 3;1642,4076,4078;, + 3;1643,1642,4079;, + 3;4078,4079,1642;, + 3;4077,1643,4079;, + 3;1647,4008,1646;, + 3;1456,4008,1647;, + 3;1648,1456,1647;, + 3;1420,1456,1648;, + 3;1649,1420,1648;, + 3;1417,1420,1649;, + 3;1650,4059,4080;, + 3;1425,4059,1650;, + 3;1651,1425,1650;, + 3;1402,1425,1651;, + 3;4081,1402,1651;, + 3;1407,1402,4081;, + 3;1653,1646,1652;, + 3;1647,1646,1653;, + 3;1654,1647,1653;, + 3;1648,1647,1654;, + 3;1655,1648,1654;, + 3;1649,1648,1655;, + 3;1656,4080,4082;, + 3;1650,4080,1656;, + 3;1657,1650,1656;, + 3;1651,1650,1657;, + 3;4083,1651,1657;, + 3;4081,1651,4083;, + 3;1659,1652,1658;, + 3;1653,1652,1659;, + 3;1660,1653,1659;, + 3;1654,1653,1660;, + 3;1661,1654,1660;, + 3;1655,1654,1661;, + 3;1662,4082,4084;, + 3;1656,4082,1662;, + 3;1663,1656,1662;, + 3;1657,1656,1663;, + 3;4085,1657,1663;, + 3;4083,1657,4085;, + 3;1665,1658,1664;, + 3;1659,1658,1665;, + 3;1666,1659,1665;, + 3;1660,1659,1666;, + 3;1667,1660,1666;, + 3;1661,1660,1667;, + 3;1668,4084,4086;, + 3;1662,4084,1668;, + 3;1669,1662,1668;, + 3;1663,1662,1669;, + 3;4087,1663,1669;, + 3;4085,1663,4087;, + 3;1671,1664,1670;, + 3;1665,1664,1671;, + 3;1672,1665,1671;, + 3;1666,1665,1672;, + 3;1673,1666,1672;, + 3;1667,1666,1673;, + 3;1674,4086,4088;, + 3;1668,4086,1674;, + 3;1675,1668,1674;, + 3;1669,1668,1675;, + 3;4089,1669,1675;, + 3;4087,1669,4089;, + 3;1677,1670,1676;, + 3;1671,1670,1677;, + 3;1678,1671,1677;, + 3;1672,1671,1678;, + 3;1679,1672,1678;, + 3;1673,1672,1679;, + 3;1680,4088,4090;, + 3;1674,4088,1680;, + 3;1681,1674,1680;, + 3;1675,1674,1681;, + 3;4091,1675,1681;, + 3;4089,1675,4091;, + 3;1683,1676,1682;, + 3;1677,1676,1683;, + 3;1684,1677,1683;, + 3;1678,1677,1684;, + 3;1685,1678,1684;, + 3;1679,1678,1685;, + 3;1686,4090,4092;, + 3;1680,4090,1686;, + 3;1687,1680,1686;, + 3;1681,1680,1687;, + 3;4093,1681,1687;, + 3;4091,1681,4093;, + 3;1689,1682,1688;, + 3;1683,1682,1689;, + 3;1690,1683,1689;, + 3;1684,1683,1690;, + 3;1691,1684,1690;, + 3;1685,1684,1691;, + 3;1692,4092,4094;, + 3;1686,4092,1692;, + 3;1693,1686,1692;, + 3;1687,1686,1693;, + 3;4095,1687,1693;, + 3;4093,1687,4095;, + 3;1695,1688,1694;, + 3;1689,1688,1695;, + 3;1696,1689,1695;, + 3;1690,1689,1696;, + 3;1697,1690,1696;, + 3;1691,1690,1697;, + 3;1698,4094,4096;, + 3;1692,4094,1698;, + 3;1699,1692,1698;, + 3;1693,1692,1699;, + 3;4097,1693,1699;, + 3;4095,1693,4097;, + 3;1701,1694,1700;, + 3;1695,1694,1701;, + 3;1702,1695,1701;, + 3;1696,1695,1702;, + 3;1703,1696,1702;, + 3;1697,1696,1703;, + 3;1704,4096,4098;, + 3;1698,4096,1704;, + 3;1705,1698,1704;, + 3;1699,1698,1705;, + 3;4099,1699,1705;, + 3;4097,1699,4099;, + 3;1701,1700,1706;, + 3;1702,1701,1707;, + 3;1706,1707,1701;, + 3;1703,1702,1707;, + 3;1704,4098,4100;, + 3;1705,1704,4101;, + 3;4100,4101,1704;, + 3;4099,1705,4101;, + 3;3994,1708,1408;, + 3;1708,1401,1418;, + 3;1426,1404,1428;, + 3;1428,1714,1426;, + 3;4036,1459,1709;, + 3;1709,1458,4036;, + 3;4009,1423,1710;, + 3;4009,1710,1424;, + 3;4059,1425,1711;, + 3;1711,1422,4059;, + 3;1458,1709,1710;, + 3;1710,1423,1458;, + 3;1459,1422,1711;, + 3;1711,1709,1459;, + 3;1710,1405,1424;, + 3;1402,3995,1426;, + 3;4102,4011,1405;, + 3;1425,1712,1711;, + 3;1711,1712,1714;, + 3;1428,1432,1714;, + 3;1712,1426,1714;, + 3;1714,1432,1709;, + 3;1709,1711,1714;, + 3;1709,1432,1710;, + 3;1710,1432,1431;, + 3;1431,1405,1710;, + 3;1431,4102,1405;, + 3;1431,4000,4102;, + 3;1715,1708,3991;, + 3;1419,1453,1715;, + 3;1722,1716,1727;, + 3;1716,1393,3983;, + 3;1724,1717,1723;, + 3;1717,4103,3987;, + 3;1394,1718,3984;, + 3;1729,1720,4104;, + 3;3988,1719,3985;, + 3;1721,4105,4106;, + 3;4104,1720,1721;, + 3;4104,1721,4106;, + 3;1719,1720,1394;, + 3;1723,1393,1722;, + 3;1717,1393,1723;, + 3;1717,1724,1725;, + 3;1717,1725,4103;, + 3;1727,1392,1726;, + 3;1716,1392,1727;, + 3;1716,1722,1393;, + 3;3989,1728,1729;, + 3;3989,1729,4104;, + 3;3986,1728,3990;, + 3;1718,1728,3986;, + 3;1397,1722,1727;, + 3;1397,1727,1396;, + 3;1399,1724,1723;, + 3;1399,1723,1397;, + 3;1729,1394,1720;, + 3;1718,1394,1729;, + 3;1721,1395,4105;, + 3;1719,1395,1721;, + 3;1731,1730,1388;, + 3;1731,1736,1295;, + 3;1732,3938,3940;, + 3;1737,3938,1732;, + 3;1733,1731,3978;, + 3;1731,1295,3978;, + 3;1300,1732,4107;, + 3;1300,4107,1390;, + 3;1294,1388,1734;, + 3;1738,1734,1297;, + 3;1299,1305,1735;, + 3;1334,1735,1298;, + 3;1731,1388,1736;, + 3;1294,1736,1388;, + 3;1300,1737,1732;, + 3;1300,3937,1737;, + 3;1301,1738,1297;, + 3;1738,1301,1299;, + 3;4108,1730,1731;, + 3;1391,1296,3979;, + 3;1391,3981,3936;, + 3;1296,1388,3980;, + 3;1388,1730,3980;, + 3;4109,4108,1731;, + 3;4109,1731,1733;, + 3;1732,4110,4107;, + 3;1732,3940,4110;, + 3;196,4111,197;, + 3;3759,4112,3760;, + 3;3938,4113,3939;, + 3;74,75,4114;, + 3;1744,6,1742;, + 3;10,97,1739;, + 3;1743,1745,142;, + 3;1740,144,215;, + 3;4115,4116,1741;, + 3;1741,1744,4115;, + 3;4117,4118,1742;, + 3;1742,1745,4117;, + 3;4118,4115,1744;, + 3;1744,1742,4118;, + 3;4119,4117,1745;, + 3;1745,1743,4119;, + 3;118,107,3471;, + 3;3460,3471,107;, + 3;233,3527,3528;, + 3;3528,3518,224;, + 3;106,5,87;, + 3;106,87,110;, + 3;1779,1790,1756;, + 3;1757,1819,1751;, + 3;1825,1826,4120;, + 3;1758,1829,1748;, + 3;2386,2124,2140;, + 3;2330,2146,2425;, + 3;1870,1872,1782;, + 3;4121,1846,4122;, + 3;1834,1835,1759;, + 3;2183,2240,2182;, + 3;2698,2714,2138;, + 3;2344,2518,2356;, + 3;4123,1852,4124;, + 3;1761,1865,4125;, + 3;1818,1799,1766;, + 3;2711,2132,2707;, + 3;2288,2450,2748;, + 3;2129,2213,2725;, + 3;2726,2753,2169;, + 3;2461,2471,2433;, + 3;1762,1763,1760;, + 3;1770,1772,1771;, + 3;2214,2022,2040;, + 3;2457,2193,2206;, + 3;2749,2758,2168;, + 3;2184,2176,2239;, + 3;2041,2190,2052;, + 3;2163,2231,2287;, + 3;2739,2284,2036;, + 3;2724,2204,2180;, + 3;2194,2044,2056;, + 3;2185,2196,2175;, + 3;2186,2043,2195;, + 3;2189,2042,2178;, + 3;2205,2188,2179;, + 3;2113,2062,2070;, + 3;2192,2458,2064;, + 3;2075,2198,2074;, + 3;2177,2042,2187;, + 3;2199,2053,2073;, + 3;2191,2065,2051;, + 3;2174,2197,2076;, + 3;2200,2700,2211;, + 3;2712,2202,2131;, + 3;2121,2396,2209;, + 3;2203,2212,2130;, + 3;1833,1800,1831;, + 3;2222,2021,2215;, + 3;2173,2077,2090;, + 3;2221,2037,2034;, + 3;2084,2020,2223;, + 3;2285,2220,2035;, + 3;2723,2181,2232;, + 3;2256,2282,2245;, + 3;2261,2278,2270;, + 3;2251,2281,2257;, + 3;2246,2277,2262;, + 3;2269,2279,2275;, + 3;2164,2249,2230;, + 3;2248,2165,2243;, + 3;2170,2259,2238;, + 3;2258,2171,2255;, + 3;2216,2267,2226;, + 3;2266,2217,2265;, + 3;2081,2254,2172;, + 3;2253,2082,2273;, + 3;2224,2272,2083;, + 3;2271,2225,2268;, + 3;2228,2264,2218;, + 3;2263,2229,2250;, + 3;2236,2242,2166;, + 3;2241,2237,2260;, + 3;2280,2252,2274;, + 3;2276,2247,2244;, + 3;2160,2738,2732;, + 3;2227,2219,2286;, + 3;2143,2159,2429;, + 3;2297,2449,2289;, + 3;2142,2430,2291;, + 3;2309,2469,2495;, + 3;2434,2127,2768;, + 3;2472,2437,2308;, + 3;2477,2302,2444;, + 3;2730,2028,2746;, + 3;4126,1823,1747;, + 3;1769,1778,3416;, + 3;4127,1838,1750;, + 3;1883,1763,1762;, + 3;1765,1856,4128;, + 3;1764,1804,1784;, + 3;1858,1859,4129;, + 3;1777,1760,1763;, + 3;1749,1752,1763;, + 3;1746,1806,1767;, + 3;1773,3416,1775;, + 3;1771,1769,1770;, + 3;4130,4131,4132;, + 3;4133,4134,1768;, + 3;4135,4136,4137;, + 3;4136,4135,4138;, + 3;4137,4139,4140;, + 3;4139,4137,4136;, + 3;4141,4142,4143;, + 3;1776,4140,4139;, + 3;1774,1768,4134;, + 3;4144,4143,4142;, + 3;4132,4138,4135;, + 3;4138,4132,4131;, + 3;4143,4144,1774;, + 3;3416,1773,4145;, + 3;1768,1774,4144;, + 3;4142,4141,1776;, + 3;3416,4145,1770;, + 3;4146,2141,4147;, + 3;4140,1776,4141;, + 3;3416,4148,1775;, + 3;4131,4130,4133;, + 3;4149,1807,4150;, + 3;4134,4133,4130;, + 3;2715,2709,2333;, + 3;2319,2343,2549;, + 3;4151,1849,4152;, + 3;2145,4153,2704;, + 3;2710,2703,2332;, + 3;2524,2523,2346;, + 3;1783,1809,4154;, + 3;2320,2147,2342;, + 3;2335,2352,2329;, + 3;2351,2336,2350;, + 3;2363,2341,2148;, + 3;2367,2328,2353;, + 3;2375,2349,2337;, + 3;2370,2385,2536;, + 3;2537,2360,2135;, + 3;4155,1867,4156;, + 3;2327,2368,2362;, + 3;2513,2512,2355;, + 3;2149,2361,2369;, + 3;2531,2529,2374;, + 3;2348,2376,2372;, + 3;1785,1811,4157;, + 3;2389,2383,2378;, + 3;2381,2134,2357;, + 3;2384,2371,2377;, + 3;2133,2382,2390;, + 3;4158,1877,4159;, + 3;2338,2388,2379;, + 3;2393,2098,2401;, + 3;2392,2397,2115;, + 3;2109,2060,2399;, + 3;2394,2412,2097;, + 3;2411,2395,2122;, + 3;1755,1813,1787;, + 3;2407,2423,2101;, + 3;2422,2408,2415;, + 3;2402,2414,2409;, + 3;2413,2403,2418;, + 3;2419,2417,2404;, + 3;2416,2420,2108;, + 3;2099,2107,2421;, + 3;4160,1840,4161;, + 3;1788,1861,4162;, + 3;1754,1843,4163;, + 3;2102,2096,2406;, + 3;2114,2398,2061;, + 3;2112,2400,2091;, + 3;4164,1873,4165;, + 3;2424,2141,2318;, + 3;1779,1879,1790;, + 3;1756,1790,1879;, + 3;1757,4166,1820;, + 3;1751,1819,4166;, + 3;1825,4167,1827;, + 3;4120,1826,4167;, + 3;1758,1828,1830;, + 3;1748,1829,1828;, + 3;1870,1871,1794;, + 3;1782,1872,1871;, + 3;4121,4168,1847;, + 3;4122,1846,4168;, + 3;1834,1836,1796;, + 3;1759,1835,1753;, + 3;4123,4169,1853;, + 3;4124,1852,4169;, + 3;1761,1864,1866;, + 3;4125,1865,1864;, + 3;4170,1789,1799;, + 3;1766,1799,1789;, + 3;1833,1832,1800;, + 3;1831,1800,1832;, + 3;1824,1822,1801;, + 3;1747,1823,1822;, + 3;4127,4171,1837;, + 3;1750,1837,4171;, + 3;1857,1855,1803;, + 3;4128,1856,1855;, + 3;4154,1781,4172;, + 3;4173,4174,4175;, + 3;1858,1860,1805;, + 3;4129,1859,1786;, + 3;1746,4176,1881;, + 3;1767,1806,1880;, + 3;4149,4177,1807;, + 3;4150,1882,4178;, + 3;4151,1850,1851;, + 3;4152,1849,4179;, + 3;1783,1781,1809;, + 3;4154,1809,1781;, + 3;4155,4180,1868;, + 3;4156,1867,4180;, + 3;1785,4181,1811;, + 3;4157,1811,4181;, + 3;1878,1876,1812;, + 3;4159,1877,1876;, + 3;2410,2426,2405;, + 3;4160,4182,1841;, + 3;4161,1840,4182;, + 3;1788,4183,1862;, + 3;4162,1861,4183;, + 3;1754,4184,1844;, + 3;4163,1843,4184;, + 3;4164,1874,1875;, + 3;4165,1873,4185;, + 3;4186,4187,4188;, + 3;4187,4186,4189;, + 3;4170,1799,1818;, + 3;4187,4189,4190;, + 3;2152,2456,2489;, + 3;2431,2300,2290;, + 3;2156,2126,2435;, + 3;2476,2301,2478;, + 3;2438,2764,2307;, + 3;2501,2485,2296;, + 3;2446,2311,2728;, + 3;2310,2447,2468;, + 3;2155,2436,2473;, + 3;2452,2293,2491;, + 3;2459,2118,2063;, + 3;2150,2465,2428;, + 3;2432,2466,2299;, + 3;2451,2492,2488;, + 3;2467,2448,2298;, + 3;2153,2500,2455;, + 3;2454,2496,2505;, + 3;2453,2506,2292;, + 3;2295,2482,2316;, + 3;2462,2494,2470;, + 3;2493,2463,2487;, + 3;2315,2483,2442;, + 3;2440,2503,2481;, + 3;2502,2441,2484;, + 3;2151,2486,2464;, + 3;2479,2498,2475;, + 3;2497,2480,2504;, + 3;2154,2474,2499;, + 3;2317,2490,2294;, + 3;2507,2366,2354;, + 3;2550,2340,2364;, + 3;2326,2544,2561;, + 3;2345,2519,2517;, + 3;2562,2325,2556;, + 3;2373,2530,2347;, + 3;2568,2324,2563;, + 3;2359,2538,2534;, + 3;2323,2569,2541;, + 3;2535,2380,2358;, + 3;2574,2528,2532;, + 3;2717,2543,2136;, + 3;2620,2599,2606;, + 3;2548,2339,2551;, + 3;2621,2629,2598;, + 3;2508,2555,2365;, + 3;2590,2634,2601;, + 3;2630,2625,2600;, + 3;2613,2589,2612;, + 3;2592,2582,2558;, + 3;2655,2616,2649;, + 3;2615,2656,2654;, + 3;2570,2579,2540;, + 3;2539,2580,2533;, + 3;2583,2567,2557;, + 3;2614,2650,2588;, + 3;2611,2581,2593;, + 3;2610,2594,2602;, + 3;2525,2608,2522;, + 3;2607,2526,2619;, + 3;2514,2596,2511;, + 3;2595,2515,2605;, + 3;2545,2632,2560;, + 3;2631,2546,2624;, + 3;2520,2604,2516;, + 3;2603,2521,2609;, + 3;2564,2645,2573;, + 3;2644,2565,2639;, + 3;2575,2618,2527;, + 3;2617,2576,2648;, + 3;2552,2623,2547;, + 3;2622,2553,2628;, + 3;2509,2627,2554;, + 3;2626,2510,2597;, + 3;2591,2559,2633;, + 3;2661,2647,2577;, + 3;2666,2572,2640;, + 3;2584,2638,2566;, + 3;2683,2676,2671;, + 3;2684,2682,2675;, + 3;2689,2681,2685;, + 3;2680,2690,2697;, + 3;2578,2571,2667;, + 3;2662,2660,2646;, + 3;2657,2687,2653;, + 3;2686,2658,2693;, + 3;2651,2669,2587;, + 3;2668,2652,2688;, + 3;2635,2678,2643;, + 3;2677,2636,2674;, + 3;2641,2695,2665;, + 3;2694,2642,2679;, + 3;2585,2673,2637;, + 3;2672,2586,2670;, + 3;2663,2692,2659;, + 3;2691,2664,2696;, + 3;1819,1791,1821;, + 3;1757,1820,1819;, + 3;2701,2120,2210;, + 3;2119,2702,2139;, + 3;1820,1791,1819;, + 3;1820,1821,1791;, + 3;1819,1821,4166;, + 3;1820,4166,1821;, + 3;1747,1822,4191;, + 3;4126,4191,1822;, + 3;1823,1801,1822;, + 3;1824,1801,1823;, + 3;4126,1822,1824;, + 3;4126,1824,1823;, + 3;4192,4167,1825;, + 3;4192,1825,4120;, + 3;1826,1827,4167;, + 3;1825,1792,1826;, + 3;1825,1827,1792;, + 3;1826,1792,1827;, + 3;1748,1828,4193;, + 3;1758,4193,1828;, + 3;1829,1793,1828;, + 3;1758,1830,1829;, + 3;1830,1793,1829;, + 3;1830,1828,1793;, + 3;4194,1831,4195;, + 3;4195,1831,4196;, + 3;1831,1832,4196;, + 3;4194,4196,1832;, + 3;4194,1832,1833;, + 3;4194,1833,1831;, + 3;4197,1753,1834;, + 3;4197,1834,1759;, + 3;1835,1796,1836;, + 3;1834,1796,1835;, + 3;1835,1836,1753;, + 3;1834,1753,1836;, + 3;1839,1837,1802;, + 3;1750,1838,1837;, + 3;1838,1802,1837;, + 3;1839,1802,1838;, + 3;4127,1837,1839;, + 3;4127,1839,1838;, + 3;1840,1814,1842;, + 3;4160,1841,1840;, + 3;1841,1814,1840;, + 3;1841,1842,1814;, + 3;1840,1842,4182;, + 3;1841,4182,1842;, + 3;1843,1845,4184;, + 3;1754,1844,1843;, + 3;1844,1816,1843;, + 3;1844,4184,1845;, + 3;1844,1845,1816;, + 3;1843,1816,1845;, + 3;1846,1848,4168;, + 3;4121,1847,1846;, + 3;1847,1795,1846;, + 3;1847,4168,1848;, + 3;1847,1848,1795;, + 3;1846,1795,1848;, + 3;1849,1808,1850;, + 3;4151,1851,1849;, + 3;1849,1850,4179;, + 3;4151,4179,1850;, + 3;1851,1808,1849;, + 3;1851,1850,1808;, + 3;1852,1854,4169;, + 3;4123,1853,1852;, + 3;1853,1797,1852;, + 3;1853,4169,1854;, + 3;1853,1854,1797;, + 3;1852,1797,1854;, + 3;4128,1855,4198;, + 3;1765,4198,1855;, + 3;1856,1803,1855;, + 3;1857,1803,1856;, + 3;1765,1855,1857;, + 3;1765,1857,1856;, + 3;4199,1786,1858;, + 3;4199,1858,4129;, + 3;1859,1805,1860;, + 3;1858,1805,1859;, + 3;1859,1860,1786;, + 3;1858,1786,1860;, + 3;1861,1815,1863;, + 3;1788,1862,1861;, + 3;1862,1815,1861;, + 3;1862,1863,1815;, + 3;1861,1863,4183;, + 3;1862,4183,1863;, + 3;4125,1864,4200;, + 3;1761,4200,1864;, + 3;1865,1798,1864;, + 3;1761,1866,1865;, + 3;1866,1798,1865;, + 3;1866,1864,1798;, + 3;1867,1869,4180;, + 3;4155,1868,1867;, + 3;1868,1810,1867;, + 3;1868,4180,1869;, + 3;1868,1869,1810;, + 3;1867,1810,1869;, + 3;4201,1780,1870;, + 3;4201,1870,1782;, + 3;1782,1871,1780;, + 3;1870,1780,1871;, + 3;1872,1794,1871;, + 3;1870,1794,1872;, + 3;1873,1817,1874;, + 3;4164,1875,1873;, + 3;1873,1874,4185;, + 3;4164,4185,1874;, + 3;1875,1817,1873;, + 3;1875,1874,1817;, + 3;4159,1876,4202;, + 3;4158,4202,1876;, + 3;1877,1812,1876;, + 3;1878,1812,1877;, + 3;4158,1876,1878;, + 3;4158,1878,1877;, + 3;1756,1879,4203;, + 3;1779,4203,1879;, + 3;4177,4178,1882;, + 3;1880,1881,4176;, + 3;1746,1881,1806;, + 3;1880,1806,1881;, + 3;4177,1882,1807;, + 3;4150,1807,1882;, + 3;2144,2705,2158;, + 3;2706,2125,2157;, + 3;2699,2201,2713;, + 3;2137,2708,2716;, + 3;2322,2542,2718;, + 3;2321,2719,2334;, + 3;2117,2460,2207;, + 3;2116,2208,2391;, + 3;2306,2759,2756;, + 3;2303,2314,2443;, + 3;2168,2235,2167;, + 3;2445,2729,2747;, + 3;2027,2731,2733;, + 3;2161,2741,2737;, + 3;2162,2283,2740;, + 3;1749,1763,1883;, + 3;2745,2023,2030;, + 3;2313,2304,2751;, + 3;2727,2312,2752;, + 3;2750,2305,2757;, + 3;2761,2722,2233;, + 3;2760,2234,2755;, + 3;2439,2765,2763;, + 3;2766,2721,2762;, + 3;2767,2128,2720;, + 3;4204,1884,4205;, + 3;4206,1885,4207;, + 3;2387,2427,2123;, + 3;1884,4206,4205;, + 3;4204,4206,1884;, + 3;1885,4204,4207;, + 3;4206,4204,1885;, + 3;1910,1887,1921;, + 3;1888,4208,1950;, + 3;1956,4209,1957;, + 3;1889,4210,1960;, + 3;3044,2796,2780;, + 3;2987,3083,2802;, + 3;2001,1913,2003;, + 3;4211,4212,1977;, + 3;1965,1890,1966;, + 3;2839,2838,2896;, + 3;3357,2790,3373;, + 3;3001,3013,3177;, + 3;4213,4214,1983;, + 3;1892,4215,1996;, + 3;1949,1897,1930;, + 3;3369,3366,2788;, + 3;2944,3395,3109;, + 3;2783,3384,2869;, + 3;3385,2825,3400;, + 3;3120,3092,3130;, + 3;1893,1891,1894;, + 3;1901,1902,1903;, + 3;2870,2039,2017;, + 3;3116,2866,2849;, + 3;3399,2816,3405;, + 3;2843,2888,2832;, + 3;2048,2049,2846;, + 3;2821,2943,2887;, + 3;2744,2031,2941;, + 3;3379,2834,2868;, + 3;2850,2055,2045;, + 3;2842,2826,2854;, + 3;2841,2855,2046;, + 3;2847,2836,2047;, + 3;2867,2835,2848;, + 3;2769,2069,2057;, + 3;2844,2067,3119;, + 3;2080,2071,2852;, + 3;2837,2840,2047;, + 3;2851,2072,2054;, + 3;2845,2050,2066;, + 3;2827,2079,2853;, + 3;2856,2861,3360;, + 3;3368,2781,2858;, + 3;2777,2863,3054;, + 3;2857,2782,2860;, + 3;1964,1962,1931;, + 3;2878,2877,2018;, + 3;2828,2089,2078;, + 3;2871,2033,2038;, + 3;2085,2882,2019;, + 3;2940,2032,2872;, + 3;3380,2895,2833;, + 3;2912,2901,2938;, + 3;2917,2926,2935;, + 3;2907,2916,2932;, + 3;2902,2921,2936;, + 3;2922,2931,2934;, + 3;2820,2883,2904;, + 3;2905,2898,2819;, + 3;2831,2889,2914;, + 3;2915,2908,2830;, + 3;2876,2879,2924;, + 3;2925,2918,2875;, + 3;2088,2829,2909;, + 3;2910,2928,2087;, + 3;2881,2086,2929;, + 3;2930,2923,2880;, + 3;2885,2874,2919;, + 3;2920,2903,2884;, + 3;2891,2818,2899;, + 3;2900,2913,2890;, + 3;2933,2927,2911;, + 3;2937,2897,2906;, + 3;2824,3386,2735;, + 3;2886,2939,2873;, + 3;2799,3090,2815;, + 3;2953,2947,3104;, + 3;2800,2945,3089;, + 3;2965,3154,3126;, + 3;3093,3415,2785;, + 3;3131,2964,3096;, + 3;3136,3103,2962;, + 3;3388,3393,2025;, + 3;4216,4217,1954;, + 3;1900,1901,3417;, + 3;4218,4219,1969;, + 3;2014,1893,1894;, + 3;1896,4220,1987;, + 3;1895,1915,1935;, + 3;1989,4221,1990;, + 3;1908,1894,1891;, + 3;1749,1894,1752;, + 3;1746,1898,1937;, + 3;3417,1906,1899;, + 3;1902,1901,1900;, + 3;4222,4223,4224;, + 3;1909,4225,4226;, + 3;4135,4137,4227;, + 3;4227,4228,4135;, + 3;4137,4229,4230;, + 3;4230,4227,4137;, + 3;4231,4232,1904;, + 3;1907,4230,4229;, + 3;1905,4226,4225;, + 3;4233,1904,4232;, + 3;4223,4135,4228;, + 3;4228,4224,4223;, + 3;4232,1905,4233;, + 3;1906,3417,4234;, + 3;4225,4233,1905;, + 3;1904,1907,4231;, + 3;4235,1900,3417;, + 3;2801,1908,1891;, + 3;4229,4231,1907;, + 3;4235,3417,1899;, + 3;4224,1909,4222;, + 3;4236,4237,1938;, + 3;4226,4222,1909;, + 3;3374,2989,3371;, + 3;2975,3208,3000;, + 3;4238,4239,1980;, + 3;2802,3364,2991;, + 3;3370,2990,3365;, + 3;3183,3006,3182;, + 3;1914,4240,1940;, + 3;2982,2996,2805;, + 3;2995,2986,3011;, + 3;3012,3002,2994;, + 3;3021,2804,2997;, + 3;3024,3010,2983;, + 3;3033,2993,3003;, + 3;3028,3195,3043;, + 3;3196,2793,3017;, + 3;4241,4242,1998;, + 3;2984,3019,3023;, + 3;3176,3008,3171;, + 3;2803,3022,3020;, + 3;3194,3029,3185;, + 3;3004,3031,3037;, + 3;1916,4243,1942;, + 3;3046,3035,3039;, + 3;3041,3016,2794;, + 3;3038,3036,3032;, + 3;2795,3045,3040;, + 3;4244,4245,2008;, + 3;2992,3034,3047;, + 3;3051,3059,2093;, + 3;3052,2773,3058;, + 3;2110,3056,2059;, + 3;3050,2094,3070;, + 3;3064,2776,3049;, + 3;1886,1918,1944;, + 3;3068,2104,3080;, + 3;3081,3071,3067;, + 3;3060,3066,3072;, + 3;3073,3074,3063;, + 3;3077,3062,3075;, + 3;3076,2105,3079;, + 3;2100,3078,2106;, + 3;4246,4247,1971;, + 3;1919,4248,1992;, + 3;4249,4250,1974;, + 3;2103,3069,2095;, + 3;2774,2058,3057;, + 3;2111,2092,3055;, + 3;4251,4252,2004;, + 3;3082,2974,4253;, + 3;1910,1921,2010;, + 3;1887,2010,1921;, + 3;1888,1951,4254;, + 3;4208,4254,1950;, + 3;1956,1958,4255;, + 3;4209,4255,1957;, + 3;1889,1961,1959;, + 3;4210,1959,1960;, + 3;2001,1925,2002;, + 3;1913,2002,2003;, + 3;4211,1978,4256;, + 3;4212,4256,1977;, + 3;1965,1927,1967;, + 3;1890,4257,1966;, + 3;4213,1984,4258;, + 3;4214,4258,1983;, + 3;1892,1997,1995;, + 3;4215,1995,1996;, + 3;4259,1930,1920;, + 3;1897,1920,1930;, + 3;1964,1931,1963;, + 3;1962,1963,1931;, + 3;1955,1932,1953;, + 3;4217,1953,1954;, + 3;4218,1968,4260;, + 3;4219,4260,1968;, + 3;1988,1934,1986;, + 3;4220,1986,1987;, + 3;4240,4261,1912;, + 3;3018,2985,3084;, + 3;1989,1936,1991;, + 3;4221,1917,1990;, + 3;1746,2012,4176;, + 3;1898,2011,1937;, + 3;4236,1938,4262;, + 3;4237,4178,2013;, + 3;4238,1982,1981;, + 3;4239,4263,1980;, + 3;1914,1940,1912;, + 3;4240,1912,1940;, + 3;4241,1999,4264;, + 3;4242,4264,1998;, + 3;1916,1942,4265;, + 3;4243,4265,1942;, + 3;2009,1943,2007;, + 3;4245,2007,2008;, + 3;3065,3061,3086;, + 3;4246,1972,4266;, + 3;4247,4266,1971;, + 3;1919,1993,4267;, + 3;4248,4267,1992;, + 3;4249,1975,4268;, + 3;4250,4268,1974;, + 3;4251,2006,2005;, + 3;4252,4269,2004;, + 3;4270,4271,4272;, + 3;4272,4273,4270;, + 3;4259,1949,1930;, + 3;4272,4274,4273;, + 3;2812,3148,3115;, + 3;3088,2946,2954;, + 3;2808,3098,2786;, + 3;3132,3140,2963;, + 3;3095,2957,3411;, + 3;3160,2952,3144;, + 3;3107,3390,2972;, + 3;2973,3127,3106;, + 3;2809,3135,3097;, + 3;3113,3152,2950;, + 3;3118,2068,2770;, + 3;2814,3091,3121;, + 3;3087,2955,3129;, + 3;3114,3145,3151;, + 3;3128,2956,3105;, + 3;2811,3110,3159;, + 3;3111,3162,3158;, + 3;3112,2951,3161;, + 3;2948,2967,3143;, + 3;3124,3125,3149;, + 3;3150,3146,3123;, + 3;2968,3100,3142;, + 3;3102,3137,3164;, + 3;3165,3141,3101;, + 3;2813,3122,3147;, + 3;3139,3133,3156;, + 3;3157,3163,3138;, + 3;2810,3155,3134;, + 3;2966,2949,3153;, + 3;3170,3009,3025;, + 3;3209,3027,2998;, + 3;2976,3220,3207;, + 3;3007,3172,3181;, + 3;3221,3219,2977;, + 3;3030,3005,3184;, + 3;3227,3226,2978;, + 3;3014,3191,3202;, + 3;2979,3199,3232;, + 3;3190,3015,3042;, + 3;3233,3193,3186;, + 3;3377,2792,3197;, + 3;3279,3265,3258;, + 3;3203,3214,2999;, + 3;3284,3254,3288;, + 3;3169,3026,3210;, + 3;3249,3263,3293;, + 3;3292,3264,3280;, + 3;3272,3271,3248;, + 3;3252,3217,3246;, + 3;3314,3308,3276;, + 3;3277,3313,3319;, + 3;3231,3200,3235;, + 3;3201,3192,3234;, + 3;3245,3218,3222;, + 3;3278,3240,3312;, + 3;3266,3251,3247;, + 3;3267,3262,3250;, + 3;3189,3178,3269;, + 3;3270,3273,3188;, + 3;3175,3166,3256;, + 3;3257,3259,3174;, + 3;3206,3215,3290;, + 3;3291,3281,3205;, + 3;3180,3173,3260;, + 3;3261,3268,3179;, + 3;3225,3228,3304;, + 3;3299,3298,3224;, + 3;3239,3187,3274;, + 3;3275,3305,3238;, + 3;3213,3204,3282;, + 3;3283,3285,3212;, + 3;3168,3211,3286;, + 3;3287,3255,3167;, + 3;3253,3289,3216;, + 3;3320,3237,3306;, + 3;3322,3303,3229;, + 3;3244,3223,3294;, + 3;3342,3330,3335;, + 3;3347,3331,3341;, + 3;3348,3346,3336;, + 3;3337,3356,3352;, + 3;3236,3321,3230;, + 3;3326,3307,3315;, + 3;3318,3309,3344;, + 3;3345,3349,3317;, + 3;3311,3241,3328;, + 3;3329,3343,3310;, + 3;3297,3300,3339;, + 3;3340,3332,3296;, + 3;3302,3323,3354;, + 3;3355,3338,3301;, + 3;3243,3295,3333;, + 3;3334,3327,3242;, + 3;3325,3316,3350;, + 3;3351,3353,3324;, + 3;1950,1952,1922;, + 3;1888,1950,1951;, + 3;3359,2862,2778;, + 3;2779,2789,3358;, + 3;1951,1950,1922;, + 3;1951,1922,1952;, + 3;1950,4254,1952;, + 3;1951,1952,4254;, + 3;4217,4275,1953;, + 3;4216,1953,4275;, + 3;1954,1953,1932;, + 3;1955,1954,1932;, + 3;4216,1955,1953;, + 3;4216,1954,1955;, + 3;4276,1956,4255;, + 3;4276,4209,1956;, + 3;1957,4255,1958;, + 3;1956,1957,1923;, + 3;1956,1923,1958;, + 3;1957,1958,1923;, + 3;4210,4277,1959;, + 3;1889,1959,4277;, + 3;1960,1959,1924;, + 3;1889,1960,1961;, + 3;1961,1960,1924;, + 3;1961,1924,1959;, + 3;4278,4279,1962;, + 3;4279,4280,1962;, + 3;1962,4280,1963;, + 3;4278,1963,4280;, + 3;4278,1964,1963;, + 3;4278,1962,1964;, + 3;4281,1965,4257;, + 3;4281,1890,1965;, + 3;1966,1967,1927;, + 3;1965,1966,1927;, + 3;1966,4257,1967;, + 3;1965,1967,4257;, + 3;1970,1933,1968;, + 3;4219,1968,1969;, + 3;1969,1968,1933;, + 3;1970,1969,1933;, + 3;4218,1970,1968;, + 3;4218,1969,1970;, + 3;1971,1973,1945;, + 3;4246,1971,1972;, + 3;1972,1971,1945;, + 3;1972,1945,1973;, + 3;1971,4266,1973;, + 3;1972,1973,4266;, + 3;1974,4268,1976;, + 3;4249,1974,1975;, + 3;1975,1974,1947;, + 3;1975,1976,4268;, + 3;1975,1947,1976;, + 3;1974,1976,1947;, + 3;1977,4256,1979;, + 3;4211,1977,1978;, + 3;1978,1977,1926;, + 3;1978,1979,4256;, + 3;1978,1926,1979;, + 3;1977,1979,1926;, + 3;1980,1981,1939;, + 3;4238,1980,1982;, + 3;1980,4263,1981;, + 3;4238,1981,4263;, + 3;1982,1980,1939;, + 3;1982,1939,1981;, + 3;1983,4258,1985;, + 3;4213,1983,1984;, + 3;1984,1983,1928;, + 3;1984,1985,4258;, + 3;1984,1928,1985;, + 3;1983,1985,1928;, + 3;4220,4282,1986;, + 3;1896,1986,4282;, + 3;1987,1986,1934;, + 3;1988,1987,1934;, + 3;1896,1988,1986;, + 3;1896,1987,1988;, + 3;4283,1989,1917;, + 3;4283,4221,1989;, + 3;1990,1991,1936;, + 3;1989,1990,1936;, + 3;1990,1917,1991;, + 3;1989,1991,1917;, + 3;1992,1994,1946;, + 3;1919,1992,1993;, + 3;1993,1992,1946;, + 3;1993,1946,1994;, + 3;1992,4267,1994;, + 3;1993,1994,4267;, + 3;4215,4284,1995;, + 3;1892,1995,4284;, + 3;1996,1995,1929;, + 3;1892,1996,1997;, + 3;1997,1996,1929;, + 3;1997,1929,1995;, + 3;1998,4264,2000;, + 3;1915,4285,4286;, + 3;1999,1998,1941;, + 3;1999,2000,4264;, + 3;1999,1941,2000;, + 3;1998,2000,1941;, + 3;4287,2001,1911;, + 3;4287,1913,2001;, + 3;1913,1911,2002;, + 3;2001,2002,1911;, + 3;2003,2002,1925;, + 3;2001,2003,1925;, + 3;2004,2005,1948;, + 3;4251,2004,2006;, + 3;2004,4269,2005;, + 3;4251,2005,4269;, + 3;2006,2004,1948;, + 3;2006,1948,2005;, + 3;4245,4288,2007;, + 3;4244,2007,4288;, + 3;2008,2007,1943;, + 3;2009,2008,1943;, + 3;4244,2009,2007;, + 3;4244,2008,2009;, + 3;1887,4289,2010;, + 3;1910,2010,4289;, + 3;4262,2013,4178;, + 3;2011,4176,2012;, + 3;1746,1937,2012;, + 3;2011,2012,1937;, + 3;4262,1938,2013;, + 3;4237,2013,1938;, + 3;2798,2806,3363;, + 3;3362,2807,2787;, + 3;3361,3367,2859;, + 3;2791,3378,3372;, + 3;2980,3376,3198;, + 3;2981,2988,3375;, + 3;2771,2865,3117;, + 3;2772,3053,2864;, + 3;2958,3402,3410;, + 3;2961,3099,2969;, + 3;2893,2817,2892;, + 3;3108,3392,3389;, + 3;2026,2734,3387;, + 3;2823,2736,2742;, + 3;2822,2743,2942;, + 3;1749,2014,1894;, + 3;3394,2029,2024;, + 3;2970,3397,2960;, + 3;3391,3396,2971;, + 3;3398,3401,2959;, + 3;3408,2894,3381;, + 3;3409,3403,2893;, + 3;3094,3406,3414;, + 3;3413,3407,3382;, + 3;3412,3383,2784;, + 3;4290,4291,2015;, + 3;4292,4293,2016;, + 3;3048,2775,3085;, + 3;2015,4291,4294;, + 3;4290,2015,4294;, + 3;2016,4293,4295;, + 3;4292,2016,4295;, + 3;2017,2040,2022;, + 3;2017,2039,2040;, + 3;2018,2870,2017;, + 3;2018,2877,2870;, + 3;2019,2878,2018;, + 3;2019,2882,2878;, + 3;2020,2085,2019;, + 3;2020,2084,2085;, + 3;2021,2223,2020;, + 3;2021,2222,2223;, + 3;2022,2215,2021;, + 3;2022,2214,2215;, + 3;2019,2017,2020;, + 3;2020,2017,2022;, + 3;2020,2022,2021;, + 3;2017,2019,2018;, + 3;2023,2746,2028;, + 3;2023,2745,2746;, + 3;2024,2030,2023;, + 3;2024,2029,2030;, + 3;2025,3394,2024;, + 3;2025,3393,3394;, + 3;2026,3388,2025;, + 3;2026,3387,3388;, + 3;2027,2734,2026;, + 3;2027,2733,2734;, + 3;2028,2731,2027;, + 3;2028,2730,2731;, + 3;2025,2028,2026;, + 3;2026,2028,2027;, + 3;2028,2025,2024;, + 3;2028,2024,2023;, + 3;2029,2014,1749;, + 3;2029,3394,2014;, + 3;1749,2745,2030;, + 3;1749,1883,2745;, + 3;1749,2030,2029;, + 3;2031,2739,2036;, + 3;2031,2744,2739;, + 3;2032,2941,2031;, + 3;2032,2940,2941;, + 3;2033,2872,2032;, + 3;2033,2871,2872;, + 3;2034,2038,2033;, + 3;2034,2037,2038;, + 3;2035,2221,2034;, + 3;2035,2220,2221;, + 3;2036,2285,2035;, + 3;2036,2284,2285;, + 3;2031,2036,2034;, + 3;2031,2034,2033;, + 3;2031,2033,2032;, + 3;2034,2036,2035;, + 3;2037,2214,2040;, + 3;2037,2221,2214;, + 3;2039,2871,2038;, + 3;2039,2870,2871;, + 3;2039,2038,2040;, + 3;2040,2038,2037;, + 3;2041,2049,2048;, + 3;2041,2052,2049;, + 3;2042,2190,2041;, + 3;2042,2189,2190;, + 3;2042,2177,2178;, + 3;2043,2187,2042;, + 3;2043,2186,2187;, + 3;2044,2195,2043;, + 3;2044,2194,2195;, + 3;2045,2056,2044;, + 3;2045,2055,2056;, + 3;2046,2850,2045;, + 3;2046,2855,2850;, + 3;2047,2841,2046;, + 3;2047,2840,2841;, + 3;2047,2836,2837;, + 3;2048,2847,2047;, + 3;2048,2846,2847;, + 3;2045,2044,2048;, + 3;2045,2048,2046;, + 3;2046,2048,2047;, + 3;2048,2044,2041;, + 3;2041,2044,2043;, + 3;2041,2043,2042;, + 3;2050,2846,2049;, + 3;2050,2845,2846;, + 3;2051,2066,2050;, + 3;2051,2065,2066;, + 3;2052,2191,2051;, + 3;2052,2190,2191;, + 3;2050,2049,2051;, + 3;2051,2049,2052;, + 3;2053,2194,2056;, + 3;2053,2199,2194;, + 3;2054,2073,2053;, + 3;2054,2072,2073;, + 3;2055,2851,2054;, + 3;2055,2850,2851;, + 3;2055,2054,2056;, + 3;2056,2054,2053;, + 3;2057,2070,2062;, + 3;2057,2069,2070;, + 3;2058,2769,2057;, + 3;2058,2774,2769;, + 3;2059,3057,2058;, + 3;2059,3056,3057;, + 3;2060,2110,2059;, + 3;2060,2109,2110;, + 3;2061,2399,2060;, + 3;2061,2398,2399;, + 3;2062,2114,2061;, + 3;2062,2113,2114;, + 3;2057,2062,2058;, + 3;2058,2062,2061;, + 3;2058,2061,2059;, + 3;2059,2061,2060;, + 3;2063,2113,2070;, + 3;2063,2118,2113;, + 3;2064,2459,2063;, + 3;2064,2458,2459;, + 3;2065,2192,2064;, + 3;2065,2191,2192;, + 3;2067,2845,2066;, + 3;2067,2844,2845;, + 3;2068,3119,2067;, + 3;2068,3118,3119;, + 3;2069,2770,2068;, + 3;2069,2769,2770;, + 3;2066,2065,2069;, + 3;2066,2069,2068;, + 3;2066,2068,2067;, + 3;2069,2065,2070;, + 3;2070,2065,2063;, + 3;2063,2065,2064;, + 3;2071,2075,2074;, + 3;2071,2080,2075;, + 3;2072,2852,2071;, + 3;2072,2851,2852;, + 3;2074,2199,2073;, + 3;2074,2198,2199;, + 3;2072,2071,2073;, + 3;2073,2071,2074;, + 3;2076,2198,2075;, + 3;2076,2197,2198;, + 3;2077,2174,2076;, + 3;2077,2173,2174;, + 3;2078,2090,2077;, + 3;2078,2089,2090;, + 3;2079,2828,2078;, + 3;2079,2827,2828;, + 3;2080,2853,2079;, + 3;2080,2852,2853;, + 3;2078,2077,2079;, + 3;2079,2077,2076;, + 3;2079,2076,2080;, + 3;2080,2076,2075;, + 3;2081,2173,2090;, + 3;2081,2172,2173;, + 3;2082,2254,2081;, + 3;2082,2253,2254;, + 3;2083,2273,2082;, + 3;2083,2272,2273;, + 3;2084,2224,2083;, + 3;2084,2223,2224;, + 3;2086,2882,2085;, + 3;2086,2881,2882;, + 3;2087,2929,2086;, + 3;2087,2928,2929;, + 3;2088,2910,2087;, + 3;2088,2909,2910;, + 3;2089,2829,2088;, + 3;2089,2828,2829;, + 3;2085,2084,2090;, + 3;2085,2090,2089;, + 3;2085,2089,2086;, + 3;2086,2089,2087;, + 3;2087,2089,2088;, + 3;2090,2084,2083;, + 3;2090,2083,2082;, + 3;2090,2082,2081;, + 3;2091,2401,2098;, + 3;2091,2400,2401;, + 3;2092,2112,2091;, + 3;2092,2111,2112;, + 3;2093,3055,2092;, + 3;2093,3059,3055;, + 3;4296,3051,2093;, + 3;4296,4297,3051;, + 3;4298,3070,2094;, + 3;4298,4299,3070;, + 3;2096,2103,2095;, + 3;2096,2102,2103;, + 3;2097,4300,4301;, + 3;2097,2412,4300;, + 3;2098,4302,4303;, + 3;2098,2393,4302;, + 3;4304,4305,4298;, + 3;4304,4298,2094;, + 3;4298,4305,4301;, + 3;4301,4305,2097;, + 3;2098,2093,2092;, + 3;2098,2092,2091;, + 3;2099,4306,4307;, + 3;2099,2421,4306;, + 3;2100,2107,2099;, + 3;2100,2106,2107;, + 3;4307,3078,2100;, + 3;4307,4308,3078;, + 3;4307,2100,2099;, + 3;2101,21,8;, + 3;2101,2423,21;, + 3;2102,2407,2101;, + 3;2102,2406,2407;, + 3;2104,3069,2103;, + 3;2104,3068,3069;, + 3;8,3080,2104;, + 3;8,151,3080;, + 3;8,2102,2101;, + 3;8,2103,2102;, + 3;8,2104,2103;, + 3;2105,4309,4310;, + 3;2105,3076,4309;, + 3;2106,3079,2105;, + 3;2106,3078,3079;, + 3;2108,2421,2107;, + 3;2108,2420,2421;, + 3;4310,2416,2108;, + 3;4310,4311,2416;, + 3;4310,2106,2105;, + 3;4310,2107,2106;, + 3;4310,2108,2107;, + 3;4312,2400,2112;, + 3;4312,4313,2400;, + 3;2111,4314,4315;, + 3;2111,3055,4314;, + 3;4315,4312,2111;, + 3;2111,4312,2112;, + 3;4316,2398,2114;, + 3;2115,2397,4317;, + 3;2116,2392,2115;, + 3;2116,2391,2392;, + 3;2117,4318,4319;, + 3;2117,2207,4318;, + 3;2118,2460,2117;, + 3;2118,2459,2460;, + 3;2114,2118,2117;, + 3;2114,2117,4316;, + 3;4316,2117,4319;, + 3;2118,2114,2113;, + 3;2119,4320,4321;, + 3;2119,2139,4320;, + 3;2120,2702,2119;, + 3;2120,2701,2702;, + 3;2121,2210,2120;, + 3;2121,2209,2210;, + 3;4322,2396,2121;, + 3;4322,4323,2396;, + 3;1755,2411,2122;, + 3;1755,1787,2411;, + 3;2123,1813,1755;, + 3;2123,2427,1813;, + 3;2124,2387,2123;, + 3;2124,2386,2387;, + 3;1755,2124,2123;, + 3;4324,2119,4321;, + 3;4324,2120,2119;, + 3;4324,2121,2120;, + 3;4324,4322,2121;, + 3;2125,4325,4326;, + 3;2125,2706,4325;, + 3;2126,2157,2125;, + 3;2126,2156,2157;, + 3;2127,2435,2126;, + 3;2127,2434,2435;, + 3;2128,2768,2127;, + 3;2128,2767,2768;, + 3;2129,2720,2128;, + 3;2129,2725,2720;, + 3;2130,2213,2129;, + 3;2130,2212,2213;, + 3;4327,2203,2130;, + 3;2131,2202,4328;, + 3;2132,2712,2131;, + 3;2132,2711,2712;, + 3;4326,2127,2126;, + 3;4326,2126,2125;, + 3;2127,4326,4327;, + 3;2127,4327,2128;, + 3;2128,4327,2130;, + 3;2128,2130,2129;, + 3;2133,4329,4320;, + 3;2133,2390,4329;, + 3;2134,2382,2133;, + 3;2134,2381,2382;, + 3;2135,2357,2134;, + 3;2135,2360,2357;, + 3;2136,2537,2135;, + 3;2136,2543,2537;, + 3;2137,2717,2136;, + 3;2137,2716,2717;, + 3;2138,2708,2137;, + 3;2138,2714,2708;, + 3;2139,2698,2138;, + 3;2139,2702,2698;, + 3;2134,2133,2135;, + 3;2135,2133,4320;, + 3;2135,4320,2136;, + 3;2136,4320,2139;, + 3;2136,2139,2137;, + 3;2137,2139,2138;, + 3;2141,2425,2146;, + 3;2141,2424,2425;, + 3;2141,4146,2318;, + 3;4330,1760,1777;, + 3;2142,1762,1760;, + 3;2142,2291,1762;, + 3;2143,2430,2142;, + 3;2143,2429,2430;, + 3;2144,2159,2143;, + 3;2144,2158,2159;, + 3;2145,2705,2144;, + 3;2145,2704,2705;, + 3;2146,2331,4331;, + 3;2146,2330,2331;, + 3;1760,2143,2142;, + 3;1760,2144,2143;, + 3;1760,2145,2144;, + 3;1760,4330,2145;, + 3;2145,4330,4153;, + 3;2147,4332,4333;, + 3;2147,2320,4332;, + 3;2148,2342,2147;, + 3;2148,2341,2342;, + 3;2149,2363,2148;, + 3;2149,2369,2363;, + 3;4333,2361,2149;, + 3;4333,4173,2361;, + 3;4333,2148,2147;, + 3;4333,2149,2148;, + 3;2150,2429,2159;, + 3;2150,2428,2429;, + 3;2151,2465,2150;, + 3;2151,2464,2465;, + 3;2152,4334,4335;, + 3;2152,2489,4334;, + 3;2153,2456,2152;, + 3;2153,2455,2456;, + 3;4336,2500,2153;, + 3;4336,4337,2500;, + 3;2155,2474,2154;, + 3;2155,2473,2474;, + 3;2156,2436,2155;, + 3;2156,2435,2436;, + 3;2158,2706,2157;, + 3;2158,2705,2706;, + 3;2158,2154,4338;, + 3;2158,4338,4339;, + 3;2158,4339,2151;, + 3;2158,2151,2150;, + 3;2158,2150,2159;, + 3;2154,2158,2155;, + 3;2155,2158,2157;, + 3;2155,2157,2156;, + 3;2160,2726,2169;, + 3;2160,2732,2726;, + 3;2161,2738,2160;, + 3;2161,2737,2738;, + 3;2162,2741,2161;, + 3;2162,2740,2741;, + 3;2163,2283,2162;, + 3;2163,2287,2283;, + 3;2164,2231,2163;, + 3;2164,2230,2231;, + 3;2165,2249,2164;, + 3;2165,2248,2249;, + 3;2166,2243,2165;, + 3;2166,2242,2243;, + 3;2167,2236,2166;, + 3;2167,2235,2236;, + 3;2168,2754,2235;, + 3;2168,2758,2754;, + 3;2169,2749,2168;, + 3;2169,2753,2749;, + 3;2167,2165,2164;, + 3;2167,2164,2163;, + 3;2167,2163,2168;, + 3;2168,2163,2162;, + 3;2168,2162,2169;, + 3;2169,2162,2161;, + 3;2169,2161,2160;, + 3;2165,2167,2166;, + 3;2170,2239,2176;, + 3;2170,2238,2239;, + 3;2171,2259,2170;, + 3;2171,2258,2259;, + 3;2172,2255,2171;, + 3;2172,2254,2255;, + 3;2175,2197,2174;, + 3;2175,2196,2197;, + 3;2176,2185,2175;, + 3;2176,2184,2185;, + 3;2171,2176,2172;, + 3;2172,2176,2174;, + 3;2172,2174,2173;, + 3;2174,2176,2175;, + 3;2176,2171,2170;, + 3;2177,2183,2182;, + 3;2177,2187,2183;, + 3;2179,2189,2178;, + 3;2179,2188,2189;, + 3;2180,2205,2179;, + 3;2180,2204,2205;, + 3;2181,2724,2180;, + 3;2181,2723,2724;, + 3;2182,2232,2181;, + 3;2182,2240,2232;, + 3;2179,2178,2180;, + 3;2180,2178,2177;, + 3;2180,2177,2182;, + 3;2180,2182,2181;, + 3;2184,2240,2183;, + 3;2184,2239,2240;, + 3;2186,2196,2185;, + 3;2186,2195,2196;, + 3;2185,2187,2186;, + 3;2187,2185,2183;, + 3;2183,2185,2184;, + 3;2188,2206,2193;, + 3;2188,2205,2206;, + 3;2193,2458,2192;, + 3;2193,2457,2458;, + 3;2189,2193,2192;, + 3;2189,2192,2190;, + 3;2190,2192,2191;, + 3;2193,2189,2188;, + 3;2199,2195,2194;, + 3;2195,2199,2198;, + 3;2195,2198,2197;, + 3;2195,2197,2196;, + 3;2200,2211,4328;, + 3;2203,4340,2212;, + 3;2201,2700,2200;, + 3;2201,2699,2700;, + 3;2202,2713,2201;, + 3;2202,2712,2713;, + 3;4328,2201,2200;, + 3;2201,4328,2202;, + 3;2204,2725,2213;, + 3;2204,2724,2725;, + 3;2207,2457,2206;, + 3;2207,2460,2457;, + 3;2209,2391,2208;, + 3;2209,2396,2391;, + 3;2211,2701,2210;, + 3;2211,2700,2701;, + 3;2205,2207,2206;, + 3;2207,2205,2204;, + 3;2207,2204,4318;, + 3;4318,2204,4340;, + 3;2208,2211,2209;, + 3;2209,2211,2210;, + 3;4340,2204,2212;, + 3;2212,2204,2213;, + 3;2216,2222,2215;, + 3;2216,2226,2222;, + 3;2217,2267,2216;, + 3;2217,2266,2267;, + 3;2218,2265,2217;, + 3;2218,2264,2265;, + 3;2219,2228,2218;, + 3;2219,2227,2228;, + 3;2220,2286,2219;, + 3;2220,2285,2286;, + 3;2218,2216,2219;, + 3;2219,2216,2220;, + 3;2220,2216,2215;, + 3;2220,2215,2221;, + 3;2221,2215,2214;, + 3;2216,2218,2217;, + 3;2225,2272,2224;, + 3;2225,2271,2272;, + 3;2226,2268,2225;, + 3;2226,2267,2268;, + 3;2222,2226,2225;, + 3;2222,2225,2224;, + 3;2222,2224,2223;, + 3;2227,2287,2231;, + 3;2227,2286,2287;, + 3;2229,2264,2228;, + 3;2229,2263,2264;, + 3;2230,2250,2229;, + 3;2230,2249,2250;, + 3;2227,2231,2228;, + 3;2228,2231,2229;, + 3;2229,2231,2230;, + 3;2233,2723,2232;, + 3;2233,2722,2723;, + 3;2234,2761,2233;, + 3;2234,2760,2761;, + 3;2235,2754,2234;, + 3;2234,2754,2755;, + 3;2237,2242,2236;, + 3;2237,2241,2242;, + 3;2238,2260,2237;, + 3;2238,2259,2260;, + 3;2237,2236,2238;, + 3;2238,2236,2235;, + 3;2238,2235,2239;, + 3;2239,2235,2234;, + 3;2239,2234,2232;, + 3;2239,2232,2240;, + 3;2232,2234,2233;, + 3;2241,2256,2245;, + 3;2241,2260,2256;, + 3;2244,2248,2243;, + 3;2244,2247,2248;, + 3;2245,2276,2244;, + 3;2245,2282,2276;, + 3;2242,2241,2243;, + 3;2243,2241,2244;, + 3;2244,2241,2245;, + 3;2246,2263,2250;, + 3;2246,2262,2263;, + 3;2247,2277,2246;, + 3;2247,2276,2277;, + 3;2246,2250,2247;, + 3;2247,2250,2249;, + 3;2247,2249,2248;, + 3;2251,2258,2255;, + 3;2251,2257,2258;, + 3;2252,2281,2251;, + 3;2252,2280,2281;, + 3;2253,2274,2252;, + 3;2253,2273,2274;, + 3;2255,2252,2251;, + 3;2252,2255,2254;, + 3;2252,2254,2253;, + 3;2257,2282,2256;, + 3;2257,2281,2282;, + 3;2257,2259,2258;, + 3;2259,2257,2256;, + 3;2259,2256,2260;, + 3;2261,2266,2265;, + 3;2261,2270,2266;, + 3;2262,2278,2261;, + 3;2262,2277,2278;, + 3;2265,2263,2262;, + 3;2265,2262,2261;, + 3;2263,2265,2264;, + 3;2269,2271,2268;, + 3;2269,2275,2271;, + 3;2270,2279,2269;, + 3;2270,2278,2279;, + 3;2270,2269,2268;, + 3;2270,2268,2266;, + 3;2266,2268,2267;, + 3;2275,2280,2274;, + 3;2275,2279,2280;, + 3;2275,2273,2271;, + 3;2271,2273,2272;, + 3;2273,2275,2274;, + 3;2279,2278,2280;, + 3;2280,2278,2282;, + 3;2280,2282,2281;, + 3;2282,2278,2276;, + 3;2276,2278,2277;, + 3;2284,2740,2283;, + 3;2284,2739,2740;, + 3;2286,2283,2287;, + 3;2283,2286,2285;, + 3;2283,2285,2284;, + 3;2288,1883,1762;, + 3;2288,2748,1883;, + 3;2289,2450,2288;, + 3;2289,2449,2450;, + 3;2290,2297,2289;, + 3;2290,2300,2297;, + 3;2291,2431,2290;, + 3;2291,2430,2431;, + 3;1762,2289,2288;, + 3;1762,2290,2289;, + 3;1762,2291,2290;, + 3;2292,2501,2296;, + 3;2292,2506,2501;, + 3;2293,2453,2292;, + 3;2293,2452,2453;, + 3;2294,2491,2293;, + 3;2294,2490,2491;, + 3;2295,2317,2294;, + 3;2295,2316,2317;, + 3;2296,2482,2295;, + 3;2296,2485,2482;, + 3;2293,2296,2294;, + 3;2294,2296,2295;, + 3;2296,2293,2292;, + 3;2298,2449,2297;, + 3;2298,2448,2449;, + 3;2299,2467,2298;, + 3;2299,2466,2467;, + 3;2300,2432,2299;, + 3;2300,2431,2432;, + 3;2297,2299,2298;, + 3;2299,2297,2300;, + 3;2301,2472,2308;, + 3;2301,2476,2472;, + 3;2302,2478,2301;, + 3;2302,2477,2478;, + 3;2303,2444,2302;, + 3;2303,2443,2444;, + 3;2304,2314,2303;, + 3;2304,2313,2314;, + 3;2305,2751,2304;, + 3;2305,2750,2751;, + 3;2306,2757,2305;, + 3;2306,2756,2757;, + 3;2307,2759,2306;, + 3;2307,2764,2759;, + 3;2308,2438,2307;, + 3;2308,2437,2438;, + 3;2306,2302,2307;, + 3;2307,2302,2301;, + 3;2307,2301,2308;, + 3;2302,2306,2305;, + 3;2302,2305,2304;, + 3;2302,2304,2303;, + 3;4341,2490,2317;, + 3;4341,4342,2490;, + 3;2310,2469,2309;, + 3;2310,2468,2469;, + 3;2311,2447,2310;, + 3;2311,2446,2447;, + 3;2312,2728,2311;, + 3;2312,2727,2728;, + 3;2313,2752,2312;, + 3;2313,2751,2752;, + 3;2315,2443,2314;, + 3;2315,2442,2443;, + 3;4343,2483,2315;, + 3;2316,2482,4344;, + 3;2312,2315,2314;, + 3;2312,2314,2313;, + 3;2315,2312,2311;, + 3;2315,2311,4343;, + 3;4343,2311,2310;, + 3;2316,4345,2317;, + 3;2317,4345,4341;, + 3;4146,2424,2318;, + 3;4146,4346,2424;, + 3;2319,2544,2326;, + 3;2319,2549,2544;, + 3;2320,2343,2319;, + 3;2320,2342,2343;, + 3;2321,4347,4332;, + 3;2321,2334,4347;, + 3;2322,2719,2321;, + 3;2322,2718,2719;, + 3;2323,2542,2322;, + 3;2323,2541,2542;, + 3;2324,2569,2323;, + 3;2324,2568,2569;, + 3;2325,2563,2324;, + 3;2325,2562,2563;, + 3;2326,2556,2325;, + 3;2326,2561,2556;, + 3;4332,2322,2321;, + 3;4332,2323,2322;, + 3;4332,2324,2323;, + 3;4332,2325,2324;, + 3;4332,2326,2325;, + 3;4332,2319,2326;, + 3;4332,2320,2319;, + 3;4175,2335,2329;, + 3;4175,4348,2335;, + 3;2327,4173,4175;, + 3;2327,2362,4173;, + 3;2328,2368,2327;, + 3;2328,2367,2368;, + 3;2329,2353,2328;, + 3;2329,2352,2353;, + 3;4175,2328,2327;, + 3;4175,2329,2328;, + 3;2330,4346,4347;, + 3;2330,2425,4346;, + 3;2332,4331,2331;, + 3;2332,2703,4331;, + 3;2333,2710,2332;, + 3;2333,2709,2710;, + 3;2334,2715,2333;, + 3;2334,2719,2715;, + 3;4347,2331,2330;, + 3;4347,2332,2331;, + 3;4347,2333,2332;, + 3;4347,2334,2333;, + 3;2336,2352,2335;, + 3;2336,2351,2352;, + 3;2337,2350,2336;, + 3;2337,2349,2350;, + 3;2338,2375,2337;, + 3;2338,2379,2375;, + 3;4348,2388,2338;, + 3;4348,4349,2388;, + 3;4348,2336,2335;, + 3;4348,2337,2336;, + 3;4348,2338,2337;, + 3;2339,2549,2343;, + 3;2339,2548,2549;, + 3;2340,2551,2339;, + 3;2340,2550,2551;, + 3;2341,2364,2340;, + 3;2341,2363,2364;, + 3;2341,2340,2339;, + 3;2341,2339,2342;, + 3;2342,2339,2343;, + 3;2344,2351,2350;, + 3;2344,2356,2351;, + 3;2345,2518,2344;, + 3;2345,2517,2518;, + 3;2346,2519,2345;, + 3;2346,2523,2519;, + 3;2347,2524,2346;, + 3;2347,2530,2524;, + 3;2348,2373,2347;, + 3;2348,2372,2373;, + 3;2349,2376,2348;, + 3;2349,2375,2376;, + 3;2349,2346,2345;, + 3;2349,2345,2350;, + 3;2350,2345,2344;, + 3;2346,2349,2348;, + 3;2346,2348,2347;, + 3;2354,2367,2353;, + 3;2354,2366,2367;, + 3;2355,2507,2354;, + 3;2355,2512,2507;, + 3;2356,2513,2355;, + 3;2356,2518,2513;, + 3;2353,2355,2354;, + 3;2355,2353,2356;, + 3;2356,2353,2352;, + 3;2356,2352,2351;, + 3;2358,2381,2357;, + 3;2358,2380,2381;, + 3;2359,2535,2358;, + 3;2359,2534,2535;, + 3;2360,2538,2359;, + 3;2360,2537,2538;, + 3;2357,2360,2358;, + 3;2358,2360,2359;, + 3;2362,2369,2361;, + 3;2362,2368,2369;, + 3;4173,2362,2361;, + 3;2365,2550,2364;, + 3;2365,2555,2550;, + 3;2366,2508,2365;, + 3;2366,2507,2508;, + 3;2365,2364,2366;, + 3;2366,2364,2369;, + 3;2366,2369,2368;, + 3;2366,2368,2367;, + 3;2369,2364,2363;, + 3;2370,2531,2374;, + 3;2370,2536,2531;, + 3;2371,2385,2370;, + 3;2371,2384,2385;, + 3;2372,2377,2371;, + 3;2372,2376,2377;, + 3;2374,2530,2373;, + 3;2374,2529,2530;, + 3;2374,2373,2372;, + 3;2374,2372,2371;, + 3;2374,2371,2370;, + 3;2378,2384,2377;, + 3;2378,2383,2384;, + 3;2379,2389,2378;, + 3;2379,2388,2389;, + 3;2379,2376,2375;, + 3;2376,2379,2377;, + 3;2377,2379,2378;, + 3;2380,2536,2385;, + 3;2380,2535,2536;, + 3;2383,2390,2382;, + 3;2383,2389,2390;, + 3;2382,2380,2385;, + 3;2382,2385,2383;, + 3;2383,2385,2384;, + 3;2380,2382,2381;, + 3;4350,2427,2387;, + 3;4350,1813,2427;, + 3;4349,2389,2388;, + 3;4349,2390,2389;, + 3;4349,4329,2390;, + 3;4350,2387,2386;, + 3;2393,2397,2392;, + 3;2393,2401,2397;, + 3;2395,2412,2394;, + 3;2395,2411,2412;, + 3;4302,2396,4323;, + 3;2396,4302,2393;, + 3;2396,2393,2391;, + 3;2391,2393,2392;, + 3;4317,2397,4313;, + 3;4313,2397,2400;, + 3;2400,2397,2401;, + 3;2402,2410,2405;, + 3;2402,2409,2410;, + 3;2403,2414,2402;, + 3;2403,2413,2414;, + 3;2404,2418,2403;, + 3;2404,2417,2418;, + 3;4351,2419,2404;, + 3;4351,4306,2419;, + 3;4352,4207,4204;, + 3;4352,4353,4207;, + 3;4351,2402,2405;, + 3;4351,2403,2402;, + 3;4351,2404,2403;, + 3;2408,2423,2407;, + 3;2408,2422,2423;, + 3;4354,2415,2408;, + 3;4354,4355,2415;, + 3;4356,4357,4358;, + 3;1787,1813,4359;, + 3;1787,2412,2411;, + 3;1787,4300,2412;, + 3;4356,2407,2406;, + 3;4356,2408,2407;, + 3;4356,4354,2408;, + 3;4356,4358,4354;, + 3;2413,4311,4360;, + 3;2413,2418,4311;, + 3;88,2422,2415;, + 3;88,21,2422;, + 3;4360,2414,2413;, + 3;88,2415,4355;, + 3;2417,2420,2416;, + 3;2417,2419,2420;, + 3;4311,2418,2416;, + 3;2416,2418,2417;, + 3;4306,2420,2419;, + 3;4306,2421,2420;, + 3;21,2423,2422;, + 3;4346,2425,2424;, + 3;2428,2461,2433;, + 3;2428,2465,2461;, + 3;2433,2466,2432;, + 3;2433,2471,2466;, + 3;2429,2428,2430;, + 3;2430,2428,2433;, + 3;2430,2433,2431;, + 3;2431,2433,2432;, + 3;2434,2765,2439;, + 3;2434,2768,2765;, + 3;2437,2473,2436;, + 3;2437,2472,2473;, + 3;2439,2764,2438;, + 3;2439,2763,2764;, + 3;2436,2435,2437;, + 3;2437,2435,2434;, + 3;2437,2434,2439;, + 3;2437,2439,2438;, + 3;2440,2477,2444;, + 3;2440,2481,2477;, + 3;2441,2503,2440;, + 3;2441,2502,2503;, + 3;2442,2484,2441;, + 3;2442,2483,2484;, + 3;2442,2441,2443;, + 3;2443,2441,2444;, + 3;2444,2441,2440;, + 3;2445,2748,2450;, + 3;2445,2747,2748;, + 3;2446,2729,2445;, + 3;2446,2728,2729;, + 3;2448,2468,2447;, + 3;2448,2467,2468;, + 3;2446,2445,2447;, + 3;2447,2445,2448;, + 3;2448,2445,2449;, + 3;2449,2445,2450;, + 3;2451,2489,2456;, + 3;2451,2488,2489;, + 3;2452,2492,2451;, + 3;2452,2491,2492;, + 3;2454,2506,2453;, + 3;2454,2505,2506;, + 3;2455,2496,2454;, + 3;2455,2500,2496;, + 3;2456,2454,2451;, + 3;2451,2454,2453;, + 3;2451,2453,2452;, + 3;2454,2456,2455;, + 3;2460,2458,2457;, + 3;2458,2460,2459;, + 3;2462,2471,2461;, + 3;2462,2470,2471;, + 3;2463,2494,2462;, + 3;2463,2493,2494;, + 3;2464,2487,2463;, + 3;2464,2486,2487;, + 3;2465,2463,2461;, + 3;2461,2463,2462;, + 3;2463,2465,2464;, + 3;2470,2495,2469;, + 3;2470,2494,2495;, + 3;2467,2469,2468;, + 3;2469,2467,2470;, + 3;2470,2467,2466;, + 3;2470,2466,2471;, + 3;2475,2499,2474;, + 3;2475,2498,2499;, + 3;2476,2479,2475;, + 3;2476,2478,2479;, + 3;2474,2473,2475;, + 3;2475,2473,2472;, + 3;2475,2472,2476;, + 3;2480,2498,2479;, + 3;2480,2497,2498;, + 3;2481,2504,2480;, + 3;2481,2503,2504;, + 3;2478,2480,2479;, + 3;2480,2478,2481;, + 3;2481,2478,2477;, + 3;2485,4361,4362;, + 3;2485,2501,4361;, + 3;2482,4362,4344;, + 3;4362,2482,2485;, + 3;2488,4363,4364;, + 3;2488,2492,4363;, + 3;4334,2489,2488;, + 3;4334,2488,4364;, + 3;4342,4365,2490;, + 3;2490,4365,2491;, + 3;2491,4365,4363;, + 3;2491,4363,2492;, + 3;4366,2505,2496;, + 3;4366,4367,2505;, + 3;4337,4368,2500;, + 3;2500,4368,2496;, + 3;2496,4368,4366;, + 3;4369,2506,4367;, + 3;4367,2506,2505;, + 3;2506,4369,2501;, + 3;2501,4369,4361;, + 3;2509,2555,2508;, + 3;2509,2554,2555;, + 3;2510,2627,2509;, + 3;2510,2626,2627;, + 3;2511,2597,2510;, + 3;2511,2596,2597;, + 3;2512,2514,2511;, + 3;2512,2513,2514;, + 3;2510,2508,2511;, + 3;2511,2508,2507;, + 3;2511,2507,2512;, + 3;2508,2510,2509;, + 3;2515,2596,2514;, + 3;2515,2595,2596;, + 3;2516,2605,2515;, + 3;2516,2604,2605;, + 3;2517,2520,2516;, + 3;2517,2519,2520;, + 3;2516,2513,2518;, + 3;2516,2518,2517;, + 3;2513,2516,2515;, + 3;2513,2515,2514;, + 3;2521,2604,2520;, + 3;2521,2603,2604;, + 3;2522,2609,2521;, + 3;2522,2608,2609;, + 3;2523,2525,2522;, + 3;2523,2524,2525;, + 3;2519,2522,2521;, + 3;2519,2521,2520;, + 3;2522,2519,2523;, + 3;2526,2608,2525;, + 3;2526,2607,2608;, + 3;2527,2619,2526;, + 3;2527,2618,2619;, + 3;2528,2575,2527;, + 3;2528,2574,2575;, + 3;2529,2532,2528;, + 3;2529,2531,2532;, + 3;2527,2526,2528;, + 3;2528,2526,2529;, + 3;2529,2526,2530;, + 3;2530,2526,2525;, + 3;2530,2525,2524;, + 3;2533,2574,2532;, + 3;2533,2580,2574;, + 3;2534,2539,2533;, + 3;2534,2538,2539;, + 3;2536,2534,2531;, + 3;2531,2534,2532;, + 3;2532,2534,2533;, + 3;2534,2536,2535;, + 3;2540,2580,2539;, + 3;2540,2579,2580;, + 3;2541,2570,2540;, + 3;2541,2569,2570;, + 3;2543,2718,2542;, + 3;2543,2717,2718;, + 3;2543,2539,2538;, + 3;2543,2538,2537;, + 3;2539,2543,2540;, + 3;2540,2543,2542;, + 3;2540,2542,2541;, + 3;2545,2561,2544;, + 3;2545,2560,2561;, + 3;2546,2632,2545;, + 3;2546,2631,2632;, + 3;2547,2624,2546;, + 3;2547,2623,2624;, + 3;2548,2552,2547;, + 3;2548,2551,2552;, + 3;2546,2544,2549;, + 3;2546,2549,2547;, + 3;2547,2549,2548;, + 3;2544,2546,2545;, + 3;2553,2623,2552;, + 3;2553,2622,2623;, + 3;2554,2628,2553;, + 3;2554,2627,2628;, + 3;2554,2550,2555;, + 3;2550,2554,2551;, + 3;2551,2554,2553;, + 3;2551,2553,2552;, + 3;2557,2562,2556;, + 3;2557,2567,2562;, + 3;2558,2583,2557;, + 3;2558,2582,2583;, + 3;2559,2592,2558;, + 3;2559,2591,2592;, + 3;2560,2633,2559;, + 3;2560,2632,2633;, + 3;2560,2559,2557;, + 3;2560,2557,2556;, + 3;2560,2556,2561;, + 3;2557,2559,2558;, + 3;2564,2568,2563;, + 3;2564,2573,2568;, + 3;2565,2645,2564;, + 3;2565,2644,2645;, + 3;2566,2639,2565;, + 3;2566,2638,2639;, + 3;2567,2584,2566;, + 3;2567,2583,2584;, + 3;2565,2567,2566;, + 3;2567,2565,2564;, + 3;2567,2564,2562;, + 3;2562,2564,2563;, + 3;2571,2579,2570;, + 3;2571,2578,2579;, + 3;2572,2667,2571;, + 3;2572,2666,2667;, + 3;2573,2640,2572;, + 3;2573,2645,2640;, + 3;2572,2568,2573;, + 3;2568,2572,2569;, + 3;2569,2572,2571;, + 3;2569,2571,2570;, + 3;2576,2618,2575;, + 3;2576,2617,2618;, + 3;2577,2648,2576;, + 3;2577,2647,2648;, + 3;2578,2661,2577;, + 3;2578,2667,2661;, + 3;2576,2580,2577;, + 3;2577,2580,2579;, + 3;2577,2579,2578;, + 3;2580,2576,2574;, + 3;2574,2576,2575;, + 3;2581,2612,2589;, + 3;2581,2611,2612;, + 3;2582,2593,2581;, + 3;2582,2592,2593;, + 3;2585,2638,2584;, + 3;2585,2637,2638;, + 3;2586,2673,2585;, + 3;2586,2672,2673;, + 3;2587,2670,2586;, + 3;2587,2669,2670;, + 3;2588,2651,2587;, + 3;2588,2650,2651;, + 3;2589,2614,2588;, + 3;2589,2613,2614;, + 3;2584,2587,2585;, + 3;2585,2587,2586;, + 3;2587,2584,2582;, + 3;2587,2582,2581;, + 3;2587,2581,2588;, + 3;2588,2581,2589;, + 3;2582,2584,2583;, + 3;2590,2602,2594;, + 3;2590,2601,2602;, + 3;2591,2634,2590;, + 3;2591,2633,2634;, + 3;2594,2611,2593;, + 3;2594,2610,2611;, + 3;2592,2591,2593;, + 3;2593,2591,2590;, + 3;2593,2590,2594;, + 3;2595,2606,2599;, + 3;2595,2605,2606;, + 3;2598,2626,2597;, + 3;2598,2629,2626;, + 3;2599,2621,2598;, + 3;2599,2620,2621;, + 3;2597,2596,2598;, + 3;2598,2596,2599;, + 3;2599,2596,2595;, + 3;2600,2620,2606;, + 3;2600,2625,2620;, + 3;2601,2630,2600;, + 3;2601,2634,2630;, + 3;2603,2610,2602;, + 3;2603,2609,2610;, + 3;2604,2602,2605;, + 3;2605,2602,2601;, + 3;2605,2601,2606;, + 3;2606,2601,2600;, + 3;2602,2604,2603;, + 3;2607,2613,2612;, + 3;2607,2619,2613;, + 3;2609,2608,2610;, + 3;2610,2608,2612;, + 3;2610,2612,2611;, + 3;2612,2608,2607;, + 3;2615,2650,2614;, + 3;2615,2654,2650;, + 3;2616,2656,2615;, + 3;2616,2655,2656;, + 3;2617,2649,2616;, + 3;2617,2648,2649;, + 3;2618,2616,2619;, + 3;2619,2616,2615;, + 3;2619,2615,2614;, + 3;2619,2614,2613;, + 3;2616,2618,2617;, + 3;2622,2629,2621;, + 3;2622,2628,2629;, + 3;2625,2631,2624;, + 3;2625,2630,2631;, + 3;2624,2623,2625;, + 3;2625,2623,2621;, + 3;2625,2621,2620;, + 3;2621,2623,2622;, + 3;2627,2626,2628;, + 3;2628,2626,2629;, + 3;2633,2632,2631;, + 3;2633,2631,2630;, + 3;2633,2630,2634;, + 3;2635,2644,2639;, + 3;2635,2643,2644;, + 3;2636,2678,2635;, + 3;2636,2677,2678;, + 3;2637,2674,2636;, + 3;2637,2673,2674;, + 3;2638,2637,2639;, + 3;2639,2637,2635;, + 3;2635,2637,2636;, + 3;2641,2666,2640;, + 3;2641,2665,2666;, + 3;2642,2695,2641;, + 3;2642,2694,2695;, + 3;2643,2679,2642;, + 3;2643,2678,2679;, + 3;2640,2645,2644;, + 3;2640,2644,2643;, + 3;2640,2643,2641;, + 3;2641,2643,2642;, + 3;2646,2655,2649;, + 3;2646,2660,2655;, + 3;2647,2662,2646;, + 3;2647,2661,2662;, + 3;2648,2647,2649;, + 3;2649,2647,2646;, + 3;2652,2669,2651;, + 3;2652,2668,2669;, + 3;2653,2688,2652;, + 3;2653,2687,2688;, + 3;2654,2657,2653;, + 3;2654,2656,2657;, + 3;2650,2654,2653;, + 3;2650,2653,2651;, + 3;2651,2653,2652;, + 3;2658,2687,2657;, + 3;2658,2686,2687;, + 3;2659,2693,2658;, + 3;2659,2692,2693;, + 3;2660,2663,2659;, + 3;2660,2662,2663;, + 3;2656,2659,2657;, + 3;2657,2659,2658;, + 3;2659,2656,2660;, + 3;2660,2656,2655;, + 3;2664,2692,2663;, + 3;2664,2691,2692;, + 3;2665,2696,2664;, + 3;2665,2695,2696;, + 3;2662,2666,2665;, + 3;2662,2665,2663;, + 3;2663,2665,2664;, + 3;2666,2662,2667;, + 3;2667,2662,2661;, + 3;2668,2683,2671;, + 3;2668,2688,2683;, + 3;2671,2672,2670;, + 3;2671,2676,2672;, + 3;2671,2670,2668;, + 3;2668,2670,2669;, + 3;2675,2677,2674;, + 3;2675,2682,2677;, + 3;2676,2684,2675;, + 3;2676,2683,2684;, + 3;2675,2674,2676;, + 3;2676,2674,2672;, + 3;2672,2674,2673;, + 3;2680,2694,2679;, + 3;2680,2697,2694;, + 3;2681,2690,2680;, + 3;2681,2689,2690;, + 3;2682,2685,2681;, + 3;2682,2684,2685;, + 3;2680,2679,2681;, + 3;2681,2679,2682;, + 3;2682,2679,2677;, + 3;2677,2679,2678;, + 3;2686,2689,2685;, + 3;2686,2693,2689;, + 3;2685,2683,2688;, + 3;2685,2688,2686;, + 3;2686,2688,2687;, + 3;2683,2685,2684;, + 3;2691,2697,2690;, + 3;2691,2696,2697;, + 3;2689,2693,2690;, + 3;2690,2693,2691;, + 3;2691,2693,2692;, + 3;2697,2696,2694;, + 3;2694,2696,2695;, + 3;2699,2714,2698;, + 3;2699,2713,2714;, + 3;2701,2698,2702;, + 3;2698,2701,2699;, + 3;2699,2701,2700;, + 3;2703,2711,2707;, + 3;2703,2710,2711;, + 3;2704,2706,2705;, + 3;2707,4331,2703;, + 3;2706,2704,4325;, + 3;2709,2716,2708;, + 3;2709,2715,2716;, + 3;2709,2712,2711;, + 3;2709,2711,2710;, + 3;2712,2709,2713;, + 3;2713,2709,2714;, + 3;2714,2709,2708;, + 3;2718,2717,2716;, + 3;2718,2716,2719;, + 3;2719,2716,2715;, + 3;2721,2767,2720;, + 3;2721,2766,2767;, + 3;2722,2761,2721;, + 3;2721,2761,2762;, + 3;2722,2721,2720;, + 3;2722,2720,2725;, + 3;2722,2725,2723;, + 3;2723,2725,2724;, + 3;2727,2753,2726;, + 3;2727,2752,2753;, + 3;2730,2747,2729;, + 3;2730,2746,2747;, + 3;2732,2733,2731;, + 3;2732,2738,2733;, + 3;2728,2731,2729;, + 3;2729,2731,2730;, + 3;2731,2728,2727;, + 3;2731,2727,2732;, + 3;2732,2727,2726;, + 3;2735,3387,2734;, + 3;2735,3386,3387;, + 3;2736,2824,2735;, + 3;2736,2823,2824;, + 3;2737,2742,2736;, + 3;2737,2741,2742;, + 3;2734,2733,2735;, + 3;2735,2733,2738;, + 3;2735,2738,2736;, + 3;2736,2738,2737;, + 3;2743,2823,2742;, + 3;2743,2822,2823;, + 3;2744,2942,2743;, + 3;2744,2941,2942;, + 3;2742,2741,2744;, + 3;2742,2744,2743;, + 3;2744,2741,2739;, + 3;2739,2741,2740;, + 3;1883,2746,2745;, + 3;1883,2747,2746;, + 3;1883,2748,2747;, + 3;2750,2758,2749;, + 3;2750,2757,2758;, + 3;2753,2750,2749;, + 3;2750,2753,2751;, + 3;2751,2753,2752;, + 3;2756,2760,2755;, + 3;2756,2759,2760;, + 3;2757,2755,2758;, + 3;2758,2755,2754;, + 3;2755,2757,2756;, + 3;2763,2766,2762;, + 3;2763,2765,2766;, + 3;2759,2762,2761;, + 3;2759,2761,2760;, + 3;2762,2759,2764;, + 3;2762,2764,2763;, + 3;2765,2767,2766;, + 3;2767,2765,2768;, + 3;2771,3118,2770;, + 3;2771,3117,3118;, + 3;4370,2865,2771;, + 3;4370,4371,2865;, + 3;2773,3053,2772;, + 3;2773,3052,3053;, + 3;2774,3057,4372;, + 3;2773,4373,3058;, + 3;2774,2770,2769;, + 3;2770,2774,2771;, + 3;2771,2774,4372;, + 3;2771,4372,4370;, + 3;2775,3044,2780;, + 3;2775,3048,3044;, + 3;1886,3085,2775;, + 3;1886,1944,3085;, + 3;2776,1918,1886;, + 3;2776,3064,1918;, + 3;2777,4374,4375;, + 3;2777,3054,4374;, + 3;2778,2863,2777;, + 3;2778,2862,2863;, + 3;2779,3359,2778;, + 3;2779,3358,3359;, + 3;4376,2789,2779;, + 3;4376,4377,2789;, + 3;4378,2777,4375;, + 3;4378,2778,2777;, + 3;4378,2779,2778;, + 3;4378,4376,2779;, + 3;1886,2775,2780;, + 3;2781,3369,2788;, + 3;2781,3368,3369;, + 3;2782,2857,4379;, + 3;2781,4380,2858;, + 3;2783,2860,2782;, + 3;2783,2869,2860;, + 3;2784,3384,2783;, + 3;2784,3383,3384;, + 3;2785,3412,2784;, + 3;2785,3415,3412;, + 3;2786,3093,2785;, + 3;2786,3098,3093;, + 3;2787,2808,2786;, + 3;2787,2807,2808;, + 3;4381,3362,2787;, + 3;4381,4382,3362;, + 3;4381,2785,4379;, + 3;4379,2785,2784;, + 3;4379,2784,2782;, + 3;2782,2784,2783;, + 3;2785,4381,2786;, + 3;2786,4381,2787;, + 3;2790,3358,2789;, + 3;2790,3357,3358;, + 3;2791,3373,2790;, + 3;2791,3372,3373;, + 3;2792,3378,2791;, + 3;2792,3377,3378;, + 3;2793,3197,2792;, + 3;2793,3196,3197;, + 3;2794,3017,2793;, + 3;2794,3016,3017;, + 3;2795,3041,2794;, + 3;2795,3040,3041;, + 3;4377,3045,2795;, + 3;4377,4383,3045;, + 3;2794,2793,2795;, + 3;2795,2793,4377;, + 3;4377,2793,2792;, + 3;4377,2792,2789;, + 3;2789,2792,2791;, + 3;2789,2791,2790;, + 3;2797,4384,4385;, + 3;2802,2991,2987;, + 3;2798,4384,2797;, + 3;2798,3363,4384;, + 3;2799,2806,2798;, + 3;2799,2815,2806;, + 3;2800,3090,2799;, + 3;2800,3089,3090;, + 3;1891,2945,2800;, + 3;1891,1893,2945;, + 3;4253,4386,4387;, + 3;4253,2974,4386;, + 3;2802,3082,4253;, + 3;2802,3083,3082;, + 3;1891,4385,2801;, + 3;1891,2797,4385;, + 3;1891,2798,2797;, + 3;1891,2799,2798;, + 3;1891,2800,2799;, + 3;2803,4388,4389;, + 3;2803,3020,4388;, + 3;2804,3022,2803;, + 3;2804,3021,3022;, + 3;2805,2997,2804;, + 3;2805,2996,2997;, + 3;4389,2982,2805;, + 3;4389,4390,2982;, + 3;4389,2804,2803;, + 3;4389,2805,2804;, + 3;2807,3363,2806;, + 3;2807,3362,3363;, + 3;2809,3098,2808;, + 3;2809,3097,3098;, + 3;2810,3135,2809;, + 3;2810,3134,3135;, + 3;2811,4391,4392;, + 3;2811,3159,4391;, + 3;2812,3110,2811;, + 3;2812,3115,3110;, + 3;4393,3148,2812;, + 3;4393,4394,3148;, + 3;2814,3122,2813;, + 3;2814,3121,3122;, + 3;2815,3091,2814;, + 3;2815,3090,3091;, + 3;2806,2810,2809;, + 3;2806,2809,2807;, + 3;2807,2809,2808;, + 3;2810,2806,4395;, + 3;4395,2806,4396;, + 3;4396,2806,2813;, + 3;2813,2806,2814;, + 3;2814,2806,2815;, + 3;2816,3400,2825;, + 3;2816,3399,3400;, + 3;2817,3404,2816;, + 3;2816,3404,3405;, + 3;2818,2892,2817;, + 3;2818,2891,2892;, + 3;2819,2899,2818;, + 3;2819,2898,2899;, + 3;2820,2905,2819;, + 3;2820,2904,2905;, + 3;2821,2883,2820;, + 3;2821,2887,2883;, + 3;2822,2943,2821;, + 3;2822,2942,2943;, + 3;2825,3386,2824;, + 3;2825,3385,3386;, + 3;2817,2819,2818;, + 3;2819,2817,2820;, + 3;2820,2817,2821;, + 3;2821,2817,2816;, + 3;2821,2816,2822;, + 3;2822,2816,2825;, + 3;2822,2825,2823;, + 3;2823,2825,2824;, + 3;2826,2843,2832;, + 3;2826,2842,2843;, + 3;2827,2854,2826;, + 3;2827,2853,2854;, + 3;2830,2909,2829;, + 3;2830,2908,2909;, + 3;2831,2915,2830;, + 3;2831,2914,2915;, + 3;2832,2889,2831;, + 3;2832,2888,2889;, + 3;2830,2829,2832;, + 3;2830,2832,2831;, + 3;2832,2829,2827;, + 3;2832,2827,2826;, + 3;2827,2829,2828;, + 3;2833,2896,2838;, + 3;2833,2895,2896;, + 3;2834,3380,2833;, + 3;2834,3379,3380;, + 3;2835,2868,2834;, + 3;2835,2867,2868;, + 3;2836,2848,2835;, + 3;2836,2847,2848;, + 3;2838,2840,2837;, + 3;2838,2839,2840;, + 3;2835,2834,2836;, + 3;2836,2834,2837;, + 3;2837,2834,2838;, + 3;2838,2834,2833;, + 3;2839,2888,2843;, + 3;2839,2896,2888;, + 3;2842,2855,2841;, + 3;2842,2854,2855;, + 3;2842,2840,2839;, + 3;2842,2839,2843;, + 3;2840,2842,2841;, + 3;2844,3116,2849;, + 3;2844,3119,3116;, + 3;2849,2867,2848;, + 3;2849,2866,2867;, + 3;2847,2849,2848;, + 3;2849,2847,2844;, + 3;2844,2847,2846;, + 3;2844,2846,2845;, + 3;2851,2855,2852;, + 3;2852,2855,2853;, + 3;2853,2855,2854;, + 3;2855,2851,2850;, + 3;2856,3361,2859;, + 3;2856,3360,3361;, + 3;4380,2861,2856;, + 3;2857,2860,4397;, + 3;2859,3368,2858;, + 3;2859,3367,3368;, + 3;4380,2856,2859;, + 3;4380,2859,2858;, + 3;2862,3360,2861;, + 3;2862,3359,3360;, + 3;2864,3054,2863;, + 3;2864,3053,3054;, + 3;2866,3117,2865;, + 3;2866,3116,3117;, + 3;2869,3379,2868;, + 3;2869,3384,3379;, + 3;2867,2866,2865;, + 3;2867,2865,2868;, + 3;2868,2865,4371;, + 3;2868,4371,4397;, + 3;2868,4397,2860;, + 3;2868,2860,2869;, + 3;2861,2864,2863;, + 3;2861,2863,2862;, + 3;2873,2940,2872;, + 3;2873,2939,2940;, + 3;2874,2886,2873;, + 3;2874,2885,2886;, + 3;2875,2919,2874;, + 3;2875,2918,2919;, + 3;2876,2925,2875;, + 3;2876,2924,2925;, + 3;2877,2879,2876;, + 3;2877,2878,2879;, + 3;2874,2876,2875;, + 3;2876,2874,2873;, + 3;2876,2873,2872;, + 3;2876,2872,2877;, + 3;2877,2872,2871;, + 3;2877,2871,2870;, + 3;2880,2924,2879;, + 3;2880,2923,2924;, + 3;2881,2930,2880;, + 3;2881,2929,2930;, + 3;2878,2880,2879;, + 3;2880,2878,2881;, + 3;2881,2878,2882;, + 3;2884,2904,2883;, + 3;2884,2903,2904;, + 3;2885,2920,2884;, + 3;2885,2919,2920;, + 3;2887,2939,2886;, + 3;2887,2943,2939;, + 3;2886,2885,2887;, + 3;2887,2885,2884;, + 3;2887,2884,2883;, + 3;2890,2914,2889;, + 3;2890,2913,2914;, + 3;2891,2900,2890;, + 3;2891,2899,2900;, + 3;2893,3404,2817;, + 3;2893,3403,3404;, + 3;2894,3409,2893;, + 3;2894,3408,3409;, + 3;2895,3381,2894;, + 3;2895,3380,3381;, + 3;2890,2889,2891;, + 3;2891,2889,2892;, + 3;2892,2889,2888;, + 3;2892,2888,2893;, + 3;2893,2888,2895;, + 3;2893,2895,2894;, + 3;2895,2888,2896;, + 3;2897,2938,2901;, + 3;2897,2937,2938;, + 3;2898,2906,2897;, + 3;2898,2905,2906;, + 3;2901,2913,2900;, + 3;2901,2912,2913;, + 3;2899,2898,2900;, + 3;2900,2898,2897;, + 3;2900,2897,2901;, + 3;2902,2937,2906;, + 3;2902,2936,2937;, + 3;2903,2921,2902;, + 3;2903,2920,2921;, + 3;2902,2906,2903;, + 3;2903,2906,2904;, + 3;2904,2906,2905;, + 3;2907,2933,2911;, + 3;2907,2932,2933;, + 3;2908,2916,2907;, + 3;2908,2915,2916;, + 3;2911,2928,2910;, + 3;2911,2927,2928;, + 3;2908,2907,2911;, + 3;2908,2911,2909;, + 3;2909,2911,2910;, + 3;2912,2932,2916;, + 3;2912,2938,2932;, + 3;2916,2914,2912;, + 3;2912,2914,2913;, + 3;2914,2916,2915;, + 3;2917,2936,2921;, + 3;2917,2935,2936;, + 3;2918,2926,2917;, + 3;2918,2925,2926;, + 3;2918,2920,2919;, + 3;2920,2918,2921;, + 3;2921,2918,2917;, + 3;2922,2935,2926;, + 3;2922,2934,2935;, + 3;2923,2931,2922;, + 3;2923,2930,2931;, + 3;2926,2923,2922;, + 3;2923,2926,2925;, + 3;2923,2925,2924;, + 3;2927,2934,2931;, + 3;2927,2933,2934;, + 3;2931,2928,2927;, + 3;2928,2931,2930;, + 3;2928,2930,2929;, + 3;2934,2933,2935;, + 3;2935,2933,2938;, + 3;2935,2938,2937;, + 3;2935,2937,2936;, + 3;2938,2933,2932;, + 3;2939,2943,2942;, + 3;2939,2942,2940;, + 3;2940,2942,2941;, + 3;2944,3104,2947;, + 3;2944,3109,3104;, + 3;1893,3395,2944;, + 3;1893,2014,3395;, + 3;2946,3089,2945;, + 3;2946,3088,3089;, + 3;2947,2954,2946;, + 3;2947,2953,2954;, + 3;1893,2946,2945;, + 3;1893,2947,2946;, + 3;1893,2944,2947;, + 3;2948,3144,2952;, + 3;2948,3143,3144;, + 3;2949,2967,2948;, + 3;2949,2966,2967;, + 3;2950,3153,2949;, + 3;2950,3152,3153;, + 3;2951,3113,2950;, + 3;2951,3112,3113;, + 3;2952,3161,2951;, + 3;2952,3160,3161;, + 3;2950,2952,2951;, + 3;2952,2950,2949;, + 3;2952,2949,2948;, + 3;2953,3105,2956;, + 3;2953,3104,3105;, + 3;2955,3088,2954;, + 3;2955,3087,3088;, + 3;2956,3129,2955;, + 3;2956,3128,3129;, + 3;2953,2956,2955;, + 3;2953,2955,2954;, + 3;2957,3096,2964;, + 3;2957,3095,3096;, + 3;2958,3411,2957;, + 3;2958,3410,3411;, + 3;2959,3402,2958;, + 3;2959,3401,3402;, + 3;2960,3398,2959;, + 3;2960,3397,3398;, + 3;2961,2970,2960;, + 3;2961,2969,2970;, + 3;2962,3099,2961;, + 3;2962,3103,3099;, + 3;2963,3136,2962;, + 3;2963,3140,3136;, + 3;2964,3132,2963;, + 3;2964,3131,3132;, + 3;2958,2962,2959;, + 3;2959,2962,2960;, + 3;2960,2962,2961;, + 3;2962,2958,2957;, + 3;2962,2957,2963;, + 3;2963,2957,2964;, + 3;2965,3127,2973;, + 3;2965,3126,3127;, + 3;4398,3154,2965;, + 3;2966,3153,4399;, + 3;2968,3142,4400;, + 3;2967,4401,3143;, + 3;2969,3100,2968;, + 3;2969,3099,3100;, + 3;2971,3397,2970;, + 3;2971,3396,3397;, + 3;2972,3391,2971;, + 3;2972,3390,3391;, + 3;2973,3107,2972;, + 3;2973,3106,3107;, + 3;2971,2968,2972;, + 3;2972,2968,4400;, + 3;2972,4400,2973;, + 3;2973,4400,4398;, + 3;2973,4398,2965;, + 3;2968,2971,2969;, + 3;2969,2971,2970;, + 3;2974,4402,4386;, + 3;2974,3082,4402;, + 3;2975,2996,2982;, + 3;2975,3000,2996;, + 3;2976,3208,2975;, + 3;2976,3207,3208;, + 3;2977,3220,2976;, + 3;2977,3219,3220;, + 3;2978,3221,2977;, + 3;2978,3226,3221;, + 3;2979,3227,2978;, + 3;2979,3232,3227;, + 3;2980,3199,2979;, + 3;2980,3198,3199;, + 3;2981,3376,2980;, + 3;2981,3375,3376;, + 3;4390,2988,2981;, + 3;4390,4403,2988;, + 3;4390,2975,2982;, + 3;4390,2976,2975;, + 3;4390,2977,2976;, + 3;4390,2978,2977;, + 3;4390,2979,2978;, + 3;4390,2980,2979;, + 3;4390,2981,2980;, + 3;2983,3011,2986;, + 3;2983,3010,3011;, + 3;2984,3024,2983;, + 3;2984,3023,3024;, + 3;2985,3019,2984;, + 3;2985,3018,3019;, + 3;4404,3084,2985;, + 3;4404,4405,3084;, + 3;2986,4406,4404;, + 3;2986,2995,4406;, + 3;4404,2983,2986;, + 3;4404,2984,2983;, + 3;4404,2985,2984;, + 3;4403,3083,2987;, + 3;4403,4402,3083;, + 3;2989,3375,2988;, + 3;2989,3374,3375;, + 3;2990,3371,2989;, + 3;2990,3370,3371;, + 3;2991,3365,2990;, + 3;2991,3364,3365;, + 3;4403,2989,2988;, + 3;4403,2990,2989;, + 3;4403,2991,2990;, + 3;4403,2987,2991;, + 3;2992,4407,4406;, + 3;2992,3047,4407;, + 3;2993,3034,2992;, + 3;2993,3033,3034;, + 3;2994,3003,2993;, + 3;2994,3002,3003;, + 3;2995,3012,2994;, + 3;2995,3011,3012;, + 3;4406,2993,2992;, + 3;4406,2994,2993;, + 3;4406,2995,2994;, + 3;2998,3021,2997;, + 3;2998,3027,3021;, + 3;2999,3209,2998;, + 3;2999,3214,3209;, + 3;3000,3203,2999;, + 3;3000,3208,3203;, + 3;2997,2999,2998;, + 3;2999,2997,2996;, + 3;2999,2996,3000;, + 3;3001,3172,3007;, + 3;3001,3177,3172;, + 3;3002,3013,3001;, + 3;3002,3012,3013;, + 3;3004,3033,3003;, + 3;3004,3037,3033;, + 3;3005,3031,3004;, + 3;3005,3030,3031;, + 3;3006,3184,3005;, + 3;3006,3183,3184;, + 3;3007,3182,3006;, + 3;3007,3181,3182;, + 3;3003,3006,3004;, + 3;3004,3006,3005;, + 3;3006,3003,3007;, + 3;3007,3003,3002;, + 3;3007,3002,3001;, + 3;3008,3177,3013;, + 3;3008,3176,3177;, + 3;3009,3171,3008;, + 3;3009,3170,3171;, + 3;3010,3025,3009;, + 3;3010,3024,3025;, + 3;3010,3008,3013;, + 3;3010,3013,3011;, + 3;3011,3013,3012;, + 3;3008,3010,3009;, + 3;3014,3196,3017;, + 3;3014,3202,3196;, + 3;3015,3191,3014;, + 3;3015,3190,3191;, + 3;3016,3042,3015;, + 3;3016,3041,3042;, + 3;3016,3015,3017;, + 3;3017,3015,3014;, + 3;3018,4405,4388;, + 3;3018,3084,4405;, + 3;3020,3023,3019;, + 3;3020,3022,3023;, + 3;4388,3019,3018;, + 3;4388,3020,3019;, + 3;3026,3170,3025;, + 3;3026,3169,3170;, + 3;3027,3210,3026;, + 3;3027,3209,3210;, + 3;3026,3025,3027;, + 3;3027,3025,3022;, + 3;3027,3022,3021;, + 3;3022,3025,3023;, + 3;3023,3025,3024;, + 3;3028,3038,3032;, + 3;3028,3043,3038;, + 3;3029,3195,3028;, + 3;3029,3194,3195;, + 3;3030,3185,3029;, + 3;3030,3184,3185;, + 3;3032,3037,3031;, + 3;3032,3036,3037;, + 3;3029,3031,3030;, + 3;3031,3029,3032;, + 3;3032,3029,3028;, + 3;3035,3047,3034;, + 3;3035,3046,3047;, + 3;3036,3039,3035;, + 3;3036,3038,3039;, + 3;3034,3037,3036;, + 3;3034,3036,3035;, + 3;3037,3034,3033;, + 3;3040,3046,3039;, + 3;3040,3045,3046;, + 3;3043,3190,3042;, + 3;3043,3195,3190;, + 3;3040,3042,3041;, + 3;3042,3040,3043;, + 3;3043,3040,3039;, + 3;3043,3039,3038;, + 3;3048,1944,4408;, + 3;3048,3085,1944;, + 3;4408,3044,3048;, + 3;4407,3045,4383;, + 3;4407,3046,3045;, + 3;4407,3047,3046;, + 3;3050,3064,3049;, + 3;3050,3070,3064;, + 3;3052,3059,3051;, + 3;3052,3058,3059;, + 3;4297,3054,3051;, + 3;3051,3054,3053;, + 3;3051,3053,3052;, + 3;3054,4297,4374;, + 3;4373,4314,3058;, + 3;3058,4314,3055;, + 3;3058,3055,3059;, + 3;3060,3073,3063;, + 3;3060,3072,3073;, + 3;3061,3066,3060;, + 3;3061,3065,3066;, + 3;4409,3086,3061;, + 3;4295,4293,4410;, + 3;3062,4308,4409;, + 3;3062,3077,4308;, + 3;3063,3075,3062;, + 3;3063,3074,3075;, + 3;4409,3063,3062;, + 3;4409,3060,3063;, + 3;4409,3061,3060;, + 3;4411,1944,1918;, + 3;4411,4412,1944;, + 3;3067,4413,4414;, + 3;3067,3071,4413;, + 3;3068,3081,3067;, + 3;3068,3080,3081;, + 3;4415,4414,4416;, + 3;4415,3067,4414;, + 3;4415,3068,3067;, + 3;4415,3069,3068;, + 3;1918,3070,4299;, + 3;1918,3064,3070;, + 3;3071,151,3755;, + 3;3071,3081,151;, + 3;4417,3074,3073;, + 3;4417,4309,3074;, + 3;3755,4413,3071;, + 3;4417,3073,3072;, + 3;3076,3077,3075;, + 3;3076,3079,3077;, + 3;4309,3076,3074;, + 3;3074,3076,3075;, + 3;4308,3079,3078;, + 3;4308,3077,3079;, + 3;151,3081,3080;, + 3;4402,3082,3083;, + 3;3087,3130,3092;, + 3;3087,3129,3130;, + 3;3092,3121,3091;, + 3;3092,3120,3121;, + 3;3090,3089,3091;, + 3;3091,3089,3092;, + 3;3092,3089,3088;, + 3;3092,3088,3087;, + 3;3094,3415,3093;, + 3;3094,3414,3415;, + 3;3095,3406,3094;, + 3;3095,3411,3406;, + 3;3097,3131,3096;, + 3;3097,3135,3131;, + 3;3097,3096,3098;, + 3;3098,3096,3093;, + 3;3093,3096,3094;, + 3;3094,3096,3095;, + 3;3101,3142,3100;, + 3;3101,3141,3142;, + 3;3102,3165,3101;, + 3;3102,3164,3165;, + 3;3103,3137,3102;, + 3;3103,3136,3137;, + 3;3100,3099,3101;, + 3;3101,3099,3103;, + 3;3101,3103,3102;, + 3;3106,3128,3105;, + 3;3106,3127,3128;, + 3;3108,3390,3107;, + 3;3108,3389,3390;, + 3;3109,3392,3108;, + 3;3109,3395,3392;, + 3;3107,3106,3108;, + 3;3108,3106,3105;, + 3;3108,3105,3104;, + 3;3108,3104,3109;, + 3;3111,3159,3110;, + 3;3111,3158,3159;, + 3;3112,3162,3111;, + 3;3112,3161,3162;, + 3;3114,3152,3113;, + 3;3114,3151,3152;, + 3;3115,3145,3114;, + 3;3115,3148,3145;, + 3;3115,3111,3110;, + 3;3111,3115,3114;, + 3;3111,3114,3112;, + 3;3112,3114,3113;, + 3;3117,3119,3118;, + 3;3119,3117,3116;, + 3;3120,3125,3124;, + 3;3120,3130,3125;, + 3;3123,3147,3122;, + 3;3123,3146,3147;, + 3;3124,3150,3123;, + 3;3124,3149,3150;, + 3;3121,3123,3122;, + 3;3123,3121,3120;, + 3;3123,3120,3124;, + 3;3126,3149,3125;, + 3;3126,3154,3149;, + 3;3128,3126,3125;, + 3;3128,3125,3129;, + 3;3129,3125,3130;, + 3;3126,3128,3127;, + 3;3133,3140,3132;, + 3;3133,3139,3140;, + 3;3134,3156,3133;, + 3;3134,3155,3156;, + 3;3134,3133,3135;, + 3;3135,3133,3131;, + 3;3131,3133,3132;, + 3;3138,3164,3137;, + 3;3138,3163,3164;, + 3;3139,3157,3138;, + 3;3139,3156,3157;, + 3;3140,3138,3137;, + 3;3140,3137,3136;, + 3;3138,3140,3139;, + 3;4418,3160,3144;, + 3;4418,4419,3160;, + 3;3143,4401,4418;, + 3;3143,4418,3144;, + 3;4420,3151,3145;, + 3;4420,4421,3151;, + 3;4394,3145,3148;, + 3;3145,4394,4420;, + 3;4399,3153,4422;, + 3;4422,3153,3152;, + 3;4422,3152,4421;, + 3;4421,3152,3151;, + 3;3158,4423,4424;, + 3;3158,3162,4423;, + 3;4391,3159,4425;, + 3;4425,3159,3158;, + 3;4425,3158,4424;, + 3;4426,4423,3161;, + 3;4426,3161,3160;, + 3;4426,3160,4419;, + 3;3161,4423,3162;, + 3;3166,3176,3171;, + 3;3166,3175,3176;, + 3;3167,3256,3166;, + 3;3167,3255,3256;, + 3;3168,3287,3167;, + 3;3168,3286,3287;, + 3;3169,3211,3168;, + 3;3169,3210,3211;, + 3;3167,3169,3168;, + 3;3169,3167,3166;, + 3;3169,3166,3170;, + 3;3170,3166,3171;, + 3;3173,3181,3172;, + 3;3173,3180,3181;, + 3;3174,3260,3173;, + 3;3174,3259,3260;, + 3;3175,3257,3174;, + 3;3175,3256,3257;, + 3;3173,3176,3174;, + 3;3174,3176,3175;, + 3;3176,3173,3177;, + 3;3177,3173,3172;, + 3;3178,3183,3182;, + 3;3178,3189,3183;, + 3;3179,3269,3178;, + 3;3179,3268,3269;, + 3;3180,3261,3179;, + 3;3180,3260,3261;, + 3;3181,3178,3182;, + 3;3178,3181,3179;, + 3;3179,3181,3180;, + 3;3186,3194,3185;, + 3;3186,3193,3194;, + 3;3187,3233,3186;, + 3;3187,3239,3233;, + 3;3188,3274,3187;, + 3;3188,3273,3274;, + 3;3189,3270,3188;, + 3;3189,3269,3270;, + 3;3187,3186,3188;, + 3;3188,3186,3185;, + 3;3188,3185,3184;, + 3;3188,3184,3189;, + 3;3189,3184,3183;, + 3;3192,3202,3191;, + 3;3192,3201,3202;, + 3;3193,3234,3192;, + 3;3193,3233,3234;, + 3;3195,3191,3190;, + 3;3191,3195,3194;, + 3;3191,3194,3193;, + 3;3191,3193,3192;, + 3;3198,3377,3197;, + 3;3198,3376,3377;, + 3;3200,3232,3199;, + 3;3200,3231,3232;, + 3;3201,3235,3200;, + 3;3201,3234,3235;, + 3;3197,3201,3200;, + 3;3197,3200,3198;, + 3;3198,3200,3199;, + 3;3201,3197,3202;, + 3;3202,3197,3196;, + 3;3204,3214,3203;, + 3;3204,3213,3214;, + 3;3205,3282,3204;, + 3;3205,3281,3282;, + 3;3206,3291,3205;, + 3;3206,3290,3291;, + 3;3207,3215,3206;, + 3;3207,3220,3215;, + 3;3205,3207,3206;, + 3;3207,3205,3208;, + 3;3208,3205,3204;, + 3;3208,3204,3203;, + 3;3212,3286,3211;, + 3;3212,3285,3286;, + 3;3213,3283,3212;, + 3;3213,3282,3283;, + 3;3211,3209,3214;, + 3;3211,3214,3212;, + 3;3212,3214,3213;, + 3;3209,3211,3210;, + 3;3216,3290,3215;, + 3;3216,3289,3290;, + 3;3217,3253,3216;, + 3;3217,3252,3253;, + 3;3218,3246,3217;, + 3;3218,3245,3246;, + 3;3219,3222,3218;, + 3;3219,3221,3222;, + 3;3215,3218,3216;, + 3;3216,3218,3217;, + 3;3218,3215,3219;, + 3;3219,3215,3220;, + 3;3223,3245,3222;, + 3;3223,3244,3245;, + 3;3224,3294,3223;, + 3;3224,3298,3294;, + 3;3225,3299,3224;, + 3;3225,3304,3299;, + 3;3226,3228,3225;, + 3;3226,3227,3228;, + 3;3224,3222,3225;, + 3;3225,3222,3221;, + 3;3225,3221,3226;, + 3;3222,3224,3223;, + 3;3229,3304,3228;, + 3;3229,3303,3304;, + 3;3230,3322,3229;, + 3;3230,3321,3322;, + 3;3231,3236,3230;, + 3;3231,3235,3236;, + 3;3229,3228,3227;, + 3;3229,3227,3232;, + 3;3229,3232,3230;, + 3;3230,3232,3231;, + 3;3237,3321,3236;, + 3;3237,3320,3321;, + 3;3238,3306,3237;, + 3;3238,3305,3306;, + 3;3239,3275,3238;, + 3;3239,3274,3275;, + 3;3238,3237,3234;, + 3;3238,3234,3233;, + 3;3238,3233,3239;, + 3;3234,3237,3235;, + 3;3235,3237,3236;, + 3;3240,3272,3248;, + 3;3240,3278,3272;, + 3;3241,3312,3240;, + 3;3241,3311,3312;, + 3;3242,3328,3241;, + 3;3242,3327,3328;, + 3;3243,3334,3242;, + 3;3243,3333,3334;, + 3;3244,3295,3243;, + 3;3244,3294,3295;, + 3;3247,3252,3246;, + 3;3247,3251,3252;, + 3;3248,3266,3247;, + 3;3248,3271,3266;, + 3;3244,3241,3246;, + 3;3244,3246,3245;, + 3;3246,3241,3247;, + 3;3247,3241,3240;, + 3;3247,3240,3248;, + 3;3241,3244,3243;, + 3;3241,3243,3242;, + 3;3249,3289,3253;, + 3;3249,3293,3289;, + 3;3250,3263,3249;, + 3;3250,3262,3263;, + 3;3251,3267,3250;, + 3;3251,3266,3267;, + 3;3252,3251,3253;, + 3;3253,3251,3249;, + 3;3249,3251,3250;, + 3;3254,3279,3258;, + 3;3254,3284,3279;, + 3;3255,3288,3254;, + 3;3255,3287,3288;, + 3;3258,3259,3257;, + 3;3258,3265,3259;, + 3;3255,3254,3256;, + 3;3256,3254,3258;, + 3;3256,3258,3257;, + 3;3262,3268,3261;, + 3;3262,3267,3268;, + 3;3264,3293,3263;, + 3;3264,3292,3293;, + 3;3265,3280,3264;, + 3;3265,3279,3280;, + 3;3260,3259,3262;, + 3;3260,3262,3261;, + 3;3262,3259,3263;, + 3;3263,3259,3265;, + 3;3263,3265,3264;, + 3;3271,3273,3270;, + 3;3271,3272,3273;, + 3;3268,3267,3269;, + 3;3269,3267,3271;, + 3;3269,3271,3270;, + 3;3271,3267,3266;, + 3;3276,3305,3275;, + 3;3276,3308,3305;, + 3;3277,3314,3276;, + 3;3277,3319,3314;, + 3;3278,3313,3277;, + 3;3278,3312,3313;, + 3;3274,3276,3275;, + 3;3276,3274,3273;, + 3;3276,3273,3277;, + 3;3277,3273,3278;, + 3;3278,3273,3272;, + 3;3281,3292,3280;, + 3;3281,3291,3292;, + 3;3284,3285,3283;, + 3;3284,3288,3285;, + 3;3281,3280,3282;, + 3;3282,3280,3284;, + 3;3282,3284,3283;, + 3;3284,3280,3279;, + 3;3286,3285,3287;, + 3;3287,3285,3288;, + 3;3289,3291,3290;, + 3;3291,3289,3292;, + 3;3292,3289,3293;, + 3;3296,3333,3295;, + 3;3296,3332,3333;, + 3;3297,3340,3296;, + 3;3297,3339,3340;, + 3;3298,3300,3297;, + 3;3298,3299,3300;, + 3;3294,3298,3295;, + 3;3295,3298,3297;, + 3;3295,3297,3296;, + 3;3301,3339,3300;, + 3;3301,3338,3339;, + 3;3302,3355,3301;, + 3;3302,3354,3355;, + 3;3303,3323,3302;, + 3;3303,3322,3323;, + 3;3303,3299,3304;, + 3;3299,3303,3300;, + 3;3300,3303,3302;, + 3;3300,3302,3301;, + 3;3307,3320,3306;, + 3;3307,3326,3320;, + 3;3308,3315,3307;, + 3;3308,3314,3315;, + 3;3305,3308,3306;, + 3;3306,3308,3307;, + 3;3309,3319,3313;, + 3;3309,3318,3319;, + 3;3310,3344,3309;, + 3;3310,3343,3344;, + 3;3311,3329,3310;, + 3;3311,3328,3329;, + 3;3312,3309,3313;, + 3;3309,3312,3311;, + 3;3309,3311,3310;, + 3;3316,3326,3315;, + 3;3316,3325,3326;, + 3;3317,3350,3316;, + 3;3317,3349,3350;, + 3;3318,3345,3317;, + 3;3318,3344,3345;, + 3;3319,3316,3315;, + 3;3319,3315,3314;, + 3;3316,3319,3318;, + 3;3316,3318,3317;, + 3;3324,3354,3323;, + 3;3324,3353,3354;, + 3;3325,3351,3324;, + 3;3325,3350,3351;, + 3;3326,3322,3321;, + 3;3326,3321,3320;, + 3;3322,3326,3323;, + 3;3323,3326,3325;, + 3;3323,3325,3324;, + 3;3327,3335,3330;, + 3;3327,3334,3335;, + 3;3330,3343,3329;, + 3;3330,3342,3343;, + 3;3330,3329,3327;, + 3;3327,3329,3328;, + 3;3331,3342,3335;, + 3;3331,3347,3342;, + 3;3332,3341,3331;, + 3;3332,3340,3341;, + 3;3331,3335,3332;, + 3;3332,3335,3334;, + 3;3332,3334,3333;, + 3;3336,3347,3341;, + 3;3336,3346,3347;, + 3;3337,3348,3336;, + 3;3337,3352,3348;, + 3;3338,3356,3337;, + 3;3338,3355,3356;, + 3;3337,3336,3338;, + 3;3338,3336,3341;, + 3;3338,3341,3340;, + 3;3338,3340,3339;, + 3;3346,3349,3345;, + 3;3346,3348,3349;, + 3;3346,3342,3347;, + 3;3342,3346,3343;, + 3;3343,3346,3345;, + 3;3343,3345,3344;, + 3;3352,3353,3351;, + 3;3352,3356,3353;, + 3;3348,3352,3349;, + 3;3349,3352,3351;, + 3;3349,3351,3350;, + 3;3356,3355,3353;, + 3;3353,3355,3354;, + 3;3357,3367,3361;, + 3;3357,3373,3367;, + 3;3359,3357,3361;, + 3;3359,3361,3360;, + 3;3357,3359,3358;, + 3;3366,3370,3365;, + 3;3366,3369,3370;, + 3;4384,3362,4382;, + 3;3365,3364,3366;, + 3;3362,4384,3363;, + 3;3372,3374,3371;, + 3;3372,3378,3374;, + 3;3371,3368,3367;, + 3;3371,3367,3373;, + 3;3371,3373,3372;, + 3;3368,3371,3369;, + 3;3369,3371,3370;, + 3;3376,3378,3377;, + 3;3378,3376,3375;, + 3;3378,3375,3374;, + 3;3382,3408,3381;, + 3;3382,3407,3408;, + 3;3383,3413,3382;, + 3;3383,3412,3413;, + 3;3381,3383,3382;, + 3;3383,3381,3384;, + 3;3384,3381,3380;, + 3;3384,3380,3379;, + 3;3385,3396,3391;, + 3;3385,3400,3396;, + 3;3389,3393,3388;, + 3;3389,3392,3393;, + 3;3390,3389,3387;, + 3;3390,3387,3391;, + 3;3391,3387,3386;, + 3;3391,3386,3385;, + 3;3387,3389,3388;, + 3;2014,3392,3395;, + 3;2014,3393,3392;, + 3;2014,3394,3393;, + 3;3399,3401,3398;, + 3;3399,3405,3401;, + 3;3400,3399,3398;, + 3;3400,3398,3397;, + 3;3400,3397,3396;, + 3;3403,3410,3402;, + 3;3403,3409,3410;, + 3;3401,3405,3403;, + 3;3401,3403,3402;, + 3;3403,3405,3404;, + 3;3407,3414,3406;, + 3;3407,3413,3414;, + 3;3410,3407,3411;, + 3;3411,3407,3406;, + 3;3407,3410,3408;, + 3;3408,3410,3409;, + 3;3414,3413,3412;, + 3;3414,3412,3415;, + 3;21,88,845;, + 3;151,846,3755;, + 3;4310,4309,4427;, + 3;4310,4428,4311;, + 3;1769,3416,1770;, + 3;3416,1778,4148;, + 3;3417,1901,4429;, + 3;4429,4234,3417;, + 3;4430,3510,185;, + 3;4430,185,3509;, + 3;61,4431,3448;, + 3;61,0,4431;; + } + + MeshTextureCoords { + 4432; + 0.551713;0.158481;, + 0.442939;0.266364;, + 0.465760;0.091118;, + 0.359428;0.057171;, + 0.465760;0.024419;, + 0.815422;0.057523;, + 0.083667;0.060652;, + 0.597076;0.069576;, + 0.920137;0.671109;, + 0.842554;0.693424;, + 0.920019;0.713969;, + 0.728562;0.172729;, + 0.118906;0.107861;, + 0.644406;0.127337;, + 0.118913;0.144835;, + 0.430296;0.052895;, + 0.359428;0.116154;, + 0.356021;0.319790;, + 0.394347;0.323160;, + 0.427233;0.319079;, + 0.430296;0.009352;, + 0.886645;0.662715;, + 0.381887;0.022695;, + 0.658351;0.174014;, + 0.092993;0.146098;, + 0.685906;0.229150;, + 0.736179;0.215636;, + 0.629846;0.219982;, + 0.464459;0.320677;, + 0.700253;0.195920;, + 0.610610;0.168595;, + 0.066200;0.058208;, + 0.733851;0.325871;, + 0.054606;0.442647;, + 0.359428;0.246170;, + 0.427560;0.247468;, + 0.438618;0.408674;, + 0.356022;0.415064;, + 0.118913;0.173767;, + 0.455026;0.364714;, + 0.052464;0.254765;, + 0.419322;0.437861;, + 0.116059;0.366961;, + 0.394347;0.328619;, + 0.427233;0.324538;, + 0.442698;0.438188;, + 0.118774;0.254205;, + 0.356153;0.437792;, + 0.059890;0.171424;, + 0.032251;0.182250;, + 0.066673;0.190119;, + 0.023519;0.157546;, + 0.058251;0.145266;, + 0.005628;0.152079;, + 0.006431;0.150480;, + 0.049446;0.218747;, + 0.095581;0.212780;, + 0.118913;0.212000;, + 0.359428;0.181162;, + 0.398753;0.181862;, + 0.432820;0.182511;, + 0.574290;0.239863;, + 0.458415;0.271707;, + 0.446591;0.185893;, + 0.065339;0.442780;, + 0.669024;0.320480;, + 0.445846;0.325337;, + 0.006030;0.151279;, + 0.465760;0.051887;, + 0.559147;0.049519;, + 0.595529;0.117266;, + 0.465925;0.109701;, + 0.549941;0.151917;, + 0.587717;0.115217;, + 0.590694;0.071521;, + 0.557217;0.052500;, + 0.495192;0.111541;, + 0.522997;0.132857;, + 0.516882;0.039315;, + 0.495714;0.070258;, + 0.356021;0.382789;, + 0.375183;0.384474;, + 0.391626;0.382434;, + 0.425472;0.376874;, + 0.031504;0.215546;, + 0.359428;0.024842;, + 0.867640;0.034178;, + 0.839678;0.036502;, + 0.857340;0.649725;, + 0.359428;0.008334;, + 0.379332;0.007404;, + 0.389688;0.008235;, + 0.400856;0.002144;, + 0.409716;0.001197;, + 0.583239;0.012330;, + 0.793406;0.132263;, + 0.861711;0.672549;, + 0.893865;0.675224;, + 0.920564;0.687001;, + 0.845283;0.668070;, + 0.385765;0.310131;, + 0.667913;0.113729;, + 0.650023;0.087602;, + 0.631536;0.052867;, + 0.617447;0.029000;, + 0.639832;0.037988;, + 0.812486;0.054699;, + 0.803245;0.160421;, + 0.785495;0.208704;, + 0.867984;0.031841;, + 0.836932;0.034143;, + 0.815334;0.099408;, + 0.867984;0.017331;, + 0.830556;0.015332;, + 0.812307;0.023785;, + 0.792631;0.034435;, + 0.777019;0.056595;, + 0.764128;0.102698;, + 0.806759;0.138419;, + 0.758543;0.203424;, + 0.756451;0.178241;, + 0.750154;0.161070;, + 0.757487;0.141824;, + 0.779602;0.155868;, + 0.644346;0.272464;, + 0.639107;0.250146;, + 0.671632;0.200776;, + 0.662200;0.223137;, + 0.613887;0.268609;, + 0.631047;0.289558;, + 0.902852;0.117289;, + 0.850579;0.117328;, + 0.858474;0.096123;, + 0.901940;0.096616;, + 0.888860;0.096164;, + 0.832815;0.095553;, + 0.833973;0.117980;, + 0.551713;0.158481;, + 0.269100;0.266364;, + 0.251153;0.091117;, + 0.251153;0.024419;, + 0.920762;0.057447;, + 0.154150;0.060652;, + 0.597076;0.069576;, + 0.999127;0.694070;, + 0.728563;0.172729;, + 0.644406;0.127337;, + 0.286617;0.052895;, + 0.317692;0.323160;, + 0.284805;0.319079;, + 0.288556;0.009352;, + 0.953569;0.662737;, + 0.336965;0.022695;, + 0.658351;0.174014;, + 0.144837;0.146098;, + 0.685906;0.229150;, + 0.736179;0.215636;, + 0.629846;0.219982;, + 0.247580;0.320677;, + 0.700253;0.195920;, + 0.610610;0.168595;, + 0.171617;0.058208;, + 0.733851;0.325871;, + 0.181585;0.442779;, + 0.289352;0.247468;, + 0.205506;0.226805;, + 0.257013;0.364714;, + 0.184968;0.254780;, + 0.293026;0.437918;, + 0.317692;0.328619;, + 0.284805;0.324538;, + 0.269586;0.437793;, + 0.177940;0.171424;, + 0.205578;0.182250;, + 0.171156;0.190119;, + 0.214310;0.157546;, + 0.179579;0.145266;, + 0.229734;0.152079;, + 0.228932;0.150480;, + 0.188350;0.218747;, + 0.142249;0.212780;, + 0.318160;0.181862;, + 0.284092;0.182511;, + 0.574290;0.239863;, + 0.253624;0.271707;, + 0.270321;0.185893;, + 0.170852;0.442780;, + 0.669025;0.320480;, + 0.266193;0.325337;, + 0.229333;0.151279;, + 0.251153;0.051887;, + 0.559147;0.049519;, + 0.595529;0.117266;, + 0.250988;0.109701;, + 0.549531;0.151558;, + 0.585685;0.115494;, + 0.590395;0.071657;, + 0.557163;0.051913;, + 0.495714;0.111887;, + 0.521581;0.134300;, + 0.516917;0.039559;, + 0.495684;0.070180;, + 0.336856;0.384474;, + 0.320412;0.382434;, + 0.286567;0.376874;, + 0.206326;0.215546;, + 0.895403;0.036408;, + 0.919225;0.096002;, + 0.339520;0.007404;, + 0.329164;0.008235;, + 0.317996;0.002144;, + 0.309135;0.001197;, + 0.583239;0.012330;, + 0.942568;0.132263;, + 0.979425;0.675217;, + 0.946726;0.677891;, + 0.996398;0.668070;, + 0.326274;0.310131;, + 0.667913;0.113729;, + 0.650023;0.087602;, + 0.631536;0.052867;, + 0.617447;0.029000;, + 0.639832;0.037988;, + 0.923488;0.054699;, + 0.932729;0.160421;, + 0.950479;0.208704;, + 0.899042;0.034144;, + 0.920641;0.099408;, + 0.905419;0.015332;, + 0.923667;0.023785;, + 0.943344;0.034435;, + 0.958955;0.056595;, + 0.971847;0.102698;, + 0.929215;0.138419;, + 0.977432;0.203424;, + 0.979524;0.178241;, + 0.985820;0.161071;, + 0.978488;0.141824;, + 0.956372;0.155868;, + 0.644346;0.272464;, + 0.639107;0.250146;, + 0.671632;0.200776;, + 0.662200;0.223137;, + 0.613887;0.268609;, + 0.631047;0.289558;, + 0.902852;0.117289;, + 0.850579;0.117328;, + 0.858475;0.096123;, + 0.901940;0.096616;, + 0.888860;0.096164;, + 0.832815;0.095553;, + 0.833973;0.117980;, + 0.362779;0.521593;, + 0.114079;0.496280;, + 0.015593;0.538621;, + 0.413067;0.590996;, + 0.071282;0.556579;, + 0.114079;0.567406;, + 0.099956;0.579574;, + 0.424300;0.515014;, + 0.462475;0.504546;, + 0.109294;0.615708;, + 0.446455;0.570659;, + 0.063583;0.507001;, + 0.114079;0.543305;, + 0.431632;0.586910;, + 0.460591;0.574244;, + 0.088110;0.748276;, + 0.375357;0.785656;, + 0.112550;0.731015;, + 0.049365;0.760989;, + 0.041062;0.962565;, + 0.410288;0.967981;, + 0.434010;0.752783;, + 0.015465;0.715644;, + 0.033054;0.737854;, + 0.457389;0.965598;, + 0.433322;0.965919;, + 0.477819;0.771756;, + 0.082704;0.664352;, + 0.114762;0.674474;, + 0.061982;0.570639;, + 0.046172;0.686846;, + 0.410308;0.618813;, + 0.788717;0.583537;, + 0.413698;0.695212;, + 0.446559;0.645880;, + 0.058540;0.706405;, + 0.418117;0.723574;, + 0.031199;0.570609;, + 0.742190;0.313064;, + 0.756779;0.321579;, + 0.783375;0.328557;, + 0.826151;0.329094;, + 0.853820;0.326370;, + 0.746033;0.275270;, + 0.762350;0.266786;, + 0.789513;0.268192;, + 0.831224;0.279205;, + 0.857563;0.289306;, + 0.724828;0.460339;, + 0.739319;0.455172;, + 0.757159;0.439798;, + 0.414408;0.971032;, + 0.728309;0.346757;, + 0.745926;0.344262;, + 0.772846;0.351868;, + 0.010735;0.967181;, + 0.861627;0.308964;, + 0.837868;0.327705;, + 0.842297;0.284145;, + 0.411091;0.651182;, + 0.428698;0.876513;, + 0.423699;0.568455;, + 0.065047;0.942678;, + 0.037106;0.942847;, + 0.079040;0.940766;, + 0.391091;0.940519;, + 0.011332;0.941808;, + 0.412732;0.940671;, + 0.462371;0.941498;, + 0.437517;0.942397;, + 0.375061;0.808473;, + 0.399631;0.794862;, + 0.442565;0.794868;, + 0.081790;0.877027;, + 0.024359;0.876663;, + 0.383056;0.878540;, + 0.449565;0.876567;, + 0.480165;0.877379;, + 0.046689;0.877006;, + 0.407005;0.875615;, + 0.013484;0.572291;, + 0.084679;0.696575;, + 0.030451;0.697677;, + 0.392449;0.753106;, + 0.421098;0.794206;, + 0.051990;0.644457;, + 0.750745;0.580656;, + 0.416248;0.711576;, + 0.418268;0.732598;, + 0.416528;0.716968;, + 0.415048;0.703811;, + 0.054057;0.740134;, + 0.043962;0.728755;, + 0.072651;0.727710;, + 0.061716;0.964870;, + 0.784783;0.408719;, + 0.023733;0.964338;, + 0.784278;0.388010;, + 0.790879;0.373359;, + 0.787672;0.372002;, + 0.799093;0.370321;, + 0.819904;0.363746;, + 0.836925;0.361193;, + 0.856879;0.367989;, + 0.852722;0.366515;, + 0.789870;0.422196;, + 0.790150;0.426709;, + 0.802645;0.438063;, + 0.841137;0.441531;, + 0.855986;0.431918;, + 0.818542;0.442967;, + 0.830870;0.443475;, + 0.849598;0.436887;, + 0.861367;0.437046;, + 0.844150;0.363301;, + 0.046193;0.968453;, + 0.034249;0.969452;, + 0.026167;0.976093;, + 0.024562;0.979040;, + 0.023590;0.980527;, + 0.021595;0.986662;, + 0.458536;0.990264;, + 0.443083;0.983817;, + 0.451432;0.985102;, + 0.054884;0.971077;, + 0.058812;0.974886;, + 0.061081;0.985310;, + 0.421917;0.990046;, + 0.429331;0.982643;, + 0.061489;0.988962;, + 0.423160;0.991430;, + 0.422049;0.986512;, + 0.437053;0.983662;, + 0.455713;0.987962;, + 0.751936;0.511608;, + 0.775565;0.511382;, + 0.790667;0.510828;, + 0.742260;0.511058;, + 0.446359;0.592000;, + 0.056469;0.615493;, + 0.429093;0.704697;, + 0.113358;0.698276;, + 0.471054;0.693874;, + 0.443694;0.677693;, + 0.732967;0.488721;, + 0.824812;0.489415;, + 0.811150;0.610036;, + 0.725246;0.572015;, + 0.797433;0.490302;, + 0.757124;0.490022;, + 0.786758;0.613931;, + 0.823818;0.573700;, + 0.726973;0.508449;, + 0.825801;0.540741;, + 0.750561;0.617018;, + 0.726834;0.606098;, + 0.821824;0.510894;, + 0.790460;0.583701;, + 0.752506;0.580815;, + 0.753155;0.511554;, + 0.793248;0.510776;, + 0.740977;0.510621;, + 0.788229;0.614117;, + 0.724265;0.508140;, + 0.752135;0.617252;, + 0.826553;0.510835;, + 0.777823;0.511251;, + 0.754149;0.511440;, + 0.805126;0.511381;, + 0.114079;0.557341;, + 0.759721;0.398421;, + 0.761054;0.366386;, + 0.752224;0.439813;, + 0.816369;0.348071;, + 0.763538;0.460181;, + 0.395296;0.477256;, + 0.359862;0.470419;, + 0.088767;0.477079;, + 0.114079;0.476699;, + 0.411840;0.477331;, + 0.424655;0.477418;, + 0.066498;0.477187;, + 0.054242;0.477230;, + 0.439588;0.477494;, + 0.104660;0.254436;, + 0.096806;0.469878;, + 0.042134;0.449763;, + 0.414949;0.445141;, + 0.445503;0.445173;, + 0.848943;0.392358;, + 0.359862;0.445094;, + 0.391297;0.471167;, + 0.359862;0.470734;, + 0.076342;0.470898;, + 0.114079;0.476851;, + 0.414326;0.471332;, + 0.432164;0.471525;, + 0.042403;0.471131;, + 0.023723;0.471226;, + 0.448021;0.471691;, + 0.096201;0.449182;, + 0.104436;0.476901;, + 0.848942;0.395254;, + 0.848943;0.414986;, + 0.838153;0.395231;, + 0.838152;0.414996;, + 0.104420;0.486605;, + 0.106000;0.540169;, + 0.114079;0.496443;, + 0.114079;0.543468;, + 0.104114;0.486767;, + 0.105694;0.540332;, + 0.418093;0.495004;, + 0.423993;0.537540;, + 0.052028;0.528907;, + 0.392382;0.518528;, + 0.393769;0.530518;, + 0.396684;0.550706;, + 0.396337;0.568785;, + 0.392230;0.581982;, + 0.393079;0.606632;, + 0.438065;0.499238;, + 0.444577;0.525255;, + 0.387594;0.633179;, + 0.392223;0.662757;, + 0.396860;0.687511;, + 0.428691;0.622255;, + 0.435371;0.647317;, + 0.432617;0.685648;, + 0.087463;0.497126;, + 0.044563;0.505211;, + 0.079294;0.533408;, + 0.064206;0.504727;, + 0.039557;0.954539;, + 0.047283;0.954585;, + 0.427587;0.955639;, + 0.436284;0.955532;, + 0.074460;0.952724;, + 0.107172;0.957531;, + 0.394046;0.960089;, + 0.011938;0.955578;, + 0.025135;0.953131;, + 0.031836;0.953763;, + 0.418250;0.955939;, + 0.445123;0.955762;, + 0.454737;0.955923;, + 0.060252;0.954128;, + 0.064395;0.953699;, + 0.468310;0.956951;, + 0.048881;0.923002;, + 0.067036;0.922724;, + 0.034866;0.922252;, + 0.041046;0.922410;, + 0.453757;0.921277;, + 0.459086;0.921847;, + 0.435977;0.920548;, + 0.429060;0.920667;, + 0.411319;0.921527;, + 0.418037;0.920760;, + 0.082849;0.921580;, + 0.105367;0.921562;, + 0.076317;0.922237;, + 0.022332;0.921620;, + 0.446710;0.921015;, + 0.009127;0.921034;, + 0.039900;0.830890;, + 0.047550;0.831189;, + 0.410351;0.830272;, + 0.423955;0.828454;, + 0.402420;0.830320;, + 0.067293;0.831602;, + 0.082288;0.830912;, + 0.028250;0.831256;, + 0.480055;0.833255;, + 0.466431;0.833260;, + 0.456669;0.830024;, + 0.393812;0.832157;, + 0.385383;0.831460;, + 0.377789;0.834202;, + 0.445359;0.830391;, + 0.437600;0.830169;, + 0.109740;0.773655;, + 0.394735;0.772286;, + 0.400492;0.771751;, + 0.434800;0.771486;, + 0.095454;0.772777;, + 0.068958;0.775796;, + 0.086328;0.774353;, + 0.039592;0.773128;, + 0.027588;0.773542;, + 0.051030;0.774597;, + 0.415238;0.750555;, + 0.418145;0.769176;, + 0.068759;0.877502;, + 0.013073;0.740827;, + 0.110236;0.754382;, + 0.078908;0.601144;, + 0.100667;0.632553;, + 0.410634;0.615525;, + 0.105165;0.597111;, + 0.392799;0.705637;, + 0.086349;0.723962;, + 0.362779;0.491146;, + 0.362779;0.547658;, + 0.394008;0.495494;, + 0.214445;0.539488;, + 0.312502;0.590996;, + 0.156867;0.556579;, + 0.127949;0.579574;, + 0.296719;0.515014;, + 0.263475;0.504546;, + 0.120939;0.615708;, + 0.274563;0.570659;, + 0.166661;0.506808;, + 0.293936;0.586910;, + 0.259858;0.571459;, + 0.148894;0.749622;, + 0.353177;0.784954;, + 0.127105;0.730907;, + 0.178784;0.760989;, + 0.194710;0.961754;, + 0.315281;0.967981;, + 0.291559;0.752783;, + 0.221894;0.714124;, + 0.202002;0.739201;, + 0.268180;0.965598;, + 0.292247;0.965919;, + 0.250861;0.773185;, + 0.148102;0.666339;, + 0.126837;0.672304;, + 0.166167;0.570639;, + 0.187128;0.679052;, + 0.315261;0.618812;, + 0.788717;0.583537;, + 0.311871;0.695212;, + 0.279010;0.645879;, + 0.176804;0.706885;, + 0.307451;0.723574;, + 0.198839;0.571476;, + 0.742190;0.312541;, + 0.756779;0.321055;, + 0.783375;0.328033;, + 0.826151;0.328571;, + 0.853820;0.325847;, + 0.746033;0.274746;, + 0.762350;0.266262;, + 0.789513;0.267668;, + 0.831224;0.278682;, + 0.857563;0.288782;, + 0.724828;0.460339;, + 0.739319;0.455172;, + 0.757159;0.439798;, + 0.319470;0.975754;, + 0.728309;0.346757;, + 0.745926;0.344262;, + 0.772846;0.351868;, + 0.227252;0.968539;, + 0.861627;0.308441;, + 0.837868;0.327181;, + 0.842297;0.283622;, + 0.314478;0.651182;, + 0.296871;0.876513;, + 0.297319;0.568455;, + 0.170740;0.942462;, + 0.198680;0.942631;, + 0.156747;0.940551;, + 0.346972;0.946444;, + 0.227556;0.941050;, + 0.312837;0.940671;, + 0.263198;0.941498;, + 0.288052;0.942397;, + 0.350771;0.806681;, + 0.325938;0.794862;, + 0.283003;0.794868;, + 0.154964;0.877145;, + 0.209435;0.877359;, + 0.350023;0.880017;, + 0.276004;0.876567;, + 0.248126;0.876903;, + 0.189592;0.877125;, + 0.327467;0.876705;, + 0.216554;0.573159;, + 0.150901;0.696187;, + 0.195986;0.685920;, + 0.333119;0.753106;, + 0.304470;0.794206;, + 0.179704;0.645000;, + 0.750745;0.580656;, + 0.309321;0.711576;, + 0.307301;0.732598;, + 0.309041;0.716968;, + 0.310520;0.703811;, + 0.179110;0.740324;, + 0.196462;0.720314;, + 0.163874;0.727025;, + 0.175639;0.964059;, + 0.784588;0.408840;, + 0.212039;0.963527;, + 0.784082;0.388131;, + 0.790683;0.373480;, + 0.787672;0.372002;, + 0.799093;0.370321;, + 0.819904;0.363746;, + 0.836925;0.361193;, + 0.856879;0.367989;, + 0.852722;0.366515;, + 0.781318;0.421781;, + 0.790151;0.426709;, + 0.802645;0.438063;, + 0.841137;0.441531;, + 0.855986;0.431918;, + 0.818542;0.442967;, + 0.830870;0.443475;, + 0.849598;0.436887;, + 0.861065;0.436308;, + 0.844150;0.363301;, + 0.188198;0.969250;, + 0.200851;0.969815;, + 0.208933;0.976456;, + 0.210538;0.979402;, + 0.211510;0.980889;, + 0.212619;0.987459;, + 0.267032;0.990264;, + 0.282486;0.983817;, + 0.274136;0.985102;, + 0.177024;0.972308;, + 0.172563;0.978070;, + 0.167812;0.984370;, + 0.311368;0.988230;, + 0.296237;0.982643;, + 0.167404;0.988023;, + 0.321700;0.992157;, + 0.303520;0.986512;, + 0.288516;0.983662;, + 0.269855;0.987962;, + 0.751936;0.511608;, + 0.775565;0.511382;, + 0.790667;0.510828;, + 0.742260;0.511058;, + 0.279210;0.591999;, + 0.172625;0.617805;, + 0.296476;0.704697;, + 0.127747;0.694998;, + 0.259571;0.683877;, + 0.281486;0.677693;, + 0.732967;0.488721;, + 0.824812;0.489415;, + 0.811150;0.610036;, + 0.725246;0.572015;, + 0.797433;0.490302;, + 0.757124;0.490022;, + 0.786758;0.613931;, + 0.823818;0.573700;, + 0.726973;0.508449;, + 0.825801;0.540741;, + 0.750561;0.617018;, + 0.726834;0.606098;, + 0.821824;0.510894;, + 0.790460;0.583701;, + 0.752506;0.580815;, + 0.753155;0.511554;, + 0.793248;0.510776;, + 0.740977;0.510621;, + 0.788229;0.614117;, + 0.724265;0.508140;, + 0.752135;0.617252;, + 0.826553;0.510835;, + 0.777823;0.511251;, + 0.754149;0.511440;, + 0.805126;0.511381;, + 0.759526;0.398542;, + 0.761054;0.366386;, + 0.752224;0.439813;, + 0.816369;0.348071;, + 0.763538;0.460181;, + 0.325722;0.477256;, + 0.139382;0.477079;, + 0.309178;0.477331;, + 0.296364;0.477418;, + 0.163540;0.478054;, + 0.175796;0.478097;, + 0.286362;0.477494;, + 0.132862;0.254436;, + 0.127918;0.469878;, + 0.186151;0.449763;, + 0.309627;0.445141;, + 0.276170;0.445173;, + 0.330860;0.471167;, + 0.152834;0.470898;, + 0.307830;0.471332;, + 0.289993;0.471525;, + 0.186773;0.471131;, + 0.205453;0.471226;, + 0.274619;0.471691;, + 0.128523;0.449182;, + 0.124295;0.476901;, + 0.858050;0.395224;, + 0.858013;0.415012;, + 0.124310;0.488385;, + 0.123749;0.539991;, + 0.124616;0.488548;, + 0.124054;0.540154;, + 0.302926;0.495004;, + 0.297025;0.537540;, + 0.178010;0.529774;, + 0.328636;0.518528;, + 0.327249;0.530518;, + 0.324335;0.550706;, + 0.324681;0.568785;, + 0.333339;0.581982;, + 0.332490;0.606632;, + 0.282953;0.499238;, + 0.276441;0.525255;, + 0.337974;0.633179;, + 0.333346;0.662757;, + 0.328709;0.687511;, + 0.296878;0.622255;, + 0.290197;0.647317;, + 0.292952;0.685648;, + 0.140893;0.496067;, + 0.185508;0.505018;, + 0.148854;0.533408;, + 0.166039;0.504534;, + 0.195019;0.954017;, + 0.187293;0.954062;, + 0.297982;0.955639;, + 0.289285;0.955532;, + 0.159912;0.950756;, + 0.134967;0.960262;, + 0.323148;0.959549;, + 0.227794;0.956682;, + 0.209442;0.952609;, + 0.202741;0.953240;, + 0.307318;0.955939;, + 0.280446;0.955762;, + 0.270832;0.955923;, + 0.174324;0.953605;, + 0.170182;0.953177;, + 0.267761;0.956475;, + 0.185260;0.923093;, + 0.166869;0.922238;, + 0.200928;0.922343;, + 0.194040;0.922790;, + 0.271812;0.921277;, + 0.266483;0.921847;, + 0.289591;0.920548;, + 0.296509;0.920667;, + 0.323153;0.922617;, + 0.307532;0.920760;, + 0.149462;0.921383;, + 0.134007;0.919990;, + 0.155182;0.922040;, + 0.211948;0.922290;, + 0.278858;0.921015;, + 0.225949;0.921414;, + 0.194927;0.831623;, + 0.186805;0.832210;, + 0.315217;0.830272;, + 0.301614;0.828454;, + 0.323149;0.830320;, + 0.167299;0.832624;, + 0.152776;0.831645;, + 0.208876;0.832250;, + 0.253050;0.830737;, + 0.267081;0.829903;, + 0.274345;0.830976;, + 0.328922;0.829025;, + 0.338526;0.829644;, + 0.351328;0.831822;, + 0.280209;0.830391;, + 0.287969;0.830169;, + 0.126361;0.773469;, + 0.330834;0.772286;, + 0.325077;0.771751;, + 0.290768;0.771486;, + 0.141975;0.768795;, + 0.164453;0.775643;, + 0.148027;0.773912;, + 0.195235;0.772686;, + 0.207004;0.772233;, + 0.179311;0.769531;, + 0.310331;0.750555;, + 0.307424;0.769176;, + 0.167049;0.878487;, + 0.222577;0.740583;, + 0.127126;0.753815;, + 0.151890;0.600774;, + 0.134216;0.634865;, + 0.314934;0.615524;, + 0.126647;0.597111;, + 0.332770;0.705637;, + 0.149467;0.725011;, + 0.327010;0.495494;, + 0.860789;0.657454;, + 0.978336;0.654931;, + 0.313267;0.411755;, + 0.400447;0.411627;, + 0.536289;0.424917;, + 0.499467;0.433281;, + 0.571290;0.353491;, + 0.590379;0.363402;, + 0.579112;0.483381;, + 0.615218;0.411951;, + 0.665610;0.410428;, + 0.615331;0.353127;, + 0.515344;0.481729;, + 0.498592;0.482057;, + 0.698075;0.478723;, + 0.614392;0.483897;, + 0.645237;0.478272;, + 0.715733;0.529411;, + 0.612983;0.524847;, + 0.523967;0.489788;, + 0.652416;0.486671;, + 0.526120;0.521423;, + 0.653761;0.532059;, + 0.495030;0.522681;, + 0.576437;0.524074;, + 0.715714;0.485627;, + 0.699421;0.485627;, + 0.577420;0.491458;, + 0.615127;0.491934;, + 0.679818;0.486289;, + 0.490235;0.487956;, + 0.635713;0.529981;, + 0.635720;0.486830;, + 0.678267;0.532636;, + 0.486373;0.534489;, + 0.494039;0.535189;, + 0.654239;0.538592;, + 0.679198;0.539289;, + 0.619681;0.536690;, + 0.636359;0.538445;, + 0.527499;0.535352;, + 0.576745;0.536475;, + 0.681707;0.479236;, + 0.716165;0.476668;, + 0.544027;0.484449;, + 0.501868;0.507433;, + 0.493455;0.506823;, + 0.697537;0.508227;, + 0.715163;0.508854;, + 0.550096;0.509441;, + 0.576243;0.509953;, + 0.593682;0.510741;, + 0.612347;0.510925;, + 0.633337;0.509019;, + 0.642214;0.509013;, + 0.687735;0.508461;, + 0.680802;0.508655;, + 0.669120;0.508902;, + 0.628648;0.508941;, + 0.520188;0.508274;, + 0.531694;0.509755;, + 0.653675;0.509091;, + 0.568360;0.596314;, + 0.521581;0.593697;, + 0.615591;0.580289;, + 0.570231;0.714150;, + 0.541700;0.715288;, + 0.505061;0.580731;, + 0.638820;0.606874;, + 0.670871;0.714940;, + 0.522733;0.717029;, + 0.693528;0.607941;, + 0.666459;0.608484;, + 0.706173;0.594310;, + 0.625995;0.593169;, + 0.512624;0.594919;, + 0.545974;0.592953;, + 0.580745;0.598731;, + 0.582736;0.661778;, + 0.592837;0.662044;, + 0.573003;0.661443;, + 0.563094;0.661023;, + 0.549894;0.660271;, + 0.517677;0.658749;, + 0.529421;0.658867;, + 0.647622;0.658026;, + 0.636012;0.658320;, + 0.623324;0.658018;, + 0.540126;0.659521;, + 0.662431;0.658703;, + 0.676303;0.658561;, + 0.685399;0.659635;, + 0.695076;0.660466;, + 0.710549;0.661174;, + 0.544941;0.576131;, + 0.541656;0.556865;, + 0.523025;0.572790;, + 0.563141;0.575307;, + 0.553866;0.374524;, + 0.579122;0.410083;, + 0.715663;0.424895;, + 0.599689;0.345884;, + 0.873230;0.274025;, + 0.898854;0.274219;, + 0.958184;0.540522;, + 0.935286;0.536674;, + 0.874609;0.301468;, + 0.894704;0.289223;, + 0.960279;0.517513;, + 0.923442;0.290776;, + 0.873524;0.323161;, + 0.908654;0.364066;, + 0.990069;0.437218;, + 0.921995;0.366162;, + 0.975391;0.495368;, + 0.936371;0.444829;, + 0.952487;0.485622;, + 0.992783;0.435764;, + 0.927528;0.325647;, + 0.939277;0.476721;, + 0.936325;0.504751;, + 0.946497;0.334246;, + 0.926817;0.477177;, + 0.949882;0.328775;, + 0.900982;0.369442;, + 0.917022;0.367144;, + 0.905700;0.368564;, + 0.885802;0.371364;, + 0.919110;0.361178;, + 0.887784;0.366305;, + 0.883099;0.371914;, + 0.897381;0.369979;, + 0.975720;0.439230;, + 0.952400;0.442506;, + 0.942930;0.443943;, + 0.983446;0.438196;, + 0.987224;0.471182;, + 0.988285;0.492297;, + 0.958862;0.483089;, + 0.957743;0.501239;, + 0.931439;0.365235;, + 0.948438;0.470833;, + 0.954353;0.469827;, + 0.927964;0.338719;, + 0.934931;0.474721;, + 0.927571;0.472571;, + 0.941879;0.487722;, + 0.921776;0.482053;, + 0.939058;0.353581;, + 0.919942;0.473511;, + 0.912300;0.476143;, + 0.946882;0.345223;, + 0.929139;0.466241;, + 0.944801;0.363381;, + 0.917960;0.459364;, + 0.913105;0.460961;, + 0.949839;0.357962;, + 1.000000;1.000000;, + 0.950983;0.367857;, + 0.913408;0.450900;, + 0.911252;0.451536;, + 0.953230;0.365413;, + 0.915244;0.449142;, + 0.900640;0.363431;, + 0.913324;0.367647;, + 0.890638;0.370774;, + 0.876313;0.372530;, + 0.928631;0.365429;, + 0.959662;0.441499;, + 0.968760;0.440024;, + 0.918587;0.373211;, + 0.921969;0.372736;, + 0.927792;0.372084;, + 0.930233;0.371906;, + 0.936779;0.438485;, + 0.942792;0.437735;, + 0.919984;0.379212;, + 0.922713;0.378822;, + 0.927354;0.378302;, + 0.929268;0.378172;, + 0.937025;0.432481;, + 0.941818;0.431883;, + 0.919581;0.384226;, + 0.922252;0.383857;, + 0.926937;0.383332;, + 0.928951;0.383176;, + 0.937170;0.427349;, + 0.942009;0.426744;, + 0.918353;0.388611;, + 0.921672;0.388155;, + 0.927494;0.387502;, + 0.929998;0.387306;, + 0.936685;0.423466;, + 0.942698;0.422715;, + 0.918796;0.395081;, + 0.921850;0.394655;, + 0.927143;0.394062;, + 0.929382;0.393895;, + 0.936942;0.417357;, + 0.942408;0.416675;, + 0.920034;0.399980;, + 0.922304;0.399663;, + 0.926264;0.399219;, + 0.927954;0.399093;, + 0.937559;0.412281;, + 0.941648;0.411769;, + 0.919307;0.404223;, + 0.921874;0.403869;, + 0.926387;0.403363;, + 0.928332;0.403212;, + 0.937409;0.408406;, + 0.942069;0.407823;, + 0.917905;0.407449;, + 0.921148;0.407016;, + 0.926970;0.406363;, + 0.929548;0.406145;, + 0.936795;0.405668;, + 0.942807;0.404917;, + 0.918548;0.413426;, + 0.921333;0.413058;, + 0.926395;0.412491;, + 0.928671;0.412292;, + 0.937141;0.399905;, + 0.942368;0.399251;, + 0.920875;0.417398;, + 0.922434;0.417195;, + 0.925394;0.416864;, + 0.926796;0.416735;, + 0.937785;0.395465;, + 0.940842;0.395081;, + 0.922919;0.418989;, + 0.924915;0.418765;, + 0.901952;0.377814;, + 0.905828;0.377270;, + 0.912504;0.376521;, + 0.915302;0.376318;, + 0.952663;0.433953;, + 0.959556;0.433094;, + 0.903532;0.386027;, + 0.906660;0.385579;, + 0.911981;0.384983;, + 0.914175;0.384834;, + 0.952869;0.425673;, + 0.958364;0.424987;, + 0.903053;0.392854;, + 0.906115;0.392431;, + 0.911486;0.391829;, + 0.913794;0.391650;, + 0.953130;0.418898;, + 0.958676;0.418205;, + 0.901631;0.398799;, + 0.905435;0.398276;, + 0.912109;0.397528;, + 0.914980;0.397303;, + 0.952576;0.413568;, + 0.959469;0.412708;, + 0.902116;0.407623;, + 0.905616;0.407134;, + 0.911684;0.406454;, + 0.914251;0.406263;, + 0.952875;0.405219;, + 0.959141;0.404437;, + 0.903517;0.414330;, + 0.906120;0.413967;, + 0.910659;0.413459;, + 0.912596;0.413313;, + 0.953585;0.398356;, + 0.958273;0.397770;, + 0.902669;0.420094;, + 0.905613;0.419688;, + 0.910786;0.419108;, + 0.913016;0.418935;, + 0.953416;0.393054;, + 0.958758;0.392386;, + 0.901052;0.424454;, + 0.904769;0.423957;, + 0.911443;0.423209;, + 0.914399;0.422959;, + 0.952714;0.389283;, + 0.959606;0.388422;, + 0.901767;0.432611;, + 0.904961;0.432189;, + 0.910763;0.431539;, + 0.913372;0.431311;, + 0.953114;0.381429;, + 0.959106;0.380679;, + 0.904421;0.438084;, + 0.906207;0.437851;, + 0.909601;0.437471;, + 0.911209;0.437325;, + 0.953855;0.375458;, + 0.957360;0.375018;, + 0.906757;0.440305;, + 0.909046;0.440049;, + 0.886697;0.379215;, + 0.890457;0.378707;, + 0.896932;0.378021;, + 0.899646;0.377844;, + 0.968718;0.432149;, + 0.975405;0.431354;, + 0.888142;0.386760;, + 0.891176;0.386342;, + 0.896337;0.385796;, + 0.898465;0.385667;, + 0.969012;0.424526;, + 0.974343;0.423891;, + 0.887606;0.393030;, + 0.890576;0.392636;, + 0.895785;0.392084;, + 0.898024;0.391927;, + 0.969344;0.418289;, + 0.974724;0.417647;, + 0.886166;0.398492;, + 0.889856;0.398005;, + 0.896330;0.397319;, + 0.899114;0.397121;, + 0.968874;0.413398;, + 0.975560;0.412602;, + 0.886544;0.406601;, + 0.889939;0.406144;, + 0.895825;0.405521;, + 0.898314;0.405354;, + 0.969265;0.405734;, + 0.975344;0.405010;, + 0.887831;0.412762;, + 0.890355;0.412423;, + 0.894759;0.411957;, + 0.896637;0.411830;, + 0.970033;0.399417;, + 0.974581;0.398875;, + 0.886950;0.418057;, + 0.889805;0.417679;, + 0.894822;0.417148;, + 0.896985;0.416995;, + 0.969934;0.394550;, + 0.975116;0.393932;, + 0.885337;0.422064;, + 0.888943;0.421602;, + 0.895416;0.420917;, + 0.898283;0.420694;, + 0.969302;0.391091;, + 0.975987;0.390294;, + 0.885945;0.429560;, + 0.889043;0.429168;, + 0.894671;0.428572;, + 0.897201;0.428368;, + 0.969784;0.383876;, + 0.975597;0.383182;, + 0.888458;0.434587;, + 0.890191;0.434371;, + 0.893483;0.434023;, + 0.895042;0.433891;, + 0.970570;0.378374;, + 0.973970;0.377966;, + 0.890699;0.436626;, + 0.892918;0.436391;, + 0.873590;0.378201;, + 0.876754;0.377927;, + 0.882197;0.377665;, + 0.884478;0.377676;, + 0.983808;0.432077;, + 0.989434;0.431709;, + 0.874466;0.383837;, + 0.877019;0.383608;, + 0.881358;0.383399;, + 0.883146;0.383419;, + 0.984483;0.426530;, + 0.988968;0.426236;, + 0.873741;0.388449;, + 0.876240;0.388241;, + 0.880620;0.388030;, + 0.882501;0.388027;, + 0.984975;0.421784;, + 0.989502;0.421487;, + 0.872297;0.392437;, + 0.875400;0.392181;, + 0.880844;0.391919;, + 0.883183;0.391913;, + 0.984828;0.418156;, + 0.990454;0.417787;, + 0.872256;0.398460;, + 0.875112;0.398216;, + 0.880061;0.397978;, + 0.882153;0.397983;, + 0.985540;0.412506;, + 0.990654;0.412170;, + 0.873061;0.403065;, + 0.875184;0.402884;, + 0.878886;0.402706;, + 0.880465;0.402709;, + 0.986482;0.407841;, + 0.990308;0.407589;, + 0.872091;0.406953;, + 0.874492;0.406754;, + 0.878711;0.406551;, + 0.880528;0.406547;, + 0.986642;0.404240;, + 0.991003;0.403953;, + 0.870567;0.409862;, + 0.873600;0.409628;, + 0.879042;0.409366;, + 0.881452;0.409338;, + 0.986290;0.401667;, + 0.991915;0.401297;, + 0.994179;0.395552;, + 0.991526;0.395405;, + 0.878083;0.415017;, + 0.880210;0.414985;, + 0.987050;0.396345;, + 0.991941;0.396022;, + 0.872625;0.419247;, + 0.874082;0.419141;, + 0.876850;0.419008;, + 0.878160;0.418981;, + 0.987960;0.392274;, + 0.990821;0.392084;, + 0.874408;0.420834;, + 0.876274;0.420745;, + 0.914444;0.330564;, + 0.962526;0.444760;, + 0.947098;0.447390;, + 0.979132;0.443610;, + 0.985271;0.454609;, + 0.930510;0.349332;, + 0.967355;0.470956;, + 0.895790;0.329672;, + 0.886980;0.274433;, + 0.919031;0.270101;, + 0.979186;0.534000;, + 0.947140;0.538822;, + 0.957002;0.521258;, + 0.942677;0.521568;, + 0.893105;0.283020;, + 0.900449;0.283372;, + 0.922519;0.283117;, + 0.928835;0.282544;, + 0.874763;0.291310;, + 0.881797;0.290567;, + 0.984320;0.517049;, + 0.965323;0.519657;, + 0.518646;0.336598;, + 0.519827;0.371410;, + 0.671119;0.374923;, + 0.486141;0.378023;, + 0.588878;0.384537;, + 0.569369;0.436791;, + 0.534201;0.395395;, + 0.634315;0.390683;, + 0.607304;0.371257;, + 0.535522;0.425621;, + 0.498701;0.433986;, + 0.570523;0.354195;, + 0.589889;0.363950;, + 0.579469;0.482740;, + 0.614731;0.411675;, + 0.665839;0.411302;, + 0.615331;0.353206;, + 0.514578;0.482433;, + 0.498517;0.482369;, + 0.698304;0.479598;, + 0.614112;0.483887;, + 0.645466;0.479147;, + 0.715264;0.526177;, + 0.613551;0.534271;, + 0.531096;0.486869;, + 0.661319;0.486708;, + 0.533898;0.532181;, + 0.661506;0.529282;, + 0.504149;0.531138;, + 0.578216;0.532151;, + 0.715484;0.485370;, + 0.707527;0.484666;, + 0.579350;0.488162;, + 0.611873;0.490245;, + 0.684034;0.484824;, + 0.499835;0.486315;, + 0.635407;0.528739;, + 0.636344;0.485738;, + 0.685374;0.525285;, + 0.485483;0.536544;, + 0.504181;0.535788;, + 0.662302;0.538686;, + 0.686436;0.536711;, + 0.619347;0.535324;, + 0.637355;0.536477;, + 0.534074;0.539453;, + 0.580776;0.536237;, + 0.681936;0.480111;, + 0.716394;0.477543;, + 0.543261;0.485154;, + 0.512380;0.507259;, + 0.504256;0.507372;, + 0.707913;0.505918;, + 0.715722;0.505571;, + 0.553334;0.507820;, + 0.578888;0.508498;, + 0.595809;0.509229;, + 0.612006;0.510097;, + 0.636064;0.506550;, + 0.642318;0.506299;, + 0.693723;0.505835;, + 0.684686;0.505729;, + 0.670350;0.505681;, + 0.629570;0.506812;, + 0.529308;0.507480;, + 0.536796;0.507313;, + 0.661416;0.507466;, + 0.517391;0.595133;, + 0.564857;0.592438;, + 0.620836;0.580957;, + 0.510599;0.715034;, + 0.533576;0.715994;, + 0.581447;0.576337;, + 0.651435;0.606044;, + 0.671670;0.716734;, + 0.561921;0.715897;, + 0.698810;0.603964;, + 0.674236;0.605860;, + 0.714006;0.590496;, + 0.634894;0.593138;, + 0.573783;0.592411;, + 0.540258;0.592834;, + 0.504639;0.596143;, + 0.509154;0.659816;, + 0.499862;0.659718;, + 0.514719;0.660512;, + 0.521908;0.660850;, + 0.535305;0.660098;, + 0.572964;0.654723;, + 0.560465;0.658285;, + 0.662012;0.654201;, + 0.650061;0.654890;, + 0.638790;0.656414;, + 0.548662;0.659348;, + 0.673319;0.653810;, + 0.686816;0.653084;, + 0.698475;0.652173;, + 0.586011;0.659448;, + 0.579484;0.655725;, + 0.541523;0.575780;, + 0.545091;0.556142;, + 0.563590;0.570593;, + 0.522875;0.573126;, + 0.553099;0.375229;, + 0.578355;0.410788;, + 0.715892;0.425770;, + 0.599584;0.345902;, + 0.869675;0.267770;, + 0.891620;0.274340;, + 0.956631;0.542084;, + 0.936131;0.537141;, + 0.875823;0.291903;, + 0.893307;0.290193;, + 0.959778;0.518762;, + 0.919671;0.294804;, + 0.874479;0.328054;, + 0.905832;0.366700;, + 0.991250;0.437386;, + 0.918895;0.367352;, + 0.973930;0.494549;, + 0.935919;0.443871;, + 0.950260;0.484642;, + 0.995481;0.435612;, + 0.924402;0.321874;, + 0.936502;0.475754;, + 0.934527;0.502788;, + 0.947699;0.339652;, + 0.925497;0.472065;, + 0.951238;0.332417;, + 0.899767;0.368320;, + 0.915033;0.365409;, + 0.903303;0.370687;, + 0.885310;0.370839;, + 0.916506;0.360664;, + 0.886275;0.368562;, + 0.881875;0.374620;, + 0.895343;0.372597;, + 0.976255;0.439156;, + 0.952245;0.441938;, + 0.942662;0.443125;, + 0.984457;0.438215;, + 0.987884;0.470638;, + 0.988977;0.491286;, + 0.957438;0.482110;, + 0.956048;0.499888;, + 0.928789;0.362833;, + 0.947826;0.469637;, + 0.954265;0.468662;, + 0.925919;0.332234;, + 0.933349;0.473352;, + 0.927207;0.467318;, + 0.938676;0.486689;, + 0.920476;0.476691;, + 0.942098;0.355717;, + 0.917880;0.468511;, + 0.911620;0.470496;, + 0.948399;0.350490;, + 0.927114;0.461639;, + 0.948339;0.363541;, + 0.915516;0.454745;, + 0.911867;0.455840;, + 0.952128;0.361098;, + 0.919864;0.450733;, + 0.954704;0.366563;, + 0.910633;0.446448;, + 0.909327;0.446777;, + 0.956207;0.366122;, + 0.912421;0.444793;, + 0.898308;0.365823;, + 0.910559;0.369492;, + 0.888924;0.373638;, + 0.875394;0.375543;, + 0.925274;0.366156;, + 0.959696;0.441092;, + 0.969126;0.439797;, + 0.946551;0.435660;, + 0.944197;0.435084;, + 0.924834;0.372188;, + 0.927874;0.369346;, + 0.936435;0.437653;, + 0.942611;0.437033;, + 0.918336;0.376837;, + 0.920307;0.378600;, + 0.924728;0.377903;, + 0.927179;0.375442;, + 0.936819;0.431756;, + 0.941743;0.431260;, + 0.918002;0.382171;, + 0.920028;0.383564;, + 0.924491;0.382858;, + 0.926928;0.380758;, + 0.937546;0.426583;, + 0.942517;0.426082;, + 0.917018;0.386350;, + 0.919551;0.388025;, + 0.925096;0.387150;, + 0.928109;0.384601;, + 0.936815;0.422845;, + 0.942991;0.422224;, + 0.917843;0.391984;, + 0.920124;0.393698;, + 0.925165;0.392903;, + 0.927926;0.390393;, + 0.936796;0.416961;, + 0.942410;0.416396;, + 0.919169;0.396797;, + 0.920867;0.398064;, + 0.924640;0.397465;, + 0.926715;0.395600;, + 0.937739;0.411927;, + 0.941942;0.411503;, + 0.918694;0.400689;, + 0.920646;0.402013;, + 0.924945;0.401331;, + 0.927293;0.399326;, + 0.937422;0.408184;, + 0.942210;0.407701;, + 0.917571;0.403505;, + 0.920137;0.404827;, + 0.925683;0.403949;, + 0.928663;0.401749;, + 0.936576;0.405558;, + 0.942753;0.404935;, + 0.918567;0.408659;, + 0.920806;0.409677;, + 0.925629;0.408910;, + 0.928213;0.407126;, + 0.936823;0.399965;, + 0.942195;0.399422;, + 0.920804;0.412883;, + 0.922075;0.413388;, + 0.924898;0.412934;, + 0.926450;0.411976;, + 0.938017;0.395490;, + 0.941162;0.395171;, + 0.922702;0.414751;, + 0.924606;0.414444;, + 0.901020;0.376297;, + 0.903892;0.378556;, + 0.910249;0.377557;, + 0.913734;0.374299;, + 0.952605;0.433562;, + 0.959684;0.432851;, + 0.902829;0.384176;, + 0.905088;0.386198;, + 0.910156;0.385399;, + 0.912966;0.382578;, + 0.953165;0.425379;, + 0.958810;0.424811;, + 0.902468;0.391336;, + 0.904790;0.392933;, + 0.909907;0.392123;, + 0.912701;0.389716;, + 0.953864;0.418645;, + 0.959563;0.418070;, + 0.901359;0.397016;, + 0.904262;0.398936;, + 0.910620;0.397933;, + 0.914074;0.395011;, + 0.953027;0.413502;, + 0.960107;0.412790;, + 0.902334;0.404835;, + 0.904949;0.406801;, + 0.910728;0.405890;, + 0.913893;0.403013;, + 0.953007;0.405443;, + 0.959443;0.404795;, + 0.903877;0.411410;, + 0.905823;0.412862;, + 0.910148;0.412176;, + 0.912527;0.410037;, + 0.954090;0.398652;, + 0.958908;0.398166;, + 0.903351;0.416741;, + 0.905589;0.418259;, + 0.910517;0.417478;, + 0.913209;0.415179;, + 0.953727;0.393522;, + 0.959217;0.392968;, + 0.902077;0.420610;, + 0.905019;0.422126;, + 0.911377;0.421119;, + 0.914793;0.418597;, + 0.952759;0.389894;, + 0.959840;0.389180;, + 0.903247;0.427782;, + 0.905813;0.428948;, + 0.911342;0.428069;, + 0.914305;0.426024;, + 0.953043;0.382263;, + 0.959202;0.381641;, + 0.905831;0.433515;, + 0.907288;0.434093;, + 0.910524;0.433573;, + 0.912302;0.432475;, + 0.954414;0.376274;, + 0.958019;0.375908;, + 0.908014;0.436040;, + 0.910197;0.435688;, + 0.886462;0.378350;, + 0.889248;0.380562;, + 0.895415;0.379631;, + 0.898797;0.376490;, + 0.969164;0.432079;, + 0.976032;0.431427;, + 0.888116;0.385590;, + 0.890308;0.387567;, + 0.895226;0.386822;, + 0.897951;0.384102;, + 0.969812;0.424541;, + 0.975288;0.424020;, + 0.887686;0.392198;, + 0.889939;0.393763;, + 0.894903;0.393008;, + 0.897614;0.390688;, + 0.970571;0.418336;, + 0.976099;0.417809;, + 0.886541;0.397415;, + 0.889358;0.399297;, + 0.895526;0.398363;, + 0.898877;0.395548;, + 0.969828;0.413622;, + 0.976697;0.412968;, + 0.887382;0.404568;, + 0.889919;0.406492;, + 0.895526;0.405643;, + 0.898596;0.402871;, + 0.969914;0.406230;, + 0.976158;0.405636;, + 0.888797;0.410616;, + 0.890686;0.412037;, + 0.894882;0.411398;, + 0.897189;0.409337;, + 0.971047;0.399978;, + 0.975720;0.399531;, + 0.888220;0.415505;, + 0.890391;0.416991;, + 0.895172;0.416264;, + 0.897783;0.414049;, + 0.970763;0.395271;, + 0.976088;0.394763;, + 0.886935;0.419043;, + 0.889789;0.420533;, + 0.895957;0.419595;, + 0.899271;0.417168;, + 0.969873;0.391947;, + 0.976742;0.391292;, + 0.887972;0.425601;, + 0.890462;0.426749;, + 0.895826;0.425931;, + 0.898700;0.423963;, + 0.970247;0.384942;, + 0.976222;0.384371;, + 0.890410;0.430892;, + 0.891823;0.431463;, + 0.894963;0.430978;, + 0.896688;0.429923;, + 0.971646;0.379415;, + 0.975143;0.379079;, + 0.892499;0.433232;, + 0.894616;0.432903;, + 0.873872;0.377973;, + 0.876220;0.379989;, + 0.881417;0.379511;, + 0.884266;0.377016;, + 0.984894;0.432226;, + 0.990673;0.431971;, + 0.874913;0.383392;, + 0.876760;0.385179;, + 0.880904;0.384796;, + 0.883200;0.382625;, + 0.985712;0.426784;, + 0.990320;0.426580;, + 0.874264;0.388323;, + 0.876163;0.389764;, + 0.880345;0.389374;, + 0.882630;0.387543;, + 0.986773;0.422001;, + 0.991425;0.421794;, + 0.873056;0.392136;, + 0.875429;0.393874;, + 0.880627;0.393393;, + 0.883450;0.391174;, + 0.986405;0.418515;, + 0.992184;0.418259;, + 0.873392;0.397396;, + 0.875529;0.399156;, + 0.880254;0.398719;, + 0.882841;0.396521;, + 0.986871;0.413082;, + 0.992125;0.412849;, + 0.874295;0.401938;, + 0.875886;0.403239;, + 0.879422;0.402908;, + 0.881366;0.401276;, + 0.988130;0.408461;, + 0.992063;0.408285;, + 0.873570;0.405513;, + 0.875399;0.406883;, + 0.879428;0.406507;, + 0.881628;0.404760;, + 0.988142;0.404988;, + 0.992623;0.404789;, + 0.872311;0.408050;, + 0.874716;0.409457;, + 0.879914;0.408973;, + 0.882707;0.407081;, + 0.987578;0.402524;, + 0.993359;0.402267;, + 0.872840;0.412876;, + 0.874937;0.413976;, + 0.879457;0.413552;, + 0.881880;0.412028;, + 0.988259;0.397367;, + 0.993286;0.397142;, + 0.874650;0.416931;, + 0.875841;0.417487;, + 0.878486;0.417234;, + 0.879940;0.416425;, + 0.989694;0.393267;, + 0.992637;0.393134;, + 0.876305;0.418781;, + 0.878089;0.418609;, + 0.911057;0.330810;, + 0.962285;0.444429;, + 0.946781;0.446617;, + 0.979370;0.443607;, + 0.986266;0.454302;, + 0.928386;0.343665;, + 0.967542;0.470029;, + 0.896709;0.331334;, + 0.879637;0.273628;, + 0.911211;0.271340;, + 0.978944;0.536142;, + 0.945667;0.539949;, + 0.955485;0.522522;, + 0.942009;0.522236;, + 0.891179;0.290655;, + 0.898435;0.289028;, + 0.916592;0.283109;, + 0.923544;0.279476;, + 0.872025;0.285035;, + 0.877537;0.287973;, + 0.984743;0.519101;, + 0.964298;0.521165;, + 0.517879;0.337303;, + 0.520333;0.371133;, + 0.671348;0.375798;, + 0.485728;0.377416;, + 0.588111;0.385241;, + 0.568603;0.437496;, + 0.533434;0.396100;, + 0.634543;0.391558;, + 0.608087;0.371187;, + 0.877145;0.707672;, + 0.960400;0.709690;, + 0.077470;0.007941;, + 0.118900;0.021439;, + 0.160343;0.007951;, + 0.096191;0.017550;, + 0.140289;0.017968;, + 0.746671;0.625954;, + 0.734244;0.671234;, + 0.732498;0.666622;, + 0.900272;0.786620;, + 0.731710;0.674849;, + 0.736027;0.666579;, + 0.900272;0.728227;, + 0.732977;0.667789;, + 0.734000;0.718795;, + 0.761074;0.747759;, + 0.736147;0.623785;, + 0.737496;0.718913;, + 0.734226;0.717671;, + 0.732523;0.718817;, + 0.810386;0.782411;, + 0.734467;0.716557;, + 0.851573;0.787367;, + 0.870436;0.732683;, + 0.553889;0.962996;, + 0.734131;0.719579;, + 0.720172;0.621381;, + 0.735588;0.646949;, + 0.030986;0.280838;, + 0.076380;0.281037;, + 0.076934;0.343481;, + 0.096103;0.280763;, + 0.095504;0.343480;, + 0.032738;0.343592;, + 0.000699;0.307701;, + 0.020304;0.311989;, + 0.047293;0.346485;, + 0.843288;0.736734;, + 0.053339;0.280612;, + 0.736338;0.664520;, + 0.725489;0.717083;, + 0.744737;0.664570;, + 0.721900;0.673406;, + 0.745925;0.715421;, + 0.562853;0.971381;, + 0.737065;0.715344;, + 0.733007;0.717941;, + 0.727989;0.737487;, + 0.733483;0.671167;, + 0.719031;0.668882;, + 0.834806;0.663521;, + 0.835007;0.658223;, + 0.834090;0.664155;, + 0.833989;0.663805;, + 0.829690;0.670101;, + 0.835801;0.668607;, + 0.835224;0.668707;, + 0.835029;0.670638;, + 0.835300;0.663893;, + 0.823120;0.662826;, + 0.832812;0.669285;, + 0.834416;0.664233;, + 0.835037;0.669733;, + 0.834887;0.666282;, + 0.561345;0.969626;, + 0.834183;0.666440;, + 0.834986;0.637076;, + 0.834482;0.664408;, + 0.835577;0.670567;, + 0.833537;0.664226;, + 0.834299;0.670158;, + 0.834830;0.672989;, + 0.833870;0.666754;, + 0.744960;0.730714;, + 0.834660;0.670688;, + 0.834070;0.669709;, + 0.832908;0.665243;, + 0.835705;0.664286;, + 0.737865;0.662673;, + 0.785973;0.667074;, + 0.787948;0.715301;, + 0.783925;0.625418;, + 0.783915;0.623808;, + 0.788056;0.716995;, + 0.784784;0.667199;, + 0.776092;0.624747;, + 0.775797;0.671137;, + 0.776148;0.714559;, + 0.786121;0.625026;, + 0.786733;0.665233;, + 0.789037;0.713793;, + 0.789604;0.625259;, + 0.792483;0.668681;, + 0.795224;0.714966;, + 0.789775;0.626794;, + 0.791308;0.716656;, + 0.788398;0.671637;, + 0.794055;0.624668;, + 0.793033;0.715686;, + 0.793153;0.675128;, + 0.789065;0.672254;, + 0.790982;0.624697;, + 0.788096;0.715701;, + 0.787237;0.625265;, + 0.782224;0.716131;, + 0.785418;0.669593;, + 0.786326;0.625266;, + 0.788118;0.668707;, + 0.790773;0.716699;, + 0.781179;0.626686;, + 0.783592;0.674061;, + 0.784872;0.713970;, + 0.792927;0.627680;, + 0.788729;0.713246;, + 0.790605;0.673075;, + 0.790030;0.625399;, + 0.791012;0.673650;, + 0.792563;0.715100;, + 0.794127;0.624315;, + 0.794834;0.671248;, + 0.795672;0.713800;, + 0.789358;0.626194;, + 0.791458;0.670782;, + 0.793092;0.716678;, + 0.788395;0.624014;, + 0.787444;0.664515;, + 0.787465;0.716819;, + 0.787466;0.627272;, + 0.786838;0.716115;, + 0.782936;0.672655;, + 0.789318;0.623431;, + 0.791531;0.717724;, + 0.791033;0.671303;, + 0.789060;0.669716;, + 0.787419;0.626528;, + 0.791040;0.712023;, + 0.785307;0.628266;, + 0.786651;0.674963;, + 0.788611;0.715906;, + 0.794461;0.691096;, + 0.735370;0.683056;, + 0.774251;0.692068;, + 0.799990;0.689774;, + 0.888227;0.790976;, + 0.835395;0.665671;, + 0.836233;0.664675;, + 0.627047;0.766014;, + 0.744572;0.715680;, + 0.736329;0.716113;, + 0.734454;0.717191;, + 0.735098;0.716966;, + 0.990159;0.782411;, + 0.734561;0.716147;, + 0.948971;0.787367;, + 0.930109;0.732683;, + 0.553889;0.962996;, + 0.734728;0.719064;, + 0.720913;0.621553;, + 0.735588;0.646949;, + 0.202979;0.278588;, + 0.159030;0.278453;, + 0.158950;0.343644;, + 0.137414;0.278462;, + 0.138487;0.343650;, + 0.204731;0.346559;, + 0.233593;0.308306;, + 0.216053;0.311410;, + 0.194414;0.346637;, + 0.957257;0.736734;, + 0.190507;0.280790;, + 0.742980;0.665126;, + 0.723160;0.707602;, + 0.740648;0.670873;, + 0.723155;0.622981;, + 0.739766;0.716934;, + 0.562853;0.971381;, + 0.733230;0.718871;, + 0.734658;0.719848;, + 0.659531;0.747477;, + 0.734644;0.670166;, + 0.721758;0.660849;, + 0.834509;0.661387;, + 0.835535;0.668135;, + 0.835670;0.666180;, + 0.834486;0.664209;, + 0.835569;0.668806;, + 0.833301;0.672000;, + 0.833602;0.671423;, + 0.834827;0.669711;, + 0.835528;0.660376;, + 0.834968;0.660657;, + 0.834747;0.664916;, + 0.834723;0.664911;, + 0.834790;0.666129;, + 0.834147;0.668202;, + 0.561345;0.969626;, + 0.836388;0.669082;, + 0.835301;0.637076;, + 0.834482;0.664408;, + 0.835101;0.665603;, + 0.834303;0.669128;, + 0.835741;0.665606;, + 0.833432;0.665737;, + 0.834464;0.665420;, + 0.642311;0.740696;, + 0.834776;0.666456;, + 0.834707;0.669011;, + 0.834423;0.666673;, + 0.833723;0.664507;, + 0.743295;0.664272;, + 0.778282;0.671219;, + 0.780253;0.710248;, + 0.775491;0.629282;, + 0.775715;0.625039;, + 0.775269;0.711772;, + 0.775669;0.666770;, + 0.776430;0.624558;, + 0.773472;0.669872;, + 0.782015;0.718525;, + 0.776570;0.627422;, + 0.778013;0.664842;, + 0.779315;0.713218;, + 0.789332;0.622118;, + 0.789420;0.664889;, + 0.792645;0.717509;, + 0.786473;0.622338;, + 0.792480;0.716735;, + 0.789424;0.671332;, + 0.789729;0.625677;, + 0.790252;0.715710;, + 0.789600;0.668773;, + 0.791820;0.669964;, + 0.789582;0.625337;, + 0.793545;0.715484;, + 0.788233;0.624304;, + 0.790431;0.718265;, + 0.790284;0.670447;, + 0.785843;0.626007;, + 0.782577;0.667710;, + 0.783500;0.716741;, + 0.790782;0.625718;, + 0.792564;0.716505;, + 0.791922;0.671684;, + 0.794635;0.627982;, + 0.794680;0.715878;, + 0.796221;0.672350;, + 0.788721;0.627413;, + 0.789794;0.670452;, + 0.791182;0.714226;, + 0.790307;0.624378;, + 0.792533;0.671815;, + 0.793801;0.716549;, + 0.784641;0.627340;, + 0.786011;0.670554;, + 0.787199;0.717576;, + 0.790351;0.663633;, + 0.793786;0.630159;, + 0.792190;0.703334;, + 0.795066;0.628478;, + 0.796832;0.714275;, + 0.796356;0.670301;, + 0.791512;0.670914;, + 0.793029;0.706406;, + 0.784249;0.635497;, + 0.771596;0.664582;, + 0.771802;0.630441;, + 0.773771;0.712776;, + 0.788489;0.625167;, + 0.799017;0.715708;, + 0.789250;0.665407;, + 0.796848;0.652952;, + 0.734108;0.683056;, + 0.774251;0.692068;, + 0.799990;0.689774;, + 0.912318;0.790976;, + 0.835605;0.668551;, + 0.834549;0.669792;, + 0.902768;0.883465;, + 0.904724;0.885479;, + 0.902228;0.888187;, + 0.898316;0.888187;, + 0.895821;0.885479;, + 0.897777;0.883465;, + 0.898265;0.798929;, + 0.902280;0.798929;, + 0.904863;0.804096;, + 0.902855;0.809357;, + 0.897690;0.809357;, + 0.895682;0.804096;, + 0.902280;0.790246;, + 0.898265;0.790246;, + 0.902880;0.857875;, + 0.905375;0.862172;, + 0.902768;0.863497;, + 0.897777;0.863497;, + 0.895169;0.862172;, + 0.897665;0.857875;, + 0.897777;0.869929;, + 0.902768;0.869929;, + 0.902768;0.875028;, + 0.897777;0.875028;, + 0.893694;0.933727;, + 0.885232;0.932009;, + 0.892792;0.930218;, + 0.898382;0.930471;, + 0.902162;0.930471;, + 0.907753;0.930218;, + 0.915313;0.932009;, + 0.906851;0.933727;, + 0.906851;0.948663;, + 0.906851;0.952882;, + 0.893694;0.952882;, + 0.893694;0.948663;, + 0.898382;0.921391;, + 0.902162;0.921391;, + 0.902162;0.926208;, + 0.898382;0.926208;, + 0.904359;0.976397;, + 0.908446;0.983814;, + 0.904359;0.987846;, + 0.896186;0.987846;, + 0.892099;0.983814;, + 0.896186;0.976397;, + 0.890317;0.960901;, + 0.887826;0.955517;, + 0.893694;0.954704;, + 0.906851;0.954704;, + 0.912719;0.955517;, + 0.910227;0.960901;, + 0.904359;0.964521;, + 0.896186;0.964521;, + 0.902162;0.914181;, + 0.902162;0.917807;, + 0.898382;0.917807;, + 0.898382;0.914181;, + 0.898382;0.906892;, + 0.895345;0.904106;, + 0.897235;0.900407;, + 0.903310;0.900407;, + 0.905199;0.904106;, + 0.902162;0.906892;, + 0.893278;0.895433;, + 0.893172;0.893912;, + 0.895173;0.891507;, + 0.898316;0.890593;, + 0.902228;0.890593;, + 0.905371;0.891507;, + 0.907373;0.893912;, + 0.907267;0.895433;, + 0.903310;0.896025;, + 0.897235;0.896025;, + 0.809585;0.995319;, + 0.809585;0.995319;, + 0.796174;0.997421;, + 0.680570;0.784109;, + 0.928526;0.597825;, + 0.911482;0.597825;, + 0.707399;0.779975;, + 0.796174;0.997421;, + 0.560395;0.749918;, + 0.553202;0.749918;, + 0.907074;0.649439;, + 0.911482;0.636891;, + 0.928526;0.636891;, + 0.932934;0.649439;, + 0.543036;0.821058;, + 0.553587;0.805318;, + 0.560009;0.805318;, + 0.570560;0.821058;, + 0.896186;0.998590;, + 0.904359;0.998590;, + 0.853099;0.996938;, + 0.853099;0.996938;, + 0.883254;0.975313;, + 0.880549;0.981966;, + 0.868039;0.983920;, + 0.861578;0.975339;, + 0.868286;0.967611;, + 0.877687;0.970762;, + 0.723494;0.934189;, + 0.746615;0.939569;, + 0.750123;0.952141;, + 0.752018;0.752872;, + 0.760772;0.738986;, + 0.765195;0.741466;, + 0.806068;0.843381;, + 0.808596;0.847477;, + 0.810932;0.854328;, + 0.813587;0.861508;, + 0.814928;0.876023;, + 0.811185;0.878414;, + 0.800855;0.868571;, + 0.799856;0.854877;, + 0.699911;0.911896;, + 0.703264;0.913021;, + 0.706468;0.908363;, + 0.706162;0.903342;, + 0.714873;0.897777;, + 0.723917;0.904455;, + 0.716064;0.916632;, + 0.767956;0.739408;, + 0.806619;0.772049;, + 0.820056;0.785642;, + 0.814083;0.790165;, + 0.809808;0.792812;, + 0.806591;0.792094;, + 0.804323;0.784892;, + 0.700241;0.822974;, + 0.693042;0.817639;, + 0.688890;0.819799;, + 0.818973;0.810336;, + 0.819099;0.812192;, + 0.836745;0.213089;, + 0.835593;0.219284;, + 0.816293;0.818786;, + 0.815805;0.820421;, + 0.814192;0.825581;, + 0.811307;0.821517;, + 0.812778;0.808834;, + 0.816886;0.806200;, + 0.878804;0.857303;, + 0.881376;0.861716;, + 0.878829;0.869526;, + 0.875890;0.874631;, + 0.874610;0.876410;, + 0.872738;0.877913;, + 0.872011;0.878691;, + 0.875817;0.878190;, + 0.870373;0.868288;, + 0.874192;0.861851;, + 0.878967;0.896213;, + 0.879498;0.898184;, + 0.884256;0.898560;, + 0.888144;0.899414;, + 0.886178;0.903064;, + 0.880760;0.905962;, + 0.878120;0.900733;, + 0.858925;0.929667;, + 0.857641;0.934125;, + 0.847363;0.935745;, + 0.842772;0.924998;, + 0.848758;0.915479;, + 0.854634;0.921769;, + 0.864692;0.915242;, + 0.870238;0.910052;, + 0.873209;0.915066;, + 0.875924;0.920533;, + 0.868938;0.923141;, + 0.854440;0.942270;, + 0.864958;0.940644;, + 0.873896;0.944310;, + 0.874080;0.948382;, + 0.868064;0.948617;, + 0.857362;0.946171;, + 0.892692;0.920061;, + 0.887110;0.919186;, + 0.884115;0.913800;, + 0.889644;0.911032;, + 0.892703;0.913806;, + 0.892756;0.917449;, + 0.801819;0.909866;, + 0.788935;0.898076;, + 0.796995;0.887735;, + 0.813905;0.896644;, + 0.837738;0.930561;, + 0.842607;0.941175;, + 0.845069;0.945218;, + 0.847347;0.950804;, + 0.841881;0.956079;, + 0.812113;0.950778;, + 0.808814;0.938359;, + 0.825141;0.930378;, + 0.827105;0.920651;, + 0.830349;0.918516;, + 0.890228;0.876990;, + 0.888016;0.878593;, + 0.885001;0.878102;, + 0.883550;0.877809;, + 0.883811;0.876027;, + 0.884569;0.874258;, + 0.887538;0.871524;, + 0.890442;0.871983;, + 0.889999;0.881860;, + 0.892460;0.884911;, + 0.889233;0.885429;, + 0.886009;0.883818;, + 0.886436;0.881270;, + 0.883464;0.873827;, + 0.882424;0.875494;, + 0.880876;0.876215;, + 0.879842;0.875642;, + 0.881287;0.873936;, + 0.862513;0.892170;, + 0.861865;0.879474;, + 0.866388;0.875409;, + 0.873781;0.879035;, + 0.873094;0.883435;, + 0.873229;0.886138;, + 0.874904;0.888885;, + 0.874217;0.893384;, + 0.868208;0.898628;, + 0.871998;0.885239;, + 0.871976;0.882555;, + 0.872387;0.881660;, + 0.872785;0.883681;, + 0.872319;0.885711;, + 0.876354;0.881234;, + 0.875097;0.881843;, + 0.874745;0.879917;, + 0.876504;0.878342;, + 0.877554;0.878922;, + 0.875559;0.894556;, + 0.877148;0.894288;, + 0.881282;0.895325;, + 0.881391;0.896768;, + 0.876803;0.896405;, + 0.872657;0.890011;, + 0.873574;0.892165;, + 0.874760;0.894155;, + 0.874214;0.892318;, + 0.872608;0.889474;, + 0.877867;0.881632;, + 0.877351;0.880920;, + 0.878578;0.878622;, + 0.880091;0.877871;, + 0.879672;0.879604;, + 0.880438;0.882205;, + 0.882153;0.882616;, + 0.881530;0.885276;, + 0.879267;0.886324;, + 0.878742;0.884308;, + 0.882323;0.888704;, + 0.885747;0.890207;, + 0.883744;0.892684;, + 0.879543;0.891763;, + 0.880101;0.889732;, + 0.874627;0.885988;, + 0.875759;0.885288;, + 0.876435;0.886058;, + 0.876968;0.888077;, + 0.876348;0.890096;, + 0.874900;0.890194;, + 0.874116;0.887997;, + 0.885181;0.866347;, + 0.889779;0.863299;, + 0.887402;0.868633;, + 0.884410;0.871352;, + 0.882180;0.871419;, + 0.861419;0.793048;, + 0.856019;0.794881;, + 0.848222;0.791381;, + 0.840650;0.788120;, + 0.868772;0.227338;, + 0.871877;0.218340;, + 0.882605;0.222061;, + 0.884179;0.229250;, + 0.877209;0.231043;, + 0.858143;0.802183;, + 0.858817;0.805122;, + 0.851020;0.801622;, + 0.850346;0.798683;, + 0.841668;0.841308;, + 0.849162;0.841548;, + 0.854411;0.840199;, + 0.855954;0.843593;, + 0.854116;0.848424;, + 0.848984;0.849435;, + 0.841452;0.846086;, + 0.837548;0.841441;, + 0.864295;0.820660;, + 0.867352;0.822653;, + 0.874914;0.824710;, + 0.874712;0.830074;, + 0.868457;0.834824;, + 0.866846;0.831410;, + 0.866617;0.828470;, + 0.900825;0.238070;, + 0.899286;0.230881;, + 0.792524;0.758021;, + 0.705076;0.847899;, + 0.705513;0.842839;, + 0.714572;0.852197;, + 0.709570;0.865796;, + 0.708642;0.862587;, + 0.705810;0.858129;, + 0.704047;0.856128;, + 0.704582;0.853479;, + 0.659696;0.842488;, + 0.656503;0.844340;, + 0.656245;0.853573;, + 0.762387;0.807790;, + 0.769007;0.814582;, + 0.759728;0.829314;, + 0.744754;0.840151;, + 0.735158;0.837187;, + 0.661040;0.868118;, + 0.662092;0.873280;, + 0.667446;0.880470;, + 0.671850;0.884983;, + 0.693052;0.825544;, + 0.688060;0.821769;, + 0.690343;0.819868;, + 0.697497;0.825214;, + 0.697128;0.830256;, + 0.660014;0.869543;, + 0.663290;0.874126;, + 0.667721;0.879178;, + 0.670059;0.882396;, + 0.668880;0.883441;, + 0.665559;0.881576;, + 0.660559;0.874149;, + 0.654537;0.855994;, + 0.653216;0.850818;, + 0.654017;0.841614;, + 0.656962;0.838804;, + 0.656277;0.843395;, + 0.654654;0.851382;, + 0.706763;0.916055;, + 0.704907;0.914299;, + 0.708048;0.909580;, + 0.709904;0.911336;, + 0.673717;0.828513;, + 0.666418;0.834185;, + 0.676727;0.821513;, + 0.674409;0.823336;, + 0.671732;0.825354;, + 0.666087;0.828624;, + 0.662138;0.831262;, + 0.665145;0.829193;, + 0.672670;0.823785;, + 0.686417;0.897062;, + 0.684116;0.895030;, + 0.679361;0.888850;, + 0.680547;0.887802;, + 0.685477;0.891393;, + 0.676015;0.884643;, + 0.678762;0.886893;, + 0.683705;0.892958;, + 0.684863;0.895504;, + 0.680052;0.889403;, + 0.695233;0.914254;, + 0.696896;0.916164;, + 0.693427;0.914360;, + 0.689562;0.910409;, + 0.688484;0.907834;, + 0.690686;0.909875;, + 0.764102;0.734585;, + 0.759679;0.732105;, + 0.683424;0.899463;, + 0.687842;0.905828;, + 0.691611;0.909855;, + 0.807160;0.984871;, + 0.811076;0.992991;, + 0.796303;0.997435;, + 0.727330;0.775774;, + 0.737141;0.770505;, + 0.781718;0.979152;, + 0.853488;0.992247;, + 0.879600;0.995136;, + 0.884085;0.998182;, + 0.853121;0.996991;, + 0.839008;0.997396;, + 0.609087;0.764632;, + 0.608054;0.773833;, + 0.600940;0.751850;, + 0.607154;0.743363;, + 0.885369;0.580065;, + 0.879410;0.592575;, + 0.868069;0.591687;, + 0.617169;0.768622;, + 0.613975;0.756093;, + 0.734130;0.748148;, + 0.723692;0.752707;, + 0.619519;0.824099;, + 0.624525;0.802560;, + 0.864390;0.635775;, + 0.601057;0.823984;, + 0.603096;0.809459;, + 0.615766;0.831442;, + 0.588944;0.744363;, + 0.581349;0.758888;, + 0.571184;0.743148;, + 0.880440;0.641059;, + 0.889476;0.646513;, + 0.773385;0.772241;, + 0.765851;0.784683;, + 0.620152;0.744959;, + 0.749855;0.729434;, + 0.825102;0.801492;, + 0.822392;0.797440;, + 0.828673;0.792745;, + 0.835934;0.796180;, + 0.836558;0.799146;, + 0.832007;0.799764;, + 0.816657;0.843915;, + 0.814437;0.836935;, + 0.817320;0.832012;, + 0.822209;0.837181;, + 0.825497;0.841743;, + 0.822828;0.843553;, + 0.855544;0.831362;, + 0.859143;0.830035;, + 0.861639;0.829097;, + 0.861907;0.832046;, + 0.856590;0.833373;, + 0.878130;0.813309;, + 0.875581;0.819497;, + 0.870798;0.817379;, + 0.867840;0.813108;, + 0.867186;0.810154;, + 0.872694;0.808236;, + 0.851931;0.212439;, + 0.856292;0.215979;, + 0.853159;0.224970;, + 0.847090;0.227705;, + 0.841223;0.221426;, + 0.842931;0.215151;, + 0.859569;0.950864;, + 0.870221;0.953350;, + 0.872713;0.958843;, + 0.862061;0.956357;, + 0.831396;0.804920;, + 0.835696;0.805432;, + 0.831419;0.806932;, + 0.824765;0.808377;, + 0.824615;0.806530;, + 0.850927;0.803168;, + 0.858731;0.806700;, + 0.861498;0.810894;, + 0.858434;0.811439;, + 0.850713;0.807974;, + 0.845972;0.803898;, + 0.822828;0.832534;, + 0.817294;0.827383;, + 0.817703;0.825787;, + 0.822270;0.829261;, + 0.826417;0.832514;, + 0.845619;0.836729;, + 0.838159;0.836479;, + 0.833506;0.833424;, + 0.837442;0.832998;, + 0.844602;0.833326;, + 0.893943;0.238008;, + 0.861501;0.828439;, + 0.859016;0.829365;, + 0.886979;0.239799;, + 0.825506;0.808906;, + 0.832120;0.807468;, + 0.853968;0.203984;, + 0.845126;0.206762;, + 0.887612;0.209226;, + 0.877060;0.205589;, + 0.872370;0.201897;, + 0.845702;0.805354;, + 0.850683;0.808355;, + 0.858295;0.811864;, + 0.844156;0.238056;, + 0.826793;0.828244;, + 0.823281;0.827308;, + 0.819797;0.824826;, + 0.838144;0.231817;, + 0.872906;0.245257;, + 0.848450;0.832215;, + 0.844955;0.832101;, + 0.837770;0.831792;, + 0.858237;0.244246;, + 0.864579;0.241448;, + 0.672033;0.833431;, + 0.677807;0.830377;, + 0.680709;0.830944;, + 0.679630;0.832272;, + 0.675688;0.836035;, + 0.670993;0.837761;, + 0.663100;0.846806;, + 0.666956;0.844848;, + 0.665079;0.848028;, + 0.663611;0.854284;, + 0.662887;0.859062;, + 0.660499;0.854764;, + 0.667818;0.869181;, + 0.667184;0.864531;, + 0.668931;0.867557;, + 0.673075;0.872891;, + 0.672055;0.874351;, + 0.681144;0.879570;, + 0.682419;0.877888;, + 0.685425;0.879351;, + 0.690262;0.881969;, + 0.691271;0.885215;, + 0.688674;0.886066;, + 0.683347;0.882783;, + 0.690935;0.896052;, + 0.693695;0.894958;, + 0.697324;0.896188;, + 0.699246;0.901554;, + 0.696117;0.906264;, + 0.691436;0.901991;, + 0.709604;0.897148;, + 0.707652;0.895403;, + 0.706068;0.890008;, + 0.707265;0.884132;, + 0.708739;0.879243;, + 0.709690;0.882449;, + 0.709279;0.891750;, + 0.698001;0.848790;, + 0.694731;0.848453;, + 0.695212;0.847373;, + 0.694722;0.842825;, + 0.694640;0.838382;, + 0.698400;0.843269;, + 0.683941;0.825341;, + 0.688958;0.829089;, + 0.689393;0.833098;, + 0.687063;0.830490;, + 0.684377;0.828104;, + 0.681690;0.826964;, + 0.694539;0.855245;, + 0.690615;0.856789;, + 0.688785;0.856515;, + 0.689343;0.854694;, + 0.691759;0.852310;, + 0.695125;0.852587;, + 0.695784;0.859438;, + 0.697654;0.861366;, + 0.696067;0.863077;, + 0.694364;0.862584;, + 0.692101;0.862333;, + 0.691934;0.860897;, + 0.701740;0.863271;, + 0.704339;0.867671;, + 0.702837;0.872650;, + 0.700954;0.870057;, + 0.700777;0.866784;, + 0.700061;0.864978;, + 0.696764;0.887057;, + 0.695813;0.883870;, + 0.697109;0.884063;, + 0.699090;0.882660;, + 0.699974;0.879929;, + 0.701745;0.882398;, + 0.700150;0.887901;, + 0.682791;0.865085;, + 0.686164;0.862035;, + 0.687662;0.862175;, + 0.687917;0.863596;, + 0.688128;0.864328;, + 0.687422;0.865453;, + 0.686734;0.866131;, + 0.686434;0.868148;, + 0.683230;0.868455;, + 0.680190;0.857580;, + 0.685190;0.858012;, + 0.684571;0.859844;, + 0.680929;0.862779;, + 0.676758;0.860502;, + 0.672221;0.839192;, + 0.674948;0.836003;, + 0.678899;0.832260;, + 0.681542;0.834280;, + 0.677631;0.838280;, + 0.671368;0.850586;, + 0.669374;0.852969;, + 0.666111;0.855920;, + 0.663889;0.857693;, + 0.662654;0.854286;, + 0.664069;0.848025;, + 0.669448;0.847198;, + 0.675476;0.874545;, + 0.672524;0.872924;, + 0.668080;0.867719;, + 0.670016;0.865994;, + 0.674082;0.868366;, + 0.675098;0.871712;, + 0.684220;0.876796;, + 0.687623;0.876853;, + 0.689145;0.878057;, + 0.690589;0.880286;, + 0.691315;0.882437;, + 0.689607;0.882089;, + 0.684693;0.879534;, + 0.686810;0.844696;, + 0.690521;0.840850;, + 0.692060;0.839733;, + 0.694180;0.842825;, + 0.694638;0.847394;, + 0.688808;0.848147;, + 0.682379;0.829107;, + 0.683790;0.828069;, + 0.686594;0.830238;, + 0.685183;0.831276;, + 0.685882;0.851965;, + 0.691829;0.851125;, + 0.691147;0.852386;, + 0.688693;0.854737;, + 0.683767;0.854326;, + 0.694711;0.863557;, + 0.693094;0.863536;, + 0.690980;0.862835;, + 0.691446;0.862372;, + 0.693808;0.862659;, + 0.700238;0.866960;, + 0.699964;0.868510;, + 0.699518;0.867847;, + 0.698620;0.865539;, + 0.698097;0.864320;, + 0.699268;0.865078;, + 0.697861;0.880863;, + 0.698608;0.882973;, + 0.696609;0.884348;, + 0.695862;0.882238;, + 0.689170;0.871016;, + 0.688397;0.868920;, + 0.689273;0.869881;, + 0.690624;0.871065;, + 0.690629;0.872304;, + 0.694403;0.875504;, + 0.692846;0.873609;, + 0.693085;0.872105;, + 0.693891;0.872222;, + 0.695408;0.872942;, + 0.696159;0.874720;, + 0.698803;0.876854;, + 0.698569;0.874951;, + 0.698109;0.873383;, + 0.698025;0.873732;, + 0.699234;0.872247;, + 0.700303;0.870748;, + 0.699830;0.873806;, + 0.686162;0.868655;, + 0.685702;0.867312;, + 0.685787;0.866385;, + 0.686247;0.867728;, + 0.688933;0.865106;, + 0.690211;0.864034;, + 0.692367;0.864878;, + 0.691761;0.866467;, + 0.689389;0.866404;, + 0.696289;0.866667;, + 0.698091;0.866703;, + 0.698808;0.869151;, + 0.697715;0.870637;, + 0.696397;0.869990;, + 0.695690;0.868468;, + 0.688500;0.870302;, + 0.690574;0.870874;, + 0.691320;0.872191;, + 0.690675;0.872854;, + 0.689815;0.872503;, + 0.688385;0.871268;, + 0.693553;0.873419;, + 0.695096;0.873894;, + 0.695274;0.874506;, + 0.694662;0.874263;, + 0.692990;0.873850;, + 0.698496;0.872792;, + 0.698611;0.873595;, + 0.697475;0.875110;, + 0.697360;0.874307;, + 0.752419;0.911565;, + 0.768600;0.909906;, + 0.781542;0.921746;, + 0.767724;0.929157;, + 0.744573;0.923751;, + 0.783132;0.826576;, + 0.802348;0.807248;, + 0.805375;0.807970;, + 0.804374;0.820607;, + 0.799209;0.833329;, + 0.745404;0.878402;, + 0.752976;0.864062;, + 0.767966;0.853234;, + 0.777948;0.859594;, + 0.778925;0.873285;, + 0.770940;0.883665;, + 0.754637;0.885236;, + 0.723141;0.869933;, + 0.715669;0.884309;, + 0.707286;0.889890;, + 0.708161;0.880536;, + 0.713583;0.866968;, + 0.827892;0.872505;, + 0.834214;0.872050;, + 0.841195;0.877118;, + 0.842540;0.889659;, + 0.836716;0.899163;, + 0.829049;0.887077;, + 0.880758;0.832548;, + 0.880652;0.824610;, + 0.880761;0.819253;, + 0.883634;0.813028;, + 0.888066;0.810723;, + 0.889764;0.816036;, + 0.885281;0.828016;, + 0.897690;0.818794;, + 0.902855;0.818794;, + 0.907566;0.830695;, + 0.904983;0.835183;, + 0.895561;0.835183;, + 0.892979;0.830695;, + 0.897665;0.850874;, + 0.892954;0.852870;, + 0.895561;0.845903;, + 0.904983;0.845903;, + 0.907591;0.852870;, + 0.902880;0.850874;, + 0.892242;0.792424;, + 0.889659;0.797544;, + 0.885280;0.799848;, + 0.879746;0.794853;, + 0.870430;0.855508;, + 0.866426;0.850510;, + 0.868293;0.845675;, + 0.874568;0.840974;, + 0.874367;0.848880;, + 0.864964;0.864889;, + 0.859859;0.861579;, + 0.855510;0.855004;, + 0.860682;0.853995;, + 0.864797;0.859048;, + 0.845572;0.854480;, + 0.849888;0.860753;, + 0.845250;0.864668;, + 0.837521;0.860045;, + 0.834652;0.852847;, + 0.838065;0.851071;, + 0.827484;0.852926;, + 0.830296;0.860081;, + 0.824296;0.860464;, + 0.821483;0.853309;, + 0.917291;0.975313;, + 0.922858;0.970762;, + 0.932259;0.967611;, + 0.861297;0.974650;, + 0.868039;0.983920;, + 0.919995;0.981966;, + 0.631865;0.755748;, + 0.637632;0.767666;, + 0.750123;0.952141;, + 0.746615;0.939569;, + 0.723494;0.934189;, + 0.628816;0.758604;, + 0.800855;0.868571;, + 0.989360;0.878414;, + 0.985617;0.876023;, + 0.986957;0.861508;, + 0.989613;0.854328;, + 0.991949;0.847477;, + 0.994477;0.843381;, + 0.799856;0.854877;, + 0.716064;0.916632;, + 0.723917;0.904455;, + 0.714873;0.897777;, + 0.706162;0.903342;, + 0.706468;0.908363;, + 0.703264;0.913021;, + 0.699911;0.911896;, + 0.625080;0.756874;, + 0.993953;0.792095;, + 0.990736;0.792812;, + 0.986462;0.790165;, + 0.980489;0.785642;, + 0.991540;0.773290;, + 0.804323;0.784892;, + 0.688890;0.819799;, + 0.693042;0.817639;, + 0.700241;0.822974;, + 0.987767;0.808834;, + 0.989237;0.821517;, + 0.986353;0.825581;, + 0.985491;0.820881;, + 0.985003;0.819246;, + 0.905184;0.219462;, + 0.903939;0.213590;, + 0.981445;0.812192;, + 0.981572;0.810336;, + 0.983659;0.806201;, + 0.930171;0.868288;, + 0.925550;0.878190;, + 0.928534;0.878691;, + 0.927806;0.877913;, + 0.925935;0.876410;, + 0.924655;0.874631;, + 0.921715;0.869526;, + 0.919169;0.861716;, + 0.921740;0.857303;, + 0.926353;0.861851;, + 0.919785;0.905962;, + 0.914367;0.903064;, + 0.912401;0.899414;, + 0.916289;0.898560;, + 0.921047;0.898184;, + 0.921578;0.896213;, + 0.922425;0.900733;, + 0.951787;0.915479;, + 0.957773;0.924998;, + 0.953182;0.935745;, + 0.942904;0.934125;, + 0.941619;0.929668;, + 0.945911;0.921769;, + 0.935853;0.915242;, + 0.931607;0.923141;, + 0.924621;0.920533;, + 0.927335;0.915066;, + 0.930306;0.910052;, + 0.932480;0.948617;, + 0.926465;0.948382;, + 0.926648;0.944310;, + 0.935587;0.940644;, + 0.946105;0.942270;, + 0.943182;0.946171;, + 0.907853;0.920061;, + 0.907789;0.917449;, + 0.907842;0.913806;, + 0.910900;0.911032;, + 0.916429;0.913800;, + 0.913434;0.919187;, + 0.801819;0.909866;, + 0.986639;0.896644;, + 0.796995;0.887735;, + 0.788935;0.898076;, + 0.973440;0.920651;, + 0.825141;0.930378;, + 0.808814;0.938359;, + 0.812113;0.950778;, + 0.841881;0.956079;, + 0.953198;0.950804;, + 0.955475;0.945218;, + 0.957938;0.941175;, + 0.962807;0.930561;, + 0.970195;0.918516;, + 0.910316;0.876990;, + 0.910102;0.871983;, + 0.913007;0.871524;, + 0.915975;0.874258;, + 0.916734;0.876027;, + 0.916994;0.877809;, + 0.915543;0.878102;, + 0.912529;0.878593;, + 0.910545;0.881860;, + 0.914109;0.881270;, + 0.914535;0.883818;, + 0.911312;0.885429;, + 0.908085;0.884911;, + 0.920703;0.875642;, + 0.919669;0.876215;, + 0.918121;0.875494;, + 0.917081;0.873827;, + 0.919258;0.873936;, + 0.926327;0.893384;, + 0.925641;0.888885;, + 0.927316;0.886138;, + 0.927450;0.883435;, + 0.926763;0.879035;, + 0.934157;0.875138;, + 0.938680;0.879474;, + 0.938032;0.892170;, + 0.932337;0.898628;, + 0.927759;0.883681;, + 0.928158;0.881660;, + 0.928568;0.882555;, + 0.928547;0.885239;, + 0.928226;0.885711;, + 0.924191;0.881234;, + 0.922991;0.878922;, + 0.924041;0.878342;, + 0.925799;0.879917;, + 0.925448;0.881843;, + 0.924985;0.894556;, + 0.923742;0.896405;, + 0.919153;0.896768;, + 0.919262;0.895325;, + 0.923396;0.894288;, + 0.927887;0.890011;, + 0.927937;0.889474;, + 0.926330;0.892318;, + 0.925785;0.894155;, + 0.926971;0.892165;, + 0.922678;0.881632;, + 0.920873;0.879604;, + 0.920453;0.877871;, + 0.921967;0.878622;, + 0.923194;0.880920;, + 0.921278;0.886324;, + 0.919014;0.885276;, + 0.918391;0.882616;, + 0.920106;0.882205;, + 0.921802;0.884308;, + 0.921002;0.891763;, + 0.916801;0.892684;, + 0.914798;0.890207;, + 0.918222;0.888704;, + 0.920444;0.889732;, + 0.925645;0.890194;, + 0.924197;0.890096;, + 0.923576;0.888077;, + 0.924110;0.886058;, + 0.924786;0.885288;, + 0.925917;0.885988;, + 0.926428;0.887997;, + 0.916135;0.871352;, + 0.913143;0.868633;, + 0.910766;0.863299;, + 0.915364;0.866347;, + 0.918364;0.871419;, + 0.939125;0.793048;, + 0.959895;0.788120;, + 0.952322;0.791381;, + 0.944526;0.794881;, + 0.852650;0.228909;, + 0.854352;0.222094;, + 0.865952;0.218567;, + 0.869308;0.227096;, + 0.860187;0.230609;, + 0.942402;0.802183;, + 0.950198;0.798683;, + 0.949524;0.801622;, + 0.941728;0.805122;, + 0.959092;0.846086;, + 0.951561;0.849435;, + 0.946429;0.848424;, + 0.944591;0.843593;, + 0.946133;0.840199;, + 0.951383;0.841548;, + 0.958877;0.841308;, + 0.962996;0.841441;, + 0.933526;0.820660;, + 0.836316;0.230455;, + 0.834651;0.237269;, + 0.931203;0.828470;, + 0.933698;0.831410;, + 0.932088;0.834824;, + 0.925832;0.830074;, + 0.925630;0.824710;, + 0.930468;0.822653;, + 0.792524;0.758021;, + 0.705076;0.847899;, + 0.704582;0.853479;, + 0.704047;0.856128;, + 0.705810;0.858129;, + 0.708642;0.862587;, + 0.709570;0.865796;, + 0.714572;0.852197;, + 0.705513;0.842839;, + 0.656503;0.844340;, + 0.659696;0.842488;, + 0.658583;0.844044;, + 0.656245;0.853573;, + 0.762387;0.807790;, + 0.735158;0.837187;, + 0.744754;0.840151;, + 0.759728;0.829314;, + 0.769007;0.814582;, + 0.671850;0.884983;, + 0.667446;0.880470;, + 0.662092;0.873280;, + 0.661040;0.868118;, + 0.697497;0.825214;, + 0.690343;0.819868;, + 0.688060;0.821769;, + 0.693052;0.825544;, + 0.697128;0.830256;, + 0.660014;0.869543;, + 0.660559;0.874149;, + 0.665559;0.881576;, + 0.668880;0.883441;, + 0.670059;0.882396;, + 0.667721;0.879178;, + 0.663290;0.874126;, + 0.656277;0.843395;, + 0.656962;0.838804;, + 0.654017;0.841614;, + 0.653216;0.850818;, + 0.654537;0.855994;, + 0.654654;0.851382;, + 0.708048;0.909580;, + 0.704907;0.914299;, + 0.706763;0.916055;, + 0.709904;0.911336;, + 0.665306;0.835742;, + 0.666418;0.834185;, + 0.673717;0.828513;, + 0.676727;0.821513;, + 0.672670;0.823785;, + 0.665146;0.829193;, + 0.662138;0.831262;, + 0.666087;0.828624;, + 0.671732;0.825354;, + 0.674409;0.823336;, + 0.686417;0.897062;, + 0.685477;0.891393;, + 0.680547;0.887802;, + 0.679361;0.888850;, + 0.684116;0.895030;, + 0.676015;0.884643;, + 0.680052;0.889403;, + 0.684863;0.895504;, + 0.683705;0.892958;, + 0.678762;0.886893;, + 0.688484;0.907834;, + 0.689562;0.910409;, + 0.693427;0.914360;, + 0.696896;0.916164;, + 0.695233;0.914254;, + 0.690686;0.909875;, + 0.626382;0.751791;, + 0.691611;0.909855;, + 0.687843;0.905828;, + 0.683424;0.899463;, + 0.629431;0.748934;, + 0.649842;0.784379;, + 0.661634;0.789005;, + 0.796303;0.997435;, + 0.811076;0.992991;, + 0.807160;0.984871;, + 0.781718;0.979152;, + 0.853121;0.996991;, + 0.916460;0.998182;, + 0.920944;0.995136;, + 0.853488;0.992247;, + 0.839008;0.997396;, + 0.501649;0.767269;, + 0.502150;0.750869;, + 0.512657;0.751850;, + 0.505542;0.773833;, + 0.652023;0.759221;, + 0.496782;0.758581;, + 0.495945;0.774158;, + 0.973029;0.592354;, + 0.962233;0.596576;, + 0.954638;0.582066;, + 0.663138;0.761836;, + 0.975073;0.631107;, + 0.491802;0.807701;, + 0.493658;0.821015;, + 0.497831;0.831442;, + 0.510501;0.809459;, + 0.512540;0.823984;, + 0.524652;0.744363;, + 0.542413;0.743148;, + 0.532247;0.758888;, + 0.949442;0.647846;, + 0.958479;0.641726;, + 0.773385;0.772241;, + 0.765851;0.784683;, + 0.660818;0.835561;, + 0.637646;0.745354;, + 0.493444;0.744959;, + 0.963987;0.799146;, + 0.964611;0.796180;, + 0.971871;0.792745;, + 0.978153;0.797440;, + 0.975442;0.801492;, + 0.968537;0.799764;, + 0.983888;0.843915;, + 0.977716;0.843553;, + 0.975048;0.841743;, + 0.978336;0.837181;, + 0.983225;0.832012;, + 0.986108;0.836936;, + 0.938638;0.832046;, + 0.936181;0.829097;, + 0.941401;0.830035;, + 0.945000;0.831362;, + 0.943954;0.833373;, + 0.933359;0.810154;, + 0.932705;0.813108;, + 0.929746;0.817379;, + 0.924964;0.819497;, + 0.922414;0.813309;, + 0.927851;0.808236;, + 0.899096;0.221492;, + 0.892752;0.227445;, + 0.886190;0.224852;, + 0.882803;0.216330;, + 0.887518;0.212975;, + 0.897249;0.215545;, + 0.940975;0.950864;, + 0.938484;0.956357;, + 0.927832;0.958843;, + 0.930323;0.953350;, + 0.969148;0.804920;, + 0.975929;0.806530;, + 0.975779;0.808377;, + 0.969125;0.806932;, + 0.964660;0.806467;, + 0.949832;0.807745;, + 0.942110;0.811209;, + 0.939047;0.810894;, + 0.941813;0.806700;, + 0.949618;0.803168;, + 0.954573;0.803898;, + 0.977716;0.832534;, + 0.974127;0.832514;, + 0.978275;0.829261;, + 0.982842;0.825787;, + 0.983251;0.827383;, + 0.954926;0.836729;, + 0.955943;0.833556;, + 0.963103;0.833228;, + 0.967039;0.832274;, + 0.962386;0.836479;, + 0.941529;0.829365;, + 0.936319;0.828439;, + 0.842092;0.237210;, + 0.849622;0.238907;, + 0.885316;0.204961;, + 0.968425;0.807468;, + 0.975039;0.808906;, + 0.894876;0.207594;, + 0.949861;0.808125;, + 0.954654;0.806389;, + 0.865418;0.202982;, + 0.860347;0.206482;, + 0.848938;0.209929;, + 0.942250;0.811634;, + 0.981687;0.824251;, + 0.977264;0.826044;, + 0.973752;0.827899;, + 0.895925;0.237256;, + 0.902426;0.231342;, + 0.864838;0.244081;, + 0.873842;0.240471;, + 0.880699;0.243123;, + 0.962774;0.831447;, + 0.955589;0.832331;, + 0.952095;0.832215;, + 0.675688;0.836035;, + 0.679630;0.832272;, + 0.680709;0.830944;, + 0.677807;0.830377;, + 0.672033;0.833431;, + 0.670993;0.837761;, + 0.662887;0.859062;, + 0.663611;0.854284;, + 0.665079;0.848028;, + 0.666956;0.844848;, + 0.663100;0.846806;, + 0.660499;0.854764;, + 0.673075;0.872891;, + 0.668931;0.867557;, + 0.667184;0.864531;, + 0.667818;0.869181;, + 0.672055;0.874351;, + 0.681144;0.879570;, + 0.683347;0.882783;, + 0.688674;0.886066;, + 0.691271;0.885215;, + 0.690262;0.881969;, + 0.685425;0.879351;, + 0.682419;0.877888;, + 0.696117;0.906264;, + 0.699246;0.901554;, + 0.697324;0.896188;, + 0.693695;0.894958;, + 0.690935;0.896052;, + 0.691436;0.901991;, + 0.709604;0.897148;, + 0.709279;0.891750;, + 0.709690;0.882449;, + 0.708739;0.879243;, + 0.707265;0.884132;, + 0.706068;0.890008;, + 0.707652;0.895403;, + 0.694640;0.838382;, + 0.694722;0.842825;, + 0.695212;0.847373;, + 0.694731;0.848453;, + 0.698001;0.848790;, + 0.698400;0.843269;, + 0.683941;0.825341;, + 0.681690;0.826964;, + 0.684378;0.828104;, + 0.687063;0.830490;, + 0.689393;0.833098;, + 0.688958;0.829089;, + 0.691759;0.852310;, + 0.689343;0.854694;, + 0.688785;0.856515;, + 0.690615;0.856789;, + 0.694539;0.855245;, + 0.695125;0.852587;, + 0.695784;0.859438;, + 0.691934;0.860897;, + 0.692101;0.862333;, + 0.694364;0.862584;, + 0.696067;0.863077;, + 0.697654;0.861366;, + 0.701740;0.863271;, + 0.700061;0.864978;, + 0.700778;0.866784;, + 0.700954;0.870057;, + 0.702837;0.872650;, + 0.704339;0.867671;, + 0.696764;0.887057;, + 0.700150;0.887901;, + 0.701745;0.882398;, + 0.699974;0.879929;, + 0.699090;0.882660;, + 0.697109;0.884063;, + 0.695813;0.883870;, + 0.686434;0.868148;, + 0.686734;0.866131;, + 0.687422;0.865453;, + 0.688128;0.864328;, + 0.687917;0.863596;, + 0.687662;0.862175;, + 0.686164;0.862035;, + 0.682791;0.865085;, + 0.683230;0.868455;, + 0.680190;0.857580;, + 0.676758;0.860502;, + 0.680929;0.862779;, + 0.684571;0.859844;, + 0.685190;0.858012;, + 0.681542;0.834280;, + 0.678899;0.832260;, + 0.674948;0.836003;, + 0.672221;0.839192;, + 0.677631;0.838280;, + 0.664069;0.848025;, + 0.662654;0.854286;, + 0.663889;0.857693;, + 0.666111;0.855920;, + 0.669374;0.852969;, + 0.671369;0.850586;, + 0.669448;0.847198;, + 0.674082;0.868366;, + 0.670016;0.865994;, + 0.668080;0.867719;, + 0.672524;0.872924;, + 0.675476;0.874545;, + 0.675098;0.871712;, + 0.684220;0.876796;, + 0.684693;0.879534;, + 0.689607;0.882089;, + 0.691315;0.882437;, + 0.690589;0.880286;, + 0.689145;0.878057;, + 0.687623;0.876853;, + 0.686810;0.844696;, + 0.688808;0.848147;, + 0.694638;0.847394;, + 0.694180;0.842825;, + 0.692061;0.839733;, + 0.690521;0.840850;, + 0.686594;0.830238;, + 0.683790;0.828069;, + 0.682379;0.829107;, + 0.685183;0.831276;, + 0.688693;0.854737;, + 0.691147;0.852386;, + 0.691829;0.851125;, + 0.685882;0.851965;, + 0.683767;0.854326;, + 0.691446;0.862372;, + 0.690980;0.862835;, + 0.693094;0.863536;, + 0.694711;0.863557;, + 0.693808;0.862659;, + 0.698097;0.864320;, + 0.698620;0.865539;, + 0.699518;0.867847;, + 0.699965;0.868510;, + 0.700238;0.866960;, + 0.699268;0.865078;, + 0.696609;0.884348;, + 0.698608;0.882973;, + 0.697861;0.880863;, + 0.695862;0.882238;, + 0.690624;0.871065;, + 0.689273;0.869881;, + 0.688397;0.868920;, + 0.689170;0.871016;, + 0.690629;0.872304;, + 0.694403;0.875504;, + 0.696159;0.874720;, + 0.695408;0.872942;, + 0.693891;0.872222;, + 0.693085;0.872105;, + 0.692846;0.873609;, + 0.698803;0.876854;, + 0.699830;0.873806;, + 0.700303;0.870748;, + 0.699234;0.872247;, + 0.698025;0.873732;, + 0.698109;0.873383;, + 0.698569;0.874951;, + 0.685787;0.866385;, + 0.685702;0.867312;, + 0.686162;0.868655;, + 0.686247;0.867728;, + 0.691761;0.866467;, + 0.692367;0.864878;, + 0.690211;0.864034;, + 0.688933;0.865106;, + 0.689389;0.866404;, + 0.696397;0.869990;, + 0.697715;0.870637;, + 0.698808;0.869151;, + 0.698091;0.866703;, + 0.696289;0.866667;, + 0.695690;0.868468;, + 0.688500;0.870302;, + 0.688385;0.871268;, + 0.689815;0.872503;, + 0.690675;0.872854;, + 0.691320;0.872191;, + 0.690574;0.870874;, + 0.693553;0.873419;, + 0.692990;0.873850;, + 0.694662;0.874263;, + 0.695274;0.874506;, + 0.695096;0.873894;, + 0.697475;0.875110;, + 0.698611;0.873595;, + 0.698496;0.872792;, + 0.697360;0.874307;, + 0.752419;0.911565;, + 0.744573;0.923751;, + 0.767724;0.929157;, + 0.781542;0.921746;, + 0.768600;0.909906;, + 0.996171;0.820607;, + 0.995169;0.807970;, + 0.799319;0.811168;, + 0.783132;0.826576;, + 0.798927;0.833329;, + 0.770940;0.883665;, + 0.778925;0.873285;, + 0.777948;0.859594;, + 0.767966;0.853234;, + 0.752976;0.864062;, + 0.745404;0.878402;, + 0.754637;0.885236;, + 0.723141;0.869933;, + 0.713583;0.866968;, + 0.708161;0.880536;, + 0.707286;0.889890;, + 0.715669;0.884309;, + 0.963829;0.899163;, + 0.958004;0.889659;, + 0.959349;0.877118;, + 0.966330;0.872050;, + 0.972653;0.872505;, + 0.971496;0.887077;, + 0.919787;0.832548;, + 0.915263;0.828016;, + 0.910781;0.816036;, + 0.912479;0.810723;, + 0.916910;0.813028;, + 0.919784;0.819253;, + 0.919893;0.824610;, + 0.915265;0.799848;, + 0.910885;0.797544;, + 0.908303;0.792424;, + 0.920798;0.794853;, + 0.925977;0.840974;, + 0.932251;0.845675;, + 0.934119;0.850510;, + 0.930114;0.855508;, + 0.926178;0.848880;, + 0.939862;0.853995;, + 0.945035;0.855004;, + 0.940686;0.861579;, + 0.935580;0.864889;, + 0.935748;0.859048;, + 0.965893;0.852847;, + 0.963024;0.860045;, + 0.955294;0.864668;, + 0.950657;0.860753;, + 0.954972;0.854480;, + 0.962479;0.851071;, + 0.976248;0.860464;, + 0.970248;0.860081;, + 0.973061;0.852926;, + 0.979061;0.853309;, + 0.050851;0.311418;, + 0.182352;0.311622;, + 0.552046;0.238197;, + 0.452719;0.187398;, + 0.438080;0.117554;, + 0.452085;0.122919;, + 0.055836;0.106868;, + 0.772088;0.251618;, + 0.356021;0.264969;, + 0.058251;0.140019;, + 0.013018;0.143812;, + 0.008445;0.097857;, + 0.017286;0.142213;, + 0.466090;0.125759;, + 0.032290;0.226805;, + 0.439368;0.396962;, + 0.028011;0.255177;, + 0.015083;0.184547;, + 0.003633;0.442765;, + 0.028225;0.366884;, + 0.008025;0.366913;, + 0.031155;0.442733;, + 0.035522;0.366908;, + 0.043503;0.366901;, + 0.078333;0.442781;, + 0.077972;0.366951;, + 0.063824;0.366910;, + 0.050581;0.366921;, + 0.116059;0.442822;, + 0.095599;0.366990;, + 0.003503;0.366840;, + 0.598234;0.316550;, + 0.550018;0.316218;, + 0.473892;0.274536;, + 0.441097;0.248866;, + 0.464459;0.326135;, + 0.538350;0.016111;, + 0.514084;0.033957;, + 0.489390;0.113365;, + 0.519113;0.138636;, + 0.490572;0.068422;, + 0.356021;0.325248;, + 0.555413;0.007122;, + 0.817949;0.096034;, + 0.787844;0.203452;, + 0.760901;0.200278;, + 0.794989;0.036951;, + 0.779378;0.059111;, + 0.766486;0.099552;, + 0.759845;0.138679;, + 0.814666;0.026300;, + 0.867984;0.019847;, + 0.832914;0.017848;, + 0.809118;0.135273;, + 0.805604;0.154688;, + 0.804978;0.157227;, + 0.758809;0.175095;, + 0.752513;0.157925;, + 0.781961;0.152723;, + 0.858184;0.093448;, + 0.831251;0.093463;, + 0.832409;0.120566;, + 0.848059;0.120499;, + 0.904949;0.121045;, + 0.904197;0.093746;, + 0.888889;0.093489;, + 0.278833;0.117554;, + 0.264828;0.122919;, + 0.181994;0.106868;, + 0.963886;0.251618;, + 0.179579;0.140019;, + 0.224812;0.143812;, + 0.220544;0.142213;, + 0.229385;0.097857;, + 0.272671;0.396962;, + 0.273453;0.408674;, + 0.209561;0.254798;, + 0.222747;0.184547;, + 0.231654;0.442713;, + 0.228618;0.366834;, + 0.207062;0.366884;, + 0.207750;0.442759;, + 0.197052;0.366829;, + 0.186357;0.366849;, + 0.156410;0.366951;, + 0.159214;0.442781;, + 0.168750;0.366884;, + 0.178828;0.366842;, + 0.136070;0.366990;, + 0.233592;0.366893;, + 0.598234;0.316550;, + 0.550018;0.316218;, + 0.238147;0.274536;, + 0.250823;0.125759;, + 0.275815;0.248866;, + 0.247580;0.326135;, + 0.538350;0.016111;, + 0.514084;0.033957;, + 0.489390;0.113365;, + 0.519113;0.138636;, + 0.490572;0.068422;, + 0.555413;0.007122;, + 0.948111;0.206039;, + 0.975073;0.200278;, + 0.940985;0.036951;, + 0.956597;0.059111;, + 0.969488;0.099552;, + 0.976129;0.138679;, + 0.921308;0.026300;, + 0.903060;0.017848;, + 0.926856;0.135273;, + 0.930370;0.157275;, + 0.930970;0.159128;, + 0.977165;0.175095;, + 0.983462;0.157925;, + 0.954013;0.152723;, + 0.858184;0.093448;, + 0.831251;0.093463;, + 0.832568;0.120761;, + 0.848059;0.120499;, + 0.904949;0.121045;, + 0.904197;0.093746;, + 0.888889;0.093489;, + 0.045297;0.477254;, + 0.024699;0.503835;, + 0.472594;0.539949;, + 0.472914;0.716324;, + 0.371776;0.675528;, + 0.373235;0.731889;, + 0.767119;0.421877;, + 0.727042;0.422032;, + 0.723334;0.470792;, + 0.740205;0.473323;, + 0.768616;0.475082;, + 0.820577;0.474485;, + 0.854839;0.474108;, + 0.857896;0.333084;, + 0.840158;0.333502;, + 0.826868;0.333518;, + 0.774925;0.333534;, + 0.746447;0.334508;, + 0.725798;0.335439;, + 0.718712;0.379084;, + 0.718703;0.421715;, + 0.726481;0.378657;, + 0.834362;0.474339;, + 0.100154;0.969885;, + 0.402711;0.957700;, + 0.481941;0.958396;, + 0.471098;0.942456;, + 0.106806;0.943084;, + 0.367369;0.618403;, + 0.362779;0.569244;, + 0.390556;0.922382;, + 0.481380;0.922948;, + 0.108160;0.830961;, + 0.474937;0.574217;, + 0.374591;0.772968;, + 0.770613;0.378738;, + 0.779658;0.375290;, + 0.468376;0.968225;, + 0.781318;0.421781;, + 0.864584;0.336319;, + 0.862721;0.473397;, + 0.861507;0.384730;, + 0.035279;0.972096;, + 0.046114;0.971274;, + 0.056515;0.976507;, + 0.058788;0.985534;, + 0.424365;0.990067;, + 0.424369;0.986643;, + 0.023807;0.986947;, + 0.025789;0.981161;, + 0.430561;0.982980;, + 0.436946;0.984040;, + 0.053072;0.973154;, + 0.026698;0.979844;, + 0.028129;0.977147;, + 0.442206;0.984188;, + 0.449680;0.985484;, + 0.059185;0.989086;, + 0.453487;0.988306;, + 0.456226;0.990546;, + 0.425617;0.991500;, + 0.371983;0.697920;, + 0.020286;0.699408;, + 0.817399;0.610136;, + 0.829895;0.574015;, + 0.829308;0.486167;, + 0.790539;0.483740;, + 0.831696;0.541216;, + 0.782813;0.613566;, + 0.720868;0.507940;, + 0.721642;0.571367;, + 0.755114;0.484599;, + 0.726396;0.484711;, + 0.749582;0.616531;, + 0.722723;0.608105;, + 0.829070;0.386901;, + 0.826063;0.425306;, + 0.002135;0.449795;, + 0.002967;0.471277;, + 0.096325;0.470207;, + 0.388540;0.470853;, + 0.410191;0.471018;, + 0.426962;0.471210;, + 0.028854;0.470922;, + 0.046416;0.470827;, + 0.441986;0.471377;, + 0.008914;0.470973;, + 0.078325;0.470594;, + 0.411197;0.444817;, + 0.359856;0.444726;, + 0.096730;0.448878;, + 0.045771;0.449319;, + 0.440173;0.445252;, + 0.007387;0.449871;, + 0.848952;0.391126;, + 0.835216;0.391122;, + 0.835524;0.392360;, + 0.835512;0.416900;, + 0.848943;0.416867;, + 0.104771;0.476750;, + 0.114079;0.496443;, + 0.114079;0.543468;, + 0.114079;0.543305;, + 0.107353;0.876654;, + 0.008722;0.875832;, + 0.010738;0.826008;, + 0.011091;0.767026;, + 0.109612;0.782815;, + 0.107819;0.799273;, + 0.373464;0.753821;, + 0.475894;0.744141;, + 0.362779;0.477059;, + 0.205339;0.504702;, + 0.184741;0.478121;, + 0.253357;0.539949;, + 0.254211;0.717753;, + 0.356515;0.676004;, + 0.353890;0.730460;, + 0.766924;0.421998;, + 0.726846;0.422153;, + 0.723334;0.470792;, + 0.740205;0.473323;, + 0.768616;0.475082;, + 0.820577;0.474485;, + 0.854839;0.474108;, + 0.857896;0.333084;, + 0.840158;0.333502;, + 0.826868;0.333518;, + 0.774925;0.333534;, + 0.746447;0.334508;, + 0.725798;0.335439;, + 0.718516;0.379205;, + 0.718508;0.421836;, + 0.726286;0.378778;, + 0.834362;0.474339;, + 0.141709;0.974550;, + 0.343835;0.965103;, + 0.248247;0.942456;, + 0.247517;0.958396;, + 0.133854;0.941784;, + 0.359367;0.618403;, + 0.346186;0.924812;, + 0.248079;0.922472;, + 0.129246;0.830609;, + 0.251014;0.574217;, + 0.352797;0.772717;, + 0.770418;0.378859;, + 0.779658;0.375290;, + 0.247079;0.968701;, + 0.864584;0.336319;, + 0.862721;0.473397;, + 0.861507;0.384730;, + 0.200708;0.973327;, + 0.188454;0.972288;, + 0.174861;0.978172;, + 0.170105;0.984594;, + 0.301203;0.990067;, + 0.301200;0.986643;, + 0.210406;0.987744;, + 0.209311;0.981523;, + 0.295008;0.982980;, + 0.288623;0.984040;, + 0.179545;0.975036;, + 0.208402;0.980206;, + 0.206971;0.977509;, + 0.283363;0.984188;, + 0.275889;0.985484;, + 0.169707;0.988147;, + 0.272081;0.988306;, + 0.269343;0.990546;, + 0.299951;0.991500;, + 0.357865;0.698872;, + 0.220267;0.695386;, + 0.817399;0.610136;, + 0.829895;0.574015;, + 0.829308;0.486167;, + 0.790539;0.483740;, + 0.831696;0.541216;, + 0.782813;0.613566;, + 0.720868;0.507940;, + 0.727230;0.571709;, + 0.755114;0.484599;, + 0.726396;0.484711;, + 0.749582;0.616531;, + 0.728311;0.605711;, + 0.829070;0.386901;, + 0.826063;0.425306;, + 0.789675;0.422317;, + 0.231551;0.471277;, + 0.232384;0.449795;, + 0.128399;0.470207;, + 0.333617;0.470853;, + 0.311966;0.471018;, + 0.295195;0.471210;, + 0.200322;0.470922;, + 0.182760;0.470827;, + 0.280654;0.471377;, + 0.225604;0.470973;, + 0.150851;0.470594;, + 0.313395;0.444893;, + 0.127994;0.448878;, + 0.182429;0.449339;, + 0.281452;0.444727;, + 0.227179;0.449362;, + 0.860812;0.392349;, + 0.861813;0.391103;, + 0.860809;0.416900;, + 0.123959;0.476750;, + 0.130619;0.875688;, + 0.223746;0.876529;, + 0.222682;0.831192;, + 0.222175;0.766782;, + 0.126664;0.781896;, + 0.127108;0.799289;, + 0.355244;0.754385;, + 0.253953;0.745093;, + 0.984741;0.646982;, + 0.615535;0.336575;, + 0.617993;0.370708;, + 0.618503;0.412274;, + 0.683406;0.333879;, + 0.617258;0.334147;, + 0.616727;0.478604;, + 0.486881;0.506343;, + 0.486377;0.522763;, + 0.619069;0.508845;, + 0.619014;0.529288;, + 0.613523;0.537819;, + 0.715761;0.536843;, + 0.698826;0.480362;, + 0.715249;0.479745;, + 0.524207;0.480304;, + 0.577151;0.481311;, + 0.614315;0.481181;, + 0.636157;0.481064;, + 0.652311;0.481307;, + 0.679859;0.480379;, + 0.490306;0.480268;, + 0.482948;0.479671;, + 0.482987;0.487223;, + 0.619378;0.479998;, + 0.618557;0.486635;, + 0.485819;0.480718;, + 0.559587;0.542715;, + 0.647989;0.541297;, + 0.637666;0.713938;, + 0.691713;0.542696;, + 0.668214;0.542030;, + 0.701857;0.714699;, + 0.712881;0.541485;, + 0.622792;0.540665;, + 0.526962;0.540637;, + 0.509701;0.540747;, + 0.715962;0.581565;, + 0.613254;0.657234;, + 0.506449;0.658654;, + 0.590872;0.585541;, + 0.576642;0.545365;, + 0.542761;0.538309;, + 0.485178;0.411726;, + 0.565621;0.335995;, + 0.536916;0.335282;, + 0.594197;0.337971;, + 0.879880;0.266471;, + 0.896585;0.266970;, + 0.981714;0.549754;, + 0.959173;0.550152;, + 0.993412;0.532121;, + 0.911361;0.265679;, + 0.944930;0.548958;, + 0.991594;0.515601;, + 0.987964;0.504932;, + 0.874609;0.301468;, + 0.881797;0.290567;, + 0.987964;0.504932;, + 0.923442;0.290776;, + 0.894704;0.289223;, + 0.988993;0.482104;, + 0.941215;0.509530;, + 0.928011;0.304107;, + 0.938862;0.340611;, + 0.928965;0.335341;, + 0.935938;0.471280;, + 0.916356;0.483920;, + 0.953678;0.337149;, + 0.927180;0.460289;, + 0.952654;0.353364;, + 1.000000;1.000000;, + 1.000000;1.000000;, + 0.922355;0.455126;, + 0.921067;0.451440;, + 0.954272;0.363662;, + 0.914584;0.447588;, + 0.872693;0.373015;, + 0.933280;0.438169;, + 0.932123;0.444577;, + 0.945306;0.436670;, + 0.947010;0.442402;, + 0.934191;0.432159;, + 0.943779;0.430962;, + 0.934464;0.427238;, + 0.944140;0.426029;, + 0.933322;0.423342;, + 0.945347;0.421842;, + 0.933852;0.417199;, + 0.944784;0.415835;, + 0.935261;0.412166;, + 0.943440;0.411143;, + 0.934807;0.408303;, + 0.944128;0.407138;, + 0.933499;0.405627;, + 0.945523;0.404125;, + 0.934306;0.399900;, + 0.944760;0.398593;, + 0.936197;0.395479;, + 0.942312;0.394711;, + 0.938126;0.393378;, + 0.940188;0.393119;, + 0.948663;0.433609;, + 0.962449;0.431891;, + 0.963569;0.439852;, + 0.949712;0.425444;, + 0.960702;0.424073;, + 0.950027;0.418771;, + 0.961120;0.417385;, + 0.948720;0.413426;, + 0.962506;0.411706;, + 0.949332;0.405039;, + 0.961865;0.403475;, + 0.950951;0.398224;, + 0.960328;0.397052;, + 0.950433;0.392937;, + 0.961118;0.391601;, + 0.948935;0.389236;, + 0.962720;0.387514;, + 0.949864;0.381423;, + 0.961849;0.379924;, + 0.952035;0.375474;, + 0.959045;0.374594;, + 0.954248;0.372686;, + 0.956611;0.372389;, + 0.964836;0.431793;, + 0.978209;0.430202;, + 0.979243;0.437677;, + 0.965950;0.424289;, + 0.976611;0.423020;, + 0.966334;0.418150;, + 0.977095;0.416868;, + 0.965133;0.413242;, + 0.978506;0.411649;, + 0.965829;0.405541;, + 0.977985;0.404094;, + 0.967479;0.399276;, + 0.976574;0.398191;, + 0.967041;0.394421;, + 0.977406;0.393185;, + 0.965636;0.391026;, + 0.979007;0.389433;, + 0.966632;0.383854;, + 0.978257;0.382466;, + 0.968804;0.378379;, + 0.975604;0.377565;, + 0.970980;0.375810;, + 0.973272;0.375535;, + 0.980527;0.431609;, + 0.991780;0.430872;, + 0.981826;0.426089;, + 0.990797;0.425501;, + 0.982442;0.421548;, + 0.991496;0.420953;, + 0.981680;0.417876;, + 0.992932;0.417138;, + 0.982647;0.412208;, + 0.992876;0.411538;, + 0.984331;0.407622;, + 0.991985;0.407118;, + 0.984207;0.404017;, + 0.992928;0.403443;, + 0.983205;0.401464;, + 0.994456;0.400724;, + 0.873351;0.415244;, + 0.984397;0.396197;, + 0.870746;0.415440;, + 0.986474;0.392206;, + 0.992196;0.391827;, + 0.988412;0.390367;, + 0.990341;0.390239;, + 0.933195;0.460832;, + 0.929516;0.270184;, + 0.960279;0.517513;, + 0.941215;0.509530;, + 0.935596;0.521485;, + 0.873524;0.323161;, + 0.715286;0.395988;, + 0.499149;0.337032;, + 0.484789;0.334008;, + 0.714967;0.334006;, + 0.616154;0.336767;, + 0.618732;0.413149;, + 0.618222;0.371582;, + 0.645009;0.344914;, + 0.684073;0.334711;, + 0.616956;0.479479;, + 0.485239;0.507463;, + 0.485593;0.530220;, + 0.619554;0.528041;, + 0.617878;0.506596;, + 0.614305;0.539126;, + 0.715662;0.536483;, + 0.707911;0.479876;, + 0.715316;0.480342;, + 0.530845;0.480046;, + 0.579638;0.481539;, + 0.611205;0.482665;, + 0.634599;0.480479;, + 0.659608;0.481359;, + 0.682447;0.479741;, + 0.500776;0.479904;, + 0.485365;0.486454;, + 0.485364;0.479957;, + 0.618547;0.487348;, + 0.618035;0.480859;, + 0.485593;0.480884;, + 0.526256;0.539496;, + 0.658985;0.539087;, + 0.642654;0.716241;, + 0.706306;0.540833;, + 0.676209;0.539484;, + 0.570340;0.539574;, + 0.589402;0.577637;, + 0.580114;0.538910;, + 0.630066;0.542891;, + 0.560574;0.538232;, + 0.707645;0.653215;, + 0.698825;0.716851;, + 0.626437;0.657671;, + 0.494342;0.580983;, + 0.509352;0.540802;, + 0.544101;0.536351;, + 0.484496;0.412560;, + 0.564904;0.336726;, + 0.536100;0.335995;, + 0.593407;0.338687;, + 0.880106;0.263780;, + 0.890029;0.264275;, + 0.983849;0.547217;, + 0.959557;0.551183;, + 0.995531;0.534564;, + 0.911710;0.264051;, + 0.946269;0.549368;, + 0.989370;0.511245;, + 0.993351;0.517791;, + 0.893307;0.290193;, + 0.875823;0.291903;, + 0.989370;0.511245;, + 0.919671;0.294804;, + 0.992837;0.480465;, + 0.940909;0.507167;, + 0.925087;0.297402;, + 0.941330;0.343586;, + 0.926942;0.328248;, + 0.934683;0.469925;, + 0.916037;0.478099;, + 0.955318;0.339833;, + 0.926602;0.455368;, + 0.955264;0.354332;, + 0.919668;0.446793;, + 0.957566;0.362848;, + 0.912527;0.443043;, + 0.872782;0.373158;, + 0.948367;0.441273;, + 0.919288;0.373060;, + 0.933018;0.443136;, + 0.934200;0.436900;, + 0.916783;0.371089;, + 0.935125;0.431048;, + 0.944973;0.430058;, + 0.935605;0.426190;, + 0.945547;0.425188;, + 0.934376;0.422378;, + 0.946729;0.421136;, + 0.934637;0.416466;, + 0.945867;0.415337;, + 0.936131;0.411562;, + 0.944536;0.410714;, + 0.935548;0.407812;, + 0.945126;0.406847;, + 0.934036;0.405221;, + 0.946391;0.403976;, + 0.934582;0.399720;, + 0.945327;0.398635;, + 0.936732;0.395377;, + 0.943022;0.394739;, + 0.938903;0.393308;, + 0.941024;0.393092;, + 0.950025;0.432725;, + 0.964184;0.431303;, + 0.965384;0.439088;, + 0.951087;0.424772;, + 0.962376;0.423636;, + 0.951639;0.418194;, + 0.963037;0.417045;, + 0.950231;0.412967;, + 0.964392;0.411542;, + 0.950532;0.404875;, + 0.963406;0.403580;, + 0.952246;0.398233;, + 0.961882;0.397261;, + 0.951580;0.393096;, + 0.962559;0.391989;, + 0.949847;0.389507;, + 0.964010;0.388079;, + 0.950475;0.381982;, + 0.962793;0.380738;, + 0.952940;0.376145;, + 0.960151;0.375413;, + 0.955429;0.373402;, + 0.957861;0.373154;, + 0.966666;0.431243;, + 0.980400;0.429939;, + 0.981495;0.437251;, + 0.967796;0.423937;, + 0.978747;0.422895;, + 0.968413;0.417885;, + 0.979469;0.416831;, + 0.967116;0.413084;, + 0.980852;0.411777;, + 0.967514;0.405663;, + 0.980002;0.404475;, + 0.969258;0.399559;, + 0.978605;0.398667;, + 0.968680;0.394844;, + 0.979330;0.393828;, + 0.967049;0.391554;, + 0.980787;0.390244;, + 0.967756;0.384653;, + 0.979704;0.383511;, + 0.970216;0.379281;, + 0.977211;0.378609;, + 0.972661;0.376752;, + 0.975020;0.376525;, + 0.982811;0.431347;, + 0.994369;0.430837;, + 0.984136;0.425982;, + 0.993352;0.425573;, + 0.984958;0.421504;, + 0.994262;0.421090;, + 0.984124;0.417916;, + 0.995683;0.417404;, + 0.984852;0.412471;, + 0.995361;0.412006;, + 0.986626;0.408010;, + 0.994491;0.407659;, + 0.986391;0.404516;, + 0.995353;0.404116;, + 0.985203;0.402047;, + 0.996764;0.401532;, + 0.986163;0.396997;, + 0.996218;0.396547;, + 0.988492;0.393082;, + 0.994378;0.392816;, + 0.990660;0.391272;, + 0.992645;0.391182;, + 0.932421;0.459512;, + 0.923257;0.263530;, + 0.959778;0.518762;, + 0.936222;0.521783;, + 0.940909;0.507167;, + 0.715515;0.396862;, + 0.499182;0.336927;, + 0.484655;0.334095;, + 0.716951;0.335782;, + 0.564387;0.076817;, + 0.643460;0.343672;, + 0.616978;0.334945;, + 0.564387;0.076817;, + 0.096204;0.018218;, + 0.077882;0.009132;, + 0.140301;0.018636;, + 0.118913;0.022106;, + 0.159948;0.009132;, + 0.733208;0.668843;, + 0.733271;0.671494;, + 0.733061;0.622205;, + 0.734636;0.718815;, + 0.733702;0.623688;, + 0.733817;0.666406;, + 0.734634;0.717573;, + 0.733411;0.719397;, + 0.733436;0.669007;, + 0.731958;0.668479;, + 0.065514;0.263969;, + 0.075463;0.280817;, + 0.088742;0.263945;, + 0.046752;0.280814;, + 0.020600;0.264050;, + 0.118135;0.263808;, + 0.097353;0.346425;, + 0.118135;0.361247;, + 0.098118;0.280881;, + 0.075557;0.346508;, + 0.087647;0.361135;, + 0.060355;0.361119;, + 0.034011;0.346597;, + 0.017495;0.361046;, + 0.017980;0.308672;, + 0.048694;0.343504;, + 0.794423;0.747604;, + 0.841006;0.735950;, + 0.032432;0.280852;, + 0.737977;0.623570;, + 0.742795;0.665101;, + 0.735401;0.718589;, + 0.735464;0.622670;, + 0.806908;0.784277;, + 0.744124;0.623382;, + 0.734055;0.716026;, + 0.735560;0.624194;, + 0.735259;0.624000;, + 0.736255;0.718648;, + 0.734441;0.669812;, + 0.733843;0.625481;, + 0.734435;0.670116;, + 0.735742;0.624306;, + 0.735112;0.623862;, + 0.721657;0.718291;, + 0.733828;0.668886;, + 0.733464;0.621691;, + 0.734023;0.717847;, + 0.733534;0.719777;, + 0.734009;0.671022;, + 0.734158;0.716596;, + 0.731633;0.621868;, + 0.731332;0.631315;, + 0.669043;0.833034;, + 0.660066;0.832672;, + 0.655598;0.849640;, + 0.737725;0.714443;, + 0.741942;0.676619;, + 0.741961;0.715542;, + 0.733665;0.674284;, + 0.734971;0.669387;, + 0.729903;0.675143;, + 0.734761;0.719063;, + 0.735332;0.716619;, + 0.734955;0.668426;, + 0.721716;0.621992;, + 0.490854;0.881098;, + 0.604315;0.879016;, + 0.619397;0.857270;, + 0.550381;0.879254;, + 0.614918;0.901410;, + 0.733632;0.622431;, + 0.733752;0.622431;, + 0.733619;0.621524;, + 0.734255;0.718460;, + 0.733645;0.623168;, + 0.734765;0.668727;, + 0.733004;0.624609;, + 0.732771;0.623537;, + 0.732742;0.623931;, + 0.733127;0.622943;, + 0.738124;0.626577;, + 0.733325;0.623897;, + 0.736550;0.716796;, + 0.733320;0.626103;, + 0.734626;0.670928;, + 0.735641;0.711463;, + 0.734563;0.670905;, + 0.735018;0.673031;, + 0.734433;0.669076;, + 0.734127;0.670046;, + 0.735105;0.667616;, + 0.734543;0.621846;, + 0.734712;0.717490;, + 0.734725;0.623514;, + 0.733232;0.624888;, + 0.736739;0.716543;, + 0.734684;0.670029;, + 0.734888;0.718644;, + 0.732628;0.670896;, + 0.733935;0.669238;, + 0.733037;0.669749;, + 0.170261;0.263941;, + 0.147528;0.263863;, + 0.159819;0.280672;, + 0.202812;0.280741;, + 0.212210;0.264050;, + 0.138917;0.346425;, + 0.137163;0.280736;, + 0.149118;0.361154;, + 0.160713;0.346508;, + 0.175915;0.361213;, + 0.217292;0.361140;, + 0.217795;0.309277;, + 0.203145;0.343675;, + 0.180652;0.278493;, + 0.737977;0.623570;, + 0.742795;0.665101;, + 0.734658;0.673204;, + 0.734427;0.624424;, + 0.741949;0.625748;, + 0.735977;0.717392;, + 0.735384;0.622600;, + 0.735442;0.624471;, + 0.734397;0.718833;, + 0.735195;0.674837;, + 0.731426;0.622834;, + 0.733554;0.671983;, + 0.732964;0.622128;, + 0.735365;0.720658;, + 0.732993;0.622640;, + 0.722763;0.718246;, + 0.734404;0.664391;, + 0.806292;0.771849;, + 0.733568;0.624201;, + 0.735564;0.717674;, + 0.734832;0.718436;, + 0.734634;0.672608;, + 0.733135;0.673954;, + 0.738890;0.713850;, + 0.734689;0.623399;, + 0.732473;0.640685;, + 0.741942;0.676619;, + 0.734732;0.719564;, + 0.736409;0.671560;, + 0.733928;0.669098;, + 0.734488;0.716382;, + 0.735985;0.719547;, + 0.734111;0.670206;, + 0.722716;0.624358;, + 0.490854;0.881098;, + 0.619397;0.857270;, + 0.604316;0.879016;, + 0.550381;0.879254;, + 0.614041;0.900874;, + 0.734698;0.623311;, + 0.733366;0.623859;, + 0.733853;0.622432;, + 0.736423;0.718140;, + 0.733794;0.624449;, + 0.733416;0.668524;, + 0.734057;0.624252;, + 0.733026;0.622840;, + 0.733957;0.622990;, + 0.733958;0.669768;, + 0.573787;0.946976;, + 0.570524;0.952054;, + 0.732989;0.677617;, + 0.733901;0.623536;, + 0.742194;0.624474;, + 0.735057;0.717697;, + 0.733910;0.670742;, + 0.722198;0.625877;, + 0.726309;0.666336;, + 0.732760;0.623866;, + 0.722409;0.718816;, + 0.771240;0.998210;, + 0.768920;0.993101;, + 0.688441;0.780145;, + 0.670920;0.758421;, + 0.716559;0.753271;, + 0.699682;0.779579;, + 0.768920;0.993101;, + 0.771240;0.998210;, + 0.684801;0.799303;, + 0.703203;0.796694;, + 0.578377;0.723871;, + 0.556798;0.737410;, + 0.535220;0.723871;, + 0.494371;0.846123;, + 0.556672;0.847727;, + 0.617913;0.846306;, + 0.883801;0.999405;, + 0.883640;0.999019;, + 0.883640;0.999019;, + 0.883801;0.999405;, + 0.869557;0.983855;, + 0.878434;0.995071;, + 0.843654;0.956371;, + 0.862861;0.974051;, + 0.704350;0.916866;, + 0.711279;0.931275;, + 0.726665;0.956005;, + 0.758250;0.982937;, + 0.718910;0.943490;, + 0.801523;0.828198;, + 0.803097;0.850936;, + 0.804537;0.864603;, + 0.813820;0.899525;, + 0.696062;0.914837;, + 0.809005;0.773290;, + 0.799319;0.811168;, + 0.709933;0.855338;, + 0.699389;0.815607;, + 0.845499;0.203618;, + 0.836934;0.209967;, + 0.834313;0.222928;, + 0.836611;0.235486;, + 0.817344;0.816095;, + 0.818300;0.813808;, + 0.827677;0.929505;, + 0.900992;0.226326;, + 0.889329;0.204667;, + 0.864170;0.826738;, + 0.897258;0.241354;, + 0.905079;0.230177;, + 0.756146;0.776044;, + 0.749218;0.822256;, + 0.665190;0.878729;, + 0.688338;0.907690;, + 0.762590;0.730701;, + 0.602368;0.738846;, + 0.723336;0.628567;, + 0.723137;0.664019;, + 0.864352;0.570403;, + 0.855895;0.608482;, + 0.865600;0.559362;, + 0.862728;0.546228;, + 0.857614;0.550540;, + 0.739543;0.726668;, + 0.631750;0.845695;, + 0.876169;0.248651;, + 0.890294;0.243145;, + 0.872748;0.198756;, + 0.854340;0.200840;, + 0.879155;0.197889;, + 0.847218;0.244311;, + 0.861893;0.250498;, + 0.842524;0.242503;, + 0.871498;0.251096;, + 0.937684;0.974051;, + 0.956890;0.956371;, + 0.930988;0.983855;, + 0.878434;0.995071;, + 0.758250;0.982937;, + 0.726665;0.956005;, + 0.711279;0.931275;, + 0.704350;0.916866;, + 0.718910;0.943490;, + 0.996007;0.864603;, + 0.813820;0.899525;, + 0.997447;0.850936;, + 0.999022;0.828198;, + 0.696062;0.914837;, + 0.998196;0.807248;, + 0.993636;0.784277;, + 0.794423;0.747604;, + 0.811872;0.736951;, + 0.669043;0.833034;, + 0.699389;0.815607;, + 0.709933;0.855338;, + 0.904083;0.234820;, + 0.906567;0.222917;, + 0.903734;0.210631;, + 0.894473;0.204614;, + 0.984046;0.817359;, + 0.982715;0.814038;, + 0.972868;0.929505;, + 0.934802;0.823017;, + 0.847081;0.205608;, + 0.933650;0.826738;, + 0.838508;0.240382;, + 0.756146;0.776044;, + 0.749218;0.822256;, + 0.655598;0.849640;, + 0.660066;0.832672;, + 0.665190;0.878729;, + 0.688338;0.907690;, + 0.625881;0.747856;, + 0.511229;0.738846;, + 0.721795;0.673083;, + 0.656300;0.740491;, + 0.647354;0.737719;, + 0.984113;0.609149;, + 0.981105;0.573070;, + 0.970594;0.556694;, + 0.980214;0.557876;, + 0.489245;0.841771;, + 0.846038;0.242079;, + 0.861311;0.247298;, + 0.884914;0.201981;, + 0.865010;0.200005;, + 0.858082;0.199183;, + 0.876747;0.249049;, + 0.892614;0.243184;, + 0.897689;0.241471;, + 0.866361;0.249615;, + 0.523805;0.842839;, + 0.590386;0.842199;, + 0.184823;0.343667;, + 0.264166;0.187404;, + 0.551922;0.238188;; + } + + VertexDuplicationIndices { + 4432; + 3420; + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 385, + 386, + 387, + 388, + 389, + 390, + 391, + 392, + 393, + 394, + 395, + 396, + 397, + 398, + 399, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 418, + 419, + 420, + 421, + 422, + 423, + 424, + 425, + 426, + 427, + 428, + 429, + 430, + 431, + 432, + 433, + 434, + 435, + 436, + 437, + 438, + 439, + 440, + 441, + 442, + 443, + 444, + 445, + 446, + 447, + 448, + 449, + 450, + 451, + 452, + 453, + 454, + 455, + 456, + 457, + 458, + 459, + 460, + 461, + 462, + 463, + 464, + 465, + 466, + 467, + 468, + 469, + 470, + 471, + 472, + 473, + 474, + 475, + 476, + 477, + 478, + 479, + 480, + 481, + 482, + 483, + 484, + 485, + 486, + 487, + 488, + 489, + 490, + 491, + 492, + 493, + 494, + 495, + 496, + 497, + 498, + 499, + 500, + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520, + 521, + 522, + 523, + 524, + 525, + 526, + 527, + 528, + 529, + 530, + 531, + 532, + 533, + 534, + 535, + 536, + 537, + 538, + 539, + 540, + 541, + 542, + 543, + 544, + 545, + 546, + 547, + 548, + 549, + 550, + 551, + 552, + 553, + 554, + 555, + 556, + 557, + 558, + 559, + 560, + 561, + 562, + 563, + 564, + 565, + 566, + 567, + 568, + 569, + 570, + 571, + 572, + 573, + 574, + 575, + 576, + 577, + 578, + 579, + 580, + 581, + 582, + 583, + 584, + 585, + 586, + 587, + 588, + 589, + 590, + 591, + 592, + 593, + 594, + 595, + 596, + 597, + 598, + 599, + 600, + 601, + 602, + 603, + 604, + 605, + 606, + 607, + 608, + 609, + 610, + 611, + 612, + 613, + 614, + 615, + 616, + 617, + 618, + 619, + 620, + 621, + 622, + 623, + 624, + 625, + 626, + 627, + 628, + 629, + 630, + 631, + 632, + 633, + 634, + 635, + 636, + 637, + 638, + 639, + 640, + 641, + 642, + 643, + 644, + 645, + 646, + 647, + 648, + 649, + 650, + 651, + 652, + 653, + 654, + 655, + 656, + 657, + 658, + 659, + 660, + 661, + 662, + 663, + 664, + 665, + 666, + 667, + 668, + 669, + 670, + 671, + 672, + 673, + 674, + 675, + 676, + 677, + 678, + 679, + 680, + 681, + 682, + 683, + 684, + 685, + 686, + 687, + 688, + 689, + 690, + 691, + 692, + 693, + 694, + 695, + 696, + 697, + 698, + 699, + 700, + 701, + 702, + 703, + 704, + 705, + 706, + 707, + 708, + 709, + 710, + 711, + 712, + 713, + 714, + 715, + 716, + 717, + 718, + 719, + 720, + 721, + 722, + 723, + 724, + 725, + 726, + 727, + 728, + 729, + 730, + 731, + 732, + 733, + 734, + 735, + 736, + 737, + 738, + 739, + 740, + 741, + 742, + 743, + 744, + 745, + 746, + 747, + 748, + 749, + 750, + 751, + 752, + 753, + 754, + 755, + 756, + 757, + 758, + 759, + 760, + 761, + 762, + 763, + 764, + 765, + 766, + 767, + 768, + 769, + 770, + 771, + 772, + 773, + 774, + 775, + 776, + 777, + 778, + 779, + 780, + 781, + 782, + 783, + 784, + 785, + 786, + 787, + 788, + 789, + 790, + 791, + 792, + 793, + 794, + 795, + 796, + 797, + 798, + 799, + 800, + 801, + 802, + 803, + 804, + 805, + 806, + 807, + 808, + 809, + 810, + 811, + 812, + 813, + 814, + 815, + 816, + 817, + 818, + 819, + 820, + 821, + 822, + 823, + 824, + 825, + 826, + 827, + 828, + 829, + 830, + 831, + 832, + 833, + 834, + 835, + 836, + 837, + 838, + 839, + 840, + 841, + 842, + 843, + 844, + 845, + 846, + 847, + 848, + 849, + 850, + 851, + 852, + 853, + 854, + 855, + 856, + 857, + 858, + 859, + 860, + 861, + 862, + 863, + 864, + 865, + 866, + 867, + 868, + 869, + 870, + 871, + 872, + 873, + 874, + 875, + 876, + 877, + 878, + 879, + 880, + 881, + 882, + 883, + 884, + 885, + 886, + 887, + 888, + 889, + 890, + 891, + 892, + 893, + 894, + 895, + 896, + 897, + 898, + 899, + 900, + 901, + 902, + 903, + 904, + 905, + 906, + 907, + 908, + 909, + 910, + 911, + 912, + 913, + 914, + 915, + 916, + 917, + 918, + 919, + 920, + 921, + 922, + 923, + 924, + 925, + 926, + 927, + 928, + 929, + 930, + 931, + 932, + 933, + 934, + 935, + 936, + 937, + 938, + 939, + 940, + 941, + 942, + 943, + 944, + 945, + 946, + 947, + 948, + 949, + 950, + 951, + 952, + 953, + 954, + 955, + 956, + 957, + 958, + 959, + 960, + 961, + 962, + 963, + 964, + 965, + 966, + 967, + 968, + 969, + 970, + 971, + 972, + 973, + 974, + 975, + 976, + 977, + 978, + 979, + 980, + 981, + 982, + 983, + 984, + 985, + 986, + 987, + 988, + 989, + 990, + 991, + 992, + 993, + 994, + 995, + 996, + 997, + 998, + 999, + 1000, + 1001, + 1002, + 1003, + 1004, + 1005, + 1006, + 1007, + 1008, + 1009, + 1010, + 1011, + 1012, + 1013, + 1014, + 1015, + 1016, + 1017, + 1018, + 1019, + 1020, + 1021, + 1022, + 1023, + 1024, + 1025, + 1026, + 1027, + 1028, + 1029, + 1030, + 1031, + 1032, + 1033, + 1034, + 1035, + 1036, + 1037, + 1038, + 1039, + 1040, + 1041, + 1042, + 1043, + 1044, + 1045, + 1046, + 1047, + 1048, + 1049, + 1050, + 1051, + 1052, + 1053, + 1054, + 1055, + 1056, + 1057, + 1058, + 1059, + 1060, + 1061, + 1062, + 1063, + 1064, + 1065, + 1066, + 1067, + 1068, + 1069, + 1070, + 1071, + 1072, + 1073, + 1074, + 1075, + 1076, + 1077, + 1078, + 1079, + 1080, + 1081, + 1082, + 1083, + 1084, + 1085, + 1086, + 1087, + 1088, + 1089, + 1090, + 1091, + 1092, + 1093, + 1094, + 1095, + 1096, + 1097, + 1098, + 1099, + 1100, + 1101, + 1102, + 1103, + 1104, + 1105, + 1106, + 1107, + 1108, + 1109, + 1110, + 1111, + 1112, + 1113, + 1114, + 1115, + 1116, + 1117, + 1118, + 1119, + 1120, + 1121, + 1122, + 1123, + 1124, + 1125, + 1126, + 1127, + 1128, + 1129, + 1130, + 1131, + 1132, + 1133, + 1134, + 1135, + 1136, + 1137, + 1138, + 1139, + 1140, + 1141, + 1142, + 1143, + 1144, + 1145, + 1146, + 1147, + 1148, + 1149, + 1150, + 1151, + 1152, + 1153, + 1154, + 1155, + 1156, + 1157, + 1158, + 1159, + 1160, + 1161, + 1162, + 1163, + 1164, + 1165, + 1166, + 1167, + 1168, + 1169, + 1170, + 1171, + 1172, + 1173, + 1174, + 1175, + 1176, + 1177, + 1178, + 1179, + 1180, + 1181, + 1182, + 1183, + 1184, + 1185, + 1186, + 1187, + 1188, + 1189, + 1190, + 1191, + 1192, + 1193, + 1194, + 1195, + 1196, + 1197, + 1198, + 1199, + 1200, + 1201, + 1202, + 1203, + 1204, + 1205, + 1206, + 1207, + 1208, + 1209, + 1210, + 1211, + 1212, + 1213, + 1214, + 1215, + 1216, + 1217, + 1218, + 1219, + 1220, + 1221, + 1222, + 1223, + 1224, + 1225, + 1226, + 1227, + 1228, + 1229, + 1230, + 1231, + 1232, + 1233, + 1234, + 1235, + 1236, + 1237, + 1238, + 1239, + 1240, + 1241, + 1242, + 1243, + 1244, + 1245, + 1246, + 1247, + 1248, + 1249, + 1250, + 1251, + 1252, + 1253, + 1254, + 1255, + 1256, + 1257, + 1258, + 1259, + 1260, + 1261, + 1262, + 1263, + 1264, + 1265, + 1266, + 1267, + 1268, + 1269, + 1270, + 1271, + 1272, + 1273, + 1274, + 1275, + 1276, + 1277, + 1278, + 1279, + 1280, + 1281, + 1282, + 1283, + 1284, + 1285, + 1286, + 1287, + 1288, + 1289, + 1290, + 1291, + 1292, + 1293, + 1294, + 1295, + 1296, + 1297, + 1298, + 1299, + 1300, + 1301, + 1302, + 1303, + 1304, + 1305, + 1306, + 1307, + 1308, + 1309, + 1310, + 1311, + 1312, + 1313, + 1314, + 1315, + 1316, + 1317, + 1318, + 1319, + 1320, + 1321, + 1322, + 1323, + 1324, + 1325, + 1326, + 1327, + 1328, + 1329, + 1330, + 1331, + 1332, + 1333, + 1334, + 1335, + 1336, + 1337, + 1338, + 1339, + 1340, + 1341, + 1342, + 1343, + 1344, + 1345, + 1346, + 1347, + 1348, + 1349, + 1350, + 1351, + 1352, + 1353, + 1354, + 1355, + 1356, + 1357, + 1358, + 1359, + 1360, + 1361, + 1362, + 1363, + 1364, + 1365, + 1366, + 1367, + 1368, + 1369, + 1370, + 1371, + 1372, + 1373, + 1374, + 1375, + 1376, + 1377, + 1378, + 1379, + 1380, + 1381, + 1382, + 1383, + 1384, + 1385, + 1386, + 1387, + 1388, + 1389, + 1390, + 1391, + 1392, + 1393, + 1394, + 1395, + 1396, + 1397, + 1398, + 1399, + 1400, + 1401, + 1402, + 1403, + 1404, + 1405, + 1406, + 1407, + 1408, + 1409, + 1410, + 1411, + 1412, + 1413, + 1414, + 1415, + 1416, + 1417, + 1418, + 1419, + 1420, + 1421, + 1422, + 1423, + 1424, + 1425, + 1426, + 1427, + 1428, + 1429, + 1430, + 1431, + 1432, + 1433, + 1434, + 1435, + 1436, + 1437, + 1438, + 1439, + 1440, + 1441, + 1442, + 1443, + 1444, + 1445, + 1446, + 1447, + 1448, + 1449, + 1450, + 1451, + 1452, + 1453, + 1454, + 1455, + 1456, + 1457, + 1458, + 1459, + 1460, + 1461, + 1462, + 1463, + 1464, + 1465, + 1466, + 1467, + 1468, + 1469, + 1470, + 1471, + 1472, + 1473, + 1474, + 1475, + 1476, + 1477, + 1478, + 1479, + 1480, + 1481, + 1482, + 1483, + 1484, + 1485, + 1486, + 1487, + 1488, + 1489, + 1490, + 1491, + 1492, + 1493, + 1494, + 1495, + 1496, + 1497, + 1498, + 1499, + 1500, + 1501, + 1502, + 1503, + 1504, + 1505, + 1506, + 1507, + 1508, + 1509, + 1510, + 1511, + 1512, + 1513, + 1514, + 1515, + 1516, + 1517, + 1518, + 1519, + 1520, + 1521, + 1522, + 1523, + 1524, + 1525, + 1526, + 1527, + 1528, + 1529, + 1530, + 1531, + 1532, + 1533, + 1534, + 1535, + 1536, + 1537, + 1538, + 1539, + 1540, + 1541, + 1542, + 1543, + 1544, + 1545, + 1546, + 1547, + 1548, + 1549, + 1550, + 1551, + 1552, + 1553, + 1554, + 1555, + 1556, + 1557, + 1558, + 1559, + 1560, + 1561, + 1562, + 1563, + 1564, + 1565, + 1566, + 1567, + 1568, + 1569, + 1570, + 1571, + 1572, + 1573, + 1574, + 1575, + 1576, + 1577, + 1578, + 1579, + 1580, + 1581, + 1582, + 1583, + 1584, + 1585, + 1586, + 1587, + 1588, + 1589, + 1590, + 1591, + 1592, + 1593, + 1594, + 1595, + 1596, + 1597, + 1598, + 1599, + 1600, + 1601, + 1602, + 1603, + 1604, + 1605, + 1606, + 1607, + 1608, + 1609, + 1610, + 1611, + 1612, + 1613, + 1614, + 1615, + 1616, + 1617, + 1618, + 1619, + 1620, + 1621, + 1622, + 1623, + 1624, + 1625, + 1626, + 1627, + 1628, + 1629, + 1630, + 1631, + 1632, + 1633, + 1634, + 1635, + 1636, + 1637, + 1638, + 1639, + 1640, + 1641, + 1642, + 1643, + 1644, + 1645, + 1646, + 1647, + 1648, + 1649, + 1650, + 1651, + 1652, + 1653, + 1654, + 1655, + 1656, + 1657, + 1658, + 1659, + 1660, + 1661, + 1662, + 1663, + 1664, + 1665, + 1666, + 1667, + 1668, + 1669, + 1670, + 1671, + 1672, + 1673, + 1674, + 1675, + 1676, + 1677, + 1678, + 1679, + 1680, + 1681, + 1682, + 1683, + 1684, + 1685, + 1686, + 1687, + 1688, + 1689, + 1690, + 1691, + 1692, + 1693, + 1694, + 1695, + 1696, + 1697, + 1698, + 1699, + 1700, + 1701, + 1702, + 1703, + 1704, + 1705, + 1706, + 1707, + 1708, + 1709, + 1710, + 1711, + 1712, + 1713, + 1714, + 1715, + 1716, + 1717, + 1718, + 1719, + 1720, + 1721, + 1722, + 1723, + 1724, + 1725, + 1726, + 1727, + 1728, + 1729, + 1730, + 1731, + 1732, + 1733, + 1734, + 1735, + 1736, + 1737, + 1738, + 1739, + 1740, + 1741, + 1742, + 1743, + 1744, + 1745, + 1746, + 1747, + 1748, + 1749, + 1750, + 1751, + 1752, + 1753, + 1754, + 1755, + 1756, + 1757, + 1758, + 1759, + 1760, + 1761, + 1762, + 1763, + 1764, + 1765, + 1766, + 1767, + 1768, + 1769, + 1770, + 1771, + 1772, + 1773, + 1774, + 1775, + 1776, + 1777, + 1778, + 1779, + 1780, + 1781, + 1782, + 1783, + 1784, + 1785, + 1786, + 1787, + 1788, + 1789, + 1790, + 1791, + 1792, + 1793, + 1794, + 1795, + 1796, + 1797, + 1798, + 1799, + 1800, + 1801, + 1802, + 1803, + 1804, + 1805, + 1806, + 1807, + 1808, + 1809, + 1810, + 1811, + 1812, + 1813, + 1814, + 1815, + 1816, + 1817, + 1818, + 1819, + 1820, + 1821, + 1822, + 1823, + 1824, + 1825, + 1826, + 1827, + 1828, + 1829, + 1830, + 1831, + 1832, + 1833, + 1834, + 1835, + 1836, + 1837, + 1838, + 1839, + 1840, + 1841, + 1842, + 1843, + 1844, + 1845, + 1846, + 1847, + 1848, + 1849, + 1850, + 1851, + 1852, + 1853, + 1854, + 1855, + 1856, + 1857, + 1858, + 1859, + 1860, + 1861, + 1862, + 1863, + 1864, + 1865, + 1866, + 1867, + 1868, + 1869, + 1870, + 1871, + 1872, + 1873, + 1874, + 1875, + 1876, + 1877, + 1878, + 1879, + 1880, + 1881, + 1882, + 1883, + 1884, + 1885, + 1886, + 1887, + 1888, + 1889, + 1890, + 1891, + 1892, + 1893, + 1894, + 1895, + 1896, + 1897, + 1898, + 1899, + 1900, + 1901, + 1902, + 1903, + 1904, + 1905, + 1906, + 1907, + 1908, + 1909, + 1910, + 1911, + 1912, + 1913, + 1914, + 1915, + 1916, + 1917, + 1918, + 1919, + 1920, + 1921, + 1922, + 1923, + 1924, + 1925, + 1926, + 1927, + 1928, + 1929, + 1930, + 1931, + 1932, + 1933, + 1934, + 1935, + 1936, + 1937, + 1938, + 1939, + 1940, + 1941, + 1942, + 1943, + 1944, + 1945, + 1946, + 1947, + 1948, + 1949, + 1950, + 1951, + 1952, + 1953, + 1954, + 1955, + 1956, + 1957, + 1958, + 1959, + 1960, + 1961, + 1962, + 1963, + 1964, + 1965, + 1966, + 1967, + 1968, + 1969, + 1970, + 1971, + 1972, + 1973, + 1974, + 1975, + 1976, + 1977, + 1978, + 1979, + 1980, + 1981, + 1982, + 1983, + 1984, + 1985, + 1986, + 1987, + 1988, + 1989, + 1990, + 1991, + 1992, + 1993, + 1994, + 1995, + 1996, + 1997, + 1998, + 1999, + 2000, + 2001, + 2002, + 2003, + 2004, + 2005, + 2006, + 2007, + 2008, + 2009, + 2010, + 2011, + 2012, + 2013, + 2014, + 2015, + 2016, + 2017, + 2018, + 2019, + 2020, + 2021, + 2022, + 2023, + 2024, + 2025, + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032, + 2033, + 2034, + 2035, + 2036, + 2037, + 2038, + 2039, + 2040, + 2041, + 2042, + 2043, + 2044, + 2045, + 2046, + 2047, + 2048, + 2049, + 2050, + 2051, + 2052, + 2053, + 2054, + 2055, + 2056, + 2057, + 2058, + 2059, + 2060, + 2061, + 2062, + 2063, + 2064, + 2065, + 2066, + 2067, + 2068, + 2069, + 2070, + 2071, + 2072, + 2073, + 2074, + 2075, + 2076, + 2077, + 2078, + 2079, + 2080, + 2081, + 2082, + 2083, + 2084, + 2085, + 2086, + 2087, + 2088, + 2089, + 2090, + 2091, + 2092, + 2093, + 2094, + 2095, + 2096, + 2097, + 2098, + 2099, + 2100, + 2101, + 2102, + 2103, + 2104, + 2105, + 2106, + 2107, + 2108, + 2109, + 2110, + 2111, + 2112, + 2113, + 2114, + 2115, + 2116, + 2117, + 2118, + 2119, + 2120, + 2121, + 2122, + 2123, + 2124, + 2125, + 2126, + 2127, + 2128, + 2129, + 2130, + 2131, + 2132, + 2133, + 2134, + 2135, + 2136, + 2137, + 2138, + 2139, + 2140, + 2141, + 2142, + 2143, + 2144, + 2145, + 2146, + 2147, + 2148, + 2149, + 2150, + 2151, + 2152, + 2153, + 2154, + 2155, + 2156, + 2157, + 2158, + 2159, + 2160, + 2161, + 2162, + 2163, + 2164, + 2165, + 2166, + 2167, + 2168, + 2169, + 2170, + 2171, + 2172, + 2173, + 2174, + 2175, + 2176, + 2177, + 2178, + 2179, + 2180, + 2181, + 2182, + 2183, + 2184, + 2185, + 2186, + 2187, + 2188, + 2189, + 2190, + 2191, + 2192, + 2193, + 2194, + 2195, + 2196, + 2197, + 2198, + 2199, + 2200, + 2201, + 2202, + 2203, + 2204, + 2205, + 2206, + 2207, + 2208, + 2209, + 2210, + 2211, + 2212, + 2213, + 2214, + 2215, + 2216, + 2217, + 2218, + 2219, + 2220, + 2221, + 2222, + 2223, + 2224, + 2225, + 2226, + 2227, + 2228, + 2229, + 2230, + 2231, + 2232, + 2233, + 2234, + 2235, + 2236, + 2237, + 2238, + 2239, + 2240, + 2241, + 2242, + 2243, + 2244, + 2245, + 2246, + 2247, + 2248, + 2249, + 2250, + 2251, + 2252, + 2253, + 2254, + 2255, + 2256, + 2257, + 2258, + 2259, + 2260, + 2261, + 2262, + 2263, + 2264, + 2265, + 2266, + 2267, + 2268, + 2269, + 2270, + 2271, + 2272, + 2273, + 2274, + 2275, + 2276, + 2277, + 2278, + 2279, + 2280, + 2281, + 2282, + 2283, + 2284, + 2285, + 2286, + 2287, + 2288, + 2289, + 2290, + 2291, + 2292, + 2293, + 2294, + 2295, + 2296, + 2297, + 2298, + 2299, + 2300, + 2301, + 2302, + 2303, + 2304, + 2305, + 2306, + 2307, + 2308, + 2309, + 2310, + 2311, + 2312, + 2313, + 2314, + 2315, + 2316, + 2317, + 2318, + 2319, + 2320, + 2321, + 2322, + 2323, + 2324, + 2325, + 2326, + 2327, + 2328, + 2329, + 2330, + 2331, + 2332, + 2333, + 2334, + 2335, + 2336, + 2337, + 2338, + 2339, + 2340, + 2341, + 2342, + 2343, + 2344, + 2345, + 2346, + 2347, + 2348, + 2349, + 2350, + 2351, + 2352, + 2353, + 2354, + 2355, + 2356, + 2357, + 2358, + 2359, + 2360, + 2361, + 2362, + 2363, + 2364, + 2365, + 2366, + 2367, + 2368, + 2369, + 2370, + 2371, + 2372, + 2373, + 2374, + 2375, + 2376, + 2377, + 2378, + 2379, + 2380, + 2381, + 2382, + 2383, + 2384, + 2385, + 2386, + 2387, + 2388, + 2389, + 2390, + 2391, + 2392, + 2393, + 2394, + 2395, + 2396, + 2397, + 2398, + 2399, + 2400, + 2401, + 2402, + 2403, + 2404, + 2405, + 2406, + 2407, + 2408, + 2409, + 2410, + 2411, + 2412, + 2413, + 2414, + 2415, + 2416, + 2417, + 2418, + 2419, + 2420, + 2421, + 2422, + 2423, + 2424, + 2425, + 2426, + 2427, + 2428, + 2429, + 2430, + 2431, + 2432, + 2433, + 2434, + 2435, + 2436, + 2437, + 2438, + 2439, + 2440, + 2441, + 2442, + 2443, + 2444, + 2445, + 2446, + 2447, + 2448, + 2449, + 2450, + 2451, + 2452, + 2453, + 2454, + 2455, + 2456, + 2457, + 2458, + 2459, + 2460, + 2461, + 2462, + 2463, + 2464, + 2465, + 2466, + 2467, + 2468, + 2469, + 2470, + 2471, + 2472, + 2473, + 2474, + 2475, + 2476, + 2477, + 2478, + 2479, + 2480, + 2481, + 2482, + 2483, + 2484, + 2485, + 2486, + 2487, + 2488, + 2489, + 2490, + 2491, + 2492, + 2493, + 2494, + 2495, + 2496, + 2497, + 2498, + 2499, + 2500, + 2501, + 2502, + 2503, + 2504, + 2505, + 2506, + 2507, + 2508, + 2509, + 2510, + 2511, + 2512, + 2513, + 2514, + 2515, + 2516, + 2517, + 2518, + 2519, + 2520, + 2521, + 2522, + 2523, + 2524, + 2525, + 2526, + 2527, + 2528, + 2529, + 2530, + 2531, + 2532, + 2533, + 2534, + 2535, + 2536, + 2537, + 2538, + 2539, + 2540, + 2541, + 2542, + 2543, + 2544, + 2545, + 2546, + 2547, + 2548, + 2549, + 2550, + 2551, + 2552, + 2553, + 2554, + 2555, + 2556, + 2557, + 2558, + 2559, + 2560, + 2561, + 2562, + 2563, + 2564, + 2565, + 2566, + 2567, + 2568, + 2569, + 2570, + 2571, + 2572, + 2573, + 2574, + 2575, + 2576, + 2577, + 2578, + 2579, + 2580, + 2581, + 2582, + 2583, + 2584, + 2585, + 2586, + 2587, + 2588, + 2589, + 2590, + 2591, + 2592, + 2593, + 2594, + 2595, + 2596, + 2597, + 2598, + 2599, + 2600, + 2601, + 2602, + 2603, + 2604, + 2605, + 2606, + 2607, + 2608, + 2609, + 2610, + 2611, + 2612, + 2613, + 2614, + 2615, + 2616, + 2617, + 2618, + 2619, + 2620, + 2621, + 2622, + 2623, + 2624, + 2625, + 2626, + 2627, + 2628, + 2629, + 2630, + 2631, + 2632, + 2633, + 2634, + 2635, + 2636, + 2637, + 2638, + 2639, + 2640, + 2641, + 2642, + 2643, + 2644, + 2645, + 2646, + 2647, + 2648, + 2649, + 2650, + 2651, + 2652, + 2653, + 2654, + 2655, + 2656, + 2657, + 2658, + 2659, + 2660, + 2661, + 2662, + 2663, + 2664, + 2665, + 2666, + 2667, + 2668, + 2669, + 2670, + 2671, + 2672, + 2673, + 2674, + 2675, + 2676, + 2677, + 2678, + 2679, + 2680, + 2681, + 2682, + 2683, + 2684, + 2685, + 2686, + 2687, + 2688, + 2689, + 2690, + 2691, + 2692, + 2693, + 2694, + 2695, + 2696, + 2697, + 2698, + 2699, + 2700, + 2701, + 2702, + 2703, + 2704, + 2705, + 2706, + 2707, + 2708, + 2709, + 2710, + 2711, + 2712, + 2713, + 2714, + 2715, + 2716, + 2717, + 2718, + 2719, + 2720, + 2721, + 2722, + 2723, + 2724, + 2725, + 2726, + 2727, + 2728, + 2729, + 2730, + 2731, + 2732, + 2733, + 2734, + 2735, + 2736, + 2737, + 2738, + 2739, + 2740, + 2741, + 2742, + 2743, + 2744, + 2745, + 2746, + 2747, + 2748, + 2749, + 2750, + 2751, + 2752, + 2753, + 2754, + 2755, + 2756, + 2757, + 2758, + 2759, + 2760, + 2761, + 2762, + 2763, + 2764, + 2765, + 2766, + 2767, + 2768, + 2769, + 2770, + 2771, + 2772, + 2773, + 2774, + 2775, + 2776, + 2777, + 2778, + 2779, + 2780, + 2781, + 2782, + 2783, + 2784, + 2785, + 2786, + 2787, + 2788, + 2789, + 2790, + 2791, + 2792, + 2793, + 2794, + 2795, + 2796, + 2797, + 2798, + 2799, + 2800, + 2801, + 2802, + 2803, + 2804, + 2805, + 2806, + 2807, + 2808, + 2809, + 2810, + 2811, + 2812, + 2813, + 2814, + 2815, + 2816, + 2817, + 2818, + 2819, + 2820, + 2821, + 2822, + 2823, + 2824, + 2825, + 2826, + 2827, + 2828, + 2829, + 2830, + 2831, + 2832, + 2833, + 2834, + 2835, + 2836, + 2837, + 2838, + 2839, + 2840, + 2841, + 2842, + 2843, + 2844, + 2845, + 2846, + 2847, + 2848, + 2849, + 2850, + 2851, + 2852, + 2853, + 2854, + 2855, + 2856, + 2857, + 2858, + 2859, + 2860, + 2861, + 2862, + 2863, + 2864, + 2865, + 2866, + 2867, + 2868, + 2869, + 2870, + 2871, + 2872, + 2873, + 2874, + 2875, + 2876, + 2877, + 2878, + 2879, + 2880, + 2881, + 2882, + 2883, + 2884, + 2885, + 2886, + 2887, + 2888, + 2889, + 2890, + 2891, + 2892, + 2893, + 2894, + 2895, + 2896, + 2897, + 2898, + 2899, + 2900, + 2901, + 2902, + 2903, + 2904, + 2905, + 2906, + 2907, + 2908, + 2909, + 2910, + 2911, + 2912, + 2913, + 2914, + 2915, + 2916, + 2917, + 2918, + 2919, + 2920, + 2921, + 2922, + 2923, + 2924, + 2925, + 2926, + 2927, + 2928, + 2929, + 2930, + 2931, + 2932, + 2933, + 2934, + 2935, + 2936, + 2937, + 2938, + 2939, + 2940, + 2941, + 2942, + 2943, + 2944, + 2945, + 2946, + 2947, + 2948, + 2949, + 2950, + 2951, + 2952, + 2953, + 2954, + 2955, + 2956, + 2957, + 2958, + 2959, + 2960, + 2961, + 2962, + 2963, + 2964, + 2965, + 2966, + 2967, + 2968, + 2969, + 2970, + 2971, + 2972, + 2973, + 2974, + 2975, + 2976, + 2977, + 2978, + 2979, + 2980, + 2981, + 2982, + 2983, + 2984, + 2985, + 2986, + 2987, + 2988, + 2989, + 2990, + 2991, + 2992, + 2993, + 2994, + 2995, + 2996, + 2997, + 2998, + 2999, + 3000, + 3001, + 3002, + 3003, + 3004, + 3005, + 3006, + 3007, + 3008, + 3009, + 3010, + 3011, + 3012, + 3013, + 3014, + 3015, + 3016, + 3017, + 3018, + 3019, + 3020, + 3021, + 3022, + 3023, + 3024, + 3025, + 3026, + 3027, + 3028, + 3029, + 3030, + 3031, + 3032, + 3033, + 3034, + 3035, + 3036, + 3037, + 3038, + 3039, + 3040, + 3041, + 3042, + 3043, + 3044, + 3045, + 3046, + 3047, + 3048, + 3049, + 3050, + 3051, + 3052, + 3053, + 3054, + 3055, + 3056, + 3057, + 3058, + 3059, + 3060, + 3061, + 3062, + 3063, + 3064, + 3065, + 3066, + 3067, + 3068, + 3069, + 3070, + 3071, + 3072, + 3073, + 3074, + 3075, + 3076, + 3077, + 3078, + 3079, + 3080, + 3081, + 3082, + 3083, + 3084, + 3085, + 3086, + 3087, + 3088, + 3089, + 3090, + 3091, + 3092, + 3093, + 3094, + 3095, + 3096, + 3097, + 3098, + 3099, + 3100, + 3101, + 3102, + 3103, + 3104, + 3105, + 3106, + 3107, + 3108, + 3109, + 3110, + 3111, + 3112, + 3113, + 3114, + 3115, + 3116, + 3117, + 3118, + 3119, + 3120, + 3121, + 3122, + 3123, + 3124, + 3125, + 3126, + 3127, + 3128, + 3129, + 3130, + 3131, + 3132, + 3133, + 3134, + 3135, + 3136, + 3137, + 3138, + 3139, + 3140, + 3141, + 3142, + 3143, + 3144, + 3145, + 3146, + 3147, + 3148, + 3149, + 3150, + 3151, + 3152, + 3153, + 3154, + 3155, + 3156, + 3157, + 3158, + 3159, + 3160, + 3161, + 3162, + 3163, + 3164, + 3165, + 3166, + 3167, + 3168, + 3169, + 3170, + 3171, + 3172, + 3173, + 3174, + 3175, + 3176, + 3177, + 3178, + 3179, + 3180, + 3181, + 3182, + 3183, + 3184, + 3185, + 3186, + 3187, + 3188, + 3189, + 3190, + 3191, + 3192, + 3193, + 3194, + 3195, + 3196, + 3197, + 3198, + 3199, + 3200, + 3201, + 3202, + 3203, + 3204, + 3205, + 3206, + 3207, + 3208, + 3209, + 3210, + 3211, + 3212, + 3213, + 3214, + 3215, + 3216, + 3217, + 3218, + 3219, + 3220, + 3221, + 3222, + 3223, + 3224, + 3225, + 3226, + 3227, + 3228, + 3229, + 3230, + 3231, + 3232, + 3233, + 3234, + 3235, + 3236, + 3237, + 3238, + 3239, + 3240, + 3241, + 3242, + 3243, + 3244, + 3245, + 3246, + 3247, + 3248, + 3249, + 3250, + 3251, + 3252, + 3253, + 3254, + 3255, + 3256, + 3257, + 3258, + 3259, + 3260, + 3261, + 3262, + 3263, + 3264, + 3265, + 3266, + 3267, + 3268, + 3269, + 3270, + 3271, + 3272, + 3273, + 3274, + 3275, + 3276, + 3277, + 3278, + 3279, + 3280, + 3281, + 3282, + 3283, + 3284, + 3285, + 3286, + 3287, + 3288, + 3289, + 3290, + 3291, + 3292, + 3293, + 3294, + 3295, + 3296, + 3297, + 3298, + 3299, + 3300, + 3301, + 3302, + 3303, + 3304, + 3305, + 3306, + 3307, + 3308, + 3309, + 3310, + 3311, + 3312, + 3313, + 3314, + 3315, + 3316, + 3317, + 3318, + 3319, + 3320, + 3321, + 3322, + 3323, + 3324, + 3325, + 3326, + 3327, + 3328, + 3329, + 3330, + 3331, + 3332, + 3333, + 3334, + 3335, + 3336, + 3337, + 3338, + 3339, + 3340, + 3341, + 3342, + 3343, + 3344, + 3345, + 3346, + 3347, + 3348, + 3349, + 3350, + 3351, + 3352, + 3353, + 3354, + 3355, + 3356, + 3357, + 3358, + 3359, + 3360, + 3361, + 3362, + 3363, + 3364, + 3365, + 3366, + 3367, + 3368, + 3369, + 3370, + 3371, + 3372, + 3373, + 3374, + 3375, + 3376, + 3377, + 3378, + 3379, + 3380, + 3381, + 3382, + 3383, + 3384, + 3385, + 3386, + 3387, + 3388, + 3389, + 3390, + 3391, + 3392, + 3393, + 3394, + 3395, + 3396, + 3397, + 3398, + 3399, + 3400, + 3401, + 3402, + 3403, + 3404, + 3405, + 3406, + 3407, + 3408, + 3409, + 3410, + 3411, + 3412, + 3413, + 3414, + 3415, + 3416, + 3417, + 3418, + 3419, + 1, + 62, + 11, + 11, + 16, + 26, + 27, + 0, + 28, + 0, + 36, + 84, + 45, + 39, + 32, + 51, + 52, + 65, + 53, + 67, + 35, + 44, + 66, + 54, + 34, + 43, + 26, + 33, + 64, + 0, + 64, + 54, + 20, + 4, + 2, + 71, + 68, + 42, + 93, + 88, + 31, + 101, + 92, + 93, + 94, + 104, + 91, + 89, + 90, + 99, + 9, + 1741, + 102, + 103, + 105, + 125, + 128, + 129, + 124, + 25, + 126, + 127, + 138, + 184, + 145, + 145, + 156, + 157, + 158, + 137, + 205, + 165, + 171, + 166, + 162, + 176, + 175, + 187, + 177, + 189, + 170, + 164, + 188, + 178, + 169, + 156, + 163, + 186, + 137, + 137, + 186, + 178, + 150, + 140, + 139, + 193, + 190, + 211, + 161, + 218, + 210, + 211, + 212, + 221, + 209, + 208, + 216, + 144, + 1743, + 219, + 220, + 222, + 240, + 243, + 244, + 239, + 155, + 241, + 242, + 435, + 260, + 254, + 274, + 280, + 269, + 424, + 300, + 290, + 291, + 292, + 293, + 294, + 299, + 310, + 298, + 297, + 296, + 295, + 295, + 290, + 304, + 309, + 303, + 490, + 492, + 318, + 317, + 261, + 257, + 512, + 516, + 530, + 332, + 533, + 423, + 350, + 307, + 357, + 308, + 308, + 365, + 349, + 347, + 358, + 359, + 360, + 364, + 353, + 352, + 361, + 365, + 357, + 351, + 350, + 355, + 356, + 362, + 366, + 354, + 363, + 393, + 394, + 282, + 337, + 281, + 289, + 391, + 334, + 390, + 286, + 332, + 266, + 394, + 395, + 307, + 303, + 440, + 451, + 453, + 427, + 431, + 432, + 434, + 433, + 435, + 435, + 429, + 41, + 47, + 436, + 40, + 45, + 45, + 46, + 436, + 452, + 453, + 446, + 437, + 460, + 461, + 264, + 327, + 329, + 525, + 278, + 268, + 322, + 547, + 546, + 428, + 562, + 733, + 557, + 575, + 581, + 570, + 724, + 601, + 591, + 592, + 593, + 594, + 595, + 600, + 611, + 599, + 598, + 597, + 596, + 596, + 591, + 605, + 610, + 604, + 780, + 619, + 782, + 618, + 563, + 802, + 806, + 820, + 633, + 823, + 723, + 651, + 608, + 609, + 609, + 666, + 650, + 648, + 659, + 660, + 661, + 665, + 654, + 653, + 662, + 666, + 658, + 652, + 651, + 656, + 657, + 663, + 667, + 655, + 664, + 694, + 695, + 583, + 638, + 582, + 590, + 692, + 635, + 691, + 587, + 633, + 567, + 695, + 696, + 608, + 604, + 658, + 745, + 738, + 747, + 727, + 729, + 730, + 732, + 731, + 733, + 733, + 728, + 168, + 734, + 167, + 171, + 171, + 746, + 734, + 747, + 735, + 628, + 630, + 815, + 579, + 569, + 623, + 837, + 836, + 207, + 198, + 856, + 854, + 194, + 198, + 860, + 893, + 862, + 897, + 863, + 883, + 879, + 858, + 857, + 853, + 860, + 861, + 887, + 859, + 888, + 889, + 857, + 870, + 861, + 873, + 888, + 886, + 884, + 910, + 882, + 881, + 915, + 879, + 883, + 880, + 879, + 912, + 924, + 938, + 909, + 883, + 885, + 945, + 200, + 197, + 201, + 910, + 911, + 910, + 914, + 947, + 915, + 915, + 1281, + 951, + 951, + 1282, + 951, + 954, + 952, + 955, + 954, + 965, + 990, + 989, + 988, + 968, + 995, + 993, + 1000, + 993, + 997, + 1002, + 998, + 1005, + 1003, + 962, + 1018, + 985, + 1015, + 970, + 1024, + 1021, + 1030, + 1027, + 1036, + 1033, + 1042, + 1039, + 1048, + 1045, + 1054, + 1051, + 1060, + 1057, + 1066, + 1063, + 1072, + 1069, + 1076, + 1075, + 1080, + 1077, + 969, + 1086, + 1083, + 1092, + 1089, + 1098, + 1095, + 1104, + 1101, + 1110, + 1107, + 1116, + 1113, + 1122, + 1119, + 1128, + 1125, + 1134, + 1131, + 1138, + 1137, + 1142, + 1139, + 972, + 1148, + 1145, + 1154, + 1151, + 1160, + 1157, + 1166, + 1163, + 1172, + 1169, + 1178, + 1175, + 1184, + 1181, + 1190, + 1187, + 1196, + 1193, + 1200, + 1199, + 1204, + 1201, + 1210, + 1207, + 1216, + 1213, + 1222, + 1219, + 1228, + 1225, + 1234, + 1231, + 1240, + 1237, + 1246, + 1243, + 1250, + 1252, + 1249, + 1258, + 1255, + 1262, + 1261, + 1268, + 950, + 953, + 954, + 1280, + 955, + 1288, + 196, + 195, + 195, + 76, + 1299, + 1301, + 77, + 72, + 1305, + 1338, + 1307, + 1308, + 1342, + 1328, + 1324, + 1303, + 1302, + 1298, + 1305, + 1306, + 1332, + 1304, + 1333, + 1334, + 1315, + 1302, + 1318, + 1306, + 1333, + 1331, + 1329, + 1355, + 1327, + 1326, + 1324, + 1363, + 1327, + 1328, + 1325, + 1382, + 1360, + 1369, + 1354, + 1328, + 1330, + 1390, + 78, + 75, + 79, + 1355, + 1356, + 1355, + 1359, + 1392, + 1360, + 1360, + 1396, + 1726, + 1397, + 1396, + 1396, + 1399, + 1400, + 1399, + 1410, + 1435, + 1434, + 1433, + 1413, + 1440, + 1438, + 1445, + 1443, + 1450, + 1448, + 1407, + 1415, + 1461, + 1430, + 1463, + 1460, + 1469, + 1466, + 1475, + 1472, + 1481, + 1478, + 1487, + 1484, + 1493, + 1490, + 1499, + 1496, + 1505, + 1502, + 1511, + 1508, + 1517, + 1514, + 1521, + 1520, + 1525, + 1522, + 1414, + 1531, + 1528, + 1537, + 1534, + 1543, + 1540, + 1549, + 1546, + 1555, + 1552, + 1561, + 1558, + 1567, + 1564, + 1573, + 1570, + 1579, + 1576, + 1583, + 1582, + 1587, + 1584, + 1417, + 1593, + 1590, + 1599, + 1596, + 1605, + 1602, + 1611, + 1608, + 1617, + 1614, + 1623, + 1620, + 1629, + 1626, + 1635, + 1632, + 1641, + 1638, + 1645, + 1644, + 1649, + 1646, + 1655, + 1652, + 1661, + 1658, + 1667, + 1664, + 1673, + 1670, + 1679, + 1676, + 1685, + 1682, + 1691, + 1688, + 1697, + 1694, + 1703, + 1700, + 1707, + 1706, + 1713, + 1395, + 1398, + 1725, + 1399, + 1733, + 74, + 73, + 73, + 1285, + 199, + 76, + 1730, + 1739, + 9, + 1740, + 10, + 144, + 1757, + 1758, + 1757, + 1759, + 1758, + 1757, + 1757, + 1759, + 1759, + 1765, + 1779, + 1769, + 1767, + 1778, + 1756, + 1746, + 1772, + 1752, + 1771, + 1770, + 1763, + 1777, + 1773, + 1766, + 1775, + 1776, + 1766, + 1777, + 1768, + 1767, + 1779, + 1764, + 1758, + 2146, + 1764, + 1784, + 1757, + 1764, + 1785, + 1765, + 1750, + 1759, + 1759, + 1750, + 1782, + 1761, + 1756, + 1748, + 1784, + 1764, + 1761, + 1753, + 1804, + 1784, + 1804, + 1781, + 1751, + 1880, + 1751, + 1784, + 1761, + 1783, + 1788, + 1786, + 1788, + 1789, + 1761, + 1774, + 1756, + 1818, + 1766, + 1751, + 1747, + 1757, + 1753, + 1748, + 1758, + 1758, + 1764, + 1759, + 1756, + 1761, + 1764, + 1751, + 1786, + 1765, + 1785, + 1813, + 1751, + 1888, + 1748, + 1889, + 1888, + 1890, + 1889, + 1888, + 1888, + 1747, + 1890, + 1750, + 1890, + 1896, + 1910, + 1898, + 1900, + 1899, + 1887, + 1903, + 1902, + 1894, + 1901, + 1908, + 1897, + 1906, + 1904, + 1909, + 1898, + 1910, + 1895, + 1889, + 1895, + 1915, + 1888, + 1895, + 1916, + 1896, + 1750, + 1890, + 1890, + 1754, + 1750, + 1913, + 1892, + 2801, + 1887, + 1748, + 1915, + 1753, + 1895, + 1892, + 1753, + 1935, + 2011, + 1915, + 1892, + 1914, + 1919, + 1917, + 1919, + 1920, + 1892, + 1887, + 1905, + 1949, + 1897, + 1751, + 1747, + 1888, + 1753, + 1748, + 1889, + 1889, + 1895, + 1890, + 1887, + 1998, + 1999, + 1892, + 1895, + 1751, + 1917, + 1896, + 1916, + 1944, + 1916, + 1917, + 2094, + 3050, + 2095, + 3069, + 2406, + 2096, + 2394, + 2097, + 2093, + 2098, + 1788, + 1754, + 1919, + 141, + 86, + 5, + 2109, + 2399, + 3056, + 2110, + 2115, + 2398, + 2208, + 2116, + 2140, + 2124, + 2122, + 2395, + 1755, + 2707, + 2132, + 2131, + 2203, + 2386, + 2141, + 2704, + 1780, + 1761, + 2486, + 2151, + 2154, + 2499, + 2153, + 2152, + 2211, + 2309, + 2495, + 2316, + 2483, + 2310, + 1789, + 1782, + 1783, + 1785, + 1785, + 1786, + 2405, + 2426, + 2409, + 2414, + 1787, + 2426, + 2410, + 2426, + 88, + 2502, + 2484, + 2493, + 2487, + 2494, + 2497, + 2504, + 2498, + 2503, + 2772, + 2864, + 2773, + 3057, + 3049, + 2776, + 2780, + 2796, + 1886, + 2781, + 2857, + 2788, + 3366, + 3044, + 3364, + 2802, + 1897, + 1908, + 1915, + 1892, + 1911, + 3155, + 2810, + 2813, + 3147, + 2811, + 2812, + 2861, + 2966, + 3154, + 2967, + 3142, + 1920, + 1913, + 1912, + 1935, + 1914, + 1916, + 1916, + 1917, + 3086, + 3065, + 3086, + 3072, + 3066, + 1918, + 3065, + 207, + 3141, + 3165, + 3146, + 3150, + 3149, + 3163, + 3157, + 3156, + 3164, + 206, + 87, + 1907, + 3418, + 3419; + } + + MeshMaterialList { + 1; + 6841; + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0; + + Material { + 1.000000;1.000000;1.000000;1.000000;; + 0.000000; + 1.000000;1.000000;1.000000;; + 0.000000;0.000000;0.000000;; + + TextureFilename { + "Tiny_skin.dds"; + } + } + } + + XSkinMeshHeader { + 2; + 4; + 35; + } + + SkinWeights { + "Bip01_R_UpperArm"; + 156; + 0, + 3449, + 3429, + 3427, + 2, + 3454, + 4, + 3453, + 7, + 15, + 68, + 3456, + 69, + 70, + 71, + 3455, + 72, + 3940, + 73, + 4110, + 4109, + 74, + 4108, + 75, + 3980, + 76, + 4113, + 3936, + 77, + 3939, + 78, + 3979, + 79, + 3981, + 1294, + 1295, + 1296, + 1297, + 1298, + 3950, + 1299, + 3937, + 1300, + 1301, + 3938, + 1302, + 3958, + 3949, + 1303, + 3948, + 1304, + 3954, + 1305, + 3951, + 3941, + 1306, + 3960, + 3952, + 1307, + 3943, + 1308, + 3944, + 1309, + 1310, + 1311, + 1312, + 1313, + 1314, + 1315, + 3957, + 1316, + 1317, + 1318, + 3959, + 1319, + 1320, + 1321, + 1322, + 1323, + 1324, + 3967, + 3947, + 1325, + 3971, + 1326, + 3966, + 1327, + 3969, + 3965, + 1328, + 3976, + 3970, + 3946, + 1329, + 3963, + 1330, + 3977, + 1331, + 3962, + 1332, + 3953, + 1333, + 3961, + 3955, + 1334, + 3956, + 1335, + 1336, + 1337, + 1338, + 3942, + 1339, + 1340, + 1341, + 1342, + 3945, + 1343, + 1344, + 1345, + 1346, + 1347, + 1348, + 1349, + 1350, + 1351, + 1352, + 1353, + 1354, + 3975, + 1357, + 1358, + 1362, + 1364, + 1365, + 1366, + 1367, + 1384, + 1385, + 1386, + 1387, + 1388, + 1389, + 1390, + 3978, + 1391, + 1730, + 4114, + 1731, + 1732, + 1733, + 4107, + 1734, + 1735, + 1736, + 1737, + 1738; + 0.605239, + 0.605239, + 0.605239, + 0.605239, + 0.208568, + 0.208568, + 0.332183, + 0.332183, + 0.490972, + 0.001349, + 0.378335, + 0.378335, + 0.505176, + 0.547675, + 0.378478, + 0.378478, + 0.520681, + 0.520681, + 0.514052, + 0.514052, + 0.514052, + 0.489167, + 0.489167, + 0.500779, + 0.500779, + 0.344750, + 0.344750, + 0.344750, + 0.444251, + 0.444251, + 0.422197, + 0.422197, + 0.459563, + 0.459563, + 1.000000, + 1.000000, + 0.523285, + 0.702523, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.754566, + 0.754566, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999998, + 0.999998, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.937900, + 0.937900, + 0.843455, + 0.843455, + 1.000000, + 1.000000, + 0.692347, + 0.536598, + 0.635737, + 0.793743, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.562271, + 1.000000, + 0.606859, + 0.525610, + 0.525610, + 0.525610, + 0.505657, + 0.505657, + 0.499507, + 0.499507, + 0.502042, + 0.502042, + 0.502042, + 0.512201, + 0.512201, + 0.512201, + 0.512201, + 0.500000, + 0.500000, + 0.564140, + 0.564140, + 0.499982, + 0.499982, + 0.999997, + 0.999997, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.995135, + 0.936519, + 1.000000, + 0.999529, + 0.980016, + 0.999871, + 0.999950, + 1.000000, + 0.951632, + 0.002571, + 0.000138, + 0.003704, + 0.003704, + 0.000096, + 0.000000, + 0.000217, + 0.000002, + 0.000020, + 0.000376, + 0.001713, + 0.017345, + 0.266756, + 0.080934, + 0.226163, + 0.796931, + 1.000000, + 1.000000, + 1.000000, + 0.171247, + 0.501141, + 0.501141, + 0.569803, + 0.914754, + 0.873090, + 0.873090, + 1.000000, + 1.000000, + 0.999889, + 0.999994, + 0.979129; + -0.941743,-0.646748,0.574719,0.000000,-0.283133,-0.461979,-0.983825,0.000000,0.923060,-1.114919,0.257891,0.000000,-65.499557,30.497688,12.852692,1.000000;; + } + + SkinWeights { + "Bip01_Spine3"; + 299; + 0, + 3449, + 3429, + 3427, + 1, + 3420, + 2, + 3454, + 3, + 4, + 3453, + 5, + 4311, + 6, + 7, + 8, + 9, + 4116, + 3470, + 10, + 4118, + 12, + 13, + 15, + 16, + 3424, + 17, + 18, + 19, + 20, + 3452, + 21, + 22, + 30, + 31, + 3460, + 42, + 3457, + 43, + 3445, + 58, + 62, + 3421, + 68, + 3456, + 69, + 70, + 71, + 3455, + 72, + 3940, + 73, + 4110, + 4109, + 74, + 4108, + 75, + 3980, + 76, + 4113, + 3936, + 77, + 3939, + 78, + 3979, + 79, + 3981, + 85, + 86, + 4310, + 87, + 4428, + 88, + 4360, + 3459, + 89, + 3467, + 90, + 3468, + 91, + 3466, + 92, + 3462, + 93, + 3463, + 3458, + 94, + 3464, + 95, + 96, + 97, + 98, + 99, + 3469, + 100, + 101, + 3461, + 102, + 3472, + 103, + 3473, + 104, + 3465, + 105, + 3474, + 107, + 108, + 109, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 137, + 3509, + 3508, + 3489, + 138, + 3482, + 139, + 3514, + 140, + 3513, + 141, + 4309, + 142, + 143, + 144, + 4119, + 3527, + 146, + 147, + 148, + 149, + 150, + 3512, + 151, + 152, + 160, + 161, + 3518, + 169, + 3504, + 184, + 3483, + 190, + 3516, + 191, + 192, + 193, + 3515, + 194, + 3759, + 195, + 3935, + 3934, + 196, + 3933, + 197, + 3800, + 198, + 3760, + 3756, + 199, + 4112, + 200, + 3799, + 201, + 3801, + 206, + 4427, + 207, + 4417, + 3755, + 208, + 3525, + 209, + 3524, + 210, + 3520, + 211, + 3521, + 3517, + 212, + 3522, + 213, + 214, + 215, + 216, + 3526, + 217, + 218, + 3519, + 219, + 3529, + 220, + 3530, + 221, + 3523, + 222, + 3531, + 224, + 225, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 845, + 846, + 851, + 852, + 856, + 3757, + 943, + 946, + 1285, + 4111, + 1286, + 1287, + 1288, + 3932, + 1291, + 1293, + 1296, + 1297, + 1301, + 3938, + 1388, + 1391, + 1730, + 4114, + 1731, + 1732, + 1733, + 4107, + 1736, + 1738, + 1739, + 4115, + 1740, + 4117, + 1741, + 3471, + 1742, + 1743, + 3528, + 1744, + 1745, + 2101, + 2102, + 2103, + 2104, + 2105, + 2108, + 2109, + 4312, + 2110, + 4315, + 2111, + 2112, + 2392, + 2397, + 2398, + 4317, + 2399, + 4313, + 2400, + 2401, + 2416, + 2422, + 2423, + 3052, + 3055, + 3056, + 4314, + 3057, + 4373, + 3058, + 3059, + 3071, + 3076, + 3080, + 3081; + 0.394761, + 0.394761, + 0.394761, + 0.394761, + 1.000000, + 1.000000, + 0.791431, + 0.791431, + 0.934090, + 0.667817, + 0.667817, + 0.407500, + 0.407500, + 1.000000, + 0.509028, + 0.500334, + 0.742859, + 0.742859, + 0.742859, + 0.646150, + 0.646150, + 0.000826, + 1.000000, + 0.998651, + 1.000000, + 1.000000, + 0.002232, + 0.000057, + 0.000008, + 0.694294, + 0.694294, + 0.500000, + 0.500000, + 0.005182, + 1.000000, + 1.000000, + 0.000077, + 0.000077, + 0.000000, + 0.000000, + 0.000000, + 0.999987, + 0.999987, + 0.621665, + 0.621665, + 0.494824, + 0.452325, + 0.621522, + 0.621522, + 0.479319, + 0.479319, + 0.485948, + 0.485948, + 0.485948, + 0.510833, + 0.510833, + 0.499221, + 0.499221, + 0.655250, + 0.655250, + 0.655250, + 0.555749, + 0.555749, + 0.577803, + 0.577803, + 0.540437, + 0.540437, + 0.500000, + 0.518319, + 0.518319, + 0.330664, + 0.330664, + 0.499933, + 0.499933, + 0.499933, + 0.506729, + 0.506729, + 0.491771, + 0.491771, + 0.496988, + 0.496988, + 0.458505, + 0.458505, + 0.478085, + 0.478085, + 0.478085, + 0.509104, + 0.509104, + 0.500228, + 0.500000, + 0.500234, + 0.500000, + 0.500000, + 0.500000, + 0.098269, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.764280, + 1.000000, + 0.273957, + 0.495039, + 0.559469, + 0.432520, + 0.464423, + 0.334571, + 0.396879, + 0.503634, + 0.500003, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.388147, + 0.388147, + 0.388147, + 0.388147, + 1.000000, + 1.000000, + 0.792207, + 0.792207, + 0.667938, + 0.667938, + 0.401391, + 0.401391, + 1.000000, + 0.507531, + 0.789169, + 0.789169, + 0.789169, + 1.000000, + 0.998645, + 0.000055, + 0.000007, + 0.696843, + 0.696843, + 0.500000, + 0.500000, + 0.004977, + 1.000000, + 1.000000, + 0.000000, + 0.000000, + 0.999989, + 0.999989, + 0.622978, + 0.622978, + 0.494410, + 0.451237, + 0.619803, + 0.619803, + 0.471398, + 0.471398, + 0.488642, + 0.488642, + 0.488642, + 0.508940, + 0.508940, + 0.499498, + 0.499498, + 0.650302, + 0.650302, + 0.650302, + 0.577673, + 0.577673, + 0.575168, + 0.575168, + 0.540492, + 0.540492, + 0.329189, + 0.329189, + 0.499882, + 0.499882, + 0.499882, + 0.491653, + 0.491653, + 0.496898, + 0.496898, + 0.457891, + 0.457891, + 0.477594, + 0.477594, + 0.477594, + 0.510518, + 0.510518, + 0.500267, + 0.500000, + 0.500219, + 0.500000, + 0.500000, + 0.097802, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.770983, + 1.000000, + 0.494890, + 0.432088, + 0.463982, + 0.333385, + 0.395719, + 0.504955, + 0.500005, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.500000, + 0.500000, + 0.477163, + 0.297364, + 0.247515, + 0.247515, + 0.204713, + 0.827083, + 0.498934, + 0.498934, + 0.430994, + 0.086300, + 0.128177, + 0.128177, + 0.000124, + 0.021432, + 0.476715, + 0.297477, + 0.245434, + 0.245434, + 0.203069, + 0.828753, + 0.498859, + 0.498859, + 0.430197, + 0.085246, + 0.126910, + 0.126910, + 0.000111, + 0.020871, + 0.652828, + 0.652828, + 0.678677, + 0.678677, + 0.750800, + 0.750800, + 0.670469, + 0.786977, + 0.786977, + 0.692151, + 0.719323, + 0.510218, + 0.490223, + 0.490260, + 0.509821, + 0.001010, + 0.001002, + 0.000093, + 0.000093, + 0.000094, + 0.000094, + 0.000638, + 0.000637, + 0.000001, + 0.000017, + 0.000001, + 0.000001, + 0.000058, + 0.000058, + 0.000607, + 0.000268, + 0.002483, + 0.503803, + 0.525515, + 0.000001, + 0.000612, + 0.000059, + 0.000059, + 0.000001, + 0.000001, + 0.000018, + 0.000271, + 0.420472, + 0.002513, + 0.523967, + 0.503150; + -0.000000,-0.000002,1.278853,0.000000,1.100796,0.223046,0.000001,0.000000,-0.291970,1.440953,0.000002,0.000000,28.876726,-65.051079,-0.142296,1.000000;; + } + + SkinWeights { + "Bip01_Neck"; + 214; + 3, + 5, + 4311, + 8, + 9, + 4116, + 3470, + 10, + 4118, + 21, + 22, + 85, + 86, + 4310, + 87, + 4428, + 88, + 4360, + 3459, + 89, + 3467, + 90, + 3468, + 91, + 3466, + 92, + 3462, + 93, + 3463, + 3458, + 94, + 3464, + 95, + 96, + 97, + 98, + 99, + 3469, + 106, + 107, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 123, + 141, + 4309, + 144, + 4119, + 3527, + 151, + 152, + 206, + 4427, + 207, + 4417, + 3755, + 208, + 3525, + 209, + 3524, + 210, + 3520, + 211, + 3521, + 3517, + 212, + 3522, + 213, + 214, + 215, + 216, + 3526, + 223, + 224, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 238, + 845, + 846, + 1739, + 4115, + 1740, + 4117, + 1741, + 3471, + 1742, + 1743, + 3528, + 1744, + 1745, + 1754, + 4307, + 4249, + 1786, + 4351, + 4204, + 4183, + 1787, + 4356, + 1917, + 4409, + 4295, + 4290, + 4267, + 1918, + 4415, + 2091, + 2092, + 2093, + 4304, + 2094, + 4296, + 2095, + 4298, + 2096, + 4301, + 2097, + 4303, + 2098, + 4305, + 2099, + 2100, + 2101, + 2102, + 2103, + 2104, + 2105, + 2106, + 2107, + 2108, + 2393, + 2394, + 4302, + 2395, + 4323, + 2402, + 2403, + 2404, + 2405, + 4352, + 2406, + 4300, + 2407, + 2408, + 2409, + 4354, + 2410, + 4358, + 2411, + 2412, + 2413, + 2414, + 4355, + 2415, + 2416, + 2417, + 2418, + 2419, + 2420, + 2421, + 2422, + 2423, + 2426, + 4359, + 4357, + 4353, + 3049, + 4374, + 3050, + 4297, + 3051, + 3060, + 3061, + 3062, + 3063, + 3064, + 3065, + 4416, + 4411, + 3066, + 4414, + 3067, + 3068, + 3069, + 4299, + 3070, + 3071, + 3072, + 4413, + 3073, + 3074, + 3075, + 3076, + 3077, + 3078, + 3079, + 3080, + 3081, + 3086, + 4412, + 4410; + 0.065910, + 0.592500, + 0.592500, + 0.499666, + 0.257141, + 0.257141, + 0.257141, + 0.353850, + 0.353850, + 0.500000, + 0.500000, + 0.500000, + 0.481681, + 0.481681, + 0.669336, + 0.669336, + 0.500067, + 0.500067, + 0.500067, + 0.493271, + 0.493271, + 0.508229, + 0.508229, + 0.503012, + 0.503012, + 0.541495, + 0.541495, + 0.521915, + 0.521915, + 0.521915, + 0.490896, + 0.490896, + 0.499772, + 0.500000, + 0.499766, + 0.500000, + 0.500000, + 0.500000, + 1.000000, + 0.235720, + 0.726043, + 1.000000, + 0.504961, + 0.440531, + 0.567480, + 0.535577, + 0.665429, + 0.603121, + 0.496366, + 0.499997, + 0.000000, + 0.598609, + 0.598609, + 0.210831, + 0.210831, + 0.210831, + 0.500000, + 0.500000, + 0.670811, + 0.670811, + 0.500118, + 0.500118, + 0.500118, + 0.508347, + 0.508347, + 0.503102, + 0.503102, + 0.542109, + 0.542109, + 0.522406, + 0.522406, + 0.522406, + 0.489482, + 0.489482, + 0.499733, + 0.500000, + 0.499781, + 0.500000, + 0.500000, + 1.000000, + 0.229017, + 1.000000, + 0.505110, + 0.567912, + 0.536018, + 0.666615, + 0.604281, + 0.495045, + 0.499995, + 0.000000, + 0.500000, + 0.500000, + 0.347172, + 0.347172, + 0.321323, + 0.321323, + 0.249200, + 0.249200, + 0.329531, + 0.213023, + 0.213023, + 0.307849, + 0.280677, + 0.029899, + 0.029899, + 0.029899, + 0.000563, + 0.000563, + 0.000563, + 0.000563, + 0.447159, + 0.447159, + 0.000741, + 0.000741, + 0.000741, + 0.000741, + 0.000741, + 0.452299, + 0.452299, + 0.000256, + 0.000265, + 0.112240, + 0.112240, + 0.502882, + 0.502882, + 0.660151, + 0.660151, + 0.660342, + 0.660342, + 0.501958, + 0.501958, + 0.110146, + 0.110146, + 0.306701, + 0.307363, + 0.489782, + 0.509777, + 0.509740, + 0.490179, + 0.998990, + 0.966439, + 0.966459, + 0.998998, + 0.006305, + 0.286696, + 0.286696, + 0.102187, + 0.102187, + 0.432449, + 0.484491, + 0.144315, + 0.014990, + 0.014990, + 0.501776, + 0.501776, + 0.689126, + 0.616328, + 0.498337, + 0.498337, + 0.292995, + 0.292995, + 0.319511, + 0.489703, + 1.000000, + 0.970473, + 0.970473, + 1.000000, + 0.997517, + 0.986590, + 1.000000, + 0.043051, + 0.348847, + 0.069256, + 0.496197, + 0.474485, + 0.000614, + 0.000614, + 0.000614, + 0.000614, + 0.111179, + 0.111179, + 0.295001, + 0.295001, + 0.007394, + 0.437806, + 0.017223, + 0.151879, + 0.486630, + 0.330150, + 0.303562, + 0.303562, + 0.303562, + 0.498825, + 0.498825, + 0.615047, + 0.687810, + 0.501685, + 0.501685, + 0.491269, + 0.579528, + 0.970098, + 0.970098, + 1.000000, + 1.000000, + 0.986508, + 0.997487, + 0.046055, + 0.071046, + 0.352668, + 0.476033, + 0.496850, + 0.000875, + 0.000875, + 0.000875; + 0.000001,-0.000002,1.278853,0.000000,1.061682,-0.366513,-0.000001,0.000000,0.479769,1.389753,0.000002,0.000000,-44.801331,-49.085537,-0.142252,1.000000;; + } + + SkinWeights { + "Bip01_Spine2"; + 138; + 11, + 3423, + 3422, + 12, + 14, + 17, + 18, + 19, + 23, + 24, + 25, + 3479, + 26, + 3446, + 3425, + 27, + 3426, + 28, + 3428, + 29, + 30, + 38, + 39, + 3433, + 42, + 3457, + 43, + 3445, + 44, + 3441, + 48, + 49, + 51, + 3435, + 52, + 3436, + 53, + 3438, + 54, + 3451, + 3443, + 58, + 59, + 60, + 61, + 62, + 3421, + 63, + 66, + 3442, + 67, + 3439, + 80, + 81, + 82, + 83, + 100, + 125, + 3475, + 126, + 3480, + 127, + 3481, + 128, + 3476, + 130, + 132, + 133, + 134, + 135, + 145, + 3485, + 3484, + 148, + 149, + 153, + 154, + 155, + 3536, + 156, + 3505, + 3486, + 157, + 3487, + 158, + 3488, + 159, + 160, + 166, + 3493, + 169, + 3504, + 170, + 3500, + 172, + 173, + 175, + 3496, + 176, + 3495, + 177, + 3498, + 178, + 3511, + 3503, + 181, + 182, + 183, + 184, + 3483, + 185, + 188, + 3502, + 189, + 3499, + 202, + 203, + 204, + 217, + 240, + 3532, + 241, + 3537, + 242, + 3538, + 243, + 3533, + 245, + 247, + 248, + 249, + 250, + 1292, + 1737, + 3418, + 4430, + 3419, + 4431; + 1.000000, + 1.000000, + 1.000000, + 0.999173, + 0.999963, + 0.997768, + 0.999943, + 0.999992, + 1.000000, + 0.999958, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.994818, + 0.119980, + 0.012547, + 0.012547, + 0.999923, + 0.999923, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.026286, + 0.000075, + 0.992608, + 0.992608, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000013, + 0.000013, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.025573, + 0.009055, + 0.013395, + 0.009298, + 0.901731, + 0.682231, + 0.682231, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.001628, + 0.001628, + 1.000000, + 0.574870, + 1.000000, + 1.000000, + 0.000066, + 1.000000, + 1.000000, + 1.000000, + 0.999945, + 0.999993, + 1.000000, + 0.999959, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.995023, + 0.012193, + 0.012193, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.025939, + 0.000070, + 0.992952, + 0.992952, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000011, + 0.000011, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.009004, + 0.013264, + 0.009112, + 0.902198, + 0.683732, + 0.683732, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.001536, + 0.001536, + 1.000000, + 0.575759, + 1.000000, + 1.000000, + 0.000058, + 0.000008, + 0.000006, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + -0.000000,-0.000002,1.278853,0.000000,1.106257,0.194155,0.000001,0.000000,-0.254150,1.448102,0.000002,0.000000,55.345093,-65.818558,-0.142298,1.000000;; + } + + SkinWeights { + "Bip01_Spine1"; + 135; + 14, + 24, + 32, + 3434, + 33, + 3447, + 34, + 3444, + 35, + 3440, + 36, + 3430, + 37, + 38, + 39, + 3433, + 40, + 3630, + 41, + 3627, + 45, + 3632, + 3631, + 3432, + 46, + 3633, + 47, + 3628, + 48, + 49, + 50, + 51, + 3435, + 55, + 56, + 57, + 64, + 3450, + 3448, + 65, + 3437, + 80, + 81, + 82, + 83, + 84, + 3431, + 124, + 3478, + 125, + 3475, + 128, + 3476, + 129, + 3477, + 131, + 132, + 135, + 136, + 154, + 162, + 3494, + 163, + 3506, + 164, + 3501, + 165, + 3491, + 166, + 3493, + 167, + 3740, + 168, + 3738, + 171, + 3742, + 3741, + 3492, + 172, + 173, + 174, + 175, + 3496, + 179, + 180, + 186, + 3510, + 3507, + 187, + 3497, + 202, + 203, + 204, + 205, + 3490, + 239, + 3535, + 240, + 3532, + 243, + 3533, + 244, + 3534, + 246, + 247, + 250, + 251, + 428, + 3650, + 436, + 3634, + 3629, + 438, + 439, + 440, + 3616, + 441, + 442, + 444, + 452, + 3635, + 454, + 456, + 734, + 3744, + 3739, + 736, + 737, + 738, + 3728, + 746, + 3743, + 748, + 847, + 848; + 0.000037, + 0.000042, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999541, + 0.880020, + 0.987453, + 0.987453, + 0.355829, + 0.355829, + 0.539595, + 0.539595, + 0.478610, + 0.478610, + 0.478610, + 0.478610, + 0.193697, + 0.193697, + 0.504065, + 0.504065, + 0.973714, + 0.999925, + 1.000000, + 0.007392, + 0.007392, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.974427, + 0.990945, + 0.986605, + 0.990703, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.317769, + 0.317769, + 0.998372, + 0.998372, + 1.000000, + 1.000000, + 1.000000, + 0.425130, + 0.999934, + 1.000000, + 0.000041, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.987807, + 0.987807, + 0.355636, + 0.355636, + 0.539137, + 0.539137, + 0.495096, + 0.495096, + 0.495096, + 0.495096, + 0.974061, + 0.999930, + 1.000000, + 0.007048, + 0.007048, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.990996, + 0.986736, + 0.990888, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.316268, + 0.316268, + 0.998464, + 0.998464, + 1.000000, + 1.000000, + 1.000000, + 0.424241, + 0.999942, + 1.000000, + 0.137283, + 0.137283, + 0.274429, + 0.274429, + 0.274429, + 0.292184, + 0.556285, + 0.480198, + 0.480198, + 0.108993, + 0.506586, + 0.129106, + 0.205417, + 0.205417, + 0.087526, + 0.173935, + 0.274599, + 0.274599, + 0.274599, + 0.292740, + 0.555983, + 0.480227, + 0.480227, + 0.205575, + 0.205575, + 0.174090, + 0.999988, + 0.999991; + -0.000000,-0.000002,1.278853,0.000000,1.106257,0.194155,0.000001,0.000000,-0.254150,1.448102,0.000002,0.000000,83.527077,-65.841003,-0.142298,1.000000;; + } + + SkinWeights { + "Bip01_R_Clavicle"; + 2; + 20, + 3452; + 0.305706, + 0.305706; + -1.253361,-0.000002,0.254069,0.000000,-0.218659,-0.223923,-1.078679,0.000000,0.058235,-1.440720,0.287274,0.000000,-7.853105,62.204407,2.554618,1.000000;; + } + + SkinWeights { + "Bip01_Spine"; + 196; + 37, + 40, + 3630, + 41, + 3627, + 45, + 3632, + 3631, + 3432, + 46, + 3633, + 47, + 3628, + 167, + 3740, + 168, + 3738, + 171, + 3742, + 3741, + 3492, + 252, + 253, + 256, + 257, + 3568, + 258, + 259, + 260, + 3540, + 263, + 264, + 3641, + 281, + 3604, + 289, + 3605, + 397, + 400, + 408, + 417, + 421, + 427, + 3619, + 428, + 3650, + 429, + 3626, + 430, + 431, + 3620, + 432, + 3621, + 433, + 3623, + 434, + 3622, + 435, + 3625, + 3624, + 3539, + 436, + 3634, + 3629, + 437, + 3638, + 438, + 439, + 440, + 3616, + 441, + 442, + 443, + 444, + 445, + 446, + 3637, + 447, + 448, + 449, + 450, + 451, + 3617, + 452, + 3635, + 453, + 3636, + 3618, + 454, + 455, + 456, + 457, + 458, + 459, + 460, + 3639, + 461, + 3640, + 462, + 463, + 464, + 465, + 466, + 467, + 468, + 469, + 470, + 471, + 473, + 474, + 481, + 482, + 483, + 484, + 548, + 551, + 554, + 555, + 556, + 559, + 560, + 561, + 562, + 3651, + 565, + 582, + 3714, + 590, + 3715, + 698, + 701, + 709, + 718, + 727, + 3730, + 728, + 3737, + 729, + 3731, + 730, + 3732, + 731, + 3734, + 732, + 3733, + 733, + 3736, + 3735, + 3652, + 734, + 3744, + 3739, + 735, + 3746, + 736, + 737, + 738, + 3728, + 739, + 740, + 741, + 742, + 743, + 744, + 745, + 3727, + 746, + 3743, + 747, + 3745, + 3729, + 748, + 749, + 750, + 751, + 752, + 753, + 754, + 755, + 756, + 757, + 758, + 759, + 760, + 761, + 763, + 764, + 771, + 772, + 773, + 774, + 838, + 841, + 844, + 847, + 848; + 0.000459, + 0.644171, + 0.644171, + 0.460405, + 0.460405, + 0.521390, + 0.521390, + 0.521390, + 0.521390, + 0.806303, + 0.806303, + 0.495935, + 0.495935, + 0.644364, + 0.644364, + 0.460863, + 0.460863, + 0.504904, + 0.504904, + 0.504904, + 0.504904, + 0.490317, + 1.000000, + 0.500000, + 1.000000, + 1.000000, + 1.000000, + 0.452523, + 1.000000, + 1.000000, + 1.000000, + 0.500000, + 0.500000, + 0.491192, + 0.491192, + 0.000010, + 0.000010, + 0.480348, + 0.000000, + 0.000731, + 0.000216, + 0.500000, + 1.000000, + 1.000000, + 0.862717, + 0.862717, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.725571, + 0.725571, + 0.725571, + 1.000000, + 1.000000, + 0.707816, + 0.443715, + 0.519802, + 0.519802, + 0.891007, + 0.493414, + 1.000000, + 0.870894, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.794583, + 0.794583, + 1.000000, + 1.000000, + 1.000000, + 0.912474, + 1.000000, + 0.826065, + 1.000000, + 1.000000, + 0.500000, + 1.000000, + 1.000000, + 0.500000, + 0.500000, + 1.000000, + 0.500000, + 1.000000, + 0.714864, + 0.500015, + 0.495456, + 0.537862, + 1.000000, + 0.362112, + 0.003282, + 1.000000, + 0.335473, + 1.000000, + 1.000000, + 0.500000, + 1.000000, + 0.061459, + 0.406936, + 0.725066, + 1.000000, + 1.000000, + 0.500000, + 1.000000, + 0.452941, + 1.000000, + 1.000000, + 1.000000, + 0.491389, + 0.491389, + 0.000010, + 0.000010, + 0.480816, + 0.000000, + 0.000763, + 0.000228, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.725401, + 0.725401, + 0.725401, + 1.000000, + 1.000000, + 0.707260, + 0.444017, + 0.519773, + 0.519773, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.794425, + 0.794425, + 1.000000, + 1.000000, + 1.000000, + 0.825910, + 1.000000, + 1.000000, + 0.500000, + 1.000000, + 0.500000, + 1.000000, + 0.716189, + 0.500014, + 0.495465, + 0.537762, + 1.000000, + 0.370655, + 0.003429, + 1.000000, + 0.336846, + 1.000000, + 1.000000, + 0.500000, + 1.000000, + 0.062153, + 0.407168, + 1.000000, + 0.000012, + 0.000009; + 0.000000,-0.000002,1.278853,0.000000,1.123165,-0.000895,-0.000000,0.000000,0.001171,1.470235,0.000002,0.000000,99.003029,-79.367149,-0.142336,1.000000;; + } + + SkinWeights { + "Bip01_L_UpperArm"; + 157; + 137, + 3509, + 3508, + 3489, + 139, + 3514, + 140, + 3513, + 143, + 147, + 190, + 3516, + 191, + 192, + 193, + 3515, + 194, + 3759, + 195, + 3935, + 3934, + 196, + 3933, + 197, + 3800, + 198, + 3760, + 3756, + 199, + 4112, + 200, + 3799, + 201, + 3801, + 849, + 850, + 851, + 852, + 853, + 3770, + 854, + 3758, + 855, + 856, + 3757, + 857, + 3777, + 3769, + 858, + 3768, + 859, + 3774, + 860, + 3771, + 3761, + 861, + 3779, + 3772, + 862, + 3763, + 863, + 3765, + 864, + 865, + 866, + 867, + 868, + 869, + 870, + 3778, + 871, + 872, + 873, + 3780, + 874, + 875, + 876, + 877, + 878, + 879, + 3791, + 3788, + 3767, + 880, + 3790, + 881, + 3786, + 882, + 3785, + 883, + 3796, + 3789, + 3766, + 884, + 3783, + 885, + 3797, + 886, + 3782, + 887, + 3773, + 888, + 3781, + 3775, + 889, + 3776, + 890, + 891, + 892, + 893, + 3762, + 894, + 895, + 896, + 897, + 3764, + 898, + 899, + 900, + 901, + 902, + 903, + 904, + 905, + 906, + 907, + 908, + 909, + 3795, + 912, + 3792, + 913, + 917, + 919, + 920, + 921, + 922, + 939, + 940, + 941, + 942, + 943, + 944, + 945, + 3798, + 946, + 1285, + 4111, + 1286, + 1287, + 1288, + 3932, + 1289, + 1290, + 1291, + 1292, + 1293; + 0.611853, + 0.611853, + 0.611853, + 0.611853, + 0.207793, + 0.207793, + 0.332061, + 0.332061, + 0.492469, + 0.001355, + 0.377022, + 0.377022, + 0.505590, + 0.548763, + 0.380197, + 0.380197, + 0.528602, + 0.528602, + 0.511358, + 0.511358, + 0.511358, + 0.491060, + 0.491060, + 0.500502, + 0.500502, + 0.349698, + 0.349698, + 0.349698, + 0.422326, + 0.422326, + 0.424832, + 0.424832, + 0.459508, + 0.459508, + 1.000000, + 1.000000, + 0.522837, + 0.702636, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.752485, + 0.752485, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999998, + 0.999998, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.940238, + 0.940238, + 0.843017, + 0.843017, + 1.000000, + 1.000000, + 0.692400, + 0.538017, + 0.636978, + 0.792629, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.562516, + 1.000000, + 0.609501, + 0.526981, + 0.526981, + 0.526981, + 0.526981, + 0.506875, + 0.506875, + 0.499506, + 0.499506, + 0.502402, + 0.502402, + 0.512438, + 0.512438, + 0.512438, + 0.512438, + 0.500000, + 0.500000, + 0.564264, + 0.564264, + 0.499990, + 0.499990, + 0.999998, + 0.999998, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.995240, + 0.937903, + 1.000000, + 0.999588, + 0.981116, + 0.999872, + 0.999950, + 1.000000, + 0.953465, + 0.002703, + 0.000144, + 0.003856, + 0.003856, + 0.000096, + 0.000096, + 0.000000, + 0.000218, + 0.000002, + 0.000021, + 0.000402, + 0.001797, + 0.017999, + 0.269651, + 0.082041, + 0.229561, + 0.795287, + 1.000000, + 1.000000, + 1.000000, + 0.172917, + 0.501066, + 0.501066, + 0.569005, + 0.913700, + 0.871823, + 0.871823, + 1.000000, + 1.000000, + 0.999876, + 0.999992, + 0.978568; + 0.941746,0.646745,0.574718,0.000000,-0.283133,-0.461979,0.983825,0.000000,0.923057,-1.114921,-0.257893,0.000000,-65.708862,30.353960,-12.980427,1.000000;; + } + + SkinWeights { + "Bip01_L_Clavicle"; + 2; + 150, + 3512; + 0.303157, + 0.303157; + 1.253361,-0.000002,0.254069,0.000000,-0.218659,-0.223923,1.078679,0.000000,0.058231,-1.440720,-0.287275,0.000000,-8.131670,62.204407,-2.611076,1.000000;; + } + + SkinWeights { + "Bip01_Pelvis"; + 33; + 252, + 254, + 3541, + 256, + 259, + 264, + 3641, + 421, + 459, + 461, + 3640, + 463, + 465, + 466, + 467, + 468, + 474, + 483, + 554, + 557, + 3653, + 559, + 561, + 751, + 753, + 755, + 756, + 757, + 758, + 764, + 773, + 1805, + 1936; + 0.509683, + 0.606020, + 0.606020, + 0.500000, + 0.547477, + 0.500000, + 0.500000, + 0.500000, + 0.500000, + 0.500000, + 0.500000, + 0.500000, + 0.285136, + 0.499985, + 0.504544, + 0.462138, + 0.664527, + 0.500000, + 0.274934, + 0.605750, + 0.605750, + 0.500000, + 0.547059, + 0.500000, + 0.500000, + 0.283811, + 0.499986, + 0.504535, + 0.462238, + 0.663154, + 0.500000, + 1.000000, + 1.000000; + -0.000002,0.000004,1.278853,0.000000,1.123165,-0.000000,0.000002,0.000000,0.000000,1.470235,-0.000004,0.000000,126.489456,-70.579353,-0.141854,1.000000;; + } + + SkinWeights { + "Bip01_R_Thigh"; + 144; + 254, + 3541, + 255, + 261, + 3567, + 262, + 265, + 266, + 3611, + 267, + 268, + 3646, + 269, + 3544, + 270, + 273, + 274, + 3542, + 275, + 278, + 3645, + 279, + 280, + 3543, + 281, + 3604, + 282, + 3602, + 283, + 284, + 285, + 286, + 3609, + 287, + 288, + 289, + 3605, + 311, + 313, + 322, + 3647, + 323, + 324, + 332, + 3610, + 3572, + 333, + 334, + 3607, + 335, + 336, + 337, + 3603, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 386, + 387, + 388, + 389, + 390, + 3608, + 391, + 3606, + 392, + 393, + 3600, + 394, + 3612, + 3601, + 395, + 3613, + 396, + 397, + 398, + 399, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 418, + 419, + 420, + 470, + 471, + 472, + 475, + 476, + 477, + 478, + 479, + 480, + 517, + 518, + 524, + 525, + 3644, + 533, + 3573, + 534, + 535, + 536, + 537, + 538, + 539, + 540, + 541, + 542, + 543, + 544, + 546, + 3649, + 547, + 3648, + 548, + 549, + 550, + 551, + 552, + 553, + 563, + 3679, + 581, + 3655, + 839; + 0.393980, + 0.393980, + 1.000000, + 0.796821, + 0.796821, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.973372, + 0.426944, + 0.426944, + 1.000000, + 1.000000, + 0.544990, + 0.984533, + 0.999195, + 0.999195, + 0.743688, + 0.445745, + 0.445745, + 1.000000, + 0.984714, + 0.984714, + 0.508808, + 0.508808, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999990, + 0.999990, + 1.000000, + 1.000000, + 0.000009, + 0.000009, + 0.000489, + 0.002645, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000320, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.908716, + 0.954129, + 0.999907, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.519652, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999269, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999784, + 1.000000, + 1.000000, + 1.000000, + 0.637888, + 0.996718, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000011, + 0.000008, + 0.000000, + 0.000000, + 0.000000, + 0.798798, + 0.798798, + 0.883879, + 0.998063, + 0.778724, + 0.679390, + 0.492835, + 0.737200, + 0.477944, + 0.442104, + 0.471318, + 1.000000, + 0.988985, + 0.691131, + 0.691131, + 0.977434, + 0.977434, + 0.938541, + 0.887283, + 1.000000, + 0.593064, + 1.000000, + 0.999984, + 0.204819, + 0.204819, + 0.015759, + 0.015759, + 0.114201; + -0.122195,-0.009615,-1.272965,0.000000,-1.117778,0.024505,0.107113,0.000000,0.030875,1.469844,-0.014066,0.000000,-130.245026,-68.027489,-17.265657,1.000000;; + } + + SkinWeights { + "Bip01_L_Thigh"; + 144; + 261, + 3567, + 280, + 3543, + 549, + 557, + 3653, + 558, + 563, + 3679, + 564, + 566, + 567, + 3721, + 568, + 569, + 3751, + 570, + 3656, + 571, + 574, + 575, + 3654, + 576, + 579, + 3750, + 580, + 581, + 3655, + 582, + 3714, + 583, + 3712, + 584, + 585, + 586, + 587, + 3719, + 588, + 589, + 590, + 3715, + 612, + 614, + 623, + 3752, + 624, + 625, + 633, + 3720, + 3683, + 634, + 635, + 3717, + 636, + 637, + 638, + 3713, + 639, + 640, + 641, + 642, + 643, + 644, + 645, + 646, + 687, + 688, + 689, + 690, + 691, + 3718, + 692, + 3716, + 693, + 694, + 3710, + 695, + 3722, + 3711, + 696, + 3723, + 697, + 698, + 699, + 700, + 701, + 702, + 703, + 704, + 705, + 706, + 707, + 708, + 709, + 710, + 711, + 712, + 713, + 714, + 715, + 716, + 717, + 718, + 719, + 720, + 721, + 760, + 761, + 762, + 765, + 766, + 767, + 768, + 769, + 770, + 807, + 808, + 814, + 815, + 3749, + 823, + 3684, + 824, + 825, + 826, + 827, + 828, + 829, + 830, + 831, + 832, + 833, + 834, + 836, + 3754, + 837, + 3753, + 838, + 839, + 840, + 841, + 842, + 843; + 0.203179, + 0.203179, + 0.015286, + 0.015286, + 0.112717, + 0.394250, + 0.394250, + 1.000000, + 0.795181, + 0.795181, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.973936, + 0.428996, + 0.428996, + 1.000000, + 1.000000, + 0.544972, + 0.984486, + 0.999176, + 0.999176, + 0.742419, + 0.445910, + 0.445910, + 1.000000, + 0.984241, + 0.984241, + 0.508611, + 0.508611, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999990, + 0.999990, + 1.000000, + 1.000000, + 0.000009, + 0.000009, + 0.000473, + 0.002664, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000318, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.908719, + 0.953856, + 0.999909, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.519184, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999237, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999772, + 1.000000, + 1.000000, + 1.000000, + 0.629345, + 0.996571, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000011, + 0.000008, + 0.000000, + 0.000000, + 0.000000, + 0.800783, + 0.800783, + 0.885426, + 0.998182, + 0.778669, + 0.680971, + 0.493117, + 0.738892, + 0.478082, + 0.442423, + 0.471379, + 1.000000, + 0.989147, + 0.690110, + 0.690110, + 0.978029, + 0.978029, + 0.937847, + 0.885799, + 1.000000, + 0.592832, + 1.000000, + 0.999985; + 0.122195,0.009619,-1.272965,0.000000,-1.117778,0.024505,-0.107113,0.000000,0.030875,1.469844,0.014070,0.000000,-130.272186,-68.029633,17.548590,1.000000;; + } + + SkinWeights { + "Bip01_R_Calf"; + 195; + 267, + 268, + 3646, + 270, + 271, + 272, + 273, + 274, + 3542, + 275, + 276, + 277, + 278, + 3645, + 287, + 293, + 3550, + 298, + 3554, + 299, + 3552, + 303, + 3615, + 3562, + 307, + 3614, + 3576, + 309, + 3561, + 310, + 3553, + 312, + 314, + 315, + 316, + 317, + 3566, + 318, + 3565, + 319, + 320, + 321, + 322, + 3647, + 323, + 324, + 325, + 326, + 327, + 3642, + 328, + 329, + 3643, + 330, + 331, + 334, + 3607, + 336, + 343, + 344, + 345, + 346, + 347, + 3582, + 348, + 349, + 3581, + 350, + 3593, + 3575, + 351, + 3592, + 352, + 3588, + 353, + 3587, + 354, + 3598, + 355, + 3594, + 356, + 3595, + 357, + 3591, + 3577, + 358, + 3583, + 359, + 3584, + 360, + 3585, + 361, + 3589, + 362, + 3596, + 363, + 3599, + 364, + 3586, + 365, + 3590, + 3580, + 366, + 3597, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 385, + 425, + 485, + 486, + 487, + 488, + 489, + 490, + 3563, + 491, + 492, + 3564, + 493, + 494, + 495, + 496, + 497, + 498, + 499, + 500, + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 3569, + 513, + 514, + 515, + 516, + 3570, + 517, + 518, + 519, + 520, + 521, + 522, + 523, + 524, + 525, + 3644, + 526, + 527, + 528, + 529, + 530, + 3571, + 531, + 532, + 533, + 3573, + 534, + 535, + 536, + 537, + 538, + 539, + 540, + 541, + 542, + 544, + 545, + 546, + 3649, + 547, + 3648, + 553; + 0.026628, + 0.573056, + 0.573056, + 0.455011, + 0.248355, + 0.607645, + 0.015467, + 0.000805, + 0.000805, + 0.256312, + 0.990209, + 0.999682, + 0.554255, + 0.554255, + 0.000000, + 0.000163, + 0.000163, + 0.006766, + 0.006766, + 0.000001, + 0.000001, + 0.274225, + 0.274225, + 0.274225, + 0.472155, + 0.472155, + 0.472155, + 0.000165, + 0.000165, + 0.003872, + 0.003872, + 1.000000, + 0.358415, + 0.498074, + 0.206102, + 0.997888, + 0.997888, + 0.519331, + 0.519331, + 1.000000, + 0.999600, + 1.000000, + 0.999990, + 0.999990, + 0.999511, + 0.997355, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000000, + 0.000000, + 0.999680, + 0.091284, + 0.045871, + 0.000094, + 0.081106, + 0.000049, + 0.000049, + 0.472477, + 0.002229, + 0.002229, + 0.006004, + 0.006004, + 0.006004, + 0.062354, + 0.062354, + 0.261482, + 0.261482, + 0.447819, + 0.447819, + 0.390951, + 0.390951, + 0.607455, + 0.607455, + 0.319347, + 0.319347, + 0.002868, + 0.002868, + 0.002868, + 0.054570, + 0.054570, + 0.134541, + 0.134541, + 0.093624, + 0.093624, + 0.539311, + 0.539311, + 0.191663, + 0.191663, + 0.179730, + 0.179730, + 0.056340, + 0.056340, + 0.731088, + 0.731088, + 0.731088, + 0.319088, + 0.319088, + 0.000359, + 0.003064, + 0.049797, + 0.236320, + 0.425663, + 0.352796, + 0.823837, + 0.413038, + 0.000386, + 0.030880, + 0.090852, + 0.059474, + 0.715907, + 0.138563, + 0.128868, + 0.029103, + 0.898838, + 0.279490, + 0.056695, + 0.028800, + 0.011590, + 1.000000, + 1.000000, + 0.465069, + 0.852364, + 0.852364, + 0.999499, + 0.505223, + 0.505223, + 0.499388, + 0.444644, + 0.999998, + 0.999999, + 0.999981, + 0.091767, + 0.242068, + 0.959793, + 0.397987, + 0.340201, + 0.504990, + 0.489005, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.998151, + 1.000000, + 1.000000, + 0.539095, + 0.966305, + 1.000000, + 0.999994, + 0.999994, + 0.999989, + 0.999992, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.201202, + 0.201202, + 0.116121, + 0.001937, + 0.221276, + 0.320610, + 0.507165, + 0.262800, + 0.522056, + 0.557896, + 0.528682, + 0.011015, + 1.000000, + 0.308869, + 0.308869, + 0.022566, + 0.022566, + 0.000016; + -0.120906,-0.020142,-1.272965,0.000000,-1.115712,-0.072214,0.107113,0.000000,-0.096302,1.467010,-0.014066,0.000000,-242.661957,-89.338974,-17.265659,1.000000;; + } + + SkinWeights { + "Bip01_R_Foot"; + 153; + 271, + 272, + 276, + 277, + 290, + 3559, + 3547, + 291, + 3548, + 292, + 3549, + 293, + 3550, + 294, + 3551, + 295, + 3558, + 3557, + 296, + 3556, + 297, + 3555, + 298, + 3554, + 299, + 3552, + 300, + 3546, + 301, + 302, + 303, + 3615, + 3562, + 304, + 3560, + 305, + 306, + 307, + 3614, + 3576, + 308, + 3579, + 3578, + 309, + 3561, + 310, + 3553, + 314, + 315, + 316, + 317, + 3566, + 318, + 3565, + 319, + 320, + 321, + 346, + 347, + 3582, + 348, + 349, + 3581, + 350, + 3593, + 3575, + 351, + 3592, + 352, + 3588, + 353, + 3587, + 354, + 3598, + 355, + 3594, + 356, + 3595, + 357, + 3591, + 3577, + 358, + 3583, + 359, + 3584, + 360, + 3585, + 361, + 3589, + 362, + 3596, + 363, + 3599, + 364, + 3586, + 365, + 3590, + 3580, + 366, + 3597, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 385, + 422, + 423, + 3574, + 424, + 3545, + 425, + 426, + 485, + 486, + 487, + 488, + 489, + 490, + 3563, + 491, + 492, + 3564, + 493, + 494, + 495, + 496, + 497, + 498, + 499, + 500, + 501, + 502, + 503, + 504, + 511, + 513, + 514, + 516, + 3570; + 0.751645, + 0.392355, + 0.009791, + 0.000318, + 0.000001, + 0.000001, + 0.000001, + 0.057440, + 0.057440, + 1.000000, + 1.000000, + 0.999837, + 0.999837, + 1.000000, + 1.000000, + 0.000037, + 0.000037, + 0.000037, + 0.450821, + 0.450821, + 1.000000, + 1.000000, + 0.993234, + 0.993234, + 0.999999, + 0.999999, + 0.000045, + 0.000045, + 0.480823, + 0.999943, + 0.725775, + 0.725775, + 0.725775, + 0.000432, + 0.000432, + 0.558857, + 1.000000, + 0.527845, + 0.527845, + 0.527845, + 1.000000, + 1.000000, + 1.000000, + 0.999835, + 0.999835, + 0.996128, + 0.996128, + 0.641585, + 0.501926, + 0.793898, + 0.002112, + 0.002112, + 0.480669, + 0.480669, + 0.000000, + 0.000400, + 0.000000, + 0.918894, + 0.999951, + 0.999951, + 0.527523, + 0.997771, + 0.997771, + 0.993996, + 0.993996, + 0.993996, + 0.937646, + 0.937646, + 0.738518, + 0.738518, + 0.552181, + 0.552181, + 0.609049, + 0.609049, + 0.392545, + 0.392545, + 0.680653, + 0.680653, + 0.997131, + 0.997131, + 0.997131, + 0.945430, + 0.945430, + 0.865459, + 0.865459, + 0.906376, + 0.906376, + 0.460689, + 0.460689, + 0.808337, + 0.808337, + 0.820270, + 0.820270, + 0.943660, + 0.943660, + 0.268912, + 0.268912, + 0.268912, + 0.680912, + 0.680912, + 1.000000, + 0.999641, + 0.996936, + 0.950203, + 0.763680, + 0.574337, + 0.647204, + 0.176163, + 0.586962, + 0.999614, + 0.969120, + 0.909148, + 0.940526, + 0.284093, + 0.861437, + 0.871132, + 0.970897, + 0.101162, + 0.720510, + 0.620766, + 1.000000, + 1.000000, + 0.712070, + 0.712070, + 0.943305, + 1.000000, + 0.971200, + 0.988410, + 0.000000, + 0.000000, + 0.534931, + 0.147636, + 0.147636, + 0.000501, + 0.494777, + 0.494777, + 0.500612, + 0.555356, + 0.000002, + 0.000001, + 0.000019, + 0.908233, + 0.757932, + 0.040207, + 0.602013, + 0.659799, + 0.495010, + 0.510995, + 0.001849, + 0.460905, + 0.033695, + 0.000006, + 0.000006; + 0.000000,0.000002,-1.278853,0.000000,-1.123165,-0.000000,-0.000000,0.000000,-0.000000,1.470235,0.000002,0.000000,-363.589264,-65.273499,-52.807724,1.000000;; + } + + SkinWeights { + "Bip01_R_Toe0"; + 20; + 290, + 3559, + 3547, + 291, + 3548, + 295, + 3558, + 3557, + 296, + 3556, + 300, + 3546, + 301, + 302, + 304, + 3560, + 305, + 422, + 424, + 3545; + 0.999999, + 0.999999, + 0.999999, + 0.942560, + 0.942560, + 0.999963, + 0.999963, + 0.999963, + 0.549179, + 0.549179, + 0.999955, + 0.999955, + 0.519177, + 0.000057, + 0.999568, + 0.999568, + 0.441143, + 0.379234, + 0.287930, + 0.287930; + 0.000002,-0.000000,-1.278853,0.000000,-0.000000,1.123166,-0.000000,0.000000,1.470235,0.000000,0.000002,0.000000,-99.850662,391.012543,-52.807743,1.000000;; + } + + SkinWeights { + "Bip01_L_Calf"; + 195; + 568, + 569, + 3751, + 571, + 572, + 573, + 574, + 575, + 3654, + 576, + 577, + 578, + 579, + 3750, + 588, + 594, + 3662, + 599, + 3666, + 600, + 3664, + 604, + 3725, + 3674, + 608, + 3724, + 3687, + 610, + 3673, + 611, + 3665, + 613, + 615, + 616, + 617, + 618, + 3678, + 619, + 3676, + 620, + 621, + 622, + 623, + 3752, + 624, + 625, + 626, + 627, + 628, + 3747, + 629, + 630, + 3748, + 631, + 632, + 635, + 3717, + 637, + 644, + 645, + 646, + 647, + 648, + 3692, + 649, + 650, + 3691, + 651, + 3703, + 3686, + 652, + 3702, + 653, + 3698, + 654, + 3697, + 655, + 3708, + 656, + 3704, + 657, + 3705, + 658, + 3726, + 3701, + 659, + 3693, + 660, + 3694, + 661, + 3695, + 662, + 3699, + 663, + 3706, + 664, + 3709, + 665, + 3696, + 666, + 3700, + 3690, + 667, + 3707, + 669, + 670, + 671, + 672, + 673, + 674, + 675, + 676, + 677, + 678, + 679, + 680, + 681, + 682, + 683, + 684, + 685, + 686, + 725, + 775, + 776, + 777, + 778, + 779, + 780, + 3675, + 781, + 782, + 3677, + 783, + 784, + 785, + 786, + 787, + 788, + 789, + 790, + 791, + 792, + 793, + 794, + 795, + 796, + 797, + 798, + 799, + 800, + 801, + 802, + 3680, + 803, + 804, + 805, + 806, + 3681, + 807, + 808, + 809, + 810, + 811, + 812, + 813, + 814, + 815, + 3749, + 816, + 817, + 818, + 819, + 820, + 3682, + 821, + 822, + 823, + 3684, + 824, + 825, + 826, + 827, + 828, + 829, + 830, + 831, + 832, + 834, + 835, + 836, + 3754, + 837, + 3753, + 843; + 0.026064, + 0.571004, + 0.571004, + 0.455028, + 0.248249, + 0.604345, + 0.015514, + 0.000824, + 0.000824, + 0.257581, + 0.990195, + 0.999682, + 0.554089, + 0.554089, + 0.000000, + 0.000158, + 0.000158, + 0.006843, + 0.006843, + 0.000001, + 0.000001, + 0.272648, + 0.272648, + 0.272648, + 0.472624, + 0.472624, + 0.472624, + 0.000161, + 0.000161, + 0.003903, + 0.003903, + 1.000000, + 0.357429, + 0.498086, + 0.204317, + 0.997876, + 0.997876, + 0.519316, + 0.519316, + 1.000000, + 0.999598, + 1.000000, + 0.999991, + 0.999991, + 0.999527, + 0.997336, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000000, + 0.000000, + 0.999682, + 0.091281, + 0.046144, + 0.000091, + 0.080118, + 0.000048, + 0.000048, + 0.472785, + 0.002242, + 0.002242, + 0.006073, + 0.006073, + 0.006073, + 0.062748, + 0.062748, + 0.262268, + 0.262268, + 0.448347, + 0.448347, + 0.391542, + 0.391542, + 0.607159, + 0.607159, + 0.319517, + 0.319517, + 0.002809, + 0.002809, + 0.002809, + 0.054075, + 0.054075, + 0.133582, + 0.133582, + 0.092798, + 0.092798, + 0.537874, + 0.537874, + 0.190501, + 0.190501, + 0.178618, + 0.178618, + 0.055746, + 0.055746, + 0.730401, + 0.730401, + 0.730401, + 0.319495, + 0.319495, + 0.000363, + 0.003114, + 0.050198, + 0.237229, + 0.426363, + 0.353552, + 0.823675, + 0.413357, + 0.000372, + 0.030495, + 0.089985, + 0.058787, + 0.714235, + 0.137448, + 0.127817, + 0.028669, + 0.898433, + 0.280034, + 0.057181, + 0.028794, + 0.011515, + 1.000000, + 1.000000, + 0.464511, + 0.852246, + 0.852246, + 0.999499, + 0.505163, + 0.505163, + 0.499411, + 0.444841, + 0.999999, + 0.999999, + 0.999981, + 0.091013, + 0.240829, + 0.959675, + 0.397767, + 0.339149, + 0.504983, + 0.489019, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.998162, + 1.000000, + 1.000000, + 0.538773, + 0.966243, + 1.000000, + 0.999994, + 0.999994, + 0.999989, + 0.999992, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.199217, + 0.199217, + 0.114574, + 0.001818, + 0.221331, + 0.319029, + 0.506883, + 0.261107, + 0.521918, + 0.557577, + 0.528621, + 0.010854, + 1.000000, + 0.309890, + 0.309890, + 0.021971, + 0.021971, + 0.000015; + 0.120906,0.020146,-1.272965,0.000000,-1.115712,-0.072214,-0.107113,0.000000,-0.096302,1.467010,0.014070,0.000000,-242.688828,-89.343452,17.548592,1.000000;; + } + + SkinWeights { + "Bip01_L_Foot"; + 153; + 572, + 573, + 577, + 578, + 591, + 3671, + 3659, + 592, + 3660, + 593, + 3661, + 594, + 3662, + 595, + 3663, + 596, + 3670, + 3669, + 597, + 3668, + 598, + 3667, + 599, + 3666, + 600, + 3664, + 601, + 3658, + 602, + 603, + 604, + 3725, + 3674, + 605, + 3672, + 606, + 607, + 608, + 3724, + 3687, + 609, + 3689, + 3688, + 610, + 3673, + 611, + 3665, + 615, + 616, + 617, + 618, + 3678, + 619, + 3676, + 620, + 621, + 622, + 647, + 648, + 3692, + 649, + 650, + 3691, + 651, + 3703, + 3686, + 652, + 3702, + 653, + 3698, + 654, + 3697, + 655, + 3708, + 656, + 3704, + 657, + 3705, + 658, + 3726, + 3701, + 659, + 3693, + 660, + 3694, + 661, + 3695, + 662, + 3699, + 663, + 3706, + 664, + 3709, + 665, + 3696, + 666, + 3700, + 3690, + 667, + 3707, + 668, + 669, + 670, + 671, + 672, + 673, + 674, + 675, + 676, + 677, + 678, + 679, + 680, + 681, + 682, + 683, + 684, + 685, + 686, + 722, + 723, + 3685, + 724, + 3657, + 725, + 726, + 775, + 776, + 777, + 778, + 779, + 780, + 3675, + 781, + 782, + 3677, + 783, + 784, + 785, + 786, + 787, + 788, + 789, + 790, + 791, + 792, + 793, + 794, + 801, + 803, + 804, + 806, + 3681; + 0.751751, + 0.395655, + 0.009805, + 0.000317, + 0.000001, + 0.000001, + 0.000001, + 0.057284, + 0.057284, + 1.000000, + 1.000000, + 0.999842, + 0.999842, + 1.000000, + 1.000000, + 0.000037, + 0.000037, + 0.000037, + 0.449247, + 0.449247, + 1.000000, + 1.000000, + 0.993157, + 0.993157, + 0.999999, + 0.999999, + 0.000045, + 0.000045, + 0.480725, + 0.999952, + 0.727352, + 0.727352, + 0.727352, + 0.000434, + 0.000434, + 0.557390, + 1.000000, + 0.527376, + 0.527376, + 0.527376, + 1.000000, + 1.000000, + 1.000000, + 0.999839, + 0.999839, + 0.996097, + 0.996097, + 0.642571, + 0.501914, + 0.795683, + 0.002124, + 0.002124, + 0.480684, + 0.480684, + 0.000000, + 0.000402, + 0.000000, + 0.919882, + 0.999952, + 0.999952, + 0.527215, + 0.997758, + 0.997758, + 0.993927, + 0.993927, + 0.993927, + 0.937252, + 0.937252, + 0.737732, + 0.737732, + 0.551653, + 0.551653, + 0.608458, + 0.608458, + 0.392841, + 0.392841, + 0.680483, + 0.680483, + 0.997191, + 0.997191, + 0.997191, + 0.945925, + 0.945925, + 0.866418, + 0.866418, + 0.907202, + 0.907202, + 0.462126, + 0.462126, + 0.809499, + 0.809499, + 0.821382, + 0.821382, + 0.944254, + 0.944254, + 0.269599, + 0.269599, + 0.269599, + 0.680505, + 0.680505, + 1.000000, + 0.999637, + 0.996886, + 0.949802, + 0.762771, + 0.573637, + 0.646448, + 0.176325, + 0.586643, + 0.999628, + 0.969505, + 0.910015, + 0.941213, + 0.285765, + 0.862552, + 0.872183, + 0.971331, + 0.101567, + 0.719966, + 0.620583, + 1.000000, + 1.000000, + 0.713557, + 0.713557, + 0.942819, + 1.000000, + 0.971206, + 0.988485, + 0.000000, + 0.000000, + 0.535488, + 0.147754, + 0.147754, + 0.000501, + 0.494837, + 0.494837, + 0.500589, + 0.555158, + 0.000002, + 0.000001, + 0.000019, + 0.908987, + 0.759171, + 0.040325, + 0.602233, + 0.660851, + 0.495017, + 0.510981, + 0.001838, + 0.461227, + 0.033757, + 0.000006, + 0.000006; + 0.000000,0.000002,-1.278853,0.000000,-1.123165,-0.000000,-0.000000,0.000000,-0.000000,1.470235,0.000002,0.000000,-363.589264,-65.273499,53.091980,1.000000;; + } + + SkinWeights { + "Bip01_L_Toe0"; + 20; + 591, + 3671, + 3659, + 592, + 3660, + 596, + 3670, + 3669, + 597, + 3668, + 601, + 3658, + 602, + 603, + 605, + 3672, + 606, + 722, + 724, + 3657; + 0.999999, + 0.999999, + 0.999999, + 0.942716, + 0.942716, + 0.999963, + 0.999963, + 0.999963, + 0.550753, + 0.550753, + 0.999955, + 0.999955, + 0.519275, + 0.000048, + 0.999566, + 0.999566, + 0.442610, + 0.379417, + 0.286443, + 0.286443; + 0.000002,0.000000,-1.278853,0.000000,-0.000000,1.123165,0.000000,0.000000,1.470235,0.000000,0.000002,0.000000,-99.850632,391.012512,53.091995,1.000000;; + } + + SkinWeights { + "Bip01_L_Forearm"; + 119; + 859, + 3774, + 862, + 3763, + 863, + 3765, + 866, + 867, + 868, + 869, + 876, + 878, + 879, + 3791, + 3788, + 3767, + 880, + 3790, + 881, + 3786, + 882, + 3785, + 883, + 3796, + 3789, + 3766, + 884, + 3783, + 885, + 3797, + 886, + 3782, + 887, + 3773, + 894, + 898, + 899, + 901, + 902, + 903, + 904, + 906, + 907, + 908, + 909, + 3795, + 910, + 3804, + 3802, + 3784, + 911, + 3803, + 912, + 3792, + 913, + 914, + 3805, + 915, + 3808, + 3807, + 3787, + 916, + 917, + 918, + 919, + 920, + 921, + 922, + 923, + 924, + 3793, + 925, + 926, + 927, + 928, + 929, + 930, + 931, + 932, + 933, + 934, + 935, + 936, + 937, + 938, + 3794, + 939, + 940, + 941, + 942, + 947, + 3806, + 948, + 949, + 950, + 3927, + 951, + 3813, + 3811, + 3810, + 952, + 3815, + 1271, + 1272, + 1273, + 1274, + 1275, + 1276, + 1277, + 1278, + 1279, + 1280, + 3930, + 1281, + 3809, + 1282, + 3812, + 1283, + 1284; + 0.000002, + 0.000002, + 0.059762, + 0.059762, + 0.156983, + 0.156983, + 0.307600, + 0.461983, + 0.363022, + 0.207371, + 0.437484, + 0.390499, + 0.473019, + 0.473019, + 0.473019, + 0.473019, + 0.493125, + 0.493125, + 0.500494, + 0.500494, + 0.497598, + 0.497598, + 0.487562, + 0.487562, + 0.487562, + 0.487562, + 0.500000, + 0.500000, + 0.435736, + 0.435736, + 0.500010, + 0.500010, + 0.000002, + 0.000002, + 0.000000, + 0.004760, + 0.062097, + 0.000412, + 0.018884, + 0.000128, + 0.000050, + 0.046535, + 0.997297, + 0.999856, + 0.996144, + 0.996144, + 0.971005, + 0.971005, + 0.971005, + 0.971005, + 0.998600, + 0.998600, + 0.999904, + 0.999904, + 1.000000, + 0.522519, + 0.522519, + 0.500009, + 0.500009, + 0.500009, + 0.500009, + 1.000000, + 0.999782, + 1.000000, + 0.999998, + 0.999979, + 0.999598, + 0.998203, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.982001, + 0.730349, + 0.917959, + 0.770439, + 1.000000, + 1.000000, + 1.000000, + 0.825192, + 0.479548, + 0.479548, + 0.280624, + 0.280624, + 0.280624, + 0.280624, + 0.454016, + 0.454016, + 1.000000, + 1.000000, + 0.999997, + 0.522228, + 0.479390, + 0.437447, + 0.393686, + 0.431087, + 0.457384, + 0.338176, + 0.338176, + 0.610102, + 0.610102, + 0.527919, + 0.527919, + 0.541473, + 0.495169; + 0.888611,0.718008,0.574718,0.000000,-0.246358,-0.482594,0.983825,0.000000,1.006948,-1.039778,-0.257893,0.000000,-156.802475,18.217770,-12.980429,1.000000;; + } + + SkinWeights { + "Bip01_L_Hand"; + 76; + 910, + 3804, + 3802, + 3784, + 911, + 3803, + 914, + 3805, + 915, + 3808, + 3807, + 3787, + 949, + 950, + 3927, + 951, + 3813, + 3811, + 3810, + 952, + 3815, + 953, + 3928, + 954, + 3929, + 3817, + 3814, + 955, + 3931, + 3816, + 956, + 959, + 961, + 963, + 964, + 965, + 3818, + 973, + 974, + 981, + 982, + 983, + 984, + 986, + 987, + 988, + 3821, + 989, + 3820, + 991, + 1008, + 1263, + 1264, + 1265, + 1266, + 1267, + 1268, + 3926, + 1269, + 1270, + 1272, + 1273, + 1274, + 1275, + 1276, + 1277, + 1278, + 1279, + 1280, + 3930, + 1281, + 3809, + 1282, + 3812, + 1283, + 1284; + 0.028995, + 0.028995, + 0.028995, + 0.028995, + 0.001400, + 0.001400, + 0.477481, + 0.477481, + 0.499991, + 0.499991, + 0.499991, + 0.499991, + 0.174808, + 0.520452, + 0.520452, + 0.719376, + 0.719376, + 0.719376, + 0.719376, + 0.545984, + 0.545984, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000575, + 1.000000, + 1.000000, + 1.000000, + 0.489764, + 1.000000, + 1.000000, + 0.007399, + 0.000084, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.480738, + 0.480738, + 0.485043, + 0.485043, + 0.500000, + 0.008638, + 1.000000, + 0.044182, + 0.012334, + 0.004315, + 0.389840, + 0.201485, + 0.201485, + 1.000000, + 1.000000, + 0.000000, + 0.000002, + 0.477772, + 0.520610, + 0.562553, + 0.606314, + 0.568913, + 0.542616, + 0.661824, + 0.661824, + 0.389898, + 0.389898, + 0.472081, + 0.472081, + 0.458527, + 0.504831; + 0.888611,-0.574146,0.718465,0.000000,-0.246358,-0.984209,-0.481810,0.000000,1.006948,0.257065,-1.039984,0.000000,-218.473953,12.994934,18.207430,1.000000;; + } + + SkinWeights { + "Bip01_L_Finger1"; + 94; + 956, + 957, + 958, + 960, + 962, + 3832, + 969, + 3859, + 970, + 3836, + 971, + 972, + 3882, + 973, + 974, + 975, + 976, + 977, + 978, + 979, + 980, + 985, + 3834, + 993, + 3826, + 3824, + 998, + 3829, + 1001, + 1008, + 1009, + 1010, + 1011, + 1012, + 1013, + 1014, + 1015, + 3835, + 1016, + 1017, + 1018, + 3833, + 1019, + 1020, + 1021, + 3838, + 1022, + 1023, + 1024, + 3837, + 1025, + 1026, + 1077, + 3858, + 1078, + 1079, + 1080, + 3857, + 1081, + 1082, + 1083, + 3861, + 1087, + 1088, + 1139, + 3881, + 1140, + 1141, + 1142, + 3880, + 1143, + 1144, + 1148, + 3883, + 1149, + 1150, + 1201, + 3904, + 1202, + 1203, + 1204, + 3903, + 1205, + 1206, + 1210, + 3905, + 1211, + 1212, + 1264, + 1265, + 1266, + 1267, + 1268, + 3926; + 0.999425, + 0.999999, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.959444, + 0.959444, + 0.998224, + 0.998224, + 0.997435, + 0.994530, + 0.994530, + 0.992601, + 0.999916, + 0.999813, + 0.994714, + 0.988947, + 0.990024, + 0.999781, + 0.999208, + 1.000000, + 1.000000, + 0.056190, + 0.056190, + 0.056190, + 0.000462, + 0.000462, + 0.002074, + 0.991362, + 0.999365, + 0.998360, + 1.000000, + 1.000000, + 0.962750, + 0.958956, + 0.501562, + 0.501562, + 0.544088, + 0.624832, + 0.644254, + 0.644254, + 0.583404, + 0.507984, + 0.001016, + 0.001016, + 0.000028, + 0.000000, + 0.000000, + 0.000000, + 0.000074, + 0.001057, + 0.492123, + 0.492123, + 0.366961, + 0.325544, + 0.443569, + 0.443569, + 0.494251, + 0.499973, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.353513, + 0.353513, + 0.257215, + 0.363813, + 0.495090, + 0.495090, + 0.498815, + 0.462536, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.548101, + 0.548101, + 0.472535, + 0.435641, + 0.482943, + 0.482943, + 0.490011, + 0.524837, + 0.000024, + 0.000024, + 0.000028, + 0.000000, + 0.955818, + 0.987666, + 0.995685, + 0.610160, + 0.798515, + 0.798515; + 0.888611,-0.574718,0.718007,0.000000,-0.246358,-0.983825,-0.482594,0.000000,1.006948,0.257893,-1.039779,0.000000,-242.561966,12.625334,18.722528,1.000000;; + } + + SkinWeights { + "Bip01_L_Finger11"; + 246; + 957, + 958, + 960, + 969, + 3859, + 970, + 3836, + 971, + 972, + 3882, + 975, + 976, + 977, + 978, + 979, + 980, + 1009, + 1010, + 1013, + 1014, + 1015, + 3835, + 1016, + 1017, + 1018, + 3833, + 1019, + 1020, + 1021, + 3838, + 1022, + 1023, + 1024, + 3837, + 1025, + 1026, + 1027, + 3840, + 1028, + 1029, + 1030, + 3839, + 1031, + 1032, + 1033, + 3842, + 1034, + 1035, + 1036, + 3841, + 1037, + 1038, + 1039, + 3844, + 1040, + 1041, + 1042, + 3843, + 1043, + 1044, + 1045, + 3846, + 1046, + 1047, + 1048, + 3845, + 1049, + 1050, + 1051, + 3848, + 1052, + 1053, + 1054, + 3847, + 1055, + 1056, + 1057, + 3850, + 1058, + 1059, + 1060, + 3849, + 1061, + 1062, + 1077, + 3858, + 1078, + 1079, + 1080, + 3857, + 1081, + 1082, + 1083, + 3861, + 1084, + 1085, + 1086, + 3860, + 1087, + 1088, + 1089, + 3863, + 1090, + 1091, + 1092, + 3862, + 1093, + 1094, + 1095, + 3865, + 1096, + 1097, + 1098, + 3864, + 1099, + 1100, + 1101, + 3867, + 1102, + 1103, + 1104, + 3866, + 1105, + 1106, + 1107, + 3869, + 1108, + 1109, + 1110, + 3868, + 1111, + 1112, + 1139, + 3881, + 1140, + 1141, + 1142, + 3880, + 1143, + 1144, + 1145, + 3884, + 1146, + 1147, + 1148, + 3883, + 1149, + 1150, + 1151, + 3886, + 1152, + 1153, + 1154, + 3885, + 1155, + 1156, + 1157, + 3888, + 1158, + 1159, + 1160, + 3887, + 1161, + 1162, + 1163, + 3890, + 1164, + 1165, + 1166, + 3889, + 1167, + 1168, + 1169, + 3892, + 1170, + 1171, + 1172, + 3891, + 1173, + 1174, + 1178, + 3893, + 1201, + 3904, + 1202, + 1203, + 1204, + 3903, + 1205, + 1206, + 1207, + 3906, + 1208, + 1209, + 1210, + 3905, + 1211, + 1212, + 1213, + 3908, + 1214, + 1215, + 1216, + 3907, + 1217, + 1218, + 1219, + 3910, + 1220, + 1221, + 1222, + 3909, + 1223, + 1224, + 1225, + 3912, + 1226, + 1227, + 1228, + 3911, + 1229, + 1230, + 1231, + 3914, + 1232, + 1233, + 1234, + 3913, + 1235, + 1236, + 1237, + 3916, + 1238, + 1239, + 1240, + 3915, + 1241, + 1242, + 1243, + 3918, + 1244, + 1245, + 1246, + 3917, + 1247, + 1248; + 0.000001, + 0.000000, + 0.000000, + 0.040556, + 0.040556, + 0.001776, + 0.001776, + 0.002565, + 0.005470, + 0.005470, + 0.000187, + 0.005286, + 0.011053, + 0.009976, + 0.000219, + 0.000792, + 0.000635, + 0.001640, + 0.037250, + 0.041044, + 0.498439, + 0.498439, + 0.455912, + 0.375168, + 0.355747, + 0.355747, + 0.416596, + 0.492016, + 0.998984, + 0.998984, + 0.999972, + 1.000000, + 1.000000, + 1.000000, + 0.999926, + 0.998943, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999590, + 0.999590, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999972, + 0.687019, + 0.687019, + 0.853539, + 0.975075, + 0.984281, + 0.984281, + 0.931293, + 0.756339, + 0.454794, + 0.454794, + 0.386277, + 0.350143, + 0.375279, + 0.375279, + 0.395390, + 0.437087, + 0.047430, + 0.047430, + 0.013109, + 0.001288, + 0.000577, + 0.000577, + 0.003844, + 0.028016, + 0.507877, + 0.507877, + 0.633039, + 0.674456, + 0.556431, + 0.556431, + 0.505749, + 0.500027, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999996, + 0.999996, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999998, + 0.999965, + 0.763473, + 0.763473, + 0.945556, + 0.978392, + 0.941282, + 0.941282, + 0.833361, + 0.659726, + 0.455132, + 0.455132, + 0.309846, + 0.264637, + 0.353841, + 0.353841, + 0.421831, + 0.468652, + 0.000004, + 0.000004, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000002, + 0.000008, + 0.646487, + 0.646487, + 0.742785, + 0.636187, + 0.504910, + 0.504910, + 0.501185, + 0.537464, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999946, + 0.999946, + 0.999997, + 0.999305, + 0.978899, + 0.978899, + 0.978208, + 0.997956, + 0.496668, + 0.496668, + 0.492731, + 0.498635, + 0.500000, + 0.500000, + 0.500000, + 0.499604, + 0.000245, + 0.000245, + 0.000164, + 0.000644, + 0.003351, + 0.003351, + 0.003048, + 0.000866, + 0.000000, + 0.000000, + 0.451899, + 0.451899, + 0.527465, + 0.564359, + 0.517057, + 0.517057, + 0.509989, + 0.475163, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999976, + 0.999976, + 0.999972, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999989, + 0.993070, + 0.993070, + 0.998995, + 1.000000, + 0.998765, + 0.998765, + 0.985174, + 0.792985, + 0.640530, + 0.640530, + 0.737351, + 0.957855, + 0.049642, + 0.049642, + 0.038349, + 0.067962, + 0.128283, + 0.128283, + 0.109217, + 0.077048; + 0.888611,-0.574718,0.718007,0.000000,-0.246358,-0.983825,-0.482594,0.000000,1.006948,0.257893,-1.039779,0.000000,-251.862015,12.625334,18.722525,1.000000;; + } + + SkinWeights { + "Bip01_L_Finger0"; + 17; + 964, + 966, + 967, + 968, + 3822, + 988, + 3821, + 989, + 3820, + 990, + 3819, + 991, + 992, + 994, + 995, + 3823, + 996; + 0.510236, + 0.957025, + 0.977791, + 1.000000, + 1.000000, + 0.519262, + 0.519262, + 0.514957, + 0.514957, + 0.500000, + 0.500000, + 0.500000, + 1.000000, + 0.000013, + 0.001700, + 0.001700, + 0.004007; + 0.131869,-1.109649,-0.621896,0.000000,0.164812,0.558010,-0.960710,0.000000,1.446397,0.024762,0.262515,0.000000,-185.006516,140.638351,15.450895,1.000000;; + } + + SkinWeights { + "Bip01_L_Finger01"; + 16; + 966, + 967, + 990, + 3819, + 992, + 993, + 3826, + 3824, + 994, + 995, + 3823, + 996, + 997, + 3827, + 1000, + 3825; + 0.042975, + 0.022209, + 0.500000, + 0.500000, + 0.000000, + 0.943810, + 0.943810, + 0.943810, + 0.999987, + 0.998300, + 0.998300, + 0.995993, + 1.000000, + 1.000000, + 0.019189, + 0.019189; + 0.588472,-0.949953,-0.621896,0.000000,-0.086455,0.575381,-0.960710,0.000000,1.300416,0.633716,0.262515,0.000000,-236.240311,45.016586,15.450904,1.000000;; + } + + SkinWeights { + "Bip01_L_Finger02"; + 15; + 998, + 3829, + 999, + 1000, + 3825, + 1001, + 1002, + 3828, + 1003, + 3831, + 1004, + 1005, + 3830, + 1006, + 1007; + 0.999538, + 0.999538, + 1.000000, + 0.980811, + 0.980811, + 0.997926, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.322554,-1.069892,-0.621896,0.000000,0.065410,0.578152,-0.960710,0.000000,1.420123,0.275550,0.262515,0.000000,-222.297882,106.169159,15.450895,1.000000;; + } + + SkinWeights { + "Bip01_L_Finger12"; + 214; + 1039, + 3844, + 1044, + 1045, + 3846, + 1046, + 1047, + 1048, + 3845, + 1049, + 1050, + 1051, + 3848, + 1052, + 1053, + 1054, + 3847, + 1055, + 1056, + 1057, + 3850, + 1058, + 1059, + 1060, + 3849, + 1061, + 1062, + 1063, + 3852, + 1064, + 1065, + 1066, + 3851, + 1067, + 1068, + 1069, + 3854, + 1070, + 1071, + 1072, + 3853, + 1073, + 1074, + 1075, + 3856, + 1076, + 3855, + 1089, + 3863, + 1092, + 3862, + 1093, + 1094, + 1095, + 3865, + 1096, + 1097, + 1098, + 3864, + 1099, + 1100, + 1101, + 3867, + 1102, + 1103, + 1104, + 3866, + 1105, + 1106, + 1107, + 3869, + 1108, + 1109, + 1110, + 3868, + 1111, + 1112, + 1113, + 3871, + 1114, + 1115, + 1116, + 3870, + 1117, + 1118, + 1119, + 3873, + 1120, + 1121, + 1122, + 3872, + 1123, + 1124, + 1125, + 3875, + 1126, + 1127, + 1128, + 3874, + 1129, + 1130, + 1131, + 3877, + 1132, + 1133, + 1134, + 3876, + 1135, + 1136, + 1137, + 3879, + 1138, + 3878, + 1157, + 3888, + 1158, + 1159, + 1160, + 3887, + 1161, + 1162, + 1163, + 3890, + 1164, + 1165, + 1166, + 3889, + 1167, + 1168, + 1169, + 3892, + 1170, + 1171, + 1172, + 3891, + 1173, + 1174, + 1175, + 3894, + 1176, + 1177, + 1178, + 3893, + 1179, + 1180, + 1181, + 3896, + 1182, + 1183, + 1184, + 3895, + 1185, + 1186, + 1187, + 3898, + 1188, + 1189, + 1190, + 3897, + 1191, + 1192, + 1193, + 3900, + 1194, + 1195, + 1196, + 3899, + 1197, + 1198, + 1199, + 3902, + 1200, + 3901, + 1233, + 1234, + 3913, + 1235, + 1237, + 3916, + 1238, + 1239, + 1240, + 3915, + 1241, + 1242, + 1243, + 3918, + 1244, + 1245, + 1246, + 3917, + 1247, + 1248, + 1249, + 3921, + 1250, + 3919, + 1251, + 1252, + 3920, + 1253, + 1254, + 1255, + 3923, + 1256, + 1257, + 1258, + 3922, + 1259, + 1260, + 1261, + 3925, + 1262, + 3924; + 0.000410, + 0.000410, + 0.000028, + 0.312981, + 0.312981, + 0.146461, + 0.024925, + 0.015719, + 0.015719, + 0.068707, + 0.243661, + 0.545206, + 0.545206, + 0.613723, + 0.649857, + 0.624721, + 0.624721, + 0.604610, + 0.562913, + 0.952570, + 0.952570, + 0.986891, + 0.998712, + 0.999423, + 0.999423, + 0.996156, + 0.971984, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000004, + 0.000004, + 0.000000, + 0.000000, + 0.000002, + 0.000035, + 0.236527, + 0.236527, + 0.054444, + 0.021608, + 0.058718, + 0.058718, + 0.166639, + 0.340274, + 0.544868, + 0.544868, + 0.690154, + 0.735363, + 0.646159, + 0.646159, + 0.578169, + 0.531348, + 0.999996, + 0.999996, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999998, + 0.999992, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000054, + 0.000054, + 0.000003, + 0.000695, + 0.021101, + 0.021101, + 0.021792, + 0.002044, + 0.503332, + 0.503332, + 0.507269, + 0.501365, + 0.500000, + 0.500000, + 0.500000, + 0.500396, + 0.999754, + 0.999754, + 0.999836, + 0.999356, + 0.996649, + 0.996649, + 0.996952, + 0.999134, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000011, + 0.006930, + 0.006930, + 0.001005, + 0.001235, + 0.001235, + 0.014826, + 0.207015, + 0.359470, + 0.359470, + 0.262649, + 0.042145, + 0.950358, + 0.950358, + 0.961651, + 0.932038, + 0.871718, + 0.871718, + 0.890783, + 0.922952, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.888611,-0.574718,0.718007,0.000000,-0.246358,-0.983825,-0.482594,0.000000,1.006948,0.257893,-1.039779,0.000000,-262.712067,12.625349,18.722527,1.000000;; + } + + SkinWeights { + "Bip01_R_Forearm"; + 118; + 1304, + 3954, + 1307, + 3943, + 1308, + 3944, + 1311, + 1312, + 1313, + 1314, + 1321, + 1323, + 1324, + 3967, + 3947, + 1325, + 3971, + 1326, + 3966, + 1327, + 3969, + 3965, + 1328, + 3976, + 3970, + 3946, + 1329, + 3963, + 1330, + 3977, + 1331, + 3962, + 1332, + 3953, + 1339, + 1343, + 1344, + 1346, + 1347, + 1348, + 1349, + 1351, + 1352, + 1353, + 1354, + 3975, + 1355, + 3984, + 3982, + 3964, + 1356, + 3983, + 1357, + 1358, + 1359, + 3985, + 1360, + 3988, + 3987, + 3973, + 1361, + 1362, + 1363, + 3968, + 1364, + 1365, + 1366, + 1367, + 1368, + 1369, + 3974, + 1370, + 1371, + 1372, + 1373, + 1374, + 1375, + 1376, + 1377, + 1378, + 1379, + 1380, + 1381, + 1382, + 3972, + 1383, + 1384, + 1385, + 1386, + 1387, + 1392, + 3986, + 1393, + 1394, + 1395, + 4103, + 1396, + 3993, + 3992, + 3989, + 1397, + 3991, + 1716, + 1717, + 1718, + 1719, + 1720, + 1721, + 1722, + 1723, + 1724, + 1725, + 4105, + 1726, + 3990, + 1727, + 1728, + 1729; + 0.000002, + 0.000002, + 0.062100, + 0.062100, + 0.156545, + 0.156545, + 0.307653, + 0.463402, + 0.364263, + 0.206257, + 0.437729, + 0.393141, + 0.474390, + 0.474390, + 0.474390, + 0.494343, + 0.494343, + 0.500493, + 0.500493, + 0.497958, + 0.497958, + 0.497958, + 0.487799, + 0.487799, + 0.487799, + 0.487799, + 0.500000, + 0.500000, + 0.435860, + 0.435860, + 0.500018, + 0.500018, + 0.000003, + 0.000003, + 0.000000, + 0.004865, + 0.063481, + 0.000471, + 0.019984, + 0.000129, + 0.000050, + 0.048368, + 0.997429, + 0.999862, + 0.996296, + 0.996296, + 0.969578, + 0.969578, + 0.969578, + 0.969578, + 0.998534, + 0.998534, + 0.999904, + 1.000000, + 0.521478, + 0.521478, + 0.500006, + 0.500006, + 0.500006, + 0.500006, + 1.000000, + 0.999783, + 1.000000, + 1.000000, + 0.999998, + 0.999980, + 0.999624, + 0.998287, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.982655, + 0.733244, + 0.919066, + 0.773837, + 1.000000, + 1.000000, + 1.000000, + 0.821199, + 0.479127, + 0.479127, + 0.373080, + 0.373080, + 0.373080, + 0.373080, + 0.494538, + 0.494538, + 1.000000, + 1.000000, + 0.999997, + 0.521167, + 0.479837, + 0.438248, + 0.533577, + 0.511417, + 0.457177, + 0.338835, + 0.338835, + 0.606293, + 0.606293, + 0.526599, + 0.539169, + 0.495281; + -0.888608,-0.718010,0.574719,0.000000,-0.246358,-0.482594,-0.983825,0.000000,1.006950,-1.039776,0.257891,0.000000,-156.604965,18.377340,12.852691,1.000000;; + } + + SkinWeights { + "Bip01_R_Hand"; + 74; + 1355, + 3984, + 3982, + 3964, + 1356, + 3983, + 1359, + 3985, + 1360, + 3988, + 3987, + 3973, + 1394, + 1395, + 4103, + 1396, + 3993, + 3992, + 3989, + 1397, + 3991, + 1398, + 4104, + 1399, + 4106, + 3996, + 3994, + 1400, + 3995, + 1401, + 1404, + 1406, + 1408, + 1409, + 1410, + 3997, + 1418, + 1419, + 1426, + 1427, + 1428, + 1429, + 1431, + 1432, + 1433, + 4000, + 1434, + 3999, + 1436, + 1453, + 1708, + 1709, + 1710, + 1711, + 1712, + 1713, + 4102, + 1714, + 1715, + 1717, + 1718, + 1719, + 1720, + 1721, + 1722, + 1723, + 1724, + 1725, + 4105, + 1726, + 3990, + 1727, + 1728, + 1729; + 0.030422, + 0.030422, + 0.030422, + 0.030422, + 0.001466, + 0.001466, + 0.478522, + 0.478522, + 0.499994, + 0.499994, + 0.499994, + 0.499994, + 0.178801, + 0.520873, + 0.520873, + 0.626920, + 0.626920, + 0.626920, + 0.626920, + 0.505462, + 0.505462, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000096, + 1.000000, + 1.000000, + 0.500000, + 0.470417, + 1.000000, + 1.000000, + 0.002561, + 0.000004, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.460453, + 0.460453, + 0.466427, + 0.466427, + 0.496454, + 0.002208, + 1.000000, + 0.022241, + 0.006276, + 0.001324, + 0.337075, + 0.124395, + 0.124395, + 1.000000, + 1.000000, + 0.000000, + 0.000003, + 0.478833, + 0.520163, + 0.561752, + 0.466423, + 0.488583, + 0.542824, + 0.661165, + 0.661165, + 0.393707, + 0.393707, + 0.473401, + 0.460831, + 0.504719; + -0.888608,0.574147,0.718468,0.000000,-0.246358,-0.984209,0.481810,0.000000,1.006950,0.257063,1.039981,0.000000,-218.276459,12.867327,-18.367111,1.000000;; + } + + SkinWeights { + "Bip01_R_Finger1"; + 88; + 1401, + 1402, + 1403, + 1405, + 1407, + 4008, + 1414, + 4036, + 1415, + 4009, + 1416, + 1417, + 4059, + 1418, + 1419, + 1420, + 1421, + 1422, + 1423, + 1424, + 1425, + 1430, + 4011, + 1438, + 4003, + 1443, + 4005, + 1446, + 1453, + 1454, + 1455, + 1456, + 1457, + 1458, + 1459, + 1460, + 4013, + 1461, + 4010, + 1462, + 1463, + 4012, + 1464, + 1465, + 1466, + 4015, + 1467, + 1469, + 4014, + 1470, + 1471, + 1522, + 4035, + 1523, + 1524, + 1525, + 4034, + 1526, + 1527, + 1533, + 1584, + 4058, + 1585, + 1586, + 1587, + 4057, + 1588, + 1589, + 1593, + 4060, + 1594, + 1646, + 4081, + 1647, + 1648, + 1649, + 4080, + 1650, + 1651, + 1655, + 4082, + 1656, + 1709, + 1710, + 1711, + 1712, + 1713, + 4102; + 0.999904, + 0.999575, + 0.999896, + 0.999998, + 0.999965, + 0.999965, + 0.826216, + 0.826216, + 0.988180, + 0.988180, + 0.963893, + 0.941790, + 0.941790, + 0.997439, + 0.999996, + 0.984101, + 0.927449, + 0.946660, + 0.969436, + 0.999024, + 0.990114, + 1.000000, + 1.000000, + 0.051519, + 0.051519, + 0.000312, + 0.000312, + 0.001440, + 0.997792, + 0.988519, + 0.958418, + 0.999946, + 1.000000, + 0.898404, + 0.871105, + 0.499901, + 0.499901, + 0.475211, + 0.475211, + 0.475116, + 0.551148, + 0.551148, + 0.553986, + 0.503293, + 0.000385, + 0.000385, + 0.000002, + 0.000000, + 0.000000, + 0.000073, + 0.000839, + 0.424792, + 0.424792, + 0.175096, + 0.154834, + 0.359990, + 0.359990, + 0.479599, + 0.496175, + 0.000000, + 0.162945, + 0.162945, + 0.064365, + 0.151668, + 0.434586, + 0.434586, + 0.478500, + 0.374775, + 0.000000, + 0.000000, + 0.000000, + 0.193238, + 0.193238, + 0.106886, + 0.203754, + 0.409137, + 0.409137, + 0.427054, + 0.345515, + 0.000000, + 0.000000, + 0.000001, + 0.977759, + 0.993724, + 0.998676, + 0.662925, + 0.875605, + 0.875605; + -0.888608,0.574719,0.718010,0.000000,-0.246358,-0.983825,0.482594,0.000000,1.006950,0.257891,1.039776,0.000000,-242.364456,12.497601,-18.882097,1.000000;; + } + + SkinWeights { + "Bip01_R_Finger11"; + 254; + 1402, + 1403, + 1405, + 1407, + 4008, + 1414, + 4036, + 1415, + 4009, + 1416, + 1417, + 4059, + 1420, + 1421, + 1422, + 1423, + 1424, + 1425, + 1454, + 1455, + 1456, + 1458, + 1459, + 1460, + 4013, + 1461, + 4010, + 1462, + 1463, + 4012, + 1464, + 1465, + 1466, + 4015, + 1467, + 1468, + 1469, + 4014, + 1470, + 1471, + 1472, + 4017, + 1473, + 1474, + 1475, + 4016, + 1476, + 1477, + 1478, + 4019, + 1479, + 1480, + 1481, + 4018, + 1482, + 1483, + 1484, + 4021, + 1485, + 1486, + 1487, + 4020, + 1488, + 1489, + 1490, + 4023, + 1491, + 1492, + 1493, + 4022, + 1494, + 1495, + 1496, + 4025, + 1497, + 1498, + 1499, + 4024, + 1500, + 1501, + 1502, + 4027, + 1503, + 1504, + 1505, + 4026, + 1506, + 1507, + 1508, + 4029, + 1513, + 1522, + 4035, + 1523, + 1524, + 1525, + 4034, + 1526, + 1527, + 1528, + 4038, + 1529, + 1530, + 1531, + 4037, + 1532, + 1533, + 1534, + 4040, + 1535, + 1536, + 1537, + 4039, + 1538, + 1539, + 1540, + 4042, + 1541, + 1542, + 1543, + 4041, + 1544, + 1545, + 1546, + 4044, + 1547, + 1548, + 1549, + 4043, + 1550, + 1551, + 1552, + 4046, + 1553, + 1554, + 1555, + 4045, + 1556, + 1557, + 1584, + 4058, + 1585, + 1586, + 1587, + 4057, + 1588, + 1589, + 1590, + 4061, + 1591, + 1592, + 1593, + 4060, + 1594, + 1595, + 1596, + 4063, + 1597, + 1598, + 1599, + 4062, + 1600, + 1601, + 1602, + 4065, + 1603, + 1604, + 1605, + 4064, + 1606, + 1607, + 1608, + 4067, + 1609, + 1610, + 1611, + 4066, + 1612, + 1613, + 1614, + 4069, + 1615, + 1616, + 1617, + 4068, + 1618, + 1619, + 1623, + 4070, + 1624, + 1646, + 4081, + 1647, + 1648, + 1649, + 4080, + 1650, + 1651, + 1652, + 4083, + 1653, + 1654, + 1655, + 4082, + 1656, + 1657, + 1658, + 4085, + 1659, + 1660, + 1661, + 4084, + 1662, + 1663, + 1664, + 4087, + 1665, + 1666, + 1667, + 4086, + 1668, + 1669, + 1670, + 4089, + 1671, + 1672, + 1673, + 4088, + 1674, + 1675, + 1676, + 4091, + 1677, + 1678, + 1679, + 4090, + 1680, + 1681, + 1682, + 4093, + 1683, + 1684, + 1685, + 4092, + 1686, + 1687, + 1688, + 4095, + 1689, + 1690, + 1691, + 4094, + 1692, + 1693; + 0.000425, + 0.000104, + 0.000002, + 0.000035, + 0.000035, + 0.173784, + 0.173784, + 0.011820, + 0.011820, + 0.036107, + 0.058210, + 0.058210, + 0.015899, + 0.072551, + 0.053340, + 0.030564, + 0.000976, + 0.009886, + 0.011481, + 0.041582, + 0.000054, + 0.101596, + 0.128895, + 0.500099, + 0.500099, + 0.524789, + 0.524789, + 0.524884, + 0.448852, + 0.448852, + 0.446014, + 0.496707, + 0.999615, + 0.999615, + 0.999998, + 1.000000, + 1.000000, + 1.000000, + 0.999927, + 0.999161, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999738, + 0.999738, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999990, + 0.732293, + 0.732293, + 0.886205, + 0.985333, + 0.992404, + 0.992404, + 0.959854, + 0.812284, + 0.489268, + 0.489268, + 0.456724, + 0.487872, + 0.558722, + 0.558722, + 0.534944, + 0.495299, + 0.141677, + 0.141677, + 0.042808, + 0.009349, + 0.010870, + 0.010870, + 0.042129, + 0.130213, + 0.000000, + 0.000000, + 0.000000, + 0.575208, + 0.575208, + 0.824904, + 0.845166, + 0.640010, + 0.640010, + 0.520401, + 0.503825, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999994, + 0.999994, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 0.999967, + 0.788284, + 0.788284, + 0.947229, + 0.980557, + 0.954581, + 0.954581, + 0.872298, + 0.693192, + 0.483189, + 0.483189, + 0.343736, + 0.320172, + 0.442659, + 0.442659, + 0.491581, + 0.499255, + 0.000025, + 0.000025, + 0.000001, + 0.000001, + 0.000008, + 0.000008, + 0.000046, + 0.000109, + 0.837055, + 0.837055, + 0.935635, + 0.848332, + 0.565414, + 0.565414, + 0.521500, + 0.625225, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999937, + 0.999937, + 0.999993, + 0.999085, + 0.980304, + 0.980304, + 0.982841, + 0.998364, + 0.503262, + 0.503262, + 0.492041, + 0.498016, + 0.500000, + 0.500000, + 0.500000, + 0.500995, + 0.000473, + 0.000473, + 0.000211, + 0.000957, + 0.007196, + 0.007196, + 0.009105, + 0.002560, + 0.000000, + 0.000000, + 0.000000, + 0.806762, + 0.806762, + 0.893114, + 0.796246, + 0.590863, + 0.590863, + 0.572946, + 0.654485, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999991, + 0.994261, + 0.994261, + 0.999425, + 1.000000, + 0.999589, + 0.999589, + 0.987588, + 0.800337, + 0.665842, + 0.665842, + 0.779593, + 0.974322, + 0.046310, + 0.046310, + 0.022865, + 0.060048, + 0.146116, + 0.146116, + 0.153619, + 0.123733; + -0.888608,0.574719,0.718010,0.000000,-0.246358,-0.983825,0.482594,0.000000,1.006950,0.257891,1.039776,0.000000,-251.664520,12.497601,-18.882095,1.000000;; + } + + SkinWeights { + "Bip01_R_Finger0"; + 17; + 1408, + 1409, + 1411, + 1412, + 1413, + 4001, + 1433, + 4000, + 1434, + 3999, + 1435, + 3998, + 1436, + 1437, + 1440, + 4002, + 1441; + 0.500000, + 0.529583, + 0.538317, + 0.843910, + 0.999997, + 0.999997, + 0.539547, + 0.539547, + 0.533573, + 0.533573, + 0.500000, + 0.500000, + 0.503546, + 0.999995, + 0.000235, + 0.000235, + 0.000825; + -0.131865,1.109649,-0.621897,0.000000,0.164812,0.558010,0.960710,0.000000,1.446398,0.024759,-0.262513,0.000000,-184.977188,140.391739,-15.312693,1.000000;; + } + + SkinWeights { + "Bip01_R_Finger01"; + 16; + 1411, + 1412, + 1413, + 4001, + 1435, + 3998, + 1437, + 1438, + 4003, + 1439, + 1440, + 4002, + 1441, + 1442, + 1445, + 4004; + 0.461683, + 0.156090, + 0.000003, + 0.000003, + 0.500000, + 0.500000, + 0.000006, + 0.948481, + 0.948481, + 1.000000, + 0.999765, + 0.999765, + 0.999175, + 1.000000, + 0.012123, + 0.012123; + -0.588468,0.949955,-0.621897,0.000000,-0.086455,0.575381,0.960710,0.000000,1.300418,0.633713,-0.262513,0.000000,-236.109512,44.805492,-15.312693,1.000000;; + } + + SkinWeights { + "Bip01_R_Finger02"; + 14; + 1443, + 4005, + 1444, + 1445, + 4004, + 1446, + 1447, + 1448, + 4007, + 1449, + 1450, + 4006, + 1451, + 1452; + 0.999688, + 0.999688, + 1.000000, + 0.987877, + 0.987877, + 0.998560, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + -0.322550,1.069893,-0.621897,0.000000,0.065410,0.578152,0.960710,0.000000,1.420124,0.275547,-0.262513,0.000000,-222.226196,105.931374,-15.312693,1.000000;; + } + + SkinWeights { + "Bip01_R_Finger12"; + 214; + 1484, + 4021, + 1489, + 1490, + 4023, + 1491, + 1492, + 1493, + 4022, + 1494, + 1495, + 1496, + 4025, + 1497, + 1498, + 1499, + 4024, + 1500, + 1501, + 1502, + 4027, + 1503, + 1504, + 1505, + 4026, + 1506, + 1507, + 1508, + 4029, + 1509, + 1510, + 1511, + 4028, + 1512, + 1513, + 1514, + 4031, + 1515, + 1516, + 1517, + 4030, + 1518, + 1519, + 1520, + 4033, + 1521, + 4032, + 1534, + 4040, + 1537, + 4039, + 1538, + 1539, + 1540, + 4042, + 1541, + 1542, + 1543, + 4041, + 1544, + 1545, + 1546, + 4044, + 1547, + 1548, + 1549, + 4043, + 1550, + 1551, + 1552, + 4046, + 1553, + 1554, + 1555, + 4045, + 1556, + 1557, + 1558, + 4048, + 1559, + 1560, + 1561, + 4047, + 1562, + 1563, + 1564, + 4050, + 1565, + 1566, + 1567, + 4049, + 1568, + 1569, + 1570, + 4052, + 1571, + 1572, + 1573, + 4051, + 1574, + 1575, + 1576, + 4054, + 1577, + 1578, + 1579, + 4053, + 1580, + 1581, + 1582, + 4056, + 1583, + 4055, + 1600, + 1602, + 4065, + 1603, + 1604, + 1605, + 4064, + 1606, + 1607, + 1608, + 4067, + 1609, + 1610, + 1611, + 4066, + 1612, + 1613, + 1614, + 4069, + 1615, + 1616, + 1617, + 4068, + 1618, + 1619, + 1620, + 4071, + 1621, + 1622, + 1623, + 4070, + 1624, + 1625, + 1626, + 4073, + 1627, + 1628, + 1629, + 4072, + 1630, + 1631, + 1632, + 4075, + 1633, + 1634, + 1635, + 4074, + 1636, + 1637, + 1638, + 4077, + 1639, + 1640, + 1641, + 4076, + 1642, + 1643, + 1644, + 4079, + 1645, + 4078, + 1678, + 1679, + 4090, + 1680, + 1682, + 4093, + 1683, + 1684, + 1685, + 4092, + 1686, + 1687, + 1688, + 4095, + 1689, + 1690, + 1691, + 4094, + 1692, + 1693, + 1694, + 4097, + 1695, + 1696, + 1697, + 4096, + 1698, + 1699, + 1700, + 4099, + 1701, + 1702, + 1703, + 4098, + 1704, + 1705, + 1706, + 4101, + 1707, + 4100; + 0.000262, + 0.000262, + 0.000010, + 0.267707, + 0.267707, + 0.113795, + 0.014667, + 0.007596, + 0.007596, + 0.040146, + 0.187716, + 0.510732, + 0.510732, + 0.543276, + 0.512128, + 0.441278, + 0.441278, + 0.465056, + 0.504701, + 0.858323, + 0.858323, + 0.957192, + 0.990651, + 0.989130, + 0.989130, + 0.957871, + 0.869787, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000006, + 0.000006, + 0.000000, + 0.000000, + 0.000001, + 0.000033, + 0.211716, + 0.211716, + 0.052771, + 0.019443, + 0.045419, + 0.045419, + 0.127702, + 0.306808, + 0.516811, + 0.516811, + 0.656264, + 0.679828, + 0.557341, + 0.557341, + 0.508419, + 0.500745, + 0.999975, + 0.999975, + 0.999999, + 0.999999, + 0.999992, + 0.999992, + 0.999954, + 0.999891, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000000, + 0.000063, + 0.000063, + 0.000007, + 0.000915, + 0.019696, + 0.019696, + 0.017159, + 0.001636, + 0.496738, + 0.496738, + 0.507959, + 0.501984, + 0.500000, + 0.500000, + 0.500000, + 0.499005, + 0.999527, + 0.999527, + 0.999789, + 0.999043, + 0.992804, + 0.992804, + 0.990895, + 0.997440, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000009, + 0.005739, + 0.005739, + 0.000575, + 0.000411, + 0.000411, + 0.012412, + 0.199663, + 0.334158, + 0.334158, + 0.220407, + 0.025678, + 0.953690, + 0.953690, + 0.977135, + 0.939952, + 0.853884, + 0.853884, + 0.846381, + 0.876267, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + -0.888608,0.574719,0.718010,0.000000,-0.246358,-0.983825,0.482594,0.000000,1.006950,0.257891,1.039776,0.000000,-262.514587,12.497601,-18.882095,1.000000;; + } + + SkinWeights { + "Bip01_Head"; + 1955; + 1746, + 4135, + 1747, + 4276, + 4217, + 4192, + 1748, + 4279, + 4255, + 4210, + 4195, + 4167, + 1749, + 1750, + 4250, + 4246, + 4219, + 4163, + 4160, + 1751, + 4289, + 4275, + 4208, + 4203, + 4191, + 4178, + 4176, + 1752, + 4137, + 1753, + 4278, + 4260, + 4257, + 4194, + 4171, + 1754, + 4307, + 4249, + 1755, + 4324, + 1756, + 4200, + 4188, + 4166, + 4134, + 1757, + 4193, + 4156, + 4126, + 4125, + 4122, + 4120, + 1758, + 4197, + 4196, + 4152, + 4124, + 4121, + 1759, + 4199, + 4162, + 4161, + 4128, + 4127, + 4123, + 1760, + 1761, + 4333, + 4201, + 4186, + 4180, + 4170, + 4165, + 1762, + 1763, + 4140, + 1764, + 4202, + 4198, + 4169, + 4157, + 4154, + 4151, + 1765, + 4205, + 4159, + 4129, + 1766, + 4190, + 4146, + 4143, + 1767, + 4149, + 4132, + 1768, + 4148, + 1769, + 4131, + 1770, + 4139, + 1771, + 4138, + 1772, + 4136, + 1773, + 4142, + 1774, + 4187, + 1775, + 4144, + 1776, + 4145, + 1777, + 4147, + 4141, + 1778, + 4133, + 1779, + 4150, + 4130, + 1780, + 4332, + 1781, + 4175, + 1782, + 4347, + 4164, + 1783, + 4348, + 4181, + 1784, + 4179, + 4173, + 4168, + 4155, + 1785, + 4350, + 4349, + 4206, + 4158, + 1786, + 4351, + 4204, + 4183, + 1787, + 4356, + 1788, + 4306, + 4184, + 4182, + 1789, + 4346, + 4185, + 1790, + 1791, + 1792, + 1793, + 1794, + 1795, + 1796, + 1797, + 1798, + 1799, + 1800, + 1801, + 1802, + 1803, + 1804, + 4174, + 4172, + 1806, + 1807, + 1808, + 1809, + 1810, + 1811, + 1812, + 1813, + 4207, + 1814, + 1815, + 1816, + 1817, + 1818, + 4189, + 1819, + 1820, + 1821, + 1822, + 1823, + 1824, + 1825, + 1826, + 1827, + 1828, + 1829, + 1830, + 1831, + 1832, + 1833, + 1834, + 1835, + 1836, + 1837, + 1838, + 1839, + 1840, + 1841, + 1842, + 1843, + 1844, + 1845, + 1846, + 1847, + 1848, + 1849, + 1850, + 1851, + 1852, + 1853, + 1854, + 1855, + 1856, + 1857, + 1858, + 1859, + 1860, + 1861, + 1862, + 1863, + 1864, + 1865, + 1866, + 1867, + 1868, + 1869, + 1870, + 1871, + 1872, + 1873, + 1874, + 1875, + 1876, + 1877, + 1878, + 1879, + 1880, + 4177, + 1881, + 1882, + 1883, + 1884, + 1885, + 1886, + 4378, + 1887, + 4284, + 4271, + 4254, + 4226, + 1888, + 4277, + 4242, + 4216, + 4215, + 4212, + 4209, + 1889, + 4281, + 4280, + 4239, + 4214, + 4211, + 1890, + 4283, + 4248, + 4247, + 4220, + 4218, + 4213, + 1891, + 1892, + 4389, + 4287, + 4270, + 4264, + 4259, + 4252, + 1893, + 1894, + 4229, + 1895, + 4288, + 4282, + 4258, + 4243, + 4240, + 4238, + 1896, + 4291, + 4245, + 4221, + 1897, + 4386, + 4274, + 4232, + 1898, + 4236, + 4223, + 1899, + 4225, + 1900, + 4224, + 1901, + 4230, + 1902, + 4228, + 1903, + 4227, + 1904, + 4234, + 1905, + 4272, + 1906, + 4233, + 1907, + 4429, + 1908, + 4387, + 4231, + 1909, + 4235, + 1910, + 4237, + 4222, + 1911, + 4390, + 1912, + 4404, + 1913, + 4403, + 4251, + 1914, + 4406, + 4265, + 1915, + 4388, + 4263, + 4256, + 4241, + 1916, + 4408, + 4407, + 4294, + 4292, + 4244, + 1917, + 4409, + 4295, + 4290, + 4267, + 1918, + 4415, + 1919, + 4308, + 4268, + 4266, + 1920, + 4402, + 4269, + 1921, + 1922, + 1923, + 1924, + 1925, + 1926, + 1927, + 1928, + 1929, + 1930, + 1931, + 1932, + 1933, + 1934, + 1935, + 4405, + 4261, + 1937, + 1938, + 1939, + 1940, + 1941, + 1942, + 1943, + 1944, + 4293, + 1945, + 1946, + 1947, + 1948, + 1949, + 4273, + 1950, + 1951, + 1952, + 1953, + 1954, + 1955, + 1956, + 1957, + 1958, + 1959, + 1960, + 1961, + 1962, + 1963, + 1964, + 1965, + 1966, + 1967, + 1968, + 1969, + 1970, + 1971, + 1972, + 1973, + 1974, + 1975, + 1976, + 1977, + 1978, + 1979, + 1980, + 1981, + 1982, + 1983, + 1984, + 1985, + 1986, + 1987, + 1988, + 1989, + 1990, + 1991, + 1992, + 1993, + 1994, + 1995, + 1996, + 1997, + 1998, + 4285, + 1999, + 4286, + 2000, + 2001, + 2002, + 2003, + 2004, + 2005, + 2006, + 2007, + 2008, + 2009, + 2010, + 2011, + 4262, + 2012, + 2013, + 2014, + 2015, + 2016, + 2017, + 2018, + 2019, + 2020, + 2021, + 2022, + 2023, + 2024, + 2025, + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032, + 2033, + 2034, + 2035, + 2036, + 2037, + 2038, + 2039, + 2040, + 2041, + 2042, + 2043, + 2044, + 2045, + 2046, + 2047, + 2048, + 2049, + 2050, + 2051, + 2052, + 2053, + 2054, + 2055, + 2056, + 2057, + 2058, + 2059, + 2060, + 2061, + 2062, + 2063, + 2064, + 2065, + 2066, + 2067, + 2068, + 2069, + 2070, + 2071, + 2072, + 2073, + 2074, + 2075, + 2076, + 2077, + 2078, + 2079, + 2080, + 2081, + 2082, + 2083, + 2084, + 2085, + 2086, + 2087, + 2088, + 2089, + 2090, + 2091, + 2092, + 2093, + 4304, + 2094, + 4296, + 2095, + 4298, + 2096, + 4301, + 2097, + 4303, + 2098, + 4305, + 2099, + 2100, + 2106, + 2107, + 2109, + 4312, + 2110, + 4315, + 2111, + 2112, + 2113, + 2114, + 2115, + 4316, + 2116, + 4319, + 2117, + 2118, + 2119, + 2120, + 2121, + 2122, + 4322, + 2123, + 2124, + 4321, + 2125, + 2126, + 2127, + 2128, + 2129, + 2130, + 2131, + 4327, + 2132, + 4326, + 2133, + 2134, + 2135, + 2136, + 2137, + 2138, + 2139, + 2140, + 4320, + 2141, + 4330, + 2142, + 2143, + 2144, + 2145, + 2146, + 4153, + 2147, + 2148, + 2149, + 2150, + 2151, + 4335, + 2152, + 4339, + 2153, + 4338, + 2154, + 4336, + 2155, + 2156, + 2157, + 2158, + 2159, + 2160, + 2161, + 2162, + 2163, + 2164, + 2165, + 2166, + 2167, + 2168, + 2169, + 2170, + 2171, + 2172, + 2173, + 2174, + 2175, + 2176, + 2177, + 2178, + 2179, + 2180, + 2181, + 2182, + 2183, + 2184, + 2185, + 2186, + 2187, + 2188, + 2189, + 2190, + 2191, + 2192, + 2193, + 2194, + 2195, + 2196, + 2197, + 2198, + 2199, + 2200, + 2201, + 2202, + 2203, + 4328, + 2204, + 2205, + 2206, + 2207, + 2208, + 4318, + 2209, + 2210, + 2211, + 4340, + 2212, + 2213, + 2214, + 2215, + 2216, + 2217, + 2218, + 2219, + 2220, + 2221, + 2222, + 2223, + 2224, + 2225, + 2226, + 2227, + 2228, + 2229, + 2230, + 2231, + 2232, + 2233, + 2234, + 2235, + 2236, + 2237, + 2238, + 2239, + 2240, + 2241, + 2242, + 2243, + 2244, + 2245, + 2246, + 2247, + 2248, + 2249, + 2250, + 2251, + 2252, + 2253, + 2254, + 2255, + 2256, + 2257, + 2258, + 2259, + 2260, + 2261, + 2262, + 2263, + 2264, + 2265, + 2266, + 2267, + 2268, + 2269, + 2270, + 2271, + 2272, + 2273, + 2274, + 2275, + 2276, + 2277, + 2278, + 2279, + 2280, + 2281, + 2282, + 2283, + 2284, + 2285, + 2286, + 2287, + 2288, + 2289, + 2290, + 2291, + 2292, + 2293, + 2294, + 2295, + 2296, + 2297, + 2298, + 2299, + 2300, + 2301, + 2302, + 2303, + 2304, + 2305, + 2306, + 2307, + 2308, + 2309, + 4341, + 2310, + 4345, + 2311, + 2312, + 2313, + 2314, + 2315, + 2316, + 4343, + 2317, + 2318, + 2319, + 2320, + 2321, + 2322, + 2323, + 2324, + 2325, + 2326, + 2327, + 2328, + 2329, + 2330, + 2331, + 2332, + 2333, + 2334, + 2335, + 2336, + 2337, + 2338, + 2339, + 2340, + 2341, + 2342, + 2343, + 2344, + 2345, + 2346, + 2347, + 2348, + 2349, + 2350, + 2351, + 2352, + 2353, + 2354, + 2355, + 2356, + 2357, + 2358, + 2359, + 2360, + 2361, + 2362, + 2363, + 2364, + 2365, + 2366, + 2367, + 2368, + 2369, + 2370, + 2371, + 2372, + 2373, + 2374, + 2375, + 2376, + 2377, + 2378, + 2379, + 2380, + 2381, + 2382, + 2383, + 2384, + 2385, + 2386, + 4329, + 2387, + 2388, + 2389, + 2390, + 2391, + 2392, + 2393, + 2394, + 4302, + 2395, + 4323, + 2396, + 2397, + 2398, + 4317, + 2399, + 4313, + 2400, + 2401, + 2402, + 2403, + 2404, + 2405, + 4352, + 2406, + 4300, + 2407, + 2408, + 2409, + 4354, + 2410, + 4358, + 2411, + 2412, + 2414, + 4355, + 2417, + 2419, + 2420, + 2421, + 2424, + 2425, + 2426, + 4359, + 4357, + 4353, + 2427, + 2428, + 2429, + 2430, + 2431, + 2432, + 2433, + 2434, + 2435, + 2436, + 2437, + 2438, + 2439, + 2440, + 2441, + 2442, + 2443, + 2444, + 2445, + 2446, + 2447, + 2448, + 2449, + 2450, + 2451, + 2452, + 2453, + 2454, + 2455, + 2456, + 2457, + 2458, + 2459, + 2460, + 2461, + 2462, + 2463, + 2464, + 2465, + 2466, + 2467, + 2468, + 2469, + 2470, + 2471, + 2472, + 2473, + 2474, + 2475, + 2476, + 2477, + 2478, + 2479, + 2480, + 2481, + 2482, + 2483, + 4344, + 2484, + 4362, + 2485, + 2486, + 4334, + 2487, + 4364, + 2488, + 2489, + 2490, + 2491, + 2492, + 2493, + 4363, + 2494, + 4365, + 2495, + 4342, + 2496, + 2497, + 4366, + 2498, + 4368, + 2499, + 4337, + 2500, + 2501, + 2502, + 4361, + 2503, + 4369, + 2504, + 4367, + 2505, + 2506, + 2507, + 2508, + 2509, + 2510, + 2511, + 2512, + 2513, + 2514, + 2515, + 2516, + 2517, + 2518, + 2519, + 2520, + 2521, + 2522, + 2523, + 2524, + 2525, + 2526, + 2527, + 2528, + 2529, + 2530, + 2531, + 2532, + 2533, + 2534, + 2535, + 2536, + 2537, + 2538, + 2539, + 2540, + 2541, + 2542, + 2543, + 2544, + 2545, + 2546, + 2547, + 2548, + 2549, + 2550, + 2551, + 2552, + 2553, + 2554, + 2555, + 2556, + 2557, + 2558, + 2559, + 2560, + 2561, + 2562, + 2563, + 2564, + 2565, + 2566, + 2567, + 2568, + 2569, + 2570, + 2571, + 2572, + 2573, + 2574, + 2575, + 2576, + 2577, + 2578, + 2579, + 2580, + 2581, + 2582, + 2583, + 2584, + 2585, + 2586, + 2587, + 2588, + 2589, + 2590, + 2591, + 2592, + 2593, + 2594, + 2595, + 2596, + 2597, + 2598, + 2599, + 2600, + 2601, + 2602, + 2603, + 2604, + 2605, + 2606, + 2607, + 2608, + 2609, + 2610, + 2611, + 2612, + 2613, + 2614, + 2615, + 2616, + 2617, + 2618, + 2619, + 2620, + 2621, + 2622, + 2623, + 2624, + 2625, + 2626, + 2627, + 2628, + 2629, + 2630, + 2631, + 2632, + 2633, + 2634, + 2635, + 2636, + 2637, + 2638, + 2639, + 2640, + 2641, + 2642, + 2643, + 2644, + 2645, + 2646, + 2647, + 2648, + 2649, + 2650, + 2651, + 2652, + 2653, + 2654, + 2655, + 2656, + 2657, + 2658, + 2659, + 2660, + 2661, + 2662, + 2663, + 2664, + 2665, + 2666, + 2667, + 2668, + 2669, + 2670, + 2671, + 2672, + 2673, + 2674, + 2675, + 2676, + 2677, + 2678, + 2679, + 2680, + 2681, + 2682, + 2683, + 2684, + 2685, + 2686, + 2687, + 2688, + 2689, + 2690, + 2691, + 2692, + 2693, + 2694, + 2695, + 2696, + 2697, + 2698, + 2699, + 2700, + 2701, + 2702, + 2703, + 2704, + 4331, + 2705, + 2706, + 2707, + 4325, + 2708, + 2709, + 2710, + 2711, + 2712, + 2713, + 2714, + 2715, + 2716, + 2717, + 2718, + 2719, + 2720, + 2721, + 2722, + 2723, + 2724, + 2725, + 2726, + 2727, + 2728, + 2729, + 2730, + 2731, + 2732, + 2733, + 2734, + 2735, + 2736, + 2737, + 2738, + 2739, + 2740, + 2741, + 2742, + 2743, + 2744, + 2745, + 2746, + 2747, + 2748, + 2749, + 2750, + 2751, + 2752, + 2753, + 2754, + 2755, + 2756, + 2757, + 2758, + 2759, + 2760, + 2761, + 2762, + 2763, + 2764, + 2765, + 2766, + 2767, + 2768, + 2769, + 2770, + 2771, + 2772, + 4370, + 2773, + 4372, + 2774, + 2775, + 2776, + 4375, + 2777, + 2778, + 2779, + 2780, + 4376, + 2781, + 4379, + 2782, + 2783, + 2784, + 2785, + 2786, + 2787, + 2788, + 4381, + 2789, + 2790, + 2791, + 2792, + 2793, + 2794, + 2795, + 2796, + 4377, + 2797, + 2798, + 2799, + 2800, + 2801, + 4253, + 2802, + 4385, + 2803, + 2804, + 2805, + 2806, + 2807, + 2808, + 2809, + 2810, + 4392, + 2811, + 4395, + 2812, + 4396, + 2813, + 4393, + 2814, + 2815, + 2816, + 2817, + 2818, + 2819, + 2820, + 2821, + 2822, + 2823, + 2824, + 2825, + 2826, + 2827, + 2828, + 2829, + 2830, + 2831, + 2832, + 2833, + 2834, + 2835, + 2836, + 2837, + 2838, + 2839, + 2840, + 2841, + 2842, + 2843, + 2844, + 2845, + 2846, + 2847, + 2848, + 2849, + 2850, + 2851, + 2852, + 2853, + 2854, + 2855, + 2856, + 2857, + 4380, + 2858, + 2859, + 2860, + 2861, + 4397, + 2862, + 2863, + 2864, + 4371, + 2865, + 2866, + 2867, + 2868, + 2869, + 2870, + 2871, + 2872, + 2873, + 2874, + 2875, + 2876, + 2877, + 2878, + 2879, + 2880, + 2881, + 2882, + 2883, + 2884, + 2885, + 2886, + 2887, + 2888, + 2889, + 2890, + 2891, + 2892, + 2893, + 2894, + 2895, + 2896, + 2897, + 2898, + 2899, + 2900, + 2901, + 2902, + 2903, + 2904, + 2905, + 2906, + 2907, + 2908, + 2909, + 2910, + 2911, + 2912, + 2913, + 2914, + 2915, + 2916, + 2917, + 2918, + 2919, + 2920, + 2921, + 2922, + 2923, + 2924, + 2925, + 2926, + 2927, + 2928, + 2929, + 2930, + 2931, + 2932, + 2933, + 2934, + 2935, + 2936, + 2937, + 2938, + 2939, + 2940, + 2941, + 2942, + 2943, + 2944, + 2945, + 2946, + 2947, + 2948, + 2949, + 2950, + 2951, + 2952, + 2953, + 2954, + 2955, + 2956, + 2957, + 2958, + 2959, + 2960, + 2961, + 2962, + 2963, + 2964, + 2965, + 2966, + 4398, + 2967, + 4400, + 2968, + 2969, + 2970, + 2971, + 2972, + 2973, + 2974, + 2975, + 2976, + 2977, + 2978, + 2979, + 2980, + 2981, + 2982, + 2983, + 2984, + 2985, + 2986, + 2987, + 2988, + 2989, + 2990, + 2991, + 2992, + 2993, + 2994, + 2995, + 2996, + 2997, + 2998, + 2999, + 3000, + 3001, + 3002, + 3003, + 3004, + 3005, + 3006, + 3007, + 3008, + 3009, + 3010, + 3011, + 3012, + 3013, + 3014, + 3015, + 3016, + 3017, + 3018, + 3019, + 3020, + 3021, + 3022, + 3023, + 3024, + 3025, + 3026, + 3027, + 3028, + 3029, + 3030, + 3031, + 3032, + 3033, + 3034, + 3035, + 3036, + 3037, + 3038, + 3039, + 3040, + 3041, + 3042, + 3043, + 3044, + 4383, + 3045, + 3046, + 3047, + 3048, + 3049, + 4374, + 3050, + 4297, + 3051, + 3052, + 3053, + 3054, + 3055, + 3056, + 4314, + 3057, + 4373, + 3058, + 3059, + 3060, + 3061, + 3062, + 3063, + 3064, + 3065, + 4416, + 4411, + 3066, + 4414, + 3067, + 3068, + 3069, + 4299, + 3070, + 3072, + 4413, + 3075, + 3077, + 3078, + 3079, + 3082, + 3083, + 3084, + 3085, + 3086, + 4412, + 4410, + 3087, + 3088, + 3089, + 3090, + 3091, + 3092, + 3093, + 3094, + 3095, + 3096, + 3097, + 3098, + 3099, + 3100, + 3101, + 3102, + 3103, + 3104, + 3105, + 3106, + 3107, + 3108, + 3109, + 3110, + 3111, + 3112, + 3113, + 3114, + 3115, + 3116, + 3117, + 3118, + 3119, + 3120, + 3121, + 3122, + 3123, + 3124, + 3125, + 3126, + 3127, + 3128, + 3129, + 3130, + 3131, + 3132, + 3133, + 3134, + 3135, + 3136, + 3137, + 3138, + 3139, + 3140, + 3141, + 4418, + 3142, + 4401, + 3143, + 3144, + 3145, + 3146, + 4420, + 3147, + 4394, + 3148, + 3149, + 4422, + 3150, + 4421, + 3151, + 3152, + 3153, + 3154, + 4399, + 3155, + 4391, + 3156, + 4425, + 3157, + 4424, + 3158, + 3159, + 3160, + 3161, + 3162, + 3163, + 4423, + 3164, + 4426, + 3165, + 4419, + 3166, + 3167, + 3168, + 3169, + 3170, + 3171, + 3172, + 3173, + 3174, + 3175, + 3176, + 3177, + 3178, + 3179, + 3180, + 3181, + 3182, + 3183, + 3184, + 3185, + 3186, + 3187, + 3188, + 3189, + 3190, + 3191, + 3192, + 3193, + 3194, + 3195, + 3196, + 3197, + 3198, + 3199, + 3200, + 3201, + 3202, + 3203, + 3204, + 3205, + 3206, + 3207, + 3208, + 3209, + 3210, + 3211, + 3212, + 3213, + 3214, + 3215, + 3216, + 3217, + 3218, + 3219, + 3220, + 3221, + 3222, + 3223, + 3224, + 3225, + 3226, + 3227, + 3228, + 3229, + 3230, + 3231, + 3232, + 3233, + 3234, + 3235, + 3236, + 3237, + 3238, + 3239, + 3240, + 3241, + 3242, + 3243, + 3244, + 3245, + 3246, + 3247, + 3248, + 3249, + 3250, + 3251, + 3252, + 3253, + 3254, + 3255, + 3256, + 3257, + 3258, + 3259, + 3260, + 3261, + 3262, + 3263, + 3264, + 3265, + 3266, + 3267, + 3268, + 3269, + 3270, + 3271, + 3272, + 3273, + 3274, + 3275, + 3276, + 3277, + 3278, + 3279, + 3280, + 3281, + 3282, + 3283, + 3284, + 3285, + 3286, + 3287, + 3288, + 3289, + 3290, + 3291, + 3292, + 3293, + 3294, + 3295, + 3296, + 3297, + 3298, + 3299, + 3300, + 3301, + 3302, + 3303, + 3304, + 3305, + 3306, + 3307, + 3308, + 3309, + 3310, + 3311, + 3312, + 3313, + 3314, + 3315, + 3316, + 3317, + 3318, + 3319, + 3320, + 3321, + 3322, + 3323, + 3324, + 3325, + 3326, + 3327, + 3328, + 3329, + 3330, + 3331, + 3332, + 3333, + 3334, + 3335, + 3336, + 3337, + 3338, + 3339, + 3340, + 3341, + 3342, + 3343, + 3344, + 3345, + 3346, + 3347, + 3348, + 3349, + 3350, + 3351, + 3352, + 3353, + 3354, + 3355, + 3356, + 3357, + 3358, + 3359, + 3360, + 3361, + 3362, + 3363, + 3364, + 4384, + 3365, + 3366, + 4382, + 3367, + 3368, + 3369, + 3370, + 3371, + 3372, + 3373, + 3374, + 3375, + 3376, + 3377, + 3378, + 3379, + 3380, + 3381, + 3382, + 3383, + 3384, + 3385, + 3386, + 3387, + 3388, + 3389, + 3390, + 3391, + 3392, + 3393, + 3394, + 3395, + 3396, + 3397, + 3398, + 3399, + 3400, + 3401, + 3402, + 3403, + 3404, + 3405, + 3406, + 3407, + 3408, + 3409, + 3410, + 3411, + 3412, + 3413, + 3414, + 3415, + 3416, + 3417; + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.970101, + 0.970101, + 0.970101, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999437, + 0.999437, + 0.999437, + 0.999437, + 0.552841, + 0.552841, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999259, + 0.999259, + 0.999259, + 0.999259, + 0.999259, + 0.547701, + 0.547701, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999744, + 0.999735, + 0.887760, + 0.887760, + 0.497118, + 0.497118, + 0.339849, + 0.339849, + 0.339658, + 0.339658, + 0.498042, + 0.498042, + 0.889854, + 0.889854, + 0.693299, + 0.692637, + 0.033561, + 0.033541, + 0.999907, + 0.999907, + 0.999906, + 0.999906, + 0.999362, + 0.999363, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 0.993695, + 0.713304, + 0.713304, + 0.897813, + 0.897813, + 1.000000, + 0.999983, + 0.999999, + 0.999999, + 0.999942, + 0.999942, + 0.999393, + 0.999732, + 0.567551, + 0.515509, + 0.855685, + 0.985010, + 0.985010, + 0.498224, + 0.498224, + 0.310874, + 0.383672, + 0.501663, + 0.501663, + 0.707005, + 0.707005, + 0.680489, + 0.510297, + 0.029527, + 0.029527, + 0.013410, + 0.956949, + 0.651153, + 0.930744, + 1.000000, + 1.000000, + 0.999386, + 0.999386, + 0.999386, + 0.999386, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.888821, + 0.888821, + 0.704999, + 0.704999, + 0.992606, + 0.999999, + 1.000000, + 1.000000, + 0.999388, + 0.999941, + 0.999941, + 0.999999, + 0.999999, + 0.999982, + 0.999729, + 0.562194, + 0.982777, + 0.848121, + 0.513370, + 0.669851, + 0.696438, + 0.696438, + 0.696438, + 0.501175, + 0.501175, + 0.384953, + 0.312190, + 0.498315, + 0.498315, + 0.508731, + 0.029902, + 0.029902, + 0.013492, + 0.953945, + 0.928954, + 0.647332, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999125, + 0.999125, + 0.999125, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.000000,-0.000002,1.278853,0.000000,1.112235,-0.156313,-0.000000,0.000000,0.204616,1.455927,0.000002,0.000000,-61.950306,-62.105236,-0.142288,1.000000;; + } + } + } + } + + Frame Box01 { + + + FrameTransformMatrix { + -1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.341751,858.815247,1.000000;; + } + + Frame Bip01 { + + + FrameTransformMatrix { + 0.186552,-0.974653,0.123489,0.000000,0.982171,0.187991,0.000000,0.000000,-0.023215,0.121288,0.992346,0.000000,-88.977890,-857.346008,247.541595,1.000000;; + } + + Frame Bip01_Footsteps { + + + FrameTransformMatrix { + 0.186552,0.982171,-0.023215,0.000000,-0.974653,0.187991,0.121288,0.000000,0.123489,-0.000000,0.992346,0.000000,-31.624149,0.000000,-254.128143,1.000000;; + } + } + + Frame Bip01_Pelvis { + + + FrameTransformMatrix { + -0.000000,0.011807,0.999930,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999930,-0.011807,0.000000,-2.454305,-1.950977,-0.000005,1.000000;; + } + + Frame Bip01_Spine { + + + FrameTransformMatrix { + 0.999137,0.041531,0.000982,0.000000,-0.040353,0.975880,-0.214545,0.000000,-0.009868,0.214320,0.976714,0.000000,27.422213,8.709480,-0.319006,1.000000;; + } + + Frame Bip01_Spine1 { + + + FrameTransformMatrix { + 0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178080,-0.022084,0.000000,1.000000;; + } + + Frame Bip01_Spine2 { + + + FrameTransformMatrix { + 0.999958,0.008483,0.003477,0.000000,-0.008313,0.998890,-0.046374,0.000000,-0.003867,0.046343,0.998918,0.000000,28.182159,-0.022430,0.001040,1.000000;; + } + + Frame Bip01_Spine3 { + + + FrameTransformMatrix { + 0.999837,-0.017696,0.003477,0.000000,0.017838,0.998765,-0.046374,0.000000,-0.002652,0.046428,0.998918,0.000000,28.181417,-0.033880,0.001568,1.000000;; + } + + Frame Bip01_Neck { + + + FrameTransformMatrix { + 0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566055,-0.019138,0.000001,1.000000;; + } + + Frame Bip01_Head { + + + FrameTransformMatrix { + 0.979775,-0.188667,-0.066683,0.000000,0.195389,0.973921,0.115333,0.000000,0.043184,-0.126029,0.991086,0.000000,27.900173,0.000003,0.000000,1.000000;; + } + + Frame Dummy21 { + + + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,0.000027,0.000002,1.000000;; + } + } + } + + Frame Bip01_L_Clavicle { + + + FrameTransformMatrix { + -0.185356,0.308957,0.932839,0.000000,-0.499811,-0.846968,0.181203,0.000000,0.846069,-0.432656,0.311411,0.000000,-12.374969,4.006883,8.346215,1.000000;; + } + + Frame Bip01_L_UpperArm { + + + FrameTransformMatrix { + 0.640423,0.117307,-0.759011,0.000000,0.064965,0.976451,0.205728,0.000000,0.765270,-0.181062,0.617720,0.000000,31.000208,-0.000032,-0.000004,1.000000;; + } + + Frame Bip01_L_Forearm { + + + FrameTransformMatrix { + 0.485335,-0.874328,-0.000000,0.000000,0.874328,0.485335,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202522,-0.000023,0.000014,1.000000;; + } + + Frame Bip01_L_Hand { + + + FrameTransformMatrix { + 0.999511,-0.027531,-0.014824,0.000000,-0.015327,-0.018154,-0.999718,0.000000,0.027254,0.999456,-0.018567,0.000000,61.671467,0.000001,-0.000001,1.000000;; + } + + Frame Bip01_L_Finger0 { + + + FrameTransformMatrix { + 0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410522,3.054963,-10.755418,1.000000;; + } + + Frame Bip01_L_Finger01 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075084,0.000006,-0.000007,1.000000;; + } + + Frame Bip01_L_Finger02 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961566,-0.000008,0.000006,1.000000;; + } + + Frame Dummy06 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961566,-0.000008,0.000003,1.000000;; + } + } + } + } + } + + Frame Bip01_L_Finger1 { + + + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087988,0.354694,-0.505022,1.000000;; + } + + Frame Bip01_L_Finger11 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300090,-0.000022,-0.000024,1.000000;; + } + + Frame Bip01_L_Finger12 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850065,0.000028,0.000040,1.000000;; + } + + Frame Dummy03 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207734,-0.000002,-0.000004,1.000000;; + } + } + } + } + } + } + } + } + } + + Frame Bip01_R_Clavicle { + + + FrameTransformMatrix { + -0.397155,0.379708,-0.835518,0.000000,-0.502616,-0.851720,-0.148157,0.000000,-0.767883,0.361103,0.529112,0.000000,-12.374941,4.006959,-8.346190,1.000000;; + } + + Frame Bip01_R_UpperArm { + + + FrameTransformMatrix { + 0.532891,0.645602,0.547015,0.000000,-0.380503,0.760229,-0.526564,0.000000,-0.755807,0.072461,0.650772,0.000000,31.000195,-0.000004,0.000004,1.000000;; + } + + Frame Bip01_R_Forearm { + + + FrameTransformMatrix { + 0.881719,-0.471776,0.000000,0.000000,0.471776,0.881718,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202530,-0.000026,0.000000,1.000000;; + } + + Frame Bip01_R_Hand { + + + FrameTransformMatrix { + 0.999848,-0.010016,0.014267,0.000000,-0.014446,-0.018025,0.999733,0.000000,-0.009756,-0.999787,-0.018167,0.000000,61.671482,0.000009,-0.000000,1.000000;; + } + + Frame Bip01_R_Finger0 { + + + FrameTransformMatrix { + 0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410507,3.054970,10.755430,1.000000;; + } + + Frame Bip01_R_Finger01 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075073,0.000020,-0.000001,1.000000;; + } + + Frame Bip01_R_Finger02 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961570,-0.000010,-0.000003,1.000000;; + } + + Frame Dummy01 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,5.961568,-0.000011,0.000000,1.000000;; + } + } + } + } + } + + Frame Bip01_R_Finger1 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087997,0.354687,0.504994,1.000000;; + } + + Frame Bip01_R_Finger11 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300055,-0.000003,-0.000036,1.000000;; + } + + Frame Bip01_R_Finger12 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850063,0.000009,0.000012,1.000000;; + } + + Frame Dummy02 { + + + FrameTransformMatrix { + 1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207763,0.000001,-0.000002,1.000000;; + } + } + } + } + } + } + } + } + } + } + } + } + } + + Frame Bip01_L_Thigh { + + + FrameTransformMatrix { + -0.959397,-0.281208,0.021883,0.000000,-0.279994,0.958874,0.046525,0.000000,-0.034066,0.038509,-0.998677,0.000000,-27.730272,-13.958670,28.295168,1.000000;; + } + + Frame Bip01_L_Calf { + + + FrameTransformMatrix { + 0.912034,-0.410114,-0.000000,0.000000,0.410114,0.912034,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231491,-0.000008,-0.000001,1.000000;; + } + + Frame Bip01_L_Foot { + + + FrameTransformMatrix { + 0.832169,0.546757,0.092472,0.000000,-0.549113,0.835748,0.000044,0.000000,-0.077259,-0.050814,0.995715,0.000000,119.231468,-0.000006,0.000000,1.000000;; + } + + Frame Bip01_L_Toe0 { + + + FrameTransformMatrix { + 0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423262,34.577110,0.000002,1.000000;; + } + + Frame Dummy16 { + + + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738586,0.000005,-0.000001,1.000000;; + } + } + } + } + } + } + + Frame Bip01_R_Thigh { + + + FrameTransformMatrix { + -0.965965,0.253205,-0.052900,0.000000,0.253587,0.886612,-0.386799,0.000000,-0.051038,-0.387049,-0.920645,0.000000,-27.789658,-0.963900,-30.864017,1.000000;; + } + + Frame Bip01_R_Calf { + + + FrameTransformMatrix { + 1.000000,-0.000691,-0.000000,0.000000,0.000691,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231522,0.000021,-0.000011,1.000000;; + } + + Frame Bip01_R_Foot { + + + FrameTransformMatrix { + 0.988831,0.124156,0.082452,0.000000,-0.122246,0.992109,-0.027835,0.000000,-0.085257,0.017445,0.996206,0.000000,119.231476,-0.000039,0.000023,1.000000;; + } + + Frame Bip01_R_Toe0 { + + + FrameTransformMatrix { + 0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423260,34.577152,-0.000010,1.000000;; + } + + Frame Dummy11 { + + + FrameTransformMatrix { + 1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738579,0.000004,-0.000012,1.000000;; + } + } + } + } + } + } + } + } + } + } +} + +AnimationSet { + + + Animation { + + + AnimationKey { + 4; + 2; + 0;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;, + 4960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;; + } + { Scene_Root } + } + + Animation { + + + AnimationKey { + 4; + 2; + 0;16;1.278853,0.000000,-0.000000,0.000000,0.000000,0.000000,1.123165,0.000000,0.000000,-1.470235,0.000000,0.000000,0.135977,2.027985,133.967667,1.000000;;, + 4960;16;1.278853,0.000000,-0.000000,0.000000,0.000000,0.000000,1.123165,0.000000,0.000000,-1.470235,0.000000,0.000000,0.135977,2.027985,133.967667,1.000000;;; + } + { body } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.951797,351.625824,1.000000;;, + 80;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.958298,360.078979,1.000000;;, + 160;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.964798,368.532135,1.000000;;, + 240;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.971298,376.985291,1.000000;;, + 320;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.977798,385.438446,1.000000;;, + 400;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.984299,393.891602,1.000000;;, + 480;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.990799,402.344757,1.000000;;, + 560;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.997299,410.797913,1.000000;;, + 640;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.003784,419.251099,1.000000;;, + 720;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.010284,427.704254,1.000000;;, + 800;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.016785,436.157410,1.000000;;, + 880;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.023285,444.610565,1.000000;;, + 960;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.029785,453.063721,1.000000;;, + 1040;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.036285,461.516876,1.000000;;, + 1120;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.042786,469.970032,1.000000;;, + 1200;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.049286,478.423187,1.000000;;, + 1280;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.055786,486.876343,1.000000;;, + 1360;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.062286,495.329498,1.000000;;, + 1440;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.068787,503.782654,1.000000;;, + 1520;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.075287,512.235779,1.000000;;, + 1600;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.081787,520.688965,1.000000;;, + 1680;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.088287,529.142090,1.000000;;, + 1760;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.094788,537.595276,1.000000;;, + 1840;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.101273,546.048462,1.000000;;, + 1920;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.107773,554.501587,1.000000;;, + 2000;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.114273,562.954773,1.000000;;, + 2080;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.120773,571.407898,1.000000;;, + 2160;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.127274,579.861084,1.000000;;, + 2240;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.133774,588.314209,1.000000;;, + 2320;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.140274,596.767395,1.000000;;, + 2400;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.146774,605.220520,1.000000;;, + 2480;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.153275,613.673706,1.000000;;, + 2560;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.159775,622.126892,1.000000;;, + 2640;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.166275,630.580017,1.000000;;, + 2720;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.172775,639.033142,1.000000;;, + 2800;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.179276,647.486328,1.000000;;, + 2880;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.185776,655.939514,1.000000;;, + 2960;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.192276,664.392639,1.000000;;, + 3040;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.198761,672.845764,1.000000;;, + 3120;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.205261,681.298950,1.000000;;, + 3200;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.211761,689.752136,1.000000;;, + 3280;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.218262,698.205261,1.000000;;, + 3360;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.224762,706.658386,1.000000;;, + 3440;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.231262,715.111572,1.000000;;, + 3520;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.237762,723.564758,1.000000;;, + 3600;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.244263,732.017883,1.000000;;, + 3680;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.250763,740.471069,1.000000;;, + 3760;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.257263,748.924194,1.000000;;, + 3840;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.263763,757.377380,1.000000;;, + 3920;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.270264,765.830505,1.000000;;, + 4000;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.276764,774.283691,1.000000;;, + 4080;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.283264,782.736816,1.000000;;, + 4160;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.289764,791.190002,1.000000;;, + 4240;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.296249,799.643127,1.000000;;, + 4320;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.302750,808.096313,1.000000;;, + 4400;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.309250,816.549500,1.000000;;, + 4480;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.315750,825.002625,1.000000;;, + 4560;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.322250,833.455750,1.000000;;, + 4640;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.328751,841.908936,1.000000;;, + 4720;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.335251,850.362122,1.000000;;, + 4800;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-246.341751,858.815247,1.000000;;, + 4960;16;-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-88.696747,-245.951797,351.625824,1.000000;;; + } + { Box01 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.215193,-0.969920,0.113783,0.000000,0.976260,0.216600,-0.000000,0.000000,-0.024646,0.111082,0.993506,0.000000,-88.995270,-350.280182,247.734116,1.000000;;, + 80;16;0.230210,-0.966046,0.117296,0.000000,0.972762,0.231808,-0.000015,0.000000,-0.027176,0.114104,0.993097,0.000000,-89.026062,-358.696838,245.527908,1.000000;;, + 160;16;0.245161,-0.961926,0.120806,0.000000,0.969026,0.246960,-0.000085,0.000000,-0.029752,0.117085,0.992676,0.000000,-89.057129,-367.113770,243.259003,1.000000;;, + 240;16;0.260919,-0.957329,0.124270,0.000000,0.964815,0.262931,-0.000218,0.000000,-0.032466,0.119955,0.992248,0.000000,-89.090034,-375.532227,240.737289,1.000000;;, + 320;16;0.274853,-0.952953,0.127816,0.000000,0.960847,0.277077,-0.000391,0.000000,-0.035042,0.122919,0.991798,0.000000,-89.121216,-383.949402,238.279861,1.000000;;, + 400;16;0.284678,-0.949573,0.131414,0.000000,0.957902,0.287096,-0.000570,0.000000,-0.037187,0.126044,0.991327,0.000000,-89.147224,-392.364716,236.076599,1.000000;;, + 480;16;0.290388,-0.947267,0.135499,0.000000,0.956114,0.292995,-0.000732,0.000000,-0.039008,0.129765,0.990777,0.000000,-89.169243,-400.772797,234.318848,1.000000;;, + 560;16;0.290787,-0.946384,0.140711,0.000000,0.955929,0.293596,-0.000834,0.000000,-0.040523,0.134752,0.990050,0.000000,-89.187599,-409.165558,233.295410,1.000000;;, + 640;16;0.287101,-0.946645,0.146409,0.000000,0.956994,0.290106,-0.000860,0.000000,-0.041660,0.140360,0.989224,0.000000,-89.201378,-417.550812,232.904465,1.000000;;, + 720;16;0.280185,-0.947747,0.152550,0.000000,0.959005,0.283386,-0.000790,0.000000,-0.042482,0.146518,0.988295,0.000000,-89.211227,-425.929321,233.223892,1.000000;;, + 800;16;0.269861,-0.949850,0.157988,0.000000,0.961957,0.273201,-0.000596,0.000000,-0.042596,0.152138,0.987441,0.000000,-89.212715,-434.314423,234.003555,1.000000;;, + 880;16;0.255996,-0.953099,0.161456,0.000000,0.965782,0.259355,-0.000282,0.000000,-0.041606,0.156003,0.986880,0.000000,-89.200623,-442.720734,235.017471,1.000000;;, + 960;16;0.239263,-0.957127,0.163283,0.000000,0.970142,0.242538,0.000126,0.000000,-0.039723,0.158377,0.986579,0.000000,-89.177910,-451.145142,236.268890,1.000000;;, + 1040;16;0.220092,-0.961751,0.163077,0.000000,0.974779,0.223171,0.000573,0.000000,-0.036945,0.158838,0.986613,0.000000,-89.144325,-459.592773,237.701111,1.000000;;, + 1120;16;0.199072,-0.966547,0.161733,0.000000,0.979407,0.201892,0.001023,0.000000,-0.033641,0.158199,0.986834,0.000000,-89.104233,-468.053619,239.267197,1.000000;;, + 1200;16;0.176961,-0.971115,0.160062,0.000000,0.983756,0.179506,0.001467,0.000000,-0.030157,0.157202,0.987106,0.000000,-89.062035,-476.518890,240.917862,1.000000;;, + 1280;16;0.153774,-0.975404,0.157925,0.000000,0.987752,0.156024,0.001873,0.000000,-0.026467,0.155703,0.987449,0.000000,-89.017326,-484.990173,242.604843,1.000000;;, + 1360;16;0.129723,-0.979294,0.155422,0.000000,0.991292,0.131664,0.002220,0.000000,-0.022637,0.153781,0.987846,0.000000,-88.970947,-493.466614,244.280289,1.000000;;, + 1440;16;0.105024,-0.982683,0.152656,0.000000,0.994293,0.106652,0.002489,0.000000,-0.018727,0.151523,0.988276,0.000000,-88.923561,-501.947113,245.893738,1.000000;;, + 1520;16;0.079902,-0.985493,0.149728,0.000000,0.996693,0.081216,0.002672,0.000000,-0.014793,0.149019,0.988724,0.000000,-88.875931,-510.430634,247.395233,1.000000;;, + 1600;16;0.054583,-0.987668,0.146741,0.000000,0.998450,0.055589,0.002762,0.000000,-0.010885,0.146363,0.989171,0.000000,-88.828560,-518.915955,248.734818,1.000000;;, + 1680;16;0.029299,-0.989173,0.143799,0.000000,0.999546,0.030007,0.002762,0.000000,-0.007047,0.143652,0.989603,0.000000,-88.782097,-527.401978,249.862305,1.000000;;, + 1760;16;0.004282,-0.990000,0.141004,0.000000,0.999985,0.004707,0.002680,0.000000,-0.003317,0.140991,0.990005,0.000000,-88.736885,-535.887329,250.727417,1.000000;;, + 1840;16;-0.020233,-0.990161,0.138461,0.000000,0.999795,-0.020076,0.002532,0.000000,0.000273,0.138484,0.990365,0.000000,-88.693428,-544.370850,251.288864,1.000000;;, + 1920;16;-0.044014,-0.989693,0.136270,0.000000,0.999024,-0.044107,0.002338,0.000000,0.003697,0.136240,0.990669,0.000000,-88.651924,-552.851196,251.468933,1.000000;;, + 2000;16;-0.066451,-0.988672,0.134580,0.000000,0.997766,-0.066772,0.002131,0.000000,0.006879,0.134421,0.990900,0.000000,-88.613358,-561.326355,251.154114,1.000000;;, + 2080;16;-0.088458,-0.987113,0.133352,0.000000,0.996030,-0.088998,0.001921,0.000000,0.009972,0.132992,0.991067,0.000000,-88.575897,-569.796814,250.409897,1.000000;;, + 2160;16;-0.110697,-0.984964,0.132636,0.000000,0.993768,-0.111454,0.001725,0.000000,0.013084,0.132000,0.991163,0.000000,-88.538185,-578.261963,249.224899,1.000000;;, + 2240;16;-0.133303,-0.982204,0.132311,0.000000,0.990942,-0.134282,0.001543,0.000000,0.016252,0.131318,0.991207,0.000000,-88.499825,-586.723389,247.716156,1.000000;;, + 2320;16;-0.156984,-0.978703,0.132274,0.000000,0.987407,-0.158195,0.001366,0.000000,0.019588,0.130823,0.991212,0.000000,-88.459404,-595.182617,245.969635,1.000000;;, + 2400;16;-0.180673,-0.974575,0.132518,0.000000,0.983275,-0.182121,0.001212,0.000000,0.022953,0.130521,0.991180,0.000000,-88.418640,-603.639404,244.067245,1.000000;;, + 2480;16;-0.203757,-0.969944,0.133012,0.000000,0.978669,-0.205441,0.001087,0.000000,0.026272,0.130397,0.991114,0.000000,-88.378433,-612.094116,242.093201,1.000000;;, + 2560;16;-0.225637,-0.964990,0.133725,0.000000,0.973766,-0.227551,0.000998,0.000000,0.029466,0.130442,0.991018,0.000000,-88.339745,-620.546692,240.126892,1.000000;;, + 2640;16;-0.245728,-0.959945,0.134624,0.000000,0.968795,-0.247860,0.000949,0.000000,0.032457,0.130656,0.990896,0.000000,-88.303505,-628.997253,238.248978,1.000000;;, + 2720;16;-0.263458,-0.955082,0.135677,0.000000,0.964030,-0.265793,0.000938,0.000000,0.035166,0.131044,0.990753,0.000000,-88.270691,-637.445679,236.540161,1.000000;;, + 2800;16;-0.278272,-0.950703,0.136852,0.000000,0.959769,-0.280788,0.000962,0.000000,0.037512,0.131614,0.990591,0.000000,-88.242264,-645.891968,235.080368,1.000000;;, + 2880;16;-0.289622,-0.947123,0.138118,0.000000,0.956329,-0.292289,0.001013,0.000000,0.039411,0.132380,0.990415,0.000000,-88.219269,-654.335876,233.952332,1.000000;;, + 2960;16;-0.296833,-0.944706,0.139362,0.000000,0.954060,-0.299614,0.001070,0.000000,0.040744,0.133278,0.990241,0.000000,-88.203102,-662.778076,233.258194,1.000000;;, + 3040;16;-0.299743,-0.943574,0.140795,0.000000,0.953116,-0.302602,0.001152,0.000000,0.041518,0.134539,0.990038,0.000000,-88.193741,-671.216003,233.019211,1.000000;;, + 3120;16;-0.297684,-0.943957,0.142584,0.000000,0.953755,-0.300582,0.001269,0.000000,0.041660,0.136368,0.989782,0.000000,-88.191994,-679.646973,233.327316,1.000000;;, + 3200;16;-0.291409,-0.945585,0.144741,0.000000,0.955708,-0.294313,0.001411,0.000000,0.041265,0.138741,0.989469,0.000000,-88.196808,-688.071472,234.072937,1.000000;;, + 3280;16;-0.281246,-0.948245,0.147418,0.000000,0.958786,-0.284126,0.001582,0.000000,0.040385,0.141787,0.989073,0.000000,-88.207474,-696.487671,235.200226,1.000000;;, + 3360;16;-0.267718,-0.951692,0.150366,0.000000,0.962706,-0.270543,0.001731,0.000000,0.039033,0.145222,0.988629,0.000000,-88.223839,-704.899170,236.639908,1.000000;;, + 3440;16;-0.251299,-0.955670,0.153436,0.000000,0.967193,-0.254036,0.001827,0.000000,0.037233,0.148862,0.988157,0.000000,-88.245697,-713.308228,238.327179,1.000000;;, + 3520;16;-0.232467,-0.959934,0.156480,0.000000,0.971974,-0.235082,0.001843,0.000000,0.035017,0.152523,0.987679,0.000000,-88.272491,-721.717102,240.193939,1.000000;;, + 3600;16;-0.211709,-0.964255,0.159346,0.000000,0.976795,-0.214171,0.001762,0.000000,0.032428,0.156021,0.987221,0.000000,-88.303909,-730.127869,242.173676,1.000000;;, + 3680;16;-0.189524,-0.968439,0.161884,0.000000,0.981432,-0.191803,0.001579,0.000000,0.029521,0.159178,0.986808,0.000000,-88.339073,-738.542786,244.197083,1.000000;;, + 3760;16;-0.166420,-0.972331,0.163945,0.000000,0.985703,-0.168490,0.001297,0.000000,0.026362,0.161817,0.986469,0.000000,-88.377380,-746.964050,246.194870,1.000000;;, + 3840;16;-0.142916,-0.975820,0.165378,0.000000,0.989467,-0.144756,0.000932,0.000000,0.023030,0.163769,0.986230,0.000000,-88.417694,-755.393494,248.100037,1.000000;;, + 3920;16;-0.120009,-0.978789,0.166042,0.000000,0.992578,-0.121612,0.000515,0.000000,0.019688,0.164871,0.986119,0.000000,-88.458206,-763.833313,249.845062,1.000000;;, + 4000;16;-0.096823,-0.981400,0.165766,0.000000,0.995170,-0.098171,0.000058,0.000000,0.016217,0.164971,0.986165,0.000000,-88.500229,-772.285217,251.362381,1.000000;;, + 4080;16;-0.072995,-0.983711,0.164270,0.000000,0.997253,-0.074069,-0.000416,0.000000,0.012576,0.163788,0.986415,0.000000,-88.544342,-780.752625,252.601303,1.000000;;, + 4160;16;-0.047948,-0.985668,0.161738,0.000000,0.998812,-0.048729,-0.000865,0.000000,0.008734,0.161504,0.986833,0.000000,-88.590874,-789.233582,253.443695,1.000000;;, + 4240;16;-0.020710,-0.987195,0.158170,0.000000,0.999775,-0.021175,-0.001258,0.000000,0.004591,0.158109,0.987411,0.000000,-88.641014,-797.727844,253.722046,1.000000;;, + 4320;16;0.007899,-0.988064,0.153839,0.000000,0.999969,0.007754,-0.001540,0.000000,0.000329,0.153846,0.988095,0.000000,-88.692696,-806.232605,253.533524,1.000000;;, + 4400;16;0.037495,-0.988134,0.148950,0.000000,0.999289,0.037666,-0.001676,0.000000,-0.003954,0.148907,0.988843,0.000000,-88.744514,-814.745667,252.858902,1.000000;;, + 4480;16;0.067688,-0.987302,0.143713,0.000000,0.997673,0.068160,-0.001645,0.000000,-0.008171,0.143490,0.989618,0.000000,-88.795670,-823.264404,251.879715,1.000000;;, + 4560;16;0.098083,-0.985516,0.138337,0.000000,0.995103,0.098835,-0.001442,0.000000,-0.012252,0.137801,0.990384,0.000000,-88.845009,-831.786499,250.727203,1.000000;;, + 4640;16;0.128286,-0.982774,0.133035,0.000000,0.991606,0.129293,-0.001079,0.000000,-0.016140,0.132057,0.991111,0.000000,-88.892197,-840.309204,249.532562,1.000000;;, + 4720;16;0.157601,-0.979148,0.128187,0.000000,0.987305,0.158835,-0.000603,0.000000,-0.019770,0.126655,0.991750,0.000000,-88.935722,-848.828125,248.514465,1.000000;;, + 4800;16;0.186552,-0.974653,0.123489,0.000000,0.982171,0.187991,0.000000,0.000000,-0.023215,0.121288,0.992346,0.000000,-88.977890,-857.346008,247.541595,1.000000;;, + 4960;16;0.215193,-0.969920,0.113783,0.000000,0.976260,0.216600,-0.000000,0.000000,-0.024646,0.111082,0.993506,0.000000,-88.995270,-350.280182,247.734116,1.000000;;; + } + { Bip01 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.215193,0.976260,-0.024646,0.000000,-0.969920,0.216600,0.111082,0.000000,0.113783,-0.000000,0.993506,0.000000,-28.695675,0.000000,-250.557556,1.000000;;, + 80;16;0.230210,0.972762,-0.027176,0.000000,-0.966046,0.231808,0.114104,0.000000,0.117296,-0.000015,0.993097,0.000000,-28.930368,0.003710,-244.942093,1.000000;;, + 160;16;0.245161,0.969026,-0.029752,0.000000,-0.961926,0.246960,0.117085,0.000000,0.120806,-0.000085,0.992676,0.000000,-29.871046,0.021084,-245.453903,1.000000;;, + 240;16;0.260919,0.964815,-0.032466,0.000000,-0.957329,0.262931,0.119955,0.000000,0.124270,-0.000218,0.992248,0.000000,-30.679300,0.053845,-244.962097,1.000000;;, + 320;16;0.274853,0.960848,-0.035042,0.000000,-0.952953,0.277077,0.122919,0.000000,0.127816,-0.000391,0.991798,0.000000,-31.485676,0.096353,-244.314850,1.000000;;, + 400;16;0.284678,0.957902,-0.037187,0.000000,-0.949573,0.287096,0.126044,0.000000,0.131414,-0.000570,0.991327,0.000000,-32.236568,0.139836,-243.178284,1.000000;;, + 480;16;0.290388,0.956114,-0.039008,0.000000,-0.947267,0.292995,0.129765,0.000000,0.135499,-0.000732,0.990777,0.000000,-33.082916,0.178625,-241.903809,1.000000;;, + 560;16;0.290787,0.955929,-0.040523,0.000000,-0.946384,0.293596,0.134752,0.000000,0.140711,-0.000834,0.990050,0.000000,-34.169113,0.202512,-240.416290,1.000000;;, + 640;16;0.287101,0.956994,-0.041660,0.000000,-0.946645,0.290106,0.140360,0.000000,0.146409,-0.000860,0.989224,0.000000,-35.483067,0.208447,-239.743652,1.000000;;, + 720;16;0.280185,0.959006,-0.042482,0.000000,-0.947747,0.283386,0.146518,0.000000,0.152550,-0.000790,0.988295,0.000000,-36.856628,0.190942,-238.775558,1.000000;;, + 800;16;0.269861,0.961957,-0.042596,0.000000,-0.949850,0.273201,0.152138,0.000000,0.157988,-0.000596,0.987441,0.000000,-38.280083,0.144505,-239.254517,1.000000;;, + 880;16;0.255996,0.965782,-0.041605,0.000000,-0.953099,0.259355,0.156003,0.000000,0.161456,-0.000282,0.986880,0.000000,-39.272747,0.068616,-240.050232,1.000000;;, + 960;16;0.239263,0.970142,-0.039723,0.000000,-0.957127,0.242538,0.158377,0.000000,0.163283,0.000126,0.986579,0.000000,-39.905502,-0.030840,-241.114822,1.000000;;, + 1040;16;0.220092,0.974779,-0.036945,0.000000,-0.961751,0.223171,0.158838,0.000000,0.163077,0.000573,0.986613,0.000000,-40.085278,-0.140866,-242.514786,1.000000;;, + 1120;16;0.199072,0.979407,-0.033641,0.000000,-0.966547,0.201892,0.158199,0.000000,0.161733,0.001023,0.986834,0.000000,-40.017071,-0.253015,-244.168747,1.000000;;, + 1200;16;0.176961,0.983756,-0.030157,0.000000,-0.971115,0.179506,0.157202,0.000000,0.160062,0.001467,0.987106,0.000000,-39.888794,-0.365580,-245.995041,1.000000;;, + 1280;16;0.153774,0.987751,-0.026467,0.000000,-0.975404,0.156024,0.155703,0.000000,0.157925,0.001873,0.987449,0.000000,-39.636044,-0.470161,-247.830200,1.000000;;, + 1360;16;0.129723,0.991292,-0.022637,0.000000,-0.979294,0.131664,0.153781,0.000000,0.155422,0.002220,0.987846,0.000000,-39.283993,-0.561041,-249.684158,1.000000;;, + 1440;16;0.105024,0.994293,-0.018727,0.000000,-0.982683,0.106652,0.151523,0.000000,0.152656,0.002489,0.988276,0.000000,-38.839005,-0.633379,-251.439117,1.000000;;, + 1520;16;0.079902,0.996693,-0.014793,0.000000,-0.985493,0.081216,0.149019,0.000000,0.149728,0.002672,0.988724,0.000000,-38.326859,-0.683906,-253.090744,1.000000;;, + 1600;16;0.054583,0.998450,-0.010885,0.000000,-0.987668,0.055589,0.146363,0.000000,0.146741,0.002762,0.989171,0.000000,-37.777111,-0.711023,-254.653427,1.000000;;, + 1680;16;0.029299,0.999546,-0.007047,0.000000,-0.989173,0.030007,0.143652,0.000000,0.143798,0.002762,0.989603,0.000000,-37.200829,-0.714508,-256.011414,1.000000;;, + 1760;16;0.004282,0.999985,-0.003317,0.000000,-0.990000,0.004707,0.140991,0.000000,0.141004,0.002680,0.990005,0.000000,-36.619717,-0.696093,-257.110870,1.000000;;, + 1840;16;-0.020233,0.999795,0.000273,0.000000,-0.990161,-0.020076,0.138484,0.000000,0.138461,0.002532,0.990365,0.000000,-36.057411,-0.659389,-257.906921,1.000000;;, + 1920;16;-0.044014,0.999024,0.003697,0.000000,-0.989694,-0.044107,0.136240,0.000000,0.136270,0.002338,0.990669,0.000000,-35.521038,-0.609429,-258.233765,1.000000;;, + 2000;16;-0.066451,0.997766,0.006879,0.000000,-0.988672,-0.066772,0.134421,0.000000,0.134580,0.002131,0.990900,0.000000,-35.047722,-0.554941,-258.053131,1.000000;;, + 2080;16;-0.088458,0.996030,0.009972,0.000000,-0.987113,-0.088998,0.132992,0.000000,0.133352,0.001921,0.991067,0.000000,-34.556820,-0.497754,-256.825684,1.000000;;, + 2160;16;-0.110697,0.993768,0.013084,0.000000,-0.984964,-0.111454,0.132000,0.000000,0.132636,0.001725,0.991163,0.000000,-34.142933,-0.444083,-255.143707,1.000000;;, + 2240;16;-0.133303,0.990942,0.016252,0.000000,-0.982204,-0.134282,0.131318,0.000000,0.132311,0.001543,0.991207,0.000000,-33.727978,-0.393298,-252.673233,1.000000;;, + 2320;16;-0.156984,0.987407,0.019588,0.000000,-0.978703,-0.158195,0.130822,0.000000,0.132274,0.001366,0.991212,0.000000,-33.356308,-0.344591,-249.960281,1.000000;;, + 2400;16;-0.180673,0.983275,0.022953,0.000000,-0.974575,-0.182121,0.130521,0.000000,0.132518,0.001212,0.991180,0.000000,-33.095207,-0.302633,-247.538528,1.000000;;, + 2480;16;-0.203757,0.978669,0.026272,0.000000,-0.969944,-0.205441,0.130397,0.000000,0.133012,0.001087,0.991114,0.000000,-32.885395,-0.268781,-245.038528,1.000000;;, + 2560;16;-0.225637,0.973766,0.029466,0.000000,-0.964990,-0.227551,0.130442,0.000000,0.133725,0.000998,0.991018,0.000000,-32.691967,-0.244099,-242.275589,1.000000;;, + 2640;16;-0.245728,0.968795,0.032457,0.000000,-0.959945,-0.247860,0.130656,0.000000,0.134624,0.000949,0.990896,0.000000,-32.764847,-0.230935,-241.164581,1.000000;;, + 2720;16;-0.263458,0.964030,0.035166,0.000000,-0.955082,-0.265793,0.131044,0.000000,0.135677,0.000938,0.990753,0.000000,-32.898090,-0.227433,-240.231201,1.000000;;, + 2800;16;-0.278272,0.959769,0.037512,0.000000,-0.950703,-0.280788,0.131614,0.000000,0.136852,0.000962,0.990591,0.000000,-33.050110,-0.232307,-239.229568,1.000000;;, + 2880;16;-0.289622,0.956329,0.039411,0.000000,-0.947123,-0.292289,0.132380,0.000000,0.138118,0.001013,0.990415,0.000000,-33.276829,-0.244129,-238.621353,1.000000;;, + 2960;16;-0.296833,0.954060,0.040744,0.000000,-0.944705,-0.299614,0.133278,0.000000,0.139362,0.001070,0.990241,0.000000,-33.489239,-0.257202,-237.958450,1.000000;;, + 3040;16;-0.299743,0.953116,0.041518,0.000000,-0.943574,-0.302602,0.134539,0.000000,0.140795,0.001152,0.990038,0.000000,-33.823746,-0.276747,-237.841446,1.000000;;, + 3120;16;-0.297684,0.953755,0.041660,0.000000,-0.943957,-0.300582,0.136368,0.000000,0.142584,0.001269,0.989782,0.000000,-34.225349,-0.304588,-237.584305,1.000000;;, + 3200;16;-0.291409,0.955708,0.041265,0.000000,-0.945585,-0.294313,0.138741,0.000000,0.144741,0.001411,0.989469,0.000000,-34.849762,-0.339790,-238.237503,1.000000;;, + 3280;16;-0.281246,0.958786,0.040385,0.000000,-0.948245,-0.284126,0.141787,0.000000,0.147418,0.001582,0.989073,0.000000,-35.660633,-0.382615,-239.258606,1.000000;;, + 3360;16;-0.267718,0.962706,0.039033,0.000000,-0.951692,-0.270543,0.145222,0.000000,0.150366,0.001731,0.988629,0.000000,-36.596420,-0.421292,-240.614899,1.000000;;, + 3440;16;-0.251299,0.967193,0.037233,0.000000,-0.955671,-0.254036,0.148862,0.000000,0.153436,0.001827,0.988157,0.000000,-37.616859,-0.447802,-242.259262,1.000000;;, + 3520;16;-0.232467,0.971974,0.035017,0.000000,-0.959934,-0.235082,0.152522,0.000000,0.156480,0.001843,0.987679,0.000000,-38.677807,-0.455441,-244.129257,1.000000;;, + 3600;16;-0.211709,0.976794,0.032428,0.000000,-0.964255,-0.214171,0.156021,0.000000,0.159346,0.001762,0.987221,0.000000,-39.733059,-0.439425,-246.164780,1.000000;;, + 3680;16;-0.189524,0.981432,0.029521,0.000000,-0.968439,-0.191803,0.159178,0.000000,0.161884,0.001579,0.986808,0.000000,-40.710854,-0.397097,-248.163681,1.000000;;, + 3760;16;-0.166420,0.985703,0.026362,0.000000,-0.972330,-0.168490,0.161817,0.000000,0.163945,0.001297,0.986469,0.000000,-41.575722,-0.328980,-250.164444,1.000000;;, + 3840;16;-0.142916,0.989467,0.023030,0.000000,-0.975820,-0.144756,0.163769,0.000000,0.165378,0.000932,0.986230,0.000000,-42.260056,-0.238165,-252.018021,1.000000;;, + 3920;16;-0.120009,0.992578,0.019688,0.000000,-0.978789,-0.121612,0.164871,0.000000,0.166042,0.000515,0.986119,0.000000,-42.725815,-0.132566,-253.747559,1.000000;;, + 4000;16;-0.096823,0.995170,0.016217,0.000000,-0.981401,-0.098171,0.164971,0.000000,0.165766,0.000058,0.986165,0.000000,-42.921295,-0.014893,-255.344513,1.000000;;, + 4080;16;-0.072995,0.997253,0.012576,0.000000,-0.983711,-0.074069,0.163788,0.000000,0.164270,-0.000416,0.986415,0.000000,-42.753769,0.108166,-256.729523,1.000000;;, + 4160;16;-0.047948,0.998812,0.008734,0.000000,-0.985668,-0.048729,0.161504,0.000000,0.161738,-0.000865,0.986833,0.000000,-42.248627,0.226077,-257.777344,1.000000;;, + 4240;16;-0.020710,0.999775,0.004591,0.000000,-0.987195,-0.021175,0.158109,0.000000,0.158170,-0.001258,0.987411,0.000000,-41.379543,0.329120,-258.320129,1.000000;;, + 4320;16;0.007899,0.999969,0.000329,0.000000,-0.988064,0.007754,0.153846,0.000000,0.153839,-0.001540,0.988095,0.000000,-40.226177,0.402630,-258.369110,1.000000;;, + 4400;16;0.037495,0.999289,-0.003954,0.000000,-0.988134,0.037666,0.148907,0.000000,0.148950,-0.001676,0.988843,0.000000,-38.856068,0.437144,-257.956085,1.000000;;, + 4480;16;0.067688,0.997673,-0.008171,0.000000,-0.987302,0.068160,0.143490,0.000000,0.143713,-0.001645,0.989618,0.000000,-37.303371,0.426951,-256.874268,1.000000;;, + 4560;16;0.098083,0.995103,-0.012252,0.000000,-0.985516,0.098835,0.137801,0.000000,0.138337,-0.001442,0.990384,0.000000,-35.704922,0.372164,-255.618713,1.000000;;, + 4640;16;0.128286,0.991606,-0.016140,0.000000,-0.982774,0.129293,0.132057,0.000000,0.133035,-0.001079,0.991111,0.000000,-34.232403,0.277539,-255.031479,1.000000;;, + 4720;16;0.157601,0.987305,-0.019770,0.000000,-0.979148,0.158835,0.126655,0.000000,0.128187,-0.000603,0.991750,0.000000,-32.951950,0.154989,-254.940338,1.000000;;, + 4800;16;0.186552,0.982171,-0.023215,0.000000,-0.974653,0.187991,0.121288,0.000000,0.123489,-0.000000,0.992346,0.000000,-31.477245,0.000000,-252.947632,1.000000;;, + 4960;16;0.215193,0.976260,-0.024646,0.000000,-0.969920,0.216600,0.111082,0.000000,0.113783,-0.000000,0.993506,0.000000,-28.695675,0.000000,-250.557556,1.000000;;; + } + { Bip01_Footsteps } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;-0.000000,0.003123,0.999995,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999995,-0.003123,0.000000,-2.498093,-1.716894,0.000001,1.000000;;, + 80;16;-0.000000,0.005798,0.999983,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999983,-0.005798,0.000000,-2.606007,-1.708811,-0.000001,1.000000;;, + 160;16;-0.000000,0.008569,0.999963,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999963,-0.008569,0.000000,-2.714359,-1.701997,0.000007,1.000000;;, + 240;16;-0.000000,0.011630,0.999932,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999932,-0.011630,0.000000,-2.825058,-1.704134,0.000006,1.000000;;, + 320;16;-0.000000,0.014786,0.999891,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999891,-0.014786,0.000000,-2.935028,-1.702141,-0.000002,1.000000;;, + 400;16;-0.000000,0.017942,0.999839,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999839,-0.017942,0.000000,-3.042238,-1.688488,-0.000005,1.000000;;, + 480;16;-0.000000,0.021002,0.999779,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999779,-0.021002,0.000000,-3.144488,-1.655950,-0.000001,1.000000;;, + 560;16;-0.000000,0.023869,0.999715,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999715,-0.023869,0.000000,-3.236930,-1.599010,0.000005,1.000000;;, + 640;16;-0.000000,0.026447,0.999650,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999650,-0.026447,0.000000,-3.326138,-1.506355,-0.000006,1.000000;;, + 720;16;-0.000000,0.028638,0.999590,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999590,-0.028638,0.000000,-3.421040,-1.360553,0.000007,1.000000;;, + 800;16;-0.000000,0.030348,0.999539,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999539,-0.030348,0.000000,-3.513980,-1.175462,0.000007,1.000000;;, + 880;16;-0.000000,0.031444,0.999506,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999506,-0.031444,0.000000,-3.607227,-0.951677,0.000001,1.000000;;, + 960;16;-0.000000,0.031938,0.999490,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999490,-0.031938,0.000000,-3.682334,-0.710419,0.000003,1.000000;;, + 1040;16;-0.000000,0.031748,0.999496,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999496,-0.031748,0.000000,-3.717381,-0.472458,0.000000,1.000000;;, + 1120;16;-0.000000,0.031018,0.999519,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999519,-0.031018,0.000000,-3.718616,-0.233649,-0.000006,1.000000;;, + 1200;16;-0.000000,0.029844,0.999555,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999555,-0.029844,0.000000,-3.677681,0.000361,0.000003,1.000000;;, + 1280;16;-0.000000,0.028287,0.999600,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999600,-0.028287,0.000000,-3.613708,0.239710,-0.000006,1.000000;;, + 1360;16;-0.000000,0.026418,0.999651,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999651,-0.026418,0.000000,-3.543681,0.493597,0.000005,1.000000;;, + 1440;16;-0.000000,0.024309,0.999704,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999705,-0.024309,0.000000,-3.467867,0.755770,-0.000003,1.000000;;, + 1520;16;-0.000000,0.022030,0.999757,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999757,-0.022030,0.000000,-3.390432,1.023540,0.000009,1.000000;;, + 1600;16;-0.000000,0.019653,0.999807,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999807,-0.019653,0.000000,-3.315237,1.293970,-0.000004,1.000000;;, + 1680;16;-0.000000,0.017248,0.999851,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999851,-0.017248,0.000000,-3.245844,1.563869,-0.000005,1.000000;;, + 1760;16;-0.000000,0.014885,0.999889,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999889,-0.014885,0.000000,-3.185597,1.829824,0.000003,1.000000;;, + 1840;16;-0.000000,0.012637,0.999920,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999920,-0.012637,0.000000,-3.137427,2.088194,-0.000000,1.000000;;, + 1920;16;-0.000000,0.010574,0.999944,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999944,-0.010574,0.000000,-3.103951,2.335164,0.000006,1.000000;;, + 2000;16;0.000000,0.008766,0.999961,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999962,-0.008766,0.000000,-3.087498,2.566761,-0.000003,1.000000;;, + 2080;16;0.000000,0.007285,0.999973,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999973,-0.007285,0.000000,-3.090148,2.778913,0.000000,1.000000;;, + 2160;16;0.000000,0.005903,0.999983,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999983,-0.005903,0.000000,-3.108274,2.971279,-0.000007,1.000000;;, + 2240;16;-0.000000,0.005588,0.999984,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999984,-0.005588,0.000000,-3.159645,3.128248,0.000006,1.000000;;, + 2320;16;-0.000000,0.007494,0.999972,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999972,-0.007494,0.000000,-3.264085,3.232729,-0.000002,1.000000;;, + 2400;16;-0.000000,0.010843,0.999941,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999941,-0.010843,0.000000,-3.409011,3.285896,0.000004,1.000000;;, + 2480;16;-0.000000,0.015881,0.999874,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999874,-0.015881,0.000000,-3.599284,3.278342,-0.000004,1.000000;;, + 2560;16;-0.000000,0.020687,0.999786,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999786,-0.020687,0.000000,-3.803129,3.227022,-0.000004,1.000000;;, + 2640;16;-0.000000,0.023550,0.999723,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999723,-0.023550,0.000000,-3.998868,3.143643,0.000006,1.000000;;, + 2720;16;-0.000000,0.024101,0.999710,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999710,-0.024101,0.000000,-4.165480,3.040740,0.000006,1.000000;;, + 2800;16;-0.000000,0.020898,0.999782,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999782,-0.020898,0.000000,-4.277241,2.936613,0.000006,1.000000;;, + 2880;16;-0.000000,0.015453,0.999881,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999881,-0.015453,0.000000,-4.329769,2.828214,-0.000001,1.000000;;, + 2960;16;-0.000000,0.008510,0.999964,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999964,-0.008510,0.000000,-4.302057,2.720577,-0.000001,1.000000;;, + 3040;16;-0.000000,0.000942,1.000000,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,1.000000,-0.000942,0.000000,-4.218734,2.604678,0.000002,1.000000;;, + 3120;16;0.000000,-0.006408,0.999979,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999979,0.006408,0.000000,-4.092600,2.470545,0.000005,1.000000;;, + 3200;16;0.000000,-0.012697,0.999919,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999919,0.012697,0.000000,-3.938424,2.322757,0.000001,1.000000;;, + 3280;16;0.000000,-0.016811,0.999859,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999859,0.016811,0.000000,-3.770470,2.162284,0.000001,1.000000;;, + 3360;16;0.000000,-0.018729,0.999825,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999825,0.018729,0.000000,-3.603011,1.990379,-0.000005,1.000000;;, + 3440;16;0.000000,-0.017737,0.999843,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999843,0.017737,0.000000,-3.456044,1.809228,0.000000,1.000000;;, + 3520;16;0.000000,-0.014794,0.999891,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999891,0.014794,0.000000,-3.326296,1.619980,-0.000004,1.000000;;, + 3600;16;0.000000,-0.010505,0.999945,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999945,0.010505,0.000000,-3.220668,1.425136,0.000007,1.000000;;, + 3680;16;0.000000,-0.005221,0.999986,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999986,0.005221,0.000000,-3.127975,1.224429,-0.000004,1.000000;;, + 3760;16;-0.000000,0.000645,1.000000,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,1.000000,-0.000645,0.000000,-3.037925,1.017790,-0.000003,1.000000;;, + 3840;16;0.000000,0.006680,0.999978,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999978,-0.006680,0.000000,-2.954320,0.805845,0.000004,1.000000;;, + 3920;16;-0.000000,0.012471,0.999922,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999922,-0.012471,0.000000,-2.877302,0.589109,0.000001,1.000000;;, + 4000;16;-0.000000,0.017603,0.999845,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999845,-0.017603,0.000000,-2.807037,0.368100,-0.000011,1.000000;;, + 4080;16;-0.000000,0.021570,0.999767,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999767,-0.021570,0.000000,-2.743605,0.143374,-0.000008,1.000000;;, + 4160;16;-0.000000,0.024240,0.999706,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999706,-0.024240,0.000000,-2.686979,-0.084498,0.000004,1.000000;;, + 4240;16;-0.000000,0.025148,0.999684,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999684,-0.025148,0.000000,-2.637086,-0.314932,-0.000005,1.000000;;, + 4320;16;-0.000000,0.024788,0.999693,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999693,-0.024788,0.000000,-2.593796,-0.547340,0.000006,1.000000;;, + 4400;16;-0.000000,0.023387,0.999727,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999727,-0.023387,0.000000,-2.556833,-0.781132,-0.000001,1.000000;;, + 4480;16;-0.000000,0.021274,0.999774,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999774,-0.021274,0.000000,-2.525928,-1.015728,-0.000006,1.000000;;, + 4560;16;-0.000000,0.018755,0.999824,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999824,-0.018755,0.000000,-2.500761,-1.250548,-0.000001,1.000000;;, + 4640;16;-0.000000,0.016135,0.999870,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999870,-0.016135,0.000000,-2.480774,-1.485050,-0.000002,1.000000;;, + 4720;16;-0.000000,0.013920,0.999903,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999903,-0.013920,0.000000,-2.464930,-1.718164,-0.000005,1.000000;;, + 4800;16;-0.000000,0.011807,0.999930,0.000000,1.000000,0.000001,-0.000000,0.000000,-0.000001,0.999930,-0.011807,0.000000,-2.454305,-1.950977,-0.000005,1.000000;;, + 4960;16;-0.000000,0.003123,0.999995,0.000000,1.000000,0.000001,0.000000,0.000000,-0.000001,0.999995,-0.003123,0.000000,-2.498093,-1.716894,0.000001,1.000000;;; + } + { Bip01_Pelvis } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.999123,0.041767,0.002963,0.000000,-0.039832,0.969877,-0.240317,0.000000,-0.012911,0.239988,0.970690,0.000000,27.423990,8.709621,-0.080291,1.000000;;, + 80;16;0.999057,0.043399,-0.000923,0.000000,-0.042240,0.967043,-0.251084,0.000000,-0.010004,0.250886,0.967965,0.000000,27.423712,8.709688,-0.153400,1.000000;;, + 160;16;0.998974,0.045019,-0.004910,0.000000,-0.044731,0.963995,-0.262132,0.000000,-0.007067,0.262083,0.965020,0.000000,27.423220,8.709748,-0.229143,1.000000;;, + 240;16;0.998870,0.046629,-0.009154,0.000000,-0.047350,0.960438,-0.274438,0.000000,-0.004004,0.274561,0.961561,0.000000,27.422466,8.709834,-0.312789,1.000000;;, + 320;16;0.998745,0.048222,-0.013527,0.000000,-0.050076,0.956816,-0.286348,0.000000,-0.000865,0.286666,0.958030,0.000000,27.421347,8.709902,-0.399080,1.000000;;, + 400;16;0.998598,0.049795,-0.017967,0.000000,-0.052886,0.953448,-0.296885,0.000000,0.002347,0.297419,0.954744,0.000000,27.420021,8.709992,-0.485405,1.000000;;, + 480;16;0.998429,0.051349,-0.022410,0.000000,-0.055741,0.950693,-0.305085,0.000000,0.005639,0.305855,0.952062,0.000000,27.418449,8.710045,-0.569127,1.000000;;, + 560;16;0.998245,0.052832,-0.026768,0.000000,-0.058535,0.948912,-0.310064,0.000000,0.009019,0.311086,0.950339,0.000000,27.416719,8.710094,-0.647637,1.000000;;, + 640;16;0.998037,0.054406,-0.031026,0.000000,-0.061365,0.948540,-0.310654,0.000000,0.012528,0.311948,0.950017,0.000000,27.415018,8.710110,-0.718311,1.000000;;, + 720;16;0.997794,0.056292,-0.035203,0.000000,-0.064365,0.950186,-0.304965,0.000000,0.016283,0.306558,0.951713,0.000000,27.413412,8.710062,-0.778545,1.000000;;, + 800;16;0.997534,0.058300,-0.039081,0.000000,-0.067245,0.953380,-0.294185,0.000000,0.020108,0.296087,0.954949,0.000000,27.412104,8.709989,-0.825681,1.000000;;, + 880;16;0.997266,0.060451,-0.042510,0.000000,-0.069929,0.957960,-0.278248,0.000000,0.023903,0.280460,0.959568,0.000000,27.411259,8.709897,-0.856093,1.000000;;, + 960;16;0.997026,0.062340,-0.045313,0.000000,-0.071994,0.963208,-0.258933,0.000000,0.027504,0.261425,0.964832,0.000000,27.410852,8.709781,-0.870053,1.000000;;, + 1040;16;0.996863,0.063519,-0.047220,0.000000,-0.072985,0.968531,-0.237953,0.000000,0.030619,0.240653,0.970128,0.000000,27.411047,8.709651,-0.865323,1.000000;;, + 1120;16;0.996767,0.064080,-0.048470,0.000000,-0.073083,0.973748,-0.215580,0.000000,0.033383,0.218425,0.975282,0.000000,27.411665,8.709511,-0.845809,1.000000;;, + 1200;16;0.996748,0.063848,-0.049164,0.000000,-0.072196,0.978567,-0.192861,0.000000,0.035796,0.195783,0.979994,0.000000,27.412643,8.709426,-0.814108,1.000000;;, + 1280;16;0.996775,0.063168,-0.049484,0.000000,-0.070700,0.983031,-0.169270,0.000000,0.037952,0.172223,0.984327,0.000000,27.413853,8.709321,-0.771938,1.000000;;, + 1360;16;0.996821,0.062333,-0.049630,0.000000,-0.068920,0.987101,-0.144503,0.000000,0.039982,0.147464,0.988259,0.000000,27.415201,8.709247,-0.721257,1.000000;;, + 1440;16;0.996884,0.061336,-0.049598,0.000000,-0.066870,0.990648,-0.118935,0.000000,0.041840,0.121881,0.991662,0.000000,27.416634,8.709151,-0.663992,1.000000;;, + 1520;16;0.996959,0.060241,-0.049434,0.000000,-0.064637,0.993586,-0.092783,0.000000,0.043528,0.095696,0.994458,0.000000,27.418028,8.709090,-0.602090,1.000000;;, + 1600;16;0.997039,0.059108,-0.049178,0.000000,-0.062306,0.995855,-0.066263,0.000000,0.045058,0.069131,0.996590,0.000000,27.419365,8.709007,-0.537485,1.000000;;, + 1680;16;0.997120,0.057998,-0.048867,0.000000,-0.059956,0.997415,-0.039601,0.000000,0.046444,0.042417,0.998020,0.000000,27.420511,8.708969,-0.472121,1.000000;;, + 1760;16;0.997196,0.056968,-0.048536,0.000000,-0.057662,0.998251,-0.013023,0.000000,0.047709,0.015785,0.998737,0.000000,27.421484,8.708943,-0.407935,1.000000;;, + 1840;16;0.997262,0.056071,-0.048214,0.000000,-0.055493,0.998371,0.013244,0.000000,0.048878,-0.010532,0.998749,0.000000,27.422323,8.708948,-0.346869,1.000000;;, + 1920;16;0.997316,0.055359,-0.047930,0.000000,-0.053513,0.997806,0.038972,0.000000,0.049982,-0.036302,0.998090,0.000000,27.422901,8.708982,-0.290859,1.000000;;, + 2000;16;0.997353,0.054879,-0.047708,0.000000,-0.051780,0.996610,0.063936,0.000000,0.051055,-0.061296,0.996813,0.000000,27.423340,8.708994,-0.241852,1.000000;;, + 2080;16;0.997370,0.054677,-0.047570,0.000000,-0.050346,0.994855,0.087914,0.000000,0.052132,-0.085287,0.994992,0.000000,27.423624,8.709033,-0.201784,1.000000;;, + 2160;16;0.997381,0.054703,-0.047314,0.000000,-0.049197,0.992647,0.110592,0.000000,0.053016,-0.107975,0.992739,0.000000,27.423874,8.709077,-0.164378,1.000000;;, + 2240;16;0.997334,0.055280,-0.047632,0.000000,-0.048570,0.990053,0.132043,0.000000,0.054458,-0.129378,0.990099,0.000000,27.423906,8.709186,-0.156224,1.000000;;, + 2320;16;0.997165,0.056772,-0.049377,0.000000,-0.048657,0.987131,0.152331,0.000000,0.057390,-0.149496,0.987095,0.000000,27.423563,8.709200,-0.208964,1.000000;;, + 2400;16;0.996914,0.058971,-0.051814,0.000000,-0.049309,0.984002,0.171196,0.000000,0.061081,-0.168113,0.983874,0.000000,27.422709,8.709292,-0.301226,1.000000;;, + 2480;16;0.996559,0.061976,-0.055031,0.000000,-0.050578,0.980749,0.188608,0.000000,0.065661,-0.185176,0.980509,0.000000,27.420868,8.709354,-0.439755,1.000000;;, + 2560;16;0.996214,0.065247,-0.057455,0.000000,-0.052261,0.977576,0.203994,0.000000,0.069476,-0.200219,0.977285,0.000000,27.418518,8.709438,-0.571916,1.000000;;, + 2640;16;0.995992,0.068417,-0.057617,0.000000,-0.054407,0.974679,0.216890,0.000000,0.070997,-0.212886,0.974494,0.000000,27.416853,8.709501,-0.650709,1.000000;;, + 2720;16;0.995927,0.071133,-0.055404,0.000000,-0.056821,0.972261,0.226894,0.000000,0.070007,-0.222822,0.972342,0.000000,27.416513,8.709535,-0.666055,1.000000;;, + 2800;16;0.996094,0.072957,-0.049737,0.000000,-0.059430,0.970551,0.233449,0.000000,0.065304,-0.229581,0.971096,0.000000,27.418550,8.709614,-0.578335,1.000000;;, + 2880;16;0.996384,0.073821,-0.042075,0.000000,-0.061852,0.969652,0.236534,0.000000,0.058259,-0.233076,0.970712,0.000000,27.421329,8.709619,-0.429106,1.000000;;, + 2960;16;0.996750,0.073367,-0.033278,0.000000,-0.063506,0.969726,0.235792,0.000000,0.049569,-0.232913,0.971234,0.000000,27.423607,8.709618,-0.238672,1.000000;;, + 3040;16;0.997114,0.072017,-0.024018,0.000000,-0.064522,0.970635,0.231744,0.000000,0.040002,-0.229526,0.972480,0.000000,27.424623,8.709596,-0.031054,1.000000;;, + 3120;16;0.997436,0.069989,-0.014943,0.000000,-0.064858,0.972275,0.224666,0.000000,0.030253,-0.223120,0.974321,0.000000,27.424124,8.709539,0.170648,1.000000;;, + 3200;16;0.997693,0.067528,-0.006951,0.000000,-0.064461,0.974507,0.214897,0.000000,0.021285,-0.213953,0.976612,0.000000,27.422415,8.709509,0.343353,1.000000;;, + 3280;16;0.997893,0.064869,-0.001153,0.000000,-0.063289,0.977180,0.202767,0.000000,0.014280,-0.202267,0.979226,0.000000,27.420753,8.709398,0.456439,1.000000;;, + 3360;16;0.998058,0.062249,0.002426,0.000000,-0.061590,0.980136,0.188522,0.000000,0.009357,-0.188306,0.982066,0.000000,27.419783,8.709392,0.509363,1.000000;;, + 3440;16;0.998194,0.060003,0.003050,0.000000,-0.059630,0.983218,0.172412,0.000000,0.007346,-0.172283,0.985020,0.000000,27.420202,8.709322,0.482506,1.000000;;, + 3520;16;0.998312,0.058058,0.001693,0.000000,-0.057620,0.986277,0.154716,0.000000,0.007313,-0.154552,0.987958,0.000000,27.421497,8.709218,0.402188,1.000000;;, + 3600;16;0.998401,0.056518,-0.001049,0.000000,-0.055853,0.989165,0.135769,0.000000,0.008711,-0.135493,0.990740,0.000000,27.422939,8.709164,0.285022,1.000000;;, + 3680;16;0.998465,0.055179,-0.004804,0.000000,-0.054254,0.991800,0.115711,0.000000,0.011149,-0.115272,0.993271,0.000000,27.424032,8.709114,0.140571,1.000000;;, + 3760;16;0.998507,0.053849,-0.009127,0.000000,-0.052744,0.994098,0.094798,0.000000,0.014178,-0.094175,0.995455,0.000000,27.424370,8.709086,-0.019833,1.000000;;, + 3840;16;0.998524,0.052587,-0.013613,0.000000,-0.051458,0.996000,0.073054,0.000000,0.017400,-0.072246,0.997235,0.000000,27.423771,8.709007,-0.184858,1.000000;;, + 3920;16;0.998519,0.051392,-0.017847,0.000000,-0.050433,0.997446,0.050570,0.000000,0.020400,-0.049595,0.998561,0.000000,27.422205,8.708976,-0.343148,1.000000;;, + 4000;16;0.998507,0.050259,-0.021413,0.000000,-0.049665,0.998389,0.027438,0.000000,0.022758,-0.026334,0.999394,0.000000,27.420103,8.708972,-0.483372,1.000000;;, + 4080;16;0.998506,0.049186,-0.023804,0.000000,-0.049111,0.998786,0.003750,0.000000,0.023959,-0.002576,0.999710,0.000000,27.417946,8.708911,-0.591626,1.000000;;, + 4160;16;0.998529,0.048169,-0.024885,0.000000,-0.048681,0.998606,-0.020381,0.000000,0.023868,0.021563,0.999483,0.000000,27.416210,8.708953,-0.664299,1.000000;;, + 4240;16;0.998592,0.047204,-0.024190,0.000000,-0.048254,0.997827,-0.044860,0.000000,0.022020,0.045964,0.998700,0.000000,27.415644,8.708937,-0.688669,1.000000;;, + 4320;16;0.998681,0.046287,-0.022210,0.000000,-0.047729,0.996437,-0.069543,0.000000,0.018912,0.070512,0.997332,0.000000,27.415854,8.709007,-0.678236,1.000000;;, + 4400;16;0.998784,0.045413,-0.019169,0.000000,-0.047025,0.994433,-0.094300,0.000000,0.014780,0.095087,0.995359,0.000000,27.416765,8.709054,-0.639246,1.000000;;, + 4480;16;0.998887,0.044578,-0.015395,0.000000,-0.046097,0.991824,-0.118995,0.000000,0.009964,0.119572,0.992776,0.000000,27.418045,8.709128,-0.580761,1.000000;;, + 4560;16;0.998979,0.043778,-0.011190,0.000000,-0.044932,0.988630,-0.143495,0.000000,0.004781,0.143852,0.989588,0.000000,27.419416,8.709133,-0.511128,1.000000;;, + 4640;16;0.999051,0.043007,-0.006858,0.000000,-0.043547,0.984881,-0.167671,0.000000,-0.000457,0.167810,0.985819,0.000000,27.420631,8.709249,-0.438722,1.000000;;, + 4720;16;0.999103,0.042252,-0.002899,0.000000,-0.042026,0.980641,-0.191252,0.000000,-0.005238,0.191202,0.981537,0.000000,27.421503,8.709340,-0.377466,1.000000;;, + 4800;16;0.999137,0.041531,0.000982,0.000000,-0.040353,0.975880,-0.214545,0.000000,-0.009868,0.214320,0.976714,0.000000,27.422213,8.709480,-0.319006,1.000000;;, + 4960;16;0.999123,0.041767,0.002963,0.000000,-0.039832,0.969877,-0.240317,0.000000,-0.012911,0.239988,0.970690,0.000000,27.423990,8.709621,-0.080291,1.000000;;; + } + { Bip01_Spine } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178093,-0.022107,-0.000000,1.000000;;, + 80;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178076,-0.022107,-0.000001,1.000000;;, + 160;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178078,-0.022100,-0.000000,1.000000;;, + 240;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178055,-0.022113,-0.000001,1.000000;;, + 320;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178087,-0.022091,-0.000000,1.000000;;, + 400;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178095,-0.022106,-0.000000,1.000000;;, + 480;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178078,-0.022101,-0.000000,1.000000;;, + 560;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178080,-0.022108,-0.000001,1.000000;;, + 640;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178099,-0.022104,0.000000,1.000000;;, + 720;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178123,-0.022100,0.000001,1.000000;;, + 800;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178085,-0.022088,-0.000000,1.000000;;, + 880;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178066,-0.022108,-0.000001,1.000000;;, + 960;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178112,-0.022100,0.000001,1.000000;;, + 1040;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178099,-0.022101,0.000000,1.000000;;, + 1120;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178110,-0.022086,0.000001,1.000000;;, + 1200;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178099,-0.022109,0.000000,1.000000;;, + 1280;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178066,-0.022097,-0.000001,1.000000;;, + 1360;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178122,-0.022110,0.000001,1.000000;;, + 1440;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178076,-0.022091,-0.000000,1.000000;;, + 1520;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178099,-0.022102,0.000000,1.000000;;, + 1600;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178057,-0.022091,-0.000001,1.000000;;, + 1680;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178072,-0.022111,-0.000001,1.000000;;, + 1760;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178089,-0.022071,0.000000,1.000000;;, + 1840;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178070,-0.022096,-0.000001,1.000000;;, + 1920;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178097,-0.022103,-0.000000,1.000000;;, + 2000;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178118,-0.022102,0.000001,1.000000;;, + 2080;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178083,-0.022100,0.000000,1.000000;;, + 2160;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178091,-0.022098,0.000000,1.000000;;, + 2240;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178087,-0.022139,0.000000,1.000000;;, + 2320;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178082,-0.022113,-0.000001,1.000000;;, + 2400;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178089,-0.022089,0.000000,1.000000;;, + 2480;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178091,-0.022090,0.000000,1.000000;;, + 2560;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178083,-0.022078,0.000000,1.000000;;, + 2640;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178047,-0.022098,-0.000001,1.000000;;, + 2720;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178083,-0.022071,0.000001,1.000000;;, + 2800;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178085,-0.022123,-0.000001,1.000000;;, + 2880;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178074,-0.022096,-0.000000,1.000000;;, + 2960;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178123,-0.022122,-0.000002,1.000000;;, + 3040;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178099,-0.022103,-0.000000,1.000000;;, + 3120;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178076,-0.022107,-0.000001,1.000000;;, + 3200;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178122,-0.022106,-0.000001,1.000000;;, + 3280;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178097,-0.022081,0.000001,1.000000;;, + 3360;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178120,-0.022132,-0.000003,1.000000;;, + 3440;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178110,-0.022128,-0.000002,1.000000;;, + 3520;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178085,-0.022074,0.000002,1.000000;;, + 3600;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178089,-0.022098,0.000000,1.000000;;, + 3680;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178097,-0.022077,0.000001,1.000000;;, + 3760;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178085,-0.022123,-0.000002,1.000000;;, + 3840;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178057,-0.022095,0.000000,1.000000;;, + 3920;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178091,-0.022088,0.000001,1.000000;;, + 4000;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178080,-0.022091,0.000001,1.000000;;, + 4080;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178082,-0.022065,0.000002,1.000000;;, + 4160;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178125,-0.022127,-0.000002,1.000000;;, + 4240;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178078,-0.022039,0.000004,1.000000;;, + 4320;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178112,-0.022084,0.000001,1.000000;;, + 4400;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178114,-0.022109,-0.000001,1.000000;;, + 4480;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178070,-0.022167,-0.000004,1.000000;;, + 4560;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178085,-0.022028,0.000003,1.000000;;, + 4640;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178066,-0.022106,-0.000000,1.000000;;, + 4720;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178074,-0.022161,-0.000002,1.000000;;, + 4800;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178080,-0.022084,0.000000,1.000000;;, + 4960;16;0.984808,-0.173648,-0.000000,0.000000,0.173648,0.984808,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,28.178093,-0.022107,-0.000000,1.000000;;; + } + { Bip01_Spine1 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.999960,0.008638,0.002139,0.000000,-0.008515,0.998612,-0.051985,0.000000,-0.002585,0.051964,0.998646,0.000000,28.182180,-0.022404,0.001167,1.000000;;, + 80;16;0.999958,0.009006,0.001953,0.000000,-0.008886,0.998480,-0.054390,0.000000,-0.002440,0.054371,0.998518,0.000000,28.182199,-0.022407,0.001221,1.000000;;, + 160;16;0.999954,0.009373,0.001769,0.000000,-0.009257,0.998339,-0.056869,0.000000,-0.002300,0.056850,0.998380,0.000000,28.182215,-0.022390,0.001277,1.000000;;, + 240;16;0.999951,0.009739,0.001601,0.000000,-0.009626,0.998174,-0.059641,0.000000,-0.002179,0.059622,0.998219,0.000000,28.182205,-0.022391,0.001339,1.000000;;, + 320;16;0.999948,0.010105,0.001428,0.000000,-0.009996,0.998005,-0.062338,0.000000,-0.002055,0.062321,0.998054,0.000000,28.182203,-0.022400,0.001399,1.000000;;, + 400;16;0.999944,0.010470,0.001238,0.000000,-0.010368,0.997848,-0.064742,0.000000,-0.001913,0.064726,0.997901,0.000000,28.182194,-0.022392,0.001452,1.000000;;, + 480;16;0.999941,0.010837,0.001019,0.000000,-0.010745,0.997720,-0.066632,0.000000,-0.001739,0.066617,0.997777,0.000000,28.182243,-0.022383,0.001496,1.000000;;, + 560;16;0.999937,0.011193,0.000763,0.000000,-0.011115,0.997637,-0.067804,0.000000,-0.001520,0.067791,0.997698,0.000000,28.182243,-0.022378,0.001522,1.000000;;, + 640;16;0.999933,0.011574,0.000449,0.000000,-0.011516,0.997620,-0.067991,0.000000,-0.001235,0.067981,0.997686,0.000000,28.182236,-0.022407,0.001525,1.000000;;, + 720;16;0.999928,0.012029,0.000047,0.000000,-0.011999,0.997696,-0.066768,0.000000,-0.000850,0.066762,0.997769,0.000000,28.182245,-0.022386,0.001498,1.000000;;, + 800;16;0.999922,0.012511,-0.000419,0.000000,-0.012512,0.997845,-0.064404,0.000000,-0.000387,0.064404,0.997924,0.000000,28.182276,-0.022409,0.001445,1.000000;;, + 880;16;0.999915,0.013021,-0.000950,0.000000,-0.013055,0.998059,-0.060894,0.000000,0.000155,0.060901,0.998144,0.000000,28.182274,-0.022404,0.001366,1.000000;;, + 960;16;0.999908,0.013465,-0.001505,0.000000,-0.013529,0.998303,-0.056640,0.000000,0.000740,0.056656,0.998393,0.000000,28.182281,-0.022418,0.001271,1.000000;;, + 1040;16;0.999904,0.013741,-0.002043,0.000000,-0.013829,0.998550,-0.052024,0.000000,0.001325,0.052047,0.998644,0.000000,28.182289,-0.022406,0.001167,1.000000;;, + 1120;16;0.999900,0.013871,-0.002578,0.000000,-0.013977,0.998792,-0.047110,0.000000,0.001921,0.047141,0.998886,0.000000,28.182270,-0.022416,0.001056,1.000000;;, + 1200;16;0.999900,0.013819,-0.003104,0.000000,-0.013937,0.999015,-0.042130,0.000000,0.002518,0.042169,0.999107,0.000000,28.182281,-0.022428,0.000945,1.000000;;, + 1280;16;0.999900,0.013660,-0.003641,0.000000,-0.013785,0.999221,-0.036971,0.000000,0.003133,0.037018,0.999310,0.000000,28.182306,-0.022411,0.000830,1.000000;;, + 1360;16;0.999900,0.013461,-0.004213,0.000000,-0.013587,0.999409,-0.031574,0.000000,0.003786,0.031628,0.999492,0.000000,28.182280,-0.022422,0.000708,1.000000;;, + 1440;16;0.999901,0.013217,-0.004801,0.000000,-0.013338,0.999573,-0.026018,0.000000,0.004455,0.026080,0.999650,0.000000,28.182310,-0.022427,0.000585,1.000000;;, + 1520;16;0.999902,0.012943,-0.005396,0.000000,-0.013050,0.999708,-0.020351,0.000000,0.005131,0.020419,0.999778,0.000000,28.182245,-0.022437,0.000456,1.000000;;, + 1600;16;0.999902,0.012651,-0.005990,0.000000,-0.012738,0.999812,-0.014617,0.000000,0.005804,0.014692,0.999875,0.000000,28.182310,-0.022420,0.000330,1.000000;;, + 1680;16;0.999902,0.012355,-0.006574,0.000000,-0.012413,0.999884,-0.008863,0.000000,0.006464,0.008943,0.999939,0.000000,28.182240,-0.022410,0.000199,1.000000;;, + 1760;16;0.999902,0.012066,-0.007140,0.000000,-0.012089,0.999922,-0.003134,0.000000,0.007101,0.003220,0.999970,0.000000,28.182266,-0.022477,0.000070,1.000000;;, + 1840;16;0.999901,0.011799,-0.007677,0.000000,-0.011780,0.999927,0.002523,0.000000,0.007706,-0.002433,0.999967,0.000000,28.182272,-0.022432,-0.000056,1.000000;;, + 1920;16;0.999900,0.011565,-0.008177,0.000000,-0.011499,0.999901,0.008063,0.000000,0.008269,-0.007969,0.999934,0.000000,28.182232,-0.022423,-0.000181,1.000000;;, + 2000;16;0.999898,0.011377,-0.008631,0.000000,-0.011260,0.999846,0.013441,0.000000,0.008782,-0.013342,0.999872,0.000000,28.182209,-0.022437,-0.000302,1.000000;;, + 2080;16;0.999896,0.011247,-0.009028,0.000000,-0.011078,0.999765,0.018609,0.000000,0.009235,-0.018507,0.999786,0.000000,28.182236,-0.022451,-0.000417,1.000000;;, + 2160;16;0.999894,0.011168,-0.009374,0.000000,-0.010945,0.999664,0.023506,0.000000,0.009634,-0.023401,0.999680,0.000000,28.182228,-0.022439,-0.000527,1.000000;;, + 2240;16;0.999891,0.011212,-0.009616,0.000000,-0.010938,0.999544,0.028137,0.000000,0.009927,-0.028029,0.999558,0.000000,28.182234,-0.022405,-0.000631,1.000000;;, + 2320;16;0.999887,0.011463,-0.009695,0.000000,-0.011142,0.999410,0.032503,0.000000,0.010061,-0.032392,0.999425,0.000000,28.182226,-0.022421,-0.000730,1.000000;;, + 2400;16;0.999883,0.011880,-0.009621,0.000000,-0.011521,0.999265,0.036556,0.000000,0.010048,-0.036441,0.999285,0.000000,28.182283,-0.022441,-0.000819,1.000000;;, + 2480;16;0.999878,0.012490,-0.009366,0.000000,-0.012103,0.999115,0.040282,0.000000,0.009861,-0.040164,0.999144,0.000000,28.182253,-0.022421,-0.000904,1.000000;;, + 2560;16;0.999873,0.013177,-0.008993,0.000000,-0.012773,0.998968,0.043576,0.000000,0.009557,-0.043456,0.999010,0.000000,28.182255,-0.022452,-0.000979,1.000000;;, + 2640;16;0.999867,0.013860,-0.008544,0.000000,-0.013450,0.998835,0.046354,0.000000,0.009176,-0.046233,0.998889,0.000000,28.182299,-0.022407,-0.001040,1.000000;;, + 2720;16;0.999863,0.014461,-0.008061,0.000000,-0.014053,0.998723,0.048534,0.000000,0.008753,-0.048414,0.998789,0.000000,28.182329,-0.022429,-0.001090,1.000000;;, + 2800;16;0.999860,0.014879,-0.007608,0.000000,-0.014480,0.998643,0.050014,0.000000,0.008342,-0.049897,0.998720,0.000000,28.182306,-0.022414,-0.001123,1.000000;;, + 2880;16;0.999860,0.015098,-0.007168,0.000000,-0.014715,0.998602,0.050771,0.000000,0.007925,-0.050658,0.998685,0.000000,28.182318,-0.022442,-0.001141,1.000000;;, + 2960;16;0.999864,0.015039,-0.006756,0.000000,-0.014678,0.998605,0.050714,0.000000,0.007509,-0.050608,0.998690,0.000000,28.182287,-0.022416,-0.001138,1.000000;;, + 3040;16;0.999870,0.014793,-0.006341,0.000000,-0.014459,0.998647,0.049943,0.000000,0.007071,-0.049844,0.998732,0.000000,28.182310,-0.022401,-0.001120,1.000000;;, + 3120;16;0.999879,0.014408,-0.005889,0.000000,-0.014106,0.998723,0.048503,0.000000,0.006580,-0.048414,0.998806,0.000000,28.182297,-0.022400,-0.001087,1.000000;;, + 3200;16;0.999888,0.013933,-0.005421,0.000000,-0.013666,0.998827,0.046459,0.000000,0.006062,-0.046380,0.998905,0.000000,28.182285,-0.022428,-0.001043,1.000000;;, + 3280;16;0.999898,0.013415,-0.004945,0.000000,-0.013186,0.998950,0.043868,0.000000,0.005529,-0.043798,0.999025,0.000000,28.182266,-0.022429,-0.000985,1.000000;;, + 3360;16;0.999907,0.012904,-0.004470,0.000000,-0.012711,0.999087,0.040788,0.000000,0.004992,-0.040728,0.999158,0.000000,28.182243,-0.022399,-0.000913,1.000000;;, + 3440;16;0.999914,0.012469,-0.004007,0.000000,-0.012311,0.999229,0.037272,0.000000,0.004468,-0.037219,0.999297,0.000000,28.182274,-0.022430,-0.000837,1.000000;;, + 3520;16;0.999920,0.012094,-0.003553,0.000000,-0.011969,0.999371,0.033398,0.000000,0.003955,-0.033353,0.999436,0.000000,28.182243,-0.022438,-0.000751,1.000000;;, + 3600;16;0.999925,0.011801,-0.003112,0.000000,-0.011705,0.999504,0.029249,0.000000,0.003456,-0.029211,0.999567,0.000000,28.182255,-0.022432,-0.000657,1.000000;;, + 3680;16;0.999930,0.011546,-0.002677,0.000000,-0.011476,0.999625,0.024863,0.000000,0.002964,-0.024830,0.999687,0.000000,28.182261,-0.022451,-0.000560,1.000000;;, + 3760;16;0.999934,0.011289,-0.002241,0.000000,-0.011241,0.999731,0.020298,0.000000,0.002469,-0.020271,0.999791,0.000000,28.182238,-0.022433,-0.000455,1.000000;;, + 3840;16;0.999937,0.011041,-0.001804,0.000000,-0.011012,0.999818,0.015564,0.000000,0.001976,-0.015543,0.999877,0.000000,28.182243,-0.022441,-0.000350,1.000000;;, + 3920;16;0.999941,0.010802,-0.001368,0.000000,-0.010787,0.999885,0.010683,0.000000,0.001483,-0.010668,0.999942,0.000000,28.182222,-0.022450,-0.000240,1.000000;;, + 4000;16;0.999944,0.010572,-0.000931,0.000000,-0.010566,0.999928,0.005677,0.000000,0.000991,-0.005667,0.999984,0.000000,28.182243,-0.022468,-0.000130,1.000000;;, + 4080;16;0.999946,0.010348,-0.000494,0.000000,-0.010348,0.999946,0.000569,0.000000,0.000500,-0.000564,1.000000,0.000000,28.182241,-0.022454,-0.000014,1.000000;;, + 4160;16;0.999949,0.010130,-0.000057,0.000000,-0.010130,0.999938,-0.004620,0.000000,0.000010,0.004620,0.999989,0.000000,28.182201,-0.022432,0.000104,1.000000;;, + 4240;16;0.999951,0.009917,0.000381,0.000000,-0.009913,0.999902,-0.009867,0.000000,-0.000478,0.009863,0.999951,0.000000,28.182232,-0.022464,0.000219,1.000000;;, + 4320;16;0.999952,0.009709,0.000819,0.000000,-0.009695,0.999838,-0.015150,0.000000,-0.000966,0.015142,0.999885,0.000000,28.182169,-0.022407,0.000342,1.000000;;, + 4400;16;0.999954,0.009503,0.001259,0.000000,-0.009475,0.999746,-0.020448,0.000000,-0.001453,0.020435,0.999790,0.000000,28.182182,-0.022431,0.000459,1.000000;;, + 4480;16;0.999955,0.009299,0.001699,0.000000,-0.009253,0.999626,-0.025737,0.000000,-0.001938,0.025721,0.999667,0.000000,28.182177,-0.022365,0.000581,1.000000;;, + 4560;16;0.999956,0.009097,0.002141,0.000000,-0.009026,0.999479,-0.030997,0.000000,-0.002422,0.030976,0.999517,0.000000,28.182198,-0.022499,0.000692,1.000000;;, + 4640;16;0.999957,0.008894,0.002585,0.000000,-0.008794,0.999306,-0.036204,0.000000,-0.002905,0.036180,0.999341,0.000000,28.182184,-0.022429,0.000812,1.000000;;, + 4720;16;0.999958,0.008688,0.003030,0.000000,-0.008556,0.999110,-0.041308,0.000000,-0.003387,0.041280,0.999142,0.000000,28.182182,-0.022396,0.000928,1.000000;;, + 4800;16;0.999958,0.008483,0.003477,0.000000,-0.008313,0.998890,-0.046374,0.000000,-0.003867,0.046343,0.998918,0.000000,28.182159,-0.022430,0.001040,1.000000;;, + 4960;16;0.999960,0.008638,0.002139,0.000000,-0.008515,0.998612,-0.051985,0.000000,-0.002585,0.051964,0.998646,0.000000,28.182180,-0.022404,0.001167,1.000000;;; + } + { Bip01_Spine2 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.999844,-0.017541,0.002139,0.000000,0.017628,0.998492,-0.051985,0.000000,-0.001224,0.052014,0.998646,0.000000,28.181387,-0.033838,0.001761,1.000000;;, + 80;16;0.999851,-0.017173,0.001953,0.000000,0.017254,0.998371,-0.054390,0.000000,-0.001015,0.054416,0.998518,0.000000,28.181393,-0.033823,0.001844,1.000000;;, + 160;16;0.999857,-0.016806,0.001769,0.000000,0.016880,0.998239,-0.056869,0.000000,-0.000811,0.056891,0.998380,0.000000,28.181393,-0.033834,0.001926,1.000000;;, + 240;16;0.999864,-0.016440,0.001601,0.000000,0.016506,0.998083,-0.059641,0.000000,-0.000618,0.059659,0.998219,0.000000,28.181406,-0.033831,0.002020,1.000000;;, + 320;16;0.999870,-0.016074,0.001428,0.000000,0.016132,0.997925,-0.062339,0.000000,-0.000423,0.062353,0.998054,0.000000,28.181440,-0.033803,0.002113,1.000000;;, + 400;16;0.999876,-0.015709,0.001238,0.000000,0.015756,0.997778,-0.064742,0.000000,-0.000218,0.064754,0.997901,0.000000,28.181459,-0.033810,0.002194,1.000000;;, + 480;16;0.999882,-0.015342,0.001019,0.000000,0.015376,0.997659,-0.066632,0.000000,0.000006,0.066640,0.997777,0.000000,28.181421,-0.033817,0.002256,1.000000;;, + 560;16;0.999887,-0.014987,0.000763,0.000000,0.015004,0.997586,-0.067804,0.000000,0.000255,0.067808,0.997698,0.000000,28.181471,-0.033799,0.002297,1.000000;;, + 640;16;0.999893,-0.014606,0.000449,0.000000,0.014602,0.997579,-0.067991,0.000000,0.000545,0.067990,0.997686,0.000000,28.181479,-0.033799,0.002304,1.000000;;, + 720;16;0.999900,-0.014151,0.000047,0.000000,0.014122,0.997669,-0.066768,0.000000,0.000898,0.066762,0.997769,0.000000,28.181480,-0.033816,0.002261,1.000000;;, + 800;16;0.999906,-0.013669,-0.000419,0.000000,0.013613,0.997831,-0.064404,0.000000,0.001299,0.064393,0.997924,0.000000,28.181528,-0.033810,0.002183,1.000000;;, + 880;16;0.999913,-0.013158,-0.000950,0.000000,0.013076,0.998059,-0.060894,0.000000,0.001749,0.060876,0.998144,0.000000,28.181520,-0.033831,0.002062,1.000000;;, + 960;16;0.999918,-0.012714,-0.001505,0.000000,0.012608,0.998315,-0.056640,0.000000,0.002222,0.056617,0.998394,0.000000,28.181570,-0.033827,0.001920,1.000000;;, + 1040;16;0.999921,-0.012438,-0.002043,0.000000,0.012315,0.998570,-0.052024,0.000000,0.002687,0.051994,0.998644,0.000000,28.181555,-0.033841,0.001762,1.000000;;, + 1120;16;0.999921,-0.012308,-0.002578,0.000000,0.012173,0.998815,-0.047110,0.000000,0.003154,0.047075,0.998886,0.000000,28.181576,-0.033837,0.001598,1.000000;;, + 1200;16;0.999919,-0.012361,-0.003104,0.000000,0.012219,0.999037,-0.042129,0.000000,0.003622,0.042088,0.999107,0.000000,28.181570,-0.033847,0.001428,1.000000;;, + 1280;16;0.999915,-0.012519,-0.003641,0.000000,0.012376,0.999240,-0.036971,0.000000,0.004101,0.036923,0.999310,0.000000,28.181587,-0.033863,0.001253,1.000000;;, + 1360;16;0.999910,-0.012718,-0.004213,0.000000,0.012579,0.999422,-0.031574,0.000000,0.004612,0.031518,0.999493,0.000000,28.181551,-0.033881,0.001069,1.000000;;, + 1440;16;0.999904,-0.012962,-0.004801,0.000000,0.012832,0.999579,-0.026018,0.000000,0.005136,0.025954,0.999650,0.000000,28.181551,-0.033876,0.000882,1.000000;;, + 1520;16;0.999898,-0.013236,-0.005396,0.000000,0.013123,0.999707,-0.020351,0.000000,0.005664,0.020278,0.999778,0.000000,28.181580,-0.033861,0.000692,1.000000;;, + 1600;16;0.999891,-0.013528,-0.005990,0.000000,0.013439,0.999803,-0.014617,0.000000,0.006187,0.014535,0.999875,0.000000,28.181488,-0.033870,0.000494,1.000000;;, + 1680;16;0.999883,-0.013824,-0.006574,0.000000,0.013766,0.999866,-0.008863,0.000000,0.006696,0.008771,0.999939,0.000000,28.181526,-0.033868,0.000301,1.000000;;, + 1760;16;0.999875,-0.014112,-0.007140,0.000000,0.014090,0.999896,-0.003134,0.000000,0.007183,0.003033,0.999970,0.000000,28.181465,-0.033827,0.000105,1.000000;;, + 1840;16;0.999867,-0.014380,-0.007677,0.000000,0.014399,0.999893,0.002523,0.000000,0.007640,-0.002634,0.999968,0.000000,28.181459,-0.033858,-0.000087,1.000000;;, + 1920;16;0.999860,-0.014614,-0.008177,0.000000,0.014679,0.999860,0.008063,0.000000,0.008058,-0.008182,0.999934,0.000000,28.181480,-0.033867,-0.000273,1.000000;;, + 2000;16;0.999853,-0.014801,-0.008631,0.000000,0.014917,0.999798,0.013441,0.000000,0.008430,-0.013567,0.999872,0.000000,28.181446,-0.033858,-0.000457,1.000000;;, + 2080;16;0.999848,-0.014931,-0.009028,0.000000,0.015097,0.999713,0.018609,0.000000,0.008748,-0.018743,0.999786,0.000000,28.181459,-0.033842,-0.000631,1.000000;;, + 2160;16;0.999843,-0.015010,-0.009375,0.000000,0.015227,0.999608,0.023506,0.000000,0.009018,-0.023645,0.999680,0.000000,28.181465,-0.033830,-0.000798,1.000000;;, + 2240;16;0.999842,-0.014966,-0.009616,0.000000,0.015231,0.999488,0.028137,0.000000,0.009190,-0.028279,0.999558,0.000000,28.181452,-0.033852,-0.000955,1.000000;;, + 2320;16;0.999845,-0.014715,-0.009695,0.000000,0.015023,0.999359,0.032503,0.000000,0.009210,-0.032644,0.999425,0.000000,28.181450,-0.033814,-0.001103,1.000000;;, + 2400;16;0.999851,-0.014298,-0.009621,0.000000,0.014641,0.999224,0.036556,0.000000,0.009091,-0.036692,0.999285,0.000000,28.181465,-0.033791,-0.001241,1.000000;;, + 2480;16;0.999862,-0.013688,-0.009366,0.000000,0.014055,0.999090,0.040282,0.000000,0.008806,-0.040409,0.999144,0.000000,28.181517,-0.033817,-0.001366,1.000000;;, + 2560;16;0.999875,-0.013001,-0.008993,0.000000,0.013381,0.998960,0.043576,0.000000,0.008417,-0.043691,0.999010,0.000000,28.181549,-0.033836,-0.001476,1.000000;;, + 2640;16;0.999888,-0.012318,-0.008544,0.000000,0.012701,0.998844,0.046354,0.000000,0.007963,-0.046458,0.998889,0.000000,28.181564,-0.033836,-0.001570,1.000000;;, + 2720;16;0.999899,-0.011717,-0.008061,0.000000,0.012095,0.998748,0.048534,0.000000,0.007483,-0.048627,0.998789,0.000000,28.181547,-0.033857,-0.001645,1.000000;;, + 2800;16;0.999907,-0.011300,-0.007608,0.000000,0.011666,0.998680,0.050014,0.000000,0.007033,-0.050098,0.998720,0.000000,28.181583,-0.033833,-0.001695,1.000000;;, + 2880;16;0.999913,-0.011081,-0.007168,0.000000,0.011430,0.998645,0.050771,0.000000,0.006596,-0.050848,0.998685,0.000000,28.181591,-0.033802,-0.001721,1.000000;;, + 2960;16;0.999915,-0.011139,-0.006756,0.000000,0.011468,0.998647,0.050714,0.000000,0.006182,-0.050787,0.998690,0.000000,28.181618,-0.033829,-0.001718,1.000000;;, + 3040;16;0.999915,-0.011385,-0.006341,0.000000,0.011688,0.998684,0.049943,0.000000,0.005764,-0.050012,0.998732,0.000000,28.181599,-0.033857,-0.001693,1.000000;;, + 3120;16;0.999913,-0.011770,-0.005889,0.000000,0.012042,0.998750,0.048503,0.000000,0.005310,-0.048570,0.998806,0.000000,28.181557,-0.033831,-0.001643,1.000000;;, + 3200;16;0.999910,-0.012246,-0.005421,0.000000,0.012485,0.998842,0.046459,0.000000,0.004846,-0.046522,0.998905,0.000000,28.181559,-0.033862,-0.001575,1.000000;;, + 3280;16;0.999906,-0.012764,-0.004945,0.000000,0.012968,0.998953,0.043868,0.000000,0.004380,-0.043928,0.999025,0.000000,28.181566,-0.033826,-0.001487,1.000000;;, + 3360;16;0.999902,-0.013275,-0.004470,0.000000,0.013446,0.999077,0.040788,0.000000,0.003924,-0.040844,0.999158,0.000000,28.181530,-0.033886,-0.001383,1.000000;;, + 3440;16;0.999898,-0.013710,-0.004007,0.000000,0.013850,0.999209,0.037272,0.000000,0.003493,-0.037324,0.999297,0.000000,28.181486,-0.033862,-0.001263,1.000000;;, + 3520;16;0.999895,-0.014085,-0.003553,0.000000,0.014195,0.999341,0.033398,0.000000,0.003080,-0.033445,0.999436,0.000000,28.181517,-0.033820,-0.001130,1.000000;;, + 3600;16;0.999892,-0.014378,-0.003112,0.000000,0.014463,0.999467,0.029249,0.000000,0.002690,-0.029291,0.999567,0.000000,28.181490,-0.033846,-0.000991,1.000000;;, + 3680;16;0.999889,-0.014633,-0.002678,0.000000,0.014695,0.999583,0.024863,0.000000,0.002313,-0.024899,0.999687,0.000000,28.181467,-0.033848,-0.000841,1.000000;;, + 3760;16;0.999887,-0.014890,-0.002241,0.000000,0.014933,0.999682,0.020298,0.000000,0.001938,-0.020329,0.999792,0.000000,28.181490,-0.033844,-0.000687,1.000000;;, + 3840;16;0.999884,-0.015138,-0.001804,0.000000,0.015164,0.999764,0.015564,0.000000,0.001568,-0.015589,0.999877,0.000000,28.181444,-0.033860,-0.000526,1.000000;;, + 3920;16;0.999881,-0.015377,-0.001368,0.000000,0.015390,0.999825,0.010683,0.000000,0.001203,-0.010703,0.999942,0.000000,28.181479,-0.033850,-0.000361,1.000000;;, + 4000;16;0.999878,-0.015607,-0.000931,0.000000,0.015612,0.999862,0.005677,0.000000,0.000842,-0.005691,0.999983,0.000000,28.181408,-0.033862,-0.000190,1.000000;;, + 4080;16;0.999875,-0.015831,-0.000494,0.000000,0.015832,0.999874,0.000569,0.000000,0.000485,-0.000577,1.000000,0.000000,28.181391,-0.033842,-0.000016,1.000000;;, + 4160;16;0.999871,-0.016049,-0.000057,0.000000,0.016049,0.999861,-0.004620,0.000000,0.000131,0.004618,0.999989,0.000000,28.181423,-0.033896,0.000155,1.000000;;, + 4240;16;0.999868,-0.016262,0.000381,0.000000,0.016265,0.999819,-0.009867,0.000000,-0.000220,0.009872,0.999951,0.000000,28.181391,-0.033872,0.000335,1.000000;;, + 4320;16;0.999864,-0.016470,0.000819,0.000000,0.016481,0.999749,-0.015150,0.000000,-0.000569,0.015162,0.999885,0.000000,28.181414,-0.033918,0.000510,1.000000;;, + 4400;16;0.999860,-0.016676,0.001259,0.000000,0.016698,0.999652,-0.020448,0.000000,-0.000917,0.020466,0.999790,0.000000,28.181410,-0.033869,0.000693,1.000000;;, + 4480;16;0.999856,-0.016880,0.001699,0.000000,0.016918,0.999526,-0.025737,0.000000,-0.001264,0.025763,0.999667,0.000000,28.181383,-0.033883,0.000871,1.000000;;, + 4560;16;0.999852,-0.017082,0.002141,0.000000,0.017141,0.999372,-0.030997,0.000000,-0.001611,0.031029,0.999517,0.000000,28.181395,-0.033810,0.001054,1.000000;;, + 4640;16;0.999847,-0.017285,0.002585,0.000000,0.017367,0.999193,-0.036204,0.000000,-0.001957,0.036244,0.999341,0.000000,28.181389,-0.033833,0.001229,1.000000;;, + 4720;16;0.999842,-0.017491,0.003030,0.000000,0.017601,0.998991,-0.041308,0.000000,-0.002305,0.041355,0.999142,0.000000,28.181398,-0.033816,0.001402,1.000000;;, + 4800;16;0.999837,-0.017696,0.003477,0.000000,0.017838,0.998765,-0.046374,0.000000,-0.002652,0.046428,0.998918,0.000000,28.181417,-0.033880,0.001568,1.000000;;, + 4960;16;0.999844,-0.017541,0.002139,0.000000,0.017628,0.998492,-0.051985,0.000000,-0.001224,0.052014,0.998646,0.000000,28.181387,-0.033838,0.001761,1.000000;;; + } + { Bip01_Spine3 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566051,-0.019152,-0.000001,1.000000;;, + 80;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566063,-0.019157,-0.000001,1.000000;;, + 160;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566074,-0.019146,-0.000000,1.000000;;, + 240;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566082,-0.019151,-0.000001,1.000000;;, + 320;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566093,-0.019149,-0.000000,1.000000;;, + 400;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566093,-0.019138,0.000001,1.000000;;, + 480;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566078,-0.019146,-0.000000,1.000000;;, + 560;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566078,-0.019152,-0.000001,1.000000;;, + 640;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566071,-0.019145,0.000000,1.000000;;, + 720;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566078,-0.019133,0.000002,1.000000;;, + 800;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566055,-0.019141,0.000000,1.000000;;, + 880;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566093,-0.019140,0.000001,1.000000;;, + 960;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566048,-0.019155,-0.000003,1.000000;;, + 1040;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566097,-0.019147,0.000001,1.000000;;, + 1120;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566082,-0.019140,0.000001,1.000000;;, + 1200;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566078,-0.019156,-0.000001,1.000000;;, + 1280;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566055,-0.019162,-0.000003,1.000000;;, + 1360;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566086,-0.019146,0.000000,1.000000;;, + 1440;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566071,-0.019169,-0.000002,1.000000;;, + 1520;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566051,-0.019159,-0.000002,1.000000;;, + 1600;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566067,-0.019163,-0.000001,1.000000;;, + 1680;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566071,-0.019174,-0.000001,1.000000;;, + 1760;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566082,-0.019169,-0.000000,1.000000;;, + 1840;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566093,-0.019141,0.000001,1.000000;;, + 1920;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566051,-0.019146,-0.000001,1.000000;;, + 2000;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566090,-0.019145,0.000001,1.000000;;, + 2080;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566048,-0.019155,-0.000001,1.000000;;, + 2160;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566059,-0.019159,-0.000001,1.000000;;, + 2240;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566086,-0.019147,0.000001,1.000000;;, + 2320;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566067,-0.019134,-0.000002,1.000000;;, + 2400;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566071,-0.019154,0.000000,1.000000;;, + 2480;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566097,-0.019141,0.000000,1.000000;;, + 2560;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566093,-0.019137,-0.000000,1.000000;;, + 2640;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566067,-0.019130,-0.000002,1.000000;;, + 2720;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566063,-0.019083,-0.000004,1.000000;;, + 2800;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566048,-0.019105,-0.000003,1.000000;;, + 2880;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566074,-0.019139,-0.000000,1.000000;;, + 2960;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566059,-0.019120,-0.000001,1.000000;;, + 3040;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566078,-0.019110,-0.000001,1.000000;;, + 3120;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566090,-0.019134,-0.000000,1.000000;;, + 3200;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566090,-0.019111,-0.000001,1.000000;;, + 3280;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566059,-0.019137,0.000000,1.000000;;, + 3360;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566067,-0.019102,-0.000000,1.000000;;, + 3440;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566082,-0.019094,0.000001,1.000000;;, + 3520;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566071,-0.019155,-0.000000,1.000000;;, + 3600;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566086,-0.019138,-0.000000,1.000000;;, + 3680;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566086,-0.019154,-0.000000,1.000000;;, + 3760;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566071,-0.019144,0.000000,1.000000;;, + 3840;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566093,-0.019120,0.000000,1.000000;;, + 3920;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566059,-0.019139,0.000001,1.000000;;, + 4000;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566074,-0.019157,-0.000001,1.000000;;, + 4080;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566097,-0.019134,0.000000,1.000000;;, + 4160;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566059,-0.019083,0.000005,1.000000;;, + 4240;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566097,-0.019126,0.000001,1.000000;;, + 4320;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566090,-0.019128,0.000001,1.000000;;, + 4400;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566086,-0.019094,0.000005,1.000000;;, + 4480;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566086,-0.019163,-0.000002,1.000000;;, + 4560;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566044,-0.019131,0.000002,1.000000;;, + 4640;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566113,-0.019136,0.000001,1.000000;;, + 4720;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566063,-0.019118,0.000004,1.000000;;, + 4800;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566055,-0.019138,0.000001,1.000000;;, + 4960;16;0.861629,0.507538,0.000001,0.000000,-0.507538,0.861629,-0.000000,0.000000,-0.000001,-0.000000,1.000000,0.000000,42.566051,-0.019152,-0.000001,1.000000;;; + } + { Bip01_Neck } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.975145,-0.214584,-0.055187,0.000000,0.220005,0.967277,0.126384,0.000000,0.026261,-0.135385,0.990445,0.000000,27.900181,-0.000002,0.000000,1.000000;;, + 80;16;0.975197,-0.214991,-0.052635,0.000000,0.220268,0.966011,0.135298,0.000000,0.021758,-0.143536,0.989406,0.000000,27.900167,-0.000002,-0.000001,1.000000;;, + 160;16;0.975267,-0.215301,-0.049997,0.000000,0.220365,0.964664,0.144437,0.000000,0.017133,-0.151882,0.988250,0.000000,27.900175,0.000002,0.000000,1.000000;;, + 240;16;0.975441,-0.215181,-0.047029,0.000000,0.219930,0.963202,0.154506,0.000000,0.012052,-0.161054,0.986872,0.000000,27.900183,-0.000004,0.000001,1.000000;;, + 320;16;0.975573,-0.215199,-0.044121,0.000000,0.219562,0.961661,0.164319,0.000000,0.007068,-0.169992,0.985420,0.000000,27.900177,0.000001,0.000001,1.000000;;, + 400;16;0.975580,-0.215682,-0.041530,0.000000,0.219629,0.960090,0.173176,0.000000,0.002521,-0.178068,0.984015,0.000000,27.900154,-0.000002,-0.000002,1.000000;;, + 480;16;0.975383,-0.216948,-0.039524,0.000000,0.220516,0.958559,0.180383,0.000000,-0.001248,-0.184658,0.982802,0.000000,27.900179,-0.000001,0.000000,1.000000;;, + 560;16;0.975012,-0.218842,-0.038201,0.000000,0.222115,0.957236,0.185378,0.000000,-0.004001,-0.189231,0.981925,0.000000,27.900166,0.000005,-0.000000,1.000000;;, + 640;16;0.974044,-0.223089,-0.038331,0.000000,0.226300,0.955921,0.187092,0.000000,-0.005097,-0.190910,0.981594,0.000000,27.900171,-0.000009,-0.000000,1.000000;;, + 720;16;0.971828,-0.232107,-0.040951,0.000000,0.235664,0.954284,0.183861,0.000000,-0.003596,-0.188332,0.982099,0.000000,27.900181,-0.000010,-0.000001,1.000000;;, + 800;16;0.968795,-0.243752,-0.044946,0.000000,0.247861,0.952526,0.176804,0.000000,-0.000284,-0.182427,0.983219,0.000000,27.900183,-0.000007,0.000000,1.000000;;, + 880;16;0.964823,-0.258093,-0.050051,0.000000,0.262858,0.950475,0.165841,0.000000,0.004770,-0.173163,0.984882,0.000000,27.900158,-0.000001,-0.000002,1.000000;;, + 960;16;0.961036,-0.270992,-0.054531,0.000000,0.276231,0.948855,0.152875,0.000000,0.010314,-0.161981,0.986740,0.000000,27.900185,-0.000003,0.000001,1.000000;;, + 1040;16;0.958751,-0.278453,-0.057093,0.000000,0.283838,0.948626,0.139806,0.000000,0.015230,-0.150244,0.988532,0.000000,27.900154,0.000002,-0.000001,1.000000;;, + 1120;16;0.958315,-0.279751,-0.058075,0.000000,0.285039,0.950072,0.126952,0.000000,0.019660,-0.138214,0.990207,0.000000,27.900169,-0.000004,-0.000001,1.000000;;, + 1200;16;0.960714,-0.271553,-0.057341,0.000000,0.276558,0.954028,0.115524,0.000000,0.023334,-0.126844,0.991648,0.000000,27.900175,0.000008,0.000000,1.000000;;, + 1280;16;0.964677,-0.257395,-0.056096,0.000000,0.262063,0.959356,0.104684,0.000000,0.026871,-0.115686,0.992922,0.000000,27.900183,0.000001,0.000001,1.000000;;, + 1360;16;0.969418,-0.239136,-0.055161,0.000000,0.243477,0.965345,0.093953,0.000000,0.030781,-0.104510,0.994047,0.000000,27.900160,0.000011,-0.000000,1.000000;;, + 1440;16;0.974249,-0.218751,-0.054649,0.000000,0.222769,0.971291,0.083475,0.000000,0.034820,-0.093500,0.995010,0.000000,27.900187,0.000001,0.000001,1.000000;;, + 1520;16;0.978630,-0.198249,-0.054603,0.000000,0.201936,0.976656,0.073246,0.000000,0.038807,-0.082707,0.995818,0.000000,27.900177,0.000001,0.000000,1.000000;;, + 1600;16;0.982195,-0.179675,-0.054862,0.000000,0.183003,0.981076,0.063241,0.000000,0.042461,-0.072155,0.996489,0.000000,27.900177,-0.000000,0.000001,1.000000;;, + 1680;16;0.984643,-0.165625,-0.055193,0.000000,0.168535,0.984267,0.053052,0.000000,0.045538,-0.061539,0.997065,0.000000,27.900185,0.000018,0.000000,1.000000;;, + 1760;16;0.986165,-0.156511,-0.054617,0.000000,0.158953,0.986321,0.043648,0.000000,0.047039,-0.051725,0.997553,0.000000,27.900152,0.000007,-0.000001,1.000000;;, + 1840;16;0.986674,-0.154239,-0.051811,0.000000,0.156181,0.987081,0.035767,0.000000,0.045625,-0.043382,0.998016,0.000000,27.900175,-0.000011,0.000000,1.000000;;, + 1920;16;0.986546,-0.156575,-0.047031,0.000000,0.158056,0.986987,0.029593,0.000000,0.041786,-0.036628,0.998455,0.000000,27.900173,-0.000017,0.000000,1.000000;;, + 2000;16;0.985931,-0.162299,-0.039997,0.000000,0.163398,0.986220,0.025917,0.000000,0.035239,-0.032088,0.998864,0.000000,27.900160,0.000003,-0.000001,1.000000;;, + 2080;16;0.984863,-0.170390,-0.031822,0.000000,0.171175,0.984952,0.023833,0.000000,0.027282,-0.028919,0.999209,0.000000,27.900188,0.000003,0.000000,1.000000;;, + 2160;16;0.983443,-0.179718,-0.023291,0.000000,0.180245,0.983354,0.022937,0.000000,0.018781,-0.026756,0.999466,0.000000,27.900175,0.000010,-0.000000,1.000000;;, + 2240;16;0.981698,-0.189796,-0.015703,0.000000,0.190118,0.981504,0.022470,0.000000,0.011148,-0.025044,0.999624,0.000000,27.900187,0.000002,-0.000001,1.000000;;, + 2320;16;0.979787,-0.199760,-0.010657,0.000000,0.199947,0.979580,0.021069,0.000000,0.006231,-0.022774,0.999721,0.000000,27.900188,-0.000012,0.000001,1.000000;;, + 2400;16;0.977670,-0.209981,-0.008269,0.000000,0.210108,0.977475,0.019939,0.000000,0.003896,-0.021231,0.999767,0.000000,27.900152,0.000001,-0.000000,1.000000;;, + 2480;16;0.975316,-0.220598,-0.009744,0.000000,0.220752,0.975133,0.019579,0.000000,0.005183,-0.021247,0.999761,0.000000,27.900166,-0.000005,0.000000,1.000000;;, + 2560;16;0.972729,-0.231551,-0.013496,0.000000,0.231795,0.972544,0.020746,0.000000,0.008321,-0.023308,0.999694,0.000000,27.900156,0.000010,-0.000000,1.000000;;, + 2640;16;0.969809,-0.243150,-0.018652,0.000000,0.243566,0.969568,0.024771,0.000000,0.012061,-0.028566,0.999519,0.000000,27.900169,-0.000002,0.000000,1.000000;;, + 2720;16;0.966884,-0.254043,-0.024428,0.000000,0.254722,0.966532,0.030538,0.000000,0.015852,-0.035749,0.999235,0.000000,27.900152,-0.000005,0.000001,1.000000;;, + 2800;16;0.964304,-0.263100,-0.029933,0.000000,0.264120,0.963753,0.037692,0.000000,0.018932,-0.044252,0.998841,0.000000,27.900171,-0.000013,0.000001,1.000000;;, + 2880;16;0.962281,-0.269829,-0.034751,0.000000,0.271235,0.961439,0.045462,0.000000,0.021144,-0.053173,0.998361,0.000000,27.900160,0.000003,0.000000,1.000000;;, + 2960;16;0.961211,-0.273166,-0.038119,0.000000,0.274934,0.959976,0.053444,0.000000,0.021994,-0.061851,0.997843,0.000000,27.900177,0.000008,-0.000000,1.000000;;, + 3040;16;0.960963,-0.273772,-0.039975,0.000000,0.275810,0.959323,0.060235,0.000000,0.021858,-0.068909,0.997383,0.000000,27.900162,-0.000004,0.000000,1.000000;;, + 3120;16;0.961544,-0.271764,-0.039720,0.000000,0.273867,0.959642,0.063915,0.000000,0.020747,-0.072335,0.997165,0.000000,27.900173,-0.000012,0.000000,1.000000;;, + 3200;16;0.962726,-0.267803,-0.037950,0.000000,0.269818,0.960676,0.065568,0.000000,0.018898,-0.073363,0.997126,0.000000,27.900158,-0.000005,0.000000,1.000000;;, + 3280;16;0.964310,-0.262468,-0.034891,0.000000,0.264264,0.962246,0.065163,0.000000,0.016470,-0.072058,0.997264,0.000000,27.900173,-0.000016,-0.000000,1.000000;;, + 3360;16;0.966149,-0.256110,-0.031048,0.000000,0.257631,0.964118,0.064053,0.000000,0.013529,-0.069883,0.997463,0.000000,27.900162,-0.000006,0.000000,1.000000;;, + 3440;16;0.968062,-0.249274,-0.026813,0.000000,0.250507,0.966045,0.063278,0.000000,0.010129,-0.067974,0.997636,0.000000,27.900162,-0.000003,-0.000000,1.000000;;, + 3520;16;0.970018,-0.241960,-0.022798,0.000000,0.242941,0.967945,0.063730,0.000000,0.006647,-0.067358,0.997707,0.000000,27.900169,-0.000007,0.000000,1.000000;;, + 3600;16;0.971815,-0.234939,-0.019495,0.000000,0.235725,0.969518,0.066851,0.000000,0.003195,-0.069562,0.997573,0.000000,27.900171,0.000011,0.000000,1.000000;;, + 3680;16;0.973899,-0.226296,-0.017646,0.000000,0.226981,0.971228,0.072079,0.000000,0.000827,-0.074203,0.997243,0.000000,27.900162,-0.000001,-0.000000,1.000000;;, + 3760;16;0.976723,-0.213722,-0.018324,0.000000,0.214504,0.973451,0.079882,0.000000,0.000765,-0.081953,0.996636,0.000000,27.900162,-0.000009,0.000000,1.000000;;, + 3840;16;0.979840,-0.198735,-0.020458,0.000000,0.199771,0.975824,0.088652,0.000000,0.002345,-0.090952,0.995853,0.000000,27.900175,-0.000003,-0.000000,1.000000;;, + 3920;16;0.983210,-0.180917,-0.023818,0.000000,0.182388,0.978428,0.097019,0.000000,0.005752,-0.099734,0.994998,0.000000,27.900173,-0.000014,-0.000000,1.000000;;, + 4000;16;0.986085,-0.163976,-0.027349,0.000000,0.165961,0.980553,0.104746,0.000000,0.009641,-0.107828,0.994123,0.000000,27.900162,0.000001,0.000000,1.000000;;, + 4080;16;0.987968,-0.151660,-0.030298,0.000000,0.154119,0.981778,0.111169,0.000000,0.012886,-0.114501,0.993340,0.000000,27.900160,0.000008,0.000000,1.000000;;, + 4160;16;0.989028,-0.143993,-0.032998,0.000000,0.146890,0.982308,0.116169,0.000000,0.015686,-0.119741,0.992681,0.000000,27.900154,-0.000039,-0.000003,1.000000;;, + 4240;16;0.989065,-0.143150,-0.035464,0.000000,0.146405,0.982010,0.119259,0.000000,0.017754,-0.123147,0.992230,0.000000,27.900167,-0.000010,-0.000001,1.000000;;, + 4320;16;0.988482,-0.146415,-0.038289,0.000000,0.150030,0.981253,0.120965,0.000000,0.019860,-0.125316,0.991918,0.000000,27.900164,0.000004,0.000000,1.000000;;, + 4400;16;0.987508,-0.151910,-0.041857,0.000000,0.155947,0.980259,0.121543,0.000000,0.022567,-0.126552,0.991703,0.000000,27.900160,-0.000023,-0.000002,1.000000;;, + 4480;16;0.986183,-0.159134,-0.046045,0.000000,0.163642,0.979044,0.121219,0.000000,0.025790,-0.127079,0.991557,0.000000,27.900187,-0.000000,0.000001,1.000000;;, + 4560;16;0.984606,-0.167248,-0.050779,0.000000,0.172273,0.977686,0.120217,0.000000,0.029539,-0.127114,0.991448,0.000000,27.900185,-0.000018,-0.000002,1.000000;;, + 4640;16;0.982904,-0.175418,-0.055927,0.000000,0.180995,0.976288,0.118754,0.000000,0.033769,-0.126846,0.991347,0.000000,27.900181,0.000027,0.000003,1.000000;;, + 4720;16;0.981339,-0.182286,-0.061210,0.000000,0.188427,0.975080,0.117110,0.000000,0.038337,-0.126458,0.991231,0.000000,27.900169,-0.000003,-0.000001,1.000000;;, + 4800;16;0.979775,-0.188667,-0.066683,0.000000,0.195389,0.973921,0.115333,0.000000,0.043184,-0.126029,0.991086,0.000000,27.900173,0.000003,0.000000,1.000000;;, + 4960;16;0.975145,-0.214584,-0.055187,0.000000,0.220005,0.967277,0.126384,0.000000,0.026261,-0.135385,0.990445,0.000000,27.900181,-0.000002,0.000000,1.000000;;; + } + { Bip01_Head } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615768,-0.000004,0.000001,1.000000;;, + 80;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615772,0.000003,0.000001,1.000000;;, + 160;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615749,-0.000000,0.000001,1.000000;;, + 240;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615746,-0.000004,0.000000,1.000000;;, + 320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615734,-0.000004,-0.000001,1.000000;;, + 400;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,0.000001,0.000001,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615765,0.000003,0.000002,1.000000;;, + 560;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615765,-0.000004,0.000002,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615761,-0.000003,0.000001,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615761,-0.000005,0.000000,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615761,-0.000002,-0.000000,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615749,0.000004,-0.000002,1.000000;;, + 960;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615753,0.000005,-0.000000,1.000000;;, + 1040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615768,-0.000001,0.000003,1.000000;;, + 1120;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615734,0.000003,-0.000002,1.000000;;, + 1200;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,-0.000001,0.000001,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615742,-0.000006,-0.000001,1.000000;;, + 1360;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615749,0.000003,-0.000001,1.000000;;, + 1440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615768,0.000004,0.000002,1.000000;;, + 1520;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615742,0.000006,-0.000000,1.000000;;, + 1600;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615749,-0.000011,0.000001,1.000000;;, + 1680;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615746,0.000012,-0.000002,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615753,0.000001,-0.000001,1.000000;;, + 1840;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615742,0.000017,-0.000003,1.000000;;, + 1920;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615761,-0.000011,0.000001,1.000000;;, + 2000;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615753,0.000013,-0.000002,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615734,-0.000007,-0.000001,1.000000;;, + 2160;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,0.000002,-0.000001,1.000000;;, + 2240;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615746,0.000013,-0.000001,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615746,-0.000003,-0.000000,1.000000;;, + 2400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615738,0.000004,-0.000001,1.000000;;, + 2480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615746,0.000004,-0.000000,1.000000;;, + 2560;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615757,-0.000004,0.000000,1.000000;;, + 2640;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615742,-0.000011,0.000001,1.000000;;, + 2720;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615753,-0.000009,0.000001,1.000000;;, + 2800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615761,0.000006,-0.000000,1.000000;;, + 2880;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615753,-0.000010,0.000001,1.000000;;, + 2960;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615761,0.000013,-0.000000,1.000000;;, + 3040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615746,-0.000012,0.000001,1.000000;;, + 3120;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615757,-0.000015,0.000001,1.000000;;, + 3200;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,-0.000011,0.000002,1.000000;;, + 3280;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615738,-0.000002,-0.000000,1.000000;;, + 3360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615738,-0.000005,0.000001,1.000000;;, + 3440;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615761,-0.000002,0.000000,1.000000;;, + 3520;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615772,0.000001,0.000000,1.000000;;, + 3600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615757,-0.000005,0.000000,1.000000;;, + 3680;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615753,-0.000011,0.000001,1.000000;;, + 3760;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615768,-0.000011,0.000001,1.000000;;, + 3840;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615757,0.000005,-0.000000,1.000000;;, + 3920;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,-0.000009,0.000001,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615765,0.000010,-0.000000,1.000000;;, + 4080;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,59.615749,0.000009,0.000000,1.000000;;, + 4160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615776,0.000010,0.000000,1.000000;;, + 4240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,-0.000026,0.000001,1.000000;;, + 4320;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615742,-0.000026,0.000000,1.000000;;, + 4400;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615765,0.000016,0.000000,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,59.615753,0.000004,0.000001,1.000000;;, + 4560;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615746,0.000007,-0.000002,1.000000;;, + 4640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615757,-0.000022,0.000001,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615765,0.000010,0.000000,1.000000;;, + 4800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,59.615768,0.000027,0.000002,1.000000;;, + 4960;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,59.615768,-0.000004,0.000001,1.000000;;; + } + { Dummy21 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;-0.167240,0.313773,0.934654,0.000000,-0.498528,-0.844794,0.194403,0.000000,0.850588,-0.433439,0.297708,0.000000,-12.374964,4.006889,8.346216,1.000000;;, + 80;16;-0.169076,0.312790,0.934653,0.000000,-0.498708,-0.845100,0.192605,0.000000,0.850120,-0.433554,0.298877,0.000000,-12.374962,4.006893,8.346217,1.000000;;, + 160;16;-0.170912,0.311807,0.934647,0.000000,-0.498887,-0.845402,0.190807,0.000000,0.849648,-0.433672,0.300046,0.000000,-12.374972,4.006898,8.346217,1.000000;;, + 240;16;-0.172799,0.310943,0.934588,0.000000,-0.499055,-0.845688,0.189093,0.000000,0.849167,-0.433736,0.301312,0.000000,-12.374967,4.006896,8.346217,1.000000;;, + 320;16;-0.174582,0.309843,0.934622,0.000000,-0.499239,-0.845999,0.187208,0.000000,0.848694,-0.433917,0.302382,0.000000,-12.374953,4.006895,8.346217,1.000000;;, + 400;16;-0.176219,0.308312,0.934821,0.000000,-0.499453,-0.846361,0.184988,0.000000,0.848230,-0.434300,0.303132,0.000000,-12.374983,4.006896,8.346216,1.000000;;, + 480;16;-0.177428,0.305993,0.935354,0.000000,-0.499714,-0.846804,0.182233,0.000000,0.847824,-0.435076,0.303156,0.000000,-12.374947,4.006888,8.346217,1.000000;;, + 560;16;-0.177768,0.302247,0.936507,0.000000,-0.500056,-0.847384,0.178562,0.000000,0.847551,-0.436563,0.301778,0.000000,-12.374949,4.006895,8.346218,1.000000;;, + 640;16;-0.177685,0.297702,0.937977,0.000000,-0.500440,-0.848033,0.174354,0.000000,0.847342,-0.438421,0.299665,0.000000,-12.374961,4.006884,8.346216,1.000000;;, + 720;16;-0.177231,0.292471,0.939707,0.000000,-0.500853,-0.848734,0.169695,0.000000,0.847193,-0.440580,0.296907,0.000000,-12.374961,4.006879,8.346214,1.000000;;, + 800;16;-0.177138,0.287473,0.941266,0.000000,-0.501251,-0.849408,0.165087,0.000000,0.846977,-0.442567,0.294558,0.000000,-12.374962,4.006883,8.346215,1.000000;;, + 880;16;-0.178220,0.283768,0.942186,0.000000,-0.501584,-0.849973,0.161118,0.000000,0.846552,-0.443871,0.293815,0.000000,-12.374976,4.006899,8.346215,1.000000;;, + 960;16;-0.180269,0.281098,0.942596,0.000000,-0.501870,-0.850457,0.157639,0.000000,0.845949,-0.444643,0.294385,0.000000,-12.374944,4.006894,8.346219,1.000000;;, + 1040;16;-0.183495,0.279724,0.942382,0.000000,-0.502099,-0.850845,0.154788,0.000000,0.845119,-0.444766,0.296575,0.000000,-12.374985,4.006907,8.346216,1.000000;;, + 1120;16;-0.187458,0.279129,0.941779,0.000000,-0.502296,-0.851179,0.152296,0.000000,0.844132,-0.444502,0.299765,0.000000,-12.374974,4.006891,8.346215,1.000000;;, + 1200;16;-0.191709,0.278753,0.941034,0.000000,-0.502485,-0.851499,0.149864,0.000000,0.843064,-0.444125,0.303308,0.000000,-12.374945,4.006901,8.346218,1.000000;;, + 1280;16;-0.196491,0.278971,0.939982,0.000000,-0.502648,-0.851776,0.147721,0.000000,0.841865,-0.443455,0.307590,0.000000,-12.374948,4.006887,8.346218,1.000000;;, + 1360;16;-0.201873,0.279924,0.938557,0.000000,-0.502781,-0.852001,0.145966,0.000000,0.840511,-0.442422,0.312736,0.000000,-12.374995,4.006908,8.346215,1.000000;;, + 1440;16;-0.207923,0.281749,0.936689,0.000000,-0.502876,-0.852161,0.144697,0.000000,0.838978,-0.440952,0.318869,0.000000,-12.374962,4.006903,8.346218,1.000000;;, + 1520;16;-0.214508,0.284228,0.934452,0.000000,-0.502944,-0.852276,0.143780,0.000000,0.837278,-0.439135,0.325771,0.000000,-12.374935,4.006886,8.346218,1.000000;;, + 1600;16;-0.222300,0.288549,0.931301,0.000000,-0.502927,-0.852248,0.144009,0.000000,0.835253,-0.436363,0.334574,0.000000,-12.374966,4.006901,8.346218,1.000000;;, + 1680;16;-0.232111,0.296207,0.926491,0.000000,-0.502747,-0.851943,0.146421,0.000000,0.832689,-0.431804,0.346662,0.000000,-12.374960,4.006915,8.346217,1.000000;;, + 1760;16;-0.243355,0.305918,0.920431,0.000000,-0.502463,-0.851462,0.150147,0.000000,0.829644,-0.425943,0.360920,0.000000,-12.374978,4.006920,8.346216,1.000000;;, + 1840;16;-0.256168,0.317769,0.912908,0.000000,-0.502061,-0.850781,0.155262,0.000000,0.826022,-0.418562,0.377483,0.000000,-12.374993,4.006886,8.346215,1.000000;;, + 1920;16;-0.269189,0.329157,0.905093,0.000000,-0.501680,-0.850135,0.159963,0.000000,0.822104,-0.411007,0.393978,0.000000,-12.374964,4.006881,8.346217,1.000000;;, + 2000;16;-0.281039,0.337658,0.898334,0.000000,-0.501467,-0.849774,0.162525,0.000000,0.818259,-0.404809,0.408144,0.000000,-12.374958,4.006900,8.346216,1.000000;;, + 2080;16;-0.291958,0.343326,0.892686,0.000000,-0.501443,-0.849734,0.162807,0.000000,0.814442,-0.400099,0.420245,0.000000,-12.374943,4.006909,8.346217,1.000000;;, + 2160;16;-0.301518,0.344840,0.888916,0.000000,-0.501707,-0.850181,0.159636,0.000000,0.810788,-0.397842,0.429353,0.000000,-12.374960,4.006894,8.346217,1.000000;;, + 2240;16;-0.310373,0.343935,0.886215,0.000000,-0.502132,-0.850901,0.154371,0.000000,0.807175,-0.397084,0.436797,0.000000,-12.374965,4.006871,8.346217,1.000000;;, + 2320;16;-0.319163,0.341745,0.883937,0.000000,-0.502641,-0.851764,0.147817,0.000000,0.803422,-0.397125,0.443627,0.000000,-12.374967,4.006865,8.346219,1.000000;;, + 2400;16;-0.327476,0.338564,0.882119,0.000000,-0.503185,-0.852686,0.140466,0.000000,0.799727,-0.397870,0.449595,0.000000,-12.374972,4.006896,8.346217,1.000000;;, + 2480;16;-0.335163,0.334888,0.880634,0.000000,-0.503717,-0.853586,0.132891,0.000000,0.796201,-0.399050,0.454779,0.000000,-12.374965,4.006886,8.346217,1.000000;;, + 2560;16;-0.342076,0.331206,0.879367,0.000000,-0.504195,-0.854397,0.125668,0.000000,0.792951,-0.400385,0.459261,0.000000,-12.374938,4.006904,8.346217,1.000000;;, + 2640;16;-0.348158,0.328208,0.878103,0.000000,-0.504580,-0.855050,0.119531,0.000000,0.790054,-0.401458,0.463300,0.000000,-12.374950,4.006896,8.346217,1.000000;;, + 2720;16;-0.352986,0.325774,0.877082,0.000000,-0.504877,-0.855552,0.114587,0.000000,0.787719,-0.402370,0.466474,0.000000,-12.374984,4.006876,8.346219,1.000000;;, + 2800;16;-0.356024,0.324125,0.876464,0.000000,-0.505064,-0.855869,0.111349,0.000000,0.786230,-0.403027,0.468414,0.000000,-12.374964,4.006858,8.346218,1.000000;;, + 2880;16;-0.357567,0.322919,0.876281,0.000000,-0.505178,-0.856062,0.109330,0.000000,0.785456,-0.403585,0.469232,0.000000,-12.374959,4.006901,8.346216,1.000000;;, + 2960;16;-0.357503,0.321827,0.876709,0.000000,-0.505237,-0.856163,0.108260,0.000000,0.785447,-0.404243,0.468680,0.000000,-12.374958,4.006893,8.346217,1.000000;;, + 3040;16;-0.356492,0.321048,0.877406,0.000000,-0.505252,-0.856187,0.107999,0.000000,0.785897,-0.404810,0.467434,0.000000,-12.374981,4.006920,8.346217,1.000000;;, + 3120;16;-0.355094,0.320544,0.878157,0.000000,-0.505240,-0.856167,0.108218,0.000000,0.786538,-0.405252,0.465971,0.000000,-12.374980,4.006894,8.346217,1.000000;;, + 3200;16;-0.353494,0.320707,0.878743,0.000000,-0.505184,-0.856073,0.109212,0.000000,0.787293,-0.405321,0.464633,0.000000,-12.374977,4.006891,8.346217,1.000000;;, + 3280;16;-0.352255,0.322102,0.878730,0.000000,-0.505069,-0.855878,0.111259,0.000000,0.787922,-0.404628,0.464171,0.000000,-12.374953,4.006900,8.346217,1.000000;;, + 3360;16;-0.350816,0.324162,0.878548,0.000000,-0.504906,-0.855602,0.114080,0.000000,0.788668,-0.403563,0.463831,0.000000,-12.374961,4.006896,8.346217,1.000000;;, + 3440;16;-0.348943,0.326855,0.878296,0.000000,-0.504688,-0.855232,0.117761,0.000000,0.789638,-0.402174,0.463387,0.000000,-12.374968,4.006890,8.346216,1.000000;;, + 3520;16;-0.346211,0.329156,0.878518,0.000000,-0.504460,-0.854846,0.121487,0.000000,0.790985,-0.401117,0.462004,0.000000,-12.374979,4.006877,8.346216,1.000000;;, + 3600;16;-0.342083,0.330111,0.879776,0.000000,-0.504266,-0.854518,0.124560,0.000000,0.792903,-0.401031,0.458780,0.000000,-12.374969,4.006895,8.346217,1.000000;;, + 3680;16;-0.336630,0.329495,0.882107,0.000000,-0.504127,-0.854282,0.126716,0.000000,0.795321,-0.402038,0.453685,0.000000,-12.374988,4.006921,8.346217,1.000000;;, + 3760;16;-0.329591,0.326439,0.885894,0.000000,-0.504094,-0.854226,0.127225,0.000000,0.798285,-0.404641,0.446101,0.000000,-12.374954,4.006886,8.346217,1.000000;;, + 3840;16;-0.321421,0.321840,0.890566,0.000000,-0.504123,-0.854276,0.126779,0.000000,0.801591,-0.408206,0.436829,0.000000,-12.374970,4.006894,8.346216,1.000000;;, + 3920;16;-0.312468,0.316118,0.895786,0.000000,-0.504197,-0.854400,0.125640,0.000000,0.805077,-0.412394,0.426359,0.000000,-12.374981,4.006866,8.346216,1.000000;;, + 4000;16;-0.302820,0.309854,0.901272,0.000000,-0.504279,-0.854540,0.124354,0.000000,0.808704,-0.416836,0.415025,0.000000,-12.374947,4.006918,8.346219,1.000000;;, + 4080;16;-0.292633,0.303606,0.906747,0.000000,-0.504340,-0.854643,0.123395,0.000000,0.812408,-0.421199,0.403217,0.000000,-12.374985,4.006909,8.346217,1.000000;;, + 4160;16;-0.282062,0.297951,0.911957,0.000000,-0.504350,-0.854660,0.123239,0.000000,0.816132,-0.425185,0.391339,0.000000,-12.374960,4.006845,8.346213,1.000000;;, + 4240;16;-0.271405,0.293515,0.916618,0.000000,-0.504281,-0.854543,0.124323,0.000000,0.819780,-0.428491,0.379941,0.000000,-12.374996,4.006858,8.346213,1.000000;;, + 4320;16;-0.260410,0.290803,0.920663,0.000000,-0.504094,-0.854225,0.127235,0.000000,0.823454,-0.430967,0.369041,0.000000,-12.374979,4.006874,8.346215,1.000000;;, + 4400;16;-0.248931,0.290808,0.923831,0.000000,-0.503712,-0.853578,0.132965,0.000000,0.827229,-0.432245,0.358965,0.000000,-12.374986,4.006876,8.346214,1.000000;;, + 4480;16;-0.236945,0.292723,0.926375,0.000000,-0.503166,-0.852654,0.140730,0.000000,0.831072,-0.432775,0.349321,0.000000,-12.374962,4.006917,8.346219,1.000000;;, + 4560;16;-0.224244,0.296375,0.928373,0.000000,-0.502439,-0.851422,0.150448,0.000000,0.835027,-0.432714,0.339837,0.000000,-12.374972,4.006852,8.346212,1.000000;;, + 4640;16;-0.211239,0.300811,0.929995,0.000000,-0.501594,-0.849990,0.161001,0.000000,0.838917,-0.432470,0.330436,0.000000,-12.374963,4.006896,8.346216,1.000000;;, + 4720;16;-0.198319,0.304878,0.931514,0.000000,-0.500729,-0.848523,0.171111,0.000000,0.842580,-0.432502,0.320939,0.000000,-12.374978,4.006879,8.346214,1.000000;;, + 4800;16;-0.185356,0.308957,0.932839,0.000000,-0.499811,-0.846968,0.181203,0.000000,0.846069,-0.432656,0.311411,0.000000,-12.374969,4.006883,8.346215,1.000000;;, + 4960;16;-0.167240,0.313773,0.934654,0.000000,-0.498528,-0.844794,0.194403,0.000000,0.850588,-0.433439,0.297708,0.000000,-12.374964,4.006889,8.346216,1.000000;;; + } + { Bip01_L_Clavicle } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.664909,0.057512,-0.744707,0.000000,0.080413,0.985725,0.147922,0.000000,0.742583,-0.158239,0.650792,0.000000,31.000193,-0.000001,0.000006,1.000000;;, + 80;16;0.677111,0.041649,-0.734701,0.000000,0.081682,0.987974,0.131286,0.000000,0.731333,-0.148907,0.665566,0.000000,31.000191,0.000002,0.000005,1.000000;;, + 160;16;0.689314,0.026352,-0.723983,0.000000,0.082675,0.989948,0.114749,0.000000,0.719730,-0.138954,0.680207,0.000000,31.000195,0.000001,0.000001,1.000000;;, + 240;16;0.702174,0.010462,-0.711928,0.000000,0.083083,0.991857,0.096521,0.000000,0.707141,-0.126924,0.695587,0.000000,31.000191,-0.000000,0.000016,1.000000;;, + 320;16;0.713950,-0.001421,-0.700196,0.000000,0.081960,0.993293,0.081554,0.000000,0.695384,-0.115614,0.709278,0.000000,31.000196,0.000010,-0.000026,1.000000;;, + 400;16;0.723141,-0.005627,-0.690678,0.000000,0.077624,0.994294,0.073172,0.000000,0.686325,-0.106527,0.719451,0.000000,31.000187,0.000001,0.000011,1.000000;;, + 480;16;0.729524,-0.001482,-0.683953,0.000000,0.071224,0.994725,0.073815,0.000000,0.680236,-0.102564,0.725782,0.000000,31.000193,-0.000003,0.000008,1.000000;;, + 560;16;0.732128,0.014851,-0.681005,0.000000,0.062323,0.994108,0.088680,0.000000,0.678310,-0.107367,0.726889,0.000000,31.000196,0.000011,-0.000018,1.000000;;, + 640;16;0.731502,0.037430,-0.680811,0.000000,0.054480,0.992091,0.113081,0.000000,0.679660,-0.119809,0.723677,0.000000,31.000193,-0.000002,0.000005,1.000000;;, + 720;16;0.728315,0.062572,-0.682379,0.000000,0.051888,0.987927,0.145971,0.000000,0.683275,-0.141720,0.716276,0.000000,31.000193,0.000001,0.000005,1.000000;;, + 800;16;0.722962,0.087923,-0.685270,0.000000,0.052813,0.981934,0.181705,0.000000,0.688866,-0.167557,0.705258,0.000000,31.000189,-0.000001,0.000021,1.000000;;, + 880;16;0.715919,0.109442,-0.689552,0.000000,0.057335,0.975086,0.214288,0.000000,0.695825,-0.192948,0.691808,0.000000,31.000189,0.000005,0.000020,1.000000;;, + 960;16;0.706804,0.129493,-0.695457,0.000000,0.063230,0.967604,0.244428,0.000000,0.704578,-0.216736,0.675718,0.000000,31.000193,0.000002,0.000012,1.000000;;, + 1040;16;0.694685,0.148445,-0.703830,0.000000,0.068273,0.960450,0.269954,0.000000,0.716067,-0.235586,0.657075,0.000000,31.000195,0.000005,-0.000002,1.000000;;, + 1120;16;0.680198,0.168418,-0.713419,0.000000,0.072459,0.953034,0.294070,0.000000,0.729439,-0.251719,0.636048,0.000000,31.000187,-0.000002,0.000021,1.000000;;, + 1200;16;0.663318,0.191979,-0.723293,0.000000,0.074914,0.944643,0.319432,0.000000,0.744578,-0.266070,0.612217,0.000000,31.000187,-0.000003,0.000004,1.000000;;, + 1280;16;0.645464,0.217336,-0.732217,0.000000,0.076240,0.935541,0.344893,0.000000,0.759976,-0.278440,0.587288,0.000000,31.000193,0.000000,-0.000009,1.000000;;, + 1360;16;0.627810,0.243434,-0.739320,0.000000,0.076846,0.925810,0.370095,0.000000,0.774564,-0.289163,0.562526,0.000000,31.000193,0.000000,0.000008,1.000000;;, + 1440;16;0.611526,0.269949,-0.743749,0.000000,0.076045,0.915594,0.394848,0.000000,0.787561,-0.298018,0.539382,0.000000,31.000185,-0.000008,0.000026,1.000000;;, + 1520;16;0.597625,0.296327,-0.745007,0.000000,0.074495,0.904654,0.419585,0.000000,0.798308,-0.306254,0.518569,0.000000,31.000196,0.000006,-0.000025,1.000000;;, + 1600;16;0.587804,0.321452,-0.742398,0.000000,0.068325,0.894666,0.441480,0.000000,0.806113,-0.310228,0.503925,0.000000,31.000189,-0.000004,0.000016,1.000000;;, + 1680;16;0.584715,0.343311,-0.735014,0.000000,0.052924,0.887966,0.456854,0.000000,0.809510,-0.306029,0.501038,0.000000,31.000196,-0.000028,-0.000003,1.000000;;, + 1760;16;0.585148,0.363285,-0.725001,0.000000,0.031238,0.883279,0.467807,0.000000,0.810325,-0.296384,0.505500,0.000000,31.000181,0.000007,0.000018,1.000000;;, + 1840;16;0.588209,0.381503,-0.713067,0.000000,0.002441,0.880894,0.473307,0.000000,0.808705,-0.280144,0.517219,0.000000,31.000193,-0.000018,-0.000001,1.000000;;, + 1920;16;0.590003,0.400505,-0.701065,0.000000,-0.026187,0.877334,0.479165,0.000000,0.806976,-0.264350,0.528118,0.000000,31.000183,-0.000005,0.000027,1.000000;;, + 2000;16;0.587083,0.422733,-0.690384,0.000000,-0.047649,0.869391,0.491823,0.000000,0.808123,-0.255845,0.530547,0.000000,31.000193,-0.000008,-0.000004,1.000000;;, + 2080;16;0.579066,0.449439,-0.680211,0.000000,-0.063170,0.856553,0.512178,0.000000,0.812830,-0.253616,0.524392,0.000000,31.000183,0.000023,-0.000003,1.000000;;, + 2160;16;0.563376,0.483771,-0.669756,0.000000,-0.069973,0.835672,0.544754,0.000000,0.823232,-0.260037,0.504648,0.000000,31.000200,-0.000022,-0.000008,1.000000;;, + 2240;16;0.543670,0.522500,-0.656823,0.000000,-0.072204,0.808801,0.583633,0.000000,0.836188,-0.269879,0.477447,0.000000,31.000198,-0.000025,0.000000,1.000000;;, + 2320;16;0.521856,0.563842,-0.640116,0.000000,-0.073318,0.777270,0.624881,0.000000,0.849877,-0.279166,0.446963,0.000000,31.000193,-0.000015,0.000014,1.000000;;, + 2400;16;0.499484,0.605335,-0.619746,0.000000,-0.072819,0.742180,0.666233,0.000000,0.863257,-0.287644,0.414787,0.000000,31.000189,0.000003,0.000012,1.000000;;, + 2480;16;0.478320,0.644525,-0.596487,0.000000,-0.071235,0.705465,0.705156,0.000000,0.875291,-0.294800,0.383350,0.000000,31.000181,0.000003,0.000021,1.000000;;, + 2560;16;0.459026,0.679997,-0.571751,0.000000,-0.069582,0.669098,0.739910,0.000000,0.885694,-0.299854,0.354448,0.000000,31.000212,0.000034,-0.000040,1.000000;;, + 2640;16;0.442866,0.709881,-0.547666,0.000000,-0.069152,0.636059,0.768536,0.000000,0.893917,-0.302486,0.330778,0.000000,31.000189,-0.000007,0.000017,1.000000;;, + 2720;16;0.428936,0.734383,-0.526020,0.000000,-0.069562,0.607432,0.791320,0.000000,0.900653,-0.302835,0.311634,0.000000,31.000189,0.000005,0.000005,1.000000;;, + 2800;16;0.416887,0.752856,-0.509327,0.000000,-0.071094,0.585631,0.807454,0.000000,0.906174,-0.300407,0.297666,0.000000,31.000204,-0.000028,-0.000015,1.000000;;, + 2880;16;0.406468,0.766636,-0.497045,0.000000,-0.072570,0.569383,0.818863,0.000000,0.910778,-0.296771,0.287071,0.000000,31.000191,-0.000002,-0.000002,1.000000;;, + 2960;16;0.396778,0.776797,-0.489034,0.000000,-0.073182,0.557841,0.826715,0.000000,0.914993,-0.292234,0.278186,0.000000,31.000198,-0.000004,-0.000009,1.000000;;, + 3040;16;0.389879,0.782941,-0.484766,0.000000,-0.072425,0.550864,0.831447,0.000000,0.918013,-0.289055,0.271475,0.000000,31.000196,0.000005,-0.000003,1.000000;;, + 3120;16;0.386919,0.785140,-0.483579,0.000000,-0.070232,0.547994,0.833529,0.000000,0.919435,-0.288546,0.267171,0.000000,31.000185,-0.000009,0.000011,1.000000;;, + 3200;16;0.389946,0.782789,-0.484958,0.000000,-0.064925,0.548710,0.833488,0.000000,0.918546,-0.293529,0.264790,0.000000,31.000206,-0.000013,-0.000020,1.000000;;, + 3280;16;0.402191,0.774994,-0.487470,0.000000,-0.054233,0.551662,0.832302,0.000000,0.913948,-0.308307,0.263904,0.000000,31.000189,0.000005,0.000007,1.000000;;, + 3360;16;0.420928,0.761746,-0.492507,0.000000,-0.039832,0.557948,0.828919,0.000000,0.906219,-0.329298,0.265198,0.000000,31.000189,0.000015,-0.000002,1.000000;;, + 3440;16;0.445819,0.742217,-0.500359,0.000000,-0.021552,0.567721,0.822939,0.000000,0.894864,-0.356098,0.269097,0.000000,31.000196,0.000023,-0.000005,1.000000;;, + 3520;16;0.472632,0.717311,-0.511941,0.000000,-0.002587,0.582046,0.813152,0.000000,0.881256,-0.382997,0.276949,0.000000,31.000185,-0.000018,0.000017,1.000000;;, + 3600;16;0.496984,0.688296,-0.528447,0.000000,0.014031,0.602525,0.797977,0.000000,0.867647,-0.403996,0.289788,0.000000,31.000195,-0.000006,-0.000004,1.000000;;, + 3680;16;0.520074,0.654703,-0.548532,0.000000,0.028011,0.628799,0.777063,0.000000,0.853662,-0.419495,0.308683,0.000000,31.000191,-0.000003,0.000003,1.000000;;, + 3760;16;0.541262,0.616501,-0.571806,0.000000,0.037364,0.661724,0.748816,0.000000,0.840023,-0.426671,0.335131,0.000000,31.000200,0.000007,-0.000021,1.000000;;, + 3840;16;0.562143,0.573838,-0.595571,0.000000,0.044106,0.698299,0.714447,0.000000,0.825863,-0.427889,0.367234,0.000000,31.000187,0.000019,-0.000002,1.000000;;, + 3920;16;0.584661,0.526231,-0.617456,0.000000,0.049698,0.736430,0.674686,0.000000,0.809754,-0.425150,0.404409,0.000000,31.000195,-0.000013,-0.000008,1.000000;;, + 4000;16;0.606639,0.476141,-0.636615,0.000000,0.054257,0.774131,0.630696,0.000000,0.793123,-0.417146,0.443784,0.000000,31.000189,0.000008,0.000006,1.000000;;, + 4080;16;0.627035,0.425517,-0.652505,0.000000,0.058091,0.809754,0.583887,0.000000,0.776822,-0.404022,0.483025,0.000000,31.000181,0.000033,0.000008,1.000000;;, + 4160;16;0.644915,0.376375,-0.665152,0.000000,0.061391,0.842003,0.535968,0.000000,0.761785,-0.386488,0.519914,0.000000,31.000193,-0.000002,-0.000007,1.000000;;, + 4240;16;0.659629,0.330881,-0.674838,0.000000,0.064313,0.869738,0.489306,0.000000,0.748834,-0.366161,0.552425,0.000000,31.000200,-0.000042,0.000002,1.000000;;, + 4320;16;0.669552,0.290112,-0.683765,0.000000,0.066772,0.893331,0.444411,0.000000,0.739758,-0.343213,0.578760,0.000000,31.000198,-0.000003,-0.000010,1.000000;;, + 4400;16;0.672038,0.256090,-0.694826,0.000000,0.068657,0.912709,0.402799,0.000000,0.737327,-0.318401,0.595793,0.000000,31.000187,0.000020,-0.000002,1.000000;;, + 4480;16;0.669411,0.226177,-0.707625,0.000000,0.069649,0.929224,0.362894,0.000000,0.739620,-0.292210,0.606279,0.000000,31.000185,0.000020,0.000001,1.000000;;, + 4560;16;0.661728,0.199092,-0.722826,0.000000,0.069524,0.943650,0.323562,0.000000,0.746513,-0.264363,0.610598,0.000000,31.000185,-0.000004,0.000019,1.000000;;, + 4640;16;0.652519,0.172744,-0.737820,0.000000,0.068460,0.956250,0.284429,0.000000,0.754673,-0.236107,0.612145,0.000000,31.000183,0.000022,0.000005,1.000000;;, + 4720;16;0.645864,0.145154,-0.749526,0.000000,0.067051,0.967181,0.245083,0.000000,0.760502,-0.208547,0.614935,0.000000,31.000189,0.000000,0.000008,1.000000;;, + 4800;16;0.640423,0.117307,-0.759011,0.000000,0.064965,0.976451,0.205728,0.000000,0.765270,-0.181062,0.617720,0.000000,31.000208,-0.000032,-0.000004,1.000000;;, + 4960;16;0.664909,0.057512,-0.744707,0.000000,0.080413,0.985725,0.147922,0.000000,0.742583,-0.158239,0.650792,0.000000,31.000193,-0.000001,0.000006,1.000000;;; + } + { Bip01_L_UpperArm } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.427260,-0.904129,0.000000,0.000000,0.904129,0.427260,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,-0.000002,0.000005,1.000000;;, + 80;16;0.388523,-0.921439,0.000000,0.000000,0.921439,0.388523,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202538,0.000007,-0.000007,1.000000;;, + 160;16;0.349087,-0.937091,0.000000,0.000000,0.937091,0.349087,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202530,0.000009,-0.000001,1.000000;;, + 240;16;0.307986,-0.951391,0.000000,0.000000,0.951391,0.307986,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202522,-0.000001,-0.000005,1.000000;;, + 320;16;0.268401,-0.963307,-0.000000,0.000000,0.963307,0.268401,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202538,0.000000,-0.000014,1.000000;;, + 400;16;0.234165,-0.972197,0.000000,0.000000,0.972197,0.234165,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202530,-0.000005,-0.000011,1.000000;;, + 480;16;0.202875,-0.979205,0.000000,0.000000,0.979205,0.202875,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202507,-0.000004,0.000001,1.000000;;, + 560;16;0.172560,-0.984999,0.000000,0.000000,0.984999,0.172560,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,-0.000012,-0.000000,1.000000;;, + 640;16;0.145352,-0.989380,0.000000,0.000000,0.989380,0.145352,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202522,-0.000008,-0.000007,1.000000;;, + 720;16;0.120234,-0.992746,0.000000,0.000000,0.992746,0.120234,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,-0.000005,-0.000001,1.000000;;, + 800;16;0.104677,-0.994506,0.000000,0.000000,0.994506,0.104677,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,-0.000008,0.000005,1.000000;;, + 880;16;0.106122,-0.994353,-0.000000,0.000000,0.994353,0.106122,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202522,0.000001,-0.000005,1.000000;;, + 960;16;0.123628,-0.992329,-0.000000,0.000000,0.992329,0.123628,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202530,-0.000003,0.000001,1.000000;;, + 1040;16;0.160645,-0.987012,-0.000000,0.000000,0.987012,0.160645,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202522,-0.000006,0.000009,1.000000;;, + 1120;16;0.210713,-0.977548,0.000000,0.000000,0.977548,0.210713,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202530,-0.000003,0.000005,1.000000;;, + 1200;16;0.268857,-0.963180,0.000000,0.000000,0.963180,0.268857,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202545,0.000005,0.000001,1.000000;;, + 1280;16;0.333371,-0.942796,0.000000,0.000000,0.942796,0.333371,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202522,0.000000,0.000003,1.000000;;, + 1360;16;0.401621,-0.915806,0.000000,0.000000,0.915806,0.401621,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202507,0.000003,-0.000005,1.000000;;, + 1440;16;0.470980,-0.882144,0.000000,0.000000,0.882144,0.470980,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202522,-0.000001,-0.000012,1.000000;;, + 1520;16;0.536024,-0.844203,0.000000,0.000000,0.844203,0.536024,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202515,-0.000002,-0.000000,1.000000;;, + 1600;16;0.603285,-0.797526,-0.000000,0.000000,0.797526,0.603285,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202530,-0.000008,-0.000010,1.000000;;, + 1680;16;0.677938,-0.735119,0.000000,0.000000,0.735119,0.677938,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202507,0.000019,-0.000015,1.000000;;, + 1760;16;0.751756,-0.659441,-0.000000,0.000000,0.659441,0.751756,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202530,0.000016,-0.000010,1.000000;;, + 1840;16;0.823370,-0.567505,-0.000000,0.000000,0.567505,0.823370,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,0.000029,-0.000014,1.000000;;, + 1920;16;0.879760,-0.475418,-0.000000,0.000000,0.475418,0.879760,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202530,0.000017,-0.000011,1.000000;;, + 2000;16;0.915394,-0.402559,0.000000,0.000000,0.402559,0.915394,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202507,0.000007,-0.000005,1.000000;;, + 2080;16;0.935580,-0.353115,0.000000,0.000000,0.353115,0.935580,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202530,0.000026,-0.000015,1.000000;;, + 2160;16;0.940380,-0.340125,-0.000000,0.000000,0.340125,0.940380,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202553,0.000032,-0.000015,1.000000;;, + 2240;16;0.936602,-0.350395,0.000000,0.000000,0.350395,0.936602,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202538,0.000019,-0.000012,1.000000;;, + 2320;16;0.926964,-0.375151,0.000000,0.000000,0.375151,0.926964,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202522,0.000033,-0.000012,1.000000;;, + 2400;16;0.912356,-0.409397,0.000000,0.000000,0.409397,0.912356,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202545,0.000023,-0.000015,1.000000;;, + 2480;16;0.894412,-0.447245,-0.000000,0.000000,0.447245,0.894412,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202538,0.000017,-0.000011,1.000000;;, + 2560;16;0.875553,-0.483123,-0.000000,0.000000,0.483123,0.875553,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202499,0.000028,-0.000006,1.000000;;, + 2640;16;0.859841,-0.510562,0.000000,0.000000,0.510562,0.859841,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,0.000021,-0.000002,1.000000;;, + 2720;16;0.848746,-0.528800,0.000000,0.000000,0.528800,0.848746,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202507,0.000019,-0.000005,1.000000;;, + 2800;16;0.846138,-0.532964,-0.000000,0.000000,0.532964,0.846138,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202538,0.000033,-0.000008,1.000000;;, + 2880;16;0.848612,-0.529015,-0.000000,0.000000,0.529015,0.848612,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202515,0.000039,-0.000009,1.000000;;, + 2960;16;0.854227,-0.519900,0.000000,0.000000,0.519900,0.854227,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202507,0.000020,-0.000006,1.000000;;, + 3040;16;0.860870,-0.508824,0.000000,0.000000,0.508824,0.860870,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202530,0.000027,-0.000011,1.000000;;, + 3120;16;0.866011,-0.500024,0.000000,0.000000,0.500024,0.866011,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202538,0.000019,-0.000009,1.000000;;, + 3200;16;0.869604,-0.493750,0.000000,0.000000,0.493751,0.869603,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202522,0.000016,-0.000008,1.000000;;, + 3280;16;0.870315,-0.492495,0.000000,0.000000,0.492495,0.870315,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202553,0.000015,-0.000006,1.000000;;, + 3360;16;0.869566,-0.493816,0.000000,0.000000,0.493816,0.869566,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202538,-0.000001,-0.000005,1.000000;;, + 3440;16;0.868279,-0.496077,0.000000,0.000000,0.496076,0.868279,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202530,0.000022,-0.000017,1.000000;;, + 3520;16;0.866450,-0.499264,0.000000,0.000000,0.499264,0.866450,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202545,0.000032,-0.000020,1.000000;;, + 3600;16;0.864007,-0.503480,0.000000,0.000000,0.503480,0.864007,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202522,0.000022,-0.000017,1.000000;;, + 3680;16;0.862093,-0.506750,-0.000000,0.000000,0.506750,0.862093,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202545,0.000024,-0.000015,1.000000;;, + 3760;16;0.862146,-0.506659,-0.000000,0.000000,0.506659,0.862146,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202538,0.000027,-0.000014,1.000000;;, + 3840;16;0.863305,-0.504683,0.000000,0.000000,0.504683,0.863304,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202530,0.000016,-0.000012,1.000000;;, + 3920;16;0.865849,-0.500306,0.000000,0.000000,0.500306,0.865849,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,0.000034,-0.000013,1.000000;;, + 4000;16;0.867722,-0.497049,-0.000000,0.000000,0.497049,0.867722,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202538,0.000038,-0.000021,1.000000;;, + 4080;16;0.867493,-0.497450,-0.000000,0.000000,0.497450,0.867493,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202522,-0.000010,0.000002,1.000000;;, + 4160;16;0.863690,-0.504024,0.000000,0.000000,0.504024,0.863690,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202538,0.000012,-0.000008,1.000000;;, + 4240;16;0.855068,-0.518517,-0.000000,0.000000,0.518517,0.855067,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,0.000002,0.000004,1.000000;;, + 4320;16;0.838383,-0.545081,-0.000000,0.000000,0.545081,0.838383,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202515,0.000005,0.000005,1.000000;;, + 4400;16;0.807911,-0.589304,-0.000000,0.000000,0.589304,0.807911,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202545,-0.000025,0.000009,1.000000;;, + 4480;16;0.764459,-0.644672,-0.000000,0.000000,0.644672,0.764459,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202545,0.000013,-0.000012,1.000000;;, + 4560;16;0.705366,-0.708843,0.000000,0.000000,0.708843,0.705366,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,-0.000013,0.000003,1.000000;;, + 4640;16;0.635360,-0.772216,0.000000,0.000000,0.772216,0.635360,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202515,0.000007,0.000003,1.000000;;, + 4720;16;0.562668,-0.826683,0.000000,0.000000,0.826683,0.562668,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,-0.000007,0.000003,1.000000;;, + 4800;16;0.485335,-0.874328,-0.000000,0.000000,0.874328,0.485335,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202522,-0.000023,0.000014,1.000000;;, + 4960;16;0.427260,-0.904129,0.000000,0.000000,0.904129,0.427260,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,-0.000002,0.000005,1.000000;;; + } + { Bip01_L_Forearm } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.999573,-0.023764,-0.016974,0.000000,-0.017488,-0.021598,-0.999614,0.000000,0.023388,0.999484,-0.022005,0.000000,61.671474,0.000008,-0.000005,1.000000;;, + 80;16;0.999618,-0.021237,-0.017707,0.000000,-0.018209,-0.023697,-0.999553,0.000000,0.020808,0.999494,-0.024075,0.000000,61.671478,-0.000011,0.000011,1.000000;;, + 160;16;0.999655,-0.018710,-0.018445,0.000000,-0.018925,-0.025798,-0.999488,0.000000,0.018225,0.999492,-0.026143,0.000000,61.671490,-0.000017,0.000006,1.000000;;, + 240;16;0.999685,-0.016109,-0.019257,0.000000,-0.019703,-0.028003,-0.999414,0.000000,0.015560,0.999478,-0.028312,0.000000,61.671482,0.000006,-0.000002,1.000000;;, + 320;16;0.999708,-0.013662,-0.019937,0.000000,-0.020340,-0.030005,-0.999343,0.000000,0.013055,0.999456,-0.030274,0.000000,61.671474,0.000001,0.000008,1.000000;;, + 400;16;0.999726,-0.011611,-0.020306,0.000000,-0.020664,-0.031527,-0.999289,0.000000,0.010963,0.999435,-0.031758,0.000000,61.671471,-0.000014,0.000015,1.000000;;, + 480;16;0.999745,-0.009844,-0.020335,0.000000,-0.020646,-0.032575,-0.999256,0.000000,0.009175,0.999421,-0.032770,0.000000,61.671478,0.000013,-0.000008,1.000000;;, + 560;16;0.999767,-0.008317,-0.019892,0.000000,-0.020157,-0.033022,-0.999251,0.000000,0.007654,0.999420,-0.033182,0.000000,61.671467,-0.000009,0.000005,1.000000;;, + 640;16;0.999792,-0.007073,-0.019106,0.000000,-0.019329,-0.032993,-0.999269,0.000000,0.006438,0.999431,-0.033122,0.000000,61.671474,0.000008,-0.000005,1.000000;;, + 720;16;0.999819,-0.006037,-0.018044,0.000000,-0.018232,-0.032591,-0.999303,0.000000,0.005445,0.999451,-0.032695,0.000000,61.671482,0.000002,0.000002,1.000000;;, + 800;16;0.999844,-0.005529,-0.016759,0.000000,-0.016927,-0.031764,-0.999352,0.000000,0.004993,0.999480,-0.031852,0.000000,61.671478,0.000022,-0.000012,1.000000;;, + 880;16;0.999865,-0.005827,-0.015342,0.000000,-0.015513,-0.030516,-0.999414,0.000000,0.005356,0.999517,-0.030602,0.000000,61.671474,-0.000009,0.000006,1.000000;;, + 960;16;0.999881,-0.006978,-0.013745,0.000000,-0.013940,-0.028786,-0.999488,0.000000,0.006579,0.999561,-0.028880,0.000000,61.671440,0.000002,-0.000012,1.000000;;, + 1040;16;0.999886,-0.009231,-0.011941,0.000000,-0.012182,-0.026468,-0.999575,0.000000,0.008911,0.999607,-0.026578,0.000000,61.671455,0.000011,-0.000019,1.000000;;, + 1120;16;0.999875,-0.012249,-0.009967,0.000000,-0.010255,-0.023710,-0.999666,0.000000,0.012009,0.999644,-0.023833,0.000000,61.671463,0.000013,-0.000017,1.000000;;, + 1200;16;0.999844,-0.015858,-0.007800,0.000000,-0.008125,-0.020548,-0.999756,0.000000,0.015694,0.999663,-0.020674,0.000000,61.671467,-0.000010,-0.000003,1.000000;;, + 1280;16;0.999788,-0.019821,-0.005588,0.000000,-0.005930,-0.017209,-0.999834,0.000000,0.019722,0.999655,-0.017323,0.000000,61.671455,-0.000011,0.000003,1.000000;;, + 1360;16;0.999708,-0.023916,-0.003435,0.000000,-0.003768,-0.013871,-0.999897,0.000000,0.023866,0.999618,-0.013957,0.000000,61.671463,-0.000001,0.000006,1.000000;;, + 1440;16;0.999609,-0.027921,-0.001439,0.000000,-0.001739,-0.010711,-0.999941,0.000000,0.027904,0.999553,-0.010756,0.000000,61.671452,0.000016,-0.000007,1.000000;;, + 1520;16;0.999503,-0.031527,0.000322,0.000000,0.000073,-0.007923,-0.999969,0.000000,0.031529,0.999471,-0.007917,0.000000,61.671452,0.000007,-0.000004,1.000000;;, + 1600;16;0.999395,-0.034756,0.001694,0.000000,0.001499,-0.005621,-0.999983,0.000000,0.034765,0.999380,-0.005565,0.000000,61.671459,0.000020,-0.000004,1.000000;;, + 1680;16;0.999294,-0.037481,0.002418,0.000000,0.002268,-0.004058,-0.999989,0.000000,0.037491,0.999289,-0.003970,0.000000,61.671463,0.000009,0.000003,1.000000;;, + 1760;16;0.999203,-0.039831,0.002724,0.000000,0.002606,-0.003006,-0.999992,0.000000,0.039839,0.999202,-0.002899,0.000000,61.671497,0.000015,-0.000007,1.000000;;, + 1840;16;0.999117,-0.041923,0.002635,0.000000,0.002537,-0.002396,-0.999994,0.000000,0.041929,0.999118,-0.002288,0.000000,61.671513,0.000010,0.000000,1.000000;;, + 1920;16;0.999043,-0.043674,0.002502,0.000000,0.002417,-0.002001,-0.999995,0.000000,0.043679,0.999044,-0.001893,0.000000,61.671482,0.000012,0.000002,1.000000;;, + 2000;16;0.998982,-0.045038,0.002676,0.000000,0.002608,-0.001574,-0.999995,0.000000,0.045042,0.998984,-0.001455,0.000000,61.671486,0.000014,-0.000004,1.000000;;, + 2080;16;0.998935,-0.046025,0.003169,0.000000,0.003122,-0.001107,-0.999995,0.000000,0.046028,0.998940,-0.000962,0.000000,61.671474,-0.000015,0.000004,1.000000;;, + 2160;16;0.998905,-0.046596,0.004187,0.000000,0.004170,-0.000469,-0.999991,0.000000,0.046597,0.998914,-0.000274,0.000000,61.671474,-0.000006,0.000004,1.000000;;, + 2240;16;0.998887,-0.046849,0.005496,0.000000,0.005513,0.000217,-0.999985,0.000000,0.046847,0.998902,0.000476,0.000000,61.671474,0.000005,-0.000002,1.000000;;, + 2320;16;0.998878,-0.046845,0.006944,0.000000,0.006992,0.000864,-0.999975,0.000000,0.046838,0.998902,0.001191,0.000000,61.671505,-0.000005,0.000003,1.000000;;, + 2400;16;0.998875,-0.046655,0.008496,0.000000,0.008575,0.001494,-0.999962,0.000000,0.046640,0.998910,0.001893,0.000000,61.671490,-0.000015,0.000006,1.000000;;, + 2480;16;0.998874,-0.046347,0.010088,0.000000,0.010197,0.002102,-0.999946,0.000000,0.046324,0.998923,0.002572,0.000000,61.671482,0.000009,-0.000002,1.000000;;, + 2560;16;0.998874,-0.045992,0.011658,0.000000,0.011794,0.002682,-0.999927,0.000000,0.045958,0.998938,0.003221,0.000000,61.671490,0.000016,-0.000006,1.000000;;, + 2640;16;0.998869,-0.045702,0.013111,0.000000,0.013273,0.003228,-0.999907,0.000000,0.045656,0.998950,0.003831,0.000000,61.671482,-0.000001,-0.000003,1.000000;;, + 2720;16;0.998863,-0.045412,0.014473,0.000000,0.014658,0.003735,-0.999886,0.000000,0.045353,0.998961,0.004396,0.000000,61.671482,0.000007,-0.000003,1.000000;;, + 2800;16;0.998859,-0.045096,0.015734,0.000000,0.015939,0.004194,-0.999864,0.000000,0.045024,0.998974,0.004908,0.000000,61.671486,-0.000004,-0.000001,1.000000;;, + 2880;16;0.998855,-0.044747,0.016908,0.000000,0.017131,0.004603,-0.999843,0.000000,0.044662,0.998988,0.005364,0.000000,61.671505,-0.000025,0.000007,1.000000;;, + 2960;16;0.998855,-0.044304,0.018029,0.000000,0.018266,0.004958,-0.999821,0.000000,0.044207,0.999006,0.005761,0.000000,61.671490,0.000004,0.000001,1.000000;;, + 3040;16;0.998855,-0.043896,0.019027,0.000000,0.019276,0.005258,-0.999800,0.000000,0.043788,0.999022,0.006098,0.000000,61.671463,-0.000010,0.000007,1.000000;;, + 3120;16;0.998852,-0.043610,0.019806,0.000000,0.020064,0.005482,-0.999784,0.000000,0.043492,0.999034,0.006350,0.000000,61.671452,-0.000006,-0.000001,1.000000;;, + 3200;16;0.998843,-0.043512,0.020470,0.000000,0.020737,0.005683,-0.999769,0.000000,0.043386,0.999037,0.006579,0.000000,61.671486,0.000021,-0.000006,1.000000;;, + 3280;16;0.998819,-0.043751,0.021126,0.000000,0.021406,0.005931,-0.999753,0.000000,0.043615,0.999025,0.006861,0.000000,61.671448,-0.000005,0.000003,1.000000;;, + 3360;16;0.998789,-0.044179,0.021667,0.000000,0.021960,0.006157,-0.999740,0.000000,0.044034,0.999005,0.007119,0.000000,61.671432,0.000015,-0.000005,1.000000;;, + 3440;16;0.998753,-0.044756,0.022114,0.000000,0.022421,0.006360,-0.999728,0.000000,0.044603,0.998978,0.007355,0.000000,61.671459,-0.000006,0.000007,1.000000;;, + 3520;16;0.998727,-0.045310,0.022186,0.000000,0.022499,0.006399,-0.999726,0.000000,0.045156,0.998952,0.007410,0.000000,61.671459,-0.000027,0.000011,1.000000;;, + 3600;16;0.998724,-0.045639,0.021621,0.000000,0.021923,0.006126,-0.999741,0.000000,0.045494,0.998939,0.007118,0.000000,61.671440,-0.000006,0.000003,1.000000;;, + 3680;16;0.998743,-0.045803,0.020381,0.000000,0.020657,0.005559,-0.999771,0.000000,0.045680,0.998935,0.006498,0.000000,61.671474,-0.000009,0.000002,1.000000;;, + 3760;16;0.998785,-0.045772,0.018247,0.000000,0.018478,0.004627,-0.999819,0.000000,0.045679,0.998941,0.005467,0.000000,61.671463,-0.000003,-0.000004,1.000000;;, + 3840;16;0.998838,-0.045632,0.015506,0.000000,0.015680,0.003447,-0.999871,0.000000,0.045572,0.998952,0.004158,0.000000,61.671455,0.000009,-0.000002,1.000000;;, + 3920;16;0.998889,-0.045491,0.012314,0.000000,0.012423,0.002109,-0.999921,0.000000,0.045461,0.998963,0.002671,0.000000,61.671463,-0.000002,0.000000,1.000000;;, + 4000;16;0.998936,-0.045249,0.008852,0.000000,0.008890,0.000629,-0.999960,0.000000,0.045242,0.998976,0.001031,0.000000,61.671463,-0.000013,0.000009,1.000000;;, + 4080;16;0.998979,-0.044860,0.005298,0.000000,0.005260,-0.000958,-0.999986,0.000000,0.044864,0.998993,-0.000721,0.000000,61.671482,0.000021,-0.000016,1.000000;;, + 4160;16;0.999018,-0.044272,0.001824,0.000000,0.001710,-0.002616,-0.999995,0.000000,0.044277,0.999016,-0.002538,0.000000,61.671467,-0.000028,0.000018,1.000000;;, + 4240;16;0.999054,-0.043471,-0.001353,0.000000,-0.001541,-0.004284,-0.999990,0.000000,0.043465,0.999046,-0.004347,0.000000,61.671459,0.000024,-0.000003,1.000000;;, + 4320;16;0.999096,-0.042305,-0.004176,0.000000,-0.004434,-0.006014,-0.999972,0.000000,0.042278,0.999087,-0.006196,0.000000,61.671509,-0.000014,0.000009,1.000000;;, + 4400;16;0.999156,-0.040575,-0.006446,0.000000,-0.006770,-0.007837,-0.999946,0.000000,0.040522,0.999146,-0.008105,0.000000,61.671440,0.000019,-0.000019,1.000000;;, + 4480;16;0.999227,-0.038410,-0.008369,0.000000,-0.008750,-0.009759,-0.999914,0.000000,0.038325,0.999214,-0.010087,0.000000,61.671467,-0.000005,0.000003,1.000000;;, + 4560;16;0.999309,-0.035783,-0.010036,0.000000,-0.010465,-0.011824,-0.999875,0.000000,0.035660,0.999290,-0.012191,0.000000,61.671474,0.000002,-0.000002,1.000000;;, + 4640;16;0.999389,-0.032964,-0.011585,0.000000,-0.012050,-0.013947,-0.999830,0.000000,0.032797,0.999359,-0.014336,0.000000,61.671474,-0.000013,0.000012,1.000000;;, + 4720;16;0.999455,-0.030246,-0.013202,0.000000,-0.013692,-0.016048,-0.999777,0.000000,0.030027,0.999414,-0.016454,0.000000,61.671448,0.000005,-0.000013,1.000000;;, + 4800;16;0.999511,-0.027531,-0.014824,0.000000,-0.015327,-0.018154,-0.999718,0.000000,0.027254,0.999456,-0.018567,0.000000,61.671467,0.000001,-0.000001,1.000000;;, + 4960;16;0.999573,-0.023764,-0.016974,0.000000,-0.017488,-0.021598,-0.999614,0.000000,0.023388,0.999484,-0.022005,0.000000,61.671474,0.000008,-0.000005,1.000000;;; + } + { Bip01_L_Hand } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410508,3.054968,-10.755419,1.000000;;, + 80;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410498,3.054974,-10.755421,1.000000;;, + 160;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410497,3.054968,-10.755431,1.000000;;, + 240;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410508,3.054964,-10.755431,1.000000;;, + 320;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410500,3.054960,-10.755434,1.000000;;, + 400;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410508,3.054971,-10.755414,1.000000;;, + 480;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410508,3.054960,-10.755432,1.000000;;, + 560;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410506,3.054965,-10.755426,1.000000;;, + 640;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410497,3.054977,-10.755417,1.000000;;, + 720;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410471,3.054978,-10.755437,1.000000;;, + 800;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410487,3.054967,-10.755437,1.000000;;, + 880;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410501,3.054976,-10.755417,1.000000;;, + 960;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410521,3.054957,-10.755430,1.000000;;, + 1040;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410499,3.054966,-10.755423,1.000000;;, + 1120;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410509,3.054960,-10.755429,1.000000;;, + 1200;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410503,3.054964,-10.755425,1.000000;;, + 1280;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410506,3.054965,-10.755434,1.000000;;, + 1360;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410516,3.054975,-10.755422,1.000000;;, + 1440;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410494,3.054971,-10.755426,1.000000;;, + 1520;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410505,3.054976,-10.755416,1.000000;;, + 1600;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410496,3.054975,-10.755421,1.000000;;, + 1680;16;0.713248,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410503,3.054969,-10.755434,1.000000;;, + 1760;16;0.713248,-0.002867,-0.700907,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410509,3.054973,-10.755425,1.000000;;, + 1840;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410497,3.054973,-10.755424,1.000000;;, + 1920;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410506,3.054967,-10.755421,1.000000;;, + 2000;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410499,3.054975,-10.755417,1.000000;;, + 2080;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410491,3.054975,-10.755412,1.000000;;, + 2160;16;0.713247,-0.002867,-0.700907,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410501,3.054973,-10.755416,1.000000;;, + 2240;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410501,3.054976,-10.755409,1.000000;;, + 2320;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410510,3.054970,-10.755433,1.000000;;, + 2400;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410506,3.054970,-10.755426,1.000000;;, + 2480;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410507,3.054971,-10.755430,1.000000;;, + 2560;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410508,3.054976,-10.755413,1.000000;;, + 2640;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410507,3.054967,-10.755429,1.000000;;, + 2720;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410498,3.054969,-10.755423,1.000000;;, + 2800;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410500,3.054970,-10.755417,1.000000;;, + 2880;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410507,3.054965,-10.755431,1.000000;;, + 2960;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410504,3.054980,-10.755417,1.000000;;, + 3040;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410500,3.054974,-10.755425,1.000000;;, + 3120;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410500,3.054966,-10.755434,1.000000;;, + 3200;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410495,3.054964,-10.755433,1.000000;;, + 3280;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410502,3.054964,-10.755434,1.000000;;, + 3360;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410505,3.054978,-10.755419,1.000000;;, + 3440;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410506,3.054974,-10.755412,1.000000;;, + 3520;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410496,3.054967,-10.755432,1.000000;;, + 3600;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410502,3.054972,-10.755426,1.000000;;, + 3680;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410500,3.054976,-10.755416,1.000000;;, + 3760;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410504,3.054980,-10.755415,1.000000;;, + 3840;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410511,3.054967,-10.755432,1.000000;;, + 3920;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410498,3.054977,-10.755418,1.000000;;, + 4000;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410497,3.054971,-10.755430,1.000000;;, + 4080;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410501,3.054986,-10.755408,1.000000;;, + 4160;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410512,3.054956,-10.755445,1.000000;;, + 4240;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410506,3.054977,-10.755414,1.000000;;, + 4320;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410501,3.054983,-10.755426,1.000000;;, + 4400;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410499,3.054965,-10.755426,1.000000;;, + 4480;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410507,3.054966,-10.755425,1.000000;;, + 4560;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410522,3.054971,-10.755424,1.000000;;, + 4640;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410505,3.054967,-10.755433,1.000000;;, + 4720;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410533,3.054963,-10.755422,1.000000;;, + 4800;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410522,3.054963,-10.755418,1.000000;;, + 4960;16;0.713247,-0.002867,-0.700906,0.000000,-0.700353,-0.042855,-0.712509,0.000000,-0.027995,0.999077,-0.032574,0.000000,12.410508,3.054968,-10.755419,1.000000;;; + } + { Bip01_L_Finger0 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075042,-0.000009,0.000013,1.000000;;, + 80;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075057,0.000004,0.000005,1.000000;;, + 160;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075050,-0.000016,0.000012,1.000000;;, + 240;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075056,-0.000019,0.000006,1.000000;;, + 320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075058,-0.000006,0.000002,1.000000;;, + 400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075063,-0.000001,-0.000003,1.000000;;, + 480;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075071,0.000015,-0.000016,1.000000;;, + 560;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075075,0.000002,-0.000006,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075053,0.000015,0.000006,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075067,-0.000004,-0.000010,1.000000;;, + 800;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075047,0.000006,0.000007,1.000000;;, + 880;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075071,0.000010,-0.000015,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075048,0.000030,0.000001,1.000000;;, + 1040;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075065,0.000007,-0.000005,1.000000;;, + 1120;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075040,-0.000001,0.000021,1.000000;;, + 1200;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075075,0.000018,-0.000009,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075082,0.000004,-0.000016,1.000000;;, + 1360;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075045,0.000004,0.000013,1.000000;;, + 1440;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075075,-0.000006,-0.000005,1.000000;;, + 1520;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075055,-0.000013,0.000004,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075053,-0.000007,0.000004,1.000000;;, + 1680;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075068,-0.000000,-0.000004,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075050,0.000011,-0.000002,1.000000;;, + 1840;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075065,-0.000005,0.000013,1.000000;;, + 1920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075034,-0.000003,-0.000003,1.000000;;, + 2000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075072,0.000011,-0.000006,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075059,0.000003,0.000002,1.000000;;, + 2160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075062,-0.000007,0.000004,1.000000;;, + 2240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075060,-0.000000,-0.000001,1.000000;;, + 2320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075060,0.000011,-0.000003,1.000000;;, + 2400;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075072,0.000001,0.000001,1.000000;;, + 2480;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075070,-0.000006,-0.000003,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075075,0.000011,-0.000008,1.000000;;, + 2640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075055,-0.000009,0.000005,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075059,0.000000,-0.000001,1.000000;;, + 2800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075051,-0.000017,0.000008,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075068,0.000004,0.000001,1.000000;;, + 2960;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075055,0.000011,-0.000002,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075054,-0.000001,-0.000001,1.000000;;, + 3120;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075063,0.000012,-0.000007,1.000000;;, + 3200;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075068,0.000006,-0.000006,1.000000;;, + 3280;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075062,-0.000019,0.000008,1.000000;;, + 3360;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075058,-0.000014,0.000005,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075047,-0.000004,0.000006,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075062,0.000001,-0.000004,1.000000;;, + 3600;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075053,0.000004,0.000005,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075042,-0.000006,0.000009,1.000000;;, + 3760;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075075,0.000004,-0.000009,1.000000;;, + 3840;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075061,-0.000009,0.000004,1.000000;;, + 3920;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075051,-0.000001,0.000008,1.000000;;, + 4000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075066,-0.000004,-0.000001,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075035,-0.000012,0.000010,1.000000;;, + 4160;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075076,0.000012,-0.000010,1.000000;;, + 4240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075080,-0.000000,-0.000001,1.000000;;, + 4320;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075083,-0.000006,-0.000003,1.000000;;, + 4400;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075057,-0.000004,-0.000002,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075103,-0.000009,-0.000019,1.000000;;, + 4560;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075098,-0.000006,-0.000016,1.000000;;, + 4640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075061,-0.000013,0.000003,1.000000;;, + 4720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075089,-0.000012,-0.000014,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075084,0.000006,-0.000007,1.000000;;, + 4960;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075042,-0.000009,0.000013,1.000000;;; + } + { Bip01_L_Finger01 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961583,0.000010,-0.000006,1.000000;;, + 80;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961592,0.000005,-0.000016,1.000000;;, + 160;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961579,0.000013,-0.000008,1.000000;;, + 240;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961580,0.000013,-0.000006,1.000000;;, + 320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961563,-0.000004,0.000012,1.000000;;, + 400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961575,0.000008,-0.000006,1.000000;;, + 480;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961571,-0.000003,0.000006,1.000000;;, + 560;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961547,0.000037,0.000017,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961574,0.000004,-0.000008,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961565,0.000021,0.000006,1.000000;;, + 800;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961578,-0.000000,-0.000003,1.000000;;, + 880;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961573,-0.000007,0.000007,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961574,-0.000013,-0.000001,1.000000;;, + 1040;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961557,-0.000014,0.000018,1.000000;;, + 1120;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961590,-0.000004,-0.000009,1.000000;;, + 1200;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961573,-0.000009,0.000002,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961561,0.000001,0.000004,1.000000;;, + 1360;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961581,-0.000005,-0.000008,1.000000;;, + 1440;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961569,0.000008,0.000004,1.000000;;, + 1520;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961579,0.000011,-0.000010,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961600,-0.000001,-0.000014,1.000000;;, + 1680;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961573,-0.000002,0.000006,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961561,-0.000008,0.000007,1.000000;;, + 1840;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961572,0.000001,-0.000005,1.000000;;, + 1920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961586,0.000006,0.000004,1.000000;;, + 2000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961570,-0.000011,0.000019,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961590,0.000008,0.000001,1.000000;;, + 2160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961572,0.000008,0.000004,1.000000;;, + 2240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961582,0.000020,-0.000002,1.000000;;, + 2320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961582,-0.000001,0.000001,1.000000;;, + 2400;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961583,0.000017,-0.000006,1.000000;;, + 2480;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961566,0.000003,0.000003,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961568,-0.000006,-0.000001,1.000000;;, + 2640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961571,0.000001,-0.000004,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961561,-0.000014,0.000009,1.000000;;, + 2800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961579,0.000009,-0.000003,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961574,-0.000007,0.000002,1.000000;;, + 2960;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961576,-0.000004,0.000002,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961565,-0.000002,0.000004,1.000000;;, + 3120;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961581,-0.000019,0.000004,1.000000;;, + 3200;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961570,-0.000012,0.000005,1.000000;;, + 3280;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961571,0.000010,-0.000000,1.000000;;, + 3360;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961576,0.000006,-0.000005,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961583,-0.000005,-0.000003,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961581,0.000019,-0.000012,1.000000;;, + 3600;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961582,-0.000001,-0.000007,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961586,0.000006,-0.000009,1.000000;;, + 3760;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961561,0.000005,0.000009,1.000000;;, + 3840;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961577,0.000002,-0.000007,1.000000;;, + 3920;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961557,-0.000012,0.000012,1.000000;;, + 4000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961568,-0.000011,0.000004,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961595,0.000018,-0.000016,1.000000;;, + 4160;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961530,-0.000013,0.000027,1.000000;;, + 4240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961580,0.000006,-0.000002,1.000000;;, + 4320;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961552,0.000002,0.000005,1.000000;;, + 4400;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961567,0.000004,0.000002,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961559,-0.000005,0.000011,1.000000;;, + 4560;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961559,-0.000019,0.000015,1.000000;;, + 4640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961563,0.000016,0.000006,1.000000;;, + 4720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961565,0.000025,0.000000,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961566,-0.000008,0.000006,1.000000;;, + 4960;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961583,0.000010,-0.000006,1.000000;;; + } + { Bip01_L_Finger02 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961576,0.000009,-0.000003,1.000000;;, + 80;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961568,-0.000009,0.000011,1.000000;;, + 160;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961581,0.000011,-0.000008,1.000000;;, + 240;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961579,0.000013,-0.000003,1.000000;;, + 320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961580,0.000014,-0.000009,1.000000;;, + 400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961574,0.000009,-0.000001,1.000000;;, + 480;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961569,-0.000002,0.000006,1.000000;;, + 560;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961576,-0.000011,-0.000001,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961578,0.000005,-0.000002,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961578,-0.000002,-0.000003,1.000000;;, + 800;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961576,-0.000000,-0.000005,1.000000;;, + 880;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961572,-0.000007,0.000004,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961579,-0.000012,0.000002,1.000000;;, + 1040;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961574,0.000008,0.000002,1.000000;;, + 1120;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961586,-0.000004,-0.000012,1.000000;;, + 1200;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961573,-0.000009,0.000007,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961569,-0.000003,0.000001,1.000000;;, + 1360;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961571,0.000000,0.000001,1.000000;;, + 1440;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961565,0.000009,-0.000000,1.000000;;, + 1520;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961580,0.000012,-0.000009,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961571,0.000002,0.000002,1.000000;;, + 1680;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961573,-0.000002,0.000001,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961590,-0.000005,-0.000004,1.000000;;, + 1840;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961571,-0.000000,0.000000,1.000000;;, + 1920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961586,0.000002,0.000003,1.000000;;, + 2000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961561,-0.000004,-0.000000,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961565,-0.000010,0.000003,1.000000;;, + 2160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961571,0.000005,-0.000002,1.000000;;, + 2240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961568,-0.000010,0.000002,1.000000;;, + 2320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961582,-0.000001,0.000000,1.000000;;, + 2400;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961562,-0.000001,0.000003,1.000000;;, + 2480;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961565,0.000005,0.000001,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961569,0.000001,0.000004,1.000000;;, + 2640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961572,0.000005,-0.000000,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961578,0.000008,-0.000005,1.000000;;, + 2800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961580,0.000013,-0.000000,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961571,-0.000005,0.000003,1.000000;;, + 2960;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961578,-0.000008,0.000000,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961578,-0.000012,0.000004,1.000000;;, + 3120;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961567,-0.000010,0.000005,1.000000;;, + 3200;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961571,-0.000007,0.000005,1.000000;;, + 3280;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961579,0.000017,-0.000002,1.000000;;, + 3360;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961581,0.000006,-0.000003,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961584,0.000001,-0.000004,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961576,-0.000014,0.000005,1.000000;;, + 3600;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961581,0.000002,-0.000007,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961588,0.000002,-0.000007,1.000000;;, + 3760;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961570,-0.000007,0.000005,1.000000;;, + 3840;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961579,0.000004,-0.000002,1.000000;;, + 3920;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961581,0.000002,-0.000001,1.000000;;, + 4000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961569,-0.000010,0.000008,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961600,0.000003,-0.000014,1.000000;;, + 4160;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961583,0.000002,-0.000000,1.000000;;, + 4240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961576,0.000004,-0.000008,1.000000;;, + 4320;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961551,0.000002,0.000005,1.000000;;, + 4400;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961569,0.000004,0.000001,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961553,0.000008,0.000013,1.000000;;, + 4560;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961561,0.000010,0.000003,1.000000;;, + 4640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961563,0.000016,0.000001,1.000000;;, + 4720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961555,0.000000,0.000016,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961566,-0.000008,0.000003,1.000000;;, + 4960;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961576,0.000009,-0.000003,1.000000;;; + } + { Dummy06 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088003,0.354686,-0.505020,1.000000;;, + 80;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088007,0.354687,-0.505029,1.000000;;, + 160;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088003,0.354683,-0.505037,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087999,0.354689,-0.505027,1.000000;;, + 320;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087999,0.354678,-0.505037,1.000000;;, + 400;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088018,0.354682,-0.505016,1.000000;;, + 480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087997,0.354684,-0.505036,1.000000;;, + 560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087997,0.354680,-0.505038,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087982,0.354697,-0.505025,1.000000;;, + 720;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087984,0.354686,-0.505039,1.000000;;, + 800;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087999,0.354695,-0.505016,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087994,0.354693,-0.505023,1.000000;;, + 960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088020,0.354688,-0.505014,1.000000;;, + 1040;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088017,0.354669,-0.505036,1.000000;;, + 1120;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087996,0.354682,-0.505036,1.000000;;, + 1200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087994,0.354682,-0.505039,1.000000;;, + 1280;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087999,0.354684,-0.505032,1.000000;;, + 1360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087997,0.354686,-0.505034,1.000000;;, + 1440;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088001,0.354692,-0.505020,1.000000;;, + 1520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088009,0.354688,-0.505025,1.000000;;, + 1600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088003,0.354678,-0.505034,1.000000;;, + 1680;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087992,0.354686,-0.505022,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087994,0.354689,-0.505026,1.000000;;, + 1840;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088005,0.354687,-0.505022,1.000000;;, + 1920;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087996,0.354682,-0.505020,1.000000;;, + 2000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087999,0.354694,-0.505015,1.000000;;, + 2080;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088005,0.354690,-0.505026,1.000000;;, + 2160;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088007,0.354689,-0.505020,1.000000;;, + 2240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088007,0.354691,-0.505020,1.000000;;, + 2320;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088007,0.354685,-0.505026,1.000000;;, + 2400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088003,0.354688,-0.505016,1.000000;;, + 2480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088007,0.354692,-0.505024,1.000000;;, + 2560;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088001,0.354689,-0.505018,1.000000;;, + 2640;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088001,0.354689,-0.505016,1.000000;;, + 2720;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087994,0.354685,-0.505033,1.000000;;, + 2800;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088005,0.354682,-0.505036,1.000000;;, + 2880;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087996,0.354688,-0.505025,1.000000;;, + 2960;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087997,0.354684,-0.505037,1.000000;;, + 3040;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088001,0.354691,-0.505015,1.000000;;, + 3120;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087999,0.354692,-0.505020,1.000000;;, + 3200;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088005,0.354682,-0.505040,1.000000;;, + 3280;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088001,0.354681,-0.505039,1.000000;;, + 3360;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088001,0.354691,-0.505018,1.000000;;, + 3440;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088003,0.354685,-0.505025,1.000000;;, + 3520;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088007,0.354681,-0.505039,1.000000;;, + 3600;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087997,0.354683,-0.505033,1.000000;;, + 3680;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088005,0.354683,-0.505036,1.000000;;, + 3760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087997,0.354693,-0.505018,1.000000;;, + 3840;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088005,0.354691,-0.505020,1.000000;;, + 3920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088005,0.354683,-0.505038,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087996,0.354698,-0.505015,1.000000;;, + 4080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087996,0.354699,-0.505005,1.000000;;, + 4160;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088001,0.354686,-0.505031,1.000000;;, + 4240;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088005,0.354692,-0.505021,1.000000;;, + 4320;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087988,0.354712,-0.505011,1.000000;;, + 4400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087994,0.354686,-0.505024,1.000000;;, + 4480;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088018,0.354674,-0.505038,1.000000;;, + 4560;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.088011,0.354684,-0.505024,1.000000;;, + 4640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.087997,0.354688,-0.505028,1.000000;;, + 4720;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088015,0.354667,-0.505041,1.000000;;, + 4800;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,0.000000,0.000796,1.000000,0.000000,24.087988,0.354694,-0.505022,1.000000;;, + 4960;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000796,0.000000,-0.000000,0.000796,1.000000,0.000000,24.088003,0.354686,-0.505020,1.000000;;; + } + { Bip01_L_Finger1 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300064,0.000003,0.000006,1.000000;;, + 80;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300063,0.000007,0.000011,1.000000;;, + 160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300055,0.000007,0.000007,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300056,-0.000004,-0.000002,1.000000;;, + 320;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300056,0.000004,0.000004,1.000000;;, + 400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300014,0.000025,0.000014,1.000000;;, + 480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300039,-0.000004,-0.000015,1.000000;;, + 560;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300041,0.000005,0.000004,1.000000;;, + 640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300058,-0.000005,-0.000002,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300057,0.000007,0.000014,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300075,0.000004,0.000018,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300048,-0.000009,-0.000014,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300048,-0.000006,-0.000015,1.000000;;, + 1040;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300055,-0.000009,-0.000013,1.000000;;, + 1120;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300047,-0.000007,-0.000015,1.000000;;, + 1200;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300065,-0.000006,0.000000,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300060,0.000002,0.000007,1.000000;;, + 1360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300070,0.000006,0.000019,1.000000;;, + 1440;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300065,-0.000004,-0.000004,1.000000;;, + 1520;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300047,0.000002,0.000002,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300076,0.000005,-0.000013,1.000000;;, + 1680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300056,0.000000,-0.000000,1.000000;;, + 1760;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300069,0.000001,0.000005,1.000000;;, + 1840;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300046,-0.000004,0.000008,1.000000;;, + 1920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300068,-0.000004,0.000000,1.000000;;, + 2000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300057,0.000006,0.000016,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300053,0.000001,0.000011,1.000000;;, + 2160;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300057,-0.000007,0.000001,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300064,-0.000003,-0.000011,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300056,-0.000001,-0.000002,1.000000;;, + 2400;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300053,-0.000002,-0.000014,1.000000;;, + 2480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300054,0.000002,0.000003,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300058,-0.000009,-0.000011,1.000000;;, + 2640;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300057,-0.000009,-0.000017,1.000000;;, + 2720;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300058,-0.000002,-0.000006,1.000000;;, + 2800;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300055,-0.000003,-0.000003,1.000000;;, + 2880;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300047,0.000005,0.000011,1.000000;;, + 2960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300066,-0.000004,-0.000015,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300047,-0.000005,-0.000022,1.000000;;, + 3120;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300045,-0.000003,-0.000006,1.000000;;, + 3200;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300055,-0.000001,0.000005,1.000000;;, + 3280;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300045,-0.000015,-0.000028,1.000000;;, + 3360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300060,0.000003,0.000007,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300044,-0.000006,-0.000009,1.000000;;, + 3520;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300054,0.000006,0.000008,1.000000;;, + 3600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300052,-0.000004,-0.000001,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300062,-0.000000,0.000005,1.000000;;, + 3760;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300060,0.000009,0.000010,1.000000;;, + 3840;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300045,0.000013,0.000027,1.000000;;, + 3920;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300067,-0.000013,-0.000011,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300056,-0.000005,0.000000,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300039,0.000021,0.000035,1.000000;;, + 4160;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300084,-0.000016,-0.000027,1.000000;;, + 4240;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300084,-0.000017,-0.000021,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300045,0.000006,0.000015,1.000000;;, + 4400;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300069,-0.000006,-0.000006,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300056,0.000011,0.000010,1.000000;;, + 4560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300076,-0.000007,-0.000010,1.000000;;, + 4640;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300057,-0.000006,-0.000009,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300072,-0.000010,-0.000010,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300090,-0.000022,-0.000024,1.000000;;, + 4960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300064,0.000003,0.000006,1.000000;;; + } + { Bip01_L_Finger11 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850065,0.000001,-0.000008,1.000000;;, + 80;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850067,-0.000012,-0.000005,1.000000;;, + 160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850059,-0.000008,-0.000011,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850067,0.000001,0.000003,1.000000;;, + 320;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850051,0.000009,0.000004,1.000000;;, + 400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850072,-0.000023,-0.000038,1.000000;;, + 480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850061,0.000006,0.000004,1.000000;;, + 560;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850071,-0.000013,-0.000012,1.000000;;, + 640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850073,-0.000001,-0.000002,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850061,-0.000004,-0.000007,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850033,-0.000012,-0.000037,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850089,-0.000003,0.000006,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850071,0.000006,0.000006,1.000000;;, + 1040;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850063,0.000002,0.000003,1.000000;;, + 1120;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850079,-0.000002,0.000002,1.000000;;, + 1200;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850054,0.000004,-0.000002,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850033,0.000003,-0.000019,1.000000;;, + 1360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850060,-0.000001,0.000000,1.000000;;, + 1440;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850060,-0.000002,0.000002,1.000000;;, + 1520;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850078,-0.000007,-0.000004,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850050,-0.000006,0.000007,1.000000;;, + 1680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850048,0.000007,0.000000,1.000000;;, + 1760;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850069,0.000001,-0.000017,1.000000;;, + 1840;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850089,0.000007,-0.000004,1.000000;;, + 1920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850056,0.000012,0.000020,1.000000;;, + 2000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850053,-0.000007,-0.000005,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850065,-0.000002,-0.000010,1.000000;;, + 2160;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850060,0.000009,-0.000003,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850053,0.000000,-0.000000,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850065,0.000006,0.000002,1.000000;;, + 2400;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850070,0.000000,0.000011,1.000000;;, + 2480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850060,-0.000006,-0.000010,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850062,0.000004,0.000002,1.000000;;, + 2640;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850082,0.000004,0.000002,1.000000;;, + 2720;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850064,0.000001,-0.000002,1.000000;;, + 2800;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850072,0.000007,0.000007,1.000000;;, + 2880;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850075,-0.000000,-0.000010,1.000000;;, + 2960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850063,0.000002,0.000011,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850078,0.000013,0.000042,1.000000;;, + 3120;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850089,-0.000001,-0.000006,1.000000;;, + 3200;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850073,0.000010,0.000013,1.000000;;, + 3280;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850079,0.000021,0.000042,1.000000;;, + 3360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850069,-0.000005,-0.000008,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850072,0.000013,0.000025,1.000000;;, + 3520;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850064,-0.000001,0.000000,1.000000;;, + 3600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850068,-0.000004,-0.000008,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850067,-0.000010,-0.000026,1.000000;;, + 3760;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850063,-0.000014,-0.000005,1.000000;;, + 3840;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850078,-0.000021,-0.000040,1.000000;;, + 3920;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850061,0.000001,-0.000003,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850081,-0.000003,-0.000007,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850072,-0.000017,-0.000023,1.000000;;, + 4160;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850025,0.000036,0.000062,1.000000;;, + 4240;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850046,0.000018,0.000011,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850097,-0.000030,-0.000042,1.000000;;, + 4400;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850051,0.000014,0.000013,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850077,-0.000010,-0.000012,1.000000;;, + 4560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850067,-0.000007,-0.000006,1.000000;;, + 4640;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850060,0.000006,0.000009,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850066,0.000001,-0.000007,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850065,0.000028,0.000040,1.000000;;, + 4960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850065,0.000001,-0.000008,1.000000;;; + } + { Bip01_L_Finger12 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207764,0.000008,0.000012,1.000000;;, + 80;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207752,0.000001,-0.000009,1.000000;;, + 160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207758,-0.000006,-0.000005,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207754,0.000013,0.000008,1.000000;;, + 320;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207761,-0.000003,-0.000001,1.000000;;, + 400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207761,0.000004,0.000010,1.000000;;, + 480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207757,-0.000003,0.000000,1.000000;;, + 560;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207770,-0.000005,-0.000006,1.000000;;, + 640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207747,0.000006,-0.000002,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207773,0.000003,-0.000002,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207769,0.000006,0.000008,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207754,0.000004,0.000008,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207753,0.000009,0.000010,1.000000;;, + 1040;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207757,0.000009,0.000006,1.000000;;, + 1120;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207743,0.000002,-0.000000,1.000000;;, + 1200;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207767,-0.000013,-0.000008,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207783,0.000011,0.000022,1.000000;;, + 1360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207764,-0.000002,0.000000,1.000000;;, + 1440;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207756,-0.000002,-0.000000,1.000000;;, + 1520;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207762,0.000002,0.000001,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207761,0.000001,-0.000005,1.000000;;, + 1680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207769,-0.000003,0.000000,1.000000;;, + 1760;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207753,0.000002,0.000003,1.000000;;, + 1840;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207752,0.000005,-0.000002,1.000000;;, + 1920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207760,-0.000011,-0.000011,1.000000;;, + 2000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207770,-0.000000,-0.000003,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207766,0.000006,0.000004,1.000000;;, + 2160;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207768,-0.000001,-0.000000,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207764,-0.000002,0.000002,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207757,-0.000010,-0.000012,1.000000;;, + 2400;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207762,0.000002,0.000014,1.000000;;, + 2480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207767,-0.000003,0.000003,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207757,0.000005,0.000015,1.000000;;, + 2640;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207755,0.000002,0.000006,1.000000;;, + 2720;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,11.207770,-0.000002,-0.000001,1.000000;;, + 2800;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207756,-0.000006,-0.000010,1.000000;;, + 2880;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207760,-0.000000,0.000002,1.000000;;, + 2960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207756,0.000005,0.000012,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207765,-0.000007,-0.000011,1.000000;;, + 3120;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207755,0.000004,0.000013,1.000000;;, + 3200;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207761,-0.000004,-0.000010,1.000000;;, + 3280;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207756,-0.000007,-0.000016,1.000000;;, + 3360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207761,-0.000004,-0.000012,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207767,-0.000005,-0.000007,1.000000;;, + 3520;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207764,-0.000003,-0.000005,1.000000;;, + 3600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207770,0.000003,0.000006,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207760,0.000007,0.000009,1.000000;;, + 3760;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207760,0.000005,0.000003,1.000000;;, + 3840;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207765,0.000008,0.000006,1.000000;;, + 3920;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207769,0.000001,-0.000002,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207773,0.000001,-0.000000,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207779,-0.000013,-0.000017,1.000000;;, + 4160;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,11.207768,-0.000015,-0.000020,1.000000;;, + 4240;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207767,-0.000003,-0.000003,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207754,0.000010,0.000015,1.000000;;, + 4400;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207767,-0.000011,-0.000015,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207764,-0.000007,-0.000010,1.000000;;, + 4560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207754,0.000014,0.000006,1.000000;;, + 4640;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207787,-0.000006,-0.000010,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,11.207737,0.000012,0.000015,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207734,-0.000002,-0.000004,1.000000;;, + 4960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,11.207764,0.000008,0.000012,1.000000;;; + } + { Dummy03 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;-0.407607,0.378871,-0.830851,0.000000,-0.503079,-0.852505,-0.141940,0.000000,-0.762081,0.360128,0.538089,0.000000,-12.374953,4.006935,-8.346194,1.000000;;, + 80;16;-0.416514,0.377872,-0.826879,0.000000,-0.503483,-0.853189,-0.136282,0.000000,-0.756981,0.359556,0.545618,0.000000,-12.374949,4.006937,-8.346193,1.000000;;, + 160;16;-0.425366,0.376888,-0.822812,0.000000,-0.503870,-0.853846,-0.130619,0.000000,-0.751784,0.359030,0.553099,0.000000,-12.374967,4.006944,-8.346194,1.000000;;, + 240;16;-0.434586,0.375814,-0.818474,0.000000,-0.504263,-0.854512,-0.124612,0.000000,-0.746227,0.358572,0.560867,0.000000,-12.374971,4.006948,-8.346193,1.000000;;, + 320;16;-0.442896,0.374968,-0.814397,0.000000,-0.504596,-0.855076,-0.119281,0.000000,-0.741098,0.358112,0.567917,0.000000,-12.374956,4.006941,-8.346194,1.000000;;, + 400;16;-0.449149,0.374601,-0.811134,0.000000,-0.504821,-0.855457,-0.115536,0.000000,-0.737171,0.357585,0.573335,0.000000,-12.374967,4.006938,-8.346195,1.000000;;, + 480;16;-0.453500,0.374765,-0.808634,0.000000,-0.504947,-0.855671,-0.113379,0.000000,-0.734415,0.356900,0.577284,0.000000,-12.374941,4.006937,-8.346192,1.000000;;, + 560;16;-0.455431,0.375689,-0.807118,0.000000,-0.504948,-0.855673,-0.113364,0.000000,-0.733219,0.355924,0.579404,0.000000,-12.374949,4.006939,-8.346192,1.000000;;, + 640;16;-0.455793,0.377101,-0.806255,0.000000,-0.504868,-0.855537,-0.114738,0.000000,-0.733049,0.354756,0.580334,0.000000,-12.374961,4.006935,-8.346194,1.000000;;, + 720;16;-0.455233,0.378873,-0.805741,0.000000,-0.504733,-0.855308,-0.117013,0.000000,-0.733490,0.353416,0.580594,0.000000,-12.374965,4.006937,-8.346196,1.000000;;, + 800;16;-0.453797,0.380821,-0.805633,0.000000,-0.504555,-0.855006,-0.119953,0.000000,-0.734501,0.352051,0.580144,0.000000,-12.374959,4.006924,-8.346196,1.000000;;, + 880;16;-0.451680,0.382774,-0.805897,0.000000,-0.504349,-0.854657,-0.123262,0.000000,-0.735947,0.350778,0.579083,0.000000,-12.374973,4.006937,-8.346195,1.000000;;, + 960;16;-0.449073,0.384565,-0.806500,0.000000,-0.504132,-0.854290,-0.126643,0.000000,-0.737688,0.349711,0.577511,0.000000,-12.374933,4.006945,-8.346191,1.000000;;, + 1040;16;-0.446313,0.385962,-0.807365,0.000000,-0.503934,-0.853955,-0.129659,0.000000,-0.739496,0.348991,0.575631,0.000000,-12.374995,4.006943,-8.346198,1.000000;;, + 1120;16;-0.443171,0.386969,-0.808612,0.000000,-0.503748,-0.853639,-0.132431,0.000000,-0.741510,0.348647,0.573244,0.000000,-12.374972,4.006928,-8.346197,1.000000;;, + 1200;16;-0.439593,0.387489,-0.810315,0.000000,-0.503580,-0.853355,-0.134880,0.000000,-0.743751,0.348767,0.570260,0.000000,-12.374940,4.006937,-8.346193,1.000000;;, + 1280;16;-0.435395,0.387588,-0.812532,0.000000,-0.503420,-0.853083,-0.137174,0.000000,-0.746324,0.349320,0.566547,0.000000,-12.374939,4.006934,-8.346193,1.000000;;, + 1360;16;-0.430296,0.387329,-0.815366,0.000000,-0.503253,-0.852800,-0.139529,0.000000,-0.749388,0.350297,0.561881,0.000000,-12.374988,4.006957,-8.346195,1.000000;;, + 1440;16;-0.424518,0.386623,-0.818723,0.000000,-0.503094,-0.852531,-0.141727,0.000000,-0.752782,0.351729,0.556423,0.000000,-12.374943,4.006949,-8.346193,1.000000;;, + 1520;16;-0.418227,0.385487,-0.822488,0.000000,-0.502949,-0.852285,-0.143708,0.000000,-0.756392,0.353567,0.550329,0.000000,-12.374943,4.006932,-8.346193,1.000000;;, + 1600;16;-0.411315,0.383640,-0.826825,0.000000,-0.502837,-0.852095,-0.145222,0.000000,-0.760247,0.356026,0.543388,0.000000,-12.374963,4.006937,-8.346194,1.000000;;, + 1680;16;-0.403712,0.380662,-0.831933,0.000000,-0.502789,-0.852014,-0.145862,0.000000,-0.764343,0.359401,0.535361,0.000000,-12.374950,4.006958,-8.346194,1.000000;;, + 1760;16;-0.395471,0.376937,-0.837569,0.000000,-0.502776,-0.851992,-0.146034,0.000000,-0.768647,0.363357,0.526453,0.000000,-12.374956,4.006951,-8.346193,1.000000;;, + 1840;16;-0.386531,0.372472,-0.843717,0.000000,-0.502794,-0.852022,-0.145794,0.000000,-0.773170,0.367862,0.516610,0.000000,-12.374984,4.006931,-8.346196,1.000000;;, + 1920;16;-0.377170,0.368002,-0.849892,0.000000,-0.502794,-0.852023,-0.145791,0.000000,-0.777779,0.372333,0.506387,0.000000,-12.374930,4.006939,-8.346193,1.000000;;, + 2000;16;-0.367752,0.364251,-0.855616,0.000000,-0.502734,-0.851920,-0.146598,0.000000,-0.782315,0.376236,0.496417,0.000000,-12.374946,4.006942,-8.346193,1.000000;;, + 2080;16;-0.357990,0.361378,-0.860958,0.000000,-0.502589,-0.851675,-0.148502,0.000000,-0.786922,0.379546,0.486516,0.000000,-12.374934,4.006934,-8.346194,1.000000;;, + 2160;16;-0.347639,0.359976,-0.865774,0.000000,-0.502302,-0.851189,-0.152220,0.000000,-0.791732,0.381963,0.476723,0.000000,-12.374949,4.006957,-8.346195,1.000000;;, + 2240;16;-0.336935,0.359491,-0.870196,0.000000,-0.501919,-0.850540,-0.157031,0.000000,-0.796588,0.383859,0.467012,0.000000,-12.374945,4.006944,-8.346195,1.000000;;, + 2320;16;-0.325771,0.359640,-0.874375,0.000000,-0.501454,-0.849752,-0.162683,0.000000,-0.801509,0.385462,0.457168,0.000000,-12.374968,4.006936,-8.346194,1.000000;;, + 2400;16;-0.314956,0.360150,-0.878120,0.000000,-0.500958,-0.848912,-0.168492,0.000000,-0.806129,0.386834,0.447790,0.000000,-12.374965,4.006927,-8.346193,1.000000;;, + 2480;16;-0.305369,0.360675,-0.881285,0.000000,-0.500500,-0.848135,-0.173683,0.000000,-0.810092,0.388046,0.439513,0.000000,-12.374954,4.006912,-8.346193,1.000000;;, + 2560;16;-0.296753,0.361113,-0.884045,0.000000,-0.500082,-0.847426,-0.178289,0.000000,-0.813545,0.389187,0.432063,0.000000,-12.374963,4.006956,-8.346196,1.000000;;, + 2640;16;-0.289142,0.361135,-0.886554,0.000000,-0.499739,-0.846845,-0.181974,0.000000,-0.816491,0.390429,0.425332,0.000000,-12.374942,4.006930,-8.346194,1.000000;;, + 2720;16;-0.282525,0.361066,-0.888713,0.000000,-0.499444,-0.846346,-0.185078,0.000000,-0.818984,0.391574,0.419446,0.000000,-12.374970,4.006927,-8.346194,1.000000;;, + 2800;16;-0.276615,0.361050,-0.890577,0.000000,-0.499173,-0.845887,-0.187887,0.000000,-0.821164,0.392580,0.414212,0.000000,-12.374959,4.006913,-8.346193,1.000000;;, + 2880;16;-0.272267,0.361310,-0.891810,0.000000,-0.498945,-0.845500,-0.190221,0.000000,-0.822754,0.393174,0.410475,0.000000,-12.374945,4.006962,-8.346195,1.000000;;, + 2960;16;-0.269968,0.362030,-0.892217,0.000000,-0.498766,-0.845196,-0.192033,0.000000,-0.823620,0.393164,0.408744,0.000000,-12.374956,4.006938,-8.346194,1.000000;;, + 3040;16;-0.270530,0.363477,-0.891458,0.000000,-0.498648,-0.844997,-0.193209,0.000000,-0.823507,0.392256,0.409844,0.000000,-12.374985,4.006958,-8.346195,1.000000;;, + 3120;16;-0.275395,0.366133,-0.888878,0.000000,-0.498614,-0.844939,-0.193552,0.000000,-0.821913,0.389904,0.415251,0.000000,-12.374957,4.006952,-8.346194,1.000000;;, + 3200;16;-0.283099,0.369485,-0.885062,0.000000,-0.498643,-0.844989,-0.193258,0.000000,-0.819274,0.386619,0.423457,0.000000,-12.374984,4.006936,-8.346194,1.000000;;, + 3280;16;-0.293334,0.373412,-0.880067,0.000000,-0.498733,-0.845141,-0.192360,0.000000,-0.815610,0.382493,0.434142,0.000000,-12.374942,4.006941,-8.346195,1.000000;;, + 3360;16;-0.304042,0.377235,-0.874787,0.000000,-0.498853,-0.845343,-0.191156,0.000000,-0.811606,0.378270,0.445204,0.000000,-12.374965,4.006917,-8.346193,1.000000;;, + 3440;16;-0.313157,0.380268,-0.870246,0.000000,-0.498974,-0.845550,-0.189922,0.000000,-0.808058,0.374755,0.454534,0.000000,-12.374965,4.006925,-8.346195,1.000000;;, + 3520;16;-0.320549,0.382559,-0.866543,0.000000,-0.499089,-0.845743,-0.188755,0.000000,-0.805083,0.371977,0.462034,0.000000,-12.374962,4.006930,-8.346194,1.000000;;, + 3600;16;-0.324950,0.383778,-0.864362,0.000000,-0.499171,-0.845882,-0.187914,0.000000,-0.803266,0.370402,0.466440,0.000000,-12.374987,4.006938,-8.346194,1.000000;;, + 3680;16;-0.327753,0.384378,-0.863036,0.000000,-0.499241,-0.846000,-0.187195,0.000000,-0.802083,0.369509,0.469176,0.000000,-12.374971,4.006967,-8.346194,1.000000;;, + 3760;16;-0.329814,0.384682,-0.862115,0.000000,-0.499305,-0.846110,-0.186524,0.000000,-0.801197,0.368940,0.471133,0.000000,-12.374954,4.006938,-8.346195,1.000000;;, + 3840;16;-0.331424,0.384701,-0.861489,0.000000,-0.499378,-0.846233,-0.185773,0.000000,-0.800488,0.368639,0.472573,0.000000,-12.374972,4.006914,-8.346196,1.000000;;, + 3920;16;-0.333010,0.384524,-0.860956,0.000000,-0.499468,-0.846387,-0.184826,0.000000,-0.799772,0.368471,0.473913,0.000000,-12.374987,4.006909,-8.346196,1.000000;;, + 4000;16;-0.335002,0.384236,-0.860312,0.000000,-0.499588,-0.846590,-0.183569,0.000000,-0.798865,0.368306,0.475568,0.000000,-12.374951,4.006948,-8.346193,1.000000;;, + 4080;16;-0.337949,0.383968,-0.859279,0.000000,-0.499749,-0.846861,-0.181872,0.000000,-0.797522,0.367960,0.478083,0.000000,-12.374978,4.006943,-8.346195,1.000000;;, + 4160;16;-0.341894,0.383677,-0.857847,0.000000,-0.499955,-0.847211,-0.179663,0.000000,-0.795709,0.367459,0.481477,0.000000,-12.374969,4.006939,-8.346195,1.000000;;, + 4240;16;-0.347213,0.383380,-0.855840,0.000000,-0.500220,-0.847661,-0.176777,0.000000,-0.793235,0.366729,0.486094,0.000000,-12.374987,4.006929,-8.346196,1.000000;;, + 4320;16;-0.353440,0.383022,-0.853448,0.000000,-0.500528,-0.848182,-0.173374,0.000000,-0.790286,0.365897,0.491495,0.000000,-12.374973,4.006942,-8.346195,1.000000;;, + 4400;16;-0.360300,0.382532,-0.850795,0.000000,-0.500870,-0.848762,-0.169506,0.000000,-0.786964,0.365065,0.497408,0.000000,-12.374979,4.006924,-8.346196,1.000000;;, + 4480;16;-0.367604,0.381976,-0.847916,0.000000,-0.501231,-0.849373,-0.165330,0.000000,-0.783349,0.364226,0.503691,0.000000,-12.374952,4.006930,-8.346195,1.000000;;, + 4560;16;-0.375143,0.381385,-0.844874,0.000000,-0.501596,-0.849993,-0.160976,0.000000,-0.779531,0.363397,0.510171,0.000000,-12.374953,4.006931,-8.346195,1.000000;;, + 4640;16;-0.382715,0.380790,-0.841741,0.000000,-0.501956,-0.850602,-0.156574,0.000000,-0.775609,0.362594,0.516678,0.000000,-12.374963,4.006971,-8.346191,1.000000;;, + 4720;16;-0.389985,0.380241,-0.838647,0.000000,-0.502292,-0.851172,-0.152345,0.000000,-0.771760,0.361833,0.522937,0.000000,-12.374979,4.006922,-8.346197,1.000000;;, + 4800;16;-0.397155,0.379708,-0.835518,0.000000,-0.502616,-0.851720,-0.148157,0.000000,-0.767883,0.361103,0.529112,0.000000,-12.374941,4.006959,-8.346190,1.000000;;, + 4960;16;-0.407607,0.378871,-0.830851,0.000000,-0.503079,-0.852505,-0.141940,0.000000,-0.762081,0.360128,0.538089,0.000000,-12.374953,4.006935,-8.346194,1.000000;;; + } + { Bip01_R_Clavicle } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.452612,0.717604,0.529327,0.000000,-0.426220,0.695510,-0.578448,0.000000,-0.783248,0.036203,0.620654,0.000000,31.000202,0.000005,0.000011,1.000000;;, + 80;16;0.440682,0.740856,0.506885,0.000000,-0.451457,0.670977,-0.588197,0.000000,-0.775877,0.030371,0.630152,0.000000,31.000204,0.000006,0.000021,1.000000;;, + 160;16;0.428367,0.763154,0.483836,0.000000,-0.476352,0.645727,-0.596763,0.000000,-0.767848,0.025157,0.640138,0.000000,31.000195,0.000000,0.000005,1.000000;;, + 240;16;0.415061,0.785612,0.458845,0.000000,-0.502242,0.618382,-0.604447,0.000000,-0.758602,0.020432,0.651234,0.000000,31.000191,0.000002,-0.000009,1.000000;;, + 320;16;0.403766,0.804658,0.435315,0.000000,-0.523951,0.593447,-0.610980,0.000000,-0.749966,0.018609,0.661214,0.000000,31.000191,-0.000002,-0.000000,1.000000;;, + 400;16;0.398536,0.817319,0.416123,0.000000,-0.536147,0.575729,-0.617319,0.000000,-0.744121,0.022920,0.667651,0.000000,31.000198,0.000007,0.000008,1.000000;;, + 480;16;0.397056,0.825128,0.401882,0.000000,-0.541189,0.564142,-0.623584,0.000000,-0.741256,0.030103,0.670547,0.000000,31.000196,0.000003,-0.000004,1.000000;;, + 560;16;0.399127,0.827686,0.394503,0.000000,-0.537802,0.559803,-0.630388,0.000000,-0.742608,0.039440,0.668564,0.000000,31.000212,0.000006,0.000019,1.000000;;, + 640;16;0.401665,0.827066,0.393225,0.000000,-0.530635,0.560148,-0.636129,0.000000,-0.746385,0.046852,0.663863,0.000000,31.000185,-0.000010,-0.000016,1.000000;;, + 720;16;0.400325,0.825301,0.398269,0.000000,-0.524681,0.562755,-0.638762,0.000000,-0.751298,0.046748,0.658305,0.000000,31.000183,-0.000005,-0.000014,1.000000;;, + 800;16;0.398441,0.821326,0.408251,0.000000,-0.517931,0.568828,-0.638891,0.000000,-0.756962,0.043114,0.652034,0.000000,31.000177,-0.000015,-0.000009,1.000000;;, + 880;16;0.397144,0.814737,0.422469,0.000000,-0.510570,0.578657,-0.635983,0.000000,-0.762623,0.036877,0.645791,0.000000,31.000189,-0.000002,-0.000010,1.000000;;, + 960;16;0.398858,0.805317,0.438607,0.000000,-0.501479,0.591997,-0.630920,0.000000,-0.767744,0.031695,0.639972,0.000000,31.000191,0.000008,-0.000007,1.000000;;, + 1040;16;0.404275,0.793806,0.454349,0.000000,-0.490979,0.607461,-0.624444,0.000000,-0.771687,0.029371,0.635324,0.000000,31.000198,-0.000008,0.000000,1.000000;;, + 1120;16;0.419312,0.777423,0.468819,0.000000,-0.474527,0.627936,-0.616863,0.000000,-0.773952,0.036190,0.632209,0.000000,31.000189,-0.000005,-0.000004,1.000000;;, + 1200;16;0.451385,0.752533,0.479527,0.000000,-0.446152,0.655725,-0.609076,0.000000,-0.772787,0.060986,0.631728,0.000000,31.000206,0.000001,0.000017,1.000000;;, + 1280;16;0.494407,0.719313,0.488007,0.000000,-0.408289,0.687812,-0.600179,0.000000,-0.767373,0.097484,0.633746,0.000000,31.000200,-0.000005,0.000008,1.000000;;, + 1360;16;0.547995,0.674778,0.494344,0.000000,-0.358778,0.723465,-0.589811,0.000000,-0.755632,0.145854,0.638550,0.000000,31.000196,0.000009,0.000008,1.000000;;, + 1440;16;0.600843,0.623908,0.499727,0.000000,-0.305625,0.756956,-0.577591,0.000000,-0.738634,0.194312,0.645493,0.000000,31.000193,0.000008,-0.000003,1.000000;;, + 1520;16;0.644029,0.573665,0.506098,0.000000,-0.257437,0.785502,-0.562773,0.000000,-0.720384,0.232153,0.653569,0.000000,31.000195,0.000002,0.000005,1.000000;;, + 1600;16;0.677819,0.525861,0.513841,0.000000,-0.215097,0.810139,-0.545351,0.000000,-0.703061,0.259123,0.662239,0.000000,31.000196,-0.000014,0.000000,1.000000;;, + 1680;16;0.698452,0.486218,0.525127,0.000000,-0.184156,0.831166,-0.524642,0.000000,-0.691557,0.269732,0.670069,0.000000,31.000195,-0.000029,-0.000009,1.000000;;, + 1760;16;0.712112,0.450626,0.538362,0.000000,-0.159496,0.850613,-0.501018,0.000000,-0.683709,0.270914,0.677605,0.000000,31.000202,-0.000005,0.000012,1.000000;;, + 1840;16;0.722193,0.416114,0.552528,0.000000,-0.137589,0.869265,-0.474813,0.000000,-0.677869,0.266885,0.685029,0.000000,31.000195,-0.000011,-0.000001,1.000000;;, + 1920;16;0.729968,0.381999,0.566766,0.000000,-0.117977,0.887209,-0.446028,0.000000,-0.673222,0.258721,0.692701,0.000000,31.000196,0.000019,0.000001,1.000000;;, + 2000;16;0.737439,0.347148,0.579373,0.000000,-0.099271,0.904197,-0.415420,0.000000,-0.668079,0.248832,0.701251,0.000000,31.000193,0.000022,0.000011,1.000000;;, + 2080;16;0.744879,0.309606,0.591015,0.000000,-0.080023,0.920878,-0.381550,0.000000,-0.662383,0.236914,0.710718,0.000000,31.000204,0.000002,0.000018,1.000000;;, + 2160;16;0.753388,0.266011,0.601369,0.000000,-0.057593,0.937702,-0.342634,0.000000,-0.655049,0.223501,0.721774,0.000000,31.000202,0.000016,0.000013,1.000000;;, + 2240;16;0.761671,0.219100,0.609798,0.000000,-0.033967,0.953304,-0.300095,0.000000,-0.647073,0.207861,0.733546,0.000000,31.000189,0.000026,0.000009,1.000000;;, + 2320;16;0.768939,0.168925,0.616601,0.000000,-0.009481,0.967368,-0.253198,0.000000,-0.639252,0.188848,0.745449,0.000000,31.000189,0.000003,-0.000001,1.000000;;, + 2400;16;0.775192,0.120581,0.620112,0.000000,0.013302,0.978281,-0.206857,0.000000,-0.631586,0.168603,0.756751,0.000000,31.000202,-0.000012,0.000010,1.000000;;, + 2480;16;0.780357,0.079030,0.620320,0.000000,0.031675,0.985713,-0.165428,0.000000,-0.624531,0.148741,0.766705,0.000000,31.000210,0.000004,0.000042,1.000000;;, + 2560;16;0.784730,0.044929,0.618207,0.000000,0.046236,0.990348,-0.130665,0.000000,-0.618110,0.131121,0.775079,0.000000,31.000202,0.000013,0.000026,1.000000;;, + 2640;16;0.788437,0.021205,0.614750,0.000000,0.056258,0.992731,-0.106395,0.000000,-0.612538,0.118470,0.781513,0.000000,31.000198,0.000002,0.000004,1.000000;;, + 2720;16;0.791435,0.005262,0.611231,0.000000,0.063142,0.993910,-0.090314,0.000000,-0.607984,0.110072,0.786282,0.000000,31.000195,0.000010,0.000002,1.000000;;, + 2800;16;0.793721,-0.004627,0.608264,0.000000,0.068325,0.994321,-0.081594,0.000000,-0.604432,0.106323,0.789530,0.000000,31.000202,-0.000019,0.000014,1.000000;;, + 2880;16;0.795044,-0.008385,0.606494,0.000000,0.071013,0.994315,-0.079343,0.000000,-0.602381,0.106150,0.791119,0.000000,31.000189,0.000019,0.000005,1.000000;;, + 2960;16;0.795173,-0.006850,0.606343,0.000000,0.071316,0.994053,-0.082297,0.000000,-0.602174,0.108682,0.790933,0.000000,31.000193,0.000009,0.000000,1.000000;;, + 3040;16;0.794147,0.001327,0.607724,0.000000,0.067899,0.993543,-0.090897,0.000000,-0.603920,0.113449,0.788929,0.000000,31.000198,-0.000002,0.000006,1.000000;;, + 3120;16;0.791804,0.018068,0.610508,0.000000,0.058857,0.992653,-0.105712,0.000000,-0.607933,0.119636,0.784924,0.000000,31.000198,-0.000002,0.000010,1.000000;;, + 3200;16;0.788313,0.041502,0.613873,0.000000,0.045577,0.991043,-0.125530,0.000000,-0.613584,0.126935,0.779360,0.000000,31.000193,-0.000014,-0.000006,1.000000;;, + 3280;16;0.783706,0.071876,0.616960,0.000000,0.027939,0.988198,-0.150616,0.000000,-0.620504,0.135275,0.772448,0.000000,31.000196,0.000021,0.000017,1.000000;;, + 3360;16;0.778145,0.104767,0.619285,0.000000,0.008416,0.984162,-0.177070,0.000000,-0.628028,0.142999,0.764939,0.000000,31.000200,-0.000020,0.000008,1.000000;;, + 3440;16;0.771949,0.135668,0.621038,0.000000,-0.010331,0.979509,-0.201136,0.000000,-0.635600,0.148851,0.757533,0.000000,31.000202,-0.000004,0.000017,1.000000;;, + 3520;16;0.765550,0.164315,0.622040,0.000000,-0.028308,0.974503,-0.222581,0.000000,-0.642753,0.152789,0.750682,0.000000,31.000198,0.000012,0.000010,1.000000;;, + 3600;16;0.759653,0.187891,0.622595,0.000000,-0.044033,0.970018,-0.239012,0.000000,-0.648836,0.154151,0.745150,0.000000,31.000191,-0.000024,-0.000017,1.000000;;, + 3680;16;0.753917,0.209216,0.622767,0.000000,-0.059075,0.965687,-0.252902,0.000000,-0.654308,0.153877,0.740407,0.000000,31.000185,0.000021,-0.000005,1.000000;;, + 3760;16;0.748277,0.230114,0.622197,0.000000,-0.074616,0.961153,-0.265739,0.000000,-0.659177,0.152421,0.736379,0.000000,31.000195,0.000003,-0.000001,1.000000;;, + 3840;16;0.742244,0.250932,0.621375,0.000000,-0.090540,0.956296,-0.278031,0.000000,-0.663985,0.150108,0.732524,0.000000,31.000195,-0.000019,-0.000002,1.000000;;, + 3920;16;0.735410,0.272427,0.620448,0.000000,-0.107080,0.950841,-0.290576,0.000000,-0.669109,0.147255,0.728430,0.000000,31.000191,-0.000032,-0.000008,1.000000;;, + 4000;16;0.727352,0.295395,0.619436,0.000000,-0.124487,0.944437,-0.304206,0.000000,-0.674879,0.144153,0.723711,0.000000,31.000198,-0.000002,0.000011,1.000000;;, + 4080;16;0.717608,0.320769,0.618180,0.000000,-0.142928,0.936556,-0.320054,0.000000,-0.681623,0.141318,0.717927,0.000000,31.000189,-0.000014,0.000006,1.000000;;, + 4160;16;0.705739,0.349021,0.616537,0.000000,-0.162977,0.926874,-0.338146,0.000000,-0.689472,0.138162,0.711013,0.000000,31.000168,0.000051,-0.000034,1.000000;;, + 4240;16;0.690887,0.381217,0.614287,0.000000,-0.185335,0.914677,-0.359188,0.000000,-0.698803,0.134310,0.702591,0.000000,31.000187,0.000017,-0.000017,1.000000;;, + 4320;16;0.673460,0.416351,0.610823,0.000000,-0.209720,0.899963,-0.382210,0.000000,-0.708851,0.129301,0.693406,0.000000,31.000189,-0.000003,-0.000010,1.000000;;, + 4400;16;0.653362,0.453959,0.605837,0.000000,-0.236263,0.882566,-0.406518,0.000000,-0.719234,0.122466,0.683889,0.000000,31.000198,-0.000005,-0.000002,1.000000;;, + 4480;16;0.631189,0.493016,0.598779,0.000000,-0.264244,0.862493,-0.431603,0.000000,-0.729230,0.114199,0.674672,0.000000,31.000196,-0.000002,0.000017,1.000000;;, + 4560;16;0.607438,0.532598,0.589371,0.000000,-0.293147,0.839865,-0.456828,0.000000,-0.738298,0.104722,0.666296,0.000000,31.000189,0.000009,-0.000021,1.000000;;, + 4640;16;0.582691,0.571791,0.577517,0.000000,-0.322475,0.814958,-0.481513,0.000000,-0.745976,0.094339,0.659257,0.000000,31.000195,0.000002,0.000001,1.000000;;, + 4720;16;0.558018,0.609306,0.563349,0.000000,-0.351534,0.788520,-0.504639,0.000000,-0.751692,0.083562,0.654199,0.000000,31.000191,-0.000009,-0.000010,1.000000;;, + 4800;16;0.532891,0.645602,0.547015,0.000000,-0.380503,0.760229,-0.526564,0.000000,-0.755807,0.072461,0.650772,0.000000,31.000195,-0.000004,0.000004,1.000000;;, + 4960;16;0.452612,0.717604,0.529327,0.000000,-0.426220,0.695510,-0.578448,0.000000,-0.783248,0.036203,0.620654,0.000000,31.000202,0.000005,0.000011,1.000000;;; + } + { Bip01_R_UpperArm } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.839302,-0.543666,-0.000000,0.000000,0.543666,0.839302,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202522,0.000004,-0.000000,1.000000;;, + 80;16;0.845569,-0.533866,0.000000,0.000000,0.533866,0.845569,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202530,-0.000005,-0.000000,1.000000;;, + 160;16;0.851723,-0.523993,0.000000,0.000000,0.523993,0.851723,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202515,-0.000010,0.000002,1.000000;;, + 240;16;0.858073,-0.513528,-0.000000,0.000000,0.513528,0.858073,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202507,0.000006,-0.000001,1.000000;;, + 320;16;0.863682,-0.504036,0.000000,0.000000,0.504036,0.863682,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202522,0.000010,-0.000001,1.000000;;, + 400;16;0.867822,-0.496876,-0.000000,0.000000,0.496876,0.867822,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202507,0.000001,0.000001,1.000000;;, + 480;16;0.870432,-0.492288,0.000000,0.000000,0.492288,0.870432,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,-0.000002,0.000001,1.000000;;, + 560;16;0.870943,-0.491383,-0.000000,0.000000,0.491383,0.870943,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202522,-0.000003,-0.000000,1.000000;;, + 640;16;0.870105,-0.492867,0.000000,0.000000,0.492866,0.870105,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202499,-0.000002,-0.000003,1.000000;;, + 720;16;0.868300,-0.496040,-0.000000,0.000000,0.496040,0.868300,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202530,-0.000012,-0.000001,1.000000;;, + 800;16;0.865941,-0.500146,0.000000,0.000000,0.500146,0.865941,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202515,-0.000000,0.000000,1.000000;;, + 880;16;0.863442,-0.504447,-0.000000,0.000000,0.504447,0.863442,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202507,-0.000005,0.000001,1.000000;;, + 960;16;0.861232,-0.508212,0.000000,0.000000,0.508212,0.861232,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202499,-0.000008,-0.000000,1.000000;;, + 1040;16;0.859419,-0.511272,0.000000,0.000000,0.511272,0.859419,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202507,-0.000001,-0.000001,1.000000;;, + 1120;16;0.859435,-0.511245,-0.000000,0.000000,0.511245,0.859435,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202507,-0.000007,-0.000002,1.000000;;, + 1200;16;0.863427,-0.504474,-0.000000,0.000000,0.504474,0.863427,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202522,0.000007,-0.000000,1.000000;;, + 1280;16;0.869177,-0.494501,-0.000000,0.000000,0.494501,0.869177,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202530,0.000000,-0.000002,1.000000;;, + 1360;16;0.876396,-0.481592,0.000000,0.000000,0.481592,0.876396,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,0.000005,-0.000003,1.000000;;, + 1440;16;0.881597,-0.472003,0.000000,0.000000,0.472003,0.881597,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202507,0.000001,-0.000001,1.000000;;, + 1520;16;0.881905,-0.471427,0.000000,0.000000,0.471427,0.881905,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202522,-0.000016,-0.000005,1.000000;;, + 1600;16;0.876021,-0.482273,-0.000000,0.000000,0.482273,0.876021,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,-0.000007,-0.000007,1.000000;;, + 1680;16;0.859824,-0.510590,0.000000,0.000000,0.510590,0.859824,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202507,0.000013,-0.000002,1.000000;;, + 1760;16;0.835646,-0.549268,-0.000000,0.000000,0.549268,0.835646,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202515,0.000009,-0.000001,1.000000;;, + 1840;16;0.803666,-0.595080,0.000000,0.000000,0.595080,0.803666,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202530,0.000029,0.000012,1.000000;;, + 1920;16;0.766699,-0.642007,-0.000000,0.000000,0.642007,0.766699,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202515,0.000022,0.000007,1.000000;;, + 2000;16;0.729471,-0.684011,-0.000000,0.000000,0.684011,0.729471,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202530,0.000014,0.000011,1.000000;;, + 2080;16;0.692161,-0.721744,-0.000000,0.000000,0.721744,0.692161,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202538,0.000032,0.000015,1.000000;;, + 2160;16;0.657421,-0.753524,0.000000,0.000000,0.753524,0.657421,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202530,0.000011,0.000011,1.000000;;, + 2240;16;0.623622,-0.781726,-0.000000,0.000000,0.781726,0.623622,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202530,0.000032,0.000010,1.000000;;, + 2320;16;0.588879,-0.808221,-0.000000,0.000000,0.808221,0.588879,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202530,0.000034,0.000008,1.000000;;, + 2400;16;0.555261,-0.831676,0.000000,0.000000,0.831676,0.555261,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202560,0.000015,0.000014,1.000000;;, + 2480;16;0.524198,-0.851596,-0.000000,0.000000,0.851596,0.524198,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202538,0.000019,0.000010,1.000000;;, + 2560;16;0.496174,-0.868223,-0.000000,0.000000,0.868223,0.496174,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202507,0.000032,0.000006,1.000000;;, + 2640;16;0.472349,-0.881412,-0.000000,0.000000,0.881412,0.472349,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202507,0.000040,0.000004,1.000000;;, + 2720;16;0.452028,-0.892004,-0.000000,0.000000,0.892004,0.452028,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202507,0.000024,0.000005,1.000000;;, + 2800;16;0.434868,-0.900494,0.000000,0.000000,0.900494,0.434868,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202492,0.000019,-0.000003,1.000000;;, + 2880;16;0.420585,-0.907253,0.000000,0.000000,0.907253,0.420585,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202515,0.000016,-0.000004,1.000000;;, + 2960;16;0.409422,-0.912345,-0.000000,0.000000,0.912345,0.409422,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202499,0.000036,-0.000002,1.000000;;, + 3040;16;0.399246,-0.916844,-0.000000,0.000000,0.916844,0.399247,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,0.000042,0.000018,1.000000;;, + 3120;16;0.386862,-0.922137,-0.000000,0.000000,0.922137,0.386862,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202522,0.000018,0.000006,1.000000;;, + 3200;16;0.375469,-0.926835,0.000000,0.000000,0.926835,0.375469,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,0.000028,0.000002,1.000000;;, + 3280;16;0.365296,-0.930891,0.000000,0.000000,0.930891,0.365296,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202515,0.000032,0.000009,1.000000;;, + 3360;16;0.362235,-0.932087,0.000000,0.000000,0.932087,0.362235,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,89.202507,0.000022,0.000010,1.000000;;, + 3440;16;0.371763,-0.928328,0.000000,0.000000,0.928328,0.371763,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,0.000029,0.000013,1.000000;;, + 3520;16;0.395109,-0.918634,0.000000,0.000000,0.918634,0.395109,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202530,0.000035,0.000017,1.000000;;, + 3600;16;0.437008,-0.899457,-0.000000,0.000000,0.899458,0.437008,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202507,0.000014,0.000007,1.000000;;, + 3680;16;0.490136,-0.871646,0.000000,0.000000,0.871646,0.490136,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202515,0.000030,0.000005,1.000000;;, + 3760;16;0.550422,-0.834887,0.000000,0.000000,0.834887,0.550422,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202538,0.000013,0.000007,1.000000;;, + 3840;16;0.612258,-0.790658,-0.000000,0.000000,0.790658,0.612258,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202507,0.000040,0.000007,1.000000;;, + 3920;16;0.671066,-0.741397,0.000000,0.000000,0.741397,0.671066,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202515,0.000025,-0.000001,1.000000;;, + 4000;16;0.723139,-0.690702,-0.000000,0.000000,0.690702,0.723139,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202507,0.000035,0.000003,1.000000;;, + 4080;16;0.764850,-0.644208,0.000000,0.000000,0.644208,0.764850,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202545,0.000027,0.000003,1.000000;;, + 4160;16;0.797213,-0.603698,-0.000000,0.000000,0.603698,0.797213,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202530,0.000025,0.000005,1.000000;;, + 4240;16;0.819067,-0.573698,-0.000000,0.000000,0.573698,0.819067,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202522,-0.000017,0.000003,1.000000;;, + 4320;16;0.834464,-0.551062,0.000000,0.000000,0.551062,0.834464,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202499,-0.000014,-0.000004,1.000000;;, + 4400;16;0.845668,-0.533709,-0.000000,0.000000,0.533709,0.845668,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202515,-0.000017,-0.000003,1.000000;;, + 4480;16;0.853964,-0.520332,-0.000000,0.000000,0.520332,0.853964,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202515,0.000008,0.000000,1.000000;;, + 4560;16;0.860620,-0.509247,-0.000000,0.000000,0.509247,0.860620,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,89.202522,-0.000018,0.000003,1.000000;;, + 4640;16;0.866783,-0.498686,0.000000,0.000000,0.498686,0.866783,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202522,-0.000006,0.000003,1.000000;;, + 4720;16;0.874184,-0.485595,0.000000,0.000000,0.485595,0.874184,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202507,-0.000021,-0.000002,1.000000;;, + 4800;16;0.881719,-0.471776,0.000000,0.000000,0.471776,0.881718,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,89.202530,-0.000026,0.000000,1.000000;;, + 4960;16;0.839302,-0.543666,-0.000000,0.000000,0.543666,0.839302,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,89.202522,0.000004,-0.000000,1.000000;;; + } + { Bip01_R_Forearm } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.999842,-0.009430,0.015054,0.000000,-0.015226,-0.018419,0.999714,0.000000,-0.009150,-0.999786,-0.018560,0.000000,61.671482,-0.000006,0.000000,1.000000;;, + 80;16;0.999827,-0.009472,0.015985,0.000000,-0.016159,-0.018507,0.999698,0.000000,-0.009174,-0.999784,-0.018657,0.000000,61.671463,-0.000007,-0.000003,1.000000;;, + 160;16;0.999812,-0.009515,0.016916,0.000000,-0.017091,-0.018595,0.999681,0.000000,-0.009198,-0.999782,-0.018754,0.000000,61.671459,0.000001,-0.000001,1.000000;;, + 240;16;0.999794,-0.009563,0.017906,0.000000,-0.018082,-0.018690,0.999662,0.000000,-0.009225,-0.999780,-0.018859,0.000000,61.671490,-0.000008,-0.000001,1.000000;;, + 320;16;0.999778,-0.009601,0.018778,0.000000,-0.018955,-0.018770,0.999644,0.000000,-0.009246,-0.999778,-0.018948,0.000000,61.671490,-0.000002,-0.000000,1.000000;;, + 400;16;0.999766,-0.009616,0.019365,0.000000,-0.019544,-0.018816,0.999632,0.000000,-0.009248,-0.999777,-0.019000,0.000000,61.671474,0.000002,0.000001,1.000000;;, + 480;16;0.999760,-0.009618,0.019699,0.000000,-0.019878,-0.018829,0.999625,0.000000,-0.009243,-0.999776,-0.019015,0.000000,61.671467,0.000002,0.000003,1.000000;;, + 560;16;0.999759,-0.009612,0.019718,0.000000,-0.019896,-0.018796,0.999625,0.000000,-0.009238,-0.999777,-0.018982,0.000000,61.671505,0.000017,0.000003,1.000000;;, + 640;16;0.999763,-0.009602,0.019530,0.000000,-0.019707,-0.018733,0.999630,0.000000,-0.009233,-0.999778,-0.018918,0.000000,61.671486,0.000014,0.000004,1.000000;;, + 720;16;0.999769,-0.009597,0.019230,0.000000,-0.019407,-0.018651,0.999638,0.000000,-0.009235,-0.999780,-0.018833,0.000000,61.671482,0.000011,0.000002,1.000000;;, + 800;16;0.999777,-0.009578,0.018802,0.000000,-0.018978,-0.018555,0.999648,0.000000,-0.009226,-0.999782,-0.018732,0.000000,61.671482,0.000007,-0.000003,1.000000;;, + 880;16;0.999788,-0.009534,0.018257,0.000000,-0.018430,-0.018450,0.999660,0.000000,-0.009194,-0.999784,-0.018622,0.000000,61.671471,0.000007,-0.000002,1.000000;;, + 960;16;0.999800,-0.009453,0.017605,0.000000,-0.017776,-0.018343,0.999674,0.000000,-0.009127,-0.999787,-0.018508,0.000000,61.671471,0.000002,-0.000001,1.000000;;, + 1040;16;0.999813,-0.009346,0.016926,0.000000,-0.017095,-0.018262,0.999687,0.000000,-0.009034,-0.999790,-0.018418,0.000000,61.671482,0.000002,0.000003,1.000000;;, + 1120;16;0.999830,-0.009133,0.016027,0.000000,-0.016191,-0.018147,0.999704,0.000000,-0.008839,-0.999794,-0.018292,0.000000,61.671497,-0.000000,0.000002,1.000000;;, + 1200;16;0.999854,-0.008707,0.014680,0.000000,-0.014835,-0.017926,0.999729,0.000000,-0.008441,-0.999801,-0.018053,0.000000,61.671471,-0.000005,-0.000001,1.000000;;, + 1280;16;0.999881,-0.008164,0.013070,0.000000,-0.013213,-0.017669,0.999757,0.000000,-0.007931,-0.999811,-0.017775,0.000000,61.671494,-0.000007,0.000003,1.000000;;, + 1360;16;0.999910,-0.007500,0.011158,0.000000,-0.011287,-0.017372,0.999785,0.000000,-0.007305,-0.999821,-0.017455,0.000000,61.671497,-0.000011,-0.000001,1.000000;;, + 1440;16;0.999932,-0.006905,0.009383,0.000000,-0.009501,-0.017186,0.999807,0.000000,-0.006743,-0.999828,-0.017250,0.000000,61.671490,-0.000003,0.000006,1.000000;;, + 1520;16;0.999945,-0.006558,0.008132,0.000000,-0.008244,-0.017252,0.999817,0.000000,-0.006417,-0.999830,-0.017305,0.000000,61.671482,0.000011,0.000003,1.000000;;, + 1600;16;0.999951,-0.006482,0.007524,0.000000,-0.007637,-0.017610,0.999816,0.000000,-0.006349,-0.999824,-0.017658,0.000000,61.671501,-0.000002,-0.000003,1.000000;;, + 1680;16;0.999945,-0.006802,0.007930,0.000000,-0.008054,-0.018389,0.999799,0.000000,-0.006654,-0.999808,-0.018443,0.000000,61.671494,0.000021,0.000014,1.000000;;, + 1760;16;0.999932,-0.007393,0.008977,0.000000,-0.009119,-0.019460,0.999769,0.000000,-0.007217,-0.999783,-0.019526,0.000000,61.671486,0.000015,0.000004,1.000000;;, + 1840;16;0.999911,-0.008187,0.010506,0.000000,-0.010674,-0.020765,0.999727,0.000000,-0.007967,-0.999751,-0.020850,0.000000,61.671494,-0.000007,0.000002,1.000000;;, + 1920;16;0.999883,-0.009146,0.012254,0.000000,-0.012455,-0.022217,0.999676,0.000000,-0.008871,-0.999711,-0.022328,0.000000,61.671494,0.000001,0.000009,1.000000;;, + 2000;16;0.999852,-0.010190,0.013890,0.000000,-0.014128,-0.023693,0.999619,0.000000,-0.009857,-0.999667,-0.023834,0.000000,61.671455,0.000022,0.000007,1.000000;;, + 2080;16;0.999816,-0.011372,0.015462,0.000000,-0.015745,-0.025248,0.999557,0.000000,-0.010977,-0.999617,-0.025422,0.000000,61.671490,-0.000011,-0.000000,1.000000;;, + 2160;16;0.999777,-0.012730,0.016875,0.000000,-0.017213,-0.026899,0.999490,0.000000,-0.012269,-0.999557,-0.027112,0.000000,61.671467,0.000003,-0.000003,1.000000;;, + 2240;16;0.999733,-0.014224,0.018223,0.000000,-0.018625,-0.028628,0.999417,0.000000,-0.013694,-0.999489,-0.028886,0.000000,61.671478,-0.000009,-0.000003,1.000000;;, + 2320;16;0.999681,-0.015881,0.019623,0.000000,-0.020101,-0.030473,0.999334,0.000000,-0.015272,-0.999409,-0.030783,0.000000,61.671467,0.000001,0.000011,1.000000;;, + 2400;16;0.999627,-0.017550,0.020908,0.000000,-0.021467,-0.032279,0.999248,0.000000,-0.016862,-0.999325,-0.032644,0.000000,61.671471,0.000003,0.000004,1.000000;;, + 2480;16;0.999577,-0.019084,0.021961,0.000000,-0.022599,-0.033901,0.999170,0.000000,-0.018323,-0.999243,-0.034318,0.000000,61.671463,-0.000016,-0.000008,1.000000;;, + 2560;16;0.999531,-0.020501,0.022751,0.000000,-0.023466,-0.035354,0.999099,0.000000,-0.019679,-0.999165,-0.035819,0.000000,61.671486,0.000012,0.000005,1.000000;;, + 2640;16;0.999495,-0.021759,0.023170,0.000000,-0.023956,-0.036589,0.999043,0.000000,-0.020891,-0.999094,-0.037092,0.000000,61.671482,-0.000005,-0.000001,1.000000;;, + 2720;16;0.999466,-0.022900,0.023327,0.000000,-0.024179,-0.037656,0.998998,0.000000,-0.021999,-0.999028,-0.038190,0.000000,61.671471,0.000016,0.000004,1.000000;;, + 2800;16;0.999442,-0.023976,0.023270,0.000000,-0.024185,-0.038610,0.998962,0.000000,-0.023053,-0.998967,-0.039168,0.000000,61.671474,0.000007,-0.000001,1.000000;;, + 2880;16;0.999423,-0.024915,0.023070,0.000000,-0.024041,-0.039392,0.998935,0.000000,-0.023979,-0.998913,-0.039969,0.000000,61.671463,0.000002,-0.000002,1.000000;;, + 2960;16;0.999411,-0.025649,0.022815,0.000000,-0.023829,-0.039954,0.998917,0.000000,-0.024709,-0.998872,-0.040542,0.000000,61.671497,0.000005,0.000003,1.000000;;, + 3040;16;0.999403,-0.026214,0.022511,0.000000,-0.023557,-0.040321,0.998909,0.000000,-0.025277,-0.998843,-0.040915,0.000000,61.671467,-0.000020,-0.000016,1.000000;;, + 3120;16;0.999399,-0.026629,0.022214,0.000000,-0.023283,-0.040508,0.998908,0.000000,-0.025700,-0.998824,-0.041104,0.000000,61.671455,-0.000006,0.000003,1.000000;;, + 3200;16;0.999399,-0.026876,0.021870,0.000000,-0.022949,-0.040500,0.998916,0.000000,-0.025961,-0.998818,-0.041092,0.000000,61.671474,-0.000005,-0.000005,1.000000;;, + 3280;16;0.999406,-0.026975,0.021446,0.000000,-0.022524,-0.040312,0.998933,0.000000,-0.026081,-0.998823,-0.040896,0.000000,61.671497,-0.000002,-0.000003,1.000000;;, + 3360;16;0.999421,-0.026824,0.020931,0.000000,-0.021991,-0.039871,0.998963,0.000000,-0.025962,-0.998845,-0.040438,0.000000,61.671486,-0.000007,-0.000006,1.000000;;, + 3440;16;0.999446,-0.026350,0.020320,0.000000,-0.021343,-0.039125,0.999006,0.000000,-0.025529,-0.998887,-0.039666,0.000000,61.671463,-0.000008,-0.000006,1.000000;;, + 3520;16;0.999483,-0.025496,0.019563,0.000000,-0.020524,-0.038022,0.999066,0.000000,-0.024729,-0.998952,-0.038526,0.000000,61.671463,-0.000012,-0.000017,1.000000;;, + 3600;16;0.999536,-0.024132,0.018581,0.000000,-0.019454,-0.036450,0.999146,0.000000,-0.023434,-0.999044,-0.036903,0.000000,61.671471,-0.000009,-0.000004,1.000000;;, + 3680;16;0.999597,-0.022410,0.017443,0.000000,-0.018211,-0.034542,0.999237,0.000000,-0.021791,-0.999152,-0.034936,0.000000,61.671455,0.000011,-0.000003,1.000000;;, + 3760;16;0.999662,-0.020385,0.016149,0.000000,-0.016803,-0.032340,0.999336,0.000000,-0.019849,-0.999269,-0.032671,0.000000,61.671494,0.000001,-0.000004,1.000000;;, + 3840;16;0.999724,-0.018232,0.014819,0.000000,-0.015362,-0.030006,0.999432,0.000000,-0.017777,-0.999383,-0.030278,0.000000,61.671478,0.000009,-0.000003,1.000000;;, + 3920;16;0.999779,-0.016095,0.013546,0.000000,-0.013988,-0.027677,0.999519,0.000000,-0.015712,-0.999487,-0.027896,0.000000,61.671463,0.000024,0.000011,1.000000;;, + 4000;16;0.999823,-0.014117,0.012423,0.000000,-0.012780,-0.025486,0.999593,0.000000,-0.013794,-0.999575,-0.025662,0.000000,61.671501,-0.000024,0.000006,1.000000;;, + 4080;16;0.999855,-0.012481,0.011565,0.000000,-0.011857,-0.023609,0.999651,0.000000,-0.012204,-0.999643,-0.023753,0.000000,61.671471,-0.000031,-0.000007,1.000000;;, + 4160;16;0.999877,-0.011208,0.011004,0.000000,-0.011249,-0.022065,0.999693,0.000000,-0.010962,-0.999694,-0.022188,0.000000,61.671509,-0.000053,-0.000012,1.000000;;, + 4240;16;0.999887,-0.010432,0.010846,0.000000,-0.011063,-0.020981,0.999719,0.000000,-0.010202,-0.999725,-0.021094,0.000000,61.671482,0.000002,-0.000003,1.000000;;, + 4320;16;0.999890,-0.009995,0.010980,0.000000,-0.011180,-0.020212,0.999733,0.000000,-0.009771,-0.999746,-0.020321,0.000000,61.671471,0.000013,0.000006,1.000000;;, + 4400;16;0.999887,-0.009808,0.011352,0.000000,-0.011543,-0.019672,0.999740,0.000000,-0.009583,-0.999758,-0.019783,0.000000,61.671455,0.000016,0.000008,1.000000;;, + 4480;16;0.999881,-0.009799,0.011888,0.000000,-0.012076,-0.019296,0.999741,0.000000,-0.009568,-0.999766,-0.019412,0.000000,61.671490,-0.000029,-0.000001,1.000000;;, + 4560;16;0.999873,-0.009892,0.012518,0.000000,-0.012704,-0.019013,0.999739,0.000000,-0.009651,-0.999770,-0.019136,0.000000,61.671459,0.000019,0.000000,1.000000;;, + 4640;16;0.999863,-0.010010,0.013171,0.000000,-0.013357,-0.018754,0.999735,0.000000,-0.009760,-0.999774,-0.018885,0.000000,61.671463,-0.000028,-0.000006,1.000000;;, + 4720;16;0.999855,-0.010026,0.013731,0.000000,-0.013913,-0.018401,0.999734,0.000000,-0.009770,-0.999780,-0.018538,0.000000,61.671471,0.000000,0.000002,1.000000;;, + 4800;16;0.999848,-0.010016,0.014267,0.000000,-0.014446,-0.018025,0.999733,0.000000,-0.009756,-0.999787,-0.018167,0.000000,61.671482,0.000009,-0.000000,1.000000;;, + 4960;16;0.999842,-0.009430,0.015054,0.000000,-0.015226,-0.018419,0.999714,0.000000,-0.009150,-0.999786,-0.018560,0.000000,61.671482,-0.000006,0.000000,1.000000;;; + } + { Bip01_R_Hand } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410504,3.054970,10.755419,1.000000;;, + 80;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410502,3.054969,10.755422,1.000000;;, + 160;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410496,3.054973,10.755424,1.000000;;, + 240;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410510,3.054973,10.755419,1.000000;;, + 320;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410503,3.054971,10.755418,1.000000;;, + 400;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410501,3.054970,10.755423,1.000000;;, + 480;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410504,3.054974,10.755414,1.000000;;, + 560;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410506,3.054973,10.755427,1.000000;;, + 640;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410496,3.054969,10.755433,1.000000;;, + 720;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410497,3.054971,10.755427,1.000000;;, + 800;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410497,3.054971,10.755422,1.000000;;, + 880;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410493,3.054971,10.755424,1.000000;;, + 960;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410510,3.054967,10.755420,1.000000;;, + 1040;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410503,3.054971,10.755429,1.000000;;, + 1120;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410495,3.054971,10.755433,1.000000;;, + 1200;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410502,3.054972,10.755430,1.000000;;, + 1280;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410520,3.054972,10.755430,1.000000;;, + 1360;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410509,3.054971,10.755430,1.000000;;, + 1440;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410509,3.054970,10.755424,1.000000;;, + 1520;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410499,3.054962,10.755417,1.000000;;, + 1600;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410498,3.054971,10.755423,1.000000;;, + 1680;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410508,3.054972,10.755428,1.000000;;, + 1760;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410496,3.054977,10.755415,1.000000;;, + 1840;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410498,3.054973,10.755422,1.000000;;, + 1920;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410505,3.054962,10.755414,1.000000;;, + 2000;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410492,3.054979,10.755416,1.000000;;, + 2080;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410499,3.054971,10.755430,1.000000;;, + 2160;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410506,3.054967,10.755430,1.000000;;, + 2240;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410517,3.054963,10.755426,1.000000;;, + 2320;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410503,3.054976,10.755416,1.000000;;, + 2400;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410486,3.054972,10.755421,1.000000;;, + 2480;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410499,3.054968,10.755430,1.000000;;, + 2560;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410509,3.054973,10.755420,1.000000;;, + 2640;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410502,3.054973,10.755420,1.000000;;, + 2720;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410489,3.054962,10.755431,1.000000;;, + 2800;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410504,3.054969,10.755413,1.000000;;, + 2880;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410510,3.054960,10.755435,1.000000;;, + 2960;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410513,3.054971,10.755418,1.000000;;, + 3040;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410494,3.054973,10.755432,1.000000;;, + 3120;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410505,3.054975,10.755428,1.000000;;, + 3200;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410489,3.054979,10.755415,1.000000;;, + 3280;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410505,3.054979,10.755413,1.000000;;, + 3360;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410506,3.054971,10.755419,1.000000;;, + 3440;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410515,3.054965,10.755436,1.000000;;, + 3520;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410480,3.054987,10.755407,1.000000;;, + 3600;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410487,3.054979,10.755419,1.000000;;, + 3680;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410525,3.054966,10.755445,1.000000;;, + 3760;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410490,3.054978,10.755404,1.000000;;, + 3840;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410493,3.054979,10.755408,1.000000;;, + 3920;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410492,3.054971,10.755415,1.000000;;, + 4000;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410519,3.054965,10.755444,1.000000;;, + 4080;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410522,3.054968,10.755445,1.000000;;, + 4160;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410519,3.054975,10.755439,1.000000;;, + 4240;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410499,3.054971,10.755405,1.000000;;, + 4320;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410506,3.054970,10.755424,1.000000;;, + 4400;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410498,3.054973,10.755425,1.000000;;, + 4480;16;0.713247,-0.002867,0.700907,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410496,3.054969,10.755423,1.000000;;, + 4560;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410496,3.054974,10.755420,1.000000;;, + 4640;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410505,3.054972,10.755441,1.000000;;, + 4720;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410500,3.054973,10.755397,1.000000;;, + 4800;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410507,3.054970,10.755430,1.000000;;, + 4960;16;0.713247,-0.002867,0.700906,0.000000,-0.700353,-0.042855,0.712509,0.000000,0.027995,-0.999077,-0.032574,0.000000,12.410504,3.054970,10.755419,1.000000;;; + } + { Bip01_R_Finger0 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075052,0.000002,0.000001,1.000000;;, + 80;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075058,-0.000000,0.000002,1.000000;;, + 160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075060,0.000007,-0.000002,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075061,0.000001,0.000002,1.000000;;, + 320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075058,-0.000003,0.000001,1.000000;;, + 400;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075050,0.000010,0.000004,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075057,-0.000000,0.000002,1.000000;;, + 560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075052,-0.000008,0.000006,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075049,-0.000002,-0.000000,1.000000;;, + 720;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075055,-0.000000,0.000001,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075058,0.000006,-0.000003,1.000000;;, + 880;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075056,0.000002,0.000001,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075064,0.000012,-0.000004,1.000000;;, + 1040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075058,0.000012,-0.000001,1.000000;;, + 1120;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075068,-0.000011,-0.000001,1.000000;;, + 1200;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075061,0.000005,0.000002,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075065,0.000005,0.000002,1.000000;;, + 1360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075057,-0.000009,-0.000001,1.000000;;, + 1440;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075051,0.000008,0.000002,1.000000;;, + 1520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075061,-0.000001,-0.000004,1.000000;;, + 1600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075050,-0.000008,-0.000012,1.000000;;, + 1680;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075062,-0.000003,0.000002,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075061,0.000004,0.000001,1.000000;;, + 1840;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075066,-0.000003,0.000002,1.000000;;, + 1920;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075069,0.000007,-0.000002,1.000000;;, + 2000;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075076,0.000014,0.000012,1.000000;;, + 2080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075056,0.000002,-0.000004,1.000000;;, + 2160;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075055,-0.000008,-0.000001,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075054,-0.000003,-0.000007,1.000000;;, + 2320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075050,0.000007,-0.000004,1.000000;;, + 2400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075045,-0.000015,-0.000011,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075078,0.000018,0.000016,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075087,0.000001,0.000011,1.000000;;, + 2640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075067,0.000012,0.000005,1.000000;;, + 2720;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075042,0.000007,-0.000007,1.000000;;, + 2800;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075064,0.000019,0.000008,1.000000;;, + 2880;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075041,0.000003,-0.000016,1.000000;;, + 2960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075039,0.000007,-0.000012,1.000000;;, + 3040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075060,0.000024,0.000005,1.000000;;, + 3120;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075059,-0.000010,-0.000001,1.000000;;, + 3200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075027,0.000053,-0.000005,1.000000;;, + 3280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075060,-0.000006,-0.000005,1.000000;;, + 3360;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075058,0.000014,0.000003,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075065,-0.000020,-0.000003,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075032,0.000007,-0.000006,1.000000;;, + 3600;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075042,0.000017,0.000001,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075056,-0.000013,-0.000005,1.000000;;, + 3760;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075061,0.000009,0.000004,1.000000;;, + 3840;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075056,-0.000006,-0.000002,1.000000;;, + 3920;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075090,0.000000,0.000008,1.000000;;, + 4000;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075047,0.000004,0.000001,1.000000;;, + 4080;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075047,-0.000000,-0.000001,1.000000;;, + 4160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075092,0.000014,0.000012,1.000000;;, + 4240;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075029,-0.000006,-0.000009,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075057,-0.000005,-0.000004,1.000000;;, + 4400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075061,-0.000004,-0.000000,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.075070,0.000014,0.000009,1.000000;;, + 4560;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075041,-0.000008,-0.000004,1.000000;;, + 4640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075053,0.000000,-0.000002,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.075084,0.000022,-0.000000,1.000000;;, + 4800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.075073,0.000020,-0.000001,1.000000;;, + 4960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.075052,0.000002,0.000001,1.000000;;; + } + { Bip01_R_Finger01 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961570,0.000006,0.000001,1.000000;;, + 80;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961572,-0.000003,0.000001,1.000000;;, + 160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961579,-0.000014,-0.000005,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961579,0.000003,-0.000004,1.000000;;, + 320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961572,-0.000001,-0.000001,1.000000;;, + 400;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961577,-0.000006,-0.000002,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961569,0.000007,-0.000003,1.000000;;, + 560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961569,0.000006,-0.000003,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961580,-0.000004,0.000001,1.000000;;, + 720;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961580,0.000001,0.000001,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961578,-0.000004,0.000001,1.000000;;, + 880;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961586,-0.000004,0.000002,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961578,0.000002,0.000001,1.000000;;, + 1040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961571,-0.000016,-0.000002,1.000000;;, + 1120;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961569,-0.000003,-0.000004,1.000000;;, + 1200;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961572,-0.000011,0.000003,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961568,0.000003,-0.000002,1.000000;;, + 1360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961584,-0.000004,-0.000001,1.000000;;, + 1440;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961586,0.000001,0.000002,1.000000;;, + 1520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961574,-0.000001,-0.000001,1.000000;;, + 1600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961571,-0.000003,0.000000,1.000000;;, + 1680;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961561,-0.000015,-0.000013,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961587,0.000014,0.000007,1.000000;;, + 1840;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961578,0.000000,0.000005,1.000000;;, + 1920;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961569,-0.000001,-0.000000,1.000000;;, + 2000;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961568,-0.000005,-0.000007,1.000000;;, + 2080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961582,-0.000002,0.000007,1.000000;;, + 2160;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961592,0.000002,0.000007,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961571,0.000001,0.000002,1.000000;;, + 2320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961581,-0.000002,0.000007,1.000000;;, + 2400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961587,0.000007,0.000005,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961561,-0.000005,-0.000009,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961563,-0.000000,-0.000002,1.000000;;, + 2640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961570,0.000003,-0.000004,1.000000;;, + 2720;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961582,-0.000004,0.000006,1.000000;;, + 2800;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961578,-0.000005,-0.000001,1.000000;;, + 2880;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961594,0.000013,0.000015,1.000000;;, + 2960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961571,-0.000003,0.000001,1.000000;;, + 3040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961572,-0.000013,-0.000007,1.000000;;, + 3120;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961565,-0.000008,-0.000008,1.000000;;, + 3200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961592,-0.000029,0.000004,1.000000;;, + 3280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961550,0.000049,0.000002,1.000000;;, + 3360;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961544,0.000018,-0.000008,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961576,0.000012,0.000001,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961610,0.000008,0.000017,1.000000;;, + 3600;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961546,0.000012,-0.000004,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961613,-0.000003,0.000015,1.000000;;, + 3760;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961617,0.000004,0.000010,1.000000;;, + 3840;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961557,-0.000016,-0.000011,1.000000;;, + 3920;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961516,-0.000004,-0.000013,1.000000;;, + 4000;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961571,-0.000010,-0.000010,1.000000;;, + 4080;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961620,0.000005,0.000005,1.000000;;, + 4160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961563,-0.000004,-0.000014,1.000000;;, + 4240;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961597,0.000014,0.000007,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961577,0.000003,0.000003,1.000000;;, + 4400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961582,0.000008,-0.000003,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,5.961578,0.000009,0.000002,1.000000;;, + 4560;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961586,0.000002,-0.000004,1.000000;;, + 4640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961611,0.000023,0.000002,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,5.961559,-0.000019,-0.000006,1.000000;;, + 4800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,5.961570,-0.000010,-0.000003,1.000000;;, + 4960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,5.961570,0.000006,0.000001,1.000000;;; + } + { Bip01_R_Finger02 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961581,-0.000005,-0.000000,1.000000;;, + 80;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961575,0.000001,0.000000,1.000000;;, + 160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961576,0.000007,-0.000000,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961576,0.000002,-0.000002,1.000000;;, + 320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961573,-0.000000,-0.000002,1.000000;;, + 400;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961582,-0.000001,-0.000004,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961582,-0.000001,0.000002,1.000000;;, + 560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,5.961582,-0.000003,-0.000002,1.000000;;, + 640;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,5.961580,-0.000005,0.000002,1.000000;;, + 720;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961580,0.000001,0.000001,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961578,0.000001,0.000002,1.000000;;, + 880;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961575,0.000007,0.000002,1.000000;;, + 960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961577,0.000006,0.000002,1.000000;;, + 1040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961578,-0.000004,0.000001,1.000000;;, + 1120;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961572,0.000001,-0.000000,1.000000;;, + 1200;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961593,-0.000010,0.000001,1.000000;;, + 1280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961579,-0.000002,0.000000,1.000000;;, + 1360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961573,0.000011,0.000003,1.000000;;, + 1440;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,5.961576,-0.000006,-0.000001,1.000000;;, + 1520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961574,-0.000000,-0.000001,1.000000;;, + 1600;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961571,-0.000001,0.000001,1.000000;;, + 1680;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961578,0.000010,0.000006,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961567,-0.000012,-0.000007,1.000000;;, + 1840;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961578,0.000001,0.000001,1.000000;;, + 1920;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961568,-0.000001,-0.000003,1.000000;;, + 2000;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961567,-0.000005,-0.000003,1.000000;;, + 2080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961581,-0.000001,-0.000001,1.000000;;, + 2160;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961565,0.000005,-0.000004,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961573,0.000003,-0.000001,1.000000;;, + 2320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961581,-0.000002,0.000000,1.000000;;, + 2400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961590,0.000008,0.000005,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961561,-0.000005,-0.000011,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961563,-0.000000,-0.000004,1.000000;;, + 2640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961572,0.000001,0.000002,1.000000;;, + 2720;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961587,-0.000002,0.000000,1.000000;;, + 2800;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961576,-0.000006,-0.000003,1.000000;;, + 2880;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961582,-0.000011,0.000001,1.000000;;, + 2960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961596,-0.000020,0.000010,1.000000;;, + 3040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961575,-0.000013,-0.000003,1.000000;;, + 3120;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961577,0.000014,0.000005,1.000000;;, + 3200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961589,-0.000028,-0.000002,1.000000;;, + 3280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961583,-0.000012,0.000003,1.000000;;, + 3360;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961590,-0.000017,0.000003,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961579,0.000012,0.000004,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961597,-0.000018,0.000009,1.000000;;, + 3600;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961603,-0.000013,0.000008,1.000000;;, + 3680;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961560,0.000020,0.000000,1.000000;;, + 3760;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961558,-0.000007,-0.000006,1.000000;;, + 3840;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961568,0.000012,-0.000001,1.000000;;, + 3920;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961574,0.000002,0.000012,1.000000;;, + 4000;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,5.961567,-0.000001,0.000005,1.000000;;, + 4080;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961557,-0.000003,0.000003,1.000000;;, + 4160;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961563,-0.000009,0.000006,1.000000;;, + 4240;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961600,-0.000002,0.000010,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961576,0.000003,0.000009,1.000000;;, + 4400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961584,0.000005,0.000009,1.000000;;, + 4480;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,5.961586,-0.000003,0.000008,1.000000;;, + 4560;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,5.961587,0.000002,0.000010,1.000000;;, + 4640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961561,-0.000013,0.000004,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,5.961559,-0.000019,0.000011,1.000000;;, + 4800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,5.961568,-0.000011,0.000000,1.000000;;, + 4960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,5.961581,-0.000005,-0.000000,1.000000;;; + } + { Dummy01 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087999,0.354686,0.505020,1.000000;;, + 80;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088005,0.354684,0.505019,1.000000;;, + 160;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087999,0.354688,0.505024,1.000000;;, + 240;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088009,0.354687,0.505020,1.000000;;, + 320;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088003,0.354686,0.505027,1.000000;;, + 400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087999,0.354684,0.505021,1.000000;;, + 480;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088009,0.354687,0.505025,1.000000;;, + 560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088003,0.354688,0.505028,1.000000;;, + 640;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087997,0.354688,0.505030,1.000000;;, + 720;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087994,0.354686,0.505022,1.000000;;, + 800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087999,0.354685,0.505018,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087994,0.354686,0.505031,1.000000;;, + 960;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088005,0.354684,0.505028,1.000000;;, + 1040;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088007,0.354689,0.505018,1.000000;;, + 1120;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088001,0.354687,0.505025,1.000000;;, + 1200;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087996,0.354690,0.505031,1.000000;;, + 1280;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087994,0.354685,0.505033,1.000000;;, + 1360;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088009,0.354686,0.505025,1.000000;;, + 1440;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088003,0.354692,0.505019,1.000000;;, + 1520;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087997,0.354684,0.505028,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088011,0.354688,0.505035,1.000000;;, + 1680;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088003,0.354685,0.505040,1.000000;;, + 1760;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088001,0.354688,0.505032,1.000000;;, + 1840;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088013,0.354688,0.505036,1.000000;;, + 1920;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087994,0.354683,0.505022,1.000000;;, + 2000;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088003,0.354689,0.505030,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087988,0.354692,0.505028,1.000000;;, + 2160;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087992,0.354689,0.505020,1.000000;;, + 2240;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088015,0.354682,0.505032,1.000000;;, + 2320;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087988,0.354681,0.505026,1.000000;;, + 2400;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087994,0.354679,0.505042,1.000000;;, + 2480;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087996,0.354681,0.505034,1.000000;;, + 2560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088009,0.354687,0.505028,1.000000;;, + 2640;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088013,0.354678,0.505034,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088007,0.354680,0.505031,1.000000;;, + 2800;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087994,0.354681,0.505026,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087967,0.354697,0.505018,1.000000;;, + 2960;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088001,0.354682,0.505031,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087996,0.354690,0.505022,1.000000;;, + 3120;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088024,0.354678,0.505043,1.000000;;, + 3200;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087999,0.354694,0.505016,1.000000;;, + 3280;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088015,0.354683,0.505044,1.000000;;, + 3360;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088017,0.354681,0.505035,1.000000;;, + 3440;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088024,0.354685,0.505028,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088020,0.354692,0.505020,1.000000;;, + 3600;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087996,0.354696,0.505013,1.000000;;, + 3680;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087994,0.354693,0.505020,1.000000;;, + 3760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087996,0.354686,0.505022,1.000000;;, + 3840;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088005,0.354690,0.505030,1.000000;;, + 3920;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088001,0.354686,0.505025,1.000000;;, + 4000;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087980,0.354687,0.505010,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088009,0.354684,0.505041,1.000000;;, + 4160;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087996,0.354690,0.505006,1.000000;;, + 4240;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087988,0.354687,0.505018,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087992,0.354683,0.505023,1.000000;;, + 4400;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.087997,0.354690,0.505014,1.000000;;, + 4480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.088001,0.354687,0.505015,1.000000;;, + 4560;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088013,0.354685,0.505053,1.000000;;, + 4640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,-0.000000,-0.000796,1.000000,0.000000,24.088007,0.354691,0.505029,1.000000;;, + 4720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087994,0.354688,0.505030,1.000000;;, + 4800;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087997,0.354687,0.504994,1.000000;;, + 4960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000796,0.000000,0.000000,-0.000796,1.000000,0.000000,24.087999,0.354686,0.505020,1.000000;;; + } + { Bip01_R_Finger1 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300053,-0.000001,-0.000002,1.000000;;, + 80;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300060,0.000002,-0.000000,1.000000;;, + 160;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300057,-0.000002,-0.000002,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300056,0.000004,0.000001,1.000000;;, + 320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300049,0.000001,-0.000006,1.000000;;, + 400;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300044,0.000001,-0.000001,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300066,0.000002,0.000005,1.000000;;, + 560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300056,0.000002,0.000000,1.000000;;, + 640;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300058,0.000001,0.000002,1.000000;;, + 720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300049,0.000002,-0.000004,1.000000;;, + 800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300060,-0.000003,-0.000002,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300063,0.000001,-0.000012,1.000000;;, + 960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300061,-0.000000,-0.000003,1.000000;;, + 1040;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300055,-0.000001,0.000002,1.000000;;, + 1120;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300057,0.000000,0.000003,1.000000;;, + 1200;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300050,0.000003,0.000002,1.000000;;, + 1280;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300063,0.000001,0.000010,1.000000;;, + 1360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300057,0.000005,-0.000010,1.000000;;, + 1440;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300047,-0.000002,0.000016,1.000000;;, + 1520;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300065,-0.000002,-0.000005,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300051,0.000005,0.000003,1.000000;;, + 1680;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300046,0.000004,-0.000021,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300056,-0.000003,0.000006,1.000000;;, + 1840;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300049,-0.000001,0.000003,1.000000;;, + 1920;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300052,0.000002,-0.000008,1.000000;;, + 2000;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300055,-0.000001,0.000007,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300063,0.000004,0.000005,1.000000;;, + 2160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300055,-0.000006,0.000004,1.000000;;, + 2240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300035,-0.000005,-0.000005,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300053,-0.000001,0.000010,1.000000;;, + 2400;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300064,0.000002,0.000004,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300051,-0.000006,0.000011,1.000000;;, + 2560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300082,-0.000002,-0.000012,1.000000;;, + 2640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300029,-0.000001,0.000011,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300046,-0.000002,0.000013,1.000000;;, + 2800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300031,-0.000002,0.000014,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300129,-0.000010,-0.000001,1.000000;;, + 2960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300054,0.000002,-0.000004,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300058,0.000006,-0.000007,1.000000;;, + 3120;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300048,-0.000009,0.000023,1.000000;;, + 3200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300021,0.000013,-0.000009,1.000000;;, + 3280;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300056,-0.000000,-0.000001,1.000000;;, + 3360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300068,0.000002,0.000001,1.000000;;, + 3440;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300078,-0.000014,0.000021,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300060,-0.000001,-0.000000,1.000000;;, + 3600;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300076,-0.000000,0.000011,1.000000;;, + 3680;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300021,0.000012,-0.000014,1.000000;;, + 3760;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300063,0.000003,-0.000001,1.000000;;, + 3840;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300073,-0.000002,0.000013,1.000000;;, + 3920;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300053,0.000004,-0.000008,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300080,-0.000001,0.000014,1.000000;;, + 4080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300086,-0.000009,0.000042,1.000000;;, + 4160;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300044,0.000002,-0.000028,1.000000;;, + 4240;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300059,-0.000001,-0.000010,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300069,-0.000008,0.000042,1.000000;;, + 4400;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300056,-0.000006,0.000022,1.000000;;, + 4480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,9.300056,0.000002,-0.000013,1.000000;;, + 4560;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300052,-0.000000,-0.000015,1.000000;;, + 4640;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,9.300047,-0.000003,-0.000012,1.000000;;, + 4720;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300055,-0.000005,0.000008,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,9.300055,-0.000003,-0.000036,1.000000;;, + 4960;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,9.300053,-0.000001,-0.000002,1.000000;;; + } + { Bip01_R_Finger11 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850059,0.000001,-0.000003,1.000000;;, + 80;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850061,-0.000004,0.000004,1.000000;;, + 160;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850073,0.000004,0.000004,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850068,-0.000001,0.000002,1.000000;;, + 320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850068,0.000000,0.000004,1.000000;;, + 400;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850073,0.000004,0.000001,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850047,-0.000004,-0.000011,1.000000;;, + 560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850059,-0.000003,0.000004,1.000000;;, + 640;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850069,0.000001,0.000000,1.000000;;, + 720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850069,-0.000003,-0.000000,1.000000;;, + 800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850062,0.000003,-0.000000,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850066,-0.000001,0.000004,1.000000;;, + 960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850061,-0.000002,-0.000004,1.000000;;, + 1040;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850067,0.000000,0.000001,1.000000;;, + 1120;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850071,0.000001,0.000002,1.000000;;, + 1200;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850074,-0.000001,0.000011,1.000000;;, + 1280;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850064,0.000000,-0.000003,1.000000;;, + 1360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850067,-0.000003,0.000001,1.000000;;, + 1440;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850084,0.000001,-0.000006,1.000000;;, + 1520;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850065,0.000003,0.000004,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850064,-0.000001,-0.000003,1.000000;;, + 1680;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850087,-0.000010,0.000038,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850060,-0.000001,0.000010,1.000000;;, + 1840;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850059,0.000010,-0.000017,1.000000;;, + 1920;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850066,0.000002,0.000002,1.000000;;, + 2000;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850079,-0.000004,0.000000,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850064,-0.000008,0.000001,1.000000;;, + 2160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850057,0.000004,-0.000001,1.000000;;, + 2240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850079,0.000004,0.000005,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850055,0.000003,-0.000010,1.000000;;, + 2400;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850050,0.000010,-0.000009,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850052,0.000010,-0.000012,1.000000;;, + 2560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850057,-0.000001,0.000003,1.000000;;, + 2640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850087,0.000005,-0.000009,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850062,0.000001,-0.000002,1.000000;;, + 2800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850121,-0.000019,-0.000002,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.849994,0.000003,0.000005,1.000000;;, + 2960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850060,0.000000,0.000005,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850060,-0.000005,0.000007,1.000000;;, + 3120;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850054,0.000008,-0.000009,1.000000;;, + 3200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850092,-0.000008,0.000003,1.000000;;, + 3280;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850080,-0.000001,0.000001,1.000000;;, + 3360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850073,0.000003,-0.000010,1.000000;;, + 3440;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850039,0.000007,-0.000015,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850013,0.000004,-0.000013,1.000000;;, + 3600;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850048,-0.000008,0.000004,1.000000;;, + 3680;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850091,-0.000011,0.000002,1.000000;;, + 3760;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850017,0.000005,-0.000012,1.000000;;, + 3840;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850051,-0.000000,-0.000004,1.000000;;, + 3920;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850064,-0.000007,-0.000001,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850058,-0.000002,-0.000005,1.000000;;, + 4080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850063,0.000002,-0.000028,1.000000;;, + 4160;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850079,0.000001,0.000024,1.000000;;, + 4240;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850040,0.000002,-0.000030,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850048,0.000017,-0.000079,1.000000;;, + 4400;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850065,0.000008,-0.000017,1.000000;;, + 4480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,10.850068,0.000002,0.000024,1.000000;;, + 4560;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850074,-0.000003,0.000020,1.000000;;, + 4640;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,10.850078,-0.000001,0.000023,1.000000;;, + 4720;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850074,-0.000001,0.000017,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,10.850063,0.000009,0.000012,1.000000;;, + 4960;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,10.850059,0.000001,-0.000003,1.000000;;; + } + { Bip01_R_Finger12 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207767,0.000001,-0.000003,1.000000;;, + 80;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207771,0.000001,-0.000006,1.000000;;, + 160;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207757,-0.000001,-0.000003,1.000000;;, + 240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207756,-0.000003,-0.000002,1.000000;;, + 320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207762,0.000000,-0.000007,1.000000;;, + 400;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207765,-0.000001,0.000005,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207770,0.000001,0.000002,1.000000;;, + 560;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207768,0.000000,-0.000007,1.000000;;, + 640;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207765,0.000001,0.000000,1.000000;;, + 720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207763,0.000001,0.000001,1.000000;;, + 800;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207768,-0.000003,0.000004,1.000000;;, + 880;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207760,-0.000002,-0.000001,1.000000;;, + 960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207767,0.000003,0.000003,1.000000;;, + 1040;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207764,0.000003,0.000001,1.000000;;, + 1120;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207767,0.000001,-0.000007,1.000000;;, + 1200;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207765,-0.000001,-0.000018,1.000000;;, + 1280;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207752,0.000002,-0.000019,1.000000;;, + 1360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207767,0.000003,-0.000009,1.000000;;, + 1440;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207752,0.000006,-0.000018,1.000000;;, + 1520;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207759,0.000003,-0.000014,1.000000;;, + 1600;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207762,0.000001,-0.000006,1.000000;;, + 1680;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207762,0.000009,-0.000012,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207764,0.000005,-0.000008,1.000000;;, + 1840;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207767,-0.000012,0.000006,1.000000;;, + 1920;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207767,-0.000005,0.000009,1.000000;;, + 2000;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207761,0.000007,-0.000007,1.000000;;, + 2080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207759,0.000001,0.000001,1.000000;;, + 2160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207764,-0.000011,-0.000003,1.000000;;, + 2240;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207760,-0.000006,0.000002,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207768,0.000004,-0.000001,1.000000;;, + 2400;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207767,-0.000001,0.000005,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207771,-0.000007,0.000007,1.000000;;, + 2560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207754,-0.000008,0.000019,1.000000;;, + 2640;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207768,-0.000000,-0.000003,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207767,0.000001,-0.000006,1.000000;;, + 2800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207760,0.000006,-0.000012,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207788,-0.000004,0.000004,1.000000;;, + 2960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207781,-0.000001,-0.000003,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207762,0.000004,0.000001,1.000000;;, + 3120;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207790,0.000001,-0.000008,1.000000;;, + 3200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207770,-0.000011,0.000011,1.000000;;, + 3280;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207776,-0.000010,0.000005,1.000000;;, + 3360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207766,-0.000003,0.000010,1.000000;;, + 3440;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207795,-0.000000,-0.000005,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207788,-0.000011,0.000012,1.000000;;, + 3600;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207775,0.000002,-0.000003,1.000000;;, + 3680;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207780,-0.000013,0.000009,1.000000;;, + 3760;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207794,-0.000012,0.000004,1.000000;;, + 3840;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207778,-0.000008,-0.000001,1.000000;;, + 3920;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207764,-0.000002,0.000000,1.000000;;, + 4000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207761,-0.000006,0.000001,1.000000;;, + 4080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207756,-0.000004,0.000003,1.000000;;, + 4160;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207771,0.000003,0.000013,1.000000;;, + 4240;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207773,0.000003,0.000022,1.000000;;, + 4320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207767,-0.000001,0.000026,1.000000;;, + 4400;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207769,-0.000001,0.000002,1.000000;;, + 4480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,11.207768,-0.000001,0.000013,1.000000;;, + 4560;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207754,-0.000001,-0.000008,1.000000;;, + 4640;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,11.207759,-0.000003,0.000012,1.000000;;, + 4720;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207764,0.000004,-0.000020,1.000000;;, + 4800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,11.207763,0.000001,-0.000002,1.000000;;, + 4960;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,11.207767,0.000001,-0.000003,1.000000;;; + } + { Dummy02 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;-0.928221,-0.372022,0.002089,0.000000,-0.371612,0.927434,0.042085,0.000000,-0.017595,0.038288,-0.999112,0.000000,-27.673786,-14.652106,27.738972,1.000000;;, + 80;16;-0.911893,-0.410423,0.001942,0.000000,-0.410014,0.911176,0.040585,0.000000,-0.018426,0.036213,-0.999174,0.000000,-27.803984,-14.906741,27.552347,1.000000;;, + 160;16;-0.894068,-0.447927,0.002030,0.000000,-0.447515,0.893423,0.039060,0.000000,-0.019310,0.034014,-0.999235,0.000000,-27.937048,-15.168123,27.357708,1.000000;;, + 240;16;-0.876729,-0.480982,0.001449,0.000000,-0.480732,0.876364,0.029699,0.000000,-0.015554,0.025342,-0.999558,0.000000,-28.077749,-15.463904,27.139896,1.000000;;, + 320;16;-0.858316,-0.513121,0.000186,0.000000,-0.513017,0.858149,0.019868,0.000000,-0.010355,0.016958,-0.999803,0.000000,-28.222052,-15.746859,26.922985,1.000000;;, + 400;16;-0.844044,-0.536271,-0.001682,0.000000,-0.536212,0.843896,0.017797,0.000000,-0.008125,0.015924,-0.999840,0.000000,-28.368185,-15.989561,26.722809,1.000000;;, + 480;16;-0.829903,-0.557881,-0.005424,0.000000,-0.557898,0.829793,0.013899,0.000000,-0.003253,0.014560,-0.999889,0.000000,-28.514095,-16.165241,26.556234,1.000000;;, + 560;16;-0.824385,-0.566006,-0.005093,0.000000,-0.565667,0.823504,0.043151,0.000000,-0.020230,0.038454,-0.999056,0.000000,-28.656796,-16.251249,26.439451,1.000000;;, + 640;16;-0.821005,-0.570894,-0.005540,0.000000,-0.569853,0.818838,0.069083,0.000000,-0.034903,0.059874,-0.997595,0.000000,-28.797022,-16.210737,26.392929,1.000000;;, + 720;16;-0.823503,-0.567299,-0.003918,0.000000,-0.564112,0.818106,0.111716,0.000000,-0.060171,0.094209,-0.993732,0.000000,-28.936790,-15.984868,26.446907,1.000000;;, + 800;16;-0.830397,-0.557166,-0.002518,0.000000,-0.551123,0.820709,0.150666,0.000000,-0.081880,0.126500,-0.988582,0.000000,-29.068157,-15.612783,26.578825,1.000000;;, + 880;16;-0.837220,-0.546855,-0.003339,0.000000,-0.539885,0.825545,0.164316,0.000000,-0.087101,0.139372,-0.986402,0.000000,-29.186691,-15.091745,26.783831,1.000000;;, + 960;16;-0.851299,-0.524663,-0.004269,0.000000,-0.517113,0.837616,0.176049,0.000000,-0.088790,0.152078,-0.984372,0.000000,-29.284082,-14.482901,27.028332,1.000000;;, + 1040;16;-0.881730,-0.471150,0.023876,0.000000,-0.460801,0.870997,0.170374,0.000000,-0.101067,0.139222,-0.985090,0.000000,-29.349228,-13.847182,27.284319,1.000000;;, + 1120;16;-0.924826,-0.375312,0.061950,0.000000,-0.359915,0.916074,0.176831,0.000000,-0.123117,0.141241,-0.982290,0.000000,-29.390091,-13.188616,27.543690,1.000000;;, + 1200;16;-0.953882,-0.285967,0.091281,0.000000,-0.264746,0.944765,0.193205,0.000000,-0.141489,0.160129,-0.976903,0.000000,-29.408573,-12.541369,27.790316,1.000000;;, + 1280;16;-0.973788,-0.194748,0.117513,0.000000,-0.166942,0.962843,0.212280,0.000000,-0.154488,0.187098,-0.970117,0.000000,-29.412472,-11.880296,28.029623,1.000000;;, + 1360;16;-0.984386,-0.107567,0.139334,0.000000,-0.074127,0.971274,0.226124,0.000000,-0.159654,0.212265,-0.964082,0.000000,-29.409801,-11.187845,28.261599,1.000000;;, + 1440;16;-0.987640,-0.032138,0.153410,0.000000,0.005524,0.971008,0.238984,0.000000,-0.156642,0.236878,-0.958828,0.000000,-29.400465,-10.475192,28.482176,1.000000;;, + 1520;16;-0.987774,0.018235,0.154822,0.000000,0.057435,0.965843,0.252683,0.000000,-0.144926,0.258485,-0.955082,0.000000,-29.386217,-9.746704,28.688866,1.000000;;, + 1600;16;-0.987223,0.055913,0.149211,0.000000,0.094826,0.958698,0.268152,0.000000,-0.128055,0.278875,-0.951751,0.000000,-29.368801,-9.006860,28.879656,1.000000;;, + 1680;16;-0.986282,0.088304,0.139466,0.000000,0.125685,0.949444,0.287680,0.000000,-0.107012,0.301263,-0.947517,0.000000,-29.349707,-8.260389,29.053083,1.000000;;, + 1760;16;-0.984677,0.118243,0.128176,0.000000,0.152614,0.939945,0.305308,0.000000,-0.084378,0.320191,-0.943588,0.000000,-29.330469,-7.512198,29.208227,1.000000;;, + 1840;16;-0.981517,0.150351,0.118402,0.000000,0.180808,0.931279,0.316272,0.000000,-0.062714,0.331834,-0.941251,0.000000,-29.312498,-6.767277,29.344717,1.000000;;, + 1920;16;-0.976290,0.186521,0.109854,0.000000,0.212371,0.923573,0.319234,0.000000,-0.041914,0.334995,-0.941287,0.000000,-29.296946,-6.030762,29.462757,1.000000;;, + 2000;16;-0.967245,0.231887,0.103275,0.000000,0.252812,0.916654,0.309568,0.000000,-0.022883,0.325537,-0.945252,0.000000,-29.285093,-5.307709,29.563105,1.000000;;, + 2080;16;-0.954827,0.281060,0.096486,0.000000,0.297109,0.908985,0.292358,0.000000,-0.005534,0.307818,-0.951429,0.000000,-29.278000,-4.603338,29.647009,1.000000;;, + 2160;16;-0.939254,0.331755,0.087974,0.000000,0.343063,0.899678,0.269978,0.000000,0.010418,0.283758,-0.958839,0.000000,-29.269199,-3.928405,29.714540,1.000000;;, + 2240;16;-0.921715,0.379808,0.078662,0.000000,0.387158,0.888636,0.245836,0.000000,0.023468,0.257045,-0.966114,0.000000,-29.282276,-3.270983,29.772947,1.000000;;, + 2320;16;-0.904576,0.420547,0.069868,0.000000,0.425042,0.877045,0.223901,0.000000,0.032884,0.232233,-0.972104,0.000000,-29.346003,-2.617593,29.828417,1.000000;;, + 2400;16;-0.888278,0.455005,0.062707,0.000000,0.457681,0.865378,0.204078,0.000000,0.038591,0.209978,-0.976944,0.000000,-29.436523,-1.981518,29.881910,1.000000;;, + 2480;16;-0.871675,0.486327,0.060564,0.000000,0.488470,0.852122,0.187846,0.000000,0.039746,0.193324,-0.980329,0.000000,-29.557138,-1.359871,29.937998,1.000000;;, + 2560;16;-0.861675,0.504099,0.058305,0.000000,0.505993,0.844767,0.174182,0.000000,0.038550,0.179590,-0.982986,0.000000,-29.655882,-0.786586,29.994652,1.000000;;, + 2640;16;-0.850559,0.522404,0.060360,0.000000,0.524798,0.835842,0.161105,0.000000,0.033710,0.168706,-0.985090,0.000000,-29.685301,-0.287678,30.054073,1.000000;;, + 2720;16;-0.839227,0.540056,0.063543,0.000000,0.543025,0.826154,0.150310,0.000000,0.028680,0.160649,-0.986595,0.000000,-29.639238,0.112493,30.116144,1.000000;;, + 2800;16;-0.831739,0.550993,0.067944,0.000000,0.554706,0.819822,0.142099,0.000000,0.022593,0.155878,-0.987518,0.000000,-29.481970,0.381362,30.180090,1.000000;;, + 2880;16;-0.824607,0.560841,0.074037,0.000000,0.565469,0.813379,0.136600,0.000000,0.016391,0.154507,-0.987856,0.000000,-29.257454,0.515694,30.246803,1.000000;;, + 2960;16;-0.823079,0.564125,0.065599,0.000000,0.567362,0.811610,0.139247,0.000000,0.025312,0.151829,-0.988082,0.000000,-28.989264,0.492861,30.314617,1.000000;;, + 3040;16;-0.821983,0.566438,0.059090,0.000000,0.568494,0.809885,0.144570,0.000000,0.034034,0.152426,-0.987728,0.000000,-28.700897,0.341238,30.383587,1.000000;;, + 3120;16;-0.826104,0.559909,0.063667,0.000000,0.562920,0.814747,0.138952,0.000000,0.025928,0.150629,-0.988250,0.000000,-28.413420,0.076273,30.454477,1.000000;;, + 3200;16;-0.836777,0.543459,0.066758,0.000000,0.547203,0.825715,0.136979,0.000000,0.019320,0.151151,-0.988322,0.000000,-28.155458,-0.285411,30.520918,1.000000;;, + 3280;16;-0.851590,0.520256,0.064253,0.000000,0.524081,0.842254,0.126286,0.000000,0.011583,0.141218,-0.989911,0.000000,-27.962389,-0.726958,30.578775,1.000000;;, + 3360;16;-0.869128,0.490799,0.061101,0.000000,0.494557,0.861031,0.118490,0.000000,0.005545,0.133201,-0.991073,0.000000,-27.836496,-1.234247,30.624882,1.000000;;, + 3440;16;-0.887892,0.456440,0.057541,0.000000,0.460052,0.880657,0.113116,0.000000,0.000957,0.126907,-0.991914,0.000000,-27.802397,-1.789792,30.654890,1.000000;;, + 3520;16;-0.907077,0.417519,0.053751,0.000000,0.420957,0.900416,0.109757,0.000000,-0.002573,0.122185,-0.992504,0.000000,-27.830305,-2.386317,30.668243,1.000000;;, + 3600;16;-0.925802,0.374125,0.054043,0.000000,0.377976,0.918066,0.119538,0.000000,-0.004893,0.131095,-0.991358,0.000000,-27.902847,-3.010064,30.663122,1.000000;;, + 3680;16;-0.943410,0.327208,0.053964,0.000000,0.331539,0.934358,0.130601,0.000000,-0.007688,0.141101,-0.989965,0.000000,-28.007349,-3.661772,30.639570,1.000000;;, + 3760;16;-0.959327,0.277680,0.050859,0.000000,0.282077,0.950027,0.133722,0.000000,-0.011186,0.142630,-0.989713,0.000000,-28.129053,-4.338365,30.598248,1.000000;;, + 3840;16;-0.973079,0.225510,0.047554,0.000000,0.229995,0.963420,0.137565,0.000000,-0.014792,0.144799,-0.989350,0.000000,-28.256105,-5.037010,30.537418,1.000000;;, + 3920;16;-0.984303,0.172439,0.037585,0.000000,0.175741,0.977218,0.118996,0.000000,-0.016209,0.123734,-0.992183,0.000000,-28.375837,-5.754852,30.456379,1.000000;;, + 4000;16;-0.992648,0.117681,0.028285,0.000000,0.119956,0.987680,0.100497,0.000000,-0.016110,0.103151,-0.994535,0.000000,-28.475786,-6.488847,30.354843,1.000000;;, + 4080;16;-0.997899,0.061722,0.019677,0.000000,0.063128,0.994679,0.081416,0.000000,-0.014548,0.082487,-0.996486,0.000000,-28.540384,-7.235955,30.232977,1.000000;;, + 4160;16;-0.999906,0.006143,0.012246,0.000000,0.006892,0.998048,0.062063,0.000000,-0.011841,0.062142,-0.997997,0.000000,-28.565617,-7.992917,30.090918,1.000000;;, + 4240;16;-0.998890,-0.045932,0.010470,0.000000,-0.045145,0.996802,0.065936,0.000000,-0.013465,0.065390,-0.997769,0.000000,-28.537481,-8.756502,29.929228,1.000000;;, + 4320;16;-0.995413,-0.095229,0.009188,0.000000,-0.094366,0.993104,0.069573,0.000000,-0.015750,0.068387,-0.997534,0.000000,-28.470556,-9.522673,29.747852,1.000000;;, + 4400;16;-0.991651,-0.128660,0.008704,0.000000,-0.127798,0.989535,0.066988,0.000000,-0.017232,0.065316,-0.997716,0.000000,-28.371780,-10.287396,29.547218,1.000000;;, + 4480;16;-0.986949,-0.160784,0.008958,0.000000,-0.159894,0.985052,0.064088,0.000000,-0.019128,0.061819,-0.997904,0.000000,-28.251011,-11.046824,29.328005,1.000000;;, + 4560;16;-0.980691,-0.195325,0.009659,0.000000,-0.194402,0.979051,0.060564,0.000000,-0.021286,0.057517,-0.998118,0.000000,-28.117359,-11.797178,29.091358,1.000000;;, + 4640;16;-0.971493,-0.236834,0.010537,0.000000,-0.235888,0.970131,0.056592,0.000000,-0.023625,0.052493,-0.998342,0.000000,-27.979946,-12.534884,28.838869,1.000000;;, + 4720;16;-0.965536,-0.259803,0.015587,0.000000,-0.258707,0.964567,0.051776,0.000000,-0.028486,0.045959,-0.998537,0.000000,-27.853834,-13.252464,28.574549,1.000000;;, + 4800;16;-0.959397,-0.281208,0.021883,0.000000,-0.279994,0.958874,0.046525,0.000000,-0.034066,0.038509,-0.998677,0.000000,-27.730272,-13.958670,28.295168,1.000000;;, + 4960;16;-0.928221,-0.372022,0.002089,0.000000,-0.371612,0.927434,0.042085,0.000000,-0.017595,0.038288,-0.999112,0.000000,-27.673786,-14.652106,27.738972,1.000000;;; + } + { Bip01_L_Thigh } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.942163,-0.335154,0.000000,0.000000,0.335154,0.942163,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231491,0.000003,-0.000001,1.000000;;, + 80;16;0.946470,-0.322791,0.000000,0.000000,0.322791,0.946470,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231499,0.000009,-0.000001,1.000000;;, + 160;16;0.950613,-0.310379,0.000000,0.000000,0.310379,0.950613,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231491,0.000003,-0.000001,1.000000;;, + 240;16;0.952025,-0.306021,-0.000000,0.000000,0.306021,0.952025,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,0.000002,-0.000002,1.000000;;, + 320;16;0.953424,-0.301634,-0.000000,0.000000,0.301634,0.953424,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231491,-0.000004,0.000001,1.000000;;, + 400;16;0.949301,-0.314369,0.000000,0.000000,0.314369,0.949301,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000008,-0.000000,1.000000;;, + 480;16;0.944996,-0.327081,0.000000,0.000000,0.327081,0.944996,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000004,-0.000001,1.000000;;, + 560;16;0.930883,-0.365318,-0.000000,0.000000,0.365318,0.930883,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000003,0.000003,1.000000;;, + 640;16;0.915212,-0.402971,0.000000,0.000000,0.402971,0.915212,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000010,-0.000001,1.000000;;, + 720;16;0.894055,-0.447956,0.000000,0.000000,0.447956,0.894055,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231522,0.000003,-0.000001,1.000000;;, + 800;16;0.870688,-0.491835,-0.000000,0.000000,0.491835,0.870688,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231522,-0.000005,0.000002,1.000000;;, + 880;16;0.855169,-0.518349,-0.000000,0.000000,0.518349,0.855169,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,-0.000015,-0.000003,1.000000;;, + 960;16;0.838845,-0.544371,-0.000000,0.000000,0.544371,0.838845,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,-0.000029,-0.000002,1.000000;;, + 1040;16;0.805776,-0.592221,-0.000000,0.000000,0.592221,0.805776,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231499,-0.000011,-0.000003,1.000000;;, + 1120;16;0.739182,-0.673506,0.000000,0.000000,0.673506,0.739182,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,-0.000016,-0.000002,1.000000;;, + 1200;16;0.662180,-0.749345,-0.000000,0.000000,0.749345,0.662180,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000011,-0.000002,1.000000;;, + 1280;16;0.580639,-0.814161,0.000000,0.000000,0.814161,0.580639,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,-0.000018,-0.000005,1.000000;;, + 1360;16;0.512479,-0.858699,0.000000,0.000000,0.858699,0.512479,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231483,-0.000010,-0.000001,1.000000;;, + 1440;16;0.468474,-0.883477,0.000000,0.000000,0.883477,0.468474,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231483,-0.000011,-0.000002,1.000000;;, + 1520;16;0.470332,-0.882490,-0.000000,0.000000,0.882490,0.470332,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000007,-0.000001,1.000000;;, + 1600;16;0.499227,-0.866471,0.000000,0.000000,0.866471,0.499227,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,0.000019,0.000001,1.000000;;, + 1680;16;0.544114,-0.839011,0.000000,0.000000,0.839011,0.544114,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231483,-0.000001,-0.000007,1.000000;;, + 1760;16;0.595785,-0.803144,0.000000,0.000000,0.803144,0.595785,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000007,0.000001,1.000000;;, + 1840;16;0.642066,-0.766650,0.000000,0.000000,0.766650,0.642066,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231491,0.000007,0.000005,1.000000;;, + 1920;16;0.685771,-0.727817,0.000000,0.000000,0.727817,0.685771,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,0.000002,-0.000004,1.000000;;, + 2000;16;0.725507,-0.688215,-0.000000,0.000000,0.688215,0.725507,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231514,0.000007,0.000003,1.000000;;, + 2080;16;0.762653,-0.646808,-0.000000,0.000000,0.646808,0.762653,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231522,0.000012,0.000005,1.000000;;, + 2160;16;0.800105,-0.599860,0.000000,0.000000,0.599860,0.800105,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231491,-0.000002,-0.000001,1.000000;;, + 2240;16;0.831071,-0.556167,-0.000000,0.000000,0.556167,0.831071,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231506,-0.000007,0.000002,1.000000;;, + 2320;16;0.851740,-0.523965,-0.000000,0.000000,0.523965,0.851740,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,0.000009,0.000002,1.000000;;, + 2400;16;0.862764,-0.505606,0.000000,0.000000,0.505606,0.862764,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231514,0.000021,0.000003,1.000000;;, + 2480;16;0.858597,-0.512651,0.000000,0.000000,0.512651,0.858597,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,-0.000001,0.000002,1.000000;;, + 2560;16;0.851861,-0.523767,-0.000000,0.000000,0.523767,0.851861,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000004,0.000000,1.000000;;, + 2640;16;0.834410,-0.551144,0.000000,0.000000,0.551144,0.834410,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231491,0.000018,0.000002,1.000000;;, + 2720;16;0.816079,-0.577940,-0.000000,0.000000,0.577940,0.816079,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231506,0.000016,-0.000001,1.000000;;, + 2800;16;0.795822,-0.605531,0.000000,0.000000,0.605531,0.795822,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,0.000002,0.000004,1.000000;;, + 2880;16;0.774632,-0.632412,-0.000000,0.000000,0.632413,0.774632,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,-0.000004,-0.000000,1.000000;;, + 2960;16;0.794443,-0.607340,-0.000000,0.000000,0.607339,0.794442,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,-0.000008,0.000003,1.000000;;, + 3040;16;0.813442,-0.581647,-0.000000,0.000000,0.581647,0.813442,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231529,0.000008,-0.000002,1.000000;;, + 3120;16;0.778247,-0.627958,0.000000,0.000000,0.627958,0.778247,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,0.000010,-0.000002,1.000000;;, + 3200;16;0.754281,-0.656552,-0.000000,0.000000,0.656552,0.754281,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231537,0.000012,0.000006,1.000000;;, + 3280;16;0.743273,-0.668988,-0.000000,0.000000,0.668988,0.743273,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231522,0.000008,0.000001,1.000000;;, + 3360;16;0.740677,-0.671861,0.000000,0.000000,0.671862,0.740677,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,0.000010,0.000003,1.000000;;, + 3440;16;0.745040,-0.667020,0.000000,0.000000,0.667020,0.745040,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231514,-0.000006,-0.000000,1.000000;;, + 3520;16;0.755634,-0.654994,0.000000,0.000000,0.654994,0.755634,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231529,0.000022,0.000002,1.000000;;, + 3600;16;0.767893,-0.640578,-0.000000,0.000000,0.640578,0.767893,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231529,-0.000014,-0.000002,1.000000;;, + 3680;16;0.784524,-0.620099,-0.000000,0.000000,0.620099,0.784524,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231529,0.000019,0.000003,1.000000;;, + 3760;16;0.802723,-0.596352,0.000000,0.000000,0.596352,0.802724,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231522,0.000000,-0.000002,1.000000;;, + 3840;16;0.823599,-0.567172,0.000000,0.000000,0.567172,0.823599,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231514,-0.000001,0.000000,1.000000;;, + 3920;16;0.847102,-0.531430,-0.000000,0.000000,0.531430,0.847102,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231529,0.000020,-0.000001,1.000000;;, + 4000;16;0.871324,-0.490708,0.000000,0.000000,0.490708,0.871324,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,-0.000010,-0.000002,1.000000;;, + 4080;16;0.895648,-0.444764,-0.000000,0.000000,0.444764,0.895648,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231522,0.000034,-0.000001,1.000000;;, + 4160;16;0.918115,-0.396313,-0.000000,0.000000,0.396313,0.918115,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000014,0.000001,1.000000;;, + 4240;16;0.935408,-0.353571,0.000000,0.000000,0.353571,0.935408,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000005,0.000003,1.000000;;, + 4320;16;0.949647,-0.313321,0.000000,0.000000,0.313321,0.949647,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,-0.000011,-0.000001,1.000000;;, + 4400;16;0.953711,-0.300723,0.000000,0.000000,0.300723,0.953711,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231483,-0.000000,0.000001,1.000000;;, + 4480;16;0.957058,-0.289897,0.000000,0.000000,0.289897,0.957058,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000009,-0.000003,1.000000;;, + 4560;16;0.961769,-0.273862,0.000000,0.000000,0.273862,0.961769,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231483,-0.000011,-0.000001,1.000000;;, + 4640;16;0.969896,-0.243518,0.000000,0.000000,0.243518,0.969896,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231491,0.000011,-0.000001,1.000000;;, + 4720;16;0.944640,-0.328109,0.000000,0.000000,0.328109,0.944640,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,0.000017,0.000000,1.000000;;, + 4800;16;0.912034,-0.410114,-0.000000,0.000000,0.410114,0.912034,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231491,-0.000008,-0.000001,1.000000;;, + 4960;16;0.942163,-0.335154,0.000000,0.000000,0.335154,0.942163,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231491,0.000003,-0.000001,1.000000;;; + } + { Bip01_L_Calf } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.819935,0.566355,0.083354,0.000000,-0.566770,0.823611,-0.020897,0.000000,-0.080486,-0.030108,0.996301,0.000000,119.231514,0.000010,0.000002,1.000000;;, + 80;16;0.819133,0.567125,0.085960,0.000000,-0.567930,0.822898,-0.017163,0.000000,-0.080470,-0.034761,0.996151,0.000000,119.231506,-0.000013,-0.000002,1.000000;;, + 160;16;0.820633,0.564575,0.088416,0.000000,-0.565741,0.824469,-0.013669,0.000000,-0.080614,-0.038804,0.995990,0.000000,119.231506,0.000009,-0.000000,1.000000;;, + 240;16;0.821535,0.563385,0.087619,0.000000,-0.564252,0.825429,-0.016908,0.000000,-0.081849,-0.035548,0.996011,0.000000,119.231499,-0.000001,-0.000001,1.000000;;, + 320;16;0.826038,0.557042,0.085821,0.000000,-0.557428,0.829943,-0.021626,0.000000,-0.083273,-0.029975,0.996076,0.000000,119.231529,0.000014,-0.000001,1.000000;;, + 400;16;0.834533,0.544288,0.085466,0.000000,-0.544571,0.838426,-0.022024,0.000000,-0.083644,-0.028163,0.996098,0.000000,119.231514,0.000008,0.000000,1.000000;;, + 480;16;0.850094,0.520000,0.083306,0.000000,-0.519840,0.853889,-0.025319,0.000000,-0.084300,-0.021782,0.996202,0.000000,119.231506,0.000009,0.000001,1.000000;;, + 560;16;0.875466,0.479959,0.056556,0.000000,-0.481614,0.876161,0.019734,0.000000,-0.040081,-0.044515,0.998204,0.000000,119.231499,0.000006,-0.000002,1.000000;;, + 640;16;0.906159,0.422411,0.021083,0.000000,-0.422892,0.904206,0.059780,0.000000,0.006188,-0.063086,0.997989,0.000000,119.231506,0.000006,0.000002,1.000000;;, + 720;16;0.936240,0.345371,-0.064606,0.000000,-0.336500,0.934263,0.117986,0.000000,0.101108,-0.088723,0.990911,0.000000,119.231529,-0.000006,-0.000001,1.000000;;, + 800;16;0.955721,0.242467,-0.166756,0.000000,-0.216573,0.963188,0.159265,0.000000,0.199234,-0.116098,0.973050,0.000000,119.231514,-0.000003,-0.000002,1.000000;;, + 880;16;0.966320,0.105838,-0.234571,0.000000,-0.068425,0.984372,0.162267,0.000000,0.248079,-0.140751,0.958460,0.000000,119.231522,0.000002,-0.000000,1.000000;;, + 960;16;0.948597,-0.080312,-0.306127,0.000000,0.130235,0.980631,0.146295,0.000000,0.288448,-0.178643,0.940683,0.000000,119.231499,0.000012,0.000000,1.000000;;, + 1040;16;0.955816,-0.074898,-0.284263,0.000000,0.118281,0.983254,0.138643,0.000000,0.269118,-0.166140,0.948669,0.000000,119.231499,0.000002,0.000001,1.000000;;, + 1120;16;0.969026,-0.051502,-0.241531,0.000000,0.081517,0.989903,0.115966,0.000000,0.233120,-0.132063,0.963439,0.000000,119.231522,0.000004,-0.000005,1.000000;;, + 1200;16;0.981818,0.002370,-0.189811,0.000000,0.011582,0.997311,0.072359,0.000000,0.189472,-0.073242,0.979151,0.000000,119.231506,0.000005,0.000003,1.000000;;, + 1280;16;0.987825,0.070976,-0.138435,0.000000,-0.068788,0.997420,0.020535,0.000000,0.139535,-0.010763,0.990159,0.000000,119.231514,0.000006,-0.000002,1.000000;;, + 1360;16;0.985606,0.137460,-0.098419,0.000000,-0.140534,0.989760,-0.024988,0.000000,0.093977,0.038460,0.994831,0.000000,119.231499,0.000006,0.000002,1.000000;;, + 1440;16;0.976475,0.203883,-0.070209,0.000000,-0.208187,0.976208,-0.060640,0.000000,0.056176,0.073830,0.995687,0.000000,119.231514,0.000014,-0.000001,1.000000;;, + 1520;16;0.962520,0.265033,-0.057563,0.000000,-0.268819,0.960425,-0.072939,0.000000,0.035953,0.085679,0.995674,0.000000,119.231514,0.000005,0.000001,1.000000;;, + 1600;16;0.944932,0.323352,-0.050465,0.000000,-0.326285,0.942765,-0.068793,0.000000,0.025332,0.081471,0.996354,0.000000,119.231529,-0.000013,-0.000005,1.000000;;, + 1680;16;0.922942,0.382664,-0.041779,0.000000,-0.384487,0.921669,-0.051931,0.000000,0.018635,0.063993,0.997776,0.000000,119.231483,0.000003,0.000014,1.000000;;, + 1760;16;0.899830,0.435313,-0.028432,0.000000,-0.436035,0.899495,-0.027961,0.000000,0.013403,0.037557,0.999205,0.000000,119.231468,0.000009,0.000009,1.000000;;, + 1840;16;0.878910,0.476864,-0.010806,0.000000,-0.476944,0.878910,-0.006518,0.000000,0.006389,0.010883,0.999920,0.000000,119.231483,-0.000007,-0.000001,1.000000;;, + 1920;16;0.861739,0.507287,0.008100,0.000000,-0.507347,0.861688,0.009672,0.000000,-0.002073,-0.012445,0.999920,0.000000,119.231506,0.000019,0.000005,1.000000;;, + 2000;16;0.850935,0.524778,0.022754,0.000000,-0.525134,0.850905,0.013979,0.000000,-0.012025,-0.023844,0.999643,0.000000,119.231506,-0.000006,-0.000003,1.000000;;, + 2080;16;0.845055,0.533679,0.032674,0.000000,-0.534274,0.845214,0.012795,0.000000,-0.020789,-0.028269,0.999384,0.000000,119.231529,-0.000003,-0.000003,1.000000;;, + 2160;16;0.843436,0.535881,0.038038,0.000000,-0.536569,0.843795,0.010216,0.000000,-0.026622,-0.029027,0.999224,0.000000,119.231483,0.000012,0.000003,1.000000;;, + 2240;16;0.845095,0.533109,0.040127,0.000000,-0.533791,0.845579,0.007924,0.000000,-0.029706,-0.028116,0.999163,0.000000,119.231514,0.000031,0.000008,1.000000;;, + 2320;16;0.848386,0.527731,0.041726,0.000000,-0.528451,0.848928,0.007796,0.000000,-0.031308,-0.028665,0.999099,0.000000,119.231499,-0.000006,0.000001,1.000000;;, + 2400;16;0.853963,0.518533,0.043240,0.000000,-0.519361,0.854496,0.009968,0.000000,-0.031780,-0.030969,0.999015,0.000000,119.231499,0.000006,-0.000000,1.000000;;, + 2480;16;0.864707,0.500080,0.046927,0.000000,-0.501277,0.865103,0.017833,0.000000,-0.031679,-0.038943,0.998739,0.000000,119.231514,0.000021,0.000004,1.000000;;, + 2560;16;0.871883,0.487224,0.049326,0.000000,-0.488704,0.872126,0.023758,0.000000,-0.031443,-0.044820,0.998500,0.000000,119.231491,0.000017,0.000005,1.000000;;, + 2640;16;0.884353,0.464053,0.050747,0.000000,-0.465906,0.884188,0.033806,0.000000,-0.029182,-0.053540,0.998139,0.000000,119.231514,0.000005,0.000001,1.000000;;, + 2720;16;0.896219,0.440584,0.051742,0.000000,-0.442796,0.895536,0.044134,0.000000,-0.026892,-0.062465,0.997685,0.000000,119.231506,0.000008,0.000002,1.000000;;, + 2800;16;0.906430,0.419224,0.051341,0.000000,-0.421676,0.905154,0.053716,0.000000,-0.023953,-0.070339,0.997236,0.000000,119.231491,-0.000000,0.000001,1.000000;;, + 2880;16;0.916137,0.397674,0.050472,0.000000,-0.400321,0.914169,0.063547,0.000000,-0.020869,-0.078422,0.996702,0.000000,119.231491,0.000012,0.000003,1.000000;;, + 2960;16;0.937630,0.345753,0.036129,0.000000,-0.347484,0.935211,0.068081,0.000000,-0.010249,-0.076389,0.997025,0.000000,119.231522,0.000028,-0.000003,1.000000;;, + 3040;16;0.955974,0.292651,0.021675,0.000000,-0.293452,0.953258,0.072014,0.000000,0.000413,-0.075204,0.997168,0.000000,119.231514,-0.000004,0.000002,1.000000;;, + 3120;16;0.942333,0.333838,0.023695,0.000000,-0.334677,0.940153,0.064063,0.000000,-0.000890,-0.068299,0.997665,0.000000,119.231514,-0.000003,0.000001,1.000000;;, + 3200;16;0.930563,0.365233,0.025652,0.000000,-0.366128,0.928602,0.060407,0.000000,-0.001758,-0.065605,0.997844,0.000000,119.231499,-0.000005,-0.000004,1.000000;;, + 3280;16;0.931320,0.363275,0.025978,0.000000,-0.364137,0.930129,0.047574,0.000000,-0.006880,-0.053766,0.998530,0.000000,119.231514,-0.000016,-0.000003,1.000000;;, + 3360;16;0.934368,0.355316,0.026583,0.000000,-0.356132,0.933653,0.038251,0.000000,-0.011228,-0.045208,0.998915,0.000000,119.231506,0.000000,-0.000001,1.000000;;, + 3440;16;0.939233,0.342190,0.027342,0.000000,-0.342963,0.938808,0.031861,0.000000,-0.014766,-0.039302,0.999118,0.000000,119.231491,0.000022,0.000001,1.000000;;, + 3520;16;0.945582,0.324161,0.028189,0.000000,-0.324910,0.945330,0.028018,0.000000,-0.017565,-0.035652,0.999210,0.000000,119.231483,-0.000023,-0.000004,1.000000;;, + 3600;16;0.944105,0.328308,0.029650,0.000000,-0.329292,0.943430,0.038819,0.000000,-0.015227,-0.046413,0.998806,0.000000,119.231491,0.000031,0.000003,1.000000;;, + 3680;16;0.944000,0.328443,0.031452,0.000000,-0.329694,0.942706,0.051065,0.000000,-0.012878,-0.058575,0.998200,0.000000,119.231499,-0.000021,-0.000000,1.000000;;, + 3760;16;0.940374,0.338217,0.036142,0.000000,-0.339794,0.938901,0.054819,0.000000,-0.015393,-0.063831,0.997842,0.000000,119.231499,-0.000012,0.000000,1.000000;;, + 3840;16;0.937802,0.344730,0.041095,0.000000,-0.346695,0.936131,0.058841,0.000000,-0.018186,-0.069429,0.997421,0.000000,119.231499,0.000010,-0.000001,1.000000;;, + 3920;16;0.939902,0.338297,0.046256,0.000000,-0.340073,0.939626,0.038111,0.000000,-0.030570,-0.051551,0.998203,0.000000,119.231522,-0.000021,0.000001,1.000000;;, + 4000;16;0.942779,0.329510,0.050891,0.000000,-0.330734,0.943560,0.017611,0.000000,-0.042216,-0.033434,0.998549,0.000000,119.231476,0.000003,0.000002,1.000000;;, + 4080;16;0.946381,0.318334,0.055010,0.000000,-0.318669,0.947862,-0.002804,0.000000,-0.053034,-0.014877,0.998482,0.000000,119.231506,-0.000026,0.000003,1.000000;;, + 4160;16;0.950159,0.306179,0.058753,0.000000,-0.305398,0.951969,-0.022063,0.000000,-0.062687,0.003020,0.998029,0.000000,119.231491,0.000031,0.000001,1.000000;;, + 4240;16;0.949908,0.306152,0.062812,0.000000,-0.305789,0.951972,-0.015556,0.000000,-0.064557,-0.004431,0.997904,0.000000,119.231514,0.000023,0.000002,1.000000;;, + 4320;16;0.949171,0.307449,0.067452,0.000000,-0.307626,0.951474,-0.008013,0.000000,-0.066642,-0.013145,0.997690,0.000000,119.231491,0.000027,0.000001,1.000000;;, + 4400;16;0.943648,0.323457,0.070034,0.000000,-0.323349,0.946188,-0.013198,0.000000,-0.070534,-0.010191,0.997457,0.000000,119.231491,0.000006,-0.000000,1.000000;;, + 4480;16;0.937464,0.340343,0.072989,0.000000,-0.339952,0.940268,-0.018100,0.000000,-0.074789,-0.007844,0.997169,0.000000,119.231483,0.000030,0.000001,1.000000;;, + 4560;16;0.931869,0.354706,0.076179,0.000000,-0.353973,0.934963,-0.023376,0.000000,-0.079516,-0.005182,0.996820,0.000000,119.231483,-0.000005,0.000001,1.000000;;, + 4640;16;0.928705,0.362194,0.079510,0.000000,-0.361018,0.932101,-0.029214,0.000000,-0.084692,-0.001573,0.996406,0.000000,119.231506,-0.000001,0.000004,1.000000;;, + 4720;16;0.876284,0.474843,0.081553,0.000000,-0.475470,0.879639,-0.012791,0.000000,-0.077811,-0.027567,0.996587,0.000000,119.231522,-0.000039,-0.000003,1.000000;;, + 4800;16;0.832169,0.546757,0.092472,0.000000,-0.549113,0.835748,0.000044,0.000000,-0.077259,-0.050814,0.995715,0.000000,119.231468,-0.000006,0.000000,1.000000;;, + 4960;16;0.819935,0.566355,0.083354,0.000000,-0.566770,0.823611,-0.020897,0.000000,-0.080486,-0.030108,0.996301,0.000000,119.231514,0.000010,0.000002,1.000000;;; + } + { Bip01_L_Foot } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423233,34.577133,0.000000,1.000000;;, + 80;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423252,34.577145,-0.000001,1.000000;;, + 160;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423252,34.577126,0.000001,1.000000;;, + 240;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423248,34.577133,0.000002,1.000000;;, + 320;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423239,34.577137,-0.000002,1.000000;;, + 400;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423252,34.577129,-0.000002,1.000000;;, + 480;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423250,34.577129,-0.000000,1.000000;;, + 560;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423246,34.577141,-0.000001,1.000000;;, + 640;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423258,34.577145,-0.000001,1.000000;;, + 720;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423256,34.577141,-0.000000,1.000000;;, + 800;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423233,34.577141,-0.000003,1.000000;;, + 880;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423244,34.577141,0.000001,1.000000;;, + 960;16;0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423248,34.577122,0.000002,1.000000;;, + 1040;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423252,34.577137,0.000001,1.000000;;, + 1120;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423254,34.577129,0.000004,1.000000;;, + 1200;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423241,34.577129,0.000001,1.000000;;, + 1280;16;0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423254,34.577145,0.000002,1.000000;;, + 1360;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423235,34.577141,-0.000001,1.000000;;, + 1440;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423248,34.577137,-0.000001,1.000000;;, + 1520;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423246,34.577137,-0.000001,1.000000;;, + 1600;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423252,34.577145,0.000002,1.000000;;, + 1680;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423256,34.577141,-0.000003,1.000000;;, + 1760;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423248,34.577129,-0.000001,1.000000;;, + 1840;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423246,34.577129,-0.000005,1.000000;;, + 1920;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423241,34.577141,0.000002,1.000000;;, + 2000;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423250,34.577148,-0.000004,1.000000;;, + 2080;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423260,34.577133,-0.000002,1.000000;;, + 2160;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423248,34.577152,0.000005,1.000000;;, + 2240;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423265,34.577129,-0.000001,1.000000;;, + 2320;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423248,34.577137,0.000001,1.000000;;, + 2400;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423250,34.577148,0.000004,1.000000;;, + 2480;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423260,34.577156,0.000003,1.000000;;, + 2560;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423262,34.577137,-0.000002,1.000000;;, + 2640;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423246,34.577126,0.000000,1.000000;;, + 2720;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423256,34.577145,0.000001,1.000000;;, + 2800;16;0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423262,34.577152,-0.000001,1.000000;;, + 2880;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423254,34.577122,0.000002,1.000000;;, + 2960;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423243,34.577114,-0.000001,1.000000;;, + 3040;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423254,34.577148,0.000003,1.000000;;, + 3120;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423237,34.577110,-0.000001,1.000000;;, + 3200;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423252,34.577164,-0.000002,1.000000;;, + 3280;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423246,34.577133,0.000000,1.000000;;, + 3360;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423244,34.577129,0.000000,1.000000;;, + 3440;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423239,34.577133,0.000002,1.000000;;, + 3520;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423237,34.577118,0.000001,1.000000;;, + 3600;16;0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423250,34.577106,0.000001,1.000000;;, + 3680;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423250,34.577160,0.000002,1.000000;;, + 3760;16;-0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423243,34.577160,-0.000000,1.000000;;, + 3840;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423256,34.577129,-0.000001,1.000000;;, + 3920;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423256,34.577160,-0.000001,1.000000;;, + 4000;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423258,34.577137,-0.000001,1.000000;;, + 4080;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423260,34.577156,-0.000002,1.000000;;, + 4160;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423262,34.577137,-0.000001,1.000000;;, + 4240;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423237,34.577126,-0.000003,1.000000;;, + 4320;16;-0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423239,34.577114,-0.000001,1.000000;;, + 4400;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423233,34.577114,0.000001,1.000000;;, + 4480;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423250,34.577129,-0.000000,1.000000;;, + 4560;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423254,34.577110,-0.000006,1.000000;;, + 4640;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423250,34.577141,-0.000003,1.000000;;, + 4720;16;0.019225,0.999811,-0.002960,0.000000,-0.999808,0.019213,-0.003948,0.000000,-0.003890,0.003035,0.999988,0.000000,27.423246,34.577110,-0.000000,1.000000;;, + 4800;16;0.000000,1.000000,0.000000,0.000000,-1.000000,-0.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,27.423262,34.577110,0.000002,1.000000;;, + 4960;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,27.423233,34.577133,0.000000,1.000000;;; + } + { Bip01_L_Toe0 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738561,-0.000003,0.000000,1.000000;;, + 80;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738552,-0.000004,0.000001,1.000000;;, + 160;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738560,-0.000006,0.000001,1.000000;;, + 240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738562,-0.000002,-0.000000,1.000000;;, + 320;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738562,-0.000007,-0.000000,1.000000;;, + 400;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738553,0.000008,0.000002,1.000000;;, + 480;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738570,-0.000012,0.000002,1.000000;;, + 560;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738561,-0.000000,0.000001,1.000000;;, + 640;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738554,0.000003,0.000001,1.000000;;, + 720;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738559,0.000018,-0.000001,1.000000;;, + 800;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738567,-0.000023,0.000003,1.000000;;, + 880;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738561,0.000015,-0.000001,1.000000;;, + 960;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738577,0.000009,0.000000,1.000000;;, + 1040;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738572,0.000005,-0.000002,1.000000;;, + 1120;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738572,0.000003,-0.000002,1.000000;;, + 1200;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738558,0.000002,0.000000,1.000000;;, + 1280;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738563,0.000006,-0.000003,1.000000;;, + 1360;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738564,-0.000010,0.000000,1.000000;;, + 1440;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738564,-0.000011,0.000004,1.000000;;, + 1520;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738545,-0.000000,-0.000006,1.000000;;, + 1600;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738548,-0.000011,-0.000001,1.000000;;, + 1680;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738566,-0.000008,0.000001,1.000000;;, + 1760;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738560,0.000012,-0.000003,1.000000;;, + 1840;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738552,-0.000004,-0.000001,1.000000;;, + 1920;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738549,-0.000001,-0.000006,1.000000;;, + 2000;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738556,-0.000001,0.000003,1.000000;;, + 2080;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738564,0.000012,-0.000001,1.000000;;, + 2160;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738553,-0.000004,-0.000002,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738557,0.000012,-0.000001,1.000000;;, + 2320;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738566,-0.000005,-0.000001,1.000000;;, + 2400;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738562,0.000005,0.000004,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738552,0.000007,-0.000000,1.000000;;, + 2560;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738543,0.000018,-0.000003,1.000000;;, + 2640;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738567,-0.000004,0.000004,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738589,-0.000015,0.000006,1.000000;;, + 2800;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738543,0.000010,-0.000005,1.000000;;, + 2880;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738537,0.000003,-0.000002,1.000000;;, + 2960;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738583,0.000002,-0.000001,1.000000;;, + 3040;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738555,0.000015,-0.000003,1.000000;;, + 3120;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738544,0.000016,-0.000002,1.000000;;, + 3200;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738552,0.000001,-0.000004,1.000000;;, + 3280;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738568,0.000010,-0.000000,1.000000;;, + 3360;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738545,0.000010,-0.000002,1.000000;;, + 3440;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738567,-0.000012,0.000003,1.000000;;, + 3520;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738564,-0.000007,0.000000,1.000000;;, + 3600;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738573,-0.000008,0.000002,1.000000;;, + 3680;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738562,-0.000005,0.000002,1.000000;;, + 3760;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738544,-0.000008,-0.000000,1.000000;;, + 3840;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738535,0.000001,0.000001,1.000000;;, + 3920;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738588,-0.000004,0.000001,1.000000;;, + 4000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738590,0.000003,0.000001,1.000000;;, + 4080;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738544,0.000012,-0.000002,1.000000;;, + 4160;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738582,-0.000001,-0.000001,1.000000;;, + 4240;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738545,-0.000004,-0.000001,1.000000;;, + 4320;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738585,-0.000005,0.000001,1.000000;;, + 4400;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738574,-0.000012,0.000001,1.000000;;, + 4480;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738592,-0.000014,0.000002,1.000000;;, + 4560;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,-1.000000,0.000000,15.738579,-0.000008,0.000006,1.000000;;, + 4640;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,-1.000000,0.000000,15.738531,-0.000003,0.000001,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738544,-0.000011,0.000005,1.000000;;, + 4800;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,-1.000000,0.000000,15.738586,0.000005,-0.000001,1.000000;;, + 4960;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,-1.000000,0.000000,15.738561,-0.000003,0.000000,1.000000;;; + } + { Dummy16 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;-0.950769,0.300574,-0.075459,0.000000,0.309313,0.905410,-0.290788,0.000000,-0.019082,-0.299812,-0.953807,0.000000,-27.853168,-0.096285,-31.055355,1.000000;;, + 80;16;-0.935626,0.342228,-0.086515,0.000000,0.352570,0.894002,-0.276506,0.000000,-0.017284,-0.289208,-0.957110,0.000000,-27.748009,0.301211,-31.076935,1.000000;;, + 160;16;-0.925290,0.368153,-0.091117,0.000000,0.378918,0.887164,-0.263366,0.000000,-0.016123,-0.278216,-0.960383,0.000000,-27.639570,0.709021,-31.093178,1.000000;;, + 240;16;-0.909113,0.404857,-0.098005,0.000000,0.416296,0.874843,-0.247683,0.000000,-0.014536,-0.265971,-0.963872,0.000000,-27.523199,1.158613,-31.101513,1.000000;;, + 320;16;-0.891424,0.441083,-0.103967,0.000000,0.452986,0.860751,-0.232186,0.000000,-0.012924,-0.254072,-0.967099,0.000000,-27.402622,1.597056,-31.104548,1.000000;;, + 400;16;-0.875825,0.470459,-0.107694,0.000000,0.482491,0.848173,-0.218644,0.000000,-0.011520,-0.243455,-0.969844,0.000000,-27.279839,1.992580,-31.105698,1.000000;;, + 480;16;-0.859232,0.499192,-0.111928,0.000000,0.511488,0.833964,-0.207084,0.000000,-0.010031,-0.235183,-0.971899,0.000000,-27.156675,2.313535,-31.109781,1.000000;;, + 560;16;-0.855702,0.505905,-0.108783,0.000000,0.517335,0.831586,-0.202064,0.000000,-0.011763,-0.229184,-0.973312,0.000000,-27.035406,2.529122,-31.122227,1.000000;;, + 640;16;-0.852038,0.512206,-0.108054,0.000000,0.523309,0.828144,-0.200814,0.000000,-0.013374,-0.227647,-0.973652,0.000000,-26.917717,2.605358,-31.149225,1.000000;;, + 720;16;-0.848776,0.515387,-0.118137,0.000000,0.528752,0.826851,-0.191672,0.000000,-0.001103,-0.225152,-0.974323,0.000000,-26.804501,2.486619,-31.197994,1.000000;;, + 800;16;-0.852712,0.506694,-0.127061,0.000000,0.522288,0.831574,-0.188944,0.000000,0.009923,-0.227477,-0.973733,0.000000,-26.700985,2.205780,-31.262104,1.000000;;, + 880;16;-0.859492,0.494064,-0.131048,0.000000,0.510717,0.840591,-0.180485,0.000000,0.020987,-0.222054,-0.974809,0.000000,-26.611767,1.761564,-31.336849,1.000000;;, + 960;16;-0.869096,0.476071,-0.134272,0.000000,0.493710,0.851557,-0.176354,0.000000,0.030383,-0.219560,-0.975126,0.000000,-26.539392,1.200514,-31.411163,1.000000;;, + 1040;16;-0.880700,0.453676,-0.136183,0.000000,0.472124,0.863998,-0.174947,0.000000,0.038293,-0.218371,-0.975114,0.000000,-26.489084,0.565444,-31.475983,1.000000;;, + 1120;16;-0.893894,0.426739,-0.137284,0.000000,0.445963,0.877632,-0.175723,0.000000,0.045497,-0.218302,-0.974820,0.000000,-26.454227,-0.131122,-31.528803,1.000000;;, + 1200;16;-0.908056,0.393894,-0.142415,0.000000,0.415567,0.889745,-0.188830,0.000000,0.052334,-0.230652,-0.971628,0.000000,-26.430658,-0.859936,-31.567528,1.000000;;, + 1280;16;-0.922470,0.357039,-0.146872,0.000000,0.381403,0.901761,-0.203369,0.000000,0.059832,-0.243619,-0.968024,0.000000,-26.415157,-1.627756,-31.590664,1.000000;;, + 1360;16;-0.936632,0.316821,-0.149480,0.000000,0.343409,0.914687,-0.213116,0.000000,0.069207,-0.250944,-0.965524,0.000000,-26.403652,-2.435472,-31.596870,1.000000;;, + 1440;16;-0.949930,0.273334,-0.151398,0.000000,0.302307,0.926494,-0.224097,0.000000,0.079016,-0.258645,-0.962735,0.000000,-26.396225,-3.271423,-31.582434,1.000000;;, + 1520;16;-0.962460,0.228345,-0.146729,0.000000,0.256494,0.941984,-0.216509,0.000000,0.088778,-0.246016,-0.965191,0.000000,-26.391926,-4.126998,-31.545103,1.000000;;, + 1600;16;-0.973279,0.180599,-0.141817,0.000000,0.207809,0.955496,-0.209388,0.000000,0.097690,-0.233264,-0.967494,0.000000,-26.390018,-4.993391,-31.483387,1.000000;;, + 1680;16;-0.982018,0.130495,-0.136426,0.000000,0.156468,0.966935,-0.201384,0.000000,0.105636,-0.219109,-0.969965,0.000000,-26.389751,-5.861845,-31.396585,1.000000;;, + 1760;16;-0.988295,0.078361,-0.130889,0.000000,0.102952,0.975744,-0.193194,0.000000,0.112575,-0.204408,-0.972391,0.000000,-26.390581,-6.723475,-31.284851,1.000000;;, + 1840;16;-0.991307,0.024053,-0.129348,0.000000,0.050465,0.977461,-0.204997,0.000000,0.121502,-0.209743,-0.970178,0.000000,-26.392103,-7.569542,-31.149120,1.000000;;, + 1920;16;-0.991445,-0.030234,-0.126977,0.000000,-0.002105,0.976380,-0.216048,0.000000,0.130510,-0.213933,-0.968091,0.000000,-26.393761,-8.391356,-30.991154,1.000000;;, + 2000;16;-0.989601,-0.065657,-0.127977,0.000000,-0.035271,0.973343,-0.226624,0.000000,0.139445,-0.219754,-0.965538,0.000000,-26.395369,-9.180367,-30.813459,1.000000;;, + 2080;16;-0.986798,-0.097252,-0.129503,0.000000,-0.064643,0.969690,-0.235632,0.000000,0.148494,-0.224150,-0.963175,0.000000,-26.396614,-9.928298,-30.619232,1.000000;;, + 2160;16;-0.984868,-0.112194,-0.132090,0.000000,-0.079888,0.970267,-0.228473,0.000000,0.153796,-0.214463,-0.964548,0.000000,-26.403309,-10.627003,-30.415258,1.000000;;, + 2240;16;-0.982743,-0.127398,-0.134113,0.000000,-0.095799,0.970749,-0.220155,0.000000,0.158237,-0.203508,-0.966201,0.000000,-26.397121,-11.268909,-30.196938,1.000000;;, + 2320;16;-0.978546,-0.154778,-0.135980,0.000000,-0.121814,0.966943,-0.224014,0.000000,0.166158,-0.202644,-0.965053,0.000000,-26.355202,-11.844269,-29.959543,1.000000;;, + 2400;16;-0.973358,-0.183789,-0.137096,0.000000,-0.149820,0.962418,-0.226507,0.000000,0.173573,-0.199933,-0.964313,0.000000,-26.298077,-12.350889,-29.710909,1.000000;;, + 2480;16;-0.967874,-0.207464,-0.142053,0.000000,-0.169510,0.955665,-0.240771,0.000000,0.185706,-0.208956,-0.960130,0.000000,-26.223885,-12.783846,-29.451048,1.000000;;, + 2560;16;-0.961966,-0.230255,-0.146982,0.000000,-0.188517,0.948972,-0.252811,0.000000,0.197693,-0.215486,-0.956286,0.000000,-26.175800,-13.142502,-29.199085,1.000000;;, + 2640;16;-0.958528,-0.239279,-0.154823,0.000000,-0.193917,0.945671,-0.260966,0.000000,0.208855,-0.220120,-0.952852,0.000000,-26.195387,-13.424680,-28.970636,1.000000;;, + 2720;16;-0.954978,-0.248082,-0.162707,0.000000,-0.199542,0.942941,-0.266544,0.000000,0.219548,-0.222077,-0.949990,0.000000,-26.283360,-13.630479,-28.778227,1.000000;;, + 2800;16;-0.953561,-0.246858,-0.172576,0.000000,-0.195597,0.943225,-0.268456,0.000000,0.229048,-0.222234,-0.947707,0.000000,-26.469358,-13.758628,-28.638807,1.000000;;, + 2880;16;-0.952465,-0.244663,-0.181521,0.000000,-0.191561,0.944292,-0.267614,0.000000,0.236884,-0.220121,-0.946273,0.000000,-26.708914,-13.811164,-28.548800,1.000000;;, + 2960;16;-0.951625,-0.242593,-0.188569,0.000000,-0.188648,0.945716,-0.264638,0.000000,0.242532,-0.216263,-0.945732,0.000000,-26.973581,-13.789098,-28.512592,1.000000;;, + 3040;16;-0.952264,-0.236555,-0.192962,0.000000,-0.183013,0.948285,-0.259349,0.000000,0.244333,-0.211654,-0.946311,0.000000,-27.246073,-13.695509,-28.519129,1.000000;;, + 3120;16;-0.951630,-0.238703,-0.193446,0.000000,-0.186562,0.949180,-0.253479,0.000000,0.244121,-0.205129,-0.947801,0.000000,-27.508265,-13.531747,-28.559759,1.000000;;, + 3200;16;-0.954384,-0.230068,-0.190314,0.000000,-0.180596,0.952381,-0.245673,0.000000,0.237773,-0.200096,-0.950487,0.000000,-27.734383,-13.301747,-28.632072,1.000000;;, + 3280;16;-0.945656,-0.267764,-0.184489,0.000000,-0.218163,0.943176,-0.250646,0.000000,0.241120,-0.196776,-0.950337,0.000000,-27.892500,-13.008595,-28.732557,1.000000;;, + 3360;16;-0.935553,-0.302299,-0.182634,0.000000,-0.248927,0.931215,-0.266222,0.000000,0.250550,-0.203603,-0.946452,0.000000,-27.983364,-12.653031,-28.858446,1.000000;;, + 3440;16;-0.942919,-0.265237,-0.201378,0.000000,-0.204891,0.938750,-0.277069,0.000000,0.262533,-0.219993,-0.939510,0.000000,-27.987085,-12.232808,-29.007380,1.000000;;, + 3520;16;-0.952445,-0.206811,-0.223779,0.000000,-0.138372,0.947867,-0.287057,0.000000,0.271480,-0.242442,-0.931408,0.000000,-27.932764,-11.757487,-29.171944,1.000000;;, + 3600;16;-0.958256,-0.157993,-0.238293,0.000000,-0.082825,0.951111,-0.297537,0.000000,0.273652,-0.265380,-0.924493,0.000000,-27.839216,-11.233636,-29.345602,1.000000;;, + 3680;16;-0.962652,-0.111330,-0.246793,0.000000,-0.030878,0.950742,-0.308443,0.000000,0.268975,-0.289303,-0.918671,0.000000,-27.716318,-10.670435,-29.522480,1.000000;;, + 3760;16;-0.966618,-0.071139,-0.246146,0.000000,0.011804,0.947299,-0.320135,0.000000,0.255948,-0.312354,-0.914836,0.000000,-27.576151,-10.080297,-29.696045,1.000000;;, + 3840;16;-0.970162,-0.033133,-0.240184,0.000000,0.050431,0.941378,-0.333563,0.000000,0.237155,-0.335723,-0.911618,0.000000,-27.431482,-9.461965,-29.864712,1.000000;;, + 3920;16;-0.972774,0.006360,-0.231670,0.000000,0.089438,0.932489,-0.349949,0.000000,0.213804,-0.361141,-0.907670,0.000000,-27.294771,-8.817940,-30.026068,1.000000;;, + 4000;16;-0.974295,0.045173,-0.220698,0.000000,0.125929,0.921535,-0.367307,0.000000,0.186789,-0.385658,-0.903536,0.000000,-27.178677,-8.150883,-30.178059,1.000000;;, + 4080;16;-0.974651,0.082562,-0.207939,0.000000,0.159039,0.909370,-0.384385,0.000000,0.157358,-0.407712,-0.899449,0.000000,-27.098522,-7.463268,-30.319038,1.000000;;, + 4160;16;-0.973899,0.117778,-0.194033,0.000000,0.188152,0.897050,-0.399875,0.000000,0.126961,-0.425945,-0.895797,0.000000,-27.058285,-6.758516,-30.447344,1.000000;;, + 4240;16;-0.972112,0.150360,-0.179973,0.000000,0.213336,0.885692,-0.412356,0.000000,0.097399,-0.439251,-0.893069,0.000000,-27.072193,-6.039464,-30.561668,1.000000;;, + 4320;16;-0.969962,0.178673,-0.165076,0.000000,0.233094,0.876778,-0.420627,0.000000,0.069581,-0.446471,-0.892089,0.000000,-27.125252,-5.310541,-30.660139,1.000000;;, + 4400;16;-0.968280,0.200485,-0.149129,0.000000,0.245693,0.872583,-0.422178,0.000000,0.045487,-0.445426,-0.894162,0.000000,-27.210672,-4.575768,-30.741310,1.000000;;, + 4480;16;-0.967196,0.217127,-0.131860,0.000000,0.252894,0.872030,-0.419057,0.000000,0.023998,-0.438658,-0.898334,0.000000,-27.318468,-3.839471,-30.804024,1.000000;;, + 4560;16;-0.967051,0.228251,-0.112754,0.000000,0.254538,0.875105,-0.411585,0.000000,0.004727,-0.426724,-0.904370,0.000000,-27.439497,-3.105746,-30.847593,1.000000;;, + 4640;16;-0.967164,0.236582,-0.092861,0.000000,0.253796,0.879644,-0.402262,0.000000,-0.013484,-0.412621,-0.910803,0.000000,-27.564468,-2.379188,-30.871828,1.000000;;, + 4720;16;-0.966712,0.245232,-0.073003,0.000000,0.253826,0.883169,-0.394442,0.000000,-0.032256,-0.399841,-0.916017,0.000000,-27.678188,-1.668544,-30.876764,1.000000;;, + 4800;16;-0.965965,0.253205,-0.052900,0.000000,0.253587,0.886612,-0.386799,0.000000,-0.051038,-0.387049,-0.920645,0.000000,-27.789658,-0.963900,-30.864017,1.000000;;, + 4960;16;-0.950769,0.300574,-0.075459,0.000000,0.309313,0.905410,-0.290788,0.000000,-0.019082,-0.299812,-0.953807,0.000000,-27.853168,-0.096285,-31.055355,1.000000;;; + } + { Bip01_R_Thigh } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000691,-0.000000,0.000000,0.000691,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000005,0.000001,1.000000;;, + 80;16;0.992696,-0.120646,-0.000000,0.000000,0.120646,0.992696,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231514,0.000002,-0.000002,1.000000;;, + 160;16;0.981416,-0.191892,-0.000000,0.000000,0.191892,0.981416,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231522,-0.000015,0.000003,1.000000;;, + 240;16;0.955509,-0.294962,-0.000000,0.000000,0.294962,0.955509,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000021,0.000008,1.000000;;, + 320;16;0.918810,-0.394701,-0.000000,0.000000,0.394701,0.918810,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231514,-0.000011,-0.000001,1.000000;;, + 400;16;0.881477,-0.472227,0.000000,0.000000,0.472227,0.881477,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231529,-0.000002,0.000000,1.000000;;, + 480;16;0.837618,-0.546256,-0.000000,0.000000,0.546256,0.837618,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000013,-0.000001,1.000000;;, + 560;16;0.859904,-0.510455,-0.000000,0.000000,0.510456,0.859904,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,-0.000008,0.000003,1.000000;;, + 640;16;0.880661,-0.473747,0.000000,0.000000,0.473747,0.880661,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231522,-0.000020,0.000005,1.000000;;, + 720;16;0.841689,-0.539962,0.000000,0.000000,0.539962,0.841689,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231514,-0.000014,0.000004,1.000000;;, + 800;16;0.814050,-0.580795,0.000000,0.000000,0.580795,0.814050,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000020,0.000008,1.000000;;, + 880;16;0.797222,-0.603687,-0.000000,0.000000,0.603687,0.797222,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231483,-0.000022,0.000007,1.000000;;, + 960;16;0.788129,-0.615510,-0.000000,0.000000,0.615510,0.788129,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000014,0.000006,1.000000;;, + 1040;16;0.785779,-0.618507,-0.000000,0.000000,0.618507,0.785779,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231499,-0.000006,0.000003,1.000000;;, + 1120;16;0.789502,-0.613748,-0.000000,0.000000,0.613748,0.789502,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231499,-0.000023,0.000006,1.000000;;, + 1200;16;0.794340,-0.607473,-0.000000,0.000000,0.607473,0.794340,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231499,-0.000002,-0.000001,1.000000;;, + 1280;16;0.803662,-0.595085,0.000000,0.000000,0.595085,0.803663,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,-0.000020,0.000005,1.000000;;, + 1360;16;0.814971,-0.579501,0.000000,0.000000,0.579501,0.814971,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,-0.000012,0.000003,1.000000;;, + 1440;16;0.829500,-0.558507,0.000000,0.000000,0.558507,0.829500,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000009,0.000001,1.000000;;, + 1520;16;0.847784,-0.530342,-0.000000,0.000000,0.530342,0.847784,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,0.000008,-0.000001,1.000000;;, + 1600;16;0.867527,-0.497391,-0.000000,0.000000,0.497391,0.867527,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231514,-0.000005,0.000004,1.000000;;, + 1680;16;0.887900,-0.460037,0.000000,0.000000,0.460037,0.887900,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231522,0.000010,-0.000002,1.000000;;, + 1760;16;0.908067,-0.418825,-0.000000,0.000000,0.418825,0.908067,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231506,-0.000008,0.000003,1.000000;;, + 1840;16;0.926226,-0.376969,0.000000,0.000000,0.376968,0.926226,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231491,0.000014,0.000001,1.000000;;, + 1920;16;0.942370,-0.334573,0.000000,0.000000,0.334573,0.942370,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,0.000007,0.000003,1.000000;;, + 2000;16;0.944301,-0.329084,0.000000,0.000000,0.329084,0.944301,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000000,0.000002,1.000000;;, + 2080;16;0.943450,-0.331516,-0.000000,0.000000,0.331516,0.943450,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,0.000019,-0.000003,1.000000;;, + 2160;16;0.931197,-0.364515,-0.000000,0.000000,0.364515,0.931197,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,-0.000000,0.000000,1.000000;;, + 2240;16;0.918168,-0.396191,-0.000000,0.000000,0.396191,0.918168,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231499,0.000011,-0.000004,1.000000;;, + 2320;16;0.914538,-0.404499,0.000000,0.000000,0.404499,0.914538,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000010,-0.000001,1.000000;;, + 2400;16;0.913027,-0.407898,-0.000000,0.000000,0.407898,0.913028,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231506,0.000013,-0.000001,1.000000;;, + 2480;16;0.908578,-0.417715,-0.000000,0.000000,0.417715,0.908578,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231491,0.000001,-0.000001,1.000000;;, + 2560;16;0.904021,-0.427488,0.000000,0.000000,0.427488,0.904021,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231491,-0.000007,0.000003,1.000000;;, + 2640;16;0.887853,-0.460127,0.000000,0.000000,0.460127,0.887853,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231522,0.000017,-0.000005,1.000000;;, + 2720;16;0.870501,-0.492167,0.000000,0.000000,0.492167,0.870501,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000000,0.000000,1.000000;;, + 2800;16;0.841677,-0.539981,-0.000000,0.000000,0.539981,0.841677,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,-0.000001,0.000001,1.000000;;, + 2880;16;0.810227,-0.586117,0.000000,0.000000,0.586117,0.810227,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231499,0.000018,-0.000004,1.000000;;, + 2960;16;0.778798,-0.627275,0.000000,0.000000,0.627275,0.778798,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,0.000008,-0.000006,1.000000;;, + 3040;16;0.745275,-0.666757,-0.000000,0.000000,0.666757,0.745275,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000001,0.000000,1.000000;;, + 3120;16;0.728440,-0.685110,0.000000,0.000000,0.685110,0.728439,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231499,-0.000004,0.000003,1.000000;;, + 3200;16;0.711169,-0.703021,0.000000,0.000000,0.703021,0.711169,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231506,-0.000007,0.000002,1.000000;;, + 3280;16;0.735082,-0.677978,-0.000000,0.000000,0.677978,0.735082,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000010,0.000000,1.000000;;, + 3360;16;0.747912,-0.663797,-0.000000,0.000000,0.663798,0.747912,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,0.000017,-0.000007,1.000000;;, + 3440;16;0.692942,-0.720993,-0.000000,0.000000,0.720993,0.692942,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,0.000020,-0.000003,1.000000;;, + 3520;16;0.618723,-0.785609,0.000000,0.000000,0.785609,0.618723,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231514,0.000003,-0.000002,1.000000;;, + 3600;16;0.568878,-0.822422,0.000000,0.000000,0.822422,0.568878,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,0.000002,-0.000004,1.000000;;, + 3680;16;0.538025,-0.842929,0.000000,0.000000,0.842929,0.538025,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,-0.000004,0.000002,1.000000;;, + 3760;16;0.538263,-0.842777,0.000000,0.000000,0.842777,0.538264,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231491,0.000011,-0.000005,1.000000;;, + 3840;16;0.556128,-0.831097,0.000000,0.000000,0.831097,0.556128,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,0.000010,-0.000007,1.000000;;, + 3920;16;0.580332,-0.814380,0.000000,0.000000,0.814380,0.580332,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000009,0.000003,1.000000;;, + 4000;16;0.612475,-0.790490,0.000000,0.000000,0.790490,0.612475,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000020,0.000009,1.000000;;, + 4080;16;0.650734,-0.759306,0.000000,0.000000,0.759306,0.650734,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231506,-0.000007,0.000001,1.000000;;, + 4160;16;0.693185,-0.720759,-0.000000,0.000000,0.720760,0.693185,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231506,0.000024,-0.000009,1.000000;;, + 4240;16;0.736246,-0.676714,0.000000,0.000000,0.676714,0.736246,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231514,0.000018,-0.000011,1.000000;;, + 4320;16;0.782863,-0.622194,-0.000000,0.000000,0.622194,0.782863,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231514,0.000011,-0.000009,1.000000;;, + 4400;16;0.834057,-0.551678,-0.000000,0.000000,0.551678,0.834057,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231499,0.000028,-0.000016,1.000000;;, + 4480;16;0.885285,-0.465049,0.000000,0.000000,0.465049,0.885285,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,119.231522,0.000006,-0.000006,1.000000;;, + 4560;16;0.933661,-0.358157,-0.000000,0.000000,0.358157,0.933661,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231491,0.000025,-0.000013,1.000000;;, + 4640;16;0.970815,-0.239830,-0.000000,0.000000,0.239830,0.970815,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,119.231476,-0.000004,0.000002,1.000000;;, + 4720;16;0.992635,-0.121142,0.000000,0.000000,0.121142,0.992635,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231483,0.000008,-0.000000,1.000000;;, + 4800;16;1.000000,-0.000691,-0.000000,0.000000,0.000691,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,119.231522,0.000021,-0.000011,1.000000;;, + 4960;16;1.000000,-0.000691,-0.000000,0.000000,0.000691,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,119.231514,-0.000005,0.000001,1.000000;;; + } + { Bip01_R_Calf } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.968778,0.242973,0.049336,0.000000,-0.242361,0.970017,-0.018119,0.000000,-0.052260,0.005597,0.998618,0.000000,119.231522,-0.000002,0.000002,1.000000;;, + 80;16;0.961616,0.269772,0.050179,0.000000,-0.268547,0.962804,-0.029856,0.000000,-0.056367,0.015235,0.998294,0.000000,119.231529,-0.000013,0.000004,1.000000;;, + 160;16;0.956946,0.285763,0.050931,0.000000,-0.284133,0.958073,-0.036938,0.000000,-0.059351,0.020876,0.998019,0.000000,119.231491,0.000001,-0.000003,1.000000;;, + 240;16;0.949554,0.309198,0.052383,0.000000,-0.306909,0.950557,-0.047416,0.000000,-0.064454,0.028947,0.997501,0.000000,119.231491,0.000013,-0.000003,1.000000;;, + 320;16;0.941553,0.332466,0.054256,0.000000,-0.329428,0.942402,-0.057929,0.000000,-0.070390,0.036669,0.996845,0.000000,119.231491,0.000004,0.000001,1.000000;;, + 400;16;0.934630,0.351170,0.056087,0.000000,-0.347449,0.935341,-0.066452,0.000000,-0.075797,0.042621,0.996212,0.000000,119.231522,-0.000004,-0.000001,1.000000;;, + 480;16;0.927307,0.369747,0.058206,0.000000,-0.365269,0.927878,-0.074976,0.000000,-0.081730,0.048265,0.995485,0.000000,119.231514,0.000006,0.000000,1.000000;;, + 560;16;0.947979,0.312243,0.061972,0.000000,-0.307242,0.948384,-0.078548,0.000000,-0.083299,0.055421,0.994982,0.000000,119.231483,0.000002,0.000000,1.000000;;, + 640;16;0.965072,0.253591,0.065789,0.000000,-0.248051,0.965269,-0.082018,0.000000,-0.084303,0.062834,0.994457,0.000000,119.231514,0.000025,-0.000004,1.000000;;, + 720;16;0.952754,0.296732,0.064877,0.000000,-0.291600,0.953349,-0.078073,0.000000,-0.085017,0.055466,0.994834,0.000000,119.231506,0.000021,-0.000005,1.000000;;, + 800;16;0.942792,0.327248,0.063655,0.000000,-0.322237,0.943467,-0.077679,0.000000,-0.085477,0.052723,0.994944,0.000000,119.231491,0.000017,-0.000006,1.000000;;, + 880;16;0.945118,0.318768,0.071687,0.000000,-0.314227,0.946918,-0.067881,0.000000,-0.089520,0.041629,0.995115,0.000000,119.231499,0.000032,-0.000006,1.000000;;, + 960;16;0.949310,0.304217,0.079135,0.000000,-0.300018,0.952000,-0.060710,0.000000,-0.093805,0.033891,0.995014,0.000000,119.231506,0.000007,-0.000003,1.000000;;, + 1040;16;0.954730,0.284711,0.086197,0.000000,-0.280703,0.958173,-0.055767,0.000000,-0.098469,0.029047,0.994716,0.000000,119.231529,0.000002,0.000001,1.000000;;, + 1120;16;0.960945,0.260642,0.093010,0.000000,-0.256682,0.965070,-0.052479,0.000000,-0.103440,0.026555,0.994281,0.000000,119.231514,0.000020,-0.000003,1.000000;;, + 1200;16;0.959528,0.266249,0.091746,0.000000,-0.261187,0.963192,-0.063574,0.000000,-0.105295,0.037039,0.993751,0.000000,119.231499,0.000007,-0.000002,1.000000;;, + 1280;16;0.959127,0.268209,0.090224,0.000000,-0.261922,0.962114,-0.075715,0.000000,-0.107113,0.048988,0.993039,0.000000,119.231506,0.000018,-0.000007,1.000000;;, + 1360;16;0.955512,0.283673,0.080786,0.000000,-0.277209,0.957255,-0.082575,0.000000,-0.100757,0.056507,0.993305,0.000000,119.231506,-0.000005,0.000000,1.000000;;, + 1440;16;0.952631,0.295732,0.070969,0.000000,-0.289172,0.953054,-0.089822,0.000000,-0.094201,0.065045,0.993426,0.000000,119.231499,-0.000014,0.000009,1.000000;;, + 1520;16;0.954221,0.292597,0.062040,0.000000,-0.287759,0.954648,-0.076430,0.000000,-0.081589,0.055078,0.995143,0.000000,119.231499,0.000002,-0.000004,1.000000;;, + 1600;16;0.956422,0.287048,0.053486,0.000000,-0.283651,0.956852,-0.063058,0.000000,-0.069279,0.045138,0.996576,0.000000,119.231491,0.000001,-0.000005,1.000000;;, + 1680;16;0.959114,0.279358,0.045371,0.000000,-0.277210,0.959592,-0.048358,0.000000,-0.057047,0.033803,0.997799,0.000000,119.231499,-0.000008,-0.000001,1.000000;;, + 1760;16;0.962123,0.269997,0.037695,0.000000,-0.268835,0.962615,-0.033178,0.000000,-0.045244,0.021788,0.998738,0.000000,119.231499,0.000015,-0.000006,1.000000;;, + 1840;16;0.962117,0.271123,0.028679,0.000000,-0.269985,0.962110,-0.038108,0.000000,-0.037925,0.028921,0.998862,0.000000,119.231491,-0.000004,-0.000002,1.000000;;, + 1920;16;0.962055,0.272157,0.019505,0.000000,-0.271184,0.961617,-0.041862,0.000000,-0.030149,0.034984,0.998933,0.000000,119.231499,-0.000008,-0.000001,1.000000;;, + 2000;16;0.954595,0.297496,0.015627,0.000000,-0.296517,0.953896,-0.046475,0.000000,-0.028733,0.039731,0.998797,0.000000,119.231491,0.000012,-0.000003,1.000000;;, + 2080;16;0.945039,0.326757,0.011431,0.000000,-0.325822,0.944092,-0.050296,0.000000,-0.027226,0.043807,0.998669,0.000000,119.231476,-0.000017,0.000006,1.000000;;, + 2160;16;0.929391,0.368812,0.014497,0.000000,-0.367984,0.928921,-0.041145,0.000000,-0.028641,0.032905,0.999048,0.000000,119.231499,-0.000003,0.000002,1.000000;;, + 2240;16;0.911959,0.409892,0.017853,0.000000,-0.409216,0.911864,-0.032326,0.000000,-0.029530,0.022175,0.999318,0.000000,119.231506,-0.000002,0.000003,1.000000;;, + 2320;16;0.897343,0.441136,0.013243,0.000000,-0.440449,0.897039,-0.036404,0.000000,-0.027938,0.026834,0.999249,0.000000,119.231506,0.000025,-0.000004,1.000000;;, + 2400;16;0.882926,0.469438,0.008413,0.000000,-0.468778,0.882405,-0.040114,0.000000,-0.026255,0.031473,0.999160,0.000000,119.231514,0.000007,-0.000002,1.000000;;, + 2480;16;0.871719,0.490003,0.001830,0.000000,-0.488862,0.869932,-0.065059,0.000000,-0.033471,0.055819,0.997880,0.000000,119.231491,0.000006,0.000001,1.000000;;, + 2560;16;0.862916,0.505338,-0.002894,0.000000,-0.503552,0.859356,-0.089117,0.000000,-0.042548,0.078358,0.996017,0.000000,119.231476,0.000015,-0.000005,1.000000;;, + 2640;16;0.851604,0.524175,0.003224,0.000000,-0.520013,0.845585,-0.120719,0.000000,-0.066004,0.101128,0.992682,0.000000,119.231514,-0.000008,-0.000003,1.000000;;, + 2720;16;0.844668,0.535099,0.014346,0.000000,-0.527177,0.836215,-0.151094,0.000000,-0.092846,0.120062,0.988415,0.000000,119.231491,0.000021,-0.000007,1.000000;;, + 2800;16;0.842347,0.537394,0.040743,0.000000,-0.522436,0.832783,-0.183122,0.000000,-0.132338,0.132967,0.982246,0.000000,119.231491,0.000019,-0.000007,1.000000;;, + 2880;16;0.847564,0.524947,0.077888,0.000000,-0.500331,0.839350,-0.212510,0.000000,-0.176932,0.141146,0.974050,0.000000,119.231491,0.000008,-0.000007,1.000000;;, + 2960;16;0.862664,0.489335,0.127914,0.000000,-0.452684,0.859806,-0.236242,0.000000,-0.225583,0.145893,0.963238,0.000000,119.231506,0.000004,0.000001,1.000000;;, + 3040;16;0.883839,0.425545,0.194266,0.000000,-0.374392,0.892473,-0.251640,0.000000,-0.280461,0.149678,0.948124,0.000000,119.231506,-0.000006,-0.000000,1.000000;;, + 3120;16;0.912598,0.319880,0.254641,0.000000,-0.255694,0.932509,-0.255046,0.000000,-0.319039,0.167644,0.932797,0.000000,119.231506,0.000024,-0.000009,1.000000;;, + 3200;16;0.928966,0.153149,0.336999,0.000000,-0.073022,0.968328,-0.238766,0.000000,-0.362892,0.197198,0.910726,0.000000,119.231483,0.000025,-0.000008,1.000000;;, + 3280;16;0.937054,0.115470,0.329539,0.000000,-0.042454,0.974414,-0.220714,0.000000,-0.346593,0.192831,0.917981,0.000000,119.231491,0.000020,-0.000004,1.000000;;, + 3360;16;0.949507,0.045192,0.310475,0.000000,0.012573,0.983296,-0.181577,0.000000,-0.313494,0.176312,0.933079,0.000000,119.231514,0.000004,-0.000000,1.000000;;, + 3440;16;0.959181,-0.032297,0.280942,0.000000,0.070203,0.989553,-0.125924,0.000000,-0.273940,0.140507,0.951428,0.000000,119.231506,-0.000007,-0.000002,1.000000;;, + 3520;16;0.963427,-0.104243,0.246864,0.000000,0.123716,0.990207,-0.064688,0.000000,-0.237704,0.092863,0.966889,0.000000,119.231506,-0.000002,-0.000002,1.000000;;, + 3600;16;0.964323,-0.151520,0.217080,0.000000,0.157682,0.987426,-0.011249,0.000000,-0.212646,0.045077,0.976089,0.000000,119.231499,0.000002,0.000002,1.000000;;, + 3680;16;0.965890,-0.170849,0.194596,0.000000,0.167334,0.985297,0.034484,0.000000,-0.197626,-0.000745,0.980277,0.000000,119.231468,0.000007,-0.000011,1.000000;;, + 3760;16;0.970914,-0.148335,0.187941,0.000000,0.138962,0.988344,0.062179,0.000000,-0.194974,-0.034254,0.980210,0.000000,119.231522,0.000009,0.000002,1.000000;;, + 3840;16;0.976399,-0.100533,0.191150,0.000000,0.087220,0.993221,0.076851,0.000000,-0.197580,-0.058365,0.978548,0.000000,119.231514,0.000010,0.000001,1.000000;;, + 3920;16;0.979355,-0.036699,0.198787,0.000000,0.020678,0.996411,0.082076,0.000000,-0.201086,-0.076271,0.976600,0.000000,119.231483,0.000022,-0.000013,1.000000;;, + 4000;16;0.977445,0.036592,0.207995,0.000000,-0.053320,0.995727,0.075395,0.000000,-0.204348,-0.084785,0.975220,0.000000,119.231491,0.000020,-0.000018,1.000000;;, + 4080;16;0.970276,0.111665,0.214698,0.000000,-0.126820,0.990222,0.058118,0.000000,-0.206109,-0.083619,0.974950,0.000000,119.231483,0.000014,-0.000012,1.000000;;, + 4160;16;0.959692,0.180561,0.215382,0.000000,-0.192249,0.980742,0.034431,0.000000,-0.205018,-0.074450,0.975923,0.000000,119.231522,-0.000024,0.000010,1.000000;;, + 4240;16;0.949330,0.234824,0.208878,0.000000,-0.242488,0.970086,0.011497,0.000000,-0.199930,-0.061565,0.977874,0.000000,119.231514,-0.000033,0.000018,1.000000;;, + 4320;16;0.942611,0.270034,0.196382,0.000000,-0.273834,0.961743,-0.008064,0.000000,-0.191047,-0.046175,0.980494,0.000000,119.231483,-0.000004,-0.000003,1.000000;;, + 4400;16;0.943918,0.276524,0.180428,0.000000,-0.277778,0.960461,-0.018793,0.000000,-0.178491,-0.032379,0.983409,0.000000,119.231506,-0.000021,0.000012,1.000000;;, + 4480;16;0.950802,0.263535,0.162863,0.000000,-0.263183,0.964444,-0.024133,0.000000,-0.163432,-0.019916,0.986354,0.000000,119.231476,-0.000019,0.000005,1.000000;;, + 4560;16;0.961555,0.233630,0.144324,0.000000,-0.232262,0.972292,-0.026493,0.000000,-0.146514,-0.008047,0.989176,0.000000,119.231476,-0.000045,0.000023,1.000000;;, + 4640;16;0.972677,0.195524,0.125179,0.000000,-0.193671,0.980697,-0.026926,0.000000,-0.128027,0.001947,0.991769,0.000000,119.231506,0.000011,-0.000006,1.000000;;, + 4720;16;0.981532,0.160253,0.104474,0.000000,-0.158198,0.987018,-0.027719,0.000000,-0.107560,0.010679,0.994141,0.000000,119.231483,0.000002,-0.000002,1.000000;;, + 4800;16;0.988831,0.124156,0.082452,0.000000,-0.122246,0.992109,-0.027835,0.000000,-0.085257,0.017445,0.996206,0.000000,119.231476,-0.000039,0.000023,1.000000;;, + 4960;16;0.968778,0.242973,0.049336,0.000000,-0.242361,0.970017,-0.018119,0.000000,-0.052260,0.005597,0.998618,0.000000,119.231522,-0.000002,0.000002,1.000000;;; + } + { Bip01_R_Foot } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423256,34.577141,-0.000001,1.000000;;, + 80;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423260,34.577141,-0.000001,1.000000;;, + 160;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423243,34.577141,-0.000002,1.000000;;, + 240;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423237,34.577122,0.000005,1.000000;;, + 320;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423248,34.577145,-0.000002,1.000000;;, + 400;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423233,34.577118,0.000006,1.000000;;, + 480;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423246,34.577118,0.000003,1.000000;;, + 560;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423237,34.577145,0.000000,1.000000;;, + 640;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423241,34.577129,0.000002,1.000000;;, + 720;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423254,34.577126,-0.000001,1.000000;;, + 800;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423248,34.577126,0.000004,1.000000;;, + 880;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423239,34.577137,-0.000002,1.000000;;, + 960;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423252,34.577133,-0.000001,1.000000;;, + 1040;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423252,34.577129,0.000002,1.000000;;, + 1120;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423243,34.577133,0.000004,1.000000;;, + 1200;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423243,34.577137,0.000003,1.000000;;, + 1280;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423254,34.577126,0.000000,1.000000;;, + 1360;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423246,34.577145,0.000000,1.000000;;, + 1440;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423246,34.577141,-0.000001,1.000000;;, + 1520;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423250,34.577145,0.000000,1.000000;;, + 1600;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423252,34.577126,0.000005,1.000000;;, + 1680;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423244,34.577145,-0.000002,1.000000;;, + 1760;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423264,34.577141,-0.000001,1.000000;;, + 1840;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423239,34.577133,0.000002,1.000000;;, + 1920;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423254,34.577148,0.000000,1.000000;;, + 2000;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423231,34.577152,-0.000002,1.000000;;, + 2080;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423248,34.577145,-0.000002,1.000000;;, + 2160;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423264,34.577126,0.000001,1.000000;;, + 2240;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423244,34.577145,0.000000,1.000000;;, + 2320;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423246,34.577126,0.000003,1.000000;;, + 2400;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423254,34.577122,0.000004,1.000000;;, + 2480;16;0.024776,0.999689,-0.002694,0.000000,-0.999680,0.024761,-0.005212,0.000000,-0.005144,0.002822,0.999983,0.000000,27.423239,34.577126,0.000006,1.000000;;, + 2560;16;0.044065,0.999017,-0.004895,0.000000,-0.998990,0.044020,-0.008951,0.000000,-0.008727,0.005284,0.999948,0.000000,27.423248,34.577118,0.000004,1.000000;;, + 2640;16;0.115791,0.993154,-0.015418,0.000000,-0.993024,0.115400,-0.024201,0.000000,-0.022256,0.018112,0.999588,0.000000,27.423241,34.577133,-0.000000,1.000000;;, + 2720;16;0.177487,0.983804,-0.025052,0.000000,-0.983603,0.176508,-0.037004,0.000000,-0.031983,0.031208,0.999001,0.000000,27.423243,34.577141,0.000001,1.000000;;, + 2800;16;0.240793,0.969825,-0.038193,0.000000,-0.969821,0.238867,-0.048881,0.000000,-0.038283,0.048810,0.998074,0.000000,27.423264,34.577126,0.000001,1.000000;;, + 2880;16;0.286167,0.956856,-0.050355,0.000000,-0.957322,0.283293,-0.057265,0.000000,-0.040530,0.064593,0.997088,0.000000,27.423264,34.577122,0.000002,1.000000;;, + 2960;16;0.286216,0.956506,-0.056368,0.000000,-0.957519,0.283368,-0.053482,0.000000,-0.035183,0.069281,0.996977,0.000000,27.423243,34.577133,0.000004,1.000000;;, + 3040;16;0.260367,0.963717,-0.058811,0.000000,-0.965111,0.258026,-0.044523,0.000000,-0.027733,0.068352,0.997276,0.000000,27.423264,34.577133,-0.000003,1.000000;;, + 3120;16;0.155009,0.987246,-0.036283,0.000000,-0.987737,0.154184,-0.024549,0.000000,-0.018642,0.039643,0.999040,0.000000,27.423260,34.577133,-0.000001,1.000000;;, + 3200;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423254,34.577126,-0.000004,1.000000;;, + 3280;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423252,34.577156,0.000000,1.000000;;, + 3360;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423235,34.577148,0.000001,1.000000;;, + 3440;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423250,34.577133,-0.000003,1.000000;;, + 3520;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423254,34.577137,-0.000004,1.000000;;, + 3600;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423254,34.577141,0.000003,1.000000;;, + 3680;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423246,34.577141,0.000001,1.000000;;, + 3760;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423243,34.577137,0.000006,1.000000;;, + 3840;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423250,34.577126,0.000009,1.000000;;, + 3920;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423264,34.577133,0.000002,1.000000;;, + 4000;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423225,34.577141,-0.000002,1.000000;;, + 4080;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423256,34.577133,-0.000001,1.000000;;, + 4160;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423248,34.577114,0.000016,1.000000;;, + 4240;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423229,34.577160,-0.000016,1.000000;;, + 4320;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423254,34.577152,-0.000008,1.000000;;, + 4400;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423243,34.577137,0.000001,1.000000;;, + 4480;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423248,34.577156,-0.000007,1.000000;;, + 4560;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423246,34.577122,0.000004,1.000000;;, + 4640;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423243,34.577122,0.000004,1.000000;;, + 4720;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423264,34.577164,-0.000009,1.000000;;, + 4800;16;0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,27.423260,34.577152,-0.000010,1.000000;;, + 4960;16;0.000000,1.000000,-0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,27.423256,34.577141,-0.000001,1.000000;;; + } + { Bip01_R_Toe0 } + } + + Animation { + + + AnimationKey { + 4; + 62; + 0;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738550,-0.000017,-0.000003,1.000000;;, + 80;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738570,0.000009,0.000001,1.000000;;, + 160;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738559,-0.000016,0.000003,1.000000;;, + 240;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738566,-0.000021,-0.000003,1.000000;;, + 320;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738569,-0.000017,-0.000004,1.000000;;, + 400;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738562,0.000016,-0.000001,1.000000;;, + 480;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738554,-0.000006,0.000001,1.000000;;, + 560;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738573,-0.000013,-0.000002,1.000000;;, + 640;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738546,0.000014,0.000001,1.000000;;, + 720;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738572,-0.000015,-0.000003,1.000000;;, + 800;16;1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738565,-0.000003,-0.000002,1.000000;;, + 880;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738555,-0.000002,-0.000002,1.000000;;, + 960;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738550,0.000001,0.000002,1.000000;;, + 1040;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738564,-0.000014,-0.000003,1.000000;;, + 1120;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738560,-0.000017,-0.000002,1.000000;;, + 1200;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738569,0.000010,-0.000004,1.000000;;, + 1280;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738572,0.000021,-0.000003,1.000000;;, + 1360;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738555,0.000018,0.000000,1.000000;;, + 1440;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738553,0.000010,-0.000001,1.000000;;, + 1520;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738554,-0.000013,-0.000002,1.000000;;, + 1600;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738569,0.000017,-0.000002,1.000000;;, + 1680;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738546,0.000001,0.000001,1.000000;;, + 1760;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738545,-0.000005,0.000004,1.000000;;, + 1840;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738573,0.000006,-0.000004,1.000000;;, + 1920;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738564,0.000001,0.000000,1.000000;;, + 2000;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738553,-0.000003,-0.000000,1.000000;;, + 2080;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738568,-0.000013,-0.000007,1.000000;;, + 2160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738563,0.000001,-0.000003,1.000000;;, + 2240;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738546,-0.000010,0.000004,1.000000;;, + 2320;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738555,0.000009,0.000001,1.000000;;, + 2400;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738561,-0.000011,-0.000002,1.000000;;, + 2480;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738555,0.000004,-0.000001,1.000000;;, + 2560;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738554,-0.000003,-0.000003,1.000000;;, + 2640;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738580,-0.000005,-0.000007,1.000000;;, + 2720;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738547,0.000002,-0.000000,1.000000;;, + 2800;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738557,0.000008,-0.000001,1.000000;;, + 2880;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738566,-0.000006,-0.000001,1.000000;;, + 2960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738572,0.000009,-0.000003,1.000000;;, + 3040;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738565,-0.000010,-0.000004,1.000000;;, + 3120;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738559,0.000005,-0.000002,1.000000;;, + 3200;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738583,0.000002,-0.000004,1.000000;;, + 3280;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738565,0.000011,-0.000003,1.000000;;, + 3360;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738559,-0.000004,-0.000001,1.000000;;, + 3440;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738562,0.000010,-0.000000,1.000000;;, + 3520;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738569,0.000010,0.000005,1.000000;;, + 3600;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738554,0.000004,-0.000001,1.000000;;, + 3680;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738561,-0.000015,-0.000001,1.000000;;, + 3760;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738567,-0.000010,-0.000000,1.000000;;, + 3840;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738560,-0.000001,-0.000002,1.000000;;, + 3920;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738556,0.000008,-0.000003,1.000000;;, + 4000;16;1.000000,-0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738570,0.000005,-0.000004,1.000000;;, + 4080;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738561,-0.000005,-0.000003,1.000000;;, + 4160;16;1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738545,-0.000018,0.000004,1.000000;;, + 4240;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738561,0.000007,0.000004,1.000000;;, + 4320;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,-0.000000,1.000000,0.000000,15.738585,0.000006,-0.000014,1.000000;;, + 4400;16;1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738553,-0.000006,0.000002,1.000000;;, + 4480;16;1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738564,0.000006,-0.000004,1.000000;;, + 4560;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738543,0.000010,0.000013,1.000000;;, + 4640;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738590,-0.000006,-0.000010,1.000000;;, + 4720;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,15.738582,-0.000003,-0.000011,1.000000;;, + 4800;16;1.000000,0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,15.738579,0.000004,-0.000012,1.000000;;, + 4960;16;1.000000,-0.000000,-0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,15.738550,-0.000017,-0.000003,1.000000;;; + } + { Dummy11 } + } +} \ No newline at end of file diff --git a/Demos/DX11ClothDemo/Media/UI/DXUTShared.fx b/Demos/DX11ClothDemo/Media/UI/DXUTShared.fx new file mode 100644 index 0000000..0da2c6b --- /dev/null +++ b/Demos/DX11ClothDemo/Media/UI/DXUTShared.fx @@ -0,0 +1,69 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTShared.fx +// +// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- +float4 g_MaterialDiffuseColor; // Material's diffuse color +float3 g_LightDir; // Light's direction in world space +float4x4 g_mWorld; // World matrix for object +float4x4 g_mWorldViewProjection; // World * View * Projection matrix + + + +//-------------------------------------------------------------------------------------- +// Vertex shader output structure +//-------------------------------------------------------------------------------------- +struct VS_OUTPUT +{ + float4 Position : POSITION; // vertex position + float4 Diffuse : COLOR0; // vertex diffuse color +}; + + +//-------------------------------------------------------------------------------------- +// This shader computes standard transform and lighting +//-------------------------------------------------------------------------------------- +VS_OUTPUT RenderWith1LightNoTextureVS( float4 vPos : POSITION, + float3 vNormal : NORMAL ) +{ + VS_OUTPUT Output; + + // Transform the position from object space to homogeneous projection space + Output.Position = mul(vPos, g_mWorldViewProjection); + + // Transform the normal from object space to world space + float3 vNormalWorldSpace; + vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space) + + // Compute simple directional lighting equation + Output.Diffuse.rgb = g_MaterialDiffuseColor * max(0,dot(vNormalWorldSpace, g_LightDir)); + Output.Diffuse.a = 1.0f; + + return Output; +} + + +//-------------------------------------------------------------------------------------- +float4 RenderWith1LightNoTexturePS( float4 Diffuse : COLOR0 ) : COLOR0 +{ + return Diffuse; +} + + +//-------------------------------------------------------------------------------------- +technique RenderWith1LightNoTexture +{ + pass P0 + { + VertexShader = compile vs_1_1 RenderWith1LightNoTextureVS(); + PixelShader = compile ps_1_1 RenderWith1LightNoTexturePS(); + } +} + diff --git a/Demos/DX11ClothDemo/Media/UI/Font.dds b/Demos/DX11ClothDemo/Media/UI/Font.dds new file mode 100644 index 0000000000000000000000000000000000000000..37514f5bf7fdb81efc52766d02bdaec0fecd3061 GIT binary patch literal 76128 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 B8 + WORD nMaxSkinWeightsPerVertex; + WORD nMaxSkinWeightsPerFace; + WORD nBones; +} + +template VertexDuplicationIndices { + + DWORD nIndices; + DWORD nOriginalVertices; + array DWORD indices[nIndices]; +} + +template SkinWeights { + <6f0d123b-bad2-4167-a0d0-80224f25fabb> + STRING transformNodeName; + DWORD nWeights; + array DWORD vertexIndices[nWeights]; + array FLOAT weights[nWeights]; + Matrix4x4 matrixOffset; +} + + +Frame Scene_Root { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;; + } + + Frame Arrow { + + + FrameTransformMatrix { + 0.004058,0.000000,0.000000,0.000000,0.000000,0.000000,0.004058,0.000000,0.000000,-0.004058,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000;; + } + + Frame Cylinder01 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000002,116.363640,0.000002,1.000000;; + } + + Frame { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,-0.000000,0.000000,0.000003,1.000000;; + } + + Mesh { + 58; + 0.000000;0.000000;0.000000;, + 24.461134;0.000000;0.000000;, + 22.038719;-10.613288;0.000000;, + 15.251267;-19.124485;0.000000;, + 5.443114;-23.847843;0.000000;, + -5.443115;-23.847841;0.000000;, + -15.251268;-19.124485;0.000000;, + -22.038721;-10.613288;0.000000;, + -24.461134;0.000001;0.000000;, + -22.038719;10.613289;0.000000;, + -15.251266;19.124485;0.000000;, + -5.443113;23.847843;0.000000;, + 5.443115;23.847841;0.000000;, + 15.251268;19.124483;0.000000;, + 22.038721;10.613287;0.000000;, + 24.461134;0.000000;-140.000000;, + 22.038719;-10.613288;-140.000000;, + 15.251267;-19.124485;-140.000000;, + 5.443114;-23.847843;-140.000000;, + -5.443115;-23.847841;-140.000000;, + -15.251268;-19.124485;-140.000000;, + -22.038721;-10.613288;-140.000000;, + -24.461134;0.000001;-140.000000;, + -22.038719;10.613289;-140.000000;, + -15.251266;19.124485;-140.000000;, + -5.443113;23.847843;-140.000000;, + 5.443115;23.847841;-140.000000;, + 15.251268;19.124483;-140.000000;, + 22.038721;10.613287;-140.000000;, + 0.000000;0.000000;-140.000000;, + 24.461134;0.000000;0.000000;, + 22.038719;-10.613288;0.000000;, + 15.251267;-19.124485;0.000000;, + 5.443114;-23.847843;0.000000;, + -5.443115;-23.847841;0.000000;, + -15.251268;-19.124485;0.000000;, + -22.038721;-10.613288;0.000000;, + -24.461134;0.000001;0.000000;, + -22.038719;10.613289;0.000000;, + -15.251266;19.124485;0.000000;, + -5.443113;23.847843;0.000000;, + 5.443115;23.847841;0.000000;, + 15.251268;19.124483;0.000000;, + 22.038721;10.613287;0.000000;, + 24.461134;0.000000;-140.000000;, + 22.038719;-10.613288;-140.000000;, + 15.251267;-19.124485;-140.000000;, + 5.443114;-23.847843;-140.000000;, + -5.443115;-23.847841;-140.000000;, + -15.251268;-19.124485;-140.000000;, + -22.038721;-10.613288;-140.000000;, + -24.461134;0.000001;-140.000000;, + -22.038719;10.613289;-140.000000;, + -15.251266;19.124485;-140.000000;, + -5.443113;23.847843;-140.000000;, + 5.443115;23.847841;-140.000000;, + 15.251268;19.124483;-140.000000;, + 22.038721;10.613287;-140.000000;; + 56; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,1,14;, + 3;30,16,15;, + 3;30,31,16;, + 3;31,17,16;, + 3;31,32,17;, + 3;32,18,17;, + 3;32,33,18;, + 3;33,19,18;, + 3;33,34,19;, + 3;34,20,19;, + 3;34,35,20;, + 3;35,21,20;, + 3;35,36,21;, + 3;36,22,21;, + 3;36,37,22;, + 3;37,23,22;, + 3;37,38,23;, + 3;38,24,23;, + 3;38,39,24;, + 3;39,25,24;, + 3;39,40,25;, + 3;40,26,25;, + 3;40,41,26;, + 3;41,27,26;, + 3;41,42,27;, + 3;42,28,27;, + 3;42,43,28;, + 3;43,15,28;, + 3;43,30,15;, + 3;29,44,45;, + 3;29,45,46;, + 3;29,46,47;, + 3;29,47,48;, + 3;29,48,49;, + 3;29,49,50;, + 3;29,50,51;, + 3;29,51,52;, + 3;29,52,53;, + 3;29,53,54;, + 3;29,54,55;, + 3;29,55,56;, + 3;29,56,57;, + 3;29,57,44;; + + MeshNormals { + 58; + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.997118;0.075862;0.000000;, + 0.931288;-0.364284;0.000000;, + 0.681004;-0.732279;0.000000;, + 0.295840;-0.955238;0.000000;, + -0.147920;-0.988999;0.000000;, + -0.562382;-0.826878;0.000000;, + -0.865457;-0.500983;0.000000;, + -0.997118;-0.075862;0.000000;, + -0.931288;0.364284;0.000000;, + -0.681004;0.732279;0.000000;, + -0.295840;0.955238;0.000000;, + 0.147920;0.988999;0.000000;, + 0.562382;0.826878;0.000000;, + 0.865457;0.500983;0.000000;, + 0.000000;0.000000;-1.000000;, + 0.997118;-0.075862;0.000000;, + 0.865457;-0.500983;0.000000;, + 0.562382;-0.826878;0.000000;, + 0.147920;-0.988999;0.000000;, + -0.295840;-0.955238;0.000000;, + -0.681004;-0.732279;0.000000;, + -0.931288;-0.364284;0.000000;, + -0.997118;0.075862;0.000000;, + -0.865457;0.500983;0.000000;, + -0.562382;0.826878;0.000000;, + -0.147920;0.988999;0.000000;, + 0.295840;0.955238;0.000000;, + 0.681004;0.732279;0.000000;, + 0.931288;0.364284;0.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;; + 56; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,1,14;, + 3;30,16,15;, + 3;30,31,16;, + 3;31,17,16;, + 3;31,32,17;, + 3;32,18,17;, + 3;32,33,18;, + 3;33,19,18;, + 3;33,34,19;, + 3;34,20,19;, + 3;34,35,20;, + 3;35,21,20;, + 3;35,36,21;, + 3;36,22,21;, + 3;36,37,22;, + 3;37,23,22;, + 3;37,38,23;, + 3;38,24,23;, + 3;38,39,24;, + 3;39,25,24;, + 3;39,40,25;, + 3;40,26,25;, + 3;40,41,26;, + 3;41,27,26;, + 3;41,42,27;, + 3;42,28,27;, + 3;42,43,28;, + 3;43,15,28;, + 3;43,30,15;, + 3;29,44,45;, + 3;29,45,46;, + 3;29,46,47;, + 3;29,47,48;, + 3;29,48,49;, + 3;29,49,50;, + 3;29,50,51;, + 3;29,51,52;, + 3;29,52,53;, + 3;29,53,54;, + 3;29,54,55;, + 3;29,55,56;, + 3;29,56,57;, + 3;29,57,44;; + } + + VertexDuplicationIndices { + 58; + 30; + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28; + } + + MeshMaterialList { + 1; + 56; + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0; + + Material { + 1.000000;1.000000;1.000000;1.000000;; + 0.000000; + 1.000000;1.000000;1.000000;; + 0.000000;0.000000;0.000000;; + } + } + } + } + } + + Frame Cone01 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,116.363640,0.000000,1.000000;; + } + + Frame { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000003,1.000000;; + } + + Mesh { + 98; + 0.000000;0.000000;0.000000;, + 58.922840;0.000000;0.000000;, + 56.915092;15.250354;0.000000;, + 51.028675;29.461420;0.000000;, + 41.664738;41.664742;0.000000;, + 29.461418;51.028679;0.000000;, + 15.250351;56.915092;0.000000;, + -0.000003;58.922840;0.000000;, + -15.250356;56.915092;0.000000;, + -29.461424;51.028675;0.000000;, + -41.664742;41.664738;0.000000;, + -51.028679;29.461416;0.000000;, + -56.915092;15.250349;0.000000;, + -58.922840;-0.000005;0.000000;, + -56.915092;-15.250359;0.000000;, + -51.028675;-29.461426;0.000000;, + -41.664734;-41.664745;0.000000;, + -29.461414;-51.028679;0.000000;, + -15.250346;-56.915096;0.000000;, + 0.000008;-58.922840;0.000000;, + 15.250361;-56.915092;0.000000;, + 29.461428;-51.028671;0.000000;, + 41.664745;-41.664734;0.000000;, + 51.028683;-29.461412;0.000000;, + 56.915096;-15.250343;0.000000;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 58.922840;0.000000;0.000000;, + 56.915092;15.250354;0.000000;, + 51.028675;29.461420;0.000000;, + 41.664738;41.664742;0.000000;, + 29.461418;51.028679;0.000000;, + 15.250351;56.915092;0.000000;, + -0.000003;58.922840;0.000000;, + -15.250356;56.915092;0.000000;, + -29.461424;51.028675;0.000000;, + -41.664742;41.664738;0.000000;, + -51.028679;29.461416;0.000000;, + -56.915092;15.250349;0.000000;, + -58.922840;-0.000005;0.000000;, + -56.915092;-15.250359;0.000000;, + -51.028675;-29.461426;0.000000;, + -41.664734;-41.664745;0.000000;, + -29.461414;-51.028679;0.000000;, + -15.250346;-56.915096;0.000000;, + 0.000008;-58.922840;0.000000;, + 15.250361;-56.915092;0.000000;, + 29.461428;-51.028671;0.000000;, + 41.664745;-41.664734;0.000000;, + 51.028683;-29.461412;0.000000;, + 56.915096;-15.250343;0.000000;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;; + 96; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,15,14;, + 3;0,16,15;, + 3;0,17,16;, + 3;0,18,17;, + 3;0,19,18;, + 3;0,20,19;, + 3;0,21,20;, + 3;0,22,21;, + 3;0,23,22;, + 3;0,24,23;, + 3;0,1,24;, + 3;50,26,25;, + 3;50,51,26;, + 3;51,27,26;, + 3;51,52,27;, + 3;52,28,27;, + 3;52,53,28;, + 3;53,29,28;, + 3;53,54,29;, + 3;54,30,29;, + 3;54,55,30;, + 3;55,31,30;, + 3;55,56,31;, + 3;56,32,31;, + 3;56,57,32;, + 3;57,33,32;, + 3;57,58,33;, + 3;58,34,33;, + 3;58,59,34;, + 3;59,35,34;, + 3;59,60,35;, + 3;60,36,35;, + 3;60,61,36;, + 3;61,37,36;, + 3;61,62,37;, + 3;62,38,37;, + 3;62,63,38;, + 3;63,39,38;, + 3;63,64,39;, + 3;64,40,39;, + 3;64,65,40;, + 3;65,41,40;, + 3;65,66,41;, + 3;66,42,41;, + 3;66,67,42;, + 3;67,43,42;, + 3;67,68,43;, + 3;68,44,43;, + 3;68,69,44;, + 3;69,45,44;, + 3;69,70,45;, + 3;70,46,45;, + 3;70,71,46;, + 3;71,47,46;, + 3;71,72,47;, + 3;72,48,47;, + 3;72,73,48;, + 3;73,25,48;, + 3;73,50,25;, + 3;49,74,75;, + 3;49,75,76;, + 3;49,76,77;, + 3;49,77,78;, + 3;49,78,79;, + 3;49,79,80;, + 3;49,80,81;, + 3;49,81,82;, + 3;49,82,83;, + 3;49,83,84;, + 3;49,84,85;, + 3;49,85,86;, + 3;49,86,87;, + 3;49,87,88;, + 3;49,88,89;, + 3;49,89,90;, + 3;49,90,91;, + 3;49,91,92;, + 3;49,92,93;, + 3;49,93,94;, + 3;49,94,95;, + 3;49,95,96;, + 3;49,96,97;, + 3;49,97,74;; + + MeshNormals { + 98; + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.886052;-0.116651;0.448669;, + 0.886052;0.116651;0.448669;, + 0.825669;0.342004;0.448669;, + 0.709018;0.544049;0.448669;, + 0.544049;0.709018;0.448669;, + 0.342003;0.825669;0.448669;, + 0.116651;0.886052;0.448669;, + -0.116651;0.886052;0.448669;, + -0.342003;0.825669;0.448669;, + -0.544049;0.709018;0.448669;, + -0.709018;0.544049;0.448669;, + -0.825669;0.342003;0.448669;, + -0.886052;0.116651;0.448669;, + -0.886052;-0.116651;0.448669;, + -0.825669;-0.342003;0.448669;, + -0.709018;-0.544049;0.448669;, + -0.544049;-0.709018;0.448669;, + -0.342003;-0.825669;0.448669;, + -0.116651;-0.886052;0.448669;, + 0.116651;-0.886052;0.448669;, + 0.342004;-0.825669;0.448669;, + 0.544049;-0.709018;0.448669;, + 0.709018;-0.544049;0.448669;, + 0.825669;-0.342003;0.448669;, + 1.000000;0.000000;0.000000;, + 0.892143;0.000000;0.451753;, + 0.861744;0.230904;0.451753;, + 0.772619;0.446072;0.451753;, + 0.630840;0.630840;0.451753;, + 0.446072;0.772619;0.451753;, + 0.230904;0.861744;0.451753;, + 0.000000;0.892143;0.451753;, + -0.230904;0.861744;0.451753;, + -0.446072;0.772619;0.451753;, + -0.630840;0.630840;0.451753;, + -0.772619;0.446071;0.451753;, + -0.861744;0.230904;0.451753;, + -0.892143;-0.000000;0.451753;, + -0.861744;-0.230904;0.451753;, + -0.772619;-0.446072;0.451753;, + -0.630840;-0.630841;0.451753;, + -0.446072;-0.772619;0.451753;, + -0.230904;-0.861744;0.451753;, + 0.000000;-0.892143;0.451753;, + 0.230904;-0.861744;0.451753;, + 0.446072;-0.772619;0.451753;, + 0.630840;-0.630840;0.451753;, + 0.772619;-0.446071;0.451753;, + 0.861744;-0.230903;0.451753;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;; + 96; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,15,14;, + 3;0,16,15;, + 3;0,17,16;, + 3;0,18,17;, + 3;0,19,18;, + 3;0,20,19;, + 3;0,21,20;, + 3;0,22,21;, + 3;0,23,22;, + 3;0,24,23;, + 3;0,1,24;, + 3;50,26,25;, + 3;50,51,26;, + 3;51,27,26;, + 3;51,52,27;, + 3;52,28,27;, + 3;52,53,28;, + 3;53,29,28;, + 3;53,54,29;, + 3;54,30,29;, + 3;54,55,30;, + 3;55,31,30;, + 3;55,56,31;, + 3;56,32,31;, + 3;56,57,32;, + 3;57,33,32;, + 3;57,58,33;, + 3;58,34,33;, + 3;58,59,34;, + 3;59,35,34;, + 3;59,60,35;, + 3;60,36,35;, + 3;60,61,36;, + 3;61,37,36;, + 3;61,62,37;, + 3;62,38,37;, + 3;62,63,38;, + 3;63,39,38;, + 3;63,64,39;, + 3;64,40,39;, + 3;64,65,40;, + 3;65,41,40;, + 3;65,66,41;, + 3;66,42,41;, + 3;66,67,42;, + 3;67,43,42;, + 3;67,68,43;, + 3;68,44,43;, + 3;68,69,44;, + 3;69,45,44;, + 3;69,70,45;, + 3;70,46,45;, + 3;70,71,46;, + 3;71,47,46;, + 3;71,72,47;, + 3;72,48,47;, + 3;72,73,48;, + 3;73,25,48;, + 3;73,50,25;, + 3;49,74,75;, + 3;49,75,76;, + 3;49,76,77;, + 3;49,77,78;, + 3;49,78,79;, + 3;49,79,80;, + 3;49,80,81;, + 3;49,81,82;, + 3;49,82,83;, + 3;49,83,84;, + 3;49,84,85;, + 3;49,85,86;, + 3;49,86,87;, + 3;49,87,88;, + 3;49,88,89;, + 3;49,89,90;, + 3;49,90,91;, + 3;49,91,92;, + 3;49,92,93;, + 3;49,93,94;, + 3;49,94,95;, + 3;49,95,96;, + 3;49,96,97;, + 3;49,97,74;; + } + + VertexDuplicationIndices { + 98; + 50; + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48; + } + + MeshMaterialList { + 1; + 96; + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0; + + Material { + 1.000000;1.000000;1.000000;1.000000;; + 0.000000; + 1.000000;1.000000;1.000000;; + 0.000000;0.000000;0.000000;; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Demos/DX11ClothDemo/Media/UI/dxutcontrols.dds b/Demos/DX11ClothDemo/Media/UI/dxutcontrols.dds new file mode 100644 index 0000000000000000000000000000000000000000..b5f52e10af505a56f0f4850202e7c5da27c571dc GIT binary patch literal 262272 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ⅇ-=EcR-gA#H-s|5f?(5pYwb#e_ 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 literal 0 HcmV?d00001 diff --git a/Demos/DX11ClothDemo/amdFlag.bmp b/Demos/DX11ClothDemo/amdFlag.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd1d394ec7ef603cd68b9956780c5430106dc9f8 GIT binary patch literal 1396038 zcmeI*39#jNSttCHeFGutt7wUZVu58b&MQ`FQR9jOF6B%yRceie0zyc-JDrWq5(C1^ z7Ls(*=}u=M3qg>Xw|GaQpcaC_C?au$aWHIw1VVri5X{m`db{U+&V7;}CwJpX)0r{P z{T$oF|D5}r|M@?k=j40-_kWiA)c^4G|L}iJW~ZNs|Nr6m|NTcyCYK&HnH({B% zd+)tBu8eEqls_HkSrgZfd(Y)ju-g4bS+us~r+M2YSI%D?1!H0UrXlmtu2dDQ;r*}=KyJq*Ye|m7= zbl;v8R-9Muzh`>yp6S8q&iJ=~Z`{w~TBp1B$B_5MwoMQ2nI4$U{A+vf-MRSVRafN) zZ3JX~n^At#Mk3-eMI(qZi{d<@I8Jff$dEYSyEk&-L7#H9xrPkVi1GPE-MxGFSn0Sv zZe_ecH#f`b6ei}A20p0U%2%8U)}QmK7Ggazr5vb|9<6vZ~c!~|F<*m z-WyL7`AoNP;Nbq*lj|y{#lWBLo9^Cw@a}j9j`ZKZ=Ro}L;`Mv}=}YhUmwRrHCyr@6 zj~tvHJTQA0IJFm$`RzwM8jSFXd>ctM_Q0bcGBEa6=Ob&}s<@C5ovWJPZy(pkk9O_a zwd7Zc2*&x%$PE~qF@M|DHY0AH>x_a}&H&HkUw)pOH$pzvKQ?uF@fz3c+!=etvs2u4 zG?mNaJhp#4$Hjfcdd82IEqv+BYma>PMU%~!ov`5zlhd|MPKo8qC!2Sy{O{DuCmSw$ z^aa=b`d#JdXyJCdizsj}#H`bqP7*82%Rp0-6O>WHEmCJvc zw;Fr$Q4o2W_defdwzk$?EbRN8*B^7rmLt#D@omrFG1<8F=+m|wv+t_dirVIP_9+dg3F*dti<~JMY8tvS3&pki><3E1XQAfqlPdxF& zIFHj2M;wvY9CzGtpZe6N*0}lFKZ*c+?sK0TD>?GWBXiBU+GCD6CNI9`HLv;SfBxrO z$xB}HlH7o-$%3PgJ~|fS`dC%uWHG=qQAg6g;~no9_n51lKhNS=b1p==H$s50F*3;Z~` zHoJKDEqA>8y8eWo0W|9qW(%_QyWew zXU2ZCyhie&gc8bi>x;Pu(#&b?ao~ zm6OxA9dYVKlTDXR&bV}yf0rEh{0k;$UwOpFD<&Ja9dW^b`S&~b-ZWj~Fnomk!T23y z=Y3BN2ln4~=U=|!nxA;?*2(58CY!fE>ZZ?rVBg(wT<5NMR#@Y8fp2WErH8*jJaixa zP3Yj82;}}}oZofVT_>M>a%OU-)`lJUZ+Le*^v8nUFQ{=PT&-~2Ky!+knp1-5f&e+axEbN<}zV*b-mmP7&r6-(m z+2qvoj@^9G(dR6Nf8_u2e;Y5E#4(>2?0D1}J0_=WpKQ2f^2*D9b~?TF8!KG0bm0CM zZD)sc?vB8J$z@Ocor@=DT{(HdmB&5%|2gtAU;N9(TkMJV@a$cX`b+qFUW|uy&&G7M ziokFG_HSp7McQZT=2JjM-yi?+ALkD6Dz{$w>bS|1pZw%l?ff%HtT1C(qdhDBJLj6%IiH-q z<*4VMKRN4)BR0hH)%H!(Y_q}L4JrIXMXYV-b%!^Ohbnywd z-u?CivzG%79NZhPvFq=RNPqb2e-_;f#2@P8`zNF*#%FQ5!BkD)M~ew#hkH9)0>HlhZGa<2jQTUU@`RuK4fO z|Me&KEZjETHI3u;2d4Ytvk?blzkRwZ4$()L$Fy#{^F6EzjdrV^i;6SUK}I#d|fcm__~O zOO83?qT|lodh9vdPTF+dai?E$)QbP&6@iyu`S0%9{i(RGd3KX#*J_zVVH34C(P4 zkqZwt^K(|QhoAADD;cYO=rTX=clmj|IWyj(`D?%SYnkoAnC<6tXf6+jCp_T^U;gr! zVmRzzk2SA&iU(5evBxJ4Ui6|DMau~?1mahx zFo}!#CfKvjK6^a&#`Z5>vvTIY;L0P;+IqqnmmIh8vdMEUjD7fT-*oZG8@3-Cuk)_> z@2stl-gM!K8!nza_rl5fZ+hCo^s5U8?z-ci55zJ2IHVJM_!0Q=yThqlCNH_>q|@SM zT*vdrJl5YrJS^8=)9bP05u4fkEw|hfqaUaFsLv#i5L@vyZW0S|tEid3CW9{55Z6bx zkNX|TA1V4^Ge5R@$xd=y6Kl?u#|pElxOjMv=jUoyJkK}eWb(%c!Q#+;I?NyDdc-3h z5m(01o=E-=fB3_(p0TO-AM9E=^JibbaPd)_w;sPCUdFxbF(3WnbvJ$SuRig`KfC4j z_pJEu=CA+J&0oI$3p?NW@vpowUY7mZZSg&9```Y-bK^zZIEEjGbYc&G7Wmg46L0T4 zeVfc*air_z%6Lq!msZzzpP4qfr=9Wp3%~FS8POxU<6>Tu@wNPXNy5j)xNY2I$@O`| z2)f&DyDi_4AFp7Jo&31w5Hf#!cSI~?)WzsykZp&)IR(8COl7citnW)7#?+{oeTA7IkrJKpx+x5V2rXYbP465r%-WE|4jynXf-&CT17b8KhKVjV8TgL55rt>qNR zH`T{uU?l%|3*!8h7V{7)|{E2cah7H`MHu<&+^lJWiGG%{`{<|pa0+w{$Si`a;0tJ#3sc; zem-|RLoKfM)2F`jhvJ=78CFF$reyaOlp@OMn&T{>}KXVdoMpMTlnf1zu> zdw%f~w6iZMn!V3{AwGN?>%RB;8~$LH?W_Is{`~q}dsW6mv{ysAc@P3Ged$Z%0gySL zahm6OQ2IxI^he`eI!}N4)8i;mzE>wM#%^}Jz5gjsc}jfASlo6zYvc_x;^O+aRR;Bn zTeDi`#|`7TBX)yh$3FM%0^=!iY;E)vr}&n+Fv%yf*yhFX-~a4apSbbr$!S}UnH|HAx7KVu`h}OB zAoJHi_M>l6ARda};u_ri;VbazPk%ZxYJT5-#8e!Mc%NN$j{8-7TkA%$RUvd~~7NCkS#qAm z`6QCdhj%~!^Pm5G-g}?&QxtB>Taew{P5W>~k)N*J>Xf@5$K^ zAH}`sIGI1jYT>X8#D5freVtbLa1n@5{l#DW#ra?ynIBii&U`eIsXJbQjcejo@$%)5 z{K${w4aYlGGT9=u<8xS%z~d#(Z+gj`F^K`Imn= zUlkoO9>-7STbOSxmUBx+aa=sSnI9|s-tYb1xT8F}HJ$`xYh(L=;0JzS*#^Yx5eGhW z%Vp0wKMuki_q+=yXJ0*;eUX}DJ1OP-ArKho{Z|>v6dTicr!mX;8%b3S7Y+aNKFs z#3{CR_SCa)@sHmgJn-SqULBvMJ>}xb3obu-b9@d<=8wmUg~Kfn56Hv4O6z+#2}EGV z{%7XWh^g3B&i(2$&pb1l$xzL%a)&>@U}ro{L~)$*wsEWYwt=sG?Q3fUeynG;%+KB9 z@teihzy9@n)gU(}Lq2Qr?(&7>%PzYt?k=AxKJbALWG^e8XA2MAetxVuKB6@!VjD*I zXA7|b;~8y6w0C-M{K=9?{^`Gbb~Q=aWlZANP{U8Oynmu@J{k;#uI5OD>69MdZHsz3+`HS3BjJAG*ws^~aw8 zOOpf{TasPm2IP4(7=M#|8h?3y@okoI6zwB7zwx=RIp)kAC(8VJD9eXeARd#4cZJsW z@Dhjsj89HwA}xujd{53>-}=^w`jL~dpZ~hoy)GU$k-%{rCKg8iXAXb%v!DH@0&8S` zqIEXEBGTheyN=!ISco{yixE@tZj)$Yb|7N$6q*0H$2~3{HX~Zc4da^e z_4{kQfE%k>Bl9yDpCOA4$g=wuVn=`9>`nD?n*G_5>E2y?zkb7q|9aE5N5vPT z#aC<2zBA#qC&Z2J`w;F5AHiMxQ0{Cvu`nx~EyNeB9o+NI54~>HH|P5t?hI?4p5niY zb=tYM=LGVV+}Ov?bj=;q%&xdH-hvplu@@bAb=6f@&8OMO)kxa7ZR~7EWyad<(8VgJ zH8MX|5(jF&{oB7i*F2w}@uRqy_a47u#689-%i?(_PCxczKlb*wzkO`d@`c=-k-Bm5 z(Dw5)@Z-5MPPxu(Hr}lizj4gpZ*1_`$ap%);=I*tGZsHIo0-3NU;L5sSlcZ2|K@*P z_2R1^^UMn-FT6UwNHac%`}Ku|dxJARd$r=f`;HDR#0vvqzBeu&T-f<%|Kn9MKf#^P z3&i7d{-Wh|B{0G#7Gm!`_C@FODqbPYyt?qh3kS~=kGtTZ~uY#uAEuy$Ju|s@q(9Jb8`H# z^7zA8)9Iai@7)=H0Bcsc;=kFmYdmGdZwhhqdl#PqcK!K>W&U{BTKI-Q{HO7a3zpWI zz4l?nK2bf8^QZSKlDRc`LU0EEDoVW&G=~)#3^qTzbuR+9&1Ccwx1vS>SF`) z#e#87W@&tV<@_to@zcCM&-2+~tYP^=Zq?z+{8(EY!pgN}j6df&&xtz?ob(C0*uq?n z>*IHjS=#U53pZ+OeHnL;gAwv7b+fpZUyZ@~LOsX>40;VYU!& zVU5?yV*|1{){y)8k@oG?qXhYh=0J<6A1q@7e)BhfbN*Iw z+sOH`B@z3xz5Q|AW|sJiM{D*U_~@-~j>U-c{fi&qT8Mr4<^N`H_&l)qotujb@r%OV zU4Qzwua)^}?tES#9+UGIEw3wqjGYY9$e-)4zdrY$<54m8oMSn5Ut=Hp>Z`BL<$PYq z^W2qZ@>M?PkwUVdu&xK zsF2}{?r`(wNZ9BBgk2Pe}=OLX4{P>dR*z7oE+7G?BCblP@E5{##pTGCWFKUS4r>=}o2Vh?|8@ciASRs85FPkBn-b(&-gc}+Am+n)HpXfBV>%({%w-ak8< zvoQVI-Wxvo(VIX1xf?$A)pvj53-4X=-zPtF!%bg!|4pC&z^6XY}wCq52v?z!jY zm#W43gC$O}8F3yLV+d`slk2Z(9X~)IQz*hMu8r?B zi;Rj#MTB|oKj(6s=V9|$h*QMch~=}+Ix7Ng9CeA6WKKTdJ|1{swam|u%wHd3ISw?% z0i3UV%m@DbPX1!x#~W^T?>!g?WM*&I-@oU;?0@&h+3qjydjAVAep37q^Z1*# z@h1*vfAMOy06&E5W&Q&mN9*W9JVe(~w_05$5CNERJ#r~tZOpy*%-#`VxiA8G{4|~> z##%G&4>|MWF7mEpA)Z#^y+HY1m$Clk3vsmM&2N75*vPR}wIV;fdHjVG5_ zhz*XKaWAnPPXT#6KNjNKhsH6kxZnGZ?kdd7JF1R35E`xnZ+K-D*deW2Tb8IXp%aV)pR;y)x+-ZLN_PXn? zi~3l@8aw$>5I-GH3K9EHed<$V4P*1Nh57U48@6`lNBb+Da-H#`Nc%X?i}A8TzOwL3 zzw}EV{pd&IzGB;=g|UU>-oLTgi~IJoLpt$Zomf7w|F%2-@)g(oM7(Gl$MEBj&g?tZ zBJi&}X2T_u)8kK~AHs3_)o$W=e$He4oyWs<{WY!Q`vfwMM&{??ortMB?zrRRlTVJv zM()r?ism7g%(oG$@t*luQQkam6{n)?YMGyh!LPjX$_Vh0_G9ywuRQN@*RD7MK0D=` z_A`N3JkPTE?OZ$aS6oS48NUPt!f+T1@z>!$_`wg3_2-r^$^5u7uDP$N_?m>p7i||0 z>D(QG|B}m|_&XQR-lY>S+Qu>bIHVJM_!0OUFP&`KcC^gT2|E8)1mXewt=!ygAJzhq zP9u?)1k^L1`OHlC@ht}#fN^C;T)as#dXJlrh>MG{oTs%}R?Gaji&IZMH9y-G>sfmx z`O_?mjn9KrAOHBr$A`IcgXhoZZ<5Q0mif8P*vSuy_&i#CemS20;*I*T&fJXHs)Ws_ z(Y&uE=ZoOG?|ad9dLRzz#2$VG{-!ri;%%9;cj;`I#4-Fhq_cVZ5fS*Cw;w0-ml(Qu z2m#Zx{*jpwOYf4pG5V&&RbzVxLpjZKX%KKHrLjo(KyH#Idj{iZ~FXSF2w5y@!iYQ{d?E?LZ7v| z@Uw@PfXsh*&Fg>L)<%NOf0shuZ^U~faQrAfgf+5mEIg=fi)_!J9#I)9&%lrM%c@@sE@@s&^foh_5+T|9fO zcH{X+&ko}}l>Z{|H(V934op7tmFwddjrg}WzS48{g0fS80h!-_#t**3`52FEjO>k2 zT`_?pb>l}5{vKvWf$~-(^G67ew~vmRHP%0BVm)J3Yt)Y)#SI@+{kUN+#LeRr+Z?A{ zUQ$rG7+)rF2lq&(+UM{U03qzyYJ59z z-ZwPc(?2l#jl*dj2*~_(FyupQG14r;KLTz3_9NmBIq2rs7V95RB^jaPVlj~CH)9t1 z2i8ii`00{+jJsR=Ci7c6mIuPP=Fk=n?wNk!%b)pQxBlt>yyb1T-2TB&-u%~}{=&OH zd*^@q^ylCAkp7E9I^Hl%pwdIv`-@EwrZnG_zeH_@Sy@1Sb zKjK4cF!C_7G-53l@@UU|{Kl1;nNe_PcM)sI8^+4>?&7G1;{&h-4hYK_-C+o?%wzH#k4Qn^jj&3iRI81 zzt3~_ci3YT_mAUSS+U#x>lcvu|N3Y2e`E_I6*B|#-sdl7Y{vQgQ^14T$Xs(Id@RJ8 zS9}#Ue^gv;W`5kH61;Jb^IIMli}$jmEbp#zk4tViF7A)NdmdqXAaXzUu@CIpyEAfk z@e9^w->mu2{hPf@=fJ)=h98G?X1`<10)O$}*fI-!1!R8T*&cdlBRnI}a^HA9*+yVS zS=`6Bl9}_H7^_|JUdBhR=8JPV?mD(1&f_$$iG{dw#Z#<5t{>|e7gsD^*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj z0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+ zfB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ)DR#*pof6W?=eSR z5FkLHA|UfCN@@rYAkafV=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq z0t5*35Rmyj=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu z7X%0ps0hgXijo=v1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}oGQXmv zh5!KqJp^Qak2&gs009CO0hwP>QbT|MfgS=fzsDSPL4W{(ih#_oD5)VpfItrcncriM zx*$M+Kt(|2SCrHcAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQ zH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX82=ow;`90>S3jzcPR0L#xMM(_-0t9*p$ow92 z)CB*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|i zNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH z9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ)DR#*pof6W?=eSR5FkLHA|UfC zN@@rYAkafV=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj z=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgX zijo=v1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qa zk2&gs009CO0hwP>QbT|MfgS=fzsDSPL4W{(ih#_oD5)VpfItrcncriMx*$M+Kt(|2 zSCrHcAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{=pi8U zd(2T61PBnQ2*~`3k{SX82=ow;`90>S3jzcPR0L#xMM(_-0t9*p$ow92)CB*#AW#vI z`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_ z{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t z%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ)DR#*pof6W?=eSR5FkLHA|UfCN@@rYAkafV z=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj=BNt-1PD|F zWPU|S4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsH zkoi64s0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qak2&gs009CO z0hwP>QbT|MfgS=fzsDSPL4W{(ih#_oD5)VpfItrcncriMx*$M+Kt(|2SCrHcAV8pp zfXwePM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ z2*~`3k{SX82=ow;`90>S3jzcPR0L#xMM(_-0t9*p$ow92)CB*#AW#vI`4uHK1PBo5 zAt3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E1pxvC zDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY z4*{9qV~)BYK!89+K;~DJ)DR#*pof6W?=eSR5FkLHA|UfCN@@rYAkafV=J%MRE(j1H zP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S4FLiK zdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsHkoi64s0#uF z2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qak2&gs009CO0hwP>QbT|M zfgS=fzsDSPL4W{(ih#_oD5)VpfItrcncriMx*$M+Kt(|2SCrHcAV8ppfXwePM_mvg zK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX8 z2=ow;`90>S3jzcPR0L#xMM(_-0t9*p$ow92)CB*#AW#vI`4uHK1PBo5At3X6%uyEv z2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ z0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BY zK!89+K;~DJ)DR#*pof6W?=eSR5FkLHA|UfCN@@rYAkafV=J%MRE(j1HP!W*%6(uzU z2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M z0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsHkoi64s0#uF2vh`Qenm+Q z0RjYi2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qak2&gs009CO0hwP>QbT|MfgS=fzsDSP zL4W{(ih#_oD5)VpfItrcncriMx*$M+Kt(|2SCrHcAV8ppfXwePM_mvgK%gQZ^D9bf z2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX82=ow;`90>S z3jzcPR0L#xMM(_-0t9*p$ow92)CB*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u z8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1 z>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ z)DR#*pof6W?=eSR5FkLHA|UfCN@@rYAkafV=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7 zQ5OUV5U2>q{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn0y4j% zq=o*6 zB{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi2*~^% zbJPU^0t6}oGQXmvh5!KqJp^Qak2&gs009CO0hwP>QbT|MfgS=fzsDSPL4W{(ih#_o zD5)VpfItrcncriMx*$M+Kt(|2SCrHcAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9LqO*D zn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX82=ow;`90>S3jzcPR0L#x zMM(_-0t9*p$ow92)CB*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBw zJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7 zUr|y+fB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ)DR#*pof6W z?=eSR5FkLHA|UfCN@@rYAkafV=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q z{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw z^Lxxu7X%0ps0hgXijo=v1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}o zGQXmvh5!KqJp^Qak2&gs009CO0hwP>QbT|MfgS=fzsDSPL4W{(ih#_oD5)VpfItrc zncriMx*$M+Kt(|2SCrHcAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(y zkogrQH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX82=ow;`90>S3jzcPR0L#xMM(_-0t9*p z$ow92)CB*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D z1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW z0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ)DR#*pof6W?=eSR5FkLH zA|UfCN@@rYAkafV=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*3 z5Rmyj=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0p zs0hgXijo=v1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}oGQXmvh5!Kq zJp^Qak2&gs009CO0hwP>QbT|MfgS=fzsDSPL4W{(ih#_oD5)VpfItrcncriMx*$M+ zKt(|2SCrHcAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{ z=pi8Ud(2T61PBnQ2*~`3k{SX82=ow;`90>S3jzcPR0L#xMM(_-0t9*p$ow92)CB*# zAW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux4 z1bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl} z0D+2t%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ)DR#*pof6W?=eSR5FkLHA|UfCN@@rY zAkafV=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj=BNt- z1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v z1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qak2&gs z009CO0hwP>QbT|MfgS=fzsDSPL4W{(ih#_oD5)VpfItrcncriMx*$M+Kt(|2SCrHc zAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T6 z1PBnQ2*~`3k{SX82=ow;`90>S3jzcPR0L#xMM(_-0t9*p$ow92)CB*#AW#vI`4uHK z1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E z1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t%&#b^ zAwYmY4*{9qV~)BYK!89+K;~DJ)DR#*pof6W?=eSR5FkLHA|UfCN@@rYAkafV=J%MR zE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S z4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsHkoi64 zs0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qak2&gs009CO0hwP> zQbT|MfgS=fzsDSPL4W{(ih#_oD5)VpfItrcncriMx*$M+Kt(|2SCrHcAV8ppfXweP zM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ2*~`3 zk{SX82=ow;`90>S3jzcPR0L#xMM(_-0t9*p$ow92)CB*#AW#vI`4uHK1PBo5At3X6 z%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXU zqNIiZ0RlY)WPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9q zV~)BYK!89+K;~DJ)DR#*pof6W?=eSR5FkLHA|UfCN@@rYAkafV=J%MRE(j1HP!W*% z6(uzU2oUHYAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S4FLiKdI-q; z9&^+M0RjXn0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsHkoi64s0#uF2vh`Q zenm+Q0RjYi2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qak2&gs009CO0hwP>QbT|MfgS=f zzsDSPL4W{(ih#_oD5)VpfItrcncriMx*$M+Kt(|2SCrHcAV8ppfXwePM_mvgK%gQZ z^D9bf2oNC9LqO*Dn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX82=ow; z`90>S3jzcPR0L#xMM(_-0t9*p$ow92)CB*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U z$oz_u8Uh3e^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY) zWPXo1>Vg0P0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BYK!89+ zK;~DJ)DR#*pof6W?=eSR5FkLHA|UfCN@@rYAkafV=J%MRE(j1HP!W*%6(uzU2oUHY zAoF|7Q5OUV5U2>q{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn z0y4j%q=o*6B{c*H5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi z2*~^%bJPU^0t6}oGQXmvh5!KqJp^Qak2&gs009CO0hwP>QbT|MfgS=fzsDSPL4W{( zih#_oD5)VpfItrcncriMx*$M+Kt(|2SCrHcAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9 zLqO*Dn4>NT5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX82=ow;`90>S3jzcP zR0L#xMM(_-0t9*p$ow92)CB*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e z^bnBwJ?5wj0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P z0u=$7Ur|y+fB=CW0y4kH9Cbl}0D+2t%&#b^AwYmY4*{9qV~)BYK!89+K;~DJ)DR#* zpof6W?=eSR5FkLHA|UfCN@@rYAkafV=J%MRE(j1HP!W*%6(uzU2oUHYAoF|7Q5OUV z5U2>q{ECtq0t5*35Rmyj=BNt-1PD|FWPU|S4FLiKdI-q;9&^+M0RjXn0y4j%q=o*6B{c*H z5a=Nw^Lxxu7X%0ps0hgXijo=v1PJsHkoi64s0#uF2vh`Qenm+Q0RjYi2*~^%bJPU^ z0t6}oGQXmvh5!KqJp^Qak2&gs009CO0hwP>QbT|MfgS=fzsDSPL4W{(ih#_oD5)Vp zfItrcncriMx*$M+Kt(|2SCrHcAV8ppfXwePM_mvgK%gQZ^D9bf2oNC9LqO*Dn4>NT z5Fk(ykogrQH3SF{=pi8Ud(2T61PBnQ2*~`3k{SX82=ow;`90>S3jzcPR0L#xMM(_- z0t9*p$ow92)CB*#AW#vI`4uHK1PBo5At3X6%uyEv2oR_U$oz_u8Uh3e^bnBwJ?5wj z0t5(D1Y~|iNeux41bPU_{2p`E1pxvCDgrXUqNIiZ0RlY)WPXo1>Vg0P0u_PC{Qn=z CQsM#t literal 0 HcmV?d00001 diff --git a/Demos/DX11ClothDemo/atiFlag.bmp b/Demos/DX11ClothDemo/atiFlag.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2be4847dd830b84f51b3a3fdd07f6e0d98a5315c GIT binary patch literal 1396038 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 +#include +#include +#include +#include + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } +#endif + +namespace BTAcceleratedSoftBody +{ + + /** + * Class to provide basic DX11 support to an application, wrapping the device creation functionality and necessary pointers. + */ + class DX11SupportHelper + { + private: + + ID3D11Device* m_pd3dDevice; + ID3D11DeviceContext* m_pd3dImmediateContext; + typedef HRESULT (WINAPI * LPD3D11CREATEDEVICE)( IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL*, UINT, UINT32, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext** ); + HMODULE m_s_hModD3D11; + LPD3D11CREATEDEVICE m_s_DynamicD3D11CreateDevice; + + + bool Dynamic_EnsureD3D11APIs( void ) + { + // If both modules are non-NULL, this function has already been called. Note + // that this doesn't guarantee that all ProcAddresses were found. + if( m_s_hModD3D11 != NULL ) + return true; + + // This may fail if Direct3D 11 isn't installed + m_s_hModD3D11 = LoadLibraryA( "d3d11.dll" ); + if( m_s_hModD3D11 != NULL ) + { + m_s_DynamicD3D11CreateDevice = ( LPD3D11CREATEDEVICE )GetProcAddress( m_s_hModD3D11, "D3D11CreateDevice" ); + } + + return ( m_s_hModD3D11 != NULL ); + } + + // Helper to call D3D11CreateDevice from d3d11.dll + HRESULT WINAPI Dynamic_D3D11CreateDevice( IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT32 Flags, + D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT32 SDKVersion, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext ) + { + if( Dynamic_EnsureD3D11APIs() && m_s_DynamicD3D11CreateDevice != NULL ) + { + return m_s_DynamicD3D11CreateDevice( + pAdapter, + DriverType, + Software, + Flags, + pFeatureLevels, + FeatureLevels, + SDKVersion, + ppDevice, + pFeatureLevel, + ppImmediateContext ); + } + else + { + MessageBoxA( 0, "Could not locate resources need by d3d11."\ + " Please install the latest DirectX SDK.", "Error", MB_ICONEXCLAMATION ); + return E_FAIL; + } + } + + public: + DX11SupportHelper() + { + m_s_hModD3D11 = 0; + m_s_DynamicD3D11CreateDevice = 0; + m_pd3dDevice = 0; + m_pd3dImmediateContext = 0; + } + + virtual ~DX11SupportHelper() + { + SAFE_RELEASE( m_pd3dDevice ); + SAFE_RELEASE( m_pd3dImmediateContext ); + } + + ID3D11Device* getDevice() + { + return m_pd3dDevice; + } + + ID3D11DeviceContext* getContext() + { + return m_pd3dImmediateContext; + } + + /** + * Do a simplistic initialisation of the first DirectCompute device in the system. + * Clearly the user can do their own version for more flexibility. + */ + bool InitComputeShaderDevice() + { + HRESULT hr = S_OK; + + UINT createDeviceFlags = 0; + #ifdef _DEBUG + createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + #endif + + D3D_FEATURE_LEVEL fl[] = { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; + + // Create a hardware Direct3D 11 device + hr = Dynamic_D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, + fl, _countof(fl), D3D11_SDK_VERSION, &m_pd3dDevice, NULL, &m_pd3dImmediateContext ); + + // Check if the hardware device supports Compute Shader 4.0 + D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts; + m_pd3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hwopts, sizeof(hwopts)); + if( !hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x ) { + SAFE_RELEASE( m_pd3dImmediateContext ); + SAFE_RELEASE( m_pd3dDevice ); + + int result = MessageBoxA(0, "This program needs to use the Direct3D 11 reference device. This device implements the entire Direct3D 11 feature set, but runs very slowly. Do you wish to continue?", "Compute Shader Sort", MB_ICONINFORMATION | MB_YESNO); + if( result == IDNO ) + return false;//E_FAIL; + + // Create a reference device if hardware is not available + hr = Dynamic_D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, createDeviceFlags, + fl, _countof(fl), D3D11_SDK_VERSION, &m_pd3dDevice, NULL, &m_pd3dImmediateContext ); + if( FAILED( hr ) ) + return (hr==S_OK); + + printf("Using Direct3D 11 Reference Device\n"); + } + + bool returnVal = (hr==S_OK); + + + return returnVal; + + } // InitComputeShaderDevice + + }; // DX11SupportHelper + +} // namespace BTAcceleratedSoftBody + + +#endif // #ifndef BT_DIRECT_COMPUTE_SUPPORT_HPP \ No newline at end of file diff --git a/Demos/DX11ClothDemo/cap.h b/Demos/DX11ClothDemo/cap.h new file mode 100644 index 0000000..c4a90b2 --- /dev/null +++ b/Demos/DX11ClothDemo/cap.h @@ -0,0 +1,298 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2010 Advanced Micro Devices + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef CAP_H +#define CAP_H + +class cap +{ + public: + + ID3D11Buffer* g_pIndexBuffer; + ID3D11Buffer* pVB[1]; + UINT Strides[1]; + UINT Offsets[1]; + + double x_offset, y_offset, z_offset; + + int width,height; + bool top; + + ID3D11Texture2D *texture2D; + ID3D11ShaderResourceView *texture2D_view; + btCollisionShape *collisionShape; + btCollisionObject *collisionObject; + + void set_collision_object(btCollisionObject* co) + { + collisionObject = co; + } + + void set_collision_shape(btCollisionShape* cs) + { + collisionShape = cs; + } + + void create_texture(void) + { + D3DX11_IMAGE_LOAD_INFO loadInfo; + ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO) ); + loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE; + loadInfo.Format = DXGI_FORMAT_BC1_UNORM; + + HRESULT hr = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, L"texture.bmp", &loadInfo, NULL, &texture2D_view, NULL); + hr = hr; + } + + void destroy() + { + SAFE_RELEASE( g_pIndexBuffer ); + SAFE_RELEASE( pVB[0] ); + SAFE_RELEASE( texture2D ); + SAFE_RELEASE( texture2D_view ); + } + + void draw(void) + { + + + if (!collisionObject) + return; + + + ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); + + D3DXMATRIX mWorldViewProjection; + D3DXVECTOR3 vLightDir; + D3DXMATRIX mWorld; + D3DXMATRIX mView; + D3DXMATRIX mProj; + + // Get the projection & view matrix from the camera class + mProj = *g_Camera.GetProjMatrix(); + mView = *g_Camera.GetViewMatrix(); + + // Get the light direction + vLightDir = g_LightControl.GetLightDirection(); + + // Per frame cb update + D3D11_MAPPED_SUBRESOURCE MappedResource; + + HRESULT hr; + + V( pd3dImmediateContext->Map( g_pcbPSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_PS_PER_FRAME* pPerFrame = ( CB_PS_PER_FRAME* )MappedResource.pData; + float fAmbient = 0.1f; + pPerFrame->m_vLightDirAmbient = D3DXVECTOR4( vLightDir.x, vLightDir.y, vLightDir.z, fAmbient ); + pd3dImmediateContext->Unmap( g_pcbPSPerFrame, 0 ); + + pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerFrameBind, 1, &g_pcbPSPerFrame ); + + + ///////////////////////////////////////Modify below////////////////////////////////////////////////////// + + //Get the mesh + //IA setup + pd3dImmediateContext->IASetInputLayout( g_pVertexLayout11 ); + + //This is where we pass the vertex buffer to DX + pd3dImmediateContext->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets ); + + //This is where we pass the index buffer to DX + pd3dImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////// + // Set the shaders + pd3dImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); + pd3dImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); + pd3dImmediateContext->GSSetShader( g_pGeometryShader, NULL, 0); + + // Set the per object constant data + + + + + btTransform trans = collisionObject->getWorldTransform(); + + + + btVector3 origin = trans.getOrigin(); + btMatrix3x3 btM = trans.getBasis(); + + btScalar* scalar_matrix = new btScalar[16];; + trans.getOpenGLMatrix(scalar_matrix); + + D3DXMATRIXA16 m_trans(scalar_matrix[0],scalar_matrix[1],scalar_matrix[2],scalar_matrix[3], + scalar_matrix[4],scalar_matrix[5],scalar_matrix[6],scalar_matrix[7], + scalar_matrix[8],scalar_matrix[9],scalar_matrix[10],scalar_matrix[11], + scalar_matrix[12],scalar_matrix[13],scalar_matrix[14],scalar_matrix[15]); + + D3DXMATRIXA16 m_scale; + float sc = 10; + D3DXMatrixScaling(&m_scale,sc,sc,sc); + + + D3DXVECTOR3 vCenter( global_shift_x, global_shift_y, global_shift_z); + + D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x+x_offset, -vCenter.y+y_offset, -vCenter.z+z_offset ); + + + D3DXMATRIXA16 m_trans_transpose; + D3DXMatrixTranspose(&m_trans_transpose,&m_trans); + + mWorld = *g_Camera.GetWorldMatrix() ; + mProj = *g_Camera.GetProjMatrix(); + mView = m_trans * *g_Camera.GetViewMatrix(); + + mWorldViewProjection = mView * mProj; + + + // VS Per object + V( pd3dImmediateContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData; + D3DXMatrixTranspose( &pVSPerObject->m_WorldViewProj, &mWorldViewProjection ); + D3DXMatrixTranspose( &pVSPerObject->m_World, &mWorld ); + pd3dImmediateContext->Unmap( g_pcbVSPerObject, 0 ); + + pd3dImmediateContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject ); + + // PS Per object + V( pd3dImmediateContext->Map( g_pcbPSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_PS_PER_OBJECT* pPSPerObject = ( CB_PS_PER_OBJECT* )MappedResource.pData; + pPSPerObject->m_vObjectColor = D3DXVECTOR4( 1, 1, 1, 1 ); + pd3dImmediateContext->Unmap( g_pcbPSPerObject, 0 ); + + pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerObjectBind, 1, &g_pcbPSPerObject ); + + //Render + SDKMESH_SUBSET* pSubset = NULL; + D3D11_PRIMITIVE_TOPOLOGY PrimType; + + pd3dImmediateContext->PSSetSamplers( 0, 1, &g_pSamLinear ); + + { + // Get the subset + pSubset = g_Mesh11.GetSubset( 0, 0 ); + + pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + pd3dImmediateContext->PSSetShaderResources(0,1,&texture2D_view); + + pd3dImmediateContext->DrawIndexed( (width*3*2+2 + height*width*3*2), 0, ( UINT )pSubset->VertexStart ); + } + + SAFE_RELEASE(pd3dImmediateContext); + } + + + void create_buffers(int width_, int height_, bool top_) + { + + top = top_; + width = width_; + height = height_; + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + + + vertex_struct *vertices = new vertex_struct[width*height]; + + btCapsuleShape* cs = static_cast(collisionShape); + if (cs) + { + float radius = cs->getRadius(); + float halfHeight = cs->getHalfHeight(); + + + if (top) + { + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + float X = (x/((float)(width-1)))*3.14159; + float Y = (y/((float)(height-1)))*3.14159; + float z_coord = radius*cos(X)*sin(Y); + float y_coord = radius*sin(X)*sin(Y) + halfHeight; + float x_coord = radius*cos(Y); + vertices[y*width+x].Pos = D3DXVECTOR3(x_coord, y_coord, z_coord); + vertices[y*width+x].Normal = D3DXVECTOR3(x_coord,y_coord-halfHeight,z_coord); + vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1))); + } + } + } else { + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + float X = (x/((float)(width-1)))*3.14159; + float Y = (y/((float)(height-1)))*3.14159; + float z_coord = radius*cos(X)*sin(Y); + float y_coord = -radius*sin(X)*sin(Y) - halfHeight; + float x_coord = radius*cos(Y); + vertices[y*width+x].Pos = D3DXVECTOR3(x_coord, y_coord, z_coord); + vertices[y*width+x].Normal = D3DXVECTOR3(x_coord,y_coord+halfHeight,z_coord); + vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1))); + } + } + } + + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = vertices; + InitData.SysMemPitch = 0; + InitData.SysMemSlicePitch = 0; + + HRESULT hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &pVB[0]); + + + + //What is this vertex stride thing all about? + Strides[0] = ( UINT )g_Mesh11.GetVertexStride( 0, 0 ); + Offsets[0] = 0; + + unsigned int* indices = new unsigned int[width*3*2+2 + height*width*3*2]; + + for(int y = 0; y < height-1; y++) + { + for(int x = 0; x < width-1; x++) + { + indices[x*3*2 + y*width*3*2] = x + y*width; + indices[x*3*2+1 + y*width*3*2] = x+1 + y*width; + indices[x*3*2+2 + y*width*3*2] = x+width + y*width; + + indices[x*3*2 + 3 + y*width*3*2] = x + 1 + y*width; + indices[x*3*2 + 4 + y*width*3*2] = x+(width+1) + y*width; + indices[x*3*2 + 5 + y*width*3*2] = x+width + y*width; + + } + } + + bufferDesc.ByteWidth = sizeof(unsigned int)*(width*3*2+2 + height*width*3*2); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + + InitData.pSysMem = indices; + + hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &g_pIndexBuffer); + hr = hr; + } + } +}; + +#endif CAP_H diff --git a/Demos/DX11ClothDemo/capsule.h b/Demos/DX11ClothDemo/capsule.h new file mode 100644 index 0000000..32482dc --- /dev/null +++ b/Demos/DX11ClothDemo/capsule.h @@ -0,0 +1,67 @@ +#include "cap.h" +#include "cylinder.h" + + +class capsule +{ + public: + + cap topCap; + cap bottomCap; + cylinder coreCylinder; + + double x_offset, y_offset, z_offset; + + int width; + int height; + bool top; + + btCollisionShape *collisionShape; + btCollisionObject *collisionObject; + + void set_collision_object(btCollisionObject* co) + { + collisionObject = co; + topCap.set_collision_object( co ); + bottomCap.set_collision_object( co ); + coreCylinder.set_collision_object( co ); + } + + void set_collision_shape(btCollisionShape* cs) + { + collisionShape = cs; + topCap.set_collision_shape( cs ); + bottomCap.set_collision_shape( cs ); + coreCylinder.set_collision_shape( cs ); + } + + void create_texture(void) + { + topCap.create_texture(); + bottomCap.create_texture(); + coreCylinder.create_texture(); + } + + void destroy() + { + topCap.destroy(); + bottomCap.destroy(); + coreCylinder.destroy(); + } + + void draw(void) + { + topCap.draw(); + bottomCap.draw(); + coreCylinder.draw(); + } + + + // paddingFactor is the amount of padding to allow the capsule collider around the + void create_buffers(int width_, int height_) + { + topCap.create_buffers(width_, height_, true); + bottomCap.create_buffers(width_, height_, false); + coreCylinder.create_buffers(width_, height_); + } +}; diff --git a/Demos/DX11ClothDemo/cloth.h b/Demos/DX11ClothDemo/cloth.h new file mode 100644 index 0000000..47781d7 --- /dev/null +++ b/Demos/DX11ClothDemo/cloth.h @@ -0,0 +1,312 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2010 Advanced Micro Devices + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef CLOTH_H +#define CLOTH_H + +#include +#include +#include + +class piece_of_cloth +{ +public: + + + void destroy(void) + { + + if(created) + { + SAFE_RELEASE(g_pIndexBuffer); + SAFE_RELEASE(pVB[0]); + SAFE_RELEASE(g_pVB_UAV); + SAFE_RELEASE(pVB_staging); + SAFE_RELEASE(texture2D_view); + if(m_vertexBufferDescriptor) delete [] m_vertexBufferDescriptor; + if(cpu_buffer) delete [] cpu_buffer; + } + } + + piece_of_cloth() + { + created = false; + m_vertexBufferDescriptor = NULL; + cpu_buffer = NULL; + } + bool created; + + ID3D11Buffer* g_pIndexBuffer; + ID3D11Buffer* pVB[1]; + ID3D11Buffer* pVB_staging; + + float* cpu_buffer; + + ID3D11UnorderedAccessView* g_pVB_UAV; + UINT Strides[1]; + UINT Offsets[1]; + + double x_offset, y_offset, z_offset; + + + ID3D11ShaderResourceView *texture2D_view; + + int width; + int height; + + btVertexBufferDescriptor *m_vertexBufferDescriptor; + + void create_texture(std::wstring filename) + { + D3DX11_IMAGE_LOAD_INFO loadInfo; + ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO) ); + loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE; + loadInfo.Format = DXGI_FORMAT_BC1_UNORM; + + HRESULT hr = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, filename.c_str(), &loadInfo, NULL, &texture2D_view, NULL); + hr = hr; + + } + + + void draw(void) + { + + ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); + + D3DXMATRIX mWorldViewProjection; + D3DXVECTOR3 vLightDir; + D3DXMATRIX mWorld; + D3DXMATRIX mView; + D3DXMATRIX mProj; + + // Get the projection & view matrix from the camera class + mProj = *g_Camera.GetProjMatrix(); + mView = *g_Camera.GetViewMatrix(); + + // Get the light direction + vLightDir = g_LightControl.GetLightDirection(); + + // Per frame cb update + D3D11_MAPPED_SUBRESOURCE MappedResource; + + HRESULT hr; +#ifndef USE_GPU_COPY + pd3dImmediateContext->Map( pVB_staging, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, cpu_buffer, 4*width*height*8 ); + pd3dImmediateContext->Unmap(pVB_staging, 0 ); + pd3dImmediateContext->CopyResource(pVB[0], pVB_staging); +#endif // #ifndef USE_GPU_COPY + + V( pd3dImmediateContext->Map( g_pcbPSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_PS_PER_FRAME* pPerFrame = ( CB_PS_PER_FRAME* )MappedResource.pData; + float fAmbient = 0.1f; + pPerFrame->m_vLightDirAmbient = D3DXVECTOR4( vLightDir.x, vLightDir.y, vLightDir.z, fAmbient ); + pd3dImmediateContext->Unmap( g_pcbPSPerFrame, 0 ); + + pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerFrameBind, 1, &g_pcbPSPerFrame ); + + + ///////////////////////////////////////Modify below////////////////////////////////////////////////////// + + //Get the mesh + //IA setup + pd3dImmediateContext->IASetInputLayout( g_pVertexLayout11 ); + + //This is where we pass the vertex buffer to DX + pd3dImmediateContext->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets ); + + //This is where we pass the index buffer to DX + pd3dImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////// + // Set the shaders + pd3dImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); + pd3dImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); + pd3dImmediateContext->GSSetShader( g_pGeometryShader, NULL, 0); + + // Set the per object constant data + + D3DXMATRIXA16 m_scale; + float sc = 10; + D3DXMatrixScaling(&m_scale,sc,sc,sc); + + + D3DXVECTOR3 vCenter( global_shift_x, global_shift_y, global_shift_z); + + D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x+x_offset, -vCenter.y+y_offset, -vCenter.z+z_offset ); + + + mWorld = *g_Camera.GetWorldMatrix(); + mProj = *g_Camera.GetProjMatrix(); + mView = *g_Camera.GetViewMatrix(); + + mWorldViewProjection = mView * mProj; + + + // VS Per object + V( pd3dImmediateContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData; + D3DXMatrixTranspose( &pVSPerObject->m_WorldViewProj, &mWorldViewProjection ); + D3DXMatrixTranspose( &pVSPerObject->m_World, &mWorld ); + pd3dImmediateContext->Unmap( g_pcbVSPerObject, 0 ); + + pd3dImmediateContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject ); + + // PS Per object + V( pd3dImmediateContext->Map( g_pcbPSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_PS_PER_OBJECT* pPSPerObject = ( CB_PS_PER_OBJECT* )MappedResource.pData; + pPSPerObject->m_vObjectColor = D3DXVECTOR4( 1, 1, 1, 1 ); + pd3dImmediateContext->Unmap( g_pcbPSPerObject, 0 ); + + pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerObjectBind, 1, &g_pcbPSPerObject ); + + //Render + SDKMESH_SUBSET* pSubset = NULL; + D3D11_PRIMITIVE_TOPOLOGY PrimType; + + if( g_wireFrame ) + pd3dImmediateContext->RSSetState(g_pRasterizerStateWF); + else + pd3dImmediateContext->RSSetState(g_pRasterizerState); + + pd3dImmediateContext->PSSetSamplers( 0, 1, &g_pSamLinear ); + + { + // Get the subset + pSubset = g_Mesh11.GetSubset( 0, 0 ); + + pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + pd3dImmediateContext->PSSetShaderResources(0,1,&texture2D_view); + + //pd3dImmediateContext->DrawIndexed( (width*3*2+2 + height*width*3*2), 0, ( UINT )pSubset->VertexStart ); + pd3dImmediateContext->DrawIndexed( ((height-1)*(width-1)*3*2), 0, ( UINT )pSubset->VertexStart ); + } + + SAFE_RELEASE(pd3dImmediateContext); + } + + void create_buffers(int width_, int height_) + { + width = width_; + height = height_; + + created = true; + + + cpu_buffer = new float[width*height*8]; + memset(cpu_buffer,0,width*height*8*4); + + // Set texture coordinates in output buffers + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + cpu_buffer[y*8*width + x*8 + 6] = x/( (float)(width-1)); + cpu_buffer[y*8*width + x*8 + 7] = 1-y/((float)(height-1)); + } + } + + + + D3D11_BUFFER_DESC bufferDesc; + ZeroMemory(&bufferDesc, sizeof(bufferDesc)); + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height; + bufferDesc.StructureByteStride = 0;//sizeof(vertex_struct); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_UNORDERED_ACCESS; + bufferDesc.MiscFlags = 0;//D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + bufferDesc.CPUAccessFlags = 0; + + vertex_struct *vertices = new vertex_struct[width*height]; + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + double coord = sin(x/5.0)*50; + //coord = sin(y/); + + vertices[y*width+x].Pos = D3DXVECTOR3( (x/((float)(width-1)))*1000, coord, (y/((float)(height-1)))*1000); + vertices[y*width+x].Normal = D3DXVECTOR3(1,0,0); + vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), 1.f-y/((float)(height-1))); + } + } + + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = vertices; + InitData.SysMemPitch = 0; + InitData.SysMemSlicePitch = 0; + + HRESULT hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &pVB[0]); + + + D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc; + ZeroMemory(&uavbuffer_desc, sizeof(uavbuffer_desc)); + uavbuffer_desc.Format = DXGI_FORMAT_R32_FLOAT; + uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + + uavbuffer_desc.Buffer.NumElements = width*height*sizeof(vertex_struct)/4; + hr = g_pd3dDevice->CreateUnorderedAccessView(pVB[0], &uavbuffer_desc, &g_pVB_UAV); + + + //What is this vertex stride thing all about? + Strides[0] = ( UINT )g_Mesh11.GetVertexStride( 0, 0 ); + Offsets[0] = 0; + + + //unsigned int indices[] = {0,1,2, 1,3,2}; + unsigned int* indices = new unsigned int[(height-1)*(width-1)*3*2]; + + for(int y = 0; y < height-1; y++) + { + for(int x = 0; x < width-1; x++) + { + // *3 indices/triangle, *2 triangles/quad + int baseIndex = (x + y*(width-1))*3*2; + indices[baseIndex] = x + y*width; + indices[baseIndex+1] = x+1 + y*width; + indices[baseIndex+2] = x+width + y*width; + + + indices[baseIndex+3] = x + 1 + y*width; + indices[baseIndex+4] = x+(width+1) + y*width; + indices[baseIndex+5] = x+width + y*width; + } + } + + + bufferDesc.ByteWidth = sizeof(unsigned int)*((height-1)*(width-1)*3*2); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + + InitData.pSysMem = indices; + + hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &g_pIndexBuffer); + + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height; + + hr = g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &pVB_staging); + + delete [] indices; + delete [] vertices; + } + +}; +#endif //CLOTH_H + + diff --git a/Demos/DX11ClothDemo/cloth_renderer.cpp b/Demos/DX11ClothDemo/cloth_renderer.cpp new file mode 100644 index 0000000..afd9db2 --- /dev/null +++ b/Demos/DX11ClothDemo/cloth_renderer.cpp @@ -0,0 +1,1356 @@ +//-------------------------------------------------------------------------------------- +// File: BasicHLSL10.cpp +// +// This sample shows a simple example of the Microsoft Direct3D's High-Level +// Shader Language (HLSL) using the Effect interface. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "DXUT.h" +#include "DXUTcamera.h" +#include "DXUTgui.h" +#include "DXUTsettingsDlg.h" +#include "SDKmisc.h" +#include "SDKMesh.h" +#include "resource.h" + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" +#include "btDirectComputeSupport.h" +#include "BulletSoftBody/btSoftRigidDynamicsWorld.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexBuffer_DX11.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "vectormath/vmInclude.h" + +class btDefaultSoftBodySolver; +class btCPUSoftBodySolver; +class btCPUSoftBodyVertexSolver; +class btDX11SoftBodySolver; +class btDX11SIMDAwareSoftBodySolver; + +#include "BulletSoftBody/btSoftBodySolvers.h" +#include "BulletSoftBody/btDefaultSoftBodySolver.h" + +#include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.h" + +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" + +#define USE_SIMDAWARE_SOLVER +//#define USE_GPU_SOLVER +#define USE_GPU_COPY +const int numFlags = 5; +const int clothWidth = 40; +const int clothHeight = 60; +float _windAngle = 1.0;//0.4; +float _windStrength = 15; + + +//#define TABLETEST + + +#include + +#include + +using Vectormath::Aos::Vector3; + + +class piece_of_cloth; +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; + +int paused = 0; + +float global_shift_x = 0; +float global_shift_y = 0; +float global_shift_z = 0; + +namespace BTAcceleratedSoftBody +{ + class BulletPhysicsDevice; + class CPUDevice; + class DX11Device; +} +namespace Vectormath +{ + namespace Aos + { + class Transform3; + } +} + + + +const float flagSpacing = 30.f; + +#include +using namespace std; + +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- +CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs +//CModelViewerCamera g_Camera; // A model viewing camera +CFirstPersonCamera g_Camera; // A model viewing camera +CDXUTDirectionWidget g_LightControl; +CD3DSettingsDlg g_D3DSettingsDlg; // Device settings dialog +CDXUTDialog g_HUD; // manages the 3D +CDXUTDialog g_SampleUI; // dialog for sample specific controls +D3DXMATRIXA16 g_mCenterMesh; +float g_fLightScale; +int g_nNumActiveLights; +int g_nActiveLight; +bool g_bShowHelp = false; // If true, it renders the UI control text + +// Direct3D9 resources +CDXUTTextHelper* g_pTxtHelper = NULL; + +CDXUTSDKMesh g_Mesh11; + +ID3D11InputLayout* g_pVertexLayout11 = NULL; +ID3D11Buffer* g_pVertexBuffer = NULL; +//ID3D11Buffer* g_pIndexBuffer = NULL; +ID3D11VertexShader* g_pVertexShader = NULL; +ID3D11GeometryShader* g_pGeometryShader = NULL; +ID3D11PixelShader* g_pPixelShader = NULL; +ID3D11SamplerState* g_pSamLinear = NULL; + +ID3D11RasterizerState *g_pRasterizerState = NULL; +ID3D11RasterizerState *g_pRasterizerStateWF = NULL; + +bool g_wireFrame = false; + +struct CB_VS_PER_OBJECT +{ + D3DXMATRIX m_WorldViewProj; + D3DXMATRIX m_World; +}; +UINT g_iCBVSPerObjectBind = 0; + +struct CB_PS_PER_OBJECT +{ + D3DXVECTOR4 m_vObjectColor; +}; +UINT g_iCBPSPerObjectBind = 0; + +struct CB_PS_PER_FRAME +{ + D3DXVECTOR4 m_vLightDirAmbient; +}; +UINT g_iCBPSPerFrameBind = 1; + +ID3D11Buffer* g_pcbVSPerObject = NULL; +ID3D11Buffer* g_pcbPSPerObject = NULL; +ID3D11Buffer* g_pcbPSPerFrame = NULL; + +ID3D11Device* g_pd3dDevice; + + + + +// Create our vertex input layout +const D3D11_INPUT_ELEMENT_DESC layout[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, +}; + +struct vertex_struct +{ + D3DXVECTOR3 Pos; + D3DXVECTOR3 Normal; + D3DXVECTOR2 Texcoord; +}; + + + + + +#include "capsule.h" +#include "cap.h" +#include "cylinder.h" +#include "cloth.h" + + + +//cylinder cyl_1; +//cap cap_1; +btRigidBody *capCollider; +capsule my_capsule; + + +btAlignedObjectArray cloths; + +////////////////////////////////////////// +// Bullet globals + +btAlignedObjectArray m_collisionShapes; +btBroadphaseInterface* m_broadphase; +btCollisionDispatcher* m_dispatcher; +btConstraintSolver* m_solver; +btDefaultCollisionConfiguration* m_collisionConfiguration; +BTAcceleratedSoftBody::DX11SupportHelper m_dxSupport; + +btAlignedObjectArray m_flags; +btSoftRigidDynamicsWorld* m_dynamicsWorld; + +btDefaultSoftBodySolver *g_defaultSolver = NULL; +btCPUSoftBodySolver *g_cpuSolver = NULL; +btDX11SoftBodySolver *g_dx11Solver = NULL; +btDX11SIMDAwareSoftBodySolver *g_dx11SIMDSolver = NULL; + +btSoftBodySolverOutput *g_softBodyOutput = NULL; + +btSoftBodySolver *g_solver = NULL; + +// End bullet globals +////////////////////////////////////////// + +// Helper to test and add links correctly. +// Records links that have already been generated +static bool testAndAddLink( btAlignedObjectArray &trianglesForLinks, btSoftBody *softBody, int triangle, int *triangleVertexIndexArray, int numVertices, int vertex0, int vertex1, int nonLinkVertex, btSoftBody::Material *structuralMaterial, bool createBendLinks, btSoftBody::Material *bendMaterial ) +{ + if( trianglesForLinks[ numVertices * vertex0 + vertex1 ] >= 0 && createBendLinks) + { + // Already have link so find other triangle and generate cross link + + int otherTriangle = trianglesForLinks[numVertices * vertex0 + vertex1]; + int otherIndices[3] = {triangleVertexIndexArray[otherTriangle * 3], triangleVertexIndexArray[otherTriangle * 3 + 1], triangleVertexIndexArray[otherTriangle * 3 + 2]}; + + int nodeA; + // Test all links of the other triangle against this link. The one that's not part of it is what we want. + if( otherIndices[0] != vertex0 && otherIndices[0] != vertex1 ) + nodeA = otherIndices[0]; + if( otherIndices[1] != vertex0 && otherIndices[1] != vertex1 ) + nodeA = otherIndices[1]; + if( otherIndices[2] != vertex0 && otherIndices[2] != vertex1 ) + nodeA = otherIndices[2]; + + softBody->appendLink( nodeA, nonLinkVertex, bendMaterial ); + + return true; + } else { + // Don't yet have link so create it + softBody->appendLink( vertex0, vertex1, structuralMaterial ); + + // If we added a new link, set the triangle array + trianglesForLinks[numVertices * vertex0 + vertex1] = triangle; + trianglesForLinks[numVertices * vertex1 + vertex0] = triangle; + return true; + } +} + +btSoftBody *createFromIndexedMesh( btVector3 *vertexArray, int numVertices, int *triangleVertexIndexArray, int numTriangles, bool createBendLinks ) +{ + btSoftBody* softBody = new btSoftBody(&(m_dynamicsWorld->getWorldInfo()), numVertices, vertexArray, 0); + btSoftBody::Material * structuralMaterial = softBody->appendMaterial(); + btSoftBody::Material * bendMaterial; + if( createBendLinks ) + { + bendMaterial = softBody->appendMaterial(); + bendMaterial->m_kLST = 0.7; + } else { + bendMaterial = NULL; + } + structuralMaterial->m_kLST = 1.0; + + + // List of values for each link saying which triangle is associated with that link + // -1 to start. Once a value is entered we know the "other" triangle + // and can add a link across the link + btAlignedObjectArray triangleForLinks; + triangleForLinks.resize( numVertices * numVertices, -1 ); + for( int triangle = 0; triangle < numTriangles; ++triangle ) + { + int index[3] = {triangleVertexIndexArray[triangle * 3], triangleVertexIndexArray[triangle * 3 + 1], triangleVertexIndexArray[triangle * 3 + 2]}; + softBody->appendFace( index[0], index[1], index[2] ); + + // Generate the structural links directly from the triangles + testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[0], index[1], index[2], structuralMaterial, createBendLinks, bendMaterial ); + testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[1], index[2], index[0], structuralMaterial, createBendLinks, bendMaterial ); + testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[2], index[0], index[1], structuralMaterial, createBendLinks, bendMaterial); + } + + return softBody; +} + +/** + * Create a sequence of flag objects and add them to the world. + */ +void createFlag( int width, int height, btAlignedObjectArray &flags ) +{ + // First create a triangle mesh to represent a flag + + using namespace BTAcceleratedSoftBody; + using Vectormath::Aos::Matrix3; + using Vectormath::Aos::Vector3; + + // Allocate a simple mesh consisting of a vertex array and a triangle index array + btIndexedMesh mesh; + mesh.m_numVertices = width*height; + mesh.m_numTriangles = 2*(width-1)*(height-1); + + btVector3 *vertexArray = new btVector3[mesh.m_numVertices]; + + mesh.m_vertexBase = reinterpret_cast(vertexArray); + int *triangleVertexIndexArray = new int[3*mesh.m_numTriangles]; + mesh.m_triangleIndexBase = reinterpret_cast(triangleVertexIndexArray); + mesh.m_triangleIndexStride = sizeof(int)*3; + mesh.m_vertexStride = sizeof(Vector3); + + // Generate normalised object space vertex coordinates for a rectangular flag + float zCoordinate = 0.0f; + + Matrix3 defaultScale(Vector3(5.f, 0.f, 0.f), Vector3(0.f, 20.f, 0.f), Vector3(0.f, 0.f, 1.f)); + for( int y = 0; y < height; ++y ) + { + float yCoordinate = y*2.0f/float(height) - 1.0f; + for( int x = 0; x < width; ++x ) + { + float xCoordinate = x*2.0f/float(width) - 1.0f; + + Vector3 vertex(xCoordinate, yCoordinate, zCoordinate); + Vector3 transformedVertex = defaultScale*vertex; + + vertexArray[y*width + x] = btVector3(transformedVertex.getX(), transformedVertex.getY(), transformedVertex.getZ() ); + + } + } + + // Generate vertex indices for triangles + for( int y = 0; y < (height-1); ++y ) + { + for( int x = 0; x < (width-1); ++x ) + { + // Triangle 0 + // Top left of square on mesh + { + int vertex0 = y*width + x; + int vertex1 = vertex0 + 1; + int vertex2 = vertex0 + width; + int triangleIndex = 2*y*(width-1) + 2*x; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)] = vertex0; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex+1)/sizeof(int)+1] = vertex1; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex+2)/sizeof(int)+2] = vertex2; + } + + // Triangle 1 + // Bottom right of square on mesh + { + int vertex0 = y*width + x + 1; + int vertex1 = vertex0 + width; + int vertex2 = vertex1 - 1; + int triangleIndex = 2*y*(width-1) + 2*x + 1; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)] = vertex0; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)+1] = vertex1; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)+2] = vertex2; + } + } + } + + + float rotateAngleRoundZ = 0.5; + float rotateAngleRoundX = 0.5; + btMatrix3x3 defaultRotate; + defaultRotate[0] = btVector3(cos(rotateAngleRoundZ), sin(rotateAngleRoundZ), 0.f); + defaultRotate[1] = btVector3(-sin(rotateAngleRoundZ), cos(rotateAngleRoundZ), 0.f); + defaultRotate[2] = btVector3(0.f, 0.f, 1.f); + + + //btMatrix3x3 defaultRotateAndScale( (defaultRotateX*defaultRotate) ); +#ifdef TABLETEST + btMatrix3x3 defaultRotateX; + rotateAngleRoundX = 3.141592654/2; + defaultRotateX[0] = btVector3(1.f, 0.f, 0.f); + defaultRotateX[1] = btVector3( 0.f, cos(rotateAngleRoundX), sin(rotateAngleRoundX)); + defaultRotateX[2] = btVector3(0.f, -sin(rotateAngleRoundX), cos(rotateAngleRoundX)); + btMatrix3x3 defaultRotateAndScale( (defaultRotateX) ); +#else + btMatrix3x3 defaultRotateX; + defaultRotateX[0] = btVector3(1.f, 0.f, 0.f); + defaultRotateX[1] = btVector3( 0.f, cos(rotateAngleRoundX), sin(rotateAngleRoundX)); + defaultRotateX[2] = btVector3(0.f, -sin(rotateAngleRoundX), cos(rotateAngleRoundX)); + btMatrix3x3 defaultRotateAndScale( (defaultRotateX) ); +#endif + + + // Construct the sequence flags applying a slightly different translation to each one to arrange them + // appropriately in the scene. + for( int i = 0; i < numFlags; ++i ) + { + float zTranslate = flagSpacing * (i-numFlags/2); + + btVector3 defaultTranslate(0.f, 20.f, zTranslate); + + btTransform transform( defaultRotateAndScale, defaultTranslate ); + + + btSoftBody *softBody = createFromIndexedMesh( vertexArray, mesh.m_numVertices, triangleVertexIndexArray, mesh.m_numTriangles, true ); + + + for( int i = 0; i < mesh.m_numVertices; ++i ) + { + softBody->setMass(i, 10.f/mesh.m_numVertices); + } + +#ifndef TABLETEST + // Set the fixed points + softBody->setMass((height-1)*(width), 0.f); + softBody->setMass((height-1)*(width) + width - 1, 0.f); + softBody->setMass((height-1)*width + width/2, 0.f); +#endif + + softBody->m_cfg.collisions = btSoftBody::fCollision::CL_SS+btSoftBody::fCollision::CL_RS; + softBody->m_cfg.kLF = 0.0005f; + softBody->m_cfg.kVCF = 0.001f; + softBody->m_cfg.kDP = 0.f; + softBody->m_cfg.kDG = 0.f; + + flags.push_back( softBody ); + + softBody->transform( transform ); + softBody->setFriction( 0.8f ); + m_dynamicsWorld->addSoftBody( softBody ); + } + + delete [] vertexArray; + delete [] triangleVertexIndexArray; +} + + + + + +void updatePhysicsWorld() +{ + static int counter = 0; + + // Change wind velocity a bit based on a frame counter + if( (counter % 400) == 0 ) + { + _windAngle = (_windAngle + 0.05f); + if( _windAngle > (2*3.141) ) + _windAngle = 0; + + for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex ) + { + btSoftBody *cloth = 0; + + cloth = m_flags[flagIndex]; + + float localWind = _windAngle + 0.5*(((float(rand())/RAND_MAX))-0.1); + float xCoordinate = cos(localWind)*_windStrength; + float zCoordinate = sin(localWind)*_windStrength; + + cloth->setWindVelocity( btVector3(xCoordinate, 0, zCoordinate) ); + } + } +#ifndef TABLETEST + if (capCollider) + { + btVector3 origin( capCollider->getWorldTransform().getOrigin() ); + origin.setZ( origin.getZ() + 0.01 ); + capCollider->getWorldTransform().setOrigin( origin ); + } +#endif + + counter++; +} + +void initBullet(void) +{ + + +#ifdef USE_GPU_SOLVER + g_dx11Solver = new btDX11SoftBodySolver( g_pd3dDevice, DXUTGetD3D11DeviceContext() ); + g_solver = g_dx11Solver; +#ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputDXtoDX( g_pd3dDevice, DXUTGetD3D11DeviceContext() ); +#else // #ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputDXtoCPU; +#endif // #ifdef USE_GPU_COPY +#else +#ifdef USE_SIMDAWARE_SOLVER + g_dx11SIMDSolver = new btDX11SIMDAwareSoftBodySolver( g_pd3dDevice, DXUTGetD3D11DeviceContext() ); + g_solver = g_dx11SIMDSolver; + g_softBodyOutput = new btSoftBodySolverOutputDXtoCPU; +#ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputDXtoDX( g_pd3dDevice, DXUTGetD3D11DeviceContext() ); +#else // #ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputDXtoCPU; +#endif // #ifdef USE_GPU_COPY +#else + g_cpuSolver = new btCPUSoftBodySolver; + g_solver = g_cpuSolver; + g_softBodyOutput = new btSoftBodySolverOutputCPUtoCPU; + //g_defaultSolver = new btDefaultSoftBodySolver; + //g_solver = g_defaultSolver; +#endif +#endif + + if (g_dx11SIMDSolver) + g_dx11SIMDSolver->setEnableUpdateBounds(true); + + if (g_dx11Solver) + g_dx11Solver->setEnableUpdateBounds(true); + + // Initialise CPU physics device + //m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_broadphase = new btDbvtBroadphase(); + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration, g_solver); + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + + m_dynamicsWorld->getWorldInfo().air_density = (btScalar)1.2; + m_dynamicsWorld->getWorldInfo().water_density = 0; + m_dynamicsWorld->getWorldInfo().water_offset = 0; + m_dynamicsWorld->getWorldInfo().water_normal = btVector3(0,0,0); + m_dynamicsWorld->getWorldInfo().m_gravity.setValue(0,-10,0); + +#if 0 + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + +#endif +#if 0 + { + btScalar mass(0.); + + //btScalar mass(1.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btCollisionShape *capsuleShape = new btCapsuleShape(5, 10); + capsuleShape->setMargin( 0.5 ); + + + + my_capsule.set_collision_shape(capsuleShape); + + btVector3 localInertia(0,0,0); + if (isDynamic) + capsuleShape->calculateLocalInertia(mass,localInertia); + + m_collisionShapes.push_back(capsuleShape); + btTransform capsuleTransform; + capsuleTransform.setIdentity(); +#ifdef TABLETEST + capsuleTransform.setOrigin(btVector3(0, 10, -11)); + const btScalar pi = 3.141592654; + capsuleTransform.setRotation(btQuaternion(0, 0, pi/2)); +#else + capsuleTransform.setOrigin(btVector3(0, 20, -10)); + + const btScalar pi = 3.141592654; + //capsuleTransform.setRotation(btQuaternion(0, 0, pi/2)); + capsuleTransform.setRotation(btQuaternion(0, 0, 0)); +#endif + btDefaultMotionState* myMotionState = new btDefaultMotionState(capsuleTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,capsuleShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction( 0.8f ); + my_capsule.set_collision_object(body); + + m_dynamicsWorld->addRigidBody(body); + //cap_1.collisionShape = body; + capCollider = body; + } +#endif + + + createFlag( clothWidth, clothHeight, m_flags ); + + // Create output buffer descriptions for ecah flag + // These describe where the simulation should send output data to + for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex ) + { + // In this case we have a DX11 output buffer with a vertex at index 0, 8, 16 and so on as well as a normal at 3, 11, 19 etc. + // Copies will be performed GPU-side directly into the output buffer +#ifdef USE_GPU_COPY + btDX11VertexBufferDescriptor *vertexBufferDescriptor = new btDX11VertexBufferDescriptor(DXUTGetD3D11DeviceContext(), cloths[flagIndex].pVB[0], cloths[flagIndex].g_pVB_UAV, 0, 8, 3, 8); + cloths[flagIndex].m_vertexBufferDescriptor = vertexBufferDescriptor; +#else // #ifdef USE_GPU_COPY + btCPUVertexBufferDescriptor *vertexBufferDescriptor = new btCPUVertexBufferDescriptor(cloths[flagIndex].cpu_buffer, 0, 8, 3, 8); + cloths[flagIndex].m_vertexBufferDescriptor = vertexBufferDescriptor; +#endif // #ifdef USE_GPU_COPY + } + + g_solver->optimize( m_dynamicsWorld->getSoftBodyArray() ); + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//-------------------------------------------------------------------------------------- +// UI control IDs +//-------------------------------------------------------------------------------------- +#define IDC_TOGGLEFULLSCREEN 1 +#define IDC_TOGGLEREF 3 +#define IDC_CHANGEDEVICE 4 +#define IDC_PAUSE 5 +#define IDC_WIREFRAME 6 + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- +bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ); +void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ); +LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, + void* pUserContext ); +void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ); +void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ); + +bool CALLBACK IsD3D11DeviceAcceptable(const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, + DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext ); +HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, + void* pUserContext ); +HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, + const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); +void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext ); +void CALLBACK OnD3D11DestroyDevice( void* pUserContext ); +void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, + float fElapsedTime, void* pUserContext ); + +void InitApp(); +void RenderText(); + + +//-------------------------------------------------------------------------------------- +// Entry point to the program. Initializes everything and goes into a message processing +// loop. Idle time is used to render the scene. +//-------------------------------------------------------------------------------------- +int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) +{ + // Enable run-time memory check for debug builds. +#if defined(DEBUG) | defined(_DEBUG) + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + _CrtSetReportMode ( _CRT_ERROR, _CRTDBG_MODE_DEBUG); +#endif + + // DXUT will create and use the best device (either D3D9 or D3D11) + // that is available on the system depending on which D3D callbacks are set below + + // Set DXUT callbacks + DXUTSetCallbackDeviceChanging( ModifyDeviceSettings ); + DXUTSetCallbackMsgProc( MsgProc ); + DXUTSetCallbackKeyboard( OnKeyboard ); + DXUTSetCallbackFrameMove( OnFrameMove ); + + + DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable ); + DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice ); + + DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain ); + DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender ); + DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain ); + + DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice ); + + + InitApp(); + DXUTInit( true, true, NULL ); // Parse the command line, show msgboxes on error, no extra command line params + DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen + DXUTCreateWindow( L"Cloth Renderer" ); + DXUTCreateDevice (D3D_FEATURE_LEVEL_11_0, true, 800, 600 ); + DXUTSetMultimonSettings(false); + //DXUTCreateDevice(true, 640, 480); + DXUTMainLoop(); // Enter into the DXUT render loop + + return DXUTGetExitCode(); +} + + +//-------------------------------------------------------------------------------------- +// Initialize the app +//-------------------------------------------------------------------------------------- +void InitApp() +{ + D3DXVECTOR3 vLightDir( 1, 0, 0 ); + D3DXVec3Normalize( &vLightDir, &vLightDir ); + g_LightControl.SetLightDirection( vLightDir ); + + // Initialize dialogs + g_D3DSettingsDlg.Init( &g_DialogResourceManager ); + g_HUD.Init( &g_DialogResourceManager ); + g_SampleUI.Init( &g_DialogResourceManager ); + + g_HUD.SetCallback( OnGUIEvent ); int iY = 10; + g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 0, iY, 170, 23 ); + + g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 0, iY += 26, 170, 23, VK_F3 ); + g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 0, iY += 26, 170, 23, VK_F2 ); + g_HUD.AddButton( IDC_PAUSE, L"Pause", 0, iY += 26, 170, 23 ); + g_HUD.AddButton( IDC_WIREFRAME, L"Wire frame", 0, iY += 26, 170, 23 ); + + g_SampleUI.SetCallback( OnGUIEvent ); iY = 10; +} + + +//-------------------------------------------------------------------------------------- +// Called right before creating a D3D9 or D3D11 device, allowing the app to modify the device settings as needed +//-------------------------------------------------------------------------------------- +bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ) +{ + // Uncomment this to get debug information from D3D11 + //pDeviceSettings->d3d11.CreateFlags |= D3D11_CREATE_DEVICE_DEBUG; + + // For the first device created if its a REF device, optionally display a warning dialog box + static bool s_bFirstTime = true; + if( s_bFirstTime ) + { + s_bFirstTime = false; + if( ( DXUT_D3D11_DEVICE == pDeviceSettings->ver && + pDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) ) + { + DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver ); + } + } + + return true; +} + + +//-------------------------------------------------------------------------------------- +// Handle updates to the scene. This is called regardless of which D3D API is used +//-------------------------------------------------------------------------------------- +void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ) +{ + // Update the camera's position based on user input + g_Camera.FrameMove( fElapsedTime ); +} + + +//-------------------------------------------------------------------------------------- +// Render the help and statistics text +//-------------------------------------------------------------------------------------- +void RenderText() +{ + UINT nBackBufferHeight = ( DXUTIsAppRenderingWithD3D9() ) ? DXUTGetD3D9BackBufferSurfaceDesc()->Height : + DXUTGetDXGIBackBufferSurfaceDesc()->Height; + + g_pTxtHelper->Begin(); + g_pTxtHelper->SetInsertionPos( 2, 0 ); + g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) ); + g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) ); + g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() ); + + // Draw help + if( g_bShowHelp ) + { + g_pTxtHelper->SetInsertionPos( 2, nBackBufferHeight - 20 * 6 ); + g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) ); + g_pTxtHelper->DrawTextLine( L"Controls:" ); + + g_pTxtHelper->SetInsertionPos( 20, nBackBufferHeight - 20 * 5 ); + g_pTxtHelper->DrawTextLine( L"Rotate view: Left mouse button\n" + L"Move camera: W, A, S, and D\n" + L"Rotate light: Right mouse button\n" + L"Zoom camera: Mouse wheel scroll\n" ); + + g_pTxtHelper->SetInsertionPos( 550, nBackBufferHeight - 20 * 5 ); + g_pTxtHelper->DrawTextLine( L"Hide help: F1\n" + L"Quit: ESC\n" ); + } + else + { + g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) ); + g_pTxtHelper->DrawTextLine( L"Press F1 for help" ); + } + + g_pTxtHelper->End(); +} + + +//-------------------------------------------------------------------------------------- +// Handle messages to the application +//-------------------------------------------------------------------------------------- +LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, + void* pUserContext ) +{ + // Pass messages to dialog resource manager calls so GUI state is updated correctly + *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam ); + if( *pbNoFurtherProcessing ) + return 0; + + // Pass messages to settings dialog if its active + if( g_D3DSettingsDlg.IsActive() ) + { + g_D3DSettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam ); + return 0; + } + + // Give the dialogs a chance to handle the message first + *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam ); + if( *pbNoFurtherProcessing ) + return 0; + *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam ); + if( *pbNoFurtherProcessing ) + return 0; + + g_LightControl.HandleMessages( hWnd, uMsg, wParam, lParam ); + + // Pass all remaining windows messages to camera so it can respond to user input + g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam ); + + return 0; +} + + +//-------------------------------------------------------------------------------------- +// Handle key presses +//-------------------------------------------------------------------------------------- +void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ) +{ + if( bKeyDown ) + { + switch( nChar ) + { + case VK_F1: + g_bShowHelp = !g_bShowHelp; break; + } + } +} + + +//-------------------------------------------------------------------------------------- +// Handles the GUI events +//-------------------------------------------------------------------------------------- +void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ) +{ + switch( nControlID ) + { + case IDC_TOGGLEFULLSCREEN: + DXUTToggleFullScreen(); break; + case IDC_TOGGLEREF: + DXUTToggleREF(); break; + case IDC_CHANGEDEVICE: + g_D3DSettingsDlg.SetActive( !g_D3DSettingsDlg.IsActive() ); break; + case IDC_PAUSE: + paused = !paused; + break; + case IDC_WIREFRAME: + g_wireFrame = !g_wireFrame; + break; + } + +} + + +//-------------------------------------------------------------------------------------- +// Reject any D3D11 devices that aren't acceptable by returning false +//-------------------------------------------------------------------------------------- +bool CALLBACK IsD3D11DeviceAcceptable( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, + DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext ) +{ + return true; +} + +//-------------------------------------------------------------------------------------- +// Use this until D3DX11 comes online and we get some compilation helpers +//-------------------------------------------------------------------------------------- +HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut ) +{ + HRESULT hr = S_OK; + + // find the file + WCHAR str[MAX_PATH]; + V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, szFileName ) ); + + // open the file + HANDLE hFile = CreateFile( str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, NULL ); + if( INVALID_HANDLE_VALUE == hFile ) + return E_FAIL; + + // Get the file size + LARGE_INTEGER FileSize; + GetFileSizeEx( hFile, &FileSize ); + + // create enough space for the file data + BYTE* pFileData = new BYTE[ FileSize.LowPart ]; + if( !pFileData ) + return E_OUTOFMEMORY; + + // read the data in + DWORD BytesRead; + if( !ReadFile( hFile, pFileData, FileSize.LowPart, &BytesRead, NULL ) ) + return E_FAIL; + + CloseHandle( hFile ); + + // Compile the shader + ID3DBlob* pErrorBlob; + hr = D3DCompile( pFileData, FileSize.LowPart, "none", NULL, NULL, szEntryPoint, szShaderModel, D3D10_SHADER_ENABLE_STRICTNESS, 0, ppBlobOut, &pErrorBlob ); + + delete []pFileData; + + if( FAILED(hr) ) + { + OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() ); + SAFE_RELEASE( pErrorBlob ); + return hr; + } + SAFE_RELEASE( pErrorBlob ); + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Create any D3D11 resources that aren't dependant on the back buffer +//-------------------------------------------------------------------------------------- +HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, + void* pUserContext ) +{ + + g_pd3dDevice = pd3dDevice; + + HRESULT hr; + + ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); + + V_RETURN( g_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) ); + V_RETURN( g_D3DSettingsDlg.OnD3D11CreateDevice( pd3dDevice ) ); + g_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &g_DialogResourceManager, 15 ); + + D3DXVECTOR3 vCenter( 0.25767413f, -28.503521f, 111.00689f); + FLOAT fObjectRadius = 378.15607f; + + D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x, -vCenter.y, -vCenter.z ); + D3DXMATRIXA16 m; + D3DXMatrixRotationY( &m, D3DX_PI ); + g_mCenterMesh *= m; + D3DXMatrixRotationX( &m, D3DX_PI / 2.0f ); + g_mCenterMesh *= m; + + // Compile the shaders to a model based on the feature level we acquired + ID3DBlob* pVertexShaderBuffer = NULL; + ID3DBlob* pGeometryShaderBuffer = NULL; + ID3DBlob* pPixelShaderBuffer = NULL; + + switch( DXUTGetD3D11DeviceFeatureLevel() ) + { + case D3D_FEATURE_LEVEL_11_0: + V_RETURN( CompileShaderFromFile( L"cloth_renderer_VS.hlsl", "VSMain", "vs_5_0" , &pVertexShaderBuffer ) ); + V_RETURN( CompileShaderFromFile( L"cloth_renderer_PS.hlsl", "GSMain", "gs_5_0" , &pGeometryShaderBuffer ) ); + V_RETURN( CompileShaderFromFile( L"cloth_renderer_PS.hlsl", "PSMain", "ps_5_0" , &pPixelShaderBuffer ) ); + break; + } + + // Create the shaders + V_RETURN( pd3dDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(), + pVertexShaderBuffer->GetBufferSize(), NULL, &g_pVertexShader ) ); + + + V_RETURN( pd3dDevice->CreateGeometryShader( pGeometryShaderBuffer->GetBufferPointer(), + pGeometryShaderBuffer->GetBufferSize(), NULL, &g_pGeometryShader ) ); + + + V_RETURN( pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(), + pPixelShaderBuffer->GetBufferSize(), NULL, &g_pPixelShader ) ); + + + + V_RETURN( pd3dDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), pVertexShaderBuffer->GetBufferPointer(), + pVertexShaderBuffer->GetBufferSize(), &g_pVertexLayout11 ) ); + + SAFE_RELEASE( pVertexShaderBuffer ); + SAFE_RELEASE( pPixelShaderBuffer ); + SAFE_RELEASE( pGeometryShaderBuffer ); + + + // Load the mesh + V_RETURN( g_Mesh11.Create( pd3dDevice, L"tiny\\tiny.sdkmesh", true ) ); + + + + + // Create a sampler state + D3D11_SAMPLER_DESC SamDesc; + SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + SamDesc.MipLODBias = 0.0f; + SamDesc.MaxAnisotropy = 1; + SamDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + SamDesc.BorderColor[0] = SamDesc.BorderColor[1] = SamDesc.BorderColor[2] = SamDesc.BorderColor[3] = 0; + SamDesc.MinLOD = 0; + SamDesc.MaxLOD = D3D11_FLOAT32_MAX; + V_RETURN( pd3dDevice->CreateSamplerState( &SamDesc, &g_pSamLinear ) ); + + + + + // Setup constant buffers + D3D11_BUFFER_DESC Desc; + Desc.Usage = D3D11_USAGE_DYNAMIC; + Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + Desc.MiscFlags = 0; + + Desc.ByteWidth = sizeof( CB_VS_PER_OBJECT ); + V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbVSPerObject ) ); + + Desc.ByteWidth = sizeof( CB_PS_PER_OBJECT ); + V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerObject ) ); + + Desc.ByteWidth = sizeof( CB_PS_PER_FRAME ); + V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerFrame ) ); + + // Setup the camera's view parameters + + + D3DXVECTOR3 vecEye( 30.0f, 30.0f, -80.0f ); + D3DXVECTOR3 vecAt ( 10.0f, 20.0f, -0.0f ); + + + g_Camera.SetViewParams( &vecEye, &vecAt ); + + cloths.resize(numFlags); + + for( int flagIndex = 0; flagIndex < numFlags; ++flagIndex ) + { + cloths[flagIndex].create_buffers(clothWidth, clothHeight); + } + + initBullet(); + +std::wstring flagTexsName[] = { + L"atiFlag.bmp", + L"amdFlag.bmp", + }; + int numFlagTexs = 2; + + + + WCHAR flagTexs[2][MAX_PATH]; + + HRESULT res = DXUTFindDXSDKMediaFileCch(flagTexs[0],MAX_PATH, flagTexsName[0].c_str()); + res = DXUTFindDXSDKMediaFileCch(flagTexs[1],MAX_PATH, flagTexsName[1].c_str()); + + + for( int flagIndex = 0; flagIndex < numFlags; ++flagIndex ) + { + cloths[flagIndex].create_texture(flagTexs[flagIndex % numFlagTexs]); + cloths[flagIndex].x_offset = 0; + cloths[flagIndex].y_offset = 0; + cloths[flagIndex].z_offset = 0; + } + + + + my_capsule.create_buffers(50,40); + my_capsule.create_texture(); + + //Turn off backface culling + D3D11_RASTERIZER_DESC rsDesc; + ZeroMemory(&rsDesc,sizeof(D3D11_RASTERIZER_DESC) ); + rsDesc.CullMode = D3D11_CULL_NONE; + rsDesc.FillMode = D3D11_FILL_SOLID; + + hr = pd3dDevice->CreateRasterizerState(&rsDesc, &g_pRasterizerState); + + rsDesc.FillMode = D3D11_FILL_WIREFRAME; + hr = pd3dDevice->CreateRasterizerState(&rsDesc, &g_pRasterizerStateWF); + + SAFE_RELEASE(pd3dImmediateContext); + + + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Create any D3D11 resources that depend on the back buffer +//-------------------------------------------------------------------------------------- +HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, + const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) +{ + HRESULT hr; + + V_RETURN( g_DialogResourceManager.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) ); + V_RETURN( g_D3DSettingsDlg.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) ); + + // Setup the camera's projection parameters + float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height; + g_Camera.SetProjParams( D3DX_PI / 4, fAspectRatio, 2.0f, 4000.0f ); + // g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); + // g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON ); + + + D3DXVECTOR3 vMin = D3DXVECTOR3( -1000.0f, -1000.0f, -1000.0f ); + D3DXVECTOR3 vMax = D3DXVECTOR3( 1000.0f, 1000.0f, 1000.0f ); + g_Camera.SetRotateButtons(TRUE, FALSE, FALSE); + + + g_Camera.SetScalers( 0.01f, 30.0f ); + g_Camera.SetDrag( true ); + g_Camera.SetEnableYAxisMovement( true ); + g_Camera.SetClipToBoundary( TRUE, &vMin, &vMax ); + g_Camera.FrameMove( 0 ); + + + g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 ); + g_HUD.SetSize( 170, 170 ); + g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 300 ); + g_SampleUI.SetSize( 170, 300 ); + + //Turn off backface culling + D3D11_RASTERIZER_DESC rsDesc; + ZeroMemory(&rsDesc,sizeof(D3D11_RASTERIZER_DESC) ); + rsDesc.CullMode = D3D11_CULL_NONE; + rsDesc.FillMode = D3D11_FILL_SOLID; + //rsDesc.FillMode = D3D11_FILL_WIREFRAME; + + + ID3D11RasterizerState *pRasterizerState = NULL; + pd3dDevice->CreateRasterizerState(&rsDesc, &pRasterizerState); + + DXUTGetD3D11DeviceContext()->RSSetState(pRasterizerState); + + SAFE_RELEASE(pRasterizerState); + + return S_OK; +} + + +btClock m_clock; +//-------------------------------------------------------------------------------------- +// Render the scene using the D3D11 device +//-------------------------------------------------------------------------------------- +void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, + float fElapsedTime, void* pUserContext ) +{ + + + + + //float ms = getDeltaTimeMicroseconds(); + btScalar dt = (btScalar)m_clock.getTimeMicroseconds(); + m_clock.reset(); + + ///step the simulation + if (m_dynamicsWorld && !paused) + { + + m_dynamicsWorld->stepSimulation(dt / 1000000.f); + + updatePhysicsWorld(); + } + + //paused = 1; + + + + /////////////////////////////////////////////////////// + + HRESULT hr; + + // If the settings dialog is being shown, then render it instead of rendering the app's scene + if( g_D3DSettingsDlg.IsActive() ) + { + g_D3DSettingsDlg.OnRender( fElapsedTime ); + return; + } + + // Clear the render target and depth stencil + float ClearColor[4] = { 0.0f, 0.25f, 0.25f, 0.55f }; + ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView(); + pd3dImmediateContext->ClearRenderTargetView( pRTV, ClearColor ); + ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView(); + pd3dImmediateContext->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); + + + for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex ) + { + g_softBodyOutput->copySoftBodyToVertexBuffer( m_flags[flagIndex], cloths[flagIndex].m_vertexBufferDescriptor ); + cloths[flagIndex].draw(); + } + + my_capsule.draw(); + + + DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); + g_HUD.OnRender( fElapsedTime ); + g_SampleUI.OnRender( fElapsedTime ); + RenderText(); + DXUT_EndPerfEvent(); + + +/* + SAFE_RELEASE(pRTV); + SAFE_RELEASE(pDSV); +*/ + + +} + + +//-------------------------------------------------------------------------------------- +// Release D3D11 resources created in OnD3D11ResizedSwapChain +//-------------------------------------------------------------------------------------- +void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext ) +{ + g_DialogResourceManager.OnD3D11ReleasingSwapChain(); + DXUTGetD3D11DeviceContext()->ClearState(); +} + + +//-------------------------------------------------------------------------------------- +// Release D3D11 resources created in OnD3D11CreateDevice +//-------------------------------------------------------------------------------------- +void CALLBACK OnD3D11DestroyDevice( void* pUserContext ) +{ + g_DialogResourceManager.OnD3D11DestroyDevice(); + g_D3DSettingsDlg.OnD3D11DestroyDevice(); + DXUTGetGlobalResourceCache().OnDestroyDevice(); + SAFE_DELETE( g_pTxtHelper ); + + g_Mesh11.Destroy(); + + + SAFE_RELEASE(g_pGeometryShader); + SAFE_RELEASE( g_pVertexLayout11 ); + SAFE_RELEASE( g_pVertexBuffer ); + SAFE_RELEASE( g_pVertexShader ); + SAFE_RELEASE( g_pPixelShader ); + SAFE_RELEASE( g_pSamLinear ); + + SAFE_RELEASE( g_pcbVSPerObject ); + SAFE_RELEASE( g_pcbPSPerObject ); + SAFE_RELEASE( g_pcbPSPerFrame ); + + SAFE_RELEASE( g_pRasterizerState ); + SAFE_RELEASE( g_pRasterizerStateWF ); + + + for( int flagIndex = 0; flagIndex < numFlags; ++flagIndex ) + { + cloths[flagIndex].destroy(); + } + + my_capsule.destroy(); + + // Shouldn't need to delete this as it's just a soft body and will be deleted later by the collision object cleanup. + //for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex ) + //{ + //delete m_flags[flagIndex]; + //} + + //cleanup in the reverse order of creation/initialization + if( g_defaultSolver ) + delete g_defaultSolver; + if( g_cpuSolver ) + delete g_cpuSolver; + if( g_dx11Solver ) + delete g_dx11Solver; + if( g_dx11SIMDSolver ) + delete g_dx11SIMDSolver; + if( g_softBodyOutput ) + delete g_softBodyOutput; + + + for(int i=0; i< m_collisionShapes.size(); i++) + delete m_collisionShapes[i]; + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + delete m_dynamicsWorld; + delete m_solver; + delete m_broadphase; + delete m_dispatcher; + delete m_collisionConfiguration; + + +} + + + + + + + + + + diff --git a/Demos/DX11ClothDemo/cloth_renderer.fx b/Demos/DX11ClothDemo/cloth_renderer.fx new file mode 100644 index 0000000..2b8f318 --- /dev/null +++ b/Demos/DX11ClothDemo/cloth_renderer.fx @@ -0,0 +1,157 @@ +//-------------------------------------------------------------------------------------- +// File: BasicHLSL.fx +// +// The effect file for the BasicHLSL sample. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- +float4 g_MaterialAmbientColor; // Material's ambient color +float4 g_MaterialDiffuseColor; // Material's diffuse color +int g_nNumLights; + +float3 g_LightDir; // Light's direction in world space +float4 g_LightDiffuse; // Light's diffuse color +float4 g_LightAmbient; // Light's ambient color + +texture g_MeshTexture; // Color texture for mesh + +float g_fTime; // App's time in seconds +float4x4 g_mWorld; // World matrix for object +float4x4 g_mWorldViewProjection; // World * View * Projection matrix + + + +//-------------------------------------------------------------------------------------- +// Texture samplers +//-------------------------------------------------------------------------------------- +sampler MeshTextureSampler = +sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; +}; + + +//-------------------------------------------------------------------------------------- +// Vertex shader output structure +//-------------------------------------------------------------------------------------- +struct VS_OUTPUT +{ + float4 Position : POSITION; // vertex position + float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1) + float2 TextureUV : TEXCOORD0; // vertex texture coords +}; + + +//-------------------------------------------------------------------------------------- +// This shader computes standard transform and lighting +//-------------------------------------------------------------------------------------- +VS_OUTPUT RenderSceneVS( float4 vPos : POSITION, + float3 vNormal : NORMAL, + float2 vTexCoord0 : TEXCOORD0, + uniform int nNumLights, + uniform bool bTexture, + uniform bool bAnimate ) +{ + + VS_OUTPUT Output; + float3 vNormalWorldSpace; + + // Transform the position from object space to homogeneous projection space + Output.Position = mul(vPos, g_mWorldViewProjection); + + // Transform the normal from object space to world space + vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space) + + // Compute simple directional lighting equation + float3 vTotalLightDiffuse = float3(0,0,0); + for(int i=0; i + + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_MAIN_ICON ICON "DXUT\Optional\\directx.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define IDC_STATIC -1\r\n" + "#include \r\n" + "\r\n" + "\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Demos/DX11ClothDemo/cloth_renderer_PS.hlsl b/Demos/DX11ClothDemo/cloth_renderer_PS.hlsl new file mode 100644 index 0000000..553a546 --- /dev/null +++ b/Demos/DX11ClothDemo/cloth_renderer_PS.hlsl @@ -0,0 +1,90 @@ +//-------------------------------------------------------------------------------------- +// File: BasicHLSL11_PS.hlsl +// +// The pixel shader file for the BasicHLSL11 sample. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +// Globals +//-------------------------------------------------------------------------------------- +cbuffer cbPerObject : register( b0 ) +{ + float4 g_vObjectColor : packoffset( c0 ); +}; + +cbuffer cbPerFrame : register( b1 ) +{ + float3 g_vLightDir : packoffset( c0 ); + float g_fAmbient : packoffset( c0.w ); +}; + +//-------------------------------------------------------------------------------------- +// Textures and Samplers +//-------------------------------------------------------------------------------------- +Texture2D g_txDiffuse : register( t0 ); +SamplerState g_samLinear : register( s0 ); + +//-------------------------------------------------------------------------------------- +// Input / Output structures +//-------------------------------------------------------------------------------------- +struct PS_INPUT +{ + float3 vNormal : NORMAL; + float2 vTexcoord : TEXCOORD0; + float4 vPosition : SV_POSITION; +}; + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- +float4 PSMain( PS_INPUT Input ) : SV_TARGET +{ + float4 vDiffuse = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord ); + + + float fLighting = saturate( dot( g_vLightDir, (Input.vNormal)/length(Input.vNormal) ) ); + //float fLighting = saturate( dot( g_vLightDir, float3(Input.vTexcoord.x,0,0) ) ); + fLighting = max( fLighting, g_fAmbient ); + + //fLighting = dot(g_vLightDir,float3(0,1,0)); + + return vDiffuse * fLighting; +} + + +struct VS_OUTPUT +{ + float3 vNormal : NORMAL; + float2 vTexcoord : TEXCOORD0; + float4 vPosition : SV_POSITION; +}; + +[maxvertexcount(3)] +void GSMain(triangle VS_OUTPUT input[3], inout TriangleStream OutputStream) +{ +PS_INPUT output = (PS_INPUT)0; + + +/* +float3 v1 = input[1].vPosition - input[0].vPosition; +float3 v2 = input[2].vPosition - input[0].vPosition; +float3 normal = cross(v1,v2); + +normal = normalize(normal); +*/ + + +for(int i = 0; i < 3; i++) +{ + +output.vNormal = input[i].vNormal; +output.vTexcoord = input[i].vTexcoord; +output.vPosition = input[i].vPosition; +OutputStream.Append(output); +} + +OutputStream.RestartStrip(); + +} \ No newline at end of file diff --git a/Demos/DX11ClothDemo/cloth_renderer_VS.hlsl b/Demos/DX11ClothDemo/cloth_renderer_VS.hlsl new file mode 100644 index 0000000..331e2f8 --- /dev/null +++ b/Demos/DX11ClothDemo/cloth_renderer_VS.hlsl @@ -0,0 +1,48 @@ +//-------------------------------------------------------------------------------------- +// File: BasicHLSL11_VS.hlsl +// +// The vertex shader file for the BasicHLSL11 sample. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +// Globals +//-------------------------------------------------------------------------------------- +cbuffer cbPerObject : register( b0 ) +{ + matrix g_mWorldViewProjection : packoffset( c0 ); + matrix g_mWorld : packoffset( c4 ); +}; + +//-------------------------------------------------------------------------------------- +// Input / Output structures +//-------------------------------------------------------------------------------------- +struct VS_INPUT +{ + float4 vPosition : POSITION; + float3 vNormal : NORMAL; + float2 vTexcoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float3 vNormal : NORMAL; + float2 vTexcoord : TEXCOORD0; + float4 vPosition : SV_POSITION; +}; + +//-------------------------------------------------------------------------------------- +// Vertex Shader +//-------------------------------------------------------------------------------------- +VS_OUTPUT VSMain( VS_INPUT Input ) +{ + VS_OUTPUT Output; + + Output.vPosition = mul( Input.vPosition, g_mWorldViewProjection ); + Output.vNormal = mul( Input.vNormal, (float3x3)g_mWorld ); + Output.vTexcoord = Input.vTexcoord; + + return Output; +} + diff --git a/Demos/DX11ClothDemo/cylinder.h b/Demos/DX11ClothDemo/cylinder.h new file mode 100644 index 0000000..225cb20 --- /dev/null +++ b/Demos/DX11ClothDemo/cylinder.h @@ -0,0 +1,297 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2010 Advanced Micro Devices + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef CYLINDER_H +#define CYLINDER_H + +class cylinder +{ + public: + + ID3D11Buffer* g_pIndexBuffer; + ID3D11Buffer* pVB[1]; + UINT Strides[1]; + UINT Offsets[1]; + + double x_offset, y_offset, z_offset; + + int width; + int height; + + ID3D11Texture2D *texture2D; + ID3D11ShaderResourceView *texture2D_view; + + btCollisionShape *collisionShape; + + //static_cast(capsuleShape) + + + btCollisionObject *collisionObject; + + void set_collision_object(btCollisionObject* co) + { + collisionObject = co; + } + + void set_collision_shape(btCollisionShape* cs) + { + collisionShape = cs; + } + + + void destroy() + { + SAFE_RELEASE( g_pIndexBuffer ); + SAFE_RELEASE( pVB[0] ); + + SAFE_RELEASE( texture2D ); + SAFE_RELEASE( texture2D_view ); + } + + void create_texture(void) + { + D3DX11_IMAGE_LOAD_INFO loadInfo; + ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO) ); + loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE; + loadInfo.Format = DXGI_FORMAT_BC1_UNORM; + + HRESULT hr = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, L"texture.bmp", &loadInfo, NULL, &texture2D_view, NULL); + } + + void draw(void) + { + + if (!collisionObject) + return; + + ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); + + D3DXMATRIX mWorldViewProjection; + D3DXVECTOR3 vLightDir; + D3DXMATRIX mWorld; + D3DXMATRIX mView; + D3DXMATRIX mProj; + + // Get the projection & view matrix from the camera class + mProj = *g_Camera.GetProjMatrix(); + mView = *g_Camera.GetViewMatrix(); + + // Get the light direction + vLightDir = g_LightControl.GetLightDirection(); + + // Per frame cb update + D3D11_MAPPED_SUBRESOURCE MappedResource; + + HRESULT hr; + + V( pd3dImmediateContext->Map( g_pcbPSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_PS_PER_FRAME* pPerFrame = ( CB_PS_PER_FRAME* )MappedResource.pData; + float fAmbient = 0.1f; + pPerFrame->m_vLightDirAmbient = D3DXVECTOR4( vLightDir.x, vLightDir.y, vLightDir.z, fAmbient ); + pd3dImmediateContext->Unmap( g_pcbPSPerFrame, 0 ); + + pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerFrameBind, 1, &g_pcbPSPerFrame ); + + + ///////////////////////////////////////Modify below////////////////////////////////////////////////////// + + //Get the mesh + //IA setup + pd3dImmediateContext->IASetInputLayout( g_pVertexLayout11 ); + + //This is where we pass the vertex buffer to DX + pd3dImmediateContext->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets ); + + //This is where we pass the index buffer to DX + pd3dImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); + + ///////////////////////////////////////////////////////////////////////////////////////////////////////// + // Set the shaders + pd3dImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); + pd3dImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); + pd3dImmediateContext->GSSetShader( g_pGeometryShader, NULL, 0); + + // Set the per object constant data + + + + btTransform trans = collisionObject->getWorldTransform(); + + + + btVector3 origin = trans.getOrigin(); + btMatrix3x3 btM = trans.getBasis(); + + btScalar* scalar_matrix = new btScalar[16];; + trans.getOpenGLMatrix(scalar_matrix); + + D3DXMATRIXA16 m_trans(scalar_matrix[0],scalar_matrix[1],scalar_matrix[2],scalar_matrix[3], + scalar_matrix[4],scalar_matrix[5],scalar_matrix[6],scalar_matrix[7], + scalar_matrix[8],scalar_matrix[9],scalar_matrix[10],scalar_matrix[11], + scalar_matrix[12],scalar_matrix[13],scalar_matrix[14],scalar_matrix[15]); + + D3DXMATRIXA16 m_scale; + float sc = 10; + D3DXMatrixScaling(&m_scale,sc,sc,sc); + + + D3DXVECTOR3 vCenter( global_shift_x, global_shift_y, global_shift_z); + + D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x+x_offset, -vCenter.y+y_offset, -vCenter.z+z_offset ); + + + D3DXMATRIXA16 m_trans_transpose; + D3DXMatrixTranspose(&m_trans_transpose,&m_trans); + + mWorld = *g_Camera.GetWorldMatrix() ; + mProj = *g_Camera.GetProjMatrix(); + mView = m_trans * *g_Camera.GetViewMatrix(); + + mWorldViewProjection = mView * mProj; + + + // VS Per object + V( pd3dImmediateContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData; + D3DXMatrixTranspose( &pVSPerObject->m_WorldViewProj, &mWorldViewProjection ); + D3DXMatrixTranspose( &pVSPerObject->m_World, &mWorld ); + pd3dImmediateContext->Unmap( g_pcbVSPerObject, 0 ); + + pd3dImmediateContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject ); + + // PS Per object + V( pd3dImmediateContext->Map( g_pcbPSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ); + CB_PS_PER_OBJECT* pPSPerObject = ( CB_PS_PER_OBJECT* )MappedResource.pData; + pPSPerObject->m_vObjectColor = D3DXVECTOR4( 1, 1, 1, 1 ); + pd3dImmediateContext->Unmap( g_pcbPSPerObject, 0 ); + + pd3dImmediateContext->PSSetConstantBuffers( g_iCBPSPerObjectBind, 1, &g_pcbPSPerObject ); + + //Render + SDKMESH_SUBSET* pSubset = NULL; + D3D11_PRIMITIVE_TOPOLOGY PrimType; + + pd3dImmediateContext->PSSetSamplers( 0, 1, &g_pSamLinear ); + + { + // Get the subset + pSubset = g_Mesh11.GetSubset( 0, 0 ); + + pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + pd3dImmediateContext->PSSetShaderResources(0,1,&texture2D_view); + + pd3dImmediateContext->DrawIndexed( (width*3*2+2 + height*width*3*2), 0, ( UINT )pSubset->VertexStart ); + } + + SAFE_RELEASE(pd3dImmediateContext); + } + + void create_buffers(int width_, int height_) + { + width = width_; + height = height_; + + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.ByteWidth = sizeof(vertex_struct)*width*height; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + + vertex_struct *vertices = new vertex_struct[width*height]; + + btCapsuleShape* cs = static_cast(collisionShape); + if (cs) + { + float radius = cs->getRadius(); + float halfHeight = cs->getHalfHeight(); + + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + double coord_2 = sin(2.2*3.141159*y/(float)height)*radius; + double coord_1 = cos(2.2*3.141159*y/(float)height)*radius; + //double coord_2 = (y/((float)(height-1)))*1000; + + //coord = sin(y/); + + vertices[y*width+x].Pos = D3DXVECTOR3(coord_1, ((x/((float)(width-1)))-.5)*halfHeight*2, coord_2); + vertices[y*width+x].Normal = D3DXVECTOR3(coord_1,0,coord_2); + vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1))); + } + } + + + /* + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + double coord = sin(x/5.0)*50; + //coord = sin(y/); + + vertices[y*width+x].Pos = D3DXVECTOR3( (x/((float)(width-1)))*1000, coord, (y/((float)(height-1)))*1000); + vertices[y*width+x].Normal = D3DXVECTOR3(1,0,0); + vertices[y*width+x].Texcoord = D3DXVECTOR2(x/( (float)(width-1)), y/((float)(height-1))); + } + } + */ + + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = vertices; + InitData.SysMemPitch = 0; + InitData.SysMemSlicePitch = 0; + + HRESULT hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &pVB[0]); + + + //What is this vertex stride thing all about? + Strides[0] = ( UINT )g_Mesh11.GetVertexStride( 0, 0 ); + Offsets[0] = 0; + + //unsigned int indices[] = {0,1,2, 1,3,2}; + unsigned int* indices = new unsigned int[width*3*2+2 + height*width*3*2]; + + for(int y = 0; y < height-1; y++) + { + for(int x = 0; x < width-1; x++) + { + indices[x*3*2 + y*width*3*2] = x + y*width; + indices[x*3*2+1 + y*width*3*2] = x+1 + y*width; + indices[x*3*2+2 + y*width*3*2] = x+width + y*width; + + indices[x*3*2 + 3 + y*width*3*2] = x + 1 + y*width; + indices[x*3*2 + 4 + y*width*3*2] = x+(width+1) + y*width; + indices[x*3*2 + 5 + y*width*3*2] = x+width + y*width; + } + } + + bufferDesc.ByteWidth = sizeof(unsigned int)*(width*3*2+2 + height*width*3*2); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + + InitData.pSysMem = indices; + + hr = g_pd3dDevice->CreateBuffer(&bufferDesc, &InitData, &g_pIndexBuffer); + hr = hr; + } + } + + +}; + +#endif CYLINDER_H diff --git a/Demos/DX11ClothDemo/premake4.lua b/Demos/DX11ClothDemo/premake4.lua new file mode 100644 index 0000000..bb21f6a --- /dev/null +++ b/Demos/DX11ClothDemo/premake4.lua @@ -0,0 +1,41 @@ + + hasDX11 = findDirectX11() + + if (hasDX11) then + + project "App_DX11ClothDemo" + + initDirectX11() + + language "C++" + + defines { "UNICODE","_UNICODE"} + + kind "WindowedApp" + flags { "WinMain" } + + targetdir "../.." + includedirs { + "../../src", + "DXUT/Core", + "DXUT/Optional" + } + + links { + "LinearMath","BulletCollision","BulletDynamics", "BulletSoftBody", "BulletSoftBodyDX11Solvers" + } + files { + "DXUT/Core/DXUT.cpp", + "DXUT/Optional/DXUTcamera.cpp", + "DXUT/Core/DXUTDevice11.cpp", + "DXUT/Core/DXUTDevice9.cpp", + "DXUT/Optional/DXUTgui.cpp", + "DXUT/Core/DXUTmisc.cpp", + "DXUT/Optional/DXUTres.cpp", + "DXUT/Optional/DXUTsettingsdlg.cpp", + "DXUT/Optional/SDKmesh.cpp", + "DXUT/Optional/SDKmisc.cpp", + "cloth_renderer.cpp" + } + + end \ No newline at end of file diff --git a/Demos/DX11ClothDemo/resource.h b/Demos/DX11ClothDemo/resource.h new file mode 100644 index 0000000..9807fb1 --- /dev/null +++ b/Demos/DX11ClothDemo/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by BasicHLSL10.rc +// +#define IDI_MAIN_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 40029 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Demos/DX11ClothDemo/texture.bmp b/Demos/DX11ClothDemo/texture.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5bd5e762a6d47f5edbf49a33e3df1dbb6b9dd979 GIT binary patch literal 263222 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 Kt2FVu@IL_Xv7VR! literal 0 HcmV?d00001 diff --git a/Demos/DoublePrecisionDemo/CMakeLists.txt b/Demos/DoublePrecisionDemo/CMakeLists.txt new file mode 100644 index 0000000..cda49cb --- /dev/null +++ b/Demos/DoublePrecisionDemo/CMakeLists.txt @@ -0,0 +1,49 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppDoublePrecisionDemo + DoublePrecisionDemo.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppDoublePrecisionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppDoublePrecisionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppDoublePrecisionDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppDoublePrecisionDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppDoublePrecisionDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/DoublePrecisionDemo/DoublePrecisionDemo.cpp b/Demos/DoublePrecisionDemo/DoublePrecisionDemo.cpp new file mode 100644 index 0000000..6120e1b --- /dev/null +++ b/Demos/DoublePrecisionDemo/DoublePrecisionDemo.cpp @@ -0,0 +1,280 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +/// +/// DoublePrecisionDemo shows high level usage of the Collision Detection. +/// + +#include "GL_Simplex1to4.h" + +//include common Bullet Collision Detection headerfiles +#include "btBulletCollisionCommon.h" + +#include "LinearMath/btIDebugDraw.h" +#include "GLDebugFont.h" + + +#include "GL_ShapeDrawer.h" +#include "DoublePrecisionDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" + +btScalar yaw=btScalar(0.); +btScalar pitch=btScalar(0.); +btScalar roll=btScalar(0.); +const int maxNumObjects = 4; +const int numObjects = 2; + +GL_Simplex1to4 simplex; + + +btCollisionObject objects[maxNumObjects]; +btCollisionWorld* collisionWorld = 0; + +// so pixel ratio is 1:1 +int screenWidth = 640; +int screenHeight = 640; +GLDebugDrawer debugDrawer; + +const btScalar LARGE_DISTANCE_FROM_ORIGIN = btScalar(999999.0); +const btScalar VERY_SMALL_INCREMENT = btScalar(0.000009); + +int main(int argc,char** argv) +{ + DoublePrecisionDemo* doublePrecisionDemo = new DoublePrecisionDemo(); + + doublePrecisionDemo->initPhysics(); + doublePrecisionDemo->setCameraDistance(btScalar(2.0)); + + doublePrecisionDemo->clientResetScene(); + + return glutmain(argc, argv,screenWidth,screenHeight,"Double Precision Demo",doublePrecisionDemo); +} + +void DoublePrecisionDemo::initPhysics() +{ + m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + + btMatrix3x3 basisA; + basisA.setIdentity(); + + btMatrix3x3 basisB; + basisB.setIdentity(); + + objects[0].getWorldTransform().setBasis(basisA); + objects[1].getWorldTransform().setBasis(basisB); + + + btBoxShape* boxA = new btBoxShape(btVector3(0.5,0.5,0.5)); + btBoxShape* boxB = new btBoxShape(btVector3(0.5,0.5,0.5)); + + objects[0].setCollisionShape(boxA);//&hullA; + objects[1].setCollisionShape(boxB);//&hullB; + + btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); + btVector3 worldAabbMin(80000,80000,80000); + btVector3 worldAabbMax(120000,120000,120000); + + btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax); + + collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration); + + collisionWorld->addCollisionObject(&objects[0]); + collisionWorld->addCollisionObject(&objects[1]); + +} + + +//to be implemented by the demo + +void DoublePrecisionDemo::clientMoveAndDisplay() +{ + + displayCallback(); +} + + +static btVoronoiSimplexSolver sGjkSimplexSolver; +btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver; + +void DoublePrecisionDemo::displayCallback(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + + collisionWorld->getDispatchInfo().m_debugDraw = &debugDrawer; + + if (collisionWorld) + collisionWorld->performDiscreteCollisionDetection(); + + int i; + + btVector3 worldBoundsMin,worldBoundsMax; + collisionWorld->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); + + + ///one way to draw all the contact points is iterating over contact manifolds / points: + int numManifolds = collisionWorld->getDispatcher()->getNumManifolds(); + for (i=0;igetDispatcher()->getManifoldByIndexInternal(i); + const btCollisionObject* obA = static_cast(contactManifold->getBody0()); + const btCollisionObject* obB = static_cast(contactManifold->getBody1()); + contactManifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform()); + + int numContacts = contactManifold->getNumContacts(); + for (int j=0;jgetContactPoint(j); + + glBegin(GL_LINES); + glColor3f(1, 1, 1); + + btVector3 ptA = pt.getPositionWorldOnA() - m_cameraPosition; + btVector3 ptB = pt.getPositionWorldOnB() - m_cameraPosition; + + glVertex3d(ptA.x(),ptA.y(),ptA.z()); + glVertex3d(ptB.x(),ptB.y(),ptB.z()); + glEnd(); + } + + //you can un-comment out this line, and then all points are removed + //contactManifold->clearManifold(); + } + + btScalar m[16]; + btTransform temp; + + + btVector3 color; + //int i; + for (i=0;idrawOpenGL(m,objects[i].getCollisionShape(),color,getDebugMode(),worldBoundsMin,worldBoundsMax); + } + + objects[1].getWorldTransform().setOrigin(objects[1].getWorldTransform().getOrigin()+btVector3(-VERY_SMALL_INCREMENT,-VERY_SMALL_INCREMENT,0)); + objects[0].getWorldTransform().setOrigin(objects[0].getWorldTransform().getOrigin()+btVector3(VERY_SMALL_INCREMENT,VERY_SMALL_INCREMENT,0)); + + float yStart = 20.f; + float yIncr = 20.f; + char buf[124]; + + glColor3f(0, 0, 0); + + setOrthographicProjection(); + + glRasterPos3f(10.0f,yStart,0); + #ifdef BT_USE_DOUBLE_PRECISION + GLDebugDrawString(10.f,yStart,"Double Precision Mode"); + #else + GLDebugDrawString(10.f,yStart,"Single Precision Mode"); + #endif + yStart += yIncr; + + glRasterPos3f(10.0f,yStart,0); + sprintf(buf,"Movement distance in x and y axis = %lf", VERY_SMALL_INCREMENT); + + GLDebugDrawString(10.f,yStart,buf); + yStart += yIncr; + + glRasterPos3f(10.0f,yStart,0); + btScalar xValue = objects[0].getWorldTransform().getOrigin().x(); + btScalar yValue = objects[0].getWorldTransform().getOrigin().y(); + btScalar zValue = objects[0].getWorldTransform().getOrigin().z(); + sprintf(buf,"Cube 0 location = ( %lf, %lf, %lf )", xValue, yValue, zValue); + GLDebugDrawString(10.f,yStart,buf); + yStart += yIncr; + + xValue = objects[1].getWorldTransform().getOrigin().x(); + yValue = objects[1].getWorldTransform().getOrigin().y(); + zValue = objects[1].getWorldTransform().getOrigin().z(); + glRasterPos3f(10.0f,yStart,0); + sprintf(buf,"Cube 1 location = ( %lf, %lf, %lf )", xValue, yValue, zValue); + GLDebugDrawString(10.f,yStart,buf); + yStart += yIncr; + + glRasterPos3f(10.0f,yStart,0); + GLDebugDrawString(10.f,yStart,"w=toggle wireframe/solid"); + + resetPerspectiveProjection(); + + glFlush(); + glutSwapBuffers(); +} + +void DoublePrecisionDemo::clientResetScene() +{ + objects[0].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN)); + objects[1].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN)); +} + + + +void DoublePrecisionDemo::updateCamera() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // look at the stationary cube + m_cameraTargetPosition = objects[0].getWorldTransform().getOrigin(); + + m_cameraPosition = m_cameraTargetPosition; + m_cameraPosition[2] = m_cameraTargetPosition[2] - m_cameraDistance; + + //update OpenGL camera settings + glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0); + + // To not loose precision in the rendering process, we shift the object to the origin + gluLookAt(0.0, 0.0, 0.0, + m_cameraTargetPosition[0]-m_cameraPosition[0],m_cameraTargetPosition[1]-m_cameraPosition[1], m_cameraTargetPosition[2]-m_cameraPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + glMatrixMode(GL_MODELVIEW); +} + +void DoublePrecisionDemo::keyboardCallback(unsigned char key, int x, int y) +{ + if (key == 'w') + { + if (m_debugMode & btIDebugDraw::DBG_DrawWireframe) + { + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe); + m_debugMode |= btIDebugDraw::DBG_DrawAabb; + } + else + { + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb); + m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + } + return; + } + + DemoApplication::keyboardCallback(key, x, y); +} + + diff --git a/Demos/DoublePrecisionDemo/DoublePrecisionDemo.h b/Demos/DoublePrecisionDemo/DoublePrecisionDemo.h new file mode 100644 index 0000000..7de07fd --- /dev/null +++ b/Demos/DoublePrecisionDemo/DoublePrecisionDemo.h @@ -0,0 +1,41 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef COLLISION_INTERFACE_DEMO_H +#define COLLISION_INTERFACE_DEMO_H + +#include "GlutDemoApplication.h" + +///DoublePrecisionDemo shows how to use the collision detection without dynamics (btCollisionWorld/CollisionObject) +class DoublePrecisionDemo : public GlutDemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene(); + + virtual void updateCamera(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + +}; + +#endif //COLLISION_INTERFACE_DEMO_H + + diff --git a/Demos/DynamicControlDemo/CMakeLists.txt b/Demos/DynamicControlDemo/CMakeLists.txt new file mode 100644 index 0000000..2fc7fda --- /dev/null +++ b/Demos/DynamicControlDemo/CMakeLists.txt @@ -0,0 +1,49 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppMotorDemo + MotorDemo.cpp + main.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppMotorDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppMotorDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppMotorDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppMotorDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppMotorDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/DynamicControlDemo/MotorDemo.cpp b/Demos/DynamicControlDemo/MotorDemo.cpp new file mode 100644 index 0000000..ee2184e --- /dev/null +++ b/Demos/DynamicControlDemo/MotorDemo.cpp @@ -0,0 +1,468 @@ +/* +Bullet Continuous Collision Detection and Physics Library Copyright (c) 2007 Erwin Coumans +Motor Demo + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btBulletDynamicsCommon.h" +#include "GlutStuff.h" +#include "GL_ShapeDrawer.h" + +#include "LinearMath/btIDebugDraw.h" + +#include "GLDebugDrawer.h" +#include "MotorDemo.h" + + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 +#endif + +#ifndef M_PI_4 +#define M_PI_4 0.785398163397448309616 +#endif + +#ifndef M_PI_8 +#define M_PI_8 0.5 * M_PI_4 +#endif + + +// LOCAL FUNCTIONS + +void vertex(btVector3 &v) +{ + glVertex3d(v.getX(), v.getY(), v.getZ()); +} + +void drawFrame(btTransform &tr) +{ + const float fSize = 1.f; + + glBegin(GL_LINES); + + // x + glColor3f(255.f,0,0); + btVector3 vX = tr*btVector3(fSize,0,0); + vertex(tr.getOrigin()); vertex(vX); + + // y + glColor3f(0,255.f,0); + btVector3 vY = tr*btVector3(0,fSize,0); + vertex(tr.getOrigin()); vertex(vY); + + // z + glColor3f(0,0,255.f); + btVector3 vZ = tr*btVector3(0,0,fSize); + vertex(tr.getOrigin()); vertex(vZ); + + glEnd(); +} + +// /LOCAL FUNCTIONS + + + +#define NUM_LEGS 6 +#define BODYPART_COUNT 2 * NUM_LEGS + 1 +#define JOINT_COUNT BODYPART_COUNT - 1 + +class TestRig +{ + btDynamicsWorld* m_ownerWorld; + btCollisionShape* m_shapes[BODYPART_COUNT]; + btRigidBody* m_bodies[BODYPART_COUNT]; + btTypedConstraint* m_joints[JOINT_COUNT]; + + btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape) + { + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + shape->calculateLocalInertia(mass,localInertia); + + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + m_ownerWorld->addRigidBody(body); + + return body; + } + + +public: + TestRig (btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed) + : m_ownerWorld (ownerWorld) + { + btVector3 vUp(0, 1, 0); + + // + // Setup geometry + // + float fBodySize = 0.25f; + float fLegLength = 0.45f; + float fForeLegLength = 0.75f; + m_shapes[0] = new btCapsuleShape(btScalar(fBodySize), btScalar(0.10)); + int i; + for ( i=0; isetDamping(0.05, 0.85); + m_bodies[i]->setDeactivationTime(0.8); + //m_bodies[i]->setSleepingThresholds(1.6, 2.5); + m_bodies[i]->setSleepingThresholds(0.5f, 0.5f); + } + + + // + // Setup the constraints + // + btHingeConstraint* hingeC; + //btConeTwistConstraint* coneC; + + btTransform localA, localB, localC; + + for ( i=0; igetWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; + hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1+2*i], localA, localB); + hingeC->setLimit(btScalar(-0.75 * M_PI_4), btScalar(M_PI_8)); + //hingeC->setLimit(btScalar(-0.1), btScalar(0.1)); + m_joints[2*i] = hingeC; + m_ownerWorld->addConstraint(m_joints[2*i], true); + + // knee joints + localA.setIdentity(); localB.setIdentity(); localC.setIdentity(); + localA.getBasis().setEulerZYX(0,-fAngle,0); localA.setOrigin(btVector3(btScalar(fCos*(fBodySize+fLegLength)), btScalar(0.), btScalar(fSin*(fBodySize+fLegLength)))); + localB = m_bodies[1+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; + localC = m_bodies[2+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; + hingeC = new btHingeConstraint(*m_bodies[1+2*i], *m_bodies[2+2*i], localB, localC); + //hingeC->setLimit(btScalar(-0.01), btScalar(0.01)); + hingeC->setLimit(btScalar(-M_PI_8), btScalar(0.2)); + m_joints[1+2*i] = hingeC; + m_ownerWorld->addConstraint(m_joints[1+2*i], true); + } + } + + virtual ~TestRig () + { + int i; + + // Remove all constraints + for ( i = 0; i < JOINT_COUNT; ++i) + { + m_ownerWorld->removeConstraint(m_joints[i]); + delete m_joints[i]; m_joints[i] = 0; + } + + // Remove all bodies and shapes + for ( i = 0; i < BODYPART_COUNT; ++i) + { + m_ownerWorld->removeRigidBody(m_bodies[i]); + + delete m_bodies[i]->getMotionState(); + + delete m_bodies[i]; m_bodies[i] = 0; + delete m_shapes[i]; m_shapes[i] = 0; + } + } + + btTypedConstraint** GetJoints() {return &m_joints[0];} + +}; + + + +void motorPreTickCallback (btDynamicsWorld *world, btScalar timeStep) +{ + MotorDemo* motorDemo = (MotorDemo*)world->getWorldUserInfo(); + + motorDemo->setMotorTargets(timeStep); + +} + + + +void MotorDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + // Setup the basic world + + m_Time = 0; + m_fCyclePeriod = 2000.f; // in milliseconds + +// m_fMuscleStrength = 0.05f; + // new SIMD solver for joints clips accumulated impulse, so the new limits for the motor + // should be (numberOfsolverIterations * oldLimits) + // currently solver uses 10 iterations, so: + m_fMuscleStrength = 0.5f; + + setCameraDistance(btScalar(5.)); + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + btVector3 worldAabbMin(-10000,-10000,-10000); + btVector3 worldAabbMax(10000,10000,10000); + m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); + + m_solver = new btSequentialImpulseConstraintSolver; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + + m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback,this,true); + + + // Setup a big ground box + { + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-10,0)); + localCreateRigidBody(btScalar(0.),groundTransform,groundShape); + } + + // Spawn one ragdoll + btVector3 startOffset(1,0.5,0); + spawnTestRig(startOffset, false); + startOffset.setValue(-2,0.5,0); + spawnTestRig(startOffset, true); + + clientResetScene(); +} + + +void MotorDemo::spawnTestRig(const btVector3& startOffset, bool bFixed) +{ + TestRig* rig = new TestRig(m_dynamicsWorld, startOffset, bFixed); + m_rigs.push_back(rig); +} + +void PreStep() +{ + +} + + + + +void MotorDemo::setMotorTargets(btScalar deltaTime) +{ + + float ms = deltaTime*1000000.; + float minFPS = 1000000.f/60.f; + if (ms > minFPS) + ms = minFPS; + + m_Time += ms; + + // + // set per-frame sinusoidal position targets using angular motor (hacky?) + // + for (int r=0; r(m_rigs[r]->GetJoints()[i]); + btScalar fCurAngle = hingeC->getHingeAngle(); + + btScalar fTargetPercent = (int(m_Time / 1000) % int(m_fCyclePeriod)) / m_fCyclePeriod; + btScalar fTargetAngle = 0.5 * (1 + sin(2 * M_PI * fTargetPercent)); + btScalar fTargetLimitAngle = hingeC->getLowerLimit() + fTargetAngle * (hingeC->getUpperLimit() - hingeC->getLowerLimit()); + btScalar fAngleError = fTargetLimitAngle - fCurAngle; + btScalar fDesiredAngularVel = 1000000.f * fAngleError/ms; + hingeC->enableAngularMotor(true, fDesiredAngularVel, m_fMuscleStrength); + } + } + + +} + +void MotorDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float deltaTime = getDeltaTimeMicroseconds()/1000000.f; + + + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(deltaTime); + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + for (int i=2; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + drawFrame(body->getWorldTransform()); + } + + glFlush(); + + glutSwapBuffers(); +} + +void MotorDemo::displayCallback() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + glutSwapBuffers(); +} + +void MotorDemo::keyboardCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case '+': case '=': + m_fCyclePeriod /= 1.1f; + if (m_fCyclePeriod < 1.f) + m_fCyclePeriod = 1.f; + break; + case '-': case '_': + m_fCyclePeriod *= 1.1f; + break; + case '[': + m_fMuscleStrength /= 1.1f; + break; + case ']': + m_fMuscleStrength *= 1.1f; + break; + default: + DemoApplication::keyboardCallback(key, x, y); + } +} + + + +void MotorDemo::exitPhysics() +{ + + int i; + + for (i=0;igetNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_rigs; + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + +public: + void initPhysics(); + + void exitPhysics(); + + virtual ~MotorDemo() + { + exitPhysics(); + } + + void spawnTestRig(const btVector3& startOffset, bool bFixed); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + MotorDemo* demo = new MotorDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } + + void setMotorTargets(btScalar deltaTime); + +}; + + +#endif diff --git a/Demos/DynamicControlDemo/main.cpp b/Demos/DynamicControlDemo/main.cpp new file mode 100644 index 0000000..188c88d --- /dev/null +++ b/Demos/DynamicControlDemo/main.cpp @@ -0,0 +1,28 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "MotorDemo.h" +#include "GlutStuff.h" + +int main(int argc,char* argv[]) +{ + MotorDemo demoApp; + + demoApp.initPhysics(); + + + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bullet.sf.net",&demoApp); +} diff --git a/Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp b/Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp new file mode 100644 index 0000000..e83d53c --- /dev/null +++ b/Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp @@ -0,0 +1,856 @@ + +///contribution by Pierre Terdiman to check penetration depth solvers +///see http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=638 + +#ifdef WIN32//for glut.h +#include +#endif + + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#else +#include +#endif + + +#include +#include +#include + +#define VERBOSE_TEXT_ONSCREEN 1 +#ifdef VERBOSE_TEXT_ONSCREEN +#include "GLDebugFont.h" +#endif + +#include "btBulletCollisionCommon.h" + +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "LinearMath/btStackAlloc.h" + +//We can use the Bullet EPA or sampling penetration depth solver, but comparison might be useful +//#define COMPARE_WITH_SOLID35_AND_OTHER_EPA 1 +#ifdef COMPARE_WITH_SOLID35_AND_OTHER_EPA +#include "../Extras/ExtraSolid35/Solid3EpaPenetrationDepth.h" +#include "../Extras/ExtraSolid35/Solid3JohnsonSimplexSolver.h" +#include "../Extras/EPA/EpaPenetrationDepthSolver.h" +#endif //COMPARE_WITH_SOLID35_AND_OTHER_EPA + +#define USE_ORIGINAL 1 +#ifndef USE_ORIGINAL +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#endif //USE_ORIGINAL + +static bool gRefMode = false; +static int gMethod = 0; +static int gLastUsedMethod = -1; +static int gNumGjkIterations = -1; +static int gLastDegenerateSimplex = -1; + +static const float gDisp = 0.01f; +static const float gCamSpeed = 0.1f; +static btVector3 Eye(3.0616338f, 1.1985892f, 2.5769043f); +static btVector3 Dir(-0.66853905,-0.14004262,-0.73037237); +static btVector3 N; +static int mx = 0; +static int my = 0; +static int glutScreenHeight = 512; +static int glutScreenWidth = 512; + +static void DrawLine(const btVector3& p0, const btVector3& p1, const btVector3& color, float line_width) +{ + glDisable(GL_LIGHTING); + glLineWidth(line_width); + glColor4f(color.x(), color.y(), color.z(), 1.0f); + btVector3 tmp[] = {p0, p1}; + glEnableClientState(GL_VERTEX_ARRAY); +#ifndef BT_USE_DOUBLE_PRECISION + glVertexPointer(3, GL_FLOAT, sizeof(btVector3), &tmp[0].x()); +#else + glVertexPointer(3, GL_DOUBLE, sizeof(btVector3), &tmp[0].x()); +#endif + glDrawArrays(GL_LINES, 0, 2); + glDisableClientState(GL_VERTEX_ARRAY); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_LIGHTING); +} + +void DrawTriangle(const btVector3& p0, const btVector3& p1, const btVector3& p2, const btVector3& color) +{ +// glDisable(GL_LIGHTING); + glColor4f(color.x(), color.y(), color.z(), 1.0f); + btVector3 tmp[] = {p0, p1, p2}; + glEnableClientState(GL_VERTEX_ARRAY); +#ifndef BT_USE_DOUBLE_PRECISION + glVertexPointer(3, GL_FLOAT, sizeof(btVector3), &tmp[0].x()); +#else + glVertexPointer(3, GL_DOUBLE, sizeof(btVector3), &tmp[0].x()); +#endif + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableClientState(GL_VERTEX_ARRAY); +// glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +// glEnable(GL_LIGHTING); +} + +class MyPoly +{ + public: + MyPoly() : mNbVerts(0), mIndices(NULL) {} + ~MyPoly() { delete[]mIndices; } + + short mNbVerts; + char* mIndices; + float mPlane[4]; +}; + +class MyConvex +{ + public: + MyConvex(); + ~MyConvex(); + + bool LoadFromFile(const char* filename); + void Render(bool only_wireframe, const btVector3& wire_color) const; + void Project(const btVector3& dir, float& min, float& max) const; + + int mNbVerts; + btVector3* mVerts; + int mNbPolys; + MyPoly* mPolys; + btTransform mTransform; +}; + +MyConvex::MyConvex() : + mNbVerts (0), + mVerts (NULL), + mNbPolys (0), + mPolys (NULL) +{ + mTransform.setIdentity(); +} + +MyConvex::~MyConvex() +{ + delete[]mPolys; + delete[]mVerts; +} + +bool MyConvex::LoadFromFile(const char* filename) +{ + FILE* fp = fopen(filename, "rb"); + if(!fp) return false; + + fread(&mNbVerts, sizeof(int), 1, fp); + + int i; + + mVerts = new btVector3[mNbVerts]; + for( i=0;i max) max = dp; + } + if(min>max) + { + float tmp = min; + min = max; + max = tmp; + } +} + +static btVector3 gNormal; +static btVector3 gPoint; +static float gDepth; + + struct MyResult : public btDiscreteCollisionDetectorInterface::Result + { + virtual void setShapeIdentifiersA(int partId0, int index0) + { + } + virtual void setShapeIdentifiersB(int partId1, int index1) + { + } + + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) + { + gNormal = normalOnBInWorld; + gPoint = pointInWorld; + gDepth = depth; + } + }; + +//2 Mb by default, could be made smaller +btStackAlloc gStackAlloc(1024*1024*2); + +static bool TestEPA(const MyConvex& hull0, const MyConvex& hull1) +{ + static btSimplexSolverInterface simplexSolver; +#ifdef COMPARE_WITH_SOLID35_AND_OTHER_EPA +// static Solid3JohnsonSimplexSolver simplexSolver2; +#endif //COMPARE_WITH_SOLID35_AND_OTHER_EPA + + simplexSolver.reset(); + + btConvexHullShape convexA((btScalar*)hull0.mVerts, hull0.mNbVerts, sizeof(btVector3)); + btConvexHullShape convexB((btScalar*)hull1.mVerts, hull1.mNbVerts, sizeof(btVector3)); + + static btGjkEpaPenetrationDepthSolver Solver0; + static btMinkowskiPenetrationDepthSolver Solver1; + +#ifdef COMPARE_WITH_SOLID35_AND_OTHER_EPA + static Solid3EpaPenetrationDepth Solver2; + static EpaPenetrationDepthSolver Solver3; +#endif + + + btConvexPenetrationDepthSolver* Solver = NULL ; + if(gMethod==0) + Solver = &Solver0; + else if(gMethod==1) + Solver = &Solver1; +#ifdef COMPARE_WITH_SOLID35_AND_OTHER_EPA + else if(gMethod==2) + Solver = &Solver2; + else + Solver = &Solver3; +#endif //COMPARE_WITH_SOLID35_AND_OTHER_EPA + + +#ifdef USE_ORIGINAL + + btGjkPairDetector GJK(&convexA, &convexB, &simplexSolver, Solver); + GJK.m_catchDegeneracies = 1; + convexA.setMargin(0.01f); + convexB.setMargin(0.01f); + + btDiscreteCollisionDetectorInterface::ClosestPointInput input; + input.m_transformA = hull0.mTransform; + input.m_transformB = hull1.mTransform; + input.m_stackAlloc = &gStackAlloc; + + MyResult output; + GJK.getClosestPoints(input, output, 0); + gLastUsedMethod = GJK.m_lastUsedMethod; + gNumGjkIterations = GJK.m_curIter; + gLastDegenerateSimplex= GJK.m_degenerateSimplex; +#else + MyResult output; + btVector3 witnesses[2]; + btVector3 normal; + btScalar depth; + + btGjkEpaSolver::sResults results; + btScalar radialMargin = 0.01f; + + btGjkEpaSolver::Collide(&convexA,hull0.mTransform, + &convexB,hull1.mTransform, + radialMargin, + results); + if (results.depth>0) + { + output.addContactPoint(results.normal,results.witnesses[1],-results.depth); + } +#endif + return true; +} + +static bool TestSepAxis(const btVector3& sep_axis, const MyConvex& hull0, const MyConvex& hull1, float& depth) +{ + float Min0,Max0; + float Min1,Max1; + hull0.Project(sep_axis, Min0, Max0); + hull1.Project(sep_axis, Min1, Max1); + + if(Max0=0.0f); + float d1 = Max1 - Min0; + btAssert(d1>=0.0f); + depth = d01e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false; + return true; +} + +static bool ReferenceCode(const MyConvex& hull0, const MyConvex& hull1, float& dmin, btVector3& sep) +{ + dmin = FLT_MAX; + + int i; + + // Test normals from hull0 + for( i=0;i0.0f) sep = -sep; + + return true; +} + + + +static MyConvex gConvex0; +static MyConvex gConvex1; + +static void KeyboardCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case 27: exit(0); break; + + case 'R': + case 'r': + gRefMode = !gRefMode; + break; + + case ' ': + gMethod++; +#ifdef COMPARE_WITH_SOLID35_AND_OTHER_EPA + if(gMethod==4) gMethod=0; +#else + if(gMethod==2) gMethod=0; +#endif + break; + + case '4': + gConvex0.mTransform.setOrigin(gConvex0.mTransform.getOrigin() + btVector3(-gDisp,0,0)); + break; + case '7': + gConvex0.mTransform.setRotation(gConvex0.mTransform.getRotation()*btQuaternion(btVector3(1,0,0),0.01)); + break; + case '9': + gConvex0.mTransform.setRotation(gConvex0.mTransform.getRotation()*btQuaternion(btVector3(1,0,0),-0.01)); + break; + case '1': + gConvex0.mTransform.setRotation(gConvex0.mTransform.getRotation()*btQuaternion(btVector3(0,1,0),0.01)); + break; + case '3': + gConvex0.mTransform.setRotation(gConvex0.mTransform.getRotation()*btQuaternion(btVector3(0,1,0),-0.01)); + break; + case '5': + gConvex0.mTransform.setRotation(gConvex0.mTransform.getRotation()*btQuaternion(btVector3(0,0,1),0.01)); + break; + + case '6': + gConvex0.mTransform.setOrigin(gConvex0.mTransform.getOrigin() + btVector3(gDisp,0,0)); + break; + case '8': + gConvex0.mTransform.setOrigin(gConvex0.mTransform.getOrigin() + btVector3(0,gDisp,0)); + break; + case '2': + gConvex0.mTransform.setOrigin(gConvex0.mTransform.getOrigin() + btVector3(0,-gDisp,0)); + break; + + case 101: Eye += Dir * gCamSpeed; break; + case 103: Eye -= Dir * gCamSpeed; break; + case 100: Eye -= N * gCamSpeed; break; + case 102: Eye += N * gCamSpeed; break; + } +} + +static void ArrowKeyCallback(int key, int x, int y) +{ + KeyboardCallback(key,x,y); +} + +static void MouseCallback(int button, int state, int x, int y) +{ + mx = x; + my = y; +} + +static const float NxPiF32 = 3.141592653589793f; + +float degToRad(float a) + { + return (float)0.01745329251994329547 * a; + } + +class NxQuat + { + public: + NxQuat(){} + + NxQuat(const float angle, const btVector3 & axis) + { + x = axis.x(); + y = axis.y(); + z = axis.z(); + + const float i_length = 1.0f / sqrtf( x*x + y*y + z*z ); + x = x * i_length; + y = y * i_length; + z = z * i_length; + + float Half = degToRad(angle * 0.5f); + + w = cosf(Half); + const float sin_theta_over_two = sinf(Half ); + x = x * sin_theta_over_two; + y = y * sin_theta_over_two; + z = z * sin_theta_over_two; + } + + void multiply(const NxQuat& left, const btVector3& right) + { + float a,b,c,d; + + a = - left.x*right.x() - left.y*right.y() - left.z *right.z(); + b = left.w*right.x() + left.y*right.z() - right.y()*left.z; + c = left.w*right.y() + left.z*right.x() - right.z()*left.x; + d = left.w*right.z() + left.x*right.y() - right.x()*left.y; + + w = a; + x = b; + y = c; + z = d; + } + + void rotate(btVector3 & v) const + { + NxQuat myInverse; + myInverse.x = -x; + myInverse.y = -y; + myInverse.z = -z; + myInverse.w = w; + + NxQuat left; + left.multiply(*this,v); + float vx = left.w*myInverse.x + myInverse.w*left.x + left.y*myInverse.z - myInverse.y*left.z; + float vy = left.w*myInverse.y + myInverse.w*left.y + left.z*myInverse.x - myInverse.z*left.x; + float vz = left.w*myInverse.z + myInverse.w*left.z + left.x*myInverse.y - myInverse.x*left.y; + v.setValue(vx, vy, vz); + } + + float x,y,z,w; +}; + + +static void MotionCallback(int x, int y) +{ + int dx = mx - x; + int dy = my - y; + + Dir = Dir.normalize(); + N = Dir.cross(btVector3(0,1,0)); + + NxQuat qx(NxPiF32 * dx * 20/ 180.0f, btVector3(0,1,0)); + qx.rotate(Dir); + NxQuat qy(NxPiF32 * dy * 20/ 180.0f, N); + qy.rotate(Dir); + + mx = x; + my = y; +} + +static void RenderCallback() +{ + // Clear buffers + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Setup camera + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0f, ((float)glutGet(GLUT_WINDOW_WIDTH))/((float)glutGet(GLUT_WINDOW_HEIGHT)), 1.0f, 10000.0f); + gluLookAt(Eye.x(), Eye.y(), Eye.z(), Eye.x() + Dir.x(), Eye.y() + Dir.y(), Eye.z() + Dir.z(), 0.0f, 1.0f, 0.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_LIGHTING); + + //clear previous frames result + gNormal.setValue(10,0,0); + gPoint.setValue(0,0,0); + gDepth = 999.999; + gLastUsedMethod = -1; + gNumGjkIterations = -1; + + + TestEPA(gConvex0, gConvex1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + btVector3 RefSep(btScalar(0.), btScalar(0.), btScalar(0.)); + float RefDMin=0.f; + bool RefResult = false; + if(gRefMode) + RefResult = ReferenceCode(gConvex0, gConvex1, RefDMin, RefSep); + +// DrawLine(gPoint, gPoint + gNormal*20.0f, btVector3(1,0,0), 2.0f); +// printf("%f: %f %f %f\n", gDepth, gNormal.x(), gNormal.y(), gNormal.z()); + +#ifdef VERBOSE_TEXT_ONSCREEN + glColor3f(255.f, 255.f, 255.f); + + setOrthographicProjection(); + float xOffset = 10.f; + float yStart = 20.f; + float yIncr = 20.f; + char buf[124]; + + sprintf(buf,"gDepth=%f: gNormal=(%f %f %f)\n", gDepth, gNormal.x(), gNormal.y(), gNormal.z()); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + sprintf(buf,"num GJK iterations =%d\n", gNumGjkIterations); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + sprintf(buf,"gLastUsedMethod=%d\n", gLastUsedMethod); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + + + + if (gLastUsedMethod >= 3) + { + switch ( gMethod) + { + case 0: + sprintf(buf,"Bullet GjkEpa Penetration depth solver (zlib free\n" ); + break; + case 1: + sprintf(buf,"Bullet Minkowski sampling Penetration depth solver\n" ); + break; + case 2: + sprintf(buf,"Solid35 EPA Penetration depth solver\n" ); + break; + case 3: + sprintf(buf,"EPA Penetration depth solver (Experimental/WorkInProgress, zlib free\n" ); + break; + default: + sprintf(buf,"Unknown Penetration Depth\n" ); + } + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + } else + { + sprintf(buf,"Hybrid GJK method %d\n", gLastUsedMethod); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + } + + if (gLastDegenerateSimplex) + { + sprintf(buf,"DegenerateSimplex %d\n", gLastDegenerateSimplex); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + } + + + + + resetPerspectiveProjection(); +#endif //VERBOSE_TEXT_ONSCREEN + + btVector3 color(0,0,0); + gConvex0.Render(false, color); + gConvex1.Render(false, color); + + if(gDepth<0.0f) + { + btTransform Saved = gConvex0.mTransform; + gConvex0.mTransform.setOrigin(gConvex0.mTransform.getOrigin() - btVector3(gNormal*gDepth)); + gConvex0.Render(true, btVector3(1.0f, 0.5f, 0.0f)); + gConvex0.mTransform = Saved; + } + else + { + DrawLine(gPoint, gPoint + gNormal, btVector3(0,1,0), 2.0f); + } + + if(RefResult & gRefMode) + { + btTransform Saved = gConvex0.mTransform; + gConvex0.mTransform.setOrigin(gConvex0.mTransform.getOrigin() + btVector3(RefSep*RefDMin)); + gConvex0.Render(true, btVector3(0.0f, 0.5f, 1.0f)); + gConvex0.mTransform = Saved; + } + + glutSwapBuffers(); +} + +static void ReshapeCallback(int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void IdleCallback() +{ + glutPostRedisplay(); +} + +int main(int argc, char** argv) +{ + // Initialize Glut + glutInit(&argc, argv); + glutInitWindowSize(glutScreenWidth, glutScreenHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + int mainHandle = glutCreateWindow("TestBullet"); + glutSetWindow(mainHandle); + glutDisplayFunc(RenderCallback); + glutReshapeFunc(ReshapeCallback); + glutIdleFunc(IdleCallback); + glutKeyboardFunc(KeyboardCallback); + glutSpecialFunc(ArrowKeyCallback); + glutMouseFunc(MouseCallback); + glutMotionFunc(MotionCallback); + MotionCallback(0,0); + + // Setup default render states + glClearColor(0.3f, 0.4f, 0.5f, 1.0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_CULL_FACE); + + // Setup lighting + glEnable(GL_LIGHTING); + float AmbientColor[] = { 0.0f, 0.1f, 0.2f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor); + float DiffuseColor[] = { 1.0f, 1.0f, 1.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor); + float SpecularColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor); + float Position[] = { -10.0f, 1000.0f, -4.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position); + glEnable(GL_LIGHT0); + + // + bool Status = gConvex0.LoadFromFile("convex0.bin"); + if(!Status) + { + Status = gConvex0.LoadFromFile("../../convex0.bin"); + if(!Status) + { + printf("Failed to load object!\n"); + exit(0); + } + } + Status = gConvex1.LoadFromFile("convex0.bin"); + if(!Status) + { + Status = gConvex1.LoadFromFile("../../convex0.bin"); + if(!Status) + { + printf("Failed to load object!\n"); + exit(0); + } + } + +// gConvex0.mTransform.setOrigin(btVector3(1.0f, 1.0f, 0.0f)); + gConvex0.mTransform.setOrigin(btVector3(0.20000069f, 0.95000005f, 0.0f)); + + // Run + glutMainLoop(); + + return 0; +} diff --git a/Demos/ForkLiftDemo/CMakeLists.txt b/Demos/ForkLiftDemo/CMakeLists.txt new file mode 100644 index 0000000..9098ad8 --- /dev/null +++ b/Demos/ForkLiftDemo/CMakeLists.txt @@ -0,0 +1,59 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +IF (WIN32) + ADD_EXECUTABLE(AppForkLiftDemo + ForkLiftDemo.cpp + main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppForkLiftDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppForkLiftDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) + +ELSE() + ADD_EXECUTABLE(AppForkLiftDemo + ForkLiftDemo.cpp + main.cpp + ) +ENDIF() + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppForkLiftDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppForkLiftDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppForkLiftDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ForkLiftDemo/ForkLiftDemo.cpp b/Demos/ForkLiftDemo/ForkLiftDemo.cpp new file mode 100644 index 0000000..30bb7f5 --- /dev/null +++ b/Demos/ForkLiftDemo/ForkLiftDemo.cpp @@ -0,0 +1,866 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///September 2006: VehicleDemo is work in progress, this file is mostly just a placeholder +///This VehicleDemo file is very early in development, please check it later +///@todo is a basic engine model: +///A function that maps user input (throttle) into torque/force applied on the wheels +///with gears etc. +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" +#include "GLDebugFont.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 +#endif + +#ifndef M_PI_4 +#define M_PI_4 0.785398163397448309616 +#endif + +//#define LIFT_EPS 0.0000001f +// +// By default, Bullet Vehicle uses Y as up axis. +// You can override the up axis, for example Z-axis up. Enable this define to see how to: +//#define FORCE_ZAXIS_UP 1 +// + +#ifdef FORCE_ZAXIS_UP + int rightIndex = 0; + int upIndex = 2; + int forwardIndex = 1; + btVector3 wheelDirectionCS0(0,0,-1); + btVector3 wheelAxleCS(1,0,0); +#else + int rightIndex = 0; + int upIndex = 1; + int forwardIndex = 2; + btVector3 wheelDirectionCS0(0,-1,0); + btVector3 wheelAxleCS(-1,0,0); +#endif + +#include "GLDebugDrawer.h" +#include //printf debugging + +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" +#include "ForkLiftDemo.h" + + +const int maxProxies = 32766; +const int maxOverlap = 65535; + +///btRaycastVehicle is the interface for the constraint that implements the raycast vehicle +///notice that for higher-quality slow-moving vehicles, another approach might be better +///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts +float gEngineForce = 0.f; + +float defaultBreakingForce = 10.f; +float gBreakingForce = 100.f; + +float maxEngineForce = 1000.f;//this should be engine/velocity dependent +float maxBreakingForce = 100.f; + +float gVehicleSteering = 0.f; +float steeringIncrement = 0.04f; +float steeringClamp = 0.3f; +float wheelRadius = 0.5f; +float wheelWidth = 0.4f; +float wheelFriction = 1000;//BT_LARGE_FLOAT; +float suspensionStiffness = 20.f; +float suspensionDamping = 2.3f; +float suspensionCompression = 4.4f; +float rollInfluence = 0.1f;//1.0f; + + +btScalar suspensionRestLength(0.6); + +#define CUBE_HALF_EXTENTS 1 + + + +//////////////////////////////////// + + + + +ForkLiftDemo::ForkLiftDemo() +: +m_carChassis(0), +m_liftBody(0), +m_forkBody(0), +m_loadBody(0), +m_indexVertexArrays(0), +m_vertices(0), +m_cameraHeight(4.f), +m_minCameraDistance(3.f), +m_maxCameraDistance(10.f) +{ + m_vehicle = 0; + m_wheelShape = 0; + m_cameraPosition = btVector3(30,30,30); + m_useDefaultCamera = false; + setTexturing(true); + setShadows(true); + +} + + +void ForkLiftDemo::termPhysics() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + + while (body->getNumConstraintRefs()) + { + btTypedConstraint* constraint = body->getConstraintRef(0); + m_dynamicsWorld->removeConstraint(constraint); + delete constraint; + } + delete body->getMotionState(); + m_dynamicsWorld->removeRigidBody(body); + } else + { + m_dynamicsWorld->removeCollisionObject( obj ); + } + delete obj; + } + + //delete collision shapes + for (int j=0;jsetGravity(btVector3(0,0,-10)); +#endif + + //m_dynamicsWorld->setGravity(btVector3(0,0,0)); +btTransform tr; +tr.setIdentity(); +tr.setOrigin(btVector3(0,-10,0)); + +//either use heightfield or triangle mesh + + + //create ground object + localCreateRigidBody(0,tr,groundShape); + +#ifdef FORCE_ZAXIS_UP +// indexRightAxis = 0; +// indexUpAxis = 2; +// indexForwardAxis = 1; + btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,2.f, 0.5f)); + btCompoundShape* compound = new btCompoundShape(); + btTransform localTrans; + localTrans.setIdentity(); + //localTrans effectively shifts the center of mass with respect to the chassis + localTrans.setOrigin(btVector3(0,0,1)); +#else + btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); + m_collisionShapes.push_back(chassisShape); + + btCompoundShape* compound = new btCompoundShape(); + m_collisionShapes.push_back(compound); + btTransform localTrans; + localTrans.setIdentity(); + //localTrans effectively shifts the center of mass with respect to the chassis + localTrans.setOrigin(btVector3(0,1,0)); +#endif + + compound->addChildShape(localTrans,chassisShape); + + { + btCollisionShape* suppShape = new btBoxShape(btVector3(0.5f,0.1f,0.5f)); + btTransform suppLocalTrans; + suppLocalTrans.setIdentity(); + //localTrans effectively shifts the center of mass with respect to the chassis + suppLocalTrans.setOrigin(btVector3(0,1.0,2.5)); + compound->addChildShape(suppLocalTrans, suppShape); + } + + tr.setOrigin(btVector3(0,0.f,0)); + + m_carChassis = localCreateRigidBody(800,tr,compound);//chassisShape); + //m_carChassis->setDamping(0.2,0.2); + + m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); + + { + btCollisionShape* liftShape = new btBoxShape(btVector3(0.5f,2.0f,0.05f)); + m_collisionShapes.push_back(liftShape); + btTransform liftTrans; + m_liftStartPos = btVector3(0.0f, 2.5f, 3.05f); + liftTrans.setIdentity(); + liftTrans.setOrigin(m_liftStartPos); + m_liftBody = localCreateRigidBody(10,liftTrans, liftShape); + + btTransform localA, localB; + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, M_PI_2, 0); + localA.setOrigin(btVector3(0.0, 1.0, 3.05)); + localB.getBasis().setEulerZYX(0, M_PI_2, 0); + localB.setOrigin(btVector3(0.0, -1.5, -0.05)); + m_liftHinge = new btHingeConstraint(*m_carChassis,*m_liftBody, localA, localB); +// m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); + m_liftHinge->setLimit(0.0f, 0.0f); + m_dynamicsWorld->addConstraint(m_liftHinge, true); + + btCollisionShape* forkShapeA = new btBoxShape(btVector3(1.0f,0.1f,0.1f)); + m_collisionShapes.push_back(forkShapeA); + btCompoundShape* forkCompound = new btCompoundShape(); + m_collisionShapes.push_back(forkCompound); + btTransform forkLocalTrans; + forkLocalTrans.setIdentity(); + forkCompound->addChildShape(forkLocalTrans, forkShapeA); + + btCollisionShape* forkShapeB = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); + m_collisionShapes.push_back(forkShapeB); + forkLocalTrans.setIdentity(); + forkLocalTrans.setOrigin(btVector3(-0.9f, -0.08f, 0.7f)); + forkCompound->addChildShape(forkLocalTrans, forkShapeB); + + btCollisionShape* forkShapeC = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); + m_collisionShapes.push_back(forkShapeC); + forkLocalTrans.setIdentity(); + forkLocalTrans.setOrigin(btVector3(0.9f, -0.08f, 0.7f)); + forkCompound->addChildShape(forkLocalTrans, forkShapeC); + + btTransform forkTrans; + m_forkStartPos = btVector3(0.0f, 0.6f, 3.2f); + forkTrans.setIdentity(); + forkTrans.setOrigin(m_forkStartPos); + m_forkBody = localCreateRigidBody(5, forkTrans, forkCompound); + + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, 0, M_PI_2); + localA.setOrigin(btVector3(0.0f, -1.9f, 0.05f)); + localB.getBasis().setEulerZYX(0, 0, M_PI_2); + localB.setOrigin(btVector3(0.0, 0.0, -0.1)); + m_forkSlider = new btSliderConstraint(*m_liftBody, *m_forkBody, localA, localB, true); + m_forkSlider->setLowerLinLimit(0.1f); + m_forkSlider->setUpperLinLimit(0.1f); +// m_forkSlider->setLowerAngLimit(-LIFT_EPS); +// m_forkSlider->setUpperAngLimit(LIFT_EPS); + m_forkSlider->setLowerAngLimit(0.0f); + m_forkSlider->setUpperAngLimit(0.0f); + m_dynamicsWorld->addConstraint(m_forkSlider, true); + + + btCompoundShape* loadCompound = new btCompoundShape(); + m_collisionShapes.push_back(loadCompound); + btCollisionShape* loadShapeA = new btBoxShape(btVector3(2.0f,0.5f,0.5f)); + m_collisionShapes.push_back(loadShapeA); + btTransform loadTrans; + loadTrans.setIdentity(); + loadCompound->addChildShape(loadTrans, loadShapeA); + btCollisionShape* loadShapeB = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); + m_collisionShapes.push_back(loadShapeB); + loadTrans.setIdentity(); + loadTrans.setOrigin(btVector3(2.1f, 0.0f, 0.0f)); + loadCompound->addChildShape(loadTrans, loadShapeB); + btCollisionShape* loadShapeC = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); + m_collisionShapes.push_back(loadShapeC); + loadTrans.setIdentity(); + loadTrans.setOrigin(btVector3(-2.1f, 0.0f, 0.0f)); + loadCompound->addChildShape(loadTrans, loadShapeC); + loadTrans.setIdentity(); + m_loadStartPos = btVector3(0.0f, -3.5f, 7.0f); + loadTrans.setOrigin(m_loadStartPos); + m_loadBody = localCreateRigidBody(4, loadTrans, loadCompound); + } + + + + clientResetScene(); + + /// create vehicle + { + + m_vehicleRayCaster = new btDefaultVehicleRaycaster(m_dynamicsWorld); + m_vehicle = new btRaycastVehicle(m_tuning,m_carChassis,m_vehicleRayCaster); + + ///never deactivate the vehicle + m_carChassis->setActivationState(DISABLE_DEACTIVATION); + + m_dynamicsWorld->addVehicle(m_vehicle); + + float connectionHeight = 1.2f; + + + bool isFrontWheel=true; + + //choose coordinate system + m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); + +#ifdef FORCE_ZAXIS_UP + btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); +#else + btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); +#endif + + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); +#ifdef FORCE_ZAXIS_UP + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); +#else + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); +#endif + + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); +#ifdef FORCE_ZAXIS_UP + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); +#else + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); +#endif //FORCE_ZAXIS_UP + isFrontWheel = false; + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); +#ifdef FORCE_ZAXIS_UP + connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); +#else + connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); +#endif + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); + + for (int i=0;igetNumWheels();i++) + { + btWheelInfo& wheel = m_vehicle->getWheelInfo(i); + wheel.m_suspensionStiffness = suspensionStiffness; + wheel.m_wheelsDampingRelaxation = suspensionDamping; + wheel.m_wheelsDampingCompression = suspensionCompression; + wheel.m_frictionSlip = wheelFriction; + wheel.m_rollInfluence = rollInfluence; + } + } + + + setCameraDistance(26.f); + +} + + +//to be implemented by the demo +void ForkLiftDemo::renderme() +{ + + updateCamera(); + + ATTRIBUTE_ALIGNED16(btScalar) m[16]; + int i; + + btVector3 wheelColor(1,0,0); + + btVector3 worldBoundsMin,worldBoundsMax; + getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); + + + + for (i=0;igetNumWheels();i++) + { + //synchronize the wheels with the (interpolated) chassis worldtransform + m_vehicle->updateWheelTransform(i,true); + //draw wheels (cylinders) + m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m); + m_shapeDrawer->drawOpenGL(m,m_wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax); + } + + + int lineWidth=250; + int xStart = m_glutScreenWidth - lineWidth; + int yStart = 20; + + if((getDebugMode() & btIDebugDraw::DBG_NoHelpText)==0) + { + setOrthographicProjection(); + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + char buf[124]; + + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"SHIFT+Cursor Left/Right - rotate lift"); + GLDebugDrawString(xStart,20,buf); + yStart+=20; + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"SHIFT+Cursor UP/Down - move fork up/down"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"F5 - toggle camera mode"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"Click inside this window for keyboard focus"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + + + resetPerspectiveProjection(); + glEnable(GL_LIGHTING); + } + DemoApplication::renderme(); +} + +void ForkLiftDemo::clientMoveAndDisplay() +{ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + { + int wheelIndex = 2; + m_vehicle->applyEngineForce(gEngineForce,wheelIndex); + m_vehicle->setBrake(gBreakingForce,wheelIndex); + wheelIndex = 3; + m_vehicle->applyEngineForce(gEngineForce,wheelIndex); + m_vehicle->setBrake(gBreakingForce,wheelIndex); + + + wheelIndex = 0; + m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex); + wheelIndex = 1; + m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex); + + } + + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_dynamicsWorld) + { + //during idle mode, just run 1 simulation step maximum + int maxSimSubSteps = m_idle ? 1 : 2; + if (m_idle) + dt = 1.0/420.f; + + int numSimSteps; + numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + + +//#define VERBOSE_FEEDBACK +#ifdef VERBOSE_FEEDBACK + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } +#endif //VERBOSE_FEEDBACK + + } + + + + + + + +#ifdef USE_QUICKPROF + btProfiler::beginBlock("render"); +#endif //USE_QUICKPROF + + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + +#ifdef USE_QUICKPROF + btProfiler::endBlock("render"); +#endif + + + glFlush(); + glutSwapBuffers(); + +} + + + +void ForkLiftDemo::displayCallback(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + +//optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + glutSwapBuffers(); +} + + + +void ForkLiftDemo::clientResetScene() +{ + gVehicleSteering = 0.f; + gBreakingForce = defaultBreakingForce; + gEngineForce = 0.f; + + m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); + m_carChassis->setLinearVelocity(btVector3(0,0,0)); + m_carChassis->setAngularVelocity(btVector3(0,0,0)); + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + if (m_vehicle) + { + m_vehicle->resetSuspension(); + for (int i=0;igetNumWheels();i++) + { + //synchronize the wheels with the (interpolated) chassis worldtransform + m_vehicle->updateWheelTransform(i,true); + } + } + btTransform liftTrans; + liftTrans.setIdentity(); + liftTrans.setOrigin(m_liftStartPos); + m_liftBody->activate(); + m_liftBody->setCenterOfMassTransform(liftTrans); + m_liftBody->setLinearVelocity(btVector3(0,0,0)); + m_liftBody->setAngularVelocity(btVector3(0,0,0)); + + btTransform forkTrans; + forkTrans.setIdentity(); + forkTrans.setOrigin(m_forkStartPos); + m_forkBody->activate(); + m_forkBody->setCenterOfMassTransform(forkTrans); + m_forkBody->setLinearVelocity(btVector3(0,0,0)); + m_forkBody->setAngularVelocity(btVector3(0,0,0)); + +// m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); + m_liftHinge->setLimit(0.0f, 0.0f); + m_liftHinge->enableAngularMotor(false, 0, 0); + + + m_forkSlider->setLowerLinLimit(0.1f); + m_forkSlider->setUpperLinLimit(0.1f); + m_forkSlider->setPoweredLinMotor(false); + + btTransform loadTrans; + loadTrans.setIdentity(); + loadTrans.setOrigin(m_loadStartPos); + m_loadBody->activate(); + m_loadBody->setCenterOfMassTransform(loadTrans); + m_loadBody->setLinearVelocity(btVector3(0,0,0)); + m_loadBody->setAngularVelocity(btVector3(0,0,0)); + +} + + + +void ForkLiftDemo::specialKeyboardUp(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP : + { + lockForkSlider(); + gEngineForce = 0.f; + gBreakingForce = defaultBreakingForce; + break; + } + case GLUT_KEY_DOWN : + { + lockForkSlider(); + gEngineForce = 0.f; + gBreakingForce = defaultBreakingForce; + break; + } + case GLUT_KEY_LEFT: + case GLUT_KEY_RIGHT: + { + lockLiftHinge(); + break; + } + default: + DemoApplication::specialKeyboardUp(key,x,y); + break; + } +} + + +void ForkLiftDemo::specialKeyboard(int key, int x, int y) +{ + + if (key==GLUT_KEY_END) + return; + + // printf("key = %i x=%i y=%i\n",key,x,y); + + int state; + state=glutGetModifiers(); + if (state & GLUT_ACTIVE_SHIFT) + { + switch (key) + { + case GLUT_KEY_LEFT : + { + + m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); + m_liftHinge->enableAngularMotor(true, -0.1, 10.0); + break; + } + case GLUT_KEY_RIGHT : + { + + m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); + m_liftHinge->enableAngularMotor(true, 0.1, 10.0); + break; + } + case GLUT_KEY_UP : + { + m_forkSlider->setLowerLinLimit(0.1f); + m_forkSlider->setUpperLinLimit(3.9f); + m_forkSlider->setPoweredLinMotor(true); + m_forkSlider->setMaxLinMotorForce(10.0); + m_forkSlider->setTargetLinMotorVelocity(1.0); + break; + } + case GLUT_KEY_DOWN : + { + m_forkSlider->setLowerLinLimit(0.1f); + m_forkSlider->setUpperLinLimit(3.9f); + m_forkSlider->setPoweredLinMotor(true); + m_forkSlider->setMaxLinMotorForce(10.0); + m_forkSlider->setTargetLinMotorVelocity(-1.0); + break; + } + + default: + DemoApplication::specialKeyboard(key,x,y); + break; + } + + } else + { + switch (key) + { + case GLUT_KEY_LEFT : + { + gVehicleSteering += steeringIncrement; + if ( gVehicleSteering > steeringClamp) + gVehicleSteering = steeringClamp; + + break; + } + case GLUT_KEY_RIGHT : + { + gVehicleSteering -= steeringIncrement; + if ( gVehicleSteering < -steeringClamp) + gVehicleSteering = -steeringClamp; + + break; + } + case GLUT_KEY_UP : + { + gEngineForce = maxEngineForce; + gBreakingForce = 0.f; + break; + } + case GLUT_KEY_DOWN : + { + gEngineForce = -maxEngineForce; + gBreakingForce = 0.f; + break; + } + + case GLUT_KEY_F5: + m_useDefaultCamera = !m_useDefaultCamera; + break; + default: + DemoApplication::specialKeyboard(key,x,y); + break; + } + + } + // glutPostRedisplay(); + + +} + +void ForkLiftDemo::updateCamera() +{ + +//#define DISABLE_CAMERA 1 + if(m_useDefaultCamera) + { + DemoApplication::updateCamera(); + return; + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + btTransform chassisWorldTrans; + + //look at the vehicle + m_carChassis->getMotionState()->getWorldTransform(chassisWorldTrans); + m_cameraTargetPosition = chassisWorldTrans.getOrigin(); + + //interpolate the camera height +#ifdef FORCE_ZAXIS_UP + m_cameraPosition[2] = (15.0*m_cameraPosition[2] + m_cameraTargetPosition[2] + m_cameraHeight)/16.0; +#else + m_cameraPosition[1] = (15.0*m_cameraPosition[1] + m_cameraTargetPosition[1] + m_cameraHeight)/16.0; +#endif + + btVector3 camToObject = m_cameraTargetPosition - m_cameraPosition; + + //keep distance between min and max distance + float cameraDistance = camToObject.length(); + float correctionFactor = 0.f; + if (cameraDistance < m_minCameraDistance) + { + correctionFactor = 0.15*(m_minCameraDistance-cameraDistance)/cameraDistance; + } + if (cameraDistance > m_maxCameraDistance) + { + correctionFactor = 0.15*(m_maxCameraDistance-cameraDistance)/cameraDistance; + } + m_cameraPosition -= correctionFactor*camToObject; + + //update OpenGL camera settings + btScalar aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; + glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + gluLookAt(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2], + m_cameraTargetPosition[0],m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + + + +} + +void ForkLiftDemo::lockLiftHinge(void) +{ + btScalar hingeAngle = m_liftHinge->getHingeAngle(); + btScalar lowLim = m_liftHinge->getLowerLimit(); + btScalar hiLim = m_liftHinge->getUpperLimit(); + m_liftHinge->enableAngularMotor(false, 0, 0); + if(hingeAngle < lowLim) + { +// m_liftHinge->setLimit(lowLim, lowLim + LIFT_EPS); + m_liftHinge->setLimit(lowLim, lowLim); + } + else if(hingeAngle > hiLim) + { +// m_liftHinge->setLimit(hiLim - LIFT_EPS, hiLim); + m_liftHinge->setLimit(hiLim, hiLim); + } + else + { +// m_liftHinge->setLimit(hingeAngle - LIFT_EPS, hingeAngle + LIFT_EPS); + m_liftHinge->setLimit(hingeAngle, hingeAngle); + } + return; +} // ForkLiftDemo::lockLiftHinge() + +void ForkLiftDemo::lockForkSlider(void) +{ + btScalar linDepth = m_forkSlider->getLinearPos(); + btScalar lowLim = m_forkSlider->getLowerLinLimit(); + btScalar hiLim = m_forkSlider->getUpperLinLimit(); + m_forkSlider->setPoweredLinMotor(false); + if(linDepth <= lowLim) + { + m_forkSlider->setLowerLinLimit(lowLim); + m_forkSlider->setUpperLinLimit(lowLim); + } + else if(linDepth > hiLim) + { + m_forkSlider->setLowerLinLimit(hiLim); + m_forkSlider->setUpperLinLimit(hiLim); + } + else + { + m_forkSlider->setLowerLinLimit(linDepth); + m_forkSlider->setUpperLinLimit(linDepth); + } + return; +} // ForkLiftDemo::lockForkSlider() diff --git a/Demos/ForkLiftDemo/ForkLiftDemo.h b/Demos/ForkLiftDemo/ForkLiftDemo.h new file mode 100644 index 0000000..6d0c825 --- /dev/null +++ b/Demos/ForkLiftDemo/ForkLiftDemo.h @@ -0,0 +1,113 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef FORKLIFT_DEMO_H +#define FORKLIFT_DEMO_H + +class btVehicleTuning; +struct btVehicleRaycaster; +class btCollisionShape; + +#include "BulletDynamics/Vehicle/btRaycastVehicle.h" +#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" +#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" + +#include "GlutDemoApplication.h" + +///VehicleDemo shows how to setup and use the built-in raycast vehicle +class ForkLiftDemo : public GlutDemoApplication +{ + public: + + btRigidBody* m_carChassis; + +//---------------------------- + btRigidBody* m_liftBody; + btVector3 m_liftStartPos; + btHingeConstraint* m_liftHinge; + + btRigidBody* m_forkBody; + btVector3 m_forkStartPos; + btSliderConstraint* m_forkSlider; + + btRigidBody* m_loadBody; + btVector3 m_loadStartPos; + + void lockLiftHinge(void); + void lockForkSlider(void); + + bool m_useDefaultCamera; +//---------------------------- + + + btAlignedObjectArray m_collisionShapes; + + class btBroadphaseInterface* m_overlappingPairCache; + + class btCollisionDispatcher* m_dispatcher; + + class btConstraintSolver* m_constraintSolver; + + class btDefaultCollisionConfiguration* m_collisionConfiguration; + + class btTriangleIndexVertexArray* m_indexVertexArrays; + + btVector3* m_vertices; + + + btRaycastVehicle::btVehicleTuning m_tuning; + btVehicleRaycaster* m_vehicleRayCaster; + btRaycastVehicle* m_vehicle; + btCollisionShape* m_wheelShape; + + float m_cameraHeight; + + float m_minCameraDistance; + float m_maxCameraDistance; + + + ForkLiftDemo(); + + virtual ~ForkLiftDemo(); + + virtual void clientMoveAndDisplay(); + + virtual void clientResetScene(); + + virtual void displayCallback(); + + ///a very basic camera following the vehicle + virtual void updateCamera(); + + virtual void specialKeyboard(int key, int x, int y); + + virtual void specialKeyboardUp(int key, int x, int y); + + void renderme(); + + void initPhysics(); + void termPhysics(); + + static DemoApplication* Create() + { + ForkLiftDemo* demo = new ForkLiftDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +#endif // FORKLIFT_DEMO_H + + diff --git a/Demos/ForkLiftDemo/main.cpp b/Demos/ForkLiftDemo/main.cpp new file mode 100644 index 0000000..42b8b06 --- /dev/null +++ b/Demos/ForkLiftDemo/main.cpp @@ -0,0 +1,18 @@ + +#include "ForkLiftDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + ForkLiftDemo* pForkLiftDemo = new ForkLiftDemo; + + pForkLiftDemo->initPhysics(); + pForkLiftDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + return glutmain(argc, argv,1024,768,"Bullet ForkLift Demo. http://www.continuousphysics.com/Bullet/phpBB2/", pForkLiftDemo); +} + diff --git a/Demos/FractureDemo/CMakeLists.txt b/Demos/FractureDemo/CMakeLists.txt new file mode 100644 index 0000000..1f7900b --- /dev/null +++ b/Demos/FractureDemo/CMakeLists.txt @@ -0,0 +1,96 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + +IF (WIN32) +ADD_EXECUTABLE(AppFractureDemo + main.cpp + FractureDemo.cpp + FractureDemo.h + btFractureBody.h + btFractureBody.cpp + btFractureDynamicsWorld.cpp + btFractureDynamicsWorld.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppFractureDemo + main.cpp + FractureDemo.cpp + FractureDemo.h + btFractureBody.h + btFractureBody.cpp + btFractureDynamicsWorld.cpp + btFractureDynamicsWorld.h + ) +ENDIF() + + + + + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppFractureDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppFractureDemo + POST_BUILD +# COMMAND copy /Y ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}/Debug + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + ENDIF(WIN32) +ELSE (USE_GLUT) + + + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + + ADD_EXECUTABLE(AppFractureDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32FractureDemo.cpp + FractureDemo.cpp + FractureDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + + +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppFractureDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppFractureDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppFractureDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/FractureDemo/FractureDemo.cpp b/Demos/FractureDemo/FractureDemo.cpp new file mode 100644 index 0000000..16b7396 --- /dev/null +++ b/Demos/FractureDemo/FractureDemo.cpp @@ -0,0 +1,362 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2011 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +///FractureDemo shows how to break objects. +///It assumes a btCompoundShaps (where the childshapes are the pre-fractured pieces) +///The btFractureBody is a class derived from btRigidBody, dealing with the collision impacts. +///Press the F key to toggle between fracture and glue mode +///This is preliminary work + + +#define CUBE_HALF_EXTENTS 1.f +#define EXTRA_HEIGHT 1.f +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "FractureDemo.h" +#include "GlutStuff.h" +#include "GLDebugFont.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" + + +#include //printf debugging + + +int sFrameNumber = 0; + +#include "btFractureBody.h" +#include "btFractureDynamicsWorld.h" + + + + + +void FractureDemo::initPhysics() +{ + + setTexturing(true); + setShadows(true); + + setDebugMode(btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_NoHelpText); + + setCameraDistance(btScalar(SCALING*20.)); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + //m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + + btFractureDynamicsWorld* fractureWorld = new btFractureDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = fractureWorld; + + m_ShootBoxInitialSpeed=100; + + //m_splitImpulse removes the penetration resolution from the applied impulse, otherwise objects might fracture due to deep penetrations. + m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; + + { + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(50,1,50)); + /// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,0,0)); + localCreateRigidBody(0.f,groundTransform,groundShape); + } + + { + ///create a few basic rigid bodies + btCollisionShape* shape = new btBoxShape(btVector3(1,1,1)); + m_collisionShapes.push_back(shape); + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(5,2,0)); + localCreateRigidBody(0.f,tr,shape); + } + + + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); + //btCollisionShape* colShape = new btCapsuleShape(SCALING*0.4,SCALING*1); + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(colShape); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); + + + int gNumObjects = 10; + + for (int i=0;isetLinearVelocity(btVector3(0,-10,0)); + + m_dynamicsWorld->addRigidBody(body); + + + } + + } + + + + fractureWorld->stepSimulation(1./60.,0); + fractureWorld->glueCallback(); + + + +} + +void FractureDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} + + +void FractureDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + + + renderme(); + + showMessage(); + + glFlush(); + + swapBuffers(); + +} + +void FractureDemo::showMessage() +{ + if((getDebugMode() & btIDebugDraw::DBG_DrawText)) + { + setOrthographicProjection(); + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + char buf[124]; + + int lineWidth=380; + int xStart = m_glutScreenWidth - lineWidth; + int yStart = 20; + + btFractureDynamicsWorld* world = (btFractureDynamicsWorld*)m_dynamicsWorld; + if (world->getFractureMode()) + { + sprintf(buf,"Fracture mode"); + } else + { + sprintf(buf,"Glue mode"); + } + GLDebugDrawString(xStart,yStart,buf); + sprintf(buf,"f to toggle fracture/glue mode"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + sprintf(buf,"space to restart, mouse to pick/shoot"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + + resetPerspectiveProjection(); + glEnable(GL_LIGHTING); + } + +} + + +void FractureDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + showMessage(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + + +void FractureDemo::keyboardUpCallback(unsigned char key, int x, int y) +{ + if (key=='f') + { + btFractureDynamicsWorld* world = (btFractureDynamicsWorld*)m_dynamicsWorld; + world->setFractureMode(!world->getFractureMode()); + } + + PlatformDemoApplication::keyboardUpCallback(key,x,y); + +} + + +void FractureDemo::shootBox(const btVector3& destination) +{ + + if (m_dynamicsWorld) + { + btScalar mass = 1.f; + btTransform startTransform; + startTransform.setIdentity(); + btVector3 camPos = getCameraPosition(); + startTransform.setOrigin(camPos); + + setShootBoxShape (); + + btAssert((!m_shootBoxShape || m_shootBoxShape->getShapeType() != INVALID_SHAPE_PROXYTYPE)); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + m_shootBoxShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + + btFractureBody* body = new btFractureBody(mass,0,m_shootBoxShape,localInertia,&mass,1,m_dynamicsWorld); + + body->setWorldTransform(startTransform); + + m_dynamicsWorld->addRigidBody(body); + + + body->setLinearFactor(btVector3(1,1,1)); + //body->setRestitution(1); + + btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed; + + body->getWorldTransform().setOrigin(camPos); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + body->setCcdMotionThreshold(1.); + body->setCcdSweptSphereRadius(0.2f); + + } +} + + + + + + +void FractureDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + void showMessage(); + + public: + + FractureDemo() + { + } + virtual ~FractureDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void keyboardUpCallback(unsigned char key, int x, int y); + + virtual void clientResetScene(); + + static DemoApplication* Create() + { + FractureDemo* demo = new FractureDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + void shootBox(const btVector3& destination); + +}; + +#endif //FRACTURE_DEMO_H + diff --git a/Demos/FractureDemo/Win32FractureDemo.cpp b/Demos/FractureDemo/Win32FractureDemo.cpp new file mode 100644 index 0000000..c7b363b --- /dev/null +++ b/Demos/FractureDemo/Win32FractureDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2011 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "FractureDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new FractureDemo(); +} + +#endif diff --git a/Demos/FractureDemo/btFractureBody.cpp b/Demos/FractureDemo/btFractureBody.cpp new file mode 100644 index 0000000..aa46c2b --- /dev/null +++ b/Demos/FractureDemo/btFractureBody.cpp @@ -0,0 +1,139 @@ + +#include "btFractureBody.h" +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletDynamics/Dynamics/btDynamicsWorld.h" + + + +void btFractureBody::recomputeConnectivity(btCollisionWorld* world) +{ + m_connections.clear(); + //@todo use the AABB tree to avoid N^2 checks + + if (getCollisionShape()->isCompound()) + { + btCompoundShape* compound = (btCompoundShape*)getCollisionShape(); + for (int i=0;igetNumChildShapes();i++) + { + for (int j=i+1;jgetNumChildShapes();j++) + { + + struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback + { + bool m_connected; + btScalar m_margin; + MyContactResultCallback() :m_connected(false),m_margin(0.05) + { + } + virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) + { + if (cp.getDistance()<=m_margin) + m_connected = true; + return 1.f; + } + }; + + MyContactResultCallback result; + + btCollisionObject obA; + obA.setWorldTransform(compound->getChildTransform(i)); + obA.setCollisionShape(compound->getChildShape(i)); + btCollisionObject obB; + obB.setWorldTransform(compound->getChildTransform(j)); + obB.setCollisionShape(compound->getChildShape(j)); + world->contactPairTest(&obA,&obB,result); + if (result.m_connected) + { + btConnection tmp; + tmp.m_childIndex0 = i; + tmp.m_childIndex1 = j; + tmp.m_childShape0 = compound->getChildShape(i); + tmp.m_childShape1 = compound->getChildShape(j); + tmp.m_strength = 1.f;//?? + m_connections.push_back(tmp); + } + } + } + } + + +} + +btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound,btScalar mass,btTransform& shift) +{ + + btVector3 principalInertia; + + btScalar* masses = new btScalar[boxCompound->getNumChildShapes()]; + for (int j=0;jgetNumChildShapes();j++) + { + //evenly distribute mass + masses[j]=mass/boxCompound->getNumChildShapes(); + } + + return shiftTransform(boxCompound,masses,shift,principalInertia); + +} + + +btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btScalar* masses,btTransform& shift, btVector3& principalInertia) +{ + btTransform principal; + + boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia); + + + ///create a new compound with world transform/center of mass properly aligned with the principal axis + + ///non-recursive compound shapes perform better + +#ifdef USE_RECURSIVE_COMPOUND + + btCompoundShape* newCompound = new btCompoundShape(); + newCompound->addChildShape(principal.inverse(),boxCompound); + newBoxCompound = newCompound; + //m_collisionShapes.push_back(newCompound); + + //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + //btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia); + +#else +#ifdef CHANGE_COMPOUND_INPLACE + newBoxCompound = boxCompound; + for (int i=0;igetNumChildShapes();i++) + { + btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i); + ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update + boxCompound->updateChildTransform(i,newChildTransform); + } + bool isDynamic = (mass != 0.f); + btVector3 localInertia(0,0,0); + if (isDynamic) + boxCompound->calculateLocalInertia(mass,localInertia); + +#else + ///creation is faster using a new compound to store the shifted children + btCompoundShape* newBoxCompound = new btCompoundShape(); + for (int i=0;igetNumChildShapes();i++) + { + btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i); + ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update + newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i)); + } + + + +#endif + +#endif//USE_RECURSIVE_COMPOUND + + shift = principal; + return newBoxCompound; +} + + + + + + diff --git a/Demos/FractureDemo/btFractureBody.h b/Demos/FractureDemo/btFractureBody.h new file mode 100644 index 0000000..a21d992 --- /dev/null +++ b/Demos/FractureDemo/btFractureBody.h @@ -0,0 +1,78 @@ + +#ifndef BT_FRACTURE_BODY +#define BT_FRACTURE_BODY + +class btCollisionShape; +class btDynamicsWorld; +class btCollisionWorld; +class btCompoundShape; +class btManifoldPoint; + +#include "LinearMath/btAlignedObjectArray.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + +#define CUSTOM_FRACTURE_TYPE (btRigidBody::CO_USER_TYPE+1) + + +struct btConnection +{ + + btCollisionShape* m_childShape0; + btCollisionShape* m_childShape1; + int m_childIndex0; + int m_childIndex1; + btScalar m_strength; +}; + +class btFractureBody : public btRigidBody +{ + //connections +public: + + btDynamicsWorld* m_world; + btAlignedObjectArray m_masses; + btAlignedObjectArray m_connections; + + + + btFractureBody( const btRigidBodyConstructionInfo& constructionInfo, btDynamicsWorld* world) + :btRigidBody(constructionInfo), + m_world(world) + { + m_masses.push_back(constructionInfo.m_mass); + m_internalType=CUSTOM_FRACTURE_TYPE+CO_RIGID_BODY; + } + + + + ///btRigidBody constructor for backwards compatibility. + ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo) + btFractureBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia, btScalar* masses, int numMasses, btDynamicsWorld* world) + :btRigidBody(mass,motionState,collisionShape,localInertia), + m_world(world) + { + + for (int i=0;igetNumManifolds(); + + ///first build the islands based on axis aligned bounding box overlap + + btUnionFind unionFind; + + int index = 0; + { + + int i; + for (i=0;iisStaticOrKinematicObject()) + { + collisionObject->setIslandTag(index++); + } else + { + collisionObject->setIslandTag(-1); + } +#else + collisionObject->setIslandTag(i); + index=i+1; +#endif + } + } + + unionFind.reset(index); + + int numElem = unionFind.getNumElements(); + + for (int i=0;igetManifoldByIndexInternal(i); + if (!manifold->getNumContacts()) + continue; + + btScalar minDist = 1e30f; + for (int v=0;vgetNumContacts();v++) + { + minDist = btMin(minDist,manifold->getContactPoint(v).getDistance()); + } + if (minDist>0.) + continue; + + btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); + btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); + int tag0 = (colObj0)->getIslandTag(); + int tag1 = (colObj1)->getIslandTag(); + //btRigidBody* body0 = btRigidBody::upcast(colObj0); + //btRigidBody* body1 = btRigidBody::upcast(colObj1); + + + if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject()) + { + unionFind.unite(tag0, tag1); + } + } + + + + + numElem = unionFind.getNumElements(); + + + + index=0; + for (int ai=0;aiisStaticOrKinematicObject()) + { + int tag = unionFind.find(index); + + collisionObject->setIslandTag( tag); + + //Set the correct object offset in Collision Object Array +#if STATIC_SIMULATION_ISLAND_OPTIMIZATION + unionFind.getElement(index).m_sz = ai; +#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION + + index++; + } + } + unionFind.sortIslands(); + + + + int endIslandIndex=1; + int startIslandIndex; + + btAlignedObjectArray removedObjects; + + ///iterate over all islands + for ( startIslandIndex=0;startIslandIndexgetInternalType()& CUSTOM_FRACTURE_TYPE) + { + fractureObjectIndex = i; + } + btRigidBody* otherObject = btRigidBody::upcast(colObj0); + if (!otherObject || !otherObject->getInvMass()) + continue; + numObjects++; + } + + ///Then for each island that contains at least two objects and one fracture object + if (fractureObjectIndex>=0 && numObjects>1) + { + + btFractureBody* fracObj = (btFractureBody*)getCollisionObjectArray()[fractureObjectIndex]; + + ///glueing objects means creating a new compound and removing the old objects + ///delay the removal of old objects to avoid array indexing problems + removedObjects.push_back(fracObj); + m_fractureBodies.remove(fracObj); + + btAlignedObjectArray massArray; + + btAlignedObjectArray oldImpulses; + btAlignedObjectArray oldCenterOfMassesWS; + + oldImpulses.push_back(fracObj->getLinearVelocity()/1./fracObj->getInvMass()); + oldCenterOfMassesWS.push_back(fracObj->getCenterOfMassPosition()); + + btScalar totalMass = 0.f; + + + btCompoundShape* compound = new btCompoundShape(); + if (fracObj->getCollisionShape()->isCompound()) + { + btTransform tr; + tr.setIdentity(); + btCompoundShape* oldCompound = (btCompoundShape*)fracObj->getCollisionShape(); + for (int c=0;cgetNumChildShapes();c++) + { + compound->addChildShape(oldCompound->getChildTransform(c),oldCompound->getChildShape(c)); + massArray.push_back(fracObj->m_masses[c]); + totalMass+=fracObj->m_masses[c]; + } + + } else + { + btTransform tr; + tr.setIdentity(); + compound->addChildShape(tr,fracObj->getCollisionShape()); + massArray.push_back(fracObj->m_masses[0]); + totalMass+=fracObj->m_masses[0]; + } + + for (idx=startIslandIndex;idxgetInvMass()) + continue; + + + oldImpulses.push_back(otherObject->getLinearVelocity()*(1.f/otherObject->getInvMass())); + oldCenterOfMassesWS.push_back(otherObject->getCenterOfMassPosition()); + + removedObjects.push_back(otherObject); + m_fractureBodies.remove((btFractureBody*)otherObject); + + btScalar curMass = 1.f/otherObject->getInvMass(); + + + if (otherObject->getCollisionShape()->isCompound()) + { + btTransform tr; + btCompoundShape* oldCompound = (btCompoundShape*)otherObject->getCollisionShape(); + for (int c=0;cgetNumChildShapes();c++) + { + tr = fracObj->getWorldTransform().inverseTimes(otherObject->getWorldTransform()*oldCompound->getChildTransform(c)); + compound->addChildShape(tr,oldCompound->getChildShape(c)); + massArray.push_back(curMass/(btScalar)oldCompound->getNumChildShapes()); + + } + } else + { + btTransform tr; + tr = fracObj->getWorldTransform().inverseTimes(otherObject->getWorldTransform()); + compound->addChildShape(tr,otherObject->getCollisionShape()); + massArray.push_back(curMass); + } + totalMass+=curMass; + } + + + + btTransform shift; + shift.setIdentity(); + btCompoundShape* newCompound = btFractureBody::shiftTransformDistributeMass(compound,totalMass,shift); + int numChildren = newCompound->getNumChildShapes(); + btAssert(numChildren == massArray.size()); + + btVector3 localInertia; + newCompound->calculateLocalInertia(totalMass,localInertia); + btFractureBody* newBody = new btFractureBody(totalMass,0,newCompound,localInertia, &massArray[0], numChildren,this); + newBody->recomputeConnectivity(this); + newBody->setWorldTransform(fracObj->getWorldTransform()*shift); + + //now the linear/angular velocity is still zero, apply the impulses + + for (int i=0;igetCenterOfMassPosition(); + const btVector3& imp = oldImpulses[i]; + newBody->applyImpulse(imp, rel_pos); + } + + addRigidBody(newBody); + + + } + + + } + + //remove the objects from the world at the very end, + //otherwise the island tags would not match the world collision object array indices anymore + while (removedObjects.size()) + { + btCollisionObject* otherCollider = removedObjects[removedObjects.size()-1]; + removedObjects.pop_back(); + + btRigidBody* otherObject = btRigidBody::upcast(otherCollider); + if (!otherObject || !otherObject->getInvMass()) + continue; + removeRigidBody(otherObject); + } + +} + + +struct btFracturePair +{ + btFractureBody* m_fracObj; + btAlignedObjectArray m_contactManifolds; +}; + + + +void btFractureDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) +{ + // todo: after fracture we should run the solver again for better realism + // for example + // save all velocities and if one or more objects fracture: + // 1) revert all velocties + // 2) apply impulses for the fracture bodies at the contact locations + // 3)and run the constaint solver again + + btDiscreteDynamicsWorld::solveConstraints(solverInfo); + + fractureCallback(); +} + +btFractureBody* btFractureDynamicsWorld::addNewBody(const btTransform& oldTransform,btScalar* masses, btCompoundShape* oldCompound) +{ + int i; + + btTransform shift; + shift.setIdentity(); + btVector3 localInertia; + btCompoundShape* newCompound = btFractureBody::shiftTransform(oldCompound,masses,shift,localInertia); + btScalar totalMass = 0; + for (i=0;igetNumChildShapes();i++) + totalMass += masses[i]; + //newCompound->calculateLocalInertia(totalMass,localInertia); + + btFractureBody* newBody = new btFractureBody(totalMass,0,newCompound,localInertia, masses,newCompound->getNumChildShapes(), this); + newBody->recomputeConnectivity(this); + + newBody->setCollisionFlags(newBody->getCollisionFlags()|btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + newBody->setWorldTransform(oldTransform*shift); + addRigidBody(newBody); + return newBody; +} + +void btFractureDynamicsWorld::addRigidBody(btRigidBody* body) +{ + if (body->getInternalType() & CUSTOM_FRACTURE_TYPE) + { + btFractureBody* fbody = (btFractureBody*)body; + m_fractureBodies.push_back(fbody); + } + btDiscreteDynamicsWorld::addRigidBody(body); +} + +void btFractureDynamicsWorld::removeRigidBody(btRigidBody* body) +{ + if (body->getInternalType() & CUSTOM_FRACTURE_TYPE) + { + btFractureBody* fbody = (btFractureBody*)body; + btAlignedObjectArray tmpConstraints; + + for (int i=0;igetNumConstraintRefs();i++) + { + tmpConstraints.push_back(fbody->getConstraintRef(i)); + } + + //remove all constraints attached to this rigid body too + for (int i=0;igetCollisionShape()->isCompound()) + return; + + btCompoundShape* compound = (btCompoundShape*)fracObj->getCollisionShape(); + int numChildren = compound->getNumChildShapes(); + + if (numChildren<=1) + return; + + //compute connectivity + btUnionFind unionFind; + + btAlignedObjectArray tags; + tags.resize(numChildren); + int i, index = 0; + for ( i=0;im_connections.size();i++) + { + btConnection& connection = fracObj->m_connections[i]; + if (connection.m_strength > 0.) + { + int tag0 = tags[connection.m_childIndex0]; + int tag1 = tags[connection.m_childIndex1]; + unionFind.unite(tag0, tag1); + } + } + numElem = unionFind.getNumElements(); + + index=0; + for (int ai=0;ai removedObjects; + + int numIslands = 0; + + for ( startIslandIndex=0;startIslandIndex masses; + + int idx; + for (idx=startIslandIndex;idxgetChildShape(i); + newCompound->addChildShape(compound->getChildTransform(i),compound->getChildShape(i)); + masses.push_back(fracObj->m_masses[i]); + numShapes++; + } + if (numShapes) + { + btFractureBody* newBody = addNewBody(fracObj->getWorldTransform(),&masses[0],newCompound); + newBody->setLinearVelocity(fracObj->getLinearVelocity()); + newBody->setAngularVelocity(fracObj->getAngularVelocity()); + + numIslands++; + } + } + + + + + + removeRigidBody(fracObj);//should it also be removed from the array? + + +} + +#include + + +void btFractureDynamicsWorld::fractureCallback( ) +{ + + btAlignedObjectArray sFracturePairs; + + if (!m_fracturingMode) + { + glueCallback(); + return; + } + + int numManifolds = getDispatcher()->getNumManifolds(); + + sFracturePairs.clear(); + + + for (int i=0;igetManifoldByIndexInternal(i); + if (!manifold->getNumContacts()) + continue; + + btScalar totalImpact = 0.f; + for (int p=0;pgetNumContacts();p++) + { + totalImpact += manifold->getContactPoint(p).m_appliedImpulse; + } + + +// printf("totalImpact=%f\n",totalImpact); + + static float maxImpact = 0; + if (totalImpact>maxImpact) + maxImpact = totalImpact; + + //some threshold otherwise resting contact would break objects after a while + if (totalImpact < 40.f) + continue; + + // printf("strong impact\n"); + + + //@todo: add better logic to decide what parts to fracture + //For example use the idea from the SIGGRAPH talk about the fracture in the movie 2012: + // + //Breaking thresholds can be stored as connectivity information between child shapes in the fracture object + // + //You can calculate some "impact value" by simulating all the individual child shapes + //as rigid bodies, without constraints, running it in a separate simulation world + //(or by running the constraint solver without actually modifying the dynamics world) + //Then measure some "impact value" using the offset and applied impulse for each child shape + //weaken the connections based on this "impact value" and only break + //if this impact value exceeds the breaking threshold. + //you can propagate the weakening and breaking of connections using the connectivity information + + int f0 = m_fractureBodies.findLinearSearch((btFractureBody*)manifold->getBody0()); + int f1 = m_fractureBodies.findLinearSearch((btFractureBody*)manifold->getBody1()); + + if (f0 == f1 == m_fractureBodies.size()) + continue; + + + if (f0getBody1(); + // btRigidBody* otherOb = btRigidBody::upcast(colOb); + // if (!otherOb->getInvMass()) + // continue; + + int pi=-1; + + for (int p=0;pgetBody0(); + btRigidBody* otherOb = btRigidBody::upcast(colOb); + // if (!otherOb->getInvMass()) + // continue; + + + int pi=-1; + + for (int p=0;pgetCollisionShape()->isCompound()) + { + btTransform tr; + tr.setIdentity(); + btCompoundShape* oldCompound = (btCompoundShape*)sFracturePairs[i].m_fracObj->getCollisionShape(); + if (oldCompound->getNumChildShapes()>1) + { + bool needsBreakingCheck = false; + + + //weaken/break the connections + + //@todo: propagate along the connection graph + for (int j=0;jgetNumContacts();k++) + { + btManifoldPoint& pt = manifold->getContactPoint(k); + if (manifold->getBody0()==sFracturePairs[i].m_fracObj) + { + for (int f=0;fm_connections.size();f++) + { + btConnection& connection = sFracturePairs[i].m_fracObj->m_connections[f]; + if ( (connection.m_childIndex0 == pt.m_index0) || + (connection.m_childIndex1 == pt.m_index0) + ) + { + connection.m_strength -= pt.m_appliedImpulse; + if (connection.m_strength<0) + { + //remove or set to zero + connection.m_strength=0.f; + needsBreakingCheck = true; + } + } + } + } else + { + for (int f=0;fm_connections.size();f++) + { + btConnection& connection = sFracturePairs[i].m_fracObj->m_connections[f]; + if ( (connection.m_childIndex0 == pt.m_index1) || + (connection.m_childIndex1 == pt.m_index1) + ) + { + connection.m_strength -= pt.m_appliedImpulse; + if (connection.m_strength<0) + { + //remove or set to zero + connection.m_strength=0.f; + needsBreakingCheck = true; + } + } + } + } + } + } + + if (needsBreakingCheck) + { + breakDisconnectedParts(sFracturePairs[i].m_fracObj); + } + } + + } + + } + } + + sFracturePairs.clear(); + +} + diff --git a/Demos/FractureDemo/btFractureDynamicsWorld.h b/Demos/FractureDemo/btFractureDynamicsWorld.h new file mode 100644 index 0000000..ad7e821 --- /dev/null +++ b/Demos/FractureDemo/btFractureDynamicsWorld.h @@ -0,0 +1,51 @@ +#ifndef _BT_FRACTURE_DYNAMICS_WORLD_H +#define _BT_FRACTURE_DYNAMICS_WORLD_H + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "LinearMath/btAlignedObjectArray.h" + +class btFractureBody; +class btCompoundShape; +class btTransform; + + +///The btFractureDynamicsWorld class enabled basic glue and fracture of objects. +///If/once this implementation is stablized/tested we might merge it into btDiscreteDynamicsWorld and remove the class. +class btFractureDynamicsWorld : public btDiscreteDynamicsWorld +{ + btAlignedObjectArray m_fractureBodies; + + bool m_fracturingMode; + + btFractureBody* addNewBody(const btTransform& oldTransform,btScalar* masses, btCompoundShape* oldCompound); + + void breakDisconnectedParts( btFractureBody* fracObj); + +public: + + btFractureDynamicsWorld ( btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + + virtual void addRigidBody(btRigidBody* body); + + virtual void removeRigidBody(btRigidBody* body); + + void solveConstraints(btContactSolverInfo& solverInfo); + + ///either fracture or glue (!fracture) + void setFractureMode(bool fracture) + { + m_fracturingMode = fracture; + } + + bool getFractureMode() const { return m_fracturingMode;} + + ///normally those callbacks are called internally by the 'solveConstraints' + void glueCallback(); + + ///normally those callbacks are called internally by the 'solveConstraints' + void fractureCallback(); + +}; + +#endif //_BT_FRACTURE_DYNAMICS_WORLD_H + diff --git a/Demos/FractureDemo/main.cpp b/Demos/FractureDemo/main.cpp new file mode 100644 index 0000000..7486bc5 --- /dev/null +++ b/Demos/FractureDemo/main.cpp @@ -0,0 +1,42 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "FractureDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + + +int main(int argc,char** argv) +{ + GLDebugDrawer gDebugDrawer; + + + FractureDemo ccdDemo; + ccdDemo.initPhysics(); + ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/GenericJointDemo/CMakeLists.txt b/Demos/GenericJointDemo/CMakeLists.txt new file mode 100644 index 0000000..d664fab --- /dev/null +++ b/Demos/GenericJointDemo/CMakeLists.txt @@ -0,0 +1,82 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + +IF (USE_GLUT) + + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppGenericJointDemo + GenericJointDemo.cpp + GenericJointDemo.h + Ragdoll.cpp + main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppGenericJointDemo + GenericJointDemo.cpp + GenericJointDemo.h + Ragdoll.cpp + main.cpp + ) + ENDIF() + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppGenericJointDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppGenericJointDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) + +ELSE(USE_GLUT) + + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppGenericJointDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32GenericJointDemo.cpp + GenericJointDemo.cpp + GenericJointDemo.h + Ragdoll.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + + ) +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppGenericJointDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppGenericJointDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppGenericJointDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/GenericJointDemo/GenericJointDemo.cpp b/Demos/GenericJointDemo/GenericJointDemo.cpp new file mode 100644 index 0000000..35e24c1 --- /dev/null +++ b/Demos/GenericJointDemo/GenericJointDemo.cpp @@ -0,0 +1,135 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Ragdoll Demo +Copyright (c) 2007 Starbreeze Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Originally Written by: Marten Svanfeldt +ReWritten by: Francisco León +*/ + + + +#include "btBulletDynamicsCommon.h" +#include "GlutStuff.h" +#include "GL_ShapeDrawer.h" + +#include "LinearMath/btIDebugDraw.h" + +#include "GLDebugDrawer.h" +#include "GenericJointDemo.h" + + + +GLDebugDrawer debugDrawer; + + + + + + +void GenericJointDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + // Setup the basic world + + btDefaultCollisionConfiguration * collision_config = new btDefaultCollisionConfiguration(); + + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collision_config); + + btVector3 worldAabbMin(-10000,-10000,-10000); + btVector3 worldAabbMax(10000,10000,10000); + btBroadphaseInterface* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax); + + btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver; + + + m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,constraintSolver,collision_config); + + m_dynamicsWorld->setGravity(btVector3(0,-30,0)); + + m_dynamicsWorld->setDebugDrawer(&debugDrawer); + + // Setup a big ground box + { + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-15,0)); + localCreateRigidBody(btScalar(0.),groundTransform,groundShape); + } + + // Spawn one ragdoll + spawnRagdoll(); + + clientResetScene(); +} + +void GenericJointDemo::spawnRagdoll(bool random) +{ + RagDoll* ragDoll = new RagDoll (m_dynamicsWorld, btVector3 (0,0,10),5.f); + m_ragdolls.push_back(ragDoll); +} + +void GenericJointDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + float minFPS = 1000000.f/60.f; + if (ms > minFPS) + ms = minFPS; + + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + glFlush(); + + swapBuffers(); +} + +void GenericJointDemo::displayCallback() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + swapBuffers(); +} + +void GenericJointDemo::keyboardCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case 'e': + spawnRagdoll(true); + break; + default: + DemoApplication::keyboardCallback(key, x, y); + } + + +} diff --git a/Demos/GenericJointDemo/GenericJointDemo.h b/Demos/GenericJointDemo/GenericJointDemo.h new file mode 100644 index 0000000..68a11c0 --- /dev/null +++ b/Demos/GenericJointDemo/GenericJointDemo.h @@ -0,0 +1,51 @@ +/* +Bullet Continuous Collision Detection and Physics Library +GenericJointDemo +Copyright (c) 2007 Starbreeze Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Marten Svanfeldt +*/ + +#ifndef GENERIGJOINTDEMO_H +#define GENERIGJOINTDEMO_H + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +#include "LinearMath/btAlignedObjectArray.h" +#include "Ragdoll.h" + +class GenericJointDemo : public PlatformDemoApplication +{ + + btAlignedObjectArray m_ragdolls; + +public: + void initPhysics(); + + void spawnRagdoll(bool random = false); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void keyboardCallback(unsigned char key, int x, int y); +}; + + +#endif diff --git a/Demos/GenericJointDemo/Ragdoll.cpp b/Demos/GenericJointDemo/Ragdoll.cpp new file mode 100644 index 0000000..0229f5a --- /dev/null +++ b/Demos/GenericJointDemo/Ragdoll.cpp @@ -0,0 +1,373 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Ragdoll Demo +Copyright (c) 2007 Starbreeze Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Marten Svanfeldt +*/ + +#include "Ragdoll.h" + +//#define RIGID 1 + +RagDoll::RagDoll (btDynamicsWorld* ownerWorld, const btVector3& positionOffset, + btScalar scale_ragdoll) : m_ownerWorld (ownerWorld) +{ + + + // Setup the geometry + m_shapes[BODYPART_PELVIS] = new btCapsuleShape( + btScalar(scale_ragdoll*0.15), btScalar(scale_ragdoll*0.20)); + m_shapes[BODYPART_SPINE] = new btCapsuleShape( + btScalar(scale_ragdoll*0.15), btScalar(scale_ragdoll*0.28)); + m_shapes[BODYPART_HEAD] = new btCapsuleShape(btScalar(scale_ragdoll*0.10), btScalar(scale_ragdoll*0.05)); + m_shapes[BODYPART_LEFT_UPPER_LEG] = new btCapsuleShape(btScalar(scale_ragdoll*0.07), btScalar(scale_ragdoll*0.45)); + m_shapes[BODYPART_LEFT_LOWER_LEG] = new btCapsuleShape(btScalar(scale_ragdoll*0.05), btScalar(scale_ragdoll*0.37)); + m_shapes[BODYPART_RIGHT_UPPER_LEG] = new btCapsuleShape(btScalar(scale_ragdoll*0.07), btScalar(scale_ragdoll*0.45)); + m_shapes[BODYPART_RIGHT_LOWER_LEG] = new btCapsuleShape(btScalar(scale_ragdoll*0.05), btScalar(scale_ragdoll*0.37)); + m_shapes[BODYPART_LEFT_UPPER_ARM] = new btCapsuleShape(btScalar(scale_ragdoll*0.05), btScalar(scale_ragdoll*0.33)); + m_shapes[BODYPART_LEFT_LOWER_ARM] = new btCapsuleShape(btScalar(scale_ragdoll*0.04), btScalar(scale_ragdoll*0.25)); + m_shapes[BODYPART_RIGHT_UPPER_ARM] = new btCapsuleShape(btScalar(scale_ragdoll*0.05), btScalar(scale_ragdoll*0.33)); + m_shapes[BODYPART_RIGHT_LOWER_ARM] = new btCapsuleShape(btScalar(scale_ragdoll*0.04), btScalar(scale_ragdoll*0.25)); + + // Setup all the rigid bodies + btTransform offset; offset.setIdentity(); + offset.setOrigin(positionOffset); + + btTransform transform; + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.), btScalar(scale_ragdoll*1.), btScalar(0.))); + m_bodies[BODYPART_PELVIS] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_PELVIS]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.), btScalar(scale_ragdoll*1.2), btScalar(0.))); + m_bodies[BODYPART_SPINE] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_SPINE]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.), btScalar(scale_ragdoll*1.6), btScalar(0.))); + m_bodies[BODYPART_HEAD] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_HEAD]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.18*scale_ragdoll), btScalar(0.65*scale_ragdoll), +btScalar(0.))); + m_bodies[BODYPART_LEFT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.18*scale_ragdoll), btScalar(0.2*scale_ragdoll), btScalar(0.))); + m_bodies[BODYPART_LEFT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.18*scale_ragdoll), btScalar(0.65*scale_ragdoll), btScalar(0.))); + m_bodies[BODYPART_RIGHT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.18*scale_ragdoll), btScalar(0.2*scale_ragdoll), btScalar(0.))); + m_bodies[BODYPART_RIGHT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.35*scale_ragdoll), btScalar(1.45*scale_ragdoll), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,SIMD_HALF_PI); + m_bodies[BODYPART_LEFT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_ARM]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.7*scale_ragdoll), btScalar(1.45*scale_ragdoll), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,SIMD_HALF_PI); + m_bodies[BODYPART_LEFT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_ARM]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.35*scale_ragdoll), btScalar(1.45*scale_ragdoll), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,-SIMD_HALF_PI); + m_bodies[BODYPART_RIGHT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_ARM]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.7*scale_ragdoll), btScalar(1.45*scale_ragdoll), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,-SIMD_HALF_PI); + m_bodies[BODYPART_RIGHT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_ARM]); + + // Setup some damping on the m_bodies + for (int i = 0; i < BODYPART_COUNT; ++i) + { + m_bodies[i]->setDamping(0.05f, 0.85f); + m_bodies[i]->setDeactivationTime(0.8f); + m_bodies[i]->setSleepingThresholds(1.6f, 2.5f); + } + +///////////////////////////// SETTING THE CONSTRAINTS /////////////////////////////////////////////7777 + // Now setup the constraints + btGeneric6DofConstraint * joint6DOF; + btTransform localA, localB; + bool useLinearReferenceFrameA = true; +/// ******* SPINE HEAD ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(0.), btScalar(0.30*scale_ragdoll), btScalar(0.))); + + localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14*scale_ragdoll), btScalar(0.))); + + joint6DOF = new btGeneric6DofConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_HEAD], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_PI*0.3f,-SIMD_EPSILON,-SIMD_PI*0.3f)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.5f,SIMD_EPSILON,SIMD_PI*0.3f)); +#endif + m_joints[JOINT_SPINE_HEAD] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_SPINE_HEAD], true); + } +/// *************************** /// + + + + +/// ******* LEFT SHOULDER ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(-0.2*scale_ragdoll), btScalar(0.15*scale_ragdoll), btScalar(0.))); + + localB.getBasis().setEulerZYX(SIMD_HALF_PI,0,-SIMD_HALF_PI); + localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18*scale_ragdoll), btScalar(0.))); + + joint6DOF = new btGeneric6DofConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_LEFT_UPPER_ARM], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_PI*0.8f,-SIMD_EPSILON,-SIMD_PI*0.5f)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.8f,SIMD_EPSILON,SIMD_PI*0.5f)); +#endif + m_joints[JOINT_LEFT_SHOULDER] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_SHOULDER], true); + } +/// *************************** /// + + +/// ******* RIGHT SHOULDER ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(0.2*scale_ragdoll), btScalar(0.15*scale_ragdoll), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,SIMD_HALF_PI); + localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18*scale_ragdoll), btScalar(0.))); + joint6DOF = new btGeneric6DofConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_RIGHT_UPPER_ARM], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_PI*0.8f,-SIMD_EPSILON,-SIMD_PI*0.5f)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.8f,SIMD_EPSILON,SIMD_PI*0.5f)); +#endif + m_joints[JOINT_RIGHT_SHOULDER] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_SHOULDER], true); + } +/// *************************** /// + +/// ******* LEFT ELBOW ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18*scale_ragdoll), btScalar(0.))); + localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14*scale_ragdoll), btScalar(0.))); + joint6DOF = new btGeneric6DofConstraint (*m_bodies[BODYPART_LEFT_UPPER_ARM], *m_bodies[BODYPART_LEFT_LOWER_ARM], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.7f,SIMD_EPSILON,SIMD_EPSILON)); +#endif + m_joints[JOINT_LEFT_ELBOW] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_ELBOW], true); + } +/// *************************** /// + +/// ******* RIGHT ELBOW ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18*scale_ragdoll), btScalar(0.))); + localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14*scale_ragdoll), btScalar(0.))); + joint6DOF = new btGeneric6DofConstraint (*m_bodies[BODYPART_RIGHT_UPPER_ARM], *m_bodies[BODYPART_RIGHT_LOWER_ARM], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.7,SIMD_EPSILON,SIMD_EPSILON)); +#endif + + m_joints[JOINT_RIGHT_ELBOW] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_ELBOW], true); + } +/// *************************** /// + + +/// ******* PELVIS ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.getBasis().setEulerZYX(0,SIMD_HALF_PI,0); + localA.setOrigin(btVector3(btScalar(0.), btScalar(0.15*scale_ragdoll), btScalar(0.))); + localB.getBasis().setEulerZYX(0,SIMD_HALF_PI,0); + localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.15*scale_ragdoll), btScalar(0.))); + joint6DOF = new btGeneric6DofConstraint (*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_PI*0.2,-SIMD_EPSILON,-SIMD_PI*0.3)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.2,SIMD_EPSILON,SIMD_PI*0.6)); +#endif + m_joints[JOINT_PELVIS_SPINE] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true); + } +/// *************************** /// + +/// ******* LEFT HIP ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(-0.18*scale_ragdoll), btScalar(-0.10*scale_ragdoll), btScalar(0.))); + + localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225*scale_ragdoll), btScalar(0.))); + + joint6DOF = new btGeneric6DofConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_LEFT_UPPER_LEG], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI*0.5,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI*0.8,SIMD_EPSILON,SIMD_HALF_PI*0.6f)); +#endif + m_joints[JOINT_LEFT_HIP] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_HIP], true); + } +/// *************************** /// + + +/// ******* RIGHT HIP ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(0.18*scale_ragdoll), btScalar(-0.10*scale_ragdoll), btScalar(0.))); + localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225*scale_ragdoll), btScalar(0.))); + + joint6DOF = new btGeneric6DofConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_RIGHT_UPPER_LEG], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI*0.5,-SIMD_EPSILON,-SIMD_HALF_PI*0.6f)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI*0.8,SIMD_EPSILON,SIMD_EPSILON)); +#endif + m_joints[JOINT_RIGHT_HIP] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_HIP], true); + } +/// *************************** /// + + +/// ******* LEFT KNEE ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225*scale_ragdoll), btScalar(0.))); + localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185*scale_ragdoll), btScalar(0.))); + joint6DOF = new btGeneric6DofConstraint (*m_bodies[BODYPART_LEFT_UPPER_LEG], *m_bodies[BODYPART_LEFT_LOWER_LEG], localA, localB,useLinearReferenceFrameA); +// +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.7f,SIMD_EPSILON,SIMD_EPSILON)); +#endif + m_joints[JOINT_LEFT_KNEE] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_KNEE], true); + } +/// *************************** /// + +/// ******* RIGHT KNEE ******** /// + { + localA.setIdentity(); localB.setIdentity(); + + localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225*scale_ragdoll), btScalar(0.))); + localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185*scale_ragdoll), btScalar(0.))); + joint6DOF = new btGeneric6DofConstraint (*m_bodies[BODYPART_RIGHT_UPPER_LEG], *m_bodies[BODYPART_RIGHT_LOWER_LEG], localA, localB,useLinearReferenceFrameA); + +#ifdef RIGID + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_EPSILON,SIMD_EPSILON,SIMD_EPSILON)); +#else + joint6DOF->setAngularLowerLimit(btVector3(-SIMD_EPSILON,-SIMD_EPSILON,-SIMD_EPSILON)); + joint6DOF->setAngularUpperLimit(btVector3(SIMD_PI*0.7f,SIMD_EPSILON,SIMD_EPSILON)); +#endif + m_joints[JOINT_RIGHT_KNEE] = joint6DOF; + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_KNEE], true); + } +/// *************************** /// + +} + + +RagDoll::~RagDoll() +{ + int i; + + // Remove all constraints + for (i = 0; i < JOINT_COUNT; ++i) + { + m_ownerWorld->removeConstraint(m_joints[i]); + delete m_joints[i]; m_joints[i] = 0; + } + + // Remove all bodies and shapes + for (i = 0; i < BODYPART_COUNT; ++i) + { + m_ownerWorld->removeRigidBody(m_bodies[i]); + + delete m_bodies[i]->getMotionState(); + + delete m_bodies[i]; m_bodies[i] = 0; + delete m_shapes[i]; m_shapes[i] = 0; + } +} + + +btRigidBody* RagDoll::localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape) +{ + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + shape->calculateLocalInertia(mass,localInertia); + + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); + rbInfo.m_additionalDamping = true; + btRigidBody* body = new btRigidBody(rbInfo); + + m_ownerWorld->addRigidBody(body); + + return body; +} diff --git a/Demos/GenericJointDemo/Ragdoll.h b/Demos/GenericJointDemo/Ragdoll.h new file mode 100644 index 0000000..29a9cbd --- /dev/null +++ b/Demos/GenericJointDemo/Ragdoll.h @@ -0,0 +1,71 @@ +#ifndef RAGDOLL_H_INCLUDED +#define RAGDOLL_H_INCLUDED + +#include "DemoApplication.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "btBulletDynamicsCommon.h" + + + + +class RagDoll +{ + enum + { + BODYPART_PELVIS = 0, + BODYPART_SPINE, + BODYPART_HEAD, + + BODYPART_LEFT_UPPER_LEG, + BODYPART_LEFT_LOWER_LEG, + + BODYPART_RIGHT_UPPER_LEG, + BODYPART_RIGHT_LOWER_LEG, + + BODYPART_LEFT_UPPER_ARM, + BODYPART_LEFT_LOWER_ARM, + + BODYPART_RIGHT_UPPER_ARM, + BODYPART_RIGHT_LOWER_ARM, + + BODYPART_COUNT + }; + + enum + { + JOINT_PELVIS_SPINE = 0, + JOINT_SPINE_HEAD, + + JOINT_LEFT_HIP, + JOINT_LEFT_KNEE, + + JOINT_RIGHT_HIP, + JOINT_RIGHT_KNEE, + + JOINT_LEFT_SHOULDER, + JOINT_LEFT_ELBOW, + + JOINT_RIGHT_SHOULDER, + JOINT_RIGHT_ELBOW, + + JOINT_COUNT + }; + + btDynamicsWorld* m_ownerWorld; + btCollisionShape* m_shapes[BODYPART_COUNT]; + btRigidBody* m_bodies[BODYPART_COUNT]; + btTypedConstraint* m_joints[JOINT_COUNT]; + + btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape); + +public: + RagDoll (btDynamicsWorld* ownerWorld, + const btVector3& positionOffset, + btScalar scale_ragdoll = btScalar(1.0)); + + ~RagDoll (); +}; + + + +#endif // RAGDOLL_H_INCLUDED diff --git a/Demos/GenericJointDemo/Win32GenericJointDemo.cpp b/Demos/GenericJointDemo/Win32GenericJointDemo.cpp new file mode 100644 index 0000000..990b1fa --- /dev/null +++ b/Demos/GenericJointDemo/Win32GenericJointDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "GenericJointDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new GenericJointDemo(); +} + +#endif diff --git a/Demos/GenericJointDemo/main.cpp b/Demos/GenericJointDemo/main.cpp new file mode 100644 index 0000000..4dd56b8 --- /dev/null +++ b/Demos/GenericJointDemo/main.cpp @@ -0,0 +1,28 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "GenericJointDemo.h" + +int main(int argc,char* argv[]) +{ + GenericJointDemo demoApp; +// demoApp.configDebugDrawer(&debugDrawer); + + demoApp.initPhysics(); + demoApp.setCameraDistance(btScalar(10.)); + + return glutmain(argc, argv,640,480,"Joint 6DOF - Sequencial Impulse Solver",&demoApp); + +} diff --git a/Demos/GimpactTestDemo/BunnyMesh.h b/Demos/GimpactTestDemo/BunnyMesh.h new file mode 100644 index 0000000..818bd02 --- /dev/null +++ b/Demos/GimpactTestDemo/BunnyMesh.h @@ -0,0 +1,1379 @@ +#ifndef BUNNY_MESH_H_ +#define BUNNY_MESH_H_ + + + +//***************************THE FAMOUS BUNNY TRIMESH********************************************// + +#define REAL btScalar +const int BUNNY_NUM_TRIANGLES =902; +const int BUNNY_NUM_VERTICES = 453; +const int BUNNY_NUM_INDICES = BUNNY_NUM_TRIANGLES * 3; + + +static REAL gVerticesBunny[BUNNY_NUM_VERTICES * 3] = { + REAL(-0.334392), REAL(0.133007), REAL(0.062259), + REAL(-0.350189), REAL(0.150354), REAL(-0.147769), + REAL(-0.234201), REAL(0.343811), REAL(-0.174307), + REAL(-0.200259), REAL(0.285207), REAL(0.093749), + REAL(0.003520), REAL(0.475208), REAL(-0.159365), + REAL(0.001856), REAL(0.419203), REAL(0.098582), + REAL(-0.252802), REAL(0.093666), REAL(0.237538), + REAL(-0.162901), REAL(0.237984), REAL(0.206905), + REAL(0.000865), REAL(0.318141), REAL(0.235370), + REAL(-0.414624), REAL(0.164083), REAL(-0.278254), + REAL(-0.262213), REAL(0.357334), REAL(-0.293246), + REAL(0.004628), REAL(0.482694), REAL(-0.338626), + REAL(-0.402162), REAL(0.133528), REAL(-0.443247), + REAL(-0.243781), REAL(0.324275), REAL(-0.436763), + REAL(0.005293), REAL(0.437592), REAL(-0.458332), + REAL(-0.339884), REAL(-0.041150), REAL(-0.668211), + REAL(-0.248382), REAL(0.255825), REAL(-0.627493), + REAL(0.006261), REAL(0.376103), REAL(-0.631506), + REAL(-0.216201), REAL(-0.126776), REAL(-0.886936), + REAL(-0.171075), REAL(0.011544), REAL(-0.881386), + REAL(-0.181074), REAL(0.098223), REAL(-0.814779), + REAL(-0.119891), REAL(0.218786), REAL(-0.760153), + REAL(-0.078895), REAL(0.276780), REAL(-0.739281), + REAL(0.006801), REAL(0.310959), REAL(-0.735661), + REAL(-0.168842), REAL(0.102387), REAL(-0.920381), + REAL(-0.104072), REAL(0.177278), REAL(-0.952530), + REAL(-0.129704), REAL(0.211848), REAL(-0.836678), + REAL(-0.099875), REAL(0.310931), REAL(-0.799381), + REAL(0.007237), REAL(0.361687), REAL(-0.794439), + REAL(-0.077913), REAL(0.258753), REAL(-0.921640), + REAL(0.007957), REAL(0.282241), REAL(-0.931680), + REAL(-0.252222), REAL(-0.550401), REAL(-0.557810), + REAL(-0.267633), REAL(-0.603419), REAL(-0.655209), + REAL(-0.446838), REAL(-0.118517), REAL(-0.466159), + REAL(-0.459488), REAL(-0.093017), REAL(-0.311341), + REAL(-0.370645), REAL(-0.100108), REAL(-0.159454), + REAL(-0.371984), REAL(-0.091991), REAL(-0.011044), + REAL(-0.328945), REAL(-0.098269), REAL(0.088659), + REAL(-0.282452), REAL(-0.018862), REAL(0.311501), + REAL(-0.352403), REAL(-0.131341), REAL(0.144902), + REAL(-0.364126), REAL(-0.200299), REAL(0.202388), + REAL(-0.283965), REAL(-0.231869), REAL(0.023668), + REAL(-0.298943), REAL(-0.155218), REAL(0.369716), + REAL(-0.293787), REAL(-0.121856), REAL(0.419097), + REAL(-0.290163), REAL(-0.290797), REAL(0.107824), + REAL(-0.264165), REAL(-0.272849), REAL(0.036347), + REAL(-0.228567), REAL(-0.372573), REAL(0.290309), + REAL(-0.190431), REAL(-0.286997), REAL(0.421917), + REAL(-0.191039), REAL(-0.240973), REAL(0.507118), + REAL(-0.287272), REAL(-0.276431), REAL(-0.065444), + REAL(-0.295675), REAL(-0.280818), REAL(-0.174200), + REAL(-0.399537), REAL(-0.313131), REAL(-0.376167), + REAL(-0.392666), REAL(-0.488581), REAL(-0.427494), + REAL(-0.331669), REAL(-0.570185), REAL(-0.466054), + REAL(-0.282290), REAL(-0.618140), REAL(-0.589220), + REAL(-0.374238), REAL(-0.594882), REAL(-0.323298), + REAL(-0.381071), REAL(-0.629723), REAL(-0.350777), + REAL(-0.382112), REAL(-0.624060), REAL(-0.221577), + REAL(-0.272701), REAL(-0.566522), REAL(0.259157), + REAL(-0.256702), REAL(-0.663406), REAL(0.286079), + REAL(-0.280948), REAL(-0.428359), REAL(0.055790), + REAL(-0.184974), REAL(-0.508894), REAL(0.326265), + REAL(-0.279971), REAL(-0.526918), REAL(0.395319), + REAL(-0.282599), REAL(-0.663393), REAL(0.412411), + REAL(-0.188329), REAL(-0.475093), REAL(0.417954), + REAL(-0.263384), REAL(-0.663396), REAL(0.466604), + REAL(-0.209063), REAL(-0.663393), REAL(0.509344), + REAL(-0.002044), REAL(-0.319624), REAL(0.553078), + REAL(-0.001266), REAL(-0.371260), REAL(0.413296), + REAL(-0.219753), REAL(-0.339762), REAL(-0.040921), + REAL(-0.256986), REAL(-0.282511), REAL(-0.006349), + REAL(-0.271706), REAL(-0.260881), REAL(0.001764), + REAL(-0.091191), REAL(-0.419184), REAL(-0.045912), + REAL(-0.114944), REAL(-0.429752), REAL(-0.124739), + REAL(-0.113970), REAL(-0.382987), REAL(-0.188540), + REAL(-0.243012), REAL(-0.464942), REAL(-0.242850), + REAL(-0.314815), REAL(-0.505402), REAL(-0.324768), + REAL(0.002774), REAL(-0.437526), REAL(-0.262766), + REAL(-0.072625), REAL(-0.417748), REAL(-0.221440), + REAL(-0.160112), REAL(-0.476932), REAL(-0.293450), + REAL(0.003859), REAL(-0.453425), REAL(-0.443916), + REAL(-0.120363), REAL(-0.581567), REAL(-0.438689), + REAL(-0.091499), REAL(-0.584191), REAL(-0.294511), + REAL(-0.116469), REAL(-0.599861), REAL(-0.188308), + REAL(-0.208032), REAL(-0.513640), REAL(-0.134649), + REAL(-0.235749), REAL(-0.610017), REAL(-0.040939), + REAL(-0.344916), REAL(-0.622487), REAL(-0.085380), + REAL(-0.336401), REAL(-0.531864), REAL(-0.212298), + REAL(0.001961), REAL(-0.459550), REAL(-0.135547), + REAL(-0.058296), REAL(-0.430536), REAL(-0.043440), + REAL(0.001378), REAL(-0.449511), REAL(-0.037762), + REAL(-0.130135), REAL(-0.510222), REAL(0.079144), + REAL(0.000142), REAL(-0.477549), REAL(0.157064), + REAL(-0.114284), REAL(-0.453206), REAL(0.304397), + REAL(-0.000592), REAL(-0.443558), REAL(0.285401), + REAL(-0.056215), REAL(-0.663402), REAL(0.326073), + REAL(-0.026248), REAL(-0.568010), REAL(0.273318), + REAL(-0.049261), REAL(-0.531064), REAL(0.389854), + REAL(-0.127096), REAL(-0.663398), REAL(0.479316), + REAL(-0.058384), REAL(-0.663401), REAL(0.372891), + REAL(-0.303961), REAL(0.054199), REAL(0.625921), + REAL(-0.268594), REAL(0.193403), REAL(0.502766), + REAL(-0.277159), REAL(0.126123), REAL(0.443289), + REAL(-0.287605), REAL(-0.005722), REAL(0.531844), + REAL(-0.231396), REAL(-0.121289), REAL(0.587387), + REAL(-0.253475), REAL(-0.081797), REAL(0.756541), + REAL(-0.195164), REAL(-0.137969), REAL(0.728011), + REAL(-0.167673), REAL(-0.156573), REAL(0.609388), + REAL(-0.145917), REAL(-0.169029), REAL(0.697600), + REAL(-0.077776), REAL(-0.214247), REAL(0.622586), + REAL(-0.076873), REAL(-0.214971), REAL(0.696301), + REAL(-0.002341), REAL(-0.233135), REAL(0.622859), + REAL(-0.002730), REAL(-0.213526), REAL(0.691267), + REAL(-0.003136), REAL(-0.192628), REAL(0.762731), + REAL(-0.056136), REAL(-0.201222), REAL(0.763806), + REAL(-0.114589), REAL(-0.166192), REAL(0.770723), + REAL(-0.155145), REAL(-0.129632), REAL(0.791738), + REAL(-0.183611), REAL(-0.058705), REAL(0.847012), + REAL(-0.165562), REAL(0.001980), REAL(0.833386), + REAL(-0.220084), REAL(0.019914), REAL(0.768935), + REAL(-0.255730), REAL(0.090306), REAL(0.670782), + REAL(-0.255594), REAL(0.113833), REAL(0.663389), + REAL(-0.226380), REAL(0.212655), REAL(0.617740), + REAL(-0.003367), REAL(-0.195342), REAL(0.799680), + REAL(-0.029743), REAL(-0.210508), REAL(0.827180), + REAL(-0.003818), REAL(-0.194783), REAL(0.873636), + REAL(-0.004116), REAL(-0.157907), REAL(0.931268), + REAL(-0.031280), REAL(-0.184555), REAL(0.889476), + REAL(-0.059885), REAL(-0.184448), REAL(0.841330), + REAL(-0.135333), REAL(-0.164332), REAL(0.878200), + REAL(-0.085574), REAL(-0.170948), REAL(0.925547), + REAL(-0.163833), REAL(-0.094170), REAL(0.897114), + REAL(-0.138444), REAL(-0.104250), REAL(0.945975), + REAL(-0.083497), REAL(-0.084934), REAL(0.979607), + REAL(-0.004433), REAL(-0.146642), REAL(0.985872), + REAL(-0.150715), REAL(0.032650), REAL(0.884111), + REAL(-0.135892), REAL(-0.035520), REAL(0.945455), + REAL(-0.070612), REAL(0.036849), REAL(0.975733), + REAL(-0.004458), REAL(-0.042526), REAL(1.015670), + REAL(-0.004249), REAL(0.046042), REAL(1.003240), + REAL(-0.086969), REAL(0.133224), REAL(0.947633), + REAL(-0.003873), REAL(0.161605), REAL(0.970499), + REAL(-0.125544), REAL(0.140012), REAL(0.917678), + REAL(-0.125651), REAL(0.250246), REAL(0.857602), + REAL(-0.003127), REAL(0.284070), REAL(0.878870), + REAL(-0.159174), REAL(0.125726), REAL(0.888878), + REAL(-0.183807), REAL(0.196970), REAL(0.844480), + REAL(-0.159890), REAL(0.291736), REAL(0.732480), + REAL(-0.199495), REAL(0.207230), REAL(0.779864), + REAL(-0.206182), REAL(0.164608), REAL(0.693257), + REAL(-0.186315), REAL(0.160689), REAL(0.817193), + REAL(-0.192827), REAL(0.166706), REAL(0.782271), + REAL(-0.175112), REAL(0.110008), REAL(0.860621), + REAL(-0.161022), REAL(0.057420), REAL(0.855111), + REAL(-0.172319), REAL(0.036155), REAL(0.816189), + REAL(-0.190318), REAL(0.064083), REAL(0.760605), + REAL(-0.195072), REAL(0.129179), REAL(0.731104), + REAL(-0.203126), REAL(0.410287), REAL(0.680536), + REAL(-0.216677), REAL(0.309274), REAL(0.642272), + REAL(-0.241515), REAL(0.311485), REAL(0.587832), + REAL(-0.002209), REAL(0.366663), REAL(0.749413), + REAL(-0.088230), REAL(0.396265), REAL(0.678635), + REAL(-0.170147), REAL(0.109517), REAL(0.840784), + REAL(-0.160521), REAL(0.067766), REAL(0.830650), + REAL(-0.181546), REAL(0.139805), REAL(0.812146), + REAL(-0.180495), REAL(0.148568), REAL(0.776087), + REAL(-0.180255), REAL(0.129125), REAL(0.744192), + REAL(-0.186298), REAL(0.078308), REAL(0.769352), + REAL(-0.167622), REAL(0.060539), REAL(0.806675), + REAL(-0.189876), REAL(0.102760), REAL(0.802582), + REAL(-0.108340), REAL(0.455446), REAL(0.657174), + REAL(-0.241585), REAL(0.527592), REAL(0.669296), + REAL(-0.265676), REAL(0.513366), REAL(0.634594), + REAL(-0.203073), REAL(0.478550), REAL(0.581526), + REAL(-0.266772), REAL(0.642330), REAL(0.602061), + REAL(-0.216961), REAL(0.564846), REAL(0.535435), + REAL(-0.202210), REAL(0.525495), REAL(0.475944), + REAL(-0.193888), REAL(0.467925), REAL(0.520606), + REAL(-0.265837), REAL(0.757267), REAL(0.500933), + REAL(-0.240306), REAL(0.653440), REAL(0.463215), + REAL(-0.309239), REAL(0.776868), REAL(0.304726), + REAL(-0.271009), REAL(0.683094), REAL(0.382018), + REAL(-0.312111), REAL(0.671099), REAL(0.286687), + REAL(-0.268791), REAL(0.624342), REAL(0.377231), + REAL(-0.302457), REAL(0.533996), REAL(0.360289), + REAL(-0.263656), REAL(0.529310), REAL(0.412564), + REAL(-0.282311), REAL(0.415167), REAL(0.447666), + REAL(-0.239201), REAL(0.442096), REAL(0.495604), + REAL(-0.220043), REAL(0.569026), REAL(0.445877), + REAL(-0.001263), REAL(0.395631), REAL(0.602029), + REAL(-0.057345), REAL(0.442535), REAL(0.572224), + REAL(-0.088927), REAL(0.506333), REAL(0.529106), + REAL(-0.125738), REAL(0.535076), REAL(0.612913), + REAL(-0.126251), REAL(0.577170), REAL(0.483159), + REAL(-0.149594), REAL(0.611520), REAL(0.557731), + REAL(-0.163188), REAL(0.660791), REAL(0.491080), + REAL(-0.172482), REAL(0.663387), REAL(0.415416), + REAL(-0.160464), REAL(0.591710), REAL(0.370659), + REAL(-0.156445), REAL(0.536396), REAL(0.378302), + REAL(-0.136496), REAL(0.444358), REAL(0.425226), + REAL(-0.095564), REAL(0.373768), REAL(0.473659), + REAL(-0.104146), REAL(0.315912), REAL(0.498104), + REAL(-0.000496), REAL(0.384194), REAL(0.473817), + REAL(-0.000183), REAL(0.297770), REAL(0.401486), + REAL(-0.129042), REAL(0.270145), REAL(0.434495), + REAL(0.000100), REAL(0.272963), REAL(0.349138), + REAL(-0.113060), REAL(0.236984), REAL(0.385554), + REAL(0.007260), REAL(0.016311), REAL(-0.883396), + REAL(0.007865), REAL(0.122104), REAL(-0.956137), + REAL(-0.032842), REAL(0.115282), REAL(-0.953252), + REAL(-0.089115), REAL(0.108449), REAL(-0.950317), + REAL(-0.047440), REAL(0.014729), REAL(-0.882756), + REAL(-0.104458), REAL(0.013137), REAL(-0.882070), + REAL(-0.086439), REAL(-0.584866), REAL(-0.608343), + REAL(-0.115026), REAL(-0.662605), REAL(-0.436732), + REAL(-0.071683), REAL(-0.665372), REAL(-0.606385), + REAL(-0.257884), REAL(-0.665381), REAL(-0.658052), + REAL(-0.272542), REAL(-0.665381), REAL(-0.592063), + REAL(-0.371322), REAL(-0.665382), REAL(-0.353620), + REAL(-0.372362), REAL(-0.665381), REAL(-0.224420), + REAL(-0.335166), REAL(-0.665380), REAL(-0.078623), + REAL(-0.225999), REAL(-0.665375), REAL(-0.038981), + REAL(-0.106719), REAL(-0.665374), REAL(-0.186351), + REAL(-0.081749), REAL(-0.665372), REAL(-0.292554), + REAL(0.006943), REAL(-0.091505), REAL(-0.858354), + REAL(0.006117), REAL(-0.280985), REAL(-0.769967), + REAL(0.004495), REAL(-0.502360), REAL(-0.559799), + REAL(-0.198638), REAL(-0.302135), REAL(-0.845816), + REAL(-0.237395), REAL(-0.542544), REAL(-0.587188), + REAL(-0.270001), REAL(-0.279489), REAL(-0.669861), + REAL(-0.134547), REAL(-0.119852), REAL(-0.959004), + REAL(-0.052088), REAL(-0.122463), REAL(-0.944549), + REAL(-0.124463), REAL(-0.293508), REAL(-0.899566), + REAL(-0.047616), REAL(-0.289643), REAL(-0.879292), + REAL(-0.168595), REAL(-0.529132), REAL(-0.654931), + REAL(-0.099793), REAL(-0.515719), REAL(-0.645873), + REAL(-0.186168), REAL(-0.605282), REAL(-0.724690), + REAL(-0.112970), REAL(-0.583097), REAL(-0.707469), + REAL(-0.108152), REAL(-0.665375), REAL(-0.700408), + REAL(-0.183019), REAL(-0.665378), REAL(-0.717630), + REAL(-0.349529), REAL(-0.334459), REAL(-0.511985), + REAL(-0.141182), REAL(-0.437705), REAL(-0.798194), + REAL(-0.212670), REAL(-0.448725), REAL(-0.737447), + REAL(-0.261111), REAL(-0.414945), REAL(-0.613835), + REAL(-0.077364), REAL(-0.431480), REAL(-0.778113), + REAL(0.005174), REAL(-0.425277), REAL(-0.651592), + REAL(0.089236), REAL(-0.431732), REAL(-0.777093), + REAL(0.271006), REAL(-0.415749), REAL(-0.610577), + REAL(0.223981), REAL(-0.449384), REAL(-0.734774), + REAL(0.153275), REAL(-0.438150), REAL(-0.796391), + REAL(0.358414), REAL(-0.335529), REAL(-0.507649), + REAL(0.193434), REAL(-0.665946), REAL(-0.715325), + REAL(0.118363), REAL(-0.665717), REAL(-0.699021), + REAL(0.123515), REAL(-0.583454), REAL(-0.706020), + REAL(0.196851), REAL(-0.605860), REAL(-0.722345), + REAL(0.109788), REAL(-0.516035), REAL(-0.644590), + REAL(0.178656), REAL(-0.529656), REAL(-0.652804), + REAL(0.061157), REAL(-0.289807), REAL(-0.878626), + REAL(0.138234), REAL(-0.293905), REAL(-0.897958), + REAL(0.066933), REAL(-0.122643), REAL(-0.943820), + REAL(0.149571), REAL(-0.120281), REAL(-0.957264), + REAL(0.280989), REAL(-0.280321), REAL(-0.666487), + REAL(0.246581), REAL(-0.543275), REAL(-0.584224), + REAL(0.211720), REAL(-0.302754), REAL(-0.843303), + REAL(0.086966), REAL(-0.665627), REAL(-0.291520), + REAL(0.110634), REAL(-0.665702), REAL(-0.185021), + REAL(0.228099), REAL(-0.666061), REAL(-0.036201), + REAL(0.337743), REAL(-0.666396), REAL(-0.074503), + REAL(0.376722), REAL(-0.666513), REAL(-0.219833), + REAL(0.377265), REAL(-0.666513), REAL(-0.349036), + REAL(0.281411), REAL(-0.666217), REAL(-0.588670), + REAL(0.267564), REAL(-0.666174), REAL(-0.654834), + REAL(0.080745), REAL(-0.665602), REAL(-0.605452), + REAL(0.122016), REAL(-0.662963), REAL(-0.435280), + REAL(0.095767), REAL(-0.585141), REAL(-0.607228), + REAL(0.118944), REAL(0.012799), REAL(-0.880702), + REAL(0.061944), REAL(0.014564), REAL(-0.882086), + REAL(0.104725), REAL(0.108156), REAL(-0.949130), + REAL(0.048513), REAL(0.115159), REAL(-0.952753), + REAL(0.112696), REAL(0.236643), REAL(0.386937), + REAL(0.128177), REAL(0.269757), REAL(0.436071), + REAL(0.102643), REAL(0.315600), REAL(0.499370), + REAL(0.094535), REAL(0.373481), REAL(0.474824), + REAL(0.136270), REAL(0.443946), REAL(0.426895), + REAL(0.157071), REAL(0.535923), REAL(0.380222), + REAL(0.161350), REAL(0.591224), REAL(0.372630), + REAL(0.173035), REAL(0.662865), REAL(0.417531), + REAL(0.162808), REAL(0.660299), REAL(0.493077), + REAL(0.148250), REAL(0.611070), REAL(0.559555), + REAL(0.125719), REAL(0.576790), REAL(0.484702), + REAL(0.123489), REAL(0.534699), REAL(0.614440), + REAL(0.087621), REAL(0.506066), REAL(0.530188), + REAL(0.055321), REAL(0.442365), REAL(0.572915), + REAL(0.219936), REAL(0.568361), REAL(0.448571), + REAL(0.238099), REAL(0.441375), REAL(0.498528), + REAL(0.281711), REAL(0.414315), REAL(0.451121), + REAL(0.263833), REAL(0.528513), REAL(0.415794), + REAL(0.303284), REAL(0.533081), REAL(0.363998), + REAL(0.269687), REAL(0.623528), REAL(0.380528), + REAL(0.314255), REAL(0.670153), REAL(0.290524), + REAL(0.272023), REAL(0.682273), REAL(0.385343), + REAL(0.311480), REAL(0.775931), REAL(0.308527), + REAL(0.240239), REAL(0.652714), REAL(0.466159), + REAL(0.265619), REAL(0.756464), REAL(0.504187), + REAL(0.192562), REAL(0.467341), REAL(0.522972), + REAL(0.201605), REAL(0.524885), REAL(0.478417), + REAL(0.215743), REAL(0.564193), REAL(0.538084), + REAL(0.264969), REAL(0.641527), REAL(0.605317), + REAL(0.201031), REAL(0.477940), REAL(0.584002), + REAL(0.263086), REAL(0.512567), REAL(0.637832), + REAL(0.238615), REAL(0.526867), REAL(0.672237), + REAL(0.105309), REAL(0.455123), REAL(0.658482), + REAL(0.183993), REAL(0.102195), REAL(0.804872), + REAL(0.161563), REAL(0.060042), REAL(0.808692), + REAL(0.180748), REAL(0.077754), REAL(0.771600), + REAL(0.175168), REAL(0.128588), REAL(0.746368), + REAL(0.175075), REAL(0.148030), REAL(0.778264), + REAL(0.175658), REAL(0.139265), REAL(0.814333), + REAL(0.154191), REAL(0.067291), REAL(0.832578), + REAL(0.163818), REAL(0.109013), REAL(0.842830), + REAL(0.084760), REAL(0.396004), REAL(0.679695), + REAL(0.238888), REAL(0.310760), REAL(0.590775), + REAL(0.213380), REAL(0.308625), REAL(0.644905), + REAL(0.199666), REAL(0.409678), REAL(0.683003), + REAL(0.190143), REAL(0.128597), REAL(0.733463), + REAL(0.184833), REAL(0.063516), REAL(0.762902), + REAL(0.166070), REAL(0.035644), REAL(0.818261), + REAL(0.154361), REAL(0.056943), REAL(0.857042), + REAL(0.168542), REAL(0.109489), REAL(0.862725), + REAL(0.187387), REAL(0.166131), REAL(0.784599), + REAL(0.180428), REAL(0.160135), REAL(0.819438), + REAL(0.201823), REAL(0.163991), REAL(0.695756), + REAL(0.194206), REAL(0.206635), REAL(0.782275), + REAL(0.155438), REAL(0.291260), REAL(0.734412), + REAL(0.177696), REAL(0.196424), REAL(0.846693), + REAL(0.152305), REAL(0.125256), REAL(0.890786), + REAL(0.119546), REAL(0.249876), REAL(0.859104), + REAL(0.118369), REAL(0.139643), REAL(0.919173), + REAL(0.079410), REAL(0.132973), REAL(0.948652), + REAL(0.062419), REAL(0.036648), REAL(0.976547), + REAL(0.127847), REAL(-0.035919), REAL(0.947070), + REAL(0.143624), REAL(0.032206), REAL(0.885913), + REAL(0.074888), REAL(-0.085173), REAL(0.980577), + REAL(0.130184), REAL(-0.104656), REAL(0.947620), + REAL(0.156201), REAL(-0.094653), REAL(0.899074), + REAL(0.077366), REAL(-0.171194), REAL(0.926545), + REAL(0.127722), REAL(-0.164729), REAL(0.879810), + REAL(0.052670), REAL(-0.184618), REAL(0.842019), + REAL(0.023477), REAL(-0.184638), REAL(0.889811), + REAL(0.022626), REAL(-0.210587), REAL(0.827500), + REAL(0.223089), REAL(0.211976), REAL(0.620493), + REAL(0.251444), REAL(0.113067), REAL(0.666494), + REAL(0.251419), REAL(0.089540), REAL(0.673887), + REAL(0.214360), REAL(0.019258), REAL(0.771595), + REAL(0.158999), REAL(0.001490), REAL(0.835374), + REAL(0.176696), REAL(-0.059249), REAL(0.849218), + REAL(0.148696), REAL(-0.130091), REAL(0.793599), + REAL(0.108290), REAL(-0.166528), REAL(0.772088), + REAL(0.049820), REAL(-0.201382), REAL(0.764454), + REAL(0.071341), REAL(-0.215195), REAL(0.697209), + REAL(0.073148), REAL(-0.214475), REAL(0.623510), + REAL(0.140502), REAL(-0.169461), REAL(0.699354), + REAL(0.163374), REAL(-0.157073), REAL(0.611416), + REAL(0.189466), REAL(-0.138550), REAL(0.730366), + REAL(0.247593), REAL(-0.082554), REAL(0.759610), + REAL(0.227468), REAL(-0.121982), REAL(0.590197), + REAL(0.284702), REAL(-0.006586), REAL(0.535347), + REAL(0.275741), REAL(0.125287), REAL(0.446676), + REAL(0.266650), REAL(0.192594), REAL(0.506044), + REAL(0.300086), REAL(0.053287), REAL(0.629620), + REAL(0.055450), REAL(-0.663935), REAL(0.375065), + REAL(0.122854), REAL(-0.664138), REAL(0.482323), + REAL(0.046520), REAL(-0.531571), REAL(0.391918), + REAL(0.024824), REAL(-0.568450), REAL(0.275106), + REAL(0.053855), REAL(-0.663931), REAL(0.328224), + REAL(0.112829), REAL(-0.453549), REAL(0.305788), + REAL(0.131265), REAL(-0.510617), REAL(0.080746), + REAL(0.061174), REAL(-0.430716), REAL(-0.042710), + REAL(0.341019), REAL(-0.532887), REAL(-0.208150), + REAL(0.347705), REAL(-0.623533), REAL(-0.081139), + REAL(0.238040), REAL(-0.610732), REAL(-0.038037), + REAL(0.211764), REAL(-0.514274), REAL(-0.132078), + REAL(0.120605), REAL(-0.600219), REAL(-0.186856), + REAL(0.096985), REAL(-0.584476), REAL(-0.293357), + REAL(0.127621), REAL(-0.581941), REAL(-0.437170), + REAL(0.165902), REAL(-0.477425), REAL(-0.291453), + REAL(0.077720), REAL(-0.417975), REAL(-0.220519), + REAL(0.320892), REAL(-0.506363), REAL(-0.320874), + REAL(0.248214), REAL(-0.465684), REAL(-0.239842), + REAL(0.118764), REAL(-0.383338), REAL(-0.187114), + REAL(0.118816), REAL(-0.430106), REAL(-0.123307), + REAL(0.094131), REAL(-0.419464), REAL(-0.044777), + REAL(0.274526), REAL(-0.261706), REAL(0.005110), + REAL(0.259842), REAL(-0.283292), REAL(-0.003185), + REAL(0.222861), REAL(-0.340431), REAL(-0.038210), + REAL(0.204445), REAL(-0.664380), REAL(0.513353), + REAL(0.259286), REAL(-0.664547), REAL(0.471281), + REAL(0.185402), REAL(-0.476020), REAL(0.421718), + REAL(0.279163), REAL(-0.664604), REAL(0.417328), + REAL(0.277157), REAL(-0.528122), REAL(0.400208), + REAL(0.183069), REAL(-0.509812), REAL(0.329995), + REAL(0.282599), REAL(-0.429210), REAL(0.059242), + REAL(0.254816), REAL(-0.664541), REAL(0.290687), + REAL(0.271436), REAL(-0.567707), REAL(0.263966), + REAL(0.386561), REAL(-0.625221), REAL(-0.216870), + REAL(0.387086), REAL(-0.630883), REAL(-0.346073), + REAL(0.380021), REAL(-0.596021), REAL(-0.318679), + REAL(0.291269), REAL(-0.619007), REAL(-0.585707), + REAL(0.339280), REAL(-0.571198), REAL(-0.461946), + REAL(0.400045), REAL(-0.489778), REAL(-0.422640), + REAL(0.406817), REAL(-0.314349), REAL(-0.371230), + REAL(0.300588), REAL(-0.281718), REAL(-0.170549), + REAL(0.290866), REAL(-0.277304), REAL(-0.061905), + REAL(0.187735), REAL(-0.241545), REAL(0.509437), + REAL(0.188032), REAL(-0.287569), REAL(0.424234), + REAL(0.227520), REAL(-0.373262), REAL(0.293102), + REAL(0.266526), REAL(-0.273650), REAL(0.039597), + REAL(0.291592), REAL(-0.291676), REAL(0.111386), + REAL(0.291914), REAL(-0.122741), REAL(0.422683), + REAL(0.297574), REAL(-0.156119), REAL(0.373368), + REAL(0.286603), REAL(-0.232731), REAL(0.027162), + REAL(0.364663), REAL(-0.201399), REAL(0.206850), + REAL(0.353855), REAL(-0.132408), REAL(0.149228), + REAL(0.282208), REAL(-0.019715), REAL(0.314960), + REAL(0.331187), REAL(-0.099266), REAL(0.092701), + REAL(0.375463), REAL(-0.093120), REAL(-0.006467), + REAL(0.375917), REAL(-0.101236), REAL(-0.154882), + REAL(0.466635), REAL(-0.094416), REAL(-0.305669), + REAL(0.455805), REAL(-0.119881), REAL(-0.460632), + REAL(0.277465), REAL(-0.604242), REAL(-0.651871), + REAL(0.261022), REAL(-0.551176), REAL(-0.554667), + REAL(0.093627), REAL(0.258494), REAL(-0.920589), + REAL(0.114248), REAL(0.310608), REAL(-0.798070), + REAL(0.144232), REAL(0.211434), REAL(-0.835001), + REAL(0.119916), REAL(0.176940), REAL(-0.951159), + REAL(0.184061), REAL(0.101854), REAL(-0.918220), + REAL(0.092431), REAL(0.276521), REAL(-0.738231), + REAL(0.133504), REAL(0.218403), REAL(-0.758602), + REAL(0.194987), REAL(0.097655), REAL(-0.812476), + REAL(0.185542), REAL(0.011005), REAL(-0.879202), + REAL(0.230315), REAL(-0.127450), REAL(-0.884202), + REAL(0.260471), REAL(0.255056), REAL(-0.624378), + REAL(0.351567), REAL(-0.042194), REAL(-0.663976), + REAL(0.253742), REAL(0.323524), REAL(-0.433716), + REAL(0.411612), REAL(0.132299), REAL(-0.438264), + REAL(0.270513), REAL(0.356530), REAL(-0.289984), + REAL(0.422146), REAL(0.162819), REAL(-0.273130), + REAL(0.164724), REAL(0.237490), REAL(0.208912), + REAL(0.253806), REAL(0.092900), REAL(0.240640), + REAL(0.203608), REAL(0.284597), REAL(0.096223), + REAL(0.241006), REAL(0.343093), REAL(-0.171396), + REAL(0.356076), REAL(0.149288), REAL(-0.143443), + REAL(0.337656), REAL(0.131992), REAL(0.066374) +}; + +static int gIndicesBunny[BUNNY_NUM_TRIANGLES][3] = { + {126,134,133}, + {342,138,134}, + {133,134,138}, + {126,342,134}, + {312,316,317}, + {169,163,162}, + {312,317,319}, + {312,319,318}, + {169,162,164}, + {169,168,163}, + {312,314,315}, + {169,164,165}, + {169,167,168}, + {312,315,316}, + {312,313,314}, + {169,165,166}, + {169,166,167}, + {312,318,313}, + {308,304,305}, + {308,305,306}, + {179,181,188}, + {177,173,175}, + {177,175,176}, + {302,293,300}, + {322,294,304}, + {188,176,175}, + {188,175,179}, + {158,177,187}, + {305,293,302}, + {305,302,306}, + {322,304,308}, + {188,181,183}, + {158,173,177}, + {293,298,300}, + {304,294,296}, + {304,296,305}, + {185,176,188}, + {185,188,183}, + {187,177,176}, + {187,176,185}, + {305,296,298}, + {305,298,293}, + {436,432, 28}, + {436, 28, 23}, + {434,278,431}, + { 30,208,209}, + { 30,209, 29}, + { 19, 20, 24}, + {208,207,211}, + {208,211,209}, + { 19,210,212}, + {433,434,431}, + {433,431,432}, + {433,432,436}, + {436,437,433}, + {277,275,276}, + {277,276,278}, + {209,210, 25}, + { 21, 26, 24}, + { 21, 24, 20}, + { 25, 26, 27}, + { 25, 27, 29}, + {435,439,277}, + {439,275,277}, + {432,431, 30}, + {432, 30, 28}, + {433,437,438}, + {433,438,435}, + {434,277,278}, + { 24, 25,210}, + { 24, 26, 25}, + { 29, 27, 28}, + { 29, 28, 30}, + { 19, 24,210}, + {208, 30,431}, + {208,431,278}, + {435,434,433}, + {435,277,434}, + { 25, 29,209}, + { 27, 22, 23}, + { 27, 23, 28}, + { 26, 22, 27}, + { 26, 21, 22}, + {212,210,209}, + {212,209,211}, + {207,208,278}, + {207,278,276}, + {439,435,438}, + { 12, 9, 10}, + { 12, 10, 13}, + { 2, 3, 5}, + { 2, 5, 4}, + { 16, 13, 14}, + { 16, 14, 17}, + { 22, 21, 16}, + { 13, 10, 11}, + { 13, 11, 14}, + { 1, 0, 3}, + { 1, 3, 2}, + { 15, 12, 16}, + { 19, 18, 15}, + { 19, 15, 16}, + { 19, 16, 20}, + { 9, 1, 2}, + { 9, 2, 10}, + { 3, 7, 8}, + { 3, 8, 5}, + { 16, 17, 23}, + { 16, 23, 22}, + { 21, 20, 16}, + { 10, 2, 4}, + { 10, 4, 11}, + { 0, 6, 7}, + { 0, 7, 3}, + { 12, 13, 16}, + {451,446,445}, + {451,445,450}, + {442,440,439}, + {442,439,438}, + {442,438,441}, + {421,420,422}, + {412,411,426}, + {412,426,425}, + {408,405,407}, + {413, 67, 68}, + {413, 68,414}, + {391,390,412}, + { 80,384,386}, + {404,406,378}, + {390,391,377}, + {390,377, 88}, + {400,415,375}, + {398,396,395}, + {398,395,371}, + {398,371,370}, + {112,359,358}, + {112,358,113}, + {351,352,369}, + {125,349,348}, + {345,343,342}, + {342,340,339}, + {341,335,337}, + {328,341,327}, + {331,323,333}, + {331,322,323}, + {327,318,319}, + {327,319,328}, + {315,314,324}, + {302,300,301}, + {302,301,303}, + {320,311,292}, + {285,284,289}, + {310,307,288}, + {310,288,290}, + {321,350,281}, + {321,281,282}, + {423,448,367}, + {272,273,384}, + {272,384,274}, + {264,265,382}, + {264,382,383}, + {440,442,261}, + {440,261,263}, + {252,253,254}, + {252,254,251}, + {262,256,249}, + {262,249,248}, + {228,243,242}, + {228, 31,243}, + {213,215,238}, + {213,238,237}, + { 19,212,230}, + {224,225,233}, + {224,233,231}, + {217,218, 56}, + {217, 56, 54}, + {217,216,239}, + {217,239,238}, + {217,238,215}, + {218,217,215}, + {218,215,214}, + { 6,102,206}, + {186,199,200}, + {197,182,180}, + {170,171,157}, + {201,200,189}, + {170,190,191}, + {170,191,192}, + {175,174,178}, + {175,178,179}, + {168,167,155}, + {122,149,158}, + {122,158,159}, + {135,153,154}, + {135,154,118}, + {143,140,141}, + {143,141,144}, + {132,133,136}, + {130,126,133}, + {124,125,127}, + {122,101,100}, + {122,100,121}, + {110,108,107}, + {110,107,109}, + { 98, 99, 97}, + { 98, 97, 64}, + { 98, 64, 66}, + { 87, 55, 57}, + { 83, 82, 79}, + { 83, 79, 84}, + { 78, 74, 50}, + { 49, 71, 41}, + { 49, 41, 37}, + { 49, 37, 36}, + { 58, 44, 60}, + { 60, 59, 58}, + { 51, 34, 33}, + { 39, 40, 42}, + { 39, 42, 38}, + {243,240, 33}, + {243, 33,229}, + { 39, 38, 6}, + { 44, 46, 40}, + { 55, 56, 57}, + { 64, 62, 65}, + { 64, 65, 66}, + { 41, 71, 45}, + { 75, 50, 51}, + { 81, 79, 82}, + { 77, 88, 73}, + { 93, 92, 94}, + { 68, 47, 46}, + { 96, 97, 99}, + { 96, 99, 95}, + {110,109,111}, + {111,112,110}, + {114,113,123}, + {114,123,124}, + {132,131,129}, + {133,137,136}, + {135,142,145}, + {145,152,135}, + {149,147,157}, + {157,158,149}, + {164,150,151}, + {153,163,168}, + {153,168,154}, + {185,183,182}, + {185,182,184}, + {161,189,190}, + {200,199,191}, + {200,191,190}, + {180,178,195}, + {180,195,196}, + {102,101,204}, + {102,204,206}, + { 43, 48,104}, + { 43,104,103}, + {216,217, 54}, + {216, 54, 32}, + {207,224,231}, + {230,212,211}, + {230,211,231}, + {227,232,241}, + {227,241,242}, + {235,234,241}, + {235,241,244}, + {430,248,247}, + {272,274,253}, + {272,253,252}, + {439,260,275}, + {225,224,259}, + {225,259,257}, + {269,270,407}, + {269,407,405}, + {270,269,273}, + {270,273,272}, + {273,269,268}, + {273,268,267}, + {273,267,266}, + {273,266,265}, + {273,265,264}, + {448,279,367}, + {281,350,368}, + {285,286,301}, + {290,323,310}, + {290,311,323}, + {282,281,189}, + {292,311,290}, + {292,290,291}, + {307,306,302}, + {307,302,303}, + {316,315,324}, + {316,324,329}, + {331,351,350}, + {330,334,335}, + {330,335,328}, + {341,337,338}, + {344,355,354}, + {346,345,348}, + {346,348,347}, + {364,369,352}, + {364,352,353}, + {365,363,361}, + {365,361,362}, + {376,401,402}, + {373,372,397}, + {373,397,400}, + {376, 92,377}, + {381,378,387}, + {381,387,385}, + {386, 77, 80}, + {390,389,412}, + {416,417,401}, + {403,417,415}, + {408,429,430}, + {419,423,418}, + {427,428,444}, + {427,444,446}, + {437,436,441}, + {450,445, 11}, + {450, 11, 4}, + {447,449, 5}, + {447, 5, 8}, + {441,438,437}, + {425,426,451}, + {425,451,452}, + {417,421,415}, + {408,407,429}, + {399,403,400}, + {399,400,397}, + {394,393,416}, + {389,411,412}, + {386,383,385}, + {408,387,378}, + {408,378,406}, + {377,391,376}, + { 94,375,415}, + {372,373,374}, + {372,374,370}, + {359,111,360}, + {359,112,111}, + {113,358,349}, + {113,349,123}, + {346,343,345}, + {343,340,342}, + {338,336,144}, + {338,144,141}, + {327,341,354}, + {327,354,326}, + {331,350,321}, + {331,321,322}, + {314,313,326}, + {314,326,325}, + {300,298,299}, + {300,299,301}, + {288,287,289}, + {189,292,282}, + {287,288,303}, + {284,285,297}, + {368,280,281}, + {448,447,279}, + {274,226,255}, + {267,268,404}, + {267,404,379}, + {429,262,430}, + {439,440,260}, + {257,258,249}, + {257,249,246}, + {430,262,248}, + {234,228,242}, + {234,242,241}, + {237,238,239}, + {237,239,236}, + { 15, 18,227}, + { 15,227,229}, + {222,223, 82}, + {222, 82, 83}, + {214,215,213}, + {214,213, 81}, + { 38,102, 6}, + {122,159,200}, + {122,200,201}, + {174,171,192}, + {174,192,194}, + {197,193,198}, + {190,170,161}, + {181,179,178}, + {181,178,180}, + {166,156,155}, + {163,153,152}, + {163,152,162}, + {120,156,149}, + {120,149,121}, + {152,153,135}, + {140,143,142}, + {135,131,132}, + {135,132,136}, + {130,129,128}, + {130,128,127}, + {100,105,119}, + {100,119,120}, + {106,104,107}, + {106,107,108}, + { 91, 95, 59}, + { 93, 94, 68}, + { 91, 89, 92}, + { 76, 53, 55}, + { 76, 55, 87}, + { 81, 78, 79}, + { 74, 73, 49}, + { 69, 60, 45}, + { 58, 62, 64}, + { 58, 64, 61}, + { 53, 31, 32}, + { 32, 54, 53}, + { 42, 43, 38}, + { 35, 36, 0}, + { 35, 0, 1}, + { 34, 35, 1}, + { 34, 1, 9}, + { 44, 40, 41}, + { 44, 41, 45}, + { 33,240, 51}, + { 63, 62, 58}, + { 63, 58, 59}, + { 45, 71, 70}, + { 76, 75, 51}, + { 76, 51, 52}, + { 86, 85, 84}, + { 86, 84, 87}, + { 89, 72, 73}, + { 89, 73, 88}, + { 91, 92, 96}, + { 91, 96, 95}, + { 72, 91, 60}, + { 72, 60, 69}, + {104,106,105}, + {119,105,117}, + {119,117,118}, + {124,127,128}, + {117,116,129}, + {117,129,131}, + {118,117,131}, + {135,140,142}, + {146,150,152}, + {146,152,145}, + {149,122,121}, + {166,165,151}, + {166,151,156}, + {158,172,173}, + {161,160,189}, + {199,198,193}, + {199,193,191}, + {204,201,202}, + {178,174,194}, + {200,159,186}, + {109, 48, 67}, + { 48,107,104}, + {216, 32,236}, + {216,236,239}, + {223,214, 81}, + {223, 81, 82}, + { 33, 12, 15}, + { 32,228,234}, + { 32,234,236}, + {240, 31, 52}, + {256,255,246}, + {256,246,249}, + {258,263,248}, + {258,248,249}, + {275,260,259}, + {275,259,276}, + {207,276,259}, + {270,271,429}, + {270,429,407}, + {413,418,366}, + {413,366,365}, + {368,367,279}, + {368,279,280}, + {303,301,286}, + {303,286,287}, + {283,282,292}, + {283,292,291}, + {320,292,189}, + {298,296,297}, + {298,297,299}, + {318,327,326}, + {318,326,313}, + {329,330,317}, + {336,333,320}, + {326,354,353}, + {334,332,333}, + {334,333,336}, + {342,339,139}, + {342,139,138}, + {345,342,126}, + {347,357,356}, + {369,368,351}, + {363,356,357}, + {363,357,361}, + {366,367,368}, + {366,368,369}, + {375,373,400}, + { 92, 90,377}, + {409,387,408}, + {386,385,387}, + {386,387,388}, + {412,394,391}, + {396,398,399}, + {408,406,405}, + {415,421,419}, + {415,419,414}, + {425,452,448}, + {425,448,424}, + {444,441,443}, + {448,452,449}, + {448,449,447}, + {446,444,443}, + {446,443,445}, + {250,247,261}, + {250,261,428}, + {421,422,423}, + {421,423,419}, + {427,410,250}, + {417,403,401}, + {403,402,401}, + {420,392,412}, + {420,412,425}, + {420,425,424}, + {386,411,389}, + {383,382,381}, + {383,381,385}, + {378,379,404}, + {372,371,395}, + {372,395,397}, + {371,372,370}, + {361,359,360}, + {361,360,362}, + {368,350,351}, + {349,347,348}, + {356,355,344}, + {356,344,346}, + {344,341,340}, + {344,340,343}, + {338,337,336}, + {328,335,341}, + {324,352,351}, + {324,351,331}, + {320,144,336}, + {314,325,324}, + {322,308,309}, + {310,309,307}, + {287,286,289}, + {203,280,279}, + {203,279,205}, + {297,295,283}, + {297,283,284}, + {447,205,279}, + {274,384, 80}, + {274, 80,226}, + {266,267,379}, + {266,379,380}, + {225,257,246}, + {225,246,245}, + {256,254,253}, + {256,253,255}, + {430,247,250}, + {226,235,244}, + {226,244,245}, + {232,233,244}, + {232,244,241}, + {230, 18, 19}, + { 32, 31,228}, + {219,220, 86}, + {219, 86, 57}, + {226,213,235}, + {206, 7, 6}, + {122,201,101}, + {201,204,101}, + {180,196,197}, + {170,192,171}, + {200,190,189}, + {194,193,195}, + {183,181,180}, + {183,180,182}, + {155,154,168}, + {149,156,151}, + {149,151,148}, + {155,156,120}, + {145,142,143}, + {145,143,146}, + {136,137,140}, + {133,132,130}, + {128,129,116}, + {100,120,121}, + {110,112,113}, + {110,113,114}, + { 66, 65, 63}, + { 66, 63, 99}, + { 66, 99, 98}, + { 96, 46, 61}, + { 89, 88, 90}, + { 86, 87, 57}, + { 80, 78, 81}, + { 72, 69, 49}, + { 67, 48, 47}, + { 67, 47, 68}, + { 56, 55, 53}, + { 50, 49, 36}, + { 50, 36, 35}, + { 40, 39, 41}, + {242,243,229}, + {242,229,227}, + { 6, 37, 39}, + { 42, 47, 48}, + { 42, 48, 43}, + { 61, 46, 44}, + { 45, 70, 69}, + { 69, 70, 71}, + { 69, 71, 49}, + { 74, 78, 77}, + { 83, 84, 85}, + { 73, 74, 77}, + { 93, 96, 92}, + { 68, 46, 93}, + { 95, 99, 63}, + { 95, 63, 59}, + {115,108,110}, + {115,110,114}, + {125,126,127}, + {129,130,132}, + {137,133,138}, + {137,138,139}, + {148,146,143}, + {148,143,147}, + {119,118,154}, + {161,147,143}, + {165,164,151}, + {158,157,171}, + {158,171,172}, + {159,158,187}, + {159,187,186}, + {194,192,191}, + {194,191,193}, + {189,202,201}, + {182,197,184}, + {205, 8, 7}, + { 48,109,107}, + {218,219, 57}, + {218, 57, 56}, + {207,231,211}, + {232,230,231}, + {232,231,233}, + { 53, 52, 31}, + {388,411,386}, + {409,430,250}, + {262,429,254}, + {262,254,256}, + {442,444,428}, + {273,264,383}, + {273,383,384}, + {429,271,251}, + {429,251,254}, + {413,365,362}, + { 67,413,360}, + {282,283,295}, + {285,301,299}, + {202,281,280}, + {284,283,291}, + {284,291,289}, + {320,189,160}, + {308,306,307}, + {307,309,308}, + {319,317,330}, + {319,330,328}, + {353,352,324}, + {332,331,333}, + {340,341,338}, + {354,341,344}, + {349,358,357}, + {349,357,347}, + {364,355,356}, + {364,356,363}, + {364,365,366}, + {364,366,369}, + {374,376,402}, + {375, 92,373}, + { 77,389,390}, + {382,380,381}, + {389, 77,386}, + {393,394,412}, + {393,412,392}, + {401,394,416}, + {415,400,403}, + {411,410,427}, + {411,427,426}, + {422,420,424}, + {247,248,263}, + {247,263,261}, + {445,443, 14}, + {445, 14, 11}, + {449,450, 4}, + {449, 4, 5}, + {443,441, 17}, + {443, 17, 14}, + {436, 23, 17}, + {436, 17,441}, + {424,448,422}, + {448,423,422}, + {414,419,418}, + {414,418,413}, + {406,404,405}, + {399,397,395}, + {399,395,396}, + {420,416,392}, + {388,410,411}, + {386,384,383}, + {390, 88, 77}, + {375, 94, 92}, + {415,414, 68}, + {415, 68, 94}, + {370,374,402}, + {370,402,398}, + {361,357,358}, + {361,358,359}, + {125,348,126}, + {346,344,343}, + {340,338,339}, + {337,335,334}, + {337,334,336}, + {325,353,324}, + {324,331,332}, + {324,332,329}, + {323,322,309}, + {323,309,310}, + {294,295,297}, + {294,297,296}, + {289,286,285}, + {202,280,203}, + {288,307,303}, + {282,295,321}, + { 67,360,111}, + {418,423,367}, + {418,367,366}, + {272,252,251}, + {272,251,271}, + {272,271,270}, + {255,253,274}, + {265,266,380}, + {265,380,382}, + {442,428,261}, + {440,263,258}, + {440,258,260}, + {409,250,410}, + {255,226,245}, + {255,245,246}, + { 31,240,243}, + {236,234,235}, + {236,235,237}, + {233,225,245}, + {233,245,244}, + {220,221, 85}, + {220, 85, 86}, + { 81,213,226}, + { 81,226, 80}, + { 7,206,205}, + {186,184,198}, + {186,198,199}, + {204,203,205}, + {204,205,206}, + {195,193,196}, + {171,174,172}, + {173,174,175}, + {173,172,174}, + {155,167,166}, + {160,161,143}, + {160,143,144}, + {119,154,155}, + {148,151,150}, + {148,150,146}, + {140,137,139}, + {140,139,141}, + {127,126,130}, + {114,124,128}, + {114,128,115}, + {117,105,106}, + {117,106,116}, + {104,105,100}, + {104,100,103}, + { 59, 60, 91}, + { 97, 96, 61}, + { 97, 61, 64}, + { 91, 72, 89}, + { 87, 84, 79}, + { 87, 79, 76}, + { 78, 80, 77}, + { 49, 50, 74}, + { 60, 44, 45}, + { 61, 44, 58}, + { 51, 50, 35}, + { 51, 35, 34}, + { 39, 37, 41}, + { 33, 34, 9}, + { 33, 9, 12}, + { 0, 36, 37}, + { 0, 37, 6}, + { 40, 46, 47}, + { 40, 47, 42}, + { 53, 54, 56}, + { 65, 62, 63}, + { 72, 49, 73}, + { 79, 78, 75}, + { 79, 75, 76}, + { 52, 53, 76}, + { 92, 89, 90}, + { 96, 93, 46}, + {102,103,100}, + {102,100,101}, + {116,106,108}, + {116,108,115}, + {123,125,124}, + {116,115,128}, + {118,131,135}, + {140,135,136}, + {148,147,149}, + {120,119,155}, + {164,162,152}, + {164,152,150}, + {157,147,161}, + {157,161,170}, + {186,187,185}, + {186,185,184}, + {193,197,196}, + {202,203,204}, + {194,195,178}, + {198,184,197}, + { 67,111,109}, + { 38, 43,103}, + { 38,103,102}, + {214,223,222}, + {214,222,221}, + {214,221,220}, + {214,220,219}, + {214,219,218}, + {213,237,235}, + {221,222, 83}, + {221, 83, 85}, + { 15,229, 33}, + {227, 18,230}, + {227,230,232}, + { 52, 51,240}, + { 75, 78, 50}, + {408,430,409}, + {260,258,257}, + {260,257,259}, + {224,207,259}, + {268,269,405}, + {268,405,404}, + {413,362,360}, + {447, 8,205}, + {299,297,285}, + {189,281,202}, + {290,288,289}, + {290,289,291}, + {322,321,295}, + {322,295,294}, + {333,323,311}, + {333,311,320}, + {317,316,329}, + {320,160,144}, + {353,325,326}, + {329,332,334}, + {329,334,330}, + {339,338,141}, + {339,141,139}, + {348,345,126}, + {347,356,346}, + {123,349,125}, + {364,353,354}, + {364,354,355}, + {365,364,363}, + {376,391,394}, + {376,394,401}, + { 92,376,374}, + { 92,374,373}, + {377, 90, 88}, + {380,379,378}, + {380,378,381}, + {388,387,409}, + {388,409,410}, + {416,393,392}, + {399,398,402}, + {399,402,403}, + {250,428,427}, + {421,417,416}, + {421,416,420}, + {426,427,446}, + {426,446,451}, + {444,442,441}, + {452,451,450}, + {452,450,449} +}; + + +//***************************THE END OF FAMOUS BUNNY TRIMESH********************************************// + + +#endif //BUNNY_MESH_H_ diff --git a/Demos/GimpactTestDemo/CMakeLists.txt b/Demos/GimpactTestDemo/CMakeLists.txt new file mode 100644 index 0000000..31ed8fd --- /dev/null +++ b/Demos/GimpactTestDemo/CMakeLists.txt @@ -0,0 +1,58 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + +IF (USE_GLUT) + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath GIMPACTUtils ConvexDecomposition ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppGimpactTestDemo + GimpactTestDemo.cpp + GimpactTestDemo.h + main.cpp + ) + IF (WIN32) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppGimpactTestDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppGimpactTestDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF(WIN32) +ELSE(USE_GLUT) + + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath GIMPACTUtils ConvexDecomposition ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppGimpactTestDemo + WIN32 + GimpactTestDemo.cpp + GimpactTestDemo.h + ../OpenGL/Win32AppMain.cpp + Win32GimpactDemo.cpp + ) +ENDIF(USE_GLUT) diff --git a/Demos/GimpactTestDemo/GimpactTestDemo.cpp b/Demos/GimpactTestDemo/GimpactTestDemo.cpp new file mode 100644 index 0000000..9e54273 --- /dev/null +++ b/Demos/GimpactTestDemo/GimpactTestDemo.cpp @@ -0,0 +1,688 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "GimpactTestDemo.h" + +#define SHOW_NUM_DEEP_PENETRATIONS + +#include "LinearMath/btDefaultMotionState.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btDefaultMotionState.h" +#include "GLDebugFont.h" +/// Including GIMPACT here + + + +#include "GLDebugDrawer.h" + +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +/// Include Torus Mesh here +#include "TorusMesh.h" +#include "BunnyMesh.h" + +#ifdef SHOW_NUM_DEEP_PENETRATIONS +extern int gNumDeepPenetrationChecks; +extern int gNumSplitImpulseRecoveries; +extern int gNumGjkChecks; +#endif // + + + +//Real dts = 0.000001f; +Real dts = 1.0 / 60.0; + + +///************************************************************************************** +/// GIMPACT Test Demo made by DevO +/// +///************************************************************************************** + + + +GimpactConcaveDemo::~GimpactConcaveDemo() +{ + + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + delete m_dynamicsWorld; + + delete m_indexVertexArrays; + delete m_trimeshShape; + + delete m_indexVertexArrays2; + delete m_trimeshShape2; + + for (i=0;igetBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); + + + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btVector3 wireColor(1,0,0); + for (int i=0;igetCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(colObj); + + if (body && body->getMotionState()) + { + btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); + myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); + } else + { + colObj->getWorldTransform().getOpenGLMatrix(m); + } + + btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation + if (i & 1) + { + wireColor = btVector3(0.f,0.0f,1.f); + } + ///color differently for active, sleeping, wantsdeactivation states + if (colObj->getActivationState() == 1) //active + { + if (i & 1) + { + wireColor += btVector3 (0.8f,0.1f,0.1f); + } else + { + wireColor += btVector3 (0.5f,0.f,0.f); + } + } + if (colObj->getActivationState() == 2) //ISLAND_SLEEPING + { + if (i & 1) + { + wireColor += btVector3 (0.5f,0.8f, 0.5f); + } else + { + wireColor += btVector3 (0.f,0.5f,0.f); + } + } + + m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),worldBoundsMin,worldBoundsMax); + } + + + float xOffset = 10.f; + float yStart = 20.f; + float yIncr = 20.f; + char buf[124]; + + glColor3f(0, 0, 0); + + setOrthographicProjection(); + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"mouse to interact"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + /* glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"space to reset"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + */ + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"cursor keys and z,x to navigate"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"i to toggle simulation, s single step"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"q to quit"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,". to shoot TRIMESH (dot)"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + // not yet hooked up again after refactoring... + +/* glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"d to toggle deactivation"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; +*/ + + /* + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"a to draw temporal AABBs"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + */ + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"h to toggle help text"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + //bool useBulletLCP = !(getDebugMode() & btIDebugDraw::DBG_DisableBulletLCP); + + bool useCCD = ((getDebugMode() & btIDebugDraw::DBG_EnableCCD) != 0); + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + #ifdef SHOW_NUM_DEEP_PENETRATIONS + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gNumDeepPenetrationChecks = %d",gNumDeepPenetrationChecks); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gNumSplitImpulseRecoveries= %d",gNumSplitImpulseRecoveries); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gNumGjkChecks= %d",gNumGjkChecks); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + #endif //SHOW_NUM_DEEP_PENETRATIONS + + + resetPerspectiveProjection(); + + + } + +} + +//------------------------------------------------------------------------------ +void GimpactConcaveDemo::initGImpactCollision() +{ + /// Create Torus Shape + { + m_indexVertexArrays = new btTriangleIndexVertexArray + (NUM_TRIANGLES, + &gIndices[0][0], + 3*sizeof(int), + NUM_VERTICES, + (Real*) &gVertices[0],sizeof(Real)*3); + + +#ifdef BULLET_GIMPACT + #ifdef BULLET_GIMPACT_CONVEX_DECOMPOSITION + btGImpactConvexDecompositionShape * trimesh = new + btGImpactConvexDecompositionShape( + m_indexVertexArrays, btVector3(1.f,1.f,1.f),btScalar(0.01)); + trimesh->setMargin(0.07); + trimesh->updateBound(); + + + #else + btGImpactMeshShape * trimesh = new btGImpactMeshShape(m_indexVertexArrays); + trimesh->setLocalScaling(btVector3(1.f,1.f,1.f)); + #ifdef BULLET_TRIANGLE_COLLISION + trimesh->setMargin(0.07f); ///????? + #else + trimesh->setMargin(0.0f); + #endif + trimesh->updateBound(); + #endif + + m_trimeshShape = trimesh; + +#else + m_trimeshShape = new btGIMPACTMeshData(m_indexVertexArrays); +#endif + + } + + /// Create Bunny Shape + { + m_indexVertexArrays2 = new btTriangleIndexVertexArray + (BUNNY_NUM_TRIANGLES, + &gIndicesBunny[0][0], + 3*sizeof(int), + BUNNY_NUM_VERTICES, + (Real*) &gVerticesBunny[0],sizeof(Real)*3); +#ifdef BULLET_GIMPACT + + #ifdef BULLET_GIMPACT_CONVEX_DECOMPOSITION + btGImpactConvexDecompositionShape * trimesh2 = new + btGImpactConvexDecompositionShape( + m_indexVertexArrays2, btVector3(4.f,4.f,4.f),btScalar(0.01)); + trimesh2->setMargin(0.07); + trimesh2->updateBound(); + #else + btGImpactMeshShape * trimesh2 = new btGImpactMeshShape(m_indexVertexArrays2); + trimesh2->setLocalScaling(btVector3(4.f,4.f,4.f)); + #ifdef BULLET_TRIANGLE_COLLISION + trimesh2->setMargin(0.07f); ///????? + #else + trimesh2->setMargin(0.0f); + #endif + trimesh2->updateBound(); + #endif + + + + m_trimeshShape2 = trimesh2; +#else + m_trimeshShape2 = new btGIMPACTMeshData(m_indexVertexArrays2); + +#endif + + } + + + ///register GIMPACT algorithm + btCollisionDispatcher * dispatcher = static_cast(m_dynamicsWorld ->getDispatcher()); + +#ifdef BULLET_GIMPACT + btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher); +#else + btConcaveConcaveCollisionAlgorithm::registerAlgorithm(dispatcher); +#endif + + +} + +#ifndef BULLET_GIMPACT +btCollisionShape * GimpactConcaveDemo::createTorusShape() +{ + btGIMPACTMeshShape * newtrimeshShape = new btGIMPACTMeshShape(m_trimeshShape); + newtrimeshShape->setLocalScaling(btVector3(1.f,1.f,1.f)); + return newtrimeshShape; +} +btCollisionShape * GimpactConcaveDemo::createBunnyShape() +{ + btGIMPACTMeshShape * newtrimeshShape = new btGIMPACTMeshShape(m_trimeshShape2); + newtrimeshShape->setLocalScaling(btVector3(4.f,4.f,4.f)); + return newtrimeshShape; +} +#endif +//------------------------------------------------------------------------------ +void GimpactConcaveDemo::initPhysics() +{ + setTexturing(true); + setShadows(false); + + setCameraDistance(45.f); + + + /// Init Bullet + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + //btOverlappingPairCache* broadphase = new btSimpleBroadphase(); + //m_broadphase = new btSimpleBroadphase(); + + int maxProxies = 1024; + btVector3 worldAabbMin(-10000,-10000,-10000); + btVector3 worldAabbMax( 10000, 10000, 10000); + m_broadphase = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); + + m_constraintSolver = new btSequentialImpulseConstraintSolver(); + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_constraintSolver,m_collisionConfiguration); + + //create trimesh model and shape + initGImpactCollision(); + + + + /// Create Scene + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + + + btCollisionShape* staticboxShape1 = new btBoxShape(btVector3(200,1,200));//floor + m_collisionShapes.push_back(staticboxShape1); + startTransform.setOrigin(btVector3(0,-10,0)); + localCreateRigidBody(mass, startTransform,staticboxShape1); + + btCollisionShape* staticboxShape2 = new btBoxShape(btVector3(1,50,200));//left wall + m_collisionShapes.push_back(staticboxShape2); + startTransform.setOrigin(btVector3(-200,15,0)); + localCreateRigidBody(mass, startTransform,staticboxShape2); + + btCollisionShape* staticboxShape3 = new btBoxShape(btVector3(1,50,200));//right wall + m_collisionShapes.push_back(staticboxShape3); + startTransform.setOrigin(btVector3(200,15,0)); + localCreateRigidBody(mass, startTransform,staticboxShape3); + + btCollisionShape* staticboxShape4 = new btBoxShape(btVector3(200,50,1));//front wall + m_collisionShapes.push_back(staticboxShape4); + startTransform.setOrigin(btVector3(0,15,200)); + localCreateRigidBody(mass, startTransform,staticboxShape4); + + btCollisionShape* staticboxShape5 = new btBoxShape(btVector3(200,50,1));//back wall + m_collisionShapes.push_back(staticboxShape5); + startTransform.setOrigin(btVector3(0,15,-200)); + localCreateRigidBody(mass, startTransform,staticboxShape5); + + + //static plane + + btVector3 normal(-0.5,0.5,0.0); + normal.normalize(); + btCollisionShape* staticplaneShape6 = new btStaticPlaneShape(normal,0.0);// A plane + m_collisionShapes.push_back(staticplaneShape6); + startTransform.setOrigin(btVector3(0,-9,0)); + + btRigidBody* staticBody2 = localCreateRigidBody(mass, startTransform,staticplaneShape6 ); + + //another static plane + + normal.setValue(0.5,0.7,0.0); + //normal.normalize(); + btCollisionShape* staticplaneShape7 = new btStaticPlaneShape(normal,0.0);// A plane + m_collisionShapes.push_back(staticplaneShape7); + startTransform.setOrigin(btVector3(0,-10,0)); + + staticBody2 = localCreateRigidBody(mass, startTransform,staticplaneShape7 ); + + /// Create Static Torus + float height = 28; + float step = 2.5; + float massT = 1.0; + + startTransform.setOrigin(btVector3(0,height,-5)); + startTransform.setRotation(btQuaternion(3.14159265*0.5,0,3.14159265*0.5)); +#ifdef BULLET_GIMPACT + kinematicTorus = localCreateRigidBody(0.0, startTransform,m_trimeshShape); + +#else + kinematicTorus = localCreateRigidBody(0.0, startTransform,createTorusShape()); + +#endif //kinematicTorus->setCollisionFlags(kinematicTorus->getCollisionFlags()|btCollisionObject::CF_STATIC_OBJECT); + //kinematicTorus->setActivationState(ISLAND_SLEEPING); + + kinematicTorus->setCollisionFlags( kinematicTorus->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + kinematicTorus->setActivationState(DISABLE_DEACTIVATION); + + /// Kinematic + kinTorusTran = btVector3(-0.1,0,0); + kinTorusRot = btQuaternion(0,3.14159265*0.01,0); + +#ifdef TEST_GIMPACT_TORUS + +#ifdef BULLET_GIMPACT + /// Create dynamic Torus + for (int i=0;i<6;i++) + { + height -= step; + startTransform.setOrigin(btVector3(0,height,-5)); + startTransform.setRotation(btQuaternion(0,0,3.14159265*0.5)); + + btRigidBody* bodyA; + bodyA= localCreateRigidBody(massT, startTransform,m_trimeshShape); + + height -= step; + startTransform.setOrigin(btVector3(0,height,-5)); + startTransform.setRotation(btQuaternion(3.14159265*0.5,0,3.14159265*0.5)); + btRigidBody* bodyB; + bodyB= localCreateRigidBody(massT, startTransform,m_trimeshShape); + + } +#else + +/// Create dynamic Torus + for (int i=0;i<6;i++) + { + height -= step; + startTransform.setOrigin(btVector3(0,height,-5)); + startTransform.setRotation(btQuaternion(0,0,3.14159265*0.5)); + + btRigidBody* bodyA = localCreateRigidBody(massT, startTransform,createTorusShape()); + + height -= step; + startTransform.setOrigin(btVector3(0,height,-5)); + startTransform.setRotation(btQuaternion(3.14159265*0.5,0,3.14159265*0.5)); + btRigidBody* bodyB = localCreateRigidBody(massT, startTransform,createTorusShape()); + + } +#endif //no BULLET_GIMPACT +#endif + + startTransform.setIdentity(); + + + /// Create Dynamic Boxes + { + for (int i=0;i<8;i++) + { + btCollisionShape* boxShape = new btBoxShape(btVector3(1,1,1)); + m_collisionShapes.push_back(boxShape); + + startTransform.setOrigin(btVector3(2*i-5,2,-3)); + localCreateRigidBody(1, startTransform,boxShape); + } + } + + + //m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + +} + +//------------------------------------------------------------------------------ +void GimpactConcaveDemo::shootTrimesh(const btVector3& destination) +{ + + if (m_dynamicsWorld) + { + float mass = 4.f; + btTransform startTransform; + startTransform.setIdentity(); + btVector3 camPos = getCameraPosition(); + startTransform.setOrigin(camPos); +#ifdef BULLET_GIMPACT + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_trimeshShape2); +#else + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,createBunnyShape()); +#endif + btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed*0.25; + + body->getWorldTransform().setOrigin(camPos); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + } +} + +//------------------------------------------------------------------------------ +void GimpactConcaveDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +#define USE_KINEMATIC_GROUND +#ifdef USE_KINEMATIC_GROUND + //kinTorusTran = btVector3(-0.05,0,0); + //kinTorusRot = btQuaternion(0,3.14159265*0.1,0); + + //kinematic object + btCollisionObject* colObj = kinematicTorus; + //is this a rigidbody with a motionstate? then use the motionstate to update positions! + if (colObj && btRigidBody::upcast(colObj) && btRigidBody::upcast(colObj)->getMotionState()) + { + btTransform newTrans; + btRigidBody::upcast(colObj)->getMotionState()->getWorldTransform(newTrans); + + newTrans.getOrigin() += kinTorusTran; + newTrans.getBasis() = newTrans.getBasis() * btMatrix3x3(kinTorusRot); + if(newTrans.getOrigin().getX() > 6.0){ + newTrans.getOrigin().setX(6.0); + kinTorusTran = -kinTorusTran; + } + if(newTrans.getOrigin().getX() < -6.0){ + newTrans.getOrigin().setX(-6.0); + kinTorusTran = -kinTorusTran; + } + + btRigidBody::upcast(colObj)->getMotionState()->setWorldTransform(newTrans); + } else + { + /* + btTransform &newTrans = m_dynamicsWorld->getCollisionObjectArray()[0]->getWorldTransform(); + newTrans.getOrigin() += kinTorusTran; + if(newTrans.getOrigin().getX() > 0.1) kinTorusTran = -kinTorusTran; + if(newTrans.getOrigin().getX() < 0.1) kinTorusTran = -kinTorusTran; + */ + } + +#endif //USE_KINEMATIC_GROUND + + + unsigned long int time = getDeltaTimeMicroseconds()/btScalar(1000); + printf("%i time %i ms \n",m_steps_done,int(time)); + +//#ifdef BULLET_GIMPACT +// printf("%i time %.1f ms \n",m_steps_done,btGImpactCollisionAlgorithm::getAverageTreeCollisionTime()); +//#else +// printf("%i time %.1f ms \n",m_steps_done,btConcaveConcaveCollisionAlgorithm::getAverageTreeCollisionTime()); +//#endif + + //float dt = float(m_clock.getTimeMicroseconds()) * dts; //0.000001f; + float dt = btScalar(1./60.); + + + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + m_steps_done++; + + //m_dynamicsWorld->stepSimulation(dts); + + renderme(); + + glFlush(); + swapBuffers(); + +} + +//------------------------------------------------------------------------------ +void GimpactConcaveDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + +//------------------------------------------------------------------------------ +void GimpactConcaveDemo::clientResetScene() +{ + m_steps_done = 0; + DemoApplication::clientResetScene(); +} + +#define KEY_ESCAPE 0x1B + + +//------------------------------------------------------------------------------ +void GimpactConcaveDemo::keyboardCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case '.': + { + shootTrimesh(getCameraTargetPosition()); + break; + } + + case '2': + { + dts += 0.000001f; + break; + } + case '3': + { + dts -= 0.000001f; if(dts<0.000001f) dts = 0.000001f; + break; + } + + default: + DemoApplication::keyboardCallback(key, x, y); + } +} + + + diff --git a/Demos/GimpactTestDemo/GimpactTestDemo.h b/Demos/GimpactTestDemo/GimpactTestDemo.h new file mode 100644 index 0000000..0b83e49 --- /dev/null +++ b/Demos/GimpactTestDemo/GimpactTestDemo.h @@ -0,0 +1,145 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef TEST_CONCAVE_DEMO_H +#define TEST_CONCAVE_DEMO_H + + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +class btTriangleIndexVertexArray; +class btDefaultCollisionConfiguration; + +//#define BULLET_TRIANGLE_COLLISION 1 +#define BULLET_GIMPACT 1 +//#define BULLET_GIMPACT_CONVEX_DECOMPOSITION 1 + +#define TEST_GIMPACT_TORUS + +#ifdef BULLET_GIMPACT + +#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" + #ifdef BULLET_GIMPACT_CONVEX_DECOMPOSITION + #include "../Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h" + #endif + + +#else + +#include "BulletCollision/Gimpact/btConcaveConcaveCollisionAlgorithm.h" +#include "BulletCollision/Gimpact/btGIMPACTMeshShape.h" + +#endif + + + +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; + +///GimpactConcaveDemo shows usage of static concave triangle meshes +///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback +class GimpactConcaveDemo : public PlatformDemoApplication +{ + +public: + GimpactConcaveDemo() + : m_steps_done(0), + m_trimeshShape(NULL), + m_trimeshShape2(NULL), + m_indexVertexArrays(NULL), + m_indexVertexArrays2(NULL), + + + kinematicTorus(NULL), + + + m_gimpactCollisionCreateFunc(NULL), + m_collisionConfiguration(NULL), + + m_dispatcher(NULL), + + m_broadphase(NULL), + m_constraintSolver(NULL) + { + } + + virtual ~GimpactConcaveDemo(); + + + void initGImpactCollision(); + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene(); + + virtual void renderme(); + virtual void keyboardCallback(unsigned char key, int x, int y); + + ///Demo functions + void shootTrimesh(const btVector3& destination); + +public: ///data + unsigned int m_steps_done; + +#ifdef BULLET_GIMPACT + btCollisionShape *m_trimeshShape; + btCollisionShape *m_trimeshShape2; +#else + + btGIMPACTMeshData * m_trimeshShape; + btGIMPACTMeshData * m_trimeshShape2; + + btCollisionShape * createTorusShape(); + btCollisionShape * createBunnyShape(); + +#endif + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btTriangleIndexVertexArray *m_indexVertexArrays; + btTriangleIndexVertexArray *m_indexVertexArrays2; + + btVector3 kinTorusTran; + btQuaternion kinTorusRot; + btRigidBody *kinematicTorus; + + + btCollisionAlgorithmCreateFunc* m_gimpactCollisionCreateFunc; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + btCollisionDispatcher* m_dispatcher; + btBroadphaseInterface* m_broadphase; + btConstraintSolver* m_constraintSolver; + + static DemoApplication* Create() + { + GimpactConcaveDemo* demo = new GimpactConcaveDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +#endif //CONCAVE_DEMO_H + diff --git a/Demos/GimpactTestDemo/TorusMesh.h b/Demos/GimpactTestDemo/TorusMesh.h new file mode 100644 index 0000000..6919041 --- /dev/null +++ b/Demos/GimpactTestDemo/TorusMesh.h @@ -0,0 +1,921 @@ +#ifndef TORUS_MESH_H_ +#define TORUS_MESH_H_ + + +//*************************** NOT REALLY FAMOUS TORUS ********************************************// + +#define Real btScalar +const int NUM_TRIANGLES =600; +const int NUM_VERTICES = 300; +const int NUM_INDICES = NUM_TRIANGLES * 3; + + +static Real gVertices[NUM_VERTICES * 3] = { + Real(2.5), Real(0), Real(0), + Real(2.405), Real(0.294), Real(0), + Real(2.155), Real(0.476), Real(0), + Real(1.845), Real(0.476), Real(0), + Real(1.595), Real(0.294), Real(0), + Real(1.5), Real(0 ), Real(0), + Real(1.595), Real(-0.294), Real(0), + Real(1.845), Real(-0.476), Real(0), + Real(2.155), Real(-0.476), Real(0), + Real(2.405), Real(-0.294), Real(0), + Real(2.445), Real(0 ), Real(0.52 ), + Real(2.352), Real(0.294), Real(0.5 ), + Real(2.107), Real(0.476), Real(0.448), + Real(1.805), Real(0.476), Real(0.384), + Real(1.561), Real(0.294), Real(0.332), + Real(1.467), Real(0 ), Real(0.312), + Real(1.561), Real(-0.294), Real(0.332), + Real(1.805), Real(-0.476), Real(0.384), + Real(2.107), Real(-0.476), Real(0.448), + Real(2.352), Real(-0.294), Real(0.5 ), + Real(2.284), Real(0), Real(1.017), + Real(2.197), Real(0.294), Real(0.978), + Real(1.968), Real(0.476), Real(0.876), + Real(1.686), Real(0.476), Real(0.751), + Real(1.458), Real(0.294), Real(0.649), + Real(1.37), Real(0), Real(0.61 ), + Real(1.458), Real(-0.294), Real(0.649), + Real(1.686), Real(-0.476), Real(0.751), + Real(1.968), Real(-0.476), Real(0.876), + Real(2.197), Real(-0.294), Real(0.978), + Real(2.023), Real(0), Real(1.469), + Real(1.945), Real(0.294), Real(1.413), + Real(1.743), Real(0.476), Real(1.266), + Real(1.493), Real(0.476), Real(1.085), + Real(1.291), Real(0.294), Real(0.938), + Real(1.214), Real(0), Real(0.882), + Real(1.291), Real(-0.294), Real(0.938), + Real(1.493), Real(-0.476), Real(1.085), + Real(1.743), Real(-0.476), Real(1.266), + Real(1.945), Real(-0.294), Real(1.413), + Real(1.673), Real(0), Real(1.858), + Real(1.609), Real(0.294), Real(1.787), + Real(1.442), Real(0.476), Real(1.601), + Real(1.235), Real(0.476), Real(1.371), + Real(1.068), Real(0.294), Real(1.186), + Real(1.004), Real(0), Real(1.115), + Real(1.068), Real(-0.294), Real(1.186), + Real(1.235), Real(-0.476), Real(1.371), + Real(1.442), Real(-0.476), Real(1.601), + Real(1.609), Real(-0.294), Real(1.787), + Real(1.25), Real(0), Real(2.165), + Real(1.202), Real(0.294), Real(2.082), + Real(1.077), Real(0.476), Real(1.866), + Real(0.923), Real(0.476), Real(1.598), + Real(0.798), Real(0.294), Real(1.382), + Real(0.75), Real(0), Real(1.299), + Real(0.798), Real(-0.294), Real(1.382), + Real(0.923), Real(-0.476), Real(1.598), + Real(1.077), Real(-0.476), Real(1.866), + Real(1.202), Real(-0.294), Real(2.082), + Real(0.773), Real(0), Real(2.378), + Real(0.743), Real(0.294), Real(2.287), + Real(0.666), Real(0.476), Real(2.049), + Real(0.57), Real(0.476), Real(1.755), + Real(0.493), Real(0.294), Real(1.517), + Real(0.464), Real(0), Real(1.427), + Real(0.493), Real(-0.294), Real(1.517), + Real(0.57), Real(-0.476), Real(1.755), + Real(0.666), Real(-0.476), Real(2.049), + Real(0.743), Real(-0.294), Real(2.287), + Real(0.261), Real(0), Real(2.486), + Real(0.251), Real(0.294), Real(2.391), + Real(0.225), Real(0.476), Real(2.143), + Real(0.193), Real(0.476), Real(1.835), + Real(0.167), Real(0.294), Real(1.587), + Real(0.157), Real(0), Real(1.492), + Real(0.167), Real(-0.294), Real(1.587), + Real(0.193), Real(-0.476), Real(1.835), + Real(0.225), Real(-0.476), Real(2.143), + Real(0.251), Real(-0.294), Real(2.391), + Real(-0.261), Real(0), Real(2.486), + Real(-0.251), Real(0.294), Real(2.391), + Real(-0.225), Real(0.476), Real(2.143), + Real(-0.193), Real(0.476), Real(1.835), + Real(-0.167), Real(0.294), Real(1.587), + Real(-0.157), Real(0), Real(1.492), + Real(-0.167), Real(-0.294), Real(1.587), + Real(-0.193), Real(-0.476), Real(1.835), + Real(-0.225), Real(-0.476), Real(2.143), + Real(-0.251), Real(-0.294), Real(2.391), + Real(-0.773), Real(0), Real(2.378), + Real(-0.743), Real(0.294), Real(2.287), + Real(-0.666), Real(0.476), Real(2.049), + Real(-0.57), Real(0.476), Real(1.755), + Real(-0.493), Real(0.294), Real(1.517), + Real(-0.464), Real(0), Real(1.427), + Real(-0.493), Real(-0.294), Real(1.517), + Real(-0.57), Real(-0.476), Real(1.755), + Real(-0.666), Real(-0.476), Real(2.049), + Real(-0.743), Real(-0.294), Real(2.287), + Real(-1.25 ), Real(0), Real(2.165), + Real(-1.202), Real(0.294), Real(2.082), + Real(-1.077), Real(0.476), Real(1.866), + Real(-0.923), Real(0.476), Real(1.598), + Real(-0.798), Real(0.294), Real(1.382), + Real(-0.75), Real(0), Real(1.299), + Real(-0.798), Real(-0.294), Real(1.382), + Real(-0.923), Real(-0.476), Real(1.598), + Real(-1.077), Real(-0.476), Real(1.866), + Real(-1.202), Real(-0.294), Real(2.082), + Real(-1.673), Real(0), Real(1.858), + Real(-1.609), Real(0.294), Real(1.787), + Real(-1.442), Real(0.476), Real(1.601), + Real(-1.235), Real(0.476), Real(1.371), + Real(-1.068), Real(0.294), Real(1.186), + Real(-1.004), Real(0), Real(1.115), + Real(-1.068), Real(-0.294), Real(1.186), + Real(-1.235), Real(-0.476), Real(1.371), + Real(-1.442), Real(-0.476), Real(1.601), + Real(-1.609), Real(-0.294), Real(1.787), + Real(-2.023), Real(0), Real(1.469), + Real(-1.945), Real(0.294), Real(1.413), + Real(-1.743), Real(0.476), Real(1.266), + Real(-1.493), Real(0.476), Real(1.085), + Real(-1.291), Real(0.294), Real(0.938), + Real(-1.214), Real(0), Real(0.882), + Real(-1.291), Real(-0.294), Real(0.938), + Real(-1.493), Real(-0.476), Real(1.085), + Real(-1.743), Real(-0.476), Real(1.266), + Real(-1.945), Real(-0.294), Real(1.413), + Real(-2.284), Real(0), Real(1.017), + Real(-2.197), Real(0.294), Real(0.978), + Real(-1.968), Real(0.476), Real(0.876), + Real(-1.686), Real(0.476), Real(0.751), + Real(-1.458), Real(0.294), Real(0.649), + Real(-1.37), Real(0), Real(0.61 ), + Real(-1.458), Real(-0.294), Real(0.649), + Real(-1.686), Real(-0.476), Real(0.751), + Real(-1.968), Real(-0.476), Real(0.876), + Real(-2.197), Real(-0.294), Real(0.978), + Real(-2.445), Real(0), Real(0.52), + Real(-2.352), Real(0.294), Real(0.5), + Real(-2.107), Real(0.476), Real(0.448), + Real(-1.805), Real(0.476), Real(0.384), + Real(-1.561), Real(0.294), Real(0.332), + Real(-1.467), Real(0), Real(0.312), + Real(-1.561), Real(-0.294), Real(0.332), + Real(-1.805), Real(-0.476), Real(0.384), + Real(-2.107), Real(-0.476), Real(0.448), + Real(-2.352), Real(-0.294), Real(0.5), + Real(-2.5 ), Real(0), Real(0), + Real(-2.405), Real(0.294), Real(0), + Real(-2.155), Real(0.476), Real(0), + Real(-1.845), Real(0.476), Real(0), + Real(-1.595), Real(0.294), Real(0), + Real(-1.5), Real(0), Real(0), + Real(-1.595), Real(-0.294), Real(0), + Real(-1.845), Real(-0.476), Real(0), + Real(-2.155), Real(-0.476), Real(0), + Real(-2.405), Real(-0.294), Real(0), + Real(-2.445), Real(0), Real(-0.52), + Real(-2.352), Real(0.294), Real(-0.5), + Real(-2.107), Real(0.476), Real(-0.448), + Real(-1.805), Real(0.476), Real(-0.384), + Real(-1.561), Real(0.294), Real(-0.332), + Real(-1.467), Real(0), Real(-0.312), + Real(-1.561), Real(-0.294), Real(-0.332), + Real(-1.805), Real(-0.476), Real(-0.384), + Real(-2.107), Real(-0.476), Real(-0.448), + Real(-2.352), Real(-0.294), Real(-0.5), + Real(-2.284), Real(0), Real(-1.017), + Real(-2.197), Real(0.294), Real(-0.978), + Real(-1.968), Real(0.476), Real(-0.876), + Real(-1.686), Real(0.476), Real(-0.751), + Real(-1.458), Real(0.294), Real(-0.649), + Real(-1.37), Real(0), Real(-0.61), + Real(-1.458), Real(-0.294), Real(-0.649), + Real(-1.686), Real(-0.476), Real(-0.751), + Real(-1.968), Real(-0.476), Real(-0.876), + Real(-2.197), Real(-0.294), Real(-0.978), + Real(-2.023), Real(0), Real(-1.469), + Real(-1.945), Real(0.294), Real(-1.413), + Real(-1.743), Real(0.476), Real(-1.266), + Real(-1.493), Real(0.476), Real(-1.085), + Real(-1.291), Real(0.294), Real(-0.938), + Real(-1.214), Real(0), Real(-0.882), + Real(-1.291), Real(-0.294), Real(-0.938), + Real(-1.493), Real(-0.476), Real(-1.085), + Real(-1.743), Real(-0.476), Real(-1.266), + Real(-1.945), Real(-0.294), Real(-1.413), + Real(-1.673), Real(0), Real(-1.858), + Real(-1.609), Real(0.294), Real(-1.787), + Real(-1.442), Real(0.476), Real(-1.601), + Real(-1.235), Real(0.476), Real(-1.371), + Real(-1.068), Real(0.294), Real(-1.186), + Real(-1.004), Real(0), Real(-1.115), + Real(-1.068), Real(-0.294), Real(-1.186), + Real(-1.235), Real(-0.476), Real(-1.371), + Real(-1.442), Real(-0.476), Real(-1.601), + Real(-1.609), Real(-0.294), Real(-1.787), + Real(-1.25 ), Real(0), Real(-2.165), + Real(-1.202), Real(0.294), Real(-2.082), + Real(-1.077), Real(0.476), Real(-1.866), + Real(-0.923), Real(0.476), Real(-1.598), + Real(-0.798), Real(0.294), Real(-1.382), + Real(-0.75), Real(0), Real(-1.299), + Real(-0.798), Real(-0.294), Real(-1.382), + Real(-0.923), Real(-0.476), Real(-1.598), + Real(-1.077), Real(-0.476), Real(-1.866), + Real(-1.202), Real(-0.294), Real(-2.082), + Real(-0.773), Real(0), Real(-2.378), + Real(-0.743), Real(0.294), Real(-2.287), + Real(-0.666), Real(0.476), Real(-2.049), + Real(-0.57), Real(0.476), Real(-1.755), + Real(-0.493), Real(0.294), Real(-1.517), + Real(-0.464), Real(0), Real(-1.427), + Real(-0.493), Real(-0.294), Real(-1.517), + Real(-0.57), Real(-0.476), Real(-1.755), + Real(-0.666), Real(-0.476), Real(-2.049), + Real(-0.743), Real(-0.294), Real(-2.287), + Real(-0.261), Real(0), Real(-2.486), + Real(-0.251), Real(0.294), Real(-2.391), + Real(-0.225), Real(0.476), Real(-2.143), + Real(-0.193), Real(0.476), Real(-1.835), + Real(-0.167), Real(0.294), Real(-1.587), + Real(-0.157), Real(0), Real(-1.492), + Real(-0.167), Real(-0.294), Real(-1.587), + Real(-0.193), Real(-0.476), Real(-1.835), + Real(-0.225), Real(-0.476), Real(-2.143), + Real(-0.251), Real(-0.294), Real(-2.391), + Real(0.261), Real(0), Real(-2.486), + Real(0.251), Real(0.294), Real(-2.391), + Real(0.225), Real(0.476), Real(-2.143), + Real(0.193), Real(0.476), Real(-1.835), + Real(0.167), Real(0.294), Real(-1.587), + Real(0.157), Real(0), Real(-1.492), + Real(0.167), Real(-0.294), Real(-1.587), + Real(0.193), Real(-0.476), Real(-1.835), + Real(0.225), Real(-0.476), Real(-2.143), + Real(0.251), Real(-0.294), Real(-2.391), + Real(0.773), Real(0), Real(-2.378), + Real(0.743), Real(0.294), Real(-2.287), + Real(0.666), Real(0.476), Real(-2.049), + Real(0.57), Real(0.476), Real(-1.755), + Real(0.493), Real(0.294), Real(-1.517), + Real(0.464), Real(0), Real(-1.427), + Real(0.493), Real(-0.294), Real(-1.517), + Real(0.57), Real(-0.476), Real(-1.755), + Real(0.666), Real(-0.476), Real(-2.049), + Real(0.743), Real(-0.294), Real(-2.287), + Real(1.25), Real(0), Real(-2.165), + Real(1.202), Real(0.294), Real(-2.082), + Real(1.077), Real(0.476), Real(-1.866), + Real(0.923), Real(0.476), Real(-1.598), + Real(0.798), Real(0.294), Real(-1.382), + Real(0.75), Real(0), Real(-1.299), + Real(0.798), Real(-0.294), Real(-1.382), + Real(0.923), Real(-0.476), Real(-1.598), + Real(1.077), Real(-0.476), Real(-1.866), + Real(1.202), Real(-0.294), Real(-2.082), + Real(1.673), Real(0), Real(-1.858), + Real(1.609), Real(0.294), Real(-1.787), + Real(1.442), Real(0.476), Real(-1.601), + Real(1.235), Real(0.476), Real(-1.371), + Real(1.068), Real(0.294), Real(-1.186), + Real(1.004), Real(0), Real(-1.115), + Real(1.068), Real(-0.294), Real(-1.186), + Real(1.235), Real(-0.476), Real(-1.371), + Real(1.442), Real(-0.476), Real(-1.601), + Real(1.609), Real(-0.294), Real(-1.787), + Real(2.023), Real(0), Real(-1.469), + Real(1.945), Real(0.294), Real(-1.413), + Real(1.743), Real(0.476), Real(-1.266), + Real(1.493), Real(0.476), Real(-1.085), + Real(1.291), Real(0.294), Real(-0.938), + Real(1.214), Real(0), Real(-0.882), + Real(1.291), Real(-0.294), Real(-0.938), + Real(1.493), Real(-0.476), Real(-1.085), + Real(1.743), Real(-0.476), Real(-1.266), + Real(1.945), Real(-0.294), Real(-1.413), + Real(2.284), Real(0), Real(-1.017), + Real(2.197), Real(0.294), Real(-0.978), + Real(1.968), Real(0.476), Real(-0.876), + Real(1.686), Real(0.476), Real(-0.751), + Real(1.458), Real(0.294), Real(-0.649), + Real(1.37), Real(0), Real(-0.61 ), + Real(1.458), Real(-0.294), Real(-0.649), + Real(1.686), Real(-0.476), Real(-0.751), + Real(1.968), Real(-0.476), Real(-0.876), + Real(2.197), Real(-0.294), Real(-0.978), + Real(2.445), Real(0), Real(-0.52 ), + Real(2.352), Real(0.294), Real(-0.5 ), + Real(2.107), Real(0.476), Real(-0.448), + Real(1.805), Real(0.476), Real(-0.384), + Real(1.561), Real(0.294), Real(-0.332), + Real(1.467), Real(0), Real(-0.312), + Real(1.561), Real(-0.294), Real(-0.332), + Real(1.805), Real(-0.476), Real(-0.384), + Real(2.107), Real(-0.476), Real(-0.448), + Real(2.352), Real(-0.294), Real(-0.5) +}; + + +static int gIndices[NUM_TRIANGLES][3] = { + {0, 1, 11}, + {1, 2, 12}, + {2, 3, 13}, + {3, 4, 14}, + {4, 5, 15}, + {5, 6, 16}, + {6, 7, 17}, + {7, 8, 18}, + {8, 9, 19}, + {9, 0, 10}, + {10, 11, 21}, + {11, 12, 22}, + {12, 13, 23}, + {13, 14, 24}, + {14, 15, 25}, + {15, 16, 26}, + {16, 17, 27}, + {17, 18, 28}, + {18, 19, 29}, + {19, 10, 20}, + {20, 21, 31}, + {21, 22, 32}, + {22, 23, 33}, + {23, 24, 34}, + {24, 25, 35}, + {25, 26, 36}, + {26, 27, 37}, + {27, 28, 38}, + {28, 29, 39}, + {29, 20, 30}, + {30, 31, 41}, + {31, 32, 42}, + {32, 33, 43}, + {33, 34, 44}, + {34, 35, 45}, + {35, 36, 46}, + {36, 37, 47}, + {37, 38, 48}, + {38, 39, 49}, + {39, 30, 40}, + {40, 41, 51}, + {41, 42, 52}, + {42, 43, 53}, + {43, 44, 54}, + {44, 45, 55}, + {45, 46, 56}, + {46, 47, 57}, + {47, 48, 58}, + {48, 49, 59}, + {49, 40, 50}, + {50, 51, 61}, + {51, 52, 62}, + {52, 53, 63}, + {53, 54, 64}, + {54, 55, 65}, + {55, 56, 66}, + {56, 57, 67}, + {57, 58, 68}, + {58, 59, 69}, + {59, 50, 60}, + {60, 61, 71}, + {61, 62, 72}, + {62, 63, 73}, + {63, 64, 74}, + {64, 65, 75}, + {65, 66, 76}, + {66, 67, 77}, + {67, 68, 78}, + {68, 69, 79}, + {69, 60, 70}, + {70, 71, 81}, + {71, 72, 82}, + {72, 73, 83}, + {73, 74, 84}, + {74, 75, 85}, + {75, 76, 86}, + {76, 77, 87}, + {77, 78, 88}, + {78, 79, 89}, + {79, 70, 80}, + {80, 81, 91}, + {81, 82, 92}, + {82, 83, 93}, + {83, 84, 94}, + {84, 85, 95}, + {85, 86, 96}, + {86, 87, 97}, + {87, 88, 98}, + {88, 89, 99}, + {89, 80, 90}, + {90, 91, 101}, + {91, 92, 102}, + {92, 93, 103}, + {93, 94, 104}, + {94, 95, 105}, + {95, 96, 106}, + {96, 97, 107}, + {97, 98, 108}, + {98, 99, 109}, + {99, 90, 100}, + {100, 101, 111}, + {101, 102, 112}, + {102, 103, 113}, + {103, 104, 114}, + {104, 105, 115}, + {105, 106, 116}, + {106, 107, 117}, + {107, 108, 118}, + {108, 109, 119}, + {109, 100, 110}, + {110, 111, 121}, + {111, 112, 122}, + {112, 113, 123}, + {113, 114, 124}, + {114, 115, 125}, + {115, 116, 126}, + {116, 117, 127}, + {117, 118, 128}, + {118, 119, 129}, + {119, 110, 120}, + {120, 121, 131}, + {121, 122, 132}, + {122, 123, 133}, + {123, 124, 134}, + {124, 125, 135}, + {125, 126, 136}, + {126, 127, 137}, + {127, 128, 138}, + {128, 129, 139}, + {129, 120, 130}, + {130, 131, 141}, + {131, 132, 142}, + {132, 133, 143}, + {133, 134, 144}, + {134, 135, 145}, + {135, 136, 146}, + {136, 137, 147}, + {137, 138, 148}, + {138, 139, 149}, + {139, 130, 140}, + {140, 141, 151}, + {141, 142, 152}, + {142, 143, 153}, + {143, 144, 154}, + {144, 145, 155}, + {145, 146, 156}, + {146, 147, 157}, + {147, 148, 158}, + {148, 149, 159}, + {149, 140, 150}, + {150, 151, 161}, + {151, 152, 162}, + {152, 153, 163}, + {153, 154, 164}, + {154, 155, 165}, + {155, 156, 166}, + {156, 157, 167}, + {157, 158, 168}, + {158, 159, 169}, + {159, 150, 160}, + {160, 161, 171}, + {161, 162, 172}, + {162, 163, 173}, + {163, 164, 174}, + {164, 165, 175}, + {165, 166, 176}, + {166, 167, 177}, + {167, 168, 178}, + {168, 169, 179}, + {169, 160, 170}, + {170, 171, 181}, + {171, 172, 182}, + {172, 173, 183}, + {173, 174, 184}, + {174, 175, 185}, + {175, 176, 186}, + {176, 177, 187}, + {177, 178, 188}, + {178, 179, 189}, + {179, 170, 180}, + {180, 181, 191}, + {181, 182, 192}, + {182, 183, 193}, + {183, 184, 194}, + {184, 185, 195}, + {185, 186, 196}, + {186, 187, 197}, + {187, 188, 198}, + {188, 189, 199}, + {189, 180, 190}, + {190, 191, 201}, + {191, 192, 202}, + {192, 193, 203}, + {193, 194, 204}, + {194, 195, 205}, + {195, 196, 206}, + {196, 197, 207}, + {197, 198, 208}, + {198, 199, 209}, + {199, 190, 200}, + {200, 201, 211}, + {201, 202, 212}, + {202, 203, 213}, + {203, 204, 214}, + {204, 205, 215}, + {205, 206, 216}, + {206, 207, 217}, + {207, 208, 218}, + {208, 209, 219}, + {209, 200, 210}, + {210, 211, 221}, + {211, 212, 222}, + {212, 213, 223}, + {213, 214, 224}, + {214, 215, 225}, + {215, 216, 226}, + {216, 217, 227}, + {217, 218, 228}, + {218, 219, 229}, + {219, 210, 220}, + {220, 221, 231}, + {221, 222, 232}, + {222, 223, 233}, + {223, 224, 234}, + {224, 225, 235}, + {225, 226, 236}, + {226, 227, 237}, + {227, 228, 238}, + {228, 229, 239}, + {229, 220, 230}, + {230, 231, 241}, + {231, 232, 242}, + {232, 233, 243}, + {233, 234, 244}, + {234, 235, 245}, + {235, 236, 246}, + {236, 237, 247}, + {237, 238, 248}, + {238, 239, 249}, + {239, 230, 240}, + {240, 241, 251}, + {241, 242, 252}, + {242, 243, 253}, + {243, 244, 254}, + {244, 245, 255}, + {245, 246, 256}, + {246, 247, 257}, + {247, 248, 258}, + {248, 249, 259}, + {249, 240, 250}, + {250, 251, 261}, + {251, 252, 262}, + {252, 253, 263}, + {253, 254, 264}, + {254, 255, 265}, + {255, 256, 266}, + {256, 257, 267}, + {257, 258, 268}, + {258, 259, 269}, + {259, 250, 260}, + {260, 261, 271}, + {261, 262, 272}, + {262, 263, 273}, + {263, 264, 274}, + {264, 265, 275}, + {265, 266, 276}, + {266, 267, 277}, + {267, 268, 278}, + {268, 269, 279}, + {269, 260, 270}, + {270, 271, 281}, + {271, 272, 282}, + {272, 273, 283}, + {273, 274, 284}, + {274, 275, 285}, + {275, 276, 286}, + {276, 277, 287}, + {277, 278, 288}, + {278, 279, 289}, + {279, 270, 280}, + {280, 281, 291}, + {281, 282, 292}, + {282, 283, 293}, + {283, 284, 294}, + {284, 285, 295}, + {285, 286, 296}, + {286, 287, 297}, + {287, 288, 298}, + {288, 289, 299}, + {289, 280, 290}, + {290, 291, 1}, + {291, 292, 2}, + {292, 293, 3}, + {293, 294, 4}, + {294, 295, 5}, + {295, 296, 6}, + {296, 297, 7}, + {297, 298, 8}, + {298, 299, 9}, + {299, 290, 0}, + {0, 11, 10}, + {1, 12, 11}, + {2, 13, 12}, + {3, 14, 13}, + {4, 15, 14}, + {5, 16, 15}, + {6, 17, 16}, + {7, 18, 17}, + {8, 19, 18}, + {9, 10, 19}, + {10, 21, 20}, + {11, 22, 21}, + {12, 23, 22}, + {13, 24, 23}, + {14, 25, 24}, + {15, 26, 25}, + {16, 27, 26}, + {17, 28, 27}, + {18, 29, 28}, + {19, 20, 29}, + {20, 31, 30}, + {21, 32, 31}, + {22, 33, 32}, + {23, 34, 33}, + {24, 35, 34}, + {25, 36, 35}, + {26, 37, 36}, + {27, 38, 37}, + {28, 39, 38}, + {29, 30, 39}, + {30, 41, 40}, + {31, 42, 41}, + {32, 43, 42}, + {33, 44, 43}, + {34, 45, 44}, + {35, 46, 45}, + {36, 47, 46}, + {37, 48, 47}, + {38, 49, 48}, + {39, 40, 49}, + {40, 51, 50}, + {41, 52, 51}, + {42, 53, 52}, + {43, 54, 53}, + {44, 55, 54}, + {45, 56, 55}, + {46, 57, 56}, + {47, 58, 57}, + {48, 59, 58}, + {49, 50, 59}, + {50, 61, 60}, + {51, 62, 61}, + {52, 63, 62}, + {53, 64, 63}, + {54, 65, 64}, + {55, 66, 65}, + {56, 67, 66}, + {57, 68, 67}, + {58, 69, 68}, + {59, 60, 69}, + {60, 71, 70}, + {61, 72, 71}, + {62, 73, 72}, + {63, 74, 73}, + {64, 75, 74}, + {65, 76, 75}, + {66, 77, 76}, + {67, 78, 77}, + {68, 79, 78}, + {69, 70, 79}, + {70, 81, 80}, + {71, 82, 81}, + {72, 83, 82}, + {73, 84, 83}, + {74, 85, 84}, + {75, 86, 85}, + {76, 87, 86}, + {77, 88, 87}, + {78, 89, 88}, + {79, 80, 89}, + {80, 91, 90}, + {81, 92, 91}, + {82, 93, 92}, + {83, 94, 93}, + {84, 95, 94}, + {85, 96, 95}, + {86, 97, 96}, + {87, 98, 97}, + {88, 99, 98}, + {89, 90, 99}, + {90, 101, 100}, + {91, 102, 101}, + {92, 103, 102}, + {93, 104, 103}, + {94, 105, 104}, + {95, 106, 105}, + {96, 107, 106}, + {97, 108, 107}, + {98, 109, 108}, + {99, 100, 109}, + {100, 111, 110}, + {101, 112, 111}, + {102, 113, 112}, + {103, 114, 113}, + {104, 115, 114}, + {105, 116, 115}, + {106, 117, 116}, + {107, 118, 117}, + {108, 119, 118}, + {109, 110, 119}, + {110, 121, 120}, + {111, 122, 121}, + {112, 123, 122}, + {113, 124, 123}, + {114, 125, 124}, + {115, 126, 125}, + {116, 127, 126}, + {117, 128, 127}, + {118, 129, 128}, + {119, 120, 129}, + {120, 131, 130}, + {121, 132, 131}, + {122, 133, 132}, + {123, 134, 133}, + {124, 135, 134}, + {125, 136, 135}, + {126, 137, 136}, + {127, 138, 137}, + {128, 139, 138}, + {129, 130, 139}, + {130, 141, 140}, + {131, 142, 141}, + {132, 143, 142}, + {133, 144, 143}, + {134, 145, 144}, + {135, 146, 145}, + {136, 147, 146}, + {137, 148, 147}, + {138, 149, 148}, + {139, 140, 149}, + {140, 151, 150}, + {141, 152, 151}, + {142, 153, 152}, + {143, 154, 153}, + {144, 155, 154}, + {145, 156, 155}, + {146, 157, 156}, + {147, 158, 157}, + {148, 159, 158}, + {149, 150, 159}, + {150, 161, 160}, + {151, 162, 161}, + {152, 163, 162}, + {153, 164, 163}, + {154, 165, 164}, + {155, 166, 165}, + {156, 167, 166}, + {157, 168, 167}, + {158, 169, 168}, + {159, 160, 169}, + {160, 171, 170}, + {161, 172, 171}, + {162, 173, 172}, + {163, 174, 173}, + {164, 175, 174}, + {165, 176, 175}, + {166, 177, 176}, + {167, 178, 177}, + {168, 179, 178}, + {169, 170, 179}, + {170, 181, 180}, + {171, 182, 181}, + {172, 183, 182}, + {173, 184, 183}, + {174, 185, 184}, + {175, 186, 185}, + {176, 187, 186}, + {177, 188, 187}, + {178, 189, 188}, + {179, 180, 189}, + {180, 191, 190}, + {181, 192, 191}, + {182, 193, 192}, + {183, 194, 193}, + {184, 195, 194}, + {185, 196, 195}, + {186, 197, 196}, + {187, 198, 197}, + {188, 199, 198}, + {189, 190, 199}, + {190, 201, 200}, + {191, 202, 201}, + {192, 203, 202}, + {193, 204, 203}, + {194, 205, 204}, + {195, 206, 205}, + {196, 207, 206}, + {197, 208, 207}, + {198, 209, 208}, + {199, 200, 209}, + {200, 211, 210}, + {201, 212, 211}, + {202, 213, 212}, + {203, 214, 213}, + {204, 215, 214}, + {205, 216, 215}, + {206, 217, 216}, + {207, 218, 217}, + {208, 219, 218}, + {209, 210, 219}, + {210, 221, 220}, + {211, 222, 221}, + {212, 223, 222}, + {213, 224, 223}, + {214, 225, 224}, + {215, 226, 225}, + {216, 227, 226}, + {217, 228, 227}, + {218, 229, 228}, + {219, 220, 229}, + {220, 231, 230}, + {221, 232, 231}, + {222, 233, 232}, + {223, 234, 233}, + {224, 235, 234}, + {225, 236, 235}, + {226, 237, 236}, + {227, 238, 237}, + {228, 239, 238}, + {229, 230, 239}, + {230, 241, 240}, + {231, 242, 241}, + {232, 243, 242}, + {233, 244, 243}, + {234, 245, 244}, + {235, 246, 245}, + {236, 247, 246}, + {237, 248, 247}, + {238, 249, 248}, + {239, 240, 249}, + {240, 251, 250}, + {241, 252, 251}, + {242, 253, 252}, + {243, 254, 253}, + {244, 255, 254}, + {245, 256, 255}, + {246, 257, 256}, + {247, 258, 257}, + {248, 259, 258}, + {249, 250, 259}, + {250, 261, 260}, + {251, 262, 261}, + {252, 263, 262}, + {253, 264, 263}, + {254, 265, 264}, + {255, 266, 265}, + {256, 267, 266}, + {257, 268, 267}, + {258, 269, 268}, + {259, 260, 269}, + {260, 271, 270}, + {261, 272, 271}, + {262, 273, 272}, + {263, 274, 273}, + {264, 275, 274}, + {265, 276, 275}, + {266, 277, 276}, + {267, 278, 277}, + {268, 279, 278}, + {269, 270, 279}, + {270, 281, 280}, + {271, 282, 281}, + {272, 283, 282}, + {273, 284, 283}, + {274, 285, 284}, + {275, 286, 285}, + {276, 287, 286}, + {277, 288, 287}, + {278, 289, 288}, + {279, 280, 289}, + {280, 291, 290}, + {281, 292, 291}, + {282, 293, 292}, + {283, 294, 293}, + {284, 295, 294}, + {285, 296, 295}, + {286, 297, 296}, + {287, 298, 297}, + {288, 299, 298}, + {289, 290, 299}, + {290, 1, 0}, + {291, 2, 1}, + {292, 3, 2}, + {293, 4, 3}, + {294, 5, 4}, + {295, 6, 5}, + {296, 7, 6}, + {297, 8, 7}, + {298, 9, 8}, + {299, 0, 9}, +}; + + +#endif diff --git a/Demos/GimpactTestDemo/Win32GimpactDemo.cpp b/Demos/GimpactTestDemo/Win32GimpactDemo.cpp new file mode 100644 index 0000000..57cc15d --- /dev/null +++ b/Demos/GimpactTestDemo/Win32GimpactDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "GimpactTestDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new GimpactConcaveDemo(); +} + +#endif diff --git a/Demos/GimpactTestDemo/main.cpp b/Demos/GimpactTestDemo/main.cpp new file mode 100644 index 0000000..2deb726 --- /dev/null +++ b/Demos/GimpactTestDemo/main.cpp @@ -0,0 +1,13 @@ + +#include "GimpactTestDemo.h" +#include "GlutStuff.h" + +//################################## main ##################################### +int main(int argc,char** argv) +{ + + GimpactConcaveDemo* concaveDemo = new GimpactConcaveDemo(); /// This will not be Deleted!!! + concaveDemo->initPhysics(); + + return glutmain(argc, argv,640,480,"DevO,s GIMPACT Test Demo",concaveDemo); +} diff --git a/Demos/GjkConvexCastDemo/CMakeLists.txt b/Demos/GjkConvexCastDemo/CMakeLists.txt new file mode 100644 index 0000000..c053ac7 --- /dev/null +++ b/Demos/GjkConvexCastDemo/CMakeLists.txt @@ -0,0 +1,48 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppLinearConvexCastDemo + LinearConvexCastDemo.cpp + main.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppLinearConvexCastDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppLinearConvexCastDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppLinearConvexCastDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppLinearConvexCastDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppLinearConvexCastDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp new file mode 100644 index 0000000..29fbb09 --- /dev/null +++ b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + + + +/* + LinearConvexCastDemo implements an efficient continuous collision detection algorithm. + Both linear and angular velocities are supported. Gjk or Simplex based methods. + Motion using Exponential Map. + Comparison with Screwing Motion. + Also comparision with Algebraic CCD and Interval Arithmetic methods (Stephane Redon) +*/ + + +///Low level demo, doesn't include btBulletCollisionCommon.h +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btTransform.h" + +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" + + + +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" + + + +#include "GL_ShapeDrawer.h" +#include "LinearConvexCastDemo.h" +#include "GlutStuff.h" + +static btVoronoiSimplexSolver sVoronoiSimplexSolver; +btSimplexSolverInterface& gGjkSimplexSolver = sVoronoiSimplexSolver; + +static float yaw=0.f,pitch=0.f,roll=0.f; +static const int maxNumObjects = 4; +static const int numObjects = 2; + +static btPolyhedralConvexShape* shapePtr[maxNumObjects]; + +static btTransform tr[numObjects]; + + + +void LinearConvexCastDemo::initPhysics() +{ + + setCameraDistance(10.f); + + tr[0].setIdentity(); + tr[0].setOrigin( btVector3( 0.0f, 5.5f, 0.0f ) ); + + tr[1].setIdentity(); + tr[1].setOrigin( btVector3( 0.0f, 0.0f, 0.0f ) ); + + // Pyramide + float r = 1.0f; + float h = 2.0f; + + btConvexHullShape* shapeA = new btConvexHullShape; + shapeA->addPoint( btVector3( 0.0f, 0.75f * h, 0.0f ) ); + shapeA->addPoint( btVector3( -r, -0.25f * h, r ) ); + shapeA->addPoint( btVector3( r, -0.25f * h, r ) ); + shapeA->addPoint( btVector3( r, -0.25f * h, -r ) ); + shapeA->addPoint( btVector3( -r, -0.25f * h, -r ) ); + + + + // Triangle + btConvexHullShape* shapeB = new btConvexHullShape; + shapeB->addPoint( btVector3( 0.0f, 1.0f, 0.0f ) ); + shapeB->addPoint( btVector3( 1.0f, -1.0f, 0.0f ) ); + shapeB->addPoint( btVector3( -1.0f, -1.0f, 0.0f ) ); + + shapePtr[0] = shapeA; + shapePtr[1] = shapeB; + + shapePtr[0]->setMargin( 0.01f ); + shapePtr[1]->setMargin( 0.01f ); +} + +//to be implemented by the demo +void LinearConvexCastDemo::clientMoveAndDisplay() +{ + displayCallback(); +} + +LinearConvexCastDemo::~LinearConvexCastDemo() +{ + delete shapePtr[0]; + delete shapePtr[1]; +} + +void LinearConvexCastDemo::displayCallback(void) +{ + updateCamera(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + + GL_ShapeDrawer::drawCoordSystem(); + + + + static btScalar angle = 0.f; + angle+=getDeltaTimeMicroseconds()/1000000.0; + + tr[1].setRotation(btQuaternion(btVector3(1,0,0),angle)); + + btTransform toA, toB; + toA = tr[0]; + toA.setOrigin( btVector3( 0.0f, 0.f, 0.0f ) ); + toB = tr[1]; + toB.setOrigin( btVector3( 0.0f, 0.0f, 0.0f ) ); + + + gGjkSimplexSolver.reset(); + + + btVector3 worldBoundsMin(-1000,-1000,-1000); + btVector3 worldBoundsMax(1000,1000,1000); + + + //btGjkConvexCast convexCaster(shapePtr[ 0 ], shapePtr[ 1 ], &gGjkSimplexSolver ); + btSubsimplexConvexCast convexCaster( shapePtr[ 0 ], shapePtr[ 1 ], &gGjkSimplexSolver ); + + btConvexCast::CastResult result; + + result.m_hitPoint.setValue(0,0,0); + + convexCaster.calcTimeOfImpact( tr[ 0 ], toA, tr[ 1 ], toB, result ); + + ATTRIBUTE_ALIGNED16(btScalar) m1[16]; + ATTRIBUTE_ALIGNED16(btScalar) m2[16]; + ATTRIBUTE_ALIGNED16(btScalar) m3[16]; + + tr[ 0 ].getOpenGLMatrix( m1 ); + tr[ 1 ].getOpenGLMatrix( m2 ); + + btSphereShape sphere(0.2); + + btTransform tmp = tr[0]; + tmp.setOrigin(result.m_hitPoint); + tmp.getOpenGLMatrix(m3); + m_shapeDrawer->drawOpenGL( m3, &sphere, btVector3( 1, 0, 1 ), getDebugMode() ,worldBoundsMin,worldBoundsMax); + + + m_shapeDrawer->drawOpenGL( m1, shapePtr[ 0 ], btVector3( 1, 0, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax); + m_shapeDrawer->drawOpenGL( m2, shapePtr[ 1 ], btVector3( 1, 0, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax); + + btVector3 originA, originB; + originA.setInterpolate3( tr[ 0 ].getOrigin(), toA.getOrigin(), result.m_fraction ); + originB.setInterpolate3( tr[ 1 ].getOrigin(), toB.getOrigin(), result.m_fraction ); + + btTransform A = tr[ 0 ]; + A.setOrigin( originA ); + + btTransform B = tr[ 1 ]; + B.setOrigin( originB ); + + A.getOpenGLMatrix( m1 ); + B.getOpenGLMatrix( m2 ); + + m_shapeDrawer->drawOpenGL( m1, shapePtr[ 0 ], btVector3( 1, 1, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax); + m_shapeDrawer->drawOpenGL( m2, shapePtr[ 1 ], btVector3( 1, 1, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax); + + glFlush(); + glutSwapBuffers(); +} diff --git a/Demos/GjkConvexCastDemo/LinearConvexCastDemo.h b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.h new file mode 100644 index 0000000..9b64d28 --- /dev/null +++ b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.h @@ -0,0 +1,44 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef LINEAR_CONVEX_CAST_DEMO_H +#define LINEAR_CONVEX_CAST_DEMO_H + +#include "GlutDemoApplication.h" + +///LinearConvexCastDemo shows the working of the object sweep / pure-linear continuous collision detection query +class LinearConvexCastDemo : public GlutDemoApplication +{ + public: + + virtual ~LinearConvexCastDemo(); + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + LinearConvexCastDemo* demo = new LinearConvexCastDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } + +}; + +#endif //LINEAR_CONVEX_CAST_DEMO_H + diff --git a/Demos/GjkConvexCastDemo/main.cpp b/Demos/GjkConvexCastDemo/main.cpp new file mode 100644 index 0000000..3c2748a --- /dev/null +++ b/Demos/GjkConvexCastDemo/main.cpp @@ -0,0 +1,17 @@ + +#include "LinearConvexCastDemo.h" +#include "GlutStuff.h" + +int screenWidth = 640; +int screenHeight = 480; + +int main(int argc,char** argv) +{ + + LinearConvexCastDemo* linearCastDemo = new LinearConvexCastDemo(); + + linearCastDemo->initPhysics(); + + + return glutmain(argc, argv,screenWidth,screenHeight,"Linear Convex Cast Demo",linearCastDemo); +} diff --git a/Demos/Gpu2dDemo/BasicDemo.cpp b/Demos/Gpu2dDemo/BasicDemo.cpp new file mode 100644 index 0000000..47f9dc2 --- /dev/null +++ b/Demos/Gpu2dDemo/BasicDemo.cpp @@ -0,0 +1,808 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///The 3 following lines include the CPU implementation of the kernels, keep them in this order. +#include "BulletMultiThreaded/btGpuDefines.h" +#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "BulletMultiThreaded/btGpuUtilsSharedCode.h" + + + +#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" + +#include "btGpuDemoPairCache.h" + +#include "btGpuDemoDynamicsWorld.h" +#include "GLDebugFont.h" + +#define USE_CUDA_DEMO_PAIR_CASHE 0 + +#define SPEC_TEST 0 +#define OECAKE_LOADER 1 + +#ifdef _DEBUG +// #define LARGE_DEMO 0 + #define LARGE_DEMO 1 +#else + #define LARGE_DEMO 1 +#endif + +#if LARGE_DEMO + ///create 512 (8x8x8) dynamic object +// #define ARRAY_SIZE_X 116 +// #define ARRAY_SIZE_Y 116 + +// #define ARRAY_SIZE_X 228 +// #define ARRAY_SIZE_Y 228 +// #define ARRAY_SIZE_X 256 +// #define ARRAY_SIZE_Y 156 + #define ARRAY_SIZE_X 50 + #define ARRAY_SIZE_Y 100 + #define ARRAY_SIZE_Z 1 +#else + ///create 125 (5x5x5) dynamic object + #define ARRAY_SIZE_X 5 + #define ARRAY_SIZE_Y 5 +// #define ARRAY_SIZE_Z 5 + #define ARRAY_SIZE_Z 1 +#endif + + +//maximum number of objects (and allow user to shoot additional boxes) +#define NUM_SMALL_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z) +#define MAX_PROXIES (NUM_SMALL_PROXIES + 1024) +#define MAX_LARGE_PROXIES 0 +#define MAX_SMALL_PROXIES (MAX_PROXIES - MAX_LARGE_PROXIES) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +//#define SCALING 0.1 +#define SCALING 1 +#define START_POS_X 0 +#define START_POS_Y 0 +#define START_POS_Z 0 + +#include "BasicDemo.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include //printf debugging + +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" + +#ifdef BT_USE_CUDA +#include "../Extras/CUDA/btCudaBroadphase.h" +#else +#include "BulletMultiThreaded/btGpu3DGridBroadphase.h" +#endif + +btScalar gTimeStep = btScalar(1./60.); + +bool gbDrawBatches = false; +int gSelectedBatch = CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES; +#ifdef BT_USE_CUDA +bool gUseCPUSolver = false; +#else +bool gUseCPUSolver = true; +#endif //BT_USE_CUDA + +bool gUseBulletNarrowphase = false; + +#include "oecakeLoader.h" + + +class BasicDemoOecakeLoader : public BasicOECakeReader +{ + + BasicDemo* m_demo; + +public: + + BasicDemoOecakeLoader(BasicDemo* demo) + :m_demo(demo) + { + + } + + virtual void createBodyForCompoundShape(btCompoundShape* compoundTmpShape,bool addConstraint, const btTransform& worldTransform, btScalar mass) + { + + btDefaultMotionState* myMotionState= 0; + + btVector3 aabbMin,aabbMax; + compoundTmpShape->getAabb(btTransform::getIdentity(),aabbMin,aabbMax); + int numSpheres = compoundTmpShape->getNumChildShapes(); + btAssert(numSpheres>0); + if (numSpheres>8) + { + printf("error: exceeded 8 spheres\n"); + return; + } + + btVector3* positions = new btVector3[numSpheres]; + btScalar* radii = new btScalar[numSpheres]; + + for (int i=0;igetChildShape(i)->getShapeType()== SPHERE_SHAPE_PROXYTYPE); + btSphereShape* sphereShape = (btSphereShape*)compoundTmpShape->getChildShape(i); + radii[i]=sphereShape->getRadius(); + positions[i] = compoundTmpShape->getChildTransform(i).getOrigin(); + } + + btMultiSphereShape* multiSphere = new btMultiSphereShape(positions,radii,numSpheres); + m_demo->addCollisionShape(multiSphere); + + btVector3 localInertia(0,0,0); + if (mass) + { + myMotionState = new btDefaultMotionState(worldTransform); + multiSphere->calculateLocalInertia(mass,localInertia); + } + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btRigidBody* body = new btRigidBody(mass,myMotionState,multiSphere,localInertia); + body->setLinearFactor(btVector3(1,1,0)); + body->setAngularFactor(btVector3(0,0,1)); + + body->setWorldTransform(worldTransform); + + + m_demo->getDynamicsWorld()->addRigidBody(body); + + if (addConstraint) + { + btVector3 pivotInA(0,0,0); + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,pivotInA); + m_demo->getDynamicsWorld()->addConstraint(p2p); + } + } + +}; + + +void BasicDemo::clientMoveAndDisplay() +{ + updateCamera(); + glDisable(GL_LIGHTING); + glColor3f(1.f, 1.f, 1.f); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glDisable(GL_TEXTURE_2D); // we always draw wireframe in this demo + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { +#if USE_CUDA_DEMO_PAIR_CASHE + btGpuDemoPairCache* pc = (btGpuDemoPairCache*)m_dynamicsWorld->getPairCache(); + pc->m_numSmallProxies = m_dynamicsWorld->getNumCollisionObjects(); // - 1; // exclude floor +#endif + m_dynamicsWorld->stepSimulation(gTimeStep,0);//ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + renderme(); + + ms = getDeltaTimeMicroseconds(); + + glFlush(); + + glutSwapBuffers(); + +} + + + +void BasicDemo::displayCallback(void) { + + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + glutSwapBuffers(); +} + + +#define POS_OFFS_X (ARRAY_SIZE_X * SCALING + 20) +#define POS_OFFS_Y (ARRAY_SIZE_Y * SCALING + 10) +#define POS_OFFS_Z (ARRAY_SIZE_Z * SCALING) + +#if OECAKE_LOADER + btVector3 gWorldMin(-200, 0, 0); + btVector3 gWorldMax( 200, 200, 0); +#else + btVector3 gWorldMin(-POS_OFFS_X, -POS_OFFS_Y, -POS_OFFS_Z); + btVector3 gWorldMax( POS_OFFS_X, POS_OFFS_Y, POS_OFFS_Z); +#endif + +//btGpuDemoPairCache* gPairCache; +btOverlappingPairCache* gPairCache; + + +static btScalar fRandMinMax(btScalar fMin, btScalar fMax) +{ + btScalar fr = btScalar(rand()) / btScalar(RAND_MAX); + return fMax - (fMax - fMin) * fr; +} + + +void BasicDemo::initPhysics() +{ + setTexturing(false); + setShadows(false); + +#if OECAKE_LOADER + setCameraDistance(80.); + m_cameraTargetPosition.setValue(50, 10, 0); +#else + #if LARGE_DEMO + setCameraDistance(btScalar(SCALING*100.)); + #else + setCameraDistance(btScalar(SCALING*20.)); + #endif + m_cameraTargetPosition.setValue(START_POS_X, -START_POS_Y-20, START_POS_Z); +#endif + m_azi = btScalar(0.f); + m_ele = btScalar(0.f); + + ///collision configuration contains default setup for memory, collision setup + + btDefaultCollisionConstructionInfo dci; + dci.m_defaultMaxPersistentManifoldPoolSize=50000; + dci.m_defaultMaxCollisionAlgorithmPoolSize=50000; + + m_collisionConfiguration = new btDefaultCollisionConfiguration(dci); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new btEmptyAlgorithm::CreateFunc); + + m_dispatcher->setNearCallback(cudaDemoNearCallback); + + +#if USE_CUDA_DEMO_PAIR_CASHE + gPairCache = new (btAlignedAlloc(sizeof(btGpuDemoPairCache),16)) btGpuDemoPairCache(MAX_PROXIES, 24, MAX_SMALL_PROXIES); +#else + gPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16))btHashedOverlappingPairCache(); +#endif + + + btVector3 numOfCells = (gWorldMax - gWorldMin) / (2. * SCALING); + int numOfCellsX = (int)numOfCells[0]; + int numOfCellsY = (int)numOfCells[1]; + int numOfCellsZ = (int)numOfCells[2]; + +// m_broadphase = new btAxisSweep3(gWorldMin, gWorldMax, MAX_PROXIES,gPairCache); + m_broadphase = new btDbvtBroadphase(gPairCache); +// m_broadphase = new btGpu3DGridBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,24,24); +// m_broadphase = new btCudaBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,24,24); + + + ///the default constraint solver + m_solver = new btSequentialImpulseConstraintSolver(); + + btGpuDemoDynamicsWorld* pDdw = new btGpuDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, MAX_PROXIES); + m_dynamicsWorld = pDdw; + pDdw->getSimulationIslandManager()->setSplitIslands(true); + pDdw->setObjRad(SCALING); + pDdw->setWorldMin(gWorldMin); + pDdw->setWorldMax(gWorldMax); +// gUseCPUSolver = true; + pDdw->setUseCPUSolver(gUseCPUSolver); + gUseBulletNarrowphase = false; + pDdw->setUseBulletNarrowphase(gUseBulletNarrowphase); + +// m_dynamicsWorld->setGravity(btVector3(0,0,0)); + m_dynamicsWorld->setGravity(btVector3(0,-10.,0)); + m_dynamicsWorld->getSolverInfo().m_numIterations = 4; + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + + +#if 1 + #define SPRADIUS btScalar(SCALING*0.1f) + #define SPRPOS btScalar(SCALING*0.05f) + static btVector3 sSphPos[8]; + + for (int k=0;k<8;k++) + { + sSphPos[k].setValue((k-4)*0.25*SCALING,0,0); + } + + btVector3 inertiaHalfExtents(SPRADIUS, SPRADIUS, SPRADIUS); + static btScalar sSphRad[8] = + { +// SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, 0.3 + SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS + }; +// sSphPos[0].setX(sSphPos[0].getX()-0.15); + #undef SPR + btMultiSphereShape* colShape[2]; + colShape[0] = new btMultiSphereShape( sSphPos, sSphRad, 8); + colShape[1] = new btMultiSphereShape( sSphPos, sSphRad, 2); + + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(colShape[0]); + m_collisionShapes.push_back(colShape[1]); +#endif + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(0.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + +#if OECAKE_LOADER + BasicDemoOecakeLoader loader(this); + if (!loader.processFile("test1.oec")) + { + loader.processFile("../../test1.oec"); + } +#if 0 // perfomance test : work-in-progress + { // add more object, but share their shapes + int numNewObjects = 500; + mass = 1.f; + for(int n_obj = 0; n_obj < numNewObjects; n_obj++) + { + btDefaultMotionState* myMotionState= 0; + btVector3 localInertia(0,0,0); + btTransform worldTransform; + worldTransform.setIdentity(); + btScalar fx = fRandMinMax(-30., 30.); + btScalar fy = fRandMinMax(5., 30.); + worldTransform.setOrigin(btVector3(fx, fy, 0.f)); + int sz = m_collisionShapes.size(); + btMultiSphereShape* multiSphere = (btMultiSphereShape*)m_collisionShapes[1]; + myMotionState = new btDefaultMotionState(worldTransform); + multiSphere->calculateLocalInertia(mass, localInertia); + btRigidBody* body = new btRigidBody(mass,myMotionState,multiSphere,localInertia); + body->setLinearFactor(btVector3(1,1,0)); + body->setAngularFactor(btVector3(0,0,1)); + body->setWorldTransform(worldTransform); + getDynamicsWorld()->addRigidBody(body); + } + } +#endif + +#else +#if (!SPEC_TEST) + float start_x = START_POS_X - ARRAY_SIZE_X * SCALING; + float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING; + float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING; + + int collisionShapeIndex = 0; + for (int k=0;kcalculateLocalInertia(mass,localInertia); + + + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[collisionShapeIndex],localInertia); + collisionShapeIndex = 1 - collisionShapeIndex; + rbInfo.m_startWorldTransform=startTransform; + btRigidBody* body = new btRigidBody(rbInfo); + m_dynamicsWorld->addRigidBody(body); + } + } + } +#else//SPEC_TEST + // narrowphase test - 2 bodies at the same position + float start_x = START_POS_X; +// float start_y = START_POS_Y; + float start_y = gWorldMin[1] + SCALING * 0.7f + 5.f; + float start_z = START_POS_Z; + startTransform.setOrigin(SCALING*btVector3(start_x,start_y,start_z)); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[0],localInertia); + rbInfo.m_startWorldTransform=startTransform; + btRigidBody* body = new btRigidBody(rbInfo); + m_dynamicsWorld->addRigidBody(body); + + btPoint2PointConstraint * p2pConstr = new btPoint2PointConstraint(*body, btVector3(1., 0., 0.)); + m_dynamicsWorld->addConstraint(p2pConstr); + + startTransform.setOrigin(SCALING*btVector3(start_x-2.f, start_y,start_z)); + rbInfo.m_startWorldTransform=startTransform; + btRigidBody* body1 = new btRigidBody(rbInfo); + m_dynamicsWorld->addRigidBody(body1); + + p2pConstr = new btPoint2PointConstraint(*body, *body1, btVector3(-1., 0., 0.), btVector3(1., 0., 0.)); + m_dynamicsWorld->addConstraint(p2pConstr); + + +#endif//SPEC_TEST +#endif //OE_CAKE_LOADER + } + // now set Ids used by collision detector and constraint solver + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray(); + for(int i = 0; i < numObjects; i++) + { + btCollisionObject* colObj = collisionObjects[i]; + colObj->setCompanionId(i+1); // 0 reserved for the "world" object + btCollisionShape* pShape = colObj->getCollisionShape(); + int shapeType = pShape->getShapeType(); + if(shapeType == MULTI_SPHERE_SHAPE_PROXYTYPE) + { + btMultiSphereShape* pMs = (btMultiSphereShape*)pShape; + int numSpheres = pMs->getSphereCount(); + pDdw->addMultiShereObject(numSpheres, i + 1); + for(int j = 0; j < numSpheres; j++) + { + btVector3 sphPos = pMs->getSpherePosition(j); + float sphRad = pMs->getSphereRadius(j); + pDdw->addSphere(sphPos, sphRad); + } + } + else + { + btAssert(0); + } + } +#if OECAKE_LOADER + clientResetScene(); +#endif +} + +void BasicDemo::clientResetScene() +{ + DemoApplication::clientResetScene(); +#if OECAKE_LOADER + return; +#endif +#if SPEC_TEST + { + float start_x = START_POS_X; +// float start_y = START_POS_Y; + float start_y = gWorldMin[1] + SCALING * 0.7f + 5.f; + float start_z = START_POS_Z; + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray(); + btTransform startTransform; + startTransform.setIdentity(); + for(int n = 0; n < numObjects; n++) + { + btCollisionObject* colObj = collisionObjects[n]; + btRigidBody* rb = btRigidBody::upcast(colObj); + if(!n) + { + startTransform.setOrigin(SCALING*btVector3(start_x,start_y,start_z)); + } + else + { +// startTransform.setOrigin(SCALING*btVector3(start_x+0.1f,start_y+SCALING * 0.7f * 2.f, start_z)); + startTransform.setOrigin(SCALING*btVector3(start_x-2.f,start_y, start_z)); + } + rb->setCenterOfMassTransform(startTransform); + } + return; + } +#endif +// we don't use motionState, so reset transforms here + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray(); + + float start_x = START_POS_X - ARRAY_SIZE_X * SCALING; + float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING; + float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING; + btTransform startTransform; + startTransform.setIdentity(); + + for(int n = 0; n < numObjects; n++) + { + btCollisionObject* colObj = collisionObjects[n]; + colObj->setCompanionId(n); + btRigidBody* rb = btRigidBody::upcast(colObj); + int offs = ARRAY_SIZE_X * ARRAY_SIZE_Z; + int indx = n; + int ky = indx / offs; + indx -= ky * offs; + int kx = indx / ARRAY_SIZE_Z; + indx -= kx * ARRAY_SIZE_Z; + int kz = indx; + startTransform.setOrigin(SCALING*btVector3( + 2.0*SCALING*kx + start_x, + 2.0*SCALING*ky + start_y, + 2.0*SCALING*kz + start_z)); + rb->setCenterOfMassTransform(startTransform); + } +} + + + +void BasicDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jsetUseCPUSolver(gUseCPUSolver); + break; + } + case 'j' : + { + btGpuDemoDynamicsWorld* pDdw = (btGpuDemoDynamicsWorld*)m_dynamicsWorld; + gUseBulletNarrowphase = !gUseBulletNarrowphase; + pDdw->setUseBulletNarrowphase(gUseBulletNarrowphase); + if(gUseBulletNarrowphase) + { + m_dispatcher->setNearCallback(btCollisionDispatcher::defaultNearCallback); + } + else + { + m_dispatcher->setNearCallback(cudaDemoNearCallback); + } + break; + } + default : + { + DemoApplication::keyboardCallback(key, x, y); + } + break; + } + + if(key == ' ') + { +#if USE_CUDA_DEMO_PAIR_CASHE + ((btGpuDemoPairCache*)gPairCache)->reset(); +#endif + } +} + + + + +#define BATCH_NUM_COLORS 12 + +const float cBatchColorTab[BATCH_NUM_COLORS * 3] = + { + 1.f, 0.f, 0.f, + 0.f, 1.f, 0.f, + 0.f, 0.f, 1.f, + 1.f, 1.f, 0.f, + 0.f, 1.f, 1.f, + 1.f, 0.f, 1.f, + 1.f, .5f, 0.f, + .5f, 1.f, 0.f, + 0.f, 1.f, .5f, + 0.f, .5f, 1.f, + .5f, 0.f, 1.f, + 1.f, 0.f, .5f + }; + + +void BasicDemo::DrawConstraintInfo() +{ + int fontW = 10; // hack, could be changed + int fontH = 14; // hack, could be changed + char buf[32]; + float xOffs; + float yOffs = fontH * 2; + glDisable(GL_LIGHTING); + glColor3f(1, 1, 1); + sprintf(buf,"solver on %s", gUseCPUSolver ? "CPU" : "CUDA"); + xOffs = m_glutScreenWidth - (strlen(buf) + 1) * fontW; + GLDebugDrawString(xOffs, yOffs,buf); + yOffs += fontH; + btGpuDemoDynamicsWorld* cddw = (btGpuDemoDynamicsWorld*)m_dynamicsWorld; + for(int i = 0; i < CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES; i++) + { + const float* pCol = cBatchColorTab + i * 3; + glColor3f(pCol[0], pCol[1], pCol[2]); + sprintf(buf,"%2d : %5d", i, cddw->m_numInBatches[i]); + xOffs = m_glutScreenWidth - (strlen(buf) + 1) * fontW; + GLDebugDrawString(xOffs, yOffs,buf); + yOffs += fontH; + } +} + + +void BasicDemo::renderme() +{ + renderscene(0); + if(gbDrawBatches) + { + ((btGpuDemoDynamicsWorld*)m_dynamicsWorld)->debugDrawConstraints(gSelectedBatch, cBatchColorTab); + } + +// if (0) + if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0) + { + setOrthographicProjection(); + int xOffset = 10.f; + int yStart = 20.f; + int yIncr = 20.f; + showProfileInfo(xOffset, yStart, yIncr); + DrawConstraintInfo(); + outputDebugInfo(xOffset, yStart, yIncr); + resetPerspectiveProjection(); + } +} + + + +extern int gNumClampedCcdMotions; +#define SHOW_NUM_DEEP_PENETRATIONS 1 +#ifdef SHOW_NUM_DEEP_PENETRATIONS + extern int gNumDeepPenetrationChecks; + extern int gNumSplitImpulseRecoveries; + extern int gNumGjkChecks; + extern int gNumAlignedAllocs; + extern int gNumAlignedFree; + extern int gTotalBytesAlignedAllocs; +#endif // + + +void BasicDemo::outputDebugInfo(int & xOffset,int & yStart, int yIncr) +{ + char buf[124]; + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + + sprintf(buf,"mouse move+buttons to interact"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"space to reset"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"cursor keys and z,x to navigate"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"i to toggle simulation, s single step"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"q to quit"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"h to toggle help text"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"p to toggle profiling (+results to file)"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"c to toggle constraint drawing"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"b to draw single constraint batch"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"u to toggle between CPU and CUDA solvers"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"d to toggle between different batch builders"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + if (getDynamicsWorld()) + { + + sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects()); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs()); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + } +} // BasicDemo::outputDebugInfo() diff --git a/Demos/Gpu2dDemo/BasicDemo.h b/Demos/Gpu2dDemo/BasicDemo.h new file mode 100644 index 0000000..5596ba6 --- /dev/null +++ b/Demos/Gpu2dDemo/BasicDemo.h @@ -0,0 +1,99 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BASIC_DEMO_H +#define BASIC_DEMO_H + +#include "DemoApplication.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" + + +#ifdef BT_USE_CUDA +//#include "btCudaDemoPairCache.h" +//#include +#endif //BT_USE_CUDA + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; +#include "GlutDemoApplication.h" + +///BasicDemo is good starting point for learning the code base and porting. +class BasicDemo : public GlutDemoApplication +{ + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + int m_mouseButtons; + int m_mouseOldX; + int m_mouseOldY; + + public: + + BasicDemo() + { + } + virtual ~BasicDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + ///don't shoot a box in this demo ;-) + virtual void shootBox(const btVector3& dest) {} + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + virtual void clientResetScene(); + + static DemoApplication* Create() + { + BasicDemo* demo = new BasicDemo; + demo->myinit(); + demo->initPhysics(); + demo->m_mouseButtons = 0; + demo->m_mouseOldX = 0; + demo->m_mouseOldY = 0; + return demo; + } + + void DrawConstraintInfo(); + void outputDebugInfo(int & xOffset,int & yStart, int yIncr); + virtual void renderme(); + void addCollisionShape(btCollisionShape* pShape) { m_collisionShapes.push_back(pShape); } +}; + + +#endif //BASIC_DEMO_H + diff --git a/Demos/Gpu2dDemo/CMakeLists.txt b/Demos/Gpu2dDemo/CMakeLists.txt new file mode 100644 index 0000000..55ebb52 --- /dev/null +++ b/Demos/Gpu2dDemo/CMakeLists.txt @@ -0,0 +1,38 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppGpu2dDemo + main.cpp + BasicDemo.cpp + BasicDemo.h + btGpuDemoPairCache.cpp + btGpuDemoPairCache.h + btGpuDemo2dSharedTypes.h + btGpuDemo2dCpuFunc.cpp + btGpuDemoDynamicsWorld.cpp + btGpuDemoDynamicsWorld.h + oecakeLoader.cpp + oecakeLoader.h + btGpuDemo2dSharedCode.h + btGpuDemo2dSharedDefs.h +) + + diff --git a/Demos/Gpu2dDemo/Makefile.am b/Demos/Gpu2dDemo/Makefile.am new file mode 100644 index 0000000..71a2a28 --- /dev/null +++ b/Demos/Gpu2dDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=BasicDemo + +BasicDemo_SOURCES=BasicDemo.cpp BasicDemo.h main.cpp +BasicDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +BasicDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lbulletdynamics -lbulletcollision -lbulletmath @opengl_LIBS@ diff --git a/Demos/Gpu2dDemo/btGpuDemo2dCpuFunc.cpp b/Demos/Gpu2dDemo/btGpuDemo2dCpuFunc.cpp new file mode 100644 index 0000000..879375c --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemo2dCpuFunc.cpp @@ -0,0 +1,30 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "LinearMath/btQuickprof.h" + + +#include "LinearMath/btScalar.h" + +#include "btGpuDemo2dSharedTypes.h" + + + +#include "BulletMultiThreaded/btGpuDefines.h" +#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "btGpuDemo2dSharedCode.h" + diff --git a/Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h b/Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h new file mode 100644 index 0000000..7a82906 --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h @@ -0,0 +1,497 @@ +/* +Impulse based Rigid body simulation using CUDA +Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#define USE_FRICTION 1 +#define FRICTION_BOX_GROUND_FACT 0.05f +#define FRICTION_BOX_BOX_FACT 0.05f +#define USE_CENTERS 1 +//#include "LinearMath/btMinMax.h" + +//---------- C o n s t r a i n t s o l v e r d e m o ---------------------------- + +#define MAX_VTX_PER_OBJ 8 + +/* +BT_GPU___device__ void kill_me() +{ + char* badPtr = (char*)0xFFFFFFFF; + *badPtr = 10; +} +*/ + + +BT_GPU___global__ void clearAccumulationOfLambdaDtD(float* lambdaDtBox, int numConstraints, int numContPoints) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index < numConstraints) + { + for(int i=0; i < numContPoints; i++) + lambdaDtBox[numContPoints * index + i] = 0; + } +} + +#define SPHERE_FACT 1.0f + +BT_GPU___device__ void testSphSph(float3 aPos, float3 bPos, float radA, float radB, float4* pOut) +{ + float3 del = bPos - aPos; + float dist = BT_GPU_dot(del, del); + dist = sqrtf(dist); + float maxD = radA + radB; + + if(dist > maxD) + { + return; + } + float penetration = (radA + radB - dist) * SPHERE_FACT; +// float penetration = (dist - radA - radB) * SPHERE_FACT; + float3 normal; + if(dist > 0.f) + { + float fact = -1.0f/dist; +// float fact = 1.0f/dist; + normal = del * fact; + } + else + { + normal = BT_GPU_make_float3(1.f, 0.f, 0.f); + } +// float3 contact = (bPos + aPos + normal * (radB - radA)) * 0.5f; + float3 tmp = (normal * radA); + float3 contact = aPos - tmp; + + // now add point + int numPoints = 0; + for(int i = 0; i < MAX_VTX_PER_OBJ; i++) + { + if(pOut[i*2].w >= 0.f) + { + numPoints++; + } + } + if(numPoints < MAX_VTX_PER_OBJ) + { + pOut[numPoints * 2] = BT_GPU_make_float42(contact, penetration); + pOut[numPoints * 2 + 1] = BT_GPU_make_float42(normal, 0.f); + } +} // testSphSph() + + + +BT_GPU___global__ void setConstraintDataD(int2 *constraints, + int numConstraints, + float4 *pos, + float *rotation, + char* shapes, + int2* shapeIds, + btCudaPartProps pProp, + float4 *contact) +{ + int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + int aId,bId; + float3 aPos,bPos; +// float positionConstraint; +// float3 normal; + float aRot,bRot; + float sideLength2 = pProp.m_diameter*0.5f/sqrt(2.0f); + + if(idx < numConstraints) + { + aId=constraints[idx].x; + bId=constraints[idx].y; + + aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId)); + bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId)); + aRot= rotation[aId]; + bRot= rotation[bId]; + float cosA = cosf(aRot); + float sinA = sinf(aRot); + float cosB = cosf(bRot); + float sinB = sinf(bRot); + float4* shapeA = (float4*)(shapes + shapeIds[aId].x); + int numSphA = shapeIds[aId].y; + float4* shapeB = (float4*)(shapes + shapeIds[bId].x); + int numSphB = shapeIds[bId].y; + int i, j; + float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f); + float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f); + float3 bi = BT_GPU_make_float3(cosB, sinB, 0.f); + float3 bj = BT_GPU_make_float3(-sinB, cosB, 0.f); + float4* pOut = contact + idx * MAX_VTX_PER_OBJ * 2; + for(i = 0; i < MAX_VTX_PER_OBJ; i++) + { + pOut[i * 2].w = -1.f; + pOut[i * 2 + 1].w = 0.f; + } + for(i = 0; i < numSphA; i++) + { + float3 va = aPos; + float3 tmp = ai * shapeA[i].x; + float3 tmp2 = aj * shapeA[i].y; + + va += tmp; + va += tmp2; + + float radA = shapeA[i].w; + for(j = 0; j < numSphB; j++) + { + float3 vb = bPos; + float3 tmp =bi * shapeB[j].x; + float3 tmp2 = bj * shapeB[j].y; + vb += tmp; + vb += tmp2; + float radB = shapeB[j].w; + testSphSph(va, vb, radA, radB, pOut); + } + } + } +} + + +BT_GPU___device__ float computeImpulse1(float3 rVel, + float positionConstraint, + float3 cNormal, + float dt) +{ +// const float collisionConstant = 0.1f; +// const float baumgarteConstant = 0.5f; +// const float penetrationError = 0.02f; + const float collisionConstant = -0.1f; + const float baumgarteConstant = 0.3f; + const float penetrationError = 0.02f; + + float lambdaDt=0; + float3 impulse=BT_GPU_make_float3(0.f,0.f,0.f); + + if(positionConstraint > 0) + return lambdaDt; + +// positionConstraint = btMin(0.0f,positionConstraint+penetrationError); + positionConstraint = (positionConstraint+penetrationError) < 0.f ? (positionConstraint+penetrationError) : 0.0f; + + lambdaDt = -(BT_GPU_dot(cNormal,rVel)*(1+collisionConstant)); + lambdaDt -= (baumgarteConstant/dt*positionConstraint); + + return lambdaDt; +} + + +BT_GPU___global__ void collisionWithWallBoxD(float4 *pos, + float4 *vel, + float *rotation, + float *angVel, + char* shapes, + int2* shapeIds, + float* invMass, + btCudaPartProps pProp, + btCudaBoxProps gProp, + int nParticles, + float dt) +{ + int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + float3 aPos; + float aRot; + float positionConstraint; + float3 impulse; + + + if((idx > 0) && (idx < nParticles)) + { + float inv_mass = invMass[idx]; + if(inv_mass <= 0.f) + { + return; + } + aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,idx)); + aRot=rotation[idx]; + float4* shape = (float4*)(shapes + shapeIds[idx].x); + int numSph = shapeIds[idx].y; + float cosA = cosf(aRot); + float sinA = sinf(aRot); + float3 ai = BT_GPU_make_float3(cosA, sinA, 0.f); + float3 aj = BT_GPU_make_float3(-sinA, cosA, 0.f); + + for(int iVtx=0;iVtx < numSph; iVtx++){ + float3 aVel = BT_GPU_make_float3(vel[idx].x, vel[idx].y, vel[idx].z); + float aAngVel = angVel[idx]; + float3 rerVertex = ai * shape[iVtx].x; + float3 tmp = aj * shape[iVtx].y; + rerVertex += tmp; + float3 vPos = aPos + rerVertex; + float rad = shape[iVtx].w; + float3 vVel =aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel),rerVertex); +// float restitution=1.0; + float restitution=0.3f; + { + positionConstraint =vPos.y - rad - gProp.minY; + impulse =BT_GPU_make_float31(0.0f); + + if(positionConstraint < 0) + { + float3 groundNormal; + groundNormal = BT_GPU_make_float3(0.0f,1.0f,0.0f); + impulse =groundNormal* + restitution * computeImpulse1(vVel,positionConstraint, + groundNormal, + dt); +#if USE_FRICTION // only with ground for now + float3 lat_vel = vVel - groundNormal * BT_GPU_dot(groundNormal,vVel); + float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel); + if (lat_vel_len > 0) + { + lat_vel_len = sqrtf(lat_vel_len); + lat_vel *= 1.f/lat_vel_len; + float3 tmp = lat_vel * BT_GPU_dot(lat_vel, vVel) * FRICTION_BOX_GROUND_FACT; + impulse -= tmp; + } +#endif //USE_FRICTION + float4 tmp = BT_GPU_make_float42(impulse,0.0f); + vel[idx] += tmp; + float tmp2 = BT_GPU_cross(rerVertex,impulse).z; + angVel[idx] += tmp2; + } + } + + { + positionConstraint =vPos.x - rad - gProp.minX; + impulse =BT_GPU_make_float31(0.0f); + + if(positionConstraint < 0){ + impulse =BT_GPU_make_float3(1.0f,0.0f,0.0f)* restitution * + computeImpulse1(vVel,positionConstraint, + BT_GPU_make_float3(1.0f,0.0f,0.0f), + dt); + + float4 tmp = BT_GPU_make_float42(impulse,0.0f); + vel[idx] += tmp; + angVel[idx] += BT_GPU_cross(rerVertex,impulse).z; + } + } + + { + positionConstraint = gProp.maxX - vPos.x - rad; + impulse =BT_GPU_make_float31(0.0f); + + if(positionConstraint < 0){ + impulse =BT_GPU_make_float3(-1.0f,0.0f,0.0f)* restitution * + computeImpulse1(vVel,positionConstraint, + BT_GPU_make_float3(-1.0f,0.0f,0.0f), + dt); + + float4 tmp = BT_GPU_make_float42(impulse,0.0f); + vel[idx] += tmp; + angVel[idx] += BT_GPU_cross(rerVertex,impulse).z; + } + } + } + } +} + +BT_GPU___device__ void collisionResolutionBox( int constrId, + int2* constraints, + float4 *pos, + float4 *vel, + float *rotation, + float *angularVel, + float *lambdaDtBox, + float4* contact, + float* invMass, + btCudaPartProps pProp, + float dt) +{ +#if 1 + float3 relVel; + float3 impulse; + float lambdaDt; + float positionConstraint; + int aId=constraints[constrId].x; + int bId=constraints[constrId].y; + float3 aPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,aId)); + float3 bPos=BT_GPU_make_float34(BT_GPU_FETCH4(pos,bId)); + float3 aVel=BT_GPU_make_float34(vel[aId]); + float3 bVel=BT_GPU_make_float34(vel[bId]); + float aAngVel=angularVel[aId]; + float bAngVel=angularVel[bId]; + float4* pCont = contact + constrId * MAX_VTX_PER_OBJ * 2; + // test Vertices in A to Box B + for(int iVtx=0;iVtx= 0) + { + float3 contactNormal = BT_GPU_make_float34(pCont[iVtx * 2 + 1]); + relVel=(aVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,aAngVel), + contactPoint)) + -(bVel+BT_GPU_cross(BT_GPU_make_float3(0.0f,0.0f,bAngVel), + contactPoint+aPos-bPos)); + + lambdaDt= computeImpulse1(relVel,-positionConstraint, + contactNormal,dt); + + { + float rLambdaDt=lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx]; + float pLambdaDt=rLambdaDt; +// rLambdaDt=btMax(pLambdaDt+lambdaDt,0.0f); + rLambdaDt=(pLambdaDt+lambdaDt) > 0.0f ? (pLambdaDt+lambdaDt) : 0.0f; + lambdaDt=rLambdaDt-pLambdaDt; + lambdaDtBox[(MAX_VTX_PER_OBJ)*(2*constrId)+iVtx]=rLambdaDt; + } + impulse= contactNormal*lambdaDt*0.5; +#if USE_FRICTION + if(pCont[iVtx * 2 + 1].w <= 0) + { + float3 lat_vel = relVel - contactNormal * BT_GPU_dot(contactNormal, relVel); + float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel); + if (lat_vel_len > 0) + { + lat_vel_len = sqrtf(lat_vel_len); + lat_vel *= 1.f/lat_vel_len; + float3 tmp = lat_vel * BT_GPU_dot(lat_vel , relVel) * FRICTION_BOX_BOX_FACT; + impulse -= tmp; + } + } +#endif //USE_FRICTION + if(aId && (invMass[aId] > 0.f)) + { + aVel+= impulse; + aAngVel+= BT_GPU_cross(contactPoint, impulse).z; + } + if(bId && (invMass[bId] > 0.f)) + { + bVel-= impulse; + bAngVel-= BT_GPU_cross(contactPoint+aPos-bPos, impulse).z; + } + } + } + vel[aId]=BT_GPU_make_float42(aVel,0.0f); + vel[bId]=BT_GPU_make_float42(bVel,0.0f); + angularVel[aId]=aAngVel; + angularVel[bId]=bAngVel; +#endif +} + +BT_GPU___global__ void collisionBatchResolutionBoxD(int2 *constraints, + int *batch, + int nConstraints, + float4 *pos, + float4 *vel, + float *rotation, + float *angularVel, + float *lambdaDtBox, + float4* contact, + float* invMass, + btCudaPartProps pProp, + int iBatch, + float dt) +{ + int k_idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(k_idx < nConstraints) + { + int idx = batch[k_idx]; + collisionResolutionBox( idx, constraints, pos, vel, rotation, angularVel, lambdaDtBox, + contact, invMass, pProp, dt); + } +} + + +extern "C" +{ + +void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints)) +{ + if(!numConstraints) + { + return; + } + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, clearAccumulationOfLambdaDtD, (lambdaDtBox, numConstraints, numContPoints)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("clearAccumulationOfLambdaDtD kernel execution failed"); + +} + +void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* contact)) +{ + if(!numConstraints) + { + return; + } + int2* pConst = (int2*)constraints; + float4* pPos = (float4*)pos; + float4* pCont = (float4*)contact; + int2* pShapeIds = (int2*)shapeIds; + + BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4))); + + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, setConstraintDataD, (pConst,numConstraints,pPos,rotation,shapes,pShapeIds,pProp,pCont)); + BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("setConstraintDataD kernel execution failed"); +} + +void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,void* invMass,btCudaPartProps pProp, btCudaBoxProps gProp,int numObjs,float dt)) +{ + if(!numObjs) + { + return; + } + float4* pPos = (float4*)pos; + float4* pVel = (float4*)vel; + int2* pShapeIds = (int2*)shapeIds; + float* pInvMass = (float*)invMass; + BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4))); + + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numObjs, 256, numBlocks, numThreads); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionWithWallBoxD, (pPos,pVel,rotation,angVel,shapes, pShapeIds,pInvMass,pProp,gProp,numObjs,dt)); + + BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("collisionWithWallBoxD kernel execution failed"); +} + +void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,void* invMass,btCudaPartProps pProp,int iBatch,float dt)) +{ + if(!numConstraints) + { + return; + } + int2* pConstr = (int2*)constraints; + float4* pPos = (float4*)pos; + float4* pVel = (float4*)vel; + float4* pCont = (float4*)contact; + float* pInvMass = (float*)invMass; + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numConstraints, 128, numBlocks, numThreads); + BT_GPU_SAFE_CALL(BT_GPU_BindTexture(0, posTex, pPos, numObjs * sizeof(float4))); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionBatchResolutionBoxD, (pConstr,batch,numConstraints,pPos,pVel,rotation,angularVel,lambdaDtBox,pCont,pInvMass,pProp,iBatch,dt)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("collisionBatchResolutionBox2D kernel execution failed"); + BT_GPU_SAFE_CALL(BT_GPU_UnbindTexture(posTex)); + +} + + +} // extern "C" diff --git a/Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h b/Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h new file mode 100644 index 0000000..36bfe41 --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h @@ -0,0 +1,33 @@ +/* +Impulse based Rigid body simulation using CUDA +Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +//---------- C o n s t r a i n t s o l v e r d e m o ---------------------------- + + + + +extern "C" +{ + +void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints)); +void BT_GPU_PREF(setConstraintData(void* constraints,int numConstraints,int numObjs,void* pos,float *rotation,char* shapes,void* shapeIds,btCudaPartProps pProp,void* oContact)); +void BT_GPU_PREF(collisionWithWallBox(void* pos,void* vel,float *rotation,float *angVel,char* shapes,void* shapeIds,void* invMass,btCudaPartProps pProp,btCudaBoxProps gProp,int numObjs,float dt)); +void BT_GPU_PREF(collisionBatchResolutionBox(void* constraints,int *batch,int numConstraints,int numObjs,void *pos,void *vel,float *rotation,float *angularVel,float *lambdaDtBox,void* contact,void* invMass,btCudaPartProps pProp,int iBatch,float dt)); + +} // extern "C" + + diff --git a/Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h b/Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h new file mode 100644 index 0000000..469e949 --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h @@ -0,0 +1,35 @@ +/* +Impulse based Rigid body simulation using CUDA +Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------- C o n s t r a i n t s o l v e r d e m o ---------------------------- + +struct btCudaPartProps +{ + float m_mass; + float m_diameter; + float m_restCoeff; +}; + +struct btCudaBoxProps +{ + float minX; + float maxX; + float minY; + float maxY; + float minZ; + float maxZ; +}; + + diff --git a/Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.cpp b/Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.cpp new file mode 100644 index 0000000..9d9f208 --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.cpp @@ -0,0 +1,592 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btGpuDemoDynamicsWorld.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "LinearMath/btQuickprof.h" +#include "GlutStuff.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" + + + + +#define BT_GPU_PREF(func) btCuda_##func + +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "btGpuDemo2dSharedDefs.h" +#undef BT_GPU_PREF + +#define BT_GPU_PREF(func) btGpu_##func +#include "btGpuDemo2dSharedDefs.h" +#undef BT_GPU_PREF + + + +btGpuDemoDynamicsWorld* gpCudaDemoDynamicsWorld = NULL; + + + +void btGpuDemoDynamicsWorld::grabNonContactConstraintData() +{ + m_numNonContactConstraints = 0; + int numNonContactConstraints = getNumConstraints(); + for(int i = 0; i < numNonContactConstraints; i++) + { + btTypedConstraint* ct = m_constraints[i]; + int ctype = ct->getConstraintType(); + switch(ctype) + { + case POINT2POINT_CONSTRAINT_TYPE : + grabP2PConstraintData((btPoint2PointConstraint*)ct); + break; + default : + // warning (not supported) here? + break; + } + } +} + + + +void btGpuDemoDynamicsWorld::grabContactData() +{ + int i; + btDispatcher* dispatcher = getDispatcher(); + btPersistentManifold** manifoldPtr = dispatcher->getInternalManifoldPointer(); + int numManifolds = dispatcher->getNumManifolds(); + btPersistentManifold* manifold = 0; + m_totalNumConstraints = 0; + for(i = 0; i < numManifolds; i++) + { + manifold = manifoldPtr[i]; + int numPoints = manifold->getNumContacts(); + if(!numPoints) + { + continue; + } + int numActualPoints = 0; + for(int n = 0; n < numPoints; n++) + { + btManifoldPoint& cp = manifold->getContactPoint(n); + if (cp.m_distance1<=0) + { + numActualPoints++; + } + } + if (!numActualPoints) + continue; + + btRigidBody *rbA, *rbB; + rbA = (btRigidBody*)manifold->getBody0(); + rbB = (btRigidBody*)manifold->getBody1(); + int idA = rbA->getCompanionId(); + int idB = rbB->getCompanionId(); + btVector3* pConstrData = (btVector3*)(m_hContact + m_totalNumConstraints * 2 * m_maxVtxPerObj); + if(idA < idB) + { + m_hIds[m_totalNumConstraints].x = idA; + m_hIds[m_totalNumConstraints].y = idB; + + for(int n = 0; n < numPoints; n++) + { + btManifoldPoint& cp = manifold->getContactPoint(n); + btVector3 v = cp.getPositionWorldOnA(); + pConstrData[0] = cp.getPositionWorldOnA(); + float dist = cp.getDistance(); + if(dist > 0.f) + { + pConstrData[0][3] = -1.f; + } + else + { + pConstrData[0][3] = -dist; + } + pConstrData[1] = cp.m_normalWorldOnB; + pConstrData[1][3] = 0.f; + pConstrData += 2; + } + } + else + { // should never happen + btAssert(0); + } + for(int n = numPoints; n < m_maxVtxPerObj; n++) + { + pConstrData[0][3] = -1.f; + pConstrData += 2; + } + m_totalNumConstraints++; + } +} + + + +void btGpuDemoDynamicsWorld::grabP2PConstraintData(btPoint2PointConstraint* ct) +{ + btRigidBody& bodyA = ct->getRigidBodyA(); + btTransform trA = bodyA.getCenterOfMassTransform(); + btVector3 pivotA = trA.getBasis() * ct->getPivotInA(); + btRigidBody& bodyB = ct->getRigidBodyB(); + btTransform trB = bodyB.getCenterOfMassTransform(); + btVector3 pivotB = trB.getBasis() * ct->getPivotInB(); + btVector3 pivotA_W = pivotA + trA.getOrigin(); + btVector3 pivotB_W = pivotB + trB.getOrigin(); + btVector3 delta = pivotB_W - pivotA_W; + int idA = bodyA.getCompanionId(); + int idB = bodyB.getCompanionId(); + m_hIds[m_totalNumConstraints].x = idA; + m_hIds[m_totalNumConstraints].y = (idB > 0) ? idB : 0; + btVector3* pConstrData = (btVector3*)(m_hContact + m_totalNumConstraints * 2 * m_maxVtxPerObj); + for(int k = 0; k < 2; k++) + { + btScalar penetration = delta[k]; + btScalar sign = (penetration < 0) ? btScalar(-1.f) : btScalar(1.f); + btVector3 normal = btVector3(0., 0., 0.); + normal[k] = sign; + penetration *= sign; + pConstrData[0] = pivotA_W; + pConstrData[0][3] = penetration; + pConstrData[1] = normal; + pConstrData[1][3] = btScalar(1.f); + pConstrData += 2; + } + for(int n = 2; n < m_maxVtxPerObj; n++) + { + pConstrData[0][3] = -1.f; + pConstrData += 2; + } + m_totalNumConstraints++; + m_numNonContactConstraints++; +} + + + +void btGpuDemoDynamicsWorld::grabData() +{ + BT_PROFILE("grab data"); + m_numObj = getNumCollisionObjects(); + m_hPos[0].x = m_hPos[0].y = m_hPos[0].z = m_hPos[0].w = 0.f; + m_hRot[0] = 0.f; + m_hVel[0].x = m_hVel[0].y = m_hVel[0].z = m_hVel[0].w = 0.f; + m_hAngVel[0] = 0.f; + for(int i = 0; i < m_numObj; i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + btRigidBody* rb = btRigidBody::upcast(colObj); + btVector3 v; + v = rb->getCenterOfMassPosition(); + m_hPos[i+1] = *((float4*)&v); + const btTransform& tr = rb->getCenterOfMassTransform(); + v = tr.getBasis().getColumn(0); + float rot = btAtan2(v[1], v[0]); + m_hRot[i+1] = rot; + v = rb->getLinearVelocity(); + m_hVel[i+1] = *((float4*)&v); + v = rb->getAngularVelocity(); + m_hAngVel[i+1] = v[2]; + if(m_copyMassDataToGPU) + { + m_hInvMass[i+1] = rb->getInvMass(); + } + } + if(m_useBulletNarrowphase) + { + grabContactData(); + } + grabNonContactConstraintData(); +} + + + +void btGpuDemoDynamicsWorld::createBatches2() +{ + BT_PROFILE("create batches"); + int sz = m_maxObjs * m_maxNeighbors; + for(int idx = 0; idx < sz; idx++) + { + m_hBatchIds[idx] = -1; + } + for(int i = 0; i < m_totalNumConstraints; i++) + { + m_hConstraintUsed[i] = 0; + } + int curBatchId=0; + int* pBatchIds = m_hBatchIds; + for(int stage = 0; stage < m_maxBatches; stage++) + { + bool isLast = (stage == m_maxBatches-1); + for(int j = 0; j < m_numObj + 1; j++) + { + m_hConstraintCounter[j] = 0; + } + int numInBatch = 0; + for(int i = 0; i < m_totalNumConstraints; i++) + { + if(m_hConstraintUsed[i]) + { + continue; + } + int2 ids = m_hIds[i]; + if(!isLast) + { + if((m_hConstraintCounter[ids.x] == 0) && (m_hConstraintCounter[ids.y] == 0)) + { + m_hConstraintCounter[ids.x]=1; + m_hConstraintCounter[ids.y]=1; + pBatchIds[numInBatch]=i; + numInBatch++; + m_hConstraintUsed[i] = 1; + } + } + else + { + pBatchIds[numInBatch]=i; + numInBatch++; + m_hConstraintUsed[i] = 1; + } + } + m_numInBatches[stage] = numInBatch; + pBatchIds += numInBatch; + } +} + + + +void btGpuDemoDynamicsWorld::writebackData() +{ + BT_PROFILE("copy velocity into btRigidBody"); + for(int i = 0; i < m_numObj; i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + btRigidBody* rb = btRigidBody::upcast(colObj); + btVector3 v; + v = *((btVector3*)(m_hVel + i + 1)); + v[2] = 0.f; + rb->setLinearVelocity(v); + v[0] = btScalar(0.f); + v[1] = btScalar(0.f); + v[2] = m_hAngVel[i + 1]; + rb->setAngularVelocity(v); + } +} + + + +void btGpuDemoDynamicsWorld::copyDataToGPU() +{ + BT_PROFILE("copyDataToGPU"); + +#ifdef BT_USE_CUDA + + btCuda_copyArrayToDevice(m_dIds, m_hIds, sizeof(int2) * m_totalNumConstraints); + btCuda_copyArrayToDevice(m_dBatchIds, m_hBatchIds, sizeof(int) * m_totalNumConstraints); + + if(m_numNonContactConstraints) + { // non-contact constraints are set up by CPU, so copy data to GPU + int nonContConstrOffs = (m_totalNumConstraints - m_numNonContactConstraints) * 2 * m_maxVtxPerObj; + int nonContConstrSize = 2 * m_numNonContactConstraints * m_maxVtxPerObj; + btCuda_copyArrayToDevice(m_dContact + nonContConstrOffs, m_hContact + nonContConstrOffs, sizeof(float4) * nonContConstrSize); + } + + if(m_numSimStep & 1) + { + m_dcPos = m_dpPos; + m_dcVel = m_dpVel; + m_dcRot = m_dpRot; + m_dcAngVel = m_dpAngVel; + } + else + { + m_dcPos = m_dPos; + m_dcVel = m_dVel; + m_dcRot = m_dRot; + m_dcAngVel = m_dAngVel; + } + btCuda_copyArrayToDevice(m_dcPos, m_hPos, (m_numObj + 1) * sizeof(float4)); + btCuda_copyArrayToDevice(m_dcVel, m_hVel, (m_numObj + 1) * sizeof(float4)); + btCuda_copyArrayToDevice(m_dcRot, m_hRot, (m_numObj + 1) * sizeof(float)); + btCuda_copyArrayToDevice(m_dcAngVel, m_hAngVel, (m_numObj + 1) * sizeof(float)); + if(m_copyShapeDataToGPU) + { + btCuda_copyArrayToDevice(m_dShapeBuffer, m_hShapeBuffer, m_firstFreeShapeBufferOffset); + btCuda_copyArrayToDevice(m_dShapeIds, m_hShapeIds, (m_numObj + 1) * sizeof(int2)); + m_copyShapeDataToGPU = false; + } + if(m_copyMassDataToGPU) + { + btCuda_copyArrayToDevice(m_dInvMass, m_hInvMass, (m_numObj + 1) * sizeof(float)); + m_copyMassDataToGPU = false; + } +#endif //BT_USE_CUDA + +} + + + +void btGpuDemoDynamicsWorld::setConstraintData(btCudaPartProps& partProps) +{ + BT_PROFILE("set constraint data"); + partProps.m_mass = 1.0f; + partProps.m_diameter = m_objRad * 2.0f; + partProps.m_restCoeff = 1.0f; +#ifdef BT_USE_CUDA + btCuda_clearAccumulationOfLambdaDt(m_dLambdaDtBox, m_totalNumConstraints, m_maxVtxPerObj * 2); + if(!m_useBulletNarrowphase) + { + btCuda_setConstraintData(m_dIds, m_totalNumConstraints - m_numNonContactConstraints, m_numObj + 1, m_dcPos, m_dcRot, m_dShapeBuffer, m_dShapeIds, + partProps, m_dContact); + } +#endif //BT_USE_CUDA + +} + + + +void btGpuDemoDynamicsWorld::copyDataFromGPU() +{ + BT_PROFILE("copy velocity data from device"); +#ifdef BT_USE_CUDA + btCuda_copyArrayFromDevice(m_hVel, m_dcVel, (m_numObj + 1) * sizeof(float4)); + btCuda_copyArrayFromDevice(m_hAngVel, m_dcAngVel, (m_numObj + 1) * sizeof(float)); +#endif //BT_USE_CUDA +} + + + +void btGpuDemoDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) +{ + if(m_useCPUSolver) + { + solveConstraintsCPU2(solverInfo); + } + else + { + solveConstraints2(solverInfo); + } + m_totalNumConstraints = 0; +} + + + +void btGpuDemoDynamicsWorld::solveConstraints2(btContactSolverInfo& solverInfo) +{ +#ifdef BT_USE_CUDA + BT_PROFILE("solveConstraints"); + grabData(); + createBatches2(); + copyDataToGPU(); + + btCudaPartProps partProps; + setConstraintData(partProps); + + btCudaBoxProps boxProps; + boxProps.minX = m_worldMin[0]; + boxProps.maxX = m_worldMax[0]; + boxProps.minY = m_worldMin[1]; + boxProps.maxY = m_worldMax[1]; + { + BT_PROFILE("btCuda_collisionBatchResolutionBox"); + + int nIter=getSolverInfo().m_numIterations; + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + btScalar timeStep = dispatchInfo.m_timeStep; + + for(int i=0;i 0) && (idB > 0)) + { + btCollisionObject* colObjA = m_collisionObjects[idA]; + btCollisionObject* colObjB = m_collisionObjects[idB]; + btVector3 vA = colObjA->getWorldTransform().getOrigin(); + btVector3 vB = colObjB->getWorldTransform().getOrigin(); + glVertex3f(vA[0], vA[1], vA[2]); + glVertex3f(vB[0], vB[1], vB[2]); + } + } + pBatchIds += numConstraints; + glEnd(); + } +} + + + +void btGpuDemoDynamicsWorld::initShapeBuffer(int maxShapeBufferSize) +{ + m_maxShapeBufferSize = maxShapeBufferSize; + m_firstFreeShapeBufferOffset = 0; + m_hShapeBuffer = new char[m_maxShapeBufferSize]; + m_hShapeIds = new int2[m_maxObjs]; + +#ifdef BT_USE_CUDA + btCuda_allocateArray((void**)&m_dShapeBuffer, m_maxShapeBufferSize); + btCuda_allocateArray((void**)&m_dShapeIds, sizeof(int) * 2 * m_maxObjs); +#endif //BT_USE_CUDA + + m_copyShapeDataToGPU = true; +} + + + +void btGpuDemoDynamicsWorld::freeShapeBuffer() +{ + delete [] m_hShapeBuffer; + delete [] m_hShapeIds; +#ifdef BT_USE_CUDA + btCuda_freeArray(m_dShapeBuffer); + btCuda_freeArray(m_dShapeIds); +#endif //BT_USE_CUDA +} + + + +void btGpuDemoDynamicsWorld::addSphere(btVector3& pos, btScalar rad) +{ + btVector3* pBuf = (btVector3*)(m_hShapeBuffer + m_firstFreeShapeBufferOffset); + *pBuf = pos; + pBuf->setW(rad); + m_firstFreeShapeBufferOffset += sizeof(btVector3); +} + + + +void btGpuDemoDynamicsWorld::addMultiShereObject(int numSpheres, int objIndex) +{ + m_hShapeIds[objIndex].x = m_firstFreeShapeBufferOffset; + m_hShapeIds[objIndex].y = numSpheres; + return; +} + + diff --git a/Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.h b/Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.h new file mode 100644 index 0000000..bc820c4 --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemoDynamicsWorld.h @@ -0,0 +1,291 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_CUDA_DEMO_DYNAMICS_WORLD_H +#define BT_CUDA_DEMO_DYNAMICS_WORLD_H + + + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" + + +//#define BT_USE_CUDA 1 +// To enable CUDA : +// 1. Uncomment //#define BT_USE_CUDA 1 +// 2. Build and add libbulletcuda (Extras/CUDA) to project +// 3. Add $(CUDA_LIB_PATH) and cudart.lib to linker properties + +#ifdef BT_USE_CUDA +// #include "btCudaDemoPairCache.h" +// #include + #include "BulletMultiThreaded/btGpuDefines.h" + #undef BT_GPU_PREF + #define BT_GPU_PREF(func) btCuda_##func + #include "BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#else + #include "BulletMultiThreaded/btGpuDefines.h" + #include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#endif + +#undef BT_GPU_PREF + + +#include "btGpuDemo2dSharedTypes.h" + + + +#define CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES 20 + +#define CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS 1024 +#define CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS 24 + +#define CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ 8 + +class btGpuDemoDynamicsWorld; + +extern btGpuDemoDynamicsWorld* gpCudaDemoDynamicsWorld; // to access world members from pair cache + +class btGpuDemoDynamicsWorld : public btDiscreteDynamicsWorld +{ +protected: + int m_maxObjs; + int m_maxNeighbors; + + int m_numObj; + int m_numSimStep; + bool m_useCPUSolver; + bool m_useBulletNarrowphase; + + float4* m_hPos; + float* m_hRot; + float4* m_hVel; + float* m_hAngVel; + + float* m_hInvMass; + float* m_dInvMass; + bool m_copyMassDataToGPU; + +#ifdef BT_USE_CUDA + float4* m_dPos; + float* m_dRot; + float4* m_dVel; + float* m_dAngVel; + float4* m_dpPos; + float* m_dpRot; + float4* m_dpVel; + float* m_dpAngVel; + + float4* m_dcPos; + float* m_dcRot; + float4* m_dcVel; + float* m_dcAngVel; +#endif //BT_USE_CUDA + + + btOverlappingPairCache* m_pairCache; + int* m_hConstraintBuffer; + int* m_hConstraintCounter; + int m_maxBatches; + int m_numBatches; + int m_totalNumConstraints; + int2* m_hIds; + int* m_hBatchIds; + + int m_maxVtxPerObj; + + int2* m_dIds; + int* m_dBatchIds; + + float* m_dLambdaDtBox; + float4* m_dContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved + + // ------------- these are only needed for CPU version and for debugging + float* m_hLambdaDtBox; + float4* m_hContact; // 8 floats : pos.x, pos.y, pos.z, penetration, norm.x, norm.y, norm.z, reserved + // ------------- + + btScalar m_objRad; + btVector3 m_worldMin; + btVector3 m_worldMax; + + + int* m_hConstraintUsed; + + + // shape buffer + int m_maxShapeBufferSize; + int m_firstFreeShapeBufferOffset; + char* m_hShapeBuffer; // (pos.x, pos.y, pos.z, radius) + char* m_dShapeBuffer;//pointer in device memory + int2* m_hShapeIds; + int2* m_dShapeIds; + bool m_copyShapeDataToGPU; + void initShapeBuffer(int maxShapeBufferSize); + void freeShapeBuffer(); + void sendShapeDataToGpu(); + + + int m_numNonContactConstraints; + void grabNonContactConstraintData(); + void grabP2PConstraintData(btPoint2PointConstraint* ct); + +public: + int m_numInBatches[CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES]; + void addSphere(btVector3& pos, btScalar rad); + void addMultiShereObject(int numSpheres, int objIndex); + + + btGpuDemoDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration, + int maxObjs = CUDA_DEMO_DYNAMICS_WORLD_MAX_OBJS, int maxNeighbors = CUDA_DEMO_DYNAMICS_WORLD_MAX_NEIGHBORS) + : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration) + { + m_maxObjs = maxObjs; + m_maxNeighbors = maxNeighbors; + m_useCPUSolver = false; + m_pairCache = pairCache->getOverlappingPairCache(); + int sz = m_maxObjs * m_maxNeighbors; + m_hConstraintBuffer = new int[sz]; + m_hConstraintCounter = new int[m_maxObjs]; + m_maxBatches = CUDA_DEMO_DYNAMICS_WORLD_MAX_BATCHES; + m_hIds = new int2[sz]; + m_hBatchIds = new int[sz]; + for(int i = 0; i < sz; i++) + { + m_hBatchIds[i] = -1; + } + m_hPos = new float4[m_maxObjs]; + m_hVel = new float4[m_maxObjs]; + m_hRot = new float[m_maxObjs]; + m_hAngVel = new float[m_maxObjs]; + + m_hInvMass = new float[m_maxObjs]; + + m_maxVtxPerObj = 8; + +#ifdef BT_USE_CUDA + btCuda_allocateArray((void**)&m_dPos, sizeof(float4) * m_maxObjs); + btCuda_allocateArray((void**)&m_dRot, sizeof(float) * m_maxObjs); + btCuda_allocateArray((void**)&m_dVel, sizeof(float4) * m_maxObjs); + btCuda_allocateArray((void**)&m_dAngVel, sizeof(float) * m_maxObjs); + btCuda_allocateArray((void**)&m_dpPos, sizeof(float4) * m_maxObjs); + btCuda_allocateArray((void**)&m_dpRot, sizeof(float) * m_maxObjs); + btCuda_allocateArray((void**)&m_dpVel, sizeof(float4) * m_maxObjs); + btCuda_allocateArray((void**)&m_dpAngVel, sizeof(float) * m_maxObjs); + + btCuda_allocateArray((void**)&m_dInvMass, sizeof(float) * m_maxObjs); + + btCuda_allocateArray((void**)&m_dIds, sizeof(int2) * sz); + btCuda_allocateArray((void**)&m_dBatchIds, sizeof(int) * sz); + + btCuda_allocateArray((void**)&m_dLambdaDtBox, sizeof(float) * sz * m_maxVtxPerObj); + btCuda_allocateArray((void**)&m_dContact, sizeof(float) * sz * m_maxVtxPerObj * 8); +// btCuda_allocateArray((void**)&m_dPositionConstraint, sizeof(float) * sz * m_maxVtxPerObj * 2); +// btCuda_allocateArray((void**)&m_dNormal, sizeof(float3) * sz * m_maxVtxPerObj * 2); +#endif //BT_USE_CUDA + + + m_hLambdaDtBox = new float[sz * m_maxVtxPerObj]; + m_hContact = new float4[sz * m_maxVtxPerObj * 2]; +// m_hPositionConstraint = new float[sz * m_maxVtxPerObj * 2]; +// m_hNormal = new float3[sz * m_maxVtxPerObj * 2]; + + m_numSimStep = 0; + + m_objRad = 1.0f; + + m_hConstraintUsed = new int[sz]; + + + gpCudaDemoDynamicsWorld = this; + m_totalNumConstraints = 0; + + initShapeBuffer(m_maxObjs * CUDA_DEMO_DYNAMICS_WORLD_MAX_SPHERES_PER_OBJ * sizeof(float) * 4); + + m_copyMassDataToGPU = true; + + } + virtual ~btGpuDemoDynamicsWorld() + { + delete [] m_hConstraintBuffer; + delete [] m_hConstraintCounter; + delete [] m_hIds; + delete [] m_hBatchIds; + delete [] m_hPos; + delete [] m_hRot; + delete [] m_hVel; + delete [] m_hAngVel; + delete [] m_hInvMass; +#ifdef BT_USE_CUDA + btCuda_freeArray(m_dPos); + btCuda_freeArray(m_dRot); + btCuda_freeArray(m_dVel); + btCuda_freeArray(m_dAngVel); + btCuda_freeArray(m_dpPos); + btCuda_freeArray(m_dpRot); + btCuda_freeArray(m_dpVel); + btCuda_freeArray(m_dpAngVel); + btCuda_freeArray(m_dInvMass); + + btCuda_freeArray(m_dIds); + btCuda_freeArray(m_dBatchIds); + btCuda_freeArray(m_dLambdaDtBox); + btCuda_freeArray(m_dContact); +#endif //BT_USE_CUDA + + delete [] m_hLambdaDtBox; + delete [] m_hContact; + delete [] m_hConstraintUsed; + + gpCudaDemoDynamicsWorld = NULL; + + freeShapeBuffer(); + } + + virtual void calculateSimulationIslands() + { + } + virtual void solveConstraints(btContactSolverInfo& solverInfo); + void solveConstraints2(btContactSolverInfo& solverInfo); + void solveConstraintsCPU2(btContactSolverInfo& solverInfo); + + void debugDrawConstraints(int selectedBatch, const float* pColorTab); + + void setObjRad(btScalar rad) { m_objRad = rad; } + void setWorldMin(const btVector3& worldMin) { m_worldMin = worldMin; } + void setWorldMax(const btVector3& worldMax) { m_worldMax = worldMax; } + + void grabData(); + void grabContactData(); + void copyDataToGPU(); + void setConstraintData(btCudaPartProps& partProps); + void copyDataFromGPU(); + void writebackData(); + void setUseCPUSolver(bool useCPU) { m_useCPUSolver = useCPU; } + void setUseBulletNarrowphase(bool useBulletNarrowphase) {m_useBulletNarrowphase = useBulletNarrowphase; } + + void createBatches2(); + + int2* getIdsPtr() { return m_hIds; } + void setTotalNumConstraints(int totalNumConstraints) { m_totalNumConstraints = totalNumConstraints; } + int getTotalNumConstraints() { return m_totalNumConstraints; } + +}; + + +#endif //BT_CUDA_DEMO_DYNAMICS_WORLD_H diff --git a/Demos/Gpu2dDemo/btGpuDemoPairCache.cpp b/Demos/Gpu2dDemo/btGpuDemoPairCache.cpp new file mode 100644 index 0000000..3fa0fa1 --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemoPairCache.cpp @@ -0,0 +1,76 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" + +#include "btGpuDemoPairCache.h" + +#include "btGpuDemoDynamicsWorld.h" + + + +void btGpuDemoPairCache::processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher) +{ + int sz = m_maxProxies * m_maxNeighbors; + int numContConstraints = 0; + int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr(); + for(int idx = 0; idx < sz; idx++) + { + int neigh = m_hNeighbors[idx]; + if(neigh >= 0) + { + int i=idx / m_maxNeighbors; + int j=idx % m_maxNeighbors; + pIds[numContConstraints].x = i; + pIds[numContConstraints].y = m_hNeighbors[i * m_maxNeighbors + j]; + numContConstraints++; + } + } + gpCudaDemoDynamicsWorld->setTotalNumConstraints(numContConstraints); +} + + + +// this will be called for each overlapping pair if collision detection uses pairCache other than btGpuDemoPairCache +// IMPORTANT : m_numConstraints in gpCudaDemoDynamicsWorld is set to 0 at start of simulation step +// IMPORTANT : companionIds for all objects should be properly set at start of simulation step +void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo) +{ + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + if (dispatcher.needsCollision(colObj0,colObj1)) + { + // int id0 = collisionPair.m_pProxy0->m_uniqueId - 2; + // int id1 = collisionPair.m_pProxy1->m_uniqueId - 2; + // cannot use m_uniqueId : it may be altered by broadphase code + // so we'll use companionIds set on the initialization stage + unsigned int id0 = colObj0->getCompanionId(); + unsigned int id1 = colObj1->getCompanionId(); + if(id0 > id1) + { + int tmp = id0; id0 = id1; id1 = tmp; + } + int totalNumConstraints = gpCudaDemoDynamicsWorld->getTotalNumConstraints(); + int2* pIds = gpCudaDemoDynamicsWorld->getIdsPtr(); + pIds += totalNumConstraints; + pIds->x = id0; + pIds->y = id1; + totalNumConstraints++; + gpCudaDemoDynamicsWorld->setTotalNumConstraints(totalNumConstraints); + } +} // cudaDemoNearCallback() + diff --git a/Demos/Gpu2dDemo/btGpuDemoPairCache.h b/Demos/Gpu2dDemo/btGpuDemoPairCache.h new file mode 100644 index 0000000..6b9503b --- /dev/null +++ b/Demos/Gpu2dDemo/btGpuDemoPairCache.h @@ -0,0 +1,136 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef CUDA_DEMO_PAIR_CACHE_H +#define CUDA_DEMO_PAIR_CACHE_H + + +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "LinearMath/btAlignedObjectArray.h" + +class btGpuDemoPairCache : public btNullPairCache +{ +public: + int m_maxProxies; + int m_maxNeighbors; + int* m_hNeighbors; + int m_numPairs; + int m_numSmallProxies; + int m_maxSmallProxies; + + btGpuDemoPairCache(int maxProxies, int maxNeighbors, int maxSmallProxies) + { + m_maxProxies = maxProxies; + m_maxNeighbors = maxNeighbors; + m_maxSmallProxies = maxSmallProxies; + int sz = maxProxies * maxNeighbors; + m_hNeighbors = new int [sz]; + reset(); + } + + ~btGpuDemoPairCache() + { + delete [] m_hNeighbors; + } + + void reset(void) + { + int sz = m_maxProxies * m_maxNeighbors; + for(int i = 0; i < sz; i++) + { + m_hNeighbors[i] = -1; + } + m_numPairs = 0; + } + + virtual int getNumOverlappingPairs() const + { + return m_numPairs; + //return 0; // to skip btSimulationIslandManager::findUnions() + } + + virtual void processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher); + + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) + { + int id0 = proxy0->m_uniqueId - 2; + int id1 = proxy1->m_uniqueId - 2; + if(id0 >= m_maxSmallProxies) + { + id0 -= m_maxSmallProxies - m_numSmallProxies; + } + if(id1 >= m_maxSmallProxies) + { + id1 -= m_maxSmallProxies - m_numSmallProxies; + } + if(id0 > id1) + { + int tmp = id0; id0 = id1; id1 = tmp; + } + int offs = id0 * m_maxNeighbors; + int i; + for(i = 0; i < m_maxNeighbors; i++) + { + if(m_hNeighbors[offs + i] < 0) + { + m_hNeighbors[offs + i] = id1; + m_numPairs++; + break; + } + } + // btAssert(i < m_maxNeighbors); + return 0; + } + + virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* /*dispatcher*/) + { + int id0 = proxy0->m_uniqueId - 2; + int id1 = proxy1->m_uniqueId - 2; + if(id0 >= m_maxSmallProxies) + { + id0 -= m_maxSmallProxies - m_numSmallProxies; + } + if(id1 >= m_maxSmallProxies) + { + id1 -= m_maxSmallProxies - m_numSmallProxies; + } + if(id0 > id1) + { + int tmp = id0; id0 = id1; id1 = tmp; + } + int offs = id0 * m_maxNeighbors; + int i; + for(i = 0; i < m_maxNeighbors; i++) + { + if(m_hNeighbors[offs + i] == id1) + { + m_hNeighbors[offs + i] = -1; + m_numPairs--; + break; + } + } +// btAssert(i < m_maxNeighbors); + return 0; + } +}; + +extern void cudaDemoNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo); + +#endif //CUDA_DEMO_PAIR_CACHE_H + + diff --git a/Demos/Gpu2dDemo/main.cpp b/Demos/Gpu2dDemo/main.cpp new file mode 100644 index 0000000..70f8a90 --- /dev/null +++ b/Demos/Gpu2dDemo/main.cpp @@ -0,0 +1,62 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BasicDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + +class OurValue + { + int m_uid; + + public: + OurValue(const btVector3& initialPos) + :m_position(initialPos) + { + static int gUid=0; + m_uid=gUid; + gUid++; + } + + btVector3 m_position; + int getUid() const + { + return m_uid; + } + }; + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + + BasicDemo ccdDemo; + ccdDemo.initPhysics(); + ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} \ No newline at end of file diff --git a/Demos/Gpu2dDemo/oecakeLoader.cpp b/Demos/Gpu2dDemo/oecakeLoader.cpp new file mode 100644 index 0000000..3158dea --- /dev/null +++ b/Demos/Gpu2dDemo/oecakeLoader.cpp @@ -0,0 +1,264 @@ +#include "oecakeLoader.h" +#include //printf debugging +#include + + + + +btCompoundShape* shiftTransform(btCompoundShape* boxCompound,btScalar mass,btTransform& shift) +{ + btTransform principal; + btVector3 principalInertia; + btScalar* masses = new btScalar[boxCompound->getNumChildShapes()]; + for (int j=0;jgetNumChildShapes();j++) + { + //evenly distribute mass + masses[j]=mass/boxCompound->getNumChildShapes(); + } + + + boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia); + + + ///create a new compound with world transform/center of mass properly aligned with the principal axis + + ///non-recursive compound shapes perform better + //#define USE_RECURSIVE_COMPOUND 1 +#ifdef USE_RECURSIVE_COMPOUND + + btCompoundShape* newCompound = new btCompoundShape(); + newCompound->addChildShape(principal.inverse(),boxCompound); + m_collisionShapes.push_back(newCompound); + + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia); + +#else +#ifdef CHANGE_COMPOUND_INPLACE + for (int i=0;igetNumChildShapes();i++) + { + btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i); + ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update + boxCompound->updateChildTransform(i,newChildTransform); + } + if (isDynamic) + boxCompound->calculateLocalInertia(mass,localInertia); + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,boxCompound,localInertia); +#else + ///creation is faster using a new compound to store the shifted children + btCompoundShape* newBoxCompound = new btCompoundShape(); + for (int i=0;igetNumChildShapes();i++) + { + btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i); + ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update + newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i)); + } + + + +#endif + +#endif//USE_RECURSIVE_COMPOUND + + shift = principal; + return newBoxCompound; +} + + +void BasicOECakeReader::addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY,float radius) +{ + //determine that we have a new shape? + if (m_particlePositions.size()) + { + if ( + (materialType != m_materialType) + || + (pIndex != m_particleObjectIndex) + ) + { + convertParticleGroup(); + } + } + + + //add to array + m_materialType = materialType; + m_particleObjectIndex = pIndex; + m_particleColor = pColor; + m_particlePositions.push_back(btVector3(pPosX,pPosY,0.)); + m_particleRadii.push_back(radius); + +} + +void BasicOECakeReader::convertParticleGroup() +{ + printf("found a particle group of %d particles\n",m_particlePositions.size()); + if (m_particlePositions.size()>0) + { + addNewCollisionShape(m_particlePositions.size(),&m_particlePositions[0],&m_particleRadii[0],m_materialType,m_particleObjectIndex,m_particleColor); + m_particlePositions.clear(); + m_particleRadii.clear(); + } +} + +void BasicOECakeReader::addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color ) +{ + //create Bullet stuff + btCompoundShape* colShape = 0; + btScalar mass; + + bool addConstraint = false; + + + if (materialType&0x800000) + { + addConstraint = true; + } + + if ((materialType & 0x20000) ||(materialType & 0x12)) + { + mass = 1.f; + } else + { + mass = 0.f; + } + btTransform startTransform; + startTransform.setIdentity(); + + int numCurSpheres = 0; + + { + + + btTransform localTrans; + localTrans.setIdentity(); + + //static + btCompoundShape* compound = new btCompoundShape(); + + for (int i=0;iaddChildShape(localTrans,particle); + if (mass==0.f && (numCurSpheres>=7)) + { + createBodyForCompoundShape(compound,false,startTransform,mass); + compound = new btCompoundShape(); + numCurSpheres = 0; + } + } + if (mass) + { + //shift the center of mass, based on all spheres + btCompoundShape* newCompound = shiftTransform(compound,mass,startTransform); + colShape = newCompound; + } else + { + //use unmodified + colShape = compound; + } + } + + btDefaultMotionState* myMotionState = 0; + + if (colShape && numCurSpheres) + { + createBodyForCompoundShape(colShape,addConstraint,startTransform,mass); + } +} + + + +int BasicOECakeReader::processLine(char * buffer, int size) +{ + int numBytesRead = 0; + + if (buffer[0] == 'p') + { + int materialType; + int particleObjectIndex; + int particleColor; + int dummy1; + float particlePosX; + float particlePosY; + + if (sscanf (buffer, "p %x %x %x %x %f %f", &materialType,&particleObjectIndex,&dummy1, &particleColor, &particlePosX, &particlePosY) == 6) + { + addParticle(materialType,particleObjectIndex,particleColor,particlePosX,particlePosY); + } + else + { + printf("ERROR: invalid line (%s)\n", buffer); + } + } + + while (*buffer != '\n' && size != 0) + { + buffer++; + numBytesRead++; + } + + + if (buffer[0]==0x0a) + { + buffer++; + numBytesRead++; + } + + + return numBytesRead; +} + +bool BasicOECakeReader::processFile(char * fileName) +{ + FILE * fp = fopen(fileName, "rb"); + if (fp == NULL) + { + printf("ERROR: file(%s) not found", fileName); + return false; + } + + int size; + if (fseek(fp, 0, SEEK_END) || (size = ftell(fp)) == EOF || fseek(fp, 0, SEEK_SET)) + { + printf("ERROR: problem reading file(%s)", fileName); + fclose(fp); + return false; + } + else + { + rewind (fp); + char * buffer = (char *) malloc(size+1); + memset(buffer,0,size); + + if (fread(buffer,1,size,fp) != size) + { + printf("Error reading file %s!\n",fileName); + fclose(fp); + return false; + } + + int totalBytesRead = 0; + + while(totalBytesRead m_particlePositions; + btAlignedObjectArray m_particleRadii; + + void addParticle(int materialType, int pIndex, int pColor, float pPosX, float pPosY, float radius=1); + + virtual void addNewCollisionShape(int numParticles, btVector3* particlePositions, btScalar* radii, int materialType, int objectIndex,int color ); + + int processLine(char * buffer, int size); + + void convertParticleGroup(); + +public: + + BasicOECakeReader() + { + } + + bool processFile(char * fileName); + + virtual void createBodyForCompoundShape(btCompoundShape* compound,bool addConstraint,const btTransform& worldTransform, btScalar mass) = 0; + +}; +#endif //OE_CAKE_LOADER_H diff --git a/Demos/Gpu3dDemo/BasicDemo3d.cpp b/Demos/Gpu3dDemo/BasicDemo3d.cpp new file mode 100644 index 0000000..5e99703 --- /dev/null +++ b/Demos/Gpu3dDemo/BasicDemo3d.cpp @@ -0,0 +1,852 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#include "BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h" + +#include "btGpuDemoDynamicsWorld3D.h" + +#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#include "BulletMultiThreaded/Win32ThreadSupport.h" +#include "GLDebugFont.h" +extern int gSkippedCol; +extern int gProcessedCol; + + + +#define SPEC_TEST 0 + +#ifdef _DEBUG + #define LARGE_DEMO 1 +// #define LARGE_DEMO 1 +#else + #define LARGE_DEMO 1 +#endif + +#if LARGE_DEMO + ///create 512 (8x8x8) dynamic object +// #define ARRAY_SIZE_X 100 +// #define ARRAY_SIZE_Y 100 +// #define ARRAY_SIZE_Z 1 +// #define ARRAY_SIZE_X 228 +// #define ARRAY_SIZE_Y 228 +// #define ARRAY_SIZE_X 30 +// #define ARRAY_SIZE_Y 100 + +#define ARRAY_SIZE_X 8 +#define ARRAY_SIZE_Y 47 +#define ARRAY_SIZE_Z 8 +#else + ///create 125 (5x5x5) dynamic object + #define ARRAY_SIZE_X 45 + #define ARRAY_SIZE_Y 45 +// #define ARRAY_SIZE_Z 5 + #define ARRAY_SIZE_Z 1 +#endif + + +//maximum number of objects (and allow user to shoot additional boxes) +#define NUM_SMALL_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z) +#define MAX_PROXIES (NUM_SMALL_PROXIES + 1024) +#define MAX_LARGE_PROXIES 10 +#define MAX_SMALL_PROXIES (MAX_PROXIES - MAX_LARGE_PROXIES) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +//#define SCALING 0.1 +#define SCALING 1 +#define START_POS_X 0 +#define START_POS_Y 5 +#define START_POS_Z 0 + +#include "BasicDemo3d.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include //printf debugging + +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" + +#include "../Extras/CUDA/btCudaBroadphase.h" + +btScalar gTimeStep = btScalar(1./60.); + +bool gbDrawBatches = false; +int gSelectedBatch = CUDA_DEMO_DYNAMICS_WORLD3D_MAX_BATCHES; +bool gUseCPUSolver = false; +bool gUseSolver2 = true; +bool gDrawWire = false; +bool gUseCudaMotIntegr = true; + + +void BasicDemo3D::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { +// btCudaDemoPairCache* pc = (btCudaDemoPairCache*)m_dynamicsWorld->getPairCache(); +// pc->m_numSmallProxies = m_dynamicsWorld->getNumCollisionObjects(); // - 1; // exclude floor + m_dynamicsWorld->stepSimulation(gTimeStep,0);//ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + renderme(); + + ms = getDeltaTimeMicroseconds(); + + glFlush(); + + glutSwapBuffers(); + +} + + + +void BasicDemo3D::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + glutSwapBuffers(); +} + +#define NUM_SOLVERS 11 +static btConstraintSolver* sConstraintSolvers[NUM_SOLVERS]; +static int sCurrSolverIndex = 9; +static char* sConstraintSolverNames[NUM_SOLVERS] = +{ + "btSequentialImpulseConstraintSolver", + "btParallelBatchConstraintSolver", + "btCudaConstraintSolver", + "btParallelBatchConstraintSolver2", + "btParallelBatchConstraintSolver3", + "btCudaConstraintSolver3", + "btParallelBatchConstraintSolver4", + "btCudaConstraintSolver4", + "btParallelBatchConstraintSolver5", + "btParallelBatchConstraintSolver6", + "btCudaConstraintSolver6", +}; + +//btVector3 gWorldMin(-228,-228,-32); +//btVector3 gWorldMin(-228,0,-32); +//btVector3 gWorldMax(228,228,32); + +//btVector3 gWorldMin(-150,-228,-32); +//btVector3 gWorldMax(150,228,32); + +#define POS_OFFS_X (ARRAY_SIZE_X * SCALING + 50) +#define POS_OFFS_Y (ARRAY_SIZE_Y * SCALING ) +#define POS_OFFS_Z (ARRAY_SIZE_Z * SCALING + 5) + +btVector3 gWorldMin(-POS_OFFS_X, -ARRAY_SIZE_Y*SCALING, -80-POS_OFFS_Z); +btVector3 gWorldMax( POS_OFFS_X, POS_OFFS_Y, 80+POS_OFFS_Z); + +//btCudaDemoPairCache* gPairCache; +btHashedOverlappingPairCache* gPairCache; + +void BasicDemo3D::initPhysics() +{ + setTexturing(true); + setShadows(false); + +// setCameraDistance(btScalar(SCALING*50.)); +#if LARGE_DEMO + setCameraDistance(btScalar(SCALING*50.)); +#else + setCameraDistance(btScalar(SCALING*20.)); +#endif + + m_cameraTargetPosition.setValue(START_POS_X, -START_POS_Y-20, START_POS_Z); + m_azi = btScalar(0.f); + m_ele = btScalar(0.f); + + ///collision configuration contains default setup for memory, collision setup + + btDefaultCollisionConstructionInfo dci; + dci.m_defaultMaxPersistentManifoldPoolSize=100000; + dci.m_defaultMaxCollisionAlgorithmPoolSize=100000; + dci.m_customCollisionAlgorithmMaxElementSize = sizeof(SpuContactManifoldCollisionAlgorithm); + + + ///SpuContactManifoldCollisionAlgorithm is larger than any of the other collision algorithms +//@@ dci.m_customMaxCollisionAlgorithmSize = sizeof(SpuContactManifoldCollisionAlgorithm); + + m_collisionConfiguration = new btDefaultCollisionConfiguration(dci); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + //m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#ifndef WIN32 + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#else + unsigned int maxNumOutstandingTasks =4; + //createCollisionLocalStoreMemory(); + //processSolverTask + Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("narrowphase_multi",processCollisionTask,createCollisionLocalStoreMemory,maxNumOutstandingTasks); + class btThreadSupportInterface* threadInterface = new Win32ThreadSupport(threadConstructionInfo); + m_dispatcher = new SpuGatheringCollisionDispatcher(threadInterface,maxNumOutstandingTasks,m_collisionConfiguration); +#endif //SINGLE_THREADED_NARROWPHASE + + +//## m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new btEmptyAlgorithm::CreateFunc); +//## m_dispatcher->registerCollisionCreateFunc(CUSTOM_CONVEX_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE,new btBox2dBox2dCollisionAlgorithm::CreateFunc); + +// m_broadphase = new btDbvtBroadphase(); + + +//## gPairCache = new (btAlignedAlloc(sizeof(btCudaDemoPairCache),16)) btCudaDemoPairCache(MAX_PROXIES, 24, MAX_SMALL_PROXIES); +// gPairCache = NULL; + gPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); + + //m_broadphase = new btSimpleBroadphase(16384, gPairCache); + +/* +btCudaBroadphase::btCudaBroadphase( btOverlappingPairCache* overlappingPairCache, + const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, + int maxBodiesPerCell, + btScalar cellFactorAABB) +*/ +// btVector3 numOfCells = (gWorldMax - gWorldMin) / (2. * SCALING * 0.7); + btVector3 numOfCells = (gWorldMax - gWorldMin) / (2. * SCALING); + int numOfCellsX = (int)numOfCells[0]; + int numOfCellsY = (int)numOfCells[1]; + int numOfCellsZ = (int)numOfCells[2]; + +// m_broadphase = new bt3DGridBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,8,8,1./1.5); +//#define USE_CUDA_BROADPHASE 1 +#ifdef USE_CUDA_BROADPHASE + m_broadphase = new btCudaBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,20,18,8,1./1.5); +#else + +#if DBVT + btDbvtBroadphase* dbvt = new btDbvtBroadphase(gPairCache); + m_broadphase = dbvt; + dbvt->m_deferedcollide=false; + dbvt->m_prediction = 0.f; +#else + m_broadphase = new btAxisSweep3(gWorldMin,gWorldMax,32000,gPairCache,true);//(btDbvtBroadphase(gPairCache); +#endif //DBVT + +#endif + + + // create solvers for tests + ///the default constraint solver + sConstraintSolvers[0] = new btSequentialImpulseConstraintSolver(); +/* + sConstraintSolvers[1] = new btParallelBatchConstraintSolver(); + sConstraintSolvers[2] = new btCudaConstraintSolver(); + sConstraintSolvers[3] = new btParallelBatchConstraintSolver2(); + sConstraintSolvers[4] = new btParallelBatchConstraintSolver3(); + sConstraintSolvers[5] = new btCudaConstraintSolver3(); + sConstraintSolvers[6] = new btParallelBatchConstraintSolver4(); + sConstraintSolvers[7] = new btCudaConstraintSolver4(); + sConstraintSolvers[8] = new btParallelBatchConstraintSolver5(); + sConstraintSolvers[9] = new btParallelBatchConstraintSolver6(); + sConstraintSolvers[10] = new btCudaConstraintSolver6(); +*/ + sCurrSolverIndex = 0; + m_solver = sConstraintSolvers[sCurrSolverIndex]; + printf("\nUsing %s\n", sConstraintSolverNames[sCurrSolverIndex]); + +// sCudaMotionInterface = new btCudaMotionInterface(MAX_PROXIES); +// m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, sCudaMotionInterface); +// m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); +//## btCudaDemoDynamicsWorld* pDdw = new btCudaDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + btCudaDemoDynamicsWorld3D* pDdw = new btCudaDemoDynamicsWorld3D(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = pDdw; + pDdw->getDispatchInfo().m_enableSPU=true; + pDdw->getSimulationIslandManager()->setSplitIslands(sCurrSolverIndex == 0); + pDdw->setObjRad(SCALING); + pDdw->setWorldMin(gWorldMin); + pDdw->setWorldMax(gWorldMax); +#ifdef BT_USE_CUDA + gUseCPUSolver = false; +#else + gUseCPUSolver = true; +#endif + pDdw->setUseCPUSolver(gUseCPUSolver); +// pDdw->setUseSolver2(gUseSolver2); + +// m_dynamicsWorld->setGravity(btVector3(0,0,0)); + m_dynamicsWorld->setGravity(btVector3(0.f,-10.f,0.f)); + m_dynamicsWorld->getSolverInfo().m_numIterations = 4; + + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + + //btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,0.1));//SCALING*1)); +//## btCollisionShape* colShape = new btBox2dShape(btVector3(SCALING*.7,SCALING*.7,0.1));//SCALING*1)); + btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*.7,SCALING*.7, SCALING*.7)); + + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(colShape); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); +#if (!SPEC_TEST) + float start_x = START_POS_X - ARRAY_SIZE_X * SCALING; + float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING; + float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING; + + for (int k=0;kaddRigidBody(body); + } + } + } +#else + // narrowphase test - 2 bodies at the same position + float start_x = START_POS_X; + float start_y = START_POS_Y; + float start_z = START_POS_Z; +// startTransform.setOrigin(SCALING*btVector3(start_x,start_y-14.f,start_z)); + startTransform.setOrigin(SCALING*btVector3(start_x,start_y-11.f,start_z)); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); + rbInfo.m_startWorldTransform=startTransform; + btRigidBody* body = new btRigidBody(rbInfo); + m_dynamicsWorld->addRigidBody(body); +// startTransform.setOrigin(SCALING*btVector3(start_x+1.2f,start_y+1.4f-14.f,start_z)); + startTransform.setOrigin(SCALING*btVector3(start_x,start_y + 1.5f -11.f, start_z)); + rbInfo.m_startWorldTransform=startTransform; + body = new btRigidBody(rbInfo); + m_dynamicsWorld->addRigidBody(body); +#endif + } + + +#if 0 + ///create a few basic rigid bodies +// btCollisionShape* groundShape = new btBox2dShape(btVector3(btScalar(50.),btScalar(1.),btScalar(50.))); +// btCollisionShape* groundShape = new btBox2dShape(btVector3(btScalar(228.),btScalar(1.),btScalar(228.))); +// btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(228.),btScalar(1.),btScalar(228.))); +// btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); +// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + btCollisionShape* groundShape = new btBoxShape(btVector3(POS_OFFS_X, btScalar(1.), POS_OFFS_Z)); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, gWorldMin[1], 0)); + +// groundTransform.setOrigin(btVector3(0,-5,0)); +// groundTransform.setOrigin(btVector3(0,-50,0)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } +#endif + //clientResetScene(); +} + +void BasicDemo3D::clientResetScene() +{ + DemoApplication::clientResetScene(); + btCudaDemoDynamicsWorld3D* pDdw = (btCudaDemoDynamicsWorld3D*)m_dynamicsWorld; + pDdw->resetScene(); +#if SPEC_TEST + { + float start_x = START_POS_X; + float start_y = START_POS_Y; + float start_z = START_POS_Z; + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray(); + btTransform startTransform; + startTransform.setIdentity(); + for(int n = 0; n < numObjects; n++) + { + btCollisionObject* colObj = collisionObjects[n]; + btRigidBody* rb = btRigidBody::upcast(colObj); + if(!n) + { +// startTransform.setOrigin(SCALING*btVector3(start_x,start_y-14.f,start_z)); + startTransform.setOrigin(SCALING*btVector3(start_x,start_y-11.f,start_z)); + } + else + { +// startTransform.setOrigin(SCALING*btVector3(start_x+1.2f,start_y+1.4f-14.f,start_z)); + startTransform.setOrigin(SCALING*btVector3(start_x, start_y+1.5f-11.f,start_z)); + } + rb->setCenterOfMassTransform(startTransform); + } + return; + } +#endif +// we don't use motionState, so reset transforms here + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray(); + + float start_x = START_POS_X - ARRAY_SIZE_X * SCALING; + float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING; + float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING; + btTransform startTransform; + startTransform.setIdentity(); + + for(int n = 0; n < numObjects; n++) + { + btCollisionObject* colObj = collisionObjects[n]; + btRigidBody* rb = btRigidBody::upcast(colObj); + int offs = ARRAY_SIZE_X * ARRAY_SIZE_Z; + int indx = n; + int ky = indx / offs; + indx -= ky * offs; + int kx = indx / ARRAY_SIZE_Z; + indx -= kx * ARRAY_SIZE_Z; + int kz = indx; + startTransform.setOrigin(SCALING*btVector3( + 2.0*SCALING*kx + start_x, + 2.0*SCALING*ky + start_y, + 2.0*SCALING*kz + start_z)); + rb->setCenterOfMassTransform(startTransform); + } +} + + + +void BasicDemo3D::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jgetSimulationIslandManager()->setSplitIslands(sCurrSolverIndex == 0); + pDdw->setConstraintSolver(sConstraintSolvers[sCurrSolverIndex]); + printf("\nUsing %s\n", sConstraintSolverNames[sCurrSolverIndex]); + } + break; +#endif + case 'c' : + { + gbDrawBatches = !gbDrawBatches; + break; + } + case 'b' : + { + gSelectedBatch++; + gSelectedBatch %= (CUDA_DEMO_DYNAMICS_WORLD3D_MAX_BATCHES + 1); + break; + } + case 'u' : + { +#ifdef BT_USE_CUDA + btCudaDemoDynamicsWorld3D* pDdw = (btCudaDemoDynamicsWorld3D*)m_dynamicsWorld; + gUseCPUSolver = !gUseCPUSolver; + pDdw->setUseCPUSolver(gUseCPUSolver); +#endif + break; + } + case 'w' : + { + gDrawWire = !gDrawWire; + setWireMode(gDrawWire); + break; + } + case 'm' : + { + btCudaDemoDynamicsWorld3D* pDdw = (btCudaDemoDynamicsWorld3D*)m_dynamicsWorld; + gUseCudaMotIntegr = !gUseCudaMotIntegr; + pDdw->setUseCudaMotIntegr(gUseCudaMotIntegr); + break; + } + + default : + { + DemoApplication::keyboardCallback(key, x, y); + } + break; + } + + if(key == ' ') + { + //gPairCache->reset(); + } +} + + +void BasicDemo3D::mouseFunc(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + m_mouseButtons |= 1<m_numInBatches[i]); + GLDebugDrawString(xOffs-80, yOffs,buf); + yOffs += 15.f; + } +} + + +void BasicDemo3D::renderme() +{ + updateCamera(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if(gDrawWire) + { + glColor3f(1.f, 1.f, 1.f); + glDisable(GL_LIGHTING); + setTexturing(false); + } + else + { + myinit(); + setTexturing(true); + } + + renderscene(0); + + if(gbDrawBatches) + { + ((btCudaDemoDynamicsWorld3D*)m_dynamicsWorld)->debugDrawConstraints(gSelectedBatch, cBatchColorTab); + } + glColor3f(0, 0, 0); + if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0) + { + setOrthographicProjection(); + int xOffset = 10.f; + int yStart = 20.f; + int yIncr = 20.f; + showProfileInfo(xOffset, yStart, yIncr); + DrawConstraintInfo(); + outputDebugInfo(xOffset, yStart, yIncr); + resetPerspectiveProjection(); + } +} + + + +extern int gNumClampedCcdMotions; +#define SHOW_NUM_DEEP_PENETRATIONS 1 +#ifdef SHOW_NUM_DEEP_PENETRATIONS + extern int gNumDeepPenetrationChecks; + extern int gNumSplitImpulseRecoveries; + extern int gNumGjkChecks; + extern int gNumAlignedAllocs; + extern int gNumAlignedFree; + extern int gTotalBytesAlignedAllocs; +#endif // + + +void BasicDemo3D::outputDebugInfo(int & xOffset,int & yStart, int yIncr) +{ + char buf[124]; + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"mouse to interact"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"space to reset"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"cursor keys and z,x to navigate"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"i to toggle simulation, s single step"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"q to quit"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"h to toggle help text"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"p to toggle profiling (+results to file)"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"w to toggle wireframe/solid rendering"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"c to toggle constraint drawing"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"b to draw single constraint batch"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"u to toggle between CPU and CUDA solvers"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"d to toggle between different batch builders"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"m to toggle between CUDA / CPU motion integrators"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + if (getDynamicsWorld()) + { + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects()); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs()); + GLDebugDrawString(xOffset,yStart,buf); + + + yStart += yIncr; + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"# skipped collisions=%d",gSkippedCol); + GLDebugDrawString(xOffset,yStart,buf); + + yStart += yIncr; + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"# processed collisions=%d",gProcessedCol); + GLDebugDrawString(xOffset,yStart,buf); + + yStart += yIncr; + glRasterPos3f(xOffset,yStart,0); + btScalar fract = (gProcessedCol+gSkippedCol)? btScalar(gSkippedCol)/(gProcessedCol+gSkippedCol) : 0.f; + sprintf(buf,"culled narrowphase collisions=%f",fract); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + gProcessedCol = 0; + gSkippedCol = 0; + + } +} // BasicDemo3D::outputDebugInfo() + +void BasicDemo3D::setWireMode(bool wireOnOff) +{ + int dbgDrawMode = m_dynamicsWorld->getDebugDrawer()->getDebugMode(); + if(wireOnOff) + { + dbgDrawMode |= btIDebugDraw::DBG_FastWireframe; + } + else + { + dbgDrawMode &= ~btIDebugDraw::DBG_FastWireframe; + } + m_dynamicsWorld->getDebugDrawer()->setDebugMode(dbgDrawMode); + m_debugMode = dbgDrawMode; +} // BasicDemo3D::setWireMode() diff --git a/Demos/Gpu3dDemo/BasicDemo3d.h b/Demos/Gpu3dDemo/BasicDemo3d.h new file mode 100644 index 0000000..7600e27 --- /dev/null +++ b/Demos/Gpu3dDemo/BasicDemo3d.h @@ -0,0 +1,93 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BASIC_DEMO3D_H +#define BASIC_DEMO3D_H + +#include "GlutDemoApplication.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; + +///BasicDemo is good starting point for learning the code base and porting. +class BasicDemo3D : public GlutDemoApplication +{ + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + int m_mouseButtons; + int m_mouseOldX; + int m_mouseOldY; + + public: + + BasicDemo3D() + { + } + virtual ~BasicDemo3D() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + virtual void mouseFunc(int button, int state, int x, int y); + virtual void mouseMotionFunc(int x,int y); + + virtual void clientResetScene(); + + static DemoApplication* Create() + { + BasicDemo3D* demo = new BasicDemo3D; + demo->myinit(); + demo->initPhysics(); + demo->m_mouseButtons = 0; + demo->m_mouseOldX = 0; + demo->m_mouseOldY = 0; + return demo; + } + + void DrawConstraintInfo(); + void outputDebugInfo(int & xOffset,int & yStart, int yIncr); + virtual void renderme(); + + void setWireMode(bool wireOnOff); +}; + + +#endif //BASIC_DEMO3D_H + diff --git a/Demos/Gpu3dDemo/CMakeLists.txt b/Demos/Gpu3dDemo/CMakeLists.txt new file mode 100644 index 0000000..e7e2a02 --- /dev/null +++ b/Demos/Gpu3dDemo/CMakeLists.txt @@ -0,0 +1,34 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletMultiThreaded BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppGpu3dDemo + main.cpp + BasicDemo3d.cpp + BasicDemo3d.h + btGpuDemo3dSharedTypes.h + btGpuDemo3dCpuFunc.cpp + btGpuDemoDynamicsWorld3D.cpp + btGpuDemoDynamicsWorld3D.h + btGpuDemo3dSharedCode.h + btGpuDemo3dSharedDefs.h +) + + diff --git a/Demos/Gpu3dDemo/btGpuDemo3dCpuFunc.cpp b/Demos/Gpu3dDemo/btGpuDemo3dCpuFunc.cpp new file mode 100644 index 0000000..9c956d4 --- /dev/null +++ b/Demos/Gpu3dDemo/btGpuDemo3dCpuFunc.cpp @@ -0,0 +1,32 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------------------------------------------------------------------------------------- + +#include "LinearMath/btQuickprof.h" + +//---------------------------------------------------------------------------------------- + +#include "btGpuDemo3dSharedTypes.h" + +//---------------------------------------------------------------------------------------- + +#include "BulletMultiThreaded/btGpuDefines.h" +#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "btGpuDemo3dSharedCode.h" + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- diff --git a/Demos/Gpu3dDemo/btGpuDemo3dSharedCode.h b/Demos/Gpu3dDemo/btGpuDemo3dSharedCode.h new file mode 100644 index 0000000..487b60f --- /dev/null +++ b/Demos/Gpu3dDemo/btGpuDemo3dSharedCode.h @@ -0,0 +1,545 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "LinearMath/btMinMax.h" + +//---------------------------------------------------------------------------------------- + +#define USE_FRICTION 1 +#define FRICTION_BOX_GROUND_FACT 0.01f +#define FRICTION_BOX_BOX_FACT 0.01f +//#define FRICTION_BOX_BOX_FACT 0.05f +#define USE_CENTERS 1 + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------- C o n s t r a i n t s o l v e r d e m o 3D -------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + +// kernel functions + + +BT_GPU___global__ void clearAccumulationOfLambdaDtD(float* lambdaDtBox, int numConstraints, int numContPoints) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index < numConstraints) + { + for(int i=0; i < numContPoints; i++) + lambdaDtBox[numContPoints * index + i] = 0; + } +} // clearAccumulationOfLambdaDtD() + +//---------------------------------------------------------------------------------------- + +BT_GPU___device__ float computeImpulse3D(float3 rVel, + float positionConstraint, + float3 cNormal, + float dt) +{ + const float collisionConstant = 0.1f; + const float baumgarteConstant = 0.1f; + const float penetrationError = 0.02f; + + float lambdaDt=0; + float3 impulse=BT_GPU_make_float3(0.f,0.f,0.f); + + if(positionConstraint >= 0) + return lambdaDt; + + positionConstraint = btMin(0.0f,positionConstraint+penetrationError); + + lambdaDt = -(BT_GPU_dot(cNormal,rVel)*(collisionConstant)); + lambdaDt -= (baumgarteConstant/dt*positionConstraint); + + return lambdaDt; +} // computeImpulse3D() + +//---------------------------------------------------------------------------------------- + +#if 0 +#define VLIM 1000.f +void BT_GPU___device__ chk_vect(float4* v) +{ + if(v->x < -VLIM) v->x = 0.f; + if(v->x > VLIM) v->x = 0.f; + if(v->y < -VLIM) v->y = 0.f; + if(v->y > VLIM) v->y = 0.f; + if(v->z < -VLIM) v->z = 0.f; + if(v->z > VLIM) v->z = 0.f; +} // chk_vect() +#endif + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void collisionWithWallBox3DD(float4 *trans, + float4 *vel, + float4* angVel, + btCudaPartProps pProp, + btCudaBoxProps gProp, + int nParticles, + float dt) +{ + int idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + float3 aPos; + float positionConstraint; + float3 impulse; + + if(idx < nParticles) + { + aPos = BT_GPU_make_float34(trans[idx * 4 + 3]); + for(int iVtx=0; iVtx < 8; iVtx++) + { + float3 dx = BT_GPU_make_float34(trans[idx * 4 + 0]); + float3 dy = BT_GPU_make_float34(trans[idx * 4 + 1]); + float3 dz = BT_GPU_make_float34(trans[idx * 4 + 2]); + float3 rerVertex = ((iVtx & 1) ? dx : dx * (-1.f)); + + rerVertex += ((iVtx & 2) ? dy : dy * (-1.f)); + rerVertex += ((iVtx & 4) ? dz : dz * (-1.f)); + float3 vPos = aPos + rerVertex; + float3 aVel = BT_GPU_make_float3(vel[idx].x, vel[idx].y, vel[idx].z); + float3 aAngVel = BT_GPU_make_float34(angVel[idx]); + float3 vVel =aVel+BT_GPU_cross(aAngVel, rerVertex); + float restitution=0.5; + { + positionConstraint = vPos.y - gProp.minY; + impulse = BT_GPU_make_float31(0.0f); + if(positionConstraint < 0) + { + float3 groundNormal; + groundNormal = BT_GPU_make_float3(0.0f,1.0f,0.0f); + impulse = groundNormal * restitution * computeImpulse3D(vVel, positionConstraint, groundNormal, dt); +#if USE_FRICTION // only with ground for now + float3 lat_vel = vVel - groundNormal * BT_GPU_dot(groundNormal,vVel); + float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel); + if (lat_vel_len > 0) + { + lat_vel_len = sqrtf(lat_vel_len); + lat_vel *= 1.f/lat_vel_len; + impulse -= lat_vel * BT_GPU_dot(lat_vel, vVel) * FRICTION_BOX_GROUND_FACT; + } +#endif //USE_FRICTION + vel[idx] += BT_GPU_make_float42(impulse,0.0f); + angVel[idx] += BT_GPU_make_float42(BT_GPU_cross(rerVertex,impulse), 0.0f); + } + } + { + positionConstraint = vPos.x - gProp.minX; + impulse = BT_GPU_make_float31(0.0f); + if(positionConstraint < 0) + { + float3 normal = BT_GPU_make_float3(1.0f,0.0f,0.0f); + impulse = normal * restitution * computeImpulse3D(vVel,positionConstraint,normal,dt); + vel[idx] += BT_GPU_make_float42(impulse,0.0f); + angVel[idx] += BT_GPU_make_float42(BT_GPU_cross(rerVertex,impulse), 0.0f); + } + } + { + positionConstraint = gProp.maxX - vPos.x; + impulse = BT_GPU_make_float31(0.0f); + if(positionConstraint < 0) + { + float3 normal = BT_GPU_make_float3(-1.0f,0.0f,0.0f); + impulse = normal * restitution * computeImpulse3D(vVel,positionConstraint,normal,dt); + vel[idx] += BT_GPU_make_float42(impulse,0.0f); + angVel[idx] += BT_GPU_make_float42(BT_GPU_cross(rerVertex,impulse), 0.0f); + } + } + { + positionConstraint = vPos.z - gProp.minZ; + impulse = BT_GPU_make_float31(0.0f); + if(positionConstraint < 0) + { + float3 normal = BT_GPU_make_float3(0.0f,0.0f,1.0f); + impulse = normal * restitution * computeImpulse3D(vVel,positionConstraint,normal,dt); + vel[idx] += BT_GPU_make_float42(impulse,0.0f); + angVel[idx] += BT_GPU_make_float42(BT_GPU_cross(rerVertex,impulse), 0.0f); + } + } + { + positionConstraint = gProp.maxZ - vPos.z; + impulse = BT_GPU_make_float31(0.0f); + if(positionConstraint < 0) + { + float3 normal = BT_GPU_make_float3(0.0f,0.0f,-1.0f); + impulse = normal * restitution * computeImpulse3D(vVel,positionConstraint,normal,dt); + vel[idx] += BT_GPU_make_float42(impulse,0.0f); + angVel[idx] += BT_GPU_make_float42(BT_GPU_cross(rerVertex,impulse), 0.0f); + } + } + } + } +} // collisionWithWallBox3DD() + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void collisionBatchResolutionBox3DD(int2 *constraints, + int *batch, + int nConstraints, + float4 *trans, + float4 *vel, + float4 *angularVel, + float *lambdaDtBox, + float *iPositionConstraint, + float3 *normal, + float3 *contact, + btCudaPartProps pProp, + int iBatch, + float dt) +{ + float3 relVel; + float3 impulse; + float lambdaDt; + float positionConstraint; + int k_idx = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(k_idx < nConstraints) + { + int idx = batch[k_idx]; + int aId=constraints[idx].x; + int bId=constraints[idx].y; + float3 aPos = BT_GPU_make_float34(trans[aId * 4 + 3]); + float3 bPos = BT_GPU_make_float34(trans[bId * 4 + 3]); + float3 aVel = BT_GPU_make_float34(vel[aId]); + float3 bVel = BT_GPU_make_float34(vel[bId]); + float3 aAngVel = BT_GPU_make_float34(angularVel[aId]); + float3 bAngVel = BT_GPU_make_float34(angularVel[bId]); + for(int iVtx = 0; iVtx < 4; iVtx++) + { + float3 contactPoint = contact[idx * 4 + iVtx] - aPos; + positionConstraint = iPositionConstraint[idx * 4 + iVtx]; + if(positionConstraint > 0) + { + float3 contactNormal = normal[idx * 4 + iVtx]; + relVel = (aVel + BT_GPU_cross(aAngVel, contactPoint)) + -(bVel + BT_GPU_cross(bAngVel, contactPoint+aPos-bPos)); + + lambdaDt= computeImpulse3D(relVel, -positionConstraint, contactNormal, dt); + { + float rLambdaDt=lambdaDtBox[idx * 4 + iVtx]; + float pLambdaDt=rLambdaDt; + rLambdaDt=btMax(pLambdaDt+lambdaDt,0.0f); + lambdaDt=rLambdaDt-pLambdaDt; + lambdaDtBox[idx * 4 + iVtx]=rLambdaDt; + } + impulse = contactNormal*lambdaDt*0.5; +#if USE_FRICTION + float3 lat_vel = relVel - contactNormal * BT_GPU_dot(contactNormal, relVel); + float lat_vel_len = BT_GPU_dot(lat_vel, lat_vel); + if (lat_vel_len > 0) + { + lat_vel_len = sqrtf(lat_vel_len); + lat_vel *= 1.f/lat_vel_len; + impulse -= lat_vel * BT_GPU_dot(lat_vel , relVel) * FRICTION_BOX_BOX_FACT; + } +#endif //USE_FRICTION + aVel+= impulse; + bVel-= impulse; + aAngVel += BT_GPU_cross(contactPoint, impulse); + bAngVel -= BT_GPU_cross(contactPoint+aPos-bPos, impulse); + } + } + vel[aId]=BT_GPU_make_float42(aVel,0.0f); + vel[bId]=BT_GPU_make_float42(bVel,0.0f); + angularVel[aId]=BT_GPU_make_float42(aAngVel,0.0f); + angularVel[bId]=BT_GPU_make_float42(bAngVel,0.0f); + } +} // collisionBatchResolutionBox3DD() + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + + +extern "C" +{ + +// global functions + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints)) +{ + if(!numConstraints) + { + return; + } + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numConstraints, 256, numBlocks, numThreads); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, clearAccumulationOfLambdaDtD, (lambdaDtBox, numConstraints, numContPoints)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("clearAccumulationOfLambdaDtD kernel execution failed"); + +} // clearAccumulationOfLambdaDt() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(collisionWithWallBox3D(void* trans,void* vel,void* angVel,btCudaPartProps pProp, btCudaBoxProps gProp,int numObjs,float dt)) +{ + if(!numObjs) + { + return; + } + float4* pTrans = (float4*)trans; + float4* pVel = (float4*)vel; + float4* pAngVel = (float4*)angVel; + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numObjs, 256, numBlocks, numThreads); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionWithWallBox3DD, (pTrans,pVel,pAngVel,pProp,gProp,numObjs,dt)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("collisionWithWallBox3DD kernel execution failed"); +} // collisionWithWallBox3D() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(collisionBatchResolutionBox3D(void* constraints,int *batch,int numConstraints,void *trans,void *vel, + void *angularVel,float *lambdaDtBox,float *positionConstraint,void* normal,void* contact, + btCudaPartProps pProp,int iBatch,float dt)) +{ + if(!numConstraints) + { + return; + } + int2* pConstr = (int2*)constraints; + float4* pTrans = (float4*)trans; + float4* pVel = (float4*)vel; + float4* pAngVel = (float4*)angularVel; + float3* pNorm = (float3*)normal; + float3* pContact = (float3*)contact; + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numConstraints, 128, numBlocks, numThreads); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, collisionBatchResolutionBox3DD, (pConstr,batch,numConstraints,pTrans,pVel,pAngVel,lambdaDtBox,positionConstraint,pNorm,pContact,pProp,iBatch,dt)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("collisionBatchResolutionBox3DD kernel execution failed"); +} // collisionBatchResolutionBox3D() + +//---------------------------------------------------------------------------------------- + +} // extern "C" + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------- M o t i o n i n t e g r a t o r d e m o ----------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + +// kernel functions + +BT_GPU___global__ void integrVelD(float4* pForceTorqueDamp, float4* pInvInertiaMass, float4* pVel, float4* pAngVel, float timeStep, unsigned int numBodies) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + // unpack input data + float3 force = BT_GPU_make_float34(pForceTorqueDamp[index * 2]); + float lin_damp = pForceTorqueDamp[index * 2].w; + float3 torque = BT_GPU_make_float34(pForceTorqueDamp[index * 2 + 1]); + float ang_damp = pForceTorqueDamp[index * 2 + 1].w; + float3 linVel = BT_GPU_make_float34(pVel[index]); + float3 angVel = BT_GPU_make_float34(pAngVel[index]); + float3 in_mass_0 = BT_GPU_make_float34(pInvInertiaMass[index * 3]); + float3 in_mass_1 = BT_GPU_make_float34(pInvInertiaMass[index * 3 + 1]); + float3 in_mass_2 = BT_GPU_make_float34(pInvInertiaMass[index * 3 + 2]); + float mass = pInvInertiaMass[index * 3].w; + // integrate linear velocity + float3 outLinVel, outAngVel; + outLinVel = linVel + force * mass * timeStep; + // integrate angular velocity + outAngVel.x = BT_GPU_dot(in_mass_0, torque); + outAngVel.y = BT_GPU_dot(in_mass_1, torque); + outAngVel.z = BT_GPU_dot(in_mass_2, torque); + outAngVel += angVel; + /// clamp angular velocity. collision calculations will fail on higher angular velocities + #if(!defined(M_PI)) + #define M_PI 3.1415926f + #endif + #define BT_CUDA_MAX_SQ_ANGVEL (M_PI*M_PI) + float sq_angvel = BT_GPU_dot(outAngVel, outAngVel); + sq_angvel *= timeStep * timeStep; + float fact; + if(sq_angvel > BT_CUDA_MAX_SQ_ANGVEL) + { + fact = sqrtf(BT_CUDA_MAX_SQ_ANGVEL/sq_angvel) / timeStep; + outAngVel *= fact; + } + // now apply damping + fact = powf(1.0f - lin_damp, timeStep); + outLinVel *= fact; + fact = powf(1.0f - ang_damp, timeStep); + outAngVel *= fact; + // pack results + pVel[index] = BT_GPU_make_float42(outLinVel, 0.f); + pAngVel[index] = BT_GPU_make_float42(outAngVel, 0.f); +} // integrVelD() + +#define BT_GPU__ANGULAR_MOTION_THRESHOLD (0.25f * M_PI) + +//---------------------------------------------------------------------------------------- + +BT_GPU___device__ float4 getRotation(float4* trans) +{ + float trace = trans[0].x + trans[1].y + trans[2].z; + float temp[4]; + if(trace > 0.0f) + { + float s = sqrtf(trace + 1.0f); + temp[3] = s * 0.5f; + s = 0.5f / s; + temp[0] = (trans[1].z - trans[2].y) * s; + temp[1] = (trans[2].x - trans[0].z) * s; + temp[2] = (trans[0].y - trans[1].x) * s; + } + else + { + typedef float btMatrRow[4]; + btMatrRow* m_el = (btMatrRow*)trans; + int i = m_el[0][0] < m_el[1][1] ? + (m_el[1][1] < m_el[2][2] ? 2 : 1) : + (m_el[0][0] < m_el[2][2] ? 2 : 0); + int j = (i + 1) % 3; + int k = (i + 2) % 3; + float s = sqrtf(m_el[i][i] - m_el[j][j] - m_el[k][k] + 1.0f); + temp[i] = s * 0.5f; + s = 0.5f / s; + temp[3] = (m_el[j][k] - m_el[k][j]) * s; + temp[j] = (m_el[i][j] + m_el[j][i]) * s; + temp[k] = (m_el[i][k] + m_el[k][i]) * s; + } + float4 q = BT_GPU_make_float44(temp[0],temp[1],temp[2],temp[3]); + return q; +} // getRotation() + +//---------------------------------------------------------------------------------------- + +BT_GPU___device__ float4 quatMult(float4& q1, float4& q2) +{ + return BT_GPU_make_float44(q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y, + q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z, + q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x, + q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z); +} // quatMult() + +//---------------------------------------------------------------------------------------- + +BT_GPU___device__ void quatNorm(float4& q) +{ + float len = sqrtf(BT_GPU_dot4(q, q)); + q *= 1.f / len; +} // quatNorm() + +//---------------------------------------------------------------------------------------- + +BT_GPU___device__ void setRotation(float4& q, float4* trans) +{ + float d = BT_GPU_dot4(q, q); + float s = 2.0f / d; + float xs = q.x * s, ys = q.y * s, zs = q.z * s; + float wx = q.w * xs, wy = q.w * ys, wz = q.w * zs; + float xx = q.x * xs, xy = q.x * ys, xz = q.x * zs; + float yy = q.y * ys, yz = q.y * zs, zz = q.z * zs; + trans[0].x = 1.0f - (yy + zz); + trans[1].x = xy - wz; + trans[2].x = xz + wy; + trans[0].y = xy + wz; + trans[1].y = 1.0f - (xx + zz); + trans[2].y = yz - wx; + trans[0].z = xz - wy; + trans[1].z = yz + wx; + trans[2].z = 1.0f - (xx + yy); + trans[0].w = trans[1].w = trans[2].w = 0.0f; +} // setRotation() + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void integrTransD(float4* pTrans, float4* pVel, float4* pAngVel, float timeStep, unsigned int numBodies) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + float3 pos = BT_GPU_make_float34(pTrans[index * 4 + 3]); + float3 linvel = BT_GPU_make_float34(pVel[index]); + pos += linvel * timeStep; + + float3 axis; + float3 angvel = BT_GPU_make_float34(pAngVel[index]); + float fAngle = sqrtf(BT_GPU_dot(angvel, angvel)); + //limit the angular motion + if(fAngle*timeStep > BT_GPU__ANGULAR_MOTION_THRESHOLD) + { + fAngle = BT_GPU__ANGULAR_MOTION_THRESHOLD / timeStep; + } + if(fAngle < 0.001f) + { + // use Taylor's expansions of sync function + axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle); + } + else + { + // sync(fAngle) = sin(c*fAngle)/t + axis = angvel * ( sinf(0.5f * fAngle * timeStep) / fAngle); + } + float4 dorn = BT_GPU_make_float42(axis, cosf(fAngle * timeStep * 0.5f)); + float4 orn0 = getRotation(pTrans + index * 4); + float4 predictedOrn = quatMult(dorn, orn0); + quatNorm(predictedOrn); + setRotation(predictedOrn, pTrans + index * 4); + pTrans[index * 4 + 3] = BT_GPU_make_float42(pos, 0.f); +} // integrTransD() + + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + +// global functions + +extern "C" +{ + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(integrVel(float* pForceTorqueDamp, float* pInvInertiaMass, void* pVel, void* pAngVel, float timeStep, unsigned int numBodies)) +{ + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads); + BT_GPU_EXECKERNEL(numBlocks, numThreads, integrVelD, ((float4*)pForceTorqueDamp, (float4*)pInvInertiaMass, (float4*)pVel, (float4*)pAngVel, timeStep, numBodies)); + BT_GPU_CHECK_ERROR("Kernel execution failed: btCuda_integrVelD"); +} // integrVel() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(integrTrans(void* trans, void* vel, void* angVel, float timeStep, int numBodies)) +{ + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads); + BT_GPU_EXECKERNEL(numBlocks, numThreads, integrTransD, ((float4*)trans, (float4*)vel, (float4*)angVel, timeStep, numBodies)); + BT_GPU_CHECK_ERROR("Kernel execution failed: btCuda_integrTransD"); +} // integrTrans() + +//---------------------------------------------------------------------------------------- + +} // extern "C" + +//------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------- diff --git a/Demos/Gpu3dDemo/btGpuDemo3dSharedDefs.h b/Demos/Gpu3dDemo/btGpuDemo3dSharedDefs.h new file mode 100644 index 0000000..d0abea4 --- /dev/null +++ b/Demos/Gpu3dDemo/btGpuDemo3dSharedDefs.h @@ -0,0 +1,38 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------- C o n s t r a i n t s o l v e r d e m o ---------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + + +extern "C" +{ + +void BT_GPU_PREF(clearAccumulationOfLambdaDt(float* lambdaDtBox, int numConstraints, int numContPoints)); +void BT_GPU_PREF(collisionWithWallBox3D(void* trans,void* vel,void* angVel,btCudaPartProps pProp, btCudaBoxProps gProp,int numObjs,float dt)); +void BT_GPU_PREF(collisionBatchResolutionBox3D(void* constraints,int *batch,int numConstraints,void *trans,void *vel, + void *angularVel,float *lambdaDtBox,float *positionConstraint,void* normal,void* contact, + btCudaPartProps pProp,int iBatch,float dt)); + +void BT_GPU_PREF(integrVel(float* pForceTorqueDamp, float* pInvInertiaMass, void* pVel, void* pAngVel, float timeStep, unsigned int numBodies)); +void BT_GPU_PREF(integrTrans(void* trans, void* vel, void* angVel, float timeStep, int numBodies)); + + +} // extern "C" + +//---------------------------------------------------------------------------------------- diff --git a/Demos/Gpu3dDemo/btGpuDemo3dSharedTypes.h b/Demos/Gpu3dDemo/btGpuDemo3dSharedTypes.h new file mode 100644 index 0000000..2d6400e --- /dev/null +++ b/Demos/Gpu3dDemo/btGpuDemo3dSharedTypes.h @@ -0,0 +1,39 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------- C o n s t r a i n t s o l v e r d e m o ---------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + +struct btCudaPartProps +{ + float m_mass; + float m_diameter; + float m_restCoeff; +}; + +struct btCudaBoxProps +{ + float minX; + float maxX; + float minY; + float maxY; + float minZ; + float maxZ; +}; + +//---------------------------------------------------------------------------------------- diff --git a/Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.cpp b/Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.cpp new file mode 100644 index 0000000..3398c96 --- /dev/null +++ b/Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.cpp @@ -0,0 +1,593 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//-------------------------------------------------------------------------- + +#include "btGpuDemoDynamicsWorld3D.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "LinearMath/btQuickprof.h" +#include "GlutStuff.h" + +#include + +//-------------------------------------------------------------------------- + +#define BT_GPU_PREF(func) btCuda_##func +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "btGpuDemo3dSharedDefs.h" +#undef BT_GPU_PREF + +#define BT_GPU_PREF(func) btGpu_##func +#include "btGpuDemo3dSharedDefs.h" +#undef BT_GPU_PREF + +//-------------------------------------------------------------------------- + +#if 0 +static void check_vel(btVector3& v, int id, char* tag) +{ + int i; + for(i = 0; i < 3; i++) + { + btScalar a = v[i]; + a = btFabs(a); + if(a > 1000.f) + { + break; + } + } + if(i < 3) + { + printf("\nERROR in %s (%4d) : %7.2f %7.2f %7.2f\n", tag, id, v[0], v[1], v[2]); + v[0] = v[1] = v[2] = 0.f; + } +} +#endif + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::grabObjData() +{ + int i; + m_numObj = getNumCollisionObjects(); + for(i = 0; i < m_numObj; i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + colObj->setCompanionId(i); + btRigidBody* rb = btRigidBody::upcast(colObj); + btVector3 v; + if(m_copyIntegrDataToGPU) + { + const btTransform& tr = rb->getCenterOfMassTransform(); + v = tr.getBasis().getColumn(0); + m_hTrans[i * 4 + 0] = *((float4*)&v); + v = tr.getBasis().getColumn(1); + m_hTrans[i * 4 + 1] = *((float4*)&v); + v = tr.getBasis().getColumn(2); + m_hTrans[i * 4 + 2] = *((float4*)&v); + v = rb->getCenterOfMassPosition(); + m_hTrans[i * 4 + 3] = *((float4*)&v); + } + if(!m_useCudaMotIntegr) + { + v = rb->getLinearVelocity(); + m_hVel[i] = *((float4*)&v); + v = rb->getAngularVelocity(); + m_hAngVel[i] = *((float4*)&v); + } + } +} // btCudaDemoDynamicsWorld3D::grabObjData() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::grabConstrData() +{ + int i; + btDispatcher* dispatcher = getDispatcher(); + btPersistentManifold** manifoldPtr = dispatcher->getInternalManifoldPointer(); + int numManifolds = dispatcher->getNumManifolds(); + btPersistentManifold* manifold = 0; + m_numConstraints = 0; + +/* // paranoia + for(int j = 0; j < m_numObj; j++) + { + m_hConstraintCounter[j] = 0; + } +*/ + for(i = 0; i < numManifolds; i++) + { + manifold = manifoldPtr[i]; + int numPoints = manifold->getNumContacts(); + if(!numPoints) + { + continue; + } + + int numActualPoints = 0; + for(int n = 0; n < numPoints; n++) + { + btManifoldPoint& cp = manifold->getContactPoint(n); + if (cp.m_distance1<=0) + { + numActualPoints++; + } + + } + if (!numActualPoints) + continue; + + btRigidBody *rbA, *rbB; + rbA = (btRigidBody*)manifold->getBody0(); + rbB = (btRigidBody*)manifold->getBody1(); + int idA = rbA->getCompanionId(); + int idB = rbB->getCompanionId(); + m_hConstraintCounter[idA]++; + m_hConstraintCounter[idB]++; + if(idA < idB) + { + m_hIds[m_numConstraints].x = idA; + m_hIds[m_numConstraints].y = idB; + + for(int n = 0; n < numPoints; n++) + { + btManifoldPoint& cp = manifold->getContactPoint(n); + btVector3 v = cp.getPositionWorldOnA(); + m_hContact[m_numConstraints * m_maxPointsPerConstr + n] = *((float3*)&v); + v = cp.m_normalWorldOnB; + m_hNormal[m_numConstraints * m_maxPointsPerConstr + n] = *((float3*)&v); + float dist = cp.getDistance(); + if(dist > 0.f) + { + dist = 0.f; + } + m_hPositionConstraint[m_numConstraints * m_maxPointsPerConstr + n] = -dist; + } + } + else + { // should never happen + btAssert(0); + } + for(int n = numPoints; n < m_maxPointsPerConstr; n++) + { + m_hPositionConstraint[m_numConstraints * m_maxPointsPerConstr + n] = 0.f; + } + m_numConstraints++; + } +/* + // paranoia + for(int j = 0; j < m_numObj; j++) + { + if(m_hConstraintCounter[j] > m_maxNeihbors) + { + printf("WARN : constraint connter is %d for object %d\n", m_hConstraintCounter[j], j); + } + } +*/ +} // btCudaDemoDynamicsWorld3D::grabConstrData() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::grabData() +{ + BT_PROFILE("grab data from rigidbody and manifold"); + grabObjData(); + // constraints + grabConstrData(); +} // btCudaDemoDynamicsWorld3D::grabGata() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::createBatches() +{ + BT_PROFILE("create batches"); + int sz = m_numConstraints; + for(int i = 0; i < m_numConstraints; i++) + { + m_hBatchIds[i] = -1; + m_hConstraintUsed[i] = 0; + } + int curBatchId=0; + int* pBatchIds = m_hBatchIds; + int stage; + for(stage = 0; stage < m_maxBatches; stage++) + { // don't print junk on demo screen :-) + m_numInBatches[stage] = 0; + } + for(stage = 0; stage < m_maxBatches; stage++) + { + bool isLast = (stage == m_maxBatches-1); + for(int j = 0; j < m_numObj; j++) + { + m_hConstraintCounter[j] = 0; + } + int numInBatch = 0; + for(int i = 0; i < m_numConstraints; i++) + { + if(m_hConstraintUsed[i]) + { + continue; + } + int2 ids = m_hIds[i]; + if(!isLast) + { + if((m_hConstraintCounter[ids.x] == 0) && (m_hConstraintCounter[ids.y] == 0)) + { + m_hConstraintCounter[ids.x]=1; + m_hConstraintCounter[ids.y]=1; + pBatchIds[numInBatch]=i; + numInBatch++; + m_hConstraintUsed[i] = 1; + } + } + else + { + pBatchIds[numInBatch]=i; + numInBatch++; + m_hConstraintUsed[i] = 1; + } + } + m_numInBatches[stage] = numInBatch; + pBatchIds += numInBatch; + if(!numInBatch) break; + } +} // btCudaDemoDynamicsWorld3D::createBatches() + +//-------------------------------------------------------------------------- + + +void btCudaDemoDynamicsWorld3D::writebackData() +{ + BT_PROFILE("copy velocity into btRigidBody"); + for(int i = 0; i < m_numObj; i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + btRigidBody* rb = btRigidBody::upcast(colObj); + btVector3 v; + v = *((btVector3*)(m_hVel + i)); + rb->setLinearVelocity(v); + v = *((btVector3*)(m_hAngVel + i)); + rb->setAngularVelocity(v); + } +} // btCudaDemoDynamicsWorld3D::writebackData() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::copyDataToGPU() +{ + BT_PROFILE("copyDataToGPU"); +#ifdef BT_USE_CUDA + btCuda_copyArrayToDevice(m_dIds, m_hIds, sizeof(int2) * m_numConstraints); + btCuda_copyArrayToDevice(m_dBatchIds, m_hBatchIds, sizeof(int) * m_numConstraints); + btCuda_copyArrayToDevice(m_dContact, m_hContact, m_numConstraints * m_maxPointsPerConstr * sizeof(float3)); + btCuda_copyArrayToDevice(m_dNormal, m_hNormal, m_numConstraints * m_maxPointsPerConstr * sizeof(float3)); + btCuda_copyArrayToDevice(m_dPositionConstraint, m_hPositionConstraint, m_numConstraints * m_maxPointsPerConstr * sizeof(float)); + + if(m_copyIntegrDataToGPU) + { + btCuda_copyArrayToDevice(m_dTrans, m_hTrans, m_numObj * sizeof(float4) * 4); + if(m_useCudaMotIntegr) + { + m_copyIntegrDataToGPU = false; + } + } + + if(!m_useCudaMotIntegr) + { + btCuda_copyArrayToDevice(m_dVel, m_hVel, m_numObj * sizeof(float4)); + btCuda_copyArrayToDevice(m_dAngVel, m_hAngVel, m_numObj * sizeof(float4)); + } +#endif +} // btCudaDemoDynamicsWorld3D::copyDataToGPU() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::copyDataFromGPU() +{ + BT_PROFILE("copy velocity data from device"); +#ifdef BT_USE_CUDA + btCuda_copyArrayFromDevice(m_hVel, m_dVel, m_numObj * sizeof(float4)); + btCuda_copyArrayFromDevice(m_hAngVel, m_dAngVel, m_numObj * sizeof(float4)); +#endif +} // btCudaDemoDynamicsWorld3D::copyDataFromGPU() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::solveConstraints(btContactSolverInfo& solverInfo) +{ + if(m_useSeqImpSolver) + { + btDiscreteDynamicsWorld::solveConstraints(solverInfo); + return; + } + if(m_useCPUSolver) + { + solveConstraintsCPU(solverInfo); + return; + } +#ifdef BT_USE_CUDA + BT_PROFILE("solveConstraints"); + grabData(); + createBatches(); + copyDataToGPU(); + + btCudaPartProps partProps; + partProps.m_mass = 1.0f; + partProps.m_diameter = m_objRad * 2.0f; + partProps.m_restCoeff = 1.0f; + + btCudaBoxProps boxProps; + boxProps.minX = m_worldMin[0]; + boxProps.maxX = m_worldMax[0]; + boxProps.minY = m_worldMin[1]; + boxProps.maxY = m_worldMax[1]; + boxProps.minZ = m_worldMin[2]; + boxProps.maxZ = m_worldMax[2]; + { + BT_PROFILE("btCuda_collisionBatchResolutionBox"); + + int nIter=getSolverInfo().m_numIterations; + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + btScalar timeStep = dispatchInfo.m_timeStep; + + btCuda_clearAccumulationOfLambdaDt(m_dLambdaDtBox, m_numConstraints, m_maxPointsPerConstr); + + for(int i=0;igetWorldTransform().getOrigin(); + btVector3 vB = colObjB->getWorldTransform().getOrigin(); + glVertex3f(vA[0], vA[1], vA[2]); + glVertex3f(vB[0], vB[1], vB[2]); + } + pBatchIds += numConstraints; + glEnd(); + } +} // btCudaDemoDynamicsWorld3D::debugDrawConstraints() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::predictUnconstraintMotion(btScalar timeStep) +{ + if(m_useCudaMotIntegr) + { + BT_PROFILE("motIntegr -- predictUnconstraintMotion"); + int i; + { + m_numObj = getNumCollisionObjects(); + float* p_fbuf = m_hForceTorqueDamp; + float* p_mbuf = m_hInvInertiaMass; + for(i = 0; i < m_numObj; i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + btRigidBody* rb = btRigidBody::upcast(colObj); + btVector3* pForce = (btVector3*)p_fbuf; + *pForce = rb->getTotalForce(); + p_fbuf[3] = rb->getLinearDamping(); + p_fbuf += 4; + btVector3* pTorque = (btVector3*)p_fbuf; + *pTorque = rb->getTotalTorque(); + p_fbuf[3] = rb->getAngularDamping(); + p_fbuf += 4; + if(m_copyIntegrDataToGPU) + { + for(int k = 0; k < 3; k++) + { + btVector3* pInert = (btVector3*)(p_mbuf + k * 4); + *pInert = rb->getInvInertiaTensorWorld().getRow(k); + } + p_mbuf[3] = rb->getInvMass(); + p_mbuf += 12; + } + btVector3 v = rb->getLinearVelocity(); + m_hVel[i] = *((float4*)&v); + v = rb->getAngularVelocity(); + m_hAngVel[i] = *((float4*)&v); + } + } + if(m_useCPUSolver) + { + //BT_PROFILE("motIntegr -- integrate on CPU"); + btGpu_integrVel(m_hForceTorqueDamp, m_hInvInertiaMass, m_hVel, m_hAngVel, timeStep, m_numObj); + writebackData(); + } + else + { +#ifdef BT_USE_CUDA + //BT_PROFILE("CUDA motIntegr -- integrate on CUDA"); + btCuda_copyArrayToDevice(m_dForceTorqueDamp, m_hForceTorqueDamp, sizeof(float) * m_numObj * 4 * 2); + if(m_copyIntegrDataToGPU) + { + btCuda_copyArrayToDevice(m_dInvInertiaMass, m_hInvInertiaMass, sizeof(float) * m_numObj * 4 * 3); + } + btCuda_copyArrayToDevice(m_dVel, m_hVel, m_numObj * sizeof(float4)); + btCuda_copyArrayToDevice(m_dAngVel, m_hAngVel, m_numObj * sizeof(float4)); + btCuda_integrVel(m_dForceTorqueDamp, m_dInvInertiaMass, m_dVel, m_dAngVel, timeStep, m_numObj); + copyDataFromGPU(); + writebackData(); +#endif + } + } + else + { + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + m_copyIntegrDataToGPU = true; + } +} // btCudaDemoDynamicsWorld3D::predictUnconstraintMotion() + +//-------------------------------------------------------------------------- + +void btCudaDemoDynamicsWorld3D::integrateTransforms(btScalar timeStep) +{ + if(m_useCudaMotIntegr) + { + BT_PROFILE("motIntegr -- integrateTransforms"); + if(m_useCPUSolver) + { + btGpu_integrTrans(m_hTrans, m_hVel, m_hAngVel, timeStep, m_numObj); + } + else + { +#ifdef BT_USE_CUDA + btCuda_integrTrans(m_dTrans, m_dVel, m_dAngVel, timeStep, m_numObj); + btCuda_copyArrayFromDevice(m_hTrans, m_dTrans, m_numObj * sizeof(float4) * 4); +#endif + } + m_numObj = getNumCollisionObjects(); + for(int i = 0; i < m_numObj; i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + btRigidBody* rb = btRigidBody::upcast(colObj); + btVector3 v; + btTransform tr; + const btVector3& v0 = *((btVector3*)&m_hTrans[i * 4 + 0]); + const btVector3& v1 = *((btVector3*)&m_hTrans[i * 4 + 1]); + const btVector3& v2 = *((btVector3*)&m_hTrans[i * 4 + 2]); + const btVector3& v3 = *((btVector3*)&m_hTrans[i * 4 + 3]); + tr.getBasis().setValue(v0[0], v1[0], v2[0], v0[1], v1[1], v2[1], v0[2], v1[2], v2[2]); + tr.getOrigin().setValue(v3[0], v3[1], v3[2]); + rb->proceedToTransform(tr); + } + } + else + { + btDiscreteDynamicsWorld::integrateTransforms(timeStep); + } +} // btCudaDemoDynamicsWorld3D::integrateTransforms() + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- diff --git a/Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.h b/Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.h new file mode 100644 index 0000000..845e8f7 --- /dev/null +++ b/Demos/Gpu3dDemo/btGpuDemoDynamicsWorld3D.h @@ -0,0 +1,252 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CUDA_DEMO_DYNAMICS_WORLD3D_H +#define BT_CUDA_DEMO_DYNAMICS_WORLD3D_H + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" + +//#define BT_USE_CUDA 1 +// To enable CUDA : +// 1. Uncomment //#define BT_USE_CUDA 1 +// 2. Build and add libbulletcuda (Extras/CUDA) to project +// 3. Add $(CUDA_LIB_PATH) and cudart.lib to linker properties + + +#ifdef BT_USE_CUDA + #include "BulletMultiThreaded/btGpuDefines.h" + #undef BT_GPU_PREF + #define BT_GPU_PREF(func) btCuda_##func + #include "BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#else + #include "BulletMultiThreaded/btGpuDefines.h" + #include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#endif + +#undef BT_GPU_PREF + + +#if 0 // ### +#include +#define BT_GPU_PREF(func) btCuda_##func +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#undef BT_GPU_PREF +#endif + +#include "btGpuDemo3dSharedTypes.h" + +//#define CUDA_DEMO_DYNAMICS_WORLD3D_MAX_BATCHES 20 +#define CUDA_DEMO_DYNAMICS_WORLD3D_MAX_BATCHES 15 + +class btCudaDemoDynamicsWorld3D : public btDiscreteDynamicsWorld +{ +protected: + int m_maxObj; + int m_maxNeihbors; + int m_maxConstr; + int m_maxPointsPerConstr; + + int m_numObj; + int m_numSimStep; + bool m_useCPUSolver; + bool m_useSeqImpSolver; + bool m_useCudaMotIntegr; + bool m_copyIntegrDataToGPU; + + +#ifdef BT_USE_CUDA + float4* m_dTrans; + float4* m_dVel; + float4* m_dAngVel; + int2* m_dIds; + int* m_dBatchIds; + float* m_dLambdaDtBox; + float* m_dPositionConstraint; + float3* m_dNormal; + float3* m_dContact; + float* m_dForceTorqueDamp; + float* m_dInvInertiaMass; +#endif + + float4* m_hTrans; + float4* m_hVel; + float4* m_hAngVel; + int* m_hConstraintBuffer; + int* m_hConstraintCounter; + int m_maxBatches; + int m_numBatches; + int m_numConstraints; + int2* m_hIds; + int* m_hBatchIds; + + int m_maxVtxPerObj; + + + // ------------- these are only needed for CPU version and for debugging + float* m_hLambdaDtBox; + float* m_hPositionConstraint; + float3* m_hNormal; + float3* m_hContact; + // ------------- + + btScalar m_objRad; + btVector3 m_worldMin; + btVector3 m_worldMax; + + //------------------------------- + int* m_hConstraintUsed; + + //------------------------------- + + float* m_hForceTorqueDamp; + float* m_hInvInertiaMass; + +public: + int m_numInBatches[CUDA_DEMO_DYNAMICS_WORLD3D_MAX_BATCHES]; + + + btCudaDemoDynamicsWorld3D(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration, int maxPointsPerConstr = 4) + : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration) + { + m_useCPUSolver = false; + m_useSeqImpSolver = false; + m_useCudaMotIntegr = true; + m_copyIntegrDataToGPU = true; + m_maxObj = 32768; + m_maxNeihbors = 26; + m_maxConstr = m_maxObj * m_maxNeihbors; + int sz = m_maxConstr; + m_hConstraintBuffer = new int[sz]; + m_hConstraintCounter = new int[m_maxObj]; + m_maxBatches = CUDA_DEMO_DYNAMICS_WORLD3D_MAX_BATCHES; + m_hIds = new int2[sz]; + m_hBatchIds = new int[sz]; + for(int i = 0; i < sz; i++) + { + m_hBatchIds[i] = -1; + } + m_hTrans = new float4[m_maxObj * 4]; + m_hVel = new float4[m_maxObj]; + m_hAngVel = new float4[m_maxObj]; + + m_maxPointsPerConstr = maxPointsPerConstr; + +#ifdef BT_USE_CUDA + btCuda_allocateArray((void**)&m_dTrans, sizeof(float4) * m_maxObj * 4); + btCuda_allocateArray((void**)&m_dVel, sizeof(float4) * m_maxObj); + btCuda_allocateArray((void**)&m_dAngVel, sizeof(float4) * m_maxObj); + + btCuda_allocateArray((void**)&m_dIds, sizeof(int2) * sz); + btCuda_allocateArray((void**)&m_dBatchIds, sizeof(int) * sz); + + + btCuda_allocateArray((void**)&m_dLambdaDtBox, sizeof(float) * sz * m_maxPointsPerConstr); + btCuda_allocateArray((void**)&m_dPositionConstraint, sizeof(float) * sz * m_maxPointsPerConstr); + btCuda_allocateArray((void**)&m_dNormal, sizeof(float3) * sz * m_maxPointsPerConstr); + btCuda_allocateArray((void**)&m_dContact, sizeof(float3) * sz * m_maxPointsPerConstr); + + btCuda_allocateArray((void**)&m_dForceTorqueDamp, sizeof(float) * m_maxObj * 4 * 2); + btCuda_allocateArray((void**)&m_dInvInertiaMass, sizeof(float) * m_maxObj * 4 * 3); +#endif + + m_hLambdaDtBox = new float[sz * m_maxPointsPerConstr]; + m_hPositionConstraint = new float[sz * m_maxPointsPerConstr]; + m_hNormal = new float3[sz * m_maxPointsPerConstr]; + m_hContact = new float3[sz * m_maxPointsPerConstr]; + + m_numSimStep = 0; + + m_objRad = 1.0f; + + m_hConstraintUsed = new int[sz]; + + m_hForceTorqueDamp = new float[m_maxObj * 4 * 2]; + m_hInvInertiaMass = new float[4 * m_maxObj * 3]; + + } + virtual ~btCudaDemoDynamicsWorld3D() + { + delete [] m_hConstraintBuffer; + delete [] m_hConstraintCounter; + delete [] m_hIds; + delete [] m_hBatchIds; + delete [] m_hTrans; + delete [] m_hVel; + delete [] m_hAngVel; + + delete [] m_hLambdaDtBox; + delete [] m_hPositionConstraint; + delete [] m_hNormal; + delete [] m_hContact; + delete [] m_hConstraintUsed; + + delete [] m_hForceTorqueDamp; + delete [] m_hInvInertiaMass; + + +#ifdef BT_USE_CUDA + btCuda_freeArray(m_dTrans); + btCuda_freeArray(m_dVel); + btCuda_freeArray(m_dAngVel); + + btCuda_freeArray(m_dIds); + btCuda_freeArray(m_dBatchIds); + btCuda_freeArray(m_dLambdaDtBox); + btCuda_freeArray(m_dPositionConstraint); + btCuda_freeArray(m_dNormal); + btCuda_freeArray(m_dContact); + btCuda_freeArray(m_dForceTorqueDamp); + btCuda_freeArray(m_dInvInertiaMass); +#endif + + } + virtual void calculateSimulationIslands() + { + if(m_useSeqImpSolver) + { + btDiscreteDynamicsWorld::calculateSimulationIslands(); + } + } + virtual void solveConstraints(btContactSolverInfo& solverInfo); + + virtual void predictUnconstraintMotion(btScalar timeStep); + virtual void integrateTransforms(btScalar timeStep); + + + + + void solveConstraintsCPU(btContactSolverInfo& solverInfo); + + void debugDrawConstraints(int selectedBatch, const float* pColorTab); + + void setObjRad(btScalar rad) { m_objRad = rad; } + void setWorldMin(const btVector3& worldMin) { m_worldMin = worldMin; } + void setWorldMax(const btVector3& worldMax) { m_worldMax = worldMax; } + + void grabData(); + void grabObjData(); + void grabConstrData(); + void createBatches(); + void copyDataToGPU(); + void copyDataFromGPU(); + void writebackData(); + void setUseCPUSolver(bool useCPU) { m_useCPUSolver = useCPU; } + void setUseSeqImpSolver(bool useSeqImpSolver) { m_useSeqImpSolver = useSeqImpSolver; } + void setUseCudaMotIntegr(bool useCudaMotIntegr) { m_useCudaMotIntegr = useCudaMotIntegr; } + void resetScene(void) { m_copyIntegrDataToGPU = true; } +}; + + +#endif //BT_CUDA_DEMO_DYNAMICS_WORLD3D_H diff --git a/Demos/Gpu3dDemo/main.cpp b/Demos/Gpu3dDemo/main.cpp new file mode 100644 index 0000000..f5eea80 --- /dev/null +++ b/Demos/Gpu3dDemo/main.cpp @@ -0,0 +1,61 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BasicDemo3d.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + +class OurValue + { + int m_uid; + + public: + OurValue(const btVector3& initialPos) + :m_position(initialPos) + { + static int gUid=0; + m_uid=gUid; + gUid++; + } + + btVector3 m_position; + int getUid() const + { + return m_uid; + } + }; + + +int main(int argc,char** argv) +{ + GLDebugDrawer gDebugDrawer; + + BasicDemo3D ccdDemo; + ccdDemo.initPhysics(); + ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + ccdDemo.setWireMode(false); + + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} diff --git a/Demos/GyroscopicDemo/CMakeLists.txt b/Demos/GyroscopicDemo/CMakeLists.txt new file mode 100644 index 0000000..828b9c4 --- /dev/null +++ b/Demos/GyroscopicDemo/CMakeLists.txt @@ -0,0 +1,71 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppGyroscopicDemo + GyroscopicDemo.cpp + GyroscopicDemo.h + main.cpp + ) + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppGyroscopicDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppGyroscopicDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}/Debug + + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) +ELSE (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppGyroscopicDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32GyroscopicDemo.cpp + GyroscopicDemo.cpp + GyroscopicDemo.h + ) +ENDIF (USE_GLUT) + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppGyroscopicDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppGyroscopicDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppGyroscopicDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/GyroscopicDemo/GyroscopicDemo.cpp b/Demos/GyroscopicDemo/GyroscopicDemo.cpp new file mode 100644 index 0000000..ffde57c --- /dev/null +++ b/Demos/GyroscopicDemo/GyroscopicDemo.cpp @@ -0,0 +1,240 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" + +#include "GLDebugDrawer.h" + +#include "GLDebugFont.h" +#include //printf debugging + +#include "GyroscopicDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + + +#include "GLDebugDrawer.h" +static GLDebugDrawer gDebugDrawer; + + + + + +void GyroscopicDemo::setupEmptyDynamicsWorld() +{ + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_overlappingPairCache = new btDbvtBroadphase(); + m_constraintSolver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); +} + +void GyroscopicDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} +void GyroscopicDemo::initPhysics() +{ + m_azi=90; + m_ele = 20; + + setTexturing(true); + setShadows(true); + setCameraUp(btVector3(0,0,1)); + setCameraForwardAxis(1); + m_sundirection.setValue(0,-1,-1); + setCameraDistance(7.f); + + setupEmptyDynamicsWorld(); + m_dynamicsWorld->setGravity(btVector3(0,0,-9.8)); + m_dynamicsWorld->setDebugDrawer(&gDebugDrawer); + + + //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(0.5))); + btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,0,1),0); + + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,0,0)); + btRigidBody* groundBody; + groundBody= localCreateRigidBody(0, groundTransform, groundShape); + groundBody->setFriction(btSqrt(2)); + btVector3 positions[2] = { + btVector3(0.8,-2,2), + btVector3(0.8,2,2) + }; + bool gyro[2] = { + true, + false + }; + + for (int i=0;i<2;i++) + { + btCylinderShapeZ* top = new btCylinderShapeZ(btVector3(1,1,0.125)); + btCapsuleShapeZ* pin = new btCapsuleShapeZ(0.05,1.5); + top->setMargin(0.01); + pin->setMargin(0.01); + btCompoundShape* compound = new btCompoundShape(); + compound->addChildShape(btTransform::getIdentity(),top); + compound->addChildShape(btTransform::getIdentity(),pin); + btVector3 localInertia; + top->calculateLocalInertia(1,localInertia); + btRigidBody* body = new btRigidBody(1,0,compound,localInertia); + btTransform tr; + tr.setIdentity(); + tr.setOrigin(positions[i]); + body->setCenterOfMassTransform(tr); + body->setAngularVelocity(btVector3(0,0,15)); + body->setLinearVelocity(btVector3(0,.2,0)); + body->setFriction(btSqrt(1)); + m_dynamicsWorld->addRigidBody(body); + if (gyro[i]) + { + body->setFlags(BT_ENABLE_GYROPSCOPIC_FORCE); + } else + { + body->setFlags(0); + } + body->setDamping(0.00001f,0.0001f); + + + } + +} + +void GyroscopicDemo::exitPhysics() +{ + + int i; + + //removed/delete constraints + for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--) + { + btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); + m_dynamicsWorld->removeConstraint(constraint); + delete constraint; + } + + //remove the rigidbodies from the dynamics world and delete them + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + + + + //delete collision shapes + for (int j=0;jgetDebugDrawer() && once) + { + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits); + once=false; + } + } + + + { + //during idle mode, just run 1 simulation step maximum + + int numSimSteps = m_dynamicsWorld->stepSimulation(dt,100,1./1000.f); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + + } + renderme(); + + + glFlush(); + swapBuffers(); +} + + + + +void GyroscopicDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + + renderme(); + + glFlush(); + swapBuffers(); +} + + diff --git a/Demos/GyroscopicDemo/GyroscopicDemo.h b/Demos/GyroscopicDemo/GyroscopicDemo.h new file mode 100644 index 0000000..8925fa5 --- /dev/null +++ b/Demos/GyroscopicDemo/GyroscopicDemo.h @@ -0,0 +1,71 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_GYROSCOPIC_DEMO_H +#define BT_GYROSCOPIC_DEMO_H + +#ifdef _WINDOWS +#include "Win32DemoApplication.h" +#define PlatformDemoApplication Win32DemoApplication +#else +#include "GlutDemoApplication.h" +#define PlatformDemoApplication GlutDemoApplication +#endif + +///GyroscopicDemo shows how to create a constraint, like Hinge or btGenericD6constraint +class GyroscopicDemo : public PlatformDemoApplication +{ + //keep track of variables to delete memory at the end + btAlignedObjectArray m_collisionShapes; + + class btBroadphaseInterface* m_overlappingPairCache; + + class btCollisionDispatcher* m_dispatcher; + + class btConstraintSolver* m_constraintSolver; + + class btDefaultCollisionConfiguration* m_collisionConfiguration; + + void setupEmptyDynamicsWorld(); + + void clientResetScene(); + + + public: + + GyroscopicDemo(); + + virtual ~GyroscopicDemo(); + + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + GyroscopicDemo* demo = new GyroscopicDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //BT_GYROSCOPIC_DEMO_H + diff --git a/Demos/GyroscopicDemo/Win32GyroscopicDemo.cpp b/Demos/GyroscopicDemo/Win32GyroscopicDemo.cpp new file mode 100644 index 0000000..37c36ff --- /dev/null +++ b/Demos/GyroscopicDemo/Win32GyroscopicDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "GyroscopicDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new GyroscopicDemo(); +} + +#endif diff --git a/Demos/GyroscopicDemo/main.cpp b/Demos/GyroscopicDemo/main.cpp new file mode 100644 index 0000000..ca2caaa --- /dev/null +++ b/Demos/GyroscopicDemo/main.cpp @@ -0,0 +1,20 @@ +#include "GyroscopicDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" + +#include "btBulletDynamicsCommon.h" + +int main(int argc,char** argv) +{ + + + + GyroscopicDemo* constraintDemo = new GyroscopicDemo(); + + + constraintDemo->initPhysics(); + constraintDemo->setDebugMode(btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits); + + return glutmain(argc, argv,640,480,"Constraint Demo. http://www.continuousphysics.com/Bullet/phpBB2/",constraintDemo); +} + diff --git a/Demos/HelloWorld/CMakeLists.txt b/Demos/HelloWorld/CMakeLists.txt new file mode 100644 index 0000000..a0ed460 --- /dev/null +++ b/Demos/HelloWorld/CMakeLists.txt @@ -0,0 +1,29 @@ +# HelloWorld is a minimal sample creating, stepping and deleting a Bullet dynamics world + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + +LINK_LIBRARIES( + BulletDynamics BulletCollision LinearMath +) + +IF (WIN32) + ADD_EXECUTABLE(AppHelloWorld + HelloWorld.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppHelloWorld + HelloWorld.cpp + ) +ENDIF() + + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/HelloWorld/HelloWorld.cpp b/Demos/HelloWorld/HelloWorld.cpp new file mode 100644 index 0000000..f1934b2 --- /dev/null +++ b/Demos/HelloWorld/HelloWorld.cpp @@ -0,0 +1,180 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///-----includes_start----- +#include "btBulletDynamicsCommon.h" +#include + +/// This is a Hello World program for running a basic Bullet physics simulation + +int main(int argc, char** argv) +{ + ///-----includes_end----- + + int i; + ///-----initialization_start----- + + ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. + btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); + + ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. + btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; + + btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration); + + dynamicsWorld->setGravity(btVector3(0,-10,0)); + + ///-----initialization_end----- + + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + + //keep track of the shapes, we release memory at exit. + //make sure to re-use collision shapes among rigid bodies whenever possible! + btAlignedObjectArray collisionShapes; + + collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-56,0)); + + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + dynamicsWorld->addRigidBody(body); + } + + + { + //create a dynamic rigidbody + + //btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); + btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + collisionShapes.push_back(colShape); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); + + startTransform.setOrigin(btVector3(2,10,0)); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + dynamicsWorld->addRigidBody(body); + } + + + +/// Do some simulation + + + ///-----stepsimulation_start----- + for (i=0;i<100;i++) + { + dynamicsWorld->stepSimulation(1.f/60.f,10); + + //print positions of all objects + for (int j=dynamicsWorld->getNumCollisionObjects()-1; j>=0 ;j--) + { + btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + btTransform trans; + body->getMotionState()->getWorldTransform(trans); + printf("world pos = %f,%f,%f\n",float(trans.getOrigin().getX()),float(trans.getOrigin().getY()),float(trans.getOrigin().getZ())); + } + } + } + + ///-----stepsimulation_end----- + + //cleanup in the reverse order of creation/initialization + + ///-----cleanup_start----- + + //remove the rigidbodies from the dynamics world and delete them + for (i=dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jm_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(float friction0,float friction1) +{ + return 0.f; + btScalar friction = friction0 * friction1; + + const btScalar MAX_FRICTION = 10.f; + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(float restitution0,float restitution1) +{ + return restitution0 * restitution1; +} + + +/////////////////////////////////////////////////////////////// + + +static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) +{ + + if (enable) + { + btAdjustInternalEdgeContacts(cp,colObj1Wrap,colObj0Wrap, partId1,index1); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); + } + + float friction0 = colObj0Wrap->getCollisionObject()->getFriction(); + float friction1 = colObj1Wrap->getCollisionObject()->getFriction(); + float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution(); + float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution(); + + if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + friction0 = 1.0;//partId0,index0 + restitution0 = 0.f; + } + if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + if (index1&1) + { + friction1 = 1.0f;//partId1,index1 + } else + { + friction1 = 0.f; + } + restitution1 = 0.f; + } + + cp.m_combinedFriction = calculateCombinedFriction(friction0,friction1); + cp.m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); + + //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction + return true; +} + +extern ContactAddedCallback gContactAddedCallback; + + const int NUM_VERTS_X = 2; + const int NUM_VERTS_Y = 2; + const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + +void InternalEdgeDemo::setVertexPositions(float waveheight, float offset) +{ + int i; + int j; + + for ( i=0;isetCollisionFlags( staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->setActivationState(DISABLE_DEACTIVATION); + } else + { + staticBody->setCollisionFlags( staticBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->forceActivationState(ACTIVE_TAG); + } + } + + DemoApplication::keyboardCallback(key,x,y); + +} + + + +void InternalEdgeDemo::initPhysics() +{ + + setTexturing(true); + setShadows(false);//true); + + #define TRISIZE 10.f + + gContactAddedCallback = CustomMaterialCombinerCallback; + +#define USE_TRIMESH_SHAPE 1 +#ifdef USE_TRIMESH_SHAPE + + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + + + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + + gVertices = new btVector3[totalVerts]; + gIndices = new int[totalTriangles*3]; + + int i; + + + setVertexPositions(waveheight,0.f); + + + //gVertices[1].setY(21.1); + //gVertices[1].setY(121.1); + gVertices[1].setY(.1f); + +#ifdef ROTATE_GROUND + //gVertices[1].setY(-1.1); +#else + //gVertices[1].setY(0.1); + //gVertices[1].setY(-0.1); + //gVertices[1].setY(-20.1); + //gVertices[1].setY(-20); +#endif + + int index=0; + for ( i=0;igetOptimizedBvh()->calculateSerializeBufferSize(); + buffer = btAlignedAlloc(numBytes,16); + bool swapEndian = false; + trimeshShape->getOptimizedBvh()->serialize(buffer,numBytes,swapEndian); + FILE* file = fopen("bvh.bin","wb"); + fwrite(buffer,1,numBytes,file); + fclose(file); + btAlignedFree(buffer); + + + +#else + + trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,false); + + char* fileName = "bvh.bin"; + + FILE* file = fopen(fileName,"rb"); + int size=0; + btOptimizedBvh* bvh = 0; + + if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ + printf("Error: cannot get filesize from %s\n", fileName); + exit(0); + } else + { + + fseek(file, 0, SEEK_SET); + + int buffersize = size+btOptimizedBvh::getAlignmentSerializationPadding(); + + void* buffer = btAlignedAlloc(buffersize,16); + int read = fread(buffer,1,size,file); + fclose(file); + bool swapEndian = false; + bvh = btOptimizedBvh::deSerializeInPlace(buffer,buffersize,swapEndian); + } + + trimeshShape->setOptimizedBvh(bvh); + +#endif + + btCollisionShape* groundShape = trimeshShape; + + btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap(); + + + btGenerateInternalEdgeInfo(trimeshShape,triangleInfoMap); + + + +#else + btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); + + m_collisionShapes.push_back(groundShape); + +#endif //USE_TRIMESH_SHAPE + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + + + m_broadphase = new btDbvtBroadphase(); + m_solver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); +/* +m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; + m_dynamicsWorld->getSolverInfo().m_splitImpulsePenetrationThreshold = 1e30f; + m_dynamicsWorld->getSolverInfo().m_maxErrorReduction = 1e30f; + m_dynamicsWorld->getSolverInfo().m_erp =1.f; + m_dynamicsWorld->getSolverInfo().m_erp2 = 1.f; +*/ + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-2,0)); + + + btConvexHullShape* colShape = new btConvexHullShape(); + for (int i=0;iaddPoint(vtx); + } + //this will enable polyhedral contact clipping, better quality, slightly slower + colShape->initializePolyhedralFeatures(); + + //the polyhedral contact clipping can use either GJK or SAT test to find the separating axis + m_dynamicsWorld->getDispatchInfo().m_enableSatConvex=false; + + m_collisionShapes.push_back(colShape); + + { + for (int i=0;i<1;i++) + { + startTransform.setOrigin(btVector3(-10.f+i*3.f,2.2f+btScalar(i)*0.1f,-1.3f)); + btRigidBody* body = localCreateRigidBody(10, startTransform,colShape); + body->setActivationState(DISABLE_DEACTIVATION); + body->setLinearVelocity(btVector3(0,0,-1)); + //body->setContactProcessingThreshold(0.f); + } + } + { + btBoxShape* colShape = new btBoxShape(btVector3(1,1,1)); + colShape->initializePolyhedralFeatures(); + m_collisionShapes.push_back(colShape); + startTransform.setOrigin(btVector3(-16.f+i*3.f,1.f+btScalar(i)*0.1f,-1.3f)); + btRigidBody* body = localCreateRigidBody(10, startTransform,colShape); + body->setActivationState(DISABLE_DEACTIVATION); + body->setLinearVelocity(btVector3(0,0,-1)); + } + + startTransform.setIdentity(); +#ifdef ROTATE_GROUND + btQuaternion orn(btVector3(0,0,1),SIMD_PI); + startTransform.setOrigin(btVector3(-20,0,0)); + startTransform.setRotation(orn); +#endif //ROTATE_GROUND + + staticBody = localCreateRigidBody(mass, startTransform,groundShape); + //staticBody->setContactProcessingThreshold(-0.031f); + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);//STATIC_OBJECT); + + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + setDebugMode(btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_NoHelpText+btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + + +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btSetDebugDrawer(&gDebugDrawer); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + +} + + +void InternalEdgeDemo::clientResetScene() +{ + DemoApplication::clientResetScene(); + for (int i=0;igetNumCollisionObjects();i++) + { + btCollisionObject* colobj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(colobj); + if (body && body->getInvMass() != 0.f) + { + + body->setLinearVelocity(btVector3(0,0,-1)); + } + + } +} + +void InternalEdgeDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_animatedMesh) + { + static float offset=0.f; + offset+=0.01f; + + // setVertexPositions(waveheight,offset); +#if 0 ///not currently supported, we need to update the btInternalTriangleInfoMap + int i; + int j; + btVector3 aabbMin(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + btVector3 aabbMax(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + + for ( i=NUM_VERTS_X/2-3;ipartialRefitTree(aabbMin,aabbMax); +#else + btVector3 aabbMin,aabbMax; + trimeshShape->getMeshInterface()->calculateAabbBruteForce(aabbMin,aabbMax); + trimeshShape->refitTree(aabbMin,aabbMax); + +#endif + + + //for debugging: clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. + //m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + } + + + + m_dynamicsWorld->stepSimulation(dt); + ///enable one of the following to debug (render debug lines each frame) + //m_dynamicsWorld->stepSimulation(1./800.,0); + //m_dynamicsWorld->stepSimulation(1./60.,100,1./800.); + //m_dynamicsWorld->stepSimulation(1./60.,0); + + + int lineWidth=450; + int xStart = m_glutScreenWidth - lineWidth; + int yStart = 20; + + if((getDebugMode() & btIDebugDraw::DBG_DrawText)!=0) + { + setOrthographicProjection(); + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + char buf[124]; + + glRasterPos3f(xStart, yStart, 0); + if (enable) + { + sprintf(buf,"InternalEdgeUtility enabled"); + } else + { + sprintf(buf,"InternalEdgeUtility disabled"); + } + GLDebugDrawString(xStart,20,buf); + yStart+=20; + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"Press 'n' to toggle InternalEdgeUtility"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + + resetPerspectiveProjection(); + glEnable(GL_LIGHTING); + } + + + renderme(); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + + glFlush(); + swapBuffers(); + +} + + + + +void InternalEdgeDemo::displayCallback(void) { + + clientMoveAndDisplay(); + /* + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + + glFlush(); + glutSwapBuffers(); + */ + +} + + + +void InternalEdgeDemo::exitPhysics() +{ + + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btTriangleIndexVertexArray* m_indexVertexArrays; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + bool m_animatedMesh; + + public: + + InternalEdgeDemo() : m_animatedMesh(true) + { + + } + void initPhysics(); + + void exitPhysics(); + + virtual ~InternalEdgeDemo() + { + exitPhysics(); + } + + virtual void clientResetScene(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + //to show refit works + void setVertexPositions(float waveheight, float offset); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + InternalEdgeDemo* demo = new InternalEdgeDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + }; +}; + +#endif //CONCAVE_DEMO_H + diff --git a/Demos/InternalEdgeDemo/Taru.mdl b/Demos/InternalEdgeDemo/Taru.mdl new file mode 100644 index 0000000..4ebc503 --- /dev/null +++ b/Demos/InternalEdgeDemo/Taru.mdl @@ -0,0 +1,49 @@ +#define TaruVtxCount 43 +#define TaruIdxCount 132 + +static float TaruVtx[] = { +1.08664f,-1.99237f,0.0f, +0.768369f,-1.99237f,-0.768369f, +1.28852f,1.34412e-007f,-1.28852f, +1.82224f,1.90735e-007f,0.0f, +0.0f,-1.99237f,-1.08664f, +0.0f,0.0f,-1.82224f, +0.0f,-1.99237f,-1.08664f, +-0.768369f,-1.99237f,-0.768369f, +-1.28852f,1.34412e-007f,-1.28852f, +0.0f,0.0f,-1.82224f, +-1.08664f,-1.99237f,1.82086e-007f, +-1.82224f,1.90735e-007f,1.59305e-007f, +-0.768369f,-1.99237f,0.76837f, +-1.28852f,2.47058e-007f,1.28852f, +1.42495e-007f,-1.99237f,1.08664f, +2.38958e-007f,2.70388e-007f,1.82224f, +0.768369f,-1.99237f,0.768369f, +1.28852f,2.47058e-007f,1.28852f, +0.768369f,1.99237f,-0.768369f, +1.08664f,1.99237f,0.0f, +0.0f,1.99237f,-1.08664f, +-0.768369f,1.99237f,-0.768369f, +0.0f,1.99237f,-1.08664f, +-1.08664f,1.99237f,0.0f, +-0.768369f,1.99237f,0.768369f, +1.42495e-007f,1.99237f,1.08664f, +0.768369f,1.99237f,0.768369f, +1.42495e-007f,-1.99237f,1.08664f, +-0.768369f,-1.99237f,0.76837f, +-1.08664f,-1.99237f,1.82086e-007f, +-0.768369f,-1.99237f,-0.768369f, +0.0f,-1.99237f,-1.08664f, +0.768369f,-1.99237f,-0.768369f, +1.08664f,-1.99237f,0.0f, +0.768369f,-1.99237f,0.768369f, +0.768369f,1.99237f,-0.768369f, +0.0f,1.99237f,-1.08664f, +-0.768369f,1.99237f,-0.768369f, +-1.08664f,1.99237f,0.0f, +-0.768369f,1.99237f,0.768369f, +1.42495e-007f,1.99237f,1.08664f, +0.768369f,1.99237f,0.768369f, +1.08664f,1.99237f,0.0f, +}; + diff --git a/Demos/InternalEdgeDemo/Win32InternalEdgeDemo.cpp b/Demos/InternalEdgeDemo/Win32InternalEdgeDemo.cpp new file mode 100644 index 0000000..f550713 --- /dev/null +++ b/Demos/InternalEdgeDemo/Win32InternalEdgeDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "InternalEdgeDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new InternalEdgeDemo(); +} + +#endif diff --git a/Demos/InternalEdgeDemo/main.cpp b/Demos/InternalEdgeDemo/main.cpp new file mode 100644 index 0000000..596ecb3 --- /dev/null +++ b/Demos/InternalEdgeDemo/main.cpp @@ -0,0 +1,19 @@ + +#include "InternalEdgeDemo.h" +#include "GlutStuff.h" + +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + + +int main(int argc,char** argv) +{ + + InternalEdgeDemo* internalEdgeDemo = new InternalEdgeDemo(); + internalEdgeDemo->initPhysics(); + internalEdgeDemo->setCameraDistance(30.f); + + + return glutmain(argc, argv,640,480,"Internal Edge Demo",internalEdgeDemo); +} + diff --git a/Demos/Makefile.am b/Demos/Makefile.am new file mode 100644 index 0000000..cb7f841 --- /dev/null +++ b/Demos/Makefile.am @@ -0,0 +1,5 @@ +if CONDITIONAL_BUILD_MULTITHREADED +SUBDIRS=OpenGL BasicDemo TerrainDemo VehicleDemo CcdPhysicsDemo MultiThreadedDemo SoftDemo AllBulletDemos +else +SUBDIRS=OpenGL BasicDemo TerrainDemo VehicleDemo CcdPhysicsDemo SoftDemo AllBulletDemos +endif diff --git a/Demos/Makefile.in b/Demos/Makefile.in new file mode 100644 index 0000000..95e9d08 --- /dev/null +++ b/Demos/Makefile.in @@ -0,0 +1,562 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = Demos +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = OpenGL BasicDemo TerrainDemo VehicleDemo CcdPhysicsDemo \ + SoftDemo AllBulletDemos MultiThreadedDemo +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@SUBDIRS = OpenGL BasicDemo TerrainDemo VehicleDemo CcdPhysicsDemo SoftDemo AllBulletDemos +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@SUBDIRS = OpenGL BasicDemo TerrainDemo VehicleDemo CcdPhysicsDemo MultiThreadedDemo SoftDemo AllBulletDemos +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/MovingConcaveDemo/CMakeLists.txt b/Demos/MovingConcaveDemo/CMakeLists.txt new file mode 100644 index 0000000..d6bcaf5 --- /dev/null +++ b/Demos/MovingConcaveDemo/CMakeLists.txt @@ -0,0 +1,51 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + + + +ADD_EXECUTABLE(AppMovingConcaveDemo +ConcavePhysicsDemo.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppMovingConcaveDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppMovingConcaveDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES) +ENDIF(WIN32) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppMovingConcaveDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppMovingConcaveDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppMovingConcaveDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/MovingConcaveDemo/ConcaveDemo.h b/Demos/MovingConcaveDemo/ConcaveDemo.h new file mode 100644 index 0000000..0a7e31b --- /dev/null +++ b/Demos/MovingConcaveDemo/ConcaveDemo.h @@ -0,0 +1,48 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONCAVE_DEMO_H +#define CONCAVE_DEMO_H + +#include "GlutDemoApplication.h" + +struct btCollisionAlgorithmCreateFunc; + +///ConcaveDemo shows usage of static concave triangle meshes +///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback +class ConcaveDemo : public GlutDemoApplication +{ + + btCollisionShape * m_trimeshShape; + + public: + + void initGImpactCollision(); + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void renderme(); + virtual void keyboardCallback(unsigned char key, int x, int y); + + ///Demo functions + void shootTrimesh(const btVector3& startPosition,const btVector3& destination); + + +}; + +#endif //CONCAVE_DEMO_H + diff --git a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp new file mode 100644 index 0000000..b04c618 --- /dev/null +++ b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp @@ -0,0 +1,1926 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "ConcaveDemo.h" + + +#include "LinearMath/btDefaultMotionState.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btDefaultMotionState.h" +#include "BulletCollision/Gimpact/btGImpactShape.h" +#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" +#include "GLDebugFont.h" + + + +#include "GLDebugDrawer.h" + +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + + +GLDebugDrawer debugDrawer1; + +//***************************THE FAMOUS BUNNY TRIMESH********************************************// + +#define REAL btScalar +const int NUM_TRIANGLES =902; +const int NUM_VERTICES = 453; +const int NUM_INDICES = NUM_TRIANGLES * 3; + + +REAL gVertices[NUM_VERTICES * 3] = { + REAL(-0.334392), REAL(0.133007), REAL(0.062259), + REAL(-0.350189), REAL(0.150354), REAL(-0.147769), + REAL(-0.234201), REAL(0.343811), REAL(-0.174307), + REAL(-0.200259), REAL(0.285207), REAL(0.093749), + REAL(0.003520), REAL(0.475208), REAL(-0.159365), + REAL(0.001856), REAL(0.419203), REAL(0.098582), + REAL(-0.252802), REAL(0.093666), REAL(0.237538), + REAL(-0.162901), REAL(0.237984), REAL(0.206905), + REAL(0.000865), REAL(0.318141), REAL(0.235370), + REAL(-0.414624), REAL(0.164083), REAL(-0.278254), + REAL(-0.262213), REAL(0.357334), REAL(-0.293246), + REAL(0.004628), REAL(0.482694), REAL(-0.338626), + REAL(-0.402162), REAL(0.133528), REAL(-0.443247), + REAL(-0.243781), REAL(0.324275), REAL(-0.436763), + REAL(0.005293), REAL(0.437592), REAL(-0.458332), + REAL(-0.339884), REAL(-0.041150), REAL(-0.668211), + REAL(-0.248382), REAL(0.255825), REAL(-0.627493), + REAL(0.006261), REAL(0.376103), REAL(-0.631506), + REAL(-0.216201), REAL(-0.126776), REAL(-0.886936), + REAL(-0.171075), REAL(0.011544), REAL(-0.881386), + REAL(-0.181074), REAL(0.098223), REAL(-0.814779), + REAL(-0.119891), REAL(0.218786), REAL(-0.760153), + REAL(-0.078895), REAL(0.276780), REAL(-0.739281), + REAL(0.006801), REAL(0.310959), REAL(-0.735661), + REAL(-0.168842), REAL(0.102387), REAL(-0.920381), + REAL(-0.104072), REAL(0.177278), REAL(-0.952530), + REAL(-0.129704), REAL(0.211848), REAL(-0.836678), + REAL(-0.099875), REAL(0.310931), REAL(-0.799381), + REAL(0.007237), REAL(0.361687), REAL(-0.794439), + REAL(-0.077913), REAL(0.258753), REAL(-0.921640), + REAL(0.007957), REAL(0.282241), REAL(-0.931680), + REAL(-0.252222), REAL(-0.550401), REAL(-0.557810), + REAL(-0.267633), REAL(-0.603419), REAL(-0.655209), + REAL(-0.446838), REAL(-0.118517), REAL(-0.466159), + REAL(-0.459488), REAL(-0.093017), REAL(-0.311341), + REAL(-0.370645), REAL(-0.100108), REAL(-0.159454), + REAL(-0.371984), REAL(-0.091991), REAL(-0.011044), + REAL(-0.328945), REAL(-0.098269), REAL(0.088659), + REAL(-0.282452), REAL(-0.018862), REAL(0.311501), + REAL(-0.352403), REAL(-0.131341), REAL(0.144902), + REAL(-0.364126), REAL(-0.200299), REAL(0.202388), + REAL(-0.283965), REAL(-0.231869), REAL(0.023668), + REAL(-0.298943), REAL(-0.155218), REAL(0.369716), + REAL(-0.293787), REAL(-0.121856), REAL(0.419097), + REAL(-0.290163), REAL(-0.290797), REAL(0.107824), + REAL(-0.264165), REAL(-0.272849), REAL(0.036347), + REAL(-0.228567), REAL(-0.372573), REAL(0.290309), + REAL(-0.190431), REAL(-0.286997), REAL(0.421917), + REAL(-0.191039), REAL(-0.240973), REAL(0.507118), + REAL(-0.287272), REAL(-0.276431), REAL(-0.065444), + REAL(-0.295675), REAL(-0.280818), REAL(-0.174200), + REAL(-0.399537), REAL(-0.313131), REAL(-0.376167), + REAL(-0.392666), REAL(-0.488581), REAL(-0.427494), + REAL(-0.331669), REAL(-0.570185), REAL(-0.466054), + REAL(-0.282290), REAL(-0.618140), REAL(-0.589220), + REAL(-0.374238), REAL(-0.594882), REAL(-0.323298), + REAL(-0.381071), REAL(-0.629723), REAL(-0.350777), + REAL(-0.382112), REAL(-0.624060), REAL(-0.221577), + REAL(-0.272701), REAL(-0.566522), REAL(0.259157), + REAL(-0.256702), REAL(-0.663406), REAL(0.286079), + REAL(-0.280948), REAL(-0.428359), REAL(0.055790), + REAL(-0.184974), REAL(-0.508894), REAL(0.326265), + REAL(-0.279971), REAL(-0.526918), REAL(0.395319), + REAL(-0.282599), REAL(-0.663393), REAL(0.412411), + REAL(-0.188329), REAL(-0.475093), REAL(0.417954), + REAL(-0.263384), REAL(-0.663396), REAL(0.466604), + REAL(-0.209063), REAL(-0.663393), REAL(0.509344), + REAL(-0.002044), REAL(-0.319624), REAL(0.553078), + REAL(-0.001266), REAL(-0.371260), REAL(0.413296), + REAL(-0.219753), REAL(-0.339762), REAL(-0.040921), + REAL(-0.256986), REAL(-0.282511), REAL(-0.006349), + REAL(-0.271706), REAL(-0.260881), REAL(0.001764), + REAL(-0.091191), REAL(-0.419184), REAL(-0.045912), + REAL(-0.114944), REAL(-0.429752), REAL(-0.124739), + REAL(-0.113970), REAL(-0.382987), REAL(-0.188540), + REAL(-0.243012), REAL(-0.464942), REAL(-0.242850), + REAL(-0.314815), REAL(-0.505402), REAL(-0.324768), + REAL(0.002774), REAL(-0.437526), REAL(-0.262766), + REAL(-0.072625), REAL(-0.417748), REAL(-0.221440), + REAL(-0.160112), REAL(-0.476932), REAL(-0.293450), + REAL(0.003859), REAL(-0.453425), REAL(-0.443916), + REAL(-0.120363), REAL(-0.581567), REAL(-0.438689), + REAL(-0.091499), REAL(-0.584191), REAL(-0.294511), + REAL(-0.116469), REAL(-0.599861), REAL(-0.188308), + REAL(-0.208032), REAL(-0.513640), REAL(-0.134649), + REAL(-0.235749), REAL(-0.610017), REAL(-0.040939), + REAL(-0.344916), REAL(-0.622487), REAL(-0.085380), + REAL(-0.336401), REAL(-0.531864), REAL(-0.212298), + REAL(0.001961), REAL(-0.459550), REAL(-0.135547), + REAL(-0.058296), REAL(-0.430536), REAL(-0.043440), + REAL(0.001378), REAL(-0.449511), REAL(-0.037762), + REAL(-0.130135), REAL(-0.510222), REAL(0.079144), + REAL(0.000142), REAL(-0.477549), REAL(0.157064), + REAL(-0.114284), REAL(-0.453206), REAL(0.304397), + REAL(-0.000592), REAL(-0.443558), REAL(0.285401), + REAL(-0.056215), REAL(-0.663402), REAL(0.326073), + REAL(-0.026248), REAL(-0.568010), REAL(0.273318), + REAL(-0.049261), REAL(-0.531064), REAL(0.389854), + REAL(-0.127096), REAL(-0.663398), REAL(0.479316), + REAL(-0.058384), REAL(-0.663401), REAL(0.372891), + REAL(-0.303961), REAL(0.054199), REAL(0.625921), + REAL(-0.268594), REAL(0.193403), REAL(0.502766), + REAL(-0.277159), REAL(0.126123), REAL(0.443289), + REAL(-0.287605), REAL(-0.005722), REAL(0.531844), + REAL(-0.231396), REAL(-0.121289), REAL(0.587387), + REAL(-0.253475), REAL(-0.081797), REAL(0.756541), + REAL(-0.195164), REAL(-0.137969), REAL(0.728011), + REAL(-0.167673), REAL(-0.156573), REAL(0.609388), + REAL(-0.145917), REAL(-0.169029), REAL(0.697600), + REAL(-0.077776), REAL(-0.214247), REAL(0.622586), + REAL(-0.076873), REAL(-0.214971), REAL(0.696301), + REAL(-0.002341), REAL(-0.233135), REAL(0.622859), + REAL(-0.002730), REAL(-0.213526), REAL(0.691267), + REAL(-0.003136), REAL(-0.192628), REAL(0.762731), + REAL(-0.056136), REAL(-0.201222), REAL(0.763806), + REAL(-0.114589), REAL(-0.166192), REAL(0.770723), + REAL(-0.155145), REAL(-0.129632), REAL(0.791738), + REAL(-0.183611), REAL(-0.058705), REAL(0.847012), + REAL(-0.165562), REAL(0.001980), REAL(0.833386), + REAL(-0.220084), REAL(0.019914), REAL(0.768935), + REAL(-0.255730), REAL(0.090306), REAL(0.670782), + REAL(-0.255594), REAL(0.113833), REAL(0.663389), + REAL(-0.226380), REAL(0.212655), REAL(0.617740), + REAL(-0.003367), REAL(-0.195342), REAL(0.799680), + REAL(-0.029743), REAL(-0.210508), REAL(0.827180), + REAL(-0.003818), REAL(-0.194783), REAL(0.873636), + REAL(-0.004116), REAL(-0.157907), REAL(0.931268), + REAL(-0.031280), REAL(-0.184555), REAL(0.889476), + REAL(-0.059885), REAL(-0.184448), REAL(0.841330), + REAL(-0.135333), REAL(-0.164332), REAL(0.878200), + REAL(-0.085574), REAL(-0.170948), REAL(0.925547), + REAL(-0.163833), REAL(-0.094170), REAL(0.897114), + REAL(-0.138444), REAL(-0.104250), REAL(0.945975), + REAL(-0.083497), REAL(-0.084934), REAL(0.979607), + REAL(-0.004433), REAL(-0.146642), REAL(0.985872), + REAL(-0.150715), REAL(0.032650), REAL(0.884111), + REAL(-0.135892), REAL(-0.035520), REAL(0.945455), + REAL(-0.070612), REAL(0.036849), REAL(0.975733), + REAL(-0.004458), REAL(-0.042526), REAL(1.015670), + REAL(-0.004249), REAL(0.046042), REAL(1.003240), + REAL(-0.086969), REAL(0.133224), REAL(0.947633), + REAL(-0.003873), REAL(0.161605), REAL(0.970499), + REAL(-0.125544), REAL(0.140012), REAL(0.917678), + REAL(-0.125651), REAL(0.250246), REAL(0.857602), + REAL(-0.003127), REAL(0.284070), REAL(0.878870), + REAL(-0.159174), REAL(0.125726), REAL(0.888878), + REAL(-0.183807), REAL(0.196970), REAL(0.844480), + REAL(-0.159890), REAL(0.291736), REAL(0.732480), + REAL(-0.199495), REAL(0.207230), REAL(0.779864), + REAL(-0.206182), REAL(0.164608), REAL(0.693257), + REAL(-0.186315), REAL(0.160689), REAL(0.817193), + REAL(-0.192827), REAL(0.166706), REAL(0.782271), + REAL(-0.175112), REAL(0.110008), REAL(0.860621), + REAL(-0.161022), REAL(0.057420), REAL(0.855111), + REAL(-0.172319), REAL(0.036155), REAL(0.816189), + REAL(-0.190318), REAL(0.064083), REAL(0.760605), + REAL(-0.195072), REAL(0.129179), REAL(0.731104), + REAL(-0.203126), REAL(0.410287), REAL(0.680536), + REAL(-0.216677), REAL(0.309274), REAL(0.642272), + REAL(-0.241515), REAL(0.311485), REAL(0.587832), + REAL(-0.002209), REAL(0.366663), REAL(0.749413), + REAL(-0.088230), REAL(0.396265), REAL(0.678635), + REAL(-0.170147), REAL(0.109517), REAL(0.840784), + REAL(-0.160521), REAL(0.067766), REAL(0.830650), + REAL(-0.181546), REAL(0.139805), REAL(0.812146), + REAL(-0.180495), REAL(0.148568), REAL(0.776087), + REAL(-0.180255), REAL(0.129125), REAL(0.744192), + REAL(-0.186298), REAL(0.078308), REAL(0.769352), + REAL(-0.167622), REAL(0.060539), REAL(0.806675), + REAL(-0.189876), REAL(0.102760), REAL(0.802582), + REAL(-0.108340), REAL(0.455446), REAL(0.657174), + REAL(-0.241585), REAL(0.527592), REAL(0.669296), + REAL(-0.265676), REAL(0.513366), REAL(0.634594), + REAL(-0.203073), REAL(0.478550), REAL(0.581526), + REAL(-0.266772), REAL(0.642330), REAL(0.602061), + REAL(-0.216961), REAL(0.564846), REAL(0.535435), + REAL(-0.202210), REAL(0.525495), REAL(0.475944), + REAL(-0.193888), REAL(0.467925), REAL(0.520606), + REAL(-0.265837), REAL(0.757267), REAL(0.500933), + REAL(-0.240306), REAL(0.653440), REAL(0.463215), + REAL(-0.309239), REAL(0.776868), REAL(0.304726), + REAL(-0.271009), REAL(0.683094), REAL(0.382018), + REAL(-0.312111), REAL(0.671099), REAL(0.286687), + REAL(-0.268791), REAL(0.624342), REAL(0.377231), + REAL(-0.302457), REAL(0.533996), REAL(0.360289), + REAL(-0.263656), REAL(0.529310), REAL(0.412564), + REAL(-0.282311), REAL(0.415167), REAL(0.447666), + REAL(-0.239201), REAL(0.442096), REAL(0.495604), + REAL(-0.220043), REAL(0.569026), REAL(0.445877), + REAL(-0.001263), REAL(0.395631), REAL(0.602029), + REAL(-0.057345), REAL(0.442535), REAL(0.572224), + REAL(-0.088927), REAL(0.506333), REAL(0.529106), + REAL(-0.125738), REAL(0.535076), REAL(0.612913), + REAL(-0.126251), REAL(0.577170), REAL(0.483159), + REAL(-0.149594), REAL(0.611520), REAL(0.557731), + REAL(-0.163188), REAL(0.660791), REAL(0.491080), + REAL(-0.172482), REAL(0.663387), REAL(0.415416), + REAL(-0.160464), REAL(0.591710), REAL(0.370659), + REAL(-0.156445), REAL(0.536396), REAL(0.378302), + REAL(-0.136496), REAL(0.444358), REAL(0.425226), + REAL(-0.095564), REAL(0.373768), REAL(0.473659), + REAL(-0.104146), REAL(0.315912), REAL(0.498104), + REAL(-0.000496), REAL(0.384194), REAL(0.473817), + REAL(-0.000183), REAL(0.297770), REAL(0.401486), + REAL(-0.129042), REAL(0.270145), REAL(0.434495), + REAL(0.000100), REAL(0.272963), REAL(0.349138), + REAL(-0.113060), REAL(0.236984), REAL(0.385554), + REAL(0.007260), REAL(0.016311), REAL(-0.883396), + REAL(0.007865), REAL(0.122104), REAL(-0.956137), + REAL(-0.032842), REAL(0.115282), REAL(-0.953252), + REAL(-0.089115), REAL(0.108449), REAL(-0.950317), + REAL(-0.047440), REAL(0.014729), REAL(-0.882756), + REAL(-0.104458), REAL(0.013137), REAL(-0.882070), + REAL(-0.086439), REAL(-0.584866), REAL(-0.608343), + REAL(-0.115026), REAL(-0.662605), REAL(-0.436732), + REAL(-0.071683), REAL(-0.665372), REAL(-0.606385), + REAL(-0.257884), REAL(-0.665381), REAL(-0.658052), + REAL(-0.272542), REAL(-0.665381), REAL(-0.592063), + REAL(-0.371322), REAL(-0.665382), REAL(-0.353620), + REAL(-0.372362), REAL(-0.665381), REAL(-0.224420), + REAL(-0.335166), REAL(-0.665380), REAL(-0.078623), + REAL(-0.225999), REAL(-0.665375), REAL(-0.038981), + REAL(-0.106719), REAL(-0.665374), REAL(-0.186351), + REAL(-0.081749), REAL(-0.665372), REAL(-0.292554), + REAL(0.006943), REAL(-0.091505), REAL(-0.858354), + REAL(0.006117), REAL(-0.280985), REAL(-0.769967), + REAL(0.004495), REAL(-0.502360), REAL(-0.559799), + REAL(-0.198638), REAL(-0.302135), REAL(-0.845816), + REAL(-0.237395), REAL(-0.542544), REAL(-0.587188), + REAL(-0.270001), REAL(-0.279489), REAL(-0.669861), + REAL(-0.134547), REAL(-0.119852), REAL(-0.959004), + REAL(-0.052088), REAL(-0.122463), REAL(-0.944549), + REAL(-0.124463), REAL(-0.293508), REAL(-0.899566), + REAL(-0.047616), REAL(-0.289643), REAL(-0.879292), + REAL(-0.168595), REAL(-0.529132), REAL(-0.654931), + REAL(-0.099793), REAL(-0.515719), REAL(-0.645873), + REAL(-0.186168), REAL(-0.605282), REAL(-0.724690), + REAL(-0.112970), REAL(-0.583097), REAL(-0.707469), + REAL(-0.108152), REAL(-0.665375), REAL(-0.700408), + REAL(-0.183019), REAL(-0.665378), REAL(-0.717630), + REAL(-0.349529), REAL(-0.334459), REAL(-0.511985), + REAL(-0.141182), REAL(-0.437705), REAL(-0.798194), + REAL(-0.212670), REAL(-0.448725), REAL(-0.737447), + REAL(-0.261111), REAL(-0.414945), REAL(-0.613835), + REAL(-0.077364), REAL(-0.431480), REAL(-0.778113), + REAL(0.005174), REAL(-0.425277), REAL(-0.651592), + REAL(0.089236), REAL(-0.431732), REAL(-0.777093), + REAL(0.271006), REAL(-0.415749), REAL(-0.610577), + REAL(0.223981), REAL(-0.449384), REAL(-0.734774), + REAL(0.153275), REAL(-0.438150), REAL(-0.796391), + REAL(0.358414), REAL(-0.335529), REAL(-0.507649), + REAL(0.193434), REAL(-0.665946), REAL(-0.715325), + REAL(0.118363), REAL(-0.665717), REAL(-0.699021), + REAL(0.123515), REAL(-0.583454), REAL(-0.706020), + REAL(0.196851), REAL(-0.605860), REAL(-0.722345), + REAL(0.109788), REAL(-0.516035), REAL(-0.644590), + REAL(0.178656), REAL(-0.529656), REAL(-0.652804), + REAL(0.061157), REAL(-0.289807), REAL(-0.878626), + REAL(0.138234), REAL(-0.293905), REAL(-0.897958), + REAL(0.066933), REAL(-0.122643), REAL(-0.943820), + REAL(0.149571), REAL(-0.120281), REAL(-0.957264), + REAL(0.280989), REAL(-0.280321), REAL(-0.666487), + REAL(0.246581), REAL(-0.543275), REAL(-0.584224), + REAL(0.211720), REAL(-0.302754), REAL(-0.843303), + REAL(0.086966), REAL(-0.665627), REAL(-0.291520), + REAL(0.110634), REAL(-0.665702), REAL(-0.185021), + REAL(0.228099), REAL(-0.666061), REAL(-0.036201), + REAL(0.337743), REAL(-0.666396), REAL(-0.074503), + REAL(0.376722), REAL(-0.666513), REAL(-0.219833), + REAL(0.377265), REAL(-0.666513), REAL(-0.349036), + REAL(0.281411), REAL(-0.666217), REAL(-0.588670), + REAL(0.267564), REAL(-0.666174), REAL(-0.654834), + REAL(0.080745), REAL(-0.665602), REAL(-0.605452), + REAL(0.122016), REAL(-0.662963), REAL(-0.435280), + REAL(0.095767), REAL(-0.585141), REAL(-0.607228), + REAL(0.118944), REAL(0.012799), REAL(-0.880702), + REAL(0.061944), REAL(0.014564), REAL(-0.882086), + REAL(0.104725), REAL(0.108156), REAL(-0.949130), + REAL(0.048513), REAL(0.115159), REAL(-0.952753), + REAL(0.112696), REAL(0.236643), REAL(0.386937), + REAL(0.128177), REAL(0.269757), REAL(0.436071), + REAL(0.102643), REAL(0.315600), REAL(0.499370), + REAL(0.094535), REAL(0.373481), REAL(0.474824), + REAL(0.136270), REAL(0.443946), REAL(0.426895), + REAL(0.157071), REAL(0.535923), REAL(0.380222), + REAL(0.161350), REAL(0.591224), REAL(0.372630), + REAL(0.173035), REAL(0.662865), REAL(0.417531), + REAL(0.162808), REAL(0.660299), REAL(0.493077), + REAL(0.148250), REAL(0.611070), REAL(0.559555), + REAL(0.125719), REAL(0.576790), REAL(0.484702), + REAL(0.123489), REAL(0.534699), REAL(0.614440), + REAL(0.087621), REAL(0.506066), REAL(0.530188), + REAL(0.055321), REAL(0.442365), REAL(0.572915), + REAL(0.219936), REAL(0.568361), REAL(0.448571), + REAL(0.238099), REAL(0.441375), REAL(0.498528), + REAL(0.281711), REAL(0.414315), REAL(0.451121), + REAL(0.263833), REAL(0.528513), REAL(0.415794), + REAL(0.303284), REAL(0.533081), REAL(0.363998), + REAL(0.269687), REAL(0.623528), REAL(0.380528), + REAL(0.314255), REAL(0.670153), REAL(0.290524), + REAL(0.272023), REAL(0.682273), REAL(0.385343), + REAL(0.311480), REAL(0.775931), REAL(0.308527), + REAL(0.240239), REAL(0.652714), REAL(0.466159), + REAL(0.265619), REAL(0.756464), REAL(0.504187), + REAL(0.192562), REAL(0.467341), REAL(0.522972), + REAL(0.201605), REAL(0.524885), REAL(0.478417), + REAL(0.215743), REAL(0.564193), REAL(0.538084), + REAL(0.264969), REAL(0.641527), REAL(0.605317), + REAL(0.201031), REAL(0.477940), REAL(0.584002), + REAL(0.263086), REAL(0.512567), REAL(0.637832), + REAL(0.238615), REAL(0.526867), REAL(0.672237), + REAL(0.105309), REAL(0.455123), REAL(0.658482), + REAL(0.183993), REAL(0.102195), REAL(0.804872), + REAL(0.161563), REAL(0.060042), REAL(0.808692), + REAL(0.180748), REAL(0.077754), REAL(0.771600), + REAL(0.175168), REAL(0.128588), REAL(0.746368), + REAL(0.175075), REAL(0.148030), REAL(0.778264), + REAL(0.175658), REAL(0.139265), REAL(0.814333), + REAL(0.154191), REAL(0.067291), REAL(0.832578), + REAL(0.163818), REAL(0.109013), REAL(0.842830), + REAL(0.084760), REAL(0.396004), REAL(0.679695), + REAL(0.238888), REAL(0.310760), REAL(0.590775), + REAL(0.213380), REAL(0.308625), REAL(0.644905), + REAL(0.199666), REAL(0.409678), REAL(0.683003), + REAL(0.190143), REAL(0.128597), REAL(0.733463), + REAL(0.184833), REAL(0.063516), REAL(0.762902), + REAL(0.166070), REAL(0.035644), REAL(0.818261), + REAL(0.154361), REAL(0.056943), REAL(0.857042), + REAL(0.168542), REAL(0.109489), REAL(0.862725), + REAL(0.187387), REAL(0.166131), REAL(0.784599), + REAL(0.180428), REAL(0.160135), REAL(0.819438), + REAL(0.201823), REAL(0.163991), REAL(0.695756), + REAL(0.194206), REAL(0.206635), REAL(0.782275), + REAL(0.155438), REAL(0.291260), REAL(0.734412), + REAL(0.177696), REAL(0.196424), REAL(0.846693), + REAL(0.152305), REAL(0.125256), REAL(0.890786), + REAL(0.119546), REAL(0.249876), REAL(0.859104), + REAL(0.118369), REAL(0.139643), REAL(0.919173), + REAL(0.079410), REAL(0.132973), REAL(0.948652), + REAL(0.062419), REAL(0.036648), REAL(0.976547), + REAL(0.127847), REAL(-0.035919), REAL(0.947070), + REAL(0.143624), REAL(0.032206), REAL(0.885913), + REAL(0.074888), REAL(-0.085173), REAL(0.980577), + REAL(0.130184), REAL(-0.104656), REAL(0.947620), + REAL(0.156201), REAL(-0.094653), REAL(0.899074), + REAL(0.077366), REAL(-0.171194), REAL(0.926545), + REAL(0.127722), REAL(-0.164729), REAL(0.879810), + REAL(0.052670), REAL(-0.184618), REAL(0.842019), + REAL(0.023477), REAL(-0.184638), REAL(0.889811), + REAL(0.022626), REAL(-0.210587), REAL(0.827500), + REAL(0.223089), REAL(0.211976), REAL(0.620493), + REAL(0.251444), REAL(0.113067), REAL(0.666494), + REAL(0.251419), REAL(0.089540), REAL(0.673887), + REAL(0.214360), REAL(0.019258), REAL(0.771595), + REAL(0.158999), REAL(0.001490), REAL(0.835374), + REAL(0.176696), REAL(-0.059249), REAL(0.849218), + REAL(0.148696), REAL(-0.130091), REAL(0.793599), + REAL(0.108290), REAL(-0.166528), REAL(0.772088), + REAL(0.049820), REAL(-0.201382), REAL(0.764454), + REAL(0.071341), REAL(-0.215195), REAL(0.697209), + REAL(0.073148), REAL(-0.214475), REAL(0.623510), + REAL(0.140502), REAL(-0.169461), REAL(0.699354), + REAL(0.163374), REAL(-0.157073), REAL(0.611416), + REAL(0.189466), REAL(-0.138550), REAL(0.730366), + REAL(0.247593), REAL(-0.082554), REAL(0.759610), + REAL(0.227468), REAL(-0.121982), REAL(0.590197), + REAL(0.284702), REAL(-0.006586), REAL(0.535347), + REAL(0.275741), REAL(0.125287), REAL(0.446676), + REAL(0.266650), REAL(0.192594), REAL(0.506044), + REAL(0.300086), REAL(0.053287), REAL(0.629620), + REAL(0.055450), REAL(-0.663935), REAL(0.375065), + REAL(0.122854), REAL(-0.664138), REAL(0.482323), + REAL(0.046520), REAL(-0.531571), REAL(0.391918), + REAL(0.024824), REAL(-0.568450), REAL(0.275106), + REAL(0.053855), REAL(-0.663931), REAL(0.328224), + REAL(0.112829), REAL(-0.453549), REAL(0.305788), + REAL(0.131265), REAL(-0.510617), REAL(0.080746), + REAL(0.061174), REAL(-0.430716), REAL(-0.042710), + REAL(0.341019), REAL(-0.532887), REAL(-0.208150), + REAL(0.347705), REAL(-0.623533), REAL(-0.081139), + REAL(0.238040), REAL(-0.610732), REAL(-0.038037), + REAL(0.211764), REAL(-0.514274), REAL(-0.132078), + REAL(0.120605), REAL(-0.600219), REAL(-0.186856), + REAL(0.096985), REAL(-0.584476), REAL(-0.293357), + REAL(0.127621), REAL(-0.581941), REAL(-0.437170), + REAL(0.165902), REAL(-0.477425), REAL(-0.291453), + REAL(0.077720), REAL(-0.417975), REAL(-0.220519), + REAL(0.320892), REAL(-0.506363), REAL(-0.320874), + REAL(0.248214), REAL(-0.465684), REAL(-0.239842), + REAL(0.118764), REAL(-0.383338), REAL(-0.187114), + REAL(0.118816), REAL(-0.430106), REAL(-0.123307), + REAL(0.094131), REAL(-0.419464), REAL(-0.044777), + REAL(0.274526), REAL(-0.261706), REAL(0.005110), + REAL(0.259842), REAL(-0.283292), REAL(-0.003185), + REAL(0.222861), REAL(-0.340431), REAL(-0.038210), + REAL(0.204445), REAL(-0.664380), REAL(0.513353), + REAL(0.259286), REAL(-0.664547), REAL(0.471281), + REAL(0.185402), REAL(-0.476020), REAL(0.421718), + REAL(0.279163), REAL(-0.664604), REAL(0.417328), + REAL(0.277157), REAL(-0.528122), REAL(0.400208), + REAL(0.183069), REAL(-0.509812), REAL(0.329995), + REAL(0.282599), REAL(-0.429210), REAL(0.059242), + REAL(0.254816), REAL(-0.664541), REAL(0.290687), + REAL(0.271436), REAL(-0.567707), REAL(0.263966), + REAL(0.386561), REAL(-0.625221), REAL(-0.216870), + REAL(0.387086), REAL(-0.630883), REAL(-0.346073), + REAL(0.380021), REAL(-0.596021), REAL(-0.318679), + REAL(0.291269), REAL(-0.619007), REAL(-0.585707), + REAL(0.339280), REAL(-0.571198), REAL(-0.461946), + REAL(0.400045), REAL(-0.489778), REAL(-0.422640), + REAL(0.406817), REAL(-0.314349), REAL(-0.371230), + REAL(0.300588), REAL(-0.281718), REAL(-0.170549), + REAL(0.290866), REAL(-0.277304), REAL(-0.061905), + REAL(0.187735), REAL(-0.241545), REAL(0.509437), + REAL(0.188032), REAL(-0.287569), REAL(0.424234), + REAL(0.227520), REAL(-0.373262), REAL(0.293102), + REAL(0.266526), REAL(-0.273650), REAL(0.039597), + REAL(0.291592), REAL(-0.291676), REAL(0.111386), + REAL(0.291914), REAL(-0.122741), REAL(0.422683), + REAL(0.297574), REAL(-0.156119), REAL(0.373368), + REAL(0.286603), REAL(-0.232731), REAL(0.027162), + REAL(0.364663), REAL(-0.201399), REAL(0.206850), + REAL(0.353855), REAL(-0.132408), REAL(0.149228), + REAL(0.282208), REAL(-0.019715), REAL(0.314960), + REAL(0.331187), REAL(-0.099266), REAL(0.092701), + REAL(0.375463), REAL(-0.093120), REAL(-0.006467), + REAL(0.375917), REAL(-0.101236), REAL(-0.154882), + REAL(0.466635), REAL(-0.094416), REAL(-0.305669), + REAL(0.455805), REAL(-0.119881), REAL(-0.460632), + REAL(0.277465), REAL(-0.604242), REAL(-0.651871), + REAL(0.261022), REAL(-0.551176), REAL(-0.554667), + REAL(0.093627), REAL(0.258494), REAL(-0.920589), + REAL(0.114248), REAL(0.310608), REAL(-0.798070), + REAL(0.144232), REAL(0.211434), REAL(-0.835001), + REAL(0.119916), REAL(0.176940), REAL(-0.951159), + REAL(0.184061), REAL(0.101854), REAL(-0.918220), + REAL(0.092431), REAL(0.276521), REAL(-0.738231), + REAL(0.133504), REAL(0.218403), REAL(-0.758602), + REAL(0.194987), REAL(0.097655), REAL(-0.812476), + REAL(0.185542), REAL(0.011005), REAL(-0.879202), + REAL(0.230315), REAL(-0.127450), REAL(-0.884202), + REAL(0.260471), REAL(0.255056), REAL(-0.624378), + REAL(0.351567), REAL(-0.042194), REAL(-0.663976), + REAL(0.253742), REAL(0.323524), REAL(-0.433716), + REAL(0.411612), REAL(0.132299), REAL(-0.438264), + REAL(0.270513), REAL(0.356530), REAL(-0.289984), + REAL(0.422146), REAL(0.162819), REAL(-0.273130), + REAL(0.164724), REAL(0.237490), REAL(0.208912), + REAL(0.253806), REAL(0.092900), REAL(0.240640), + REAL(0.203608), REAL(0.284597), REAL(0.096223), + REAL(0.241006), REAL(0.343093), REAL(-0.171396), + REAL(0.356076), REAL(0.149288), REAL(-0.143443), + REAL(0.337656), REAL(0.131992), REAL(0.066374) +}; + +int gIndices[NUM_TRIANGLES][3] = { + {126,134,133}, + {342,138,134}, + {133,134,138}, + {126,342,134}, + {312,316,317}, + {169,163,162}, + {312,317,319}, + {312,319,318}, + {169,162,164}, + {169,168,163}, + {312,314,315}, + {169,164,165}, + {169,167,168}, + {312,315,316}, + {312,313,314}, + {169,165,166}, + {169,166,167}, + {312,318,313}, + {308,304,305}, + {308,305,306}, + {179,181,188}, + {177,173,175}, + {177,175,176}, + {302,293,300}, + {322,294,304}, + {188,176,175}, + {188,175,179}, + {158,177,187}, + {305,293,302}, + {305,302,306}, + {322,304,308}, + {188,181,183}, + {158,173,177}, + {293,298,300}, + {304,294,296}, + {304,296,305}, + {185,176,188}, + {185,188,183}, + {187,177,176}, + {187,176,185}, + {305,296,298}, + {305,298,293}, + {436,432, 28}, + {436, 28, 23}, + {434,278,431}, + { 30,208,209}, + { 30,209, 29}, + { 19, 20, 24}, + {208,207,211}, + {208,211,209}, + { 19,210,212}, + {433,434,431}, + {433,431,432}, + {433,432,436}, + {436,437,433}, + {277,275,276}, + {277,276,278}, + {209,210, 25}, + { 21, 26, 24}, + { 21, 24, 20}, + { 25, 26, 27}, + { 25, 27, 29}, + {435,439,277}, + {439,275,277}, + {432,431, 30}, + {432, 30, 28}, + {433,437,438}, + {433,438,435}, + {434,277,278}, + { 24, 25,210}, + { 24, 26, 25}, + { 29, 27, 28}, + { 29, 28, 30}, + { 19, 24,210}, + {208, 30,431}, + {208,431,278}, + {435,434,433}, + {435,277,434}, + { 25, 29,209}, + { 27, 22, 23}, + { 27, 23, 28}, + { 26, 22, 27}, + { 26, 21, 22}, + {212,210,209}, + {212,209,211}, + {207,208,278}, + {207,278,276}, + {439,435,438}, + { 12, 9, 10}, + { 12, 10, 13}, + { 2, 3, 5}, + { 2, 5, 4}, + { 16, 13, 14}, + { 16, 14, 17}, + { 22, 21, 16}, + { 13, 10, 11}, + { 13, 11, 14}, + { 1, 0, 3}, + { 1, 3, 2}, + { 15, 12, 16}, + { 19, 18, 15}, + { 19, 15, 16}, + { 19, 16, 20}, + { 9, 1, 2}, + { 9, 2, 10}, + { 3, 7, 8}, + { 3, 8, 5}, + { 16, 17, 23}, + { 16, 23, 22}, + { 21, 20, 16}, + { 10, 2, 4}, + { 10, 4, 11}, + { 0, 6, 7}, + { 0, 7, 3}, + { 12, 13, 16}, + {451,446,445}, + {451,445,450}, + {442,440,439}, + {442,439,438}, + {442,438,441}, + {421,420,422}, + {412,411,426}, + {412,426,425}, + {408,405,407}, + {413, 67, 68}, + {413, 68,414}, + {391,390,412}, + { 80,384,386}, + {404,406,378}, + {390,391,377}, + {390,377, 88}, + {400,415,375}, + {398,396,395}, + {398,395,371}, + {398,371,370}, + {112,359,358}, + {112,358,113}, + {351,352,369}, + {125,349,348}, + {345,343,342}, + {342,340,339}, + {341,335,337}, + {328,341,327}, + {331,323,333}, + {331,322,323}, + {327,318,319}, + {327,319,328}, + {315,314,324}, + {302,300,301}, + {302,301,303}, + {320,311,292}, + {285,284,289}, + {310,307,288}, + {310,288,290}, + {321,350,281}, + {321,281,282}, + {423,448,367}, + {272,273,384}, + {272,384,274}, + {264,265,382}, + {264,382,383}, + {440,442,261}, + {440,261,263}, + {252,253,254}, + {252,254,251}, + {262,256,249}, + {262,249,248}, + {228,243,242}, + {228, 31,243}, + {213,215,238}, + {213,238,237}, + { 19,212,230}, + {224,225,233}, + {224,233,231}, + {217,218, 56}, + {217, 56, 54}, + {217,216,239}, + {217,239,238}, + {217,238,215}, + {218,217,215}, + {218,215,214}, + { 6,102,206}, + {186,199,200}, + {197,182,180}, + {170,171,157}, + {201,200,189}, + {170,190,191}, + {170,191,192}, + {175,174,178}, + {175,178,179}, + {168,167,155}, + {122,149,158}, + {122,158,159}, + {135,153,154}, + {135,154,118}, + {143,140,141}, + {143,141,144}, + {132,133,136}, + {130,126,133}, + {124,125,127}, + {122,101,100}, + {122,100,121}, + {110,108,107}, + {110,107,109}, + { 98, 99, 97}, + { 98, 97, 64}, + { 98, 64, 66}, + { 87, 55, 57}, + { 83, 82, 79}, + { 83, 79, 84}, + { 78, 74, 50}, + { 49, 71, 41}, + { 49, 41, 37}, + { 49, 37, 36}, + { 58, 44, 60}, + { 60, 59, 58}, + { 51, 34, 33}, + { 39, 40, 42}, + { 39, 42, 38}, + {243,240, 33}, + {243, 33,229}, + { 39, 38, 6}, + { 44, 46, 40}, + { 55, 56, 57}, + { 64, 62, 65}, + { 64, 65, 66}, + { 41, 71, 45}, + { 75, 50, 51}, + { 81, 79, 82}, + { 77, 88, 73}, + { 93, 92, 94}, + { 68, 47, 46}, + { 96, 97, 99}, + { 96, 99, 95}, + {110,109,111}, + {111,112,110}, + {114,113,123}, + {114,123,124}, + {132,131,129}, + {133,137,136}, + {135,142,145}, + {145,152,135}, + {149,147,157}, + {157,158,149}, + {164,150,151}, + {153,163,168}, + {153,168,154}, + {185,183,182}, + {185,182,184}, + {161,189,190}, + {200,199,191}, + {200,191,190}, + {180,178,195}, + {180,195,196}, + {102,101,204}, + {102,204,206}, + { 43, 48,104}, + { 43,104,103}, + {216,217, 54}, + {216, 54, 32}, + {207,224,231}, + {230,212,211}, + {230,211,231}, + {227,232,241}, + {227,241,242}, + {235,234,241}, + {235,241,244}, + {430,248,247}, + {272,274,253}, + {272,253,252}, + {439,260,275}, + {225,224,259}, + {225,259,257}, + {269,270,407}, + {269,407,405}, + {270,269,273}, + {270,273,272}, + {273,269,268}, + {273,268,267}, + {273,267,266}, + {273,266,265}, + {273,265,264}, + {448,279,367}, + {281,350,368}, + {285,286,301}, + {290,323,310}, + {290,311,323}, + {282,281,189}, + {292,311,290}, + {292,290,291}, + {307,306,302}, + {307,302,303}, + {316,315,324}, + {316,324,329}, + {331,351,350}, + {330,334,335}, + {330,335,328}, + {341,337,338}, + {344,355,354}, + {346,345,348}, + {346,348,347}, + {364,369,352}, + {364,352,353}, + {365,363,361}, + {365,361,362}, + {376,401,402}, + {373,372,397}, + {373,397,400}, + {376, 92,377}, + {381,378,387}, + {381,387,385}, + {386, 77, 80}, + {390,389,412}, + {416,417,401}, + {403,417,415}, + {408,429,430}, + {419,423,418}, + {427,428,444}, + {427,444,446}, + {437,436,441}, + {450,445, 11}, + {450, 11, 4}, + {447,449, 5}, + {447, 5, 8}, + {441,438,437}, + {425,426,451}, + {425,451,452}, + {417,421,415}, + {408,407,429}, + {399,403,400}, + {399,400,397}, + {394,393,416}, + {389,411,412}, + {386,383,385}, + {408,387,378}, + {408,378,406}, + {377,391,376}, + { 94,375,415}, + {372,373,374}, + {372,374,370}, + {359,111,360}, + {359,112,111}, + {113,358,349}, + {113,349,123}, + {346,343,345}, + {343,340,342}, + {338,336,144}, + {338,144,141}, + {327,341,354}, + {327,354,326}, + {331,350,321}, + {331,321,322}, + {314,313,326}, + {314,326,325}, + {300,298,299}, + {300,299,301}, + {288,287,289}, + {189,292,282}, + {287,288,303}, + {284,285,297}, + {368,280,281}, + {448,447,279}, + {274,226,255}, + {267,268,404}, + {267,404,379}, + {429,262,430}, + {439,440,260}, + {257,258,249}, + {257,249,246}, + {430,262,248}, + {234,228,242}, + {234,242,241}, + {237,238,239}, + {237,239,236}, + { 15, 18,227}, + { 15,227,229}, + {222,223, 82}, + {222, 82, 83}, + {214,215,213}, + {214,213, 81}, + { 38,102, 6}, + {122,159,200}, + {122,200,201}, + {174,171,192}, + {174,192,194}, + {197,193,198}, + {190,170,161}, + {181,179,178}, + {181,178,180}, + {166,156,155}, + {163,153,152}, + {163,152,162}, + {120,156,149}, + {120,149,121}, + {152,153,135}, + {140,143,142}, + {135,131,132}, + {135,132,136}, + {130,129,128}, + {130,128,127}, + {100,105,119}, + {100,119,120}, + {106,104,107}, + {106,107,108}, + { 91, 95, 59}, + { 93, 94, 68}, + { 91, 89, 92}, + { 76, 53, 55}, + { 76, 55, 87}, + { 81, 78, 79}, + { 74, 73, 49}, + { 69, 60, 45}, + { 58, 62, 64}, + { 58, 64, 61}, + { 53, 31, 32}, + { 32, 54, 53}, + { 42, 43, 38}, + { 35, 36, 0}, + { 35, 0, 1}, + { 34, 35, 1}, + { 34, 1, 9}, + { 44, 40, 41}, + { 44, 41, 45}, + { 33,240, 51}, + { 63, 62, 58}, + { 63, 58, 59}, + { 45, 71, 70}, + { 76, 75, 51}, + { 76, 51, 52}, + { 86, 85, 84}, + { 86, 84, 87}, + { 89, 72, 73}, + { 89, 73, 88}, + { 91, 92, 96}, + { 91, 96, 95}, + { 72, 91, 60}, + { 72, 60, 69}, + {104,106,105}, + {119,105,117}, + {119,117,118}, + {124,127,128}, + {117,116,129}, + {117,129,131}, + {118,117,131}, + {135,140,142}, + {146,150,152}, + {146,152,145}, + {149,122,121}, + {166,165,151}, + {166,151,156}, + {158,172,173}, + {161,160,189}, + {199,198,193}, + {199,193,191}, + {204,201,202}, + {178,174,194}, + {200,159,186}, + {109, 48, 67}, + { 48,107,104}, + {216, 32,236}, + {216,236,239}, + {223,214, 81}, + {223, 81, 82}, + { 33, 12, 15}, + { 32,228,234}, + { 32,234,236}, + {240, 31, 52}, + {256,255,246}, + {256,246,249}, + {258,263,248}, + {258,248,249}, + {275,260,259}, + {275,259,276}, + {207,276,259}, + {270,271,429}, + {270,429,407}, + {413,418,366}, + {413,366,365}, + {368,367,279}, + {368,279,280}, + {303,301,286}, + {303,286,287}, + {283,282,292}, + {283,292,291}, + {320,292,189}, + {298,296,297}, + {298,297,299}, + {318,327,326}, + {318,326,313}, + {329,330,317}, + {336,333,320}, + {326,354,353}, + {334,332,333}, + {334,333,336}, + {342,339,139}, + {342,139,138}, + {345,342,126}, + {347,357,356}, + {369,368,351}, + {363,356,357}, + {363,357,361}, + {366,367,368}, + {366,368,369}, + {375,373,400}, + { 92, 90,377}, + {409,387,408}, + {386,385,387}, + {386,387,388}, + {412,394,391}, + {396,398,399}, + {408,406,405}, + {415,421,419}, + {415,419,414}, + {425,452,448}, + {425,448,424}, + {444,441,443}, + {448,452,449}, + {448,449,447}, + {446,444,443}, + {446,443,445}, + {250,247,261}, + {250,261,428}, + {421,422,423}, + {421,423,419}, + {427,410,250}, + {417,403,401}, + {403,402,401}, + {420,392,412}, + {420,412,425}, + {420,425,424}, + {386,411,389}, + {383,382,381}, + {383,381,385}, + {378,379,404}, + {372,371,395}, + {372,395,397}, + {371,372,370}, + {361,359,360}, + {361,360,362}, + {368,350,351}, + {349,347,348}, + {356,355,344}, + {356,344,346}, + {344,341,340}, + {344,340,343}, + {338,337,336}, + {328,335,341}, + {324,352,351}, + {324,351,331}, + {320,144,336}, + {314,325,324}, + {322,308,309}, + {310,309,307}, + {287,286,289}, + {203,280,279}, + {203,279,205}, + {297,295,283}, + {297,283,284}, + {447,205,279}, + {274,384, 80}, + {274, 80,226}, + {266,267,379}, + {266,379,380}, + {225,257,246}, + {225,246,245}, + {256,254,253}, + {256,253,255}, + {430,247,250}, + {226,235,244}, + {226,244,245}, + {232,233,244}, + {232,244,241}, + {230, 18, 19}, + { 32, 31,228}, + {219,220, 86}, + {219, 86, 57}, + {226,213,235}, + {206, 7, 6}, + {122,201,101}, + {201,204,101}, + {180,196,197}, + {170,192,171}, + {200,190,189}, + {194,193,195}, + {183,181,180}, + {183,180,182}, + {155,154,168}, + {149,156,151}, + {149,151,148}, + {155,156,120}, + {145,142,143}, + {145,143,146}, + {136,137,140}, + {133,132,130}, + {128,129,116}, + {100,120,121}, + {110,112,113}, + {110,113,114}, + { 66, 65, 63}, + { 66, 63, 99}, + { 66, 99, 98}, + { 96, 46, 61}, + { 89, 88, 90}, + { 86, 87, 57}, + { 80, 78, 81}, + { 72, 69, 49}, + { 67, 48, 47}, + { 67, 47, 68}, + { 56, 55, 53}, + { 50, 49, 36}, + { 50, 36, 35}, + { 40, 39, 41}, + {242,243,229}, + {242,229,227}, + { 6, 37, 39}, + { 42, 47, 48}, + { 42, 48, 43}, + { 61, 46, 44}, + { 45, 70, 69}, + { 69, 70, 71}, + { 69, 71, 49}, + { 74, 78, 77}, + { 83, 84, 85}, + { 73, 74, 77}, + { 93, 96, 92}, + { 68, 46, 93}, + { 95, 99, 63}, + { 95, 63, 59}, + {115,108,110}, + {115,110,114}, + {125,126,127}, + {129,130,132}, + {137,133,138}, + {137,138,139}, + {148,146,143}, + {148,143,147}, + {119,118,154}, + {161,147,143}, + {165,164,151}, + {158,157,171}, + {158,171,172}, + {159,158,187}, + {159,187,186}, + {194,192,191}, + {194,191,193}, + {189,202,201}, + {182,197,184}, + {205, 8, 7}, + { 48,109,107}, + {218,219, 57}, + {218, 57, 56}, + {207,231,211}, + {232,230,231}, + {232,231,233}, + { 53, 52, 31}, + {388,411,386}, + {409,430,250}, + {262,429,254}, + {262,254,256}, + {442,444,428}, + {273,264,383}, + {273,383,384}, + {429,271,251}, + {429,251,254}, + {413,365,362}, + { 67,413,360}, + {282,283,295}, + {285,301,299}, + {202,281,280}, + {284,283,291}, + {284,291,289}, + {320,189,160}, + {308,306,307}, + {307,309,308}, + {319,317,330}, + {319,330,328}, + {353,352,324}, + {332,331,333}, + {340,341,338}, + {354,341,344}, + {349,358,357}, + {349,357,347}, + {364,355,356}, + {364,356,363}, + {364,365,366}, + {364,366,369}, + {374,376,402}, + {375, 92,373}, + { 77,389,390}, + {382,380,381}, + {389, 77,386}, + {393,394,412}, + {393,412,392}, + {401,394,416}, + {415,400,403}, + {411,410,427}, + {411,427,426}, + {422,420,424}, + {247,248,263}, + {247,263,261}, + {445,443, 14}, + {445, 14, 11}, + {449,450, 4}, + {449, 4, 5}, + {443,441, 17}, + {443, 17, 14}, + {436, 23, 17}, + {436, 17,441}, + {424,448,422}, + {448,423,422}, + {414,419,418}, + {414,418,413}, + {406,404,405}, + {399,397,395}, + {399,395,396}, + {420,416,392}, + {388,410,411}, + {386,384,383}, + {390, 88, 77}, + {375, 94, 92}, + {415,414, 68}, + {415, 68, 94}, + {370,374,402}, + {370,402,398}, + {361,357,358}, + {361,358,359}, + {125,348,126}, + {346,344,343}, + {340,338,339}, + {337,335,334}, + {337,334,336}, + {325,353,324}, + {324,331,332}, + {324,332,329}, + {323,322,309}, + {323,309,310}, + {294,295,297}, + {294,297,296}, + {289,286,285}, + {202,280,203}, + {288,307,303}, + {282,295,321}, + { 67,360,111}, + {418,423,367}, + {418,367,366}, + {272,252,251}, + {272,251,271}, + {272,271,270}, + {255,253,274}, + {265,266,380}, + {265,380,382}, + {442,428,261}, + {440,263,258}, + {440,258,260}, + {409,250,410}, + {255,226,245}, + {255,245,246}, + { 31,240,243}, + {236,234,235}, + {236,235,237}, + {233,225,245}, + {233,245,244}, + {220,221, 85}, + {220, 85, 86}, + { 81,213,226}, + { 81,226, 80}, + { 7,206,205}, + {186,184,198}, + {186,198,199}, + {204,203,205}, + {204,205,206}, + {195,193,196}, + {171,174,172}, + {173,174,175}, + {173,172,174}, + {155,167,166}, + {160,161,143}, + {160,143,144}, + {119,154,155}, + {148,151,150}, + {148,150,146}, + {140,137,139}, + {140,139,141}, + {127,126,130}, + {114,124,128}, + {114,128,115}, + {117,105,106}, + {117,106,116}, + {104,105,100}, + {104,100,103}, + { 59, 60, 91}, + { 97, 96, 61}, + { 97, 61, 64}, + { 91, 72, 89}, + { 87, 84, 79}, + { 87, 79, 76}, + { 78, 80, 77}, + { 49, 50, 74}, + { 60, 44, 45}, + { 61, 44, 58}, + { 51, 50, 35}, + { 51, 35, 34}, + { 39, 37, 41}, + { 33, 34, 9}, + { 33, 9, 12}, + { 0, 36, 37}, + { 0, 37, 6}, + { 40, 46, 47}, + { 40, 47, 42}, + { 53, 54, 56}, + { 65, 62, 63}, + { 72, 49, 73}, + { 79, 78, 75}, + { 79, 75, 76}, + { 52, 53, 76}, + { 92, 89, 90}, + { 96, 93, 46}, + {102,103,100}, + {102,100,101}, + {116,106,108}, + {116,108,115}, + {123,125,124}, + {116,115,128}, + {118,131,135}, + {140,135,136}, + {148,147,149}, + {120,119,155}, + {164,162,152}, + {164,152,150}, + {157,147,161}, + {157,161,170}, + {186,187,185}, + {186,185,184}, + {193,197,196}, + {202,203,204}, + {194,195,178}, + {198,184,197}, + { 67,111,109}, + { 38, 43,103}, + { 38,103,102}, + {214,223,222}, + {214,222,221}, + {214,221,220}, + {214,220,219}, + {214,219,218}, + {213,237,235}, + {221,222, 83}, + {221, 83, 85}, + { 15,229, 33}, + {227, 18,230}, + {227,230,232}, + { 52, 51,240}, + { 75, 78, 50}, + {408,430,409}, + {260,258,257}, + {260,257,259}, + {224,207,259}, + {268,269,405}, + {268,405,404}, + {413,362,360}, + {447, 8,205}, + {299,297,285}, + {189,281,202}, + {290,288,289}, + {290,289,291}, + {322,321,295}, + {322,295,294}, + {333,323,311}, + {333,311,320}, + {317,316,329}, + {320,160,144}, + {353,325,326}, + {329,332,334}, + {329,334,330}, + {339,338,141}, + {339,141,139}, + {348,345,126}, + {347,356,346}, + {123,349,125}, + {364,353,354}, + {364,354,355}, + {365,364,363}, + {376,391,394}, + {376,394,401}, + { 92,376,374}, + { 92,374,373}, + {377, 90, 88}, + {380,379,378}, + {380,378,381}, + {388,387,409}, + {388,409,410}, + {416,393,392}, + {399,398,402}, + {399,402,403}, + {250,428,427}, + {421,417,416}, + {421,416,420}, + {426,427,446}, + {426,446,451}, + {444,442,441}, + {452,451,450}, + {452,450,449} +}; + + +//***************************THE END OF FAMOUS BUNNY TRIMESH********************************************// + +//****GLOBALS + +//****GLOBALS + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(float friction0,float friction1) +{ + btScalar friction = friction0 * friction1; + + const btScalar MAX_FRICTION = 10.f; + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(float restitution0,float restitution1) +{ + return restitution0 * restitution1; +} + + + +bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) +{ + + float friction0 = colObj0Wrap->getCollisionObject()->getFriction(); + float friction1 = colObj1Wrap->getCollisionObject()->getFriction(); + float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution(); + float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution(); + + if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + friction0 = 1.0;//partId0,index0 + restitution0 = 0.f; + } + if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + if (index1&1) + { + friction1 = 1.0f;//partId1,index1 + } else + { + friction1 = 0.f; + } + restitution1 = 0.f; + } + + cp.m_combinedFriction = calculateCombinedFriction(friction0,friction1); + cp.m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); + + //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction + return true; +} + +extern ContactAddedCallback gContactAddedCallback; + + + +int main(int argc,char** argv) +{ + gContactAddedCallback = CustomMaterialCombinerCallback; + + ConcaveDemo* concaveDemo = new ConcaveDemo(); + concaveDemo->initPhysics(); + concaveDemo->setCameraDistance(30.f); +//cannot run stepFront yet, the OpenGL context is not opened (stepFront updates camera...) +// concaveDemo->stepFront(); +// concaveDemo->stepFront(); +// concaveDemo->stepFront(); +// concaveDemo->stepFront(); + + return glutmain(argc, argv,640,480,"Moving Concave Mesh Demo",concaveDemo); +} + +void ConcaveDemo::renderme() +{ + updateCamera(); + + btScalar m[16]; + + if (m_dynamicsWorld) + { + btVector3 worldBoundsMin,worldBoundsMax; + getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); + + + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btVector3 wireColor(1,0,0); + for (int i=0;igetCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(colObj); + + if (body && body->getMotionState()) + { + btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); + myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); + } else + { + colObj->getWorldTransform().getOpenGLMatrix(m); + } + + btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation + if (i & 1) + { + wireColor = btVector3(0.f,0.0f,1.f); + } + ///color differently for active, sleeping, wantsdeactivation states + if (colObj->getActivationState() == 1) //active + { + if (i & 1) + { + wireColor += btVector3 (1.f,0.f,0.f); + } else + { + wireColor += btVector3 (.5f,0.f,0.f); + } + } + if (colObj->getActivationState() == 2) //ISLAND_SLEEPING + { + if (i & 1) + { + wireColor += btVector3 (0.f,1.f, 0.f); + } else + { + wireColor += btVector3 (0.f,0.5f,0.f); + } + } + + m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),worldBoundsMin,worldBoundsMax); + } + + + float xOffset = 10.f; + float yStart = 20.f; + float yIncr = 20.f; + char buf[124]; + + glColor3f(0, 0, 0); + + setOrthographicProjection(); + + sprintf(buf,"mouse to interact"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + /* glRasterPos3f(xOffset,xOffset,0); + sprintf(buf,"space to reset"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + */ + + sprintf(buf,"cursor keys and z,x to navigate"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + + sprintf(buf,"i to toggle simulation, s single step"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + + sprintf(buf,"q to quit"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + + sprintf(buf,". to shoot TRIMESH (dot)"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + // not yet hooked up again after refactoring... + +/* glRasterPos3f(xOffset,xOffset,0); + sprintf(buf,"d to toggle deactivation"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; +*/ + + /* + glRasterPos3f(xOffset,xOffset,0); + sprintf(buf,"a to draw temporal AABBs"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + */ + + + sprintf(buf,"h to toggle help text"); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + //bool useBulletLCP = !(getDebugMode() & btIDebugDraw::DBG_DisableBulletLCP); + + bool useCCD = ((getDebugMode() & btIDebugDraw::DBG_EnableCCD) != 0); + + + sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + + sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); + GLDebugDrawString(xOffset,xOffset,buf); + xOffset += yIncr; + + resetPerspectiveProjection(); + + + } + +} + + + +void ConcaveDemo::initGImpactCollision() +{ + // create trimesh + btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(NUM_TRIANGLES, + &gIndices[0][0], + 3*sizeof(int), + NUM_VERTICES,(REAL*) &gVertices[0],sizeof(REAL)*3); + + btGImpactMeshShape * trimesh = new btGImpactMeshShape(indexVertexArrays); + trimesh->setLocalScaling(btVector3(4.f,4.f,4.f)); + trimesh->updateBound(); + m_trimeshShape = trimesh; + + //register algorithm + + btCollisionDispatcher * dispatcher = static_cast(m_dynamicsWorld ->getDispatcher()); + btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher); + +} + +void ConcaveDemo::initPhysics() +{ + + btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + + //btConstraintSolver* solver = new btSequentialImpulseConstraintSolver; + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); + //btOverlappingPairCache* broadphase = new btSimpleBroadphase(); + btBroadphaseInterface* broadphase = new btSimpleBroadphase(); + + btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver,collisionConfiguration); + + + //create trimesh model and shape + initGImpactCollision(); + + + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + + btCollisionShape* staticboxShape1 = new btBoxShape(btVector3(200,1,200));//floor + btCollisionShape* staticboxShape2 = new btBoxShape(btVector3(1,50,200));//left wall + btCollisionShape* staticboxShape3 = new btBoxShape(btVector3(1,50,200));//right wall + btCollisionShape* staticboxShape4 = new btBoxShape(btVector3(200,50,1));//front wall + btCollisionShape* staticboxShape5 = new btBoxShape(btVector3(200,50,1));//back wall + + btCompoundShape* staticScenario = new btCompoundShape();//static scenario + + startTransform.setOrigin(btVector3(0,0,0)); + staticScenario->addChildShape(startTransform,staticboxShape1); + startTransform.setOrigin(btVector3(-200,25,0)); + staticScenario->addChildShape(startTransform,staticboxShape2); + startTransform.setOrigin(btVector3(200,25,0)); + staticScenario->addChildShape(startTransform,staticboxShape3); + startTransform.setOrigin(btVector3(0,25,200)); + staticScenario->addChildShape(startTransform,staticboxShape4); + startTransform.setOrigin(btVector3(0,25,-200)); + staticScenario->addChildShape(startTransform,staticboxShape5); + + startTransform.setOrigin(btVector3(0,0,0)); + + btRigidBody* staticBody = localCreateRigidBody(mass, startTransform,staticScenario); + + staticBody->setCollisionFlags(staticBody->getCollisionFlags()|btCollisionObject::CF_STATIC_OBJECT); + + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags()|btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + + //static plane + btVector3 normal(0.4,1.5,-0.4); + normal.normalize(); + btCollisionShape* staticplaneShape6 = new btStaticPlaneShape(normal,0.0);// A plane + + startTransform.setOrigin(btVector3(0,0,0)); + + btRigidBody* staticBody2 = localCreateRigidBody(mass, startTransform,staticplaneShape6 ); + + staticBody2->setCollisionFlags(staticBody2->getCollisionFlags()|btCollisionObject::CF_STATIC_OBJECT); + + { + for (int i=0;i<9;i++) + { + btCollisionShape* boxShape = new btBoxShape(btVector3(1,1,1)); + startTransform.setOrigin(btVector3(2*i-5,2,-3)); + localCreateRigidBody(1, startTransform,boxShape); + } + } + + shootTrimesh(btVector3(0,10,0),btVector3(0,0,0)); + + shootTrimesh(btVector3(0,20,0),btVector3(0,10,0)); + + //m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + +} + +void ConcaveDemo::keyboardCallback(unsigned char key, int x, int y) +{ + m_lastKey = 0; + + switch (key) + { + case 'q' : exit(0); break; + + case 'l' : stepLeft(); break; + case 'r' : stepRight(); break; + case 'f' : stepFront(); break; + case 'b' : stepBack(); break; + case 'z' : zoomIn(); break; + case 'x' : zoomOut(); break; + case 'i' : toggleIdle(); break; + case 'h': + if (m_debugMode & btIDebugDraw::DBG_NoHelpText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText); + else + m_debugMode |= btIDebugDraw::DBG_NoHelpText; + break; + + case 'w': + if (m_debugMode & btIDebugDraw::DBG_DrawWireframe) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe); + else + m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + break; + + case 'p': + if (m_debugMode & btIDebugDraw::DBG_ProfileTimings) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_ProfileTimings); + else + m_debugMode |= btIDebugDraw::DBG_ProfileTimings; + break; + + case 'm': + if (m_debugMode & btIDebugDraw::DBG_EnableSatComparison) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableSatComparison); + else + m_debugMode |= btIDebugDraw::DBG_EnableSatComparison; + break; + + case 'n': + if (m_debugMode & btIDebugDraw::DBG_DisableBulletLCP) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DisableBulletLCP); + else + m_debugMode |= btIDebugDraw::DBG_DisableBulletLCP; + break; + + case 't' : + if (m_debugMode & btIDebugDraw::DBG_DrawText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawText); + else + m_debugMode |= btIDebugDraw::DBG_DrawText; + break; + case 'y': + if (m_debugMode & btIDebugDraw::DBG_DrawFeaturesText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawFeaturesText); + else + m_debugMode |= btIDebugDraw::DBG_DrawFeaturesText; + break; + case 'a': + if (m_debugMode & btIDebugDraw::DBG_DrawAabb) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb); + else + m_debugMode |= btIDebugDraw::DBG_DrawAabb; + break; + case 'c' : + if (m_debugMode & btIDebugDraw::DBG_DrawContactPoints) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawContactPoints); + else + m_debugMode |= btIDebugDraw::DBG_DrawContactPoints; + break; + + case 'd' : + if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation); + else + m_debugMode |= btIDebugDraw::DBG_NoDeactivation; + if (m_debugMode | btIDebugDraw::DBG_NoDeactivation) + { + gDisableDeactivation = true; + } else + { + gDisableDeactivation = false; + } + break; + + + + + case 'o' : + { + m_stepping = !m_stepping; + break; + } + case 's' : clientMoveAndDisplay(); break; +// case ' ' : newRandom(); break; + case ' ': + clientResetScene(); + break; + case '1': + { + if (m_debugMode & btIDebugDraw::DBG_EnableCCD) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableCCD); + else + m_debugMode |= btIDebugDraw::DBG_EnableCCD; + break; + } + + case '.': + { + shootTrimesh(getCameraPosition(),getCameraTargetPosition()); + break; + } + + case '+': + { + m_ShootBoxInitialSpeed += 10.f; + break; + } + case '-': + { + m_ShootBoxInitialSpeed -= 10.f; + break; + } + + default: +// std::cout << "unused key : " << key << std::endl; + break; + } + + if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) + getDynamicsWorld()->getDebugDrawer()->setDebugMode(m_debugMode); + + glutPostRedisplay(); + +} + + +void ConcaveDemo::shootTrimesh(const btVector3& startPosition,const btVector3& destination) +{ + + if (m_dynamicsWorld) + { + float mass = 4.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(startPosition); + + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_trimeshShape); + + btVector3 linVel(destination[0]-startPosition[0],destination[1]-startPosition[1],destination[2]-startPosition[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed*0.25; + + body->getWorldTransform().setOrigin(startPosition); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + } +} + +void ConcaveDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = float(getDeltaTimeMicroseconds()) * 0.000001f; + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + glutSwapBuffers(); + +} + + + + +void ConcaveDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + glutSwapBuffers(); +} + + diff --git a/Demos/MultiMaterialDemo/CMakeLists.txt b/Demos/MultiMaterialDemo/CMakeLists.txt new file mode 100644 index 0000000..b995b88 --- /dev/null +++ b/Demos/MultiMaterialDemo/CMakeLists.txt @@ -0,0 +1,31 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppMultiMaterialDemo + MultiMaterialDemo.cpp + main.cpp +) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppMultiMaterialDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppMultiMaterialDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppMultiMaterialDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/MultiMaterialDemo/MultiMaterialDemo.cpp b/Demos/MultiMaterialDemo/MultiMaterialDemo.cpp new file mode 100644 index 0000000..14e9619 --- /dev/null +++ b/Demos/MultiMaterialDemo/MultiMaterialDemo.cpp @@ -0,0 +1,383 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" +#include "GLDebugDrawer.h" +#include "MultiMaterialDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h" +#include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btMaterial.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +// Create a custom material, just because we can +class CustomMaterial : public btMaterial +{ +public: + int foo1; + int foo2; + CustomMaterial(){} + CustomMaterial(int a, int b) {foo1 = a; foo2 = b;} +}; + +// Storage for the vertex data +static btVector3* gVertices = 0; +// Storage for the face data +static int* gIndices = 0; +// Storage for the material data +static CustomMaterial* gMaterials = 0; +// Storage for the face -> material index data +static int* gFaceMaterialIndices = 0; + +static btBvhTriangleMeshShape* trimeshShape =0; +static btRigidBody* staticBody = 0; +static float waveheight = 0.f; + +const float TRIANGLE_SIZE=1.f; + + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(float friction0,float friction1) +{ + btScalar friction = friction0 * friction1; + + const btScalar MAX_FRICTION = 10.f; + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(float restitution0,float restitution1) +{ + return restitution0 * restitution1; +} + + + +static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) +{ + + // Apply material properties + if (colObj0Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) + { + const btCollisionShape* parent0 = colObj0Wrap->getCollisionObject()->getCollisionShape(); + if(parent0 != 0 && parent0->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE) + { + btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent0; + const btMaterial * props = shape->getMaterialProperties(partId0, index0); + cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj1Wrap->getCollisionObject()->getFriction()); + cp.m_combinedRestitution = props->m_restitution * colObj1Wrap->getCollisionObject()->getRestitution(); + } + } + else if (colObj1Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) + { + const btCollisionShape* parent1 = colObj1Wrap->getCollisionObject()->getCollisionShape(); + if(parent1 != 0 && parent1->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE) + { + btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent1; + const btMaterial * props = shape->getMaterialProperties(partId1, index1); + cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj0Wrap->getCollisionObject()->getFriction()); + cp.m_combinedRestitution = props->m_restitution * colObj0Wrap->getCollisionObject()->getRestitution(); + } + } + + //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction + return true; +} + +extern ContactAddedCallback gContactAddedCallback; + +const int NUM_VERTS_X = 20; +const int NUM_VERTS_Y = 50; +const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + +void MultiMaterialDemo::setVertexPositions(float waveheight, float offset) +{ + int i; + int j; + + for ( i=0;isetCollisionFlags( staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->setActivationState(DISABLE_DEACTIVATION); + } else + { + staticBody->setCollisionFlags( staticBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->forceActivationState(ACTIVE_TAG); + } + } + + DemoApplication::keyboardCallback(key,x,y); + +} + +void MultiMaterialDemo::initPhysics() +{ +#define TRISIZE 50.f + + gContactAddedCallback = CustomMaterialCombinerCallback; + + // The number of triangles + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + // The number of materials + const int totalMaterials = 2; + + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + // int materialStride = sizeof(CustomMaterial); + // int triangleMaterialStride = sizeof(int); + + gVertices = new btVector3[totalVerts]; + gIndices = new int[totalTriangles*3]; + gMaterials = new CustomMaterial[totalMaterials]; + gFaceMaterialIndices = new int[totalTriangles]; + + // Explicitly set up the materials. It's a small array so let's do it bit by bit. + gMaterials[0].m_friction = 0; + gMaterials[0].m_restitution = 0.9; + gMaterials[0].foo1 = 5; + gMaterials[0].foo2 = 7; + gMaterials[1].m_friction = 0.9; + gMaterials[1].m_restitution = 0.1; + gMaterials[1].foo1 = 53; + gMaterials[1].foo2 = 15; + + int i; + // Set up the vertex data + setVertexPositions(waveheight,0.f); + int index=0; + // Set up the face data + for ( i=0;imaterial index data + for(int a = 0; a < totalTriangles; a++) + { + // This will give the first half of the faces low friction and high restitution + // and the second half of the faces high friction and low restitution + if(a > totalTriangles*0.5f) + gFaceMaterialIndices[a] = 0; + else + gFaceMaterialIndices[a] = 1; + } + + // Create the array structure + m_indexVertexArrays = new btTriangleIndexVertexMaterialArray( + totalTriangles, gIndices, indexStride, + totalVerts,(btScalar*) &gVertices[0].x(),vertStride, + totalMaterials, (unsigned char *)gMaterials, sizeof(CustomMaterial), + gFaceMaterialIndices, sizeof(int)); + + bool useQuantizedAabbCompression = true; + // Create the multimaterial mesh shape + trimeshShape = new btMultimaterialTriangleMeshShape((btTriangleIndexVertexMaterialArray*)m_indexVertexArrays,useQuantizedAabbCompression); + m_collisionShapes.push_back(trimeshShape); + + btCollisionShape* groundShape = trimeshShape; + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + m_broadphase = new btAxisSweep3(worldMin,worldMax); + m_solver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-2,0)); + + btCollisionShape* colShape = new btBoxShape(btVector3(0.5f,0.5f,0.5f)); + m_collisionShapes.push_back(colShape); + + { + for (int i=0;i<1;i++) + { + startTransform.setOrigin(btVector3(10,10,-20)); + btRigidBody* body = localCreateRigidBody(1, startTransform,colShape); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + body->setFriction(0.9f); + body->setGravity(btVector3(0,-20.f,0)); + body->applyCentralImpulse(btVector3(-7.7f,0,0)); + } + } + + startTransform.setIdentity(); + staticBody = localCreateRigidBody(mass, startTransform,groundShape); + + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); + + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); +} + +void MultiMaterialDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_animatedMesh) + { + static float offset=0.f; + offset+=0.01f; + + // setVertexPositions(waveheight,offset); + + int i; + int j; + btVector3 aabbMin(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + btVector3 aabbMax(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + + for ( i=NUM_VERTS_X/2-3;ipartialRefitTree(aabbMin,aabbMax); + + //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + } + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + glutSwapBuffers(); + +} + + + + +void MultiMaterialDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + glFlush(); + glutSwapBuffers(); +} + + + +void MultiMaterialDemo::exitPhysics() +{ + + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btTriangleIndexVertexArray* m_indexVertexArrays; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + bool m_animatedMesh; + + public: + + MultiMaterialDemo() : m_animatedMesh(true) + { + + } + void initPhysics(); + + void exitPhysics(); + + virtual ~MultiMaterialDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + //to show refit works + void setVertexPositions(float waveheight, float offset); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + MultiMaterialDemo* demo = new MultiMaterialDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + }; +}; + +#endif //CONCAVE_DEMO_H + diff --git a/Demos/MultiMaterialDemo/main.cpp b/Demos/MultiMaterialDemo/main.cpp new file mode 100644 index 0000000..9b8d35b --- /dev/null +++ b/Demos/MultiMaterialDemo/main.cpp @@ -0,0 +1,22 @@ + +#include "MultiMaterialDemo.h" +#include "GlutStuff.h" + +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + MultiMaterialDemo* multiMaterialDemo = new MultiMaterialDemo(); + multiMaterialDemo->initPhysics(); + multiMaterialDemo->setCameraDistance(30.f); + + multiMaterialDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + return glutmain(argc, argv,640,480,"Multimaterial Mesh Demo",multiMaterialDemo); +} + diff --git a/Demos/MultiThreadedDemo/CMakeLists.txt b/Demos/MultiThreadedDemo/CMakeLists.txt new file mode 100644 index 0000000..75da820 --- /dev/null +++ b/Demos/MultiThreadedDemo/CMakeLists.txt @@ -0,0 +1,55 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${VECTOR_MATH_INCLUDE} +) + +IF(WIN32) + ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + +LINK_LIBRARIES( +OpenGLSupport BulletMultiThreaded BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppMultiThreadedDemo + main.cpp + MultiThreadedDemo.cpp + MultiThreadedDemo.h +) +IF (UNIX) + TARGET_LINK_LIBRARIES(AppMultiThreadedDemo pthread) +ENDIF(UNIX) + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppMultiThreadedDemo POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppMultiThreadedDemo POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppMultiThreadedDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppMultiThreadedDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppMultiThreadedDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/MultiThreadedDemo/Makefile.am b/Demos/MultiThreadedDemo/Makefile.am new file mode 100644 index 0000000..71d8dd3 --- /dev/null +++ b/Demos/MultiThreadedDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=MultiThreadedDemo + +MultiThreadedDemo_SOURCES=MultiThreadedDemo.cpp MultiThreadedDemo.h main.cpp +MultiThreadedDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL -I@top_builddir@/Extras $(CXXFLAGS) +MultiThreadedDemo_LDADD=-L../OpenGL -L../../Extras -L../../src -lbulletmultithreaded -lbulletopenglsupport -lbulletdynamics -lbulletcollision -lbulletmath @opengl_LIBS@ -lpthread diff --git a/Demos/MultiThreadedDemo/Makefile.in b/Demos/MultiThreadedDemo/Makefile.in new file mode 100644 index 0000000..7e98b0d --- /dev/null +++ b/Demos/MultiThreadedDemo/Makefile.in @@ -0,0 +1,520 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = MultiThreadedDemo$(EXEEXT) +subdir = Demos/MultiThreadedDemo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_MultiThreadedDemo_OBJECTS = \ + MultiThreadedDemo-MultiThreadedDemo.$(OBJEXT) \ + MultiThreadedDemo-main.$(OBJEXT) +MultiThreadedDemo_OBJECTS = $(am_MultiThreadedDemo_OBJECTS) +MultiThreadedDemo_DEPENDENCIES = +MultiThreadedDemo_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(MultiThreadedDemo_SOURCES) +DIST_SOURCES = $(MultiThreadedDemo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +MultiThreadedDemo_SOURCES = MultiThreadedDemo.cpp MultiThreadedDemo.h main.cpp +MultiThreadedDemo_CXXFLAGS = -I@top_builddir@/src -I@top_builddir@/Demos/OpenGL -I@top_builddir@/Extras $(CXXFLAGS) +MultiThreadedDemo_LDADD = -L../OpenGL -L../../Extras -L../../src -lbulletmultithreaded -lbulletopenglsupport -lbulletdynamics -lbulletcollision -lbulletmath @opengl_LIBS@ -lpthread +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/MultiThreadedDemo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/MultiThreadedDemo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +MultiThreadedDemo$(EXEEXT): $(MultiThreadedDemo_OBJECTS) $(MultiThreadedDemo_DEPENDENCIES) + @rm -f MultiThreadedDemo$(EXEEXT) + $(MultiThreadedDemo_LINK) $(MultiThreadedDemo_OBJECTS) $(MultiThreadedDemo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiThreadedDemo-MultiThreadedDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiThreadedDemo-main.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +MultiThreadedDemo-MultiThreadedDemo.o: MultiThreadedDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -MT MultiThreadedDemo-MultiThreadedDemo.o -MD -MP -MF $(DEPDIR)/MultiThreadedDemo-MultiThreadedDemo.Tpo -c -o MultiThreadedDemo-MultiThreadedDemo.o `test -f 'MultiThreadedDemo.cpp' || echo '$(srcdir)/'`MultiThreadedDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/MultiThreadedDemo-MultiThreadedDemo.Tpo $(DEPDIR)/MultiThreadedDemo-MultiThreadedDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MultiThreadedDemo.cpp' object='MultiThreadedDemo-MultiThreadedDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -c -o MultiThreadedDemo-MultiThreadedDemo.o `test -f 'MultiThreadedDemo.cpp' || echo '$(srcdir)/'`MultiThreadedDemo.cpp + +MultiThreadedDemo-MultiThreadedDemo.obj: MultiThreadedDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -MT MultiThreadedDemo-MultiThreadedDemo.obj -MD -MP -MF $(DEPDIR)/MultiThreadedDemo-MultiThreadedDemo.Tpo -c -o MultiThreadedDemo-MultiThreadedDemo.obj `if test -f 'MultiThreadedDemo.cpp'; then $(CYGPATH_W) 'MultiThreadedDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/MultiThreadedDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/MultiThreadedDemo-MultiThreadedDemo.Tpo $(DEPDIR)/MultiThreadedDemo-MultiThreadedDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MultiThreadedDemo.cpp' object='MultiThreadedDemo-MultiThreadedDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -c -o MultiThreadedDemo-MultiThreadedDemo.obj `if test -f 'MultiThreadedDemo.cpp'; then $(CYGPATH_W) 'MultiThreadedDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/MultiThreadedDemo.cpp'; fi` + +MultiThreadedDemo-main.o: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -MT MultiThreadedDemo-main.o -MD -MP -MF $(DEPDIR)/MultiThreadedDemo-main.Tpo -c -o MultiThreadedDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/MultiThreadedDemo-main.Tpo $(DEPDIR)/MultiThreadedDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='MultiThreadedDemo-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -c -o MultiThreadedDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp + +MultiThreadedDemo-main.obj: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -MT MultiThreadedDemo-main.obj -MD -MP -MF $(DEPDIR)/MultiThreadedDemo-main.Tpo -c -o MultiThreadedDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/MultiThreadedDemo-main.Tpo $(DEPDIR)/MultiThreadedDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='MultiThreadedDemo-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MultiThreadedDemo_CXXFLAGS) $(CXXFLAGS) -c -o MultiThreadedDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/MultiThreadedDemo/MultiThreadedDemo.cpp b/Demos/MultiThreadedDemo/MultiThreadedDemo.cpp new file mode 100644 index 0000000..5d4d3a1 --- /dev/null +++ b/Demos/MultiThreadedDemo/MultiThreadedDemo.cpp @@ -0,0 +1,505 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#define USE_PARALLEL_SOLVER 1 //experimental parallel solver +#define USE_PARALLEL_DISPATCHER 1 + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" + +#ifdef USE_PARALLEL_DISPATCHER +#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#include "BulletMultiThreaded/PlatformDefinitions.h" + +#ifdef USE_LIBSPE2 +#include "BulletMultiThreaded/SpuLibspe2Support.h" +#elif defined (_WIN32) +#include "BulletMultiThreaded/Win32ThreadSupport.h" +#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" + +#elif defined (USE_PTHREADS) + +#include "BulletMultiThreaded/PosixThreadSupport.h" +#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" + +#else +//other platforms run the parallel code sequentially (until pthread support or other parallel implementation is added) + +#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#endif //USE_LIBSPE2 + +#ifdef USE_PARALLEL_SOLVER +#include "BulletMultiThreaded/btParallelConstraintSolver.h" +#include "BulletMultiThreaded/SequentialThreadSupport.h" + + +btThreadSupportInterface* createSolverThreadSupport(int maxNumThreads) +{ +//#define SEQUENTIAL +#ifdef SEQUENTIAL + SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads",SolverThreadFunc,SolverlsMemoryFunc); + SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci); + threadSupport->startSPU(); +#else + +#ifdef _WIN32 + Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("solverThreads",SolverThreadFunc,SolverlsMemoryFunc,maxNumThreads); + Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo); + threadSupport->startSPU(); +#elif defined (USE_PTHREADS) + PosixThreadSupport::ThreadConstructionInfo solverConstructionInfo("solver", SolverThreadFunc, + SolverlsMemoryFunc, maxNumThreads); + + PosixThreadSupport* threadSupport = new PosixThreadSupport(solverConstructionInfo); + +#else + SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads",SolverThreadFunc,SolverlsMemoryFunc); + SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci); + threadSupport->startSPU(); +#endif + +#endif + + return threadSupport; +} + +#endif //USE_PARALLEL_SOLVER + +#endif//USE_PARALLEL_DISPATCHER + + + + +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btIDebugDraw.h" + + + +#include //printf debugging + +#include "MultiThreadedDemo.h" +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" + + +extern float eye[3]; +extern int glutScreenWidth; +extern int glutScreenHeight; + +const int maxProxies = 32766; +const int maxOverlap = 65535; + + + + +#ifdef _DEBUG +const int gNumObjects = 120; +#else +const int gNumObjects = 120;//try this in release mode: 3000. never go above 16384, unless you increate maxNumObjects value in DemoApplication.cp +#endif + + +const int maxNumObjects = 32760; + +static int shapeIndex[maxNumObjects]; + + +#define CUBE_HALF_EXTENTS 0.5 + +#define EXTRA_HEIGHT -10.f +//GL_LineSegmentShape shapeE(btVector3(-50,0,0), +// btVector3(50,0,0)); + + +void MultiThreadedDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ) +{ + btTransform trans; + trans.setIdentity(); + + for(int i=0; istepSimulation(1.0f/60.f,0); + //CProfileManager::dumpAll(); + +#else + //during idle mode, just run 1 simulation step maximum + int maxSimSubSteps = m_idle ? 1 : 1; + if (m_idle) + dt = 1.0/420.f; + + int numSimSteps = 0; + numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + + +#ifdef VERBOSE_TIMESTEPPING_CONSOLEOUTPUT + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } +#endif //VERBOSE_TIMESTEPPING_CONSOLEOUTPUT + +#endif + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + } + +#ifdef USE_QUICKPROF + btProfiler::beginBlock("render"); +#endif //USE_QUICKPROF + + renderme(); + + + //render the graphics objects, with center of mass shift + + updateCamera(); + + + +#ifdef USE_QUICKPROF + btProfiler::endBlock("render"); +#endif + glFlush(); + + + glutSwapBuffers(); + +} + + + +void MultiThreadedDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + + renderme(); + + glFlush(); + glutSwapBuffers(); +} + + + + + +void MultiThreadedDemo::initPhysics() +{ +#ifdef USE_PARALLEL_DISPATCHER + m_threadSupportSolver = 0; + m_threadSupportCollision = 0; +#endif + +//#define USE_GROUND_PLANE 1 +#ifdef USE_GROUND_PLANE + m_collisionShapes.push_back(new btStaticPlaneShape(btVector3(0,1,0),0.5)); +#else + + ///Please don't make the box sizes larger then 1000: the collision detection will be inaccurate. + ///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=346 + m_collisionShapes.push_back(new btBoxShape (btVector3(200,CUBE_HALF_EXTENTS,200))); +#endif + + m_collisionShapes.push_back(new btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); + + + + setCameraDistance(32.5f); + + m_azi = 90.f; + + m_dispatcher=0; + btDefaultCollisionConstructionInfo cci; + cci.m_defaultMaxPersistentManifoldPoolSize = 32768; + m_collisionConfiguration = new btDefaultCollisionConfiguration(cci); + +#ifdef USE_PARALLEL_DISPATCHER + int maxNumOutstandingTasks = 4; + +#ifdef USE_WIN32_THREADING + +m_threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( + "collision", + processCollisionTask, + createCollisionLocalStoreMemory, + maxNumOutstandingTasks)); +#else + +#ifdef USE_LIBSPE2 + + spe_program_handle_t * program_handle; +#ifndef USE_CESOF + program_handle = spe_image_open ("./spuCollision.elf"); + if (program_handle == NULL) + { + perror( "SPU OPEN IMAGE ERROR\n"); + } + else + { + printf( "IMAGE OPENED\n"); + } +#else + extern spe_program_handle_t spu_program; + program_handle = &spu_program; +#endif + SpuLibspe2Support* threadSupportCollision = new SpuLibspe2Support( program_handle, maxNumOutstandingTasks); +#elif defined (USE_PTHREADS) + PosixThreadSupport::ThreadConstructionInfo constructionInfo("collision", + processCollisionTask, + createCollisionLocalStoreMemory, + maxNumOutstandingTasks); + m_threadSupportCollision = new PosixThreadSupport(constructionInfo); +#else + + SequentialThreadSupport::SequentialThreadConstructionInfo colCI("collision",processCollisionTask,createCollisionLocalStoreMemory); + SequentialThreadSupport* m_threadSupportCollision = new SequentialThreadSupport(colCI); + +#endif //USE_LIBSPE2 + +///Playstation 3 SPU (SPURS) version is available through PS3 Devnet +/// For Unix/Mac someone could implement a pthreads version of btThreadSupportInterface? +///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface +#endif + + + m_dispatcher = new SpuGatheringCollisionDispatcher(m_threadSupportCollision,maxNumOutstandingTasks,m_collisionConfiguration); +// m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#else + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#endif //USE_PARALLEL_DISPATCHER + + + btVector3 worldAabbMin(-1000,-1000,-1000); + btVector3 worldAabbMax(1000,1000,1000); + + + + m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); + + + +#ifdef USE_PARALLEL_SOLVER + m_threadSupportSolver = createSolverThreadSupport(maxNumOutstandingTasks); + m_solver = new btParallelConstraintSolver(m_threadSupportSolver); + //this solver requires the contacts to be in a contiguous pool, so avoid dynamic allocation + m_dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); +#else + + btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); + m_solver = solver; + //default solverMode is SOLVER_RANDMIZE_ORDER. Warmstarting seems not to improve convergence, see + //solver->setSolverMode(0);//btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); +#endif //USE_PARALLEL_SOLVER + + + btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = world; + + world->getSimulationIslandManager()->setSplitIslands(false); + world->getSolverInfo().m_numIterations = 4; + world->getSolverInfo().m_solverMode = SOLVER_SIMD+SOLVER_USE_WARMSTARTING;//+SOLVER_RANDMIZE_ORDER; + + m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + + + int i; + + btTransform tr; + tr.setIdentity(); + + + for (i=0;i0) + { + shapeIndex[i] = 1;//sphere + } + else + shapeIndex[i] = 0; + } + + + btTransform trans; + trans.setIdentity(); + + btScalar halfExtents = CUBE_HALF_EXTENTS; + + trans.setOrigin(btVector3(0,-halfExtents,0)); + + + + localCreateRigidBody(0.f,trans,m_collisionShapes[shapeIndex[0]]); + + int numWalls = 15; + int wallHeight = 15; + float wallDistance = 3; + + + for ( i=0;isetLinearVelocity(btVector3(0,0,-10)); +#endif +// clientResetScene(); + + +} + + + + + + +void MultiThreadedDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + class btThreadSupportInterface* m_threadSupportCollision; + class btThreadSupportInterface* m_threadSupportSolver; + + btConstraintSolver* m_solver; + + btCollisionAlgorithmCreateFunc* m_boxBoxCF; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + + public: + + void initPhysics(); + + void exitPhysics(); + + virtual ~MultiThreadedDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + void createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ); + + static DemoApplication* Create() + { + MultiThreadedDemo* demo = new MultiThreadedDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + +}; + +#endif //MULTI_THREADED_DEMO_H + diff --git a/Demos/MultiThreadedDemo/main.cpp b/Demos/MultiThreadedDemo/main.cpp new file mode 100644 index 0000000..36b56de --- /dev/null +++ b/Demos/MultiThreadedDemo/main.cpp @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include +#include "MultiThreadedDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + MultiThreadedDemo* demo = new MultiThreadedDemo(); + + demo->initPhysics(); + demo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + + glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",demo); + + delete demo; + + return EXIT_SUCCESS; +} diff --git a/Demos/NativeClient/bin_html/bind.js b/Demos/NativeClient/bin_html/bind.js new file mode 100644 index 0000000..92fbbd2 --- /dev/null +++ b/Demos/NativeClient/bin_html/bind.js @@ -0,0 +1,22 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview This class implements an extension to Function object that + * lets you bind a scope for |this| to a function. + */ + +/** + * Bind a scope to a function. Used to bind an object to |this| for event + * handlers. + * @param {!Object} scope The scope in which the function executes. |scope| + * becomes |this| during function execution. + * @return {function} the bound version of the original function. + */ +Function.prototype.bind = function(scope) { + var boundContext = this; + return function() { + return boundContext.apply(scope, arguments); + } +} diff --git a/Demos/NativeClient/bin_html/dragger.js b/Demos/NativeClient/bin_html/dragger.js new file mode 100644 index 0000000..232d8b5 --- /dev/null +++ b/Demos/NativeClient/bin_html/dragger.js @@ -0,0 +1,134 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview This class implements a mouse-drag event. It registers for + * mousedown events, and when it sees one, starts capturing mousemove events + * until it gets a mousup event. It manufactures three drag events: the + * DRAG_START, DRAG and DRAG_END. + */ + +// Requires bind + +/** + * Constructor for the Dragger. Register for mousedown events that happen on + * |opt_target|. If |opt_target| is null or undefined, then this object + * observes mousedown on the whole document. + * @param {?Element} opt_target The event target. Defaults to the whole + * document. + * @constructor + */ +tumbler.Dragger = function(opt_target) { + /** + * The event target. + * @type {Element} + * @private + */ + this.target_ = opt_target || document; + + /** + * The array of objects that get notified of drag events. Each object in + * this array get sent a handleStartDrag(), handleDrag() and handleEndDrag() + * message. + * @type {Array.} + * @private + */ + this.listeners_ = []; + + /** + * Flag to indicate whether the object is in a drag sequence or not. + * @type {boolean} + * @private + */ + this.isDragging_ = false; + + /** + * The function objects that get attached as event handlers. These are + * cached so that they can be removed on mouse up. + * @type {function} + * @private + */ + this.boundMouseMove_ = null; + this.boundMouseUp_ = null; + + this.target_.addEventListener('mousedown', + this.onMouseDown.bind(this), + false); +} + +/** + * The ids used for drag event types. + * @enum {string} + */ +tumbler.Dragger.DragEvents = { + DRAG_START: 'dragstart', // Start a drag sequence + DRAG: 'drag', // Mouse moved during a drag sequence. + DRAG_END: 'dragend' // End a drag sewquence. +}; + +/** + * Add a drag listener. Each listener should respond to thhree methods: + * handleStartDrag(), handleDrag() and handleEndDrag(). This method assumes + * that |listener| does not already exist in the array of listeners. + * @param {!Object} listener The object that will listen to drag events. + */ +tumbler.Dragger.prototype.addDragListener = function(listener) { + this.listeners_.push(listener); +} + +/** + * Handle a mousedown event: register for mousemove and mouseup, then tell + * the target that is has a DRAG_START event. + * @param {Event} event The mousedown event that triggered this method. + */ +tumbler.Dragger.prototype.onMouseDown = function(event) { + this.boundMouseMove_ = this.onMouseMove.bind(this); + this.boundMouseUp_ = this.onMouseUp.bind(this); + this.target_.addEventListener('mousemove', this.boundMouseMove_); + this.target_.addEventListener('mouseup', this.boundMouseUp_); + this.isDragging_ = true; + var dragStartEvent = { type: tumbler.Dragger.DragEvents.DRAG_START, + clientX: event.offsetX, + clientY: event.offsetY }; + var i; + for (i = 0; i < this.listeners_.length; ++i) { + this.listeners_[i].handleStartDrag(this.target_, dragStartEvent); + } +} + +/** + * Handle a mousemove event: tell the target that is has a DRAG event. + * @param {Event} event The mousemove event that triggered this method. + */ +tumbler.Dragger.prototype.onMouseMove = function(event) { + if (!this.isDragging_) + return; + var dragEvent = { type: tumbler.Dragger.DragEvents.DRAG, + clientX: event.offsetX, + clientY: event.offsetY}; + var i; + for (i = 0; i < this.listeners_.length; ++i) { + this.listeners_[i].handleDrag(this.target_, dragEvent); + } +} + +/** + * Handle a mouseup event: un-register for mousemove and mouseup, then tell + * the target that is has a DRAG_END event. + * @param {Event} event The mouseup event that triggered this method. + */ +tumbler.Dragger.prototype.onMouseUp = function(event) { + this.target_.removeEventListener('mouseup', this.boundMouseUp_, false); + this.target_.removeEventListener('mousemove', this.boundMouseMove_, false); + this.boundMouseUp_ = null; + this.boundMouseMove_ = null; + this.isDragging_ = false; + var dragEndEvent = { type: tumbler.Dragger.DragEvents.DRAG_END, + clientX: event.offsetX, + clientY: event.offsetY}; + var i; + for (i = 0; i < this.listeners_.length; ++i) { + this.listeners_[i].handleEndDrag(this.target_, dragEndEvent); + } +} diff --git a/Demos/NativeClient/bin_html/httpd.cmd b/Demos/NativeClient/bin_html/httpd.cmd new file mode 100644 index 0000000..5a31ae7 --- /dev/null +++ b/Demos/NativeClient/bin_html/httpd.cmd @@ -0,0 +1,9 @@ +@echo off +setlocal + +REM Relative path of CygWin +set CYGWIN=%~dp0%..\third_party\cygwin\bin + +PATH=%CYGWIN%;%PATH% + +python httpd.py diff --git a/Demos/NativeClient/bin_html/httpd.py b/Demos/NativeClient/bin_html/httpd.py new file mode 100644 index 0000000..65434a8 --- /dev/null +++ b/Demos/NativeClient/bin_html/httpd.py @@ -0,0 +1,114 @@ +#!/usr/bin/python +# +# Copyright (c) 2011, The Native Client Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# + +"""A tiny web server. + +This is intended to be used for testing, and only run from within the examples +directory. +""" + +import BaseHTTPServer +import logging +import os +import SimpleHTTPServer +import SocketServer +import sys +import urlparse + +logging.getLogger().setLevel(logging.INFO) + +# Using 'localhost' means that we only accept connections +# via the loop back interface. +SERVER_PORT = 5103 +SERVER_HOST = '' + +# We only run from the examples directory (the one that contains scons-out), so +# that not too much is exposed via this HTTP server. Everything in the +# directory is served, so there should never be anything potentially sensitive +# in the serving directory, especially if the machine might be a +# multi-user machine and not all users are trusted. We only serve via +# the loopback interface. + +SAFE_DIR_COMPONENTS = ['bin_html'] +SAFE_DIR_SUFFIX = apply(os.path.join, SAFE_DIR_COMPONENTS) + +def SanityCheckDirectory(): + if os.getcwd().endswith(SAFE_DIR_SUFFIX): + return + logging.error('httpd.py should only be run from the %s', SAFE_DIR_SUFFIX) + logging.error('directory for testing purposes.') + logging.error('We are currently in %s', os.getcwd()) + sys.exit(1) + + +# An HTTP server that will quit when |is_running| is set to False. We also use +# SocketServer.ThreadingMixIn in order to handle requests asynchronously for +# faster responses. +class QuittableHTTPServer(SocketServer.ThreadingMixIn, + BaseHTTPServer.HTTPServer): + def serve_forever(self, timeout=0.5): + self.is_running = True + self.timeout = timeout + while self.is_running: + self.handle_request() + + def shutdown(self): + self.is_running = False + return 1 + + +# "Safely" split a string at |sep| into a [key, value] pair. If |sep| does not +# exist in |str|, then the entire |str| is the key and the value is set to an +# empty string. +def KeyValuePair(str, sep='='): + if sep in str: + return str.split(sep) + else: + return [str, ''] + + +# A small handler that looks for '?quit=1' query in the path and shuts itself +# down if it finds that parameter. +class QuittableHTTPHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): + def do_GET(self): + (_, _, _, query, _) = urlparse.urlsplit(self.path) + url_params = dict([KeyValuePair(key_value) + for key_value in query.split('&')]) + if 'quit' in url_params and '1' in url_params['quit']: + self.send_response(200, 'OK') + self.send_header('Content-type', 'text/html') + self.send_header('Content-length', '0') + self.end_headers() + self.server.shutdown() + return + + SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) + + +def Run(server_address, + server_class=QuittableHTTPServer, + handler_class=QuittableHTTPHandler): + httpd = server_class(server_address, handler_class) + logging.info("Starting local server on port %d", server_address[1]) + logging.info("To shut down send http://localhost:%d?quit=1", + server_address[1]) + try: + httpd.serve_forever() + except KeyboardInterrupt: + logging.info("Received keyboard interrupt.") + httpd.server_close() + + logging.info("Shutting down local server on port %d", server_address[1]) + + +if __name__ == '__main__': + SanityCheckDirectory() + if len(sys.argv) > 1: + Run((SERVER_HOST, int(sys.argv[1]))) + else: + Run((SERVER_HOST, SERVER_PORT)) + sys.exit(0) diff --git a/Demos/NativeClient/bin_html/index.html b/Demos/NativeClient/bin_html/index.html new file mode 100644 index 0000000..a3002da --- /dev/null +++ b/Demos/NativeClient/bin_html/index.html @@ -0,0 +1,33 @@ + + + + + Interactive Cube Example + + + + + + + + +

    Interactive Cube Example

    +

    + The Native Client module executed in this page draws a 3D cube + and allows you to rotate it using a virtual trackball method. +

    +
    + + + diff --git a/Demos/NativeClient/bin_html/trackball.js b/Demos/NativeClient/bin_html/trackball.js new file mode 100644 index 0000000..88b9a62 --- /dev/null +++ b/Demos/NativeClient/bin_html/trackball.js @@ -0,0 +1,296 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Implement a virtual trackball in the tumbler.Trackball + * class. This class maps 2D mouse events to 3D rotations by simulating a + * trackball that you roll by dragging the mouse. There are two principle + * methods in the class: startAtPointInFrame which you use to begin a trackball + * simulation and rollToPoint, which you use while dragging the mouse. The + * rollToPoint method returns a rotation expressed as a quaternion. + */ + + +// Requires tumbler.Application +// Requires tumbler.DragEvent +// Requires tumbler.Vector3 + +/** + * Constructor for the Trackball object. This class maps 2D mouse drag events + * into 3D rotations by simulating a trackball. The idea is to simulate + * clicking on the trackball, and then rolling it as you drag the mouse. + * The math behind the trackball is simple: start with a vector from the first + * mouse-click on the ball to the center of the 3D view. At the same time, set + * the radius of the ball to be the smaller dimension of the 3D view. As you + * drag the mouse around in the 3D view, a second vector is computed from the + * surface of the ball to the center. The axis of rotation is the cross + * product of these two vectors, and the angle of rotation is the angle between + * the two vectors. + * @constructor + */ +tumbler.Trackball = function() { + /** + * The square of the trackball's radius. The math never looks at the radius, + * but looks at the radius squared. + * @type {number} + * @private + */ + this.sqrRadius_ = 0; + + /** + * The 3D vector representing the point on the trackball where the mouse + * was clicked. Default is pointing stright through the center of the ball. + * @type {Object} + * @private + */ + this.rollStart_ = new tumbler.Vector3(0, 0, 1); + + /** + * The 2D center of the frame that encloses the trackball. + * @type {!Object} + * @private + */ + this.center_ = { x: 0, y: 0 }; + + /** + * Cached camera orientation. When a drag START event happens this is set to + * the current orientation in the calling view's plugin. The default is the + * identity quaternion. + * @type {Array.} + * @private + */ + this.cameraOrientation_ = [0, 0, 0, 1]; +}; + +/** + * Compute the dimensions of the virtual trackball to fit inside |frameSize|. + * The radius of the trackball is set to be 1/2 of the smaller of the two frame + * dimensions, the center point is at the midpoint of each side. + * @param {!goog.math.Size} frameSize 2D-point representing the size of the + * element that encloses the virtual trackball. + * @private + */ +tumbler.Trackball.prototype.initInFrame_ = function(frameSize) { + // Compute the radius of the virtual trackball. This is 1/2 of the smaller + // of the frame's width and height. + var halfFrameSize = 0.5 * Math.min(frameSize.width, frameSize.height); + // Cache the square of the trackball's radius. + this.sqrRadius_ = halfFrameSize * halfFrameSize; + // Figure the center of the view. + this.center_.x = frameSize.width * 0.5; + this.center_.y = frameSize.height * 0.5; +}; + +/** + * Method to convert (by translation) a 2D client point from a coordinate space + * with origin in the lower-left corner of the client view to a space with + * origin in the center of the client view. Use this method before mapping the + * 2D point to he 3D tackball point (see also the projectOnTrackball_() method). + * Call the startAtPointInFrame before calling this method so that the + * |center_| property is correctly initialized. + * @param {!Object} clientPoint map this point to the coordinate space with + * origin in thecenter of the client view. + * @return {Object} the converted point. + * @private + */ +tumbler.Trackball.prototype.convertClientPoint_ = function(clientPoint) { + var difference = { x: clientPoint.x - this.center_.x, + y: clientPoint.y - this.center_.y } + return difference; +}; + +/** + * Method to map a 2D point to a 3D point on the virtual trackball that was set + * up using the startAtPointInFrame method. If the point lies outside of the + * radius of the virtual trackball, then the z-coordinate of the 3D point + * is set to 0. + * @param {!Object.} point 2D-point in the coordinate space with origin + * in the center of the client view. + * @return {tumbler.Vector3} the 3D point on the virtual trackball. + * @private + */ +tumbler.Trackball.prototype.projectOnTrackball_ = function(point) { + var sqrRadius2D = point.x * point.x + point.y * point.y; + var zValue; + if (sqrRadius2D > this.sqrRadius_) { + // |point| lies outside the virtual trackball's sphere, so use a virtual + // z-value of 0. This is equivalent to clicking on the horizontal equator + // of the trackball. + zValue = 0; + } else { + // A sphere can be defined as: r^2 = x^2 + y^2 + z^2, so z = + // sqrt(r^2 - (x^2 + y^2)). + zValue = Math.sqrt(this.sqrRadius_ - sqrRadius2D); + } + var trackballPoint = new tumbler.Vector3(point.x, point.y, zValue); + return trackballPoint; +}; + +/** + * Method to start up the trackball. The trackball works by pretending that a + * ball encloses the 3D view. You roll this pretend ball with the mouse. For + * example, if you click on the center of the ball and move the mouse straight + * to the right, you roll the ball around its Y-axis. This produces a Y-axis + * rotation. You can click on the "edge" of the ball and roll it around + * in a circle to get a Z-axis rotation. + * @param {!Object.} startPoint 2D-point, usually the mouse-down + * point. + * @param {!Object.} frameSize 2D-point representing the size of + * the element that encloses the virtual trackball. + */ +tumbler.Trackball.prototype.startAtPointInFrame = + function(startPoint, frameSize) { + this.initInFrame_(frameSize); + // Compute the starting vector from the surface of the ball to its center. + this.rollStart_ = this.projectOnTrackball_( + this.convertClientPoint_(startPoint)); +}; + +/** + * Method to roll the virtual trackball; call this in response to a mouseDrag + * event. Takes |dragPoint| and projects it from 2D mouse coordinates onto the + * virtual track ball that was set up in startAtPointInFrame method. + * Returns a quaternion that represents the rotation from |rollStart_| to + * |rollEnd_|. + * @param {!Object.} dragPoint 2D-point representing the + * destination mouse point. + * @return {Array.} a quaternion that represents the rotation from + * the point wnere the mouse was clicked on the trackball to this point. + * The quaternion looks like this: [[v], cos(angle/2)], where [v] is the + * imaginary part of the quaternion and is computed as [x, y, z] * + * sin(angle/2). + */ +tumbler.Trackball.prototype.rollToPoint = function(dragPoint) { + var rollTo = this.convertClientPoint_(dragPoint); + if ((Math.abs(this.rollStart_.x - rollTo.x) < + tumbler.Trackball.DOUBLE_EPSILON) && + (Math.abs(this.rollStart_.y, rollTo.y) < + tumbler.Trackball.DOUBLE_EPSILON)) { + // Not enough change in the vectors to roll the ball, return the identity + // quaternion. + return [0, 0, 0, 1]; + } + + // Compute the ending vector from the surface of the ball to its center. + var rollEnd = this.projectOnTrackball_(rollTo); + + // Take the cross product of the two vectors. r = s X e + var rollVector = this.rollStart_.cross(rollEnd); + var invStartMag = 1.0 / this.rollStart_.magnitude(); + var invEndMag = 1.0 / rollEnd.magnitude(); + + // cos(a) = (s . e) / (||s|| ||e||) + var cosAng = this.rollStart_.dot(rollEnd) * invStartMag * invEndMag; + // sin(a) = ||(s X e)|| / (||s|| ||e||) + var sinAng = rollVector.magnitude() * invStartMag * invEndMag; + // Build a quaternion that represents the rotation about |rollVector|. + // Use atan2 for a better angle. If you use only cos or sin, you only get + // half the possible angles, and you can end up with rotations that flip + // around near the poles. + var rollHalfAngle = Math.atan2(sinAng, cosAng) * 0.5; + rollVector.normalize(); + // The quaternion looks like this: [[v], cos(angle/2)], where [v] is the + // imaginary part of the quaternion and is computed as [x, y, z] * + // sin(angle/2). + rollVector.scale(Math.sin(rollHalfAngle)); + var ballQuaternion = [rollVector.x, + rollVector.y, + rollVector.z, + Math.cos(rollHalfAngle)]; + return ballQuaternion; +}; + +/** + * Handle the drag START event: grab the current camera orientation from the + * sending view and set up the virtual trackball. + * @param {!tumbler.Application} view The view controller that called this + * method. + * @param {!tumbler.DragEvent} dragStartEvent The DRAG_START event that + * triggered this handler. + */ +tumbler.Trackball.prototype.handleStartDrag = + function(controller, dragStartEvent) { + // Cache the camera orientation. The orientations from the trackball as it + // rolls are concatenated to this orientation and pushed back into the + // plugin on the other side of the JavaScript bridge. + controller.setCameraOrientation(this.cameraOrientation_); + // Invert the y-coordinate for the trackball computations. + var frameSize = { width: controller.offsetWidth, + height: controller.offsetHeight }; + var flippedY = { x: dragStartEvent.clientX, + y: frameSize.height - dragStartEvent.clientY }; + this.startAtPointInFrame(flippedY, frameSize); +}; + +/** + * Handle the drag DRAG event: concatenate the current orientation to the + * cached orientation. Send this final value through to the GSPlugin via the + * setValueForKey() method. + * @param {!tumbler.Application} view The view controller that called this + * method. + * @param {!tumbler.DragEvent} dragEvent The DRAG event that triggered this + * handler. + */ +tumbler.Trackball.prototype.handleDrag = + function(controller, dragEvent) { + // Flip the y-coordinate so that the 2D origin is in the lower-left corner. + var frameSize = { width: controller.offsetWidth, + height: controller.offsetHeight }; + var flippedY = { x: dragEvent.clientX, + y: frameSize.height - dragEvent.clientY }; + controller.setCameraOrientation( + tumbler.multQuaternions(this.rollToPoint(flippedY), + this.cameraOrientation_)); +}; + +/** + * Handle the drag END event: get the final orientation and concatenate it to + * the cached orientation. + * @param {!tumbler.Application} view The view controller that called this + * method. + * @param {!tumbler.DragEvent} dragEndEvent The DRAG_END event that triggered + * this handler. + */ +tumbler.Trackball.prototype.handleEndDrag = + function(controller, dragEndEvent) { + // Flip the y-coordinate so that the 2D origin is in the lower-left corner. + var frameSize = { width: controller.offsetWidth, + height: controller.offsetHeight }; + var flippedY = { x: dragEndEvent.clientX, + y: frameSize.height - dragEndEvent.clientY }; + this.cameraOrientation_ = tumbler.multQuaternions(this.rollToPoint(flippedY), + this.cameraOrientation_); + controller.setCameraOrientation(this.cameraOrientation_); +}; + +/** + * A utility function to multiply two quaterions. Returns the product q0 * q1. + * This is effectively the same thing as concatenating the two rotations + * represented in each quaternion together. Note that quaternion multiplication + * is NOT commutative: q0 * q1 != q1 * q0. + * @param {!Array.} q0 A 4-element array representing the first + * quaternion. + * @param {!Array.} q1 A 4-element array representing the second + * quaternion. + * @return {Array.} A 4-element array representing the product q0 * q1. + */ +tumbler.multQuaternions = function(q0, q1) { + // Return q0 * q1 (note the order). + var qMult = [ + q0[3] * q1[0] + q0[0] * q1[3] + q0[1] * q1[2] - q0[2] * q1[1], + q0[3] * q1[1] - q0[0] * q1[2] + q0[1] * q1[3] + q0[2] * q1[0], + q0[3] * q1[2] + q0[0] * q1[1] - q0[1] * q1[0] + q0[2] * q1[3], + q0[3] * q1[3] - q0[0] * q1[0] - q0[1] * q1[1] - q0[2] * q1[2] + ]; + return qMult; +}; + +/** + * Real numbers that are less than this distance apart are considered + * equivalent. + * TODO(dspringer): It seems as though there should be a const like this + * in Closure somewhere (goog.math?). + * @type {number} + */ +tumbler.Trackball.DOUBLE_EPSILON = 1.0e-16; diff --git a/Demos/NativeClient/bin_html/tumbler.js b/Demos/NativeClient/bin_html/tumbler.js new file mode 100644 index 0000000..e8e42eb --- /dev/null +++ b/Demos/NativeClient/bin_html/tumbler.js @@ -0,0 +1,133 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The tumbler Application object. This object instantiates a + * Trackball object and connects it to the element named |tumbler_content|. + * It also conditionally embeds a debuggable module or a release module into + * the |tumbler_content| element. + */ + +// Requires tumbler +// Requires tumbler.Dragger +// Requires tumbler.Trackball + +/** + * Constructor for the Application class. Use the run() method to populate + * the object with controllers and wire up the events. + * @constructor + */ +tumbler.Application = function() { + /** + * The native module for the application. This refers to the module loaded + * via the tag. + * @type {Element} + * @private + */ + this.module_ = null; + + /** + * The trackball object. + * @type {tumbler.Trackball} + * @private + */ + this.trackball_ = null; + + /** + * The mouse-drag event object. + * @type {tumbler.Dragger} + * @private + */ + this.dragger_ = null; + + /** + * The function objects that get attached as event handlers. These are + * cached so that they can be removed when they are no longer needed. + * @type {function} + * @private + */ + this.boundModuleDidLoad_ = null; +} + +/** + * The ids used for elements in the DOM. The Tumlber Application expects these + * elements to exist. + * @enum {string} + * @private + */ +tumbler.Application.DomIds_ = { + MODULE: 'tumbler', // The element representing the NaCl module + VIEW: 'tumbler_view' // The
    containing the NaCl element. +} + +/** + * Called by the module loading function once the module has been loaded. + * @param {?Element} nativeModule The instance of the native module. + */ +tumbler.Application.prototype.moduleDidLoad = function() { + this.module_ = document.getElementById(tumbler.Application.DomIds_.MODULE); + // Unbind the load function. + this.boundModuleDidLoad_ = null; + + /** + * Set the camera orientation property on the NaCl module. + * @param {Array.} orientation A 4-element array representing the + * camera orientation as a quaternion. + */ + this.module_.setCameraOrientation = function(orientation) { + var methodString = 'setCameraOrientation ' + + 'orientation:' + + JSON.stringify(orientation); + this.postMessage(methodString); + } + + this.trackball_ = new tumbler.Trackball(); + this.dragger_ = new tumbler.Dragger(this.module_); + this.dragger_.addDragListener(this.trackball_); +} + +/** + * Asserts that cond is true; issues an alert and throws an Error otherwise. + * @param {bool} cond The condition. + * @param {String} message The error message issued if cond is false. + */ +tumbler.Application.prototype.assert = function(cond, message) { + if (!cond) { + message = "Assertion failed: " + message; + alert(message); + throw new Error(message); + } +} + +/** + * The run() method starts and 'runs' the application. The trackball object + * is allocated and all the events get wired up. + * @param {?String} opt_contentDivName The id of a DOM element in which to + * embed the Native Client module. If unspecified, defaults to + * VIEW. The DOM element must exist. + */ +tumbler.Application.prototype.run = function(opt_contentDivName) { + contentDivName = opt_contentDivName || tumbler.Application.DomIds_.VIEW; + var contentDiv = document.getElementById(contentDivName); + this.assert(contentDiv, "Missing DOM element '" + contentDivName + "'"); + + // Note that the element is wrapped inside a
    , which has a 'load' + // event listener attached. This method is used instead of attaching the + // 'load' event listener directly to the element to ensure that the + // listener is active before the NaCl module 'load' event fires. + this.boundModuleDidLoad_ = this.moduleDidLoad.bind(this); + contentDiv.addEventListener('load', this.boundModuleDidLoad_, true); + + // Load the published .nexe. This includes the 'nacl' attribute which + // shows how to load multi-architecture modules. Each entry in the "nexes" + // object in the .nmf manifest file is a key-value pair: the key is the + // runtime ('x86-32', 'x86-64', etc.); the value is a URL for the desired + // NaCl module. To load the debug versions of your .nexes, set the 'nacl' + // attribute to the _dbg.nmf version of the manifest file. + contentDiv.innerHTML = '' +} diff --git a/Demos/NativeClient/bin_html/tumbler.nmf b/Demos/NativeClient/bin_html/tumbler.nmf new file mode 100644 index 0000000..1c5b495 --- /dev/null +++ b/Demos/NativeClient/bin_html/tumbler.nmf @@ -0,0 +1,6 @@ +{ + "program": { + "x86-64": {"url": "NativeClientTumbler_x64.exe"}, + "x86-32": {"url": "NativeClientTumbler.exe"} + } +} diff --git a/Demos/NativeClient/bin_html/vector3.js b/Demos/NativeClient/bin_html/vector3.js new file mode 100644 index 0000000..a79f781 --- /dev/null +++ b/Demos/NativeClient/bin_html/vector3.js @@ -0,0 +1,91 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview A 3D vector class. Proviudes some utility functions on + * 3-dimentional vectors. + */ + +// Requires tumbler + +/** + * Constructor for the Vector3 object. This class contains a 3-tuple that + * represents a vector in 3D space. + * @param {?number} opt_x The x-coordinate for this vector. If null or + * undefined, the x-coordinate value is set to 0. + * @param {?number} opt_y The y-coordinate for this vector. If null or + * undefined, the y-coordinate value is set to 0. + * @param {?number} opt_z The z-coordinate for this vector. If null or + * undefined, the z-coordinate value is set to 0. + * @constructor + */ +tumbler.Vector3 = function(opt_x, opt_y, opt_z) { + /** + * The vector's 3-tuple. + * @type {number} + */ + this.x = opt_x || 0; + this.y = opt_y || 0; + this.z = opt_z || 0; +} + +/** + * Method to return the magnitude of a Vector3. + * @return {number} the magnitude of the vector. + */ +tumbler.Vector3.prototype.magnitude = function() { + return Math.sqrt(this.dot(this)); +} + +/** + * Normalize the vector in-place. + * @return {number} the magnitude of the vector. + */ +tumbler.Vector3.prototype.normalize = function() { + var mag = this.magnitude(); + if (mag < tumbler.Vector3.DOUBLE_EPSILON) + return 0.0; // |this| is equivalent to the 0-vector, don't normalize. + this.scale(1.0 / mag); + return mag; +} + +/** + * Scale the vector in-place by |s|. + * @param {!number} s The scale factor. + */ +tumbler.Vector3.prototype.scale = function(s) { + this.x *= s; + this.y *= s; + this.z *= s; +} + +/** + * Compute the dot product: |this| . v. + * @param {!tumbler.Vector3} v The vector to dot. + * @return {number} the result of |this| . v. + */ +tumbler.Vector3.prototype.dot = function(v) { + return this.x * v.x + this.y * v.y + this.z * v.z; +} + +/** + * Compute the cross product: |this| X v. + * @param {!tumbler.Vector3} v The vector to cross with. + * @return {tumbler.Vector3} the result of |this| X v. + */ +tumbler.Vector3.prototype.cross = function(v) { + var vCross = new tumbler.Vector3(this.y * v.z - this.z * v.y, + this.z * v.x - this.x * v.z, + this.x * v.y - this.y * v.x); + return vCross; +} + +/** + * Real numbers that are less than this distance apart are considered + * equivalent. + * TODO(dspringer): It seems as though there should be a const like this + * in generally available somewhere. + * @type {number} + */ +tumbler.Vector3.DOUBLE_EPSILON = 1.0e-16; diff --git a/Demos/NativeClient/callback.h b/Demos/NativeClient/callback.h new file mode 100644 index 0000000..4d67262 --- /dev/null +++ b/Demos/NativeClient/callback.h @@ -0,0 +1,92 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXAMPLES_TUMBLER_CALLBACK_H_ +#define EXAMPLES_TUMBLER_CALLBACK_H_ + +#include +#include +#include + +namespace tumbler { + +class ScriptingBridge; + +// Templates used to support method call-backs when a method or property is +// accessed from the browser code. + +// Class suite used to publish a method name to Javascript. Typical use is +// like this: +// photo::MethodCallback* calculate_callback_; +// calculate_callback_ = +// new scripting::MethodCallback(this, +// &Calculator::Calculate); +// bridge->AddMethodNamed("calculate", calculate_callback_); +// ... +// delete calculate_callback_; +// +// The caller must delete the callback. + +// Methods get parameters as a dictionary that maps parameter names to values. +typedef std::map MethodParameter; + +// Pure virtual class used in STL containers. +class MethodCallbackExecutor { + public: + virtual ~MethodCallbackExecutor() {} + virtual void Execute( + const ScriptingBridge& bridge, + const MethodParameter& parameters) = 0; +}; + +template +class MethodCallback : public MethodCallbackExecutor { + public: + typedef void (T::*Method)( + const ScriptingBridge& bridge, + const MethodParameter& parameters); + + MethodCallback(T* instance, Method method) + : instance_(instance), method_(method) {} + virtual ~MethodCallback() {} + virtual void Execute( + const ScriptingBridge& bridge, + const MethodParameter& parameters) { + // Use "this->" to force C++ to look inside our templatized base class; see + // Effective C++, 3rd Ed, item 43, p210 for details. + ((this->instance_)->*(this->method_))(bridge, parameters); + } + + private: + T* instance_; + Method method_; +}; + +template +class ConstMethodCallback : public MethodCallbackExecutor { + public: + typedef void (T::*ConstMethod)( + const ScriptingBridge& bridge, + const MethodParameter& parameters) const; + + ConstMethodCallback(const T* instance, ConstMethod method) + : instance_(instance), const_method_(method) {} + virtual ~ConstMethodCallback() {} + virtual void Execute( + const ScriptingBridge& bridge, + const MethodParameter& parameters) { + // Use "this->" to force C++ to look inside our templatized base class; see + // Effective C++, 3rd Ed, item 43, p210 for details. + ((this->instance_)->*(this->const_method_))(bridge, parameters); + } + + private: + const T* instance_; + ConstMethod const_method_; +}; + +} // namespace tumbler + +#endif // EXAMPLES_TUMBLER_CALLBACK_H_ + diff --git a/Demos/NativeClient/cube.cc b/Demos/NativeClient/cube.cc new file mode 100644 index 0000000..777e6eb --- /dev/null +++ b/Demos/NativeClient/cube.cc @@ -0,0 +1,267 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cube.h" + +#include + +#include "shader_util.h" +#include "transforms.h" + +namespace tumbler { + +static const size_t kVertexCount = 24; +static const int kIndexCount = 36; + +Cube::Cube(SharedOpenGLContext opengl_context) + : opengl_context_(opengl_context), + width_(1), + height_(1) { + eye_[0] = eye_[1] = 0.0f; + eye_[2] = 2.0f; + orientation_[0] = 0.0f; + orientation_[1] = 0.0f; + orientation_[2] = 0.0f; + orientation_[3] = 1.0f; +} + +Cube::~Cube() { + glDeleteBuffers(3, cube_vbos_); + glDeleteProgram(shader_program_object_); +} + +void Cube::PrepareOpenGL() { + CreateShaders(); + CreateCube(); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_DEPTH_TEST); +} + +void Cube::Resize(int width, int height) { + width_ = std::max(width, 1); + height_ = std::max(height, 1); + // Set the viewport + glViewport(0, 0, width_, height_); + // Compute the perspective projection matrix with a 60 degree FOV. + GLfloat aspect = static_cast(width_) / static_cast(height_); + transform_4x4::LoadIdentity(perspective_proj_); + transform_4x4::Perspective(perspective_proj_, 60.0f, aspect, 1.0f, 20.0f); +} + +void Cube::Draw() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Compute a new model-view matrix, then use that to make the composite + // model-view-projection matrix: MVP = MV . P. + GLfloat model_view[16]; + ComputeModelViewTransform(model_view); + transform_4x4::Multiply(mvp_matrix_, model_view, perspective_proj_); + + glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[0]); + glUseProgram(shader_program_object_); + glEnableVertexAttribArray(position_location_); + glVertexAttribPointer(position_location_, + 3, + GL_FLOAT, + GL_FALSE, + 3 * sizeof(GLfloat), + NULL); + glEnableVertexAttribArray(color_location_); + glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[1]); + glVertexAttribPointer(color_location_, + 3, + GL_FLOAT, + GL_FALSE, + 3 * sizeof(GLfloat), + NULL); + glUniformMatrix4fv(mvp_location_, 1, GL_FALSE, mvp_matrix_); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_vbos_[2]); + glDrawElements(GL_TRIANGLES, kIndexCount, GL_UNSIGNED_SHORT, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +bool Cube::CreateShaders() { + const char vertex_shader_src[] = + "uniform mat4 u_mvpMatrix; \n" + "attribute vec4 a_position; \n" + "attribute vec3 a_color; \n" + "varying lowp vec4 v_color; \n" + "void main() \n" + "{ \n" + " v_color.xyz = a_color; \n" + " v_color.w = 1.0; \n" + " gl_Position = u_mvpMatrix * a_position; \n" + "} \n"; + + const char fragment_shader_src[] = + "varying lowp vec4 v_color; \n" + "void main() \n" + "{ \n" + " gl_FragColor = v_color; \n" + "} \n"; + + // Load the shaders and get a linked program object + shader_program_object_ = + shader_util::CreateProgramFromVertexAndFragmentShaders( + vertex_shader_src, fragment_shader_src); + if (shader_program_object_ == 0) + return false; + position_location_ = glGetAttribLocation(shader_program_object_, + "a_position"); + color_location_ = glGetAttribLocation(shader_program_object_, "a_color"); + mvp_location_ = glGetUniformLocation(shader_program_object_, "u_mvpMatrix"); + return true; +} + +void Cube::CreateCube() { + static const GLfloat cube_vertices[] = { + // Vertex coordinates interleaved with color values + // Bottom + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + // Top + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + // Back + -0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + // Front + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + // Left + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, -0.5f, + // Right + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f + }; + + static const GLfloat cube_colors[] = { + // Vertex coordinates interleaved with color values + // Bottom + 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + // Top + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + // Back + 0.0, 0.0, 1.0, + 0.0, 0.0, 1.0, + 0.0, 0.0, 1.0, + 0.0, 0.0, 1.0, + // Front + 1.0, 0.0, 1.0, + 1.0, 0.0, 1.0, + 1.0, 0.0, 1.0, + 1.0, 0.0, 1.0, + // Left + 1.0, 1.0, 0.0, + 1.0, 1.0, 0.0, + 1.0, 1.0, 0.0, + 1.0, 1.0, 0.0, + // Right + 0.0, 1.0, 1.0, + 0.0, 1.0, 1.0, + 0.0, 1.0, 1.0, + 0.0, 1.0, 1.0 + }; + + static const GLushort cube_indices[] = { + // Bottom + 0, 2, 1, + 0, 3, 2, + // Top + 4, 5, 6, + 4, 6, 7, + // Back + 8, 9, 10, + 8, 10, 11, + // Front + 12, 15, 14, + 12, 14, 13, + // Left + 16, 17, 18, + 16, 18, 19, + // Right + 20, 23, 22, + 20, 22, 21 + }; + + // Generate the VBOs and upload them to the graphics context. + glGenBuffers(3, cube_vbos_); + glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[0]); + glBufferData(GL_ARRAY_BUFFER, + kVertexCount * sizeof(GLfloat) * 3, + cube_vertices, + GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[1]); + glBufferData(GL_ARRAY_BUFFER, + kVertexCount * sizeof(GLfloat) * 3, + cube_colors, + GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_vbos_[2]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + kIndexCount * sizeof(GL_UNSIGNED_SHORT), + cube_indices, + GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void Cube::ComputeModelViewTransform(GLfloat* model_view) { + // This method takes into account the possiblity that |orientation_| + // might not be normalized. + double sqrx = orientation_[0] * orientation_[0]; + double sqry = orientation_[1] * orientation_[1]; + double sqrz = orientation_[2] * orientation_[2]; + double sqrw = orientation_[3] * orientation_[3]; + double sqrLength = 1.0 / (sqrx + sqry + sqrz + sqrw); + + transform_4x4::LoadIdentity(model_view); + model_view[0] = (sqrx - sqry - sqrz + sqrw) * sqrLength; + model_view[5] = (-sqrx + sqry - sqrz + sqrw) * sqrLength; + model_view[10] = (-sqrx - sqry + sqrz + sqrw) * sqrLength; + + double temp1 = orientation_[0] * orientation_[1]; + double temp2 = orientation_[2] * orientation_[3]; + model_view[1] = 2.0 * (temp1 + temp2) * sqrLength; + model_view[4] = 2.0 * (temp1 - temp2) * sqrLength; + + temp1 = orientation_[0] * orientation_[2]; + temp2 = orientation_[1] * orientation_[3]; + model_view[2] = 2.0 * (temp1 - temp2) * sqrLength; + model_view[8] = 2.0 * (temp1 + temp2) * sqrLength; + temp1 = orientation_[1] * orientation_[2]; + temp2 = orientation_[0] * orientation_[3]; + model_view[6] = 2.0 * (temp1 + temp2) * sqrLength; + model_view[9] = 2.0 * (temp1 - temp2) * sqrLength; + model_view[3] = 0.0; + model_view[7] = 0.0; + model_view[11] = 0.0; + + // Concatenate the translation to the eye point. + model_view[12] = -eye_[0]; + model_view[13] = -eye_[1]; + model_view[14] = -eye_[2]; + model_view[15] = 1.0; +} + +} // namespace tumbler diff --git a/Demos/NativeClient/cube.h b/Demos/NativeClient/cube.h new file mode 100644 index 0000000..1c3b62b --- /dev/null +++ b/Demos/NativeClient/cube.h @@ -0,0 +1,97 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXAMPLES_TUMBLER_CUBE_H_ +#define EXAMPLES_TUMBLER_CUBE_H_ + +#include +#include +#include "opengl_context.h" +#include "opengl_context_ptrs.h" + +namespace tumbler { + +// The Cube class provides a place to implement 3D rendering. It has a +// frame that it occupies in a browser window. +class Cube { + public: + explicit Cube(SharedOpenGLContext opengl_context); + ~Cube(); + + // Called once when a new RenderContext is first bound to the view. The + // bound context is guaranteed to be current and valid before calling this + // method. + void PrepareOpenGL(); + + // Called whenever the size of the browser view changes. This method is + // called at least once when the view is first made visible. Clamps the + // sizes to 1. + void Resize(int width, int height); + + // Called every time the view need to be drawn. The bound context is + // guaranteed to be current and valid before this method is called. The + // visible portion of the context is flushed to the browser after this + // method returns. + void Draw(); + + // Accessor for width and height. To change these, call Resize. + const int width() const { + return width_; + } + + const int height() const { + return height_; + } + + // Accessor/mutator for the camera orientation. + void GetOrientation(std::vector* orientation) const { + if (!orientation) + return; + (*orientation)[0] = static_cast(orientation_[0]); + (*orientation)[1] = static_cast(orientation_[1]); + (*orientation)[2] = static_cast(orientation_[2]); + (*orientation)[3] = static_cast(orientation_[3]); + } + void SetOrientation(const std::vector& orientation) { + orientation_[0] = static_cast(orientation[0]); + orientation_[1] = static_cast(orientation[1]); + orientation_[2] = static_cast(orientation[2]); + orientation_[3] = static_cast(orientation[3]); + } + + private: + // Create the shaders used to draw the cube, and link them into a program. + // Initializes |shader_progam_object_|, |position_loction_| and + // |mvp_location_|. + bool CreateShaders(); + + // Generates a cube as a series of GL_TRIANGLE_STRIPs, and initializes + // |index_count_| to the number of indices in the index list used as a VBO. + // Creates the |vbo_ids_| required for the vertex and index data and uploads + // the the VBO data. + void CreateCube(); + + // Build up the model-view transform from the eye and orienation properties. + // Assumes that |model_view| is a 4x4 matrix. + void ComputeModelViewTransform(GLfloat* model_view); + + SharedOpenGLContext opengl_context_; + int width_; + int height_; + GLuint shader_program_object_; // The compiled shaders. + GLint position_location_; // The position attribute location. + GLint color_location_; // The color attribute location. + GLint mvp_location_; // The Model-View-Projection composite matrix. + GLuint cube_vbos_[3]; + GLfloat eye_[3]; // The eye point of the virtual camera. + // The orientation of the virtual camera stored as a quaternion. The + // quaternion is laid out as {{x, y, z}, w}. + GLfloat orientation_[4]; + GLfloat perspective_proj_[16]; + GLfloat mvp_matrix_[16]; +}; + +} // namespace tumbler + +#endif // EXAMPLES_TUMBLER_CUBE_H_ diff --git a/Demos/NativeClient/opengl_context.cc b/Demos/NativeClient/opengl_context.cc new file mode 100644 index 0000000..1c0afa7 --- /dev/null +++ b/Demos/NativeClient/opengl_context.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "opengl_context.h" + +#include +#include "ppapi/gles2/gl2ext_ppapi.h" + +namespace { +// This is called by the brower when the 3D context has been flushed to the +// browser window. +void FlushCallback(void* data, int32_t result) { + static_cast(data)->set_flush_pending(false); +} +} // namespace + +namespace tumbler { + +OpenGLContext::OpenGLContext(pp::Instance* instance) + : pp::Graphics3DClient_Dev(instance), + flush_pending_(false) { + pp::Module* module = pp::Module::Get(); + assert(module); + gles2_interface_ = static_cast( + module->GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE)); + assert(gles2_interface_); +} + +OpenGLContext::~OpenGLContext() { + glSetCurrentContextPPAPI(0); +} + +bool OpenGLContext::MakeContextCurrent(pp::Instance* instance) { + if (instance == NULL) { + glSetCurrentContextPPAPI(0); + return false; + } + // Lazily create the Pepper context. + if (context_.is_null()) { + context_ = pp::Context3D_Dev(*instance, 0, pp::Context3D_Dev(), NULL); + if (context_.is_null()) { + glSetCurrentContextPPAPI(0); + return false; + } + surface_ = pp::Surface3D_Dev(*instance, 0, NULL); + context_.BindSurfaces(surface_, surface_); + instance->BindGraphics(surface_); + } + glSetCurrentContextPPAPI(context_.pp_resource()); + return true; +} + +void OpenGLContext::InvalidateContext(pp::Instance* instance) { + if (instance == NULL) + return; + // Unbind the existing surface and re-bind to null surfaces. + instance->BindGraphics(pp::Surface3D_Dev()); + context_.BindSurfaces(pp::Surface3D_Dev(), pp::Surface3D_Dev()); + glSetCurrentContextPPAPI(0); +} + +void OpenGLContext::FlushContext() { + if (flush_pending()) { + // A flush is pending so do nothing; just drop this flush on the floor. + return; + } + set_flush_pending(true); + surface_.SwapBuffers(pp::CompletionCallback(&FlushCallback, this)); +} +} // namespace tumbler + diff --git a/Demos/NativeClient/opengl_context.h b/Demos/NativeClient/opengl_context.h new file mode 100644 index 0000000..851b9db --- /dev/null +++ b/Demos/NativeClient/opengl_context.h @@ -0,0 +1,90 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXAMPLES_TUMBLER_OPENGL_CONTEXT_H_ +#define EXAMPLES_TUMBLER_OPENGL_CONTEXT_H_ + +/// +/// @file +/// OpenGLContext manages the OpenGL context in the browser that is associated +/// with a @a pp::Instance instance. +/// + +#include + +#include +#include + +#include "opengl_context_ptrs.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" +#include "ppapi/cpp/dev/context_3d_dev.h" +#include "ppapi/cpp/dev/graphics_3d_client_dev.h" +#include "ppapi/cpp/dev/graphics_3d_dev.h" +#include "ppapi/cpp/dev/surface_3d_dev.h" +#include "ppapi/cpp/instance.h" + +namespace tumbler { + +/// OpenGLContext manages an OpenGL rendering context in the browser. +/// +class OpenGLContext : public pp::Graphics3DClient_Dev { + public: + explicit OpenGLContext(pp::Instance* instance); + + /// Release all the in-browser resources used by this context, and make this + /// context invalid. + virtual ~OpenGLContext(); + + /// The Graphics3DClient interfcace. + virtual void Graphics3DContextLost() { + assert(!"Unexpectedly lost graphics context"); + } + + /// Make @a this the current 3D context in @a instance. + /// @param instance The instance of the NaCl module that will receive the + /// the current 3D context. + /// @return success. + bool MakeContextCurrent(pp::Instance* instance); + + /// Flush the contents of this context to the browser's 3D device. + void FlushContext(); + + /// Make the underlying 3D device invalid, so that any subsequent rendering + /// commands will have no effect. The next call to MakeContextCurrent() will + /// cause the underlying 3D device to get rebound and start receiving + /// receiving rendering commands again. Use InvalidateContext(), for + /// example, when resizing the context's viewing area. + void InvalidateContext(pp::Instance* instance); + + /// The OpenGL ES 2.0 interface. + const struct PPB_OpenGLES2_Dev* gles2() const { + return gles2_interface_; + } + + /// The PP_Resource needed to make GLES2 calls through the Pepper interface. + const PP_Resource gl_context() const { + return context_.pp_resource(); + } + + /// Indicate whether a flush is pending. This can only be called from the + /// main thread; it is not thread safe. + bool flush_pending() const { + return flush_pending_; + } + void set_flush_pending(bool flag) { + flush_pending_ = flag; + } + + private: + pp::Context3D_Dev context_; + pp::Surface3D_Dev surface_; + bool flush_pending_; + + const struct PPB_OpenGLES2_Dev* gles2_interface_; +}; + +} // namespace tumbler + +#endif // EXAMPLES_TUMBLER_OPENGL_CONTEXT_H_ + diff --git a/Demos/NativeClient/opengl_context_ptrs.h b/Demos/NativeClient/opengl_context_ptrs.h new file mode 100644 index 0000000..3478521 --- /dev/null +++ b/Demos/NativeClient/opengl_context_ptrs.h @@ -0,0 +1,22 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXAMPLES_TUMBLER_OPENGL_CONTEXT_PTRS_H_ +#define EXAMPLES_TUMBLER_OPENGL_CONTEXT_PTRS_H_ + +// A convenience wrapper for a shared OpenGLContext pointer type. As other +// smart pointer types are needed, add them here. + +#include + +namespace tumbler { + +class OpenGLContext; + +typedef std::tr1::shared_ptr SharedOpenGLContext; + +} // namespace tumbler + +#endif // EXAMPLES_TUMBLER_OPENGL_CONTEXT_PTRS_H_ + diff --git a/Demos/NativeClient/premake4.lua b/Demos/NativeClient/premake4.lua new file mode 100644 index 0000000..2090597 --- /dev/null +++ b/Demos/NativeClient/premake4.lua @@ -0,0 +1,27 @@ + project "NativeClientTumbler" + + kind "ConsoleApp" + + targetdir "bin_html" + + includedirs { "." } + + --libdirs {} + + links { + "ppapi_gles2", + "ppapi", + "ppapi_cpp", + "ppruntime" + } + + + files { + "cube.cc", + "opengl_context.cc", + "scripting_bridge.cc", + "shader_util.cc", + "transforms.cc", + "tumbler.cc", + "tumbler_module.cc" + } \ No newline at end of file diff --git a/Demos/NativeClient/scripting_bridge.cc b/Demos/NativeClient/scripting_bridge.cc new file mode 100644 index 0000000..abc67ca --- /dev/null +++ b/Demos/NativeClient/scripting_bridge.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "scripting_bridge.h" + +namespace { +const char* const kWhiteSpaceCharacters = " \t"; + +// Helper function to pull out the next token in |token_string|. A token is +// delimited by whitespace. Scanning begins at |*pos|, if pos goes beyond the +// end of |token_string|, it is set to std::string::npos and an empty string +// is returned. On return, |*pos| will point to the beginning of the next +// token. |pos| must not be NULL. +const std::string ScanToken(const std::string& token_string, size_t* pos) { + std::string token; + if (*pos == std::string::npos) { + return token; + } + size_t token_start_pos = token_string.find_first_not_of(kWhiteSpaceCharacters, + *pos); + size_t token_end_pos = token_string.find_first_of(kWhiteSpaceCharacters, + token_start_pos); + if (token_start_pos != std::string::npos) { + token = token_string.substr(token_start_pos, token_end_pos); + } + *pos = token_end_pos; + return token; +} + +// Take a string of the form 'name:value' and split it into two strings, one +// containing 'name' and the other 'value'. If the ':' separator is missing, +// or is the last character in |parameter|, |parameter| is copied to +// |param_name|, |param_value| is left unchanged and false is returned. +bool ParseParameter(const std::string& parameter, + std::string* param_name, + std::string* param_value) { + bool success = false; + size_t sep_pos = parameter.find_first_of(':'); + if (sep_pos != std::string::npos) { + *param_name = parameter.substr(0, sep_pos); + if (sep_pos < parameter.length() - 1) { + *param_value = parameter.substr(sep_pos + 1); + success = true; + } else { + success = false; + } + } else { + *param_name = parameter; + success = false; + } + return success; +} +} // namespace + +namespace tumbler { + +bool ScriptingBridge::AddMethodNamed(const std::string& method_name, + SharedMethodCallbackExecutor method) { + if (method_name.size() == 0 || method == NULL) + return false; + method_dictionary_.insert( + std::pair(method_name, + method)); + return true; +} + +bool ScriptingBridge::InvokeMethod(const std::string& method) { + size_t current_pos = 0; + const std::string method_name = ScanToken(method, ¤t_pos); + MethodDictionary::iterator method_iter; + method_iter = method_dictionary_.find(method_name); + if (method_iter != method_dictionary_.end()) { + // Pull out the method parameters and build a dictionary that maps + // parameter names to values. + std::map param_dict; + while (current_pos != std::string::npos) { + const std::string parameter = ScanToken(method, ¤t_pos); + if (parameter.length()) { + std::string param_name; + std::string param_value; + if (ParseParameter(parameter, ¶m_name, ¶m_value)) { + // Note that duplicate parameter names will override each other. The + // last one in the method string will be used. + param_dict[param_name] = param_value; + } + } + } + (*method_iter->second).Execute(*this, param_dict); + return true; + } + return false; +} + +} // namespace tumbler diff --git a/Demos/NativeClient/scripting_bridge.h b/Demos/NativeClient/scripting_bridge.h new file mode 100644 index 0000000..f6a366c --- /dev/null +++ b/Demos/NativeClient/scripting_bridge.h @@ -0,0 +1,52 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXAMPLES_TUMBLER_SCRIPTING_BRIDGE_H_ +#define EXAMPLES_TUMBLER_SCRIPTING_BRIDGE_H_ + +#include +#include +#include +#include + +#include "callback.h" +#include "ppapi/cpp/var.h" + +namespace tumbler { + +class MethodCallbackExecutor; + +// This class handles the interface between the browser and the NaCl module. +// There is a single point of entry from the browser: postMessage(). The +// string passed to postMessage() has this format: +// 'function_name arg_name0:arg_0 arg_name1:arg1 ...' +// The arguments have undetermined type; they are placed in a map of argument +// names and values. Values are all strings, it is up to the target code to +// do any type coercion. +// Methods called by the scripting bridge must have a signature like this: +// void Method(const ScriptingBridge& bridge, +// const ParameterDictionary&); +class ScriptingBridge { + public: + // Shared pointer type used in the method map. + typedef std::tr1::shared_ptr + SharedMethodCallbackExecutor; + + virtual ~ScriptingBridge() {} + + // Causes |method_name| to be published as a method that can be called via + // postMessage() from the browser. Associates this method with |method|. + bool AddMethodNamed(const std::string& method_name, + SharedMethodCallbackExecutor method); + + bool InvokeMethod(const std::string& method); + + private: + typedef std::map MethodDictionary; + + MethodDictionary method_dictionary_; +}; + +} // namespace tumbler +#endif // EXAMPLES_TUMBLER_SCRIPTING_BRIDGE_H_ diff --git a/Demos/NativeClient/shader_util.cc b/Demos/NativeClient/shader_util.cc new file mode 100644 index 0000000..802955b --- /dev/null +++ b/Demos/NativeClient/shader_util.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "shader_util.h" + +#include +#include + +namespace shader_util { + +GLuint CreateShaderOfType(GLenum type, const char *shader_src) { + GLuint shader; + GLint compiled; + + // Create the shader object + shader = glCreateShader(type); + + if (shader == 0) + return 0; + + // Load and compile the shader source + glShaderSource(shader, 1, &shader_src, NULL); + glCompileShader(shader); + + // Check the compile status + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (compiled == 0) { + GLint info_len = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len); + if (info_len > 1) { + char* info_log = reinterpret_cast(malloc(sizeof(char) * info_len)); + glGetShaderInfoLog(shader, info_len, NULL, info_log); + // TODO(dspringer): We could really use a logging API. + printf("Error compiling shader:\n%s\n", info_log); + free(info_log); + } + glDeleteShader(shader); + return 0; + } + + return shader; +} + +GLuint CreateProgramFromVertexAndFragmentShaders( + const char *vertex_shader_src, const char *fragment_shader_src) { + GLuint vertex_shader; + GLuint fragment_shader; + GLuint program_object; + GLint linked; + + // Load the vertex/fragment shaders + vertex_shader = CreateShaderOfType(GL_VERTEX_SHADER, vertex_shader_src); + if (vertex_shader == 0) + return 0; + fragment_shader = CreateShaderOfType(GL_FRAGMENT_SHADER, fragment_shader_src); + if (fragment_shader == 0) { + glDeleteShader(vertex_shader); + return 0; + } + + // Create the program object and attach the shaders. + program_object = glCreateProgram(); + if (program_object == 0) + return 0; + glAttachShader(program_object, vertex_shader); + glAttachShader(program_object, fragment_shader); + + // Link the program + glLinkProgram(program_object); + + // Check the link status + glGetProgramiv(program_object, GL_LINK_STATUS, &linked); + if (linked == 0) { + GLint info_len = 0; + glGetProgramiv(program_object, GL_INFO_LOG_LENGTH, &info_len); + if (info_len > 1) { + char* info_log = reinterpret_cast(malloc(info_len)); + glGetProgramInfoLog(program_object, info_len, NULL, info_log); + // TODO(dspringer): We could really use a logging API. + printf("Error linking program:\n%s\n", info_log); + free(info_log); + } + glDeleteProgram(program_object); + return 0; + } + + // Delete these here because they are attached to the program object. + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + return program_object; +} + +} // namespace shader_util diff --git a/Demos/NativeClient/shader_util.h b/Demos/NativeClient/shader_util.h new file mode 100644 index 0000000..635b16b --- /dev/null +++ b/Demos/NativeClient/shader_util.h @@ -0,0 +1,29 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Some simple helper functions that load shaders and create program objects. + +#ifndef EXAMPLES_TUMBLER_SHADER_UTIL_H_ +#define EXAMPLES_TUMBLER_SHADER_UTIL_H_ + +#include + +namespace shader_util { + +// Load and compile a shader. |type| can be one of GL_VERTEX_SHADER or +// GL_FRAGMENT_SHADER. Returns a non-0 value representing the compiled +// shader on success, 0 on failure. The caller is responsible for deleting +// the returned shader using glDeleteShader(). +GLuint CreateShaderOfType(GLenum type, const char *shader_src); + +// Load and compile the vertex and fragment shaders, then link these together +// into a complete program. Returns a non-0 value representing the program on, +// success or 0 on failure. The caller is responsible for deleting the +// returned program using glDeleteProgram(). +GLuint CreateProgramFromVertexAndFragmentShaders( + const char *vertex_shader_src, const char *fragment_shader_src); + +} // namespace shader_util + +#endif // EXAMPLES_TUMBLER_SHADER_UTIL_H_ diff --git a/Demos/NativeClient/transforms.cc b/Demos/NativeClient/transforms.cc new file mode 100644 index 0000000..10ab16c --- /dev/null +++ b/Demos/NativeClient/transforms.cc @@ -0,0 +1,116 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "transforms.h" + +#include +#include +#include + +namespace transform_4x4 { + +static const GLfloat kPI = 3.1415926535897932384626433832795f; + +void Translate(GLfloat* m, GLfloat tx, GLfloat ty, GLfloat tz) { + m[12] += (m[0] * tx + m[4] * ty + m[8] * tz); + m[13] += (m[1] * tx + m[5] * ty + m[9] * tz); + m[14] += (m[2] * tx + m[6] * ty + m[10] * tz); + m[15] += (m[3] * tx + m[7] * ty + m[11] * tz); +} + +void Frustum(GLfloat* m, + GLfloat left, + GLfloat right, + GLfloat bottom, + GLfloat top, + GLfloat near_z, + GLfloat far_z) { + GLfloat delta_x = right - left; + GLfloat delta_y = top - bottom; + GLfloat delta_z = far_z - near_z; + GLfloat frustum[16]; + + if ((near_z <= 0.0f) || (far_z <= 0.0f) || + (delta_x <= 0.0f) || (delta_y <= 0.0f) || (delta_z <= 0.0f)) + return; + + frustum[0] = 2.0f * near_z / delta_x; + frustum[1] = frustum[2] = frustum[3] = 0.0f; + + frustum[5] = 2.0f * near_z / delta_y; + frustum[4] = frustum[6] = frustum[7] = 0.0f; + + frustum[8] = (right + left) / delta_x; + frustum[9] = (top + bottom) / delta_y; + frustum[10] = -(near_z + far_z) / delta_z; + frustum[11] = -1.0f; + + frustum[14] = -2.0f * near_z * far_z / delta_z; + frustum[12] = frustum[13] = frustum[15] = 0.0f; + + transform_4x4::Multiply(m, frustum, m); +} + + +void Perspective(GLfloat* m, + GLfloat fovy, + GLfloat aspect, + GLfloat near_z, + GLfloat far_z) { + GLfloat frustum_w, frustum_h; + + frustum_h = tanf((fovy * 0.5f) / 180.0f * kPI) * near_z; + frustum_w = frustum_h * aspect; + transform_4x4::Frustum(m, -frustum_w, frustum_w, -frustum_h, frustum_h, + near_z, far_z); +} + +void Multiply(GLfloat *m, GLfloat *a, GLfloat* b) { + GLfloat tmp[16]; + // tmp = a . b + GLfloat a0, a1, a2, a3; + a0 = a[0]; + a1 = a[1]; + a2 = a[2]; + a3 = a[3]; + tmp[0] = a0 * b[0] + a1 * b[4] + a2 * b[8] + a3 * b[12]; + tmp[1] = a0 * b[1] + a1 * b[5] + a2 * b[9] + a3 * b[13]; + tmp[2] = a0 * b[2] + a1 * b[6] + a2 * b[10] + a3 * b[14]; + tmp[3] = a0 * b[3] + a1 * b[7] + a2 * b[11] + a3 * b[15]; + + a0 = a[4]; + a1 = a[5]; + a2 = a[6]; + a3 = a[7]; + tmp[4] = a0 * b[0] + a1 * b[4] + a2 * b[8] + a3 * b[12]; + tmp[5] = a0 * b[1] + a1 * b[5] + a2 * b[9] + a3 * b[13]; + tmp[6] = a0 * b[2] + a1 * b[6] + a2 * b[10] + a3 * b[14]; + tmp[7] = a0 * b[3] + a1 * b[7] + a2 * b[11] + a3 * b[15]; + + a0 = a[8]; + a1 = a[9]; + a2 = a[10]; + a3 = a[11]; + tmp[8] = a0 * b[0] + a1 * b[4] + a2 * b[8] + a3 * b[12]; + tmp[9] = a0 * b[1] + a1 * b[5] + a2 * b[9] + a3 * b[13]; + tmp[10] = a0 * b[2] + a1 * b[6] + a2 * b[10] + a3 * b[14]; + tmp[11] = a0 * b[3] + a1 * b[7] + a2 * b[11] + a3 * b[15]; + + a0 = a[12]; + a1 = a[13]; + a2 = a[14]; + a3 = a[15]; + tmp[12] = a0 * b[0] + a1 * b[4] + a2 * b[8] + a3 * b[12]; + tmp[13] = a0 * b[1] + a1 * b[5] + a2 * b[9] + a3 * b[13]; + tmp[14] = a0 * b[2] + a1 * b[6] + a2 * b[10] + a3 * b[14]; + tmp[15] = a0 * b[3] + a1 * b[7] + a2 * b[11] + a3 * b[15]; + memcpy(m, tmp, sizeof(GLfloat) * 4 * 4); +} + +void LoadIdentity(GLfloat* m) { + memset(m, 0, sizeof(GLfloat) * 4 * 4); + m[0] = m[5] = m[10] = m[15] = 1.0f; +} + +} // namespace transform_4x4 diff --git a/Demos/NativeClient/transforms.h b/Demos/NativeClient/transforms.h new file mode 100644 index 0000000..5ac3d6e --- /dev/null +++ b/Demos/NativeClient/transforms.h @@ -0,0 +1,45 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXAMPLES_TUMBLER_TRANSFORMS_H_ +#define EXAMPLES_TUMBLER_TRANSFORMS_H_ + +#include + +// A very simple set of 4x4 matrix routines. In all these routines, the input +// matrix is assumed to be a 4x4 of GLfloats. + +namespace transform_4x4 { + +// Pre-multply |m| with a projection transformation 4x4 matrix from a +// truncated pyramid viewing frustum. +void Frustum(GLfloat* m, + GLfloat left, + GLfloat right, + GLfloat bottom, + GLfloat top, + GLfloat near_z, + GLfloat far_z); + +// Replace |m| with the 4x4 identity matrix. +void LoadIdentity(GLfloat* m); + +// |m| <- |a| . |b|. |m| can point at the same memory as either |a| or |b|. +void Multiply(GLfloat *m, GLfloat *a, GLfloat* b); + +// Pre-multiply |m| with a single-point perspective matrix based on the viewing +// frustum whose view angle is |fovy|. +void Perspective(GLfloat* m, + GLfloat fovy, + GLfloat aspect, + GLfloat near_z, + GLfloat far_z); + +// Pre-multiply |m| with a matrix that represents a translation by |tx|, |ty|, +// |tz|. +void Translate(GLfloat* m, GLfloat tx, GLfloat ty, GLfloat tz); +} // namespace transform_4x4 + +#endif // EXAMPLES_TUMBLER_TRANSFORMS_H_ + diff --git a/Demos/NativeClient/tumbler.cc b/Demos/NativeClient/tumbler.cc new file mode 100644 index 0000000..1beecd3 --- /dev/null +++ b/Demos/NativeClient/tumbler.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "tumbler.h" + +#include +#include +#include +#include + +#include "cube.h" +#include "opengl_context.h" +#include "scripting_bridge.h" +#include "ppapi/cpp/rect.h" +#include "ppapi/cpp/size.h" +#include "ppapi/cpp/var.h" + +namespace { +const size_t kQuaternionElementCount = 4; +const char* const kArrayStartCharacter = "["; +const char* const kArrayEndCharacter = "]"; +const char* const kArrayDelimiter = ","; + +// Return the value of parameter named |param_name| from |parameters|. If +// |param_name| doesn't exist, then return an empty string. +std::string GetParameterNamed( + const std::string& param_name, + const tumbler::MethodParameter& parameters) { + tumbler::MethodParameter::const_iterator i = + parameters.find(param_name); + if (i == parameters.end()) { + return ""; + } + return i->second; +} + +// Convert the JSON string |array| into a vector of floats. |array| is +// expected to be a string bounded by '[' and ']', and a comma-delimited list +// of numbers. Any errors result in the return of an empty array. +std::vector CreateArrayFromJSON(const std::string& json_array) { + std::vector float_array; + size_t array_start_pos = json_array.find_first_of(kArrayStartCharacter); + size_t array_end_pos = json_array.find_last_of(kArrayEndCharacter); + if (array_start_pos == std::string::npos || + array_end_pos == std::string::npos) + return float_array; // Malformed JSON: missing '[' or ']'. + // Pull out the array elements. + size_t token_pos = array_start_pos + 1; + while (token_pos < array_end_pos) { + float_array.push_back(strtof(json_array.data() + token_pos, NULL)); + size_t delim_pos = json_array.find_first_of(kArrayDelimiter, token_pos); + if (delim_pos == std::string::npos) + break; + token_pos = delim_pos + 1; + } + return float_array; +} +} // namespace + +namespace tumbler { + +Tumbler::Tumbler(PP_Instance instance) + : pp::Instance(instance), + cube_(NULL) { +} + +Tumbler::~Tumbler() { + // Destroy the cube view while GL context is current. + opengl_context_->MakeContextCurrent(this); + delete cube_; +} + +bool Tumbler::Init(uint32_t /* argc */, + const char* /* argn */[], + const char* /* argv */[]) { + // Add all the methods to the scripting bridge. + ScriptingBridge::SharedMethodCallbackExecutor set_orientation_method( + new tumbler::MethodCallback( + this, &Tumbler::SetCameraOrientation)); + scripting_bridge_.AddMethodNamed("setCameraOrientation", + set_orientation_method); + return true; +} + +void Tumbler::HandleMessage(const pp::Var& message) { + if (!message.is_string()) + return; + scripting_bridge_.InvokeMethod(message.AsString()); +} + +void Tumbler::DidChangeView(const pp::Rect& position, const pp::Rect& clip) { + int cube_width = cube_ ? cube_->width() : 0; + int cube_height = cube_ ? cube_->height() : 0; + if (position.size().width() == cube_width && + position.size().height() == cube_height) + return; // Size didn't change, no need to update anything. + + if (opengl_context_ == NULL) + opengl_context_.reset(new OpenGLContext(this)); + opengl_context_->InvalidateContext(this); + if (!opengl_context_->MakeContextCurrent(this)) + return; + if (cube_ == NULL) { + cube_ = new Cube(opengl_context_); + cube_->PrepareOpenGL(); + } + cube_->Resize(position.size().width(), position.size().height()); + DrawSelf(); +} + +void Tumbler::DrawSelf() { + if (cube_ == NULL || opengl_context_ == NULL) + return; + opengl_context_->MakeContextCurrent(this); + cube_->Draw(); + opengl_context_->FlushContext(); +} + +void Tumbler::SetCameraOrientation( + const tumbler::ScriptingBridge& bridge, + const tumbler::MethodParameter& parameters) { + // |parameters| is expected to contain one object named "orientation", whose + // value is a JSON string that represents an array of four floats. + if (parameters.size() != 1 || cube_ == NULL) + return; + std::string orientation_desc = GetParameterNamed("orientation", parameters); + std::vector orientation = CreateArrayFromJSON(orientation_desc); + if (orientation.size() != kQuaternionElementCount) { + return; + } + cube_->SetOrientation(orientation); + DrawSelf(); +} +} // namespace tumbler + diff --git a/Demos/NativeClient/tumbler.h b/Demos/NativeClient/tumbler.h new file mode 100644 index 0000000..e29d353 --- /dev/null +++ b/Demos/NativeClient/tumbler.h @@ -0,0 +1,64 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXAMPLES_TUMBLER_TUMBLER_H_ +#define EXAMPLES_TUMBLER_TUMBLER_H_ + +#include +#include +#include + +#include "cube.h" +#include "opengl_context.h" +#include "opengl_context_ptrs.h" +#include "scripting_bridge.h" +#include "ppapi/cpp/instance.h" + +namespace tumbler { + +class Tumbler : public pp::Instance { + public: + explicit Tumbler(PP_Instance instance); + + // The dtor makes the 3D context current before deleting the cube view, then + // destroys the 3D context both in the module and in the browser. + virtual ~Tumbler(); + + // Called by the browser when the NaCl module is loaded and all ready to go. + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); + + // Called whenever the in-browser window changes size. + virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip); + + // Called by the browser to handle the postMessage() call in Javascript. + virtual void HandleMessage(const pp::Var& message); + + // Bind and publish the module's methods to JavaScript. + void InitializeMethods(ScriptingBridge* bridge); + + // Set the camera orientation to the quaternion in |args[0]|. |args| must + // have length at least 1; the first element is expeted to be an Array + // object containing 4 floating point number elements (the quaternion). + // This method is bound to the JavaScript "setCameraOrientation" method and + // is called like this: + // module.setCameraOrientation([0.0, 1.0, 0.0, 0.0]); + void SetCameraOrientation( + const tumbler::ScriptingBridge& bridge, + const tumbler::MethodParameter& parameters); + + // Called to draw the contents of the module's browser area. + void DrawSelf(); + + private: + // Browser connectivity and scripting support. + ScriptingBridge scripting_bridge_; + + SharedOpenGLContext opengl_context_; + // Wouldn't it be awesome if we had boost::scoped_ptr<>? + Cube* cube_; +}; + +} // namespace tumbler + +#endif // EXAMPLES_TUMBLER_TUMBLER_H_ diff --git a/Demos/NativeClient/tumbler_module.cc b/Demos/NativeClient/tumbler_module.cc new file mode 100644 index 0000000..e58d73e --- /dev/null +++ b/Demos/NativeClient/tumbler_module.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2011 The Native Client Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "tumbler.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/gles2/gl2ext_ppapi.h" + +/// The Module class. The browser calls the CreateInstance() method to create +/// an instance of your NaCl module on the web page. The browser creates a new +/// instance for each tag with type="application/x-nacl". +class TumberModule : public pp::Module { + public: + TumberModule() : pp::Module() {} + virtual ~TumberModule() { + glTerminatePPAPI(); + } + + /// Called by the browser when the module is first loaded and ready to run. + /// This is called once per module, not once per instance of the module on + /// the page. + virtual bool Init() { + return glInitializePPAPI(get_browser_interface()) == GL_TRUE; + } + + /// Create and return a Tumbler instance object. + /// @param[in] instance The browser-side instance. + /// @return the plugin-side instance. + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new tumbler::Tumbler(instance); + } +}; + +namespace pp { +/// Factory function called by the browser when the module is first loaded. +/// The browser keeps a singleton of this module. It calls the +/// CreateInstance() method on the object you return to make instances. There +/// is one instance per tag on the page. This is the main binding +/// point for your NaCl module with the browser. +Module* CreateModule() { + return new TumberModule(); +} +} // namespace pp + diff --git a/Demos/OpenCLClothDemo/AMD/CMakeLists.txt b/Demos/OpenCLClothDemo/AMD/CMakeLists.txt new file mode 100644 index 0000000..cd73354 --- /dev/null +++ b/Demos/OpenCLClothDemo/AMD/CMakeLists.txt @@ -0,0 +1,86 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${AMD_OPENCL_INCLUDES} +) + +ADD_DEFINITIONS(-DUSE_AMD_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_AMD) + +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + +IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY + ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) +ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) +ENDIF(CMAKE_CL_64) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletSoftBodySolvers_OpenCL_AMD + BulletMultiThreaded + BulletSoftBody + BulletDynamics + BulletCollision + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ${CMAKE_ATISTREAMSDK_LIBRARY} + ) + + + ADD_EXECUTABLE(AppOpenCLClothDemo_AMD + ../cl_cloth_demo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h +# ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL/GLDebugDrawer.cpp + ../gl_win.cpp + ../clstuff.cpp + + + ../clstuff.h + ../gl_win.h + ../cloth.h + + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF(WIN32) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF(WIN32) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/bullet_logo.png ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF(NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppOpenCLClothDemo_AMD pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_AMD PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_AMD PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_AMD PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/OpenCLClothDemo/AMD/premake4.lua b/Demos/OpenCLClothDemo/AMD/premake4.lua new file mode 100644 index 0000000..6d78362 --- /dev/null +++ b/Demos/OpenCLClothDemo/AMD/premake4.lua @@ -0,0 +1,67 @@ + + hasCL = findOpenCL_AMD() + + if (hasCL) then + + project "AppOpenCLClothDemo_AMD" + + defines { "USE_AMD_OPENCL","CL_PLATFORM_AMD"} + + initOpenCL_AMD() + + language "C++" + + kind "ConsoleApp" + targetdir "../../.." + + libdirs {"../../../Glut"} + + links { + "LinearMath", + "BulletCollision", + "BulletDynamics", + "BulletSoftBody", + "BulletSoftBodySolvers_OpenCL_AMD", + "opengl32" + } + + configuration { "Windows" } + defines { "GLEW_STATIC"} + + configuration "x64" + links { + "glut64", + "glew64s" + } + configuration "x32" + links { + "glut32", + "glew32s" + } + + configuration{} + + + includedirs { + "../../../src", + "../../../Glut", + "../../SharedOpenCL", + "../../OpenGL" + } + + files { + "../cl_cloth_demo.cpp", + "../../SharedOpenCL/btOpenCLUtils.cpp", + "../../SharedOpenCL/btOpenCLUtils.h", + "../../SharedOpenCL/btOpenCLInclude.h", + "../../OpenGL/GLDebugDrawer.cpp", + "../../OpenGL/stb_image.cpp", + "../../OpenGL/stb_image.h", + "../gl_win.cpp", + "../clstuff.cpp", + "../clstuff.h", + "../gl_win.h", + "../cloth.h" + } + + end \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/Apple/CMakeLists.txt b/Demos/OpenCLClothDemo/Apple/CMakeLists.txt new file mode 100644 index 0000000..18a10d4 --- /dev/null +++ b/Demos/OpenCLClothDemo/Apple/CMakeLists.txt @@ -0,0 +1,55 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + + +IF (APPLE) + FIND_LIBRARY(OPENCL_LIBRARY OpenCL DOC "OpenCL lib for OSX") + FIND_PATH(OPENCL_INCLUDE_DIR OpenCL/cl.h DOC "Include for OpenCL on OSX") +ENDIF (APPLE) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletSoftBodySolvers_OpenCL_Apple + BulletMultiThreaded + BulletSoftBody + BulletDynamics + BulletCollision + LinearMath + ${OPENCL_LIBRARY} + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ) + + + ADD_EXECUTABLE(AppOpenCLClothDemo_Apple + ../cl_cloth_demo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + ../gl_win.cpp + ../clstuff.cpp + ../clstuff.h + ../gl_win.h + + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + + +ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_Apple POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/bullet_logo.png ${CMAKE_CURRENT_BINARY_DIR} + ) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppOpenCLClothDemo_Apple pthread) +ENDIF(UNIX) + diff --git a/Demos/OpenCLClothDemo/CLClothDemo.sln b/Demos/OpenCLClothDemo/CLClothDemo.sln new file mode 100644 index 0000000..48af26c --- /dev/null +++ b/Demos/OpenCLClothDemo/CLClothDemo.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CLClothDemo", "CLClothDemo.vcproj", "{A61906AF-B5DE-454E-99F6-B653C250D221}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A61906AF-B5DE-454E-99F6-B653C250D221}.Debug|Win32.ActiveCfg = Debug|Win32 + {A61906AF-B5DE-454E-99F6-B653C250D221}.Debug|Win32.Build.0 = Debug|Win32 + {A61906AF-B5DE-454E-99F6-B653C250D221}.Release|Win32.ActiveCfg = Release|Win32 + {A61906AF-B5DE-454E-99F6-B653C250D221}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Demos/OpenCLClothDemo/CLClothDemo.vcproj b/Demos/OpenCLClothDemo/CLClothDemo.vcproj new file mode 100644 index 0000000..1023daf --- /dev/null +++ b/Demos/OpenCLClothDemo/CLClothDemo.vcproj @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demos/OpenCLClothDemo/CMakeLists.txt b/Demos/OpenCLClothDemo/CMakeLists.txt new file mode 100644 index 0000000..eaaaeaa --- /dev/null +++ b/Demos/OpenCLClothDemo/CMakeLists.txt @@ -0,0 +1,17 @@ +SUBDIRS( MiniCL ) + +IF(BUILD_INTEL_OPENCL_DEMOS) + SUBDIRS(Intel) +ENDIF() + +IF(BUILD_AMD_OPENCL_DEMOS) + SUBDIRS(AMD) +ENDIF() + +IF(BUILD_NVIDIA_OPENCL_DEMOS) + SUBDIRS(NVidia) +ENDIF() + +IF(APPLE) + SUBDIRS(Apple) +ENDIF() diff --git a/Demos/OpenCLClothDemo/Intel/CMakeLists.txt b/Demos/OpenCLClothDemo/Intel/CMakeLists.txt new file mode 100644 index 0000000..ff8d4b2 --- /dev/null +++ b/Demos/OpenCLClothDemo/Intel/CMakeLists.txt @@ -0,0 +1,83 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${INTEL_OPENCL_INCLUDES} +) + +ADD_DEFINITIONS(-DUSE_INTEL_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_INTEL) +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + +IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY + ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) +ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) +ENDIF(CMAKE_CL_64) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletSoftBodySolvers_OpenCL_Intel + BulletMultiThreaded + BulletSoftBody + BulletDynamics + BulletCollision + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ${INTEL_OPENCL_LIBRARIES} + ) + + + ADD_EXECUTABLE(AppOpenCLClothDemo_Intel + ../cl_cloth_demo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h +# ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL/GLDebugDrawer.cpp + ../gl_win.cpp + ../clstuff.cpp + ../clstuff.h + ../gl_win.h + ../cloth.h + + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF(WIN32) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_Intel POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_Intel POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF(WIN32) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_Intel POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/bullet_logo.png ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF(NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppOpenCLClothDemo_Intel pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_Intel PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_Intel PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_Intel PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/OpenCLClothDemo/Intel/premake4.lua b/Demos/OpenCLClothDemo/Intel/premake4.lua new file mode 100644 index 0000000..930f8e7 --- /dev/null +++ b/Demos/OpenCLClothDemo/Intel/premake4.lua @@ -0,0 +1,68 @@ + + hasCL = findOpenCL_Intel() + + if (hasCL) then + + project "AppOpenCLClothDemo_Intel" + + defines { "USE_INTEL_OPENCL","CL_PLATFORM_INTEL"} + + initOpenCL_Intel() + + language "C++" + + kind "ConsoleApp" + targetdir "../../.." + + libdirs {"../../../Glut"} + + links { + "LinearMath", + "BulletCollision", + "BulletDynamics", + "BulletSoftBody", + "BulletSoftBodySolvers_OpenCL_Intel", + "opengl32" + } + + configuration { "Windows" } + defines { "GLEW_STATIC"} + + + configuration "x64" + links { + "glut64", + "glew64s" + } + configuration "x32" + links { + "glut32", + "glew32s" + } + + configuration{} + + + includedirs { + "../../../src", + "../../../Glut", + "../../SharedOpenCL", + "../../OpenGL" + } + + files { + "../cl_cloth_demo.cpp", + "../../SharedOpenCL/btOpenCLUtils.cpp", + "../../SharedOpenCL/btOpenCLUtils.h", + "../../SharedOpenCL/btOpenCLInclude.h", + "../../OpenGL/GLDebugDrawer.cpp", + "../../OpenGL/stb_image.cpp", + "../../OpenGL/stb_image.h", + "../gl_win.cpp", + "../clstuff.cpp", + "../clstuff.h", + "../gl_win.h", + "../cloth.h" + } + + end \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/MiniCL/CMakeLists.txt b/Demos/OpenCLClothDemo/MiniCL/CMakeLists.txt new file mode 100644 index 0000000..608b16e --- /dev/null +++ b/Demos/OpenCLClothDemo/MiniCL/CMakeLists.txt @@ -0,0 +1,88 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +ADD_DEFINITIONS(-DUSE_MINICL) + +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + +IF (WIN32) + IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY + ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) + ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) + ENDIF(CMAKE_CL_64) +ENDIF() + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletSoftBodySolvers_OpenCL_Mini + MiniCL + BulletMultiThreaded + BulletSoftBody + BulletDynamics + BulletCollision + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + + ) + + + ADD_EXECUTABLE(AppOpenCLClothDemo_Mini + ../cl_cloth_demo.cpp + ../gl_win.cpp + ../clstuff.cpp + ../clstuff.h + ../gl_win.h + ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/MiniCLTaskWrap.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_Mini POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_Mini POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + +IF(NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_Mini POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/bullet_logo.png ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF() +IF (UNIX) + TARGET_LINK_LIBRARIES(AppOpenCLClothDemo_Mini pthread) +ENDIF(UNIX) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_Mini PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_Mini PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_Mini PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/NVidia/CMakeLists.txt b/Demos/OpenCLClothDemo/NVidia/CMakeLists.txt new file mode 100644 index 0000000..fab2f0b --- /dev/null +++ b/Demos/OpenCLClothDemo/NVidia/CMakeLists.txt @@ -0,0 +1,86 @@ + + +ADD_DEFINITIONS(-DUSE_NVIDIA_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_NVIDIA) + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${NVIDIA_OPENCL_INCLUDES} +) + +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + + +IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY + ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) +ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) +ENDIF(CMAKE_CL_64) + + +IF (USE_GLUT) + + LINK_LIBRARIES( + OpenGLSupport + BulletSoftBodySolvers_OpenCL_NVidia + BulletMultiThreaded + BulletSoftBody + BulletDynamics + BulletCollision + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ${NVIDIA_OPENCL_LIBRARIES} + ) + + ADD_EXECUTABLE(AppOpenCLClothDemo_NVidia + ../cl_cloth_demo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + ../gl_win.cpp + ../clstuff.cpp + ../clstuff.h + ../gl_win.h + + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_NVidia POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_NVidia POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) +IF(NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppOpenCLClothDemo_NVidia POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/bullet_logo.png ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF() +IF (UNIX) + TARGET_LINK_LIBRARIES(AppOpenCLClothDemo_NVidia pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_NVidia PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_NVidia PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppOpenCLClothDemo_NVidia PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/OpenCLClothDemo/NVidia/premake4.lua b/Demos/OpenCLClothDemo/NVidia/premake4.lua new file mode 100644 index 0000000..00ae412 --- /dev/null +++ b/Demos/OpenCLClothDemo/NVidia/premake4.lua @@ -0,0 +1,68 @@ + + hasCL = findOpenCL_NVIDIA() + + if (hasCL) then + + project "AppOpenCLClothDemo_NVIDIA" + + defines { "USE_NVIDIA_OPENCL","CL_PLATFORM_NVIDIA"} + + initOpenCL_NVIDIA() + + language "C++" + + kind "ConsoleApp" + targetdir "../../.." + + libdirs {"../../../Glut"} + + links { + "LinearMath", + "BulletCollision", + "BulletDynamics", + "BulletSoftBody", + "BulletSoftBodySolvers_OpenCL_NVIDIA", + "opengl32" + } + + configuration { "Windows" } + defines { "GLEW_STATIC"} + + + configuration "x64" + links { + "glut64", + "glew64s" + } + configuration "x32" + links { + "glut32", + "glew32s" + } + + configuration{} + + + includedirs { + "../../../src", + "../../../Glut", + "../../SharedOpenCL", + "../../OpenGL" + } + + files { + "../cl_cloth_demo.cpp", + "../../SharedOpenCL/btOpenCLUtils.cpp", + "../../SharedOpenCL/btOpenCLUtils.h", + "../../SharedOpenCL/btOpenCLInclude.h", + "../../OpenGL/GLDebugDrawer.cpp", + "../../OpenGL/stb_image.cpp", + "../../OpenGL/stb_image.h", + "../gl_win.cpp", + "../clstuff.cpp", + "../clstuff.h", + "../gl_win.h", + "../cloth.h" + } + + end \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/btOpenCLSupport.h b/Demos/OpenCLClothDemo/btOpenCLSupport.h new file mode 100644 index 0000000..5b03e14 --- /dev/null +++ b/Demos/OpenCLClothDemo/btOpenCLSupport.h @@ -0,0 +1,84 @@ +#ifndef BT_OPENCL_SUPPORT_HPP +#define BT_OPENCL_SUPPORT_HPP + +// OpenCL support +#include + +namespace BTAcceleratedSoftBody +{ + class OpenCLSupportHelper + { + private: + cl::Context m_context; + std::vector m_devices; + cl::CommandQueue m_queue; + public: + OpenCLSupportHelper() + { + } + + virtual ~OpenCLSupportHelper() + { + } + + cl::Device getDevice() + { + return m_devices[0]; + } + + cl::CommandQueue getCommandQueue() + { + return m_queue; + } + + cl::Context getContext() + { + return m_context; + } + + bool InitOpenCLDevice() + { + cl_int err; + + std::vector platforms; + err = cl::Platform::get(&platforms); + checkErr(platforms.size() != 0 ? CL_SUCCESS : -1, "Platform::get()"); + + std::string platformVendor; + platforms[0].getInfo(CL_PLATFORM_VENDOR, &platformVendor); + //std::cout << "Platform is by: " << platformVendor << "\n"; + + intptr_t properties[] = { + CL_CONTEXT_PLATFORM, (intptr_t)platforms[0](), + 0, 0 + }; + m_context = cl::Context( + CL_DEVICE_TYPE_GPU, + properties, + NULL, + NULL, + &err); + + if (err != CL_SUCCESS) + { + btAssert( "Context::Context()" ); + } + + m_devices = m_context.getInfo(); + if( m_devices.size() <= 0 ) + { + btAssert( "devices.size() > 0" ); + } + + m_queue = cl::CommandQueue(m_context, m_devices[0], 0, &err); + if (err != CL_SUCCESS) + { + btAssert( "CommandQueue::CommandQueue()"); + } + } + }; + + +} // namespace BTAcceleratedSoftBody + +#endif // #ifndef BT_OPENCL_SUPPORT_HPP \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/cl_cloth_demo.cpp b/Demos/OpenCLClothDemo/cl_cloth_demo.cpp new file mode 100644 index 0000000..9031279 --- /dev/null +++ b/Demos/OpenCLClothDemo/cl_cloth_demo.cpp @@ -0,0 +1,614 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2008 Advanced Micro Devices + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifdef _WIN32 +#include +#endif + + + +#ifndef USE_MINICL +#define USE_SIMDAWARE_SOLVER +#endif + +#if !defined (__APPLE__) +#define USE_GPU_SOLVER +#if defined (_WIN32) && !defined(USE_MINICL) + #define USE_GPU_COPY //only tested on Windows +#endif //_WIN32 && !USE_MINICL +#endif //!__APPLE__ + + + + + +#include "clstuff.h" +#include "gl_win.h" +#include "cloth.h" + +#include "../OpenGL/GLDebugDrawer.h" + +GLDebugDrawer debugDraw; + +const int numFlags = 5; +const int clothWidth = 40; +const int clothHeight = 60;//60; +float _windAngle = 1.0;//0.4; +float _windStrength = 0.; + + + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" +#include "BulletSoftBody/btSoftRigidDynamicsWorld.h" +#include "vectormath/vmInclude.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.h" + + +btRigidBody *capCollider; + + +using Vectormath::Aos::Vector3; + +class piece_of_cloth; +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; + +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" + +namespace Vectormath +{ + namespace Aos + { + class Transform3; + } +} + + +btAlignedObjectArray m_collisionShapes; +btBroadphaseInterface* m_broadphase; +btCollisionDispatcher* m_dispatcher; +btConstraintSolver* m_solver; +btDefaultCollisionConfiguration* m_collisionConfiguration; + +btOpenCLSoftBodySolver *g_openCLSolver = NULL; +btOpenCLSoftBodySolverSIMDAware *g_openCLSIMDSolver = NULL; + +btSoftBodySolver *g_solver = NULL; + +btSoftBodySolverOutput *g_softBodyOutput = NULL; + +btAlignedObjectArray m_flags; +btSoftRigidDynamicsWorld* m_dynamicsWorld; +btAlignedObjectArray cloths; + +extern cl_context g_cxMainContext; +extern cl_device_id g_cdDevice; +extern cl_command_queue g_cqCommandQue; + + +const float flagSpacing = 30.f; + + +// Helper to test and add links correctly. +// Records links that have already been generated +static bool testAndAddLink( btAlignedObjectArray &trianglesForLinks, btSoftBody *softBody, int triangle, int *triangleVertexIndexArray, int numVertices, int vertex0, int vertex1, int nonLinkVertex, btSoftBody::Material *structuralMaterial, bool createBendLinks, btSoftBody::Material *bendMaterial ) +{ + if( trianglesForLinks[ numVertices * vertex0 + vertex1 ] >= 0 && createBendLinks) + { + // Already have link so find other triangle and generate cross link + + int otherTriangle = trianglesForLinks[numVertices * vertex0 + vertex1]; + int otherIndices[3] = {triangleVertexIndexArray[otherTriangle * 3], triangleVertexIndexArray[otherTriangle * 3 + 1], triangleVertexIndexArray[otherTriangle * 3 + 2]}; + + int nodeA; + // Test all links of the other triangle against this link. The one that's not part of it is what we want. + if( otherIndices[0] != vertex0 && otherIndices[0] != vertex1 ) + nodeA = otherIndices[0]; + if( otherIndices[1] != vertex0 && otherIndices[1] != vertex1 ) + nodeA = otherIndices[1]; + if( otherIndices[2] != vertex0 && otherIndices[2] != vertex1 ) + nodeA = otherIndices[2]; + + softBody->appendLink( nodeA, nonLinkVertex, bendMaterial ); + } else { + // Don't yet have link so create it + softBody->appendLink( vertex0, vertex1, structuralMaterial ); + + // If we added a new link, set the triangle array + trianglesForLinks[numVertices * vertex0 + vertex1] = triangle; + trianglesForLinks[numVertices * vertex1 + vertex0] = triangle; + + } + + return true; +} + +btSoftBody *createFromIndexedMesh( btVector3 *vertexArray, int numVertices, int *triangleVertexIndexArray, int numTriangles, bool createBendLinks ) +{ + btSoftBody* softBody = new btSoftBody(&(m_dynamicsWorld->getWorldInfo()), numVertices, vertexArray, 0); + btSoftBody::Material * structuralMaterial = softBody->appendMaterial(); + btSoftBody::Material * bendMaterial; + if( createBendLinks ) + { + bendMaterial = softBody->appendMaterial(); + bendMaterial->m_kLST = 0.7; + } else { + bendMaterial = NULL; + } + structuralMaterial->m_kLST = 1.0; + + + // List of values for each link saying which triangle is associated with that link + // -1 to start. Once a value is entered we know the "other" triangle + // and can add a link across the link + btAlignedObjectArray triangleForLinks; + triangleForLinks.resize( numVertices * numVertices, -1 ); +// int numLinks = 0; + for( int triangle = 0; triangle < numTriangles; ++triangle ) + { + int index[3] = {triangleVertexIndexArray[triangle * 3], triangleVertexIndexArray[triangle * 3 + 1], triangleVertexIndexArray[triangle * 3 + 2]}; + softBody->appendFace( index[0], index[1], index[2] ); + + // Generate the structural links directly from the triangles + testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[0], index[1], index[2], structuralMaterial, createBendLinks, bendMaterial ); + testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[1], index[2], index[0], structuralMaterial, createBendLinks, bendMaterial ); + testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[2], index[0], index[1], structuralMaterial, createBendLinks, bendMaterial); + } + + return softBody; +} + +/** + * Create a sequence of flag objects and add them to the world. + */ +void createFlag( btSoftBodySolver &solver, int width, int height, btAlignedObjectArray &flags ) +{ + // First create a triangle mesh to represent a flag + + using Vectormath::Aos::Matrix3; + using Vectormath::Aos::Vector3; + + // Allocate a simple mesh consisting of a vertex array and a triangle index array + btIndexedMesh mesh; + mesh.m_numVertices = width*height; + mesh.m_numTriangles = 2*(width-1)*(height-1); + + btVector3 *vertexArray = new btVector3[mesh.m_numVertices]; + + mesh.m_vertexBase = reinterpret_cast(vertexArray); + int *triangleVertexIndexArray = new int[3*mesh.m_numTriangles]; + mesh.m_triangleIndexBase = reinterpret_cast(triangleVertexIndexArray); + mesh.m_triangleIndexStride = sizeof(int)*3; + mesh.m_vertexStride = sizeof(Vector3); + + // Generate normalised object space vertex coordinates for a rectangular flag + float zCoordinate = 0.0f; + + Matrix3 defaultScale(Vector3(5.f, 0.f, 0.f), Vector3(0.f, 20.f, 0.f), Vector3(0.f, 0.f, 1.f)); + for( int y = 0; y < height; ++y ) + { + float yCoordinate = y*2.0f/float(height) - 1.0f; + for( int x = 0; x < width; ++x ) + { + float xCoordinate = x*2.0f/float(width) - 1.0f; + + Vector3 vertex(xCoordinate, yCoordinate, zCoordinate); + Vector3 transformedVertex = defaultScale*vertex; + + vertexArray[y*width + x] = btVector3(transformedVertex.getX(), transformedVertex.getY(), transformedVertex.getZ() ); + + } + } + + // Generate vertex indices for triangles + for( int y = 0; y < (height-1); ++y ) + { + for( int x = 0; x < (width-1); ++x ) + { + // Triangle 0 + // Top left of square on mesh + { + int vertex0 = y*width + x; + int vertex1 = vertex0 + 1; + int vertex2 = vertex0 + width; + int triangleIndex = 2*y*(width-1) + 2*x; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)] = vertex0; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex+1)/sizeof(int)+1] = vertex1; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex+2)/sizeof(int)+2] = vertex2; + } + + // Triangle 1 + // Bottom right of square on mesh + { + int vertex0 = y*width + x + 1; + int vertex1 = vertex0 + width; + int vertex2 = vertex1 - 1; + int triangleIndex = 2*y*(width-1) + 2*x + 1; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)] = vertex0; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)+1] = vertex1; + triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)+2] = vertex2; + } + } + } + + + float rotateAngleRoundZ = 0.0; + float rotateAngleRoundX = 0.5; + btMatrix3x3 defaultRotate; + defaultRotate[0] = btVector3(cos(rotateAngleRoundZ), sin(rotateAngleRoundZ), 0.f); + defaultRotate[1] = btVector3(-sin(rotateAngleRoundZ), cos(rotateAngleRoundZ), 0.f); + defaultRotate[2] = btVector3(0.f, 0.f, 1.f); + btMatrix3x3 defaultRotateX; + defaultRotateX[0] = btVector3(1.f, 0.f, 0.f); + defaultRotateX[1] = btVector3( 0.f, cos(rotateAngleRoundX), sin(rotateAngleRoundX)); + defaultRotateX[2] = btVector3(0.f, -sin(rotateAngleRoundX), cos(rotateAngleRoundX)); + + btMatrix3x3 defaultRotateAndScale( (defaultRotateX*defaultRotate) ); + + + // Construct the sequence flags applying a slightly different translation to each one to arrange them + // appropriately in the scene. + for( int i = 0; i < numFlags; ++i ) + { + float zTranslate = flagSpacing * (i-numFlags/2); + + btVector3 defaultTranslate(0.f, 20.f, zTranslate); + + btTransform transform( defaultRotateAndScale, defaultTranslate ); + transform.setOrigin(defaultTranslate); + + + btSoftBody *softBody = createFromIndexedMesh( vertexArray, mesh.m_numVertices, triangleVertexIndexArray, mesh.m_numTriangles, true ); + + + for( int i = 0; i < mesh.m_numVertices; ++i ) + { + softBody->setMass(i, 10.f/mesh.m_numVertices); + } + softBody->setMass((height-1)*(width), 0.f); + softBody->setMass((height-1)*(width) + width - 1, 0.f); + softBody->setMass((height-1)*width + width/2, 0.f); + softBody->m_cfg.collisions = btSoftBody::fCollision::CL_SS+btSoftBody::fCollision::CL_RS; + + softBody->m_cfg.kLF = 0.0005f; + softBody->m_cfg.kVCF = 0.001f; + softBody->m_cfg.kDP = 0.f; + softBody->m_cfg.kDG = 0.f; + + + flags.push_back( softBody ); + + softBody->transform( transform ); + + m_dynamicsWorld->addSoftBody( softBody ); + } + + delete [] vertexArray; + delete [] triangleVertexIndexArray; +} + + +void updatePhysicsWorld() +{ + static int counter = 1; + + // Change wind velocity a bit based on a frame counter + if( (counter % 400) == 0 ) + { + _windAngle = (_windAngle + 0.05f); + if( _windAngle > (2*3.141) ) + _windAngle = 0; + + for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex ) + { + btSoftBody *cloth = 0; + + cloth = m_flags[flagIndex]; + + float localWind = _windAngle + 0.5*(((float(rand())/RAND_MAX))-0.1); + float xCoordinate = cos(localWind)*_windStrength; + float zCoordinate = sin(localWind)*_windStrength; + + cloth->setWindVelocity( btVector3(xCoordinate, 0, zCoordinate) ); + } + } + + //btVector3 origin( capCollider->getWorldTransform().getOrigin() ); + //origin.setX( origin.getX() + 0.05 ); + //capCollider->getWorldTransform().setOrigin( origin ); + + counter++; +} + +void initBullet(void) +{ + +#ifdef USE_GPU_SOLVER +#ifdef USE_SIMDAWARE_SOLVER + g_openCLSIMDSolver = new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue, g_cxMainContext); + g_solver = g_openCLSIMDSolver; +#ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputCLtoGL(g_cqCommandQue, g_cxMainContext); +#else // #ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputCLtoCPU; +#endif // #ifdef USE_GPU_COPY +#else + g_openCLSolver = new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext ); + g_solver = g_openCLSolver; +#ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputCLtoGL(g_cqCommandQue, g_cxMainContext); +#else // #ifdef USE_GPU_COPY + g_softBodyOutput = new btSoftBodySolverOutputCLtoCPU; +#endif // #ifdef USE_GPU_COPY +#endif +#else + g_openCLSolver = new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext ); + g_solver = g_openCLSolver; +#endif + + //m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_broadphase = new btDbvtBroadphase(); + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration, g_solver); + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + + + + + + + m_dynamicsWorld->getWorldInfo().air_density = (btScalar)1.2; + m_dynamicsWorld->getWorldInfo().water_density = 0; + m_dynamicsWorld->getWorldInfo().water_offset = 0; + m_dynamicsWorld->getWorldInfo().water_normal = btVector3(0,0,0); + m_dynamicsWorld->getWorldInfo().m_gravity.setValue(0,-10,0); + + + +#if 0 + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + +#endif + + #if 1 + { + btScalar mass(0.); + + //btScalar mass(1.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btCollisionShape *capsuleShape = new btCapsuleShape(5, 10); + capsuleShape->setMargin( 0.5 ); + + + + + btVector3 localInertia(0,0,0); + if (isDynamic) + capsuleShape->calculateLocalInertia(mass,localInertia); + + m_collisionShapes.push_back(capsuleShape); + btTransform capsuleTransform; + capsuleTransform.setIdentity(); +#ifdef TABLETEST + capsuleTransform.setOrigin(btVector3(0, 10, -11)); + const btScalar pi = 3.141592654; + capsuleTransform.setRotation(btQuaternion(0, 0, pi/2)); +#else + capsuleTransform.setOrigin(btVector3(0, 0, 0)); + + // const btScalar pi = 3.141592654; + //capsuleTransform.setRotation(btQuaternion(0, 0, pi/2)); + capsuleTransform.setRotation(btQuaternion(0, 0, 0)); +#endif + btDefaultMotionState* myMotionState = new btDefaultMotionState(capsuleTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,capsuleShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction( 0.8f ); + + m_dynamicsWorld->addRigidBody(body); + //cap_1.collisionShape = body; + capCollider = body; + } +#endif + + +//#ifdef USE_GPU_SOLVER + createFlag( *g_openCLSolver, clothWidth, clothHeight, m_flags ); +//#else + +//#endif + + // Create output buffer descriptions for ecah flag + // These describe where the simulation should send output data to + for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex ) + { +// m_flags[flagIndex]->setWindVelocity( Vectormath::Aos::Vector3( 0.f, 0.f, 15.f ) ); + + // In this case we have a DX11 output buffer with a vertex at index 0, 8, 16 and so on as well as a normal at 3, 11, 19 etc. + // Copies will be performed GPU-side directly into the output buffer + +#ifdef USE_GPU_COPY + GLuint targetVBO = cloths[flagIndex].getVBO(); + btOpenGLInteropVertexBufferDescriptor *vertexBufferDescriptor = new btOpenGLInteropVertexBufferDescriptor(g_cqCommandQue, g_cxMainContext, targetVBO, 0, 8, 3, 8); +#else + btCPUVertexBufferDescriptor *vertexBufferDescriptor = new btCPUVertexBufferDescriptor(reinterpret_cast< float* >(cloths[flagIndex].cpu_buffer), 0, 8, 3, 8); +#endif + cloths[flagIndex].m_vertexBufferDescriptor = vertexBufferDescriptor; + } + + + g_solver->optimize( m_dynamicsWorld->getSoftBodyArray() ); + + if (!g_solver->checkInitialized()) + { + printf("OpenCL kernel initialization ?failed\n"); + btAssert(0); + exit(0); + } + +} + + + + +btClock m_clock; + +void doFlags() +{ + //float ms = getDeltaTimeMicroseconds(); + btScalar dt = (btScalar)m_clock.getTimeMicroseconds(); + m_clock.reset(); + + ///step the simulation + if( m_dynamicsWorld ) + { + m_dynamicsWorld->stepSimulation(dt/1000000.); + + static int frameCount = 0; + frameCount++; + if (frameCount==100) + { + m_dynamicsWorld->stepSimulation(1./60.,0); + + // Option to save a .bullet file + // btDefaultSerializer* serializer = new btDefaultSerializer(); + // m_dynamicsWorld->serialize(serializer); + // FILE* file = fopen("testFile.bullet","wb"); + // fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); + // fclose(file); + + CProfileManager::dumpAll(); + } + updatePhysicsWorld(); + + //m_dynamicsWorld->setDebugDrawer(&debugDraw); + //debugDraw.setDebugMode(btIDebugDraw::DBG_DrawWireframe); + //g_solver->copyBackToSoftBodies(); + + m_dynamicsWorld->debugDrawWorld(); + + } + + + for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex ) + { + if (g_softBodyOutput) + g_softBodyOutput->copySoftBodyToVertexBuffer( m_flags[flagIndex], cloths[flagIndex].m_vertexBufferDescriptor ); + cloths[flagIndex].draw(); + } +} + + +int main(int argc, char *argv[]) +{ + + + preInitGL(argc, argv); +#ifdef _WIN32 + glewInit(); +#endif + +#ifdef USE_GPU_COPY +#ifdef _WIN32 + HGLRC glCtx = wglGetCurrentContext(); +#else //!_WIN32 + GLXContext glCtx = glXGetCurrentContext(); +#endif //!_WIN32 + HDC glDC = wglGetCurrentDC(); + + initCL(glCtx, glDC); +#else + + initCL(); + +#endif + + cloths.resize(numFlags); + + for( int flagIndex = 0; flagIndex < numFlags; ++flagIndex ) + { + cloths[flagIndex].create_buffers(clothWidth, clothHeight); + } + + initBullet(); + m_dynamicsWorld->stepSimulation(1./60.,0); + + std::string flagTexs[] = { + "bullet_logo.png", + "bullet_logo.png", + }; + int numFlagTexs = 2; + + for( int flagIndex = 0; flagIndex < numFlags; ++flagIndex ) + { + cloths[flagIndex].create_texture(flagTexs[flagIndex % numFlagTexs]); + cloths[flagIndex].x_offset = 0; + cloths[flagIndex].y_offset = 0; + cloths[flagIndex].z_offset = 0; + } + + goGL(); + + if( g_openCLSolver ) + delete g_openCLSolver; + if( g_openCLSIMDSolver ) + delete g_openCLSIMDSolver; + if( g_softBodyOutput ) + delete g_softBodyOutput; + + return 0; +} + diff --git a/Demos/OpenCLClothDemo/cloth.h b/Demos/OpenCLClothDemo/cloth.h new file mode 100644 index 0000000..e3a0216 --- /dev/null +++ b/Demos/OpenCLClothDemo/cloth.h @@ -0,0 +1,258 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2008 Advanced Micro Devices + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "gl_win.h" //for OpenGL stuff + +#include "stb_image.h" + +#include +#include +#include "LinearMath/btScalar.h" +#include + + +struct vertex_struct +{ + float pos[3]; + float normal[3]; + float texcoord[2]; + +}; + +class btVertexBufferDescriptor; + +class piece_of_cloth +{ + public: + + void destroy(void) + { + if(created) + { + if(cpu_buffer) delete [] cpu_buffer; + } + } + + piece_of_cloth() + { + created = false; + cpu_buffer = NULL; + m_vertexBufferDescriptor = NULL; +#ifdef USE_GPU_COPY + clothVBO = 0; +#endif + } + + bool created; + + vertex_struct* cpu_buffer; + unsigned int* indices; + btVertexBufferDescriptor *m_vertexBufferDescriptor; + + double x_offset, y_offset, z_offset; + + int width; + int height; + + GLuint m_texture; +#ifdef USE_GPU_COPY + + GLuint clothVBO; + + GLuint getVBO() + { + return clothVBO; + } +#endif //USE_GPU_COPY + + void draw(void) + { + glEnable(GL_TEXTURE_2D); + glBindTexture (GL_TEXTURE_2D, m_texture); + + glEnable(GL_DEPTH_TEST); + + glColor3f(1.0f, 1.0f, 1.0f); +#ifdef USE_GPU_COPY + int error = 0; + glBindBuffer(GL_ARRAY_BUFFER, clothVBO); +#ifndef USE_GPU_COPY + // Upload data to VBO + // Needed while we're not doing interop + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_struct)*width*height, &(cpu_buffer[0]), GL_DYNAMIC_DRAW); +#endif +#endif + glEnableClientState(GL_VERTEX_ARRAY); +#ifdef USE_GPU_COPY + glEnableClientState(GL_NORMAL_ARRAY); +#endif + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glBindTexture(GL_TEXTURE_2D, m_texture); +#ifdef USE_GPU_COPY + error = glGetError(); + + // VBO version + glVertexPointer( 3, GL_FLOAT, sizeof(vertex_struct), (const GLvoid *)0 ); + error = glGetError(); + glNormalPointer( GL_FLOAT, sizeof(vertex_struct), (const GLvoid *)(sizeof(float)*3) ); + error = glGetError(); + glTexCoordPointer( 2, GL_FLOAT, sizeof(vertex_struct), (const GLvoid *)(sizeof(float)*6) ); + error = glGetError(); + + +#else + glVertexPointer( 3, GL_FLOAT, sizeof(vertex_struct), reinterpret_cast< GLvoid* >(&(cpu_buffer[0].pos[0])) ); + //glNormalPointer( 3, sizeof(vertex_struct), reinterpret_cast< GLvoid* >(&(cpu_buffer[0].normal[0])) ); + glTexCoordPointer( 2, GL_FLOAT, sizeof(vertex_struct), reinterpret_cast< GLvoid* >(&(cpu_buffer[0].texcoord[0])) ); +#endif + + glDrawElements(GL_TRIANGLES, (height-1 )*(width-1)*3*2, GL_UNSIGNED_INT, indices); +// glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glBindTexture(GL_TEXTURE_2D, 0); +#ifdef USE_GPU_COPY + error = glGetError(); + glBindBuffer(GL_ARRAY_BUFFER, 0); + error = glGetError(); +#endif + + } + + void create_texture(std::string filename) + { + int width,height,n; + unsigned char *data = stbi_load(filename.c_str(), &width, &height, &n, 0); + if (!data) + { + //premake project happens to be 2 levels above the root of Bullet, so try this instead: + std::string newname = "../../"+filename; + data = stbi_load(newname.c_str(), &width, &height, &n, 0); + } + + GLubyte* image=new GLubyte[512*256*4]; + for(int y=0;y<256;++y) + { + const int t=y>>4; + GLubyte* pi=image+y*512*4; + for(int x=0;x<512;++x) + { + const int s=x>>5; + const GLubyte b=180; + GLubyte c=b+((s+t&1)&1)*(255-b); + pi[0]=pi[1]=pi[2]=c;pi[3]=1;pi+=4; + } + } + + if ( data ) + { + + for (int i=0;i + +cl_context g_cxMainContext; +cl_device_id g_cdDevice; +cl_command_queue g_cqCommandQue; + +void initCL( void* glCtx, void* glDC ) +{ + int ciErrNum = 0; + +#if defined(CL_PLATFORM_MINI_CL) + cl_device_type deviceType = CL_DEVICE_TYPE_CPU;//or use CL_DEVICE_TYPE_DEBUG to debug MiniCL +#elif defined(CL_PLATFORM_INTEL) + cl_device_type deviceType = CL_DEVICE_TYPE_CPU; +#elif defined(CL_PLATFORM_AMD) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#elif defined(CL_PLATFORM_NVIDIA) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#else +#ifdef __APPLE__ + cl_device_type deviceType = CL_DEVICE_TYPE_ALL;//GPU; +#else + cl_device_type deviceType = CL_DEVICE_TYPE_CPU;//CL_DEVICE_TYPE_ALL +#endif//__APPLE__ +#endif + + g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + + int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext); + if (!numDev) + { + btAssert(0); + exit(0);//this is just a demo, exit now + } + + g_cdDevice = btOpenCLUtils::getDevice(g_cxMainContext,0); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + btOpenCLDeviceInfo clInfo; + btOpenCLUtils::getDeviceInfo(g_cdDevice,clInfo); + btOpenCLUtils::printDeviceInfo(g_cdDevice); + + // create a command-queue + g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_cdDevice, 0, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); +} diff --git a/Demos/OpenCLClothDemo/clstuff.h b/Demos/OpenCLClothDemo/clstuff.h new file mode 100644 index 0000000..83b0bbc --- /dev/null +++ b/Demos/OpenCLClothDemo/clstuff.h @@ -0,0 +1,11 @@ +#ifndef __CLSTUFF_HDR__ +#define __CLSTUFF_HDR__ + + + + +// OpenCL initialization. +// Takes an optional GL context which, if passed, will create an interop-enabled CL context. +void initCL( void* glContext = 0, void* glDC = 0 ); + +#endif //__CLSTUFF_HDR__ \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/clstuff.hpp b/Demos/OpenCLClothDemo/clstuff.hpp new file mode 100644 index 0000000..09f6313 --- /dev/null +++ b/Demos/OpenCLClothDemo/clstuff.hpp @@ -0,0 +1,10 @@ +#ifndef __CLSTUFF_HDR__ +#define __CLSTUFF_HDR__ + + + + + +void initCL(void); + +#endif //__CLSTUFF_HDR__ \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/fragment.glsl b/Demos/OpenCLClothDemo/fragment.glsl new file mode 100644 index 0000000..6a265d3 --- /dev/null +++ b/Demos/OpenCLClothDemo/fragment.glsl @@ -0,0 +1,7 @@ +uniform sampler2D tex; + +void main() +{ + vec4 color = texture2D(tex,gl_TexCoord[0].st); + gl_FragColor = color; +} \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/gl_win.cpp b/Demos/OpenCLClothDemo/gl_win.cpp new file mode 100644 index 0000000..464fd0e --- /dev/null +++ b/Demos/OpenCLClothDemo/gl_win.cpp @@ -0,0 +1,268 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2008 Advanced Micro Devices + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "clstuff.h" +#include "gl_win.h" + +#include +#include +#include +#include + + +//#ifndef _WIN32 && !defined(__APPLE__) +//#include +//#endif //!_WIN32 + + + +//static GLuint vbo = 0; + +#ifdef _WIN32 +#include +#endif + + +static unsigned int windowWidth = 1280; +static unsigned int windowHeight = 1024; + +// mouse controls +int mouseOldX; +int mouseOldY; +int mouseButtons = 0; + +float rotateX; +float rotateY; + +float translateZ; +float translateX; +float translateY; + +static GLuint glProgram; + + +void doFlags(); + + +void render( void) +{ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); +// glDisable ( GL_CULL_FACE ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glTranslatef( translateX, translateY, translateZ ); + glRotatef( rotateX, 0.5f , 0.0f, 0.0f ); + glRotatef( rotateY, 0.0f, 0.5f, 0.0f ); + +// glDisable (GL_BLEND); + + doFlags(); + // TODO: + //glBindBuffer(GL_ARRAY_BUFFER, vbo); + //glVertexPointer(4, GL_FLOAT, 0, NULL); + //glEnableClientState(GL_VERTEX_ARRAY); + + //glDrawArrays(GL_POINTS, 0, 4*4); + +// glDisableClientState(GL_VERTEX_ARRAY); + // glBindBuffer(GL_ARRAY_BUFFER, 0); + + +// glUseProgram(0); +} + +static void initGL(void) +{ + //glClearColor( 0.05f, 0.0f, 0.1f, 0.1f ); + glClearColor( 0.0f, 0.45f, 0.45f, 1.f); + +#if 0 + GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat mat_shininess[] = { 50.0f }; + GLfloat light_position[] = { + -10.f, + 5.f, + -1.f, + 1.0f }; + + glEnable ( GL_COLOR_MATERIAL ); + glShadeModel( GL_SMOOTH ); + glEnable( GL_LINE_SMOOTH ); + + + glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular ); + glMaterialfv( GL_FRONT, GL_SHININESS, mat_shininess ); + glLightfv( GL_LIGHT0, GL_POSITION, light_position ); + + //glEnable( GL_LIGHTING ); + //glEnable( GL_LIGHT0 ); // Switch on and crashes! + glEnable( GL_DEPTH_TEST ); +#endif +#if 0 + + + glEnable ( GL_COLOR_MATERIAL ); + glShadeModel( GL_SMOOTH ); + glEnable( GL_LINE_SMOOTH ); + + glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular ); + glMaterialfv( GL_FRONT, GL_SHININESS, mat_shininess ); + glLightfv( GL_LIGHT0, GL_POSITION, light_position ); + + glEnable( GL_LIGHTING ); + glEnable( GL_LIGHT0 ); + glEnable( GL_DEPTH_TEST ); +#endif + rotateX = 0; + rotateY = 30; + translateX = 0.0f; + translateY = -30.0f; + translateZ = -120.0; +} + +void display(void) +{ + render(); + + glutSwapBuffers(); + glutPostRedisplay(); +} + +void keyboard( unsigned char key, int /*x*/, int /*y*/) +{ + switch( key) { + case('q') : +#ifdef _WIN32 + case VK_ESCAPE: +#endif //_WIN32 + exit(0); + break; + case('a'): + translateY += 0.1f; + break; + case('z'): + translateY -= 0.1f; + break; + case('d'): + translateX += 0.1f; + break; + case('s'): + translateX -= 0.1f; + break; + case('f'): + translateZ += 0.1f; + break; + case('g'): + translateZ -= 0.1f; + break; + } +} + +void mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + mouseButtons |= 1< +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#include +#else + + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#endif //_WINDOWS +#endif //APPLE + + +#include + +void goGL(void); +void preInitGL(int argc, char ** argv); + +//int getVBO( std::string, int size ); + +#endif //__GL_WIN_HDR__ diff --git a/Demos/OpenCLClothDemo/gl_win.hpp b/Demos/OpenCLClothDemo/gl_win.hpp new file mode 100644 index 0000000..e7d3f93 --- /dev/null +++ b/Demos/OpenCLClothDemo/gl_win.hpp @@ -0,0 +1,34 @@ +#ifndef __GL_WIN_HDR__ +#define __GL_WIN_HDR__ + +#ifdef _WIN32//for glut.h +#include +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#include +#else + + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#endif //_WINDOWS +#endif //APPLE + + +#include + +void goGL(void); +void preInitGL(int argc, char ** argv); + +int getVBO( std::string, int size ); + +#endif //__GL_WIN_HDR__ diff --git a/Demos/OpenCLClothDemo/shaders.cl b/Demos/OpenCLClothDemo/shaders.cl new file mode 100644 index 0000000..27e2d21 --- /dev/null +++ b/Demos/OpenCLClothDemo/shaders.cl @@ -0,0 +1,535 @@ +#pragma OPENCL EXTENSION cl_amd_printf : enable + +#define float3 float4 +#define uint3 uint4 + +#define PARTICLE_RADIUS 0.05; + +#define width 1280 +#define height 1024 + +#define B 0 +#define T height +#define L 0 +#define R width + +#define shiftNumber 4 +#define shiftMask 0xF +#define shiftValue 16.0f +#define stride 4 + +#define screenWidth1 width +#define screenHeight1 height +#define halfScreenWidth1 screenWidth1/2 +#define halfScreenHeight1 screenHeight1/2 +#define screenWidth1SubOne (screenWidth1-1) +#define screenHeight1SubOne (screenHeight1-1) +#define stride screenWidth1 +#define screenPixelNumber screenWidth1*screenHeight1 +#define depthBufferSize screenPixelNumber*depthComplexity + +#define WGS 1 + +//--------------------------------------------------------------- + +struct __VSSpriteOut +{ + float4 position; + float4 particlePosition; +}; + +typedef struct __VSSpriteout VSSpriteOut; + +struct __GSSpriteOut +{ + float4 position; + float2 textureUV; +// float4 viewSpacePosition; +// float4 particlePosition; +}; + +typedef struct __GSSpriteout GSSpriteOut; + +//------------------------------------------------------------------------------ + +__constant float4 g_positions[4] = +{ + (float4)(-1.0f, 1.0f, 0.0f, 0.0f), + (float4)( 1.0f, 1.0f, 0.0f, 0.0f), + (float4)( -1.0f, -1.0f, 0.0f, 0.0f), + (float4)( 1.0f, -1.0f, 0.0f, 0.0f) +}; + +__constant float2 g_texcoords[4] = +{ + (float2)(0.0f,0.0f), + (float2)(1.0f,0.0f), + (float2)(0.0f,1.0f), + (float2)(1.0f,1.0f) +}; + +//------------------------------------------------------------------------------ + +void copyMatrix( + float matrix[16], + __constant float matrix0[16]) +{ + uint i; + + for (i = 0; i < 16; i++) { + matrix[i] = matrix0[i]; + } +} + +void matrixMulLoopBody( + uint i, + float matrix[16], + __constant float matrix0[16], + __constant float matrix1[16]) +{ + matrix[i] = 0.0f; + matrix[i] += matrix0[(i%4) + (0*4)] * matrix1[(0) + ((i/4)*4)]; + matrix[i] += matrix0[(i%4) + (1*4)] * matrix1[(1) + ((i/4)*4)]; + matrix[i] += matrix0[(i%4) + (2*4)] * matrix1[(2) + ((i/4)*4)]; + matrix[i] += matrix0[(i%4) + (3*4)] * matrix1[(3) + ((i/4)*4)]; +} + +void matrixMul( + float matrix[16], + __constant float matrix0[16], + __constant float matrix1[16]) +{ + matrixMulLoopBody(0, matrix, matrix0, matrix1); + matrixMulLoopBody(1, matrix, matrix0, matrix1); + matrixMulLoopBody(2, matrix, matrix0, matrix1); + matrixMulLoopBody(3, matrix, matrix0, matrix1); + matrixMulLoopBody(4, matrix, matrix0, matrix1); + matrixMulLoopBody(5, matrix, matrix0, matrix1); + matrixMulLoopBody(6, matrix, matrix0, matrix1); + matrixMulLoopBody(7, matrix, matrix0, matrix1); + matrixMulLoopBody(8, matrix, matrix0, matrix1); + matrixMulLoopBody(9, matrix, matrix0, matrix1); + matrixMulLoopBody(10, matrix, matrix0, matrix1); + matrixMulLoopBody(11, matrix, matrix0, matrix1); + matrixMulLoopBody(12, matrix, matrix0, matrix1); + matrixMulLoopBody(13, matrix, matrix0, matrix1); + matrixMulLoopBody(14, matrix, matrix0, matrix1); + matrixMulLoopBody(15, matrix, matrix0, matrix1); +} + +float4 matrixVectorMul(float matrix[16], float4 vector) +{ + float4 result; + + result.x = matrix[0]*vector.x + matrix[4+0]*vector.y + matrix[8+0]*vector.z + matrix[12+0]*vector.w; + result.y = matrix[1]*vector.x + matrix[4+1]*vector.y + matrix[8+1]*vector.z + matrix[12+1]*vector.w; + result.z = matrix[2]*vector.x + matrix[4+2]*vector.y + matrix[8+2]*vector.z + matrix[12+2]*vector.w; + result.w = matrix[3]*vector.x + matrix[4+3]*vector.y + matrix[8+3]*vector.z + matrix[12+3]*vector.w; + + return result; +} + +float3 matrixVector3Mul(__constant float matrix[9], float3 vector) +{ + float3 result; + + result.x = matrix[0]*vector.x + matrix[3+0]*vector.y + matrix[6+0]*vector.z; + result.y = matrix[1]*vector.x + matrix[3+1]*vector.y + matrix[6+1]*vector.z; + result.z = matrix[2]*vector.x + matrix[3+2]*vector.y + matrix[6+2]*vector.z; + + return result; +} + +//------------------------------------------------------------------------------ + +//#define DEVICE_CPU 1 +#if defined(DEVICE_CPU) +void printMatrix(char * name, __constant float matrix[16]) +{ + printf("%s[0] = %f, %f, %f, %f\n", name, matrix[0], matrix[1], matrix[2], matrix[3]); + printf("%s[1] = %f, %f, %f, %f\n", name, matrix[4], matrix[5], matrix[6], matrix[7]); + printf("%s[2] = %f, %f, %f, %f\n", name, matrix[8], matrix[9], matrix[10], matrix[11]); + printf("%s[3] = %f, %f, %f, %f\n", name, matrix[12], matrix[13], matrix[14], matrix[15]); +} +#endif + +#if 1 +__kernel void vertexShader( + __constant float modelview[16], + __constant float projection[16], + __global float4 * inputPrimitives, + __global float4 * outputPrimitives) +{ + float matrix[16]; + float4 gl_Vertex; + float4 gl_Position; + + uint id = get_global_id(0); + + gl_Vertex = inputPrimitives[id]; + + // gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex + matrixMul(matrix, projection, modelview); + + gl_Position = matrixVectorMul(matrix, gl_Vertex); + + outputPrimitives[id] = gl_Position; +} + +#else + +__kernel void vertexShader( + __constant float modelview[16], + __constant float projection[16], + __global float4 * inputPrimitives, + __global float4 * outputPrimitives) +{ + uint id = get_global_id(0); + + outputPrimitives[id] = inputPrimitives[id]; +} + +#endif + +//----------------------------------------------------------------------------------- + +__kernel void +clearImage( + __write_only image2d_t image, + float4 color) +{ + + int2 coords = (int2)(get_global_id(0), get_global_id(1)); + write_imagef(image, coords, color); +} + +// OpenGL viewport transformation +// The site http://research.cs.queensu.ca/~jstewart/454/notes/pipeline/ +// contains a description of this process +void +viewportTransform(float4 v, __constant int4 viewport[1], float2 * output) +{ + int4 vp = viewport[0]; + *output + = 0.5f * + (float2)(v.x+1,v.y+1) * + (float2)((vp.s2-vp.s0) + vp.s0, + (vp.s3-vp.s1) + vp.s1); +} + +#define PARTICLE_WIDTH 32.0f +#define PARTICLE_HEIGHT 32.0f + +// Unoptimized triangle rasterizer function +// Details of the algorithm can be found here: +// http://www.devmaster.net/forums/showthread.php?t=1884 +// +void +rasterizerUnOpt( + __global struct __GSSpriteOut * outputPrimitives, +// __global float4 * outputPrimitives, + __constant int4 viewport[1], + __write_only image2d_t screen, + __read_only image2d_t particle, + uint v1Offset, + uint v2Offset, + uint v3Offset, + __global float4 * debugOut1) +{ + sampler_t sampler = + CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; + + uint id = get_global_id(0); + + struct __GSSpriteOut output; + float2 v1, v2, v3; + float2 uv1, uv2, uv3; + + output = outputPrimitives[id*4+v1Offset]; + uv1 = output.textureUV; + viewportTransform(output.position, viewport, &v1); + + output = outputPrimitives[id*4+v2Offset]; + uv2 = output.textureUV; + viewportTransform(output.position, viewport, &v2); + + output = outputPrimitives[id*4+v3Offset]; + uv3 = output.textureUV; + viewportTransform(output.position, viewport, &v3); + + // Bounding rectangle + int2 min_ = convert_int2(min(v1, min(v2, v3))); + int2 max_ = convert_int2(max(v1, max(v2, v3))); + + // naive bi-linear interploation for texture coords, note this is + // broken with respect to OpenGL and needs to be fixed for the + // general case. + float p1x = v2.x - v1.x; + float p1y = v2.y - v1.y; + + float p2x = v3.x - v1.x; + float p2y = v3.y - v1.y; + + // Scan through bounding rectangle + for(int y = min_.y; y < max_.y; y++) { + for(int x = min_.x; x < max_.x; x++) { + // When all half-space functions positive, pixel is in triangle + if((v1.x - v2.x) * (y - v1.y) - (v1.y - v2.y) * (x - v1.x) > 0 && + (v2.x - v3.x) * (y - v2.y) - (v2.y - v3.y) * (x - v2.x) > 0 && + (v3.x - v1.x) * (y - v3.y) - (v3.y - v1.y) * (x - v3.x) > 0) { + + float px = x - v1.x; + float py = y - v1.y; + + write_imagef( + screen, + (int2)(x,y), + // texel); + (float4)(1.0f,1.0f,1.0f,1.0f)); + } + } + } +} + +// Optimized rasterizer function +// Details of the algorithm can be found here: +// http://www.devmaster.net/forums/showthread.php?t=1884 +// +// Currently has a bug, still work in progess +__kernel void +rasterizerXX( + __global float4 * outputPrimitives, + __write_only image2d_t screen, + __global float4 * debugOut1, + __global int2 * debugOut2) +{ + uint id = get_global_id(0); + +// printf("ras\n"); + + float4 v1 = outputPrimitives[id*4+0]; + float4 v2 = outputPrimitives[id*4+1]; + float4 v3 = outputPrimitives[id*4+2]; + + float y1 = 0.5f* (v1.y+1) * (T - B) + B; + float y2 = 0.5f* (v2.y+1) * (T - B) + B; + float y3 = 0.5f* (v3.y+1) * (T - B) + B; + + float x1 = 0.5f * (v1.x+1) * (R - L) + L; + float x2 = 0.5f * (v2.x+1) * (R - L) + L; + float x3 = 0.5f * (v3.x+1) * (R - L) + L; + + const int Y1 = convert_int(shiftValue * y1); + const int Y2 = convert_int(shiftValue * y2); + const int Y3 = convert_int(shiftValue * y3); + + const int X1 = convert_int(shiftValue * x1); + const int X2 = convert_int(shiftValue * x2); + const int X3 = convert_int(shiftValue * x3); + + debugOut1[id*4+0] = v1; + debugOut1[id*4+1] = v2; + debugOut1[id*4+2] = v3; + + debugOut2[id*3+0] = (int2)(X1, Y1); + debugOut2[id*3+1] = (int2)(X2, Y2); + debugOut2[id*3+2] = (int2)(X3, Y3); + + // Deltas + const int DX12 = X1 - X2; + const int DX23 = X2 - X3; + const int DX31 = X3 - X1; + + const int DY12 = Y1 - Y2; + const int DY23 = Y2 - Y3; + const int DY31 = Y3 - Y1; + + // Fixed-point deltas + const int FDX12 = DX12 << shiftNumber; + const int FDX23 = DX23 << shiftNumber; + const int FDX31 = DX31 << shiftNumber; + + const int FDY12 = DY12 << shiftNumber; + const int FDY23 = DY23 << shiftNumber; + const int FDY31 = DY31 << shiftNumber; + + // Bounding rectangle + int minx = (min(X1, min(X2, X3)) + shiftMask) >> shiftNumber; + //minx = max(0,minx); + + int maxx = (max(X1, min(X2, X3)) + shiftMask) >> shiftNumber; + //min(maxx , screenWidth1SubOne); + + int miny = (min(Y1, min(Y2, Y3)) + shiftMask) >> shiftNumber; + //max(0,miny); + + int maxy = (max(Y1, min(Y2, Y3)) + shiftMask) >> shiftNumber; + //min(maxy , screenHeight1SubOne); + + //(char*&)colorBuffer += miny * stride; + int offset = miny * stride; + + // Half-edge constants + int C1 = DY12 * X1 - DX12 * Y1; + int C2 = DY23 * X2 - DX23 * Y2; + int C3 = DY31 * X3 - DX31 * Y3; + + // Correct for fill convention + if(DY12 < 0 || (DY12 == 0 && DX12 > 0)) C1++; + if(DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++; + if(DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++; + + int CY1 = C1 + DX12 * (miny << shiftNumber) - DY12 * (minx << shiftNumber); + int CY2 = C2 + DX23 * (miny << shiftNumber) - DY23 * (minx << shiftNumber); + int CY3 = C3 + DX31 * (miny << shiftNumber) - DY31 * (minx << shiftNumber); + + for(int y = miny; y < maxy; y++) { + int CX1 = CY1; + int CX2 = CY2; + int CX3 = CY3; + + debugOut2[id*3+0] = (int2)(minx, maxx); + + for(int x = minx; x < maxx; x++) { + debugOut2[id*3+0] = (int2)(CX1, CX2); + + if(CX1 > 0 && CX2 > 0 && CX3 > 0) { + debugOut2[id*3+0] = (int2)(1, 1); + write_imagef( + screen, + (int2)(x,y), + (float4)(1.0f,1.0f,1.0f,1.0f)); + } + + CX1 -= FDY12; + CX2 -= FDY23; + CX3 -= FDY31; + } + + CY1 += FDX12; + CY2 += FDX23; + CY3 += FDX31; + + //(char*&)colorBuffer += stride; + offset += stride; + } +} + +//------------------------------------------------------------------------------ + +void geometryShader( + __constant float modelview[16], + __constant float projection[16], + __constant float inverseView[9], + __constant int4 viewport[1], + __local struct __VSSpriteOut * vsOutputPrimitives, + __global struct __GSSpriteOut * outputPrimitives, +// __global float4 * outputPrimitives, + __write_only image2d_t screen, + __read_only image2d_t particle, + __global float4 * debugOut1, + __global int * debugOut2) +{ + float2 texcoords[4] = + { + (float2)(0.0f,0.0f), + (float2)(1.0f,0.0f), + (float2)(0.0f,1.0f), + (float2)(1.0f,1.0f) + }; + + float matrix[16]; + + uint id = get_global_id(0); + uint lid = get_local_id(0); + + float4 vsPosition = vsOutputPrimitives[lid].position; + + matrixMul(matrix, projection, modelview); + // + // Emit two new triangles + // + for (uint i = 0; i<4; i++) { + float3 position = g_positions[i] * PARTICLE_RADIUS; + position = matrixVector3Mul(inverseView, position) + vsPosition; + float3 particlePosition = + matrixVector3Mul( + inverseView, + (float4)(0.0f,0.0f,0.0f,0.0f)) + vsPosition; // world space + + // Compute view space position + position.w = 1.0f; + position = matrixVectorMul(matrix, position); + + //perspective division + position /= position.w; + + struct __GSSpriteOut output; + output.position = position; + //output.textureUV = g_texcoords[i]; + output.textureUV = texcoords[i]; + outputPrimitives[id*4+i] = output; + } + + // Render QUAD - Triangle 1 + rasterizerUnOpt( + outputPrimitives, + viewport, + screen, + particle, + 0, + 1, + 2, + debugOut1); + + // Render QUAD - Triangle 2 + rasterizerUnOpt( + outputPrimitives, + viewport, + screen, + particle, + 2, + 1, + 3, + debugOut1); +} + +__kernel void vertexShaderSprite( + __constant float modelview[16], + __constant float projection[16], + __constant float inverseView[9], + __constant int4 viewport[1], + __local struct __VSSpriteOut * vsOutputPrimitives, + __global float4 * inputPrimitives, + __global struct __GSSpriteOut * outputPrimitives, +// __global float4 * outputPrimitives, + __write_only image2d_t screen, + __read_only image2d_t particle, + __global float4 * debugOut1, + __global int * debugOut2) +{ + float matrix[16]; + + uint id = get_global_id(0); + uint lid = get_local_id(0); + + // gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex + matrixMul(matrix, projection, modelview); + + float4 position = inputPrimitives[id]; + vsOutputPrimitives[lid].position = position; + vsOutputPrimitives[lid].particlePosition = + matrixVectorMul(matrix, position); + + geometryShader( + modelview, + projection, + inverseView, + viewport, + vsOutputPrimitives, + outputPrimitives, + screen, + particle, + debugOut1, + debugOut2); +} \ No newline at end of file diff --git a/Demos/OpenCLClothDemo/vertex.glsl b/Demos/OpenCLClothDemo/vertex.glsl new file mode 100644 index 0000000..5169830 --- /dev/null +++ b/Demos/OpenCLClothDemo/vertex.glsl @@ -0,0 +1,7 @@ +void main() +{ + //gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; + + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = gl_Vertex; +} \ No newline at end of file diff --git a/Demos/OpenGL/CMakeLists.txt b/Demos/OpenGL/CMakeLists.txt new file mode 100644 index 0000000..067b099 --- /dev/null +++ b/Demos/OpenGL/CMakeLists.txt @@ -0,0 +1,67 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + + +# You shouldn't have to modify anything below this line +######################################################## + + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Extras/ConvexHull +) + + +ADD_LIBRARY(OpenGLSupport + GLDebugFont.cpp + GLDebugFont.h + GL_DialogDynamicsWorld.cpp + GL_DialogDynamicsWorld.h + GL_DialogWindow.cpp + GL_DialogWindow.h + GL_ShapeDrawer.cpp + GL_ShapeDrawer.h + GL_Simplex1to4.cpp + GL_Simplex1to4.h + GLDebugDrawer.cpp + GLDebugDrawer.h + + RenderTexture.cpp + RenderTexture.h + DemoApplication.cpp + DemoApplication.h + + GlutDemoApplication.cpp + GlutDemoApplication.h + GlutStuff.cpp + GlutStuff.h + + stb_image.cpp + stb_image.h + + Win32DemoApplication.cpp + Win32DemoApplication.h +) + + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(OpenGLSupport BulletDynamics BulletCollision ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) +ENDIF (BUILD_SHARED_LIBS) + +#INSTALL of other files requires CMake 2.6 +IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF(INSTALL_EXTRA_LIBS) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS OpenGLSupport DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS OpenGLSupport DESTINATION lib) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (INSTALL_EXTRA_LIBS) +ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) diff --git a/Demos/OpenGL/CommandLineArguments.h b/Demos/OpenGL/CommandLineArguments.h new file mode 100644 index 0000000..4c11c4b --- /dev/null +++ b/Demos/OpenGL/CommandLineArguments.h @@ -0,0 +1,112 @@ +/****************************************************************************** + * Copyright 2010 Duane Merrill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For more information, see our Google Code project site: + * http://code.google.com/p/back40computing/ + * + * Thanks! + ******************************************************************************/ + +#ifndef COMMAND_LINE_ARGS_H +#define COMMAND_LINE_ARGS_H + +/****************************************************************************** + * Command-line parsing + ******************************************************************************/ +#include +#include +#include +#include +class CommandLineArguments +{ +protected: + + std::map pairs; + +public: + + // Constructor + CommandLineArguments(int argc, char **argv) + { + using namespace std; + + for (int i = 1; i < argc; i++) + { + string arg = argv[i]; + + if ((arg[0] != '-') || (arg[1] != '-')) { + continue; + } + + string::size_type pos; + string key, val; + if ((pos = arg.find( '=')) == string::npos) { + key = string(arg, 2, arg.length() - 2); + val = ""; + } else { + key = string(arg, 2, pos - 2); + val = string(arg, pos + 1, arg.length() - 1); + } + pairs[key] = val; + } + } + + bool CheckCmdLineFlag(const char* arg_name) + { + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + return true; + } + return false; + } + + template + void GetCmdLineArgument(const char *arg_name, T &val); + + int ParsedArgc() + { + return pairs.size(); + } +}; + +template +void CommandLineArguments::GetCmdLineArgument(const char *arg_name, T &val) +{ + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + istringstream strstream(itr->second); + strstream >> val; + } +} + +template <> +void CommandLineArguments::GetCmdLineArgument(const char* arg_name, char* &val) +{ + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + + string s = itr->second; + val = (char*) malloc(sizeof(char) * (s.length() + 1)); + strcpy(val, s.c_str()); + + } else { + val = NULL; + } +} + +#endif //COMMAND_LINE_ARGS_H diff --git a/Demos/OpenGL/DebugCastResult.h b/Demos/OpenGL/DebugCastResult.h new file mode 100644 index 0000000..ee476bf --- /dev/null +++ b/Demos/OpenGL/DebugCastResult.h @@ -0,0 +1,88 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEBUG_CAST_RESULT_H +#define DEBUG_CAST_RESULT_H + +#include "BulletCollision/NarrowPhaseCollision/btConvexCast.h" +#include "LinearMath/btTransform.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" +#ifdef WIN32 +#include +#endif +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#else +#include +#endif +struct btDebugCastResult : public btConvexCast::CastResult +{ + + btTransform m_fromTrans; + const btPolyhedralConvexShape* m_shape; + btVector3 m_linVel; + btVector3 m_angVel; + GL_ShapeDrawer* m_shapeDrawer; + + btDebugCastResult(const btTransform& fromTrans,const btPolyhedralConvexShape* shape, + const btVector3& linVel,const btVector3& angVel,GL_ShapeDrawer* drawer) + :m_fromTrans(fromTrans), + m_shape(shape), + m_linVel(linVel), + m_angVel(angVel), + m_shapeDrawer(drawer) + { + } + + virtual void drawCoordSystem(const btTransform& tr) + { + btScalar m[16]; + tr.getOpenGLMatrix(m); + glPushMatrix(); + btglLoadMatrix(m); + glBegin(GL_LINES); + btglColor3(1, 0, 0); + btglVertex3(0, 0, 0); + btglVertex3(1, 0, 0); + btglColor3(0, 1, 0); + btglVertex3(0, 0, 0); + btglVertex3(0, 1, 0); + btglColor3(0, 0, 1); + btglVertex3(0, 0, 0); + btglVertex3(0, 0, 1); + glEnd(); + glPopMatrix(); + } + + virtual void DebugDraw(btScalar fraction) + { + btVector3 worldBoundsMin(-1000,-1000,-1000); + btVector3 worldBoundsMax(1000,1000,1000); + + + ATTRIBUTE_ALIGNED16(btScalar) m[16]; + btTransform hitTrans; + btTransformUtil::integrateTransform(m_fromTrans,m_linVel,m_angVel,fraction,hitTrans); + hitTrans.getOpenGLMatrix(m); + if (m_shapeDrawer) + m_shapeDrawer->drawOpenGL(m,m_shape,btVector3(1,0,0),btIDebugDraw::DBG_NoDebug,worldBoundsMin,worldBoundsMax); + } +}; + + +#endif //DEBUG_CAST_RESULT_H diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp new file mode 100644 index 0000000..65541b9 --- /dev/null +++ b/Demos/OpenGL/DemoApplication.cpp @@ -0,0 +1,1382 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "DemoApplication.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletDynamics/Dynamics/btDynamicsWorld.h" + +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"//picking +#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"//picking + +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionShapes/btUniformScalingShape.h" +#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h" +#include "GL_ShapeDrawer.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btDefaultMotionState.h" +#include "LinearMath/btSerializer.h" +#include "GLDebugFont.h" + + +extern bool gDisableDeactivation; +int numObjects = 0; +const int maxNumObjects = 16384; +btTransform startTransforms[maxNumObjects]; +btCollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes) +#define SHOW_NUM_DEEP_PENETRATIONS 1 + +extern int gNumClampedCcdMotions; + +#ifdef SHOW_NUM_DEEP_PENETRATIONS +extern int gNumDeepPenetrationChecks; + +extern int gNumSplitImpulseRecoveries; +extern int gNumGjkChecks; +extern int gNumAlignedAllocs; +extern int gNumAlignedFree; +extern int gTotalBytesAlignedAllocs; + +#endif // + + +DemoApplication::DemoApplication() +//see btIDebugDraw.h for modes +: +m_dynamicsWorld(0), +m_pickConstraint(0), +m_shootBoxShape(0), +m_cameraDistance(15.0), +m_debugMode(0), +m_ele(20.f), +m_azi(0.f), +m_cameraPosition(0.f,0.f,0.f), +m_cameraTargetPosition(0.f,0.f,0.f), +m_mouseOldX(0), +m_mouseOldY(0), +m_mouseButtons(0), +m_modifierKeys(0), +m_scaleBottom(0.5f), +m_scaleFactor(2.f), +m_cameraUp(0,1,0), +m_forwardAxis(2), +m_zoomStepSize(0.4), +m_glutScreenWidth(0), +m_glutScreenHeight(0), +m_frustumZNear(1.f), +m_frustumZFar(10000.f), +m_ortho(0), +m_ShootBoxInitialSpeed(40.f), +m_stepping(true), +m_singleStep(false), +m_idle(false), + +m_enableshadows(false), +m_sundirection(btVector3(1,-2,1)*1000), +m_defaultContactProcessingThreshold(BT_LARGE_FLOAT) +{ +#ifndef BT_NO_PROFILE + m_profileIterator = CProfileManager::Get_Iterator(); +#endif //BT_NO_PROFILE + + m_shapeDrawer = new GL_ShapeDrawer (); + m_shapeDrawer->enableTexture(true); + m_enableshadows = false; +} + + + +DemoApplication::~DemoApplication() +{ +#ifndef BT_NO_PROFILE + CProfileManager::Release_Iterator(m_profileIterator); +#endif //BT_NO_PROFILE + + if (m_shootBoxShape) + delete m_shootBoxShape; + + if (m_shapeDrawer) + delete m_shapeDrawer; +} + + +void DemoApplication::overrideGLShapeDrawer (GL_ShapeDrawer* shapeDrawer) +{ + shapeDrawer->enableTexture (m_shapeDrawer->hasTextureEnabled()); + delete m_shapeDrawer; + m_shapeDrawer = shapeDrawer; +} + +void DemoApplication::myinit(void) +{ + + GLfloat light_ambient[] = { btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0) }; + GLfloat light_diffuse[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0) }; + GLfloat light_specular[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0 )}; + /* light_position is NOT default value */ + GLfloat light_position0[] = { btScalar(1.0), btScalar(10.0), btScalar(1.0), btScalar(0.0 )}; + GLfloat light_position1[] = { btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0) }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT1, GL_POSITION, light_position1); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + + glClearColor(btScalar(0.7),btScalar(0.7),btScalar(0.7),btScalar(0)); + + // glEnable(GL_CULL_FACE); + // glCullFace(GL_BACK); +} + + +void DemoApplication::setCameraDistance(float dist) +{ + m_cameraDistance = dist; +} + +float DemoApplication::getCameraDistance() +{ + return m_cameraDistance; +} + + + +void DemoApplication::toggleIdle() { + if (m_idle) { + m_idle = false; + } + else { + m_idle = true; + } +} + + + + +void DemoApplication::updateCamera() { + + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + btScalar rele = m_ele * btScalar(0.01745329251994329547);// rads per deg + btScalar razi = m_azi * btScalar(0.01745329251994329547);// rads per deg + + + btQuaternion rot(m_cameraUp,razi); + + + btVector3 eyePos(0,0,0); + eyePos[m_forwardAxis] = -m_cameraDistance; + + btVector3 forward(eyePos[0],eyePos[1],eyePos[2]); + if (forward.length2() < SIMD_EPSILON) + { + forward.setValue(1.f,0.f,0.f); + } + btVector3 right = m_cameraUp.cross(forward); + btQuaternion roll(right,-rele); + + eyePos = btMatrix3x3(rot) * btMatrix3x3(roll) * eyePos; + + m_cameraPosition[0] = eyePos.getX(); + m_cameraPosition[1] = eyePos.getY(); + m_cameraPosition[2] = eyePos.getZ(); + m_cameraPosition += m_cameraTargetPosition; + + if (m_glutScreenWidth == 0 && m_glutScreenHeight == 0) + return; + + btScalar aspect; + btVector3 extents; + + aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; + extents.setValue(aspect * 1.0f, 1.0f,0); + + + if (m_ortho) + { + // reset matrix + glLoadIdentity(); + + + extents *= m_cameraDistance; + btVector3 lower = m_cameraTargetPosition - extents; + btVector3 upper = m_cameraTargetPosition + extents; + //gluOrtho2D(lower.x, upper.x, lower.y, upper.y); + glOrtho(lower.getX(), upper.getX(), lower.getY(), upper.getY(),-1000,1000); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + //glTranslatef(100,210,0); + } else + { +// glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0); + glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(m_cameraPosition[0], m_cameraPosition[1], m_cameraPosition[2], + m_cameraTargetPosition[0], m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + } + +} + + + +const float STEPSIZE = 5; + +void DemoApplication::stepLeft() +{ + m_azi -= STEPSIZE; if (m_azi < 0) m_azi += 360; updateCamera(); +} +void DemoApplication::stepRight() +{ + m_azi += STEPSIZE; if (m_azi >= 360) m_azi -= 360; updateCamera(); +} +void DemoApplication::stepFront() +{ + m_ele += STEPSIZE; if (m_ele >= 360) m_ele -= 360; updateCamera(); +} +void DemoApplication::stepBack() +{ + m_ele -= STEPSIZE; if (m_ele < 0) m_ele += 360; updateCamera(); +} +void DemoApplication::zoomIn() +{ + m_cameraDistance -= btScalar(m_zoomStepSize); updateCamera(); + if (m_cameraDistance < btScalar(0.1)) + m_cameraDistance = btScalar(0.1); + +} +void DemoApplication::zoomOut() +{ + m_cameraDistance += btScalar(m_zoomStepSize); updateCamera(); + +} + + + + + + + + + + +void DemoApplication::reshape(int w, int h) +{ + GLDebugResetFont(w,h); + + m_glutScreenWidth = w; + m_glutScreenHeight = h; + + glViewport(0, 0, w, h); + updateCamera(); +} + + + +void DemoApplication::keyboardCallback(unsigned char key, int x, int y) +{ + (void)x; + (void)y; + + m_lastKey = 0; + +#ifndef BT_NO_PROFILE + if (key >= 0x31 && key <= 0x39) + { + int child = key-0x31; + m_profileIterator->Enter_Child(child); + } + if (key==0x30) + { + m_profileIterator->Enter_Parent(); + } +#endif //BT_NO_PROFILE + + switch (key) + { + case 'q' : +#ifdef BT_USE_FREEGLUT + //return from glutMainLoop(), detect memory leaks etc. + glutLeaveMainLoop(); +#else + exit(0); +#endif + break; + + case 'l' : stepLeft(); break; + case 'r' : stepRight(); break; + case 'f' : stepFront(); break; + case 'b' : stepBack(); break; + case 'z' : zoomIn(); break; + case 'x' : zoomOut(); break; + case 'i' : toggleIdle(); break; + case 'g' : m_enableshadows=!m_enableshadows;break; + case 'u' : m_shapeDrawer->enableTexture(!m_shapeDrawer->enableTexture(false));break; + case 'h': + if (m_debugMode & btIDebugDraw::DBG_NoHelpText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText); + else + m_debugMode |= btIDebugDraw::DBG_NoHelpText; + break; + + case 'w': + if (m_debugMode & btIDebugDraw::DBG_DrawWireframe) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe); + else + m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + break; + + case 'p': + if (m_debugMode & btIDebugDraw::DBG_ProfileTimings) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_ProfileTimings); + else + m_debugMode |= btIDebugDraw::DBG_ProfileTimings; + break; + + case '=': + { + int maxSerializeBufferSize = 1024*1024*5; + btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); + //serializer->setSerializationFlags(BT_SERIALIZE_NO_DUPLICATE_ASSERT); + m_dynamicsWorld->serialize(serializer); + FILE* f2 = fopen("testFile.bullet","wb"); + fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); + fclose(f2); + delete serializer; + break; + + } + + case 'm': + if (m_debugMode & btIDebugDraw::DBG_EnableSatComparison) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableSatComparison); + else + m_debugMode |= btIDebugDraw::DBG_EnableSatComparison; + break; + + case 'n': + if (m_debugMode & btIDebugDraw::DBG_DisableBulletLCP) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DisableBulletLCP); + else + m_debugMode |= btIDebugDraw::DBG_DisableBulletLCP; + break; + case 'N': + if (m_debugMode & btIDebugDraw::DBG_DrawNormals) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawNormals); + else + m_debugMode |= btIDebugDraw::DBG_DrawNormals; + break; + + case 't' : + if (m_debugMode & btIDebugDraw::DBG_DrawText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawText); + else + m_debugMode |= btIDebugDraw::DBG_DrawText; + break; + case 'y': + if (m_debugMode & btIDebugDraw::DBG_DrawFeaturesText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawFeaturesText); + else + m_debugMode |= btIDebugDraw::DBG_DrawFeaturesText; + break; + case 'a': + if (m_debugMode & btIDebugDraw::DBG_DrawAabb) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb); + else + m_debugMode |= btIDebugDraw::DBG_DrawAabb; + break; + case 'c' : + if (m_debugMode & btIDebugDraw::DBG_DrawContactPoints) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawContactPoints); + else + m_debugMode |= btIDebugDraw::DBG_DrawContactPoints; + break; + case 'C' : + if (m_debugMode & btIDebugDraw::DBG_DrawConstraints) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraints); + else + m_debugMode |= btIDebugDraw::DBG_DrawConstraints; + break; + case 'L' : + if (m_debugMode & btIDebugDraw::DBG_DrawConstraintLimits) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraintLimits); + else + m_debugMode |= btIDebugDraw::DBG_DrawConstraintLimits; + break; + + case 'd' : + if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation); + else + m_debugMode |= btIDebugDraw::DBG_NoDeactivation; + if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) + { + gDisableDeactivation = true; + } else + { + gDisableDeactivation = false; + } + break; + + + + + case 'o' : + { + m_ortho = !m_ortho;//m_stepping = !m_stepping; + break; + } + case 's' : clientMoveAndDisplay(); break; + // case ' ' : newRandom(); break; + case ' ': + clientResetScene(); + break; + case '1': + { + if (m_debugMode & btIDebugDraw::DBG_EnableCCD) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableCCD); + else + m_debugMode |= btIDebugDraw::DBG_EnableCCD; + break; + } + + case '.': + { + shootBox(getRayTo(x,y));//getCameraTargetPosition()); + break; + } + + case '+': + { + m_ShootBoxInitialSpeed += 10.f; + break; + } + case '-': + { + m_ShootBoxInitialSpeed -= 10.f; + break; + } + + default: + // std::cout << "unused key : " << key << std::endl; + break; + } + + if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) + getDynamicsWorld()->getDebugDrawer()->setDebugMode(m_debugMode); + + + +} + +void DemoApplication::setDebugMode(int mode) +{ + m_debugMode = mode; + if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) + getDynamicsWorld()->getDebugDrawer()->setDebugMode(mode); +} + + + + + + +void DemoApplication::moveAndDisplay() +{ + if (!m_idle) + clientMoveAndDisplay(); + else + displayCallback(); +} + + + + +void DemoApplication::displayCallback() +{ +} + +#define NUM_SPHERES_ON_DIAGONAL 9 + +void DemoApplication::setShootBoxShape () +{ + if (!m_shootBoxShape) + { + btBoxShape* box = new btBoxShape(btVector3(0.5,0.5,0.5)); + // box->initializePolyhedralFeatures(); + m_shootBoxShape = box; + } +} + +void DemoApplication::shootBox(const btVector3& destination) +{ + + if (m_dynamicsWorld) + { + float mass = 1.f; + btTransform startTransform; + startTransform.setIdentity(); + btVector3 camPos = getCameraPosition(); + startTransform.setOrigin(camPos); + + setShootBoxShape (); + + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape); + body->setLinearFactor(btVector3(1,1,1)); + //body->setRestitution(1); + + btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed; + + body->getWorldTransform().setOrigin(camPos); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + body->setCcdMotionThreshold(0.5); + body->setCcdSweptSphereRadius(0.4f);//value should be smaller (embedded) than the half extends of the box (see ::setShootBoxShape) +// printf("shootBox uid=%d\n", body->getBroadphaseHandle()->getUid()); +// printf("camPos=%f,%f,%f\n",camPos.getX(),camPos.getY(),camPos.getZ()); +// printf("destination=%f,%f,%f\n",destination.getX(),destination.getY(),destination.getZ()); + + } +} + + +int gPickingConstraintId = 0; +btVector3 gOldPickingPos; +btVector3 gHitPos(-1,-1,-1); +float gOldPickingDist = 0.f; +btRigidBody* pickedBody = 0;//for deactivation state + + +btVector3 DemoApplication::getRayTo(int x,int y) +{ + + + + if (m_ortho) + { + + btScalar aspect; + btVector3 extents; + aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; + extents.setValue(aspect * 1.0f, 1.0f,0); + + extents *= m_cameraDistance; + btVector3 lower = m_cameraTargetPosition - extents; + btVector3 upper = m_cameraTargetPosition + extents; + + btScalar u = x / btScalar(m_glutScreenWidth); + btScalar v = (m_glutScreenHeight - y) / btScalar(m_glutScreenHeight); + + btVector3 p(0,0,0); + p.setValue((1.0f - u) * lower.getX() + u * upper.getX(),(1.0f - v) * lower.getY() + v * upper.getY(),m_cameraTargetPosition.getZ()); + return p; + } + + float top = 1.f; + float bottom = -1.f; + float nearPlane = 1.f; + float tanFov = (top-bottom)*0.5f / nearPlane; + float fov = btScalar(2.0) * btAtan(tanFov); + + btVector3 rayFrom = getCameraPosition(); + btVector3 rayForward = (getCameraTargetPosition()-getCameraPosition()); + rayForward.normalize(); + float farPlane = 10000.f; + rayForward*= farPlane; + + btVector3 rightOffset; + btVector3 vertical = m_cameraUp; + + btVector3 hor; + hor = rayForward.cross(vertical); + hor.normalize(); + vertical = hor.cross(rayForward); + vertical.normalize(); + + float tanfov = tanf(0.5f*fov); + + + hor *= 2.f * farPlane * tanfov; + vertical *= 2.f * farPlane * tanfov; + + btScalar aspect; + + aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; + + hor*=aspect; + + + btVector3 rayToCenter = rayFrom + rayForward; + btVector3 dHor = hor * 1.f/float(m_glutScreenWidth); + btVector3 dVert = vertical * 1.f/float(m_glutScreenHeight); + + + btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; + rayTo += btScalar(x) * dHor; + rayTo -= btScalar(y) * dVert; + return rayTo; +} + +btScalar mousePickClamping = 30.f; + + +void DemoApplication::mouseFunc(int button, int state, int x, int y) +{ + if (state == 0) + { + m_mouseButtons |= 1<rayTest(m_cameraPosition,rayTo,rayCallback); + if (rayCallback.hasHit()) + { + + btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); + if (body) + { + body->setActivationState(ACTIVE_TAG); + btVector3 impulse = rayTo; + impulse.normalize(); + float impulseStrength = 10.f; + impulse *= impulseStrength; + btVector3 relPos = rayCallback.m_hitPointWorld - body->getCenterOfMassPosition(); + body->applyImpulse(impulse,relPos); + } + } + } +#endif + + + + } else + { + + } + break; + } + case 0: + { + if (state==0) + { + + + //add a point to point constraint for picking + if (m_dynamicsWorld) + { + + btVector3 rayFrom; + if (m_ortho) + { + rayFrom = rayTo; + rayFrom.setZ(-100.f); + } else + { + rayFrom = m_cameraPosition; + } + + btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo); + m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback); + if (rayCallback.hasHit()) + { + + + btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject); + if (body) + { + //other exclusions? + if (!(body->isStaticObject() || body->isKinematicObject())) + { + pickedBody = body; + pickedBody->setActivationState(DISABLE_DEACTIVATION); + + + btVector3 pickPos = rayCallback.m_hitPointWorld; + //printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ()); + + + btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; + + + + + + + if ((m_modifierKeys& BT_ACTIVE_SHIFT)==0) + { + btTransform tr; + tr.setIdentity(); + tr.setOrigin(localPivot); + btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body, tr,false); + dof6->setLinearLowerLimit(btVector3(0,0,0)); + dof6->setLinearUpperLimit(btVector3(0,0,0)); + dof6->setAngularLowerLimit(btVector3(0,0,0)); + dof6->setAngularUpperLimit(btVector3(0,0,0)); + + m_dynamicsWorld->addConstraint(dof6,true); + m_pickConstraint = dof6; + + dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,0); + dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,1); + dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,2); + dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,3); + dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,4); + dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,5); + + dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,0); + dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,1); + dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,2); + dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,3); + dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,4); + dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,5); + } else + { + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot); + m_dynamicsWorld->addConstraint(p2p,true); + m_pickConstraint = p2p; + p2p->m_setting.m_impulseClamp = mousePickClamping; + //very weak constraint for picking + p2p->m_setting.m_tau = 0.001f; +/* + p2p->setParam(BT_CONSTRAINT_CFM,0.8,0); + p2p->setParam(BT_CONSTRAINT_CFM,0.8,1); + p2p->setParam(BT_CONSTRAINT_CFM,0.8,2); + p2p->setParam(BT_CONSTRAINT_ERP,0.1,0); + p2p->setParam(BT_CONSTRAINT_ERP,0.1,1); + p2p->setParam(BT_CONSTRAINT_ERP,0.1,2); + */ + + + } + + //save mouse position for dragging + gOldPickingPos = rayTo; + gHitPos = pickPos; + + gOldPickingDist = (pickPos-rayFrom).length(); + } + } + } + } + + } else + { + removePickingConstraint(); + } + + break; + + } + default: + { + } + } + +} + +void DemoApplication::removePickingConstraint() +{ + if (m_pickConstraint && m_dynamicsWorld) + { + m_dynamicsWorld->removeConstraint(m_pickConstraint); + delete m_pickConstraint; + //printf("removed constraint %i",gPickingConstraintId); + m_pickConstraint = 0; + pickedBody->forceActivationState(ACTIVE_TAG); + pickedBody->setDeactivationTime( 0.f ); + pickedBody = 0; + } +} + +void DemoApplication::mouseMotionFunc(int x,int y) +{ + + if (m_pickConstraint) + { + //move the constraint pivot + + if (m_pickConstraint->getConstraintType() == D6_CONSTRAINT_TYPE) + { + btGeneric6DofConstraint* pickCon = static_cast(m_pickConstraint); + if (pickCon) + { + //keep it at the same picking distance + + btVector3 newRayTo = getRayTo(x,y); + btVector3 rayFrom; + btVector3 oldPivotInB = pickCon->getFrameOffsetA().getOrigin(); + + btVector3 newPivotB; + if (m_ortho) + { + newPivotB = oldPivotInB; + newPivotB.setX(newRayTo.getX()); + newPivotB.setY(newRayTo.getY()); + } else + { + rayFrom = m_cameraPosition; + btVector3 dir = newRayTo-rayFrom; + dir.normalize(); + dir *= gOldPickingDist; + + newPivotB = rayFrom + dir; + } + pickCon->getFrameOffsetA().setOrigin(newPivotB); + } + + } else + { + btPoint2PointConstraint* pickCon = static_cast(m_pickConstraint); + if (pickCon) + { + //keep it at the same picking distance + + btVector3 newRayTo = getRayTo(x,y); + btVector3 rayFrom; + btVector3 oldPivotInB = pickCon->getPivotInB(); + btVector3 newPivotB; + if (m_ortho) + { + newPivotB = oldPivotInB; + newPivotB.setX(newRayTo.getX()); + newPivotB.setY(newRayTo.getY()); + } else + { + rayFrom = m_cameraPosition; + btVector3 dir = newRayTo-rayFrom; + dir.normalize(); + dir *= gOldPickingDist; + + newPivotB = rayFrom + dir; + } + pickCon->setPivotB(newPivotB); + } + } + } + + float dx, dy; + dx = btScalar(x) - m_mouseOldX; + dy = btScalar(y) - m_mouseOldY; + + + ///only if ALT key is pressed (Maya style) + if (m_modifierKeys& BT_ACTIVE_ALT) + { + if(m_mouseButtons & 2) + { + btVector3 hor = getRayTo(0,0)-getRayTo(1,0); + btVector3 vert = getRayTo(0,0)-getRayTo(0,1); + btScalar multiplierX = btScalar(0.001); + btScalar multiplierY = btScalar(0.001); + if (m_ortho) + { + multiplierX = 1; + multiplierY = 1; + } + + + m_cameraTargetPosition += hor* dx * multiplierX; + m_cameraTargetPosition += vert* dy * multiplierY; + } + + if(m_mouseButtons & (2 << 2) && m_mouseButtons & 1) + { + } + else if(m_mouseButtons & 1) + { + m_azi += dx * btScalar(0.2); + m_azi = fmodf(m_azi, btScalar(360.f)); + m_ele += dy * btScalar(0.2); + m_ele = fmodf(m_ele, btScalar(180.f)); + } + else if(m_mouseButtons & 4) + { + m_cameraDistance -= dy * btScalar(0.02f); + if (m_cameraDistancegetShapeType() != INVALID_SHAPE_PROXYTYPE)); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + shape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + +#define USE_MOTIONSTATE 1 +#ifdef USE_MOTIONSTATE + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + + btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia); + + btRigidBody* body = new btRigidBody(cInfo); + body->setContactProcessingThreshold(m_defaultContactProcessingThreshold); + +#else + btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + body->setWorldTransform(startTransform); +#endif// + + m_dynamicsWorld->addRigidBody(body); + + return body; +} + +//See http://www.lighthouse3d.com/opengl/glut/index.php?bmpfontortho +void DemoApplication::setOrthographicProjection() +{ + + // switch to projection mode + glMatrixMode(GL_PROJECTION); + + // save previous matrix which contains the + //settings for the perspective projection + glPushMatrix(); + // reset matrix + glLoadIdentity(); + // set a 2D orthographic projection + gluOrtho2D(0, m_glutScreenWidth, 0, m_glutScreenHeight); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // invert the y axis, down is positive + glScalef(1, -1, 1); + // mover the origin from the bottom left corner + // to the upper left corner + glTranslatef(btScalar(0), btScalar(-m_glutScreenHeight), btScalar(0)); + +} + +void DemoApplication::resetPerspectiveProjection() +{ + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + updateCamera(); +} + + + + +extern CProfileIterator * m_profileIterator; + +void DemoApplication::displayProfileString(int xOffset,int yStart,char* message) +{ + glRasterPos3f(btScalar(xOffset),btScalar(yStart),btScalar(0)); + GLDebugDrawString(xOffset,yStart,message); +} + + +void DemoApplication::showProfileInfo(int& xOffset,int& yStart, int yIncr) +{ +#ifndef BT_NO_PROFILE + + static double time_since_reset = 0.f; + if (!m_idle) + { + time_since_reset = CProfileManager::Get_Time_Since_Reset(); + } + + + { + //recompute profiling data, and store profile strings + + char blockTime[128]; + + double totalTime = 0; + + int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); + + m_profileIterator->First(); + + double parent_time = m_profileIterator->Is_Root() ? time_since_reset : m_profileIterator->Get_Current_Parent_Total_Time(); + + { + sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", m_profileIterator->Get_Current_Parent_Name(), parent_time ); + displayProfileString(xOffset,yStart,blockTime); + yStart += yIncr; + sprintf(blockTime,"press (1,2...) to display child timings, or 0 for parent" ); + displayProfileString(xOffset,yStart,blockTime); + yStart += yIncr; + + } + + + double accumulated_time = 0.f; + + for (int i = 0; !m_profileIterator->Is_Done(); m_profileIterator->Next()) + { + double current_total_time = m_profileIterator->Get_Current_Total_Time(); + accumulated_time += current_total_time; + double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; + + sprintf(blockTime,"%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)", + ++i, m_profileIterator->Get_Current_Name(), fraction, + (current_total_time / (double)frames_since_reset),m_profileIterator->Get_Current_Total_Calls()); + displayProfileString(xOffset,yStart,blockTime); + yStart += yIncr; + totalTime += current_total_time; + } + + sprintf(blockTime,"%s (%.3f %%) :: %.3f ms", "Unaccounted", + // (min(0, time_since_reset - totalTime) / time_since_reset) * 100); + parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + + displayProfileString(xOffset,yStart,blockTime); + yStart += yIncr; + + + + sprintf(blockTime,"-------------------------------------------------"); + displayProfileString(xOffset,yStart,blockTime); + yStart += yIncr; + + } +#endif//BT_NO_PROFILE + + + + +} + + +// +void DemoApplication::renderscene(int pass) +{ + btScalar m[16]; + btMatrix3x3 rot;rot.setIdentity(); + const int numObjects=m_dynamicsWorld->getNumCollisionObjects(); + btVector3 wireColor(1,0,0); + for(int i=0;igetCollisionObjectArray()[i]; + btRigidBody* body=btRigidBody::upcast(colObj); + if(body&&body->getMotionState()) + { + btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); + myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); + rot=myMotionState->m_graphicsWorldTrans.getBasis(); + } + else + { + colObj->getWorldTransform().getOpenGLMatrix(m); + rot=colObj->getWorldTransform().getBasis(); + } + btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation + if(i&1) wireColor=btVector3(0.f,0.0f,1.f); + ///color differently for active, sleeping, wantsdeactivation states + if (colObj->getActivationState() == 1) //active + { + if (i & 1) + { + wireColor += btVector3 (1.f,0.f,0.f); + } + else + { + wireColor += btVector3 (.5f,0.f,0.f); + } + } + if(colObj->getActivationState()==2) //ISLAND_SLEEPING + { + if(i&1) + { + wireColor += btVector3 (0.f,1.f, 0.f); + } + else + { + wireColor += btVector3 (0.f,0.5f,0.f); + } + } + + btVector3 aabbMin,aabbMax; + m_dynamicsWorld->getBroadphase()->getBroadphaseAabb(aabbMin,aabbMax); + + aabbMin-=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + aabbMax+=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); +// printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ()); +// printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ()); +// m_dynamicsWorld->getDebugDrawer()->drawAabb(aabbMin,aabbMax,btVector3(1,1,1)); + + + if (!(getDebugMode()& btIDebugDraw::DBG_DrawWireframe)) + { + switch(pass) + { + case 0: m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),aabbMin,aabbMax);break; + case 1: m_shapeDrawer->drawShadow(m,m_sundirection*rot,colObj->getCollisionShape(),aabbMin,aabbMax);break; + case 2: m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor*btScalar(0.3),0,aabbMin,aabbMax);break; + } + } + } +} + +// +void DemoApplication::renderme() +{ + myinit(); + + updateCamera(); + + if (m_dynamicsWorld) + { + if(m_enableshadows) + { + glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_CULL_FACE); + renderscene(0); + + glDisable(GL_LIGHTING); + glDepthMask(GL_FALSE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_STENCIL_TEST); + glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + glStencilFunc(GL_ALWAYS,1,0xFFFFFFFFL); + glFrontFace(GL_CCW); + glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); + renderscene(1); + glFrontFace(GL_CW); + glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); + renderscene(1); + glFrontFace(GL_CCW); + + glPolygonMode(GL_FRONT,GL_FILL); + glPolygonMode(GL_BACK,GL_FILL); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_LIGHTING); + glDepthMask(GL_TRUE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + + glDepthFunc(GL_LEQUAL); + glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL ); + glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + glDisable(GL_LIGHTING); + renderscene(2); + glEnable(GL_LIGHTING); + glDepthFunc(GL_LESS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + } + else + { + glDisable(GL_CULL_FACE); + renderscene(0); + } + + int xOffset = 10; + int yStart = 20; + int yIncr = 20; + + + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + + if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0) + { + setOrthographicProjection(); + + showProfileInfo(xOffset,yStart,yIncr); + +#ifdef USE_QUICKPROF + + + if ( getDebugMode() & btIDebugDraw::DBG_ProfileTimings) + { + static int counter = 0; + counter++; + std::map::iterator iter; + for (iter = btProfiler::mProfileBlocks.begin(); iter != btProfiler::mProfileBlocks.end(); ++iter) + { + char blockTime[128]; + sprintf(blockTime, "%s: %lf",&((*iter).first[0]),btProfiler::getBlockTime((*iter).first, btProfiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); + glRasterPos3f(xOffset,yStart,0); + GLDebugDrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); + yStart += yIncr; + + } + + } +#endif //USE_QUICKPROF + + + + + resetPerspectiveProjection(); + } + + glDisable(GL_LIGHTING); + + + } + + updateCamera(); + +} + +#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h" + + +void DemoApplication::clientResetScene() +{ + removePickingConstraint(); + +#ifdef SHOW_NUM_DEEP_PENETRATIONS + gNumDeepPenetrationChecks = 0; + gNumGjkChecks = 0; +#endif //SHOW_NUM_DEEP_PENETRATIONS + + gNumClampedCcdMotions = 0; + int numObjects = 0; + int i; + + if (m_dynamicsWorld) + { + int numConstraints = m_dynamicsWorld->getNumConstraints(); + for (i=0;igetConstraint(0)->setEnabled(true); + } + numObjects = m_dynamicsWorld->getNumCollisionObjects(); + + ///create a copy of the array, not a reference! + btCollisionObjectArray copyArray = m_dynamicsWorld->getCollisionObjectArray(); + + + + + for (i=0;igetMotionState()) + { + btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); + myMotionState->m_graphicsWorldTrans = myMotionState->m_startWorldTrans; + body->setCenterOfMassTransform( myMotionState->m_graphicsWorldTrans ); + colObj->setInterpolationWorldTransform( myMotionState->m_startWorldTrans ); + colObj->forceActivationState(ACTIVE_TAG); + colObj->activate(); + colObj->setDeactivationTime(0); + //colObj->setActivationState(WANTS_DEACTIVATION); + } + //removed cached contact points (this is not necessary if all objects have been removed from the dynamics world) + if (m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()) + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + + btRigidBody* body = btRigidBody::upcast(colObj); + if (body && !body->isStaticObject()) + { + btRigidBody::upcast(colObj)->setLinearVelocity(btVector3(0,0,0)); + btRigidBody::upcast(colObj)->setAngularVelocity(btVector3(0,0,0)); + } + } + + } + + ///reset some internal cached data in the broadphase + m_dynamicsWorld->getBroadphase()->resetPool(getDynamicsWorld()->getDispatcher()); + m_dynamicsWorld->getConstraintSolver()->reset(); + + } + +} diff --git a/Demos/OpenGL/DemoApplication.h b/Demos/OpenGL/DemoApplication.h new file mode 100644 index 0000000..85a4f69 --- /dev/null +++ b/Demos/OpenGL/DemoApplication.h @@ -0,0 +1,258 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEMO_APPLICATION_H +#define DEMO_APPLICATION_H + + +#include "GlutStuff.h" +#include "GL_ShapeDrawer.h" + +#include +#include +#include + + +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btAlignedObjectArray.h" + +class btCollisionShape; +class btDynamicsWorld; +class btRigidBody; +class btTypedConstraint; + + + +class DemoApplication +{ +protected: + void displayProfileString(int xOffset,int yStart,char* message); + class CProfileIterator* m_profileIterator; + + protected: +#ifdef USE_BT_CLOCK + btClock m_clock; +#endif //USE_BT_CLOCK + + ///this is the most important class + btDynamicsWorld* m_dynamicsWorld; + + ///constraint for mouse picking + btTypedConstraint* m_pickConstraint; + + virtual void removePickingConstraint(); + + btCollisionShape* m_shootBoxShape; + + float m_cameraDistance; + int m_debugMode; + + float m_ele; + float m_azi; + btVector3 m_cameraPosition; + btVector3 m_cameraTargetPosition;//look at + + int m_mouseOldX; + int m_mouseOldY; + int m_mouseButtons; +public: + int m_modifierKeys; +protected: + + float m_scaleBottom; + float m_scaleFactor; + btVector3 m_cameraUp; + int m_forwardAxis; + float m_zoomStepSize; + + int m_glutScreenWidth; + int m_glutScreenHeight; + + float m_frustumZNear; + float m_frustumZFar; + + int m_ortho; + + float m_ShootBoxInitialSpeed; + + bool m_stepping; + bool m_singleStep; + bool m_idle; + int m_lastKey; + + void showProfileInfo(int& xOffset,int& yStart, int yIncr); + void renderscene(int pass); + + GL_ShapeDrawer* m_shapeDrawer; + bool m_enableshadows; + btVector3 m_sundirection; + btScalar m_defaultContactProcessingThreshold; + +public: + + DemoApplication(); + + virtual ~DemoApplication(); + + btDynamicsWorld* getDynamicsWorld() + { + return m_dynamicsWorld; + } + + virtual void initPhysics() = 0; + + virtual void setDrawClusters(bool drawClusters) + { + + } + + void overrideGLShapeDrawer (GL_ShapeDrawer* shapeDrawer); + + void setOrthographicProjection(); + void resetPerspectiveProjection(); + + bool setTexturing(bool enable) { return(m_shapeDrawer->enableTexture(enable)); } + bool setShadows(bool enable) { bool p=m_enableshadows;m_enableshadows=enable;return(p); } + bool getTexturing() const + { + return m_shapeDrawer->hasTextureEnabled(); + } + bool getShadows() const + { + return m_enableshadows; + } + + + int getDebugMode() + { + return m_debugMode ; + } + + void setDebugMode(int mode); + + void setAzi(float azi) + { + m_azi = azi; + } + + void setCameraUp(const btVector3& camUp) + { + m_cameraUp = camUp; + } + void setCameraForwardAxis(int axis) + { + m_forwardAxis = axis; + } + + virtual void myinit(); + + void toggleIdle(); + + virtual void updateCamera(); + + btVector3 getCameraPosition() + { + return m_cameraPosition; + } + btVector3 getCameraTargetPosition() + { + return m_cameraTargetPosition; + } + + btScalar getDeltaTimeMicroseconds() + { +#ifdef USE_BT_CLOCK + btScalar dt = (btScalar)m_clock.getTimeMicroseconds(); + m_clock.reset(); + return dt; +#else + return btScalar(16666.); +#endif + } + void setFrustumZPlanes(float zNear, float zFar) + { + m_frustumZNear = zNear; + m_frustumZFar = zFar; + } + + ///glut callbacks + + float getCameraDistance(); + void setCameraDistance(float dist); + void moveAndDisplay(); + + virtual void clientMoveAndDisplay() = 0; + + virtual void clientResetScene(); + + ///Demo functions + virtual void setShootBoxShape (); + virtual void shootBox(const btVector3& destination); + + + btVector3 getRayTo(int x,int y); + + btRigidBody* localCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape); + + ///callback methods by glut + + virtual void keyboardCallback(unsigned char key, int x, int y); + + virtual void keyboardUpCallback(unsigned char key, int x, int y) {} + + virtual void specialKeyboard(int key, int x, int y){} + + virtual void specialKeyboardUp(int key, int x, int y){} + + virtual void reshape(int w, int h); + + virtual void mouseFunc(int button, int state, int x, int y); + + virtual void mouseMotionFunc(int x,int y); + + virtual void displayCallback(); + + virtual void renderme(); + + virtual void swapBuffers() = 0; + + virtual void updateModifierKeys() = 0; + + void stepLeft(); + void stepRight(); + void stepFront(); + void stepBack(); + void zoomIn(); + void zoomOut(); + + bool isIdle() const + { + return m_idle; + } + + void setIdle(bool idle) + { + m_idle = idle; + } + + +}; + +#endif //DEMO_APPLICATION_H + + diff --git a/Demos/OpenGL/GLDebugDrawer.cpp b/Demos/OpenGL/GLDebugDrawer.cpp new file mode 100644 index 0000000..bddd135 --- /dev/null +++ b/Demos/OpenGL/GLDebugDrawer.cpp @@ -0,0 +1,130 @@ + +#include "GLDebugDrawer.h" +#include "GLDebugFont.h" +#include "GlutStuff.h" + + + +#include //printf debugging +GLDebugDrawer::GLDebugDrawer() +:m_debugMode(0) +{ + +} + +GLDebugDrawer::~GLDebugDrawer() +{ +} + +void GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& fromColor, const btVector3& toColor) +{ + glBegin(GL_LINES); + glColor3f(fromColor.getX(), fromColor.getY(), fromColor.getZ()); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glColor3f(toColor.getX(), toColor.getY(), toColor.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + glEnd(); +} + +void GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& color) +{ + drawLine(from,to,color,color); +} + +void GLDebugDrawer::drawSphere (const btVector3& p, btScalar radius, const btVector3& color) +{ + glColor4f (color.getX(), color.getY(), color.getZ(), btScalar(1.0f)); + glPushMatrix (); + glTranslatef (p.getX(), p.getY(), p.getZ()); + + int lats = 5; + int longs = 5; + + int i, j; + for(i = 0; i <= lats; i++) { + btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats); + btScalar z0 = radius*sin(lat0); + btScalar zr0 = radius*cos(lat0); + + btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats); + btScalar z1 = radius*sin(lat1); + btScalar zr1 = radius*cos(lat1); + + glBegin(GL_QUAD_STRIP); + for(j = 0; j <= longs; j++) { + btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs; + btScalar x = cos(lng); + btScalar y = sin(lng); + + glNormal3f(x * zr0, y * zr0, z0); + glVertex3f(x * zr0, y * zr0, z0); + glNormal3f(x * zr1, y * zr1, z1); + glVertex3f(x * zr1, y * zr1, z1); + } + glEnd(); + } + + glPopMatrix(); +} + + + +void GLDebugDrawer::drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha) +{ +// if (m_debugMode > 0) + { + const btVector3 n=btCross(b-a,c-a).normalized(); + glBegin(GL_TRIANGLES); + glColor4f(color.getX(), color.getY(), color.getZ(),alpha); + glNormal3d(n.getX(),n.getY(),n.getZ()); + glVertex3d(a.getX(),a.getY(),a.getZ()); + glVertex3d(b.getX(),b.getY(),b.getZ()); + glVertex3d(c.getX(),c.getY(),c.getZ()); + glEnd(); + } +} + +void GLDebugDrawer::setDebugMode(int debugMode) +{ + m_debugMode = debugMode; + +} + +void GLDebugDrawer::draw3dText(const btVector3& location,const char* textString) +{ + glRasterPos3f(location.x(), location.y(), location.z()); + //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),textString); +} + +void GLDebugDrawer::reportErrorWarning(const char* warningString) +{ + printf("%s\n",warningString); +} + +void GLDebugDrawer::drawContactPoint(const btVector3& pointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) +{ + + { + btVector3 to=pointOnB+normalOnB*1;//distance; + const btVector3&from = pointOnB; + glColor4f(color.getX(), color.getY(), color.getZ(),1.f); + //glColor4f(0,0,0,1.f); + glBegin(GL_LINES); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + glEnd(); + + +// glRasterPos3f(from.x(), from.y(), from.z()); +// char buf[12]; +// sprintf(buf," %d",lifeTime); + //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + + + } +} + + + + + diff --git a/Demos/OpenGL/GLDebugDrawer.h b/Demos/OpenGL/GLDebugDrawer.h new file mode 100644 index 0000000..6ac987d --- /dev/null +++ b/Demos/OpenGL/GLDebugDrawer.h @@ -0,0 +1,37 @@ +#ifndef GL_DEBUG_DRAWER_H +#define GL_DEBUG_DRAWER_H + +#include "LinearMath/btIDebugDraw.h" + + + +class GLDebugDrawer : public btIDebugDraw +{ + int m_debugMode; + +public: + + GLDebugDrawer(); + virtual ~GLDebugDrawer(); + + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& fromColor, const btVector3& toColor); + + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color); + + virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color); + + virtual void drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha); + + virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color); + + virtual void reportErrorWarning(const char* warningString); + + virtual void draw3dText(const btVector3& location,const char* textString); + + virtual void setDebugMode(int debugMode); + + virtual int getDebugMode() const { return m_debugMode;} + +}; + +#endif//GL_DEBUG_DRAWER_H diff --git a/Demos/OpenGL/GLDebugFont.cpp b/Demos/OpenGL/GLDebugFont.cpp new file mode 100644 index 0000000..6160068 --- /dev/null +++ b/Demos/OpenGL/GLDebugFont.cpp @@ -0,0 +1,1000 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "GLDebugFont.h" + + +#ifdef _WIN32//for glut.h +#include +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#if (defined (TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined (TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR) +#import +#define glOrtho glOrthof +#else +#include +#include +#include +#endif +#else + + + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif +#endif + +#include +#include //for memset + +extern unsigned char sFontData[]; +static bool sTexturesInitialized = false; + +static GLuint sTexture = -1; +static int sScreenWidth = -1; +static int sScreenHeight = -1; + + +void GLDebugResetFont(int screenWidth,int screenHeight) +{ + + if ((sScreenWidth == screenWidth) && (sScreenHeight == screenHeight)) + return; + + sScreenWidth = screenWidth; + sScreenHeight = screenHeight; + + if (!sTexturesInitialized) + { + sTexturesInitialized = true; + glGenTextures(1, &sTexture); + glBindTexture(GL_TEXTURE_2D, sTexture); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 3, 256 , 256 , 0, GL_RGB, GL_UNSIGNED_BYTE, &sFontData[0]); + } + +// printf("generating font at resolution %d,%d\n",screenWidth,screenHeight); + +} + +#define USE_ARRAYS 1 + +void GLDebugDrawStringInternal(int x,int y,const char* string, const btVector3& rgb) +{ + GLDebugDrawStringInternal(x,y,string,rgb,true,10); +} + +void GLDebugDrawStringInternal(int x,int y,const char* string, const btVector3& rgb, bool enableBlend, int spacing) +{ + + if (!sTexturesInitialized) + { + GLDebugResetFont(sScreenWidth,sScreenHeight); + } + if (strlen(string)) + { + + glColor4f(rgb.getX(),rgb.getY(),rgb.getZ(),1.f); + float cx; + float cy; + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_R); + + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glDepthFunc (GL_LEQUAL); + + if (enableBlend) + { + glEnable(GL_BLEND); + } else + { + glDisable(GL_BLEND); + } + glEnable (GL_DEPTH_TEST); + glBindTexture(GL_TEXTURE_2D, sTexture); + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glOrtho(0,sScreenWidth,0,sScreenHeight,-1,1); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(btScalar(x),btScalar(sScreenHeight - y),btScalar(0)); + +#if USE_ARRAYS + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); +#endif + + GLfloat verts[] ={ + 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + 0.f,0.f,0.f + }; + + GLfloat uv_texcoords[] = { + 0,0, + 0,0, + 0,0, + 0,0 + }; + verts[0] = 0; verts[1] = 0; verts[2] = 0; + verts[3] = 16-1; verts[4] = 0; verts[5] = 0; + verts[6] = 16-1; verts[7] = 16-1; verts[8] = 0; + verts[9] = 0; verts[10] = 16-1; verts[11] = 0; + + for (int i=0;i=0) + { + cx=float(ch%16) * btScalar(1./16.f); + cy=float(ch/16) * btScalar(1./16.f); + + uv_texcoords[0] = cx; uv_texcoords[1] = btScalar(1-cy-1./16.f); + uv_texcoords[2] = btScalar(cx+1./16.f); uv_texcoords[3] = btScalar(1-cy-1./16.f); + uv_texcoords[4] = btScalar(cx+1./16.f); uv_texcoords[5] = btScalar(1-cy); + uv_texcoords[6] = cx; uv_texcoords[7] = btScalar(1-cy); +#if USE_ARRAYS + glTexCoordPointer(2,GL_FLOAT,0,uv_texcoords); + glVertexPointer(3, GL_FLOAT, 0, verts); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +#else + glBegin(GL_QUADS); + glTexCoord2f(cx,1-cy-1./16.f); + + glVertex2i(0,0); + glTexCoord2f(cx+1./16.f,1-cy-1./16.f); + + glVertex2i(16 - 1,0); + glTexCoord2f(cx+1./16.f,1-cy); + + glVertex2i(16 - 1,16 -1); + glTexCoord2f(cx,1-cy); + + glVertex2i(0,16 -1); + glEnd(); +#endif + + glTranslatef(spacing,0,0); + } + } + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +#if 1 + glEnable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glDepthFunc (GL_LEQUAL); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(btScalar(0.025),btScalar(0.025),btScalar(0.025)); +#endif + glMatrixMode(GL_MODELVIEW); +#if USE_ARRAYS + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState (GL_TEXTURE_COORD_ARRAY); +#endif + //glDisable(GL_TEXTURE_2D); + } +} + +void GLDebugDrawString(int x,int y,const char* string) +{ + + btVector3 rgb(1,1,1); + GLDebugDrawStringInternal(x,y,string,rgb); +} + + +unsigned char sFontData[] = +{ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,145,145,145,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,213,213,213,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,103,103,103,2,2,2,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213, + 213,213,255,255,255,255,255,255,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,213,213,213,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,213,213,213,255,255,255,255,255,255,255,255,255,213,213,213,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,178,178,178,178,178,178,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,0,0,0,0,0,0,0,0,0,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,145,145,145,178,178,178,255,255,255,255,255,255,255,255,255,145,145,145,103,103,103,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,2,2,2,255,255,255,178,178,178,103,103,103,145,145,145,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,103,103,103,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,103,103,103,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,145,145,145,103,103,103,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,178,178,178,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,178,178,178,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,103,103,103,103,103,103,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,145,145,145,178,178,178,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,0,0,0,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,70,70,70,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70, + 70,70,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,70,70, + 70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,213,213,213,255,255,255,255,255,255,0,0,0,0,0,0,70,70,70,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,103,103,103,255,255,255,213,213,213,70,70,70,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,255,255,255,246,246,246,178,178,178,246,246,246,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37, + 37,37,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,178,178,178,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,213,213, + 213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,255,255,255,103,103,103,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,178,178,178,255,255,255,37,37,37,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,255,255,255,255,255,255,145,145,145,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,145,145,145,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,103,103,103,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,145,145,145,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,70,70,70,255,255,255,70,70,70,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,213,213,213,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,70,70,70,255,255,255,37,37,37,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,103,103,103,246,246,246,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,70,70,70,255,255,255,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,0,0,0,37,37,37,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,0,0,0,37,37,37,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,70,70,70,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,103,103,103,213,213,213,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,37,37,37,255,255,255,178,178,178,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,70,70,70,0,0,0,70,70,70,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,145,145,145,213,213,213,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,70,70,70,255,255,255,37,37,37,0,0,0,145,145,145,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,178,178,178,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,0,0,0,103,103,103,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,0,0,0,103,103,103,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,255,255,255,213,213,213,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,246,246,246,103,103,103,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,37,37,37,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,103,103,103,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,103,103,103,70,70,70,0,0,0,103,103,103,255,255, + 255,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,2,2,2,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,178,178,178,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,255,255,255,246,246, + 246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,103,103,103,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,213,213,213,213,213,213,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,213,213,213,213,213,213,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255, + 255,255,255,255,255,213,213,213,213,213,213,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,178,178,178,213,213,213,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,178,178,178,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178, + 178,178,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,145,145,145,145,145,145,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,145,145,145,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,255,255,255,145,145,145,0,0,0,37,37,37,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,145,145,145,0,0,0,37,37,37,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2, + 2,2,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103, + 103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,178,178, + 178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,103,103,103,103,103,103,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,103,103,103,103,103,103,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37, + 37,37,103,103,103,103,103,103,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,103,103,103,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246, + 246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,0,0,0,37,37,37,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,246,246,246,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,103,103, + 103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,0,0,0,103,103,103,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103, + 103,103,246,246,246,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,103,103,103,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,70,70,70,70,70,70,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,37,37,37,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,37,37,37,70,70,70,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,178,178,178,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,246,246,246,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,145,145,145,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,213,213,213,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,213,213,213,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,213,213,213,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246, + 246,246,255,255,255,255,255,255,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,145,145,145,178,178,178,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,178,178,178,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,246,246,246,103,103,103,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,103,103,103,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255, + 255,255,213,213,213,178,178,178,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,178,178,178,0,0,0,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,178,178,178,255,255,255,255,255,255,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,103,103,103,103,103,103,178,178,178,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,37,37,37,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0,0,2,2,2,37,37,37,145,145,145,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255, + 255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,145,145,145,255,255,255,103,103,103,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,178,178,178,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,246,246,246,0,0,0,0,0,0,246,246,246,70,70, + 70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,2,2,2,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,2,2,2,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,178,178,178,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,70,70,70,2,2,2,2,2,2,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,103,103,103,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,255,255,255,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,178,178,178,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,103,103,103,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,145,145,145,255,255,255,103,103,103,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,178,178,178,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,246,246,246,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,255,255,255,246,246,246,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,145,145,145,103,103,103,178,178,178,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,103,103,103,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255, + 255,255,213,213,213,0,0,0,37,37,37,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,213,213,213,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,70,70,70,103,103,103,246,246,246,0,0,0,213,213,213,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,103,103,103,103,103,103,255,255,255,255,255,255,246,246, + 246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,213,213,213,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,145,145,145,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,70,70,70,178,178,178,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255, + 255,255,255,255,255,0,0,0,103,103,103,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,145,145,145,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,103,103,103,103,103,103,145,145,145,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,178,178,178,103,103,103,178,178,178,255,255,255,145,145,145,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,213,213,213,213,213,213,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,213,213,213,213,213,213,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,213,213,213,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,213,213,213,213,213,213,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213, + 213,213,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,213,213,213,145,145,145,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,213,213,213,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,255,255,255,145,145,145,178,178,178,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,178,178,178,255,255,255,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246, + 246,246,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,178,178,178,255,255,255,178,178,178,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,178,178,178,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,0,0,0,178,178,178,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,37,37,37,178,178,178,255,255,255,37,37,37,178,178,178,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,0,0,0,70,70,70,178,178,178,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,213,213,213,103,103,103,103,103,103,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,37,37,37,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,103,103,103,255,255,255,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246, + 246,246,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,255,255,255,2,2,2,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,103,103,103,103,103,103,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,103,103,103,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,103,103,103,213,213,213,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,246,246,246,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,213,213,213,255,255,255,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,37,37,37,255,255,255,255,255,255,70,70,70,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,103,103,103,145,145,145,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,178,178,178,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,213,213,213,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,145,145,145,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,145,145,145,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,178,178,178,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,178,178,178,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,37,37, + 37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,246,246,246,255,255,255,145,145,145,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,213,213,213,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246, + 246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,246,246,246,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,103,103,103,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255, + 255,255,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,0,0,0,103,103,103,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,145,145,145,103,103,103,178,178,178,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,213,213,213,255,255,255,246,246,246,2,2,2,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,103,103,103,103,103,103,178,178,178,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37, + 37,37,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,2,2,2,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,145,145,145,0,0,0,0,0,0,255,255,255,103,103, + 103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,103,103,103,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2, + 2,2,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,37,37,37,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,255,255,255,2,2,2,246,246,246,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,0,0,0,145,145,145,103,103, + 103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,213,213,213,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,246,246,246,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103, + 103,103,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,103,103,103,246,246,246,255,255,255,103,103,103,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,70,70,70,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,2,2,2,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,145,145,145,2,2,2,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,70,70,70,255,255,255,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213, + 213,213,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,255,255,255,255,255,255,2,2,2,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,0,0,0,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,37,37,37,0,0,0,255,255,255,37,37,37,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,37,37,37,0,0,0,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,103,103,103,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,103,103,103,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,103,103,103,103,103,103,103,103,103,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,255,255,255,246,246,246,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255, + 255,255,103,103,103,103,103,103,0,0,0,70,70,70,103,103,103,255,255,255,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,246,246,246,2,2,2,0,0,0,0,0,0,213,213,213,255,255,255,213,213,213,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,0,0,0,213,213,213,255,255,255,145,145,145,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,145,145,145,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,103,103,103,213,213,213,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,2,2,2,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,178,178,178,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,213,213,213,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,213,213,213,103,103,103,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,103,103,103,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,145,145,145,0,0,0,0,0,0,37,37,37,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,178,178,178,103,103,103,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,103,103,103,145,145,145,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255, + 255,255,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,103,103,103,103,103,103,213,213,213,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,103,103,103,0,0,0,178,178,178,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,70,70,70,0,0,0,37,37,37,255,255,255,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,103,103,103,103,103,103,103,103,103,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,255,255,255,103,103,103,0,0,0,2,2,2,178,178,178,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,255,255,255,103,103,103,0,0,0,70,70,70,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,103,103,103,255,255,255,255,255,255,178,178,178,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,145,145,145,178,178,178,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,246,246,246,255,255,255,2,2,2,213,213,213,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,103,103,103,103,103,103,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,178,178,178,103,103,103,255,255,255,213,213,213,70,70,70,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,103,103,103,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,103,103,103,103,103,103,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,2,2,2,178,178,178,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,246,246,246,255,255,255,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,255,255,255,213,213,213,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,37,37,37,255,255,255,178,178,178,37,37,37,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,246,246,246,255,255,255,178,178,178,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,70,70,70,255,255,255,70,70,70,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,145,145,145,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246, + 246,246,213,213,213,0,0,0,70,70,70,255,255,255,37,37,37,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,70,70,70,255,255,255,37,37,37,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,246,246,246,103,103,103,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,213,213,213,255,255,255,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145, + 145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37, + 37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,246,246,246,2,2,2,103,103,103,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,246,246,246,103,103,103,103,103,103,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,103,103,103,103,103,103,103,103,103,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,103,103,103,103,103,103,103,103,103,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213, + 213,213,255,255,255,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,103,103,103,103,103,103,103,103,103,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,103,103,103,0,0,0,103,103,103,255,255,255,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,103,103,103,255,255,255,246,246,246,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,255,255,255,246,246, + 246,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,103,103,103,103,103,103,0,0,0,255,255,255,255,255,255,145,145,145,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,213,213,213,255,255,255,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,2,2,2,0,0,0,255,255,255,255,255,255,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,70,70,70,0,0,0,103,103,103,255,255,255,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,145,145,145,103,103,103,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,70,70,70,246,246,246,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,103,103,103,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255, + 255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,178,178,178,255,255,255,178,178,178,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,103,103,103,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,255,255,255,178,178,178,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213, + 213,213,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,103,103,103,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,246,246,246,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,213,213,213,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,103,103,103,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,37,37,37,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,213,213,213,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,213,213,213,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,178,178,178,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246, + 246,246,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,246,246,246,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,178,178,178,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145, + 145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,246,246,246,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37, + 37,37,255,255,255,103,103,103,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,103,103,103,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,103,103,103,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,213,213,213,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,213,213,213,103,103,103,103,103,103,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,246,246,246,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,178,178,178,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,246,246,246,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,246,246,246,213,213,213,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,145,145,145,213,213,213,255,255,255,255,255,255,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,178, + 178,178,0,0,0,0,0,0,213,213,213,213,213,213,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,2,2,2,178,178,178,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,178,178,178,255,255,255,178,178,178,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,145,145,145,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103, + 103,103,255,255,255,178,178,178,0,0,0,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,103,103,103,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,246,246,246,255,255,255,255,255,255,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,2,2,178,178,178,255,255,255,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,213,213,213,37,37,37,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,213,213,213,255,255,255,37,37, + 37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,103,103,103,213,213,213,255,255,255,145,145,145,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255, + 255,255,255,255,255,145,145,145,0,0,0,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,37,37,37,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,145,145,145,70,70,70,2,2,2,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255, + 255,255,0,0,0,255,255,255,2,2,2,0,0,0,2,2,2,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,145,145,145,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255, + 255,255,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,2,2,2,255,255,255,145,145,145,70,70, + 70,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70, + 70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,145,145,145,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,255,255, + 255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,246,246,246,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37, + 37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0, + 0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,213,213,213,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,2,2,2,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,213,213,213,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,37,37,37,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,2,2,2,255,255,255,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,246,246,246,103,103,103,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,103,103,103,246,246,246,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,2,2,2,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,103,103,103,255,255,255,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,213,213,213,246,246,246,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,145,145,145,246,246,246,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,103,103,103,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,103,103,103,255,255,255,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37, + 37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,37,37,37,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,145,145,145,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,37,37,37,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,70,70,70,0,0,0,2,2,2,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,37,37,37,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0, + 0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,145,145,145,0,0,0,70,70,70,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,178,178,178,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0, + 0,145,145,145,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,213,213,213,145,145,145,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,70,70,70,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,159,159,159,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,246,246,246,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,255,255,255,255,255,255,37,37,37,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,255,255,255,255,255,255,255,255, + 255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,213,213,213,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,213,213,213,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,246,246,246,0,0,0,0,0,0,213,213,213,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,213,213,213,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,178,178,178,0,0,0,0,0,0,0,0, + 0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103, + 103,103,255,255,255,37,37,37,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,178,178,178,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,178,178,178,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,2,2,178,178,178,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,178,178,178,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,246,246,246,255,255, + 255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,145,145, + 145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,70,70,70,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255, + 255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,145,145,145,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,145,145,145,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,213,213,213,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,178,178, + 178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,70,70,70,0,0,0,0,0,0,2,2,2,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,37,37,37,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,70,70,70,0,0,0,2,2,2,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,37,37,37,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,2,2,2,0,0,0,70,70,70,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,37,37,37,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,145,145,145,0,0,0,70,70,70,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,246,246,246,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,70,70,70,0,0,0,145,145,145,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,145,145,145,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,213,213,213,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,70,70,70,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,37,37,37,246,246,246,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,255,255,255,37,37,37,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,0,0,0,37,37,37,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,213,213,213,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,145,145,145,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,213,213,213,0,0,0,145,145,145,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,213,213,213,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,145,145,145,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,246,246,246,0,0,0,255,255,255,0,0,0,213,213,213,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,0,0,0,103,103,103,246,246,246,255,255,255,0,0,0,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178, + 178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,255,255,255,37,37,37,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,2,2,2,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,255,255,255,70,70,70,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,2,2,2,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,70,70,70,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,246,246,246,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,37,37,37,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,213,213,213,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,37,37,37,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,37,37,37,246,246,246,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,70,70,70,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,246,246,246,103,103,103,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,213,213,213,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,37,37,37,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37, + 37,37,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,37,37,37,255,255,255,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,246,246,246,103,103,103,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,246,246,246,103,103,103,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,246,246,246,103,103,103,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,178,178,178,246,246,246,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,255,246,246,246,246,246,246,246,246,246,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,246,246,246,103,103,103,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213, + 213,213,178,178,178,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,213,213,213,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,37,37,37,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,246,246,246,246,246,246,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,255,255,255,37,37,37,70,70,70,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,70,70,70,0,0,0,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,246,246,246,2,2,2,145,145,145,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,70,70,70,255,255,255,246,246,246,178,178,178,213,213,213,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,246,246,246,2,2,2,145,145,145,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,37,37,37,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,145,145,145,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,2,2,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,178,178,178,145,145,145,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,37,37,37,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,246,246,246,255,255,255,0,0,0,178,178,178,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,37,37,37,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,246,246,246,103,103,103,103,103,103,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,37,37,37,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37,37,0,0,0,145,145,145,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,103,103,103,0,0,0,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,246,246,246,0,0,0,255,255,255,213,213,213,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,37,37,37,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,255,255,255,0,0,0,255,255,255,2,2,2,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,255,255,255,103,103,103,255,255,255,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,70,70,70,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,246,246,246,255,255,255,178,178,178,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,178,178,178,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,37,37,37,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,37,37, + 37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,70,70,70,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,2,2,2,246,246,246,0,0,0,0,0,0,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,103,103,103,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,37,37,37,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,213,213,213,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,178,178,178,255,255,255,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,178,178, + 178,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,213,213,213,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,145,145,145,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,246,246,246,246,246,246,246,246,246,246,246,246,246,246, + 246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,103,103,103,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,246,246,246,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,37,37, + 37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,103,103,103,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,0,0,0,0,0,0,103,103,103,0,0,0,70,70,70,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,255,255,255,178,178,178,178,178,178,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,103,103,103,255,255,255,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,2,2,2,255,255,255,0,0,0,178,178,178,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,246,246,246,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,2,2,2,246,246,246,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,255,255,255,246,246,246,246,246,246,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,246,246,246,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,213,213,213,178,178,178,255,255,255,70,70,70,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,103,103,103,255,255,255,2,2,2,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,145,145,145,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,255,255,255,2,2,2,103,103,103,213,213,213,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,255,255,255,178,178,178,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,103,103,103,0,0,0,145,145,145,103,103,103,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,255,255,255,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,246,246,246,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,103,103,103,246,246,246,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,37,37,37,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,70,70,70,0,0,0,0,0,0,2,2,2,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,70,70,70,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,178,178,178,255,255,255,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,103,103,103,255,255, + 255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,213,213,213,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,246,246,246,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246, + 246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,213,213,213,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,70,70,70,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,246,246,246,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,246,246,246,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,103,103,103,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,246,246,246,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,70,70,70,103,103,103,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,37,37,37,246,246,246,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,246,246,246,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,213,213,213,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,178,178,178,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,103,103,103,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,178,178,178,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,246,246,246,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,213,213,213,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,2,2,2,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,246,246,246,246,246,246,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,103,103,103,103,103,103,145,145,145,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,2,2,2,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,2,2,2,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,255,255,255,255,255,255,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,145,145,145,246,246,246,246,246,246,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,255,255,255,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,70,70,70,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,255,255,255,255,255,255,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,178, + 178,178,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,255,255,255,255,255,255,103,103,103,145,145,145,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,2,2,2,0,0,0,255,255,255,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246, + 246,246,37,37,37,0,0,0,37,37,37,246,246,246,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,103,103,103,0,0,0,0,0,0,246,246,246,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,103,103,103,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,255,0,0,0,103,103,103,103,103,103,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,246,246,246,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,255,255,255,246,246,246,255,255,255,255,255,255,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,70,70,70,246,246,246,37,37,37,246,246,246,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,246,246,246,255,255,255,0,0,0,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,246,246,246,255,255,255,255,255,255,246,246,246,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,103,103,103,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,213,213,213,103,103,103,145,145,145,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,70,70,70,255,255,255,2,2,2,0,0,0,246,246,246,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,255,255,255,103,103,103,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,37,37,37,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,2,2,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,255,255,255,246,246,246,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,246,246,246,246,246,246,103,103,103,255,255,255,178,178,178,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255, + 255,255,145,145,145,255,255,255,37,37,37,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,255,255,255,145,145,145,178,178, + 178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,255,255,255,103,103,103,213,213,213,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,2,2,2,0,0,0,70,70, + 70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,2,2,2,0,0,0,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,255,255,255,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0, + 0,0,0,0,0,103,103,103,103,103,103,0,0,0,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,103,103,103,2,2,2,70,70,70,70,70, + 70,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,70,70,70,0,0,0,178,178,178,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,70,70,70,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,255,255,255,103,103,103,255,255,255,2,2,2,103,103,103,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,213,213,103, + 103,103,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,213,213,213,0,0,0,255,255,255,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,178,178,178,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,103,103,103,0,0,0,246,246,246,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,103,103,103,0,0,0,103,103,103,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,213,213,213,255,255,255,246,246,246,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178, + 178,178,246,246,246,37,37,37,0,0,0,0,0,0,0,0,0,103,103,103,213,213,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,178,178,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,255,255,255,255,255,255,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,178,178,178,255,255,255,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,145,145,145,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,70,70,70,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,2,2,2,0,0,0,70,70,70,70,70,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,246,246,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,103,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,70,70,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; diff --git a/Demos/OpenGL/GLDebugFont.h b/Demos/OpenGL/GLDebugFont.h new file mode 100644 index 0000000..bf2c257 --- /dev/null +++ b/Demos/OpenGL/GLDebugFont.h @@ -0,0 +1,29 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_DEBUG_FONT_H +#define BT_DEBUG_FONT_H + +#include "LinearMath/btVector3.h" + + +void GLDebugDrawStringInternal(int x,int y,const char* string,const btVector3& rgb, bool enableBlend, int spacing); +void GLDebugDrawStringInternal(int x,int y,const char* string,const btVector3& rgb); +void GLDebugDrawString(int x,int y,const char* string); +void GLDebugResetFont(int screenWidth,int screenHeight); + +#endif //BT_DEBUG_FONT_H + diff --git a/Demos/OpenGL/GL_DialogDynamicsWorld.cpp b/Demos/OpenGL/GL_DialogDynamicsWorld.cpp new file mode 100644 index 0000000..08948d2 --- /dev/null +++ b/Demos/OpenGL/GL_DialogDynamicsWorld.cpp @@ -0,0 +1,761 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "GL_DialogDynamicsWorld.h" +#include "GL_DialogWindow.h" +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h" +#include "BulletCollision/CollisionShapes/btBox2dShape.h" +#include "BulletCollision/CollisionShapes/btConvex2dShape.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" + +GL_DialogDynamicsWorld::GL_DialogDynamicsWorld() +{ + m_upperBorder = 0; + m_lowerBorder =0; + + m_pickConstraint = 0; + m_screenWidth = 0; + m_screenHeight = 0; + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_broadphase = new btDbvtBroadphase(); + m_constraintSolver = new btSequentialImpulseConstraintSolver(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_constraintSolver,m_collisionConfiguration); + m_dynamicsWorld ->getSolverInfo().m_splitImpulse = true; + //m_dynamicsWorld->setGravity(btVector3(0,10,0)); + m_dynamicsWorld->setGravity(btVector3(0,0,0)); + + m_simplexSolver = new btVoronoiSimplexSolver(); + m_pdSolver = new btMinkowskiPenetrationDepthSolver(); + + btConvex2dConvex2dAlgorithm::CreateFunc* convexAlgo2d = new btConvex2dConvex2dAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver); + + m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d); + m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d); + m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,convexAlgo2d); + m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,new btBox2dBox2dCollisionAlgorithm::CreateFunc()); + + ///enable boarders, to avoid 'loosing' menus +#if 1 + btTransform tr; + tr.setIdentity(); + + { + btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(0,1,0),0); + m_upperBorder = new btCollisionObject(); + tr.setOrigin(btVector3(0,-BT_LARGE_FLOAT,0)); + m_upperBorder->setWorldTransform(tr); + m_upperBorder->setCollisionShape(plane); + m_dynamicsWorld->addCollisionObject(m_upperBorder); + } + + { + btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(0,-1,0),0); + m_lowerBorder = new btCollisionObject(); + + tr.setIdentity(); + tr.setOrigin(btVector3(0,BT_LARGE_FLOAT,0)); + m_lowerBorder->setWorldTransform(tr); + m_lowerBorder->setCollisionShape(plane); + m_dynamicsWorld->addCollisionObject(m_lowerBorder); + } + { + btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(1,0,0),0); + m_leftBorder = new btCollisionObject(); + tr.setIdentity(); + tr.setOrigin(btVector3(-BT_LARGE_FLOAT,0,0)); + m_leftBorder->setWorldTransform(tr); + m_leftBorder->setCollisionShape(plane); + m_dynamicsWorld->addCollisionObject(m_leftBorder); + } + { + btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(-1,0,0),0); + m_rightBorder = new btCollisionObject(); + tr.setIdentity(); + tr.setOrigin(btVector3(BT_LARGE_FLOAT,0,0)); + m_rightBorder->setWorldTransform(tr); + m_rightBorder->setCollisionShape(plane); + m_dynamicsWorld->addCollisionObject(m_rightBorder); + } +#endif + +} + +GL_DialogDynamicsWorld::~GL_DialogDynamicsWorld() +{ + delete m_dynamicsWorld; + delete m_dispatcher; + delete m_constraintSolver; + delete m_broadphase; + delete m_collisionConfiguration; +} + +void GL_DialogDynamicsWorld::setScreenSize(int width, int height) +{ + + + int i; + + for ( i=0;igetCollisionObjectArray().size();i++) + { + btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(colObj); + if (body) + { + m_dynamicsWorld->removeRigidBody(body); + btVector3 newPos = colObj->getWorldTransform().getOrigin() + btVector3(btScalar(m_screenWidth/2.),btScalar(m_screenHeight/2),btScalar(0))-btVector3(btScalar(width/2.),btScalar(height/2.),btScalar(0)); + colObj->getWorldTransform().setOrigin(newPos); + m_dynamicsWorld->addRigidBody(body); + } else + { + m_dynamicsWorld->removeCollisionObject(colObj); + btVector3 newPos = colObj->getWorldTransform().getOrigin() + btVector3(btScalar(m_screenWidth/2.),btScalar(m_screenHeight/2.),btScalar(0))-btVector3(btScalar(width/2.),btScalar(height/2.),btScalar(0)); + colObj->getWorldTransform().setOrigin(newPos); + m_dynamicsWorld->addCollisionObject(colObj); + } + } + + for ( i=0;isetScreenSize(width,height); + } + if (width && height) + { + if (m_upperBorder) + { + m_dynamicsWorld->removeCollisionObject(m_upperBorder); + + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(0),btScalar(-height/2.),btScalar(0.))); + m_upperBorder->setWorldTransform(tr); + m_dynamicsWorld->addCollisionObject(m_upperBorder); + } + + if (m_lowerBorder) + { + m_dynamicsWorld->removeCollisionObject(m_lowerBorder); + + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(0),btScalar(height/2.),btScalar(0))); + m_lowerBorder->setWorldTransform(tr); + m_dynamicsWorld->addCollisionObject(m_lowerBorder); + } + if (m_leftBorder) + { + m_dynamicsWorld->removeCollisionObject(m_leftBorder); + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(-width/2.),btScalar(0),btScalar(0))); + m_leftBorder->setWorldTransform(tr); + m_dynamicsWorld->addCollisionObject(m_leftBorder); + } + if (m_rightBorder) + { + m_dynamicsWorld->removeCollisionObject(m_rightBorder); + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(btScalar(width/2.),btScalar(0),btScalar(0))); + m_rightBorder->setWorldTransform(tr); + m_dynamicsWorld->addCollisionObject(m_rightBorder); + + } + + } + + + m_screenWidth = width; + m_screenHeight = height; +} + +GL_DialogWindow* GL_DialogDynamicsWorld::createDialog(int horPos,int vertPos,int dialogWidth,int dialogHeight, const char* dialogTitle ) +{ + btBox2dShape* boxShape = new btBox2dShape(btVector3(dialogWidth/2.f,dialogHeight/2.f,0.4f)); + btScalar mass = 100.f; + btVector3 localInertia; + boxShape->calculateLocalInertia(mass,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,boxShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + btTransform trans; + trans.setIdentity(); +// trans.setOrigin(btVector3(btScalar(horPos-m_screenWidth/2+dialogWidth/2), btScalar(vertPos+m_screenHeight/2.+dialogHeight/2),btScalar(0.))); + trans.setOrigin(btVector3(btScalar(horPos-m_screenWidth/2+dialogWidth/2), btScalar(vertPos-m_screenHeight/2.+dialogHeight/2),btScalar(0.))); + + + + body->setWorldTransform(trans); + body->setDamping(0.999f,0.99f); + + //body->setActivationState(ISLAND_SLEEPING); + body->setLinearFactor(btVector3(1,1,0)); + //body->setAngularFactor(btVector3(0,0,1)); + body->setAngularFactor(btVector3(0,0,0)); + + GL_DialogWindow* dialogWindow = new GL_DialogWindow(horPos,vertPos,dialogWidth,dialogHeight,body,dialogTitle); + m_dialogs.push_back(dialogWindow); + m_dynamicsWorld->addRigidBody(body); + + return dialogWindow; + +} + +GL_SliderControl* GL_DialogDynamicsWorld::createSlider(GL_DialogWindow* dialog, const char* sliderText, btScalar initialFraction) +{ + btBox2dShape* boxShape = new btBox2dShape(btVector3(6.f,6.f,0.4f)); + btScalar mass = .1f; + btVector3 localInertia; + boxShape->calculateLocalInertia(mass,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,boxShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + btTransform trans; + trans.setIdentity(); + int sliderX = dialog->getDialogHorPos() - m_screenWidth/2 + dialog->getDialogWidth()/2; +// int sliderY = dialog->getDialogVertPos() + m_screenHeight/2 + dialog->getDialogHeight()/2 + dialog->getNumControls()*20; + int sliderY = dialog->getDialogVertPos() - m_screenHeight/2 + dialog->getDialogHeight()/2 + dialog->getNumControls()*20; + trans.setOrigin(btVector3((btScalar)sliderX, (btScalar)sliderY,(btScalar)-0.2f)); + + body->setWorldTransform(trans); + //body->setDamping(0.999,0.99); + + //body->setActivationState(ISLAND_SLEEPING); + body->setLinearFactor(btVector3(1,1,0)); + //body->setAngularFactor(btVector3(0,0,1)); + body->setAngularFactor(btVector3(0,0,0)); + + m_dynamicsWorld->addRigidBody(body); + body->setCollisionFlags(body->getFlags()|btCollisionObject::CF_NO_CONTACT_RESPONSE); + + btRigidBody* dialogBody = btRigidBody::upcast(dialog->getCollisionObject()); + btAssert(dialogBody); + + + + btTransform frameInA; + frameInA.setIdentity(); + int offsX = -dialog->getDialogWidth()/2 + 16; + int offsY = -dialog->getDialogHeight()/2 + dialog->getNumControls()*20 + 36; + btVector3 offset(btVector3((btScalar)offsX, (btScalar)offsY, (btScalar)0.2f)); + frameInA.setOrigin(offset); + + + btTransform frameInB; + frameInB.setIdentity(); + //frameInB.setOrigin(-offset/2); + +// btScalar lowerLimit = 80.f; +// btScalar upperLimit = 170.f; + btScalar lowerLimit = 141.f; + btScalar upperLimit = 227.f; + + btScalar actualLimit = lowerLimit+initialFraction*(upperLimit-lowerLimit); + + +#if 0 + bool useFrameA = false; + + btGeneric6DofConstraint* constraint = new btGeneric6DofConstraint(*dialogBody,*body,frameInA,frameInB,useFrameA); + m_dynamicsWorld->addConstraint(constraint,true); + constraint->setLimit(0,lowerLimit,upperLimit); +#else + btSliderConstraint* sliderConstraint = new btSliderConstraint(*dialogBody,*body,frameInA,frameInB,true);//useFrameA); + sliderConstraint->setLowerLinLimit(actualLimit); + sliderConstraint->setUpperLinLimit(actualLimit); + m_dynamicsWorld->addConstraint(sliderConstraint,true); + +#endif + + + GL_SliderControl* slider = new GL_SliderControl(sliderText, body,dialog,lowerLimit,upperLimit, sliderConstraint); + body->setUserPointer(slider); + dialog->addControl(slider); + + slider->m_fraction = initialFraction; + + return slider; +} + + + +GL_ToggleControl* GL_DialogDynamicsWorld::createToggle(GL_DialogWindow* dialog, const char* toggleText) +{ + + + btBox2dShape* boxShape = new btBox2dShape(btVector3(6.f,6.f,0.4f)); + btScalar mass = 0.1f; + btVector3 localInertia; + boxShape->calculateLocalInertia(mass,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,boxShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + btTransform trans; + trans.setIdentity(); + + int toggleX = dialog->getDialogHorPos() - m_screenWidth/2 + dialog->getDialogWidth()/2; +// int toggleY = dialog->getDialogVertPos() + m_screenHeight/2 + dialog->getDialogHeight()/2 + dialog->getNumControls()*20; + int toggleY = dialog->getDialogVertPos() - m_screenHeight/2 + dialog->getDialogHeight()/2 + dialog->getNumControls()*20; + trans.setOrigin(btVector3((btScalar)toggleX, (btScalar)toggleY,(btScalar) -0.2f)); + + body->setWorldTransform(trans); + body->setDamping(0.999f,0.99f); + + //body->setActivationState(ISLAND_SLEEPING); + body->setLinearFactor(btVector3(1,1,0)); + //body->setAngularFactor(btVector3(0,0,1)); + body->setAngularFactor(btVector3(0,0,0)); + + m_dynamicsWorld->addRigidBody(body); + body->setCollisionFlags(body->getFlags()|btCollisionObject::CF_NO_CONTACT_RESPONSE); + + btRigidBody* dialogBody = btRigidBody::upcast(dialog->getCollisionObject()); + btAssert(dialogBody); + + + + btTransform frameInA; + frameInA.setIdentity(); + btVector3 offset(btVector3(+dialog->getDialogWidth()/2.f-32.f,-dialog->getDialogHeight()/2.f+dialog->getNumControls()*20.f+36.f,0.2f)); + frameInA.setOrigin(offset); + + + btTransform frameInB; + frameInB.setIdentity(); + //frameInB.setOrigin(-offset/2); + bool useFrameA = true; + + btGeneric6DofConstraint* constraint = new btGeneric6DofConstraint(*dialogBody,*body,frameInA,frameInB,useFrameA); + m_dynamicsWorld->addConstraint(constraint,true); + + + GL_ToggleControl* toggle = new GL_ToggleControl(toggleText, body,dialog); + body->setUserPointer(toggle); + dialog->addControl(toggle); + return toggle; +} + +void GL_DialogDynamicsWorld::draw(btScalar timeStep) +{ + if (timeStep) + { + m_dynamicsWorld->stepSimulation(timeStep); + } + + for (int i=0;idraw(timeStep); + } +} + +static btRigidBody* pickedBody = 0;//for deactivation state +static btScalar mousePickClamping = 111130.f; + +//static int gPickingConstraintId = 0; +static btVector3 gOldPickingPos; +static btVector3 gHitPos(-1,-1,-1); + +static btScalar gOldPickingDist = 0.f; + +bool GL_DialogDynamicsWorld::mouseFunc(int button, int state, int x, int y) +{ + if (state == 0) + { + m_mouseButtons |= 1<rayTest(m_cameraPosition,rayTo,rayCallback); + if (rayCallback.hasHit()) + { + + btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); + if (body) + { + body->setActivationState(ACTIVE_TAG); + btVector3 impulse = rayTo; + impulse.normalize(); + float impulseStrength = 10.f; + impulse *= impulseStrength; + btVector3 relPos = rayCallback.m_hitPointWorld - body->getCenterOfMassPosition(); + body->applyImpulse(impulse,relPos); + } + } + } +#endif + + + + } else + { + + } + break; + } + + case 0: + { + if (state==0) + { + + + //add a point to point constraint for picking + if (m_dynamicsWorld) + { + + btVector3 rayFrom; + if (1)//m_ortho) + { + rayFrom = rayTo; + rayFrom.setZ(-100.f); + } + //else + //{ + // rayFrom = m_cameraPosition; + //} + + btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo); + m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback); + if (rayCallback.hasHit()) + { + + + btScalar maxPickingClamp = mousePickClamping; + + btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject); + if (body) + { + bool doPick = true; + if (body->getUserPointer()) + { + ///deal with controls in a special way + GL_DialogControl* ctrl = (GL_DialogControl*)body->getUserPointer(); + + switch(ctrl->getType()) + { + case GL_TOGGLE_CONTROL: + { + GL_ToggleControl* toggle = (GL_ToggleControl*) ctrl; + toggle->m_active = !toggle->m_active; + doPick = false; + break; + } + case GL_SLIDER_CONTROL: + { + GL_SliderControl* slider = (GL_SliderControl*) ctrl; + btTypedConstraint* constraint = slider->getConstraint(); + if (constraint->getConstraintType() == SLIDER_CONSTRAINT_TYPE) + { + btSliderConstraint* sliderConstraint = (btSliderConstraint*) constraint; + sliderConstraint->setLowerLinLimit(slider->getLowerLimit()); + sliderConstraint->setUpperLinLimit(slider->getUpperLimit()); + } + maxPickingClamp = 100; + } + default: + { + } + }; + + }; + + if (doPick) + { + //other exclusions? + if (!(body->isStaticObject() || body->isKinematicObject())) + { + pickedBody = body; + pickedBody->setActivationState(DISABLE_DEACTIVATION); + + + + btVector3 pickPos = rayCallback.m_hitPointWorld; + //printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ()); + + + btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; + + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot); + p2p->m_setting.m_impulseClamp = maxPickingClamp; + + m_dynamicsWorld->addConstraint(p2p); + m_pickConstraint = p2p; + + //save mouse position for dragging + gOldPickingPos = rayTo; + gHitPos = pickPos; + + gOldPickingDist = (pickPos-rayFrom).length(); + + //very weak constraint for picking + p2p->m_setting.m_tau = 0.1f; + } + } + return true; + } + } + } + + } else + { + + if (m_pickConstraint && m_dynamicsWorld) + { + m_dynamicsWorld->removeConstraint(m_pickConstraint); + delete m_pickConstraint; + //printf("removed constraint %i",gPickingConstraintId); + m_pickConstraint = 0; + pickedBody->forceActivationState(ACTIVE_TAG); + pickedBody->setDeactivationTime( 0.f ); + + + if (pickedBody->getUserPointer()) + { + ///deal with controls in a special way + GL_DialogControl* ctrl = (GL_DialogControl*)pickedBody->getUserPointer(); + if (ctrl->getType()==GL_SLIDER_CONTROL) + { + GL_SliderControl* sliderControl = (GL_SliderControl*) ctrl; + + btSliderConstraint* slider = 0; + btTypedConstraint* constraint = sliderControl->getConstraint(); + if (constraint->getConstraintType() == SLIDER_CONSTRAINT_TYPE) + { + slider = (btSliderConstraint*)constraint; + } + if (slider) + { + btScalar linDepth = slider->getLinearPos(); + btScalar lowLim = slider->getLowerLinLimit(); + btScalar hiLim = slider->getUpperLinLimit(); + slider->setPoweredLinMotor(false); + if(linDepth <= lowLim) + { + slider->setLowerLinLimit(lowLim); + slider->setUpperLinLimit(lowLim); + } + else if(linDepth > hiLim) + { + slider->setLowerLinLimit(hiLim); + slider->setUpperLinLimit(hiLim); + } + else + { + slider->setLowerLinLimit(linDepth); + slider->setUpperLinLimit(linDepth); + } + } + } + + } + + pickedBody = 0; + + } + + + + } + + break; + + } + + default: + { + } + } + + return false; + +} + + + +btVector3 GL_DialogDynamicsWorld::getRayTo(int x,int y) +{ + float cameraDistance = m_screenHeight/2.f;//m_screenWidth/2;//1.f; + btVector3 cameraTargetPosition(0,0,0); + btVector3 cameraUp(0,-1,0); + + if (1)//_ortho) + { + + btScalar aspect; + btVector3 extents; + if (m_screenWidth> m_screenHeight) + { + + aspect = m_screenWidth / (btScalar)m_screenHeight; + extents.setValue(aspect * 1.0f, 1.0f,0); + } else + { + cameraDistance = m_screenWidth/2.f; + aspect = m_screenHeight / (btScalar)m_screenWidth; + extents.setValue(1.0f, aspect*1.f,0); + } + + + + extents *= cameraDistance; + btVector3 lower = cameraTargetPosition - extents; + btVector3 upper = cameraTargetPosition + extents; + + btScalar u = x / btScalar(m_screenWidth); + btScalar v = (m_screenHeight - y) / btScalar(m_screenHeight); + + btVector3 p(0,0,0); + p.setValue( + (1.0f - u) * lower.getX() + u * upper.getX(), + -((1.0f - v) * lower.getY() + v * upper.getY()), + cameraTargetPosition.getZ()); + return p; + } + + float top = 1.f; + float bottom = -1.f; + float nearPlane = 1.f; + float tanFov = (top-bottom)*0.5f / nearPlane; + float fov = 2 * atanf (tanFov); + + btVector3 cameraPosition(0,0,-100); + btVector3 rayFrom = cameraPosition; + btVector3 rayForward = (cameraTargetPosition-cameraPosition); + rayForward.normalize(); + float farPlane = 10000.f; + rayForward*= farPlane; + + btVector3 rightOffset; + btVector3 vertical = cameraUp; + + btVector3 hor; + hor = rayForward.cross(vertical); + hor.normalize(); + vertical = hor.cross(rayForward); + vertical.normalize(); + + float tanfov = tanf(0.5f*fov); + + + hor *= 2.f * farPlane * tanfov; + vertical *= 2.f * farPlane * tanfov; + + btScalar aspect; + + if (m_screenWidth > m_screenHeight) + { + aspect = m_screenWidth / (btScalar)m_screenHeight; + + hor*=aspect; + } else + { + aspect = m_screenHeight / (btScalar)m_screenWidth; + vertical*=aspect; + } + + + btVector3 rayToCenter = rayFrom + rayForward; + btVector3 dHor = hor * 1.f/float(m_screenWidth); + btVector3 dVert = vertical * 1.f/float(m_screenHeight); + + + btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; + rayTo += btScalar(x) * dHor; + rayTo -= btScalar(y) * dVert; + //rayTo += y * dVert; + + return rayTo; +} + + + +void GL_DialogDynamicsWorld::mouseMotionFunc(int x,int y) +{ + + if (m_pickConstraint) + { + //move the constraint pivot + btPoint2PointConstraint* p2p = static_cast(m_pickConstraint); + if (p2p) + { + //keep it at the same picking distance + + btVector3 newRayTo = getRayTo(x,y); + btVector3 rayFrom; + btVector3 oldPivotInB = p2p->getPivotInB(); + btVector3 newPivotB; + if (1)//_ortho) + { + newPivotB = oldPivotInB; + newPivotB.setX(newRayTo.getX()); + newPivotB.setY(newRayTo.getY()); + } else + { + //rayFrom = m_cameraPosition; + // btVector3 dir = newRayTo-rayFrom; + // dir.normalize(); + // dir *= gOldPickingDist; + + // newPivotB = rayFrom + dir; + } + + + + p2p->setPivotB(newPivotB); + } + + } + + btScalar dx, dy; + dx = btScalar(x) - m_mouseOldX; + dy = btScalar(y) - m_mouseOldY; + + + + + m_mouseOldX = x; + m_mouseOldY = y; +// updateCamera(); + + +} + + diff --git a/Demos/OpenGL/GL_DialogDynamicsWorld.h b/Demos/OpenGL/GL_DialogDynamicsWorld.h new file mode 100644 index 0000000..8292ae4 --- /dev/null +++ b/Demos/OpenGL/GL_DialogDynamicsWorld.h @@ -0,0 +1,91 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef GL_DIALOG_DYNAMICS_WORLD_H +#define GL_DIALOG_DYNAMICS_WORLD_H + +class btDiscreteDynamicsWorld; +class GL_DialogWindow; +class btDefaultCollisionConfiguration; +struct btDbvtBroadphase; +class btSequentialImpulseConstraintSolver; +class btCollisionDispatcher; +class btVoronoiSimplexSolver; +class btMinkowskiPenetrationDepthSolver; +class btCollisionObject; +class btTypedConstraint; +struct GL_ToggleControl; +struct GL_SliderControl; + + +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btVector3.h" + +class GL_DialogDynamicsWorld +{ + + btDefaultCollisionConfiguration* m_collisionConfiguration; + btDbvtBroadphase* m_broadphase; + btSequentialImpulseConstraintSolver* m_constraintSolver; + btCollisionDispatcher* m_dispatcher; + btVoronoiSimplexSolver* m_simplexSolver; + btMinkowskiPenetrationDepthSolver* m_pdSolver; + + btDiscreteDynamicsWorld* m_dynamicsWorld; + + btCollisionObject* m_lowerBorder; + btCollisionObject* m_upperBorder; + btCollisionObject* m_leftBorder; + btCollisionObject* m_rightBorder; + + btAlignedObjectArray m_dialogs; + + int m_screenWidth; + int m_screenHeight; + + + ///for picking + int m_mouseOldX; + int m_mouseOldY; + int m_mouseButtons; + ///constraint for mouse picking + btTypedConstraint* m_pickConstraint; + + btVector3 getRayTo(int x,int y); + +public: + + GL_DialogDynamicsWorld(); + + virtual ~GL_DialogDynamicsWorld(); + + virtual void setScreenSize(int width, int height); + + virtual GL_DialogWindow* createDialog(int horPos,int vertPos,int dialogWidth,int dialogHeight, const char* dialogTitle ); + + GL_ToggleControl* createToggle(GL_DialogWindow* dialog, const char* toggleText); + + GL_SliderControl* createSlider(GL_DialogWindow* dialog, const char* sliderText, btScalar initialFraction = btScalar(0.5f)); + + virtual void draw(btScalar timeStep); + + virtual bool mouseFunc(int button, int state, int x, int y); + + virtual void mouseMotionFunc(int x,int y); + +}; + +#endif //GL_DIALOG_DYNAMICS_WORLD_H diff --git a/Demos/OpenGL/GL_DialogWindow.cpp b/Demos/OpenGL/GL_DialogWindow.cpp new file mode 100644 index 0000000..b3ecae8 --- /dev/null +++ b/Demos/OpenGL/GL_DialogWindow.cpp @@ -0,0 +1,358 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "GL_DialogWindow.h" + + + +#include "GLDebugFont.h" +#include "btBulletDynamicsCommon.h" + +#include // for sprintf() + +#define USE_ARRAYS 1 + + +GL_DialogWindow::GL_DialogWindow(int horPos,int vertPos,int dialogWidth,int dialogHeight, btCollisionObject* collisionObject,const char* dialogTitle) +:m_dialogHorPos(horPos), +m_dialogVertPos(vertPos), +m_dialogWidth(dialogWidth), +m_dialogHeight(dialogHeight), +m_screenWidth(0), +m_screenHeight(0), +m_dialogTitle(dialogTitle), +m_MaxClipPlanes(-1), +m_collisionObject(collisionObject) + +{ +} + +void GL_DialogWindow::setScreenSize(int width, int height) +{ + m_screenWidth = width; + m_screenHeight = height; +} +GL_DialogWindow::~GL_DialogWindow() +{ + +} + + + +static void drawLine(int _X0, int _Y0, int _X1, int _Y1, unsigned int _Color0, unsigned int _Color1) +{ + const GLfloat dx = +0.5f; + const GLfloat dy = -0.5f; + + GLfloat vVertices[] = {(GLfloat)_X0+dx,(GLfloat)_Y0+dy,(GLfloat)_X1+dx,(GLfloat)_Y1+dy}; + + bool antiAliased = false; + if( antiAliased ) + glEnable(GL_LINE_SMOOTH); + else + glDisable(GL_LINE_SMOOTH); + glDisable(GL_TEXTURE_2D); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + +#ifdef USE_ARRAYS + glColor4ub(GLubyte(_Color0>>16), GLubyte(_Color0>>8), GLubyte(_Color0), GLubyte(_Color0>>24)); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glLineWidth(2.0f); + glVertexPointer(2, GL_FLOAT, 0, vVertices); + glEnableClientState(GL_VERTEX_ARRAY); + glDrawArrays(GL_LINES,0,2); +#else + glLineWidth(13.0f); + glBegin(GL_LINES); + glColor4ub(GLubyte(_Color0>>16), GLubyte(_Color0>>8), GLubyte(_Color0), GLubyte(_Color0>>24)); + glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy); + glColor4ub(GLubyte(_Color1>>16), GLubyte(_Color1>>8), GLubyte(_Color1), GLubyte(_Color1>>24)); + glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy); + glEnd(); +#endif + glDisable(GL_LINE_SMOOTH); +} + +static void drawRect(int horStart, int vertStart, int horEnd, int vertEnd, unsigned int argbColor00,unsigned int argbColor10,unsigned int argbColor01,unsigned int argbColor11) +{ + float dx = 0; + float dy = 0; + glDisable(GL_TEXTURE_2D); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +#ifdef USE_ARRAYS + GLfloat verts[] ={ + 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + 0.f,0.f,0.f + }; + + glColor4ub(GLubyte(argbColor00>>16), GLubyte(argbColor00>>8), GLubyte(argbColor00), GLubyte(argbColor00>>24)); + verts[0] = (GLfloat)horStart+dx; verts[1] = (GLfloat)vertStart+dy; + verts[2] = (GLfloat)horEnd+dx; verts[3] = (GLfloat)vertStart+dy; + verts[4] = (GLfloat)horEnd+dx; verts[5] = (GLfloat)vertEnd+dy; + verts[6] = (GLfloat)horStart+dx; verts[7] = (GLfloat)vertEnd+dy; + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState (GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, verts); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + +#else + glBegin(GL_QUADS); + glColor4ub(GLubyte(argbColor00>>16), GLubyte(argbColor00>>8), GLubyte(argbColor00), GLubyte(argbColor00>>24)); + glVertex2f((GLfloat)horStart+dx, (GLfloat)vertStart+dy); + glColor4ub(GLubyte(argbColor10>>16), GLubyte(argbColor10>>8), GLubyte(argbColor10), GLubyte(argbColor10>>24)); + glVertex2f((GLfloat)horEnd+dx, (GLfloat)vertStart+dy); + glColor4ub(GLubyte(argbColor11>>16), GLubyte(argbColor11>>8), GLubyte(argbColor11), GLubyte(argbColor11>>24)); + glVertex2f((GLfloat)horEnd+dx, (GLfloat)vertEnd+dy); + glColor4ub(GLubyte(argbColor01>>16), GLubyte(argbColor01>>8), GLubyte(argbColor01), GLubyte(argbColor01>>24)); + glVertex2f((GLfloat)horStart+dx, (GLfloat)vertEnd+dy); + glEnd(); +#endif + +} + +void GL_DialogWindow::draw(btScalar deltaTime) +{ + if (!m_screenWidth || !m_screenHeight) + return; + + m_dialogHorPos = int(m_collisionObject->getWorldTransform().getOrigin()[0]+m_screenWidth/2.f-m_dialogWidth/2.f); + + m_dialogVertPos = int(m_collisionObject->getWorldTransform().getOrigin()[1]+m_screenHeight/2.f-m_dialogHeight/2.f); + saveOpenGLState(); + + //drawRect(m_dialogHorPos,m_dialogVertPos,m_dialogHorPos+m_dialogWidth,m_dialogVertPos+m_dialogHeight,0xa6000000); + unsigned int argbColor = 0x86000000; + int charHeight = 16; + int charWidth = 10; + + int titleHeight = charHeight + 2; + + drawRect(m_dialogHorPos,m_dialogVertPos,m_dialogHorPos+m_dialogWidth-1,m_dialogVertPos+titleHeight,argbColor,argbColor,argbColor,argbColor); + //const unsigned int COL0 = 0x50ffffff; + const unsigned int COL0 = 0xffffffff; + const unsigned int COL1 = 0xff1f1f1f; + + drawRect(m_dialogHorPos,m_dialogVertPos,m_dialogHorPos+m_dialogWidth-1,m_dialogVertPos+1,COL0,COL0,COL1,COL1); + + argbColor = 0x864f4f4f; + drawRect(m_dialogHorPos+1,m_dialogVertPos+titleHeight,m_dialogHorPos+m_dialogWidth-1,m_dialogVertPos+m_dialogHeight,argbColor,argbColor,argbColor,argbColor); + + + int y = m_dialogVertPos+charHeight+1; + glLineWidth(3); + drawLine(m_dialogHorPos, y, m_dialogHorPos+m_dialogWidth-1, y, 0x80afafaf,0x80afafaf); + + + + unsigned int clight = 0x5FFFFFFF; // bar contour + drawLine(m_dialogHorPos, m_dialogVertPos, m_dialogHorPos, m_dialogVertPos+m_dialogHeight, clight,clight); + drawLine(m_dialogHorPos, m_dialogVertPos, m_dialogHorPos+m_dialogWidth, m_dialogVertPos, clight,clight); + drawLine(m_dialogHorPos+m_dialogWidth, m_dialogVertPos, m_dialogHorPos+m_dialogWidth, m_dialogVertPos+m_dialogHeight, clight,clight); + drawLine(m_dialogHorPos, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+m_dialogWidth, m_dialogVertPos+m_dialogHeight, clight,clight); + int dshad = 3; // bar shadows + + unsigned int cshad = (((0x40000000>>24)/2)<<24) & 0xFF000000; + drawRect(m_dialogHorPos, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+dshad, m_dialogVertPos+m_dialogHeight+dshad, 0, cshad, 0, 0); + drawRect(m_dialogHorPos+dshad+1, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+m_dialogWidth-1, m_dialogVertPos+m_dialogHeight+dshad, cshad, cshad, 0, 0); + drawRect(m_dialogHorPos+m_dialogWidth, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+m_dialogWidth+dshad, m_dialogVertPos+m_dialogHeight+dshad, cshad, 0, 0, 0); + drawRect(m_dialogHorPos+m_dialogWidth, m_dialogVertPos, m_dialogHorPos+m_dialogWidth+dshad, m_dialogVertPos+dshad, 0, 0, cshad, 0); + drawRect(m_dialogHorPos+m_dialogWidth, m_dialogVertPos+dshad+1, m_dialogHorPos+m_dialogWidth+dshad, m_dialogVertPos+m_dialogHeight-1, cshad, 0, cshad, 0); + + int yInc = 16; + int curHorPos = m_dialogHorPos+5; + int curVertPos = m_dialogVertPos; + curVertPos += yInc; + + GLDebugDrawString(m_dialogHorPos+m_dialogWidth/2-((int(strlen(m_dialogTitle)/2))*charWidth),m_dialogVertPos+yInc ,m_dialogTitle); + curVertPos += 20; + + + for (int i=0;idraw(curHorPos,curVertPos,deltaTime); + } + + restoreOpenGLState(); +} + + +void GL_DialogWindow::saveOpenGLState() +{ +#if 0 + glPushAttrib(GL_ALL_ATTRIB_BITS); + glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); +#endif + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + GLint Vp[4]; + glGetIntegerv(GL_VIEWPORT, Vp); + + if( m_screenWidth>0 && m_screenHeight>0 ) + { + Vp[0] = 0; + Vp[1] = 0; + Vp[2] = m_screenWidth-1; + Vp[3] = m_screenHeight-1; + glViewport(Vp[0], Vp[1], Vp[2], Vp[3]); + } + glLoadIdentity(); + glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1); + glGetIntegerv(GL_VIEWPORT, m_ViewportInit); + glGetFloatv(GL_PROJECTION_MATRIX, m_ProjMatrixInit); + + glGetFloatv(GL_LINE_WIDTH, &m_PrevLineWidth); + // glDisable(GL_POLYGON_STIPPLE); + glLineWidth(1); + + glDisable(GL_LINE_SMOOTH); +// glDisable(GL_LINE_STIPPLE); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glEnable(GL_BLEND); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &m_PrevTexEnv); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_TEXTURE_2D); + +} + +void GL_DialogWindow::restoreOpenGLState() +{ + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_PrevTexEnv); + glLineWidth(m_PrevLineWidth); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glPopClientAttrib(); + glPopAttrib(); + +} + + +void GL_TextControl::draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime) +{ + for (int i=0;igetWorldTransform().getOrigin()[0]+m_parentWindow->getScreenWidth()/2); + int controlVertPos = int(m_toggleBody->getWorldTransform().getOrigin()[1]+m_parentWindow->getScreenHeight()/2); + + int parentHorPos = controlHorPos-8; + int parentVertPos = controlVertPos-8; + + unsigned int grey = 0xff6f6f6f; + + drawRect(parentHorPos, parentVertPos, parentHorPos+16, parentVertPos+16, grey, grey, grey, grey); + + int borderSize = 2; + unsigned int white = 0xffefefef; + drawRect(parentHorPos+borderSize, parentVertPos+borderSize, parentHorPos+16-borderSize, parentVertPos+16-borderSize, white,white,white,white); + + + if (m_active) + { + //unsigned int red = 0xff8f0000; + // unsigned int white = 0xff8f0000; + unsigned int black = 0xff1f1f1f; + borderSize = 4; + drawRect(parentHorPos+borderSize, parentVertPos+borderSize, parentHorPos+16-borderSize, parentVertPos+16-borderSize, black,black,black,black); + } + + btVector3 rgb(1,1,1); + + GLDebugDrawStringInternal(parentHorPos2,parentVertPos+16,m_toggleText,rgb); + parentVertPos2+=20; + +} + +void GL_SliderControl::draw(int& parentHorPos2,int& parentVertPos2,btScalar deltaTime) +{ + + int controlHorPos = int(m_sliderBody->getWorldTransform().getOrigin()[0]+m_parentWindow->getScreenWidth()/2); + int controlVertPos = int(m_sliderBody->getWorldTransform().getOrigin()[1]+m_parentWindow->getScreenHeight()/2); + + int parentHorPos = controlHorPos-8; + int parentVertPos = controlVertPos-8; + + unsigned int grey = 0xff6f6f6f; + int borderSize = 2; + unsigned int white = 0xffefefef; + int sliderPosS = parentHorPos2+150+borderSize; + int sliderPosE = parentHorPos2+m_parentWindow->getDialogWidth()-40-borderSize; + int sliderPos = controlHorPos; + if(sliderPos < sliderPosS) sliderPos = sliderPosS; + if(sliderPos > sliderPosE) sliderPos = sliderPosE; +// drawRect(parentHorPos2+80+borderSize, parentVertPos2+borderSize, parentHorPos2+m_parentWindow->getDialogWidth()-16-borderSize, parentVertPos2+2-borderSize, white,white,white,white); + drawRect( sliderPosS, + parentVertPos2+borderSize, + sliderPosE, + parentVertPos2+2-borderSize, + white,white,white,white); + + drawRect(parentHorPos, parentVertPos, parentHorPos+16, parentVertPos+16, grey, grey, grey, grey); + + + + drawRect(parentHorPos+borderSize, parentVertPos+borderSize, parentHorPos+16-borderSize, parentVertPos+16-borderSize, white,white,white,white); + + + + btVector3 rgb(1,1,1); + +// btSliderConstraint* pSlider = (btSliderConstraint*)m_constraint; +// btScalar currPos = pSlider->getLinearPos(); +// if(currPos < pSlider->getLowerLinLimit()) currPos = pSlider->getLowerLinLimit(); +// if(currPos > pSlider->getUpperLinLimit()) currPos = pSlider->getUpperLinLimit(); +// m_fraction = (currPos - pSlider->getLowerLinLimit()) / (pSlider->getUpperLinLimit() - pSlider->getLowerLinLimit()); + m_fraction = (btScalar)(sliderPos - sliderPosS) / (btScalar)(sliderPosE - sliderPosS); + + char tmpBuf[256]; + sprintf(tmpBuf, "%s %3d%%", m_sliderText, (int)(m_fraction * 100.f)); + +// GLDebugDrawStringInternal(parentHorPos2,parentVertPos2+8,m_sliderText,rgb); + GLDebugDrawStringInternal(parentHorPos2,parentVertPos2+8, tmpBuf, rgb); + parentVertPos2+=20; + +} diff --git a/Demos/OpenGL/GL_DialogWindow.h b/Demos/OpenGL/GL_DialogWindow.h new file mode 100644 index 0000000..75cb04e --- /dev/null +++ b/Demos/OpenGL/GL_DialogWindow.h @@ -0,0 +1,285 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef GL_DIALOG_WINDOW_H +#define GL_DIALOG_WINDOW_H + +class btCollisionObject; + + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#if (defined (TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined (TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR) +#import +#define glOrtho glOrthof +#else +#include +#include +#include +#endif +#else + + +#ifdef _WIN32 +#include +#include +#include +#else +#include +#include +#endif +#endif + + +#include "LinearMath/btScalar.h" +#include "LinearMath/btAlignedObjectArray.h" +class btTypedConstraint; + +class GL_DialogWindow; + +enum GL_DIALOG_CONTROL_TYPES +{ + GL_TEXT_CONTROL=1, + GL_TOGGLE_CONTROL, + GL_SLIDER_CONTROL, + GL_CONTROL_MAX_TYPE +}; + +class GL_DialogControl +{ +protected: + int m_type; + +public: + + virtual ~GL_DialogControl() + { + } + virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime)=0; + + int getType() const + { + return m_type; + } +}; + +struct GL_TextControl : public GL_DialogControl +{ +public: + + btAlignedObjectArray m_textLines; + + GL_TextControl() + { + m_type = GL_TEXT_CONTROL; + } + + virtual ~GL_TextControl() {} + + virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime); +}; + + +struct GL_ToggleControl : public GL_DialogControl +{ + btCollisionObject* m_toggleBody; + GL_DialogWindow* m_parentWindow; + + const char* m_toggleText; + +public: + + bool m_active; + + + GL_ToggleControl(const char* toggleText,btCollisionObject* toggleBody, GL_DialogWindow* parentWindow) + :m_toggleBody(toggleBody), + m_parentWindow(parentWindow), + m_toggleText(toggleText), + m_active(false) + { + m_type = GL_TOGGLE_CONTROL; + } + + virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime); +}; + +struct GL_SliderControl : public GL_DialogControl +{ + btCollisionObject* m_sliderBody; + GL_DialogWindow* m_parentWindow; + btScalar m_lowerLimit; + btScalar m_upperLimit; + btTypedConstraint* m_constraint; + btScalar m_fraction; + + const char* m_sliderText; +public: + + GL_SliderControl(const char* sliderText,btCollisionObject* sliderBody, GL_DialogWindow* parentWindow, btScalar lowerLimit,btScalar upperLimit,btTypedConstraint* constaint) + :m_sliderBody(sliderBody), + m_parentWindow(parentWindow), + m_lowerLimit(lowerLimit), + m_upperLimit(upperLimit), + m_constraint(constaint), + m_sliderText(sliderText) + { + m_type = GL_SLIDER_CONTROL; + } + + virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime); + + btScalar btGetFraction() { return m_fraction; } + + btScalar getLowerLimit() + { + return m_lowerLimit; + } + btScalar getUpperLimit() + { + return m_upperLimit; + } + btTypedConstraint* getConstraint() + { + return m_constraint; + } +}; + +///Very basic OpenGL Graphical Userinterface Window with text, toggle, slider control +class GL_DialogWindow +{ + + int m_dialogHorPos; + int m_dialogVertPos; + int m_dialogWidth; + int m_dialogHeight; + + int m_screenWidth; + int m_screenHeight; + + const char* m_dialogTitle; + + //saved OpenGL settings + GLfloat m_PrevLineWidth; + GLint m_PrevTexEnv; + GLint m_PrevPolygonMode[2]; + GLint m_MaxClipPlanes; + GLint m_PrevTexture; + GLint m_PrevArrayBufferARB; + GLint m_PrevElementArrayBufferARB; + GLboolean m_PrevVertexProgramARB; + GLboolean m_PrevFragmentProgramARB; + GLuint m_PrevProgramObjectARB; + GLboolean m_PrevTexture3D; + GLboolean m_PrevActiveTexture1D[32]; + GLboolean m_PrevActiveTexture2D[32]; + GLboolean m_PrevActiveTexture3D[32]; + GLint m_PrevActiveTextureARB; + bool m_SupportTexRect; + GLboolean m_PrevTexRectARB; + GLint m_PrevBlendEquation; + GLint m_PrevBlendEquationRGB; + GLint m_PrevBlendEquationAlpha; + GLint m_PrevBlendSrcRGB; + GLint m_PrevBlendDstRGB; + GLint m_PrevBlendSrcAlpha; + GLint m_PrevBlendDstAlpha; + GLint m_ViewportInit[4]; + GLfloat m_ProjMatrixInit[16]; + + btCollisionObject* m_collisionObject; + + btAlignedObjectArray m_controls; + +protected: + + + void saveOpenGLState(); + void restoreOpenGLState(); + +// void drawLine(int _X0, int _Y0, int _X1, int _Y1, unsigned int _Color0, unsigned int _Color1, bool antiAliased); +// void drawRect(int horStart, int vertStart, int horEnd, int vertEnd, unsigned int argbColor00,unsigned int argbColor10,unsigned int argbColor01,unsigned int argbColor11); + +public: + + + GL_DialogWindow(int horPos,int vertPos,int dialogWidth,int dialogHeight,btCollisionObject* colObject, const char* dialogTitle); + + virtual ~GL_DialogWindow(); + + void draw(btScalar deltaTime); + + void setScreenSize(int width, int height); + + void setStartPosition(int dialogHorPos,int dialogVertPos); + + void addControl(GL_DialogControl* control) + { + m_controls.push_back(control); + } + + void removeControl(GL_DialogControl* control) + { + m_controls.remove(control); + } + + btCollisionObject* getCollisionObject() + { + return m_collisionObject; + } + + int getDialogHorPos() const + { + return m_dialogHorPos; + } + int getDialogVertPos() const + { + return m_dialogVertPos; + } + int getDialogWidth() const + { + return m_dialogWidth; + } + + int getDialogHeight() const + { + return m_dialogHeight; + } + int getScreenWidth() const + { + return m_screenWidth; + } + int getScreenHeight() const + { + return m_screenHeight; + } + + int getNumControls() const + { + return m_controls.size(); + } + + const GL_DialogControl* getControl(int index) const + { + return m_controls[index]; + } + GL_DialogControl* getControl(int index) + { + return m_controls[index]; + } +}; + +#endif //GL_DIALOG_WINDOW_H diff --git a/Demos/OpenGL/GL_ShapeDrawer.cpp b/Demos/OpenGL/GL_ShapeDrawer.cpp new file mode 100644 index 0000000..f9acd12 --- /dev/null +++ b/Demos/OpenGL/GL_ShapeDrawer.cpp @@ -0,0 +1,987 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifdef _WIN32 //needed for glut.h +#include +#endif +#include "GLDebugFont.h" + + + +#include "GlutStuff.h" +#include "GL_ShapeDrawer.h" +#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" +#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btConeShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btUniformScalingShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h" + +/// +#include "BulletCollision/CollisionShapes/btShapeHull.h" + +#include "LinearMath/btTransformUtil.h" + + +#include "LinearMath/btIDebugDraw.h" +//for debugmodes + +#include //printf debugging + +//#define USE_DISPLAY_LISTS 1 +#ifdef USE_DISPLAY_LISTS + +#include + +using namespace std; + +//Set for storing Display list per trimesh +struct TRIMESH_KEY +{ + btCollisionShape* m_shape; + GLuint m_dlist;//OpenGL display list +}; + +typedef map TRIMESH_KEY_MAP; + +typedef pair TRIMESH_KEY_PAIR; + +TRIMESH_KEY_MAP g_display_lists; + +class GlDisplaylistDrawcallback : public btTriangleCallback +{ +public: + + virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex) + { + + btVector3 diff1 = triangle[1] - triangle[0]; + btVector3 diff2 = triangle[2] - triangle[0]; + btVector3 normal = diff1.cross(diff2); + + normal.normalize(); + + glBegin(GL_TRIANGLES); + glColor3f(1, 1, 1); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + + //glColor3f(0, 1, 0); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + + //glColor3f(0, 1, 0); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glEnd(); + + /*glBegin(GL_LINES); + glColor3f(1, 1, 0); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glColor3f(1, 1, 0); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glColor3f(1, 1, 0); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glNormal3d(normal.getX(),normal.getY(),normal.getZ()); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glEnd();*/ + + + } +}; + +GLuint OGL_get_displaylist_for_shape(btCollisionShape * shape) +{ + TRIMESH_KEY_MAP::iterator map_iter; + + unsigned long key = (unsigned long)shape; + map_iter = g_display_lists.find(key); + if(map_iter!=g_display_lists.end()) + { + return map_iter->second.m_dlist; + } + + return 0; +} + +void OGL_displaylist_clean() +{ + TRIMESH_KEY_MAP::iterator map_iter,map_itend; + + map_iter = g_display_lists.begin(); + + while(map_iter!=map_itend) + { + glDeleteLists(map_iter->second.m_dlist,1); + map_iter++; + } + + g_display_lists.clear(); +} + + +void OGL_displaylist_register_shape(btCollisionShape * shape) +{ + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + btVector3 aabbMin(-btScalar(BT_LARGE_FLOAT),-btScalar(BT_LARGE_FLOAT),-btScalar(BT_LARGE_FLOAT)); + GlDisplaylistDrawcallback drawCallback; + TRIMESH_KEY dlist; + + dlist.m_dlist = glGenLists(1); + dlist.m_shape = shape; + + unsigned long key = (unsigned long)shape; + + g_display_lists.insert(TRIMESH_KEY_PAIR(key,dlist)); + + glNewList(dlist.m_dlist,GL_COMPILE); + +// glEnable(GL_CULL_FACE); + + glCullFace(GL_BACK); + + if (shape->isConcave()) + { + btConcaveShape* concaveMesh = (btConcaveShape*) shape; + //todo pass camera, for some culling + concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); + } + +// glDisable(GL_CULL_FACE); + + glEndList(); +} +#endif //USE_DISPLAY_LISTS + +void GL_ShapeDrawer::drawCoordSystem() { + glBegin(GL_LINES); + glColor3f(1, 0, 0); + glVertex3d(0, 0, 0); + glVertex3d(1, 0, 0); + glColor3f(0, 1, 0); + glVertex3d(0, 0, 0); + glVertex3d(0, 1, 0); + glColor3f(0, 0, 1); + glVertex3d(0, 0, 0); + glVertex3d(0, 0, 1); + glEnd(); + +} + + + + + +class GlDrawcallback : public btTriangleCallback +{ + +public: + + bool m_wireframe; + + GlDrawcallback() + :m_wireframe(false) + { + } + + virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex) + { + + (void)triangleIndex; + (void)partId; + + + if (m_wireframe) + { + glBegin(GL_LINES); + glColor3f(1, 0, 0); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glColor3f(0, 1, 0); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glColor3f(0, 0, 1); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glEnd(); + } else + { + glBegin(GL_TRIANGLES); + //glColor3f(1, 1, 1); + + + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glEnd(); + } + } +}; + +class TriangleGlDrawcallback : public btInternalTriangleIndexCallback +{ +public: + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + (void)triangleIndex; + (void)partId; + + + glBegin(GL_TRIANGLES);//LINES); + glColor3f(1, 0, 0); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glColor3f(0, 1, 0); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); + glColor3f(0, 0, 1); + glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); + glEnd(); + } +}; + + +void GL_ShapeDrawer::drawSphere(btScalar radius, int lats, int longs) +{ + int i, j; + for(i = 0; i <= lats; i++) { + btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats); + btScalar z0 = radius*sin(lat0); + btScalar zr0 = radius*cos(lat0); + + btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats); + btScalar z1 = radius*sin(lat1); + btScalar zr1 = radius*cos(lat1); + + glBegin(GL_QUAD_STRIP); + for(j = 0; j <= longs; j++) { + btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs; + btScalar x = cos(lng); + btScalar y = sin(lng); + glNormal3f(x * zr1, y * zr1, z1); + glVertex3f(x * zr1, y * zr1, z1); + glNormal3f(x * zr0, y * zr0, z0); + glVertex3f(x * zr0, y * zr0, z0); + } + glEnd(); + } +} + +void GL_ShapeDrawer::drawCylinder(float radius,float halfHeight, int upAxis) +{ + + + glPushMatrix(); + switch (upAxis) + { + case 0: + glRotatef(-90.0, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, -halfHeight); + break; + case 1: + glRotatef(-90.0, 1.0, 0.0, 0.0); + glTranslatef(0.0, 0.0, -halfHeight); + break; + case 2: + + glTranslatef(0.0, 0.0, -halfHeight); + break; + default: + { + btAssert(0); + } + + } + + GLUquadricObj *quadObj = gluNewQuadric(); + + //The gluCylinder subroutine draws a cylinder that is oriented along the z axis. + //The base of the cylinder is placed at z = 0; the top of the cylinder is placed at z=height. + //Like a sphere, the cylinder is subdivided around the z axis into slices and along the z axis into stacks. + + gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); + gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); + + gluDisk(quadObj,0,radius,15, 10); + + gluCylinder(quadObj, radius, radius, 2.f*halfHeight, 15, 10); + glTranslatef(0.0f, 0.0f, 2.f*halfHeight); + glRotatef(-180.0f, 0.0f, 1.0f, 0.0f); + gluDisk(quadObj,0.f,radius,15, 10); + + glPopMatrix(); + gluDeleteQuadric(quadObj); +} + +GL_ShapeDrawer::ShapeCache* GL_ShapeDrawer::cache(btConvexShape* shape) +{ + ShapeCache* sc=(ShapeCache*)shape->getUserPointer(); + if(!sc) + { + sc=new(btAlignedAlloc(sizeof(ShapeCache),16)) ShapeCache(shape); + sc->m_shapehull.buildHull(shape->getMargin()); + m_shapecaches.push_back(sc); + shape->setUserPointer(sc); + /* Build edges */ + const int ni=sc->m_shapehull.numIndices(); + const int nv=sc->m_shapehull.numVertices(); + const unsigned int* pi=sc->m_shapehull.getIndexPointer(); + const btVector3* pv=sc->m_shapehull.getVertexPointer(); + btAlignedObjectArray edges; + sc->m_edges.reserve(ni); + edges.resize(nv*nv,0); + for(int i=0;im_edges.push_back(ShapeCache::Edge()); + e=&sc->m_edges[sc->m_edges.size()-1]; + e->n[0]=nrm;e->n[1]=-nrm; + e->v[0]=a;e->v[1]=b; + } + else + { + e->n[1]=nrm; + } + } + } + } + return(sc); +} + +void renderSquareA(float x, float y, float z) +{ + glBegin(GL_LINE_LOOP); + glVertex3f(x, y, z); + glVertex3f(x + 10.f, y, z); + glVertex3f(x + 10.f, y + 10.f, z); + glVertex3f(x, y + 10.f, z); + glEnd(); +} + +inline void glDrawVector(const btVector3& v) { glVertex3d(v[0], v[1], v[2]); } + + +void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax) +{ + + if (shape->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE) + { + btVector3 org(m[12], m[13], m[14]); + btVector3 dx(m[0], m[1], m[2]); + btVector3 dy(m[4], m[5], m[6]); +// btVector3 dz(m[8], m[9], m[10]); + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); + dx *= halfExtent[0]; + dy *= halfExtent[1]; +// dz *= halfExtent[2]; + glColor3f(1,1,1); + glDisable(GL_LIGHTING); + glLineWidth(2); + + glBegin(GL_LINE_LOOP); + glDrawVector(org - dx - dy); + glDrawVector(org - dx + dy); + glDrawVector(org + dx + dy); + glDrawVector(org + dx - dy); + glEnd(); + return; + } + else if((shape->getShapeType() == BOX_SHAPE_PROXYTYPE) && (debugMode & btIDebugDraw::DBG_FastWireframe)) + { + btVector3 org(m[12], m[13], m[14]); + btVector3 dx(m[0], m[1], m[2]); + btVector3 dy(m[4], m[5], m[6]); + btVector3 dz(m[8], m[9], m[10]); + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); + dx *= halfExtent[0]; + dy *= halfExtent[1]; + dz *= halfExtent[2]; + glBegin(GL_LINE_LOOP); + glDrawVector(org - dx - dy - dz); + glDrawVector(org + dx - dy - dz); + glDrawVector(org + dx + dy - dz); + glDrawVector(org - dx + dy - dz); + glDrawVector(org - dx + dy + dz); + glDrawVector(org + dx + dy + dz); + glDrawVector(org + dx - dy + dz); + glDrawVector(org - dx - dy + dz); + glEnd(); + glBegin(GL_LINES); + glDrawVector(org + dx - dy - dz); + glDrawVector(org + dx - dy + dz); + glDrawVector(org + dx + dy - dz); + glDrawVector(org + dx + dy + dz); + glDrawVector(org - dx - dy - dz); + glDrawVector(org - dx + dy - dz); + glDrawVector(org - dx - dy + dz); + glDrawVector(org - dx + dy + dz); + glEnd(); + return; + } + + glPushMatrix(); + btglMultMatrix(m); + + + if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) + { + const btUniformScalingShape* scalingShape = static_cast(shape); + const btConvexShape* convexShape = scalingShape->getChildShape(); + float scalingFactor = (float)scalingShape->getUniformScalingFactor(); + { + btScalar tmpScaling[4][4]={{scalingFactor,0,0,0}, + {0,scalingFactor,0,0}, + {0,0,scalingFactor,0}, + {0,0,0,1}}; + + drawOpenGL( (btScalar*)tmpScaling,convexShape,color,debugMode,worldBoundsMin,worldBoundsMax); + } + glPopMatrix(); + return; + } + + if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) + { + const btCompoundShape* compoundShape = static_cast(shape); + for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* colShape = compoundShape->getChildShape(i); + ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + childTrans.getOpenGLMatrix(childMat); + drawOpenGL(childMat,colShape,color,debugMode,worldBoundsMin,worldBoundsMax); + } + + } else + { + if(m_textureenabled&&(!m_textureinitialized)) + { + GLubyte* image=new GLubyte[256*256*3]; + for(int y=0;y<256;++y) + { + const int t=y>>4; + GLubyte* pi=image+y*256*3; + for(int x=0;x<256;++x) + { + const int s=x>>4; + const GLubyte b=180; + GLubyte c=b+((s+t&1)&1)*(255-b); + pi[0]=pi[1]=pi[2]=c;pi+=3; + } + } + + glGenTextures(1,(GLuint*)&m_texturehandle); + glBindTexture(GL_TEXTURE_2D,m_texturehandle); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + gluBuild2DMipmaps(GL_TEXTURE_2D,3,256,256,GL_RGB,GL_UNSIGNED_BYTE,image); + delete[] image; + + + } + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(0.025f,0.025f,0.025f); + glMatrixMode(GL_MODELVIEW); + + static const GLfloat planex[]={1,0,0,0}; + // static const GLfloat planey[]={0,1,0,0}; + static const GLfloat planez[]={0,0,1,0}; + glTexGenfv(GL_S,GL_OBJECT_PLANE,planex); + glTexGenfv(GL_T,GL_OBJECT_PLANE,planez); + glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + m_textureinitialized=true; + + + + + //drawCoordSystem(); + + //glPushMatrix(); + glEnable(GL_COLOR_MATERIAL); + if(m_textureenabled) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,m_texturehandle); + } else + { + glDisable(GL_TEXTURE_2D); + } + + + glColor3f(color.x(),color.y(), color.z()); + + bool useWireframeFallback = true; + + if (!(debugMode & btIDebugDraw::DBG_DrawWireframe)) + { + ///you can comment out any of the specific cases, and use the default + + ///the benefit of 'default' is that it approximates the actual collision shape including collision margin + //int shapetype=m_textureenabled?MAX_BROADPHASE_COLLISION_TYPES:shape->getShapeType(); + int shapetype=shape->getShapeType(); + switch (shapetype) + { + + case SPHERE_SHAPE_PROXYTYPE: + { + const btSphereShape* sphereShape = static_cast(shape); + float radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin + drawSphere(radius,10,10); + useWireframeFallback = false; + break; + } + + case BOX_SHAPE_PROXYTYPE: + { + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); + + static int indices[36] = { + 0,1,2, + 3,2,1, + 4,0,6, + 6,0,2, + 5,1,4, + 4,1,0, + 7,3,1, + 7,1,5, + 5,4,7, + 7,4,6, + 7,2,3, + 7,6,2}; + + btVector3 vertices[8]={ + btVector3(halfExtent[0],halfExtent[1],halfExtent[2]), + btVector3(-halfExtent[0],halfExtent[1],halfExtent[2]), + btVector3(halfExtent[0],-halfExtent[1],halfExtent[2]), + btVector3(-halfExtent[0],-halfExtent[1],halfExtent[2]), + btVector3(halfExtent[0],halfExtent[1],-halfExtent[2]), + btVector3(-halfExtent[0],halfExtent[1],-halfExtent[2]), + btVector3(halfExtent[0],-halfExtent[1],-halfExtent[2]), + btVector3(-halfExtent[0],-halfExtent[1],-halfExtent[2])}; +#if 1 + glBegin (GL_TRIANGLES); + int si=36; + for (int i=0;i(shape); + int upIndex = coneShape->getConeUpIndex(); + float radius = coneShape->getRadius();//+coneShape->getMargin(); + float height = coneShape->getHeight();//+coneShape->getMargin(); + switch (upIndex) + { + case 0: + glRotatef(90.0, 0.0, 1.0, 0.0); + break; + case 1: + glRotatef(-90.0, 1.0, 0.0, 0.0); + break; + case 2: + break; + default: + { + } + }; + + glTranslatef(0.0, 0.0, -0.5*height); + glutSolidCone(radius,height,10,10); + useWireframeFallback = false; + break; + + } +#endif + + case STATIC_PLANE_PROXYTYPE: + { + const btStaticPlaneShape* staticPlaneShape = static_cast(shape); + btScalar planeConst = staticPlaneShape->getPlaneConstant(); + const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); + btVector3 planeOrigin = planeNormal * planeConst; + btVector3 vec0,vec1; + btPlaneSpace1(planeNormal,vec0,vec1); + btScalar vecLen = 100.f; + btVector3 pt0 = planeOrigin + vec0*vecLen; + btVector3 pt1 = planeOrigin - vec0*vecLen; + btVector3 pt2 = planeOrigin + vec1*vecLen; + btVector3 pt3 = planeOrigin - vec1*vecLen; + glBegin(GL_LINES); + glVertex3f(pt0.getX(),pt0.getY(),pt0.getZ()); + glVertex3f(pt1.getX(),pt1.getY(),pt1.getZ()); + glVertex3f(pt2.getX(),pt2.getY(),pt2.getZ()); + glVertex3f(pt3.getX(),pt3.getY(),pt3.getZ()); + glEnd(); + + + break; + + } + +/* + case CYLINDER_SHAPE_PROXYTYPE: + { + const btCylinderShape* cylinder = static_cast(shape); + int upAxis = cylinder->getUpAxis(); + + + float radius = cylinder->getRadius(); + float halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis]; + + drawCylinder(radius,halfHeight,upAxis); + + break; + } +*/ + + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + const btMultiSphereShape* multiSphereShape = static_cast(shape); + + btTransform childTransform; + childTransform.setIdentity(); + + + for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--) + { + btSphereShape sc(multiSphereShape->getSphereRadius(i)); + childTransform.setOrigin(multiSphereShape->getSpherePosition(i)); + ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + childTransform.getOpenGLMatrix(childMat); + drawOpenGL(childMat,&sc,color,debugMode,worldBoundsMin,worldBoundsMax); + } + + break; + } + + default: + { + if (shape->isConvex()) + { + const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0; + if (poly) + { + int i; + glBegin (GL_TRIANGLES); + for (i=0;im_faces.size();i++) + { + btVector3 centroid(0,0,0); + int numVerts = poly->m_faces[i].m_indices.size(); + if (numVerts>2) + { + btVector3 v1 = poly->m_vertices[poly->m_faces[i].m_indices[0]]; + for (int v=0;vm_faces[i].m_indices.size()-2;v++) + { + + btVector3 v2 = poly->m_vertices[poly->m_faces[i].m_indices[v+1]]; + btVector3 v3 = poly->m_vertices[poly->m_faces[i].m_indices[v+2]]; + btVector3 normal = (v3-v1).cross(v2-v1); + normal.normalize (); + glNormal3f(normal.getX(),normal.getY(),normal.getZ()); + glVertex3f (v1.x(), v1.y(), v1.z()); + glVertex3f (v2.x(), v2.y(), v2.z()); + glVertex3f (v3.x(), v3.y(), v3.z()); + } + } + } + glEnd (); + } else + { + ShapeCache* sc=cache((btConvexShape*)shape); + //glutSolidCube(1.0); + btShapeHull* hull = &sc->m_shapehull/*(btShapeHull*)shape->getUserPointer()*/; + + if (hull->numTriangles () > 0) + { + int index = 0; + const unsigned int* idx = hull->getIndexPointer(); + const btVector3* vtx = hull->getVertexPointer(); + + glBegin (GL_TRIANGLES); + + for (int i = 0; i < hull->numTriangles (); i++) + { + int i1 = index++; + int i2 = index++; + int i3 = index++; + btAssert(i1 < hull->numIndices () && + i2 < hull->numIndices () && + i3 < hull->numIndices ()); + + int index1 = idx[i1]; + int index2 = idx[i2]; + int index3 = idx[i3]; + btAssert(index1 < hull->numVertices () && + index2 < hull->numVertices () && + index3 < hull->numVertices ()); + + btVector3 v1 = vtx[index1]; + btVector3 v2 = vtx[index2]; + btVector3 v3 = vtx[index3]; + btVector3 normal = (v3-v1).cross(v2-v1); + normal.normalize (); + glNormal3f(normal.getX(),normal.getY(),normal.getZ()); + glVertex3f (v1.x(), v1.y(), v1.z()); + glVertex3f (v2.x(), v2.y(), v2.z()); + glVertex3f (v3.x(), v3.y(), v3.z()); + + } + glEnd (); + + } + } + } + } + } + + } + + + glNormal3f(0,1,0); + + + /// for polyhedral shapes + if (debugMode==btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral())) + { + btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape; + + { + + glColor3f(1.f, 1.f, 1.f); + int i; + for (i=0;igetNumVertices();i++) + { + btVector3 vtx; + polyshape->getVertex(i,vtx); + char buf[12]; + sprintf(buf," %d",i); + //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf); + } + + for (i=0;igetNumPlanes();i++) + { + btVector3 normal; + btVector3 vtx; + polyshape->getPlane(normal,vtx,i); + //btScalar d = vtx.dot(normal); + + //char buf[12]; + //sprintf(buf," plane %d",i); + //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf); + + } + } + + } + + +#ifdef USE_DISPLAY_LISTS + + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) + { + GLuint dlist = OGL_get_displaylist_for_shape((btCollisionShape * )shape); + if (dlist) + { + glCallList(dlist); + } + else + { +#else + if (shape->isConcave() && !shape->isInfinite()) + { + btConcaveShape* concaveMesh = (btConcaveShape*) shape; + + GlDrawcallback drawCallback; + drawCallback.m_wireframe = (debugMode & btIDebugDraw::DBG_DrawWireframe)!=0; + + concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax); + + } +#endif + +#ifdef USE_DISPLAY_LISTS + } +} +#endif + + + + + + } + glPopMatrix(); + +} + +// +void GL_ShapeDrawer::drawShadow(btScalar* m,const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax) +{ + glPushMatrix(); + btglMultMatrix(m); + if(shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) + { + const btUniformScalingShape* scalingShape = static_cast(shape); + const btConvexShape* convexShape = scalingShape->getChildShape(); + float scalingFactor = (float)scalingShape->getUniformScalingFactor(); + btScalar tmpScaling[4][4]={ {scalingFactor,0,0,0}, + {0,scalingFactor,0,0}, + {0,0,scalingFactor,0}, + {0,0,0,1}}; + drawShadow((btScalar*)tmpScaling,extrusion,convexShape,worldBoundsMin,worldBoundsMax); + glPopMatrix(); + return; + } + else if(shape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) + { + const btCompoundShape* compoundShape = static_cast(shape); + for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* colShape = compoundShape->getChildShape(i); + ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + childTrans.getOpenGLMatrix(childMat); + drawShadow(childMat,extrusion*childTrans.getBasis(),colShape,worldBoundsMin,worldBoundsMax); + } + } + else + { + // bool useWireframeFallback = true; + if (shape->isConvex()) + { + ShapeCache* sc=cache((btConvexShape*)shape); + btShapeHull* hull =&sc->m_shapehull; + glBegin(GL_QUADS); + for(int i=0;im_edges.size();++i) + { + const btScalar d=btDot(sc->m_edges[i].n[0],extrusion); + if((d*btDot(sc->m_edges[i].n[1],extrusion))<0) + { + const int q= d<0?1:0; + const btVector3& a= hull->getVertexPointer()[sc->m_edges[i].v[q]]; + const btVector3& b= hull->getVertexPointer()[sc->m_edges[i].v[1-q]]; + glVertex3f(a[0],a[1],a[2]); + glVertex3f(b[0],b[1],b[2]); + glVertex3f(b[0]+extrusion[0],b[1]+extrusion[1],b[2]+extrusion[2]); + glVertex3f(a[0]+extrusion[0],a[1]+extrusion[1],a[2]+extrusion[2]); + } + } + glEnd(); + } + + } + + + + + if (shape->isConcave())//>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) + // if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btConcaveShape* concaveMesh = (btConcaveShape*) shape; + + GlDrawcallback drawCallback; + drawCallback.m_wireframe = false; + + concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax); + + } + glPopMatrix(); + +} + +// +GL_ShapeDrawer::GL_ShapeDrawer() +{ + m_texturehandle = 0; + m_textureenabled = false; + m_textureinitialized = false; +} + +GL_ShapeDrawer::~GL_ShapeDrawer() +{ + int i; + for (i=0;i~ShapeCache(); + btAlignedFree(m_shapecaches[i]); + } + m_shapecaches.clear(); + if(m_textureinitialized) + { + glDeleteTextures(1,(const GLuint*) &m_texturehandle); + } +} + + diff --git a/Demos/OpenGL/GL_ShapeDrawer.h b/Demos/OpenGL/GL_ShapeDrawer.h new file mode 100644 index 0000000..65bf29d --- /dev/null +++ b/Demos/OpenGL/GL_ShapeDrawer.h @@ -0,0 +1,70 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef GL_SHAPE_DRAWER_H +#define GL_SHAPE_DRAWER_H + +class btCollisionShape; +class btShapeHull; +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btVector3.h" + +#include "BulletCollision/CollisionShapes/btShapeHull.h" + +/// OpenGL shape drawing +class GL_ShapeDrawer +{ +protected: + struct ShapeCache + { + struct Edge { btVector3 n[2];int v[2]; }; + ShapeCache(btConvexShape* s) : m_shapehull(s) {} + btShapeHull m_shapehull; + btAlignedObjectArray m_edges; + }; + //clean-up memory of dynamically created shape hulls + btAlignedObjectArray m_shapecaches; + unsigned int m_texturehandle; + bool m_textureenabled; + bool m_textureinitialized; + + + ShapeCache* cache(btConvexShape*); + +public: + GL_ShapeDrawer(); + + virtual ~GL_ShapeDrawer(); + + ///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer + virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax); + virtual void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax); + + bool enableTexture(bool enable) { bool p=m_textureenabled;m_textureenabled=enable;return(p); } + bool hasTextureEnabled() const + { + return m_textureenabled; + } + + static void drawCylinder(float radius,float halfHeight, int upAxis); + void drawSphere(btScalar r, int lats, int longs); + static void drawCoordSystem(); + +}; + +void OGL_displaylist_register_shape(btCollisionShape * shape); +void OGL_displaylist_clean(); + +#endif //GL_SHAPE_DRAWER_H + diff --git a/Demos/OpenGL/GL_Simplex1to4.cpp b/Demos/OpenGL/GL_Simplex1to4.cpp new file mode 100644 index 0000000..440f41d --- /dev/null +++ b/Demos/OpenGL/GL_Simplex1to4.cpp @@ -0,0 +1,80 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include "GL_Simplex1to4.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "GL_ShapeDrawer.h" +#ifdef _WIN32 +#include +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#else +#include +#endif +#include "GlutStuff.h" +#include "LinearMath/btTransform.h" + +GL_Simplex1to4::GL_Simplex1to4() +:m_simplexSolver(0) +{ +} + +GL_Simplex1to4::~GL_Simplex1to4() +{ +} + +/// +/// Debugging method calcClosest calculates the closest point to the origin, using m_simplexSolver +/// +void GL_Simplex1to4::calcClosest(btScalar* m) +{ + btTransform tr; + tr.setFromOpenGLMatrix(m); + + + + GL_ShapeDrawer::drawCoordSystem(); + + if (m_simplexSolver) + { + m_simplexSolver->reset(); + bool res; + + btVector3 v; + + for (int i=0;iaddVertex(v,v,btVector3(0.f,0.f,0.f)); + res = m_simplexSolver->closest(v); + } + + //draw v? + glDisable(GL_LIGHTING); + glBegin(GL_LINES); + btglColor3(1.f, 0.f, 0.f); + btglVertex3(0.f, 0.f, 0.f); + btglVertex3(v.x(),v.y(),v.z()); + glEnd(); + + glEnable(GL_LIGHTING); + + + } + +} diff --git a/Demos/OpenGL/GL_Simplex1to4.h b/Demos/OpenGL/GL_Simplex1to4.h new file mode 100644 index 0000000..e256aab --- /dev/null +++ b/Demos/OpenGL/GL_Simplex1to4.h @@ -0,0 +1,41 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef GL_SIMPLEX_1TO4_H +#define GL_SIMPLEX_1TO4_H + +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" + +///GL_Simplex1to4 is a class to debug a Simplex Solver with 1 to 4 points. +///Can be used by GJK. +class GL_Simplex1to4 : public btBU_Simplex1to4 +{ + btSimplexSolverInterface* m_simplexSolver; + + public: + + GL_Simplex1to4(); + virtual ~GL_Simplex1to4(); + + void calcClosest(btScalar* m); + + void setSimplexSolver(btSimplexSolverInterface* simplexSolver) { + m_simplexSolver = simplexSolver; + } + +}; + +#endif //GL_SIMPLEX_1TO4_H diff --git a/Demos/OpenGL/GlutDemoApplication.cpp b/Demos/OpenGL/GlutDemoApplication.cpp new file mode 100644 index 0000000..0ceaede --- /dev/null +++ b/Demos/OpenGL/GlutDemoApplication.cpp @@ -0,0 +1,87 @@ + +#ifndef _WINDOWS + +#include "GlutDemoApplication.h" + +#include "GlutStuff.h" + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + +void GlutDemoApplication::updateModifierKeys() +{ + m_modifierKeys = 0; + if (glutGetModifiers() & GLUT_ACTIVE_ALT) + m_modifierKeys |= BT_ACTIVE_ALT; + + if (glutGetModifiers() & GLUT_ACTIVE_CTRL) + m_modifierKeys |= BT_ACTIVE_CTRL; + + if (glutGetModifiers() & GLUT_ACTIVE_SHIFT) + m_modifierKeys |= BT_ACTIVE_SHIFT; +} + +void GlutDemoApplication::specialKeyboard(int key, int x, int y) +{ + (void)x; + (void)y; + + switch (key) + { + case GLUT_KEY_F1: + { + + break; + } + + case GLUT_KEY_F2: + { + + break; + } + + + case GLUT_KEY_END: + { + int numObj = getDynamicsWorld()->getNumCollisionObjects(); + if (numObj) + { + btCollisionObject* obj = getDynamicsWorld()->getCollisionObjectArray()[numObj-1]; + + getDynamicsWorld()->removeCollisionObject(obj); + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + delete obj; + + + } + break; + } + case GLUT_KEY_LEFT : stepLeft(); break; + case GLUT_KEY_RIGHT : stepRight(); break; + case GLUT_KEY_UP : stepFront(); break; + case GLUT_KEY_DOWN : stepBack(); break; + case GLUT_KEY_PAGE_UP : zoomIn(); break; + case GLUT_KEY_PAGE_DOWN : zoomOut(); break; + case GLUT_KEY_HOME : toggleIdle(); break; + default: + // std::cout << "unused (special) key : " << key << std::endl; + break; + } + + glutPostRedisplay(); + +} + +void GlutDemoApplication::swapBuffers() +{ + glutSwapBuffers(); + +} + +#endif //_WINDOWS + + diff --git a/Demos/OpenGL/GlutDemoApplication.h b/Demos/OpenGL/GlutDemoApplication.h new file mode 100644 index 0000000..9d3a721 --- /dev/null +++ b/Demos/OpenGL/GlutDemoApplication.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef GLUT_DEMO_APPLICATION_H +#define GLUT_DEMO_APPLICATION_H + +#include "DemoApplication.h" + +ATTRIBUTE_ALIGNED16(class) GlutDemoApplication : public DemoApplication +{ +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + void specialKeyboard(int key, int x, int y); + + virtual void swapBuffers(); + + virtual void updateModifierKeys(); + +}; +#endif //GLUT_DEMO_APPLICATION_H + diff --git a/Demos/OpenGL/GlutStuff.cpp b/Demos/OpenGL/GlutStuff.cpp new file mode 100644 index 0000000..d8de3e7 --- /dev/null +++ b/Demos/OpenGL/GlutStuff.cpp @@ -0,0 +1,120 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _WINDOWS + +#include "DemoApplication.h" + +//glut is C code, this global gDemoApplication links glut to the C++ demo +static DemoApplication* gDemoApplication = 0; + + +#include "GlutStuff.h" + +static void glutKeyboardCallback(unsigned char key, int x, int y) +{ + gDemoApplication->keyboardCallback(key,x,y); +} + +static void glutKeyboardUpCallback(unsigned char key, int x, int y) +{ + gDemoApplication->keyboardUpCallback(key,x,y); +} + +static void glutSpecialKeyboardCallback(int key, int x, int y) +{ + gDemoApplication->specialKeyboard(key,x,y); +} + +static void glutSpecialKeyboardUpCallback(int key, int x, int y) +{ + gDemoApplication->specialKeyboardUp(key,x,y); +} + + +static void glutReshapeCallback(int w, int h) +{ + gDemoApplication->reshape(w,h); +} + +static void glutMoveAndDisplayCallback() +{ + gDemoApplication->moveAndDisplay(); +} + +static void glutMouseFuncCallback(int button, int state, int x, int y) +{ + gDemoApplication->mouseFunc(button,state,x,y); +} + + +static void glutMotionFuncCallback(int x,int y) +{ + gDemoApplication->mouseMotionFunc(x,y); +} + + +static void glutDisplayCallback(void) +{ + gDemoApplication->displayCallback(); +} + + +int glutmain(int argc, char **argv,int width,int height,const char* title,DemoApplication* demoApp) { + + gDemoApplication = demoApp; + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); + glutInitWindowPosition(0, 0); + glutInitWindowSize(width, height); + glutCreateWindow(title); +#ifdef BT_USE_FREEGLUT + glutSetOption (GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); +#endif + + gDemoApplication->myinit(); + + glutKeyboardFunc(glutKeyboardCallback); + glutKeyboardUpFunc(glutKeyboardUpCallback); + glutSpecialFunc(glutSpecialKeyboardCallback); + glutSpecialUpFunc(glutSpecialKeyboardUpCallback); + + glutReshapeFunc(glutReshapeCallback); + //createMenu(); + glutIdleFunc(glutMoveAndDisplayCallback); + glutMouseFunc(glutMouseFuncCallback); + glutPassiveMotionFunc(glutMotionFuncCallback); + glutMotionFunc(glutMotionFuncCallback); + glutDisplayFunc( glutDisplayCallback ); + + glutMoveAndDisplayCallback(); + +//enable vsync to avoid tearing on Apple (todo: for Windows) + +#if defined(__APPLE__) && !defined (VMDMESA) +int swap_interval = 1; +CGLContextObj cgl_context = CGLGetCurrentContext(); +CGLSetParameter(cgl_context, kCGLCPSwapInterval, &swap_interval); +#endif + + + + glutMainLoop(); + return 0; +} + + +#endif //_WINDOWS diff --git a/Demos/OpenGL/GlutStuff.h b/Demos/OpenGL/GlutStuff.h new file mode 100644 index 0000000..0f618be --- /dev/null +++ b/Demos/OpenGL/GlutStuff.h @@ -0,0 +1,86 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef GLUT_STUFF_H +#define GLUT_STUFF_H + +#ifdef _WIN32//for glut.h +#include +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#include +#else + + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif //_WINDOWS +#endif //APPLE + +#ifdef _WINDOWS +#define BT_ACTIVE_ALT VK_LMENU + +#else +#define BT_KEY_K 'k' +#define BT_KEY_LEFT GLUT_KEY_LEFT +#define BT_KEY_RIGHT GLUT_KEY_RIGHT +#define BT_KEY_UP GLUT_KEY_UP +#define BT_KEY_DOWN GLUT_KEY_DOWN +#define BT_KEY_F1 GLUT_KEY_F1 +#define BT_KEY_F2 GLUT_KEY_F2 +#define BT_KEY_F3 GLUT_KEY_F3 +#define BT_KEY_F4 GLUT_KEY_F4 +#define BT_KEY_F5 GLUT_KEY_F5 +#define BT_KEY_PAGEUP GLUT_KEY_PAGE_UP +#define BT_KEY_PAGEDOWN GLUT_KEY_PAGE_DOWN +#define BT_KEY_END GLUT_KEY_END +#define BT_KEY_HOME GLUT_KEY_HOME +#define BT_ACTIVE_ALT GLUT_ACTIVE_ALT +#define BT_ACTIVE_CTRL GLUT_ACTIVE_ALT +#define BT_ACTIVE_SHIFT GLUT_ACTIVE_SHIFT +#endif + +#if BT_USE_FREEGLUT +#include "GL/freeglut_ext.h" //to be able to return from glutMainLoop() +#endif + + + +class DemoApplication; + +int glutmain(int argc, char **argv,int width,int height,const char* title,DemoApplication* demoApp); + +#if defined(BT_USE_DOUBLE_PRECISION) +#define btglLoadMatrix glLoadMatrixd +#define btglMultMatrix glMultMatrixd +#define btglColor3 glColor3d +#define btglVertex3 glVertex3d +#else +#define btglLoadMatrix glLoadMatrixf +#define btglMultMatrix glMultMatrixf +#define btglColor3 glColor3f +#define btglVertex3 glVertex3d +#endif + +#endif //GLUT_STUFF_H diff --git a/Demos/OpenGL/Makefile.am b/Demos/OpenGL/Makefile.am new file mode 100644 index 0000000..11eeed4 --- /dev/null +++ b/Demos/OpenGL/Makefile.am @@ -0,0 +1,12 @@ +noinst_LIBRARIES = libbulletopenglsupport.a + +libbulletopenglsupport_a_SOURCES = \ + DemoApplication.cpp GLDebugDrawer.h GL_Simplex1to4.cpp \ + GLDebugFont.cpp GLDebugFont.h GlutDemoApplication.cpp GlutDemoApplication.h \ + GlutStuff.h \ + DemoApplication.h GL_ShapeDrawer.cpp \ + GL_Simplex1to4.h RenderTexture.cpp \ + DebugCastResult.h GLDebugDrawer.cpp \ + GL_ShapeDrawer.h GlutStuff.cpp RenderTexture.h + +INCLUDES=-I../../src diff --git a/Demos/OpenGL/Makefile.in b/Demos/OpenGL/Makefile.in new file mode 100644 index 0000000..f880fb0 --- /dev/null +++ b/Demos/OpenGL/Makefile.in @@ -0,0 +1,501 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = Demos/OpenGL +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libbulletopenglsupport_a_AR = $(AR) $(ARFLAGS) +libbulletopenglsupport_a_LIBADD = +am_libbulletopenglsupport_a_OBJECTS = DemoApplication.$(OBJEXT) \ + GL_Simplex1to4.$(OBJEXT) GLDebugFont.$(OBJEXT) \ + GlutDemoApplication.$(OBJEXT) GL_ShapeDrawer.$(OBJEXT) \ + RenderTexture.$(OBJEXT) GLDebugDrawer.$(OBJEXT) \ + GlutStuff.$(OBJEXT) +libbulletopenglsupport_a_OBJECTS = \ + $(am_libbulletopenglsupport_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libbulletopenglsupport_a_SOURCES) +DIST_SOURCES = $(libbulletopenglsupport_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libbulletopenglsupport.a +libbulletopenglsupport_a_SOURCES = \ + DemoApplication.cpp GLDebugDrawer.h GL_Simplex1to4.cpp \ + GLDebugFont.cpp GLDebugFont.h GlutDemoApplication.cpp GlutDemoApplication.h \ + GlutStuff.h \ + DemoApplication.h GL_ShapeDrawer.cpp \ + GL_Simplex1to4.h RenderTexture.cpp \ + DebugCastResult.h GLDebugDrawer.cpp \ + GL_ShapeDrawer.h GlutStuff.cpp RenderTexture.h + +INCLUDES = -I../../src +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/OpenGL/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/OpenGL/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libbulletopenglsupport.a: $(libbulletopenglsupport_a_OBJECTS) $(libbulletopenglsupport_a_DEPENDENCIES) + -rm -f libbulletopenglsupport.a + $(libbulletopenglsupport_a_AR) libbulletopenglsupport.a $(libbulletopenglsupport_a_OBJECTS) $(libbulletopenglsupport_a_LIBADD) + $(RANLIB) libbulletopenglsupport.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DemoApplication.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GLDebugDrawer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GLDebugFont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GL_ShapeDrawer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GL_Simplex1to4.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GlutDemoApplication.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GlutStuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RenderTexture.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/OpenGL/RenderTexture.cpp b/Demos/OpenGL/RenderTexture.cpp new file mode 100644 index 0000000..2c8b88b --- /dev/null +++ b/Demos/OpenGL/RenderTexture.cpp @@ -0,0 +1,86 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "RenderTexture.h" +#include + + +renderTexture::renderTexture(int width,int height) +:m_height(height),m_width(width) +{ + m_buffer = new unsigned char[m_width*m_height*4]; + + //clear screen + memset(m_buffer,0,m_width*m_height*4); + + //clear screen version 2 + for (int x=0;x>=1; + y++; + } + x++; + } + //xx+=16; + xx+=10; + } +} + +renderTexture::~renderTexture() +{ + delete [] m_buffer; +} + + + diff --git a/Demos/OpenGL/RenderTexture.h b/Demos/OpenGL/RenderTexture.h new file mode 100644 index 0000000..1aee51d --- /dev/null +++ b/Demos/OpenGL/RenderTexture.h @@ -0,0 +1,73 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef RENDER_TEXTURE_H +#define RENDER_TEXTURE_H + +#include "LinearMath/btVector3.h" +#include "GLDebugFont.h" + +/// +///renderTexture provides a software-render context (setpixel/printf) +/// +class renderTexture +{ + int m_height; + int m_width; + unsigned char* m_buffer; + +public: + + renderTexture(int width,int height); + ~renderTexture(); + + ///rgba input is in range [0..1] for each component + inline void setPixel(int x,int y,const btVector4& rgba) + { + unsigned char* pixel = &m_buffer[ (x+y*m_width) * 4]; + + pixel[0] = (unsigned char)(255.*rgba.getX()); + pixel[1] = (unsigned char)(255.*rgba.getY()); + pixel[2] = (unsigned char)(255.*rgba.getZ()); + pixel[3] = (unsigned char)(255.*rgba.getW()); + } + + inline void addPixel(int x,int y,const btVector4& rgba) + { + unsigned char* pixel = &m_buffer[ (x+y*m_width) * 4]; + pixel[0] = (unsigned char)btMin(btScalar(255.f),((btScalar)pixel[0] + btScalar(255.f)*rgba.getX())); + pixel[1] = (unsigned char)btMin(btScalar(255.f),((btScalar)pixel[1] + btScalar(255.f)*rgba.getY())); + pixel[2] = (unsigned char)btMin(btScalar(255.f),((btScalar)pixel[2] + btScalar(255.f)*rgba.getZ())); +// pixel[3] = (unsigned char)btMin(btScalar(255.f),((btScalar)pixel[3] + btScalar(255.f)*rgba.getW())); + } + + inline btVector4 getPixel(int x,int y) + { + unsigned char* pixel = &m_buffer[ (x+y*m_width) * 4]; + return btVector4(pixel[0]*1.f/255.f, + pixel[1]*1.f/255.f, + pixel[2]*1.f/255.f, + pixel[3]*1.f/255.f); + } + + const unsigned char* getBuffer() const { return m_buffer;} + int getWidth() const { return m_width;} + int getHeight() const { return m_height;} + void grapicalPrintf(char* str, void* fontData, int startx = 0,int starty=0); + +}; + +#endif //RENDER_TEXTURE_H + diff --git a/Demos/OpenGL/Win32AppMain.cpp b/Demos/OpenGL/Win32AppMain.cpp new file mode 100644 index 0000000..84f48a3 --- /dev/null +++ b/Demos/OpenGL/Win32AppMain.cpp @@ -0,0 +1,405 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include +#include + + +#include "DemoApplication.h" + +#include "GLDebugDrawer.h" +#include "GLDebugFont.h" + +#include "BulletDynamics/Dynamics/btDynamicsWorld.h" + +/// This Win32AppMain is shared code between all demos. +/// The actual demo, derived from DemoApplication is created using 'createDemo', in a separate .cpp file +DemoApplication* gDemoApplication = 0; +DemoApplication* createDemo(); + + +// Function Declarations + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC); +void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC); +static bool sOpenGLInitialized = false; +static int sWidth = 0; +static int sHeight =0; +static int quitRequest = 0; + +// WinMain + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int iCmdShow) +{ + WNDCLASS wc; + HWND hWnd; + HDC hDC; + HGLRC hRC; + MSG msg; + BOOL quit = FALSE; + float theta = 0.0f; + + gDemoApplication = createDemo(); + + + // register window class + wc.style = CS_OWNDC; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); + wc.hCursor = LoadCursor( NULL, IDC_ARROW ); + wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); + wc.lpszMenuName = NULL; + wc.lpszClassName = "BulletPhysics"; + RegisterClass( &wc ); + + // create main window + hWnd = CreateWindow( + "BulletPhysics", "Bullet Physics Sample. http://bulletphysics.org", + WS_CAPTION | WS_VISIBLE | WS_OVERLAPPEDWINDOW, +// 0, 0, 640, 480, + 0, 0, 1024, 768, + NULL, NULL, hInstance, NULL ); + + // enable OpenGL for the window + EnableOpenGL( hWnd, &hDC, &hRC ); + + + GLDebugDrawer debugDraw; + gDemoApplication->myinit(); + //gDemoApplication->reshape(1024, 768); + gDemoApplication->initPhysics(); + if (gDemoApplication->getDynamicsWorld()) + gDemoApplication->getDynamicsWorld()->setDebugDrawer(&debugDraw); + + gDemoApplication->reshape(sWidth,sHeight); + + // program main loop + while ( !quit ) + { + + // check for messages + if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) + { + + // handle or dispatch messages + if ( msg.message == WM_QUIT ) + { + quit = TRUE; + } + else + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + +// gDemoApplication->displayCallback(); + + + }; + + // OpenGL animation code goes here + + glClearColor( .7f, 0.7f, 0.7f, 1.f ); + + gDemoApplication->moveAndDisplay(); + + + SwapBuffers( hDC ); + + theta += 1.0f; + + + } + + + + // shutdown OpenGL + DisableOpenGL( hWnd, hDC, hRC ); + + // destroy the window explicitly + DestroyWindow( hWnd ); + + delete gDemoApplication; + + return msg.wParam; + +} + +// Window Procedure + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + + + + switch (message) + { + + case WM_SYSKEYDOWN: + { + if (lParam & 1<<29) + { + gDemoApplication->m_modifierKeys = VK_LMENU; + } + break; + } + case WM_SYSKEYUP: + { + if (lParam & 1<<29) + { + gDemoApplication->m_modifierKeys = VK_LMENU; + } else + { + gDemoApplication->m_modifierKeys = 0; + } + + break; + } + + + case WM_SIZE: // Size Action Has Taken Place + + switch (wParam) // Evaluate Size Action + { + case SIZE_MINIMIZED: // Was Window Minimized? + return 0; // Return + + case SIZE_MAXIMIZED: // Was Window Maximized? + sWidth = LOWORD (lParam); + sHeight = HIWORD (lParam); + if (sOpenGLInitialized) + { + gDemoApplication->reshape(sWidth,sHeight); + } + return 0; // Return + + case SIZE_RESTORED: // Was Window Restored? + sWidth = LOWORD (lParam); + sHeight = HIWORD (lParam); + if (sOpenGLInitialized) + { + gDemoApplication->reshape(sWidth,sHeight); + } + return 0; // Return + } + break; + + case WM_CREATE: + return 0; + + case WM_MBUTTONUP: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + gDemoApplication->mouseFunc(1,1,xPos,yPos); + break; + } + case WM_MBUTTONDOWN: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + gDemoApplication->mouseFunc(1,0,xPos,yPos); + break; + } + + case WM_LBUTTONUP: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + gDemoApplication->mouseFunc(0,1,xPos,yPos); + break; + } + case 0x020A://WM_MOUSEWHEEL: + { + + int zDelta = (short)HIWORD(wParam); + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + if (zDelta>0) + gDemoApplication->zoomIn(); + else + gDemoApplication->zoomOut(); + break; + } + + case WM_MOUSEMOVE: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + gDemoApplication->mouseMotionFunc(xPos,yPos); + break; + } + case WM_RBUTTONUP: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + gDemoApplication->mouseFunc(2,1,xPos,yPos); + break; + } + case WM_RBUTTONDOWN: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + gDemoApplication->mouseFunc(2,0,xPos,yPos); + break; + } + case WM_LBUTTONDOWN: + { + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + gDemoApplication->mouseFunc(0,0,xPos,yPos); + break; + } +/*#define WM_LBUTTONUP 0x0202 +#define WM_LBUTTONDBLCLK 0x0203 +#define WM_RBUTTONDOWN 0x0204 +#define WM_RBUTTONUP 0x0205 +#define WM_RBUTTONDBLCLK 0x0206 +#define WM_MBUTTONDOWN 0x0207 +#define WM_MBUTTONUP 0x0208 +#define WM_MBUTTONDBLCLK 0x0209 +*/ + + + + case WM_CLOSE: + PostQuitMessage( 0 ); + return 0; + + case WM_DESTROY: + return 0; + + case WM_KEYUP: + switch ( wParam ) + { + + case VK_PRIOR: + case VK_NEXT: + case VK_END: + case VK_HOME: + case VK_LEFT: + case VK_UP: + case VK_RIGHT: + case VK_DOWN: + { + if (gDemoApplication) + gDemoApplication->specialKeyboardUp(wParam,0,0); + return 0; + } + default: + { + gDemoApplication->keyboardUpCallback(tolower(wParam),0,0); + } + return DefWindowProc( hWnd, message, wParam, lParam ); + } + + case WM_KEYDOWN: + printf("bla\n"); + switch ( wParam ) + { + case VK_CONTROL: + case VK_PRIOR: + case VK_NEXT: + case VK_END: + case VK_HOME: + case VK_LEFT: + case VK_UP: + case VK_RIGHT: + case VK_DOWN: + { + if (gDemoApplication) + gDemoApplication->specialKeyboard(wParam,0,0); + break; + } + + case ' ': + { + if (gDemoApplication) + gDemoApplication->clientResetScene(); + break; + } + case 'Q': + case VK_ESCAPE: + { + quitRequest = 1; + PostQuitMessage(0); + } + return 0; + + } + return 0; + + case WM_CHAR: + if (!quitRequest) + gDemoApplication->keyboardCallback(wParam,0,0); + break; + + default: + return DefWindowProc( hWnd, message, wParam, lParam ); + + } + return 0; +} + +// Enable OpenGL + +void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC) +{ + PIXELFORMATDESCRIPTOR pfd; + int format; + + // get the device context (DC) + *hDC = GetDC( hWnd ); + + // set the pixel format for the DC + ZeroMemory( &pfd, sizeof( pfd ) ); + pfd.nSize = sizeof( pfd ); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 16; + pfd.cStencilBits = 1; + pfd.iLayerType = PFD_MAIN_PLANE; + format = ChoosePixelFormat( *hDC, &pfd ); + SetPixelFormat( *hDC, format, &pfd ); + + // create and enable the render context (RC) + *hRC = wglCreateContext( *hDC ); + wglMakeCurrent( *hDC, *hRC ); + sOpenGLInitialized = true; + + +} + +// Disable OpenGL + +void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC) +{ + sOpenGLInitialized = false; + + wglMakeCurrent( NULL, NULL ); + wglDeleteContext( hRC ); + ReleaseDC( hWnd, hDC ); +} + +#endif //_WINDOWS diff --git a/Demos/OpenGL/Win32DemoApplication.cpp b/Demos/OpenGL/Win32DemoApplication.cpp new file mode 100644 index 0000000..f959cbf --- /dev/null +++ b/Demos/OpenGL/Win32DemoApplication.cpp @@ -0,0 +1,79 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifdef _WINDOWS + +#include "Win32DemoApplication.h" + + + + +#if 0 +void Win32DemoApplication::renderme() +{ +} +void Win32DemoApplication::setTexturing(bool useTexture) +{ +} + +void Win32DemoApplication::setShadows(bool useShadows) +{ +} + +void Win32DemoApplication::setCameraDistance(float camDist) +{ +} +void Win32DemoApplication::clientResetScene() +{ + +} +#endif + +void Win32DemoApplication::updateModifierKeys() +{ + //not yet +} + + + +void Win32DemoApplication::specialKeyboard(int key, int x, int y) +{ + (void)x; + (void)y; + + switch (key) + { + case VK_LEFT : stepLeft(); break; + case VK_RIGHT : stepRight(); break; + case VK_UP : stepFront(); break; + case VK_DOWN : stepBack(); break; + +// case GLUT_KEY_PAGE_UP : zoomIn(); break; +// case GLUT_KEY_PAGE_DOWN : zoomOut(); break; +// case GLUT_KEY_HOME : toggleIdle(); break; + + default: + // std::cout << "unused (special) key : " << key << std::endl; + break; + } + +} + +void Win32DemoApplication::swapBuffers() +{ +} + +#endif + diff --git a/Demos/OpenGL/Win32DemoApplication.h b/Demos/OpenGL/Win32DemoApplication.h new file mode 100644 index 0000000..af3eec9 --- /dev/null +++ b/Demos/OpenGL/Win32DemoApplication.h @@ -0,0 +1,41 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef WIN32_DEMO_APPLICATION_H +#define WIN32_DEMO_APPLICATION_H + + +#include "DemoApplication.h" + +ATTRIBUTE_ALIGNED16(class) Win32DemoApplication : public DemoApplication +{ +protected: + + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + virtual void swapBuffers(); + + void specialKeyboard(int key, int x, int y); + + virtual void updateModifierKeys(); + + +}; + +#endif //WIN32_DEMO_APPLICATION_H \ No newline at end of file diff --git a/Demos/OpenGL/premake4.lua b/Demos/OpenGL/premake4.lua new file mode 100644 index 0000000..3e2208e --- /dev/null +++ b/Demos/OpenGL/premake4.lua @@ -0,0 +1,18 @@ + project "OpenGLSupport" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + ".", + "../../src" + } + configuration {"Windows"} + includedirs { + "../../Glut" + } + configuration{} + + files { + "**.cpp", + "**.h" + } diff --git a/Demos/OpenGL/stb_image.cpp b/Demos/OpenGL/stb_image.cpp new file mode 100644 index 0000000..a60e130 --- /dev/null +++ b/Demos/OpenGL/stb_image.cpp @@ -0,0 +1,4341 @@ +#include "stb_image.h" + +#ifndef STBI_HEADER_FILE_ONLY + +#ifndef STBI_NO_HDR +#include // ldexp +#include // strcmp, strtok +#endif + +#ifndef STBI_NO_STDIO +#include +#endif +#include +#include +#include +#include + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + + +// implementation: +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned int uint; + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1]; + +#if defined(STBI_NO_STDIO) && !defined(STBI_NO_WRITE) +#define STBI_NO_WRITE +#endif + +#define STBI_NOTUSED(v) (void)sizeof(v) + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +/////////////////////////////////////////////// +// +// stbi struct and start_xxx functions + +// stbi structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + uint8 buffer_start[128]; + + uint8 *img_buffer, *img_buffer_end; + uint8 *img_buffer_original; +} stbi; + + +static void refill_buffer(stbi *s); + +// initialize a memory-decode context +static void start_mem(stbi *s, uint8 const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (uint8 *) buffer; + s->img_buffer_end = (uint8 *) buffer+len; +} + +// initialize a callback-based context +static void start_callbacks(stbi *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + refill_buffer(s); +} + +#ifndef STBI_NO_STDIO + +static int stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stdio_skip(void *user, unsigned n) +{ + fseek((FILE*) user, n, SEEK_CUR); +} + +static int stdio_eof(void *user) +{ + return feof((FILE*) user); +} + +static stbi_io_callbacks stbi_stdio_callbacks = +{ + stdio_read, + stdio_skip, + stdio_eof, +}; + +static void start_file(stbi *s, FILE *f) +{ + start_callbacks(s, &stbi_stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi_rewind(stbi *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; +} + +static int stbi_jpeg_test(stbi *s); +static stbi_uc *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp); +static int stbi_png_test(stbi *s); +static stbi_uc *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_png_info(stbi *s, int *x, int *y, int *comp); +static int stbi_bmp_test(stbi *s); +static stbi_uc *stbi_bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_tga_test(stbi *s); +static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_tga_info(stbi *s, int *x, int *y, int *comp); +static int stbi_psd_test(stbi *s); +static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_hdr_test(stbi *s); +static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_pic_test(stbi *s); +static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_gif_test(stbi *s); +static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_gif_info(stbi *s, int *x, int *y, int *comp); + + +// this is not threadsafe +static const char *failure_reason; + +const char *stbi_failure_reason(void) +{ + return failure_reason; +} + +static int e(const char *str) +{ + failure_reason = str; + return 0; +} + +// e - error +// epf - error returning pointer to float +// epuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define e(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define e(x,y) e(y) +#else + #define e(x,y) e(x) +#endif + +#define epf(x,y) ((float *) (e(x,y)?NULL:NULL)) +#define epuc(x,y) ((unsigned char *) (e(x,y)?NULL:NULL)) + +void stbi_image_free(void *retval_from_stbi_load) +{ + free(retval_from_stbi_load); +} + +#ifndef STBI_NO_HDR +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static unsigned char *stbi_load_main(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + if (stbi_jpeg_test(s)) return stbi_jpeg_load(s,x,y,comp,req_comp); + if (stbi_png_test(s)) return stbi_png_load(s,x,y,comp,req_comp); + if (stbi_bmp_test(s)) return stbi_bmp_load(s,x,y,comp,req_comp); + if (stbi_gif_test(s)) return stbi_gif_load(s,x,y,comp,req_comp); + if (stbi_psd_test(s)) return stbi_psd_load(s,x,y,comp,req_comp); + if (stbi_pic_test(s)) return stbi_pic_load(s,x,y,comp,req_comp); + + #ifndef STBI_NO_HDR + if (stbi_hdr_test(s)) { + float *hdr = stbi_hdr_load(s, x,y,comp,req_comp); + return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + // test tga last because it's a crappy test! + if (stbi_tga_test(s)) + return stbi_tga_load(s,x,y,comp,req_comp); + return epuc("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_STDIO +unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = fopen(filename, "rb"); + unsigned char *result; + if (!f) return epuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s,f); + return stbi_load_main(&s,x,y,comp,req_comp); +} +#endif //!STBI_NO_STDIO + +unsigned char *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s,buffer,len); + return stbi_load_main(&s,x,y,comp,req_comp); +} + +unsigned char *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi_load_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_HDR + +float *stbi_loadf_main(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi_hdr_test(s)) + return stbi_hdr_load(s,x,y,comp,req_comp); + #endif + data = stbi_load_main(s, x, y, comp, req_comp); + if (data) + return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return epf("unknown image type", "Image not of any known type, or corrupt"); +} + +float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s,buffer,len); + return stbi_loadf_main(&s,x,y,comp,req_comp); +} + +float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi_loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = fopen(filename, "rb"); + float *result; + if (!f) return epf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s,f); + return stbi_loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_HDR + +// these is-hdr-or-not is defined independent of whether STBI_NO_HDR is +// defined, for API simplicity; if STBI_NO_HDR is defined, it always +// reports false! + +int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi s; + start_mem(&s,buffer,len); + return stbi_hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +extern int stbi_is_hdr (char const *filename) +{ + FILE *f = fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +extern int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + stbi s; + start_file(&s,f); + return stbi_hdr_test(&s); + #else + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi_hdr_test(&s); + #else + return 0; + #endif +} + +#ifndef STBI_NO_HDR +static float h2l_gamma_i=1.0f/2.2f, h2l_scale_i=1.0f; +static float l2h_gamma=2.2f, l2h_scale=1.0f; + +void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1/gamma; } +void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1/scale; } + +void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; } +void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } +#endif + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + SCAN_load=0, + SCAN_type, + SCAN_header +}; + +static void refill_buffer(stbi *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + if (n == 0) { + // at end of file, treat same as if from memory + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_end-1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static int get8(stbi *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +stbi_inline static int at_eof(stbi *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} + +stbi_inline static uint8 get8u(stbi *s) +{ + return (uint8) get8(s); +} + +static void skip(stbi *s, int n) +{ + if (s->io.read) { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} + +static int getn(stbi *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} + +static int get16(stbi *s) +{ + int z = get8(s); + return (z << 8) + get8(s); +} + +static uint32 get32(stbi *s) +{ + uint32 z = get16(s); + return (z << 16) + get16(s); +} + +static int get16le(stbi *s) +{ + int z = get8(s); + return z + (get8(s) << 8); +} + +static uint32 get32le(stbi *s) +{ + uint32 z = get16le(s); + return z + (get16le(s) << 16); +} + +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static uint8 compute_y(int r, int g, int b) +{ + return (uint8) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp, uint x, uint y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + assert(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) malloc(req_comp * x * y); + if (good == NULL) { + free(data); + return epuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define COMBO(a,b) ((a)*8+(b)) + #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (COMBO(img_n, req_comp)) { + CASE(1,2) dest[0]=src[0], dest[1]=255; break; + CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; + CASE(2,1) dest[0]=src[0]; break; + CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; + CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; + CASE(3,1) dest[0]=compute_y(src[0],src[1],src[2]); break; + CASE(3,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = 255; break; + CASE(4,1) dest[0]=compute_y(src[0],src[1],src[2]); break; + CASE(4,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; + CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + default: assert(0); + } + #undef CASE + } + + free(data); + return good; +} + +#ifndef STBI_NO_HDR +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output = (float *) malloc(x * y * comp * sizeof(float)); + if (output == NULL) { free(data); return epf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) pow(data[i*comp+k]/255.0f, l2h_gamma) * l2h_scale; + } + if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + free(data); + return output; +} + +#define float2int(x) ((int) (x)) +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output = (stbi_uc *) malloc(x * y * comp); + if (output == NULL) { free(data); return epuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (uint8) float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (uint8) float2int(z); + } + } + free(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder (not actually fully baseline implementation) +// +// simple implementation +// - channel subsampling of at most 2 in each dimension +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - uses a lot of intermediate memory, could cache poorly +// - load http://nothings.org/remote/anemones.jpg 3 times on 2.8Ghz P4 +// stb_jpeg: 1.34 seconds (MSVC6, default release build) +// stb_jpeg: 1.06 seconds (MSVC6, processor = Pentium Pro) +// IJL11.dll: 1.08 seconds (compiled by intel) +// IJG 1998: 0.98 seconds (MSVC6, makefile provided by IJG) +// IJG 1998: 0.95 seconds (MSVC6, makefile + proc=PPro) + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + uint8 fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + uint16 code[256]; + uint8 values[256]; + uint8 size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} huffman; + +typedef struct +{ + #ifdef STBI_SIMD + unsigned short dequant2[4][64]; + #endif + stbi *s; + huffman huff_dc[4]; + huffman huff_ac[4]; + uint8 dequant[4][64]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + uint8 *data; + void *raw_data; + uint8 *linebuf; + } img_comp[4]; + + uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int scan_n, order[4]; + int restart_interval, todo; +} jpeg; + +static int build_huffman(huffman *h, int *count) +{ + int i,j,k=0,code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (uint8) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (uint16) (code++); + if (code-1 >= (1 << j)) return e("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (uint8) i; + } + } + } + return 1; +} + +static void grow_buffer_unsafe(jpeg *j) +{ + do { + int b = j->nomore ? 0 : get8(j->s); + if (b == 0xff) { + int c = get8(j->s); + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static uint32 bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int decode(jpeg *j, huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & bmask[k]) + h->delta[k]; + assert((((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// combined JPEG 'receive' and JPEG 'extend', since baseline +// always extends everything it receives. +stbi_inline static int extend_receive(jpeg *j, int n) +{ + unsigned int m = 1 << (n-1); + unsigned int k; + if (j->code_bits < n) grow_buffer_unsafe(j); + + #if 1 + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~bmask[n]; + k &= bmask[n]; + j->code_bits -= n; + #else + k = (j->code_buffer >> (32 - n)) & bmask[n]; + j->code_bits -= n; + j->code_buffer <<= n; + #endif + // the following test is probably a random branch that won't + // predict well. I tried to table accelerate it but failed. + // maybe it's compiling as a conditional move? + if (k < m) + return (-1 << n) + k + 1; + else + return k; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static uint8 dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int decode_block(jpeg *j, short data[64], huffman *hdc, huffman *hac, int b) +{ + int diff,dc,k; + int t = decode(j, hdc); + if (t < 0) return e("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) dc; + + // decode AC components, see JPEG spec + k = 1; + do { + int r,s; + int rs = decode(j, hac); + if (rs < 0) return e("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + data[dezigzag[k++]] = (short) extend_receive(j,s); + } + } while (k < 64); + return 1; +} + +// take a -128..127 value and clamp it and convert to 0..255 +stbi_inline static uint8 clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (uint8) x; +} + +#define f2f(x) (int) (((x) * 4096 + 0.5)) +#define fsh(x) ((x) << 12) + +// derived from jidctint -- DCT_ISLOW +#define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * f2f(0.5411961f); \ + t2 = p1 + p3*f2f(-1.847759065f); \ + t3 = p1 + p2*f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = fsh(p2+p3); \ + t1 = fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*f2f( 1.175875602f); \ + t0 = t0*f2f( 0.298631336f); \ + t1 = t1*f2f( 2.053119869f); \ + t2 = t2*f2f( 3.072711026f); \ + t3 = t3*f2f( 1.501321110f); \ + p1 = p5 + p1*f2f(-0.899976223f); \ + p2 = p5 + p2*f2f(-2.562915447f); \ + p3 = p3*f2f(-1.961570560f); \ + p4 = p4*f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +#ifdef STBI_SIMD +typedef unsigned short stbi_dequantize_t; +#else +typedef uint8 stbi_dequantize_t; +#endif + +// .344 seconds on 3*anemones.jpg +static void idct_block(uint8 *out, int out_stride, short data[64], stbi_dequantize_t *dequantize) +{ + int i,val[64],*v=val; + stbi_dequantize_t *dq = dequantize; + uint8 *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d,++dq, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] * dq[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24], + d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = clamp((x0+t3) >> 17); + o[7] = clamp((x0-t3) >> 17); + o[1] = clamp((x1+t2) >> 17); + o[6] = clamp((x1-t2) >> 17); + o[2] = clamp((x2+t1) >> 17); + o[5] = clamp((x2-t1) >> 17); + o[3] = clamp((x3+t0) >> 17); + o[4] = clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SIMD +static stbi_idct_8x8 stbi_idct_installed = idct_block; + +void stbi_install_idct(stbi_idct_8x8 func) +{ + stbi_idct_installed = func; +} +#endif + +#define MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static uint8 get_marker(jpeg *j) +{ + uint8 x; + if (j->marker != MARKER_none) { x = j->marker; j->marker = MARKER_none; return x; } + x = get8u(j->s); + if (x != 0xff) return MARKER_none; + while (x == 0xff) + x = get8u(j->s); + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, reset the entropy decoder and +// the dc prediction +static void reset(jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int parse_entropy_coded_data(jpeg *z) +{ + reset(z); + if (z->scan_n == 1) { + int i,j; + #ifdef STBI_SIMD + __declspec(align(16)) + #endif + short data[64]; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; + #ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); + #else + idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); + #endif + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } else { // interleaved! + int i,j,k,x,y; + short data[64]; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; + #ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); + #else + idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); + #endif + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } + return 1; +} + +static int process_marker(jpeg *z, int m) +{ + int L; + switch (m) { + case MARKER_none: // no marker found + return e("expected marker","Corrupt JPEG"); + + case 0xC2: // SOF - progressive + return e("progressive jpeg","JPEG format not supported (progressive)"); + + case 0xDD: // DRI - specify restart interval + if (get16(z->s) != 4) return e("bad DRI len","Corrupt JPEG"); + z->restart_interval = get16(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = get16(z->s)-2; + while (L > 0) { + int q = get8(z->s); + int p = q >> 4; + int t = q & 15,i; + if (p != 0) return e("bad DQT type","Corrupt JPEG"); + if (t > 3) return e("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) + z->dequant[t][dezigzag[i]] = get8u(z->s); + #ifdef STBI_SIMD + for (i=0; i < 64; ++i) + z->dequant2[t][i] = z->dequant[t][i]; + #endif + L -= 65; + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = get16(z->s)-2; + while (L > 0) { + uint8 *v; + int sizes[16],i,m=0; + int q = get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return e("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = get8(z->s); + m += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < m; ++i) + v[i] = get8u(z->s); + L -= m; + } + return L==0; + } + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + skip(z->s, get16(z->s)-2); + return 1; + } + return 0; +} + +// after we see SOS +static int process_scan_header(jpeg *z) +{ + int i; + int Ls = get16(z->s); + z->scan_n = get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return e("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = get8(z->s), which; + int q = get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return e("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); + get8(z->s); // should be 63, but might be 0 + if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); + + return 1; +} + +static int process_frame_header(jpeg *z, int scan) +{ + stbi *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = get16(s); if (Lf < 11) return e("bad SOF len","Corrupt JPEG"); // JPEG + p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = get16(s); if (s->img_x == 0) return e("0 width","Corrupt JPEG"); // JPEG requires + c = get8(s); + if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG"); // JFIF requires + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG"); + + for (i=0; i < s->img_n; ++i) { + z->img_comp[i].id = get8(s); + if (z->img_comp[i].id != i+1) // JFIF requires + if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! + return e("bad component ID","Corrupt JPEG"); + q = get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V","Corrupt JPEG"); + z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG"); + } + + if (scan != SCAN_load) return 1; + + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); + if (z->img_comp[i].raw_data == NULL) { + for(--i; i >= 0; --i) { + free(z->img_comp[i].raw_data); + z->img_comp[i].data = NULL; + } + return e("outofmem", "Out of memory"); + } + // align blocks for installable-idct using mmx/sse + z->img_comp[i].data = (uint8*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define DNL(x) ((x) == 0xdc) +#define SOI(x) ((x) == 0xd8) +#define EOI(x) ((x) == 0xd9) +#define SOF(x) ((x) == 0xc0 || (x) == 0xc1) +#define SOS(x) ((x) == 0xda) + +static int decode_jpeg_header(jpeg *z, int scan) +{ + int m; + z->marker = MARKER_none; // initialize cached marker to empty + m = get_marker(z); + if (!SOI(m)) return e("no SOI","Corrupt JPEG"); + if (scan == SCAN_type) return 1; + m = get_marker(z); + while (!SOF(m)) { + if (!process_marker(z,m)) return 0; + m = get_marker(z); + while (m == MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (at_eof(z->s)) return e("no SOF", "Corrupt JPEG"); + m = get_marker(z); + } + } + if (!process_frame_header(z, scan)) return 0; + return 1; +} + +static int decode_jpeg_image(jpeg *j) +{ + int m; + j->restart_interval = 0; + if (!decode_jpeg_header(j, SCAN_load)) return 0; + m = get_marker(j); + while (!EOI(m)) { + if (SOS(m)) { + if (!process_scan_header(j)) return 0; + if (!parse_entropy_coded_data(j)) return 0; + if (j->marker == MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!at_eof(j->s)) { + int x = get8(j->s); + if (x == 255) { + j->marker = get8u(j->s); + break; + } else if (x != 0) { + return 0; + } + } + // if we reach eof without hitting a marker, get_marker() below will fail and we'll eventually return 0 + } + } else { + if (!process_marker(j, m)) return 0; + } + m = get_marker(j); + } + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1, + int w, int hs); + +#define div4(x) ((uint8) ((x) >> 2)) + +static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + uint8 *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = div4(n+input[i-1]); + out[i*2+1] = div4(n+input[i+1]); + } + out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define div16(x) ((uint8) ((x) >> 4)) + +static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = div16(3*t0 + t1 + 8); + out[i*2 ] = div16(3*t1 + t0 + 8); + } + out[w*2-1] = div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) + +// 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) +// VC6 without processor=Pro is generating multiple LEAs per multiply! +static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 16) + 32768; // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr*float2fixed(1.40200f); + g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); + b = y_fixed + cb*float2fixed(1.77200f); + r >>= 16; + g >>= 16; + b >>= 16; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (uint8)r; + out[1] = (uint8)g; + out[2] = (uint8)b; + out[3] = 255; + out += step; + } +} + +#ifdef STBI_SIMD +static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row; + +void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func) +{ + stbi_YCbCr_installed = func; +} +#endif + + +// clean up the temporary component buffers +static void cleanup_jpeg(jpeg *j) +{ + int i; + for (i=0; i < j->s->img_n; ++i) { + if (j->img_comp[i].data) { + free(j->img_comp[i].raw_data); + j->img_comp[i].data = NULL; + } + if (j->img_comp[i].linebuf) { + free(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } +} + +typedef struct +{ + resample_row_func resample; + uint8 *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi_resample; + +static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n; + // validate req_comp + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + z->s->img_n = 0; + + // load a jpeg image from whichever source + if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n; + + if (z->s->img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s->img_n; + + // resample and color-convert + { + int k; + uint i,j; + uint8 *output; + uint8 *coutput[4]; + + stbi_resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi_resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (uint8 *) malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2; + else r->resample = resample_row_generic; + } + + // can't error after this so, this is safe + output = (uint8 *) malloc(n * z->s->img_x * z->s->img_y + 1); + if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + uint8 *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi_resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + uint8 *y = coutput[0]; + if (z->s->img_n == 3) { + #ifdef STBI_SIMD + stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); + #else + YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s->img_x, n); + #endif + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + uint8 *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n; // report original components, not output + return output; + } +} + +static unsigned char *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + jpeg j; + j.s = s; + return load_jpeg_image(&j, x,y,comp,req_comp); +} + +static int stbi_jpeg_test(stbi *s) +{ + int r; + jpeg j; + j.s = s; + r = decode_jpeg_header(&j, SCAN_type); + stbi_rewind(s); + return r; +} + +static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp) +{ + if (!decode_jpeg_header(j, SCAN_header)) { + stbi_rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n; + return 1; +} + +static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp) +{ + jpeg j; + j.s = s; + return stbi_jpeg_info_raw(&j, x, y, comp); +} + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define ZFAST_BITS 9 // accelerate all cases in default tables +#define ZFAST_MASK ((1 << ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + uint16 fast[1 << ZFAST_BITS]; + uint16 firstcode[16]; + int maxcode[17]; + uint16 firstsymbol[16]; + uint8 size[288]; + uint16 value[288]; +} zhuffman; + +stbi_inline static int bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int bit_reverse(int v, int bits) +{ + assert(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return bitreverse16(v) >> (16-bits); +} + +static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 255, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + assert(sizes[i] <= (1 << i)); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (uint16) code; + z->firstsymbol[i] = (uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + z->size[c] = (uint8)s; + z->value[c] = (uint16)i; + if (s <= ZFAST_BITS) { + int k = bit_reverse(next_code[s],s); + while (k < (1 << ZFAST_BITS)) { + z->fast[k] = (uint16) c; + k += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + uint8 *zbuffer, *zbuffer_end; + int num_bits; + uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + zhuffman z_length, z_distance; +} zbuf; + +stbi_inline static int zget8(zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void fill_bits(zbuf *z) +{ + do { + assert(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int zreceive(zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +stbi_inline static int zhuffman_decode(zbuf *a, zhuffman *z) +{ + int b,s,k; + if (a->num_bits < 16) fill_bits(a); + b = z->fast[a->code_buffer & ZFAST_MASK]; + if (b < 0xffff) { + s = z->size[b]; + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; + } + + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = bit_reverse(a->code_buffer, 16); + for (s=ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + assert(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +static int expand(zbuf *z, int n) // need to make room for n bytes +{ + char *q; + int cur, limit; + if (!z->z_expandable) return e("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) realloc(z->zout_start, limit); + if (q == NULL) return e("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static int length_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static int length_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static int dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static int dist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int parse_huffman_block(zbuf *a) +{ + for(;;) { + int z = zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return e("bad huffman code","Corrupt PNG"); // error in huffman codes + if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0; + *a->zout++ = (char) z; + } else { + uint8 *p; + int len,dist; + if (z == 256) return 1; + z -= 257; + len = length_base[z]; + if (length_extra[z]) len += zreceive(a, length_extra[z]); + z = zhuffman_decode(a, &a->z_distance); + if (z < 0) return e("bad huffman code","Corrupt PNG"); + dist = dist_base[z]; + if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); + if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG"); + if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0; + p = (uint8 *) (a->zout - dist); + while (len--) + *a->zout++ = *p++; + } + } +} + +static int compute_huffman_codes(zbuf *a) +{ + static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + zhuffman z_codelength; + uint8 lencodes[286+32+137];//padding for maximum single op + uint8 codelength_sizes[19]; + int i,n; + + int hlit = zreceive(a,5) + 257; + int hdist = zreceive(a,5) + 1; + int hclen = zreceive(a,4) + 4; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (uint8) s; + } + if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < hlit + hdist) { + int c = zhuffman_decode(a, &z_codelength); + assert(c >= 0 && c < 19); + if (c < 16) + lencodes[n++] = (uint8) c; + else if (c == 16) { + c = zreceive(a,2)+3; + memset(lencodes+n, lencodes[n-1], c); + n += c; + } else if (c == 17) { + c = zreceive(a,3)+3; + memset(lencodes+n, 0, c); + n += c; + } else { + assert(c == 18); + c = zreceive(a,7)+11; + memset(lencodes+n, 0, c); + n += c; + } + } + if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG"); + if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int parse_uncompressed_block(zbuf *a) +{ + uint8 header[4]; + int len,nlen,k; + if (a->num_bits & 7) + zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns? + a->code_buffer >>= 8; + a->num_bits -= 8; + } + assert(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = (uint8) zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!expand(a, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int parse_zlib_header(zbuf *a) +{ + int cmf = zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = zget8(a); + if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return e("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return e("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +// @TODO: should statically initialize these for optimal thread safety +static uint8 default_length[288], default_distance[32]; +static void init_defaults(void) +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) default_length[i] = 8; + for ( ; i <= 255; ++i) default_length[i] = 9; + for ( ; i <= 279; ++i) default_length[i] = 7; + for ( ; i <= 287; ++i) default_length[i] = 8; + + for (i=0; i <= 31; ++i) default_distance[i] = 5; +} + +int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead +static int parse_zlib(zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = zreceive(a,1); + type = zreceive(a,2); + if (type == 0) { + if (!parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!default_distance[31]) init_defaults(); + if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0; + if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; + } else { + if (!compute_huffman_codes(a)) return 0; + } + if (!parse_huffman_block(a)) return 0; + } + if (stbi_png_partial && a->zout - a->zout_start > 65536) + break; + } while (!final); + return 1; +} + +static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return parse_zlib(a, parse_header); +} + +char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + zbuf a; + char *p = (char *) malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer + len; + if (do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + zbuf a; + char *p = (char *) malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer + len; + if (do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + zbuf a; + a.zbuffer = (uint8 *) ibuffer; + a.zbuffer_end = (uint8 *) ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + zbuf a; + char *p = (char *) malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer+len; + if (do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + zbuf a; + a.zbuffer = (uint8 *) ibuffer; + a.zbuffer_end = (uint8 *) ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + + +typedef struct +{ + uint32 length; + uint32 type; +} chunk; + +#define PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) + +static chunk get_chunk_header(stbi *s) +{ + chunk c; + c.length = get32(s); + c.type = get32(s); + return c; +} + +static int check_png_header(stbi *s) +{ + static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (get8u(s) != png_sig[i]) return e("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi *s; + uint8 *idata, *expanded, *out; +} png; + + +enum { + F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4, + F_avg_first, F_paeth_first +}; + +static uint8 first_row_filter[5] = +{ + F_none, F_sub, F_none, F_avg_first, F_paeth_first +}; + +static int paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +// create the png data from post-deflated data +static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) +{ + stbi *s = a->s; + uint32 i,j,stride = x*out_n; + int k; + int img_n = s->img_n; // copy it into a local for later + assert(out_n == s->img_n || out_n == s->img_n+1); + if (stbi_png_partial) y = 1; + a->out = (uint8 *) malloc(x * y * out_n); + if (!a->out) return e("outofmem", "Out of memory"); + if (!stbi_png_partial) { + if (s->img_x == x && s->img_y == y) { + if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + } else { // interlaced: + if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + } + } + for (j=0; j < y; ++j) { + uint8 *cur = a->out + stride*j; + uint8 *prior = cur - stride; + int filter = *raw++; + if (filter > 4) return e("invalid filter","Corrupt PNG"); + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + // handle first pixel explicitly + for (k=0; k < img_n; ++k) { + switch (filter) { + case F_none : cur[k] = raw[k]; break; + case F_sub : cur[k] = raw[k]; break; + case F_up : cur[k] = raw[k] + prior[k]; break; + case F_avg : cur[k] = raw[k] + (prior[k]>>1); break; + case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break; + case F_avg_first : cur[k] = raw[k]; break; + case F_paeth_first: cur[k] = raw[k]; break; + } + } + if (img_n != out_n) cur[img_n] = 255; + raw += img_n; + cur += out_n; + prior += out_n; + // this is a little gross, so that we don't switch per-pixel or per-component + if (img_n == out_n) { + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ + for (k=0; k < img_n; ++k) + switch (filter) { + CASE(F_none) cur[k] = raw[k]; break; + CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break; + CASE(F_up) cur[k] = raw[k] + prior[k]; break; + CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break; + CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break; + CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break; + CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break; + } + #undef CASE + } else { + assert(img_n+1 == out_n); + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ + for (k=0; k < img_n; ++k) + switch (filter) { + CASE(F_none) cur[k] = raw[k]; break; + CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break; + CASE(F_up) cur[k] = raw[k] + prior[k]; break; + CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break; + CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; + CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break; + CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break; + } + #undef CASE + } + } + return 1; +} + +static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) +{ + uint8 *final; + int p; + int save; + if (!interlaced) + return create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y); + save = stbi_png_partial; + stbi_png_partial = 0; + + // de-interlacing + final = (uint8 *) malloc(a->s->img_x * a->s->img_y * out_n); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { + free(final); + return 0; + } + for (j=0; j < y; ++j) + for (i=0; i < x; ++i) + memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n, + a->out + (j*x+i)*out_n, out_n); + free(a->out); + raw += (x*out_n+1)*y; + raw_len -= (x*out_n+1)*y; + } + } + a->out = final; + + stbi_png_partial = save; + return 1; +} + +static int compute_transparency(png *z, uint8 tc[3], int out_n) +{ + stbi *s = z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + assert(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) +{ + uint32 i, pixel_count = a->s->img_x * a->s->img_y; + uint8 *p, *temp_out, *orig = a->out; + + p = (uint8 *) malloc(pixel_count * pal_img_n); + if (p == NULL) return e("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + free(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi_unpremultiply_on_load = 0; +static int stbi_de_iphone_flag = 0; + +void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply; +} +void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi_de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi_de_iphone(png *z) +{ + stbi *s = z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + assert(s->img_out_n == 4); + if (stbi_unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + uint8 a = p[3]; + uint8 t = p[0]; + if (a) { + p[0] = p[2] * 255 / a; + p[1] = p[1] * 255 / a; + p[2] = t * 255 / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +static int parse_png_file(png *z, int scan, int req_comp) +{ + uint8 palette[1024], pal_img_n=0; + uint8 has_trans=0, tc[3]; + uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, iphone=0; + stbi *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!check_png_header(s)) return 0; + + if (scan == SCAN_type) return 1; + + for (;;) { + chunk c = get_chunk_header(s); + switch (c.type) { + case PNG_TYPE('C','g','B','I'): + iphone = stbi_de_iphone_flag; + skip(s, c.length); + break; + case PNG_TYPE('I','H','D','R'): { + int depth,color,comp,filter; + if (!first) return e("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return e("bad IHDR len","Corrupt PNG"); + s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)"); + s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)"); + depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only"); + color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG"); + comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG"); + filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG"); + interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + if (scan == SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case PNG_TYPE('P','L','T','E'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = get8u(s); + palette[i*4+1] = get8u(s); + palette[i*4+2] = get8u(s); + palette[i*4+3] = 255; + } + break; + } + + case PNG_TYPE('t','R','N','S'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (z->idata) return e("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = get8u(s); + } else { + if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG"); + if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG"); + has_trans = 1; + for (k=0; k < s->img_n; ++k) + tc[k] = (uint8) get16(s); // non 8-bit images will be larger + } + break; + } + + case PNG_TYPE('I','D','A','T'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG"); + if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; } + if (ioff + c.length > idata_limit) { + uint8 *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL) return e("outofmem", "Out of memory"); + z->idata = p; + } + if (!getn(s, z->idata+ioff,c.length)) return e("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case PNG_TYPE('I','E','N','D'): { + uint32 raw_len; + if (first) return e("first not IHDR", "Corrupt PNG"); + if (scan != SCAN_load) return 1; + if (z->idata == NULL) return e("no IDAT","Corrupt PNG"); + z->expanded = (uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, 16384, (int *) &raw_len, !iphone); + if (z->expanded == NULL) return 0; // zlib should set error + free(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; + if (has_trans) + if (!compute_transparency(z, tc, s->img_out_n)) return 0; + if (iphone && s->img_out_n > 2) + stbi_de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!expand_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + free(z->expanded); z->expanded = NULL; + return 1; + } + + default: + // if critical, fail + if (first) return e("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX chunk not known"; + invalid_chunk[0] = (uint8) (c.type >> 24); + invalid_chunk[1] = (uint8) (c.type >> 16); + invalid_chunk[2] = (uint8) (c.type >> 8); + invalid_chunk[3] = (uint8) (c.type >> 0); + #endif + return e(invalid_chunk, "PNG not supported: unknown chunk type"); + } + skip(s, c.length); + break; + } + // end of chunk, read and skip CRC + get32(s); + } +} + +static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp) +{ + unsigned char *result=NULL; + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + if (parse_png_file(p, SCAN_load, req_comp)) { + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + result = convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + free(p->out); p->out = NULL; + free(p->expanded); p->expanded = NULL; + free(p->idata); p->idata = NULL; + + return result; +} + +static unsigned char *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + png p; + p.s = s; + return do_png(&p, x,y,comp,req_comp); +} + +static int stbi_png_test(stbi *s) +{ + int r; + r = check_png_header(s); + stbi_rewind(s); + return r; +} + +static int stbi_png_info_raw(png *p, int *x, int *y, int *comp) +{ + if (!parse_png_file(p, SCAN_header, 0)) { + stbi_rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi_png_info(stbi *s, int *x, int *y, int *comp) +{ + png p; + p.s = s; + return stbi_png_info_raw(&p, x, y, comp); +} + +// Microsoft/Windows BMP image + +static int bmp_test(stbi *s) +{ + int sz; + if (get8(s) != 'B') return 0; + if (get8(s) != 'M') return 0; + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + get32le(s); // discard data offset + sz = get32le(s); + if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; + return 0; +} + +static int stbi_bmp_test(stbi *s) +{ + int r = bmp_test(s); + stbi_rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; +} + +static int bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +static int shiftsigned(int v, int shift, int bits) +{ + int result; + int z=0; + + if (shift < 0) v <<= -shift; + else v >>= shift; + result = v; + + z = bits; + while (z < 8) { + result += v >> z; + z += bits; + } + return result; +} + +static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + uint8 *out; + unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; + stbi_uc pal[256][4]; + int psize=0,i,j,compress=0,width; + int bpp, flip_vertically, pad, target, offset, hsz; + if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP"); + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + offset = get32le(s); + hsz = get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = get16le(s); + s->img_y = get16le(s); + } else { + s->img_x = get32le(s); + s->img_y = get32le(s); + } + if (get16le(s) != 1) return epuc("bad BMP", "bad BMP"); + bpp = get16le(s); + if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit"); + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + if (hsz == 12) { + if (bpp < 24) + psize = (offset - 14 - 24) / 3; + } else { + compress = get32le(s); + if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE"); + get32le(s); // discard sizeof + get32le(s); // discard hres + get32le(s); // discard vres + get32le(s); // discard colorsused + get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + get32le(s); + get32le(s); + get32le(s); + get32le(s); + } + if (bpp == 16 || bpp == 32) { + mr = mg = mb = 0; + if (compress == 0) { + if (bpp == 32) { + mr = 0xffu << 16; + mg = 0xffu << 8; + mb = 0xffu << 0; + ma = 0xffu << 24; + fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 + } else { + mr = 31u << 10; + mg = 31u << 5; + mb = 31u << 0; + } + } else if (compress == 3) { + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (mr == mg && mg == mb) { + // ?!?!? + return epuc("bad BMP", "bad BMP"); + } + } else + return epuc("bad BMP", "bad BMP"); + } + } else { + assert(hsz == 108); + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + ma = get32le(s); + get32le(s); // discard color space + for (i=0; i < 12; ++i) + get32le(s); // discard color space parameters + } + if (bpp < 16) + psize = (offset - 14 - hsz) >> 2; + } + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + out = (stbi_uc *) malloc(target * s->img_x * s->img_y); + if (!out) return epuc("outofmem", "Out of memory"); + if (bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + if (hsz != 12) get8(s); + pal[i][3] = 255; + } + skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); + if (bpp == 4) width = (s->img_x + 1) >> 1; + else if (bpp == 8) width = s->img_x; + else { free(out); return epuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=get8(s),v2=0; + if (bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (bpp == 8) ? get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + skip(s, pad); + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + skip(s, offset - 14 - hsz); + if (bpp == 24) width = 3 * s->img_x; + else if (bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (bpp == 24) { + easy = 1; + } else if (bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { free(out); return epuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = high_bit(mr)-7; rcount = bitcount(mr); + gshift = high_bit(mg)-7; gcount = bitcount(mr); + bshift = high_bit(mb)-7; bcount = bitcount(mr); + ashift = high_bit(ma)-7; acount = bitcount(mr); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + int a; + out[z+2] = get8u(s); + out[z+1] = get8u(s); + out[z+0] = get8u(s); + z += 3; + a = (easy == 2 ? get8(s) : 255); + if (target == 4) out[z++] = (uint8) a; + } + } else { + for (i=0; i < (int) s->img_x; ++i) { + uint32 v = (bpp == 16 ? get16le(s) : get32le(s)); + int a; + out[z++] = (uint8) shiftsigned(v & mr, rshift, rcount); + out[z++] = (uint8) shiftsigned(v & mg, gshift, gcount); + out[z++] = (uint8) shiftsigned(v & mb, bshift, bcount); + a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); + if (target == 4) out[z++] = (uint8) a; + } + } + skip(s, pad); + } + } + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} + +static stbi_uc *stbi_bmp_load(stbi *s,int *x, int *y, int *comp, int req_comp) +{ + return bmp_load(s, x,y,comp,req_comp); +} + + +// Targa Truevision - TGA +// by Jonathan Dummer + +static int tga_info(stbi *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp; + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if( sz > 1 ) { + stbi_rewind(s); + return 0; // only RGB or indexed allowed + } + sz = get8u(s); // image type + // only RGB or grey allowed, +/- RLE + if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; + skip(s,9); + tga_w = get16le(s); + if( tga_w < 1 ) { + stbi_rewind(s); + return 0; // test width + } + tga_h = get16le(s); + if( tga_h < 1 ) { + stbi_rewind(s); + return 0; // test height + } + sz = get8(s); // bits per pixel + // only RGB or RGBA or grey allowed + if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) { + stbi_rewind(s); + return 0; + } + tga_comp = sz; + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp / 8; + return 1; // seems to have passed everything +} + +int stbi_tga_info(stbi *s, int *x, int *y, int *comp) +{ + return tga_info(s, x, y, comp); +} + +static int tga_test(stbi *s) +{ + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if ( sz > 1 ) return 0; // only RGB or indexed allowed + sz = get8u(s); // image type + if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE + get16(s); // discard palette start + get16(s); // discard palette length + get8(s); // discard bits per palette color entry + get16(s); // discard x origin + get16(s); // discard y origin + if ( get16(s) < 1 ) return 0; // test width + if ( get16(s) < 1 ) return 0; // test height + sz = get8(s); // bits per pixel + if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) return 0; // only RGB or RGBA or grey allowed + return 1; // seems to have passed everything +} + +static int stbi_tga_test(stbi *s) +{ + int res = tga_test(s); + stbi_rewind(s); + return res; +} + +static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + // read in the TGA header stuff + int tga_offset = get8u(s); + int tga_indexed = get8u(s); + int tga_image_type = get8u(s); + int tga_is_RLE = 0; + int tga_palette_start = get16le(s); + int tga_palette_len = get16le(s); + int tga_palette_bits = get8u(s); + int tga_x_origin = get16le(s); + int tga_y_origin = get16le(s); + int tga_width = get16le(s); + int tga_height = get16le(s); + int tga_bits_per_pixel = get8u(s); + int tga_inverted = get8u(s); + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4]; + unsigned char trans_data[4]; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + /* int tga_alpha_bits = tga_inverted & 15; */ + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // error check + if ( //(tga_indexed) || + (tga_width < 1) || (tga_height < 1) || + (tga_image_type < 1) || (tga_image_type > 3) || + ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && + (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) + ) + { + return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA + } + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) + { + tga_bits_per_pixel = tga_palette_bits; + } + + // tga info + *x = tga_width; + *y = tga_height; + if ( (req_comp < 1) || (req_comp > 4) ) + { + // just use whatever the file was + req_comp = tga_bits_per_pixel / 8; + *comp = req_comp; + } else + { + // force a new number of components + *comp = tga_bits_per_pixel/8; + } + tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp ); + if (!tga_data) return epuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + skip(s, tga_offset ); + // do I need to load a palette? + if ( tga_indexed ) + { + // any data to skip? (offset usually = 0) + skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 ); + if (!tga_palette) return epuc("outofmem", "Out of memory"); + if (!getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) { + free(tga_data); + free(tga_palette); + return epuc("bad palette", "Corrupt TGA"); + } + } + // load the data + trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0; + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE chunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = get8u(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in 1 byte, then perform the lookup + int pal_idx = get8u(s); + if ( pal_idx >= tga_palette_len ) + { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_bits_per_pixel / 8; + for (j = 0; j*8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else + { + // read in the data raw + for (j = 0; j*8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = get8u(s); + } + } + // convert raw to the intermediate format + switch (tga_bits_per_pixel) + { + case 8: + // Luminous => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 16: + // Luminous,Alpha => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[1]; + break; + case 24: + // BGR => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 32: + // BGRA => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[3]; + break; + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + // convert to final format + switch (req_comp) + { + case 1: + // RGBA => Luminance + tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); + break; + case 2: + // RGBA => Luminance,Alpha + tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); + tga_data[i*req_comp+1] = trans_data[3]; + break; + case 3: + // RGBA => RGB + tga_data[i*req_comp+0] = trans_data[0]; + tga_data[i*req_comp+1] = trans_data[1]; + tga_data[i*req_comp+2] = trans_data[2]; + break; + case 4: + // RGBA => RGBA + tga_data[i*req_comp+0] = trans_data[0]; + tga_data[i*req_comp+1] = trans_data[1]; + tga_data[i*req_comp+2] = trans_data[2]; + tga_data[i*req_comp+3] = trans_data[3]; + break; + } + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * req_comp; + int index2 = (tga_height - 1 - j) * tga_width * req_comp; + for (i = tga_width * req_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + free( tga_palette ); + } + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; +} + +static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return tga_load(s,x,y,comp,req_comp); +} + + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +static int psd_test(stbi *s) +{ + if (get32(s) != 0x38425053) return 0; // "8BPS" + else return 1; +} + +static int stbi_psd_test(stbi *s) +{ + int r = psd_test(s); + stbi_rewind(s); + return r; +} + +static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + int pixelCount; + int channelCount, compression; + int channel, i, count, len; + int w,h; + uint8 *out; + + // Check identifier + if (get32(s) != 0x38425053) // "8BPS" + return epuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (get16(s) != 1) + return epuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = get16(s); + if (channelCount < 0 || channelCount > 16) + return epuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = get32(s); + w = get32(s); + + // Make sure the depth is 8 bits. + if (get16(s) != 8) + return epuc("unsupported bit depth", "PSD bit depth is not 8 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (get16(s) != 3) + return epuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + skip(s,get32(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + skip(s, get32(s) ); + + // Skip the reserved data. + skip(s, get32(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = get16(s); + if (compression > 1) + return epuc("bad compression", "PSD has an unknown compression format"); + + // Create the destination image. + out = (stbi_uc *) malloc(4 * w*h); + if (!out) return epuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + uint8 *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; + } else { + // Read the RLE data. + count = 0; + while (count < pixelCount) { + len = get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + count += len; + while (len) { + *p = get8u(s); + p += 4; + len--; + } + } else if (len > 128) { + uint8 val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len ^= 0x0FF; + len += 2; + val = get8u(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + uint8 *p; + + p = out + channel; + if (channel > channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; + } else { + // Read the data. + for (i = 0; i < pixelCount; i++) + *p = get8u(s), p += 4; + } + } + } + + if (req_comp && req_comp != 4) { + out = convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // convert_format frees input on failure + } + + if (comp) *comp = channelCount; + *y = h; + *x = w; + + return out; +} + +static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return psd_load(s,x,y,comp,req_comp); +} + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +static int pic_is4(stbi *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int pic_test(stbi *s) +{ + int i; + + if (!pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + get8(s); + + if (!pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} pic_packet_t; + +static stbi_uc *pic_readval(stbi *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (at_eof(s)) return epuc("bad file","PIC file too short"); + dest[i]=get8u(s); + } + } + + return dest; +} + +static void pic_copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + pic_packet_t packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + pic_packet_t *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return epuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = get8(s); + packet->size = get8u(s); + packet->type = get8u(s); + packet->channel = get8u(s); + + act_comp |= packet->channel; + + if (at_eof(s)) return epuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return epuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return epuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=get8u(s); + if (at_eof(s)) return epuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (uint8) left; + + if (!pic_readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = get8(s), i; + if (at_eof(s)) return epuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + int i; + + if (count==128) + count = get16(s); + else + count -= 127; + if (count > left) + return epuc("bad file","scanline overrun"); + + if (!pic_readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return epuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static stbi_uc *pic_load(stbi *s,int *px,int *py,int *comp,int req_comp) +{ + stbi_uc *result; + int i, x,y; + + for (i=0; i<92; ++i) + get8(s); + + x = get16(s); + y = get16(s); + if (at_eof(s)) return epuc("bad file","file too short (pic header)"); + if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode"); + + get32(s); //skip `ratio' + get16(s); //skip `fields' + get16(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) malloc(x*y*4); + memset(result, 0xff, x*y*4); + + if (!pic_load2(s,x,y,comp, result)) { + free(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi_pic_test(stbi *s) +{ + int r = pic_test(s); + stbi_rewind(s); + return r; +} + +static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return pic_load(s,x,y,comp,req_comp); +} + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb +typedef struct stbi_gif_lzw_struct { + int16 prefix; + uint8 first; + uint8 suffix; +} stbi_gif_lzw; + +typedef struct stbi_gif_struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + int flags, bgindex, ratio, transparent, eflags; + uint8 pal[256][4]; + uint8 lpal[256][4]; + stbi_gif_lzw codes[4096]; + uint8 *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; +} stbi_gif; + +static int gif_test(stbi *s) +{ + int sz; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') return 0; + sz = get8(s); + if (sz != '9' && sz != '7') return 0; + if (get8(s) != 'a') return 0; + return 1; +} + +static int stbi_gif_test(stbi *s) +{ + int r = gif_test(s); + stbi_rewind(s); + return r; +} + +static void stbi_gif_parse_colortable(stbi *s, uint8 pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + pal[i][3] = transp ? 0 : 255; + } +} + +static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info) +{ + uint8 version; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') + return e("not GIF", "Corrupt GIF"); + + version = get8u(s); + if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF"); + if (get8(s) != 'a') return e("not GIF", "Corrupt GIF"); + + failure_reason = ""; + g->w = get16le(s); + g->h = get16le(s); + g->flags = get8(s); + g->bgindex = get8(s); + g->ratio = get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi_gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi_gif_info_raw(stbi *s, int *x, int *y, int *comp) +{ + stbi_gif g; + if (!stbi_gif_header(s, &g, comp, 1)) { + stbi_rewind( s ); + return 0; + } + if (x) *x = g.w; + if (y) *y = g.h; + return 1; +} + +static void stbi_out_gif_code(stbi_gif *g, uint16 code) +{ + uint8 *p, *c; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi_out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + p = &g->out[g->cur_x + g->cur_y]; + c = &g->color_table[g->codes[code].suffix * 4]; + + if (c[3] >= 128) { + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g) +{ + uint8 lzw_cs; + int32 len, code; + uint32 first; + int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi_gif_lzw *p; + + lzw_cs = get8u(s); + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (code = 0; code < clear; code++) { + g->codes[code].prefix = -1; + g->codes[code].first = (uint8) code; + g->codes[code].suffix = (uint8) code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (int32) get8(s) << valid_bits; + valid_bits += 8; + } else { + int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + skip(s, len); + while ((len = get8(s)) > 0) + skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) return epuc("no clear code", "Corrupt GIF"); + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 4096) return epuc("too many codes", "Corrupt GIF"); + p->prefix = (int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return epuc("illegal code in raster", "Corrupt GIF"); + + stbi_out_gif_code(g, (uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return epuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +static void stbi_fill_gif_background(stbi_gif *g) +{ + int i; + uint8 *c = g->pal[g->bgindex]; + // @OPTIMIZE: write a dword at a time + for (i = 0; i < g->w * g->h * 4; i += 4) { + uint8 *p = &g->out[i]; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +static uint8 *stbi_gif_load_next(stbi *s, stbi_gif *g, int *comp, int req_comp) +{ + int i; + uint8 *old_out = 0; + + if (g->out == 0) { + if (!stbi_gif_header(s, g, comp,0)) return 0; // failure_reason set by stbi_gif_header + g->out = (uint8 *) malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + stbi_fill_gif_background(g); + } else { + // animated-gif-only path + if (((g->eflags & 0x1C) >> 2) == 3) { + old_out = g->out; + g->out = (uint8 *) malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + memcpy(g->out, old_out, g->w*g->h*4); + } + } + + for (;;) { + switch (get8(s)) { + case 0x2C: /* Image Descriptor */ + { + int32 x, y, w, h; + uint8 *o; + + x = get16le(s); + y = get16le(s); + w = get16le(s); + h = get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return epuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + g->lflags = get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi_gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (uint8 *) g->lpal; + } else if (g->flags & 0x80) { + for (i=0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent + g->pal[i][3] = 255; + if (g->transparent >= 0 && (g->eflags & 0x01)) + g->pal[g->transparent][3] = 0; + g->color_table = (uint8 *) g->pal; + } else + return epuc("missing color table", "Corrupt GIF"); + + o = stbi_process_gif_raster(s, g); + if (o == NULL) return NULL; + + if (req_comp && req_comp != 4) + o = convert_format(o, 4, req_comp, g->w, g->h); + return o; + } + + case 0x21: // Comment Extension. + { + int len; + if (get8(s) == 0xF9) { // Graphic Control Extension. + len = get8(s); + if (len == 4) { + g->eflags = get8(s); + get16le(s); // delay + g->transparent = get8(s); + } else { + skip(s, len); + break; + } + } + while ((len = get8(s)) != 0) + skip(s, len); + break; + } + + case 0x3B: // gif stream termination code + return (uint8 *) 1; + + default: + return epuc("unknown code", "Corrupt GIF"); + } + } +} + +static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + uint8 *u = 0; + stbi_gif g={0}; + + u = stbi_gif_load_next(s, &g, comp, req_comp); + if (u == (void *) 1) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + } + + return u; +} + +static int stbi_gif_info(stbi *s, int *x, int *y, int *comp) +{ + return stbi_gif_info_raw(s,x,y,comp); +} + + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int hdr_test(stbi *s) +{ + const char *signature = "#?RADIANCE\n"; + int i; + for (i=0; signature[i]; ++i) + if (get8(s) != signature[i]) + return 0; + return 1; +} + +static int stbi_hdr_test(stbi* s) +{ + int r = hdr_test(s); + stbi_rewind(s); + return r; +} + +#define HDR_BUFLEN 1024 +static char *hdr_gettoken(stbi *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) get8(z); + + while (!at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == HDR_BUFLEN-1) { + // flush to end of line + while (!at_eof(z) && get8(z) != '\n') + ; + break; + } + c = (char) get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + char buffer[HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + + + // Check identifier + if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + return epf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return epf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = strtol(token, NULL, 10); + + *x = width; + *y = height; + + *comp = 3; + if (req_comp == 0) req_comp = 3; + + // Read data + hdr_data = (float *) malloc(height * width * req_comp * sizeof(float)); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + getn(s, rgbe, 4); + hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = get8(s); + c2 = get8(s); + len = get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + uint8 rgbe[4]; + rgbe[0] = (uint8) c1; + rgbe[1] = (uint8) c2; + rgbe[2] = (uint8) len; + rgbe[3] = (uint8) get8u(s); + hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + free(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= get8(s); + if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4); + + for (k = 0; k < 4; ++k) { + i = 0; + while (i < width) { + count = get8u(s); + if (count > 128) { + // Run + value = get8u(s); + count -= 128; + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = get8u(s); + } + } + } + for (i=0; i < width; ++i) + hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + free(scanline); + } + + return hdr_data; +} + +static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + return hdr_load(s,x,y,comp,req_comp); +} + +static int stbi_hdr_info(stbi *s, int *x, int *y, int *comp) +{ + char buffer[HDR_BUFLEN]; + char *token; + int valid = 0; + + if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) { + stbi_rewind( s ); + return 0; + } + + for(;;) { + token = hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi_rewind( s ); + return 0; + } + token = hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi_rewind( s ); + return 0; + } + token += 3; + *y = strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi_rewind( s ); + return 0; + } + token += 3; + *x = strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +static int stbi_bmp_info(stbi *s, int *x, int *y, int *comp) +{ + int hsz; + if (get8(s) != 'B' || get8(s) != 'M') { + stbi_rewind( s ); + return 0; + } + skip(s,12); + hsz = get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) { + stbi_rewind( s ); + return 0; + } + if (hsz == 12) { + *x = get16le(s); + *y = get16le(s); + } else { + *x = get32le(s); + *y = get32le(s); + } + if (get16le(s) != 1) { + stbi_rewind( s ); + return 0; + } + *comp = get16le(s) / 8; + return 1; +} + +static int stbi_psd_info(stbi *s, int *x, int *y, int *comp) +{ + int channelCount; + if (get32(s) != 0x38425053) { + stbi_rewind( s ); + return 0; + } + if (get16(s) != 1) { + stbi_rewind( s ); + return 0; + } + skip(s, 6); + channelCount = get16(s); + if (channelCount < 0 || channelCount > 16) { + stbi_rewind( s ); + return 0; + } + *y = get32(s); + *x = get32(s); + if (get16(s) != 8) { + stbi_rewind( s ); + return 0; + } + if (get16(s) != 3) { + stbi_rewind( s ); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi_pic_info(stbi *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained; + pic_packet_t packets[10]; + + skip(s, 92); + + *x = get16(s); + *y = get16(s); + if (at_eof(s)) return 0; + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi_rewind( s ); + return 0; + } + + skip(s, 8); + + do { + pic_packet_t *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = get8(s); + packet->size = get8u(s); + packet->type = get8u(s); + packet->channel = get8u(s); + act_comp |= packet->channel; + + if (at_eof(s)) { + stbi_rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi_rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} + +static int stbi_info_main(stbi *s, int *x, int *y, int *comp) +{ + if (stbi_jpeg_info(s, x, y, comp)) + return 1; + if (stbi_png_info(s, x, y, comp)) + return 1; + if (stbi_gif_info(s, x, y, comp)) + return 1; + if (stbi_bmp_info(s, x, y, comp)) + return 1; + if (stbi_psd_info(s, x, y, comp)) + return 1; + if (stbi_pic_info(s, x, y, comp)) + return 1; + #ifndef STBI_NO_HDR + if (stbi_hdr_info(s, x, y, comp)) + return 1; + #endif + // test tga last because it's a crappy test! + if (stbi_tga_info(s, x, y, comp)) + return 1; + return e("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_STDIO +int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = fopen(filename, "rb"); + int result; + if (!f) return e("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi s; + long pos = ftell(f); + start_file(&s, f); + r = stbi_info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi s; + start_mem(&s,buffer,len); + return stbi_info_main(&s,x,y,comp); +} + +int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi s; + start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi_info_main(&s,x,y,comp); +} + +#endif // STBI_HEADER_FILE_ONLY + +/* + revision history: + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-uint8 to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.e. Janez (U+017D)emva) + 1.21 fix use of 'uint8' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 2008-08-02 + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 first released version +*/ diff --git a/Demos/OpenGL/stb_image.h b/Demos/OpenGL/stb_image.h new file mode 100644 index 0000000..9df58d6 --- /dev/null +++ b/Demos/OpenGL/stb_image.h @@ -0,0 +1,332 @@ +/* stbi-1.33 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c + when you control the images you're loading + no warranty implied; use at your own risk + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline (no JPEG progressive) + PNG 8-bit only + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) + + Latest revisions: + 1.33 (2011-07-14) minor fixes suggested by Dave Moore + 1.32 (2011-07-13) info support for all filetypes (SpartanJ) + 1.31 (2011-06-19) a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) added ability to load files via io callbacks (Ben Wenger) + 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila) + allow trailing 0s at end of image data (Laurent Gomila) + 1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ + + See end of file for full revision history. + + TODO: + stbi_info support for BMP,PSD,HDR,PIC + + + ============================ Contributors ========================= + + Image formats Optimizations & bugfixes + Sean Barrett (jpeg, png, bmp) Fabian "ryg" Giesen + Nicolas Schulz (hdr, psd) + Jonathan Dummer (tga) Bug fixes & warning fixes + Jean-Marc Lienher (gif) Marc LeBlanc + Tom Seddon (pic) Christpher Lloyd + Thatcher Ulrich (psd) Dave Moore + Won Chun + the Horde3D community + Extensions, features Janez Zemva + Jetro Lauha (stbi_info) Jonathan Blow + James "moose2000" Brown (iPhone PNG) Laurent Gomila + Ben "Disch" Wenger (io callbacks) Aruelien Pocheville + Martin "SpartanJ" Golini Ryamond Barbiero + David Woo + + + If your name should be here but isn't, let Sean know. + +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// To get a header file for this, either cut and paste the header, +// or create stb_image.h, #define STBI_HEADER_FILE_ONLY, and +// then include stb_image.c from it. + +//// begin header file //////////////////////////////////////////////////// +// +// Limitations: +// - no jpeg progressive support +// - non-HDR formats support 8-bit samples only (jpeg, png) +// - no delayed line count (jpeg) -- IJG doesn't support either +// - no 1-bit BMP +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *comp -- outputs # of image components in image file +// int req_comp -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. +// If req_comp is non-zero, *comp has the number of components that _would_ +// have been output otherwise. E.g. if you set req_comp to 4, you will always +// get RGBA output, but you can check *comp to easily see if it's opaque. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() +// can be queried for an extremely brief, end-user unfriendly explanation +// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid +// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB; nominally they +// would silently load as BGR, except the existing code should have just +// failed on such iPhone PNGs. But you can disable this conversion by +// by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through. +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image now supports loading HDR images in general, and currently +// the Radiance .HDR file format, although the support is provided +// generically. You can still load any file through the existing interface; +// if you attempt to load an HDR file, it will be automatically remapped to +// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). + + +#ifndef STBI_NO_STDIO + +#if defined(_MSC_VER) && _MSC_VER >= 0x1400 +#define _CRT_SECURE_NO_WARNINGS // suppress bogus warnings about fopen() +#endif + +#include +#endif + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for req_comp + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +typedef unsigned char stbi_uc; + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_STDIO +extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,unsigned n); // skip the next 'n' bytes + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +extern stbi_uc *stbi_load_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_HDR + extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + + #ifndef STBI_NO_STDIO + extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); + extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + #endif + + extern float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + + extern void stbi_hdr_to_ldr_gamma(float gamma); + extern void stbi_hdr_to_ldr_scale(float scale); + + extern void stbi_ldr_to_hdr_gamma(float gamma); + extern void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_HDR + +// stbi_is_hdr is always defined +extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +extern int stbi_is_hdr (char const *filename); +extern int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// NOT THREADSAFE +extern const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +extern void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +extern int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +extern int stbi_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); + +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + + +// ZLIB client - used by PNG, available for other purposes + +extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +// define faster low-level operations (typically SIMD support) +#ifdef STBI_SIMD +typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize); +// compute an integer IDCT on "input" +// input[x] = data[x] * dequantize[x] +// write results to 'out': 64 samples, each run of 8 spaced by 'out_stride' +// CLAMP results to 0..255 +typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step); +// compute a conversion from YCbCr to RGB +// 'count' pixels +// write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B +// y: Y input channel +// cb: Cb input channel; scale/biased to be 0..255 +// cr: Cr input channel; scale/biased to be 0..255 + +extern void stbi_install_idct(stbi_idct_8x8 func); +extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); +#endif // STBI_SIMD + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H diff --git a/Demos/OpenPL_Demo/CApi.cpp b/Demos/OpenPL_Demo/CApi.cpp new file mode 100644 index 0000000..171c770 --- /dev/null +++ b/Demos/OpenPL_Demo/CApi.cpp @@ -0,0 +1,159 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including +*/ + +#include "Bullet-C-Api.h" +#include "btBulletDynamicsCommon.h" + +/* + Create and Delete a Physics SDK +*/ + +plPhysicsSdkHandle plNewBulletSdk() +{ + return 0; +} + +void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk) +{ + +} + +/* Dynamics World */ +plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk) +{ + return (plDynamicsWorldHandle) new btDiscreteDynamicsWorld; +} +void plDeleteDynamicsWorld(plDynamicsWorldHandle world) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + delete dynamicsWorld; +} + +void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + assert(dynamicsWorld); + dynamicsWorld->stepSimulation(timeStep); +} + +void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + assert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + assert(body); + + dynamicsWorld->addRigidBody(body); +} + +void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + assert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + assert(body); + + dynamicsWorld->removeRigidBody(body); +} + +/* Rigid Body */ + +plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape ) +{ + btTransform trans; + trans.setIdentity(); + btVector3 localInertia; + btCollisionShape* shape = reinterpret_cast( cshape); + assert(shape); + shape->calculateLocalInertia(mass,localInertia); + btRigidBody* body = new btRigidBody(mass, trans,shape,localInertia); + body->m_userObjectPointer = user_data; + return (plRigidBodyHandle) body; +} + +void plDeleteRigidBody(plRigidBodyHandle cbody) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody); + assert(body); + delete body; +} + + +/* Collision Shape definition */ + +plCollisionShapeHandle plNewSphereShape(plReal radius) +{ + return (plCollisionShapeHandle) new btSphereShape(radius); + +} + +plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z) +{ + return (plCollisionShapeHandle) new btBoxShape(btVector3(x,y,z)); +} + +plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height) +{ + //capsule is convex hull of 2 spheres, so use btMultiSphereShape + btVector3 inertiaHalfExtents(radius,height,radius); + const int numSpheres = 2; + btVector3 positions[numSpheres] = {btVector3(0,height,0),btVector3(0,-height,0)}; + btScalar radi[numSpheres] = {radius,radius}; + return (plCollisionShapeHandle) new btMultiSphereShape(inertiaHalfExtents,positions,radi,numSpheres); +} +plCollisionShapeHandle plNewConeShape(plReal radius, plReal height) +{ + return (plCollisionShapeHandle) new btConeShape(radius,height); +} + +plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height) +{ + return (plCollisionShapeHandle) new btCylinderShape(btVector3(radius,height,radius)); +} + +void plDeleteShape(plCollisionShapeHandle cshape) +{ + btCollisionShape* shape = reinterpret_cast( cshape); + assert(shape); + delete shape; +} +void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling) +{ + btCollisionShape* shape = reinterpret_cast( cshape); + assert(shape); + btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]); + shape->setLocalScaling(scaling); +} + + + +void plSetPosition(plRigidBodyHandle object, const plVector3 position) +{ +} +void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation) +{ +} + + +//plRigidBodyHandle plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); + +// extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); diff --git a/Demos/OpenPL_Demo/OpenPL_Demo.c b/Demos/OpenPL_Demo/OpenPL_Demo.c new file mode 100644 index 0000000..cef1f76 --- /dev/null +++ b/Demos/OpenPL_Demo/OpenPL_Demo.c @@ -0,0 +1,44 @@ + +#include "Bullet-C-Api.h" + + +int main() +{ + float timeStep = 1.f/60.f; + + /* initialize */ + plPhysicsSdkHandle sdk = plNewBulletSdk(); + + plDynamicsWorldHandle world = plCreateDynamicsWorld(sdk); + + + float radius = 1.f; + plCollisionShapeHandle collisionShape = plNewSphereShape(radius); + + void* user_data = 0;/* can point to a graphics object */ + + float mass = 1.f; + + plRigidBodyHandle body = plCreateRigidBody(user_data, mass, collisionShape ); + + plAddRigidBody(world, body); + + + + plStepSimulation(world,0.1f); + + /* cleanup */ + + plRemoveRigidBody(world, body); + + + plDeleteRigidBody(body); + + plDeleteShape( collisionShape); + + plDeleteDynamicsWorld( world); + + plDeletePhysicsSdk(sdk); + + return 0; +} \ No newline at end of file diff --git a/Demos/ParticlesOpenCL/AMD/CMakeLists.txt b/Demos/ParticlesOpenCL/AMD/CMakeLists.txt new file mode 100644 index 0000000..972fb50 --- /dev/null +++ b/Demos/ParticlesOpenCL/AMD/CMakeLists.txt @@ -0,0 +1,86 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${AMD_OPENCL_INCLUDES} +) + +ADD_DEFINITIONS(-DUSE_AMD_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_AMD) + +IF(WIN32) + ADD_DEFINITIONS(-DGLEW_STATIC) + IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY + ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) + ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) + ENDIF(CMAKE_CL_64) +else() + SET(CMAK_GLEW_LIBRARY GLEW) +endIF(WIN32) + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletDynamics + BulletCollision + BulletMultiThreaded + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ${CMAKE_ATISTREAMSDK_LIBRARY} + ) + + + ADD_EXECUTABLE(AppParticlesOCL_AMD + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedDefs.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedTypes.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.h + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.cpp + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppParticlesOCL_AMD pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppParticlesOCL_AMD PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppParticlesOCL_AMD PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppParticlesOCL_AMD PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/ParticlesOpenCL/Apple/CMakeLists.txt b/Demos/ParticlesOpenCL/Apple/CMakeLists.txt new file mode 100644 index 0000000..22ecedb --- /dev/null +++ b/Demos/ParticlesOpenCL/Apple/CMakeLists.txt @@ -0,0 +1,84 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +IF (APPLE) + FIND_LIBRARY(OPENCL_LIBRARY OpenCL DOC "OpenCL lib for OSX") + FIND_PATH(OPENCL_INCLUDE_DIR OpenCL/cl.h DOC "Include for OpenCL on OSX") +ENDIF (APPLE) + + +#ADD_DEFINITIONS(-DUSE_MINICL) + +IF(WIN32) +IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64.lib ) +ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32.lib ) +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletDynamics + BulletCollision + LinearMath + ${OPENCL_LIBRARY} + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ) + + + ADD_EXECUTABLE(AppParticlesOCL_Apple + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedDefs.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedTypes.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Apple POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Apple POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLEW64.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Apple POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Apple POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLEW32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + +ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Apple POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl ${CMAKE_CURRENT_BINARY_DIR}) + + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppParticlesOCL_Apple pthread) +ENDIF(UNIX) + diff --git a/Demos/ParticlesOpenCL/CMakeLists.txt b/Demos/ParticlesOpenCL/CMakeLists.txt new file mode 100644 index 0000000..369414d --- /dev/null +++ b/Demos/ParticlesOpenCL/CMakeLists.txt @@ -0,0 +1,19 @@ +IF(BUILD_MINICL_OPENCL_DEMOS) + SUBDIRS( MiniCL ) +ENDIF() + +IF(BUILD_INTEL_OPENCL_DEMOS) + SUBDIRS(Intel) +ENDIF() + +IF(BUILD_AMD_OPENCL_DEMOS) + SUBDIRS(AMD) +ENDIF() + +IF(BUILD_NVIDIA_OPENCL_DEMOS) + SUBDIRS(NVidia) +ENDIF() + +IF(APPLE) + SUBDIRS(Apple) +ENDIF() diff --git a/Demos/ParticlesOpenCL/Intel/CMakeLists.txt b/Demos/ParticlesOpenCL/Intel/CMakeLists.txt new file mode 100644 index 0000000..ff73111 --- /dev/null +++ b/Demos/ParticlesOpenCL/Intel/CMakeLists.txt @@ -0,0 +1,86 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${INTEL_OPENCL_INCLUDES} +) + +ADD_DEFINITIONS(-DUSE_INTEL_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_INTEL) + +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + +IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY + ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) +ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) +ENDIF(CMAKE_CL_64) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletDynamics + BulletCollision + BulletMultiThreaded + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ${INTEL_OPENCL_LIBRARIES} + ) + + + ADD_EXECUTABLE(AppParticlesOCL_Intel + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedDefs.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedTypes.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.h + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.cpp + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Intel POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Intel POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Intel POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Intel POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppParticlesOCL_Intel pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppParticlesOCL_Intel PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppParticlesOCL_Intel PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppParticlesOCL_Intel PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/ParticlesOpenCL/MiniCL/CMakeLists.txt b/Demos/ParticlesOpenCL/MiniCL/CMakeLists.txt new file mode 100644 index 0000000..b97fe0b --- /dev/null +++ b/Demos/ParticlesOpenCL/MiniCL/CMakeLists.txt @@ -0,0 +1,94 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +ADD_DEFINITIONS(-DUSE_MINICL) + +#to get this to compile under linux, you could try setting CMAK_GLEW_LIBRARY +#to /usr/lib/libGLEW.so + +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + +IF(WIN32) +IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) +ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + +IF(UNIX AND NOT APPLE) + SET(CMAK_GLEW_LIBRARY /usr/lib/libGLEW.so ) +ENDIF(UNIX AND NOT APPLE) + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletDynamics + BulletCollision + MiniCL + BulletMultiThreaded + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ) + + + ADD_EXECUTABLE(AppParticlesOCL_Mini + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedDefs.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedTypes.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/MiniCL/MiniCLTaskWrap.cpp + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Mini POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Mini POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + +ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Mini POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl ${CMAKE_CURRENT_BINARY_DIR}) + + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppParticlesOCL_Mini pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppParticlesOCL_Mini PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppParticlesOCL_Mini PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppParticlesOCL_Mini PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ParticlesOpenCL/MiniCL/MiniCLTaskWrap.cpp b/Demos/ParticlesOpenCL/MiniCL/MiniCLTaskWrap.cpp new file mode 100644 index 0000000..9f0c023 --- /dev/null +++ b/Demos/ParticlesOpenCL/MiniCL/MiniCLTaskWrap.cpp @@ -0,0 +1,33 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include + +#define MSTRINGIFY(A) A +#define LOCAL_SIZE_MAX 1024U + +#include "../ParticlesOCL.cl" + +MINICL_REGISTER(kComputeCellId) +MINICL_REGISTER(kClearCellStart) +MINICL_REGISTER(kFindCellStart) +MINICL_REGISTER(kIntegrateMotion) +MINICL_REGISTER(kCollideParticles) +MINICL_REGISTER(kBitonicSortCellIdLocal) +MINICL_REGISTER(kBitonicSortCellIdLocal1) +MINICL_REGISTER(kBitonicSortCellIdMergeGlobal) +MINICL_REGISTER(kBitonicSortCellIdMergeLocal) + diff --git a/Demos/ParticlesOpenCL/NVidia/CMakeLists.txt b/Demos/ParticlesOpenCL/NVidia/CMakeLists.txt new file mode 100644 index 0000000..1241f21 --- /dev/null +++ b/Demos/ParticlesOpenCL/NVidia/CMakeLists.txt @@ -0,0 +1,95 @@ + + +ADD_DEFINITIONS(-DUSE_NVIDIA_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_NVIDIA) + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${NVIDIA_OPENCL_INCLUDES} +) + +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + +IF(WIN32) + IF (CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib ) + ELSE(CMAKE_CL_64) + SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib ) + ENDIF(CMAKE_CL_64) +ELSE() + IF(UNIX AND NOT APPLE) + FIND_LIBRARY(CMAK_GLEW_LIBRARY GLEW PATH /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64 ) + ENDIF() +ENDIF(WIN32) + +IF(CMAK_GLEW_LIBRARY) + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletDynamics + BulletCollision + LinearMath + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ${NVIDIA_OPENCL_LIBRARIES} + ) + + ADD_EXECUTABLE(AppParticlesOCL_Nv + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedDefs.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesSharedTypes.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.h + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/shaders.cpp + + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl + ) +ELSE (USE_GLUT) +ENDIF (USE_GLUT) + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Nv POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Nv POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(CMAKE_CL_64) + + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppParticlesOCL_Nv POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/ParticlesOpenCL/ParticlesOCL.cl ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(WIN32) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppParticlesOCL_Nv pthread) +ENDIF(UNIX) + +ENDIF(CMAK_GLEW_LIBRARY) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppParticlesOCL_Nv PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppParticlesOCL_Nv PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppParticlesOCL_Nv PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/ParticlesOpenCL/ParticlesDemo.cpp b/Demos/ParticlesOpenCL/ParticlesDemo.cpp new file mode 100644 index 0000000..64f0b47 --- /dev/null +++ b/Demos/ParticlesOpenCL/ParticlesDemo.cpp @@ -0,0 +1,651 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#define START_POS_X btScalar(0.f) +#define START_POS_Y btScalar(0.f) +#define START_POS_Z btScalar(0.f) +//#define START_POS_Y btScalar(40.f) +//#define START_POS_Z btScalar(40.f) +//#define START_POS_Y btScalar(0.4f) +//#define START_POS_Z btScalar(0.4f) +#define ARRAY_SIZE_X 32 +#define ARRAY_SIZE_Y 32 +//#define ARRAY_SIZE_Y 16 +#define ARRAY_SIZE_Z 32 +//16 +//#define ARRAY_SIZE_Z 1 +//#define DIST btScalar(2.f) +#define DIST (DEF_PARTICLE_RADIUS * 2.f) + +#define STRESS_X 20 +//#define STRESS_Y 200 +#define STRESS_Y 640 + + + + + +///The 3 following lines include the CPU implementation of the kernels, keep them in this order. +#include "BulletMultiThreaded/btGpuDefines.h" +#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "BulletMultiThreaded/btGpuUtilsSharedCode.h" +#ifndef __APPLE__ +#include +#endif + + +#include "GL_DialogDynamicsWorld.h" +#include "GL_DialogWindow.h" + + + +#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" +#include "GLDebugFont.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include //printf debugging +#include "shaders.h" + +#include "ParticlesDemo.h" + + + + + +btScalar gTimeStep = 0.5f;//btScalar(1./60.); + +#define SCALING btScalar(1.f) + +void ParticlesDemo::clientMoveAndDisplay() +{ + + + updateCamera(); + glDisable(GL_LIGHTING); + glColor3f(1.f, 1.f, 1.f); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glDisable(GL_TEXTURE_2D); // we always draw wireframe in this demo + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + renderme(); + + if (m_dialogDynamicsWorld) + m_dialogDynamicsWorld->draw(gTimeStep); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(gTimeStep,0);//ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + + + ms = getDeltaTimeMicroseconds(); + + glFlush(); + + glutSwapBuffers(); + +} + + + +void ParticlesDemo::displayCallback(void) { + + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + //if (m_dialogDynamicsWorld) + // m_dialogDynamicsWorld->draw(gTimeStep); + + glFlush(); + glutSwapBuffers(); +} + +class btNullBroadphase : public btBroadphaseInterface +{ +public: + btNullBroadphase() + { + } + virtual ~btNullBroadphase() + { + } + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) + { + return NULL; + } + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) + { + } + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher) + { + } + virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const + { + } + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) + { + } + virtual void calculateOverlappingPairs(btDispatcher* dispatcher) + { + } + virtual btOverlappingPairCache* getOverlappingPairCache() + { + return NULL; + } + virtual const btOverlappingPairCache* getOverlappingPairCache() const + { + return NULL; + } + virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const + { + } + virtual void resetPool(btDispatcher* dispatcher) + { + } + virtual void printStats() + { + } + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) + { + } +}; + + + +void ParticlesDemo::initPhysics() +{ + + setTexturing(false); + setShadows(false); + +// setCameraDistance(80.f); + setCameraDistance(3.0f); +// m_cameraTargetPosition.setValue(50, 10, 0); + m_cameraTargetPosition.setValue(0, 0, 0); +// m_azi = btScalar(0.f); +// m_ele = btScalar(0.f); + m_azi = btScalar(45.f); + m_ele = btScalar(30.f); + setFrustumZPlanes(0.1f, 10.f); + + ///collision configuration contains default setup for memory, collision setup + + btDefaultCollisionConstructionInfo dci; + dci.m_defaultMaxPersistentManifoldPoolSize=50000; + dci.m_defaultMaxCollisionAlgorithmPoolSize=50000; + + m_collisionConfiguration = new btDefaultCollisionConfiguration(dci); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_pairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16))btHashedOverlappingPairCache(); + + +// m_broadphase = new btDbvtBroadphase(m_pairCache); + m_broadphase = new btNullBroadphase(); + + ///the default constraint solver + m_solver = new btSequentialImpulseConstraintSolver(); + + m_pWorld = new btParticlesDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, 65536); + + m_dialogDynamicsWorld = new GL_DialogDynamicsWorld(); + GL_DialogWindow* settings = m_dialogDynamicsWorld->createDialog(50,0,280,280,"CPU fallback"); + + m_pWorld->m_useCpuControls[0] = 0; + GL_ToggleControl* ctrl = 0; + m_pWorld->m_useCpuControls[SIMSTAGE_INTEGRATE_MOTION] = m_dialogDynamicsWorld->createToggle(settings,"Integrate Motion"); + m_pWorld->m_useCpuControls[SIMSTAGE_COMPUTE_CELL_ID] = m_dialogDynamicsWorld->createToggle(settings,"Compute Cell ID"); + m_pWorld->m_useCpuControls[SIMSTAGE_SORT_CELL_ID] = m_dialogDynamicsWorld->createToggle(settings,"Sort Cell ID"); + m_pWorld->m_useCpuControls[SIMSTAGE_FIND_CELL_START] = m_dialogDynamicsWorld->createToggle(settings,"Find Cell Start"); + m_pWorld->m_useCpuControls[SIMSTAGE_COLLIDE_PARTICLES] = m_dialogDynamicsWorld->createToggle(settings,"Collide Particles"); + + + for(int i = 1; i < SIMSTAGE_TOTAL; i++) + { + m_pWorld->m_useCpuControls[i]->m_active = false; + } +#if defined(CL_PLATFORM_MINI_CL) + // these kernels use barrier() + m_pWorld->m_useCpuControls[SIMSTAGE_SORT_CELL_ID]->m_active = true; + m_pWorld->m_useCpuControls[SIMSTAGE_FIND_CELL_START]->m_active = true; +#endif + +#if defined(CL_PLATFORM_AMD) + // these kernels use barrier() + m_pWorld->m_useCpuControls[SIMSTAGE_SORT_CELL_ID]->m_active = true; + m_pWorld->m_useCpuControls[SIMSTAGE_FIND_CELL_START]->m_active = true; +#endif + + + m_dynamicsWorld = m_pWorld; + + m_pWorld->getSimulationIslandManager()->setSplitIslands(true); + m_pWorld->setGravity(btVector3(0,-10.,0)); + m_pWorld->getSolverInfo().m_numIterations = 4; + + { +// btCollisionShape* colShape = new btSphereShape(btScalar(1.0f)); +/* + btCollisionShape* colShape = new btSphereShape(DEF_PARTICLE_RADIUS); + m_collisionShapes.push_back(colShape); + btTransform startTransform; + startTransform.setIdentity(); + btScalar mass(1.f); + btVector3 localInertia(0,0,0); + colShape->calculateLocalInertia(mass,localInertia); + float start_x = START_POS_X - ARRAY_SIZE_X * DIST * btScalar(0.5f); + float start_y = START_POS_Y - ARRAY_SIZE_Y * DIST * btScalar(0.5f); + float start_z = START_POS_Z - ARRAY_SIZE_Z * DIST * btScalar(0.5f); + startTransform.setOrigin(btVector3(start_x, start_y, start_z)); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); + rbInfo.m_startWorldTransform = startTransform; + btRigidBody* body = new btRigidBody(rbInfo); + m_pWorld->addRigidBody(body); + */ + + init_scene_directly(); + } + clientResetScene(); + m_pWorld->initDeviceData(); +} + +inline float frand(void){ + return (float)rand() / (float)RAND_MAX; +} + +void ParticlesDemo::init_scene_directly() +{ + + + srand(1969); + float start_x = -1+DEF_PARTICLE_RADIUS;//START_POS_X - ARRAY_SIZE_X * DIST * btScalar(0.5f); + float start_y = -1+DEF_PARTICLE_RADIUS;//START_POS_Y - ARRAY_SIZE_Y * DIST * btScalar(0.5f); + float start_z = -1+DEF_PARTICLE_RADIUS;//START_POS_Z - ARRAY_SIZE_Z * DIST * btScalar(0.5f); + int numParticles = ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z; + m_pWorld->m_hPos.resize(numParticles); + m_pWorld->m_hVel.resize(numParticles); + + btScalar spacing = 2 * DEF_PARTICLE_RADIUS; + + for(int z=0; zm_hVel[i]= btVector3(0,0,0); + m_pWorld->m_hPos[i].setX((spacing * x) + 2*DEF_PARTICLE_RADIUS -WORLD_SIZE+jitter.getX()); + m_pWorld->m_hPos[i].setY((spacing * y) + 2*DEF_PARTICLE_RADIUS -WORLD_SIZE+jitter.getY()); + m_pWorld->m_hPos[i].setZ((spacing * z) + 2*DEF_PARTICLE_RADIUS -WORLD_SIZE+jitter.getZ()); + } + } + } + } + + m_pWorld->m_numParticles = numParticles; + +} + + +void ParticlesDemo::clientResetScene() +{ + static bool bFirstCall = true; + DemoApplication::clientResetScene(); + init_scene_directly(); + if(bFirstCall) + { + bFirstCall = false; + } + else + { + + m_pWorld->grabSimulationData(); + } +} + + +void ParticlesDemo::exitPhysics() +{ + delete m_dialogDynamicsWorld; + m_dialogDynamicsWorld = 0; + + //cleanup in the reverse order of creation/initialization + int i; + + //remove the rigidbodies from the dynamics world and delete them + for (i=m_pWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_pWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_pWorld->removeCollisionObject( obj ); + delete obj; + } + //delete collision shapes + for (int j=0;j m_glutScreenHeight) ? m_glutScreenHeight : m_glutScreenWidth; + glUniform1f( glGetUniformLocation(m_shaderProgram, "pointScale"), dist ); +// glUniform1f( glGetUniformLocation(m_shaderProgram, "pointRadius"), 0.5f ); + int numParticles = m_pWorld->getNumParticles(); + int col_vbo = m_pWorld->m_colVbo; + int curr_vbo = m_pWorld->m_vbo; + float sphere_rad = m_pWorld->m_particleRad; + + glUniform1f( glGetUniformLocation(m_shaderProgram, "pointRadius"), sphere_rad ); + glColor3f(1, 1, 1); + + // render from the vbo + glBindBuffer(GL_ARRAY_BUFFER, curr_vbo); + glVertexPointer(4, GL_FLOAT, 0, 0); + glEnableClientState(GL_VERTEX_ARRAY); + if(col_vbo) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, col_vbo); + glColorPointer(4, GL_FLOAT, 0, 0); + glEnableClientState(GL_COLOR_ARRAY); + } + glDrawArrays(GL_POINTS, 0, numParticles); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glUseProgram(0); + glDisable(GL_POINT_SPRITE_ARB); + glBindBufferARB(GL_ARRAY_BUFFER,0); + if(m_drawGridMode) + { + btVector3& wmin = m_pWorld->m_worldMin; + btVector3& wmax = m_pWorld->m_worldMax; + glBegin(GL_LINE_LOOP); + glVertex3f(wmin[0], wmin[1], wmin[2]); + glVertex3f(wmin[0], wmax[1], wmin[2]); + glVertex3f(wmax[0], wmax[1], wmin[2]); + glVertex3f(wmax[0], wmin[1], wmin[2]); + glVertex3f(wmax[0], wmin[1], wmax[2]); + glVertex3f(wmax[0], wmax[1], wmax[2]); + glVertex3f(wmin[0], wmax[1], wmax[2]); + glVertex3f(wmin[0], wmin[1], wmax[2]); + glEnd(); + glBegin(GL_LINES); + glVertex3f(wmin[0], wmin[1], wmin[2]); + glVertex3f(wmax[0], wmin[1], wmin[2]); + glVertex3f(wmin[0], wmin[1], wmax[2]); + glVertex3f(wmax[0], wmin[1], wmax[2]); + glVertex3f(wmin[0], wmax[1], wmin[2]); + glVertex3f(wmin[0], wmax[1], wmax[2]); + glVertex3f(wmax[0], wmax[1], wmin[2]); + glVertex3f(wmax[0], wmax[1], wmax[2]); + glEnd(); + if(m_drawGridMode == 2) + { + int szx = m_pWorld->m_simParams.m_gridSize[0]; + int szy = m_pWorld->m_simParams.m_gridSize[1]; + glBegin(GL_LINES); + for(int i = 1; i < (szx-1); i++) + { + float wgt = (float)i / (float)(szx-1); + btVector3 vtx = wmax * wgt + wmin * (1.0f - wgt); + glVertex3f(vtx[0], wmin[1], wmin[2]); + glVertex3f(vtx[0], wmax[1], wmin[2]); + } + for(int i = 1; i < (szy-1); i++) + { + float wgt = (float)i / (float)(szy-1); + btVector3 vtx = wmax * wgt + wmin * (1.0f - wgt); + glVertex3f(wmin[0], vtx[1], wmin[2]); + glVertex3f(wmax[0], vtx[1], wmin[2]); + } + glEnd(); + } + } + + if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0) + { + setOrthographicProjection(); + int xOffset = 10.f; + int yStart = 20.f; + int yIncr = 20.f; + showProfileInfo(xOffset, yStart, yIncr); + outputDebugInfo(xOffset, yStart, yIncr); + resetPerspectiveProjection(); + } +} + + + +void ParticlesDemo::outputDebugInfo(int & xOffset,int & yStart, int yIncr) +{ + char buf[124]; + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + + sprintf(buf,"mouse move+buttons to interact"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"space to reset"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"cursor keys and z,x to navigate"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"i to toggle simulation, s single step"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"q to quit"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"h to toggle help text"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + + sprintf(buf,"p to toggle profiling (+results to file)"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + sprintf(buf,"j to toggle between demos (integration/OECake2D/OECake3D)"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + { + sprintf(buf,"G to draw broadphase grid"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + sprintf(buf,"D and U to toggle between GPU and CPU"); + GLDebugDrawString(xOffset,yStart,buf); + yStart += yIncr; + + } + +} + + +GLuint _compileProgram(const char *vsource, const char *fsource) +{ + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + + glShaderSource(vertexShader, 1, &vsource, 0); + glShaderSource(fragmentShader, 1, &fsource, 0); + + glCompileShader(vertexShader); + glCompileShader(fragmentShader); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + + glLinkProgram(program); + + // check if program linked + GLint success = 0; + glGetProgramiv(program, GL_LINK_STATUS, &success); + + if (!success) { + char temp[256]; + glGetProgramInfoLog(program, 256, 0, temp); + printf("Failed to link program:\n%s\n", temp); + glDeleteProgram(program); + program = 0; + } + return program; +} + + +void ParticlesDemo::myinit() +{ + DemoApplication::myinit(); +#ifndef __APPLE__ + glewInit(); + if (!glewIsSupported("GL_VERSION_2_0 GL_VERSION_1_5 GL_ARB_multitexture GL_ARB_vertex_buffer_object")) { + fprintf(stderr, "Required OpenGL extensions missing."); + exit(-1); + } +#endif //__APPLE__ + + m_shaderProgram = _compileProgram(vertexShader, spherePixelShader); + m_pWorld->initCLKernels(m_argc, m_argv); +} + + + + + + +void ParticlesDemo::mouseFunc(int button, int state, int x, int y) +{ + + if (!m_dialogDynamicsWorld->mouseFunc(button,state,x,y)) + { + DemoApplication::mouseFunc(button,state,x,y); + } +} + +void ParticlesDemo::mouseMotionFunc(int x,int y) +{ + m_dialogDynamicsWorld->mouseMotionFunc(x,y); + DemoApplication::mouseMotionFunc(x,y); +} + + + +void ParticlesDemo::reshape(int w, int h) +{ + if (m_dialogDynamicsWorld) + m_dialogDynamicsWorld->setScreenSize(w,h); + GlutDemoApplication::reshape(w,h); +} + diff --git a/Demos/ParticlesOpenCL/ParticlesDemo.h b/Demos/ParticlesOpenCL/ParticlesDemo.h new file mode 100644 index 0000000..76c165b --- /dev/null +++ b/Demos/ParticlesOpenCL/ParticlesDemo.h @@ -0,0 +1,128 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SPHERES_GRID_DEMO_H +#define SPHERES_GRID_DEMO_H + +#define USE_BULLET_BODIES 0 + +///enable one or both options (NVidia profiler doesn't support multi-OpenCL context) +#define INTEGRATION_DEMO 1 +#define SPHERES_DEMO 1 + +#include "DemoApplication.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" + +#include "btParticlesDynamicsWorld.h" + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; +#include "../OpenGL/GlutDemoApplication.h" + + +///BasicDemo is good starting point for learning the code base and porting. +class ParticlesDemo : public GlutDemoApplication +{ + + class GL_DialogDynamicsWorld* m_dialogDynamicsWorld; + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + btOverlappingPairCache* m_pairCache; + + int m_mouseButtons; + int m_mouseOldX; + int m_mouseOldY; + + int m_argc; + char** m_argv; + + public: + + int m_drawGridMode; + int m_GpuCpuTogglePtr; + + btParticlesDynamicsWorld* m_pWorld; + + + // shader + GLuint m_shaderProgram; + + ParticlesDemo(int argc, char** argv) + { + m_argc = argc; + m_argv = argv; + m_drawGridMode = 0; + m_GpuCpuTogglePtr = SIMSTAGE_NONE; + m_dialogDynamicsWorld = 0; + } + virtual ~ParticlesDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + virtual void clientResetScene(); + + virtual void mouseFunc(int button, int state, int x, int y); + virtual void mouseMotionFunc(int x,int y); + virtual void reshape(int w, int h); +/* + static DemoApplication* Create() + { + SpheresGridDemo* demo = new SpheresGridDemo; + demo->myinit(); + demo->initPhysics(); + demo->m_mouseButtons = 0; + demo->m_mouseOldX = 0; + demo->m_mouseOldY = 0; + return demo; + } +*/ + + void outputDebugInfo(int & xOffset,int & yStart, int yIncr); + + + virtual void renderme(); + virtual void myinit(); + void init_scene_directly(); + +}; + + +#endif // PARTICLES_DEMO_H + diff --git a/Demos/ParticlesOpenCL/ParticlesOCL.cl b/Demos/ParticlesOpenCL/ParticlesOCL.cl new file mode 100644 index 0000000..2e80e3a --- /dev/null +++ b/Demos/ParticlesOpenCL/ParticlesOCL.cl @@ -0,0 +1,467 @@ +MSTRINGIFY( + +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +int4 getGridPos(float4 worldPos, __global float4* pParams) +{ + int4 gridPos; + gridPos.x = (int)floor((worldPos.x - pParams[1].x) / pParams[3].x); + gridPos.y = (int)floor((worldPos.y - pParams[1].y) / pParams[3].y); + gridPos.z = (int)floor((worldPos.z - pParams[1].z) / pParams[3].z); + return gridPos; +} + +unsigned int getPosHash(int4 gridPos, __global float4* pParams) +{ + int4 gridDim = *((__global int4*)(pParams + 4)); + if(gridPos.x < 0) gridPos.x = 0; + if(gridPos.x >= gridDim.x) gridPos.x = gridDim.x - 1; + if(gridPos.y < 0) gridPos.y = 0; + if(gridPos.y >= gridDim.y) gridPos.y = gridDim.y - 1; + if(gridPos.z < 0) gridPos.z = 0; + if(gridPos.z >= gridDim.z) gridPos.z = gridDim.z - 1; + unsigned int hash = gridPos.z * gridDim.y * gridDim.x + gridPos.y * gridDim.x + gridPos.x; + return hash; +} + + +__kernel void kComputeCellId( int numParticles, + __global float4* pPos, + __global int2* pPosHash, + __global float4* pParams GUID_ARG) +{ + int index = get_global_id(0); + if(index >= numParticles) + { + return; + } + float4 pos = pPos[index]; + int4 gridPos = getGridPos(pos, pParams); + unsigned int hash = getPosHash(gridPos, pParams); + pPosHash[index].x = hash; + pPosHash[index].y = index; +} + +__kernel void kClearCellStart( int numCells, + __global int* pCellStart GUID_ARG) +{ + int index = get_global_id(0); + if(index >= numCells) + { + return; + } + pCellStart[index] = -1; +} + +__kernel void kFindCellStart( int numParticles, + __global int2* pHash, + __global int* cellStart, + __global float4* pPos, + __global float4* pVel, + __global float4* pSortedPos, + __global float4* pSortedVel GUID_ARG) +{ + int index = get_global_id(0); + __local int sharedHash[1025];//maximum workgroup size 1024 + int2 sortedData; + + if(index < numParticles) + { + + sortedData = pHash[index]; + // Load hash data into shared memory so that we can look + // at neighboring body's hash value without loading + // two hash values per thread + sharedHash[get_local_id(0) + 1] = sortedData.x; + if((index > 0) && (get_local_id(0) == 0)) + { + // first thread in block must load neighbor body hash + sharedHash[0] = pHash[index-1].x; + } + + } + barrier(CLK_LOCAL_MEM_FENCE); + + if(index < numParticles) + { + if((index == 0) || (sortedData.x != sharedHash[get_local_id(0)])) + { + cellStart[sortedData.x] = index; + } + int unsortedIndex = sortedData.y; + float4 pos = pPos[unsortedIndex]; + float4 vel = pVel[unsortedIndex]; + pSortedPos[index] = pos; + pSortedVel[index] = vel; + } +} + +__kernel void kIntegrateMotion( int numParticles, + __global float4* pPos, + __global float4* pVel, + __global float4* pParams, + float timeStep GUID_ARG) +{ + int index = get_global_id(0); + if(index >= numParticles) + { + return; + } + float4 pos = pPos[index]; + float4 vel = pVel[index]; + pos.w = 1.0f; + vel.w = 0.0f; + // apply gravity + float4 gravity = *((__global float4*)(pParams + 0)); + float particleRad = pParams[5].x; + float globalDamping = pParams[5].y; + float boundaryDamping = pParams[5].z; + vel += gravity * timeStep; + vel *= globalDamping; + // integrate position + pos += vel * timeStep; + // collide with world boundaries + float4 worldMin = *((__global float4*)(pParams + 1)); + float4 worldMax = *((__global float4*)(pParams + 2)); + + + if(pos.x < (worldMin.x + 2*particleRad)) + { + pos.x = worldMin.x + 2*particleRad; + vel.x *= boundaryDamping; + } + if(pos.x > (worldMax.x - 2*particleRad)) + { + pos.x = worldMax.x - 2*particleRad; + vel.x *= boundaryDamping; + } + if(pos.y < (worldMin.y + 2*particleRad)) + { + pos.y = worldMin.y + 2*particleRad; + vel.y *= boundaryDamping; + } + if(pos.y > (worldMax.y - 2*particleRad)) + { + pos.y = worldMax.y - 2*particleRad; + vel.y *= boundaryDamping; + } + if(pos.z < (worldMin.z + 2*particleRad)) + { + pos.z = worldMin.z + 2*particleRad; + vel.z *= boundaryDamping; + } + if(pos.z > (worldMax.z - 2*particleRad)) + { + pos.z = worldMax.z - 2*particleRad; + vel.z *= boundaryDamping; + } + // write back position and velocity + pPos[index] = pos; + pVel[index] = vel; +} + + +float4 collideTwoParticles( + float4 posA, + float4 posB, + float4 velA, + float4 velB, + float radiusA, + float radiusB, + float spring, + float damping, + float shear, + float attraction +) +{ + //Calculate relative position + float4 relPos = posB - posA; relPos.w = 0.f; + float dist = sqrt(relPos.x * relPos.x + relPos.y * relPos.y + relPos.z * relPos.z); + float collideDist = radiusA + radiusB; + + float4 force = (float4)0.f; + if(dist < collideDist){ + float4 norm = relPos * (1.f / dist); norm.w = 0.f; + + //Relative velocity + float4 relVel = velB - velA; relVel.w = 0.f; + + //Relative tangential velocity + float relVelDotNorm = relVel.x * norm.x + relVel.y * norm.y + relVel.z * norm.z; + float4 tanVel = relVel - norm * relVelDotNorm; tanVel.w = 0.f; + + //Spring force (potential) + float springFactor = -spring * (collideDist - dist); + force = springFactor * norm + damping * relVel + shear * tanVel + attraction * relPos; + force.w = 0.f; + } + return force; +} + + +__kernel void kCollideParticles(int numParticles, + __global float4* pVel, //output: new velocity + __global const float4* pSortedPos, //input: reordered positions + __global const float4* pSortedVel, //input: reordered velocities + __global const int2 *pPosHash, //input: reordered particle indices + __global const int *pCellStart, //input: cell boundaries + __global float4* pParams GUID_ARG) +{ + int index = get_global_id(0); + if(index >= numParticles) + { + return; + } + + float4 posA = pSortedPos[index]; + float4 velA = pSortedVel[index]; + float4 force = (float4)0.f; + float particleRad = pParams[5].x; + float collisionDamping = pParams[5].w; + float spring = pParams[6].x; + float shear = pParams[6].y; + float attraction = pParams[6].z; + int unsortedIndex = pPosHash[index].y; + + //Get address in grid + int4 gridPosA = getGridPos(posA, pParams); + + //Accumulate surrounding cells + int4 gridPosB; + for(int z = -1; z <= 1; z++) + { + gridPosB.z = gridPosA.z + z; + for(int y = -1; y <= 1; y++) + { + gridPosB.y = gridPosA.y + y; + for(int x = -1; x <= 1; x++) + { + gridPosB.x = gridPosA.x + x; + //Get start particle index for this cell + uint hashB = getPosHash(gridPosB, pParams); + int startI = pCellStart[hashB]; + //Skip empty cell + if(startI < 0) + { + continue; + } + //Iterate over particles in this cell + int endI = startI + 32; + if(endI >= numParticles) + endI = numParticles ; + + for(int j = startI; j < endI; j++) + { + uint hashC = pPosHash[j].x; + if(hashC != hashB) + { + break; + } + if(j == index) + { + continue; + } + float4 posB = pSortedPos[j]; + float4 velB = pSortedVel[j]; + //Collide two spheres + force += collideTwoParticles( posA, posB, velA, velB, particleRad, particleRad, + spring, collisionDamping, shear, attraction); + } + } + } + } + //Write new velocity back to original unsorted location + pVel[unsortedIndex] = velA + force; +} + + + + + + +/* + * Copyright 1993-2009 NVIDIA Corporation. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and + * proprietary rights in and to this software and related documentation. + * Any use, reproduction, disclosure, or distribution of this software + * and related documentation without an express license agreement from + * NVIDIA Corporation is strictly prohibited. + * + * Please refer to the applicable NVIDIA end user license agreement (EULA) + * associated with this source code for terms and conditions that govern + * your use of this NVIDIA software. + * + */ + + + +inline void ComparatorPrivate(int2* keyA, int2* keyB, uint dir) +{ + if((keyA[0].x > keyB[0].x) == dir) + { + int2 tmp = *keyA; + *keyA = *keyB; + *keyB = tmp; + } +} + +inline void ComparatorLocal(__local int2* keyA, __local int2* keyB, uint dir) +{ + if((keyA[0].x > keyB[0].x) == dir) + { + int2 tmp = *keyA; + *keyA = *keyB; + *keyB = tmp; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Monolithic bitonic sort kernel for short arrays fitting into local memory +//////////////////////////////////////////////////////////////////////////////// +__kernel void kBitonicSortCellIdLocal(__global int2* pKey, uint arrayLength, uint dir GUID_ARG) +{ + __local int2 l_key[LOCAL_SIZE_MAX]; + int localSizeLimit = get_local_size(0) * 2; + + //Offset to the beginning of subbatch and load data + pKey += get_group_id(0) * localSizeLimit + get_local_id(0); + l_key[get_local_id(0) + 0] = pKey[ 0]; + l_key[get_local_id(0) + (localSizeLimit / 2)] = pKey[(localSizeLimit / 2)]; + + for(uint size = 2; size < arrayLength; size <<= 1) + { + //Bitonic merge + uint ddd = dir ^ ( (get_local_id(0) & (size / 2)) != 0 ); + for(uint stride = size / 2; stride > 0; stride >>= 1) + { + barrier(CLK_LOCAL_MEM_FENCE); + uint pos = 2 * get_local_id(0) - (get_local_id(0) & (stride - 1)); + ComparatorLocal(&l_key[pos + 0], &l_key[pos + stride], ddd); + } + } + + //ddd == dir for the last bitonic merge step + { + for(uint stride = arrayLength / 2; stride > 0; stride >>= 1) + { + barrier(CLK_LOCAL_MEM_FENCE); + uint pos = 2 * get_local_id(0) - (get_local_id(0) & (stride - 1)); + ComparatorLocal(&l_key[pos + 0], &l_key[pos + stride], dir); + } + } + + barrier(CLK_LOCAL_MEM_FENCE); + pKey[ 0] = l_key[get_local_id(0) + 0]; + pKey[(localSizeLimit / 2)] = l_key[get_local_id(0) + (localSizeLimit / 2)]; +} + +//////////////////////////////////////////////////////////////////////////////// +// Bitonic sort kernel for large arrays (not fitting into local memory) +//////////////////////////////////////////////////////////////////////////////// +//Bottom-level bitonic sort +//Almost the same as bitonicSortLocal with the only exception +//of even / odd subarrays (of LOCAL_SIZE_LIMIT points) being +//sorted in opposite directions +__kernel void kBitonicSortCellIdLocal1(__global int2* pKey GUID_ARG) +{ + __local int2 l_key[LOCAL_SIZE_MAX]; + uint localSizeLimit = get_local_size(0) * 2; + + //Offset to the beginning of subarray and load data + pKey += get_group_id(0) * localSizeLimit + get_local_id(0); + l_key[get_local_id(0) + 0] = pKey[ 0]; + l_key[get_local_id(0) + (localSizeLimit / 2)] = pKey[(localSizeLimit / 2)]; + + uint comparatorI = get_global_id(0) & ((localSizeLimit / 2) - 1); + + for(uint size = 2; size < localSizeLimit; size <<= 1) + { + //Bitonic merge + uint ddd = (comparatorI & (size / 2)) != 0; + for(uint stride = size / 2; stride > 0; stride >>= 1) + { + barrier(CLK_LOCAL_MEM_FENCE); + uint pos = 2 * get_local_id(0) - (get_local_id(0) & (stride - 1)); + ComparatorLocal(&l_key[pos + 0], &l_key[pos + stride], ddd); + } + } + + //Odd / even arrays of localSizeLimit elements + //sorted in opposite directions + { + uint ddd = (get_group_id(0) & 1); + for(uint stride = localSizeLimit / 2; stride > 0; stride >>= 1) + { + barrier(CLK_LOCAL_MEM_FENCE); + uint pos = 2 * get_local_id(0) - (get_local_id(0) & (stride - 1)); + ComparatorLocal(&l_key[pos + 0], &l_key[pos + stride], ddd); + } + } + + barrier(CLK_LOCAL_MEM_FENCE); + pKey[ 0] = l_key[get_local_id(0) + 0]; + pKey[(localSizeLimit / 2)] = l_key[get_local_id(0) + (localSizeLimit / 2)]; +} + +//Bitonic merge iteration for 'stride' >= LOCAL_SIZE_LIMIT +__kernel void kBitonicSortCellIdMergeGlobal(__global int2* pKey, uint arrayLength, uint size, uint stride, uint dir GUID_ARG) +{ + uint global_comparatorI = get_global_id(0); + uint comparatorI = global_comparatorI & (arrayLength / 2 - 1); + + //Bitonic merge + uint ddd = dir ^ ( (comparatorI & (size / 2)) != 0 ); + uint pos = 2 * global_comparatorI - (global_comparatorI & (stride - 1)); + + int2 keyA = pKey[pos + 0]; + int2 keyB = pKey[pos + stride]; + + ComparatorPrivate(&keyA, &keyB, ddd); + + pKey[pos + 0] = keyA; + pKey[pos + stride] = keyB; +} + +//Combined bitonic merge steps for +//'size' > LOCAL_SIZE_LIMIT and 'stride' = [1 .. LOCAL_SIZE_LIMIT / 2] +__kernel void kBitonicSortCellIdMergeLocal(__global int2* pKey, uint arrayLength, uint stride, uint size, uint dir GUID_ARG) +{ + __local int2 l_key[LOCAL_SIZE_MAX]; + int localSizeLimit = get_local_size(0) * 2; + + pKey += get_group_id(0) * localSizeLimit + get_local_id(0); + l_key[get_local_id(0) + 0] = pKey[ 0]; + l_key[get_local_id(0) + (localSizeLimit / 2)] = pKey[(localSizeLimit / 2)]; + + //Bitonic merge + uint comparatorI = get_global_id(0) & ((arrayLength / 2) - 1); + uint ddd = dir ^ ( (comparatorI & (size / 2)) != 0 ); + for(; stride > 0; stride >>= 1) + { + barrier(CLK_LOCAL_MEM_FENCE); + uint pos = 2 * get_local_id(0) - (get_local_id(0) & (stride - 1)); + ComparatorLocal(&l_key[pos + 0], &l_key[pos + stride], ddd); + } + + barrier(CLK_LOCAL_MEM_FENCE); + pKey[ 0] = l_key[get_local_id(0) + 0]; + pKey[(localSizeLimit / 2)] = l_key[get_local_id(0) + (localSizeLimit / 2)]; +} + +); diff --git a/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp b/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp new file mode 100644 index 0000000..8bbced4 --- /dev/null +++ b/Demos/ParticlesOpenCL/btParticlesDemoDynamicsWorld.cpp @@ -0,0 +1,1177 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#ifdef __APPLE__ +//CL_PLATFORM_MINI_CL could be defined in build system +#else +#include +#ifdef USE_MINICL + +#include //for CL_PLATFORM_MINI_CL definition +#else +#include //for CL_PLATFORM_MINI_CL definition +#endif +#endif //__APPLE__ + + +#include "btOpenCLUtils.h" + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "LinearMath/btQuickprof.h" +#include "GlutStuff.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" + +#include "btParticlesDynamicsWorld.h" +#include "GL_DialogWindow.h" + +//when loading from disk, you need to remove the 'MSTRINGIFY' line at the start, and ); at the end of the .cl file + +#define LOAD_FROM_MEMORY +#ifdef LOAD_FROM_MEMORY +#define MSTRINGIFY(A) #A +static const char* source= +#include "ParticlesOCL.cl" +#endif //LOAD_FROM_MEMORY + +btParticlesDynamicsWorld::~btParticlesDynamicsWorld() +{ +} + +static int gStepNum = 0; + +int btParticlesDynamicsWorld::stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) +{ + startProfiling(timeStep); + m_timeStep = timeStep; + BT_PROFILE("stepSimulation"); +// printf("Step : %d\n", gStepNum); + { + BT_PROFILE("IntegrateMotion"); + runIntegrateMotionKernel(); + } + { + runComputeCellIdKernel(); + } + { + BT_PROFILE("SortHash"); + runSortHashKernel(); + } + { + BT_PROFILE("FindCellStart"); + runFindCellStartKernel(); + } + { + BT_PROFILE("CollideParticles"); +// printf("\ncollide particles\n\n"); + runCollideParticlesKernel(); + } + gStepNum++; + +#ifndef BT_NO_PROFILE + CProfileManager::Increment_Frame_Counter(); +#endif //BT_NO_PROFILE + return 1; +} + +static unsigned int getMaxPowOf2(unsigned int num) +{ + unsigned int maxPowOf2 = 1; + for(int bit = 1; bit < 32; bit++) + { + if(maxPowOf2 >= num) + { + break; + } + maxPowOf2 <<= 1; + } + return maxPowOf2; +} + + +void btParticlesDynamicsWorld::initDeviceData() +{ + getShapeData(); +} + + + +void btParticlesDynamicsWorld::postInitDeviceData() +{ + m_hashSize = getMaxPowOf2(m_numParticles); + createVBO(); + allocateBuffers(); + adjustGrid(); + grabSimulationData(); +} + + +void btParticlesDynamicsWorld::getShapeData() +{ + int numObjects = getNumCollisionObjects(); + btCollisionObjectArray& collisionObjects = getCollisionObjectArray(); + for(int i = 0; i < numObjects; i++) + { + btCollisionObject* colObj = collisionObjects[i]; + btCollisionShape* pShape = colObj->getCollisionShape(); + int shapeType = pShape->getShapeType(); + if(shapeType == SPHERE_SHAPE_PROXYTYPE) + { + btSphereShape* pSph = (btSphereShape*)pShape; + btScalar sphRad = pSph->getRadius(); + if(!i) + { + m_particleRad = sphRad; + } + else + { + btAssert(m_particleRad == sphRad); + } + } + else + { + btAssert(0); + } + } + printf("Total number of particles : %d\n", m_numParticles); +} + +void btParticlesDynamicsWorld::allocateBuffers() +{ + cl_int ciErrNum; + // positions of spheres + m_hPos.resize(m_numParticles); + m_hVel.resize(m_numParticles); + m_hSortedPos.resize(m_numParticles); + m_hSortedVel.resize(m_numParticles); + m_hPosHash.resize(m_hashSize); + for(int i = 0; i < m_hashSize; i++) { m_hPosHash[i].x = 0x7FFFFFFF; m_hPosHash[i].y = 0; } + unsigned int memSize = sizeof(btVector3) * m_numParticles; + m_dPos = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + m_dVel = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + m_dSortedPos = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + m_dSortedVel = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + memSize = m_hashSize * sizeof(btInt2); + m_dPosHash = clCreateBuffer(m_cxMainContext, CL_MEM_READ_ONLY, memSize, NULL, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + // global simulation parameters + memSize = sizeof(btSimParams); + m_dSimParams = clCreateBuffer(m_cxMainContext, CL_MEM_READ_ONLY, memSize, NULL, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); +} + +void btParticlesDynamicsWorld::adjustGrid() +{ + //btVector3 wmin( BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); + //btVector3 wmax(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT); + + btVector3 wmin( BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); + btVector3 wmax(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT); + btVector3 boxDiag(m_particleRad, m_particleRad, m_particleRad); + for(int i = 0; i < m_numParticles; i++) + { + btVector3 pos = m_hPos[i]; + btVector3 boxMin = pos - boxDiag; + btVector3 boxMax = pos + boxDiag; + wmin.setMin(boxMin); + wmax.setMax(boxMax); + } + m_worldMin = wmin; + m_worldMax = wmax; + btVector3 wsize = m_worldMax - m_worldMin; + wsize[3] = 1.0f; + + glBindBufferARB(GL_ARRAY_BUFFER, m_colVbo); + btVector3* color = (btVector3*)glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + for(int i = 0; i < m_numParticles; i++, color++) + { + *color = (m_hPos[i] - m_worldMin) / wsize; + (*color)[3] = 1.f; + } + glUnmapBufferARB(GL_ARRAY_BUFFER); + +/* + wsize[0] *= 0.5f; + wsize[1] *= 0.1f; + wsize[2] *= 0.5f; + m_worldMin -= wsize; + m_worldMax += wsize; +*/ + m_worldMin.setValue(-WORLD_SIZE, -WORLD_SIZE, -WORLD_SIZE); + m_worldMax.setValue( WORLD_SIZE, WORLD_SIZE, WORLD_SIZE); + wsize = m_worldMax - m_worldMin; + + m_cellSize[0] = m_cellSize[1] = m_cellSize[2] = m_particleRad * btScalar(2.f); + + m_simParams.m_worldMin[0] = m_worldMin[0]; + m_simParams.m_worldMin[1] = m_worldMin[1]; + m_simParams.m_worldMin[2] = m_worldMin[2]; + + m_simParams.m_worldMax[0] = m_worldMax[0]; + m_simParams.m_worldMax[1] = m_worldMax[1]; + m_simParams.m_worldMax[2] = m_worldMax[2]; + + m_simParams.m_cellSize[0] = m_cellSize[0]; + m_simParams.m_cellSize[1] = m_cellSize[1]; + m_simParams.m_cellSize[2] = m_cellSize[2]; + + m_simParams.m_gridSize[0] = (int)(wsize[0] / m_cellSize[0] + 0.999999f); + m_simParams.m_gridSize[1] = (int)(wsize[1] / m_cellSize[1] + 0.999999f); + m_simParams.m_gridSize[2] = (int)(wsize[2] / m_cellSize[2] + 0.999999f); + + m_numGridCells = m_simParams.m_gridSize[0] * m_simParams.m_gridSize[1] * m_simParams.m_gridSize[2]; + m_hCellStart.resize(m_numGridCells); + unsigned int memSize = sizeof(int) * m_numGridCells; + cl_int ciErrNum; + m_dCellStart = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + +} + + +void btParticlesDynamicsWorld::grabSimulationData() +{ +// const btVector3& gravity = getGravity(); + //btVector3 gravity(0., -0.06, 0.); + //btVector3 gravity(0., -0.0003f, 0.); + btVector3 gravity(0,-0.0003,0); + + + + m_simParams.m_gravity[0] = gravity[0]; + m_simParams.m_gravity[1] = gravity[1]; + m_simParams.m_gravity[2] = gravity[2]; + m_simParams.m_particleRad = m_particleRad; + m_simParams.m_globalDamping = 1.0f; + m_simParams.m_boundaryDamping = -0.5f; + +// m_simParams.m_collisionDamping = 0.02f; +// m_simParams.m_spring = 0.5f; +// m_simParams.m_shear = 0.1f; +// m_simParams.m_attraction = 0.0f; + m_simParams.m_collisionDamping = 0.025f;//0.02f; + m_simParams.m_spring = 0.5f; + m_simParams.m_shear = 0.1f; + m_simParams.m_attraction = 0.001f; + + + + // copy data to GPU + cl_int ciErrNum; + unsigned int memSize = sizeof(btVector3) * m_numParticles; + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dVel, CL_TRUE, 0, memSize, &(m_hVel[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + memSize = sizeof(btSimParams); + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dSimParams, CL_TRUE, 0, memSize, &m_simParams, 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + memSize = m_hashSize * sizeof(btInt2); + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); +} + + +void btParticlesDynamicsWorld::createVBO() +{ + // create buffer object + glGenBuffers(1, &m_vbo); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + // positions of spheres + unsigned int memSize = sizeof(btVector3) * m_numParticles; + glBufferData(GL_ARRAY_BUFFER, memSize, 0, GL_DYNAMIC_DRAW); + // colors + GLuint vbo; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, memSize, 0, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + m_colVbo = vbo; + // fill color buffer + glBindBufferARB(GL_ARRAY_BUFFER, m_colVbo); + float *data = (float*)glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + float *ptr = data; + for(int i = 0; i < m_numParticles; i++) + { + float t = i / (float)m_numParticles; + ptr[0] = 0.f; + ptr[1] = 1.f; + ptr[2] = 0.f; + ptr+=3; + *ptr++ = 1.0f; + } + glUnmapBufferARB(GL_ARRAY_BUFFER); + glBindBufferARB(GL_ARRAY_BUFFER, 0); +} + + + +void btParticlesDynamicsWorld::initCLKernels(int argc, char** argv) +{ + cl_int ciErrNum; + + if (!m_cxMainContext) + { + + cl_device_type deviceType = CL_DEVICE_TYPE_ALL; + m_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0, 0); + + int numDev = btOpenCLUtils::getNumDevices(m_cxMainContext); + if (!numDev) + { + btAssert(0); + exit(0);//this is just a demo, exit now + } + + m_cdDevice = btOpenCLUtils::getDevice(m_cxMainContext,0); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + btOpenCLDeviceInfo clInfo; + btOpenCLUtils::getDeviceInfo(m_cdDevice,clInfo); + btOpenCLUtils::printDeviceInfo(m_cdDevice); + + // create a command-queue + m_cqCommandQue = clCreateCommandQueue(m_cxMainContext, m_cdDevice, 0, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + // Program Setup + size_t program_length; + + +#ifdef LOAD_FROM_MEMORY + program_length = strlen(source); + printf("OpenCL compiles ParticlesOCL.cl ... "); +#else + + const char* fileName = "ParticlesOCL.cl"; + FILE * fp = fopen(fileName, "rb"); + char newFileName[512]; + + if (fp == NULL) + { + sprintf(newFileName,"..//%s",fileName); + fp = fopen(newFileName, "rb"); + if (fp) + fileName = newFileName; + } + + if (fp == NULL) + { + sprintf(newFileName,"Demos//ParticlesOpenCL//%s",fileName); + fp = fopen(newFileName, "rb"); + if (fp) + fileName = newFileName; + } + + if (fp == NULL) + { + sprintf(newFileName,"..//..//..//..//..//Demos//ParticlesOpenCL//%s",fileName); + fp = fopen(newFileName, "rb"); + if (fp) + fileName = newFileName; + else + { + printf("cannot find %s\n",newFileName); + exit(0); + } + } + +// char *source = oclLoadProgSource(".//Demos//SpheresGrid//SpheresGrid.cl", "", &program_length); + //char *source = btOclLoadProgSource(".//Demos//SpheresOpenCL//Shared//SpheresGrid.cl", "", &program_length); + + char *source = btOclLoadProgSource(fileName, "", &program_length); + if(source == NULL) + { + printf("ERROR : OpenCL can't load file %s\n", fileName); + } +// oclCHECKERROR (source == NULL, oclFALSE); + btAssert(source != NULL); + + // create the program + printf("OpenCL compiles %s ...", fileName); + +#endif //LOAD_FROM_MEMORY + + + //printf("%s\n", source); + + m_cpProgram = clCreateProgramWithSource(m_cxMainContext, 1, (const char**)&source, &program_length, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); +#ifndef LOAD_FROM_MEMORY + free(source); +#endif //LOAD_FROM_MEMORY + + //#define LOCAL_SIZE_LIMIT 1024U +#define LOCAL_SIZE_MAX 1024U + + // Build the program with 'mad' Optimization option +#ifdef MAC + const char* flags = "-I. -DLOCAL_SIZE_MAX=1024U -cl-mad-enable -DMAC -DGUID_ARG"; +#else + const char* flags = "-I. -DLOCAL_SIZE_MAX=1024U -DGUID_ARG= "; +#endif + // build the program + ciErrNum = clBuildProgram(m_cpProgram, 0, NULL, flags, NULL, NULL); + if(ciErrNum != CL_SUCCESS) + { + // write out standard error +// oclLog(LOGBOTH | ERRORMSG, (double)ciErrNum, STDERROR); + // write out the build log and ptx, then exit + char cBuildLog[10240]; +// char* cPtx; +// size_t szPtxLength; + clGetProgramBuildInfo(m_cpProgram, m_cdDevice, CL_PROGRAM_BUILD_LOG, + sizeof(cBuildLog), cBuildLog, NULL ); +// oclGetProgBinary(m_cpProgram, oclGetFirstDev(m_cxMainContext), &cPtx, &szPtxLength); +// oclLog(LOGBOTH | CLOSELOG, 0.0, "\n\nLog:\n%s\n\n\n\n\nPtx:\n%s\n\n\n", cBuildLog, cPtx); + printf("\n\n%s\n\n\n", cBuildLog); + printf("Press ENTER key to terminate the program\n"); + getchar(); + exit(-1); + } + printf("OK\n"); + + // create the kernels + + postInitDeviceData(); + + initKernel(PARTICLES_KERNEL_COMPUTE_CELL_ID, "kComputeCellId"); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_COMPUTE_CELL_ID].m_kernel, 1, sizeof(cl_mem), (void*) &m_dPos); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_COMPUTE_CELL_ID].m_kernel, 2, sizeof(cl_mem), (void*) &m_dPosHash); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_COMPUTE_CELL_ID].m_kernel, 3, sizeof(cl_mem), (void*) &m_dSimParams); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + initKernel(PARTICLES_KERNEL_INTEGRATE_MOTION, "kIntegrateMotion"); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_INTEGRATE_MOTION].m_kernel, 1, sizeof(cl_mem), (void *) &m_dPos); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_INTEGRATE_MOTION].m_kernel, 2, sizeof(cl_mem), (void *) &m_dVel); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_INTEGRATE_MOTION].m_kernel, 3, sizeof(cl_mem), (void *) &m_dSimParams); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + + initKernel(PARTICLES_KERNEL_CLEAR_CELL_START, "kClearCellStart"); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_CLEAR_CELL_START].m_kernel, 0, sizeof(int), (void *) &m_numGridCells); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_CLEAR_CELL_START].m_kernel, 1, sizeof(cl_mem), (void*) &m_dCellStart); + + initKernel(PARTICLES_KERNEL_FIND_CELL_START, "kFindCellStart"); +// ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_FIND_CELL_START].m_kernel, 0, sizeof(int), (void*) &m_numParticles); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_FIND_CELL_START].m_kernel, 1, sizeof(cl_mem), (void*) &m_dPosHash); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_FIND_CELL_START].m_kernel, 2, sizeof(cl_mem), (void*) &m_dCellStart); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_FIND_CELL_START].m_kernel, 3, sizeof(cl_mem), (void*) &m_dPos); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_FIND_CELL_START].m_kernel, 4, sizeof(cl_mem), (void*) &m_dVel); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_FIND_CELL_START].m_kernel, 5, sizeof(cl_mem), (void*) &m_dSortedPos); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_FIND_CELL_START].m_kernel, 6, sizeof(cl_mem), (void*) &m_dSortedVel); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + initKernel(PARTICLES_KERNEL_COLLIDE_PARTICLES, "kCollideParticles"); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_COLLIDE_PARTICLES].m_kernel, 1, sizeof(cl_mem), (void*) &m_dVel); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_COLLIDE_PARTICLES].m_kernel, 2, sizeof(cl_mem), (void*) &m_dSortedPos); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_COLLIDE_PARTICLES].m_kernel, 3, sizeof(cl_mem), (void*) &m_dSortedVel); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_COLLIDE_PARTICLES].m_kernel, 4, sizeof(cl_mem), (void*) &m_dPosHash); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_COLLIDE_PARTICLES].m_kernel, 5, sizeof(cl_mem), (void*) &m_dCellStart); + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_COLLIDE_PARTICLES].m_kernel, 6, sizeof(cl_mem), (void*) &m_dSimParams); + + initKernel(PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL, "kBitonicSortCellIdLocal"); + initKernel(PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL_1, "kBitonicSortCellIdLocal1"); + initKernel(PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL, "kBitonicSortCellIdMergeGlobal"); + initKernel(PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL, "kBitonicSortCellIdMergeLocal"); +} + +static btInt4 cpu_getGridPos(btVector3& worldPos, btSimParams* pParams) +{ + btInt4 gridPos; + gridPos.x = (int)floor((worldPos[0] - pParams->m_worldMin[0]) / pParams->m_cellSize[0]); + gridPos.y = (int)floor((worldPos[1] - pParams->m_worldMin[1]) / pParams->m_cellSize[1]); + gridPos.z = (int)floor((worldPos[2] - pParams->m_worldMin[2]) / pParams->m_cellSize[2]); + return gridPos; +} + +static unsigned int cpu_getPosHash(btInt4& gridPos, btSimParams* pParams) +{ + btInt4 gridDim = *((btInt4*)(pParams->m_gridSize)); + if(gridPos.x < 0) gridPos.x = 0; + if(gridPos.x >= gridDim.x) gridPos.x = gridDim.x - 1; + if(gridPos.y < 0) gridPos.y = 0; + if(gridPos.y >= gridDim.y) gridPos.y = gridDim.y - 1; + if(gridPos.z < 0) gridPos.z = 0; + if(gridPos.z >= gridDim.z) gridPos.z = gridDim.z - 1; + unsigned int hash = gridPos.z * gridDim.y * gridDim.x + gridPos.y * gridDim.x + gridPos.x; + return hash; +} + + + + +void btParticlesDynamicsWorld::runComputeCellIdKernel() +{ + cl_int ciErrNum; +#if 0 + if(m_useCpuControls[SIMSTAGE_COMPUTE_CELL_ID]->m_active) + { // CPU version + unsigned int memSize = sizeof(btVector3) * m_numParticles; + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + for(int index = 0; index < m_numParticles; index++) + { + btVector3 pos = m_hPos[index]; + btInt4 gridPos = cpu_getGridPos(pos, &m_simParams); + unsigned int hash = cpu_getPosHash(gridPos, &m_simParams); + m_hPosHash[index].x = hash; + m_hPosHash[index].y = index; + } + memSize = sizeof(btInt2) * m_numParticles; + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + else +#endif + { + BT_PROFILE("ComputeCellId"); + runKernelWithWorkgroupSize(PARTICLES_KERNEL_COMPUTE_CELL_ID, m_numParticles); + ciErrNum = clFinish(m_cqCommandQue); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } +/* + // check + int memSize = sizeof(btInt2) * m_hashSize; + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + memSize = sizeof(float) * 4 * m_numParticles; + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); +*/ + + { + BT_PROFILE("Copy VBO"); + // Explicit Copy (until OpenGL interop will work) + // map the PBO to copy data from the CL buffer via host + glBindBufferARB(GL_ARRAY_BUFFER, m_vbo); + // map the buffer object into client's memory + void* ptr = glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY_ARB); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, sizeof(float) * 4 * m_numParticles, ptr, 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + glUnmapBufferARB(GL_ARRAY_BUFFER); + glBindBufferARB(GL_ARRAY_BUFFER,0); + } +} + + + +static btVector3 cpu_collideTwoParticles( + btVector3& posA, + btVector3& posB, + btVector3& velA, + btVector3& velB, + float radiusA, + float radiusB, + float spring, + float damping, + float shear, + float attraction +) +{ + //Calculate relative position + btVector3 relPos = posB - posA; relPos[3] = 0.f; + float dist = sqrt(relPos[0] * relPos[0] + relPos[1] * relPos[1] + relPos[2] * relPos[2]); + float collideDist = radiusA + radiusB; + + btVector3 force = btVector3(0, 0, 0); + if(dist < collideDist) + { + btVector3 norm = relPos / dist; + + //Relative velocity + btVector3 relVel = velB - velA; relVel[3] = 0.f;; + + //Relative tangential velocity + float relVelDotNorm = relVel.dot(norm); + btVector3 tanVel = relVel - relVelDotNorm * norm; + //Spring force (potential) + //float springFactor = -spring * (collideDist - dist); + float springFactor = -0.4 * (collideDist - dist); + force = springFactor * norm + damping * relVel;// + shear * tanVel + attraction * relPos; + } + return force; +} + +struct btPair +{ + union + { + int value; + short v0[2]; + }; +}; + +void btParticlesDynamicsWorld::runCollideParticlesKernel() +{ + btAlignedObjectArray pairs; + +// float particleRad = m_simParams.m_particleRad; +// float collideDist2 = (particleRad + particleRad)*(particleRad + particleRad); + cl_int ciErrNum; + if(m_useCpuControls[SIMSTAGE_COLLIDE_PARTICLES]->m_active) + { // CPU version + int memSize = sizeof(btVector3) * m_numParticles; + { + BT_PROFILE("Copy from GPU"); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dSortedPos, CL_TRUE, 0, memSize, &(m_hSortedPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dSortedVel, CL_TRUE, 0, memSize, &(m_hSortedVel[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + memSize = sizeof(btInt2) * m_numParticles; + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + memSize = m_numGridCells * sizeof(int); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dCellStart, CL_TRUE, 0, memSize, &(m_hCellStart[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + + for(int index = 0; index < m_numParticles; index++) + { + btVector3 posA = m_hSortedPos[index]; + btVector3 velA = m_hSortedVel[index]; + btVector3 force = btVector3(0, 0, 0); + float particleRad = m_simParams.m_particleRad; + float collisionDamping = m_simParams.m_collisionDamping; + float spring = m_simParams.m_spring; + float shear = m_simParams.m_shear; + float attraction = m_simParams.m_attraction; + int unsortedIndex = m_hPosHash[index].y; + //Get address in grid + btInt4 gridPosA = cpu_getGridPos(posA, &m_simParams); + //Accumulate surrounding cells + btInt4 gridPosB; + for(int z = -1; z <= 1; z++) + { + gridPosB.z = gridPosA.z + z; + for(int y = -1; y <= 1; y++) + { + gridPosB.y = gridPosA.y + y; + for(int x = -1; x <= 1; x++) + { + gridPosB.x = gridPosA.x + x; + //Get start particle index for this cell + unsigned int hashB = cpu_getPosHash(gridPosB, &m_simParams); + int startI = m_hCellStart[hashB]; + //Skip empty cell + if(startI < 0) + { + continue; + } + //Iterate over particles in this cell + int endI = startI + 32; + if(endI > m_numParticles) + endI = m_numParticles; + + for(int j = startI; j < endI; j++) + { + unsigned int hashC = m_hPosHash[j].x; + if(hashC != hashB) + { + break; + } + if(j == index) + { + continue; + } + + btPair pair; + pair.v0[0] = index; + pair.v0[1] = j; + pairs.push_back(pair.value); + +// printf("index=%d, j=%d\n",index,j); +// printf("(index=%d, j=%d) ",index,j); + btVector3 posB = m_hSortedPos[j]; + btVector3 velB = m_hSortedVel[j]; + //Collide two spheres + force += cpu_collideTwoParticles( posA, posB, velA, velB, particleRad, particleRad, + spring, collisionDamping, shear, attraction); + } + } + } + } + //Write new velocity back to original unsorted location + m_hVel[unsortedIndex] = velA + force; + } + +//#define BRUTE_FORCE_CHECK 1 +#ifdef BRUTE_FORCE_CHECK + for(int index = 0; index < m_numParticles; index++) + { + btVector3 posA = m_hSortedPos[index]; + btVector3 velA = m_hSortedVel[index]; + btVector3 force = btVector3(0, 0, 0); + int unsortedIndex = m_hPosHash[index].y; + + float collisionDamping = m_simParams.m_collisionDamping; + float spring = m_simParams.m_spring; + float shear = m_simParams.m_shear; + float attraction = m_simParams.m_attraction; + for(int j = 0 ; j < m_numParticles; j++) + { + if (index!=j) + { + btVector3 posB = m_hSortedPos[j]; + btVector3 velB = m_hSortedVel[j]; + + + btVector3 relPos = posB - posA; relPos[3] = 0.f; + float dist2 = (relPos[0] * relPos[0] + relPos[1] * relPos[1] + relPos[2] * relPos[2]); + + + + if(dist2 < collideDist2) + { + //Collide two spheres + // force += cpu_collideTwoParticles( posA, posB, velA, velB, particleRad, particleRad, + // spring, collisionDamping, shear, attraction); + + btPair pair; + pair.v0[0] = index; + pair.v0[1] = j; + if (pairs.findLinearSearch(pair.value)==pairs.size()) + { + printf("not found index=%d, j=%d\n",index,j); + } + + + } + } + } + //Write new velocity back to original unsorted location + //m_hVel[unsortedIndex] = velA + force; + } +#endif //BRUTE_FORCE_CHECK + + memSize = sizeof(btVector3) * m_numParticles; + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dVel, CL_TRUE, 0, memSize, &(m_hVel[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + else + { + runKernelWithWorkgroupSize(PARTICLES_KERNEL_COLLIDE_PARTICLES, m_numParticles); + cl_int ciErrNum = clFinish(m_cqCommandQue); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } +} + + +void btParticlesDynamicsWorld::runIntegrateMotionKernel() +{ + cl_int ciErrNum; + if(m_useCpuControls[SIMSTAGE_INTEGRATE_MOTION]->m_active) + { + // CPU version +#if 1 + // read from GPU + unsigned int memSize = sizeof(btVector3) * m_numParticles; + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dVel, CL_TRUE, 0, memSize, &(m_hVel[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + for(int index = 0; index < m_numParticles; index++) + { + btVector3 pos = m_hPos[index]; + btVector3 vel = m_hVel[index]; + pos[3] = 1.0f; + vel[3] = 0.0f; + // apply gravity + btVector3 gravity; + gravity[0] = m_simParams.m_gravity[0]; + gravity[1] = m_simParams.m_gravity[1]; + gravity[2] = m_simParams.m_gravity[2]; + + float particleRad = m_simParams.m_particleRad; + float globalDamping = m_simParams.m_globalDamping; + float boundaryDamping = m_simParams.m_boundaryDamping; + vel += gravity * m_timeStep; + vel *= globalDamping; + // integrate position + pos += vel * m_timeStep; + // collide with world boundaries + btVector3 worldMin; + worldMin[0] = m_simParams.m_worldMin[0]; + worldMin[1] = m_simParams.m_worldMin[1]; + worldMin[2] = m_simParams.m_worldMin[2]; + + btVector3 worldMax; + worldMax[0] = m_simParams.m_worldMax[0]; + worldMax[1] = m_simParams.m_worldMax[1]; + worldMax[2] = m_simParams.m_worldMax[2]; + + for(int j = 0; j < 3; j++) + { + if(pos[j] < (worldMin[j] + particleRad)) + { + pos[j] = worldMin[j] + particleRad; + vel[j] *= boundaryDamping; + } + if(pos[j] > (worldMax[j] - particleRad)) + { + pos[j] = worldMax[j] - particleRad; + vel[j] *= boundaryDamping; + } + } + // write back position and velocity + m_hPos[index] = pos; + m_hVel[index] = vel; + } +#endif + // write back to GPU + memSize = sizeof(btVector3) * m_numParticles; + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dVel, CL_TRUE, 0, memSize, &(m_hVel[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + else + { + // Set work size and execute the kernel + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_INTEGRATE_MOTION].m_kernel, 4, sizeof(float), &m_timeStep); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + runKernelWithWorkgroupSize(PARTICLES_KERNEL_INTEGRATE_MOTION, m_numParticles); + ciErrNum = clFinish(m_cqCommandQue); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } +} + +void btParticlesDynamicsWorld::runSortHashKernel() +{ + cl_int ciErrNum; + int memSize = m_numParticles * sizeof(btInt2); + if(m_useCpuControls[SIMSTAGE_SORT_CELL_ID]->m_active) + { + // CPU version + // get hash from GPU + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + // sort + class btHashPosKey + { + public: + unsigned int hash; + unsigned int index; + void quickSort(btHashPosKey* pData, int lo, int hi) + { + int i=lo, j=hi; + btHashPosKey x = pData[(lo+hi)/2]; + do + { + while(pData[i].hash < x.hash) i++; + while(x.hash < pData[j].hash) j--; + if(i <= j) + { + btHashPosKey t = pData[i]; + pData[i] = pData[j]; + pData[j] = t; + i++; j--; + } + } while(i <= j); + if(lo < j) pData->quickSort(pData, lo, j); + if(i < hi) pData->quickSort(pData, i, hi); + } + void bitonicSort(btHashPosKey* pData, int lo, int n, bool dir) + { + if(n > 1) + { + int m = n / 2; + bitonicSort(pData, lo, m, !dir); + bitonicSort(pData, lo + m, n - m, dir); + bitonicMerge(pData, lo, n, dir); + } + } + void bitonicMerge(btHashPosKey* pData, int lo, int n, bool dir) + { + if(n > 1) + { + int m = greatestPowerOfTwoLessThan(n); + for(int i = lo; i < (lo + n - m); i++) + { + compare(pData, i, i + m, dir); + } + bitonicMerge(pData, lo, m, dir); + bitonicMerge(pData, lo + m, n - m, dir); + } + } + void compare(btHashPosKey* pData, int i, int j, bool dir) + { + if(dir == (pData[i].hash > pData[j].hash)) + { + btHashPosKey t = pData[i]; + pData[i] = pData[j]; + pData[j] = t; + } + } + int greatestPowerOfTwoLessThan(int n) + { + int k = 1; + while(k < n) + { + k = k << 1; + } + return k>>1; + } + }; + btHashPosKey* pHash = (btHashPosKey*)(&m_hPosHash[0]); + pHash->quickSort(pHash, 0, m_numParticles-1 ); + // pHash->bitonicSort(pHash, 0, m_hashSize, true); + // write back to GPU + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + else + { + // bitonic sort on GPU (shared memory) + int dir = 1; + bitonicSortNv(m_dPosHash, 1, m_hashSize, dir); + ciErrNum = clFinish(m_cqCommandQue); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } +#if 0 + // check order + memSize = m_numParticles * sizeof(btInt2); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + for(int i = 1; i < m_hashSize; i++) + { + if(m_hPosHash[i-1].x > m_hPosHash[i].x) + { + printf("Hash sort error at %d\n", i); + } + } +#endif +} + + +void btParticlesDynamicsWorld::runFindCellStartKernel() +{ + cl_int ciErrNum; + if(m_useCpuControls[SIMSTAGE_FIND_CELL_START]->m_active) + { + // CPU version + // get hash from GPU + int memSize = m_numParticles * sizeof(btInt2); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPosHash, CL_TRUE, 0, memSize, &(m_hPosHash[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + memSize = sizeof(btVector3) * m_numParticles; + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dPos, CL_TRUE, 0, memSize, &(m_hPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clEnqueueReadBuffer(m_cqCommandQue, m_dVel, CL_TRUE, 0, memSize, &(m_hVel[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + // clear cells + for(int i = 0; i < m_numGridCells; i++) + { + m_hCellStart[i] = -1; + } + // find start of each cell in sorted hash + btInt2 hash = m_hPosHash[0]; + m_hCellStart[hash.x] = 0; + int unsortedIndex = hash.y; + btVector3 pos = m_hPos[unsortedIndex]; + btVector3 vel = m_hVel[unsortedIndex]; + m_hSortedPos[0] = pos; + m_hSortedVel[0] = vel; + for(int i = 1; i < m_numParticles; i++) + { + if(m_hPosHash[i-1].x != m_hPosHash[i].x) + { + m_hCellStart[m_hPosHash[i].x] = i; + } + unsortedIndex = m_hPosHash[i].y; + pos = m_hPos[unsortedIndex]; + vel = m_hVel[unsortedIndex]; + m_hSortedPos[i] = pos; + m_hSortedVel[i] = vel; + } + // write back to GPU + memSize = m_numGridCells * sizeof(int); + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dCellStart, CL_TRUE, 0, memSize, &(m_hCellStart[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + memSize = sizeof(btVector3) * m_numParticles; + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dSortedPos, CL_TRUE, 0, memSize, &(m_hSortedPos[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clEnqueueWriteBuffer(m_cqCommandQue, m_dSortedVel, CL_TRUE, 0, memSize, &(m_hSortedVel[0]), 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + else + { // GPU + runKernelWithWorkgroupSize(PARTICLES_KERNEL_CLEAR_CELL_START, m_numGridCells); + runKernelWithWorkgroupSize(PARTICLES_KERNEL_FIND_CELL_START, m_numParticles); + ciErrNum = clFinish(m_cqCommandQue); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } +} + + +void btParticlesDynamicsWorld::initKernel(int kernelId, const char* pName) +{ + + cl_int ciErrNum; + cl_kernel kernel = clCreateKernel(m_cpProgram, pName, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + size_t wgSize; + ciErrNum = clGetKernelWorkGroupInfo(kernel, m_cdDevice, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &wgSize, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + + + +// if (wgSize > 256) +// wgSize = 256; + + if (wgSize > 512) + wgSize = 512; + +// if (wgSize > 1024) +// wgSize = 1024; + + m_kernels[kernelId].m_Id = kernelId; + m_kernels[kernelId].m_kernel = kernel; + m_kernels[kernelId].m_name = pName; + m_kernels[kernelId].m_workgroupSize = wgSize; + + return; +} + +void btParticlesDynamicsWorld::runKernelWithWorkgroupSize(int kernelId, int globalSize) +{ + if(globalSize <= 0) + { + return; + } + cl_kernel kernelFunc = m_kernels[kernelId].m_kernel; + cl_int ciErrNum = clSetKernelArg(kernelFunc, 0, sizeof(int), (void*)&globalSize); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + int workgroupSize = m_kernels[kernelId].m_workgroupSize; + if(workgroupSize <= 0) + { // let OpenCL library calculate workgroup size + size_t globalWorkSize[2]; + globalWorkSize[0] = globalSize; + globalWorkSize[1] = 1; + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, kernelFunc, 1, NULL, globalWorkSize, NULL, 0,0,0 ); + } + else + { + size_t localWorkSize[2], globalWorkSize[2]; + workgroupSize = btMin(workgroupSize, globalSize); + int num_t = globalSize / workgroupSize; + int num_g = num_t * workgroupSize; + if(num_g < globalSize) + { + num_t++; + } + localWorkSize[0] = workgroupSize; + globalWorkSize[0] = num_t * workgroupSize; + localWorkSize[1] = 1; + globalWorkSize[1] = 1; + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, kernelFunc, 1, NULL, globalWorkSize, localWorkSize, 0,0,0 ); + } + oclCHECKERROR(ciErrNum, CL_SUCCESS); +} + + +//Note: logically shared with BitonicSort OpenCL code! +// TODO : get parameter from OpenCL and pass it to kernel (needed for platforms other than NVIDIA) +//static const unsigned int LOCAL_SIZE_LIMIT = 1024U; + +void btParticlesDynamicsWorld::bitonicSortNv(cl_mem pKey, unsigned int batch, unsigned int arrayLength, unsigned int dir) +{ + unsigned int localSizeLimit = m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL].m_workgroupSize * 2; + if(arrayLength < 2) + return; + //Only power-of-two array lengths are supported so far + dir = (dir != 0); + cl_int ciErrNum; + size_t localWorkSize, globalWorkSize; + if(arrayLength <= localSizeLimit) + { + btAssert( (batch * arrayLength) % localSizeLimit == 0); + //Launch bitonicSortLocal + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL].m_kernel, 0, sizeof(cl_mem), (void *)&pKey); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL].m_kernel, 1, sizeof(cl_uint), (void *)&arrayLength); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL].m_kernel, 2, sizeof(cl_uint), (void *)&dir); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + localWorkSize = localSizeLimit / 2; + globalWorkSize = batch * arrayLength / 2; + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL].m_kernel, 1, NULL, &globalWorkSize, &localWorkSize, 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + else + { + //Launch bitonicSortLocal1 + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL_1].m_kernel, 0, sizeof(cl_mem), (void *)&pKey); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + localWorkSize = localSizeLimit / 2; + globalWorkSize = batch * arrayLength / 2; + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL_1].m_kernel, 1, NULL, &globalWorkSize, &localWorkSize, 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + for(unsigned int size = 2 * localSizeLimit; size <= arrayLength; size <<= 1) + { + for(unsigned stride = size / 2; stride > 0; stride >>= 1) + { + if(stride >= localSizeLimit) + { + //Launch bitonicMergeGlobal + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL].m_kernel, 0, sizeof(cl_mem), (void *)&pKey); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL].m_kernel, 1, sizeof(cl_uint), (void *)&arrayLength); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL].m_kernel, 2, sizeof(cl_uint), (void *)&size); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL].m_kernel, 3, sizeof(cl_uint), (void *)&stride); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL].m_kernel, 4, sizeof(cl_uint), (void *)&dir); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + localWorkSize = localSizeLimit / 4; + globalWorkSize = batch * arrayLength / 2; + + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL].m_kernel, 1, NULL, &globalWorkSize, &localWorkSize, 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + } + else + { + //Launch bitonicMergeLocal + ciErrNum = clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL].m_kernel, 0, sizeof(cl_mem), (void *)&pKey); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL].m_kernel, 1, sizeof(cl_uint), (void *)&arrayLength); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL].m_kernel, 2, sizeof(cl_uint), (void *)&stride); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL].m_kernel, 3, sizeof(cl_uint), (void *)&size); + ciErrNum |= clSetKernelArg(m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL].m_kernel, 4, sizeof(cl_uint), (void *)&dir); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + localWorkSize = localSizeLimit / 2; + globalWorkSize = batch * arrayLength / 2; + + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, m_kernels[PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL].m_kernel, 1, NULL, &globalWorkSize, &localWorkSize, 0, NULL, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + break; + } + } + } + } +} + diff --git a/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h b/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h new file mode 100644 index 0000000..66e99af --- /dev/null +++ b/Demos/ParticlesOpenCL/btParticlesDynamicsWorld.h @@ -0,0 +1,183 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_PARTICLES_DYNAMICS_WORLD_H +#define BT_PARTICLES_DYNAMICS_WORLD_H + + +#ifdef USE_MINICL +#include +#include +#else +#ifdef __APPLE__ + #include +#else + #include + #include +#endif __APPLE__ +#endif + + + + + + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" + +#include "btParticlesSharedDefs.h" +#include "btParticlesSharedTypes.h" + + +#define PARTICLES_MAX_NEIGHBORS (32) +#define DEF_PARTICLE_RADIUS (0.023f) +//#define WORLD_SIZE 1.9f +#define WORLD_SIZE 1.f + +enum +{ + PARTICLES_KERNEL_INTEGRATE_MOTION = 0, + PARTICLES_KERNEL_COMPUTE_CELL_ID, + PARTICLES_KERNEL_CLEAR_CELL_START, + PARTICLES_KERNEL_FIND_CELL_START, + PARTICLES_KERNEL_COLLIDE_PARTICLES, + PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL, + PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_LOCAL_1, + PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_GLOBAL, + PARTICLES_KERNEL_BITONIC_SORT_CELL_ID_MERGE_LOCAL, + PARTICLES_KERNEL_TOTAL +}; + + +enum +{ + SIMSTAGE_NONE = 0, + SIMSTAGE_INTEGRATE_MOTION, + SIMSTAGE_COMPUTE_CELL_ID, + SIMSTAGE_SORT_CELL_ID, + SIMSTAGE_FIND_CELL_START, + SIMSTAGE_COLLIDE_PARTICLES, + SIMSTAGE_TOTAL +}; + +struct btKernelInfo +{ + int m_Id; + cl_kernel m_kernel; + const char* m_name; + int m_workgroupSize; +}; + +class btParticlesDynamicsWorld : public btDiscreteDynamicsWorld +{ +public: + int m_numParticles; + int m_usedDevice; + btScalar m_particleRad; + struct GL_ToggleControl* m_useCpuControls[SIMSTAGE_TOTAL]; + +protected: + int m_hashSize; // power of 2 >= m_numSpheres; + int m_numGridCells; + int m_maxNeighbors; + int m_numSolverIterations; + // CPU side data +public: + btAlignedObjectArray m_hPos; + btAlignedObjectArray m_hVel; + btAlignedObjectArray m_hSortedPos; + btAlignedObjectArray m_hSortedVel; +protected: + btAlignedObjectArray m_hPosHash; + btAlignedObjectArray m_hCellStart; + // GPU side data + cl_mem m_dPos; + cl_mem m_dVel; + cl_mem m_dPosHash; + cl_mem m_dCellStart; + cl_mem m_dSimParams; // copy of m_simParams : global simulation paramerers such as gravity, etc. + cl_mem m_dSortedPos; + cl_mem m_dSortedVel; + // OpenCL +public: + cl_context m_cxMainContext; + cl_device_id m_cdDevice; + cl_command_queue m_cqCommandQue; + cl_program m_cpProgram; +protected: + btKernelInfo m_kernels[PARTICLES_KERNEL_TOTAL]; + + btVector3 m_cellSize; + +public: + btVector3 m_worldMin; + btVector3 m_worldMax; + // vbo variables + GLuint m_vbo; + unsigned int m_posVbo; + unsigned int m_colVbo; + btSimParams m_simParams; + float m_timeStep; + + int getNumParticles() { return m_numParticles; } + float* getPosBuffer() { return (float*)&(m_hPos[0]); } + + + btParticlesDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration, + int maxObjs , int maxNeighbors = PARTICLES_MAX_NEIGHBORS) + : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration) + { + m_cxMainContext = 0; + m_usedDevice = 1; +// m_particleRad = btScalar(0.5f); + m_particleRad = DEF_PARTICLE_RADIUS; + m_simParams.m_gravity[0] = 0.f; + m_simParams.m_gravity[1] = -10.f; + m_simParams.m_gravity[2] = 0.f; + m_simParams.m_gravity[3] = 0.f; + m_numSolverIterations = 4; + } + virtual ~btParticlesDynamicsWorld(); + virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); + + void initDeviceData(); + void initCLKernels(int argc, char** argv); + void createVBO(); + void postInitDeviceData(); + void getShapeData(); + void allocateBuffers(); + void grabSimulationData(); + void adjustGrid(); + void runIntegrateMotionKernel(); + void runComputeCellIdKernel(); + void runSortHashKernel(); + void runFindCellStartKernel(); + void runCollideParticlesKernel(); + + void initKernel(int kernelId, const char* pName); + void runKernelWithWorkgroupSize(int kernelId, int globalSize); + void bitonicSortNv(cl_mem pKey, unsigned int batch, unsigned int arrayLength, unsigned int dir); + + void scanExclusiveLocal1(cl_mem d_Dst, cl_mem d_Src, unsigned int n, unsigned int size); + void scanExclusiveLocal2(cl_mem d_Buffer, cl_mem d_Dst, cl_mem d_Src, unsigned int n, unsigned int size); + void uniformUpdate(cl_mem d_Dst, cl_mem d_Buffer, unsigned int n); + void scanExclusive(cl_mem d_Dst, cl_mem d_Src, unsigned int arrayLength); + +}; + + +#endif //BT_PARTICLES_DYNAMICS_WORLD_H diff --git a/Demos/ParticlesOpenCL/btParticlesSharedDefs.h b/Demos/ParticlesOpenCL/btParticlesSharedDefs.h new file mode 100644 index 0000000..247075b --- /dev/null +++ b/Demos/ParticlesOpenCL/btParticlesSharedDefs.h @@ -0,0 +1,14 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ diff --git a/Demos/ParticlesOpenCL/btParticlesSharedTypes.h b/Demos/ParticlesOpenCL/btParticlesSharedTypes.h new file mode 100644 index 0000000..8ee8690 --- /dev/null +++ b/Demos/ParticlesOpenCL/btParticlesSharedTypes.h @@ -0,0 +1,54 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_SPHERES_GRID_DEMO_SHARED_TYPES +#define BT_SPHERES_GRID_DEMO_SHARED_TYPES + +struct btSimParams +{ + float m_gravity[4]; + float m_worldMin[4]; + float m_worldMax[4]; + float m_cellSize[4]; + int m_gridSize[4]; + + float m_particleRad; + float m_globalDamping; + float m_boundaryDamping; + float m_collisionDamping; + + float m_spring; + float m_shear; + float m_attraction; + float m_dummy; +}; + +struct btInt2 +{ + int x; + int y; +}; + +struct btInt4 +{ + int x; + int y; + int z; + int w; +}; + + + +#endif + diff --git a/Demos/ParticlesOpenCL/main.cpp b/Demos/ParticlesOpenCL/main.cpp new file mode 100644 index 0000000..037bba7 --- /dev/null +++ b/Demos/ParticlesOpenCL/main.cpp @@ -0,0 +1,51 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "ParticlesDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + + +// standard utility and system includes +//#include +// Extra CL/GL include +//#include + + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + // start logs +// oclSetLogFileName ("appSpheresGrid.txt"); +// oclLog(LOGBOTH, 0.0, "appSpheresGrid.exe Starting...\n\n"); + + + ParticlesDemo ccdDemo(argc, argv); + ccdDemo.initPhysics(); + ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} \ No newline at end of file diff --git a/Demos/ParticlesOpenCL/shaders.cpp b/Demos/ParticlesOpenCL/shaders.cpp new file mode 100644 index 0000000..79b01f5 --- /dev/null +++ b/Demos/ParticlesOpenCL/shaders.cpp @@ -0,0 +1,56 @@ +#define STRINGIFY(A) #A +//use most up-to-date AMD Radeon drivers to make point sprites work +//see also http://forums.amd.com/devforum/messageview.cfm?catid=392&threadid=129431 +// vertex shader +const char *vertexShader = STRINGIFY( +uniform float pointRadius; // point size in world space +uniform float pointScale; // scale to calculate size in pixels +uniform float densityScale; +uniform float densityOffset; +varying vec3 posEye; +void main() +{ + // calculate window-space point size + posEye = vec3(gl_ModelViewMatrix * vec4(gl_Vertex.xyz, 1.0)); + float dist = length(posEye); + gl_PointSize = pointRadius * (pointScale / dist); + + gl_TexCoord[0] = gl_MultiTexCoord0; + + gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); + + gl_FrontColor = gl_Color; +} +); + + + +// pixel shader for rendering points as shaded spheres +const char *spherePixelShader = STRINGIFY( +uniform float pointRadius; // point size in world space +varying vec3 posEye; // position of center in eye space +void main() +{ + const vec3 lightDir = vec3(0.577, 0.577, 0.577); + const float shininess = 40.0; + + // calculate normal from texture coordinates + vec3 N; + N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); + float mag = dot(N.xy, N.xy); + if (mag > 1.0) discard; // kill pixels outside circle + N.z = sqrt(1.0-mag); + + // point on surface of sphere in eye space + vec3 spherePosEye = posEye + N*pointRadius; + + // calculate lighting + float diffuse = max(0.0, dot(lightDir, N)); +// gl_FragColor = gl_Color * diffuse; + + vec3 v = normalize(-spherePosEye); + vec3 h = normalize(lightDir + v); + float specular = pow(max(0.0, dot(N, h)), shininess); + gl_FragColor = gl_Color * diffuse + specular; +} +); diff --git a/Demos/ParticlesOpenCL/shaders.h b/Demos/ParticlesOpenCL/shaders.h new file mode 100644 index 0000000..d90b40c --- /dev/null +++ b/Demos/ParticlesOpenCL/shaders.h @@ -0,0 +1,2 @@ +extern const char *vertexShader; +extern const char *spherePixelShader; diff --git a/Demos/RagdollDemo/CMakeLists.txt b/Demos/RagdollDemo/CMakeLists.txt new file mode 100644 index 0000000..c6caa49 --- /dev/null +++ b/Demos/RagdollDemo/CMakeLists.txt @@ -0,0 +1,49 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppRagdollDemo + RagdollDemo.cpp + main.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRagdollDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRagdollDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppRagdollDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppRagdollDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppRagdollDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/RagdollDemo/RagdollDemo.cpp b/Demos/RagdollDemo/RagdollDemo.cpp new file mode 100644 index 0000000..0ec12df --- /dev/null +++ b/Demos/RagdollDemo/RagdollDemo.cpp @@ -0,0 +1,507 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Ragdoll Demo +Copyright (c) 2007 Starbreeze Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Marten Svanfeldt +*/ + +#define CONSTRAINT_DEBUG_SIZE 0.2f + + +#include "btBulletDynamicsCommon.h" +#include "GlutStuff.h" +#include "GL_ShapeDrawer.h" + +#include "LinearMath/btIDebugDraw.h" + +#include "GLDebugDrawer.h" +#include "RagdollDemo.h" + + +// Enrico: Shouldn't these three variables be real constants and not defines? + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 +#endif + +#ifndef M_PI_4 +#define M_PI_4 0.785398163397448309616 +#endif + +class RagDoll +{ + enum + { + BODYPART_PELVIS = 0, + BODYPART_SPINE, + BODYPART_HEAD, + + BODYPART_LEFT_UPPER_LEG, + BODYPART_LEFT_LOWER_LEG, + + BODYPART_RIGHT_UPPER_LEG, + BODYPART_RIGHT_LOWER_LEG, + + BODYPART_LEFT_UPPER_ARM, + BODYPART_LEFT_LOWER_ARM, + + BODYPART_RIGHT_UPPER_ARM, + BODYPART_RIGHT_LOWER_ARM, + + BODYPART_COUNT + }; + + enum + { + JOINT_PELVIS_SPINE = 0, + JOINT_SPINE_HEAD, + + JOINT_LEFT_HIP, + JOINT_LEFT_KNEE, + + JOINT_RIGHT_HIP, + JOINT_RIGHT_KNEE, + + JOINT_LEFT_SHOULDER, + JOINT_LEFT_ELBOW, + + JOINT_RIGHT_SHOULDER, + JOINT_RIGHT_ELBOW, + + JOINT_COUNT + }; + + btDynamicsWorld* m_ownerWorld; + btCollisionShape* m_shapes[BODYPART_COUNT]; + btRigidBody* m_bodies[BODYPART_COUNT]; + btTypedConstraint* m_joints[JOINT_COUNT]; + + btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape) + { + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + shape->calculateLocalInertia(mass,localInertia); + + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + m_ownerWorld->addRigidBody(body); + + return body; + } + +public: + RagDoll (btDynamicsWorld* ownerWorld, const btVector3& positionOffset) + : m_ownerWorld (ownerWorld) + { + // Setup the geometry + m_shapes[BODYPART_PELVIS] = new btCapsuleShape(btScalar(0.15), btScalar(0.20)); + m_shapes[BODYPART_SPINE] = new btCapsuleShape(btScalar(0.15), btScalar(0.28)); + m_shapes[BODYPART_HEAD] = new btCapsuleShape(btScalar(0.10), btScalar(0.05)); + m_shapes[BODYPART_LEFT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07), btScalar(0.45)); + m_shapes[BODYPART_LEFT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05), btScalar(0.37)); + m_shapes[BODYPART_RIGHT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07), btScalar(0.45)); + m_shapes[BODYPART_RIGHT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05), btScalar(0.37)); + m_shapes[BODYPART_LEFT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05), btScalar(0.33)); + m_shapes[BODYPART_LEFT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04), btScalar(0.25)); + m_shapes[BODYPART_RIGHT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05), btScalar(0.33)); + m_shapes[BODYPART_RIGHT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04), btScalar(0.25)); + + // Setup all the rigid bodies + btTransform offset; offset.setIdentity(); + offset.setOrigin(positionOffset); + + btTransform transform; + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.), btScalar(1.), btScalar(0.))); + m_bodies[BODYPART_PELVIS] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_PELVIS]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.), btScalar(1.2), btScalar(0.))); + m_bodies[BODYPART_SPINE] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_SPINE]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.), btScalar(1.6), btScalar(0.))); + m_bodies[BODYPART_HEAD] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_HEAD]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.18), btScalar(0.65), btScalar(0.))); + m_bodies[BODYPART_LEFT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.18), btScalar(0.2), btScalar(0.))); + m_bodies[BODYPART_LEFT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.18), btScalar(0.65), btScalar(0.))); + m_bodies[BODYPART_RIGHT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.18), btScalar(0.2), btScalar(0.))); + m_bodies[BODYPART_RIGHT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_LEG]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.35), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,M_PI_2); + m_bodies[BODYPART_LEFT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_ARM]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(-0.7), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,M_PI_2); + m_bodies[BODYPART_LEFT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_ARM]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.35), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,-M_PI_2); + m_bodies[BODYPART_RIGHT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_ARM]); + + transform.setIdentity(); + transform.setOrigin(btVector3(btScalar(0.7), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0,0,-M_PI_2); + m_bodies[BODYPART_RIGHT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_ARM]); + + // Setup some damping on the m_bodies + for (int i = 0; i < BODYPART_COUNT; ++i) + { + m_bodies[i]->setDamping(0.05, 0.85); + m_bodies[i]->setDeactivationTime(0.8); + m_bodies[i]->setSleepingThresholds(1.6, 2.5); + } + + // Now setup the constraints + btHingeConstraint* hingeC; + btConeTwistConstraint* coneC; + + btTransform localA, localB; + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB); + hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2)); + m_joints[JOINT_PELVIS_SPINE] = hingeC; + hingeC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,M_PI_2); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.30), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_HEAD], localA, localB); + coneC->setLimit(M_PI_4, M_PI_4, M_PI_2); + m_joints[JOINT_SPINE_HEAD] = coneC; + coneC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_SPINE_HEAD], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,-M_PI_4*5); localA.setOrigin(btVector3(btScalar(-0.18), btScalar(-0.10), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,-M_PI_4*5); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_LEFT_UPPER_LEG], localA, localB); + coneC->setLimit(M_PI_4, M_PI_4, 0); + m_joints[JOINT_LEFT_HIP] = coneC; + coneC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_HIP], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_LEG], *m_bodies[BODYPART_LEFT_LOWER_LEG], localA, localB); + hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); + m_joints[JOINT_LEFT_KNEE] = hingeC; + hingeC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_KNEE], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,M_PI_4); localA.setOrigin(btVector3(btScalar(0.18), btScalar(-0.10), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_4); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_RIGHT_UPPER_LEG], localA, localB); + coneC->setLimit(M_PI_4, M_PI_4, 0); + m_joints[JOINT_RIGHT_HIP] = coneC; + coneC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_HIP], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_LEG], *m_bodies[BODYPART_RIGHT_LOWER_LEG], localA, localB); + hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); + m_joints[JOINT_RIGHT_KNEE] = hingeC; + hingeC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_KNEE], true); + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,M_PI); localA.setOrigin(btVector3(btScalar(-0.2), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_LEFT_UPPER_ARM], localA, localB); + coneC->setLimit(M_PI_2, M_PI_2, 0); + coneC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_joints[JOINT_LEFT_SHOULDER] = coneC; + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_SHOULDER], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_ARM], *m_bodies[BODYPART_LEFT_LOWER_ARM], localA, localB); +// hingeC->setLimit(btScalar(-M_PI_2), btScalar(0)); + hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); + m_joints[JOINT_LEFT_ELBOW] = hingeC; + hingeC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_ELBOW], true); + + + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,0,0); localA.setOrigin(btVector3(btScalar(0.2), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); + coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_RIGHT_UPPER_ARM], localA, localB); + coneC->setLimit(M_PI_2, M_PI_2, 0); + m_joints[JOINT_RIGHT_SHOULDER] = coneC; + coneC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_SHOULDER], true); + + localA.setIdentity(); localB.setIdentity(); + localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); + localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_ARM], *m_bodies[BODYPART_RIGHT_LOWER_ARM], localA, localB); +// hingeC->setLimit(btScalar(-M_PI_2), btScalar(0)); + hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); + m_joints[JOINT_RIGHT_ELBOW] = hingeC; + hingeC->setDbgDrawSize(CONSTRAINT_DEBUG_SIZE); + + m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_ELBOW], true); + } + + virtual ~RagDoll () + { + int i; + + // Remove all constraints + for ( i = 0; i < JOINT_COUNT; ++i) + { + m_ownerWorld->removeConstraint(m_joints[i]); + delete m_joints[i]; m_joints[i] = 0; + } + + // Remove all bodies and shapes + for ( i = 0; i < BODYPART_COUNT; ++i) + { + m_ownerWorld->removeRigidBody(m_bodies[i]); + + delete m_bodies[i]->getMotionState(); + + delete m_bodies[i]; m_bodies[i] = 0; + delete m_shapes[i]; m_shapes[i] = 0; + } + } +}; + + + + +void RagdollDemo::initPhysics() +{ + // Setup the basic world + + setTexturing(true); + setShadows(true); + + setCameraDistance(btScalar(5.)); + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + btVector3 worldAabbMin(-10000,-10000,-10000); + btVector3 worldAabbMax(10000,10000,10000); + m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); + + m_solver = new btSequentialImpulseConstraintSolver; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + //m_dynamicsWorld->getDispatchInfo().m_useConvexConservativeDistanceUtil = true; + //m_dynamicsWorld->getDispatchInfo().m_convexConservativeDistanceThreshold = 0.01f; + + + + // Setup a big ground box + { + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-10,0)); + +#define CREATE_GROUND_COLLISION_OBJECT 1 +#ifdef CREATE_GROUND_COLLISION_OBJECT + btCollisionObject* fixedGround = new btCollisionObject(); + fixedGround->setCollisionShape(groundShape); + fixedGround->setWorldTransform(groundTransform); + m_dynamicsWorld->addCollisionObject(fixedGround); +#else + localCreateRigidBody(btScalar(0.),groundTransform,groundShape); +#endif //CREATE_GROUND_COLLISION_OBJECT + + } + + // Spawn one ragdoll + btVector3 startOffset(1,0.5,0); + spawnRagdoll(startOffset); + startOffset.setValue(-1,0.5,0); + spawnRagdoll(startOffset); + + clientResetScene(); +} + +void RagdollDemo::spawnRagdoll(const btVector3& startOffset) +{ + RagDoll* ragDoll = new RagDoll (m_dynamicsWorld, startOffset); + m_ragdolls.push_back(ragDoll); +} + +void RagdollDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + float minFPS = 1000000.f/60.f; + if (ms > minFPS) + ms = minFPS; + + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + + } + + renderme(); + + glFlush(); + + glutSwapBuffers(); +} + +void RagdollDemo::displayCallback() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + glutSwapBuffers(); +} + +void RagdollDemo::keyboardCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case 'e': + { + btVector3 startOffset(0,2,0); + spawnRagdoll(startOffset); + break; + } + default: + DemoApplication::keyboardCallback(key, x, y); + } + + +} + + + +void RagdollDemo::exitPhysics() +{ + + int i; + + for (i=0;igetNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_ragdolls; + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + +public: + void initPhysics(); + + void exitPhysics(); + + virtual ~RagdollDemo() + { + exitPhysics(); + } + + void spawnRagdoll(const btVector3& startOffset); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + RagdollDemo* demo = new RagdollDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } + +}; + + +#endif diff --git a/Demos/RagdollDemo/main.cpp b/Demos/RagdollDemo/main.cpp new file mode 100644 index 0000000..0cbf63b --- /dev/null +++ b/Demos/RagdollDemo/main.cpp @@ -0,0 +1,31 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "RagdollDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char* argv[]) +{ + RagdollDemo demoApp; + + demoApp.initPhysics(); + demoApp.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.com",&demoApp); +} diff --git a/Demos/RaytestDemo/CMakeLists.txt b/Demos/RaytestDemo/CMakeLists.txt new file mode 100644 index 0000000..17f51eb --- /dev/null +++ b/Demos/RaytestDemo/CMakeLists.txt @@ -0,0 +1,87 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + +IF (WIN32) +ADD_EXECUTABLE(AppRaytestDemo + main.cpp + RaytestDemo.cpp + RaytestDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppRaytestDemo + main.cpp + RaytestDemo.cpp + RaytestDemo.h + ) +ENDIF() + + + + + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRaytestDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRaytestDemo + POST_BUILD +# COMMAND copy /Y ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + ENDIF(WIN32) +ELSE (USE_GLUT) + + + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + + ADD_EXECUTABLE(AppRaytestDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32RaytestDemo.cpp + RaytestDemo.cpp + RaytestDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + + +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppRaytestDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppRaytestDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppRaytestDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/RaytestDemo/Makefile.am b/Demos/RaytestDemo/Makefile.am new file mode 100644 index 0000000..a73e4fb --- /dev/null +++ b/Demos/RaytestDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=BasicDemo + +BasicDemo_SOURCES=BasicDemo.cpp BasicDemo.h main.cpp +BasicDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +BasicDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/RaytestDemo/RaytestDemo.cpp b/Demos/RaytestDemo/RaytestDemo.cpp new file mode 100644 index 0000000..b32a1e3 --- /dev/null +++ b/Demos/RaytestDemo/RaytestDemo.cpp @@ -0,0 +1,326 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "RaytestDemo.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" + +#include //printf debugging +#include "GLDebugDrawer.h" +static GLDebugDrawer sDebugDraw; + + + +void RaytestDemo::castRays() +{ + + static float up = 0.f; + static float dir = 1.f; + //add some simple animation + if (!m_idle) + { + up+=0.01*dir; + + if (btFabs(up)>2) + { + dir*=-1.f; + } + + btTransform tr = m_dynamicsWorld->getCollisionObjectArray()[1]->getWorldTransform(); + static float angle = 0.f; + angle+=0.01f; + tr.setRotation(btQuaternion(btVector3(0,1,0),angle)); + m_dynamicsWorld->getCollisionObjectArray()[1]->setWorldTransform(tr); + } + + + ///step the simulation + if (m_dynamicsWorld) + { + + m_dynamicsWorld->updateAabbs(); + m_dynamicsWorld->computeOverlappingPairs(); + + btVector3 red(1,0,0); + btVector3 blue(0,0,1); + + ///all hits + { + btVector3 from(-30,1+up,0); + btVector3 to(30,1,0); + sDebugDraw.drawLine(from,to,btVector4(0,0,0,1)); + btCollisionWorld::AllHitsRayResultCallback allResults(from,to); + allResults.m_flags |= btTriangleRaycastCallback::kF_KeepUnflippedNormal; + m_dynamicsWorld->rayTest(from,to,allResults); + + for (int i=0;irayTest(from,to,closestResults); + + + if (closestResults.hasHit()) + { + + btVector3 p = from.lerp(to,closestResults.m_closestHitFraction); + sDebugDraw.drawSphere(p,0.1,blue); + sDebugDraw.drawLine(p,p+closestResults.m_hitNormalWorld,blue); + + } + } + } + +} + + +void RaytestDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + castRays(); + + if (m_dynamicsWorld) + { + float ms = getDeltaTimeMicroseconds(); + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + + m_dynamicsWorld->debugDrawWorld(); + } + + + + renderme(); + + glFlush(); + + swapBuffers(); + +} + + + +void RaytestDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + castRays(); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + + + + + +void RaytestDemo::initPhysics() +{ + m_ele = 10; + m_azi = 75; + + setTexturing(true); + setShadows(true); + + setCameraDistance(btScalar(20.)); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld ->setDebugDrawer(&sDebugDraw); + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); +// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setRollingFriction(1); + body->setFriction(1); + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + + { + btVector3 convexPoints[]={ btVector3(-1,-1,-1),btVector3(-1,-1,1),btVector3(-1,1,1),btVector3(-1,1,-1), + btVector3(2,0,0)}; + + btVector3 quad[] = { + btVector3(0,1,-1), + btVector3(0,1,1), + btVector3(0,-1,1), + btVector3(0,-1,-1)}; + + btTriangleMesh* mesh = new btTriangleMesh(); + mesh->addTriangle(quad[0],quad[1],quad[2],true); + mesh->addTriangle(quad[0],quad[2],quad[3],true); + + btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(mesh,true,true); + +#define NUM_SHAPES 6 + btCollisionShape* colShapes[NUM_SHAPES] = { + trimesh, + new btConvexHullShape(&convexPoints[0].getX(),sizeof(convexPoints)/sizeof(btVector3),sizeof(btVector3)), + new btSphereShape(1), + new btCapsuleShape(0.2,1), + new btCylinderShape(btVector3(0.2,1,0.2)), + new btBoxShape(btVector3(1,1,1)) + }; + + for (int i=0;icalculateLocalInertia(mass,localInertia); + + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); + rbInfo.m_startWorldTransform = startTransform; + btRigidBody* body = new btRigidBody(rbInfo); + body->setRollingFriction(0.03); + body->setFriction(1); + body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + + m_dynamicsWorld->addRigidBody(body); + + } + + } +} +void RaytestDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} + + +void RaytestDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + public: + + RaytestDemo() + { + } + virtual ~RaytestDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + void castRays(); + virtual void displayCallback(); + virtual void clientResetScene(); + + static DemoApplication* Create() + { + RaytestDemo* demo = new RaytestDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //BT_RAYTEST_DEMO_H + diff --git a/Demos/RaytestDemo/Win32RaytestDemo.cpp b/Demos/RaytestDemo/Win32RaytestDemo.cpp new file mode 100644 index 0000000..a55fb67 --- /dev/null +++ b/Demos/RaytestDemo/Win32RaytestDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BasicDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new BasicDemo(); +} + +#endif diff --git a/Demos/RaytestDemo/main.cpp b/Demos/RaytestDemo/main.cpp new file mode 100644 index 0000000..b951ad4 --- /dev/null +++ b/Demos/RaytestDemo/main.cpp @@ -0,0 +1,41 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "RaytestDemo.h" +#include "GlutStuff.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + + + + + +int main(int argc,char** argv) +{ + + RaytestDemo ccdDemo; + ccdDemo.initPhysics(); + + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,1024,600,"Bullet Physics Demo. http://bulletphysics.org",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/Raytracer/CMakeLists.txt b/Demos/Raytracer/CMakeLists.txt new file mode 100644 index 0000000..21eef24 --- /dev/null +++ b/Demos/Raytracer/CMakeLists.txt @@ -0,0 +1,49 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppRaytracer + Raytracer.cpp + main.cpp +) + + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRaytracer + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRaytracer + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppRaytracer PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppRaytracer PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppRaytracer PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/Raytracer/Raytracer.cpp b/Demos/Raytracer/Raytracer.cpp new file mode 100644 index 0000000..97810a1 --- /dev/null +++ b/Demos/Raytracer/Raytracer.cpp @@ -0,0 +1,627 @@ +/* +* Copyright (c) 2005 Erwin Coumans +* +* Permission to use, copy, modify, distribute and sell this software +* and its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies. +* Erwin Coumans makes no representations about the suitability +* of this software for any purpose. +* It is provided "as is" without express or implied warranty. +*/ + + + +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" + +/* +Raytracer uses the Convex rayCast to visualize the Collision Shapes/Minkowski Sum. +Very basic raytracer, rendering into a texture. +*/ + +///Low level demo, doesn't include btBulletCollisionCommon.h + +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btTransform.h" +#include "GL_ShapeDrawer.h" +#include "GLDebugDrawer.h" + +#include "Raytracer.h" +#include "GlutStuff.h" + + +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" + +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" + +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "LinearMath/btAabbUtil2.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" + + +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" +#include "BulletCollision/CollisionShapes/btConeShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" + +#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h" +#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h" + +#include "RenderTexture.h" + + + +static btVoronoiSimplexSolver simplexSolver; + +static float yaw=0.f,pitch=0.f,roll=0.f; +static const int maxNumObjects = 4; +static const int numObjects = 3; + + +static btConvexShape* shapePtr[maxNumObjects]; +static btTransform transforms[maxNumObjects]; + +renderTexture* raytracePicture = 0; + +//this applies to the raytracer virtual screen/image buffer +static int screenWidth = 128;//256; +//float aspectRatio = (3.f/4.f); +static int screenHeight = 64;//256;//screenWidth * aspectRatio; +GLuint glTextureId; + +btConeShape myCone(1,1); +btSphereShape mysphere(1); +btBoxShape mybox(btVector3(1,1,1)); + +btCollisionWorld* m_collisionWorld = 0; + + + +/// +/// +/// + +void Raytracer::initPhysics() +{ + m_ele = 0; + + raytracePicture = new renderTexture(screenWidth,screenHeight); + myCone.setMargin(0.2f); + + //choose shape + shapePtr[0] = &myCone; + shapePtr[1] = &mysphere; + shapePtr[2] = &mybox; + + for (int i=0;isetCollisionShape(shapePtr[s]); + obj->setWorldTransform(transforms[s]); + m_collisionWorld->addCollisionObject(obj); + } + + +} + +Raytracer::~Raytracer() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_collisionWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_collisionWorld->getCollisionObjectArray()[i]; + m_collisionWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision world + delete m_collisionWorld; + + //delete broadphase + delete m_overlappingPairCache; + + //delete dispatcher + delete m_dispatcher; + + delete m_collisionConfiguration; + + delete raytracePicture; + raytracePicture=0; +} + +//to be implemented by the demo + +void Raytracer::clientMoveAndDisplay() +{ + displayCallback(); +} + + + + + + +bool Raytracer::worldRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint) +{ + + struct AllRayResultCallback : public btCollisionWorld::RayResultCallback + { + AllRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) + :m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld) + { + } + + btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; + + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) + { + +//caller already does the filter on the m_closestHitFraction + btAssert(rayResult.m_hitFraction <= m_closestHitFraction); + + m_closestHitFraction = rayResult.m_hitFraction; + + m_collisionObject = rayResult.m_collisionObject; + if (normalInWorldSpace) + { + m_hitNormalWorld = rayResult.m_hitNormalLocal; + } else + { + ///need to transform normal into worldspace + m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + } + m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); + return 1.f; + } + }; + + + AllRayResultCallback resultCallback(rayFrom,rayTo); +// btCollisionWorld::ClosestRayResultCallback resultCallback(rayFrom,rayTo); + m_collisionWorld->rayTest(rayFrom,rayTo,resultCallback); + if (resultCallback.hasHit()) + { + worldNormal = resultCallback.m_hitNormalWorld; + return true; + } + return false; +} + + +bool Raytracer::singleObjectRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint) +{ + +// btScalar closestHitResults = 1.f; + + btCollisionWorld::ClosestRayResultCallback resultCallback(rayFrom,rayTo); + + bool hasHit = false; + btConvexCast::CastResult rayResult; + btSphereShape pointShape(0.0f); + btTransform rayFromTrans; + btTransform rayToTrans; + + rayFromTrans.setIdentity(); + rayFromTrans.setOrigin(rayFrom); + rayToTrans.setIdentity(); + rayToTrans.setOrigin(rayTo); + + for (int s=0;sgetAabb(transforms[s],aabbMin,aabbMax); + btScalar hitLambda = 1.f; + btVector3 hitNormal; + btCollisionObject tmpObj; + tmpObj.setWorldTransform(transforms[s]); + + + if (btRayAabb(rayFrom,rayTo,aabbMin,aabbMax,hitLambda,hitNormal)) + { + //reset previous result + + btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans, &tmpObj, shapePtr[s], transforms[s], resultCallback); + if (resultCallback.hasHit()) + { + //float fog = 1.f - 0.1f * rayResult.m_fraction; + resultCallback.m_hitNormalWorld.normalize();//.m_normal.normalize(); + worldNormal = resultCallback.m_hitNormalWorld; + //worldNormal = transforms[s].getBasis() *rayResult.m_normal; + worldNormal.normalize(); + hasHit = true; + } + } + } + + return hasHit; +} + + +bool Raytracer::lowlevelRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint) +{ + + btScalar closestHitResults = 1.f; + + bool hasHit = false; + btConvexCast::CastResult rayResult; + btSphereShape pointShape(0.0f); + btTransform rayFromTrans; + btTransform rayToTrans; + + rayFromTrans.setIdentity(); + rayFromTrans.setOrigin(rayFrom); + rayToTrans.setIdentity(); + rayToTrans.setOrigin(rayTo); + + for (int s=0;sgetAabb(transforms[s],aabbMin,aabbMax); + btScalar hitLambda = 1.f; + btVector3 hitNormal; + btCollisionObject tmpObj; + tmpObj.setWorldTransform(transforms[s]); + + + if (btRayAabb(rayFrom,rayTo,aabbMin,aabbMax,hitLambda,hitNormal)) + { + //reset previous result + + //choose the continuous collision detection method + btSubsimplexConvexCast convexCaster(&pointShape,shapePtr[s],&simplexSolver); + //btGjkConvexCast convexCaster(&pointShape,shapePtr[s],&simplexSolver); + //btContinuousConvexCollision convexCaster(&pointShape,shapePtr[s],&simplexSolver,0); + + if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,transforms[s],transforms[s],rayResult)) + { + if (rayResult.m_fraction < closestHitResults) + { + closestHitResults = rayResult.m_fraction; + + worldNormal = transforms[s].getBasis() *rayResult.m_normal; + worldNormal.normalize(); + hasHit = true; + } + } + } + } + + return hasHit; + +} + + +void Raytracer::displayCallback() +{ + + updateCamera(); + + for (int i=0;isetPixel(x,y,rgba); + } + } + +#if 1 + btVector3 rayTo; + btTransform colObjWorldTransform; + colObjWorldTransform.setIdentity(); + + int mode = 0; + + for (x=0;xsetPixel(x,y,rgba); + } else + { + // btVector4 rgba = raytracePicture->getPixel(x,y); + } + if (!rgba.length2()) + { + raytracePicture->setPixel(x,y,btVector4(1,1,1,1)); + } + } + } +#endif + +extern unsigned char sFontData[]; + if (0) + { + + const char* text="ABC abc 123 !@#"; + int x=0; + for (int cc = 0;ccsetPixel(x,y,rgba); + raytracePicture->addPixel(x,y,rgba); + } + y++; + } + x++; + } + } + } + + + //raytracePicture->grapicalPrintf("CCD RAYTRACER",sFontData); + char buffer[256]; + sprintf(buffer,"%d rays",screenWidth*screenHeight*numObjects); + //sprintf(buffer,"Toggle",screenWidth*screenHeight*numObjects); + //sprintf(buffer,"TEST",screenWidth*screenHeight*numObjects); + //raytracePicture->grapicalPrintf(buffer,sFontData,0,10);//&BMF_font_helv10,0,10); + raytracePicture->grapicalPrintf(buffer,sFontData,0,0);//&BMF_font_helv10,0,10); + + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glFrustum(-1.0,1.0,-1.0,1.0,3,2020.0); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); // reset The Modelview Matrix + glTranslatef(0.0f,0.0f,-3.1f); // Move Into The Screen 5 Units + + + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,glTextureId ); + + const unsigned char *ptr = raytracePicture->getBuffer(); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + raytracePicture->getWidth(),raytracePicture->getHeight(), + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + ptr); + + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f (1,1,1,1); // alpha=0.5=half visible + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex2f(-1,1); + glTexCoord2f(1.0f, 0.0f); + glVertex2f(1,1); + glTexCoord2f(1.0f, 1.0f); + glVertex2f(1,-1); + glTexCoord2f(0.0f, 1.0f); + glVertex2f(-1,-1); + glEnd(); + + + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + + GL_ShapeDrawer::drawCoordSystem(); + + + + { + for (int i=0;igetAabb(transforms[i],aabbMin,aabbMax); + } + } + + glPushMatrix(); + + + + + glPopMatrix(); + + pitch += 0.005f; + yaw += 0.01f; + m_azi += 1.f; + + glFlush(); + glutSwapBuffers(); +} + diff --git a/Demos/Raytracer/Raytracer.h b/Demos/Raytracer/Raytracer.h new file mode 100644 index 0000000..a8ff33f --- /dev/null +++ b/Demos/Raytracer/Raytracer.h @@ -0,0 +1,65 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef RAYTRACER_H +#define RAYTRACER_H + +#include "GlutDemoApplication.h" + +class btDefaultCollisionConfiguration; +class btCollisionDispatcher; +class btAxisSweep3; +class btCollisionWorld; + +///Raytracer shows the inner working of the ray casting, using ray tracing rendering into a texture. +class Raytracer : public GlutDemoApplication +{ + + btDefaultCollisionConfiguration* m_collisionConfiguration; + btCollisionDispatcher* m_dispatcher; + btAxisSweep3* m_overlappingPairCache; + btCollisionWorld* m_collisionWorld; + bool m_initialized; + + public: + + void initPhysics(); + + virtual ~Raytracer(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + ///worldRaytest performs a ray versus all objects in a collision world, returning true is a hit is found (filling in worldNormal and worldHitPoint) + bool worldRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint); + + ///singleObjectRaytest performs a ray versus one collision shape, returning true is a hit is found (filling in worldNormal and worldHitPoint) + bool singleObjectRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint); + + ///lowlevelRaytest performs a ray versus convex shape, returning true is a hit is found (filling in worldNormal and worldHitPoint) + bool lowlevelRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint); + + static DemoApplication* Create() + { + Raytracer* demo = new Raytracer(); + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +#endif //RAYTRACER_H + + diff --git a/Demos/Raytracer/main.cpp b/Demos/Raytracer/main.cpp new file mode 100644 index 0000000..dd51529 --- /dev/null +++ b/Demos/Raytracer/main.cpp @@ -0,0 +1,16 @@ + +#include "Raytracer.h" +#include "GlutStuff.h" + + +int main(int argc,char** argv) +{ + Raytracer* raytraceDemo = new Raytracer(); + + raytraceDemo->initPhysics(); + + raytraceDemo->setCameraDistance(6.f); + + return glutmain(argc, argv,640,640,"Bullet GJK Implicit Shape Raytracer Demo",raytraceDemo); +} + diff --git a/Demos/RollingFrictionDemo/CMakeLists.txt b/Demos/RollingFrictionDemo/CMakeLists.txt new file mode 100644 index 0000000..99809ca --- /dev/null +++ b/Demos/RollingFrictionDemo/CMakeLists.txt @@ -0,0 +1,87 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + +IF (WIN32) +ADD_EXECUTABLE(AppRollingFrictionDemo + main.cpp + RollingFrictionDemo.cpp + RollingFrictionDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppRollingFrictionDemo + main.cpp + RollingFrictionDemo.cpp + RollingFrictionDemo.h + ) +ENDIF() + + + + + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRollingFrictionDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppRollingFrictionDemo + POST_BUILD +# COMMAND copy /Y ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + ENDIF(WIN32) +ELSE (USE_GLUT) + + + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + + ADD_EXECUTABLE(AppRollingFrictionDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32RollingFrictionDemo.cpp + RollingFrictionDemo.cpp + RollingFrictionDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + + +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppRollingFrictionDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppRollingFrictionDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppRollingFrictionDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/RollingFrictionDemo/Makefile.am b/Demos/RollingFrictionDemo/Makefile.am new file mode 100644 index 0000000..a73e4fb --- /dev/null +++ b/Demos/RollingFrictionDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=BasicDemo + +BasicDemo_SOURCES=BasicDemo.cpp BasicDemo.h main.cpp +BasicDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +BasicDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/RollingFrictionDemo/RollingFrictionDemo.cpp b/Demos/RollingFrictionDemo/RollingFrictionDemo.cpp new file mode 100644 index 0000000..71ef8e3 --- /dev/null +++ b/Demos/RollingFrictionDemo/RollingFrictionDemo.cpp @@ -0,0 +1,291 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "RollingFrictionDemo.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "GLDebugDrawer.h" +static GLDebugDrawer sDebugDraw; +#include //printf debugging + + +void RollingFrictionDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + glFlush(); + + swapBuffers(); + +} + + + +void RollingFrictionDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + + + + + +void RollingFrictionDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + setCameraDistance(btScalar(SCALING*26.)); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld->setDebugDrawer(&sDebugDraw); +// m_dynamicsWorld->getSolverInfo().m_singleAxisRollingFrictionThreshold = 0.f;//faster but lower quality + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + { + + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(20.),btScalar(50.),btScalar(10.))); + + // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setRotation(btQuaternion(btVector3(0,0,1),SIMD_PI*0.03)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(1); + body->setRollingFriction(1); + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + { + + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(100.),btScalar(50.),btScalar(100.))); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-54,0)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(1); + body->setRollingFriction(1); + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance +#define NUM_SHAPES 10 + btCollisionShape* colShapes[NUM_SHAPES] = { + new btSphereShape(btScalar(1.)), + new btCapsuleShape(0.5,1), + new btCapsuleShapeX(0.5,1), + new btCapsuleShapeZ(0.5,1), + new btConeShape(0.5,1), + new btConeShapeX(0.5,1), + new btConeShapeZ(0.5,1), + new btCylinderShape(btVector3(0.5,1,0.5)), + new btCylinderShapeX(btVector3(1,0.5,0.5)), + new btCylinderShapeZ(btVector3(0.5,0.5,1)), + }; + for (int i=0;icalculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(1.f); + body->setRollingFriction(.3); + body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + + + m_dynamicsWorld->addRigidBody(body); + } + } + } + } + } + + +} +void RollingFrictionDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} + + +void RollingFrictionDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + public: + + RollingFrictionDemo() + { + } + virtual ~RollingFrictionDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + virtual void clientResetScene(); + + static DemoApplication* Create() + { + RollingFrictionDemo* demo = new RollingFrictionDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //_ROLLING_FRICTION_DEMO_H + diff --git a/Demos/RollingFrictionDemo/Win32RollingFrictionDemo.cpp b/Demos/RollingFrictionDemo/Win32RollingFrictionDemo.cpp new file mode 100644 index 0000000..2ecf747 --- /dev/null +++ b/Demos/RollingFrictionDemo/Win32RollingFrictionDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "RollingFrictionDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new RollingFrictionDemo(); +} + +#endif diff --git a/Demos/RollingFrictionDemo/main.cpp b/Demos/RollingFrictionDemo/main.cpp new file mode 100644 index 0000000..fe09664 --- /dev/null +++ b/Demos/RollingFrictionDemo/main.cpp @@ -0,0 +1,41 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "RollingFrictionDemo.h" +#include "GlutStuff.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + + + + + +int main(int argc,char** argv) +{ + + RollingFrictionDemo ccdDemo; + ccdDemo.initPhysics(); + + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,1024,600,"Bullet Physics Demo. http://bulletphysics.org",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/SerializeDemo/AMD/CMakeLists.txt b/Demos/SerializeDemo/AMD/CMakeLists.txt new file mode 100644 index 0000000..736c3c4 --- /dev/null +++ b/Demos/SerializeDemo/AMD/CMakeLists.txt @@ -0,0 +1,157 @@ + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL +${AMD_OPENCL_INCLUDES} +) + +ADD_DEFINITIONS(-DDESERIALIZE_SOFT_BODIES) +ADD_DEFINITIONS(-DUSE_AMD_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_AMD) + +IF(WIN32) +ADD_DEFINITIONS(-DGLEW_STATIC) +ENDIF(WIN32) + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport + BulletWorldImporter + BulletSoftBody + BulletDynamics + BulletCollision + BulletFileLoader + LinearMath + BulletSoftBodySolvers_OpenCL_AMD + BulletMultiThreaded + ${GLUT_glut_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAK_GLEW_LIBRARY} + ${CMAKE_ATISTREAMSDK_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppSerializeDemo_AMD + ../main.cpp + ../SerializeDemo.cpp + ../SerializeDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/clew.c + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/clew.h + + ) + ELSE() + ADD_EXECUTABLE(AppSerializeDemo_AMD + ../main.cpp + ../SerializeDemo.cpp + ../SerializeDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + + ) + ENDIF() + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (WIN32) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSerializeDemo_AMD + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSerializeDemo_AMD + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF(WIN32) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + +ELSE (USE_GLUT) + + LINK_LIBRARIES( + OpenGLSupport + BulletWorldImporter + BulletSoftBody + BulletDynamics + BulletCollision + BulletFileLoader + LinearMath + BulletSoftBodySolvers_OpenCL_AMD + BulletMultiThreaded + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${CMAKE_GLEW_LIBRARY} + ${CMAKE_ATISTREAMSDK_LIBRARY} + ) + + ADD_EXECUTABLE(AppSerializeDemo_AMD + WIN32 + ../../OpenGL/Win32AppMain.cpp + ../Win32SerializeDemo.cpp + ../SerializeDemo.cpp + ../SerializeDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h + ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h + ) +ENDIF (USE_GLUT) + +IF(WIN32) +IF (CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppSerializeDemo_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) + ENDIF() +ELSE(CMAKE_CL_64) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( TARGET AppSerializeDemo_AMD POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() +ENDIF(CMAKE_CL_64) +ENDIF(WIN32) + + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES AND NOT INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) + ADD_CUSTOM_COMMAND( + TARGET AppSerializeDemo_AMD + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SerializeDemo/testFileCloth.bullet ${CMAKE_CURRENT_BINARY_DIR}/testFile.bullet + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ApplyForces.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/ApplyForces.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ComputeBounds.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/ComputeBounds.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/Integrate.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/Integrate.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/OutputToVertexArray.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/OutputToVertexArray.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/PrepareLinks.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/PrepareLinks.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocities.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/SolveCollisionsAndUpdateVelocities.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositions.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/SolvePositions.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositionsSIMDBatched.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/SolvePositionsSIMDBatched.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateConstants.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/UpdateConstants.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateFixedVertexPositions.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/UpdateFixedVertexPositions.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNodes.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/UpdateNodes.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNormals.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/UpdateNormals.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositions.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/UpdatePositions.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositionsFromVelocities.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/UpdatePositionsFromVelocities.cl + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/VSolveLinks.cl ${CMAKE_CURRENT_BINARY_DIR}/OpenCLC10/VSolveLinks.cl + + ) +ENDIF () + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppSerializeDemo_AMD PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppSerializeDemo_AMD PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppSerializeDemo_AMD PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/SerializeDemo/AMD/premake4.lua b/Demos/SerializeDemo/AMD/premake4.lua new file mode 100644 index 0000000..360633b --- /dev/null +++ b/Demos/SerializeDemo/AMD/premake4.lua @@ -0,0 +1,65 @@ + + hasCL = findOpenCL_AMD() + + if (hasCL) then + + project "AppOpenCLClothDemo_AMD" + + defines { "USE_AMD_OPENCL","CL_PLATFORM_AMD"} + + initOpenCL_AMD() + + language "C++" + + kind "ConsoleApp" + targetdir "../../.." + + libdirs {"../../../Glut"} + + links { + "LinearMath", + "BulletCollision", + "BulletDynamics", + "BulletSoftBody", + "BulletSoftBodySolvers_OpenCL_AMD", + "opengl32" + } + + configuration "x64" + links { + "glut64", + "glew64s" + } + configuration "x32" + links { + "glut32", + "glew32s" + } + + configuration{} + + + includedirs { + "../../../src", + "../../../Glut", + "../../SharedOpenCL", + "../../OpenGL" + } + + files { + "../cl_cloth_demo.cpp", + "../../SharedOpenCL/btOclUtils.h", + "../../SharedOpenCL/btOclCommon.h", + "../../SharedOpenCL/btOclUtils.cpp", + "../../SharedOpenCL/btOclCommon.cpp", + "../../OpenGL/GLDebugDrawer.cpp", + "../../OpenGL/stb_image.cpp", + "../../OpenGL/stb_image.h", + "../gl_win.cpp", + "../clstuff.cpp", + "../clstuff.h", + "../gl_win.h", + "../cloth.h" + } + + end \ No newline at end of file diff --git a/Demos/SerializeDemo/CMakeLists.txt b/Demos/SerializeDemo/CMakeLists.txt new file mode 100644 index 0000000..ea5a31a --- /dev/null +++ b/Demos/SerializeDemo/CMakeLists.txt @@ -0,0 +1,95 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +IF(BUILD_AMD_OPENCL_DEMOS AND BUILD_MULTITHREADING) + SUBDIRS(AMD) +ENDIF() + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +) + +ADD_DEFINITIONS(-DDESERIALIZE_SOFT_BODIES) + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppSerializeDemo + main.cpp + SerializeDemo.cpp + SerializeDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppSerializeDemo + main.cpp + SerializeDemo.cpp + SerializeDemo.h + ) + ENDIF() + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (WIN32) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSerializeDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSerializeDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF(WIN32) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + +ELSE (USE_GLUT) + + LINK_LIBRARIES( + OpenGLSupport BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletFileLoader LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + ADD_EXECUTABLE(AppSerializeDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32SerializeDemo.cpp + SerializeDemo.cpp + SerializeDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ENDIF (USE_GLUT) + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES AND NOT INTERNAL_UPDATE_SERIALIZATION_STRUCTURES) + ADD_CUSTOM_COMMAND( + TARGET AppSerializeDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SerializeDemo/testFile.bullet ${CMAKE_CURRENT_BINARY_DIR}/testFile.bullet + ) +ENDIF () + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppSerializeDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppSerializeDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppSerializeDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + + diff --git a/Demos/SerializeDemo/SerializeDemo.cpp b/Demos/SerializeDemo/SerializeDemo.cpp new file mode 100644 index 0000000..3862dd2 --- /dev/null +++ b/Demos/SerializeDemo/SerializeDemo.cpp @@ -0,0 +1,940 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#define TEST_SERIALIZATION 1 +//#undef DESERIALIZE_SOFT_BODIES + +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#define CREATE_NEW_BULLETFILE 1 +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "SerializeDemo.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#ifdef TEST_SERIALIZATION +#include "LinearMath/btSerializer.h" +#include "btBulletFile.h" +#include "btBulletWorldImporter.h" +#endif //TEST_SERIALIZATION + +#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" +#include //printf debugging + + + +#ifdef DESERIALIZE_SOFT_BODIES +#include "BulletSoftBody/btSoftBodySolvers.h" + + +#ifdef USE_AMD_OPENCL + #include + #include + #include "../SharedOpenCL/btOpenCLUtils.h" + + extern cl_context g_cxMainContext; + extern cl_device_id g_cdDevice; + extern cl_command_queue g_cqCommandQue; +#endif + +btSoftBodySolver* fSoftBodySolver=0; + +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/btSoftRigidDynamicsWorld.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#endif + +void SerializeDemo::keyboardCallback(unsigned char key, int x, int y) +{ + btAlignedObjectArray bodies; + if (key == 'g') + { + int numManifolds = getDynamicsWorld()->getDispatcher()->getNumManifolds(); + + for (int i=0;igetDispatcher()->getManifoldByIndexInternal(i); + if (!manifold->getNumContacts()) + continue; + + btScalar minDist = 1e30f; + int minIndex = -1; + for (int v=0;vgetNumContacts();v++) + { + if (minDist >manifold->getContactPoint(v).getDistance()) + { + minDist = manifold->getContactPoint(v).getDistance(); + minIndex = v; + } + } + if (minDist>0.) + continue; + + btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); + btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); + // int tag0 = (colObj0)->getIslandTag(); + // int tag1 = (colObj1)->getIslandTag(); + btRigidBody* body0 = btRigidBody::upcast(colObj0); + btRigidBody* body1 = btRigidBody::upcast(colObj1); + if (bodies.findLinearSearch(body0)==bodies.size()) + bodies.push_back(body0); + if (bodies.findLinearSearch(body1)==bodies.size()) + bodies.push_back(body1); + + if (body0 && body1) + { + if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject()) + { + if (body0->checkCollideWithOverride(body1)) + { + { + btTransform trA,trB; + trA.setIdentity(); + trB.setIdentity(); + btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA; + btTransform globalFrame; + globalFrame.setIdentity(); + globalFrame.setOrigin(contactPosWorld); + + trA = body0->getWorldTransform().inverse()*globalFrame; + trB = body1->getWorldTransform().inverse()*globalFrame; + + btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true); + dof6->setOverrideNumSolverIterations(100); + + dof6->setBreakingImpulseThreshold(35); + + for (int i=0;i<6;i++) + dof6->setLimit(i,0,0); + getDynamicsWorld()->addConstraint(dof6,true); + + } + } + } + } + + } + + for (int i=0;iremoveRigidBody(bodies[i]); + getDynamicsWorld()->addRigidBody(bodies[i]); + } + }else + { + PlatformDemoApplication::keyboardCallback(key,x,y); + } +} + + +void SerializeDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + + +#ifdef DESERIALIZE_SOFT_BODIES + if (fSoftBodySolver) + fSoftBodySolver->copyBackToSoftBodies(); +#endif + + m_dynamicsWorld->debugDrawWorld(); + +#ifdef DESERIALIZE_SOFT_BODIES + if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD) + { + //optional but useful: debug drawing + btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld; + + for ( int i=0;igetSoftBodyArray().size();i++) + { + btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i]; + if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) + { + btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags()); + } + } + } +#endif //DESERIALIZE_SOFT_BODIES + + } + + renderme(); + + glFlush(); + + swapBuffers(); + +} +#ifdef USE_AMD_OPENCL + +///the CachingCLFuncs class will try to create/load precompiled binary programs, instead of the slow on-line compilation of programs +class CachingCLFuncs : public CLFunctions +{ + cl_device_id m_device; + + public: + + CachingCLFuncs (cl_command_queue cqCommandQue, cl_context cxMainContext, cl_device_id device) + :CLFunctions(cqCommandQue,cxMainContext), + m_device(device) + { + } + + virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros, const char* srcFileNameForCaching) + { + + cl_int pErrNum; + cl_program prog; + + prog = btOpenCLUtils::compileCLProgramFromFile( m_cxMainContext,m_device, &pErrNum,additionalMacros ,srcFileNameForCaching); + if (!prog) + { + printf("Using embedded kernel source instead:\n"); + prog = btOpenCLUtils::compileCLProgramFromString( m_cxMainContext,m_device, kernelSource, &pErrNum,additionalMacros); + } + + return btOpenCLUtils::compileCLKernelFromString( m_cxMainContext,m_device, kernelSource, kernelName, &pErrNum, prog,additionalMacros); + } + +}; +#endif + + +void SerializeDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD) + { +#ifdef DESERIALIZE_SOFT_BODIES + + //optional but useful: debug drawing + btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld; + + for ( int i=0;igetSoftBodyArray().size();i++) + { + btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i]; + if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) + { + btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags()); + } + } +#endif //DESERIALIZE_SOFT_BODIES + } + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + +enum SolverType +{ + kSolverAccelerationOpenCL_CPU = 1, + kSolverAccelerationOpenCL_GPU = 2, + kSolverAccelerationNone = 3 +}; + + +void SerializeDemo::setupEmptyDynamicsWorld() +{ + ///collision configuration contains default setup for memory, collision setup + //m_collisionConfiguration = new btDefaultCollisionConfiguration(); +#ifdef DESERIALIZE_SOFT_BODIES + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); +#else + m_collisionConfiguration = new btDefaultCollisionConfiguration(); +#endif //DESERIALIZE_SOFT_BODIES + + //m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + btGImpactCollisionAlgorithm::registerAlgorithm(m_dispatcher); + + m_broadphase = new btDbvtBroadphase(); + + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + +#ifdef DESERIALIZE_SOFT_BODIES + + + + #ifdef USE_AMD_OPENCL + + int solverAccel = kSolverAccelerationOpenCL_GPU; + + if ( 1 ) { + switch (solverAccel) + { + case kSolverAccelerationOpenCL_GPU: + { + btOpenCLSoftBodySolverSIMDAware* softSolv= new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue, g_cxMainContext ); + //btOpenCLSoftBodySolver* softSolv= new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext); + fSoftBodySolver = softSolv; + + CLFunctions* funcs = new CachingCLFuncs(g_cqCommandQue, g_cxMainContext,g_cdDevice); + softSolv->setCLFunctions(funcs); + + + break; + } + case kSolverAccelerationOpenCL_CPU: + { + //fSoftBodySolver = new btCPUSoftBodySolver(); + break; + }; + case kSolverAccelerationNone: + default: + { + fSoftBodySolver = NULL; + } + }; + } + else + { + if ( solverAccel != kSolverAccelerationNone ) + { + } + else + { + } + fSoftBodySolver = NULL; + } +#else + + fSoftBodySolver = NULL; +#endif + + btSoftRigidDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, + m_collisionConfiguration, fSoftBodySolver); + m_dynamicsWorld = world; + + + //world->setDrawFlags(world->getDrawFlags()^fDrawFlags::Clusters); +#else + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + //m_dynamicsWorld ->getSolverInfo().m_solverMode|=SOLVER_RANDMIZE_ORDER; + //m_dynamicsWorld->getDispatchInfo().m_enableSatConvex = true; + //m_dynamicsWorld->getSolverInfo().m_splitImpulse=true; +#endif //DESERIALIZE_SOFT_BODIES + + //btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher()); + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + +} + + +#ifdef DESERIALIZE_SOFT_BODIES +#include "BulletSoftBody/btSoftBodyData.h" +class MySoftBulletWorldImporter : public btBulletWorldImporter +{ + + btSoftRigidDynamicsWorld* m_softRigidWorld; + + btHashMap m_materialMap; + + btHashMap m_clusterBodyMap; + btHashMap m_softBodyMap; + + + +public: + + MySoftBulletWorldImporter(btSoftRigidDynamicsWorld* world) + :btBulletWorldImporter(world), + m_softRigidWorld(world) + { + + } + + virtual ~MySoftBulletWorldImporter() + { + + } + + virtual bool convertAllObjects( bParse::btBulletFile* bulletFile2) + { + bool result = btBulletWorldImporter::convertAllObjects(bulletFile2); + int i; + //now the soft bodies + for (i=0;im_softBodies.size();i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btAssert(0); //not yet + //btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i]; + } else + { + btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i]; + int i; + int numNodes = softBodyData->m_numNodes; + + + btSoftBody* psb=new btSoftBody(&m_softRigidWorld->getWorldInfo()); + m_softBodyMap.insert(softBodyData,psb); + + //materials + for (i=0;im_numMaterials;i++) + { + SoftBodyMaterialData* matData = softBodyData->m_materials[i]; + btSoftBody::Material** matPtr = m_materialMap.find(matData); + btSoftBody::Material* mat = 0; + if (matPtr&& *matPtr) + { + mat = *matPtr; + } else + { + mat = psb->appendMaterial(); + mat->m_flags = matData->m_flags; + mat->m_kAST = matData->m_angularStiffness; + mat->m_kLST = matData->m_linearStiffness; + mat->m_kVST = matData->m_volumeStiffness; + m_materialMap.insert(matData,mat); + } + } + + + + + for (i=0;im_nodes[i]; + btVector3 position; + position.deSerializeFloat(nodeData.m_position); + btScalar mass = nodeData.m_inverseMass? 1./nodeData.m_inverseMass : 0.f; + psb->appendNode(position,mass); + btSoftBody::Node* node = &psb->m_nodes[psb->m_nodes.size()-1]; + node->m_area = nodeData.m_area; + node->m_battach = nodeData.m_attach; + node->m_f.deSerializeFloat(nodeData.m_accumulatedForce); + node->m_im = nodeData.m_inverseMass; + + btSoftBody::Material** matPtr = m_materialMap.find(nodeData.m_material); + if (matPtr && *matPtr) + { + node->m_material = *matPtr; + } else + { + printf("no mat?\n"); + } + + node->m_n.deSerializeFloat(nodeData.m_normal); + node->m_q = node->m_x; + node->m_v.deSerializeFloat(nodeData.m_velocity); + + } + + for (i=0;im_numLinks;i++) + { + SoftBodyLinkData& linkData = softBodyData->m_links[i]; + btSoftBody::Material** matPtr = m_materialMap.find(linkData.m_material); + if (matPtr && *matPtr) + { + psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1],*matPtr); + } else + { + psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1]); + } + btSoftBody::Link* link = &psb->m_links[psb->m_links.size()-1]; + link->m_bbending = linkData.m_bbending; + link->m_rl = linkData.m_restLength; + } + + for (i=0;im_numFaces;i++) + { + SoftBodyFaceData& faceData = softBodyData->m_faces[i]; + btSoftBody::Material** matPtr = m_materialMap.find(faceData.m_material); + if (matPtr && *matPtr) + { + psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2],*matPtr); + } else + { + psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2]); + } + btSoftBody::Face* face = &psb->m_faces[psb->m_faces.size()-1]; + face->m_normal.deSerializeFloat(faceData.m_normal); + face->m_ra = faceData.m_restArea; + } + + + + //anchors + for (i=0;im_numAnchors;i++) + { + btCollisionObject** colAptr = m_bodyMap.find(softBodyData->m_anchors[i].m_rigidBody); + if (colAptr && *colAptr) + { + btRigidBody* body = btRigidBody::upcast(*colAptr); + if (body) + { + bool disableCollision = false; + btVector3 localPivot; + localPivot.deSerializeFloat(softBodyData->m_anchors[i].m_localFrame); + psb->appendAnchor(softBodyData->m_anchors[i].m_nodeIndex,body,localPivot, disableCollision); + } + } + } + + if (softBodyData->m_pose) + { + psb->m_pose.m_aqq.deSerializeFloat( softBodyData->m_pose->m_aqq); + psb->m_pose.m_bframe = (softBodyData->m_pose->m_bframe!=0); + psb->m_pose.m_bvolume = (softBodyData->m_pose->m_bvolume!=0); + psb->m_pose.m_com.deSerializeFloat(softBodyData->m_pose->m_com); + + psb->m_pose.m_pos.resize(softBodyData->m_pose->m_numPositions); + for (i=0;im_pose->m_numPositions;i++) + { + psb->m_pose.m_pos[i].deSerializeFloat(softBodyData->m_pose->m_positions[i]); + } + psb->m_pose.m_rot.deSerializeFloat(softBodyData->m_pose->m_rot); + psb->m_pose.m_scl.deSerializeFloat(softBodyData->m_pose->m_scale); + psb->m_pose.m_wgh.resize(softBodyData->m_pose->m_numWeigts); + for (i=0;im_pose->m_numWeigts;i++) + { + psb->m_pose.m_wgh[i] = softBodyData->m_pose->m_weights[i]; + } + psb->m_pose.m_volume = softBodyData->m_pose->m_restVolume; + } + +#if 1 + psb->m_cfg.piterations=softBodyData->m_config.m_positionIterations; + psb->m_cfg.diterations=softBodyData->m_config.m_driftIterations; + psb->m_cfg.citerations=softBodyData->m_config.m_clusterIterations; + psb->m_cfg.viterations=softBodyData->m_config.m_velocityIterations; + + //psb->setTotalMass(0.1); + psb->m_cfg.aeromodel = (btSoftBody::eAeroModel::_)softBodyData->m_config.m_aeroModel; + psb->m_cfg.kLF = softBodyData->m_config.m_lift; + psb->m_cfg.kDG = softBodyData->m_config.m_drag; + psb->m_cfg.kMT = softBodyData->m_config.m_poseMatch; + psb->m_cfg.collisions = softBodyData->m_config.m_collisionFlags; + psb->m_cfg.kDF = 1.f;//softBodyData->m_config.m_dynamicFriction; + psb->m_cfg.kDP = softBodyData->m_config.m_damping; + psb->m_cfg.kPR = softBodyData->m_config.m_pressure; + psb->m_cfg.kVC = softBodyData->m_config.m_volume; + psb->m_cfg.kAHR = softBodyData->m_config.m_anchorHardness; + psb->m_cfg.kKHR = softBodyData->m_config.m_kineticContactHardness; + psb->m_cfg.kSHR = softBodyData->m_config.m_softContactHardness; + psb->m_cfg.kSRHR_CL = softBodyData->m_config.m_softRigidClusterHardness; + psb->m_cfg.kSKHR_CL = softBodyData->m_config.m_softKineticClusterHardness; + psb->m_cfg.kSSHR_CL = softBodyData->m_config.m_softSoftClusterHardness; +#endif + +// pm->m_kLST = 1; + +#if 1 + //clusters + if (softBodyData->m_numClusters) + { + m_clusterBodyMap.insert(softBodyData->m_clusters,psb); + int j; + psb->m_clusters.resize(softBodyData->m_numClusters); + for (i=0;im_numClusters;i++) + { + psb->m_clusters[i] = new(btAlignedAlloc(sizeof(btSoftBody::Cluster),16)) btSoftBody::Cluster(); + psb->m_clusters[i]->m_adamping = softBodyData->m_clusters[i].m_adamping; + psb->m_clusters[i]->m_av.deSerializeFloat(softBodyData->m_clusters[i].m_av); + psb->m_clusters[i]->m_clusterIndex = softBodyData->m_clusters[i].m_clusterIndex; + psb->m_clusters[i]->m_collide = (softBodyData->m_clusters[i].m_collide!=0); + psb->m_clusters[i]->m_com.deSerializeFloat(softBodyData->m_clusters[i].m_com); + psb->m_clusters[i]->m_containsAnchor = (softBodyData->m_clusters[i].m_containsAnchor!=0); + psb->m_clusters[i]->m_dimpulses[0].deSerializeFloat(softBodyData->m_clusters[i].m_dimpulses[0]); + psb->m_clusters[i]->m_dimpulses[1].deSerializeFloat(softBodyData->m_clusters[i].m_dimpulses[1]); + + psb->m_clusters[i]->m_framerefs.resize(softBodyData->m_clusters[i].m_numFrameRefs); + for (j=0;jm_clusters[i].m_numFrameRefs;j++) + { + psb->m_clusters[i]->m_framerefs[j].deSerializeFloat(softBodyData->m_clusters[i].m_framerefs[j]); + } + psb->m_clusters[i]->m_nodes.resize(softBodyData->m_clusters[i].m_numNodes); + for (j=0;jm_clusters[i].m_numNodes;j++) + { + int nodeIndex = softBodyData->m_clusters[i].m_nodeIndices[j]; + psb->m_clusters[i]->m_nodes[j] = &psb->m_nodes[nodeIndex]; + } + + psb->m_clusters[i]->m_masses.resize(softBodyData->m_clusters[i].m_numMasses); + for (j=0;jm_clusters[i].m_numMasses;j++) + { + psb->m_clusters[i]->m_masses[j] = softBodyData->m_clusters[i].m_masses[j]; + } + psb->m_clusters[i]->m_framexform.deSerializeFloat(softBodyData->m_clusters[i].m_framexform); + psb->m_clusters[i]->m_idmass = softBodyData->m_clusters[i].m_idmass; + psb->m_clusters[i]->m_imass = softBodyData->m_clusters[i].m_imass; + psb->m_clusters[i]->m_invwi.deSerializeFloat(softBodyData->m_clusters[i].m_invwi); + psb->m_clusters[i]->m_ldamping = softBodyData->m_clusters[i].m_ldamping; + psb->m_clusters[i]->m_locii.deSerializeFloat(softBodyData->m_clusters[i].m_locii); + psb->m_clusters[i]->m_lv.deSerializeFloat(softBodyData->m_clusters[i].m_lv); + psb->m_clusters[i]->m_matching = softBodyData->m_clusters[i].m_matching; + psb->m_clusters[i]->m_maxSelfCollisionImpulse = 0;//softBodyData->m_clusters[i].m_maxSelfCollisionImpulse; + psb->m_clusters[i]->m_ndamping = softBodyData->m_clusters[i].m_ndamping; + psb->m_clusters[i]->m_ndimpulses = softBodyData->m_clusters[i].m_ndimpulses; + psb->m_clusters[i]->m_nvimpulses = softBodyData->m_clusters[i].m_nvimpulses; + psb->m_clusters[i]->m_selfCollisionImpulseFactor = softBodyData->m_clusters[i].m_selfCollisionImpulseFactor; + psb->m_clusters[i]->m_vimpulses[0].deSerializeFloat(softBodyData->m_clusters[i].m_vimpulses[0]); + psb->m_clusters[i]->m_vimpulses[1].deSerializeFloat(softBodyData->m_clusters[i].m_vimpulses[1]); + + } + //psb->initializeClusters(); + //psb->updateClusters(); + + } +#else + + psb->m_cfg.piterations = 2; + psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS; + //psb->setTotalMass(50,true); + //psb->generateClusters(64); + //psb->m_cfg.kDF=1; + psb->generateClusters(8); + + +#endif // + + + + psb->updateConstants(); + m_softRigidWorld->getWorldInfo().m_dispatcher = m_softRigidWorld->getDispatcher(); + + m_softRigidWorld->addSoftBody(psb); + + + } + } + + + //now the soft body joints + for (i=0;im_softBodies.size();i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btAssert(0); //not yet + //btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i]; + } else + { + btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i]; + btSoftBody** sbp = m_softBodyMap.find(softBodyData); + if (sbp && *sbp) + { + btSoftBody* sb = *sbp; + for (int i=0;im_numJoints;i++) + { + btSoftBodyJointData* sbjoint = &softBodyData->m_joints[i]; + + + btSoftBody::Body bdyB; + + btSoftBody* sbB = 0; + btTransform transA; + transA.setIdentity(); + transA = sb->m_clusters[0]->m_framexform; + + btCollisionObject** colBptr = m_bodyMap.find(sbjoint->m_bodyB); + if (colBptr && *colBptr) + { + btRigidBody* rbB = btRigidBody::upcast(*colBptr); + if (rbB) + { + bdyB = rbB; + } else + { + bdyB = *colBptr; + } + } + + + btSoftBody** bodyBptr = m_clusterBodyMap.find(sbjoint->m_bodyB); + if (bodyBptr && *bodyBptr ) + { + sbB = *bodyBptr; + bdyB = sbB->m_clusters[0]; + } + + + if (sbjoint->m_jointType==btSoftBody::Joint::eType::Linear) + { + btSoftBody::LJoint::Specs specs; + specs.cfm = sbjoint->m_cfm; + specs.erp = sbjoint->m_erp; + specs.split = sbjoint->m_split; + btVector3 relA; + relA.deSerializeFloat(sbjoint->m_refs[0]); + specs.position = transA*relA; + sb->appendLinearJoint(specs,sb->m_clusters[0],bdyB); + } + + if (sbjoint->m_jointType==btSoftBody::Joint::eType::Angular) + { + btSoftBody::AJoint::Specs specs; + specs.cfm = sbjoint->m_cfm; + specs.erp = sbjoint->m_erp; + specs.split = sbjoint->m_split; + btVector3 relA; + relA.deSerializeFloat(sbjoint->m_refs[0]); + specs.axis = transA.getBasis()*relA; + sb->appendAngularJoint(specs,sb->m_clusters[0],bdyB); + } + } + } + + } + } + + return result; + + } +}; +#endif //DESERIALIZE_SOFT_BODIES + +SerializeDemo::SerializeDemo() +:m_verboseMode(0), +m_fileName("testFile.bullet") +{ + m_idle=true; + +} +SerializeDemo::~SerializeDemo() +{ + m_fileLoader->deleteAllData(); + delete m_fileLoader; + exitPhysics(); +} + +void SerializeDemo::initPhysics() +{ + setTexturing(true); + setShadows(false);//true); + + setCameraDistance(btScalar(SCALING*30.)); + + setupEmptyDynamicsWorld(); + +#ifdef DESERIALIZE_SOFT_BODIES + m_fileLoader = new MySoftBulletWorldImporter((btSoftRigidDynamicsWorld*)m_dynamicsWorld); +#else + m_fileLoader = new btBulletWorldImporter(m_dynamicsWorld); +#endif //DESERIALIZE_SOFT_BODIES + + m_fileLoader->setVerboseMode(m_verboseMode); + + + + if (!m_fileLoader->loadFile("testFile.bullet")) +// if (!m_fileLoader->loadFile("../SoftDemo/testFile.bullet")) + { + ///create a few basic rigid bodies and save them to testFile.bullet + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + btCollisionObject* groundObject = 0; + + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + groundObject = body; + } + + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + int numSpheres = 2; + btVector3 positions[2] = {btVector3(0.1f,0.2f,0.3f),btVector3(0.4f,0.5f,0.6f)}; + btScalar radii[2] = {0.3f,0.4f}; + + btMultiSphereShape* colShape = new btMultiSphereShape(positions,radii,numSpheres); + + //btCollisionShape* colShape = new btCapsuleShapeZ(SCALING*1,SCALING*1); + //btCollisionShape* colShape = new btCylinderShapeZ(btVector3(SCALING*1,SCALING*1,SCALING*1)); + //btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(colShape); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); + + float start_x = START_POS_X - ARRAY_SIZE_X/2; + float start_y = START_POS_Y; + float start_z = START_POS_Z - ARRAY_SIZE_Z/2; + + for (int k=0;kaddRigidBody(body); + //body->setActivationState(ISLAND_SLEEPING); + } + } + } + } + + int maxSerializeBufferSize = 1024*1024*5; + + btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); + + static const char* groundName = "GroundName"; + serializer->registerNameForPointer(groundObject, groundName); + + for (int i=0;iregisterNameForPointer(m_collisionShapes[i],name); + } + + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*(btRigidBody*)getDynamicsWorld()->getCollisionObjectArray()[2],btVector3(0,1,0)); + m_dynamicsWorld->addConstraint(p2p); + + const char* name = "constraintje"; + serializer->registerNameForPointer(p2p,name); + + m_dynamicsWorld->serialize(serializer); +#if 1 + FILE* f2 = fopen("testFile.bullet","wb"); + fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); + fclose(f2); +#endif + + } + + //clientResetScene(); + +} + + +void SerializeDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + class btBulletWorldImporter* m_fileLoader; + const char* m_fileName; + int m_verboseMode; + + public: + + SerializeDemo(); + virtual ~SerializeDemo(); + + void initPhysics(); + + void setupEmptyDynamicsWorld(); + + void exitPhysics(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + void setFileName(const char* name) + { + m_fileName = name; + } + const char* getFileName() const + { + return m_fileName; + } + + void setVerboseMode(int mode) + { + m_verboseMode = mode; + } + int getVerboseMode() const + { + return m_verboseMode; + } + + static DemoApplication* Create() + { + SerializeDemo* demo = new SerializeDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //SERIALIZE_DEMO_H + diff --git a/Demos/SerializeDemo/Win32SerializeDemo.cpp b/Demos/SerializeDemo/Win32SerializeDemo.cpp new file mode 100644 index 0000000..0cf13e8 --- /dev/null +++ b/Demos/SerializeDemo/Win32SerializeDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SerializeDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new SerializeDemo(); +} + +#endif diff --git a/Demos/SerializeDemo/main.cpp b/Demos/SerializeDemo/main.cpp new file mode 100644 index 0000000..87b88f8 --- /dev/null +++ b/Demos/SerializeDemo/main.cpp @@ -0,0 +1,134 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SerializeDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" +#include "btBulletFile.h" +#include "CommandLineArguments.h" + + +#ifdef USE_AMD_OPENCL + + + +#include "btOpenCLUtils.h" + +#include + +cl_context g_cxMainContext; +cl_device_id g_cdDevice; +cl_command_queue g_cqCommandQue; + + +// Returns true if OpenCL is initialized properly, false otherwise. +bool initCL( void* glCtx, void* glDC ) +{ + const char* vendorSDK = btOpenCLUtils::getSdkVendorName(); + printf("This program was compiled using the %s OpenCL SDK\n",vendorSDK); + + int ciErrNum = 0; + +#ifdef BT_USE_CLEW + ciErrNum = clewInit( "OpenCL.dll" ); + if ( ciErrNum != CLEW_SUCCESS ) { + return false; + } +#endif + +#if defined(CL_PLATFORM_MINI_CL) + cl_device_type deviceType = CL_DEVICE_TYPE_CPU; +#elif defined(CL_PLATFORM_AMD) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#elif defined(CL_PLATFORM_NVIDIA) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#else + cl_device_type deviceType = CL_DEVICE_TYPE_CPU; +#endif + + g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext); + if (!numDev) + return false; + + g_cdDevice = btOpenCLUtils::getDevice(g_cxMainContext,0); + + btOpenCLDeviceInfo clInfo; + btOpenCLUtils::getDeviceInfo(g_cdDevice,clInfo); + btOpenCLUtils::printDeviceInfo(g_cdDevice); + + // create a command-queue + g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_cdDevice, 0, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + return true; +} + +#endif //#ifdef USE_AMD_OPENCL + + +int main(int argc,char** argv) +{ + CommandLineArguments arg(argc,argv); + char* filename=0; + arg.GetCmdLineArgument("filename", filename); + bool dumpXml = arg.CheckCmdLineFlag("dump_xml"); + if (!dumpXml && !filename) + { + printf("There are some optional commandline arguments for this demo:\n"); + printf("Load another .bullet file instead of testFile.bullet:\n"); + printf("--filename=testfile.bullet\n"); + printf("Dump the imported .bullet file to XML\n"); + printf("--dump_xml\n"); + + } + + + + GLDebugDrawer gDebugDrawer; +#ifdef USE_AMD_OPENCL + + bool initialized = initCL(0,0); + btAssert(initialized); +#endif //USE_AMD_OPENCL + + + SerializeDemo serializeDemo; + + int mode = 0; + if (dumpXml) + mode |=bParse::FD_VERBOSE_EXPORT_XML; + if (filename) + serializeDemo.setFileName(filename); + serializeDemo.setVerboseMode(mode); + + serializeDemo.initPhysics(); + serializeDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + +#ifdef CHECK_MEMORY_LEAKS + serializeDemo.exitPhysics(); +#else + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.org",&serializeDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/SerializeDemo/testFile.bullet b/Demos/SerializeDemo/testFile.bullet new file mode 100644 index 0000000000000000000000000000000000000000..d535938f066791f0f6f12f50b6c83689721a9d9f GIT binary patch literal 171368 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

    ukqgbr5ktHn!7zoDgoV+tBq(do1|O?-Prxz} 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 idbdvU9-ZPxba40S&~{Eye%~JU(#}5i(~ +#else +#include +#endif +#else +#ifdef USE_MINICL +#include +#else +#include +#include +#endif +#endif //__APPLE__ + +#include +#include +#define oclCHECKERROR(a, b) if((a)!=(b)) { printf("OCL Error : %d\n", (a)); assert((a) == (b)); } + + +#endif //BT_OPENCL_INCLUDE_H + diff --git a/Demos/SharedOpenCL/btOpenCLUtils.cpp b/Demos/SharedOpenCL/btOpenCLUtils.cpp new file mode 100644 index 0000000..a76971a --- /dev/null +++ b/Demos/SharedOpenCL/btOpenCLUtils.cpp @@ -0,0 +1,789 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2011 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//original author: Roman Ponomarev +//cleanup by Erwin Coumans + +#include + +#include "btOpenCLUtils.h" +#include +#include + +#define BT_MAX_CL_DEVICES 16 //who needs 16 devices? +//#define BT_USE_CACHE_DIR +#ifdef _WIN32 +#include +#endif //_WIN32 + +#include +#define btAssert assert + +//Set the preferred platform vendor using the OpenCL SDK +static const char* spPlatformVendor = +#if defined(CL_PLATFORM_MINI_CL) +"MiniCL, SCEA"; +#elif defined(CL_PLATFORM_AMD) +"Advanced Micro Devices, Inc."; +#elif defined(CL_PLATFORM_NVIDIA) +"NVIDIA Corporation"; +#elif defined(CL_PLATFORM_INTEL) +"Intel(R) Corporation"; +#else +"Unknown Vendor"; +#endif + +#ifndef CL_PLATFORM_MINI_CL +#ifdef _WIN32 +#include "CL/cl_gl.h" +#endif //_WIN32 +#endif + +int btOpenCLUtils::getNumPlatforms(cl_int* pErrNum) +{ + cl_uint numPlatforms=0; + cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); + + if(ciErrNum != CL_SUCCESS) + { + if(pErrNum != NULL) + *pErrNum = ciErrNum; + } + return numPlatforms; +} + +const char* btOpenCLUtils::getSdkVendorName() +{ + return spPlatformVendor; +} + +cl_platform_id btOpenCLUtils::getPlatform(int platformIndex, cl_int* pErrNum) +{ + cl_platform_id platform = 0; + + cl_uint numPlatforms; + cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); + + if (platformIndex>=0 && platformIndex=0 && preferredDeviceIndex 0) + { + cl_platform_id* platforms = new cl_platform_id[numPlatforms]; + ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL); + if(ciErrNum != CL_SUCCESS) + { + if(pErrNum != NULL) *pErrNum = ciErrNum; + return NULL; + } + int i; + + + for ( i = 0; i < numPlatforms; ++i) + { + char pbuf[128]; + ciErrNum = clGetPlatformInfo( platforms[i], + CL_PLATFORM_VENDOR, + sizeof(pbuf), + pbuf, + NULL); + if(ciErrNum != CL_SUCCESS) + { + if(pErrNum != NULL) *pErrNum = ciErrNum; + return NULL; + } + + if (preferredPlatformIndex>=0 && i==preferredPlatformIndex) + { + cl_platform_id tmpPlatform = platforms[0]; + platforms[0] = platforms[i]; + platforms[i] = tmpPlatform; + break; + } else + { + if(!strcmp(pbuf, spPlatformVendor)) + { + cl_platform_id tmpPlatform = platforms[0]; + platforms[0] = platforms[i]; + platforms[i] = tmpPlatform; + break; + } + } + } + + for (i = 0; i < numPlatforms; ++i) + { + cl_platform_id platform = platforms[i]; + assert(platform); + + retContext = btOpenCLUtils::createContextFromPlatform(platform,deviceType,pErrNum,pGLContext,pGLDC,preferredDeviceIndex); + + if (retContext) + { +// printf("OpenCL platform details:\n"); + btOpenCLPlatformInfo platformInfo; + + btOpenCLUtils::getPlatformInfo(platform, platformInfo); + + printf(" CL_PLATFORM_VENDOR: \t\t\t%s\n",platformInfo.m_platformVendor); + printf(" CL_PLATFORM_NAME: \t\t\t%s\n",platformInfo.m_platformName); + printf(" CL_PLATFORM_VERSION: \t\t\t%s\n",platformInfo.m_platformVersion); + + break; + } + } + + delete[] platforms; + } + return retContext; +} + + +////////////////////////////////////////////////////////////////////////////// +//! Gets the id of the nth device from the context +//! +//! @return the id or -1 when out of range +//! @param cxMainContext OpenCL context +//! @param device_idx index of the device of interest +////////////////////////////////////////////////////////////////////////////// +cl_device_id btOpenCLUtils::getDevice(cl_context cxMainContext, int deviceIndex) +{ + size_t szParmDataBytes; + cl_device_id* cdDevices; + + // get the list of devices associated with context + clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes); + + if( szParmDataBytes / sizeof(cl_device_id) < deviceIndex ) { + return (cl_device_id)-1; + } + + cdDevices = (cl_device_id*) malloc(szParmDataBytes); + + clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL); + + cl_device_id device = cdDevices[deviceIndex]; + free(cdDevices); + + return device; +} + +int btOpenCLUtils::getNumDevices(cl_context cxMainContext) +{ + size_t szParamDataBytes; + clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParamDataBytes); + int device_count = (int) szParamDataBytes/ sizeof(cl_device_id); + return device_count; +} + +void btOpenCLUtils::printDeviceInfo(cl_device_id device) +{ + btOpenCLDeviceInfo info; + getDeviceInfo(device,info); + + printf(" CL_DEVICE_NAME: \t\t\t%s\n", info.m_deviceName); + printf(" CL_DEVICE_VENDOR: \t\t\t%s\n", info.m_deviceVendor); + printf(" CL_DRIVER_VERSION: \t\t\t%s\n", info.m_driverVersion); + + if( info.m_deviceType & CL_DEVICE_TYPE_CPU ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_CPU"); + if( info.m_deviceType & CL_DEVICE_TYPE_GPU ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_GPU"); + if( info.m_deviceType & CL_DEVICE_TYPE_ACCELERATOR ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR"); + if( info.m_deviceType & CL_DEVICE_TYPE_DEFAULT ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT"); + + printf(" CL_DEVICE_MAX_COMPUTE_UNITS:\t\t%u\n", info.m_computeUnits); + printf(" CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:\t%zu\n", info.m_workitemDims); + printf(" CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%zu / %zu / %zu \n", info.m_workItemSize[0], info.m_workItemSize[1], info.m_workItemSize[2]); + printf(" CL_DEVICE_MAX_WORK_GROUP_SIZE:\t%zu\n", info.m_workgroupSize); + printf(" CL_DEVICE_MAX_CLOCK_FREQUENCY:\t%u MHz\n", info.m_clockFrequency); + printf(" CL_DEVICE_ADDRESS_BITS:\t\t%u\n", info.m_addressBits); + printf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_maxMemAllocSize/ (1024 * 1024))); + printf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_globalMemSize/ (1024 * 1024))); + printf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", info.m_errorCorrectionSupport== CL_TRUE ? "yes" : "no"); + printf(" CL_DEVICE_LOCAL_MEM_TYPE:\t\t%s\n", info.m_localMemType == 1 ? "local" : "global"); + printf(" CL_DEVICE_LOCAL_MEM_SIZE:\t\t%u KByte\n", (unsigned int)(info.m_localMemSize / 1024)); + printf(" CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:\t%u KByte\n", (unsigned int)(info.m_constantBufferSize / 1024)); + if( info.m_queueProperties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE ) + printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE"); + if( info.m_queueProperties & CL_QUEUE_PROFILING_ENABLE ) + printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_PROFILING_ENABLE"); + + printf(" CL_DEVICE_IMAGE_SUPPORT:\t\t%u\n", info.m_imageSupport); + + printf(" CL_DEVICE_MAX_READ_IMAGE_ARGS:\t%u\n", info.m_maxReadImageArgs); + printf(" CL_DEVICE_MAX_WRITE_IMAGE_ARGS:\t%u\n", info.m_maxWriteImageArgs); + printf("\n CL_DEVICE_IMAGE "); + printf("\t\t\t2D_MAX_WIDTH\t %zu\n", info.m_image2dMaxWidth); + printf("\t\t\t\t\t2D_MAX_HEIGHT\t %zu\n", info.m_image2dMaxHeight); + printf("\t\t\t\t\t3D_MAX_WIDTH\t %zu\n", info.m_image3dMaxWidth); + printf("\t\t\t\t\t3D_MAX_HEIGHT\t %zu\n", info.m_image3dMaxHeight); + printf("\t\t\t\t\t3D_MAX_DEPTH\t %zu\n", info.m_image3dMaxDepth); + if (info.m_deviceExtensions != 0) + printf("\n CL_DEVICE_EXTENSIONS:%s\n",info.m_deviceExtensions); + else + printf(" CL_DEVICE_EXTENSIONS: None\n"); + printf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_\t"); + printf("CHAR %u, SHORT %u, INT %u,LONG %u, FLOAT %u, DOUBLE %u\n\n\n", + info.m_vecWidthChar, info.m_vecWidthShort, info.m_vecWidthInt, info.m_vecWidthLong,info.m_vecWidthFloat, info.m_vecWidthDouble); + + +} + +void btOpenCLUtils::getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo& info) +{ + + // CL_DEVICE_NAME + clGetDeviceInfo(device, CL_DEVICE_NAME, BT_MAX_STRING_LENGTH, &info.m_deviceName, NULL); + + // CL_DEVICE_VENDOR + clGetDeviceInfo(device, CL_DEVICE_VENDOR, BT_MAX_STRING_LENGTH, &info.m_deviceVendor, NULL); + + // CL_DRIVER_VERSION + clGetDeviceInfo(device, CL_DRIVER_VERSION, BT_MAX_STRING_LENGTH, &info.m_driverVersion, NULL); + + // CL_DEVICE_INFO + clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(cl_device_type), &info.m_deviceType, NULL); + + // CL_DEVICE_MAX_COMPUTE_UNITS + clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(info.m_computeUnits), &info.m_computeUnits, NULL); + + // CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(info.m_workitemDims), &info.m_workitemDims, NULL); + + // CL_DEVICE_MAX_WORK_ITEM_SIZES + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(info.m_workItemSize), &info.m_workItemSize, NULL); + + // CL_DEVICE_MAX_WORK_GROUP_SIZE + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(info.m_workgroupSize), &info.m_workgroupSize, NULL); + + // CL_DEVICE_MAX_CLOCK_FREQUENCY + clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(info.m_clockFrequency), &info.m_clockFrequency, NULL); + + // CL_DEVICE_ADDRESS_BITS + clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(info.m_addressBits), &info.m_addressBits, NULL); + + // CL_DEVICE_MAX_MEM_ALLOC_SIZE + clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(info.m_maxMemAllocSize), &info.m_maxMemAllocSize, NULL); + + // CL_DEVICE_GLOBAL_MEM_SIZE + clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(info.m_globalMemSize), &info.m_globalMemSize, NULL); + + // CL_DEVICE_ERROR_CORRECTION_SUPPORT + clGetDeviceInfo(device, CL_DEVICE_ERROR_CORRECTION_SUPPORT, sizeof(info.m_errorCorrectionSupport), &info.m_errorCorrectionSupport, NULL); + + // CL_DEVICE_LOCAL_MEM_TYPE + clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_TYPE, sizeof(info.m_localMemType), &info.m_localMemType, NULL); + + // CL_DEVICE_LOCAL_MEM_SIZE + clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(info.m_localMemSize), &info.m_localMemSize, NULL); + + // CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE + clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(info.m_constantBufferSize), &info.m_constantBufferSize, NULL); + + // CL_DEVICE_QUEUE_PROPERTIES + clGetDeviceInfo(device, CL_DEVICE_QUEUE_PROPERTIES, sizeof(info.m_queueProperties), &info.m_queueProperties, NULL); + + // CL_DEVICE_IMAGE_SUPPORT + clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(info.m_imageSupport), &info.m_imageSupport, NULL); + + // CL_DEVICE_MAX_READ_IMAGE_ARGS + clGetDeviceInfo(device, CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof(info.m_maxReadImageArgs), &info.m_maxReadImageArgs, NULL); + + // CL_DEVICE_MAX_WRITE_IMAGE_ARGS + clGetDeviceInfo(device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof(info.m_maxWriteImageArgs), &info.m_maxWriteImageArgs, NULL); + + // CL_DEVICE_IMAGE2D_MAX_WIDTH, CL_DEVICE_IMAGE2D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_WIDTH, CL_DEVICE_IMAGE3D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_DEPTH + clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &info.m_image2dMaxWidth, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &info.m_image2dMaxHeight, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &info.m_image3dMaxWidth, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &info.m_image3dMaxHeight, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &info.m_image3dMaxDepth, NULL); + + // CL_DEVICE_EXTENSIONS: get device extensions, and if any then parse & log the string onto separate lines + clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, BT_MAX_STRING_LENGTH, &info.m_deviceExtensions, NULL); + + // CL_DEVICE_PREFERRED_VECTOR_WIDTH_ + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &info.m_vecWidthChar, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof(cl_uint), &info.m_vecWidthShort, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), &info.m_vecWidthInt, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof(cl_uint), &info.m_vecWidthLong, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(cl_uint), &info.m_vecWidthFloat, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &info.m_vecWidthDouble, NULL); +} + +static char* strip1(char* name, const char* pattern,int* numOccurences=0) +{ + size_t const patlen = strlen(pattern); + char * oriptr; + char * patloc; + // find how many times the pattern occurs in the original string + for (oriptr = name; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen) + { + if (numOccurences) + (*numOccurences)++; + } + return oriptr; +} +static const char* strip2(const char* name, const char* pattern,int* numOccurences=0) +{ + size_t const patlen = strlen(pattern); + const char * oriptr; + const char * patloc; + // find how many times the pattern occurs in the original string + for (oriptr = name; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen) + { + if (numOccurences) + (*numOccurences)++; + } + return oriptr; +} + +cl_program btOpenCLUtils::compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSource, cl_int* pErrNum, const char* additionalMacros) +{ + + cl_int localErrNum; + size_t program_length = strlen(kernelSource); + + cl_program m_cpProgram = clCreateProgramWithSource(clContext, 1, (const char**)&kernelSource, &program_length, &localErrNum); + if (localErrNum!= CL_SUCCESS) + { + if (pErrNum) + *pErrNum = localErrNum; + return 0; + } + + // Build the program with 'mad' Optimization option + + +#ifdef MAC + char* flags = "-cl-mad-enable -DMAC -DGUID_ARG"; +#else + //const char* flags = "-DGUID_ARG= -fno-alias"; + const char* flags = "-DGUID_ARG= "; +#endif + + char* compileFlags = new char[strlen(additionalMacros) + strlen(flags) + 5]; + sprintf(compileFlags, "%s %s", flags, additionalMacros); + localErrNum = clBuildProgram(m_cpProgram, 1, &device, compileFlags, NULL, NULL); + if (localErrNum!= CL_SUCCESS) + { + char *build_log; + size_t ret_val_size; + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); + build_log = new char[ret_val_size+1]; + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); + + // to be carefully, terminate with \0 + // there's no information in the reference whether the string is 0 terminated or not + build_log[ret_val_size] = '\0'; + + + printf("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log); + delete[] build_log; + if (pErrNum) + *pErrNum = localErrNum; + return 0; + } + delete[] compileFlags; + return m_cpProgram; +} + +cl_program btOpenCLUtils::compileCLProgramFromFile(cl_context clContext, cl_device_id device, cl_int* pErrNum, const char* additionalMacros , const char* clFileNameForCaching) +{ + + cl_program m_cpProgram=0; + cl_int status; + char binaryFileName[522]; + + if (clFileNameForCaching) + { +#ifdef _WIN32 + char deviceName[256]; + char driverVersion[256]; + clGetDeviceInfo(device, CL_DEVICE_NAME, 256, &deviceName, NULL); + clGetDeviceInfo(device, CL_DRIVER_VERSION, 256, &driverVersion, NULL); + + + const char* strippedName = strip2(clFileNameForCaching,"\\"); + strippedName = strip2(strippedName,"/"); +#ifdef BT_USE_CACHE_DIR + sprintf_s(binaryFileName,"cache/%s.%s.%s.bin",strippedName, deviceName,driverVersion ); +#else + sprintf_s(binaryFileName,"%s.%s.%s.bin",strippedName, deviceName,driverVersion ); +#endif + + //printf("searching for %s\n", binaryFileName); + + bool fileUpToDate = false; + bool binaryFileValid=false; + + FILETIME modtimeBinary; + +#ifdef BT_USE_CACHE_DIR + CreateDirectory("cache",0); +#endif //BT_USE_CACHE_DIR + { + + HANDLE binaryFileHandle = CreateFile(binaryFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + if (binaryFileHandle ==INVALID_HANDLE_VALUE) + { + DWORD errorCode; + errorCode = GetLastError(); + switch (errorCode) + { + case ERROR_FILE_NOT_FOUND: + { + printf("\nCached file not found %s\n", binaryFileName); + break; + } + case ERROR_PATH_NOT_FOUND: + { + printf("\nCached file path not found %s\n", binaryFileName); + break; + } + default: + { + printf("\nFailed reading cached file with errorCode = %d\n", errorCode); + } + } + } else + { + if (GetFileTime(binaryFileHandle, NULL, NULL, &modtimeBinary)==0) + { + DWORD errorCode; + errorCode = GetLastError(); + printf("\nGetFileTime errorCode = %d\n", errorCode); + } else + { + binaryFileValid = true; + } + CloseHandle(binaryFileHandle); + } + + if (binaryFileValid) + { + HANDLE srcFileHandle = CreateFile(clFileNameForCaching,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + if (srcFileHandle!=INVALID_HANDLE_VALUE) + { + FILETIME modtimeSrc; + if (GetFileTime(srcFileHandle, NULL, NULL, &modtimeSrc)==0) + { + DWORD errorCode; + errorCode = GetLastError(); + printf("\nGetFileTime errorCode = %d\n", errorCode); + } + if ( ( modtimeSrc.dwHighDateTime < modtimeBinary.dwHighDateTime) + ||(( modtimeSrc.dwHighDateTime == modtimeBinary.dwHighDateTime)&&(modtimeSrc.dwLowDateTime <= modtimeBinary.dwLowDateTime))) + { + fileUpToDate=true; + } else + { + printf("\nCached binary file out-of-date (%s)\n",binaryFileName); + } + CloseHandle(srcFileHandle); + } + else + { + DWORD errorCode; + errorCode = GetLastError(); + switch (errorCode) + { + case ERROR_FILE_NOT_FOUND: + { + printf("\nSrc file not found %s\n", clFileNameForCaching); + break; + } + case ERROR_PATH_NOT_FOUND: + { + printf("\nSrc path not found %s\n", clFileNameForCaching); + break; + } + default: + { + printf("\nnSrc file reading errorCode = %d\n", errorCode); + } + } + + //we should make sure the src file exists so we can verify the timestamp with binary + fileUpToDate = false; + } + } + + + } + + if( fileUpToDate) + { + FILE* file = fopen(binaryFileName, "rb"); + if (file) + { + fseek( file, 0L, SEEK_END ); + size_t binarySize = ftell( file ); + rewind( file ); + char* binary = new char[binarySize]; + fread( binary, sizeof(char), binarySize, file ); + fclose( file ); + + m_cpProgram = clCreateProgramWithBinary( clContext, 1,&device, &binarySize, (const unsigned char**)&binary, 0, &status ); + btAssert( status == CL_SUCCESS ); + status = clBuildProgram( m_cpProgram, 1, &device, additionalMacros, 0, 0 ); + btAssert( status == CL_SUCCESS ); + + if( status != CL_SUCCESS ) + { + char *build_log; + size_t ret_val_size; + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); + build_log = new char[ret_val_size+1]; + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); + build_log[ret_val_size] = '\0'; + printf("%s\n", build_log); + delete build_log; + btAssert(0); + m_cpProgram = 0; + } + delete[] binary; + } + } +#endif //_WIN32 + + } + + if (!m_cpProgram) + { + + FILE* file = fopen(clFileNameForCaching, "r"); + if (file) + { + fseek( file, 0L, SEEK_END ); + size_t fileSize= ftell( file ); + rewind( file ); + char* kernelSource2 = new char[fileSize+1]; + fread( kernelSource2, sizeof(char), fileSize, file ); + fclose( file ); + kernelSource2[fileSize]=0; + int numOccurences = 0; + ///patch/remove the MSTRINGIFY( and ); + char* kernelSource = strip1(kernelSource2,"MSTRINGIFY(",&numOccurences); + int newlen = strlen(kernelSource); + if (numOccurences) + { + int i=newlen-1; + + for (;i>=0;i--) + { + if (kernelSource[i] == ';') + { + kernelSource[i] = 0;//' '; + break; + } + } + for (;i>=0;i--) + { + if (kernelSource[i] == ')') + { + kernelSource[i] = 0;//' '; + break; + } + } + } + + m_cpProgram = compileCLProgramFromString(clContext,device,kernelSource,pErrNum,additionalMacros); + + if( clFileNameForCaching ) + { // write to binary + + cl_uint numAssociatedDevices; + status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &numAssociatedDevices, 0 ); + btAssert( status == CL_SUCCESS ); + if (numAssociatedDevices==1) + { + + size_t binarySize; + status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binarySize, 0 ); + btAssert( status == CL_SUCCESS ); + + char* binary = new char[binarySize]; + + status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARIES, sizeof(char*), &binary, 0 ); + btAssert( status == CL_SUCCESS ); + + { + FILE* file = fopen(binaryFileName, "wb"); + if (file) + { + fwrite( binary, sizeof(char), binarySize, file ); + fclose( file ); + } else + { + printf("cannot write file %s\n", binaryFileName); + } + } + + delete [] binary; + } + } + } + } + + return m_cpProgram; +} + + +cl_kernel btOpenCLUtils::compileCLKernelFromString(cl_context clContext, cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog, const char* additionalMacros ) +{ + printf("compiling kernel %s ",kernelName); + cl_kernel kernel; + cl_int localErrNum; + //size_t program_length = strlen(kernelSource); + + + cl_program m_cpProgram = prog; + if (!m_cpProgram) + { + m_cpProgram = compileCLProgramFromString(clContext,device,kernelSource,pErrNum, additionalMacros); + } + + + // Create the kernel + kernel = clCreateKernel(m_cpProgram, kernelName, &localErrNum); + if (localErrNum != CL_SUCCESS) + { + printf("Error in clCreateKernel, Line %u in file %s, cannot find kernel function %s !!!\n\n", __LINE__, __FILE__, kernelName); + if (pErrNum) + *pErrNum = localErrNum; + return 0; + } + + if (!prog && m_cpProgram) + { + clReleaseProgram(m_cpProgram); + } + printf("ready. \n"); + + + if (pErrNum) + *pErrNum = CL_SUCCESS; + return kernel; + +} diff --git a/Demos/SharedOpenCL/btOpenCLUtils.h b/Demos/SharedOpenCL/btOpenCLUtils.h new file mode 100644 index 0000000..e9f4228 --- /dev/null +++ b/Demos/SharedOpenCL/btOpenCLUtils.h @@ -0,0 +1,107 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2011 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//original author: Roman Ponomarev +//cleanup by Erwin Coumans + +#ifndef BT_OPENCL_UTILS_H +#define BT_OPENCL_UTILS_H + +#include "btOpenCLInclude.h" + + +#define BT_MAX_STRING_LENGTH 1024 + +struct btOpenCLDeviceInfo +{ + char m_deviceName[BT_MAX_STRING_LENGTH]; + char m_deviceVendor[BT_MAX_STRING_LENGTH]; + char m_driverVersion[BT_MAX_STRING_LENGTH]; + char m_deviceExtensions[BT_MAX_STRING_LENGTH]; + + cl_device_type m_deviceType; + cl_uint m_computeUnits; + size_t m_workitemDims; + size_t m_workItemSize[3]; + size_t m_image2dMaxWidth; + size_t m_image2dMaxHeight; + size_t m_image3dMaxWidth; + size_t m_image3dMaxHeight; + size_t m_image3dMaxDepth; + size_t m_workgroupSize; + cl_uint m_clockFrequency; + cl_ulong m_constantBufferSize; + cl_ulong m_localMemSize; + cl_ulong m_globalMemSize; + cl_bool m_errorCorrectionSupport; + cl_device_local_mem_type m_localMemType; + cl_uint m_maxReadImageArgs; + cl_uint m_maxWriteImageArgs; + + + + cl_uint m_addressBits; + cl_ulong m_maxMemAllocSize; + cl_command_queue_properties m_queueProperties; + cl_bool m_imageSupport; + cl_uint m_vecWidthChar; + cl_uint m_vecWidthShort; + cl_uint m_vecWidthInt; + cl_uint m_vecWidthLong; + cl_uint m_vecWidthFloat; + cl_uint m_vecWidthDouble; + +}; + +struct btOpenCLPlatformInfo +{ + char m_platformVendor[BT_MAX_STRING_LENGTH]; + char m_platformName[BT_MAX_STRING_LENGTH]; + char m_platformVersion[BT_MAX_STRING_LENGTH]; +}; + +class btOpenCLUtils +{ +public: + + /// CL Context optionally takes a GL context. This is a generic type because we don't really want this code + /// to have to understand GL types. It is a HGLRC in _WIN32 or a GLXContext otherwise. + static cl_context createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0, int preferredDeviceIndex = -1, int preferredPlatformIndex= - 1); + + static int getNumDevices(cl_context cxMainContext); + static cl_device_id getDevice(cl_context cxMainContext, int nr); + static void getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo& info); + static void printDeviceInfo(cl_device_id device); + + static cl_kernel compileCLKernelFromString( cl_context clContext,cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum=0, cl_program prog=0,const char* additionalMacros = "" ); + + //optional + static cl_program compileCLProgramFromString( cl_context clContext,cl_device_id device, const char* kernelSource, cl_int* pErrNum=0,const char* additionalMacros = ""); + ///compileCLProgramFromFile will attempt to save/load the binary precompiled program + static cl_program compileCLProgramFromFile( cl_context clContext,cl_device_id device, cl_int* pErrNum=0,const char* additionalMacros = "" , const char* srcFileNameForCaching=0); + + + //the following optional APIs provide access using specific platform information + static int getNumPlatforms(cl_int* pErrNum=0); + ///get the nr'th platform, where nr is in the range [0..getNumPlatforms) + static cl_platform_id getPlatform(int nr, cl_int* pErrNum=0); + static void getPlatformInfo(cl_platform_id platform, btOpenCLPlatformInfo& platformInfo); + static const char* getSdkVendorName(); + static cl_context createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0,int preferredDeviceIndex = -1, int preferredPlatformIndex= -1); +}; + + + +#endif // BT_OPENCL_UTILS_H diff --git a/Demos/SharedOpenCL/clew.c b/Demos/SharedOpenCL/clew.c new file mode 100644 index 0000000..cfc6ed0 --- /dev/null +++ b/Demos/SharedOpenCL/clew.c @@ -0,0 +1,313 @@ +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2009 Organic Vectory B.V. +// Written by George van Venrooij +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file license.txt) +////////////////////////////////////////////////////////////////////////// +#ifndef USE_MINICL +#include "clew.h" + +//! \file clew.c +//! \brief OpenCL run-time loader source + +#ifndef CLCC_GENERATE_DOCUMENTATION +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #define VC_EXTRALEAN + #define NOMINMAX + #include + + typedef HMODULE CLCC_DYNLIB_HANDLE; + + #define CLCC_DYNLIB_OPEN LoadLibrary + #define CLCC_DYNLIB_CLOSE FreeLibrary + #define CLCC_DYNLIB_IMPORT GetProcAddress +#else + #include + + typedef void* CLCC_DYNLIB_HANDLE; + + #define CLCC_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL) + #define CLCC_DYNLIB_CLOSE dlclose + #define CLCC_DYNLIB_IMPORT dlsym +#endif +#else + //typedef implementation_defined CLCC_DYNLIB_HANDLE; + //#define CLCC_DYNLIB_OPEN(path) implementation_defined + //#define CLCC_DYNLIB_CLOSE implementation_defined + //#define CLCC_DYNLIB_IMPORT implementation_defined +#endif + +#include + +//! \brief module handle +static CLCC_DYNLIB_HANDLE module = NULL; + +// Variables holding function entry points +#ifndef CLCC_GENERATE_DOCUMENTATION +PFNCLGETPLATFORMIDS __clewGetPlatformIDs = NULL; +PFNCLGETPLATFORMINFO __clewGetPlatformInfo = NULL; +PFNCLGETDEVICEIDS __clewGetDeviceIDs = NULL; +PFNCLGETDEVICEINFO __clewGetDeviceInfo = NULL; +PFNCLCREATECONTEXT __clewCreateContext = NULL; +PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType = NULL; +PFNCLRETAINCONTEXT __clewRetainContext = NULL; +PFNCLRELEASECONTEXT __clewReleaseContext = NULL; +PFNCLGETCONTEXTINFO __clewGetContextInfo = NULL; +PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue = NULL; +PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue = NULL; +PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue = NULL; +PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo = NULL; +PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty = NULL; +PFNCLCREATEBUFFER __clewCreateBuffer = NULL; +PFNCLCREATEIMAGE2D __clewCreateImage2D = NULL; +PFNCLCREATEIMAGE3D __clewCreateImage3D = NULL; +PFNCLRETAINMEMOBJECT __clewRetainMemObject = NULL; +PFNCLRELEASEMEMOBJECT __clewReleaseMemObject = NULL; +PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats = NULL; +PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo = NULL; +PFNCLGETIMAGEINFO __clewGetImageInfo = NULL; +PFNCLCREATESAMPLER __clewCreateSampler = NULL; +PFNCLRETAINSAMPLER __clewRetainSampler = NULL; +PFNCLRELEASESAMPLER __clewReleaseSampler = NULL; +PFNCLGETSAMPLERINFO __clewGetSamplerInfo = NULL; +PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource = NULL; +PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary = NULL; +PFNCLRETAINPROGRAM __clewRetainProgram = NULL; +PFNCLRELEASEPROGRAM __clewReleaseProgram = NULL; +PFNCLBUILDPROGRAM __clewBuildProgram = NULL; +PFNCLUNLOADCOMPILER __clewUnloadCompiler = NULL; +PFNCLGETPROGRAMINFO __clewGetProgramInfo = NULL; +PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo = NULL; +PFNCLCREATEKERNEL __clewCreateKernel = NULL; +PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram = NULL; +PFNCLRETAINKERNEL __clewRetainKernel = NULL; +PFNCLRELEASEKERNEL __clewReleaseKernel = NULL; +PFNCLSETKERNELARG __clewSetKernelArg = NULL; +PFNCLGETKERNELINFO __clewGetKernelInfo = NULL; +PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo = NULL; +PFNCLWAITFOREVENTS __clewWaitForEvents = NULL; +PFNCLGETEVENTINFO __clewGetEventInfo = NULL; +PFNCLRETAINEVENT __clewRetainEvent = NULL; +PFNCLRELEASEEVENT __clewReleaseEvent = NULL; +PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo = NULL; +PFNCLFLUSH __clewFlush = NULL; +PFNCLFINISH __clewFinish = NULL; +PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer = NULL; +PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer = NULL; +PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer = NULL; +PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage = NULL; +PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage = NULL; +PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage = NULL; +PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer = NULL; +PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage = NULL; +PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer = NULL; +PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage = NULL; +PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject = NULL; +PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel = NULL; +PFNCLENQUEUETASK __clewEnqueueTask = NULL; +PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel = NULL; +PFNCLENQUEUEMARKER __clewEnqueueMarker = NULL; +PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents = NULL; +PFNCLENQUEUEBARRIER __clewEnqueueBarrier = NULL; +PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress = NULL; +#endif // CLCC_GENERATE_DOCUMENTATION + + +//! \brief Unloads OpenCL dynamic library, should not be called directly +static void clewExit(void) +{ + if (module != NULL) + { + // Ignore errors + CLCC_DYNLIB_CLOSE(module); + module = NULL; + } +} + +//! \param path path to dynamic library to load +//! \return CLEW_ERROR_OPEN_FAILED if the library could not be opened +//! CLEW_ERROR_ATEXIT_FAILED if atexit(clewExit) failed +//! CLEW_SUCCESS when the library was succesfully loaded +int clewInit(const char* path) +{ + int error = 0; + + // Check if already initialized + if (module != NULL) + { + return CLEW_SUCCESS; + } + + // Load library + module = CLCC_DYNLIB_OPEN(path); + + // Check for errors + if (module == NULL) + { + return CLEW_ERROR_OPEN_FAILED; + } + + // Set unloading + error = atexit(clewExit); + + if (error) + { + // Failure queing atexit, shutdown with error + CLCC_DYNLIB_CLOSE(module); + module = NULL; + + return CLEW_ERROR_ATEXIT_FAILED; + } + + // Determine function entry-points + __clewGetPlatformIDs = (PFNCLGETPLATFORMIDS )CLCC_DYNLIB_IMPORT(module, "clGetPlatformIDs"); + __clewGetPlatformInfo = (PFNCLGETPLATFORMINFO )CLCC_DYNLIB_IMPORT(module, "clGetPlatformInfo"); + __clewGetDeviceIDs = (PFNCLGETDEVICEIDS )CLCC_DYNLIB_IMPORT(module, "clGetDeviceIDs"); + __clewGetDeviceInfo = (PFNCLGETDEVICEINFO )CLCC_DYNLIB_IMPORT(module, "clGetDeviceInfo"); + __clewCreateContext = (PFNCLCREATECONTEXT )CLCC_DYNLIB_IMPORT(module, "clCreateContext"); + __clewCreateContextFromType = (PFNCLCREATECONTEXTFROMTYPE )CLCC_DYNLIB_IMPORT(module, "clCreateContextFromType"); + __clewRetainContext = (PFNCLRETAINCONTEXT )CLCC_DYNLIB_IMPORT(module, "clRetainContext"); + __clewReleaseContext = (PFNCLRELEASECONTEXT )CLCC_DYNLIB_IMPORT(module, "clReleaseContext"); + __clewGetContextInfo = (PFNCLGETCONTEXTINFO )CLCC_DYNLIB_IMPORT(module, "clGetContextInfo"); + __clewCreateCommandQueue = (PFNCLCREATECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clCreateCommandQueue"); + __clewRetainCommandQueue = (PFNCLRETAINCOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clRetainCommandQueue"); + __clewReleaseCommandQueue = (PFNCLRELEASECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clReleaseCommandQueue"); + __clewGetCommandQueueInfo = (PFNCLGETCOMMANDQUEUEINFO )CLCC_DYNLIB_IMPORT(module, "clGetCommandQueueInfo"); + __clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY )CLCC_DYNLIB_IMPORT(module, "clSetCommandQueueProperty"); + __clewCreateBuffer = (PFNCLCREATEBUFFER )CLCC_DYNLIB_IMPORT(module, "clCreateBuffer"); + __clewCreateImage2D = (PFNCLCREATEIMAGE2D )CLCC_DYNLIB_IMPORT(module, "clCreateImage2D"); + __clewCreateImage3D = (PFNCLCREATEIMAGE3D )CLCC_DYNLIB_IMPORT(module, "clCreateImage3D"); + __clewRetainMemObject = (PFNCLRETAINMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clRetainMemObject"); + __clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clReleaseMemObject"); + __clewGetSupportedImageFormats = (PFNCLGETSUPPORTEDIMAGEFORMATS )CLCC_DYNLIB_IMPORT(module, "clGetSupportedImageFormats"); + __clewGetMemObjectInfo = (PFNCLGETMEMOBJECTINFO )CLCC_DYNLIB_IMPORT(module, "clGetMemObjectInfo"); + __clewGetImageInfo = (PFNCLGETIMAGEINFO )CLCC_DYNLIB_IMPORT(module, "clGetImageInfo"); + __clewCreateSampler = (PFNCLCREATESAMPLER )CLCC_DYNLIB_IMPORT(module, "clCreateSampler"); + __clewRetainSampler = (PFNCLRETAINSAMPLER )CLCC_DYNLIB_IMPORT(module, "clRetainSampler"); + __clewReleaseSampler = (PFNCLRELEASESAMPLER )CLCC_DYNLIB_IMPORT(module, "clReleaseSampler"); + __clewGetSamplerInfo = (PFNCLGETSAMPLERINFO )CLCC_DYNLIB_IMPORT(module, "clGetSamplerInfo"); + __clewCreateProgramWithSource = (PFNCLCREATEPROGRAMWITHSOURCE )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithSource"); + __clewCreateProgramWithBinary = (PFNCLCREATEPROGRAMWITHBINARY )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithBinary"); + __clewRetainProgram = (PFNCLRETAINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clRetainProgram"); + __clewReleaseProgram = (PFNCLRELEASEPROGRAM )CLCC_DYNLIB_IMPORT(module, "clReleaseProgram"); + __clewBuildProgram = (PFNCLBUILDPROGRAM )CLCC_DYNLIB_IMPORT(module, "clBuildProgram"); + __clewUnloadCompiler = (PFNCLUNLOADCOMPILER )CLCC_DYNLIB_IMPORT(module, "clUnloadCompiler"); + __clewGetProgramInfo = (PFNCLGETPROGRAMINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramInfo"); + __clewGetProgramBuildInfo = (PFNCLGETPROGRAMBUILDINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramBuildInfo"); + __clewCreateKernel = (PFNCLCREATEKERNEL )CLCC_DYNLIB_IMPORT(module, "clCreateKernel"); + __clewCreateKernelsInProgram = (PFNCLCREATEKERNELSINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clCreateKernelsInProgram"); + __clewRetainKernel = (PFNCLRETAINKERNEL )CLCC_DYNLIB_IMPORT(module, "clRetainKernel"); + __clewReleaseKernel = (PFNCLRELEASEKERNEL )CLCC_DYNLIB_IMPORT(module, "clReleaseKernel"); + __clewSetKernelArg = (PFNCLSETKERNELARG )CLCC_DYNLIB_IMPORT(module, "clSetKernelArg"); + __clewGetKernelInfo = (PFNCLGETKERNELINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelInfo"); + __clewGetKernelWorkGroupInfo = (PFNCLGETKERNELWORKGROUPINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelWorkGroupInfo"); + __clewWaitForEvents = (PFNCLWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clWaitForEvents"); + __clewGetEventInfo = (PFNCLGETEVENTINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventInfo"); + __clewRetainEvent = (PFNCLRETAINEVENT )CLCC_DYNLIB_IMPORT(module, "clRetainEvent"); + __clewReleaseEvent = (PFNCLRELEASEEVENT )CLCC_DYNLIB_IMPORT(module, "clReleaseEvent"); + __clewGetEventProfilingInfo = (PFNCLGETEVENTPROFILINGINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventProfilingInfo"); + __clewFlush = (PFNCLFLUSH )CLCC_DYNLIB_IMPORT(module, "clFlush"); + __clewFinish = (PFNCLFINISH )CLCC_DYNLIB_IMPORT(module, "clFinish"); + __clewEnqueueReadBuffer = (PFNCLENQUEUEREADBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadBuffer"); + __clewEnqueueWriteBuffer = (PFNCLENQUEUEWRITEBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteBuffer"); + __clewEnqueueCopyBuffer = (PFNCLENQUEUECOPYBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBuffer"); + __clewEnqueueReadImage = (PFNCLENQUEUEREADIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadImage"); + __clewEnqueueWriteImage = (PFNCLENQUEUEWRITEIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteImage"); + __clewEnqueueCopyImage = (PFNCLENQUEUECOPYIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImage"); + __clewEnqueueCopyImageToBuffer = (PFNCLENQUEUECOPYIMAGETOBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImageToBuffer"); + __clewEnqueueCopyBufferToImage = (PFNCLENQUEUECOPYBUFFERTOIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBufferToImage"); + __clewEnqueueMapBuffer = (PFNCLENQUEUEMAPBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapBuffer"); + __clewEnqueueMapImage = (PFNCLENQUEUEMAPIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapImage"); + __clewEnqueueUnmapMemObject = (PFNCLENQUEUEUNMAPMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clEnqueueUnmapMemObject"); + __clewEnqueueNDRangeKernel = (PFNCLENQUEUENDRANGEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNDRangeKernel"); + __clewEnqueueTask = (PFNCLENQUEUETASK )CLCC_DYNLIB_IMPORT(module, "clEnqueueTask"); + __clewEnqueueNativeKernel = (PFNCLENQUEUENATIVEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNativeKernel"); + __clewEnqueueMarker = (PFNCLENQUEUEMARKER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMarker"); + __clewEnqueueWaitForEvents = (PFNCLENQUEUEWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clEnqueueWaitForEvents"); + __clewEnqueueBarrier = (PFNCLENQUEUEBARRIER )CLCC_DYNLIB_IMPORT(module, "clEnqueueBarrier"); + __clewGetExtensionFunctionAddress = (PFNCLGETEXTENSIONFUNCTIONADDRESS )CLCC_DYNLIB_IMPORT(module, "clGetExtensionFunctionAddress"); + + return CLEW_SUCCESS; +} + +//! \param error CL error code +//! \return a string representation of the error code +const char* clewErrorString(cl_int error) +{ + static const char* strings[] = + { + // Error Codes + "CL_SUCCESS" // 0 + , "CL_DEVICE_NOT_FOUND" // -1 + , "CL_DEVICE_NOT_AVAILABLE" // -2 + , "CL_COMPILER_NOT_AVAILABLE" // -3 + , "CL_MEM_OBJECT_ALLOCATION_FAILURE" // -4 + , "CL_OUT_OF_RESOURCES" // -5 + , "CL_OUT_OF_HOST_MEMORY" // -6 + , "CL_PROFILING_INFO_NOT_AVAILABLE" // -7 + , "CL_MEM_COPY_OVERLAP" // -8 + , "CL_IMAGE_FORMAT_MISMATCH" // -9 + , "CL_IMAGE_FORMAT_NOT_SUPPORTED" // -10 + , "CL_BUILD_PROGRAM_FAILURE" // -11 + , "CL_MAP_FAILURE" // -12 + + , "" // -13 + , "" // -14 + , "" // -15 + , "" // -16 + , "" // -17 + , "" // -18 + , "" // -19 + + , "" // -20 + , "" // -21 + , "" // -22 + , "" // -23 + , "" // -24 + , "" // -25 + , "" // -26 + , "" // -27 + , "" // -28 + , "" // -29 + + , "CL_INVALID_VALUE" // -30 + , "CL_INVALID_DEVICE_TYPE" // -31 + , "CL_INVALID_PLATFORM" // -32 + , "CL_INVALID_DEVICE" // -33 + , "CL_INVALID_CONTEXT" // -34 + , "CL_INVALID_QUEUE_PROPERTIES" // -35 + , "CL_INVALID_COMMAND_QUEUE" // -36 + , "CL_INVALID_HOST_PTR" // -37 + , "CL_INVALID_MEM_OBJECT" // -38 + , "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" // -39 + , "CL_INVALID_IMAGE_SIZE" // -40 + , "CL_INVALID_SAMPLER" // -41 + , "CL_INVALID_BINARY" // -42 + , "CL_INVALID_BUILD_OPTIONS" // -43 + , "CL_INVALID_PROGRAM" // -44 + , "CL_INVALID_PROGRAM_EXECUTABLE" // -45 + , "CL_INVALID_KERNEL_NAME" // -46 + , "CL_INVALID_KERNEL_DEFINITION" // -47 + , "CL_INVALID_KERNEL" // -48 + , "CL_INVALID_ARG_INDEX" // -49 + , "CL_INVALID_ARG_VALUE" // -50 + , "CL_INVALID_ARG_SIZE" // -51 + , "CL_INVALID_KERNEL_ARGS" // -52 + , "CL_INVALID_WORK_DIMENSION" // -53 + , "CL_INVALID_WORK_GROUP_SIZE" // -54 + , "CL_INVALID_WORK_ITEM_SIZE" // -55 + , "CL_INVALID_GLOBAL_OFFSET" // -56 + , "CL_INVALID_EVENT_WAIT_LIST" // -57 + , "CL_INVALID_EVENT" // -58 + , "CL_INVALID_OPERATION" // -59 + , "CL_INVALID_GL_OBJECT" // -60 + , "CL_INVALID_BUFFER_SIZE" // -61 + , "CL_INVALID_MIP_LEVEL" // -62 + , "CL_INVALID_GLOBAL_WORK_SIZE" // -63 + }; + + return strings[-error]; +} +#endif diff --git a/Demos/SharedOpenCL/clew.h b/Demos/SharedOpenCL/clew.h new file mode 100644 index 0000000..27198ae --- /dev/null +++ b/Demos/SharedOpenCL/clew.h @@ -0,0 +1,1316 @@ +#ifndef CLCC_CLEW_HPP_INCLUDED +#define CLCC_CLEW_HPP_INCLUDED +#ifndef USE_MINICL +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2009 Organic Vectory B.V. +// Written by George van Venrooij +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file license.txt) +////////////////////////////////////////////////////////////////////////// + +//! \file clew.h +//! \brief OpenCL run-time loader header +//! +//! This file contains a copy of the contents of CL.H and CL_PLATFORM.H from the +//! official OpenCL spec. The purpose of this code is to load the OpenCL dynamic +//! library at run-time and thus allow the executable to function on many +//! platforms regardless of the vendor of the OpenCL driver actually installed. +//! Some of the techniques used here were inspired by work done in the GLEW +//! library (http://glew.sourceforge.net/) + +// Run-time dynamic linking functionality based on concepts used in GLEW +#ifdef __OPENCL_CL_H +#error cl.h included before clew.h +#endif + +#ifdef __OPENCL_CL_PLATFORM_H +#error cl_platform.h included before clew.h +#endif + +#ifndef CLCC_GENERATE_DOCUMENTATION +// Prevent cl.h inclusion +#define __OPENCL_CL_H +// Prevent cl_platform.h inclusion +#define __CL_PLATFORM_H +#endif // CLCC_GENERATE_DOCUMENTATION + +/******************************************************************************* +* Copyright (c) 2008-2009 The Khronos Group Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and/or associated documentation files (the +* "Materials"), to deal in the Materials without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Materials, and to +* permit persons to whom the Materials are furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Materials. +* +* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +******************************************************************************/ +#ifdef __APPLE__ +/* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CLCC_GENERATE_DOCUMENTATION + +#if defined(_WIN32) +#define CL_API_ENTRY +#define CL_API_CALL __stdcall +#else +#define CL_API_ENTRY +#define CL_API_CALL +#endif + +#if defined(__APPLE__) +#define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) +#else +#define CL_API_SUFFIX__VERSION_1_0 +#define CL_EXTENSION_WEAK_LINK +#endif + +#if defined(_WIN32) && defined(_MSC_VER) + +/* scalar types */ +typedef signed __int8 cl_char; +typedef unsigned __int8 cl_uchar; +typedef signed __int16 cl_short; +typedef unsigned __int16 cl_ushort; +typedef signed __int32 cl_int; +typedef unsigned __int32 cl_uint; +typedef signed __int64 cl_long; +typedef unsigned __int64 cl_ulong; + +typedef unsigned __int16 cl_half; +typedef float cl_float; +typedef double cl_double; + + +/* +* Vector types +* +* Note: OpenCL requires that all types be naturally aligned. +* This means that vector types must be naturally aligned. +* For example, a vector of four floats must be aligned to +* a 16 byte boundary (calculated as 4 * the natural 4-byte +* alignment of the float). The alignment qualifiers here +* will only function properly if your compiler supports them +* and if you don't actively work to defeat them. For example, +* in order for a cl_float4 to be 16 byte aligned in a struct, +* the start of the struct must itself be 16-byte aligned. +* +* Maintaining proper alignment is the user's responsibility. +*/ +typedef signed __int8 cl_char2[2]; +typedef signed __int8 cl_char4[4]; +typedef signed __int8 cl_char8[8]; +typedef signed __int8 cl_char16[16]; +typedef unsigned __int8 cl_uchar2[2]; +typedef unsigned __int8 cl_uchar4[4]; +typedef unsigned __int8 cl_uchar8[8]; +typedef unsigned __int8 cl_uchar16[16]; + +typedef signed __int16 cl_short2[2]; +typedef signed __int16 cl_short4[4]; +typedef signed __int16 cl_short8[8]; +typedef signed __int16 cl_short16[16]; +typedef unsigned __int16 cl_ushort2[2]; +typedef unsigned __int16 cl_ushort4[4]; +typedef unsigned __int16 cl_ushort8[8]; +typedef unsigned __int16 cl_ushort16[16]; + +typedef signed __int32 cl_int2[2]; +typedef signed __int32 cl_int4[4]; +typedef signed __int32 cl_int8[8]; +typedef signed __int32 cl_int16[16]; +typedef unsigned __int32 cl_uint2[2]; +typedef unsigned __int32 cl_uint4[4]; +typedef unsigned __int32 cl_uint8[8]; +typedef unsigned __int32 cl_uint16[16]; + +typedef signed __int64 cl_long2[2]; +typedef signed __int64 cl_long4[4]; +typedef signed __int64 cl_long8[8]; +typedef signed __int64 cl_long16[16]; +typedef unsigned __int64 cl_ulong2[2]; +typedef unsigned __int64 cl_ulong4[4]; +typedef unsigned __int64 cl_ulong8[8]; +typedef unsigned __int64 cl_ulong16[16]; + +typedef float cl_float2[2]; +typedef float cl_float4[4]; +typedef float cl_float8[8]; +typedef float cl_float16[16]; + +typedef double cl_double2[2]; +typedef double cl_double4[4]; +typedef double cl_double8[8]; +typedef double cl_double16[16]; +/* There are no vector types for half */ + +#else + +#include + +/* scalar types */ +typedef int8_t cl_char; +typedef uint8_t cl_uchar; +typedef int16_t cl_short __attribute__((aligned(2))); +typedef uint16_t cl_ushort __attribute__((aligned(2))); +typedef int32_t cl_int __attribute__((aligned(4))); +typedef uint32_t cl_uint __attribute__((aligned(4))); +typedef int64_t cl_long __attribute__((aligned(8))); +typedef uint64_t cl_ulong __attribute__((aligned(8))); + +typedef uint16_t cl_half __attribute__((aligned(2))); +typedef float cl_float __attribute__((aligned(4))); +typedef double cl_double __attribute__((aligned(8))); + +/* +* Vector types +* +* Note: OpenCL requires that all types be naturally aligned. +* This means that vector types must be naturally aligned. +* For example, a vector of four floats must be aligned to +* a 16 byte boundary (calculated as 4 * the natural 4-byte +* alignment of the float). The alignment qualifiers here +* will only function properly if your compiler supports them +* and if you don't actively work to defeat them. For example, +* in order for a cl_float4 to be 16 byte aligned in a struct, +* the start of the struct must itself be 16-byte aligned. +* +* Maintaining proper alignment is the user's responsibility. +*/ +typedef int8_t cl_char2[2] __attribute__((aligned(2))); +typedef int8_t cl_char4[4] __attribute__((aligned(4))); +typedef int8_t cl_char8[8] __attribute__((aligned(8))); +typedef int8_t cl_char16[16] __attribute__((aligned(16))); +typedef uint8_t cl_uchar2[2] __attribute__((aligned(2))); +typedef uint8_t cl_uchar4[4] __attribute__((aligned(4))); +typedef uint8_t cl_uchar8[8] __attribute__((aligned(8))); +typedef uint8_t cl_uchar16[16] __attribute__((aligned(16))); + +typedef int16_t cl_short2[2] __attribute__((aligned(4))); +typedef int16_t cl_short4[4] __attribute__((aligned(8))); +typedef int16_t cl_short8[8] __attribute__((aligned(16))); +typedef int16_t cl_short16[16] __attribute__((aligned(32))); +typedef uint16_t cl_ushort2[2] __attribute__((aligned(4))); +typedef uint16_t cl_ushort4[4] __attribute__((aligned(8))); +typedef uint16_t cl_ushort8[8] __attribute__((aligned(16))); +typedef uint16_t cl_ushort16[16] __attribute__((aligned(32))); + +typedef int32_t cl_int2[2] __attribute__((aligned(8))); +typedef int32_t cl_int4[4] __attribute__((aligned(16))); +typedef int32_t cl_int8[8] __attribute__((aligned(32))); +typedef int32_t cl_int16[16] __attribute__((aligned(64))); +typedef uint32_t cl_uint2[2] __attribute__((aligned(8))); +typedef uint32_t cl_uint4[4] __attribute__((aligned(16))); +typedef uint32_t cl_uint8[8] __attribute__((aligned(32))); +typedef uint32_t cl_uint16[16] __attribute__((aligned(64))); + +typedef int64_t cl_long2[2] __attribute__((aligned(16))); +typedef int64_t cl_long4[4] __attribute__((aligned(32))); +typedef int64_t cl_long8[8] __attribute__((aligned(64))); +typedef int64_t cl_long16[16] __attribute__((aligned(128))); +typedef uint64_t cl_ulong2[2] __attribute__((aligned(16))); +typedef uint64_t cl_ulong4[4] __attribute__((aligned(32))); +typedef uint64_t cl_ulong8[8] __attribute__((aligned(64))); +typedef uint64_t cl_ulong16[16] __attribute__((aligned(128))); + +typedef float cl_float2[2] __attribute__((aligned(8))); +typedef float cl_float4[4] __attribute__((aligned(16))); +typedef float cl_float8[8] __attribute__((aligned(32))); +typedef float cl_float16[16] __attribute__((aligned(64))); + +typedef double cl_double2[2] __attribute__((aligned(16))); +typedef double cl_double4[4] __attribute__((aligned(32))); +typedef double cl_double8[8] __attribute__((aligned(64))); +typedef double cl_double16[16] __attribute__((aligned(128))); + +/* There are no vector types for half */ + +#endif + +/******************************************************************************/ + +// Macro names and corresponding values defined by OpenCL + +#define CL_CHAR_BIT 8 +#define CL_SCHAR_MAX 127 +#define CL_SCHAR_MIN (-127-1) +#define CL_CHAR_MAX CL_SCHAR_MAX +#define CL_CHAR_MIN CL_SCHAR_MIN +#define CL_UCHAR_MAX 255 +#define CL_SHRT_MAX 32767 +#define CL_SHRT_MIN (-32767-1) +#define CL_USHRT_MAX 65535 +#define CL_INT_MAX 2147483647 +#define CL_INT_MIN (-2147483647-1) +#define CL_UINT_MAX 0xffffffffU +#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) +#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) +#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) + +#define CL_FLT_DIG 6 +#define CL_FLT_MANT_DIG 24 +#define CL_FLT_MAX_10_EXP +38 +#define CL_FLT_MAX_EXP +128 +#define CL_FLT_MIN_10_EXP -37 +#define CL_FLT_MIN_EXP -125 +#define CL_FLT_RADIX 2 +#if defined(_MSC_VER) +// MSVC doesn't understand hex floats +#define CL_FLT_MAX 3.402823466e+38F +#define CL_FLT_MIN 1.175494351e-38F +#define CL_FLT_EPSILON 1.192092896e-07F +#else +#define CL_FLT_MAX 0x1.fffffep127f +#define CL_FLT_MIN 0x1.0p-126f +#define CL_FLT_EPSILON 0x1.0p-23f +#endif + +#define CL_DBL_DIG 15 +#define CL_DBL_MANT_DIG 53 +#define CL_DBL_MAX_10_EXP +308 +#define CL_DBL_MAX_EXP +1024 +#define CL_DBL_MIN_10_EXP -307 +#define CL_DBL_MIN_EXP -1021 +#define CL_DBL_RADIX 2 +#if defined(_MSC_VER) +// MSVC doesn't understand hex floats +#define CL_DBL_MAX 1.7976931348623158e+308 +#define CL_DBL_MIN 2.2250738585072014e-308 +#define CL_DBL_EPSILON 2.2204460492503131e-016 +#else +#define CL_DBL_MAX 0x1.fffffffffffffp1023 +#define CL_DBL_MIN 0x1.0p-1022 +#define CL_DBL_EPSILON 0x1.0p-52 +#endif + +#include + + +// CL.h contents +/******************************************************************************/ + +typedef struct _cl_platform_id * cl_platform_id; +typedef struct _cl_device_id * cl_device_id; +typedef struct _cl_context * cl_context; +typedef struct _cl_command_queue * cl_command_queue; +typedef struct _cl_mem * cl_mem; +typedef struct _cl_program * cl_program; +typedef struct _cl_kernel * cl_kernel; +typedef struct _cl_event * cl_event; +typedef struct _cl_sampler * cl_sampler; + +typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */ +typedef cl_ulong cl_bitfield; +typedef cl_bitfield cl_device_type; +typedef cl_uint cl_platform_info; +typedef cl_uint cl_device_info; +typedef cl_bitfield cl_device_address_info; +typedef cl_bitfield cl_device_fp_config; +typedef cl_uint cl_device_mem_cache_type; +typedef cl_uint cl_device_local_mem_type; +typedef cl_bitfield cl_device_exec_capabilities; +typedef cl_bitfield cl_command_queue_properties; + +typedef intptr_t cl_context_properties; +typedef cl_uint cl_context_info; +typedef cl_uint cl_command_queue_info; +typedef cl_uint cl_channel_order; +typedef cl_uint cl_channel_type; +typedef cl_bitfield cl_mem_flags; +typedef cl_uint cl_mem_object_type; +typedef cl_uint cl_mem_info; +typedef cl_uint cl_image_info; +typedef cl_uint cl_addressing_mode; +typedef cl_uint cl_filter_mode; +typedef cl_uint cl_sampler_info; +typedef cl_bitfield cl_map_flags; +typedef cl_uint cl_program_info; +typedef cl_uint cl_program_build_info; +typedef cl_int cl_build_status; +typedef cl_uint cl_kernel_info; +typedef cl_uint cl_kernel_work_group_info; +typedef cl_uint cl_event_info; +typedef cl_uint cl_command_type; +typedef cl_uint cl_profiling_info; + +typedef struct _cl_image_format { + cl_channel_order image_channel_order; + cl_channel_type image_channel_data_type; +} cl_image_format; + + + +/******************************************************************************/ + +// Error Codes +#define CL_SUCCESS 0 +#define CL_DEVICE_NOT_FOUND -1 +#define CL_DEVICE_NOT_AVAILABLE -2 +#define CL_COMPILER_NOT_AVAILABLE -3 +#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4 +#define CL_OUT_OF_RESOURCES -5 +#define CL_OUT_OF_HOST_MEMORY -6 +#define CL_PROFILING_INFO_NOT_AVAILABLE -7 +#define CL_MEM_COPY_OVERLAP -8 +#define CL_IMAGE_FORMAT_MISMATCH -9 +#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 +#define CL_BUILD_PROGRAM_FAILURE -11 +#define CL_MAP_FAILURE -12 + +#define CL_INVALID_VALUE -30 +#define CL_INVALID_DEVICE_TYPE -31 +#define CL_INVALID_PLATFORM -32 +#define CL_INVALID_DEVICE -33 +#define CL_INVALID_CONTEXT -34 +#define CL_INVALID_QUEUE_PROPERTIES -35 +#define CL_INVALID_COMMAND_QUEUE -36 +#define CL_INVALID_HOST_PTR -37 +#define CL_INVALID_MEM_OBJECT -38 +#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39 +#define CL_INVALID_IMAGE_SIZE -40 +#define CL_INVALID_SAMPLER -41 +#define CL_INVALID_BINARY -42 +#define CL_INVALID_BUILD_OPTIONS -43 +#define CL_INVALID_PROGRAM -44 +#define CL_INVALID_PROGRAM_EXECUTABLE -45 +#define CL_INVALID_KERNEL_NAME -46 +#define CL_INVALID_KERNEL_DEFINITION -47 +#define CL_INVALID_KERNEL -48 +#define CL_INVALID_ARG_INDEX -49 +#define CL_INVALID_ARG_VALUE -50 +#define CL_INVALID_ARG_SIZE -51 +#define CL_INVALID_KERNEL_ARGS -52 +#define CL_INVALID_WORK_DIMENSION -53 +#define CL_INVALID_WORK_GROUP_SIZE -54 +#define CL_INVALID_WORK_ITEM_SIZE -55 +#define CL_INVALID_GLOBAL_OFFSET -56 +#define CL_INVALID_EVENT_WAIT_LIST -57 +#define CL_INVALID_EVENT -58 +#define CL_INVALID_OPERATION -59 +#define CL_INVALID_GL_OBJECT -60 +#define CL_INVALID_BUFFER_SIZE -61 +#define CL_INVALID_MIP_LEVEL -62 +#define CL_INVALID_GLOBAL_WORK_SIZE -63 + +// OpenCL Version +#define CL_VERSION_1_0 1 + +// cl_bool +#define CL_FALSE 0 +#define CL_TRUE 1 + +// cl_platform_info +#define CL_PLATFORM_PROFILE 0x0900 +#define CL_PLATFORM_VERSION 0x0901 +#define CL_PLATFORM_NAME 0x0902 +#define CL_PLATFORM_VENDOR 0x0903 +#define CL_PLATFORM_EXTENSIONS 0x0904 + +// cl_device_type - bitfield +#define CL_DEVICE_TYPE_DEFAULT (1 << 0) +#define CL_DEVICE_TYPE_CPU (1 << 1) +#define CL_DEVICE_TYPE_GPU (1 << 2) +#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) +#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF + +// cl_device_info +#define CL_DEVICE_TYPE 0x1000 +#define CL_DEVICE_VENDOR_ID 0x1001 +#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002 +#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003 +#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004 +#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B +#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C +#define CL_DEVICE_ADDRESS_BITS 0x100D +#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E +#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F +#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010 +#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011 +#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012 +#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013 +#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014 +#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015 +#define CL_DEVICE_IMAGE_SUPPORT 0x1016 +#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017 +#define CL_DEVICE_MAX_SAMPLERS 0x1018 +#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019 +#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A +#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B +#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C +#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D +#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E +#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F +#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020 +#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021 +#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022 +#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023 +#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024 +#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025 +#define CL_DEVICE_ENDIAN_LITTLE 0x1026 +#define CL_DEVICE_AVAILABLE 0x1027 +#define CL_DEVICE_COMPILER_AVAILABLE 0x1028 +#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029 +#define CL_DEVICE_QUEUE_PROPERTIES 0x102A +#define CL_DEVICE_NAME 0x102B +#define CL_DEVICE_VENDOR 0x102C +#define CL_DRIVER_VERSION 0x102D +#define CL_DEVICE_PROFILE 0x102E +#define CL_DEVICE_VERSION 0x102F +#define CL_DEVICE_EXTENSIONS 0x1030 +#define CL_DEVICE_PLATFORM 0x1031 + +// cl_device_fp_config - bitfield +#define CL_FP_DENORM (1 << 0) +#define CL_FP_INF_NAN (1 << 1) +#define CL_FP_ROUND_TO_NEAREST (1 << 2) +#define CL_FP_ROUND_TO_ZERO (1 << 3) +#define CL_FP_ROUND_TO_INF (1 << 4) +#define CL_FP_FMA (1 << 5) + +// cl_device_mem_cache_type +#define CL_NONE 0x0 +#define CL_READ_ONLY_CACHE 0x1 +#define CL_READ_WRITE_CACHE 0x2 + +// cl_device_local_mem_type +#define CL_LOCAL 0x1 +#define CL_GLOBAL 0x2 + +// cl_device_exec_capabilities - bitfield +#define CL_EXEC_KERNEL (1 << 0) +#define CL_EXEC_NATIVE_KERNEL (1 << 1) + +// cl_command_queue_properties - bitfield +#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0) +#define CL_QUEUE_PROFILING_ENABLE (1 << 1) + +// cl_context_info +#define CL_CONTEXT_REFERENCE_COUNT 0x1080 +#define CL_CONTEXT_DEVICES 0x1081 +#define CL_CONTEXT_PROPERTIES 0x1082 + +// cl_context_properties +#define CL_CONTEXT_PLATFORM 0x1084 + +// cl_command_queue_info +#define CL_QUEUE_CONTEXT 0x1090 +#define CL_QUEUE_DEVICE 0x1091 +#define CL_QUEUE_REFERENCE_COUNT 0x1092 +#define CL_QUEUE_PROPERTIES 0x1093 + +// cl_mem_flags - bitfield +#define CL_MEM_READ_WRITE (1 << 0) +#define CL_MEM_WRITE_ONLY (1 << 1) +#define CL_MEM_READ_ONLY (1 << 2) +#define CL_MEM_USE_HOST_PTR (1 << 3) +#define CL_MEM_ALLOC_HOST_PTR (1 << 4) +#define CL_MEM_COPY_HOST_PTR (1 << 5) + +// cl_channel_order +#define CL_R 0x10B0 +#define CL_A 0x10B1 +#define CL_RG 0x10B2 +#define CL_RA 0x10B3 +#define CL_RGB 0x10B4 +#define CL_RGBA 0x10B5 +#define CL_BGRA 0x10B6 +#define CL_ARGB 0x10B7 +#define CL_INTENSITY 0x10B8 +#define CL_LUMINANCE 0x10B9 + +// cl_channel_type +#define CL_SNORM_INT8 0x10D0 +#define CL_SNORM_INT16 0x10D1 +#define CL_UNORM_INT8 0x10D2 +#define CL_UNORM_INT16 0x10D3 +#define CL_UNORM_SHORT_565 0x10D4 +#define CL_UNORM_SHORT_555 0x10D5 +#define CL_UNORM_INT_101010 0x10D6 +#define CL_SIGNED_INT8 0x10D7 +#define CL_SIGNED_INT16 0x10D8 +#define CL_SIGNED_INT32 0x10D9 +#define CL_UNSIGNED_INT8 0x10DA +#define CL_UNSIGNED_INT16 0x10DB +#define CL_UNSIGNED_INT32 0x10DC +#define CL_HALF_FLOAT 0x10DD +#define CL_FLOAT 0x10DE + +// cl_mem_object_type +#define CL_MEM_OBJECT_BUFFER 0x10F0 +#define CL_MEM_OBJECT_IMAGE2D 0x10F1 +#define CL_MEM_OBJECT_IMAGE3D 0x10F2 + +// cl_mem_info +#define CL_MEM_TYPE 0x1100 +#define CL_MEM_FLAGS 0x1101 +#define CL_MEM_SIZE 0x1102 +#define CL_MEM_HOST_PTR 0x1103 +#define CL_MEM_MAP_COUNT 0x1104 +#define CL_MEM_REFERENCE_COUNT 0x1105 +#define CL_MEM_CONTEXT 0x1106 + +// cl_image_info +#define CL_IMAGE_FORMAT 0x1110 +#define CL_IMAGE_ELEMENT_SIZE 0x1111 +#define CL_IMAGE_ROW_PITCH 0x1112 +#define CL_IMAGE_SLICE_PITCH 0x1113 +#define CL_IMAGE_WIDTH 0x1114 +#define CL_IMAGE_HEIGHT 0x1115 +#define CL_IMAGE_DEPTH 0x1116 + +// cl_addressing_mode +#define CL_ADDRESS_NONE 0x1130 +#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 +#define CL_ADDRESS_CLAMP 0x1132 +#define CL_ADDRESS_REPEAT 0x1133 + +// cl_filter_mode +#define CL_FILTER_NEAREST 0x1140 +#define CL_FILTER_LINEAR 0x1141 + +// cl_sampler_info +#define CL_SAMPLER_REFERENCE_COUNT 0x1150 +#define CL_SAMPLER_CONTEXT 0x1151 +#define CL_SAMPLER_NORMALIZED_COORDS 0x1152 +#define CL_SAMPLER_ADDRESSING_MODE 0x1153 +#define CL_SAMPLER_FILTER_MODE 0x1154 + +// cl_map_flags - bitfield +#define CL_MAP_READ (1 << 0) +#define CL_MAP_WRITE (1 << 1) + +// cl_program_info +#define CL_PROGRAM_REFERENCE_COUNT 0x1160 +#define CL_PROGRAM_CONTEXT 0x1161 +#define CL_PROGRAM_NUM_DEVICES 0x1162 +#define CL_PROGRAM_DEVICES 0x1163 +#define CL_PROGRAM_SOURCE 0x1164 +#define CL_PROGRAM_BINARY_SIZES 0x1165 +#define CL_PROGRAM_BINARIES 0x1166 + +// cl_program_build_info +#define CL_PROGRAM_BUILD_STATUS 0x1181 +#define CL_PROGRAM_BUILD_OPTIONS 0x1182 +#define CL_PROGRAM_BUILD_LOG 0x1183 + +// cl_build_status +#define CL_BUILD_SUCCESS 0 +#define CL_BUILD_NONE -1 +#define CL_BUILD_ERROR -2 +#define CL_BUILD_IN_PROGRESS -3 + +// cl_kernel_info +#define CL_KERNEL_FUNCTION_NAME 0x1190 +#define CL_KERNEL_NUM_ARGS 0x1191 +#define CL_KERNEL_REFERENCE_COUNT 0x1192 +#define CL_KERNEL_CONTEXT 0x1193 +#define CL_KERNEL_PROGRAM 0x1194 + +// cl_kernel_work_group_info +#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 +#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 +#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 + +// cl_event_info +#define CL_EVENT_COMMAND_QUEUE 0x11D0 +#define CL_EVENT_COMMAND_TYPE 0x11D1 +#define CL_EVENT_REFERENCE_COUNT 0x11D2 +#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 + +// cl_command_type +#define CL_COMMAND_NDRANGE_KERNEL 0x11F0 +#define CL_COMMAND_TASK 0x11F1 +#define CL_COMMAND_NATIVE_KERNEL 0x11F2 +#define CL_COMMAND_READ_BUFFER 0x11F3 +#define CL_COMMAND_WRITE_BUFFER 0x11F4 +#define CL_COMMAND_COPY_BUFFER 0x11F5 +#define CL_COMMAND_READ_IMAGE 0x11F6 +#define CL_COMMAND_WRITE_IMAGE 0x11F7 +#define CL_COMMAND_COPY_IMAGE 0x11F8 +#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9 +#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA +#define CL_COMMAND_MAP_BUFFER 0x11FB +#define CL_COMMAND_MAP_IMAGE 0x11FC +#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD +#define CL_COMMAND_MARKER 0x11FE +#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF +#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 + +// command execution status +#define CL_COMPLETE 0x0 +#define CL_RUNNING 0x1 +#define CL_SUBMITTED 0x2 +#define CL_QUEUED 0x3 + +// cl_profiling_info +#define CL_PROFILING_COMMAND_QUEUED 0x1280 +#define CL_PROFILING_COMMAND_SUBMIT 0x1281 +#define CL_PROFILING_COMMAND_START 0x1282 +#define CL_PROFILING_COMMAND_END 0x1283 + +/********************************************************************************************************/ + +/********************************************************************************************************/ + +// Function signature typedef's + +// Platform API +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETPLATFORMIDS)(cl_uint /* num_entries */, + cl_platform_id * /* platforms */, + cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETPLATFORMINFO)(cl_platform_id /* platform */, + cl_platform_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Device APIs +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETDEVICEIDS)(cl_platform_id /* platform */, + cl_device_type /* device_type */, + cl_uint /* num_entries */, + cl_device_id * /* devices */, + cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETDEVICEINFO)(cl_device_id /* device */, + cl_device_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Context APIs +typedef CL_API_ENTRY cl_context (CL_API_CALL * +PFNCLCREATECONTEXT)(const cl_context_properties * /* properties */, + cl_uint /* num_devices */, + const cl_device_id * /* devices */, + void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */, + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_context (CL_API_CALL * +PFNCLCREATECONTEXTFROMTYPE)(const cl_context_properties * /* properties */, + cl_device_type /* device_type */, + void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */, + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRETAINCONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRELEASECONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETCONTEXTINFO)(cl_context /* context */, + cl_context_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Command Queue APIs +typedef CL_API_ENTRY cl_command_queue (CL_API_CALL * +PFNCLCREATECOMMANDQUEUE)(cl_context /* context */, + cl_device_id /* device */, + cl_command_queue_properties /* properties */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRETAINCOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRELEASECOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETCOMMANDQUEUEINFO)(cl_command_queue /* command_queue */, + cl_command_queue_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLSETCOMMANDQUEUEPROPERTY)(cl_command_queue /* command_queue */, + cl_command_queue_properties /* properties */, + cl_bool /* enable */, + cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0; + +// Memory Object APIs +typedef CL_API_ENTRY cl_mem (CL_API_CALL * +PFNCLCREATEBUFFER)(cl_context /* context */, + cl_mem_flags /* flags */, + size_t /* size */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL * +PFNCLCREATEIMAGE2D)(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_row_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL * +PFNCLCREATEIMAGE3D)(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_depth */, + size_t /* image_row_pitch */, + size_t /* image_slice_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRETAINMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRELEASEMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETSUPPORTEDIMAGEFORMATS)(cl_context /* context */, + cl_mem_flags /* flags */, + cl_mem_object_type /* image_type */, + cl_uint /* num_entries */, + cl_image_format * /* image_formats */, + cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETMEMOBJECTINFO)(cl_mem /* memobj */, + cl_mem_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETIMAGEINFO)(cl_mem /* image */, + cl_image_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Sampler APIs +typedef CL_API_ENTRY cl_sampler (CL_API_CALL * +PFNCLCREATESAMPLER)(cl_context /* context */, + cl_bool /* normalized_coords */, + cl_addressing_mode /* addressing_mode */, + cl_filter_mode /* filter_mode */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRETAINSAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRELEASESAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETSAMPLERINFO)(cl_sampler /* sampler */, + cl_sampler_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Program Object APIs +typedef CL_API_ENTRY cl_program (CL_API_CALL * +PFNCLCREATEPROGRAMWITHSOURCE)(cl_context /* context */, + cl_uint /* count */, + const char ** /* strings */, + const size_t * /* lengths */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_program (CL_API_CALL * +PFNCLCREATEPROGRAMWITHBINARY)(cl_context /* context */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const size_t * /* lengths */, + const unsigned char ** /* binaries */, + cl_int * /* binary_status */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRETAINPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRELEASEPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLBUILDPROGRAM)(cl_program /* program */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const char * /* options */, + void (*pfn_notify)(cl_program /* program */, void * /* user_data */), + void * /* user_data */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLUNLOADCOMPILER)(void) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETPROGRAMINFO)(cl_program /* program */, + cl_program_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETPROGRAMBUILDINFO)(cl_program /* program */, + cl_device_id /* device */, + cl_program_build_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Kernel Object APIs +typedef CL_API_ENTRY cl_kernel (CL_API_CALL * +PFNCLCREATEKERNEL)(cl_program /* program */, + const char * /* kernel_name */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLCREATEKERNELSINPROGRAM)(cl_program /* program */, + cl_uint /* num_kernels */, + cl_kernel * /* kernels */, + cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRETAINKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRELEASEKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLSETKERNELARG)(cl_kernel /* kernel */, + cl_uint /* arg_index */, + size_t /* arg_size */, + const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETKERNELINFO)(cl_kernel /* kernel */, + cl_kernel_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETKERNELWORKGROUPINFO)(cl_kernel /* kernel */, + cl_device_id /* device */, + cl_kernel_work_group_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Event Object APIs +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLWAITFOREVENTS)(cl_uint /* num_events */, + const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETEVENTINFO)(cl_event /* event */, + cl_event_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRETAINEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLRELEASEEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; + +// Profiling APIs +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLGETEVENTPROFILINGINFO)(cl_event /* event */, + cl_profiling_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Flush and Finish APIs +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLFLUSH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLFINISH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +// Enqueued Commands APIs +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEREADBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_read */, + size_t /* offset */, + size_t /* cb */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEWRITEBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_write */, + size_t /* offset */, + size_t /* cb */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUECOPYBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_buffer */, + size_t /* src_offset */, + size_t /* dst_offset */, + size_t /* cb */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEREADIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_read */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t /* row_pitch */, + size_t /* slice_pitch */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEWRITEIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_write */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t /* input_row_pitch */, + size_t /* input_slice_pitch */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUECOPYIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* src_image */, + cl_mem /* dst_image */, + const size_t * /* src_origin[3] */, + const size_t * /* dst_origin[3] */, + const size_t * /* region[3] */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUECOPYIMAGETOBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* src_image */, + cl_mem /* dst_buffer */, + const size_t * /* src_origin[3] */, + const size_t * /* region[3] */, + size_t /* dst_offset */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUECOPYBUFFERTOIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_image */, + size_t /* src_offset */, + const size_t * /* dst_origin[3] */, + const size_t * /* region[3] */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY void * (CL_API_CALL * +PFNCLENQUEUEMAPBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_map */, + cl_map_flags /* map_flags */, + size_t /* offset */, + size_t /* cb */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY void * (CL_API_CALL * +PFNCLENQUEUEMAPIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_map */, + cl_map_flags /* map_flags */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t * /* image_row_pitch */, + size_t * /* image_slice_pitch */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEUNMAPMEMOBJECT)(cl_command_queue /* command_queue */, + cl_mem /* memobj */, + void * /* mapped_ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUENDRANGEKERNEL)(cl_command_queue /* command_queue */, + cl_kernel /* kernel */, + cl_uint /* work_dim */, + const size_t * /* global_work_offset */, + const size_t * /* global_work_size */, + const size_t * /* local_work_size */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUETASK)(cl_command_queue /* command_queue */, + cl_kernel /* kernel */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUENATIVEKERNEL)(cl_command_queue /* command_queue */, + void (*user_func)(void *), + void * /* args */, + size_t /* cb_args */, + cl_uint /* num_mem_objects */, + const cl_mem * /* mem_list */, + const void ** /* args_mem_loc */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEMARKER)(cl_command_queue /* command_queue */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEWAITFOREVENTS)(cl_command_queue /* command_queue */, + cl_uint /* num_events */, + const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL * +PFNCLENQUEUEBARRIER)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +// Extension function access +// +// Returns the extension function address for the given function name, +// or NULL if a valid function can not be found. The client must +// check to make sure the address is not NULL, before using or +// calling the returned function address. +// +typedef CL_API_ENTRY void * (CL_API_CALL * PFNCLGETEXTENSIONFUNCTIONADDRESS)(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0; + + +#define CLEW_STATIC + +#ifdef CLEW_STATIC +# define CLEWAPI extern +#else +# ifdef CLEW_BUILD +# define CLEWAPI extern __declspec(dllexport) +# else +# define CLEWAPI extern __declspec(dllimport) +# endif +#endif + +#if defined(_WIN32) +#define CLEW_FUN_EXPORT extern +#else +#define CLEW_FUN_EXPORT CLEWAPI +#endif + +#define CLEW_GET_FUN(x) x + + +// Variables holding function entry points +CLEW_FUN_EXPORT PFNCLGETPLATFORMIDS __clewGetPlatformIDs ; +CLEW_FUN_EXPORT PFNCLGETPLATFORMINFO __clewGetPlatformInfo ; +CLEW_FUN_EXPORT PFNCLGETDEVICEIDS __clewGetDeviceIDs ; +CLEW_FUN_EXPORT PFNCLGETDEVICEINFO __clewGetDeviceInfo ; +CLEW_FUN_EXPORT PFNCLCREATECONTEXT __clewCreateContext ; +CLEW_FUN_EXPORT PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType ; +CLEW_FUN_EXPORT PFNCLRETAINCONTEXT __clewRetainContext ; +CLEW_FUN_EXPORT PFNCLRELEASECONTEXT __clewReleaseContext ; +CLEW_FUN_EXPORT PFNCLGETCONTEXTINFO __clewGetContextInfo ; +CLEW_FUN_EXPORT PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue ; +CLEW_FUN_EXPORT PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue ; +CLEW_FUN_EXPORT PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue ; +CLEW_FUN_EXPORT PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo ; +CLEW_FUN_EXPORT PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty ; +CLEW_FUN_EXPORT PFNCLCREATEBUFFER __clewCreateBuffer ; +CLEW_FUN_EXPORT PFNCLCREATEIMAGE2D __clewCreateImage2D ; +CLEW_FUN_EXPORT PFNCLCREATEIMAGE3D __clewCreateImage3D ; +CLEW_FUN_EXPORT PFNCLRETAINMEMOBJECT __clewRetainMemObject ; +CLEW_FUN_EXPORT PFNCLRELEASEMEMOBJECT __clewReleaseMemObject ; +CLEW_FUN_EXPORT PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats ; +CLEW_FUN_EXPORT PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo ; +CLEW_FUN_EXPORT PFNCLGETIMAGEINFO __clewGetImageInfo ; +CLEW_FUN_EXPORT PFNCLCREATESAMPLER __clewCreateSampler ; +CLEW_FUN_EXPORT PFNCLRETAINSAMPLER __clewRetainSampler ; +CLEW_FUN_EXPORT PFNCLRELEASESAMPLER __clewReleaseSampler ; +CLEW_FUN_EXPORT PFNCLGETSAMPLERINFO __clewGetSamplerInfo ; +CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource ; +CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary ; +CLEW_FUN_EXPORT PFNCLRETAINPROGRAM __clewRetainProgram ; +CLEW_FUN_EXPORT PFNCLRELEASEPROGRAM __clewReleaseProgram ; +CLEW_FUN_EXPORT PFNCLBUILDPROGRAM __clewBuildProgram ; +CLEW_FUN_EXPORT PFNCLUNLOADCOMPILER __clewUnloadCompiler ; +CLEW_FUN_EXPORT PFNCLGETPROGRAMINFO __clewGetProgramInfo ; +CLEW_FUN_EXPORT PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo ; +CLEW_FUN_EXPORT PFNCLCREATEKERNEL __clewCreateKernel ; +CLEW_FUN_EXPORT PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram ; +CLEW_FUN_EXPORT PFNCLRETAINKERNEL __clewRetainKernel ; +CLEW_FUN_EXPORT PFNCLRELEASEKERNEL __clewReleaseKernel ; +CLEW_FUN_EXPORT PFNCLSETKERNELARG __clewSetKernelArg ; +CLEW_FUN_EXPORT PFNCLGETKERNELINFO __clewGetKernelInfo ; +CLEW_FUN_EXPORT PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo ; +CLEW_FUN_EXPORT PFNCLWAITFOREVENTS __clewWaitForEvents ; +CLEW_FUN_EXPORT PFNCLGETEVENTINFO __clewGetEventInfo ; +CLEW_FUN_EXPORT PFNCLRETAINEVENT __clewRetainEvent ; +CLEW_FUN_EXPORT PFNCLRELEASEEVENT __clewReleaseEvent ; +CLEW_FUN_EXPORT PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo ; +CLEW_FUN_EXPORT PFNCLFLUSH __clewFlush ; +CLEW_FUN_EXPORT PFNCLFINISH __clewFinish ; +CLEW_FUN_EXPORT PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer ; +CLEW_FUN_EXPORT PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer ; +CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer ; +CLEW_FUN_EXPORT PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage ; +CLEW_FUN_EXPORT PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage ; +CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage ; +CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer ; +CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage ; +CLEW_FUN_EXPORT PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer ; +CLEW_FUN_EXPORT PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage ; +CLEW_FUN_EXPORT PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject ; +CLEW_FUN_EXPORT PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel ; +CLEW_FUN_EXPORT PFNCLENQUEUETASK __clewEnqueueTask ; +CLEW_FUN_EXPORT PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel ; +CLEW_FUN_EXPORT PFNCLENQUEUEMARKER __clewEnqueueMarker ; +CLEW_FUN_EXPORT PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents ; +CLEW_FUN_EXPORT PFNCLENQUEUEBARRIER __clewEnqueueBarrier ; +CLEW_FUN_EXPORT PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress ; + + +#define clGetPlatformIDs CLEW_GET_FUN(__clewGetPlatformIDs ) +#define clGetPlatformInfo CLEW_GET_FUN(__clewGetPlatformInfo ) +#define clGetDeviceIDs CLEW_GET_FUN(__clewGetDeviceIDs ) +#define clGetDeviceInfo CLEW_GET_FUN(__clewGetDeviceInfo ) +#define clCreateContext CLEW_GET_FUN(__clewCreateContext ) +#define clCreateContextFromType CLEW_GET_FUN(__clewCreateContextFromType ) +#define clRetainContext CLEW_GET_FUN(__clewRetainContext ) +#define clReleaseContext CLEW_GET_FUN(__clewReleaseContext ) +#define clGetContextInfo CLEW_GET_FUN(__clewGetContextInfo ) +#define clCreateCommandQueue CLEW_GET_FUN(__clewCreateCommandQueue ) +#define clRetainCommandQueue CLEW_GET_FUN(__clewRetainCommandQueue ) +#define clReleaseCommandQueue CLEW_GET_FUN(__clewReleaseCommandQueue ) +#define clGetCommandQueueInfo CLEW_GET_FUN(__clewGetCommandQueueInfo ) +#define clSetCommandQueueProperty CLEW_GET_FUN(__clewSetCommandQueueProperty ) +#define clCreateBuffer CLEW_GET_FUN(__clewCreateBuffer ) +#define clCreateImage2D CLEW_GET_FUN(__clewCreateImage2D ) +#define clCreateImage3D CLEW_GET_FUN(__clewCreateImage3D ) +#define clRetainMemObject CLEW_GET_FUN(__clewRetainMemObject ) +#define clReleaseMemObject CLEW_GET_FUN(__clewReleaseMemObject ) +#define clGetSupportedImageFormats CLEW_GET_FUN(__clewGetSupportedImageFormats ) +#define clGetMemObjectInfo CLEW_GET_FUN(__clewGetMemObjectInfo ) +#define clGetImageInfo CLEW_GET_FUN(__clewGetImageInfo ) +#define clCreateSampler CLEW_GET_FUN(__clewCreateSampler ) +#define clRetainSampler CLEW_GET_FUN(__clewRetainSampler ) +#define clReleaseSampler CLEW_GET_FUN(__clewReleaseSampler ) +#define clGetSamplerInfo CLEW_GET_FUN(__clewGetSamplerInfo ) +#define clCreateProgramWithSource CLEW_GET_FUN(__clewCreateProgramWithSource ) +#define clCreateProgramWithBinary CLEW_GET_FUN(__clewCreateProgramWithBinary ) +#define clRetainProgram CLEW_GET_FUN(__clewRetainProgram ) +#define clReleaseProgram CLEW_GET_FUN(__clewReleaseProgram ) +#define clBuildProgram CLEW_GET_FUN(__clewBuildProgram ) +#define clUnloadCompiler CLEW_GET_FUN(__clewUnloadCompiler ) +#define clGetProgramInfo CLEW_GET_FUN(__clewGetProgramInfo ) +#define clGetProgramBuildInfo CLEW_GET_FUN(__clewGetProgramBuildInfo ) +#define clCreateKernel CLEW_GET_FUN(__clewCreateKernel ) +#define clCreateKernelsInProgram CLEW_GET_FUN(__clewCreateKernelsInProgram ) +#define clRetainKernel CLEW_GET_FUN(__clewRetainKernel ) +#define clReleaseKernel CLEW_GET_FUN(__clewReleaseKernel ) +#define clSetKernelArg CLEW_GET_FUN(__clewSetKernelArg ) +#define clGetKernelInfo CLEW_GET_FUN(__clewGetKernelInfo ) +#define clGetKernelWorkGroupInfo CLEW_GET_FUN(__clewGetKernelWorkGroupInfo ) +#define clWaitForEvents CLEW_GET_FUN(__clewWaitForEvents ) +#define clGetEventInfo CLEW_GET_FUN(__clewGetEventInfo ) +#define clRetainEvent CLEW_GET_FUN(__clewRetainEvent ) +#define clReleaseEvent CLEW_GET_FUN(__clewReleaseEvent ) +#define clGetEventProfilingInfo CLEW_GET_FUN(__clewGetEventProfilingInfo ) +#define clFlush CLEW_GET_FUN(__clewFlush ) +#define clFinish CLEW_GET_FUN(__clewFinish ) +#define clEnqueueReadBuffer CLEW_GET_FUN(__clewEnqueueReadBuffer ) +#define clEnqueueWriteBuffer CLEW_GET_FUN(__clewEnqueueWriteBuffer ) +#define clEnqueueCopyBuffer CLEW_GET_FUN(__clewEnqueueCopyBuffer ) +#define clEnqueueReadImage CLEW_GET_FUN(__clewEnqueueReadImage ) +#define clEnqueueWriteImage CLEW_GET_FUN(__clewEnqueueWriteImage ) +#define clEnqueueCopyImage CLEW_GET_FUN(__clewEnqueueCopyImage ) +#define clEnqueueCopyImageToBuffer CLEW_GET_FUN(__clewEnqueueCopyImageToBuffer ) +#define clEnqueueCopyBufferToImage CLEW_GET_FUN(__clewEnqueueCopyBufferToImage ) +#define clEnqueueMapBuffer CLEW_GET_FUN(__clewEnqueueMapBuffer ) +#define clEnqueueMapImage CLEW_GET_FUN(__clewEnqueueMapImage ) +#define clEnqueueUnmapMemObject CLEW_GET_FUN(__clewEnqueueUnmapMemObject ) +#define clEnqueueNDRangeKernel CLEW_GET_FUN(__clewEnqueueNDRangeKernel ) +#define clEnqueueTask CLEW_GET_FUN(__clewEnqueueTask ) +#define clEnqueueNativeKernel CLEW_GET_FUN(__clewEnqueueNativeKernel ) +#define clEnqueueMarker CLEW_GET_FUN(__clewEnqueueMarker ) +#define clEnqueueWaitForEvents CLEW_GET_FUN(__clewEnqueueWaitForEvents ) +#define clEnqueueBarrier CLEW_GET_FUN(__clewEnqueueBarrier ) +#define clGetExtensionFunctionAddress CLEW_GET_FUN(__clewGetExtensionFunctionAddress ) + +#endif // CLCC_GENERATE_DOCUMENTATION + +#define CLEW_SUCCESS 0 //!< Success error code +#define CLEW_ERROR_OPEN_FAILED -1 //!< Error code for failing to open the dynamic library +#define CLEW_ERROR_ATEXIT_FAILED -2 //!< Error code for failing to queue the closing of the dynamic library to atexit() + +//! \brief Load OpenCL dynamic library and set function entry points +int clewInit (const char*); +//! \brief Convert an OpenCL error code to its string equivalent +const char* clewErrorString (cl_int error); + +#ifdef __cplusplus +} +#endif +#endif //USE_MINICL +#endif // CLCC_CLEW_HPP_INCLUDED diff --git a/Demos/SimplexDemo/CMakeLists.txt b/Demos/SimplexDemo/CMakeLists.txt new file mode 100644 index 0000000..9556823 --- /dev/null +++ b/Demos/SimplexDemo/CMakeLists.txt @@ -0,0 +1,48 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppSimplexDemo + SimplexDemo.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSimplexDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSimplexDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppSimplexDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppSimplexDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppSimplexDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/SimplexDemo/SimplexDemo.cpp b/Demos/SimplexDemo/SimplexDemo.cpp new file mode 100644 index 0000000..f804c73 --- /dev/null +++ b/Demos/SimplexDemo/SimplexDemo.cpp @@ -0,0 +1,123 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* + SimplexDemo demonstrated the working of the subdistance algorithm as used in GJK. + It draws the simplex, and calculates the closest vector from simplex to the origin +*/ + +#include "GL_Simplex1to4.h" +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btTransform.h" +#include "GL_ShapeDrawer.h" + +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "SimplexDemo.h" +#include "GlutStuff.h" + +btVoronoiSimplexSolver simplexSolver; + + + +float yaw=0.f,pitch=0.f,roll=0.f; +const int maxNumObjects = 4; +const int numObjects = 1; +int screenWidth = 640; +int screenHeight = 480; +/// simplex contains the vertices, and some extra code to draw and debug +GL_Simplex1to4 simplex; + + +btPolyhedralConvexShape* shapePtr[maxNumObjects]; + + +/// +/// +/// +int main(int argc,char** argv) +{ + + SimplexDemo* demo = new SimplexDemo(); + + demo->initPhysics(); + + return glutmain(argc, argv,screenWidth,screenHeight,"SimplexDemo",demo); +} + +//to be implemented by the demo + +void SimplexDemo::clientMoveAndDisplay() +{ + + displayCallback(); +} + + + +void SimplexDemo::displayCallback() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + + GL_ShapeDrawer::drawCoordSystem(); + + btScalar m[16]; + int i; + + btVector3 worldBoundsMin(-1000,-1000,-1000); + btVector3 worldBoundsMax(1000,1000,1000); + + for (i=0;idrawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax); + + /// calculate closest point from simplex to the origin, and draw this vector + simplex.calcClosest(m); + + } + pitch += 0.005f; + yaw += 0.01f; + + glFlush(); + glutSwapBuffers(); +} + +void SimplexDemo::initPhysics() +{ + + simplex.setSimplexSolver(&simplexSolver); + + simplex.addVertex(btVector3(-2,0,-2)); + simplex.addVertex(btVector3(2,0,-2)); + simplex.addVertex(btVector3(0,0,2)); + simplex.addVertex(btVector3(0,2,0)); + + shapePtr[0] = &simplex; + + btTransform tr; + tr.setIdentity(); +} + + diff --git a/Demos/SimplexDemo/SimplexDemo.h b/Demos/SimplexDemo/SimplexDemo.h new file mode 100644 index 0000000..72f6200 --- /dev/null +++ b/Demos/SimplexDemo/SimplexDemo.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef SIMPLEX_DEMO_H +#define SIMPLEX_DEMO_H + +#include "GlutDemoApplication.h" + +///SimplexDemo shows the working of the sub-distance algorithm, used inside GJK +class SimplexDemo : public GlutDemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + +}; + +#endif //SIMPLEX_DEMO_H + + diff --git a/Demos/SliderConstraintDemo/CMakeLists.txt b/Demos/SliderConstraintDemo/CMakeLists.txt new file mode 100644 index 0000000..d43bce4 --- /dev/null +++ b/Demos/SliderConstraintDemo/CMakeLists.txt @@ -0,0 +1,51 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( +OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppSliderConstraintDemo + SliderConstraintDemo.cpp + main.cpp +) + +IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSliderConstraintDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSliderConstraintDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF(WIN32) + + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppSliderConstraintDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppSliderConstraintDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppSliderConstraintDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/SliderConstraintDemo/SliderConstraintDemo.cpp b/Demos/SliderConstraintDemo/SliderConstraintDemo.cpp new file mode 100755 index 0000000..12fe4e5 --- /dev/null +++ b/Demos/SliderConstraintDemo/SliderConstraintDemo.cpp @@ -0,0 +1,512 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* +Added by Roman Ponomarev (rponom@gmail.com) +April 04, 2008 + +Added support for ODE sover +April 24, 2008 +*/ + + + + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" + +#include "GLDebugDrawer.h" + + +#include //printf debugging + +#include "SliderConstraintDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + + + +#define SLIDER_DEMO_USE_ODE_SOLVER 0 +#define SLIDER_DEMO_USE_6DOF 0 + +#define CUBE_HALF_EXTENTS 1.f + +#define SLIDER_ENABLE_ALL_DEMOS 1 + + + +// A couple of sliders +#if SLIDER_DEMO_USE_6DOF + static btGeneric6DofConstraint *spSlider1, *spSlider2; +#else + static btSliderConstraint *spSlider1, *spSlider2; +#endif + +static btPoint2PointConstraint* spP2PConst; +//static btHingeConstraint* spHingeConst; + + + +static void draw_axes(const btRigidBody& rb, const btTransform& frame) +{ + glBegin(GL_LINES); + // draw world transform + btVector3 from = rb.getWorldTransform().getOrigin(); + btVector3 to = from + rb.getWorldTransform().getBasis() * btVector3(5,0,0); + // X in red + glColor3f(255.0F, 0.0F, 0.0F); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + to = from + rb.getWorldTransform().getBasis() * btVector3(0,5,0); + // Y in green + glColor3f(0.0F, 255.0F, 0.0F); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + to = from + rb.getWorldTransform().getBasis() * btVector3(0,0,5); + // Z in blue + glColor3f(0.0F, 0.0F, 255.0F); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + // draw slider frame + btTransform calc_frame = rb.getWorldTransform() * frame; + from = calc_frame.getOrigin(); + to = from + calc_frame.getBasis() * btVector3(10,0,0); + // X in red + glColor3f(255.0F, 0.0F, 0.0F); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + to = from + calc_frame.getBasis() * btVector3(0,10,0); + // Y in green + glColor3f(0.0F, 255.0F, 0.0F); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + to = from + calc_frame.getBasis() * btVector3(0,0,10); + // Z in blue + glColor3f(0.0F, 0.0F, 255.0F); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + glEnd(); +} // draw_axes() + + + +#if SLIDER_DEMO_USE_6DOF +static void drawSlider(btGeneric6DofConstraint* pSlider) +{ + draw_axes(pSlider->getRigidBodyA(), pSlider->getFrameOffsetA()); + draw_axes(pSlider->getRigidBodyB(), pSlider->getFrameOffsetB()); +} // drawSlider() +#else +static void drawSlider(btSliderConstraint* pSlider) +{ + draw_axes(pSlider->getRigidBodyA(), pSlider->getFrameOffsetA()); + draw_axes(pSlider->getRigidBodyB(), pSlider->getFrameOffsetB()); + // draw limits in white + btVector3 from(pSlider->getLowerLinLimit(), 0, 0); + btVector3 to(pSlider->getUpperLinLimit(), 0, 0); + btTransform trans; + if(pSlider->getUseLinearReferenceFrameA()) + { + trans = pSlider->getRigidBodyA().getWorldTransform() * pSlider->getFrameOffsetA(); + } + else + { + trans = pSlider->getRigidBodyB().getWorldTransform() * pSlider->getFrameOffsetB(); + } + from = trans * from; + to = trans * to; + glBegin(GL_LINES); + glColor3f(255.0F, 255.0F, 255.0F); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + glEnd(); +} // drawSlider() +#endif + + + +void SliderConstraintDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + setCameraDistance(26.f); + + // init world + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + m_overlappingPairCache = new btAxisSweep3(worldMin,worldMax); + +#if SLIDER_DEMO_USE_ODE_SOLVER + m_constraintSolver = new btOdeQuickstepConstraintSolver(); +#else + m_constraintSolver = new btSequentialImpulseConstraintSolver(); +#endif + + btDiscreteDynamicsWorld* wp = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); + // wp->getSolverInfo().m_numIterations = 20; // default is 10 + m_dynamicsWorld = wp; +// wp->getSolverInfo().m_erp = 0.8; + + // add floor + //btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-76,0)); + btRigidBody* groundBody; + groundBody = localCreateRigidBody(0, groundTransform, groundShape); + + // add box shape (will be reused for all bodies) + btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); + m_collisionShapes.push_back(shape); + // mass of dymamic bodies + btScalar mass = btScalar(1.); + + // add dynamic rigid body A1 + btTransform trans; + trans.setIdentity(); + btVector3 worldPos(-20,0,0); + trans.setOrigin(worldPos); + btTransform frameInA, frameInB; + frameInA = btTransform::getIdentity(); + frameInB = btTransform::getIdentity(); + +#if SLIDER_ENABLE_ALL_DEMOS + btRigidBody* pRbA1 = localCreateRigidBody(mass, trans, shape); +// btRigidBody* pRbA1 = localCreateRigidBody(0.f, trans, shape); + pRbA1->setActivationState(DISABLE_DEACTIVATION); + + // add dynamic rigid body B1 + worldPos.setValue(-30,0,0); + trans.setOrigin(worldPos); + btRigidBody* pRbB1 = localCreateRigidBody(mass, trans, shape); +// btRigidBody* pRbB1 = localCreateRigidBody(0.f, trans, shape); + pRbB1->setActivationState(DISABLE_DEACTIVATION); + + // create slider constraint between A1 and B1 and add it to world + +#if SLIDER_DEMO_USE_6DOF + spSlider1 = new btGeneric6DofConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true); + btVector3 lowerSliderLimit = btVector3(-20,0,0); + btVector3 hiSliderLimit = btVector3(-10,0,0); +// btVector3 lowerSliderLimit = btVector3(-20,-5,-5); +// btVector3 hiSliderLimit = btVector3(-10,5,5); + spSlider1->setLinearLowerLimit(lowerSliderLimit); + spSlider1->setLinearUpperLimit(hiSliderLimit); + spSlider1->setAngularLowerLimit(btVector3(0,0,0)); + spSlider1->setAngularUpperLimit(btVector3(0,0,0)); +#else + spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true); +// spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, false); + spSlider1->setLowerLinLimit(-15.0F); + spSlider1->setUpperLinLimit(-5.0F); +// spSlider1->setLowerLinLimit(5.0F); +// spSlider1->setUpperLinLimit(15.0F); +// spSlider1->setLowerLinLimit(-10.0F); +// spSlider1->setUpperLinLimit(-10.0F); + + spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F); + spSlider1->setUpperAngLimit( SIMD_PI / 3.0F); +#endif + + m_dynamicsWorld->addConstraint(spSlider1, true); + spSlider1->setDbgDrawSize(btScalar(5.f)); +#endif + +#if SLIDER_ENABLE_ALL_DEMOS + // add kinematic rigid body A2 +// worldPos.setValue(20,4,0); + worldPos.setValue(5,-20,0); + trans.setOrigin(worldPos); + btRigidBody* pRbA2 = localCreateRigidBody(0., trans, shape); +// btRigidBody* pRbA2 = localCreateRigidBody(mass, trans, shape); +// btRigidBody* pRbA2 = localCreateRigidBody(mass * 10000, trans, shape); + pRbA2->setActivationState(DISABLE_DEACTIVATION); + + // add dynamic rigid body B2 +// worldPos.setValue(-20,4,0); + worldPos.setValue(-5,-20,0); + trans.setOrigin(worldPos); +// btRigidBody* pRbB2 = localCreateRigidBody(0., trans, shape); + btRigidBody* pRbB2 = localCreateRigidBody(mass, trans, shape); +// btRigidBody* pRbB2 = localCreateRigidBody(mass * 10000, trans, shape); + pRbB2->setActivationState(DISABLE_DEACTIVATION); + +// frameInA.getBasis().setEulerZYX(1.f, 1.f, 1.f); +// frameInB.getBasis().setEulerZYX(1.f, 1.f, 1.f); +// frameInA.getBasis().setEulerZYX(1.f, 1.f, 1.f); +// frameInB.getBasis().setEulerZYX(1.f, 1.f, 1.f); + + +// frameInA.setOrigin(btVector3(-20., 5., 0)); +// frameInB.setOrigin(btVector3( 20., 5., 0)); + frameInA.setOrigin(btVector3(-5., 20., 0)); + frameInB.setOrigin(btVector3( 5., 20., 0)); + + + // create slider constraint between A2 and B2 and add it to world +#if SLIDER_DEMO_USE_6DOF + spSlider2 = new btGeneric6DofConstraint(*pRbA2, *pRbB2, frameInA, frameInB, true); + spSlider2->setLinearLowerLimit(lowerSliderLimit); + spSlider2->setLinearUpperLimit(hiSliderLimit); + spSlider2->setAngularLowerLimit(btVector3(0,0,0)); + spSlider2->setAngularUpperLimit(btVector3(0,0,0)); +#else + spSlider2 = new btSliderConstraint(*pRbA2, *pRbB2, frameInA, frameInB, true); +// spSlider2 = new btSliderConstraint(*pRbA2, *pRbB2, frameInA, frameInB, false); +// spSlider2->setLowerLinLimit(0.0F); +// spSlider2->setUpperLinLimit(0.0F); + spSlider2->setLowerLinLimit(-2.0F); + spSlider2->setUpperLinLimit(2.0F); +// spSlider2->setLowerLinLimit(5.0F); +// spSlider2->setUpperLinLimit(25.0F); +// spSlider2->setUpperLinLimit(-5.0F); +// spSlider2->setUpperLinLimit(-9.99F); + + +// spSlider2->setLowerAngLimit(SIMD_PI / 2.0F); +// spSlider2->setUpperAngLimit(-SIMD_PI / 2.0F); + + // spSlider2->setLowerAngLimit(-SIMD_PI / 2.0F); +// spSlider2->setUpperAngLimit(SIMD_PI / 2.0F); + +// spSlider2->setLowerAngLimit(-SIMD_PI); +// spSlider2->setUpperAngLimit(SIMD_PI *0.8F); + + +// spSlider2->setLowerAngLimit(-0.01F); +// spSlider2->setUpperAngLimit(0.01F); + spSlider2->setLowerAngLimit(-1.570796326F * 0.5f); + spSlider2->setUpperAngLimit(1.570796326F * 0.5f); +// spSlider2->setLowerAngLimit(1.F); +// spSlider2->setUpperAngLimit(-1.F); + + +// spSlider2->setDampingLimLin(0.5f); + +#if 0 + // add motors + spSlider2->setPoweredLinMotor(true); + spSlider2->setMaxLinMotorForce(0.1); + spSlider2->setTargetLinMotorVelocity(-5.0); + + spSlider2->setPoweredAngMotor(true); +// spSlider2->setMaxAngMotorForce(0.01); + spSlider2->setMaxAngMotorForce(10.0); + spSlider2->setTargetAngMotorVelocity(1.0); + + // change default damping and restitution + + spSlider2->setDampingDirLin(0.005F); + spSlider2->setRestitutionLimLin(1.1F); +#endif + + // various ODE tests +// spSlider2->setDampingLimLin(0.1F); // linear bounce factor for ODE == 1.0 - DampingLimLin; +// spSlider2->setDampingLimAng(0.1F); // angular bounce factor for ODE == 1.0 - DampingLimAng; +// spSlider2->setSoftnessOrthoAng(0.1); +// spSlider2->setSoftnessOrthoLin(0.1); +// spSlider2->setSoftnessLimLin(0.1); +// spSlider2->setSoftnessLimAng(0.1); +#endif + m_dynamicsWorld->addConstraint(spSlider2, true); + spSlider2->setDbgDrawSize(btScalar(5.f)); +#endif + +#if SLIDER_ENABLE_ALL_DEMOS +{ + // add dynamic rigid body A1 + trans.setIdentity(); + worldPos.setValue(20,0,0); + trans.setOrigin(worldPos); + btRigidBody* pRbA3 = localCreateRigidBody(0.0F, trans, shape); + pRbA3->setActivationState(DISABLE_DEACTIVATION); + + // add dynamic rigid body B1 + worldPos.setValue(25,0,0); + trans.setOrigin(worldPos); + btRigidBody* pRbB3 = localCreateRigidBody(mass, trans, shape); + pRbB3->setActivationState(DISABLE_DEACTIVATION); + + btVector3 pivA( 2.5, 0., 0.); + btVector3 pivB(-2.5, 0., 0.); + spP2PConst = new btPoint2PointConstraint(*pRbA3, *pRbB3, pivA, pivB); + m_dynamicsWorld->addConstraint(spP2PConst, true); + spP2PConst->setDbgDrawSize(btScalar(5.f)); + +} +#endif + +#if 0 // SLIDER_ENABLE_ALL_DEMOS + // add dynamic rigid body A4 + trans.setIdentity(); + worldPos.setValue(20,10,0); + trans.setOrigin(worldPos); + btRigidBody* pRbA4 = localCreateRigidBody(0.0F, trans, shape); + pRbA4->setActivationState(DISABLE_DEACTIVATION); + + // add dynamic rigid body B1 + worldPos.setValue(27,10,0); + trans.setOrigin(worldPos); + btRigidBody* pRbB4 = localCreateRigidBody(mass, trans, shape); + pRbB1->setActivationState(DISABLE_DEACTIVATION); + + + btVector3 pivA( 2., 0., 0.); + btVector3 pivB(-5., 0., 0.); + btVector3 axisA(0., 0., 1.); + btVector3 axisB(0., 0., 1.); + + spHingeConst = new btHingeConstraint(*pRbA4, *pRbB4, pivA, pivB, axisA, axisB); +// spHingeConst->setLimit(-1.57, 1.57); + spHingeConst->setLimit(1.57, -1.57); + spHingeConst->enableAngularMotor(true, 10.0, 0.19); + + m_dynamicsWorld->addConstraint(spHingeConst, true); + spHingeConst->setDbgDrawSize(btScalar(5.f)); + +#endif + +} // SliderConstraintDemo::initPhysics() + + + +SliderConstraintDemo::~SliderConstraintDemo() +{ + //cleanup in the reverse order of creation/initialization + int i; + //removed/delete constraints + for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--) + { + btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); + m_dynamicsWorld->removeConstraint(constraint); + delete constraint; + } + //remove the rigidbodies from the dynamics world and delete them + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + //delete collision shapes + for (int j=0;jstepSimulation(dt,maxSimSubSteps); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + bool verbose = false; + if (verbose) + { + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } + } + renderme(); +// drawSlider(spSlider1); +// drawSlider(spSlider2); + glFlush(); + glutSwapBuffers(); +} // SliderConstraintDemo::clientMoveAndDisplay() + + + +void SliderConstraintDemo::displayCallback(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if(m_dynamicsWorld) + { + m_dynamicsWorld->debugDrawWorld(); + } +// drawSlider(spSlider1); +// drawSlider(spSlider2); + renderme(); + glFlush(); + glutSwapBuffers(); +} // SliderConstraintDemo::displayCallback() + + +void SliderConstraintDemo::keyboardCallback(unsigned char key, int x, int y) +{ + (void)x; + (void)y; + switch (key) + { + case 'O' : + { + bool offectOnOff; + offectOnOff = spSlider1->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spSlider1->setUseFrameOffset(offectOnOff); + printf("Slider1 %s frame offset\n", offectOnOff ? "uses" : "does not use"); + offectOnOff = spSlider2->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spSlider2->setUseFrameOffset(offectOnOff); + printf("Slider2 %s frame offset\n", offectOnOff ? "uses" : "does not use"); + } + break; + default : + { + DemoApplication::keyboardCallback(key, x, y); + } + break; + } +} + diff --git a/Demos/SliderConstraintDemo/SliderConstraintDemo.h b/Demos/SliderConstraintDemo/SliderConstraintDemo.h new file mode 100755 index 0000000..f0a652a --- /dev/null +++ b/Demos/SliderConstraintDemo/SliderConstraintDemo.h @@ -0,0 +1,73 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef SLIDER_CONSTRAINT_DEMO_H +#define SLIDER_CONSTRAINT_DEMO_H + + + +#include "btBulletDynamicsCommon.h" +#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" +#include "GlutDemoApplication.h" + + + + +/// SliderConstraintDemo shows how to create a slider constraint +class SliderConstraintDemo : public GlutDemoApplication +{ + //keep track of variables to delete memory at the end + btAlignedObjectArray m_collisionShapes; + + class btBroadphaseInterface* m_overlappingPairCache; + + class btCollisionDispatcher* m_dispatcher; + + class btConstraintSolver* m_constraintSolver; + + class btDefaultCollisionConfiguration* m_collisionConfiguration; + + public: + + virtual ~SliderConstraintDemo(); + + void initPhysics(); + + void initModel(); + + void drawSliders(); + void drawSliderConstraint(btSliderConstraint* constraint); + + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + static DemoApplication* Create() + { + SliderConstraintDemo* demo = new SliderConstraintDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } + + virtual void keyboardCallback(unsigned char key, int x, int y); + +}; + +#endif //SLIDER_CONSTRAINT_DEMO_H + diff --git a/Demos/SliderConstraintDemo/main.cpp b/Demos/SliderConstraintDemo/main.cpp new file mode 100755 index 0000000..54f1afa --- /dev/null +++ b/Demos/SliderConstraintDemo/main.cpp @@ -0,0 +1,25 @@ +/* +Added by Roman Ponomarev (rponom@gmail.com) +April 04, 2008 +*/ +#include "SliderConstraintDemo.h" +#include "GlutStuff.h" + +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + SliderConstraintDemo* sliderConstraintDemo = new SliderConstraintDemo(); + + sliderConstraintDemo->initPhysics(); + sliderConstraintDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + sliderConstraintDemo->setDebugMode(btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits); + + + return glutmain(argc, argv,640,480,"Slider Constraint Demo. http://www.continuousphysics.com/Bullet/phpBB2/", sliderConstraintDemo); +} + diff --git a/Demos/SoftDemo/AMD/premake4.lua b/Demos/SoftDemo/AMD/premake4.lua new file mode 100644 index 0000000..2ff0887 --- /dev/null +++ b/Demos/SoftDemo/AMD/premake4.lua @@ -0,0 +1,59 @@ + + hasCL = findOpenCL_AMD() + + if (hasCL) then + + project "AppSoftBodyDemo_AMD" + + defines { "USE_AMD_OPENCL","CL_PLATFORM_AMD"} + + initOpenCL_AMD() + + language "C++" + + kind "ConsoleApp" + targetdir "../../.." + + libdirs {"../../../Glut"} + + links { + "LinearMath", + "BulletCollision", + "BulletDynamics", + "BulletSoftBody", + "BulletSoftBodySolvers_OpenCL_AMD", + "OpenGLSupport", + "opengl32" + } + + configuration "x64" + links { + "glut64", + "glew64s" + } + configuration "x32" + links { + "glut32", + "glew32s" + } + + configuration{} + + + includedirs { + "../../SharedOpenCL", + "../../../src", + "../../../Glut", + "../../OpenGL" + } + + files { + "../SoftDemo.cpp", + "../SoftDemo.h", + "../main.cpp", + "../../SharedOpenCL/btOpenCLUtils.cpp", + "../../SharedOpenCL/btOpenCLUtils.h", + "../../SharedOpenCL/btOpenCLInclude.h" + } + + end \ No newline at end of file diff --git a/Demos/SoftDemo/CMakeLists.txt b/Demos/SoftDemo/CMakeLists.txt new file mode 100644 index 0000000..e819e46 --- /dev/null +++ b/Demos/SoftDemo/CMakeLists.txt @@ -0,0 +1,64 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + + +# You shouldn't have to modify anything below this line +######################################################## + +IF (USE_GLUT) + + INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ) + + LINK_LIBRARIES( + OpenGLSupport BulletSoftBody BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + IF (WIN32) + ADD_EXECUTABLE(AppSoftBodyDemo + main.cpp + SoftDemo.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + ELSE() + ADD_EXECUTABLE(AppSoftBodyDemo + main.cpp + SoftDemo.cpp + + ) + ENDIF() + + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSoftBodyDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppSoftBodyDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ENDIF(WIN32) + + +ELSE(USE_GLUT) + +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppSoftBodyDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppSoftBodyDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppSoftBodyDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/SoftDemo/Makefile.am b/Demos/SoftDemo/Makefile.am new file mode 100644 index 0000000..ede95b8 --- /dev/null +++ b/Demos/SoftDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=SoftDemo + +SoftDemo_SOURCES=SoftDemo.cpp SoftDemo.h main.cpp +SoftDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +SoftDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/SoftDemo/Makefile.in b/Demos/SoftDemo/Makefile.in new file mode 100644 index 0000000..90fae54 --- /dev/null +++ b/Demos/SoftDemo/Makefile.in @@ -0,0 +1,518 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = SoftDemo$(EXEEXT) +subdir = Demos/SoftDemo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_SoftDemo_OBJECTS = SoftDemo-SoftDemo.$(OBJEXT) \ + SoftDemo-main.$(OBJEXT) +SoftDemo_OBJECTS = $(am_SoftDemo_OBJECTS) +SoftDemo_DEPENDENCIES = +SoftDemo_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(SoftDemo_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(SoftDemo_SOURCES) +DIST_SOURCES = $(SoftDemo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SoftDemo_SOURCES = SoftDemo.cpp SoftDemo.h main.cpp +SoftDemo_CXXFLAGS = -I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +SoftDemo_LDADD = -L../OpenGL -lbulletopenglsupport -L../../src -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/SoftDemo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/SoftDemo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +SoftDemo$(EXEEXT): $(SoftDemo_OBJECTS) $(SoftDemo_DEPENDENCIES) + @rm -f SoftDemo$(EXEEXT) + $(SoftDemo_LINK) $(SoftDemo_OBJECTS) $(SoftDemo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SoftDemo-SoftDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SoftDemo-main.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +SoftDemo-SoftDemo.o: SoftDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -MT SoftDemo-SoftDemo.o -MD -MP -MF $(DEPDIR)/SoftDemo-SoftDemo.Tpo -c -o SoftDemo-SoftDemo.o `test -f 'SoftDemo.cpp' || echo '$(srcdir)/'`SoftDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/SoftDemo-SoftDemo.Tpo $(DEPDIR)/SoftDemo-SoftDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SoftDemo.cpp' object='SoftDemo-SoftDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -c -o SoftDemo-SoftDemo.o `test -f 'SoftDemo.cpp' || echo '$(srcdir)/'`SoftDemo.cpp + +SoftDemo-SoftDemo.obj: SoftDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -MT SoftDemo-SoftDemo.obj -MD -MP -MF $(DEPDIR)/SoftDemo-SoftDemo.Tpo -c -o SoftDemo-SoftDemo.obj `if test -f 'SoftDemo.cpp'; then $(CYGPATH_W) 'SoftDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/SoftDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/SoftDemo-SoftDemo.Tpo $(DEPDIR)/SoftDemo-SoftDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SoftDemo.cpp' object='SoftDemo-SoftDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -c -o SoftDemo-SoftDemo.obj `if test -f 'SoftDemo.cpp'; then $(CYGPATH_W) 'SoftDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/SoftDemo.cpp'; fi` + +SoftDemo-main.o: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -MT SoftDemo-main.o -MD -MP -MF $(DEPDIR)/SoftDemo-main.Tpo -c -o SoftDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/SoftDemo-main.Tpo $(DEPDIR)/SoftDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='SoftDemo-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -c -o SoftDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp + +SoftDemo-main.obj: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -MT SoftDemo-main.obj -MD -MP -MF $(DEPDIR)/SoftDemo-main.Tpo -c -o SoftDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/SoftDemo-main.Tpo $(DEPDIR)/SoftDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='SoftDemo-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(SoftDemo_CXXFLAGS) $(CXXFLAGS) -c -o SoftDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/SoftDemo/SoftDemo.cpp b/Demos/SoftDemo/SoftDemo.cpp new file mode 100644 index 0000000..2413c02 --- /dev/null +++ b/Demos/SoftDemo/SoftDemo.cpp @@ -0,0 +1,2293 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///btSoftBody implementation by Nathanael Presson + + +#include "btBulletDynamicsCommon.h" +#include "BulletSoftBody/btSoftRigidDynamicsWorld.h" + +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btIDebugDraw.h" + +#include "../GimpactTestDemo/BunnyMesh.h" +#include "../GimpactTestDemo/TorusMesh.h" +#include //printf debugging +#include "LinearMath/btConvexHull.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" + +#include "SoftDemo.h" +#include "GL_ShapeDrawer.h" +#include "GLDebugFont.h" +#include "GlutStuff.h" + +extern float eye[3]; +extern int glutScreenWidth; +extern int glutScreenHeight; + +static bool sDemoMode = false; + +const int maxProxies = 32766; +const int maxOverlap = 65535; + +static btVector3* gGroundVertices=0; +static int* gGroundIndices=0; +static btBvhTriangleMeshShape* trimeshShape =0; +static btRigidBody* staticBody = 0; +static float waveheight = 5.f; + +const float TRIANGLE_SIZE=8.f; +int current_demo=20; +#define DEMO_MODE_TIMEOUT 15.f //15 seconds for each demo + + +#ifdef _DEBUG +const int gNumObjects = 1; +#else +const int gNumObjects = 1;//try this in release mode: 3000. never go above 16384, unless you increate maxNumObjects value in DemoApplication.cp +#endif + +const int maxNumObjects = 32760; + +#define CUBE_HALF_EXTENTS 1.5 +#define EXTRA_HEIGHT -10.f + + +#ifdef USE_AMD_OPENCL +#include "btOpenCLUtils.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h" +#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h" + +btOpenCLSoftBodySolver* g_openCLSIMDSolver=0; +btSoftBodySolverOutputCLtoCPU* g_softBodyOutput = 0; + +cl_context g_cxMainContext; +cl_device_id g_cdDevice; +cl_command_queue g_cqCommandQue; + +void initCL( void* glCtx, void* glDC ) +{ + int ciErrNum = 0; + +#if defined(CL_PLATFORM_MINI_CL) + cl_device_type deviceType = CL_DEVICE_TYPE_CPU;//or use CL_DEVICE_TYPE_DEBUG to debug MiniCL +#elif defined(CL_PLATFORM_INTEL) + cl_device_type deviceType = CL_DEVICE_TYPE_CPU; +#elif defined(CL_PLATFORM_AMD) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#elif defined(CL_PLATFORM_NVIDIA) + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; +#else +#ifdef __APPLE__ + cl_device_type deviceType = CL_DEVICE_TYPE_ALL;//GPU; +#else + cl_device_type deviceType = CL_DEVICE_TYPE_CPU;//CL_DEVICE_TYPE_ALL +#endif//__APPLE__ +#endif + + g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + + int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext); + if (!numDev) + { + btAssert(0); + exit(0);//this is just a demo, exit now + } + + g_cdDevice = btOpenCLUtils::getDevice(g_cxMainContext,0); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + btOpenCLDeviceInfo clInfo; + btOpenCLUtils::getDeviceInfo(g_cdDevice,clInfo); + btOpenCLUtils::printDeviceInfo(g_cdDevice); + + // create a command-queue + g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_cdDevice, 0, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); +} + +class CachingCLFunctions : public CLFunctions +{ +protected: + + cl_device_id m_device; + + const char* strip(const char* name, const char* pattern); + +public: + CachingCLFunctions(cl_command_queue cqCommandQue, cl_context cxMainContext) : + CLFunctions(cqCommandQue,cxMainContext) + { + size_t actualSize; + cl_int retval = clGetCommandQueueInfo ( cqCommandQue, CL_QUEUE_DEVICE, sizeof(cl_device_id), + &m_device, &actualSize); + } + + /** + * Compile a compute shader kernel from a string and return the appropriate cl_kernel object. + */ + virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros , const char* orgSrcFileNameForCaching) + { + char srcFileNameForCaching[1024]; + sprintf(srcFileNameForCaching,"%s/%s","../../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL",orgSrcFileNameForCaching); + + btAssert(additionalMacros); + btAssert(srcFileNameForCaching && strlen(srcFileNameForCaching)); + + printf("compiling kernelName: %s ",kernelName); + cl_kernel kernel=0; + cl_int ciErrNum; + + + size_t program_length = strlen(kernelSource); + + cl_program m_cpProgram = btOpenCLUtils::compileCLProgramFromString(m_cxMainContext, m_device, kernelSource, &ciErrNum, additionalMacros); + + + // Create the kernel + kernel = clCreateKernel(m_cpProgram, kernelName, &ciErrNum); + if (ciErrNum != CL_SUCCESS) + { + const char* msg = ""; + switch(ciErrNum) + { + case CL_INVALID_PROGRAM: + msg = "Program is not a valid program object."; + break; + case CL_INVALID_PROGRAM_EXECUTABLE: + msg = "There is no successfully built executable for program."; + break; + case CL_INVALID_KERNEL_NAME: + msg = "kernel_name is not found in program."; + break; + case CL_INVALID_KERNEL_DEFINITION: + msg = "the function definition for __kernel function given by kernel_name such as the number of arguments, the argument types are not the same for all devices for which the program executable has been built."; + break; + case CL_INVALID_VALUE: + msg = "kernel_name is NULL."; + break; + case CL_OUT_OF_HOST_MEMORY: + msg = "Failure to allocate resources required by the OpenCL implementation on the host."; + break; + default: + { + } + } + + printf("Error in clCreateKernel for kernel '%s', error is \"%s\", Line %u in file %s !!!\n\n", kernelName, msg, __LINE__, __FILE__); + + #ifndef BT_SUPPRESS_OPENCL_ASSERTS + btAssert(0); + #endif //BT_SUPPRESS_OPENCL_ASSERTS + m_kernelCompilationFailures++; + return 0; + } + + printf("ready. \n"); + if (!kernel) + m_kernelCompilationFailures++; + return kernel; + } + +}; + + +#endif //USE_AMD_OPENCL + +// +void SoftDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ) +{ + btTransform trans; + trans.setIdentity(); + + for(int i=0; igetWorldUserInfo(); + + if(softDemo->m_drag) + { + const int x=softDemo->m_lastmousepos[0]; + const int y=softDemo->m_lastmousepos[1]; + const btVector3 rayFrom=softDemo->getCameraPosition(); + const btVector3 rayTo=softDemo->getRayTo(x,y); + const btVector3 rayDir=(rayTo-rayFrom).normalized(); + const btVector3 N=(softDemo->getCameraTargetPosition()-softDemo->getCameraPosition()).normalized(); + const btScalar O=btDot(softDemo->m_impact,N); + const btScalar den=btDot(N,rayDir); + if((den*den)>0) + { + const btScalar num=O-btDot(N,rayFrom); + const btScalar hit=num/den; + if((hit>0)&&(hit<1500)) + { + softDemo->m_goal=rayFrom+rayDir*hit; + } + } + btVector3 delta=softDemo->m_goal-softDemo->m_node->m_x; + static const btScalar maxdrag=10; + if(delta.length2()>(maxdrag*maxdrag)) + { + delta=delta.normalized()*maxdrag; + } + softDemo->m_node->m_v+=delta/timeStep; + } + +} + + + +void SoftDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + renderme(); + + glFlush(); + swapBuffers(); +} + + +// +// ImplicitShape +// + +// +struct ImplicitSphere : btSoftBody::ImplicitFn +{ + btVector3 center; + btScalar sqradius; + ImplicitSphere() {} + ImplicitSphere(const btVector3& c,btScalar r) : center(c),sqradius(r*r) {} + btScalar Eval(const btVector3& x) + { + return((x-center).length2()-sqradius); + } +}; + +// +// Tetra meshes +// + +struct TetraBunny +{ +#include "bunny.inl" +}; + +struct TetraCube +{ +#include "cube.inl" +}; + + +// +// Random +// + +static inline btScalar UnitRand() +{ + return(rand()/(btScalar)RAND_MAX); +} + +static inline btScalar SignedUnitRand() +{ + return(UnitRand()*2-1); +} + +static inline btVector3 Vector3Rand() +{ + const btVector3 p=btVector3(SignedUnitRand(),SignedUnitRand(),SignedUnitRand()); + return(p.normalized()); +} + +// +// Rb rain +// +static void Ctor_RbUpStack(SoftDemo* pdemo,int count) +{ + float mass=10; + + btCompoundShape* cylinderCompound = new btCompoundShape; + btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(4,1,1)); + btCollisionShape* boxShape = new btBoxShape(btVector3(4,1,1)); + btTransform localTransform; + localTransform.setIdentity(); + cylinderCompound->addChildShape(localTransform,boxShape); + btQuaternion orn(SIMD_HALF_PI,0,0); + localTransform.setRotation(orn); + // localTransform.setOrigin(btVector3(1,1,1)); + cylinderCompound->addChildShape(localTransform,cylinderShape); + + + btCollisionShape* shape[]={cylinderCompound, + new btBoxShape(btVector3(1,1,1)), + new btSphereShape(1.5) + + }; + static const int nshapes=sizeof(shape)/sizeof(shape[0]); + for(int i=0;ilocalCreateRigidBody(mass,startTransform,shape[i%nshapes]); + //pdemo->localCreateRigidBody(mass,startTransform,shape[0]); + } +} + +// +// Big ball +// +static void Ctor_BigBall(SoftDemo* pdemo,btScalar mass=10) +{ + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,13,0)); + pdemo->localCreateRigidBody(mass,startTransform,new btSphereShape(3)); +} + +// +// Big plate +// +static btRigidBody* Ctor_BigPlate(SoftDemo* pdemo,btScalar mass=15,btScalar height=4) +{ + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,height,0.5)); + btRigidBody* body=pdemo->localCreateRigidBody(mass,startTransform,new btBoxShape(btVector3(5,1,5))); + body->setFriction(1); + return(body); +} + +// +// Linear stair +// +static void Ctor_LinearStair(SoftDemo* pdemo,const btVector3& org,const btVector3& sizes,btScalar angle,int count) +{ + btBoxShape* shape=new btBoxShape(sizes); + for(int i=0;ilocalCreateRigidBody(0,startTransform,shape); + body->setFriction(1); + } +} + +// +// Softbox +// +static btSoftBody* Ctor_SoftBox(SoftDemo* pdemo,const btVector3& p,const btVector3& s) +{ + const btVector3 h=s*0.5; + const btVector3 c[]={ p+h*btVector3(-1,-1,-1), + p+h*btVector3(+1,-1,-1), + p+h*btVector3(-1,+1,-1), + p+h*btVector3(+1,+1,-1), + p+h*btVector3(-1,-1,+1), + p+h*btVector3(+1,-1,+1), + p+h*btVector3(-1,+1,+1), + p+h*btVector3(+1,+1,+1)}; + btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,c,8); + psb->generateBendingConstraints(2); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + return(psb); + +} + +// +// SoftBoulder +// +static btSoftBody* Ctor_SoftBoulder(SoftDemo* pdemo,const btVector3& p,const btVector3& s,int np,int id) +{ + btAlignedObjectArray pts; + if(id) srand(id); + for(int i=0;im_softBodyWorldInfo,&pts[0],pts.size()); + psb->generateBendingConstraints(2); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + return(psb); +} + +//#define TRACEDEMO { pdemo->demoname=__FUNCTION__+5;printf("Launching demo: " __FUNCTION__ "\r\n"); } + +// +// Basic ropes +// +static void Init_Ropes(SoftDemo* pdemo) +{ + //TRACEDEMO + const int n=15; + for(int i=0;im_softBodyWorldInfo, btVector3(-10,0,i*0.25), + btVector3(10,0,i*0.25), + 16, + 1+2); + psb->m_cfg.piterations = 4; + psb->m_materials[0]->m_kLST = 0.1+(i/(btScalar)(n-1))*0.9; + psb->setTotalMass(20); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + } +} + +// +// Rope attach +// +static void Init_RopeAttach(SoftDemo* pdemo) +{ + //TRACEDEMO + pdemo->m_softBodyWorldInfo.m_sparsesdf.RemoveReferences(0); + struct Functors + { + static btSoftBody* CtorRope(SoftDemo* pdemo,const btVector3& p) + { + btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo,p,p+btVector3(10,0,0),8,1); + psb->setTotalMass(50); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + return(psb); + } + }; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(12,8,0)); + btRigidBody* body=pdemo->localCreateRigidBody(50,startTransform,new btBoxShape(btVector3(2,6,2))); + btSoftBody* psb0=Functors::CtorRope(pdemo,btVector3(0,8,-1)); + btSoftBody* psb1=Functors::CtorRope(pdemo,btVector3(0,8,+1)); + psb0->appendAnchor(psb0->m_nodes.size()-1,body); + psb1->appendAnchor(psb1->m_nodes.size()-1,body); +} + +// +// Cloth attach +// +static void Init_ClothAttach(SoftDemo* pdemo) +{ + //TRACEDEMO + const btScalar s=4; + const btScalar h=6; + const int r=9; + btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s), + btVector3(+s,h,-s), + btVector3(-s,h,+s), + btVector3(+s,h,+s),r,r,4+8,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,h,-(s+3.5))); + btRigidBody* body=pdemo->localCreateRigidBody(20,startTransform,new btBoxShape(btVector3(s,1,3))); + psb->appendAnchor(0,body); + psb->appendAnchor(r-1,body); + pdemo->m_cutting=true; +} + +// +// Impact +// +static void Init_Impact(SoftDemo* pdemo) +{ + //TRACEDEMO + btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo, btVector3(0,0,0), + btVector3(0,-1,0), + 0, + 1); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + psb->m_cfg.kCHR=0.5; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,20,0)); + pdemo->localCreateRigidBody(10,startTransform,new btBoxShape(btVector3(2,2,2))); +} + +static void Init_CapsuleCollision(SoftDemo* pdemo) +{ +#ifdef USE_AMD_OPENCL + btAlignedObjectArray emptyArray; + if (g_openCLSIMDSolver) + g_openCLSIMDSolver->optimize(emptyArray); +#endif //USE_AMD_OPENCL + + //TRACEDEMO + const btScalar s=4; + const btScalar h=6; + const int r=20; + + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,h-2,0)); + + btCollisionShape* capsuleShape= new btCapsuleShapeX(1,5); + capsuleShape->setMargin( 0.5 ); + + // capsule->setLocalScaling(btVector3(5,1,1)); +// btRigidBody* body=pdemo->localCreateRigidBody(20,startTransform,capsuleShape); + btRigidBody* body=pdemo->localCreateRigidBody(0,startTransform,capsuleShape); + body->setFriction( 0.8f ); + + int fixed=0;//4+8; + btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s), + btVector3(+s,h,-s), + btVector3(-s,h,+s), + btVector3(+s,h,+s),r,r,fixed,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + psb->setTotalMass(0.1); + + psb->m_cfg.piterations = 10; + psb->m_cfg.citerations = 10; + psb->m_cfg.diterations = 10; +// psb->m_cfg.viterations = 10; + + + // psb->appendAnchor(0,body); +// psb->appendAnchor(r-1,body); +// pdemo->m_cutting=true; +} + +// +// Collide +// +static void Init_Collide(SoftDemo* pdemo) +{ + //TRACEDEMO + struct Functor + { + static btSoftBody* Create(SoftDemo* pdemo,const btVector3& x,const btVector3& a) + { + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices, + &gIndices[0][0], + NUM_TRIANGLES); + psb->generateBendingConstraints(2); + psb->m_cfg.piterations=2; + psb->m_cfg.collisions|=btSoftBody::fCollision::VF_SS; + psb->randomizeConstraints(); + btMatrix3x3 m; + m.setEulerZYX(a.x(),a.y(),a.z()); + psb->transform(btTransform(m,x)); + psb->scale(btVector3(2,2,2)); + psb->setTotalMass(50,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + return(psb); + } + }; + for(int i=0;i<3;++i) + { + Functor::Create(pdemo,btVector3(3*i,2,0),btVector3(SIMD_PI/2*(1-(i&1)),SIMD_PI/2*(i&1),0)); + } + pdemo->m_cutting=true; +} + +// +// Collide2 +// +static void Init_Collide2(SoftDemo* pdemo) +{ + //TRACEDEMO + struct Functor + { + static btSoftBody* Create(SoftDemo* pdemo,const btVector3& x,const btVector3& a) + { + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny, + &gIndicesBunny[0][0], + BUNNY_NUM_TRIANGLES); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 0.5; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->m_cfg.piterations = 2; + psb->m_cfg.kDF = 0.5; + psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS; + psb->randomizeConstraints(); + btMatrix3x3 m; + m.setEulerZYX(a.x(),a.y(),a.z()); + psb->transform(btTransform(m,x)); + psb->scale(btVector3(6,6,6)); + psb->setTotalMass(100,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + return(psb); + } + }; + for(int i=0;i<3;++i) + { + Functor::Create(pdemo,btVector3(0,-1+5*i,0),btVector3(0,SIMD_PI/2*(i&1),0)); + } + pdemo->m_cutting=true; +} + +// +// Collide3 +// +static void Init_Collide3(SoftDemo* pdemo) +{ + //TRACEDEMO + { + const btScalar s=8; + btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s), + btVector3(+s,0,-s), + btVector3(-s,0,+s), + btVector3(+s,0,+s), + 15,15,1+2+4+8,true); + psb->m_materials[0]->m_kLST = 0.4; + psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS; + psb->setTotalMass(150); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + } + { + const btScalar s=4; + const btVector3 o=btVector3(5,10,0); + btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo, + btVector3(-s,0,-s)+o, + btVector3(+s,0,-s)+o, + btVector3(-s,0,+s)+o, + btVector3(+s,0,+s)+o, + 7,7,0,true); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 0.1; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->m_materials[0]->m_kLST = 0.5; + psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS; + psb->setTotalMass(150); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + pdemo->m_cutting=true; + } +} + +// +// Aerodynamic forces, 50x1g flyers +// +static void Init_Aero(SoftDemo* pdemo) +{ + //TRACEDEMO + const btScalar s=2; + const btScalar h=10; + const int segments=6; + const int count=50; + for(int i=0;im_softBodyWorldInfo,btVector3(-s,h,-s), + btVector3(+s,h,-s), + btVector3(-s,h,+s), + btVector3(+s,h,+s), + segments,segments, + 0,true); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->m_cfg.kLF = 0.004; + psb->m_cfg.kDG = 0.0003; + psb->m_cfg.aeromodel = btSoftBody::eAeroModel::V_TwoSided; + btTransform trs; + btQuaternion rot; + btVector3 ra=Vector3Rand()*0.1; + btVector3 rp=Vector3Rand()*15+btVector3(0,20,80); + rot.setEuler(SIMD_PI/8+ra.x(),-SIMD_PI/7+ra.y(),ra.z()); + trs.setIdentity(); + trs.setOrigin(rp); + trs.setRotation(rot); + psb->transform(trs); + psb->setTotalMass(0.1); + psb->addForce(btVector3(0,2,0),0); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + } + pdemo->m_autocam=true; +} + +static void Init_Aero2(SoftDemo* pdemo) +{ + //TRACEDEMO + const btScalar s=5; + const int segments=10; + const int count=5; + btVector3 pos(-s*segments, 0, 0); + btScalar gap = 0.5; + + for(int i=0;im_softBodyWorldInfo,btVector3(-s,0,-s*3), + btVector3(+s,0,-s*3), + btVector3(-s,0,+s), + btVector3(+s,0,+s), + segments,segments*3, + 1+2,true); + + psb->getCollisionShape()->setMargin(0.5); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 0.0004; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + + psb->m_cfg.kLF = 0.05; + psb->m_cfg.kDG = 0.01; + + //psb->m_cfg.kLF = 0.004; + //psb->m_cfg.kDG = 0.0003; + + psb->m_cfg.piterations = 2; + psb->m_cfg.aeromodel = btSoftBody::eAeroModel::V_TwoSidedLiftDrag; + + + psb->setWindVelocity(btVector3(4, -12.0, -25.0)); + + btTransform trs; + btQuaternion rot; + pos += btVector3(s*2 + gap, 0, 0); + rot.setRotation(btVector3(1, 0, 0), btScalar(SIMD_PI/2)); + trs.setIdentity(); + trs.setOrigin(pos); + trs.setRotation(rot); + psb->transform(trs); + psb->setTotalMass(2.0); + + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + } + + pdemo->m_autocam=true; +} + +// +// Friction +// +static void Init_Friction(SoftDemo* pdemo) +{ + //TRACEDEMO + const btScalar bs=2; + const btScalar ts=bs+bs/4; + for(int i=0,ni=20;im_cfg.kDF = 0.1 * ((i+1)/(btScalar)ni); + psb->addVelocity(btVector3(0,0,-10)); + } +} + +// +// Pressure +// +static void Init_Pressure(SoftDemo* pdemo) +{ + //TRACEDEMO + btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0), + btVector3(1,1,1)*3, + 512); + psb->m_materials[0]->m_kLST = 0.1; + psb->m_cfg.kDF = 1; + psb->m_cfg.kDP = 0.001; // fun factor... + psb->m_cfg.kPR = 2500; + psb->setTotalMass(30,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + Ctor_BigPlate(pdemo); + Ctor_LinearStair(pdemo,btVector3(0,0,0),btVector3(2,1,5),0,10); + pdemo->m_autocam=true; + +} + +// +// Volume conservation +// +static void Init_Volume(SoftDemo* pdemo) +{ + //TRACEDEMO + btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0), + btVector3(1,1,1)*3, + 512); + psb->m_materials[0]->m_kLST = 0.45; + psb->m_cfg.kVC = 20; + psb->setTotalMass(50,true); + psb->setPose(true,false); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + Ctor_BigPlate(pdemo); + Ctor_LinearStair(pdemo,btVector3(0,0,0),btVector3(2,1,5),0,10); + pdemo->m_autocam=true; + +} + +// +// Stick+Bending+Rb's +// +static void Init_Sticks(SoftDemo* pdemo) +{ + //TRACEDEMO + const int n=16; + const int sg=4; + const btScalar sz=5; + const btScalar hg=4; + const btScalar in=1/(btScalar)(n-1); + for(int y=0;ym_softBodyWorldInfo, org, + org+btVector3(hg*0.001,hg,0), + sg, + 1); + psb->m_cfg.kDP = 0.005; + psb->m_cfg.kCHR = 0.1; + for(int i=0;i<3;++i) + { + psb->generateBendingConstraints(2+i); + } + psb->setMass(1,0); + psb->setTotalMass(0.01); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + } + } + Ctor_BigBall(pdemo); +} + +// +// Bending +// +static void Init_Bending(SoftDemo* pdemo) +{ + //TRACEDEMO + const btScalar s=4; + const btVector3 x[]={ btVector3(-s,0,-s), + btVector3(+s,0,-s), + btVector3(+s,0,+s), + btVector3(-s,0,+s)}; + const btScalar m[]={ 0,0,0,1}; + btSoftBody* psb=new btSoftBody(&pdemo->m_softBodyWorldInfo,4,x,m); + psb->appendLink(0,1); + psb->appendLink(1,2); + psb->appendLink(2,3); + psb->appendLink(3,0); + psb->appendLink(0,2); + + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); +} + +// +// 100kg cloth locked at corners, 10 falling 10kg rb's. +// +static void Init_Cloth(SoftDemo* pdemo) +{ + //TRACEDEMO + const btScalar s=8; + btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s), + btVector3(+s,0,-s), + btVector3(-s,0,+s), + btVector3(+s,0,+s), + 31,31, + // 31,31, + 1+2+4+8,true); + + psb->getCollisionShape()->setMargin(0.5); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 0.4; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->setTotalMass(150); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + Ctor_RbUpStack(pdemo,10); + pdemo->m_cutting=true; +} + +// +// 100kg Stanford's bunny +// +static void Init_Bunny(SoftDemo* pdemo) +{ + //TRACEDEMO + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny, + &gIndicesBunny[0][0], + BUNNY_NUM_TRIANGLES); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 0.5; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->m_cfg.piterations = 2; + psb->m_cfg.kDF = 0.5; + psb->randomizeConstraints(); + psb->scale(btVector3(6,6,6)); + psb->setTotalMass(100,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + pdemo->m_cutting=true; + +} + +// +// 100kg Stanford's bunny with pose matching +// +static void Init_BunnyMatch(SoftDemo* pdemo) +{ + //TRACEDEMO + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVerticesBunny, + &gIndicesBunny[0][0], + BUNNY_NUM_TRIANGLES); + psb->m_cfg.kDF = 0.5; + psb->m_cfg.kMT = 0.05; + psb->m_cfg.piterations = 5; + psb->randomizeConstraints(); + psb->scale(btVector3(6,6,6)); + psb->setTotalMass(100,true); + psb->setPose(false,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + +} + +// +// 50Kg Torus +// +static void Init_Torus(SoftDemo* pdemo) +{ + //TRACEDEMO + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh( pdemo->m_softBodyWorldInfo, gVertices, + &gIndices[0][0], + NUM_TRIANGLES); + psb->generateBendingConstraints(2); + psb->m_cfg.piterations=2; + psb->randomizeConstraints(); + btMatrix3x3 m; + m.setEulerZYX(SIMD_PI/2,0,0); + psb->transform(btTransform(m,btVector3(0,4,0))); + psb->scale(btVector3(2,2,2)); + psb->setTotalMass(50,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + pdemo->m_cutting=true; + + +} + +// +// 50Kg Torus with pose matching +// +static void Init_TorusMatch(SoftDemo* pdemo) +{ + //TRACEDEMO + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVertices, + &gIndices[0][0], + NUM_TRIANGLES); + psb->m_materials[0]->m_kLST = 0.1; + psb->m_cfg.kMT = 0.05; + psb->randomizeConstraints(); + btMatrix3x3 m; + m.setEulerZYX(SIMD_PI/2,0,0); + psb->transform(btTransform(m,btVector3(0,4,0))); + psb->scale(btVector3(2,2,2)); + psb->setTotalMass(50,true); + psb->setPose(false,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); +} + +// +// Cutting1 +// +static void Init_Cutting1(SoftDemo* pdemo) +{ + const btScalar s=6; + const btScalar h=2; + const int r=16; + const btVector3 p[]={ btVector3(+s,h,-s), + btVector3(-s,h,-s), + btVector3(+s,h,+s), + btVector3(-s,h,+s)}; + btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,p[0],p[1],p[2],p[3],r,r,1+2+4+8,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + psb->m_cfg.piterations=1; + pdemo->m_cutting=true; +} + +// +// Clusters +// + +// +static void Ctor_Gear(SoftDemo* pdemo,const btVector3& pos,btScalar speed) +{ + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(pos); + btCompoundShape* shape=new btCompoundShape(); +#if 1 + shape->addChildShape(btTransform(btQuaternion(0,0,0)),new btBoxShape(btVector3(5,1,6))); + shape->addChildShape(btTransform(btQuaternion(0,0,SIMD_HALF_PI)),new btBoxShape(btVector3(5,1,6))); +#else + shape->addChildShape(btTransform(btQuaternion(0,0,0)),new btCylinderShapeZ(btVector3(5,1,7))); + shape->addChildShape(btTransform(btQuaternion(0,0,SIMD_HALF_PI)),new btBoxShape(btVector3(4,1,8))); +#endif + btRigidBody* body=pdemo->localCreateRigidBody(10,startTransform,shape); + body->setFriction(1); + btDynamicsWorld* world=pdemo->getDynamicsWorld(); + btHingeConstraint* hinge=new btHingeConstraint(*body,btTransform::getIdentity()); + if(speed!=0) hinge->enableAngularMotor(true,speed,3); + world->addConstraint(hinge); +} + +// +static btSoftBody* Ctor_ClusterBunny(SoftDemo* pdemo,const btVector3& x,const btVector3& a) +{ + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,&gIndicesBunny[0][0],BUNNY_NUM_TRIANGLES); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 1; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->m_cfg.piterations = 2; + psb->m_cfg.kDF = 1; + psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ + btSoftBody::fCollision::CL_RS; + psb->randomizeConstraints(); + btMatrix3x3 m; + m.setEulerZYX(a.x(),a.y(),a.z()); + psb->transform(btTransform(m,x)); + psb->scale(btVector3(8,8,8)); + psb->setTotalMass(150,true); + psb->generateClusters(1); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + return(psb); +} + +// +static btSoftBody* Ctor_ClusterTorus(SoftDemo* pdemo,const btVector3& x,const btVector3& a,const btVector3& s=btVector3(2,2,2)) +{ + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices,&gIndices[0][0],NUM_TRIANGLES); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 1; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->m_cfg.piterations = 2; + psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ + btSoftBody::fCollision::CL_RS; + psb->randomizeConstraints(); + psb->scale(s); + psb->rotate(btQuaternion(a[0],a[1],a[2])); + psb->translate(x); + psb->setTotalMass(50,true); + psb->generateClusters(64); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + return(psb); +} + +// +static struct MotorControl : btSoftBody::AJoint::IControl +{ + MotorControl() + { + goal=0; + maxtorque=0; + } + btScalar Speed(btSoftBody::AJoint*,btScalar current) + { + return(current+btMin(maxtorque,btMax(-maxtorque,goal-current))); + } + btScalar goal; + btScalar maxtorque; +} motorcontrol; + +// +struct SteerControl : btSoftBody::AJoint::IControl +{ + SteerControl(btScalar s) + { + angle=0; + sign=s; + } + void Prepare(btSoftBody::AJoint* joint) + { + joint->m_refs[0][0]=btCos(angle*sign); + joint->m_refs[0][2]=btSin(angle*sign); + } + btScalar Speed(btSoftBody::AJoint* joint,btScalar current) + { + return(motorcontrol.Speed(joint,current)); + } + btScalar angle; + btScalar sign; +}; + +static SteerControl steercontrol_f(+1); +static SteerControl steercontrol_r(-1); + +// +static void Init_ClusterDeform(SoftDemo* pdemo) +{ + btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,0,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI)); + psb->generateClusters(8); + psb->m_cfg.kDF=1; +} + +// +static void Init_ClusterCollide1(SoftDemo* pdemo) +{ + const btScalar s=8; + btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s), + btVector3(+s,0,-s), + btVector3(-s,0,+s), + btVector3(+s,0,+s), + 17,17,//9,9,//31,31, + 1+2+4+8, + true); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_kLST = 0.4; + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->m_cfg.kDF = 1; + psb->m_cfg.kSRHR_CL = 1; + psb->m_cfg.kSR_SPLT_CL = 0; + psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ + + btSoftBody::fCollision::CL_RS; + psb->generateBendingConstraints(2,pm); + + psb->getCollisionShape()->setMargin(0.05); + psb->setTotalMass(50); + + ///pass zero in generateClusters to create cluster for each tetrahedron or triangle + psb->generateClusters(0); + //psb->generateClusters(64); + + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + + Ctor_RbUpStack(pdemo,10); +} + +// +static void Init_ClusterCollide2(SoftDemo* pdemo) +{ + struct Functor + { + static btSoftBody* Create(SoftDemo* pdemo,const btVector3& x,const btVector3& a) + { + btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices, + &gIndices[0][0], + NUM_TRIANGLES); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); + psb->m_cfg.piterations=2; + psb->m_cfg.kDF =1; + psb->m_cfg.kSSHR_CL =1; + psb->m_cfg.kSS_SPLT_CL =0; + psb->m_cfg.kSKHR_CL =0.1f; + psb->m_cfg.kSK_SPLT_CL =1; + psb->m_cfg.collisions= btSoftBody::fCollision::CL_SS+ + btSoftBody::fCollision::CL_RS; + psb->randomizeConstraints(); + btMatrix3x3 m; + m.setEulerZYX(a.x(),a.y(),a.z()); + psb->transform(btTransform(m,x)); + psb->scale(btVector3(2,2,2)); + psb->setTotalMass(50,true); + psb->generateClusters(16); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + return(psb); + } + }; + for(int i=0;i<3;++i) + { + Functor::Create(pdemo,btVector3(3*i,2,0),btVector3(SIMD_PI/2*(1-(i&1)),SIMD_PI/2*(i&1),0)); + } +} + +// +static void Init_ClusterSocket(SoftDemo* pdemo) +{ + btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,0,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI)); + btRigidBody* prb=Ctor_BigPlate(pdemo,50,8); + psb->m_cfg.kDF=1; + btSoftBody::LJoint::Specs lj; + lj.position = btVector3(0,5,0); + psb->appendLinearJoint(lj,prb); +} + +// +static void Init_ClusterHinge(SoftDemo* pdemo) +{ + btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,0,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI)); + btRigidBody* prb=Ctor_BigPlate(pdemo,50,8); + psb->m_cfg.kDF=1; + btSoftBody::AJoint::Specs aj; + aj.axis = btVector3(0,0,1); + psb->appendAngularJoint(aj,prb); +} + +// +static void Init_ClusterCombine(SoftDemo* pdemo) +{ + const btVector3 sz(2,4,2); + btSoftBody* psb0=Ctor_ClusterTorus(pdemo,btVector3(0,8,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI),sz); + btSoftBody* psb1=Ctor_ClusterTorus(pdemo,btVector3(0,8,10),btVector3(SIMD_PI/2,0,SIMD_HALF_PI),sz); + btSoftBody* psbs[]={psb0,psb1}; + for(int j=0;j<2;++j) + { + psbs[j]->m_cfg.kDF=1; + psbs[j]->m_cfg.kDP=0; + psbs[j]->m_cfg.piterations=1; + psbs[j]->m_clusters[0]->m_matching = 0.05; + psbs[j]->m_clusters[0]->m_ndamping = 0.05; + } + btSoftBody::AJoint::Specs aj; + aj.axis = btVector3(0,0,1); + aj.icontrol = &motorcontrol; + psb0->appendAngularJoint(aj,psb1); + + btSoftBody::LJoint::Specs lj; + lj.position = btVector3(0,8,5); + psb0->appendLinearJoint(lj,psb1); +} + +// +static void Init_ClusterCar(SoftDemo* pdemo) +{ + pdemo->setAzi(180); + const btVector3 origin(100,80,0); + const btQuaternion orientation(-SIMD_PI/2,0,0); + const btScalar widthf=8; + const btScalar widthr=9; + const btScalar length=8; + const btScalar height=4; + const btVector3 wheels[]= { + btVector3(+widthf,-height,+length), // Front left + btVector3(-widthf,-height,+length), // Front right + btVector3(+widthr,-height,-length), // Rear left + btVector3(-widthr,-height,-length), // Rear right + }; + btSoftBody* pa=Ctor_ClusterBunny(pdemo,btVector3(0,0,0),btVector3(0,0,0)); + btSoftBody* pfl=Ctor_ClusterTorus(pdemo,wheels[0],btVector3(0,0,SIMD_HALF_PI),btVector3(2,4,2)); + btSoftBody* pfr=Ctor_ClusterTorus(pdemo,wheels[1],btVector3(0,0,SIMD_HALF_PI),btVector3(2,4,2)); + btSoftBody* prl=Ctor_ClusterTorus(pdemo,wheels[2],btVector3(0,0,SIMD_HALF_PI),btVector3(2,5,2)); + btSoftBody* prr=Ctor_ClusterTorus(pdemo,wheels[3],btVector3(0,0,SIMD_HALF_PI),btVector3(2,5,2)); + + pfl->m_cfg.kDF = + pfr->m_cfg.kDF = + prl->m_cfg.kDF = + prr->m_cfg.kDF = 1; + + btSoftBody::LJoint::Specs lspecs; + lspecs.cfm = 1; + lspecs.erp = 1; + lspecs.position = btVector3(0,0,0); + + lspecs.position=wheels[0];pa->appendLinearJoint(lspecs,pfl); + lspecs.position=wheels[1];pa->appendLinearJoint(lspecs,pfr); + lspecs.position=wheels[2];pa->appendLinearJoint(lspecs,prl); + lspecs.position=wheels[3];pa->appendLinearJoint(lspecs,prr); + + btSoftBody::AJoint::Specs aspecs; + aspecs.cfm = 1; + aspecs.erp = 1; + aspecs.axis = btVector3(1,0,0); + + aspecs.icontrol = &steercontrol_f; + pa->appendAngularJoint(aspecs,pfl); + pa->appendAngularJoint(aspecs,pfr); + + aspecs.icontrol = &motorcontrol; + pa->appendAngularJoint(aspecs,prl); + pa->appendAngularJoint(aspecs,prr); + + pa->rotate(orientation); + pfl->rotate(orientation); + pfr->rotate(orientation); + prl->rotate(orientation); + prr->rotate(orientation); + pa->translate(origin); + pfl->translate(origin); + pfr->translate(origin); + prl->translate(origin); + prr->translate(origin); + pfl->m_cfg.piterations = + pfr->m_cfg.piterations = + prl->m_cfg.piterations = + prr->m_cfg.piterations = 1; + pfl->m_clusters[0]->m_matching = + pfr->m_clusters[0]->m_matching = + prl->m_clusters[0]->m_matching = + prr->m_clusters[0]->m_matching = 0.05; + pfl->m_clusters[0]->m_ndamping = + pfr->m_clusters[0]->m_ndamping = + prl->m_clusters[0]->m_ndamping = + prr->m_clusters[0]->m_ndamping = 0.05; + + Ctor_LinearStair(pdemo,btVector3(0,-8,0),btVector3(3,2,40),0,20); + Ctor_RbUpStack(pdemo,50); + pdemo->m_autocam=true; + +} + +// +static void Init_ClusterRobot(SoftDemo* pdemo) +{ + struct Functor + { + static btSoftBody* CreateBall(SoftDemo* pdemo,const btVector3& pos) + { + btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,pos,btVector3(1,1,1)*3,512); + psb->m_materials[0]->m_kLST = 0.45; + psb->m_cfg.kVC = 20; + psb->setTotalMass(50,true); + psb->setPose(true,false); + psb->generateClusters(1); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + return(psb); + } + }; + const btVector3 base=btVector3(0,25,8); + btSoftBody* psb0=Functor::CreateBall(pdemo,base+btVector3(-8,0,0)); + btSoftBody* psb1=Functor::CreateBall(pdemo,base+btVector3(+8,0,0)); + btSoftBody* psb2=Functor::CreateBall(pdemo,base+btVector3(0,0,+8*btSqrt(2))); + const btVector3 ctr=(psb0->clusterCom(0)+psb1->clusterCom(0)+psb2->clusterCom(0))/3; + btCylinderShape* pshp=new btCylinderShape(btVector3(8,1,8)); + btRigidBody* prb=pdemo->localCreateRigidBody(50,btTransform(btQuaternion(0,0,0),ctr+btVector3(0,5,0)),pshp); + btSoftBody::LJoint::Specs ls; + ls.erp=0.5f; + ls.position=psb0->clusterCom(0);psb0->appendLinearJoint(ls,prb); + ls.position=psb1->clusterCom(0);psb1->appendLinearJoint(ls,prb); + ls.position=psb2->clusterCom(0);psb2->appendLinearJoint(ls,prb); + + btBoxShape* pbox=new btBoxShape(btVector3(20,1,40)); + btRigidBody* pgrn=pdemo->localCreateRigidBody(0,btTransform(btQuaternion(0,-SIMD_HALF_PI/2,0),btVector3(0,0,0)),pbox); + + pdemo->m_autocam=true; + +} + +// +static void Init_ClusterStackSoft(SoftDemo* pdemo) +{ + for(int i=0;i<10;++i) + { + btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,-9+8.25*i,0),btVector3(0,0,0)); + psb->m_cfg.kDF=1; + } +} + +// +static void Init_ClusterStackMixed(SoftDemo* pdemo) +{ + for(int i=0;i<10;++i) + { + if((i+1)&1) + { + Ctor_BigPlate(pdemo,50,-9+4.25*i); + } + else + { + btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,-9+4.25*i,0),btVector3(0,0,0)); + psb->m_cfg.kDF=1; + } + } +} + + +// +// TetraBunny +// +static void Init_TetraBunny(SoftDemo* pdemo) +{ + btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo, + TetraBunny::getElements(), + 0, + TetraBunny::getNodes(), + false,true,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + psb->rotate(btQuaternion(SIMD_PI/2,0,0)); + psb->setVolumeMass(150); + psb->m_cfg.piterations=2; + //psb->m_cfg.piterations=1; + pdemo->m_cutting=false; + //psb->getCollisionShape()->setMargin(0.01); + psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS + //+ btSoftBody::fCollision::CL_SELF + ; + + ///pass zero in generateClusters to create cluster for each tetrahedron or triangle + psb->generateClusters(0); + //psb->m_materials[0]->m_kLST=.2; + psb->m_cfg.kDF = 10. ; + + +} + +// +// TetraCube +// +static void Init_TetraCube(SoftDemo* pdemo) +{ + btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo, + TetraCube::getElements(), + 0, + TetraCube::getNodes(), + false,true,true); + pdemo->getSoftDynamicsWorld()->addSoftBody(psb); + psb->scale(btVector3(4,4,4)); + psb->translate(btVector3(0,5,0)); + psb->setVolumeMass(300); + + + ///fix one vertex + //psb->setMass(0,0); + //psb->setMass(10,0); + //psb->setMass(20,0); + psb->m_cfg.piterations=1; + //psb->generateClusters(128); + psb->generateClusters(16); + //psb->getCollisionShape()->setMargin(0.5); + + psb->getCollisionShape()->setMargin(0.01); + psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS + //+ btSoftBody::fCollision::CL_SELF + ; + psb->m_materials[0]->m_kLST=0.8; + pdemo->m_cutting=false; +} + + + + + + /* Init */ + void (*demofncs[])(SoftDemo*)= + { + Init_Cloth, + Init_Pressure, + Init_Volume, + Init_Ropes, + Init_RopeAttach, + Init_ClothAttach, + Init_Sticks, + Init_CapsuleCollision, + Init_Collide, + Init_Collide2, + Init_Collide3, + Init_Impact, + Init_Aero, + Init_Aero2, + Init_Friction, + Init_Torus, + Init_TorusMatch, + Init_Bunny, + Init_BunnyMatch, + Init_Cutting1, + Init_ClusterDeform, + Init_ClusterCollide1, + Init_ClusterCollide2, + Init_ClusterSocket, + Init_ClusterHinge, + Init_ClusterCombine, + Init_ClusterCar, + Init_ClusterRobot, + Init_ClusterStackSoft, + Init_ClusterStackMixed, + Init_TetraCube, + Init_TetraBunny, + }; + +void SoftDemo::clientResetScene() +{ + m_azi = 0; + m_cameraDistance = 30.f; + m_cameraTargetPosition.setValue(0,0,0); + + DemoApplication::clientResetScene(); + /* Clean up */ + for(int i=m_dynamicsWorld->getNumCollisionObjects()-1;i>=0;i--) + { + btCollisionObject* obj=m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body=btRigidBody::upcast(obj); + if(body&&body->getMotionState()) + { + delete body->getMotionState(); + } + while(m_dynamicsWorld->getNumConstraints()) + { + btTypedConstraint* pc=m_dynamicsWorld->getConstraint(0); + m_dynamicsWorld->removeConstraint(pc); + delete pc; + } + btSoftBody* softBody = btSoftBody::upcast(obj); + if (softBody) + { + getSoftDynamicsWorld()->removeSoftBody(softBody); + } else + { + btRigidBody* body = btRigidBody::upcast(obj); + if (body) + m_dynamicsWorld->removeRigidBody(body); + else + m_dynamicsWorld->removeCollisionObject(obj); + } + delete obj; + } + + + //create ground object + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(0,-12,0)); + + btCollisionObject* newOb = new btCollisionObject(); + newOb->setWorldTransform(tr); + newOb->setInterpolationWorldTransform( tr); + int lastDemo = (sizeof(demofncs)/sizeof(demofncs[0]))-1; + + if (current_demo<0) + current_demo = lastDemo; + if (current_demo > lastDemo) + current_demo =0; + + + if (current_demo>19) + { + newOb->setCollisionShape(m_collisionShapes[0]); + } else + { + newOb->setCollisionShape(m_collisionShapes[1]); + } + + m_dynamicsWorld->addCollisionObject(newOb); + + m_softBodyWorldInfo.m_sparsesdf.Reset(); + + + + + + + + motorcontrol.goal = 0; + motorcontrol.maxtorque = 0; + + + + m_softBodyWorldInfo.air_density = (btScalar)1.2; + m_softBodyWorldInfo.water_density = 0; + m_softBodyWorldInfo.water_offset = 0; + m_softBodyWorldInfo.water_normal = btVector3(0,0,0); + m_softBodyWorldInfo.m_gravity.setValue(0,-10,0); + + + m_autocam = false; + m_raycast = false; + m_cutting = false; + m_results.fraction = 1.f; + demofncs[current_demo](this); +} + + +void SoftDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + + + + + float ms = getDeltaTimeMicroseconds(); + float dt = ms / 1000000.f;//1.0/60.; + + + + if (m_dynamicsWorld) + { + + if (sDemoMode) + { + static float demoCounter = DEMO_MODE_TIMEOUT; + demoCounter-= dt; + if (demoCounter<0) + { + + demoCounter=DEMO_MODE_TIMEOUT; + current_demo++; + current_demo=current_demo%(sizeof(demofncs)/sizeof(demofncs[0])); + clientResetScene(); + } + } + + +//#define FIXED_STEP +#ifdef FIXED_STEP + m_dynamicsWorld->stepSimulation(dt=1.0f/60.f,0); + +#else + //during idle mode, just run 1 simulation step maximum, otherwise 4 at max + // int maxSimSubSteps = m_idle ? 1 : 4; + //if (m_idle) + // dt = 1.0/420.f; + + int numSimSteps; + numSimSteps = m_dynamicsWorld->stepSimulation(dt); + //numSimSteps = m_dynamicsWorld->stepSimulation(dt,10,1./240.f); + +#ifdef VERBOSE_TIMESTEPPING_CONSOLEOUTPUT + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } +#endif //VERBOSE_TIMESTEPPING_CONSOLEOUTPUT + +#endif + +#ifdef USE_AMD_OPENCL + if (g_openCLSIMDSolver) + g_openCLSIMDSolver->copyBackToSoftBodies(); +#endif //USE_AMD_OPENCL + + if(m_drag) + { + m_node->m_v*=0; + } + + m_softBodyWorldInfo.m_sparsesdf.GarbageCollect(); + + //optional but useful: debug drawing + + } + +#ifdef USE_QUICKPROF + btProfiler::beginBlock("render"); +#endif //USE_QUICKPROF + + renderme(); + + //render the graphics objects, with center of mass shift + + updateCamera(); + + + +#ifdef USE_QUICKPROF + btProfiler::endBlock("render"); +#endif + glFlush(); + //some additional debugging info +#ifdef PRINT_CONTACT_STATISTICS + printf("num manifolds: %i\n",gNumManifold); + printf("num gOverlappingPairs: %i\n",gOverlappingPairs); + +#endif //PRINT_CONTACT_STATISTICS + + + swapBuffers(); + +} + + + +void SoftDemo::renderme() +{ + btIDebugDraw* idraw=m_dynamicsWorld->getDebugDrawer(); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + m_dynamicsWorld->debugDrawWorld(); + + //int debugMode = m_dynamicsWorld->getDebugDrawer()? m_dynamicsWorld->getDebugDrawer()->getDebugMode() : -1; + + btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld; + //btIDebugDraw* sdraw = softWorld ->getDebugDrawer(); + + + for ( int i=0;igetSoftBodyArray().size();i++) + { + btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i]; + if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) + { + btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags()); + } + } + + /* Bodies */ + btVector3 ps(0,0,0); + int nps=0; + + btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray(); + for(int ib=0;ibm_nodes.size(); + for(int i=0;im_nodes.size();++i) + { + ps+=psb->m_nodes[i].m_x; + } + } + ps/=nps; + if(m_autocam) + m_cameraTargetPosition+=(ps-m_cameraTargetPosition)*0.05; + /* Anm */ + if(!isIdle()) + m_animtime=m_clock.getTimeMilliseconds()/1000.f; + /* Ray cast */ + if(m_raycast) + { + /* Prepare rays */ + const int res=64; + const btScalar fres=res-1; + const btScalar size=8; + const btScalar dist=10; + btTransform trs; + trs.setOrigin(ps); + btScalar rayLength = 1000.f; + + const btScalar angle=m_animtime*0.2; + trs.setRotation(btQuaternion(angle,SIMD_PI/4,0)); + btVector3 dir=trs.getBasis()*btVector3(0,-1,0); + trs.setOrigin(ps-dir*dist); + btAlignedObjectArray origins; + btAlignedObjectArray fractions; + origins.resize(res*res); + fractions.resize(res*res,1.f); + for(int y=0;yrayTest(rayFrom,rayTo,results)) + { + *fraction=results.fraction; + } + } + ++org;++fraction; + } + long ms=btMax(m_clock.getTimeMilliseconds(),1); + long rayperseconds=(1000*(origins.size()*sbs.size()))/ms; + printf("%d ms (%d rays/s)\r\n",int(ms),int(rayperseconds)); + } + } + /* Draw rays */ + const btVector3 c[]={ origins[0], + origins[res-1], + origins[res*(res-1)], + origins[res*(res-1)+res-1]}; + idraw->drawLine(c[0],c[1],btVector3(0,0,0)); + idraw->drawLine(c[1],c[3],btVector3(0,0,0)); + idraw->drawLine(c[3],c[2],btVector3(0,0,0)); + idraw->drawLine(c[2],c[0],btVector3(0,0,0)); + for(int i=0,ni=origins.size();idrawLine(org,org+dir*rayLength*fraction,btVector3(1,0,0)); + } + else + { + idraw->drawLine(org,org-dir*rayLength*0.1,btVector3(0,0,0)); + } + } +#undef RES + } + /* Water level */ + static const btVector3 axis[]={btVector3(1,0,0), + btVector3(0,1,0), + btVector3(0,0,1)}; + if(m_softBodyWorldInfo.water_density>0) + { + const btVector3 c= btVector3((btScalar)0.25,(btScalar)0.25,1); + const btScalar a= (btScalar)0.5; + const btVector3 n= m_softBodyWorldInfo.water_normal; + const btVector3 o= -n*m_softBodyWorldInfo.water_offset; + const btVector3 x= btCross(n,axis[n.minAxis()]).normalized(); + const btVector3 y= btCross(x,n).normalized(); + const btScalar s= 25; + idraw->drawTriangle(o-x*s-y*s,o+x*s-y*s,o+x*s+y*s,c,a); + idraw->drawTriangle(o-x*s-y*s,o+x*s+y*s,o-x*s+y*s,c,a); + } + // + + int lineWidth=280; + int xStart = m_glutScreenWidth - lineWidth; + int yStart = 20; + + if((getDebugMode() & btIDebugDraw::DBG_NoHelpText)==0) + { + setOrthographicProjection(); + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + char buf[124]; + + glRasterPos3f(xStart, yStart, 0); + if (sDemoMode) + { + sprintf(buf,"d to toggle demo mode (on)"); + } else + { + sprintf(buf,"d to toggle demo mode (off)"); + } + GLDebugDrawString(xStart,20,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"] for next demo (%d)",current_demo); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"c to visualize clusters"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"; to toggle camera mode"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"n,m,l,k for power and steering"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + + + resetPerspectiveProjection(); + glEnable(GL_LIGHTING); + } + + DemoApplication::renderme(); + +} + +void SoftDemo::setDrawClusters(bool drawClusters) +{ + if (drawClusters) + { + getSoftDynamicsWorld()->setDrawFlags(getSoftDynamicsWorld()->getDrawFlags()|fDrawFlags::Clusters); + } else + { + getSoftDynamicsWorld()->setDrawFlags(getSoftDynamicsWorld()->getDrawFlags()& (~fDrawFlags::Clusters)); + } +} + + + +void SoftDemo::keyboardCallback(unsigned char key, int x, int y) +{ + switch(key) + { + case 'd': sDemoMode = !sDemoMode; break; + case 'n': motorcontrol.maxtorque=10;motorcontrol.goal+=1;break; + case 'm': motorcontrol.maxtorque=10;motorcontrol.goal-=1;break; + case 'l': steercontrol_f.angle+=0.1;steercontrol_r.angle+=0.1;break; + case 'k': steercontrol_f.angle-=0.1;steercontrol_r.angle-=0.1;break; + case ']': ++current_demo;clientResetScene();break; + case '[': --current_demo;clientResetScene();break; + case ',': m_raycast=!m_raycast;break; + case ';': m_autocam=!m_autocam;break; + case 'c': getSoftDynamicsWorld()->setDrawFlags(getSoftDynamicsWorld()->getDrawFlags()^fDrawFlags::Clusters);break; + case '`': + { + btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray(); + for(int ib=0;ibstaticSolve(128); + } + } + break; + default: DemoApplication::keyboardCallback(key,x,y); + } +} + +// +void SoftDemo::mouseMotionFunc(int x,int y) +{ + if(m_node&&(m_results.fraction<1.f)) + { + if(!m_drag) + { +#define SQ(_x_) (_x_)*(_x_) + if((SQ(x-m_lastmousepos[0])+SQ(y-m_lastmousepos[1]))>6) + { + m_drag=true; + } +#undef SQ + } + if(m_drag) + { + m_lastmousepos[0] = x; + m_lastmousepos[1] = y; + } + } + else + { + DemoApplication::mouseMotionFunc(x,y); + } +} + +// +void SoftDemo::mouseFunc(int button, int state, int x, int y) +{ + if(button==0) + { + switch(state) + { + case 0: + { + m_results.fraction=1.f; + DemoApplication::mouseFunc(button,state,x,y); + if(!m_pickConstraint) + { + const btVector3 rayFrom=m_cameraPosition; + const btVector3 rayTo=getRayTo(x,y); + const btVector3 rayDir=(rayTo-rayFrom).normalized(); + btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray(); + for(int ib=0;ibrayTest(rayFrom,rayTo,res)) + { + m_results=res; + } + } + if(m_results.fraction<1.f) + { + m_impact = rayFrom+(rayTo-rayFrom)*m_results.fraction; + m_drag = m_cutting ? false : true; + m_lastmousepos[0] = x; + m_lastmousepos[1] = y; + m_node = 0; + switch(m_results.feature) + { + case btSoftBody::eFeature::Tetra: + { + btSoftBody::Tetra& tet=m_results.body->m_tetras[m_results.index]; + m_node=tet.m_n[0]; + for(int i=1;i<4;++i) + { + if( (m_node->m_x-m_impact).length2()> + (tet.m_n[i]->m_x-m_impact).length2()) + { + m_node=tet.m_n[i]; + } + } + break; + } + case btSoftBody::eFeature::Face: + { + btSoftBody::Face& f=m_results.body->m_faces[m_results.index]; + m_node=f.m_n[0]; + for(int i=1;i<3;++i) + { + if( (m_node->m_x-m_impact).length2()> + (f.m_n[i]->m_x-m_impact).length2()) + { + m_node=f.m_n[i]; + } + } + } + break; + } + if(m_node) m_goal=m_node->m_x; + return; + } + } + } + break; + case 1: + if((!m_drag)&&m_cutting&&(m_results.fraction<1.f)) + { + ImplicitSphere isphere(m_impact,1); + printf("Mass before: %f\r\n",m_results.body->getTotalMass()); + m_results.body->refine(&isphere,0.0001,true); + printf("Mass after: %f\r\n",m_results.body->getTotalMass()); + } + m_results.fraction=1.f; + m_drag=false; + DemoApplication::mouseFunc(button,state,x,y); + break; + } + } + else + { + DemoApplication::mouseFunc(button,state,x,y); + } +} + + +void SoftDemo::initPhysics() +{ + ///create concave ground mesh + + + m_azi = 0; + + //reset and disable motorcontrol at the start + motorcontrol.goal = 0; + motorcontrol.maxtorque = 0; + + btCollisionShape* groundShape = 0; + { + int i; + int j; + + const int NUM_VERTS_X = 30; + const int NUM_VERTS_Y = 30; + const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + + gGroundVertices = new btVector3[totalVerts]; + gGroundIndices = new int[totalTriangles*3]; + + btScalar offset(-50); + + for ( i=0;isetMargin(0.5); + } + + m_collisionShapes.push_back(groundShape); + + btCollisionShape* groundBox = new btBoxShape (btVector3(100,CUBE_HALF_EXTENTS,100)); + m_collisionShapes.push_back(groundBox); + + btCompoundShape* cylinderCompound = new btCompoundShape; + btCollisionShape* cylinderShape = new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); + btTransform localTransform; + localTransform.setIdentity(); + cylinderCompound->addChildShape(localTransform,cylinderShape); + btQuaternion orn(btVector3(0,1,0),SIMD_PI); + localTransform.setRotation(orn); + cylinderCompound->addChildShape(localTransform,cylinderShape); + + m_collisionShapes.push_back(cylinderCompound); + + + m_dispatcher=0; + + ///register some softbody collision algorithms on top of the default btDefaultCollisionConfiguration + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_softBodyWorldInfo.m_dispatcher = m_dispatcher; + + //////////////////////////// + ///Register softbody versus softbody collision algorithm + + + ///Register softbody versus rigidbody collision algorithm + + + //////////////////////////// + + btVector3 worldAabbMin(-1000,-1000,-1000); + btVector3 worldAabbMax(1000,1000,1000); + + m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); + + m_softBodyWorldInfo.m_broadphase = m_broadphase; + + btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); + + m_solver = solver; + + btSoftBodySolver* softBodySolver = 0; +#ifdef USE_AMD_OPENCL + + static bool once = true; + if (once) + { + once=false; + initCL(0,0); + } + + if( g_openCLSIMDSolver ) + delete g_openCLSIMDSolver; + if( g_softBodyOutput ) + delete g_softBodyOutput; + + if (1) + { + g_openCLSIMDSolver = new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue, g_cxMainContext); + // g_openCLSIMDSolver = new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext); + g_openCLSIMDSolver->setCLFunctions(new CachingCLFunctions(g_cqCommandQue, g_cxMainContext)); + } + + + + softBodySolver = g_openCLSIMDSolver; + g_softBodyOutput = new btSoftBodySolverOutputCLtoCPU; +#endif //USE_AMD_OPENCL + + btDiscreteDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration,softBodySolver); + m_dynamicsWorld = world; + m_dynamicsWorld->setInternalTickCallback(pickingPreTickCallback,this,true); + + + m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + m_softBodyWorldInfo.m_gravity.setValue(0,-10,0); + + // clientResetScene(); + + m_softBodyWorldInfo.m_sparsesdf.Initialize(); + clientResetScene(); +} + + + + + + +void SoftDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_SoftSoftCollisionAlgorithms; + + btAlignedObjectArray m_SoftRigidCollisionAlgorithms; + + btSoftBodyWorldInfo m_softBodyWorldInfo; + + + + bool m_autocam; + bool m_cutting; + bool m_raycast; + btScalar m_animtime; + btClock m_clock; + int m_lastmousepos[2]; + btVector3 m_impact; + btSoftBody::sRayCast m_results; + btSoftBody::Node* m_node; + btVector3 m_goal; + bool m_drag; + + + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + + btConstraintSolver* m_solver; + + btCollisionAlgorithmCreateFunc* m_boxBoxCF; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + +public: + + void initPhysics(); + + void exitPhysics(); + + SoftDemo() : m_drag(false) + { + setTexturing(true); + setShadows(true); + } + virtual ~SoftDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + void createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ); + + static DemoApplication* Create() + { + SoftDemo* demo = new SoftDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + virtual void setDrawClusters(bool drawClusters); + + virtual const btSoftRigidDynamicsWorld* getSoftDynamicsWorld() const + { + ///just make it a btSoftRigidDynamicsWorld please + ///or we will add type checking + return (btSoftRigidDynamicsWorld*) m_dynamicsWorld; + } + + virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld() + { + ///just make it a btSoftRigidDynamicsWorld please + ///or we will add type checking + return (btSoftRigidDynamicsWorld*) m_dynamicsWorld; + } + + // + void clientResetScene(); + void renderme(); + void keyboardCallback(unsigned char key, int x, int y); + void mouseFunc(int button, int state, int x, int y); + void mouseMotionFunc(int x,int y); + +}; + +#define MACRO_SOFT_DEMO(a) class SoftDemo##a : public SoftDemo\ +{\ +public:\ + static DemoApplication* Create()\ + {\ + SoftDemo* demo = new SoftDemo##a;\ + extern int current_demo;\ + current_demo=a;\ + demo->myinit();\ + demo->initPhysics();\ + return demo;\ + }\ +}; + + +MACRO_SOFT_DEMO(0) //Init_Cloth +MACRO_SOFT_DEMO(1) //Init_Pressure +MACRO_SOFT_DEMO(2)//Init_Volume +MACRO_SOFT_DEMO(3)//Init_Ropes +MACRO_SOFT_DEMO(4)//Init_Ropes_Attach +MACRO_SOFT_DEMO(5)//Init_ClothAttach +MACRO_SOFT_DEMO(6)//Init_Sticks +MACRO_SOFT_DEMO(7)//Init_Collide +MACRO_SOFT_DEMO(8)//Init_Collide2 +MACRO_SOFT_DEMO(9)//Init_Collide3 +MACRO_SOFT_DEMO(10)//Init_Impact +MACRO_SOFT_DEMO(11)//Init_Aero +MACRO_SOFT_DEMO(12)//Init_Friction +MACRO_SOFT_DEMO(13)//Init_Torus +MACRO_SOFT_DEMO(14)//Init_TorusMatch +MACRO_SOFT_DEMO(15)//Init_Bunny +MACRO_SOFT_DEMO(16)//Init_BunnyMatch +MACRO_SOFT_DEMO(17)//Init_Cutting1 +MACRO_SOFT_DEMO(18)//Init_ClusterDeform +MACRO_SOFT_DEMO(19)//Init_ClusterCollide1 +MACRO_SOFT_DEMO(20)//Init_ClusterCollide2 +MACRO_SOFT_DEMO(21)//Init_ClusterSocket +MACRO_SOFT_DEMO(22)//Init_ClusterHinge +MACRO_SOFT_DEMO(23)//Init_ClusterCombine +MACRO_SOFT_DEMO(24)//Init_ClusterCar +MACRO_SOFT_DEMO(25)//Init_ClusterRobot +MACRO_SOFT_DEMO(26)//Init_ClusterStackSoft +MACRO_SOFT_DEMO(27)//Init_ClusterStackMixed +MACRO_SOFT_DEMO(28)//Init_TetraCube +MACRO_SOFT_DEMO(29)//Init_TetraBunny + + +#endif //CCD_PHYSICS_DEMO_H + + + + + diff --git a/Demos/SoftDemo/bunny.inl b/Demos/SoftDemo/bunny.inl new file mode 100755 index 0000000..fbdbfd3 --- /dev/null +++ b/Demos/SoftDemo/bunny.inl @@ -0,0 +1,4 @@ +static const char* getNodes() { return( +"454 3 0 0\n"" 0 -2.0063499999999999 0.79804200000000003 0.373554\n"" 1 -2.1011299999999999 0.90212400000000004 -0.88661400000000001\n"" 2 -1.4052100000000001 2.0628700000000002 -1.0458400000000001\n"" 3 -1.2015499999999999 1.7112400000000001 0.56249400000000005\n"" 4 0.02112 2.8512499999999998 -0.95618999999999998\n"" 5 0.011136 2.5152199999999998 0.59149200000000002\n"" 6 -1.51681 0.56199600000000005 1.42523\n"" 7 -0.977406 1.4278999999999999 1.24143\n"" 8 0.0051900000000000002 1.9088499999999999 1.41222\n"" 9 -2.4877400000000001 0.98449799999999998 -1.6695199999999999\n"" 10 -1.57328 2.1440000000000001 -1.7594799999999999\n"" 11 0.027768000000000001 2.8961600000000001 -2.0317599999999998\n"" 12 -2.4129700000000001 0.80116799999999999 -2.6594799999999998\n"" 13 -1.46269 1.9456500000000001 -2.6205799999999999\n"" 14 0.031758000000000002 2.6255500000000001 -2.7499899999999999\n"" 15 -2.0392999999999999 -0.24690000000000001 -4.0092699999999999\n"" 16 -1.4902899999999999 1.53495 -3.7649599999999999\n"" 17 0.037566000000000002 2.2566199999999998 -3.78904\n"" 18 -1.29721 -0.760656 -5.3216200000000002\n"" 19 -1.0264500000000001 0.069264000000000006 -5.2883199999999997\n"" 20 -1.0864400000000001 0.58933800000000003 -4.8886700000000003\n"" 21 -0.71934600000000004 1.3127200000000001 -4.5609200000000003\n"" 22 -0.47337000000000001 1.6606799999999999 -4.4356900000000001\n"" 23 0.040806000000000002 1.86575 -4.4139699999999999\n"" 24 -1.01305 0.61432200000000003 -5.5222899999999999\n"" 25 -0.62443199999999999 1.0636699999999999 -5.7151800000000001\n"" 26 -0.77822400000000003 1.2710900000000001 -5.0200699999999996\n"" 27 -0.59924999999999995 1.8655900000000001 -4.7962899999999999\n"" 28 0.043422000000000002 2.1701199999999998 -4.7666300000000001\n"" 29 -0.467478 1.5525199999999999 -5.5298400000000001\n"" 30 0.047742 1.6934499999999999 -5.5900800000000004\n"" 31 -1.5133300000000001 -3.3024100000000001 -3.3468599999999999\n"" 32 -1.6057999999999999 -3.6205099999999999 -3.9312499999999999\n"" 33 -2.6810299999999998 -0.71110200000000001 -2.7969499999999998\n"" 34 -2.7569300000000001 -0.55810199999999999 -1.86805\n"" 35 -2.2238699999999998 -0.60064799999999996 -0.95672400000000002\n"" 36 -2.2319 -0.55194600000000005 -0.066264000000000003\n"" 37 -1.97367 -0.58961399999999997 0.53195400000000004\n"" 38 -1.6947099999999999 -0.11317199999999999 1.8690100000000001\n"" 39 -2.11442 -0.78804600000000002 0.86941199999999996\n"" 40 -2.1847599999999998 -1.2017899999999999 1.2143299999999999\n"" 41 -1.7037899999999999 -1.3912100000000001 0.142008\n"" 42 -1.79366 -0.93130800000000002 2.2183000000000002\n"" 43 -1.7627200000000001 -0.73113600000000001 2.51458\n"" 44 -1.74098 -1.74478 0.64694399999999996\n"" 45 -1.5849899999999999 -1.6370899999999999 0.218082\n"" 46 -1.3714 -2.2354400000000001 1.7418499999999999\n"" 47 -1.14259 -1.7219800000000001 2.5314999999999999\n"" 48 -1.1462300000000001 -1.44584 3.04271\n"" 49 -1.72363 -1.65859 -0.39266400000000001\n"" 50 -1.7740499999999999 -1.6849099999999999 -1.0451999999999999\n"" 51 -2.3972199999999999 -1.87879 -2.2570000000000001\n"" 52 -2.3559999999999999 -2.9314900000000002 -2.5649600000000001\n"" 53 -1.9900100000000001 -3.4211100000000001 -2.7963200000000001\n"" 54 -1.69374 -3.7088399999999999 -3.53532\n"" 55 -2.2454299999999998 -3.5692900000000001 -1.9397899999999999\n"" 56 -2.2864300000000002 -3.77834 -2.10466\n"" 57 -2.2926700000000002 -3.7443599999999999 -1.3294600000000001\n"" 58 -1.6362099999999999 -3.39913 1.55494\n"" 59 -1.5402100000000001 -3.9804400000000002 1.7164699999999999\n"" 60 -1.6856899999999999 -2.5701499999999999 0.33473999999999998\n"" 61 -1.1098399999999999 -3.0533600000000001 1.9575899999999999\n"" 62 -1.6798299999999999 -3.1615099999999998 2.3719100000000002\n"" 63 -1.6955899999999999 -3.9803600000000001 2.4744700000000002\n"" 64 -1.1299699999999999 -2.8505600000000002 2.5077199999999999\n"" 65 -1.5803 -3.9803799999999998 2.79962\n"" 66 -1.2543800000000001 -3.9803600000000001 3.05606\n"" 67 -0.012264000000000001 -1.91774 3.31847\n"" 68 -0.0075960000000000003 -2.22756 2.4797799999999999\n"" 69 -1.3185199999999999 -2.03857 -0.24552599999999999\n"" 70 -1.54192 -1.6950700000000001 -0.038094000000000003\n"" 71 -1.6302399999999999 -1.5652900000000001 0.010584\n"" 72 -0.54714600000000002 -2.5150999999999999 -0.27547199999999999\n"" 73 -0.68966400000000005 -2.5785100000000001 -0.74843400000000004\n"" 74 -0.68381999999999998 -2.29792 -1.13124\n"" 75 -1.45807 -2.78965 -1.4571000000000001\n"" 76 -1.88889 -3.03241 -1.94861\n"" 77 0.016643999999999999 -2.6251600000000002 -1.5766\n"" 78 -0.43575000000000003 -2.5064899999999999 -1.32864\n"" 79 -0.96067199999999997 -2.8615900000000001 -1.7606999999999999\n"" 80 0.023154000000000001 -2.7205499999999998 -2.6635\n"" 81 -0.72217799999999999 -3.4893999999999998 -2.6321300000000001\n"" 82 -0.54899399999999998 -3.50515 -1.7670699999999999\n"" 83 -0.69881400000000005 -3.59917 -1.12985\n"" 84 -1.2481899999999999 -3.0818400000000001 -0.807894\n"" 85 -1.41449 -3.6600999999999999 -0.24563399999999999\n"" 86 -2.0695000000000001 -3.7349199999999998 -0.51227999999999996\n"" 87 -2.0184099999999998 -3.1911800000000001 -1.27379\n"" 88 0.011766 -2.7572999999999999 -0.81328199999999995\n"" 89 -0.34977599999999998 -2.5832199999999998 -0.26063999999999998\n"" 90 0.0082679999999999993 -2.6970700000000001 -0.226572\n"" 91 -0.78081 -3.0613299999999999 0.47486400000000001\n"" 92 0.000852 -2.8652899999999999 0.942384\n"" 93 -0.68570399999999998 -2.7192400000000001 1.8263799999999999\n"" 94 -0.003552 -2.6613500000000001 1.71241\n"" 95 -0.33728999999999998 -3.98041 1.95644\n"" 96 -0.15748799999999999 -3.4080599999999999 1.63991\n"" 97 -0.295566 -3.1863800000000002 2.3391199999999999\n"" 98 -0.76257600000000003 -3.9803899999999999 2.8759000000000001\n"" 99 -0.350304 -3.98041 2.2373500000000002\n"" 100 -1.8237699999999999 0.32519399999999998 3.7555299999999998\n"" 101 -1.6115600000000001 1.16042 3.0165999999999999\n"" 102 -1.6629499999999999 0.75673800000000002 2.6597300000000001\n"" 103 -1.72563 -0.034332000000000001 3.1910599999999998\n"" 104 -1.3883799999999999 -0.72773399999999999 3.5243199999999999\n"" 105 -1.52085 -0.490782 4.53925\n"" 106 -1.1709799999999999 -0.82781400000000005 4.3680700000000003\n"" 107 -1.00604 -0.939438 3.6563300000000001\n"" 108 -0.875502 -1.01417 4.1856\n"" 109 -0.46665600000000002 -1.28548 3.7355200000000002\n"" 110 -0.46123799999999998 -1.28983 4.17781\n"" 111 -0.014045999999999999 -1.3988100000000001 3.7371500000000002\n"" 112 -0.016379999999999999 -1.2811600000000001 4.1475999999999997\n"" 113 -0.018815999999999999 -1.15577 4.57639\n"" 114 -0.336816 -1.20733 4.58284\n"" 115 -0.68753399999999998 -0.99715200000000004 4.6243400000000001\n"" 116 -0.93086999999999998 -0.77779200000000004 4.7504299999999997\n"" 117 -1.1016699999999999 -0.35222999999999999 5.0820699999999999\n"" 118 -0.99337200000000003 0.01188 5.0003200000000003\n"" 119 -1.3205 0.11948400000000001 4.6136100000000004\n"" 120 -1.5343800000000001 0.54183599999999998 4.0246899999999997\n"" 121 -1.53356 0.68299799999999999 3.9803299999999999\n"" 122 -1.3582799999999999 1.27593 3.7064400000000002\n"" 123 -0.020202000000000001 -1.17205 4.7980799999999997\n"" 124 -0.17845800000000001 -1.26305 4.9630799999999997\n"" 125 -0.022908000000000001 -1.1687000000000001 5.2418199999999997\n"" 126 -0.024695999999999999 -0.94744200000000001 5.5876099999999997\n"" 127 -0.18768000000000001 -1.1073299999999999 5.3368599999999997\n"" 128 -0.35931000000000002 -1.10669 5.0479799999999999\n"" 129 -0.811998 -0.98599199999999998 5.2691999999999997\n"" 130 -0.51344400000000001 -1.02569 5.55328\n"" 131 -0.98299800000000004 -0.56501999999999997 5.3826799999999997\n"" 132 -0.83066399999999996 -0.62549999999999994 5.6758499999999996\n"" 133 -0.50098200000000004 -0.50960399999999995 5.8776400000000004\n"" 134 -0.026598 -0.87985199999999997 5.9152300000000002\n"" 135 -0.90429000000000004 0.19589999999999999 5.3046699999999998\n"" 136 -0.81535199999999997 -0.21312 5.6727299999999996\n"" 137 -0.42367199999999999 0.22109400000000001 5.8544\n"" 138 -0.026748000000000001 -0.25515599999999999 6.0940200000000004\n"" 139 -0.025493999999999999 0.276252 6.0194400000000003\n"" 140 -0.521814 0.79934400000000005 5.6858000000000004\n"" 141 -0.023238000000000002 0.96962999999999999 5.8229899999999999\n"" 142 -0.75326400000000004 0.84007200000000004 5.5060700000000002\n"" 143 -0.75390599999999997 1.5014799999999999 5.1456099999999996\n"" 144 -0.018762000000000001 1.70442 5.2732200000000002\n"" 145 -0.955044 0.75435600000000003 5.3332699999999997\n"" 146 -1.10284 1.1818200000000001 5.0668800000000003\n"" 147 -0.95933999999999997 1.7504200000000001 4.3948799999999997\n"" 148 -1.1969700000000001 1.2433799999999999 4.6791799999999997\n"" 149 -1.23709 0.98764799999999997 4.1595399999999998\n"" 150 -1.1178900000000001 0.96413400000000005 4.9031599999999997\n"" 151 -1.15696 1.00024 4.6936299999999997\n"" 152 -1.05067 0.66004799999999997 5.1637300000000002\n"" 153 -0.96613199999999999 0.34451999999999999 5.1306700000000003\n"" 154 -1.0339100000000001 0.21693000000000001 4.8971299999999998\n"" 155 -1.14191 0.38449800000000001 4.5636299999999999\n"" 156 -1.1704300000000001 0.77507400000000004 4.3866199999999997\n"" 157 -1.2187600000000001 2.4617200000000001 4.0832199999999998\n"" 158 -1.30006 1.85564 3.8536299999999999\n"" 159 -1.44909 1.8689100000000001 3.5269900000000001\n"" 160 -0.013254 2.19998 4.49648\n"" 161 -0.52937999999999996 2.3775900000000001 4.0718100000000002\n"" 162 -1.02088 0.65710199999999996 5.0446999999999997\n"" 163 -0.96312600000000004 0.40659600000000001 4.9839000000000002\n"" 164 -1.08928 0.83882999999999996 4.8728800000000003\n"" 165 -1.08297 0.89140799999999998 4.6565200000000004\n"" 166 -1.0815300000000001 0.77475000000000005 4.4651500000000004\n"" 167 -1.1177900000000001 0.46984799999999999 4.6161099999999999\n"" 168 -1.00573 0.363234 4.8400499999999997\n"" 169 -1.1392599999999999 0.61656 4.8154899999999996\n"" 170 -0.65003999999999995 2.7326800000000002 3.9430399999999999\n"" 171 -1.4495100000000001 3.1655500000000001 4.0157800000000003\n"" 172 -1.59406 3.0802 3.8075600000000001\n"" 173 -1.21844 2.8713000000000002 3.48916\n"" 174 -1.60063 3.85398 3.6123699999999999\n"" 175 -1.3017700000000001 3.3890799999999999 3.2126100000000002\n"" 176 -1.21326 3.1529699999999998 2.8556599999999999\n"" 177 -1.16333 2.80755 3.12364\n"" 178 -1.5950200000000001 4.5435999999999996 3.0055999999999998\n"" 179 -1.44184 3.9206400000000001 2.77929\n"" 180 -1.8554299999999999 4.6612099999999996 1.82836\n"" 181 -1.62605 4.09856 2.2921100000000001\n"" 182 -1.8726700000000001 4.0265899999999997 1.7201200000000001\n"" 183 -1.6127499999999999 3.7460499999999999 2.2633899999999998\n"" 184 -1.81474 3.2039800000000001 2.1617299999999999\n"" 185 -1.5819399999999999 3.1758600000000001 2.4753799999999999\n"" 186 -1.69387 2.4910000000000001 2.6859999999999999\n"" 187 -1.4352100000000001 2.6525799999999999 2.9736199999999999\n"" 188 -1.32026 3.4141599999999999 2.6752600000000002\n"" 189 -0.0075779999999999997 2.3737900000000001 3.6121699999999999\n"" 190 -0.34406999999999999 2.6552099999999998 3.4333399999999998\n"" 191 -0.53356199999999998 3.0379999999999998 3.1746400000000001\n"" 192 -0.75442799999999999 3.2104599999999999 3.6774800000000001\n"" 193 -0.75750600000000001 3.4630200000000002 2.8989500000000001\n"" 194 -0.89756400000000003 3.6691199999999999 3.34639\n"" 195 -0.979128 3.96475 2.9464800000000002\n"" 196 -1.0348900000000001 3.9803199999999999 2.4925000000000002\n"" 197 -0.96278399999999997 3.5502600000000002 2.2239499999999999\n"" 198 -0.93867 3.2183799999999998 2.2698100000000001\n"" 199 -0.81897600000000004 2.66615 2.5513599999999999\n"" 200 -0.573384 2.24261 2.8419500000000002\n"" 201 -0.62487599999999999 1.89547 2.9886200000000001\n"" 202 -0.0029759999999999999 2.3051599999999999 2.8429000000000002\n"" 203 -0.001098 1.7866200000000001 2.4089200000000002\n"" 204 -0.77425200000000005 1.62087 2.60697\n"" 205 0.00059999999999999995 1.63778 2.09483\n"" 206 -0.67835999999999996 1.4218999999999999 2.31332\n"" 207 0.043560000000000001 0.097865999999999995 -5.3003799999999996\n"" 208 0.047190000000000003 0.73262400000000005 -5.7368199999999998\n"" 209 -0.197052 0.69169199999999997 -5.7195099999999996\n"" 210 -0.53469 0.65069399999999999 -5.7019000000000002\n"" 211 -0.28464 0.088373999999999994 -5.2965400000000002\n"" 212 -0.62674799999999997 0.078822000000000003 -5.2924199999999999\n"" 213 -0.51863400000000004 -3.5091999999999999 -3.6500599999999999\n"" 214 -0.69015599999999999 -3.9756300000000002 -2.62039\n"" 215 -0.43009799999999998 -3.9922300000000002 -3.6383100000000002\n"" 216 -1.5472999999999999 -3.9922900000000001 -3.9483100000000002\n"" 217 -1.6352500000000001 -3.9922900000000001 -3.5523799999999999\n"" 218 -2.2279300000000002 -3.9922900000000001 -2.1217199999999998\n"" 219 -2.2341700000000002 -3.9922900000000001 -1.3465199999999999\n"" 220 -2.0110000000000001 -3.9922800000000001 -0.47173799999999999\n"" 221 -1.35599 -3.9922499999999999 -0.23388600000000001\n"" 222 -0.64031400000000005 -3.9922399999999998 -1.1181099999999999\n"" 223 -0.49049399999999999 -3.9922300000000002 -1.75532\n"" 224 0.041658000000000001 -0.54903000000000002 -5.1501200000000003\n"" 225 0.036701999999999999 -1.68591 -4.6197999999999997\n"" 226 0.026970000000000001 -3.01416 -3.3587899999999999\n"" 227 -1.1918299999999999 -1.81281 -5.0749000000000004\n"" 228 -1.4243699999999999 -3.2552599999999998 -3.5231300000000001\n"" 229 -1.62001 -1.67693 -4.0191699999999999\n"" 230 -0.80728200000000006 -0.71911199999999997 -5.7540199999999997\n"" 231 -0.31252799999999997 -0.73477800000000004 -5.6672900000000004\n"" 232 -0.74677800000000005 -1.76105 -5.3974000000000002\n"" 233 -0.28569600000000001 -1.73786 -5.2757500000000004\n"" 234 -1.0115700000000001 -3.1747899999999998 -3.9295900000000001\n"" 235 -0.59875800000000001 -3.0943100000000001 -3.8752399999999998\n"" 236 -1.1170100000000001 -3.6316899999999999 -4.3481399999999999\n"" 237 -0.67781999999999998 -3.49858 -4.2448100000000002\n"" 238 -0.64891200000000004 -3.9922499999999999 -4.2024499999999998\n"" 239 -1.0981099999999999 -3.99227 -4.3057800000000004\n"" 240 -2.0971700000000002 -2.0067499999999998 -3.0719099999999999\n"" 241 -0.84709199999999996 -2.6262300000000001 -4.7891599999999999\n"" 242 -1.2760199999999999 -2.6923499999999998 -4.4246800000000004\n"" 243 -1.56667 -2.4896699999999998 -3.6830099999999999\n"" 244 -0.46418399999999999 -2.5888800000000001 -4.6686800000000002\n"" 245 0.031043999999999999 -2.55166 -3.9095499999999999\n"" 246 0.535416 -2.5903900000000002 -4.66256\n"" 247 1.6260399999999999 -2.4944899999999999 -3.6634600000000002\n"" 248 1.34389 -2.6962999999999999 -4.4086400000000001\n"" 249 0.91964999999999997 -2.6288999999999998 -4.7783499999999997\n"" 250 2.1504799999999999 -2.0131700000000001 -3.04589\n"" 251 1.1606000000000001 -3.9956800000000001 -4.2919499999999999\n"" 252 0.71017799999999998 -3.9943 -4.1941300000000004\n"" 253 0.74109000000000003 -3.5007199999999998 -4.2361199999999997\n"" 254 1.1811100000000001 -3.6351599999999999 -4.3340699999999996\n"" 255 0.65872799999999998 -3.0962100000000001 -3.86754\n"" 256 1.0719399999999999 -3.17794 -3.91682\n"" 257 0.36694199999999999 -1.7388399999999999 -5.2717599999999996\n"" 258 0.82940400000000003 -1.7634300000000001 -5.3877499999999996\n"" 259 0.40159800000000001 -0.73585800000000001 -5.6629199999999997\n"" 260 0.89742599999999995 -0.72168600000000005 -5.7435799999999997\n"" 261 1.6859299999999999 -1.6819299999999999 -3.99892\n"" 262 1.47949 -3.2596500000000002 -3.5053399999999999\n"" 263 1.2703199999999999 -1.8165199999999999 -5.0598200000000002\n"" 264 0.52179600000000004 -3.99376 -1.74912\n"" 265 0.66380399999999995 -3.9942099999999998 -1.1101300000000001\n"" 266 1.36859 -3.9963700000000002 -0.21720600000000001\n"" 267 2.0264600000000002 -3.99838 -0.44701800000000003\n"" 268 2.2603300000000002 -3.9990800000000002 -1.319\n"" 269 2.2635900000000002 -3.9990800000000002 -2.09422\n"" 270 1.6884699999999999 -3.9973000000000001 -3.5320200000000002\n"" 271 1.60538 -3.9970400000000001 -3.9289999999999998\n"" 272 0.48447000000000001 -3.9936099999999999 -3.6327099999999999\n"" 273 0.73209599999999997 -3.9777800000000001 -2.6116799999999998\n"" 274 0.57460199999999995 -3.51085 -3.64337\n"" 275 0.71366399999999997 0.076794000000000001 -5.2842099999999999\n"" 276 0.37166399999999999 0.087384000000000003 -5.2925199999999997\n"" 277 0.62834999999999996 0.64893599999999996 -5.6947799999999997\n"" 278 0.291078 0.69095399999999996 -5.71652\n"" 279 0.676176 1.4198599999999999 2.3216199999999998\n"" 280 0.76906200000000002 1.6185400000000001 2.6164299999999998\n"" 281 0.61585800000000002 1.8935999999999999 2.9962200000000001\n"" 282 0.56720999999999999 2.2408899999999998 2.8489399999999998\n"" 283 0.81762000000000001 2.6636799999999998 2.5613700000000001\n"" 284 0.94242599999999999 3.2155399999999998 2.2813300000000001\n"" 285 0.96809999999999996 3.5473400000000002 2.2357800000000001\n"" 286 1.0382100000000001 3.9771899999999998 2.5051899999999998\n"" 287 0.97684800000000005 3.9617900000000001 2.9584600000000001\n"" 288 0.88949999999999996 3.66642 3.3573300000000001\n"" 289 0.75431400000000004 3.4607399999999999 2.90821\n"" 290 0.74093399999999998 3.2081900000000001 3.6866400000000001\n"" 291 0.52572600000000003 3.0364 3.18113\n"" 292 0.331926 2.6541899999999998 3.4374899999999999\n"" 293 1.31962 3.4101699999999999 2.69143\n"" 294 1.42859 2.64825 2.9911699999999999\n"" 295 1.6902699999999999 2.4858899999999999 2.7067299999999999\n"" 296 1.583 3.1710799999999999 2.4947599999999999\n"" 297 1.8197000000000001 3.1984900000000001 2.1839900000000001\n"" 298 1.61812 3.7411699999999999 2.2831700000000001\n"" 299 1.8855299999999999 4.0209200000000003 1.7431399999999999\n"" 300 1.6321399999999999 4.0936399999999997 2.3120599999999998\n"" 301 1.8688800000000001 4.6555900000000001 1.8511599999999999\n"" 302 1.44143 3.91628 2.7969499999999998\n"" 303 1.59371 4.53878 3.0251199999999998\n"" 304 1.15537 2.8040500000000002 3.1378300000000001\n"" 305 1.20963 3.1493099999999998 2.8704999999999998\n"" 306 1.2944599999999999 3.3851599999999999 3.2284999999999999\n"" 307 1.5898099999999999 3.8491599999999999 3.6318999999999999\n"" 308 1.2061900000000001 2.8676400000000002 3.5040100000000001\n"" 309 1.5785199999999999 3.0754000000000001 3.8269899999999999\n"" 310 1.4316899999999999 3.1612 4.0334199999999996\n"" 311 0.63185400000000003 2.7307399999999999 3.9508899999999998\n"" 312 1.1039600000000001 0.61316999999999999 4.8292299999999999\n"" 313 0.96937799999999996 0.36025200000000002 4.85215\n"" 314 1.08449 0.46652399999999999 4.6295999999999999\n"" 315 1.05101 0.77152799999999999 4.4782099999999998\n"" 316 1.0504500000000001 0.88817999999999997 4.6695799999999998\n"" 317 1.0539499999999999 0.83559000000000005 4.8860000000000001\n"" 318 0.92514600000000002 0.40374599999999999 4.9954700000000001\n"" 319 0.982908 0.65407800000000005 5.0569800000000003\n"" 320 0.50856000000000001 2.37602 4.0781700000000001\n"" 321 1.43333 1.86456 3.5446499999999999\n"" 322 1.2802800000000001 1.85175 3.8694299999999999\n"" 323 1.198 2.4580700000000002 4.09802\n"" 324 1.14086 0.77158199999999999 4.4007800000000001\n"" 325 1.109 0.38109599999999999 4.5774100000000004\n"" 326 0.99641999999999997 0.213864 4.9095700000000004\n"" 327 0.92616600000000004 0.34165800000000002 5.1422499999999998\n"" 328 1.01125 0.65693400000000002 5.1763500000000002\n"" 329 1.12432 0.99678599999999995 4.7075899999999997\n"" 330 1.08257 0.96081000000000005 4.9166299999999996\n"" 331 1.2109399999999999 0.98394599999999999 4.1745400000000004\n"" 332 1.1652400000000001 1.2398100000000001 4.6936499999999999\n"" 333 0.93262800000000001 1.74756 4.4064699999999997\n"" 334 1.0661799999999999 1.1785399999999999 5.0801600000000002\n"" 335 0.91383000000000003 0.75153599999999998 5.3447199999999997\n"" 336 0.71727600000000002 1.49926 5.1546200000000004\n"" 337 0.71021400000000001 0.83785799999999999 5.5150399999999999\n"" 338 0.47645999999999999 0.79783800000000005 5.69191\n"" 339 0.37451400000000001 0.219888 5.85928\n"" 340 0.76708200000000004 -0.21551400000000001 5.6824199999999996\n"" 341 0.86174399999999995 0.19323599999999999 5.31548\n"" 342 0.44932800000000001 -0.51103799999999999 5.8834600000000004\n"" 343 0.78110400000000002 -0.62793600000000005 5.6857199999999999\n"" 344 0.93720599999999998 -0.56791800000000003 5.3944400000000003\n"" 345 0.464196 -1.0271600000000001 5.5592699999999997\n"" 346 0.76633200000000001 -0.98837399999999997 5.2788599999999999\n"" 347 0.31602000000000002 -1.10771 5.0521099999999999\n"" 348 0.14086199999999999 -1.1078300000000001 5.33887\n"" 349 0.13575599999999999 -1.26352 4.9649999999999999\n"" 350 1.33853 1.27186 3.72296\n"" 351 1.5086599999999999 0.67840199999999995 3.9989599999999998\n"" 352 1.50851 0.53724000000000005 4.0433199999999996\n"" 353 1.28616 0.115548 4.6295700000000002\n"" 354 0.95399400000000001 0.00894 5.0122400000000003\n"" 355 1.0601799999999999 -0.35549399999999998 5.0953099999999996\n"" 356 0.89217599999999997 -0.78054599999999996 4.76159\n"" 357 0.64973999999999998 -0.99916799999999995 4.63253\n"" 358 0.29892000000000002 -1.2082900000000001 4.5867199999999997\n"" 359 0.42804599999999998 -1.2911699999999999 4.1832500000000001\n"" 360 0.438888 -1.28685 3.7410600000000001\n"" 361 0.84301199999999998 -1.01677 4.1961199999999996\n"" 362 0.980244 -0.942438 3.6684999999999999\n"" 363 1.1368 -0.83130000000000004 4.3822000000000001\n"" 364 1.48556 -0.49532399999999999 4.5576600000000003\n"" 365 1.3648100000000001 -0.73189199999999999 3.5411800000000002\n"" 366 1.70821 -0.039516000000000003 3.2120799999999998\n"" 367 1.65445 0.751722 2.6800600000000001\n"" 368 1.5999000000000001 1.1555599999999999 3.03626\n"" 369 1.8005199999999999 0.31972200000000001 3.77772\n"" 370 0.3327 -3.9836100000000001 2.2503899999999999\n"" 371 0.737124 -3.9848300000000001 2.8939400000000002\n"" 372 0.27911999999999998 -3.1894300000000002 2.3515100000000002\n"" 373 0.14894399999999999 -3.4106999999999998 1.6506400000000001\n"" 374 0.32312999999999997 -3.98359 1.9693400000000001\n"" 375 0.67697399999999996 -2.7212900000000002 1.83473\n"" 376 0.78759000000000001 -3.0636999999999999 0.48447600000000002\n"" 377 0.36704399999999998 -2.5842999999999998 -0.25625999999999999\n"" 378 2.0461100000000001 -3.1973199999999999 -1.2488999999999999\n"" 379 2.08623 -3.7412000000000001 -0.48683399999999999\n"" 380 1.42824 -3.66439 -0.22822200000000001\n"" 381 1.27058 -3.0856400000000002 -0.79246799999999995\n"" 382 0.72363 -3.6013099999999998 -1.12114\n"" 383 0.58191000000000004 -3.5068600000000001 -1.76014\n"" 384 0.76572600000000002 -3.4916499999999999 -2.6230199999999999\n"" 385 0.99541199999999996 -2.8645499999999999 -1.7487200000000001\n"" 386 0.46632000000000001 -2.5078499999999999 -1.32311\n"" 387 1.9253499999999999 -3.0381800000000001 -1.9252400000000001\n"" 388 1.4892799999999999 -2.7940999999999998 -1.4390499999999999\n"" 389 0.712584 -2.30003 -1.1226799999999999\n"" 390 0.71289599999999997 -2.5806399999999998 -0.739842\n"" 391 0.56478600000000001 -2.5167799999999998 -0.26866200000000001\n"" 392 1.64716 -1.5702400000000001 0.03066\n"" 393 1.55905 -1.6997500000000001 -0.019109999999999999\n"" 394 1.33717 -2.0425900000000001 -0.22925999999999999\n"" 395 1.2266699999999999 -3.9862799999999998 3.08012\n"" 396 1.55572 -3.9872800000000002 2.82769\n"" 397 1.1124099999999999 -2.8561200000000002 2.5303100000000001\n"" 398 1.6749799999999999 -3.9876200000000002 2.5039699999999998\n"" 399 1.6629400000000001 -3.16873 2.4012500000000001\n"" 400 1.0984100000000001 -3.0588700000000002 1.97997\n"" 401 1.6955899999999999 -2.5752600000000001 0.35545199999999999\n"" 402 1.5288999999999999 -3.98725 1.7441199999999999\n"" 403 1.62862 -3.4062399999999999 1.5838000000000001\n"" 404 2.3193700000000002 -3.7513299999999998 -1.30122\n"" 405 2.3225199999999999 -3.7852999999999999 -2.0764399999999998\n"" 406 2.2801300000000002 -3.57613 -1.9120699999999999\n"" 407 1.7476100000000001 -3.7140399999999998 -3.51424\n"" 408 2.0356800000000002 -3.42719 -2.7716799999999999\n"" 409 2.4002699999999999 -2.9386700000000001 -2.5358399999999999\n"" 410 2.4409000000000001 -1.88609 -2.2273800000000001\n"" 411 1.8035300000000001 -1.69031 -1.02329\n"" 412 1.7452000000000001 -1.6638200000000001 -0.37142999999999998\n"" 413 1.1264099999999999 -1.4492700000000001 3.0566200000000001\n"" 414 1.12819 -1.7254100000000001 2.5453999999999999\n"" 415 1.3651199999999999 -2.2395700000000001 1.75861\n"" 416 1.5991599999999999 -1.6418999999999999 0.23758199999999999\n"" 417 1.7495499999999999 -1.7500599999999999 0.66831600000000002\n"" 418 1.7514799999999999 -0.73644600000000005 2.5360999999999998\n"" 419 1.7854399999999999 -0.93671400000000005 2.2402099999999998\n"" 420 1.7196199999999999 -1.39639 0.16297200000000001\n"" 421 2.18798 -1.2083900000000001 1.2411000000000001\n"" 422 2.1231300000000002 -0.79444800000000004 0.89536800000000005\n"" 423 1.6932499999999999 -0.11829000000000001 1.8897600000000001\n"" 424 1.98712 -0.59559600000000001 0.55620599999999998\n"" 425 2.25278 -0.55871999999999999 -0.038802000000000003\n"" 426 2.2555000000000001 -0.60741599999999996 -0.92929200000000001\n"" 427 2.7998099999999999 -0.566496 -1.8340099999999999\n"" 428 2.7348300000000001 -0.71928599999999998 -2.7637900000000002\n"" 429 1.66479 -3.6254499999999998 -3.9112300000000002\n"" 430 1.56613 -3.3070599999999999 -3.3279999999999998\n"" 431 0.56176199999999998 1.5509599999999999 -5.5235300000000001\n"" 432 0.68548799999999999 1.86365 -4.7884200000000003\n"" 433 0.86539200000000005 1.2685999999999999 -5.0100100000000003\n"" 434 0.71949600000000002 1.0616399999999999 -5.70695\n"" 435 1.1043700000000001 0.611124 -5.5093199999999998\n"" 436 0.55458600000000002 1.65913 -4.4293899999999997\n"" 437 0.80102399999999996 1.3104199999999999 -4.5516100000000002\n"" 438 1.1699200000000001 0.58592999999999995 -4.87486\n"" 439 1.1132500000000001 0.066030000000000005 -5.2752100000000004\n"" 440 1.3818900000000001 -0.76470000000000005 -5.3052099999999998\n"" 441 1.5628299999999999 1.53034 -3.74627\n"" 442 2.1093999999999999 -0.253164 -3.98386\n"" 443 1.5224500000000001 1.9411400000000001 -2.6023000000000001\n"" 444 2.4696699999999998 0.793794 -2.6295799999999998\n"" 445 1.6230800000000001 2.1391800000000001 -1.7399\n"" 446 2.53288 0.97691399999999995 -1.6387799999999999\n"" 447 0.988344 1.4249400000000001 1.2534700000000001\n"" 448 1.52284 0.55740000000000001 1.44384\n"" 449 1.2216499999999999 1.7075800000000001 0.57733800000000002\n"" 450 1.44604 2.0585599999999999 -1.0283800000000001\n"" 451 2.13646 0.89572799999999997 -0.86065800000000003\n"" 452 2.0259399999999999 0.79195199999999999 0.39824399999999999\n"" 453 -0.42761063083709772 1.6952470543869633 2.5510779406671853\n""# Generated by tetgen -YY bunny.smesh \n"); } +static const char* getElements() { return( +"1374 4 0\n"" 0 395 372 399 371\n"" 1 96 46 93 44\n"" 2 135 140 137 163\n"" 3 318 326 354 313\n"" 4 133 127 128 126\n"" 5 76 83 55 218\n"" 6 193 188 198 176\n"" 7 450 443 451 1\n"" 8 437 442 438 441\n"" 9 160 336 320 144\n"" 10 79 50 51 75\n"" 11 408 378 387 273\n"" 12 94 38 47 68\n"" 13 323 308 322 311\n"" 14 339 135 163 341\n"" 15 152 135 153 145\n"" 16 333 166 160 147\n"" 17 348 346 347 342\n"" 18 446 426 451 444\n"" 19 46 92 94 93\n"" 20 208 21 26 207\n"" 21 38 360 48 413\n"" 22 229 80 243 245\n"" 23 241 229 227 242\n"" 24 34 50 35 51\n"" 25 9 33 35 34\n"" 26 103 122 121 206\n"" 27 257 260 259 440\n"" 28 142 318 163 144\n"" 29 446 443 444 451\n"" 30 272 251 252 274\n"" 31 193 199 176 198\n"" 32 165 149 147 166\n"" 33 447 3 8 449\n"" 34 29 208 209 30\n"" 35 300 285 286 299\n"" 36 100 104 119 105\n"" 37 39 44 40 41\n"" 38 315 318 313 316\n"" 39 422 417 421 419\n"" 40 382 273 264 383\n"" 41 145 143 150 146\n"" 42 406 268 405 404\n"" 43 427 411 426 428\n"" 44 323 290 308 311\n"" 45 232 18 230 227\n"" 46 243 79 80 240\n"" 47 391 412 390 389\n"" 48 360 423 107 362\n"" 49 389 71 393 392\n"" 50 142 162 163 145\n"" 51 245 247 261 80\n"" 52 376 373 375 92\n"" 53 324 352 325 362\n"" 54 119 104 106 105\n"" 55 165 149 166 151\n"" 56 428 389 411 442\n"" 57 366 351 331 352\n"" 58 166 318 316 163\n"" 59 368 281 280 350\n"" 60 315 168 313 166\n"" 61 417 422 423 419\n"" 62 279 203 205 453\n"" 63 80 243 245 226\n"" 64 416 41 420 45\n"" 65 319 330 317 335\n"" 66 15 442 225 224\n"" 67 116 131 117 129\n"" 68 335 318 337 319\n"" 69 188 197 193 198\n"" 70 326 314 325 313\n"" 71 313 315 314 325\n"" 72 451 3 449 450\n"" 73 451 449 452 450\n"" 74 299 286 300 301\n"" 75 450 1 3 2\n"" 76 107 103 120 149\n"" 77 76 82 81 79\n"" 78 81 83 218 214\n"" 79 14 10 2 11\n"" 80 22 436 437 23\n"" 81 318 144 316 163\n"" 82 420 426 425 412\n"" 83 450 14 11 445\n"" 84 262 254 429 274\n"" 85 443 442 441 444\n"" 86 356 353 364 363\n"" 87 102 122 206 101\n"" 88 315 168 325 313\n"" 89 281 331 280 350\n"" 90 107 155 120 104\n"" 91 443 426 444 451\n"" 92 123 118 354 113\n"" 93 84 220 86 83\n"" 94 268 406 405 269\n"" 95 287 293 289 286\n"" 96 17 16 443 13\n"" 97 315 168 166 325\n"" 98 283 296 297 284\n"" 99 333 144 336 160\n"" 100 450 13 1 2\n"" 101 414 423 418 419\n"" 102 331 352 324 362\n"" 103 144 315 333 316\n"" 104 21 442 16 15\n"" 105 45 72 91 69\n"" 106 437 208 21 433\n"" 107 288 310 290 306\n"" 108 213 217 214 31\n"" 109 335 327 328 341\n"" 110 109 67 48 111\n"" 111 316 314 315 312\n"" 112 45 60 91 44\n"" 113 128 118 115 116\n"" 114 423 45 38 448\n"" 115 155 362 166 325\n"" 116 130 136 132 133\n"" 117 92 72 89 91\n"" 118 145 143 142 150\n"" 119 153 140 163 142\n"" 120 317 313 312 319\n"" 121 347 118 126 354\n"" 122 148 165 147 143\n"" 123 170 157 171 173\n"" 124 78 50 74 240\n"" 125 381 273 385 378\n"" 126 337 330 335 317\n"" 127 267 273 379 268\n"" 128 80 247 261 250\n"" 129 80 225 261 245\n"" 130 80 442 261 225\n"" 131 211 24 212 20\n"" 132 398 395 399 371\n"" 133 390 389 377 391\n"" 134 308 292 290 291\n"" 135 176 191 177 199\n"" 136 318 166 313 163\n"" 137 23 16 436 17\n"" 138 354 353 325 326\n"" 139 423 362 366 279\n"" 140 415 400 375 403\n"" 141 217 239 216 213\n"" 142 377 89 88 90\n"" 143 10 12 13 9\n"" 144 155 325 113 112\n"" 145 151 164 165 150\n"" 146 113 118 128 123\n"" 147 95 97 99 96\n"" 148 449 3 8 5\n"" 149 61 99 97 64\n"" 150 223 83 222 82\n"" 151 37 38 6 39\n"" 152 0 7 6 37\n"" 153 385 430 247 250\n"" 154 108 109 110 107\n"" 155 415 401 417 403\n"" 156 102 121 122 101\n"" 157 120 107 149 156\n"" 158 104 100 119 120\n"" 159 3 4 2 5\n"" 160 207 21 224 437\n"" 161 270 273 408 430\n"" 162 80 247 226 245\n"" 163 80 228 81 243\n"" 164 43 107 48 38\n"" 165 354 340 344 341\n"" 166 312 316 313 317\n"" 167 435 275 277 439\n"" 168 27 30 29 28\n"" 169 52 76 31 240\n"" 170 338 339 163 318\n"" 171 47 43 42 48\n"" 172 61 96 59 58\n"" 173 428 389 442 261\n"" 174 194 171 192 174\n"" 175 318 339 341 338\n"" 176 417 422 416 423\n"" 177 123 124 125 128\n"" 178 113 108 115 155\n"" 179 300 285 299 298\n"" 180 320 160 189 333\n"" 181 443 35 1 13\n"" 182 96 46 44 61\n"" 183 316 314 313 315\n"" 184 119 107 155 106\n"" 185 357 325 356 361\n"" 186 224 15 21 20\n"" 187 319 336 337 317\n"" 188 306 287 307 302\n"" 189 143 141 140 144\n"" 190 366 423 279 367\n"" 191 74 73 88 89\n"" 192 447 7 8 3\n"" 193 449 8 447 5\n"" 194 436 21 22 437\n"" 195 92 72 91 45\n"" 196 153 140 142 135\n"" 197 206 121 103 149\n"" 198 35 69 389 71\n"" 199 165 168 167 166\n"" 200 12 1 13 9\n"" 201 361 112 113 325\n"" 202 195 175 193 194\n"" 203 292 304 322 321\n"" 204 337 336 144 338\n"" 205 399 372 400 371\n"" 206 332 336 334 333\n"" 207 111 68 67 48\n"" 208 389 391 393 72\n"" 209 196 179 188 195\n"" 210 104 119 155 120\n"" 211 168 166 325 155\n"" 212 112 108 113 155\n"" 213 449 425 451 452\n"" 214 220 214 83 221\n"" 215 261 246 245 225\n"" 216 93 44 46 92\n"" 217 80 255 226 247\n"" 218 384 262 247 430\n"" 219 336 144 319 337\n"" 220 144 315 316 166\n"" 221 332 336 333 316\n"" 222 175 191 194 192\n"" 223 362 353 325 363\n"" 224 110 113 115 114\n"" 225 400 370 374 402\n"" 226 319 337 335 317\n"" 227 430 262 247 248\n"" 228 324 362 315 331\n"" 229 80 228 235 81\n"" 230 347 342 126 348\n"" 231 295 283 296 297\n"" 232 306 304 305 308\n"" 233 356 353 325 354\n"" 234 21 23 437 433\n"" 235 195 174 194 178\n"" 236 192 175 177 173\n"" 237 302 287 303 286\n"" 238 208 211 26 209\n"" 239 118 128 115 113\n"" 240 351 366 369 352\n"" 241 342 344 340 343\n"" 242 118 347 123 354\n"" 243 354 168 163 313\n"" 244 356 325 363 361\n"" 245 282 321 294 304\n"" 246 268 379 267 404\n"" 247 296 305 284 283\n"" 248 290 304 308 291\n"" 249 316 318 313 319\n"" 250 143 160 147 161\n"" 251 149 201 122 147\n"" 252 38 448 45 6\n"" 253 92 415 417 94\n"" 254 225 224 261 440\n"" 255 198 185 184 186\n"" 256 7 205 447 8\n"" 257 368 351 350 367\n"" 258 74 13 12 35\n"" 259 190 147 161 158\n"" 260 270 429 262 407\n"" 261 3 4 450 2\n"" 262 15 443 442 16\n"" 263 193 188 195 196\n"" 264 342 347 340 344\n"" 265 391 393 45 416\n"" 266 92 415 94 375\n"" 267 61 60 91 58\n"" 268 60 72 69 91\n"" 269 289 283 305 291\n"" 270 96 44 93 92\n"" 271 324 362 325 315\n"" 272 13 2 14 10\n"" 273 62 63 61 64\n"" 274 144 166 160 315\n"" 275 417 423 416 94\n"" 276 449 4 450 3\n"" 277 450 13 443 1\n"" 278 352 364 365 369\n"" 279 7 448 205 6\n"" 280 225 440 261 263\n"" 281 116 155 119 118\n"" 282 2 4 450 11\n"" 283 416 377 92 89\n"" 284 376 403 415 375\n"" 285 417 376 415 92\n"" 286 416 377 89 391\n"" 287 249 262 246 256\n"" 288 336 317 316 330\n"" 289 47 43 48 38\n"" 290 354 168 313 113\n"" 291 115 168 118 113\n"" 292 34 50 51 33\n"" 293 166 169 167 165\n"" 294 319 316 317 313\n"" 295 318 144 337 319\n"" 296 354 325 313 326\n"" 297 30 436 433 431\n"" 298 289 283 291 284\n"" 299 58 91 96 59\n"" 300 185 182 183 197\n"" 301 224 438 276 437\n"" 302 15 442 80 225\n"" 303 111 110 112 109\n"" 304 52 76 240 51\n"" 305 208 26 30 29\n"" 306 7 449 3 447\n"" 307 296 294 283 295\n"" 308 306 291 289 305\n"" 309 338 140 141 144\n"" 310 331 352 351 324\n"" 311 322 281 333 320\n"" 312 83 81 76 82\n"" 313 384 262 274 255\n"" 314 60 45 91 69\n"" 315 15 20 19 16\n"" 316 197 188 193 196\n"" 317 80 229 225 245\n"" 318 18 233 227 232\n"" 319 344 345 343 342\n"" 320 417 414 94 415\n"" 321 443 16 441 442\n"" 322 177 199 187 176\n"" 323 149 206 121 453\n"" 324 350 279 331 280\n"" 325 181 188 196 179\n"" 326 102 121 101 103\n"" 327 347 357 354 356\n"" 328 338 327 318 337\n"" 329 337 330 334 335\n"" 330 319 336 317 316\n"" 331 193 175 188 176\n"" 332 164 143 162 165\n"" 333 120 104 100 103\n"" 334 376 416 92 417\n"" 335 113 325 155 168\n"" 336 416 376 92 391\n"" 337 420 45 41 393\n"" 338 249 262 248 246\n"" 339 147 189 161 160\n"" 340 18 231 224 233\n"" 341 71 45 70 41\n"" 342 126 341 135 339\n"" 343 21 23 22 437\n"" 344 148 165 143 151\n"" 345 337 327 318 335\n"" 346 354 318 313 163\n"" 347 115 118 155 116\n"" 348 341 340 338 339\n"" 349 166 168 313 163\n"" 350 166 318 313 315\n"" 351 48 68 67 47\n"" 352 150 162 145 152\n"" 353 140 339 137 163\n"" 354 199 185 187 176\n"" 355 333 144 316 336\n"" 356 338 327 337 341\n"" 357 389 70 72 393\n"" 358 331 366 350 351\n"" 359 94 45 92 44\n"" 360 9 33 12 35\n"" 361 126 139 137 138\n"" 362 321 295 282 294\n"" 363 135 140 136 137\n"" 364 153 162 163 152\n"" 365 325 362 363 361\n"" 366 80 235 226 81\n"" 367 74 377 89 88\n"" 368 13 14 450 443\n"" 369 157 172 158 171\n"" 370 450 443 14 445\n"" 371 155 107 120 156\n"" 372 135 339 163 137\n"" 373 365 325 352 362\n"" 374 153 140 135 163\n"" 375 448 206 205 6\n"" 376 137 141 139 339\n"" 377 103 107 120 104\n"" 378 448 425 447 452\n"" 379 165 162 168 163\n"" 380 76 83 79 87\n"" 381 420 45 393 416\n"" 382 334 329 330 336\n"" 383 89 45 92 416\n"" 384 181 195 179 196\n"" 385 420 448 41 416\n"" 386 438 277 435 275\n"" 387 400 399 402 403\n"" 388 304 296 283 305\n"" 389 170 158 190 161\n"" 390 387 386 388 250\n"" 391 54 218 217 53\n"" 392 311 304 308 322\n"" 393 149 281 201 189\n"" 394 211 24 209 212\n"" 395 166 333 149 147\n"" 396 426 424 420 425\n"" 397 394 376 401 416\n"" 398 147 159 122 158\n"" 399 202 203 201 453\n"" 400 280 203 279 453\n"" 401 135 126 339 137\n"" 402 449 4 3 5\n"" 403 14 2 450 11\n"" 404 126 125 127 347\n"" 405 423 413 38 414\n"" 406 185 198 188 176\n"" 407 144 163 142 162\n"" 408 201 122 204 453\n"" 409 447 425 451 449\n"" 410 290 289 306 291\n"" 411 35 69 71 49\n"" 412 207 224 211 231\n"" 413 135 154 163 118\n"" 414 126 118 341 354\n"" 415 191 175 194 193\n"" 416 436 16 437 17\n"" 417 420 422 416 421\n"" 418 135 142 153 145\n"" 419 15 443 16 13\n"" 420 440 275 259 224\n"" 421 416 421 422 417\n"" 422 442 275 440 224\n"" 423 347 340 354 126\n"" 424 254 256 253 274\n"" 425 34 50 33 35\n"" 426 176 191 175 177\n"" 427 433 278 434 277\n"" 428 175 191 192 177\n"" 429 101 206 102 204\n"" 430 132 135 136 130\n"" 431 49 35 50 36\n"" 432 353 356 325 363\n"" 433 435 277 433 434\n"" 434 224 275 276 438\n"" 435 212 230 18 19\n"" 436 143 150 148 151\n"" 437 235 228 243 234\n"" 438 29 22 26 30\n"" 439 125 347 349 123\n"" 440 237 234 235 236\n"" 441 144 336 319 316\n"" 442 165 316 166 144\n"" 443 142 318 338 163\n"" 444 137 141 140 139\n"" 445 447 279 205 448\n"" 446 106 116 108 155\n"" 447 217 238 239 215\n"" 448 16 17 443 441\n"" 449 407 262 270 430\n"" 450 88 74 389 77\n"" 451 78 79 80 81\n"" 452 126 138 134 342\n"" 453 165 150 143 151\n"" 454 409 430 387 250\n"" 455 128 118 116 131\n"" 456 339 126 340 342\n"" 457 173 192 171 170\n"" 458 400 376 403 373\n"" 459 15 18 212 224\n"" 460 37 49 36 35\n"" 461 81 82 83 214\n"" 462 173 157 171 172\n"" 463 220 214 219 83\n"" 464 114 113 128 123\n"" 465 366 423 367 418\n"" 466 379 273 378 406\n"" 467 30 436 23 433\n"" 468 23 432 28 436\n"" 469 147 144 160 143\n"" 470 79 243 31 240\n"" 471 33 74 50 240\n"" 472 342 348 345 126\n"" 473 94 416 417 92\n"" 474 416 377 391 92\n"" 475 147 158 149 157\n"" 476 273 274 384 430\n"" 477 203 281 201 453\n"" 478 243 235 245 226\n"" 479 18 229 227 225\n"" 480 45 72 69 70\n"" 481 189 149 147 201\n"" 482 175 195 193 188\n"" 483 362 107 155 166\n"" 484 185 199 198 176\n"" 485 331 166 333 149\n"" 486 31 76 81 79\n"" 487 323 290 310 308\n"" 488 43 107 104 48\n"" 489 436 16 21 437\n"" 490 368 279 350 280\n"" 491 424 416 423 448\n"" 492 150 142 164 143\n"" 493 258 248 246 249\n"" 494 381 383 385 273\n"" 495 73 49 72 74\n"" 496 117 106 119 116\n"" 497 74 377 88 389\n"" 498 408 273 387 384\n"" 499 191 170 173 190\n"" 500 199 177 200 191\n"" 501 13 80 74 12\n"" 502 130 135 128 131\n"" 503 92 90 89 377\n"" 504 84 219 83 86\n"" 505 408 378 273 406\n"" 506 386 384 80 385\n"" 507 392 426 389 420\n"" 508 80 79 243 81\n"" 509 158 177 173 190\n"" 510 377 72 89 391\n"" 511 394 376 416 391\n"" 512 442 224 440 261\n"" 513 130 131 129 132\n"" 514 95 63 61 59\n"" 515 252 274 253 272\n"" 516 273 274 272 384\n"" 517 225 263 246 257\n"" 518 76 52 31 53\n"" 519 243 79 31 81\n"" 520 448 420 424 416\n"" 521 347 358 349 123\n"" 522 138 137 126 133\n"" 523 368 279 367 350\n"" 524 38 360 413 423\n"" 525 165 168 166 163\n"" 526 207 211 26 208\n"" 527 54 217 32 228\n"" 528 125 347 348 349\n"" 529 118 347 128 123\n"" 530 423 94 45 416\n"" 531 250 389 428 261\n"" 532 119 116 118 117\n"" 533 358 113 347 357\n"" 534 168 164 165 169\n"" 535 242 235 243 234\n"" 536 354 318 341 327\n"" 537 226 247 255 245\n"" 538 377 72 389 74\n"" 539 168 354 163 118\n"" 540 163 316 166 165\n"" 541 145 163 142 153\n"" 542 262 80 247 255\n"" 543 281 304 292 321\n"" 544 12 1 9 35\n"" 545 392 426 420 412\n"" 546 51 79 76 240\n"" 547 274 270 273 272\n"" 548 270 274 273 430\n"" 549 329 331 332 324\n"" 550 325 313 168 113\n"" 551 306 304 308 290\n"" 552 71 35 49 41\n"" 553 348 346 342 345\n"" 554 270 262 274 430\n"" 555 353 363 365 364\n"" 556 29 22 30 27\n"" 557 447 425 424 451\n"" 558 53 31 217 54\n"" 559 194 171 175 192\n"" 560 29 25 209 210\n"" 561 123 358 349 113\n"" 562 80 385 384 247\n"" 563 204 202 201 453\n"" 564 259 225 440 224\n"" 565 128 347 125 123\n"" 566 111 68 48 413\n"" 567 48 68 47 414\n"" 568 415 68 414 94\n"" 569 437 208 207 21\n"" 570 424 1 3 451\n"" 571 447 452 449 448\n"" 572 389 390 377 88\n"" 573 158 170 190 173\n"" 574 169 165 168 167\n"" 575 155 154 119 118\n"" 576 115 168 155 118\n"" 577 354 168 113 118\n"" 578 147 201 161 189\n"" 579 115 168 113 155\n"" 580 168 166 155 167\n"" 581 259 225 257 440\n"" 582 263 247 261 246\n"" 583 281 279 201 453\n"" 584 128 135 136 126\n"" 585 275 260 439 440\n"" 586 66 63 65 64\n"" 587 277 438 276 275\n"" 588 163 339 341 318\n"" 589 325 314 324 315\n"" 590 338 327 341 318\n"" 591 319 327 328 335\n"" 592 391 45 89 416\n"" 593 203 281 280 202\n"" 594 362 423 206 279\n"" 595 239 237 213 238\n"" 596 362 353 365 325\n"" 597 80 235 243 226\n"" 598 80 228 243 235\n"" 599 15 21 20 16\n"" 600 31 214 81 53\n"" 601 227 244 233 225\n"" 602 442 21 224 15\n"" 603 284 293 298 285\n"" 604 233 18 227 225\n"" 605 18 233 224 225\n"" 606 205 203 204 453\n"" 607 163 154 168 118\n"" 608 208 21 433 26\n"" 609 443 389 442 444\n"" 610 27 23 30 28\n"" 611 54 218 56 217\n"" 612 391 412 389 393\n"" 613 9 13 10 1\n"" 614 61 44 96 91\n"" 615 316 314 312 313\n"" 616 416 376 401 417\n"" 617 116 108 155 115\n"" 618 106 107 155 108\n"" 619 442 389 411 426\n"" 620 164 142 162 143\n"" 621 321 294 322 295\n"" 622 144 165 143 147\n"" 623 357 325 313 354\n"" 624 389 35 41 426\n"" 625 448 7 205 447\n"" 626 227 244 229 241\n"" 627 206 38 103 102\n"" 628 206 448 205 279\n"" 629 10 4 2 11\n"" 630 246 256 245 255\n"" 631 37 49 35 41\n"" 632 128 127 124 125\n"" 633 126 138 133 134\n"" 634 312 318 319 313\n"" 635 81 235 226 213\n"" 636 213 228 235 234\n"" 637 228 81 243 31\n"" 638 81 228 235 213\n"" 639 317 336 337 330\n"" 640 330 336 337 334\n"" 641 316 330 317 329\n"" 642 319 330 335 328\n"" 643 231 18 232 233\n"" 644 18 231 232 230\n"" 645 17 437 436 441\n"" 646 287 307 302 303\n"" 647 287 306 307 288\n"" 648 303 288 287 307\n"" 649 323 320 333 311\n"" 650 393 420 416 392\n"" 651 79 51 76 75\n"" 652 336 329 316 332\n"" 653 213 236 234 237\n"" 654 76 31 81 53\n"" 655 45 72 391 89\n"" 656 31 76 79 240\n"" 657 395 372 397 399\n"" 658 393 45 41 70\n"" 659 45 416 94 92\n"" 660 211 21 224 207\n"" 661 376 417 415 401\n"" 662 262 254 274 256\n"" 663 320 304 292 311\n"" 664 1 10 9 2\n"" 665 162 165 168 164\n"" 666 385 247 80 250\n"" 667 371 400 370 372\n"" 668 384 247 385 430\n"" 669 128 130 131 129\n"" 670 443 13 442 80\n"" 671 284 293 289 305\n"" 672 448 206 6 423\n"" 673 360 107 109 362\n"" 674 112 360 359 111\n"" 675 287 305 306 289\n"" 676 362 325 112 361\n"" 677 362 166 325 315\n"" 678 437 17 16 441\n"" 679 438 277 276 433\n"" 680 200 189 190 201\n"" 681 416 422 424 423\n"" 682 320 292 281 189\n"" 683 110 108 113 112\n"" 684 108 110 113 115\n"" 685 144 318 316 319\n"" 686 250 386 389 80\n"" 687 166 318 315 316\n"" 688 63 62 59 58\n"" 689 319 327 335 318\n"" 690 337 327 335 341\n"" 691 1 450 3 451\n"" 692 239 237 236 213\n"" 693 21 442 437 16\n"" 694 450 443 445 451\n"" 695 14 13 450 2\n"" 696 39 44 42 40\n"" 697 363 357 356 361\n"" 698 350 366 367 351\n"" 699 331 366 362 279\n"" 700 368 366 369 351\n"" 701 47 43 38 42\n"" 702 140 339 163 338\n"" 703 289 285 293 284\n"" 704 339 141 338 140\n"" 705 137 141 339 140\n"" 706 234 216 213 32\n"" 707 273 408 430 384\n"" 708 273 270 408 269\n"" 709 84 220 83 85\n"" 710 158 170 157 161\n"" 711 255 262 274 256\n"" 712 304 282 283 294\n"" 713 83 218 219 87\n"" 714 377 72 74 89\n"" 715 206 205 204 453\n"" 716 446 443 451 445\n"" 717 304 292 322 320\n"" 718 155 362 112 107\n"" 719 292 283 304 282\n"" 720 443 1 426 451\n"" 721 149 362 166 107\n"" 722 272 271 274 270\n"" 723 306 287 289 288\n"" 724 366 331 350 279\n"" 725 331 366 352 362\n"" 726 61 95 96 97\n"" 727 224 442 275 438\n"" 728 273 387 384 385\n"" 729 262 271 429 270\n"" 730 185 182 197 184\n"" 731 153 162 145 163\n"" 732 74 443 35 426\n"" 733 41 389 426 420\n"" 734 40 47 46 44\n"" 735 262 246 247 248\n"" 736 1 37 3 0\n"" 737 433 432 431 436\n"" 738 23 432 436 30\n"" 739 67 360 413 111\n"" 740 109 360 112 111\n"" 741 361 360 112 362\n"" 742 246 258 249 257\n"" 743 87 218 219 55\n"" 744 151 149 166 156\n"" 745 165 149 151 148\n"" 746 149 165 147 148\n"" 747 155 154 118 168\n"" 748 217 214 218 215\n"" 749 31 214 53 217\n"" 750 291 304 283 305\n"" 751 23 16 22 436\n"" 752 143 162 165 144\n"" 753 103 102 100 101\n"" 754 195 175 179 188\n"" 755 182 196 197 180\n"" 756 400 376 375 403\n"" 757 149 281 189 331\n"" 758 146 143 150 148\n"" 759 150 146 152 145\n"" 760 168 162 164 169\n"" 761 262 384 274 430\n"" 762 54 218 53 56\n"" 763 125 127 347 128\n"" 764 304 306 291 290\n"" 765 262 80 384 247\n"" 766 153 162 152 145\n"" 767 150 162 152 164\n"" 768 168 162 169 163\n"" 769 262 80 255 384\n"" 770 38 68 414 47\n"" 771 423 206 38 107\n"" 772 46 68 94 47\n"" 773 385 430 250 387\n"" 774 413 68 48 414\n"" 775 46 68 93 94\n"" 776 41 416 448 45\n"" 777 111 68 413 67\n"" 778 77 88 74 73\n"" 779 393 41 420 392\n"" 780 274 256 253 255\n"" 781 26 23 433 30\n"" 782 218 217 53 214\n"" 783 231 212 18 224\n"" 784 446 426 444 427\n"" 785 113 114 128 115\n"" 786 128 114 123 124\n"" 787 285 289 293 286\n"" 788 301 285 299 286\n"" 789 300 285 298 286\n"" 790 297 285 298 299\n"" 791 26 23 30 22\n"" 792 44 38 94 45\n"" 793 187 158 159 177\n"" 794 218 76 81 53\n"" 795 162 143 142 144\n"" 796 397 373 400 372\n"" 797 164 142 145 162\n"" 798 128 135 126 118\n"" 799 289 283 284 305\n"" 800 282 189 281 292\n"" 801 200 186 187 199\n"" 802 21 24 211 20\n"" 803 11 13 14 10\n"" 804 2 13 1 10\n"" 805 72 377 389 391\n"" 806 74 72 73 89\n"" 807 92 72 45 89\n"" 808 413 366 418 362\n"" 809 281 304 282 292\n"" 810 429 251 274 254\n"" 811 438 439 275 435\n"" 812 37 424 1 3\n"" 813 202 189 201 281\n"" 814 333 189 320 281\n"" 815 94 38 68 423\n"" 816 389 261 250 80\n"" 817 242 241 235 234\n"" 818 364 366 365 369\n"" 819 302 305 306 287\n"" 820 362 366 352 365\n"" 821 350 366 279 367\n"" 822 368 366 351 367\n"" 823 191 176 175 193\n"" 824 173 191 177 192\n"" 825 103 121 101 100\n"" 826 176 191 199 193\n"" 827 191 177 200 190\n"" 828 275 442 439 438\n"" 829 275 442 440 439\n"" 830 224 442 225 261\n"" 831 442 224 437 438\n"" 832 258 246 263 257\n"" 833 386 384 385 383\n"" 834 149 333 331 189\n"" 835 318 326 327 354\n"" 836 207 437 224 276\n"" 837 56 76 218 53\n"" 838 350 333 322 281\n"" 839 37 38 45 6\n"" 840 232 244 227 241\n"" 841 423 206 6 38\n"" 842 411 386 250 410\n"" 843 224 229 18 225\n"" 844 6 423 38 448\n"" 845 218 57 219 55\n"" 846 68 423 38 414\n"" 847 377 376 391 92\n"" 848 415 376 375 92\n"" 849 103 121 100 120\n"" 850 101 121 122 100\n"" 851 102 121 103 122\n"" 852 7 206 6 205\n"" 853 38 206 6 102\n"" 854 107 38 103 206\n"" 855 448 206 423 279\n"" 856 298 305 284 296\n"" 857 30 432 436 431\n"" 858 23 432 30 28\n"" 859 119 107 104 155\n"" 860 142 337 318 144\n"" 861 107 103 43 104\n"" 862 426 424 425 451\n"" 863 107 156 155 166\n"" 864 119 107 106 104\n"" 865 156 107 149 166\n"" 866 103 107 43 38\n"" 867 103 122 206 102\n"" 868 448 41 45 37\n"" 869 423 416 45 448\n"" 870 81 228 213 31\n"" 871 217 239 213 215\n"" 872 403 376 415 401\n"" 873 443 74 80 389\n"" 874 135 163 341 118\n"" 875 133 126 136 137\n"" 876 228 216 213 217\n"" 877 447 451 7 449\n"" 878 71 41 393 392\n"" 879 282 321 304 281\n"" 880 95 63 99 61\n"" 881 185 197 183 188\n"" 882 433 23 437 436\n"" 883 212 24 210 19\n"" 884 257 260 440 258\n"" 885 184 197 185 198\n"" 886 175 178 195 179\n"" 887 61 60 58 44\n"" 888 362 363 361 365\n"" 889 447 451 424 7\n"" 890 132 135 130 131\n"" 891 61 91 96 58\n"" 892 385 430 387 384\n"" 893 127 133 130 126\n"" 894 80 274 226 255\n"" 895 80 274 255 384\n"" 896 219 87 86 84\n"" 897 275 259 224 276\n"" 898 18 229 15 227\n"" 899 320 304 311 322\n"" 900 23 21 26 433\n"" 901 109 38 48 107\n"" 902 342 139 126 138\n"" 903 21 23 26 22\n"" 904 426 428 444 427\n"" 905 331 166 362 315\n"" 906 122 206 204 453\n"" 907 12 1 35 13\n"" 908 189 331 281 333\n"" 909 35 9 34 1\n"" 910 426 412 389 411\n"" 911 287 305 289 293\n"" 912 320 160 333 336\n"" 913 0 35 37 36\n"" 914 262 255 247 256\n"" 915 353 352 325 324\n"" 916 336 329 330 316\n"" 917 275 260 440 259\n"" 918 16 442 437 441\n"" 919 380 378 273 381\n"" 920 7 424 447 448\n"" 921 400 376 373 375\n"" 922 222 223 214 83\n"" 923 30 22 23 27\n"" 924 262 271 274 429\n"" 925 45 44 37 41\n"" 926 380 265 382 273\n"" 927 149 333 189 147\n"" 928 242 245 229 243\n"" 929 131 135 128 118\n"" 930 245 256 247 255\n"" 931 391 412 393 394\n"" 932 99 61 97 95\n"" 933 281 203 280 453\n"" 934 350 333 331 322\n"" 935 41 71 393 70\n"" 936 398 400 399 402\n"" 937 323 309 308 310\n"" 938 37 3 0 7\n"" 939 72 393 45 391\n"" 940 408 270 430 407\n"" 941 40 47 44 42\n"" 942 298 305 293 284\n"" 943 250 385 386 80\n"" 944 266 379 273 380\n"" 945 191 170 192 173\n"" 946 364 354 356 355\n"" 947 200 186 159 187\n"" 948 159 147 190 158\n"" 949 229 244 225 245\n"" 950 427 250 411 428\n"" 951 342 347 126 340\n"" 952 13 80 12 15\n"" 953 342 346 347 344\n"" 954 268 273 379 406\n"" 955 352 365 366 369\n"" 956 78 50 240 51\n"" 957 322 321 304 294\n"" 958 183 180 196 182\n"" 959 266 379 267 273\n"" 960 58 59 60 91\n"" 961 405 273 269 406\n"" 962 84 220 85 86\n"" 963 81 82 214 223\n"" 964 21 24 26 211\n"" 965 87 219 86 57\n"" 966 442 411 428 426\n"" 967 35 443 1 426\n"" 968 47 44 94 46\n"" 969 357 325 113 313\n"" 970 313 357 354 113\n"" 971 31 217 228 213\n"" 972 99 61 66 64\n"" 973 144 166 147 160\n"" 974 298 284 285 297\n"" 975 398 400 371 399\n"" 976 51 78 50 79\n"" 977 298 284 297 296\n"" 978 7 451 3 449\n"" 979 281 279 280 331\n"" 980 158 177 190 159\n"" 981 117 106 105 119\n"" 982 278 276 277 433\n"" 983 200 122 201 177\n"" 984 72 35 389 74\n"" 985 54 228 31 217\n"" 986 379 406 378 404\n"" 987 347 127 126 128\n"" 988 109 362 112 360\n"" 989 126 339 340 341\n"" 990 142 338 140 163\n"" 991 38 44 47 42\n"" 992 150 142 145 164\n"" 993 426 424 451 420\n"" 994 431 208 433 30\n"" 995 437 207 433 276\n"" 996 135 154 153 163\n"" 997 163 341 354 318\n"" 998 443 13 74 35\n"" 999 143 142 144 140\n"" 1000 320 322 323 333\n"" 1001 122 147 158 149\n"" 1002 112 359 361 113\n"" 1003 359 112 361 360\n"" 1004 149 121 201 453\n"" 1005 361 358 113 359\n"" 1006 361 113 357 325\n"" 1007 113 359 358 112\n"" 1008 409 388 410 250\n"" 1009 71 69 389 70\n"" 1010 430 409 387 408\n"" 1011 32 217 216 228\n"" 1012 400 374 372 373\n"" 1013 419 422 423 421\n"" 1014 51 78 79 240\n"" 1015 387 386 250 385\n"" 1016 48 360 109 111\n"" 1017 438 277 433 435\n"" 1018 316 331 329 315\n"" 1019 74 50 49 35\n"" 1020 302 305 287 293\n"" 1021 287 293 286 302\n"" 1022 258 440 257 263\n"" 1023 188 183 181 196\n"" 1024 1 426 41 35\n"" 1025 236 216 213 234\n"" 1026 292 283 291 304\n"" 1027 381 383 273 382\n"" 1028 50 15 33 35\n"" 1029 79 240 78 80\n"" 1030 177 122 201 190\n"" 1031 307 308 309 310\n"" 1032 229 240 33 243\n"" 1033 200 187 177 199\n"" 1034 31 214 213 81\n"" 1035 128 133 126 136\n"" 1036 37 424 448 41\n"" 1037 263 247 246 248\n"" 1038 444 389 442 426\n"" 1039 423 417 414 94\n"" 1040 177 190 191 173\n"" 1041 417 419 415 421\n"" 1042 300 293 302 286\n"" 1043 442 13 15 80\n"" 1044 121 103 149 120\n"" 1045 136 126 135 137\n"" 1046 201 122 121 149\n"" 1047 331 316 333 315\n"" 1048 18 19 15 212\n"" 1049 38 45 423 94\n"" 1050 113 347 354 123\n"" 1051 273 405 269 408\n"" 1052 26 208 30 433\n"" 1053 431 208 278 433\n"" 1054 429 251 271 274\n"" 1055 109 38 360 48\n"" 1056 400 398 371 370\n"" 1057 174 173 175 171\n"" 1058 149 362 107 206\n"" 1059 245 242 229 244\n"" 1060 417 423 414 419\n"" 1061 185 199 186 198\n"" 1062 158 170 173 157\n"" 1063 177 122 190 159\n"" 1064 308 292 311 290\n"" 1065 380 378 379 273\n"" 1066 218 81 214 53\n"" 1067 232 244 233 227\n"" 1068 72 49 35 74\n"" 1069 235 245 226 244\n"" 1070 234 243 242 228\n"" 1071 316 331 332 329\n"" 1072 451 41 424 1\n"" 1073 362 353 363 365\n"" 1074 224 20 21 211\n"" 1075 258 248 263 246\n"" 1076 393 389 392 412\n"" 1077 212 15 224 20\n"" 1078 342 346 344 345\n"" 1079 229 74 240 80\n"" 1080 302 301 300 286\n"" 1081 203 202 204 453\n"" 1082 216 234 236 32\n"" 1083 386 388 410 411\n"" 1084 144 163 165 316\n"" 1085 347 344 346 356\n"" 1086 21 442 224 437\n"" 1087 190 122 201 147\n"" 1088 6 424 7 448\n"" 1089 269 270 408 407\n"" 1090 126 125 347 348\n"" 1091 37 44 45 38\n"" 1092 393 72 45 70\n"" 1093 413 423 418 414\n"" 1094 31 32 54 53\n"" 1095 29 22 27 26\n"" 1096 403 376 401 402\n"" 1097 83 220 221 85\n"" 1098 433 207 278 276\n"" 1099 218 57 55 56\n"" 1100 155 116 119 106\n"" 1101 173 175 171 192\n"" 1102 244 225 245 233\n"" 1103 158 173 172 157\n"" 1104 281 203 201 202\n"" 1105 344 354 356 347\n"" 1106 315 144 333 160\n"" 1107 392 426 412 389\n"" 1108 87 83 79 84\n"" 1109 347 358 357 349\n"" 1110 342 139 339 126\n"" 1111 126 341 340 354\n"" 1112 37 424 3 7\n"" 1113 210 29 25 26\n"" 1114 261 389 442 80\n"" 1115 107 112 155 108\n"" 1116 389 250 428 411\n"" 1117 80 12 15 74\n"" 1118 380 265 273 266\n"" 1119 190 122 147 159\n"" 1120 142 338 144 140\n"" 1121 109 362 107 112\n"" 1122 362 423 366 418\n"" 1123 97 66 98 64\n"" 1124 300 293 286 298\n"" 1125 130 136 133 128\n"" 1126 389 77 80 386\n"" 1127 142 337 338 318\n"" 1128 56 76 55 218\n"" 1129 214 82 83 223\n"" 1130 246 261 263 225\n"" 1131 35 12 15 33\n"" 1132 420 1 451 426\n"" 1133 63 99 61 66\n"" 1134 96 44 92 91\n"" 1135 219 214 218 83\n"" 1136 323 308 309 322\n"" 1137 224 229 225 15\n"" 1138 38 413 48 414\n"" 1139 281 149 279 331\n"" 1140 183 188 197 196\n"" 1141 180 195 181 196\n"" 1142 50 15 35 74\n"" 1143 113 347 357 354\n"" 1144 331 166 315 333\n"" 1145 19 15 212 20\n"" 1146 69 389 70 72\n"" 1147 216 236 213 239\n"" 1148 6 424 448 37\n"" 1149 74 229 33 15\n"" 1150 185 199 187 186\n"" 1151 71 389 41 392\n"" 1152 195 174 175 194\n"" 1153 398 400 402 370\n"" 1154 282 283 294 295\n"" 1155 244 227 229 225\n"" 1156 308 310 306 290\n"" 1157 288 310 306 307\n"" 1158 307 308 310 306\n"" 1159 251 274 254 252\n"" 1160 55 219 87 57\n"" 1161 64 63 65 62\n"" 1162 15 13 16 12\n"" 1163 190 201 189 161\n"" 1164 316 331 333 332\n"" 1165 329 331 324 315\n"" 1166 364 354 353 356\n"" 1167 166 144 147 165\n"" 1168 334 329 336 332\n"" 1169 420 422 424 416\n"" 1170 350 333 281 331\n"" 1171 322 292 321 281\n"" 1172 209 24 210 212\n"" 1173 424 37 1 41\n"" 1174 269 407 408 405\n"" 1175 429 430 407 408\n"" 1176 15 443 13 442\n"" 1177 214 221 222 83\n"" 1178 13 17 16 14\n"" 1179 333 166 315 160\n"" 1180 224 20 211 212\n"" 1181 122 201 121 453\n"" 1182 246 247 245 256\n"" 1183 391 393 416 394\n"" 1184 37 44 38 39\n"" 1185 344 354 355 356\n"" 1186 189 147 333 160\n"" 1187 437 208 433 207\n"" 1188 181 195 178 179\n"" 1189 403 376 402 373\n"" 1190 183 180 181 196\n"" 1191 433 276 438 437\n"" 1192 380 273 382 381\n"" 1193 209 24 26 210\n"" 1194 379 406 404 268\n"" 1195 7 451 424 3\n"" 1196 400 402 373 403\n"" 1197 21 207 211 26\n"" 1198 451 41 1 420\n"" 1199 201 149 279 281\n"" 1200 347 344 354 340\n"" 1201 419 417 415 414\n"" 1202 344 345 346 343\n"" 1203 79 83 76 82\n"" 1204 128 133 130 127\n"" 1205 6 424 37 7\n"" 1206 190 147 201 161\n"" 1207 87 218 55 83\n"" 1208 39 44 41 37\n"" 1209 245 242 235 243\n"" 1210 389 41 392 420\n"" 1211 24 212 20 19\n"" 1212 451 41 420 424\n"" 1213 78 75 50 79\n"" 1214 440 257 263 225\n"" 1215 81 83 76 218\n"" 1216 385 378 387 381\n"" 1217 430 387 384 408\n"" 1218 329 315 324 316\n"" 1219 281 280 279 453\n"" 1220 279 205 206 453\n"" 1221 253 254 274 252\n"" 1222 325 357 356 354\n"" 1223 443 17 13 14\n"" 1224 322 292 281 320\n"" 1225 399 372 397 400\n"" 1226 56 76 53 55\n"" 1227 212 231 18 230\n"" 1228 24 26 211 209\n"" 1229 420 1 426 41\n"" 1230 182 196 183 197\n"" 1231 229 74 80 15\n"" 1232 118 347 126 128\n"" 1233 180 195 178 181\n"" 1234 361 358 357 113\n"" 1235 239 213 215 238\n"" 1236 224 229 15 18\n"" 1237 423 68 94 414\n"" 1238 6 45 37 448\n"" 1239 48 360 111 413\n"" 1240 302 301 286 303\n"" 1241 35 41 1 37\n"" 1242 431 278 434 433\n"" 1243 145 164 162 150\n"" 1244 174 173 171 172\n"" 1245 423 279 367 448\n"" 1246 362 423 107 206\n"" 1247 272 271 251 274\n"" 1248 273 385 378 387\n"" 1249 200 122 177 159\n"" 1250 452 425 447 449\n"" 1251 210 29 26 209\n"" 1252 130 135 136 128\n"" 1253 234 213 237 235\n"" 1254 216 54 217 32\n"" 1255 402 373 376 374\n"" 1256 164 143 165 150\n"" 1257 427 250 410 411\n"" 1258 386 388 250 410\n"" 1259 96 61 59 95\n"" 1260 159 200 187 177\n"" 1261 389 443 442 80\n"" 1262 398 395 396 399\n"" 1263 87 83 55 76\n"" 1264 389 77 74 80\n"" 1265 229 15 80 225\n"" 1266 207 433 278 208\n"" 1267 96 59 91 95\n"" 1268 341 126 135 118\n"" 1269 62 61 59 58\n"" 1270 206 149 279 453\n"" 1271 400 370 372 374\n"" 1272 389 35 426 74\n"" 1273 360 423 362 413\n"" 1274 54 228 32 31\n"" 1275 109 38 107 360\n"" 1276 87 83 84 219\n"" 1277 72 35 69 389\n"" 1278 246 262 247 256\n"" 1279 352 364 353 365\n"" 1280 268 273 406 269\n"" 1281 443 74 13 80\n"" 1282 242 244 241 229\n"" 1283 149 279 362 206\n"" 1284 99 64 66 97\n"" 1285 376 373 92 374\n"" 1286 26 29 25 27\n"" 1287 32 213 228 216\n"" 1288 118 163 341 354\n"" 1289 161 158 147 157\n"" 1290 61 60 44 91\n"" 1291 292 308 304 291\n"" 1292 163 144 165 162\n"" 1293 407 262 430 429\n"" 1294 63 62 61 59\n"" 1295 153 163 154 168\n"" 1296 350 281 322 321\n"" 1297 262 271 270 274\n"" 1298 442 426 428 444\n"" 1299 38 44 42 39\n"" 1300 80 240 229 243\n"" 1301 194 171 174 175\n"" 1302 155 362 325 112\n"" 1303 306 304 291 305\n"" 1304 77 78 74 80\n"" 1305 80 74 240 78\n"" 1306 38 44 94 47\n"" 1307 273 405 408 406\n"" 1308 293 298 285 286\n"" 1309 88 389 390 77\n"" 1310 311 304 292 308\n"" 1311 99 66 98 97\n"" 1312 26 210 24 25\n"" 1313 259 224 276 207\n"" 1314 61 62 64 58\n"" 1315 244 242 235 245\n"" 1316 244 241 235 242\n"" 1317 63 61 64 66\n"" 1318 149 201 279 453\n"" 1319 206 122 121 453\n"" 1320 413 366 362 365\n"" 1321 409 388 250 387\n"" 1322 423 362 413 418\n"" 1323 38 414 48 47\n"" 1324 38 360 423 107\n"" 1325 290 289 288 306\n"" 1326 333 322 323 331\n"" 1327 389 443 74 426\n"" 1328 35 71 389 41\n"" 1329 279 149 362 331\n"" 1330 74 12 15 35\n"" 1331 424 423 422 448\n"" 1332 190 201 177 200\n"" 1333 365 325 353 352\n"" 1334 385 383 384 273\n"" 1335 331 322 321 350\n"" 1336 71 70 389 393\n"" 1337 126 139 339 137\n"" 1338 44 45 92 91\n"" 1339 72 49 69 35\n"" 1340 175 178 174 195\n"" 1341 247 246 245 261\n"" 1342 41 424 448 420\n"" 1343 46 92 44 94\n"" 1344 402 400 373 374\n"" 1345 198 197 185 188\n"" 1346 304 296 294 283\n"" 1347 116 131 129 128\n"" 1348 50 15 74 33\n"" 1349 110 108 112 109\n"" 1350 448 425 424 447\n"" 1351 166 331 362 149\n"" 1352 206 149 103 107\n"" 1353 209 26 208 29\n"" 1354 211 231 224 212\n"" 1355 33 50 51 240\n"" 1356 32 213 234 228\n"" 1357 444 389 426 443\n"" 1358 107 112 108 109\n"" 1359 217 213 214 215\n"" 1360 16 22 436 21\n"" 1361 142 337 144 338\n"" 1362 323 311 322 320\n"" 1363 411 386 389 250\n"" 1364 265 273 264 382\n"" 1365 211 230 231 212\n"" 1366 295 296 294 297\n"" 1367 0 35 1 37\n"" 1368 229 74 33 240\n"" 1369 131 118 116 117\n"" 1370 122 204 101 201\n"" 1371 206 122 204 101\n"" 1372 83 220 86 219\n"" 1373 113 358 347 123\n""# Generated by tetgen -YY bunny.smesh \n"); } diff --git a/Demos/SoftDemo/cube.inl b/Demos/SoftDemo/cube.inl new file mode 100755 index 0000000..7015a23 --- /dev/null +++ b/Demos/SoftDemo/cube.inl @@ -0,0 +1,4 @@ +static const char* getNodes() { return( +"400 3 0 0\n"" 0 1 1 -1\n"" 1 1 -1 -1\n"" 2 -1 -1 -1\n"" 3 1 1 1\n"" 4 -1 -1 1\n"" 5 -1 1 -1\n"" 6 1 -1 1\n"" 7 -1 1 1\n"" 8 -1 -1 -0.000116\n"" 9 0.00039500000000000006 -1 1\n"" 10 1 -1 -0.00065799999999999995\n"" 11 1 0.00061700000000000004 -1\n"" 12 0.00098999999999999999 1 -1\n"" 13 -1 1 0.00045400000000000008\n"" 14 0.00052800000000008396 1 1\n"" 15 1 1 -0.00038699999999991519\n"" 16 -1 -5.9999999999504894e-006 1\n"" 17 -1 0.00021000000000004349 -1\n"" 18 1 0.00067400000000006344 1\n"" 19 1.0863393114549872e-007 3.0682525964387253e-008 1\n"" 20 0.00097299999999989062 -1 -1\n"" 21 -1.4065544284846965e-008 1 5.0429866114086973e-008\n"" 22 1 -7.0792689266241382e-008 -4.4728299621228391e-008\n"" 23 8.4069120565846353e-008 3.8392827594879719e-007 -1\n"" 24 1 0.49980668112692161 -0.4996917965899465\n"" 25 1 0.50006700000000004 -1\n"" 26 1 1 -0.50034809999999996\n"" 27 1 1 0.50025040000000009\n"" 28 0.50020930000000008 1 1\n"" 29 -1 0.50010129999999997 1\n"" 30 -0.49958379999999991 1 1\n"" 31 -1 9.2038384777827427e-008 -1.100605984127867e-008\n"" 32 -0.5001201999999999 -1 1\n"" 33 1.0486788869007099e-007 -1 -3.3620911388254626e-008\n"" 34 -1 -1 0.50008699999999995\n"" 35 1 -0.50010220000000005 -1\n"" 36 1 -1 -0.49985400000000002\n"" 37 1 -0.4996526 1\n"" 38 1 -1 0.49990490000000004\n"" 39 -0.49930649999999999 1 -1\n"" 40 -1 1 -0.50002420000000003\n"" 41 1 -0.24974260000000004 -0.50015432157969908\n"" 42 0.50015422769290296 -0.24974260000000001 -1\n"" 43 0.50009680402228707 1 0.24993170000000009\n"" 44 1 0.50009675187018254 0.24993170000000009\n"" 45 0.24987467313200107 0.24987468273492527 -0.24987454967853764\n"" 46 0.50006970000000006 1 -1\n"" 47 -1 1 0.50062509999999982\n"" 48 -0.24952789999999991 1 0.50013191885453001\n"" 49 -0.24952789999999991 0.50013187836130635 1\n"" 50 -1 -0.50000239999999996 -1\n"" 51 -0.49917350000000005 -1 -1\n"" 52 -1 -0.37500110896930483 0.49999770999384097\n"" 53 -0.49999768418870116 -0.37500109958532857 1\n"" 54 0.50016842960649455 -0.24948929999999997 1\n"" 55 1 -0.24948929999999997 0.50016837821653382\n"" 56 -1 0.50011355427218929 -0.24978510000000004\n"" 57 -0.50011349993113807 1 -0.24978510000000009\n"" 58 0.49983560886453382 -1 -0.25025600000000003\n"" 59 1 -0.24959280000000006 -1\n"" 60 0.46861653427920624 0.31279234072878337 -1\n"" 61 0.46874721181012263 1 -0.31263609558485356\n"" 62 1 1 0.24986720000000007\n"" 63 1 0.50004500000000007 1\n"" 64 0.41666006216462159 0.41668749191836219 1\n"" 65 1 0.62492318088559184 0.62497446433589154\n"" 66 0.62493687874554793 1 0.62494713479954256\n"" 67 -0.32510780807963724 -0.32510780489834346 -0.32510793388507692\n"" 68 1 0.12495484505171366 -0.3748231366627352\n"" 69 -0.24915825000000003 0.50024732783000192 -1\n"" 70 1 0.74957571448653726 -0.74971600694021778\n"" 71 0.64874656072370729 1 -0.64882932411306993\n"" 72 0.6488668035834122 0.64886599996407779 -1\n"" 73 -1 0.41673079803079871 0.41664307505523179\n"" 74 -0.62468209179782908 1 0.62494186195929313\n"" 75 -0.62476903429567798 0.62489835940819183 1\n"" 76 -1 0.75020764999999989 1\n"" 77 0.12520010648567331 0.45856412436943739 0.37477910185628149\n"" 78 -0.24942439999999994 1 1\n"" 79 -0.37474797737976173 1 0.74996984889996166\n"" 80 -0.3748348177892612 0.74992638728967431 1\n"" 81 -1 -1 -0.49994339999999993\n"" 82 -0.50002894420427402 -1 0.24998549999999997\n"" 83 -1 -0.50045000000000006 1\n"" 84 -0.015617775048046156 -0.5000062299955631 1\n"" 85 -0.062520154989433377 -1 0.50002475010607028\n"" 86 0.50024029999999997 -1 1\n"" 87 1 -0.24929619999999997 1\n"" 88 0.37505270907528421 -0.3750526949043349 0.12522791934472338\n"" 89 -1 0.5001348000000001 -1\n"" 90 -1 1 -0.24999450000000001\n"" 91 1 -0.62477132796083668 -0.25025600000000003\n"" 92 0.50052129999999995 -1 -1\n"" 93 1 0.018238422269637886 -0.6785517711937521\n"" 94 0.750039598406532 -0.12448790000000004 -1\n"" 95 0.32367160517680327 0.022514689090561368 -0.65701963759824777\n"" 96 0.32369468988306127 0.65698780035674154 -0.022395524628340657\n"" 97 1 1 -0.25020424999999996\n"" 98 1 0.62501462613012171 -0.12492844204372336\n"" 99 0.16205966081319645 0.60689608104137205 -1\n"" 100 0.23307615322925276 1 -0.65509826790501591\n"" 101 0.6349049175761754 0.105723024682608 1\n"" 102 1 0.18290638148392097 0.59627500837254621\n"" 103 0.67708420758319754 0.67702605426027662 1\n"" 104 1 0.7498625000000001 1\n"" 105 0.75029925000000008 1 1\n"" 106 0.75006454389022692 1 0.37500606926950353\n"" 107 1 0.7500645207487896 0.37502882687227923\n"" 108 -0.39273716375981493 0.28664398202145958 -0.051638660454459806\n"" 109 -0.41671246738153483 -0.41657507574696978 -1\n"" 110 -0.24910025000000008 -1 -0.50024283860374685\n"" 111 -1 -0.50000177258228129 0.01562108247952367\n"" 112 -1 0.062713405747402015 -0.49998686350971472\n"" 113 -0.21672667787876426 1 -0.60296047487967241\n"" 114 1 0.7499052299192317 -0.37495181123207261\n"" 115 0.74540338978064358 1 -0.37527617499999999\n"" 116 0.52159008257288741 0.55923294709068649 -0.50062662770660094\n"" 117 0.75009235000000007 1 -1\n"" 118 -0.52928249862025711 0.10679011696853863 1\n"" 119 -1 0.034077217919757319 0.58381620432891879\n"" 120 -1 0.7383278941763165 0.25053954999999994\n"" 121 -0.70891631291249579 1 0.25053954999999989\n"" 122 -0.46050965421976553 0.49218708190674731 0.49218708126315491\n"" 123 -1 0.68039176952095026 0.65291562053589947\n"" 124 0.10567541850782136 0.6349221513724419 1\n"" 125 0.18288602711749127 1 0.59629803533945958\n"" 126 0.54298856425431818 0.54298737875163716 0.56762073808494473\n"" 127 -0.67702799351191578 -0.67732215502802495 -1\n"" 128 -0.74942264999999997 -1 -1\n"" 129 -1 -1 -0.74980449999999998\n"" 130 -1 -0.49218854513728494 -0.49218946358719012\n"" 131 -0.42414945787750447 -1 0.62500198796368489\n"" 132 -0.34611026252144428 -0.35284219355707647 0.34611025416343177\n"" 133 -1 -0.25018009999999996 1\n"" 134 1 -0.62478846817134759 0.62485153607962096\n"" 135 0.46873640237350567 -1 0.46875741869756882\n"" 136 0.62487945516234578 -0.62473271086601501 1\n"" 137 1 -1 0.75017445000000005\n"" 138 0.74996116568713633 -0.37481680473944939 1\n"" 139 1 -0.37487247538331225 0.74993327711783697\n"" 140 0.52037384429375466 0.13732055395658338 0.20134643019667742\n"" 141 0.15110486348630267 -0.58850137906978839 -0.32248691722782763\n"" 142 0.18460607304185575 -0.25601325165021294 0.59072519783751942\n"" 143 0.58280144730296801 -0.1236683742487249 -0.25429890766156527\n"" 144 -0.62459780071323356 0.62480472798869868 -1\n"" 145 -1 0.62491663124728913 -0.6248890159372763\n"" 146 -0.62484746422599169 1 -0.62502715932999464\n"" 147 -0.7093663193037405 1 -0.043380902757278066\n"" 148 -1 0.70881555044570888 -0.042280622034258974\n"" 149 1 -1 -0.25034290000000009\n"" 150 1 -0.40640338795560693 0.10958986646960317\n"" 151 0.62965348921187414 -1 0.11553823232370244\n"" 152 0.62491481284490769 -0.62481034920526324 -1\n"" 153 0.62518044398996542 -1 -0.62501367730297908\n"" 154 1 -0.63771354537448766 -0.63764519345816328\n"" 155 1 0.31875234539841601 -0.74994017167142224\n"" 156 1 0.25014510000000001 -1\n"" 157 0.74289722234692146 0.382058894292784 -1\n"" 158 0.32367160517680327 0.022514689090561313 -1\n"" 159 -0.16523027793533418 0.12134647368575949 -0.52708319267772263\n"" 160 0.66127538009577513 0.12758426427554953 -1\n"" 161 0.66190311587317174 -0.14472935797430672 -0.63288146125613987\n"" 162 0.32369468988306133 1 -0.022395524628340657\n"" 163 0.66678290425073372 1 -0.041514421404229618\n"" 164 0.25040265000000006 1 -1\n"" 165 0.0399620660587649 1 -0.35479393735090492\n"" 166 0.39507172571995386 0.7484116421252891 -1\n"" 167 1 -0.072369672334633761 0.72403943393322545\n"" 168 1 0.25022030000000006 1\n"" 169 -1 0.34715093732334323 0.069506853183406409\n"" 170 0.004224600474193374 -0.00030510666109673235 0.14430736392114327\n"" 171 -0.094962845556292308 0.5834952204256858 0.029410273259612763\n"" 172 -0.37516021595805987 -1 -0.12532788579913123\n"" 173 -0.24910025000000008 -0.73780528173239301 -1\n"" 174 -0.24899625000000003 -1 -1\n"" 175 -1 -0.68752594294730018 0.32233197415569781\n"" 176 -0.63898818329694262 -0.019780155017187176 -0.25640753531059018\n"" 177 -0.24918545000000003 1 -1\n"" 178 -0.090115044090208485 0.73312064098608642 -1\n"" 179 0.70087100707296945 0.7030864101348856 -0.70306291837965817\n"" 180 0.43929348327839085 1 -0.54468859277252801\n"" 181 0.24904127574612012 0.39074020564473289 -0.70186910867307939\n"" 182 1 0.37487410261969639 -0.24965440370335262\n"" 183 -1 0.25002235 1\n"" 184 -1 0.3834446703544917 0.71903607815447956\n"" 185 -0.1156880925075553 0.64434016438489528 0.64434017606689242\n"" 186 -0.49172745225271947 1 0.39835250767529351\n"" 187 -0.49767862299671706 0.38046779215689319 1\n"" 188 -0.71839703681869116 0.71780974657570373 0.44934935063382636\n"" 189 -0.51344827724776054 0.71469177745101886 0.71472798522876002\n"" 190 -0.23617534848477656 0.19448005635194549 1\n"" 191 0.10846459384596518 0.30820266021358389 1\n"" 192 0.25057285000000007 1 1\n"" 193 0.017230183845622971 1 0.32091029596366771\n"" 194 0.73101248242769623 0.7310147155780512 0.70877874225568527\n"" 195 0.31697048198150773 0.74665075980915008 0.4006579958540028\n"" 196 0.22826577744747956 0.47891948624469016 0.71004422740180217\n"" 197 1 0.41190390341165745 0.48757967789479273\n"" 198 0.39445308838583859 1 0.75656358081536812\n"" 199 0.37539107500000007 0.73916688955610543 1\n"" 200 1 0.37513265000000007 0.77169890914285255\n"" 201 0.73942011355234571 0.37513265000000007 1\n"" 202 0.63994038137069154 0.63994036678159205 0.2035446667438317\n"" 203 -0.46370016318896046 -0.62998103084618617 -0.61483850042635191\n"" 204 -1 -0.21786745446900305 -0.71882640763337879\n"" 205 -0.7381625142245487 -0.24989619999999996 -1\n"" 206 -1 -0.68409919087038817 -0.74320185410965045\n"" 207 -0.32233403971208485 -0.68753538843092254 1\n"" 208 -0.24999429999999997 -1 1\n"" 209 -1 -0.68747379665002328 0.68733786195201785\n"" 210 -1 -1 0.74993719999999997\n"" 211 -0.68734034505209507 -0.68746383783523624 1\n"" 212 0.012621642749083783 -0.62121055252239044 0.25549907282899653\n"" 213 -0.6302385799280833 -0.18856073836207951 0.63023858315073289\n"" 214 -1 -0.24375245663389172 0.20780956095073669\n"" 215 0.27457426263537876 -0.71671644193112283 1\n"" 216 0.25031765 -1 0.74826556642116959\n"" 217 0.67415846717387884 -1 0.72313083855082583\n"" 218 0.62503542334105555 -0.31221159888129457 0.62503541050290967\n"" 219 0.5971993096065894 0.14306806366195202 0.59872066564664705\n"" 220 1 0.017233350071975677 0.32090429254255515\n"" 221 0.26312362546126472 0.33468192363906535 0.084065768486193945\n"" 222 0.32197792152690552 -1 0.018797337932729474\n"" 223 0.18800195544968995 -1 -0.56289551925444881\n"" 224 0.57038729142869704 -0.57307887210152808 -0.20881754066389768\n"" 225 -0.0086896099297664228 -0.40801963637004723 -1\n"" 226 0.18460607304185569 -0.25601325165021294 1\n"" 227 -0.20780680948491165 -0.24375608761730455 1\n"" 228 0.16210795897650465 -0.16280891134401318 -0.30907215240469521\n"" 229 1 -0.26636148213032163 -0.17942676839456378\n"" 230 0.56446572384612781 0.1973176117738667 -0.43724659666019622\n"" 231 0.68853374013319157 -0.17744483013216472 0.09783510961497599\n"" 232 -1 0.25009230000000005 -1\n"" 233 -0.44245798368554617 0.091797696559903857 -1\n"" 234 -0.37472098690918887 0.74987909210814685 -1\n"" 235 -1 0.75000438735900432 -0.37495636858710685\n"" 236 -0.74996704638216471 1 -0.37508384505925174\n"" 237 -1 0.74990679999999998 -1\n"" 238 -0.54712707263607874 0.54712707774677038 -0.44245689687343565\n"" 239 -0.74990204999999999 1 -1\n"" 240 -0.72822316548562926 0.72874031845750664 0.1036085388532241\n"" 241 1 -0.71873547817891748 0.28112338497214717\n"" 242 1 -1 0.24972335000000001\n"" 243 0.75048264999999992 -1 -1\n"" 244 0.74989614566839657 -1 -0.37495931701899499\n"" 245 0.32778297288621805 -0.39528027615360428 -0.64821309452322518\n"" 246 1 -0.38051416654716286 -0.74727639147947866\n"" 247 0.75568696149005932 -0.39170758577960507 -1\n"" 248 0.67082477453227773 0.69774082076774491 -0.21670307025395311\n"" 249 0.25644629494787752 0.72897062001391455 -0.35498913750943906\n"" 250 -0.66044139980269567 0.12332997433814857 0.28570391360731856\n"" 251 -0.20800059812674501 0.28777064045558248 0.28593682199556314\n"" 252 0.29133599196527848 -0.095788071590640317 0.30648986161740821\n"" 253 -0.19340828105680374 -0.0068671095901119807 -0.17510149752792639\n"" 254 -0.21084753812463372 1 -0.20339622724796672\n"" 255 -0.098922382084248209 0.356624117376247 -0.256263439404529\n"" 256 -1 -0.74213790787259271 -0.24206983063972595\n"" 257 -0.72511478181115718 -1 -0.25002969999999997\n"" 258 -0.1250383368944159 -1 -0.24987830054645518\n"" 259 -0.5432409326212666 -0.58336779772250913 -0.0060938376146522089\n"" 260 -1 -1 0.25020549999999997\n"" 261 -0.69517902037783963 -1 0.48465629903462193\n"" 262 -1 0.19801494027267907 -0.22908951271298833\n"" 263 -1 -0.21170789004360985 -0.2804810168349573\n"" 264 0.12431896494966958 0.19380761445281547 -0.51506516411314296\n"" 265 0.016877018602808991 0.32057899216794972 -1\n"" 266 0.31815206866103007 0.69886802178230512 -0.69773364246572678\n"" 267 1 0.29452437620263039 0.03597223402760958\n"" 268 -0.23854616157962166 0.70039865549364788 0.32382827237146705\n"" 269 -0.072417036863037423 1 0.7240118059209224\n"" 270 -0.65715846697692126 0.26022065746019457 0.6943166148678479\n"" 271 0.032006652383344852 0.12877070459954792 0.60754383991332461\n"" 272 0.70679839053632465 0.35784100137989416 0.35408213575434944\n"" 273 1 0.75583880296190964 0.10796710954834202\n"" 274 -0.066417091587110066 -0.67493516441615642 -0.64835749920354258\n"" 275 -0.66000110931003353 -0.29732769674682547 -0.5356675566159671\n"" 276 -1 -0.7460956789293286 -0.49597432811515113\n"" 277 -0.63537062135554268 -1 -0.62487395000000001\n"" 278 -0.072189529852730625 -0.75207129129950046 1\n"" 279 -0.12479964999999998 -1 0.76180792382505302\n"" 280 -0.64633703603487636 -0.58450521092750218 0.50482020379778969\n"" 281 -0.19793040641595078 -1 0.22917284009874619\n"" 282 0.36430902573049584 -0.60319992435881997 0.46610302519244695\n"" 283 -0.014560432971481855 -0.28974170434477692 0.31899501601243035\n"" 284 -0.16677858939457951 -0.59736466720530357 0.62746423626615599\n"" 285 -0.70838149553417962 -0.14588171485233958 1\n"" 286 -1 -0.20773576611374234 0.72382280144202749\n"" 287 0.65401865792186442 -0.65865126715652123 0.6540215253821221\n"" 288 0.76868552550191671 -0.1162896631221611 1\n"" 289 0.39236022879703553 0.3070079448900544 0.42979647060190596\n"" 290 0.3368388593683827 0.015623435483033674 1\n"" 291 0.19283437348027005 -1 0.30983198636425424\n"" 292 0.23987671409711908 -0.66618838122351409 0.0008945936534150746\n"" 293 0.42213117252176491 -0.74712687995942406 -0.48458654817973601\n"" 294 1 -0.66026812967233972 0.017464640590841476\n"" 295 0.76163529643898698 -1 -0.11209435873849422\n"" 296 0.71607191560259942 -0.37037315933178871 -0.41086960011962592\n"" 297 -0.21716346053460103 -0.19947717862659675 -1\n"" 298 -0.066700914192858729 -0.25756978212559839 -0.62896708724727191\n"" 299 0.32965714090299714 -0.016623876027232615 -0.04345086208713933\n"" 300 0.3771146741942551 -0.33750921003054202 -0.17865283786030017\n"" 301 0.68867680851486557 0.35765454098697025 -0.68521532739244984\n"" 302 0.68683764447685003 -0.49596319168560488 0.30085803648362652\n"" 303 0.7090270874729655 -0.090415723473831255 0.40719961870896915\n"" 304 -0.71897798523587353 0.032300798531047246 -1\n"" 305 -0.78106895850102998 0.78106955040650416 -1\n"" 306 -1 1 -0.75022459999999991\n"" 307 -0.6917164744917017 0.69170418541265011 -0.69178840942223951\n"" 308 -0.44874465612278081 0.23033846865992608 -0.37975265656437374\n"" 309 -0.42791646676676653 1 -0.48213646482850109\n"" 310 -0.50093773209802361 0.36943796178744326 -1\n"" 311 -0.27376979380830829 0.64426231976101334 -0.66489790575084351\n"" 312 -1 0.35637030336560244 -0.50592472907968644\n"" 313 -0.67546025565396317 0.47435524682845248 -0.12755140965778172\n"" 314 1 -1 -0.74991180000000002\n"" 315 1 -0.75028080000000008 -1\n"" 316 0.75389683099717963 -0.68868788457723729 -0.44203141186583489\n"" 317 0.30599251534318156 -0.52261127269823027 -1\n"" 318 0.40047237565428867 -0.18178393484624253 -0.46933497457143036\n"" 319 0.59482353914036401 0.38624515090984007 -0.049897636224658731\n"" 320 -1 0.12332997433814856 0.2857039136073185\n"" 321 -1 -0.14689524813441618 0.42688908174824769\n"" 322 -0.66262979736993932 -0.22367581355790006 0.28652907305244368\n"" 323 -0.73506511384989526 0.43296210769478211 0.23284828493726362\n"" 324 -0.35917397776062404 -0.0011820981956873755 0.46134022362807492\n"" 325 -0.46329592253134338 -0.04321417701540118 0.047101266600350966\n"" 326 -0.27019578023748486 0.66094639539627242 -0.2626201492532621\n"" 327 -0.034393111593928383 0.28261880242562187 0.033764464745287937\n"" 328 0.18250360638285329 -1 -0.25535398043003921\n"" 329 -0.3030416241215706 -0.68638401151842854 -0.29392180366815041\n"" 330 -0.20024923856661142 -0.43390131265744347 0.010814269493628442\n"" 331 -0.70928533124789683 -1 0.043514240508664342\n"" 332 -0.66723744746271052 -0.6603325322519602 -0.32775579384930814\n"" 333 -0.75004930000000003 -1 1\n"" 334 -0.19527119007052851 0.17101403421852743 -1\n"" 335 0.035377884590221398 0.72616811699961958 0.38837547693302749\n"" 336 -0.3958963327893722 1 0.076655950240576198\n"" 337 -1 0.21457329427678187 0.47543850615348943\n"" 338 -0.7309823244201562 0.04824246580043276 0.53867561355267524\n"" 339 0.31731660817460328 0.019726050398274825 0.58867762989660533\n"" 340 -0.23374781763549932 0.32728908975345111 0.68606341552187544\n"" 341 -0.05707064185106852 -1 -0.71659883209883557\n"" 342 0.025895325626349025 -1 -0.41197380535174077\n"" 343 -0.63238580600180661 -0.3446250983839011 -0.21239475499198135\n"" 344 -1 -0.44899498782248648 -0.76904522126668295\n"" 345 -0.47299161220497166 -0.16458691872110107 -1\n"" 346 -0.71473237282422963 -0.73570249654826969 -0.71737349776128545\n"" 347 -0.74042724546706096 -1 0.74043153378626769\n"" 348 -0.75006482996996637 -0.43746254158362985 1\n"" 349 -1 -0.45163184813329721 0.75853196322407168\n"" 350 -0.50484417551448635 -0.72312317896459377 0.74770602252103513\n"" 351 -0.40758966352762416 -0.67845102844514626 0.2869272680702189\n"" 352 0.34674400209661604 -0.46348651949776365 1\n"" 353 -0.064367666161959269 -0.33637242545568102 0.74735946563471645\n"" 354 0.092602515587840606 -0.73476755239921543 0.53136369836931496\n"" 355 0.7405253302829875 -1 0.37931276242110001\n"" 356 0.72074474478028516 -0.071123657589263783 0.72858260191381197\n"" 357 -0.37493998320650845 -0.13123609584112483 -0.59370675998889832\n"" 358 -0.038352185780633007 -0.36921106178200458 -0.36036098843849301\n"" 359 -0.21058188105209746 -0.51336343843000509 -1\n"" 360 0.48755585676167218 -0.72413212665883209 0.19600157800093837\n"" 361 0.72678157399644117 -0.45646629587434373 0.011780680786240783\n"" 362 1 -0.2170765504241112 0.26033741814256661\n"" 363 -0.74541512030390267 -0.021189991595686748 -0.68170217165320612\n"" 364 -0.37387254482300358 0.32527982613660117 -0.69267828171913437\n"" 365 0.014913421017989981 0.548850834537849 -0.51262186425268497\n"" 366 -0.74537069514237131 0.2884463439624349 -1\n"" 367 -1 0.37511355000000007 -0.76842458715696027\n"" 368 -0.68532657097754035 0.18056419100293586 -0.02075972921423834\n"" 369 0.78133395148913365 -1 -0.78126287896225588\n"" 370 0.78115294817471781 -0.78112807555219699 -1\n"" 371 0.59082087507768066 -0.57000731366339108 -0.68829605397498683\n"" 372 0.062122976656860403 -0.70293283755163305 -1\n"" 373 0.71559274300689513 0.42281759201802555 -0.31813908171117911\n"" 374 0.7564597747876356 0.13217713297538497 -0.16417576007580004\n"" 375 0.40814884545639363 0.4915141193769953 -0.2436752542444009\n"" 376 -0.75696767061236314 -0.5164837362163468 0.21622587965261447\n"" 377 -0.452391830423859 0.55519361636450704 0.12429201972918034\n"" 378 -0.43481019055019038 -0.12925317405502307 1\n"" 379 -0.24742795067222612 -0.11366422696012682 0.2223275751188645\n"" 380 -0.006677616808027087 -0.21615237698969206 -0.065426614396930594\n"" 381 -0.062406752747729527 -0.70182414510247981 -0.087999792237402064\n"" 382 0.10306104864954116 0.76464771966531997 0.11700653142882178\n"" 383 0.27486783995540093 -0.12812237061584772 0.79536259891875982\n"" 384 -0.74059417471417499 -0.15757730258109431 0.00074049988054281091\n"" 385 -0.64002796579304344 -0.45394506207193958 -1\n"" 386 -0.42239397063762912 -0.42048979870740139 0.69490811148992537\n"" 387 -0.17195299402586212 -0.76346805360446235 0.40560748360163079\n"" 388 0.37676760090127209 -0.4417530820461561 0.70978247252690463\n"" 389 -0.20593363392839478 -0.044483242006169432 0.7439953909431003\n"" 390 -0.31521564832256066 -0.39420460209868968 -0.72065547292536469\n"" 391 -0.07315504595340451 0.34077703680706245 -0.71267230392230696\n"" 392 -0.0052948425242513517 1 -0.74523404665783877\n"" 393 -0.70127839101164502 0.30537699044254324 -0.64148488859352526\n"" 394 0.25061214999999992 -1 -1\n"" 395 0.40565131063307963 -0.76032995286218041 -1\n"" 396 0.38398614307047785 -1 -0.75304567260853106\n"" 397 0.23839244367761547 -0.68688896416028877 -0.73641430830181331\n"" 398 0.76674691103343318 0.57740125411814403 -0.50231823898754502\n"" 399 0.14110565781161721 -0.59279131304323562 0.77705687354697894\n""# Generated by tetgen -a0.01 cube.smesh \n"); } +static const char* getElements() { return( +"1580 4 0\n"" 0 120 148 13 240\n"" 1 77 251 185 268\n"" 2 126 194 66 198\n"" 3 297 298 159 357\n"" 4 13 148 147 240\n"" 5 219 272 102 303\n"" 6 134 137 37 136\n"" 7 302 360 88 361\n"" 8 23 264 95 391\n"" 9 307 311 238 364\n"" 10 57 309 254 326\n"" 11 345 357 233 363\n"" 12 176 343 325 384\n"" 13 275 332 67 343\n"" 14 141 245 228 318\n"" 15 108 368 323 377\n"" 16 7 47 74 123\n"" 17 73 188 184 270\n"" 18 56 235 148 313\n"" 19 46 72 117 179\n"" 20 66 105 28 194\n"" 21 205 275 204 344\n"" 22 66 194 28 198\n"" 23 96 221 45 375\n"" 24 93 160 94 161\n"" 25 225 317 245 397\n"" 26 121 186 74 188\n"" 27 213 280 52 322\n"" 28 52 322 280 376\n"" 29 96 195 77 221\n"" 30 8 257 256 331\n"" 31 358 380 330 381\n"" 32 99 181 166 266\n"" 33 120 123 73 188\n"" 34 122 189 187 340\n"" 35 141 292 224 300\n"" 36 313 326 240 377\n"" 37 203 274 173 390\n"" 38 140 299 221 319\n"" 39 44 197 107 272\n"" 40 171 326 108 377\n"" 41 71 166 46 179\n"" 42 69 364 334 391\n"" 43 26 114 97 115\n"" 44 228 253 159 358\n"" 45 221 272 202 289\n"" 46 123 184 73 188\n"" 47 22 220 140 231\n"" 48 250 324 322 325\n"" 49 270 324 213 338\n"" 50 147 240 57 336\n"" 51 69 265 178 391\n"" 52 100 249 165 365\n"" 53 296 316 224 371\n"" 54 74 188 186 189\n"" 55 21 171 165 249\n"" 56 23 297 225 298\n"" 57 191 196 64 290\n"" 58 87 139 138 288\n"" 59 126 198 196 199\n"" 60 223 328 141 342\n"" 61 293 371 153 396\n"" 62 238 308 108 313\n"" 63 49 187 80 189\n"" 64 143 300 224 361\n"" 65 111 256 130 343\n"" 66 62 107 106 273\n"" 67 64 196 126 219\n"" 68 314 154 315 369\n"" 69 50 205 204 344\n"" 70 0 70 26 71\n"" 71 95 158 23 265\n"" 72 37 138 87 139\n"" 73 125 193 43 195\n"" 74 56 312 238 313\n"" 75 257 259 172 332\n"" 76 25 70 0 72\n"" 77 141 300 228 358\n"" 78 32 207 208 350\n"" 79 101 201 200 219\n"" 80 13 147 121 240\n"" 81 67 275 176 357\n"" 82 116 249 180 266\n"" 83 197 219 200 272\n"" 84 152 247 42 371\n"" 85 95 158 60 160\n"" 86 45 230 116 375\n"" 87 88 282 142 283\n"" 88 96 162 61 249\n"" 89 209 280 211 350\n"" 90 84 353 226 399\n"" 91 33 258 172 381\n"" 92 118 285 213 378\n"" 93 196 271 77 289\n"" 94 282 287 218 388\n"" 95 196 198 125 199\n"" 96 74 7 76 30\n"" 97 95 230 181 264\n"" 98 297 359 225 390\n"" 99 280 347 261 350\n"" 100 253 299 170 380\n"" 101 125 269 193 335\n"" 102 245 293 224 300\n"" 103 41 143 68 161\n"" 104 58 295 244 316\n"" 105 83 348 211 349\n"" 106 75 29 76 123\n"" 107 171 249 96 255\n"" 108 124 196 125 199\n"" 109 61 248 96 249\n"" 110 221 255 45 327\n"" 111 254 326 171 336\n"" 112 194 198 126 199\n"" 113 208 278 9 279\n"" 114 94 93 11 160\n"" 115 275 357 345 363\n"" 116 127 173 109 203\n"" 117 134 139 55 218\n"" 118 45 255 253 327\n"" 119 154 35 315 370\n"" 120 283 284 142 353\n"" 121 186 336 268 377\n"" 122 59 93 11 94\n"" 123 110 203 51 277\n"" 124 59 246 94 247\n"" 125 116 248 61 249\n"" 126 41 229 143 296\n"" 127 91 154 36 316\n"" 128 71 179 116 180\n"" 129 45 299 221 327\n"" 130 319 373 182 374\n"" 131 64 219 101 290\n"" 132 116 301 179 398\n"" 133 122 323 188 377\n"" 134 182 373 68 374\n"" 135 97 115 114 248\n"" 136 60 158 95 181\n"" 137 185 268 48 335\n"" 138 66 125 43 195\n"" 139 86 215 136 287\n"" 140 106 202 163 273\n"" 141 43 106 66 195\n"" 142 271 324 283 389\n"" 143 95 158 42 245\n"" 144 186 188 122 189\n"" 145 25 179 157 301\n"" 146 173 274 110 341\n"" 147 136 138 37 287\n"" 148 244 293 58 316\n"" 149 107 197 65 272\n"" 150 42 160 158 161\n"" 151 28 105 103 194\n"" 152 200 201 126 219\n"" 153 147 235 90 236\n"" 154 224 292 141 293\n"" 155 220 272 140 303\n"" 156 4 209 83 211\n"" 157 207 278 208 279\n"" 158 296 300 143 318\n"" 159 226 352 84 399\n"" 160 104 65 63 194\n"" 161 212 282 88 283\n"" 162 255 308 238 364\n"" 163 150 229 91 361\n"" 164 43 163 106 202\n"" 165 126 219 196 289\n"" 166 48 185 79 189\n"" 167 257 329 110 332\n"" 168 170 299 252 380\n"" 169 30 74 75 76\n"" 170 30 79 78 80\n"" 171 39 234 146 307\n"" 172 218 252 142 339\n"" 173 185 251 77 340\n"" 174 102 200 197 219\n"" 175 49 189 185 340\n"" 176 213 348 286 349\n"" 177 133 286 285 348\n"" 178 65 197 126 272\n"" 179 187 189 49 340\n"" 180 213 285 53 378\n"" 181 63 194 65 200\n"" 182 131 279 85 387\n"" 183 120 169 148 323\n"" 184 197 200 126 272\n"" 185 46 166 72 179\n"" 186 15 248 98 273\n"" 187 98 114 24 373\n"" 188 46 180 100 266\n"" 189 22 231 140 374\n"" 190 171 335 77 382\n"" 191 27 106 62 107\n"" 192 255 264 159 391\n"" 193 132 325 322 379\n"" 194 240 323 313 377\n"" 195 155 160 93 301\n"" 196 221 299 170 327\n"" 197 158 160 95 161\n"" 198 79 80 30 189\n"" 199 178 365 311 391\n"" 200 16 285 133 286\n"" 201 249 255 171 365\n"" 202 188 270 73 323\n"" 203 162 165 61 249\n"" 204 107 126 65 194\n"" 205 155 156 93 160\n"" 206 219 303 102 356\n"" 207 259 330 132 351\n"" 208 224 293 141 300\n"" 209 77 271 170 289\n"" 210 231 252 140 299\n"" 211 147 240 148 313\n"" 212 152 370 153 395\n"" 213 154 246 35 247\n"" 214 291 354 212 387\n"" 215 211 348 280 349\n"" 216 144 234 39 307\n"" 217 212 292 33 381\n"" 218 133 348 83 349\n"" 219 119 337 270 338\n"" 220 120 188 73 323\n"" 221 211 280 209 349\n"" 222 209 211 333 347\n"" 223 251 325 108 379\n"" 224 236 238 146 309\n"" 225 274 329 110 342\n"" 226 39 305 144 307\n"" 227 144 305 89 307\n"" 228 96 249 248 375\n"" 229 113 178 177 392\n"" 230 91 294 224 295\n"" 231 94 160 42 161\n"" 232 165 171 21 326\n"" 233 170 324 251 379\n"" 234 211 347 209 350\n"" 235 116 179 115 398\n"" 236 214 263 31 384\n"" 237 70 117 71 0\n"" 238 43 195 96 202\n"" 239 90 235 40 236\n"" 240 134 136 37 287\n"" 241 67 253 159 357\n"" 242 33 328 258 381\n"" 243 71 116 115 180\n"" 244 55 241 134 302\n"" 245 155 301 24 398\n"" 246 275 345 205 363\n"" 247 52 209 175 280\n"" 248 287 302 241 355\n"" 249 79 185 48 269\n"" 250 45 181 116 230\n"" 251 68 182 24 373\n"" 252 106 126 66 195\n"" 253 170 299 253 327\n"" 254 228 298 245 358\n"" 255 275 357 67 390\n"" 256 126 195 77 196\n"" 257 176 275 67 343\n"" 258 17 363 232 367\n"" 259 248 249 116 375\n"" 260 251 324 250 325\n"" 261 122 251 185 340\n"" 262 238 311 309 326\n"" 263 157 160 155 301\n"" 264 60 181 99 265\n"" 265 98 248 114 373\n"" 266 34 261 209 347\n"" 267 132 330 212 351\n"" 268 245 274 141 358\n"" 269 190 191 19 271\n"" 270 236 238 57 313\n"" 271 105 104 103 194\n"" 272 94 246 161 247\n"" 273 35 246 59 247\n"" 274 140 319 267 374\n"" 275 212 281 33 291\n"" 276 117 71 46 179\n"" 277 70 117 72 179\n"" 278 159 253 228 264\n"" 279 80 185 49 189\n"" 280 209 333 4 210\n"" 281 2 128 127 206\n"" 282 100 164 46 166\n"" 283 74 76 7 123\n"" 284 80 187 75 189\n"" 285 103 194 63 201\n"" 286 171 326 249 365\n"" 287 136 6 137 37\n"" 288 216 291 85 354\n"" 289 47 120 13 121\n"" 290 101 288 54 356\n"" 291 130 263 111 343\n"" 292 168 200 101 201\n"" 293 68 143 41 229\n"" 294 282 291 135 354\n"" 295 49 191 190 340\n"" 296 184 189 75 270\n"" 297 202 272 126 289\n"" 298 218 356 339 383\n"" 299 352 388 215 399\n"" 300 124 192 125 269\n"" 301 70 117 0 72\n"" 302 136 218 138 287\n"" 303 108 255 171 327\n"" 304 223 293 153 396\n"" 305 25 156 155 157\n"" 306 115 116 61 180\n"" 307 320 321 250 338\n"" 308 60 166 99 181\n"" 309 228 245 141 358\n"" 310 127 346 203 385\n"" 311 96 249 171 382\n"" 312 219 272 140 289\n"" 313 112 275 204 363\n"" 314 126 197 65 200\n"" 315 270 337 250 338\n"" 316 42 158 95 161\n"" 317 183 187 118 270\n"" 318 212 283 132 284\n"" 319 204 275 205 363\n"" 320 165 180 61 249\n"" 321 67 275 203 332\n"" 322 14 185 80 269\n"" 323 224 296 91 316\n"" 324 209 261 175 280\n"" 325 290 339 219 383\n"" 326 193 269 48 335\n"" 327 106 195 43 202\n"" 328 176 357 275 363\n"" 329 77 251 170 271\n"" 330 44 267 220 272\n"" 331 75 189 187 270\n"" 332 65 194 126 200\n"" 333 68 267 182 374\n"" 334 125 195 66 198\n"" 335 17 204 50 205\n"" 336 250 325 322 384\n"" 337 66 195 126 198\n"" 338 79 185 80 189\n"" 339 159 298 67 357\n"" 340 218 302 88 303\n"" 341 78 80 79 269\n"" 342 77 221 170 327\n"" 343 90 147 13 148\n"" 344 319 373 230 375\n"" 345 126 200 194 201\n"" 346 143 161 41 296\n"" 347 297 357 345 390\n"" 348 126 195 106 202\n"" 349 64 196 124 199\n"" 350 209 333 211 4\n"" 351 44 202 107 273\n"" 352 195 196 125 335\n"" 353 284 353 84 399\n"" 354 125 196 195 198\n"" 355 64 126 103 201\n"" 356 63 200 168 201\n"" 357 278 279 207 284\n"" 358 175 209 34 261\n"" 359 224 294 91 361\n"" 360 274 298 225 390\n"" 361 258 329 172 381\n"" 362 293 316 153 371\n"" 363 37 139 134 287\n"" 364 200 219 126 272\n"" 365 110 277 257 332\n"" 366 158 225 42 245\n"" 367 191 271 190 340\n"" 368 6 86 136 217\n"" 369 96 163 43 202\n"" 370 41 246 154 296\n"" 371 2 127 50 206\n"" 372 120 240 188 323\n"" 373 171 268 77 335\n"" 374 257 277 276 332\n"" 375 308 313 238 393\n"" 376 98 248 202 273\n"" 377 167 303 55 356\n"" 378 136 137 6 217\n"" 379 88 283 252 380\n"" 380 188 323 240 377\n"" 381 140 272 267 319\n"" 382 121 188 120 240\n"" 383 323 368 313 377\n"" 384 172 258 110 329\n"" 385 192 198 28 199\n"" 386 284 354 85 387\n"" 387 155 157 156 160\n"" 388 143 230 45 299\n"" 389 173 341 20 372\n"" 390 248 319 96 375\n"" 391 242 241 151 355\n"" 392 30 80 75 189\n"" 393 51 173 127 203\n"" 394 81 256 8 257\n"" 395 187 270 122 340\n"" 396 38 241 242 355\n"" 397 141 293 245 300\n"" 398 93 156 11 160\n"" 399 88 252 218 303\n"" 400 29 123 75 184\n"" 401 159 334 297 357\n"" 402 206 344 130 346\n"" 403 185 269 125 335\n"" 404 151 294 10 295\n"" 405 105 66 27 194\n"" 406 150 302 55 362\n"" 407 261 280 209 347\n"" 408 312 367 145 393\n"" 409 194 200 63 201\n"" 410 176 275 112 363\n"" 411 334 357 159 364\n"" 412 231 302 88 361\n"" 413 57 238 236 309\n"" 414 88 300 292 380\n"" 415 192 124 125 199\n"" 416 148 240 120 323\n"" 417 126 194 103 201\n"" 418 259 331 82 351\n"" 419 119 184 183 270\n"" 420 150 241 55 302\n"" 421 126 272 219 289\n"" 422 230 301 116 373\n"" 423 123 188 74 189\n"" 424 74 186 79 189\n"" 425 92 369 243 370\n"" 426 131 280 261 350\n"" 427 143 299 228 300\n"" 428 220 303 231 362\n"" 429 277 332 203 346\n"" 430 256 257 81 276\n"" 431 154 314 36 369\n"" 432 100 180 165 249\n"" 433 149 294 91 295\n"" 434 274 329 141 358\n"" 435 126 201 64 219\n"" 436 64 201 101 219\n"" 437 207 211 53 350\n"" 438 283 330 132 379\n"" 439 243 369 1 370\n"" 440 24 373 114 398\n"" 441 143 230 161 318\n"" 442 161 296 245 371\n"" 443 110 257 172 329\n"" 444 96 162 43 163\n"" 445 248 373 319 375\n"" 446 171 221 77 327\n"" 447 21 254 171 336\n"" 448 306 5 239 305\n"" 449 197 220 102 272\n"" 450 82 281 172 351\n"" 451 113 146 39 234\n"" 452 143 229 68 374\n"" 453 68 93 41 161\n"" 454 172 351 281 381\n"" 455 112 204 17 363\n"" 456 124 191 185 196\n"" 457 215 216 9 278\n"" 458 19 383 353 389\n"" 459 185 189 122 340\n"" 460 137 38 287 134\n"" 461 122 270 250 324\n"" 462 126 202 107 272\n"" 463 70 71 117 179\n"" 464 84 227 226 353\n"" 465 109 173 390 203\n"" 466 13 121 120 240\n"" 467 53 285 213 348\n"" 468 228 358 300 380\n"" 469 14 80 78 269\n"" 470 55 302 218 303\n"" 471 285 286 213 348\n"" 472 107 202 106 273\n"" 473 307 367 366 393\n"" 474 147 148 90 235\n"" 475 94 161 42 247\n"" 476 276 332 277 346\n"" 477 141 293 223 397\n"" 478 51 203 127 346\n"" 479 22 229 150 231\n"" 480 163 202 96 248\n"" 481 48 269 185 335\n"" 482 162 163 96 248\n"" 483 141 274 245 397\n"" 484 115 163 61 248\n"" 485 147 236 57 313\n"" 486 158 181 60 265\n"" 487 311 365 364 391\n"" 488 193 195 125 335\n"" 489 125 185 124 269\n"" 490 224 296 245 300\n"" 491 49 185 124 191\n"" 492 132 280 213 322\n"" 493 96 202 195 221\n"" 494 233 357 334 364\n"" 495 99 166 164 266\n"" 496 245 293 141 397\n"" 497 36 244 149 316\n"" 498 74 79 30 189\n"" 499 30 75 74 189\n"" 500 12 178 99 392\n"" 501 322 325 259 384\n"" 502 195 196 126 198\n"" 503 57 313 238 326\n"" 504 48 268 186 336\n"" 505 91 296 154 316\n"" 506 14 192 124 269\n"" 507 259 332 111 343\n"" 508 238 311 255 364\n"" 509 45 230 95 264\n"" 510 140 252 221 299\n"" 511 176 262 112 263\n"" 512 32 211 207 350\n"" 513 261 376 351 82\n"" 514 19 227 190 389\n"" 515 2 129 128 206\n"" 516 102 220 167 303\n"" 517 181 249 116 266\n"" 518 170 271 251 324\n"" 519 186 188 121 240\n"" 520 213 321 286 338\n"" 521 124 185 14 269\n"" 522 91 295 224 316\n"" 523 143 299 231 374\n"" 524 159 364 255 391\n"" 525 310 334 69 364\n"" 526 170 283 271 379\n"" 527 229 231 143 361\n"" 528 241 287 134 302\n"" 529 70 72 25 179\n"" 530 72 157 25 179\n"" 531 26 71 70 179\n"" 532 70 114 26 179\n"" 533 287 388 282 399\n"" 534 68 229 22 374\n"" 535 61 180 116 249\n"" 536 115 116 71 179\n"" 537 143 296 229 361\n"" 538 142 354 282 399\n"" 539 25 155 70 179\n"" 540 139 288 167 356\n"" 541 114 115 26 179\n"" 542 26 115 71 179\n"" 543 116 180 179 266\n"" 544 164 166 100 266\n"" 545 100 166 46 266\n"" 546 171 255 221 327\n"" 547 132 330 325 379\n"" 548 140 289 252 339\n"" 549 24 182 98 373\n"" 550 180 249 100 266\n"" 551 320 321 214 322\n"" 552 213 285 270 338\n"" 553 214 321 52 322\n"" 554 122 188 186 268\n"" 555 271 289 196 339\n"" 556 108 251 250 325\n"" 557 153 293 244 316\n"" 558 43 193 162 382\n"" 559 80 124 49 185\n"" 560 159 67 358 253\n"" 561 142 282 212 283\n"" 562 14 124 80 185\n"" 563 110 174 173 341\n"" 564 187 189 122 270\n"" 565 252 299 88 380\n"" 566 55 218 139 356\n"" 567 227 378 190 389\n"" 568 33 292 222 328\n"" 569 47 121 74 188\n"" 570 74 123 47 188\n"" 571 120 121 47 188\n"" 572 47 123 120 188\n"" 573 55 303 218 356\n"" 574 167 288 18 356\n"" 575 58 224 151 295\n"" 576 18 167 87 288\n"" 577 116 230 181 301\n"" 578 161 246 41 296\n"" 579 91 244 149 295\n"" 580 33 281 212 381\n"" 581 23 225 158 245\n"" 582 79 186 48 189\n"" 583 75 184 123 189\n"" 584 74 75 76 189\n"" 585 75 123 76 189\n"" 586 76 123 74 189\n"" 587 67 357 298 390\n"" 588 124 185 125 196\n"" 589 186 240 121 336\n"" 590 64 191 124 196\n"" 591 209 210 34 347\n"" 592 80 185 79 269\n"" 593 63 103 104 194\n"" 594 27 107 65 194\n"" 595 9 278 216 279\n"" 596 66 126 106 194\n"" 597 104 27 65 194\n"" 598 66 106 27 194\n"" 599 106 107 27 194\n"" 600 27 3 105 194\n"" 601 105 3 104 194\n"" 602 104 3 27 194\n"" 603 77 335 195 382\n"" 604 136 217 86 287\n"" 605 226 290 54 383\n"" 606 290 356 54 383\n"" 607 218 339 142 383\n"" 608 21 268 193 336\n"" 609 193 268 48 336\n"" 610 171 268 21 336\n"" 611 103 194 126 199\n"" 612 28 198 194 199\n"" 613 125 198 192 199\n"" 614 28 194 103 199\n"" 615 106 163 62 273\n"" 616 98 202 44 273\n"" 617 221 252 170 299\n"" 618 141 300 245 318\n"" 619 185 196 77 335\n"" 620 244 295 91 316\n"" 621 62 163 15 273\n"" 622 231 299 143 300\n"" 623 317 371 245 397\n"" 624 126 196 64 199\n"" 625 103 126 64 199\n"" 626 93 94 59 246\n"" 627 127 344 206 346\n"" 628 224 292 222 360\n"" 629 225 359 274 390\n"" 630 221 319 45 375\n"" 631 25 157 155 301\n"" 632 19 271 191 290\n"" 633 110 341 274 342\n"" 634 163 248 15 273\n"" 635 132 283 212 330\n"" 636 119 321 320 338\n"" 637 186 189 122 268\n"" 638 106 194 126 202\n"" 639 126 194 107 202\n"" 640 107 194 106 202\n"" 641 141 358 329 381\n"" 642 88 302 282 360\n"" 643 263 275 176 343\n"" 644 173 203 110 274\n"" 645 260 175 34 261\n"" 646 250 270 122 323\n"" 647 21 165 162 249\n"" 648 193 335 268 382\n"" 649 130 332 275 343\n"" 650 204 275 130 344\n"" 651 51 110 174 203\n"" 652 110 173 174 203\n"" 653 174 173 51 203\n"" 654 70 155 24 398\n"" 655 177 113 39 234\n"" 656 218 252 88 282\n"" 657 352 383 54 388\n"" 658 112 263 204 275\n"" 659 54 352 226 383\n"" 660 134 287 241 355\n"" 661 238 307 146 309\n"" 662 224 295 58 316\n"" 663 325 343 259 384\n"" 664 259 329 67 330\n"" 665 88 292 224 360\n"" 666 9 215 86 216\n"" 667 221 299 45 319\n"" 668 245 296 161 318\n"" 669 136 134 137 287\n"" 670 83 211 209 349\n"" 671 132 324 283 379\n"" 672 84 284 207 353\n"" 673 138 139 37 287\n"" 674 140 252 231 303\n"" 675 219 289 140 339\n"" 676 181 230 45 264\n"" 677 228 300 299 380\n"" 678 85 279 216 354\n"" 679 169 320 250 323\n"" 680 68 230 143 374\n"" 681 207 227 84 353\n"" 682 240 313 57 326\n"" 683 49 190 187 340\n"" 684 286 348 133 349\n"" 685 52 280 213 349\n"" 686 263 343 176 384\n"" 687 51 277 203 346\n"" 688 220 267 140 272\n"" 689 137 217 136 287\n"" 690 203 329 274 390\n"" 691 31 320 250 368\n"" 692 224 316 293 371\n"" 693 231 252 88 303\n"" 694 252 271 170 283\n"" 695 253 358 228 380\n"" 696 256 276 130 332\n"" 697 19 353 227 389\n"" 698 219 339 303 356\n"" 699 170 252 221 289\n"" 700 142 271 252 283\n"" 701 209 347 280 350\n"" 702 142 252 88 283\n"" 703 251 324 271 340\n"" 704 95 264 181 391\n"" 705 171 251 77 268\n"" 706 98 319 248 373\n"" 707 331 351 259 376\n"" 708 41 154 91 296\n"" 709 10 241 151 242\n"" 710 330 380 292 381\n"" 711 132 284 283 353\n"" 712 140 272 221 289\n"" 713 126 196 77 289\n"" 714 152 371 317 395\n"" 715 36 149 91 316\n"" 716 108 253 176 308\n"" 717 255 365 264 391\n"" 718 202 248 163 273\n"" 719 224 300 88 361\n"" 720 65 126 107 272\n"" 721 67 159 358 298\n"" 722 88 300 231 361\n"" 723 153 223 58 293\n"" 724 146 238 236 307\n"" 725 202 248 98 319\n"" 726 141 328 292 381\n"" 727 42 161 95 245\n"" 728 176 253 108 325\n"" 729 10 294 149 295\n"" 730 155 179 25 301\n"" 731 68 161 143 230\n"" 732 264 365 181 391\n"" 733 225 274 245 298\n"" 734 225 245 23 298\n"" 735 41 161 93 246\n"" 736 97 163 115 248\n"" 737 93 161 94 246\n"" 738 45 255 96 375\n"" 739 212 291 282 354\n"" 740 148 313 323 169\n"" 741 224 292 88 300\n"" 742 142 283 212 354\n"" 743 61 162 96 248\n"" 744 97 114 98 248\n"" 745 185 189 48 268\n"" 746 205 345 275 385\n"" 747 48 268 193 335\n"" 748 24 155 68 301\n"" 749 60 160 157 301\n"" 750 159 357 308 364\n"" 751 297 345 109 390\n"" 752 61 163 162 248\n"" 753 61 116 115 248\n"" 754 230 299 143 374\n"" 755 140 267 22 374\n"" 756 102 303 167 356\n"" 757 134 287 218 302\n"" 758 218 282 88 302\n"" 759 93 161 68 230\n"" 760 357 363 308 364\n"" 761 224 295 294 361\n"" 762 153 244 36 316\n"" 763 303 339 218 356\n"" 764 294 302 150 361\n"" 765 153 371 152 395\n"" 766 57 326 254 336\n"" 767 48 189 186 268\n"" 768 238 308 255 326\n"" 769 214 322 52 376\n"" 770 132 322 259 376\n"" 771 111 331 259 376\n"" 772 121 240 147 336\n"" 773 253 379 330 380\n"" 774 223 274 141 397\n"" 775 176 308 262 313\n"" 776 31 262 176 263\n"" 777 334 364 159 391\n"" 778 255 311 238 326\n"" 779 110 274 203 329\n"" 780 315 369 154 370\n"" 781 146 234 113 311\n"" 782 363 366 232 367\n"" 783 159 298 228 358\n"" 784 292 328 33 381\n"" 785 68 301 230 373\n"" 786 271 340 324 389\n"" 787 176 263 112 275\n"" 788 1 369 315 370\n"" 789 159 308 255 364\n"" 790 253 255 159 308\n"" 791 262 312 56 313\n"" 792 19 290 226 383\n"" 793 84 352 215 399\n"" 794 23 158 95 245\n"" 795 145 235 56 238\n"" 796 132 322 213 324\n"" 797 77 268 185 335\n"" 798 175 214 52 376\n"" 799 108 255 253 308\n"" 800 56 238 235 313\n"" 801 111 175 8 331\n"" 802 52 286 213 321\n"" 803 149 244 91 316\n"" 804 237 5 306 305\n"" 805 165 326 113 365\n"" 806 58 293 224 316\n"" 807 204 263 130 275\n"" 808 222 292 58 328\n"" 809 175 261 260 331\n"" 810 45 253 228 299\n"" 811 250 321 320 322\n"" 812 102 272 220 303\n"" 813 182 267 98 319\n"" 814 170 379 253 380\n"" 815 151 241 10 294\n"" 816 52 321 213 322\n"" 817 215 278 84 399\n"" 818 282 354 216 399\n"" 819 22 267 68 374\n"" 820 230 373 319 374\n"" 821 97 98 15 248\n"" 822 274 341 223 342\n"" 823 15 163 97 248\n"" 824 153 316 36 369\n"" 825 132 351 212 387\n"" 826 185 251 122 268\n"" 827 122 189 185 268\n"" 828 250 324 270 338\n"" 829 233 345 297 357\n"" 830 129 277 128 346\n"" 831 165 249 171 326\n"" 832 122 268 251 377\n"" 833 259 329 172 332\n"" 834 255 364 311 365\n"" 835 140 220 22 267\n"" 836 142 282 218 388\n"" 837 108 326 313 377\n"" 838 221 252 140 289\n"" 839 77 196 195 335\n"" 840 251 271 77 340\n"" 841 250 251 122 324\n"" 842 238 309 57 326\n"" 843 227 386 378 389\n"" 844 171 255 108 326\n"" 845 256 259 111 331\n"" 846 178 365 266 392\n"" 847 178 311 69 391\n"" 848 102 219 197 272\n"" 849 172 259 257 331\n"" 850 258 342 329 381\n"" 851 143 296 224 300\n"" 852 88 299 231 300\n"" 853 182 319 98 373\n"" 854 44 220 197 272\n"" 855 107 202 44 272\n"" 856 333 210 209 347\n"" 857 299 300 88 380\n"" 858 67 253 176 325\n"" 859 212 354 284 387\n"" 860 203 110 332 277\n"" 861 171 251 108 327\n"" 862 96 221 171 255\n"" 863 45 221 96 255\n"" 864 58 293 223 328\n"" 865 148 235 147 313\n"" 866 36 316 154 369\n"" 867 92 395 394 396\n"" 868 132 351 280 376\n"" 869 253 299 45 327\n"" 870 233 334 310 364\n"" 871 195 335 193 382\n"" 872 193 268 21 382\n"" 873 223 293 141 328\n"" 874 292 293 58 328\n"" 875 38 137 287 217\n"" 876 315 1 314 369\n"" 877 141 274 223 342\n"" 878 188 268 122 377\n"" 879 141 293 292 328\n"" 880 235 236 147 313\n"" 881 235 238 236 313\n"" 882 57 240 147 313\n"" 883 88 282 212 292\n"" 884 23 297 159 334\n"" 885 259 325 132 330\n"" 886 23 334 159 391\n"" 887 283 324 132 389\n"" 888 205 345 304 363\n"" 889 253 325 67 330\n"" 890 43 162 96 382\n"" 891 257 331 259 332\n"" 892 256 331 257 332\n"" 893 172 329 257 332\n"" 894 54 356 218 383\n"" 895 259 331 256 332\n"" 896 208 131 32 350\n"" 897 280 348 213 349\n"" 898 118 270 213 285\n"" 899 16 270 118 285\n"" 900 253 308 159 357\n"" 901 81 276 257 277\n"" 902 228 253 45 264\n"" 903 31 262 169 368\n"" 904 262 313 169 368\n"" 905 108 313 308 368\n"" 906 159 255 253 264\n"" 907 253 255 45 264\n"" 908 95 181 158 265\n"" 909 45 264 255 365\n"" 910 113 311 178 392\n"" 911 177 178 12 392\n"" 912 100 365 165 392\n"" 913 369 370 92 395\n"" 914 72 179 166 266\n"" 915 150 294 241 302\n"" 916 134 218 55 302\n"" 917 166 179 71 266\n"" 918 179 180 71 266\n"" 919 46 166 71 266\n"" 920 71 180 46 266\n"" 921 308 364 363 393\n"" 922 238 313 312 393\n"" 923 238 364 308 393\n"" 924 366 367 363 393\n"" 925 218 287 282 302\n"" 926 72 166 60 266\n"" 927 166 181 60 266\n"" 928 116 373 301 398\n"" 929 225 372 317 397\n"" 930 226 388 352 399\n"" 931 145 238 56 312\n"" 932 176 325 108 368\n"" 933 152 35 154 370\n"" 934 108 327 251 379\n"" 935 135 291 216 354\n"" 936 283 324 271 379\n"" 937 213 324 322 338\n"" 938 284 351 132 387\n"" 939 321 322 250 338\n"" 940 73 323 270 337\n"" 941 270 323 250 337\n"" 942 286 321 119 338\n"" 943 250 323 320 337\n"" 944 320 323 73 337\n"" 945 213 322 321 338\n"" 946 122 189 188 270\n"" 947 183 184 29 270\n"" 948 29 187 183 270\n"" 949 16 183 118 270\n"" 950 119 183 16 270\n"" 951 252 271 142 339\n"" 952 196 289 219 339\n"" 953 69 311 310 364\n"" 954 185 191 49 340\n"" 955 29 184 75 270\n"" 956 75 187 29 270\n"" 957 184 188 123 270\n"" 958 188 189 123 270\n"" 959 123 189 184 270\n"" 960 255 308 108 326\n"" 961 108 308 238 326\n"" 962 245 298 274 358\n"" 963 111 332 256 343\n"" 964 53 227 207 386\n"" 965 58 244 153 293\n"" 966 91 296 224 361\n"" 967 268 336 171 377\n"" 968 162 249 96 382\n"" 969 141 329 274 342\n"" 970 259 322 132 325\n"" 971 213 348 280 386\n"" 972 130 275 263 343\n"" 973 161 230 95 318\n"" 974 95 230 45 318\n"" 975 228 298 95 318\n"" 976 302 303 55 362\n"" 977 45 230 143 318\n"" 978 95 245 161 318\n"" 979 77 251 171 327\n"" 980 233 363 357 364\n"" 981 213 280 132 386\n"" 982 173 109 390 359\n"" 983 159 297 23 298\n"" 984 213 286 52 349\n"" 985 108 251 171 377\n"" 986 209 280 52 349\n"" 987 252 289 271 339\n"" 988 84 278 207 284\n"" 989 142 252 218 282\n"" 990 88 252 142 282\n"" 991 190 271 19 389\n"" 992 257 276 256 332\n"" 993 251 268 171 377\n"" 994 122 270 188 323\n"" 995 138 218 139 287\n"" 996 226 383 352 388\n"" 997 73 169 120 323\n"" 998 73 320 169 323\n"" 999 324 325 251 379\n"" 1000 364 365 255 391\n"" 1001 228 300 141 318\n"" 1002 224 296 143 361\n"" 1003 87 167 139 288\n"" 1004 297 334 233 357\n"" 1005 85 284 279 354\n"" 1006 122 324 251 340\n"" 1007 170 221 77 289\n"" 1008 170 271 252 289\n"" 1009 77 195 126 289\n"" 1010 167 220 55 303\n"" 1011 139 218 134 287\n"" 1012 216 217 135 287\n"" 1013 135 282 216 287\n"" 1014 245 300 296 318\n"" 1015 58 292 224 293\n"" 1016 171 249 21 382\n"" 1017 172 259 82 351\n"" 1018 131 284 279 387\n"" 1019 134 241 38 355\n"" 1020 18 288 101 356\n"" 1021 38 287 134 355\n"" 1022 139 167 55 356\n"" 1023 139 218 138 356\n"" 1024 142 383 271 389\n"" 1025 216 282 135 354\n"" 1026 353 383 142 389\n"" 1027 271 283 142 389\n"" 1028 131 350 284 387\n"" 1029 274 358 298 390\n"" 1030 86 216 215 287\n"" 1031 86 217 216 287\n"" 1032 195 202 126 289\n"" 1033 195 221 202 289\n"" 1034 77 221 195 289\n"" 1035 140 272 219 303\n"" 1036 33 291 222 292\n"" 1037 212 291 33 292\n"" 1038 229 296 91 361\n"" 1039 140 231 220 303\n"" 1040 145 307 238 393\n"" 1041 222 224 58 292\n"" 1042 270 324 122 340\n"" 1043 96 319 221 375\n"" 1044 216 278 215 399\n"" 1045 274 341 173 372\n"" 1046 88 252 231 299\n"" 1047 216 279 278 399\n"" 1048 115 248 116 398\n"" 1049 274 359 225 372\n"" 1050 153 395 92 396\n"" 1051 245 298 228 318\n"" 1052 95 298 245 318\n"" 1053 143 300 228 318\n"" 1054 231 303 302 362\n"" 1055 91 229 41 296\n"" 1056 293 396 223 397\n"" 1057 249 255 45 375\n"" 1058 42 245 225 317\n"" 1059 304 345 233 363\n"" 1060 55 303 220 362\n"" 1061 231 302 150 362\n"" 1062 216 354 279 399\n"" 1063 361 224 151 360\n"" 1064 282 388 142 399\n"" 1065 96 255 249 375\n"" 1066 151 222 135 360\n"" 1067 222 292 291 360\n"" 1068 159 264 23 391\n"" 1069 127 206 128 346\n"" 1070 95 265 23 391\n"" 1071 69 334 265 391\n"" 1072 159 264 228 298\n"" 1073 228 264 95 298\n"" 1074 23 245 95 298\n"" 1075 282 292 88 360\n"" 1076 67 330 329 358\n"" 1077 23 264 159 298\n"" 1078 95 264 23 298\n"" 1079 229 231 22 374\n"" 1080 60 157 72 301\n"" 1081 157 179 72 301\n"" 1082 116 266 179 301\n"" 1083 95 160 60 301\n"" 1084 60 266 181 301\n"" 1085 181 266 116 301\n"" 1086 60 181 95 301\n"" 1087 181 230 95 301\n"" 1088 160 161 93 301\n"" 1089 161 230 93 301\n"" 1090 68 155 93 301\n"" 1091 93 230 68 301\n"" 1092 179 266 72 301\n"" 1093 72 266 60 301\n"" 1094 95 161 160 301\n"" 1095 95 230 161 301\n"" 1096 308 357 176 363\n"" 1097 255 326 171 365\n"" 1098 91 294 150 361\n"" 1099 294 360 302 361\n"" 1100 231 300 143 361\n"" 1101 88 302 231 303\n"" 1102 245 371 293 397\n"" 1103 146 236 40 307\n"" 1104 236 238 235 307\n"" 1105 235 238 145 307\n"" 1106 110 203 332 329\n"" 1107 177 234 178 311\n"" 1108 113 234 177 311\n"" 1109 169 262 56 313\n"" 1110 148 169 56 313\n"" 1111 89 237 145 307\n"" 1112 89 305 237 307\n"" 1113 306 40 145 307\n"" 1114 146 40 306 307\n"" 1115 237 306 145 307\n"" 1116 237 305 306 307\n"" 1117 306 239 146 307\n"" 1118 305 239 306 307\n"" 1119 146 239 39 307\n"" 1120 239 305 39 307\n"" 1121 40 235 145 307\n"" 1122 40 236 235 307\n"" 1123 177 178 113 311\n"" 1124 253 255 108 327\n"" 1125 307 309 238 311\n"" 1126 178 234 69 311\n"" 1127 170 251 77 327\n"" 1128 271 324 170 379\n"" 1129 146 307 234 311\n"" 1130 181 266 99 365\n"" 1131 69 234 144 311\n"" 1132 234 307 144 311\n"" 1133 228 299 253 380\n"" 1134 100 266 249 365\n"" 1135 178 266 99 392\n"" 1136 99 266 178 365\n"" 1137 113 365 311 392\n"" 1138 99 266 164 392\n"" 1139 108 308 176 368\n"" 1140 313 323 169 368\n"" 1141 45 255 249 365\n"" 1142 232 363 304 366\n"" 1143 308 313 176 368\n"" 1144 146 309 307 311\n"" 1145 113 309 146 311\n"" 1146 52 280 175 376\n"" 1147 144 310 69 311\n"" 1148 115 179 114 398\n"" 1149 114 248 115 398\n"" 1150 176 262 31 368\n"" 1151 212 284 132 387\n"" 1152 89 366 144 367\n"" 1153 153 370 369 395\n"" 1154 153 369 92 395\n"" 1155 301 373 24 398\n"" 1156 53 350 348 386\n"" 1157 108 325 250 368\n"" 1158 371 395 153 396\n"" 1159 24 301 68 373\n"" 1160 70 179 155 398\n"" 1161 161 296 143 318\n"" 1162 95 264 228 318\n"" 1163 228 264 45 318\n"" 1164 45 264 95 318\n"" 1165 45 299 228 318\n"" 1166 228 299 143 318\n"" 1167 143 299 45 318\n"" 1168 68 373 230 374\n"" 1169 267 319 182 374\n"" 1170 259 351 132 376\n"" 1171 202 272 221 319\n"" 1172 221 272 140 319\n"" 1173 202 221 96 319\n"" 1174 96 248 202 319\n"" 1175 116 373 248 375\n"" 1176 44 202 98 319\n"" 1177 98 267 44 319\n"" 1178 267 272 44 319\n"" 1179 44 272 202 319\n"" 1180 230 373 116 375\n"" 1181 143 231 229 374\n"" 1182 116 249 181 375\n"" 1183 45 319 230 375\n"" 1184 116 181 45 375\n"" 1185 175 331 111 376\n"" 1186 280 322 132 376\n"" 1187 171 336 326 377\n"" 1188 261 347 131 350\n"" 1189 131 347 32 350\n"" 1190 128 206 129 346\n"" 1191 238 313 108 326\n"" 1192 171 254 21 326\n"" 1193 329 358 330 381\n"" 1194 251 327 170 379\n"" 1195 325 330 253 379\n"" 1196 172 281 33 381\n"" 1197 212 282 142 354\n"" 1198 110 329 258 342\n"" 1199 205 344 50 385\n"" 1200 376 261 351 280\n"" 1201 173 174 20 341\n"" 1202 322 324 132 379\n"" 1203 322 325 324 379\n"" 1204 298 358 67 390\n"" 1205 67 329 203 390\n"" 1206 21 254 165 326\n"" 1207 184 270 119 337\n"" 1208 142 284 283 354\n"" 1209 73 270 184 337\n"" 1210 218 303 252 339\n"" 1211 250 323 108 368\n"" 1212 245 274 225 397\n"" 1213 165 254 113 326\n"" 1214 275 344 205 385\n"" 1215 254 309 113 326\n"" 1216 309 311 113 326\n"" 1217 96 221 77 382\n"" 1218 249 326 165 365\n"" 1219 125 196 185 335\n"" 1220 224 245 371 293\n"" 1221 203 329 67 332\n"" 1222 50 206 127 344\n"" 1223 162 193 21 382\n"" 1224 8 256 111 331\n"" 1225 82 259 172 331\n"" 1226 245 224 371 296\n"" 1227 260 8 175 331\n"" 1228 250 368 325 384\n"" 1229 219 356 290 383\n"" 1230 96 195 43 382\n"" 1231 271 339 290 383\n"" 1232 212 330 292 381\n"" 1233 265 334 23 391\n"" 1234 329 330 259 381\n"" 1235 329 342 141 381\n"" 1236 77 221 171 382\n"" 1237 43 195 193 382\n"" 1238 292 380 141 381\n"" 1239 141 380 358 381\n"" 1240 111 259 256 332\n"" 1241 135 355 151 360\n"" 1242 130 344 275 346\n"" 1243 206 276 129 346\n"" 1244 207 350 53 386\n"" 1245 128 277 51 346\n"" 1246 51 127 128 346\n"" 1247 353 386 227 389\n"" 1248 271 290 19 383\n"" 1249 339 356 219 383\n"" 1250 322 324 250 338\n"" 1251 250 337 320 338\n"" 1252 320 337 119 338\n"" 1253 119 270 16 338\n"" 1254 270 285 16 338\n"" 1255 213 286 285 338\n"" 1256 285 286 16 338\n"" 1257 16 286 119 338\n"" 1258 343 376 259 384\n"" 1259 250 320 31 384\n"" 1260 252 303 140 339\n"" 1261 140 303 219 339\n"" 1262 191 271 196 339\n"" 1263 191 290 271 339\n"" 1264 196 290 191 339\n"" 1265 196 219 64 339\n"" 1266 219 290 64 339\n"" 1267 64 290 196 339\n"" 1268 31 368 250 384\n"" 1269 31 263 176 384\n"" 1270 322 376 214 384\n"" 1271 185 196 191 340\n"" 1272 196 271 191 340\n"" 1273 203 275 67 390\n"" 1274 345 357 275 390\n"" 1275 77 196 185 340\n"" 1276 77 271 196 340\n"" 1277 187 190 118 340\n"" 1278 118 270 187 340\n"" 1279 256 332 130 343\n"" 1280 67 325 176 343\n"" 1281 67 329 259 343\n"" 1282 67 332 329 343\n"" 1283 329 332 259 343\n"" 1284 298 357 297 390\n"" 1285 227 353 207 386\n"" 1286 344 346 127 385\n"" 1287 203 346 275 385\n"" 1288 348 350 280 386\n"" 1289 67 330 325 343\n"" 1290 325 330 259 343\n"" 1291 259 330 67 343\n"" 1292 284 350 207 386\n"" 1293 280 350 284 386\n"" 1294 207 353 284 386\n"" 1295 130 276 206 346\n"" 1296 130 332 276 346\n"" 1297 129 276 81 346\n"" 1298 276 277 81 346\n"" 1299 81 277 129 346\n"" 1300 203 332 275 346\n"" 1301 275 332 130 346\n"" 1302 53 348 213 386\n"" 1303 284 353 132 386\n"" 1304 280 348 211 350\n"" 1305 211 348 53 350\n"" 1306 85 281 131 387\n"" 1307 207 284 279 350\n"" 1308 279 284 131 350\n"" 1309 207 279 208 350\n"" 1310 208 279 131 350\n"" 1311 333 211 32 350\n"" 1312 333 347 211 350\n"" 1313 32 347 333 350\n"" 1314 350 351 284 387\n"" 1315 85 291 281 387\n"" 1316 281 381 351 387\n"" 1317 240 336 186 377\n"" 1318 313 368 108 377\n"" 1319 21 268 171 382\n"" 1320 171 221 96 382\n"" 1321 268 335 171 382\n"" 1322 218 287 136 388\n"" 1323 54 383 218 388\n"" 1324 218 383 142 388\n"" 1325 142 383 226 388\n"" 1326 82 261 131 351\n"" 1327 261 280 131 351\n"" 1328 284 350 280 351\n"" 1329 280 350 131 351\n"" 1330 226 227 19 353\n"" 1331 85 354 291 387\n"" 1332 131 351 350 387\n"" 1333 150 231 229 361\n"" 1334 88 360 224 361\n"" 1335 279 284 85 387\n"" 1336 281 291 212 387\n"" 1337 135 287 217 355\n"" 1338 150 302 231 361\n"" 1339 217 287 38 355\n"" 1340 283 284 212 354\n"" 1341 132 353 283 389\n"" 1342 118 340 190 389\n"" 1343 190 340 271 389\n"" 1344 271 383 19 389\n"" 1345 138 288 139 356\n"" 1346 176 368 31 384\n"" 1347 102 167 168 356\n"" 1348 101 219 200 356\n"" 1349 200 219 102 356\n"" 1350 167 18 168 356\n"" 1351 168 18 101 356\n"" 1352 101 290 219 356\n"" 1353 54 290 101 356\n"" 1354 138 218 54 356\n"" 1355 54 288 138 356\n"" 1356 259 376 322 384\n"" 1357 325 368 176 384\n"" 1358 168 200 102 356\n"" 1359 101 200 168 356\n"" 1360 176 253 67 357\n"" 1361 176 308 253 357\n"" 1362 307 310 144 364\n"" 1363 266 365 100 392\n"" 1364 135 291 282 360\n"" 1365 222 291 135 360\n"" 1366 282 291 212 360\n"" 1367 291 292 212 360\n"" 1368 212 292 282 360\n"" 1369 58 222 151 360\n"" 1370 58 224 222 360\n"" 1371 151 224 58 360\n"" 1372 22 231 150 362\n"" 1373 220 231 22 362\n"" 1374 241 294 151 360\n"" 1375 241 302 294 360\n"" 1376 282 302 287 360\n"" 1377 302 355 287 360\n"" 1378 282 287 135 360\n"" 1379 287 355 135 360\n"" 1380 241 355 302 360\n"" 1381 151 355 241 360\n"" 1382 294 295 151 361\n"" 1383 151 360 294 361\n"" 1384 204 205 17 363\n"" 1385 205 304 17 363\n"" 1386 132 324 213 386\n"" 1387 17 304 232 363\n"" 1388 250 320 169 368\n"" 1389 113 326 311 365\n"" 1390 274 372 225 397\n"" 1391 238 312 145 393\n"" 1392 372 395 317 397\n"" 1393 144 307 89 367\n"" 1394 89 307 145 367\n"" 1395 181 264 45 365\n"" 1396 249 266 181 365\n"" 1397 311 326 255 365\n"" 1398 310 311 144 364\n"" 1399 144 311 307 364\n"" 1400 176 313 262 368\n"" 1401 169 320 31 368\n"" 1402 144 366 307 367\n"" 1403 169 323 250 368\n"" 1404 232 366 89 367\n"" 1405 112 363 17 367\n"" 1406 275 346 344 385\n"" 1407 317 395 371 397\n"" 1408 145 367 307 393\n"" 1409 363 364 233 393\n"" 1410 363 367 112 393\n"" 1411 164 266 100 392\n"" 1412 307 364 238 393\n"" 1413 112 367 312 393\n"" 1414 165 365 113 392\n"" 1415 311 365 178 392\n"" 1416 12 99 164 392\n"" 1417 173 359 274 372\n"" 1418 248 373 116 398\n"" 1419 245 317 42 371\n"" 1420 42 317 152 371\n"" 1421 161 245 42 371\n"" 1422 42 247 161 371\n"" 1423 161 247 246 371\n"" 1424 246 296 161 371\n"" 1425 154 296 246 371\n"" 1426 154 316 296 371\n"" 1427 246 247 154 371\n"" 1428 152 154 35 371\n"" 1429 154 247 35 371\n"" 1430 35 247 152 371\n"" 1431 152 370 154 371\n"" 1432 114 373 248 398\n"" 1433 179 301 155 398\n"" 1434 114 179 70 398\n"" 1435 24 114 70 398\n"" 1436 153 370 152 371\n"" 1437 154 369 316 371\n"" 1438 154 370 369 371\n"" 1439 316 369 153 371\n"" 1440 369 370 153 371\n"" 1441 215 388 287 399\n"" 1442 278 284 84 399\n"" 1443 231 299 140 374\n"" 1444 299 319 140 374\n"" 1445 45 299 230 374\n"" 1446 45 319 299 374\n"" 1447 230 319 45 374\n"" 1448 45 365 249 375\n"" 1449 249 365 181 375\n"" 1450 181 365 45 375\n"" 1451 311 364 69 391\n"" 1452 259 343 111 376\n"" 1453 111 214 175 376\n"" 1454 175 280 261 376\n"" 1455 224 361 151 295\n"" 1456 82 351 331 376\n"" 1457 127 203 109 385\n"" 1458 50 344 127 385\n"" 1459 82 331 261 376\n"" 1460 261 331 175 376\n"" 1461 250 251 108 377\n"" 1462 108 323 250 377\n"" 1463 122 251 250 377\n"" 1464 250 323 122 377\n"" 1465 188 240 186 377\n"" 1466 186 268 188 377\n"" 1467 240 326 57 377\n"" 1468 326 336 57 377\n"" 1469 57 336 240 377\n"" 1470 108 325 253 379\n"" 1471 170 327 253 379\n"" 1472 253 327 108 379\n"" 1473 252 283 170 380\n"" 1474 212 283 88 380\n"" 1475 212 330 283 380\n"" 1476 330 379 283 380\n"" 1477 283 379 170 380\n"" 1478 253 330 67 380\n"" 1479 330 358 67 380\n"" 1480 67 358 253 380\n"" 1481 21 249 162 382\n"" 1482 300 358 141 380\n"" 1483 292 300 141 380\n"" 1484 77 195 96 382\n"" 1485 88 292 212 380\n"" 1486 292 330 212 380\n"" 1487 330 351 259 381\n"" 1488 172 329 259 381\n"" 1489 259 351 172 381\n"" 1490 212 351 330 381\n"" 1491 141 342 328 381\n"" 1492 328 342 258 381\n"" 1493 142 353 226 383\n"" 1494 226 353 19 383\n"" 1495 142 339 271 383\n"" 1496 274 359 173 390\n"" 1497 225 298 297 390\n"" 1498 31 320 214 384\n"" 1499 250 322 320 384\n"" 1500 320 322 214 384\n"" 1501 111 376 343 384\n"" 1502 214 376 111 384\n"" 1503 111 263 214 384\n"" 1504 111 343 263 384\n"" 1505 53 378 227 386\n"" 1506 213 378 53 386\n"" 1507 203 385 275 390\n"" 1508 132 351 284 386\n"" 1509 284 351 280 386\n"" 1510 280 351 132 386\n"" 1511 109 385 203 390\n"" 1512 109 359 297 390\n"" 1513 351 381 212 387\n"" 1514 212 381 281 387\n"" 1515 131 281 82 387\n"" 1516 281 351 82 387\n"" 1517 82 351 131 387\n"" 1518 313 148 323 240\n"" 1519 136 287 215 388\n"" 1520 215 352 136 388\n"" 1521 136 352 54 388\n"" 1522 54 138 136 388\n"" 1523 54 218 138 388\n"" 1524 138 218 136 388\n"" 1525 283 353 142 389\n"" 1526 190 378 118 389\n"" 1527 324 340 270 389\n"" 1528 270 340 118 389\n"" 1529 378 386 213 389\n"" 1530 213 386 324 389\n"" 1531 132 386 353 389\n"" 1532 324 386 132 389\n"" 1533 118 378 213 389\n"" 1534 213 270 118 389\n"" 1535 213 324 270 389\n"" 1536 275 385 345 390\n"" 1537 345 385 109 390\n"" 1538 67 358 329 390\n"" 1539 329 358 274 390\n"" 1540 181 265 95 391\n"" 1541 99 265 181 391\n"" 1542 181 365 99 391\n"" 1543 178 265 99 391\n"" 1544 99 365 178 391\n"" 1545 233 364 310 393\n"" 1546 310 366 233 393\n"" 1547 304 363 233 393\n"" 1548 304 366 363 393\n"" 1549 233 366 304 393\n"" 1550 310 364 307 393\n"" 1551 308 363 176 393\n"" 1552 176 363 112 393\n"" 1553 312 313 262 393\n"" 1554 262 313 308 393\n"" 1555 144 310 307 393\n"" 1556 144 366 310 393\n"" 1557 307 366 144 393\n"" 1558 262 308 176 393\n"" 1559 112 262 176 393\n"" 1560 112 312 262 393\n"" 1561 223 341 274 397\n"" 1562 341 372 274 397\n"" 1563 223 396 341 397\n"" 1564 394 395 372 397\n"" 1565 394 396 395 397\n"" 1566 395 396 371 397\n"" 1567 371 396 293 397\n"" 1568 341 396 394 397\n"" 1569 341 394 20 397\n"" 1570 394 372 20 397\n"" 1571 20 372 341 397\n"" 1572 279 284 278 399\n"" 1573 279 354 284 399\n"" 1574 216 287 282 399\n"" 1575 215 287 216 399\n"" 1576 142 353 284 399\n"" 1577 284 354 142 399\n"" 1578 226 353 142 399\n"" 1579 142 388 226 399\n""# Generated by tetgen -a0.01 cube.smesh \n"); } diff --git a/Demos/SoftDemo/main.cpp b/Demos/SoftDemo/main.cpp new file mode 100644 index 0000000..3408ae3 --- /dev/null +++ b/Demos/SoftDemo/main.cpp @@ -0,0 +1,37 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SoftDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + SoftDemo* softDemo = new SoftDemo(); + + softDemo->initPhysics(); + softDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + + glutmain(argc, argv,1024,768,"Bullet Physics Demo. http://bulletphysics.com",softDemo); + + delete softDemo; + return 0; + +} diff --git a/Demos/TerrainDemo/Makefile.am b/Demos/TerrainDemo/Makefile.am new file mode 100644 index 0000000..3dbfb10 --- /dev/null +++ b/Demos/TerrainDemo/Makefile.am @@ -0,0 +1,6 @@ + +noinst_PROGRAMS=TerrainDemo + +TerrainDemo_SOURCES=TerrainDemo.cpp TerrainDemo.h main.cpp +TerrainDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +TerrainDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/TerrainDemo/Makefile.in b/Demos/TerrainDemo/Makefile.in new file mode 100644 index 0000000..5ede237 --- /dev/null +++ b/Demos/TerrainDemo/Makefile.in @@ -0,0 +1,518 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = TerrainDemo$(EXEEXT) +subdir = Demos/TerrainDemo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_TerrainDemo_OBJECTS = TerrainDemo-TerrainDemo.$(OBJEXT) \ + TerrainDemo-main.$(OBJEXT) +TerrainDemo_OBJECTS = $(am_TerrainDemo_OBJECTS) +TerrainDemo_DEPENDENCIES = +TerrainDemo_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(TerrainDemo_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(TerrainDemo_SOURCES) +DIST_SOURCES = $(TerrainDemo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TerrainDemo_SOURCES = TerrainDemo.cpp TerrainDemo.h main.cpp +TerrainDemo_CXXFLAGS = -I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +TerrainDemo_LDADD = -L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/TerrainDemo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/TerrainDemo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +TerrainDemo$(EXEEXT): $(TerrainDemo_OBJECTS) $(TerrainDemo_DEPENDENCIES) + @rm -f TerrainDemo$(EXEEXT) + $(TerrainDemo_LINK) $(TerrainDemo_OBJECTS) $(TerrainDemo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TerrainDemo-TerrainDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TerrainDemo-main.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +TerrainDemo-TerrainDemo.o: TerrainDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -MT TerrainDemo-TerrainDemo.o -MD -MP -MF $(DEPDIR)/TerrainDemo-TerrainDemo.Tpo -c -o TerrainDemo-TerrainDemo.o `test -f 'TerrainDemo.cpp' || echo '$(srcdir)/'`TerrainDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/TerrainDemo-TerrainDemo.Tpo $(DEPDIR)/TerrainDemo-TerrainDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TerrainDemo.cpp' object='TerrainDemo-TerrainDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -c -o TerrainDemo-TerrainDemo.o `test -f 'TerrainDemo.cpp' || echo '$(srcdir)/'`TerrainDemo.cpp + +TerrainDemo-TerrainDemo.obj: TerrainDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -MT TerrainDemo-TerrainDemo.obj -MD -MP -MF $(DEPDIR)/TerrainDemo-TerrainDemo.Tpo -c -o TerrainDemo-TerrainDemo.obj `if test -f 'TerrainDemo.cpp'; then $(CYGPATH_W) 'TerrainDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/TerrainDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/TerrainDemo-TerrainDemo.Tpo $(DEPDIR)/TerrainDemo-TerrainDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TerrainDemo.cpp' object='TerrainDemo-TerrainDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -c -o TerrainDemo-TerrainDemo.obj `if test -f 'TerrainDemo.cpp'; then $(CYGPATH_W) 'TerrainDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/TerrainDemo.cpp'; fi` + +TerrainDemo-main.o: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -MT TerrainDemo-main.o -MD -MP -MF $(DEPDIR)/TerrainDemo-main.Tpo -c -o TerrainDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/TerrainDemo-main.Tpo $(DEPDIR)/TerrainDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='TerrainDemo-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -c -o TerrainDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp + +TerrainDemo-main.obj: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -MT TerrainDemo-main.obj -MD -MP -MF $(DEPDIR)/TerrainDemo-main.Tpo -c -o TerrainDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/TerrainDemo-main.Tpo $(DEPDIR)/TerrainDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='TerrainDemo-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(TerrainDemo_CXXFLAGS) $(CXXFLAGS) -c -o TerrainDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/TerrainDemo/TerrainDemo.cpp b/Demos/TerrainDemo/TerrainDemo.cpp new file mode 100644 index 0000000..cc32b68 --- /dev/null +++ b/Demos/TerrainDemo/TerrainDemo.cpp @@ -0,0 +1,921 @@ + +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006,2008 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "TerrainDemo.h" // always include our own header first! + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" + +#include "GLDebugDrawer.h" + +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" +#include "GLDebugFont.h" + + + +// constants ------------------------------------------------------------------- +static const float s_gravity = 9.8; // 9.8 m/s^2 + +static const int s_gridSize = 64 + 1; // must be (2^N) + 1 +static const float s_gridSpacing = 5.0; + +static const float s_gridHeightScale = 0.2; + +// the singularity at the center of the radial model means we need a lot of +// finely-spaced time steps to get the physics right. +// These numbers are probably too aggressive for a real game! +static const int s_requestedHz = 180; +static const float s_engineTimeStep = 1.0 / s_requestedHz; + +// delta phase: radians per second +static const float s_deltaPhase = 0.25 * 2.0 * SIMD_PI; + +// what type of terrain is generated? +enum eTerrainModel { + eRadial = 1, // deterministic + eFractal = 2 // random +}; + + +typedef unsigned char byte_t; + + + +//////////////////////////////////////////////////////////////////////////////// +// +// static helper methods +// +// Only used within this file (helpers and terrain generation, etc) +// +//////////////////////////////////////////////////////////////////////////////// + +static const char * +getTerrainTypeName +( +eTerrainModel model +) +{ + switch (model) { + case eRadial: + return "Radial"; + + case eFractal: + return "Fractal"; + + default: + btAssert(!"bad terrain model type"); + } + + return NULL; +} + + + +static const char * +getDataTypeName +( +PHY_ScalarType type +) +{ + switch (type) { + case PHY_UCHAR: + return "UnsignedChar"; + + case PHY_SHORT: + return "Short"; + + case PHY_FLOAT: + return "Float"; + + default: + btAssert(!"bad heightfield data type"); + } + + return NULL; +} + + + +static const char * +getUpAxisName +( +int axis +) +{ + switch (axis) { + case 0: + return "X"; + + case 1: + return "Y"; + + case 2: + return "Z"; + + default: + btAssert(!"bad up axis"); + } + + return NULL; +} + + + +static btVector3 +getUpVector +( +int upAxis, +btScalar regularValue, +btScalar upValue +) +{ + btAssert(upAxis >= 0 && upAxis <= 2 && "bad up axis"); + + btVector3 v(regularValue, regularValue, regularValue); + v[upAxis] = upValue; + + return v; +} + + + +// TODO: it would probably cleaner to have a struct per data type, so +// you could lookup byte sizes, conversion functions, etc. +static int getByteSize +( +PHY_ScalarType type +) +{ + int size = 0; + + switch (type) { + case PHY_FLOAT: + size = sizeof(float); + break; + + case PHY_UCHAR: + size = sizeof(unsigned char); + break; + + case PHY_SHORT: + size = sizeof(short); + break; + + default: + btAssert(!"Bad heightfield data type"); + } + + return size; +} + + + +static float +convertToFloat +( +const byte_t * p, +PHY_ScalarType type +) +{ + btAssert(p); + + switch (type) { + case PHY_FLOAT: + { + float * pf = (float *) p; + return *pf; + } + + case PHY_UCHAR: + { + unsigned char * pu = (unsigned char *) p; + return ((*pu) * s_gridHeightScale); + } + + case PHY_SHORT: + { + short * ps = (short *) p; + return ((*ps) * s_gridHeightScale); + } + + default: + btAssert(!"bad type"); + } + + return 0; +} + + + +static float +getGridHeight +( +byte_t * grid, +int i, +int j, +PHY_ScalarType type +) +{ + btAssert(grid); + btAssert(i >= 0 && i < s_gridSize); + btAssert(j >= 0 && j < s_gridSize); + + int bpe = getByteSize(type); + btAssert(bpe > 0 && "bad bytes per element"); + + int idx = (j * s_gridSize) + i; + long offset = ((long) bpe) * idx; + + byte_t * p = grid + offset; + + return convertToFloat(p, type); +} + + + +static void +convertFromFloat +( +byte_t * p, +float value, +PHY_ScalarType type +) +{ + btAssert(p && "null"); + + switch (type) { + case PHY_FLOAT: + { + float * pf = (float *) p; + *pf = value; + } + break; + + case PHY_UCHAR: + { + unsigned char * pu = (unsigned char *) p; + *pu = (unsigned char) (value / s_gridHeightScale); + } + break; + + case PHY_SHORT: + { + short * ps = (short *) p; + *ps = (short) (value / s_gridHeightScale); + } + break; + + default: + btAssert(!"bad type"); + } +} + + + +// creates a radially-varying heightfield +static void +setRadial +( +byte_t * grid, +int bytesPerElement, +PHY_ScalarType type, +float phase = 0.0 +) +{ + btAssert(grid); + btAssert(bytesPerElement > 0); + + // min/max + float period = 0.5 / s_gridSpacing; + float floor = 0.0; + float min_r = 3.0 * sqrt(s_gridSpacing); + float magnitude = 50.0 * sqrt(s_gridSpacing); + + // pick a base_phase such that phase = 0 results in max height + // (this way, if you create a heightfield with phase = 0, + // you can rely on the min/max heights that result) + float base_phase = (0.5 * SIMD_PI) - (period * min_r); + phase += base_phase; + + // center of grid + float cx = 0.5 * s_gridSize * s_gridSpacing; + float cy = cx; // assume square grid + byte_t * p = grid; + for (int i = 0; i < s_gridSize; ++i) { + float x = i * s_gridSpacing; + for (int j = 0; j < s_gridSize; ++j) { + float y = j * s_gridSpacing; + + float dx = x - cx; + float dy = y - cy; + + float r = sqrt((dx * dx) + (dy * dy)); + + float z = period; + if (r < min_r) { + r = min_r; + } + z = (1.0 / r) * sin(period * r + phase); + if (z > period) { + z = period; + } else if (z < -period) { + z = -period; + } + z = floor + magnitude * z; + + convertFromFloat(p, z, type); + p += bytesPerElement; + } + } +} + + + +static float +randomHeight +( +int step +) +{ + return (0.33 * s_gridSpacing * s_gridSize * step * (rand() - (0.5 * RAND_MAX))) / (1.0 * RAND_MAX * s_gridSize); +} + + + +static void +dumpGrid +( +const byte_t * grid, +int bytesPerElement, +PHY_ScalarType type, +int max +) +{ + //std::cerr << "Grid:\n"; + + char buffer[32]; + + for (int j = 0; j < max; ++j) { + for (int i = 0; i < max; ++i) { + long offset = j * s_gridSize + i; + float z = convertToFloat(grid + offset * bytesPerElement, type); + sprintf(buffer, "%6.2f", z); + //std::cerr << " " << buffer; + } + //std::cerr << "\n"; + } +} + + + +static void +updateHeight +( +byte_t * p, +float new_val, +PHY_ScalarType type +) +{ + float old_val = convertToFloat(p, type); + if (!old_val) { + convertFromFloat(p, new_val, type); + } +} + + + +// creates a random, fractal heightfield +static void +setFractal +( +byte_t * grid, +int bytesPerElement, +PHY_ScalarType type, +int step +) +{ + btAssert(grid); + btAssert(bytesPerElement > 0); + btAssert(step > 0); + btAssert(step < s_gridSize); + + int newStep = step / 2; +// std::cerr << "Computing grid with step = " << step << ": before\n"; +// dumpGrid(grid, bytesPerElement, type, step + 1); + + // special case: starting (must set four corners) + if (s_gridSize - 1 == step) { + // pick a non-zero (possibly negative) base elevation for testing + float base = randomHeight(step / 2); + + convertFromFloat(grid, base, type); + convertFromFloat(grid + step * bytesPerElement, base, type); + convertFromFloat(grid + step * s_gridSize * bytesPerElement, base, type); + convertFromFloat(grid + (step * s_gridSize + step) * bytesPerElement, base, type); + } + + // determine elevation of each corner + float c00 = convertToFloat(grid, type); + float c01 = convertToFloat(grid + step * bytesPerElement, type); + float c10 = convertToFloat(grid + (step * s_gridSize) * bytesPerElement, type); + float c11 = convertToFloat(grid + (step * s_gridSize + step) * bytesPerElement, type); + + // set top middle + updateHeight(grid + newStep * bytesPerElement, 0.5 * (c00 + c01) + randomHeight(step), type); + + // set left middle + updateHeight(grid + (newStep * s_gridSize) * bytesPerElement, 0.5 * (c00 + c10) + randomHeight(step), type); + + // set right middle + updateHeight(grid + (newStep * s_gridSize + step) * bytesPerElement, 0.5 * (c01 + c11) + randomHeight(step), type); + + // set bottom middle + updateHeight(grid + (step * s_gridSize + newStep) * bytesPerElement, 0.5 * (c10 + c11) + randomHeight(step), type); + + // set middle + updateHeight(grid + (newStep * s_gridSize + newStep) * bytesPerElement, 0.25 * (c00 + c01 + c10 + c11) + randomHeight(step), type); + +// std::cerr << "Computing grid with step = " << step << ": after\n"; +// dumpGrid(grid, bytesPerElement, type, step + 1); + + // terminate? + if (newStep < 2) { + return; + } + + // recurse + setFractal(grid, bytesPerElement, type, newStep); + setFractal(grid + newStep * bytesPerElement, bytesPerElement, type, newStep); + setFractal(grid + (newStep * s_gridSize) * bytesPerElement, bytesPerElement, type, newStep); + setFractal(grid + ((newStep * s_gridSize) + newStep) * bytesPerElement, bytesPerElement, type, newStep); +} + + + +static byte_t * +getRawHeightfieldData +( +eTerrainModel model, +PHY_ScalarType type, +btScalar& minHeight, +btScalar& maxHeight +) +{ +// std::cerr << "\nRegenerating terrain\n"; +// std::cerr << " model = " << model << "\n"; +// std::cerr << " type = " << type << "\n"; + + long nElements = ((long) s_gridSize) * s_gridSize; +// std::cerr << " nElements = " << nElements << "\n"; + + int bytesPerElement = getByteSize(type); +// std::cerr << " bytesPerElement = " << bytesPerElement << "\n"; + btAssert(bytesPerElement > 0 && "bad bytes per element"); + + long nBytes = nElements * bytesPerElement; +// std::cerr << " nBytes = " << nBytes << "\n"; + byte_t * raw = new byte_t[nBytes]; + btAssert(raw && "out of memory"); + + // reseed randomization every 30 seconds +// srand(time(NULL) / 30); + + // populate based on model + switch (model) { + case eRadial: + setRadial(raw, bytesPerElement, type); + break; + + case eFractal: + for (int i = 0; i < nBytes; i++) + { + raw[i] = 0; + } + setFractal(raw, bytesPerElement, type, s_gridSize - 1); + break; + + default: + btAssert(!"bad model type"); + } + + if (0) { + // inside if(0) so it keeps compiling but isn't + // exercised and doesn't cause warnings +// std::cerr << "final grid:\n"; + dumpGrid(raw, bytesPerElement, type, s_gridSize - 1); + } + + // find min/max + for (int i = 0; i < s_gridSize; ++i) { + for (int j = 0; j < s_gridSize; ++j) { + float z = getGridHeight(raw, i, j, type); +// std::cerr << "i=" << i << ", j=" << j << ": z=" << z << "\n"; + + // update min/max + if (!i && !j) { + minHeight = z; + maxHeight = z; + } else { + if (z < minHeight) { + minHeight = z; + } + if (z > maxHeight) { + maxHeight = z; + } + } + } + } + + if (maxHeight < -minHeight) { + maxHeight = -minHeight; + } + if (minHeight > -maxHeight) { + minHeight = -maxHeight; + } + +// std::cerr << " minHeight = " << minHeight << "\n"; +// std::cerr << " maxHeight = " << maxHeight << "\n"; + + return raw; +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TerrainDemo class +// +//////////////////////////////////////////////////////////////////////////////// + +/// class that demonstrates the btHeightfieldTerrainShape object +class TerrainDemo : public GlutDemoApplication { +public: + // constructor, destructor --------------------------------------------- + TerrainDemo(void); + ~TerrainDemo(void); + + virtual void initPhysics() {} + + // public class methods ------------------------------------------------ + void initialize(void); + + // DemoApplication class interface methods ----------------------------- + void clientMoveAndDisplay(void); + void keyboardCallback(unsigned char key, int x, int y); + void renderme(void); + +private: + // private helper methods ---------------------------------------------- + void resetPhysics(void); + void clearWorld(void); + + // private data members ------------------------------------------------ + btDefaultCollisionConfiguration * m_collisionConfiguration; + btCollisionDispatcher * m_dispatcher; + btAxisSweep3 * m_overlappingPairCache; + btSequentialImpulseConstraintSolver * m_constraintSolver; + btAlignedObjectArray m_collisionShapes; + int m_upAxis; + PHY_ScalarType m_type; + eTerrainModel m_model; + byte_t * m_rawHeightfieldData; + btScalar m_minHeight; + btScalar m_maxHeight; + float m_phase; // for dynamics + bool m_isDynamic; +}; + + + +TerrainDemo::TerrainDemo(void) +: +m_collisionConfiguration(NULL), +m_dispatcher(NULL), +m_overlappingPairCache(NULL), +m_constraintSolver(NULL), +m_upAxis(1), +m_type(PHY_FLOAT), +m_model(eFractal), +m_rawHeightfieldData(NULL), +m_phase(0.0), +m_isDynamic(true) +{ +} + + + +TerrainDemo::~TerrainDemo(void) +{ + clearWorld(); + + //delete dynamics world + delete m_dynamicsWorld; + + //delete solver + delete m_constraintSolver; + + //delete broadphase + delete m_overlappingPairCache; + + //delete dispatcher + delete m_dispatcher; + + delete m_collisionConfiguration; + +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TerrainDemo -- public class methods +// +//////////////////////////////////////////////////////////////////////////////// + +/// one-time class and physics initialization +void TerrainDemo::initialize(void) +{ +// std::cerr << "initializing...\n"; + + // set up basic state + m_upAxis = 1; // start with Y-axis as "up" + m_type = PHY_FLOAT; + m_model = eRadial;//eFractal; + m_isDynamic = true; + + // set up the physics world + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + m_overlappingPairCache = new btAxisSweep3(worldMin,worldMax); + m_constraintSolver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); + + // initialize axis- or type-dependent physics from here + this->resetPhysics(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TerrainDemo -- DemoApplication class interface methods +// +//////////////////////////////////////////////////////////////////////////////// + +void TerrainDemo::clientMoveAndDisplay(void) +{ + // elapsed time + float us = getDeltaTimeMicroseconds(); + float seconds = 1.0e-6 * us; + + // we'll carefully iterate through each time step so we can update + // the dynamic model if necessary + long nStepsPerIteration = 1; + while (seconds > 1.0e-6) { + float dt = nStepsPerIteration * s_engineTimeStep; + if (dt > seconds) { + dt = seconds; + } + seconds -= dt; + // std::cerr << " Stepping through " << dt << " seconds\n"; + + // if dynamic and radial, go ahead and update the field + if (m_rawHeightfieldData && m_isDynamic && eRadial == m_model) { + m_phase += s_deltaPhase * dt; + if (m_phase > 2.0 * SIMD_PI) { + m_phase -= 2.0 * SIMD_PI; + } + int bpe = getByteSize(m_type); + btAssert(bpe > 0 && "Bad bytes per element"); + setRadial(m_rawHeightfieldData, bpe, m_type, m_phase); + } + + if (m_dynamicsWorld) { + m_dynamicsWorld->stepSimulation(dt, + nStepsPerIteration + 1, s_engineTimeStep); + } + } + + // okay, render + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + renderme(); + glFlush(); + glutSwapBuffers(); +} + + +static PHY_ScalarType nextType (PHY_ScalarType type) +{ + switch (type) + { + case PHY_FLOAT: + return PHY_SHORT; + break; + case PHY_SHORT: + return PHY_UCHAR; + break; + case PHY_UCHAR: + return PHY_FLOAT; + break; + } + btAssert (0); + return PHY_FLOAT; +} + +void TerrainDemo::keyboardCallback(unsigned char key, int x, int y) { + + if (',' == key) { + // increment model + m_model = (eFractal == m_model) ? eRadial : eFractal; + this->resetPhysics(); + } + if ('/' == key) { + // increment type + m_type = nextType(m_type); + this->resetPhysics(); + } + if ('\\' == key) { + // increment axis + m_upAxis++; + if (m_upAxis > 2) { + m_upAxis = 0; + } + this->resetPhysics(); + } + if ('[' == key) { + // toggle dynamics + m_isDynamic = !m_isDynamic; + } + + // let demo base class handle! + DemoApplication::keyboardCallback(key, x, y); +} + + + +static void doPrint(int x,int& y,int dy,const char * text) +{ + GLDebugDrawString(x,y, text); + y += dy; +} + + + +/// override the default display just so we can overlay a bit more text +void TerrainDemo::renderme(void) +{ + // give base class a shot + DemoApplication::renderme(); + + // overlay any debug information + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + // switch to orthographic + setOrthographicProjection(); + + // we'll draw on the right top of the screen + const int lineWidth = 200; + const int lineHeight = 16; + char buffer[256]; + + int xStart = m_glutScreenWidth - lineWidth; + int yStart = lineHeight; + + sprintf(buffer, "Terrain Type: %s", getTerrainTypeName(m_model)); + doPrint(xStart, yStart, lineHeight, buffer); + doPrint(xStart, yStart, lineHeight, "Press ',' to cycle terrain types"); + doPrint(xStart, yStart, lineHeight, ""); + + sprintf(buffer, "Data Type: %s", getDataTypeName(m_type)); + doPrint(xStart, yStart, lineHeight, buffer); + doPrint(xStart, yStart, lineHeight, "Press '/' to cycle data types"); + doPrint(xStart, yStart, lineHeight, ""); + + sprintf(buffer, "'up' axis: %s", getUpAxisName(m_upAxis)); + doPrint(xStart, yStart, lineHeight, buffer); + doPrint(xStart, yStart, lineHeight, "Press '\\' to cycle 'up' axes"); + doPrint(xStart, yStart, lineHeight, ""); + + if (eRadial == m_model) { + sprintf(buffer, "Dynamic: %s", m_isDynamic ? "yes" : "no"); + doPrint(xStart, yStart, lineHeight, buffer); + doPrint(xStart, yStart, lineHeight, "Press '[' to toggle dynamics"); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TerrainDemo -- private helper methods +// +//////////////////////////////////////////////////////////////////////////////// + +/// called whenever key terrain attribute is changed +void TerrainDemo::resetPhysics(void) +{ + // remove old heightfield + clearWorld(); + + // reset gravity to point in appropriate direction + m_dynamicsWorld->setGravity(getUpVector(m_upAxis, 0.0, -s_gravity)); + + // get new heightfield of appropriate type + m_rawHeightfieldData = + getRawHeightfieldData(m_model, m_type, m_minHeight, m_maxHeight); + btAssert(m_rawHeightfieldData && "failed to create raw heightfield"); + + bool flipQuadEdges = false; + btHeightfieldTerrainShape * heightfieldShape = + new btHeightfieldTerrainShape(s_gridSize, s_gridSize, + m_rawHeightfieldData, + s_gridHeightScale, + m_minHeight, m_maxHeight, + m_upAxis, m_type, flipQuadEdges); + btAssert(heightfieldShape && "null heightfield"); + + // scale the shape + btVector3 localScaling = getUpVector(m_upAxis, s_gridSpacing, 1.0); + heightfieldShape->setLocalScaling(localScaling); + + // stash this shape away + m_collisionShapes.push_back(heightfieldShape); + + // set origin to middle of heightfield + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(0,-20,0)); + + // create ground object + float mass = 0.0; + localCreateRigidBody(mass, tr, heightfieldShape); +} + + +/// removes all objects and shapes from the world +void TerrainDemo::clearWorld(void) +{ + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jinitialize(); + + return demo; +} + diff --git a/Demos/TerrainDemo/TerrainDemo.h b/Demos/TerrainDemo/TerrainDemo.h new file mode 100644 index 0000000..1b6a3e6 --- /dev/null +++ b/Demos/TerrainDemo/TerrainDemo.h @@ -0,0 +1,27 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006,2008 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef TERRAIN_DEMO_H +#define TERRAIN_DEMO_H + + +#include "GlutDemoApplication.h" + + +// all we need to expose publicly is the factory method! +GlutDemoApplication * btCreateTerrainDemo(void); + + +#endif //TERRAIN_DEMO_H + diff --git a/Demos/TerrainDemo/main.cpp b/Demos/TerrainDemo/main.cpp new file mode 100644 index 0000000..6510f24 --- /dev/null +++ b/Demos/TerrainDemo/main.cpp @@ -0,0 +1,14 @@ + +#include "TerrainDemo.h" +#include "GlutStuff.h" + +int main(int argc,char** argv) +{ + DemoApplication * demo = btCreateTerrainDemo(); + btAssert(demo && "failed to create terrain demo object"); + + return glutmain(argc, argv, 800, 600, + "Terrain Demo. http://www.continuousphysics.com/Bullet/phpBB2/", + demo); +} + diff --git a/Demos/ThreadingDemo/CMakeLists.txt b/Demos/ThreadingDemo/CMakeLists.txt new file mode 100644 index 0000000..54bdf31 --- /dev/null +++ b/Demos/ThreadingDemo/CMakeLists.txt @@ -0,0 +1,47 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +#currently this demo has only been tested under Windows 32bit +#IF (WIN32) + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL + ${VECTOR_MATH_INCLUDE} +) + +LINK_LIBRARIES( +BulletMultiThreaded BulletDynamics BulletCollision LinearMath +) + +IF (WIN32) +ADD_EXECUTABLE(AppThreadingDemo + main.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppThreadingDemo + main.cpp + ) +ENDIF() + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppThreadingDemo pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppThreadingDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppThreadingDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppThreadingDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + +#ENDIF(WIN32) diff --git a/Demos/ThreadingDemo/main.cpp b/Demos/ThreadingDemo/main.cpp new file mode 100644 index 0000000..405a5f7 --- /dev/null +++ b/Demos/ThreadingDemo/main.cpp @@ -0,0 +1,185 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2010 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/// ThreadingDemo shows how to use the cross platform thread support interface. +/// You can start threads and perform a blocking wait for completion +/// Under Windows it uses Win32 Threads. On Mac and Linux it uses pthreads. On PlayStation 3 Cell SPU it uses SPURS. + +/// June 2010 +/// New: critical section/barriers and non-blocking pollingn for completion, currently Windows only + +void SampleThreadFunc(void* userPtr,void* lsMemory); +void* SamplelsMemoryFunc(); + +#include +#include "BulletMultiThreaded/PlatformDefinitions.h" + +#ifdef USE_PTHREADS +//#ifdef __APPLE__ +#include "BulletMultiThreaded/PosixThreadSupport.h" + +btThreadSupportInterface* createThreadSupport(int numThreads) +{ + PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads", + SampleThreadFunc, + SamplelsMemoryFunc, + numThreads); + btThreadSupportInterface* threadSupport = new PosixThreadSupport(constructionInfo); + + return threadSupport; + +} + + +#elif defined( _WIN32) +#include "BulletMultiThreaded/Win32ThreadSupport.h" + +btThreadSupportInterface* createThreadSupport(int numThreads) +{ + Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("testThreads",SampleThreadFunc,SamplelsMemoryFunc,numThreads); + Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo); + return threadSupport; + +} + +#endif + + +struct SampleArgs +{ + SampleArgs() + :m_fakeWork(1) + { + } + btCriticalSection* m_cs; + float m_fakeWork; +}; + +struct SampleThreadLocalStorage +{ + int threadId; +}; + + +void SampleThreadFunc(void* userPtr,void* lsMemory) +{ + printf("thread started\n"); + + SampleThreadLocalStorage* localStorage = (SampleThreadLocalStorage*) lsMemory; + + SampleArgs* args = (SampleArgs*) userPtr; + int workLeft = true; + while (workLeft) + { + args->m_cs->lock(); + int count = args->m_cs->getSharedParam(0); + args->m_cs->setSharedParam(0,count-1); + args->m_cs->unlock(); + if (count>0) + { + printf("thread %d processed number %d\n",localStorage->threadId, count); + } + //do some fake work + for (int i=0;i<1000000;i++) + args->m_fakeWork = btScalar(1.21)*args->m_fakeWork; + workLeft = count>0; + } + printf("finished\n"); + //do nothing +} + + +void* SamplelsMemoryFunc() +{ + //don't create local store memory, just return 0 + return new SampleThreadLocalStorage; +} + + + + + + + + + + +int main(int argc,char** argv) +{ + int numThreads = 8; + + btThreadSupportInterface* threadSupport = createThreadSupport(numThreads); + + + threadSupport->startSPU(); + + for (int i=0;igetNumTasks();i++) + { + SampleThreadLocalStorage* storage = (SampleThreadLocalStorage*)threadSupport->getThreadLocalMemory(i); + btAssert(storage); + storage->threadId = i; + } + + + SampleArgs args; + args.m_cs = threadSupport->createCriticalSection(); + args.m_cs->setSharedParam(0,100); + + + unsigned int arg0,arg1; + int i; + for (i=0;isendRequest(1, (ppu_address_t) &args, i); + } + + bool blockingWait =true; + if (blockingWait) + { + for (i=0;iwaitForResponse(&arg0,&arg1); + printf("finished waiting for response: %d %d\n", arg0,arg1); + } + } else + { +#if _WIN32 + int numActiveThreads = numThreads; + while (numActiveThreads) + { + if (((Win32ThreadSupport*)threadSupport)->isTaskCompleted(&arg0,&arg1,0)) + { + numActiveThreads--; + printf("numActiveThreads = %d\n",numActiveThreads); + + } else + { + printf("polling\n"); + } + }; +#else + btAssert(0); + printf("non-blocking wait is not supported on this platform\n"); + exit(0); +#endif + } + +printf("stopping threads\n"); + + delete threadSupport; + printf("Press ENTER to quit\n"); + getchar(); + return 0; +} diff --git a/Demos/UserCollisionAlgorithm/CMakeLists.txt b/Demos/UserCollisionAlgorithm/CMakeLists.txt new file mode 100644 index 0000000..cfe9e4a --- /dev/null +++ b/Demos/UserCollisionAlgorithm/CMakeLists.txt @@ -0,0 +1,38 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +IF (WIN32) + ADD_EXECUTABLE(AppUserCollisionAlgorithm + UserCollisionAlgorithm.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppUserCollisionAlgorithm + UserCollisionAlgorithm.cpp + ) +ENDIF() + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppUserCollisionAlgorithm PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppUserCollisionAlgorithm PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppUserCollisionAlgorithm PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp new file mode 100644 index 0000000..5d094f2 --- /dev/null +++ b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp @@ -0,0 +1,175 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" +#include "GLDebugDrawer.h" +#include "UserCollisionAlgorithm.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +//The user defined collision algorithm +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" + +GLDebugDrawer debugDrawer; + +static const int NUM_VERTICES = 5; +static const int NUM_TRIANGLES=4; + +btVector3 gVertices[NUM_VERTICES]; +int gIndices[NUM_TRIANGLES*3]; +const float TRIANGLE_SIZE=10.f; + + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(float friction0,float friction1) +{ + btScalar friction = friction0 * friction1; + + const btScalar MAX_FRICTION = 10.f; + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(float restitution0,float restitution1) +{ + return restitution0 * restitution1; +} + + + + + + +int main(int argc,char** argv) +{ + + UserCollisionAlgorithm* userCollisionAlgorithm = new UserCollisionAlgorithm; + userCollisionAlgorithm->initPhysics(); + userCollisionAlgorithm->setCameraDistance(30.f); + + return glutmain(argc, argv,640,480,"Static Concave Mesh Demo",userCollisionAlgorithm); +} + +void UserCollisionAlgorithm::initPhysics() +{ + #define TRISIZE 5.f + + + const int NUM_VERTS_X = 50; + const int NUM_VERTS_Y = 50; + const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + + btVector3* gVertices = new btVector3[totalVerts]; + + int i; + for ( i=0;iaddTriangle(gVertices[j*NUM_VERTS_X+i],gVertices[j*NUM_VERTS_X+i+1],gVertices[(j+1)*NUM_VERTS_X+i+1]); + trimesh->addTriangle(gVertices[j*NUM_VERTS_X+i],gVertices[(j+1)*NUM_VERTS_X+i+1],gVertices[(j+1)*NUM_VERTS_X+i]); + } + } + + delete[] gVertices; + + bool useQuantizedBvhTree = true; + btCollisionShape* trimeshShape = new btBvhTriangleMeshShape(trimesh,useQuantizedBvhTree); + + //ConstraintSolver* solver = new btSequentialImpulseConstraintSolver; + btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); + + btVector3 maxAabb(10000,10000,10000); + btBroadphaseInterface* broadphase = new btAxisSweep3(-maxAabb,maxAabb);//SimpleBroadphase(); + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btSphereSphereCollisionAlgorithm::CreateFunc); + + btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver,collisionConfiguration); + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-2,0)); + + btRigidBody* staticBody= localCreateRigidBody(mass, startTransform,trimeshShape); + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + { + for (int i=0;i<10;i++) + { + btCollisionShape* sphereShape = new btSphereShape(1); + startTransform.setOrigin(btVector3(1,2*i,1)); + //btRigidBody* body = localCreateRigidBody(1, startTransform,sphereShape); + localCreateRigidBody(1, startTransform,sphereShape); + } + } + + + + m_dynamicsWorld->setDebugDrawer(&debugDrawer); +} + +void UserCollisionAlgorithm::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + glutSwapBuffers(); + +} + + + + + + +void UserCollisionAlgorithm::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + glFlush(); + glutSwapBuffers(); +} + + diff --git a/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.h b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.h new file mode 100644 index 0000000..acfa37c --- /dev/null +++ b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef USER_COLLISION_ALGORITHM_DEMO_H +#define USER_COLLISION_ALGORITHM_DEMO_H + +#include "GlutDemoApplication.h" + +///UserCollisionAlgorithmDemo shows how to register and use your own collision algorithm for a certain shape pair type +class UserCollisionAlgorithm : public GlutDemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + + +}; + +#endif //USER_COLLISION_ALGORITHM_DEMO_H + diff --git a/Demos/VectorAdd_OpenCL/AMD/CMakeLists.txt b/Demos/VectorAdd_OpenCL/AMD/CMakeLists.txt new file mode 100644 index 0000000..0b6e7ec --- /dev/null +++ b/Demos/VectorAdd_OpenCL/AMD/CMakeLists.txt @@ -0,0 +1,34 @@ + + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${AMD_OPENCL_INCLUDES} +) + +LINK_LIBRARIES( + BulletMultiThreaded LinearMath + ${CMAKE_ATISTREAMSDK_LIBRARY} +) + +ADD_EXECUTABLE(AppVectorAdd_AMD +../MiniCL_VectorAdd.cpp +../VectorAddKernels.cl +) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppVectorAdd_AMD pthread) +ENDIF(UNIX) + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( + TARGET AppVectorAdd_AMD + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/VectorAdd_OpenCL/VectorAddKernels.cl ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF() + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppVectorAdd_AMD PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppVectorAdd_AMD PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppVectorAdd_AMD PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) diff --git a/Demos/VectorAdd_OpenCL/Apple/CMakeLists.txt b/Demos/VectorAdd_OpenCL/Apple/CMakeLists.txt new file mode 100644 index 0000000..521c3b4 --- /dev/null +++ b/Demos/VectorAdd_OpenCL/Apple/CMakeLists.txt @@ -0,0 +1,25 @@ +# AppVectorAdd is a very basic test OpenCL/MiniCL. + +IF (APPLE) + FIND_LIBRARY(OPENCL_LIBRARY OpenCL DOC "OpenCL lib for OSX") + FIND_PATH(OPENCL_INCLUDE_DIR OpenCL/cl.h DOC "Include for OpenCL on OSX") +ENDIF (APPLE) + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + +LINK_LIBRARIES( + LinearMath ${OPENCL_LIBRARY} +) + +ADD_EXECUTABLE(AppVectorAdd_Apple +../MiniCL_VectorAdd.cpp +../VectorAddKernels.cl +) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppVectorAdd_Apple pthread) +ENDIF(UNIX) + diff --git a/Demos/VectorAdd_OpenCL/CMakeLists.txt b/Demos/VectorAdd_OpenCL/CMakeLists.txt new file mode 100644 index 0000000..8f59145 --- /dev/null +++ b/Demos/VectorAdd_OpenCL/CMakeLists.txt @@ -0,0 +1,16 @@ + +IF(BUILD_MINICL_OPENCL_DEMOS) + SUBDIRS( MiniCL ) +ENDIF() + +IF(BUILD_AMD_OPENCL_DEMOS) + SUBDIRS(AMD) +ENDIF() + +IF(BUILD_NVIDIA_OPENCL_DEMOS) + SUBDIRS(NVidia) +ENDIF() + +IF(APPLE) + SUBDIRS(Apple) +ENDIF() diff --git a/Demos/VectorAdd_OpenCL/MiniCL/CMakeLists.txt b/Demos/VectorAdd_OpenCL/MiniCL/CMakeLists.txt new file mode 100644 index 0000000..d0c4863 --- /dev/null +++ b/Demos/VectorAdd_OpenCL/MiniCL/CMakeLists.txt @@ -0,0 +1,38 @@ +# AppMiniCLVectorAdd is a very basic test for MiniCL. + + +ADD_DEFINITIONS(-DUSE_MINICL) + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + +LINK_LIBRARIES( + MiniCL + BulletMultiThreaded + LinearMath +) + +ADD_EXECUTABLE(AppVectorAdd_Mini +../MiniCL_VectorAdd.cpp +../VectorAddKernels.cl +) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppVectorAdd_Mini pthread) +ENDIF(UNIX) + + +IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + ADD_CUSTOM_COMMAND( + TARGET AppVectorAdd_Mini + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/VectorAdd_OpenCL/VectorAddKernels.cl ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF() + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppVectorAdd_Mini PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppVectorAdd_Mini PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppVectorAdd_Mini PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/VectorAdd_OpenCL/MiniCL_VectorAdd.cpp b/Demos/VectorAdd_OpenCL/MiniCL_VectorAdd.cpp new file mode 100644 index 0000000..5857f8c --- /dev/null +++ b/Demos/VectorAdd_OpenCL/MiniCL_VectorAdd.cpp @@ -0,0 +1,389 @@ + +///VectorAdd sample, from the NVidia JumpStart Guide +///http://developer.download.nvidia.com/OpenCL/NVIDIA_OpenCL_JumpStart_Guide.pdf + +///Instead of #include we include +///Apart from this include file, all other code should compile and work on OpenCL compliant implementation + + +//#define LOAD_FROM_FILE + +#ifdef USE_MINICL + #include "MiniCL/cl.h" +#else //USE_MINICL + #ifdef __APPLE__ + #include + #else + #include + #endif //__APPLE__ +#endif//USE_MINICL + +#include +#include +#include +#include +#include "LinearMath/btMinMax.h" +#define GRID3DOCL_CHECKERROR(a, b) if((a)!=(b)) { printf("3D GRID OCL Error : %d\n", (a)); btAssert((a) == (b)); } +size_t wgSize; + + +#ifndef USE_MINICL +#define MSTRINGIFY(A) #A +const char* stringifiedSourceCL = +#include "VectorAddKernels.cl" +#else +const char* stringifiedSourceCL = ""; +#endif + + + + +char* loadProgSource(const char* cFilename, const char* cPreamble, size_t* szFinalLength) +{ + // locals + FILE* pFileStream = NULL; + size_t szSourceLength; + + // open the OpenCL source code file + pFileStream = fopen(cFilename, "rb"); + if(pFileStream == 0) + { + return NULL; + } + + size_t szPreambleLength = strlen(cPreamble); + + // get the length of the source code + fseek(pFileStream, 0, SEEK_END); + szSourceLength = ftell(pFileStream); + fseek(pFileStream, 0, SEEK_SET); + + // allocate a buffer for the source code string and read it in + char* cSourceString = (char *)malloc(szSourceLength + szPreambleLength + 1); + memcpy(cSourceString, cPreamble, szPreambleLength); + fread((cSourceString) + szPreambleLength, szSourceLength, 1, pFileStream); + + // close the file and return the total length of the combined (preamble + source) string + fclose(pFileStream); + if(szFinalLength != 0) + { + *szFinalLength = szSourceLength + szPreambleLength; + } + cSourceString[szSourceLength + szPreambleLength] = '\0'; + + return cSourceString; +} + +size_t workitem_size[3]; + +void printDevInfo(cl_device_id device) +{ + char device_string[1024]; + + clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(device_string), &device_string, NULL); + printf( " Device %s:\n", device_string); + + // CL_DEVICE_INFO + cl_device_type type; + clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(type), &type, NULL); + if( type & CL_DEVICE_TYPE_CPU ) + printf(" CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_CPU"); + if( type & CL_DEVICE_TYPE_GPU ) + printf( " CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_GPU"); + if( type & CL_DEVICE_TYPE_ACCELERATOR ) + printf( " CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR"); + if( type & CL_DEVICE_TYPE_DEFAULT ) + printf( " CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT"); + + // CL_DEVICE_MAX_COMPUTE_UNITS + cl_uint compute_units; + clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL); + printf( " CL_DEVICE_MAX_COMPUTE_UNITS:\t%d\n", compute_units); + + // CL_DEVICE_MAX_WORK_GROUP_SIZE + + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(workitem_size), &workitem_size, NULL); + printf( " CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%zu / %zu / %zu \n", workitem_size[0], workitem_size[1], workitem_size[2]); + +} + + + + +// Main function +// ********************************************************************* +int main(int argc, char **argv) +{ + void *srcA, *srcB, *dst; // Host buffers for OpenCL test + cl_context cxGPUContext; // OpenCL context + cl_command_queue cqCommandQue; // OpenCL command que + cl_device_id* cdDevices; // OpenCL device list + cl_program cpProgram; // OpenCL program + cl_kernel ckKernel; // OpenCL kernel + cl_mem cmMemObjs[3]; // OpenCL memory buffer objects: 3 for device + size_t szGlobalWorkSize[1]; // 1D var for Total # of work items + size_t szLocalWorkSize[1]; // 1D var for # of work items in the work group + size_t szParmDataBytes; // Byte size of context information + cl_int ciErr1, ciErr2; // Error code var + int iTestN = 100000 * 8; // Size of Vectors to process + + int actualGlobalSize = iTestN>>3; + + // set Global and Local work size dimensions + szGlobalWorkSize[0] = iTestN >> 3; // do 8 computations per work item + szLocalWorkSize[0]= iTestN>>3; + + + // Allocate and initialize host arrays + srcA = (void *)malloc (sizeof(cl_float) * iTestN); + srcB = (void *)malloc (sizeof(cl_float) * iTestN); + dst = (void *)malloc (sizeof(cl_float) * iTestN); + + int i; + + // Initialize arrays with some values + for (i=0;i processing outside of the buffer + //make sure to check kernel + } + + size_t globalThreads[] = {num_t * workgroupSize}; + size_t localThreads[] = {workgroupSize}; + + + localWorkSize[0] = workgroupSize; + globalWorkSize[0] = num_t * workgroupSize; + localWorkSize[1] = 1; + globalWorkSize[1] = 1; + + // Copy input data from host to GPU and launch kernel + ciErr1 |= clEnqueueNDRangeKernel(cqCommandQue, ckKernel, 1, NULL, globalThreads, localThreads, 0, NULL, NULL); + + } + + if (ciErrNum != CL_SUCCESS) + { + printf("cannot clEnqueueNDRangeKernel\n"); + exit(0); + } + + clFinish(cqCommandQue); + // Read back results and check accumulated errors + ciErr1 |= clEnqueueReadBuffer(cqCommandQue, cmMemObjs[2], CL_TRUE, 0, sizeof(cl_float8) * szGlobalWorkSize[0], dst, 0, NULL, NULL); + + // Release kernel, program, and memory objects + // NOTE: Most properly this should be done at any of the exit points above, but it is omitted elsewhere for clarity. + free(cdDevices); + clReleaseKernel(ckKernel); + clReleaseProgram(cpProgram); + clReleaseCommandQueue(cqCommandQue); + clReleaseContext(cxGPUContext); + + + // print the results + int iErrorCount = 0; + for (i = 0; i < iTestN; i++) + { + if (((float*)dst)[i] != ((float*)srcA)[i]+((float*)srcB)[i]) + iErrorCount++; + } + + if (iErrorCount) + { + printf("MiniCL validation FAILED\n"); + } else + { + printf("MiniCL validation SUCCESSFULL\n"); + } + // Free host memory, close log and return success + for (i = 0; i < 3; i++) + { + clReleaseMemObject(cmMemObjs[i]); + } + + free(srcA); + free(srcB); + free (dst); + printf("Press ENTER to quit\n"); + getchar(); +} + + +#ifdef USE_MINICL + +#include "MiniCL/cl_MiniCL_Defs.h" + +extern "C" +{ + ///GUID_ARG is only used by MiniCL to pass in the guid used by its get_global_id implementation + + + #define MSTRINGIFY(A) A + #include "VectorAddKernels.cl" + #undef MSTRINGIFY +} +MINICL_REGISTER(VectorAdd) +#endif//USE_MINICL diff --git a/Demos/VectorAdd_OpenCL/NVidia/CMakeLists.txt b/Demos/VectorAdd_OpenCL/NVidia/CMakeLists.txt new file mode 100644 index 0000000..f23717b --- /dev/null +++ b/Demos/VectorAdd_OpenCL/NVidia/CMakeLists.txt @@ -0,0 +1,28 @@ + + + + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${NVIDIA_OPENCL_INCLUDES} +) + +LINK_LIBRARIES( + LinearMath + ${NVIDIA_OPENCL_LIBRARIES} +) + +ADD_EXECUTABLE(AppVectorAdd_NVidia +../MiniCL_VectorAdd.cpp +../VectorAddKernels.cl +) + +IF (UNIX) + TARGET_LINK_LIBRARIES(AppVectorAdd_NVidia pthread) +ENDIF(UNIX) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppVectorAdd_NVidia PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppVectorAdd_NVidia PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppVectorAdd_NVidia PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/VectorAdd_OpenCL/VectorAddKernels.cl b/Demos/VectorAdd_OpenCL/VectorAddKernels.cl new file mode 100644 index 0000000..03f13a9 --- /dev/null +++ b/Demos/VectorAdd_OpenCL/VectorAddKernels.cl @@ -0,0 +1,35 @@ + + +MSTRINGIFY( + +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +/////////////////////////////////////////////////// +// OpenCL Kernel Function for element by element vector addition +__kernel void VectorAdd(__global const float8* a, __global const float8* b, __global float8* c GUID_ARG) +{ + // get oct-float index into global data array + int iGID = get_global_id(0); + if (iGID>=100000) + return; + + // write back out to GMEM + c[iGID] = a[iGID] + b[iGID]; +} + +); \ No newline at end of file diff --git a/Demos/VehicleDemo/CMakeLists.txt b/Demos/VehicleDemo/CMakeLists.txt new file mode 100644 index 0000000..744b73d --- /dev/null +++ b/Demos/VehicleDemo/CMakeLists.txt @@ -0,0 +1,31 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + + +# You shouldn't have to modify anything below this line +######################################################## + + + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + +LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(AppVehicleDemo + VehicleDemo.cpp + main.cpp +) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppVehicleDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppVehicleDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppVehicleDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/VehicleDemo/Makefile.am b/Demos/VehicleDemo/Makefile.am new file mode 100644 index 0000000..89e5bca --- /dev/null +++ b/Demos/VehicleDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=VehicleDemo + +VehicleDemo_SOURCES=VehicleDemo.cpp VehicleDemo.h main.cpp +VehicleDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +VehicleDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/VehicleDemo/Makefile.in b/Demos/VehicleDemo/Makefile.in new file mode 100644 index 0000000..61e3220 --- /dev/null +++ b/Demos/VehicleDemo/Makefile.in @@ -0,0 +1,518 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = VehicleDemo$(EXEEXT) +subdir = Demos/VehicleDemo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_VehicleDemo_OBJECTS = VehicleDemo-VehicleDemo.$(OBJEXT) \ + VehicleDemo-main.$(OBJEXT) +VehicleDemo_OBJECTS = $(am_VehicleDemo_OBJECTS) +VehicleDemo_DEPENDENCIES = +VehicleDemo_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(VehicleDemo_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(VehicleDemo_SOURCES) +DIST_SOURCES = $(VehicleDemo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +VehicleDemo_SOURCES = VehicleDemo.cpp VehicleDemo.h main.cpp +VehicleDemo_CXXFLAGS = -I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +VehicleDemo_LDADD = -L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Demos/VehicleDemo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Demos/VehicleDemo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +VehicleDemo$(EXEEXT): $(VehicleDemo_OBJECTS) $(VehicleDemo_DEPENDENCIES) + @rm -f VehicleDemo$(EXEEXT) + $(VehicleDemo_LINK) $(VehicleDemo_OBJECTS) $(VehicleDemo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VehicleDemo-VehicleDemo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VehicleDemo-main.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +VehicleDemo-VehicleDemo.o: VehicleDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -MT VehicleDemo-VehicleDemo.o -MD -MP -MF $(DEPDIR)/VehicleDemo-VehicleDemo.Tpo -c -o VehicleDemo-VehicleDemo.o `test -f 'VehicleDemo.cpp' || echo '$(srcdir)/'`VehicleDemo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/VehicleDemo-VehicleDemo.Tpo $(DEPDIR)/VehicleDemo-VehicleDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='VehicleDemo.cpp' object='VehicleDemo-VehicleDemo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -c -o VehicleDemo-VehicleDemo.o `test -f 'VehicleDemo.cpp' || echo '$(srcdir)/'`VehicleDemo.cpp + +VehicleDemo-VehicleDemo.obj: VehicleDemo.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -MT VehicleDemo-VehicleDemo.obj -MD -MP -MF $(DEPDIR)/VehicleDemo-VehicleDemo.Tpo -c -o VehicleDemo-VehicleDemo.obj `if test -f 'VehicleDemo.cpp'; then $(CYGPATH_W) 'VehicleDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/VehicleDemo.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/VehicleDemo-VehicleDemo.Tpo $(DEPDIR)/VehicleDemo-VehicleDemo.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='VehicleDemo.cpp' object='VehicleDemo-VehicleDemo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -c -o VehicleDemo-VehicleDemo.obj `if test -f 'VehicleDemo.cpp'; then $(CYGPATH_W) 'VehicleDemo.cpp'; else $(CYGPATH_W) '$(srcdir)/VehicleDemo.cpp'; fi` + +VehicleDemo-main.o: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -MT VehicleDemo-main.o -MD -MP -MF $(DEPDIR)/VehicleDemo-main.Tpo -c -o VehicleDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/VehicleDemo-main.Tpo $(DEPDIR)/VehicleDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='VehicleDemo-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -c -o VehicleDemo-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp + +VehicleDemo-main.obj: main.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -MT VehicleDemo-main.obj -MD -MP -MF $(DEPDIR)/VehicleDemo-main.Tpo -c -o VehicleDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/VehicleDemo-main.Tpo $(DEPDIR)/VehicleDemo-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='main.cpp' object='VehicleDemo-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(VehicleDemo_CXXFLAGS) $(CXXFLAGS) -c -o VehicleDemo-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Demos/VehicleDemo/VehicleDemo.cpp b/Demos/VehicleDemo/VehicleDemo.cpp new file mode 100644 index 0000000..2dfb990 --- /dev/null +++ b/Demos/VehicleDemo/VehicleDemo.cpp @@ -0,0 +1,671 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/// September 2006: VehicleDemo is work in progress, this file is mostly just a placeholder +/// This VehicleDemo file is very early in development, please check it later +/// One todo is a basic engine model: +/// A function that maps user input (throttle) into torque/force applied on the wheels +/// with gears etc. +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" + +// +// By default, Bullet Vehicle uses Y as up axis. +// You can override the up axis, for example Z-axis up. Enable this define to see how to: +//#define FORCE_ZAXIS_UP 1 +// + +#ifdef FORCE_ZAXIS_UP + int rightIndex = 0; + int upIndex = 2; + int forwardIndex = 1; + btVector3 wheelDirectionCS0(0,0,-1); + btVector3 wheelAxleCS(1,0,0); +#else + int rightIndex = 0; + int upIndex = 1; + int forwardIndex = 2; + btVector3 wheelDirectionCS0(0,-1,0); + btVector3 wheelAxleCS(-1,0,0); +#endif + +#include "GLDebugDrawer.h" +#include //printf debugging + +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" +#include "VehicleDemo.h" + +const int maxProxies = 32766; +const int maxOverlap = 65535; + +///btRaycastVehicle is the interface for the constraint that implements the raycast vehicle +///notice that for higher-quality slow-moving vehicles, another approach might be better +///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts +float gEngineForce = 0.f; +float gBreakingForce = 0.f; + +float maxEngineForce = 1000.f;//this should be engine/velocity dependent +float maxBreakingForce = 100.f; + +float gVehicleSteering = 0.f; +float steeringIncrement = 0.04f; +float steeringClamp = 0.3f; +float wheelRadius = 0.5f; +float wheelWidth = 0.4f; +float wheelFriction = 1000;//BT_LARGE_FLOAT; +float suspensionStiffness = 20.f; +float suspensionDamping = 2.3f; +float suspensionCompression = 4.4f; +float rollInfluence = 0.1f;//1.0f; + + +btScalar suspensionRestLength(0.6); + +#define CUBE_HALF_EXTENTS 1 + + + +//////////////////////////////////// + + + + +VehicleDemo::VehicleDemo() +: +m_carChassis(0), +m_indexVertexArrays(0), +m_vertices(0), +m_cameraHeight(4.f), +m_minCameraDistance(3.f), +m_maxCameraDistance(10.f) +{ + m_vehicle = 0; + m_wheelShape = 0; + m_cameraPosition = btVector3(30,30,30); +} + +VehicleDemo::~VehicleDemo() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jsetGravity(btVector3(0,0,-10)); +#endif + + //m_dynamicsWorld->setGravity(btVector3(0,0,0)); +btTransform tr; +tr.setIdentity(); + +//either use heightfield or triangle mesh +#define USE_TRIMESH_GROUND 1 +#ifdef USE_TRIMESH_GROUND + int i; + +const float TRIANGLE_SIZE=20.f; + + //create a triangle-mesh ground + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + + const int NUM_VERTS_X = 20; + const int NUM_VERTS_Y = 20; + const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + + m_vertices = new btVector3[totalVerts]; + int* gIndices = new int[totalTriangles*3]; + + + + for ( i=0;isetUseDiamondSubdivision(true); + + btVector3 localScaling(20,20,20); + localScaling[upIndex]=1.f; + groundShape->setLocalScaling(localScaling); + + tr.setOrigin(btVector3(0,-64.5f,0)); + +#endif // + + m_collisionShapes.push_back(groundShape); + + //create ground object + localCreateRigidBody(0,tr,groundShape); + +#ifdef FORCE_ZAXIS_UP +// indexRightAxis = 0; +// indexUpAxis = 2; +// indexForwardAxis = 1; + btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,2.f, 0.5f)); + btCompoundShape* compound = new btCompoundShape(); + btTransform localTrans; + localTrans.setIdentity(); + //localTrans effectively shifts the center of mass with respect to the chassis + localTrans.setOrigin(btVector3(0,0,1)); +#else + btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); + m_collisionShapes.push_back(chassisShape); + + btCompoundShape* compound = new btCompoundShape(); + m_collisionShapes.push_back(compound); + btTransform localTrans; + localTrans.setIdentity(); + //localTrans effectively shifts the center of mass with respect to the chassis + localTrans.setOrigin(btVector3(0,1,0)); +#endif + + compound->addChildShape(localTrans,chassisShape); + + tr.setOrigin(btVector3(0,0.f,0)); + + m_carChassis = localCreateRigidBody(800,tr,compound);//chassisShape); + //m_carChassis->setDamping(0.2,0.2); + + m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); + + clientResetScene(); + + /// create vehicle + { + + m_vehicleRayCaster = new btDefaultVehicleRaycaster(m_dynamicsWorld); + m_vehicle = new btRaycastVehicle(m_tuning,m_carChassis,m_vehicleRayCaster); + + ///never deactivate the vehicle + m_carChassis->setActivationState(DISABLE_DEACTIVATION); + + m_dynamicsWorld->addVehicle(m_vehicle); + + float connectionHeight = 1.2f; + + + bool isFrontWheel=true; + + //choose coordinate system + m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); + +#ifdef FORCE_ZAXIS_UP + btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); +#else + btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); +#endif + + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); +#ifdef FORCE_ZAXIS_UP + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); +#else + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); +#endif + + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); +#ifdef FORCE_ZAXIS_UP + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); +#else + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); +#endif //FORCE_ZAXIS_UP + isFrontWheel = false; + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); +#ifdef FORCE_ZAXIS_UP + connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); +#else + connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); +#endif + m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); + + for (int i=0;igetNumWheels();i++) + { + btWheelInfo& wheel = m_vehicle->getWheelInfo(i); + wheel.m_suspensionStiffness = suspensionStiffness; + wheel.m_wheelsDampingRelaxation = suspensionDamping; + wheel.m_wheelsDampingCompression = suspensionCompression; + wheel.m_frictionSlip = wheelFriction; + wheel.m_rollInfluence = rollInfluence; + } + } + + + setCameraDistance(26.f); + +} + + +//to be implemented by the demo +void VehicleDemo::renderme() +{ + + updateCamera(); + + btScalar m[16]; + int i; + + + btVector3 wheelColor(1,0,0); + + btVector3 worldBoundsMin,worldBoundsMax; + getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); + + + + for (i=0;igetNumWheels();i++) + { + //synchronize the wheels with the (interpolated) chassis worldtransform + m_vehicle->updateWheelTransform(i,true); + //draw wheels (cylinders) + m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m); + m_shapeDrawer->drawOpenGL(m,m_wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax); + } + + + DemoApplication::renderme(); + +} + +void VehicleDemo::clientMoveAndDisplay() +{ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + { + int wheelIndex = 2; + m_vehicle->applyEngineForce(gEngineForce,wheelIndex); + m_vehicle->setBrake(gBreakingForce,wheelIndex); + wheelIndex = 3; + m_vehicle->applyEngineForce(gEngineForce,wheelIndex); + m_vehicle->setBrake(gBreakingForce,wheelIndex); + + + wheelIndex = 0; + m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex); + wheelIndex = 1; + m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex); + + } + + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_dynamicsWorld) + { + //during idle mode, just run 1 simulation step maximum + int maxSimSubSteps = m_idle ? 1 : 2; + if (m_idle) + dt = 1.0/420.f; + + int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + + +//#define VERBOSE_FEEDBACK +#ifdef VERBOSE_FEEDBACK + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } +#endif //VERBOSE_FEEDBACK + + } + + + + + + + +#ifdef USE_QUICKPROF + btProfiler::beginBlock("render"); +#endif //USE_QUICKPROF + + + renderme(); + + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + +#ifdef USE_QUICKPROF + btProfiler::endBlock("render"); +#endif + + + glFlush(); + glutSwapBuffers(); + +} + + + +void VehicleDemo::displayCallback(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + +//optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + glutSwapBuffers(); +} + + + +void VehicleDemo::clientResetScene() +{ + gVehicleSteering = 0.f; + m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); + m_carChassis->setLinearVelocity(btVector3(0,0,0)); + m_carChassis->setAngularVelocity(btVector3(0,0,0)); + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + if (m_vehicle) + { + m_vehicle->resetSuspension(); + for (int i=0;igetNumWheels();i++) + { + //synchronize the wheels with the (interpolated) chassis worldtransform + m_vehicle->updateWheelTransform(i,true); + } + } + +} + + + +void VehicleDemo::specialKeyboardUp(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP : + { + gEngineForce = 0.f; + break; + } + case GLUT_KEY_DOWN : + { + gBreakingForce = 0.f; + break; + } + default: + DemoApplication::specialKeyboardUp(key,x,y); + break; + } + +} + + +void VehicleDemo::specialKeyboard(int key, int x, int y) +{ + +// printf("key = %i x=%i y=%i\n",key,x,y); + + switch (key) + { + case GLUT_KEY_LEFT : + { + gVehicleSteering += steeringIncrement; + if ( gVehicleSteering > steeringClamp) + gVehicleSteering = steeringClamp; + + break; + } + case GLUT_KEY_RIGHT : + { + gVehicleSteering -= steeringIncrement; + if ( gVehicleSteering < -steeringClamp) + gVehicleSteering = -steeringClamp; + + break; + } + case GLUT_KEY_UP : + { + gEngineForce = maxEngineForce; + gBreakingForce = 0.f; + break; + } + case GLUT_KEY_DOWN : + { + gBreakingForce = maxBreakingForce; + gEngineForce = 0.f; + break; + } + default: + DemoApplication::specialKeyboard(key,x,y); + break; + } + +// glutPostRedisplay(); + + +} + + + +void VehicleDemo::updateCamera() +{ + +//#define DISABLE_CAMERA 1 +#ifdef DISABLE_CAMERA + DemoApplication::updateCamera(); + return; +#endif //DISABLE_CAMERA + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + btTransform chassisWorldTrans; + + //look at the vehicle + m_carChassis->getMotionState()->getWorldTransform(chassisWorldTrans); + m_cameraTargetPosition = chassisWorldTrans.getOrigin(); + + //interpolate the camera height +#ifdef FORCE_ZAXIS_UP + m_cameraPosition[2] = (15.0*m_cameraPosition[2] + m_cameraTargetPosition[2] + m_cameraHeight)/16.0; +#else + m_cameraPosition[1] = (15.0*m_cameraPosition[1] + m_cameraTargetPosition[1] + m_cameraHeight)/16.0; +#endif + + btVector3 camToObject = m_cameraTargetPosition - m_cameraPosition; + + //keep distance between min and max distance + float cameraDistance = camToObject.length(); + float correctionFactor = 0.f; + if (cameraDistance < m_minCameraDistance) + { + correctionFactor = 0.15*(m_minCameraDistance-cameraDistance)/cameraDistance; + } + if (cameraDistance > m_maxCameraDistance) + { + correctionFactor = 0.15*(m_maxCameraDistance-cameraDistance)/cameraDistance; + } + m_cameraPosition -= correctionFactor*camToObject; + + btScalar aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; + glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + gluLookAt(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2], + m_cameraTargetPosition[0],m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + + + +} + diff --git a/Demos/VehicleDemo/VehicleDemo.h b/Demos/VehicleDemo/VehicleDemo.h new file mode 100644 index 0000000..4a05c8f --- /dev/null +++ b/Demos/VehicleDemo/VehicleDemo.h @@ -0,0 +1,91 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef VEHICLE_DEMO_H +#define VEHICLE_DEMO_H + +class btVehicleTuning; +struct btVehicleRaycaster; +class btCollisionShape; + +#include "BulletDynamics/Vehicle/btRaycastVehicle.h" + +#include "GlutDemoApplication.h" + +///VehicleDemo shows how to setup and use the built-in raycast vehicle +class VehicleDemo : public GlutDemoApplication +{ + public: + + btRigidBody* m_carChassis; + + btAlignedObjectArray m_collisionShapes; + + class btBroadphaseInterface* m_overlappingPairCache; + + class btCollisionDispatcher* m_dispatcher; + + class btConstraintSolver* m_constraintSolver; + + class btDefaultCollisionConfiguration* m_collisionConfiguration; + + class btTriangleIndexVertexArray* m_indexVertexArrays; + + btVector3* m_vertices; + + + btRaycastVehicle::btVehicleTuning m_tuning; + btVehicleRaycaster* m_vehicleRayCaster; + btRaycastVehicle* m_vehicle; + btCollisionShape* m_wheelShape; + + float m_cameraHeight; + + float m_minCameraDistance; + float m_maxCameraDistance; + + + VehicleDemo(); + + virtual ~VehicleDemo(); + + virtual void clientMoveAndDisplay(); + + virtual void clientResetScene(); + + virtual void displayCallback(); + + ///a very basic camera following the vehicle + virtual void updateCamera(); + + virtual void specialKeyboard(int key, int x, int y); + + virtual void specialKeyboardUp(int key, int x, int y); + + void renderme(); + + void initPhysics(); + + static DemoApplication* Create() + { + VehicleDemo* demo = new VehicleDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +#endif //VEHICLE_DEMO_H + + diff --git a/Demos/VehicleDemo/main.cpp b/Demos/VehicleDemo/main.cpp new file mode 100644 index 0000000..0bc51c2 --- /dev/null +++ b/Demos/VehicleDemo/main.cpp @@ -0,0 +1,18 @@ + +#include "VehicleDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + VehicleDemo* vehicleDemo = new VehicleDemo; + + vehicleDemo->initPhysics(); + vehicleDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + return glutmain(argc, argv,640,480,"Bullet Vehicle Demo. http://www.continuousphysics.com/Bullet/phpBB2/", vehicleDemo); +} + diff --git a/Demos/VoronoiFractureDemo/CMakeLists.txt b/Demos/VoronoiFractureDemo/CMakeLists.txt new file mode 100644 index 0000000..4789254 --- /dev/null +++ b/Demos/VoronoiFractureDemo/CMakeLists.txt @@ -0,0 +1,87 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL +) + + + +IF (USE_GLUT) + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + +IF (WIN32) +ADD_EXECUTABLE(AppVoronoiFractureDemo + main.cpp + VoronoiFractureDemo.cpp + VoronoiFractureDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ELSE() + ADD_EXECUTABLE(AppVoronoiFractureDemo + main.cpp + VoronoiFractureDemo.cpp + VoronoiFractureDemo.h + ) +ENDIF() + + + + + IF (WIN32) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppVoronoiFractureDemo + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} + ) + ELSE(CMAKE_CL_64) + ADD_CUSTOM_COMMAND( + TARGET AppVoronoiFractureDemo + POST_BUILD +# COMMAND copy /Y ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} + ) + ENDIF(CMAKE_CL_64) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + + ENDIF(WIN32) +ELSE (USE_GLUT) + + + + LINK_LIBRARIES( + OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} + ) + + + ADD_EXECUTABLE(AppVoronoiFractureDemo + WIN32 + ../OpenGL/Win32AppMain.cpp + Win32VoronoiFractureDemo.cpp + VoronoiFractureDemo.cpp + VoronoiFractureDemo.h + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) + + +ENDIF (USE_GLUT) + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppVoronoiFractureDemo PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppVoronoiFractureDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppVoronoiFractureDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Demos/VoronoiFractureDemo/Makefile.am b/Demos/VoronoiFractureDemo/Makefile.am new file mode 100644 index 0000000..a73e4fb --- /dev/null +++ b/Demos/VoronoiFractureDemo/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS=BasicDemo + +BasicDemo_SOURCES=BasicDemo.cpp BasicDemo.h main.cpp +BasicDemo_CXXFLAGS=-I@top_builddir@/src -I@top_builddir@/Demos/OpenGL $(CXXFLAGS) +BasicDemo_LDADD=-L../OpenGL -lbulletopenglsupport -L../../src -lBulletDynamics -lBulletCollision -lLinearMath @opengl_LIBS@ diff --git a/Demos/VoronoiFractureDemo/VoronoiFractureDemo.cpp b/Demos/VoronoiFractureDemo/VoronoiFractureDemo.cpp new file mode 100644 index 0000000..174c795 --- /dev/null +++ b/Demos/VoronoiFractureDemo/VoronoiFractureDemo.cpp @@ -0,0 +1,660 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/* +Voronoi fracture and shatter code and demo copyright (c) 2011 Alain Ducharme + - Reset scene (press spacebar) to generate new random voronoi shattered cuboids + - Check console for total time required to: compute and mesh all 3D shards, calculate volumes and centers of mass and create rigid bodies + - Modify VORONOIPOINTS define below to change number of potential voronoi shards + - Note that demo's visual cracks between voronoi shards are NOT present in the internally generated voronoi mesh! +*/ + +//Number of random voronoi points to generate for shattering +#define VORONOIPOINTS 100 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (2048) +#define BREAKING_THRESHOLD 2 +#define CONVEX_MARGIN 0.04 + +#include "VoronoiFractureDemo.h" +#include "GlutStuff.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" + +#include //printf debugging + +#include "GLDebugDrawer.h" +static GLDebugDrawer sDebugDraw; + +void VoronoiFractureDemo::attachFixedConstraints() +{ + btAlignedObjectArray bodies; + + int numManifolds = getDynamicsWorld()->getDispatcher()->getNumManifolds(); + + for (int i=0;igetDispatcher()->getManifoldByIndexInternal(i); + if (!manifold->getNumContacts()) + continue; + + btScalar minDist = 1e30f; + int minIndex = -1; + for (int v=0;vgetNumContacts();v++) + { + if (minDist >manifold->getContactPoint(v).getDistance()) + { + minDist = manifold->getContactPoint(v).getDistance(); + minIndex = v; + } + } + if (minDist>0.) + continue; + + btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); + btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); + // int tag0 = (colObj0)->getIslandTag(); +// int tag1 = (colObj1)->getIslandTag(); + btRigidBody* body0 = btRigidBody::upcast(colObj0); + btRigidBody* body1 = btRigidBody::upcast(colObj1); + if (bodies.findLinearSearch(body0)==bodies.size()) + bodies.push_back(body0); + if (bodies.findLinearSearch(body1)==bodies.size()) + bodies.push_back(body1); + + if (body0 && body1) + { + if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject()) + { + if (body0->checkCollideWithOverride(body1)) + { + { + btTransform trA,trB; + trA.setIdentity(); + trB.setIdentity(); + btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA; + btTransform globalFrame; + globalFrame.setIdentity(); + globalFrame.setOrigin(contactPosWorld); + + trA = body0->getWorldTransform().inverse()*globalFrame; + trB = body1->getWorldTransform().inverse()*globalFrame; + + btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true); + dof6->setOverrideNumSolverIterations(100); + + float totalMass = 1.f/body0->getInvMass() + 1.f/body1->getInvMass(); + + dof6->setBreakingImpulseThreshold(BREAKING_THRESHOLD*totalMass); + + for (int i=0;i<6;i++) + dof6->setLimit(i,0,0); + getDynamicsWorld()->addConstraint(dof6,true); + + } + } + } + } + + } + + for (int i=0;iremoveRigidBody(bodies[i]); + getDynamicsWorld()->addRigidBody(bodies[i]); + } +} + +void VoronoiFractureDemo::keyboardCallback(unsigned char key, int x, int y) +{ + if (key == 'g') + { + attachFixedConstraints(); + }else + { + PlatformDemoApplication::keyboardCallback(key,x,y); + } +} + + +void VoronoiFractureDemo::getVerticesInsidePlanes(const btAlignedObjectArray& planes, btAlignedObjectArray& verticesOut, std::set& planeIndicesOut) +{ + // Based on btGeometryUtil.cpp (Gino van den Bergen / Erwin Coumans) + verticesOut.resize(0); + planeIndicesOut.clear(); + const int numPlanes = planes.size(); + int i, j, k, l; + for (i=0;i btScalar(0.0001)) + { + for (k=j+1;k btScalar(0.0001)) && (n3n1.length2() > btScalar(0.0001) )) + { + btScalar quotient = (N1.dot(n2n3)); + if (btFabs(quotient) > btScalar(0.0001)) + { + btVector3 potentialVertex = (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * (btScalar(-1.) / quotient); + for (l=0; l btScalar(0.000001)) + break; + } + if (l == numPlanes) + { + // vertex (three plane intersection) inside all planes + verticesOut.push_back(potentialVertex); + planeIndicesOut.insert(i); + planeIndicesOut.insert(j); + planeIndicesOut.insert(k); + } + } + } + } + } + } + } +} + +static btVector3 curVoronoiPoint; + +struct pointCmp +{ + bool operator()(const btVector3& p1, const btVector3& p2) const + { + float v1 = (p1-curVoronoiPoint).length2(); + float v2 = (p2-curVoronoiPoint).length2(); + bool result0 = v1 < v2; + //bool result1 = ((btScalar)(p1-curVoronoiPoint).length2()) < ((btScalar)(p2-curVoronoiPoint).length2()); + //apparently result0 is not always result1, because extended precision used in registered is different from precision when values are stored in memory + return result0; + } +}; + +void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray& points, const btVector3& bbmin, const btVector3& bbmax, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) { + // points define voronoi cells in world space (avoid duplicates) + // bbmin & bbmax = bounding box min and max in local space + // bbq & bbt = bounding box quaternion rotation and translation + // matDensity = Material density for voronoi shard mass calculation + btVector3 bbvx = quatRotate(bbq, btVector3(1.0, 0.0, 0.0)); + btVector3 bbvy = quatRotate(bbq, btVector3(0.0, 1.0, 0.0)); + btVector3 bbvz = quatRotate(bbq, btVector3(0.0, 0.0, 1.0)); + btQuaternion bbiq = bbq.inverse(); + btConvexHullComputer* convexHC = new btConvexHullComputer(); + btAlignedObjectArray vertices; + btVector3 rbb, nrbb; + btScalar nlength, maxDistance, distance; + btAlignedObjectArray sortedVoronoiPoints; + sortedVoronoiPoints.copyFromArray(points); + btVector3 normal, plane; + btAlignedObjectArray planes; + std::set planeIndices; + std::set::iterator planeIndicesIter; + int numplaneIndices; + int cellnum = 0; + int i, j, k; + + int numpoints = points.size(); + for (i=0; i < numpoints ;i++) { + curVoronoiPoint = points[i]; + btVector3 icp = quatRotate(bbiq, curVoronoiPoint - bbt); + rbb = icp - bbmax; + nrbb = bbmin - icp; + planes.resize(6); + planes[0] = bbvx; planes[0][3] = rbb.x(); + planes[1] = bbvy; planes[1][3] = rbb.y(); + planes[2] = bbvz; planes[2][3] = rbb.z(); + planes[3] = -bbvx; planes[3][3] = nrbb.x(); + planes[4] = -bbvy; planes[4][3] = nrbb.y(); + planes[5] = -bbvz; planes[5][3] = nrbb.z(); + maxDistance = SIMD_INFINITY; + sortedVoronoiPoints.heapSort(pointCmp()); + for (j=1; j < numpoints; j++) { + normal = sortedVoronoiPoints[j] - curVoronoiPoint; + nlength = normal.length(); + if (nlength > maxDistance) + break; + plane = normal.normalized(); + plane[3] = -nlength / btScalar(2.); + planes.push_back(plane); + getVerticesInsidePlanes(planes, vertices, planeIndices); + if (vertices.size() == 0) + break; + numplaneIndices = planeIndices.size(); + if (numplaneIndices != planes.size()) { + planeIndicesIter = planeIndices.begin(); + for (k=0; k < numplaneIndices; k++) { + if (k != *planeIndicesIter) + planes[k] = planes[*planeIndicesIter]; + planeIndicesIter++; + } + planes.resize(numplaneIndices); + } + maxDistance = vertices[0].length(); + for (k=1; k < vertices.size(); k++) { + distance = vertices[k].length(); + if (maxDistance < distance) + maxDistance = distance; + } + maxDistance *= btScalar(2.); + } + if (vertices.size() == 0) + continue; + + // Clean-up voronoi convex shard vertices and generate edges & faces + convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(),CONVEX_MARGIN,0.0); + + // At this point we have a complete 3D voronoi shard mesh contained in convexHC + + // Calculate volume and center of mass (Stan Melax volume integration) + int numFaces = convexHC->faces.size(); + int v0, v1, v2; // Triangle vertices + btScalar volume = btScalar(0.); + btVector3 com(0., 0., 0.); + for (j=0; j < numFaces; j++) { + const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]]; + v0 = edge->getSourceVertex(); + v1 = edge->getTargetVertex(); + edge = edge->getNextEdgeOfFace(); + v2 = edge->getTargetVertex(); + while (v2 != v0) { + // Counter-clockwise triangulated voronoi shard mesh faces (v0-v1-v2) and edges here... + btScalar vol = convexHC->vertices[v0].triple(convexHC->vertices[v1], convexHC->vertices[v2]); + volume += vol; + com += vol * (convexHC->vertices[v0] + convexHC->vertices[v1] + convexHC->vertices[v2]); + edge = edge->getNextEdgeOfFace(); + v1 = v2; + v2 = edge->getTargetVertex(); + } + } + com /= volume * btScalar(4.); + volume /= btScalar(6.); + + // Shift all vertices relative to center of mass + int numVerts = convexHC->vertices.size(); + for (j=0; j < numVerts; j++) + { + convexHC->vertices[j] -= com; + } + + // Note: + // At this point convex hulls contained in convexHC should be accurate (line up flush with other pieces, no cracks), + // ...however Bullet Physics rigid bodies demo visualizations appear to produce some visible cracks. + // Use the mesh in convexHC for visual display or to perform boolean operations with. + + // Create Bullet Physics rigid body shards + btCollisionShape* shardShape = new btConvexHullShape(&(convexHC->vertices[0].getX()), convexHC->vertices.size()); + shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this + m_collisionShapes.push_back(shardShape); + btTransform shardTransform; + shardTransform.setIdentity(); + shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location + btDefaultMotionState* shardMotionState = new btDefaultMotionState(shardTransform); + btScalar shardMass(volume * matDensity); + btVector3 shardInertia(0.,0.,0.); + shardShape->calculateLocalInertia(shardMass, shardInertia); + btRigidBody::btRigidBodyConstructionInfo shardRBInfo(shardMass, shardMotionState, shardShape, shardInertia); + btRigidBody* shardBody = new btRigidBody(shardRBInfo); + m_dynamicsWorld->addRigidBody(shardBody); + + cellnum ++; + + } + printf("Generated %d voronoi btRigidBody shards\n", cellnum); +} + +void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArray& points, const btAlignedObjectArray& verts, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) { + // points define voronoi cells in world space (avoid duplicates) + // verts = source (convex hull) mesh vertices in local space + // bbq & bbt = source (convex hull) mesh quaternion rotation and translation + // matDensity = Material density for voronoi shard mass calculation + btConvexHullComputer* convexHC = new btConvexHullComputer(); + btAlignedObjectArray vertices, chverts; + btVector3 rbb, nrbb; + btScalar nlength, maxDistance, distance; + btAlignedObjectArray sortedVoronoiPoints; + sortedVoronoiPoints.copyFromArray(points); + btVector3 normal, plane; + btAlignedObjectArray planes, convexPlanes; + std::set planeIndices; + std::set::iterator planeIndicesIter; + int numplaneIndices; + int cellnum = 0; + int i, j, k; + + // Convert verts to world space and get convexPlanes + int numverts = verts.size(); + chverts.resize(verts.size()); + for (i=0; i < numverts ;i++) { + chverts[i] = quatRotate(bbq, verts[i]) + bbt; + } + //btGeometryUtil::getPlaneEquationsFromVertices(chverts, convexPlanes); + // Using convexHullComputer faster than getPlaneEquationsFromVertices for large meshes... + convexHC->compute(&chverts[0].getX(), sizeof(btVector3), numverts, 0.0, 0.0); + int numFaces = convexHC->faces.size(); + int v0, v1, v2; // vertices + for (i=0; i < numFaces; i++) { + const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[i]]; + v0 = edge->getSourceVertex(); + v1 = edge->getTargetVertex(); + edge = edge->getNextEdgeOfFace(); + v2 = edge->getTargetVertex(); + plane = (convexHC->vertices[v1]-convexHC->vertices[v0]).cross(convexHC->vertices[v2]-convexHC->vertices[v0]).normalize(); + plane[3] = -plane.dot(convexHC->vertices[v0]); + convexPlanes.push_back(plane); + } + const int numconvexPlanes = convexPlanes.size(); + + int numpoints = points.size(); + for (i=0; i < numpoints ;i++) { + curVoronoiPoint = points[i]; + planes.copyFromArray(convexPlanes); + for (j=0; j < numconvexPlanes ;j++) { + planes[j][3] += planes[j].dot(curVoronoiPoint); + } + maxDistance = SIMD_INFINITY; + sortedVoronoiPoints.heapSort(pointCmp()); + for (j=1; j < numpoints; j++) { + normal = sortedVoronoiPoints[j] - curVoronoiPoint; + nlength = normal.length(); + if (nlength > maxDistance) + break; + plane = normal.normalized(); + plane[3] = -nlength / btScalar(2.); + planes.push_back(plane); + getVerticesInsidePlanes(planes, vertices, planeIndices); + if (vertices.size() == 0) + break; + numplaneIndices = planeIndices.size(); + if (numplaneIndices != planes.size()) { + planeIndicesIter = planeIndices.begin(); + for (k=0; k < numplaneIndices; k++) { + if (k != *planeIndicesIter) + planes[k] = planes[*planeIndicesIter]; + planeIndicesIter++; + } + planes.resize(numplaneIndices); + } + maxDistance = vertices[0].length(); + for (k=1; k < vertices.size(); k++) { + distance = vertices[k].length(); + if (maxDistance < distance) + maxDistance = distance; + } + maxDistance *= btScalar(2.); + } + if (vertices.size() == 0) + continue; + + // Clean-up voronoi convex shard vertices and generate edges & faces + convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(),0.0,0.0); + + // At this point we have a complete 3D voronoi shard mesh contained in convexHC + + // Calculate volume and center of mass (Stan Melax volume integration) + numFaces = convexHC->faces.size(); + btScalar volume = btScalar(0.); + btVector3 com(0., 0., 0.); + for (j=0; j < numFaces; j++) { + const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]]; + v0 = edge->getSourceVertex(); + v1 = edge->getTargetVertex(); + edge = edge->getNextEdgeOfFace(); + v2 = edge->getTargetVertex(); + while (v2 != v0) { + // Counter-clockwise triangulated voronoi shard mesh faces (v0-v1-v2) and edges here... + btScalar vol = convexHC->vertices[v0].triple(convexHC->vertices[v1], convexHC->vertices[v2]); + volume += vol; + com += vol * (convexHC->vertices[v0] + convexHC->vertices[v1] + convexHC->vertices[v2]); + edge = edge->getNextEdgeOfFace(); + v1 = v2; + v2 = edge->getTargetVertex(); + } + } + com /= volume * btScalar(4.); + volume /= btScalar(6.); + + // Shift all vertices relative to center of mass + int numVerts = convexHC->vertices.size(); + for (j=0; j < numVerts; j++) + { + convexHC->vertices[j] -= com; + } + + // Note: + // At this point convex hulls contained in convexHC should be accurate (line up flush with other pieces, no cracks), + // ...however Bullet Physics rigid bodies demo visualizations appear to produce some visible cracks. + // Use the mesh in convexHC for visual display or to perform boolean operations with. + + // Create Bullet Physics rigid body shards + btCollisionShape* shardShape = new btConvexHullShape(&(convexHC->vertices[0].getX()), convexHC->vertices.size()); + shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this + m_collisionShapes.push_back(shardShape); + btTransform shardTransform; + shardTransform.setIdentity(); + shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location + btDefaultMotionState* shardMotionState = new btDefaultMotionState(shardTransform); + btScalar shardMass(volume * matDensity); + btVector3 shardInertia(0.,0.,0.); + shardShape->calculateLocalInertia(shardMass, shardInertia); + btRigidBody::btRigidBodyConstructionInfo shardRBInfo(shardMass, shardMotionState, shardShape, shardInertia); + btRigidBody* shardBody = new btRigidBody(shardRBInfo); + m_dynamicsWorld->addRigidBody(shardBody); + + cellnum ++; + + } + printf("Generated %d voronoi btRigidBody shards\n", cellnum); +} + +void VoronoiFractureDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(ms / 1000000.f); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } + + renderme(); + + glFlush(); + + swapBuffers(); +} + + +void VoronoiFractureDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + //optional but useful: debug drawing to detect problems + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); + swapBuffers(); +} + + +void VoronoiFractureDemo::initPhysics() +{ + setTexturing(true); + setShadows(true); + + setCameraDistance(btScalar(20.)); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; + m_dynamicsWorld->setDebugDrawer(&sDebugDraw); + + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + ///create a few basic rigid bodies + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); +// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + { + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + // ==> Voronoi Shatter Basic Demo: Random Cuboid + + // Random size cuboid (defined by bounding box max and min) + btVector3 bbmax(btScalar(rand() / btScalar(RAND_MAX)) * 6. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 6. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 6. +0.5); + btVector3 bbmin = -bbmax; + // Place it 10 units above ground + btVector3 bbt(0,10,0); + // Use an arbitrary material density for shards (should be consitent/relative with/to rest of RBs in world) + btScalar matDensity = 1; + // Using random rotation + btQuaternion bbq(btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.); + bbq.normalize(); + // Generate random points for voronoi cells + btAlignedObjectArray points; + btVector3 point; + btVector3 diff = bbmax - bbmin; + for (int i=0; i < VORONOIPOINTS; i++) { + // Place points within box area (points are in world coordinates) + point = quatRotate(bbq, btVector3(btScalar(rand() / btScalar(RAND_MAX)) * diff.x() -diff.x()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.y() -diff.y()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.z() -diff.z()/2.)) + bbt; + points.push_back(point); + } + m_perfmTimer.reset(); + voronoiBBShatter(points, bbmin, bbmax, bbq, bbt, matDensity); + printf("Total Time: %f seconds\n", m_perfmTimer.getTimeMilliseconds()/1000.); + + for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + obj->getCollisionShape()->setMargin(CONVEX_MARGIN+0.01); + } + m_dynamicsWorld->performDiscreteCollisionDetection(); + + for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + obj->getCollisionShape()->setMargin(CONVEX_MARGIN); + } + + attachFixedConstraints(); + +} +void VoronoiFractureDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} + + +void VoronoiFractureDemo::exitPhysics() +{ + + //cleanup in the reverse order of creation/initialization + + int i; + //remove all constraints + for (i=m_dynamicsWorld->getNumConstraints()-1;i>=0;i--) + { + btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); + m_dynamicsWorld->removeConstraint(constraint); + delete constraint; + } + + //remove the rigidbodies from the dynamics world and delete them + + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j +#include + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; + +///VoronoiFractureDemo is good starting point for learning the code base and porting. + +class VoronoiFractureDemo : public PlatformDemoApplication +{ + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + btClock m_perfmTimer; + + public: + + VoronoiFractureDemo() + { + srand((unsigned)time(NULL)); // Seed it... + } + virtual ~VoronoiFractureDemo() + { + exitPhysics(); + } + void initPhysics(); + + void exitPhysics(); + + void getVerticesInsidePlanes(const btAlignedObjectArray& planes, btAlignedObjectArray& verticesOut, std::set& planeIndicesOut); + void voronoiBBShatter(const btAlignedObjectArray& points, const btVector3& bbmin, const btVector3& bbmax, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity); + void voronoiConvexHullShatter(const btAlignedObjectArray& points, const btAlignedObjectArray& verts, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + virtual void clientResetScene(); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + void attachFixedConstraints(); + + + static DemoApplication* Create() + { + VoronoiFractureDemo* demo = new VoronoiFractureDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + + +}; + +#endif //BASIC_DEMO_H + diff --git a/Demos/VoronoiFractureDemo/Win32VoronoiFractureDemo.cpp b/Demos/VoronoiFractureDemo/Win32VoronoiFractureDemo.cpp new file mode 100644 index 0000000..a55fb67 --- /dev/null +++ b/Demos/VoronoiFractureDemo/Win32VoronoiFractureDemo.cpp @@ -0,0 +1,25 @@ +#ifdef _WINDOWS +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BasicDemo.h" + +///The 'createDemo' function is called from Bullet/Demos/OpenGL/Win32AppMain.cpp to instantiate this particular demo +DemoApplication* createDemo() +{ + return new BasicDemo(); +} + +#endif diff --git a/Demos/VoronoiFractureDemo/main.cpp b/Demos/VoronoiFractureDemo/main.cpp new file mode 100644 index 0000000..e391128 --- /dev/null +++ b/Demos/VoronoiFractureDemo/main.cpp @@ -0,0 +1,51 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "VoronoiFractureDemo.h" +#include "GlutStuff.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btHashMap.h" + + + +static bool cmp(const int& p1, const int& p2) { + return p1 bla; + + bla.push_back(8); + bla.push_back(6); + bla.push_back(6); + bla.push_back(4); + bla.push_back(9); + bla.quickSort(cmp); + + VoronoiFractureDemo ccdDemo; + ccdDemo.initPhysics(); + +#ifdef CHECK_MEMORY_LEAKS + ccdDemo.exitPhysics(); +#else + return glutmain(argc, argv,1024,600,"Bullet Physics Demo. http://bulletphysics.org",&ccdDemo); +#endif + + //default glut doesn't return from mainloop + return 0; +} + diff --git a/Demos/premake4.lua b/Demos/premake4.lua new file mode 100644 index 0000000..afa6766 --- /dev/null +++ b/Demos/premake4.lua @@ -0,0 +1,100 @@ + + + +function createDemos( demos, incdirs, linknames) + for _, name in ipairs(demos) do + + project ( "App_" .. name ) + + kind "ConsoleApp" + targetdir ".." + + includedirs {incdirs} + + configuration { "Windows" } + defines { "GLEW_STATIC"} + links { "opengl32" } + includedirs{ "../Glut" } + libdirs {"../Glut"} + files { "../build/bullet.rc" } + + configuration {"Windows", "x32"} + links {"glew32s","glut32"} + configuration {"Windows", "x64"} + links {"glew64s", "glut64"} + + configuration {"MacOSX"} + --print "hello" + linkoptions { "-framework Carbon -framework OpenGL -framework AGL -framework Glut" } + + configuration {"not Windows", "not MacOSX"} + links {"GL","GLU","glut"} + configuration{} + + links { + linknames + } + + files { + "./" .. name .. "/*.cpp" , + "./" .. name .. "/*.h" + } + end +end + +-- "CharacterDemo", fixme: it includes BspDemo files + + local localdemos = { + "BasicDemo", + "Box2dDemo", + "BspDemo", + "CcdPhysicsDemo", + "CollisionDemo", + "CollisionInterfaceDemo", + "ConcaveConvexcastDemo", + "ConcaveDemo", + "ConcaveRaycastDemo", + "ConstraintDemo", + "ContinuousConvexCollision", + "ConvexHullDistance", + "DynamicControlDemo", + "EPAPenDepthDemo", + "ForkLiftDemo", + "FractureDemo", + "GenericJointDemo", + "GimpactTestDemo", + "GjkConvexCastDemo", + "GyroscopicDemo", + "InternalEdgeDemo", + "MovingConcaveDemo", + "MultiMaterialDemo", + "RagdollDemo", + "Raytracer", + "RaytestDemo", + "RollingFrictionDemo", + "SimplexDemo", + "SliderConstraintDemo", + "TerrainDemo", + "UserCollisionAlgorithm", + "VehicleDemo", + "VoronoiFractureDemo" + } + +-- the following demos require custom include or link settings + + createDemos({"HelloWorld"},{"../src"},{"BulletDynamics","BulletCollision","LinearMath"}) + + createDemos(localdemos,{"../src","OpenGL"},{"OpenGLSupport","BulletDynamics", "BulletCollision", "LinearMath"}) + + createDemos({"ConvexDecompositionDemo"},{"../Extras/HACD","../Extras/ConvexDecomposition","../src","OpenGL"},{"OpenGLSupport","BulletDynamics", "BulletCollision", "LinearMath","HACD","ConvexDecomposition"}) + + createDemos({"SoftDemo"},{"../src","OpenGL"}, {"OpenGLSupport","BulletSoftBody", "BulletDynamics", "BulletCollision", "LinearMath"}) + + createDemos({"SerializeDemo"},{"../Extras/Serialize/BulletFileLoader","../Extras/Serialize/BulletWorldImporter","../src","OpenGL"},{"OpenGLSupport","BulletWorldImporter", "BulletFileLoader", "BulletSoftBody", "BulletDynamics", "BulletCollision", "LinearMath"}) + +createDemos({"BulletXmlImportDemo"},{"../Extras/Serialize/BulletFileLoader","../Extras/Serialize/BulletXmlWorldImporter", "../Extras/Serialize/BulletWorldImporter","../src","OpenGL"},{"OpenGLSupport","BulletXmlWorldImporter","BulletWorldImporter", "BulletFileLoader", "BulletSoftBody", "BulletDynamics", "BulletCollision", "LinearMath"}) + + +include "OpenGL" + + diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..d483fe4 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,780 @@ +# Doxyfile 1.2.4 + +# This file describes the settings to be used by doxygen for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + + + + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. +PROJECT_NAME = "Bullet Collision Detection & Physics Library" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, +# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian, +# Polish, Portuguese and Slovene. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a class diagram (in Html and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. + +CLASS_DIAGRAMS = YES + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The ENABLE_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +FILE_PATTERNS = *.h *.cpp *.c + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = YES + +# HHC_LOCATION = "C:\Program Files\HTML Help Workshop\hhc.exe" +HHC_LOCATION = "C:\Program Files (x86)\HTML Help Workshop\hhc.exe" + + +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +#HTML_STYLESHEET = "\\server\exchange\Software Development\Documentation\DoxyGen\doxygen.css" + +CHM_FILE = BulletDocs.chm +HHC_LOCATION = "c:\program files\HTML Help Workshop\hhc.exe" +GENERATE_CHI = YES +BINARY_TOC = YES + +TOC_EXPAND = YES + +SHOW_DIRECTORIES = YES + + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 1 + +# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Netscape 4.0+ +# or Internet explorer 4.0+). + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using a WORD or other. +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Warning: This feature +# is still experimental and very incomplete. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = src + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = "ATTRIBUTE_ALIGNED128(x)=x" \ + "ATTRIBUTE_ALIGNED16(x)=x" \ + "SIMD_FORCE_INLINE=inline" \ + "VECTORMATH_FORCE_INLINE=inline" \ + "USE_WIN32_THREADING=1"\ + "USE_PTHREADS=1"\ + "_WIN32=1" + + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other +# documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented header file showing +# the documented files that directly or indirectly include this file + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + + +# delete intermediate dot files? + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = c:\program files\doxygen\bin + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/Extras/AllBulletDemosOSX/AllBulletDemos.xcodeproj/TemplateIcon.icns b/Extras/AllBulletDemosOSX/AllBulletDemos.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..62cb7015e09d6ea3e65d7f7949c4c07f9246a908 GIT binary patch literal 52318 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 WhsmLR^b3` + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + AIODescriptionKey + DockingSystemVisible + + Extension + perspectivev3 + FavBarConfig + + PBXProjectModuleGUID + 36C69D140DC9E7C30034504A + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.defaultV3 + MajorVersion + 34 + MinorVersion + 0 + Name + All-In-One + Notifications + + + XCObserverAutoDisconnectKey + + XCObserverDefintionKey + + PBXStatusErrorsKey + 0 + + XCObserverFactoryKey + XCPerspectivesSpecificationIdentifier + XCObserverGUIDKey + XCObserverProjectIdentifier + XCObserverNotificationKey + PBXStatusBuildStateMessageNotification + XCObserverTargetKey + XCMainBuildResultsModuleGUID + XCObserverTriggerKey + awakenModuleWithObserver: + XCObserverValidationKey + + PBXStatusErrorsKey + 2 + + + + XCObserverAutoDisconnectKey + + XCObserverDefintionKey + + PBXStatusWarningsKey + 0 + + XCObserverFactoryKey + XCPerspectivesSpecificationIdentifier + XCObserverGUIDKey + XCObserverProjectIdentifier + XCObserverNotificationKey + PBXStatusBuildStateMessageNotification + XCObserverTargetKey + XCMainBuildResultsModuleGUID + XCObserverTriggerKey + awakenModuleWithObserver: + XCObserverValidationKey + + PBXStatusWarningsKey + 2 + + + + OpenEditors + + PerspectiveWidths + + 1440 + 1440 + + Perspectives + + + ChosenToolbarItems + + XCToolbarPerspectiveControl + NSToolbarSeparatorItem + active-target-popup + active-executable-popup + active-buildstyle-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-goOrGo + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + researchAssistant + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CA23ED40692098700951B8B + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 352 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 36A05D5A0DCBAD9000ADF289 + 36C69D250DC9E7FE0034504A + 36A05DC60DCBBAC000ADF289 + 29B97317FDCFA39411CA2CEA + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 20 + 18 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {352, 780}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {369, 798}} + GroupTreeTableConfiguration + + MainColumn + 352 + + RubberWindowFrame + 0 39 1440 839 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 369pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 36C69D0F0DC9E7C30034504A + PBXProjectModuleLabel + + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 36C69D100DC9E7C30034504A + PBXProjectModuleLabel + + + SplitCount + 1 + + StatusBarVisibility + + XCSharingToken + com.apple.Xcode.CommonNavigatorGroupSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {1066, 555}} + RubberWindowFrame + 0 39 1440 839 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 555pt + + + Proportion + 238pt + Tabs + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA23EDF0692099D00951B8B + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{10, 27}, {1066, 211}} + RubberWindowFrame + 0 39 1440 839 0 0 1440 878 + + Module + XCDetailModule + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA23EE00692099D00951B8B + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{10, 27}, {1066, -27}} + + Module + PBXProjectFindModule + + + ContentConfiguration + + PBXCVSModuleFilterTypeKey + 1032 + PBXProjectModuleGUID + 1CA23EE10692099D00951B8B + PBXProjectModuleLabel + SCM Results + + GeometryConfiguration + + Frame + {{10, 31}, {603, 297}} + + Module + PBXCVSModule + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1013 + + GeometryConfiguration + + Frame + {{10, 27}, {1066, 211}} + + Module + PBXBuildResultsModule + + + + + Proportion + 1066pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDockableTabModule + XCDetailModule + PBXProjectFindModule + PBXCVSModule + PBXBuildResultsModule + + TableOfContents + + 3699D2370DCF89C9001D9494 + 1CA23ED40692098700951B8B + 3699D2380DCF89C9001D9494 + 36C69D0F0DC9E7C30034504A + 3699D2390DCF89C9001D9494 + 1CA23EDF0692099D00951B8B + 1CA23EE00692099D00951B8B + 1CA23EE10692099D00951B8B + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ChosenToolbarItems + + XCToolbarPerspectiveControl + NSToolbarSeparatorItem + build-and-go + go + NSToolbarFlexibleSpaceItem + debugger-fix-and-continue + debugger-restart-executable + debugger-pause + debugger-step-over + debugger-step-into + debugger-step-out + debugger-step-instruction + NSToolbarFlexibleSpaceItem + + ControllerClassBaseName + PBXDebugSessionModule + IconName + DebugTabIcon + Identifier + perspective.debug + IsVertical + + Layout + + + ContentConfiguration + + PBXProjectModuleGUID + 1CCC7628064C1048000F2A68 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {1440, 238}} + + Module + PBXDebugCLIModule + Proportion + 238pt + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {703, 268}} + {{703, 0}, {737, 268}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {1440, 268}} + {{0, 268}, {1440, 287}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1CCC7629064C1048000F2A68 + PBXProjectModuleLabel + Debug + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 243}, {1440, 555}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 507 + + Frame + {{703, 0}, {737, 268}} + + + Module + PBXDebugSessionModule + Proportion + 555pt + + + Name + Debug + ServiceClasses + + XCModuleDock + PBXDebugCLIModule + PBXDebugSessionModule + PBXDebugProcessAndThreadModule + PBXDebugProcessViewModule + PBXDebugThreadViewModule + PBXDebugStackFrameViewModule + PBXNavigatorGroup + + TableOfContents + + 3699D2080DCF68BE001D9494 + 1CCC7628064C1048000F2A68 + 1CCC7629064C1048000F2A68 + 3699D2090DCF68BE001D9494 + 3699D20A0DCF68BE001D9494 + 3699D20B0DCF68BE001D9494 + 3699D20C0DCF68BE001D9494 + 36C69D0F0DC9E7C30034504A + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecification.xcperspec' + StatusbarIsVisible + + TimeStamp + 231705097.779064 + ToolbarDisplayMode + 2 + ToolbarIsVisible + + ToolbarSizeMode + 2 + Type + Perspectives + UpdateMessage + + WindowJustification + 5 + WindowOrderList + + /Users/zakariya/Code/vendor/bullet-2.68/Extras/AllBulletDemosOSX/AllBulletDemos.xcodeproj + + WindowString + 0 39 1440 839 0 0 1440 878 + WindowToolsV3 + + + Identifier + windowTool.debugger + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {317, 164}} + {{317, 0}, {377, 164}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 164}} + {{0, 164}, {694, 216}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 380}} + RubberWindowFrame + 321 238 694 422 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 100% + + + Proportion + 100% + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CD10A99069EF8BA00B06720 + 1C0AD2AB069F1E9B00FABCE6 + 1C162984064C10D400B95A72 + 1C0AD2AC069F1E9B00FABCE6 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 321 238 694 422 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + 0 + + + Identifier + windowTool.build + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD052900623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {500, 215}} + RubberWindowFrame + 192 257 500 500 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + + GeometryConfiguration + + Frame + {{0, 222}, {500, 236}} + RubberWindowFrame + 192 257 500 500 0 0 1280 1002 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 458pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAA5065D492600B07095 + 1C78EAA6065D492600B07095 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowString + 192 257 500 500 0 0 1280 1002 + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.debuggerConsole + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {700, 358}} + RubberWindowFrame + 149 87 700 400 0 0 1440 878 + + Module + PBXDebugCLIModule + Proportion + 358pt + + + Proportion + 358pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D5B069F1CE1000CFCEE + 1C530D5C069F1CE1000CFCEE + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 149 87 440 400 0 0 1440 878 + WindowToolGUID + 1C530D5B069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scmV3 + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 166pt + + + Proportion + 166pt + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {369, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {616, 353}} + MembersFrame + {{0, 105}, {369, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 94 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 597 125 616 374 0 0 1280 1002 + + Module + PBXClassBrowserModule + Proportion + 354pt + + + Proportion + 354pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C78EABA065D492600B07095 + 1C78EABB065D492600B07095 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 597 125 616 374 0 0 1280 1002 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/Extras/AllBulletDemosOSX/AllBulletDemos_Prefix.pch b/Extras/AllBulletDemosOSX/AllBulletDemos_Prefix.pch new file mode 100644 index 0000000..f1d2c11 --- /dev/null +++ b/Extras/AllBulletDemosOSX/AllBulletDemos_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'AllBulletDemos' target in the 'AllBulletDemos' project +// + +#ifdef __OBJC__ + #import +#endif diff --git a/Extras/AllBulletDemosOSX/BulletIcon.icns b/Extras/AllBulletDemosOSX/BulletIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..1429602ce60360b8a4f8238c60b7fbc08505dd12 GIT binary patch literal 28472 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 A(*OVf literal 0 HcmV?d00001 diff --git a/Extras/AllBulletDemosOSX/BulletIcon.psd b/Extras/AllBulletDemosOSX/BulletIcon.psd new file mode 100644 index 0000000000000000000000000000000000000000..c0b4a99c98e71bf4d1248a33d32738024e8fa106 GIT binary patch literal 101941 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 a!Y*1dX%G66ZqL#C$|bw0ZoP5@jOGW1ArT7z literal 0 HcmV?d00001 diff --git a/Extras/AllBulletDemosOSX/English.lproj/MainMenu.xib b/Extras/AllBulletDemosOSX/English.lproj/MainMenu.xib new file mode 100644 index 0000000..6a63aae --- /dev/null +++ b/Extras/AllBulletDemosOSX/English.lproj/MainMenu.xib @@ -0,0 +1,2157 @@ + + + + 1040 + 9E17 + 670 + 949.33 + 352.00 + + YES + + + + + YES + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + YES + + + AllBulletDemos + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + AllBulletDemos + + YES + + + About AllBulletDemos + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + UHJlZmVyZW5jZXPigKY + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + YES + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide AllBulletDemos + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit AllBulletDemos + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 2147483647 + + + submenuAction: + + File + + YES + + + Reset Current Demo + r + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + YES + + + Previous Demo + [ + 1048576 + 2147483647 + + + + + + Next Demo + ] + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Fullscreen + F + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + YES + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Show Paramaters + P + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + _NSMainMenu + + + 15 + 2 + {{500, 363}, {593, 360}} + 1954021376 + All Bullet Demos + NSWindow + + {3.40282e+38, 3.40282e+38} + {593, 360} + + + 256 + + YES + + + 274 + {593, 320} + + BTOpenGLView + + + + 268 + {{17, 328}, {210, 22}} + + YES + + -2076049856 + 133120 + + LucidaGrande + 1.100000e+01 + 3100 + + + 109199615 + 129 + + + 400 + 75 + + + Item 1 + + 1048576 + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + Item 2 + + 1048576 + 2147483647 + + + _popUpItemAction: + + + + + Item 3 + + 1048576 + 2147483647 + + + _popUpItemAction: + + + + + 1 + YES + YES + 2 + + + + + 265 + {{489, 331}, {86, 18}} + + YES + + 67239424 + 131072 + Fullscreen + + + 1211912703 + 130 + + NSImage + NSSwitch + + + NSSwitch + + + + 200 + 25 + + + + + 265 + {{393, 331}, {93, 18}} + + YES + + 67239424 + 131072 + Parameters + + + 1211912703 + 130 + + + + + 200 + 25 + + + + + 268 + {{227, 325}, {96, 28}} + + YES + + 67239424 + 134348800 + Reset + + + -2038284033 + 129 + + + 200 + 25 + + + + {593, 360} + + {{0, 0}, {1440, 878}} + {593, 382} + {3.40282e+38, 3.40282e+38} + _main_window_ + + + NSFontManager + + + BTDemosAppController + + + 19 + 2 + {{196, 291}, {276, 219}} + -469762048 + Parameters + NSPanel + + {276, 219} + {276, 219} + + + 256 + + YES + + + 268 + {{17, 177}, {64, 17}} + + YES + + 68288064 + 272630784 + Iterations + + LucidaGrande + 1.300000e+01 + 1044 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2OQA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 268 + {{86, 174}, {121, 22}} + + YES + + -1804468671 + -1874852864 + + + + + YES + + YES + allowsFloats + formatterBehavior + minimum + + + YES + + + + + + # + # + + + + + + + + + + NaN + + YES + + YES + + + YES + + + + + + 0 + 0 + YES + NO + 1 + AAAAAAAAAAAAAAAAAAAAAA + + + 3 + YES + YES + YES + + . + , + NO + YES + YES + + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + + + + + + 268 + {{84, 140}, {149, 18}} + + YES + + -2080244224 + 0 + Disable deactivation + + + 1211912703 + 130 + + + + + 200 + 25 + + + + + 12 + {{12, 106}, {252, 5}} + + {0, 0} + + 67239424 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxAA + + + 3 + 2 + 0 + NO + + + + 268 + {{212, 171}, {19, 27}} + + YES + + 917024 + 0 + + 1.000000e+02 + 1.000000e+00 + YES + + + + + 268 + {{9, 84}, {69, 17}} + + YES + + 68288064 + 272630784 + Rendering + + + + + + + + + 268 + {{84, 59}, {63, 18}} + + YES + + -2080244224 + 0 + AABBs + + + 1211912703 + 130 + + + + + 200 + 25 + + + + + 268 + {{84, 39}, {113, 18}} + + YES + + -2080244224 + 0 + Wireframe + + + 1211912703 + 130 + + + + + 200 + 25 + + + + + 268 + {{84, 19}, {113, 18}} + + YES + + -2080244224 + 0 + Contacts + + + 1211912703 + 130 + + + + + 200 + 25 + + + + + 268 + {{84, 115}, {149, 18}} + + YES + + -2080244224 + 0 + Enable Split Impulse + + + 1211912703 + 130 + + + + + 200 + 25 + + + + {276, 219} + + + {{0, 0}, {1440, 878}} + {276, 235} + {276, 235} + _parameters_window_ + + + BTSimulationParameters + + + YES + + + + + YES + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + performZoom: + + + + 240 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + terminate: + + + + 369 + + + + unhideAllApplications: + + + + 370 + + + + _glView + + + + 451 + + + + delegate + + + + 453 + + + + content: demos + + + + + + content: demos + content + demos + 2 + + + 489 + + + + selectedValue: demo + + + + + + selectedValue: demo + selectedValue + demo + + 2 + + + 490 + + + + value: fullscreen + + + + + + value: fullscreen + value + fullscreen + 2 + + + 493 + + + + nextDemo: + + + + 498 + + + + previousDemo: + + + + 499 + + + + _parameters + + + + 526 + + + + value: iterations + + + + + + value: iterations + value + iterations + 2 + + + 527 + + + + maxValue: maxIterations + + + + + + maxValue: maxIterations + maxValue + maxIterations + 2 + + + 531 + + + + minValue: minIterations + + + + + + minValue: minIterations + minValue + minIterations + + 2 + + + 532 + + + + value: iterations + + + + + + value: iterations + value + iterations + + 2 + + + 533 + + + + value: disableDeactivation + + + + + + value: disableDeactivation + value + disableDeactivation + 2 + + + 534 + + + + value: drawAABBs + + + + + + value: drawAABBs + value + drawAABBs + 2 + + + 535 + + + + value: debugDraw + + + + + + value: debugDraw + value + debugDraw + 2 + + + 537 + + + + visible: showParameters + + + + + + visible: showParameters + visible + showParameters + 2 + + + 540 + + + + value: showParameters + + + + + + value: showParameters + value + showParameters + 2 + + + 543 + + + + performClose: + + + + 559 + + + + value: showParameters + + + + + + value: showParameters + value + showParameters + 2 + + + 564 + + + + value: fullscreen + + + + + + value: fullscreen + value + fullscreen + 2 + + + 567 + + + + resetDemo: + + + + 570 + + + + resetDemo: + + + + 573 + + + + value: drawContacts + + + + + + value: drawContacts + value + drawContacts + 2 + + + 576 + + + + nullMenuTarget: + + + + 579 + + + + nullMenuTarget: + + + + 580 + + + + value: splitImpulse + + + + + + value: splitImpulse + value + splitImpulse + 2 + + + 589 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + YES + + + + + + + MainMenu + + + 19 + + + YES + + + + + + 56 + + + YES + + + + + + 57 + + + YES + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + 1111 + + + 144 + + + + + 129 + + + 121 + + + 143 + + + + + 236 + + + + + 131 + + + YES + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + YES + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + YES + + + + + + 296 + + + YES + + + + + + + + + 371 + + + YES + + + + + + 372 + + + YES + + + + + + + + + + 420 + + + + + 449 + + + + + 450 + + + + + 483 + + + YES + + + + + + 484 + + + YES + + + + + + 485 + + + YES + + + + + + + + 486 + + + + + 487 + + + + + 488 + + + + + 491 + + + YES + + + + + + 492 + + + + + 496 + + + + + 497 + + + + + 501 + + + + + 503 + + + YES + + + + + + 504 + + + YES + + + + + + + + + + + + + + + 507 + + + YES + + + + + + 508 + + + + + 509 + + + YES + + + + + + 510 + + + YES + + + + + + 511 + + + + + 512 + + + YES + + + + + + 513 + + + + + 514 + + + + + 515 + + + YES + + + + + + 516 + + + + + 517 + + + YES + + + + + + 518 + + + + + 519 + + + YES + + + + + + 520 + + + + + 521 + + + YES + + + + + + 522 + + + + + 523 + + + YES + + + + + + 524 + + + + + 525 + + + + + 538 + + + + + 541 + + + YES + + + + + + 542 + + + + + 544 + + + YES + + + + + + 545 + + + YES + + + + + + + + 550 + + + + + 560 + + + + + 561 + + + + + 562 + + + + + 568 + + + + + 569 + + + + + 571 + + + YES + + + + + + 572 + + + + + 581 + + + YES + + + + + + 582 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 129.IBPluginDependency + 129.ImportedFromIB2 + 130.IBPluginDependency + 130.ImportedFromIB2 + 130.editorWindowContentRectSynchronizationRect + 131.IBPluginDependency + 131.ImportedFromIB2 + 134.IBPluginDependency + 134.ImportedFromIB2 + 136.IBPluginDependency + 136.ImportedFromIB2 + 143.IBPluginDependency + 143.ImportedFromIB2 + 144.IBPluginDependency + 144.ImportedFromIB2 + 145.IBPluginDependency + 145.ImportedFromIB2 + 149.IBPluginDependency + 149.ImportedFromIB2 + 150.IBPluginDependency + 150.ImportedFromIB2 + 19.IBPluginDependency + 19.ImportedFromIB2 + 23.IBPluginDependency + 23.ImportedFromIB2 + 236.IBPluginDependency + 236.ImportedFromIB2 + 239.IBPluginDependency + 239.ImportedFromIB2 + 24.IBEditorWindowLastContentRect + 24.IBPluginDependency + 24.ImportedFromIB2 + 24.editorWindowContentRectSynchronizationRect + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 29.ImportedFromIB2 + 29.WindowOrigin + 29.editorWindowContentRectSynchronizationRect + 295.IBPluginDependency + 296.IBEditorWindowLastContentRect + 296.IBPluginDependency + 296.editorWindowContentRectSynchronizationRect + 371.IBEditorWindowLastContentRect + 371.IBPluginDependency + 371.IBWindowTemplateEditedContentRect + 371.NSWindowTemplate.visibleAtLaunch + 371.editorWindowContentRectSynchronizationRect + 371.windowTemplate.hasMinSize + 371.windowTemplate.maxSize + 371.windowTemplate.minSize + 372.IBPluginDependency + 449.IBPluginDependency + 450.IBPluginDependency + 483.IBPluginDependency + 484.IBPluginDependency + 485.IBPluginDependency + 486.IBPluginDependency + 487.IBPluginDependency + 488.IBPluginDependency + 491.IBPluginDependency + 492.IBPluginDependency + 496.IBPluginDependency + 497.IBPluginDependency + 5.IBPluginDependency + 5.ImportedFromIB2 + 501.IBPluginDependency + 503.IBEditorWindowLastContentRect + 503.IBPluginDependency + 503.IBWindowTemplateEditedContentRect + 503.NSWindowTemplate.visibleAtLaunch + 503.windowTemplate.hasMaxSize + 503.windowTemplate.hasMinSize + 503.windowTemplate.maxSize + 503.windowTemplate.minSize + 504.IBPluginDependency + 507.IBPluginDependency + 508.IBPluginDependency + 509.IBPluginDependency + 510.IBPluginDependency + 511.IBPluginDependency + 512.IBPluginDependency + 513.IBPluginDependency + 514.IBPluginDependency + 515.IBPluginDependency + 516.IBPluginDependency + 517.IBPluginDependency + 518.IBPluginDependency + 519.IBPluginDependency + 520.IBPluginDependency + 521.IBPluginDependency + 522.IBPluginDependency + 523.IBPluginDependency + 524.IBPluginDependency + 525.IBPluginDependency + 541.IBPluginDependency + 542.IBPluginDependency + 544.IBPluginDependency + 545.IBEditorWindowLastContentRect + 545.IBPluginDependency + 550.IBPluginDependency + 56.IBPluginDependency + 56.ImportedFromIB2 + 560.IBPluginDependency + 561.IBPluginDependency + 562.IBPluginDependency + 568.IBPluginDependency + 569.IBPluginDependency + 57.IBEditorWindowLastContentRect + 57.IBPluginDependency + 57.ImportedFromIB2 + 57.editorWindowContentRectSynchronizationRect + 571.IBPluginDependency + 572.IBPluginDependency + 58.IBPluginDependency + 58.ImportedFromIB2 + 581.IBPluginDependency + 582.IBPluginDependency + 92.IBPluginDependency + 92.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{436, 809}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{526, 428}, {211, 103}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{525, 802}, {197, 73}} + {{293, 531}, {316, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {74, 862} + {{6, 978}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + {{390, 212}, {192, 73}} + com.apple.InterfaceBuilder.CocoaPlugin + {{475, 832}, {234, 43}} + {{1073, 539}, {593, 360}} + com.apple.InterfaceBuilder.CocoaPlugin + {{1073, 539}, {593, 360}} + + {{33, 99}, {480, 360}} + + {3.40282e+38, 3.40282e+38} + {593, 360} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + {{378, 681}, {276, 219}} + com.apple.InterfaceBuilder.CocoaPlugin + {{378, 681}, {276, 219}} + + + + {276, 219} + {276, 219} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{348, 232}, {218, 53}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{219, 102}, {242, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{23, 794}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 589 + + + + YES + + BTDemosAppController + NSObject + + YES + + YES + nextDemo: + nullMenuTarget: + previousDemo: + resetDemo: + toggleFullscreen: + toggleParameters: + + + YES + id + id + id + id + id + id + + + + YES + + YES + _glView + _parameters + + + YES + BTOpenGLView + BTSimulationParameters + + + + IBProjectSource + src/BTDemosAppController.h + + + + BTOpenGLView + NSView + + _delegate + id + + + IBProjectSource + src/toolkit/BTOpenGLView.h + + + + BTSimulationParameters + NSObject + + IBProjectSource + src/BTSimulationParameters.h + + + + + 0 + ../AllBulletDemos.xcodeproj + 3 + + diff --git a/Extras/AllBulletDemosOSX/Info.plist b/Extras/AllBulletDemosOSX/Info.plist new file mode 100644 index 0000000..5081c73 --- /dev/null +++ b/Extras/AllBulletDemosOSX/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + BulletIcon + CFBundleIdentifier + org.bullet.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/Extras/AllBulletDemosOSX/README.txt b/Extras/AllBulletDemosOSX/README.txt new file mode 100644 index 0000000..173847c --- /dev/null +++ b/Extras/AllBulletDemosOSX/README.txt @@ -0,0 +1,6 @@ +To build: +Place AllBulletDemosOSX in bullet-/Extras and build with Xcode. + +Questions: +contact Shamyl Zakariya +shamyl@zakariya.net \ No newline at end of file diff --git a/Extras/AllBulletDemosOSX/main.m b/Extras/AllBulletDemosOSX/main.m new file mode 100644 index 0000000..699ddd4 --- /dev/null +++ b/Extras/AllBulletDemosOSX/main.m @@ -0,0 +1,14 @@ +// +// main.m +// AllBulletDemos +// +// Created by Shamyl Zakariya on 5/1/08. +// Copyright Shamyl Zakariya 2008. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/Extras/AllBulletDemosOSX/src/BTDemo.h b/Extras/AllBulletDemosOSX/src/BTDemo.h new file mode 100644 index 0000000..235353e --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/BTDemo.h @@ -0,0 +1,106 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import +#import "BTOpenGLDisplayDelegate.h" + +@class BTDemoEntry; + +@interface BTDemo : NSObject { + + NSString *_demoName; + BTDemoEntry *_demo; +} + +/** + @brief Array of all available bullet demos +*/ ++ (NSArray*) demoNames; + +/** + @brief Verify a given string is a demo name +*/ ++ (BOOL) isDemo: (NSString *) demoName; + +/** + @brief Create a demo with a given name + @note Returns nil if the name is not a valid demo name +*/ ++ (BTDemo*) demoWithName: (NSString *) demoName; + +/** + @brief Initialize a demo with a given name +*/ +- (id) initWithDemoName: (NSString *) demoName; + +/** + @brief Reset current demo +*/ +- (void) reset; + +/** + @brief Name of current demo +*/ +- (NSString*) demoName; + +/////////////////////////////////////////////////////////////////////// +// BTOpenGLDisplayDelegate + +- (void) contextCreated; +- (void) contextWillBeDestroyed; +- (void) contextWillResize; +- (void) contextResized: (NSSize) newSize; +- (void) contextDidResize; +- (void) contextStateInvalidated; + +- (void) display: (float) deltaT; + +- (void) keyPressed: (unsigned char) key; +- (void) keyReleased: (unsigned char) key; + +- (void) specialKeyPressed: (unsigned) GLUTKey; +- (void) specialKeyReleased: (unsigned) GLUTKey; + +- (void) mouseButtonPressed: (unsigned) mouseButton; +- (void) mouseButtonReleased: (unsigned) mouseButton; +- (void) mouseMoved: (NSPoint) delta; +- (void) newMousePosition: (NSPoint) newMousePosition; +- (void) scrollWheel: (NSPoint) delta; + +/////////////////////////////////////////////////////////////////////// +// Global simulation properties -- applies to all demos + ++ (void) setIterations: (unsigned) iterations; ++ (unsigned) iterations; + ++ (unsigned) minIterations; ++ (unsigned) maxIterations; + ++ (void) setDisableDeactivation: (BOOL) disableDeactivation; ++ (BOOL) disableDeactivation; + ++ (void) setDrawAABBs: (BOOL) drawAABBs; ++ (BOOL) drawAABBs; + ++ (void) setDebugDraw: (BOOL) debugDraw; ++ (BOOL) debugDraw; + ++ (void) setSplitImpulse: (BOOL) splitImpulse; ++ (BOOL) splitImpulse; + ++ (void) setDrawContacts: (BOOL) drawContacts; ++ (BOOL) drawContacts; + +@end diff --git a/Extras/AllBulletDemosOSX/src/BTDemo.mm b/Extras/AllBulletDemosOSX/src/BTDemo.mm new file mode 100644 index 0000000..ebdab21 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/BTDemo.mm @@ -0,0 +1,413 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import "BTDemo.h" + +/////////////////////////////////////////////////////////////////////// +// Bullet includes + +#include "LinearMath/btScalar.h" +#include "LinearMath/btMinMax.h" + +#include "DemoApplication.h" +#include "DemoEntries.h" +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" + +#include "GLDebugDrawer.h" + +#include "LinearMath/btQuickprof.h" + + +/////////////////////////////////////////////////////////////////////// + +#pragma mark - +#pragma mark Globals + +static NSPoint MousePosition; +static NSSize ViewSize; +static int NumIterations = 10; +static BOOL DisableDeactivation = NO; +static BOOL DrawAABBs = NO; +static BOOL DebugDraw = NO; +static BOOL SplitImpulse = NO; +static BOOL DrawContacts = NO; + +/////////////////////////////////////////////////////////////////////// + +#pragma mark - +#pragma mark BTDemoEntry + +@interface BTDemoEntry : NSObject { + btDemoEntry *ctor; + DemoApplication *demo; +} + +- (id) initWithDemoEntry: (btDemoEntry*) constructor; +- (DemoApplication*) demo; +- (void) reset; + +@end + +@implementation BTDemoEntry + +- (id) initWithDemoEntry: (btDemoEntry*) constructor +{ + if ( self = [super init] ) + { + ctor = constructor; + [self reset]; + } + + return self; +} + +- (void) dealloc +{ + if ( demo ) delete demo; + [super dealloc]; +} + +- (DemoApplication*) demo +{ + return demo; +} + +- (void) reset +{ + if ( demo ) + { + if (demo->getDynamicsWorld()->getDebugDrawer()) + delete demo->getDynamicsWorld()->getDebugDrawer(); + + delete demo; + demo = NULL; + } + + demo = ctor->createFcn(); + btAssert(demo); + + if (demo->getDynamicsWorld()) + { + demo->getDynamicsWorld()->setDebugDrawer(new GLDebugDrawer()); + } + + #ifndef BT_NO_PROFILE + CProfileManager::Reset(); + #endif //BT_NO_PROFILE +} + +@end + +/////////////////////////////////////////////////////////////////////// + +#pragma mark - +#pragma mark BTDemo + + +@implementation BTDemo + ++ (NSArray*) demoNames +{ + static NSMutableArray *DEMOS = nil; + if ( !DEMOS ) + { + DEMOS = [[NSMutableArray alloc] init]; + + btDemoEntry* e = g_demoEntries; + while (e->createFcn) + { + [DEMOS addObject: [NSString stringWithUTF8String: e->name]]; + ++e; + } + } + + return DEMOS; +} + ++ (BOOL) isDemo: (NSString *) demoName +{ + return [[self demoNames] containsObject: demoName]; +} + ++ (BTDemo*) demoWithName: (NSString *) demoName +{ + if ( [BTDemo isDemo: demoName] ) + { + return [[[BTDemo alloc] initWithDemoName: demoName] autorelease]; + } + + return nil; +} + +- (id) initWithDemoName: (NSString *) demoName +{ + if ( self = [super init] ) + { + _demoName = [demoName copy]; + + // now walk the constructor list and find this demo + + btDemoEntry* e = g_demoEntries; + while (e->createFcn) + { + NSString *name = [NSString stringWithCString: e->name]; + if ( [name isEqualToString: demoName] ) + { + _demo = [[BTDemoEntry alloc] initWithDemoEntry: e]; + break; + } + + e++; + } + } + + return self; +} + +- (void) dealloc +{ + [_demoName release]; + [_demo release]; + [super dealloc]; +} + +- (void) reset +{ + [_demo reset]; + + [self contextWillResize]; + [self contextResized: ViewSize]; + [self contextDidResize]; +} + +- (NSString*) demoName +{ + return _demoName; +} + +#pragma mark - +#pragma mark BTOpenGLDisplayDelegate + +- (void) contextCreated +{} + +- (void) contextWillBeDestroyed +{} + +- (void) contextWillResize +{} + +- (void) contextResized: (NSSize) newSize +{ + ViewSize = newSize; + glViewport( 0, 0, (int) newSize.width, (int) newSize.height ); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + [_demo demo]->reshape( (int) newSize.width, (int) newSize.height ); +} + +- (void) contextDidResize +{} + +- (void) contextStateInvalidated +{} + +- (void) display: (float) deltaT +{ + DemoApplication *demo = [_demo demo]; + + if ( !demo ) + { + glClearColor( 1, 0.5, 1, 1 ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + return; + } + + if (demo->getDynamicsWorld()) + { + if (SplitImpulse) + { + demo->getDynamicsWorld()->getSolverInfo().m_splitImpulse=1; + } else + { + demo->getDynamicsWorld()->getSolverInfo().m_splitImpulse=0; + } + } + if (DrawAABBs) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawAabb); + } + else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawAabb)); + } + + if (DebugDraw) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawWireframe); + } + else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawWireframe)); + } + + if (DrawContacts) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawContactPoints); + } + else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawContactPoints)); + } + + if (DisableDeactivation) + { + demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_NoDeactivation); + } + else + { + demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_NoDeactivation)); + } + + if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getWorldType() == BT_DISCRETE_DYNAMICS_WORLD) + { + btDiscreteDynamicsWorld* discreteWorld = (btDiscreteDynamicsWorld*) demo->getDynamicsWorld(); + discreteWorld->getSolverInfo().m_numIterations = NumIterations; + } + + if (!demo->isIdle()) + { + demo->clientMoveAndDisplay(); + } + else + { + demo->displayCallback(); + } + +} + +- (void) keyPressed: (unsigned char) key +{ + [_demo demo]->keyboardCallback(key, (int)MousePosition.x, (int)MousePosition.y ); +} + +- (void) keyReleased: (unsigned char) key +{} + +- (void) specialKeyPressed: (unsigned) key +{ + [_demo demo]->specialKeyboard(key,(int)MousePosition.x, (int)MousePosition.y ); +} + +- (void) specialKeyReleased: (unsigned) key +{ + [_demo demo]->specialKeyboardUp(key,(int)MousePosition.x, (int)MousePosition.y ); +} + +- (void) mouseButtonPressed: (unsigned) mouseButton +{ + [_demo demo]->mouseFunc( mouseButton, GLUT_DOWN, (int)MousePosition.x, (int)MousePosition.y ); +} + +- (void) mouseButtonReleased: (unsigned) mouseButton +{ + [_demo demo]->mouseFunc( mouseButton, GLUT_UP, (int)MousePosition.x, (int)MousePosition.y ); +} + +- (void) mouseMoved: (NSPoint) delta +{ + [_demo demo]->mouseMotionFunc((int)MousePosition.x, (int)MousePosition.y ); +} + +- (void) newMousePosition: (NSPoint) newMousePosition +{ + // Need to invert Y, since DemoApplication assumes origin at top-left + MousePosition = NSMakePoint( newMousePosition.x, ViewSize.height - newMousePosition.y ); +} + +- (void) scrollWheel: (NSPoint) delta +{} + +#pragma mark - +#pragma mark Global Simulation Properties + ++ (void) setIterations: (unsigned) iterations +{ + NumIterations = iterations; +} + ++ (unsigned) iterations +{ + return NumIterations; +} + ++ (unsigned) minIterations { return 1; } ++ (unsigned) maxIterations { return 1000; } + + ++ (void) setDisableDeactivation: (BOOL) disableDeactivation +{ + DisableDeactivation = disableDeactivation; +} + ++ (BOOL) disableDeactivation +{ + return DisableDeactivation; +} + ++ (void) setDrawAABBs: (BOOL) drawAABBs +{ + DrawAABBs = drawAABBs; +} + ++ (BOOL) drawAABBs +{ + return DrawAABBs; +} + ++ (void) setDebugDraw: (BOOL) debugDraw +{ + DebugDraw = debugDraw; +} + ++ (BOOL) debugDraw +{ + return DebugDraw; +} + ++ (void) setSplitImpulse: (BOOL) splitImpulse +{ + SplitImpulse = splitImpulse; +} + ++ (BOOL) splitImpulse +{ + return SplitImpulse; +} + ++ (void) setDrawContacts: (BOOL) drawContacts +{ + DrawContacts = drawContacts; +} + ++ (BOOL) drawContacts +{ + return DrawContacts; +} + + +@end diff --git a/Extras/AllBulletDemosOSX/src/BTDemosAppController.h b/Extras/AllBulletDemosOSX/src/BTDemosAppController.h new file mode 100644 index 0000000..62349e3 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/BTDemosAppController.h @@ -0,0 +1,54 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import +#import "BTOpenGLView.h" +#import "BTSimulationParameters.h" +#import "BTDemo.h" + +@interface BTDemosAppController : NSObject { + + IBOutlet BTOpenGLView* _glView; + IBOutlet BTSimulationParameters *_parameters; + + BTDemo *_currentDemo; + BOOL _showParameters; +} + +/////////////////////////////////////////////////////////////////////// +// Public API + +- (void) setFullscreen: (BOOL) fullscreen; +- (BOOL) fullscreen; + +- (void) setShowParameters: (BOOL) showParameters; +- (BOOL) showParameters; + +- (NSArray*) demos; + +- (void) setDemo: (NSString*) demoName; +- (NSString*) demo; + +/////////////////////////////////////////////////////////////////////// +// IBActions + +- (IBAction) nextDemo: (id) sender; +- (IBAction) previousDemo: (id) sender; +- (IBAction) toggleFullscreen: (id) sender; +- (IBAction) toggleParameters: (id) sender; +- (IBAction) resetDemo: (id) sender; +- (IBAction) nullMenuTarget: (id) sender; + +@end diff --git a/Extras/AllBulletDemosOSX/src/BTDemosAppController.m b/Extras/AllBulletDemosOSX/src/BTDemosAppController.m new file mode 100644 index 0000000..5444713 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/BTDemosAppController.m @@ -0,0 +1,151 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import "BTDemosAppController.h" + + +@implementation BTDemosAppController + +- (id) init +{ + if ( self = [super init] ) + { + // change cwd to .app/Contents/Resources + NSString *resourcePath = [[NSBundle mainBundle] resourcePath]; + [[NSFileManager defaultManager] changeCurrentDirectoryPath:resourcePath]; + } + + return self; +} + +- (void) awakeFromNib +{} + +#pragma mark - +#pragma mark Public API + +- (void) setFullscreen: (BOOL) fullscreen +{ + [_glView setFullscreen: fullscreen]; +} + +- (BOOL) fullscreen +{ + return [_glView fullscreen]; +} + +- (void) setShowParameters: (BOOL) showParameters +{ + _showParameters = showParameters; +} + +- (BOOL) showParameters +{ + return _showParameters; +} + +- (NSArray*) demos +{ + return [BTDemo demoNames]; +} + +- (void) setDemo: (NSString*) demoName +{ + [_currentDemo release]; + [_glView setDelegate: nil]; + + _currentDemo = [[BTDemo demoWithName: demoName] retain]; + + if ( _currentDemo ) + { + // the demo is the rendering & input delegate for the gl view + [_glView setDelegate: _currentDemo]; + + [_currentDemo contextWillResize]; + [_currentDemo contextResized: [_glView bounds].size]; + [_currentDemo contextDidResize]; + } +} + +- (NSString*) demo +{ + return _currentDemo ? [_currentDemo demoName] : nil; +} + +#pragma mark - +#pragma mark IBActions + +- (IBAction) nextDemo: (id) sender +{ + NSArray *demos = [self demos]; + unsigned index = [demos indexOfObject: [self demo]]; + if ( index != NSNotFound ) + { + index = ( index + 1 ) % [demos count]; + [self setDemo: [demos objectAtIndex: index]]; + } +} + +- (IBAction) previousDemo: (id) sender +{ + NSArray *demos = [self demos]; + unsigned index = [demos indexOfObject: [self demo]]; + if ( index != NSNotFound ) + { + if ( index == 0 ) index = [demos count] - 1; + else index--; + + [self setDemo: [demos objectAtIndex: index]]; + } +} + +- (IBAction) toggleFullscreen: (id) sender +{ + [self setFullscreen: ![self fullscreen]]; +} + +- (IBAction) toggleParameters: (id) sender +{ + [self setShowParameters: ![self showParameters]]; +} + +- (IBAction) resetDemo: (id) sender +{ + [_currentDemo reset]; +} + +- (IBAction) nullMenuTarget: (id) sender +{ + // this handles a 10.4 bug. A menu bound to some property for toggling + // will not invoke unless it has a target and selector set. +} + +#pragma mark - +#pragma mark NSApplicationDelegate + +- (void) applicationDidFinishLaunching: (NSNotification *)aNotification +{ + // note: We load the first demo here and not in -awakeFromNib as the + // OpenGL view is instantiated, but not running yet at that point + + [self setDemo: [[self demos] objectAtIndex:0]]; +} + +- (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *)theApplication +{ + return YES; +} + +@end diff --git a/Extras/AllBulletDemosOSX/src/BTSimulationParameters.h b/Extras/AllBulletDemosOSX/src/BTSimulationParameters.h new file mode 100644 index 0000000..298c9dd --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/BTSimulationParameters.h @@ -0,0 +1,47 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import + +/* + BTSimulationParameters is an instanceable proxy for BTDemo's global + simulation properties. We're doing this so we can bind UI to something + in the nib file. +*/ + +@interface BTSimulationParameters : NSObject {} + +- (void) setIterations: (unsigned) iterations; +- (unsigned) iterations; + +- (unsigned) minIterations; +- (unsigned) maxIterations; + +- (void) setDisableDeactivation: (BOOL) disableDeactivation; +- (BOOL) disableDeactivation; + +- (void) setDrawAABBs: (BOOL) drawAABBs; +- (BOOL) drawAABBs; + +- (void) setDebugDraw: (BOOL) debugDraw; +- (BOOL) debugDraw; + +- (void) setSplitImpulse: (BOOL) splitImpulse; +- (BOOL) splitImpulse; + +- (void) setDrawContacts: (BOOL) drawContacts; +- (BOOL) drawContacts; + +@end diff --git a/Extras/AllBulletDemosOSX/src/BTSimulationParameters.m b/Extras/AllBulletDemosOSX/src/BTSimulationParameters.m new file mode 100644 index 0000000..ab87cd9 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/BTSimulationParameters.m @@ -0,0 +1,96 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import "BTSimulationParameters.h" +#import "BTDemo.h" + +@implementation BTSimulationParameters + +- (id) init +{ + if ( self = [super init] ) + {} + + return self; +} + +#pragma mark Public API + +- (void) setIterations: (unsigned) iterations +{ + [BTDemo setIterations: iterations]; +} + +- (unsigned) iterations +{ + return [BTDemo iterations]; +} + +- (unsigned) minIterations { return [BTDemo minIterations]; } +- (unsigned) maxIterations { return [BTDemo maxIterations]; } + + +- (void) setDisableDeactivation: (BOOL) disableDeactivation +{ + [BTDemo setDisableDeactivation: disableDeactivation]; +} + +- (BOOL) disableDeactivation +{ + return [BTDemo disableDeactivation]; +} + +- (void) setDrawAABBs: (BOOL) drawAABBs +{ + [BTDemo setDrawAABBs: drawAABBs]; +} + +- (BOOL) drawAABBs +{ + return [BTDemo drawAABBs];; +} + +- (void) setDebugDraw: (BOOL) debugDraw +{ + [BTDemo setDebugDraw: debugDraw]; +} + +- (BOOL) debugDraw +{ + return [BTDemo debugDraw]; +} + +- (void) setSplitImpulse: (BOOL) splitImpulse +{ + [BTDemo setSplitImpulse: splitImpulse]; +} + +- (BOOL) splitImpulse +{ + return [BTDemo splitImpulse]; +} + + +- (void) setDrawContacts: (BOOL) drawContacts +{ + [BTDemo setDrawContacts: drawContacts]; +} + +- (BOOL) drawContacts +{ + return [BTDemo drawContacts]; +} + +@end diff --git a/Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.h b/Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.h new file mode 100644 index 0000000..3172f95 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.h @@ -0,0 +1,25 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import + + +@interface BTFullScreenWindow : NSWindow { + +} + +- (id) initForScreen: (NSScreen *) screen; + +@end diff --git a/Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.m b/Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.m new file mode 100644 index 0000000..2528f6e --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/toolkit/BTFullscreenWindow.m @@ -0,0 +1,48 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import "BTFullScreenWindow.h" + + +@implementation BTFullScreenWindow + +- (id) initForScreen: (NSScreen *) screen +{ + NSRect frame = [screen frame]; + frame.size.height -= [NSMenuView menuBarHeight]; + + self = [self initWithContentRect: frame + styleMask: NSBorderlessWindowMask + backing: NSBackingStoreBuffered + defer: YES + screen: screen ]; + if ( self ) + { + /* + For some reason, without this + we lose mouse moved events in fullscreen + */ + [self setAcceptsMouseMovedEvents: YES]; + } + + return self; +} + +- (BOOL)canBecomeKeyWindow +{ + return YES; +} + +@end diff --git a/Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.h b/Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.h new file mode 100644 index 0000000..3d19f47 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.h @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BT_KEY_CODE_H__ +#define __BT_KEY_CODE_H__ + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + @brief Determine if a key is a letter. + @return true if @a keycode is a letter, and not a control + or modifier key. E.g., the letter 'b' is, where the Esc key ( BTKey_Escape ) is not. +*/ +extern BOOL BTKeyIsAlpha( int ); + +/** + @brief Determine if a key is a GLUT special key. ( arrow, F-Keys, etc ) +*/ +extern BOOL BTKeyIsSpecial( int keycode ); + +/** + @brief Convert an OS X keycode to GLUT Special key representation +*/ +extern int BTKeyTranslateKeyCodeToSpecial( int ); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.m b/Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.m new file mode 100644 index 0000000..786498d --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/toolkit/BTGLUTKeyAdapter.m @@ -0,0 +1,128 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import "BTGLUTKeyAdapter.h" +#import + +BOOL BTKeyIsAlpha( int key ) +{ + return !BTKeyIsSpecial( key ); +} + +BOOL BTKeyIsSpecial( int keycode ) +{ + BOOL ret = NO; + switch( keycode ) + { + case NSUpArrowFunctionKey: + case NSDownArrowFunctionKey: + case NSLeftArrowFunctionKey: + case NSRightArrowFunctionKey: + case NSF1FunctionKey: + case NSF2FunctionKey: + case NSF3FunctionKey: + case NSF4FunctionKey: + case NSF5FunctionKey: + case NSF6FunctionKey: + case NSF7FunctionKey: + case NSF8FunctionKey: + case NSF9FunctionKey: + case NSF10FunctionKey: + case NSF11FunctionKey: + case NSF12FunctionKey: + ret = YES; + break; + + default: break; + } + + return ret; +} + + +int BTKeyTranslateKeyCodeToSpecial( int kc ) +{ + int ret = kc; + switch( kc ) + { + case NSUpArrowFunctionKey: + ret = GLUT_KEY_UP; + break; + + case NSDownArrowFunctionKey: + ret = GLUT_KEY_DOWN; + break; + + case NSLeftArrowFunctionKey: + ret = GLUT_KEY_LEFT; + break; + + case NSRightArrowFunctionKey: + ret = GLUT_KEY_RIGHT; + break; + + case NSF1FunctionKey: + ret = GLUT_KEY_F1; + break; + + case NSF2FunctionKey: + ret = GLUT_KEY_F2; + break; + + case NSF3FunctionKey: + ret = GLUT_KEY_F3; + break; + + case NSF4FunctionKey: + ret = GLUT_KEY_F4; + break; + + case NSF5FunctionKey: + ret = GLUT_KEY_F5; + break; + + case NSF6FunctionKey: + ret = GLUT_KEY_F6; + break; + + case NSF7FunctionKey: + ret = GLUT_KEY_F7; + break; + + case NSF8FunctionKey: + ret = GLUT_KEY_F8; + break; + + case NSF9FunctionKey: + ret = GLUT_KEY_F9; + break; + + case NSF10FunctionKey: + ret = GLUT_KEY_F10; + break; + + case NSF11FunctionKey: + ret = GLUT_KEY_F11; + break; + + case NSF12FunctionKey: + ret = GLUT_KEY_F12; + break; + + default: break; + } + + return ret; +} diff --git a/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLDisplayDelegate.h b/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLDisplayDelegate.h new file mode 100644 index 0000000..41d5069 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLDisplayDelegate.h @@ -0,0 +1,50 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import + + +@protocol BTOpenGLDisplayDelegate + +- (void) contextCreated; +- (void) contextWillBeDestroyed; +- (void) contextWillResize; +- (void) contextResized: (NSSize) newSize; +- (void) contextDidResize; +- (void) contextStateInvalidated; + +- (void) display: (float) deltaT; + +/////////////////////////////////////////////////////////////////////// +// ASCII keypresses + +- (void) keyPressed: (unsigned char) key; +- (void) keyReleased: (unsigned char) key; + +/////////////////////////////////////////////////////////////////////// +// GLUT Special Keys, such as GLUT_KEY_LEFT ( "left arrow key" ) + +- (void) specialKeyPressed: (unsigned) GLUTKey; +- (void) specialKeyReleased: (unsigned) GLUTKey; + +/////////////////////////////////////////////////////////////////////// +// Mouse. button is GLUT_LEFT_MOUSE, GLUT_RIGHT_MOUSE, etc. + +- (void) mouseButtonPressed: (unsigned) mouseButton; +- (void) mouseButtonReleased: (unsigned) mouseButton; +- (void) mouseMoved: (NSPoint) delta; +- (void) newMousePosition: (NSPoint) newMousePosition; +- (void) scrollWheel: (NSPoint) delta; +@end diff --git a/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.h b/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.h new file mode 100644 index 0000000..a5f4c72 --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.h @@ -0,0 +1,65 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import +#import +#import "BTOpenGLDisplayDelegate.h" + +@interface BTOpenGLView : NSView +{ + IBOutlet id _delegate; + + BOOL _firstFrame, + _setupBoundsChangeNotification, + _isFullScreen, + _multisample, + _vblSync, + _suppressResize; + + NSOpenGLContext *_windowedContext; + + unsigned int _modifierFlags; + + float _interval, + _currentFPS; + + double _lastFrameTime; + + NSWindow *_fullscreenWindow, + *_windowedWindow; + + NSTimer *_timer; +} + +- (void) setDelegate: (id ) delegate; +- (id ) delegate; + +- (void) setTargetFPS: (float) fps; +- (float) targetFPS; +- (float) currentFPS; + +- (void) setFullscreen: (BOOL) yesno; +- (BOOL) fullscreen; + +- (void) setMultisampleRendering: (BOOL) multisample; +- (BOOL) multisampleRendering; + +- (void) setVBLSync: (BOOL) sync; +- (BOOL) vblSync; + +- (NSOpenGLContext*) openGLContext; + + +@end diff --git a/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.m b/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.m new file mode 100644 index 0000000..bbe745d --- /dev/null +++ b/Extras/AllBulletDemosOSX/src/toolkit/BTOpenGLView.m @@ -0,0 +1,603 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#import "BTOpenGLView.h" + +#include +#import +#import + +#import "BTFullScreenWindow.h" +#import "BTGLUTKeyAdapter.h" + +#pragma mark - +#pragma mark Private Methods + +@interface BTOpenGLView (Internal) + +- (void) update; +- (void) boundsDidChange: (NSNotification *) notification; +- (void) setVBL: (BOOL*) vbl forContext: (NSOpenGLContext*) context; +- (void) setMultithreaded: (BOOL) mt; +- (NSOpenGLPixelFormat*) windowedPixelFormat: (BOOL*) antialias; + +@end + +@implementation BTOpenGLView + +#pragma mark - +#pragma mark Bootstrap + +- (id)initWithFrame:(NSRect)frameRect +{ + self = [super initWithFrame:frameRect]; + if (self == nil) + { + NSLog( @"BTOpenGLView::initWithFrame - Unable to init" ); + return nil; + } + + _modifierFlags = 0; + _multisample = YES; + _vblSync = YES; + _firstFrame = YES; + _setupBoundsChangeNotification = NO; + + /* + Set up the windowed context -- it will be assigned to the + view later, not now. + */ + _windowedContext = [[NSOpenGLContext alloc] initWithFormat: [self windowedPixelFormat: &_multisample] + shareContext: nil]; + + [self setVBL: &_vblSync forContext: _windowedContext]; + + if (_windowedContext == nil) + { + NSLog(@"Got nil windowed context"); + [self dealloc]; + return nil; + } + + /* + Setup and start the update timer. + */ + _interval = 1.0 / 60.0; + _timer = [[NSTimer scheduledTimerWithTimeInterval: _interval + target: self + selector: @selector(update) + userInfo: nil + repeats: YES ] retain]; + + [[NSRunLoop currentRunLoop] addTimer: _timer forMode: NSEventTrackingRunLoopMode]; + + return self; +} + +- (void)dealloc +{ + [_timer invalidate]; + [_timer release]; + + [_delegate contextWillBeDestroyed]; + + [_windowedContext release]; + + [[NSNotificationCenter defaultCenter] removeObserver: self]; + + [super dealloc]; +} + +- (void) awakeFromNib +{ + NSWindow *window = [self window]; + [window setAcceptsMouseMovedEvents: YES]; + [window makeFirstResponder: self]; + [window setInitialFirstResponder: self]; +} + +- (void)drawRect:(NSRect)rect +{ + [self update]; +} + +#pragma mark - +#pragma mark Public API + +- (void) setDelegate: (id ) delegate +{ + // we don't retain delegates + _delegate = delegate; +} + +- (id ) delegate +{ + return _delegate; +} + +- (void) setTargetFPS: (float) fps +{ + float newInterval = 1.0 / fps; + if ( ABS( newInterval - _interval ) > 1.0e-3 ) + { + _interval = newInterval; + + [_timer invalidate]; + [_timer release]; + + _timer = [[NSTimer scheduledTimerWithTimeInterval: _interval + target: self + selector: @selector(update) + userInfo: nil + repeats: YES ] retain]; + + [[NSRunLoop currentRunLoop] addTimer: _timer forMode: NSEventTrackingRunLoopMode]; + } + +} + +- (float) targetFPS +{ + return 1.0 / _interval; +} + +- (float) currentFPS +{ + return _currentFPS; +} + +- (void) setFullscreen: (BOOL) fullscreen +{ + if ( fullscreen == _isFullScreen ) return; + + _isFullScreen = fullscreen; + _suppressResize = YES; + + if ( _isFullScreen ) + { + _windowedWindow = [self window]; + + /* + Detach & retain the content view from the non-fullscreen window. + */ + + NSView *contentView = [_windowedWindow contentView]; + [contentView retain]; + [contentView removeFromSuperviewWithoutNeedingDisplay]; + + /* + Create a fullscreen window, attach the content view, + and release the content view since the fullscreen window retained it. + */ + + _fullscreenWindow = [[BTFullScreenWindow alloc] initForScreen: [_windowedWindow screen]]; + [_fullscreenWindow setContentView: contentView ]; + [_fullscreenWindow makeKeyAndOrderFront:nil]; + [contentView release]; + + /* + Hide the old window + */ + [_windowedWindow orderOut: nil]; + + /* + Now, use the SetSystemUIMode API to auto-hide the dock + */ + + OSStatus error = SetSystemUIMode( kUIModeContentSuppressed, 0 ); + if ( error != noErr) + { + NSLog(@"Error couldn't set SystemUIMode: %ld", (long)error); + } + + } + else if ( _fullscreenWindow ) + { + /* + Detach and retain the content view from the fullscreen window + */ + NSView *contentView = [_fullscreenWindow contentView]; + [contentView retain]; + [contentView removeFromSuperviewWithoutNeedingDisplay]; + + /* + Reparent the content view to the non-fullscreen window, + and release it since it's now owned by the non-fullscreen window + */ + [_windowedWindow setContentView: contentView]; + [contentView release]; + + [_windowedWindow makeKeyAndOrderFront: nil]; + + /* + Release the fullscreen window + */ + [_fullscreenWindow orderOut: nil]; + [_fullscreenWindow release]; + _fullscreenWindow = nil; + + /* + Restore dock's normal behaior + */ + + OSStatus error = SetSystemUIMode( kUIModeNormal, 0 ); + if ( error != noErr) + { + NSLog(@"Error couldn't set SystemUIMode: %ld", (long)error); + } + } + + _suppressResize = NO; + + [self boundsDidChange: nil]; +} + +- (BOOL) fullscreen +{ + return _isFullScreen; +} + +- (void) setMultisampleRendering: (BOOL) multisample +{ + if ( multisample == _multisample ) return; + + _multisample = multisample; + _firstFrame = YES; + + + NSOpenGLContext *oldWindowedContext = _windowedContext; + _windowedContext = [[NSOpenGLContext alloc] initWithFormat: [self windowedPixelFormat: &_multisample] + shareContext: oldWindowedContext ]; + + [self setVBL: &_vblSync forContext: _windowedContext]; + + [oldWindowedContext release]; + [_windowedContext setView: self]; + [_windowedContext makeCurrentContext]; + [_windowedContext update]; + [self update]; +} + +- (BOOL) multisampleRendering +{ + return _multisample; +} + +- (void) setVBLSync: (BOOL) sync +{ + if ( sync == _vblSync ) return; + + _vblSync = sync; + [self setVBL: &_vblSync forContext: _windowedContext]; +} + +- (BOOL) vblSync +{ + return _vblSync; +} + +- (NSOpenGLContext *) openGLContext +{ + return _windowedContext; +} + +#pragma mark - +#pragma mark NSView Overrides + +- (BOOL) isOpaque +{ + return YES; +} + +- (BOOL) acceptsFirstResponder +{ + return YES; +} + +- (void) keyDown:(NSEvent *)theEvent +{ + int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; + + if ( BTKeyIsAlpha( key )) + { + [ _delegate keyPressed: key ]; + } + else + { + [_delegate specialKeyPressed: BTKeyTranslateKeyCodeToSpecial( key )]; + } +} + +- (void) keyUp:(NSEvent *)theEvent +{ + int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; + + if ( BTKeyIsAlpha( key )) + { + [ _delegate keyReleased: key ]; + } + else + { + [_delegate specialKeyReleased: BTKeyTranslateKeyCodeToSpecial( key )]; + } +} + +- (void) mouseDown: (NSEvent *) event +{ + int button = GLUT_LEFT_BUTTON; + switch( [event buttonNumber] ) + { + case 0: button = GLUT_LEFT_BUTTON; break; + case 1: button = GLUT_RIGHT_BUTTON; break; + case 2: button = GLUT_MIDDLE_BUTTON; break; + default: break; + } + + if ( _modifierFlags & NSControlKeyMask ) button = GLUT_RIGHT_BUTTON; + else if ( _modifierFlags & NSAlternateKeyMask ) button = GLUT_MIDDLE_BUTTON; + + [_delegate mouseButtonPressed: button]; +} + +- (void) mouseUp: (NSEvent *) event +{ + int button = GLUT_LEFT_BUTTON; + switch( [event buttonNumber] ) + { + case 0: button = GLUT_LEFT_BUTTON; break; + case 1: button = GLUT_RIGHT_BUTTON; break; + case 2: button = GLUT_MIDDLE_BUTTON; break; + default: break; + } + + if ( _modifierFlags & NSControlKeyMask ) button = GLUT_RIGHT_BUTTON; + else if ( _modifierFlags & NSAlternateKeyMask ) button = GLUT_MIDDLE_BUTTON; + + [_delegate mouseButtonReleased: button]; +} + +-(void) mouseMoved: (NSEvent *) event +{ + float dx = [event deltaX], + dy = [event deltaY]; + + NSPoint locationInView = [self convertPoint: [event locationInWindow] fromView: nil ]; + + [_delegate mouseMoved: NSMakePoint( dx, dy )]; + [_delegate newMousePosition: locationInView]; +} + +-(void) mouseDragged: (NSEvent *) event +{ + [self mouseMoved: event]; +} + +- (void) scrollWheel: (NSEvent *) event +{ + float dx = [event deltaX], + dy = [event deltaY]; + + [_delegate scrollWheel: NSMakePoint( dx, dy )]; +} + +- (void)flagsChanged:(NSEvent *) event +{ + _modifierFlags = [event modifierFlags]; +} + + +#pragma mark - +#pragma mark Private + +- (void) update +{ + if ( !_setupBoundsChangeNotification ) + { + _setupBoundsChangeNotification = YES; + + /* + This is hacky, but basically, we can't handle bounds-changing + ops correctly until everything's set up correctly. + */ + [self setPostsBoundsChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] addObserver: self + selector: @selector( boundsDidChange: ) + name: NSViewFrameDidChangeNotification + object: nil]; + } + + if (_firstFrame) + { + [_windowedContext setView:self]; + } + + [_windowedContext makeCurrentContext]; + + if (_firstFrame) + { + _firstFrame = NO; + + [_delegate contextCreated]; + + if ( _multisample ) + { + glEnable (GL_MULTISAMPLE_ARB); + // this fucks up text rendering, on nVIDIA, at least + //glHint (GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); + } + else + { + glDisable( GL_MULTISAMPLE_ARB ); + } + + [self setMultithreaded: NO]; + + NSSize contextSize; + if ( _isFullScreen ) + { + contextSize.width = CGDisplayPixelsWide(kCGDirectMainDisplay); + contextSize.height = CGDisplayPixelsHigh(kCGDirectMainDisplay); + } + else + { + contextSize = [self bounds].size; + } + + [_delegate contextWillResize]; + [_delegate contextResized: contextSize]; + [_delegate contextDidResize]; + [_delegate contextStateInvalidated]; + } + + double now = CFAbsoluteTimeGetCurrent(); + + if ( _delegate) [_delegate display: now - _lastFrameTime]; + else + { + glClearColor( 0.5, 0.5, 0.5, 1 ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + } + + _lastFrameTime = now; + + + [[NSOpenGLContext currentContext] flushBuffer]; + + /* + Now, update our FPS + */ + + { + static unsigned int frameCounter = 1; + static double lastCheckTime = 0; + + double elapsed = now - lastCheckTime; + if ( elapsed > 1.0 ) + { + _currentFPS = (float) ( ((double) frameCounter ) / elapsed ); + + lastCheckTime = now; + frameCounter = 0; + } + + frameCounter++; + } +} + +- (void) boundsDidChange: (NSNotification *) notification +{ + if ( _suppressResize ) return; + + [_windowedContext setView:self]; + [_windowedContext makeCurrentContext]; + [_windowedContext update]; + + NSSize contextSize = [self bounds].size; + + if ( _delegate ) + { + [_delegate contextWillResize]; + [_delegate contextResized: contextSize ]; + [_delegate contextDidResize]; + } + else + { + glViewport( 0, 0, (int) contextSize.width, (int) contextSize.height ); + } +} + +- (void) setVBL: (BOOL*) vbl forContext: (NSOpenGLContext*) context +{ + GLint value = *vbl ? 1 : 0; + [context setValues: &value forParameter: NSOpenGLCPSwapInterval]; + + *vbl = value ? YES : NO; +} + +- (void) setMultithreaded: (BOOL) mt +{ + CGLError err = kCGLNoError; + CGLContextObj ctx = CGLGetCurrentContext(); + + // Enable Apple's multi-threaded GL engine -- it's generally useful for + // high vertex throughput. Not high fragment situations + + if ( mt ) + { + err = CGLEnable( ctx, kCGLCEMPEngine ); + } + else + { + err = CGLDisable( ctx, kCGLCEMPEngine ); + } + + if (err != kCGLNoError ) + { + NSLog( @"BTOpenGLView -setMultithreaded: forContext: -- Unable to %s multithreaded GL", + mt ? "enable" : "disable" ); + } +} + +- (NSOpenGLPixelFormat*) windowedPixelFormat: (BOOL*) antialias +{ + NSOpenGLPixelFormatAttribute aaAttrs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAAccelerated, + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32, + NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8, + NSOpenGLPFASingleRenderer, + NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)( 1 ), + NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)( 4 ), + NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute) CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), + NSOpenGLPFANoRecovery, + (NSOpenGLPixelFormatAttribute)0 + }; + + NSOpenGLPixelFormatAttribute vanillaAttrs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAAccelerated, + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32, + NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8, + NSOpenGLPFASingleRenderer, + NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)( 0 ), + NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)( 0 ), + NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute) CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), + NSOpenGLPFANoRecovery, + (NSOpenGLPixelFormatAttribute)0 + }; + + NSOpenGLPixelFormat* fmt = 0; + + if ( *antialias ) + { + fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) aaAttrs]; + if ( nil == fmt ) + { + *antialias = NO; + fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) vanillaAttrs]; + } + } + else + { + fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) vanillaAttrs]; + } + + return fmt; +} + + +@end diff --git a/Extras/CDTestFramework/AntTweakBar/ChangeLog.txt b/Extras/CDTestFramework/AntTweakBar/ChangeLog.txt new file mode 100644 index 0000000..a4ca261 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/ChangeLog.txt @@ -0,0 +1,208 @@ +--- AntTweakBar library release notes --- + +* Version 1.15 (2012/07/22) + + - Added support for OpenGL Core Profile (3.2 and higher); it is enabled by + setting the TwGraphAPI parameter of the TwInit function to TW_OPENGL_CORE + (Thanks to Oystein E. and Arnaud M. for their contribution). + - Added a simple example that uses OpenGL Core Profile and SDL; see + TwGLCoreSDL.c . + - Added helper function TwEventX11 to handle native X11 events (Thanks to + Greg P. for the code). + - Added builtin fixed-width font for tweak bars; it is enabled through + the fontstyle bar parameter; it is not resizable (Thanks to Jay D. for + the font). + - Store and restore states of OpenGL vertex attribute arrays (Thanks to + Jerry J. and Eduard B.). + - Fixed memory access violation caused by the popup bar (Thanks to Matthias R. + for reporting it). + - Added code to overcome issue caused by the memory representation change + of std::string that occurs between Visual Studio 2008 and 2010. + +* Version 1.14 (2011/03/26) + + - Added 64 bit version of the library. + - Added multiple windows support (Inspired by comments and code from Evan F. + and Ivo H.) + - Better MacOSX support (Thanks to Alexis DH., Fabrice N., Diederick H., + Alec J.). + - Improved readability of overlapped transparent bars. Content of overlapped + regions is clipped and not drawn. This behavior can be disabled using + the bar parameter "overlap". + - Added support for Direct3D11 (Thanks to Jorge H., Lukasz M., Se1zen). + - Added an example based on DirectX 11. + - Added support for SDL 1.3 integration in addition to SDL 1.2. + ABI modification: TwEventSDL takes SDL version as an additional parameter. + - Added support for SFML 1.6 integration. + - Added support for GLFW 2.7 integration in addition to GLFW 2.6. This may + imply changing the calling convention of event callbacks. Can be done by + defining GLFW_CDECL before including AntTweakBar.h if needed. + - Added function TwKeyTest that checks if a key event would be processed by + AntTweakBar but without processing it. Needed to fix bad handling report of + WM_KEYUP and WM_KEYDOWN in TwEventWin (Thanks to Ryan DB. for reporting it). + - Added check sign for vars of type boolean. + - Added new bar parameter "buttonalign" to center or left-align buttons + (Suggested by Michael R.). + - Allowed values column width to be adjusted to fit its content. This is done + by setting the bar parameter valueswidth=fit (Requested by Koshmaar and + Michael R.). The user can also click in the left or right area near the + value width slider to fit column content. + - Added new helper function TwDefineEnumFromString to ease the defining of an + enum through a string of comma-separated enum values (Thanks to Bruno L. + for the suggestion and code). + - Fixed compilation issues with gcc4 (missing includes, warnings). + - Fixes for the fedora package maintained by Sean Middleditch. + - Fixed rotation widget display and interaction issues when the library is + compiled with gcc -O3 (Thanks to Ares L. for reporting this). + - Fixed SDL key event SDLK_RETURN handling after a bar is minimized (Thanks + to Sean M. for reporting this). + - Fixed issue with SDL_ShowCursor (Thanks to Hugues M. for reporting it). + - Fixed DirectX10 resource issue. + - Store and restore GL_TEXTURE_COORD_ARRAY state (Thanks to Jerry J. for + reporting this). + - Fixed mouse click repetition issue with passive event loop (Thanks to + Bruno L. for reporting it). + - Fixed issue with mouse button event when glut windows doesn't have focus + (Thanks to Scott J. for the fix). + - Reset enum content each time the var parameter "enum" is set using TwDefine + or TwSetParam (Following Carsten W. and Sulaiman remarks). + - Fixed memory corruption when more than one std_string are defined in a + custom struct (Thanks to Sulaiman for reporting it). + - Fixed mouse position issue with Direct3D9 fullscreen mode in TwSimpleDX9 + (Thanks to Paolo S. for pointing this out). + - Fixed ignored double-click in TwEvenWin (Thanks to H. Seungho for this). + +* Version 1.13 (2009/04/19) + + - Now compiles on Mac OSX (Many thanks to Evan F. for rewritting the OS + specific code, and to Tyler S. and Konstantin L. for their feedback). + - Added functions TwGetBarCount, TwGetBarByIndex, TwGetBarByName, + TwRefreshBar. + - Fixed bug related to var of type TW_TYPE_STDSTRING on Windows: Microsoft + implementation of std::string does not have the same size in Debug and + Release mode (hidden member added for debugging), which caused a crash when + mixing the Release version of AntTweakBar with a program compiled in Debug + mode (Thanks to Minh D. for reporting it). + - Added function TwGetParam and TwSetParam to allow access to the parameters + defining the behavior of bars and variables. + - Changed the bar/var parameters without value (like "show"/"hide") to + parameters with value ("visible=true or false") to be compatible with the + new TwGetParam and TwSetParam functions (the old syntax is still kept + for backward compatibility). + - Arrow keys and Return key can now be used to navigate and tweak values. + - Bars can now be moved partly outside of the window. They can still be + constrained to be fully contained in the window by setting the parameter + "contained=true". + - Added another way to move a bar by pressing mouse middle button in the bar. + +* Version 1.12 (2008/09/27) + + - Added new var types TW_TYPE_QUAT* and TW_TYPE_DIR* allowing for the + interactive tweaking of rotations (through quaternions) and 3D vectors + (directions). + - Better management of transparent tweak bars. New bar parameters added: + alpha=n text=dark/light. + - Default color scheme changed (now transparent by default). To reactivate the + previous scheme, call TwDefine("GLOBAL colorscheme=0") before creating bars. + - Added paramters to manage the bar behavior: resizable, movable, iconifiable, + fontresizable, alwaystop, alwaysbottom, visible, iconified (following + Jeppe F. B. feedback). + - Added functions TwSetBottomBar and TwGetBottomBar. + - The library can now be recompiled without requiring to install GLUT, GLFW + and SDL. + - New var parameters arrow, arrowcolor, axisx, axusy, axisz and showval added + for quaternion and direction types. + - Msvc specific keyword removed from PrefTimer (thanks to Tim J. for pointing + this out). + - Fixed bug related to popup behavior when the help bar is visible. + - GL_TEXTURE_RECTANGLE_ARB/EXT state is now saved and restored by TwDraw + (thanks to Cyril C. for suggesting this). + - glBlendFunc and glBlendEquationEXT are now saved and restored by TwDraw + (thanks to Sebastion B. for reporting the problem). + - Fixed bug related cursor visibility state with SDL (Thanks to Jeppe F. B. + for reporting it). + +* Version 1.11 (2007/12/10) + + - Now DirectX10 is also supported in addition to OpenGL and DirectX9. + Initialization of AntTweakBar with DX10: TwInit(TW_DIRECT3D10, d3d10Device). + - A new example that uses DirectX10 has been added: see TwSimpleDX10 in the + examples directory. + - Recap for string variables added to the doc. See + http://www.antisphere.com/Wiki/tools:anttweakbar:varstring + - An example that illustrates the use of the different types of string + variables has been added. See TwString in the examples directory. + - Added some code for multi-thread safety (thanks to Daniel 'DrUiD' B. for + the tip). + - Cleanup of the Help bar. Now only variables having help are displayed in + the Help bar. + - Function TwHandleErrors documented. + - Separators don't require a name anymore. + - Var parameter 'order' becomes 'colororder', and its values become 'rgba' and + 'argb' (order=ogl and order=dx still exist but are deprecated). + - A small icon added for variables of type bool. + - Function TwCopyCDStringToLibrary added. + - The keyword 'GLOBAL' has been added for TwDefine commands that don't apply + to a specific tweak bar (suggested by Koshmaar). + - TwEventWin32 becomes TwEventWin (a #define has been added to keep + compatibility with previous applications). + - TwWindowSize(0,0) now releases graphics resources allocated by AntTweakBar + (may be useful for Direct3D applications, before resizing for instance). + - A wrong assert removed from TwMgr.cpp (thanks to Chris W. for reporting it). + - Some slight cosmetic changes (again). + +* Version 1.10 (2007/08/31) + + - Variable values can now also be entered and edited via keyboard input + (implementation based on modifications made by Laury M., thank you Laury). + - Variables of type string are now handled: 3 types of string added + TW_TYPE_CSSTRING, TW_TYPE_CDSTRING and TW_STDSTRING. + - Text selection and copy/paste added. + - Position of bar icons is modifiable (cf. TwBar paramters iconPos, iconAlign + and iconMargin). + - Separators can be added in a bar (TwAddSeparator). + - OpenGL: states related to 3D textures and multitexturing are now saved and + restored by TwDraw (thanks to Dylan D. for pointing this out). + - Selected element of a listbox now highlighted. + - ReadOnly and ReadWrite behavior of buttons revisited. + - Documentation improved (examples for TwType, new functions documented,...). + - Some slight cosmetic changes. + +* Version 1.05 (2007/03/01) + + - Listbox and rotoslider buttons added. + - Icon resources (AntTweakBar.rc) no more required for static linkage (thanks + to Joe C. for pointing this out). + - Fixed a rotoslider precision problem when mouse button is released. + +* Version 1.04 (2006/12/16) + + - OpenGL: Vertex buffer object state and Vertex/fragment program and object + states are now reset and restored by TwDraw (thanks to Dylan D. and Siva K. + for pointing this out). + - Fixed problem that occurs when an initialized variable of type float/double + is displayed. + +* Version 1.03 (2006/10/28) + + - Medium font antialiased. + - Now also compiles on 64 bits x86 platform (thanks to Herling G. for this). + - Slight changes to avoid visual 8 secure crt warnings. + - Corrected behaviour if min/max values are not defined. + - Modif to avoid looping to max value when reaching zero with unsigned types. + - Min/max/step parameters for type TW_TYPE_CHAR now read ascii codes (not + characters). + - Added FPU precision control (because DirectX changes it). + - Fixed problem that occurs when the lib is initialized/uninitialized more + than once (thanks Lukasz P. for reporting it). + - Distribution follows Savannah's recommendations. + +* Version 1.02 (2006/09/27) + + - Library sources released. + +* Version 1.01 (2006/09/14) + + - First official release. + + \ No newline at end of file diff --git a/Extras/CDTestFramework/AntTweakBar/Clean.bat b/Extras/CDTestFramework/AntTweakBar/Clean.bat new file mode 100644 index 0000000..06d9186 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/Clean.bat @@ -0,0 +1,24 @@ +RMDIR /S /Q src\debug32 +RMDIR /S /Q src\debug64 +RMDIR /S /Q src\release32 +RMDIR /S /Q src\release64 +CD src +DEL *.ncb *.aps *.o *.bak *.user +DEL /A:h *.suo +CD .. +RMDIR /S /Q lib\debug +RMDIR /S /Q examples\debug32 +RMDIR /S /Q examples\debug64 +RMDIR /S /Q examples\tmp +DEL lib\*.exp +CD examples +DEL *.ncb *.aps *.o *.bak *.user +DEL /A:h *.suo +DEL /S BuildLog.htm +DEL bin\*.obj +DEL bin\*.idb +CD .. + +PAUSE + + diff --git a/Extras/CDTestFramework/AntTweakBar/License.txt b/Extras/CDTestFramework/AntTweakBar/License.txt new file mode 100644 index 0000000..f9ce6ff --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/License.txt @@ -0,0 +1,24 @@ +--- AntTweakBar license --- + +Copyright (C) 2005-2012 Philippe Decaudin + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the +use of this software. + +Permission is granted to anyone to use this software for any purpose, including +commercial applications, and to alter it and redistribute it freely, subject to +the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim +that you wrote the original software. If you use this software in a product, +an acknowledgment in the product documentation would be appreciated but is not +required. + +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. + + +http://www.antisphere.com diff --git a/Extras/CDTestFramework/AntTweakBar/Readme.txt b/Extras/CDTestFramework/AntTweakBar/Readme.txt new file mode 100644 index 0000000..19ab5ba --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/Readme.txt @@ -0,0 +1,15 @@ +--- AntTweakBar development library --- + + +AntTweakBar is a small and easy-to-use C/C++ library that allows programmers +to quickly add a light and intuitive GUI into OpenGL and DirectX based +graphic programs to interactively tweak parameters. + +This package includes the development version of the AntTweakBar library +for Windows, GNU/Linux and OSX, and some program examples (sources + binaries). + +For installation and documentation please refer to: +http://www.antisphere.com/Wiki/tools:anttweakbar + + +Philippe Decaudin - http://www.antisphere.com diff --git a/Extras/CDTestFramework/AntTweakBar/include/AntTweakBar.h b/Extras/CDTestFramework/AntTweakBar/include/AntTweakBar.h new file mode 100644 index 0000000..9b26b5b --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/include/AntTweakBar.h @@ -0,0 +1,381 @@ +// ---------------------------------------------------------------------------- +// +// @file AntTweakBar.h +// +// @brief AntTweakBar is a light and intuitive graphical user interface +// that can be readily integrated into OpenGL and DirectX +// applications in order to interactively tweak parameters. +// +// @author Philippe Decaudin - http://www.antisphere.com +// +// @doc http://www.antisphere.com/Wiki/tools:anttweakbar +// +// @license This file is part of the AntTweakBar library. +// AntTweakBar is a free software released under the zlib license. +// For conditions of distribution and use, see License.txt +// +// ---------------------------------------------------------------------------- + + +#if !defined TW_INCLUDED +#define TW_INCLUDED + +#define TW_STATIC 1 //no dynamic link library (DLL) hell +#define TW_NO_LIB_PRAGMA 1 //no magic linking nonsense, thank you + +#include + +#define TW_VERSION 115 // Version Mmm : M=Major mm=minor (e.g., 102 is version 1.02) + + +#ifdef __cplusplus +# if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4995 4530) +# include +# pragma warning(pop) +# else +# include +# endif + extern "C" { +#endif // __cplusplus + + +// ---------------------------------------------------------------------------- +// OS specific definitions +// ---------------------------------------------------------------------------- + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(TW_STATIC) +# define TW_CALL __stdcall +# define TW_CDECL_CALL __cdecl +# define TW_EXPORT_API __declspec(dllexport) +# define TW_IMPORT_API __declspec(dllimport) +#else +# define TW_CALL +# define TW_CDECL_CALL +# define TW_EXPORT_API +# define TW_IMPORT_API +#endif + +#if defined TW_EXPORTS +# define TW_API TW_EXPORT_API +#elif defined TW_STATIC +# define TW_API +# if defined(_MSC_VER) && !defined(TW_NO_LIB_PRAGMA) +# ifdef _WIN64 +# pragma comment(lib, "AntTweakBarStatic64") +# else +# pragma comment(lib, "AntTweakBarStatic") +# endif +# endif +#else +# define TW_API TW_IMPORT_API +# if defined(_MSC_VER) && !defined(TW_NO_LIB_PRAGMA) +# ifdef _WIN64 +# pragma comment(lib, "AntTweakBar64") +# else +# pragma comment(lib, "AntTweakBar") +# endif +# endif +#endif + + +// ---------------------------------------------------------------------------- +// Bar functions and definitions +// ---------------------------------------------------------------------------- + +typedef struct CTwBar TwBar; // structure CTwBar is not exposed. + +TW_API TwBar * TW_CALL TwNewBar(const char *barName); +TW_API int TW_CALL TwDeleteBar(TwBar *bar); +TW_API int TW_CALL TwDeleteAllBars(); +TW_API int TW_CALL TwSetTopBar(const TwBar *bar); +TW_API TwBar * TW_CALL TwGetTopBar(); +TW_API int TW_CALL TwSetBottomBar(const TwBar *bar); +TW_API TwBar * TW_CALL TwGetBottomBar(); +TW_API const char * TW_CALL TwGetBarName(TwBar *bar); +TW_API int TW_CALL TwGetBarCount(); +TW_API TwBar * TW_CALL TwGetBarByIndex(int barIndex); +TW_API TwBar * TW_CALL TwGetBarByName(const char *barName); +TW_API int TW_CALL TwRefreshBar(TwBar *bar); + +// ---------------------------------------------------------------------------- +// Var functions and definitions +// ---------------------------------------------------------------------------- + +typedef enum ETwType +{ + TW_TYPE_UNDEF = 0, +#ifdef __cplusplus + TW_TYPE_BOOLCPP = 1, +#endif // __cplusplus + TW_TYPE_BOOL8 = 2, + TW_TYPE_BOOL16, + TW_TYPE_BOOL32, + TW_TYPE_CHAR, + TW_TYPE_INT8, + TW_TYPE_UINT8, + TW_TYPE_INT16, + TW_TYPE_UINT16, + TW_TYPE_INT32, + TW_TYPE_UINT32, + TW_TYPE_FLOAT, + TW_TYPE_DOUBLE, + TW_TYPE_COLOR32, // 32 bits color. Order is RGBA if API is OpenGL or Direct3D10, and inversed if API is Direct3D9 (can be modified by defining 'colorOrder=...', see doc) + TW_TYPE_COLOR3F, // 3 floats color. Order is RGB. + TW_TYPE_COLOR4F, // 4 floats color. Order is RGBA. + TW_TYPE_CDSTRING, // Null-terminated C Dynamic String (pointer to an array of char dynamically allocated with malloc/realloc/strdup) +#ifdef __cplusplus +# if defined(_MSC_VER) && (_MSC_VER > 1500) + TW_TYPE_STDSTRING = (0x2ffe0000+sizeof(std::string)), // VS2010 or higher C++ STL string (std::string) +# else + TW_TYPE_STDSTRING = (0x2fff0000+sizeof(std::string)), // C++ STL string (std::string) +# endif +#endif // __cplusplus + TW_TYPE_QUAT4F = TW_TYPE_CDSTRING+2, // 4 floats encoding a quaternion {qx,qy,qz,qs} + TW_TYPE_QUAT4D, // 4 doubles encoding a quaternion {qx,qy,qz,qs} + TW_TYPE_DIR3F, // direction vector represented by 3 floats + TW_TYPE_DIR3D // direction vector represented by 3 doubles +} TwType; +#define TW_TYPE_CSSTRING(n) ((TwType)(0x30000000+((n)&0xfffffff))) // Null-terminated C Static String of size n (defined as char[n], with n<2^28) + +typedef void (TW_CALL * TwSetVarCallback)(const void *value, void *clientData); +typedef void (TW_CALL * TwGetVarCallback)(void *value, void *clientData); +typedef void (TW_CALL * TwButtonCallback)(void *clientData); + +TW_API int TW_CALL TwAddVarRW(TwBar *bar, const char *name, TwType type, void *var, const char *def); +TW_API int TW_CALL TwAddVarRO(TwBar *bar, const char *name, TwType type, const void *var, const char *def); +TW_API int TW_CALL TwAddVarCB(TwBar *bar, const char *name, TwType type, TwSetVarCallback setCallback, TwGetVarCallback getCallback, void *clientData, const char *def); +TW_API int TW_CALL TwAddButton(TwBar *bar, const char *name, TwButtonCallback callback, void *clientData, const char *def); +TW_API int TW_CALL TwAddSeparator(TwBar *bar, const char *name, const char *def); +TW_API int TW_CALL TwRemoveVar(TwBar *bar, const char *name); +TW_API int TW_CALL TwRemoveAllVars(TwBar *bar); + +typedef struct CTwEnumVal +{ + int Value; + const char * Label; +} TwEnumVal; +typedef struct CTwStructMember +{ + const char * Name; + TwType Type; + size_t Offset; + const char * DefString; +} TwStructMember; +typedef void (TW_CALL * TwSummaryCallback)(char *summaryString, size_t summaryMaxLength, const void *value, void *clientData); + +TW_API int TW_CALL TwDefine(const char *def); +TW_API TwType TW_CALL TwDefineEnum(const char *name, const TwEnumVal *enumValues, unsigned int nbValues); +TW_API TwType TW_CALL TwDefineEnumFromString(const char *name, const char *enumString); +TW_API TwType TW_CALL TwDefineStruct(const char *name, const TwStructMember *structMembers, unsigned int nbMembers, size_t structSize, TwSummaryCallback summaryCallback, void *summaryClientData); + +typedef void (TW_CALL * TwCopyCDStringToClient)(char **destinationClientStringPtr, const char *sourceString); +TW_API void TW_CALL TwCopyCDStringToClientFunc(TwCopyCDStringToClient copyCDStringFunc); +TW_API void TW_CALL TwCopyCDStringToLibrary(char **destinationLibraryStringPtr, const char *sourceClientString); +#ifdef __cplusplus +typedef void (TW_CALL * TwCopyStdStringToClient)(std::string& destinationClientString, const std::string& sourceString); +TW_API void TW_CALL TwCopyStdStringToClientFunc(TwCopyStdStringToClient copyStdStringToClientFunc); +TW_API void TW_CALL TwCopyStdStringToLibrary(std::string& destinationLibraryString, const std::string& sourceClientString); +#endif // __cplusplus + +typedef enum ETwParamValueType +{ + TW_PARAM_INT32, + TW_PARAM_FLOAT, + TW_PARAM_DOUBLE, + TW_PARAM_CSTRING // Null-terminated array of char (ie, c-string) +} TwParamValueType; +TW_API int TW_CALL TwGetParam(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int outValueMaxCount, void *outValues); +TW_API int TW_CALL TwSetParam(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int inValueCount, const void *inValues); + + +// ---------------------------------------------------------------------------- +// Management functions and definitions +// ---------------------------------------------------------------------------- + +typedef enum ETwGraphAPI +{ + TW_OPENGL = 1, + TW_DIRECT3D9 = 2, + TW_DIRECT3D10 = 3, + TW_DIRECT3D11 = 4, + TW_OPENGL_CORE = 5 +} TwGraphAPI; + +TW_API int TW_CALL TwInit(TwGraphAPI graphAPI, void *device); +TW_API int TW_CALL TwTerminate(); + +TW_API int TW_CALL TwDraw(); +TW_API int TW_CALL TwWindowSize(int width, int height); + +TW_API int TW_CALL TwSetCurrentWindow(int windowID); // multi-windows support +TW_API int TW_CALL TwGetCurrentWindow(); +TW_API int TW_CALL TwWindowExists(int windowID); + +typedef enum ETwKeyModifier +{ + TW_KMOD_NONE = 0x0000, // same codes as SDL keysym.mod + TW_KMOD_SHIFT = 0x0003, + TW_KMOD_CTRL = 0x00c0, + TW_KMOD_ALT = 0x0100, + TW_KMOD_META = 0x0c00 +} TwKeyModifier; +typedef enum EKeySpecial +{ + TW_KEY_BACKSPACE = '\b', + TW_KEY_TAB = '\t', + TW_KEY_CLEAR = 0x0c, + TW_KEY_RETURN = '\r', + TW_KEY_PAUSE = 0x13, + TW_KEY_ESCAPE = 0x1b, + TW_KEY_SPACE = ' ', + TW_KEY_DELETE = 0x7f, + TW_KEY_UP = 273, // same codes and order as SDL 1.2 keysym.sym + TW_KEY_DOWN, + TW_KEY_RIGHT, + TW_KEY_LEFT, + TW_KEY_INSERT, + TW_KEY_HOME, + TW_KEY_END, + TW_KEY_PAGE_UP, + TW_KEY_PAGE_DOWN, + TW_KEY_F1, + TW_KEY_F2, + TW_KEY_F3, + TW_KEY_F4, + TW_KEY_F5, + TW_KEY_F6, + TW_KEY_F7, + TW_KEY_F8, + TW_KEY_F9, + TW_KEY_F10, + TW_KEY_F11, + TW_KEY_F12, + TW_KEY_F13, + TW_KEY_F14, + TW_KEY_F15, + TW_KEY_LAST +} TwKeySpecial; + +TW_API int TW_CALL TwKeyPressed(int key, int modifiers); +TW_API int TW_CALL TwKeyTest(int key, int modifiers); + +typedef enum ETwMouseAction +{ + TW_MOUSE_RELEASED, + TW_MOUSE_PRESSED +} TwMouseAction; +typedef enum ETwMouseButtonID +{ + TW_MOUSE_LEFT = 1, // same code as SDL_BUTTON_LEFT + TW_MOUSE_MIDDLE = 2, // same code as SDL_BUTTON_MIDDLE + TW_MOUSE_RIGHT = 3 // same code as SDL_BUTTON_RIGHT +} TwMouseButtonID; + +TW_API int TW_CALL TwMouseButton(TwMouseAction action, TwMouseButtonID button); +TW_API int TW_CALL TwMouseMotion(int mouseX, int mouseY); +TW_API int TW_CALL TwMouseWheel(int pos); + +TW_API const char * TW_CALL TwGetLastError(); +typedef void (TW_CALL * TwErrorHandler)(const char *errorMessage); +TW_API void TW_CALL TwHandleErrors(TwErrorHandler errorHandler); + + +// ---------------------------------------------------------------------------- +// Helper functions to translate events from some common window management +// frameworks to AntTweakBar. +// They call TwKeyPressed, TwMouse* and TwWindowSize for you (implemented in +// files TwEventWin.c TwEventSDL*.c TwEventGLFW.c TwEventGLUT.c) +// ---------------------------------------------------------------------------- + +// For Windows message proc +#ifndef _W64 // Microsoft specific (detection of 64 bits portability issues) +# define _W64 +#endif // _W64 +#ifdef _WIN64 + TW_API int TW_CALL TwEventWin(void *wnd, unsigned int msg, unsigned __int64 _W64 wParam, __int64 _W64 lParam); +#else + TW_API int TW_CALL TwEventWin(void *wnd, unsigned int msg, unsigned int _W64 wParam, int _W64 lParam); +#endif +#define TwEventWin32 TwEventWin // For compatibility with AntTweakBar versions prior to 1.11 + +// For libSDL event loop +TW_API int TW_CALL TwEventSDL(const void *sdlEvent, unsigned char sdlMajorVersion, unsigned char sdlMinorVersion); + +// For GLFW event callbacks +// You should define GLFW_CDECL before including AntTweakBar.h if your version of GLFW uses cdecl calling convensions +#ifdef GLFW_CDECL + TW_API int TW_CDECL_CALL TwEventMouseButtonGLFWcdecl(int glfwButton, int glfwAction); + TW_API int TW_CDECL_CALL TwEventKeyGLFWcdecl(int glfwKey, int glfwAction); + TW_API int TW_CDECL_CALL TwEventCharGLFWcdecl(int glfwChar, int glfwAction); + TW_API int TW_CDECL_CALL TwEventMousePosGLFWcdecl(int mouseX, int mouseY); + TW_API int TW_CDECL_CALL TwEventMouseWheelGLFWcdecl(int wheelPos); +# define TwEventMouseButtonGLFW TwEventMouseButtonGLFWcdecl +# define TwEventKeyGLFW TwEventKeyGLFWcdecl +# define TwEventCharGLFW TwEventCharGLFWcdecl +# define TwEventMousePosGLFW TwEventMousePosGLFWcdecl +# define TwEventMouseWheelGLFW TwEventMouseWheelGLFWcdecl +#else + TW_API int TW_CALL TwEventMouseButtonGLFW(int glfwButton, int glfwAction); + TW_API int TW_CALL TwEventKeyGLFW(int glfwKey, int glfwAction); + TW_API int TW_CALL TwEventCharGLFW(int glfwChar, int glfwAction); +# define TwEventMousePosGLFW TwMouseMotion +# define TwEventMouseWheelGLFW TwMouseWheel +#endif + +// For GLUT event callbacks (Windows calling convention for GLUT callbacks is cdecl) +#if defined(_WIN32) || defined(_WIN64) +# define TW_GLUT_CALL TW_CDECL_CALL +#else +# define TW_GLUT_CALL +#endif +TW_API int TW_GLUT_CALL TwEventMouseButtonGLUT(int glutButton, int glutState, int mouseX, int mouseY); +TW_API int TW_GLUT_CALL TwEventMouseMotionGLUT(int mouseX, int mouseY); +TW_API int TW_GLUT_CALL TwEventKeyboardGLUT(unsigned char glutKey, int mouseX, int mouseY); +TW_API int TW_GLUT_CALL TwEventSpecialGLUT(int glutKey, int mouseX, int mouseY); +TW_API int TW_CALL TwGLUTModifiersFunc(int (TW_CALL *glutGetModifiersFunc)(void)); +typedef void (TW_GLUT_CALL *GLUTmousebuttonfun)(int glutButton, int glutState, int mouseX, int mouseY); +typedef void (TW_GLUT_CALL *GLUTmousemotionfun)(int mouseX, int mouseY); +typedef void (TW_GLUT_CALL *GLUTkeyboardfun)(unsigned char glutKey, int mouseX, int mouseY); +typedef void (TW_GLUT_CALL *GLUTspecialfun)(int glutKey, int mouseX, int mouseY); + +// For SFML event loop +TW_API int TW_CALL TwEventSFML(const void *sfmlEvent, unsigned char sfmlMajorVersion, unsigned char sfmlMinorVersion); + +// For X11 event loop +#if defined(_UNIX) + TW_API int TW_CDECL_CALL TwEventX11(void *xevent); +#endif + +// ---------------------------------------------------------------------------- +// Make sure the types have the right sizes +// ---------------------------------------------------------------------------- + +#define TW_COMPILE_TIME_ASSERT(name, x) typedef int TW_DUMMY_ ## name[(x) * 2 - 1] + +TW_COMPILE_TIME_ASSERT(TW_CHAR, sizeof(char) == 1); +TW_COMPILE_TIME_ASSERT(TW_SHORT, sizeof(short) == 2); +TW_COMPILE_TIME_ASSERT(TW_INT, sizeof(int) == 4); +TW_COMPILE_TIME_ASSERT(TW_FLOAT, sizeof(float) == 4); +TW_COMPILE_TIME_ASSERT(TW_DOUBLE, sizeof(double) == 8); + +// Check pointer size on Windows +#if !defined(_WIN64) && defined(_WIN32) + // If the following assert failed, the platform is not 32-bit and _WIN64 is not defined. + // When targetting 64-bit Windows platform, _WIN64 must be defined. + TW_COMPILE_TIME_ASSERT(TW_PTR32, sizeof(void*) == 4); +#elif defined(_WIN64) + // If the following assert failed, _WIN64 is defined but the targeted platform is not 64-bit. + TW_COMPILE_TIME_ASSERT(TW_PTR64, sizeof(void*) == 8); +#endif + +// --------------------------------------------------------------------------- + + +#ifdef __cplusplus + } // extern "C" +#endif // __cplusplus + + +#endif // !defined TW_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/AntPerfTimer.h b/Extras/CDTestFramework/AntTweakBar/src/AntPerfTimer.h new file mode 100644 index 0000000..5771270 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/AntPerfTimer.h @@ -0,0 +1,56 @@ +// --------------------------------------------------------------------------- +// +// @file AntPerfTimer.h +// @brief A performance (precision) timer for benchs +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: No cpp file is needed, everything is defined in this header +// +// --------------------------------------------------------------------------- + +#if !defined ANT_PERF_TIMER_INCLUDED +#define ANT_PERF_TIMER_INCLUDED + +#ifndef __cplusplus +# error This is a C++ header +#endif // __cplusplus + + +#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64) + + #include + #include + + struct PerfTimer + { + inline PerfTimer() { if( !QueryPerformanceFrequency(&Freq) ) MessageBox(NULL, _T("Precision timer not supported"), _T("Problem"), MB_ICONEXCLAMATION); Reset(); } + inline void Reset() { QueryPerformanceCounter(&Start); } + inline double GetTime() { if( QueryPerformanceCounter(&End) ) return ((double)End.QuadPart - (double)Start.QuadPart)/((double)Freq.QuadPart); else return 0; } + protected: + LARGE_INTEGER Start, End, Freq; + }; + +#else // !_WIN (-> LINUX) + + #include + #include + + struct PerfTimer + { + inline PerfTimer() { Reset(); } + inline void Reset() { gettimeofday(&Start, &TZ); } + inline double GetTime() { gettimeofday(&End,&TZ); + double t1 = (double)Start.tv_sec + (double)Start.tv_usec/(1000*1000); + double t2 = (double)End.tv_sec + (double)End.tv_usec/(1000*1000); + return t2-t1; } + protected: + struct timeval Start, End; + struct timezone TZ; + }; + +#endif // _WIN + + +#endif // ANT_PERF_TIMER_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.rc b/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.rc new file mode 100644 index 0000000..8ff7072 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.rc @@ -0,0 +1,83 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +//#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Français (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +//LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +IDC_CURSOR1 CURSOR "res\\cur00013.cur" +IDC_CURSOR2 CURSOR "res\\cur00000.cur" +IDC_CURSOR3 CURSOR "res\\cur00001.cur" +IDC_CURSOR4 CURSOR "res\\cur00002.cur" +IDC_CURSOR5 CURSOR "res\\cur00003.cur" +IDC_CURSOR6 CURSOR "res\\cur00004.cur" +IDC_CURSOR7 CURSOR "res\\cur00005.cur" +IDC_CURSOR8 CURSOR "res\\cur00006.cur" +IDC_CURSOR9 CURSOR "res\\cur00007.cur" +IDC_CURSOR10 CURSOR "res\\cur00008.cur" +IDC_CURSOR11 CURSOR "res\\cur00009.cur" +IDC_CURSOR12 CURSOR "res\\cur00010.cur" +IDC_CURSOR13 CURSOR "res\\cur00011.cur" +IDC_CURSOR14 CURSOR "res\\cur00012.cur" +#endif // Français (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.sln b/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.sln new file mode 100644 index 0000000..46f37d2 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AntTweakBar", "AntTweakBar.vcproj", "{B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug|Win32.ActiveCfg = Debug|Win32 + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug|Win32.Build.0 = Debug|Win32 + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug|x64.ActiveCfg = Debug|x64 + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Debug|x64.Build.0 = Debug|x64 + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release|Win32.ActiveCfg = Release|Win32 + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release|Win32.Build.0 = Release|Win32 + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release|x64.ActiveCfg = Release|x64 + {B99E1FA1-C30A-45F2-9D57-9E9C21B2DF42}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.vcproj b/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.vcproj new file mode 100644 index 0000000..fe42339 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/AntTweakBar.vcproj @@ -0,0 +1,997 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/CDTestFramework/AntTweakBar/src/LoadOGL.cpp b/Extras/CDTestFramework/AntTweakBar/src/LoadOGL.cpp new file mode 100644 index 0000000..24cda1d --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/LoadOGL.cpp @@ -0,0 +1,531 @@ +// --------------------------------------------------------------------------- +// +// @file LoadOGL.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "LoadOGL.h" + + +// --------------------------------------------------------------------------- + +#define ANT_NB_OGL_FUNC_MAX 1024 + +struct COGLFuncRec +{ + const char * m_Name; + GL::PFNOpenGL * m_FuncPtr; + COGLFuncRec() : m_Name(NULL), m_FuncPtr(NULL) {} +}; +COGLFuncRec g_OGLFuncRec[ANT_NB_OGL_FUNC_MAX]; +int g_NbOGLFunc = 0; +#if defined(ANT_WINDOWS) +HMODULE g_OGLModule = NULL; +#endif + +// --------------------------------------------------------------------------- + +ANT_GL_IMPL(glAccum) +ANT_GL_IMPL(glAlphaFunc) +ANT_GL_IMPL(glAreTexturesResident) +ANT_GL_IMPL(glArrayElement) +ANT_GL_IMPL(glBegin) +ANT_GL_IMPL(glBindTexture) +ANT_GL_IMPL(glBitmap) +ANT_GL_IMPL(glBlendFunc) +ANT_GL_IMPL(glCallList) +ANT_GL_IMPL(glCallLists) +ANT_GL_IMPL(glClear) +ANT_GL_IMPL(glClearAccum) +ANT_GL_IMPL(glClearColor) +ANT_GL_IMPL(glClearDepth) +ANT_GL_IMPL(glClearIndex) +ANT_GL_IMPL(glClearStencil) +ANT_GL_IMPL(glClipPlane) +ANT_GL_IMPL(glColor3b) +ANT_GL_IMPL(glColor3bv) +ANT_GL_IMPL(glColor3d) +ANT_GL_IMPL(glColor3dv) +ANT_GL_IMPL(glColor3f) +ANT_GL_IMPL(glColor3fv) +ANT_GL_IMPL(glColor3i) +ANT_GL_IMPL(glColor3iv) +ANT_GL_IMPL(glColor3s) +ANT_GL_IMPL(glColor3sv) +ANT_GL_IMPL(glColor3ub) +ANT_GL_IMPL(glColor3ubv) +ANT_GL_IMPL(glColor3ui) +ANT_GL_IMPL(glColor3uiv) +ANT_GL_IMPL(glColor3us) +ANT_GL_IMPL(glColor3usv) +ANT_GL_IMPL(glColor4b) +ANT_GL_IMPL(glColor4bv) +ANT_GL_IMPL(glColor4d) +ANT_GL_IMPL(glColor4dv) +ANT_GL_IMPL(glColor4f) +ANT_GL_IMPL(glColor4fv) +ANT_GL_IMPL(glColor4i) +ANT_GL_IMPL(glColor4iv) +ANT_GL_IMPL(glColor4s) +ANT_GL_IMPL(glColor4sv) +ANT_GL_IMPL(glColor4ub) +ANT_GL_IMPL(glColor4ubv) +ANT_GL_IMPL(glColor4ui) +ANT_GL_IMPL(glColor4uiv) +ANT_GL_IMPL(glColor4us) +ANT_GL_IMPL(glColor4usv) +ANT_GL_IMPL(glColorMask) +ANT_GL_IMPL(glColorMaterial) +ANT_GL_IMPL(glColorPointer) +ANT_GL_IMPL(glCopyPixels) +ANT_GL_IMPL(glCopyTexImage1D) +ANT_GL_IMPL(glCopyTexImage2D) +ANT_GL_IMPL(glCopyTexSubImage1D) +ANT_GL_IMPL(glCopyTexSubImage2D) +ANT_GL_IMPL(glCullFace) +ANT_GL_IMPL(glDeleteLists) +ANT_GL_IMPL(glDeleteTextures) +ANT_GL_IMPL(glDepthFunc) +ANT_GL_IMPL(glDepthMask) +ANT_GL_IMPL(glDepthRange) +ANT_GL_IMPL(glDisable) +ANT_GL_IMPL(glDisableClientState) +ANT_GL_IMPL(glDrawArrays) +ANT_GL_IMPL(glDrawBuffer) +ANT_GL_IMPL(glDrawElements) +ANT_GL_IMPL(glDrawPixels) +ANT_GL_IMPL(glEdgeFlag) +ANT_GL_IMPL(glEdgeFlagPointer) +ANT_GL_IMPL(glEdgeFlagv) +ANT_GL_IMPL(glEnable) +ANT_GL_IMPL(glEnableClientState) +ANT_GL_IMPL(glEnd) +ANT_GL_IMPL(glEndList) +ANT_GL_IMPL(glEvalCoord1d) +ANT_GL_IMPL(glEvalCoord1dv) +ANT_GL_IMPL(glEvalCoord1f) +ANT_GL_IMPL(glEvalCoord1fv) +ANT_GL_IMPL(glEvalCoord2d) +ANT_GL_IMPL(glEvalCoord2dv) +ANT_GL_IMPL(glEvalCoord2f) +ANT_GL_IMPL(glEvalCoord2fv) +ANT_GL_IMPL(glEvalMesh1) +ANT_GL_IMPL(glEvalMesh2) +ANT_GL_IMPL(glEvalPoint1) +ANT_GL_IMPL(glEvalPoint2) +ANT_GL_IMPL(glFeedbackBuffer) +ANT_GL_IMPL(glFinish) +ANT_GL_IMPL(glFlush) +ANT_GL_IMPL(glFogf) +ANT_GL_IMPL(glFogfv) +ANT_GL_IMPL(glFogi) +ANT_GL_IMPL(glFogiv) +ANT_GL_IMPL(glFrontFace) +ANT_GL_IMPL(glFrustum) +ANT_GL_IMPL(glGenLists) +ANT_GL_IMPL(glGenTextures) +ANT_GL_IMPL(glGetBooleanv) +ANT_GL_IMPL(glGetClipPlane) +ANT_GL_IMPL(glGetDoublev) +ANT_GL_IMPL(glGetError) +ANT_GL_IMPL(glGetFloatv) +ANT_GL_IMPL(glGetIntegerv) +ANT_GL_IMPL(glGetLightfv) +ANT_GL_IMPL(glGetLightiv) +ANT_GL_IMPL(glGetMapdv) +ANT_GL_IMPL(glGetMapfv) +ANT_GL_IMPL(glGetMapiv) +ANT_GL_IMPL(glGetMaterialfv) +ANT_GL_IMPL(glGetMaterialiv) +ANT_GL_IMPL(glGetPixelMapfv) +ANT_GL_IMPL(glGetPixelMapuiv) +ANT_GL_IMPL(glGetPixelMapusv) +ANT_GL_IMPL(glGetPointerv) +ANT_GL_IMPL(glGetPolygonStipple) +ANT_GL_IMPL(glGetString) +ANT_GL_IMPL(glGetTexEnvfv) +ANT_GL_IMPL(glGetTexEnviv) +ANT_GL_IMPL(glGetTexGendv) +ANT_GL_IMPL(glGetTexGenfv) +ANT_GL_IMPL(glGetTexGeniv) +ANT_GL_IMPL(glGetTexImage) +ANT_GL_IMPL(glGetTexLevelParameterfv) +ANT_GL_IMPL(glGetTexLevelParameteriv) +ANT_GL_IMPL(glGetTexParameterfv) +ANT_GL_IMPL(glGetTexParameteriv) +ANT_GL_IMPL(glHint) +ANT_GL_IMPL(glIndexMask) +ANT_GL_IMPL(glIndexPointer) +ANT_GL_IMPL(glIndexd) +ANT_GL_IMPL(glIndexdv) +ANT_GL_IMPL(glIndexf) +ANT_GL_IMPL(glIndexfv) +ANT_GL_IMPL(glIndexi) +ANT_GL_IMPL(glIndexiv) +ANT_GL_IMPL(glIndexs) +ANT_GL_IMPL(glIndexsv) +ANT_GL_IMPL(glIndexub) +ANT_GL_IMPL(glIndexubv) +ANT_GL_IMPL(glInitNames) +ANT_GL_IMPL(glInterleavedArrays) +ANT_GL_IMPL(glIsEnabled) +ANT_GL_IMPL(glIsList) +ANT_GL_IMPL(glIsTexture) +ANT_GL_IMPL(glLightModelf) +ANT_GL_IMPL(glLightModelfv) +ANT_GL_IMPL(glLightModeli) +ANT_GL_IMPL(glLightModeliv) +ANT_GL_IMPL(glLightf) +ANT_GL_IMPL(glLightfv) +ANT_GL_IMPL(glLighti) +ANT_GL_IMPL(glLightiv) +ANT_GL_IMPL(glLineStipple) +ANT_GL_IMPL(glLineWidth) +ANT_GL_IMPL(glListBase) +ANT_GL_IMPL(glLoadIdentity) +ANT_GL_IMPL(glLoadMatrixd) +ANT_GL_IMPL(glLoadMatrixf) +ANT_GL_IMPL(glLoadName) +ANT_GL_IMPL(glLogicOp) +ANT_GL_IMPL(glMap1d) +ANT_GL_IMPL(glMap1f) +ANT_GL_IMPL(glMap2d) +ANT_GL_IMPL(glMap2f) +ANT_GL_IMPL(glMapGrid1d) +ANT_GL_IMPL(glMapGrid1f) +ANT_GL_IMPL(glMapGrid2d) +ANT_GL_IMPL(glMapGrid2f) +ANT_GL_IMPL(glMaterialf) +ANT_GL_IMPL(glMaterialfv) +ANT_GL_IMPL(glMateriali) +ANT_GL_IMPL(glMaterialiv) +ANT_GL_IMPL(glMatrixMode) +ANT_GL_IMPL(glMultMatrixd) +ANT_GL_IMPL(glMultMatrixf) +ANT_GL_IMPL(glNewList) +ANT_GL_IMPL(glNormal3b) +ANT_GL_IMPL(glNormal3bv) +ANT_GL_IMPL(glNormal3d) +ANT_GL_IMPL(glNormal3dv) +ANT_GL_IMPL(glNormal3f) +ANT_GL_IMPL(glNormal3fv) +ANT_GL_IMPL(glNormal3i) +ANT_GL_IMPL(glNormal3iv) +ANT_GL_IMPL(glNormal3s) +ANT_GL_IMPL(glNormal3sv) +ANT_GL_IMPL(glNormalPointer) +ANT_GL_IMPL(glOrtho) +ANT_GL_IMPL(glPassThrough) +ANT_GL_IMPL(glPixelMapfv) +ANT_GL_IMPL(glPixelMapuiv) +ANT_GL_IMPL(glPixelMapusv) +ANT_GL_IMPL(glPixelStoref) +ANT_GL_IMPL(glPixelStorei) +ANT_GL_IMPL(glPixelTransferf) +ANT_GL_IMPL(glPixelTransferi) +ANT_GL_IMPL(glPixelZoom) +ANT_GL_IMPL(glPointSize) +ANT_GL_IMPL(glPolygonMode) +ANT_GL_IMPL(glPolygonOffset) +ANT_GL_IMPL(glPolygonStipple) +ANT_GL_IMPL(glPopAttrib) +ANT_GL_IMPL(glPopClientAttrib) +ANT_GL_IMPL(glPopMatrix) +ANT_GL_IMPL(glPopName) +ANT_GL_IMPL(glPrioritizeTextures) +ANT_GL_IMPL(glPushAttrib) +ANT_GL_IMPL(glPushClientAttrib) +ANT_GL_IMPL(glPushMatrix) +ANT_GL_IMPL(glPushName) +ANT_GL_IMPL(glRasterPos2d) +ANT_GL_IMPL(glRasterPos2dv) +ANT_GL_IMPL(glRasterPos2f) +ANT_GL_IMPL(glRasterPos2fv) +ANT_GL_IMPL(glRasterPos2i) +ANT_GL_IMPL(glRasterPos2iv) +ANT_GL_IMPL(glRasterPos2s) +ANT_GL_IMPL(glRasterPos2sv) +ANT_GL_IMPL(glRasterPos3d) +ANT_GL_IMPL(glRasterPos3dv) +ANT_GL_IMPL(glRasterPos3f) +ANT_GL_IMPL(glRasterPos3fv) +ANT_GL_IMPL(glRasterPos3i) +ANT_GL_IMPL(glRasterPos3iv) +ANT_GL_IMPL(glRasterPos3s) +ANT_GL_IMPL(glRasterPos3sv) +ANT_GL_IMPL(glRasterPos4d) +ANT_GL_IMPL(glRasterPos4dv) +ANT_GL_IMPL(glRasterPos4f) +ANT_GL_IMPL(glRasterPos4fv) +ANT_GL_IMPL(glRasterPos4i) +ANT_GL_IMPL(glRasterPos4iv) +ANT_GL_IMPL(glRasterPos4s) +ANT_GL_IMPL(glRasterPos4sv) +ANT_GL_IMPL(glReadBuffer) +ANT_GL_IMPL(glReadPixels) +ANT_GL_IMPL(glRectd) +ANT_GL_IMPL(glRectdv) +ANT_GL_IMPL(glRectf) +ANT_GL_IMPL(glRectfv) +ANT_GL_IMPL(glRecti) +ANT_GL_IMPL(glRectiv) +ANT_GL_IMPL(glRects) +ANT_GL_IMPL(glRectsv) +ANT_GL_IMPL(glRenderMode) +ANT_GL_IMPL(glRotated) +ANT_GL_IMPL(glRotatef) +ANT_GL_IMPL(glScaled) +ANT_GL_IMPL(glScalef) +ANT_GL_IMPL(glScissor) +ANT_GL_IMPL(glSelectBuffer) +ANT_GL_IMPL(glShadeModel) +ANT_GL_IMPL(glStencilFunc) +ANT_GL_IMPL(glStencilMask) +ANT_GL_IMPL(glStencilOp) +ANT_GL_IMPL(glTexCoord1d) +ANT_GL_IMPL(glTexCoord1dv) +ANT_GL_IMPL(glTexCoord1f) +ANT_GL_IMPL(glTexCoord1fv) +ANT_GL_IMPL(glTexCoord1i) +ANT_GL_IMPL(glTexCoord1iv) +ANT_GL_IMPL(glTexCoord1s) +ANT_GL_IMPL(glTexCoord1sv) +ANT_GL_IMPL(glTexCoord2d) +ANT_GL_IMPL(glTexCoord2dv) +ANT_GL_IMPL(glTexCoord2f) +ANT_GL_IMPL(glTexCoord2fv) +ANT_GL_IMPL(glTexCoord2i) +ANT_GL_IMPL(glTexCoord2iv) +ANT_GL_IMPL(glTexCoord2s) +ANT_GL_IMPL(glTexCoord2sv) +ANT_GL_IMPL(glTexCoord3d) +ANT_GL_IMPL(glTexCoord3dv) +ANT_GL_IMPL(glTexCoord3f) +ANT_GL_IMPL(glTexCoord3fv) +ANT_GL_IMPL(glTexCoord3i) +ANT_GL_IMPL(glTexCoord3iv) +ANT_GL_IMPL(glTexCoord3s) +ANT_GL_IMPL(glTexCoord3sv) +ANT_GL_IMPL(glTexCoord4d) +ANT_GL_IMPL(glTexCoord4dv) +ANT_GL_IMPL(glTexCoord4f) +ANT_GL_IMPL(glTexCoord4fv) +ANT_GL_IMPL(glTexCoord4i) +ANT_GL_IMPL(glTexCoord4iv) +ANT_GL_IMPL(glTexCoord4s) +ANT_GL_IMPL(glTexCoord4sv) +ANT_GL_IMPL(glTexCoordPointer) +ANT_GL_IMPL(glTexEnvf) +ANT_GL_IMPL(glTexEnvfv) +ANT_GL_IMPL(glTexEnvi) +ANT_GL_IMPL(glTexEnviv) +ANT_GL_IMPL(glTexGend) +ANT_GL_IMPL(glTexGendv) +ANT_GL_IMPL(glTexGenf) +ANT_GL_IMPL(glTexGenfv) +ANT_GL_IMPL(glTexGeni) +ANT_GL_IMPL(glTexGeniv) +ANT_GL_IMPL(glTexImage1D) +ANT_GL_IMPL(glTexImage2D) +ANT_GL_IMPL(glTexParameterf) +ANT_GL_IMPL(glTexParameterfv) +ANT_GL_IMPL(glTexParameteri) +ANT_GL_IMPL(glTexParameteriv) +ANT_GL_IMPL(glTexSubImage1D) +ANT_GL_IMPL(glTexSubImage2D) +ANT_GL_IMPL(glTranslated) +ANT_GL_IMPL(glTranslatef) +ANT_GL_IMPL(glVertex2d) +ANT_GL_IMPL(glVertex2dv) +ANT_GL_IMPL(glVertex2f) +ANT_GL_IMPL(glVertex2fv) +ANT_GL_IMPL(glVertex2i) +ANT_GL_IMPL(glVertex2iv) +ANT_GL_IMPL(glVertex2s) +ANT_GL_IMPL(glVertex2sv) +ANT_GL_IMPL(glVertex3d) +ANT_GL_IMPL(glVertex3dv) +ANT_GL_IMPL(glVertex3f) +ANT_GL_IMPL(glVertex3fv) +ANT_GL_IMPL(glVertex3i) +ANT_GL_IMPL(glVertex3iv) +ANT_GL_IMPL(glVertex3s) +ANT_GL_IMPL(glVertex3sv) +ANT_GL_IMPL(glVertex4d) +ANT_GL_IMPL(glVertex4dv) +ANT_GL_IMPL(glVertex4f) +ANT_GL_IMPL(glVertex4fv) +ANT_GL_IMPL(glVertex4i) +ANT_GL_IMPL(glVertex4iv) +ANT_GL_IMPL(glVertex4s) +ANT_GL_IMPL(glVertex4sv) +ANT_GL_IMPL(glVertexPointer) +ANT_GL_IMPL(glViewport) +#if defined(ANT_WINDOWS) +ANT_GL_IMPL(wglGetProcAddress) +#endif + +namespace GL { PFNGLGetProcAddress _glGetProcAddress = NULL; } + +// --------------------------------------------------------------------------- + +#if defined(ANT_WINDOWS) + + // --------------------------------------------------------------------------- + + int LoadOpenGL() + { + if( g_OGLModule!=NULL ) + { + return 1; // "OpenGL library already loaded" + } + + g_OGLModule = LoadLibrary("OPENGL32.DLL"); + if( g_OGLModule ) + { + // Info(VERB_LOW, "Load %d OpenGL functions", g_NbOGLFunc); + + int Res = 1; + for(int i=0; i0); + *(g_OGLFuncRec[i].m_FuncPtr) = reinterpret_cast(GetProcAddress(g_OGLModule, g_OGLFuncRec[i].m_Name)); + if( *(g_OGLFuncRec[i].m_FuncPtr)==NULL ) + Res = 0; // Error("cannot find OpenGL function"); + + } + + _glGetProcAddress = reinterpret_cast(_wglGetProcAddress); + if( _glGetProcAddress==NULL ) + Res = 0; + + return Res; + } + else + { + // InternDisplayLastErrorWIN("Cannot load opengl32 DLL", false); + return 0; // cannot load DLL + } + } + + // --------------------------------------------------------------------------- + + int UnloadOpenGL() + { + if( g_OGLModule==NULL ) + { + return 1; // "OpenGL library not loaded" + } + + // Info(VERB_LOW, "Unload %d OpenGL functions", g_NbOGLFunc); + for(int i=0; i0); + *(g_OGLFuncRec[i].m_FuncPtr) = NULL; + } + if( FreeLibrary(g_OGLModule) ) + { + // Info(VERB_LOW, "OpenGL library unloaded"); + g_OGLModule = NULL; + return 1; + } + else + { + // InternDisplayLastErrorWIN("Cannot unload opengl32 DLL", false); + return 0; // cannot unload opengl32.dll + } + } + + // --------------------------------------------------------------------------- + + namespace GL + { + + PFNOpenGL Record(const char *_FuncName, PFNOpenGL *_FuncPtr) + { + if( g_NbOGLFunc>=ANT_NB_OGL_FUNC_MAX ) + { + fprintf(stderr, "Too many OpenGL functions declared. Change ANT_NB_OGL_FUNC_MAX."); + exit(-1); + } + + g_OGLFuncRec[g_NbOGLFunc].m_Name = _FuncName; + g_OGLFuncRec[g_NbOGLFunc].m_FuncPtr = _FuncPtr; + ++g_NbOGLFunc; + + return NULL; + } + + } // namespace GL + + // --------------------------------------------------------------------------- + +#endif // defined(ANT_WINDOWS) + +// --------------------------------------------------------------------------- + +#if defined(ANT_UNIX) + + int LoadOpenGL() + { + _glGetProcAddress = reinterpret_cast(glXGetProcAddressARB); + + return 1; // "OpenGL library is statically linked" + } + + int UnloadOpenGL() + { + return 1; // "OpenGL library is statically linked" + } + +#elif defined(ANT_OSX) + + #include + + static void *gl_dyld = NULL; + void *NSGLGetProcAddressNew(const GLubyte *name) + { + void *proc=NULL; + if (gl_dyld == NULL) + { + gl_dyld = dlopen("OpenGL",RTLD_LAZY); + } + if (gl_dyld) + { + NSString *sym = [[NSString alloc] initWithFormat: @"_%s",name]; + proc = dlsym(gl_dyld,[sym UTF8String]); + [sym release]; + } + return proc; + } + + int LoadOpenGL() + { + _glGetProcAddress = reinterpret_cast(NSGLGetProcAddressNew); + return 1; + } + + int UnloadOpenGL() + { + if (gl_dyld) + { + dlclose(gl_dyld); + gl_dyld = NULL; + } + return 1; + } + +#endif // defined(ANT_UNIX) + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/LoadOGL.h b/Extras/CDTestFramework/AntTweakBar/src/LoadOGL.h new file mode 100644 index 0000000..02e99c2 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/LoadOGL.h @@ -0,0 +1,397 @@ +// --------------------------------------------------------------------------- +// +// @file LoadOGL.h +// @brief OpenGL declarations for dynamic loading +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_LOAD_OGL_INCLUDED +#define ANT_LOAD_OGL_INCLUDED + + +#define ANT_GL_DECL(_Ret, _Fct, _Params) \ + extern "C" { typedef _Ret (APIENTRY* PFN##_Fct)_Params; } \ + namespace GL { extern PFN##_Fct _##_Fct; } \ + using GL::_##_Fct; + +#if defined(ANT_WINDOWS) +# define ANT_GL_IMPL(_Fct) \ + namespace GL { PFN##_Fct _##_Fct = (PFN##_Fct)Record(#_Fct, (PFNOpenGL*)(&_##_Fct)); } +#elif defined(ANT_UNIX) || defined(ANT_OSX) +# define ANT_GL_IMPL(_Fct) \ + namespace GL { PFN##_Fct _##_Fct = _Fct; } +# if !defined(APIENTRY) +# define APIENTRY +# endif +#endif + + +int LoadOpenGL(); +int UnloadOpenGL(); + +namespace GL +{ + extern "C" { typedef void (APIENTRY* PFNOpenGL)(); } + PFNOpenGL Record(const char *_FuncName, PFNOpenGL *_FuncPtr); + + extern "C" { typedef PFNOpenGL (APIENTRY *PFNGLGetProcAddress)(const char *); } + extern PFNGLGetProcAddress _glGetProcAddress; +} +using GL::_glGetProcAddress; + + +ANT_GL_DECL(void, glAccum, (GLenum op, GLfloat value)) +ANT_GL_DECL(void, glAlphaFunc, (GLenum func, GLclampf ref)) +ANT_GL_DECL(GLboolean, glAreTexturesResident, (GLsizei n, const GLuint *textures, GLboolean *residences)) +ANT_GL_DECL(void, glArrayElement, (GLint i)) +ANT_GL_DECL(void, glBegin, (GLenum mode)) +ANT_GL_DECL(void, glBindTexture, (GLenum target, GLuint texture)) +ANT_GL_DECL(void, glBitmap, (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)) +ANT_GL_DECL(void, glBlendFunc, (GLenum sfactor, GLenum dfactor)) +ANT_GL_DECL(void, glCallList, (GLuint list)) +ANT_GL_DECL(void, glCallLists, (GLsizei n, GLenum type, const GLvoid *lists)) +ANT_GL_DECL(void, glClear, (GLbitfield mask)) +ANT_GL_DECL(void, glClearAccum, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) +ANT_GL_DECL(void, glClearColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) +ANT_GL_DECL(void, glClearDepth, (GLclampd depth)) +ANT_GL_DECL(void, glClearIndex, (GLfloat c)) +ANT_GL_DECL(void, glClearStencil, (GLint s)) +ANT_GL_DECL(void, glClipPlane, (GLenum plane, const GLdouble *equation)) +ANT_GL_DECL(void, glColor3b, (GLbyte red, GLbyte green, GLbyte blue)) +ANT_GL_DECL(void, glColor3bv, (const GLbyte *v)) +ANT_GL_DECL(void, glColor3d, (GLdouble red, GLdouble green, GLdouble blue)) +ANT_GL_DECL(void, glColor3dv, (const GLdouble *v)) +ANT_GL_DECL(void, glColor3f, (GLfloat red, GLfloat green, GLfloat blue)) +ANT_GL_DECL(void, glColor3fv, (const GLfloat *v)) +ANT_GL_DECL(void, glColor3i, (GLint red, GLint green, GLint blue)) +ANT_GL_DECL(void, glColor3iv, (const GLint *v)) +ANT_GL_DECL(void, glColor3s, (GLshort red, GLshort green, GLshort blue)) +ANT_GL_DECL(void, glColor3sv, (const GLshort *v)) +ANT_GL_DECL(void, glColor3ub, (GLubyte red, GLubyte green, GLubyte blue)) +ANT_GL_DECL(void, glColor3ubv, (const GLubyte *v)) +ANT_GL_DECL(void, glColor3ui, (GLuint red, GLuint green, GLuint blue)) +ANT_GL_DECL(void, glColor3uiv, (const GLuint *v)) +ANT_GL_DECL(void, glColor3us, (GLushort red, GLushort green, GLushort blue)) +ANT_GL_DECL(void, glColor3usv, (const GLushort *v)) +ANT_GL_DECL(void, glColor4b, (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)) +ANT_GL_DECL(void, glColor4bv, (const GLbyte *v)) +ANT_GL_DECL(void, glColor4d, (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)) +ANT_GL_DECL(void, glColor4dv, (const GLdouble *v)) +ANT_GL_DECL(void, glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) +ANT_GL_DECL(void, glColor4fv, (const GLfloat *v)) +ANT_GL_DECL(void, glColor4i, (GLint red, GLint green, GLint blue, GLint alpha)) +ANT_GL_DECL(void, glColor4iv, (const GLint *v)) +ANT_GL_DECL(void, glColor4s, (GLshort red, GLshort green, GLshort blue, GLshort alpha)) +ANT_GL_DECL(void, glColor4sv, (const GLshort *v)) +ANT_GL_DECL(void, glColor4ub, (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) +ANT_GL_DECL(void, glColor4ubv, (const GLubyte *v)) +ANT_GL_DECL(void, glColor4ui, (GLuint red, GLuint green, GLuint blue, GLuint alpha)) +ANT_GL_DECL(void, glColor4uiv, (const GLuint *v)) +ANT_GL_DECL(void, glColor4us, (GLushort red, GLushort green, GLushort blue, GLushort alpha)) +ANT_GL_DECL(void, glColor4usv, (const GLushort *v)) +ANT_GL_DECL(void, glColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) +ANT_GL_DECL(void, glColorMaterial, (GLenum face, GLenum mode)) +ANT_GL_DECL(void, glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +ANT_GL_DECL(void, glCopyPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)) +ANT_GL_DECL(void, glCopyTexImage1D, (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)) +ANT_GL_DECL(void, glCopyTexImage2D, (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) +ANT_GL_DECL(void, glCopyTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) +ANT_GL_DECL(void, glCopyTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) +ANT_GL_DECL(void, glCullFace, (GLenum mode)) +ANT_GL_DECL(void, glDeleteLists, (GLuint list, GLsizei range)) +ANT_GL_DECL(void, glDeleteTextures, (GLsizei n, const GLuint *textures)) +ANT_GL_DECL(void, glDepthFunc, (GLenum func)) +ANT_GL_DECL(void, glDepthMask, (GLboolean flag)) +ANT_GL_DECL(void, glDepthRange, (GLclampd zNear, GLclampd zFar)) +ANT_GL_DECL(void, glDisable, (GLenum cap)) +ANT_GL_DECL(void, glDisableClientState, (GLenum array)) +ANT_GL_DECL(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count)) +ANT_GL_DECL(void, glDrawBuffer, (GLenum mode)) +ANT_GL_DECL(void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) +ANT_GL_DECL(void, glDrawPixels, (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_DECL(void, glEdgeFlag, (GLboolean flag)) +ANT_GL_DECL(void, glEdgeFlagPointer, (GLsizei stride, const void *pointer)) +ANT_GL_DECL(void, glEdgeFlagv, (const GLboolean *flag)) +ANT_GL_DECL(void, glEnable, (GLenum cap)) +ANT_GL_DECL(void, glEnableClientState, (GLenum array)) +ANT_GL_DECL(void, glEnd, (void)) +ANT_GL_DECL(void, glEndList, (void)) +ANT_GL_DECL(void, glEvalCoord1d, (GLdouble u)) +ANT_GL_DECL(void, glEvalCoord1dv, (const GLdouble *u)) +ANT_GL_DECL(void, glEvalCoord1f, (GLfloat u)) +ANT_GL_DECL(void, glEvalCoord1fv, (const GLfloat *u)) +ANT_GL_DECL(void, glEvalCoord2d, (GLdouble u, GLdouble v)) +ANT_GL_DECL(void, glEvalCoord2dv, (const GLdouble *u)) +ANT_GL_DECL(void, glEvalCoord2f, (GLfloat u, GLfloat v)) +ANT_GL_DECL(void, glEvalCoord2fv, (const GLfloat *u)) +ANT_GL_DECL(void, glEvalMesh1, (GLenum mode, GLint i1, GLint i2)) +ANT_GL_DECL(void, glEvalMesh2, (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)) +ANT_GL_DECL(void, glEvalPoint1, (GLint i)) +ANT_GL_DECL(void, glEvalPoint2, (GLint i, GLint j)) +ANT_GL_DECL(void, glFeedbackBuffer, (GLsizei size, GLenum type, GLfloat *buffer)) +ANT_GL_DECL(void, glFinish, (void)) +ANT_GL_DECL(void, glFlush, (void)) +ANT_GL_DECL(void, glFogf, (GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glFogfv, (GLenum pname, const GLfloat *params)) +ANT_GL_DECL(void, glFogi, (GLenum pname, GLint param)) +ANT_GL_DECL(void, glFogiv, (GLenum pname, const GLint *params)) +ANT_GL_DECL(void, glFrontFace, (GLenum mode)) +ANT_GL_DECL(void, glFrustum, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) +ANT_GL_DECL(GLuint, glGenLists, (GLsizei range)) +ANT_GL_DECL(void, glGenTextures, (GLsizei n, GLuint *textures)) +ANT_GL_DECL(void, glGetBooleanv, (GLenum pname, GLboolean *params)) +ANT_GL_DECL(void, glGetClipPlane, (GLenum plane, GLdouble *equation)) +ANT_GL_DECL(void, glGetDoublev, (GLenum pname, GLdouble *params)) +ANT_GL_DECL(GLenum, glGetError, (void)) +ANT_GL_DECL(void, glGetFloatv, (GLenum pname, GLfloat *params)) +ANT_GL_DECL(void, glGetIntegerv, (GLenum pname, GLint *params)) +ANT_GL_DECL(void, glGetLightfv, (GLenum light, GLenum pname, GLfloat *params)) +ANT_GL_DECL(void, glGetLightiv, (GLenum light, GLenum pname, GLint *params)) +ANT_GL_DECL(void, glGetMapdv, (GLenum target, GLenum query, GLdouble *v)) +ANT_GL_DECL(void, glGetMapfv, (GLenum target, GLenum query, GLfloat *v)) +ANT_GL_DECL(void, glGetMapiv, (GLenum target, GLenum query, GLint *v)) +ANT_GL_DECL(void, glGetMaterialfv, (GLenum face, GLenum pname, GLfloat *params)) +ANT_GL_DECL(void, glGetMaterialiv, (GLenum face, GLenum pname, GLint *params)) +ANT_GL_DECL(void, glGetPixelMapfv, (GLenum map, GLfloat *values)) +ANT_GL_DECL(void, glGetPixelMapuiv, (GLenum map, GLuint *values)) +ANT_GL_DECL(void, glGetPixelMapusv, (GLenum map, GLushort *values)) +ANT_GL_DECL(void, glGetPointerv, (GLenum pname, GLvoid* *params)) +ANT_GL_DECL(void, glGetPolygonStipple, (GLubyte *mask)) +ANT_GL_DECL(const GLubyte *, glGetString, (GLenum name)) +ANT_GL_DECL(void, glGetTexEnvfv, (GLenum target, GLenum pname, GLfloat *params)) +ANT_GL_DECL(void, glGetTexEnviv, (GLenum target, GLenum pname, GLint *params)) +ANT_GL_DECL(void, glGetTexGendv, (GLenum coord, GLenum pname, GLdouble *params)) +ANT_GL_DECL(void, glGetTexGenfv, (GLenum coord, GLenum pname, GLfloat *params)) +ANT_GL_DECL(void, glGetTexGeniv, (GLenum coord, GLenum pname, GLint *params)) +ANT_GL_DECL(void, glGetTexImage, (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)) +ANT_GL_DECL(void, glGetTexLevelParameterfv, (GLenum target, GLint level, GLenum pname, GLfloat *params)) +ANT_GL_DECL(void, glGetTexLevelParameteriv, (GLenum target, GLint level, GLenum pname, GLint *params)) +ANT_GL_DECL(void, glGetTexParameterfv, (GLenum target, GLenum pname, GLfloat *params)) +ANT_GL_DECL(void, glGetTexParameteriv, (GLenum target, GLenum pname, GLint *params)) +ANT_GL_DECL(void, glHint, (GLenum target, GLenum mode)) +ANT_GL_DECL(void, glIndexMask, (GLuint mask)) +ANT_GL_DECL(void, glIndexPointer, (GLenum type, GLsizei stride, const GLvoid *pointer)) +ANT_GL_DECL(void, glIndexd, (GLdouble c)) +ANT_GL_DECL(void, glIndexdv, (const GLdouble *c)) +ANT_GL_DECL(void, glIndexf, (GLfloat c)) +ANT_GL_DECL(void, glIndexfv, (const GLfloat *c)) +ANT_GL_DECL(void, glIndexi, (GLint c)) +ANT_GL_DECL(void, glIndexiv, (const GLint *c)) +ANT_GL_DECL(void, glIndexs, (GLshort c)) +ANT_GL_DECL(void, glIndexsv, (const GLshort *c)) +ANT_GL_DECL(void, glIndexub, (GLubyte c)) +ANT_GL_DECL(void, glIndexubv, (const GLubyte *c)) +ANT_GL_DECL(void, glInitNames, (void)) +ANT_GL_DECL(void, glInterleavedArrays, (GLenum format, GLsizei stride, const GLvoid *pointer)) +ANT_GL_DECL(GLboolean, glIsEnabled, (GLenum cap)) +ANT_GL_DECL(GLboolean, glIsList, (GLuint list)) +ANT_GL_DECL(GLboolean, glIsTexture, (GLuint texture)) +ANT_GL_DECL(void, glLightModelf, (GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glLightModelfv, (GLenum pname, const GLfloat *params)) +ANT_GL_DECL(void, glLightModeli, (GLenum pname, GLint param)) +ANT_GL_DECL(void, glLightModeliv, (GLenum pname, const GLint *params)) +ANT_GL_DECL(void, glLightf, (GLenum light, GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glLightfv, (GLenum light, GLenum pname, const GLfloat *params)) +ANT_GL_DECL(void, glLighti, (GLenum light, GLenum pname, GLint param)) +ANT_GL_DECL(void, glLightiv, (GLenum light, GLenum pname, const GLint *params)) +ANT_GL_DECL(void, glLineStipple, (GLint factor, GLushort pattern)) +ANT_GL_DECL(void, glLineWidth, (GLfloat width)) +ANT_GL_DECL(void, glListBase, (GLuint base)) +ANT_GL_DECL(void, glLoadIdentity, (void)) +ANT_GL_DECL(void, glLoadMatrixd, (const GLdouble *m)) +ANT_GL_DECL(void, glLoadMatrixf, (const GLfloat *m)) +ANT_GL_DECL(void, glLoadName, (GLuint name)) +ANT_GL_DECL(void, glLogicOp, (GLenum opcode)) +ANT_GL_DECL(void, glMap1d, (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) +ANT_GL_DECL(void, glMap1f, (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) +ANT_GL_DECL(void, glMap2d, (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) +ANT_GL_DECL(void, glMap2f, (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) +ANT_GL_DECL(void, glMapGrid1d, (GLint un, GLdouble u1, GLdouble u2)) +ANT_GL_DECL(void, glMapGrid1f, (GLint un, GLfloat u1, GLfloat u2)) +ANT_GL_DECL(void, glMapGrid2d, (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)) +ANT_GL_DECL(void, glMapGrid2f, (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)) +ANT_GL_DECL(void, glMaterialf, (GLenum face, GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glMaterialfv, (GLenum face, GLenum pname, const GLfloat *params)) +ANT_GL_DECL(void, glMateriali, (GLenum face, GLenum pname, GLint param)) +ANT_GL_DECL(void, glMaterialiv, (GLenum face, GLenum pname, const GLint *params)) +ANT_GL_DECL(void, glMatrixMode, (GLenum mode)) +ANT_GL_DECL(void, glMultMatrixd, (const GLdouble *m)) +ANT_GL_DECL(void, glMultMatrixf, (const GLfloat *m)) +ANT_GL_DECL(void, glNewList, (GLuint list, GLenum mode)) +ANT_GL_DECL(void, glNormal3b, (GLbyte nx, GLbyte ny, GLbyte nz)) +ANT_GL_DECL(void, glNormal3bv, (const GLbyte *v)) +ANT_GL_DECL(void, glNormal3d, (GLdouble nx, GLdouble ny, GLdouble nz)) +ANT_GL_DECL(void, glNormal3dv, (const GLdouble *v)) +ANT_GL_DECL(void, glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz)) +ANT_GL_DECL(void, glNormal3fv, (const GLfloat *v)) +ANT_GL_DECL(void, glNormal3i, (GLint nx, GLint ny, GLint nz)) +ANT_GL_DECL(void, glNormal3iv, (const GLint *v)) +ANT_GL_DECL(void, glNormal3s, (GLshort nx, GLshort ny, GLshort nz)) +ANT_GL_DECL(void, glNormal3sv, (const GLshort *v)) +ANT_GL_DECL(void, glNormalPointer, (GLenum type, GLsizei stride, const GLvoid *pointer)) +ANT_GL_DECL(void, glOrtho, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) +ANT_GL_DECL(void, glPassThrough, (GLfloat token)) +ANT_GL_DECL(void, glPixelMapfv, (GLenum map, GLsizei mapsize, const GLfloat *values)) +ANT_GL_DECL(void, glPixelMapuiv, (GLenum map, GLsizei mapsize, const GLuint *values)) +ANT_GL_DECL(void, glPixelMapusv, (GLenum map, GLsizei mapsize, const GLushort *values)) +ANT_GL_DECL(void, glPixelStoref, (GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glPixelStorei, (GLenum pname, GLint param)) +ANT_GL_DECL(void, glPixelTransferf, (GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glPixelTransferi, (GLenum pname, GLint param)) +ANT_GL_DECL(void, glPixelZoom, (GLfloat xfactor, GLfloat yfactor)) +ANT_GL_DECL(void, glPointSize, (GLfloat size)) +ANT_GL_DECL(void, glPolygonMode, (GLenum face, GLenum mode)) +ANT_GL_DECL(void, glPolygonOffset, (GLfloat factor, GLfloat units)) +ANT_GL_DECL(void, glPolygonStipple, (const GLubyte *mask)) +ANT_GL_DECL(void, glPopAttrib, (void)) +ANT_GL_DECL(void, glPopClientAttrib, (void)) +ANT_GL_DECL(void, glPopMatrix, (void)) +ANT_GL_DECL(void, glPopName, (void)) +ANT_GL_DECL(void, glPrioritizeTextures, (GLsizei n, const GLuint *textures, const GLclampf *priorities)) +ANT_GL_DECL(void, glPushAttrib, (GLbitfield mask)) +ANT_GL_DECL(void, glPushClientAttrib, (GLbitfield mask)) +ANT_GL_DECL(void, glPushMatrix, (void)) +ANT_GL_DECL(void, glPushName, (GLuint name)) +ANT_GL_DECL(void, glRasterPos2d, (GLdouble x, GLdouble y)) +ANT_GL_DECL(void, glRasterPos2dv, (const GLdouble *v)) +ANT_GL_DECL(void, glRasterPos2f, (GLfloat x, GLfloat y)) +ANT_GL_DECL(void, glRasterPos2fv, (const GLfloat *v)) +ANT_GL_DECL(void, glRasterPos2i, (GLint x, GLint y)) +ANT_GL_DECL(void, glRasterPos2iv, (const GLint *v)) +ANT_GL_DECL(void, glRasterPos2s, (GLshort x, GLshort y)) +ANT_GL_DECL(void, glRasterPos2sv, (const GLshort *v)) +ANT_GL_DECL(void, glRasterPos3d, (GLdouble x, GLdouble y, GLdouble z)) +ANT_GL_DECL(void, glRasterPos3dv, (const GLdouble *v)) +ANT_GL_DECL(void, glRasterPos3f, (GLfloat x, GLfloat y, GLfloat z)) +ANT_GL_DECL(void, glRasterPos3fv, (const GLfloat *v)) +ANT_GL_DECL(void, glRasterPos3i, (GLint x, GLint y, GLint z)) +ANT_GL_DECL(void, glRasterPos3iv, (const GLint *v)) +ANT_GL_DECL(void, glRasterPos3s, (GLshort x, GLshort y, GLshort z)) +ANT_GL_DECL(void, glRasterPos3sv, (const GLshort *v)) +ANT_GL_DECL(void, glRasterPos4d, (GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +ANT_GL_DECL(void, glRasterPos4dv, (const GLdouble *v)) +ANT_GL_DECL(void, glRasterPos4f, (GLfloat x, GLfloat y, GLfloat z, GLfloat w)) +ANT_GL_DECL(void, glRasterPos4fv, (const GLfloat *v)) +ANT_GL_DECL(void, glRasterPos4i, (GLint x, GLint y, GLint z, GLint w)) +ANT_GL_DECL(void, glRasterPos4iv, (const GLint *v)) +ANT_GL_DECL(void, glRasterPos4s, (GLshort x, GLshort y, GLshort z, GLshort w)) +ANT_GL_DECL(void, glRasterPos4sv, (const GLshort *v)) +ANT_GL_DECL(void, glReadBuffer, (GLenum mode)) +ANT_GL_DECL(void, glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) +ANT_GL_DECL(void, glRectd, (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) +ANT_GL_DECL(void, glRectdv, (const GLdouble *v1, const GLdouble *v2)) +ANT_GL_DECL(void, glRectf, (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) +ANT_GL_DECL(void, glRectfv, (const GLfloat *v1, const GLfloat *v2)) +ANT_GL_DECL(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2)) +ANT_GL_DECL(void, glRectiv, (const GLint *v1, const GLint *v2)) +ANT_GL_DECL(void, glRects, (GLshort x1, GLshort y1, GLshort x2, GLshort y2)) +ANT_GL_DECL(void, glRectsv, (const GLshort *v1, const GLshort *v2)) +ANT_GL_DECL(GLint, glRenderMode, (GLenum mode)) +ANT_GL_DECL(void, glRotated, (GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) +ANT_GL_DECL(void, glRotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) +ANT_GL_DECL(void, glScaled, (GLdouble x, GLdouble y, GLdouble z)) +ANT_GL_DECL(void, glScalef, (GLfloat x, GLfloat y, GLfloat z)) +ANT_GL_DECL(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height)) +ANT_GL_DECL(void, glSelectBuffer, (GLsizei size, GLuint *buffer)) +ANT_GL_DECL(void, glShadeModel, (GLenum mode)) +ANT_GL_DECL(void, glStencilFunc, (GLenum func, GLint ref, GLuint mask)) +ANT_GL_DECL(void, glStencilMask, (GLuint mask)) +ANT_GL_DECL(void, glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass)) +ANT_GL_DECL(void, glTexCoord1d, (GLdouble s)) +ANT_GL_DECL(void, glTexCoord1dv, (const GLdouble *v)) +ANT_GL_DECL(void, glTexCoord1f, (GLfloat s)) +ANT_GL_DECL(void, glTexCoord1fv, (const GLfloat *v)) +ANT_GL_DECL(void, glTexCoord1i, (GLint s)) +ANT_GL_DECL(void, glTexCoord1iv, (const GLint *v)) +ANT_GL_DECL(void, glTexCoord1s, (GLshort s)) +ANT_GL_DECL(void, glTexCoord1sv, (const GLshort *v)) +ANT_GL_DECL(void, glTexCoord2d, (GLdouble s, GLdouble t)) +ANT_GL_DECL(void, glTexCoord2dv, (const GLdouble *v)) +ANT_GL_DECL(void, glTexCoord2f, (GLfloat s, GLfloat t)) +ANT_GL_DECL(void, glTexCoord2fv, (const GLfloat *v)) +ANT_GL_DECL(void, glTexCoord2i, (GLint s, GLint t)) +ANT_GL_DECL(void, glTexCoord2iv, (const GLint *v)) +ANT_GL_DECL(void, glTexCoord2s, (GLshort s, GLshort t)) +ANT_GL_DECL(void, glTexCoord2sv, (const GLshort *v)) +ANT_GL_DECL(void, glTexCoord3d, (GLdouble s, GLdouble t, GLdouble r)) +ANT_GL_DECL(void, glTexCoord3dv, (const GLdouble *v)) +ANT_GL_DECL(void, glTexCoord3f, (GLfloat s, GLfloat t, GLfloat r)) +ANT_GL_DECL(void, glTexCoord3fv, (const GLfloat *v)) +ANT_GL_DECL(void, glTexCoord3i, (GLint s, GLint t, GLint r)) +ANT_GL_DECL(void, glTexCoord3iv, (const GLint *v)) +ANT_GL_DECL(void, glTexCoord3s, (GLshort s, GLshort t, GLshort r)) +ANT_GL_DECL(void, glTexCoord3sv, (const GLshort *v)) +ANT_GL_DECL(void, glTexCoord4d, (GLdouble s, GLdouble t, GLdouble r, GLdouble q)) +ANT_GL_DECL(void, glTexCoord4dv, (const GLdouble *v)) +ANT_GL_DECL(void, glTexCoord4f, (GLfloat s, GLfloat t, GLfloat r, GLfloat q)) +ANT_GL_DECL(void, glTexCoord4fv, (const GLfloat *v)) +ANT_GL_DECL(void, glTexCoord4i, (GLint s, GLint t, GLint r, GLint q)) +ANT_GL_DECL(void, glTexCoord4iv, (const GLint *v)) +ANT_GL_DECL(void, glTexCoord4s, (GLshort s, GLshort t, GLshort r, GLshort q)) +ANT_GL_DECL(void, glTexCoord4sv, (const GLshort *v)) +ANT_GL_DECL(void, glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +ANT_GL_DECL(void, glTexEnvf, (GLenum target, GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glTexEnvfv, (GLenum target, GLenum pname, const GLfloat *params)) +ANT_GL_DECL(void, glTexEnvi, (GLenum target, GLenum pname, GLint param)) +ANT_GL_DECL(void, glTexEnviv, (GLenum target, GLenum pname, const GLint *params)) +ANT_GL_DECL(void, glTexGend, (GLenum coord, GLenum pname, GLdouble param)) +ANT_GL_DECL(void, glTexGendv, (GLenum coord, GLenum pname, const GLdouble *params)) +ANT_GL_DECL(void, glTexGenf, (GLenum coord, GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glTexGenfv, (GLenum coord, GLenum pname, const GLfloat *params)) +ANT_GL_DECL(void, glTexGeni, (GLenum coord, GLenum pname, GLint param)) +ANT_GL_DECL(void, glTexGeniv, (GLenum coord, GLenum pname, const GLint *params)) +#if defined(ANT_OSX) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1070) +// Mac OSX < 10.7 redefines these OpenGL calls: glTexImage1D, glTexImage2D +ANT_GL_DECL(void, glTexImage1D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_DECL(void, glTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +#else +ANT_GL_DECL(void, glTexImage1D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_DECL(void, glTexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +#endif +ANT_GL_DECL(void, glTexParameterf, (GLenum target, GLenum pname, GLfloat param)) +ANT_GL_DECL(void, glTexParameterfv, (GLenum target, GLenum pname, const GLfloat *params)) +ANT_GL_DECL(void, glTexParameteri, (GLenum target, GLenum pname, GLint param)) +ANT_GL_DECL(void, glTexParameteriv, (GLenum target, GLenum pname, const GLint *params)) +ANT_GL_DECL(void, glTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_DECL(void, glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_DECL(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z)) +ANT_GL_DECL(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z)) +ANT_GL_DECL(void, glVertex2d, (GLdouble x, GLdouble y)) +ANT_GL_DECL(void, glVertex2dv, (const GLdouble *v)) +ANT_GL_DECL(void, glVertex2f, (GLfloat x, GLfloat y)) +ANT_GL_DECL(void, glVertex2fv, (const GLfloat *v)) +ANT_GL_DECL(void, glVertex2i, (GLint x, GLint y)) +ANT_GL_DECL(void, glVertex2iv, (const GLint *v)) +ANT_GL_DECL(void, glVertex2s, (GLshort x, GLshort y)) +ANT_GL_DECL(void, glVertex2sv, (const GLshort *v)) +ANT_GL_DECL(void, glVertex3d, (GLdouble x, GLdouble y, GLdouble z)) +ANT_GL_DECL(void, glVertex3dv, (const GLdouble *v)) +ANT_GL_DECL(void, glVertex3f, (GLfloat x, GLfloat y, GLfloat z)) +ANT_GL_DECL(void, glVertex3fv, (const GLfloat *v)) +ANT_GL_DECL(void, glVertex3i, (GLint x, GLint y, GLint z)) +ANT_GL_DECL(void, glVertex3iv, (const GLint *v)) +ANT_GL_DECL(void, glVertex3s, (GLshort x, GLshort y, GLshort z)) +ANT_GL_DECL(void, glVertex3sv, (const GLshort *v)) +ANT_GL_DECL(void, glVertex4d, (GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +ANT_GL_DECL(void, glVertex4dv, (const GLdouble *v)) +ANT_GL_DECL(void, glVertex4f, (GLfloat x, GLfloat y, GLfloat z, GLfloat w)) +ANT_GL_DECL(void, glVertex4fv, (const GLfloat *v)) +ANT_GL_DECL(void, glVertex4i, (GLint x, GLint y, GLint z, GLint w)) +ANT_GL_DECL(void, glVertex4iv, (const GLint *v)) +ANT_GL_DECL(void, glVertex4s, (GLshort x, GLshort y, GLshort z, GLshort w)) +ANT_GL_DECL(void, glVertex4sv, (const GLshort *v)) +ANT_GL_DECL(void, glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +ANT_GL_DECL(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height)) + +#ifdef ANT_WINDOWS +ANT_GL_DECL(PROC, wglGetProcAddress, (LPCSTR)) +#endif + + +#endif // !defined ANT_LOAD_OGL_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.cpp b/Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.cpp new file mode 100644 index 0000000..7ebe2d5 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.cpp @@ -0,0 +1,527 @@ +// --------------------------------------------------------------------------- +// +// @file LoadOGLCore.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "LoadOGLCore.h" + +// --------------------------------------------------------------------------- + +#define ANT_NB_OGL_CORE_FUNC_MAX 512 + +struct COGLCoreFuncRec +{ + const char * m_Name; + GLCore::PFNOpenGL * m_FuncPtr; + COGLCoreFuncRec() : m_Name(NULL), m_FuncPtr(NULL) {} +}; +COGLCoreFuncRec g_OGLCoreFuncRec[ANT_NB_OGL_CORE_FUNC_MAX]; +int g_NbOGLCoreFunc = 0; +#if defined(ANT_WINDOWS) +HMODULE g_OGLCoreModule = NULL; +#endif + +// --------------------------------------------------------------------------- + +// GL 1.0 +ANT_GL_CORE_IMPL(glCullFace) +ANT_GL_CORE_IMPL(glFrontFace) +ANT_GL_CORE_IMPL(glHint) +ANT_GL_CORE_IMPL(glLineWidth) +ANT_GL_CORE_IMPL(glPointSize) +ANT_GL_CORE_IMPL(glPolygonMode) +ANT_GL_CORE_IMPL(glScissor) +ANT_GL_CORE_IMPL(glTexParameterf) +ANT_GL_CORE_IMPL(glTexParameterfv) +ANT_GL_CORE_IMPL(glTexParameteri) +ANT_GL_CORE_IMPL(glTexParameteriv) +ANT_GL_CORE_IMPL(glTexImage1D) +ANT_GL_CORE_IMPL(glTexImage2D) +ANT_GL_CORE_IMPL(glDrawBuffer) +ANT_GL_CORE_IMPL(glClear) +ANT_GL_CORE_IMPL(glClearColor) +ANT_GL_CORE_IMPL(glClearStencil) +ANT_GL_CORE_IMPL(glClearDepth) +ANT_GL_CORE_IMPL(glStencilMask) +ANT_GL_CORE_IMPL(glColorMask) +ANT_GL_CORE_IMPL(glDepthMask) +ANT_GL_CORE_IMPL(glDisable) +ANT_GL_CORE_IMPL(glEnable) +ANT_GL_CORE_IMPL(glFinish) +ANT_GL_CORE_IMPL(glFlush) +ANT_GL_CORE_IMPL(glBlendFunc) +ANT_GL_CORE_IMPL(glLogicOp) +ANT_GL_CORE_IMPL(glStencilFunc) +ANT_GL_CORE_IMPL(glStencilOp) +ANT_GL_CORE_IMPL(glDepthFunc) +ANT_GL_CORE_IMPL(glPixelStoref) +ANT_GL_CORE_IMPL(glPixelStorei) +ANT_GL_CORE_IMPL(glReadBuffer) +ANT_GL_CORE_IMPL(glReadPixels) +ANT_GL_CORE_IMPL(glGetBooleanv) +ANT_GL_CORE_IMPL(glGetDoublev) +ANT_GL_CORE_IMPL(glGetError) +ANT_GL_CORE_IMPL(glGetFloatv) +ANT_GL_CORE_IMPL(glGetIntegerv) +ANT_GL_CORE_IMPL(glGetString) +ANT_GL_CORE_IMPL(glGetTexImage) +ANT_GL_CORE_IMPL(glGetTexParameterfv) +ANT_GL_CORE_IMPL(glGetTexParameteriv) +ANT_GL_CORE_IMPL(glGetTexLevelParameterfv) +ANT_GL_CORE_IMPL(glGetTexLevelParameteriv) +ANT_GL_CORE_IMPL(glIsEnabled) +ANT_GL_CORE_IMPL(glDepthRange) +ANT_GL_CORE_IMPL(glViewport) +// GL 1.1 +ANT_GL_CORE_IMPL(glDrawArrays) +ANT_GL_CORE_IMPL(glDrawElements) +ANT_GL_CORE_IMPL(glGetPointerv) +ANT_GL_CORE_IMPL(glPolygonOffset) +ANT_GL_CORE_IMPL(glCopyTexImage1D) +ANT_GL_CORE_IMPL(glCopyTexImage2D) +ANT_GL_CORE_IMPL(glCopyTexSubImage1D) +ANT_GL_CORE_IMPL(glCopyTexSubImage2D) +ANT_GL_CORE_IMPL(glTexSubImage1D) +ANT_GL_CORE_IMPL(glTexSubImage2D) +ANT_GL_CORE_IMPL(glBindTexture) +ANT_GL_CORE_IMPL(glDeleteTextures) +ANT_GL_CORE_IMPL(glGenTextures) +ANT_GL_CORE_IMPL(glIsTexture) +// GL 1.2 +ANT_GL_CORE_IMPL(glBlendColor) +ANT_GL_CORE_IMPL(glBlendEquation) +ANT_GL_CORE_IMPL(glDrawRangeElements) +ANT_GL_CORE_IMPL(glTexImage3D) +ANT_GL_CORE_IMPL(glTexSubImage3D) +ANT_GL_CORE_IMPL(glCopyTexSubImage3D) +// GL 1.3 +ANT_GL_CORE_IMPL(glActiveTexture) +ANT_GL_CORE_IMPL(glSampleCoverage) +ANT_GL_CORE_IMPL(glCompressedTexImage3D) +ANT_GL_CORE_IMPL(glCompressedTexImage2D) +ANT_GL_CORE_IMPL(glCompressedTexImage1D) +ANT_GL_CORE_IMPL(glCompressedTexSubImage3D) +ANT_GL_CORE_IMPL(glCompressedTexSubImage2D) +ANT_GL_CORE_IMPL(glCompressedTexSubImage1D) +ANT_GL_CORE_IMPL(glGetCompressedTexImage) +// GL 1.4 +ANT_GL_CORE_IMPL(glBlendFuncSeparate) +ANT_GL_CORE_IMPL(glMultiDrawArrays) +ANT_GL_CORE_IMPL(glMultiDrawElements) +ANT_GL_CORE_IMPL(glPointParameterf) +ANT_GL_CORE_IMPL(glPointParameterfv) +ANT_GL_CORE_IMPL(glPointParameteri) +ANT_GL_CORE_IMPL(glPointParameteriv) +// GL 1.5 +ANT_GL_CORE_IMPL(glGenQueries) +ANT_GL_CORE_IMPL(glDeleteQueries) +ANT_GL_CORE_IMPL(glIsQuery) +ANT_GL_CORE_IMPL(glBeginQuery) +ANT_GL_CORE_IMPL(glEndQuery) +ANT_GL_CORE_IMPL(glGetQueryiv) +ANT_GL_CORE_IMPL(glGetQueryObjectiv) +ANT_GL_CORE_IMPL(glGetQueryObjectuiv) +ANT_GL_CORE_IMPL(glBindBuffer) +ANT_GL_CORE_IMPL(glDeleteBuffers) +ANT_GL_CORE_IMPL(glGenBuffers) +ANT_GL_CORE_IMPL(glIsBuffer) +ANT_GL_CORE_IMPL(glBufferData) +ANT_GL_CORE_IMPL(glBufferSubData) +ANT_GL_CORE_IMPL(glGetBufferSubData) +ANT_GL_CORE_IMPL(glMapBuffer) +ANT_GL_CORE_IMPL(glUnmapBuffer) +ANT_GL_CORE_IMPL(glGetBufferParameteriv) +ANT_GL_CORE_IMPL(glGetBufferPointerv) +// GL 2.0 +ANT_GL_CORE_IMPL(glBlendEquationSeparate) +ANT_GL_CORE_IMPL(glDrawBuffers) +ANT_GL_CORE_IMPL(glStencilOpSeparate) +ANT_GL_CORE_IMPL(glStencilFuncSeparate) +ANT_GL_CORE_IMPL(glStencilMaskSeparate) +ANT_GL_CORE_IMPL(glAttachShader) +ANT_GL_CORE_IMPL(glBindAttribLocation) +ANT_GL_CORE_IMPL(glCompileShader) +ANT_GL_CORE_IMPL(glCreateProgram) +ANT_GL_CORE_IMPL(glCreateShader) +ANT_GL_CORE_IMPL(glDeleteProgram) +ANT_GL_CORE_IMPL(glDeleteShader) +ANT_GL_CORE_IMPL(glDetachShader) +ANT_GL_CORE_IMPL(glDisableVertexAttribArray) +ANT_GL_CORE_IMPL(glEnableVertexAttribArray) +ANT_GL_CORE_IMPL(glGetActiveAttrib) +ANT_GL_CORE_IMPL(glGetActiveUniform) +ANT_GL_CORE_IMPL(glGetAttachedShaders) +ANT_GL_CORE_IMPL(glGetAttribLocation) +ANT_GL_CORE_IMPL(glGetProgramiv) +ANT_GL_CORE_IMPL(glGetProgramInfoLog) +ANT_GL_CORE_IMPL(glGetShaderiv) +ANT_GL_CORE_IMPL(glGetShaderInfoLog) +ANT_GL_CORE_IMPL(glGetShaderSource) +ANT_GL_CORE_IMPL(glGetUniformLocation) +ANT_GL_CORE_IMPL(glGetUniformfv) +ANT_GL_CORE_IMPL(glGetUniformiv) +ANT_GL_CORE_IMPL(glGetVertexAttribdv) +ANT_GL_CORE_IMPL(glGetVertexAttribfv) +ANT_GL_CORE_IMPL(glGetVertexAttribiv) +ANT_GL_CORE_IMPL(glGetVertexAttribPointerv) +ANT_GL_CORE_IMPL(glIsProgram) +ANT_GL_CORE_IMPL(glIsShader) +ANT_GL_CORE_IMPL(glLinkProgram) +ANT_GL_CORE_IMPL(glShaderSource) +ANT_GL_CORE_IMPL(glUseProgram) +ANT_GL_CORE_IMPL(glUniform1f) +ANT_GL_CORE_IMPL(glUniform2f) +ANT_GL_CORE_IMPL(glUniform3f) +ANT_GL_CORE_IMPL(glUniform4f) +ANT_GL_CORE_IMPL(glUniform1i) +ANT_GL_CORE_IMPL(glUniform2i) +ANT_GL_CORE_IMPL(glUniform3i) +ANT_GL_CORE_IMPL(glUniform4i) +ANT_GL_CORE_IMPL(glUniform1fv) +ANT_GL_CORE_IMPL(glUniform2fv) +ANT_GL_CORE_IMPL(glUniform3fv) +ANT_GL_CORE_IMPL(glUniform4fv) +ANT_GL_CORE_IMPL(glUniform1iv) +ANT_GL_CORE_IMPL(glUniform2iv) +ANT_GL_CORE_IMPL(glUniform3iv) +ANT_GL_CORE_IMPL(glUniform4iv) +ANT_GL_CORE_IMPL(glUniformMatrix2fv) +ANT_GL_CORE_IMPL(glUniformMatrix3fv) +ANT_GL_CORE_IMPL(glUniformMatrix4fv) +ANT_GL_CORE_IMPL(glValidateProgram) +ANT_GL_CORE_IMPL(glVertexAttrib1d) +ANT_GL_CORE_IMPL(glVertexAttrib1dv) +ANT_GL_CORE_IMPL(glVertexAttrib1f) +ANT_GL_CORE_IMPL(glVertexAttrib1fv) +ANT_GL_CORE_IMPL(glVertexAttrib1s) +ANT_GL_CORE_IMPL(glVertexAttrib1sv) +ANT_GL_CORE_IMPL(glVertexAttrib2d) +ANT_GL_CORE_IMPL(glVertexAttrib2dv) +ANT_GL_CORE_IMPL(glVertexAttrib2f) +ANT_GL_CORE_IMPL(glVertexAttrib2fv) +ANT_GL_CORE_IMPL(glVertexAttrib2s) +ANT_GL_CORE_IMPL(glVertexAttrib2sv) +ANT_GL_CORE_IMPL(glVertexAttrib3d) +ANT_GL_CORE_IMPL(glVertexAttrib3dv) +ANT_GL_CORE_IMPL(glVertexAttrib3f) +ANT_GL_CORE_IMPL(glVertexAttrib3fv) +ANT_GL_CORE_IMPL(glVertexAttrib3s) +ANT_GL_CORE_IMPL(glVertexAttrib3sv) +ANT_GL_CORE_IMPL(glVertexAttrib4Nbv) +ANT_GL_CORE_IMPL(glVertexAttrib4Niv) +ANT_GL_CORE_IMPL(glVertexAttrib4Nsv) +ANT_GL_CORE_IMPL(glVertexAttrib4Nub) +ANT_GL_CORE_IMPL(glVertexAttrib4Nubv) +ANT_GL_CORE_IMPL(glVertexAttrib4Nuiv) +ANT_GL_CORE_IMPL(glVertexAttrib4Nusv) +ANT_GL_CORE_IMPL(glVertexAttrib4bv) +ANT_GL_CORE_IMPL(glVertexAttrib4d) +ANT_GL_CORE_IMPL(glVertexAttrib4dv) +ANT_GL_CORE_IMPL(glVertexAttrib4f) +ANT_GL_CORE_IMPL(glVertexAttrib4fv) +ANT_GL_CORE_IMPL(glVertexAttrib4iv) +ANT_GL_CORE_IMPL(glVertexAttrib4s) +ANT_GL_CORE_IMPL(glVertexAttrib4sv) +ANT_GL_CORE_IMPL(glVertexAttrib4ubv) +ANT_GL_CORE_IMPL(glVertexAttrib4uiv) +ANT_GL_CORE_IMPL(glVertexAttrib4usv) +ANT_GL_CORE_IMPL(glVertexAttribPointer) +/* +// GL 2.1 +ANT_GL_CORE_IMPL(glUniformMatrix2x3fv) +ANT_GL_CORE_IMPL(glUniformMatrix3x2fv) +ANT_GL_CORE_IMPL(glUniformMatrix2x4fv) +ANT_GL_CORE_IMPL(glUniformMatrix4x2fv) +ANT_GL_CORE_IMPL(glUniformMatrix3x4fv) +ANT_GL_CORE_IMPL(glUniformMatrix4x3fv) +// GL 3.0 +ANT_GL_CORE_IMPL(glColorMaski) +ANT_GL_CORE_IMPL(glGetBooleani_v) +ANT_GL_CORE_IMPL(glGetIntegeri_v) +ANT_GL_CORE_IMPL(glEnablei) +ANT_GL_CORE_IMPL(glDisablei) +ANT_GL_CORE_IMPL(glIsEnabledi) +ANT_GL_CORE_IMPL(glBeginTransformFeedback) +ANT_GL_CORE_IMPL(glEndTransformFeedback) +ANT_GL_CORE_IMPL(glBindBufferRange) +ANT_GL_CORE_IMPL(glBindBufferBase) +ANT_GL_CORE_IMPL(glTransformFeedbackVaryings) +ANT_GL_CORE_IMPL(glGetTransformFeedbackVarying) +ANT_GL_CORE_IMPL(glClampColor) +ANT_GL_CORE_IMPL(glBeginConditionalRender) +ANT_GL_CORE_IMPL(glEndConditionalRender) +ANT_GL_CORE_IMPL(glVertexAttribIPointer) +ANT_GL_CORE_IMPL(glGetVertexAttribIiv) +ANT_GL_CORE_IMPL(glGetVertexAttribIuiv) +ANT_GL_CORE_IMPL(glVertexAttribI1i) +ANT_GL_CORE_IMPL(glVertexAttribI2i) +ANT_GL_CORE_IMPL(glVertexAttribI3i) +ANT_GL_CORE_IMPL(glVertexAttribI4i) +ANT_GL_CORE_IMPL(glVertexAttribI1ui) +ANT_GL_CORE_IMPL(glVertexAttribI2ui) +ANT_GL_CORE_IMPL(glVertexAttribI3ui) +ANT_GL_CORE_IMPL(glVertexAttribI4ui) +ANT_GL_CORE_IMPL(glVertexAttribI1iv) +ANT_GL_CORE_IMPL(glVertexAttribI2iv) +ANT_GL_CORE_IMPL(glVertexAttribI3iv) +ANT_GL_CORE_IMPL(glVertexAttribI4iv) +ANT_GL_CORE_IMPL(glVertexAttribI1uiv) +ANT_GL_CORE_IMPL(glVertexAttribI2uiv) +ANT_GL_CORE_IMPL(glVertexAttribI3uiv) +ANT_GL_CORE_IMPL(glVertexAttribI4uiv) +ANT_GL_CORE_IMPL(glVertexAttribI4bv) +ANT_GL_CORE_IMPL(glVertexAttribI4sv) +ANT_GL_CORE_IMPL(glVertexAttribI4ubv) +ANT_GL_CORE_IMPL(glVertexAttribI4usv) +ANT_GL_CORE_IMPL(glGetUniformuiv) +ANT_GL_CORE_IMPL(glBindFragDataLocation) +ANT_GL_CORE_IMPL(glGetFragDataLocation) +ANT_GL_CORE_IMPL(glUniform1ui) +ANT_GL_CORE_IMPL(glUniform2ui) +ANT_GL_CORE_IMPL(glUniform3ui) +ANT_GL_CORE_IMPL(glUniform4ui) +ANT_GL_CORE_IMPL(glUniform1uiv) +ANT_GL_CORE_IMPL(glUniform2uiv) +ANT_GL_CORE_IMPL(glUniform3uiv) +ANT_GL_CORE_IMPL(glUniform4uiv) +ANT_GL_CORE_IMPL(glTexParameterIiv) +ANT_GL_CORE_IMPL(glTexParameterIuiv) +ANT_GL_CORE_IMPL(glGetTexParameterIiv) +ANT_GL_CORE_IMPL(glGetTexParameterIuiv) +ANT_GL_CORE_IMPL(glClearBufferiv) +ANT_GL_CORE_IMPL(glClearBufferuiv) +ANT_GL_CORE_IMPL(glClearBufferfv) +ANT_GL_CORE_IMPL(glClearBufferfi) +ANT_GL_CORE_IMPL(glGetStringi) +// GL 3.1 +ANT_GL_CORE_IMPL(glDrawArraysInstanced) +ANT_GL_CORE_IMPL(glDrawElementsInstanced) +ANT_GL_CORE_IMPL(glTexBuffer) +ANT_GL_CORE_IMPL(glPrimitiveRestartIndex) +// GL 3.2 +//ANT_GL_CORE_IMPL(glGetInteger64i_v) +//ANT_GL_CORE_IMPL(glGetBufferParameteri64v) +ANT_GL_CORE_IMPL(glFramebufferTexture) +*/ + +// GL_ARB_vertex_array_object +#if defined(ANT_WINDOWS) + ANT_GL_CORE_IMPL(glBindVertexArray) + ANT_GL_CORE_IMPL(glDeleteVertexArrays) + ANT_GL_CORE_IMPL(glGenVertexArrays) + ANT_GL_CORE_IMPL(glIsVertexArray) +#else + // these extensions are loaded explicitely by LoadOpenGLCore + // because they may not be avialable on non-OpenGL 3.2 environments + namespace GLCore + { + PFNglBindVertexArray _glBindVertexArray = NULL; + PFNglDeleteVertexArrays _glDeleteVertexArrays = NULL; + PFNglGenVertexArrays _glGenVertexArrays = NULL; + PFNglIsVertexArray _glIsVertexArray = NULL; + } +#endif + +#if defined(ANT_WINDOWS) + ANT_GL_CORE_IMPL(wglGetProcAddress) +#endif + +namespace GLCore { PFNGLGetProcAddress _glGetProcAddress = NULL; } + +// --------------------------------------------------------------------------- + +#if defined(ANT_WINDOWS) + + // --------------------------------------------------------------------------- + + int LoadOpenGLCore() + { + if( g_OGLCoreModule!=NULL ) + { + return 1; // "OpenGL library already loaded" + } + + g_OGLCoreModule = LoadLibrary("OPENGL32.DLL"); + if( g_OGLCoreModule ) + { + // Info(VERB_LOW, "Load %d OpenGL Core functions", g_NbOGLCoreFunc); + + int Res = 1; + + // Use wglGetProcAddress to retreive Core functions + _glGetProcAddress = reinterpret_cast(GetProcAddress(g_OGLCoreModule, "wglGetProcAddress")); + if( _glGetProcAddress!=NULL ) + for(int i=0; i0); + // Try to get the function pointer with wglGetProcAddress + *(g_OGLCoreFuncRec[i].m_FuncPtr) = reinterpret_cast(_glGetProcAddress(g_OGLCoreFuncRec[i].m_Name)); + if( *(g_OGLCoreFuncRec[i].m_FuncPtr)==NULL ) + { + // Try to get the function pointer with GetProcAddress + *(g_OGLCoreFuncRec[i].m_FuncPtr) = reinterpret_cast(GetProcAddress(g_OGLCoreModule, g_OGLCoreFuncRec[i].m_Name)); + if( *(g_OGLCoreFuncRec[i].m_FuncPtr)==NULL ) + { + #ifdef _DEBUG + fprintf(stderr, "AntTweakBar: Cannot load function %s\n", g_OGLCoreFuncRec[i].m_Name); + #endif + Res = 0; // Error("cannot find OpenGL Core function"); + } + } + + } + + return Res; + } + else + { + // InternDisplayLastErrorWIN("Cannot load opengl32 DLL", false); + return 0; // cannot load DLL + } + } + + // --------------------------------------------------------------------------- + + int UnloadOpenGLCore() + { + if( g_OGLCoreModule==NULL ) + { + return 1; // "OpenGL library not loaded" + } + + // Info(VERB_LOW, "Unload %d OpenGL Core functions", g_NbOGLCoreFunc); + for(int i=0; i0); + *(g_OGLCoreFuncRec[i].m_FuncPtr) = NULL; + } + if( FreeLibrary(g_OGLCoreModule) ) + { + // Info(VERB_LOW, "OpenGL library unloaded"); + g_OGLCoreModule = NULL; + return 1; + } + else + { + // InternDisplayLastErrorWIN("Cannot unload opengl32 DLL", false); + return 0; // cannot unload opengl32.dll + } + } + + // --------------------------------------------------------------------------- + + namespace GLCore + { + + PFNOpenGL Record(const char *_FuncName, PFNOpenGL *_FuncPtr) + { + if( g_NbOGLCoreFunc>=ANT_NB_OGL_CORE_FUNC_MAX ) + { + fprintf(stderr, "Too many OpenGL Core functions declared. Change ANT_NB_OGL_CORE_FUNC_MAX."); + exit(-1); + } + + g_OGLCoreFuncRec[g_NbOGLCoreFunc].m_Name = _FuncName; + g_OGLCoreFuncRec[g_NbOGLCoreFunc].m_FuncPtr = _FuncPtr; + ++g_NbOGLCoreFunc; + + return NULL; + } + + } // namespace GL + + // --------------------------------------------------------------------------- + +#endif // defined(ANT_WINDOWS) + +// --------------------------------------------------------------------------- + +#if defined(ANT_UNIX) + + int LoadOpenGLCore() + { + _glGetProcAddress = reinterpret_cast(glXGetProcAddressARB); + + _glBindVertexArray = reinterpret_cast(_glGetProcAddress("glBindVertexArray")); + _glDeleteVertexArrays = reinterpret_cast(_glGetProcAddress("glDeleteVertexArrays")); + _glGenVertexArrays = reinterpret_cast(_glGetProcAddress("glGenVertexArrays")); + _glIsVertexArray = reinterpret_cast(_glGetProcAddress("glIsVertexArray")); + + if( _glBindVertexArray==NULL || _glDeleteVertexArrays==NULL || _glGenVertexArrays==NULL || _glIsVertexArray==NULL ) + { + fprintf(stderr, "AntTweakBar: OpenGL Core Profile functions cannot be loaded.\n"); + return 0; + } + else + return 1; + } + + int UnloadOpenGLCore() + { + return 1; + } + +#elif defined(ANT_OSX) + + #include + + static void *gl_dyld = NULL; + void *NSGLCoreGetProcAddressNew(const GLubyte *name) + { + void *proc=NULL; + if (gl_dyld == NULL) + { + gl_dyld = dlopen("OpenGL",RTLD_LAZY); + } + if (gl_dyld) + { + NSString *sym = [[NSString alloc] initWithFormat: @"_%s",name]; + proc = dlsym(gl_dyld,[sym UTF8String]); + [sym release]; + } + return proc; + } + + int LoadOpenGLCore() + { + _glGetProcAddress = reinterpret_cast(NSGLCoreGetProcAddressNew); + + _glBindVertexArray = reinterpret_cast(_glGetProcAddress("glBindVertexArray")); + _glDeleteVertexArrays = reinterpret_cast(_glGetProcAddress("glDeleteVertexArrays")); + _glGenVertexArrays = reinterpret_cast(_glGetProcAddress("glGenVertexArrays")); + _glIsVertexArray = reinterpret_cast(_glGetProcAddress("glIsVertexArray")); + + if( _glBindVertexArray==NULL || _glDeleteVertexArrays==NULL || _glGenVertexArrays==NULL || _glIsVertexArray==NULL ) + { + fprintf(stderr, "AntTweakBar: OpenGL Core Profile functions cannot be loaded.\n"); + return 0; + } + else + return 1; + } + + int UnloadOpenGLCore() + { + if (gl_dyld) + { + dlclose(gl_dyld); + gl_dyld = NULL; + } + return 1; + } + +#endif // defined(ANT_UNIX) + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.h b/Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.h new file mode 100644 index 0000000..46a58e9 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/LoadOGLCore.h @@ -0,0 +1,403 @@ +// --------------------------------------------------------------------------- +// +// @file LoadOGLCore.h +// @brief OpenGL Core Profile declarations for dynamic loading +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_LOAD_OGL_CORE_INCLUDED +#define ANT_LOAD_OGL_CORE_INCLUDED + + +#define ANT_GL_CORE_DECL_NO_FORWARD(_Ret, _Fct, _Params) \ + extern "C" { typedef _Ret (APIENTRY* PFN##_Fct)_Params; } \ + namespace GLCore { extern PFN##_Fct _##_Fct; } \ + using GLCore::_##_Fct; + +#if defined(ANT_WINDOWS) +# define ANT_GL_CORE_DECL(_Ret, _Fct, _Params) \ + ANT_GL_CORE_DECL_NO_FORWARD(_Ret, _Fct, _Params) +# define ANT_GL_CORE_IMPL(_Fct) \ + namespace GLCore { PFN##_Fct _##_Fct = (PFN##_Fct)Record(#_Fct, (PFNOpenGL*)(&_##_Fct)); } +#elif defined(ANT_UNIX) || defined(ANT_OSX) +# if !defined(APIENTRY) +# define APIENTRY +# endif +# define ANT_GL_CORE_DECL(_Ret, _Fct, _Params) \ + ANT_GL_CORE_DECL_NO_FORWARD(_Ret, _Fct, _Params) \ + extern "C" { _Ret APIENTRY _Fct _Params; } +# define ANT_GL_CORE_IMPL(_Fct) \ + namespace GLCore { PFN##_Fct _##_Fct = _Fct; } +#endif + + +int LoadOpenGLCore(); +int UnloadOpenGLCore(); + +namespace GLCore +{ + extern "C" { typedef void (APIENTRY* PFNOpenGL)(); } + PFNOpenGL Record(const char *_FuncName, PFNOpenGL *_FuncPtr); + + extern "C" { typedef PFNOpenGL (APIENTRY *PFNGLGetProcAddress)(const char *); } + extern PFNGLGetProcAddress _glGetProcAddress; +} +using GLCore::_glGetProcAddress; + + +// GL 1.0 +ANT_GL_CORE_DECL(void, glCullFace, (GLenum mode)) +ANT_GL_CORE_DECL(void, glFrontFace, (GLenum mode)) +ANT_GL_CORE_DECL(void, glHint, (GLenum target, GLenum mode)) +ANT_GL_CORE_DECL(void, glLineWidth, (GLfloat width)) +ANT_GL_CORE_DECL(void, glPointSize, (GLfloat size)) +ANT_GL_CORE_DECL(void, glPolygonMode, (GLenum face, GLenum mode)) +ANT_GL_CORE_DECL(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height)) +ANT_GL_CORE_DECL(void, glTexParameterf, (GLenum target, GLenum pname, GLfloat param)) +ANT_GL_CORE_DECL(void, glTexParameterfv, (GLenum target, GLenum pname, const GLfloat *params)) +ANT_GL_CORE_DECL(void, glTexParameteri, (GLenum target, GLenum pname, GLint param)) +ANT_GL_CORE_DECL(void, glTexParameteriv, (GLenum target, GLenum pname, const GLint *params)) +#if defined(ANT_OSX) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1070) +// Mac OSX < 10.7 redefines these OpenGL calls: glTexImage1D, glTexImage2D +ANT_GL_CORE_DECL(void, glTexImage1D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_CORE_DECL(void, glTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +#else +ANT_GL_CORE_DECL(void, glTexImage1D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_CORE_DECL(void, glTexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +#endif +ANT_GL_CORE_DECL(void, glDrawBuffer, (GLenum mode)) +ANT_GL_CORE_DECL(void, glClear, (GLbitfield mask)) +ANT_GL_CORE_DECL(void, glClearColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) +ANT_GL_CORE_DECL(void, glClearStencil, (GLint s)) +ANT_GL_CORE_DECL(void, glClearDepth, (GLclampd depth)) +ANT_GL_CORE_DECL(void, glStencilMask, (GLuint mask)) +ANT_GL_CORE_DECL(void, glColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) +ANT_GL_CORE_DECL(void, glDepthMask, (GLboolean flag)) +ANT_GL_CORE_DECL(void, glDisable, (GLenum cap)) +ANT_GL_CORE_DECL(void, glEnable, (GLenum cap)) +ANT_GL_CORE_DECL(void, glFinish, (void)) +ANT_GL_CORE_DECL(void, glFlush, (void)) +ANT_GL_CORE_DECL(void, glBlendFunc, (GLenum sfactor, GLenum dfactor)) +ANT_GL_CORE_DECL(void, glLogicOp, (GLenum opcode)) +ANT_GL_CORE_DECL(void, glStencilFunc, (GLenum func, GLint ref, GLuint mask)) +ANT_GL_CORE_DECL(void, glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass)) +ANT_GL_CORE_DECL(void, glDepthFunc, (GLenum func)) +ANT_GL_CORE_DECL(void, glPixelStoref, (GLenum pname, GLfloat param)) +ANT_GL_CORE_DECL(void, glPixelStorei, (GLenum pname, GLint param)) +ANT_GL_CORE_DECL(void, glReadBuffer, (GLenum mode)) +ANT_GL_CORE_DECL(void, glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) +ANT_GL_CORE_DECL(void, glGetBooleanv, (GLenum pname, GLboolean *params)) +ANT_GL_CORE_DECL(void, glGetDoublev, (GLenum pname, GLdouble *params)) +ANT_GL_CORE_DECL(GLenum, glGetError, (void)) +ANT_GL_CORE_DECL(void, glGetFloatv, (GLenum pname, GLfloat *params)) +ANT_GL_CORE_DECL(void, glGetIntegerv, (GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(const GLubyte *, glGetString, (GLenum name)) +ANT_GL_CORE_DECL(void, glGetTexImage, (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)) +ANT_GL_CORE_DECL(void, glGetTexParameterfv, (GLenum target, GLenum pname, GLfloat *params)) +ANT_GL_CORE_DECL(void, glGetTexParameteriv, (GLenum target, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetTexLevelParameterfv, (GLenum target, GLint level, GLenum pname, GLfloat *params)) +ANT_GL_CORE_DECL(void, glGetTexLevelParameteriv, (GLenum target, GLint level, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(GLboolean, glIsEnabled, (GLenum cap)) +ANT_GL_CORE_DECL(void, glDepthRange, (GLclampd near, GLclampd far)) +ANT_GL_CORE_DECL(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height)) +// GL 1.1 +ANT_GL_CORE_DECL(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count)) +ANT_GL_CORE_DECL(void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) +ANT_GL_CORE_DECL(void, glGetPointerv, (GLenum pname, GLvoid* *params)) +ANT_GL_CORE_DECL(void, glPolygonOffset, (GLfloat factor, GLfloat units)) +ANT_GL_CORE_DECL(void, glCopyTexImage1D, (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)) +ANT_GL_CORE_DECL(void, glCopyTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) +ANT_GL_CORE_DECL(void, glCopyTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) +ANT_GL_CORE_DECL(void, glCopyTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) +ANT_GL_CORE_DECL(void, glTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_CORE_DECL(void, glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_CORE_DECL(void, glBindTexture, (GLenum target, GLuint texture)) +ANT_GL_CORE_DECL(void, glDeleteTextures, (GLsizei n, const GLuint *textures)) +ANT_GL_CORE_DECL(void, glGenTextures, (GLsizei n, GLuint *textures)) +ANT_GL_CORE_DECL(GLboolean, glIsTexture, (GLuint texture)) +// GL 1.2 +ANT_GL_CORE_DECL(void, glBlendColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) +ANT_GL_CORE_DECL(void, glBlendEquation, (GLenum mode)) +ANT_GL_CORE_DECL(void, glDrawRangeElements, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)) +#if defined(ANT_OSX) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1070) +// Mac OSX < 10.7 redefines this OpenGL call: glTexImage3D +ANT_GL_CORE_DECL(void, glTexImage3D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +#else +ANT_GL_CORE_DECL(void, glTexImage3D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +#endif +ANT_GL_CORE_DECL(void, glTexSubImage3D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)) +ANT_GL_CORE_DECL(void, glCopyTexSubImage3D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)) +// GL 1.3 +ANT_GL_CORE_DECL(void, glActiveTexture, (GLenum texture)) +ANT_GL_CORE_DECL(void, glSampleCoverage, (GLclampf value, GLboolean invert)) +ANT_GL_CORE_DECL(void, glCompressedTexImage3D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data)) +ANT_GL_CORE_DECL(void, glCompressedTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)) +ANT_GL_CORE_DECL(void, glCompressedTexImage1D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data)) +ANT_GL_CORE_DECL(void, glCompressedTexSubImage3D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data)) +ANT_GL_CORE_DECL(void, glCompressedTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)) +ANT_GL_CORE_DECL(void, glCompressedTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data)) +ANT_GL_CORE_DECL(void, glGetCompressedTexImage, (GLenum target, GLint level, GLvoid *img)) +// GL 1.4 +ANT_GL_CORE_DECL(void, glBlendFuncSeparate, (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)) +ANT_GL_CORE_DECL(void, glMultiDrawArrays, (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount)) +ANT_GL_CORE_DECL(void, glMultiDrawElements, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount)) +ANT_GL_CORE_DECL(void, glPointParameterf, (GLenum pname, GLfloat param)) +ANT_GL_CORE_DECL(void, glPointParameterfv, (GLenum pname, const GLfloat *params)) +ANT_GL_CORE_DECL(void, glPointParameteri, (GLenum pname, GLint param)) +ANT_GL_CORE_DECL(void, glPointParameteriv, (GLenum pname, const GLint *params)) +// GL 1.5 +#ifndef ANT_OSX + typedef ptrdiff_t GLintptr; + typedef ptrdiff_t GLsizeiptr; +#endif +ANT_GL_CORE_DECL(void, glGenQueries, (GLsizei n, GLuint *ids)) +ANT_GL_CORE_DECL(void, glDeleteQueries, (GLsizei n, const GLuint *ids)) +ANT_GL_CORE_DECL(GLboolean, glIsQuery, (GLuint id)) +ANT_GL_CORE_DECL(void, glBeginQuery, (GLenum target, GLuint id)) +ANT_GL_CORE_DECL(void, glEndQuery, (GLenum target)) +ANT_GL_CORE_DECL(void, glGetQueryiv, (GLenum target, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetQueryObjectiv, (GLuint id, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetQueryObjectuiv, (GLuint id, GLenum pname, GLuint *params)) +ANT_GL_CORE_DECL(void, glBindBuffer, (GLenum target, GLuint buffer)) +ANT_GL_CORE_DECL(void, glDeleteBuffers, (GLsizei n, const GLuint *buffers)) +ANT_GL_CORE_DECL(void, glGenBuffers, (GLsizei n, GLuint *buffers)) +ANT_GL_CORE_DECL(GLboolean, glIsBuffer, (GLuint buffer)) +ANT_GL_CORE_DECL(void, glBufferData, (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)) +ANT_GL_CORE_DECL(void, glBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)) +ANT_GL_CORE_DECL(void, glGetBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)) +ANT_GL_CORE_DECL(GLvoid*, glMapBuffer, (GLenum target, GLenum access)) +ANT_GL_CORE_DECL(GLboolean, glUnmapBuffer, (GLenum target)) +ANT_GL_CORE_DECL(void, glGetBufferParameteriv, (GLenum target, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetBufferPointerv, (GLenum target, GLenum pname, GLvoid* *params)) +// GL 2.0 +typedef char GLchar; +ANT_GL_CORE_DECL(void, glBlendEquationSeparate, (GLenum modeRGB, GLenum modeAlpha)) +ANT_GL_CORE_DECL(void, glDrawBuffers, (GLsizei n, const GLenum *bufs)) +ANT_GL_CORE_DECL(void, glStencilOpSeparate, (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)) +ANT_GL_CORE_DECL(void, glStencilFuncSeparate, (GLenum face, GLenum func, GLint ref, GLuint mask)) +ANT_GL_CORE_DECL(void, glStencilMaskSeparate, (GLenum face, GLuint mask)) +ANT_GL_CORE_DECL(void, glAttachShader, (GLuint program, GLuint shader)) +ANT_GL_CORE_DECL(void, glBindAttribLocation, (GLuint program, GLuint index, const GLchar *name)) +ANT_GL_CORE_DECL(void, glCompileShader, (GLuint shader)) +ANT_GL_CORE_DECL(GLuint, glCreateProgram, (void)) +ANT_GL_CORE_DECL(GLuint, glCreateShader, (GLenum type)) +ANT_GL_CORE_DECL(void, glDeleteProgram, (GLuint program)) +ANT_GL_CORE_DECL(void, glDeleteShader, (GLuint shader)) +ANT_GL_CORE_DECL(void, glDetachShader, (GLuint program, GLuint shader)) +ANT_GL_CORE_DECL(void, glDisableVertexAttribArray, (GLuint index)) +ANT_GL_CORE_DECL(void, glEnableVertexAttribArray, (GLuint index)) +ANT_GL_CORE_DECL(void, glGetActiveAttrib, (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)) +ANT_GL_CORE_DECL(void, glGetActiveUniform, (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)) +ANT_GL_CORE_DECL(void, glGetAttachedShaders, (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj)) +ANT_GL_CORE_DECL(GLint, glGetAttribLocation, (GLuint program, const GLchar *name)) +ANT_GL_CORE_DECL(void, glGetProgramiv, (GLuint program, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetProgramInfoLog, (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)) +ANT_GL_CORE_DECL(void, glGetShaderiv, (GLuint shader, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetShaderInfoLog, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)) +ANT_GL_CORE_DECL(void, glGetShaderSource, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source)) +ANT_GL_CORE_DECL(GLint, glGetUniformLocation, (GLuint program, const GLchar *name)) +ANT_GL_CORE_DECL(void, glGetUniformfv, (GLuint program, GLint location, GLfloat *params)) +ANT_GL_CORE_DECL(void, glGetUniformiv, (GLuint program, GLint location, GLint *params)) +ANT_GL_CORE_DECL(void, glGetVertexAttribdv, (GLuint index, GLenum pname, GLdouble *params)) +ANT_GL_CORE_DECL(void, glGetVertexAttribfv, (GLuint index, GLenum pname, GLfloat *params)) +ANT_GL_CORE_DECL(void, glGetVertexAttribiv, (GLuint index, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetVertexAttribPointerv, (GLuint index, GLenum pname, GLvoid* *pointer)) +ANT_GL_CORE_DECL(GLboolean, glIsProgram, (GLuint program)) +ANT_GL_CORE_DECL(GLboolean, glIsShader, (GLuint shader)) +ANT_GL_CORE_DECL(void, glLinkProgram, (GLuint program)) +ANT_GL_CORE_DECL(void, glShaderSource, (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length)) +ANT_GL_CORE_DECL(void, glUseProgram, (GLuint program)) +ANT_GL_CORE_DECL(void, glUniform1f, (GLint location, GLfloat v0)) +ANT_GL_CORE_DECL(void, glUniform2f, (GLint location, GLfloat v0, GLfloat v1)) +ANT_GL_CORE_DECL(void, glUniform3f, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2)) +ANT_GL_CORE_DECL(void, glUniform4f, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)) +ANT_GL_CORE_DECL(void, glUniform1i, (GLint location, GLint v0)) +ANT_GL_CORE_DECL(void, glUniform2i, (GLint location, GLint v0, GLint v1)) +ANT_GL_CORE_DECL(void, glUniform3i, (GLint location, GLint v0, GLint v1, GLint v2)) +ANT_GL_CORE_DECL(void, glUniform4i, (GLint location, GLint v0, GLint v1, GLint v2, GLint v3)) +ANT_GL_CORE_DECL(void, glUniform1fv, (GLint location, GLsizei count, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniform2fv, (GLint location, GLsizei count, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniform3fv, (GLint location, GLsizei count, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniform4fv, (GLint location, GLsizei count, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniform1iv, (GLint location, GLsizei count, const GLint *value)) +ANT_GL_CORE_DECL(void, glUniform2iv, (GLint location, GLsizei count, const GLint *value)) +ANT_GL_CORE_DECL(void, glUniform3iv, (GLint location, GLsizei count, const GLint *value)) +ANT_GL_CORE_DECL(void, glUniform4iv, (GLint location, GLsizei count, const GLint *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glValidateProgram, (GLuint program)) +ANT_GL_CORE_DECL(void, glVertexAttrib1d, (GLuint index, GLdouble x)) +ANT_GL_CORE_DECL(void, glVertexAttrib1dv, (GLuint index, const GLdouble *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib1f, (GLuint index, GLfloat x)) +ANT_GL_CORE_DECL(void, glVertexAttrib1fv, (GLuint index, const GLfloat *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib1s, (GLuint index, GLshort x)) +ANT_GL_CORE_DECL(void, glVertexAttrib1sv, (GLuint index, const GLshort *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib2d, (GLuint index, GLdouble x, GLdouble y)) +ANT_GL_CORE_DECL(void, glVertexAttrib2dv, (GLuint index, const GLdouble *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib2f, (GLuint index, GLfloat x, GLfloat y)) +ANT_GL_CORE_DECL(void, glVertexAttrib2fv, (GLuint index, const GLfloat *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib2s, (GLuint index, GLshort x, GLshort y)) +ANT_GL_CORE_DECL(void, glVertexAttrib2sv, (GLuint index, const GLshort *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib3d, (GLuint index, GLdouble x, GLdouble y, GLdouble z)) +ANT_GL_CORE_DECL(void, glVertexAttrib3dv, (GLuint index, const GLdouble *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib3f, (GLuint index, GLfloat x, GLfloat y, GLfloat z)) +ANT_GL_CORE_DECL(void, glVertexAttrib3fv, (GLuint index, const GLfloat *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib3s, (GLuint index, GLshort x, GLshort y, GLshort z)) +ANT_GL_CORE_DECL(void, glVertexAttrib3sv, (GLuint index, const GLshort *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4Nbv, (GLuint index, const GLbyte *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4Niv, (GLuint index, const GLint *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4Nsv, (GLuint index, const GLshort *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4Nub, (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)) +ANT_GL_CORE_DECL(void, glVertexAttrib4Nubv, (GLuint index, const GLubyte *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4Nuiv, (GLuint index, const GLuint *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4Nusv, (GLuint index, const GLushort *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4bv, (GLuint index, const GLbyte *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4d, (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +ANT_GL_CORE_DECL(void, glVertexAttrib4dv, (GLuint index, const GLdouble *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4f, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)) +ANT_GL_CORE_DECL(void, glVertexAttrib4fv, (GLuint index, const GLfloat *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4iv, (GLuint index, const GLint *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4s, (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)) +ANT_GL_CORE_DECL(void, glVertexAttrib4sv, (GLuint index, const GLshort *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4ubv, (GLuint index, const GLubyte *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4uiv, (GLuint index, const GLuint *v)) +ANT_GL_CORE_DECL(void, glVertexAttrib4usv, (GLuint index, const GLushort *v)) +ANT_GL_CORE_DECL(void, glVertexAttribPointer, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer)) +/* +// GL 2.1 +ANT_GL_CORE_DECL(void, glUniformMatrix2x3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix3x2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix2x4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix4x2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix3x4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glUniformMatrix4x3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) +// GL 3.0 +ANT_GL_CORE_DECL(void, glColorMaski, (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)) +ANT_GL_CORE_DECL(void, glGetBooleani_v, (GLenum target, GLuint index, GLboolean *data)) +ANT_GL_CORE_DECL(void, glGetIntegeri_v, (GLenum target, GLuint index, GLint *data)) +ANT_GL_CORE_DECL(void, glEnablei, (GLenum target, GLuint index)) +ANT_GL_CORE_DECL(void, glDisablei, (GLenum target, GLuint index)) +ANT_GL_CORE_DECL(GLboolean, glIsEnabledi, (GLenum target, GLuint index)) +ANT_GL_CORE_DECL(void, glBeginTransformFeedback, (GLenum primitiveMode)) +ANT_GL_CORE_DECL(void, glEndTransformFeedback, (void)) +ANT_GL_CORE_DECL(void, glBindBufferRange, (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)) +ANT_GL_CORE_DECL(void, glBindBufferBase, (GLenum target, GLuint index, GLuint buffer)) +ANT_GL_CORE_DECL(void, glTransformFeedbackVaryings, (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode)) +ANT_GL_CORE_DECL(void, glGetTransformFeedbackVarying, (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)) +ANT_GL_CORE_DECL(void, glClampColor, (GLenum target, GLenum clamp)) +ANT_GL_CORE_DECL(void, glBeginConditionalRender, (GLuint id, GLenum mode)) +ANT_GL_CORE_DECL(void, glEndConditionalRender, (void)) +ANT_GL_CORE_DECL(void, glVertexAttribIPointer, (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +ANT_GL_CORE_DECL(void, glGetVertexAttribIiv, (GLuint index, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetVertexAttribIuiv, (GLuint index, GLenum pname, GLuint *params)) +ANT_GL_CORE_DECL(void, glVertexAttribI1i, (GLuint index, GLint x)) +ANT_GL_CORE_DECL(void, glVertexAttribI2i, (GLuint index, GLint x, GLint y)) +ANT_GL_CORE_DECL(void, glVertexAttribI3i, (GLuint index, GLint x, GLint y, GLint z)) +ANT_GL_CORE_DECL(void, glVertexAttribI4i, (GLuint index, GLint x, GLint y, GLint z, GLint w)) +ANT_GL_CORE_DECL(void, glVertexAttribI1ui, (GLuint index, GLuint x)) +ANT_GL_CORE_DECL(void, glVertexAttribI2ui, (GLuint index, GLuint x, GLuint y)) +ANT_GL_CORE_DECL(void, glVertexAttribI3ui, (GLuint index, GLuint x, GLuint y, GLuint z)) +ANT_GL_CORE_DECL(void, glVertexAttribI4ui, (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)) +ANT_GL_CORE_DECL(void, glVertexAttribI1iv, (GLuint index, const GLint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI2iv, (GLuint index, const GLint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI3iv, (GLuint index, const GLint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI4iv, (GLuint index, const GLint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI1uiv, (GLuint index, const GLuint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI2uiv, (GLuint index, const GLuint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI3uiv, (GLuint index, const GLuint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI4uiv, (GLuint index, const GLuint *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI4bv, (GLuint index, const GLbyte *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI4sv, (GLuint index, const GLshort *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI4ubv, (GLuint index, const GLubyte *v)) +ANT_GL_CORE_DECL(void, glVertexAttribI4usv, (GLuint index, const GLushort *v)) +ANT_GL_CORE_DECL(void, glGetUniformuiv, (GLuint program, GLint location, GLuint *params)) +ANT_GL_CORE_DECL(void, glBindFragDataLocation, (GLuint program, GLuint color, const GLchar *name)) +ANT_GL_CORE_DECL(GLint, glGetFragDataLocation, (GLuint program, const GLchar *name)) +ANT_GL_CORE_DECL(void, glUniform1ui, (GLint location, GLuint v0)) +ANT_GL_CORE_DECL(void, glUniform2ui, (GLint location, GLuint v0, GLuint v1)) +ANT_GL_CORE_DECL(void, glUniform3ui, (GLint location, GLuint v0, GLuint v1, GLuint v2)) +ANT_GL_CORE_DECL(void, glUniform4ui, (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)) +ANT_GL_CORE_DECL(void, glUniform1uiv, (GLint location, GLsizei count, const GLuint *value)) +ANT_GL_CORE_DECL(void, glUniform2uiv, (GLint location, GLsizei count, const GLuint *value)) +ANT_GL_CORE_DECL(void, glUniform3uiv, (GLint location, GLsizei count, const GLuint *value)) +ANT_GL_CORE_DECL(void, glUniform4uiv, (GLint location, GLsizei count, const GLuint *value)) +ANT_GL_CORE_DECL(void, glTexParameterIiv, (GLenum target, GLenum pname, const GLint *params)) +ANT_GL_CORE_DECL(void, glTexParameterIuiv, (GLenum target, GLenum pname, const GLuint *params)) +ANT_GL_CORE_DECL(void, glGetTexParameterIiv, (GLenum target, GLenum pname, GLint *params)) +ANT_GL_CORE_DECL(void, glGetTexParameterIuiv, (GLenum target, GLenum pname, GLuint *params)) +ANT_GL_CORE_DECL(void, glClearBufferiv, (GLenum buffer, GLint drawbuffer, const GLint *value)) +ANT_GL_CORE_DECL(void, glClearBufferuiv, (GLenum buffer, GLint drawbuffer, const GLuint *value)) +ANT_GL_CORE_DECL(void, glClearBufferfv, (GLenum buffer, GLint drawbuffer, const GLfloat *value)) +ANT_GL_CORE_DECL(void, glClearBufferfi, (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)) +ANT_GL_CORE_DECL(const GLubyte *, glGetStringi, (GLenum name, GLuint index)) +// GL 3.1 +ANT_GL_CORE_DECL(void, glDrawArraysInstanced, (GLenum mode, GLint first, GLsizei count, GLsizei primcount)) +ANT_GL_CORE_DECL(void, glDrawElementsInstanced, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)) +ANT_GL_CORE_DECL(void, glTexBuffer, (GLenum target, GLenum internalformat, GLuint buffer)) +ANT_GL_CORE_DECL(void, glPrimitiveRestartIndex, (GLuint index)) +// GL 3.2 +//typedef int64_t GLint64; +//ANT_GL_CORE_DECL(void, glGetInteger64i_v, (GLenum target, GLuint index, GLint64 *data)) +//ANT_GL_CORE_DECL(void, glGetBufferParameteri64v, (GLenum target, GLenum pname, GLint64 *params)) +ANT_GL_CORE_DECL(void, glFramebufferTexture, (GLenum target, GLenum attachment, GLuint texture, GLint level)) +*/ +// GL_ARB_vertex_array_object +ANT_GL_CORE_DECL_NO_FORWARD(void, glBindVertexArray, (GLuint array)) +ANT_GL_CORE_DECL_NO_FORWARD(void, glDeleteVertexArrays, (GLsizei n, const GLuint *arrays)) +ANT_GL_CORE_DECL_NO_FORWARD(void, glGenVertexArrays, (GLsizei n, GLuint *arrays)) +ANT_GL_CORE_DECL_NO_FORWARD(GLboolean, glIsVertexArray, (GLuint array)) + + +#ifdef ANT_WINDOWS +ANT_GL_CORE_DECL(PROC, wglGetProcAddress, (LPCSTR)) +#endif + +#ifndef GL_CLAMP_TO_EDGE +# define GL_CLAMP_TO_EDGE 0x812F +#endif +#ifndef GL_COMPILE_STATUS +# define GL_COMPILE_STATUS 0x8B81 +#endif +#ifndef GL_INFO_LOG_LENGTH +# define GL_INFO_LOG_LENGTH 0x8B84 +#endif +#ifndef GL_LINK_STATUS +# define GL_LINK_STATUS 0x8B82 +#endif +#ifndef GL_ARRAY_BUFFER +# define GL_ARRAY_BUFFER 0x8892 +#endif +#ifndef GL_DYNAMIC_DRAW +# define GL_DYNAMIC_DRAW 0x88E8 +#endif +#ifndef GL_VERTEX_SHADER +# define GL_VERTEX_SHADER 0x8B31 +#endif +#ifndef GL_FRAGMENT_SHADER +# define GL_FRAGMENT_SHADER 0x8B30 +#endif +#ifndef GL_VERTEX_ARRAY_BINDING +# define GL_VERTEX_ARRAY_BINDING 0x85B5 +#endif +#ifndef GL_CURRENT_PROGRAM +# define GL_CURRENT_PROGRAM 0x8B8D +#endif +#ifndef GL_ACTIVE_TEXTURE +# define GL_ACTIVE_TEXTURE 0x84E0 +#endif +#ifndef GL_TEXTURE0 +# define GL_TEXTURE0 0x84C0 +#endif +#ifndef GL_BGRA +# define GL_BGRA 0x80E1 +#endif + + +#endif // !defined ANT_LOAD_OGL_CORE_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/Makefile b/Extras/CDTestFramework/AntTweakBar/src/Makefile new file mode 100644 index 0000000..140a6dc --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/Makefile @@ -0,0 +1,100 @@ +####### Compiler, tools and options + +#---- LINUX +SO_EXT = .so +SO_VERSION = 1 + +#---- Release +CXXCFG = -O3 +LFLAGS = +OUT_DIR = ../lib +#---- Debug +#CXXCFG = -g -D_DEBUG +#LFLAGS = +#OUT_DIR = ../lib/debug + + +CXX = gcc +CXXFLAGS = $(CXXCFG) -Wall -fPIC -fno-strict-aliasing -D_UNIX -D__PLACEMENT_NEW_INLINE +INCPATH = -I../include -I/usr/local/include -I/usr/X11R6/include -I/usr/include +LINK = gcc +#LIBS = -L/usr/X11R6/lib -L. -lglfw -lGL -lGLU -lX11 -lXxf86vm -lXext -lpthread -lm +#LIBS = -L/usr/X11R6/lib -lGL -lX11 -lXxf86vm -lXext -lpthread -lm +LIBS = +AR = ar cqs +RANLIB = +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE = $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = rm -f +SYMLINK = ln -sf +DEL_DIR = rmdir +MOVE = mv +NO_STDERR = 2> /dev/null + + +####### Files + + +# name of the application: +TARGET = AntTweakBar + +# source files without extension: +SRC_FILES = TwColors.cpp TwFonts.cpp TwOpenGL.cpp TwOpenGLCore.cpp TwBar.cpp TwMgr.cpp TwPrecomp.cpp LoadOGL.cpp LoadOGLCore.cpp TwEventGLFW.c TwEventGLUT.c TwEventSDL.c TwEventSDL12.c TwEventSDL13.c TwEventSFML.cpp TwEventX11.c + +# build object list from source files +OBJS_1 = $(SRC_FILES:.c=.o) +OBJS = $(OBJS_1:.cpp=.o) + + +####### Build rules + + +#first: depend all +first: all + +all: Makefile $(TARGET) + +# append dependencies to this Makefile +#depend: +# @echo "==== Make dependencies =====" +# makedepend -Y +# makedepend -a -Y -- $(CXXFLAGS) $(INCPATH) -- $(SRC_FILES) $(NO_STDERR) + +$(TARGET): $(OBJS) + @echo "===== Link $@ =====" + $(LINK) $(LFLAGS) -shared -Wl,-soname,lib$(TARGET)$(SO_EXT).$(SO_VERSION) -o $(OUT_DIR)/lib$(TARGET)$(SO_EXT) $(OBJS) $(LIBS) + $(SYMLINK) $(OUT_DIR)/lib$(TARGET)$(SO_EXT) $(OUT_DIR)/lib$(TARGET)$(SO_EXT).$(SO_VERSION) + +.cpp.o: + @echo "===== Compile $< =====" + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + @echo "===== Compile $< =====" + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +clean: + @echo "===== Clean =====" + -$(DEL_FILE) *.o + -$(DEL_FILE) *~ core *.core *.stackdump + + +####### DEPENDENCIES + +TwColors.o: TwPrecomp.h TwColors.h +TwFonts.o: TwPrecomp.h ../include/AntTweakBar.h TwFonts.h TwMgr.h TwColors.h TwGraph.h AntPerfTimer.h +TwOpenGL.o: TwPrecomp.h ../include/AntTweakBar.h TwOpenGL.h LoadOGL.h TwGraph.h TwColors.h TwFonts.h TwMgr.h AntPerfTimer.h +TwOpenGLCore.o: TwPrecomp.h ../include/AntTweakBar.h TwOpenGLCore.h LoadOGLCore.h TwGraph.h TwColors.h TwFonts.h TwMgr.h AntPerfTimer.h +TwBar.o: TwPrecomp.h ../include/AntTweakBar.h TwBar.h TwMgr.h TwColors.h TwFonts.h TwGraph.h AntPerfTimer.h +TwMgr.o: TwPrecomp.h ../include/AntTweakBar.h TwMgr.h TwColors.h TwFonts.h TwGraph.h AntPerfTimer.h TwBar.h TwOpenGL.h res/TwXCursors.h +TwPrecomp.o: TwPrecomp.h +LoadOGL.o: TwPrecomp.h LoadOGL.h +TwEventGLFW.o: ../include/AntTweakBar.h MiniGLFW.h +TwEventGLUT.o: ../include/AntTweakBar.h MiniGLUT.h +TwEventSDL.o: ../include/AntTweakBar.h +TwEventSDL12.o: ../include/AntTweakBar.h MiniSDL12.h +TwEventSDL13.o: ../include/AntTweakBar.h MiniSDL13.h +TwEventX11.o: ../include/AntTweakBar.h diff --git a/Extras/CDTestFramework/AntTweakBar/src/Makefile.x86_64 b/Extras/CDTestFramework/AntTweakBar/src/Makefile.x86_64 new file mode 100644 index 0000000..e237e0a --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/Makefile.x86_64 @@ -0,0 +1,97 @@ +####### Compiler, tools and options + +#---- MinGW +#MINGWFLAGS = -mno-cygwin +#SO_EXT = .dll +#---- LINUX +SO_EXT = .so + +#---- Release +CXXCFG = -O3 +LFLAGS = -Wl,-s +OUT_DIR = ../lib +#---- Debug +#CXXCFG = -g -D_DEBUG +#LFLAGS = +#OUT_DIR = ../lib/debug + + +CXX = gcc -fPIC +#CXXFLAGS = $(CXXCFG) $(MINGWFLAGS) -pipe -Wall -fomit-frame-pointer -mcpu=pentiumpro -march=i586 -ffast-math -fno-strength-reduce -fpic -D_UNIX -D__PLACEMENT_NEW_INLINE +CXXFLAGS = $(CXXCFG) $(MINGWFLAGS) -Wall -ffast-math -D_UNIX -D__PLACEMENT_NEW_INLINE +INCPATH = -I/usr/include -I/usr/include -I../include +LINK = gcc -fPIC +#LIBS = -L/usr/lib64 -L. -lGL -lGLU -lX11 -lXxf86vm -lXext -lpthread -lm +#LIBS = -L/usr/lib -lGL -lX11 -lXxf86vm -lXext -lpthread -lm +LIBS = +AR = ar cqs +RANLIB = +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE = $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = rm -f +SYMLINK = ln -sf +DEL_DIR = rmdir +MOVE = mv +NO_STDERR = 2> /dev/null + + +####### Files + + +# name of the application: +TARGET = AntTweakBar + +# source files without extension: +SRC_FILES = TwColors.cpp TwFonts.cpp TwOpenGL.cpp TwBar.cpp TwMgr.cpp TwPrecomp.cpp LoadOGL.cpp TwEventGLFW.c TwEventGLUT.c TwEventSDL.c + +# build object list from source files +OBJS_1 = $(SRC_FILES:.c=.o) +OBJS = $(OBJS_1:.cpp=.o) + + +####### Build rules + +#first: depend all +first: all + +all: Makefile $(TARGET) + +# append dependencies to this Makefile +#depend: +# @echo "==== Make dependencies =====" +# makedepend -Y +# makedepend -a -Y -- $(CXXFLAGS) $(INCPATH) -- $(SRC_FILES) $(NO_STDERR) + +$(TARGET): $(OBJS) + @echo "===== Link $@ =====" + $(LINK) $(LFLAGS) -shared -Wl,-soname,lib$(TARGET)$(SO_EXT) -o $(OUT_DIR)/lib$(TARGET)$(SO_EXT) $(OBJS) $(LIBS) + +.cpp.o: + @echo "===== Compile $< =====" + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + @echo "===== Compile $< =====" + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +clean: + @echo "===== Clean =====" + -$(DEL_FILE) *.o + -$(DEL_FILE) *~ core *.core *.stackdump + + +####### DEPENDENCIES + +TwColors.o: TwPrecomp.h TwColors.h +TwFonts.o: TwPrecomp.h ../include/AntTweakBar.h TwFonts.h TwMgr.h TwColors.h TwGraph.h AntPerfTimer.h +TwOpenGL.o: TwPrecomp.h ../include/AntTweakBar.h TwOpenGL.h LoadOGL.h TwGraph.h TwColors.h TwFonts.h TwMgr.h AntPerfTimer.h +TwBar.o: TwPrecomp.h ../include/AntTweakBar.h TwBar.h TwMgr.h TwColors.h TwFonts.h TwGraph.h AntPerfTimer.h +TwMgr.o: TwPrecomp.h ../include/AntTweakBar.h TwMgr.h TwColors.h TwFonts.h TwGraph.h AntPerfTimer.h TwBar.h TwOpenGL.h res/TwXCursors.h +TwPrecomp.o: TwPrecomp.h +LoadOGL.o: TwPrecomp.h LoadOGL.h +TwEventGLFW.o: ../include/AntTweakBar.h +TwEventGLUT.o: ../include/AntTweakBar.h +TwEventSDL.o: ../include/AntTweakBar.h diff --git a/Extras/CDTestFramework/AntTweakBar/src/MiniGLUT.h b/Extras/CDTestFramework/AntTweakBar/src/MiniGLUT.h new file mode 100644 index 0000000..8459264 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/MiniGLUT.h @@ -0,0 +1,142 @@ +// --------------------------------------------------------------------------- +// +// @file MiniGLUT.h +// @brief A subset of GLUT definitions needed to compile helper functions +// implemented in TwEventGLUT.c +// +// notes: - Private header +// - AntTweakBar.dll does not need to link with GLUT, +// it just needs some definitions for its helper functions. +// - This header is provided to avoid the need of having GLUT +// installed to recompile AntTweakBar. +// - Do not use this header in your own programs, better use the +// GLUT.h header from the actual GLUT library SDK : +// http://opengl.org/resources/libraries/glut +// +// --------------------------------------------------------------------------- + +#if !defined MINI_GLUT_INCLUDED +#define MINI_GLUT_INCLUDED + +#if defined(_WIN32) || defined(_WIN64) +# define WIN32_LEAN_AND_MEAN +# include // needed by gl.h +# define GLUT_CALL __stdcall +# define GLUT_CALLBACK __cdecl +# define GLUT_API __declspec(dllimport) +#else +# define GLUT_CALL +# define GLUT_CALLBACK +# define GLUT_API extern +#endif + +#if defined(_MACOSX) +# include +# include +#else +# include // must be included after windows.h +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +// Mouse buttons +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +// Mouse button state +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +// glutGetModifiers return mask +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +// function keys +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 + +// directional keys +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 + +// display mode bit masks +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 + +// timer +#define GLUT_ELAPSED_TIME ((GLenum) 700) + + +// functions subset +GLUT_API void GLUT_CALL glutInit(int *argcp, char **argv); +GLUT_API void GLUT_CALL glutInitDisplayMode(unsigned int mode); +GLUT_API int GLUT_CALL glutCreateWindow(const char *title); +GLUT_API int GLUT_CALL glutGetWindow(void); +GLUT_API void GLUT_CALL glutSetWindow(int win); +GLUT_API int GLUT_CALL glutCreateSubWindow(int win, int x, int y, int width, int height); +GLUT_API int GLUT_CALL glutGet(GLenum type); +GLUT_API void GLUT_CALL glutSwapBuffers(); +GLUT_API void GLUT_CALL glutPostRedisplay(); +GLUT_API void GLUT_CALL glutInitWindowPosition(int x, int y); +GLUT_API void GLUT_CALL glutInitWindowSize(int width, int height); +GLUT_API void GLUT_CALL glutPositionWindow(int x, int y); +GLUT_API void GLUT_CALL glutReshapeWindow(int width, int height); +GLUT_API void GLUT_CALL glutMainLoop(); +GLUT_API int GLUT_CALL glutCreateMenu(void (GLUT_CALLBACK *func)(int)); +GLUT_API void GLUT_CALL glutDisplayFunc(void (GLUT_CALLBACK *func)(void)); +GLUT_API void GLUT_CALL glutReshapeFunc(void (GLUT_CALLBACK *func)(int width, int height)); +GLUT_API void GLUT_CALL glutKeyboardFunc(void (GLUT_CALLBACK *func)(unsigned char key, int x, int y)); +GLUT_API void GLUT_CALL glutMouseFunc(void (GLUT_CALLBACK *func)(int button, int state, int x, int y)); +GLUT_API void GLUT_CALL glutMotionFunc(void (GLUT_CALLBACK *func)(int x, int y)); +GLUT_API void GLUT_CALL glutPassiveMotionFunc(void (GLUT_CALLBACK *func)(int x, int y)); +GLUT_API void GLUT_CALL glutSpecialFunc(void (GLUT_CALLBACK *func)(int key, int x, int y)); +GLUT_API int GLUT_CALL glutGetModifiers(void); +GLUT_API void GLUT_CALL glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUT_API void GLUT_CALL glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUT_API void GLUT_CALL glutSolidTeapot(GLdouble size); + +// GLUT exit problem workaround (see glut.h) +#if (defined(_WIN32) || defined(_WIN64)) && !defined(GLUT_DISABLE_ATEXIT_HACK) + extern void __cdecl exit(int); + GLUT_API void GLUT_CALL __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); + static void GLUT_CALL glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } + #define glutInit glutInit_ATEXIT_HACK +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // !defined MINI_GLUT_INCLUDED + diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwBar.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwBar.cpp new file mode 100644 index 0000000..4f6e4bf --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwBar.cpp @@ -0,0 +1,7766 @@ +// --------------------------------------------------------------------------- +// +// @file TwBar.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include +#include "TwMgr.h" +#include "TwBar.h" +#include "TwColors.h" + +using namespace std; + +extern const char *g_ErrNotFound; +const char *g_ErrUnknownAttrib = "Unknown parameter"; +const char *g_ErrInvalidAttrib = "Invalid parameter"; +const char *g_ErrNotGroup = "Value is not a group"; +const char *g_ErrNoValue = "Value required"; +const char *g_ErrBadValue = "Bad value"; +const char *g_ErrUnknownType = "Unknown type"; +const char *g_ErrNotEnum = "Must be of type Enum"; + +#undef PERF // comment to print benchs +#define PERF(cmd) + + +PerfTimer g_BarTimer; + +#define ANT_SET_CURSOR(_Name) g_TwMgr->SetCursor(g_TwMgr->m_Cursor##_Name) +#define ANT_SET_ROTO_CURSOR(_Num) g_TwMgr->SetCursor(g_TwMgr->m_RotoCursors[_Num]) + +#if !defined(ANT_WINDOWS) +# define _stricmp strcasecmp +# define _strdup strdup +#endif // defined(ANT_WINDOWS) + +#if !defined(M_PI) +# define M_PI 3.1415926535897932384626433832795 +#endif // !defined(M_PI) + +const float FLOAT_MAX = 3.0e+38f; +const double DOUBLE_MAX = 1.0e+308; +const double DOUBLE_EPS = 1.0e-307; + +bool IsCustomType(int _Type) +{ + return (g_TwMgr && _Type>=TW_TYPE_CUSTOM_BASE && _Typem_Customs.size()); +} + +bool IsCSStringType(int _Type) +{ + return (_Type>TW_TYPE_CSSTRING_BASE && _Type<=TW_TYPE_CSSTRING_MAX); +} + +bool IsEnumType(int _Type) +{ + return (g_TwMgr && _Type>=TW_TYPE_ENUM_BASE && _Typem_Enums.size()); +} + +// --------------------------------------------------------------------------- + +CTwVar::CTwVar() +{ + m_IsRoot = false; + m_DontClip = false; + m_Visible = true; + m_LeftMargin = 0; + m_TopMargin = 0; + m_ColorPtr = &COLOR32_WHITE; + m_BgColorPtr = &COLOR32_ZERO; // default +} + +CTwVarAtom::CTwVarAtom() +{ + m_Type = TW_TYPE_UNDEF; + m_Ptr = NULL; + m_SetCallback = NULL; + m_GetCallback = NULL; + m_ClientData = NULL; + m_ReadOnly = false; + m_NoSlider = false; + m_KeyIncr[0] = 0; + m_KeyIncr[1] = 0; + m_KeyDecr[0] = 0; + m_KeyDecr[1] = 0; + memset(&m_Val, 0, sizeof(UVal)); +} + +CTwVarAtom::~CTwVarAtom() +{ + if( m_Type==TW_TYPE_BOOL8 || m_Type==TW_TYPE_BOOL16 || m_Type==TW_TYPE_BOOL32 || m_Type==TW_TYPE_BOOLCPP ) + { + if( m_Val.m_Bool.m_FreeTrueString && m_Val.m_Bool.m_TrueString!=NULL ) + { + free(m_Val.m_Bool.m_TrueString); + m_Val.m_Bool.m_TrueString = NULL; + } + if( m_Val.m_Bool.m_FreeFalseString && m_Val.m_Bool.m_FalseString!=NULL ) + { + free(m_Val.m_Bool.m_FalseString); + m_Val.m_Bool.m_FalseString = NULL; + } + } + else if( m_Type==TW_TYPE_CDSTDSTRING && m_GetCallback==CTwMgr::CCDStdString::GetCB && m_ClientData!=NULL && g_TwMgr!=NULL ) + { + // delete corresponding g_TwMgr->m_CDStdStrings element + const CTwMgr::CCDStdString *CDStdString = (const CTwMgr::CCDStdString *)m_ClientData; + //if( &(*CDStdString->m_This)==CDStdString ) + // g_TwMgr->m_CDStdStrings.erase(CDStdString->m_This); + for( list::iterator it=g_TwMgr->m_CDStdStrings.begin(); it!=g_TwMgr->m_CDStdStrings.end(); ++it ) + if( &(*it)==CDStdString ) + { + g_TwMgr->m_CDStdStrings.erase(it); + break; + } + } + /* + else if( m_Type==TW_TYPE_ENUM8 || m_Type==TW_TYPE_ENUM16 || m_Type==TW_TYPE_ENUM32 ) + { + if( m_Val.m_Enum.m_Entries!=NULL ) + { + delete m_Val.m_Enum.m_Entries; + m_Val.m_Enum.m_Entries = NULL; + } + } + */ +} + +// --------------------------------------------------------------------------- + +void CTwVarAtom::ValueToString(string *_Str) const +{ + assert(_Str!=NULL); + static const char *ErrStr = "unreachable"; + char Tmp[1024]; + if( m_Type==TW_TYPE_UNDEF || m_Type==TW_TYPE_HELP_ATOM || m_Type==TW_TYPE_HELP_GRP || m_Type==TW_TYPE_BUTTON ) // has no value + { + *_Str = ""; + return; + } + else if( m_Type==TW_TYPE_HELP_HEADER ) + { + *_Str = "SHORTCUTS"; + return; + } + else if( m_Type==TW_TYPE_SHORTCUT ) // special case for help bar: display shortcut + { + *_Str = ""; + if( m_ReadOnly && m_Val.m_Shortcut.m_Incr[0]==0 && m_Val.m_Shortcut.m_Decr[0]==0 ) + (*_Str) = "(read only)"; + else + { + if( m_Val.m_Shortcut.m_Incr[0]>0 ) + TwGetKeyString(_Str, m_Val.m_Shortcut.m_Incr[0], m_Val.m_Shortcut.m_Incr[1]); + else + (*_Str) += "(none)"; + if( m_Val.m_Shortcut.m_Decr[0]>0 ) + { + (*_Str) += " "; + TwGetKeyString(_Str, m_Val.m_Shortcut.m_Decr[0], m_Val.m_Shortcut.m_Decr[1]); + } + } + return; + } + else if( m_Type==TW_TYPE_HELP_STRUCT ) + { + int idx = m_Val.m_HelpStruct.m_StructType - TW_TYPE_STRUCT_BASE; + if( idx>=0 && idx<(int)g_TwMgr->m_Structs.size() ) + { + if( g_TwMgr->m_Structs[idx].m_Name.length()>0 ) + (*_Str) = '{' + g_TwMgr->m_Structs[idx].m_Name + '}'; + else + (*_Str) = "{struct}"; + } + return; + } + + if( m_Ptr==NULL && m_GetCallback==NULL ) + { + *_Str = ErrStr; + return; + } + bool UseGet = (m_GetCallback!=NULL); + switch( m_Type ) + { + case TW_TYPE_BOOLCPP: + { + bool Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(bool *)m_Ptr; + if( Val ) + *_Str = (m_Val.m_Bool.m_TrueString!=NULL) ? m_Val.m_Bool.m_TrueString : "1"; + else + *_Str = (m_Val.m_Bool.m_FalseString!=NULL) ? m_Val.m_Bool.m_FalseString : "0"; + } + break; + case TW_TYPE_BOOL8: + { + char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(char *)m_Ptr; + if( Val ) + *_Str = (m_Val.m_Bool.m_TrueString!=NULL) ? m_Val.m_Bool.m_TrueString : "1"; + else + *_Str = (m_Val.m_Bool.m_FalseString!=NULL) ? m_Val.m_Bool.m_FalseString : "0"; + } + break; + case TW_TYPE_BOOL16: + { + short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(short *)m_Ptr; + if( Val ) + *_Str = (m_Val.m_Bool.m_TrueString!=NULL) ? m_Val.m_Bool.m_TrueString : "1"; + else + *_Str = (m_Val.m_Bool.m_FalseString!=NULL) ? m_Val.m_Bool.m_FalseString : "0"; + } + break; + case TW_TYPE_BOOL32: + { + int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(int *)m_Ptr; + if( Val ) + *_Str = (m_Val.m_Bool.m_TrueString!=NULL) ? m_Val.m_Bool.m_TrueString : "1"; + else + *_Str = (m_Val.m_Bool.m_FalseString!=NULL) ? m_Val.m_Bool.m_FalseString : "0"; + } + break; + case TW_TYPE_CHAR: + { + unsigned char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned char *)m_Ptr; + if( Val!=0 ) + { + int d = Val; + if( m_Val.m_Char.m_Hexa ) + sprintf(Tmp, "%c (0x%.2X)", Val, d); + else + sprintf(Tmp, "%c (%d)", Val, d); + *_Str = Tmp; + } + else + { + *_Str = " (0)"; + const_cast(_Str->c_str())[0] = '\0'; + } + } + break; + case TW_TYPE_INT8: + { + signed char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(signed char *)m_Ptr; + int d = Val; + if( m_Val.m_Int8.m_Hexa ) + sprintf(Tmp, "0x%.2X", d&0xff); + else + sprintf(Tmp, "%d", d); + *_Str = Tmp; + } + break; + case TW_TYPE_UINT8: + { + unsigned char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned char *)m_Ptr; + unsigned int d = Val; + if( m_Val.m_UInt8.m_Hexa ) + sprintf(Tmp, "0x%.2X", d); + else + sprintf(Tmp, "%u", d); + *_Str = Tmp; + } + break; + case TW_TYPE_INT16: + { + short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(short *)m_Ptr; + int d = Val; + if( m_Val.m_Int16.m_Hexa ) + sprintf(Tmp, "0x%.4X", d&0xffff); + else + sprintf(Tmp, "%d", d); + *_Str = Tmp; + } + break; + case TW_TYPE_UINT16: + { + unsigned short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned short *)m_Ptr; + unsigned int d = Val; + if( m_Val.m_UInt16.m_Hexa ) + sprintf(Tmp, "0x%.4X", d); + else + sprintf(Tmp, "%u", d); + *_Str = Tmp; + } + break; + case TW_TYPE_INT32: + { + int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(int *)m_Ptr; + if( m_Val.m_Int32.m_Hexa ) + sprintf(Tmp, "0x%.8X", Val); + else + sprintf(Tmp, "%d", Val); + *_Str = Tmp; + } + break; + case TW_TYPE_UINT32: + { + unsigned int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned int *)m_Ptr; + if( m_Val.m_UInt32.m_Hexa ) + sprintf(Tmp, "0x%.8X", Val); + else + sprintf(Tmp, "%u", Val); + *_Str = Tmp; + } + break; + case TW_TYPE_FLOAT: + { + float Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(float *)m_Ptr; + if( m_Val.m_Float32.m_Precision<0 ) + sprintf(Tmp, "%g", Val); + else + { + char Fmt[64]; + sprintf(Fmt, "%%.%df", (int)m_Val.m_Float32.m_Precision); + sprintf(Tmp, Fmt, Val); + } + *_Str = Tmp; + } + break; + case TW_TYPE_DOUBLE: + { + double Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(double *)m_Ptr; + if( m_Val.m_Float64.m_Precision<0 ) + sprintf(Tmp, "%g", Val); + else + { + char Fmt[128]; + sprintf(Fmt, "%%.%dlf", (int)m_Val.m_Float64.m_Precision); + sprintf(Tmp, Fmt, Val); + } + *_Str = Tmp; + } + break; + case TW_TYPE_STDSTRING: + { + if( UseGet ) + m_GetCallback(_Str, m_ClientData); + else + *_Str = *(std::string *)m_Ptr; + } + break; + /* + case TW_TYPE_ENUM8: + case TW_TYPE_ENUM16: + case TW_TYPE_ENUM32: + { + unsigned int d = 0; + if( m_Type==TW_TYPE_ENUM8 ) + { + unsigned char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned char *)m_Ptr; + d = Val; + } + else if( m_Type==TW_TYPE_ENUM16 ) + { + unsigned short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned short *)m_Ptr; + d = Val; + } + else + { + assert(m_Type==TW_TYPE_ENUM32); + unsigned int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned int *)m_Ptr; + d = Val; + } + bool Found = false; + if( m_Val.m_Enum.m_Entries!=NULL ) + { + UVal::CEnumVal::CEntries::iterator It = m_Val.m_Enum.m_Entries->find(d); + if( It!=m_Val.m_Enum.m_Entries->end() ) + { + *_Str = It->second; + Found = true; + } + } + if( !Found ) + { + sprintf(Tmp, "%u", d); + *_Str = Tmp; + } + } + break; + */ + default: + if( IsEnumType(m_Type) ) + { + unsigned int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned int *)m_Ptr; + + CTwMgr::CEnum& e = g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE]; + CTwMgr::CEnum::CEntries::iterator It = e.m_Entries.find(Val); + if( It!=e.m_Entries.end() ) + *_Str = It->second; + else + { + sprintf(Tmp, "%u", Val); + *_Str = Tmp; + } + } + else if( IsCSStringType(m_Type) ) + { + char *Val = NULL; + if( UseGet ) + { + int n = TW_CSSTRING_SIZE(m_Type); + if( n+32>(int)g_TwMgr->m_CSStringBuffer.size() ) + g_TwMgr->m_CSStringBuffer.resize(n+32); + Val = &(g_TwMgr->m_CSStringBuffer[0]); + m_GetCallback(Val , m_ClientData); + Val[n] = '\0'; + } + else + Val = (char *)m_Ptr; + if( Val!=NULL ) + *_Str = Val; + else + *_Str = ""; + } + else if( m_Type==TW_TYPE_CDSTRING || m_Type==TW_TYPE_CDSTDSTRING ) + { + char *Val = NULL; + if( UseGet ) + m_GetCallback(&Val , m_ClientData); + else + Val = *(char **)m_Ptr; + if( Val!=NULL ) + *_Str = Val; + else + *_Str = ""; + } + else if( IsCustom() ) // m_Type>=TW_TYPE_CUSTOM_BASE && m_Typem_Customs.size() ) + { + *_Str = ""; + } + else + { + *_Str = "unknown type"; + const_cast(this)->m_ReadOnly = true; + } + } +} + +// --------------------------------------------------------------------------- + +double CTwVarAtom::ValueToDouble() const +{ + if( m_Ptr==NULL && m_GetCallback==NULL ) + return 0; // unreachable + bool UseGet = (m_GetCallback!=NULL); + switch( m_Type ) + { + case TW_TYPE_BOOLCPP: + { + bool Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(bool *)m_Ptr; + if( Val ) + return 1; + else + return 0; + } + break; + case TW_TYPE_BOOL8: + { + char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(char *)m_Ptr; + if( Val ) + return 1; + else + return 0; + } + break; + case TW_TYPE_BOOL16: + { + short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(short *)m_Ptr; + if( Val ) + return 1; + else + return 0; + } + break; + case TW_TYPE_BOOL32: + { + int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(int *)m_Ptr; + if( Val ) + return 1; + else + return 0; + } + break; + case TW_TYPE_CHAR: + { + unsigned char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned char *)m_Ptr; + return Val; + } + break; + case TW_TYPE_INT8: + { + signed char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(signed char *)m_Ptr; + int d = Val; + return d; + } + break; + case TW_TYPE_UINT8: + { + unsigned char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned char *)m_Ptr; + unsigned int d = Val; + return d; + } + break; + case TW_TYPE_INT16: + { + short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(short *)m_Ptr; + int d = Val; + return d; + } + break; + case TW_TYPE_UINT16: + { + unsigned short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned short *)m_Ptr; + unsigned int d = Val; + return d; + } + break; + case TW_TYPE_INT32: + { + int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(int *)m_Ptr; + return Val; + } + break; + case TW_TYPE_UINT32: + { + unsigned int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned int *)m_Ptr; + return Val; + } + break; + case TW_TYPE_FLOAT: + { + float Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(float *)m_Ptr; + return Val; + } + break; + case TW_TYPE_DOUBLE: + { + double Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(double *)m_Ptr; + return Val; + } + break; + /* + case TW_TYPE_ENUM8: + case TW_TYPE_ENUM16: + case TW_TYPE_ENUM32: + { + unsigned int d = 0; + if( m_Type==TW_TYPE_ENUM8 ) + { + unsigned char Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned char *)m_Ptr; + d = Val; + } + else if( m_Type==TW_TYPE_ENUM16 ) + { + unsigned short Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned short *)m_Ptr; + d = Val; + } + else + { + assert(m_Type==TW_TYPE_ENUM32); + unsigned int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned int *)m_Ptr; + d = Val; + } + return d; + } + break; + */ + default: + if( IsEnumType(m_Type) ) + { + unsigned int Val = 0; + if( UseGet ) + m_GetCallback(&Val, m_ClientData); + else + Val = *(unsigned int *)m_Ptr; + return Val; + } + else + return 0; // unknown type + } +} + +// --------------------------------------------------------------------------- + +void CTwVarAtom::ValueFromDouble(double _Val) +{ + if( m_Ptr==NULL && m_SetCallback==NULL ) + return; // unreachable + bool UseSet = (m_SetCallback!=NULL); + switch( m_Type ) + { + case TW_TYPE_BOOLCPP: + { + bool Val = (_Val!=0); + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(bool*)m_Ptr = Val; + } + break; + case TW_TYPE_BOOL8: + { + char Val = (_Val!=0) ? 1 : 0; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(char*)m_Ptr = Val; + } + break; + case TW_TYPE_BOOL16: + { + short Val = (_Val!=0) ? 1 : 0; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(short*)m_Ptr = Val; + } + break; + case TW_TYPE_BOOL32: + { + int Val = (_Val!=0) ? 1 : 0; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(int*)m_Ptr = Val; + } + break; + case TW_TYPE_CHAR: + { + unsigned char Val = (unsigned char)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(unsigned char*)m_Ptr = Val; + } + break; + case TW_TYPE_INT8: + { + signed char Val = (signed char)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(signed char*)m_Ptr = Val; + } + break; + case TW_TYPE_UINT8: + //case TW_TYPE_ENUM8: + { + unsigned char Val = (unsigned char)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(unsigned char*)m_Ptr = Val; + } + break; + case TW_TYPE_INT16: + { + short Val = (short)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(short*)m_Ptr = Val; + } + break; + case TW_TYPE_UINT16: + //case TW_TYPE_ENUM16: + { + unsigned short Val = (unsigned short)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(unsigned short*)m_Ptr = Val; + } + break; + case TW_TYPE_INT32: + { + int Val = (int)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(int*)m_Ptr = Val; + } + break; + case TW_TYPE_UINT32: + //case TW_TYPE_ENUM32: + { + unsigned int Val = (unsigned int)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(unsigned int*)m_Ptr = Val; + } + break; + case TW_TYPE_FLOAT: + { + float Val = (float)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(float*)m_Ptr = Val; + } + break; + case TW_TYPE_DOUBLE: + { + double Val = (double)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(double*)m_Ptr = Val; + } + break; + default: + if( IsEnumType(m_Type) ) + { + unsigned int Val = (unsigned int)_Val; + if( UseSet ) + m_SetCallback(&Val, m_ClientData); + else + *(unsigned int*)m_Ptr = Val; + } + } +} + +// --------------------------------------------------------------------------- + +void CTwVarAtom::MinMaxStepToDouble(double *_Min, double *_Max, double *_Step) const +{ + double max = DOUBLE_MAX; + double min = -DOUBLE_MAX; + double step = 1; + + switch( m_Type ) + { + case TW_TYPE_BOOLCPP: + case TW_TYPE_BOOL8: + case TW_TYPE_BOOL16: + case TW_TYPE_BOOL32: + min = 0; + max = 1; + step = 1; + break; + case TW_TYPE_CHAR: + min = (double)m_Val.m_Char.m_Min; + max = (double)m_Val.m_Char.m_Max; + step = (double)m_Val.m_Char.m_Step; + break; + case TW_TYPE_INT8: + min = (double)m_Val.m_Int8.m_Min; + max = (double)m_Val.m_Int8.m_Max; + step = (double)m_Val.m_Int8.m_Step; + break; + case TW_TYPE_UINT8: + min = (double)m_Val.m_UInt8.m_Min; + max = (double)m_Val.m_UInt8.m_Max; + step = (double)m_Val.m_UInt8.m_Step; + break; + case TW_TYPE_INT16: + min = (double)m_Val.m_Int16.m_Min; + max = (double)m_Val.m_Int16.m_Max; + step = (double)m_Val.m_Int16.m_Step; + break; + case TW_TYPE_UINT16: + min = (double)m_Val.m_UInt16.m_Min; + max = (double)m_Val.m_UInt16.m_Max; + step = (double)m_Val.m_UInt16.m_Step; + break; + case TW_TYPE_INT32: + min = (double)m_Val.m_Int32.m_Min; + max = (double)m_Val.m_Int32.m_Max; + step = (double)m_Val.m_Int32.m_Step; + break; + case TW_TYPE_UINT32: + min = (double)m_Val.m_UInt32.m_Min; + max = (double)m_Val.m_UInt32.m_Max; + step = (double)m_Val.m_UInt32.m_Step; + break; + case TW_TYPE_FLOAT: + min = (double)m_Val.m_Float32.m_Min; + max = (double)m_Val.m_Float32.m_Max; + step = (double)m_Val.m_Float32.m_Step; + break; + case TW_TYPE_DOUBLE: + min = m_Val.m_Float64.m_Min; + max = m_Val.m_Float64.m_Max; + step = m_Val.m_Float64.m_Step; + break; + default: + {} // nothing + } + + if( _Min!=NULL ) + *_Min = min; + if( _Max!=NULL ) + *_Max = max; + if( _Step!=NULL ) + *_Step = step; +} + +// --------------------------------------------------------------------------- + +const CTwVar *CTwVarAtom::Find(const char *_Name, CTwVarGroup **_Parent, int *_Index) const +{ + if( strcmp(_Name, m_Name.c_str())==0 ) + { + if( _Parent!=NULL ) + *_Parent = NULL; + if( _Index!=NULL ) + *_Index = -1; + return this; + } + else + return NULL; +} + +// --------------------------------------------------------------------------- + +enum EVarAttribs +{ + V_LABEL = 1, + V_HELP, + V_GROUP, + V_SHOW, + V_HIDE, + V_READONLY, + V_READWRITE, + V_ORDER, + V_VISIBLE, + V_ENDTAG +}; + +int CTwVar::HasAttrib(const char *_Attrib, bool *_HasValue) const +{ + *_HasValue = true; + if( _stricmp(_Attrib, "label")==0 ) + return V_LABEL; + else if( _stricmp(_Attrib, "help")==0 ) + return V_HELP; + else if( _stricmp(_Attrib, "group")==0 ) + return V_GROUP; + else if( _stricmp(_Attrib, "order")==0 ) + return V_ORDER; + else if( _stricmp(_Attrib, "visible")==0 ) + return V_VISIBLE; + else if( _stricmp(_Attrib, "readonly")==0 ) + return V_READONLY; + + // for backward compatibility + *_HasValue = false; + if( _stricmp(_Attrib, "show")==0 ) + return V_SHOW; + else if( _stricmp(_Attrib, "hide")==0 ) + return V_HIDE; + if( _stricmp(_Attrib, "readonly")==0 ) + return V_READONLY; + else if( _stricmp(_Attrib, "readwrite")==0 ) + return V_READWRITE; + + return 0; // not found +} + +int CTwVar::SetAttrib(int _AttribID, const char *_Value, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex) +{ + switch( _AttribID ) + { + case V_LABEL: + case V_HELP: + if( _Value && strlen(_Value)>0 ) + { + /* + if( IsGroup() && static_cast(this)->m_StructValuePtr!=NULL ) + { + int Idx = static_cast(this)->m_StructType-TW_TYPE_STRUCT_BASE; + if( Idx>=0 && Idx<(int)g_TwMgr->m_Structs.size() ) + if( _AttribID==V_LABEL ) + g_TwMgr->m_Structs[Idx].m_Label = _Value; + else // V_HELP + g_TwMgr->m_Structs[Idx].m_Help = _Value; + } + else + */ + { + CTwVarGroup *Parent = NULL; + CTwVar *ThisVar = _Bar->Find(m_Name.c_str(), &Parent); + if( this==ThisVar && Parent!=NULL && Parent->m_StructValuePtr!=NULL ) + { + int Idx = Parent->m_StructType-TW_TYPE_STRUCT_BASE; + if( Idx>=0 && Idx<(int)g_TwMgr->m_Structs.size() ) + { + size_t nl = m_Name.length(); + for( size_t im=0; imm_Structs[Idx].m_Members.size(); ++im ) + { + size_t ml = g_TwMgr->m_Structs[Idx].m_Members[im].m_Name.length(); + if( nl>=ml && strcmp(g_TwMgr->m_Structs[Idx].m_Members[im].m_Name.c_str(), m_Name.c_str()+(nl-ml))==0 ) + { + // TODO: would have to be applied to other vars already created + if( _AttribID==V_LABEL ) + { + g_TwMgr->m_Structs[Idx].m_Members[im].m_Label = _Value; +// m_Label = _Value; + } + else // V_HELP + g_TwMgr->m_Structs[Idx].m_Members[im].m_Help = _Value; + break; + } + } + } + } + else + { + if( _AttribID==V_LABEL ) + m_Label = _Value; + else // V_HELP + m_Help = _Value; + } + } + _Bar->NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case V_GROUP: + { + CTwVarGroup *Grp = NULL; + if( _Value==NULL || strlen(_Value)<=0 ) + Grp = &(_Bar->m_VarRoot); + else + { + CTwVar *v = _Bar->Find(_Value, NULL, NULL); + if( v && !v->IsGroup() ) + { + g_TwMgr->SetLastError(g_ErrNotGroup); + return 0; + } + Grp = static_cast(v); + if( Grp==NULL ) + { + Grp = new CTwVarGroup; + Grp->m_Name = _Value; + Grp->m_Open = true; + Grp->m_SummaryCallback = NULL; + Grp->m_SummaryClientData = NULL; + Grp->m_StructValuePtr = NULL; + Grp->m_ColorPtr = &(_Bar->m_ColGrpText); + _Bar->m_VarRoot.m_Vars.push_back(Grp); + } + } + Grp->m_Vars.push_back(this); + if( _VarParent!=NULL && _VarIndex>=0 ) + { + _VarParent->m_Vars.erase(_VarParent->m_Vars.begin()+_VarIndex); + if( _VarParent!=&(_Bar->m_VarRoot) && _VarParent->m_Vars.size()<=0 ) + TwRemoveVar(_Bar, _VarParent->m_Name.c_str()); + } + _Bar->NotUpToDate(); + return 1; + } + case V_SHOW: // for backward compatibility + if( !m_Visible ) + { + m_Visible = true; + _Bar->NotUpToDate(); + } + return 1; + case V_HIDE: // for backward compatibility + if( m_Visible ) + { + m_Visible = false; + _Bar->NotUpToDate(); + } + return 1; + /* + case V_READONLY: + SetReadOnly(true); + _Bar->NotUpToDate(); + return 1; + */ + case V_READWRITE: // for backward compatibility + SetReadOnly(false); + _Bar->NotUpToDate(); + return 1; + case V_ORDER: + // a special case for compatibility with deprecated command 'option=ogl/dx' + if( IsGroup() && _Value!=NULL && static_cast(this)->m_SummaryCallback==CColorExt::SummaryCB && static_cast(this)->m_StructValuePtr!=NULL ) // is tw_type_color? + { + if( _stricmp(_Value, "ogl")==0 ) + { + static_cast(static_cast(this)->m_StructValuePtr)->m_OGL = true; + return 1; + } + else if( _stricmp(_Value, "dx")==0 ) + { + static_cast(static_cast(this)->m_StructValuePtr)->m_OGL = false; + return 1; + } + } + // todo: general 'order' command (no else) + return 0; + case V_VISIBLE: + if( _Value!=NULL && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "true")==0 || _stricmp(_Value, "1")==0 ) + { + if( !m_Visible ) + { + m_Visible = true; + _Bar->NotUpToDate(); + } + return 1; + } + else if( _stricmp(_Value, "false")==0 || _stricmp(_Value, "0")==0 ) + { + if( m_Visible ) + { + m_Visible = false; + _Bar->NotUpToDate(); + } + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case V_READONLY: + if( _Value==NULL || strlen(_Value)==0 // no value is acceptable (for backward compatibility) + || _stricmp(_Value, "true")==0 || _stricmp(_Value, "1")==0 ) + { + if( !IsReadOnly() ) + { + SetReadOnly(true); + _Bar->NotUpToDate(); + } + return 1; + } + else if( _stricmp(_Value, "false")==0 || _stricmp(_Value, "0")==0 ) + { + if( IsReadOnly() ) + { + SetReadOnly(false); + _Bar->NotUpToDate(); + } + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + default: + g_TwMgr->SetLastError(g_ErrUnknownAttrib); + return 0; + } +} + + +ERetType CTwVar::GetAttrib(int _AttribID, TwBar * /*_Bar*/, CTwVarGroup * _VarParent, int /*_VarIndex*/, std::vector& outDoubles, std::ostringstream& outString) const +{ + outDoubles.clear(); + outString.clear(); + + switch( _AttribID ) + { + case V_LABEL: + outString << m_Label; + return RET_STRING; + case V_HELP: + outString << m_Help; + return RET_STRING; + case V_GROUP: + if( _VarParent!=NULL ) + outString << _VarParent->m_Name; + return RET_STRING; + case V_VISIBLE: + outDoubles.push_back(m_Visible ? 1 : 0); + return RET_DOUBLE; + case V_READONLY: + outDoubles.push_back(IsReadOnly() ? 1 : 0); + return RET_DOUBLE; + default: + g_TwMgr->SetLastError(g_ErrUnknownAttrib); + return RET_ERROR; + } +} + + +// --------------------------------------------------------------------------- + +enum EVarAtomAttribs +{ + VA_KEY_INCR = V_ENDTAG+1, + VA_KEY_DECR, + VA_MIN, + VA_MAX, + VA_STEP, + VA_PRECISION, + VA_HEXA, + VA_DECIMAL, // for backward compatibility + VA_TRUE, + VA_FALSE, + VA_ENUM, + VA_VALUE +}; + +int CTwVarAtom::HasAttrib(const char *_Attrib, bool *_HasValue) const +{ + *_HasValue = true; + if( _stricmp(_Attrib, "keyincr")==0 || _stricmp(_Attrib, "key")==0 ) + return VA_KEY_INCR; + else if( _stricmp(_Attrib, "keydecr")==0 ) + return VA_KEY_DECR; + else if( _stricmp(_Attrib, "min")==0 ) + return VA_MIN; + else if( _stricmp(_Attrib, "max")==0 ) + return VA_MAX; + else if( _stricmp(_Attrib, "step")==0 ) + return VA_STEP; + else if( _stricmp(_Attrib, "precision")==0 ) + return VA_PRECISION; + else if( _stricmp(_Attrib, "hexa")==0 ) + return VA_HEXA; + else if( _stricmp(_Attrib, "decimal")==0 ) // for backward compatibility + { + *_HasValue = false; + return VA_DECIMAL; + } + else if( _stricmp(_Attrib, "true")==0 ) + return VA_TRUE; + else if( _stricmp(_Attrib, "false")==0 ) + return VA_FALSE; + else if( _stricmp(_Attrib, "enum")==0 + || _stricmp(_Attrib, "val")==0 ) // for backward compatibility + return VA_ENUM; + else if( _stricmp(_Attrib, "value")==0 ) + return VA_VALUE; + + return CTwVar::HasAttrib(_Attrib, _HasValue); +} + +int CTwVarAtom::SetAttrib(int _AttribID, const char *_Value, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex) +{ + switch( _AttribID ) + { + case VA_KEY_INCR: + { + int Key = 0; + int Mod = 0; + if( TwGetKeyCode(&Key, &Mod, _Value) ) + { + m_KeyIncr[0] = Key; + m_KeyIncr[1] = Mod; + return 1; + } + else + return 0; + } + case VA_KEY_DECR: + { + int Key = 0; + int Mod = 0; + if( TwGetKeyCode(&Key, &Mod, _Value) ) + { + m_KeyDecr[0] = Key; + m_KeyDecr[1] = Mod; + return 1; + } + else + return 0; + } + case VA_TRUE: + if( (m_Type==TW_TYPE_BOOL8 || m_Type==TW_TYPE_BOOL16 || m_Type==TW_TYPE_BOOL32 || m_Type==TW_TYPE_BOOLCPP) && _Value!=NULL ) + { + if( m_Val.m_Bool.m_FreeTrueString && m_Val.m_Bool.m_TrueString!=NULL ) + free(m_Val.m_Bool.m_TrueString); + m_Val.m_Bool.m_TrueString = _strdup(_Value); + m_Val.m_Bool.m_FreeTrueString = true; + return 1; + } + else + return 0; + case VA_FALSE: + if( (m_Type==TW_TYPE_BOOL8 || m_Type==TW_TYPE_BOOL16 || m_Type==TW_TYPE_BOOL32 || m_Type==TW_TYPE_BOOLCPP) && _Value!=NULL ) + { + if( m_Val.m_Bool.m_FreeFalseString && m_Val.m_Bool.m_FalseString!=NULL ) + free(m_Val.m_Bool.m_FalseString); + m_Val.m_Bool.m_FalseString = _strdup(_Value); + m_Val.m_Bool.m_FreeFalseString = true; + return 1; + } + else + return 0; + case VA_MIN: + case VA_MAX: + case VA_STEP: + if( _Value && strlen(_Value)>0 ) + { + void *Ptr = NULL; + const char *Fmt = NULL; + int d = 0; + unsigned int u = 0; + int Num = (_AttribID==VA_STEP) ? 2 : ((_AttribID==VA_MAX) ? 1 : 0); + switch( m_Type ) + { + case TW_TYPE_CHAR: + //Ptr = (&m_Val.m_Char.m_Min) + Num; + //Fmt = "%c"; + Ptr = &u; + Fmt = "%u"; + break; + case TW_TYPE_INT16: + Ptr = (&m_Val.m_Int16.m_Min) + Num; + Fmt = "%hd"; + break; + case TW_TYPE_INT32: + Ptr = (&m_Val.m_Int32.m_Min) + Num; + Fmt = "%d"; + break; + case TW_TYPE_UINT16: + Ptr = (&m_Val.m_UInt16.m_Min) + Num; + Fmt = "%hu"; + break; + case TW_TYPE_UINT32: + Ptr = (&m_Val.m_UInt32.m_Min) + Num; + Fmt = "%u"; + break; + case TW_TYPE_FLOAT: + Ptr = (&m_Val.m_Float32.m_Min) + Num; + Fmt = "%f"; + break; + case TW_TYPE_DOUBLE: + Ptr = (&m_Val.m_Float64.m_Min) + Num; + Fmt = "%lf"; + break; + case TW_TYPE_INT8: + Ptr = &d; + Fmt = "%d"; + break; + case TW_TYPE_UINT8: + Ptr = &u; + Fmt = "%u"; + break; + default: + g_TwMgr->SetLastError(g_ErrUnknownType); + return 0; + } + + if( Fmt!=NULL && Ptr!=NULL && sscanf(_Value, Fmt, Ptr)==1 ) + { + if( m_Type==TW_TYPE_CHAR ) + *((&m_Val.m_Char.m_Min)+Num) = (unsigned char)(u); + else if( m_Type==TW_TYPE_INT8 ) + *((&m_Val.m_Int8.m_Min)+Num) = (signed char)(d); + else if( m_Type==TW_TYPE_UINT8 ) + *((&m_Val.m_UInt8.m_Min)+Num) = (unsigned char)(u); + + // set precision + if( _AttribID==VA_STEP && ((m_Type==TW_TYPE_FLOAT && m_Val.m_Float32.m_Precision<0) || (m_Type==TW_TYPE_DOUBLE && m_Val.m_Float64.m_Precision<0)) ) + { + double Step = fabs( (m_Type==TW_TYPE_FLOAT) ? m_Val.m_Float32.m_Step : m_Val.m_Float64.m_Step ); + signed char *Precision = (m_Type==TW_TYPE_FLOAT) ? &m_Val.m_Float32.m_Precision : &m_Val.m_Float64.m_Precision; + const double K_EPS = 1.0 - 1.0e-6; + if( Step>=1 ) + *Precision = 0; + else if( Step>=0.1*K_EPS ) + *Precision = 1; + else if( Step>=0.01*K_EPS ) + *Precision = 2; + else if( Step>=0.001*K_EPS ) + *Precision = 3; + else if( Step>=0.0001*K_EPS ) + *Precision = 4; + else if( Step>=0.00001*K_EPS ) + *Precision = 5; + else if( Step>=0.000001*K_EPS ) + *Precision = 6; + else if( Step>=0.0000001*K_EPS ) + *Precision = 7; + else if( Step>=0.00000001*K_EPS ) + *Precision = 8; + else if( Step>=0.000000001*K_EPS ) + *Precision = 9; + else if( Step>=0.0000000001*K_EPS ) + *Precision = 10; + else if( Step>=0.00000000001*K_EPS ) + *Precision = 11; + else if( Step>=0.000000000001*K_EPS ) + *Precision = 12; + else + *Precision = -1; + } + + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case VA_PRECISION: + if( _Value && strlen(_Value)>0 ) + { + int Precision = 0; + if( sscanf(_Value, "%d", &Precision)==1 && Precision>=-1 && Precision<=12 ) + { + if( m_Type==TW_TYPE_FLOAT ) + m_Val.m_Float32.m_Precision = (signed char)Precision; + else if ( m_Type==TW_TYPE_DOUBLE ) + m_Val.m_Float64.m_Precision = (signed char)Precision; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case VA_HEXA: + case VA_DECIMAL: + { + bool hexa = false; + if (_AttribID==VA_HEXA) + { + if( _Value==NULL || strlen(_Value)==0 // no value is acceptable (for backward compatibility) + || _stricmp(_Value, "true")==0 || _stricmp(_Value, "1")==0 ) + hexa = true; + } + + switch( m_Type ) + { + case TW_TYPE_CHAR: + m_Val.m_Char.m_Hexa = hexa; + return 1; + case TW_TYPE_INT8: + m_Val.m_Int8.m_Hexa = hexa; + return 1; + case TW_TYPE_INT16: + m_Val.m_Int16.m_Hexa = hexa; + return 1; + case TW_TYPE_INT32: + m_Val.m_Int32.m_Hexa = hexa; + return 1; + case TW_TYPE_UINT8: + m_Val.m_UInt8.m_Hexa = hexa; + return 1; + case TW_TYPE_UINT16: + m_Val.m_UInt16.m_Hexa = hexa; + return 1; + case TW_TYPE_UINT32: + m_Val.m_UInt32.m_Hexa = hexa; + return 1; + default: + return 0; + } + } + case VA_ENUM: + if( _Value && strlen(_Value)>0 && IsEnumType(m_Type) ) + { + const char *s = _Value; + int n = 0, i = 0; + unsigned int u; + bool Cont; + g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE].m_Entries.clear(); // anyway reset entries + do + { + Cont = false; + i = 0; + char Sep; + n = sscanf(s, "%u %c%n", &u, &Sep, &i); + if( n==2 && i>0 && ( Sep=='<' || Sep=='{' || Sep=='[' || Sep=='(' ) ) + { + if( Sep=='<' ) // Change to closing separator + Sep = '>'; + else if( Sep=='{' ) + Sep = '}'; + else if( Sep=='[' ) + Sep = ']'; + else if( Sep=='(' ) + Sep = ')'; + s += i; + i = 0; + while( s[i]!=Sep && s[i]!=0 ) + ++i; + if( s[i]==Sep ) + { + //if( m_Val.m_Enum.m_Entries==NULL ) + // m_Val.m_Enum.m_Entries = new UVal::CEnumVal::CEntries; + //UVal::CEnumVal::CEntries::value_type v(u, ""); + CTwMgr::CEnum::CEntries::value_type v(u, ""); + if( i>0 ) + v.second.assign(s, i); + //m_Val.m_Enum.m_Entries->insert(v); + pair ret; + ret = g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE].m_Entries.insert(v); + if( !ret.second ) // force overwrite if element already exists + { + g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE].m_Entries.erase(ret.first); + g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE].m_Entries.insert(v); + } + + s += i+1; + i = 0; + n = sscanf(s, " ,%n", &i); + if( n==0 && i>=1 ) + { + s += i; + Cont = true; + } + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } while( Cont ); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + break; + case VA_VALUE: + if( _Value!=NULL && strlen(_Value)>0 ) // do not check ReadOnly here. + { + if( !( m_Type==TW_TYPE_BUTTON || IsCustom() ) ) // || (m_Type>=TW_TYPE_CUSTOM_BASE && m_Typem_Customs.size()) ) ) + { + if( m_Type==TW_TYPE_CDSTRING || m_Type==TW_TYPE_CDSTDSTRING ) + { + if( m_SetCallback!=NULL ) + { + m_SetCallback(&_Value, m_ClientData); + if( g_TwMgr!=NULL ) // Mgr might have been destroyed by the client inside a callback call + _Bar->NotUpToDate(); + return 1; + } + else if( m_Type!=TW_TYPE_CDSTDSTRING ) + { + char **StringPtr = (char **)m_Ptr; + if( StringPtr!=NULL && g_TwMgr->m_CopyCDStringToClient!=NULL ) + { + g_TwMgr->m_CopyCDStringToClient(StringPtr, _Value); + _Bar->NotUpToDate(); + return 1; + } + } + } + else if( IsCSStringType(m_Type) ) + { + int n = TW_CSSTRING_SIZE(m_Type); + if( n>0 ) + { + string str = _Value; + if( (int)str.length()>n-1 ) + str.resize(n-1); + if( m_SetCallback!=NULL ) + { + m_SetCallback(str.c_str(), m_ClientData); + if( g_TwMgr!=NULL ) // Mgr might have been destroyed by the client inside a callback call + _Bar->NotUpToDate(); + return 1; + } + else if( m_Ptr!=NULL ) + { + if( n>1 ) + strncpy((char *)m_Ptr, str.c_str(), n-1); + ((char *)m_Ptr)[n-1] = '\0'; + _Bar->NotUpToDate(); + return 1; + } + } + } + else + { + double dbl; + if( sscanf(_Value, "%lf", &dbl)==1 ) + { + ValueFromDouble(dbl); + if( g_TwMgr!=NULL ) // Mgr might have been destroyed by the client inside a callback call + _Bar->NotUpToDate(); + return 1; + } + } + } + } + return 0; + default: + return CTwVar::SetAttrib(_AttribID, _Value, _Bar, _VarParent, _VarIndex); + } +} + +ERetType CTwVarAtom::GetAttrib(int _AttribID, TwBar *_Bar, CTwVarGroup *_VarParent, int _VarIndex, std::vector& outDoubles, std::ostringstream& outString) const +{ + outDoubles.clear(); + outString.clear(); + std::string str; + int num = 0; + + switch( _AttribID ) + { + case VA_KEY_INCR: + if( TwGetKeyString(&str, m_KeyIncr[0], m_KeyIncr[1]) ) + outString << str; + return RET_STRING; + case VA_KEY_DECR: + if( TwGetKeyString(&str, m_KeyDecr[0], m_KeyDecr[1]) ) + outString << str; + return RET_STRING; + case VA_TRUE: + if( m_Type==TW_TYPE_BOOL8 || m_Type==TW_TYPE_BOOL16 || m_Type==TW_TYPE_BOOL32 || m_Type==TW_TYPE_BOOLCPP ) + { + outString << m_Val.m_Bool.m_TrueString; + return RET_STRING; + } + else + { + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + } + case VA_FALSE: + if( m_Type==TW_TYPE_BOOL8 || m_Type==TW_TYPE_BOOL16 || m_Type==TW_TYPE_BOOL32 || m_Type==TW_TYPE_BOOLCPP ) + { + outString << m_Val.m_Bool.m_FalseString; + return RET_STRING; + } + else + { + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + } + case VA_MIN: + case VA_MAX: + case VA_STEP: + num = (_AttribID==VA_STEP) ? 2 : ((_AttribID==VA_MAX) ? 1 : 0); + switch( m_Type ) + { + case TW_TYPE_CHAR: + outDoubles.push_back( *((&m_Val.m_Char.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_INT8: + outDoubles.push_back( *((&m_Val.m_Int8.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_UINT8: + outDoubles.push_back( *((&m_Val.m_UInt8.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_INT16: + outDoubles.push_back( *((&m_Val.m_Int16.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_INT32: + outDoubles.push_back( *((&m_Val.m_Int32.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_UINT16: + outDoubles.push_back( *((&m_Val.m_UInt16.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_UINT32: + outDoubles.push_back( *((&m_Val.m_UInt32.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_FLOAT: + outDoubles.push_back( *((&m_Val.m_Float32.m_Min) + num) ); + return RET_DOUBLE; + case TW_TYPE_DOUBLE: + outDoubles.push_back( *((&m_Val.m_Float64.m_Min) + num) ); + return RET_DOUBLE; + default: + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + } + case VA_PRECISION: + if( m_Type==TW_TYPE_FLOAT ) + { + outDoubles.push_back( m_Val.m_Float32.m_Precision ); + return RET_DOUBLE; + } + else if ( m_Type==TW_TYPE_DOUBLE ) + { + outDoubles.push_back( m_Val.m_Float64.m_Precision ); + return RET_DOUBLE; + } + else + { + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + } + case VA_HEXA: + switch( m_Type ) + { + case TW_TYPE_CHAR: + outDoubles.push_back( m_Val.m_Char.m_Hexa ); + return RET_DOUBLE; + case TW_TYPE_INT8: + outDoubles.push_back( m_Val.m_Int8.m_Hexa ); + return RET_DOUBLE; + case TW_TYPE_INT16: + outDoubles.push_back( m_Val.m_Int16.m_Hexa ); + return RET_DOUBLE; + case TW_TYPE_INT32: + outDoubles.push_back( m_Val.m_Int32.m_Hexa ); + return RET_DOUBLE; + case TW_TYPE_UINT8: + outDoubles.push_back( m_Val.m_UInt8.m_Hexa ); + return RET_DOUBLE; + case TW_TYPE_UINT16: + outDoubles.push_back( m_Val.m_UInt16.m_Hexa ); + return RET_DOUBLE; + case TW_TYPE_UINT32: + outDoubles.push_back( m_Val.m_UInt32.m_Hexa ); + return RET_DOUBLE; + default: + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + } + case VA_ENUM: + if( IsEnumType(m_Type) ) + { + CTwMgr::CEnum::CEntries::iterator it = g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE].m_Entries.begin(); + for( ; it != g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE].m_Entries.end(); ++it ) + { + if( it != g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE].m_Entries.begin() ) + outString << ','; + outString << it->first << ' '; + if( it->second.find_first_of("{}")==std::string::npos ) + outString << '{' << it->second << '}'; + else if ( it->second.find_first_of("<>")==std::string::npos ) + outString << '<' << it->second << '>'; + else if ( it->second.find_first_of("()")==std::string::npos ) + outString << '(' << it->second << ')'; + else if ( it->second.find_first_of("[]")==std::string::npos ) + outString << '[' << it->second << ']'; + else + outString << '{' << it->second << '}'; // should not occured (use braces) + } + return RET_STRING; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + case VA_VALUE: + if( !( m_Type==TW_TYPE_BUTTON || IsCustom() ) ) // || (m_Type>=TW_TYPE_CUSTOM_BASE && m_Typem_Customs.size()) ) ) + { + if( m_Type==TW_TYPE_CDSTRING || m_Type==TW_TYPE_CDSTDSTRING || IsCSStringType(m_Type) ) + { + string str; + ValueToString(&str); + outString << str; + return RET_STRING; + } + else + { + outDoubles.push_back( ValueToDouble() ); + return RET_DOUBLE; + } + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + default: + return CTwVar::GetAttrib(_AttribID, _Bar, _VarParent, _VarIndex, outDoubles, outString); + } +} + +// --------------------------------------------------------------------------- + +void CTwVarAtom::Increment(int _Step) +{ + if( _Step==0 ) + return; + switch( m_Type ) + { + case TW_TYPE_BOOL8: + { + char v = false; + if( m_Ptr!=NULL ) + v = *((char *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + if( v ) + v = false; + else + v = true; + if( m_Ptr!=NULL ) + *((char *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_BOOL16: + { + short v = false; + if( m_Ptr!=NULL ) + v = *((short *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + if( v ) + v = false; + else + v = true; + if( m_Ptr!=NULL ) + *((short *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_BOOL32: + { + int v = false; + if( m_Ptr!=NULL ) + v = *((int *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + if( v ) + v = false; + else + v = true; + if( m_Ptr!=NULL ) + *((int *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_BOOLCPP: + { + bool v = false; + if( m_Ptr!=NULL ) + v = *((bool *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + if( v ) + v = false; + else + v = true; + if( m_Ptr!=NULL ) + *((bool *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_CHAR: + { + unsigned char v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned char *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + int iv = _Step*(int)m_Val.m_Char.m_Step + (int)v; + if( ivm_Val.m_Char.m_Max ) + iv = m_Val.m_Char.m_Max; + if( iv<0 ) + iv = 0; + else if( iv>0xff ) + iv = 0xff; + v = (unsigned char)iv; + if( m_Ptr!=NULL ) + *((unsigned char *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_INT8: + { + signed char v = 0; + if( m_Ptr!=NULL ) + v = *((signed char *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + int iv = _Step*(int)m_Val.m_Int8.m_Step + (int)v; + if( ivm_Val.m_Int8.m_Max ) + iv = m_Val.m_Int8.m_Max; + v = (signed char)iv; + if( m_Ptr!=NULL ) + *((signed char *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_UINT8: + { + unsigned char v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned char *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + int iv = _Step*(int)m_Val.m_UInt8.m_Step + (int)v; + if( ivm_Val.m_UInt8.m_Max ) + iv = m_Val.m_UInt8.m_Max; + if( iv<0 ) + iv = 0; + else if( iv>0xff ) + iv = 0xff; + v = (unsigned char)iv; + if( m_Ptr!=NULL ) + *((unsigned char *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_INT16: + { + short v = 0; + if( m_Ptr!=NULL ) + v = *((short *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + int iv = _Step*(int)m_Val.m_Int16.m_Step + (int)v; + if( ivm_Val.m_Int16.m_Max ) + iv = m_Val.m_Int16.m_Max; + v = (short)iv; + if( m_Ptr!=NULL ) + *((short *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_UINT16: + { + unsigned short v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned short *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + int iv = _Step*(int)m_Val.m_UInt16.m_Step + (int)v; + if( ivm_Val.m_UInt16.m_Max ) + iv = m_Val.m_UInt16.m_Max; + if( iv<0 ) + iv = 0; + else if( iv>0xffff ) + iv = 0xffff; + v = (unsigned short)iv; + if( m_Ptr!=NULL ) + *((unsigned short *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_INT32: + { + int v = 0; + if( m_Ptr!=NULL ) + v = *((int *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + double dv = (double)_Step*(double)m_Val.m_Int32.m_Step + (double)v; + if( dv>(double)0x7fffffff ) + v = 0x7fffffff; + else if( dv<(double)(-0x7fffffff-1) ) + v = -0x7fffffff-1; + else + v = _Step*m_Val.m_Int32.m_Step + v; + if( vm_Val.m_Int32.m_Max ) + v = m_Val.m_Int32.m_Max; + if( m_Ptr!=NULL ) + *((int *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_UINT32: + { + unsigned int v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned int *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + double dv = (double)_Step*(double)m_Val.m_UInt32.m_Step + (double)v; + if( dv>(double)0xffffffff ) + v = 0xffffffff; + else if( dv<0 ) + v = 0; + else + v = _Step*m_Val.m_UInt32.m_Step + v; + if( vm_Val.m_UInt32.m_Max ) + v = m_Val.m_UInt32.m_Max; + if( m_Ptr!=NULL ) + *((unsigned int *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_FLOAT: + { + float v = 0; + if( m_Ptr!=NULL ) + v = *((float *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + v += _Step*m_Val.m_Float32.m_Step; + if( vm_Val.m_Float32.m_Max ) + v = m_Val.m_Float32.m_Max; + if( m_Ptr!=NULL ) + *((float *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + case TW_TYPE_DOUBLE: + { + double v = 0; + if( m_Ptr!=NULL ) + v = *((double *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + v += _Step*m_Val.m_Float64.m_Step; + if( vm_Val.m_Float64.m_Max ) + v = m_Val.m_Float64.m_Max; + if( m_Ptr!=NULL ) + *((double *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + break; + /* + case TW_TYPE_ENUM8: + { + assert(_Step==1 || _Step==-1); + unsigned char v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned char *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + if( m_Val.m_Enum.m_Entries!=NULL ) + { + UVal::CEnumVal::CEntries::iterator It = m_Val.m_Enum.m_Entries->find(v); + if( It==m_Val.m_Enum.m_Entries->end() ) + It = m_Val.m_Enum.m_Entries->begin(); + else if( _Step==1 ) + { + ++It; + if( It==m_Val.m_Enum.m_Entries->end() ) + It = m_Val.m_Enum.m_Entries->begin(); + } + else if( _Step==-1 ) + { + if( It==m_Val.m_Enum.m_Entries->begin() ) + It = m_Val.m_Enum.m_Entries->end(); + if( It!=m_Val.m_Enum.m_Entries->begin() ) + --It; + } + if( It != m_Val.m_Enum.m_Entries->end() ) + { + v = (unsigned char)(It->first); + if( m_Ptr!=NULL ) + *((unsigned char *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + } + } + break; + case TW_TYPE_ENUM16: + { + assert(_Step==1 || _Step==-1); + unsigned short v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned short *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + if( m_Val.m_Enum.m_Entries!=NULL ) + { + UVal::CEnumVal::CEntries::iterator It = m_Val.m_Enum.m_Entries->find(v); + if( It==m_Val.m_Enum.m_Entries->end() ) + It = m_Val.m_Enum.m_Entries->begin(); + else if( _Step==1 ) + { + ++It; + if( It==m_Val.m_Enum.m_Entries->end() ) + It = m_Val.m_Enum.m_Entries->begin(); + } + else if( _Step==-1 ) + { + if( It==m_Val.m_Enum.m_Entries->begin() ) + It = m_Val.m_Enum.m_Entries->end(); + if( It!=m_Val.m_Enum.m_Entries->begin() ) + --It; + } + if( It != m_Val.m_Enum.m_Entries->end() ) + { + v = (unsigned short)(It->first); + if( m_Ptr!=NULL ) + *((unsigned short *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + } + } + break; + case TW_TYPE_ENUM32: + { + assert(_Step==1 || _Step==-1); + unsigned int v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned int *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + if( m_Val.m_Enum.m_Entries!=NULL ) + { + UVal::CEnumVal::CEntries::iterator It = m_Val.m_Enum.m_Entries->find(v); + if( It==m_Val.m_Enum.m_Entries->end() ) + It = m_Val.m_Enum.m_Entries->begin(); + else if( _Step==1 ) + { + ++It; + if( It==m_Val.m_Enum.m_Entries->end() ) + It = m_Val.m_Enum.m_Entries->begin(); + } + else if( _Step==-1 ) + { + if( It==m_Val.m_Enum.m_Entries->begin() ) + It = m_Val.m_Enum.m_Entries->end(); + if( It!=m_Val.m_Enum.m_Entries->begin() ) + --It; + } + if( It!=m_Val.m_Enum.m_Entries->end() ) + { + v = (unsigned int)(It->first); + if( m_Ptr!=NULL ) + *((unsigned int *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + } + } + break; + */ + default: + if( m_Type==TW_TYPE_BUTTON ) + { + if( m_Val.m_Button.m_Callback!=NULL ) + { + m_Val.m_Button.m_Callback(m_ClientData); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return; + } + } + else if( IsEnumType(m_Type) ) + { + assert(_Step==1 || _Step==-1); + unsigned int v = 0; + if( m_Ptr!=NULL ) + v = *((unsigned int *)m_Ptr); + else if( m_GetCallback!=NULL ) + m_GetCallback(&v, m_ClientData); + CTwMgr::CEnum& e = g_TwMgr->m_Enums[m_Type-TW_TYPE_ENUM_BASE]; + CTwMgr::CEnum::CEntries::iterator It = e.m_Entries.find(v); + if( It==e.m_Entries.end() ) + It = e.m_Entries.begin(); + else if( _Step==1 ) + { + ++It; + if( It==e.m_Entries.end() ) + It = e.m_Entries.begin(); + } + else if( _Step==-1 ) + { + if( It==e.m_Entries.begin() ) + It = e.m_Entries.end(); + if( It!=e.m_Entries.begin() ) + --It; + } + if( It!=e.m_Entries.end() ) + { + v = (unsigned int)(It->first); + if( m_Ptr!=NULL ) + *((unsigned int *)m_Ptr) = v; + else if( m_SetCallback!=NULL ) + m_SetCallback(&v, m_ClientData); + } + } + else + fprintf(stderr, "CTwVarAtom::Increment : unknown or unimplemented type\n"); + } +} + +// --------------------------------------------------------------------------- + +void CTwVarAtom::SetDefaults() +{ + switch( m_Type ) + { + case TW_TYPE_BOOL8: + case TW_TYPE_BOOL16: + case TW_TYPE_BOOL32: + case TW_TYPE_BOOLCPP: + m_NoSlider = true; + break; + case TW_TYPE_CHAR: + m_Val.m_Char.m_Max = 0xff; + m_Val.m_Char.m_Min = 0; + m_Val.m_Char.m_Step = 1; + m_Val.m_Char.m_Precision = -1; + m_Val.m_Char.m_Hexa = false; + break; + case TW_TYPE_INT8: + m_Val.m_Int8.m_Max = 0x7f; + m_Val.m_Int8.m_Min = -m_Val.m_Int8.m_Max-1; + m_Val.m_Int8.m_Step = 1; + m_Val.m_Int8.m_Precision = -1; + m_Val.m_Int8.m_Hexa = false; + break; + case TW_TYPE_UINT8: + m_Val.m_UInt8.m_Max = 0xff; + m_Val.m_UInt8.m_Min = 0; + m_Val.m_UInt8.m_Step = 1; + m_Val.m_UInt8.m_Precision = -1; + m_Val.m_UInt8.m_Hexa = false; + break; + case TW_TYPE_INT16: + m_Val.m_Int16.m_Max = 0x7fff; + m_Val.m_Int16.m_Min = -m_Val.m_Int16.m_Max-1; + m_Val.m_Int16.m_Step = 1; + m_Val.m_Int16.m_Precision = -1; + m_Val.m_Int16.m_Hexa = false; + break; + case TW_TYPE_UINT16: + m_Val.m_UInt16.m_Max = 0xffff; + m_Val.m_UInt16.m_Min = 0; + m_Val.m_UInt16.m_Step = 1; + m_Val.m_UInt16.m_Precision = -1; + m_Val.m_UInt16.m_Hexa = false; + break; + case TW_TYPE_INT32: + m_Val.m_Int32.m_Max = 0x7fffffff; + m_Val.m_Int32.m_Min = -m_Val.m_Int32.m_Max-1; + m_Val.m_Int32.m_Step = 1; + m_Val.m_Int32.m_Precision = -1; + m_Val.m_Int32.m_Hexa = false; + break; + case TW_TYPE_UINT32: + m_Val.m_UInt32.m_Max = 0xffffffff; + m_Val.m_UInt32.m_Min = 0; + m_Val.m_UInt32.m_Step = 1; + m_Val.m_UInt32.m_Precision = -1; + m_Val.m_UInt32.m_Hexa = false; + break; + case TW_TYPE_FLOAT: + m_Val.m_Float32.m_Max = FLOAT_MAX; + m_Val.m_Float32.m_Min = -FLOAT_MAX; + m_Val.m_Float32.m_Step = 1; + m_Val.m_Float32.m_Precision = -1; + m_Val.m_Float32.m_Hexa = false; + break; + case TW_TYPE_DOUBLE: + m_Val.m_Float64.m_Max = DOUBLE_MAX; + m_Val.m_Float64.m_Min = -DOUBLE_MAX; + m_Val.m_Float64.m_Step = 1; + m_Val.m_Float64.m_Precision = -1; + m_Val.m_Float64.m_Hexa = false; + break; + case TW_TYPE_CDSTRING: + case TW_TYPE_STDSTRING: + m_NoSlider = true; + break; + /* + case TW_TYPE_ENUM8: + case TW_TYPE_ENUM16: + case TW_TYPE_ENUM32: + m_NoSlider = true; + break; + */ + default: + {} // nothing + } + + // special types + if( m_Type==TW_TYPE_BUTTON + || IsEnumType(m_Type) // (m_Type>=TW_TYPE_ENUM_BASE && m_Typem_Enums.size()) + || IsCSStringType(m_Type) // (m_Type>=TW_TYPE_CSSTRING_BASE && m_Type<=TW_TYPE_CSSTRING_MAX) + || m_Type==TW_TYPE_CDSTDSTRING + || IsCustom() ) // (m_Type>=TW_TYPE_CUSTOM_BASE && m_Typem_Customs.size()) ) + m_NoSlider = true; +} + +// --------------------------------------------------------------------------- + +/* +int CTwVarAtom::DefineEnum(const TwEnumVal *_EnumValues, unsigned int _NbValues) +{ + assert(_EnumValues!=NULL); + if( m_Type!=TW_TYPE_ENUM8 && m_Type!=TW_TYPE_ENUM16 && m_Type!=TW_TYPE_ENUM32 ) + { + g_TwMgr->SetLastError(g_ErrNotEnum); + return 0; + } + if( m_Val.m_Enum.m_Entries==NULL ) + m_Val.m_Enum.m_Entries = new UVal::CEnumVal::CEntries; + for(unsigned int i=0; i<_NbValues; ++i) + { + UVal::CEnumVal::CEntries::value_type Entry(_EnumValues[i].Value, (_EnumValues[i].Label!=NULL)?_EnumValues[i].Label:""); + pair Result = m_Val.m_Enum.m_Entries->insert(Entry); + if( !Result.second ) + (Result.first)->second = Entry.second; + } + return 1; +} +*/ + +// --------------------------------------------------------------------------- + +enum EVarGroupAttribs +{ + VG_OPEN = V_ENDTAG+1, // for backward compatibility + VG_CLOSE, // for backward compatibility + VG_OPENED, + VG_TYPEID, // used internally for structs + VG_VALPTR, // used internally for structs + VG_ALPHA, // for backward compatibility + VG_NOALPHA, // for backward compatibility + VG_COLORALPHA, // tw_type_color* only + VG_HLS, // for backward compatibility + VG_RGB, // for backward compatibility + VG_COLORMODE, // tw_type_color* only + VG_COLORORDER, // tw_type_color* only + VG_ARROW, // tw_type_quat* only + VG_ARROWCOLOR, // tw_type_quat* only + VG_AXISX, // tw_type_quat* only + VG_AXISY, // tw_type_quat* only + VG_AXISZ, // tw_type_quat* only + VG_SHOWVAL // tw_type_quat* only +}; + +int CTwVarGroup::HasAttrib(const char *_Attrib, bool *_HasValue) const +{ + *_HasValue = false; + if( _stricmp(_Attrib, "open")==0 ) // for backward compatibility + return VG_OPEN; + else if( _stricmp(_Attrib, "close")==0 ) // for backward compatibility + return VG_CLOSE; + else if( _stricmp(_Attrib, "opened")==0 ) + { + *_HasValue = true; + return VG_OPENED; + } + else if( _stricmp(_Attrib, "typeid")==0 ) + { + *_HasValue = true; + return VG_TYPEID; + } + else if( _stricmp(_Attrib, "valptr")==0 ) + { + *_HasValue = true; + return VG_VALPTR; + } + else if( _stricmp(_Attrib, "alpha")==0 ) // for backward compatibility + return VG_ALPHA; + else if( _stricmp(_Attrib, "noalpha")==0 ) // for backward compatibility + return VG_NOALPHA; + else if( _stricmp(_Attrib, "coloralpha")==0 ) + { + *_HasValue = true; + return VG_COLORALPHA; + } + else if( _stricmp(_Attrib, "hls")==0 ) // for backward compatibility + return VG_HLS; + else if( _stricmp(_Attrib, "rgb")==0 ) // for backward compatibility + return VG_RGB; + else if( _stricmp(_Attrib, "colormode")==0 ) + { + *_HasValue = true; + return VG_COLORMODE; + } + else if( _stricmp(_Attrib, "colororder")==0 ) + { + *_HasValue = true; + return VG_COLORORDER; + } + else if( _stricmp(_Attrib, "arrow")==0 ) + { + *_HasValue = true; + return VG_ARROW; + } + else if( _stricmp(_Attrib, "arrowcolor")==0 ) + { + *_HasValue = true; + return VG_ARROWCOLOR; + } + else if( _stricmp(_Attrib, "axisx")==0 ) + { + *_HasValue = true; + return VG_AXISX; + } + else if( _stricmp(_Attrib, "axisy")==0 ) + { + *_HasValue = true; + return VG_AXISY; + } + else if( _stricmp(_Attrib, "axisz")==0 ) + { + *_HasValue = true; + return VG_AXISZ; + } + else if( _stricmp(_Attrib, "showval")==0 ) + { + *_HasValue = true; + return VG_SHOWVAL; + } + + return CTwVar::HasAttrib(_Attrib, _HasValue); +} + +int CTwVarGroup::SetAttrib(int _AttribID, const char *_Value, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex) +{ + switch( _AttribID ) + { + case VG_OPEN: // for backward compatibility + if( !m_Open ) + { + m_Open = true; + _Bar->NotUpToDate(); + } + return 1; + case VG_CLOSE: // for backward compatibility + if( m_Open ) + { + m_Open = false; + _Bar->NotUpToDate(); + } + return 1; + case VG_OPENED: + if( _Value!=NULL && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "true")==0 || _stricmp(_Value, "1")==0 ) + { + if( !m_Open ) + { + m_Open = true; + _Bar->NotUpToDate(); + } + return 1; + } + else if( _stricmp(_Value, "false")==0 || _stricmp(_Value, "0")==0 ) + { + if( m_Open ) + { + m_Open = false; + _Bar->NotUpToDate(); + } + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case VG_TYPEID: + { + int type = TW_TYPE_UNDEF; + if( _Value!=NULL && sscanf(_Value, "%d", &type)==1 ) + { + int idx = type - TW_TYPE_STRUCT_BASE; + if( idx>=0 && idx<(int)g_TwMgr->m_Structs.size() ) + { + m_SummaryCallback = g_TwMgr->m_Structs[idx].m_SummaryCallback; + m_SummaryClientData = g_TwMgr->m_Structs[idx].m_SummaryClientData; + m_StructType = (TwType)type; + return 1; + } + } + return 0; + } + case VG_VALPTR: + { + void *structValuePtr = NULL; + if( _Value!=NULL && sscanf(_Value, "%p", &structValuePtr)==1 ) + { + m_StructValuePtr = structValuePtr; + m_ColorPtr = &(_Bar->m_ColStructText); + return 1; + } + return 0; + } + case VG_ALPHA: // for backward compatibility + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + if( static_cast(m_StructValuePtr)->m_CanHaveAlpha ) + { + static_cast(m_StructValuePtr)->m_HasAlpha = true; + _Bar->NotUpToDate(); + return 1; + } + return 0; + case VG_NOALPHA: // for backward compatibility + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + static_cast(m_StructValuePtr)->m_HasAlpha = false; + _Bar->NotUpToDate(); + return 1; + } + else + return 0; + case VG_COLORALPHA: + if( _Value!=NULL && strlen(_Value)>0 ) + { + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + if( _stricmp(_Value, "true")==0 || _stricmp(_Value, "1")==0 ) + { + if( static_cast(m_StructValuePtr)->m_CanHaveAlpha ) + { + if( !static_cast(m_StructValuePtr)->m_HasAlpha ) + { + static_cast(m_StructValuePtr)->m_HasAlpha = true; + _Bar->NotUpToDate(); + } + return 1; + } + } + else if( _stricmp(_Value, "false")==0 || _stricmp(_Value, "0")==0 ) + { + if( static_cast(m_StructValuePtr)->m_HasAlpha ) + { + static_cast(m_StructValuePtr)->m_HasAlpha = false; + _Bar->NotUpToDate(); + } + return 1; + } + } + } + return 0; + case VG_HLS: // for backward compatibility + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + static_cast(m_StructValuePtr)->m_HLS = true; + _Bar->NotUpToDate(); + return 1; + } + else + return 0; + case VG_RGB: // for backward compatibility + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + static_cast(m_StructValuePtr)->m_HLS = false; + _Bar->NotUpToDate(); + return 1; + } + else + return 0; + case VG_COLORMODE: + if( _Value!=NULL && strlen(_Value)>0 ) + { + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + if( _stricmp(_Value, "hls")==0 ) + { + if( !static_cast(m_StructValuePtr)->m_HLS ) + { + static_cast(m_StructValuePtr)->m_HLS = true; + _Bar->NotUpToDate(); + } + return 1; + } + else if( _stricmp(_Value, "rgb")==0 ) + { + if( static_cast(m_StructValuePtr)->m_HLS ) + { + static_cast(m_StructValuePtr)->m_HLS = false; + _Bar->NotUpToDate(); + } + return 1; + } + } + } + return 0; + case VG_COLORORDER: + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + if( _Value!=NULL ) + { + if( _stricmp(_Value, "rgba")==0 ) + static_cast(m_StructValuePtr)->m_OGL = true; + else if( _stricmp(_Value, "argb")==0 ) + static_cast(m_StructValuePtr)->m_OGL = false; + else + return 0; + return 1; + } + return 0; + } + else + return 0; + case VG_ARROW: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + if( _Value!=NULL ) + { + double *dir = static_cast(m_StructValuePtr)->m_Dir; + double x, y, z; + if( sscanf(_Value, "%lf %lf %lf", &x, &y, &z)==3 ) + { + dir[0] = x; + dir[1] = y; + dir[2] = z; + } + else if( _stricmp(_Value, "off")==0 || _stricmp(_Value, "0")==0 ) + dir[0] = dir[1] = dir[2] = 0; + else + return 0; + return 1; + } + return 0; + } + else + return 0; + case VG_ARROWCOLOR: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + if( _Value!=NULL ) + { + int r, g, b; + if( sscanf(_Value, "%d %d %d", &r, &g, &b)==3 ) + static_cast(m_StructValuePtr)->m_DirColor = Color32FromARGBi(255, r, g, b); + else + return 0; + return 1; + } + return 0; + } + else + return 0; + case VG_AXISX: + case VG_AXISY: + case VG_AXISZ: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + if( _Value!=NULL ) + { + float x = 0, y = 0, z = 0; + if( _stricmp(_Value, "x")==0 || _stricmp(_Value, "+x")==0 ) + x = 1; + else if( _stricmp(_Value, "-x")==0 ) + x = -1; + else if( _stricmp(_Value, "y")==0 || _stricmp(_Value, "+y")==0 ) + y = 1; + else if( _stricmp(_Value, "-y")==0 ) + y = -1; + else if( _stricmp(_Value, "z")==0 || _stricmp(_Value, "+z")==0 ) + z = 1; + else if( _stricmp(_Value, "-z")==0 ) + z = -1; + else + return 0; + int i = (_AttribID==VG_AXISX) ? 0 : ((_AttribID==VG_AXISY) ? 1 : 2); + static_cast(m_StructValuePtr)->m_Permute[i][0] = x; + static_cast(m_StructValuePtr)->m_Permute[i][1] = y; + static_cast(m_StructValuePtr)->m_Permute[i][2] = z; + return 1; + } + return 0; + } + else + return 0; + case VG_SHOWVAL: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + if( _Value!=NULL ) + { + if( _stricmp(_Value, "true")==0 || _stricmp(_Value, "on")==0 || _stricmp(_Value, "1")==0 ) + { + static_cast(m_StructValuePtr)->m_ShowVal = true; + _Bar->NotUpToDate(); + return 1; + } + else if( _stricmp(_Value, "false")==0 || _stricmp(_Value, "off")==0 || _stricmp(_Value, "0")==0 ) + { + static_cast(m_StructValuePtr)->m_ShowVal = false; + _Bar->NotUpToDate(); + return 1; + } + } + return 0; + } + else + return 0; + default: + return CTwVar::SetAttrib(_AttribID, _Value, _Bar, _VarParent, _VarIndex); + } +} + +ERetType CTwVarGroup::GetAttrib(int _AttribID, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex, std::vector& outDoubles, std::ostringstream& outString) const +{ + outDoubles.clear(); + outString.clear(); + + switch( _AttribID ) + { + case VG_OPENED: + outDoubles.push_back( m_Open ); + return RET_DOUBLE; + case VG_COLORALPHA: + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + outDoubles.push_back( static_cast(m_StructValuePtr)->m_HasAlpha ); + return RET_DOUBLE; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + case VG_COLORMODE: + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + if( static_cast(m_StructValuePtr)->m_HLS ) + outString << "hls"; + else + outString << "rgb"; + return RET_STRING; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + case VG_COLORORDER: + if( m_SummaryCallback==CColorExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_color? + { + if( static_cast(m_StructValuePtr)->m_OGL ) + outString << "rgba"; + else + outString << "argb"; + return RET_STRING; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + case VG_ARROW: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + double *dir = static_cast(m_StructValuePtr)->m_Dir; + outDoubles.push_back(dir[0]); + outDoubles.push_back(dir[1]); + outDoubles.push_back(dir[2]); + return RET_DOUBLE; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + case VG_ARROWCOLOR: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + int a, r, g, b; + a = r = g = b = 0; + Color32ToARGBi(static_cast(m_StructValuePtr)->m_DirColor, &a, &r, &g, &b); + outDoubles.push_back(r); + outDoubles.push_back(g); + outDoubles.push_back(b); + return RET_DOUBLE; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + case VG_AXISX: + case VG_AXISY: + case VG_AXISZ: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + int i = (_AttribID==VG_AXISX) ? 0 : ((_AttribID==VG_AXISY) ? 1 : 2); + float x = static_cast(m_StructValuePtr)->m_Permute[i][0]; + float y = static_cast(m_StructValuePtr)->m_Permute[i][1]; + float z = static_cast(m_StructValuePtr)->m_Permute[i][2]; + if( x>0 ) + outString << "+x"; + else if( x<0 ) + outString << "-x"; + else if( y>0 ) + outString << "+y"; + else if( y<0 ) + outString << "-y"; + else if( z>0 ) + outString << "+z"; + else if( z<0 ) + outString << "-z"; + else + outString << "0"; // should not happened + return RET_DOUBLE; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + case VG_SHOWVAL: + if( m_SummaryCallback==CQuaternionExt::SummaryCB && m_StructValuePtr!=NULL ) // is tw_type_quat? + { + outDoubles.push_back( static_cast(m_StructValuePtr)->m_ShowVal ); + return RET_DOUBLE; + } + g_TwMgr->SetLastError(g_ErrInvalidAttrib); + return RET_ERROR; + default: + return CTwVar::GetAttrib(_AttribID, _Bar, _VarParent, _VarIndex, outDoubles, outString); + } +} + +// --------------------------------------------------------------------------- + +const CTwVar *CTwVarGroup::Find(const char *_Name, CTwVarGroup **_Parent, int *_Index) const +{ + if( strcmp(_Name, m_Name.c_str())==0 ) + { + if( _Parent!=NULL ) + *_Parent = NULL; + if( _Index!=NULL ) + *_Index = -1; + return this; + } + else + { + const CTwVar *v; + for( size_t i=0; iFind(_Name, _Parent, _Index); + if( v!=NULL ) + { + if( _Parent!=NULL && *_Parent==NULL ) + { + *_Parent = const_cast(this); + if( _Index!=NULL ) + *_Index = (int)i; + } + return v; + } + } + return NULL; + } +} + +// --------------------------------------------------------------------------- + +size_t CTwVar::GetDataSize(TwType _Type) +{ + switch( _Type ) + { + case TW_TYPE_BOOLCPP: + return sizeof(bool); + case TW_TYPE_BOOL8: + case TW_TYPE_CHAR: + case TW_TYPE_INT8: + case TW_TYPE_UINT8: + //case TW_TYPE_ENUM8: + return 1; + case TW_TYPE_BOOL16: + case TW_TYPE_INT16: + case TW_TYPE_UINT16: + //case TW_TYPE_ENUM16: + return 2; + case TW_TYPE_BOOL32: + case TW_TYPE_INT32: + case TW_TYPE_UINT32: + case TW_TYPE_FLOAT: + //case TW_TYPE_ENUM32: + return 4; + case TW_TYPE_DOUBLE: + return 8; + case TW_TYPE_CDSTRING: + return sizeof(char *); + case TW_TYPE_STDSTRING: + return (g_TwMgr!=0) ? g_TwMgr->m_ClientStdStringStructSize : sizeof(std::string); + default: + if( g_TwMgr && _Type>=TW_TYPE_STRUCT_BASE && _Typem_Structs.size() ) + { + const CTwMgr::CStruct& s = g_TwMgr->m_Structs[_Type-TW_TYPE_STRUCT_BASE]; + return s.m_Size; + /* + size_t size = 0; + for( size_t i=0; im_ClientStdStringStructSize : sizeof(std::string); + else // includes TW_TYPE_BUTTON + return 0; + } +} + +// --------------------------------------------------------------------------- + +CTwBar::CTwBar(const char *_Name) +{ + assert(g_TwMgr!=NULL && g_TwMgr->m_Graph!=NULL); + + m_Name = _Name; + m_Visible = true; + m_VarRoot.m_IsRoot = true; + m_VarRoot.m_Open = true; + m_VarRoot.m_SummaryCallback = NULL; + m_VarRoot.m_SummaryClientData = NULL; + m_VarRoot.m_StructValuePtr = NULL; + + m_UpToDate = false; + int n = (int)g_TwMgr->m_Bars.size(); + m_PosX = 24*n-8; + m_PosY = 24*n-8; + m_Width = 200; + m_Height = 320; + int cr, cg, cb; + if( g_TwMgr->m_UseOldColorScheme ) + { + ColorHLSToRGBi(g_TwMgr->m_BarInitColorHue%256, 180, 200, &cr, &cg, &cb); + m_Color = Color32FromARGBi(0xf0, cr, cg, cb); + m_DarkText = true; + } + else + { + ColorHLSToRGBi(g_TwMgr->m_BarInitColorHue%256, 80, 200, &cr, &cg, &cb); + m_Color = Color32FromARGBi(64, cr, cg, cb); + m_DarkText = false; + } + g_TwMgr->m_BarInitColorHue -= 16; + if( g_TwMgr->m_BarInitColorHue<0 ) + g_TwMgr->m_BarInitColorHue += 256; + m_Font = g_TwMgr->m_CurrentFont; + //m_Font = g_DefaultNormalFont; + //m_Font = g_DefaultSmallFont; + //m_Font = g_DefaultLargeFont; + m_TitleWidth = 0; + m_Sep = 1; +//#pragma warning "lineSep WIP" + m_LineSep = 1; + m_ValuesWidth = 10*(m_Font->m_CharHeight/2); // about 10 characters + m_NbHierLines = 0; + m_NbDisplayedLines = 0; + m_FirstLine = 0; + m_LastUpdateTime = 0; + m_UpdatePeriod = 2; + m_ScrollYW = 0; + m_ScrollYH = 0; + m_ScrollY0 = 0; + m_ScrollY1 = 0; + + m_DrawHandles = false; + m_DrawIncrDecrBtn = false; + m_DrawRotoBtn = false; + m_DrawClickBtn = false; + m_DrawListBtn = false; + m_DrawBoolBtn = false; + m_MouseDrag = false; + m_MouseDragVar = false; + m_MouseDragTitle = false; + m_MouseDragScroll = false; + m_MouseDragResizeUR = false; + m_MouseDragResizeUL = false; + m_MouseDragResizeLR = false; + m_MouseDragResizeLL = false; + m_MouseDragValWidth = false; + m_MouseOriginX = 0; + m_MouseOriginY = 0; + m_ValuesWidthRatio = 0; + m_VarHasBeenIncr = true; + m_FirstLine0 = 0; + m_HighlightedLine = -1; + m_HighlightedLinePrev = -1; + m_HighlightedLineLastValid = -1; + m_HighlightIncrBtn = false; + m_HighlightDecrBtn = false; + m_HighlightRotoBtn = false; + m_HighlightClickBtn = false; + m_HighlightClickBtnAuto = 0; + m_HighlightListBtn = false; + m_HighlightBoolBtn = false; + m_HighlightTitle = false; + m_HighlightScroll = false; + m_HighlightUpScroll = false; + m_HighlightDnScroll = false; + m_HighlightMinimize = false; + m_HighlightFont = false; + m_HighlightValWidth = false; + m_HighlightLabelsHeader = false; + m_HighlightValuesHeader = false; + m_ButtonAlign = g_TwMgr->m_ButtonAlign; + + m_IsMinimized = false; + m_MinNumber = 0; + m_MinPosX = 0; + m_MinPosY = 0; + m_HighlightMaximize = false; + m_IsHelpBar = false; + m_IsPopupList = false; + m_VarEnumLinkedToPopupList = NULL; + m_BarLinkedToPopupList = NULL; + + m_Resizable = true; + m_Movable = true; + m_Iconifiable = true; + m_Contained = g_TwMgr->m_Contained; + + m_TitleTextObj = g_TwMgr->m_Graph->NewTextObj(); + m_LabelsTextObj = g_TwMgr->m_Graph->NewTextObj(); + m_ValuesTextObj = g_TwMgr->m_Graph->NewTextObj(); + m_ShortcutTextObj = g_TwMgr->m_Graph->NewTextObj(); + m_HeadersTextObj = g_TwMgr->m_Graph->NewTextObj(); + m_ShortcutLine = -1; + + m_RotoMinRadius = 24; + m_RotoNbSubdiv = 256; // number of steps for one turn + + m_CustomActiveStructProxy = NULL; + + UpdateColors(); + NotUpToDate(); +} + +// --------------------------------------------------------------------------- + +CTwBar::~CTwBar() +{ + if( m_IsMinimized ) + g_TwMgr->Maximize(this); + if( m_TitleTextObj ) + g_TwMgr->m_Graph->DeleteTextObj(m_TitleTextObj); + if( m_LabelsTextObj ) + g_TwMgr->m_Graph->DeleteTextObj(m_LabelsTextObj); + if( m_ValuesTextObj ) + g_TwMgr->m_Graph->DeleteTextObj(m_ValuesTextObj); + if( m_ShortcutTextObj ) + g_TwMgr->m_Graph->DeleteTextObj(m_ShortcutTextObj); + if( m_HeadersTextObj ) + g_TwMgr->m_Graph->DeleteTextObj(m_HeadersTextObj); +} + +// --------------------------------------------------------------------------- + +const CTwVar *CTwBar::Find(const char *_Name, CTwVarGroup **_Parent, int *_Index) const +{ + return m_VarRoot.Find(_Name, _Parent, _Index); +} + +CTwVar *CTwBar::Find(const char *_Name, CTwVarGroup **_Parent, int *_Index) +{ + return const_cast(const_cast(this)->Find(_Name, _Parent, _Index)); +} + +// --------------------------------------------------------------------------- + +enum EBarAttribs +{ + BAR_LABEL = 1, + BAR_HELP, + BAR_COLOR, + BAR_ALPHA, + BAR_TEXT, + BAR_SHOW, // deprecated, used BAR_VISIBLE instead + BAR_HIDE, // deprecated, used BAR_VISIBLE instead + BAR_ICONIFY, // deprecated, used BAR_ICONIFIED instead + BAR_VISIBLE, + BAR_ICONIFIED, + BAR_SIZE, + BAR_POSITION, + BAR_REFRESH, + BAR_FONT_SIZE, + BAR_FONT_STYLE, + BAR_VALUES_WIDTH, + BAR_ICON_POS, + BAR_ICON_ALIGN, + BAR_ICON_MARGIN, + BAR_RESIZABLE, + BAR_MOVABLE, + BAR_ICONIFIABLE, + BAR_FONT_RESIZABLE, + BAR_ALWAYS_TOP, + BAR_ALWAYS_BOTTOM, + BAR_COLOR_SCHEME, + BAR_CONTAINED, + BAR_BUTTON_ALIGN +}; + +int CTwBar::HasAttrib(const char *_Attrib, bool *_HasValue) const +{ + *_HasValue = true; + if( _stricmp(_Attrib, "label")==0 ) + return BAR_LABEL; + else if( _stricmp(_Attrib, "help")==0 ) + return BAR_HELP; + else if( _stricmp(_Attrib, "color")==0 ) + return BAR_COLOR; + else if( _stricmp(_Attrib, "alpha")==0 ) + return BAR_ALPHA; + else if( _stricmp(_Attrib, "text")==0 ) + return BAR_TEXT; + else if( _stricmp(_Attrib, "size")==0 ) + return BAR_SIZE; + else if( _stricmp(_Attrib, "position")==0 ) + return BAR_POSITION; + else if( _stricmp(_Attrib, "refresh")==0 ) + return BAR_REFRESH; + else if( _stricmp(_Attrib, "fontsize")==0 ) + return BAR_FONT_SIZE; + else if( _stricmp(_Attrib, "fontstyle")==0 ) + return BAR_FONT_STYLE; + else if( _stricmp(_Attrib, "valueswidth")==0 ) + return BAR_VALUES_WIDTH; + else if( _stricmp(_Attrib, "iconpos")==0 ) + return BAR_ICON_POS; + else if( _stricmp(_Attrib, "iconalign")==0 ) + return BAR_ICON_ALIGN; + else if( _stricmp(_Attrib, "iconmargin")==0 ) + return BAR_ICON_MARGIN; + else if( _stricmp(_Attrib, "resizable")==0 ) + return BAR_RESIZABLE; + else if( _stricmp(_Attrib, "movable")==0 ) + return BAR_MOVABLE; + else if( _stricmp(_Attrib, "iconifiable")==0 ) + return BAR_ICONIFIABLE; + else if( _stricmp(_Attrib, "fontresizable")==0 ) + return BAR_FONT_RESIZABLE; + else if( _stricmp(_Attrib, "alwaystop")==0 ) + return BAR_ALWAYS_TOP; + else if( _stricmp(_Attrib, "alwaysbottom")==0 ) + return BAR_ALWAYS_BOTTOM; + else if( _stricmp(_Attrib, "visible")==0 ) + return BAR_VISIBLE; + else if( _stricmp(_Attrib, "iconified")==0 ) + return BAR_ICONIFIED; + else if( _stricmp(_Attrib, "colorscheme")==0 ) + return BAR_COLOR_SCHEME; + else if( _stricmp(_Attrib, "contained")==0 ) + return BAR_CONTAINED; + else if( _stricmp(_Attrib, "buttonalign")==0 ) + return BAR_BUTTON_ALIGN; + + *_HasValue = false; + if( _stricmp(_Attrib, "show")==0 ) // for backward compatibility + return BAR_SHOW; + else if( _stricmp(_Attrib, "hide")==0 ) // for backward compatibility + return BAR_HIDE; + else if( _stricmp(_Attrib, "iconify")==0 ) // for backward compatibility + return BAR_ICONIFY; + + return 0; // not found +} + +int CTwBar::SetAttrib(int _AttribID, const char *_Value) +{ + switch( _AttribID ) + { + case BAR_LABEL: + if( _Value && strlen(_Value)>0 ) + { + m_Label = _Value; + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_HELP: + if( _Value && strlen(_Value)>0 ) + { + m_Help = _Value; + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_COLOR: + if( _Value && strlen(_Value)>0 ) + { + int v0, v1, v2, v3; + int n = sscanf(_Value, "%d%d%d%d", &v0, &v1, &v2, &v3); + color32 c; + int alpha = (m_Color>>24) & 0xff; + if( n==3 && v0>=0 && v0<=255 && v1>=0 && v1<=255 && v2>=0 && v2<=255 ) + c = Color32FromARGBi(alpha, v0, v1, v2); + else if( n==4 && v0>=0 && v0<=255 && v1>=0 && v1<=255 && v2>=0 && v2<=255 && v3>=0 && v3<=255 ) + c = Color32FromARGBi(v0, v1, v2, v3); + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + m_Color = c; + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_ALPHA: + if( _Value && strlen(_Value)>0 ) + { + int alpha = 255; + int n = sscanf(_Value, "%d", &alpha); + if( n==1 && alpha>=0 && alpha<=255 ) + m_Color = (alpha<<24) | (m_Color & 0xffffff); + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_TEXT: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "dark")==0 ) + m_DarkText = true; + else if( _stricmp(_Value, "light")==0 ) + m_DarkText = false; + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_SIZE: + if( _Value && strlen(_Value)>0 ) + { + int sx, sy; + int n = sscanf(_Value, "%d%d", &sx, &sy); + if( n==2 && sx>0 && sy>0 ) + { + m_Width = sx; + m_Height = sy; + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_POSITION: + if( _Value && strlen(_Value)>0 ) + { + int x, y; + int n = sscanf(_Value, "%d%d", &x, &y); + if( n==2 && x>=0 && y>=0 ) + { + m_PosX = x; + m_PosY = y; + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_REFRESH: + if( _Value && strlen(_Value)>0 ) + { + float r; + int n = sscanf(_Value, "%f", &r); + if( n==1 && r>=0 ) + { + m_UpdatePeriod = r; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_VALUES_WIDTH: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "fit")==0 ) + { + m_ValuesWidth = VALUES_WIDTH_FIT; + NotUpToDate(); + return 1; + } + else + { + int w; + int n = sscanf(_Value, "%d", &w); + if( n==1 && w>0 ) + { + m_ValuesWidth = w; + NotUpToDate(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_FONT_SIZE: + return g_TwMgr->SetAttrib(MGR_FONT_SIZE, _Value); + case BAR_FONT_STYLE: + return g_TwMgr->SetAttrib(MGR_FONT_STYLE, _Value); + case BAR_ICON_POS: + return g_TwMgr->SetAttrib(MGR_ICON_POS, _Value); + case BAR_ICON_ALIGN: + return g_TwMgr->SetAttrib(MGR_ICON_ALIGN, _Value); + case BAR_ICON_MARGIN: + return g_TwMgr->SetAttrib(MGR_ICON_MARGIN, _Value); + case BAR_SHOW: // deprecated + TwSetBarState(this, TW_STATE_SHOWN); + return 1; + case BAR_HIDE: // deprecated + TwSetBarState(this, TW_STATE_HIDDEN); + return 1; + case BAR_ICONIFY: // deprecated + TwSetBarState(this, TW_STATE_ICONIFIED); + return 1; + case BAR_RESIZABLE: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + m_Resizable = true; + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + m_Resizable = false; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_MOVABLE: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + m_Movable = true; + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + m_Movable = false; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_ICONIFIABLE: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + m_Iconifiable = true; + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + m_Iconifiable = false; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_FONT_RESIZABLE: + return g_TwMgr->SetAttrib(MGR_FONT_RESIZABLE, _Value); + case BAR_ALWAYS_TOP: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + g_TwMgr->m_BarAlwaysOnTop = m_Name; + if( g_TwMgr->m_BarAlwaysOnBottom.length()>0 && strcmp(g_TwMgr->m_BarAlwaysOnBottom.c_str(), m_Name.c_str())==0 ) + g_TwMgr->m_BarAlwaysOnBottom.clear(); + TwSetTopBar(this); + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + if( g_TwMgr->m_BarAlwaysOnTop.length()>0 && strcmp(g_TwMgr->m_BarAlwaysOnTop.c_str(), m_Name.c_str())==0 ) + g_TwMgr->m_BarAlwaysOnTop.clear(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_ALWAYS_BOTTOM: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + g_TwMgr->m_BarAlwaysOnBottom = m_Name; + if( g_TwMgr->m_BarAlwaysOnTop.length()>0 && strcmp(g_TwMgr->m_BarAlwaysOnTop.c_str(), m_Name.c_str())==0 ) + g_TwMgr->m_BarAlwaysOnTop.clear(); + TwSetBottomBar(this); + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + if( g_TwMgr->m_BarAlwaysOnBottom.length()>0 && strcmp(g_TwMgr->m_BarAlwaysOnBottom.c_str(), m_Name.c_str())==0 ) + g_TwMgr->m_BarAlwaysOnBottom.clear(); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_VISIBLE: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + TwSetBarState(this, TW_STATE_SHOWN); + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + TwSetBarState(this, TW_STATE_HIDDEN); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_ICONIFIED: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + TwSetBarState(this, TW_STATE_ICONIFIED); + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + TwSetBarState(this, TW_STATE_UNICONIFIED); + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_COLOR_SCHEME: + return g_TwMgr->SetAttrib(MGR_COLOR_SCHEME, _Value); + case BAR_CONTAINED: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + m_Contained = true; + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + m_Contained = false; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case BAR_BUTTON_ALIGN: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "left")==0 ) + { + m_ButtonAlign = BUTTON_ALIGN_LEFT; + return 1; + } + else if( _stricmp(_Value, "center")==0 ) + { + m_ButtonAlign = BUTTON_ALIGN_CENTER; + return 1; + } + if( _stricmp(_Value, "right")==0 ) + { + m_ButtonAlign = BUTTON_ALIGN_RIGHT; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + default: + g_TwMgr->SetLastError(g_ErrUnknownAttrib); + return 0; + } +} + +ERetType CTwBar::GetAttrib(int _AttribID, std::vector& outDoubles, std::ostringstream& outString) const +{ + outDoubles.clear(); + outString.clear(); + + switch( _AttribID ) + { + case BAR_LABEL: + outString << m_Label; + return RET_STRING; + case BAR_HELP: + outString << m_Help; + return RET_STRING; + case BAR_COLOR: + { + int a, r, g, b; + a = r = g = b = 0; + Color32ToARGBi(m_Color, &a, &r, &g, &b); + outDoubles.push_back(r); + outDoubles.push_back(g); + outDoubles.push_back(b); + return RET_DOUBLE; + } + case BAR_ALPHA: + { + int a, r, g, b; + a = r = g = b = 0; + Color32ToARGBi(m_Color, &a, &r, &g, &b); + outDoubles.push_back(a); + return RET_DOUBLE; + } + case BAR_TEXT: + if( m_DarkText ) + outString << "dark"; + else + outString << "light"; + return RET_STRING; + case BAR_SIZE: + outDoubles.push_back(m_Width); + outDoubles.push_back(m_Height); + return RET_DOUBLE; + case BAR_POSITION: + outDoubles.push_back(m_PosX); + outDoubles.push_back(m_PosY); + return RET_DOUBLE; + case BAR_REFRESH: + outDoubles.push_back(m_UpdatePeriod); + return RET_DOUBLE; + case BAR_VALUES_WIDTH: + outDoubles.push_back(m_ValuesWidth); + return RET_DOUBLE; + case BAR_FONT_SIZE: + return g_TwMgr->GetAttrib(MGR_FONT_SIZE, outDoubles, outString); + case BAR_FONT_STYLE: + return g_TwMgr->GetAttrib(MGR_FONT_STYLE, outDoubles, outString); + case BAR_ICON_POS: + return g_TwMgr->GetAttrib(MGR_ICON_POS, outDoubles, outString); + case BAR_ICON_ALIGN: + return g_TwMgr->GetAttrib(MGR_ICON_ALIGN, outDoubles, outString); + case BAR_ICON_MARGIN: + return g_TwMgr->GetAttrib(MGR_ICON_MARGIN, outDoubles, outString); + case BAR_RESIZABLE: + outDoubles.push_back(m_Resizable); + return RET_DOUBLE; + case BAR_MOVABLE: + outDoubles.push_back(m_Movable); + return RET_DOUBLE; + case BAR_ICONIFIABLE: + outDoubles.push_back(m_Iconifiable); + return RET_DOUBLE; + case BAR_FONT_RESIZABLE: + return g_TwMgr->GetAttrib(MGR_FONT_RESIZABLE, outDoubles, outString); + case BAR_ALWAYS_TOP: + outDoubles.push_back( g_TwMgr->m_BarAlwaysOnTop == m_Name ); + return RET_DOUBLE; + case BAR_ALWAYS_BOTTOM: + outDoubles.push_back( g_TwMgr->m_BarAlwaysOnBottom == m_Name ); + return RET_DOUBLE; + case BAR_VISIBLE: + outDoubles.push_back(m_Visible); + return RET_DOUBLE; + case BAR_ICONIFIED: + outDoubles.push_back(m_IsMinimized); + return RET_DOUBLE; + case BAR_COLOR_SCHEME: + return g_TwMgr->GetAttrib(MGR_COLOR_SCHEME, outDoubles, outString); + case BAR_CONTAINED: + outDoubles.push_back(m_Contained); + return RET_DOUBLE; + case BAR_BUTTON_ALIGN: + if( m_ButtonAlign==BUTTON_ALIGN_LEFT ) + outString << "left"; + else if( m_ButtonAlign==BUTTON_ALIGN_CENTER ) + outString << "center"; + else + outString << "right"; + return RET_STRING; + default: + g_TwMgr->SetLastError(g_ErrUnknownAttrib); + return RET_ERROR; + } +} + +// --------------------------------------------------------------------------- + +void CTwBar::NotUpToDate() +{ + m_UpToDate = false; +} + +// --------------------------------------------------------------------------- + +void CTwBar::UpdateColors() +{ + float a, r, g, b, h, l, s; + Color32ToARGBf(m_Color, &a, &r, &g, &b); + ColorRGBToHLSf(r, g, b, &h, &l, &s); + bool lightText = !m_DarkText; + + // Colors independant of m_Color + + // Highlighted line background ramp + m_ColHighBg0 = lightText ? Color32FromARGBf(0.4f, 0.9f, 0.9f, 0.9f) : Color32FromARGBf(0.4f, 1.0f, 1.0f, 1.0f); + m_ColHighBg1 = lightText ? Color32FromARGBf(0.4f, 0.2f, 0.2f, 0.2f) : Color32FromARGBf(0.1f, 0.7f, 0.7f, 0.7f); + + // Text colors & background + m_ColLabelText = lightText ? COLOR32_WHITE : COLOR32_BLACK; + m_ColStructText = lightText ? 0xffefef00 : 0xff303000; + + m_ColValText = lightText ? 0xffc7d7ff : 0xff000080; + m_ColValTextRO = lightText ? 0xffb7b7b7 : 0xff505050; + m_ColValMin = lightText ? 0xff9797ff : 0xff0000f0; + m_ColValMax = m_ColValMin; + m_ColValTextNE = lightText ? 0xff97f797 : 0xff004000; + + m_ColValBg = lightText ? Color32FromARGBf(0.2f+0.3f*a, 0.1f, 0.1f, 0.1f) : Color32FromARGBf(0.2f+0.3f*a, 1, 1, 1); + m_ColStructBg = lightText ? Color32FromARGBf(0.4f*a, 0, 0, 0) : Color32FromARGBf(0.4f*a, 1, 1, 1); + + m_ColLine = lightText ? Color32FromARGBf(0.6f, 1, 1, 1) : Color32FromARGBf(0.6f, 0.3f, 0.3f, 0.3f); + m_ColLineShadow = lightText ? Color32FromARGBf(0.6f, 0, 0, 0) : Color32FromARGBf(0.6f, 0, 0, 0); + m_ColUnderline = lightText ? 0xffd0d0d0 : 0xff202000; + + m_ColGrpBg = lightText ? Color32FromARGBf(0.1f+0.25f*a, 1, 1, 1) : Color32FromARGBf(0.1f+0.05f*a, 0, 0, 0); + m_ColGrpText = lightText ? 0xffffff80 : 0xff000000; + + m_ColShortcutText = lightText ? 0xffffb060 : 0xff802000; + m_ColShortcutBg = lightText ? Color32FromARGBf(0.4f*a, 0.2f, 0.2f, 0.2f) : Color32FromARGBf(0.4f*a, 0.8f, 0.8f, 0.8f); + m_ColInfoText = lightText ? Color32FromARGBf(1.0f, 0.7f, 0.7f, 0.7f) : Color32FromARGBf(1.0f, 0.3f, 0.3f, 0.3f); + + m_ColRoto = lightText ? Color32FromARGBf(0.8f, 0.85f, 0.85f, 0.85f) : Color32FromARGBf(0.8f, 0.1f, 0.1f, 0.1f); + m_ColRotoVal = Color32FromARGBf(1, 1.0f, 0.2f, 0.2f); + m_ColRotoBound = lightText ? Color32FromARGBf(0.8f, 0.6f, 0.6f, 0.6f) : Color32FromARGBf(0.8f, 0.3f, 0.3f, 0.3f); + + m_ColEditText = lightText ? COLOR32_WHITE : COLOR32_BLACK; + m_ColEditBg = lightText ? 0xff575757 : 0xffc7c7c7; // must be opaque + m_ColEditSelText = lightText ? COLOR32_BLACK : COLOR32_WHITE; + m_ColEditSelBg = lightText ? 0xffc7c7c7 : 0xff575757; + + // Colors dependant of m_Colors + + // Bar background + ColorHLSToRGBf(h, l, s, &r, &g, &b); + m_ColBg = Color32FromARGBf(a, r, g, b); + ColorHLSToRGBf(h, l-0.05f, s, &r, &g, &b); + m_ColBg1 = Color32FromARGBf(a, r, g, b); + ColorHLSToRGBf(h, l-0.1f, s, &r, &g, &b); + m_ColBg2 = Color32FromARGBf(a, r, g, b); + + ColorHLSToRGBf(h, l-0.15f, s, &r, &g, &b); + m_ColTitleBg = Color32FromARGBf(a+0.9f, r, g, b); + m_ColTitleText = lightText ? COLOR32_WHITE : COLOR32_BLACK; + m_ColTitleShadow = lightText ? 0x40000000 : 0x00000000; + ColorHLSToRGBf(h, l-0.25f, s, &r, &g, &b); + m_ColTitleHighBg = Color32FromARGBf(a+0.8f, r, g, b); + ColorHLSToRGBf(h, l-0.3f, s, &r, &g, &b); + m_ColTitleUnactiveBg = Color32FromARGBf(a+0.2f, r, g, b); + + ColorHLSToRGBf(h, l-0.2f, s, &r, &g, &b); + m_ColHierBg = Color32FromARGBf(a, r, g, b); + + ColorHLSToRGBf(h, l+0.1f, s, &r, &g, &b); + m_ColBtn = Color32FromARGBf(0.2f+0.4f*a, r, g, b); + ColorHLSToRGBf(h, l-0.35f, s, &r, &g, &b); + m_ColHighBtn = Color32FromARGBf(0.4f+0.4f*a, r, g, b); + ColorHLSToRGBf(h, l-0.25f, s, &r, &g, &b); + m_ColFold = Color32FromARGBf(0.1f+0.4f*a, r, g, b); + ColorHLSToRGBf(h, l-0.35f, s, &r, &g, &b); + m_ColHighFold = Color32FromARGBf(0.3f+0.4f*a, r, g, b); + + ColorHLSToRGBf(h, 0.75f, s, &r, &g, &b); + m_ColHelpBg = Color32FromARGBf(0.2f, 1, 1, 1); + m_ColHelpText = lightText ? Color32FromARGBf(1, 0.2f, 1.0f, 0.2f) : Color32FromARGBf(1, 0, 0.4f, 0); + m_ColSeparator = m_ColValTextRO; + m_ColStaticText = m_ColHelpText; +} + +/* +void CTwBar::UpdateColors() +{ + float a, r, g, b, h, l, s; + Color32ToARGBf(m_Color, &a, &r, &g, &b); + ColorRGBToHLSf(r, g, b, &h, &l, &s); + bool lightText = !m_DarkText; // (l<=0.45f); + l = 0.2f + 0.6f*l; + + ColorHLSToRGBf(h, l, s, &r, &g, &b); + m_ColBg = Color32FromARGBf(a, r, g, b); + ColorHLSToRGBf(h, l-0.1f, s, &r, &g, &b); + m_ColBg1 = Color32FromARGBf(a, r, g, b); + ColorHLSToRGBf(h, l-0.2f, s, &r, &g, &b); + m_ColBg2 = Color32FromARGBf(a, r, g, b); + + ColorHLSToRGBf(h, l+0.1f, s, &r, &g, &b); + m_ColHighBg = Color32FromARGBf(0.4f, r, g, b); + //m_ColHighBg = Color32FromARGBf(a, 0.95f, 0.95f, 0.2f); + + m_ColLabelText = lightText ? COLOR32_WHITE : COLOR32_BLACK; + m_ColStructText = lightText ? 0xffefef00 : 0xff505000; + + m_ColValText = lightText ? 0xffb7b7ff : 0xff000080; + m_ColValTextRO = lightText ? 0xffb7b7b7 : 0xff505050; + m_ColValMin = lightText ? 0xff9797ff : 0xff0000f0; + m_ColValMax = m_ColValMin; + m_ColValTextNE = lightText ? 0xff97f797 : 0xff006000; + + ColorHLSToRGBf(h, lightText ? (min(l+0.2f, 0.3f)) : (max(l-0.2f, 0.6f)), s, &r, &g, &b); + m_ColValBg = Color32FromARGBf(0.4f*a, 0, 0, 0); + m_ColStructBg = Color32FromARGBf(0.4f*a, 0, 0, 0); + + ColorHLSToRGBf(h, 0.4f, s, &r, &g, &b); + m_ColTitleBg = Color32FromARGBf(a+0.4f, r, g, b); + m_ColTitleText = lightText ? COLOR32_WHITE : COLOR32_BLACK; + m_ColTitleShadow = lightText ? 0x80000000 : 0x80ffffff; + ColorHLSToRGBf(h, 0.3f, s, &r, &g, &b); + m_ColTitleHighBg = Color32FromARGBf(a+0.4f, r, g, b); + ColorHLSToRGBf(h, 0.4f, s, &r, &g, &b); + m_ColTitleUnactiveBg = Color32FromARGBf(a+0.2f, r, g, b); + + ColorHLSToRGBf(h, 0.8f, s, &r, &g, &b); + m_ColLine = Color32FromARGBf(0.6f, r, g, b); // 0xfff0f0f0; + m_ColLineShadow = Color32FromARGBf(0.6f, 0, 0, 0); //COLOR32_BLACK; + m_ColUnderline = lightText ? 0xffd0d0d0 : 0xff202000; + ColorHLSToRGBf(h, 0.7f, s, &r, &g, &b); + m_ColBtn = Color32FromARGBf(0.6f, r, g, b); + ColorHLSToRGBf(h, 0.4f, s, &r, &g, &b); + m_ColHighBtn = Color32FromARGBf(0.6f, r, g, b); + ColorHLSToRGBf(h, 0.6f, s, &r, &g, &b); + m_ColFold = Color32FromARGBf(0.3f*a, r, g, b); + ColorHLSToRGBf(h, 0.4f, s, &r, &g, &b); + m_ColHighFold = Color32FromARGBf(0.3f, r, g, b); + + ColorHLSToRGBf(h, lightText ? l+0.2f : l-0.2f, s, &r, &g, &b); + m_ColGrpBg = Color32FromARGBf(0.5f*a, r, g, b); + m_ColGrpText = lightText ? 0xffffff80 : 0xff404000; + + ColorHLSToRGBf(h, 0.75f, s, &r, &g, &b); + m_ColHelpBg = Color32FromARGBf(a, r, g, b); + m_ColHelpText = Color32FromARGBf(1, 0, 0.4f, 0); + + ColorHLSToRGBf(h, 0.45f, s, &r, &g, &b); + m_ColHierBg = Color32FromARGBf(0.75f*a, r, g, b); + + m_ColShortcutText = lightText ? 0xffff8040 : 0xff802000; //0xfff0f0f0; + m_ColShortcutBg = Color32FromARGBf(0.4f*a, 0.2f, 0.2f, 0.2f); + m_ColInfoText = Color32FromARGBf(1.0f, 0.7f, 0.7f, 0.7f); + + m_ColRoto = Color32FromARGBf(1, 0.75f, 0.75f, 0.75f); + m_ColRotoVal = Color32FromARGBf(1, 1.0f, 0.2f, 0.2f); + m_ColRotoBound = Color32FromARGBf(1, 0.4f, 0.4f, 0.4f); + + m_ColEditText = lightText ? COLOR32_WHITE : COLOR32_BLACK; + m_ColEditBg = lightText ? 0xb7575757 : 0xb7c7c7c7; + m_ColEditSelText = lightText ? COLOR32_BLACK : COLOR32_WHITE; + m_ColEditSelBg = lightText ? 0xffc7c7c7 : 0xff575757; + + m_ColSeparator = m_ColValTextRO; + m_ColStaticText = m_ColHelpText; +} +*/ + +// --------------------------------------------------------------------------- + +CTwVarGroup::~CTwVarGroup() +{ + for( vector::iterator it= m_Vars.begin(); it!=m_Vars.end(); ++it ) + if( *it != NULL ) + { + CTwVar *Var = *it; + delete Var; + *it = NULL; + } +} + +// --------------------------------------------------------------------------- + +static inline int IncrBtnWidth(int _CharHeight) +{ + return ((2*_CharHeight)/3+2)&0xfffe; // force even value +} + +// --------------------------------------------------------------------------- + +void CTwBar::BrowseHierarchy(int *_CurrLine, int _CurrLevel, const CTwVar *_Var, int _First, int _Last) +{ + assert(_Var!=NULL); + if( !_Var->m_IsRoot ) + { + if( (*_CurrLine)>=_First && (*_CurrLine)<=_Last ) + { + CHierTag Tag; + Tag.m_Level = _CurrLevel; + Tag.m_Var = const_cast(_Var); + Tag.m_Closing = false; + m_HierTags.push_back(Tag); + } + *_CurrLine += 1; + } + else + { + *_CurrLine = 0; + _CurrLevel = -1; + m_HierTags.resize(0); + } + + if( _Var->IsGroup() ) + { + const CTwVarGroup *Grp = static_cast(_Var); + if( Grp->m_Open ) + for( vector::const_iterator it=Grp->m_Vars.begin(); it!=Grp->m_Vars.end(); ++it ) + if( (*it)->m_Visible ) + BrowseHierarchy(_CurrLine, _CurrLevel+1, *it, _First, _Last); + if( m_HierTags.size()>0 ) + m_HierTags[m_HierTags.size()-1].m_Closing = true; + } +} + +// --------------------------------------------------------------------------- + +void CTwBar::ListLabels(vector& _Labels, vector& _Colors, vector& _BgColors, bool *_HasBgColors, const CTexFont *_Font, int _AtomWidthMax, int _GroupWidthMax) +{ + const int NbEtc = 2; + string ValStr; + int Len, i, x, Etc, s; + const unsigned char *Text; + unsigned char ch; + int WidthMax; + + int Space = _Font->m_CharWidth[(int)' ']; + int LevelSpace = max(_Font->m_CharHeight-6, 4); // space used by DrawHierHandles + + int nh = (int)m_HierTags.size(); + for( int h=0; hm_Label.length(); + if( Len>0 ) + Text = (const unsigned char *)(m_HierTags[h].m_Var->m_Label.c_str()); + else + { + Text = (const unsigned char *)(m_HierTags[h].m_Var->m_Name.c_str()); + Len = (int)m_HierTags[h].m_Var->m_Name.length(); + } + x = 0; + Etc = 0; + _Labels.push_back(""); // add a new text line + if( !m_HierTags[h].m_Var->IsGroup() && static_cast(m_HierTags[h].m_Var)->m_Type==TW_TYPE_BUTTON && static_cast(m_HierTags[h].m_Var)->m_ReadOnly && static_cast(m_HierTags[h].m_Var)->m_Val.m_Button.m_Callback!=NULL ) + _Colors.push_back(m_ColValTextRO); // special case for read-only buttons + else + _Colors.push_back(m_HierTags[h].m_Var->m_ColorPtr!=NULL ? *(m_HierTags[h].m_Var->m_ColorPtr) : COLOR32_WHITE); + color32 bg = m_HierTags[h].m_Var->m_BgColorPtr!=NULL ? *(m_HierTags[h].m_Var->m_BgColorPtr) : 0; + _BgColors.push_back(bg); + if( _HasBgColors!=NULL && bg!=0 ) + *_HasBgColors = true; + bool IsCustom = m_HierTags[h].m_Var->IsCustom(); // !m_HierTags[h].m_Var->IsGroup() && (static_cast(m_HierTags[h].m_Var)->m_Type>=TW_TYPE_CUSTOM_BASE && static_cast(m_HierTags[h].m_Var)->m_Typem_Customs.size()); + if( !IsCustom ) + { + string& CurrentLabel = _Labels[_Labels.size()-1]; + if( m_HierTags[h].m_Var->IsGroup() && static_cast(m_HierTags[h].m_Var)->m_SummaryCallback==NULL ) + WidthMax = _GroupWidthMax; + else if( !m_HierTags[h].m_Var->IsGroup() && static_cast(m_HierTags[h].m_Var)->m_Type==TW_TYPE_BUTTON ) + { + if( static_cast(m_HierTags[h].m_Var)->m_Val.m_Button.m_Callback==NULL ) + WidthMax = _GroupWidthMax; + else if( m_ButtonAlign == BUTTON_ALIGN_RIGHT ) + WidthMax = _GroupWidthMax - 2*IncrBtnWidth(m_Font->m_CharHeight); + else + WidthMax = _AtomWidthMax; + } + //else if( m_HighlightedLine==h && m_DrawRotoBtn ) + // WidthMax = _AtomWidthMax - IncrBtnWidth(m_Font->m_CharHeight); + else + WidthMax = _AtomWidthMax; + if( Space>0 ) + for( s=0; sm_CharWidth[(int)'.']m_DontClip) + for( i=0; im_CharWidth[(int)ch]; + if( Etc>0 ) + { + ++Etc; + if( Etc>NbEtc ) + break; + } + else if( im_CharWidth[(int)'.']>=WidthMax && !(m_HierTags[h].m_Var->m_DontClip)) + Etc = 1; + } + } + } +} + +// --------------------------------------------------------------------------- + +void CTwBar::ListValues(vector& _Values, vector& _Colors, vector& _BgColors, const CTexFont *_Font, int _WidthMax) +{ + CTwFPU fpu; // force fpu precision + + const int NbEtc = 2; + const CTwVarAtom *Atom = NULL; + string ValStr; + int Len, i, x, Etc; + const unsigned char *Text; + unsigned char ch; + bool ReadOnly; + bool IsMax; + bool IsMin; + bool IsROText; + bool HasBgColor; + bool AcceptEdit; + size_t SummaryMaxLength = max(_WidthMax/_Font->m_CharWidth[(int)'I'], 4); + static vector Summary; + Summary.resize(SummaryMaxLength+32); + + int nh = (int)m_HierTags.size(); + for( int h=0; hIsGroup() || m_IsHelpBar + || (m_HierTags[h].m_Var->IsGroup() && static_cast(m_HierTags[h].m_Var)->m_SummaryCallback!=NULL) ) + { + ReadOnly = true; + IsMax = false; + IsMin = false; + IsROText = false; + HasBgColor = true; + AcceptEdit = false; + if( !m_HierTags[h].m_Var->IsGroup() ) + { + Atom = static_cast(m_HierTags[h].m_Var); + Atom->ValueToString(&ValStr); + if( !m_IsHelpBar || (Atom->m_Type==TW_TYPE_SHORTCUT && (Atom->m_Val.m_Shortcut.m_Incr[0]>0 || Atom->m_Val.m_Shortcut.m_Decr[0]>0)) ) + ReadOnly = Atom->m_ReadOnly; + if( !Atom->m_NoSlider ) + { + double v, vmin, vmax; + v = Atom->ValueToDouble(); + Atom->MinMaxStepToDouble(&vmin, &vmax, NULL); + IsMax = (v>=vmax); + IsMin = (v<=vmin); + } + if( Atom->m_Type==TW_TYPE_BOOLCPP || Atom->m_Type==TW_TYPE_BOOL8 || Atom->m_Type==TW_TYPE_BOOL16 || Atom->m_Type==TW_TYPE_BOOL32 ) + { + if (ValStr=="1") + ValStr = "\x7f"; // check sign + else if (ValStr=="0") + ValStr = " -"; //"\x97"; // uncheck sign + } + if( (Atom->m_Type==TW_TYPE_CDSTRING && Atom->m_SetCallback==NULL && g_TwMgr->m_CopyCDStringToClient==NULL) + || (Atom->m_Type==TW_TYPE_CDSTDSTRING && Atom->m_SetCallback==NULL) + || (Atom->m_Type==TW_TYPE_STDSTRING && Atom->m_SetCallback==NULL && g_TwMgr->m_CopyStdStringToClient==NULL) ) + IsROText = true; + if( Atom->m_Type==TW_TYPE_HELP_ATOM || Atom->m_Type==TW_TYPE_HELP_GRP || Atom->m_Type==TW_TYPE_BUTTON || Atom->IsCustom() ) // (Atom->m_Type>=TW_TYPE_CUSTOM_BASE && Atom->m_Typem_Customs.size()) ) + HasBgColor = false; + AcceptEdit = EditInPlaceAcceptVar(Atom) || (Atom->m_Type==TW_TYPE_SHORTCUT); + } + else if(m_HierTags[h].m_Var->IsGroup() && static_cast(m_HierTags[h].m_Var)->m_SummaryCallback!=NULL) + { + const CTwVarGroup *Grp = static_cast(m_HierTags[h].m_Var); + // force internal value update + for( size_t v=0; vm_Vars.size(); v++ ) + if( Grp->m_Vars[v]!=NULL && !Grp->m_Vars[v]->IsGroup() && Grp->m_Vars[v]->m_Visible ) + static_cast(Grp->m_Vars[v])->ValueToDouble(); + + Summary[0] = '\0'; + if( Grp->m_SummaryCallback==CTwMgr::CStruct::DefaultSummary ) + Grp->m_SummaryCallback(&Summary[0], SummaryMaxLength, Grp, Grp->m_SummaryClientData); + else + Grp->m_SummaryCallback(&Summary[0], SummaryMaxLength, Grp->m_StructValuePtr, Grp->m_SummaryClientData); + ValStr = (const char *)(&Summary[0]); + } + else + { + ValStr = ""; // is a group in the help bar + HasBgColor = false; + } + Len = (int)ValStr.length(); + Text = (const unsigned char *)(ValStr.c_str()); + x = 0; + Etc = 0; + _Values.push_back(""); // add a new text line + if( ReadOnly || (IsMin && IsMax) || IsROText ) + _Colors.push_back(m_ColValTextRO); + else if( IsMin ) + _Colors.push_back(m_ColValMin); + else if( IsMax ) + _Colors.push_back(m_ColValMax); + else if( !AcceptEdit ) + _Colors.push_back(m_ColValTextNE); + else + _Colors.push_back(m_ColValText); + if( !HasBgColor ) + _BgColors.push_back(0x00000000); + else if( m_HierTags[h].m_Var->IsGroup() ) + { + const CTwVarGroup *Grp = static_cast(m_HierTags[h].m_Var); + // if typecolor set bgcolor + if( Grp->m_SummaryCallback==CColorExt::SummaryCB ) + _BgColors.push_back(0xff000000); + else + _BgColors.push_back(m_ColStructBg); + } + else + _BgColors.push_back(m_ColValBg); + + string& CurrentValue = _Values[_Values.size()-1]; + int wmax = _WidthMax; + if( m_HighlightedLine==h && m_DrawRotoBtn ) + wmax -= 3*IncrBtnWidth(m_Font->m_CharHeight); + else if( m_HighlightedLine==h && m_DrawIncrDecrBtn ) + wmax -= 2*IncrBtnWidth(m_Font->m_CharHeight); + else if( m_HighlightedLine==h && m_DrawListBtn ) + wmax -= 1*IncrBtnWidth(m_Font->m_CharHeight); + else if( m_HighlightedLine==h && m_DrawBoolBtn ) + wmax -= 1*IncrBtnWidth(m_Font->m_CharHeight); + for( i=0; im_CharWidth[(int)ch]; + if( Etc>0 ) + { + ++Etc; + if( Etc>NbEtc ) + break; + } + else if( im_CharWidth[(int)'.'])>=wmax ) + Etc = 1; + } + } + else + { + _Values.push_back(""); // add a new empty line + _Colors.push_back(COLOR32_BLACK); + _BgColors.push_back(0x00000000); + } +} + +// --------------------------------------------------------------------------- + +int CTwBar::ComputeLabelsWidth(const CTexFont *_Font) +{ + int Len, i, x, s; + const unsigned char *Text; + int LabelsWidth = 0; + int Space = _Font->m_CharWidth[(int)' ']; + int LevelSpace = max(_Font->m_CharHeight-6, 4); // space used by DrawHierHandles + + int nh = (int)m_HierTags.size(); + for( int h=0; hm_Label.length(); + if( Len>0 ) + Text = (const unsigned char *)(m_HierTags[h].m_Var->m_Label.c_str()); + else + { + Text = (const unsigned char *)(m_HierTags[h].m_Var->m_Name.c_str()); + Len = (int)m_HierTags[h].m_Var->m_Name.length(); + } + x = 0; + bool IsCustom = m_HierTags[h].m_Var->IsCustom(); // !m_HierTags[h].m_Var->IsGroup() && (static_cast(m_HierTags[h].m_Var)->m_Type>=TW_TYPE_CUSTOM_BASE && static_cast(m_HierTags[h].m_Var)->m_Typem_Customs.size()); + if( !IsCustom ) + { + if( Space>0 ) + for( s=0; sm_CharWidth[(int)Text[i]]; + x += 3*Space; // add little margin + } + if (x > LabelsWidth) + LabelsWidth = x; + } + + return LabelsWidth; +} + +int CTwBar::ComputeValuesWidth(const CTexFont *_Font) +{ + CTwFPU fpu; // force fpu precision + + const CTwVarAtom *Atom = NULL; + string ValStr; + int Len, i, x; + int Space = _Font->m_CharWidth[(int)' ']; + const unsigned char *Text; + int ValuesWidth = 0; + + int nh = (int)m_HierTags.size(); + for( int h=0; hIsGroup() ) + { + Atom = static_cast(m_HierTags[h].m_Var); + Atom->ValueToString(&ValStr); + + Len = (int)ValStr.length(); + Text = (const unsigned char *)(ValStr.c_str()); + x = 0; + for( i=0; im_CharWidth[(int)Text[i]]; + x += 2*Space; // add little margin + if (x > ValuesWidth) + ValuesWidth = x; + } + + return ValuesWidth; +} + +// --------------------------------------------------------------------------- + +static int ClampText(string& _Text, const CTexFont *_Font, int _WidthMax) +{ + int Len = (int)_Text.length(); + unsigned char ch; + int Width = 0; + int i; + for( i=0; im_CharWidth[(int)'.']>=_WidthMax ) + break; + Width += _Font->m_CharWidth[ch]; + } + if( im_CharWidth[(int)'.']; + } + return Width; +} + +// --------------------------------------------------------------------------- + +void CTwBar::Update() +{ + assert(m_UpToDate==false); + assert(m_Font); + ITwGraph *Gr = g_TwMgr->m_Graph; + + bool DoEndDraw = false; + if( !Gr->IsDrawing() ) + { + Gr->BeginDraw(g_TwMgr->m_WndWidth, g_TwMgr->m_WndHeight); + DoEndDraw = true; + } + + bool ValuesWidthFit = false; + if( m_ValuesWidth==VALUES_WIDTH_FIT ) + { + ValuesWidthFit = true; + m_ValuesWidth = 0; + } + int PrevPosY = m_PosY; + int vpx, vpy, vpw, vph; + vpx = 0; + vpy = 0; + vpw = g_TwMgr->m_WndWidth; + vph = g_TwMgr->m_WndHeight; + if( !m_IsMinimized && vpw>0 && vph>0 ) + { + bool Modif = false; + if( m_Resizable ) + { + if( m_Width>vpw && m_Contained ) + { + m_Width = vpw; + Modif = true; + } + if( m_Width<8*m_Font->m_CharHeight ) + { + m_Width = 8*m_Font->m_CharHeight; + Modif = true; + } + if( m_Height>vph && m_Contained ) + { + m_Height = vph; + Modif = true; + } + if( m_Height<5*m_Font->m_CharHeight ) + { + m_Height = 5*m_Font->m_CharHeight; + Modif = true; + } + } + if( m_Movable && m_Contained ) + { + if( m_PosX+m_Width>vpx+vpw ) + m_PosX = vpx+vpw-m_Width; + if( m_PosXvpy+vph ) + m_PosY = vpy+vph-m_Height; + if( m_PosYm_CharHeight ) + { + m_ValuesWidth = 2*m_Font->m_CharHeight; + Modif = true; + } + if( m_ValuesWidth>m_Width-4*m_Font->m_CharHeight ) + { + m_ValuesWidth = m_Width-4*m_Font->m_CharHeight; + Modif = true; + } + if (ValuesWidthFit) + Modif = true; + if( Modif && m_IsHelpBar ) + { + g_TwMgr->m_HelpBarNotUpToDate = true; + g_TwMgr->m_KeyPressedBuildText = true; + g_TwMgr->m_InfoBuildText = true; + } + } + + UpdateColors(); + + // update geometry relatively to (m_PosX, m_PosY) + if( !m_IsPopupList ) + { + //m_VarX0 = 2*m_Font->m_CharHeight+m_Sep; + m_VarX0 = m_Font->m_CharHeight+m_Sep; + //m_VarX2 = m_Width - 4; + m_VarX2 = m_Width - m_Font->m_CharHeight - m_Sep-2; + m_VarX1 = m_VarX2 - m_ValuesWidth; + } + else + { + //m_VarX0 = m_Font->m_CharHeight+6+m_Sep; + m_VarX0 = 2; + //m_VarX2 = m_Width - 4; + m_VarX2 = m_Width - m_Font->m_CharHeight - m_Sep-2; + m_VarX1 = m_VarX2; + } + if( m_VarX1m_VarX2 ) + m_VarX1 = m_VarX2; + if( !m_IsPopupList ) + { + m_VarY0 = m_Font->m_CharHeight+2+m_Sep+6; + m_VarY1 = m_Height-m_Font->m_CharHeight-2-m_Sep; + m_VarY2 = m_Height-1; + } + else + { + m_VarY0 = 4; + m_VarY1 = m_Height-2-m_Sep; + m_VarY2 = m_Height-1; + } + + int NbLines = (m_VarY1-m_VarY0+1)/(m_Font->m_CharHeight+m_LineSep); + if( NbLines<= 0 ) + NbLines = 1; + if( !m_IsMinimized ) + { + int LineNum = 0; + BrowseHierarchy(&LineNum, 0, &m_VarRoot, m_FirstLine, m_FirstLine+NbLines); // add a dummy tag at the end to avoid wrong 'tag-closing' problems + if( (int)m_HierTags.size()>NbLines ) + m_HierTags.resize(NbLines); // remove the last dummy tag + m_NbHierLines = LineNum; + m_NbDisplayedLines = (int)m_HierTags.size(); + + if( ValuesWidthFit ) + { + m_ValuesWidth = ComputeValuesWidth(m_Font); + if( m_ValuesWidth<2*m_Font->m_CharHeight ) + m_ValuesWidth = 2*m_Font->m_CharHeight; // enough to draw buttons + if( m_ValuesWidth>m_VarX2 - m_VarX0 ) + m_ValuesWidth = max(m_VarX2 - m_VarX0 - m_Font->m_CharHeight, 0); + m_VarX1 = m_VarX2 - m_ValuesWidth; + if( m_VarX1m_VarX2 ) + m_VarX1 = m_VarX2; + m_ValuesWidth = m_VarX2 - m_VarX1; + } + } + + // scroll bar + int y0 = m_PosY+m_VarY0; + int y1 = m_PosY+m_VarY1; + int x0 = m_PosX+2; + int x1 = m_PosX+m_Font->m_CharHeight-2; + if( ((x0+x1)&1)==1 ) + x1 += 1; + int w = x1-x0+1; + int h = y1-y0-2*w; + int hscr = (m_NbHierLines>0) ? ((h*m_NbDisplayedLines)/m_NbHierLines) : h; + if( hscr<=4 ) + hscr = 4; + if( hscr>h ) + hscr = h; + int yscr = (m_NbHierLines>0) ? ((h*m_FirstLine)/m_NbHierLines) : 0; + if( yscr<=0 ) + yscr = 0; + if( yscr>h-4 ) + yscr = h-4; + if( yscr+hscr>h ) + hscr = h-yscr; + if( hscr>h ) + hscr = h; + if( hscr<=4 ) + hscr = 4; + m_ScrollYW = w; + m_ScrollYH = h; + m_ScrollY0 = y0+w+yscr; + m_ScrollY1 = y0+w+yscr+hscr; + + // Build title + string Title; + if( m_Label.size()>0 ) + Title = m_Label; + else + Title = m_Name; + m_TitleWidth = ClampText(Title, m_Font, (!m_IsMinimized)?(m_Width-5*m_Font->m_CharHeight):(16*m_Font->m_CharHeight)); + Gr->BuildText(m_TitleTextObj, &Title, NULL, NULL, 1, m_Font, 0, 0); + + if( !m_IsMinimized ) + { + // Build labels + vector Labels; + vector Colors; + vector BgColors; + bool HasBgColors = false; + ListLabels(Labels, Colors, BgColors, &HasBgColors, m_Font, m_VarX1-m_VarX0, m_VarX2-m_VarX0); + assert( Labels.size()==Colors.size() && Labels.size()==BgColors.size() ); + if( Labels.size()>0 ) + Gr->BuildText(m_LabelsTextObj, &(Labels[0]), &(Colors[0]), &(BgColors[0]), (int)Labels.size(), m_Font, m_LineSep, HasBgColors ? m_VarX1-m_VarX0-m_Font->m_CharHeight+2 : 0); + else + Gr->BuildText(m_LabelsTextObj, NULL, NULL, NULL, 0, m_Font, m_LineSep, 0); + + // Should draw click button? + m_DrawClickBtn = ( m_VarX2-m_VarX1>4*IncrBtnWidth(m_Font->m_CharHeight) + && m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() + && m_HierTags[m_HighlightedLine].m_Var!=NULL + && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() + && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly + && ( static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BUTTON )); + // || static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOLCPP + // || static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOL8 + // || static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOL16 + // || static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOL32 )); + + // Should draw [-/+] button? + m_DrawIncrDecrBtn = ( m_VarX2-m_VarX1>5*IncrBtnWidth(m_Font->m_CharHeight) + && m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() + && m_HierTags[m_HighlightedLine].m_Var!=NULL + && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() + && static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type!=TW_TYPE_BUTTON + && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly + && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_NoSlider + && !(m_EditInPlace.m_Active && m_EditInPlace.m_Var==m_HierTags[m_HighlightedLine].m_Var) ); + + // Should draw [v] button (list)? + m_DrawListBtn = ( m_VarX2-m_VarX1>2*IncrBtnWidth(m_Font->m_CharHeight) + && m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() + && m_HierTags[m_HighlightedLine].m_Var!=NULL + && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() + && IsEnumType(static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type) + && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly ); + + // Should draw [<>] button (bool)? + m_DrawBoolBtn = ( m_VarX2-m_VarX1>4*IncrBtnWidth(m_Font->m_CharHeight) + && m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() + && m_HierTags[m_HighlightedLine].m_Var!=NULL + && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() + && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly + && ( static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOLCPP + || static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOL8 + || static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOL16 + || static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BOOL32 )); + + // Should draw [o] button? + m_DrawRotoBtn = m_DrawIncrDecrBtn; + /* + m_DrawRotoBtn = ( m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() + && m_HierTags[m_HighlightedLine].m_Var!=NULL + && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() + && static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type!=TW_TYPE_BUTTON + && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly + && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_NoSlider ); + */ + + // Build values + vector& Values = Labels; // reuse + Values.resize(0); + Colors.resize(0); + BgColors.resize(0); + ListValues(Values, Colors, BgColors, m_Font, m_VarX2-m_VarX1); + assert( BgColors.size()==Values.size() && Colors.size()==Values.size() ); + if( Values.size()>0 ) + Gr->BuildText(m_ValuesTextObj, &(Values[0]), &(Colors[0]), &(BgColors[0]), (int)Values.size(), m_Font, m_LineSep, m_VarX2-m_VarX1); + else + Gr->BuildText(m_ValuesTextObj, NULL, NULL, NULL, 0, m_Font, m_LineSep, m_VarX2-m_VarX1); + + // Build key shortcut text + string Shortcut; + m_ShortcutLine = -1; + if( m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() && m_HierTags[m_HighlightedLine].m_Var!=NULL && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + const CTwVarAtom *Atom = static_cast(m_HierTags[m_HighlightedLine].m_Var); + if( Atom->m_KeyIncr[0]>0 || Atom->m_KeyDecr[0]>0 ) + { + if( Atom->m_KeyIncr[0]>0 && Atom->m_KeyDecr[0]>0 ) + Shortcut = "Keys: "; + else + Shortcut = "Key: "; + if( Atom->m_KeyIncr[0]>0 ) + TwGetKeyString(&Shortcut, Atom->m_KeyIncr[0], Atom->m_KeyIncr[1]); + else + Shortcut += "(none)"; + if( Atom->m_KeyDecr[0]>0 ) + { + Shortcut += " "; + TwGetKeyString(&Shortcut, Atom->m_KeyDecr[0], Atom->m_KeyDecr[1]); + } + m_ShortcutLine = m_HighlightedLine; + } + } + ClampText(Shortcut, m_Font, m_Width-3*m_Font->m_CharHeight); + Gr->BuildText(m_ShortcutTextObj, &Shortcut, NULL, NULL, 1, m_Font, 0, 0); + + // build headers text + if (m_HighlightLabelsHeader || m_HighlightValuesHeader) { + std::string HeadersText = "Fit column content"; + ClampText(HeadersText, m_Font, m_Width-3*m_Font->m_CharHeight); + Gr->BuildText(m_HeadersTextObj, &HeadersText, NULL, NULL, 1, m_Font, 0, 0); + } + } + + if( DoEndDraw ) + Gr->EndDraw(); + + m_UpToDate = true; + m_LastUpdateTime = float(g_BarTimer.GetTime()); +} + +// --------------------------------------------------------------------------- + +void CTwBar::DrawHierHandle() +{ + assert(m_Font); + ITwGraph *Gr = g_TwMgr->m_Graph; + + //int x0 = m_PosX+m_Font->m_CharHeight+1; + int x0 = m_PosX+3; + //int x2 = m_PosX+m_VarX0-5; + //int x2 = m_PosX+3*m_Font->m_CharWidth[(int)' ']-2; + int x2 = m_PosX+m_Font->m_CharHeight-3; + if( x2-x0<4 ) + x2 = x0+4; + if( (x2-x0)&1 ) + --x2; + int x1 = (x0+x2)/2; + int w = x2-x0+1; + int y0 = m_PosY+m_VarY0 +1; + int y1; + int dh0 = (m_Font->m_CharHeight+m_Sep-1-w)/2; + if( dh0<0 ) + dh0 = 0; + int dh1 = dh0+w-1; + int i, h=0; + + if( !m_IsPopupList ) + { + CTwVarGroup *Grp; + int nh = (int)m_HierTags.size(); + for( h=0; hm_CharHeight+m_Sep-1; + if( m_HierTags[h].m_Var->IsGroup() ) + Grp = static_cast(m_HierTags[h].m_Var); + else + Grp = NULL; + + int dx = m_HierTags[h].m_Level * (x2-x0); + + if( Grp ) + { + if( m_ColGrpBg!=0 && Grp->m_StructValuePtr==NULL ) + { + color32 cb = (Grp->m_StructType==TW_TYPE_HELP_STRUCT) ? m_ColStructBg : m_ColGrpBg; + //Gr->DrawRect(x0+dx-1, y0, m_PosX+m_VarX2, y0+m_Font->m_CharHeight-1, cb); + Gr->DrawRect(x2+dx+3, y0, m_PosX+m_VarX2, y0+m_Font->m_CharHeight-1+m_LineSep-1, cb); + } + + if( m_DrawHandles ) + { + Gr->DrawLine(dx+x2+1,y0+dh0+1, dx+x2+1,y0+dh1+1, m_ColLineShadow); + Gr->DrawLine(dx+x0+1,y0+dh1+1, dx+x2+2,y0+dh1+1, m_ColLineShadow); + } + + //Gr->DrawRect(x0+1,y0+dh0+1,x2-1,y0+dh1-1, (h==m_HighlightedLine) ? m_ColHighBtn : m_ColBtn); + Gr->DrawRect(dx+x0, y0+dh0, dx+x2, y0+dh1, (h==m_HighlightedLine) ? m_ColHighFold : m_ColFold); + if( m_DrawHandles ) + { + Gr->DrawLine(dx+x0,y0+dh0, dx+x2,y0+dh0, m_ColLine); + Gr->DrawLine(dx+x2,y0+dh0, dx+x2,y0+dh1+1, m_ColLine); + Gr->DrawLine(dx+x2,y0+dh1, dx+x0,y0+dh1, m_ColLine); + Gr->DrawLine(dx+x0,y0+dh1, dx+x0,y0+dh0, m_ColLine); + } + + Gr->DrawLine(dx+x0+2,y0+dh0+w/2, dx+x2-1,y0+dh0+w/2, m_ColTitleText); + if( !Grp->m_Open ) + Gr->DrawLine(dx+x1,y0+dh0+2, dx+x1,y0+dh1-1, m_ColTitleText); + + /* + if( m_ColGrpBg!=0 && Grp->m_StructValuePtr==NULL ) + { + color32 cb = (Grp->m_StructType==TW_TYPE_HELP_STRUCT) ? m_ColStructBg : m_ColGrpBg; + //int decal = m_Font->m_CharHeight/2-2+2*m_HierTags[h].m_Level; + //if( decal>m_Font->m_CharHeight-3 ) + // decal = m_Font->m_CharHeight-3; + int margin = dx; //m_Font->m_CharWidth[(int)' ']*m_HierTags[h].m_Level; + //Gr->DrawRect(m_PosX+m_VarX0+margin, y0+decal, m_PosX+m_VarX2, y0+m_Font->m_CharHeight-1, cb); + Gr->DrawRect(m_PosX+m_VarX0+margin-1, y0+1, m_PosX+m_VarX2, y0+m_Font->m_CharHeight, cb);// m_ColHierBg); + //Gr->DrawRect(m_PosX+m_VarX0-4, y0+m_Font->m_CharHeight/2-1, m_PosX+m_VarX0+margin-2, y0+m_Font->m_CharHeight/2, m_ColHierBg); + } + */ + } + else if( static_cast(m_HierTags[h].m_Var)->m_Type==TW_TYPE_HELP_GRP && m_ColHelpBg!=0 ) + Gr->DrawRect(m_PosX+m_VarX0+m_HierTags[h].m_Var->m_LeftMargin, y0+m_HierTags[h].m_Var->m_TopMargin, m_PosX+m_VarX2, y0+m_Font->m_CharHeight-1, m_ColHelpBg); + //else if( static_cast(m_HierTags[h].m_Var)->m_Type==TW_TYPE_HELP_HEADER && m_ColHelpBg!=0 ) + // Gr->DrawRect(m_PosX+m_VarX0+m_HierTags[h].m_Var->m_LeftMargin, y0+m_HierTags[h].m_Var->m_TopMargin, m_PosX+m_VarX2, y0+m_Font->m_CharHeight-1, m_ColHelpBg); + /* + else if( static_cast(m_HierTags[h].m_Var)->m_Type==TW_TYPE_BUTTON && m_ColBtn!=0 ) + { + // draw button + int cbx0 = m_PosX+m_VarX2-2*bw+bw/2, cby0 = y0+2, cbx1 = m_PosX+m_VarX2-2-bw/2, cby1 = y0+m_Font->m_CharHeight-4; + if( m_HighlightClickBtn ) + { + Gr->DrawRect(cbx0+2, cby0+2, cbx1+2, cby1+2, m_ColBtn); + Gr->DrawLine(cbx0+3, cby1+3, cbx1+4, cby1+3, 0x7F000000); + Gr->DrawLine(cbx1+3, cby0+3, cbx1+3, cby1+3, 0x7F000000); + } + else + { + Gr->DrawRect(cbx0+3, cby1+1, cbx1+3, cby1+3, 0x7F000000); + Gr->DrawRect(cbx1+1, cby0+3, cbx1+3, cby1, 0x7F000000); + Gr->DrawRect(cbx0, cby0, cbx1, cby1, m_ColBtn); + } + } + */ + + y0 = y1+m_LineSep; + } + } + + if( m_NbDisplayedLinesm_CharHeight-2; + x0 = m_PosX + m_VarX2+4; + x1 = x0 + m_Font->m_CharHeight-4; + if( ((x0+x1)&1)==1 ) + x1 += 1; + w = m_ScrollYW; + h = m_ScrollYH; + + Gr->DrawRect(x0+2,y0+w, x1-2,y1-1-w, (m_ColBg&0xffffff)|0x11000000); + if( m_DrawHandles || m_IsPopupList ) + { + // scroll handle shadow lines + Gr->DrawLine(x1-1,m_ScrollY0+1, x1-1,m_ScrollY1+1, m_ColLineShadow); + Gr->DrawLine(x0+2,m_ScrollY1+1, x1,m_ScrollY1+1, m_ColLineShadow); + + // up & down arrow + for( i=0; i<(x1-x0-2)/2; ++i ) + { + Gr->DrawLine(x0+2+i,y0+w-2*i, x1-i,y0+w-2*i, m_ColLineShadow); + Gr->DrawLine(x0+1+i,y0+w-1-2*i, x1-1-i,y0+w-1-2*i, m_HighlightUpScroll?((m_ColLine&0xffffff)|0x4f000000):m_ColLine); + + Gr->DrawLine(x0+2+i,y1-w+2+2*i, x1-i,y1-w+2+2*i, m_ColLineShadow); + Gr->DrawLine(x0+1+i,y1-w+1+2*i, x1-1-i,y1-w+1+2*i, m_HighlightDnScroll?((m_ColLine&0xffffff)|0x4f000000):m_ColLine); + } + + // middle lines + Gr->DrawLine((x0+x1)/2-1,y0+w, (x0+x1)/2-1,m_ScrollY0, m_ColLine); + Gr->DrawLine((x0+x1)/2,y0+w, (x0+x1)/2,m_ScrollY0, m_ColLine); + Gr->DrawLine((x0+x1)/2+1,y0+w, (x0+x1)/2+1,m_ScrollY0, m_ColLineShadow); + Gr->DrawLine((x0+x1)/2-1,m_ScrollY1, (x0+x1)/2-1,y1-w+1, m_ColLine); + Gr->DrawLine((x0+x1)/2,m_ScrollY1, (x0+x1)/2,y1-w+1, m_ColLine); + Gr->DrawLine((x0+x1)/2+1,m_ScrollY1, (x0+x1)/2+1,y1-w+1, m_ColLineShadow); + // scroll handle lines + Gr->DrawRect(x0+2,m_ScrollY0+1, x1-3,m_ScrollY1-1, m_HighlightScroll?m_ColHighBtn:m_ColBtn); + Gr->DrawLine(x1-2,m_ScrollY0, x1-2,m_ScrollY1, m_ColLine); + Gr->DrawLine(x0+1,m_ScrollY0, x0+1,m_ScrollY1, m_ColLine); + Gr->DrawLine(x0+1,m_ScrollY1, x1-1,m_ScrollY1, m_ColLine); + Gr->DrawLine(x0+1,m_ScrollY0, x1-2,m_ScrollY0, m_ColLine); + } + else + Gr->DrawRect(x0+3,m_ScrollY0+1, x1-3,m_ScrollY1-1, m_ColBtn); + } + + if( m_DrawHandles && !m_IsPopupList ) + { + if( m_Resizable ) // Draw resize handles + { + // lower-left + Gr->DrawLine(m_PosX+3, m_PosY+m_Height-m_Font->m_CharHeight+3, m_PosX+3, m_PosY+m_Height-4, m_ColLine); + Gr->DrawLine(m_PosX+4, m_PosY+m_Height-m_Font->m_CharHeight+4, m_PosX+4, m_PosY+m_Height-3, m_ColLineShadow); + Gr->DrawLine(m_PosX+3, m_PosY+m_Height-4, m_PosX+m_Font->m_CharHeight-4, m_PosY+m_Height-4, m_ColLine); + Gr->DrawLine(m_PosX+4, m_PosY+m_Height-3, m_PosX+m_Font->m_CharHeight-3, m_PosY+m_Height-3, m_ColLineShadow); + // lower-right + Gr->DrawLine(m_PosX+m_Width-4, m_PosY+m_Height-m_Font->m_CharHeight+3, m_PosX+m_Width-4, m_PosY+m_Height-4, m_ColLine); + Gr->DrawLine(m_PosX+m_Width-3, m_PosY+m_Height-m_Font->m_CharHeight+4, m_PosX+m_Width-3, m_PosY+m_Height-3, m_ColLineShadow); + Gr->DrawLine(m_PosX+m_Width-4, m_PosY+m_Height-4, m_PosX+m_Width-m_Font->m_CharHeight+3, m_PosY+m_Height-4, m_ColLine); + Gr->DrawLine(m_PosX+m_Width-3, m_PosY+m_Height-3, m_PosX+m_Width-m_Font->m_CharHeight+4, m_PosY+m_Height-3, m_ColLineShadow); + // upper-left + Gr->DrawLine(m_PosX+3, m_PosY+m_Font->m_CharHeight-4, m_PosX+3, m_PosY+3, m_ColLine); + Gr->DrawLine(m_PosX+4, m_PosY+m_Font->m_CharHeight-3, m_PosX+4, m_PosY+4, m_ColLineShadow); + Gr->DrawLine(m_PosX+3, m_PosY+3, m_PosX+m_Font->m_CharHeight-4, m_PosY+3, m_ColLine); + Gr->DrawLine(m_PosX+4, m_PosY+4, m_PosX+m_Font->m_CharHeight-3, m_PosY+4, m_ColLineShadow); + // upper-right + Gr->DrawLine(m_PosX+m_Width-4, m_PosY+3, m_PosX+m_Width-m_Font->m_CharHeight+3, m_PosY+3, m_ColLine); + Gr->DrawLine(m_PosX+m_Width-3, m_PosY+4, m_PosX+m_Width-m_Font->m_CharHeight+4, m_PosY+4, m_ColLineShadow); + Gr->DrawLine(m_PosX+m_Width-4, m_PosY+m_Font->m_CharHeight-4, m_PosX+m_Width-4, m_PosY+3, m_ColLine); + Gr->DrawLine(m_PosX+m_Width-3, m_PosY+m_Font->m_CharHeight-3, m_PosX+m_Width-3, m_PosY+4, m_ColLineShadow); + } + + int xm = m_PosX+m_Width-2*m_Font->m_CharHeight, wm=m_Font->m_CharHeight-6; + wm = (wm<6) ? 6 : wm; + if( m_Iconifiable ) // Draw minimize button + { + Gr->DrawRect(xm+1, m_PosY+4, xm+wm-1, m_PosY+3+wm, m_HighlightMinimize?m_ColHighBtn:((m_ColBtn&0xffffff)|0x4f000000)); + Gr->DrawLine(xm, m_PosY+3, xm+wm, m_PosY+3, m_ColLine); + Gr->DrawLine(xm+wm, m_PosY+3, xm+wm, m_PosY+3+wm, m_ColLine); + Gr->DrawLine(xm+wm, m_PosY+3+wm, xm, m_PosY+3+wm, m_ColLine); + Gr->DrawLine(xm, m_PosY+3+wm, xm, m_PosY+3, m_ColLine); + Gr->DrawLine(xm+wm+1, m_PosY+4, xm+wm+1, m_PosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm+1, m_PosY+4+wm, xm, m_PosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm/3+((wm<9)?1:0)-1, m_PosY+4+wm/3-((wm<9)?0:1), xm+wm/2, m_PosY+2+wm-1, m_ColTitleText, true); + Gr->DrawLine(xm+wm-wm/3+((wm<9)?0:1), m_PosY+4+wm/3-((wm<9)?0:1), xm+wm/2, m_PosY+2+wm-1, m_ColTitleText, true); + } + + if( g_TwMgr->m_FontResizable ) // Draw font button + { + xm = m_PosX+m_Font->m_CharHeight+2; + Gr->DrawRect(xm+1, m_PosY+4, xm+wm-1, m_PosY+3+wm, m_HighlightFont?m_ColHighBtn:((m_ColBtn&0xffffff)|0x4f000000)); + Gr->DrawLine(xm, m_PosY+3, xm+wm, m_PosY+3, m_ColLine); + Gr->DrawLine(xm+wm, m_PosY+3, xm+wm, m_PosY+3+wm, m_ColLine); + Gr->DrawLine(xm+wm, m_PosY+3+wm, xm, m_PosY+3+wm, m_ColLine); + Gr->DrawLine(xm, m_PosY+3+wm, xm, m_PosY+3, m_ColLine); + Gr->DrawLine(xm+wm+1, m_PosY+4, xm+wm+1, m_PosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm+1, m_PosY+4+wm, xm, m_PosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm/2-wm/6, m_PosY+3+wm/3, xm+wm/2+wm/6+1, m_PosY+3+wm/3, m_ColTitleText); + Gr->DrawLine(xm+wm/2-wm/6, m_PosY+3+wm/3, xm+wm/2-wm/6, m_PosY+4+wm-wm/3+(wm>11?1:0), m_ColTitleText); + Gr->DrawLine(xm+wm/2-wm/6, m_PosY+3+wm/2+(wm>11?1:0), xm+wm/2+wm/6, m_PosY+3+wm/2+(wm>11?1:0), m_ColTitleText); + } + } +} + +// --------------------------------------------------------------------------- + +void CTwBar::Draw(int _DrawPart) +{ + PERF( PerfTimer Timer; double DT; ) + + assert(m_Font); + ITwGraph *Gr = g_TwMgr->m_Graph; + + m_CustomRecords.clear(); + + if( float(g_BarTimer.GetTime())>m_LastUpdateTime+m_UpdatePeriod ) + NotUpToDate(); + + if( m_HighlightedLine!=m_HighlightedLinePrev ) + { + m_HighlightedLinePrev = m_HighlightedLine; + NotUpToDate(); + } + + if( m_IsHelpBar && g_TwMgr->m_HelpBarNotUpToDate ) + g_TwMgr->UpdateHelpBar(); + + if( !m_UpToDate ) + Update(); + + if( !m_IsMinimized ) + { + int y = m_PosY+1; + int LevelSpace = max(m_Font->m_CharHeight-6, 4); // space used by DrawHierHandles + + color32 colBg = m_ColBg, colBg1 = m_ColBg1, colBg2 = m_ColBg2; + if( m_DrawHandles || m_IsPopupList ) + { + unsigned int alphaMin = 0x70; + if( m_IsPopupList ) + alphaMin = 0xa0; + if( (colBg>>24)>24)>24)DrawRect(m_PosX, m_PosY, m_PosX+m_Width-1, m_PosY+m_Font->m_CharHeight+1, (m_HighlightTitle||m_MouseDragTitle) ? m_ColTitleHighBg : (m_DrawHandles ? m_ColTitleBg : m_ColTitleUnactiveBg)); + if( m_HighlightTitle || m_MouseDragTitle ) + Gr->DrawRect(m_PosX, m_PosY, m_PosX+m_Width-1, m_PosY+m_Font->m_CharHeight+1, m_ColTitleHighBg); + else if (m_DrawHandles) + Gr->DrawRect(m_PosX, m_PosY, m_PosX+m_Width-1, m_PosY+m_Font->m_CharHeight+1, m_ColTitleBg, m_ColTitleBg, colBg2, colBg1); + else + Gr->DrawRect(m_PosX, m_PosY, m_PosX+m_Width-1, m_PosY+m_Font->m_CharHeight+1, m_ColTitleBg, m_ColTitleBg, colBg2, colBg1); + } + if( _DrawPart&DRAW_CONTENT ) + { + const color32 COL0 = 0x50ffffff; + const color32 COL1 = 0x501f1f1f; + Gr->DrawRect(m_PosX, m_PosY, m_PosX+m_Width-1, y, COL0, COL0, COL1, COL1); + if( m_ColTitleShadow!=0 ) + Gr->DrawText(m_TitleTextObj, m_PosX+(m_Width-m_TitleWidth)/2+1, m_PosY+1, m_ColTitleShadow, 0); + Gr->DrawText(m_TitleTextObj, m_PosX+(m_Width-m_TitleWidth)/2, m_PosY, m_ColTitleText, 0); + } + y = m_PosY+m_Font->m_CharHeight+1; + if( _DrawPart&DRAW_CONTENT && m_DrawHandles ) + Gr->DrawLine(m_PosX, y, m_PosX+m_Width-1, y, 0x30ffffff); // 0x80afafaf); + y++; + PERF( DT = Timer.GetTime(); printf("Title=%.4fms ", 1000.0*DT); ) + } + + // Draw background + PERF( Timer.Reset(); ) + if( _DrawPart&DRAW_BG ) + { + Gr->DrawRect(m_PosX, y, m_PosX+m_Width-1, m_PosY+m_Height-1, colBg2, colBg1, colBg1, colBg); + //Gr->DrawRect(m_PosX, y, m_PosX+m_VarX0-5, m_PosY+m_Height-1, m_ColHierBg); + Gr->DrawRect(m_PosX+m_VarX2+3, y, m_PosX+m_Width-1, m_PosY+m_Height-1, m_ColHierBg); + } + + if( _DrawPart&DRAW_CONTENT ) + { + // Draw highlighted line + if( m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() && m_HierTags[m_HighlightedLine].m_Var!=NULL + && (m_HierTags[m_HighlightedLine].m_Var->IsGroup() + || (!static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly && !m_IsHelpBar + && !m_HierTags[m_HighlightedLine].m_Var->IsCustom() ) ) ) // !(static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type>=TW_TYPE_CUSTOM_BASE && static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Typem_Customs.size()))) ) + { + int y0 = m_PosY + m_VarY0 + m_HighlightedLine*(m_Font->m_CharHeight+m_LineSep); + Gr->DrawRect(m_PosX+LevelSpace+6+LevelSpace*m_HierTags[m_HighlightedLine].m_Level, y0+1, m_PosX+m_VarX2, y0+m_Font->m_CharHeight-1+m_LineSep-1, m_ColHighBg0, m_ColHighBg0, m_ColHighBg1, m_ColHighBg1); + int eps = (g_TwMgr->m_GraphAPI==TW_OPENGL || g_TwMgr->m_GraphAPI==TW_OPENGL_CORE) ? 1 : 0; + if( !m_EditInPlace.m_Active ) + Gr->DrawLine(m_PosX+LevelSpace+6+LevelSpace*m_HierTags[m_HighlightedLine].m_Level, y0+m_Font->m_CharHeight+m_LineSep-1+eps, m_PosX+m_VarX2, y0+m_Font->m_CharHeight+m_LineSep-1+eps, m_ColUnderline); + } + else if( m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + int y0 = m_PosY + m_VarY0 + m_HighlightedLine*(m_Font->m_CharHeight+m_LineSep); + color32 col = ColorBlend(m_ColHighBg0, m_ColHighBg1, 0.5f); + CTwVarAtom *Atom = static_cast(m_HierTags[m_HighlightedLine].m_Var); + if( !Atom->IsCustom() // !(Atom->m_Type>=TW_TYPE_CUSTOM_BASE && Atom->m_Typem_Customs.size()) + && !(Atom->m_Type==TW_TYPE_BUTTON && Atom->m_Val.m_Button.m_Callback==NULL) ) + Gr->DrawRect(m_PosX+LevelSpace+6+LevelSpace*m_HierTags[m_HighlightedLine].m_Level, y0+1, m_PosX+m_VarX2, y0+m_Font->m_CharHeight-1+m_LineSep-1, col); + else + Gr->DrawRect(m_PosX+LevelSpace+6+LevelSpace*m_HierTags[m_HighlightedLine].m_Level, y0+1, m_PosX+LevelSpace+6+LevelSpace*m_HierTags[m_HighlightedLine].m_Level+4, y0+m_Font->m_CharHeight-1+m_LineSep-1, col); + } + color32 clight = 0x5FFFFFFF; // bar contour + Gr->DrawLine(m_PosX, m_PosY, m_PosX, m_PosY+m_Height, clight); + Gr->DrawLine(m_PosX, m_PosY, m_PosX+m_Width, m_PosY, clight); + Gr->DrawLine(m_PosX+m_Width, m_PosY, m_PosX+m_Width, m_PosY+m_Height, clight); + Gr->DrawLine(m_PosX, m_PosY+m_Height, m_PosX+m_Width, m_PosY+m_Height, clight); + int dshad = 3; // bar shadows + color32 cshad = (((m_Color>>24)/2)<<24) & 0xFF000000; + Gr->DrawRect(m_PosX, m_PosY+m_Height, m_PosX+dshad, m_PosY+m_Height+dshad, 0, cshad, 0, 0); + Gr->DrawRect(m_PosX+dshad+1, m_PosY+m_Height, m_PosX+m_Width-1, m_PosY+m_Height+dshad, cshad, cshad, 0, 0); + Gr->DrawRect(m_PosX+m_Width, m_PosY+m_Height, m_PosX+m_Width+dshad, m_PosY+m_Height+dshad, cshad, 0, 0, 0); + Gr->DrawRect(m_PosX+m_Width, m_PosY, m_PosX+m_Width+dshad, m_PosY+dshad, 0, 0, cshad, 0); + Gr->DrawRect(m_PosX+m_Width, m_PosY+dshad+1, m_PosX+m_Width+dshad, m_PosY+m_Height-1, cshad, 0, cshad, 0); + PERF( DT = Timer.GetTime(); printf("Bg=%.4fms ", 1000.0*DT); ) + + // Draw hierarchy handle + PERF( Timer.Reset(); ) + DrawHierHandle(); + PERF( DT = Timer.GetTime(); printf("Handles=%.4fms ", 1000.0*DT); ) + + // Draw labels + PERF( Timer.Reset(); ) + Gr->DrawText(m_LabelsTextObj, m_PosX+LevelSpace+6, m_PosY+m_VarY0, 0 /*m_ColLabelText*/, 0); + PERF( DT = Timer.GetTime(); printf("Labels=%.4fms ", 1000.0*DT); ) + + // Draw values + if( !m_IsPopupList ) + { + PERF( Timer.Reset(); ) + Gr->DrawText(m_ValuesTextObj, m_PosX+m_VarX1, m_PosY+m_VarY0, 0 /*m_ColValText*/, 0 /*m_ColValBg*/); + PERF( DT = Timer.GetTime(); printf("Values=%.4fms ", 1000.0*DT); ) + } + + // Draw preview for color values and draw buttons and custom types + int h, nh = (int)m_HierTags.size(); + int yh = m_PosY+m_VarY0; + int bw = IncrBtnWidth(m_Font->m_CharHeight); + for( h=0; hIsGroup() ) + { + const CTwVarGroup * Grp = static_cast(m_HierTags[h].m_Var); + if( Grp->m_SummaryCallback==CColorExt::SummaryCB && Grp->m_StructValuePtr!=NULL ) + { + // draw color value + if( Grp->m_Vars.size()>0 && Grp->m_Vars[0]!=NULL && !Grp->m_Vars[0]->IsGroup() ) + static_cast(Grp->m_Vars[0])->ValueToDouble(); // force ext update + int ydecal = (g_TwMgr->m_GraphAPI==TW_OPENGL || g_TwMgr->m_GraphAPI==TW_OPENGL_CORE) ? 1 : 0; + const int checker = 8; + for( int c=0; cDrawRect(m_PosX+m_VarX1+(c*(m_VarX2-m_VarX1))/checker, yh+1+ydecal+((c%2)*(m_Font->m_CharHeight-2))/2, m_PosX+m_VarX1-1+((c+1)*(m_VarX2-m_VarX1))/checker, yh+ydecal+(((c%2)+1)*(m_Font->m_CharHeight-2))/2, 0xffffffff); + Gr->DrawRect(m_PosX+m_VarX1, yh+1+ydecal, m_PosX+m_VarX2-1, yh+ydecal+m_Font->m_CharHeight-2, 0xbfffffff); + const CColorExt *colExt = static_cast(Grp->m_StructValuePtr); + color32 col = Color32FromARGBi((colExt->m_HasAlpha ? colExt->A : 255), colExt->R, colExt->G, colExt->B); + if( col!=0 ) + Gr->DrawRect(m_PosX+m_VarX1, yh+1+ydecal, m_PosX+m_VarX2-1, yh+ydecal+m_Font->m_CharHeight-2, col); + /* + Gr->DrawLine(m_PosX+m_VarX1-1, yh, m_PosX+m_VarX2+1, yh, 0xff000000); + Gr->DrawLine(m_PosX+m_VarX1-1, yh+m_Font->m_CharHeight, m_PosX+m_VarX2+1, yh+m_Font->m_CharHeight, 0xff000000); + Gr->DrawLine(m_PosX+m_VarX1-1, yh, m_PosX+m_VarX1-1, yh+m_Font->m_CharHeight, 0xff000000); + Gr->DrawLine(m_PosX+m_VarX2, yh, m_PosX+m_VarX2, yh+m_Font->m_CharHeight, 0xff000000); + */ + } + //else if( Grp->m_SummaryCallback==CustomTypeSummaryCB && Grp->m_StructValuePtr!=NULL ) + //{ + //} + } + else if( static_cast(m_HierTags[h].m_Var)->m_Type==TW_TYPE_BUTTON && !m_IsPopupList ) + { + // draw button + int cbx0, cbx1; + if( m_ButtonAlign == BUTTON_ALIGN_LEFT ) + { + cbx0 = m_PosX+m_VarX1+2; + cbx1 = m_PosX+m_VarX1+bw; + } + else if( m_ButtonAlign == BUTTON_ALIGN_CENTER ) + { + cbx0 = m_PosX+(m_VarX1+m_VarX2)/2-bw/2+1; + cbx1 = m_PosX+(m_VarX1+m_VarX2)/2+bw/2-1; + } + else + { + cbx0 = m_PosX+m_VarX2-2*bw+bw/2; + cbx1 = m_PosX+m_VarX2-2-bw/2; + } + int cby0 = yh+3; + int cby1 = yh+m_Font->m_CharHeight-3; + if( !static_cast(m_HierTags[h].m_Var)->m_ReadOnly ) + { + double BtnAutoDelta = g_TwMgr->m_Timer.GetTime() - m_HighlightClickBtnAuto; + if( (m_HighlightClickBtn || (BtnAutoDelta>=0 && BtnAutoDelta<0.1)) && h==m_HighlightedLine ) + { + cbx0--; cby0--; cbx1--; cby1--; + Gr->DrawRect(cbx0+2, cby0+2, cbx1+2, cby1+2, m_ColHighBtn); + Gr->DrawLine(cbx0+3, cby1+3, cbx1+4, cby1+3, 0xAF000000); + Gr->DrawLine(cbx1+3, cby0+3, cbx1+3, cby1+3, 0xAF000000); + Gr->DrawLine(cbx0+2, cby0+2, cbx0+2, cby1+2, m_ColLine); + Gr->DrawLine(cbx0+2, cby1+2, cbx1+2, cby1+2, m_ColLine); + Gr->DrawLine(cbx1+2, cby1+2, cbx1+2, cby0+2, m_ColLine); + Gr->DrawLine(cbx1+2, cby0+2, cbx0+2, cby0+2, m_ColLine); + } + else + { + Gr->DrawRect(cbx0+2, cby1+1, cbx1+2, cby1+2, (h==m_HighlightedLine)?0xAF000000:0x7F000000); + Gr->DrawRect(cbx1+1, cby0+2, cbx1+2, cby1, (h==m_HighlightedLine)?0xAF000000:0x7F000000); + Gr->DrawRect(cbx0, cby0, cbx1, cby1, (h==m_HighlightedLine)?m_ColHighBtn:m_ColBtn); + Gr->DrawLine(cbx0, cby0, cbx0, cby1, m_ColLine); + Gr->DrawLine(cbx0, cby1, cbx1, cby1, m_ColLine); + Gr->DrawLine(cbx1, cby1, cbx1, cby0, m_ColLine); + Gr->DrawLine(cbx1, cby0, cbx0, cby0, m_ColLine); + } + } + else if( static_cast(m_HierTags[h].m_Var)->m_Val.m_Button.m_Callback!=NULL ) + { + Gr->DrawRect(cbx0+1, cby0+1, cbx1+1, cby1+1, m_ColBtn); + } + else if( static_cast(m_HierTags[h].m_Var)->m_Val.m_Button.m_Separator==1 ) + { + int LevelSpace = max(m_Font->m_CharHeight-6, 4); // space used by DrawHierHandles + Gr->DrawLine(m_PosX+m_VarX0+m_HierTags[h].m_Level*LevelSpace, yh+m_Font->m_CharHeight/2, m_PosX+m_VarX2, yh+m_Font->m_CharHeight/2, m_ColSeparator ); + } + } + else if( m_HierTags[h].m_Var->IsCustom() ) //static_cast(m_HierTags[h].m_Var)->m_Type>=TW_TYPE_CUSTOM_BASE && static_cast(m_HierTags[h].m_Var)->m_Typem_Customs.size() ) + { // record custom types + CTwMgr::CMemberProxy *mProxy = static_cast(m_HierTags[h].m_Var)->m_Val.m_Custom.m_MemberProxy; + if( mProxy!=NULL && mProxy->m_StructProxy!=NULL ) + { + CustomMap::iterator it = m_CustomRecords.find(mProxy->m_StructProxy); + int xMin = m_PosX + m_VarX0 + m_HierTags[h].m_Level*LevelSpace; + int xMax = m_PosX + m_VarX2 - 2; + int yMin = yh + 1; + int yMax = yh + m_Font->m_CharHeight; + if( it==m_CustomRecords.end() ) + { + std::pair pr; + pr.first = mProxy->m_StructProxy; + pr.second.m_IndexMin = pr.second.m_IndexMax = mProxy->m_MemberIndex; + pr.second.m_XMin = xMin; + pr.second.m_XMax = xMax; + pr.second.m_YMin = yMin; + pr.second.m_YMax = yMax; + pr.second.m_Y0 = 0; // will be filled by the draw loop below + pr.second.m_Y1 = 0; // will be filled by the draw loop below + pr.second.m_Var = mProxy->m_VarParent; + m_CustomRecords.insert(pr); + } + else + { + it->second.m_IndexMin = min(it->second.m_IndexMin, mProxy->m_MemberIndex); + it->second.m_IndexMax = min(it->second.m_IndexMax, mProxy->m_MemberIndex); + it->second.m_XMin = min(it->second.m_XMin, xMin); + it->second.m_XMax = max(it->second.m_XMax, xMax); + it->second.m_YMin = min(it->second.m_YMin, yMin); + it->second.m_YMax = max(it->second.m_YMax, yMax); + it->second.m_Y0 = 0; + it->second.m_Y1 = 0; + assert( it->second.m_Var==mProxy->m_VarParent ); + } + } + } + + yh += m_Font->m_CharHeight+m_LineSep; + } + + // Draw custom types + for( CustomMap::iterator it = m_CustomRecords.begin(); it!=m_CustomRecords.end(); ++it ) + { + CTwMgr::CStructProxy *sProxy = it->first; + assert( sProxy!=NULL ); + CCustomRecord& r = it->second; + if( sProxy->m_CustomDrawCallback!=NULL ) + { + int y0 = r.m_YMin - max(r.m_IndexMin - sProxy->m_CustomIndexFirst, 0)*(m_Font->m_CharHeight + m_LineSep); + int y1 = y0 + max(sProxy->m_CustomIndexLast - sProxy->m_CustomIndexFirst + 1, 0)*(m_Font->m_CharHeight + m_LineSep) - 2; + if( y0ChangeViewport(r.m_XMin, r.m_YMin, r.m_XMax-r.m_XMin+1, r.m_YMax-r.m_YMin+1, 0, y0-r.m_YMin+1); + sProxy->m_CustomDrawCallback(r.m_XMax-r.m_XMin, y1-y0, sProxy->m_StructExtData, sProxy->m_StructClientData, this, r.m_Var); + Gr->RestoreViewport(); + } + } + } + + if( m_DrawHandles && !m_IsPopupList ) + { + // Draw -/+/o/click/v buttons + if( (m_DrawIncrDecrBtn || m_DrawClickBtn || m_DrawListBtn || m_DrawBoolBtn || m_DrawRotoBtn) && m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() ) + { + int y0 = m_PosY + m_VarY0 + m_HighlightedLine*(m_Font->m_CharHeight+m_LineSep); + if( m_DrawIncrDecrBtn ) + { + bool IsMin = false; + bool IsMax = false; + if( !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + const CTwVarAtom *Atom = static_cast(m_HierTags[m_HighlightedLine].m_Var); + double v, vmin, vmax; + v = Atom->ValueToDouble(); + Atom->MinMaxStepToDouble(&vmin, &vmax, NULL); + IsMax = (v>=vmax); + IsMin = (v<=vmin); + } + + /* + Gr->DrawRect(m_PosX+m_VarX2-2*bw+1, y0+1, m_PosX+m_VarX2-bw-1, y0+m_Font->m_CharHeight-2, (m_HighlightDecrBtn && !IsMin)?m_ColHighBtn:m_ColBtn); + Gr->DrawRect(m_PosX+m_VarX2-bw+1, y0+1, m_PosX+m_VarX2-1, y0+m_Font->m_CharHeight-2, (m_HighlightIncrBtn && !IsMax)?m_ColHighBtn:m_ColBtn); + // [-] + Gr->DrawLine(m_PosX+m_VarX2-2*bw+3+(bw>8?1:0), y0+m_Font->m_CharHeight/2, m_PosX+m_VarX2-bw-2-(bw>8?1:0), y0+m_Font->m_CharHeight/2, IsMin?m_ColValTextRO:m_ColTitleText); + // [+] + Gr->DrawLine(m_PosX+m_VarX2-bw+3, y0+m_Font->m_CharHeight/2, m_PosX+m_VarX2-2, y0+m_Font->m_CharHeight/2, IsMax?m_ColValTextRO:m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX2-bw/2, y0+m_Font->m_CharHeight/2-bw/2+2, m_PosX+m_VarX2-bw/2, y0+m_Font->m_CharHeight/2+bw/2-1, IsMax?m_ColValTextRO:m_ColTitleText); + */ + Gr->DrawRect(m_PosX+m_VarX2-3*bw+1, y0+1, m_PosX+m_VarX2-2*bw-1, y0+m_Font->m_CharHeight-2, (m_HighlightDecrBtn && !IsMin)?m_ColHighBtn:m_ColBtn); + Gr->DrawRect(m_PosX+m_VarX2-2*bw+1, y0+1, m_PosX+m_VarX2-bw-1, y0+m_Font->m_CharHeight-2, (m_HighlightIncrBtn && !IsMax)?m_ColHighBtn:m_ColBtn); + // [-] + Gr->DrawLine(m_PosX+m_VarX2-3*bw+3+(bw>8?1:0), y0+m_Font->m_CharHeight/2, m_PosX+m_VarX2-2*bw-2-(bw>8?1:0), y0+m_Font->m_CharHeight/2, IsMin?m_ColValTextRO:m_ColTitleText); + // [+] + Gr->DrawLine(m_PosX+m_VarX2-2*bw+3, y0+m_Font->m_CharHeight/2, m_PosX+m_VarX2-bw-2, y0+m_Font->m_CharHeight/2, IsMax?m_ColValTextRO:m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX2-bw-bw/2, y0+m_Font->m_CharHeight/2-bw/2+2, m_PosX+m_VarX2-bw-bw/2, y0+m_Font->m_CharHeight/2+bw/2-1, IsMax?m_ColValTextRO:m_ColTitleText); + } + else if( m_DrawListBtn ) + { + // [v] + int eps = 1; + int dx = -1; + Gr->DrawRect(m_PosX+m_VarX2-bw+1, y0+1, m_PosX+m_VarX2-1, y0+m_Font->m_CharHeight-2, m_HighlightListBtn?m_ColHighBtn:m_ColBtn); + Gr->DrawLine(m_PosX+m_VarX2-bw+4+dx, y0+m_Font->m_CharHeight/2-eps, m_PosX+m_VarX2-bw/2+1+dx, y0+m_Font->m_CharHeight-4, m_ColTitleText, true); + Gr->DrawLine(m_PosX+m_VarX2-bw/2+1+dx, y0+m_Font->m_CharHeight-4, m_PosX+m_VarX2-2+dx, y0+m_Font->m_CharHeight/2-1, m_ColTitleText, true); + } + else if( m_DrawBoolBtn ) + { + Gr->DrawRect(m_PosX+m_VarX2-bw+1, y0+1, m_PosX+m_VarX2-1, y0+m_Font->m_CharHeight-2, m_HighlightBoolBtn?m_ColHighBtn:m_ColBtn); + // [x] + //Gr->DrawLine(m_PosX+m_VarX2-bw/2-bw/6, y0+m_Font->m_CharHeight/2-bw/6, m_PosX+m_VarX2-bw/2+bw/6, y0+m_Font->m_CharHeight/2+bw/6, m_ColTitleText, true); + //Gr->DrawLine(m_PosX+m_VarX2-bw/2-bw/6, y0+m_Font->m_CharHeight/2+bw/6, m_PosX+m_VarX2-bw/2+bw/6, y0+m_Font->m_CharHeight/2-bw/6, m_ColTitleText, true); + // [<>] + int s = bw/4; + int eps = 1; + Gr->DrawLine(m_PosX+m_VarX2-bw/2-1, y0+m_Font->m_CharHeight/2-s, m_PosX+m_VarX2-bw/2-s-1, y0+m_Font->m_CharHeight/2, m_ColTitleText, true); + Gr->DrawLine(m_PosX+m_VarX2-bw/2-s-1, y0+m_Font->m_CharHeight/2, m_PosX+m_VarX2-bw/2-eps, y0+m_Font->m_CharHeight/2+s+1-eps, m_ColTitleText, true); + //Gr->DrawLine(m_PosX+m_VarX2-bw/2+1, y0+m_Font->m_CharHeight/2+s, m_PosX+m_VarX2-bw/2+s+1, y0+m_Font->m_CharHeight/2, m_ColTitleText, true); + //Gr->DrawLine(m_PosX+m_VarX2-bw/2+s+1, y0+m_Font->m_CharHeight/2, m_PosX+m_VarX2-bw/2+1, y0+m_Font->m_CharHeight/2-s, m_ColTitleText, true); + Gr->DrawLine(m_PosX+m_VarX2-bw/2+2, y0+m_Font->m_CharHeight/2-s, m_PosX+m_VarX2-bw/2+s+2, y0+m_Font->m_CharHeight/2, m_ColTitleText, true); + Gr->DrawLine(m_PosX+m_VarX2-bw/2+s+2, y0+m_Font->m_CharHeight/2, m_PosX+m_VarX2-bw/2+1+eps, y0+m_Font->m_CharHeight/2+s+1-eps, m_ColTitleText, true); + } + + if( m_DrawRotoBtn ) + { + // [o] rotoslider button + /* + Gr->DrawRect(m_PosX+m_VarX1-bw-1, y0+1, m_PosX+m_VarX1-3, y0+m_Font->m_CharHeight-2, m_HighlightRotoBtn?m_ColHighBtn:m_ColBtn); + Gr->DrawLine(m_PosX+m_VarX1-bw+bw/2-2, y0+m_Font->m_CharHeight/2-1, m_PosX+m_VarX1-bw+bw/2-1, y0+m_Font->m_CharHeight/2-1, m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX1-bw+bw/2-3, y0+m_Font->m_CharHeight/2+0, m_PosX+m_VarX1-bw+bw/2+0, y0+m_Font->m_CharHeight/2+0, m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX1-bw+bw/2-3, y0+m_Font->m_CharHeight/2+1, m_PosX+m_VarX1-bw+bw/2+0, y0+m_Font->m_CharHeight/2+1, m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX1-bw+bw/2-2, y0+m_Font->m_CharHeight/2+2, m_PosX+m_VarX1-bw+bw/2-1, y0+m_Font->m_CharHeight/2+2, m_ColTitleText); + */ + /* + Gr->DrawRect(m_PosX+m_VarX2-3*bw+1, y0+1, m_PosX+m_VarX2-2*bw-1, y0+m_Font->m_CharHeight-2, m_HighlightRotoBtn?m_ColHighBtn:m_ColBtn); + Gr->DrawLine(m_PosX+m_VarX2-3*bw+bw/2+0, y0+m_Font->m_CharHeight/2-1, m_PosX+m_VarX2-3*bw+bw/2+1, y0+m_Font->m_CharHeight/2-1, m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX2-3*bw+bw/2-1, y0+m_Font->m_CharHeight/2+0, m_PosX+m_VarX2-3*bw+bw/2+2, y0+m_Font->m_CharHeight/2+0, m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX2-3*bw+bw/2-1, y0+m_Font->m_CharHeight/2+1, m_PosX+m_VarX2-3*bw+bw/2+2, y0+m_Font->m_CharHeight/2+1, m_ColTitleText); + Gr->DrawLine(m_PosX+m_VarX2-3*bw+bw/2+0, y0+m_Font->m_CharHeight/2+2, m_PosX+m_VarX2-3*bw+bw/2+1, y0+m_Font->m_CharHeight/2+2, m_ColTitleText); + */ + int dy = 0; + Gr->DrawRect(m_PosX+m_VarX2-bw+1, y0+1, m_PosX+m_VarX2-1, y0+m_Font->m_CharHeight-2, m_HighlightRotoBtn?m_ColHighBtn:m_ColBtn); + Gr->DrawLine(m_PosX+m_VarX2-bw+bw/2+0, y0+m_Font->m_CharHeight/2-1+dy, m_PosX+m_VarX2-bw+bw/2+1, y0+m_Font->m_CharHeight/2-1+dy, m_ColTitleText, true); + Gr->DrawLine(m_PosX+m_VarX2-bw+bw/2-1, y0+m_Font->m_CharHeight/2+0+dy, m_PosX+m_VarX2-bw+bw/2+2, y0+m_Font->m_CharHeight/2+0+dy, m_ColTitleText, true); + Gr->DrawLine(m_PosX+m_VarX2-bw+bw/2-1, y0+m_Font->m_CharHeight/2+1+dy, m_PosX+m_VarX2-bw+bw/2+2, y0+m_Font->m_CharHeight/2+1+dy, m_ColTitleText, true); + Gr->DrawLine(m_PosX+m_VarX2-bw+bw/2+0, y0+m_Font->m_CharHeight/2+2+dy, m_PosX+m_VarX2-bw+bw/2+1, y0+m_Font->m_CharHeight/2+2+dy, m_ColTitleText, true); + } + } + + + // Draw value width slider + if( !m_HighlightValWidth ) + { + color32 col = m_DarkText ? COLOR32_WHITE : m_ColTitleText; + Gr->DrawRect(m_PosX+m_VarX1-2, m_PosY+m_VarY0-8, m_PosX+m_VarX1-1, m_PosY+m_VarY0-4, col); + Gr->DrawLine(m_PosX+m_VarX1-1, m_PosY+m_VarY0-3, m_PosX+m_VarX1, m_PosY+m_VarY0-3, m_ColLineShadow); + Gr->DrawLine(m_PosX+m_VarX1, m_PosY+m_VarY0-3, m_PosX+m_VarX1, m_PosY+m_VarY0-8, m_ColLineShadow); + } + else + { + color32 col = m_DarkText ? COLOR32_WHITE : m_ColTitleText; + Gr->DrawRect(m_PosX+m_VarX1-2, m_PosY+m_VarY0-8, m_PosX+m_VarX1-1, m_PosY+m_VarY1, col); + Gr->DrawLine(m_PosX+m_VarX1-1, m_PosY+m_VarY1+1, m_PosX+m_VarX1, m_PosY+m_VarY1+1, m_ColLineShadow); + Gr->DrawLine(m_PosX+m_VarX1, m_PosY+m_VarY1+1, m_PosX+m_VarX1, m_PosY+m_VarY0-8, m_ColLineShadow); + } + + // Draw labels & values headers + if (m_HighlightLabelsHeader) + { + Gr->DrawRect(m_PosX+m_VarX0, m_PosY+m_Font->m_CharHeight+2, m_PosX+m_VarX1-4, m_PosY+m_VarY0-1, m_ColHighBg0, m_ColHighBg0, m_ColHighBg1, m_ColHighBg1); + } + if (m_HighlightValuesHeader) + { + Gr->DrawRect(m_PosX+m_VarX1+2, m_PosY+m_Font->m_CharHeight+2, m_PosX+m_VarX2, m_PosY+m_VarY0-1, m_ColHighBg0, m_ColHighBg0, m_ColHighBg1, m_ColHighBg1); + } + } + + // Draw key shortcut text + if( m_HighlightedLine>=0 && m_HighlightedLine==m_ShortcutLine && !m_IsPopupList && !m_EditInPlace.m_Active ) + { + PERF( Timer.Reset(); ) + Gr->DrawRect(m_PosX+m_Font->m_CharHeight-2, m_PosY+m_VarY1+1, m_PosX+m_Width-m_Font->m_CharHeight-2, m_PosY+m_VarY1+1+m_Font->m_CharHeight, m_ColShortcutBg); + Gr->DrawText(m_ShortcutTextObj, m_PosX+m_Font->m_CharHeight, m_PosY+m_VarY1+1, m_ColShortcutText, 0); + PERF( DT = Timer.GetTime(); printf("Shortcut=%.4fms ", 1000.0*DT); ) + } + else if( (m_HighlightLabelsHeader || m_HighlightValuesHeader) && !m_IsPopupList && !m_EditInPlace.m_Active ) + { + Gr->DrawRect(m_PosX+m_Font->m_CharHeight-2, m_PosY+m_VarY1+1, m_PosX+m_Width-m_Font->m_CharHeight-2, m_PosY+m_VarY1+1+m_Font->m_CharHeight, m_ColShortcutBg); + Gr->DrawText(m_HeadersTextObj, m_PosX+m_Font->m_CharHeight, m_PosY+m_VarY1+1, m_ColShortcutText, 0); + } + else if( m_IsHelpBar ) + { + if( g_TwMgr->m_KeyPressedTextObj && g_TwMgr->m_KeyPressedStr.size()>0 ) // Draw key pressed + { + if( g_TwMgr->m_KeyPressedBuildText ) + { + string Str = g_TwMgr->m_KeyPressedStr; + ClampText(Str, m_Font, m_Width-2*m_Font->m_CharHeight); + g_TwMgr->m_Graph->BuildText(g_TwMgr->m_KeyPressedTextObj, &Str, NULL, NULL, 1, g_TwMgr->m_HelpBar->m_Font, 0, 0); + g_TwMgr->m_KeyPressedBuildText = false; + g_TwMgr->m_KeyPressedTime = (float)g_BarTimer.GetTime(); + } + if( (float)g_BarTimer.GetTime()>g_TwMgr->m_KeyPressedTime+1.0f ) // draw key pressed at least 1 second + g_TwMgr->m_KeyPressedStr = ""; + PERF( Timer.Reset(); ) + Gr->DrawRect(m_PosX+m_Font->m_CharHeight-2, m_PosY+m_VarY1+1, m_PosX+m_Width-m_Font->m_CharHeight-2, m_PosY+m_VarY1+1+m_Font->m_CharHeight, m_ColShortcutBg); + Gr->DrawText(g_TwMgr->m_KeyPressedTextObj, m_PosX+m_Font->m_CharHeight, m_PosY+m_VarY1+1, m_ColShortcutText, 0); + PERF( DT = Timer.GetTime(); printf("KeyPressed=%.4fms ", 1000.0*DT); ) + } + else + { + if( g_TwMgr->m_InfoBuildText ) + { + string Info = "> AntTweakBar"; + char Ver[64]; + sprintf(Ver, " (v%d.%02d)", TW_VERSION/100, TW_VERSION%100); + Info += Ver; + ClampText(Info, m_Font, m_Width-2*m_Font->m_CharHeight); + g_TwMgr->m_Graph->BuildText(g_TwMgr->m_InfoTextObj, &Info, NULL, NULL, 1, g_TwMgr->m_HelpBar->m_Font, 0, 0); + g_TwMgr->m_InfoBuildText = false; + } + PERF( Timer.Reset(); ) + Gr->DrawRect(m_PosX+m_Font->m_CharHeight-2, m_PosY+m_VarY1+1, m_PosX+m_Width-m_Font->m_CharHeight-2, m_PosY+m_VarY1+1+m_Font->m_CharHeight, m_ColShortcutBg); + Gr->DrawText(g_TwMgr->m_InfoTextObj, m_PosX+m_Font->m_CharHeight, m_PosY+m_VarY1+1, m_ColInfoText, 0); + PERF( DT = Timer.GetTime(); printf("Info=%.4fms ", 1000.0*DT); ) + } + } + + if( !m_IsPopupList ) + { + // Draw RotoSlider + RotoDraw(); + + // Draw EditInPlace + EditInPlaceDraw(); + } + + if( g_TwMgr->m_PopupBar!=NULL && this!=g_TwMgr->m_PopupBar ) + { + // darken bar if a popup bar is displayed + Gr->DrawRect(m_PosX, m_PosY, m_PosX+m_Width-1, m_PosY+m_Height-1, 0x1F000000); + } + } + } + else // minimized + { + int vpx, vpy, vpw, vph; + vpx = 0; + vpy = 0; + vpw = g_TwMgr->m_WndWidth; + vph = g_TwMgr->m_WndHeight; + if( g_TwMgr->m_IconMarginX>0 ) + { + vpx = min(g_TwMgr->m_IconMarginX, vpw/3); + vpw -= 2 * vpx; + } + if( g_TwMgr->m_IconMarginY>0 ) + { + vpy = min(g_TwMgr->m_IconMarginY, vph/3); + vph -= 2 * vpy; + } + + int MinXOffset = 0, MinYOffset = 0; + if( g_TwMgr->m_IconPos==3 ) // top-right + { + if( g_TwMgr->m_IconAlign==1 ) // horizontal + { + int n = max(1, vpw/m_Font->m_CharHeight-1); + m_MinPosX = vpx + vpw-((m_MinNumber%n)+1)*m_Font->m_CharHeight; + m_MinPosY = vpy + (m_MinNumber/n)*m_Font->m_CharHeight; + MinYOffset = m_Font->m_CharHeight; + MinXOffset = -m_TitleWidth; + } + else // vertical + { + int n = max(1, vph/m_Font->m_CharHeight-1); + m_MinPosY = vpy + (m_MinNumber%n)*m_Font->m_CharHeight; + m_MinPosX = vpx + vpw-((m_MinNumber/n)+1)*m_Font->m_CharHeight; + MinXOffset = -m_TitleWidth-m_Font->m_CharHeight; + } + } + else if( g_TwMgr->m_IconPos==2 ) // top-left + { + if( g_TwMgr->m_IconAlign==1 ) // horizontal + { + int n = max(1, vpw/m_Font->m_CharHeight-1); + m_MinPosX = vpx + (m_MinNumber%n)*m_Font->m_CharHeight; + m_MinPosY = vpy + (m_MinNumber/n)*m_Font->m_CharHeight; + MinYOffset = m_Font->m_CharHeight; + } + else // vertical + { + int n = max(1, vph/m_Font->m_CharHeight-1); + m_MinPosY = vpy + (m_MinNumber%n)*m_Font->m_CharHeight; + m_MinPosX = vpx + (m_MinNumber/n)*m_Font->m_CharHeight; + MinXOffset = m_Font->m_CharHeight; + } + } + else if( g_TwMgr->m_IconPos==1 ) // bottom-right + { + if( g_TwMgr->m_IconAlign==1 ) // horizontal + { + int n = max(1, vpw/m_Font->m_CharHeight-1); + m_MinPosX = vpx + vpw-((m_MinNumber%n)+1)*m_Font->m_CharHeight; + m_MinPosY = vpy + vph-((m_MinNumber/n)+1)*m_Font->m_CharHeight; + MinYOffset = -m_Font->m_CharHeight; + MinXOffset = -m_TitleWidth; + } + else // vertical + { + int n = max(1, vph/m_Font->m_CharHeight-1); + m_MinPosY = vpy + vph-((m_MinNumber%n)+1)*m_Font->m_CharHeight; + m_MinPosX = vpx + vpw-((m_MinNumber/n)+1)*m_Font->m_CharHeight; + MinXOffset = -m_TitleWidth-m_Font->m_CharHeight; + } + } + else // bottom-left + { + if( g_TwMgr->m_IconAlign==1 ) // horizontal + { + int n = max(1, vpw/m_Font->m_CharHeight-1); + m_MinPosX = vpx + (m_MinNumber%n)*m_Font->m_CharHeight; + m_MinPosY = vpy + vph-((m_MinNumber/n)+1)*m_Font->m_CharHeight; + MinYOffset = -m_Font->m_CharHeight; + } + else // vertical + { + int n = max(1, vph/m_Font->m_CharHeight-1); + m_MinPosY = vpy + vph-((m_MinNumber%n)+1)*m_Font->m_CharHeight; + m_MinPosX = vpx + (m_MinNumber/n)*m_Font->m_CharHeight; + MinXOffset = m_Font->m_CharHeight; + } + } + + if( m_HighlightMaximize ) + { + // Draw title + if( _DrawPart&DRAW_BG ) + { + Gr->DrawRect(m_MinPosX, m_MinPosY, m_MinPosX+m_Font->m_CharHeight, m_MinPosY+m_Font->m_CharHeight, m_ColTitleUnactiveBg); + Gr->DrawRect(m_MinPosX+MinXOffset, m_MinPosY+MinYOffset, m_MinPosX+MinXOffset+m_TitleWidth+m_Font->m_CharHeight, m_MinPosY+MinYOffset+m_Font->m_CharHeight, m_ColTitleUnactiveBg); + } + if( _DrawPart&DRAW_CONTENT ) + { + if( m_ColTitleShadow!=0 ) + Gr->DrawText(m_TitleTextObj, m_MinPosX+MinXOffset+m_Font->m_CharHeight/2, m_MinPosY+1+MinYOffset, m_ColTitleShadow, 0); + Gr->DrawText(m_TitleTextObj, m_MinPosX+MinXOffset+m_Font->m_CharHeight/2, m_MinPosY+MinYOffset, m_ColTitleText, 0); + } + } + + if( !m_IsHelpBar ) + { + // Draw maximize button + int xm = m_MinPosX+2, wm=m_Font->m_CharHeight-6; + wm = (wm<6) ? 6 : wm; + if( _DrawPart&DRAW_BG ) + Gr->DrawRect(xm+1, m_MinPosY+4, xm+wm-1, m_MinPosY+3+wm, m_HighlightMaximize?m_ColHighBtn:m_ColBtn); + if( _DrawPart&DRAW_CONTENT ) + { + Gr->DrawLine(xm, m_MinPosY+3, xm+wm, m_MinPosY+3, m_ColLine); + Gr->DrawLine(xm+wm, m_MinPosY+3, xm+wm, m_MinPosY+3+wm, m_ColLine); + Gr->DrawLine(xm+wm, m_MinPosY+3+wm, xm, m_MinPosY+3+wm, m_ColLine); + Gr->DrawLine(xm, m_MinPosY+3+wm, xm, m_MinPosY+3, m_ColLine); + Gr->DrawLine(xm+wm+1, m_MinPosY+4, xm+wm+1, m_MinPosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm+1, m_MinPosY+4+wm, xm, m_MinPosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm/3-1, m_MinPosY+3+wm-wm/3, xm+wm/2, m_MinPosY+6, m_ColTitleText, true); + Gr->DrawLine(xm+wm-wm/3+1, m_MinPosY+3+wm-wm/3, xm+wm/2, m_MinPosY+6, m_ColTitleText, true); + } + } + else + { + // Draw help button + int xm = m_MinPosX+2, wm=m_Font->m_CharHeight-6; + wm = (wm<6) ? 6 : wm; + if( _DrawPart&DRAW_BG ) + Gr->DrawRect(xm+1, m_MinPosY+4, xm+wm-1, m_MinPosY+3+wm, m_HighlightMaximize?m_ColHighBtn:m_ColBtn); + if( _DrawPart&DRAW_CONTENT ) + { + Gr->DrawLine(xm, m_MinPosY+3, xm+wm, m_MinPosY+3, m_ColLine); + Gr->DrawLine(xm+wm, m_MinPosY+3, xm+wm, m_MinPosY+3+wm, m_ColLine); + Gr->DrawLine(xm+wm, m_MinPosY+3+wm, xm, m_MinPosY+3+wm, m_ColLine); + Gr->DrawLine(xm, m_MinPosY+3+wm, xm, m_MinPosY+3, m_ColLine); + Gr->DrawLine(xm+wm+1, m_MinPosY+4, xm+wm+1, m_MinPosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm+1, m_MinPosY+4+wm, xm, m_MinPosY+4+wm, m_ColLineShadow); + Gr->DrawLine(xm+wm/2-wm/6, m_MinPosY+3+wm/4, xm+wm-wm/3, m_MinPosY+3+wm/4, m_ColTitleText); + Gr->DrawLine(xm+wm-wm/3, m_MinPosY+3+wm/4, xm+wm-wm/3, m_MinPosY+3+wm/2, m_ColTitleText); + Gr->DrawLine(xm+wm-wm/3, m_MinPosY+3+wm/2, xm+wm/2, m_MinPosY+3+wm/2, m_ColTitleText); + Gr->DrawLine(xm+wm/2, m_MinPosY+3+wm/2, xm+wm/2, m_MinPosY+3+wm-wm/4, m_ColTitleText); + Gr->DrawLine(xm+wm/2, m_MinPosY+3+wm-wm/4+1, xm+wm/2, m_MinPosY+3+wm-wm/4+2, m_ColTitleText); + } + } + } +} + +// --------------------------------------------------------------------------- + +bool CTwBar::MouseMotion(int _X, int _Y) +{ + assert(g_TwMgr->m_Graph && g_TwMgr->m_WndHeight>0 && g_TwMgr->m_WndWidth>0); + if( !m_UpToDate ) + Update(); + + bool Handled = false; + bool CustomArea = false; + if( !m_IsMinimized ) + { + bool InBar = (_X>=m_PosX && _X=m_PosY && _Ym_Bars.size(); ++ib ) + if( g_TwMgr->m_Bars[ib]!=NULL ) + { + g_TwMgr->m_Bars[ib]->m_DrawHandles = false; + g_TwMgr->m_Bars[ib]->m_HighlightTitle = false; + } + m_DrawHandles = InBar; + const int ContainedMargin = 32; + + if( !m_MouseDrag ) + { + Handled = InBar; + m_HighlightedLine = -1; + m_HighlightIncrBtn = false; + m_HighlightDecrBtn = false; + m_HighlightRotoBtn = false; + if( abs(m_MouseOriginX-_X)>6 || abs(m_MouseOriginY-_Y)>6 ) + m_HighlightClickBtn = false; + m_HighlightListBtn = false; + m_HighlightTitle = false; + m_HighlightScroll = false; + m_HighlightUpScroll = false; + m_HighlightDnScroll = false; + m_HighlightMinimize = false; + m_HighlightFont = false; + m_HighlightValWidth = false; + m_HighlightLabelsHeader = false; + m_HighlightValuesHeader = false; + //if( InBar && _X>m_PosX+m_Font->m_CharHeight+1 && _X=m_PosY+m_VarY0 && _Ym_PosX+2 && _X=m_PosY+m_VarY0 && _Ym_CharHeight+m_LineSep); + if( m_HighlightedLine>=(int)m_HierTags.size() ) + m_HighlightedLine = -1; + else if(m_HighlightedLine>=0) + m_HighlightedLineLastValid = m_HighlightedLine; + if( m_HighlightedLine<0 || m_HierTags[m_HighlightedLine].m_Var==NULL || m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + ANT_SET_CURSOR(Arrow); + else + { + if( !m_HierTags[m_HighlightedLine].m_Var->IsGroup() && static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_NoSlider ) + { + if( static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly && !m_IsHelpBar + && !(static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Type==TW_TYPE_BUTTON && static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_Val.m_Button.m_Callback==NULL) ) + ANT_SET_CURSOR(No); //(Arrow); + else + { + ANT_SET_CURSOR(Arrow); + CustomArea = true; + } + + if( m_DrawListBtn ) + { + m_HighlightListBtn = true; + CustomArea = false; + } + if( m_DrawBoolBtn ) + { + m_HighlightBoolBtn = true; + CustomArea = false; + } + } + else if( m_DrawRotoBtn && ( _X>=m_PosX+m_VarX2-IncrBtnWidth(m_Font->m_CharHeight) || _X=m_PosX+m_VarX2-2*IncrBtnWidth(m_Font->m_CharHeight) ) // [+] button + { + m_HighlightIncrBtn = true; + ANT_SET_CURSOR(Arrow); + } + else if( m_DrawIncrDecrBtn && _X>=m_PosX+m_VarX2-3*IncrBtnWidth(m_Font->m_CharHeight) ) // [-] button + { + m_HighlightDecrBtn = true; + ANT_SET_CURSOR(Arrow); + } + else if( !m_HierTags[m_HighlightedLine].m_Var->IsGroup() && static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly ) + { + if( !m_IsHelpBar ) + ANT_SET_CURSOR(No); + else + ANT_SET_CURSOR(Arrow); + } + else + //ANT_SET_CURSOR(Point); + ANT_SET_CURSOR(IBeam); + } + } + else if( InBar && m_Movable && !m_IsPopupList && _X>=m_PosX+2*m_Font->m_CharHeight && _Xm_CharHeight && _Ym_CharHeight ) + { // mouse over title + m_HighlightTitle = true; + ANT_SET_CURSOR(Move); + } + else if ( InBar && !m_IsPopupList && _X>=m_PosX+m_VarX1-5 && _Xm_PosY+m_Font->m_CharHeight && _Y=m_PosX+m_VarX0 && _Xm_PosY+m_Font->m_CharHeight && _Y=m_PosX+m_VarX1+5 && _Xm_PosY+m_Font->m_CharHeight && _Y=m_PosX && _Xm_CharHeight && _Y>=m_ScrollY0 && _Y=m_PosX+m_VarX2+2 && _X=m_ScrollY0 && _Y=m_PosX+m_VarX2+2 && _X=m_PosY+m_VarY0 && _Y=m_PosX+m_VarX2+2 && _X=m_ScrollY1 && _Y=m_PosX && _Xm_CharHeight && _Y>=m_PosY && _Ym_CharHeight ) + ANT_SET_CURSOR(TopLeft); + else if( InBar && !m_IsPopupList && _X>=m_PosX && _Xm_CharHeight && _Y>=m_PosY+m_Height-m_Font->m_CharHeight && _Y=m_PosX+m_Width-m_Font->m_CharHeight && _X=m_PosY && _Ym_CharHeight ) + ANT_SET_CURSOR(TopRight); + else if( InBar && m_Resizable && !m_IsPopupList && _X>=m_PosX+m_Width-m_Font->m_CharHeight && _X=m_PosY+m_Height-m_Font->m_CharHeight && _Ym_FontResizable && !m_IsPopupList && _X>=m_PosX+m_Font->m_CharHeight && _Xm_CharHeight && _Ym_CharHeight ) + { + m_HighlightFont = true; + ANT_SET_CURSOR(Arrow); + } + else if( InBar && m_Iconifiable && !m_IsPopupList && _X>=m_PosX+m_Width-2*m_Font->m_CharHeight && _Xm_CharHeight && _Ym_CharHeight ) + { + m_HighlightMinimize = true; + ANT_SET_CURSOR(Arrow); + } + else if( m_IsHelpBar && InBar && _X>=m_PosX+m_VarX0 && _Xm_CharHeight && _Y>m_PosY+m_Height-m_Font->m_CharHeight && _Y=0 && m_HighlightedLine<(int)m_HierTags.size() && m_HierTags[m_HighlightedLine].m_Var && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + /* + CTwVarAtom *Var = static_cast(m_HierTags[m_HighlightedLine].m_Var); + int Delta = _X-m_MouseOriginX; + if( Delta!=0 ) + { + if( !Var->m_NoSlider && !Var->m_ReadOnly ) + { + Var->Increment(Delta); + NotUpToDate(); + } + m_VarHasBeenIncr = true; + } + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + if( !Var->m_NoSlider && !Var->m_ReadOnly ) + ANT_SET_CURSOR(Center); + //ANT_SET_CURSOR(WE); + else + ANT_SET_CURSOR(Arrow); + Handled = true; + */ + + // move rotoslider + if( !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_NoSlider ) + RotoOnMouseMove(_X, _Y); + + if( static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly ) + ANT_SET_CURSOR(No); + else if( static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_NoSlider ) + { + ANT_SET_CURSOR(Arrow); + CustomArea = true; + } + m_VarHasBeenIncr = true; + Handled = true; + m_DrawHandles = true; + } + else if( m_MouseDragTitle ) + { + int y = m_PosY; + m_PosX += _X-m_MouseOriginX; + m_PosY += _Y-m_MouseOriginY; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + int vpx, vpy, vpw, vph; + vpx = 0; + vpy = 0; + vpw = g_TwMgr->m_WndWidth; + vph = g_TwMgr->m_WndHeight; + if( m_Contained ) + { + if( m_PosX+m_Width>vpx+vpw ) + m_PosX = vpx+vpw-m_Width; + if( m_PosXvpy+vph ) + m_PosY = vpy+vph-m_Height; + if( m_PosYvpx+vpw ) + m_PosX = vpx+vpw-ContainedMargin; + if( m_PosX+m_Widthvpy+vph ) + m_PosY = vpy+vph-ContainedMargin; + if( m_PosY+m_Heightm_HelpBarNotUpToDate = true; + ANT_SET_CURSOR(WE); + Handled = true; + m_DrawHandles = true; + } + else if( m_MouseDragScroll ) + { + if( m_ScrollYH>0 ) + { + int dl = ((_Y-m_MouseOriginY)*m_NbHierLines)/m_ScrollYH; + if( m_FirstLine0+dl<0 ) + m_FirstLine = 0; + else if( m_FirstLine0+dl+m_NbDisplayedLines>m_NbHierLines ) + m_FirstLine = m_NbHierLines-m_NbDisplayedLines; + else + m_FirstLine = m_FirstLine0+dl; + NotUpToDate(); + } + #ifdef ANT_WINDOWS + ANT_SET_CURSOR(NS); + #else + ANT_SET_CURSOR(Arrow); + #endif + Handled = true; + m_DrawHandles = true; + } + else if( m_MouseDragResizeUL ) + { + int w = m_Width; + int h = m_Height; + m_PosX += _X-m_MouseOriginX; + m_PosY += _Y-m_MouseOriginY; + m_Width -= _X-m_MouseOriginX; + m_Height -= _Y-m_MouseOriginY; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + int vpx = 0, vpy = 0, vpw = g_TwMgr->m_WndWidth, vph = g_TwMgr->m_WndHeight; + if( !m_Contained ) + { + if( m_PosX+ContainedMargin>vpx+vpw ) + m_PosX = vpx+vpw-ContainedMargin; + if( m_PosX+m_Widthvpy+vph ) + m_PosY = vpy+vph-ContainedMargin; + if( m_PosY+m_Height 0) + m_ValuesWidth = int(m_ValuesWidthRatio * m_Width + 0.5); + ANT_SET_CURSOR(TopLeft); + NotUpToDate(); + if( m_IsHelpBar ) + { + g_TwMgr->m_HelpBarNotUpToDate = true; + g_TwMgr->m_HelpBarUpdateNow = true; + } + g_TwMgr->m_KeyPressedBuildText = true; + g_TwMgr->m_InfoBuildText = true; + Handled = true; + m_DrawHandles = true; + } + else if( m_MouseDragResizeUR ) + { + int h = m_Height; + m_PosY += _Y-m_MouseOriginY; + m_Width += _X-m_MouseOriginX; + m_Height -= _Y-m_MouseOriginY; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + int vpx = 0, vpy = 0, vpw = g_TwMgr->m_WndWidth, vph = g_TwMgr->m_WndHeight; + if( !m_Contained ) + { + if( m_PosX+ContainedMargin>vpx+vpw ) + m_PosX = vpx+vpw-ContainedMargin; + if( m_PosX+m_Widthvpy+vph ) + m_PosY = vpy+vph-ContainedMargin; + if( m_PosY+m_Heightvpx+vpw ) + m_Width = vpx+vpw-m_PosX; + if( m_PosY 0) + m_ValuesWidth = int(m_ValuesWidthRatio * m_Width + 0.5); + ANT_SET_CURSOR(TopRight); + NotUpToDate(); + if( m_IsHelpBar ) + { + g_TwMgr->m_HelpBarNotUpToDate = true; + g_TwMgr->m_HelpBarUpdateNow = true; + } + g_TwMgr->m_KeyPressedBuildText = true; + g_TwMgr->m_InfoBuildText = true; + Handled = true; + m_DrawHandles = true; + } + else if( m_MouseDragResizeLL ) + { + int w = m_Width; + m_PosX += _X-m_MouseOriginX; + m_Width -= _X-m_MouseOriginX; + m_Height += _Y-m_MouseOriginY; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + int vpx = 0, vpy = 0, vpw = g_TwMgr->m_WndWidth, vph = g_TwMgr->m_WndHeight; + if( !m_Contained ) + { + if( m_PosX+ContainedMargin>vpx+vpw ) + m_PosX = vpx+vpw-ContainedMargin; + if( m_PosX+m_Widthvpy+vph ) + m_PosY = vpy+vph-ContainedMargin; + if( m_PosY+m_Heightvpy+vph ) + m_Height = vpy+vph-m_PosY; + if( m_PosX 0) + m_ValuesWidth = int(m_ValuesWidthRatio * m_Width + 0.5); + ANT_SET_CURSOR(BottomLeft); + NotUpToDate(); + if( m_IsHelpBar ) + { + g_TwMgr->m_HelpBarNotUpToDate = true; + g_TwMgr->m_HelpBarUpdateNow = true; + } + g_TwMgr->m_KeyPressedBuildText = true; + g_TwMgr->m_InfoBuildText = true; + Handled = true; + m_DrawHandles = true; + } + else if( m_MouseDragResizeLR ) + { + m_Width += _X-m_MouseOriginX; + m_Height += _Y-m_MouseOriginY; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + int vpx = 0, vpy = 0, vpw = g_TwMgr->m_WndWidth, vph = g_TwMgr->m_WndHeight; + if( !m_Contained ) + { + if( m_PosX+ContainedMargin>vpx+vpw ) + m_PosX = vpx+vpw-ContainedMargin; + if( m_PosX+m_Widthvpy+vph ) + m_PosY = vpy+vph-ContainedMargin; + if( m_PosY+m_Heightvpx+vpw ) + m_Width = vpx+vpw-m_PosX; + if( m_PosY+m_Height>vpy+vph ) + m_Height = vpy+vph-m_PosY; + } + if (m_ValuesWidthRatio > 0) + m_ValuesWidth = int(m_ValuesWidthRatio * m_Width + 0.5); + ANT_SET_CURSOR(BottomRight); + NotUpToDate(); + if( m_IsHelpBar ) + { + g_TwMgr->m_HelpBarNotUpToDate = true; + g_TwMgr->m_HelpBarUpdateNow = true; + } + g_TwMgr->m_KeyPressedBuildText = true; + g_TwMgr->m_InfoBuildText = true; + Handled = true; + m_DrawHandles = true; + } + else if( m_EditInPlace.m_Active ) + { + EditInPlaceMouseMove(_X, _Y, true); + ANT_SET_CURSOR(IBeam); + Handled = true; + } + //else if( InBar ) + // ANT_SET_CURSOR(Arrow); + } + } + else // minimized + { + if( m_Iconifiable && _X>=m_MinPosX+2 && _Xm_CharHeight && _Y>m_MinPosY && _Ym_CharHeight-2 ) + { + m_HighlightMaximize = true; + if( !m_IsHelpBar ) + ANT_SET_CURSOR(Arrow); + else + #ifdef ANT_WINDOWS + ANT_SET_CURSOR(Help); + #else + ANT_SET_CURSOR(Arrow); + #endif + Handled = true; + } + else + m_HighlightMaximize = false; + } + + // Handled by a custom widget? + CTwMgr::CStructProxy *currentCustomActiveStructProxy = NULL; + if( g_TwMgr!=NULL && (!Handled || CustomArea) && !m_IsMinimized && m_CustomRecords.size()>0 ) + { + bool CustomHandled = false; + for( int s=0; s<2; ++s ) // 2 iterations: first for custom widget having focus, second for others if no focused widget. + for( CustomMap::iterator it=m_CustomRecords.begin(); it!=m_CustomRecords.end(); ++it ) + { + CTwMgr::CStructProxy *sProxy = it->first; + const CCustomRecord& r = it->second; + if( (s==1 || sProxy->m_CustomCaptureFocus) && !CustomHandled && sProxy!=NULL && sProxy->m_CustomMouseMotionCallback!=NULL && r.m_XMin=r.m_Y0 && r.m_YMax<=r.m_Y1 ) + { + if( sProxy->m_CustomCaptureFocus || (_X>=r.m_XMin && _X=r.m_YMin && _Ym_CustomMouseMotionCallback(_X-r.m_XMin, _Y-r.m_Y0, r.m_XMax-r.m_XMin, r.m_Y1-r.m_Y0, sProxy->m_StructExtData, sProxy->m_StructClientData, this, r.m_Var); + currentCustomActiveStructProxy = sProxy; + s = 2; // force s-loop exit + } + } + else if( sProxy!=NULL ) + { + sProxy->m_CustomCaptureFocus = false; // force free focus, just in case. + ANT_SET_CURSOR(Arrow); + } + } + if( CustomHandled ) + Handled = true; + } + // If needed, send a 'MouseLeave' message to previously active custom struct + if( g_TwMgr!=NULL && m_CustomActiveStructProxy!=NULL && m_CustomActiveStructProxy!=currentCustomActiveStructProxy ) + { + bool found = false; + for( list::iterator it=g_TwMgr->m_StructProxies.begin(); it!=g_TwMgr->m_StructProxies.end() && !found; ++it ) + found = (&(*it)==m_CustomActiveStructProxy); + if( found && m_CustomActiveStructProxy->m_CustomMouseLeaveCallback!=NULL ) + m_CustomActiveStructProxy->m_CustomMouseLeaveCallback(m_CustomActiveStructProxy->m_StructExtData, m_CustomActiveStructProxy->m_StructClientData, this); + } + m_CustomActiveStructProxy = currentCustomActiveStructProxy; + + return Handled; +} + +// --------------------------------------------------------------------------- + +#ifdef ANT_WINDOWS +# pragma optimize("", off) +// disable optimizations because the conversion of Enum from unsigned int to double is not always exact if optimized and GraphAPI=DirectX ! +#endif +static void ANT_CALL PopupCallback(void *_ClientData) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr!=NULL && g_TwMgr->m_PopupBar!=NULL ) + { + unsigned int Enum = *(unsigned int *)&_ClientData; + CTwVarAtom *Var = g_TwMgr->m_PopupBar->m_VarEnumLinkedToPopupList; + CTwBar *Bar = g_TwMgr->m_PopupBar->m_BarLinkedToPopupList; + if( Bar!=NULL && Var!=NULL && !Var->m_ReadOnly && IsEnumType(Var->m_Type) ) + { + Var->ValueFromDouble(Enum); + //Bar->UnHighlightLine(); + Bar->HaveFocus(true); + Bar->NotUpToDate(); + } + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } +} +#ifdef ANT_WINDOWS +# pragma optimize("", on) +#endif + +// --------------------------------------------------------------------------- + +bool CTwBar::MouseButton(ETwMouseButtonID _Button, bool _Pressed, int _X, int _Y) +{ + assert(g_TwMgr->m_Graph && g_TwMgr->m_WndHeight>0 && g_TwMgr->m_WndWidth>0); + bool Handled = false; + if( !m_UpToDate ) + Update(); + bool EditInPlaceActive = false; + bool CustomArea = false; + + if( !m_IsMinimized ) + { + Handled = (_X>=m_PosX && _X=m_PosY && _Y=0 && m_HighlightedLine<(int)m_HierTags.size() && m_HierTags[m_HighlightedLine].m_Var ) + { + if( m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + if( _Pressed && !g_TwMgr->m_IsRepeatingMousePressed ) + { + CTwVarGroup *Grp = static_cast(m_HierTags[m_HighlightedLine].m_Var); + Grp->m_Open = !Grp->m_Open; + NotUpToDate(); + ANT_SET_CURSOR(Arrow); + } + } + else if( _Pressed && m_HighlightIncrBtn ) + { + static_cast(m_HierTags[m_HighlightedLine].m_Var)->Increment(1); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + NotUpToDate(); + } + else if( _Pressed && m_HighlightDecrBtn ) + { + static_cast(m_HierTags[m_HighlightedLine].m_Var)->Increment(-1); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + NotUpToDate(); + } + else if( _Pressed && !m_MouseDrag ) + { + m_MouseDrag = true; + m_MouseDragVar = true; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + m_VarHasBeenIncr = false; + CTwVarAtom * Var = static_cast(m_HierTags[m_HighlightedLine].m_Var); + if( !Var->m_NoSlider && !Var->m_ReadOnly && m_HighlightRotoBtn ) + { + // begin rotoslider + if( _X>m_PosX+m_VarX1 ) + RotoOnLButtonDown(m_PosX+m_VarX2-(1*IncrBtnWidth(m_Font->m_CharHeight))/2, _Y); + else + RotoOnLButtonDown(_X, _Y); + m_MouseDrag = true; + m_MouseDragVar = true; + } + else if( (Var->m_Type==TW_TYPE_BOOL8 || Var->m_Type==TW_TYPE_BOOL16 || Var->m_Type==TW_TYPE_BOOL32 || Var->m_Type==TW_TYPE_BOOLCPP) && !Var->m_ReadOnly ) + { + Var->Increment(1); + //m_HighlightClickBtn = true; + m_VarHasBeenIncr = true; + m_MouseDragVar = false; + m_MouseDrag = false; + NotUpToDate(); + } + else if( Var->m_Type==TW_TYPE_BUTTON && !Var->m_ReadOnly ) + { + m_HighlightClickBtn = true; + m_MouseDragVar = false; + m_MouseDrag = false; + } + //else if( (Var->m_Type==TW_TYPE_ENUM8 || Var->m_Type==TW_TYPE_ENUM16 || Var->m_Type==TW_TYPE_ENUM32) && !Var->m_ReadOnly ) + else if( IsEnumType(Var->m_Type) && !Var->m_ReadOnly && !g_TwMgr->m_IsRepeatingMousePressed ) + { + m_MouseDragVar = false; + m_MouseDrag = false; + if( g_TwMgr->m_PopupBar!=NULL ) + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + // popup list + CTwMgr::CEnum& e = g_TwMgr->m_Enums[Var->m_Type-TW_TYPE_ENUM_BASE]; + g_TwMgr->m_PopupBar = TwNewBar("~ Enum Popup ~"); + g_TwMgr->m_PopupBar->m_IsPopupList = true; + g_TwMgr->m_PopupBar->m_Color = m_Color; + g_TwMgr->m_PopupBar->m_DarkText = m_DarkText; + g_TwMgr->m_PopupBar->m_PosX = m_PosX + m_VarX1 - 2; + g_TwMgr->m_PopupBar->m_PosY = m_PosY + m_VarY0 + (m_HighlightedLine+1)*(m_Font->m_CharHeight+m_LineSep); + g_TwMgr->m_PopupBar->m_Width = m_Width - 2*m_Font->m_CharHeight; + g_TwMgr->m_PopupBar->m_LineSep = g_TwMgr->m_PopupBar->m_Sep; + int popHeight0 = (int)e.m_Entries.size()*(m_Font->m_CharHeight+m_Sep) + m_Font->m_CharHeight/2+2; + int popHeight = popHeight0; + if( g_TwMgr->m_PopupBar->m_PosY+popHeight+2 > g_TwMgr->m_WndHeight ) + popHeight = g_TwMgr->m_WndHeight-g_TwMgr->m_PopupBar->m_PosY-2; + if( popHeightm_WndHeight/2 ) + popHeight = min(popHeight0, g_TwMgr->m_WndHeight/2); + if( popHeight<3*(m_Font->m_CharHeight+m_Sep) ) + popHeight = 3*(m_Font->m_CharHeight+m_Sep); + g_TwMgr->m_PopupBar->m_Height = popHeight; + g_TwMgr->m_PopupBar->m_VarEnumLinkedToPopupList = Var; + g_TwMgr->m_PopupBar->m_BarLinkedToPopupList = this; + unsigned int CurrentEnumValue = (unsigned int)((int)Var->ValueToDouble()); + for( CTwMgr::CEnum::CEntries::iterator It=e.m_Entries.begin(); It!=e.m_Entries.end(); ++It ) + { + char ID[64]; + sprintf(ID, "%u", It->first); + //ultoa(It->first, ID, 10); + TwAddButton(g_TwMgr->m_PopupBar, ID, PopupCallback, *(void**)&(It->first), NULL); + CTwVar *Btn = g_TwMgr->m_PopupBar->Find(ID); + if( Btn!=NULL ) + { + Btn->m_Label = It->second.c_str(); + if( It->first==CurrentEnumValue ) + { + Btn->m_ColorPtr = &m_ColValTextNE; + Btn->m_BgColorPtr = &m_ColGrpBg; + } + } + } + g_TwMgr->m_HelpBarNotUpToDate = false; + } + else if( (Var->m_ReadOnly && (Var->m_Type==TW_TYPE_CDSTRING || Var->m_Type==TW_TYPE_CDSTDSTRING || Var->m_Type==TW_TYPE_STDSTRING || IsCSStringType(Var->m_Type)) && EditInPlaceAcceptVar(Var)) + || (!Var->m_ReadOnly && EditInPlaceAcceptVar(Var)) ) + { + int dw = 0; + //if( m_DrawIncrDecrBtn ) + // dw = 2*IncrBtnWidth(m_Font->m_CharHeight); + if( !m_EditInPlace.m_Active || m_EditInPlace.m_Var!=Var ) + { + EditInPlaceStart(Var, m_VarX1, m_VarY0+(m_HighlightedLine)*(m_Font->m_CharHeight+m_LineSep), m_VarX2-m_VarX1-dw-1); + if( EditInPlaceIsReadOnly() ) + EditInPlaceMouseMove(_X, _Y, false); + m_MouseDrag = false; + m_MouseDragVar = false; + } + else + { + EditInPlaceMouseMove(_X, _Y, false); + m_MouseDrag = true; + m_MouseDragVar = false; + } + EditInPlaceActive = m_EditInPlace.m_Active; + if( Var->m_ReadOnly ) + ANT_SET_CURSOR(No); + else + ANT_SET_CURSOR(IBeam); + } + else if( Var->m_ReadOnly ) + ANT_SET_CURSOR(No); + else + { + ANT_SET_CURSOR(Arrow); + CustomArea = true; + } + } + else if ( !_Pressed && m_MouseDragVar ) + { + m_MouseDrag = false; + m_MouseDragVar = false; + if( !Handled ) + m_DrawHandles = false; + Handled = true; + // end rotoslider + RotoOnLButtonUp(_X, _Y); + + /* Incr/decr on right or left click + if( !m_VarHasBeenIncr && !static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly ) + { + if( _Button==TW_MOUSE_LEFT ) + static_cast(m_HierTags[m_HighlightedLine].m_Var)->Increment(-1); + else if( _Button==TW_MOUSE_RIGHT ) + static_cast(m_HierTags[m_HighlightedLine].m_Var)->Increment(1); + NotUpToDate(); + } + */ + + if( static_cast(m_HierTags[m_HighlightedLine].m_Var)->m_ReadOnly ) + ANT_SET_CURSOR(No); + else + { + ANT_SET_CURSOR(Arrow); + CustomArea = true; + } + } + else if( !_Pressed && m_HighlightClickBtn ) // a button variable is activated + { + m_HighlightClickBtn = false; + m_MouseDragVar = false; + m_MouseDrag = false; + Handled = true; + NotUpToDate(); + if( !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + CTwVarAtom * Var = static_cast(m_HierTags[m_HighlightedLine].m_Var); + if( !Var->m_ReadOnly && Var->m_Type==TW_TYPE_BUTTON && Var->m_Val.m_Button.m_Callback!=NULL ) + { + Var->m_Val.m_Button.m_Callback(Var->m_ClientData); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + } + } + } + else if( !_Pressed ) + { + m_MouseDragVar = false; + m_MouseDrag = false; + CustomArea = true; + } + } + else if( _Pressed && !m_MouseDrag && m_Movable && !m_IsPopupList + && ( (_Button==TW_MOUSE_LEFT && _X>=m_PosX+2*m_Font->m_CharHeight && _Xm_CharHeight && _Y>=m_PosY && _Ym_CharHeight) + || (_Button==TW_MOUSE_MIDDLE && _X>=m_PosX && _X=m_PosY && _Y=m_PosX+m_VarX1-3 && _Xm_PosY+m_Font->m_CharHeight && _Y=m_PosX+m_VarX2+2 && _X=m_ScrollY0 && _Y=m_PosX+m_VarX2+2 && _X=m_PosY+m_VarY0 && _Y0 ) + { + --m_FirstLine; + NotUpToDate(); + } + } + else if( _Pressed && _Button==TW_MOUSE_LEFT && _X>=m_PosX+m_VarX2+2 && _X=m_ScrollY1 && _Y=m_PosX && _Xm_CharHeight && _Y>=m_PosY && _Ym_CharHeight ) + { + m_MouseDrag = true; + m_MouseDragResizeUL = true; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + m_ValuesWidthRatio = (m_Width>0) ? (double)m_ValuesWidth/m_Width : 0; + ANT_SET_CURSOR(TopLeft); + } + else if( !_Pressed && m_MouseDragResizeUL ) + { + m_MouseDrag = false; + m_MouseDragResizeUL = false; + ANT_SET_CURSOR(Arrow); + } + else if( _Pressed && !m_MouseDrag && m_Resizable && !m_IsPopupList && _Button==TW_MOUSE_LEFT && _X>=m_PosX+m_Width-m_Font->m_CharHeight && _X=m_PosY && _Ym_CharHeight ) + { + m_MouseDrag = true; + m_MouseDragResizeUR = true; + m_MouseOriginX = _X; + m_MouseOriginY = _Y; + m_ValuesWidthRatio = (m_Width>0) ? (double)m_ValuesWidth/m_Width : 0; + ANT_SET_CURSOR(TopRight); + } + else if( !_Pressed && m_MouseDragResizeUR ) + { + m_MouseDrag = false; + m_MouseDragResizeUR = false; + ANT_SET_CURSOR(Arrow); + } + else if( _Pressed && !m_MouseDrag && m_Resizable && !m_IsPopupList && _Button==TW_MOUSE_LEFT && _X>=m_PosX && _Xm_CharHeight && _Y>=m_PosY+m_Height-m_Font->m_CharHeight && _Y0) ? (double)m_ValuesWidth/m_Width : 0; + ANT_SET_CURSOR(BottomLeft); + } + else if( !_Pressed && m_MouseDragResizeLL ) + { + m_MouseDrag = false; + m_MouseDragResizeLL = false; + ANT_SET_CURSOR(Arrow); + } + else if( _Pressed && !m_MouseDrag && m_Resizable && !m_IsPopupList && _Button==TW_MOUSE_LEFT && _X>=m_PosX+m_Width-m_Font->m_CharHeight && _X=m_PosY+m_Height-m_Font->m_CharHeight && _Y0) ? (double)m_ValuesWidth/m_Width : 0; + ANT_SET_CURSOR(BottomRight); + } + else if( !_Pressed && m_MouseDragResizeLR ) + { + m_MouseDrag = false; + m_MouseDragResizeLR = false; + ANT_SET_CURSOR(Arrow); + } + else if( _Pressed && !m_IsPopupList && _Button==TW_MOUSE_LEFT && m_HighlightLabelsHeader ) + { + int w = ComputeLabelsWidth(m_Font); + if( wm_CharHeight ) + w = m_Font->m_CharHeight; + m_ValuesWidth = m_VarX2 - m_VarX0 - w; + if( m_ValuesWidthm_CharHeight ) + m_ValuesWidth = m_Font->m_CharHeight; + if( m_ValuesWidth>m_VarX2 - m_VarX0 ) + m_ValuesWidth = max(m_VarX2 - m_VarX0 - m_Font->m_CharHeight, 0); + NotUpToDate(); + ANT_SET_CURSOR(Arrow); + } + else if( _Pressed && !m_IsPopupList && _Button==TW_MOUSE_LEFT && m_HighlightValuesHeader ) + { + int w = ComputeValuesWidth(m_Font); + if( w<2*m_Font->m_CharHeight ) + w = 2*m_Font->m_CharHeight; // enough to draw a button + m_ValuesWidth = w; + if( m_ValuesWidth>m_VarX2 - m_VarX0 ) + m_ValuesWidth = max(m_VarX2 - m_VarX0 - m_Font->m_CharHeight, 0); + NotUpToDate(); + ANT_SET_CURSOR(Arrow); + } + else if( _Pressed && g_TwMgr->m_FontResizable && !m_IsPopupList && _X>=m_PosX+m_Font->m_CharHeight && _Xm_CharHeight && _Y>m_PosY && _Ym_CharHeight ) + { + // change font + if( _Button==TW_MOUSE_LEFT ) + { + if( m_Font==g_DefaultSmallFont ) + g_TwMgr->SetFont(g_DefaultNormalFont, true); + else if( m_Font==g_DefaultNormalFont ) + g_TwMgr->SetFont(g_DefaultLargeFont, true); + else if( m_Font==g_DefaultLargeFont ) + g_TwMgr->SetFont(g_DefaultSmallFont, true); + else + g_TwMgr->SetFont(g_DefaultNormalFont, true); + } + else if( _Button==TW_MOUSE_RIGHT ) + { + if( m_Font==g_DefaultSmallFont ) + g_TwMgr->SetFont(g_DefaultLargeFont, true); + else if( m_Font==g_DefaultNormalFont ) + g_TwMgr->SetFont(g_DefaultSmallFont, true); + else if( m_Font==g_DefaultLargeFont ) + g_TwMgr->SetFont(g_DefaultNormalFont, true); + else + g_TwMgr->SetFont(g_DefaultNormalFont, true); + } + + ANT_SET_CURSOR(Arrow); + } + else if( _Pressed && m_Iconifiable && !m_IsPopupList && _Button==TW_MOUSE_LEFT && _X>=m_PosX+m_Width-2*m_Font->m_CharHeight && _Xm_CharHeight && _Y>m_PosY && _Ym_CharHeight ) + { + // minimize + g_TwMgr->Minimize(this); + ANT_SET_CURSOR(Arrow); + } + else if( m_IsHelpBar && _Pressed && !g_TwMgr->m_IsRepeatingMousePressed && _X>=m_PosX+m_VarX0 && _Xm_CharHeight && _Y>m_PosY+m_Height-m_Font->m_CharHeight && _Y& null &", browser, WebPage); + if( system(cmd) ) {} // avoiding warn_unused_result + browser = strtok(NULL, ","); // grab the next browser + } + #elif defined ANT_OSX + char cmd[256]; + snprintf(cmd, sizeof(cmd), "open \"%s\" 1>& null &", WebPage); + if( system(cmd) ) {} // avoiding warn_unused_result + #endif + ANT_SET_CURSOR(Hand); + */ + } + else + { + CustomArea = true; + } + } + else // minimized + { + if( _Pressed && m_HighlightMaximize ) + { + m_HighlightMaximize = false; + g_TwMgr->Maximize(this); + ANT_SET_CURSOR(Arrow); + Handled = true; + } + } + + if( g_TwMgr!=NULL ) // Mgr might have been destroyed by the client inside a callback call + if( _Pressed && !EditInPlaceActive && m_EditInPlace.m_Active ) + EditInPlaceEnd(true); + + // Handled by a custom widget? + if( g_TwMgr!=NULL && (!Handled || CustomArea) && !m_IsMinimized && m_CustomRecords.size()>0 ) + { + bool CustomHandled = false; + for( int s=0; s<2; ++s ) // 2 iterations: first for custom widget having focus, second for others if no focused widget. + for( CustomMap::iterator it=m_CustomRecords.begin(); it!=m_CustomRecords.end(); ++it ) + { + CTwMgr::CStructProxy *sProxy = it->first; + const CCustomRecord& r = it->second; + if( (s==1 || sProxy->m_CustomCaptureFocus) && !CustomHandled && sProxy!=NULL && sProxy->m_CustomMouseButtonCallback!=NULL && r.m_XMin=r.m_Y0 && r.m_YMax<=r.m_Y1 ) + { + if( sProxy->m_CustomCaptureFocus || (_X>=r.m_XMin && _X=r.m_YMin && _Ym_CustomCaptureFocus = _Pressed; + CustomHandled = sProxy->m_CustomMouseButtonCallback(_Button, _Pressed, _X-r.m_XMin, _Y-r.m_Y0, r.m_XMax-r.m_XMin, r.m_Y1-r.m_Y0, sProxy->m_StructExtData, sProxy->m_StructClientData, this, r.m_Var); + s = 2; // force s-loop exit + } + } + else if( sProxy!=NULL ) + { + sProxy->m_CustomCaptureFocus = false; // force free focus, just in case. + ANT_SET_CURSOR(Arrow); + } + } + if( CustomHandled ) + Handled = true; + } + + return Handled; +} + + +// --------------------------------------------------------------------------- + +bool CTwBar::MouseWheel(int _Pos, int _PrevPos, int _MouseX, int _MouseY) +{ + assert(g_TwMgr->m_Graph && g_TwMgr->m_WndHeight>0 && g_TwMgr->m_WndWidth>0); + if( !m_UpToDate ) + Update(); + + bool Handled = false; + if( !m_IsMinimized && _MouseX>=m_PosX && _MouseX=m_PosY && _MouseY_PrevPos && m_FirstLine>0 ) + { + --m_FirstLine; + NotUpToDate(); + } + else if( _Pos<_PrevPos && m_FirstLine' ' && _Key<256 ) // don't test SHIFT if _Key is a common key + Mask &= ~TW_KMOD_SHIFT; + + // don't test KMOD_NUM and KMOD_CAPS modifiers coming from SDL + Mask &= ~(0x1000); // 0x1000 is the KMOD_NUM value defined in SDL_keysym.h + Mask &= ~(0x2000); // 0x2000 is the KMOD_CAPS value defined in SDL_keysym.h + + // complete partial modifiers comming from SDL + if( _Modifiers & TW_KMOD_SHIFT ) + _Modifiers |= TW_KMOD_SHIFT; + if( _Modifiers & TW_KMOD_CTRL ) + _Modifiers |= TW_KMOD_CTRL; + if( _Modifiers & TW_KMOD_ALT ) + _Modifiers |= TW_KMOD_ALT; + if( _Modifiers & TW_KMOD_META ) + _Modifiers |= TW_KMOD_META; + + for(size_t i=0; iIsGroup() ) + { + Atom = static_cast(m_Vars[i])->FindShortcut(_Key, _Modifiers, _DoIncr); + if( Atom!=NULL ) + return Atom; + } + else + { + Atom = static_cast(m_Vars[i]); + if( Atom->m_KeyIncr[0]==_Key && (Atom->m_KeyIncr[1]&Mask)==(_Modifiers&Mask) ) + { + if( _DoIncr!=NULL ) + *_DoIncr = true; + return Atom; + } + else if( Atom->m_KeyDecr[0]==_Key && (Atom->m_KeyDecr[1]&Mask)==(_Modifiers&Mask) ) + { + if( _DoIncr!=NULL ) + *_DoIncr = false; + return Atom; + } + } + } + return NULL; +} + +bool CTwBar::KeyPressed(int _Key, int _Modifiers) +{ + assert(g_TwMgr->m_Graph && g_TwMgr->m_WndHeight>0 && g_TwMgr->m_WndWidth>0); + bool Handled = false; + if( !m_UpToDate ) + Update(); + + if( _Key>0 && _Key0 && _Key<32 ) + _Key += 'a'-1; + + // PAD translation (for SDL keysym) + if( _Key>=256 && _Key<=272 ) // 256=SDLK_KP0 ... 272=SDLK_KP_EQUALS + { + bool Num = ((_Modifiers&TW_KMOD_SHIFT) && !(_Modifiers&0x1000)) || (!(_Modifiers&TW_KMOD_SHIFT) && (_Modifiers&0x1000)); // 0x1000 is SDL's KMOD_NUM + _Modifiers &= ~TW_KMOD_SHIFT; // remove shift modifier + if( _Key==266 ) // SDLK_KP_PERIOD + _Key = Num ? '.' : TW_KEY_DELETE; + else if( _Key==267 ) // SDLK_KP_DIVIDE + _Key = '/'; + else if( _Key==268 ) // SDLK_KP_MULTIPLY + _Key = '*'; + else if( _Key==269 ) // SDLK_KP_MINUS + _Key = '-'; + else if( _Key==270 ) // SDLK_KP_PLUS + _Key = '+'; + else if( _Key==271 ) // SDLK_KP_ENTER + _Key = TW_KEY_RETURN; + else if( _Key==272 ) // SDLK_KP_EQUALS + _Key = '='; + else if( Num ) // num SDLK_KP0..9 + _Key += '0' - 256; + else if( _Key==256 ) // non-num SDLK_KP01 + _Key = TW_KEY_INSERT; + else if( _Key==257 ) // non-num SDLK_KP1 + _Key = TW_KEY_END; + else if( _Key==258 ) // non-num SDLK_KP2 + _Key = TW_KEY_DOWN; + else if( _Key==259 ) // non-num SDLK_KP3 + _Key = TW_KEY_PAGE_DOWN; + else if( _Key==260 ) // non-num SDLK_KP4 + _Key = TW_KEY_LEFT; + else if( _Key==262 ) // non-num SDLK_KP6 + _Key = TW_KEY_RIGHT; + else if( _Key==263 ) // non-num SDLK_KP7 + _Key = TW_KEY_HOME; + else if( _Key==264 ) // non-num SDLK_KP8 + _Key = TW_KEY_UP; + else if( _Key==265 ) // non-num SDLK_KP9 + _Key = TW_KEY_PAGE_UP; + } + */ + + /* + string Str; + TwGetKeyString(&Str, _Key, _Modifiers); + printf("key: %d 0x%04xd %s\n", _Key, _Modifiers, Str.c_str()); + */ + + if( m_EditInPlace.m_Active ) + { + Handled = EditInPlaceKeyPressed(_Key, _Modifiers); + } + else + { + bool BarActive = (m_DrawHandles || m_IsPopupList) && !m_IsMinimized; + bool DoIncr = true; + CTwVarAtom *Atom = m_VarRoot.FindShortcut(_Key, _Modifiers, &DoIncr); + if( Atom!=NULL && Atom->m_Visible ) + { + if( !Atom->m_ReadOnly ) + { + Atom->Increment( DoIncr ? +1 : -1 ); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + m_HighlightClickBtnAuto = g_TwMgr->m_Timer.GetTime(); + } + NotUpToDate(); + Show(Atom); + Handled = true; + } + else if( BarActive && m_HighlightedLine>=0 && m_HighlightedLine<(int)m_HierTags.size() && m_HierTags[m_HighlightedLine].m_Var ) + { + if( _Key==TW_KEY_RIGHT ) + { + if( !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + CTwVarAtom *Atom = static_cast(m_HierTags[m_HighlightedLine].m_Var); + bool Accept = !Atom->m_NoSlider || Atom->m_Type==TW_TYPE_BUTTON + || Atom->m_Type==TW_TYPE_BOOL8 || Atom->m_Type==TW_TYPE_BOOL16 || Atom->m_Type==TW_TYPE_BOOL32 || Atom->m_Type==TW_TYPE_BOOLCPP + || IsEnumType(Atom->m_Type); + if( !Atom->IsReadOnly() && !m_IsPopupList && Accept ) + { + Atom->Increment(+1); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + m_HighlightClickBtnAuto = g_TwMgr->m_Timer.GetTime(); + NotUpToDate(); + } + } + else + { + CTwVarGroup *Grp = static_cast(m_HierTags[m_HighlightedLine].m_Var); + if( !Grp->m_Open ) + { + Grp->m_Open = true; + NotUpToDate(); + } + } + Handled = true; + } + else if( _Key==TW_KEY_LEFT ) + { + if( !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + CTwVarAtom *Atom = static_cast(m_HierTags[m_HighlightedLine].m_Var); + bool Accept = !Atom->m_NoSlider || Atom->m_Type==TW_TYPE_BUTTON + || Atom->m_Type==TW_TYPE_BOOL8 || Atom->m_Type==TW_TYPE_BOOL16 || Atom->m_Type==TW_TYPE_BOOL32 || Atom->m_Type==TW_TYPE_BOOLCPP + || IsEnumType(Atom->m_Type); + if( !Atom->IsReadOnly() && Accept && !m_IsPopupList ) + { + Atom->Increment(-1); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + m_HighlightClickBtnAuto = g_TwMgr->m_Timer.GetTime(); + NotUpToDate(); + } + } + else + { + CTwVarGroup *Grp = static_cast(m_HierTags[m_HighlightedLine].m_Var); + if( Grp->m_Open ) + { + Grp->m_Open = false; + NotUpToDate(); + } + } + Handled = true; + } + else if( _Key==TW_KEY_RETURN ) + { + if( !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + CTwVarAtom *Atom = static_cast(m_HierTags[m_HighlightedLine].m_Var); + if( !Atom->IsReadOnly() ) + { + if( Atom->m_Type==TW_TYPE_BUTTON || Atom->m_Type==TW_TYPE_BOOLCPP + || Atom->m_Type==TW_TYPE_BOOL8 || Atom->m_Type==TW_TYPE_BOOL16 || Atom->m_Type==TW_TYPE_BOOL32 ) + { + bool isPopup = m_IsPopupList; + Atom->Increment(+1); + if( g_TwMgr==NULL // Mgr might have been destroyed by the client inside a callback call + || isPopup ) // A popup destroys itself + return 1; + m_HighlightClickBtnAuto = g_TwMgr->m_Timer.GetTime(); + NotUpToDate(); + } + else // if( IsEnumType(Atom->m_Type) ) + { + // simulate a mouse click + int y = m_PosY + m_VarY0 + m_HighlightedLine*(m_Font->m_CharHeight+m_LineSep) + m_Font->m_CharHeight/2; + int x = m_PosX + m_VarX1 + 2; + if( x>m_PosX+m_VarX2-2 ) + x = m_PosX + m_VarX2 - 2; + MouseMotion(x, y); + MouseButton(TW_MOUSE_LEFT, true, x, y); + } + } + } + else + { + CTwVarGroup *Grp = static_cast(m_HierTags[m_HighlightedLine].m_Var); + Grp->m_Open = !Grp->m_Open; + NotUpToDate(); + } + Handled = true; + } + else if( _Key==TW_KEY_UP ) + { + --m_HighlightedLine; + if( m_HighlightedLine<0 ) + { + m_HighlightedLine = 0; + if( m_FirstLine>0 ) + { + --m_FirstLine; + NotUpToDate(); + } + } + m_HighlightedLineLastValid = m_HighlightedLine; + Handled = true; + } + else if( _Key==TW_KEY_DOWN ) + { + ++m_HighlightedLine; + if( m_HighlightedLine>=(int)m_HierTags.size() ) + { + m_HighlightedLine = (int)m_HierTags.size() - 1; + if( m_FirstLinem_PopupBar = NULL; + if( LinkedBar!=NULL ) + LinkedBar->m_DrawHandles = true; + return true; // this bar has been destroyed + } + } + else if( BarActive ) + { + if( _Key==TW_KEY_UP || _Key==TW_KEY_DOWN || _Key==TW_KEY_LEFT || _Key==TW_KEY_RIGHT || _Key==TW_KEY_RETURN ) + { + if( m_HighlightedLineLastValid>=0 && m_HighlightedLineLastValid<(int)m_HierTags.size() ) + m_HighlightedLine = m_HighlightedLineLastValid; + else if( m_HierTags.size()>0 ) + { + if( _Key==TW_KEY_UP ) + m_HighlightedLine = (int)m_HierTags.size()-1; + else + m_HighlightedLine = 0; + } + Handled = true; + } + else if( _Key==TW_KEY_ESCAPE && m_IsPopupList ) + { + Handled = true; + CTwBar *LinkedBar = m_BarLinkedToPopupList; + TwDeleteBar(this); + g_TwMgr->m_PopupBar = NULL; + if( LinkedBar!=NULL ) + LinkedBar->m_DrawHandles = true; + return true; // this bar has been destroyed + } + } + } + } + return Handled; +} + +// --------------------------------------------------------------------------- + +bool CTwBar::KeyTest(int _Key, int _Modifiers) +{ + assert(g_TwMgr->m_Graph && g_TwMgr->m_WndHeight>0 && g_TwMgr->m_WndWidth>0); + bool Handled = false; + if( !m_UpToDate ) + Update(); + + if( _Key>0 && _Keym_Visible ) + Handled = true; + else if( BarActive && ( _Key==TW_KEY_RIGHT || _Key==TW_KEY_LEFT || _Key==TW_KEY_UP || _Key==TW_KEY_DOWN + || _Key==TW_KEY_RETURN || (_Key==TW_KEY_ESCAPE && m_IsPopupList) ) ) + Handled = true; + } + } + return Handled; +} + +// --------------------------------------------------------------------------- + +bool CTwBar::Show(CTwVar *_Var) +{ + if( _Var==NULL || !_Var->m_Visible ) + return false; + if( !m_UpToDate ) + Update(); + + if( OpenHier(&m_VarRoot, _Var) ) + { + if( !m_UpToDate ) + Update(); + int l = LineInHier(&m_VarRoot, _Var); + if( l>=0 ) + { + int NbLines = (m_VarY1-m_VarY0+1)/(m_Font->m_CharHeight+m_LineSep); + if( NbLines<= 0 ) + NbLines = 1; + if( l=m_FirstLine+NbLines ) + { + m_FirstLine = l-NbLines/2; + if( m_FirstLine<0 ) + m_FirstLine = 0; + NotUpToDate(); + Update(); + if( m_NbDisplayedLinesm_Vars.size(); ++i) + if( _Root->m_Vars[i]!=NULL ) + { + if( _Var==_Root->m_Vars[i] + || (_Root->m_Vars[i]->IsGroup() && OpenHier(static_cast(_Root->m_Vars[i]), _Var)) ) + { + _Root->m_Open = true; + NotUpToDate(); + return true; + } + } + return false; +} + +// --------------------------------------------------------------------------- + +int CTwBar::LineInHier(CTwVarGroup *_Root, CTwVar *_Var) +{ + assert( _Root!=NULL ); + int l = 0; + for(size_t i=0; i<_Root->m_Vars.size(); ++i) + if( _Root->m_Vars[i]!=NULL && _Root->m_Vars[i]->m_Visible ) + { + if( _Var==_Root->m_Vars[i] ) + return l; + else if( _Root->m_Vars[i]->IsGroup() && static_cast(_Root->m_Vars[i])->m_Open ) + { + ++l; + int ll = LineInHier(static_cast(_Root->m_Vars[i]), _Var); + if( ll>=0 ) + return l+ll; + else + l += -ll-2; + } + ++l; + } + return -l-1; +} + +// --------------------------------------------------------------------------- + +void DrawArc(int _X, int _Y, int _Radius, float _StartAngleDeg, float _EndAngleDeg, color32 _Color) // angles in degree +{ + ITwGraph *Gr = g_TwMgr->m_Graph; + if( Gr==NULL || !Gr->IsDrawing() || _Radius==0 || _StartAngleDeg==_EndAngleDeg ) + return; + + float startAngle = (float)M_PI*_StartAngleDeg/180; + float endAngle = (float)M_PI*_EndAngleDeg/180; + //float stepAngle = 8/(float)_Radius; // segment length = 8 pixels + float stepAngle = 4/(float)_Radius; // segment length = 4 pixels + if( stepAngle>(float)M_PI/4 ) + stepAngle = (float)M_PI/4; + bool fullCircle = fabsf(endAngle-startAngle)>=2.0f*(float)M_PI+fabsf(stepAngle); + int numSteps; + if( fullCircle ) + { + numSteps = int((2.0f*(float)M_PI)/stepAngle); + startAngle = 0; + endAngle = 2.0f*(float)M_PI; + } + else + numSteps = int(fabsf(endAngle-startAngle)/stepAngle); + if( startAngle>endAngle ) + stepAngle = -stepAngle; + + int x0 = int(_X + _Radius * cosf(startAngle) + 0.5f); + int y0 = int(_Y - _Radius * sinf(startAngle) + 0.5f); + int x1, y1; + float angle = startAngle+stepAngle; + + for( int i=0; iDrawLine(x0, y0, x1, y1, _Color, true); + x0 = x1; + y0 = y1; + } + + if( fullCircle ) + { + x1 = int(_X + _Radius * cosf(startAngle) + 0.5f); + y1 = int(_Y - _Radius * sinf(startAngle) + 0.5f); + } + else + { + x1 = int(_X + _Radius * cosf(endAngle) + 0.5f); + y1 = int(_Y - _Radius * sinf(endAngle) + 0.5f); + } + Gr->DrawLine(x0, y0, x1, y1, _Color, true); +} + +// --------------------------------------------------------------------------- + +CTwBar::CRotoSlider::CRotoSlider() +{ + m_Var = NULL; + m_Active = false; + m_ActiveMiddle = false; + m_Subdiv = 256; // will be recalculated in RotoOnLButtonDown +} + +void CTwBar::RotoDraw() +{ + ITwGraph *Gr = g_TwMgr->m_Graph; + if( Gr==NULL || !Gr->IsDrawing() ) + return; + + if( m_Roto.m_Active ) + { + DrawArc(m_Roto.m_Origin.x, m_Roto.m_Origin.y, 32, 0, 360, m_ColRoto); + DrawArc(m_Roto.m_Origin.x+1, m_Roto.m_Origin.y, 32, 0, 360, m_ColRoto); + DrawArc(m_Roto.m_Origin.x, m_Roto.m_Origin.y+1, 32, 0, 360, m_ColRoto); + + if( m_Roto.m_HasPrevious ) + { + double varMax = RotoGetMax(); + double varMin = RotoGetMin(); + double varStep = RotoGetStep(); + if( varMax-DOUBLE_MAX && fabs(varStep)>DOUBLE_EPS && m_Roto.m_Subdiv>0 ) + { + double dtMax = 360.0*(varMax-m_Roto.m_ValueAngle0)/((double)m_Roto.m_Subdiv*varStep);//+2; + double dtMin = 360.0*(varMin-m_Roto.m_ValueAngle0)/((double)m_Roto.m_Subdiv*varStep);//-2; + + if( dtMax>=0 && dtMax<360 && dtMin<=0 && dtMin>-360 && fabs(dtMax-dtMin)<=360 ) + { + int x1, y1, x2, y2; + double da = 2.0*M_PI/m_Roto.m_Subdiv; + + x1 = m_Roto.m_Origin.x + (int)(40*cos(-M_PI*(m_Roto.m_Angle0+dtMax)/180-da)); + y1 = m_Roto.m_Origin.y + (int)(40*sin(-M_PI*(m_Roto.m_Angle0+dtMax)/180-da)+0.5); + x2 = m_Roto.m_Origin.x + (int)(40*cos(-M_PI*(m_Roto.m_Angle0+dtMax-10)/180-da)); + y2 = m_Roto.m_Origin.y + (int)(40*sin(-M_PI*(m_Roto.m_Angle0+dtMax-10)/180-da)+0.5); + Gr->DrawLine(m_Roto.m_Origin.x, m_Roto.m_Origin.y, x1, y1, m_ColRotoBound, true); + Gr->DrawLine(m_Roto.m_Origin.x+1, m_Roto.m_Origin.y, x1+1, y1, m_ColRotoBound, true); + Gr->DrawLine(m_Roto.m_Origin.x, m_Roto.m_Origin.y+1, x1, y1+1, m_ColRotoBound, true); + Gr->DrawLine(x1, y1, x2, y2, m_ColRotoBound, true); + Gr->DrawLine(x1+1, y1, x2+1, y2, m_ColRotoBound, true); + Gr->DrawLine(x1, y1+1, x2, y2+1, m_ColRotoBound, true); + + x1 = m_Roto.m_Origin.x + (int)(40*cos(-M_PI*(m_Roto.m_Angle0+dtMin)/180+da)); + y1 = m_Roto.m_Origin.y + (int)(40*sin(-M_PI*(m_Roto.m_Angle0+dtMin)/180+da)+0.5); + x2 = m_Roto.m_Origin.x + (int)(40*cos(-M_PI*(m_Roto.m_Angle0+dtMin+10)/180+da)); + y2 = m_Roto.m_Origin.y + (int)(40*sin(-M_PI*(m_Roto.m_Angle0+dtMin+10)/180+da)+0.5); + Gr->DrawLine(m_Roto.m_Origin.x, m_Roto.m_Origin.y, x1, y1, m_ColRotoBound, true); + Gr->DrawLine(m_Roto.m_Origin.x+1, m_Roto.m_Origin.y, x1+1, y1, m_ColRotoBound, true); + Gr->DrawLine(m_Roto.m_Origin.x, m_Roto.m_Origin.y+1, x1, y1+1, m_ColRotoBound, true); + Gr->DrawLine(x1, y1, x2, y2, m_ColRotoBound, true); + Gr->DrawLine(x1+1, y1, x2+1, y2, m_ColRotoBound, true); + Gr->DrawLine(x1, y1+1, x2, y2+1, m_ColRotoBound, true); + } + } + } + + Gr->DrawLine(m_Roto.m_Origin.x+1, m_Roto.m_Origin.y, m_Roto.m_Current.x+1, m_Roto.m_Current.y, m_ColRotoVal, true); + Gr->DrawLine(m_Roto.m_Origin.x, m_Roto.m_Origin.y+1, m_Roto.m_Current.x, m_Roto.m_Current.y+1, m_ColRotoVal, true); + Gr->DrawLine(m_Roto.m_Origin.x, m_Roto.m_Origin.y, m_Roto.m_Current.x, m_Roto.m_Current.y, m_ColRotoVal, true); + + if( fabs(m_Roto.m_AngleDT)>=1 ) + { + DrawArc(m_Roto.m_Origin.x, m_Roto.m_Origin.y, 32, float(m_Roto.m_Angle0), float(m_Roto.m_Angle0+m_Roto.m_AngleDT-1), m_ColRotoVal); + DrawArc(m_Roto.m_Origin.x+1, m_Roto.m_Origin.y, 32, float(m_Roto.m_Angle0), float(m_Roto.m_Angle0+m_Roto.m_AngleDT-1), m_ColRotoVal); + DrawArc(m_Roto.m_Origin.x, m_Roto.m_Origin.y+1, 32, float(m_Roto.m_Angle0), float(m_Roto.m_Angle0+m_Roto.m_AngleDT-1), m_ColRotoVal); + } + } +} + +double CTwBar::RotoGetValue() const +{ + assert(m_Roto.m_Var!=NULL); + return m_Roto.m_Var->ValueToDouble(); +} + +void CTwBar::RotoSetValue(double _Val) +{ + assert(m_Roto.m_Var!=NULL); + if( _Val!=m_Roto.m_CurrentValue ) + { + m_Roto.m_CurrentValue = _Val; + m_Roto.m_Var->ValueFromDouble(_Val); + NotUpToDate(); + } +} + +double CTwBar::RotoGetMin() const +{ + assert(m_Roto.m_Var!=NULL); + double min = -DOUBLE_MAX; + m_Roto.m_Var->MinMaxStepToDouble(&min, NULL, NULL); + return min; +} + +double CTwBar::RotoGetMax() const +{ + assert(m_Roto.m_Var!=NULL); + double max = DOUBLE_MAX; + m_Roto.m_Var->MinMaxStepToDouble(NULL, &max, NULL); + return max; +} + +double CTwBar::RotoGetStep() const +{ + assert(m_Roto.m_Var!=NULL); + double step = 1; + m_Roto.m_Var->MinMaxStepToDouble(NULL, NULL, &step); + return step; +} + +double CTwBar::RotoGetSteppedValue() const +{ + double d = m_Roto.m_PreciseValue-m_Roto.m_Value0; + double n = int(d/RotoGetStep()); + return m_Roto.m_Value0 + RotoGetStep()*n; +} + +void CTwBar::RotoOnMouseMove(int _X, int _Y) +{ + CPoint p(_X, _Y); + if( m_Roto.m_Active ) + { + m_Roto.m_Current = p; + RotoSetValue(RotoGetSteppedValue()); + //DrawManip(); + + int ti = -1; + double t = 0; + float r = sqrtf(float( (m_Roto.m_Current.x-m_Roto.m_Origin.x)*(m_Roto.m_Current.x-m_Roto.m_Origin.x) + + (m_Roto.m_Current.y-m_Roto.m_Origin.y)*(m_Roto.m_Current.y-m_Roto.m_Origin.y))); + if( r>m_RotoMinRadius ) + { + t = - atan2(double(m_Roto.m_Current.y-m_Roto.m_Origin.y), double(m_Roto.m_Current.x-m_Roto.m_Origin.x)); + ti = (int((t/(2.0*M_PI)+1.0)*NB_ROTO_CURSORS+0.5)) % NB_ROTO_CURSORS; + if( m_Roto.m_HasPrevious ) + { + CPoint v0 = m_Roto.m_Previous-m_Roto.m_Origin; + CPoint v1 = m_Roto.m_Current-m_Roto.m_Origin; + double l0 = sqrt(double(v0.x*v0.x+v0.y*v0.y)); + double l1 = sqrt(double(v1.x*v1.x+v1.y*v1.y)); + double dt = acos(max(-1+1.0e-30,min(1-1.0e-30,double(v0.x*v1.x+v0.y*v1.y)/(l0*l1)))); + if( v0.x*v1.y-v0.y*v1.x>0 ) + dt = - dt; + double preciseInc = double(m_Roto.m_Subdiv) * dt/(2.0*M_PI) * RotoGetStep(); + if( preciseInc>RotoGetStep() || preciseInc<-RotoGetStep() ) + { + m_Roto.m_PreciseValue += preciseInc; + if( m_Roto.m_PreciseValue>RotoGetMax() ) + { + m_Roto.m_PreciseValue = RotoGetMax(); + m_Roto.m_Value0 = RotoGetMax(); + + double da = 360*(RotoGetMax()-m_Roto.m_ValueAngle0)/(double(m_Roto.m_Subdiv)*RotoGetStep()); + m_Roto.m_Angle0 = ((int((t/(2.0*M_PI)+1.0)*360.0+0.5)) % 360) - da; + m_Roto.m_AngleDT = da; + } + else if( m_Roto.m_PreciseValue=0 && ti=0 && m_HighlightedLine<(int)m_HierTags.size() && m_HierTags[m_HighlightedLine].m_Var && !m_HierTags[m_HighlightedLine].m_Var->IsGroup() ) + { + m_Roto.m_Var = static_cast(m_HierTags[m_HighlightedLine].m_Var); + int y = m_PosY + m_VarY0 + m_HighlightedLine*(m_Font->m_CharHeight+m_LineSep) + m_Font->m_CharHeight/2; + m_Roto.m_Origin = CPoint(p.x, y); //r.CenterPoint().y); + m_Roto.m_Current = p; + m_Roto.m_Active = true; + m_Roto.m_HasPrevious = false; + m_Roto.m_Angle0 = 0; + m_Roto.m_AngleDT = 0; + //SetCapture(); + + m_Roto.m_Value0 = RotoGetValue(); + m_Roto.m_CurrentValue = m_Roto.m_Value0; + m_Roto.m_ValueAngle0 = m_Roto.m_Value0; + m_Roto.m_PreciseValue = m_Roto.m_Value0; + //RotoSetValue(RotoGetSteppedValue()); Not here + //DrawManip(); + + m_Roto.m_Subdiv = m_RotoNbSubdiv; + // re-adjust m_Subdiv if needed: + double min=-DOUBLE_MAX, max=DOUBLE_MAX, step=1; + m_Roto.m_Var->MinMaxStepToDouble(&min, &max, &step); + if( fabs(step)>0 && min>-DOUBLE_MAX && maxm_Graph!=NULL ); + + m_Var = NULL; + m_Active = false; + m_EditTextObj = g_TwMgr->m_Graph->NewTextObj(); + m_EditSelTextObj = g_TwMgr->m_Graph->NewTextObj(); + + m_X = m_Y = m_Width = 0; +} + +CTwBar::CEditInPlace::~CEditInPlace() +{ + assert( g_TwMgr!=NULL && g_TwMgr->m_Graph!=NULL ); + + if( m_EditTextObj ) + g_TwMgr->m_Graph->DeleteTextObj(m_EditTextObj); + if( m_EditSelTextObj ) + g_TwMgr->m_Graph->DeleteTextObj(m_EditSelTextObj); +} + +bool CTwBar::EditInPlaceIsReadOnly() +{ + if( m_EditInPlace.m_Var==NULL ) + return true; + else if( m_EditInPlace.m_Var->m_ReadOnly ) + return true; + else if( m_EditInPlace.m_Var->m_Type==TW_TYPE_CDSTRING && ((m_EditInPlace.m_Var->m_Ptr==NULL && m_EditInPlace.m_Var->m_SetCallback==NULL) || (m_EditInPlace.m_Var->m_Ptr!=NULL && g_TwMgr->m_CopyCDStringToClient==NULL)) ) + return true; + else if( m_EditInPlace.m_Var->m_Type==TW_TYPE_CDSTDSTRING && m_EditInPlace.m_Var->m_SetCallback==NULL ) + return true; + else if( m_EditInPlace.m_Var->m_Type==TW_TYPE_STDSTRING && ((m_EditInPlace.m_Var->m_Ptr==NULL && m_EditInPlace.m_Var->m_SetCallback==NULL) || (m_EditInPlace.m_Var->m_Ptr!=NULL && g_TwMgr->m_CopyStdStringToClient==NULL)) ) + return true; + else + return false; +} + +void CTwBar::EditInPlaceDraw() +{ + if( !m_EditInPlace.m_Active || m_EditInPlace.m_Var==NULL || m_EditInPlace.m_Width<=0 ) + return; + + // adjust m_FirstChar to see the caret, and extract the visible sub-string + int i, StringLen = (int)m_EditInPlace.m_String.length(); + if( m_EditInPlace.m_FirstChar>m_EditInPlace.m_CaretPos ) + m_EditInPlace.m_FirstChar = m_EditInPlace.m_CaretPos; + int SubstrWidth = 0; + for( i=min(m_EditInPlace.m_CaretPos, StringLen-1); i>=0 && SubstrWidthm_CharWidth[u]; + } + int FirstChar = max(0, i); + if( SubstrWidth>=m_EditInPlace.m_Width ) + FirstChar += 2; + if( m_EditInPlace.m_FirstChar0 ) + --m_EditInPlace.m_FirstChar; + SubstrWidth = 0; + for( i=m_EditInPlace.m_FirstChar; im_CharWidth[u]; + } + int LastChar = i; + if( SubstrWidth>=m_EditInPlace.m_Width ) + --LastChar; + string Substr = m_EditInPlace.m_String.substr( m_EditInPlace.m_FirstChar, LastChar-m_EditInPlace.m_FirstChar ); + + // compute caret x pos + int CaretX = m_PosX + m_EditInPlace.m_X; + for( i=m_EditInPlace.m_FirstChar; im_CharWidth[u]; + } + + // draw edit text + color32 ColText = EditInPlaceIsReadOnly() ? m_ColValTextRO : m_ColEditText; + color32 ColBg = EditInPlaceIsReadOnly() ? m_ColValBg : m_ColEditBg; + g_TwMgr->m_Graph->BuildText(m_EditInPlace.m_EditTextObj, &Substr, NULL, NULL, 1, m_Font, 0, m_EditInPlace.m_Width); + g_TwMgr->m_Graph->DrawText(m_EditInPlace.m_EditTextObj, m_PosX+m_EditInPlace.m_X, m_PosY+m_EditInPlace.m_Y, ColText, ColBg); + + // draw selected text + string StrSelected = ""; + if( m_EditInPlace.m_CaretPos>m_EditInPlace.m_SelectionStart ) + { + int FirstSel = max(m_EditInPlace.m_SelectionStart, m_EditInPlace.m_FirstChar); + int LastSel = min(m_EditInPlace.m_CaretPos, LastChar); + StrSelected = m_EditInPlace.m_String.substr( FirstSel, LastSel-FirstSel ); + } + else + { + int FirstSel = max(m_EditInPlace.m_CaretPos, m_EditInPlace.m_FirstChar); + int LastSel = min(m_EditInPlace.m_SelectionStart, LastChar); + StrSelected = m_EditInPlace.m_String.substr( FirstSel, LastSel-FirstSel ); + } + int SelWidth = 0; + for( i=0; i<(int)StrSelected.length(); ++i ) + { + unsigned char u = StrSelected.c_str()[i]; + SelWidth += m_Font->m_CharWidth[u]; + } + if( SelWidth>0 && StrSelected.length()>0 ) + { + color32 ColSelBg = EditInPlaceIsReadOnly() ? m_ColValTextRO : m_ColEditSelBg; + g_TwMgr->m_Graph->BuildText(m_EditInPlace.m_EditSelTextObj, &StrSelected, NULL, NULL, 1, m_Font, 0, SelWidth); + if ( m_EditInPlace.m_CaretPos>m_EditInPlace.m_SelectionStart ) + g_TwMgr->m_Graph->DrawText(m_EditInPlace.m_EditSelTextObj, CaretX-SelWidth, m_PosY+m_EditInPlace.m_Y, m_ColEditSelText, ColSelBg); + else + g_TwMgr->m_Graph->DrawText(m_EditInPlace.m_EditSelTextObj, CaretX, m_PosY+m_EditInPlace.m_Y, m_ColEditSelText, ColSelBg); + } + + // draw caret + if( CaretX<=m_PosX+m_EditInPlace.m_X+m_EditInPlace.m_Width ) + g_TwMgr->m_Graph->DrawLine( CaretX, m_PosY+m_EditInPlace.m_Y+1, CaretX, m_PosY+m_EditInPlace.m_Y+m_Font->m_CharHeight, m_ColEditText ); +} + +bool CTwBar::EditInPlaceAcceptVar(const CTwVarAtom* _Var) +{ + if( _Var==NULL ) + return false; + if( _Var->m_Type>=TW_TYPE_CHAR && _Var->m_Type<=TW_TYPE_DOUBLE ) + return true; + if( _Var->m_Type==TW_TYPE_CDSTRING || _Var->m_Type==TW_TYPE_CDSTDSTRING || _Var->m_Type==TW_TYPE_STDSTRING ) + return true; + if( IsCSStringType(_Var->m_Type) ) + return true; + + return false; +} + +void CTwBar::EditInPlaceStart(CTwVarAtom* _Var, int _X, int _Y, int _Width) +{ + if( m_EditInPlace.m_Active ) + EditInPlaceEnd(true); + + m_EditInPlace.m_Active = true; + m_EditInPlace.m_Var = _Var; + m_EditInPlace.m_X = _X; + m_EditInPlace.m_Y = _Y; + m_EditInPlace.m_Width = _Width; + m_EditInPlace.m_Var->ValueToString(&m_EditInPlace.m_String); + if( m_EditInPlace.m_Var->m_Type==TW_TYPE_CHAR ) + m_EditInPlace.m_String = m_EditInPlace.m_String.substr(0, 1); + m_EditInPlace.m_CaretPos = (int)m_EditInPlace.m_String.length(); + if( EditInPlaceIsReadOnly() ) + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + else + m_EditInPlace.m_SelectionStart = 0; + m_EditInPlace.m_FirstChar = 0; +} + +void CTwBar::EditInPlaceEnd(bool _Commit) +{ + if( _Commit && m_EditInPlace.m_Active && m_EditInPlace.m_Var!=NULL ) + { + if( m_EditInPlace.m_Var->m_Type==TW_TYPE_CDSTRING || m_EditInPlace.m_Var->m_Type==TW_TYPE_CDSTDSTRING ) + { + if( m_EditInPlace.m_Var->m_SetCallback!=NULL ) + { + const char *String = m_EditInPlace.m_String.c_str(); + m_EditInPlace.m_Var->m_SetCallback(&String, m_EditInPlace.m_Var->m_ClientData); + } + else if( m_EditInPlace.m_Var->m_Type!=TW_TYPE_CDSTDSTRING ) + { + char **StringPtr = (char **)m_EditInPlace.m_Var->m_Ptr; + if( StringPtr!=NULL && g_TwMgr->m_CopyCDStringToClient!=NULL ) + g_TwMgr->m_CopyCDStringToClient(StringPtr, m_EditInPlace.m_String.c_str()); + } + } + else if( m_EditInPlace.m_Var->m_Type==TW_TYPE_STDSTRING ) + { + // this case should never happened: TW_TYPE_STDSTRING are converted to TW_TYPE_CDSTDSTRING by TwAddVar + if( m_EditInPlace.m_Var->m_SetCallback!=NULL ) + m_EditInPlace.m_Var->m_SetCallback(&(m_EditInPlace.m_String), m_EditInPlace.m_Var->m_ClientData); + else + { + string *StringPtr = (string *)m_EditInPlace.m_Var->m_Ptr; + if( StringPtr!=NULL && g_TwMgr->m_CopyStdStringToClient!=NULL ) + g_TwMgr->m_CopyStdStringToClient(*StringPtr, m_EditInPlace.m_String); + } + } + else if( IsCSStringType(m_EditInPlace.m_Var->m_Type) ) + { + int n = TW_CSSTRING_SIZE(m_EditInPlace.m_Var->m_Type); + if( n>0 ) + { + if( (int)m_EditInPlace.m_String.length()>n-1 ) + m_EditInPlace.m_String.resize(n-1); + if( m_EditInPlace.m_Var->m_SetCallback!=NULL ) + m_EditInPlace.m_Var->m_SetCallback(m_EditInPlace.m_String.c_str(), m_EditInPlace.m_Var->m_ClientData); + else if( m_EditInPlace.m_Var->m_Ptr!=NULL ) + { + if( n>1 ) + strncpy((char *)m_EditInPlace.m_Var->m_Ptr, m_EditInPlace.m_String.c_str(), n-1); + ((char *)m_EditInPlace.m_Var->m_Ptr)[n-1] = '\0'; + } + } + } + else + { + double Val = 0, Min = 0, Max = 0, Step = 0; + int n = 0; + if( m_EditInPlace.m_Var->m_Type==TW_TYPE_CHAR ) + { + unsigned char Char = 0; + n = sscanf(m_EditInPlace.m_String.c_str(), "%c", &Char); + Val = Char; + } + else + n = sscanf(m_EditInPlace.m_String.c_str(), "%lf", &Val); + if( n==1 ) + { + m_EditInPlace.m_Var->MinMaxStepToDouble(&Min, &Max, &Step); + if( ValMax ) + Val = Max; + m_EditInPlace.m_Var->ValueFromDouble(Val); + } + } + if( g_TwMgr!=NULL ) // Mgr might have been destroyed by the client inside a callback call + NotUpToDate(); + } + m_EditInPlace.m_Active = false; + m_EditInPlace.m_Var = NULL; +} + +bool CTwBar::EditInPlaceKeyPressed(int _Key, int _Modifiers) +{ + if( !m_EditInPlace.m_Active ) + return false; + bool Handled = true; // if EditInPlace is active, it catches all key events + bool DoCopy = false, DoPaste = false; + + switch( _Key ) + { + case TW_KEY_ESCAPE: + EditInPlaceEnd(false); + break; + case TW_KEY_RETURN: + EditInPlaceEnd(true); + break; + case TW_KEY_LEFT: + if( _Modifiers==TW_KMOD_SHIFT ) + m_EditInPlace.m_CaretPos = max(0, m_EditInPlace.m_CaretPos-1); + else + { + if( m_EditInPlace.m_SelectionStart!=m_EditInPlace.m_CaretPos ) + m_EditInPlace.m_CaretPos = min(m_EditInPlace.m_SelectionStart, m_EditInPlace.m_CaretPos); + else + m_EditInPlace.m_CaretPos = max(0, m_EditInPlace.m_CaretPos-1); + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + } + break; + case TW_KEY_RIGHT: + if( _Modifiers==TW_KMOD_SHIFT ) + m_EditInPlace.m_CaretPos = min((int)m_EditInPlace.m_String.length(), m_EditInPlace.m_CaretPos+1); + else + { + if( m_EditInPlace.m_SelectionStart!=m_EditInPlace.m_CaretPos ) + m_EditInPlace.m_CaretPos = max(m_EditInPlace.m_SelectionStart, m_EditInPlace.m_CaretPos); + else + m_EditInPlace.m_CaretPos = min((int)m_EditInPlace.m_String.length(), m_EditInPlace.m_CaretPos+1); + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + } + break; + case TW_KEY_BACKSPACE: + if( !EditInPlaceIsReadOnly() ) + { + if( m_EditInPlace.m_SelectionStart==m_EditInPlace.m_CaretPos ) + m_EditInPlace.m_SelectionStart = max(0, m_EditInPlace.m_CaretPos-1); + EditInPlaceEraseSelect(); + } + break; + case TW_KEY_DELETE: + if( !EditInPlaceIsReadOnly() ) + { + if( m_EditInPlace.m_SelectionStart==m_EditInPlace.m_CaretPos ) + m_EditInPlace.m_SelectionStart = min(m_EditInPlace.m_CaretPos+1, (int)m_EditInPlace.m_String.length()); + EditInPlaceEraseSelect(); + } + break; + case TW_KEY_HOME: + m_EditInPlace.m_CaretPos = 0; + if( _Modifiers!=TW_KMOD_SHIFT ) + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + break; + case TW_KEY_END: + m_EditInPlace.m_CaretPos = (int)m_EditInPlace.m_String.length(); + if( _Modifiers!=TW_KMOD_SHIFT ) + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + break; + case TW_KEY_INSERT: + if( _Modifiers==TW_KMOD_CTRL ) + DoCopy = true; + else if( _Modifiers==TW_KMOD_SHIFT ) + DoPaste = true; + break; + default: + if( _Modifiers==TW_KMOD_CTRL ) + { + if( _Key=='c' || _Key=='C' ) + DoCopy = true; + else if( _Key=='v' || _Key=='V' ) + DoPaste = true; + } + else if( _Key>=32 && _Key<=255 ) + { + if( !EditInPlaceIsReadOnly() && m_EditInPlace.m_CaretPos>=0 && m_EditInPlace.m_CaretPos<=(int)m_EditInPlace.m_String.length() ) + { + if( m_EditInPlace.m_SelectionStart!=m_EditInPlace.m_CaretPos ) + EditInPlaceEraseSelect(); + string Str(1, (char)_Key); + m_EditInPlace.m_String.insert(m_EditInPlace.m_CaretPos, Str); + ++m_EditInPlace.m_CaretPos; + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + } + } + } + + if( DoPaste && !EditInPlaceIsReadOnly() ) + { + if( m_EditInPlace.m_SelectionStart!=m_EditInPlace.m_CaretPos ) + EditInPlaceEraseSelect(); + string Str = ""; + if( EditInPlaceGetClipboard(&Str) && Str.length()>0 ) + { + m_EditInPlace.m_String.insert(m_EditInPlace.m_CaretPos, Str); + m_EditInPlace.m_CaretPos += (int)Str.length(); + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + } + } + if( DoCopy ) + { + string Str = ""; + if( m_EditInPlace.m_CaretPos>m_EditInPlace.m_SelectionStart ) + Str = m_EditInPlace.m_String.substr(m_EditInPlace.m_SelectionStart, m_EditInPlace.m_CaretPos-m_EditInPlace.m_SelectionStart); + else if( m_EditInPlace.m_CaretPosPosMin ) + m_EditInPlace.m_FirstChar = PosMin; + return true; + } + else + return false; +} + + +bool CTwBar::EditInPlaceMouseMove(int _X, int _Y, bool _Select) +{ + if ( !m_EditInPlace.m_Active || _Ym_PosY+m_EditInPlace.m_Y+m_Font->m_CharHeight ) + return false; + + int i, CaretX = m_PosX+m_EditInPlace.m_X; + for( i=m_EditInPlace.m_FirstChar; i<(int)m_EditInPlace.m_String.length() && CaretXm_CharWidth[u]; + if( _X < CaretX + CharWidth / 2 ) + break; + CaretX += CharWidth; + } + if( CaretX>=m_PosX+m_EditInPlace.m_X+m_EditInPlace.m_Width ) + i = max(0, i-1); + + m_EditInPlace.m_CaretPos = i; + if( !_Select ) + m_EditInPlace.m_SelectionStart = m_EditInPlace.m_CaretPos; + return true; +} + + +bool CTwBar::EditInPlaceGetClipboard(std::string *_OutString) +{ + assert( _OutString!=NULL ); + *_OutString = m_EditInPlace.m_Clipboard; // default implementation + +#if defined ANT_WINDOWS + + if( !IsClipboardFormatAvailable(CF_TEXT) ) + return false; + if( !OpenClipboard(NULL) ) + return false; + HGLOBAL TextHandle = GetClipboardData(CF_TEXT); + if( TextHandle!=NULL ) + { + const char *TextString = static_cast(GlobalLock(TextHandle)); + if( TextHandle!=NULL ) + { + *_OutString = TextString; + GlobalUnlock(TextHandle); + } + } + CloseClipboard(); + +#elif defined ANT_UNIX + + if( g_TwMgr->m_CurrentXDisplay!=NULL ) + { + int NbBytes = 0; + char *Buffer = XFetchBytes(g_TwMgr->m_CurrentXDisplay, &NbBytes); + if( Buffer!=NULL ) + { + if( NbBytes>0 ) + { + char *Text = new char[NbBytes+1]; + memcpy(Text, Buffer, NbBytes); + Text[NbBytes] = '\0'; + *_OutString = Text; + delete[] Text; + } + XFree(Buffer); + } + } + +#endif + + return true; +} + + +bool CTwBar::EditInPlaceSetClipboard(const std::string& _String) +{ + if( _String.length()<=0 ) + return false; // keep last clipboard + m_EditInPlace.m_Clipboard = _String; // default implementation + +#if defined ANT_WINDOWS + + if( !OpenClipboard(NULL) ) + return false; + EmptyClipboard(); + HGLOBAL TextHandle = GlobalAlloc(GMEM_MOVEABLE, _String.length()+1); + if( TextHandle==NULL ) + { + CloseClipboard(); + return false; + } + char *TextString = static_cast(GlobalLock(TextHandle)); + memcpy(TextString, _String.c_str(), _String.length()); + TextString[_String.length()] = '\0'; + GlobalUnlock(TextHandle); + SetClipboardData(CF_TEXT, TextHandle); + CloseClipboard(); + +#elif defined ANT_UNIX + + if( g_TwMgr->m_CurrentXDisplay!=NULL ) + { + XSetSelectionOwner(g_TwMgr->m_CurrentXDisplay, XA_PRIMARY, None, CurrentTime); + char *Text = new char[_String.length()+1]; + memcpy(Text, _String.c_str(), _String.length()); + Text[_String.length()] = '\0'; + XStoreBytes(g_TwMgr->m_CurrentXDisplay, Text, _String.length()); + delete[] Text; + } + +#endif + + return true; +} + + +// --------------------------------------------------------------------------- + + diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwBar.h b/Extras/CDTestFramework/AntTweakBar/src/TwBar.h new file mode 100644 index 0000000..fba105f --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwBar.h @@ -0,0 +1,438 @@ +// --------------------------------------------------------------------------- +// +// @file TwBar.h +// @brief Tweak bar and var classes. +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_BAR_INCLUDED +#define ANT_TW_BAR_INCLUDED + +#include +#include "TwColors.h" + +#define ANT_TWEAK_BAR_DLL "AntTweakBar" + + +// --------------------------------------------------------------------------- + +bool IsCustomType(int _Type); + +struct CTwVar +{ + std::string m_Name; + std::string m_Label; + std::string m_Help; + bool m_IsRoot; + bool m_DontClip; + bool m_Visible; + signed short m_LeftMargin; + signed short m_TopMargin; + const color32 * m_ColorPtr; + const color32 * m_BgColorPtr; + + virtual bool IsGroup() const = 0; + virtual bool IsCustom() const { return false; } + virtual const CTwVar * Find(const char *_Name, struct CTwVarGroup **_Parent, int *_Index) const = 0; + virtual int HasAttrib(const char *_Attrib, bool *_HasValue) const; + virtual int SetAttrib(int _AttribID, const char *_Value, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex); + virtual ERetType GetAttrib(int _AttribID, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex, std::vector& outDouble, std::ostringstream& outString) const; + virtual void SetReadOnly(bool _ReadOnly) = 0; + virtual bool IsReadOnly() const = 0; + CTwVar(); + virtual ~CTwVar() {} + + static size_t GetDataSize(TwType _Type); +}; + + +struct CTwVarAtom : CTwVar +{ + ETwType m_Type; + void * m_Ptr; + TwSetVarCallback m_SetCallback; + TwGetVarCallback m_GetCallback; + void * m_ClientData; + bool m_ReadOnly; + bool m_NoSlider; + int m_KeyIncr[2]; // [0]=key_code [1]=modifiers + int m_KeyDecr[2]; // [0]=key_code [1]=modifiers + + template struct TVal + { + _T m_Min; + _T m_Max; + _T m_Step; + signed char m_Precision; + bool m_Hexa; + }; + union UVal + { + TVal m_Char; + TVal m_Int8; + TVal m_UInt8; + TVal m_Int16; + TValm_UInt16; + TVal m_Int32; + TVal m_UInt32; + TVal m_Float32; + TVal m_Float64; + struct CBoolVal + { + char * m_TrueString; + char * m_FalseString; + bool m_FreeTrueString; + bool m_FreeFalseString; + } m_Bool; + struct CEnumVal // empty -> enum entries are deduced from m_Type + { + //typedef std::map CEntries; + //CEntries * m_Entries; + } m_Enum; + struct CShortcutVal + { + int m_Incr[2]; + int m_Decr[2]; + } m_Shortcut; + struct CHelpStruct + { + int m_StructType; + } m_HelpStruct; + struct CButtonVal + { + TwButtonCallback m_Callback; + int m_Separator; + } m_Button; + struct CCustomVal + { + CTwMgr::CMemberProxy *m_MemberProxy; + } m_Custom; + }; + UVal m_Val; + + virtual bool IsGroup() const { return false; } + virtual bool IsCustom() const { return IsCustomType(m_Type); } + virtual void ValueToString(std::string *_Str) const; + virtual double ValueToDouble() const; + virtual void ValueFromDouble(double _Val); + virtual void MinMaxStepToDouble(double *_Min, double *_Max, double *_Step) const; + virtual const CTwVar * Find(const char *_Name, struct CTwVarGroup **_Parent, int *_Index) const; + virtual int HasAttrib(const char *_Attrib, bool *_HasValue) const; + virtual int SetAttrib(int _AttribID, const char *_Value, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex); + virtual ERetType GetAttrib(int _AttribID, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex, std::vector& outDouble, std::ostringstream& outString) const; + virtual void Increment(int _Step); + virtual void SetDefaults(); + virtual void SetReadOnly(bool _ReadOnly) { m_ReadOnly=_ReadOnly; if( m_Type!=TW_TYPE_BUTTON && m_SetCallback==NULL && m_Ptr==NULL ) m_ReadOnly=true; } + virtual bool IsReadOnly() const { if( m_Type!=TW_TYPE_BUTTON && m_SetCallback==NULL && m_Ptr==NULL ) return true; else return m_ReadOnly; } + //virtual int DefineEnum(const TwEnumVal *_EnumValues, unsigned int _NbValues); + CTwVarAtom(); + virtual ~CTwVarAtom(); +}; + + +struct CTwVarGroup : CTwVar +{ + std::vector m_Vars; + bool m_Open; + TwSummaryCallback m_SummaryCallback; + void * m_SummaryClientData; + void * m_StructValuePtr; + TwType m_StructType; + + virtual bool IsGroup() const { return true; } + virtual const CTwVar * Find(const char *_Name, CTwVarGroup **_Parent, int *_Index) const; + virtual int HasAttrib(const char *_Attrib, bool *_HasValue) const; + virtual int SetAttrib(int _AttribID, const char *_Value, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex); + virtual ERetType GetAttrib(int _AttribID, TwBar *_Bar, struct CTwVarGroup *_VarParent, int _VarIndex, std::vector& outDouble, std::ostringstream& outString) const; + virtual CTwVarAtom * FindShortcut(int _Key, int _Modifiers, bool *_DoIncr); + virtual void SetReadOnly(bool _ReadOnly) { for(size_t i=0; iSetReadOnly(_ReadOnly); } + virtual bool IsReadOnly() const { for(size_t i=0; iIsReadOnly()) return false; return true; } + CTwVarGroup() { m_Open=false; m_StructType=TW_TYPE_UNDEF; m_SummaryCallback=NULL; m_SummaryClientData=NULL; m_StructValuePtr=NULL; } + virtual ~CTwVarGroup(); +}; + +// --------------------------------------------------------------------------- + +struct CTwBar +{ + std::string m_Name; + std::string m_Label; + std::string m_Help; + bool m_Visible; + int m_PosX; + int m_PosY; + int m_Width; + int m_Height; + color32 m_Color; + bool m_DarkText; + const CTexFont * m_Font; + int m_ValuesWidth; + int m_Sep; + int m_LineSep; + int m_FirstLine; + float m_UpdatePeriod; + bool m_IsHelpBar; + int m_MinNumber; // accessed by TwDeleteBar + bool m_IsPopupList; + CTwVarAtom * m_VarEnumLinkedToPopupList; + CTwBar * m_BarLinkedToPopupList; + bool m_Resizable; + bool m_Movable; + bool m_Iconifiable; + bool m_Contained; + + CTwVarGroup m_VarRoot; + + enum EDrawPart { DRAW_BG=(1<<0), DRAW_CONTENT=(1<<1), DRAW_ALL=DRAW_BG|DRAW_CONTENT }; + void Draw(int _DrawPart=DRAW_ALL); + void NotUpToDate(); + const CTwVar * Find(const char *_Name, CTwVarGroup **_Parent=NULL, int *_Index=NULL) const; + CTwVar * Find(const char *_Name, CTwVarGroup **_Parent=NULL, int *_Index=NULL); + int HasAttrib(const char *_Attrib, bool *_HasValue) const; + int SetAttrib(int _AttribID, const char *_Value); + ERetType GetAttrib(int _AttribID, std::vector& outDouble, std::ostringstream& outString) const; + bool MouseMotion(int _X, int _Y); + bool MouseButton(ETwMouseButtonID _Button, bool _Pressed, int _X, int _Y); + bool MouseWheel(int _Pos, int _PrevPos, int _MouseX, int _MouseY); + bool KeyPressed(int _Key, int _Modifiers); + bool KeyTest(int _Key, int _Modifiers); + bool IsMinimized() const { return m_IsMinimized; } + bool IsDragging() const { return m_MouseDrag; } + bool Show(CTwVar *_Var); // display the line associated to _Var + bool OpenHier(CTwVarGroup *_Root, CTwVar *_Var); // open a hierarchy if it contains _Var + int LineInHier(CTwVarGroup *_Root, CTwVar *_Var); // returns the number of the line associated to _Var + void UnHighlightLine() { m_HighlightedLine = -1; NotUpToDate(); } // used by PopupCallback + void HaveFocus(bool _Focus) { m_DrawHandles = _Focus; } // used by PopupCallback + void StopEditInPlace() { if( m_EditInPlace.m_Active ) EditInPlaceEnd(false); } + CTwBar(const char *_Name); + ~CTwBar(); + + color32 m_ColBg, m_ColBg1, m_ColBg2; + color32 m_ColHighBg0; + color32 m_ColHighBg1; + color32 m_ColLabelText; + color32 m_ColStructText; + color32 m_ColValBg; + color32 m_ColValText; + color32 m_ColValTextRO; + color32 m_ColValTextNE; + color32 m_ColValMin; + color32 m_ColValMax; + color32 m_ColStructBg; + color32 m_ColTitleBg; + color32 m_ColTitleHighBg; + color32 m_ColTitleUnactiveBg; + color32 m_ColTitleText; + color32 m_ColTitleShadow; + color32 m_ColLine; + color32 m_ColLineShadow; + color32 m_ColUnderline; + color32 m_ColBtn; + color32 m_ColHighBtn; + color32 m_ColFold; + color32 m_ColHighFold; + color32 m_ColGrpBg; + color32 m_ColGrpText; + color32 m_ColHierBg; + color32 m_ColShortcutText; + color32 m_ColShortcutBg; + color32 m_ColInfoText; + color32 m_ColHelpBg; + color32 m_ColHelpText; + color32 m_ColRoto; + color32 m_ColRotoVal; + color32 m_ColRotoBound; + color32 m_ColEditBg; + color32 m_ColEditText; + color32 m_ColEditSelBg; + color32 m_ColEditSelText; + color32 m_ColSeparator; + color32 m_ColStaticText; + void UpdateColors(); + +protected: + int m_TitleWidth; + int m_VarX0; + int m_VarX1; + int m_VarX2; + int m_VarY0; + int m_VarY1; + int m_VarY2; + int m_ScrollYW; + int m_ScrollYH; + int m_ScrollY0; + int m_ScrollY1; + int m_NbHierLines; + int m_NbDisplayedLines; + bool m_UpToDate; + float m_LastUpdateTime; + void Update(); + + bool m_MouseDrag; + bool m_MouseDragVar; + bool m_MouseDragTitle; + bool m_MouseDragScroll; + bool m_MouseDragResizeUR; + bool m_MouseDragResizeUL; + bool m_MouseDragResizeLR; + bool m_MouseDragResizeLL; + bool m_MouseDragValWidth; + int m_MouseOriginX; + int m_MouseOriginY; + double m_ValuesWidthRatio; + bool m_VarHasBeenIncr; + int m_FirstLine0; + int m_HighlightedLine; + int m_HighlightedLinePrev; + int m_HighlightedLineLastValid; + bool m_HighlightIncrBtn; + bool m_HighlightDecrBtn; + bool m_HighlightRotoBtn; + bool m_HighlightListBtn; + bool m_HighlightBoolBtn; + bool m_HighlightClickBtn; + double m_HighlightClickBtnAuto; + bool m_HighlightTitle; + bool m_HighlightScroll; + bool m_HighlightUpScroll; + bool m_HighlightDnScroll; + bool m_HighlightMinimize; + bool m_HighlightFont; + bool m_HighlightValWidth; + bool m_HighlightLabelsHeader; + bool m_HighlightValuesHeader; + bool m_DrawHandles; + + bool m_IsMinimized; + int m_MinPosX; + int m_MinPosY; + bool m_HighlightMaximize; + bool m_DrawIncrDecrBtn; + bool m_DrawRotoBtn; + bool m_DrawClickBtn; + bool m_DrawListBtn; + bool m_DrawBoolBtn; + EButtonAlign m_ButtonAlign; + + struct CHierTag + { + CTwVar * m_Var; + int m_Level; + bool m_Closing; + }; + std::vector m_HierTags; + void BrowseHierarchy(int *_LineNum, int _CurrLevel, const CTwVar *_Var, int _First, int _Last); + void * m_TitleTextObj; + void * m_LabelsTextObj; + void * m_ValuesTextObj; + void * m_ShortcutTextObj; + int m_ShortcutLine; + void * m_HeadersTextObj; + void ListLabels(std::vector& _Labels, std::vector& _Colors, std::vector& _BgColors, bool *_HasBgColors, const CTexFont *_Font, int _AtomWidthMax, int _GroupWidthMax); + void ListValues(std::vector& _Values, std::vector& _Colors, std::vector& _BgColors, const CTexFont *_Font, int _WidthMax); + int ComputeLabelsWidth(const CTexFont *_Font); + int ComputeValuesWidth(const CTexFont *_Font); + void DrawHierHandle(); + + enum EValuesWidthFit { VALUES_WIDTH_FIT = -5555 }; + + // RotoSlider + struct CPoint + { + int x, y; + CPoint() {} + CPoint(int _X, int _Y):x(_X), y(_Y) {} + const CPoint operator+ (const CPoint& p) const { return CPoint(x+p.x, y+p.y); } + const CPoint operator- (const CPoint& p) const { return CPoint(x-p.x, y-p.y); } + }; + struct CRotoSlider + { + CRotoSlider(); + CTwVarAtom * m_Var; + double m_PreciseValue; + double m_CurrentValue; + double m_Value0; + double m_ValueAngle0; + bool m_Active; + bool m_ActiveMiddle; + CPoint m_Origin; + CPoint m_Current; + bool m_HasPrevious; + CPoint m_Previous; + double m_Angle0; + double m_AngleDT; + int m_Subdiv; + }; + CRotoSlider m_Roto; + int m_RotoMinRadius; + int m_RotoNbSubdiv; // number of steps for one turn + void RotoDraw(); + void RotoOnMouseMove(int _X, int _Y); + void RotoOnLButtonDown(int _X, int _Y); + void RotoOnLButtonUp(int _X, int _Y); + void RotoOnMButtonDown(int _X, int _Y); + void RotoOnMButtonUp(int _X, int _Y); + double RotoGetValue() const; + void RotoSetValue(double _Val); + double RotoGetMin() const; + double RotoGetMax() const; + double RotoGetStep() const; + double RotoGetSteppedValue() const; + + // Edit-in-place + struct CEditInPlace + { + CEditInPlace(); + ~CEditInPlace(); + CTwVarAtom * m_Var; + bool m_Active; + std::string m_String; + void * m_EditTextObj; + void * m_EditSelTextObj; + int m_CaretPos; + int m_SelectionStart; + int m_X, m_Y; + int m_Width; + int m_FirstChar; + std::string m_Clipboard; + }; + CEditInPlace m_EditInPlace; + void EditInPlaceDraw(); + bool EditInPlaceAcceptVar(const CTwVarAtom* _Var); + bool EditInPlaceIsReadOnly(); + void EditInPlaceStart(CTwVarAtom* _Var, int _X, int _Y, int _Width); + void EditInPlaceEnd(bool _Commit); + bool EditInPlaceKeyPressed(int _Key, int _Modifiers); + bool EditInPlaceEraseSelect(); + bool EditInPlaceMouseMove(int _X, int _Y, bool _Select); + bool EditInPlaceSetClipboard(const std::string& _String); + bool EditInPlaceGetClipboard(std::string *_OutString); + + struct CCustomRecord + { + int m_IndexMin; + int m_IndexMax; + int m_XMin, m_XMax; + int m_YMin, m_YMax; // Y visible range + int m_Y0, m_Y1; // Y widget range + CTwVarGroup * m_Var; + }; + typedef std::map CustomMap; + CustomMap m_CustomRecords; + CTwMgr::CStructProxy * m_CustomActiveStructProxy; + + friend struct CTwMgr; +}; + +void DrawArc(int _X, int _Y, int _Radius, float _StartAngleDeg, float _EndAngleDeg, color32 _Color); + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_BAR_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwColors.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwColors.cpp new file mode 100644 index 0000000..39bfbb2 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwColors.cpp @@ -0,0 +1,153 @@ +// --------------------------------------------------------------------------- +// +// @file TwColors.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "TwColors.h" + + +void ColorRGBToHLSf(float _R, float _G, float _B, float *_Hue, float *_Light, float *_Saturation) +{ + // Compute HLS from RGB. The r,g,b triplet is between [0,1], + // hue is between [0,360], light and saturation are [0,1]. + + float rnorm, gnorm, bnorm, minval, maxval, msum, mdiff, r, g, b; + r = g = b = 0; + if(_R>0) r = _R; if(r>1) r = 1; + if(_G>0) g = _G; if(g>1) g = 1; + if(_B>0) b = _B; if(b>1) b = 1; + + minval = r; + if(gmaxval) maxval = g; + if(b>maxval) maxval = b; + + rnorm = gnorm = bnorm = 0; + mdiff = maxval - minval; + msum = maxval + minval; + float l = 0.5f * msum; + if(_Light) + *_Light = l; + if(maxval!=minval) + { + rnorm = (maxval - r)/mdiff; + gnorm = (maxval - g)/mdiff; + bnorm = (maxval - b)/mdiff; + } + else + { + if(_Saturation) + *_Saturation = 0; + if(_Hue) + *_Hue = 0; + return; + } + + if(_Saturation) + { + if(l<0.5f) + *_Saturation = mdiff/msum; + else + *_Saturation = mdiff/(2.0f - msum); + } + + if(_Hue) + { + if(r==maxval) + *_Hue = 60.0f * (6.0f + bnorm - gnorm); + else if(g==maxval) + *_Hue = 60.0f * (2.0f + rnorm - bnorm); + else + *_Hue = 60.0f * (4.0f + gnorm - rnorm); + + if(*_Hue>360.0f) + *_Hue -= 360.0f; + } +} + + +void ColorRGBToHLSi(int _R, int _G, int _B, int *_Hue, int *_Light, int *_Saturation) +{ + float h, l, s; + ColorRGBToHLSf((1.0f/255.0f)*float(_R), (1.0f/255.0f)*float(_G), (1.0f/255.0f)*float(_B), &h, &l, &s); + if(_Hue) *_Hue = (int)TClamp(h*(256.0f/360.0f), 0.0f, 255.0f); + if(_Light) *_Light = (int)TClamp(l*256.0f, 0.0f, 255.0f); + if(_Saturation) *_Saturation= (int)TClamp(s*256.0f, 0.0f, 255.0f); +} + + +void ColorHLSToRGBf(float _Hue, float _Light, float _Saturation, float *_R, float *_G, float *_B) +{ + // Compute RGB from HLS. The light and saturation are between [0,1] + // and hue is between [0,360]. The returned r,g,b triplet is between [0,1]. + + // a local auxiliary function + struct CLocal + { + static float HLSToRGB(float _Rn1, float _Rn2, float _Huei) + { + float hue = _Huei; + if(hue>360) hue = hue - 360; + if(hue<0) hue = hue + 360; + if(hue<60 ) return _Rn1 + (_Rn2-_Rn1)*hue/60; + if(hue<180) return _Rn2; + if(hue<240) return _Rn1 + (_Rn2-_Rn1)*(240-hue)/60; + return _Rn1; + } + }; + + float rh, rl, rs, rm1, rm2; + rh = rl = rs = 0; + if(_Hue>0) rh = _Hue; if(rh>360) rh = 360; + if(_Light>0) rl = _Light; if(rl>1) rl = 1; + if(_Saturation>0) rs = _Saturation; if(rs>1) rs = 1; + + if(rl<=0.5f) + rm2 = rl*(1.0f + rs); + else + rm2 = rl + rs - rl*rs; + rm1 = 2.0f*rl - rm2; + + if(!rs) + { + if(_R) *_R = rl; + if(_G) *_G = rl; + if(_B) *_B = rl; + } + else + { + if(_R) *_R = CLocal::HLSToRGB(rm1, rm2, rh+120); + if(_G) *_G = CLocal::HLSToRGB(rm1, rm2, rh); + if(_B) *_B = CLocal::HLSToRGB(rm1, rm2, rh-120); + } +} + + +void ColorHLSToRGBi(int _Hue, int _Light, int _Saturation, int *_R, int *_G, int *_B) +{ + float r, g, b; + ColorHLSToRGBf((360.0f/255.0f)*float(_Hue), (1.0f/255.0f)*float(_Light), (1.0f/255.0f)*float(_Saturation), &r, &g, &b); + if(_R) *_R = (int)TClamp(r*256.0f, 0.0f, 255.0f); + if(_G) *_G = (int)TClamp(g*256.0f, 0.0f, 255.0f); + if(_B) *_B = (int)TClamp(b*256.0f, 0.0f, 255.0f); +} + + +color32 ColorBlend(color32 _Color1, color32 _Color2, float _S) +{ + float a1, r1, g1, b1, a2, r2, g2, b2; + Color32ToARGBf(_Color1, &a1, &r1, &g1, &b1); + Color32ToARGBf(_Color2, &a2, &r2, &g2, &b2); + float t = 1.0f-_S; + return Color32FromARGBf(t*a1+_S*a2, t*r1+_S*r2, t*g1+_S*g2, t*b1+_S*b2); +} + + diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwColors.h b/Extras/CDTestFramework/AntTweakBar/src/TwColors.h new file mode 100644 index 0000000..f4e88ce --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwColors.h @@ -0,0 +1,80 @@ +// --------------------------------------------------------------------------- +// +// @file TwColors.h +// @brief Color conversions +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_COLORS_INCLUDED +#define ANT_TW_COLORS_INCLUDED + + +// --------------------------------------------------------------------------- + + +typedef unsigned int color32; + + +const color32 COLOR32_BLACK = 0xff000000; // Black +const color32 COLOR32_WHITE = 0xffffffff; // White +const color32 COLOR32_ZERO = 0x00000000; // Zero +const color32 COLOR32_RED = 0xffff0000; // Red +const color32 COLOR32_GREEN = 0xff00ff00; // Green +const color32 COLOR32_BLUE = 0xff0000ff; // Blue + + +template inline const _T& TClamp(const _T& _X, const _T& _Limit1, const _T& _Limit2) +{ + if( _Limit1<_Limit2 ) + return (_X<=_Limit1) ? _Limit1 : ( (_X>=_Limit2) ? _Limit2 : _X ); + else + return (_X<=_Limit2) ? _Limit2 : ( (_X>=_Limit1) ? _Limit1 : _X ); +} + +inline color32 Color32FromARGBi(int _A, int _R, int _G, int _B) +{ + return (((color32)TClamp(_A, 0, 255))<<24) | (((color32)TClamp(_R, 0, 255))<<16) | (((color32)TClamp(_G, 0, 255))<<8) | ((color32)TClamp(_B, 0, 255)); +} + +inline color32 Color32FromARGBf(float _A, float _R, float _G, float _B) +{ + return (((color32)TClamp(_A*256.0f, 0.0f, 255.0f))<<24) | (((color32)TClamp(_R*256.0f, 0.0f, 255.0f))<<16) | (((color32)TClamp(_G*256.0f, 0.0f, 255.0f))<<8) | ((color32)TClamp(_B*256.0f, 0.0f, 255.0f)); +} + +inline void Color32ToARGBi(color32 _Color, int *_A, int *_R, int *_G, int *_B) +{ + if(_A) *_A = (_Color>>24)&0xff; + if(_R) *_R = (_Color>>16)&0xff; + if(_G) *_G = (_Color>>8)&0xff; + if(_B) *_B = _Color&0xff; +} + +inline void Color32ToARGBf(color32 _Color, float *_A, float *_R, float *_G, float *_B) +{ + if(_A) *_A = (1.0f/255.0f)*float((_Color>>24)&0xff); + if(_R) *_R = (1.0f/255.0f)*float((_Color>>16)&0xff); + if(_G) *_G = (1.0f/255.0f)*float((_Color>>8)&0xff); + if(_B) *_B = (1.0f/255.0f)*float(_Color&0xff); +} + +void ColorRGBToHLSf(float _R, float _G, float _B, float *_Hue, float *_Light, float *_Saturation); + +void ColorRGBToHLSi(int _R, int _G, int _B, int *_Hue, int *_Light, int *_Saturation); + +void ColorHLSToRGBf(float _Hue, float _Light, float _Saturation, float *_R, float *_G, float *_B); + +void ColorHLSToRGBi(int _Hue, int _Light, int _Saturation, int *_R, int *_G, int *_B); + +color32 ColorBlend(color32 _Color1, color32 _Color2, float _S); + + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_COLORS_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.cpp new file mode 100644 index 0000000..0622c23 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.cpp @@ -0,0 +1,1291 @@ +// --------------------------------------------------------------------------- +// +// @file TwDirect3D10.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "TwDirect3D10.h" +#include "TwMgr.h" +#include "TwColors.h" + +#include "d3d10vs2003.h" // Workaround to include D3D10.h with VS2003 +#define D3D10_IGNORE_SDK_LAYERS // d3d10sdklayers.h may not exist +#include + + +using namespace std; + +const char *g_ErrCantLoadD3D10 = "Cannot load Direct3D10 library dynamically"; +const char *g_ErrCompileFX10 = "Direct3D10 effect compilation failed"; +const char *g_ErrCreateFX10 = "Direct3D10 effect creation failed"; +const char *g_ErrTechNotFound10 = "Cannot find Direct3D10 technique effect"; +const char *g_ErrCreateLayout10 = "Direct3D10 vertex layout creation failed"; +const char *g_ErrCreateBuffer10 = "Direct3D10 vertex buffer creation failed"; + +// --------------------------------------------------------------------------- + +// Dynamically loaded D3D10 functions (to avoid static linkage with d3d10.lib) +HMODULE g_D3D10Module = NULL; +typedef HRESULT (WINAPI *D3D10CompileEffectFromMemoryProc)(void *pData, SIZE_T DataLength, LPCSTR pSrcFileName, CONST D3D10_SHADER_MACRO *pDefines, ID3D10Include *pInclude, UINT HLSLFlags, UINT FXFlags, ID3D10Blob **ppCompiledEffect, ID3D10Blob **ppErrors); +typedef HRESULT (WINAPI *D3D10CreateEffectFromMemoryProc)(void *pData, SIZE_T DataLength, UINT FXFlags, ID3D10Device *pDevice, ID3D10EffectPool *pEffectPool, ID3D10Effect **ppEffect); +typedef HRESULT (WINAPI *D3D10StateBlockMaskEnableAllProc)(D3D10_STATE_BLOCK_MASK *pMask); +typedef HRESULT (WINAPI *D3D10CreateStateBlockProc)(ID3D10Device *pDevice, D3D10_STATE_BLOCK_MASK *pStateBlockMask, ID3D10StateBlock **ppStateBlock); +D3D10CompileEffectFromMemoryProc _D3D10CompileEffectFromMemory = NULL; +D3D10CreateEffectFromMemoryProc _D3D10CreateEffectFromMemory = NULL; +D3D10StateBlockMaskEnableAllProc _D3D10StateBlockMaskEnableAll = NULL; +D3D10CreateStateBlockProc _D3D10CreateStateBlock = NULL; + +const RECT FullRect = {0, 0, 16000, 16000}; +static bool RectIsFull(const RECT& r) { return r.left==FullRect.left && r.right==FullRect.right && r.top==FullRect.top && r.bottom==FullRect.bottom; } + +static int LoadDirect3D10() +{ + if( g_D3D10Module!=NULL ) + return 1; // Direct3D10 library already loaded + + g_D3D10Module = LoadLibrary("D3D10.DLL"); + if( g_D3D10Module ) + { + int res = 1; + _D3D10CompileEffectFromMemory = reinterpret_cast(GetProcAddress(g_D3D10Module, "D3D10CompileEffectFromMemory")); + if( _D3D10CompileEffectFromMemory==NULL ) + res = 0; + _D3D10CreateEffectFromMemory = reinterpret_cast(GetProcAddress(g_D3D10Module, "D3D10CreateEffectFromMemory")); + if( _D3D10CreateEffectFromMemory==NULL ) + res = 0; + _D3D10StateBlockMaskEnableAll = reinterpret_cast(GetProcAddress(g_D3D10Module, "D3D10StateBlockMaskEnableAll")); + if( _D3D10StateBlockMaskEnableAll==NULL ) + res = 0; + _D3D10CreateStateBlock = reinterpret_cast(GetProcAddress(g_D3D10Module, "D3D10CreateStateBlock")); + if( _D3D10CreateStateBlock==NULL ) + res = 0; + return res; + } + else + return 0; // cannot load DLL +} + +static int UnloadDirect3D10() +{ + _D3D10CompileEffectFromMemory = NULL; + _D3D10CreateEffectFromMemory = NULL; + _D3D10StateBlockMaskEnableAll = NULL; + _D3D10CreateStateBlock = NULL; + + if( g_D3D10Module==NULL ) + return 1; // Direct3D10 library not loaded + + if( FreeLibrary(g_D3D10Module) ) + { + g_D3D10Module = NULL; + return 1; + } + else + return 0; // cannot unload d3d10.dll +} + +// --------------------------------------------------------------------------- + +static ID3D10ShaderResourceView *BindFont(ID3D10Device *_Dev, ID3D10EffectShaderResourceVariable *_ResVar, const CTexFont *_Font) +{ + assert(_Font!=NULL); + assert(_ResVar!=NULL); + + int w = _Font->m_TexWidth; + int h = _Font->m_TexHeight; + color32 *font32 = new color32[w*h]; + color32 *p = font32; + for( int i=0; im_TexBytes[i]))<<24); + + D3D10_TEXTURE2D_DESC desc; + desc.Width = w; + desc.Height = h; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D10_USAGE_IMMUTABLE; + desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + D3D10_SUBRESOURCE_DATA data; + data.pSysMem = font32; + data.SysMemPitch = w*sizeof(color32); + data.SysMemSlicePitch = 0; + ID3D10Texture2D *tex = NULL; + ID3D10ShaderResourceView *texRV = NULL; + if( SUCCEEDED(_Dev->CreateTexture2D(&desc, &data, &tex)) ) + { + if( SUCCEEDED(_Dev->CreateShaderResourceView(tex, NULL, &texRV)) ) + if( _ResVar ) + _ResVar->SetResource(texRV); + tex->Release(); + tex = NULL; + } + + delete[] font32; + return texRV; +} + +// --------------------------------------------------------------------------- + +static void UnbindFont(ID3D10Device *_Dev, ID3D10EffectShaderResourceVariable *_ResVar, ID3D10ShaderResourceView *_TexRV) +{ + (void)_Dev; + + if( _ResVar ) + _ResVar->SetResource(NULL); + + if( _TexRV ) + { + ULONG rc = _TexRV->Release(); + assert( rc==0 ); (void)rc; + } +} + +// --------------------------------------------------------------------------- + +struct CState10 +{ + ID3D10StateBlock * m_StateBlock; + + void Save(); + void Restore(); + CState10(ID3D10Device *_Dev); + ~CState10(); +private: + ID3D10Device * m_D3DDev; +}; + +CState10::CState10(ID3D10Device *_Dev) +{ + ZeroMemory(this, sizeof(CState10)); + m_D3DDev = _Dev; +} + +CState10::~CState10() +{ + if( m_StateBlock ) + { + UINT rc = m_StateBlock->Release(); + assert( rc==0 ); (void)rc; + m_StateBlock = NULL; + } +} + +void CState10::Save() +{ + if( !m_StateBlock ) + { + D3D10_STATE_BLOCK_MASK stateMask; + _D3D10StateBlockMaskEnableAll(&stateMask); + _D3D10CreateStateBlock(m_D3DDev, &stateMask, &m_StateBlock); + } + + if( m_StateBlock ) + m_StateBlock->Capture(); +} + +void CState10::Restore() +{ + if( m_StateBlock ) + m_StateBlock->Apply(); +} + +// --------------------------------------------------------------------------- + +char g_ShaderFX[] = "// AntTweakBar shaders and techniques \n" + " float4 g_Offset = 0; float4 g_CstColor = 1; \n" + " struct LineRectPSInput { float4 Pos : SV_POSITION; float4 Color : COLOR0; }; \n" + " LineRectPSInput LineRectVS(float4 pos : POSITION, float4 color : COLOR, uniform bool useCstColor) { \n" + " LineRectPSInput ps; ps.Pos = pos + g_Offset; \n" + " ps.Color = useCstColor ? g_CstColor : color; return ps; } \n" + " float4 LineRectPS(LineRectPSInput input) : SV_Target { return input.Color; } \n" + " technique10 LineRect { pass P0 { \n" + " SetVertexShader( CompileShader( vs_4_0, LineRectVS(false) ) ); \n" + " SetGeometryShader( NULL ); \n" + " SetPixelShader( CompileShader( ps_4_0, LineRectPS() ) ); \n" + " } }\n" + " technique10 LineRectCstColor { pass P0 { \n" + " SetVertexShader( CompileShader( vs_4_0, LineRectVS(true) ) ); \n" + " SetGeometryShader( NULL ); \n" + " SetPixelShader( CompileShader( ps_4_0, LineRectPS() ) ); \n" + " } }\n" + " Texture2D Font; \n" + " SamplerState FontSampler { Filter = MIN_MAG_MIP_POINT; AddressU = BORDER; AddressV = BORDER; BorderColor=float4(0, 0, 0, 0); }; \n" + " struct TextPSInput { float4 Pos : SV_POSITION; float4 Color : COLOR0; float2 Tex : TEXCOORD0; }; \n" + " TextPSInput TextVS(float4 pos : POSITION, float4 color : COLOR, float2 tex : TEXCOORD0, uniform bool useCstColor) { \n" + " TextPSInput ps; ps.Pos = pos + g_Offset; \n" + " ps.Color = useCstColor ? g_CstColor : color; ps.Tex = tex; return ps; } \n" + " float4 TextPS(TextPSInput input) : SV_Target { return Font.Sample(FontSampler, input.Tex)*input.Color; } \n" + " technique10 Text { pass P0 { \n" + " SetVertexShader( CompileShader( vs_4_0, TextVS(false) ) ); \n" + " SetGeometryShader( NULL ); \n" + " SetPixelShader( CompileShader( ps_4_0, TextPS() ) ); \n" + " } }\n" + " technique10 TextCstColor { pass P0 { \n" + " SetVertexShader( CompileShader( vs_4_0, TextVS(true) ) ); \n" + " SetGeometryShader( NULL ); \n" + " SetPixelShader( CompileShader( ps_4_0, TextPS() ) ); \n" + " } }\n" + " // End of AntTweakBar shaders and techniques \n"; + +// --------------------------------------------------------------------------- + +int CTwGraphDirect3D10::Init() +{ + assert(g_TwMgr!=NULL); + assert(g_TwMgr->m_Device!=NULL); + + m_D3DDev = static_cast(g_TwMgr->m_Device); + m_D3DDevInitialRefCount = m_D3DDev->AddRef() - 1; + + m_Drawing = false; + m_OffsetX = m_OffsetY = 0; + m_ViewportInit = new D3D10_VIEWPORT; + m_FontTex = NULL; + m_FontD3DTexRV = NULL; + m_WndWidth = 0; + m_WndHeight = 0; + m_State = NULL; + m_DepthStencilState = NULL; + m_BlendState = NULL; + m_RasterState = NULL; + m_RasterStateAntialiased = NULL; + m_RasterStateCullCW = NULL; + m_RasterStateCullCCW = NULL; + m_Effect = NULL; + m_LineRectTech = NULL; + m_LineRectCstColorTech = NULL; + m_LineRectVertexLayout = NULL; + m_LineVertexBuffer = NULL; + m_RectVertexBuffer = NULL; + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + m_TextTech = NULL; + m_TextCstColorTech = NULL; + m_TextVertexLayout = NULL; + m_FontD3DResVar = NULL; + m_OffsetVar = NULL; + m_CstColorVar = NULL; + + // Load some D3D10 functions + if( !LoadDirect3D10() ) + { + g_TwMgr->SetLastError(g_ErrCantLoadD3D10); + Shut(); + return 0; + } + + // Allocate state object + m_State = new CState10(m_D3DDev); + + // Compile shaders + DWORD shaderFlags = D3D10_SHADER_ENABLE_STRICTNESS; + #if defined( DEBUG ) || defined( _DEBUG ) + // shaderFlags |= D3D10_SHADER_DEBUG; // no more supported + #endif + ID3D10Blob *compiledFX = NULL; + ID3D10Blob *errors = NULL; + HRESULT hr = _D3D10CompileEffectFromMemory(g_ShaderFX, strlen(g_ShaderFX), "AntTweakBarFX", NULL, NULL, shaderFlags, 0, &compiledFX, &errors); + if( FAILED(hr) ) + { + const size_t ERR_MSG_MAX_LEN = 4096; + static char s_ErrorMsg[ERR_MSG_MAX_LEN]; // must be static to be sent to SetLastError + strncpy(s_ErrorMsg, g_ErrCompileFX10, ERR_MSG_MAX_LEN-1); + size_t errOffset = strlen(s_ErrorMsg); + size_t errLen = 0; + if( errors!=NULL ) + { + s_ErrorMsg[errOffset++] = ':'; + s_ErrorMsg[errOffset++] = '\n'; + errLen = min(errors->GetBufferSize(), ERR_MSG_MAX_LEN-errOffset-2); + strncpy(s_ErrorMsg+errOffset, static_cast(errors->GetBufferPointer()), errLen); + errors->Release(); + errors = NULL; + } + s_ErrorMsg[errOffset+errLen] = '\0'; + g_TwMgr->SetLastError(s_ErrorMsg); + Shut(); + return 0; + } + hr = _D3D10CreateEffectFromMemory(compiledFX->GetBufferPointer(), compiledFX->GetBufferSize(), 0, m_D3DDev, NULL, &m_Effect); + compiledFX->Release(); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateFX10); + Shut(); + return 0; + } + + // Obtain the techniques + m_LineRectTech = m_Effect->GetTechniqueByName("LineRect"); + m_LineRectCstColorTech = m_Effect->GetTechniqueByName("LineRectCstColor"); + m_TextTech = m_Effect->GetTechniqueByName("Text"); + m_TextCstColorTech = m_Effect->GetTechniqueByName("TextCstColor"); + if( m_LineRectTech==NULL || m_TextTech==NULL || m_LineRectCstColorTech==NULL || m_TextCstColorTech==NULL ) + { + g_TwMgr->SetLastError(g_ErrTechNotFound10); + Shut(); + return 0; + } + + // Create input layout for lines & rect + D3D10_INPUT_ELEMENT_DESC lineRectLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(CLineRectVtx, m_Color), D3D10_INPUT_PER_VERTEX_DATA, 0 } + }; + D3D10_PASS_DESC passDesc; + hr = m_LineRectTech->GetPassByIndex(0)->GetDesc(&passDesc); + if( SUCCEEDED(hr) ) + hr = m_D3DDev->CreateInputLayout(lineRectLayout, sizeof(lineRectLayout)/sizeof(lineRectLayout[0]), passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &m_LineRectVertexLayout); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateLayout10); + Shut(); + return 0; + } + + // Create line vertex buffer + D3D10_BUFFER_DESC bd; + bd.Usage = D3D10_USAGE_DYNAMIC; + bd.ByteWidth = 2 * sizeof(CLineRectVtx); + bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_LineVertexBuffer); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateBuffer10); + Shut(); + return 0; + } + + // Create rect vertex buffer + bd.ByteWidth = 4 * sizeof(CLineRectVtx); + hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_RectVertexBuffer); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateBuffer10); + Shut(); + return 0; + } + + // Create input layout for text + D3D10_INPUT_ELEMENT_DESC textLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(CTextVtx, m_Color), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(CTextVtx, m_UV), D3D10_INPUT_PER_VERTEX_DATA, 0 } + }; + hr = m_TextTech->GetPassByIndex(0)->GetDesc(&passDesc); + if( SUCCEEDED(hr) ) + hr = m_D3DDev->CreateInputLayout(textLayout, sizeof(textLayout)/sizeof(textLayout[0]), passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &m_TextVertexLayout); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateLayout10); + Shut(); + return 0; + } + + // Create depth stencil state object + D3D10_DEPTH_STENCILOP_DESC od; + od.StencilFunc = D3D10_COMPARISON_ALWAYS; + od.StencilFailOp = D3D10_STENCIL_OP_KEEP; + od.StencilPassOp = D3D10_STENCIL_OP_KEEP; + od.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; + D3D10_DEPTH_STENCIL_DESC dsd; + dsd.DepthEnable = FALSE; + dsd.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ZERO; + dsd.DepthFunc = D3D10_COMPARISON_ALWAYS; + dsd.StencilEnable = FALSE; + dsd.StencilReadMask = D3D10_DEFAULT_STENCIL_READ_MASK; + dsd.StencilWriteMask = D3D10_DEFAULT_STENCIL_WRITE_MASK; + dsd.FrontFace = od; + dsd.BackFace = od; + m_D3DDev->CreateDepthStencilState(&dsd, &m_DepthStencilState); + + // Create blend state object + D3D10_BLEND_DESC bsd; + bsd.AlphaToCoverageEnable = FALSE; + for(int i=0; i<8; ++i) + { + bsd.BlendEnable[i] = TRUE; + bsd.RenderTargetWriteMask[i] = D3D10_COLOR_WRITE_ENABLE_ALL; + } + bsd.SrcBlend = D3D10_BLEND_SRC_ALPHA; + bsd.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; + bsd.BlendOp = D3D10_BLEND_OP_ADD; + bsd.SrcBlendAlpha = D3D10_BLEND_SRC_ALPHA; + bsd.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; + bsd.BlendOpAlpha = D3D10_BLEND_OP_ADD; + m_D3DDev->CreateBlendState(&bsd, &m_BlendState); + + // Create rasterizer state object + D3D10_RASTERIZER_DESC rd; + rd.FillMode = D3D10_FILL_SOLID; + rd.CullMode = D3D10_CULL_NONE; + rd.FrontCounterClockwise = true; + rd.DepthBias = false; + rd.DepthBiasClamp = 0; + rd.SlopeScaledDepthBias = 0; + rd.DepthClipEnable = false; + rd.ScissorEnable = true; + rd.MultisampleEnable = false; + rd.AntialiasedLineEnable = false; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterState); + + rd.AntialiasedLineEnable = true; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateAntialiased); + rd.AntialiasedLineEnable = false; + + rd.CullMode = D3D10_CULL_BACK; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateCullCW); + + rd.CullMode = D3D10_CULL_FRONT; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateCullCCW); + + m_ViewportAndScissorRects[0] = FullRect; + m_ViewportAndScissorRects[1] = FullRect; + m_D3DDev->RSSetScissorRects(1, m_ViewportAndScissorRects); + + // Get effect globals + if( m_Effect->GetVariableByName("Font") ) + m_FontD3DResVar = m_Effect->GetVariableByName("Font")->AsShaderResource(); + assert( m_FontD3DResVar!=NULL ); + if( m_Effect->GetVariableByName("g_Offset") ) + m_OffsetVar = m_Effect->GetVariableByName("g_Offset")->AsVector(); + assert( m_OffsetVar!=NULL ); + if( m_Effect->GetVariableByName("g_CstColor") ) + m_CstColorVar = m_Effect->GetVariableByName("g_CstColor")->AsVector(); + assert( m_CstColorVar!=NULL ); + + return 1; +} + +// --------------------------------------------------------------------------- + +int CTwGraphDirect3D10::Shut() +{ + assert(m_Drawing==false); + + UnbindFont(m_D3DDev, m_FontD3DResVar, m_FontD3DTexRV); + m_FontD3DTexRV = NULL; + if( m_State ) + { + delete m_State; + m_State = NULL; + } + if( m_ViewportInit ) + { + delete m_ViewportInit; + m_ViewportInit = NULL; + } + + if( m_DepthStencilState ) + { + ULONG rc = m_DepthStencilState->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_DepthStencilState = NULL; + } + if( m_BlendState ) + { + ULONG rc = m_BlendState->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_BlendState = NULL; + } + if( m_RasterState ) + { + ULONG rc = m_RasterState->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterState = NULL; + } + if( m_RasterStateAntialiased ) + { + ULONG rc = m_RasterStateAntialiased->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterStateAntialiased = NULL; + } + if( m_RasterStateCullCW ) + { + ULONG rc = m_RasterStateCullCW->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterStateCullCW = NULL; + } + if( m_RasterStateCullCCW ) + { + ULONG rc = m_RasterStateCullCCW->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterStateCullCCW = NULL; + } + + m_FontD3DResVar = NULL; + m_OffsetVar = NULL; + m_CstColorVar = NULL; + + if( m_LineVertexBuffer ) + { + ULONG rc = m_LineVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + m_LineVertexBuffer = NULL; + } + if( m_RectVertexBuffer ) + { + ULONG rc = m_RectVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + m_RectVertexBuffer = NULL; + } + if( m_TrianglesVertexBuffer ) + { + ULONG rc = m_TrianglesVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + } + if( m_LineRectVertexLayout ) + { + ULONG rc = m_LineRectVertexLayout->Release(); + assert( rc==0 ); (void)rc; + m_LineRectVertexLayout = NULL; + } + if( m_TextVertexLayout ) + { + ULONG rc = m_TextVertexLayout->Release(); + assert( rc==0 ); (void)rc; + m_TextVertexLayout = NULL; + } + if( m_Effect ) + { + ULONG rc = m_Effect->Release(); + assert( rc==0 ); (void)rc; + m_Effect = NULL; + } + + if( m_D3DDev ) + { + //unsigned int rc = m_D3DDev->Release(); + //assert( m_D3DDevInitialRefCount==rc ); (void)rc; + m_D3DDev->Release(); + m_D3DDev = NULL; + } + + // Unload D3D10 + UnloadDirect3D10(); // this is not a problem if it cannot be unloaded + + return 1; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::BeginDraw(int _WndWidth, int _WndHeight) +{ + assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0); + m_Drawing = true; + + m_WndWidth = _WndWidth; + m_WndHeight = _WndHeight; + m_OffsetX = m_OffsetY = 0; + + // save context + m_State->Save(); + + // Setup the viewport + D3D10_VIEWPORT vp; + vp.Width = _WndWidth; + vp.Height = _WndHeight; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = 0; + vp.TopLeftY = 0; + m_D3DDev->RSSetViewports(1, &vp); + *static_cast(m_ViewportInit) = vp; + + m_D3DDev->RSSetState(m_RasterState); + + m_D3DDev->OMSetDepthStencilState(m_DepthStencilState, 0); + float blendFactors[4] = { 1, 1, 1, 1 }; + m_D3DDev->OMSetBlendState(m_BlendState, blendFactors, 0xffffffff); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::EndDraw() +{ + m_D3DDev->RSSetState(NULL); + m_D3DDev->OMSetDepthStencilState(NULL, 0); + m_D3DDev->OMSetBlendState(NULL, NULL, 0xffffffff); + + assert(m_Drawing==true); + m_Drawing = false; + + // restore context + m_State->Restore(); +} + +// --------------------------------------------------------------------------- + +bool CTwGraphDirect3D10::IsDrawing() +{ + return m_Drawing; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::Restore() +{ + if( m_State ) + { + if( m_State->m_StateBlock ) + { + UINT rc = m_State->m_StateBlock->Release(); + assert( rc==0 ); (void)rc; + m_State->m_StateBlock = NULL; + } + } + + UnbindFont(m_D3DDev, m_FontD3DResVar, m_FontD3DTexRV); + m_FontD3DTexRV = NULL; + + m_FontTex = NULL; +} + + +// --------------------------------------------------------------------------- + +static inline float ToNormScreenX(int x, int wndWidth) +{ + return 2.0f*((float)x-0.5f)/wndWidth - 1.0f; +} + +static inline float ToNormScreenY(int y, int wndHeight) +{ + return 1.0f - 2.0f*((float)y-0.5f)/wndHeight; +} + +static inline color32 ToR8G8B8A8(color32 col) +{ + return (col & 0xff00ff00) | ((col>>16) & 0xff) | ((col<<16) & 0xff0000); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased) +{ + assert(m_Drawing==true); + + float x0 = ToNormScreenX(_X0 + m_OffsetX, m_WndWidth); + float y0 = ToNormScreenY(_Y0 + m_OffsetY, m_WndHeight); + float x1 = ToNormScreenX(_X1 + m_OffsetX, m_WndWidth); + float y1 = ToNormScreenY(_Y1 + m_OffsetY, m_WndHeight); + + CLineRectVtx *vertices = NULL; + HRESULT hr = m_LineVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void **)&vertices); + if( SUCCEEDED(hr) ) + { + // Fill vertex buffer + vertices[0].m_Pos[0] = x0; + vertices[0].m_Pos[1] = y0; + vertices[0].m_Pos[2] = 0; + vertices[0].m_Color = ToR8G8B8A8(_Color0); + vertices[1].m_Pos[0] = x1; + vertices[1].m_Pos[1] = y1; + vertices[1].m_Pos[2] = 0; + vertices[1].m_Color = ToR8G8B8A8(_Color1); + + m_LineVertexBuffer->Unmap(); + + if( _AntiAliased ) + m_D3DDev->RSSetState(m_RasterStateAntialiased); + + // Reset shader globals + float offsetVec[4] = { 0, 0, 0, 0 }; + if( m_OffsetVar ) + m_OffsetVar->SetFloatVector(offsetVec); + float colorVec[4] = { 1, 1, 1, 1 }; + if( m_CstColorVar ) + m_CstColorVar->SetFloatVector(colorVec); + + // Set the input layout + m_D3DDev->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDev->IASetVertexBuffers(0, 1, &m_LineVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINELIST); + + // Render the line + D3D10_TECHNIQUE_DESC techDesc; + m_LineRectTech->GetDesc(&techDesc); + for(UINT p=0; pGetPassByIndex(p)->Apply(0); + m_D3DDev->Draw(2, 0); + } + + if( _AntiAliased ) + m_D3DDev->RSSetState(m_RasterState); // restore default raster state + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11) +{ + assert(m_Drawing==true); + + // border adjustment + if(_X0<_X1) + ++_X1; + else if(_X0>_X1) + ++_X0; + if(_Y0<_Y1) + ++_Y1; + else if(_Y0>_Y1) + ++_Y0; + + float x0 = ToNormScreenX(_X0 + m_OffsetX, m_WndWidth); + float y0 = ToNormScreenY(_Y0 + m_OffsetY, m_WndHeight); + float x1 = ToNormScreenX(_X1 + m_OffsetX, m_WndWidth); + float y1 = ToNormScreenY(_Y1 + m_OffsetY, m_WndHeight); + + CLineRectVtx *vertices = NULL; + HRESULT hr = m_RectVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void **)&vertices); + if( SUCCEEDED(hr) ) + { + // Fill vertex buffer + vertices[0].m_Pos[0] = x0; + vertices[0].m_Pos[1] = y0; + vertices[0].m_Pos[2] = 0; + vertices[0].m_Color = ToR8G8B8A8(_Color00); + vertices[1].m_Pos[0] = x1; + vertices[1].m_Pos[1] = y0; + vertices[1].m_Pos[2] = 0; + vertices[1].m_Color = ToR8G8B8A8(_Color10); + vertices[2].m_Pos[0] = x0; + vertices[2].m_Pos[1] = y1; + vertices[2].m_Pos[2] = 0; + vertices[2].m_Color = ToR8G8B8A8(_Color01); + vertices[3].m_Pos[0] = x1; + vertices[3].m_Pos[1] = y1; + vertices[3].m_Pos[2] = 0; + vertices[3].m_Color = ToR8G8B8A8(_Color11); + + m_RectVertexBuffer->Unmap(); + + // Reset shader globals + float offsetVec[4] = { 0, 0, 0, 0 }; + if( m_OffsetVar ) + m_OffsetVar->SetFloatVector(offsetVec); + float colorVec[4] = { 1, 1, 1, 1 }; + if( m_CstColorVar ) + m_CstColorVar->SetFloatVector(colorVec); + + // Set the input layout + m_D3DDev->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDev->IASetVertexBuffers(0, 1, &m_RectVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // Render the rect + D3D10_TECHNIQUE_DESC techDesc; + m_LineRectTech->GetDesc(&techDesc); + for(UINT p=0; pGetPassByIndex(p)->Apply(0); + m_D3DDev->Draw(4, 0); + } + } +} + +// --------------------------------------------------------------------------- + +void *CTwGraphDirect3D10::NewTextObj() +{ + CTextObj *textObj = new CTextObj; + memset(textObj, 0, sizeof(CTextObj)); + return textObj; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::DeleteTextObj(void *_TextObj) +{ + assert(_TextObj!=NULL); + CTextObj *textObj = static_cast(_TextObj); + if( textObj->m_TextVertexBuffer ) + textObj->m_TextVertexBuffer->Release(); + if( textObj->m_BgVertexBuffer ) + textObj->m_BgVertexBuffer->Release(); + memset(textObj, 0, sizeof(CTextObj)); + delete textObj; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + assert(_Font!=NULL); + + if( _Font != m_FontTex ) + { + UnbindFont(m_D3DDev, m_FontD3DResVar, m_FontD3DTexRV); + m_FontD3DTexRV = BindFont(m_D3DDev, m_FontD3DResVar, _Font); + m_FontTex = _Font; + } + + int nbTextVerts = 0; + int line; + for( line=0; line<_NbLines; ++line ) + nbTextVerts += 6 * (int)_TextLines[line].length(); + int nbBgVerts = 0; + if( _BgWidth>0 ) + nbBgVerts = _NbLines*6; + + CTextObj *textObj = static_cast(_TextObj); + textObj->m_LineColors = (_LineColors!=NULL); + textObj->m_LineBgColors = (_LineBgColors!=NULL); + + // (re)create text vertex buffer if needed, and map it + CTextVtx *textVerts = NULL; + if( nbTextVerts>0 ) + { + if( textObj->m_TextVertexBuffer==NULL || textObj->m_TextVertexBufferSizem_TextVertexBuffer!=NULL ) + { + ULONG rc = textObj->m_TextVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + textObj->m_TextVertexBuffer = NULL; + } + textObj->m_TextVertexBufferSize = nbTextVerts + 6*256; // add a reserve of 256 characters + D3D10_BUFFER_DESC bd; + bd.Usage = D3D10_USAGE_DYNAMIC; + bd.ByteWidth = textObj->m_TextVertexBufferSize * sizeof(CTextVtx); + bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + m_D3DDev->CreateBuffer(&bd, NULL, &textObj->m_TextVertexBuffer); + } + + if( textObj->m_TextVertexBuffer!=NULL ) + textObj->m_TextVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void **)&textVerts); + } + + // (re)create bg vertex buffer if needed, and map it + CLineRectVtx *bgVerts = NULL; + if( nbBgVerts>0 ) + { + if( textObj->m_BgVertexBuffer==NULL || textObj->m_BgVertexBufferSizem_BgVertexBuffer!=NULL ) + { + ULONG rc = textObj->m_BgVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + textObj->m_BgVertexBuffer = NULL; + } + textObj->m_BgVertexBufferSize = nbBgVerts + 6*32; // add a reserve of 32 rects + D3D10_BUFFER_DESC bd; + bd.Usage = D3D10_USAGE_DYNAMIC; + bd.ByteWidth = textObj->m_BgVertexBufferSize * sizeof(CLineRectVtx); + bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + m_D3DDev->CreateBuffer(&bd, NULL, &textObj->m_BgVertexBuffer); + } + + if( textObj->m_BgVertexBuffer!=NULL ) + textObj->m_BgVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void **)&bgVerts); + } + + int x, x1, y, y1, i, len; + float px, px1, py, py1; + unsigned char ch; + const unsigned char *text; + color32 lineColor = COLOR32_RED; + CTextVtx vtx; + vtx.m_Pos[2] = 0; + CLineRectVtx bgVtx; + bgVtx.m_Pos[2] = 0; + int textVtxIndex = 0; + int bgVtxIndex = 0; + for( line=0; line<_NbLines; ++line ) + { + x = 0; + y = line * (_Font->m_CharHeight+_Sep); + y1 = y+_Font->m_CharHeight; + len = (int)_TextLines[line].length(); + text = (const unsigned char *)(_TextLines[line].c_str()); + if( _LineColors!=NULL ) + lineColor = ToR8G8B8A8(_LineColors[line]); + + if( textVerts!=NULL ) + for( i=0; im_CharWidth[ch]; + + px = ToNormScreenX(x, m_WndWidth); + py = ToNormScreenY(y, m_WndHeight); + px1 = ToNormScreenX(x1, m_WndWidth); + py1 = ToNormScreenY(y1, m_WndHeight); + + vtx.m_Color = lineColor; + + vtx.m_Pos[0] = px; + vtx.m_Pos[1] = py; + vtx.m_UV [0] = _Font->m_CharU0[ch]; + vtx.m_UV [1] = _Font->m_CharV0[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px1; + vtx.m_Pos[1] = py; + vtx.m_UV [0] = _Font->m_CharU1[ch]; + vtx.m_UV [1] = _Font->m_CharV0[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px; + vtx.m_Pos[1] = py1; + vtx.m_UV [0] = _Font->m_CharU0[ch]; + vtx.m_UV [1] = _Font->m_CharV1[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px1; + vtx.m_Pos[1] = py; + vtx.m_UV [0] = _Font->m_CharU1[ch]; + vtx.m_UV [1] = _Font->m_CharV0[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px1; + vtx.m_Pos[1] = py1; + vtx.m_UV [0] = _Font->m_CharU1[ch]; + vtx.m_UV [1] = _Font->m_CharV1[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px; + vtx.m_Pos[1] = py1; + vtx.m_UV [0] = _Font->m_CharU0[ch]; + vtx.m_UV [1] = _Font->m_CharV1[ch]; + textVerts[textVtxIndex++] = vtx; + + x = x1; + } + + if( _BgWidth>0 && bgVerts!=NULL ) + { + if( _LineBgColors!=NULL ) + bgVtx.m_Color = ToR8G8B8A8(_LineBgColors[line]); + else + bgVtx.m_Color = ToR8G8B8A8(COLOR32_BLACK); + + px = ToNormScreenX(-1, m_WndWidth); + py = ToNormScreenY(y, m_WndHeight); + px1 = ToNormScreenX(_BgWidth+1, m_WndWidth); + py1 = ToNormScreenY(y1, m_WndHeight); + + bgVtx.m_Pos[0] = px; + bgVtx.m_Pos[1] = py; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px1; + bgVtx.m_Pos[1] = py; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px; + bgVtx.m_Pos[1] = py1; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px1; + bgVtx.m_Pos[1] = py; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px1; + bgVtx.m_Pos[1] = py1; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px; + bgVtx.m_Pos[1] = py1; + bgVerts[bgVtxIndex++] = bgVtx; + } + } + assert( textVtxIndex==nbTextVerts ); + assert( bgVtxIndex==nbBgVerts ); + textObj->m_NbTextVerts = nbTextVerts; + textObj->m_NbBgVerts = nbBgVerts; + + if( textVerts!=NULL ) + textObj->m_TextVertexBuffer->Unmap(); + if( bgVerts!=NULL ) + textObj->m_BgVertexBuffer->Unmap(); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + CTextObj *textObj = static_cast(_TextObj); + float dx = 2.0f*(float)(_X + m_OffsetX)/m_WndWidth; + float dy = -2.0f*(float)(_Y + m_OffsetY)/m_WndHeight; + + float offsetVec[4] = { 0, 0, 0, 0 }; + offsetVec[0] = dx; + offsetVec[1] = dy; + if( m_OffsetVar ) + m_OffsetVar->SetFloatVector(offsetVec); + + // Draw background + if( textObj->m_NbBgVerts>=4 && textObj->m_BgVertexBuffer!=NULL ) + { + float color[4]; + Color32ToARGBf(_BgColor, color+3, color+0, color+1, color+2); + if( m_CstColorVar ) + m_CstColorVar->SetFloatVector(color); + + // Set the input layout + m_D3DDev->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDev->IASetVertexBuffers(0, 1, &textObj->m_BgVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // Render the bg rectangles + ID3D10EffectTechnique *tech; + if( _BgColor!=0 || !textObj->m_LineBgColors ) // use a constant bg color + tech = m_LineRectCstColorTech; + else // use vertex buffer colors + tech = m_LineRectTech; + D3D10_TECHNIQUE_DESC techDesc; + tech->GetDesc(&techDesc); + for( UINT p=0; pGetPassByIndex(p)->Apply(0); + m_D3DDev->Draw(textObj->m_NbBgVerts, 0); + } + } + + // Draw text + if( textObj->m_NbTextVerts>=4 && textObj->m_TextVertexBuffer!=NULL ) + { + float color[4]; + Color32ToARGBf(_Color, color+3, color+0, color+1, color+2); + if( m_CstColorVar ) + m_CstColorVar->SetFloatVector(color); + + // Set the input layout + m_D3DDev->IASetInputLayout(m_TextVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CTextVtx); + UINT offset = 0; + m_D3DDev->IASetVertexBuffers(0, 1, &textObj->m_TextVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // Render text + ID3D10EffectTechnique *tech; + if( _Color!=0 || !textObj->m_LineColors ) // use a constant color + tech = m_TextCstColorTech; + else // use vertex buffer colors + tech = m_TextTech; + D3D10_TECHNIQUE_DESC techDesc; + tech->GetDesc(&techDesc); + for( UINT p=0; pGetPassByIndex(p)->Apply(0); + m_D3DDev->Draw(textObj->m_NbTextVerts, 0); + } + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY) +{ + if( _Width>0 && _Height>0 ) + { + /* viewport changes screen coordinates, use scissor instead + D3D10_VIEWPORT vp; + vp.TopLeftX = _X0; + vp.TopLeftY = _Y0; + vp.Width = _Width; + vp.Height = _Height; + vp.MinDepth = 0; + vp.MaxDepth = 1; + m_D3DDev->RSSetViewports(1, &vp); + */ + + m_ViewportAndScissorRects[0].left = _X0; + m_ViewportAndScissorRects[0].right = _X0 + _Width - 1; + m_ViewportAndScissorRects[0].top = _Y0; + m_ViewportAndScissorRects[0].bottom = _Y0 + _Height - 1; + if( RectIsFull(m_ViewportAndScissorRects[1]) ) + m_D3DDev->RSSetScissorRects(1, m_ViewportAndScissorRects); // viewport clipping only + else + m_D3DDev->RSSetScissorRects(2, m_ViewportAndScissorRects); + + m_OffsetX = _X0 + _OffsetX; + m_OffsetY = _Y0 + _OffsetY; + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::RestoreViewport() +{ + //m_D3DDev->RSSetViewports(1, static_cast(m_ViewportInit)); + m_ViewportAndScissorRects[0] = FullRect; + m_D3DDev->RSSetScissorRects(1, m_ViewportAndScissorRects+1); // scissor only + + m_OffsetX = m_OffsetY = 0; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::SetScissor(int _X0, int _Y0, int _Width, int _Height) +{ + if( _Width>0 && _Height>0 ) + { + m_ViewportAndScissorRects[1].left = _X0 - 2; + m_ViewportAndScissorRects[1].right = _X0 + _Width - 3; + m_ViewportAndScissorRects[1].top = _Y0 - 1; + m_ViewportAndScissorRects[1].bottom = _Y0 + _Height - 1; + if( RectIsFull(m_ViewportAndScissorRects[0]) ) + m_D3DDev->RSSetScissorRects(1, m_ViewportAndScissorRects+1); // no viewport clipping + else + m_D3DDev->RSSetScissorRects(2, m_ViewportAndScissorRects); + } + else + { + m_ViewportAndScissorRects[1] = FullRect; + m_D3DDev->RSSetScissorRects(1, m_ViewportAndScissorRects); // apply viewport clipping only + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D10::DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode) +{ + assert(m_Drawing==true); + + if( _NumTriangles<=0 ) + return; + + if( m_TrianglesVertexBufferCount<3*_NumTriangles ) // force re-creation + { + if( m_TrianglesVertexBuffer!=NULL ) + m_TrianglesVertexBuffer->Release(); + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + } + + // DrawTriangles uses LineRect layout and technique + + if( m_TrianglesVertexBuffer==NULL ) + { + // Create triangles vertex buffer + D3D10_BUFFER_DESC bd; + bd.Usage = D3D10_USAGE_DYNAMIC; + bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + bd.ByteWidth = 3*_NumTriangles * sizeof(CLineRectVtx); + HRESULT hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_TrianglesVertexBuffer); + if( SUCCEEDED(hr) ) + m_TrianglesVertexBufferCount = 3*_NumTriangles; + else + { + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + return; // Problem: cannot create triangles VB + } + } + assert( m_TrianglesVertexBufferCount>=3*_NumTriangles ); + assert( m_TrianglesVertexBuffer!=NULL ); + + CLineRectVtx *vertices = NULL; + HRESULT hr = m_TrianglesVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void **)&vertices); + if( SUCCEEDED(hr) ) + { + // Fill vertex buffer + for( int i=0; i<3*_NumTriangles; ++ i ) + { + vertices[i].m_Pos[0] = ToNormScreenX(_Vertices[2*i+0] + m_OffsetX, m_WndWidth); + vertices[i].m_Pos[1] = ToNormScreenY(_Vertices[2*i+1] + m_OffsetY, m_WndHeight); + vertices[i].m_Pos[2] = 0; + vertices[i].m_Color = ToR8G8B8A8(_Colors[i]); + } + m_TrianglesVertexBuffer->Unmap(); + + // Reset shader globals + float offsetVec[4] = { 0, 0, 0, 0 }; + if( m_OffsetVar ) + m_OffsetVar->SetFloatVector(offsetVec); + float colorVec[4] = { 1, 1, 1, 1 }; + if( m_CstColorVar ) + m_CstColorVar->SetFloatVector(colorVec); + + // Set the input layout + m_D3DDev->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDev->IASetVertexBuffers(0, 1, &m_TrianglesVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + if( _CullMode==CULL_CW ) + m_D3DDev->RSSetState(m_RasterStateCullCW); + else if( _CullMode==CULL_CCW ) + m_D3DDev->RSSetState(m_RasterStateCullCCW); + + // Render the triangles + D3D10_TECHNIQUE_DESC techDesc; + m_LineRectTech->GetDesc(&techDesc); + for(UINT p=0; pGetPassByIndex(p)->Apply(0); + m_D3DDev->Draw(3*_NumTriangles, 0); + } + + if( _CullMode==CULL_CW || _CullMode==CULL_CCW ) + m_D3DDev->RSSetState(m_RasterState); // restore default raster state + + // Unset vertex buffer + ID3D10Buffer *vb = NULL; + m_D3DDev->IASetVertexBuffers(0, 1, &vb, &stride, &offset); + } +} + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.h b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.h new file mode 100644 index 0000000..46e1f3d --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D10.h @@ -0,0 +1,108 @@ +// --------------------------------------------------------------------------- +// +// @file TwDirect3D10.h +// @brief Direct3D10 graph functions +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_DIRECT3D10_INCLUDED +#define ANT_TW_DIRECT3D10_INCLUDED + +#include "TwGraph.h" + +// --------------------------------------------------------------------------- + +class CTwGraphDirect3D10 : public ITwGraph +{ +public: + virtual int Init(); + virtual int Shut(); + virtual void BeginDraw(int _WndWidth, int _WndHeight); + virtual void EndDraw(); + virtual bool IsDrawing(); + virtual void Restore(); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased=false); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color, bool _AntiAliased=false) { DrawLine(_X0, _Y0, _X1, _Y1, _Color, _Color, _AntiAliased); } + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11); + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color) { DrawRect(_X0, _Y0, _X1, _Y1, _Color, _Color, _Color, _Color); } + virtual void DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode); + + virtual void * NewTextObj(); + virtual void DeleteTextObj(void *_TextObj); + virtual void BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth); + virtual void DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor); + + virtual void ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY); + virtual void RestoreViewport(); + virtual void SetScissor(int _X0, int _Y0, int _Width, int _Height); + +protected: + struct ID3D10Device * m_D3DDev; + unsigned int m_D3DDevInitialRefCount; + bool m_Drawing; + const CTexFont * m_FontTex; + struct ID3D10ShaderResourceView *m_FontD3DTexRV; + int m_WndWidth; + int m_WndHeight; + int m_OffsetX; + int m_OffsetY; + void * m_ViewportInit; + RECT m_ViewportAndScissorRects[2]; + + struct CLineRectVtx + { + float m_Pos[3]; + color32 m_Color; + }; + struct CTextVtx + { + float m_Pos[3]; + color32 m_Color; + float m_UV[2]; + }; + + struct CTextObj + { + struct ID3D10Buffer * m_TextVertexBuffer; + struct ID3D10Buffer * m_BgVertexBuffer; + int m_NbTextVerts; + int m_NbBgVerts; + int m_TextVertexBufferSize; + int m_BgVertexBufferSize; + bool m_LineColors; + bool m_LineBgColors; + }; + + struct CState10 * m_State; + struct ID3D10DepthStencilState *m_DepthStencilState; + struct ID3D10BlendState * m_BlendState; + struct ID3D10RasterizerState * m_RasterState; + struct ID3D10RasterizerState * m_RasterStateAntialiased; + struct ID3D10RasterizerState * m_RasterStateCullCW; + struct ID3D10RasterizerState * m_RasterStateCullCCW; + struct ID3D10Effect * m_Effect; + struct ID3D10EffectTechnique* m_LineRectTech; + struct ID3D10EffectTechnique* m_LineRectCstColorTech; + struct ID3D10InputLayout * m_LineRectVertexLayout; + struct ID3D10Buffer * m_LineVertexBuffer; + struct ID3D10Buffer * m_RectVertexBuffer; + struct ID3D10Buffer * m_TrianglesVertexBuffer; + int m_TrianglesVertexBufferCount; + struct ID3D10EffectTechnique* m_TextTech; + struct ID3D10EffectTechnique* m_TextCstColorTech; + struct ID3D10InputLayout * m_TextVertexLayout; + struct ID3D10EffectShaderResourceVariable *m_FontD3DResVar; + struct ID3D10EffectVectorVariable *m_OffsetVar; + struct ID3D10EffectVectorVariable *m_CstColorVar; +}; + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_DIRECT3D10_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.cpp new file mode 100644 index 0000000..ea86d74 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.cpp @@ -0,0 +1,1653 @@ +// --------------------------------------------------------------------------- +// +// @file TwDirect3D11.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "TwDirect3D11.h" +#include "TwMgr.h" +#include "TwColors.h" + +#include "d3d10vs2003.h" // Workaround to include D3D10.h and D3D11.h with VS2003 +#define D3D11_IGNORE_SDK_LAYERS // d3d11sdklayers.h may not exist +#include + + +using namespace std; + +const char *g_ErrCantLoadD3D11 = "Cannot load Direct3D11 library dynamically"; +const char *g_ErrCreateVS11 = "Direct3D11 vertex shader creation failed"; +const char *g_ErrCreatePS11 = "Direct3D11 pixel shader creation failed"; +const char *g_ErrCreateLayout11 = "Direct3D11 vertex layout creation failed"; +const char *g_ErrCreateBuffer11 = "Direct3D11 vertex buffer creation failed"; +const char *g_ErrCreateSampler11 = "Direct3D11 sampler state creation failed"; + +// --------------------------------------------------------------------------- +// Shaders : In order to avoid linkage with D3DX11 or D3DCompile libraries, +// vertex and pixel shaders are compiled offline in a pre-build step using +// the fxc.exe compiler (from the DirectX SDK Aug'09 or later) + +#ifdef _WIN64 +# ifdef _DEBUG +# include "debug64\TwDirect3D11_LineRectVS.h" +# include "debug64\TwDirect3D11_LineRectCstColorVS.h" +# include "debug64\TwDirect3D11_LineRectPS.h" +# include "debug64\TwDirect3D11_TextVS.h" +# include "debug64\TwDirect3D11_TextCstColorVS.h" +# include "debug64\TwDirect3D11_TextPS.h" +# else +# include "release64\TwDirect3D11_LineRectVS.h" +# include "release64\TwDirect3D11_LineRectCstColorVS.h" +# include "release64\TwDirect3D11_LineRectPS.h" +# include "release64\TwDirect3D11_TextVS.h" +# include "release64\TwDirect3D11_TextCstColorVS.h" +# include "release64\TwDirect3D11_TextPS.h" +# endif +#else +# ifdef _DEBUG +# include "debug32\TwDirect3D11_LineRectVS.h" +# include "debug32\TwDirect3D11_LineRectCstColorVS.h" +# include "debug32\TwDirect3D11_LineRectPS.h" +# include "debug32\TwDirect3D11_TextVS.h" +# include "debug32\TwDirect3D11_TextCstColorVS.h" +# include "debug32\TwDirect3D11_TextPS.h" +# else +# include "release32\TwDirect3D11_LineRectVS.h" +# include "release32\TwDirect3D11_LineRectCstColorVS.h" +# include "release32\TwDirect3D11_LineRectPS.h" +# include "release32\TwDirect3D11_TextVS.h" +# include "release32\TwDirect3D11_TextCstColorVS.h" +# include "release32\TwDirect3D11_TextPS.h" +# endif +#endif + +// --------------------------------------------------------------------------- + +const RECT FullRect = {0, 0, 16000, 16000}; +static bool RectIsFull(const RECT& r) { return r.left==FullRect.left && r.right==FullRect.right && r.top==FullRect.top && r.bottom==FullRect.bottom; } + +// --------------------------------------------------------------------------- + +static void BindFont(ID3D11Device *_Dev, const CTexFont *_Font, ID3D11Texture2D **_Tex, ID3D11ShaderResourceView **_TexRV) +{ + assert(_Font!=NULL); + *_Tex = NULL; + *_TexRV = NULL; + + int w = _Font->m_TexWidth; + int h = _Font->m_TexHeight; + color32 *font32 = new color32[w*h]; + color32 *p = font32; + for( int i=0; im_TexBytes[i]))<<24); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = w; + desc.Height = h; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_IMMUTABLE; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = font32; + data.SysMemPitch = w*sizeof(color32); + data.SysMemSlicePitch = 0; + + if( SUCCEEDED(_Dev->CreateTexture2D(&desc, &data, _Tex)) ) + _Dev->CreateShaderResourceView(*_Tex, NULL, _TexRV); + + delete[] font32; +} + +// --------------------------------------------------------------------------- + +static void UnbindFont(ID3D11Device *_Dev, ID3D11Texture2D *_Tex, ID3D11ShaderResourceView *_TexRV) +{ + (void)_Dev; + + if( _TexRV ) + { + ULONG rc = _TexRV->Release(); + assert( rc==0 ); (void)rc; + } + if( _Tex ) + { + ULONG rc = _Tex->Release(); + assert( rc==0 ); (void)rc; + } +} + +// --------------------------------------------------------------------------- + +struct CState11 +{ + ID3D11ComputeShader * m_CSShader; + ID3D11ClassInstance ** m_CSClassInstances; + UINT m_CSNumClassInstances; + ID3D11DomainShader * m_DSShader; + ID3D11ClassInstance ** m_DSClassInstances; + UINT m_DSNumClassInstances; + ID3D11GeometryShader * m_GSShader; + ID3D11ClassInstance ** m_GSClassInstances; + UINT m_GSNumClassInstances; + ID3D11HullShader * m_HSShader; + ID3D11ClassInstance ** m_HSClassInstances; + UINT m_HSNumClassInstances; + ID3D11PixelShader * m_PSShader; + ID3D11ClassInstance ** m_PSClassInstances; + UINT m_PSNumClassInstances; + ID3D11Buffer * m_PSConstantBuffer; // backup the first constant buffer only + ID3D11SamplerState * m_PSSampler; // backup the first sampler only + ID3D11ShaderResourceView*m_PSShaderResourceView; // backup the first shader resource only + ID3D11VertexShader * m_VSShader; + ID3D11ClassInstance ** m_VSClassInstances; + UINT m_VSNumClassInstances; + ID3D11Buffer * m_VSConstantBuffer; // backup the first constant buffer only + + ID3D11Buffer * m_IAIndexBuffer; + DXGI_FORMAT m_IAIndexBufferFormat; + UINT m_IAIndexBufferOffset; + ID3D11InputLayout * m_IAInputLayout; + D3D11_PRIMITIVE_TOPOLOGY m_IATopology; + ID3D11Buffer * m_IAVertexBuffer; // backup the first buffer only + UINT m_IAVertexBufferStride; + UINT m_IAVertexBufferOffset; + + ID3D11BlendState * m_OMBlendState; + FLOAT m_OMBlendFactor[4]; + UINT m_OMSampleMask; + ID3D11DepthStencilState*m_OMDepthStencilState; + UINT m_OMStencilRef; + + UINT m_RSScissorNumRects; + D3D11_RECT m_RSScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D11RasterizerState * m_RSRasterizerState; + UINT m_RSNumViewports; + D3D11_VIEWPORT m_RSViewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + + void Save(); + void Restore(); + void Release(); + CState11(ID3D11Device *_Dev, ID3D11DeviceContext *_ImmCtx); + ~CState11(); +private: + ID3D11Device * m_D3DDev; + ID3D11DeviceContext * m_D3DDevImmContext; +}; + +CState11::CState11(ID3D11Device *_Dev, ID3D11DeviceContext *_ImmCtx) +{ + ZeroMemory(this, sizeof(CState11)); + m_D3DDev = _Dev; + m_D3DDevImmContext = _ImmCtx; +} + +CState11::~CState11() +{ + Release(); + m_D3DDev = NULL; + m_D3DDevImmContext = NULL; +} + +void CState11::Save() +{ + // Release previous state if needed + Release(); + + // Save shaders. + // Not sure how xxGetShader works, D3D11 doc is evasive... Attempt: + // First call GetShader with NULL ClassInstances to get the number of class instances. + // Second, if not zero allocate an array of class instances and call GetShader again + // with this array ptr to get the class instances and release the shader since its + // ref count has been incremented a second time. + + m_CSShader = NULL; + m_CSClassInstances = NULL; + m_CSNumClassInstances = 0; + m_D3DDevImmContext->CSGetShader(&m_CSShader, NULL, &m_CSNumClassInstances); + if (m_CSNumClassInstances > 0) + { + m_CSClassInstances = new ID3D11ClassInstance*[m_CSNumClassInstances]; + for (UINT i = 0; i < m_CSNumClassInstances; i++) + m_CSClassInstances[i] = NULL; + m_D3DDevImmContext->CSGetShader(&m_CSShader, m_CSClassInstances, &m_CSNumClassInstances); + if (m_CSShader != NULL) + m_CSShader->Release(); + } + + m_DSShader = NULL; + m_DSClassInstances = NULL; + m_DSNumClassInstances = 0; + m_D3DDevImmContext->DSGetShader(&m_DSShader, NULL, &m_DSNumClassInstances); + if (m_DSNumClassInstances > 0) + { + m_DSClassInstances = new ID3D11ClassInstance*[m_DSNumClassInstances]; + for (UINT i = 0; i < m_DSNumClassInstances; i++) + m_DSClassInstances[i] = NULL; + m_D3DDevImmContext->DSGetShader(&m_DSShader, m_DSClassInstances, &m_DSNumClassInstances); + if (m_DSShader != NULL) + m_DSShader->Release(); + } + + m_GSShader = NULL; + m_GSClassInstances = NULL; + m_GSNumClassInstances = 0; + m_D3DDevImmContext->GSGetShader(&m_GSShader, NULL, &m_GSNumClassInstances); + if (m_GSNumClassInstances > 0) + { + m_GSClassInstances = new ID3D11ClassInstance*[m_GSNumClassInstances]; + for (UINT i = 0; i < m_GSNumClassInstances; i++) + m_GSClassInstances[i] = NULL; + m_D3DDevImmContext->GSGetShader(&m_GSShader, m_GSClassInstances, &m_GSNumClassInstances); + if (m_GSShader != NULL) + m_GSShader->Release(); + } + + m_HSShader = NULL; + m_HSClassInstances = NULL; + m_HSNumClassInstances = 0; + m_D3DDevImmContext->HSGetShader(&m_HSShader, NULL, &m_HSNumClassInstances); + if (m_HSNumClassInstances > 0) + { + m_HSClassInstances = new ID3D11ClassInstance*[m_HSNumClassInstances]; + for (UINT i = 0; i < m_HSNumClassInstances; i++) + m_HSClassInstances[i] = NULL; + m_D3DDevImmContext->HSGetShader(&m_HSShader, m_HSClassInstances, &m_HSNumClassInstances); + if (m_HSShader != NULL) + m_HSShader->Release(); + } + + m_PSShader = NULL; + m_PSClassInstances = NULL; + m_PSNumClassInstances = 0; + m_D3DDevImmContext->PSGetShader(&m_PSShader, NULL, &m_PSNumClassInstances); + if (m_PSNumClassInstances > 0) + { + m_PSClassInstances = new ID3D11ClassInstance*[m_PSNumClassInstances]; + for (UINT i = 0; i < m_PSNumClassInstances; i++) + m_PSClassInstances[i] = NULL; + m_D3DDevImmContext->PSGetShader(&m_PSShader, m_PSClassInstances, &m_PSNumClassInstances); + if (m_PSShader != NULL) + m_PSShader->Release(); + } + m_D3DDevImmContext->PSGetConstantBuffers(0, 1, &m_PSConstantBuffer); + m_D3DDevImmContext->PSGetSamplers(0, 1, &m_PSSampler); + m_D3DDevImmContext->PSGetShaderResources(0, 1, &m_PSShaderResourceView); + + m_VSShader = NULL; + m_VSClassInstances = NULL; + m_VSNumClassInstances = 0; + m_D3DDevImmContext->VSGetShader(&m_VSShader, NULL, &m_VSNumClassInstances); + if (m_VSNumClassInstances > 0) + { + m_VSClassInstances = new ID3D11ClassInstance*[m_VSNumClassInstances]; + for (UINT i = 0; i < m_VSNumClassInstances; i++) + m_VSClassInstances[i] = NULL; + m_D3DDevImmContext->VSGetShader(&m_VSShader, m_VSClassInstances, &m_VSNumClassInstances); + if (m_VSShader != NULL) + m_VSShader->Release(); + } + m_D3DDevImmContext->VSGetConstantBuffers(0, 1, &m_VSConstantBuffer); + + // Save Input-Assembler states + m_D3DDevImmContext->IAGetIndexBuffer(&m_IAIndexBuffer, &m_IAIndexBufferFormat, &m_IAIndexBufferOffset); + m_D3DDevImmContext->IAGetInputLayout(&m_IAInputLayout); + m_D3DDevImmContext->IAGetPrimitiveTopology(&m_IATopology); + m_D3DDevImmContext->IAGetVertexBuffers(0, 1, &m_IAVertexBuffer, &m_IAVertexBufferStride, &m_IAVertexBufferOffset); + + // Save Ouput-Merger states + m_D3DDevImmContext->OMGetBlendState(&m_OMBlendState, m_OMBlendFactor, &m_OMSampleMask); + m_D3DDevImmContext->OMGetDepthStencilState(&m_OMDepthStencilState, &m_OMStencilRef); + + // Save Rasterizer states + m_D3DDevImmContext->RSGetScissorRects(&m_RSScissorNumRects, NULL); + if (m_RSScissorNumRects > 0) + m_D3DDevImmContext->RSGetScissorRects(&m_RSScissorNumRects, m_RSScissorRects); + m_D3DDevImmContext->RSGetViewports(&m_RSNumViewports, NULL); + if (m_RSNumViewports > 0) + m_D3DDevImmContext->RSGetViewports(&m_RSNumViewports, m_RSViewports); + m_D3DDevImmContext->RSGetState(&m_RSRasterizerState); +} + +void CState11::Restore() +{ + // Restore shaders + m_D3DDevImmContext->CSSetShader(m_CSShader, m_CSClassInstances, m_CSNumClassInstances); + m_D3DDevImmContext->DSSetShader(m_DSShader, m_DSClassInstances, m_DSNumClassInstances); + m_D3DDevImmContext->GSSetShader(m_GSShader, m_GSClassInstances, m_GSNumClassInstances); + m_D3DDevImmContext->HSSetShader(m_HSShader, m_HSClassInstances, m_HSNumClassInstances); + m_D3DDevImmContext->PSSetShader(m_PSShader, m_PSClassInstances, m_PSNumClassInstances); + m_D3DDevImmContext->PSSetConstantBuffers(0, 1, &m_PSConstantBuffer); + m_D3DDevImmContext->PSSetSamplers(0, 1, &m_PSSampler); + m_D3DDevImmContext->PSSetShaderResources(0, 1, &m_PSShaderResourceView); + m_D3DDevImmContext->VSSetShader(m_VSShader, m_VSClassInstances, m_VSNumClassInstances); + m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_VSConstantBuffer); + + // Restore Input-Assembler + m_D3DDevImmContext->IASetIndexBuffer(m_IAIndexBuffer, m_IAIndexBufferFormat, m_IAIndexBufferOffset); + m_D3DDevImmContext->IASetInputLayout(m_IAInputLayout); + m_D3DDevImmContext->IASetPrimitiveTopology(m_IATopology); + m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_IAVertexBuffer, &m_IAVertexBufferStride, &m_IAVertexBufferOffset); + + // Restore Ouput-Merger + m_D3DDevImmContext->OMSetBlendState(m_OMBlendState, m_OMBlendFactor, m_OMSampleMask); + m_D3DDevImmContext->OMSetDepthStencilState(m_OMDepthStencilState, m_OMStencilRef); + + // Restore Rasterizer states + m_D3DDevImmContext->RSSetScissorRects(m_RSScissorNumRects, m_RSScissorRects); + m_D3DDevImmContext->RSSetViewports(m_RSNumViewports, m_RSViewports); + m_D3DDevImmContext->RSSetState(m_RSRasterizerState); +} + +void CState11::Release() +{ + // Release stored shaders + + if (m_CSClassInstances != NULL) + { + for (UINT i = 0; i < m_CSNumClassInstances; i++) + if (m_CSClassInstances[i] != NULL) + m_CSClassInstances[i]->Release(); + delete[] m_CSClassInstances; + m_CSClassInstances = NULL; + m_CSNumClassInstances = 0; + } + if (m_CSShader != NULL) + { + m_CSShader->Release(); + m_CSShader = NULL; + } + + if (m_DSClassInstances != NULL) + { + for (UINT i = 0; i < m_DSNumClassInstances; i++) + if (m_DSClassInstances[i] != NULL) + m_DSClassInstances[i]->Release(); + delete[] m_DSClassInstances; + m_DSClassInstances = NULL; + m_DSNumClassInstances = 0; + } + if (m_DSShader != NULL) + { + m_DSShader->Release(); + m_DSShader = NULL; + } + + if (m_GSClassInstances != NULL) + { + for (UINT i = 0; i < m_GSNumClassInstances; i++) + if (m_GSClassInstances[i] != NULL) + m_GSClassInstances[i]->Release(); + delete[] m_GSClassInstances; + m_GSClassInstances = NULL; + m_GSNumClassInstances = 0; + } + if (m_GSShader != NULL) + { + m_GSShader->Release(); + m_GSShader = NULL; + } + + if (m_HSClassInstances != NULL) + { + for (UINT i = 0; i < m_HSNumClassInstances; i++) + if (m_HSClassInstances[i] != NULL) + m_HSClassInstances[i]->Release(); + delete[] m_HSClassInstances; + m_HSClassInstances = NULL; + m_HSNumClassInstances = 0; + } + if (m_HSShader != NULL) + { + m_HSShader->Release(); + m_HSShader = NULL; + } + + if (m_PSClassInstances != NULL) + { + for (UINT i = 0; i < m_PSNumClassInstances; i++) + if (m_PSClassInstances[i] != NULL) + m_PSClassInstances[i]->Release(); + delete[] m_PSClassInstances; + m_PSClassInstances = NULL; + m_PSNumClassInstances = 0; + } + if (m_PSShader != NULL) + { + m_PSShader->Release(); + m_PSShader = NULL; + } + if (m_PSConstantBuffer != NULL) + { + m_PSConstantBuffer->Release(); + m_PSConstantBuffer = NULL; + } + if (m_PSSampler != NULL) + { + m_PSSampler->Release(); + m_PSSampler = NULL; + } + if (m_PSShaderResourceView != NULL) + { + m_PSShaderResourceView->Release(); + m_PSShaderResourceView = NULL; + } + + if (m_VSClassInstances != NULL) + { + for (UINT i = 0; i < m_VSNumClassInstances; i++) + if (m_VSClassInstances[i] != NULL) + m_VSClassInstances[i]->Release(); + delete[] m_VSClassInstances; + m_VSClassInstances = NULL; + m_VSNumClassInstances = 0; + } + if (m_VSShader != NULL) + { + m_VSShader->Release(); + m_VSShader = NULL; + } + if (m_VSConstantBuffer != NULL) + { + m_VSConstantBuffer->Release(); + m_VSConstantBuffer = NULL; + } + + // Release Input-Assembler states + if (m_IAIndexBuffer != NULL) + { + m_IAIndexBuffer->Release(); + m_IAIndexBuffer = NULL; + } + if (m_IAInputLayout != NULL) + { + m_IAInputLayout->Release(); + m_IAInputLayout = 0; + } + if (m_IAVertexBuffer != NULL) + { + m_IAVertexBuffer->Release(); + m_IAVertexBuffer = NULL; + } + + // Release Output-Merger states + if (m_OMBlendState != NULL) + { + m_OMBlendState->Release(); + m_OMBlendState = NULL; + } + if (m_OMDepthStencilState != NULL) + { + m_OMDepthStencilState->Release(); + m_OMDepthStencilState = NULL; + } + + // Release Rasterizer state + if (m_RSRasterizerState != 0) + { + m_RSRasterizerState->Release(); + m_RSRasterizerState = NULL; + } + m_RSNumViewports = 0; + m_RSScissorNumRects = 0; +} + +// --------------------------------------------------------------------------- + +int CTwGraphDirect3D11::Init() +{ + assert(g_TwMgr!=NULL); + assert(g_TwMgr->m_Device!=NULL); + + m_D3DDev = static_cast(g_TwMgr->m_Device); + m_D3DDevInitialRefCount = m_D3DDev->AddRef() - 1; + m_D3DDev->GetImmediateContext(&m_D3DDevImmContext); + + m_Drawing = false; + m_OffsetX = m_OffsetY = 0; + m_ViewportInit = new D3D11_VIEWPORT; + m_FontTex = NULL; + m_FontD3DTex = NULL; + m_FontD3DTexRV = NULL; + m_WndWidth = 0; + m_WndHeight = 0; + m_State = NULL; + m_DepthStencilState = NULL; + m_BlendState = NULL; + m_RasterState = NULL; + m_RasterStateAntialiased = NULL; + m_RasterStateMultisample = NULL; + m_RasterStateCullCW = NULL; + m_RasterStateCullCCW = NULL; + m_LineRectVS = NULL; + m_LineRectCstColorVS = NULL; + m_LineRectPS = NULL; + m_LineRectVertexLayout = NULL; + m_TextVS = NULL; + m_TextCstColorVS = NULL; + m_TextPS = NULL; + m_TextVertexLayout = NULL; + m_LineVertexBuffer = NULL; + m_RectVertexBuffer = NULL; + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + m_ConstantBuffer = NULL; + m_SamplerState = NULL; + + // Allocate state object + m_State = new CState11(m_D3DDev, m_D3DDevImmContext); + + // Disable client shaders + m_D3DDevImmContext->CSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->DSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->GSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->HSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->PSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->VSSetShader(NULL, NULL, 0); + + // Create shaders + HRESULT hr = m_D3DDev->CreateVertexShader(g_LineRectVS, sizeof(g_LineRectVS), NULL, &m_LineRectVS); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateVS11); + Shut(); + return 0; + } + hr = m_D3DDev->CreateVertexShader(g_LineRectCstColorVS, sizeof(g_LineRectCstColorVS), NULL, &m_LineRectCstColorVS); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateVS11); + Shut(); + return 0; + } + hr = m_D3DDev->CreatePixelShader(g_LineRectPS, sizeof(g_LineRectPS), NULL, &m_LineRectPS); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreatePS11); + Shut(); + return 0; + } + hr = m_D3DDev->CreateVertexShader(g_TextVS, sizeof(g_TextVS), NULL, &m_TextVS); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateVS11); + Shut(); + return 0; + } + hr = m_D3DDev->CreateVertexShader(g_TextCstColorVS, sizeof(g_TextCstColorVS), NULL, &m_TextCstColorVS); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateVS11); + Shut(); + return 0; + } + hr = m_D3DDev->CreatePixelShader(g_TextPS, sizeof(g_TextPS), NULL, &m_TextPS); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreatePS11); + Shut(); + return 0; + } + + // Create input layout for lines & rect + D3D11_INPUT_ELEMENT_DESC lineRectLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(CLineRectVtx, m_Color), D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + hr = m_D3DDev->CreateInputLayout(lineRectLayout, sizeof(lineRectLayout)/sizeof(lineRectLayout[0]), g_LineRectVS, sizeof(g_LineRectVS), &m_LineRectVertexLayout); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateLayout11); + Shut(); + return 0; + } + + // Create line vertex buffer + D3D11_BUFFER_DESC bd; + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.ByteWidth = 2 * sizeof(CLineRectVtx); + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + bd.StructureByteStride = 0; + hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_LineVertexBuffer); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateBuffer11); + Shut(); + return 0; + } + + // Create rect vertex buffer + bd.ByteWidth = 4 * sizeof(CLineRectVtx); + hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_RectVertexBuffer); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateBuffer11); + Shut(); + return 0; + } + + // Create constant buffer + bd.ByteWidth = sizeof(CConstants); + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_ConstantBuffer); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateBuffer11); + Shut(); + return 0; + } + + // Create sampler + D3D11_SAMPLER_DESC sd; + sd.AddressU = sd.AddressV = sd.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; + sd.BorderColor[0] = sd.BorderColor[1] = sd.BorderColor[2] = sd.BorderColor[3] = 0; + sd.ComparisonFunc = D3D11_COMPARISON_NEVER; + sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + sd.MaxAnisotropy = 1; + sd.MaxLOD = sd.MinLOD = 0; + sd.MipLODBias = 0; + hr = m_D3DDev->CreateSamplerState(&sd, &m_SamplerState); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateSampler11); + Shut(); + return 0; + } + + // Create input layout for text + D3D11_INPUT_ELEMENT_DESC textLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(CTextVtx, m_Color), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(CTextVtx, m_UV), D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + hr = m_D3DDev->CreateInputLayout(textLayout, sizeof(textLayout)/sizeof(textLayout[0]), g_TextVS, sizeof(g_TextVS), &m_TextVertexLayout); + if( FAILED(hr) ) + { + g_TwMgr->SetLastError(g_ErrCreateLayout11); + Shut(); + return 0; + } + + // Create depth stencil state object + D3D11_DEPTH_STENCILOP_DESC od; + od.StencilFunc = D3D11_COMPARISON_ALWAYS; + od.StencilFailOp = D3D11_STENCIL_OP_KEEP; + od.StencilPassOp = D3D11_STENCIL_OP_KEEP; + od.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + D3D11_DEPTH_STENCIL_DESC dsd; + dsd.DepthEnable = FALSE; + dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + dsd.DepthFunc = D3D11_COMPARISON_ALWAYS; + dsd.StencilEnable = FALSE; + dsd.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + dsd.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + dsd.FrontFace = od; + dsd.BackFace = od; + m_D3DDev->CreateDepthStencilState(&dsd, &m_DepthStencilState); + + // Create blend state object + D3D11_BLEND_DESC bsd; + bsd.AlphaToCoverageEnable = FALSE; + bsd.IndependentBlendEnable = FALSE; + for(int i=0; i<8; ++i) + { + bsd.RenderTarget[i].BlendEnable = TRUE; + bsd.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + bsd.RenderTarget[i].SrcBlend = D3D11_BLEND_SRC_ALPHA; + bsd.RenderTarget[i].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + bsd.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD; + bsd.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + bsd.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + bsd.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; + } + m_D3DDev->CreateBlendState(&bsd, &m_BlendState); + + // Create rasterizer state object + D3D11_RASTERIZER_DESC rd; + rd.FillMode = D3D11_FILL_SOLID; + rd.CullMode = D3D11_CULL_NONE; + rd.FrontCounterClockwise = true; + rd.DepthBias = false; + rd.DepthBiasClamp = 0; + rd.SlopeScaledDepthBias = 0; + rd.DepthClipEnable = false; + rd.ScissorEnable = true; + rd.MultisampleEnable = false; // do not allow msaa (fonts would be degraded) + rd.AntialiasedLineEnable = false; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterState); + + rd.AntialiasedLineEnable = true; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateAntialiased); + rd.AntialiasedLineEnable = false; + + // the three following raster states allow msaa + rd.MultisampleEnable = true; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateMultisample); + + rd.CullMode = D3D11_CULL_BACK; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateCullCW); + + rd.CullMode = D3D11_CULL_FRONT; + m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateCullCCW); + + return 1; +} + +// --------------------------------------------------------------------------- + +int CTwGraphDirect3D11::Shut() +{ + assert(m_Drawing==false); + + UnbindFont(m_D3DDev, m_FontD3DTex, m_FontD3DTexRV); + m_FontD3DTex = NULL; + m_FontD3DTexRV = NULL; + if( m_State ) + { + delete m_State; + m_State = NULL; + } + if( m_ViewportInit ) + { + delete m_ViewportInit; + m_ViewportInit = NULL; + } + + if( m_DepthStencilState ) + { + ULONG rc = m_DepthStencilState->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_DepthStencilState = NULL; + } + if( m_BlendState ) + { + ULONG rc = m_BlendState->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_BlendState = NULL; + } + if( m_RasterState ) + { + ULONG rc = m_RasterState->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterState = NULL; + } + if( m_RasterStateAntialiased ) + { + ULONG rc = m_RasterStateAntialiased->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterStateAntialiased = NULL; + } + if( m_RasterStateMultisample ) + { + ULONG rc = m_RasterStateMultisample->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterStateMultisample = NULL; + } + if( m_RasterStateCullCW ) + { + ULONG rc = m_RasterStateCullCW->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterStateCullCW = NULL; + } + if( m_RasterStateCullCCW ) + { + ULONG rc = m_RasterStateCullCCW->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_RasterStateCullCCW = NULL; + } + if( m_SamplerState ) + { + ULONG rc = m_SamplerState->Release(); + //assert( rc==0 ); // no assert: the client can use a similar (then shared) state + (void)rc; + m_SamplerState = NULL; + } + + if( m_LineRectVS ) + { + ULONG rc = m_LineRectVS->Release(); + assert( rc==0 ); (void)rc; + m_LineRectVS = NULL; + } + if( m_LineRectCstColorVS ) + { + ULONG rc = m_LineRectCstColorVS->Release(); + assert( rc==0 ); (void)rc; + m_LineRectCstColorVS = NULL; + } + if( m_LineRectPS ) + { + ULONG rc = m_LineRectPS->Release(); + assert( rc==0 ); (void)rc; + m_LineRectPS = NULL; + } + if( m_TextVS ) + { + ULONG rc = m_TextVS->Release(); + assert( rc==0 ); (void)rc; + m_TextVS = NULL; + } + if( m_TextCstColorVS ) + { + ULONG rc = m_TextCstColorVS->Release(); + assert( rc==0 ); (void)rc; + m_TextCstColorVS = NULL; + } + if( m_TextPS ) + { + ULONG rc = m_TextPS->Release(); + assert( rc==0 ); (void)rc; + m_TextPS = NULL; + } + if( m_LineVertexBuffer ) + { + ULONG rc = m_LineVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + m_LineVertexBuffer = NULL; + } + if( m_RectVertexBuffer ) + { + ULONG rc = m_RectVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + m_RectVertexBuffer = NULL; + } + if( m_TrianglesVertexBuffer ) + { + ULONG rc = m_TrianglesVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + } + if( m_ConstantBuffer ) + { + ULONG rc = m_ConstantBuffer->Release(); + assert( rc==0 ); (void)rc; + m_ConstantBuffer = NULL; + } + if( m_LineRectVertexLayout ) + { + ULONG rc = m_LineRectVertexLayout->Release(); + assert( rc==0 ); (void)rc; + m_LineRectVertexLayout = NULL; + } + if( m_TextVertexLayout ) + { + ULONG rc = m_TextVertexLayout->Release(); + assert( rc==0 ); (void)rc; + m_TextVertexLayout = NULL; + } + + if( m_D3DDevImmContext ) + { + m_D3DDevImmContext->Release(); + m_D3DDevImmContext = NULL; + } + + if( m_D3DDev ) + { + //unsigned int rc = m_D3DDev->Release(); + //assert( m_D3DDevInitialRefCount==rc ); (void)rc; + m_D3DDev->Release(); + m_D3DDev = NULL; + } + + return 1; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::BeginDraw(int _WndWidth, int _WndHeight) +{ + assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0); + m_Drawing = true; + + m_WndWidth = _WndWidth; + m_WndHeight = _WndHeight; + m_OffsetX = m_OffsetY = 0; + + // save client context state + m_State->Save(); + + // Setup the viewport + D3D11_VIEWPORT vp; + vp.Width = (FLOAT)_WndWidth; + vp.Height = (FLOAT)_WndHeight; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = 0; + vp.TopLeftY = 0; + m_D3DDevImmContext->RSSetViewports(1, &vp); + *static_cast(m_ViewportInit) = vp; + + m_ViewportAndScissorRects[0] = FullRect; + m_ViewportAndScissorRects[1] = FullRect; + m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects); + + m_D3DDevImmContext->RSSetState(m_RasterState); + + m_D3DDevImmContext->OMSetDepthStencilState(m_DepthStencilState, 0); + float blendFactors[4] = { 1, 1, 1, 1 }; + m_D3DDevImmContext->OMSetBlendState(m_BlendState, blendFactors, 0xffffffff); + + m_D3DDevImmContext->CSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->DSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->GSSetShader(NULL, NULL, 0); + m_D3DDevImmContext->HSSetShader(NULL, NULL, 0); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::EndDraw() +{ + m_D3DDevImmContext->RSSetState(NULL); + m_D3DDevImmContext->OMSetDepthStencilState(NULL, 0); + m_D3DDevImmContext->OMSetBlendState(NULL, NULL, 0xffffffff); + + assert(m_Drawing==true); + m_Drawing = false; + + // restore and release client context state + m_State->Restore(); + m_State->Release(); +} + +// --------------------------------------------------------------------------- + +bool CTwGraphDirect3D11::IsDrawing() +{ + return m_Drawing; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::Restore() +{ + if( m_State ) + m_State->Release(); + + UnbindFont(m_D3DDev, m_FontD3DTex, m_FontD3DTexRV); + m_FontD3DTexRV = NULL; + m_FontD3DTex = NULL; + + m_FontTex = NULL; +} + +// --------------------------------------------------------------------------- + +static inline float ToNormScreenX(int x, int wndWidth) +{ + return 2.0f*((float)x-0.5f)/wndWidth - 1.0f; +} + +static inline float ToNormScreenY(int y, int wndHeight) +{ + return 1.0f - 2.0f*((float)y-0.5f)/wndHeight; +} + +static inline color32 ToR8G8B8A8(color32 col) +{ + return (col & 0xff00ff00) | ((col>>16) & 0xff) | ((col<<16) & 0xff0000); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased) +{ + assert(m_Drawing==true); + + float x0 = ToNormScreenX(_X0 + m_OffsetX, m_WndWidth); + float y0 = ToNormScreenY(_Y0 + m_OffsetY, m_WndHeight); + float x1 = ToNormScreenX(_X1 + m_OffsetX, m_WndWidth); + float y1 = ToNormScreenY(_Y1 + m_OffsetY, m_WndHeight); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = m_D3DDevImmContext->Map(m_LineVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CLineRectVtx *vertices = (CLineRectVtx *)mappedResource.pData; + // Fill vertex buffer + vertices[0].m_Pos[0] = x0; + vertices[0].m_Pos[1] = y0; + vertices[0].m_Pos[2] = 0; + vertices[0].m_Color = ToR8G8B8A8(_Color0); + vertices[1].m_Pos[0] = x1; + vertices[1].m_Pos[1] = y1; + vertices[1].m_Pos[2] = 0; + vertices[1].m_Color = ToR8G8B8A8(_Color1); + + m_D3DDevImmContext->Unmap(m_LineVertexBuffer, 0); + + if( _AntiAliased ) + m_D3DDevImmContext->RSSetState(m_RasterStateAntialiased); + + // Reset shader constants + hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CConstants *constants = (CConstants *)mappedResource.pData; + constants->m_Offset[0] = 0; + constants->m_Offset[1] = 0; + constants->m_Offset[2] = 0; + constants->m_Offset[3] = 0; + constants->m_CstColor[0] = 1; + constants->m_CstColor[1] = 1; + constants->m_CstColor[2] = 1; + constants->m_CstColor[3] = 1; + + m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0); + } + + // Set the input layout + m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_LineVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + + // Render the line + m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer); + m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0); + m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0); + m_D3DDevImmContext->Draw(2, 0); + + if( _AntiAliased ) + m_D3DDevImmContext->RSSetState(m_RasterState); // restore default raster state + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11) +{ + assert(m_Drawing==true); + + // border adjustment + if(_X0<_X1) + ++_X1; + else if(_X0>_X1) + ++_X0; + if(_Y0<_Y1) + ++_Y1; + else if(_Y0>_Y1) + ++_Y0; + + float x0 = ToNormScreenX(_X0 + m_OffsetX, m_WndWidth); + float y0 = ToNormScreenY(_Y0 + m_OffsetY, m_WndHeight); + float x1 = ToNormScreenX(_X1 + m_OffsetX, m_WndWidth); + float y1 = ToNormScreenY(_Y1 + m_OffsetY, m_WndHeight); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = m_D3DDevImmContext->Map(m_RectVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CLineRectVtx *vertices = (CLineRectVtx *)mappedResource.pData; + // Fill vertex buffer + vertices[0].m_Pos[0] = x0; + vertices[0].m_Pos[1] = y0; + vertices[0].m_Pos[2] = 0; + vertices[0].m_Color = ToR8G8B8A8(_Color00); + vertices[1].m_Pos[0] = x1; + vertices[1].m_Pos[1] = y0; + vertices[1].m_Pos[2] = 0; + vertices[1].m_Color = ToR8G8B8A8(_Color10); + vertices[2].m_Pos[0] = x0; + vertices[2].m_Pos[1] = y1; + vertices[2].m_Pos[2] = 0; + vertices[2].m_Color = ToR8G8B8A8(_Color01); + vertices[3].m_Pos[0] = x1; + vertices[3].m_Pos[1] = y1; + vertices[3].m_Pos[2] = 0; + vertices[3].m_Color = ToR8G8B8A8(_Color11); + + m_D3DDevImmContext->Unmap(m_RectVertexBuffer, 0); + + // Reset shader constants + hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CConstants *constants = (CConstants *)mappedResource.pData; + constants->m_Offset[0] = 0; + constants->m_Offset[1] = 0; + constants->m_Offset[2] = 0; + constants->m_Offset[3] = 0; + constants->m_CstColor[0] = 1; + constants->m_CstColor[1] = 1; + constants->m_CstColor[2] = 1; + constants->m_CstColor[3] = 1; + + m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0); + } + + // Set the input layout + m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_RectVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // Render the rect + m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer); + m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0); + m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0); + m_D3DDevImmContext->Draw(4, 0); + } +} + +// --------------------------------------------------------------------------- + +void *CTwGraphDirect3D11::NewTextObj() +{ + CTextObj *textObj = new CTextObj; + memset(textObj, 0, sizeof(CTextObj)); + return textObj; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::DeleteTextObj(void *_TextObj) +{ + assert(_TextObj!=NULL); + CTextObj *textObj = static_cast(_TextObj); + if( textObj->m_TextVertexBuffer ) + textObj->m_TextVertexBuffer->Release(); + if( textObj->m_BgVertexBuffer ) + textObj->m_BgVertexBuffer->Release(); + memset(textObj, 0, sizeof(CTextObj)); + delete textObj; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + assert(_Font!=NULL); + + if( _Font != m_FontTex ) + { + UnbindFont(m_D3DDev, m_FontD3DTex, m_FontD3DTexRV); + BindFont(m_D3DDev, _Font, &m_FontD3DTex, &m_FontD3DTexRV); + m_FontTex = _Font; + } + + int nbTextVerts = 0; + int line; + for( line=0; line<_NbLines; ++line ) + nbTextVerts += 6 * (int)_TextLines[line].length(); + int nbBgVerts = 0; + if( _BgWidth>0 ) + nbBgVerts = _NbLines*6; + + CTextObj *textObj = static_cast(_TextObj); + textObj->m_LineColors = (_LineColors!=NULL); + textObj->m_LineBgColors = (_LineBgColors!=NULL); + + // (re)create text vertex buffer if needed, and map it + CTextVtx *textVerts = NULL; + if( nbTextVerts>0 ) + { + if( textObj->m_TextVertexBuffer==NULL || textObj->m_TextVertexBufferSizem_TextVertexBuffer!=NULL ) + { + ULONG rc = textObj->m_TextVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + textObj->m_TextVertexBuffer = NULL; + } + textObj->m_TextVertexBufferSize = nbTextVerts + 6*256; // add a reserve of 256 characters + D3D11_BUFFER_DESC bd; + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.ByteWidth = textObj->m_TextVertexBufferSize * sizeof(CTextVtx); + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + bd.StructureByteStride = 0; + m_D3DDev->CreateBuffer(&bd, NULL, &textObj->m_TextVertexBuffer); + } + + if( textObj->m_TextVertexBuffer!=NULL ) + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + m_D3DDevImmContext->Map(textObj->m_TextVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + textVerts = (CTextVtx *)mappedResource.pData; + } + } + + // (re)create bg vertex buffer if needed, and map it + CLineRectVtx *bgVerts = NULL; + if( nbBgVerts>0 ) + { + if( textObj->m_BgVertexBuffer==NULL || textObj->m_BgVertexBufferSizem_BgVertexBuffer!=NULL ) + { + ULONG rc = textObj->m_BgVertexBuffer->Release(); + assert( rc==0 ); (void)rc; + textObj->m_BgVertexBuffer = NULL; + } + textObj->m_BgVertexBufferSize = nbBgVerts + 6*32; // add a reserve of 32 rects + D3D11_BUFFER_DESC bd; + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.ByteWidth = textObj->m_BgVertexBufferSize * sizeof(CLineRectVtx); + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + bd.StructureByteStride = 0; + m_D3DDev->CreateBuffer(&bd, NULL, &textObj->m_BgVertexBuffer); + } + + if( textObj->m_BgVertexBuffer!=NULL ) + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + m_D3DDevImmContext->Map(textObj->m_BgVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + bgVerts = (CLineRectVtx *)mappedResource.pData; + } + } + + int x, x1, y, y1, i, len; + float px, px1, py, py1; + unsigned char ch; + const unsigned char *text; + color32 lineColor = COLOR32_RED; + CTextVtx vtx; + vtx.m_Pos[2] = 0; + CLineRectVtx bgVtx; + bgVtx.m_Pos[2] = 0; + int textVtxIndex = 0; + int bgVtxIndex = 0; + for( line=0; line<_NbLines; ++line ) + { + x = 0; + y = line * (_Font->m_CharHeight+_Sep); + y1 = y+_Font->m_CharHeight; + len = (int)_TextLines[line].length(); + text = (const unsigned char *)(_TextLines[line].c_str()); + if( _LineColors!=NULL ) + lineColor = ToR8G8B8A8(_LineColors[line]); + + if( textVerts!=NULL ) + for( i=0; im_CharWidth[ch]; + + px = ToNormScreenX(x, m_WndWidth); + py = ToNormScreenY(y, m_WndHeight); + px1 = ToNormScreenX(x1, m_WndWidth); + py1 = ToNormScreenY(y1, m_WndHeight); + + vtx.m_Color = lineColor; + + vtx.m_Pos[0] = px; + vtx.m_Pos[1] = py; + vtx.m_UV [0] = _Font->m_CharU0[ch]; + vtx.m_UV [1] = _Font->m_CharV0[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px1; + vtx.m_Pos[1] = py; + vtx.m_UV [0] = _Font->m_CharU1[ch]; + vtx.m_UV [1] = _Font->m_CharV0[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px; + vtx.m_Pos[1] = py1; + vtx.m_UV [0] = _Font->m_CharU0[ch]; + vtx.m_UV [1] = _Font->m_CharV1[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px1; + vtx.m_Pos[1] = py; + vtx.m_UV [0] = _Font->m_CharU1[ch]; + vtx.m_UV [1] = _Font->m_CharV0[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px1; + vtx.m_Pos[1] = py1; + vtx.m_UV [0] = _Font->m_CharU1[ch]; + vtx.m_UV [1] = _Font->m_CharV1[ch]; + textVerts[textVtxIndex++] = vtx; + + vtx.m_Pos[0] = px; + vtx.m_Pos[1] = py1; + vtx.m_UV [0] = _Font->m_CharU0[ch]; + vtx.m_UV [1] = _Font->m_CharV1[ch]; + textVerts[textVtxIndex++] = vtx; + + x = x1; + } + + if( _BgWidth>0 && bgVerts!=NULL ) + { + if( _LineBgColors!=NULL ) + bgVtx.m_Color = ToR8G8B8A8(_LineBgColors[line]); + else + bgVtx.m_Color = ToR8G8B8A8(COLOR32_BLACK); + + px = ToNormScreenX(-1, m_WndWidth); + py = ToNormScreenY(y, m_WndHeight); + px1 = ToNormScreenX(_BgWidth+1, m_WndWidth); + py1 = ToNormScreenY(y1, m_WndHeight); + + bgVtx.m_Pos[0] = px; + bgVtx.m_Pos[1] = py; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px1; + bgVtx.m_Pos[1] = py; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px; + bgVtx.m_Pos[1] = py1; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px1; + bgVtx.m_Pos[1] = py; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px1; + bgVtx.m_Pos[1] = py1; + bgVerts[bgVtxIndex++] = bgVtx; + + bgVtx.m_Pos[0] = px; + bgVtx.m_Pos[1] = py1; + bgVerts[bgVtxIndex++] = bgVtx; + } + } + assert( textVtxIndex==nbTextVerts ); + assert( bgVtxIndex==nbBgVerts ); + textObj->m_NbTextVerts = nbTextVerts; + textObj->m_NbBgVerts = nbBgVerts; + + if( textVerts!=NULL ) + m_D3DDevImmContext->Unmap(textObj->m_TextVertexBuffer, 0); + if( bgVerts!=NULL ) + m_D3DDevImmContext->Unmap(textObj->m_BgVertexBuffer, 0); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + CTextObj *textObj = static_cast(_TextObj); + float dx = 2.0f*(float)(_X + m_OffsetX)/m_WndWidth; + float dy = -2.0f*(float)(_Y + m_OffsetY)/m_WndHeight; + + // Draw background + if( textObj->m_NbBgVerts>=4 && textObj->m_BgVertexBuffer!=NULL ) + { + // Set offset and constant color + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CConstants *constants = (CConstants *)mappedResource.pData; + constants->m_Offset[0] = dx; + constants->m_Offset[1] = dy; + constants->m_Offset[2] = 0; + constants->m_Offset[3] = 0; + Color32ToARGBf(_BgColor, constants->m_CstColor+3, constants->m_CstColor+0, constants->m_CstColor+1, constants->m_CstColor+2); + m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0); + } + + // Set the input layout + m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDevImmContext->IASetVertexBuffers(0, 1, &textObj->m_BgVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // Render the bg rectangles + m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer); + if( _BgColor!=0 || !textObj->m_LineBgColors ) // use a constant bg color + m_D3DDevImmContext->VSSetShader(m_LineRectCstColorVS, NULL, 0); + else + m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0); + m_D3DDevImmContext->PSSetSamplers(0, 1, &m_SamplerState); + m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0); + m_D3DDevImmContext->Draw(textObj->m_NbBgVerts, 0); + } + + // Draw text + if( textObj->m_NbTextVerts>=4 && textObj->m_TextVertexBuffer!=NULL ) + { + // Set offset and constant color + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CConstants *constants = (CConstants *)mappedResource.pData; + constants->m_Offset[0] = dx; + constants->m_Offset[1] = dy; + constants->m_Offset[2] = 0; + constants->m_Offset[3] = 0; + Color32ToARGBf(_Color, constants->m_CstColor+3, constants->m_CstColor+0, constants->m_CstColor+1, constants->m_CstColor+2); + m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0); + } + + // Set the input layout + m_D3DDevImmContext->IASetInputLayout(m_TextVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CTextVtx); + UINT offset = 0; + m_D3DDevImmContext->IASetVertexBuffers(0, 1, &textObj->m_TextVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // Render the text + m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer); + if( _Color!=0 || !textObj->m_LineColors ) // use a constant color + m_D3DDevImmContext->VSSetShader(m_TextCstColorVS, NULL, 0); + else + m_D3DDevImmContext->VSSetShader(m_TextVS, NULL, 0); + m_D3DDevImmContext->PSSetShaderResources(0, 1, &m_FontD3DTexRV); + m_D3DDevImmContext->PSSetSamplers(0, 1, &m_SamplerState); + m_D3DDevImmContext->PSSetShader(m_TextPS, NULL, 0); + m_D3DDevImmContext->Draw(textObj->m_NbTextVerts, 0); + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY) +{ + if( _Width>0 && _Height>0 ) + { + /* viewport changes screen coordinates, use scissor instead + D3D11_VIEWPORT vp; + vp.TopLeftX = _X0; + vp.TopLeftY = _Y0; + vp.Width = _Width; + vp.Height = _Height; + vp.MinDepth = 0; + vp.MaxDepth = 1; + m_D3DDev->RSSetViewports(1, &vp); + */ + + m_ViewportAndScissorRects[0].left = _X0; + m_ViewportAndScissorRects[0].right = _X0 + _Width - 1; + m_ViewportAndScissorRects[0].top = _Y0; + m_ViewportAndScissorRects[0].bottom = _Y0 + _Height - 1; + if( RectIsFull(m_ViewportAndScissorRects[1]) ) + m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects); // viewport clipping only + else + m_D3DDevImmContext->RSSetScissorRects(2, m_ViewportAndScissorRects); + + m_OffsetX = _X0 + _OffsetX; + m_OffsetY = _Y0 + _OffsetY; + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::RestoreViewport() +{ + //m_D3DDevImmContext->RSSetViewports(1, static_cast(m_ViewportInit)); + m_ViewportAndScissorRects[0] = FullRect; + m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects+1); // scissor only + + m_OffsetX = m_OffsetY = 0; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::SetScissor(int _X0, int _Y0, int _Width, int _Height) +{ + if( _Width>0 && _Height>0 ) + { + m_ViewportAndScissorRects[1].left = _X0 - 2; + m_ViewportAndScissorRects[1].right = _X0 + _Width - 3; + m_ViewportAndScissorRects[1].top = _Y0 - 1; + m_ViewportAndScissorRects[1].bottom = _Y0 + _Height - 1; + if( RectIsFull(m_ViewportAndScissorRects[0]) ) + m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects+1); // no viewport clipping + else + m_D3DDevImmContext->RSSetScissorRects(2, m_ViewportAndScissorRects); + } + else + { + m_ViewportAndScissorRects[1] = FullRect; + m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects); // apply viewport clipping only + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D11::DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode) +{ + assert(m_Drawing==true); + + if( _NumTriangles<=0 ) + return; + + if( m_TrianglesVertexBufferCount<3*_NumTriangles ) // force re-creation + { + if( m_TrianglesVertexBuffer!=NULL ) + m_TrianglesVertexBuffer->Release(); + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + } + + // DrawTriangles uses LineRect layout and shaders + + if( m_TrianglesVertexBuffer==NULL ) + { + // Create triangles vertex buffer + D3D11_BUFFER_DESC bd; + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bd.MiscFlags = 0; + bd.ByteWidth = 3*_NumTriangles * sizeof(CLineRectVtx); + bd.StructureByteStride = 0; + HRESULT hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_TrianglesVertexBuffer); + if( SUCCEEDED(hr) ) + m_TrianglesVertexBufferCount = 3*_NumTriangles; + else + { + m_TrianglesVertexBuffer = NULL; + m_TrianglesVertexBufferCount = 0; + return; // Problem: cannot create triangles VB + } + } + assert( m_TrianglesVertexBufferCount>=3*_NumTriangles ); + assert( m_TrianglesVertexBuffer!=NULL ); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = m_D3DDevImmContext->Map(m_TrianglesVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CLineRectVtx *vertices = (CLineRectVtx *)mappedResource.pData; + // Fill vertex buffer + for( int i=0; i<3*_NumTriangles; ++ i ) + { + vertices[i].m_Pos[0] = ToNormScreenX(_Vertices[2*i+0] + m_OffsetX, m_WndWidth); + vertices[i].m_Pos[1] = ToNormScreenY(_Vertices[2*i+1] + m_OffsetY, m_WndHeight); + vertices[i].m_Pos[2] = 0; + vertices[i].m_Color = ToR8G8B8A8(_Colors[i]); + } + m_D3DDevImmContext->Unmap(m_TrianglesVertexBuffer, 0); + + // Reset shader constants + hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( SUCCEEDED(hr) ) + { + CConstants *constants = (CConstants *)mappedResource.pData; + constants->m_Offset[0] = 0; + constants->m_Offset[1] = 0; + constants->m_Offset[2] = 0; + constants->m_Offset[3] = 0; + constants->m_CstColor[0] = 1; + constants->m_CstColor[1] = 1; + constants->m_CstColor[2] = 1; + constants->m_CstColor[3] = 1; + m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0); + } + + // Set the input layout + m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout); + + // Set vertex buffer + UINT stride = sizeof(CLineRectVtx); + UINT offset = 0; + m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_TrianglesVertexBuffer, &stride, &offset); + + // Set primitive topology + m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + if( _CullMode==CULL_CW ) + m_D3DDevImmContext->RSSetState(m_RasterStateCullCW); + else if( _CullMode==CULL_CCW ) + m_D3DDevImmContext->RSSetState(m_RasterStateCullCCW); + else + m_D3DDevImmContext->RSSetState(m_RasterStateMultisample); + + // Render the triangles + m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer); + m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0); + m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0); + m_D3DDevImmContext->Draw(3*_NumTriangles, 0); + + m_D3DDevImmContext->RSSetState(m_RasterState); // restore default raster state + } +} + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.h b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.h new file mode 100644 index 0000000..7ea48ac --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D11.h @@ -0,0 +1,117 @@ +// --------------------------------------------------------------------------- +// +// @file TwDirect3D11.h +// @brief Direct3D11 graphic functions +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_DIRECT3D11_INCLUDED +#define ANT_TW_DIRECT3D11_INCLUDED + +#include "TwGraph.h" + +// --------------------------------------------------------------------------- + +class CTwGraphDirect3D11 : public ITwGraph +{ +public: + virtual int Init(); + virtual int Shut(); + virtual void BeginDraw(int _WndWidth, int _WndHeight); + virtual void EndDraw(); + virtual bool IsDrawing(); + virtual void Restore(); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased=false); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color, bool _AntiAliased=false) { DrawLine(_X0, _Y0, _X1, _Y1, _Color, _Color, _AntiAliased); } + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11); + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color) { DrawRect(_X0, _Y0, _X1, _Y1, _Color, _Color, _Color, _Color); } + virtual void DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode); + + virtual void * NewTextObj(); + virtual void DeleteTextObj(void *_TextObj); + virtual void BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth); + virtual void DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor); + + virtual void ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY); + virtual void RestoreViewport(); + virtual void SetScissor(int _X0, int _Y0, int _Width, int _Height); + +protected: + struct ID3D11Device * m_D3DDev; + struct ID3D11DeviceContext *m_D3DDevImmContext; + unsigned int m_D3DDevInitialRefCount; + bool m_Drawing; + const CTexFont * m_FontTex; + struct ID3D11Texture2D * m_FontD3DTex; + struct ID3D11ShaderResourceView *m_FontD3DTexRV; + int m_WndWidth; + int m_WndHeight; + int m_OffsetX; + int m_OffsetY; + void * m_ViewportInit; + RECT m_ViewportAndScissorRects[2]; + + struct CLineRectVtx + { + float m_Pos[3]; + color32 m_Color; + }; + struct CTextVtx + { + float m_Pos[3]; + color32 m_Color; + float m_UV[2]; + }; + struct CConstants + { + float m_Offset[4]; + float m_CstColor[4]; + }; + + struct CTextObj + { + struct ID3D11Buffer * m_TextVertexBuffer; + struct ID3D11Buffer * m_BgVertexBuffer; + int m_NbTextVerts; + int m_NbBgVerts; + int m_TextVertexBufferSize; + int m_BgVertexBufferSize; + bool m_LineColors; + bool m_LineBgColors; + }; + + struct CState11 * m_State; + struct ID3D11DepthStencilState *m_DepthStencilState; + struct ID3D11BlendState * m_BlendState; + struct ID3D11RasterizerState * m_RasterState; + struct ID3D11RasterizerState * m_RasterStateAntialiased; + struct ID3D11RasterizerState * m_RasterStateMultisample; + struct ID3D11RasterizerState * m_RasterStateCullCW; + struct ID3D11RasterizerState * m_RasterStateCullCCW; + + struct ID3D11VertexShader * m_LineRectVS; + struct ID3D11VertexShader * m_LineRectCstColorVS; + struct ID3D11PixelShader * m_LineRectPS; + struct ID3D11InputLayout * m_LineRectVertexLayout; + struct ID3D11VertexShader * m_TextVS; + struct ID3D11VertexShader * m_TextCstColorVS; + struct ID3D11PixelShader * m_TextPS; + struct ID3D11InputLayout * m_TextVertexLayout; + struct ID3D11Buffer * m_LineVertexBuffer; + struct ID3D11Buffer * m_RectVertexBuffer; + struct ID3D11Buffer * m_TrianglesVertexBuffer; + int m_TrianglesVertexBufferCount; + struct ID3D11Buffer * m_ConstantBuffer; + struct ID3D11SamplerState * m_SamplerState; +}; + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_DIRECT3D11_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.cpp new file mode 100644 index 0000000..b19355b --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.cpp @@ -0,0 +1,640 @@ +// --------------------------------------------------------------------------- +// +// @file TwDirect3D9.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "TwDirect3D9.h" +#include "TwMgr.h" + +#include +#ifdef _DEBUG +// #include +// #pragma comment(lib, "dxerr9") +#endif // _DEBUG + + +using namespace std; + +const char *g_ErrCantLoadD3D9 = "Cannot load Direct3D9 library dynamically"; +const char *g_ErrCantUnloadD3D9 = "Cannot unload Direct3D9 library"; + + +// --------------------------------------------------------------------------- + +static IDirect3DTexture9 *BindFont(IDirect3DDevice9 *_Dev, const CTexFont *_Font) +{ + assert(_Font!=NULL); + + IDirect3DTexture9 *Tex = NULL; + IDirect3DDevice9Ex *D3DDev9Ex = NULL; + bool IsD3DDev9Ex = SUCCEEDED(_Dev->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void **)&D3DDev9Ex)) && D3DDev9Ex != NULL; + HRESULT hr; + if (IsD3DDev9Ex) + { + hr = _Dev->CreateTexture(_Font->m_TexWidth, _Font->m_TexHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &Tex, NULL); + D3DDev9Ex->Release(); + } + else + hr = _Dev->CreateTexture(_Font->m_TexWidth, _Font->m_TexHeight, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &Tex, NULL); + if( FAILED(hr) ) + return NULL; + + D3DLOCKED_RECT r; + hr = Tex->LockRect(0, &r, NULL, 0); + if( SUCCEEDED(hr) ) + { + color32 *p = static_cast(r.pBits); + for( int i=0; i<_Font->m_TexWidth*_Font->m_TexHeight; ++i, ++p ) + *p = 0x00ffffff | (((color32)(_Font->m_TexBytes[i]))<<24); + Tex->UnlockRect(0); + } + return Tex; +} + +// --------------------------------------------------------------------------- + +static void UnbindFont(IDirect3DDevice9 *_Dev, IDirect3DTexture9 *_Tex) +{ + (void)_Dev; + + if( _Tex ) + _Tex->Release(); +} + +// --------------------------------------------------------------------------- + +struct CState +{ + IDirect3DStateBlock9 *m_StateBlock; + + // DeviceCaps (filled by constructor) + D3DCAPS9 m_Caps; + + void Save(); + void Restore(); + CState(IDirect3DDevice9 *_Dev); + ~CState(); +private: + IDirect3DDevice9 *m_D3DDev; +}; + +CState::CState(IDirect3DDevice9 *_Dev) +{ + ZeroMemory(this, sizeof(CState)); + m_D3DDev = _Dev; + + m_D3DDev->GetDeviceCaps(&m_Caps); +} + +CState::~CState() +{ + if( m_StateBlock ) + { + UINT rc = m_StateBlock->Release(); + assert( rc==0 ); (void)rc; + m_StateBlock = NULL; + } +} + +void CState::Save() +{ + if( !m_StateBlock && m_D3DDev ) + m_D3DDev->CreateStateBlock(D3DSBT_ALL, &m_StateBlock); + + if( m_StateBlock ) + m_StateBlock->Capture(); +} + +void CState::Restore() +{ + if( m_StateBlock ) + m_StateBlock->Apply(); +} + +// --------------------------------------------------------------------------- + +int CTwGraphDirect3D9::Init() +{ + assert(g_TwMgr->m_Device!=NULL); + + m_D3DDev = static_cast(g_TwMgr->m_Device); + m_Drawing = false; + m_FontTex = NULL; + m_FontD3DTex = NULL; + D3DDEVICE_CREATION_PARAMETERS cp; + m_D3DDev->GetCreationParameters(&cp); + m_PureDevice = ( cp.BehaviorFlags & D3DCREATE_PUREDEVICE ) ? true : false; + m_WndWidth = 0; + m_WndHeight = 0; + m_State = new CState(m_D3DDev); + m_ViewportInit = new D3DVIEWPORT9; + ZeroMemory(m_ViewportInit, sizeof(D3DVIEWPORT9)); + m_OffsetX = 0; + m_OffsetY = 0; + + return 1; +} + +// --------------------------------------------------------------------------- + +int CTwGraphDirect3D9::Shut() +{ + assert(m_Drawing==false); + + UnbindFont(m_D3DDev, m_FontD3DTex); + m_FontD3DTex = NULL; + delete m_State; + m_State = NULL; + m_D3DDev = NULL; + delete m_ViewportInit; + m_ViewportInit = NULL; + + return 1; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::BeginDraw(int _WndWidth, int _WndHeight) +{ + assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0); + m_Drawing = true; + + m_WndWidth = _WndWidth; + m_WndHeight = _WndHeight; + m_OffsetX = 0; + m_OffsetY = 0; + + // save context + if( !m_PureDevice ) + m_State->Save(); + + if( m_WndWidth>0 && m_WndHeight>0 ) + { + D3DVIEWPORT9 Vp; + Vp.X = 0; + Vp.Y = 0; + Vp.Width = m_WndWidth; + Vp.Height = m_WndHeight; + Vp.MinZ = 0; + Vp.MaxZ = 1; + m_D3DDev->SetViewport(&Vp); + + //D3DMATRIX Transfo = { 2.0f/_WndWidth,0,0,0, 0,2.0f/_WndHeight,0,0, 0,0,-1,0, 0,0,0,1 }; + //m_D3DDev->SetTransform(D3DTS_PROJECTION, &Transfo); + } + m_D3DDev->GetViewport(static_cast(m_ViewportInit)); + // const D3DMATRIX id = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; + // m_D3DDev->SetTransform(D3DTS_VIEW, &id); + // m_D3DDev->SetTransform(D3DTS_WORLD, &id); + // m_D3DDev->SetTransform(D3DTS_TEXTURE0, &id); + + m_D3DDev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + m_D3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + m_D3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + m_D3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + m_D3DDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + m_D3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + m_D3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + m_D3DDev->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + m_D3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + m_D3DDev->SetRenderState(D3DRS_LASTPIXEL, FALSE); + m_D3DDev->SetRenderState(D3DRS_FOGENABLE, FALSE); + m_D3DDev->SetRenderState(D3DRS_STENCILENABLE, FALSE); + m_D3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F); + m_D3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + if( m_State->m_Caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND ) + m_D3DDev->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + //if( m_State->m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) + m_D3DDev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE); + + m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + m_D3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + m_D3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + m_D3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU); + m_D3DDev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + m_D3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + m_D3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + m_D3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + m_D3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + m_D3DDev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + + m_D3DDev->SetVertexShader(NULL); + m_D3DDev->SetPixelShader(NULL); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::EndDraw() +{ + assert(m_Drawing==true); + m_Drawing = false; + + // restore context + if( !m_PureDevice ) + m_State->Restore(); +} + +// --------------------------------------------------------------------------- + +bool CTwGraphDirect3D9::IsDrawing() +{ + return m_Drawing; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::Restore() +{ + if( m_State ) + if( m_State->m_StateBlock ) + { + UINT rc = m_State->m_StateBlock->Release(); + assert( rc==0 ); (void)rc; + m_State->m_StateBlock = NULL; + } + + UnbindFont(m_D3DDev, m_FontD3DTex); + m_FontD3DTex = NULL; + + m_FontTex = NULL; +} + + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased) +{ + assert(m_Drawing==true); + + struct CVtx + { + float m_Pos[4]; + DWORD m_Color; + }; + CVtx p[2]; + + p[0].m_Pos[0] = (float)(_X0 + m_OffsetX); + p[0].m_Pos[1] = (float)(_Y0 + m_OffsetY); + p[0].m_Pos[2] = 0; + p[0].m_Pos[3] = 0; + p[0].m_Color = _Color0; + + p[1].m_Pos[0] = (float)(_X1 + m_OffsetX); + p[1].m_Pos[1] = (float)(_Y1 + m_OffsetY); + p[1].m_Pos[2] = 0; + p[1].m_Pos[3] = 0; + p[1].m_Color = _Color1; + + //if( m_State->m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) + m_D3DDev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, (_AntiAliased ? TRUE : FALSE)); + m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); + m_D3DDev->DrawPrimitiveUP(D3DPT_LINELIST, 1, p, sizeof(CVtx)); + //if( m_State->m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) + m_D3DDev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11) +{ + assert(m_Drawing==true); + + // border adjustment + if(_X0<_X1) + ++_X1; + else if(_X0>_X1) + ++_X0; + if(_Y0<_Y1) + ++_Y1; + else if(_Y0>_Y1) + ++_Y0; + + struct CVtx + { + float m_Pos[4]; + DWORD m_Color; + }; + CVtx p[4]; + + p[0].m_Pos[0] = (float)(_X1 + m_OffsetX); + p[0].m_Pos[1] = (float)(_Y0 + m_OffsetY); + p[0].m_Pos[2] = 0; + p[0].m_Pos[3] = 1; + p[0].m_Color = _Color10; + + p[1].m_Pos[0] = (float)(_X0 + m_OffsetX); + p[1].m_Pos[1] = (float)(_Y0 + m_OffsetY); + p[1].m_Pos[2] = 0; + p[1].m_Pos[3] = 1; + p[1].m_Color = _Color00; + + p[2].m_Pos[0] = (float)(_X1 + m_OffsetX); + p[2].m_Pos[1] = (float)(_Y1 + m_OffsetY); + p[2].m_Pos[2] = 0; + p[2].m_Pos[3] = 1; + p[2].m_Color = _Color11; + + p[3].m_Pos[0] = (float)(_X0 + m_OffsetX); + p[3].m_Pos[1] = (float)(_Y1 + m_OffsetY); + p[3].m_Pos[2] = 0; + p[3].m_Pos[3] = 1; + p[3].m_Color = _Color01; + + m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); + m_D3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, p, sizeof(CVtx)); +} + +// --------------------------------------------------------------------------- + +void *CTwGraphDirect3D9::NewTextObj() +{ + return new CTextObj; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::DeleteTextObj(void *_TextObj) +{ + assert(_TextObj!=NULL); + delete static_cast(_TextObj); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + assert(_Font!=NULL); + + if( _Font != m_FontTex ) + { + UnbindFont(m_D3DDev, m_FontD3DTex); + m_FontD3DTex = BindFont(m_D3DDev, _Font); + m_FontTex = _Font; + } + + CTextObj *TextObj = static_cast(_TextObj); + TextObj->m_TextVerts.resize(0); + TextObj->m_BgVerts.resize(0); + TextObj->m_LineColors = (_LineColors!=NULL); + TextObj->m_LineBgColors = (_LineBgColors!=NULL); + + int x, x1, y, y1, i, Len; + unsigned char ch; + const unsigned char *Text; + color32 LineColor = COLOR32_RED; + CTextVtx Vtx; + Vtx.m_Pos[2] = 0; + Vtx.m_Pos[3] = 1; + CBgVtx BgVtx; + BgVtx.m_Pos[2] = 0; + BgVtx.m_Pos[3] = 1; + for( int Line=0; Line<_NbLines; ++Line ) + { + x = 0; + y = Line * (_Font->m_CharHeight+_Sep); + y1 = y+_Font->m_CharHeight; + Len = (int)_TextLines[Line].length(); + Text = (const unsigned char *)(_TextLines[Line].c_str()); + if( _LineColors!=NULL ) + LineColor = _LineColors[Line]; + + for( i=0; im_CharWidth[ch]; + + Vtx.m_Color = LineColor; + + Vtx.m_Pos[0] = (float)x; + Vtx.m_Pos[1] = (float)y; + Vtx.m_UV [0] = _Font->m_CharU0[ch]; + Vtx.m_UV [1] = _Font->m_CharV0[ch]; + TextObj->m_TextVerts.push_back(Vtx); + + Vtx.m_Pos[0] = (float)x1; + Vtx.m_Pos[1] = (float)y; + Vtx.m_UV [0] = _Font->m_CharU1[ch]; + Vtx.m_UV [1] = _Font->m_CharV0[ch]; + TextObj->m_TextVerts.push_back(Vtx); + + Vtx.m_Pos[0] = (float)x; + Vtx.m_Pos[1] = (float)y1; + Vtx.m_UV [0] = _Font->m_CharU0[ch]; + Vtx.m_UV [1] = _Font->m_CharV1[ch]; + TextObj->m_TextVerts.push_back(Vtx); + + Vtx.m_Pos[0] = (float)x1; + Vtx.m_Pos[1] = (float)y; + Vtx.m_UV [0] = _Font->m_CharU1[ch]; + Vtx.m_UV [1] = _Font->m_CharV0[ch]; + TextObj->m_TextVerts.push_back(Vtx); + + Vtx.m_Pos[0] = (float)x1; + Vtx.m_Pos[1] = (float)y1; + Vtx.m_UV [0] = _Font->m_CharU1[ch]; + Vtx.m_UV [1] = _Font->m_CharV1[ch]; + TextObj->m_TextVerts.push_back(Vtx); + + Vtx.m_Pos[0] = (float)x; + Vtx.m_Pos[1] = (float)y1; + Vtx.m_UV [0] = _Font->m_CharU0[ch]; + Vtx.m_UV [1] = _Font->m_CharV1[ch]; + TextObj->m_TextVerts.push_back(Vtx); + + x = x1; + } + if( _BgWidth>0 ) + { + if( _LineBgColors!=NULL ) + BgVtx.m_Color = _LineBgColors[Line]; + else + BgVtx.m_Color = COLOR32_BLACK; + + BgVtx.m_Pos[0] = -1; + BgVtx.m_Pos[1] = (float)y; + TextObj->m_BgVerts.push_back(BgVtx); + + BgVtx.m_Pos[0] = (float)(_BgWidth+1); + BgVtx.m_Pos[1] = (float)y; + TextObj->m_BgVerts.push_back(BgVtx); + + BgVtx.m_Pos[0] = -1; + BgVtx.m_Pos[1] = (float)y1; + TextObj->m_BgVerts.push_back(BgVtx); + + BgVtx.m_Pos[0] = (float)(_BgWidth+1); + BgVtx.m_Pos[1] = (float)y; + TextObj->m_BgVerts.push_back(BgVtx); + + BgVtx.m_Pos[0] = (float)(_BgWidth+1); + BgVtx.m_Pos[1] = (float)y1; + TextObj->m_BgVerts.push_back(BgVtx); + + BgVtx.m_Pos[0] = -1; + BgVtx.m_Pos[1] = (float)y1; + TextObj->m_BgVerts.push_back(BgVtx); + } + } + +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + CTextObj *TextObj = static_cast(_TextObj); + float x = (float)_X; + float y = (float)_Y; + + int i; + int nv = (int)TextObj->m_TextVerts.size(); + int nb = (int)TextObj->m_BgVerts.size(); + + if( nb>=4 ) + { + for( i=0; im_BgVerts[i].m_Pos[0] += x + m_OffsetX; + TextObj->m_BgVerts[i].m_Pos[1] += y + m_OffsetY; + if( _BgColor!=0 || !TextObj->m_LineBgColors ) + TextObj->m_BgVerts[i].m_Color = _BgColor; + } + + m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); + m_D3DDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nb/3, &(TextObj->m_BgVerts[0]), sizeof(CBgVtx)); + + for( i=0; im_BgVerts[i].m_Pos[0] -= x + m_OffsetX; + TextObj->m_BgVerts[i].m_Pos[1] -= y + m_OffsetY; + } + } + + if( nv>=4 ) + { + for( i=0; im_TextVerts[i].m_Pos[0] += x + m_OffsetX; + TextObj->m_TextVerts[i].m_Pos[1] += y + m_OffsetY; + } + if( _Color!=0 || !TextObj->m_LineColors ) + for( i=0; im_TextVerts[i].m_Color = _Color; + + m_D3DDev->SetTexture(0, m_FontD3DTex); + m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE2(0)); + m_D3DDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nv/3, &(TextObj->m_TextVerts[0]), sizeof(CTextVtx)); + + for( i=0; im_TextVerts[i].m_Pos[0] -= x + m_OffsetX; + TextObj->m_TextVerts[i].m_Pos[1] -= y + m_OffsetY; + } + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY) +{ + if( _Width>0 && _Height>0 ) + { + D3DVIEWPORT9 Vp; + Vp.X = _X0; + Vp.Y = _Y0; + Vp.Width = _Width; + Vp.Height = _Height; + Vp.MinZ = 0; + Vp.MaxZ = 1; + m_D3DDev->SetViewport(&Vp); + + m_OffsetX = _X0 + _OffsetX; + m_OffsetY = _Y0 + _OffsetY - 1; + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::RestoreViewport() +{ + m_D3DDev->SetViewport(static_cast(m_ViewportInit)); + m_OffsetX = m_OffsetY = 0; +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::SetScissor(int _X0, int _Y0, int _Width, int _Height) +{ + if( _Width>0 && _Height>0 ) + { + RECT Rect; + Rect.left = _X0 - 1; + Rect.right = Rect.left + _Width - 1; + Rect.top = _Y0; + Rect.bottom = Rect.top + _Height; + m_D3DDev->SetScissorRect(&Rect); + m_D3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + } + else + m_D3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); +} + +// --------------------------------------------------------------------------- + +void CTwGraphDirect3D9::DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode) +{ + assert(m_Drawing==true); + + if( _NumTriangles<0 ) + return; + + DWORD prevCullMode = D3DCULL_NONE; + m_D3DDev->GetRenderState(D3DRS_CULLMODE, &prevCullMode); + if( _CullMode==CULL_CW ) + m_D3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + else if( _CullMode==CULL_CCW ) + m_D3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + else + m_D3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + if( (int)m_TriVertices.size()<3*_NumTriangles ) + m_TriVertices.resize(3*_NumTriangles); + + for( int i=0; i<3*_NumTriangles; ++i ) + { + m_TriVertices[i].m_Pos[0] = (float)(_Vertices[2*i+0] + m_OffsetX); + m_TriVertices[i].m_Pos[1] = (float)(_Vertices[2*i+1] + m_OffsetY); + m_TriVertices[i].m_Pos[2] = 0; + m_TriVertices[i].m_Pos[3] = 1; + m_TriVertices[i].m_Color = _Colors[i]; + } + + m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); + m_D3DDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, _NumTriangles, &(m_TriVertices[0]), sizeof(CTriVtx)); + + m_D3DDev->SetRenderState(D3DRS_CULLMODE, prevCullMode); +} + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.h b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.h new file mode 100644 index 0000000..39b5147 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.h @@ -0,0 +1,90 @@ +// --------------------------------------------------------------------------- +// +// @file TwDirect3D9.h +// @brief Direct3D9 graph functions +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_DIRECT3D9_INCLUDED +#define ANT_TW_DIRECT3D9_INCLUDED + +#include "TwGraph.h" + +// --------------------------------------------------------------------------- + +class CTwGraphDirect3D9 : public ITwGraph +{ +public: + virtual int Init(); + virtual int Shut(); + virtual void BeginDraw(int _WndWidth, int _WndHeight); + virtual void EndDraw(); + virtual bool IsDrawing(); + virtual void Restore(); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased=false); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color, bool _AntiAliased=false) { DrawLine(_X0, _Y0, _X1, _Y1, _Color, _Color, _AntiAliased); } + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11); + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color) { DrawRect(_X0, _Y0, _X1, _Y1, _Color, _Color, _Color, _Color); } + virtual void DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode); + + virtual void * NewTextObj(); + virtual void DeleteTextObj(void *_TextObj); + virtual void BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth); + virtual void DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor); + + virtual void ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY); + virtual void RestoreViewport(); + virtual void SetScissor(int _X0, int _Y0, int _Width, int _Height); + +protected: + struct IDirect3DDevice9 * m_D3DDev; + bool m_Drawing; + const CTexFont * m_FontTex; + struct IDirect3DTexture9 * m_FontD3DTex; + bool m_PureDevice; + int m_WndWidth; + int m_WndHeight; + void * m_ViewportInit; + int m_OffsetX; + int m_OffsetY; + + struct CTextVtx + { + float m_Pos[4]; + color32 m_Color; + float m_UV[2]; + }; + struct CBgVtx + { + float m_Pos[4]; + color32 m_Color; + }; + + struct CTextObj + { + std::vector m_TextVerts; + std::vector m_BgVerts; + bool m_LineColors; + bool m_LineBgColors; + }; + + struct CTriVtx + { + float m_Pos[4]; + DWORD m_Color; + }; + std::vector m_TriVertices; + + struct CState * m_State; +}; + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_DIRECT3D9_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwEventGLFW.c b/Extras/CDTestFramework/AntTweakBar/src/TwEventGLFW.c new file mode 100644 index 0000000..98b515a --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwEventGLFW.c @@ -0,0 +1,212 @@ +// --------------------------------------------------------------------------- +// +// @file TwEventGLFW.c +// @brief Helper: +// translate and re-send mouse and keyboard events +// from GLFW event callbacks to AntTweakBar +// +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + +// #include +#include "MiniGLFW.h" // a subset of GLFW.h needed to compile TwEventGLFW.c +// note: AntTweakBar.dll does not need to link with GLFW, +// it just needs some definitions for its helper functions. + +#include + + +int TW_CALL TwEventMouseButtonGLFW(int glfwButton, int glfwAction) +{ + int handled = 0; + TwMouseAction action = (glfwAction==GLFW_PRESS) ? TW_MOUSE_PRESSED : TW_MOUSE_RELEASED; + + if( glfwButton==GLFW_MOUSE_BUTTON_LEFT ) + handled = TwMouseButton(action, TW_MOUSE_LEFT); + else if( glfwButton==GLFW_MOUSE_BUTTON_RIGHT ) + handled = TwMouseButton(action, TW_MOUSE_RIGHT); + else if( glfwButton==GLFW_MOUSE_BUTTON_MIDDLE ) + handled = TwMouseButton(action, TW_MOUSE_MIDDLE); + + return handled; +} + + +int g_KMod = 0; + + +int TW_CALL TwEventKeyGLFW(int glfwKey, int glfwAction) +{ + int handled = 0; + + // Register of modifiers state + if( glfwAction==GLFW_PRESS ) + { + switch( glfwKey ) + { + case GLFW_KEY_LSHIFT: + case GLFW_KEY_RSHIFT: + g_KMod |= TW_KMOD_SHIFT; + break; + case GLFW_KEY_LCTRL: + case GLFW_KEY_RCTRL: + g_KMod |= TW_KMOD_CTRL; + break; + case GLFW_KEY_LALT: + case GLFW_KEY_RALT: + g_KMod |= TW_KMOD_ALT; + break; + } + } + else + { + switch( glfwKey ) + { + case GLFW_KEY_LSHIFT: + case GLFW_KEY_RSHIFT: + g_KMod &= ~TW_KMOD_SHIFT; + break; + case GLFW_KEY_LCTRL: + case GLFW_KEY_RCTRL: + g_KMod &= ~TW_KMOD_CTRL; + break; + case GLFW_KEY_LALT: + case GLFW_KEY_RALT: + g_KMod &= ~TW_KMOD_ALT; + break; + } + } + + // Process key pressed + if( glfwAction==GLFW_PRESS ) + { + int mod = g_KMod; + int testkp = ((mod&TW_KMOD_CTRL) || (mod&TW_KMOD_ALT)) ? 1 : 0; + + if( (mod&TW_KMOD_CTRL) && glfwKey>0 && glfwKey=GLFW_KEY_SPECIAL ) + { + int k = 0; + + if( glfwKey>=GLFW_KEY_F1 && glfwKey<=GLFW_KEY_F15 ) + k = TW_KEY_F1 + (glfwKey-GLFW_KEY_F1); + else if( testkp && glfwKey>=GLFW_KEY_KP_0 && glfwKey<=GLFW_KEY_KP_9 ) + k = '0' + (glfwKey-GLFW_KEY_KP_0); + else + { + switch( glfwKey ) + { + case GLFW_KEY_ESC: + k = TW_KEY_ESCAPE; + break; + case GLFW_KEY_UP: + k = TW_KEY_UP; + break; + case GLFW_KEY_DOWN: + k = TW_KEY_DOWN; + break; + case GLFW_KEY_LEFT: + k = TW_KEY_LEFT; + break; + case GLFW_KEY_RIGHT: + k = TW_KEY_RIGHT; + break; + case GLFW_KEY_TAB: + k = TW_KEY_TAB; + break; + case GLFW_KEY_ENTER: + k = TW_KEY_RETURN; + break; + case GLFW_KEY_BACKSPACE: + k = TW_KEY_BACKSPACE; + break; + case GLFW_KEY_INSERT: + k = TW_KEY_INSERT; + break; + case GLFW_KEY_DEL: + k = TW_KEY_DELETE; + break; + case GLFW_KEY_PAGEUP: + k = TW_KEY_PAGE_UP; + break; + case GLFW_KEY_PAGEDOWN: + k = TW_KEY_PAGE_DOWN; + break; + case GLFW_KEY_HOME: + k = TW_KEY_HOME; + break; + case GLFW_KEY_END: + k = TW_KEY_END; + break; + case GLFW_KEY_KP_ENTER: + k = TW_KEY_RETURN; + break; + case GLFW_KEY_KP_DIVIDE: + if( testkp ) + k = '/'; + break; + case GLFW_KEY_KP_MULTIPLY: + if( testkp ) + k = '*'; + break; + case GLFW_KEY_KP_SUBTRACT: + if( testkp ) + k = '-'; + break; + case GLFW_KEY_KP_ADD: + if( testkp ) + k = '+'; + break; + case GLFW_KEY_KP_DECIMAL: + if( testkp ) + k = '.'; + break; + case GLFW_KEY_KP_EQUAL: + if( testkp ) + k = '='; + break; + } + } + + if( k>0 ) + handled = TwKeyPressed(k, mod); + } + } + + return handled; +} + + +int TW_CALL TwEventCharGLFW(int glfwChar, int glfwAction) +{ + if( glfwAction==GLFW_PRESS && (glfwChar & 0xff00)==0 ) + return TwKeyPressed(glfwChar, g_KMod); + + return 0; +} + +// functions with __cdecl calling convension +TW_API int TW_CDECL_CALL TwEventMouseButtonGLFWcdecl(int glfwButton, int glfwAction) +{ + return TwEventMouseButtonGLFW(glfwButton, glfwAction); +} +TW_API int TW_CDECL_CALL TwEventKeyGLFWcdecl(int glfwKey, int glfwAction) +{ + return TwEventKeyGLFW(glfwKey, glfwAction); +} +TW_API int TW_CDECL_CALL TwEventCharGLFWcdecl(int glfwChar, int glfwAction) +{ + return TwEventCharGLFW(glfwChar, glfwAction); +} +TW_API int TW_CDECL_CALL TwEventMousePosGLFWcdecl(int mouseX, int mouseY) +{ + return TwMouseMotion(mouseX, mouseY); +} +TW_API int TW_CDECL_CALL TwEventMouseWheelGLFWcdecl(int wheelPos) +{ + return TwMouseWheel(wheelPos); +} diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwEventGLUT.c b/Extras/CDTestFramework/AntTweakBar/src/TwEventGLUT.c new file mode 100644 index 0000000..ef6fec5 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwEventGLUT.c @@ -0,0 +1,150 @@ +// --------------------------------------------------------------------------- +// +// @file TwEventGLUT.c +// @brief Helper: +// translate and re-send mouse and keyboard events +// from GLUT event callbacks to AntTweakBar +// +// @author Philippe Decaudin - http://www.antisphere.com +// @date 2006/05/10 +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#define GLUT_NO_LIB_PRAGMA // we do not want to force linkage with glut +#ifdef _MSC_VER +# pragma warning(disable: 4505) // glut generates 'unreferenced function' warnings +# pragma warning(disable: 4100) // unreferenced parameter +#endif // _MSC_VER + +// #include +#include "MiniGLUT.h" // a subset of glut.h needed to compile TwEventGLUT.c +// note: AntTweakBar.dll does not need to link with GLUT, +// it just needs some definitions for its helper functions. + +#include + + +int TW_GLUT_CALL TwEventMouseButtonGLUT(int glutButton, int glutState, int mouseX, int mouseY) +{ + TwMouseAction action = (glutState==GLUT_DOWN) ? TW_MOUSE_PRESSED : TW_MOUSE_RELEASED; + + TwMouseMotion(mouseX, mouseY); + switch( glutButton ) + { + case GLUT_LEFT_BUTTON: + return TwMouseButton(action, TW_MOUSE_LEFT); + case GLUT_RIGHT_BUTTON: + return TwMouseButton(action, TW_MOUSE_RIGHT); + case GLUT_MIDDLE_BUTTON: + return TwMouseButton(action, TW_MOUSE_MIDDLE); + default: + return 0; + } +} + +int TW_GLUT_CALL TwEventMouseMotionGLUT(int mouseX, int mouseY) +{ + return TwMouseMotion(mouseX, mouseY); +} + + +// GLUT does not send modifiers state to 'Key' and 'Special' callbacks, +// and we cannot call glutGetModifiers here because we do not want to link +// AntTweakBar with glut, so the following function is used to store +// a pointer to the glutGetModifiers function of the calling application. +// It must be called at initialisation of the application. + +int (TW_CALL *g_GLUTGetModifiers)(void) = NULL; + +int TW_CALL TwGLUTModifiersFunc(int (TW_CALL *glutGetModifiersFunc)(void)) +{ + g_GLUTGetModifiers = glutGetModifiersFunc; + return (g_GLUTGetModifiers==NULL) ? 0 : 1; +} + + +int TW_GLUT_CALL TwEventKeyboardGLUT(unsigned char glutKey, int mouseX, int mouseY) +{ + int kmod = 0; + + if( g_GLUTGetModifiers!=NULL ) + { + int glutMod = g_GLUTGetModifiers(); + + if( glutMod&GLUT_ACTIVE_SHIFT ) + kmod |= TW_KMOD_SHIFT; + if( glutMod&GLUT_ACTIVE_CTRL ) + kmod |= TW_KMOD_CTRL; + if( glutMod&GLUT_ACTIVE_ALT ) + kmod |= TW_KMOD_ALT; + } + + if( (kmod&TW_KMOD_CTRL) && (glutKey>0 && glutKey<27) ) // CTRL special case + glutKey += 'a'-1; + + return TwKeyPressed((int)glutKey, kmod); +} + + +int TW_GLUT_CALL TwEventSpecialGLUT(int glutKey, int mouseX, int mouseY) +{ + int k = 0, kmod = 0; + + if( g_GLUTGetModifiers!=NULL ) + { + int glutMod = g_GLUTGetModifiers(); + + if( glutMod&GLUT_ACTIVE_SHIFT ) + kmod |= TW_KMOD_SHIFT; + if( glutMod&GLUT_ACTIVE_CTRL ) + kmod |= TW_KMOD_CTRL; + if( glutMod&GLUT_ACTIVE_ALT ) + kmod |= TW_KMOD_ALT; + } + + if( glutKey>=GLUT_KEY_F1 && glutKey<=GLUT_KEY_F12 ) + k = TW_KEY_F1 + (glutKey-GLUT_KEY_F1); + else + { + switch( glutKey ) + { + case GLUT_KEY_LEFT: + k = TW_KEY_LEFT; + break; + case GLUT_KEY_UP: + k = TW_KEY_UP; + break; + case GLUT_KEY_RIGHT: + k = TW_KEY_RIGHT; + break; + case GLUT_KEY_DOWN: + k = TW_KEY_DOWN; + break; + case GLUT_KEY_PAGE_UP: + k = TW_KEY_PAGE_UP; + break; + case GLUT_KEY_PAGE_DOWN: + k = TW_KEY_PAGE_DOWN; + break; + case GLUT_KEY_HOME: + k = TW_KEY_HOME; + break; + case GLUT_KEY_END: + k = TW_KEY_END; + break; + case GLUT_KEY_INSERT: + k = TW_KEY_INSERT; + break; + } + } + + if( k>0 && k + +int TW_CALL TwEventSDL12(const void *sdlEvent); // implemented in TwEventSDL12.c +int TW_CALL TwEventSDL13(const void *sdlEvent); // implmeneted in TwEventSDL13.c +#ifdef __cplusplus + extern "C" { int TW_CALL TwSetLastError(const char *staticErrorMessage); } +#else + int TW_CALL TwSetLastError(const char *staticErrorMessage); +#endif // __cplusplus + + +// TwEventSDL returns zero if msg has not been handled or the SDL version +// is not supported, and a non-zero value if it has been handled by the +// AntTweakBar library. +int TW_CALL TwEventSDL(const void *sdlEvent, unsigned char majorVersion, unsigned char minorVersion) +{ + if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 2)) + { + static const char *g_ErrBadSDLVersion = "Unsupported SDL version"; + TwSetLastError(g_ErrBadSDLVersion); + return 0; + } + else if (majorVersion == 1 && minorVersion == 2) + return TwEventSDL12(sdlEvent); + else // if( majorVersion==1 && minorVersion==3 ) + return TwEventSDL13(sdlEvent); // will probably not work for version > 1.3, but give it a chance +} diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwEventWin.c b/Extras/CDTestFramework/AntTweakBar/src/TwEventWin.c new file mode 100644 index 0000000..7d6ebc7 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwEventWin.c @@ -0,0 +1,256 @@ +// --------------------------------------------------------------------------- +// +// @file TwEventWin.c +// @brief Helper: +// translate and re-send mouse and keyboard events +// from Windows message proc to AntTweakBar +// +// @author Philippe Decaudin - http://www.antisphere.com +// @date 2006/05/10 +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + +#include + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include + +// Mouse wheel support +#if !defined WM_MOUSEWHEEL +# define WM_MOUSEWHEEL 0x020A +#endif // WM_MOUSEWHEEL +#if !defined WHEEL_DELTA +#define WHEEL_DELTA 120 +#endif // WHEEL_DELTA + +#ifdef _WIN64 +#define PARAM_INT __int64 +#else +#define PARAM_INT int +#endif + +// TwEventWin returns zero if msg has not been handled, +// and a non-zero value if it has been handled by the AntTweakBar library. +int TW_CALL TwEventWin(void *wnd, unsigned int msg, unsigned PARAM_INT _W64 wParam, PARAM_INT _W64 lParam) +{ + int handled = 0; + static unsigned PARAM_INT s_PrevKeyDown = 0; + static PARAM_INT s_PrevKeyDownMod = 0; + static int s_PrevKeyDownHandled = 0; + + switch( msg ) + { + case WM_MOUSEMOVE: + // send signed! mouse coordinates + handled = TwMouseMotion((short)LOWORD(lParam), (short)HIWORD(lParam)); + break; + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + SetCapture(wnd); + handled = TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_LEFT); + break; + case WM_LBUTTONUP: + ReleaseCapture(); + handled = TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_LEFT); + break; + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + SetCapture(wnd); + handled = TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_MIDDLE); + break; + case WM_MBUTTONUP: + ReleaseCapture(); + handled = TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_MIDDLE); + break; + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + SetCapture(wnd); + handled = TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_RIGHT); + break; + case WM_RBUTTONUP: + ReleaseCapture(); + handled = TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_RIGHT); + break; + case WM_CHAR: + case WM_SYSCHAR: + { + int key = (int)(wParam&0xff); + int kmod = 0; + + if( GetAsyncKeyState(VK_SHIFT)<0 ) + kmod |= TW_KMOD_SHIFT; + if( GetAsyncKeyState(VK_CONTROL)<0 ) + { + kmod |= TW_KMOD_CTRL; + if( key>0 && key<27 ) + key += 'a'-1; + } + if( GetAsyncKeyState(VK_MENU)<0 ) + kmod |= TW_KMOD_ALT; + if( key>0 && key<256 ) + handled = TwKeyPressed(key, kmod); + } + break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + int kmod = 0; + int testkp = 0; + int k = 0; + + if( GetAsyncKeyState(VK_SHIFT)<0 ) + kmod |= TW_KMOD_SHIFT; + if( GetAsyncKeyState(VK_CONTROL)<0 ) + { + kmod |= TW_KMOD_CTRL; + testkp = 1; + } + if( GetAsyncKeyState(VK_MENU)<0 ) + { + kmod |= TW_KMOD_ALT; + testkp = 1; + } + if( wParam>=VK_F1 && wParam<=VK_F15 ) + k = TW_KEY_F1 + ((int)wParam-VK_F1); + else if( testkp && wParam>=VK_NUMPAD0 && wParam<=VK_NUMPAD9 ) + k = '0' + ((int)wParam-VK_NUMPAD0); + else + { + switch( wParam ) + { + case VK_UP: + k = TW_KEY_UP; + break; + case VK_DOWN: + k = TW_KEY_DOWN; + break; + case VK_LEFT: + k = TW_KEY_LEFT; + break; + case VK_RIGHT: + k = TW_KEY_RIGHT; + break; + case VK_INSERT: + k = TW_KEY_INSERT; + break; + case VK_DELETE: + k = TW_KEY_DELETE; + break; + case VK_PRIOR: + k = TW_KEY_PAGE_UP; + break; + case VK_NEXT: + k = TW_KEY_PAGE_DOWN; + break; + case VK_HOME: + k = TW_KEY_HOME; + break; + case VK_END: + k = TW_KEY_END; + break; + case VK_DIVIDE: + if( testkp ) + k = '/'; + break; + case VK_MULTIPLY: + if( testkp ) + k = '*'; + break; + case VK_SUBTRACT: + if( testkp ) + k = '-'; + break; + case VK_ADD: + if( testkp ) + k = '+'; + break; + case VK_DECIMAL: + if( testkp ) + k = '.'; + break; + default: + if( (kmod&TW_KMOD_CTRL) && (kmod&TW_KMOD_ALT) ) + k = MapVirtualKey( (UINT)wParam, 2 ) & 0x0000FFFF; + } + } + if( k!=0 ) + handled = TwKeyPressed(k, kmod); + else + { + // if the key will be handled at next WM_CHAR report this event as handled + int key = (int)(wParam&0xff); + if( kmod&TW_KMOD_CTRL && key>0 && key<27 ) + key += 'a'-1; + if( key>0 && key<256 ) + handled = TwKeyTest(key, kmod); + } + s_PrevKeyDown = wParam; + s_PrevKeyDownMod = kmod; + s_PrevKeyDownHandled = handled; + } + break; + case WM_KEYUP: + case WM_SYSKEYUP: + { + int kmod = 0; + if( GetAsyncKeyState(VK_SHIFT)<0 ) + kmod |= TW_KMOD_SHIFT; + if( GetAsyncKeyState(VK_CONTROL)<0 ) + kmod |= TW_KMOD_CTRL; + if( GetAsyncKeyState(VK_MENU)<0 ) + kmod |= TW_KMOD_ALT; + // if the key has been handled at previous WM_KEYDOWN report this event as handled + if( s_PrevKeyDown==wParam && s_PrevKeyDownMod==kmod ) + handled = s_PrevKeyDownHandled; + else + { + // if the key would have been handled report this event as handled + int key = (int)(wParam&0xff); + if( kmod&TW_KMOD_CTRL && key>0 && key<27 ) + key += 'a'-1; + if( key>0 && key<256 ) + handled = TwKeyTest(key, kmod); + } + // reset previous keydown + s_PrevKeyDown = 0; + s_PrevKeyDownMod = 0; + s_PrevKeyDownHandled = 0; + } + break; + case WM_MOUSEWHEEL: + { + static int s_WheelPos = 0; + s_WheelPos += ((short)HIWORD(wParam))/WHEEL_DELTA; + handled = TwMouseWheel(s_WheelPos); + } + break; + case WM_SIZE: + // tell the new size to AntTweakBar + TwWindowSize(LOWORD(lParam), HIWORD(lParam)); + // do not set 'handled', WM_SIZE may be also processed by the calling application + break; + } + + if( handled ) + // Event has been handled by AntTweakBar, so we invalidate the window + // content to send a WM_PAINT which will redraw the tweak bar(s). + InvalidateRect(wnd, NULL, FALSE); + + return handled; +} + + +// For compatibility with AntTweakBar versions prior to 1.11 +#undef TwEventWin32 +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus +TW_EXPORT_API int TW_CALL TwEventWin32(void *wnd, unsigned int msg, unsigned int _W64 wParam, int _W64 lParam) +{ + return TwEventWin(wnd, msg, wParam, lParam); +} +#ifdef __cplusplus +} +#endif // __cplusplus diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwEventWin32.c b/Extras/CDTestFramework/AntTweakBar/src/TwEventWin32.c new file mode 100644 index 0000000..3c39f77 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwEventWin32.c @@ -0,0 +1,188 @@ +// --------------------------------------------------------------------------- +// +// @file TwEventWin32.c +// @brief Helper: +// translate and re-send mouse and keyboard events +// from Win32 message proc to AntTweakBar +// +// @author Philippe Decaudin - http://www.antisphere.com +// @date 2006/05/10 +// @license This file is part of the AntTweakBar library. +// Copyright © 2005, 2006 Philippe Decaudin. +// For conditions of distribution and use, see License.txt +// +// note: TAB=4 +// +// --------------------------------------------------------------------------- + +#include + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include + +// Mouse wheel support +#if !defined WM_MOUSEWHEEL +# define WM_MOUSEWHEEL 0x020A +#endif // WM_MOUSEWHEEL +#if !defined WHEEL_DELTA +#define WHEEL_DELTA 120 +#endif // WHEEL_DELTA + + +// TwEventWin32 returns zero if msg has not been handled, +// and a non-zero value if it has been handled by the AntTweakBar library. +int TW_CALL TwEventWin32(void *wnd, unsigned int msg, unsigned int _W64 wParam, int _W64 lParam) +{ + int handled = 0; + switch( msg ) + { + case WM_MOUSEMOVE: + // send signed! mouse coordinates + handled = TwMouseMotion((short)LOWORD(lParam), (short)HIWORD(lParam)); + break; + case WM_LBUTTONDOWN: + SetCapture(wnd); + handled = TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_LEFT); + break; + case WM_LBUTTONUP: + ReleaseCapture(); + handled = TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_LEFT); + break; + case WM_MBUTTONDOWN: + SetCapture(wnd); + handled = TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_MIDDLE); + break; + case WM_MBUTTONUP: + ReleaseCapture(); + handled = TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_MIDDLE); + break; + case WM_RBUTTONDOWN: + SetCapture(wnd); + handled = TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_RIGHT); + break; + case WM_RBUTTONUP: + ReleaseCapture(); + handled = TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_RIGHT); + break; + case WM_CHAR: + case WM_SYSCHAR: + { + int key = (int)(wParam&0xff); + int kmod = 0; + + if( GetAsyncKeyState(VK_SHIFT)<0 ) + kmod |= TW_KMOD_SHIFT; + if( GetAsyncKeyState(VK_CONTROL)<0 ) + { + kmod |= TW_KMOD_CTRL; + if( key>0 && key<27 ) + key += 'a'-1; + } + if( GetAsyncKeyState(VK_MENU)<0 ) + kmod |= TW_KMOD_ALT; + if( key>0 && key<256 ) + handled = TwKeyPressed(key, kmod); + } + break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + int kmod = 0; + int testkp = 0; + int k = 0; + + if( GetAsyncKeyState(VK_SHIFT)<0 ) + kmod |= TW_KMOD_SHIFT; + if( GetAsyncKeyState(VK_CONTROL)<0 ) + { + kmod |= TW_KMOD_CTRL; + testkp = 1; + } + if( GetAsyncKeyState(VK_MENU)<0 ) + { + kmod |= TW_KMOD_ALT; + testkp = 1; + } + if( wParam>=VK_F1 && wParam<=VK_F15 ) + k = TW_KEY_F1 + ((int)wParam-VK_F1); + else if( testkp && wParam>=VK_NUMPAD0 && wParam<=VK_NUMPAD9 ) + k = '0' + ((int)wParam-VK_NUMPAD0); + else + { + switch( wParam ) + { + case VK_UP: + k = TW_KEY_UP; + break; + case VK_DOWN: + k = TW_KEY_DOWN; + break; + case VK_LEFT: + k = TW_KEY_LEFT; + break; + case VK_RIGHT: + k = TW_KEY_RIGHT; + break; + case VK_INSERT: + k = TW_KEY_INSERT; + break; + case VK_DELETE: + k = TW_KEY_DELETE; + break; + case VK_PRIOR: + k = TW_KEY_PAGE_UP; + break; + case VK_NEXT: + k = TW_KEY_PAGE_DOWN; + break; + case VK_HOME: + k = TW_KEY_HOME; + break; + case VK_END: + k = TW_KEY_END; + break; + case VK_DIVIDE: + if( testkp ) + k = '/'; + break; + case VK_MULTIPLY: + if( testkp ) + k = '*'; + break; + case VK_SUBTRACT: + if( testkp ) + k = '-'; + break; + case VK_ADD: + if( testkp ) + k = '+'; + break; + case VK_DECIMAL: + if( testkp ) + k = '.'; + break; + default: + if( (kmod&TW_KMOD_CTRL) && (kmod&TW_KMOD_ALT) ) + k = MapVirtualKey( (UINT)wParam, 2 ) & 0x0000FFFF; + } + } + if( k!=0 ) + handled = TwKeyPressed(k, kmod); + } + break; + case WM_MOUSEWHEEL: + { + static int s_WheelPos = 0; + s_WheelPos += ((short)HIWORD(wParam))/WHEEL_DELTA; + handled = TwMouseWheel(s_WheelPos); + } + break; + case WM_SIZE: + // tell the new size to TweakBar + TwWindowSize(LOWORD(lParam), HIWORD(lParam)); + // do not set 'handled', WM_SIZE may be also processed by the calling application + break; + } + + return handled; +} diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwEventX11.c b/Extras/CDTestFramework/AntTweakBar/src/TwEventX11.c new file mode 100644 index 0000000..92cd7d2 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwEventX11.c @@ -0,0 +1,205 @@ +// --------------------------------------------------------------------------- +// +// @file TwEventX11.c +// @brief Helper: +// translate and forward mouse and keyboard events +// from X11 to AntTweakBar +// +// @contrib Greg Popovitch +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + +#include +#include +#include +#include + +static int s_KMod = 0; +const int buff_sz = 80; + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +static int _XKeyRelease(XEvent *event) +{ + KeySym keysym; + char buffer[buff_sz]; + + XLookupString((XKeyEvent *)event, buffer, buff_sz, &keysym, 0); + + switch (keysym) + { + case XK_Control_L: + case XK_Control_R: s_KMod &= ~TW_KMOD_CTRL; break; + + case XK_Shift_L: + case XK_Shift_R: s_KMod &= ~TW_KMOD_SHIFT; break; + + case XK_Alt_L: + case XK_Alt_R: s_KMod &= ~TW_KMOD_ALT; break; + } + return 0; +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +static int _XKeyPress(XEvent *event) +{ + int modifiers = 0; // modifiers sent to AntTweakBar + int k = 0; // key sent to AntTweakBar + KeySym keysym; + char buffer[buff_sz]; + + int num_char = XLookupString((XKeyEvent *)event, buffer, buff_sz, &keysym, 0); + + if (event->xkey.state & ControlMask) + modifiers |= TW_KMOD_CTRL; + if (event->xkey.state & ShiftMask) + modifiers |= TW_KMOD_SHIFT; + if (event->xkey.state & Mod1Mask) + modifiers |= TW_KMOD_ALT; + + switch (keysym) + { + case XK_Control_L: + case XK_Control_R: s_KMod |= TW_KMOD_CTRL; break; + + case XK_Shift_L: + case XK_Shift_R: s_KMod |= TW_KMOD_SHIFT; break; + + case XK_Alt_L: + case XK_Alt_R: s_KMod |= TW_KMOD_ALT; break; + + case XK_Escape: k = TW_KEY_ESCAPE; break; + case XK_Help: k = TW_KEY_F1; break; + case XK_F1: k = TW_KEY_F1; break; + case XK_F2: k = TW_KEY_F2; break; + case XK_F3: k = TW_KEY_F3; break; + case XK_F4: k = TW_KEY_F4; break; + case XK_F5: k = TW_KEY_F5; break; + case XK_F6: k = TW_KEY_F6; break; + case XK_F7: k = TW_KEY_F7; break; + case XK_F8: k = TW_KEY_F8; break; + case XK_F9: k = TW_KEY_F9; break; + case XK_F10: k = TW_KEY_F10; break; + case XK_F11: k = TW_KEY_F11; break; + case XK_F12: k = TW_KEY_F12; break; + case XK_Up: k = TW_KEY_UP; break; + case XK_Down: k = TW_KEY_DOWN; break; + case XK_Right: k = TW_KEY_RIGHT; break; + case XK_Left: k = TW_KEY_LEFT; break; + case XK_Return: k = TW_KEY_RETURN; break; + case XK_Insert: k = TW_KEY_INSERT; break; + case XK_Delete: k = TW_KEY_DELETE; break; + case XK_BackSpace: k = TW_KEY_BACKSPACE; break; + case XK_Home: k = TW_KEY_HOME; break; + case XK_Tab: k = TW_KEY_TAB; break; + case XK_End: k = TW_KEY_END; break; + +#ifdef XK_Enter + case XK_Enter: k = TW_KEY_RETURN; break; +#endif + +#ifdef XK_KP_Home + case XK_KP_Home: k = TW_KEY_HOME; break; + case XK_KP_End: k = TW_KEY_END; break; + case XK_KP_Delete: k = TW_KEY_DELETE; break; +#endif + +#ifdef XK_KP_Up + case XK_KP_Up: k = TW_KEY_UP; break; + case XK_KP_Down: k = TW_KEY_DOWN; break; + case XK_KP_Right: k = TW_KEY_RIGHT; break; + case XK_KP_Left: k = TW_KEY_LEFT; break; +#endif + +#ifdef XK_KP_Page_Up + case XK_KP_Page_Up: k = TW_KEY_PAGE_UP; break; + case XK_KP_Page_Down: k = TW_KEY_PAGE_DOWN; break; +#endif + +#ifdef XK_KP_Tab + case XK_KP_Tab: k = TW_KEY_TAB; break; +#endif + + default: + if (0) + { + // should we do that, or rely on the buffer (see code below) + if (keysym > 12 && keysym < 127) + k = keysym; + } + break; + } + + if (k == 0 && num_char) + { + int i, handled = 0; + for (i=0; i 0) ? TwKeyPressed(k, modifiers) : 0; +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +static int _XButtonEvent(XEvent *event) +{ + TwMouseAction action = (event->type == ButtonPress) ? TW_MOUSE_PRESSED : TW_MOUSE_RELEASED; + XButtonEvent *xbe = (XButtonEvent *)event; + return TwMouseButton(action, xbe->button); +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +static int _XConfigureEvent(XEvent *event) +{ + XConfigureEvent *xce = (XConfigureEvent *)event; + TwWindowSize(xce->width, xce->height); + return 0; +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +static int _XMotionEvent(XEvent *event) +{ + XMotionEvent *xme = (XMotionEvent *)event; + return TwMouseMotion(xme->x, xme->y); +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +TW_API int TW_CDECL_CALL TwEventX11(void *xevent) +{ + XEvent *event = (XEvent *)xevent; + + switch (event->type) + { + case KeyPress: + return _XKeyPress(xevent); + + case KeyRelease: + return 0; // _XKeyRelease(xevent); + + case ButtonPress: + case ButtonRelease: + return _XButtonEvent(xevent); + + case MotionNotify: + return _XMotionEvent(xevent); + + case ConfigureNotify: + return _XConfigureEvent(xevent); + + default: + break; + } + return 0; +} + diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwFonts.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwFonts.cpp new file mode 100644 index 0000000..871f23b --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwFonts.cpp @@ -0,0 +1,4898 @@ +// --------------------------------------------------------------------------- +// +// @file TwFonts.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "TwMgr.h" +#include "TwFonts.h" + +// Fedora patch: memset() +using std::memset; + +// --------------------------------------------------------------------------- + +CTexFont::CTexFont() +{ + for( int i=0; i<256; ++i ) + { + m_CharU0[i] = 0; + m_CharU1[i] = 0; + m_CharV0[i] = 0; + m_CharV1[i] = 0; + m_CharWidth[i] = 0; + } + m_TexWidth = 0; + m_TexHeight = 0; + m_TexBytes = NULL; + m_NbCharRead = 0; + m_CharHeight = 0; +} + +// --------------------------------------------------------------------------- + +CTexFont::~CTexFont() +{ + if( m_TexBytes ) + delete[] m_TexBytes; + m_TexBytes = NULL; + m_TexWidth = 0; + m_TexHeight = 0; + m_NbCharRead = 0; +} + +// --------------------------------------------------------------------------- + +static int NextPow2(int _n) +{ + int r = 1; + while( r<_n ) + r *= 2; + return r; +} + +// --------------------------------------------------------------------------- + +const char *g_ErrBadFontHeight = "Cannot determine font height while reading font bitmap (check first pixel column)"; + +CTexFont *TwGenerateFont(const unsigned char *_Bitmap, int _BmWidth, int _BmHeight) +{ + // find height of the font + int x, y; + int h = 0, hh = 0; + int r, NbRow = 0; + for( y=0; y<_BmHeight; ++y ) + if( _Bitmap[y*_BmWidth]==0 ) + { + if( (hh<=0 && h<=0) || (h!=hh && h>0 && hh>0) ) + { + g_TwMgr->SetLastError(g_ErrBadFontHeight); + return NULL; + } + else if( h<=0 ) + h = hh; + else if( hh<=0 ) + break; + hh = 0; + ++NbRow; + } + else + ++hh; + + // find width and position of each character + int w = 0; + int x0[224], y0[224], x1[224], y1[224]; + int ch = 32; + int start; + for( r=0; rlmax ) + lmax = l; + } + // A little empty margin is added between chars to avoid artefact when antialiasing is on + const int MARGIN_X = 2; + const int MARGIN_Y = 2; + lmax += 16*MARGIN_X; + // - Second, build the texture + CTexFont *TexFont = new CTexFont; + TexFont->m_NbCharRead = ch-32; + TexFont->m_CharHeight = h; + TexFont->m_TexWidth = NextPow2(lmax); + TexFont->m_TexHeight = NextPow2(14*(h+MARGIN_Y)); + TexFont->m_TexBytes = new unsigned char[TexFont->m_TexWidth*TexFont->m_TexHeight]; + memset(TexFont->m_TexBytes, 0, TexFont->m_TexWidth*TexFont->m_TexHeight); + int xx; + float du = 0.4f; + float dv = 0.4f; + assert( g_TwMgr!=NULL ); + if( g_TwMgr ) + { + if( g_TwMgr->m_GraphAPI==TW_OPENGL || g_TwMgr->m_GraphAPI==TW_OPENGL_CORE ) + { + du = 0; + dv = 0; + } + else // texel alignement for D3D + { + du = 0.5f; + dv = 0.5f; + } + } + float alpha; + for( r=0; r<14; ++r ) + for( xx=0, ch=r*16; ch<(r+1)*16; ++ch ) + if( y1[ch]-y0[ch]==h-1 ) + { + for( y=0; ym_TexBytes[(xx+x-x0[ch])+(r*(h+MARGIN_Y)+y)*TexFont->m_TexWidth] = (unsigned char)(alpha*256.0f); + } + TexFont->m_CharU0[ch+32] = (float(xx)+du)/float(TexFont->m_TexWidth); + xx += x1[ch]-x0[ch]+1; + TexFont->m_CharU1[ch+32] = (float(xx)+du)/float(TexFont->m_TexWidth); + TexFont->m_CharV0[ch+32] = (float(r*(h+MARGIN_Y))+dv)/float(TexFont->m_TexHeight); + TexFont->m_CharV1[ch+32] = (float(r*(h+MARGIN_Y)+h)+dv)/float(TexFont->m_TexHeight); + TexFont->m_CharWidth[ch+32] = x1[ch]-x0[ch]+1; + xx += MARGIN_X; + } + + const unsigned char Undef = 127; // default character used as for undifined ones (having ascii codes from 0 to 31) + for( ch=0; ch<32; ++ch ) + { + TexFont->m_CharU0[ch] = TexFont->m_CharU0[Undef]; + TexFont->m_CharU1[ch] = TexFont->m_CharU1[Undef]; + TexFont->m_CharV0[ch] = TexFont->m_CharV0[Undef]; + TexFont->m_CharV1[ch] = TexFont->m_CharV1[Undef]; + TexFont->m_CharWidth[ch] = TexFont->m_CharWidth[Undef]/2; + } + + return TexFont; +} + +// --------------------------------------------------------------------------- + +CTexFont *g_DefaultSmallFont = NULL; +CTexFont *g_DefaultNormalFont = NULL; +CTexFont *g_DefaultLargeFont = NULL; +CTexFont *g_DefaultFixed1Font = NULL; + +// Small font +const int FONT0_BM_W = 211; +const int FONT0_BM_H = 84; +static const unsigned char s_Font0[] = +{ + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0, + 0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,0,0,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,255,0,255,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,0,0,255,255,0,0, + 0,255,0,0,0,0,255,255,0,0,0,255,0,0,255,0,0,255,0,0,255,0,255,0,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,255,0,0,0,255,0,0,255,255, + 255,0,0,255,255,255,0,0,0,0,0,255,0,255,255,255,255,0,0,255,255,0,0,255, + 255,255,255,0,0,255,255,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,0,0,0,0,255,0,255,0,255,0,0,0,255,0,0,255,0,0,255,255,255,255, + 0,255,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,255,0,255,0,0,0,0,255,0,0,255, + 255,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,255, + 255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,255,255,0,255,0,0,0,0,255,0,0,0,0,0, + 0,0,255,0,255,0,0,255,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,255,0,0,0,0,0,0,255,255,255,255,255,255,255,0,255,0,0,0,255,0,0, + 255,0,255,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,255,0,255,0,255,0,255, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,0,255,0,0,0, + 0,0,255,0,0,0,0,255,0,0,255,0,255,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0, + 255,0,0,255,0,255,0,0,255,0,0,255,0,0,255,0,0,0,0,0,255,255,0,0,0,0,0,0, + 0,0,0,255,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,0,0,0,0,255,0,0,0,0,0,0,0,255,0,255,0,0,0,255,255,0,0,0,0,255,255,0, + 255,0,255,255,0,0,0,255,255,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0, + 0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,0,255, + 0,0,0,0,255,0,0,0,255,255,0,0,255,0,0,255,0,255,255,255,0,0,255,255,255, + 0,0,0,0,255,0,0,0,255,255,0,0,0,255,255,255,0,0,255,0,0,255,0,0,0,255,255, + 0,0,0,255,255,255,255,255,255,0,0,0,0,255,255,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,255,0,0,0,0,0,255,255,255,255,255, + 255,0,0,0,255,255,0,0,0,0,0,255,0,255,0,0,255,0,255,0,0,255,0,0,0,0,255, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,255,0,0,0,0,0,255,0, + 0,255,0,0,255,0,0,255,0,0,0,255,0,0,0,0,0,0,255,0,255,255,255,255,255,0, + 0,0,255,0,255,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0, + 255,0,255,0,0,0,0,255,0,255,0,0,255,0,255,0,0,255,255,0,0,0,255,0,0,0,0, + 255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,255,0, + 0,255,0,0,255,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,255,0, + 0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,0,255,0,0,255,0,0,255,0,0,0,255,255, + 0,0,0,255,255,255,255,255,255,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,255,0,0,0,0,0,0,255,0,0,255,0,0,255, + 255,255,255,0,0,0,0,255,0,0,0,255,255,0,0,0,255,255,0,0,255,0,0,255,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,255, + 255,0,0,255,255,255,0,255,255,255,255,0,255,255,255,0,0,0,0,0,255,0,255, + 255,255,0,0,0,255,255,0,0,255,0,0,0,0,0,255,255,0,0,0,255,255,0,0,0,255, + 0,0,255,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,0,127,0,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,127,0,127,127,127,127,127,0,127,0,127,127,0,127,127,127,0,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,0,127,127,127,0,127,0,127, + 127,127,0,127,127,127,127,0,127,127,127,0,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,0,127,127,127,127,0,127,127,0,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,255,0,0,0,255,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,255,255,255,0,0,0,0,0, + 255,255,0,0,0,255,255,255,0,0,0,0,0,255,255,255,0,0,255,255,255,255,0,0, + 0,255,255,255,255,255,0,255,255,255,255,255,0,0,0,255,255,255,0,0,255,0, + 0,0,0,255,0,255,255,255,0,0,255,255,0,255,0,0,0,255,0,255,0,0,0,255,255, + 0,0,0,255,255,0,255,0,0,0,0,255,0,0,0,255,255,255,0,0,0,255,255,255,255, + 0,0,0,0,255,255,255,0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,255,255, + 255,255,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,255,0,0,255,0, + 255,0,0,255,0,255,0,0,0,255,0,255,255,255,255,0,255,0,0,255,0,0,0,0,255, + 0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,255,0, + 0,0,255,0,0,0,0,255,255,0,0,0,255,0,0,255,0,0,0,255,0,0,0,255,0,255,0,0, + 0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,255, + 0,0,255,0,0,0,0,255,0,255,0,0,255,0,0,255,0,0,0,255,255,0,0,0,255,255,0, + 255,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255, + 0,0,255,0,0,0,255,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,255,0, + 0,0,0,255,0,255,0,0,255,0,0,255,0,255,0,0,255,0,0,255,0,255,0,0,0,0,0,255, + 0,255,0,0,0,255,0,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,255,0,0,255,255,0,255,0,0,255,0,0,255,0,0,255,0,0,255, + 0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0, + 0,0,0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,0,255,0,255,0,255,0,0,0,255,0,0, + 0,255,0,255,0,255,0,255,0,255,0,255,0,0,255,0,255,0,0,0,0,0,255,0,255,0, + 0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,0,0,0,0,255,0,0, + 0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,255,0,255,0,255,0,0,255,255, + 0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,0,255,0,0,0,255,0,255,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,255,0,255,0,255, + 0,0,255,0,0,255,0,0,255,255,255,255,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255, + 0,255,255,255,255,0,0,255,255,255,255,0,0,255,0,0,255,255,255,0,255,255, + 255,255,255,255,0,0,255,0,0,0,0,255,0,255,255,0,0,0,0,255,0,0,0,255,0,255, + 0,255,0,255,0,255,0,0,255,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,255,0,255, + 0,0,0,0,0,255,0,255,255,255,255,0,0,0,255,255,255,0,0,0,0,255,0,0,0,255, + 0,0,0,0,255,0,0,255,0,0,255,0,0,255,0,255,0,255,0,255,0,0,255,255,0,0,0, + 0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,255,0,255,0,255,0,255,255,255, + 255,255,255,0,255,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0, + 0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,0,0,255, + 0,255,0,255,0,0,0,255,0,0,0,255,0,0,255,0,0,255,0,255,0,0,0,255,255,0,255, + 0,0,0,0,0,255,0,255,255,255,255,0,0,255,0,0,0,0,0,255,0,255,0,255,0,0,0, + 0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,255,0,0,255,0,0,255,0,255, + 0,255,0,255,0,0,255,255,0,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255, + 0,0,255,255,255,0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,0,255,0,0,0,255,0, + 255,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0, + 0,0,255,0,0,255,0,0,0,0,255,0,255,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0, + 255,0,255,0,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,0,0,0,255,0,0,0,255, + 0,0,255,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255, + 255,0,0,0,0,255,0,0,0,255,0,0,255,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,255, + 0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,255,255,255,255,0,0,0,0,255, + 255,255,0,0,255,255,255,255,0,0,0,255,255,255,255,255,0,255,0,0,0,0,0,0, + 0,255,255,255,255,0,255,0,0,0,0,255,0,255,255,255,0,255,255,0,0,255,0,0, + 0,255,0,255,255,255,255,255,0,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,255,255, + 255,0,0,0,255,0,0,0,0,0,0,0,255,255,255,0,0,0,255,0,0,0,255,0,255,255,255, + 255,0,0,0,0,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,0,0,0,0,255,0,0, + 0,255,0,0,255,0,0,255,0,0,0,255,0,0,0,255,255,255,255,0,255,0,0,0,0,255, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0, + 0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 0,0,0,0,0,255,255,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,0, + 127,127,127,127,127,127,0,127,127,127,0,127,127,127,0,127,127,127,127,127, + 0,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,0,127, + 127,0,127,127,127,0,127,127,0,127,127,127,127,127,0,127,127,127,127,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,255,0,0,0,0,0,0,0,255,0,0, + 0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0, + 255,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,4,4, + 4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0, + 0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0, + 0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,4,4,4,4,12,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,0,0,0,0,0,255,255,0,0,255,255,255,0,0,0,255,255,0,0,255,255,255,0,0, + 255,255,0,0,255,255,255,0,255,255,255,0,255,255,255,0,0,255,0,255,255,0, + 255,0,0,255,0,255,0,255,255,255,0,255,255,0,0,255,255,255,0,0,0,255,255, + 0,0,255,255,255,0,0,0,255,255,255,0,255,0,255,255,255,255,0,255,255,0,255, + 0,0,255,0,255,0,0,0,255,0,255,0,0,255,0,0,255,0,255,0,255,0,255,0,0,0,255, + 0,255,255,255,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0, + 255,0,255,0,0,255,0,255,0,0,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0, + 0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,255,0,0,255,0,255,0,0,255,0,0, + 255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,255,0, + 255,0,0,0,255,0,0,255,0,0,255,0,0,255,0,255,0,0,255,0,0,255,0,0,255,0,0, + 255,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,255, + 0,0,255,0,0,255,4,4,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,0,0,0,0,0,255,255,255,0,255,0,0,255,0,255,0,0,0,255,0,0,255,0, + 255,255,255,255,0,255,0,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255, + 255,0,0,0,255,0,255,0,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0, + 0,255,0,255,0,0,255,0,255,0,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,255, + 0,0,255,0,255,0,255,0,255,0,0,255,0,0,0,255,0,255,0,0,0,255,0,0,255,0,0, + 0,0,255,0,0,0,0,255,0,255,0,0,255,255,0,0,0,255,255,4,255,255,0,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,255,0,0,255,0,255,0, + 0,255,0,255,0,0,0,255,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,255,0,255,0, + 0,255,0,255,0,0,255,0,255,0,255,0,0,255,0,255,0,0,255,0,0,255,0,255,0,0, + 255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,0,0,255,0,255,0, + 0,255,0,0,255,0,0,255,0,255,0,0,0,255,255,0,255,255,0,0,0,255,0,0,0,255, + 0,255,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 0,255,255,255,0,255,255,255,0,0,0,255,255,0,0,255,255,255,0,0,255,255,255, + 0,255,0,0,0,255,255,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255, + 0,255,0,0,255,0,0,255,0,255,0,0,255,0,0,255,255,0,0,255,255,255,0,0,0,255, + 255,255,0,255,0,0,255,255,255,0,0,255,0,0,255,255,255,0,0,0,255,0,0,0,0, + 255,0,0,0,255,0,0,255,0,255,0,0,0,255,0,0,0,255,255,255,0,0,255,0,0,0,255, + 0,0,0,255,0,0,0,0,0,0,0,0,0,0,20,0,255,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255, + 0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,4,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,255,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,0,127,127,127,127,0, + 127,127,127,127,0,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127, + 127,0,127,127,127,127,0,127,127,127,127,0,127,0,127,127,0,127,127,127,127, + 0,127,0,127,127,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127, + 0,127,127,127,127,0,127,127,127,127,0,127,127,0,127,127,127,0,127,127,0, + 127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,0,127,127,127,127,127,0,127,127,127,0,127,127,127,0,127,127,127, + 0,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0, + 255,255,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 0,255,0,0,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,255,255,255,0,0,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,255,255,0,0, + 0,255,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,255,255,255,255,255,255,255, + 0,0,255,255,255,255,255,255,255,0,255,255,255,255,0,0,255,255,255,255,255, + 255,255,0,0,255,255,255,255,255,255,255,0,255,0,0,255,255,0,255,0,0,255, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,255,255,255,255,0,255, + 0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,0, + 0,255,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,255,255,255,255,0,255,255,255,255,255,0,0,0,0,0,0,255,0,0,255,0,255, + 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0, + 255,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,255,255, + 0,0,255,0,255,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255, + 0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 255,255,255,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255,0,0,255,0,255,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,255,0,255,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0, + 0,255,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,255,0, + 255,255,255,0,255,0,0,0,255,255,0,255,255,0,0,0,255,0,0,0,0,0,255,0,255, + 255,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,255,255,0,255,0,255, + 255,0,255,255,0,0,0,255,255,255,0,0,255,0,0,255,0,0,0,255,255,255,255,0, + 0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,255,0,0,255,0,0,255,0, + 0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,255,255,255,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 0,0,255,0,0,255,0,0,0,0,0,255,0,255,0,0,255,0,0,0,255,0,0,0,0,0,255,0,0, + 0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,0,255,255,255,255,0,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,255,255, + 255,255,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,255, + 0,0,255,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,255,0,255,0,0,255,0,0,255,0,0,0,0,0,255,0,0,255,0,255,0,0,0,255, + 0,0,0,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,255,0,0,255,0,0,0,0,0, + 255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,0,255,255,255,0,0,255,255,255,255,255,255,255,0,0,255, + 0,255,0,0,0,0,255,0,255,0,255,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,0,0,0,255,255,0,255,255,0,0,255,255,255,255,0,0,0,0,0,0,255, + 255,255,255,255,255,255,0,0,255,255,255,255,255,255,255,0,255,255,255,255, + 0,0,255,255,255,255,255,255,255,0,0,255,255,255,255,255,255,255,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,255,255,0,0,0,0,0,255,255,0,255,255,255,0,0,255,255,255,255,255, + 255,255,0,255,255,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,255,0,0,0,255,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,0,127,127, + 127,127,0,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,0, + 127,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,0,127,127,0,127,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,0,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,0,127,0,127, + 127,127,0,127,127,127,0,127,127,127,0,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 0,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,127,127,127,0,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,255,0,0,0,0,0,0,0,255,0, + 0,0,255,0,255,0,0,255,255,255,0,0,255,0,255,0,0,0,255,255,255,255,0,0,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,255,255,255,0,255,255,255,0,0,255,0,0,0,0,0,0, + 0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,255,0,0,0,0,0,0,0,0,255, + 0,0,255,0,0,0,0,0,255,0,0,0,255,0,0,0,255,255,255,0,0,255,0,0,0,0,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0, + 0,255,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,255,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,255, + 0,0,0,0,255,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,255,0,255, + 0,0,0,0,0,0,0,0,0,0,255,255,0,255,0,0,255,0,0,0,0,0,0,255,255,0,255,0,0, + 0,0,0,255,255,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,0,0,0,0,0,255,0,0,255,255,255,0,0,255,0,0,0,0,255,255,255,0,0,0,255, + 0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,255,0,0,255,255,0,0,255,255,0,255, + 0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,255,255,255,0,0,255,0,0,0,0,0, + 0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,255, + 255,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,255,0,255,0,255,0,0,0,255, + 0,255,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,0,0,255,0,255,0,255,0,0,255,255,255,0,0,0,255,0,255, + 0,0,0,0,255,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,255,0,255,0,0,0,0,255,0, + 255,255,0,255,0,255,0,0,0,255,255,255,255,255,0,0,0,0,255,0,255,0,0,255, + 0,255,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,255,255,255,0,255,255, + 0,0,0,0,0,0,255,0,0,255,0,255,255,0,255,0,0,255,0,0,0,0,0,0,0,255,255,255, + 0,255,255,0,0,0,255,0,255,0,0,255,255,0,0,255,255,0,0,0,255,0,255,0,255, + 255,0,0,255,255,0,255,0,255,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0, + 255,0,255,0,255,0,0,0,255,0,0,0,0,255,255,255,0,0,0,255,255,255,0,0,0,0, + 255,0,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0, + 0,0,0,255,0,255,255,0,255,0,255,255,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,255,0,0,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0,255,0,255,0,255,0,0,0,0,255, + 0,0,0,0,255,0,0,0,255,0,255,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 0,255,0,255,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0, + 255,255,255,0,0,0,0,0,0,255,0,0,255,255,0,0,255,0,0,0,0,0,255,0,255,0,0, + 0,0,0,0,255,0,0,0,0,255,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0,0,255,0,255,255,255,255,0,0,0,255, + 0,0,0,255,0,0,0,0,255,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0, + 0,0,0,255,0,0,255,255,255,0,255,255,255,255,0,0,0,0,0,0,0,0,0,255,0,0,0, + 255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,255,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,255, + 255,0,0,255,0,0,0,0,255,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0, + 0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,127,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,127,127,127,127,0,127,0,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,0,127,127,127,127, + 0,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,0,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 127,0,127,127,127,0,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127, + 127,127,0,127,127,127,0,127,127,127,0,127,127,127,127,0,127,127,127,127, + 0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,255,0, + 0,0,0,0,255,0,0,0,0,0,0,255,0,255,0,0,0,255,0,255,255,0,0,0,255,0,0,255, + 0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255, + 0,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,0,0,255,0,0,255,0,255,0,255, + 0,255,0,0,0,0,0,0,0,0,0,255,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0, + 0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,255,0,0,0,0,255,0,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,255, + 0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,127,0,0,255,255, + 0,0,0,0,0,255,255,0,0,0,0,0,255,255,0,0,0,0,0,255,255,0,0,0,0,0,255,255, + 0,0,0,0,0,255,255,0,0,0,0,0,255,255,255,255,255,0,0,0,255,255,255,0,0,255, + 255,255,255,255,0,255,255,255,255,255,0,255,255,255,255,255,0,255,255,255, + 255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255, + 255,255,0,0,0,255,0,0,0,0,255,0,0,0,255,255,255,0,0,0,0,0,255,255,255,0, + 0,0,0,0,255,255,255,0,0,0,0,0,255,255,255,0,0,0,0,0,255,255,255,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0, + 255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,0,255,0,0, + 255,0,127,0,0,255,255,0,0,0,0,0,255,255,0,0,0,0,0,255,255,0,0,0,0,0,255, + 255,0,0,0,0,0,255,255,0,0,0,0,0,255,255,0,0,0,0,255,0,255,0,0,0,0,0,255, + 0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255, + 0,0,0,255,0,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,255,0,0,0,255,0, + 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0, + 255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,255,0,0,0, + 0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,255, + 0,0,255,255,255,0,0,255,0,0,255,0,127,0,255,0,0,255,0,0,0,255,0,0,255,0, + 0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0, + 0,0,255,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0, + 0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,255,0,0,0, + 0,255,0,255,0,255,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,255,0,0,0,255, + 0,255,0,0,0,255,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0, + 255,0,255,0,0,0,0,255,0,0,255,0,255,0,0,255,0,0,255,0,255,0,255,0,0,127, + 0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0, + 0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,255,255,255,255,0,255,0,0,0, + 0,0,0,255,255,255,255,0,0,255,255,255,255,0,0,255,255,255,255,0,0,255,255, + 255,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,255,255,255,0,0,255, + 0,255,0,0,255,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0, + 0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,255,0,255,0,0,255, + 0,0,255,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0, + 255,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,255,0,255,0,0,255,0,127,255,255, + 255,255,255,255,0,255,255,255,255,255,255,0,255,255,255,255,255,255,0,255, + 255,255,255,255,255,0,255,255,255,255,255,255,0,255,255,255,255,255,255, + 0,0,255,255,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255, + 0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,255,0,0, + 0,0,255,0,255,0,0,0,255,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0, + 255,0,255,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255, + 0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,255,0,255,0,0,255,0,127,255,0, + 0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0, + 0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,255,0,0,0,0,0,255,0,0,0,255,0,255, + 0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0, + 0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,0,255,0,0,255,0,0,0,255, + 0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0, + 0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,0,0,255,0,0,255,0,0,0,0,255,0,255, + 0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,255, + 255,0,0,255,0,0,255,0,127,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0, + 0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,255, + 255,255,255,0,0,0,255,255,255,0,0,255,255,255,255,255,0,255,255,255,255, + 255,0,255,255,255,255,255,0,255,255,255,255,255,0,255,255,255,0,255,255, + 255,0,255,255,255,0,255,255,255,0,255,255,255,255,0,0,0,255,0,0,0,0,255, + 0,0,0,255,255,255,0,0,0,0,0,255,255,255,0,0,0,0,0,255,255,255,0,0,0,0,0, + 255,255,255,0,0,0,0,0,255,255,255,0,0,0,0,255,0,0,0,255,0,255,0,255,255, + 255,0,0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,255,255,255,255, + 0,0,0,255,255,255,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,255,0,0,127,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,0,127, + 127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 0,127,127,127,0,127,127,127,0,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,255,255,0,255,0, + 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0, + 0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,255,255,0,255, + 0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,255,255,0,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,255, + 0,0,0,0,255,0,0,0,255,0,255,0,255,0,255,255,0,0,255,0,255,0,0,255,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,255,0,255,0,0,255,0, + 255,0,0,255,0,255,0,255,0,255,255,0,255,0,0,255,255,0,255,0,255,255,0,0, + 0,255,0,0,0,0,255,0,0,0,255,0,255,0,255,0,255,255,0,255,0,0,255,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,255,0,255,0,0,255,0,255,0, + 0,0,255,0,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,0,255,255,0,0,0,255,255,0,0,0,255,255,0,0,0,255,255,0,0,0,255, + 255,0,0,0,255,255,0,0,255,255,255,0,255,255,0,0,0,255,255,0,0,255,255,0, + 0,0,255,255,0,0,0,255,255,0,0,0,255,255,0,0,0,255,0,255,0,0,255,0,0,255, + 0,0,0,0,255,0,255,255,255,0,0,0,255,255,0,0,0,255,255,0,0,0,255,255,0,0, + 0,255,255,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,255,0,0,255, + 0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,0,255,0,255,255,255, + 0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,255,0,0,0, + 0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,255, + 0,255,0,0,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,0,255, + 0,255,0,0,255,0,0,255,0,0,255,255,255,0,255,0,0,255,0,255,0,0,255,0,255, + 0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,0,255,255,255,255,255, + 0,255,0,0,255,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255, + 0,0,255,0,255,0,0,255,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,255,255,255,0,0,255,255,255,0,0,255,255,255,0,0,255,255,255, + 0,0,255,255,255,0,0,255,255,255,0,0,255,255,255,255,255,255,0,255,0,0,0, + 255,255,255,255,0,255,255,255,255,0,255,255,255,255,0,255,255,255,255,0, + 0,255,0,255,0,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0, + 255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,0,0,0,0,0,0,0,255, + 0,255,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,0, + 255,0,255,0,0,255,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,127,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0, + 255,0,255,0,0,255,0,255,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0, + 0,255,0,0,0,0,255,0,0,0,0,0,255,0,255,0,0,255,0,0,255,0,255,0,0,255,0,255, + 0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255,0, + 0,255,0,0,0,0,255,0,0,0,255,255,0,0,255,0,255,0,0,255,0,255,0,0,255,0,255, + 0,0,255,0,255,0,0,255,0,0,255,0,255,0,0,255,0,0,255,0,0,255,0,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,255,255,255,0,0,255,255,255,0,0,255, + 255,255,0,0,255,255,255,0,0,255,255,255,0,0,255,255,255,0,0,255,255,0,255, + 255,255,0,0,255,255,0,0,255,255,255,0,0,255,255,255,0,0,255,255,255,0,0, + 255,255,255,0,0,255,0,255,0,0,255,0,0,255,0,0,255,255,0,0,255,0,0,255,0, + 0,255,255,0,0,0,255,255,0,0,0,255,255,0,0,0,255,255,0,0,0,255,255,0,0,0, + 0,0,0,0,0,0,0,255,255,255,0,0,0,255,255,255,0,0,255,255,255,0,0,255,255, + 255,0,0,255,255,255,0,0,0,255,0,0,0,255,255,255,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,0,127,127,127,127,0,127,127, + 127,127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,0,127,127,127,127,0,127,127,127,127,0, + 127,127,127,127,0,127,127,127,127,0,127,127,0,127,0,127,127,0,127,127,0, + 127,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,0, + 127,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127, + 127,127,0,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,0,127, + 127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + + +// Normal font +const int FONT1_BM_W = 253; +const int FONT1_BM_H = 106; +static const unsigned char s_Font1[] = +{ + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,255, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0, + 0,255,0,255,0,0,0,0,0,255,0,0,0,0,255,255,0,0,0,0,255,0,0,0,0,0,255,255, + 255,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255,0,255,0,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,255,255,255,0,0,0,0,0, + 255,0,0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,0,0,0,255,0,0,255, + 255,255,255,255,255,0,0,0,255,255,255,0,0,255,255,255,255,255,255,0,0,255, + 255,255,255,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,127,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,255,255, + 255,0,0,255,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255, + 0,0,0,0,255,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,255,255,255,0,0,0,255,0,0,0,0,255,0, + 255,0,0,0,0,255,0,0,0,0,255,255,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255, + 0,0,255,0,255,0,255,0,255,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,255,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,255,0,0,255,0,255,0,255,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,255,0,0,0,0,0,0,255,0,0,0,0, + 0,0,0,0,0,0,255,0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,0,255, + 0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,255, + 0,0,0,0,255,0,255,0,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,255,0,255,0,0,0, + 0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0, + 0,255,0,0,0,0,0,0,255,0,0,255,0,0,255,0,0,255,255,255,255,255,0,0,255,255, + 255,255,255,0,0,0,0,0,0,255,0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255, + 0,0,0,255,0,0,0,0,0,0,255,255,0,0,0,0,255,255,255,255,255,255,0,0,0,0,255, + 255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,255,0,0, + 0,0,0,0,0,0,0,0,255,0,255,0,0,0,0,0,255,255,0,0,0,0,255,255,0,0,255,0,0, + 255,255,0,0,0,255,255,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0, + 255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,255,255,0,0,255,0,0,0,255, + 0,0,0,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,255,255,255, + 0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,255,255,0, + 0,0,0,0,0,0,255,0,255,0,0,255,0,255,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0, + 0,0,0,255,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,0,0,0,0,0,255,255, + 255,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,255, + 0,0,0,0,0,0,0,0,255,0,255,255,255,255,255,255,0,0,0,0,0,0,255,0,255,0,0, + 0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,255,255,255,255,255,0,0,0, + 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0, + 0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,255,0,0,0,0, + 0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,255,0,0,255, + 0,255,0,0,0,255,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0, + 0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,255, + 0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0, + 0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0, + 0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,255,0,0,0,0,0,255,0,255,0,255,0,0,0,0,0,255,0,0,255,0,0,255,0,255, + 0,0,0,255,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255, + 0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,0, + 255,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0, + 255,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0, + 0,0,255,0,0,0,255,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,255,0,0,0,0,0, + 0,0,0,0,255,0,255,0,0,0,0,0,0,255,255,255,0,0,0,0,0,255,0,0,0,0,255,255, + 0,0,0,255,255,255,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0, + 0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,255,255, + 255,0,0,0,255,255,255,255,255,0,255,255,255,255,255,255,0,0,255,255,255, + 255,0,0,0,0,0,0,255,0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,255, + 0,0,0,0,0,0,255,255,255,255,0,0,0,255,255,255,0,0,0,0,255,0,0,0,255,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,0, + 127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,0,127,127,127,0,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,0,127,127,127, + 127,0,127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,255,0,0,0,0,0,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,255, + 255,255,255,0,0,0,0,0,0,0,255,0,0,0,0,255,255,255,255,255,0,0,0,0,255,255, + 255,255,0,255,255,255,255,255,0,0,0,255,255,255,255,255,255,0,255,255,255, + 255,255,0,0,0,255,255,255,255,0,0,255,0,0,0,0,0,255,0,255,255,255,0,0,255, + 255,255,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,255,0,0,0,0,255,255,0,255, + 255,0,0,0,0,255,0,0,0,255,255,255,255,0,0,0,255,255,255,255,255,0,0,0,0, + 255,255,255,255,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,255,255, + 255,255,255,255,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0, + 0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,255,255,255, + 255,255,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,255,255,0,0,0,0,255,255,0,0, + 0,0,255,0,255,0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0, + 0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,0, + 0,255,0,0,0,0,0,255,0,255,0,0,0,255,0,0,255,0,0,0,0,0,255,255,0,0,0,0,255, + 255,0,255,255,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,255, + 0,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,255,0,0,255, + 0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0, + 0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,0,255,0,255,255,255,255,0,255,0,0,0,0,255,0,255,0,0,0,255,0,0, + 0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0, + 0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,255,0,0, + 255,0,0,0,255,0,0,0,0,0,255,0,255,0,0,255,0,255,0,255,0,255,0,0,0,255,0, + 255,0,0,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0, + 255,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0, + 0,255,0,0,0,255,0,0,255,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,0, + 255,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,255,0,0, + 0,255,0,0,255,0,0,0,255,0,255,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0, + 0,0,0,255,0,0,255,0,0,0,0,0,255,0,255,0,255,0,0,0,0,255,0,0,0,0,0,255,0, + 255,0,0,255,0,255,0,255,0,255,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0, + 0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0, + 255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,255,0,0,0,255,0,0,255,0,255, + 0,0,255,0,0,0,0,255,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,255, + 0,0,0,0,255,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,255,0,0,0,255,0,0,255,0,0,255,0,0,0,255, + 0,0,255,255,255,255,255,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,255,255, + 255,255,255,255,0,255,255,255,255,255,0,255,0,0,0,255,255,255,0,255,255, + 255,255,255,255,255,0,0,255,0,0,0,0,0,255,0,255,255,0,0,0,0,0,255,0,0,0, + 0,0,255,0,255,0,0,255,0,255,0,255,0,0,255,0,0,255,0,255,0,0,0,0,0,0,255, + 0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,255,255,255,0,0,0,0,255,255, + 255,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,255,0,0,0, + 255,0,0,255,0,255,0,0,255,0,0,0,0,255,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255, + 0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,255,0,0,0,255,0,0,255,0,0,255, + 0,0,0,255,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,255, + 0,0,0,0,0,255,0,255,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,255,0,0,255, + 0,255,0,0,0,255,0,255,0,255,0,0,0,0,0,0,255,0,255,255,255,255,255,0,0,255, + 0,0,0,0,0,0,255,0,255,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255, + 0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,0, + 255,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0, + 0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,127,255,0,255,0,0,0,255,0,0,255,0,0,255,255,255,255,255,0,0,255,0,0,0, + 0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0, + 0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,255,0,0, + 255,0,0,0,255,0,0,0,0,0,255,0,0,255,255,0,0,255,0,255,0,0,0,255,0,255,0, + 255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,255,0,0,0,255, + 0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,0,255,0,255, + 0,0,0,0,0,255,255,0,0,0,255,255,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0, + 0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,255,0,255,255,255,255, + 255,255,0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0, + 0,0,0,255,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0, + 0,0,0,255,0,0,255,0,0,0,0,0,255,0,255,0,0,0,255,0,0,255,0,0,0,0,0,255,0, + 0,0,0,0,0,255,0,255,0,0,0,0,255,255,0,0,255,0,0,0,0,255,0,0,255,0,0,0,0, + 0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,255, + 0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0, + 0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, + 255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,255,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,255,255,255, + 255,255,0,0,0,0,255,255,255,255,0,255,255,255,255,255,0,0,0,255,255,255, + 255,255,255,0,255,0,0,0,0,0,0,0,255,255,255,255,255,0,255,0,0,0,0,0,255, + 0,255,255,255,0,255,255,255,0,0,255,0,0,0,0,255,0,255,255,255,255,255,0, + 255,0,0,0,0,0,0,255,0,255,0,0,0,0,255,255,0,0,0,255,255,255,255,0,0,0,255, + 0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,255,0,0,0,0,255,0,0,255,255,255,255, + 0,0,0,0,0,255,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0, + 0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,255,255,255,255, + 255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,255,255,255,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,255,0,0, + 255,255,255,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 0,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0, + 0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,255, + 0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0, + 0,0,0,255,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,255,255,255,0,0,255,0,255,255, + 255,0,0,0,255,255,255,255,0,0,255,255,255,255,255,0,0,255,255,255,255,0, + 0,255,255,255,255,0,255,255,255,255,255,0,255,0,255,255,255,0,0,255,0,255, + 255,0,255,0,0,0,255,0,255,0,255,255,255,255,0,255,255,255,0,0,255,0,255, + 255,255,0,0,0,255,255,255,255,0,0,255,0,255,255,255,0,0,0,255,255,255,255, + 255,0,255,0,255,0,0,255,255,255,0,255,255,255,255,0,255,0,0,0,0,255,0,255, + 0,0,0,255,0,255,0,0,0,255,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,255, + 255,255,255,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 0,0,0,0,0,0,255,0,255,255,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,255,0,255, + 0,0,0,0,255,0,0,255,0,0,255,0,0,0,0,255,0,255,255,0,0,0,255,0,255,0,0,255, + 0,255,0,0,255,0,0,255,0,255,0,0,0,255,0,0,0,255,0,255,255,0,0,0,255,0,255, + 0,0,0,0,255,0,255,255,0,0,0,255,0,255,0,0,0,0,255,0,255,255,0,0,255,0,0, + 0,0,0,255,0,0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,0,0,255, + 0,0,255,0,255,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,0,255,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,0,255,0,0,0,0,255, + 0,255,0,0,0,0,255,0,255,0,0,255,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0, + 0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0, + 0,0,255,0,255,0,0,0,255,0,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,255,0,255, + 0,0,0,255,0,255,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,0,255, + 0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,255,0,0,0,255,0,0,0, + 255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0, + 0,255,255,255,255,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,255,0,255, + 255,255,255,255,255,0,0,255,0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255, + 0,0,255,0,255,255,0,0,0,0,255,0,255,0,0,0,255,0,0,0,255,0,255,0,0,0,0,255, + 0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255, + 255,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,255,0,255,0,0,0,255,0,255,0,255, + 0,255,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,0,0,255,255,0,0,0,0,0,0, + 255,0,0,0,0,0,255,255,0,0,255,0,0,255,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,255,0,0,0,255,0,255,0, + 0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,0,255,0,0,255, + 0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,255,0,255,0,255,0,0,0,255,0,255, + 0,0,0,255,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255, + 0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,255,0,0,0,255,0,0,0,0,255,0, + 0,255,0,255,0,0,0,255,0,255,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,255, + 0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,255, + 255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,255, + 255,0,255,0,0,0,0,255,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,0,255,0, + 255,0,0,255,0,255,0,0,255,0,0,255,0,255,0,0,0,255,0,0,0,255,0,255,0,0,0, + 0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,255,255,0,255,0,0, + 0,0,0,0,255,0,0,255,0,0,0,255,0,0,0,255,255,0,0,0,255,0,0,0,0,0,255,0,0, + 0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0, + 255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,255,255,255,255,0,255,255, + 255,255,255,0,0,0,255,255,255,255,0,0,255,255,255,0,255,0,0,255,255,255, + 255,0,0,0,255,0,0,0,255,255,255,0,255,0,255,0,0,0,0,255,0,255,0,0,255,0, + 255,0,0,0,255,0,255,0,255,0,0,0,255,0,0,0,255,0,255,0,0,0,0,255,0,0,255, + 255,255,255,0,0,255,255,255,255,255,0,0,0,255,255,255,0,255,0,255,0,0,0, + 255,255,255,0,0,0,0,255,255,0,0,255,255,255,0,255,0,0,0,255,0,0,0,0,0,255, + 0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,255,255,255,0,0,0,255, + 0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0, + 255,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,0,127,127,127,127,127,0, + 127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,0,127,127,0,127,127,127,127,127,0,127,0,127,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,0,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 0,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,0,127,127, + 127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,255,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0, + 0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,255,0,255, + 0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,127,0,0,255, + 255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0, + 255,0,0,255,0,0,0,255,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255, + 255,255,255,255,255,255,0,255,255,255,255,255,255,0,0,0,255,255,255,255, + 255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,0,255,0,0, + 0,255,0,255,0,255,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,0,255,255,0,0,0,255,255,255,0,255,0,0,0,255,0,0,255,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,0,0,255,255,0,0,255,0,0,0,0,0,255,0,127,0,255,0,0,0,0,0,0,0,255,0,0, + 0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,255,0,0,255,0,0, + 255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0, + 0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,255,0,255,0,0,0,255,0,255,0,255,0, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,0,255,255,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,127,255,0,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0, + 0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0,0,0,255, + 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0, + 0,0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255, + 0,255,0,255,0,0,255,255,255,0,0,255,0,0,0,0,255,255,255,255,0,255,255,255, + 0,0,0,0,255,0,0,0,0,0,0,0,255,0,255,255,255,255,0,0,255,0,0,0,255,0,0,127, + 255,255,255,255,255,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0, + 0,0,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255, + 0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,0, + 0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,255,0,0, + 0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,255,0,255, + 0,0,0,127,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,255,255,0,0,255,0,0,255,255,0,0,0,255,255,0,0,0,255,255, + 255,255,0,0,0,255,0,0,0,255,0,0,0,0,0,255,255,255,255,255,0,0,0,255,0,0, + 0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0, + 0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 0,0,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255, + 0,0,0,255,0,0,0,0,0,255,0,0,0,0,127,255,255,255,255,255,255,0,0,0,255,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 0,0,255,0,255,0,0,255,0,0,0,0,0,0,255,0,0,255,0,0,0,255,0,0,0,0,0,255,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0, + 0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,0,255,255,255,255,255,0,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,255, + 0,255,0,0,0,0,255,255,255,255,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,255,0, + 0,0,0,0,0,255,0,0,0,0,127,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,255,0,0,255,0,0,0, + 0,0,0,255,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0, + 0,255,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255, + 0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0, + 0,0,255,0,0,0,0,127,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,255,0, + 0,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,255,0,0,255,0,255, + 0,0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, + 0,0,255,0,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0, + 0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,255,0,0,0,0,0, + 0,0,255,0,0,0,0,127,0,0,255,255,255,255,0,0,0,255,255,255,255,255,255,255, + 255,255,0,0,255,0,0,0,255,0,0,0,0,0,255,0,255,0,0,255,0,0,255,0,0,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,255,0, + 0,0,255,255,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255, + 255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,0,255,255,255, + 255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,0,0,0,0,0,0,0,0,255,255,255,255,0,255,255,255,255,0,0,0,255,255, + 255,255,255,255,255,255,255,0,255,255,255,255,0,0,0,0,255,0,0,0,0,127,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,127,127,0,127,127,0,127,127,127,127,127,127,0,127,127,127,127,0,127, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,0, + 127,127,0,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127, + 0,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,0,127,127, + 127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,255,0,0,0, + 0,0,255,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0, + 255,0,0,0,0,255,255,255,255,0,0,255,0,0,255,0,0,0,0,0,255,255,255,255,0, + 0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,0,0,0,255,255,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,255,255,0,0,0,0,0,0, + 0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,255, + 255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 0,0,0,0,255,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,255,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,255, + 0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 255,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,255,0,0,0,255,0,0, + 0,0,0,0,0,0,0,255,255,0,0,0,255,0,0,0,0,0,0,255,255,0,0,0,0,255,0,0,0,0, + 0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,127,0,0,0,0,0,255,0,0,0,0,255,255,255,255,0,0,255,0,0,0,0, + 0,255,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,0,0,255,255,0,0,255,0,0,0,0,255,255,255,0,0,0,255,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,255,255,0,0,255,0,0,0,0,0,0,0,0, + 0,0,255,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,255,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,255,0,255,255,255,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,0,0,255,0,0,0,255,0,255,0,0,255,0,0,0,0,0,255,0,0,0,255,0,0,0, + 0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255,255,0,0,0,255,0,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,255,0,0, + 0,255,0,255,0,0,0,0,255,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,0,255,0, + 0,0,0,255,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,0,255, + 0,0,255,0,0,255,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255, + 0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,255,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,255,255,255,255,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,255,0,0, + 0,0,255,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,255, + 0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,255,0,0,0, + 0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0, + 0,0,0,255,0,0,255,0,0,255,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,0,255,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,255,0,0,255,255,255,255,0,0,255,255,255,0,0,0,0,0,0,0,0,0,255,0, + 0,0,0,255,0,0,255,255,255,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 0,255,0,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,255,255,0,0,0,0, + 255,0,0,255,0,255,255,255,0,0,0,0,0,0,255,0,255,0,0,255,255,0,0,0,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,255,0,0, + 0,255,0,255,0,0,0,255,255,255,255,255,0,0,0,255,0,0,255,0,0,0,255,255,255, + 255,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0, + 0,255,0,0,0,255,255,255,0,255,0,0,255,0,0,0,0,255,255,255,255,255,255,255, + 0,255,255,255,0,255,0,0,255,255,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255, + 0,0,0,0,255,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0, + 0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,255,0,0,0,0, + 255,0,0,255,255,255,0,255,0,0,255,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0, + 255,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255, + 0,0,255,0,0,0,0,0,0,0,0,255,0,0,255,0,0,255,0,0,255,0,0,0,0,0,0,0,0,255, + 0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,255,0,0,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,255,0,0,255,0,0,0,0,0, + 0,255,0,0,0,0,255,0,0,0,0,0,0,255,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,255,0,0,0,255,0,255, + 0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0, + 0,255,255,0,0,0,0,0,0,0,0,0,0,255,0,0,255,255,0,0,255,0,0,0,0,0,0,0,0,0, + 0,255,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,255,0,0,0,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,255,0,0,0,0,255,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,255,0,0,255, + 255,255,255,255,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,255,0,0,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,255,0,0,0,0,255,255,255,255,0,255,255,255,255,255,255,0,0,0,0, + 0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255, + 255,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0, + 0,0,0,0,255,255,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,255,0,0,0, + 0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,255,255,255,255,0,0,0,0,255, + 0,0,0,0,0,0,255,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,255,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,0,255,0,255,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 127,127,0,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,0, + 127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,0,127,127,127,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,127,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,255, + 0,0,0,0,0,255,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,255,0,0,0,0,255,255,0, + 0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,255,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255, + 255,0,0,0,0,0,0,0,255,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,255,0,0,0, + 255,0,255,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,255,0, + 0,0,255,0,0,255,0,0,0,255,0,0,0,255,0,0,255,0,0,255,255,0,255,0,0,0,0,0, + 0,0,0,0,0,255,0,255,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0, + 0,255,0,0,255,0,0,0,0,0,255,0,255,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,255, + 0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,255,0,0,0,0,0,0,0,255,0, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0, + 0,0,0,0,0,0,255,255,255,255,255,255,255,0,0,0,255,255,255,255,0,255,255, + 255,255,255,255,0,255,255,255,255,255,255,0,255,255,255,255,255,255,0,255, + 255,255,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255, + 255,0,0,255,255,255,255,0,0,0,255,255,0,0,0,0,255,0,0,0,255,255,255,255, + 0,0,0,0,0,255,255,255,255,0,0,0,0,0,255,255,255,255,0,0,0,0,0,255,255,255, + 255,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,127,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,0, + 255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255, + 0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255, + 0,0,0,255,0,0,255,255,0,0,0,0,255,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0, + 255,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,255,0,0,0, + 0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,255,0,0,0,255,0,0,255, + 0,0,0,0,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,127,0,0,255,0,255,0,0,0, + 0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255, + 0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, + 255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,255,0,255,0,255,0,0,0,255,0,255, + 0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0, + 0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,255, + 0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0, + 0,0,255,0,0,255,0,0,0,255,0,0,255,255,255,255,255,0,0,255,0,0,0,255,0,0, + 0,0,0,0,0,0,0,0,0,127,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0, + 255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0, + 0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0, + 255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0, + 0,255,0,0,0,0,255,0,255,0,255,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0, + 0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0, + 0,255,0,0,0,255,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,255,0,0,0,0,0,255, + 0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,255,0, + 255,0,0,0,255,0,0,0,0,255,0,255,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255, + 0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,255,255,255,255, + 255,0,255,0,0,0,0,0,0,255,255,255,255,255,255,0,255,255,255,255,255,255, + 0,255,255,255,255,255,255,0,255,255,255,255,255,255,0,0,255,0,0,0,255,0, + 0,0,255,0,0,0,255,0,0,255,255,255,255,0,0,255,0,255,0,0,255,0,0,255,0,255, + 0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0, + 0,0,0,255,0,255,0,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,0,255,0,0, + 0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,0,0, + 0,0,0,0,0,0,0,0,127,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0, + 255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255, + 255,255,255,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0, + 0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0, + 0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,255,0,255,0,0,0,0,0,0,255,0,255,0, + 0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0, + 0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,255,0,255,0,0,0,0,0,255, + 0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0,255, + 0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,127,0,255, + 255,255,255,255,0,0,0,255,255,255,255,255,0,0,0,255,255,255,255,255,0,0, + 0,255,255,255,255,255,0,0,0,255,255,255,255,255,0,0,0,255,255,255,255,255, + 0,0,0,255,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0, + 0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255, + 0,0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,255,0,255,0,0,0,0,0,0,255,0,255, + 0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0,0,0,0,255,0,255,0,0,0, + 0,0,0,255,0,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,0, + 255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0, + 255,0,0,0,0,255,255,255,255,255,0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0, + 127,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0, + 0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,255,0,0,0,255,0,0, + 0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255, + 0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0, + 255,0,0,0,0,255,255,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255, + 0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0, + 0,255,0,0,0,255,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0, + 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0, + 0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,127,255,0,0,0,0,0,255,0,255,0,0,0, + 0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255,0,0,0,0,0,255,0,255, + 0,0,0,0,0,255,0,255,0,0,0,0,255,255,255,255,255,0,0,0,255,255,255,255,0, + 255,255,255,255,255,255,0,255,255,255,255,255,255,0,255,255,255,255,255, + 255,0,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255, + 0,255,255,255,0,0,255,255,255,255,0,0,0,255,0,0,0,0,255,255,0,0,0,255,255, + 255,255,0,0,0,0,0,255,255,255,255,0,0,0,0,0,255,255,255,255,0,0,0,0,0,255, + 255,255,255,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 255,255,255,0,0,0,0,0,255,255,255,0,0,0,0,0,255,255,255,0,0,0,0,0,255,255, + 255,0,0,0,0,0,255,255,255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,0,255,0, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,0,127,127,127,0,127,127, + 127,0,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,255,0,0,0,0,0,0,255,0,0, + 0,0,255,255,0,0,0,255,255,0,255,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,255,255,0,0, + 0,0,0,0,0,0,0,0,255,0,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0, + 255,0,0,255,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,255,0,0,0,0,0,255,255,0,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0, + 0,255,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,255,0,0,0,0,255,0,0,0,0,255, + 0,0,255,0,255,0,255,255,0,0,0,255,0,0,255,0,0,255,0,0,255,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0, + 0,255,0,0,255,0,0,0,255,0,255,0,255,0,255,255,0,255,0,0,255,0,255,0,0,0, + 255,0,255,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,255, + 0,255,255,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,0,0,0,0,0,255,0,0,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,0,0,255,0, + 0,0,255,0,0,0,0,0,0,0,255,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,0,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255, + 0,0,0,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255,0,0,255,255,0,0,0, + 0,255,255,255,255,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,255,255, + 255,255,0,0,0,255,255,255,255,0,0,0,255,0,255,0,0,255,0,0,255,0,0,255,255, + 0,255,0,0,255,0,255,255,255,0,0,0,255,255,255,255,0,0,0,255,255,255,255, + 0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0, + 0,0,0,255,0,0,0,0,0,0,255,255,255,255,0,0,255,0,0,0,0,255,0,255,0,0,0,0, + 255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,255,0,255,0,255,255, + 255,0,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,255,0,0,0,0,0, + 255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255, + 255,0,0,255,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0, + 0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,255,0,0,255,0,0,255,0,0,0,0,0,0,255, + 0,255,255,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255, + 0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,255, + 0,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255, + 0,255,0,0,0,255,0,255,255,0,0,0,255,0,255,0,0,0,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,127,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0, + 255,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0,0, + 255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,255, + 0,0,255,0,0,255,0,0,255,255,255,255,255,0,255,0,0,0,0,255,0,255,0,0,0,0, + 255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0, + 255,0,0,0,0,0,0,0,0,0,0,255,0,0,0,255,0,255,0,255,0,0,0,0,255,0,255,0,0, + 0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,255,0,0,255,0,0,0, + 0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,255,255,255,255,0,0, + 255,255,255,255,0,0,255,255,255,255,0,0,255,255,255,255,0,0,255,255,255, + 255,0,0,255,255,255,255,0,0,255,255,255,255,255,255,255,255,255,0,255,0, + 0,0,0,0,255,255,255,255,255,255,0,255,255,255,255,255,255,0,255,255,255, + 255,255,255,0,255,255,255,255,255,255,0,0,255,0,255,0,0,255,0,0,255,0,255, + 0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255, + 0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,255,255,255,255, + 255,255,0,255,0,0,255,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255, + 0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,255,0,0,255,0,0,0,0,255,0,0,255, + 0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255,0,0,0,255,0,255,0,0,0,255,0,255, + 0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255, + 0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0, + 0,255,0,0,0,0,0,0,0,255,0,255,0,0,255,0,0,255,0,255,0,0,0,0,255,0,255,0, + 0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0, + 0,0,0,255,0,255,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,255,0,255,0,0,0,255,0,255, + 0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255, + 0,255,0,0,255,0,0,0,0,255,0,0,255,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,255, + 0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255,0,255,0,0,0,255, + 0,255,0,0,0,255,0,255,0,0,0,255,255,0,0,0,255,0,255,0,0,0,0,0,255,0,0,0, + 0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,0,255,0,255, + 0,0,255,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0, + 255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0,255,0,0,0,0,255,0, + 0,0,0,0,255,0,0,0,0,0,255,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255, + 255,0,255,0,0,0,255,255,0,255,0,0,0,255,255,0,0,0,255,0,0,0,255,0,0,0,0, + 255,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,255,255,255,255,0,0,255, + 255,255,255,0,0,255,255,255,255,0,0,255,255,255,255,0,0,255,255,255,255, + 0,0,255,255,255,255,0,0,255,255,255,0,0,255,255,255,0,0,0,255,255,255,255, + 0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,255, + 255,255,255,0,0,0,255,0,255,0,0,255,0,0,255,0,0,255,255,255,255,0,0,255, + 0,0,0,0,255,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,255,255,255, + 255,0,0,0,255,255,255,255,0,0,0,255,255,255,255,0,0,0,0,0,0,255,0,0,0,0, + 0,255,255,255,255,0,0,0,0,255,255,255,0,255,0,0,255,255,255,0,255,0,0,255, + 255,255,0,255,0,0,255,255,255,0,255,0,0,0,255,0,0,0,255,255,255,255,255, + 0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0, + 0,255,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 127,127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,0,127,0,127,127,0,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +// Normal font anti-aliased +const int FONT1AA_BM_W = 264; +const int FONT1AA_BM_H = 106; +static const unsigned char s_Font1AA[] = +{ + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0, + 0,0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0, + 59,241,97,206,166,0,0,0,0,0,0,0,0,0,0,0,0,0,168,34,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,251,89,0,0,89,255,125,89,255,125,0,0,0,0, + 7,199,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0, + 0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21,59,238,42, + 206,125,0,0,0,0,7,199,34,89,166,0,0,0,0,168,34,0,0,0,175,255,255,166,0, + 0,7,202,89,0,0,0,0,59,245,255,251,89,0,0,0,59,238,34,0,12,232,89,0,0,89, + 247,34,0,59,245,206,199,124,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,7,202,89,0,12,235,255,247,34,0,0,0,0,12,232,89,0,0,12,235, + 255,255,251,89,0,7,206,255,255,255,125,0,0,0,0,138,251,89,0,0,59,245,255, + 255,255,251,89,0,0,89,255,255,166,0,89,255,255,255,255,255,201,0,0,59,245, + 255,255,125,0,0,12,235,255,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255,255,255,247,34,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0, + 0,0,0,0,0,127,0,0,0,0,0,138,225,21,59,238,34,175,125,0,0,0,0,59,192,0,172, + 89,0,0,59,245,255,255,251,89,89,247,34,12,228,34,0,138,166,0,0,0,0,12,235, + 125,0,175,225,21,0,0,59,238,34,0,138,201,0,0,0,0,175,166,0,0,0,89,255,201, + 0,0,0,0,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,215,21,0,175, + 166,0,138,201,0,0,7,206,255,251,89,0,0,59,192,0,0,138,247,34,59,192,0,0, + 89,251,89,0,0,59,245,251,89,0,0,59,241,89,0,0,0,0,0,89,247,34,0,0,0,0,0, + 0,0,7,206,166,0,7,206,125,0,89,247,34,7,206,166,0,138,225,21,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,12,232,89,0,0,0,0,0,0,0,0,0,0,0,175,166,0,0,0,0,0, + 0,0,89,125,0,0,175,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0, + 0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21,12,206, + 21,175,125,0,0,89,255,255,255,255,255,255,166,59,241,89,168,34,138,125, + 89,225,21,7,202,89,12,228,34,0,0,0,0,12,232,89,0,138,201,0,0,0,12,206,21, + 7,202,89,0,0,0,0,59,215,21,59,245,206,199,124,255,125,0,0,0,0,7,202,89, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166,0,12,232,89,0,59,238,34,0,0, + 0,59,241,89,0,0,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,12,232,132,241,89, + 0,0,59,241,89,0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,89,247,34,0,12,232,89,0, + 12,232,89,59,241,89,0,59,241,89,0,138,247,34,0,0,138,247,34,0,0,0,0,0,12, + 235,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,138,255,166,0,0,0,0,0,0,0,0,0,138, + 225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0, + 0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,172, + 89,59,192,0,0,59,238,34,168,34,0,0,89,247,34,12,228,34,138,166,0,0,0,0, + 0,0,138,251,159,247,34,0,0,0,0,0,0,59,238,34,0,0,0,0,7,202,89,0,0,7,199, + 34,0,0,0,0,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,59, + 241,89,0,59,241,89,0,0,0,59,241,89,0,0,0,0,0,0,89,247,34,0,0,0,0,138,201, + 0,7,206,125,59,241,89,0,0,59,245,255,255,251,89,0,12,235,255,255,255,125, + 0,0,0,0,7,206,166,0,0,0,175,251,89,138,201,0,59,241,89,0,12,235,125,0,138, + 247,34,0,0,138,247,34,0,0,0,59,245,247,34,0,0,0,0,7,206,255,255,255,255, + 255,255,125,0,0,0,0,138,255,201,0,0,0,0,0,0,89,251,89,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0, + 127,0,0,0,0,0,138,201,0,0,0,0,0,0,0,0,0,12,206,21,138,125,0,0,7,206,255, + 247,34,0,0,0,175,255,255,166,59,215,21,175,255,255,125,0,0,138,171,206, + 166,0,175,201,0,0,0,0,89,201,0,0,0,0,0,0,175,125,0,0,0,0,0,0,0,0,12,235, + 255,255,255,255,255,255,125,0,0,0,0,138,255,255,251,89,0,0,0,0,0,59,215, + 21,0,59,241,89,0,59,241,89,0,0,0,59,241,89,0,0,0,0,0,12,235,166,0,0,0,138, + 255,255,125,0,175,201,0,59,241,89,0,0,0,0,0,0,175,247,34,59,241,89,0,89, + 247,34,0,0,0,89,247,34,0,0,0,89,255,255,255,125,0,12,235,166,0,59,245,125, + 0,0,0,0,0,0,0,0,0,0,0,175,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,89,251,89,0,0,7,206,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,201, + 0,0,0,0,0,0,0,12,235,255,255,255,255,255,225,21,0,0,0,175,255,251,89,0, + 0,0,0,0,175,125,89,225,21,59,238,34,89,225,21,12,235,166,175,166,0,0,0, + 0,89,201,0,0,0,0,0,0,175,125,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,138,166,0,0,59,241,89,0,59,241,89,0,0,0,59,241,89, + 0,0,0,0,12,235,166,0,0,0,0,0,0,59,241,97,206,255,255,255,255,255,125,0, + 0,0,0,0,59,241,89,59,238,34,0,12,235,125,0,0,12,235,125,0,0,0,12,232,89, + 0,59,245,125,0,89,255,255,232,241,89,0,0,0,0,0,0,0,0,0,0,0,0,59,245,247, + 34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,255,201,0,0,0,0,7,206,125,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4, + 4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,125,12,206,21, + 0,0,0,0,0,168,34,175,166,0,0,0,0,59,215,21,138,201,0,12,228,34,138,225, + 21,0,12,235,251,89,0,0,0,0,59,215,21,0,0,0,0,12,232,89,0,0,0,0,0,0,0,0, + 0,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,12,232,89,0, + 59,238,34,0,0,0,59,241,89,0,0,0,12,235,166,0,0,0,0,0,0,0,12,235,125,0,0, + 0,59,241,89,0,0,0,0,0,0,59,241,89,12,232,89,0,12,232,89,0,0,138,225,21, + 0,0,0,59,238,34,0,7,206,166,0,0,0,0,89,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,12,235,247,34,0,0,7,206,255,255,255,255,255,255,125,0,0,138,255,166,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0, + 0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21,0,0,0,0, + 0,0,0,0,172,89,89,166,0,0,0,89,166,0,168,42,206,125,0,0,0,7,202,89,0,89, + 225,21,59,238,34,89,251,89,0,0,175,255,201,0,0,0,0,7,202,89,0,0,0,0,59, + 215,21,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,0,0,138,247,34,0,0,0,0,0,7,206, + 201,0,12,228,34,0,0,0,175,166,0,138,201,0,0,0,0,59,241,89,0,0,12,235,166, + 0,0,0,0,89,166,0,0,89,251,89,0,0,0,59,241,89,0,0,59,192,0,0,175,225,21, + 0,175,201,0,138,225,21,0,12,235,125,0,0,0,0,12,235,166,0,59,241,89,0,0, + 0,7,206,166,0,0,138,247,34,0,0,59,245,125,0,0,0,0,0,0,0,12,232,89,0,0,0, + 0,0,0,0,0,0,0,0,175,166,0,0,0,0,0,0,0,0,7,206,166,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0, + 127,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,12,206,21,138,125,0,0,0,12,235,255, + 255,255,166,0,0,0,0,138,201,0,0,0,175,255,255,125,0,0,138,255,255,255,125, + 12,235,247,0,0,0,0,138,201,0,0,0,0,175,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,7,206,166,0,0,0,0,0,0,7,206,201,0,89,201,0,0,0,0,12,235,255,247, + 34,0,0,7,206,255,255,255,225,21,89,255,255,255,255,255,166,59,245,255,255, + 251,89,0,0,0,0,59,241,89,0,0,12,235,255,255,225,21,0,0,12,235,255,251,89, + 0,0,175,225,21,0,0,0,0,0,59,245,255,255,125,0,0,89,255,255,166,0,0,0,138, + 247,34,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,7,206,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4, + 0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,168,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,12,232,89,0,0,59,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,125, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0, + 4,4,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,168,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89, + 255,125,89,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,201,0,0,0,0, + 0,0,0,0,0,0,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,228,34,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0, + 127,127,127,127,0,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,0,127,127,127,127, + 0,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,0,127,127,127,0,127,127,127,127,0,127,127,127,0,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,0, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,255,125,138,166,0,0,0,89,255,255,247, + 34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,89,255,255, + 255,255,166,0,0,0,0,0,12,235,225,21,0,0,59,245,255,255,255,251,89,0,0,0, + 59,245,255,255,251,89,59,245,255,255,255,247,34,0,0,59,245,255,255,255, + 255,127,81,245,255,255,255,255,127,0,0,59,245,255,255,255,166,0,59,241, + 89,0,0,0,59,241,89,89,255,255,255,125,7,206,255,251,89,59,241,89,0,0,89, + 255,166,59,241,89,0,0,0,0,59,245,225,21,0,0,7,206,251,89,59,245,247,34, + 0,0,59,241,89,0,0,138,255,255,255,166,0,0,59,245,255,255,255,225,21,0,0, + 0,138,255,255,255,166,0,0,59,245,255,255,255,251,89,0,0,0,59,245,255,255, + 201,89,255,255,255,255,255,255,255,125,59,241,89,0,0,0,59,241,97,206,166, + 0,0,0,0,175,201,175,201,0,0,7,206,201,0,0,0,175,171,206,225,21,0,0,59,245, + 166,245,125,0,0,0,89,251,89,89,255,255,255,255,255,127,0,228,34,0,0,59, + 215,21,0,0,0,0,12,228,34,0,0,0,59,245,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,175,225,21,0,0,0,175,225,21,0,0,0,89,232,241,89,0,0,59, + 241,89,0,0,138,225,21,0,89,255,125,0,0,59,192,59,241,89,0,0,175,251,89, + 0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,89,255,125,0,0,7,199,34,59,241, + 89,0,0,0,59,241,89,0,59,241,89,0,0,0,59,241,89,59,241,89,0,59,241,89,0, + 59,241,89,0,0,0,0,59,245,255,125,0,0,89,255,251,89,59,245,255,201,0,0,59, + 241,89,0,138,251,89,0,12,235,166,0,59,241,89,0,7,206,225,21,0,138,251,89, + 0,12,235,166,0,59,241,89,0,0,138,247,34,0,12,235,125,0,7,176,21,0,0,59, + 241,89,0,0,0,59,241,89,0,0,0,59,241,89,138,225,21,0,0,12,235,125,89,225, + 21,0,59,245,247,34,0,12,232,89,12,235,166,0,7,206,166,0,89,247,34,0,7,206, + 125,0,0,0,0,0,7,206,166,12,228,34,0,0,7,202,89,0,0,0,0,12,228,34,0,0,12, + 235,133,206,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,138,201,0,138, + 255,255,255,125,138,166,0,0,7,206,166,175,166,0,0,59,241,89,0,0,89,247, + 34,7,206,166,0,0,0,0,0,59,241,89,0,0,0,175,225,21,59,241,89,0,0,0,0,59, + 241,89,0,0,0,0,7,206,166,0,0,0,0,0,0,59,241,89,0,0,0,59,241,89,0,59,241, + 89,0,0,0,59,241,89,59,241,89,59,241,89,0,0,59,241,89,0,0,0,0,59,241,159, + 225,21,0,175,166,241,89,59,241,132,241,89,0,59,241,89,12,235,166,0,0,0, + 89,247,34,59,241,89,0,0,89,247,34,12,235,166,0,0,0,89,247,34,59,241,89, + 0,0,59,241,89,0,59,238,34,0,0,0,0,0,0,59,241,89,0,0,0,59,241,89,0,0,0,59, + 241,89,59,241,89,0,0,89,225,21,59,241,89,0,89,206,202,89,0,59,238,34,0, + 89,251,89,138,225,21,0,0,175,201,0,138,225,21,0,0,0,0,0,175,225,21,12,228, + 34,0,0,0,138,166,0,0,0,0,12,228,34,0,7,206,166,0,12,235,125,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,7,202,89,89,225,21,7,206,125,12,206,21,0,59,238, + 34,89,247,34,0,59,241,89,0,0,175,201,0,59,241,89,0,0,0,0,0,59,241,89,0, + 0,0,59,241,89,59,241,89,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,0, + 59,241,89,0,0,0,59,241,89,0,59,241,89,0,0,0,59,241,89,59,241,102,232,89, + 0,0,0,59,241,89,0,0,0,0,59,241,102,232,89,59,215,81,241,89,59,241,89,138, + 225,21,59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,7,206,201,0,59,241, + 89,0,0,0,59,241,89,59,241,89,0,0,175,201,0,0,12,235,166,0,0,0,0,0,0,59, + 241,89,0,0,0,59,241,89,0,0,0,59,241,89,7,206,166,0,0,175,166,0,7,206,125, + 0,175,125,175,166,0,138,201,0,0,0,175,255,251,89,0,0,0,59,245,166,241,89, + 0,0,0,0,0,89,247,34,0,12,228,34,0,0,0,89,201,0,0,0,0,12,228,34,12,235,201, + 0,0,0,59,245,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,59,215,21,175,125, + 0,7,206,125,7,199,34,0,138,201,0,12,235,125,0,59,245,255,255,255,247,34, + 0,59,241,89,0,0,0,0,0,59,241,89,0,0,0,59,241,89,59,245,255,255,255,255, + 127,59,245,255,255,255,255,127,59,241,89,0,0,0,0,0,0,59,245,255,255,255, + 255,255,251,89,0,59,241,89,0,0,0,59,241,89,59,245,255,247,34,0,0,0,59,241, + 89,0,0,0,0,59,241,89,138,201,175,166,59,241,89,59,241,89,12,235,125,59, + 241,89,59,241,89,0,0,0,12,235,125,59,245,255,255,255,201,0,0,59,241,89, + 0,0,0,12,235,125,59,245,255,255,255,125,0,0,0,0,59,245,255,255,125,0,0, + 0,59,241,89,0,0,0,59,241,89,0,0,0,59,241,89,0,138,225,21,59,241,89,0,0, + 175,201,7,202,89,89,201,0,175,166,0,0,0,12,235,166,0,0,0,0,0,138,255,166, + 0,0,0,0,0,59,245,125,0,0,12,228,34,0,0,0,12,228,34,0,0,0,12,228,34,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,59,215,21,175,125,0,7, + 206,125,7,199,34,7,206,125,0,0,175,201,0,59,241,89,0,0,89,247,34,59,241, + 89,0,0,0,0,0,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,0,59,241,89,0,0, + 0,0,59,241,89,0,59,245,255,251,89,59,241,89,0,0,0,59,241,89,0,59,241,89, + 0,0,0,59,241,89,59,241,89,175,225,21,0,0,59,241,89,0,0,0,0,59,241,89,12, + 235,247,34,59,241,89,59,241,89,0,89,247,94,241,89,59,241,89,0,0,0,59,241, + 89,59,241,89,0,0,0,0,0,59,241,89,0,0,0,59,241,89,59,241,89,12,235,166,0, + 0,0,0,0,0,0,138,251,89,0,0,59,241,89,0,0,0,59,241,89,0,0,0,59,241,89,0, + 12,232,89,138,225,21,0,0,89,225,81,215,21,12,228,47,232,89,0,0,0,175,255, + 251,89,0,0,0,0,59,241,89,0,0,0,0,7,206,201,0,0,0,12,228,34,0,0,0,0,175, + 125,0,0,0,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 12,228,34,89,201,0,7,206,125,59,215,21,59,245,255,255,255,255,247,34,59, + 241,89,0,0,59,241,89,7,206,166,0,0,0,0,0,59,241,89,0,0,0,138,225,21,59, + 241,89,0,0,0,0,59,241,89,0,0,0,0,7,206,166,0,0,0,59,241,89,59,241,89,0, + 0,0,59,241,89,0,59,241,89,0,0,0,59,241,89,59,241,89,7,206,201,0,0,59,241, + 89,0,0,0,0,59,241,89,0,175,166,0,59,241,89,59,241,89,0,7,206,200,241,89, + 12,235,166,0,0,0,89,247,34,59,241,89,0,0,0,0,0,12,235,166,0,0,0,89,247, + 34,59,241,89,0,59,245,125,0,0,0,0,0,0,12,232,89,0,0,59,241,89,0,0,0,12, + 232,89,0,0,0,59,238,34,0,0,175,171,206,166,0,0,0,12,232,159,201,0,7,202, + 132,215,21,0,0,89,247,34,175,225,21,0,0,0,59,241,89,0,0,0,0,138,225,21, + 0,0,0,12,228,34,0,0,0,0,89,201,0,0,0,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,138,201,7,206,255,251,226,255,255,166,0, + 138,201,0,0,0,12,235,125,59,241,89,0,0,138,247,34,0,89,255,125,0,0,59,192, + 59,241,89,0,0,138,251,89,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,89,255, + 125,0,0,59,241,89,59,241,89,0,0,0,59,241,89,0,59,241,89,0,0,0,89,247,34, + 59,241,89,0,12,235,166,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,59,241,89, + 59,241,89,0,0,59,245,251,89,0,138,251,89,0,59,245,166,0,59,241,89,0,0,0, + 0,0,0,138,251,89,0,59,245,166,0,59,241,89,0,0,138,251,89,0,89,166,0,0,89, + 247,34,0,0,59,241,89,0,0,0,0,138,225,21,0,7,206,166,0,0,0,89,255,251,89, + 0,0,0,7,206,255,125,0,0,138,255,201,0,0,12,235,125,0,12,235,166,0,0,0,59, + 241,89,0,0,0,89,251,89,0,0,0,0,12,228,34,0,0,0,0,12,228,34,0,0,12,228,34, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,7,206,225,21,0, + 0,0,0,0,0,7,206,125,0,0,0,0,175,201,59,245,255,255,255,247,34,0,0,0,59, + 245,255,255,251,89,59,245,255,255,255,225,21,0,0,59,245,255,255,255,255, + 127,81,241,89,0,0,0,0,0,0,59,245,255,255,255,201,0,59,241,89,0,0,0,59,241, + 89,89,255,255,255,138,235,255,255,125,0,59,241,89,0,0,89,255,201,59,245, + 255,255,255,255,166,59,241,89,0,0,0,0,59,241,89,59,241,89,0,0,0,175,251, + 89,0,0,138,255,255,255,166,0,0,59,241,89,0,0,0,0,0,0,0,138,255,255,255, + 166,0,0,59,241,89,0,0,0,175,251,89,12,235,255,255,251,89,0,0,0,59,241,89, + 0,0,0,0,0,59,245,255,251,89,0,0,0,0,12,235,201,0,0,0,0,0,138,251,89,0,0, + 89,255,125,0,7,206,225,21,0,0,89,255,125,0,0,59,241,89,0,0,0,175,255,255, + 255,255,255,127,0,228,34,0,0,0,0,0,175,125,0,0,12,228,34,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,89,255,255,255,255,125,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, + 228,34,0,0,0,0,0,89,201,0,0,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,138,255,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,255,125,0,0,0,12,228, + 124,255,255,247,34,0,0,0,0,0,0,0,0,0,245,255,255,255,255,255,255,0,0,0, + 0,0,0,0,0,0,0,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,0,127, + 127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,0,89,255,125,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,89,255,255,166,0,0,0,0,0, + 0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,255,201,0,12,228, + 34,0,0,89,255,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,116,116, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,0,59,241,89,0,0,0,0,0,0,0,0,0,59,241,89,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0, + 0,0,0,59,241,89,0,0,0,0,59,241,89,0,89,251,89,59,241,89,0,0,0,0,59,241, + 89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,225, + 21,0,0,12,228,34,0,0,0,0,138,201,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4, + 4,4,28,244,252,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59, + 241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,59,241,89,0, + 0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,59,241, + 89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166, + 0,0,0,12,228,34,0,0,0,0,89,225,21,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4, + 4,180,252,164,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,7,206,255,255,255, + 125,0,59,241,194,255,251,89,0,0,7,206,255,255,201,0,12,235,255,255,251, + 89,0,12,235,255,251,89,7,206,255,255,247,34,0,12,235,255,255,251,89,59, + 241,194,255,255,125,0,59,241,89,89,255,251,89,59,241,89,0,138,251,89,59, + 241,89,59,241,159,255,255,125,89,255,255,166,0,59,241,194,255,255,125,0, + 0,0,12,235,255,247,34,0,59,241,194,255,255,125,0,0,12,235,255,255,251,89, + 59,241,159,255,201,0,138,255,255,247,34,206,255,255,255,166,59,241,89,0, + 59,241,97,206,166,0,0,12,235,125,175,201,0,7,206,166,0,7,206,133,206,225, + 21,0,89,255,255,166,0,0,12,235,125,138,255,255,255,255,166,0,0,138,166, + 0,0,0,12,228,34,0,0,0,0,89,225,21,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4, + 76,252,244,20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,89,247,34, + 59,245,166,0,138,225,21,7,206,201,0,0,0,7,206,166,0,59,241,89,7,206,125, + 0,89,225,21,59,241,89,0,0,7,206,166,0,59,241,89,59,245,166,0,89,247,34, + 59,241,89,0,59,241,89,59,241,89,138,225,21,0,59,241,89,59,245,201,0,89, + 255,201,0,89,247,34,59,245,166,0,89,247,34,0,7,206,166,0,138,225,21,59, + 245,166,0,138,247,34,7,206,166,0,59,241,89,59,245,201,0,0,59,238,34,0,130, + 34,59,241,89,0,0,59,241,89,0,59,241,89,89,247,34,0,89,247,34,138,225,21, + 12,235,225,21,12,232,89,7,206,166,12,235,125,89,247,34,0,89,247,34,0,0, + 0,89,247,34,0,0,138,166,0,0,0,12,228,34,0,0,0,0,89,225,21,0,0,7,206,247, + 34,0,0,89,201,0,0,4,4,68,12,4,4,4,220,252,108,4,4,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,0,0,0,0,0,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,0,0,59, + 241,89,0,59,241,89,59,238,34,0,59,238,34,59,241,89,0,0,59,241,89,0,59,241, + 89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,159,201,0,0,0,59, + 241,89,59,241,89,0,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,59,241, + 89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0, + 0,59,241,89,0,0,0,59,241,89,0,0,59,241,89,0,59,241,89,12,235,125,0,175, + 166,0,59,238,34,89,171,202,89,89,225,21,0,59,241,226,201,0,12,235,125,0, + 175,166,0,0,0,12,235,125,0,0,59,238,34,0,0,0,12,228,34,0,0,0,0,7,206,125, + 0,7,202,89,12,235,166,0,175,125,0,0,4,60,244,172,4,4,132,252,212,4,4,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,89,255,255,255,251,89,59,241,89, + 0,59,241,89,59,238,34,0,0,0,59,238,34,0,59,241,89,59,245,255,255,255,251, + 0,59,241,89,0,0,59,238,34,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0, + 59,241,89,59,245,255,225,21,0,0,59,241,89,59,241,89,0,59,241,89,0,59,241, + 89,59,241,89,0,59,241,89,0,59,238,34,0,12,232,89,59,241,89,0,12,232,89, + 59,238,34,0,59,241,89,59,241,89,0,0,0,175,255,255,201,0,59,241,89,0,0,59, + 241,89,0,59,241,89,0,175,201,12,232,89,0,7,206,125,172,89,138,166,138,201, + 0,0,0,138,247,34,0,0,175,201,12,232,89,0,0,7,206,166,0,0,175,225,21,0,0, + 0,0,12,228,34,0,0,0,0,0,0,175,225,34,206,21,0,0,175,255,166,0,0,0,4,52, + 244,252,140,36,244,252,60,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,59, + 241,89,0,59,241,89,59,241,89,0,59,238,34,59,241,89,0,0,0,59,241,89,0,59, + 241,89,59,238,34,0,0,0,0,59,241,89,0,0,59,241,89,0,59,241,89,59,241,89, + 0,59,241,89,59,241,89,0,59,241,89,59,241,97,206,201,0,0,59,241,89,59,241, + 89,0,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,59,241,89,0,59,241,89, + 59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,0,0,0,0,59,245, + 125,59,241,89,0,0,59,241,89,0,59,241,89,0,59,238,124,225,21,0,0,175,176, + 206,21,59,215,187,125,0,0,59,245,255,201,0,0,89,247,124,225,21,0,0,138, + 225,21,0,0,0,59,241,89,0,0,0,12,228,34,0,0,0,0,12,235,125,0,0,0,0,0,0,0, + 0,0,0,0,0,4,4,76,252,252,220,252,164,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,0,0,0,0,0,89,247,34,0,89,251,89,59,241,89,0,175,201,0,7,206,201,0,0,0, + 7,206,166,0,138,251,89,7,206,166,0,7,199,34,59,241,89,0,0,7,206,166,0,138, + 251,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,12,235,166, + 0,59,241,89,59,241,89,0,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,7, + 206,166,0,138,225,21,59,241,89,0,138,225,21,7,206,166,0,89,251,89,59,241, + 89,0,0,89,125,0,12,232,89,12,232,89,0,12,12,235,125,0,175,251,89,0,7,206, + 255,125,0,0,0,89,255,201,0,7,206,247,34,0,7,206,166,59,245,125,0,7,206, + 255,125,0,0,59,241,89,0,0,0,0,0,138,166,0,0,0,12,228,34,0,0,0,0,89,225, + 21,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,100,252,252,244,28,4,4,4,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,0,0,0,175,255,255,232,241,89,59,245,255,255,247,34, + 0,0,12,235,255,255,201,0,59,245,255,200,241,89,0,12,235,255,251,89,0,59, + 241,89,0,0,0,12,235,255,200,241,89,59,241,89,0,59,241,89,59,241,89,0,59, + 241,89,59,241,89,0,59,245,201,59,241,89,59,241,89,0,59,241,89,0,59,241, + 89,59,241,89,0,59,241,89,0,0,12,235,255,247,34,0,59,245,166,255,247,34, + 0,0,59,245,255,166,241,89,59,241,89,0,0,59,245,255,255,166,0,0,138,255, + 255,125,0,89,255,255,166,241,89,0,0,138,247,34,0,0,0,59,245,125,0,0,138, + 225,21,7,206,225,21,0,138,251,0,0,138,247,34,0,0,175,255,255,255,255,166, + 0,0,138,166,0,0,0,12,228,34,0,0,0,0,89,225,21,0,0,0,0,0,0,0,0,0,0,0,0,4, + 4,4,4,132,252,108,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,89,247,34,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0, + 0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,232,89,0,0,0,0,0,0,0,0,0,0,0,138, + 201,0,0,0,12,228,34,0,0,0,0,138,201,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4, + 116,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,166,255,255, + 247,34,0,0,0,0,0,0,0,0,0,0,0,255,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,59, + 241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,7,206,255, + 201,0,12,228,34,0,0,89,255,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4, + 4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,0,127,127,127,0,127,127,127, + 127,127,127,0,127,127,0,127,127,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,0,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,127,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,89,247,34,138,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,59,238,34,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255, + 225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,235,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,238,34,138,201,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,34,0,0,0,0,0,7,199,34,0,0,0,0,138,255, + 201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,251,89,0,0,138,255,251,97,206,201,0,0,138, + 251,102,235,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255, + 201,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0,7,206,166,12,232,89,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,166,12,235,127,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,0,175,255,255,255,225,21,59,245,255,255,255, + 255,255,125,0,0,0,0,0,0,0,7,206,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,7,199,34,0,0,0,0,0,7,199,34,0,0,0,138,225,21,175,166,0,0,175,255,255, + 166,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,59,245,255,255,201,0,0,0,0,0,0,0,0, + 59,245,255,255,255,255,255,255,255,255,125,0,59,245,255,255,255,255,255, + 125,0,0,89,255,255,255,255,255,225,21,59,245,255,255,255,255,255,125,0, + 0,0,59,245,255,255,255,255,255,125,7,206,166,0,0,175,171,206,166,89,247, + 34,0,175,201,59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,228,34,175,255,125,0,0,89,255,255,255,125,175,251,89,89,255,125,0,7, + 206,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,255,255,255, + 255,255,125,0,0,7,206,255,125,59,245,125,0,0,0,89,251,89,0,0,0,0,0,0,0, + 127,7,206,225,21,0,0,0,0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,0,175,201,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,255,255,255,255,125,0,59,245,255, + 255,255,255,125,0,0,0,0,0,0,0,89,247,34,12,228,34,0,138,166,0,0,0,0,0,0, + 0,0,0,0,12,235,125,0,7,176,21,0,0,0,0,0,0,138,251,89,0,0,138,201,0,0,0, + 0,0,0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,7,206,166,0,59,115,0,0,0,0,59,115, + 0,0,0,59,115,0,0,0,0,59,115,0,89,201,0,12,232,89,89,201,7,202,89,12,232, + 89,138,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,7,199,34,0,172,132,196,199,163,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,0,89,247,34,0,7, + 206,125,0,0,0,0,0,0,0,0,127,89,247,34,0,0,0,0,0,59,115,0,0,0,0,59,115,0, + 0,0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,34,0, + 0,0,0,0,7,199,34,0,0,0,0,0,0,0,0,0,89,225,21,7,202,89,12,228,34,0,0,0,0, + 0,0,0,0,0,0,59,238,34,0,0,0,0,0,0,0,130,34,59,241,89,0,0,0,138,201,0,0, + 0,0,0,0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,175,225,21,0,59,115,0,0,0,0,59, + 115,0,0,0,59,115,0,0,0,0,59,115,0,12,228,34,59,192,0,12,228,34,138,166, + 59,215,21,175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,7,199,34,0,172,89,175,166,138,125,0,138,255,255,247,34,12, + 146,0,0,0,0,89,255,255,255,125,12,235,255,255,125,0,0,0,59,115,0,0,0,0, + 59,115,0,138,255,255,255,255,127,0,175,201,0,138,225,21,0,0,0,0,0,0,0,0, + 127,245,255,255,255,255,255,125,0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,12, + 232,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,34,0,0,0,0,0,7,199, + 34,0,0,0,0,0,0,0,0,0,89,247,34,12,228,34,138,166,0,0,0,0,0,0,0,0,0,0,0, + 12,235,166,0,0,0,0,0,0,175,225,21,138,225,21,0,0,0,138,201,0,0,0,0,0,0, + 59,115,0,0,0,0,59,115,0,0,0,0,0,89,247,34,0,0,59,115,0,0,0,0,59,115,0,0, + 0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,255,166, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,34,0,172, + 89,0,0,138,125,59,238,34,0,130,34,7,206,201,0,0,59,241,89,0,12,235,255, + 125,0,59,241,89,0,0,59,115,0,0,0,0,59,115,0,0,0,0,89,247,34,0,59,245,166, + 241,89,0,0,0,0,0,0,0,0,0,127,138,225,21,0,0,0,0,0,59,115,0,0,0,0,59,115, + 0,0,0,0,0,89,255,255,255,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199, + 34,0,0,0,0,0,7,199,34,0,0,0,0,0,0,0,0,0,0,175,255,255,166,59,215,21,175, + 255,255,125,0,89,255,255,201,0,0,0,59,245,255,255,125,0,12,235,166,0,0, + 138,225,21,0,0,0,138,255,255,255,255,247,34,0,59,115,0,0,0,0,59,115,0,0, + 0,0,59,245,125,0,0,0,59,115,0,0,0,0,59,115,0,0,0,59,115,0,0,0,0,59,115, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,255,251,102,0,255,255,255,255, + 255,0,245,255,255,255,255,255,255,255,255,255,255,127,21,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,59,241,89,0,0,0,0,0,138,247,34,138,201,0,0,0,175, + 201,0,0,0,175,166,0,0,59,115,0,0,0,0,59,115,0,0,0,12,235,125,0,0,0,138, + 255,166,0,0,0,0,0,0,0,0,0,0,127,245,255,255,255,255,225,21,0,59,115,0,0, + 0,0,59,115,0,0,0,0,0,0,89,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,7,199,34,0,0,0,59,245,255,255,255,255,125,0,0,0,0,0,0,0,0,0,0,0,0,175, + 125,89,225,21,59,238,47,232,89,7,206,125,0,0,0,0,0,138,251,89,12,235,166, + 0,0,138,225,21,0,0,0,138,201,0,0,0,0,0,0,59,115,0,0,0,0,59,115,0,0,0,7, + 206,201,0,0,0,0,59,115,0,0,0,0,59,115,0,0,0,59,115,0,0,0,0,59,115,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,255,251,89,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,255,255,201,0, + 0,0,138,247,34,175,201,0,0,0,138,255,255,255,255,255,166,0,0,59,115,0,0, + 0,0,59,115,0,0,7,206,166,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,127,89,251, + 89,0,0,0,0,0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,138,201,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,34,0,0,0,0,0,7,199,34,0,0,0,0,0,0,0,0,0, + 0,0,0,0,59,215,21,138,201,0,12,228,47,228,34,0,175,166,0,0,0,0,0,12,232, + 89,0,0,175,225,21,59,241,89,0,0,0,138,201,0,0,0,0,0,0,59,115,0,0,0,0,59, + 115,0,0,0,138,225,21,0,0,0,0,59,115,0,0,0,0,59,115,0,0,0,59,115,0,0,0,0, + 59,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,255,166,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59, + 245,125,7,206,201,0,0,138,201,0,0,0,175,201,0,0,0,0,0,0,0,59,115,0,0,0, + 0,59,115,0,0,138,225,21,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,127,7,206, + 247,34,0,0,0,0,59,115,0,0,0,0,59,115,0,59,245,125,0,0,175,166,0,0,0,59, + 245,125,175,225,29,206,166,0,89,247,34,7,206,166,0,0,0,7,199,34,0,0,0,0, + 0,7,199,34,0,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,89,225,21,59,238,47,232,89, + 7,206,125,0,89,166,0,0,89,247,34,0,0,0,130,34,0,138,255,125,0,0,138,201, + 0,0,0,0,0,0,59,115,0,0,0,0,59,115,0,0,89,251,89,0,0,0,0,0,59,115,0,0,0, + 0,59,115,0,0,0,59,115,0,0,0,0,59,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,89,125,0,12,232,89,12,146,0,0,0,59,241,89,0,12,235,247, + 34,0,0,89,125,0,0,59,115,0,0,0,0,59,115,0,59,241,89,0,0,0,0,0,59,241,89, + 0,0,0,0,0,0,0,0,0,0,127,0,0,175,255,255,255,225,21,59,245,255,255,255,255, + 255,125,0,138,225,21,0,12,235,125,0,0,0,138,225,34,235,125,7,206,166,0, + 89,247,34,7,206,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 138,201,0,0,0,175,255,255,125,0,89,255,255,201,0,0,12,235,255,255,251,89, + 0,0,0,0,0,0,0,0,89,255,255,255,255,255,255,255,255,255,125,0,59,245,255, + 255,255,255,255,125,0,0,175,255,255,255,255,255,247,34,59,245,255,255,255, + 255,255,125,0,0,0,59,245,255,255,255,255,255,125,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,255,255,166,0,0,0,0,0,0,0,89,255,255, + 255,125,59,245,255,255,201,0,0,0,59,245,255,255,255,255,255,125,0,175,255, + 255,255,255,127,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,175,166,0,255,255,201,0,0,0,0,175,166,59,238,34,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,228,34,0,0, + 0,0,0,0,0,12,228,34,138,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,0,127,127,127,127,127, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,127,0,127,127,0,127,127,0,127,127,127,127,0, + 127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,255,255,255,255,255, + 251,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21, + 0,0,0,138,125,0,0,0,0,59,245,255,255,125,0,0,0,0,0,0,0,0,138,225,21,0,0, + 175,166,0,12,228,34,0,0,59,245,255,255,247,34,0,89,225,29,206,166,0,0,0, + 0,0,89,255,255,255,255,125,0,0,0,7,206,255,255,247,34,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255,255,255,255,125,0,0,0,0,0,0,0, + 0,0,0,0,0,138,255,255,166,0,0,0,0,7,202,89,0,0,0,0,0,12,235,255,125,0,0, + 175,255,255,225,21,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,138,255,255,255, + 255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,228,34,0,0,89,255,255,225,21,0,0, + 0,0,0,0,0,0,0,0,0,138,166,0,0,0,89,225,21,0,0,0,0,0,138,166,0,0,0,89,225, + 21,0,0,0,12,235,255,255,166,0,0,7,206,125,0,0,0,0,0,0,89,247,34,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21,0,0,0,138,125,0,0,0,12, + 235,125,0,59,115,0,0,0,0,0,0,0,0,7,206,125,0,59,215,21,0,12,228,34,0,12, + 235,125,0,0,168,34,0,0,0,0,0,0,0,0,0,0,175,225,21,0,0,0,175,225,21,0,0, + 0,0,0,138,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,225, + 21,0,0,0,175,225,21,0,0,0,0,0,0,0,0,0,59,238,34,7,206,125,0,0,0,7,202,89, + 0,0,0,0,7,199,34,59,238,34,0,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,89,255,255,255,125,175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,138,255,247,34,0, + 59,241,89,0,175,201,0,0,0,0,0,0,0,0,0,7,206,255,166,0,0,12,232,89,0,0,0, + 0,7,206,255,166,0,0,12,232,89,0,0,0,0,0,0,0,59,215,21,0,89,201,0,0,0,0, + 0,0,0,89,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,7, + 206,255,255,251,89,0,59,241,89,0,0,0,138,201,0,0,0,138,201,0,0,89,225,21, + 175,125,0,0,12,228,34,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166,0, + 89,255,255,247,34,89,201,0,0,89,255,255,255,166,0,0,0,0,168,34,7,151,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166,7,206,255,255,225,21,89,201,0,0,0, + 0,0,0,0,0,0,89,166,0,0,138,166,0,0,0,7,202,89,0,0,0,0,0,0,0,59,238,34,0, + 7,206,255,125,0,0,0,0,0,0,0,0,0,59,238,34,0,0,175,166,0,175,255,255,255, + 125,175,125,0,138,247,34,0,0,0,0,0,0,0,0,0,0,12,228,34,0,89,201,0,0,89, + 225,0,81,115,0,134,89,0,0,0,0,0,138,166,0,0,138,166,0,0,0,0,0,0,0,138,166, + 0,0,138,166,0,0,0,0,0,0,59,245,247,34,0,12,232,89,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,201,0,7,206,201,138,125, + 138,125,0,59,241,89,0,0,0,0,175,255,255,255,225,21,0,0,7,206,166,215,21, + 0,0,12,228,34,0,0,138,255,255,251,89,0,0,0,0,0,0,0,0,0,12,206,21,59,241, + 89,0,134,89,0,172,89,59,238,34,0,138,166,0,0,7,206,201,12,235,125,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,12,206,21,7,202,89,12,235,125,0,172,89,0,0,0,0, + 0,0,0,0,59,238,34,7,206,125,12,235,255,255,255,255,255,255,125,0,0,0,12, + 235,125,0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,59,238,34,0,0,175,166,0,175,255, + 255,255,125,175,125,0,138,247,34,0,0,0,0,0,0,0,0,0,0,12,228,34,0,89,201, + 0,0,89,225,0,29,206,166,59,245,125,0,0,0,0,138,166,0,12,228,34,0,175,225, + 21,0,0,0,138,166,0,12,228,42,206,255,255,166,0,0,0,0,12,228,34,138,166, + 0,89,247,34,0,0,0,0,59,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0, + 0,0,138,201,0,59,241,89,138,125,0,0,59,245,255,255,255,125,0,0,138,166, + 0,89,201,0,0,0,0,89,255,125,0,0,0,0,0,0,0,7,206,125,0,138,251,89,0,0,0, + 0,0,0,0,0,89,166,0,138,201,0,0,0,0,0,89,166,59,215,21,0,175,166,0,59,245, + 125,89,251,89,0,0,12,235,255,255,255,255,255,255,125,138,255,255,251,89, + 127,166,0,7,202,89,12,232,89,0,89,166,0,0,0,0,0,0,0,0,0,138,255,255,166, + 0,0,0,0,7,202,89,0,0,0,0,0,59,241,89,0,0,0,0,0,7,206,125,0,0,0,0,0,0,0, + 0,59,238,34,0,0,175,166,0,89,255,255,255,125,175,125,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,12,228,34,0,59,241,89,0,175,201,0,0,0,175,201,7,206,201,0,0,0, + 138,166,0,175,166,0,138,200,215,21,0,0,0,138,166,0,175,166,7,151,0,89,247, + 34,0,0,0,59,238,47,228,34,59,219,209,34,0,0,0,89,255,125,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21,59,238,34,138,125,0,0,0,59, + 241,89,0,0,0,0,138,166,0,89,201,0,0,59,245,255,255,255,255,125,0,0,0,0, + 0,59,238,34,0,7,206,125,0,0,0,0,0,0,0,0,89,166,0,138,201,0,0,0,0,0,89,166, + 0,175,255,255,223,166,0,12,235,125,59,241,89,0,0,0,0,0,0,0,0,0,175,125, + 0,0,0,0,0,138,125,0,7,206,255,255,125,0,0,59,157,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,7,202,89,0,0,0,0,7,206,255,255,255,166,7,206,255,255,201,0, + 0,0,0,0,0,0,0,0,59,238,34,0,0,175,166,0,0,89,255,255,125,175,125,0,0,0, + 0,0,0,0,0,0,0,0,0,0,89,255,255,251,89,0,89,255,255,225,21,0,0,0,175,225, + 29,206,166,0,0,0,138,166,59,215,21,59,215,81,215,21,0,0,0,138,166,59,215, + 21,0,0,0,89,225,21,59,245,255,255,125,138,166,7,202,97,199,34,0,0,89,251, + 89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225,21,59,241, + 89,138,125,0,0,0,89,247,34,0,0,0,0,175,255,255,255,225,21,0,0,0,12,232, + 89,0,0,0,12,228,34,0,12,235,225,21,59,215,21,0,0,0,0,0,0,0,0,12,206,21, + 59,241,89,0,134,89,0,172,89,0,0,0,0,0,0,0,0,7,206,201,12,235,125,0,0,0, + 0,0,0,0,0,175,125,0,0,0,0,0,12,206,21,7,202,89,7,206,125,0,172,89,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,59,238,34,0,0,175,166,0,0,0,0,175,125,175,125,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,166,59,245,125,0,0,0,0,0,0, + 175,125,12,228,34,59,215,21,0,0,0,0,0,175,125,0,0,0,12,232,89,0,0,0,0,0, + 59,238,34,175,125,7,199,34,0,0,175,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,0,0,0,0,0,138,225,21,7,206,201,138,125,138,125,7,202,89,0,0,0, + 0,138,201,0,0,0,138,166,0,0,0,12,232,89,0,0,0,12,228,34,0,0,0,175,255,255, + 166,0,0,0,0,0,0,0,0,0,0,138,166,0,89,255,255,247,34,89,201,0,0,0,0,0,0, + 0,0,0,0,0,168,34,7,151,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0,0,138,166,7,202, + 89,0,89,247,124,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,255,255,255, + 255,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,125,0,7,206, + 166,0,0,0,0,175,125,175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,59,115,0,134,89,0,0,0,0,0,0,59,215,21,59,245,255,255,255,225,21,0, + 0,0,59,215,21,0,0,59,238,34,0,0,0,0,0,0,175,125,7,206,255,255,255,251,89, + 0,138,247,34,0,59,157,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,225, + 21,0,7,206,255,255,251,89,138,255,255,255,255,255,166,0,0,0,0,0,0,0,0,0, + 0,12,232,89,0,0,0,12,228,34,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,175, + 225,21,0,0,0,175,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,175,225,21,0,0,0,175,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,238,198, + 255,251,194,166,0,0,0,0,175,125,175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,125,0,0,0,0,89,225,21,0,0,0, + 7,206,125,0,0,12,235,255,255,255,166,0,0,0,89,225,21,0,0,0,12,228,34,0, + 0,0,175,255,255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0, + 0,0,0,0,138,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,228, + 34,0,7,176,21,0,89,247,34,0,0,0,0,0,0,0,0,0,0,0,89,255,255,255,255,125, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89, + 255,255,255,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,238,34,0,0,0,0,0,0,0,0,175, + 125,175,125,0,0,0,0,0,0,0,0,59,215,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 0,0,0,0,0,0,0,138,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,228,34,0,7,206,255,255,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,238,34,0,0,0,0,0,0,0,0,175,125,175,125, + 0,0,0,0,0,0,59,245,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,0,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,89, + 255,125,0,0,0,0,0,0,12,235,201,0,0,0,0,12,235,251,89,0,0,0,0,175,255,125, + 89,201,0,0,0,0,0,0,0,0,0,0,0,59,245,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,89,255,125,0,0,0,0,0,0,138,251,89,0,0,0,12,235,251, + 89,0,0,0,0,0,0,0,0,7,206,225,21,0,0,0,89,255,125,0,89,255,225,21,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,247,34,172,89,0,0,0,0,7,206,225,21,0,0, + 0,0,0,0,0,89,255,125,0,0,0,0,0,0,89,255,225,21,0,0,0,0,12,235,247,34,172, + 89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89, + 255,125,0,0,0,0,0,0,0,7,206,225,21,0,0,0,0,89,255,225,21,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,89,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0, + 0,89,247,34,0,0,0,0,0,175,166,0,0,0,0,7,206,125,59,241,89,0,0,89,201,12, + 235,247,34,0,0,7,206,166,59,241,89,0,0,12,228,34,59,215,21,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,238,34,0,0,0,0,89,247,34,0,0,0,7, + 206,125,59,241,89,0,7,206,166,59,238,34,0,0,175,166,0,0,59,241,89,0,89, + 247,34,138,201,59,238,34,138,201,0,0,0,0,0,0,0,0,0,0,0,175,125,89,255,201, + 0,0,0,0,0,0,0,175,201,0,0,0,0,0,0,12,232,89,0,0,0,0,0,0,59,238,34,138,225, + 21,0,0,0,175,125,89,255,201,0,0,0,0,59,238,34,138,201,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,247,34,0,0,0,0,0,0,138,201,0,0,0,0, + 0,59,238,34,138,225,21,0,0,0,59,238,34,138,201,0,0,0,0,12,232,89,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,228,34,59,215,21,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,255,125,0, + 0,0,0,127,0,0,12,235,225,21,0,0,0,0,12,235,225,21,0,0,0,0,12,235,225,21, + 0,0,0,0,12,235,225,21,0,0,0,0,12,235,225,21,0,0,0,0,12,235,225,21,0,0,0, + 0,0,175,255,255,255,255,255,255,255,166,0,0,138,255,255,255,251,89,59,245, + 255,255,255,255,127,81,245,255,255,255,255,225,21,59,245,255,255,255,255, + 127,81,245,255,255,255,255,127,111,255,255,255,125,89,255,255,255,125,89, + 255,255,255,125,89,255,255,255,125,7,206,255,255,255,255,125,0,0,59,245, + 247,34,0,0,59,241,89,0,0,0,138,255,255,255,166,0,0,0,0,138,255,255,255, + 166,0,0,0,0,0,138,255,255,255,166,0,0,0,0,138,255,255,255,166,0,0,0,0,138, + 255,255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,255,255,255,210,235,166, + 59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59, + 241,89,59,241,89,0,0,0,59,241,132,245,125,0,0,0,89,251,89,12,232,89,0,0, + 0,0,7,206,166,0,89,251,89,0,0,0,127,0,0,89,232,241,89,0,0,0,0,89,232,241, + 89,0,0,0,0,89,232,241,89,0,0,0,0,89,232,241,89,0,0,0,0,89,232,241,89,0, + 0,0,0,89,232,241,89,0,0,0,0,12,232,89,89,225,21,0,0,0,0,0,175,247,34,0, + 0,59,192,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,0,0,59,241, + 89,0,0,0,0,0,59,241,89,0,0,59,241,89,0,0,59,241,89,0,0,59,241,89,0,7,206, + 166,0,0,59,245,201,0,59,245,255,201,0,0,59,241,89,0,0,138,251,89,0,12,235, + 166,0,0,138,251,89,0,12,235,166,0,0,0,138,251,89,0,12,235,166,0,0,138,251, + 89,0,12,235,166,0,0,138,251,89,0,12,235,166,0,0,0,138,166,0,0,0,12,228, + 34,0,0,175,247,34,0,0,175,225,21,59,241,89,0,0,0,59,241,89,59,241,89,0, + 0,0,59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,89,247, + 34,0,7,206,125,0,12,232,89,0,0,0,0,59,241,89,0,12,232,89,0,0,0,127,0,7, + 206,166,175,166,0,0,0,7,206,166,175,166,0,0,0,7,206,166,175,166,0,0,0,7, + 206,166,175,166,0,0,0,7,206,166,175,166,0,0,0,0,175,166,175,166,0,0,0,0, + 138,225,21,89,225,21,0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,0,0,59,241, + 89,0,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,59,241, + 89,0,0,59,241,89,0,0,59,241,89,0,7,206,166,0,0,0,59,245,125,59,241,132, + 241,89,0,59,241,89,0,12,235,166,0,0,0,89,247,34,12,235,166,0,0,0,89,247, + 34,0,12,235,166,0,0,0,89,247,34,12,235,166,0,0,0,89,247,34,12,235,166,0, + 0,0,89,247,34,0,0,12,235,125,0,12,235,125,0,0,59,241,89,0,0,138,176,235, + 166,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0, + 59,241,89,59,241,89,0,0,0,59,241,89,0,175,201,0,138,225,21,0,12,235,255, + 255,255,225,21,59,238,34,0,138,225,21,0,0,0,127,0,59,238,34,89,247,34,0, + 0,59,238,34,89,247,34,0,0,59,238,34,89,247,34,0,0,59,238,34,89,247,34,0, + 0,59,238,34,89,247,34,0,0,59,241,89,89,225,21,0,0,7,206,125,0,89,225,21, + 0,0,0,0,138,225,21,0,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,59,241, + 89,0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,59,241,89,0,0,59,241,89,0, + 0,59,241,89,0,7,206,166,0,0,0,7,206,166,59,241,89,138,225,21,59,241,89, + 0,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,0,59,241,89,0,0,0, + 59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,0,0,0,12, + 235,138,235,125,0,0,0,138,225,21,0,59,215,21,175,201,59,241,89,0,0,0,59, + 241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0, + 0,0,59,241,89,0,59,245,166,241,89,0,0,12,232,89,0,0,175,225,59,238,47,235, + 225,21,0,0,0,0,127,0,138,201,0,12,235,125,0,0,138,201,0,12,235,125,0,0, + 138,201,0,12,235,125,0,0,138,201,0,12,235,125,0,0,138,201,0,12,235,125, + 0,0,138,225,21,12,235,125,0,0,89,247,34,0,89,255,255,255,255,251,89,138, + 225,21,0,0,0,0,0,59,245,255,255,255,255,127,59,245,255,255,255,255,166, + 0,59,245,255,255,255,255,127,59,245,255,255,255,255,127,0,59,241,89,0,0, + 59,241,89,0,0,59,241,89,0,0,59,241,89,7,206,255,255,255,166,0,0,175,201, + 59,241,89,12,235,125,59,241,89,0,59,241,89,0,0,0,12,235,125,59,241,89,0, + 0,0,12,235,125,0,59,241,89,0,0,0,12,235,125,59,241,89,0,0,0,12,235,125, + 59,241,89,0,0,0,12,235,125,0,0,0,0,12,235,125,0,0,0,0,138,225,21,7,199, + 34,0,138,225,81,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,59,241, + 89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,0,0,138,255,166,0,0,0,12,232, + 89,0,0,89,247,59,238,34,0,59,245,125,0,0,0,127,7,206,125,0,0,175,201,0, + 7,206,125,0,0,175,201,0,7,206,125,0,0,175,201,0,7,206,125,0,0,175,201,0, + 7,206,125,0,0,175,201,0,7,206,125,0,0,175,201,0,7,206,255,255,255,255,225, + 21,0,0,0,0,138,225,21,0,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,59, + 241,89,0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,59,241,89,0,0,59,241,89, + 0,0,59,241,89,0,7,206,166,0,0,0,7,206,166,59,241,89,0,89,247,94,241,89, + 0,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,0,59,241,89,0,0,0, + 59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,0,0,0,12, + 235,138,235,125,0,0,0,138,225,21,175,125,0,0,175,201,59,241,89,0,0,0,59, + 241,89,59,241,89,0,0,0,59,241,89,59,241,89,0,0,0,59,241,89,59,241,89,0, + 0,0,59,241,89,0,0,59,241,89,0,0,0,12,232,89,0,7,206,201,59,238,34,0,0,138, + 201,0,0,0,127,59,245,255,255,255,255,247,34,59,245,255,255,255,255,247, + 34,59,245,255,255,255,255,247,34,59,245,255,255,255,255,247,34,59,245,255, + 255,255,255,247,34,59,245,255,255,255,255,247,34,59,241,89,0,0,89,225,21, + 0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,59,241, + 89,0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,59,241,89,0,0,59,241,89,0, + 0,59,241,89,0,7,206,166,0,0,0,59,241,89,59,241,89,0,7,206,200,241,89,0, + 12,235,166,0,0,0,89,247,34,12,235,166,0,0,0,89,247,34,0,12,235,166,0,0, + 0,89,247,34,12,235,166,0,0,0,89,247,34,12,235,166,0,0,0,89,247,34,0,0,12, + 235,125,0,12,235,125,0,0,59,241,159,166,0,0,12,235,166,12,232,89,0,0,0, + 59,238,34,12,232,89,0,0,0,59,238,34,12,232,89,0,0,0,59,238,34,12,232,89, + 0,0,0,59,238,34,0,0,59,241,89,0,0,0,12,235,255,255,255,201,0,59,238,34, + 0,0,138,201,0,0,0,127,138,201,0,0,0,12,235,125,138,201,0,0,0,12,235,125, + 138,201,0,0,0,12,235,125,138,201,0,0,0,12,235,125,138,201,0,0,0,12,235, + 125,138,201,0,0,0,12,235,125,175,201,0,0,0,89,225,21,0,0,0,0,0,175,247, + 34,0,0,59,192,59,241,89,0,0,0,0,59,241,89,0,0,0,0,0,59,241,89,0,0,0,0,59, + 241,89,0,0,0,0,0,59,241,89,0,0,59,241,89,0,0,59,241,89,0,0,59,241,89,0, + 7,206,166,0,0,59,245,201,0,59,241,89,0,0,59,245,251,89,0,0,138,251,89,0, + 59,245,166,0,0,138,251,89,0,59,245,166,0,0,0,138,251,89,0,59,245,166,0, + 0,138,251,89,0,59,245,166,0,0,138,251,89,0,59,245,166,0,0,0,138,166,0,0, + 0,12,228,34,0,0,175,247,34,0,7,206,225,21,0,138,225,21,0,7,206,166,0,0, + 138,225,21,0,7,206,166,0,0,138,225,21,0,7,206,166,0,0,138,225,21,0,7,206, + 166,0,0,0,59,241,89,0,0,0,12,232,89,0,0,0,0,59,238,34,0,12,235,125,0,0, + 0,127,206,125,0,0,0,0,175,206,206,125,0,0,0,0,175,206,206,125,0,0,0,0,175, + 206,206,125,0,0,0,0,175,206,206,125,0,0,0,0,175,206,206,125,0,0,0,0,175, + 232,245,125,0,0,0,89,255,255,255,255,255,166,0,0,138,255,255,255,251,89, + 59,245,255,255,255,255,127,81,245,255,255,255,255,225,21,59,245,255,255, + 255,255,127,81,245,255,255,255,255,127,111,255,255,255,125,89,255,255,255, + 125,89,255,255,255,125,89,255,255,255,125,7,206,255,255,255,255,125,0,0, + 59,241,89,0,0,0,175,251,89,0,0,0,138,255,255,255,166,0,0,0,0,138,255,255, + 255,166,0,0,0,0,0,138,255,255,255,166,0,0,0,0,138,255,255,255,166,0,0,0, + 0,138,255,255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,7,202,194,255,255,255,201, + 0,0,0,0,59,245,255,251,89,0,0,0,0,59,245,255,251,89,0,0,0,0,59,245,255, + 251,89,0,0,0,0,59,245,255,251,89,0,0,0,0,59,241,89,0,0,0,12,232,89,0,0, + 0,0,59,238,47,235,255,166,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138, + 166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,166,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127, + 127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,0, + 0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,201,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,7,206, + 225,21,0,0,0,0,0,12,235,201,0,0,0,138,255,201,0,0,0,59,245,225,29,202,89, + 0,0,0,0,0,0,0,0,138,166,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,206,225,21,0,0,0,0,0,12,235,201,0,0,0,89,255,225,21,0,0,0,0,0,0,0,0,175, + 247,34,0,12,235,255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,59,245,225,29,202,89, + 0,0,138,251,89,0,0,0,0,0,7,206,225,21,0,0,0,89,255,225,21,0,0,59,245,225, + 29,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,225, + 21,0,0,0,0,0,89,255,125,0,0,0,89,255,225,21,0,0,0,0,0,0,0,0,0,0,0,0,138, + 251,89,0,59,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,175, + 166,0,0,0,0,7,206,166,0,0,0,89,225,21,175,201,0,7,202,89,138,255,166,0, + 0,89,247,34,175,166,0,0,138,166,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,7,206,166,0,0,0,0,0,175,166,0,0,0,89,247,34,138,201,0,0,89,247, + 34,175,201,0,0,138,201,0,175,200,215,34,235,247,47,232,0,138,255,225,111, + 225,21,0,0,172,89,138,255,166,0,0,0,0,89,225,21,0,0,0,0,175,201,0,0,0,0, + 89,247,34,138,201,0,0,172,89,138,255,166,0,0,59,238,34,138,201,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,166,0,0,0,0,59,241,89,0,0,0,89, + 247,34,138,201,0,0,0,59,238,34,138,201,0,0,0,89,247,34,0,0,59,238,34,0, + 0,0,0,0,138,225,29,206,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,201,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,225,21,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,12,235,166,0,0,0,0,0,0,0,0,89,166,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,238,34,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,7,206,255,255,255,125,0,7,206,255,255,255, + 125,0,7,206,255,255,255,125,0,7,206,255,255,255,125,0,7,206,255,255,255, + 125,0,12,235,255,255,251,89,0,12,235,255,255,251,89,59,245,255,166,0,0, + 59,245,255,255,201,0,12,235,255,251,89,0,0,12,235,255,251,89,0,0,12,235, + 255,251,89,0,0,12,235,255,251,89,0,59,238,34,59,238,34,59,238,34,59,238, + 34,0,59,241,89,175,225,21,0,59,241,194,255,255,125,0,0,12,235,255,247,34, + 0,0,12,235,255,247,34,0,0,0,12,235,255,247,34,0,0,12,235,255,247,34,0,0, + 12,235,255,247,34,0,0,0,0,0,12,235,166,0,0,0,0,7,206,255,255,225,21,0,59, + 241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,59,241, + 89,0,59,241,97,206,166,0,0,12,235,125,59,238,163,255,255,201,7,206,166, + 0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,89,247,34,0,0,0,0,89,247, + 34,0,0,0,0,89,247,34,0,0,0,0,89,247,34,0,0,0,0,89,247,34,0,0,0,0,138,225, + 21,0,0,0,0,89,255,225,21,0,138,201,59,245,125,0,0,0,7,206,125,0,89,225, + 21,7,206,125,0,89,225,21,7,206,125,0,89,225,21,7,206,125,0,89,225,21,59, + 238,34,59,238,34,59,238,34,59,238,34,0,0,0,0,12,235,125,0,59,245,166,0, + 89,247,34,7,206,166,0,138,225,21,7,206,166,0,138,225,21,0,7,206,166,0,138, + 225,21,7,206,166,0,138,225,21,7,206,166,0,138,225,21,0,0,0,0,0,0,0,0,0, + 0,12,232,89,0,138,251,89,0,59,241,89,0,59,241,89,59,241,89,0,59,241,89, + 59,241,89,0,59,241,89,0,59,241,89,0,59,241,89,89,247,34,0,89,247,34,59, + 245,166,0,7,206,166,89,247,34,0,89,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 59,241,89,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0,59,241,89,0,0,0,0, + 59,241,89,0,0,0,0,59,238,34,0,0,0,0,12,232,89,0,0,59,238,127,225,21,0,0, + 0,59,238,34,0,59,238,34,59,238,34,0,59,238,34,59,238,34,0,59,238,34,59, + 238,34,0,59,238,34,59,238,34,59,238,34,59,238,34,59,238,34,0,138,255,255, + 255,255,201,0,59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59, + 241,89,0,59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59,241, + 89,0,12,235,255,255,255,255,255,255,166,138,201,0,59,157,175,201,0,59,241, + 89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,59,241,89, + 0,59,241,89,12,235,125,0,175,166,0,59,238,34,0,0,138,225,34,235,125,0,175, + 166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,127,0,89,255,255,255,251,89,0,89,255,255,255,251, + 89,0,89,255,255,255,251,89,0,89,255,255,255,251,89,0,89,255,255,255,251, + 89,0,138,255,255,255,247,34,0,175,255,255,255,255,255,255,255,255,251,127, + 201,0,0,0,0,59,245,255,255,255,251,89,59,245,255,255,255,251,89,59,245, + 255,255,255,251,89,59,245,255,255,255,251,89,59,238,34,59,238,34,59,238, + 34,59,238,34,138,247,34,0,0,138,201,0,59,241,89,0,59,241,89,59,238,34,0, + 12,232,89,59,238,34,0,12,232,89,0,59,238,34,0,12,232,89,59,238,34,0,12, + 232,89,59,238,34,0,12,232,89,0,0,0,0,0,0,0,0,0,0,175,201,7,176,21,138,201, + 0,59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,59, + 241,89,0,59,241,89,0,175,201,12,232,89,0,59,238,34,0,0,138,225,21,175,201, + 12,232,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,59,241,89,0,59,241,89,59,241,89,0,59, + 241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89, + 138,247,34,0,59,238,34,138,225,21,0,12,232,89,0,0,0,0,138,201,0,0,0,0,59, + 238,34,0,0,0,0,59,238,34,0,0,0,0,59,238,34,0,0,0,0,59,238,34,0,0,0,0,59, + 238,34,59,238,34,59,238,34,59,238,34,175,201,0,0,0,138,166,0,59,241,89, + 0,59,241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,59,241,89,0,59, + 241,89,59,241,89,0,59,241,89,59,241,89,0,59,241,89,0,0,0,0,12,235,166,0, + 0,0,138,201,134,89,0,175,166,0,59,241,89,0,59,241,89,59,241,89,0,59,241, + 89,59,241,89,0,59,241,89,0,59,241,89,0,59,241,89,0,89,247,124,225,21,0, + 59,238,34,0,0,138,201,0,89,247,124,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,89,247, + 34,0,89,251,89,89,247,34,0,89,251,89,89,247,34,0,89,251,89,89,247,34,0, + 89,251,89,89,247,34,0,89,251,89,175,201,0,0,175,247,34,175,201,0,0,59,245, + 225,21,0,7,199,94,245,125,0,0,0,7,206,166,0,7,199,34,7,206,166,0,7,199, + 34,7,206,166,0,7,199,34,7,206,166,0,7,199,34,59,238,34,59,238,34,59,238, + 34,59,238,34,138,247,34,0,12,232,89,0,59,241,89,0,59,241,89,7,206,166,0, + 138,225,21,7,206,166,0,138,225,21,0,7,206,166,0,138,225,21,7,206,166,0, + 138,225,21,7,206,166,0,138,225,21,0,0,0,0,12,235,166,0,0,0,59,245,166,0, + 59,241,89,0,12,235,125,0,175,251,89,12,235,125,0,175,251,89,12,235,125, + 0,175,251,89,0,12,235,125,0,175,251,89,0,7,206,255,125,0,0,59,238,34,0, + 12,235,125,0,7,206,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,175,255,255,232, + 241,89,0,175,255,255,232,241,89,0,175,255,255,232,241,89,0,175,255,255, + 232,241,89,0,175,255,255,232,241,89,12,235,255,255,166,238,34,12,235,255, + 255,225,21,89,255,255,251,89,0,89,255,255,255,201,0,12,235,255,251,89,0, + 0,12,235,255,251,89,0,0,12,235,255,251,89,0,0,12,235,255,251,89,0,59,238, + 34,59,238,34,59,238,34,59,238,34,0,138,255,255,255,125,0,0,59,241,89,0, + 59,241,89,0,12,235,255,247,34,0,0,12,235,255,247,34,0,0,0,12,235,255,247, + 34,0,0,12,235,255,247,34,0,0,12,235,255,247,34,0,0,0,0,0,0,0,0,0,0,0,7, + 206,255,255,225,21,0,0,0,89,255,255,166,241,89,0,89,255,255,166,241,89, + 0,89,255,255,166,241,89,0,0,89,255,255,166,241,89,0,0,138,247,34,0,0,59, + 245,166,255,255,166,0,0,0,138,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,215,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,232,89,0,0,0,59,238,34,0,0,0,0,0, + 12,232,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,12,235,255,125,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,138,225,21,0,0,0,59,238,34,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,0,127,127,0,127,127, + 0,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + + +// Large font anti-aliased +const int FONT2AA_BM_W = 276; +const int FONT2AA_BM_H = 120; +static const unsigned char s_Font2AA[] = +{ + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0, + 0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,59,245,125,175,225,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,138,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,59,241,89,0,0,12,235,201,89,255,166,0,0,0,0,0,172,89,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,225,21,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0, + 0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,138,247,34,0,12, + 232,89,138,225,21,0,0,0,0,138,125,7,199,34,0,0,0,0,138,125,0,0,0,0,138, + 255,255,201,0,0,0,59,215,21,0,0,0,0,59,245,255,255,166,0,0,0,59,241,89, + 0,7,206,201,0,0,89,251,89,0,59,215,21,172,89,59,192,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,166,0,0,138,255,251,89,0,0,0,0,0, + 138,201,0,0,0,7,206,255,255,255,166,0,0,7,206,255,255,255,201,0,0,0,0,0, + 0,138,251,89,0,0,175,255,255,255,255,225,21,0,0,12,235,255,255,125,89,255, + 255,255,255,255,251,89,0,12,235,255,255,225,21,0,0,59,245,255,255,166,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,59,245,255,255,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,89,247, + 34,0,12,232,89,138,201,0,0,0,0,7,202,89,59,215,21,0,0,12,235,255,255,255, + 166,0,59,241,89,12,235,125,0,0,172,89,0,0,0,0,7,206,166,0,89,251,89,0,0, + 12,228,34,0,89,247,34,0,0,0,175,201,0,0,89,251,191,194,247,34,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,232,89,0,175,201,0,12,235, + 125,0,0,138,255,255,201,0,0,0,12,182,0,0,59,245,125,0,12,206,21,0,12,235, + 166,0,0,0,0,89,255,251,89,0,0,175,201,0,0,0,0,0,0,89,255,125,0,0,0,0,0, + 0,0,0,89,251,89,12,235,166,0,7,206,201,0,59,245,125,0,12,235,166,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,89,166,0,0,138,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0, + 0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,89,247,34,0,12, + 228,34,89,201,0,0,0,0,12,206,21,89,166,0,0,12,235,125,138,125,59,192,0, + 89,247,34,7,206,166,0,89,201,0,0,0,0,0,12,235,125,0,12,232,89,0,0,12,228, + 34,0,175,201,0,0,0,0,59,241,89,0,0,7,206,166,0,0,0,0,0,0,0,138,166,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,225,21,59,241,89,0,0,138,225,21,0, + 0,0,175,201,0,0,0,0,0,0,0,7,206,201,0,0,0,0,0,0,175,201,0,0,0,59,241,132, + 241,89,0,0,175,201,0,0,0,0,0,7,206,166,0,0,0,0,0,0,0,0,7,206,201,0,59,241, + 89,0,0,138,225,21,138,225,21,0,0,138,225,21,89,255,125,0,0,89,255,125,0, + 0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,138,201,0,0,0,0,0,0,0,0, + 0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0, + 0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,89,247,34,0,0,0,0,0,0,0, + 0,89,255,255,255,255,255,255,255,125,59,238,34,138,125,0,0,0,89,247,34, + 7,206,166,7,202,89,0,0,0,0,0,0,175,225,21,138,225,21,0,0,0,0,0,12,235,125, + 0,0,0,0,7,206,125,0,89,251,191,194,247,34,0,0,0,0,0,138,166,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,138,166,0,89,247,34,0,0,89,247,34,0,0,0,175,201, + 0,0,0,0,0,0,0,12,235,166,0,0,0,0,0,59,245,125,0,0,12,235,125,59,241,89, + 0,0,175,201,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,89,247,34,0,12,235,201, + 0,0,175,201,0,138,225,21,0,0,89,247,34,89,255,125,0,0,89,255,125,0,0,0, + 0,0,12,235,255,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,175,255,251,89,0,0,0,0, + 0,0,0,0,138,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0, + 0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,89,247,34,0,0,0,0,0, + 0,0,0,0,0,175,125,7,199,34,0,0,12,235,166,138,125,0,0,0,59,241,89,12,235, + 125,89,201,12,235,255,251,89,0,0,7,206,255,166,0,59,241,89,0,0,0,59,238, + 34,0,0,0,0,0,175,166,59,215,21,172,89,59,192,0,0,0,0,0,138,166,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,125,0,138,247,34,0,0,89,247,34,0,0,0, + 175,201,0,0,0,0,0,0,0,89,251,89,0,0,0,89,255,247,34,0,0,7,206,166,0,59, + 241,89,0,0,175,255,255,255,225,21,0,89,251,226,255,255,247,34,0,0,0,7,206, + 166,0,0,0,12,235,255,255,201,0,0,89,255,125,0,0,138,247,34,0,0,0,0,0,0, + 0,0,0,0,0,89,255,255,166,0,0,0,0,0,175,255,255,255,255,255,255,225,21,0, + 0,0,0,59,245,255,201,0,0,0,0,0,175,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0, + 0,0,89,225,21,0,0,0,0,0,0,0,0,0,7,199,34,59,215,21,0,0,0,59,245,255,255, + 201,0,0,0,138,255,255,201,12,228,34,175,166,0,138,201,0,12,235,125,89,255, + 125,59,241,89,0,0,0,59,238,34,0,0,0,0,0,138,201,0,0,0,172,89,0,0,0,7,206, + 255,255,255,255,255,255,247,34,0,0,0,0,89,255,255,255,166,0,0,0,0,0,59, + 238,34,0,138,247,34,0,0,89,247,34,0,0,0,175,201,0,0,0,0,0,0,59,245,166, + 0,0,0,0,0,0,12,235,166,0,138,201,0,0,59,241,89,0,0,0,0,0,12,235,201,0,138, + 251,89,0,0,175,225,21,0,0,89,247,34,0,0,7,206,166,0,175,255,166,0,0,89, + 255,255,255,223,247,34,0,0,0,0,0,0,0,0,0,0,175,247,34,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,225,21,0,0,175,225,21,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0, + 0,0,127,0,0,0,0,0,59,215,21,0,0,0,0,0,0,0,12,235,255,255,255,255,255,255, + 166,0,0,0,0,138,125,175,225,21,0,0,0,0,0,138,166,7,206,125,0,89,247,34, + 138,225,21,0,89,255,166,215,21,0,0,0,59,238,34,0,0,0,0,0,138,201,0,0,0, + 0,0,0,0,0,0,0,0,0,138,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,201,0, + 0,89,247,34,0,0,89,247,34,0,0,0,175,201,0,0,0,0,0,12,235,201,0,0,0,0,0, + 0,0,0,138,225,21,175,255,255,255,255,255,255,125,0,0,0,0,0,138,247,34,89, + 247,34,0,0,59,241,89,0,7,206,166,0,0,0,138,247,34,0,0,138,247,34,0,0,0, + 0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,89,255,255,166,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,59,245,255,201,0,0,0,0,175,201,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0, + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,166,0,175,125,0,0,0,0,0,0,138, + 125,89,247,34,0,0,0,0,12,228,34,7,206,125,0,89,247,34,138,247,34,0,0,89, + 255,166,0,0,0,0,59,238,34,0,0,0,0,0,175,166,0,0,0,0,0,0,0,0,0,0,0,0,138, + 166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,125,0,0,59,241,89,0,0,138,225, + 21,0,0,0,175,201,0,0,0,0,12,235,201,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0, + 0,59,241,89,0,0,0,0,0,0,138,225,21,59,241,89,0,0,59,241,89,0,89,247,34, + 0,0,0,138,247,34,0,0,89,251,89,0,0,0,0,7,206,166,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,12,235,255,225,21,0,0,175,255,255,255,255,255,255,225,21,0,0,175, + 255,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,89,247, + 34,0,0,0,0,0,0,0,0,0,175,125,7,199,34,0,0,0,89,201,0,138,125,175,201,0, + 0,0,0,0,138,166,0,0,175,166,0,138,201,0,89,255,166,0,0,89,255,255,125,0, + 0,0,12,235,125,0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,0,0,0,0,138,166,0,0,0, + 0,0,138,255,125,0,0,0,0,0,0,175,247,34,59,238,34,0,0,0,175,201,0,12,235, + 125,0,0,0,0,175,201,0,0,0,12,235,166,0,0,0,0,0,89,166,0,0,59,245,166,0, + 0,0,0,0,59,241,89,0,59,215,21,0,12,235,166,0,7,206,201,0,0,175,225,21,7, + 206,166,0,0,0,0,59,245,166,0,7,206,225,21,0,0,0,0,175,225,21,0,89,255,125, + 0,0,12,235,201,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,138,201, + 0,0,0,0,0,0,0,0,0,175,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0,0,0,89,247, + 34,0,0,0,0,0,0,0,0,7,199,34,59,215,21,0,0,0,12,235,255,255,255,201,0,0, + 0,0,0,59,215,21,0,0,12,235,255,251,89,0,0,89,255,255,255,201,0,89,255,0, + 0,0,0,175,201,0,0,0,0,59,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175, + 201,0,0,0,0,0,0,0,175,247,34,138,201,0,0,0,0,0,138,255,251,89,0,0,0,138, + 255,255,255,255,166,0,89,255,255,255,255,255,247,34,12,235,255,255,255, + 166,0,0,0,0,0,0,59,241,89,0,12,235,255,255,255,166,0,0,0,7,206,255,255, + 225,21,0,138,247,34,0,0,0,0,0,59,245,255,255,201,0,0,0,175,255,255,201, + 0,0,0,89,255,125,0,0,89,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,175,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,4,4,4,4,4,4,4,4,52,4,4,4,4,4,4,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,125,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,247,34,0,0,0,175,201,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,232,89,0,0,0,0,0,0,0,0,0,0,175,125, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,125,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,201,0,0,89,251,89,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,201,0,0,0,0,0,0,0,0,0,0,12,232,89, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,232,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,0,0,0,0,0,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,201,0,0,201,201,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,127,127,127,0,127,127,127, + 127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,0,127,127,0,127,127,127,127,0,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 127,0,127,127,127,0,127,127,127,127,0,127,127,127,0,127,127,127,127,0,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,255, + 201,0,138,201,0,0,0,0,89,255,255,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,127,0,0,0,0,175,255,255,255,247,34,0,0,0,0,0,7,206,251,89,0,0,12,0, + 235,255,255,255,255,201,0,0,0,0,59,245,255,255,255,201,12,0,235,255,255, + 255,255,166,0,0,0,12,235,255,255,255,255,255,127,12,235,255,255,255,255, + 251,89,0,0,12,235,255,255,255,251,89,12,235,166,0,0,0,12,235,125,89,255, + 255,255,201,0,0,175,255,255,225,21,12,235,166,0,0,7,206,251,102,0,235,166, + 0,0,0,0,12,235,251,89,0,0,0,89,255,225,21,12,235,251,89,0,0,12,235,125, + 0,0,0,138,255,255,166,0,0,0,12,235,255,255,255,251,89,0,0,0,0,175,255,255, + 201,0,0,0,12,235,255,255,255,251,89,0,0,0,12,235,255,255,255,247,47,235, + 255,255,255,255,255,255,255,138,0,235,125,0,0,0,59,245,133,206,166,0,0, + 0,0,59,245,255,133,201,0,0,0,138,251,89,0,0,12,235,133,206,247,34,0,0,0, + 175,229,216,225,21,0,0,0,138,247,124,255,255,255,255,255,255,125,7,206, + 125,0,0,0,59,238,34,0,0,0,0,0,12,235,125,0,0,0,0,175,247,34,0,0,0,0,0,0, + 0,0,0,0,127,0,0,59,245,166,0,0,0,59,245,166,0,0,0,0,59,245,255,166,0,0, + 12,0,235,166,0,0,59,245,125,0,0,138,255,125,0,0,7,202,102,0,235,166,0,0, + 59,245,225,21,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,0,89,255,166, + 0,0,0,89,127,12,235,166,0,0,0,12,235,125,0,12,235,125,0,0,0,0,0,138,225, + 21,12,235,166,0,7,206,225,21,12,0,235,166,0,0,0,0,12,235,255,166,0,0,7, + 206,255,225,21,12,235,255,201,0,0,12,235,125,0,59,245,166,0,0,138,251,89, + 0,12,235,166,0,0,138,251,89,0,89,255,125,0,0,89,255,125,0,12,235,166,0, + 0,138,251,89,0,12,235,166,0,0,7,202,89,0,0,0,138,225,21,0,0,12,0,235,125, + 0,0,0,59,245,125,138,225,21,0,0,0,138,225,151,34,247,34,0,0,175,255,125, + 0,0,89,247,34,12,235,166,0,0,89,247,34,59,245,125,0,0,59,245,125,0,0,0, + 0,0,138,247,34,7,206,125,0,0,0,7,206,125,0,0,0,0,0,12,235,125,0,0,0,138, + 225,187,201,0,0,0,0,0,0,0,0,0,0,127,0,12,232,89,0,0,0,0,0,12,232,89,0,0, + 0,138,225,151,225,21,0,12,0,235,166,0,0,12,235,166,0,12,235,166,0,0,0,0, + 0,12,0,235,166,0,0,0,12,235,166,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0, + 0,0,12,235,166,0,0,0,0,0,0,12,235,166,0,0,0,12,235,125,0,12,235,125,0,0, + 0,0,0,138,225,21,12,235,166,0,175,225,21,0,12,0,235,166,0,0,0,0,12,235, + 166,238,34,0,59,215,187,225,21,12,235,166,245,125,0,12,235,125,12,235,125, + 0,0,0,0,138,247,34,12,235,166,0,0,12,235,166,12,235,125,0,0,0,0,138,247, + 34,12,235,166,0,0,12,235,166,0,89,247,34,0,0,0,0,0,0,0,0,138,225,21,0,0, + 12,0,235,125,0,0,0,59,245,125,59,241,89,0,0,7,206,166,59,0,241,89,0,12, + 232,194,201,0,0,138,225,21,0,89,251,89,12,235,166,0,0,138,247,34,7,206, + 201,0,0,0,0,0,59,245,125,0,7,206,125,0,0,0,0,138,201,0,0,0,0,0,12,235,125, + 0,0,59,241,89,12,235,166,0,0,0,0,0,0,0,0,0,127,0,175,166,0,59,245,255,255, + 247,34,138,201,0,0,7,206,166,59,241,89,0,12,0,235,166,0,0,89,251,89,0,89, + 247,34,0,0,0,0,0,12,0,235,166,0,0,0,0,138,225,21,12,235,166,0,0,0,0,0,12, + 235,166,0,0,0,0,0,89,247,34,0,0,0,0,0,0,12,235,166,0,0,0,12,235,125,0,12, + 235,125,0,0,0,0,0,138,225,21,12,235,166,175,247,34,0,0,12,0,235,166,0,0, + 0,0,12,235,133,206,166,0,175,166,175,225,21,12,235,125,138,225,21,12,235, + 125,89,247,34,0,0,0,0,59,245,125,12,235,166,0,0,12,235,166,89,247,34,0, + 0,0,0,59,245,125,12,235,166,0,0,12,235,125,0,89,255,125,0,0,0,0,0,0,0,0, + 138,225,21,0,0,12,0,235,125,0,0,0,59,245,125,7,206,201,0,0,59,241,89,7, + 0,206,166,0,59,215,111,225,21,7,206,166,0,0,0,175,225,187,225,21,0,0,12, + 235,166,89,247,34,0,0,0,0,7,206,201,0,0,7,206,125,0,0,0,0,89,225,21,0,0, + 0,0,12,235,125,0,12,235,166,0,0,59,241,89,0,0,0,0,0,0,0,0,127,0,202,89, + 12,235,125,0,12,228,34,59,215,0,0,59,241,89,7,206,166,0,12,0,235,255,255, + 255,255,166,0,0,138,225,21,0,0,0,0,0,12,0,235,166,0,0,0,0,89,247,34,12, + 235,255,255,255,255,247,34,12,235,255,255,255,255,247,0,163,225,21,0,0, + 0,0,0,0,12,235,255,255,255,255,255,255,125,0,12,235,125,0,0,0,0,0,138,225, + 21,12,235,255,247,34,0,0,0,12,0,235,166,0,0,0,0,12,235,125,89,225,34,228, + 34,175,225,21,12,235,125,12,235,125,12,235,125,138,225,21,0,0,0,0,12,235, + 166,12,235,166,0,0,175,247,34,138,225,21,0,0,0,0,12,235,166,12,235,166, + 0,0,175,225,21,0,0,175,255,255,225,21,0,0,0,0,0,138,225,21,0,0,12,0,235, + 125,0,0,0,59,245,125,0,138,247,34,0,138,225,21,0,0,175,201,0,138,201,12, + 232,89,12,235,125,0,0,0,12,235,251,89,0,0,0,0,89,255,255,125,0,0,0,0,0, + 138,247,34,0,0,7,206,125,0,0,0,0,12,232,89,0,0,0,0,12,235,125,7,206,201, + 0,0,0,0,138,251,89,0,0,0,0,0,0,0,127,7,228,34,89,225,21,0,12,228,34,12, + 228,0,0,138,225,21,0,138,225,21,12,0,235,166,0,0,12,235,201,0,138,225,21, + 0,0,0,0,0,12,0,235,166,0,0,0,0,89,247,34,12,235,166,0,0,0,0,0,12,235,166, + 0,0,0,0,0,138,225,21,0,12,235,255,255,127,12,235,166,0,0,0,12,235,125,0, + 12,235,125,0,0,0,0,0,138,225,21,12,235,229,216,225,21,0,0,12,0,235,166, + 0,0,0,0,12,235,125,12,235,223,201,0,175,225,21,12,235,125,0,138,225,34, + 235,125,138,225,21,0,0,0,0,12,235,166,12,235,255,255,255,247,34,0,138,225, + 21,0,0,0,0,12,235,166,12,235,255,255,255,166,0,0,0,0,0,0,89,255,255,247, + 34,0,0,0,138,225,21,0,0,12,0,235,125,0,0,0,59,245,125,0,59,245,125,7,206, + 166,0,0,0,89,247,34,175,125,7,206,125,89,247,34,0,0,0,12,235,251,89,0,0, + 0,0,7,206,225,21,0,0,0,0,59,245,125,0,0,0,7,206,125,0,0,0,0,0,175,166,0, + 0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,12,228,34,89,225, + 21,0,12,228,34,59,215,0,7,206,255,255,255,255,251,89,12,0,235,166,0,0,0, + 138,247,0,124,247,34,0,0,0,0,0,12,0,235,166,0,0,0,0,138,225,21,12,235,166, + 0,0,0,0,0,12,235,166,0,0,0,0,0,89,247,34,0,0,0,0,175,127,12,235,166,0,0, + 0,12,235,125,0,12,235,125,0,0,0,0,0,138,225,21,12,235,166,59,245,201,0, + 0,12,0,235,166,0,0,0,0,12,235,125,0,138,251,89,0,175,225,21,12,235,125, + 0,12,235,138,235,125,89,247,34,0,0,0,0,59,245,125,12,235,166,0,0,0,0,0, + 89,247,34,0,0,0,0,59,245,125,12,235,166,0,175,247,34,0,0,0,0,0,0,0,59,245, + 166,0,0,0,138,225,21,0,0,12,0,235,125,0,0,0,59,241,89,0,7,206,201,59,241, + 89,0,0,0,59,241,102,232,89,0,138,201,138,225,21,0,0,0,175,201,175,225,21, + 0,0,0,0,175,225,21,0,0,0,7,206,201,0,0,0,0,7,206,125,0,0,0,0,0,89,225,21, + 0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,12,232,89,59,241, + 89,0,89,247,34,89,201,0,59,241,89,0,0,7,206,166,12,0,235,166,0,0,0,138, + 225,0,81,245,166,0,0,0,0,0,12,0,235,166,0,0,0,12,235,166,0,12,235,166,0, + 0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,175,127,12,235,166,0,0, + 0,12,235,125,0,12,235,125,0,0,0,0,0,138,225,21,12,235,166,0,89,255,166, + 0,12,0,235,166,0,0,0,0,12,235,125,0,12,182,0,0,175,225,21,12,235,125,0, + 0,138,232,245,125,12,235,125,0,0,0,0,138,247,34,12,235,166,0,0,0,0,0,12, + 235,125,0,0,0,0,138,247,34,12,235,166,0,7,206,225,21,0,0,0,0,0,0,12,235, + 166,0,0,0,138,225,21,0,0,12,0,235,166,0,0,0,89,251,89,0,0,138,247,163,225, + 21,0,0,0,7,206,200,215,21,0,89,225,187,166,0,0,0,89,251,89,12,235,166,0, + 0,0,0,175,225,21,0,0,0,138,247,34,0,0,0,0,7,206,125,0,0,0,0,0,12,232,89, + 0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,12,175,166,0,89, + 255,255,210,235,255,255,125,0,138,225,21,0,0,0,138,247,47,0,235,166,0,0, + 59,245,166,0,0,138,255,125,0,0,7,202,102,0,235,166,0,0,12,235,225,21,0, + 12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,0,138,255,125,0,0,0,175,127,12, + 235,166,0,0,0,12,235,125,0,12,235,125,0,0,0,0,7,206,201,0,12,235,166,0, + 0,138,255,125,12,0,235,166,0,0,0,12,0,235,125,0,0,0,0,0,175,225,21,12,235, + 125,0,0,12,235,255,125,0,89,255,125,0,0,89,251,89,0,12,235,166,0,0,0,0, + 0,0,89,255,125,0,0,89,255,125,0,12,235,166,0,0,12,235,201,0,138,166,0,0, + 0,138,251,89,0,0,0,138,225,21,0,0,0,0,138,247,34,0,7,206,225,21,0,0,12, + 235,255,166,0,0,0,0,0,175,255,201,0,0,12,235,255,125,0,0,12,235,166,0,0, + 138,251,89,0,0,0,175,225,21,0,0,89,251,89,0,0,0,0,0,7,206,125,0,0,0,0,0, + 0,175,166,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,59,241, + 89,0,0,0,0,0,0,0,0,7,206,166,0,0,0,0,59,245,138,0,235,255,255,255,255,125, + 0,0,0,0,59,245,255,255,255,201,12,0,235,255,255,255,255,166,0,0,0,12,235, + 255,255,255,255,255,127,12,235,166,0,0,0,0,0,0,0,59,245,255,255,255,225, + 21,12,235,166,0,0,0,12,235,125,89,255,255,255,210,127,235,255,255,225,21, + 0,12,235,166,0,0,0,175,255,127,0,235,255,255,255,247,47,0,235,125,0,0,0, + 0,0,175,225,21,12,235,125,0,0,0,138,255,125,0,0,0,175,255,255,201,0,0,0, + 12,235,166,0,0,0,0,0,0,0,0,175,255,255,201,0,0,0,12,235,166,0,0,0,89,255, + 225,34,235,255,255,255,247,34,0,0,0,0,138,225,21,0,0,0,0,0,138,255,255, + 255,201,0,0,0,0,0,175,251,89,0,0,0,0,0,89,255,166,0,0,7,206,247,34,0,7, + 206,225,21,0,0,7,206,225,21,0,0,175,225,21,0,0,138,255,255,255,255,255, + 255,166,7,206,125,0,0,0,0,0,0,138,201,0,0,0,12,235,125,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,127,0,0,89,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,201,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,7,206,125,0,0,0,0,0,0,59,238,34,0,0,12,235,125,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,0,0,0,7,206,255,255,255,225,21,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,251,89,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,7,206,125,0,0,0,0,0,0,7,206,125,0,0,12,235,125,0,0,0, + 0,0,0,0,0,0,0,245,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138, + 255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,255,201,0,0,0,0,0,0,89,89,255,255, + 255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,59,245,166,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,89,247,34,0,0,0,0,0,0,0,0,0,0,12,235, + 125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,12,235, + 255,247,0,0,0,0,0,0,0,12,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125, + 0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,255,251,89,0,7,206,125,0,89,255,251,89, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,84,84,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,7,206, + 125,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138, + 225,21,0,0,0,0,0,0,0,0,0,175,201,0,0,0,0,0,0,0,0,0,12,12,235,125,0,0,0, + 0,0,59,245,102,0,89,247,34,12,235,125,0,0,0,0,0,12,235,125,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 59,241,89,0,0,0,7,206,125,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,4,4,4,4,4,4,4,100,252,252,84,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, + 235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,12,0, + 235,125,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125, + 0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235, + 125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,247,34,0,0,0,7,206,125,0,0,0,59,238, + 34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,20,236,252,164,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,0,0,0,0,0,0,12,235,255,255,255,166,0,12,235,166,245,255,247,34,0,0,12, + 235,255,255,247,34,0,34,235,255,255,255,225,21,0,12,235,255,255,225,29, + 0,206,255,255,255,127,0,12,235,255,255,255,225,21,12,235,138,235,255,247, + 34,0,12,235,102,175,255,247,34,12,235,125,0,59,245,201,0,12,235,125,12, + 0,235,166,245,255,225,29,206,255,251,89,0,12,235,138,235,255,247,34,0,0, + 12,235,255,255,201,0,0,12,235,166,245,255,251,89,0,0,12,235,255,255,255, + 225,21,12,235,138,235,247,127,34,138,255,255,255,206,0,206,255,255,255, + 201,59,241,89,0,0,89,247,42,206,201,0,0,0,138,225,187,201,0,0,138,225,21, + 0,59,241,187,226,247,34,0,7,206,206,206,201,0,0,0,138,225,151,255,255,255, + 255,247,0,0,89,247,34,0,0,0,7,206,125,0,0,0,59,238,34,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,4,4,4,4,4,4,148,252,236,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,12,206, + 21,0,59,245,125,12,235,247,34,0,138,225,21,12,235,166,0,0,134,102,0,235, + 166,0,0,138,225,21,12,235,125,0,0,175,201,12,0,235,125,0,0,12,235,166,0, + 0,138,225,21,12,235,247,34,0,175,201,0,12,235,102,0,89,247,34,12,235,125, + 12,235,166,0,0,12,235,125,12,0,235,225,21,12,235,251,89,0,175,201,0,12, + 235,247,34,0,175,201,0,12,235,166,0,7,206,201,0,12,235,225,21,0,175,225, + 21,12,235,166,0,0,138,225,21,12,235,247,34,0,0,89,247,34,0,12,206,34,0, + 235,125,0,0,59,241,89,0,0,89,247,34,89,247,34,0,7,206,166,138,225,21,7, + 206,251,89,0,89,225,138,34,235,201,0,138,225,21,89,247,34,0,7,206,166,0, + 0,0,7,206,166,0,0,89,225,21,0,0,0,7,206,125,0,0,0,59,241,89,0,0,0,0,138, + 251,89,0,0,7,202,89,0,0,4,4,4,4,4,4,52,252,252,108,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0, + 0,0,0,0,0,0,0,0,7,206,102,12,235,125,0,0,59,241,89,138,225,21,0,0,0,34, + 89,225,21,0,0,138,225,21,89,225,21,0,0,89,247,47,0,235,125,0,0,89,225,21, + 0,0,138,225,21,12,235,125,0,0,89,247,34,12,235,102,0,89,247,34,12,235,138, + 235,166,0,0,0,12,235,125,12,0,235,125,0,7,206,166,0,0,138,225,21,12,235, + 125,0,0,89,247,34,138,225,21,0,0,59,238,34,12,235,125,0,0,59,241,89,89, + 225,21,0,0,138,225,21,12,235,125,0,0,0,138,225,21,0,0,0,12,0,235,125,0, + 0,59,241,89,0,0,89,247,34,12,235,125,0,59,241,89,59,238,34,12,228,198,166, + 0,175,166,59,0,89,251,132,241,89,0,12,235,125,0,59,238,34,0,0,0,138,225, + 21,0,12,235,166,0,0,0,0,7,206,125,0,0,0,0,175,201,0,0,0,138,166,12,235, + 166,0,12,232,89,0,0,12,84,4,4,4,4,204,252,204,4,4,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0, + 0,0,0,59,245,255,255,255,102,12,235,125,0,0,12,235,125,175,201,0,0,0,0, + 0,175,201,0,0,0,138,225,21,175,255,255,255,255,255,247,47,0,235,125,0,0, + 175,201,0,0,0,138,225,21,12,235,125,0,0,89,247,34,12,235,102,0,89,247,34, + 12,235,255,225,21,0,0,0,12,235,125,12,0,235,125,0,7,206,166,0,0,138,225, + 21,12,235,125,0,0,89,247,34,175,201,0,0,0,12,232,89,12,235,125,0,0,12,235, + 125,175,201,0,0,0,138,225,21,12,235,125,0,0,0,59,245,255,247,34,0,12,0, + 235,125,0,0,59,241,89,0,0,89,247,34,0,175,201,0,138,201,0,12,235,125,89, + 201,89,225,29,206,125,12,0,0,175,255,166,0,0,0,175,201,0,138,201,0,0,0, + 89,251,89,0,138,247,34,0,0,0,0,0,7,206,125,0,0,0,0,0,89,255,125,7,202,89, + 0,89,251,89,89,201,0,0,0,172,252,84,4,4,100,252,252,60,4,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,0,0,0,0,0,0,89,255,166,0,7,206,102,12,235,125,0,0,12,235,125,175,201, + 0,0,0,0,0,175,201,0,0,0,138,225,21,175,201,0,0,0,0,0,12,0,235,125,0,0,175, + 201,0,0,0,138,225,21,12,235,125,0,0,89,247,34,12,235,102,0,89,247,34,12, + 235,138,235,201,0,0,0,12,235,125,12,0,235,125,0,7,206,166,0,0,138,225,21, + 12,235,125,0,0,89,247,34,175,201,0,0,0,12,232,89,12,235,125,0,0,12,235, + 125,175,201,0,0,0,138,225,21,12,235,125,0,0,0,0,0,138,255,255,201,12,0, + 235,125,0,0,59,241,89,0,0,89,247,34,0,89,247,42,206,125,0,0,175,166,175, + 125,12,232,102,232,89,0,0,0,175,255,201,0,0,0,89,247,47,235,125,0,0,12, + 235,166,0,0,0,12,235,125,0,0,0,0,7,206,125,0,0,0,0,138,201,0,0,12,232,89, + 0,0,59,245,225,21,0,0,0,196,252,244,60,20,236,252,156,4,4,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,0,0,0,0,0,0,175,201,0,0,7,206,102,12,235,125,0,0,59,241,89,138,225,21, + 0,0,0,34,89,225,21,0,0,138,225,21,138,247,34,0,0,0,0,12,0,235,125,0,0,138, + 225,21,0,0,138,225,21,12,235,125,0,0,89,247,34,12,235,102,0,89,247,34,12, + 235,125,59,245,125,0,0,12,235,125,12,0,235,125,0,7,206,166,0,0,138,225, + 21,12,235,125,0,0,89,247,34,138,225,21,0,0,89,247,34,12,235,125,0,0,59, + 241,89,138,225,21,0,0,138,225,21,12,235,125,0,0,0,0,0,0,0,89,247,47,0,235, + 125,0,0,59,241,89,0,0,89,247,34,0,12,235,166,238,34,0,0,138,210,228,34, + 0,175,166,215,21,0,0,89,251,159,251,89,0,0,12,235,191,247,34,0,0,175,225, + 21,0,0,0,0,138,225,21,0,0,0,7,206,125,0,0,0,12,232,89,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,20,220,252,236,180,252,244,28,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0, + 138,225,21,0,138,255,102,12,235,125,0,7,206,201,0,12,235,166,0,0,134,132, + 0,245,125,0,59,245,225,21,12,235,201,0,0,12,206,34,0,235,125,0,0,59,245, + 125,0,12,235,225,21,12,235,125,0,0,89,247,34,12,235,102,0,89,247,34,12, + 235,125,0,138,251,89,0,12,235,125,12,0,235,125,0,7,206,166,0,0,138,225, + 21,12,235,125,0,0,89,247,34,12,235,166,0,7,206,201,0,12,235,125,0,7,206, + 201,0,59,245,125,0,12,235,225,21,12,235,125,0,0,0,138,125,0,0,138,225,29, + 0,206,166,0,0,7,206,166,0,59,245,247,34,0,0,175,255,201,0,0,0,59,245,225, + 21,0,89,255,201,0,0,12,235,166,0,175,225,21,0,0,138,255,166,0,0,89,251, + 89,0,0,0,0,0,89,247,34,0,0,0,7,206,125,0,0,0,59,238,34,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,4,36,236,252,252,252,108,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0, + 7,206,255,255,171,206,102,12,232,226,255,255,225,21,0,0,12,235,255,255, + 247,34,0,89,255,255,247,163,225,21,0,7,206,255,255,247,34,12,0,235,125, + 0,0,0,89,255,255,247,163,225,21,12,235,125,0,0,89,247,34,12,235,102,0,89, + 247,34,12,235,125,0,0,175,251,34,0,235,125,12,0,235,125,0,7,206,166,0,0, + 138,225,21,12,235,125,0,0,89,247,34,0,12,235,255,255,201,0,0,12,235,255, + 255,255,225,21,0,0,89,255,255,247,163,225,21,12,235,125,0,0,0,89,255,255, + 255,247,34,0,0,89,255,255,127,0,59,245,255,225,111,247,34,0,0,59,245,125, + 0,0,0,12,235,166,0,0,59,245,125,7,0,206,225,21,0,12,235,201,0,0,59,241, + 89,0,0,175,255,255,255,255,247,0,0,89,247,34,0,0,0,7,206,125,0,0,0,59,238, + 34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,60,252,252,204,4,4,4,4,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,201,0,0,0,0,0,0,0,0,0,0,0,0,0, + 89,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,89,247,34,0,0,0,7, + 206,125,0,0,0,59,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,76,252,60,4,4, + 4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,34,0,12,232,89,0,0, + 0,0,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0, + 0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,166,0,0,0,0,0,0,0,0, + 0,0,0,12,235,125,0,0,0,7,206,125,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,235,255,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,89,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235, + 125,0,0,0,0,0,0,0,0,0,0,138,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89, + 247,34,0,0,0,0,0,0,0,0,0,0,0,0,89,255,251,89,0,7,206,125,0,89,255,247,34, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,0,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127, + 127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,125,0,175,166,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,206,125,0,175,166, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,225,21,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,125,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,125,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,166,0,138,201,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,166,0,138,201,0,7,206,166,12,235, + 125,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0,175,125, + 0,0,0,0,0,175,171,206,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255,125,0, + 31,206,130,255,166,175,247,34,0,0,89,255,125,175,247,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,247,34,138,166,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,59,241,132,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,59,241,132,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0, + 59,245,255,255,255,125,0,12,235,255,255,255,255,255,225,21,0,0,0,0,0,0, + 0,0,175,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,0,0, + 0,0,175,125,0,0,0,0,89,225,21,59,238,34,0,0,138,255,255,201,0,0,0,59,215, + 21,0,0,0,0,0,0,0,0,0,12,235,255,255,255,247,34,0,0,0,0,0,0,0,12,235,255, + 255,255,255,255,255,255,255,251,89,0,12,235,255,255,255,255,255,225,21, + 0,89,255,255,255,255,255,255,125,0,12,235,255,255,255,255,255,225,21,0, + 0,12,235,255,255,255,255,255,225,21,7,206,201,0,50,206,56,255,201,12,235, + 125,0,0,138,225,29,206,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,7,202,89,89,255,225,21,0,89,255,255,255,225,81,245,201,0,138,251, + 89,0,0,138,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,255, + 255,255,255,225,21,0,0,0,138,255,166,7,206,225,21,0,0,0,138,247,34,0,0, + 0,0,127,0,89,255,125,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,0,89, + 247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0,175, + 125,0,0,0,0,0,0,0,0,0,0,0,59,241,89,12,235,125,0,0,172,89,0,0,0,0,0,0,0, + 0,0,12,235,166,0,0,7,202,89,0,0,0,0,0,0,89,255,201,0,0,12,235,125,0,0,0, + 0,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,138,247,34,0,12,146,0,0,0,0,0, + 144,21,0,0,12,146,0,0,0,0,0,144,21,0,89,225,21,71,157,22,191,225,21,175, + 201,0,7,206,125,59,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,59,196,199,47,206,184,89,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0, + 0,0,0,59,245,125,0,0,59,245,125,0,0,0,0,0,127,12,235,166,0,0,0,0,0,0,12, + 146,0,0,0,0,0,144,21,0,0,0,0,0,0,0,175,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,12,235,255,255,255,255,127,34,235,255,255,255,255,225,21,0, + 0,0,0,0,0,0,0,89,247,34,7,206,166,0,89,201,0,0,0,0,0,0,0,0,0,0,89,247,34, + 0,0,0,0,0,0,0,0,59,115,12,235,166,0,0,0,12,235,125,0,0,0,0,0,0,12,146,0, + 0,0,0,0,144,21,0,0,0,0,0,59,245,125,0,0,12,146,0,0,0,0,0,144,21,0,0,12, + 146,0,0,0,0,0,144,21,0,7,202,89,117,104,0,29,202,89,59,215,21,59,215,21, + 138,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,175,125,0,59,192,89,223,125,172,89,0,138,255,255,255,201,12,182, + 0,0,0,0,0,175,255,255,125,0,89,255,255,247,34,0,0,12,146,0,0,0,0,0,144, + 21,0,138,255,255,255,255,247,34,138,247,34,7,206,201,0,0,0,0,0,0,127,89, + 251,89,0,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,7,206,166,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0,175,125,0,0,0, + 0,0,0,0,0,0,0,0,89,247,34,7,206,166,7,202,89,0,0,0,0,0,0,0,0,0,0,89,255, + 125,0,0,0,0,0,0,0,89,255,125,89,247,34,0,0,0,12,235,125,0,0,0,0,0,0,12, + 146,0,0,0,0,0,144,21,0,0,0,0,7,206,201,0,0,0,12,146,0,0,0,0,0,144,21,0, + 0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245, + 255,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175, + 125,0,59,192,12,228,34,172,89,89,247,34,0,12,206,29,206,201,0,0,7,206,166, + 0,7,206,255,225,21,0,89,247,34,0,12,146,0,0,0,0,0,144,21,0,0,0,0,7,206, + 166,0,12,235,166,89,247,34,0,0,0,0,0,0,127,245,255,255,255,255,255,201, + 0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,59,245,255,255,255,127,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0,175,125,0,0,0,0,0,0,0, + 0,0,0,0,59,241,89,12,235,125,89,201,12,235,255,251,89,0,89,255,255,225, + 21,0,175,255,255,225,21,0,0,0,89,251,89,0,138,225,21,0,0,0,12,235,255,255, + 255,255,225,21,0,12,146,0,0,0,0,0,144,21,0,0,0,0,138,247,34,0,0,0,12,146, + 0,0,0,0,0,144,21,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,12,235,255,255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,59,192,0,0,0,172,89,138,225,21,0,0,0, + 0,7,206,225,21,138,225,21,0,0,89,251,89,0,0,12,235,125,0,12,146,0,0,0,0, + 0,144,21,0,0,0,0,138,225,21,0,0,89,255,255,125,0,0,0,0,0,0,0,127,138,225, + 21,0,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,59,241,89,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,0,12,235,255,255,255,255, + 225,21,0,0,0,0,0,0,0,0,0,138,255,255,201,12,228,34,175,166,0,138,201,7, + 206,125,7,206,166,0,0,0,89,255,255,247,34,59,241,89,0,0,138,225,21,0,0, + 0,12,235,125,0,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,0,59,245,125,0,0,0, + 0,12,146,0,0,0,0,0,144,21,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,59,245,255,255,255,207,235,255,255,255,255,255,255, + 207,235,255,255,255,255,255,255,255,255,255,255,255,225,21,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,59,245,255,247,34,0,0,0,0,175,166,175,201,0,0,0, + 59,245,255,255,255,255,255,125,0,12,146,0,0,0,0,0,144,21,0,0,0,89,251,89, + 0,0,0,7,206,225,21,0,0,0,0,0,0,0,127,245,255,255,255,255,255,125,0,0,12, + 146,0,0,0,0,0,144,21,0,0,0,0,0,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0,175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,138,166,7,206,125,0,89,247,94,241,89,0,138,201,0,0,0,0,0,59,245,166, + 0,89,251,89,0,89,247,34,0,0,0,12,235,125,0,0,0,0,0,0,12,146,0,0,0,0,0,144, + 21,0,0,7,206,201,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,12,146,0,0,0,0,0, + 144,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,255,255,166,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,138,255,255,201,0,7,206,225,21,175,201,0,0,0,59,241,89,0,0,0,0, + 0,0,12,146,0,0,0,0,0,144,21,0,0,12,235,166,0,0,0,0,0,175,225,21,0,0,0,0, + 0,0,0,127,89,255,125,0,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,89, + 247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,125,0,0,0,0,0, + 175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,228,34,7,206,125,0,89,247,94,241, + 89,0,138,201,0,0,0,0,0,12,235,166,0,0,89,255,125,12,235,166,0,0,0,12,235, + 125,0,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,138,247,34,0,0,0,0,0,12,146, + 0,0,0,0,0,144,21,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,59,245,255,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,247,42,206,201,0,0,89, + 225,21,0,0,89,255,125,0,0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,0,175,225,21, + 0,0,0,0,0,175,225,21,0,0,0,0,0,0,0,127,0,175,251,89,0,0,0,0,0,12,146,0, + 0,0,0,0,144,21,0,59,245,166,0,0,138,225,21,0,0,0,59,245,166,138,251,89, + 7,206,201,0,12,235,125,0,59,241,89,0,0,0,175,125,0,0,0,0,0,175,125,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,138,166,0,0,175,166,0,138,201,7,206,125,7,206, + 166,138,166,0,0,0,138,251,89,0,0,0,59,115,0,89,255,201,0,0,12,235,125,0, + 0,0,0,0,0,12,146,0,0,0,0,0,144,21,0,89,251,89,0,0,0,0,0,0,12,146,0,0,0, + 0,0,144,21,0,0,12,146,0,0,0,0,0,144,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,138,125,0,0,138,225,34,182,0,0,0,7,206,166,0, + 7,206,255,247,34,0,0,175,125,0,12,146,0,0,0,0,0,144,21,0,89,251,89,0,0, + 0,0,0,0,175,225,21,0,0,0,0,0,0,0,127,0,0,138,255,255,255,255,125,0,12,235, + 255,255,255,255,255,225,21,0,138,247,34,0,7,206,166,0,0,0,0,89,247,34,175, + 201,0,7,206,201,0,12,235,125,0,59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,59,215,21,0,0,12,235,255,251,89,0,89,255,255,225, + 21,12,235,255,255,255,247,34,0,0,0,0,0,0,0,0,12,235,255,255,255,255,255, + 255,255,255,251,89,0,12,235,255,255,255,255,255,225,21,0,138,255,255,255, + 255,255,255,166,0,12,235,255,255,255,255,255,225,21,0,0,12,235,255,255, + 255,255,255,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,89,255,255,255,247,34,0,0,0,0,0,0,0,175,255,255,125,0,138,255,255, + 255,125,0,0,12,235,255,255,255,255,255,225,21,0,175,255,255,255,255,247, + 0,0,0,175,225,21,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,175,166,0,255,255,201,0,0,0,0,0,175,166,12,232,89,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, + 228,34,0,0,0,0,0,0,0,0,12,232,89,59,215,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127,0,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,0,127,127,127,0,127,127,0,127,127,127,127,127,0,127,127,127,127, + 127,0,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127, + 0,127,127,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,245,255,255,255,255,255,255,225,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,225,21,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,247, + 34,0,0,0,0,59,192,0,0,0,0,0,7,206,255,255,225,21,0,0,0,0,0,0,0,0,138,247, + 34,0,0,89,251,89,0,7,206,125,0,0,7,206,255,255,255,166,0,89,251,89,138, + 247,34,0,0,0,0,7,206,255,255,255,247,34,0,0,0,0,175,255,255,251,89,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,255,255,247, + 34,0,0,0,0,0,0,0,0,0,0,0,0,89,255,255,247,34,0,0,0,0,0,0,0,0,0,0,0,0,12, + 235,255,247,34,0,0,7,206,255,251,89,0,0,7,206,125,0,0,0,0,0,0,0,0,0,0,0, + 0,89,255,255,255,255,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,0, + 59,245,255,247,34,0,0,0,0,0,0,0,0,0,0,0,89,201,0,0,0,0,175,166,0,0,0,0, + 0,0,89,201,0,0,0,0,175,166,0,0,0,0,0,59,245,255,201,0,0,0,59,241,89,0,0, + 0,0,0,59,245,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,247,34, + 0,0,0,0,59,192,0,0,0,0,0,175,201,0,0,144,21,0,0,0,0,0,0,0,0,7,206,166,0, + 7,206,166,0,0,7,206,125,0,7,206,201,0,0,89,166,0,0,0,0,0,0,0,0,0,0,89,255, + 125,0,0,0,59,245,166,0,0,0,0,0,0,12,206,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,89,255,125,0,0,0,59,245,166,0,0,0,0,0,0,0,0,0,0,59, + 241,89,0,138,201,0,0,0,0,0,138,166,0,0,0,0,0,168,34,7,206,166,0,0,172,89, + 0,175,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255,255,255,166,89,225,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,89,255,251,89,0,0,12,235,125,0,138,225,21,0,0, + 0,0,0,0,0,0,7,206,255,201,0,0,0,89,225,21,0,0,0,0,7,206,255,201,0,0,0,89, + 225,21,0,0,0,0,12,206,21,12,235,125,0,0,175,166,0,0,0,0,0,0,59,245,125, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,175,255,255,255, + 166,0,0,12,235,125,0,0,0,0,89,225,21,0,0,12,232,89,0,89,247,34,89,247,34, + 0,0,7,206,125,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,89,225,21,0,0,0,0, + 0,7,206,125,0,0,7,206,255,255,247,34,0,0,0,85,89,0,85,89,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,89,225,21,0,0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,0,89,201, + 0,0,12,228,34,0,0,0,0,138,166,0,0,0,0,0,0,0,7,206,125,0,0,7,206,255,166, + 0,0,0,0,0,0,0,0,0,12,235,125,0,0,89,247,34,175,255,255,255,166,89,225,21, + 0,89,255,125,0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,89,225,21,0,12,232,89,59, + 115,0,59,115,0,0,0,0,0,89,201,0,0,7,206,125,0,0,0,0,0,0,0,89,201,0,0,7, + 206,125,0,0,0,0,0,0,0,0,12,232,89,0,59,238,34,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,225,21,0,0,138,247,94,192,12,182, + 0,0,12,235,125,0,0,0,0,0,175,255,255,255,255,166,0,0,7,206,171,206,166, + 0,0,0,7,206,125,0,7,206,251,89,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,59,245, + 255,255,201,0,12,228,34,12,235,166,0,12,228,34,0,0,138,251,89,138,247,34, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,202,89,0,138,255,255,255,125,0,12,228,34, + 0,0,0,0,0,0,0,0,59,241,89,0,138,201,0,0,0,0,0,138,166,0,0,0,0,0,0,0,175, + 201,0,0,0,0,0,0,175,201,0,0,0,0,0,0,0,0,12,235,125,0,0,89,247,34,175,255, + 255,255,166,89,225,21,0,89,255,125,0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,138, + 225,21,0,12,235,125,12,235,166,59,245,166,0,0,0,0,89,201,0,0,89,225,21, + 0,0,0,0,0,0,0,89,201,0,0,89,225,21,0,0,0,0,0,0,12,235,255,125,0,0,175,125, + 0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89, + 225,21,0,12,235,125,59,192,0,0,0,0,12,235,125,0,0,0,0,0,59,215,21,59,238, + 34,0,0,0,89,255,247,34,0,0,0,7,206,125,0,0,7,206,255,255,247,34,0,0,0,0, + 0,0,0,0,59,192,0,12,235,166,0,7,176,21,0,175,125,59,238,34,0,12,228,34, + 0,138,247,34,138,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,192,0,0,138, + 201,0,89,247,34,0,175,125,0,0,0,0,0,0,0,0,0,89,255,255,225,21,0,7,206,255, + 255,255,255,255,255,247,34,0,12,235,125,0,0,0,7,176,21,0,175,201,0,0,0, + 0,0,0,0,0,12,235,125,0,0,89,247,34,89,255,255,255,166,89,225,21,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,7,202,89,0,0,89,225,21,0,12,232,89,0,12,235,166,12, + 235,166,0,0,0,89,201,0,7,206,125,0,12,235,166,0,0,0,0,89,201,0,7,206,125, + 89,255,255,255,125,0,0,0,0,7,206,125,89,225,21,0,138,225,21,0,0,0,138,255, + 125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,247,34,0,59,241,89,59, + 192,0,0,0,12,235,255,255,255,225,21,0,0,138,166,0,7,202,89,0,0,0,7,206, + 166,0,0,0,0,0,0,0,0,7,206,125,0,12,235,201,0,0,0,0,0,0,0,0,89,166,0,89, + 247,34,0,0,0,0,0,89,166,12,232,89,0,138,247,34,89,247,34,59,238,34,0,0, + 12,235,255,255,255,255,255,255,247,34,89,255,255,255,166,89,166,0,0,138, + 201,0,138,225,21,0,89,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166, + 0,0,0,0,7,206,255,255,255,247,34,0,59,245,255,247,34,0,0,0,0,0,0,0,0,12, + 235,125,0,0,89,247,34,0,89,255,255,166,89,225,21,0,0,0,0,0,0,0,0,0,0,0, + 0,0,89,255,255,255,166,0,12,235,125,0,138,225,21,0,0,12,235,125,12,235, + 125,0,0,89,201,0,89,201,0,7,206,223,166,0,0,0,0,89,201,0,89,201,0,89,125, + 0,138,225,21,12,182,0,7,206,133,206,125,0,89,232,215,21,0,7,206,247,34, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,247,34,0,59,241,89,59, + 192,0,0,0,0,12,235,125,0,0,0,0,0,59,215,21,59,238,34,0,59,245,255,255,255, + 255,225,21,0,0,0,0,0,59,241,89,0,0,138,225,21,0,0,0,0,0,0,0,89,166,0,89, + 247,34,0,0,0,0,0,89,166,0,138,255,255,176,228,34,0,138,247,34,138,247,34, + 0,0,0,0,0,0,0,0,59,238,34,0,0,0,0,0,89,166,0,0,138,255,255,225,21,0,0,89, + 166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,89,247,34,0,0,0,138,166,89,225, + 21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,255,247,34,0,0,12,235, + 166,12,235,166,0,0,0,0,0,12,232,89,0,175,166,138,166,0,0,0,0,0,0,12,232, + 89,0,0,0,0,138,201,0,0,89,255,255,201,89,225,21,89,225,81,215,21,0,138, + 247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,247,34,0,12,235, + 125,59,192,0,0,0,0,59,241,89,0,0,0,0,0,175,255,255,255,255,166,0,0,0,7, + 206,166,0,0,0,0,7,206,125,0,12,235,201,0,7,206,166,0,0,0,0,0,0,0,0,59,192, + 0,12,235,166,0,7,176,21,0,175,125,0,0,0,0,0,0,0,0,0,138,251,89,138,247, + 34,0,0,0,0,0,0,0,59,238,34,0,0,0,0,0,59,192,0,0,138,201,59,245,166,0,0, + 175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,166,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,89,247,34,0,0,0,138,166, + 89,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,166, + 59,245,166,0,0,0,0,0,0,138,201,0,138,201,0,138,166,0,0,0,0,0,0,138,201, + 0,0,0,0,89,247,34,0,0,0,0,0,7,206,125,59,238,34,59,215,21,0,175,225,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,89,247,34,0,0,175,225,81, + 192,12,182,0,7,206,125,0,0,0,0,0,89,225,21,0,0,12,232,89,0,0,7,206,166, + 0,0,0,0,7,206,125,0,0,59,245,255,255,166,0,0,0,0,0,0,0,0,0,7,202,89,0,59, + 245,255,255,166,0,12,228,34,0,0,0,0,0,0,0,0,0,0,85,89,0,85,89,0,0,0,0,0, + 0,0,59,238,34,0,0,0,0,0,7,202,89,0,138,201,0,59,245,225,34,228,34,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,255,255,255,255,255,247,34,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,201,0,0,175,247,34,0,0,0,138,166, + 89,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,115,0, + 59,115,0,0,0,0,0,0,12,232,89,0,175,255,255,255,255,201,0,0,0,0,12,232,89, + 0,0,0,138,201,0,0,0,0,0,0,0,89,201,0,89,255,255,255,255,247,34,138,251, + 89,0,7,176,21,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,138,247,34,0,0,0, + 175,255,255,255,166,0,89,255,255,255,255,255,247,34,0,0,0,0,0,0,0,0,0,0, + 7,206,166,0,0,0,0,7,206,125,0,0,0,0,0,138,255,166,0,0,0,0,0,0,0,0,0,89, + 225,21,0,0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,59,238,34,0,0,0,0,0,0,89,225,21,0,0,0,0,0,7,206,125,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,12,235,191,255,255,166,238,34,0,0,0,138,166,89,225,21,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,201,0,0, + 0,0,0,138,166,0,0,0,0,0,175,201,0,0,0,89,255,255,255,255,125,0,0,0,12,232, + 89,0,0,0,0,59,215,21,0,0,138,255,255,255,225,21,0,0,0,0,0,0,0,0,0,0,0,0, + 0,127,0,0,0,0,0,0,0,0,0,0,0,0,59,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,7,206,125,0,0,0,0,0,0,175,201,0,0,0,0,0,0,0,0,0,0, + 89,255,125,0,0,0,59,245,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,89,255,125,0,0,0,59,245,166,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,12,235,125,0,0,0,0,0,0,0,0,138,166,89,225,21,0,0,0,0,0,0,0,0,0,175, + 125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,59,192,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,125,0,7,199,34, + 0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,7,206,255,255,255,247,34,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,255, + 255,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0,0,138,166, + 89,225,21,0,0,0,0,0,0,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,7,206,125,0,7,206,255,255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,12,235,255,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127, + 127,127,0,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,0,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,0,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,138,225, + 21,0,0,0,0,0,12,235,125,0,0,0,0,19,172,255,190,11,0,0,0,0,138,255,201,7, + 202,89,0,0,0,0,0,0,0,0,0,0,7,206,255,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,59,138,225,21,0,0,0,0,0,0,59,245,201,0,0,0,19,172, + 255,190,11,0,0,0,0,0,0,0,0,0,7,206,225,21,0,0,0,59,245,201,19,172,255,190, + 11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,251,89,89,201,0,0,0,0,0,175, + 201,0,0,0,0,0,0,0,0,7,206,225,21,0,0,0,0,0,19,172,255,190,11,0,0,0,0,0, + 175,255,166,12,228,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,89,255,125,0,0,0,0,0,0,0,12,175,247,34,0,0,0,19,172,255, + 190,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,247,34,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,0,0,0,7,206,125,0,0,0,0,0,138,201,0,0,0,0,0,136,190, + 45,196,145,0,0,0,59,215,21,175,255,166,0,0,0,175,225,29,206,166,0,0,7,202, + 89,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,209,125, + 0,0,0,0,0,0,138,225,21,0,0,0,136,190,45,196,145,0,0,0,175,225,29,206,166, + 0,0,12,235,125,0,0,12,138,225,21,136,190,45,196,145,159,251,89,138,247, + 34,0,0,0,0,0,0,0,0,0,0,0,175,125,59,245,247,34,0,0,0,0,0,12,232,89,0,0, + 0,0,0,0,0,175,166,0,0,0,0,0,0,12,136,190,45,196,145,0,0,0,0,138,166,12, + 235,255,125,0,0,0,0,7,206,166,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,12,232,89,0,0,0,0,0,0,138,201,0,0,0,0,0,136,190,45, + 196,145,34,0,0,0,89,251,89,138,247,34,0,0,0,0,0,138,201,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,202,89,7,202,89,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,255, + 255,125,0,0,0,0,127,0,0,7,206,251,89,0,0,0,0,7,206,251,89,0,0,0,0,7,206, + 251,89,0,0,0,0,0,7,206,251,89,0,0,0,0,7,206,251,89,0,0,0,0,12,235,255,125, + 0,0,0,0,0,89,255,255,255,255,255,255,255,255,125,0,0,0,59,245,255,255,255, + 201,12,235,255,255,255,255,255,125,12,235,255,255,255,255,255,125,12,235, + 255,255,255,255,255,125,12,235,255,255,255,255,255,125,89,255,255,255,201, + 89,255,255,255,201,89,255,255,255,201,89,255,255,255,201,0,175,255,255, + 255,255,201,0,0,0,12,235,251,89,0,0,12,235,125,0,0,0,138,255,255,166,0, + 0,0,0,0,0,138,255,255,166,0,0,0,0,0,0,138,255,255,166,0,0,0,0,0,0,138,255, + 255,166,0,0,0,0,0,0,138,255,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138, + 255,255,201,89,251,89,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59,245, + 125,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59,245,125,7,206,225,21, + 0,0,0,138,247,0,235,166,0,0,0,0,0,0,138,225,21,7,206,166,0,0,0,127,0,0, + 59,245,255,166,0,0,0,0,59,245,255,166,0,0,0,0,59,245,255,166,0,0,0,0,0, + 59,245,255,166,0,0,0,0,59,245,255,166,0,0,0,0,59,245,255,166,0,0,0,0,0, + 175,201,7,206,166,0,0,0,0,0,0,0,138,255,125,0,0,7,202,102,235,166,0,0,0, + 0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,0,12, + 235,125,0,0,12,235,125,0,0,12,235,125,0,0,12,235,125,0,0,175,201,0,0,7, + 206,251,89,0,12,235,255,201,0,0,12,235,125,0,59,245,166,0,0,138,251,89, + 0,0,59,245,166,0,0,138,251,89,0,0,59,245,166,0,0,138,251,89,0,0,59,245, + 166,0,0,138,251,89,0,0,59,245,166,0,0,138,251,89,0,0,0,0,0,0,0,0,0,0,0, + 0,59,245,166,0,0,89,255,166,0,12,235,125,0,0,0,59,245,125,12,235,125,0, + 0,0,59,245,125,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59,245,125, + 0,59,245,125,0,0,59,245,125,12,235,166,0,0,0,0,0,12,235,125,0,0,175,201, + 0,0,0,127,0,0,138,225,151,225,21,0,0,0,138,225,151,225,21,0,0,0,138,225, + 151,225,21,0,0,0,0,138,225,151,225,21,0,0,0,138,225,151,225,21,0,0,0,138, + 225,151,225,21,0,0,0,59,241,89,7,206,166,0,0,0,0,0,0,12,235,166,0,0,0,0, + 0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235, + 166,0,0,0,0,0,0,12,235,125,0,0,12,235,125,0,0,12,235,125,0,0,12,235,125, + 0,0,175,201,0,0,0,0,175,225,21,12,235,166,245,125,0,12,235,125,12,235,125, + 0,0,0,0,138,247,34,12,235,125,0,0,0,0,138,247,34,12,235,125,0,0,0,0,138, + 247,34,12,235,125,0,0,0,0,138,247,34,12,235,125,0,0,0,0,138,247,34,0,138, + 225,21,0,0,0,175,201,0,12,235,125,0,0,7,202,159,247,34,12,235,125,0,0,0, + 59,245,125,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59,245,125,12,235, + 125,0,0,0,59,245,125,0,0,138,247,34,7,206,201,0,12,235,255,255,255,251, + 89,0,12,235,125,0,12,235,125,0,0,0,127,0,7,206,166,59,241,89,0,0,7,206, + 166,59,241,89,0,0,7,206,166,59,241,89,0,0,0,7,206,166,59,241,89,0,0,7,206, + 166,59,241,89,0,0,7,206,166,59,241,89,0,0,0,138,225,21,7,206,166,0,0,0, + 0,0,0,89,247,34,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12, + 235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,0,12,235,125,0,0,12,235,125,0,0, + 12,235,125,0,0,12,235,125,0,0,175,201,0,0,0,0,59,241,89,12,235,125,138, + 225,21,12,235,125,89,247,34,0,0,0,0,59,245,125,89,247,34,0,0,0,0,59,245, + 125,89,247,34,0,0,0,0,59,245,125,89,247,34,0,0,0,0,59,245,125,89,247,34, + 0,0,0,0,59,245,125,0,0,175,225,21,0,175,225,21,0,89,247,34,0,0,138,166, + 12,235,125,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59,245,125,12,235, + 125,0,0,0,59,245,125,12,235,125,0,0,0,59,245,125,0,0,12,235,166,89,247, + 34,0,12,235,166,0,0,138,251,89,12,235,133,206,255,125,0,0,0,0,127,0,59, + 241,89,7,206,166,0,0,59,241,89,7,206,166,0,0,59,241,89,7,206,166,0,0,0, + 59,241,89,7,206,166,0,0,59,241,89,7,206,166,0,0,59,241,89,7,206,166,0,0, + 12,235,125,0,7,206,255,255,255,255,247,34,0,138,225,21,0,0,0,0,0,12,235, + 255,255,255,255,247,34,12,235,255,255,255,255,247,34,12,235,255,255,255, + 255,247,34,12,235,255,255,255,255,247,34,0,12,235,125,0,0,12,235,125,0, + 0,12,235,125,0,0,12,235,125,0,206,255,255,255,247,34,0,12,235,125,12,235, + 125,12,235,125,12,235,125,138,225,21,0,0,0,0,12,235,166,138,225,21,0,0, + 0,0,12,235,166,138,225,21,0,0,0,0,12,235,166,138,225,21,0,0,0,0,12,235, + 166,138,225,21,0,0,0,0,12,235,166,0,0,0,175,225,187,225,21,0,0,138,225, + 21,0,59,215,21,7,206,166,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59, + 245,125,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59,245,125,0,0,0,89, + 255,255,125,0,0,12,235,166,0,0,12,235,166,12,235,125,0,7,206,201,0,0,0, + 127,0,138,225,21,0,138,225,21,0,138,225,21,0,138,225,21,0,138,225,21,0, + 138,225,21,0,0,138,225,21,0,138,225,21,0,138,225,21,0,138,225,21,0,138, + 225,21,0,138,225,21,0,89,255,255,255,255,255,166,0,0,0,0,0,0,138,225,21, + 0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0, + 0,12,235,166,0,0,0,0,0,0,12,235,125,0,0,12,235,125,0,0,12,235,125,0,0,12, + 235,125,0,0,175,201,0,0,0,0,12,235,125,12,235,125,0,138,225,34,235,125, + 138,225,21,0,0,0,0,12,235,166,138,225,21,0,0,0,0,12,235,166,138,225,21, + 0,0,0,0,12,235,166,138,225,21,0,0,0,0,12,235,166,138,225,21,0,0,0,0,12, + 235,166,0,0,0,0,175,225,21,0,0,0,138,225,21,7,202,89,0,7,206,166,12,235, + 125,0,0,0,59,245,125,12,235,125,0,0,0,59,245,125,12,235,125,0,0,0,59,245, + 125,12,235,125,0,0,0,59,245,125,0,0,0,7,206,225,21,0,0,12,235,166,0,0,12, + 235,166,12,235,125,0,0,59,241,89,0,0,127,7,206,255,255,255,255,251,89,7, + 206,255,255,255,255,251,89,7,206,255,255,255,255,251,89,0,7,206,255,255, + 255,255,251,89,7,206,255,255,255,255,251,89,7,206,255,255,255,255,251,89, + 7,206,166,0,0,7,206,166,0,0,0,0,0,0,89,247,34,0,0,0,0,0,12,235,166,0,0, + 0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,0, + 12,235,125,0,0,12,235,125,0,0,12,235,125,0,0,12,235,125,0,0,175,201,0,0, + 0,0,59,241,89,12,235,125,0,12,235,138,235,125,89,247,34,0,0,0,0,59,245, + 125,89,247,34,0,0,0,0,59,245,125,89,247,34,0,0,0,0,59,245,125,89,247,34, + 0,0,0,0,59,245,125,89,247,34,0,0,0,0,59,245,125,0,0,0,175,225,187,225,21, + 0,0,138,247,34,175,125,0,0,12,235,125,12,235,125,0,0,0,59,241,89,12,235, + 125,0,0,0,59,241,89,12,235,125,0,0,0,59,241,89,12,235,125,0,0,0,59,241, + 89,0,0,0,0,175,225,21,0,0,12,235,166,0,0,175,247,34,12,235,125,0,0,12,235, + 125,0,0,127,59,241,89,0,0,7,206,166,59,241,89,0,0,7,206,166,59,241,89,0, + 0,7,206,166,0,59,241,89,0,0,7,206,166,59,241,89,0,0,7,206,166,59,241,89, + 0,0,7,206,166,59,241,89,0,0,7,206,166,0,0,0,0,0,0,59,245,166,0,0,0,0,0, + 12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235,166, + 0,0,0,0,0,0,12,235,125,0,0,12,235,125,0,0,12,235,125,0,0,12,235,125,0,0, + 175,201,0,0,0,0,175,225,21,12,235,125,0,0,138,232,245,125,12,235,125,0, + 0,0,0,138,247,34,12,235,125,0,0,0,0,138,247,34,12,235,125,0,0,0,0,138,247, + 34,12,235,125,0,0,0,0,138,247,34,12,235,125,0,0,0,0,138,247,34,0,0,175, + 225,21,0,175,225,21,0,59,245,191,201,0,0,0,89,225,21,12,235,166,0,0,0,89, + 251,89,12,235,166,0,0,0,89,251,89,12,235,166,0,0,0,89,251,89,12,235,166, + 0,0,0,89,251,89,0,0,0,0,175,225,21,0,0,12,235,255,255,255,247,34,0,12,235, + 125,0,0,59,241,89,0,0,127,138,225,21,0,0,0,138,247,163,225,21,0,0,0,138, + 247,163,225,21,0,0,0,138,247,34,138,225,21,0,0,0,138,247,163,225,21,0,0, + 0,138,247,163,225,21,0,0,0,138,247,198,225,21,0,0,7,206,166,0,0,0,0,0,0, + 0,138,255,125,0,0,7,202,102,235,166,0,0,0,0,0,12,235,166,0,0,0,0,0,12,235, + 166,0,0,0,0,0,12,235,166,0,0,0,0,0,0,12,235,125,0,0,12,235,125,0,0,12,235, + 125,0,0,12,235,125,0,0,175,201,0,0,7,206,251,89,0,12,235,125,0,0,12,235, + 255,125,0,89,255,125,0,0,89,251,89,0,0,89,255,125,0,0,89,251,89,0,0,89, + 255,125,0,0,89,251,89,0,0,89,255,125,0,0,89,251,89,0,0,89,255,125,0,0,89, + 251,89,0,0,138,225,21,0,0,0,175,201,0,0,138,251,89,0,0,89,251,89,0,0,138, + 247,34,0,7,206,225,21,0,138,247,34,0,7,206,225,21,0,138,247,34,0,7,206, + 225,21,0,138,247,34,0,7,206,225,21,0,0,0,0,175,225,21,0,0,12,235,166,0, + 0,0,0,0,12,235,125,0,0,175,225,21,0,0,127,206,166,0,0,0,0,59,245,255,166, + 0,0,0,0,59,245,255,166,0,0,0,0,59,245,133,206,166,0,0,0,0,59,245,255,166, + 0,0,0,0,59,245,255,166,0,0,0,0,59,245,255,125,0,0,0,7,206,255,255,255,255, + 255,125,0,0,0,59,245,255,255,255,201,12,235,255,255,255,255,255,125,12, + 235,255,255,255,255,255,125,12,235,255,255,255,255,255,125,12,235,255,255, + 255,255,255,125,89,255,255,255,201,89,255,255,255,201,89,255,255,255,201, + 89,255,255,255,201,0,175,255,255,255,255,225,21,0,0,12,235,125,0,0,0,138, + 255,125,0,0,0,175,255,255,201,0,0,0,0,0,0,175,255,255,201,0,0,0,0,0,0,175, + 255,255,201,0,0,0,0,0,0,175,255,255,201,0,0,0,0,0,0,175,255,255,201,0,0, + 0,0,0,0,0,0,0,0,0,0,0,7,202,97,206,255,255,201,0,0,0,0,0,138,255,255,255, + 201,0,0,0,0,138,255,255,255,201,0,0,0,0,138,255,255,255,201,0,0,0,0,138, + 255,255,255,201,0,0,0,0,0,0,175,225,21,0,0,12,235,166,0,0,0,0,0,12,235, + 133,206,255,225,21,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,138,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,138,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,175,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,225,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,0,127,127,127,127,0,127,127,127,127,0,127,127,127, + 127,0,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,7,206,225,21, + 0,0,0,0,0,12,235,225,21,0,0,89,255,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,7,206,255,247,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,247, + 34,0,0,0,0,0,0,0,138,251,89,0,0,59,245,247,34,0,0,0,0,0,0,0,0,0,175,247, + 34,0,0,175,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,225,21, + 0,0,0,0,0,0,0,138,255,125,0,0,0,12,235,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,251,89,0,0,0,0,0,0, + 7,206,225,21,0,0,0,7,206,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,59,245,166,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,59,241,89,0,0,0,0, + 0,89,247,34,0,0,7,206,138,235,125,0,0,89,255,225,21,175,125,0,0,0,0,0,0, + 0,0,0,138,201,0,138,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, + 235,125,0,0,0,0,0,0,12,235,125,0,0,0,175,171,206,166,0,0,0,0,0,0,0,0,0, + 7,206,166,0,59,245,255,166,238,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,125,59, + 215,21,0,0,59,241,89,0,0,0,0,0,0,7,206,166,0,0,0,0,138,201,175,201,0,0, + 0,12,235,251,89,89,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,7,206,166,0,0,0,0,0,0,89,247,34,0,0,0,0,89,225,151,201,0,0,0,0, + 0,0,0,0,0,0,0,0,0,175,201,0,12,235,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,127,0,0,0,138,201,0,0,0,0,7,206,125,0,0,0,138,201,0,89,225,21, + 12,228,34,138,255,201,0,0,0,138,247,34,175,225,21,0,138,201,0,138,201,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,225,21,0,0,0,0,0,89,225, + 21,0,0,89,247,34,59,241,89,0,59,241,89,89,247,34,0,0,89,225,21,175,127, + 215,21,206,247,42,206,0,138,255,247,42,206,125,0,0,138,166,12,235,251,89, + 0,0,0,0,138,201,0,0,0,0,0,0,89,225,21,0,0,0,59,241,89,12,235,125,0,0,175, + 125,59,245,247,34,0,0,12,235,125,89,251,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,59,238,34,0,0,0,0,0,175,166,0,0,0,0,12,232,89,7,206,125,0, + 0,12,235,166,59,245,125,0,0,0,59,238,34,0,12,235,125,0,0,0,0,0,0,89,247, + 34,138,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,255,247,34,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,251,89,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,34,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,235,125,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,12,235,255,255,255,166,0,12,235,255, + 255,255,166,0,12,235,255,255,255,166,0,12,235,255,255,255,166,0,0,12,235, + 255,255,255,166,0,12,235,255,255,255,166,0,12,235,255,255,255,166,0,175, + 255,255,125,0,0,12,235,255,255,125,0,0,12,235,255,255,225,21,0,0,12,235, + 255,255,225,21,0,12,235,255,255,225,21,0,12,235,255,255,225,21,0,12,235, + 125,12,235,125,12,235,125,12,235,125,0,12,235,125,89,251,89,0,12,235,138, + 235,255,247,34,0,0,12,235,255,255,201,0,0,0,12,235,255,255,201,0,0,0,12, + 235,255,255,201,0,0,0,12,235,255,255,201,0,0,0,12,235,255,255,201,0,0,0, + 0,0,0,175,247,34,0,0,0,12,235,255,255,255,166,0,59,241,89,0,0,89,247,34, + 59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,42, + 206,201,0,0,0,138,232,245,166,245,255,251,89,7,206,201,0,0,0,138,225,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,12,206,21,0,59,245,125,12,206,21,0,59,245,125,12,206, + 21,0,59,245,125,12,206,21,0,59,245,125,0,12,206,21,0,59,245,125,12,206, + 21,0,59,245,125,12,206,21,0,12,235,255,125,0,7,206,166,12,235,166,0,0,172, + 102,0,235,125,0,0,175,201,0,12,235,125,0,0,175,201,12,235,125,0,0,175,201, + 12,235,125,0,0,175,201,0,12,235,125,12,235,125,12,235,125,12,235,125,0, + 0,0,0,0,175,201,0,12,235,247,34,0,175,201,0,12,235,166,0,7,206,201,0,12, + 235,166,0,7,206,201,0,12,235,166,0,7,206,201,0,12,235,166,0,7,206,201,0, + 12,235,166,0,7,206,201,0,0,0,0,0,175,247,34,0,0,12,235,166,0,12,235,201, + 0,59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,34,59,241,89,0,0,89,247, + 34,59,241,89,0,0,89,247,34,89,247,34,0,7,206,176,235,225,21,0,175,225,21, + 89,247,34,0,7,206,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,7,206,166,0,0,0,0,7, + 206,166,0,0,0,0,7,206,166,0,0,0,0,7,206,166,0,0,0,0,0,7,206,166,0,0,0,0, + 7,206,166,0,0,0,0,0,175,201,0,0,0,89,225,138,225,21,0,0,0,0,89,225,21,0, + 0,89,247,34,89,225,21,0,0,89,247,124,225,21,0,0,89,247,124,225,21,0,0,89, + 247,34,12,235,125,12,235,125,12,235,125,12,235,125,0,89,255,255,255,255, + 247,34,12,235,125,0,0,89,247,34,138,225,21,0,0,59,238,34,138,225,21,0,0, + 59,238,34,138,225,21,0,0,59,238,34,138,225,21,0,0,59,238,34,138,225,21, + 0,0,59,238,34,0,0,0,0,0,0,0,0,0,138,225,21,0,172,132,238,34,59,241,89,0, + 0,89,247,34,59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,34,59,241,89,0, + 0,89,247,34,12,235,125,0,59,238,47,235,125,0,0,59,241,89,12,235,125,0,59, + 238,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,59,245,255,255,255,166,0,59,245,255,255, + 255,166,0,59,245,255,255,255,166,0,59,245,255,255,255,166,0,0,59,245,255, + 255,255,166,0,59,245,255,255,255,166,0,89,255,255,255,255,255,255,255,255, + 255,247,175,201,0,0,0,0,0,175,255,255,255,255,255,247,34,175,255,255,255, + 255,255,247,198,255,255,255,255,255,247,198,255,255,255,255,255,247,34, + 12,235,125,12,235,125,12,235,125,12,235,125,89,251,89,0,0,59,241,89,12, + 235,125,0,0,89,247,34,175,201,0,0,0,12,232,89,175,201,0,0,0,12,232,89,175, + 201,0,0,0,12,232,89,175,201,0,0,0,12,232,89,175,201,0,0,0,12,232,89,7,206, + 255,255,255,255,255,255,251,226,201,0,89,166,12,232,89,59,241,89,0,0,89, + 247,34,59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,34,59,241,89,0,0,89, + 247,34,0,175,201,0,138,201,12,235,125,0,0,12,235,125,0,175,201,0,138,201, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,127,89,255,166,0,7,206,166,89,255,166,0,7,206,166,89, + 255,166,0,7,206,166,89,255,166,0,7,206,166,0,89,255,166,0,7,206,166,89, + 255,166,0,7,206,166,138,255,125,0,0,175,201,0,0,0,0,0,175,201,0,0,0,0,0, + 175,201,0,0,0,0,0,0,175,201,0,0,0,0,0,175,201,0,0,0,0,0,175,201,0,0,0,0, + 0,0,12,235,125,12,235,125,12,235,125,12,235,125,175,201,0,0,0,59,241,89, + 12,235,125,0,0,89,247,34,175,201,0,0,0,12,232,89,175,201,0,0,0,12,232,89, + 175,201,0,0,0,12,232,89,175,201,0,0,0,12,232,89,175,201,0,0,0,12,232,89, + 0,0,0,0,0,0,0,0,0,175,201,7,176,21,12,232,89,59,241,89,0,0,89,247,34,59, + 241,89,0,0,89,247,34,59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,34,0, + 89,247,47,235,125,12,235,125,0,0,12,235,125,0,89,247,47,235,125,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,127,175,201,0,0,7,206,166,175,201,0,0,7,206,166,175,201,0,0, + 7,206,166,175,201,0,0,7,206,166,0,175,201,0,0,7,206,166,175,201,0,0,7,206, + 166,175,201,0,0,0,138,225,21,0,0,0,0,138,225,21,0,0,0,0,138,247,34,0,0, + 0,0,0,138,247,34,0,0,0,0,138,247,34,0,0,0,0,138,247,34,0,0,0,0,0,12,235, + 125,12,235,125,12,235,125,12,235,125,175,201,0,0,0,89,247,34,12,235,125, + 0,0,89,247,34,138,225,21,0,0,89,247,34,138,225,21,0,0,89,247,34,138,225, + 21,0,0,89,247,34,138,225,21,0,0,89,247,34,138,225,21,0,0,89,247,34,0,0, + 0,0,175,247,34,0,0,138,225,151,125,0,89,247,34,59,241,89,0,0,89,247,34, + 59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,34,59,241,89,0,0,89,247,34, + 0,12,235,191,247,34,12,235,125,0,0,59,241,89,0,12,235,191,247,34,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,127,138,225,21,0,138,255,166,138,225,21,0,138,255,166,138, + 225,21,0,138,255,166,138,225,21,0,138,255,166,0,138,225,21,0,138,255,166, + 138,225,21,0,138,255,166,89,247,34,0,89,255,255,166,0,0,12,206,12,235,166, + 0,0,127,102,0,235,201,0,0,12,206,21,12,235,201,0,0,12,206,34,235,201,0, + 0,12,206,34,235,201,0,0,12,206,21,12,235,125,12,235,125,12,235,125,12,235, + 125,89,255,125,0,7,206,166,0,12,235,125,0,0,89,247,34,12,235,166,0,7,206, + 201,0,12,235,166,0,7,206,201,0,12,235,166,0,7,206,201,0,12,235,166,0,7, + 206,201,0,12,235,166,0,7,206,201,0,0,0,0,0,175,247,34,0,0,12,235,201,0, + 7,206,201,0,7,206,166,0,59,245,247,34,7,206,166,0,59,245,247,34,7,206,166, + 0,59,245,247,34,7,206,166,0,59,245,247,34,0,0,138,255,166,0,12,235,125, + 0,7,206,201,0,0,0,138,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,7,206,255,255,171, + 206,166,7,206,255,255,171,206,166,7,206,255,255,171,206,166,7,206,255,255, + 171,206,166,0,7,206,255,255,171,206,166,7,206,255,255,171,206,166,0,89, + 255,255,201,0,0,175,255,255,247,34,0,12,235,255,255,166,0,0,7,206,255,255, + 247,34,0,0,7,206,255,255,247,34,0,7,206,255,255,247,34,0,7,206,255,255, + 247,34,0,12,235,125,12,235,125,12,235,125,12,235,125,0,89,255,255,255,201, + 0,0,12,235,125,0,0,89,247,34,0,12,235,255,255,201,0,0,0,12,235,255,255, + 201,0,0,0,12,235,255,255,201,0,0,0,12,235,255,255,201,0,0,0,12,235,255, + 255,201,0,0,0,0,0,0,0,0,0,0,0,7,206,255,255,255,201,0,0,0,59,245,255,225, + 111,247,34,0,59,245,255,225,111,247,34,0,59,245,255,225,111,247,34,0,59, + 245,255,225,111,247,34,0,0,59,241,89,0,12,235,255,255,255,225,21,0,0,0, + 59,241,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,175,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,138,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,225,21,0,12,235,125,0,0,0,0,0,0,0, + 138,225,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,7,202,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,206,166,0,0,12,235,125,0,0,0,0,0,0,7,206, + 166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,235,255,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,247,34,0,0,12,235,125,0,0,0,0,0,0,89,247, + 34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,0,127,127,0,127,127,0,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,0,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0 +}; + + +const int FONTFIXED1_BM_W = 257; +const int FONTFIXED1_BM_H = 112; + +static const unsigned char s_FontFixed1[] = { + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,52,255,56,255,4,0,0, + 0,0,0,212,44,76,180,0,0,0,52,255,4,0,0,0,0,109,231,218,72,0,0,0,0,0,96,227, + 243,170,0,0,0,0,52,255,4,0,0,0,0,0,0,0,158,104,0,0,0,0,153,114,0,0,0,0,0,0,0, + 52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,172,128,0,0,12,164,241,234,133,1,0,0,22,179,237,255,4,0,0,0,141,220 + ,246,236,164,22,0,0,94,216,242,243,194,56,0,0,0,0,0,186,255,4,0,0,52,255,244, + 244,244,91,0,0,1,120,223,244,225,62,0,0,244,244,244,244,249,242,0,0,62,200, + 245,242,181,35,0,0,46,196,244,232,139,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104,216,246,215,62,0,0,127,0,0 + ,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,52,255,56,255,4,0,0,0,0,13,239,2,131,124,0, + 0,110,232,255,238,202,62,0,29,254,51,99,231,0,0,0,0,0,241,53,0,34,0,0,0,0,52, + 255,4,0,0,0,0,0,0,45,225,4,0,0,0,0,30,237,15,0,0,0,0,99,95,52,255,11,127,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,242, + 19,0,0,155,188,12,29,221,103,0,0,21,101,90,255,4,0,0,0,127,46,1,15,165,192,0, + 0,34,24,0,5,127,233,0,0,0,0,98,197,255,4,0,0,52,255,4,0,0,0,0,0,121,219,45,0, + 22,27,0,0,0,0,0,0,170,151,0,14,242,119,4,12,160,207,0,3,224,136,5,18,188,114, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,114,38,2,133,225,0,0,127,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,52,255, + 56,255,4,0,0,0,0,67,189,0,187,69,0,26,254,100,255,8,53,44,0,30,254,49,100,235 + ,0,1,0,0,0,206,47,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,155,133,0,0,0,0,0,0,186, + 110,0,0,0,0,3,103,195,255,177,75,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,144,0,0,5,244,63,0,0,112,200,0,0,0,0,52, + 255,4,0,0,0,0,0,0,0,60,251,0,0,0,0,0,10,127,211,0,0,0,25,215,67,255,4,0,0,52, + 255,4,0,0,0,0,1,235,77,0,0,0,0,0,0,0,0,0,24,250,49,0,44,255,15,0,0,64,251,0, + 41,255,17,0,0,68,205,0,0,0,43,216,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,147,0, + 0,0,0,0,0,0,0,0,0,197,97,11,0,0,0,0,0,0,0,0,69,248,0,0,127,0,0,0,0,0,0,0,0,0, + 0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,63,240,247,248,240,254,241,0,42,255,69,255,4 + ,0,0,0,0,112,232,221,80,97,184,0,0,14,189,196,7,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 233,64,0,0,0,0,0,0,117,186,0,0,0,0,3,102,194,255,177,74,0,0,0,0,52,255,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,244,30,0,0,37,255,37 + ,175,0,66,244,0,0,0,0,52,255,4,0,0,0,0,0,0,0,126,195,0,0,0,48,241,255,190,16, + 0,0,0,176,90,52,255,4,0,0,52,255,228,236,162,16,0,33,255,106,220,237,172,21,0 + ,0,0,0,0,125,203,0,0,4,205,120,6,14,160,159,0,40,255,21,0,0,69,245,0,0,0,52, + 255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,13,102,203,225,132,0,0,240,240,240,240,240 + ,240,0,0,84,180,237,152,52,0,0,0,0,0,11,204,150,0,0,127,0,0,0,0,0,0,0,0,0,0, + 52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,190,66,54,202,0,0,2,196,220,255,106,32,0,0 + ,0,0,13,116,184,93,4,0,0,176,114,109,159,0,52,0,1,0,0,0,0,0,0,0,0,0,29,255,22 + ,0,0,0,0,0,0,72,236,0,0,0,0,99,96,52,255,11,128,0,0,240,240,243,255,240,240,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,161,0,0,0,49,255, + 33,216,0,54,255,0,0,0,0,52,255,4,0,0,0,0,0,0,68,236,45,0,0,0,0,0,27,198,133,0 + ,0,87,189,0,52,255,4,0,0,19,40,0,29,197,168,0,49,255,146,9,15,182,176,0,0,0,0 + ,3,226,100,0,0,0,28,210,252,255,182,7,0,2,223,142,6,20,186,255,0,0,0,0,0,0,0, + 0,0,0,0,43,216,3,0,0,0,0,158,233,162,67,1,0,0,0,0,0,0,0,0,0,0,0,0,0,23,115, + 210,208,0,0,0,0,176,192,6,0,0,127,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0, + 0,0,0,0,0,7,239,9,118,138,0,0,0,5,109,255,153,234,112,0,0,88,179,76,110,231, + 220,0,28,255,16,0,176,110,68,0,0,0,0,0,0,0,0,0,0,0,46,255,8,0,0,0,0,0,0,57, + 253,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,244,244, + 244,0,0,0,0,0,0,0,0,0,0,0,0,0,17,241,43,0,0,0,37,255,17,0,0,66,244,0,0,0,0,52 + ,255,4,0,0,0,0,0,73,233,60,0,0,0,0,0,0,0,69,238,0,16,227,40,0,52,255,4,0,0,0, + 0,0,0,69,246,0,38,255,20,0,0,69,247,0,0,0,0,79,242,11,0,0,5,214,122,7,16,162, + 175,0,0,46,193,239,210,125,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,215, + 114,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,67,162,236,0,0,0,34,255,31,0,0,0,127,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,236,244,251,240,251,244,228,0,0, + 0,52,255,4,76,245,0,0,11,0,29,254,51,101,0,40,255,30,0,18,222,193,0,0,0,0,0,0 + ,0,0,0,0,0,29,255,23,0,0,0,0,0,0,72,237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,178,0,0,0,0,5,245 + ,63,0,0,111,200,0,0,0,0,52,255,4,0,0,0,0,87,233,54,0,0,0,0,0,0,0,0,70,248,0, + 52,255,255,255,255,255,255,0,0,0,0,0,0,68,246,0,6,248,19,0,0,65,247,0,0,0,0, + 185,151,0,0,0,42,255,15,0,0,59,252,0,0,0,0,0,0,124,188,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,46,147,234,180,86,0,0,244,244,244,244,244,244,0,0,39,133,226, + 197,97,10,0,0,0,51,255,4,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,140,115,12,235,8,0,0,32,73,55,255,11,143,215,0,0,0,0,31,255,47,97,0,1 + ,211,174,16,6,148,252,0,0,0,0,0,0,0,0,0,0,0,1,233,65,0,0,0,0,0,0,116,187,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0, + 44,220,3,0,0,0,0,9,234,58,0,0,0,0,0,155,186,12,28,220,103,0,0,0,8,58,255,11,8 + ,0,0,105,232,47,0,0,0,0,0,101,32,0,25,193,173,0,0,0,0,0,52,255,4,0,0,70,25,0, + 25,193,166,0,0,165,147,7,13,176,176,0,0,0,36,254,49,0,0,0,15,245,120,4,12,157 + ,210,0,0,37,12,0,68,239,74,0,0,0,44,220,3,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,8, + 92,192,0,0,0,0,0,0,0,0,0,0,235,142,41,0,0,0,0,0,0,4,24,0,0,0,0,127,0,0,0,0,0, + 0,0,0,0,0,49,244,3,0,0,0,0,0,0,0,0,0,0,0,0,222,33,87,169,0,0,0,23,186,245,255 + ,243,186,39,0,0,0,0,0,122,239,229,0,0,30,181,245,231,147,178,0,3,0,0,0,0,0,0, + 0,0,0,0,155,133,0,0,0,0,0,0,185,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,62,241,1,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,108,195,0,0,0,0,0,0,13, + 165,241,235,134,1,0,0,0,255,255,255,255,255,0,0,255,250,244,244,244,244,0,0, + 143,226,244,238,163,17,0,0,0,0,0,52,255,4,0,0,134,236,245,236,155,13,0,0,16, + 167,238,242,175,22,0,0,0,139,203,0,0,0,0,0,68,203,246,243,185,39,0,0,104,235, + 244,212,88,0,0,0,0,52,255,4,0,0,0,0,0,62,241,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,6,0,0,0,0,0,0,0,0,49,244,3,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,225,4,0,0,0,0,29,237,16,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,120,157,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,223, + 75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,157,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,158,104,0,0,0,0,153,115,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,181,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,119,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,181,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0 + ,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127 + ,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,28,160 + ,229,236,163,14,0,0,0,20,252,200,0,0,0,52,255,244,243,238,177,32,0,0,0,96,213 + ,244,234,137,0,52,255,244,239,190,68,0,0,52,255,244,244,244,244,68,0,0,52,255 + ,244,244,244,244,0,0,0,104,217,244,222,100,0,52,255,4,0,0,52,255,0,0,244,246, + 255,244,244,0,0,0,0,137,244,246,255,4,0,52,255,4,0,0,137,216,0,0,52,255,4,0,0 + ,0,0,52,255,163,0,0,212,255,0,52,255,166,0,0,52,255,0,0,15,168,241,236,141,2, + 0,52,255,244,244,239,176,33,0,0,15,168,241,236,141,2,0,52,255,244,244,236,171 + ,30,0,0,47,189,243,241,204,73,0,0,244,244,246,255,244,244,0,52,255,4,0,0,52, + 255,0,125,203,0,0,0,24,254,0,236,75,0,0,0,0,152,0,44,247,51,0,0,71,241,0,220, + 112,0,0,0,161,179,0,0,244,244,244,244,249,254,0,0,0,52,255,244,125,0,0,35,244 + ,23,0,0,0,0,0,0,0,171,246,255,4,0,0,0,0,41,242,200,7,0,0,0,0,0,0,0,0,0,0,127, + 24,227,130,13,21,206,163,0,0,0,98,207,251,26,0,0,52,255,4,0,8,147,204,0,0,100 + ,224,51,0,22,89,0,52,255,4,7,81,238,66,0,52,255,4,0,0,0,0,0,0,52,255,4,0,0,0, + 0,0,106,221,46,0,29,89,0,52,255,4,0,0,52,255,0,0,0,52,255,4,0,0,0,0,0,0,0,52, + 255,4,0,52,255,4,0,133,218,26,0,0,52,255,4,0,0,0,0,52,255,202,4,36,219,255,0, + 52,255,242,30,0,52,255,0,0,160,175,10,24,213,112,0,52,255,4,0,20,166,204,0,0, + 160,175,10,24,213,112,0,52,255,4,0,17,166,201,0,8,232,119,7,3,56,63,0,0,0,0, + 52,255,4,0,0,52,255,4,0,0,52,255,0,48,253,19,0,0,94,226,0,197,107,0,0,0,0,184 + ,0,0,131,201,2,8,220,101,0,74,238,18,0,52,245,33,0,0,0,0,0,1,192,148,0,0,0,52 + ,255,4,0,0,0,0,168,135,0,0,0,0,0,0,0,0,52,255,4,0,0,0,16,218,106,178,159,0,0, + 0,0,0,0,0,0,0,0,127,157,170,0,0,0,88,243,0,0,0,179,121,200,105,0,0,52,255,4,0 + ,0,63,251,0,0,227,86,0,0,0,0,0,52,255,4,0,0,125,186,0,52,255,4,0,0,0,0,0,0,52 + ,255,4,0,0,0,0,1,229,84,0,0,0,0,0,52,255,4,0,0,52,255,0,0,0,52,255,4,0,0,0,0, + 0,0,0,52,255,4,0,52,255,4,130,220,27,0,0,0,52,255,4,0,0,0,0,52,255,141,66,115 + ,140,255,0,52,255,150,143,0,52,255,0,6,246,54,0,0,105,204,0,52,255,4,0,0,60, + 253,0,6,246,54,0,0,105,204,0,52,255,4,0,0,59,252,0,46,255,15,0,0,0,0,0,0,0,0, + 52,255,4,0,0,52,255,4,0,0,52,255,0,0,225,87,0,0,165,150,0,157,139,0,234,154,0 + ,215,0,0,7,216,102,132,187,0,0,0,176,146,0,194,127,0,0,0,0,0,0,101,223,12,0,0 + ,0,52,255,4,0,0,0,0,48,239,14,0,0,0,0,0,0,0,52,255,4,0,0,3,184,122,0,8,193, + 112,0,0,0,0,0,0,0,0,0,127,243,67,72,217,233,162,255,0,3,12,248,51,130,186,0,0 + ,52,255,4,0,12,158,197,0,31,255,22,0,0,0,0,0,52,255,4,0,0,69,240,0,52,255,4,0 + ,0,0,0,0,0,52,255,4,0,0,0,0,32,255,22,0,0,0,0,0,52,255,4,0,0,52,255,0,0,0,52, + 255,4,0,0,0,0,0,0,0,52,255,4,0,52,255,130,244,29,0,0,0,0,52,255,4,0,0,0,0,52, + 255,61,146,188,66,255,0,52,255,37,239,16,52,255,0,38,255,15,0,0,64,244,0,52, + 255,4,0,24,169,202,0,38,255,15,0,0,64,244,0,52,255,4,0,16,159,188,0,11,235, + 176,72,17,0,0,0,0,0,0,52,255,4,0,0,52,255,4,0,0,52,255,0,0,148,157,0,1,234,73 + ,0,118,170,31,225,207,0,246,0,0,0,62,237,237,32,0,0,0,31,241,124,221,8,0,0,0, + 0,0,25,238,68,0,0,0,0,52,255,4,0,0,0,0,0,184,118,0,0,0,0,0,0,0,52,255,4,0,0, + 44,101,0,0,0,14,121,0,0,0,0,0,0,0,0,0,127,255,32,242,102,5,147,255,0,4,86,235 + ,1,59,250,16,0,52,255,240,241,254,223,32,0,48,255,6,0,0,0,0,0,52,255,4,0,0,55 + ,255,0,52,255,240,240,240,240,22,0,0,52,255,240,240,240,202,0,48,255,6,0,138, + 241,248,0,52,255,240,240,240,243,255,0,0,0,52,255,4,0,0,0,0,0,0,0,52,255,4,0, + 52,255,220,235,100,0,0,0,0,52,255,4,0,0,0,0,52,255,6,209,182,52,255,0,52,255, + 4,169,120,52,255,0,49,255,5,0,0,54,255,0,52,255,240,240,231,169,31,0,49,255,5 + ,0,0,54,255,0,52,255,240,244,255,173,11,0,0,38,160,229,253,188,37,0,0,0,0,52, + 255,4,0,0,52,255,4,0,0,52,255,0,0,70,227,0,51,244,7,0,78,202,83,147,220,32, + 251,0,0,0,14,235,202,0,0,0,0,0,124,255,75,0,0,0,0,0,0,173,156,0,0,0,0,0,52, + 255,4,0,0,0,0,0,64,230,7,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,127,255,54,255,13,0,62,255,0,4,167,167,0,4,240,92,0,52,255,4,0,18,164, + 181,0,31,255,22,0,0,0,0,0,52,255,4,0,0,69,240,0,52,255,4,0,0,0,0,0,0,52,255,4 + ,0,0,0,0,32,255,20,0,0,52,255,0,52,255,4,0,0,52,255,0,0,0,52,255,4,0,0,0,0,0, + 0,0,52,255,3,0,52,255,33,86,243,35,0,0,0,52,255,4,0,0,0,0,52,255,4,127,89,52, + 255,0,52,255,4,52,230,58,255,0,38,255,15,0,0,64,244,0,52,255,4,0,0,0,0,0,38, + 255,15,0,0,64,247,0,52,255,4,1,87,251,67,0,0,0,0,0,32,176,207,0,0,0,0,52,255, + 4,0,0,51,255,4,0,0,52,255,0,0,6,242,42,121,174,0,0,39,234,136,91,168,112,218, + 0,0,0,153,180,211,98,0,0,0,0,52,255,4,0,0,0,0,0,80,228,15,0,0,0,0,0,52,255,4, + 0,0,0,0,0,0,200,101,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,255,37,243,102,5,147,255,0,11,241,250,248,248,253,173,0,52,255,4,0,0,58, + 249,0,0,228,84,0,0,0,0,0,52,255,4,0,0,126,186,0,52,255,4,0,0,0,0,0,0,52,255,4 + ,0,0,0,0,1,230,78,0,0,52,255,0,52,255,4,0,0,52,255,0,0,0,52,255,4,0,0,0,0,0,0 + ,0,61,250,0,0,52,255,4,0,170,199,3,0,0,52,255,4,0,0,0,0,52,255,4,0,0,52,255,0 + ,52,255,4,0,192,149,255,0,6,247,54,0,0,104,204,0,52,255,4,0,0,0,0,0,6,247,54, + 0,0,104,209,0,52,255,4,0,0,151,207,0,0,0,0,0,0,61,253,0,0,0,0,52,255,4,0,0,40 + ,255,8,0,0,56,248,0,0,0,171,112,192,97,0,0,4,250,199,35,111,196,178,0,0,66, + 241,28,64,236,21,0,0,0,52,255,4,0,0,0,0,14,228,75,0,0,0,0,0,0,52,255,4,0,0,0, + 0,0,0,80,218,2,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,238 + ,80,75,219,234,164,248,0,77,249,16,0,0,87,245,0,52,255,4,0,9,145,216,0,0,102, + 222,50,0,22,89,0,52,255,4,7,82,239,67,0,52,255,4,0,0,0,0,0,0,52,255,4,0,0,0,0 + ,0,109,215,40,0,81,255,0,52,255,4,0,0,52,255,0,0,0,52,255,4,0,0,0,43,112,13,3 + ,145,201,0,0,52,255,4,0,20,233,126,0,0,52,255,11,8,8,8,0,52,255,4,0,0,52,255, + 0,52,255,4,0,75,246,255,0,0,163,173,9,23,212,114,0,52,255,4,0,0,0,0,0,0,162, + 173,9,23,212,123,0,52,255,4,0,0,25,246,0,14,123,29,0,18,163,202,0,0,0,0,52, + 255,4,0,0,5,232,107,3,9,151,190,0,0,0,93,195,248,21,0,0,0,216,233,0,54,254, + 139,0,10,221,108,0,0,168,163,0,0,0,52,255,4,0,0,0,0,151,163,0,0,0,0,0,0,0,52, + 255,4,0,0,0,0,0,0,1,214,84,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,127,146,193,1,0,0,0,0,0,155,179,0,0,0,11,245,0,52,255,244,243,239,184,44 + ,0,0,0,99,214,244,237,140,0,52,255,244,240,191,69,0,0,52,255,244,244,244,244, + 99,0,0,52,255,4,0,0,0,0,0,0,109,219,243,223,116,0,52,255,4,0,0,52,255,0,0,244 + ,246,255,244,244,0,0,27,186,240,244,204,50,0,0,52,255,4,0,0,82,251,0,0,52,255 + ,255,255,255,255,0,52,255,4,0,0,52,255,0,52,255,4,0,1,213,255,0,0,16,171,241, + 237,143,3,0,52,255,4,0,0,0,0,0,0,16,170,241,254,187,6,0,52,255,4,0,0,0,138,0, + 9,171,229,246,240,177,33,0,0,0,0,52,255,4,0,0,0,51,197,244,241,177,28,0,0,0, + 18,252,198,0,0,0,0,176,179,0,5,247,99,0,144,199,2,0,0,27,243,0,0,0,52,255,4,0 + ,0,0,0,254,247,244,244,244,244,0,0,0,52,255,4,0,0,0,0,0,0,0,96,203,0,0,0,0,0, + 52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,16,216,165,31,2,24,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,237,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,5,226,68,0,0,0,0,52, + 255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,19,144,222,242,159,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,248,240,123,0,0,0,0,0,0,0,71,79,0,0,0,168, + 241,248,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,244,244,244,244,244,244,99,0,0,127,127,127,127,127,127,127,0,127,127, + 127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127 + ,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,9,124,20,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,0,127,0,0,112,174,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,4,221,0,127,0,0,0,159,98,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,0,0,0,0,0,0,0,0,0,0,0,2,166,243,244,102,0, + 0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,49,244,3,0,0,0,0,0,49,244,3,0,0,0,52 + ,255,4,0,0,0,0,11,244,246,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,158,239,209,0,0,0,0,52,255,4,0,0,11 + ,244,233,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,162,0,127,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,0,0,0,0,0, + 0,0,0,0,0,0,46,255,24,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,255,46,0,0,0,0,0 + ,52,255,4,0,0,0,0,96,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,149,81,0,127,0,0,0 + ,0,0,0,0,0,0,103,213,244,239,180,36,0,52,255,122,232,241,159,9,0,0,12,151,233 + ,244,202,40,0,0,26,183,244,223,133,255,0,0,13,156,236,241,165,12,0,19,244,246 + ,255,244,244,102,0,0,25,182,244,221,127,255,0,52,255,111,233,235,80,0,0,0,0, + 244,246,255,4,0,0,0,45,244,246,255,4,0,0,0,52,255,4,0,122,210,0,0,0,52,255,4, + 0,0,0,255,173,246,137,195,245,114,0,52,255,111,233,235,80,0,0,0,29,182,242, + 237,157,11,0,52,255,121,231,241,161,10,0,0,26,183,244,222,130,255,0,0,52,255, + 78,217,244,175,0,0,0,109,226,245,229,114,0,19,244,246,255,244,244,152,0,52, + 255,4,0,52,255,4,0,51,242,9,0,0,73,228,0,226,63,0,0,0,0,140,0,13,219,93,0,0, + 173,156,0,40,250,19,0,0,50,245,0,0,209,244,244,246,255,0,0,0,0,0,51,255,4,0,0 + ,0,0,0,52,255,4,0,0,0,0,52,255,3,0,0,0,0,0,0,0,0,0,0,0,0,5,8,0,1,219,10,0,127 + ,0,0,0,0,0,0,0,0,0,93,52,2,9,162,204,0,52,255,163,9,19,198,144,0,0,174,188,24 + ,0,53,43,0,0,193,157,7,20,200,255,0,0,173,186,16,11,179,152,0,0,0,52,255,4,0, + 0,0,0,189,167,10,19,199,255,0,52,255,121,2,133,219,0,0,0,0,0,52,255,4,0,0,0,0 + ,0,52,255,4,0,0,0,52,255,4,133,204,19,0,0,0,52,255,4,0,0,0,255,51,99,255,55, + 96,227,0,52,255,121,2,133,219,0,0,0,198,158,8,19,198,149,0,52,255,163,9,19, + 198,145,0,0,192,158,8,20,198,255,0,0,52,255,169,20,2,52,0,0,31,255,62,0,20,57 + ,0,0,0,52,255,4,0,0,0,52,255,4,0,52,255,4,0,0,216,84,0,0,162,139,0,166,118,0, + 0,0,0,195,0,0,49,235,36,104,211,9,0,0,200,106,0,0,142,163,0,0,0,0,0,149,171,0 + ,0,0,0,0,54,255,2,0,0,0,0,0,52,255,4,0,0,0,0,50,255,5,0,0,0,0,0,0,0,0,0,0,0, + 95,232,100,0,55,175,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,61,252,0,52,255,33,0,0, + 81,233,0,22,255,41,0,0,0,0,0,25,255,32,0,0,82,255,0,21,255,49,0,0,70,236,0,0, + 0,52,255,4,0,0,0,24,255,35,0,0,82,255,0,52,255,18,0,56,254,1,0,0,0,0,52,255,4 + ,0,0,0,0,0,52,255,4,0,0,0,52,255,146,227,15,0,0,0,0,52,255,4,0,0,0,255,8,56, + 255,8,56,253,0,52,255,18,0,56,254,1,0,27,255,32,0,0,81,234,0,52,255,33,0,0,81 + ,232,0,25,255,32,0,0,81,255,0,0,52,255,41,0,0,0,0,0,26,252,96,11,0,0,0,0,0,52 + ,255,4,0,0,0,52,255,4,0,52,255,4,0,0,125,173,0,8,242,48,0,106,173,0,192,118,4 + ,246,0,0,0,106,212,234,40,0,0,0,103,199,0,3,230,67,0,0,0,0,90,216,13,0,0,0,0, + 1,121,226,0,0,0,0,0,0,52,255,4,0,0,0,0,22,252,74,0,0,0,0,115,225,233,149,42, + 25,0,15,54,177,0,136,94,0,0,127,0,0,0,0,0,0,0,0,0,78,197,237,240,243,255,0,52 + ,255,6,0,0,55,254,0,47,255,7,0,0,0,0,0,48,255,6,0,0,55,255,0,47,255,240,240, + 240,241,247,0,0,0,52,255,4,0,0,0,48,255,7,0,0,55,255,0,52,255,4,0,52,255,4,0, + 0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,52,255,187,238,80,0,0,0,0,52,255,4,0, + 0,0,255,4,52,255,4,52,255,0,55,255,4,0,52,255,4,0,48,255,6,0,0,55,254,0,52, + 255,6,0,0,55,254,0,48,255,6,0,0,55,255,0,0,52,255,6,0,0,0,0,0,0,84,186,239, + 208,75,0,0,0,52,255,4,0,0,0,52,255,4,0,52,255,4,0,0,35,246,13,84,213,0,0,46, + 228,16,202,187,49,226,0,0,0,13,239,176,0,0,0,0,15,246,36,70,225,1,0,0,0,43, + 233,43,0,0,0,0,33,247,247,73,0,0,0,0,0,0,52,255,4,0,0,0,0,0,112,254,237,0,0,0 + ,139,14,17,117,219,229,0,0,1,219,8,211,18,0,0,127,0,0,0,0,0,0,0,0,24,251,86,5 + ,0,65,255,0,52,255,32,0,0,80,232,0,22,255,41,0,0,0,0,0,25,255,32,0,0,81,255,0 + ,22,255,21,0,0,0,0,0,0,0,52,255,4,0,0,0,25,255,34,0,0,81,255,0,52,255,4,0,52, + 255,4,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,52,255,8,84,237,29,0,0,0,51, + 255,5,0,0,0,255,4,52,255,4,52,255,0,56,255,4,0,52,255,4,0,27,255,32,0,0,81, + 234,0,52,255,32,0,0,80,233,0,26,255,32,0,0,81,255,0,0,52,255,4,0,0,0,0,0,0,0, + 0,4,126,237,0,0,0,51,255,4,0,0,0,48,255,8,0,66,255,4,0,0,0,199,94,173,122,0,0 + ,2,239,110,116,189,116,166,0,0,0,166,166,222,90,0,0,0,0,166,128,162,131,0,0,0 + ,13,216,90,0,0,0,0,0,0,3,137,210,0,0,0,0,0,0,52,255,4,0,0,0,0,14,244,89,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,154,117,188,0,0,0,127,0,0,0,0,0,0,0,0,33,255,68,0,26,189 + ,255,0,52,255,160,8,17,195,143,0,0,177,185,23,0,50,42,0,0,194,158,7,19,198, + 255,0,0,176,162,17,0,32,76,0,0,0,52,255,4,0,0,0,0,191,164,10,17,195,255,0,52, + 255,4,0,52,255,4,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,52,255,4,0,156,194 + ,0,0,0,24,254,67,0,0,0,255,4,52,255,4,52,255,0,56,255,4,0,52,255,4,0,0,200, + 158,7,19,198,151,0,52,255,160,8,17,195,146,0,0,194,158,7,19,198,255,0,0,52, + 255,4,0,0,0,0,0,31,72,8,2,124,230,0,0,0,30,255,51,0,0,0,15,251,62,0,147,255,4 + ,0,0,0,108,195,246,32,0,0,0,182,228,42,120,228,106,0,0,103,217,11,55,238,39,0 + ,0,0,70,222,242,36,0,0,0,172,148,0,0,0,0,0,0,0,0,57,254,1,0,0,0,0,0,52,255,4, + 0,0,0,0,49,255,8,0,0,0,0,0,0,0,0,0,0,0,0,0,78,244,107,0,0,0,127,0,0,0,0,0,0,0 + ,0,0,114,231,243,204,108,255,0,52,255,120,232,240,159,9,0,0,14,153,234,244, + 206,41,0,0,28,184,244,223,132,255,0,0,14,155,234,244,218,111,0,0,0,52,255,4,0 + ,0,0,0,27,184,245,221,123,255,0,52,255,4,0,52,255,4,0,0,118,244,246,255,244, + 244,0,0,0,0,52,255,4,0,0,0,52,255,4,0,11,217,0,0,0,0,121,240,244,114,0,255,4, + 52,255,4,52,255,0,56,255,4,0,52,255,4,0,0,31,184,243,238,160,12,0,52,255,120, + 232,241,160,10,0,0,28,185,244,223,130,255,0,0,52,255,4,0,0,0,0,0,35,199,242, + 246,204,61,0,0,0,0,141,236,229,142,0,0,120,234,191,137,255,4,0,0,0,21,251,197 + ,0,0,0,0,122,224,0,45,255,46,0,48,241,50,0,0,118,210,0,0,0,2,227,198,0,0,0,0, + 255,246,244,244,244,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,52,255,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,10,245,27,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,72,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,254,1,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52 + ,255,4,0,0,0,0,0,0,0,0,0,0,52,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 199,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,255,5,0,0,0,0,0,52,255,4,0,0,0,0,53, + 255,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,53,55,2,15,182,162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,121,215,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,52,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,64,244,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,255,56,0,0,0,0,0,52,255,4,0,0 + ,0,0,106,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,75,220,246,237,162,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 194,246,227,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,52,255,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,203,237,92,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,133,229,206, + 0,0,0,0,52,255,4,0,0,11,240,221,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127 + ,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,187,58,108,143,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,102,10,58,54,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,97,59,0,0,0,0,0,0,0,0,0,0,0,0,0,33,222,208,8,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,194,183,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,48,240,52,240,3,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,58,199,211,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,184,143,119,77,39,156,0, + 0,0,73,164,22,196,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42, + 179,3,188,30,0,0,0,0,0,0,0,0,0,0,127,0,4,134,230,245,210,44,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,57,219,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52, + 255,4,0,0,0,0,0,52,255,4,0,0,0,0,4,195,31,94,137,0,0,109,231,221,73,0,0,0,0,0 + ,47,189,243,241,204,73,0,0,0,0,0,0,0,0,0,0,26,175,241,247,255,244,0,0,0,0,0,0 + ,0,0,0,0,244,244,244,244,249,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,111, + 129,0,0,0,0,0,0,52,255,4,0,0,0,0,111,178,0,111,129,0,0,52,255,4,52,255,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,224,40,191,0,0,0,196,0, + 196,159,147,211,0,0,0,0,125,231,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,143,189,126,0,0,0,171,161,0,0,1,208,134,0,127,0,137,197,27,0,51 + ,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,218,103,1,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,254,51,101 + ,235,0,0,0,0,8,233,119,7,3,56,63,0,0,0,0,0,0,0,0,0,0,181,177,20,52,255,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,1,192,148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,206, + 69,0,0,0,0,0,0,62,241,1,0,0,0,0,206,94,0,206,69,0,0,62,241,1,66,241,1,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,174,39,188,126,0,0,0,196,0,196 + ,55,118,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,15,125,8,0,0,0,29,241,39,0,85,240,17,0,127,8,244,57,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,249,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,118, + 244,246,255,244,244,72,0,118,244,246,255,244,244,72,0,0,0,0,0,0,0,0,0,254,50, + 100,234,1,57,97,0,46,255,15,0,0,0,0,0,0,0,0,0,31,0,0,0,10,252,51,0,52,255,4,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,101,223,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35, + 255,14,0,0,0,0,0,0,118,157,0,0,0,0,35,255,18,35,255,14,0,0,120,157,0,143,157, + 0,0,0,0,84,234,231,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 196,0,196,0,0,196,0,0,0,109,226,245,229,114,0,0,0,0,30,0,0,0,0,0,103,239,220, + 122,231,236,0,0,0,0,0,0,0,0,0,0,209,244,244,246,255,0,0,0,120,167,2,213,127,0 + ,0,127,240,255,241,240,236,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,74, + 210,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0 + ,0,0,0,0,0,0,0,0,0,111,234,255,210,148,92,14,0,10,232,176,72,17,0,0,0,0,0,0, + 55,219,0,0,0,40,255,14,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,25,238,68,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,178,63,0,0,0,0,52,255,4, + 52,255,4,0,0,181,63,0,225,63,0,0,0,0,234,255,255,232,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,255,62,0,20,57,0,0,0,0,218, + 54,0,0,0,5,243,62,113,255,57,106,0,0,0,0,0,0,0,0,0,0,0,0,0,149,171,0,0,0,6, + 214,135,237,14,0,0,127,51,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 22,240,247,250,240,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0 + ,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,129,149,89,13,0,0,0,0,0,33,152,222,253,188, + 37,0,0,0,85,217,46,0,0,0,49,255,6,0,52,255,240,0,0,0,0,0,0,0,0,0,0,0,0,173, + 156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,234,255,255,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,252,96,11,0,0,0,0,0,0,46,217,85, + 0,0,39,255,11,62,255,6,54,0,0,0,0,0,0,0,0,0,0,0,0,90,216,13,0,0,0,0,68,255, + 121,0,0,0,127,240,255,240,240,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 156,126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4 + ,0,0,0,0,0,0,0,0,0,0,0,113,231,221,73,73,223,225,0,0,0,0,0,27,170,207,0,0,0, + 229,102,0,0,0,0,40,255,14,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,80,228,15,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,84,235,233,79,0,0,244,244,244,244,244,244,244,0,244,244, + 244,244,244,244,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,84,186,239,208,75,0 + ,0,0,0,0,103,229,0,0,50,255,5,53,255,240,241,0,3,0,0,0,0,0,0,0,0,0,43,233,43, + 0,0,0,0,0,0,252,60,0,0,0,127,9,247,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,200,85,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,116, + 240,243,255,240,240,71,0,0,0,0,0,0,0,0,0,254,51,102,235,229,51,101,0,0,0,0,0, + 0,61,253,0,0,0,29,206,115,0,0,0,10,252,51,0,52,255,4,0,0,0,0,0,0,0,0,0,0,14, + 228,75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,126,237,0,0,0,0,116,206,29,0,0 + ,39,255,11,60,255,8,0,0,0,0,0,0,0,0,0,0,0,13,216,90,0,0,0,0,0,0,0,252,60,0,0, + 0,127,0,146,201,26,0,50,39,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,1,243,45, + 0,0,0,0,52,255,4,52,255,4,0,44,220,3,44,220,3,44,0,3,0,52,255,4,0,0,0,0,0,52, + 255,4,0,0,0,0,0,0,0,0,0,0,0,254,47,99,235,230,47,97,0,15,135,41,5,30,171,202, + 0,0,0,0,12,180,0,0,0,0,181,177,19,52,255,4,0,0,0,0,0,0,0,0,0,0,151,163,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,72,8,2,124,230,0,0,0,0,179,12,0,0,0,6,244,62, + 114,255,80,0,0,1,0,0,0,0,0,0,0,0,172,148,0,0,0,0,0,0,0,0,252,60,0,0,0,127,0,6 + ,140,231,245,213,44,0,0,0,0,0,0,0,0,0,0,0,62,241,1,0,0,0,0,0,33,253,7,0,0,0,0 + ,62,241,1,66,241,1,0,52,255,4,52,255,4,52,0,4,0,52,255,4,0,0,0,0,0,52,255,4,0 + ,0,0,0,0,0,0,0,0,0,0,116,239,229,79,79,231,233,0,9,166,229,252,240,177,33,0,0 + ,0,0,0,3,0,0,0,0,26,177,242,247,255,244,0,0,0,0,0,0,0,0,0,0,254,247,244,244, + 244,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,199,242,246,204,61,0,0,0,0,2,0,0,0,0,0, + 105,240,221,111,222,244,0,1,0,0,0,0,0,0,0,0,255,246,244,244,244,0,0,0,0,0,252 + ,60,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,157,0,0,0,0,0,0,85,212, + 0,0,0,0,0,120,157,0,143,157,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255 + ,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,181,63,0,0,0,0,30,11,195,131, + 0,0,0,0,0,181,63,0,225,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,227,245,177,12,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127, + 127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0 + ,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127 + ,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,58,98,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, + 8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,221,50,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,185,255,4,0,0,0,0,106,186,255,4,0,0 + ,0,0,0,144,235,229,126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0, + 0,0,0,0,49,244,3,0,0,0,0,0,0,0,52,255,4,0,0,0,0,86,224,245,206,0,0,0,0,0,0,0, + 0,0,215,116,0,0,0,164,172,0,0,0,0,52,255,4,0,0,0,110,227,245,223,102,0,0,0,49 + ,244,53,244,3,0,0,0,0,0,0,0,0,0,0,0,0,122,237,237,102,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,244,244,244,175,0,0,0,0,116,239,227,77,0,0,0 + ,0,0,0,0,0,0,0,0,0,116,235,233,108,0,0,0,0,165,239,235,132,0,0,0,0,0,173,88,0 + ,0,0,0,0,0,0,0,0,0,0,0,40,184,245,255,246,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,101,185,255,4,0,0,0,0,77,219,247,201,45,0,0,0,0,0,0,0,0,0,0,52,255,4,0 + ,0,0,0,0,52,255,4,0,0,0,0,0,17,0,101,238,0,0,0,0,0,49,244,3,0,0,0,0,0,0,0,0,0 + ,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,11,245,105,1, + 43,0,0,0,0,0,0,0,0,0,62,241,25,0,61,236,23,0,0,0,0,52,255,4,0,0,33,255,60,0, + 26,51,0,0,0,0,0,0,0,0,0,0,0,53,181,236,230,161,31,0,0,0,33,1,102,238,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,181,236,230,161,31,0,0,0,0,0,0,0,0,0,0,30, + 254,51,99,236,0,0,0,0,0,0,0,0,0,0,0,0,42,3,96,248,0,0,0,0,15,2,107,236,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,226,255,255,255,56,255,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,14,244,93,2,142,209,0,0,0,0,0,0,0,0,0,0,52, + 255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,222,242,72,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,161,243,255,236,0,0,0,47, + 255,11,0,0,0,0,82,25,0,0,44,64,0,0,155,165,3,210,93,0,0,0,0,0,52,255,4,0,0,15 + ,230,104,0,0,0,0,0,0,0,0,0,0,0,0,0,67,255,255,253,224,140,233,0,0,3,160,237, + 243,255,3,0,0,0,0,31,0,0,31,0,0,0,0,0,0,0,0,0,67,255,255,251,251,255,233,0,0, + 0,0,0,0,0,0,0,0,30,254,50,100,234,0,0,0,0,0,52,255,4,0,0,0,0,0,0,113,173,0,0, + 0,0,0,244,239,67,0,0,0,0,0,0,0,0,0,0,52,255,4,0,52,255,4,0,45,255,255,255,255 + ,56,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,47,255,12,0,61 + ,253,0,0,30,0,0,30,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,108,224, + 0,0,0,0,0,44,255,3,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0 + ,0,0,0,174,182,65,255,13,0,0,0,52,255,4,0,0,0,0,79,222,204,189,221,47,0,123, + 185,244,166,235,176,90,0,0,0,0,52,255,4,0,0,0,100,237,188,46,0,0,0,0,0,0,0,0, + 0,0,0,222,255,110,2,21,6,156,0,0,42,255,40,100,255,4,0,0,0,55,219,0,55,218,0, + 0,0,0,0,0,0,0,0,222,161,255,4,86,247,157,0,0,0,0,0,0,0,0,0,0,0,114,233,220,71 + ,0,0,0,0,0,52,255,4,0,0,0,0,0,65,191,12,0,0,0,0,0,0,107,224,0,0,0,0,0,0,0,0,0 + ,0,52,255,4,0,52,255,4,0,19,250,255,255,255,56,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,52,255,4,0,0,0,12,243,94,4,144,206,0,0,218,54,0,219,54,0,0,81, + 176,212,160,0,28,70,0,81,176,212,168,31,8,78,0,0,35,1,114,240,0,0,0,0,0,63, + 242,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,22,255, + 48,52,255,4,0,0,172,243,255,240,240,37,0,0,17,230,49,97,201,0,0,0,0,101,255, + 50,0,0,0,0,0,0,52,255,4,0,0,21,249,20,108,240,103,0,0,0,0,0,0,0,0,0,0,255,255 + ,14,0,0,0,67,0,0,5,182,234,147,248,3,0,0,85,219,47,85,212,43,0,186,244,244, + 244,244,245,252,0,255,71,255,244,232,84,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,240,240,243,255,240,240,0,0,0,56,182,13,0,0,0,0,0,42,1,116,239,0,0,0,0,0,0, + 0,0,0,0,52,255,4,0,52,255,4,0,0,105,248,255,255,56,255,0,0,0,44,220,3,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,81,176,212,168,49,0,0,0,72,213,242,195,40,0,0,44,213,85,48 + ,220,85,0,0,2,56,132,204,195,104,0,0,0,12,86,169,231,170,0,0,180,240,219,87, + 42,91,0,0,15,210,132,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,52,255,4 + ,0,0,0,0,48,255,11,52,255,4,0,0,0,52,255,4,0,0,0,0,16,229,53,101,198,0,0,168, + 240,243,255,240,240,123,0,0,0,0,0,0,0,0,0,30,254,67,0,93,244,0,0,0,0,0,0,0,0, + 0,0,255,222,111,4,17,5,67,0,0,0,0,0,0,0,0,0,0,229,109,0,229,89,0,0,0,0,0,0,0, + 52,255,0,255,71,255,9,178,76,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52, + 255,4,0,0,0,0,173,242,240,240,11,0,0,0,200,241,217,82,0,0,0,0,0,0,0,0,0,0,52, + 255,4,0,52,255,4,0,0,0,18,107,255,56,255,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,229,0,109,229,0,150,216,167,92,18,0,0 + ,0,92,177,230,162,79,8,0,0,21,98,143,151,148,110,60,0,0,186,168,2,0,0,0,0,0,0 + ,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,21,255,43,52,255,4,0,0, + 0,52,255,4,0,0,0,0,76,223,204,189,222,49,0,0,0,52,255,4,0,0,0,0,0,0,52,255,4, + 0,0,0,117,241,119,83,210,0,0,0,0,0,0,0,0,0,0,224,153,197,240,202,13,157,0,0,3 + ,240,240,240,240,11,0,0,29,207,117,29,205,112,0,0,0,0,0,0,50,248,0,224,156, + 228,3,22,188,166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,11,0,62,255,4,0,0,0,0,52,255, + 56,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,240,240,240, + 172,0,0,113,205,29,118,207,29,0,49,4,0,0,146,255,4,0,130,71,5,87,225,232,129, + 0,21,53,7,0,2,174,255,0,40,255,20,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0 + ,0,0,0,52,255,4,0,0,0,0,0,175,172,59,255,8,0,0,0,52,255,4,0,0,0,0,85,25,0,0, + 46,62,0,0,0,52,255,4,0,0,0,0,0,0,52,255,4,0,0,0,0,43,182,246,51,0,0,0,0,0,0,0 + ,0,0,0,68,240,97,7,14,129,232,0,0,0,0,0,0,0,0,0,0,0,12,180,0,12,180,0,0,0,0,0 + ,0,0,0,0,68,240,97,7,14,129,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,99,3,157,255,18,0 + ,0,0,0,52,255,56,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,179,12,0,179,12,0,0,0,0,0,44,141,255,4,0,0,0,0,28,5,88,239,0,0,0, + 0,0,126,102,255,0,23,252,95,8,66,99,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0 + ,0,52,255,4,0,0,0,0,0,13,156,235,255,231,0,0,244,246,255,244,244,244,0,0,0,0, + 0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,127,213,0,0,0,0,0,0,0 + ,0,0,0,0,53,184,236,232,164,31,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,3,0,0,0,0,0,0,0, + 0,0,0,53,184,236,232,164,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,244,244,244, + 244,244,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,163,243, + 148,208,191,0,0,0,0,52,255,56,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,136,53,255,4,0,0,0,0,0,9,168,67, + 0,0,0,0,84,94,52,255,0,0,101,231,249,202,68,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,52,255,4,0,0,1,72,10,3,120,233,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,52,255,56,255,0,0,0,0,0,0,0,0,0,0,0,0 + ,33,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,243, + 255,176,0,0,0,0,28,162,38,0,0,0,0,0,174,240,243,255,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,2,188,234,241,201,61,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,23,116,25, + 116,0,0,0,0,0,0,0,0,0,0,0,0,2,214,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,143,245,244,244,0,0,0,0,0,0,52,255,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,116,199,178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127 + ,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,0,0,51,90,0,0,0, + 0,0,0,0,6,119,17,0,0,0,0,4,117,84,0,0,0,0,2,196,190,20,191,0,0,0,0,0,0,0,0,0, + 0,0,0,145,237,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,99,44,0,0,0,0,0,0 + ,0,48,95,0,0,0,0,0,41,128,38,0,0,0,0,0,0,0,0,0,0,0,0,0,97,35,0,0,0,0,0,0,0,57 + ,85,0,0,0,0,0,46,127,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,217,181,17 + ,203,0,0,0,0,74,213,6,0,0,0,0,0,0,27,229,40,0,0,0,0,29,222,209,8,0,0,0,2,195, + 200,27,193,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,212,8, + 0,0,0,0,0,0,29,234,61,0,0,0,0,42,226,218,16,0,0,0,0,0,0,0,0,0,0,0,0,0,143,135 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,3,172,83,0,0,0,0,0,0,158,105,0 + ,0,0,0,0,154,91,157,84,0,0,0,34,144,63,189,101,0,0,0,48,240,52,240,3,0,0,0,32 + ,255,96,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,201,20,0,0,0,0,0,25, + 203,35,0,0,0,0,24,188,62,188,22,0,0,0,48,240,52,240,3,0,0,0,0,42,195,12,0,0,0 + ,0,0,29,198,25,0,0,0,0,22,184,66,185,14,0,0,0,48,240,52,240,3,0,0,0,0,0,0,0,0 + ,0,0,0,74,110,77,192,109,0,0,0,0,0,139,130,0,0,0,0,0,0,177,92,0,0,0,0,1,183, + 63,107,141,0,0,0,37,141,60,187,123,0,0,0,48,240,3,48,240,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,151,143,0,0,0,0,0,1,189,104,0,0,0,0,8,200,53,93,169,0,0 + ,0,48,240,3,48,240,3,0,0,0,42,192,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,20,246,100,217,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,20,252,200, + 0,0,0,0,0,20,252,200,0,0,0,0,0,20,252,200,0,0,0,0,0,20,252,200,0,0,0,0,0,80, + 255,32,0,0,0,0,0,62,238,30,0,0,0,0,0,196,247,255,244,244,0,0,0,96,213,244,234 + ,137,0,52,255,244,244,244,244,68,0,52,255,244,244,244,244,68,0,52,255,244,244 + ,244,244,68,0,52,255,244,244,244,236,0,0,0,244,246,255,244,244,0,0,0,244,246, + 255,244,244,0,0,0,244,246,255,244,244,0,0,0,244,246,255,244,244,0,0,52,255, + 244,239,190,68,0,0,52,255,166,0,0,52,255,0,0,15,168,241,236,141,2,0,0,15,168, + 241,236,141,2,0,0,15,168,241,236,141,2,0,0,15,168,241,236,141,2,0,0,15,168, + 241,236,141,2,0,0,0,0,0,0,0,0,0,0,13,166,240,239,148,152,0,52,255,4,0,0,52, + 255,0,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0,220, + 112,0,0,0,161,179,0,52,255,4,0,0,0,0,0,0,100,226,247,212,58,0,0,127,0,0,98, + 207,251,26,0,0,0,0,98,207,251,26,0,0,0,0,98,207,251,26,0,0,0,0,98,207,251,26, + 0,0,0,0,160,212,112,0,0,0,0,0,91,210,42,0,0,0,0,17,242,58,255,4,0,0,0,100,223 + ,50,0,22,89,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255 + ,4,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52, + 255,4,0,0,0,52,255,4,7,81,238,66,0,52,255,242,30,0,52,255,0,0,160,175,10,24, + 213,112,0,0,160,175,10,24,213,112,0,0,160,175,10,24,213,112,0,0,160,175,10,24 + ,213,112,0,0,160,175,10,24,213,112,0,0,0,0,0,0,0,0,0,0,158,169,7,42,243,176,0 + ,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0,52,255,4,0 + ,0,52,255,0,74,238,18,0,52,245,33,0,52,255,4,0,0,0,0,0,20,251,87,1,120,216,0, + 0,127,0,0,179,121,200,105,0,0,0,0,179,121,200,105,0,0,0,0,179,121,200,105,0,0 + ,0,0,179,121,200,105,0,0,0,3,236,97,192,0,0,0,0,0,185,107,136,0,0,0,0,86,189, + 52,255,4,0,0,0,227,84,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255, + 4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52, + 255,4,0,0,0,0,0,52,255,4,0,0,0,52,255,4,0,0,125,186,0,52,255,150,143,0,52,255 + ,0,6,246,54,0,0,105,204,0,6,246,54,0,0,105,204,0,6,246,54,0,0,105,204,0,6,246 + ,54,0,0,105,204,0,6,246,54,0,0,105,204,0,0,123,22,0,0,66,81,0,5,246,57,0,52, + 245,208,0,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0, + 52,255,4,0,0,52,255,0,0,176,146,0,194,127,0,0,52,255,240,240,233,177,38,0,50, + 255,8,69,180,160,0,0,127,0,12,248,51,130,186,0,0,0,12,248,51,130,186,0,0,0,12 + ,248,51,130,186,0,0,0,12,248,51,130,186,0,0,0,64,222,16,250,19,0,0,0,25,230, + 26,227,2,0,0,0,159,125,52,255,4,0,0,31,255,21,0,0,0,0,0,52,255,4,0,0,0,0,0,52 + ,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0 + ,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,52,255,4,0,0,69,240,0, + 52,255,37,239,16,52,255,0,38,255,15,0,0,64,244,0,38,255,15,0,0,64,244,0,38, + 255,15,0,0,64,244,0,38,255,15,0,0,64,244,0,38,255,15,0,0,64,244,0,0,130,214, + 25,73,235,64,0,38,255,20,12,210,108,246,0,52,255,4,0,0,52,255,0,52,255,4,0,0, + 52,255,0,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0,0,31,241,124,221,8,0,0, + 52,255,4,0,18,164,208,0,52,255,30,251,36,0,0,0,127,0,86,235,1,59,250,16,0,0, + 86,235,1,59,250,16,0,0,86,235,1,59,250,16,0,0,86,235,1,59,250,16,0,0,144,164, + 0,213,96,0,0,0,117,182,0,230,68,0,0,1,231,61,52,255,240,240,0,48,255,6,0,0,0, + 0,0,52,255,240,240,240,240,22,0,52,255,240,240,240,240,22,0,52,255,240,240, + 240,240,22,0,52,255,240,240,240,187,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0 + ,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,239,255,240,198,0,55,255,0,52,255,4, + 169,120,52,255,0,49,255,5,0,0,54,255,0,49,255,5,0,0,54,255,0,49,255,5,0,0,54, + 255,0,49,255,5,0,0,54,255,0,49,255,5,0,0,54,255,0,0,0,124,225,235,60,0,0,49, + 255,6,160,101,53,255,0,52,255,4,0,0,52,255,0,52,255,4,0,0,52,255,0,52,255,4,0 + ,0,52,255,0,52,255,4,0,0,52,255,0,0,0,124,255,75,0,0,0,52,255,4,0,0,59,253,0, + 52,255,26,245,109,2,0,0,127,0,167,167,0,4,240,92,0,0,167,167,0,4,240,92,0,0, + 167,167,0,4,240,92,0,0,167,167,0,4,240,92,0,0,223,105,0,154,176,0,0,0,210,130 + ,0,179,162,0,0,49,246,6,52,255,4,0,0,31,255,23,0,0,0,0,0,52,255,4,0,0,0,0,0, + 52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,52,255,4,0,0,0,0 + ,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,52,255,4,0,0,69,240,0 + ,52,255,4,52,230,58,255,0,38,255,15,0,0,64,244,0,38,255,15,0,0,64,244,0,38, + 255,15,0,0,64,244,0,38,255,15,0,0,64,244,0,38,255,15,0,0,64,244,0,0,0,80,241, + 224,31,0,0,40,255,92,164,0,63,245,0,51,255,4,0,0,52,255,0,51,255,4,0,0,52,255 + ,0,51,255,4,0,0,52,255,0,51,255,4,0,0,52,255,0,0,0,52,255,4,0,0,0,52,255,4,0, + 17,161,208,0,52,255,4,47,187,209,46,0,127,7,241,250,248,248,253,173,0,7,241, + 250,248,248,253,173,0,7,241,250,248,248,253,173,0,7,241,250,248,248,253,173,0 + ,48,255,249,248,250,246,10,0,49,255,249,248,250,244,11,0,122,251,240,243,255, + 4,0,0,0,228,88,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0 + ,0,0,52,255,4,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0, + 0,0,0,0,52,255,4,0,0,0,52,255,4,0,0,126,186,0,52,255,4,0,192,149,255,0,6,247, + 54,0,0,104,204,0,6,247,54,0,0,104,204,0,6,247,54,0,0,104,204,0,6,247,54,0,0, + 104,204,0,6,247,54,0,0,104,204,0,0,87,233,51,113,224,34,0,10,253,203,12,0,100 + ,203,0,40,255,9,0,0,57,248,0,40,255,9,0,0,57,248,0,40,255,9,0,0,57,248,0,40, + 255,8,0,0,56,248,0,0,0,52,255,4,0,0,0,52,255,240,240,234,178,38,0,52,255,4,0, + 0,116,220,0,127,74,249,16,0,0,87,245,0,74,249,16,0,0,87,245,0,74,249,16,0,0, + 87,245,0,74,249,16,0,0,87,245,0,128,211,0,0,15,248,80,0,143,187,0,0,5,234,94, + 0,195,109,0,52,255,4,0,0,0,102,228,62,5,34,99,0,52,255,4,0,0,0,0,0,52,255,4,0 + ,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255, + 4,0,0,0,0,8,58,255,11,8,0,0,0,0,52,255,4,0,0,0,52,255,4,7,82,239,67,0,52,255, + 4,0,75,246,255,0,0,163,173,9,23,212,114,0,0,163,173,9,23,212,114,0,0,163,173, + 9,23,212,114,0,0,163,173,9,23,212,114,0,0,163,173,9,23,212,114,0,0,166,49,0,0 + ,108,107,0,13,237,190,15,18,206,111,0,5,232,117,10,19,158,190,0,5,232,117,10, + 19,158,190,0,5,232,117,10,19,158,190,0,5,232,107,3,9,151,190,0,0,0,52,255,4,0 + ,0,0,52,255,4,0,0,0,0,0,52,255,34,8,2,118,240,0,127,155,179,0,0,0,11,245,0, + 155,179,0,0,0,11,245,0,155,179,0,0,0,11,245,0,155,179,0,0,0,11,245,0,208,126, + 0,0,0,176,160,0,232,94,0,0,0,144,188,0,251,31,0,52,255,244,244,0,0,0,99,214, + 255,240,135,0,52,255,244,244,244,244,99,0,52,255,244,244,244,244,99,0,52,255, + 244,244,244,244,99,0,52,255,244,244,244,244,22,0,0,244,246,255,244,244,0,0,0, + 244,246,255,244,244,0,0,0,255,255,255,255,255,0,0,0,244,246,255,244,244,0,0, + 52,255,244,240,191,69,0,0,52,255,4,0,1,213,255,0,0,16,171,241,237,143,3,0,0, + 16,171,241,237,143,3,0,0,16,171,241,237,143,3,0,0,16,171,241,237,143,3,0,0,16 + ,171,241,237,143,3,0,0,0,0,0,0,0,0,0,157,99,185,245,234,140,2,0,0,51,197,249, + 244,177,28,0,0,51,197,249,244,177,28,0,0,51,197,249,244,177,28,0,0,51,197,244 + ,241,177,28,0,0,0,52,255,4,0,0,0,52,255,4,0,0,0,0,0,52,255,116,240,246,211,74 + ,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,107,120,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,69,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,233,241,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,127,127,127,127,127,0,127,127,127,127,127 + ,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127 + ,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104,226,228,110,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,8,195,125,0,0,0,0,0,0,0,0,98,212,15,0,0 + ,0,2,197,213,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,241,45,96,248,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,157,139,0,0,0,0,0,0,0,0,154,142,0,0,0,0,10, + 199,192,5,0,0,0,0,0,0,0,0,0,0,0,0,111,190,2,0,0,0,0,0,0,0,50,225,29,0,0,0,0, + 130,241,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,187,114,0 + ,0,0,0,0,0,0,1,161,149,1,0,0,0,24,211,193,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,217,9,0,0,0,0,0,0,0,44,223,23,0,0,0,0 + ,88,244,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,91,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,0,0,18,213,67,0,0,0,0,0,0,46,220,30,0,0,0,0,115,148,123,138,0,0,0, + 14,196,237,203,189,27,0,0,0,240,3,49,244,3,0,0,0,105,226,228,110,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,155,105,0,0,0,0,0,0,121,140,0,0,0,0,0,158,74,90 + ,145,0,0,0,0,240,3,49,244,3,0,0,0,0,158,122,0,0,0,0,0,0,12,210,56,0,0,0,0,38, + 200,77,175,0,0,0,49,244,53,244,3,0,0,0,3,138,202,114,121,12,0,0,86,232,214, + 194,37,0,0,0,0,7,172,97,0,0,0,0,0,0,144,133,0,0,0,0,6,185,54,92,153,0,0,0,25, + 206,234,199,174,3,0,0,49,244,3,49,244,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,123,138,0,0,0,0,0,0,2,195,59,0,0,0,0,11,204,78,171,0,0,0,0,49,244,53,244,3,0 + ,0,0,0,0,51,205,26,0,0,52,255,4,0,0,0,0,0,0,49,244,53,244,3,0,0,127,0,0,0,32, + 105,0,0,0,0,0,0,91,46,0,0,0,0,2,113,7,1,111,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,117,7,0,0,0,0,0,57,72,0,0,0,0,0 + ,74,38,0,93,20,0,0,0,0,0,0,0,0,0,0,51,110,93,212,36,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,1,109,6,0,0,0,0,0,35,80,0,0,0,0,0,49,64,0, + 96,15,0,0,0,0,0,0,0,0,0,0,0,0,0,103,25,0,0,0,52,255,4,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,127,0,103,213,244,239,180,36,0,0,103,213,244,240,180,36,0,0,103,213,244, + 239,180,36,0,0,103,213,244,239,180,36,0,0,103,213,244,239,180,36,0,0,103,213, + 244,239,180,36,0,0,132,239,226,131,234,236,0,0,12,151,233,244,202,40,0,0,13, + 156,236,241,165,12,0,0,13,156,236,241,165,12,0,0,13,156,236,241,165,12,0,0,13 + ,156,235,241,165,12,0,0,0,244,246,255,4,0,0,0,0,244,246,255,4,0,0,0,0,244,246 + ,255,4,0,0,0,148,244,255,4,0,0,0,0,25,178,243,251,214,9,0,52,255,111,233,235, + 80,0,0,0,29,182,242,237,157,11,0,0,29,182,242,237,157,11,0,0,29,182,242,237, + 157,11,0,0,29,182,242,237,157,11,0,0,29,182,242,237,157,11,0,0,0,0,49,244,3,0 + ,0,0,29,181,242,238,160,192,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255,4,0,52, + 255,4,0,52,255,4,0,52,255,4,0,52,255,4,0,40,250,19,0,0,50,245,0,52,255,121, + 231,241,161,10,0,93,212,0,0,0,221,87,0,127,0,93,52,2,9,162,204,0,0,93,52,2,10 + ,165,204,0,0,93,52,2,9,162,204,0,0,93,52,2,9,162,204,0,0,93,52,2,9,162,204,0, + 0,93,52,2,9,159,204,0,0,48,4,120,255,57,104,0,0,174,188,24,0,53,43,0,0,173, + 187,16,11,178,153,0,0,173,187,16,11,178,153,0,0,173,186,16,11,179,152,0,0,173 + ,177,14,11,179,152,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0 + ,0,0,0,252,4,0,0,0,0,192,167,11,4,181,123,0,52,255,121,2,133,219,0,0,0,198, + 158,8,19,198,149,0,0,198,158,8,19,198,149,0,0,198,158,8,19,198,149,0,0,198, + 158,8,19,198,149,0,0,198,158,8,19,198,149,0,0,0,0,0,0,0,0,0,0,198,161,9,24, + 239,165,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255,4,0, + 52,255,4,0,52,255,4,0,0,200,106,0,0,142,163,0,52,255,163,9,19,198,145,0,11, + 244,36,0,48,244,10,0,127,0,0,0,0,0,61,252,0,0,0,0,0,0,62,252,0,0,0,0,0,0,61, + 252,0,0,0,0,0,0,61,252,0,0,0,0,0,0,61,252,0,0,0,0,0,0,57,252,0,0,0,0,55,255,6 + ,54,0,22,255,41,0,0,0,0,0,21,255,50,0,0,67,236,0,21,255,50,0,0,67,236,0,21, + 255,49,0,0,70,236,0,21,255,37,0,0,70,236,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4, + 0,0,0,0,0,52,255,4,0,0,0,0,0,252,4,0,0,0,25,255,35,0,0,86,217,0,52,255,18,0, + 56,254,1,0,27,255,32,0,0,81,234,0,27,255,32,0,0,81,234,0,27,255,32,0,0,81,234 + ,0,27,255,32,0,0,81,234,0,27,255,32,0,0,81,234,0,0,240,240,240,240,240,240,0, + 27,255,31,2,168,165,235,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255, + 4,0,52,255,4,0,52,255,4,0,52,255,4,0,0,103,199,0,3,230,67,0,52,255,33,0,0,81, + 232,0,0,162,117,0,130,165,0,0,127,0,78,197,237,240,243,255,0,0,71,189,224,224 + ,230,255,0,0,78,197,237,240,243,255,0,0,78,197,237,240,243,255,0,0,78,197,237 + ,240,243,255,0,0,78,197,237,240,243,255,0,0,125,231,244,255,240,241,0,50,255, + 7,0,0,0,0,0,47,255,225,224,224,227,239,0,47,255,225,224,224,227,239,0,47,255, + 240,240,240,241,247,0,47,255,240,240,240,241,247,0,0,0,0,52,255,4,0,0,0,0,0, + 52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,252,4,0,0,0,48,255,7,0,0,56,254,0,52, + 255,4,0,52,255,4,0,48,255,6,0,0,55,254,0,48,255,6,0,0,55,254,0,48,255,6,0,0, + 55,254,0,48,255,6,0,0,55,254,0,48,255,6,0,0,55,254,0,0,0,0,0,0,0,0,0,48,255,7 + ,152,111,54,255,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255,4,0,52,255,4,0,52, + 255,4,0,52,255,4,0,52,255,4,0,0,15,246,36,70,225,1,0,52,255,6,0,0,55,254,0,0, + 68,197,0,212,76,0,0,127,24,251,95,6,0,62,255,0,23,250,82,2,0,65,255,0,24,251, + 86,5,0,65,255,0,24,251,86,5,0,65,255,0,24,251,86,5,0,65,255,0,24,251,86,5,0, + 65,255,0,32,255,57,53,255,8,0,0,22,255,41,0,0,0,0,0,22,255,23,0,0,0,0,0,22, + 255,23,0,0,0,0,0,22,255,21,0,0,0,0,0,22,255,21,0,0,0,0,0,0,0,0,52,255,4,0,0,0 + ,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,252,4,0,0,0,25,255,34,0,0,83,238,0 + ,52,255,4,0,52,255,4,0,27,255,32,0,0,81,234,0,27,255,32,0,0,81,234,0,27,255, + 32,0,0,81,234,0,27,255,32,0,0,81,234,0,27,255,32,0,0,81,234,0,0,0,0,48,240,3, + 0,0,27,255,165,129,0,81,234,0,48,255,8,0,66,255,4,0,48,255,8,0,66,255,4,0,48, + 255,8,0,66,255,4,0,48,255,8,0,66,255,4,0,0,0,166,128,162,131,0,0,52,255,32,0, + 0,80,233,0,0,2,226,62,238,5,0,0,127,33,255,38,0,4,170,255,0,33,255,69,0,26, + 189,255,0,33,255,68,0,26,189,255,0,33,255,68,0,26,189,255,0,33,255,68,0,26, + 189,255,0,33,255,68,0,26,189,255,0,38,255,39,95,255,76,1,0,0,177,185,23,0,50, + 42,0,0,176,165,17,0,32,76,0,0,176,165,17,0,32,76,0,0,176,162,17,0,32,76,0,0, + 176,162,17,0,29,79,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0,0,0,0,52,255,4,0,0 + ,0,0,0,252,4,0,0,0,0,194,163,8,21,202,156,0,52,255,4,0,52,255,4,0,0,200,158,7 + ,19,198,151,0,0,200,158,7,19,198,151,0,0,200,158,7,19,198,151,0,0,200,158,7, + 19,198,151,0,0,200,158,7,19,198,151,0,0,0,0,0,0,0,0,0,0,216,210,7,19,198,151, + 0,15,251,62,0,147,255,4,0,15,251,62,0,147,255,4,0,15,251,62,0,147,255,4,0,15, + 251,62,0,147,255,4,0,0,0,70,222,242,36,0,0,52,255,160,8,17,195,146,0,0,0,137, + 215,157,0,0,0,127,0,114,219,196,189,127,255,0,0,114,231,243,204,107,255,0,0, + 114,231,243,204,108,255,0,0,114,231,243,204,108,255,0,0,114,231,243,204,108, + 255,0,0,113,230,243,205,106,255,0,0,154,245,215,95,224,242,0,0,14,153,237,255 + ,207,42,0,0,14,155,234,244,218,111,0,0,14,155,234,244,218,111,0,0,14,155,234, + 244,218,111,0,0,14,153,233,244,220,120,0,0,118,244,246,255,244,244,0,0,108, + 224,230,255,224,224,0,0,108,224,230,255,224,224,0,22,244,244,255,244,244,34,0 + ,0,27,180,242,238,161,13,0,52,255,4,0,52,255,4,0,0,31,184,243,238,160,12,0,0, + 31,184,243,238,160,12,0,0,31,184,243,238,160,12,0,0,31,184,243,238,160,12,0,0 + ,31,184,243,238,160,12,0,0,0,0,0,0,0,0,0,95,164,178,242,238,160,12,0,0,120, + 234,191,137,255,4,0,0,120,234,191,137,255,4,0,0,120,234,191,137,255,4,0,0,120 + ,234,191,137,255,4,0,0,0,2,227,198,0,0,0,52,255,120,232,241,160,10,0,0,0,43, + 255,72,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,187,14,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,40,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,199,105,0,0,0,52,255,4,0,0,0,0,0,0,0,18,232,4,0, + 0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,1,167,67,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,64,244,16,0,0,0,52,255,4,0,0,0,0,0,0,0,132,148,0,0,0,0,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,242,213,19,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,203,237,92,0,0,0,0,52,255,4,0,0,0,0,0,11,243,209,25,0,0,0,0,0,127, + 127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127 + ,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127, + 0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127 + ,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0, + 127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127, + 127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127 + ,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127, + 127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127 + ,127,127,127,127,127,0,127,127,127,127,127,127,127,0,127,127,127,127,127,127, + 127,0,127,127,127,127,127,127,127,0 +}; + + +void TwGenerateDefaultFonts() +{ + g_DefaultSmallFont = TwGenerateFont(s_Font0, FONT0_BM_W, FONT0_BM_H); + assert(g_DefaultSmallFont && g_DefaultSmallFont->m_NbCharRead==224); + g_DefaultNormalFont = TwGenerateFont(s_Font1AA, FONT1AA_BM_W, FONT1AA_BM_H); + assert(g_DefaultNormalFont && g_DefaultNormalFont->m_NbCharRead==224); + g_DefaultLargeFont = TwGenerateFont(s_Font2AA, FONT2AA_BM_W, FONT2AA_BM_H); + assert(g_DefaultLargeFont && g_DefaultLargeFont->m_NbCharRead==224); + g_DefaultFixed1Font = TwGenerateFont(s_FontFixed1, FONTFIXED1_BM_W, FONTFIXED1_BM_H); + assert(g_DefaultFixed1Font && g_DefaultFixed1Font->m_NbCharRead==224); +} + +// --------------------------------------------------------------------------- + +void TwDeleteDefaultFonts() +{ + delete g_DefaultSmallFont; + g_DefaultSmallFont = NULL; + delete g_DefaultNormalFont; + g_DefaultNormalFont = NULL; + delete g_DefaultLargeFont; + g_DefaultLargeFont = NULL; + delete g_DefaultFixed1Font; + g_DefaultFixed1Font = NULL; +} + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwFonts.h b/Extras/CDTestFramework/AntTweakBar/src/TwFonts.h new file mode 100644 index 0000000..3be79ed --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwFonts.h @@ -0,0 +1,66 @@ +// --------------------------------------------------------------------------- +// +// @file TwFonts.h +// @brief Bitmaps fonts +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_FONTS_INCLUDED +#define ANT_TW_FONTS_INCLUDED + +//#include + +/* +A source bitmap includes 224 characters starting from ascii char 32 (i.e. space) to ascii char 255: + + !"#$%&'()*+,-./0123456789:;<=>? +@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ +`abcdefghijklmnopqrstuvwxyz{|}~ +€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ + ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ +ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß +àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ + +First column of a source bitmap is a delimiter with color=zero at the end of each line of characters. +Last row of a line of characters is a delimiter with color=zero at the last pixel of each character. + +*/ + + +struct CTexFont +{ + unsigned char * m_TexBytes; + int m_TexWidth; // power of 2 + int m_TexHeight; // power of 2 + float m_CharU0[256]; + float m_CharV0[256]; + float m_CharU1[256]; + float m_CharV1[256]; + int m_CharWidth[256]; + int m_CharHeight; + int m_NbCharRead; + + CTexFont(); + ~CTexFont(); +}; + + +CTexFont *TwGenerateFont(const unsigned char *_Bitmap, int _BmWidth, int _BmHeight); + + +extern CTexFont *g_DefaultSmallFont; +extern CTexFont *g_DefaultNormalFont; +extern CTexFont *g_DefaultLargeFont; +extern CTexFont *g_DefaultFixed1Font; + +void TwGenerateDefaultFonts(); +void TwDeleteDefaultFonts(); + + +#endif // !defined ANT_TW_FONTS_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwGraph.h b/Extras/CDTestFramework/AntTweakBar/src/TwGraph.h new file mode 100644 index 0000000..e9102cd --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwGraph.h @@ -0,0 +1,58 @@ +// --------------------------------------------------------------------------- +// +// @file TwGraph.h +// @brief ITwGraph pure interface +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_GRAPH_INCLUDED +#define ANT_TW_GRAPH_INCLUDED + +#include "TwColors.h" +#include "TwFonts.h" + + +// --------------------------------------------------------------------------- + +#ifdef DrawText // DirectX redefines 'DrawText' !! +# undef DrawText +#endif // DrawText + +class ITwGraph +{ +public: + virtual int Init() = 0; + virtual int Shut() = 0; + virtual void BeginDraw(int _WndWidth, int _WndHeight) = 0; + virtual void EndDraw() = 0; + virtual bool IsDrawing() = 0; + virtual void Restore() = 0; + + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased=false) = 0; + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color, bool _AntiAliased=false) = 0; + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11) = 0; + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color) = 0; + enum Cull { CULL_NONE, CULL_CW, CULL_CCW }; + virtual void DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode) = 0; + + virtual void * NewTextObj() = 0; + virtual void DeleteTextObj(void *_TextObj) = 0; + virtual void BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth) = 0; + virtual void DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor) = 0; + + virtual void ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY) = 0; + virtual void RestoreViewport() = 0; + virtual void SetScissor(int _X0, int _Y0, int _Width, int _Height) = 0; + + virtual ~ITwGraph() {} // required by gcc +}; + +// --------------------------------------------------------------------------- + +#endif // ANT_TW_GRAPH_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwMgr.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwMgr.cpp new file mode 100644 index 0000000..ae422e6 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwMgr.cpp @@ -0,0 +1,6726 @@ +// --------------------------------------------------------------------------- +// +// @file TwMgr.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include +#include "TwMgr.h" +#include "TwBar.h" +#include "TwFonts.h" +#include "TwOpenGL.h" +#include "TwOpenGLCore.h" +#ifdef ANT_WINDOWS +# include "TwDirect3D9.h" +# include "TwDirect3D10.h" +# include "TwDirect3D11.h" +# include "resource.h" +# ifdef _DEBUG +# include +# endif // _DEBUG +#endif // ANT_WINDOWS + +#if !defined(ANT_WINDOWS) +# define _snprintf snprintf +#endif // defined(ANT_WINDOWS) + + +using namespace std; + +CTwMgr *g_TwMgr = NULL; // current TwMgr +bool g_BreakOnError = false; +TwErrorHandler g_ErrorHandler = NULL; +int g_TabLength = 4; +CTwBar * const TW_GLOBAL_BAR = (CTwBar *)(-1); +int g_InitWndWidth = -1; +int g_InitWndHeight = -1; +TwCopyCDStringToClient g_InitCopyCDStringToClient = NULL; +TwCopyStdStringToClient g_InitCopyStdStringToClient = NULL; + +// multi-windows +const int TW_MASTER_WINDOW_ID = 0; +typedef map CTwWndMap; +CTwWndMap g_Wnds; +CTwMgr *g_TwMasterMgr = NULL; + +// error messages +extern const char *g_ErrUnknownAttrib; +extern const char *g_ErrNoValue; +extern const char *g_ErrBadValue; +const char *g_ErrInit = "Already initialized"; +const char *g_ErrShut = "Already shutdown"; +const char *g_ErrNotInit = "Not initialized"; +const char *g_ErrUnknownAPI = "Unsupported graph API"; +const char *g_ErrBadDevice = "Invalid graph device"; +const char *g_ErrBadParam = "Invalid parameter"; +const char *g_ErrExist = "Exists already"; +const char *g_ErrNotFound = "Not found"; +const char *g_ErrNthToDo = "Nothing to do"; +const char *g_ErrBadSize = "Bad size"; +const char *g_ErrIsDrawing = "Asynchronous drawing detected"; +const char *g_ErrIsProcessing="Asynchronous processing detected"; +const char *g_ErrOffset = "Offset larger than StructSize"; +const char *g_ErrDelStruct = "Cannot delete a struct member"; +const char *g_ErrNoBackQuote= "Name cannot include back-quote"; +const char *g_ErrStdString = "Debug/Release std::string mismatch"; +const char *g_ErrCStrParam = "Value count for TW_PARAM_CSTRING must be 1"; +const char *g_ErrOutOfRange = "Index out of range"; +const char *g_ErrHasNoValue = "Has no value"; +const char *g_ErrBadType = "Incompatible type"; +const char *g_ErrDelHelp = "Cannot delete help bar"; +char g_ErrParse[512]; + +void ANT_CALL TwGlobalError(const char *_ErrorMessage); + +#if defined(ANT_UNIX) || defined(ANT_OSX) +#define _stricmp strcasecmp +#define _strdup strdup +#endif + +#ifdef ANT_WINDOWS + bool g_UseCurRsc = true; // use dll resources for rotoslider cursors +#endif + +// --------------------------------------------------------------------------- + +const float FLOAT_EPS = 1.0e-7f; +const float FLOAT_EPS_SQ = 1.0e-14f; +const float FLOAT_PI = 3.14159265358979323846f; +const double DOUBLE_EPS = 1.0e-14; +const double DOUBLE_EPS_SQ = 1.0e-28; +const double DOUBLE_PI = 3.14159265358979323846; + +inline double DegToRad(double degree) { return degree * (DOUBLE_PI/180.0); } +inline double RadToDeg(double radian) { return radian * (180.0/DOUBLE_PI); } + +// --------------------------------------------------------------------------- + +// a static global object to verify that Tweakbar module has been properly terminated (in debug mode only) +#ifdef _DEBUG +static struct CTwVerif +{ + ~CTwVerif() + { + if( g_TwMgr!=NULL ) + g_TwMgr->SetLastError("Tweak bar module has not been terminated properly: call TwTerminate()\n"); + } +} s_Verif; +#endif // _DEBUG + +// --------------------------------------------------------------------------- +// Color ext type +// --------------------------------------------------------------------------- + +void CColorExt::RGB2HLS() +{ + float fH = 0, fL = 0, fS = 0; + ColorRGBToHLSf((float)R/255.0f, (float)G/255.0f, (float)B/255.0f, &fH, &fL, &fS); + H = (int)fH; + if( H>=360 ) + H -= 360; + else if( H<0 ) + H += 360; + L = (int)(255.0f*fL + 0.5f); + if( L<0 ) + L = 0; + else if( L>255 ) + L = 255; + S = (int)(255.0f*fS + 0.5f); + if( S<0 ) + S = 0; + else if( S>255 ) + S = 255; +} + +void CColorExt::HLS2RGB() +{ + float fR = 0, fG = 0, fB = 0; + ColorHLSToRGBf((float)H, (float)L/255.0f, (float)S/255.0f, &fR, &fG, &fB); + R = (int)(255.0f*fR + 0.5f); + if( R<0 ) + R = 0; + else if( R>255 ) + R = 255; + G = (int)(255.0f*fG + 0.5f); + if( G<0 ) + G = 0; + else if( G>255 ) + G = 255; + B = (int)(255.0f*fB + 0.5f); + if( B<0 ) + B = 0; + else if( B>255 ) + B = 255; +} + +void ANT_CALL CColorExt::InitColor32CB(void *_ExtValue, void *_ClientData) +{ + CColorExt *ext = static_cast(_ExtValue); + if( ext ) + { + ext->m_IsColorF = false; + ext->R = 0; + ext->G = 0; + ext->B = 0; + ext->H = 0; + ext->L = 0; + ext->S = 0; + ext->A = 255; + ext->m_HLS = false; + ext->m_HasAlpha = false; + ext->m_CanHaveAlpha = true; + if( g_TwMgr && g_TwMgr->m_GraphAPI==TW_DIRECT3D9 ) // D3D10 now use OGL rgba order! + ext->m_OGL = false; + else + ext->m_OGL = true; + ext->m_PrevConvertedColor = Color32FromARGBi(ext->A, ext->R, ext->G, ext->B); + ext->m_StructProxy = (CTwMgr::CStructProxy *)_ClientData; + } +} + +void ANT_CALL CColorExt::InitColor3FCB(void *_ExtValue, void *_ClientData) +{ + InitColor32CB(_ExtValue, _ClientData); + CColorExt *ext = static_cast(_ExtValue); + if( ext ) + { + ext->m_IsColorF = true; + ext->m_HasAlpha = false; + ext->m_CanHaveAlpha = false; + } +} + +void ANT_CALL CColorExt::InitColor4FCB(void *_ExtValue, void *_ClientData) +{ + InitColor32CB(_ExtValue, _ClientData); + CColorExt *ext = static_cast(_ExtValue); + if( ext ) + { + ext->m_IsColorF = true; + ext->m_HasAlpha = true; + ext->m_CanHaveAlpha = true; + } +} + +void ANT_CALL CColorExt::CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData) +{ + unsigned int *var32 = static_cast(_VarValue); + float *varF = static_cast(_VarValue); + CColorExt *ext = (CColorExt *)(_ExtValue); + CTwMgr::CMemberProxy *mProxy = static_cast(_ClientData); + if( _VarValue && ext ) + { + if( ext->m_HasAlpha && mProxy && mProxy->m_StructProxy && mProxy->m_StructProxy->m_Type==g_TwMgr->m_TypeColor3F ) + ext->m_HasAlpha = false; + + // Synchronize HLS and RGB + if( _ExtMemberIndex>=0 && _ExtMemberIndex<=2 ) + ext->RGB2HLS(); + else if( _ExtMemberIndex>=3 && _ExtMemberIndex<=5 ) + ext->HLS2RGB(); + else if( mProxy && _ExtMemberIndex==7 && mProxy->m_VarParent ) + { + assert( mProxy->m_VarParent->m_Vars.size()==8 ); + if( mProxy->m_VarParent->m_Vars[0]->m_Visible != !ext->m_HLS + || mProxy->m_VarParent->m_Vars[1]->m_Visible != !ext->m_HLS + || mProxy->m_VarParent->m_Vars[2]->m_Visible != !ext->m_HLS + || mProxy->m_VarParent->m_Vars[3]->m_Visible != ext->m_HLS + || mProxy->m_VarParent->m_Vars[4]->m_Visible != ext->m_HLS + || mProxy->m_VarParent->m_Vars[5]->m_Visible != ext->m_HLS ) + { + mProxy->m_VarParent->m_Vars[0]->m_Visible = !ext->m_HLS; + mProxy->m_VarParent->m_Vars[1]->m_Visible = !ext->m_HLS; + mProxy->m_VarParent->m_Vars[2]->m_Visible = !ext->m_HLS; + mProxy->m_VarParent->m_Vars[3]->m_Visible = ext->m_HLS; + mProxy->m_VarParent->m_Vars[4]->m_Visible = ext->m_HLS; + mProxy->m_VarParent->m_Vars[5]->m_Visible = ext->m_HLS; + mProxy->m_Bar->NotUpToDate(); + } + if( mProxy->m_VarParent->m_Vars[6]->m_Visible != ext->m_HasAlpha ) + { + mProxy->m_VarParent->m_Vars[6]->m_Visible = ext->m_HasAlpha; + mProxy->m_Bar->NotUpToDate(); + } + if( static_cast(mProxy->m_VarParent->m_Vars[7])->m_ReadOnly ) + { + static_cast(mProxy->m_VarParent->m_Vars[7])->m_ReadOnly = false; + mProxy->m_Bar->NotUpToDate(); + } + } + // Convert to color32 + color32 col = Color32FromARGBi((ext->m_HasAlpha ? ext->A : 255), ext->R, ext->G, ext->B); + if( ext->m_OGL && !ext->m_IsColorF ) + col = (col&0xff00ff00) | (unsigned char)(col>>16) | (((unsigned char)(col))<<16); + if( ext->m_IsColorF ) + Color32ToARGBf(col, (ext->m_HasAlpha ? varF+3 : NULL), varF+0, varF+1, varF+2); + else + { + if( ext->m_HasAlpha ) + *var32 = col; + else + *var32 = ((*var32)&0xff000000) | (col&0x00ffffff); + } + ext->m_PrevConvertedColor = col; + } +} + +void ANT_CALL CColorExt::CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData) +{ + const unsigned int *var32 = static_cast(_VarValue); + const float *varF = static_cast(_VarValue); + CColorExt *ext = static_cast(_ExtValue); + CTwMgr::CMemberProxy *mProxy = static_cast(_ClientData); + if( _VarValue && ext ) + { + if( ext->m_HasAlpha && mProxy && mProxy->m_StructProxy && mProxy->m_StructProxy->m_Type==g_TwMgr->m_TypeColor3F ) + ext->m_HasAlpha = false; + + if( mProxy && _ExtMemberIndex==7 && mProxy->m_VarParent ) + { + assert( mProxy->m_VarParent->m_Vars.size()==8 ); + if( mProxy->m_VarParent->m_Vars[0]->m_Visible != !ext->m_HLS + || mProxy->m_VarParent->m_Vars[1]->m_Visible != !ext->m_HLS + || mProxy->m_VarParent->m_Vars[2]->m_Visible != !ext->m_HLS + || mProxy->m_VarParent->m_Vars[3]->m_Visible != ext->m_HLS + || mProxy->m_VarParent->m_Vars[4]->m_Visible != ext->m_HLS + || mProxy->m_VarParent->m_Vars[5]->m_Visible != ext->m_HLS ) + { + mProxy->m_VarParent->m_Vars[0]->m_Visible = !ext->m_HLS; + mProxy->m_VarParent->m_Vars[1]->m_Visible = !ext->m_HLS; + mProxy->m_VarParent->m_Vars[2]->m_Visible = !ext->m_HLS; + mProxy->m_VarParent->m_Vars[3]->m_Visible = ext->m_HLS; + mProxy->m_VarParent->m_Vars[4]->m_Visible = ext->m_HLS; + mProxy->m_VarParent->m_Vars[5]->m_Visible = ext->m_HLS; + mProxy->m_Bar->NotUpToDate(); + } + if( mProxy->m_VarParent->m_Vars[6]->m_Visible != ext->m_HasAlpha ) + { + mProxy->m_VarParent->m_Vars[6]->m_Visible = ext->m_HasAlpha; + mProxy->m_Bar->NotUpToDate(); + } + if( static_cast(mProxy->m_VarParent->m_Vars[7])->m_ReadOnly ) + { + static_cast(mProxy->m_VarParent->m_Vars[7])->m_ReadOnly = false; + mProxy->m_Bar->NotUpToDate(); + } + } + color32 col; + if( ext->m_IsColorF ) + col = Color32FromARGBf((ext->m_HasAlpha ? varF[3] : 1), varF[0], varF[1], varF[2]); + else + col = *var32; + if( ext->m_OGL && !ext->m_IsColorF ) + col = (col&0xff00ff00) | (unsigned char)(col>>16) | (((unsigned char)(col))<<16); + Color32ToARGBi(col, (ext->m_HasAlpha ? &ext->A : NULL), &ext->R, &ext->G, &ext->B); + if( (col & 0x00ffffff)!=(ext->m_PrevConvertedColor & 0x00ffffff) ) + ext->RGB2HLS(); + ext->m_PrevConvertedColor = col; + } +} + +void ANT_CALL CColorExt::SummaryCB(char *_SummaryString, size_t /*_SummaryMaxLength*/, const void *_ExtValue, void * /*_ClientData*/) +{ + // copy var + CColorExt *ext = (CColorExt *)(_ExtValue); + if( ext && ext->m_StructProxy && ext->m_StructProxy->m_StructData ) + { + if( ext->m_StructProxy->m_StructGetCallback ) + ext->m_StructProxy->m_StructGetCallback(ext->m_StructProxy->m_StructData, ext->m_StructProxy->m_StructClientData); + //if( *(unsigned int *)(ext->m_StructProxy->m_StructData)!=ext->m_PrevConvertedColor ) + CopyVarToExtCB(ext->m_StructProxy->m_StructData, ext, 99, NULL); + } + + //unsigned int col = 0; + //CopyVar32FromExtCB(&col, _ExtValue, 99, _ClientData); + //_snprintf(_SummaryString, _SummaryMaxLength, "0x%.8X", col); + //(void) _SummaryMaxLength, _ExtValue, _ClientData; + _SummaryString[0] = ' '; // required to force background color for this value + _SummaryString[1] = '\0'; +} + +void CColorExt::CreateTypes() +{ + if( g_TwMgr==NULL ) + return; + TwStructMember ColorExtMembers[] = { { "Red", TW_TYPE_INT32, offsetof(CColorExt, R), "min=0 max=255" }, + { "Green", TW_TYPE_INT32, offsetof(CColorExt, G), "min=0 max=255" }, + { "Blue", TW_TYPE_INT32, offsetof(CColorExt, B), "min=0 max=255" }, + { "Hue", TW_TYPE_INT32, offsetof(CColorExt, H), "hide min=0 max=359" }, + { "Lightness", TW_TYPE_INT32, offsetof(CColorExt, L), "hide min=0 max=255" }, + { "Saturation", TW_TYPE_INT32, offsetof(CColorExt, S), "hide min=0 max=255" }, + { "Alpha", TW_TYPE_INT32, offsetof(CColorExt, A), "hide min=0 max=255" }, + { "Mode", TW_TYPE_BOOLCPP, offsetof(CColorExt, m_HLS), "true='HLS' false='RGB' readwrite" } }; + g_TwMgr->m_TypeColor32 = TwDefineStructExt("COLOR32", ColorExtMembers, 8, sizeof(unsigned int), sizeof(CColorExt), CColorExt::InitColor32CB, CColorExt::CopyVarFromExtCB, CColorExt::CopyVarToExtCB, CColorExt::SummaryCB, CTwMgr::CStruct::s_PassProxyAsClientData, "A 32-bit-encoded color."); + g_TwMgr->m_TypeColor3F = TwDefineStructExt("COLOR3F", ColorExtMembers, 8, 3*sizeof(float), sizeof(CColorExt), CColorExt::InitColor3FCB, CColorExt::CopyVarFromExtCB, CColorExt::CopyVarToExtCB, CColorExt::SummaryCB, CTwMgr::CStruct::s_PassProxyAsClientData, "A 3-floats-encoded RGB color."); + g_TwMgr->m_TypeColor4F = TwDefineStructExt("COLOR4F", ColorExtMembers, 8, 4*sizeof(float), sizeof(CColorExt), CColorExt::InitColor4FCB, CColorExt::CopyVarFromExtCB, CColorExt::CopyVarToExtCB, CColorExt::SummaryCB, CTwMgr::CStruct::s_PassProxyAsClientData, "A 4-floats-encoded RGBA color."); + // Do not name them "TW_COLOR*" because the name is displayed in the help bar. +} + +// --------------------------------------------------------------------------- +// Quaternion ext type +// --------------------------------------------------------------------------- + +void ANT_CALL CQuaternionExt::InitQuat4FCB(void *_ExtValue, void *_ClientData) +{ + CQuaternionExt *ext = static_cast(_ExtValue); + if( ext ) + { + ext->Qx = ext->Qy = ext->Qz = 0; + ext->Qs = 1; + ext->Vx = 1; + ext->Vy = ext->Vz = 0; + ext->Angle = 0; + ext->Dx = ext->Dy = ext->Dz = 0; + ext->m_AAMode = false; // Axis & angle mode hidden + ext->m_ShowVal = false; + ext->m_IsFloat = true; + ext->m_IsDir = false; + ext->m_Dir[0] = ext->m_Dir[1] = ext->m_Dir[2] = 0; + ext->m_DirColor = 0xffffff00; + int i, j; + for(i=0; i<3; ++i) + for(j=0; j<3; ++j) + ext->m_Permute[i][j] = (i==j) ? 1.0f : 0.0f; + ext->m_StructProxy = (CTwMgr::CStructProxy *)_ClientData; + ext->ConvertToAxisAngle(); + ext->m_Highlighted = false; + ext->m_Rotating = false; + if( ext->m_StructProxy!=NULL ) + { + ext->m_StructProxy->m_CustomDrawCallback = CQuaternionExt::DrawCB; + ext->m_StructProxy->m_CustomMouseButtonCallback = CQuaternionExt::MouseButtonCB; + ext->m_StructProxy->m_CustomMouseMotionCallback = CQuaternionExt::MouseMotionCB; + ext->m_StructProxy->m_CustomMouseLeaveCallback = CQuaternionExt::MouseLeaveCB; + } + } +} + +void ANT_CALL CQuaternionExt::InitQuat4DCB(void *_ExtValue, void *_ClientData) +{ + CQuaternionExt *ext = static_cast(_ExtValue); + if( ext ) + { + ext->Qx = ext->Qy = ext->Qz = 0; + ext->Qs = 1; + ext->Vx = 1; + ext->Vy = ext->Vz = 0; + ext->Angle = 0; + ext->Dx = ext->Dy = ext->Dz = 0; + ext->m_AAMode = false; // Axis & angle mode hidden + ext->m_ShowVal = false; + ext->m_IsFloat = false; + ext->m_IsDir = false; + ext->m_Dir[0] = ext->m_Dir[1] = ext->m_Dir[2] = 0; + ext->m_DirColor = 0xffffff00; + int i, j; + for(i=0; i<3; ++i) + for(j=0; j<3; ++j) + ext->m_Permute[i][j] = (i==j) ? 1.0f : 0.0f; + ext->m_StructProxy = (CTwMgr::CStructProxy *)_ClientData; + ext->ConvertToAxisAngle(); + ext->m_Highlighted = false; + ext->m_Rotating = false; + if( ext->m_StructProxy!=NULL ) + { + ext->m_StructProxy->m_CustomDrawCallback = CQuaternionExt::DrawCB; + ext->m_StructProxy->m_CustomMouseButtonCallback = CQuaternionExt::MouseButtonCB; + ext->m_StructProxy->m_CustomMouseMotionCallback = CQuaternionExt::MouseMotionCB; + ext->m_StructProxy->m_CustomMouseLeaveCallback = CQuaternionExt::MouseLeaveCB; + } + } +} + +void ANT_CALL CQuaternionExt::InitDir3FCB(void *_ExtValue, void *_ClientData) +{ + CQuaternionExt *ext = static_cast(_ExtValue); + if( ext ) + { + ext->Qx = ext->Qy = ext->Qz = 0; + ext->Qs = 1; + ext->Vx = 1; + ext->Vy = ext->Vz = 0; + ext->Angle = 0; + ext->Dx = 1; + ext->Dy = ext->Dz = 0; + ext->m_AAMode = false; // Axis & angle mode hidden + ext->m_ShowVal = true; + ext->m_IsFloat = true; + ext->m_IsDir = true; + ext->m_Dir[0] = ext->m_Dir[1] = ext->m_Dir[2] = 0; + ext->m_DirColor = 0xffffff00; + int i, j; + for(i=0; i<3; ++i) + for(j=0; j<3; ++j) + ext->m_Permute[i][j] = (i==j) ? 1.0f : 0.0f; + ext->m_StructProxy = (CTwMgr::CStructProxy *)_ClientData; + ext->ConvertToAxisAngle(); + ext->m_Highlighted = false; + ext->m_Rotating = false; + if( ext->m_StructProxy!=NULL ) + { + ext->m_StructProxy->m_CustomDrawCallback = CQuaternionExt::DrawCB; + ext->m_StructProxy->m_CustomMouseButtonCallback = CQuaternionExt::MouseButtonCB; + ext->m_StructProxy->m_CustomMouseMotionCallback = CQuaternionExt::MouseMotionCB; + ext->m_StructProxy->m_CustomMouseLeaveCallback = CQuaternionExt::MouseLeaveCB; + } + } +} + +void ANT_CALL CQuaternionExt::InitDir3DCB(void *_ExtValue, void *_ClientData) +{ + CQuaternionExt *ext = static_cast(_ExtValue); + if( ext ) + { + ext->Qx = ext->Qy = ext->Qz = 0; + ext->Qs = 1; + ext->Vx = 1; + ext->Vy = ext->Vz = 0; + ext->Angle = 0; + ext->Dx = 1; + ext->Dy = ext->Dz = 0; + ext->m_AAMode = false; // Axis & angle mode hidden + ext->m_ShowVal = true; + ext->m_IsFloat = false; + ext->m_IsDir = true; + ext->m_Dir[0] = ext->m_Dir[1] = ext->m_Dir[2] = 0; + ext->m_DirColor = 0xffffff00; + int i, j; + for(i=0; i<3; ++i) + for(j=0; j<3; ++j) + ext->m_Permute[i][j] = (i==j) ? 1.0f : 0.0f; + ext->m_StructProxy = (CTwMgr::CStructProxy *)_ClientData; + ext->ConvertToAxisAngle(); + ext->m_Highlighted = false; + ext->m_Rotating = false; + if( ext->m_StructProxy!=NULL ) + { + ext->m_StructProxy->m_CustomDrawCallback = CQuaternionExt::DrawCB; + ext->m_StructProxy->m_CustomMouseButtonCallback = CQuaternionExt::MouseButtonCB; + ext->m_StructProxy->m_CustomMouseMotionCallback = CQuaternionExt::MouseMotionCB; + ext->m_StructProxy->m_CustomMouseLeaveCallback = CQuaternionExt::MouseLeaveCB; + } + } +} + +void ANT_CALL CQuaternionExt::CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData) +{ + CQuaternionExt *ext = (CQuaternionExt *)(_ExtValue); + CTwMgr::CMemberProxy *mProxy = static_cast(_ClientData); + if( _VarValue && ext ) + { + // Synchronize Quat and AxisAngle + if( _ExtMemberIndex>=4 && _ExtMemberIndex<=7 ) + { + ext->ConvertToAxisAngle(); + // show/hide quat values + if( _ExtMemberIndex==4 && mProxy && mProxy->m_VarParent ) + { + assert( mProxy->m_VarParent->m_Vars.size()==16 ); + bool visible = ext->m_ShowVal; + if( ext->m_IsDir ) + { + if( mProxy->m_VarParent->m_Vars[13]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[14]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[15]->m_Visible != visible ) + { + mProxy->m_VarParent->m_Vars[13]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[14]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[15]->m_Visible = visible; + mProxy->m_Bar->NotUpToDate(); + } + } + else + { + if( mProxy->m_VarParent->m_Vars[4]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[5]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[6]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[7]->m_Visible != visible ) + { + mProxy->m_VarParent->m_Vars[4]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[5]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[6]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[7]->m_Visible = visible; + mProxy->m_Bar->NotUpToDate(); + } + } + } + } + else if( _ExtMemberIndex>=8 && _ExtMemberIndex<=11 ) + ext->ConvertFromAxisAngle(); + else if( mProxy && _ExtMemberIndex==12 && mProxy->m_VarParent && !ext->m_IsDir ) + { + assert( mProxy->m_VarParent->m_Vars.size()==16 ); + bool aa = ext->m_AAMode; + if( mProxy->m_VarParent->m_Vars[4]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[5]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[6]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[7]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[8 ]->m_Visible != aa + || mProxy->m_VarParent->m_Vars[9 ]->m_Visible != aa + || mProxy->m_VarParent->m_Vars[10]->m_Visible != aa + || mProxy->m_VarParent->m_Vars[11]->m_Visible != aa ) + { + mProxy->m_VarParent->m_Vars[4]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[5]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[6]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[7]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[8 ]->m_Visible = aa; + mProxy->m_VarParent->m_Vars[9 ]->m_Visible = aa; + mProxy->m_VarParent->m_Vars[10]->m_Visible = aa; + mProxy->m_VarParent->m_Vars[11]->m_Visible = aa; + mProxy->m_Bar->NotUpToDate(); + } + if( static_cast(mProxy->m_VarParent->m_Vars[12])->m_ReadOnly ) + { + static_cast(mProxy->m_VarParent->m_Vars[12])->m_ReadOnly = false; + mProxy->m_Bar->NotUpToDate(); + } + } + + if( ext->m_IsFloat ) + { + float *var = static_cast(_VarValue); + if( ext->m_IsDir ) + { + var[0] = (float)ext->Dx; + var[1] = (float)ext->Dy; + var[2] = (float)ext->Dz; + } + else // quat + { + var[0] = (float)ext->Qx; + var[1] = (float)ext->Qy; + var[2] = (float)ext->Qz; + var[3] = (float)ext->Qs; + } + } + else + { + double *var = static_cast(_VarValue); + if( ext->m_IsDir ) + { + var[0] = ext->Dx; + var[1] = ext->Dy; + var[2] = ext->Dz; + } + else // quat + { + var[0] = ext->Qx; + var[1] = ext->Qy; + var[2] = ext->Qz; + var[3] = ext->Qs; + } + } + } +} + +void ANT_CALL CQuaternionExt::CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData) +{ + CQuaternionExt *ext = static_cast(_ExtValue); + CTwMgr::CMemberProxy *mProxy = static_cast(_ClientData); + (void)mProxy; + if( _VarValue && ext ) + { + if( mProxy && _ExtMemberIndex==12 && mProxy->m_VarParent && !ext->m_IsDir ) + { + assert( mProxy->m_VarParent->m_Vars.size()==16 ); + bool aa = ext->m_AAMode; + if( mProxy->m_VarParent->m_Vars[4]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[5]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[6]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[7]->m_Visible != !aa + || mProxy->m_VarParent->m_Vars[8 ]->m_Visible != aa + || mProxy->m_VarParent->m_Vars[9 ]->m_Visible != aa + || mProxy->m_VarParent->m_Vars[10]->m_Visible != aa + || mProxy->m_VarParent->m_Vars[11]->m_Visible != aa ) + { + mProxy->m_VarParent->m_Vars[4]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[5]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[6]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[7]->m_Visible = !aa; + mProxy->m_VarParent->m_Vars[8 ]->m_Visible = aa; + mProxy->m_VarParent->m_Vars[9 ]->m_Visible = aa; + mProxy->m_VarParent->m_Vars[10]->m_Visible = aa; + mProxy->m_VarParent->m_Vars[11]->m_Visible = aa; + mProxy->m_Bar->NotUpToDate(); + } + if( static_cast(mProxy->m_VarParent->m_Vars[12])->m_ReadOnly ) + { + static_cast(mProxy->m_VarParent->m_Vars[12])->m_ReadOnly = false; + mProxy->m_Bar->NotUpToDate(); + } + } + else if( mProxy && _ExtMemberIndex==4 && mProxy->m_VarParent ) + { + assert( mProxy->m_VarParent->m_Vars.size()==16 ); + bool visible = ext->m_ShowVal; + if( ext->m_IsDir ) + { + if( mProxy->m_VarParent->m_Vars[13]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[14]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[15]->m_Visible != visible ) + { + mProxy->m_VarParent->m_Vars[13]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[14]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[15]->m_Visible = visible; + mProxy->m_Bar->NotUpToDate(); + } + } + else + { + if( mProxy->m_VarParent->m_Vars[4]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[5]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[6]->m_Visible != visible + || mProxy->m_VarParent->m_Vars[7]->m_Visible != visible ) + { + mProxy->m_VarParent->m_Vars[4]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[5]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[6]->m_Visible = visible; + mProxy->m_VarParent->m_Vars[7]->m_Visible = visible; + mProxy->m_Bar->NotUpToDate(); + } + } + } + + if( ext->m_IsFloat ) + { + const float *var = static_cast(_VarValue); + if( ext->m_IsDir ) + { + ext->Dx = var[0]; + ext->Dy = var[1]; + ext->Dz = var[2]; + QuatFromDir(&ext->Qx, &ext->Qy, &ext->Qz, &ext->Qs, var[0], var[1], var[2]); + } + else + { + ext->Qx = var[0]; + ext->Qy = var[1]; + ext->Qz = var[2]; + ext->Qs = var[3]; + } + + } + else + { + const double *var = static_cast(_VarValue); + if( ext->m_IsDir ) + { + ext->Dx = var[0]; + ext->Dy = var[1]; + ext->Dz = var[2]; + QuatFromDir(&ext->Qx, &ext->Qy, &ext->Qz, &ext->Qs, var[0], var[1], var[2]); + } + else + { + ext->Qx = var[0]; + ext->Qy = var[1]; + ext->Qz = var[2]; + ext->Qs = var[3]; + } + } + ext->ConvertToAxisAngle(); + } +} + +void ANT_CALL CQuaternionExt::SummaryCB(char *_SummaryString, size_t _SummaryMaxLength, const void *_ExtValue, void * /*_ClientData*/) +{ + const CQuaternionExt *ext = static_cast(_ExtValue); + if( ext ) + { + if( ext->m_AAMode ) + _snprintf(_SummaryString, _SummaryMaxLength, "V={%.2f,%.2f,%.2f} A=%.0f°", ext->Vx, ext->Vy, ext->Vz, ext->Angle); + else if( ext->m_IsDir ) + { + //float d[] = {1, 0, 0}; + //ApplyQuat(d+0, d+1, d+2, 1, 0, 0, (float)ext->Qx, (float)ext->Qy, (float)ext->Qz, (float)ext->Qs); + _snprintf(_SummaryString, _SummaryMaxLength, "V={%.2f,%.2f,%.2f}", ext->Dx, ext->Dy, ext->Dz); + } + else + _snprintf(_SummaryString, _SummaryMaxLength, "Q={x:%.2f,y:%.2f,z:%.2f,s:%.2f}", ext->Qx, ext->Qy, ext->Qz, ext->Qs); + } + else + { + _SummaryString[0] = ' '; // required to force background color for this value + _SummaryString[1] = '\0'; + } +} + +TwType CQuaternionExt::s_CustomType = TW_TYPE_UNDEF; +vector CQuaternionExt::s_SphTri; +vector CQuaternionExt::s_SphCol; +vector CQuaternionExt::s_SphTriProj; +vector CQuaternionExt::s_SphColLight; +vector CQuaternionExt::s_ArrowTri[4]; +vector CQuaternionExt::s_ArrowNorm[4]; +vector CQuaternionExt::s_ArrowTriProj[4]; +vector CQuaternionExt::s_ArrowColLight[4]; + +void CQuaternionExt::CreateTypes() +{ + if( g_TwMgr==NULL ) + return; + s_CustomType = (TwType)(TW_TYPE_CUSTOM_BASE + (int)g_TwMgr->m_Customs.size()); + g_TwMgr->m_Customs.push_back(NULL); // increment custom type number + + for(int pass=0; pass<2; pass++) // pass 0: create quat types; pass 1: create dir types + { + const char *quatDefPass0 = "step=0.01 hide"; + const char *quatDefPass1 = "step=0.01 hide"; + const char *quatSDefPass0 = "step=0.01 min=-1 max=1 hide"; + const char *quatSDefPass1 = "step=0.01 min=-1 max=1 hide"; + const char *dirDefPass0 = "step=0.01 hide"; + const char *dirDefPass1 = "step=0.01"; + const char *quatDef = (pass==0) ? quatDefPass0 : quatDefPass1; + const char *quatSDef = (pass==0) ? quatSDefPass0 : quatSDefPass1; + const char *dirDef = (pass==0) ? dirDefPass0 : dirDefPass1; + + TwStructMember QuatExtMembers[] = { { "0", s_CustomType, 0, "" }, + { "1", s_CustomType, 0, "" }, + { "2", s_CustomType, 0, "" }, + { "3", s_CustomType, 0, "" }, + { "Quat X", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Qx), quatDef }, // copy of the source quaternion + { "Quat Y", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Qy), quatDef }, + { "Quat Z", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Qz), quatDef }, + { "Quat S", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Qs), quatSDef }, + { "Axis X", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Vx), "step=0.01 hide" }, // axis and angle conversion -> Mode hidden because it is not equivalent to a quat (would have required vector renormalization) + { "Axis Y", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Vy), "step=0.01 hide" }, + { "Axis Z", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Vz), "step=0.01 hide" }, + { "Angle (degree)", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Angle), "step=1 min=-360 max=360 hide" }, + { "Mode", TW_TYPE_BOOLCPP, offsetof(CQuaternionExt, m_AAMode), "true='Axis Angle' false='Quaternion' readwrite hide" }, + { "Dir X", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Dx), dirDef }, // copy of the source direction + { "Dir Y", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Dy), dirDef }, + { "Dir Z", TW_TYPE_DOUBLE, offsetof(CQuaternionExt, Dz), dirDef } }; + if( pass==0 ) + { + g_TwMgr->m_TypeQuat4F = TwDefineStructExt("QUAT4F", QuatExtMembers, sizeof(QuatExtMembers)/sizeof(QuatExtMembers[0]), 4*sizeof(float), sizeof(CQuaternionExt), CQuaternionExt::InitQuat4FCB, CQuaternionExt::CopyVarFromExtCB, CQuaternionExt::CopyVarToExtCB, CQuaternionExt::SummaryCB, CTwMgr::CStruct::s_PassProxyAsClientData, "A 4-floats-encoded quaternion"); + g_TwMgr->m_TypeQuat4D = TwDefineStructExt("QUAT4D", QuatExtMembers, sizeof(QuatExtMembers)/sizeof(QuatExtMembers[0]), 4*sizeof(double), sizeof(CQuaternionExt), CQuaternionExt::InitQuat4DCB, CQuaternionExt::CopyVarFromExtCB, CQuaternionExt::CopyVarToExtCB, CQuaternionExt::SummaryCB, CTwMgr::CStruct::s_PassProxyAsClientData, "A 4-doubles-encoded quaternion"); + } + else if( pass==1 ) + { + g_TwMgr->m_TypeDir3F = TwDefineStructExt("DIR4F", QuatExtMembers, sizeof(QuatExtMembers)/sizeof(QuatExtMembers[0]), 3*sizeof(float), sizeof(CQuaternionExt), CQuaternionExt::InitDir3FCB, CQuaternionExt::CopyVarFromExtCB, CQuaternionExt::CopyVarToExtCB, CQuaternionExt::SummaryCB, CTwMgr::CStruct::s_PassProxyAsClientData, "A 3-floats-encoded direction"); + g_TwMgr->m_TypeDir3D = TwDefineStructExt("DIR4D", QuatExtMembers, sizeof(QuatExtMembers)/sizeof(QuatExtMembers[0]), 3*sizeof(double), sizeof(CQuaternionExt), CQuaternionExt::InitDir3DCB, CQuaternionExt::CopyVarFromExtCB, CQuaternionExt::CopyVarToExtCB, CQuaternionExt::SummaryCB, CTwMgr::CStruct::s_PassProxyAsClientData, "A 3-doubles-encoded direction"); + } + } + + CreateSphere(); + CreateArrow(); +} + +void CQuaternionExt::ConvertToAxisAngle() +{ + if( fabs(Qs)>(1.0 + FLOAT_EPS) ) + { + //Vx = Vy = Vz = 0; // no, keep the previous value + Angle = 0; + } + else + { + double a; + if( Qs>=1.0f ) + a = 0; // and keep V + else if( Qs<=-1.0f ) + a = DOUBLE_PI; // and keep V + else if( fabs(Qx*Qx+Qy*Qy+Qz*Qz+Qs*Qs)FLOAT_PI ) + // Angle -= 2.0f*FLOAT_PI; + // else if( Angle<-FLOAT_PI ) + // Angle += 2.0f*FLOAT_PI; + Angle = RadToDeg(Angle); + + if( fabs(Angle)FLOAT_EPS_SQ ) + { + double f = 0.5*DegToRad(Angle); + Qs = cos(f); + //do not normalize + //if( fabs(n - 1.0)>FLOAT_EPS_SQ ) + // f = sin(f) * (1.0/sqrt(n)) ; + //else + // f = sin(f); + f = sin(f); + + Qx = Vx * f; + Qy = Vy * f; + Qz = Vz * f; + } + else + { + Qs = 1.0; + Qx = Qy = Qz = 0.0; + } +} + +void CQuaternionExt::CopyToVar() +{ + if( m_StructProxy!=NULL ) + { + if( m_StructProxy->m_StructSetCallback!=NULL ) + { + if( m_IsFloat ) + { + if( m_IsDir ) + { + float d[] = {1, 0, 0}; + ApplyQuat(d+0, d+1, d+2, 1, 0, 0, (float)Qx, (float)Qy, (float)Qz, (float)Qs); + float l = (float)sqrt(Dx*Dx + Dy*Dy + Dz*Dz); + d[0] *= l; d[1] *= l; d[2] *= l; + Dx = d[0]; Dy = d[1]; Dz = d[2]; // update also Dx,Dy,Dz + m_StructProxy->m_StructSetCallback(d, m_StructProxy->m_StructClientData); + } + else + { + float q[] = { (float)Qx, (float)Qy, (float)Qz, (float)Qs }; + m_StructProxy->m_StructSetCallback(q, m_StructProxy->m_StructClientData); + } + } + else + { + if( m_IsDir ) + { + float d[] = {1, 0, 0}; + ApplyQuat(d+0, d+1, d+2, 1, 0, 0, (float)Qx, (float)Qy, (float)Qz, (float)Qs); + double l = sqrt(Dx*Dx + Dy*Dy + Dz*Dz); + double dd[] = {l*d[0], l*d[1], l*d[2]}; + Dx = dd[0]; Dy = dd[1]; Dz = dd[2]; // update also Dx,Dy,Dz + m_StructProxy->m_StructSetCallback(dd, m_StructProxy->m_StructClientData); + } + else + { + double q[] = { Qx, Qy, Qz, Qs }; + m_StructProxy->m_StructSetCallback(q, m_StructProxy->m_StructClientData); + } + } + } + else if( m_StructProxy->m_StructData!=NULL ) + { + if( m_IsFloat ) + { + if( m_IsDir ) + { + float *d = static_cast(m_StructProxy->m_StructData); + ApplyQuat(d+0, d+1, d+2, 1, 0, 0, (float)Qx, (float)Qy, (float)Qz, (float)Qs); + float l = (float)sqrt(Dx*Dx + Dy*Dy + Dz*Dz); + d[0] *= l; d[1] *= l; d[2] *= l; + Dx = d[0]; Dy = d[1]; Dz = d[2]; // update also Dx,Dy,Dz + } + else + { + float *q = static_cast(m_StructProxy->m_StructData); + q[0] = (float)Qx; q[1] = (float)Qy; q[2] = (float)Qz; q[3] = (float)Qs; + } + } + else + { + if( m_IsDir ) + { + double *dd = static_cast(m_StructProxy->m_StructData); + float d[] = {1, 0, 0}; + ApplyQuat(d+0, d+1, d+2, 1, 0, 0, (float)Qx, (float)Qy, (float)Qz, (float)Qs); + double l = sqrt(Dx*Dx + Dy*Dy + Dz*Dz); + dd[0] = l*d[0]; dd[1] = l*d[1]; dd[2] = l*d[2]; + Dx = dd[0]; Dy = dd[1]; Dz = dd[2]; // update also Dx,Dy,Dz + } + else + { + double *q = static_cast(m_StructProxy->m_StructData); + q[0] = Qx; q[1] = Qy; q[2] = Qz; q[3] = Qs; + } + } + } + } +} + +void CQuaternionExt::CreateSphere() +{ + const int SUBDIV = 7; + s_SphTri.clear(); + s_SphCol.clear(); + + const float A[8*3] = { 1,0,0, 0,0,-1, -1,0,0, 0,0,1, 0,0,1, 1,0,0, 0,0,-1, -1,0,0 }; + const float B[8*3] = { 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0 }; + const float C[8*3] = { 0,0,1, 1,0,0, 0,0,-1, -1,0,0, 1,0,0, 0,0,-1, -1,0,0, 0,0,1 }; + //const color32 COL_A[8] = { 0xffff8080, 0xff000080, 0xff800000, 0xff8080ff, 0xff8080ff, 0xffff8080, 0xff000080, 0xff800000 }; + //const color32 COL_B[8] = { 0xff80ff80, 0xff80ff80, 0xff80ff80, 0xff80ff80, 0xff008000, 0xff008000, 0xff008000, 0xff008000 }; + //const color32 COL_C[8] = { 0xff8080ff, 0xffff8080, 0xff000080, 0xff800000, 0xffff8080, 0xff000080, 0xff800000, 0xff8080ff }; + const color32 COL_A[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff }; + const color32 COL_B[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff }; + const color32 COL_C[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff }; + + int i, j, k, l; + float xa, ya, za, xb, yb, zb, xc, yc, zc, x, y, z, norm, u[3], v[3]; + color32 col; + for( i=0; i<8; ++i ) + { + xa = A[3*i+0]; ya = A[3*i+1]; za = A[3*i+2]; + xb = B[3*i+0]; yb = B[3*i+1]; zb = B[3*i+2]; + xc = C[3*i+0]; yc = C[3*i+1]; zc = C[3*i+2]; + for( j=0; j<=SUBDIV; ++j ) + for( k=0; k<=2*(SUBDIV-j); ++k ) + { + if( k%2==0 ) + { + u[0] = ((float)j)/(SUBDIV+1); + v[0] = ((float)(k/2))/(SUBDIV+1); + u[1] = ((float)(j+1))/(SUBDIV+1); + v[1] = ((float)(k/2))/(SUBDIV+1); + u[2] = ((float)j)/(SUBDIV+1); + v[2] = ((float)(k/2+1))/(SUBDIV+1); + } + else + { + u[0] = ((float)j)/(SUBDIV+1); + v[0] = ((float)(k/2+1))/(SUBDIV+1); + u[1] = ((float)(j+1))/(SUBDIV+1); + v[1] = ((float)(k/2))/(SUBDIV+1); + u[2] = ((float)(j+1))/(SUBDIV+1); + v[2] = ((float)(k/2+1))/(SUBDIV+1); + } + + for( l=0; l<3; ++l ) + { + x = (1.0f-u[l]-v[l])*xa + u[l]*xb + v[l]*xc; + y = (1.0f-u[l]-v[l])*ya + u[l]*yb + v[l]*yc; + z = (1.0f-u[l]-v[l])*za + u[l]*zb + v[l]*zc; + norm = sqrtf(x*x+y*y+z*z); + x /= norm; y /= norm; z /= norm; + s_SphTri.push_back(x); s_SphTri.push_back(y); s_SphTri.push_back(z); + if( u[l]+v[l]>FLOAT_EPS ) + col = ColorBlend(COL_A[i], ColorBlend(COL_B[i], COL_C[i], v[l]/(u[l]+v[l])), u[l]+v[l]); + else + col = COL_A[i]; + //if( (j==0 && k==0) || (j==0 && k==2*SUBDIV) || (j==SUBDIV && k==0) ) + // col = 0xffff0000; + s_SphCol.push_back(col); + } + } + } + s_SphTriProj.clear(); + s_SphTriProj.resize(2*s_SphCol.size(), 0); + s_SphColLight.clear(); + s_SphColLight.resize(s_SphCol.size(), 0); +} + +void CQuaternionExt::CreateArrow() +{ + const int SUBDIV = 15; + const float CYL_RADIUS = 0.08f; + const float CONE_RADIUS = 0.16f; + const float CONE_LENGTH = 0.25f; + const float ARROW_BGN = -1.1f; + const float ARROW_END = 1.15f; + int i; + for(i=0; i<4; ++i) + { + s_ArrowTri[i].clear(); + s_ArrowNorm[i].clear(); + } + + float x0, x1, y0, y1, z0, z1, a0, a1, nx, nn; + for(i=0; iDOUBLE_EPS ) + { + double f = 0.5*angle; + out[3] = cos(f); + f = sin(f)/sqrt(n); + out[0] = axis[0]*f; + out[1] = axis[1]*f; + out[2] = axis[2]*f; + } + else + { + out[3] = 1.0; + out[0] = out[1] = out[2] = 0.0; + } +} + +static inline void Vec3Cross(double *out, const double *a, const double *b) +{ + out[0] = a[1]*b[2]-a[2]*b[1]; + out[1] = a[2]*b[0]-a[0]*b[2]; + out[2] = a[0]*b[1]-a[1]*b[0]; +} + +static inline double Vec3Dot(const double *a, const double *b) +{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; +} + +static inline void Vec3RotY(float *x, float *y, float *z) +{ + (void)y; + float tmp = *x; + *x = - *z; + *z = tmp; +} + +static inline void Vec3RotZ(float *x, float *y, float *z) +{ + (void)z; + float tmp = *x; + *x = - *y; + *y = tmp; +} + +void CQuaternionExt::ApplyQuat(float *outX, float *outY, float *outZ, float x, float y, float z, float qx, float qy, float qz, float qs) +{ + float ps = - qx * x - qy * y - qz * z; + float px = qs * x + qy * z - qz * y; + float py = qs * y + qz * x - qx * z; + float pz = qs * z + qx * y - qy * x; + *outX = - ps * qx + px * qs - py * qz + pz * qy; + *outY = - ps * qy + py * qs - pz * qx + px * qz; + *outZ = - ps * qz + pz * qs - px * qy + py * qx; +} + +void CQuaternionExt::QuatFromDir(double *outQx, double *outQy, double *outQz, double *outQs, double dx, double dy, double dz) +{ + // compute a quaternion that rotates (1,0,0) to (dx,dy,dz) + + double dn = sqrt(dx*dx + dy*dy + dz*dz); + if( dnm_Graph==NULL ) + return; + assert( g_TwMgr->m_Graph->IsDrawing() ); + CQuaternionExt *ext = static_cast(_ExtValue); + assert( ext!=NULL ); + (void)_ClientData; (void)_Bar; + + // show/hide quat values + assert( varGrp->m_Vars.size()==16 ); + bool visible = ext->m_ShowVal; + if( ext->m_IsDir ) + { + if( varGrp->m_Vars[13]->m_Visible != visible + || varGrp->m_Vars[14]->m_Visible != visible + || varGrp->m_Vars[15]->m_Visible != visible ) + { + varGrp->m_Vars[13]->m_Visible = visible; + varGrp->m_Vars[14]->m_Visible = visible; + varGrp->m_Vars[15]->m_Visible = visible; + _Bar->NotUpToDate(); + } + } + else + { + if( varGrp->m_Vars[4]->m_Visible != visible + || varGrp->m_Vars[5]->m_Visible != visible + || varGrp->m_Vars[6]->m_Visible != visible + || varGrp->m_Vars[7]->m_Visible != visible ) + { + varGrp->m_Vars[4]->m_Visible = visible; + varGrp->m_Vars[5]->m_Visible = visible; + varGrp->m_Vars[6]->m_Visible = visible; + varGrp->m_Vars[7]->m_Visible = visible; + _Bar->NotUpToDate(); + } + } + + // force ext update + static_cast(varGrp->m_Vars[4])->ValueToDouble(); + + assert( s_SphTri.size()>0 ); + assert( s_SphTri.size()==3*s_SphCol.size() ); + assert( s_SphTriProj.size()==2*s_SphCol.size() ); + assert( s_SphColLight.size()==s_SphCol.size() ); + + if( QuatD(w, h)<=2 ) + return; + float x, y, z, nx, ny, nz, kx, ky, kz, qx, qy, qz, qs; + int i, j, k, l, m; + + // normalize quaternion + float qn = (float)sqrt(ext->Qs*ext->Qs+ext->Qx*ext->Qx+ext->Qy*ext->Qy+ext->Qz*ext->Qz); + if( qn>FLOAT_EPS ) + { + qx = (float)ext->Qx/qn; + qy = (float)ext->Qy/qn; + qz = (float)ext->Qz/qn; + qs = (float)ext->Qs/qn; + } + else + { + qx = qy = qz = 0; + qs = 1; + } + + double normDir = sqrt(ext->m_Dir[0]*ext->m_Dir[0] + ext->m_Dir[1]*ext->m_Dir[1] + ext->m_Dir[2]*ext->m_Dir[2]); + bool drawDir = ext->m_IsDir || (normDir>DOUBLE_EPS); + color32 alpha = ext->m_Highlighted ? 0xffffffff : 0xb0ffffff; + + // check if frame is right-handed + ext->Permute(&kx, &ky, &kz, 1, 0, 0); + double px[3] = { (double)kx, (double)ky, (double)kz }; + ext->Permute(&kx, &ky, &kz, 0, 1, 0); + double py[3] = { (double)kx, (double)ky, (double)kz }; + ext->Permute(&kx, &ky, &kz, 0, 0, 1); + double pz[3] = { (double)kx, (double)ky, (double)kz }; + double ez[3]; + Vec3Cross(ez, px, py); + bool frameRightHanded = (ez[0]*pz[0]+ez[1]*pz[1]+ez[2]*pz[2] >= 0); + ITwGraph::Cull cull = frameRightHanded ? ITwGraph::CULL_CW : ITwGraph::CULL_CCW; + + if( drawDir ) + { + float dir[] = {(float)ext->m_Dir[0], (float)ext->m_Dir[1], (float)ext->m_Dir[2]}; + if( normDirPermute(&x, &y, &z, kx, ky, kz); + j = (z>0) ? 3-k : k; + + assert( s_ArrowTriProj[j].size()==2*(s_ArrowTri[j].size()/3) && s_ArrowColLight[j].size()==s_ArrowTri[j].size()/3 && s_ArrowNorm[j].size()==s_ArrowTri[j].size() ); + const int ntri = (int)s_ArrowTri[j].size()/3; + const float *tri = &(s_ArrowTri[j][0]); + const float *norm = &(s_ArrowNorm[j][0]); + int *triProj = &(s_ArrowTriProj[j][0]); + color32 *colLight = &(s_ArrowColLight[j][0]); + for(i=0; i0 ) + x = 2.5f*x - 2.0f; + else + x += 0.2f; + y *= 1.5f; + z *= 1.5f; + ApplyQuat(&x, &y, &z, x, y, z, (float)rotDirQuat[0], (float)rotDirQuat[1], (float)rotDirQuat[2], (float)rotDirQuat[3]); + ApplyQuat(&x, &y, &z, x, y, z, qx, qy, qz, qs); + ext->Permute(&x, &y, &z, x, y, z); + ApplyQuat(&nx, &ny, &nz, nx, ny, nz, (float)rotDirQuat[0], (float)rotDirQuat[1], (float)rotDirQuat[2], (float)rotDirQuat[3]); + ApplyQuat(&nx, &ny, &nz, nx, ny, nz, qx, qy, qz, qs); + ext->Permute(&nx, &ny, &nz, nx, ny, nz); + triProj[2*i+0] = QuatPX(x, w, h); + triProj[2*i+1] = QuatPY(y, w, h); + color32 col = (ext->m_DirColor|0xff000000) & alpha; + colLight[i] = ColorBlend(0xff000000, col, fabsf(TClamp(nz, -1.0f, 1.0f))); + } + if( s_ArrowTri[j].size()>=9 ) // 1 tri = 9 floats + g_TwMgr->m_Graph->DrawTriangles((int)s_ArrowTri[j].size()/9, triProj, colLight, cull); + } + } + else + { + /* + int px0 = QuatPX(0, w, h)-1, py0 = QuatPY(0, w, h), r0 = (int)(0.5f*QuatD(w, h)-0.5f); + color32 col0 = 0x80000000; + DrawArc(px0-1, py0, r0, 0, 360, col0); + DrawArc(px0+1, py0, r0, 0, 360, col0); + DrawArc(px0, py0-1, r0, 0, 360, col0); + DrawArc(px0, py0+1, r0, 0, 360, col0); + */ + // draw arrows & sphere + const float SPH_RADIUS = 0.75f; + for(m=0; m<2; ++m) // m=0: back, m=1: front + { + for(l=0; l<3; ++l) // draw 3 arrows + { + kx = 1; ky = 0; kz = 0; + if( l==1 ) + Vec3RotZ(&kx, &ky, &kz); + else if( l==2 ) + Vec3RotY(&kx, &ky, &kz); + ApplyQuat(&kx, &ky, &kz, kx, ky, kz, qx, qy, qz, qs); + for(k=0; k<4; ++k) // 4 parts of the arrow + { + // draw order + ext->Permute(&x, &y, &z, kx, ky, kz); + j = (z>0) ? 3-k : k; + + bool cone = true; + if( (m==0 && z>0) || (m==1 && z<=0) ) + { + if( j==ARROW_CONE || j==ARROW_CONE_CAP ) // do not draw cone + continue; + else + cone = false; + } + assert( s_ArrowTriProj[j].size()==2*(s_ArrowTri[j].size()/3) && s_ArrowColLight[j].size()==s_ArrowTri[j].size()/3 && s_ArrowNorm[j].size()==s_ArrowTri[j].size() ); + const int ntri = (int)s_ArrowTri[j].size()/3; + const float *tri = &(s_ArrowTri[j][0]); + const float *norm = &(s_ArrowNorm[j][0]); + int *triProj = &(s_ArrowTriProj[j][0]); + color32 *colLight = &(s_ArrowColLight[j][0]); + for(i=0; i0 ) + x = -SPH_RADIUS; + nx = norm[3*i+0]; ny = norm[3*i+1]; nz = norm[3*i+2]; + if( l==1 ) + { + Vec3RotZ(&x, &y, &z); + Vec3RotZ(&nx, &ny, &nz); + } + else if( l==2 ) + { + Vec3RotY(&x, &y, &z); + Vec3RotY(&nx, &ny, &nz); + } + ApplyQuat(&x, &y, &z, x, y, z, qx, qy, qz, qs); + ext->Permute(&x, &y, &z, x, y, z); + ApplyQuat(&nx, &ny, &nz, nx, ny, nz, qx, qy, qz, qs); + ext->Permute(&nx, &ny, &nz, nx, ny, nz); + triProj[2*i+0] = QuatPX(x, w, h); + triProj[2*i+1] = QuatPY(y, w, h); + float fade = ( m==0 && z<0 ) ? TClamp(2.0f*z*z, 0.0f, 1.0f) : 0; + float alphaFade = 1.0f; + Color32ToARGBf(alpha, &alphaFade, NULL, NULL, NULL); + alphaFade *= (1.0f-fade); + color32 alphaFadeCol = Color32FromARGBf(alphaFade, 1, 1, 1); + color32 col = (l==0) ? 0xffff0000 : ( (l==1) ? 0xff00ff00 : 0xff0000ff ); + colLight[i] = ColorBlend(0xff000000, col, fabsf(TClamp(nz, -1.0f, 1.0f))) & alphaFadeCol; + } + if( s_ArrowTri[j].size()>=9 ) // 1 tri = 9 floats + g_TwMgr->m_Graph->DrawTriangles((int)s_ArrowTri[j].size()/9, triProj, colLight, cull); + } + } + + if( m==0 ) + { + const float *tri = &(s_SphTri[0]); + int *triProj = &(s_SphTriProj[0]); + const color32 *col = &(s_SphCol[0]); + color32 *colLight = &(s_SphColLight[0]); + const int ntri = (int)s_SphTri.size()/3; + for(i=0; iPermute(&x, &y, &z, x, y, z); + triProj[2*i+0] = QuatPX(x, w, h); + triProj[2*i+1] = QuatPY(y, w, h); + colLight[i] = ColorBlend(0xff000000, col[i], fabsf(TClamp(z/SPH_RADIUS, -1.0f, 1.0f))) & alpha; + } + g_TwMgr->m_Graph->DrawTriangles((int)s_SphTri.size()/9, triProj, colLight, cull); + } + } + + // draw x + g_TwMgr->m_Graph->DrawLine(w-12, h-36, w-12+5, h-36+5, 0xffc00000, true); + g_TwMgr->m_Graph->DrawLine(w-12+5, h-36, w-12, h-36+5, 0xffc00000, true); + // draw y + g_TwMgr->m_Graph->DrawLine(w-12, h-25, w-12+3, h-25+4, 0xff00c000, true); + g_TwMgr->m_Graph->DrawLine(w-12+5, h-25, w-12, h-25+7, 0xff00c000, true); + // draw z + g_TwMgr->m_Graph->DrawLine(w-12, h-12, w-12+5, h-12, 0xff0000c0, true); + g_TwMgr->m_Graph->DrawLine(w-12, h-12+5, w-12+5, h-12+5, 0xff0000c0, true); + g_TwMgr->m_Graph->DrawLine(w-12, h-12+5, w-12+5, h-12, 0xff0000c0, true); + } + + // draw borders + g_TwMgr->m_Graph->DrawLine(1, 0, w-1, 0, 0x40000000); + g_TwMgr->m_Graph->DrawLine(w-1, 0, w-1, h-1, 0x40000000); + g_TwMgr->m_Graph->DrawLine(w-1, h-1, 1, h-1, 0x40000000); + g_TwMgr->m_Graph->DrawLine(1, h-1, 1, 0, 0x40000000); +} + +bool CQuaternionExt::MouseMotionCB(int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp) +{ + CQuaternionExt *ext = static_cast(structExtValue); + if( ext==NULL ) + return false; + (void)clientData, (void)varGrp; + + if( mouseX>0 && mouseX0 && mouseYm_Highlighted = true; + + if( ext->m_Rotating ) + { + double x = QuatIX(mouseX, w, h); + double y = QuatIY(mouseY, w, h); + double z = 1; + double px, py, pz, ox, oy, oz; + ext->PermuteInv(&px, &py, &pz, x, y, z); + ext->PermuteInv(&ox, &oy, &oz, ext->m_OrigX, ext->m_OrigY, 1); + double n0 = sqrt(ox*ox + oy*oy + oz*oz); + double n1 = sqrt(px*px + py*py + pz*pz); + if( n0>DOUBLE_EPS && n1>DOUBLE_EPS ) + { + double v0[] = { ox/n0, oy/n0, oz/n0 }; + double v1[] = { px/n1, py/n1, pz/n1 }; + double axis[3]; + Vec3Cross(axis, v0, v1); + double sa = sqrt(Vec3Dot(axis, axis)); + double ca = Vec3Dot(v0, v1); + double angle = atan2(sa, ca); + if( x*x+y*y>1.0 ) + angle *= 1.0 + 0.2f*(sqrt(x*x+y*y)-1.0); + double qrot[4], qres[4], qorig[4]; + QuatFromAxisAngle(qrot, axis, angle); + double nqorig = sqrt(ext->m_OrigQuat[0]*ext->m_OrigQuat[0]+ext->m_OrigQuat[1]*ext->m_OrigQuat[1]+ext->m_OrigQuat[2]*ext->m_OrigQuat[2]+ext->m_OrigQuat[3]*ext->m_OrigQuat[3]); + if( fabs(nqorig)>DOUBLE_EPS_SQ ) + { + qorig[0] = ext->m_OrigQuat[0]/nqorig; + qorig[1] = ext->m_OrigQuat[1]/nqorig; + qorig[2] = ext->m_OrigQuat[2]/nqorig; + qorig[3] = ext->m_OrigQuat[3]/nqorig; + QuatMult(qres, qrot, qorig); + ext->Qx = qres[0]; + ext->Qy = qres[1]; + ext->Qz = qres[2]; + ext->Qs = qres[3]; + } + else + { + ext->Qx = qrot[0]; + ext->Qy = qrot[1]; + ext->Qz = qrot[2]; + ext->Qs = qrot[3]; + } + ext->CopyToVar(); + if( bar!=NULL ) + bar->NotUpToDate(); + + ext->m_PrevX = x; + ext->m_PrevY = y; + } + } + + return true; +} + +bool CQuaternionExt::MouseButtonCB(TwMouseButtonID button, bool pressed, int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp) +{ + CQuaternionExt *ext = static_cast(structExtValue); + if( ext==NULL ) + return false; + (void)clientData; (void)bar, (void)varGrp; + + if( button==TW_MOUSE_LEFT ) + { + if( pressed ) + { + ext->m_OrigQuat[0] = ext->Qx; + ext->m_OrigQuat[1] = ext->Qy; + ext->m_OrigQuat[2] = ext->Qz; + ext->m_OrigQuat[3] = ext->Qs; + ext->m_OrigX = QuatIX(mouseX, w, h); + ext->m_OrigY = QuatIY(mouseY, w, h); + ext->m_PrevX = ext->m_OrigX; + ext->m_PrevY = ext->m_OrigY; + ext->m_Rotating = true; + } + else + ext->m_Rotating = false; + } + + //printf("Click %x\n", structExtValue); + return true; +} + +void CQuaternionExt::MouseLeaveCB(void *structExtValue, void *clientData, TwBar *bar) +{ + CQuaternionExt *ext = static_cast(structExtValue); + if( ext==NULL ) + return; + (void)clientData; (void)bar; + + //printf("Leave %x\n", structExtValue); + ext->m_Highlighted = false; + ext->m_Rotating = false; +} + + +// --------------------------------------------------------------------------- +// Convertion between VC++ Debug/Release std::string +// (Needed because VC++ adds some extra info to std::string in Debug mode!) +// And resolve binary std::string incompatibility between VS2008- and VS2010+ +// --------------------------------------------------------------------------- + +#ifdef _MSC_VER +// VS2008 and lower store the string allocator pointer at the beginning +// VS2010 and higher store the string allocator pointer at the end +static void FixVS2010StdStringLibToClient(void *strPtr) +{ + char *ptr = (char *)strPtr; + const size_t SizeOfUndecoratedString = 16 + 2*sizeof(size_t) + sizeof(void *); // size of a VS std::string without extra debug iterator and info. + assert(SizeOfUndecoratedString <= sizeof(std::string)); + TwType LibStdStringBaseType = (TwType)(TW_TYPE_STDSTRING&0xffff0000); + void **allocAddress2008 = (void **)(ptr + sizeof(std::string) - SizeOfUndecoratedString); + void **allocAddress2010 = (void **)(ptr + sizeof(std::string) - sizeof(void *)); + if (LibStdStringBaseType == TW_TYPE_STDSTRING_VS2008 && g_TwMgr->m_ClientStdStringBaseType == TW_TYPE_STDSTRING_VS2010) + { + void *allocator = *allocAddress2008; + memmove(allocAddress2008, allocAddress2008 + 1, SizeOfUndecoratedString - sizeof(void *)); + *allocAddress2010 = allocator; + } + else if (LibStdStringBaseType == TW_TYPE_STDSTRING_VS2010 && g_TwMgr->m_ClientStdStringBaseType == TW_TYPE_STDSTRING_VS2008) + { + void *allocator = *allocAddress2010; + memmove(allocAddress2008 + 1, allocAddress2008, SizeOfUndecoratedString - sizeof(void *)); + *allocAddress2008 = allocator; + } +} + +static void FixVS2010StdStringClientToLib(void *strPtr) +{ + char *ptr = (char *)strPtr; + const size_t SizeOfUndecoratedString = 16 + 2*sizeof(size_t) + sizeof(void *); // size of a VS std::string without extra debug iterator and info. + assert(SizeOfUndecoratedString <= sizeof(std::string)); + TwType LibStdStringBaseType = (TwType)(TW_TYPE_STDSTRING&0xffff0000); + void **allocAddress2008 = (void **)(ptr + sizeof(std::string) - SizeOfUndecoratedString); + void **allocAddress2010 = (void **)(ptr + sizeof(std::string) - sizeof(void *)); + if (LibStdStringBaseType == TW_TYPE_STDSTRING_VS2008 && g_TwMgr->m_ClientStdStringBaseType == TW_TYPE_STDSTRING_VS2010) + { + void *allocator = *allocAddress2010; + memmove(allocAddress2008 + 1, allocAddress2008, SizeOfUndecoratedString - sizeof(void *)); + *allocAddress2008 = allocator; + } + else if (LibStdStringBaseType == TW_TYPE_STDSTRING_VS2010 && g_TwMgr->m_ClientStdStringBaseType == TW_TYPE_STDSTRING_VS2008) + { + void *allocator = *allocAddress2008; + memmove(allocAddress2008, allocAddress2008 + 1, SizeOfUndecoratedString - sizeof(void *)); + *allocAddress2010 = allocator; + } +} +#endif // _MSC_VER + +CTwMgr::CClientStdString::CClientStdString() +{ + memset(m_Data, 0, sizeof(m_Data)); +} + +void CTwMgr::CClientStdString::FromLib(const char *libStr) +{ + m_LibStr = libStr; // it is ok to have a local copy here + memcpy(m_Data + sizeof(void *), &m_LibStr, sizeof(std::string)); +#ifdef _MSC_VER + FixVS2010StdStringLibToClient(m_Data + sizeof(void *)); +#endif +} + +std::string& CTwMgr::CClientStdString::ToClient() +{ + assert( g_TwMgr!=NULL ); + if( g_TwMgr->m_ClientStdStringStructSize==sizeof(std::string)+sizeof(void *) ) + return *(std::string *)(m_Data); + else if( g_TwMgr->m_ClientStdStringStructSize+sizeof(void *)==sizeof(std::string) ) + return *(std::string *)(m_Data + 2*sizeof(void *)); + else + { + assert( g_TwMgr->m_ClientStdStringStructSize==sizeof(std::string) ); + return *(std::string *)(m_Data + sizeof(void *)); + } +} + + +CTwMgr::CLibStdString::CLibStdString() +{ + memset(m_Data, 0, sizeof(m_Data)); +} + +void CTwMgr::CLibStdString::FromClient(const std::string& clientStr) +{ + assert( g_TwMgr!=NULL ); + memcpy(m_Data + sizeof(void *), &clientStr, g_TwMgr->m_ClientStdStringStructSize); +#ifdef _MSC_VER + FixVS2010StdStringClientToLib(m_Data + sizeof(void *)); +#endif +} + +std::string& CTwMgr::CLibStdString::ToLib() +{ + assert( g_TwMgr!=NULL ); + if( g_TwMgr->m_ClientStdStringStructSize==sizeof(std::string)+sizeof(void *) ) + return *(std::string *)(m_Data + 2*sizeof(void *)); + else if( g_TwMgr->m_ClientStdStringStructSize+sizeof(void *)==sizeof(std::string) ) + return *(std::string *)(m_Data); + else + { + assert( g_TwMgr->m_ClientStdStringStructSize==sizeof(std::string) ); + return *(std::string *)(m_Data + sizeof(void *)); + } +} + + +// --------------------------------------------------------------------------- +// Management functions +// --------------------------------------------------------------------------- + + +static int TwCreateGraph(ETwGraphAPI _GraphAPI) +{ + assert( g_TwMgr!=NULL && g_TwMgr->m_Graph==NULL ); + + switch( _GraphAPI ) + { + case TW_OPENGL: + g_TwMgr->m_Graph = new CTwGraphOpenGL; + break; + case TW_OPENGL_CORE: + g_TwMgr->m_Graph = new CTwGraphOpenGLCore; + break; + case TW_DIRECT3D9: + #ifdef ANT_WINDOWS_DX9 + if( g_TwMgr->m_Device!=NULL ) + g_TwMgr->m_Graph = new CTwGraphDirect3D9; + else + { + g_TwMgr->SetLastError(g_ErrBadDevice); + return 0; + } + #endif // ANT_WINDOWS + break; + case TW_DIRECT3D10: + #ifdef ANT_WINDOWS_DX10 + if( g_TwMgr->m_Device!=NULL ) + g_TwMgr->m_Graph = new CTwGraphDirect3D10; + else + { + g_TwMgr->SetLastError(g_ErrBadDevice); + return 0; + } + #endif // ANT_WINDOWS + break; + case TW_DIRECT3D11: + #ifdef ANT_WINDOWS_DX11 + if( g_TwMgr->m_Device!=NULL ) + g_TwMgr->m_Graph = new CTwGraphDirect3D11; + else + { + g_TwMgr->SetLastError(g_ErrBadDevice); + return 0; + } + #endif // ANT_WINDOWS + break; + } + + if( g_TwMgr->m_Graph==NULL ) + { + g_TwMgr->SetLastError(g_ErrUnknownAPI); + return 0; + } + else + return g_TwMgr->m_Graph->Init(); +} + +// --------------------------------------------------------------------------- + +static inline int TwFreeAsyncDrawing() +{ + if( g_TwMgr && g_TwMgr->m_Graph && g_TwMgr->m_Graph->IsDrawing() ) + { + const double SLEEP_MAX = 0.25; // wait at most 1/4 second + PerfTimer timer; + while( g_TwMgr->m_Graph->IsDrawing() && timer.GetTime()m_Graph->IsDrawing() ) + { + g_TwMgr->SetLastError(g_ErrIsDrawing); + return 0; + } + } + return 1; +} + +// --------------------------------------------------------------------------- + +/* +static inline int TwFreeAsyncProcessing() +{ + if( g_TwMgr && g_TwMgr->IsProcessing() ) + { + const double SLEEP_MAX = 0.25; // wait at most 1/4 second + PerfTimer timer; + while( g_TwMgr->IsProcessing() && timer.GetTime()IsProcessing() ) + { + g_TwMgr->SetLastError(g_ErrIsProcessing); + return 0; + } + } + return 1; +} + +static inline int TwBeginProcessing() +{ + if( !TwFreeAsyncProcessing() ) + return 0; + if( g_TwMgr ) + g_TwMgr->SetProcessing(true); +} + +static inline int TwEndProcessing() +{ + if( g_TwMgr ) + g_TwMgr->SetProcessing(false); +} +*/ + +// --------------------------------------------------------------------------- + +static int TwInitMgr() +{ + assert( g_TwMasterMgr!=NULL ); + assert( g_TwMgr!=NULL ); + + g_TwMgr->m_CurrentFont = g_DefaultNormalFont; + g_TwMgr->m_Graph = g_TwMasterMgr->m_Graph; + + g_TwMgr->m_KeyPressedTextObj = g_TwMgr->m_Graph->NewTextObj(); + g_TwMgr->m_InfoTextObj = g_TwMgr->m_Graph->NewTextObj(); + + g_TwMgr->m_HelpBar = TwNewBar("TW_HELP"); + if( g_TwMgr->m_HelpBar ) + { + g_TwMgr->m_HelpBar->m_Label = "~ Help & Shortcuts ~"; + g_TwMgr->m_HelpBar->m_PosX = 32; + g_TwMgr->m_HelpBar->m_PosY = 32; + g_TwMgr->m_HelpBar->m_Width = 400; + g_TwMgr->m_HelpBar->m_Height = 200; + g_TwMgr->m_HelpBar->m_ValuesWidth = 12*(g_TwMgr->m_HelpBar->m_Font->m_CharHeight/2); + g_TwMgr->m_HelpBar->m_Color = 0xa05f5f5f; //0xd75f5f5f; + g_TwMgr->m_HelpBar->m_DarkText = false; + g_TwMgr->m_HelpBar->m_IsHelpBar = true; + g_TwMgr->Minimize(g_TwMgr->m_HelpBar); + } + else + return 0; + + CColorExt::CreateTypes(); + CQuaternionExt::CreateTypes(); + + return 1; +} + + +int ANT_CALL TwInit(ETwGraphAPI _GraphAPI, void *_Device) +{ +#if defined(_DEBUG) && defined(ANT_WINDOWS) + _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF)); +#endif + + if( g_TwMasterMgr!=NULL ) + { + g_TwMasterMgr->SetLastError(g_ErrInit); + return 0; + } + assert( g_TwMgr==0 ); + assert( g_Wnds.empty() ); + + g_TwMasterMgr = new CTwMgr(_GraphAPI, _Device, TW_MASTER_WINDOW_ID); + g_Wnds[TW_MASTER_WINDOW_ID] = g_TwMasterMgr; + g_TwMgr = g_TwMasterMgr; + + TwGenerateDefaultFonts(); + g_TwMgr->m_CurrentFont = g_DefaultNormalFont; + + int Res = TwCreateGraph(_GraphAPI); + if( Res ) + Res = TwInitMgr(); + + if( !Res ) + TwTerminate(); + + return Res; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwSetLastError(const char *_StaticErrorMessage) +{ + if( g_TwMasterMgr!=0 ) + { + g_TwMasterMgr->SetLastError(_StaticErrorMessage); + return 1; + } + else + return 0; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwTerminate() +{ + if( g_TwMgr==NULL ) + { + //TwGlobalError(g_ErrShut); -> not an error + return 0; // already shutdown + } + + // For multi-thread safety + if( !TwFreeAsyncDrawing() ) + return 0; + + CTwWndMap::iterator it; + for( it=g_Wnds.begin(); it!=g_Wnds.end(); it++ ) + { + g_TwMgr = it->second; + + g_TwMgr->m_Terminating = true; + TwDeleteAllBars(); + if( g_TwMgr->m_CursorsCreated ) + g_TwMgr->FreeCursors(); + + if( g_TwMgr->m_Graph ) + { + if( g_TwMgr->m_KeyPressedTextObj ) + { + g_TwMgr->m_Graph->DeleteTextObj(g_TwMgr->m_KeyPressedTextObj); + g_TwMgr->m_KeyPressedTextObj = NULL; + } + if( g_TwMgr->m_InfoTextObj ) + { + g_TwMgr->m_Graph->DeleteTextObj(g_TwMgr->m_InfoTextObj); + g_TwMgr->m_InfoTextObj = NULL; + } + if (g_TwMgr != g_TwMasterMgr) + g_TwMgr->m_Graph = NULL; + } + + if (g_TwMgr != g_TwMasterMgr) + { + delete g_TwMgr; + g_TwMgr = NULL; + } + } + + // delete g_TwMasterMgr + int Res = 1; + g_TwMgr = g_TwMasterMgr; + if( g_TwMasterMgr->m_Graph ) + { + Res = g_TwMasterMgr->m_Graph->Shut(); + delete g_TwMasterMgr->m_Graph; + g_TwMasterMgr->m_Graph = NULL; + } + TwDeleteDefaultFonts(); + delete g_TwMasterMgr; + g_TwMasterMgr = NULL; + g_TwMgr = NULL; + g_Wnds.clear(); + + return Res; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwGetCurrentWindow() +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + + return g_TwMgr->m_WndID; +} + +int ANT_CALL TwSetCurrentWindow(int wndID) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + + if (wndID != g_TwMgr->m_WndID) + { + CTwWndMap::iterator foundWnd = g_Wnds.find(wndID); + if (foundWnd == g_Wnds.end()) + { + // create a new CTwMgr + g_TwMgr = new CTwMgr(g_TwMasterMgr->m_GraphAPI, g_TwMasterMgr->m_Device, wndID); + g_Wnds[wndID] = g_TwMgr; + return TwInitMgr(); + } + else + { + g_TwMgr = foundWnd->second; + return 1; + } + } + else + return 1; +} + +int ANT_CALL TwWindowExists(int wndID) +{ + CTwWndMap::iterator foundWnd = g_Wnds.find(wndID); + if (foundWnd == g_Wnds.end()) + return 0; + else + return 1; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwDraw() +{ + PERF( PerfTimer Timer; double DT; ) + //CTwFPU fpu; // fpu precision only forced in update (do not modif dx draw calls) + + if( g_TwMgr==NULL || g_TwMgr->m_Graph==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + + assert(g_TwMgr->m_Bars.size()==g_TwMgr->m_Order.size()); + + // For multi-thread savety + if( !TwFreeAsyncDrawing() ) + return 0; + + // Create cursors + #if defined(ANT_WINDOWS) || defined(ANT_OSX) + if( !g_TwMgr->m_CursorsCreated ) + g_TwMgr->CreateCursors(); + #elif defined(ANT_UNIX) + if( !g_TwMgr->m_CurrentXDisplay ) + g_TwMgr->m_CurrentXDisplay = glXGetCurrentDisplay(); + if( !g_TwMgr->m_CurrentXWindow ) + g_TwMgr->m_CurrentXWindow = glXGetCurrentDrawable(); + if( g_TwMgr->m_CurrentXDisplay && !g_TwMgr->m_CursorsCreated ) + g_TwMgr->CreateCursors(); + #endif + + // Autorepeat TW_MOUSE_PRESSED + double CurrTime = g_TwMgr->m_Timer.GetTime(); + double RepeatDT = CurrTime - g_TwMgr->m_LastMousePressedTime; + double DrawDT = CurrTime - g_TwMgr->m_LastDrawTime; + if( RepeatDT>2.0*g_TwMgr->m_RepeatMousePressedDelay + || DrawDT>2.0*g_TwMgr->m_RepeatMousePressedDelay + || abs(g_TwMgr->m_LastMousePressedPosition[0]-g_TwMgr->m_LastMouseX)>4 + || abs(g_TwMgr->m_LastMousePressedPosition[1]-g_TwMgr->m_LastMouseY)>4 ) + { + g_TwMgr->m_CanRepeatMousePressed = false; + g_TwMgr->m_IsRepeatingMousePressed = false; + } + if( g_TwMgr->m_CanRepeatMousePressed ) + { + if( (!g_TwMgr->m_IsRepeatingMousePressed && RepeatDT>g_TwMgr->m_RepeatMousePressedDelay) + || (g_TwMgr->m_IsRepeatingMousePressed && RepeatDT>g_TwMgr->m_RepeatMousePressedPeriod) ) + { + g_TwMgr->m_IsRepeatingMousePressed = true; + g_TwMgr->m_LastMousePressedTime = g_TwMgr->m_Timer.GetTime(); + TwMouseButton(TW_MOUSE_PRESSED, g_TwMgr->m_LastMousePressedButtonID); + } + } + g_TwMgr->m_LastDrawTime = CurrTime; + + if( g_TwMgr->m_WndWidth<0 || g_TwMgr->m_WndHeight<0 ) + { + g_TwMgr->SetLastError(g_ErrBadSize); + return 0; + } + else if( g_TwMgr->m_WndWidth==0 || g_TwMgr->m_WndHeight==0 ) // probably iconified + return 1; // nothing to do + + // count number of bars to draw + size_t i, j; + int Nb = 0; + for( i=0; im_Bars.size(); ++i ) + if( g_TwMgr->m_Bars[i]!=NULL && g_TwMgr->m_Bars[i]->m_Visible ) + ++Nb; + + if( Nb>0 ) + { + PERF( Timer.Reset(); ) + g_TwMgr->m_Graph->BeginDraw(g_TwMgr->m_WndWidth, g_TwMgr->m_WndHeight); + PERF( DT = Timer.GetTime(); printf("\nBegin=%.4fms ", 1000.0*DT); ) + + PERF( Timer.Reset(); ) + vector TopBarsRects, ClippedBarRects; + for( i=0; im_Bars.size(); ++i ) + { + CTwBar *Bar = g_TwMgr->m_Bars[ g_TwMgr->m_Order[i] ]; + if( Bar->m_Visible ) + { + if( g_TwMgr->m_OverlapContent || Bar->IsMinimized() ) + Bar->Draw(); + else + { + // Clip overlapped transparent bars to make them more readable + const int Margin = 4; + CRect BarRect(Bar->m_PosX - Margin, Bar->m_PosY - Margin, Bar->m_Width + 2*Margin, Bar->m_Height + 2*Margin); + TopBarsRects.clear(); + for( j=i+1; jm_Bars.size(); ++j ) + { + CTwBar *TopBar = g_TwMgr->m_Bars[g_TwMgr->m_Order[j]]; + if( TopBar->m_Visible && !TopBar->IsMinimized() ) + TopBarsRects.push_back(CRect(TopBar->m_PosX, TopBar->m_PosY, TopBar->m_Width, TopBar->m_Height)); + } + ClippedBarRects.clear(); + BarRect.Subtract(TopBarsRects, ClippedBarRects); + + if( ClippedBarRects.size()==1 && ClippedBarRects[0]==BarRect ) + //g_TwMgr->m_Graph->DrawRect(Bar->m_PosX, Bar->m_PosY, Bar->m_PosX+Bar->m_Width-1, Bar->m_PosY+Bar->m_Height-1, 0x70ffffff); // Clipping test + Bar->Draw(); // unclipped + else + { + Bar->Draw(CTwBar::DRAW_BG); // draw background only + + // draw content for each clipped rectangle + for( j=0; j1 && ClippedBarRects[j].H>1) + { + g_TwMgr->m_Graph->SetScissor(ClippedBarRects[j].X+1, ClippedBarRects[j].Y, ClippedBarRects[j].W, ClippedBarRects[j].H-1); + //g_TwMgr->m_Graph->DrawRect(0, 0, 1000, 1000, 0x70ffffff); // Clipping test + Bar->Draw(CTwBar::DRAW_CONTENT); + } + g_TwMgr->m_Graph->SetScissor(0, 0, 0, 0); + } + } + } + } + PERF( DT = Timer.GetTime(); printf("Draw=%.4fms ", 1000.0*DT); ) + + PERF( Timer.Reset(); ) + g_TwMgr->m_Graph->EndDraw(); + PERF( DT = Timer.GetTime(); printf("End=%.4fms\n", 1000.0*DT); ) + } + + return 1; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwWindowSize(int _Width, int _Height) +{ + g_InitWndWidth = _Width; + g_InitWndHeight = _Height; + + if( g_TwMgr==NULL || g_TwMgr->m_Graph==NULL ) + { + //TwGlobalError(g_ErrNotInit); -> not an error here + return 0; // not initialized + } + + if( _Width<0 || _Height<0 ) + { + g_TwMgr->SetLastError(g_ErrBadSize); + return 0; + } + + // For multi-thread savety + if( !TwFreeAsyncDrawing() ) + return 0; + + // Delete the extra text objects + if( g_TwMgr->m_KeyPressedTextObj ) + { + g_TwMgr->m_Graph->DeleteTextObj(g_TwMgr->m_KeyPressedTextObj); + g_TwMgr->m_KeyPressedTextObj = NULL; + } + if( g_TwMgr->m_InfoTextObj ) + { + g_TwMgr->m_Graph->DeleteTextObj(g_TwMgr->m_InfoTextObj); + g_TwMgr->m_InfoTextObj = NULL; + } + + g_TwMgr->m_WndWidth = _Width; + g_TwMgr->m_WndHeight = _Height; + g_TwMgr->m_Graph->Restore(); + + // Recreate extra text objects + if( g_TwMgr->m_WndWidth!=0 && g_TwMgr->m_WndHeight!=0 ) + { + if( g_TwMgr->m_KeyPressedTextObj==NULL ) + { + g_TwMgr->m_KeyPressedTextObj = g_TwMgr->m_Graph->NewTextObj(); + g_TwMgr->m_KeyPressedBuildText = true; + } + if( g_TwMgr->m_InfoTextObj==NULL ) + { + g_TwMgr->m_InfoTextObj = g_TwMgr->m_Graph->NewTextObj(); + g_TwMgr->m_InfoBuildText = true; + } + } + + for( std::vector::iterator it=g_TwMgr->m_Bars.begin(); it!=g_TwMgr->m_Bars.end(); ++it ) + (*it)->NotUpToDate(); + + return 1; +} + +// --------------------------------------------------------------------------- + +CTwMgr::CTwMgr(ETwGraphAPI _GraphAPI, void *_Device, int _WndID) +{ + m_GraphAPI = _GraphAPI; + m_Device = _Device; + m_WndID = _WndID; + m_LastError = NULL; + m_CurrentDbgFile = ""; + m_CurrentDbgLine = 0; + //m_Processing = false; + m_Graph = NULL; + m_WndWidth = g_InitWndWidth; + m_WndHeight = g_InitWndHeight; + m_CurrentFont = NULL; // set after by TwIntialize + m_NbMinimizedBars = 0; + m_HelpBar = NULL; + m_HelpBarNotUpToDate = true; + m_HelpBarUpdateNow = false; + m_LastHelpUpdateTime = 0; + m_LastMouseX = -1; + m_LastMouseY = -1; + m_LastMouseWheelPos = 0; + m_IconPos = 0; + m_IconAlign = 0; + m_IconMarginX = m_IconMarginY = 8; + m_FontResizable = true; + m_KeyPressedTextObj = NULL; + m_KeyPressedBuildText = false; + m_KeyPressedTime = 0; + m_InfoTextObj = NULL; + m_InfoBuildText = true; + m_BarInitColorHue = 155; + m_PopupBar = NULL; + m_TypeColor32 = TW_TYPE_UNDEF; + m_TypeColor3F = TW_TYPE_UNDEF; + m_TypeColor4F = TW_TYPE_UNDEF; + m_LastMousePressedTime = 0; + m_LastMousePressedButtonID = TW_MOUSE_MIDDLE; + m_LastMousePressedPosition[0] = -1000; + m_LastMousePressedPosition[1] = -1000; + m_RepeatMousePressedDelay = 0.5; + m_RepeatMousePressedPeriod = 0.1; + m_CanRepeatMousePressed = false; + m_IsRepeatingMousePressed = false; + m_LastDrawTime = 0; + m_UseOldColorScheme = false; + m_Contained = false; + m_ButtonAlign = BUTTON_ALIGN_RIGHT; + m_OverlapContent = false; + m_Terminating = false; + + m_CursorsCreated = false; + #if defined(ANT_UNIX) + m_CurrentXDisplay = NULL; + m_CurrentXWindow = 0; + #endif // defined(ANT_UNIX) + + m_CopyCDStringToClient = g_InitCopyCDStringToClient; + m_CopyStdStringToClient = g_InitCopyStdStringToClient; + m_ClientStdStringStructSize = 0; + m_ClientStdStringBaseType = (TwType)0; +} + +// --------------------------------------------------------------------------- + +CTwMgr::~CTwMgr() +{ +} + +// --------------------------------------------------------------------------- + +int CTwMgr::FindBar(const char *_Name) const +{ + if( _Name==NULL || strlen(_Name)<=0 ) + return -1; + int i; + for( i=0; i<(int)m_Bars.size(); ++i ) + if( m_Bars[i]!=NULL && strcmp(_Name, m_Bars[i]->m_Name.c_str())==0 ) + return i; + return -1; +} + + +// --------------------------------------------------------------------------- + +int CTwMgr::HasAttrib(const char *_Attrib, bool *_HasValue) const +{ + *_HasValue = true; + if( _stricmp(_Attrib, "help")==0 ) + return MGR_HELP; + else if( _stricmp(_Attrib, "fontsize")==0 ) + return MGR_FONT_SIZE; + else if( _stricmp(_Attrib, "fontstyle")==0 ) + return MGR_FONT_STYLE; + else if( _stricmp(_Attrib, "iconpos")==0 ) + return MGR_ICON_POS; + else if( _stricmp(_Attrib, "iconalign")==0 ) + return MGR_ICON_ALIGN; + else if( _stricmp(_Attrib, "iconmargin")==0 ) + return MGR_ICON_MARGIN; + else if( _stricmp(_Attrib, "fontresizable")==0 ) + return MGR_FONT_RESIZABLE; + else if( _stricmp(_Attrib, "colorscheme")==0 ) + return MGR_COLOR_SCHEME; + else if( _stricmp(_Attrib, "contained")==0 ) + return MGR_CONTAINED; + else if( _stricmp(_Attrib, "buttonalign")==0 ) + return MGR_BUTTON_ALIGN; + else if( _stricmp(_Attrib, "overlap")==0 ) + return MGR_OVERLAP; + + *_HasValue = false; + return 0; // not found +} + +int CTwMgr::SetAttrib(int _AttribID, const char *_Value) +{ + switch( _AttribID ) + { + case MGR_HELP: + if( _Value && strlen(_Value)>0 ) + { + m_Help = _Value; + m_HelpBarNotUpToDate = true; + return 1; + } + else + { + SetLastError(g_ErrNoValue); + return 0; + } + case MGR_FONT_SIZE: + if( _Value && strlen(_Value)>0 ) + { + int s; + int n = sscanf(_Value, "%d", &s); + if( n==1 && s>=1 && s<=3 ) + { + if( s==1 ) + SetFont(g_DefaultSmallFont, true); + else if( s==2 ) + SetFont(g_DefaultNormalFont, true); + else if( s==3 ) + SetFont(g_DefaultLargeFont, true); + return 1; + } + else + { + SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + SetLastError(g_ErrNoValue); + return 0; + } + case MGR_FONT_STYLE: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "fixed")==0 ) + { + if( m_CurrentFont!=g_DefaultFixed1Font ) + { + SetFont(g_DefaultFixed1Font, true); + m_FontResizable = false; // for now fixed font is not resizable + } + return 1; + } + else if( _stricmp(_Value, "default")==0 ) + { + if( m_CurrentFont!=g_DefaultSmallFont && m_CurrentFont!=g_DefaultNormalFont && m_CurrentFont!=g_DefaultLargeFont ) + { + if( m_CurrentFont == g_DefaultFixed1Font ) + m_FontResizable = true; + SetFont(g_DefaultNormalFont, true); + } + return 1; + } + else + { + SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + SetLastError(g_ErrNoValue); + return 0; + } + case MGR_ICON_POS: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "bl")==0 || _stricmp(_Value, "lb")==0 || _stricmp(_Value, "bottomleft")==0 || _stricmp(_Value, "leftbottom")==0 ) + { + m_IconPos = 0; + return 1; + } + else if( _stricmp(_Value, "br")==0 || _stricmp(_Value, "rb")==0 || _stricmp(_Value, "bottomright")==0 || _stricmp(_Value, "rightbottom")==0 ) + { + m_IconPos = 1; + return 1; + } + else if( _stricmp(_Value, "tl")==0 || _stricmp(_Value, "lt")==0 || _stricmp(_Value, "topleft")==0 || _stricmp(_Value, "lefttop")==0 ) + { + m_IconPos = 2; + return 1; + } + else if( _stricmp(_Value, "tr")==0 || _stricmp(_Value, "rt")==0 || _stricmp(_Value, "topright")==0 || _stricmp(_Value, "righttop")==0 ) + { + m_IconPos = 3; + return 1; + } + else + { + SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + SetLastError(g_ErrNoValue); + return 0; + } + case MGR_ICON_ALIGN: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "vert")==0 || _stricmp(_Value, "vertical")==0 ) + { + m_IconAlign = 0; + return 1; + } + else if( _stricmp(_Value, "horiz")==0 || _stricmp(_Value, "horizontal")==0 ) + { + m_IconAlign = 1; + return 1; + } + else + { + SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + SetLastError(g_ErrNoValue); + return 0; + } + case MGR_ICON_MARGIN: + if( _Value && strlen(_Value)>0 ) + { + int x, y; + int n = sscanf(_Value, "%d%d", &x, &y); + if( n==2 && x>=0 && y>=0 ) + { + m_IconMarginX = x; + m_IconMarginY = y; + return 1; + } + else + { + SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + SetLastError(g_ErrNoValue); + return 0; + } + case MGR_FONT_RESIZABLE: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + m_FontResizable = true; + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + m_FontResizable = false; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case MGR_COLOR_SCHEME: + if( _Value && strlen(_Value)>0 ) + { + int s; + int n = sscanf(_Value, "%d", &s); + if( n==1 && s>=0 && s<=1 ) + { + if( s==0 ) + m_UseOldColorScheme = true; + else + m_UseOldColorScheme = false; + return 1; + } + else + { + SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case MGR_CONTAINED: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + m_Contained = true; + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + m_Contained = false; + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + vector::iterator barIt; + for( barIt=g_TwMgr->m_Bars.begin(); barIt!=g_TwMgr->m_Bars.end(); ++barIt ) + if( (*barIt)!=NULL ) + (*barIt)->m_Contained = m_Contained; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case MGR_BUTTON_ALIGN: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "left")==0 ) + m_ButtonAlign = BUTTON_ALIGN_LEFT; + else if( _stricmp(_Value, "center")==0 ) + m_ButtonAlign = BUTTON_ALIGN_CENTER; + else if( _stricmp(_Value, "right")==0 ) + m_ButtonAlign = BUTTON_ALIGN_RIGHT; + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + vector::iterator barIt; + for( barIt=g_TwMgr->m_Bars.begin(); barIt!=g_TwMgr->m_Bars.end(); ++barIt ) + if( (*barIt)!=NULL ) + (*barIt)->m_ButtonAlign = m_ButtonAlign; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + case MGR_OVERLAP: + if( _Value && strlen(_Value)>0 ) + { + if( _stricmp(_Value, "1")==0 || _stricmp(_Value, "true")==0 ) + { + m_OverlapContent = true; + return 1; + } + else if( _stricmp(_Value, "0")==0 || _stricmp(_Value, "false")==0 ) + { + m_OverlapContent = false; + return 1; + } + else + { + g_TwMgr->SetLastError(g_ErrBadValue); + return 0; + } + } + else + { + g_TwMgr->SetLastError(g_ErrNoValue); + return 0; + } + default: + g_TwMgr->SetLastError(g_ErrUnknownAttrib); + return 0; + } +} + +ERetType CTwMgr::GetAttrib(int _AttribID, std::vector& outDoubles, std::ostringstream& outString) const +{ + outDoubles.clear(); + outString.clear(); + + switch( _AttribID ) + { + case MGR_HELP: + outString << m_Help; + return RET_STRING; + case MGR_FONT_SIZE: + if( m_CurrentFont==g_DefaultSmallFont ) + outDoubles.push_back(1); + else if( m_CurrentFont==g_DefaultNormalFont ) + outDoubles.push_back(2); + else if( m_CurrentFont==g_DefaultLargeFont ) + outDoubles.push_back(3); + else + outDoubles.push_back(0); // should not happened + return RET_DOUBLE; + case MGR_FONT_STYLE: + if( m_CurrentFont==g_DefaultFixed1Font ) + outString << "fixed"; + else + outString << "default"; + return RET_STRING; + case MGR_ICON_POS: + if( m_IconPos==0 ) + outString << "bottomleft"; + else if( m_IconPos==1 ) + outString << "bottomright"; + else if( m_IconPos==2 ) + outString << "topleft"; + else if( m_IconPos==3 ) + outString << "topright"; + else + outString << "undefined"; // should not happened + return RET_STRING; + case MGR_ICON_ALIGN: + if( m_IconAlign==0 ) + outString << "vertical"; + else if( m_IconAlign==1 ) + outString << "horizontal"; + else + outString << "undefined"; // should not happened + return RET_STRING; + case MGR_ICON_MARGIN: + outDoubles.push_back(m_IconMarginX); + outDoubles.push_back(m_IconMarginY); + return RET_DOUBLE; + case MGR_FONT_RESIZABLE: + outDoubles.push_back(m_FontResizable); + return RET_DOUBLE; + case MGR_COLOR_SCHEME: + outDoubles.push_back(m_UseOldColorScheme ? 0 : 1); + return RET_DOUBLE; + case MGR_CONTAINED: + { + bool contained = m_Contained; + /* + if( contained ) + { + vector::iterator barIt; + for( barIt=g_TwMgr->m_Bars.begin(); barIt!=g_TwMgr->m_Bars.end(); ++barIt ) + if( (*barIt)!=NULL && !(*barIt)->m_Contained ) + { + contained = false; + break; + } + } + */ + outDoubles.push_back(contained); + return RET_DOUBLE; + } + case MGR_BUTTON_ALIGN: + if( m_ButtonAlign==BUTTON_ALIGN_LEFT ) + outString << "left"; + else if( m_ButtonAlign==BUTTON_ALIGN_CENTER ) + outString << "center"; + else + outString << "right"; + return RET_STRING; + case MGR_OVERLAP: + outDoubles.push_back(m_OverlapContent); + return RET_DOUBLE; + default: + g_TwMgr->SetLastError(g_ErrUnknownAttrib); + return RET_ERROR; + } +} + +// --------------------------------------------------------------------------- + +void CTwMgr::Minimize(TwBar *_Bar) +{ + assert(m_Graph!=NULL && _Bar!=NULL); + assert(m_Bars.size()==m_MinOccupied.size()); + if( _Bar->m_IsMinimized ) + return; + if( _Bar->m_Visible ) + { + size_t i = m_NbMinimizedBars; + m_NbMinimizedBars++; + for( i=0; im_MinNumber = (int)i; + } + else + _Bar->m_MinNumber = -1; + _Bar->m_IsMinimized = true; + _Bar->NotUpToDate(); +} + +// --------------------------------------------------------------------------- + +void CTwMgr::Maximize(TwBar *_Bar) +{ + assert(m_Graph!=NULL && _Bar!=NULL); + assert(m_Bars.size()==m_MinOccupied.size()); + if( !_Bar->m_IsMinimized ) + return; + if( _Bar->m_Visible ) + { + --m_NbMinimizedBars; + if( m_NbMinimizedBars<0 ) + m_NbMinimizedBars = 0; + if( _Bar->m_MinNumber>=0 && _Bar->m_MinNumber<(int)m_MinOccupied.size() ) + m_MinOccupied[_Bar->m_MinNumber] = false; + } + _Bar->m_IsMinimized = false; + _Bar->NotUpToDate(); + if( _Bar->m_IsHelpBar ) + m_HelpBarNotUpToDate = true; +} + +// --------------------------------------------------------------------------- + +void CTwMgr::Hide(TwBar *_Bar) +{ + assert(m_Graph!=NULL && _Bar!=NULL); + if( !_Bar->m_Visible ) + return; + if( _Bar->IsMinimized() ) + { + Maximize(_Bar); + _Bar->m_Visible = false; + Minimize(_Bar); + } + else + _Bar->m_Visible = false; + if( !_Bar->m_IsHelpBar ) + m_HelpBarNotUpToDate = true; +} + +// --------------------------------------------------------------------------- + +void CTwMgr::Unhide(TwBar *_Bar) +{ + assert(m_Graph!=NULL && _Bar!=NULL); + if( _Bar->m_Visible ) + return; + if( _Bar->IsMinimized() ) + { + Maximize(_Bar); + _Bar->m_Visible = true; + Minimize(_Bar); + } + else + _Bar->m_Visible = true; + _Bar->NotUpToDate(); + if( !_Bar->m_IsHelpBar ) + m_HelpBarNotUpToDate = true; +} + +// --------------------------------------------------------------------------- + +void CTwMgr::SetFont(const CTexFont *_Font, bool _ResizeBars) +{ + assert(m_Graph!=NULL); + assert(_Font!=NULL); + + m_CurrentFont = _Font; + + for( int i=0; i<(int)m_Bars.size(); ++i ) + if( m_Bars[i]!=NULL ) + { + int fh = m_Bars[i]->m_Font->m_CharHeight; + m_Bars[i]->m_Font = _Font; + if( _ResizeBars ) + { + if( m_Bars[i]->m_Movable ) + { + m_Bars[i]->m_PosX += (3*(fh-_Font->m_CharHeight))/2; + m_Bars[i]->m_PosY += (fh-_Font->m_CharHeight)/2; + } + if( m_Bars[i]->m_Resizable ) + { + m_Bars[i]->m_Width = (m_Bars[i]->m_Width*_Font->m_CharHeight)/fh; + m_Bars[i]->m_Height = (m_Bars[i]->m_Height*_Font->m_CharHeight)/fh; + m_Bars[i]->m_ValuesWidth = (m_Bars[i]->m_ValuesWidth*_Font->m_CharHeight)/fh; + } + } + m_Bars[i]->NotUpToDate(); + } + + if( g_TwMgr->m_HelpBar!=NULL ) + g_TwMgr->m_HelpBar->Update(); + g_TwMgr->m_InfoBuildText = true; + g_TwMgr->m_KeyPressedBuildText = true; + m_HelpBarNotUpToDate = true; +} + +// --------------------------------------------------------------------------- + +void ANT_CALL TwGlobalError(const char *_ErrorMessage) // to be called when g_TwMasterMgr is not created +{ + if( g_ErrorHandler==NULL ) + { + fprintf(stderr, "ERROR(AntTweakBar) >> %s\n", _ErrorMessage); + #ifdef ANT_WINDOWS + OutputDebugString("ERROR(AntTweakBar) >> "); + OutputDebugString(_ErrorMessage); + OutputDebugString("\n"); + #endif // ANT_WINDOWS + } + else + g_ErrorHandler(_ErrorMessage); + + if( g_BreakOnError ) + abort(); +} + +// --------------------------------------------------------------------------- + +void CTwMgr::SetLastError(const char *_ErrorMessage) // _ErrorMessage must be a static string +{ + if (this != g_TwMasterMgr) + { + // route to master + g_TwMasterMgr->SetLastError(_ErrorMessage); + return; + } + + m_LastError = _ErrorMessage; + + if( g_ErrorHandler==NULL ) + { + if( m_CurrentDbgFile!=NULL && strlen(m_CurrentDbgFile)>0 && m_CurrentDbgLine>0 ) + fprintf(stderr, "%s(%d): ", m_CurrentDbgFile, m_CurrentDbgLine); + fprintf(stderr, "ERROR(AntTweakBar) >> %s\n", m_LastError); + #ifdef ANT_WINDOWS + if( m_CurrentDbgFile!=NULL && strlen(m_CurrentDbgFile)>0 && m_CurrentDbgLine>0 ) + { + OutputDebugString(m_CurrentDbgFile); + char sl[32]; + sprintf(sl, "(%d): ", m_CurrentDbgLine); + OutputDebugString(sl); + } + OutputDebugString("ERROR(AntTweakBar) >> "); + OutputDebugString(m_LastError); + OutputDebugString("\n"); + #endif // ANT_WINDOWS + } + else + g_ErrorHandler(_ErrorMessage); + + if( g_BreakOnError ) + abort(); +} + +// --------------------------------------------------------------------------- + +const char *CTwMgr::GetLastError() +{ + if (this != g_TwMasterMgr) + { + // route to master + return g_TwMasterMgr->GetLastError(); + } + + const char *Err = m_LastError; + m_LastError = NULL; + return Err; +} + +// --------------------------------------------------------------------------- + +const char *CTwMgr::CheckLastError() const +{ + return m_LastError; +} + +// --------------------------------------------------------------------------- + +void CTwMgr::SetCurrentDbgParams(const char *dbgFile, int dbgLine) +{ + m_CurrentDbgFile = dbgFile; + m_CurrentDbgLine = dbgLine; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL __TwDbg(const char *dbgFile, int dbgLine) +{ + if( g_TwMgr!=NULL ) + g_TwMgr->SetCurrentDbgParams(dbgFile, dbgLine); + return 0; // always returns zero +} + +// --------------------------------------------------------------------------- + +void ANT_CALL TwHandleErrors(TwErrorHandler _ErrorHandler, int _BreakOnError) +{ + g_ErrorHandler = _ErrorHandler; + g_BreakOnError = (_BreakOnError) ? true : false; +} + +void ANT_CALL TwHandleErrors(TwErrorHandler _ErrorHandler) +{ + TwHandleErrors(_ErrorHandler, false); +} + +// --------------------------------------------------------------------------- + +const char *ANT_CALL TwGetLastError() +{ + if( g_TwMasterMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return g_ErrNotInit; + } + else + return g_TwMasterMgr->GetLastError(); +} + +// --------------------------------------------------------------------------- + +TwBar *ANT_CALL TwNewBar(const char *_Name) +{ + if( g_TwMgr==NULL || g_TwMgr->m_Graph==NULL ) + { + TwGlobalError(g_ErrNotInit); + return NULL; // not initialized + } + + TwFreeAsyncDrawing(); // For multi-thread savety + + if( _Name==NULL || strlen(_Name)<=0 ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return NULL; + } + if( g_TwMgr->FindBar(_Name)>=0 ) + { + g_TwMgr->SetLastError(g_ErrExist); + return NULL; + } + + if( strstr(_Name, "`")!=NULL ) + { + g_TwMgr->SetLastError(g_ErrNoBackQuote); + return NULL; + } + + if( g_TwMgr->m_PopupBar!=NULL ) // delete popup bar if it exists + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + + TwBar *Bar = new CTwBar(_Name); + g_TwMgr->m_Bars.push_back(Bar); + g_TwMgr->m_Order.push_back((int)g_TwMgr->m_Bars.size()-1); + g_TwMgr->m_MinOccupied.push_back(false); + g_TwMgr->m_HelpBarNotUpToDate = true; + + return Bar; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwDeleteBar(TwBar *_Bar) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( _Bar==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + if( _Bar==g_TwMgr->m_HelpBar ) + { + g_TwMgr->SetLastError(g_ErrDelHelp); + return 0; + } + + TwFreeAsyncDrawing(); // For multi-thread savety + + vector::iterator BarIt; + int i = 0; + for( BarIt=g_TwMgr->m_Bars.begin(); BarIt!=g_TwMgr->m_Bars.end(); ++BarIt, ++i ) + if( (*BarIt)==_Bar ) + break; + if( BarIt==g_TwMgr->m_Bars.end() ) + { + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; + } + + if( g_TwMgr->m_PopupBar!=NULL && _Bar!=g_TwMgr->m_PopupBar ) // delete popup bar first if it exists + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + + // force bar to un-minimize + g_TwMgr->Maximize(_Bar); + // find an empty MinOccupied + vector::iterator itm; + int j = 0; + for( itm=g_TwMgr->m_MinOccupied.begin(); itm!=g_TwMgr->m_MinOccupied.end(); ++itm, ++j) + if( (*itm)==false ) + break; + assert( itm!=g_TwMgr->m_MinOccupied.end() ); + // shift MinNumbers and erase the empty MinOccupied + for( size_t k=0; km_Bars.size(); ++k ) + if( g_TwMgr->m_Bars[k]!=NULL && g_TwMgr->m_Bars[k]->m_MinNumber>j ) + g_TwMgr->m_Bars[k]->m_MinNumber -= 1; + g_TwMgr->m_MinOccupied.erase(itm); + // erase _Bar order + vector::iterator BarOrderIt = g_TwMgr->m_Order.end(); + for(vector::iterator it=g_TwMgr->m_Order.begin(); it!=g_TwMgr->m_Order.end(); ++it ) + if( (*it)==i ) + BarOrderIt = it; + else if( (*it)>i ) + (*it) -= 1; + assert( BarOrderIt!=g_TwMgr->m_Order.end() ); + g_TwMgr->m_Order.erase(BarOrderIt); + + // erase & delete _Bar + g_TwMgr->m_Bars.erase(BarIt); + delete _Bar; + + g_TwMgr->m_HelpBarNotUpToDate = true; + return 1; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwDeleteAllBars() +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + + TwFreeAsyncDrawing(); // For multi-thread savety + + int n = 0; + if( g_TwMgr->m_Terminating || g_TwMgr->m_HelpBar==NULL ) + { + for( size_t i=0; im_Bars.size(); ++i ) + if( g_TwMgr->m_Bars[i]!=NULL ) + { + ++n; + delete g_TwMgr->m_Bars[i]; + g_TwMgr->m_Bars[i] = NULL; + } + g_TwMgr->m_Bars.clear(); + g_TwMgr->m_Order.clear(); + g_TwMgr->m_MinOccupied.clear(); + g_TwMgr->m_HelpBarNotUpToDate = true; + } + else + { + vector bars = g_TwMgr->m_Bars; + for( size_t i = 0; i < bars.size(); ++i ) + if( bars[i]!=0 && bars[i]!=g_TwMgr->m_HelpBar) + { + ++n; + TwDeleteBar(bars[i]); + } + g_TwMgr->m_HelpBarNotUpToDate = true; + } + + if( n==0 ) + { + //g_TwMgr->SetLastError(g_ErrNthToDo); + return 0; + } + else + return 1; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwSetTopBar(const TwBar *_Bar) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( _Bar==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + TwFreeAsyncDrawing(); // For multi-thread savety + + if( _Bar!=g_TwMgr->m_PopupBar && g_TwMgr->m_BarAlwaysOnBottom.length()>0 ) + { + if( strcmp(_Bar->m_Name.c_str(), g_TwMgr->m_BarAlwaysOnBottom.c_str())==0 ) + return TwSetBottomBar(_Bar); + } + + int i = -1, iOrder; + for( iOrder=0; iOrder<(int)g_TwMgr->m_Bars.size(); ++iOrder ) + { + i = g_TwMgr->m_Order[iOrder]; + assert( i>=0 && i<(int)g_TwMgr->m_Bars.size() ); + if( g_TwMgr->m_Bars[i]==_Bar ) + break; + } + if( i<0 || iOrder>=(int)g_TwMgr->m_Bars.size() ) // bar not found + { + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; + } + + for( int j=iOrder; j<(int)g_TwMgr->m_Bars.size()-1; ++j ) + g_TwMgr->m_Order[j] = g_TwMgr->m_Order[j+1]; + g_TwMgr->m_Order[(int)g_TwMgr->m_Bars.size()-1] = i; + + if( _Bar!=g_TwMgr->m_PopupBar && g_TwMgr->m_BarAlwaysOnTop.length()>0 ) + { + int topIdx = g_TwMgr->FindBar(g_TwMgr->m_BarAlwaysOnTop.c_str()); + TwBar *top = (topIdx>=0 && topIdx<(int)g_TwMgr->m_Bars.size()) ? g_TwMgr->m_Bars[topIdx] : NULL; + if( top!=NULL && top!=_Bar ) + TwSetTopBar(top); + } + + if( g_TwMgr->m_PopupBar!=NULL && _Bar!=g_TwMgr->m_PopupBar ) + TwSetTopBar(g_TwMgr->m_PopupBar); + + return 1; +} + +// --------------------------------------------------------------------------- + +TwBar * ANT_CALL TwGetTopBar() +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return NULL; // not initialized + } + + if( g_TwMgr->m_Bars.size()>0 && g_TwMgr->m_PopupBar==NULL ) + return g_TwMgr->m_Bars[g_TwMgr->m_Order[ g_TwMgr->m_Bars.size()-1 ]]; + else if( g_TwMgr->m_Bars.size()>1 && g_TwMgr->m_PopupBar!=NULL ) + return g_TwMgr->m_Bars[g_TwMgr->m_Order[ g_TwMgr->m_Bars.size()-2 ]]; + else + return NULL; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwSetBottomBar(const TwBar *_Bar) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( _Bar==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + TwFreeAsyncDrawing(); // For multi-thread savety + + if( _Bar!=g_TwMgr->m_PopupBar && g_TwMgr->m_BarAlwaysOnTop.length()>0 ) + { + if( strcmp(_Bar->m_Name.c_str(), g_TwMgr->m_BarAlwaysOnTop.c_str())==0 ) + return TwSetTopBar(_Bar); + } + + int i = -1, iOrder; + for( iOrder=0; iOrder<(int)g_TwMgr->m_Bars.size(); ++iOrder ) + { + i = g_TwMgr->m_Order[iOrder]; + assert( i>=0 && i<(int)g_TwMgr->m_Bars.size() ); + if( g_TwMgr->m_Bars[i]==_Bar ) + break; + } + if( i<0 || iOrder>=(int)g_TwMgr->m_Bars.size() ) // bar not found + { + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; + } + + if( iOrder>0 ) + for( int j=iOrder-1; j>=0; --j ) + g_TwMgr->m_Order[j+1] = g_TwMgr->m_Order[j]; + g_TwMgr->m_Order[0] = i; + + if( _Bar!=g_TwMgr->m_PopupBar && g_TwMgr->m_BarAlwaysOnBottom.length()>0 ) + { + int btmIdx = g_TwMgr->FindBar(g_TwMgr->m_BarAlwaysOnBottom.c_str()); + TwBar *btm = (btmIdx>=0 && btmIdx<(int)g_TwMgr->m_Bars.size()) ? g_TwMgr->m_Bars[btmIdx] : NULL; + if( btm!=NULL && btm!=_Bar ) + TwSetBottomBar(btm); + } + + return 1; +} + +// --------------------------------------------------------------------------- + +TwBar* ANT_CALL TwGetBottomBar() +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return NULL; // not initialized + } + + if( g_TwMgr->m_Bars.size()>0 ) + return g_TwMgr->m_Bars[g_TwMgr->m_Order[0]]; + else + return NULL; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwSetBarState(TwBar *_Bar, TwState _State) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( _Bar==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + TwFreeAsyncDrawing(); // For multi-thread savety + + switch( _State ) + { + case TW_STATE_SHOWN: + g_TwMgr->Unhide(_Bar); + return 1; + case TW_STATE_ICONIFIED: + //g_TwMgr->Unhide(_Bar); + g_TwMgr->Minimize(_Bar); + return 1; + case TW_STATE_HIDDEN: + //g_TwMgr->Maximize(_Bar); + g_TwMgr->Hide(_Bar); + return 1; + case TW_STATE_UNICONIFIED: + //g_TwMgr->Unhide(_Bar); + g_TwMgr->Maximize(_Bar); + return 1; + default: + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } +} + +// --------------------------------------------------------------------------- + +/* +TwState ANT_CALL TwGetBarState(const TwBar *_Bar) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return TW_STATE_ERROR; // not initialized + } + if( _Bar==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return TW_STATE_ERROR; + } + + if( !_Bar->m_Visible ) + return TW_STATE_HIDDEN; + else if( _Bar->IsMinimized() ) + return TW_STATE_ICONIFIED; + else + return TW_STATE_SHOWN; +} +*/ + +// --------------------------------------------------------------------------- + +const char * ANT_CALL TwGetBarName(TwBar *_Bar) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return NULL; // not initialized + } + if( _Bar==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return NULL; + } + vector::iterator BarIt; + int i = 0; + for( BarIt=g_TwMgr->m_Bars.begin(); BarIt!=g_TwMgr->m_Bars.end(); ++BarIt, ++i ) + if( (*BarIt)==_Bar ) + break; + if( BarIt==g_TwMgr->m_Bars.end() ) + { + g_TwMgr->SetLastError(g_ErrNotFound); + return NULL; + } + + return _Bar->m_Name.c_str(); +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwGetBarCount() +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + + return (int)g_TwMgr->m_Bars.size(); +} + + +// --------------------------------------------------------------------------- + +TwBar * ANT_CALL TwGetBarByIndex(int index) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return NULL; // not initialized + } + + if( index>=0 && index<(int)g_TwMgr->m_Bars.size() ) + return g_TwMgr->m_Bars[index]; + else + { + g_TwMgr->SetLastError(g_ErrOutOfRange); + return NULL; + } +} + +// --------------------------------------------------------------------------- + +TwBar * ANT_CALL TwGetBarByName(const char *name) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return NULL; // not initialized + } + + int idx = g_TwMgr->FindBar(name); + if ( idx>=0 && idx<(int)g_TwMgr->m_Bars.size() ) + return g_TwMgr->m_Bars[idx]; + else + return NULL; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwRefreshBar(TwBar *bar) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( bar==NULL ) + { + vector::iterator BarIt; + for( BarIt=g_TwMgr->m_Bars.begin(); BarIt!=g_TwMgr->m_Bars.end(); ++BarIt ) + if( *BarIt!=NULL ) + (*BarIt)->NotUpToDate(); + } + else + { + vector::iterator BarIt; + int i = 0; + for( BarIt=g_TwMgr->m_Bars.begin(); BarIt!=g_TwMgr->m_Bars.end(); ++BarIt, ++i ) + if( (*BarIt)==bar ) + break; + if( BarIt==g_TwMgr->m_Bars.end() ) + { + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; + } + + bar->NotUpToDate(); + } + return 1; +} + +// --------------------------------------------------------------------------- + +int BarVarHasAttrib(CTwBar *_Bar, CTwVar *_Var, const char *_Attrib, bool *_HasValue); +int BarVarSetAttrib(CTwBar *_Bar, CTwVar *_Var, CTwVarGroup *_VarParent, int _VarIndex, int _AttribID, const char *_Value); +ERetType BarVarGetAttrib(CTwBar *_Bar, CTwVar *_Var, CTwVarGroup *_VarParent, int _VarIndex, int _AttribID, std::vector& outDouble, std::ostringstream& outString); + + +int ANT_CALL TwGetParam(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int outValueMaxCount, void *outValues) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( paramName==NULL || strlen(paramName)<=0 ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + if( outValueMaxCount<=0 || outValues==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + if( bar==NULL ) + bar = TW_GLOBAL_BAR; + else + { + vector::iterator barIt; + int i = 0; + for( barIt=g_TwMgr->m_Bars.begin(); barIt!=g_TwMgr->m_Bars.end(); ++barIt, ++i ) + if( (*barIt)==bar ) + break; + if( barIt==g_TwMgr->m_Bars.end() ) + { + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; + } + } + CTwVarGroup *varParent = NULL; + int varIndex = -1; + CTwVar *var = NULL; + if( varName!=NULL && strlen(varName)>0 ) + { + var = bar->Find(varName, &varParent, &varIndex); + if( var==NULL ) + { + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Unknown var '%s/%s'", + (bar==TW_GLOBAL_BAR) ? "GLOBAL" : bar->m_Name.c_str(), varName); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + } + + bool hasValue = false; + int paramID = BarVarHasAttrib(bar, var, paramName, &hasValue); + if( paramID>0 ) + { + std::ostringstream valStr; + std::vector valDbl; + const char *PrevLastErrorPtr = g_TwMgr->CheckLastError(); + + ERetType retType = BarVarGetAttrib(bar, var, varParent, varIndex, paramID, valDbl, valStr); + unsigned int i, valDblCount = (unsigned int)valDbl.size(); + if( valDblCount > outValueMaxCount ) + valDblCount = outValueMaxCount; + if( retType==RET_DOUBLE && valDblCount==0 ) + { + g_TwMgr->SetLastError(g_ErrHasNoValue); + retType = RET_ERROR; + } + + if( retType==RET_DOUBLE ) + { + switch( paramValueType ) + { + case TW_PARAM_INT32: + for( i=0; i(outValues))[i] = (int)valDbl[i]; + return valDblCount; + case TW_PARAM_FLOAT: + for( i=0; i(outValues))[i] = (float)valDbl[i]; + return valDblCount; + case TW_PARAM_DOUBLE: + for( i=0; i(outValues))[i] = valDbl[i]; + return valDblCount; + case TW_PARAM_CSTRING: + valStr.clear(); + for( i=0; i<(unsigned int)valDbl.size(); i++ ) // not valDblCount here + valStr << ((i>0) ? " " : "") << valDbl[i]; + strncpy(static_cast(outValues), valStr.str().c_str(), outValueMaxCount); + i = (unsigned int)valStr.str().size(); + if( i>outValueMaxCount-1 ) + i = outValueMaxCount-1; + (static_cast(outValues))[i] = '\0'; + return 1; // always returns 1 for CSTRING + default: + g_TwMgr->SetLastError(g_ErrBadParam); // Unknown param value type + retType = RET_ERROR; + } + } + else if( retType==RET_STRING ) + { + if( paramValueType == TW_PARAM_CSTRING ) + { + strncpy(static_cast(outValues), valStr.str().c_str(), outValueMaxCount); + i = (unsigned int)valStr.str().size(); + if( i>outValueMaxCount-1 ) + i = outValueMaxCount-1; + (static_cast(outValues))[i] = '\0'; + return 1; // always returns 1 for CSTRING + } + else + { + g_TwMgr->SetLastError(g_ErrBadType); // string cannot be converted to int or double + retType = RET_ERROR; + } + } + + if( retType==RET_ERROR ) + { + bool errMsg = (g_TwMgr->CheckLastError()!=NULL && strlen(g_TwMgr->CheckLastError())>0 && PrevLastErrorPtr!=g_TwMgr->CheckLastError()); + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Unable to get param '%s%s%s %s' %s%s", + (bar==TW_GLOBAL_BAR) ? "GLOBAL" : bar->m_Name.c_str(), (var!=NULL) ? "/" : "", + (var!=NULL) ? varName : "", paramName, errMsg ? " : " : "", + errMsg ? g_TwMgr->CheckLastError() : ""); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + } + return retType; + } + else + { + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Unknown param '%s%s%s %s'", + (bar==TW_GLOBAL_BAR) ? "GLOBAL" : bar->m_Name.c_str(), + (var!=NULL) ? "/" : "", (var!=NULL) ? varName : "", paramName); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } +} + + +int ANT_CALL TwSetParam(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int inValueCount, const void *inValues) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( paramName==NULL || strlen(paramName)<=0 ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + if( inValueCount>0 && inValues==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + TwFreeAsyncDrawing(); // For multi-thread savety + + if( bar==NULL ) + bar = TW_GLOBAL_BAR; + else + { + vector::iterator barIt; + int i = 0; + for( barIt=g_TwMgr->m_Bars.begin(); barIt!=g_TwMgr->m_Bars.end(); ++barIt, ++i ) + if( (*barIt)==bar ) + break; + if( barIt==g_TwMgr->m_Bars.end() ) + { + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; + } + } + CTwVarGroup *varParent = NULL; + int varIndex = -1; + CTwVar *var = NULL; + if( varName!=NULL && strlen(varName)>0 ) + { + var = bar->Find(varName, &varParent, &varIndex); + if( var==NULL ) + { + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Unknown var '%s/%s'", + (bar==TW_GLOBAL_BAR) ? "GLOBAL" : bar->m_Name.c_str(), varName); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + } + + bool hasValue = false; + int paramID = BarVarHasAttrib(bar, var, paramName, &hasValue); + if( paramID>0 ) + { + int ret = 0; + const char *PrevLastErrorPtr = g_TwMgr->CheckLastError(); + if( hasValue ) + { + std::ostringstream valuesStr; + unsigned int i; + switch( paramValueType ) + { + case TW_PARAM_INT32: + for( i=0; i(inValues))[i] << ((i(inValues))[i] << ((i(inValues))[i] << ((i(inValues))[i]; + for( const char *ch = str; *ch!=0; ch++ ) + if( *ch=='`' ) + valuesStr << "`'`'`"; + else + valuesStr << *ch; + valuesStr << "` "; + } + */ + if( inValueCount!=1 ) + { + g_TwMgr->SetLastError(g_ErrCStrParam); // count for CString param must be 1 + return 0; + } + else + valuesStr << static_cast(inValues); + break; + default: + g_TwMgr->SetLastError(g_ErrBadParam); // Unknown param value type + return 0; + } + ret = BarVarSetAttrib(bar, var, varParent, varIndex, paramID, valuesStr.str().c_str()); + } + else + ret = BarVarSetAttrib(bar, var, varParent, varIndex, paramID, NULL); + if( ret==0 ) + { + bool errMsg = (g_TwMgr->CheckLastError()!=NULL && strlen(g_TwMgr->CheckLastError())>0 && PrevLastErrorPtr!=g_TwMgr->CheckLastError()); + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Unable to set param '%s%s%s %s' %s%s", + (bar==TW_GLOBAL_BAR) ? "GLOBAL" : bar->m_Name.c_str(), (var!=NULL) ? "/" : "", + (var!=NULL) ? varName : "", paramName, errMsg ? " : " : "", + errMsg ? g_TwMgr->CheckLastError() : ""); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + } + return ret; + } + else + { + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Unknown param '%s%s%s %s'", + (bar==TW_GLOBAL_BAR) ? "GLOBAL" : bar->m_Name.c_str(), + (var!=NULL) ? "/" : "", (var!=NULL) ? varName : "", paramName); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } +} + +// --------------------------------------------------------------------------- + +static int s_PassProxy = 0; +void *CTwMgr::CStruct::s_PassProxyAsClientData = &s_PassProxy; // special tag + +CTwMgr::CStructProxy::CStructProxy() +{ + memset(this, 0, sizeof(*this)); +} + +CTwMgr::CStructProxy::~CStructProxy() +{ + if( m_StructData!=NULL && m_DeleteStructData ) + { + //if( m_StructExtData==NULL && g_TwMgr!=NULL && m_Type>=TW_TYPE_STRUCT_BASE && m_Typem_Structs.size() ) + // g_TwMgr->UninitVarData(m_Type, m_StructData, g_TwMgr->m_Structs[m_Type-TW_TYPE_STRUCT_BASE].m_Size); + delete[] (char*)m_StructData; + } + if( m_StructExtData!=NULL ) + { + //if( g_TwMgr!=NULL && m_Type>=TW_TYPE_STRUCT_BASE && m_Typem_Structs.size() ) + // g_TwMgr->UninitVarData(m_Type, m_StructExtData, g_TwMgr->m_Structs[m_Type-TW_TYPE_STRUCT_BASE].m_Size); + delete[] (char*)m_StructExtData; + } + memset(this, 0, sizeof(*this)); +} + +/* +void CTwMgr::InitVarData(TwType _Type, void *_Data, size_t _Size) +{ + if( _Data!=NULL ) + { + if( _Type>=TW_TYPE_STRUCT_BASE && _Type=TW_TYPE_STRUCT_BASE && _Type~string(); + memset(_Data, 0, _Size); + } + else + memset(_Data, 0, _Size); + } +} +*/ + +void CTwMgr::UnrollCDStdString(std::vector& _Records, TwType _Type, void *_Data) +{ + if( _Data!=NULL ) + { + if( _Type>=TW_TYPE_STRUCT_BASE && _Type& _Records) +{ + for( size_t i=0; i<_Records.size(); ++i ) + memcpy(_Records[i].m_DataPtr, _Records[i].m_PrevValue, m_ClientStdStringStructSize); +} + +CTwMgr::CMemberProxy::CMemberProxy() +{ + memset(this, 0, sizeof(*this)); +} + +CTwMgr::CMemberProxy::~CMemberProxy() +{ + memset(this, 0, sizeof(*this)); +} + +void ANT_CALL CTwMgr::CMemberProxy::SetCB(const void *_Value, void *_ClientData) +{ + if( _ClientData && _Value ) + { + const CMemberProxy *mProxy = static_cast(_ClientData); + if( g_TwMgr && mProxy ) + { + const CStructProxy *sProxy = mProxy->m_StructProxy; + if( sProxy && sProxy->m_StructData && sProxy->m_Type>=TW_TYPE_STRUCT_BASE && sProxy->m_Typem_Structs.size() ) + { + CTwMgr::CStruct& s = g_TwMgr->m_Structs[sProxy->m_Type-TW_TYPE_STRUCT_BASE]; + if( mProxy->m_MemberIndex>=0 && mProxy->m_MemberIndex<(int)s.m_Members.size() ) + { + CTwMgr::CStructMember& m = s.m_Members[mProxy->m_MemberIndex]; + if( m.m_Size>0 && m.m_Type!=TW_TYPE_BUTTON ) + { + if( s.m_IsExt ) + { + memcpy((char *)sProxy->m_StructExtData + m.m_Offset, _Value, m.m_Size); + if( s.m_CopyVarFromExtCallback && sProxy->m_StructExtData ) + s.m_CopyVarFromExtCallback(sProxy->m_StructData, sProxy->m_StructExtData, mProxy->m_MemberIndex, (s.m_ExtClientData==s.s_PassProxyAsClientData) ? _ClientData : s.m_ExtClientData); + } + else + memcpy((char *)sProxy->m_StructData + m.m_Offset, _Value, m.m_Size); + if( sProxy->m_StructSetCallback ) + { + g_TwMgr->m_CDStdStringRecords.resize(0); + g_TwMgr->UnrollCDStdString(g_TwMgr->m_CDStdStringRecords, sProxy->m_Type, sProxy->m_StructData); + sProxy->m_StructSetCallback(sProxy->m_StructData, sProxy->m_StructClientData); + g_TwMgr->RestoreCDStdString(g_TwMgr->m_CDStdStringRecords); + } + } + } + } + } + } +} + +void ANT_CALL CTwMgr::CMemberProxy::GetCB(void *_Value, void *_ClientData) +{ + if( _ClientData && _Value ) + { + const CMemberProxy *mProxy = static_cast(_ClientData); + if( g_TwMgr && mProxy ) + { + const CStructProxy *sProxy = mProxy->m_StructProxy; + if( sProxy && sProxy->m_StructData && sProxy->m_Type>=TW_TYPE_STRUCT_BASE && sProxy->m_Typem_Structs.size() ) + { + CTwMgr::CStruct& s = g_TwMgr->m_Structs[sProxy->m_Type-TW_TYPE_STRUCT_BASE]; + if( mProxy->m_MemberIndex>=0 && mProxy->m_MemberIndex<(int)s.m_Members.size() ) + { + CTwMgr::CStructMember& m = s.m_Members[mProxy->m_MemberIndex]; + if( m.m_Size>0 && m.m_Type!=TW_TYPE_BUTTON ) + { + if( sProxy->m_StructGetCallback ) + sProxy->m_StructGetCallback(sProxy->m_StructData, sProxy->m_StructClientData); + if( s.m_IsExt ) + { + if( s.m_CopyVarToExtCallback && sProxy->m_StructExtData ) + s.m_CopyVarToExtCallback(sProxy->m_StructData, sProxy->m_StructExtData, mProxy->m_MemberIndex, (s.m_ExtClientData==s.s_PassProxyAsClientData) ? _ClientData : s.m_ExtClientData); + memcpy(_Value, (char *)sProxy->m_StructExtData + m.m_Offset, m.m_Size); + } + else + memcpy(_Value, (char *)sProxy->m_StructData + m.m_Offset, m.m_Size); + } + } + } + } + } +} + +// --------------------------------------------------------------------------- + +void ANT_CALL CTwMgr::CCDStdString::SetCB(const void *_Value, void *_ClientData) +{ + if( _Value==NULL || _ClientData==NULL || g_TwMgr==NULL ) + return; + CTwMgr::CCDStdString *CDStdString = (CTwMgr::CCDStdString *)_ClientData; + const char *SrcStr = *(const char **)_Value; + if( SrcStr==NULL ) + { + static char s_EmptyString[] = ""; + SrcStr = s_EmptyString; + } + if( CDStdString->m_ClientSetCallback==NULL ) + { + if( g_TwMgr->m_CopyStdStringToClient && CDStdString->m_ClientStdStringPtr!=NULL ) + { + CTwMgr::CClientStdString clientSrcStr; // convert VC++ Release/Debug std::string + clientSrcStr.FromLib(SrcStr); + g_TwMgr->m_CopyStdStringToClient(*(CDStdString->m_ClientStdStringPtr), clientSrcStr.ToClient()); + } + } + else + { + if( CDStdString->m_ClientSetCallback==CMemberProxy::SetCB ) + CDStdString->m_ClientSetCallback(&SrcStr, CDStdString->m_ClientData); + else + { + CTwMgr::CClientStdString clientSrcStr; // convert VC++ Release/Debug std::string + clientSrcStr.FromLib(SrcStr); + std::string& ValStr = clientSrcStr.ToClient(); + CDStdString->m_ClientSetCallback(&ValStr, CDStdString->m_ClientData); + } + } +} + +void ANT_CALL CTwMgr::CCDStdString::GetCB(void *_Value, void *_ClientData) +{ + if( _Value==NULL || _ClientData==NULL || g_TwMgr==NULL ) + return; + CTwMgr::CCDStdString *CDStdString = (CTwMgr::CCDStdString *)_ClientData; + char **DstStrPtr = (char **)_Value; + if( CDStdString->m_ClientGetCallback==NULL ) + { + if( CDStdString->m_ClientStdStringPtr!=NULL ) + { + //*DstStrPtr = const_cast(CDStdString->m_ClientStdStringPtr->c_str()); + static CTwMgr::CLibStdString s_LibStr; // static because it will be used as a returned value + s_LibStr.FromClient(*CDStdString->m_ClientStdStringPtr); + *DstStrPtr = const_cast(s_LibStr.ToLib().c_str()); + } + else + { + static char s_EmptyString[] = ""; + *DstStrPtr = s_EmptyString; + } + } + else + { + // m_ClientGetCallback uses TwCopyStdStringToLibrary to copy string + // and TwCopyStdStringToLibrary does the VC++ Debug/Release std::string conversion. + CDStdString->m_ClientGetCallback(&(CDStdString->m_LocalString[0]), CDStdString->m_ClientData); + //*DstStrPtr = const_cast(CDStdString->m_LocalString.c_str()); + char **StrPtr = (char **)&(CDStdString->m_LocalString[0]); + *DstStrPtr = *StrPtr; + } +} + +// --------------------------------------------------------------------------- + +static int s_SeparatorTag = 0; + +// --------------------------------------------------------------------------- + +static int AddVar(TwBar *_Bar, const char *_Name, ETwType _Type, void *_VarPtr, bool _ReadOnly, TwSetVarCallback _SetCallback, TwGetVarCallback _GetCallback, TwButtonCallback _ButtonCallback, void *_ClientData, const char *_Def) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + + char unnamedVarName[64]; + if( _Name==NULL || strlen(_Name)==0 ) // create a name automatically + { + static unsigned int s_UnnamedVarCount = 0; + _snprintf(unnamedVarName, sizeof(unnamedVarName), "TW_UNNAMED_%04X", s_UnnamedVarCount); + _Name = unnamedVarName; + ++s_UnnamedVarCount; + } + + if( _Bar==NULL || _Name==NULL || strlen(_Name)==0 || (_VarPtr==NULL && _GetCallback==NULL && _Type!=TW_TYPE_BUTTON) ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + if( _Bar->Find(_Name)!=NULL ) + { + g_TwMgr->SetLastError(g_ErrExist); + return 0; + } + + if( strstr(_Name, "`")!=NULL ) + { + g_TwMgr->SetLastError(g_ErrNoBackQuote); + return 0; + } + + if( _VarPtr==NULL && _Type!=TW_TYPE_BUTTON && _GetCallback!=NULL && _SetCallback==NULL ) + _ReadOnly = true; // force readonly in this case + + // Convert color types + if( _Type==TW_TYPE_COLOR32 ) + _Type = g_TwMgr->m_TypeColor32; + else if( _Type==TW_TYPE_COLOR3F ) + _Type = g_TwMgr->m_TypeColor3F; + else if( _Type==TW_TYPE_COLOR4F ) + _Type = g_TwMgr->m_TypeColor4F; + + // Convert rotation types + if( _Type==TW_TYPE_QUAT4F ) + _Type = g_TwMgr->m_TypeQuat4F; + else if( _Type==TW_TYPE_QUAT4D ) + _Type = g_TwMgr->m_TypeQuat4D; + else if( _Type==TW_TYPE_DIR3F ) + _Type = g_TwMgr->m_TypeDir3F; + else if( _Type==TW_TYPE_DIR3D ) + _Type = g_TwMgr->m_TypeDir3D; + + // VC++ uses a different definition of std::string in Debug and Release modes. + // sizeof(std::string) is encoded in TW_TYPE_STDSTRING to overcome this issue. + // With VS2010 the binary representation of std::string has changed too. This is + // also detected here. + if( (_Type&0xffff0000)==(TW_TYPE_STDSTRING&0xffff0000) || (_Type&0xffff0000)==TW_TYPE_STDSTRING_VS2010 || (_Type&0xffff0000)==TW_TYPE_STDSTRING_VS2008 ) + { + if( g_TwMgr->m_ClientStdStringBaseType==0 ) + g_TwMgr->m_ClientStdStringBaseType = (TwType)(_Type&0xffff0000); + + size_t clientStdStringStructSize = (_Type&0xffff); + if( g_TwMgr->m_ClientStdStringStructSize==0 ) + g_TwMgr->m_ClientStdStringStructSize = clientStdStringStructSize; + int diff = abs((int)g_TwMgr->m_ClientStdStringStructSize - (int)sizeof(std::string)); + if( g_TwMgr->m_ClientStdStringStructSize!=clientStdStringStructSize || g_TwMgr->m_ClientStdStringStructSize==0 + || (diff!=0 && diff!=sizeof(void*))) + { + g_TwMgr->SetLastError(g_ErrStdString); + return 0; + } + + _Type = TW_TYPE_STDSTRING; // force type to be our TW_TYPE_STDSTRING + } + + if( _Type==TW_TYPE_STDSTRING ) + { + g_TwMgr->m_CDStdStrings.push_back(CTwMgr::CCDStdString()); + CTwMgr::CCDStdString& CDStdString = g_TwMgr->m_CDStdStrings.back(); + CDStdString.m_ClientStdStringPtr = (std::string *)_VarPtr; + CDStdString.m_ClientSetCallback = _SetCallback; + CDStdString.m_ClientGetCallback = _GetCallback; + CDStdString.m_ClientData = _ClientData; + //CDStdString.m_This = g_TwMgr->m_CDStdStrings.end(); + //--CDStdString.m_This; + TwGetVarCallback GetCB = CTwMgr::CCDStdString::GetCB; + TwSetVarCallback SetCB = CTwMgr::CCDStdString::SetCB; + if( _VarPtr==NULL && _SetCallback==NULL ) + SetCB = NULL; + if( _VarPtr==NULL && _GetCallback==NULL ) + GetCB = NULL; + return AddVar(_Bar, _Name, TW_TYPE_CDSTDSTRING, NULL, _ReadOnly, SetCB, GetCB, NULL, &CDStdString, _Def); + } + else if( (_Type>TW_TYPE_UNDEF && _Type=TW_TYPE_ENUM_BASE && _Typem_Enums.size()) + || (_Type>TW_TYPE_CSSTRING_BASE && _Type<=TW_TYPE_CSSTRING_MAX) + || _Type==TW_TYPE_CDSTDSTRING + || IsCustomType(_Type) ) // (_Type>=TW_TYPE_CUSTOM_BASE && _Typem_Customs.size()) ) + { + CTwVarAtom *Var = new CTwVarAtom; + Var->m_Name = _Name; + Var->m_Ptr = _VarPtr; + Var->m_Type = _Type; + Var->m_ColorPtr = &(_Bar->m_ColLabelText); + if( _VarPtr!=NULL ) + { + assert( _GetCallback==NULL && _SetCallback==NULL && _ButtonCallback==NULL ); + + Var->m_ReadOnly = _ReadOnly; + Var->m_GetCallback = NULL; + Var->m_SetCallback = NULL; + Var->m_ClientData = NULL; + } + else + { + assert( _GetCallback!=NULL || _Type==TW_TYPE_BUTTON ); + + Var->m_GetCallback = _GetCallback; + Var->m_SetCallback = _SetCallback; + Var->m_ClientData = _ClientData; + if( _Type==TW_TYPE_BUTTON ) + { + Var->m_Val.m_Button.m_Callback = _ButtonCallback; + if( _ButtonCallback==NULL && _ClientData==&s_SeparatorTag ) + { + Var->m_Val.m_Button.m_Separator = 1; + Var->m_Label = " "; + } + else if( _ButtonCallback==NULL ) + Var->m_ColorPtr = &(_Bar->m_ColStaticText); + } + if( _Type!=TW_TYPE_BUTTON ) + Var->m_ReadOnly = (_SetCallback==NULL || _ReadOnly); + else + Var->m_ReadOnly = (_ButtonCallback==NULL); + } + Var->SetDefaults(); + + if( IsCustomType(_Type) ) // _Type>=TW_TYPE_CUSTOM_BASE && _Typem_Customs.size() ) + { + if( Var->m_GetCallback==CTwMgr::CMemberProxy::GetCB && Var->m_SetCallback==CTwMgr::CMemberProxy::SetCB ) + Var->m_Val.m_Custom.m_MemberProxy = static_cast(Var->m_ClientData); + else + Var->m_Val.m_Custom.m_MemberProxy = NULL; + } + + _Bar->m_VarRoot.m_Vars.push_back(Var); + _Bar->NotUpToDate(); + g_TwMgr->m_HelpBarNotUpToDate = true; + + if( _Def!=NULL && strlen(_Def)>0 ) + { + string d = '`' + _Bar->m_Name + "`/`" + _Name + "` " + _Def; + return TwDefine(d.c_str()); + } + else + return 1; + } + else if(_Type>=TW_TYPE_STRUCT_BASE && _Typem_Structs.size()) + { + CTwMgr::CStruct& s = g_TwMgr->m_Structs[_Type-TW_TYPE_STRUCT_BASE]; + CTwMgr::CStructProxy *sProxy = NULL; + void *vPtr; + if( !s.m_IsExt ) + { + if( _VarPtr!=NULL ) + vPtr = _VarPtr; + else + { + assert( _GetCallback!=NULL || _SetCallback!=NULL ); + assert( s.m_Size>0 ); + vPtr = new char[s.m_Size]; + memset(vPtr, 0, s.m_Size); + // create a new StructProxy + g_TwMgr->m_StructProxies.push_back(CTwMgr::CStructProxy()); + sProxy = &(g_TwMgr->m_StructProxies.back()); + sProxy->m_Type = _Type; + sProxy->m_StructData = vPtr; + sProxy->m_DeleteStructData = true; + sProxy->m_StructSetCallback = _SetCallback; + sProxy->m_StructGetCallback = _GetCallback; + sProxy->m_StructClientData = _ClientData; + sProxy->m_CustomDrawCallback = NULL; + sProxy->m_CustomMouseButtonCallback = NULL; + sProxy->m_CustomMouseMotionCallback = NULL; + sProxy->m_CustomMouseLeaveCallback = NULL; + sProxy->m_CustomCaptureFocus = false; + sProxy->m_CustomIndexFirst = -1; + sProxy->m_CustomIndexLast = -1; + //g_TwMgr->InitVarData(sProxy->m_Type, sProxy->m_StructData, s.m_Size); + } + } + else // s.m_IsExt + { + assert( s.m_Size>0 && s.m_ClientStructSize>0 ); + vPtr = new char[s.m_Size]; // will be m_StructExtData + memset(vPtr, 0, s.m_Size); + // create a new StructProxy + g_TwMgr->m_StructProxies.push_back(CTwMgr::CStructProxy()); + sProxy = &(g_TwMgr->m_StructProxies.back()); + sProxy->m_Type = _Type; + sProxy->m_StructExtData = vPtr; + sProxy->m_StructSetCallback = _SetCallback; + sProxy->m_StructGetCallback = _GetCallback; + sProxy->m_StructClientData = _ClientData; + sProxy->m_CustomDrawCallback = NULL; + sProxy->m_CustomMouseButtonCallback = NULL; + sProxy->m_CustomMouseMotionCallback = NULL; + sProxy->m_CustomMouseLeaveCallback = NULL; + sProxy->m_CustomCaptureFocus = false; + sProxy->m_CustomIndexFirst = -1; + sProxy->m_CustomIndexLast = -1; + //g_TwMgr->InitVarData(sProxy->m_Type, sProxy->m_StructExtData, s.m_Size); + if( _VarPtr!=NULL ) + { + sProxy->m_StructData = _VarPtr; + sProxy->m_DeleteStructData = false; + } + else + { + sProxy->m_StructData = new char[s.m_ClientStructSize]; + memset(sProxy->m_StructData, 0, s.m_ClientStructSize); + sProxy->m_DeleteStructData = true; + //g_TwMgr->InitVarData(ClientStructType, sProxy->m_StructData, s.m_ClientStructSize); //ClientStructType is unknown + } + _VarPtr = NULL; // force use of TwAddVarCB for members + + // init m_StructExtdata + if( s.m_ExtClientData==CTwMgr::CStruct::s_PassProxyAsClientData ) + s.m_StructExtInitCallback(sProxy->m_StructExtData, sProxy); + else + s.m_StructExtInitCallback(sProxy->m_StructExtData, s.m_ExtClientData); + } + + for( int i=0; i<(int)s.m_Members.size(); ++i ) + { + CTwMgr::CStructMember& m = s.m_Members[i]; + string name = string(_Name) + '.' + m.m_Name; + const char *access = ""; + if( _ReadOnly ) + access = "readonly "; + string def = "label=`" + m.m_Name + "` group=`" + _Name + "` " + access; // + m.m_DefString; // member def must be done after group def + if( _VarPtr!=NULL ) + { + if( TwAddVarRW(_Bar, name.c_str(), m.m_Type, (char*)vPtr+m.m_Offset, def.c_str())==0 ) + return 0; + } + else + { + assert( sProxy!=NULL ); + // create a new MemberProxy + g_TwMgr->m_MemberProxies.push_back(CTwMgr::CMemberProxy()); + CTwMgr::CMemberProxy& mProxy = g_TwMgr->m_MemberProxies.back(); + mProxy.m_StructProxy = sProxy; + mProxy.m_MemberIndex = i; + assert( !(s.m_IsExt && (m.m_Type==TW_TYPE_STDSTRING || m.m_Type==TW_TYPE_CDSTDSTRING)) ); // forbidden because this case is not handled by UnrollCDStdString + if( TwAddVarCB(_Bar, name.c_str(), m.m_Type, CTwMgr::CMemberProxy::SetCB, CTwMgr::CMemberProxy::GetCB, &mProxy, def.c_str())==0 ) + return 0; + mProxy.m_Var = _Bar->Find(name.c_str(), &mProxy.m_VarParent, NULL); + mProxy.m_Bar = _Bar; + } + + if( sProxy!=NULL && IsCustomType(m.m_Type) ) // m.m_Type>=TW_TYPE_CUSTOM_BASE && m.m_Typem_Customs.size() ) + { + if( sProxy->m_CustomIndexFirst<0 ) + sProxy->m_CustomIndexFirst = sProxy->m_CustomIndexLast = i; + else + sProxy->m_CustomIndexLast = i; + } + } + char structInfo[64]; + sprintf(structInfo, "typeid=%d valptr=%p close ", _Type, vPtr); + string grpDef = '`' + _Bar->m_Name + "`/`" + _Name + "` " + structInfo; + if( _Def!=NULL && strlen(_Def)>0 ) + grpDef += _Def; + int ret = TwDefine(grpDef.c_str()); + for( int i=0; i<(int)s.m_Members.size(); ++i ) // members must be defined even if grpDef has error + { + CTwMgr::CStructMember& m = s.m_Members[i]; + if( m.m_DefString.length()>0 ) + { + string memberDef = '`' + _Bar->m_Name + "`/`" + _Name + '.' + m.m_Name + "` " + m.m_DefString; + if( !TwDefine(memberDef.c_str()) ) // all members must be defined even if memberDef has error + ret = 0; + } + } + return ret; + } + else + { + if( _Type==TW_TYPE_CSSTRING_BASE ) + g_TwMgr->SetLastError(g_ErrBadSize); // static string of size null + else + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; + } +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwAddVarRW(TwBar *_Bar, const char *_Name, ETwType _Type, void *_Var, const char *_Def) +{ + return AddVar(_Bar, _Name, _Type, _Var, false, NULL, NULL, NULL, NULL, _Def); +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwAddVarRO(TwBar *_Bar, const char *_Name, ETwType _Type, const void *_Var, const char *_Def) +{ + return AddVar(_Bar, _Name, _Type, const_cast(_Var), true, NULL, NULL, NULL, NULL, _Def); +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwAddVarCB(TwBar *_Bar, const char *_Name, ETwType _Type, TwSetVarCallback _SetCallback, TwGetVarCallback _GetCallback, void *_ClientData, const char *_Def) +{ + return AddVar(_Bar, _Name, _Type, NULL, false, _SetCallback, _GetCallback, NULL, _ClientData, _Def); +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwAddButton(TwBar *_Bar, const char *_Name, TwButtonCallback _Callback, void *_ClientData, const char *_Def) +{ + return AddVar(_Bar, _Name, TW_TYPE_BUTTON, NULL, false, NULL, NULL, _Callback, _ClientData, _Def); +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwAddSeparator(TwBar *_Bar, const char *_Name, const char *_Def) +{ + return AddVar(_Bar, _Name, TW_TYPE_BUTTON, NULL, true, NULL, NULL, NULL, &s_SeparatorTag, _Def); +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwRemoveVar(TwBar *_Bar, const char *_Name) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( _Bar==NULL || _Name==NULL || strlen(_Name)==0 ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + if( g_TwMgr->m_PopupBar!=NULL && _Bar!=g_TwMgr->m_PopupBar ) // delete popup bar first if it exists + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + + _Bar->StopEditInPlace(); // desactivate EditInPlace + + CTwVarGroup *Parent = NULL; + int Index = -1; + CTwVar *Var = _Bar->Find(_Name, &Parent, &Index); + if( Var!=NULL && Parent!=NULL && Index>=0 ) + { + if( Parent->m_StructValuePtr!=NULL ) + { + g_TwMgr->SetLastError(g_ErrDelStruct); + return 0; + } + + delete Var; + Parent->m_Vars.erase(Parent->m_Vars.begin()+Index); + if( Parent!=&(_Bar->m_VarRoot) && Parent->m_Vars.size()<=0 ) + TwRemoveVar(_Bar, Parent->m_Name.c_str()); + _Bar->NotUpToDate(); + if( _Bar!=g_TwMgr->m_HelpBar ) + g_TwMgr->m_HelpBarNotUpToDate = true; + return 1; + } + + g_TwMgr->SetLastError(g_ErrNotFound); + return 0; +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwRemoveAllVars(TwBar *_Bar) +{ + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( _Bar==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + if( g_TwMgr->m_PopupBar!=NULL && _Bar!=g_TwMgr->m_PopupBar && _Bar!=g_TwMgr->m_HelpBar ) // delete popup bar first if it exists + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + + _Bar->StopEditInPlace(); // desactivate EditInPlace + + for( vector::iterator it=_Bar->m_VarRoot.m_Vars.begin(); it!=_Bar->m_VarRoot.m_Vars.end(); ++it ) + if( *it != NULL ) + { + delete *it; + *it = NULL; + } + _Bar->m_VarRoot.m_Vars.resize(0); + _Bar->NotUpToDate(); + g_TwMgr->m_HelpBarNotUpToDate = true; + return 1; +} + +// --------------------------------------------------------------------------- + +int ParseToken(string& _Token, const char *_Def, int& Line, int& Column, bool _KeepQuotes, bool _EndCR, char _Sep1='\0', char _Sep2='\0') +{ + const char *Cur = _Def; + _Token = ""; + // skip spaces + while( *Cur==' ' || *Cur=='\t' || *Cur=='\r' || *Cur=='\n' ) + { + if( *Cur=='\n' && _EndCR ) + return (int)(Cur-_Def); // a CR has been found + ++Cur; + if( *Cur=='\n' ) + { + ++Line; + Column = 1; + } + else if( *Cur=='\t' ) + Column += g_TabLength; + else if( *Cur!='\r' ) + ++Column; + } + // read token + int QuoteLine=0, QuoteColumn=0; + const char *QuoteCur; + char Quote = 0; + bool AddChar; + bool LineJustIncremented = false; + while( (Quote==0 && (*Cur!='\0' && *Cur!=' ' && *Cur!='\t' && *Cur!='\r' && *Cur!='\n' && *Cur!=_Sep1 && *Cur!=_Sep2)) + || (Quote!=0 && (*Cur!='\0' /* && *Cur!='\r' && *Cur!='\n' */)) ) // allow multi-line strings + { + LineJustIncremented = false; + AddChar = true; + if( Quote==0 && (*Cur=='\'' || *Cur=='\"' || *Cur=='`') ) + { + Quote = *Cur; + QuoteLine = Line; + QuoteColumn = Column; + QuoteCur = Cur; + AddChar = _KeepQuotes; + } + else if ( Quote!=0 && *Cur==Quote ) + { + Quote = 0; + AddChar = _KeepQuotes; + } + + if( AddChar ) + _Token += *Cur; + ++Cur; + if( *Cur=='\t' ) + Column += g_TabLength; + else if( *Cur=='\n' ) + { + ++Line; + LineJustIncremented = true; + Column = 1; + } + else + ++Column; + } + + if( Quote!=0 ) + { + Line = QuoteLine; + Column = QuoteColumn; + return -(int)(Cur-_Def); // unclosed quote + } + else + { + if( *Cur=='\n' ) + { + if( !LineJustIncremented ) + ++Line; + Column = 1; + } + else if( *Cur=='\t' ) + Column += g_TabLength; + else if( *Cur!='\r' && *Cur!='\0' ) + ++Column; + return (int)(Cur-_Def); + } +} + +// --------------------------------------------------------------------------- + +int GetBarVarFromString(CTwBar **_Bar, CTwVar **_Var, CTwVarGroup **_VarParent, int *_VarIndex, const char *_Str) +{ + *_Bar = NULL; + *_Var = NULL; + *_VarParent = NULL; + *_VarIndex = -1; + vector Names; + string Token; + const char *Cur =_Str; + int l=1, c=1, p=1; + while( *Cur!='\0' && p>0 && Names.size()<=3 ) + { + p = ParseToken(Token, Cur, l, c, false, true, '/', '\\'); + if( p>0 && Token.size()>0 ) + { + Names.push_back(Token); + Cur += p + ((Cur[p]!='\0')?1:0); + } + } + if( p<=0 || (Names.size()!=1 && Names.size()!=2) ) + return 0; // parse error + int BarIdx = g_TwMgr->FindBar(Names[0].c_str()); + if( BarIdx<0 ) + { + if( Names.size()==1 && strcmp(Names[0].c_str(), "GLOBAL")==0 ) + { + *_Bar = TW_GLOBAL_BAR; + return +3; // 'GLOBAL' found + } + else + return -1; // bar not found + } + *_Bar = g_TwMgr->m_Bars[BarIdx]; + if( Names.size()==1 ) + return 1; // bar found, no var name parsed + *_Var = (*_Bar)->Find(Names[1].c_str(), _VarParent, _VarIndex); + if( *_Var==NULL ) + return -2; // var not found + return 2; // bar and var found +} + + +int BarVarHasAttrib(CTwBar *_Bar, CTwVar *_Var, const char *_Attrib, bool *_HasValue) +{ + assert(_Bar!=NULL && _HasValue!=NULL && _Attrib!=NULL && strlen(_Attrib)>0); + *_HasValue = false; + if( _Bar==TW_GLOBAL_BAR ) + { + assert( _Var==NULL ); + return g_TwMgr->HasAttrib(_Attrib, _HasValue); + } + else if( _Var==NULL ) + return _Bar->HasAttrib(_Attrib, _HasValue); + else + return _Var->HasAttrib(_Attrib, _HasValue); +} + + +int BarVarSetAttrib(CTwBar *_Bar, CTwVar *_Var, CTwVarGroup *_VarParent, int _VarIndex, int _AttribID, const char *_Value) +{ + assert(_Bar!=NULL && _AttribID>0); + + /* don't delete popupbar here: if any attrib is changed every frame by the app, popup will not work anymore. + if( g_TwMgr->m_PopupBar!=NULL && _Bar!=g_TwMgr->m_PopupBar && g_TwMgr->m_PopupBar->m_BarLinkedToPopupList==_Bar ) // delete popup bar first if it exists + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + */ + + if( _Bar==TW_GLOBAL_BAR ) + { + assert( _Var==NULL ); + return g_TwMgr->SetAttrib(_AttribID, _Value); + } + else if( _Var==NULL ) + return _Bar->SetAttrib(_AttribID, _Value); + else + return _Var->SetAttrib(_AttribID, _Value, _Bar, _VarParent, _VarIndex); + // don't make _Bar not-up-to-date here, should be done in SetAttrib if needed to avoid too frequent refreshs +} + + +ERetType BarVarGetAttrib(CTwBar *_Bar, CTwVar *_Var, CTwVarGroup *_VarParent, int _VarIndex, int _AttribID, std::vector& outDoubles, std::ostringstream& outString) +{ + assert(_Bar!=NULL && _AttribID>0); + + if( _Bar==TW_GLOBAL_BAR ) + { + assert( _Var==NULL ); + return g_TwMgr->GetAttrib(_AttribID, outDoubles, outString); + } + else if( _Var==NULL ) + return _Bar->GetAttrib(_AttribID, outDoubles, outString); + else + return _Var->GetAttrib(_AttribID, _Bar, _VarParent, _VarIndex, outDoubles, outString); +} + +// --------------------------------------------------------------------------- + +static inline std::string ErrorPosition(bool _MultiLine, int _Line, int _Column) +{ + if( !_MultiLine ) + return ""; + else + { + char pos[32]; + //_snprintf(pos, sizeof(pos)-1, " line %d column %d", _Line, _Column); + _snprintf(pos, sizeof(pos)-1, " line %d", _Line); (void)_Column; + pos[sizeof(pos)-1] = '\0'; + return pos; + } +} + +// --------------------------------------------------------------------------- + +int ANT_CALL TwDefine(const char *_Def) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return 0; // not initialized + } + if( _Def==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return 0; + } + + bool MultiLine = false; + const char *Cur = _Def; + while( *Cur!='\0' ) + { + if( *Cur=='\n' ) + { + MultiLine = true; + break; + } + ++Cur; + } + + int Line = 1; + int Column = 1; + enum EState { PARSE_NAME, PARSE_ATTRIB }; + EState State = PARSE_NAME; + string Token; + string Value; + CTwBar *Bar = NULL; + CTwVar *Var = NULL; + CTwVarGroup *VarParent = NULL; + int VarIndex = -1; + int p; + + Cur = _Def; + while( *Cur!='\0' ) + { + const char *PrevCur = Cur; + p = ParseToken(Token, Cur, Line, Column, (State==PARSE_NAME), (State==PARSE_ATTRIB), (State==PARSE_ATTRIB)?'=':'\0'); + if( p<=0 || Token.size()<=0 ) + { + if( p>0 && Cur[p]=='\0' ) + { + Cur += p; + continue; + } + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), (p<0)?(Cur-p):PrevCur); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + char CurSep = Cur[p]; + Cur += p + ((CurSep!='\0')?1:0); + + if( State==PARSE_NAME ) + { + int Err = GetBarVarFromString(&Bar, &Var, &VarParent, &VarIndex, Token.c_str()); + if( Err<=0 ) + { + if( Err==-1 ) + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string: Bar not found%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + else if( Err==-2 ) + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string: Variable not found%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + else + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + State = PARSE_ATTRIB; + } + else // State==PARSE_ATTRIB + { + assert(State==PARSE_ATTRIB); + assert(Bar!=NULL); + + bool HasValue = false; + Value = ""; + int AttribID = BarVarHasAttrib(Bar, Var, Token.c_str(), &HasValue); + if( AttribID<=0 ) + { + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string: Unknown attribute%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + + // special case for backward compatibility + if( HasValue && ( _stricmp(Token.c_str(), "readonly")==0 || _stricmp(Token.c_str(), "hexa")==0 ) ) + { + if( CurSep==' ' || CurSep=='\t' ) + { + const char *ch = Cur; + while( *ch==' ' || *ch=='\t' ) // find next non-space character + ++ch; + if( *ch!='=' ) // if this is not '=' the param has no value + HasValue = false; + } + } + + if( HasValue ) + { + if( CurSep!='=' ) + { + string EqualStr; + p = ParseToken(EqualStr, Cur, Line, Column, true, true, '='); + CurSep = Cur[p]; + if( p<0 || EqualStr.size()>0 || CurSep!='=' ) + { + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string: '=' not found while reading attribute value%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + Cur += p + 1; + } + p = ParseToken(Value, Cur, Line, Column, false, true); + if( p<=0 ) + { + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string: can't read attribute value%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + CurSep = Cur[p]; + Cur += p + ((CurSep!='\0')?1:0); + } + const char *PrevLastErrorPtr = g_TwMgr->CheckLastError(); + if( BarVarSetAttrib(Bar, Var, VarParent, VarIndex, AttribID, HasValue?Value.c_str():NULL)==0 ) + { + if( g_TwMgr->CheckLastError()==NULL || strlen(g_TwMgr->CheckLastError())<=0 || g_TwMgr->CheckLastError()==PrevLastErrorPtr ) + _snprintf(g_ErrParse, sizeof(g_ErrParse), "Parsing error in def string: wrong attribute value%s [%-16s...]", ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + else + _snprintf(g_ErrParse, sizeof(g_ErrParse), "%s%s [%-16s...]", g_TwMgr->CheckLastError(), ErrorPosition(MultiLine, Line, Column).c_str(), Token.c_str()); + g_ErrParse[sizeof(g_ErrParse)-1] = '\0'; + g_TwMgr->SetLastError(g_ErrParse); + return 0; + } + // sweep spaces to detect next attrib + while( *Cur==' ' || *Cur=='\t' || *Cur=='\r' ) + { + ++Cur; + if( *Cur=='\t' ) + Column += g_TabLength; + else if( *Cur!='\r' ) + ++Column; + } + if( *Cur=='\n' ) // new line detected + { + ++Line; + Column = 1; + State = PARSE_NAME; + } + } + } + + g_TwMgr->m_HelpBarNotUpToDate = true; + return 1; +} + +// --------------------------------------------------------------------------- + +TwType ANT_CALL TwDefineEnum(const char *_Name, const TwEnumVal *_EnumValues, unsigned int _NbValues) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return TW_TYPE_UNDEF; // not initialized + } + if( _EnumValues==NULL && _NbValues!=0 ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return TW_TYPE_UNDEF; + } + + if( g_TwMgr->m_PopupBar!=NULL ) // delete popup bar first if it exists + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + + size_t enumIndex = g_TwMgr->m_Enums.size(); + if( _Name!=NULL && strlen(_Name)>0 ) + for( size_t j=0; jm_Enums.size(); ++j ) + if( strcmp(_Name, g_TwMgr->m_Enums[j].m_Name.c_str())==0 ) + { + enumIndex = j; + break; + } + if( enumIndex==g_TwMgr->m_Enums.size() ) + g_TwMgr->m_Enums.push_back(CTwMgr::CEnum()); + assert( enumIndex>=0 && enumIndexm_Enums.size() ); + CTwMgr::CEnum& e = g_TwMgr->m_Enums[enumIndex]; + if( _Name!=NULL && strlen(_Name)>0 ) + e.m_Name = _Name; + else + e.m_Name = ""; + e.m_Entries.clear(); + for(unsigned int i=0; i<_NbValues; ++i) + { + CTwMgr::CEnum::CEntries::value_type Entry(_EnumValues[i].Value, (_EnumValues[i].Label!=NULL)?_EnumValues[i].Label:""); + pair Result = e.m_Entries.insert(Entry); + if( !Result.second ) + (Result.first)->second = Entry.second; + } + + return TwType( TW_TYPE_ENUM_BASE + enumIndex ); +} + +// --------------------------------------------------------------------------- + +TwType TW_CALL TwDefineEnumFromString(const char *_Name, const char *_EnumString) +{ + if (_EnumString == NULL) + return TwDefineEnum(_Name, NULL, 0); + + // split enumString + stringstream EnumStream(_EnumString); + string Label; + vector Labels; + while( getline(EnumStream, Label, ',') ) { + // trim Label + size_t Start = Label.find_first_not_of(" \n\r\t"); + size_t End = Label.find_last_not_of(" \n\r\t"); + if( Start==string::npos || End==string::npos ) + Label = ""; + else + Label = Label.substr(Start, (End-Start)+1); + // store Label + Labels.push_back(Label); + } + // create TwEnumVal array + vector Vals(Labels.size()); + for( int i=0; i<(int)Labels.size(); i++ ) + { + Vals[i].Value = i; + Vals[i].Label = Labels[i].c_str(); + } + + return TwDefineEnum(_Name, Vals.empty() ? NULL : &(Vals[0]), (unsigned int)Vals.size()); +} + +// --------------------------------------------------------------------------- + +void ANT_CALL CTwMgr::CStruct::DefaultSummary(char *_SummaryString, size_t _SummaryMaxLength, const void *_Value, void *_ClientData) +{ + const CTwVarGroup *varGroup = static_cast(_Value); // special case + if( _SummaryString && _SummaryMaxLength>0 ) + _SummaryString[0] = '\0'; + size_t structIndex = (size_t)(_ClientData); + if( g_TwMgr && _SummaryString && _SummaryMaxLength>2 + && varGroup && static_cast(varGroup)->IsGroup() + && structIndex>=0 && structIndex<=g_TwMgr->m_Structs.size() ) + { + // return g_TwMgr->m_Structs[structIndex].m_Name.c_str(); + CTwMgr::CStruct& s = g_TwMgr->m_Structs[structIndex]; + _SummaryString[0] = '{'; + _SummaryString[1] = '\0'; + bool separator = false; + for( size_t i=0; im_Name + '.' + s.m_Members[i].m_Name; + const CTwVar *var = varGroup->Find(varName.c_str(), NULL, NULL); + if( var ) + { + if( var->IsGroup() ) + { + const CTwVarGroup *grp = static_cast(var); + if( grp->m_SummaryCallback!=NULL ) + { + size_t l = strlen(_SummaryString); + if( separator ) + { + _SummaryString[l++] = ','; + _SummaryString[l++] = '\0'; + } + if( grp->m_SummaryCallback==CTwMgr::CStruct::DefaultSummary ) + grp->m_SummaryCallback(_SummaryString+l, _SummaryMaxLength-l, grp, grp->m_SummaryClientData); + else + grp->m_SummaryCallback(_SummaryString+l, _SummaryMaxLength-l, grp->m_StructValuePtr, grp->m_SummaryClientData); + separator = true; + } + } + else + { + size_t l = strlen(_SummaryString); + if( separator ) + { + _SummaryString[l++] = ','; + _SummaryString[l++] = '\0'; + } + string valString; + const CTwVarAtom *atom = static_cast(var); + atom->ValueToString(&valString); + if( atom->m_Type==TW_TYPE_BOOLCPP || atom->m_Type==TW_TYPE_BOOL8 || atom->m_Type==TW_TYPE_BOOL16 || atom->m_Type==TW_TYPE_BOOL32 ) + { + if (valString == "0") + valString = "-"; + else if (valString == "1") + valString = "\x7f"; // check sign + } + strncat(_SummaryString, valString.c_str(), _SummaryMaxLength-l); + separator = true; + } + if( strlen(_SummaryString)>_SummaryMaxLength-2 ) + break; + } + } + size_t l = strlen(_SummaryString); + if( l>_SummaryMaxLength-2 ) + { + _SummaryString[_SummaryMaxLength-2] = '.'; + _SummaryString[_SummaryMaxLength-1] = '.'; + _SummaryString[_SummaryMaxLength+0] = '\0'; + } + else + { + _SummaryString[l+0] = '}'; + _SummaryString[l+1] = '\0'; + } + } +} + +// --------------------------------------------------------------------------- + +TwType ANT_CALL TwDefineStruct(const char *_StructName, const TwStructMember *_StructMembers, unsigned int _NbMembers, size_t _StructSize, TwSummaryCallback _SummaryCallback, void *_SummaryClientData) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return TW_TYPE_UNDEF; // not initialized + } + if( _StructMembers==NULL || _NbMembers==0 || _StructSize==0 ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return TW_TYPE_UNDEF; + } + + if( _StructName!=NULL && strlen(_StructName)>0 ) + for( size_t j=0; jm_Structs.size(); ++j ) + if( strcmp(_StructName, g_TwMgr->m_Structs[j].m_Name.c_str())==0 ) + { + g_TwMgr->SetLastError(g_ErrExist); + return TW_TYPE_UNDEF; + } + + size_t structIndex = g_TwMgr->m_Structs.size(); + CTwMgr::CStruct s; + s.m_Size = _StructSize; + if( _StructName!=NULL && strlen(_StructName)>0 ) + s.m_Name = _StructName; + else + s.m_Name = ""; + s.m_Members.resize(_NbMembers); + if( _SummaryCallback!=NULL ) + { + s.m_SummaryCallback = _SummaryCallback; + s.m_SummaryClientData = _SummaryClientData; + } + else + { + s.m_SummaryCallback = CTwMgr::CStruct::DefaultSummary; + s.m_SummaryClientData = (void *)(structIndex); + } + for( unsigned int i=0; i<_NbMembers; ++i ) + { + CTwMgr::CStructMember& m = s.m_Members[i]; + if( _StructMembers[i].Name!=NULL ) + m.m_Name = _StructMembers[i].Name; + else + { + char name[16]; + sprintf(name, "%u", i); + m.m_Name = name; + } + m.m_Type = _StructMembers[i].Type; + m.m_Size = 0; // to avoid endless recursivity in GetDataSize + m.m_Size = CTwVar::GetDataSize(m.m_Type); + if( _StructMembers[i].Offset<_StructSize ) + m.m_Offset = _StructMembers[i].Offset; + else + { + g_TwMgr->SetLastError(g_ErrOffset); + return TW_TYPE_UNDEF; + } + if( _StructMembers[i].DefString!=NULL && strlen(_StructMembers[i].DefString)>0 ) + m.m_DefString = _StructMembers[i].DefString; + else + m.m_DefString = ""; + } + + g_TwMgr->m_Structs.push_back(s); + assert( g_TwMgr->m_Structs.size()==structIndex+1 ); + return TwType( TW_TYPE_STRUCT_BASE + structIndex ); +} + +// --------------------------------------------------------------------------- + +TwType ANT_CALL TwDefineStructExt(const char *_StructName, const TwStructMember *_StructExtMembers, unsigned int _NbExtMembers, size_t _StructSize, size_t _StructExtSize, TwStructExtInitCallback _StructExtInitCallback, TwCopyVarFromExtCallback _CopyVarFromExtCallback, TwCopyVarToExtCallback _CopyVarToExtCallback, TwSummaryCallback _SummaryCallback, void *_ClientData, const char *_Help) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL ) + { + TwGlobalError(g_ErrNotInit); + return TW_TYPE_UNDEF; // not initialized + } + if( _StructSize==0 || _StructExtInitCallback==NULL || _CopyVarFromExtCallback==NULL || _CopyVarToExtCallback==NULL ) + { + g_TwMgr->SetLastError(g_ErrBadParam); + return TW_TYPE_UNDEF; + } + TwType type = TwDefineStruct(_StructName, _StructExtMembers, _NbExtMembers, _StructExtSize, _SummaryCallback, _ClientData); + if( type>=TW_TYPE_STRUCT_BASE && typem_Structs.size() ) + { + CTwMgr::CStruct& s = g_TwMgr->m_Structs[type-TW_TYPE_STRUCT_BASE]; + s.m_IsExt = true; + s.m_ClientStructSize = _StructSize; + s.m_StructExtInitCallback = _StructExtInitCallback; + s.m_CopyVarFromExtCallback = _CopyVarFromExtCallback; + s.m_CopyVarToExtCallback = _CopyVarToExtCallback; + s.m_ExtClientData = _ClientData; + if( _Help!=NULL ) + s.m_Help = _Help; + } + return type; +} + + +// --------------------------------------------------------------------------- + +bool TwGetKeyCode(int *_Code, int *_Modif, const char *_String) +{ + assert(_Code!=NULL && _Modif!=NULL); + bool Ok = true; + *_Modif = TW_KMOD_NONE; + *_Code = 0; + size_t Start = strlen(_String)-1; + if( Start<0 ) + return false; + while( Start>0 && _String[Start-1]!='+' ) + --Start; + while( _String[Start]==' ' || _String[Start]=='\t' ) + ++Start; + char *CodeStr = _strdup(_String+Start); + for( size_t i=strlen(CodeStr)-1; i>=0; ++i ) + if( CodeStr[i]==' ' || CodeStr[i]=='\t' ) + CodeStr[i] = '\0'; + else + break; + + /* + if( strstr(_String, "SHIFT")!=NULL || strstr(_String, "shift")!=NULL ) + *_Modif |= TW_KMOD_SHIFT; + if( strstr(_String, "CTRL")!=NULL || strstr(_String, "ctrl")!=NULL ) + *_Modif |= TW_KMOD_CTRL; + if( strstr(_String, "META")!=NULL || strstr(_String, "meta")!=NULL ) + *_Modif |= TW_KMOD_META; + + if( strstr(_String, "ALTGR")!=NULL || strstr(_String, "altgr")!=NULL ) + ((void)(0)); // *_Modif |= TW_KMOD_ALTGR; + else // ALT and ALTGR are exclusive + if( strstr(_String, "ALT")!=NULL || strstr(_String, "alt")!=NULL ) + *_Modif |= TW_KMOD_ALT; + */ + char *up = _strdup(_String); + // _strupr(up); + for( char *upch=up; *upch!='\0'; ++upch ) + *upch = (char)toupper(*upch); + if( strstr(up, "SHIFT")!=NULL ) + *_Modif |= TW_KMOD_SHIFT; + if( strstr(up, "CTRL")!=NULL ) + *_Modif |= TW_KMOD_CTRL; + if( strstr(up, "META")!=NULL ) + *_Modif |= TW_KMOD_META; + + if( strstr(up, "ALTGR")!=NULL ) + ((void)(0)); // *_Modif |= TW_KMOD_ALTGR; + else // ALT and ALTGR are exclusive + if( strstr(up, "ALT")!=NULL ) + *_Modif |= TW_KMOD_ALT; + free(up); + + if( strlen(CodeStr)==1 ) + *_Code = (unsigned char)(CodeStr[0]); + else if( _stricmp(CodeStr, "backspace")==0 || _stricmp(CodeStr, "bs")==0 ) + *_Code = TW_KEY_BACKSPACE; + else if( _stricmp(CodeStr, "tab")==0 ) + *_Code = TW_KEY_TAB; + else if( _stricmp(CodeStr, "clear")==0 || _stricmp(CodeStr, "clr")==0 ) + *_Code = TW_KEY_CLEAR; + else if( _stricmp(CodeStr, "return")==0 || _stricmp(CodeStr, "ret")==0 ) + *_Code = TW_KEY_RETURN; + else if( _stricmp(CodeStr, "pause")==0 ) + *_Code = TW_KEY_PAUSE; + else if( _stricmp(CodeStr, "escape")==0 || _stricmp(CodeStr, "esc")==0 ) + *_Code = TW_KEY_ESCAPE; + else if( _stricmp(CodeStr, "space")==0 ) + *_Code = TW_KEY_SPACE; + else if( _stricmp(CodeStr, "delete")==0 || _stricmp(CodeStr, "del")==0 ) + *_Code = TW_KEY_DELETE; + /* + else if( strlen(CodeStr)==4 && CodeStr[3]>='0' && CodeStr[3]<='9' && (strstr(CodeStr, "pad")==CodeStr || strstr(CodeStr, "PAD")==CodeStr) ) + *_Code = TW_KEY_PAD_0 + CodeStr[3]-'0'; + else if( _stricmp(CodeStr, "pad.")==0 ) + *_Code = TW_KEY_PAD_PERIOD; + else if( _stricmp(CodeStr, "pad/")==0 ) + *_Code = TW_KEY_PAD_DIVIDE; + else if( _stricmp(CodeStr, "pad*")==0 ) + *_Code = TW_KEY_PAD_MULTIPLY; + else if( _stricmp(CodeStr, "pad+")==0 ) + *_Code = TW_KEY_PAD_PLUS; + else if( _stricmp(CodeStr, "pad-")==0 ) + *_Code = TW_KEY_PAD_MINUS; + else if( _stricmp(CodeStr, "padenter")==0 ) + *_Code = TW_KEY_PAD_ENTER; + else if( _stricmp(CodeStr, "pad=")==0 ) + *_Code = TW_KEY_PAD_EQUALS; + */ + else if( _stricmp(CodeStr, "up")==0 ) + *_Code = TW_KEY_UP; + else if( _stricmp(CodeStr, "down")==0 ) + *_Code = TW_KEY_DOWN; + else if( _stricmp(CodeStr, "right")==0 ) + *_Code = TW_KEY_RIGHT; + else if( _stricmp(CodeStr, "left")==0 ) + *_Code = TW_KEY_LEFT; + else if( _stricmp(CodeStr, "insert")==0 || _stricmp(CodeStr, "ins")==0 ) + *_Code = TW_KEY_INSERT; + else if( _stricmp(CodeStr, "home")==0 ) + *_Code = TW_KEY_HOME; + else if( _stricmp(CodeStr, "end")==0 ) + *_Code = TW_KEY_END; + else if( _stricmp(CodeStr, "pgup")==0 ) + *_Code = TW_KEY_PAGE_UP; + else if( _stricmp(CodeStr, "pgdown")==0 ) + *_Code = TW_KEY_PAGE_DOWN; + else if( (strlen(CodeStr)==2 || strlen(CodeStr)==3) && (CodeStr[0]=='f' || CodeStr[0]=='F') ) + { + int n = 0; + if( sscanf(CodeStr+1, "%d", &n)==1 && n>0 && n<16 ) + *_Code = TW_KEY_F1 + n-1; + else + Ok = false; + } + + free(CodeStr); + return Ok; +} + +bool TwGetKeyString(std::string *_String, int _Code, int _Modif) +{ + assert(_String!=NULL); + bool Ok = true; + if( _Modif & TW_KMOD_SHIFT ) + *_String += "SHIFT+"; + if( _Modif & TW_KMOD_CTRL ) + *_String += "CTRL+"; + if ( _Modif & TW_KMOD_ALT ) + *_String += "ALT+"; + if ( _Modif & TW_KMOD_META ) + *_String += "META+"; + // if ( _Modif & TW_KMOD_ALTGR ) + // *_String += "ALTGR+"; + switch( _Code ) + { + case TW_KEY_BACKSPACE: + *_String += "BackSpace"; + break; + case TW_KEY_TAB: + *_String += "Tab"; + break; + case TW_KEY_CLEAR: + *_String += "Clear"; + break; + case TW_KEY_RETURN: + *_String += "Return"; + break; + case TW_KEY_PAUSE: + *_String += "Pause"; + break; + case TW_KEY_ESCAPE: + *_String += "Esc"; + break; + case TW_KEY_SPACE: + *_String += "Space"; + break; + case TW_KEY_DELETE: + *_String += "Delete"; + break; + /* + case TW_KEY_PAD_0: + *_String += "PAD0"; + break; + case TW_KEY_PAD_1: + *_String += "PAD1"; + break; + case TW_KEY_PAD_2: + *_String += "PAD2"; + break; + case TW_KEY_PAD_3: + *_String += "PAD3"; + break; + case TW_KEY_PAD_4: + *_String += "PAD4"; + break; + case TW_KEY_PAD_5: + *_String += "PAD5"; + break; + case TW_KEY_PAD_6: + *_String += "PAD6"; + break; + case TW_KEY_PAD_7: + *_String += "PAD7"; + break; + case TW_KEY_PAD_8: + *_String += "PAD8"; + break; + case TW_KEY_PAD_9: + *_String += "PAD9"; + break; + case TW_KEY_PAD_PERIOD: + *_String += "PAD."; + break; + case TW_KEY_PAD_DIVIDE: + *_String += "PAD/"; + break; + case TW_KEY_PAD_MULTIPLY: + *_String += "PAD*"; + break; + case TW_KEY_PAD_MINUS: + *_String += "PAD-"; + break; + case TW_KEY_PAD_PLUS: + *_String += "PAD+"; + break; + case TW_KEY_PAD_ENTER: + *_String += "PADEnter"; + break; + case TW_KEY_PAD_EQUALS: + *_String += "PAD="; + break; + */ + case TW_KEY_UP: + *_String += "Up"; + break; + case TW_KEY_DOWN: + *_String += "Down"; + break; + case TW_KEY_RIGHT: + *_String += "Right"; + break; + case TW_KEY_LEFT: + *_String += "Left"; + break; + case TW_KEY_INSERT: + *_String += "Insert"; + break; + case TW_KEY_HOME: + *_String += "Home"; + break; + case TW_KEY_END: + *_String += "End"; + break; + case TW_KEY_PAGE_UP: + *_String += "PgUp"; + break; + case TW_KEY_PAGE_DOWN: + *_String += "PgDown"; + break; + case TW_KEY_F1: + *_String += "F1"; + break; + case TW_KEY_F2: + *_String += "F2"; + break; + case TW_KEY_F3: + *_String += "F3"; + break; + case TW_KEY_F4: + *_String += "F4"; + break; + case TW_KEY_F5: + *_String += "F5"; + break; + case TW_KEY_F6: + *_String += "F6"; + break; + case TW_KEY_F7: + *_String += "F7"; + break; + case TW_KEY_F8: + *_String += "F8"; + break; + case TW_KEY_F9: + *_String += "F9"; + break; + case TW_KEY_F10: + *_String += "F10"; + break; + case TW_KEY_F11: + *_String += "F11"; + break; + case TW_KEY_F12: + *_String += "F12"; + break; + case TW_KEY_F13: + *_String += "F13"; + break; + case TW_KEY_F14: + *_String += "F14"; + break; + case TW_KEY_F15: + *_String += "F15"; + break; + default: + if( _Code>0 && _Code<256 ) + *_String += char(_Code); + else + { + *_String += "Unknown"; + Ok = false; + } + } + return Ok; +} + +// --------------------------------------------------------------------------- + +const int TW_MOUSE_NOMOTION = -1; +ETwMouseAction TW_MOUSE_MOTION = (ETwMouseAction)(-2); +ETwMouseAction TW_MOUSE_WHEEL = (ETwMouseAction)(-3); +ETwMouseButtonID TW_MOUSE_NA = (ETwMouseButtonID)(-1); + +static int TwMouseEvent(ETwMouseAction _EventType, TwMouseButtonID _Button, int _MouseX, int _MouseY, int _WheelPos) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL || g_TwMgr->m_Graph==NULL ) + { + // TwGlobalError(g_ErrNotInit); -> not an error here + return 0; // not initialized + } + if( g_TwMgr->m_WndHeight<=0 || g_TwMgr->m_WndWidth<=0 ) + { + //g_TwMgr->SetLastError(g_ErrBadWndSize); // not an error, windows not yet ready. + return 0; + } + + // For multi-thread safety + if( !TwFreeAsyncDrawing() ) + return 0; + + if( _MouseX==TW_MOUSE_NOMOTION ) + _MouseX = g_TwMgr->m_LastMouseX; + else + g_TwMgr->m_LastMouseX = _MouseX; + if( _MouseY==TW_MOUSE_NOMOTION ) + _MouseY = g_TwMgr->m_LastMouseY; + else + g_TwMgr->m_LastMouseY = _MouseY; + + // for autorepeat + if( (!g_TwMgr->m_IsRepeatingMousePressed || !g_TwMgr->m_CanRepeatMousePressed) && _EventType==TW_MOUSE_PRESSED ) + { + g_TwMgr->m_LastMousePressedTime = g_TwMgr->m_Timer.GetTime(); + g_TwMgr->m_LastMousePressedButtonID = _Button; + g_TwMgr->m_LastMousePressedPosition[0] = _MouseX; + g_TwMgr->m_LastMousePressedPosition[1] = _MouseY; + g_TwMgr->m_CanRepeatMousePressed = true; + g_TwMgr->m_IsRepeatingMousePressed = false; + } + else if( _EventType==TW_MOUSE_RELEASED || _EventType==TW_MOUSE_WHEEL ) + { + g_TwMgr->m_CanRepeatMousePressed = false; + g_TwMgr->m_IsRepeatingMousePressed = false; + } + + bool Handled = false; + bool wasPopup = (g_TwMgr->m_PopupBar!=NULL); + CTwBar *Bar = NULL; + int i; + + // search for a bar with mousedrag enabled + CTwBar *BarDragging = NULL; + for( i=((int)g_TwMgr->m_Bars.size())-1; i>=0; --i ) + { + Bar = g_TwMgr->m_Bars[g_TwMgr->m_Order[i]]; + if( Bar!=NULL && Bar->m_Visible && Bar->IsDragging() ) + { + BarDragging = Bar; + break; + } + } + + for( i=(int)g_TwMgr->m_Bars.size(); i>=0; --i ) + { + if( i==(int)g_TwMgr->m_Bars.size() ) // first try the bar with mousedrag enabled (this bar has the focus) + Bar = BarDragging; + else + { + Bar = g_TwMgr->m_Bars[g_TwMgr->m_Order[i]]; + if( Bar==BarDragging ) + continue; + } + if( Bar!=NULL && Bar->m_Visible ) + { + if( _EventType==TW_MOUSE_MOTION ) + Handled = Bar->MouseMotion(_MouseX, _MouseY); + else if( _EventType==TW_MOUSE_PRESSED || _EventType==TW_MOUSE_RELEASED ) + Handled = Bar->MouseButton(_Button, (_EventType==TW_MOUSE_PRESSED), _MouseX, _MouseY); + else if( _EventType==TW_MOUSE_WHEEL ) + { + if( abs(_WheelPos-g_TwMgr->m_LastMouseWheelPos)<4 ) // avoid crazy wheel positions + Handled = Bar->MouseWheel(_WheelPos, g_TwMgr->m_LastMouseWheelPos, _MouseX, _MouseY); + } + if( Handled ) + break; + } + } + + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + + /* + if( i>=0 && Bar!=NULL && Handled && (_EventType==TW_MOUSE_PRESSED || Bar->IsMinimized()) && i!=((int)g_TwMgr->m_Bars.size())-1 ) + { + int iOrder = g_TwMgr->m_Order[i]; + for( int j=i; j<(int)g_TwMgr->m_Bars.size()-1; ++j ) + g_TwMgr->m_Order[j] = g_TwMgr->m_Order[j+1]; + g_TwMgr->m_Order[(int)g_TwMgr->m_Bars.size()-1] = iOrder; + } + */ + if( _EventType==TW_MOUSE_PRESSED || (Bar!=NULL && Bar->IsMinimized() && Handled) ) + { + if( wasPopup && Bar!=g_TwMgr->m_PopupBar && g_TwMgr->m_PopupBar!=NULL ) // delete popup + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + + if( i>=0 && Bar!=NULL && Handled && !wasPopup ) + TwSetTopBar(Bar); + } + + if( _EventType==TW_MOUSE_WHEEL ) + g_TwMgr->m_LastMouseWheelPos = _WheelPos; + + return Handled ? 1 : 0; +} + +int ANT_CALL TwMouseButton(ETwMouseAction _EventType, TwMouseButtonID _Button) +{ + return TwMouseEvent(_EventType, _Button, TW_MOUSE_NOMOTION, TW_MOUSE_NOMOTION, 0); +} + +int ANT_CALL TwMouseMotion(int _MouseX, int _MouseY) +{ + return TwMouseEvent(TW_MOUSE_MOTION, TW_MOUSE_NA, _MouseX, _MouseY, 0); +} + +int ANT_CALL TwMouseWheel(int _Pos) +{ + return TwMouseEvent(TW_MOUSE_WHEEL, TW_MOUSE_NA, TW_MOUSE_NOMOTION, TW_MOUSE_NOMOTION, _Pos); +} + +// --------------------------------------------------------------------------- + +static int TranslateKey(int _Key, int _Modifiers) +{ + // CTRL special cases + //if( (_Modifiers&TW_KMOD_CTRL) && !(_Modifiers&TW_KMOD_ALT || _Modifiers&TW_KMOD_META) && _Key>0 && _Key<32 ) + // _Key += 'a'-1; + if( (_Modifiers&TW_KMOD_CTRL) ) + { + if( _Key>='a' && _Key<='z' && ( ((_Modifiers&0x2000) && !(_Modifiers&TW_KMOD_SHIFT)) || (!(_Modifiers&0x2000) && (_Modifiers&TW_KMOD_SHIFT)) )) // 0x2000 is SDL's KMOD_CAPS + _Key += 'A'-'a'; + else if ( _Key>='A' && _Key<='Z' && ( ((_Modifiers&0x2000) && (_Modifiers&TW_KMOD_SHIFT)) || (!(_Modifiers&0x2000) && !(_Modifiers&TW_KMOD_SHIFT)) )) // 0x2000 is SDL's KMOD_CAPS + _Key += 'a'-'A'; + } + + // PAD translation (for SDL keysym) + if( _Key>=256 && _Key<=272 ) // 256=SDLK_KP0 ... 272=SDLK_KP_EQUALS + { + //bool Num = ((_Modifiers&TW_KMOD_SHIFT) && !(_Modifiers&0x1000)) || (!(_Modifiers&TW_KMOD_SHIFT) && (_Modifiers&0x1000)); // 0x1000 is SDL's KMOD_NUM + //_Modifiers &= ~TW_KMOD_SHIFT; // remove shift modifier + bool Num = (!(_Modifiers&TW_KMOD_SHIFT) && (_Modifiers&0x1000)); // 0x1000 is SDL's KMOD_NUM + if( _Key==266 ) // SDLK_KP_PERIOD + _Key = Num ? '.' : TW_KEY_DELETE; + else if( _Key==267 ) // SDLK_KP_DIVIDE + _Key = '/'; + else if( _Key==268 ) // SDLK_KP_MULTIPLY + _Key = '*'; + else if( _Key==269 ) // SDLK_KP_MINUS + _Key = '-'; + else if( _Key==270 ) // SDLK_KP_PLUS + _Key = '+'; + else if( _Key==271 ) // SDLK_KP_ENTER + _Key = TW_KEY_RETURN; + else if( _Key==272 ) // SDLK_KP_EQUALS + _Key = '='; + else if( Num ) // num SDLK_KP0..9 + _Key += '0' - 256; + else if( _Key==256 ) // non-num SDLK_KP01 + _Key = TW_KEY_INSERT; + else if( _Key==257 ) // non-num SDLK_KP1 + _Key = TW_KEY_END; + else if( _Key==258 ) // non-num SDLK_KP2 + _Key = TW_KEY_DOWN; + else if( _Key==259 ) // non-num SDLK_KP3 + _Key = TW_KEY_PAGE_DOWN; + else if( _Key==260 ) // non-num SDLK_KP4 + _Key = TW_KEY_LEFT; + else if( _Key==262 ) // non-num SDLK_KP6 + _Key = TW_KEY_RIGHT; + else if( _Key==263 ) // non-num SDLK_KP7 + _Key = TW_KEY_HOME; + else if( _Key==264 ) // non-num SDLK_KP8 + _Key = TW_KEY_UP; + else if( _Key==265 ) // non-num SDLK_KP9 + _Key = TW_KEY_PAGE_UP; + } + return _Key; +} + +// --------------------------------------------------------------------------- + +static int KeyPressed(int _Key, int _Modifiers, bool _TestOnly) +{ + CTwFPU fpu; // force fpu precision + + if( g_TwMgr==NULL || g_TwMgr->m_Graph==NULL ) + { + // TwGlobalError(g_ErrNotInit); -> not an error here + return 0; // not initialized + } + if( g_TwMgr->m_WndHeight<=0 || g_TwMgr->m_WndWidth<=0 ) + { + //g_TwMgr->SetLastError(g_ErrBadWndSize); // not an error, windows not yet ready. + return 0; + } + + // For multi-thread savety + if( !TwFreeAsyncDrawing() ) + return 0; + + /* + // Test for TwDeleteBar + if( _Key>='0' && _Key<='9' ) + { + int n = _Key-'0'; + if( (int)g_TwMgr->m_Bars.size()>n && g_TwMgr->m_Bars[n]!=NULL ) + { + printf("Delete %s\n", g_TwMgr->m_Bars[n]->m_Name.c_str()); + TwDeleteBar(g_TwMgr->m_Bars[n]); + } + else + printf("can't delete %d\n", n); + return 1; + } + */ + + //char s[256]; + //sprintf(s, "twkeypressed k=%d m=%x\n", _Key, _Modifiers); + //OutputDebugString(s); + + _Key = TranslateKey(_Key, _Modifiers); + if( _Key>' ' && _Key<256 ) // don't test SHIFT if _Key is a common key + _Modifiers &= ~TW_KMOD_SHIFT; + // complete partial modifiers comming from SDL + if( _Modifiers & TW_KMOD_SHIFT ) + _Modifiers |= TW_KMOD_SHIFT; + if( _Modifiers & TW_KMOD_CTRL ) + _Modifiers |= TW_KMOD_CTRL; + if( _Modifiers & TW_KMOD_ALT ) + _Modifiers |= TW_KMOD_ALT; + if( _Modifiers & TW_KMOD_META ) + _Modifiers |= TW_KMOD_META; + + bool Handled = false; + CTwBar *Bar = NULL; + CTwBar *PopupBar = g_TwMgr->m_PopupBar; + //int Order = 0; + int i; + if( _Key>0 && _Keym_LastMouseX; + int MouseY = g_TwMgr->m_LastMouseY; + for( i=((int)g_TwMgr->m_Bars.size())-1; i>=0 && !Handled; --i ) + { + Bar = g_TwMgr->m_Bars[g_TwMgr->m_Order[i]]; + if( Bar!=NULL && Bar->m_Visible && !Bar->IsMinimized() + && ( (MouseX>=Bar->m_PosX && MouseXm_PosX+Bar->m_Width && MouseY>=Bar->m_PosY && MouseYm_PosY+Bar->m_Height) + || Bar==PopupBar) ) + { + if (_TestOnly) + Handled = Bar->KeyTest(_Key, _Modifiers); + else + Handled = Bar->KeyPressed(_Key, _Modifiers); + } + } + + // If not handled, send it to non-iconified bars in the right order + for( i=((int)g_TwMgr->m_Bars.size())-1; i>=0 && !Handled; --i ) + { + Bar = g_TwMgr->m_Bars[g_TwMgr->m_Order[i]]; + /* + for( size_t j=0; jm_Bars.size(); ++j ) + if( g_TwMgr->m_Order[j]==i ) + { + Bar = g_TwMgr->m_Bars[j]; + break; + } + Order = i; + */ + + if( Bar!=NULL && Bar->m_Visible && !Bar->IsMinimized() ) + { + if( _TestOnly ) + Handled = Bar->KeyTest(_Key, _Modifiers); + else + Handled = Bar->KeyPressed(_Key, _Modifiers); + if( g_TwMgr==NULL ) // Mgr might have been destroyed by the client inside a callback call + return 1; + } + } + + // If not handled, send it to iconified bars in the right order + for( i=((int)g_TwMgr->m_Bars.size())-1; i>=0 && !Handled; --i ) + { + Bar = g_TwMgr->m_Bars[g_TwMgr->m_Order[i]]; + if( Bar!=NULL && Bar->m_Visible && Bar->IsMinimized() ) + { + if( _TestOnly ) + Handled = Bar->KeyTest(_Key, _Modifiers); + else + Handled = Bar->KeyPressed(_Key, _Modifiers); + } + } + + if( g_TwMgr->m_HelpBar!=NULL && g_TwMgr->m_Graph && !_TestOnly ) + { + string Str; + TwGetKeyString(&Str, _Key, _Modifiers); + char Msg[256]; + sprintf(Msg, "Key pressed: %s", Str.c_str()); + g_TwMgr->m_KeyPressedStr = Msg; + g_TwMgr->m_KeyPressedBuildText = true; + // OutputDebugString(Msg); + } + } + + if( Handled && Bar!=g_TwMgr->m_PopupBar && g_TwMgr->m_PopupBar!=NULL && g_TwMgr->m_PopupBar==PopupBar ) // delete popup + { + TwDeleteBar(g_TwMgr->m_PopupBar); + g_TwMgr->m_PopupBar = NULL; + } + + if( Handled && Bar!=NULL && Bar!=g_TwMgr->m_PopupBar && Bar!=PopupBar ) // popup bar may have been destroyed + TwSetTopBar(Bar); + + return Handled ? 1 : 0; +} + +int ANT_CALL TwKeyPressed(int _Key, int _Modifiers) +{ + return KeyPressed(_Key, _Modifiers, false); +} + +int ANT_CALL TwKeyTest(int _Key, int _Modifiers) +{ + return KeyPressed(_Key, _Modifiers, true); +} + +// --------------------------------------------------------------------------- + +struct StructCompare : public binary_function +{ + bool operator()(const TwType& _Left, const TwType& _Right) const + { + assert( g_TwMgr!=NULL ); + int i0 = _Left-TW_TYPE_STRUCT_BASE; + int i1 = _Right-TW_TYPE_STRUCT_BASE; + if( i0>=0 && i0<(int)g_TwMgr->m_Structs.size() && i1>=0 && i1<(int)g_TwMgr->m_Structs.size() ) + return g_TwMgr->m_Structs[i0].m_Name < g_TwMgr->m_Structs[i1].m_Name; + else + return false; + } +}; + +typedef set StructSet; + +static void InsertUsedStructs(StructSet& _Set, const CTwVarGroup *_Grp) +{ + assert( g_TwMgr!=NULL && _Grp!=NULL ); + + for( size_t i=0; i<_Grp->m_Vars.size(); ++i ) + if( _Grp->m_Vars[i]!=NULL && _Grp->m_Vars[i]->m_Visible && _Grp->m_Vars[i]->IsGroup() )// && _Grp->m_Vars[i]->m_Help.length()>0 ) + { + const CTwVarGroup *SubGrp = static_cast(_Grp->m_Vars[i]); + if( SubGrp->m_StructValuePtr!=NULL && SubGrp->m_StructType>=TW_TYPE_STRUCT_BASE && SubGrp->m_StructTypem_Structs.size() && g_TwMgr->m_Structs[SubGrp->m_StructType-TW_TYPE_STRUCT_BASE].m_Name.length()>0 ) + { + if( SubGrp->m_Help.length()>0 ) + _Set.insert(SubGrp->m_StructType); + else + { + int idx = SubGrp->m_StructType - TW_TYPE_STRUCT_BASE; + if( idx>=0 && idx<(int)g_TwMgr->m_Structs.size() && g_TwMgr->m_Structs[idx].m_Name.length()>0 ) + { + for( size_t j=0; jm_Structs[idx].m_Members.size(); ++j ) + if( g_TwMgr->m_Structs[idx].m_Members[j].m_Help.length()>0 ) + { + _Set.insert(SubGrp->m_StructType); + break; + } + } + } + } + InsertUsedStructs(_Set, SubGrp); + } +} + +static void SplitString(vector& _OutSplits, const char *_String, int _Width, const CTexFont *_Font) +{ + assert( _Font!=NULL && _String!=NULL ); + _OutSplits.resize(0); + int l = (int)strlen(_String); + if( l==0 ) + { + _String = " "; + l = 1; + } + + if( _String!=NULL && l>0 && _Width>0 ) + { + int w = 0; + int i = 0; + int First = 0; + int Last = 0; + bool PrevNotBlank = true; + unsigned char c; + bool Tab = false, CR = false; + string Split; + const string TabString(g_TabLength, ' '); + + while( im_CharWidth[(int)' ']; + Tab = true; + } + else if( c=='\n' ) + { + w += _Width+1; // force split + Last = i; + CR = true; + } + else + w += _Font->m_CharWidth[(int)c]; + if( w>_Width || i==l-1 ) + { + if( Last<=First || i==l-1 ) + Last = i; + if( Tab ) + { + Split.resize(0); + for(int k=0; km_HelpBar!=NULL); + assert( _String!=NULL ); + int n = 0; + const CTexFont *Font = g_TwMgr->m_HelpBar->m_Font; + assert(Font!=NULL); + string Decal; + for( int s=0; s<_Level; ++s ) + Decal += ' '; + int DecalWidth = (_Level+2)*Font->m_CharWidth[(int)' ']; + + if( _Width>DecalWidth ) + { + vector Split; + SplitString(Split, _String, _Width-DecalWidth, Font); + for( int i=0; i<(int)Split.size(); ++i ) + { + CTwVarAtom *Var = new CTwVarAtom; + Var->m_Name = Decal + Split[i]; + Var->m_Ptr = NULL; + if( _Type==TW_TYPE_HELP_HEADER ) + Var->m_ReadOnly = false; + else + Var->m_ReadOnly = true; + Var->m_NoSlider = true; + Var->m_DontClip = true; + Var->m_Type = _Type; + Var->m_LeftMargin = (signed short)((_Level+1)*Font->m_CharWidth[(int)' ']); + Var->m_TopMargin = (signed short)(-g_TwMgr->m_HelpBar->m_Sep); + //Var->m_TopMargin = 1; + Var->m_ColorPtr = &(g_TwMgr->m_HelpBar->m_ColHelpText); + Var->SetDefaults(); + _Grp->m_Vars.push_back(Var); + ++n; + } + } + return n; +} + +static int AppendHelp(CTwVarGroup *_Grp, const CTwVarGroup *_ToAppend, int _Level, int _Width) +{ + assert( _Grp!=NULL ); + assert( _ToAppend!=NULL ); + int n = 0; + string Decal; + for( int s=0; s<_Level; ++s ) + Decal += ' '; + + if( _ToAppend->m_Help.size()>0 ) + n += AppendHelpString(_Grp, _ToAppend->m_Help.c_str(), _Level, _Width, TW_TYPE_HELP_GRP); + + for( size_t i=0; i<_ToAppend->m_Vars.size(); ++i ) + if( _ToAppend->m_Vars[i]!=NULL && _ToAppend->m_Vars[i]->m_Visible ) + { + bool append = true; + if( !_ToAppend->m_Vars[i]->IsGroup() ) + { + const CTwVarAtom *a = static_cast(_ToAppend->m_Vars[i]); + if( a->m_Type==TW_TYPE_BUTTON && a->m_Val.m_Button.m_Callback==NULL ) + append = false; + else if( a->m_KeyIncr[0]==0 && a->m_KeyIncr[1]==0 && a->m_KeyDecr[0]==0 && a->m_KeyDecr[1]==0 && a->m_Help.length()<=0 ) + append = false; + } + else if( _ToAppend->m_Vars[i]->IsGroup() && static_cast(_ToAppend->m_Vars[i])->m_StructValuePtr!=NULL // that's a struct var + && _ToAppend->m_Vars[i]->m_Help.length()<=0 ) + append = false; + + if( append ) + { + CTwVarAtom *Var = new CTwVarAtom; + Var->m_Name = Decal; + if( _ToAppend->m_Vars[i]->m_Label.size()>0 ) + Var->m_Name += _ToAppend->m_Vars[i]->m_Label; + else + Var->m_Name += _ToAppend->m_Vars[i]->m_Name; + Var->m_Ptr = NULL; + if( _ToAppend->m_Vars[i]->IsGroup() && static_cast(_ToAppend->m_Vars[i])->m_StructValuePtr!=NULL ) + { // That's a struct var + Var->m_Type = TW_TYPE_HELP_STRUCT; + Var->m_Val.m_HelpStruct.m_StructType = static_cast(_ToAppend->m_Vars[i])->m_StructType; + Var->m_ReadOnly = true; + Var->m_NoSlider = true; + } + else if( !_ToAppend->m_Vars[i]->IsGroup() ) + { + Var->m_Type = TW_TYPE_SHORTCUT; + Var->m_Val.m_Shortcut.m_Incr[0] = static_cast(_ToAppend->m_Vars[i])->m_KeyIncr[0]; + Var->m_Val.m_Shortcut.m_Incr[1] = static_cast(_ToAppend->m_Vars[i])->m_KeyIncr[1]; + Var->m_Val.m_Shortcut.m_Decr[0] = static_cast(_ToAppend->m_Vars[i])->m_KeyDecr[0]; + Var->m_Val.m_Shortcut.m_Decr[1] = static_cast(_ToAppend->m_Vars[i])->m_KeyDecr[1]; + Var->m_ReadOnly = static_cast(_ToAppend->m_Vars[i])->m_ReadOnly; + Var->m_NoSlider = true; + } + else + { + Var->m_Type = TW_TYPE_HELP_GRP; + Var->m_DontClip = true; + Var->m_LeftMargin = (signed short)((_Level+2)*g_TwMgr->m_HelpBar->m_Font->m_CharWidth[(int)' ']); + //Var->m_TopMargin = (signed short)(g_TwMgr->m_HelpBar->m_Font->m_CharHeight/2-2+2*(_Level-1)); + Var->m_TopMargin = 2; + if( Var->m_TopMargin>g_TwMgr->m_HelpBar->m_Font->m_CharHeight-3 ) + Var->m_TopMargin = (signed short)(g_TwMgr->m_HelpBar->m_Font->m_CharHeight-3); + Var->m_ReadOnly = true; + } + Var->SetDefaults(); + _Grp->m_Vars.push_back(Var); + size_t VarIndex = _Grp->m_Vars.size()-1; + ++n; + if( _ToAppend->m_Vars[i]->IsGroup() && static_cast(_ToAppend->m_Vars[i])->m_StructValuePtr==NULL ) + { + int nAppended = AppendHelp(_Grp, static_cast(_ToAppend->m_Vars[i]), _Level+1, _Width); + if( _Grp->m_Vars.size()==VarIndex+1 ) + { + delete _Grp->m_Vars[VarIndex]; + _Grp->m_Vars.resize(VarIndex); + } + else + n += nAppended; + } + else if( _ToAppend->m_Vars[i]->m_Help.length()>0 ) + n += AppendHelpString(_Grp, _ToAppend->m_Vars[i]->m_Help.c_str(), _Level+1, _Width, TW_TYPE_HELP_ATOM); + } + } + return n; +} + + +static void CopyHierarchy(CTwVarGroup *dst, const CTwVarGroup *src) +{ + if( dst==NULL || src==NULL ) + return; + + dst->m_Name = src->m_Name; + dst->m_Open = src->m_Open; + dst->m_Visible = src->m_Visible; + dst->m_ColorPtr = src->m_ColorPtr; + dst->m_DontClip = src->m_DontClip; + dst->m_IsRoot = src->m_IsRoot; + dst->m_LeftMargin = src->m_LeftMargin; + dst->m_TopMargin = src->m_TopMargin; + + dst->m_Vars.resize(src->m_Vars.size()); + for(size_t i=0; im_Vars.size(); ++i) + if( src->m_Vars[i]!=NULL && src->m_Vars[i]->IsGroup() ) + { + CTwVarGroup *grp = new CTwVarGroup; + CopyHierarchy(grp, static_cast(src->m_Vars[i])); + dst->m_Vars[i] = grp; + } + else + dst->m_Vars[i] = NULL; +} + +// copy the 'open' flag from original hierarchy to current hierarchy +static void SynchroHierarchy(CTwVarGroup *cur, const CTwVarGroup *orig) +{ + if( cur==NULL || orig==NULL ) + return; + + if( strcmp(cur->m_Name.c_str(), orig->m_Name.c_str())==0 ) + cur->m_Open = orig->m_Open; + + size_t j = 0; + while( jm_Vars.size() && (orig->m_Vars[j]==NULL || !orig->m_Vars[j]->IsGroup()) ) + ++j; + + for(size_t i=0; im_Vars.size(); ++i) + if( cur->m_Vars[i]!=NULL && cur->m_Vars[i]->IsGroup() && jm_Vars.size() && orig->m_Vars[j]!=NULL && orig->m_Vars[j]->IsGroup() ) + { + CTwVarGroup *curGrp = static_cast(cur->m_Vars[i]); + const CTwVarGroup *origGrp = static_cast(orig->m_Vars[j]); + if( strcmp(curGrp->m_Name.c_str(), origGrp->m_Name.c_str())==0 ) + { + curGrp->m_Open = origGrp->m_Open; + + SynchroHierarchy(curGrp, origGrp); + + ++j; + while( jm_Vars.size() && (orig->m_Vars[j]==NULL || !orig->m_Vars[j]->IsGroup()) ) + ++j; + } + } +} + + +void CTwMgr::UpdateHelpBar() +{ + if( m_HelpBar==NULL || m_HelpBar->IsMinimized() ) + return; + if( !m_HelpBarUpdateNow && (float)m_Timer.GetTime()m_VarRoot); + + TwRemoveAllVars(m_HelpBar); + + if( m_HelpBar->m_UpToDate ) + m_HelpBar->Update(); + + if( m_Help.size()>0 ) + AppendHelpString(&(m_HelpBar->m_VarRoot), m_Help.c_str(), 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_ATOM); + if( m_HelpBar->m_Help.size()>0 ) + AppendHelpString(&(m_HelpBar->m_VarRoot), m_HelpBar->m_Help.c_str(), 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_ATOM); + AppendHelpString(&(m_HelpBar->m_VarRoot), "", 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_HEADER); + + for( size_t ib=0; ibm_IsHelpBar) && m_Bars[ib]!=m_PopupBar && m_Bars[ib]->m_Visible ) + { + // Create a group + CTwVarGroup *Grp = new CTwVarGroup; + Grp->m_SummaryCallback = NULL; + Grp->m_SummaryClientData = NULL; + Grp->m_StructValuePtr = NULL; + if( m_Bars[ib]->m_Label.size()<=0 ) + Grp->m_Name = m_Bars[ib]->m_Name; + else + Grp->m_Name = m_Bars[ib]->m_Label; + Grp->m_Open = true; + Grp->m_ColorPtr = &(m_HelpBar->m_ColGrpText); + m_HelpBar->m_VarRoot.m_Vars.push_back(Grp); + if( m_Bars[ib]->m_Help.size()>0 ) + AppendHelpString(Grp, m_Bars[ib]->m_Help.c_str(), 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_GRP); + + // Append variables (recursive) + AppendHelp(Grp, &(m_Bars[ib]->m_VarRoot), 1, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0); + + // Append structures + StructSet UsedStructs; + InsertUsedStructs(UsedStructs, &(m_Bars[ib]->m_VarRoot)); + CTwVarGroup *StructGrp = NULL; + int MemberCount = 0; + for( StructSet::iterator it=UsedStructs.begin(); it!=UsedStructs.end(); ++it ) + { + int idx = (*it) - TW_TYPE_STRUCT_BASE; + if( idx>=0 && idx<(int)g_TwMgr->m_Structs.size() && g_TwMgr->m_Structs[idx].m_Name.length()>0 ) + { + if( StructGrp==NULL ) + { + StructGrp = new CTwVarGroup; + StructGrp->m_StructType = TW_TYPE_HELP_STRUCT; // a special line background color will be used + StructGrp->m_Name = "Structures"; + StructGrp->m_Open = false; + StructGrp->m_ColorPtr = &(m_HelpBar->m_ColStructText); + //Grp->m_Vars.push_back(StructGrp); + MemberCount = 0; + } + CTwVarAtom *Var = new CTwVarAtom; + Var->m_Ptr = NULL; + Var->m_Type = TW_TYPE_HELP_GRP; + Var->m_DontClip = true; + Var->m_LeftMargin = (signed short)(3*g_TwMgr->m_HelpBar->m_Font->m_CharWidth[(int)' ']); + Var->m_TopMargin = 2; + Var->m_ReadOnly = true; + Var->m_NoSlider = true; + Var->m_Name = '{'+g_TwMgr->m_Structs[idx].m_Name+'}'; + StructGrp->m_Vars.push_back(Var); + size_t structIndex = StructGrp->m_Vars.size()-1; + if( g_TwMgr->m_Structs[idx].m_Help.size()>0 ) + AppendHelpString(StructGrp, g_TwMgr->m_Structs[idx].m_Help.c_str(), 2, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0-2*Var->m_LeftMargin, TW_TYPE_HELP_ATOM); + + // Append struct members + for( size_t im=0; imm_Structs[idx].m_Members.size(); ++im ) + { + if( g_TwMgr->m_Structs[idx].m_Members[im].m_Help.size()>0 ) + { + CTwVarAtom *Var = new CTwVarAtom; + Var->m_Ptr = NULL; + Var->m_Type = TW_TYPE_SHORTCUT; + Var->m_Val.m_Shortcut.m_Incr[0] = 0; + Var->m_Val.m_Shortcut.m_Incr[1] = 0; + Var->m_Val.m_Shortcut.m_Decr[0] = 0; + Var->m_Val.m_Shortcut.m_Decr[1] = 0; + Var->m_ReadOnly = false; + Var->m_NoSlider = true; + if( g_TwMgr->m_Structs[idx].m_Members[im].m_Label.length()>0 ) + Var->m_Name = " "+g_TwMgr->m_Structs[idx].m_Members[im].m_Label; + else + Var->m_Name = " "+g_TwMgr->m_Structs[idx].m_Members[im].m_Name; + StructGrp->m_Vars.push_back(Var); + //if( g_TwMgr->m_Structs[idx].m_Members[im].m_Help.size()>0 ) + AppendHelpString(StructGrp, g_TwMgr->m_Structs[idx].m_Members[im].m_Help.c_str(), 3, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0-4*Var->m_LeftMargin, TW_TYPE_HELP_ATOM); + } + } + + if( StructGrp->m_Vars.size()==structIndex+1 ) // remove struct from help + { + delete StructGrp->m_Vars[structIndex]; + StructGrp->m_Vars.resize(structIndex); + } + else + ++MemberCount; + } + } + if( StructGrp!=NULL ) + { + if( MemberCount==1 ) + StructGrp->m_Name = "Structure"; + if( StructGrp->m_Vars.size()>0 ) + Grp->m_Vars.push_back(StructGrp); + else + { + delete StructGrp; + StructGrp = NULL; + } + } + } + + // Append RotoSlider + CTwVarGroup *RotoGrp = new CTwVarGroup; + RotoGrp->m_SummaryCallback = NULL; + RotoGrp->m_SummaryClientData = NULL; + RotoGrp->m_StructValuePtr = NULL; + RotoGrp->m_Name = "RotoSlider"; + RotoGrp->m_Open = false; + RotoGrp->m_ColorPtr = &(m_HelpBar->m_ColGrpText); + m_HelpBar->m_VarRoot.m_Vars.push_back(RotoGrp); + AppendHelpString(RotoGrp, "The RotoSlider allows rapid editing of numerical values.", 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_ATOM); + AppendHelpString(RotoGrp, "To modify a numerical value, click on its label or on its roto [.] button, then move the mouse outside of the grey circle while keeping the mouse button pressed, and turn around the circle to increase or decrease the numerical value.", 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_ATOM); + AppendHelpString(RotoGrp, "The two grey lines depict the min and max bounds.", 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_ATOM); + AppendHelpString(RotoGrp, "Moving the mouse far form the circle allows precise increase or decrease, while moving near the circle allows fast increase or decrease.", 0, m_HelpBar->m_VarX2-m_HelpBar->m_VarX0, TW_TYPE_HELP_ATOM); + + SynchroHierarchy(&m_HelpBar->m_VarRoot, &prevHierarchy); + + m_HelpBarNotUpToDate = false; +} + +// --------------------------------------------------------------------------- + +#if defined(ANT_WINDOWS) + +#include "res/TwXCursors.h" + +void CTwMgr::CreateCursors() +{ + if( m_CursorsCreated ) + return; + m_CursorArrow = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_ARROW)); + m_CursorMove = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_SIZEALL)); + m_CursorWE = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_SIZEWE)); + m_CursorNS = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_SIZENS)); + m_CursorTopRight = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_SIZENESW)); + m_CursorTopLeft = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_SIZENWSE)); + m_CursorBottomLeft = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_SIZENESW)); + m_CursorBottomRight = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_SIZENWSE)); + m_CursorHelp = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_HELP)); + m_CursorCross = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_CROSS)); + m_CursorUpArrow = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_UPARROW)); + m_CursorNo = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_NO)); + m_CursorIBeam = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_IBEAM)); + #ifdef IDC_HAND + m_CursorHand = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_HAND)); + #else + m_CursorHand = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_UPARROW)); + #endif + int cur; + HMODULE hdll = GetModuleHandle(ANT_TWEAK_BAR_DLL); + if( hdll==NULL ) + g_UseCurRsc = false; // force the use of built-in cursors (not using resources) + if( g_UseCurRsc ) + m_CursorCenter = ::LoadCursor(hdll, MAKEINTRESOURCE(IDC_CURSOR1+0)); + else + m_CursorCenter = PixmapCursor(0); + if( m_CursorCenter==NULL ) + m_CursorCenter = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_CROSS)); + if( g_UseCurRsc ) + m_CursorPoint = ::LoadCursor(hdll, MAKEINTRESOURCE(IDC_CURSOR1+1)); + else + m_CursorPoint = PixmapCursor(1); + if( m_CursorPoint==NULL ) + m_CursorPoint = ::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_CROSS)); + + for( cur=0; cur>2) + y*8] |= (unsigned char)(g_CurPict[_CurIdx][x+y*32] << 2*(3-(x&3))+1); //turn whiteon + data[(x>>2) + y*8] |= (unsigned char)(g_CurMask[_CurIdx][x+y*32] << 2*(3-(x&3))); //turn the alpha all the way up + } + //printf("\n"); + } + NSImage *img = [[NSImage alloc] initWithSize: [imgr size]]; + [img addRepresentation: imgr]; + NSCursor *cur = [[NSCursor alloc] initWithImage: img hotSpot: NSMakePoint(g_CurHot[_CurIdx][0],g_CurHot[_CurIdx][1])]; + + [imgr autorelease]; + [img autorelease]; + if (cur) + return cur; + else + return [NSCursor arrowCursor]; +} + +void CTwMgr::CreateCursors() +{ + if (m_CursorsCreated) + return; + + m_CursorArrow = [[NSCursor arrowCursor] retain]; + m_CursorMove = [[NSCursor crosshairCursor] retain]; + m_CursorWE = [[NSCursor resizeLeftRightCursor] retain]; + m_CursorNS = [[NSCursor resizeUpDownCursor] retain]; + m_CursorTopRight = [[NSCursor arrowCursor] retain]; //osx not have one + m_CursorTopLeft = [[NSCursor arrowCursor] retain]; //osx not have one + m_CursorBottomRight = [[NSCursor arrowCursor] retain]; //osx not have one + m_CursorBottomLeft = [[NSCursor arrowCursor] retain]; //osx not have one + m_CursorHelp = [[NSCursor arrowCursor] retain]; //osx not have one + m_CursorHand = [[NSCursor pointingHandCursor] retain]; + m_CursorCross = [[NSCursor arrowCursor] retain]; + m_CursorUpArrow = [[NSCursor arrowCursor] retain]; + m_CursorNo = [[NSCursor arrowCursor] retain]; + m_CursorIBeam = [[NSCursor IBeamCursor] retain]; + for (int i=0;ierror_code, err->request_code); + // No exit! + return 0 ; +} + +static void IgnoreXErrors() +{ + if( g_TwMgr!=NULL && g_TwMgr->m_CurrentXDisplay==glXGetCurrentDisplay() ) + { + XFlush(g_TwMgr->m_CurrentXDisplay); + XSync(g_TwMgr->m_CurrentXDisplay, False); + } + s_PrevErrorHandler = XSetErrorHandler(InactiveErrorHandler); +} + +static void RestoreXErrors() +{ + if( g_TwMgr!=NULL && g_TwMgr->m_CurrentXDisplay==glXGetCurrentDisplay() ) + { + XFlush(g_TwMgr->m_CurrentXDisplay); + XSync(g_TwMgr->m_CurrentXDisplay, False); + } + XSetErrorHandler(s_PrevErrorHandler); +} + +CTwMgr::CCursor CTwMgr::PixmapCursor(int _CurIdx) +{ + if( !m_CurrentXDisplay || !m_CurrentXWindow ) + return XC_left_ptr; + + IgnoreXErrors(); + + XColor black, white, exact; + Colormap colmap = DefaultColormap(m_CurrentXDisplay, DefaultScreen(m_CurrentXDisplay)); + Status s1 = XAllocNamedColor(m_CurrentXDisplay, colmap, "black", &black, &exact); + Status s2 = XAllocNamedColor(m_CurrentXDisplay, colmap, "white", &white, &exact); + if( s1==0 || s2==0 ) + return XC_left_ptr; // cannot allocate colors! + int x, y; + unsigned int mask[32]; + unsigned int pict[32]; + for( y=0; y<32; ++y ) + { + mask[y] = pict[y] = 0; + for( x=0; x<32; ++x ) + { + mask[y] |= (((unsigned int)(g_CurMask[_CurIdx][x+y*32]))<m_CurrentXDisplay ) + { + Window wnd = glXGetCurrentDrawable(); + if( wnd!=g_TwMgr->m_CurrentXWindow ) + { + FreeCursors(); + g_TwMgr->m_CurrentXWindow = wnd; + CreateCursors(); + // now _Cursor is not a valid cursor ID. + } + else + { + IgnoreXErrors(); + XDefineCursor(m_CurrentXDisplay, m_CurrentXWindow, _Cursor); + RestoreXErrors(); + } + } + } +} + +#endif //defined(ANT_UNIX) + +// --------------------------------------------------------------------------- + +void ANT_CALL TwCopyCDStringToClientFunc(TwCopyCDStringToClient copyCDStringToClientFunc) +{ + g_InitCopyCDStringToClient = copyCDStringToClientFunc; + if( g_TwMgr!=NULL ) + g_TwMgr->m_CopyCDStringToClient = copyCDStringToClientFunc; +} + +void ANT_CALL TwCopyCDStringToLibrary(char **destinationLibraryStringPtr, const char *sourceClientString) +{ + if( g_TwMgr==NULL ) + { + if( destinationLibraryStringPtr!=NULL ) + *destinationLibraryStringPtr = const_cast(sourceClientString); + return; + } + + // static buffer to store sourceClientString copy associated to sourceClientString pointer + std::vector& Buf = g_TwMgr->m_CDStdStringCopyBuffers[(void *)sourceClientString]; + + size_t len = (sourceClientString!=NULL) ? strlen(sourceClientString) : 0; + if( Buf.size()m_CopyStdStringToClient = copyStdStringToClientFunc; +} + +void ANT_CALL TwCopyStdStringToLibrary(std::string& destLibraryString, const std::string& srcClientString) +{ + /* + // check if destLibraryString should be initialized + char *Mem = (char *)&destLibraryString; + bool Init = true; + for( int i=0; i& Buf = g_TwMgr->m_CDStdStringCopyBuffers[(void *)&srcClientString]; + + size_t len = strlen(SrcStr); + if( Buf.size()& _OutRects) const +{ + if( Empty() ) + return false; + if( _Rect.Empty() || _Rect.Y>=Y+H || _Rect.Y+_Rect.H<=Y || _Rect.X>=X+W || _Rect.X+_Rect.W<=X ) + { + _OutRects.push_back(*this); + return true; + } + + bool Ret = false; + int Y0 = Y; + int Y1 = Y+H-1; + if( _Rect.Y>Y ) + { + Y0 = _Rect.Y; + _OutRects.push_back(CRect(X, Y, W, Y0-Y+1)); + Ret = true; + } + if( _Rect.Y+_Rect.HX ) + { + X0 = _Rect.X; //-2; + _OutRects.push_back(CRect(X, Y0, X0-X+1, Y1-Y0+1)); + Ret = true; + } + if( _Rect.X+_Rect.W& _Rects, vector& _OutRects) const +{ + _OutRects.clear(); + size_t i, j, NbRects = _Rects.size(); + if( NbRects==0 ) + { + _OutRects.push_back(*this); + return true; + } + else + { + vector TmpRects; + Subtract(_Rects[0], _OutRects); + + for( i=1; i +#define ANT_CALL TW_CALL + +#include "TwColors.h" +#include "TwFonts.h" +#include "TwGraph.h" +#include "AntPerfTimer.h" + + +//#define BENCH // uncomment to activate benchmarks + +#ifdef BENCH +# define PERF(cmd) cmd +#else // BENCH +# define PERF(cmd) +#endif // BENCH + +const int NB_ROTO_CURSORS = 12; + + +// --------------------------------------------------------------------------- +// API unexposed by AntTweakBar.h +// --------------------------------------------------------------------------- + +// bar states -> use TwDefine instead +typedef enum ETwState +{ + TW_STATE_SHOWN = 1, + TW_STATE_ICONIFIED = 2, + TW_STATE_HIDDEN = 3, + TW_STATE_UNICONIFIED = 4, + TW_STATE_ERROR = 0 +} TwState; +/*ANT_TWEAK_BAR_API*/ int ANT_CALL TwSetBarState(TwBar *bar, TwState state); +/*ANT_TWEAK_BAR_API*/ //TwState ANT_CALL TwGetBarState(const TwBar *bar); +// var states -> use TwDefine instead: visible/iconified implemented only as string commands +//ANT_TWEAK_BAR_API int ANT_CALL TwSetVarState(TwBar *bar, const char *name, TwState state); +//ANT_TWEAK_BAR_API TwState ANT_CALL TwGetVarState(const TwBar *bar, const char *name); + +struct CTwVarGroup; +typedef void (ANT_CALL *TwStructExtInitCallback)(void *structExtValue, void *clientData); +typedef void (ANT_CALL *TwCopyVarFromExtCallback)(void *structValue, const void *structExtValue, unsigned int structExtMemberIndex, void *clientData); +typedef void (ANT_CALL *TwCopyVarToExtCallback)(const void *structValue, void *structExtValue, unsigned int structExtMemberIndex, void *clientData); +/*ANT_TWEAK_BAR_API*/ TwType ANT_CALL TwDefineStructExt(const char *name, const TwStructMember *structExtMembers, unsigned int nbExtMembers, size_t structSize, size_t structExtSize, TwStructExtInitCallback structExtInitCallback, TwCopyVarFromExtCallback copyVarFromExtCallback, TwCopyVarToExtCallback copyVarToExtCallback, TwSummaryCallback summaryCallback, void *clientData, const char *help); +typedef void (ANT_CALL *TwCustomDrawCallback)(int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp); +typedef bool (ANT_CALL *TwCustomMouseMotionCallback)(int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp); +typedef bool (ANT_CALL *TwCustomMouseButtonCallback)(TwMouseButtonID button, bool pressed, int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp); +typedef void (ANT_CALL *TwCustomMouseLeaveCallback)(void *structExtValue, void *clientData, TwBar *bar); + +enum ERetType +{ + RET_ERROR = 0, + RET_DOUBLE, + RET_STRING +}; + +enum EButtonAlign +{ + BUTTON_ALIGN_LEFT, + BUTTON_ALIGN_CENTER, + BUTTON_ALIGN_RIGHT +}; + +// --------------------------------------------------------------------------- +// AntTweakBar Manager +// --------------------------------------------------------------------------- + +struct CTwMgr +{ + ETwGraphAPI m_GraphAPI; + void * m_Device; + int m_WndID; + class ITwGraph * m_Graph; + int m_WndWidth; + int m_WndHeight; + const CTexFont * m_CurrentFont; + + std::vector m_Bars; + std::vector m_Order; + + std::vector m_MinOccupied; + void Minimize(TwBar *_Bar); + void Maximize(TwBar *_Bar); + void Hide(TwBar *_Bar); + void Unhide(TwBar *_Bar); + void SetFont(const CTexFont *_Font, bool _ResizeBars); + int m_LastMouseX; + int m_LastMouseY; + int m_LastMouseWheelPos; + int m_IconPos; // 0: bottom-left, 1:bottom-right, 2:top-left, 3:top-right + int m_IconAlign; // 0: vertical, 1: horizontal + int m_IconMarginX, m_IconMarginY; + bool m_FontResizable; + std::string m_BarAlwaysOnTop; + std::string m_BarAlwaysOnBottom; + bool m_UseOldColorScheme; + bool m_Contained; + EButtonAlign m_ButtonAlign; + bool m_OverlapContent; + bool m_Terminating; + + std::string m_Help; + TwBar * m_HelpBar; + float m_LastHelpUpdateTime; + void UpdateHelpBar(); + bool m_HelpBarNotUpToDate; + bool m_HelpBarUpdateNow; + void * m_KeyPressedTextObj; + bool m_KeyPressedBuildText; + std::string m_KeyPressedStr; + float m_KeyPressedTime; + void * m_InfoTextObj; + bool m_InfoBuildText; + int m_BarInitColorHue; + int FindBar(const char *_Name) const; + int HasAttrib(const char *_Attrib, bool *_HasValue) const; + int SetAttrib(int _AttribID, const char *_Value); + ERetType GetAttrib(int _AttribID, std::vector& outDouble, std::ostringstream& outString) const; + void SetLastError(const char *_StaticErrorMesssage); // _StaticErrorMesssage must be a static string + const char * GetLastError(); // returns a static string describing the error, and set LastError to NULL + const char * CheckLastError() const; // returns the LastError, but does not set it to NULL + void SetCurrentDbgParams(const char *file, int line); + TwBar * m_PopupBar; + //bool IsProcessing() const { return m_Processing); + //void SetProcessing(bool processing) { m_Processing = processing; } + + CTwMgr(ETwGraphAPI _GraphAPI, void *_Device, int _WndID); + ~CTwMgr(); + + struct CStructMember + { + std::string m_Name; + std::string m_Label; + TwType m_Type; + size_t m_Offset; + std::string m_DefString; + size_t m_Size; + std::string m_Help; + }; + struct CStruct + { + std::string m_Name; + std::vector m_Members; + size_t m_Size; + TwSummaryCallback m_SummaryCallback; + void * m_SummaryClientData; + std::string m_Help; + bool m_IsExt; + size_t m_ClientStructSize; + TwStructExtInitCallback m_StructExtInitCallback; + TwCopyVarFromExtCallback m_CopyVarFromExtCallback; + TwCopyVarToExtCallback m_CopyVarToExtCallback; + void * m_ExtClientData; + CStruct() : m_IsExt(false), m_StructExtInitCallback(NULL), m_CopyVarFromExtCallback(NULL), m_CopyVarToExtCallback(NULL), m_ExtClientData(NULL) {} + static void ANT_CALL DefaultSummary(char *_SummaryString, size_t _SummaryMaxLength, const void *_Value, void *_ClientData); + static void * s_PassProxyAsClientData; + }; + std::vector m_Structs; + + // followings are used for TwAddVarCB( ... StructType ... ) + struct CStructProxy + { + TwType m_Type; + void * m_StructData; + bool m_DeleteStructData; + void * m_StructExtData; + TwSetVarCallback m_StructSetCallback; + TwGetVarCallback m_StructGetCallback; + void * m_StructClientData; + TwCustomDrawCallback m_CustomDrawCallback; + TwCustomMouseMotionCallback m_CustomMouseMotionCallback; + TwCustomMouseButtonCallback m_CustomMouseButtonCallback; + TwCustomMouseLeaveCallback m_CustomMouseLeaveCallback; + bool m_CustomCaptureFocus; + int m_CustomIndexFirst; + int m_CustomIndexLast; + CStructProxy(); + ~CStructProxy(); + }; + struct CMemberProxy + { + CStructProxy * m_StructProxy; + int m_MemberIndex; + struct CTwVar * m_Var; + struct CTwVarGroup * m_VarParent; + CTwBar * m_Bar; + CMemberProxy(); + ~CMemberProxy(); + static void ANT_CALL SetCB(const void *_Value, void *_ClientData); + static void ANT_CALL GetCB(void *_Value, void *_ClientData); + }; + std::list m_StructProxies; // elements should not move + std::list m_MemberProxies; // elements should not move + //void InitVarData(TwType _Type, void *_Data, size_t _Size); + //void UninitVarData(TwType _Type, void *_Data, size_t _Size); + + struct CEnum + { + std::string m_Name; + typedef std::map CEntries; + CEntries m_Entries; + }; + std::vector m_Enums; + + TwType m_TypeColor32; + TwType m_TypeColor3F; + TwType m_TypeColor4F; + TwType m_TypeQuat4F; + TwType m_TypeQuat4D; + TwType m_TypeDir3F; + TwType m_TypeDir3D; + + std::vector m_CSStringBuffer; + struct CCDStdString + { + std::string * m_ClientStdStringPtr; + char m_LocalString[sizeof(std::string)+2*sizeof(void*)]; //+2*sizeof(void*) because of VC++ std::string extra info in Debug + TwSetVarCallback m_ClientSetCallback; + TwGetVarCallback m_ClientGetCallback; + void * m_ClientData; + static void ANT_CALL SetCB(const void *_Value, void *_ClientData); + static void ANT_CALL GetCB(void *_Value, void *_ClientData); + }; + std::list m_CDStdStrings; + struct CClientStdString // Convertion between VC++ Debug/Release std::string + { + CClientStdString(); + void FromLib(const char *libStr); + std::string& ToClient(); + private: + char m_Data[sizeof(std::string)+2*sizeof(void *)]; + std::string m_LibStr; + }; + struct CLibStdString // Convertion between VC++ Debug/Release std::string + { + CLibStdString(); + void FromClient(const std::string& clientStr); + std::string& ToLib(); + private: + char m_Data[sizeof(std::string)+2*sizeof(void *)]; + }; + struct CCDStdStringRecord + { + void * m_DataPtr; + char m_PrevValue[sizeof(std::string)+2*sizeof(void*)]; + CClientStdString m_ClientStdString; + }; + std::vector m_CDStdStringRecords; + void UnrollCDStdString(std::vector& _Records, TwType _Type, void *_Data); + void RestoreCDStdString(const std::vector& _Records); + std::map > m_CDStdStringCopyBuffers; + + struct CCustom // custom var type + { + virtual ~CCustom() = 0; + }; + std::vector m_Customs; + + PerfTimer m_Timer; + double m_LastMousePressedTime; + TwMouseButtonID m_LastMousePressedButtonID; + int m_LastMousePressedPosition[2]; + double m_RepeatMousePressedDelay; + double m_RepeatMousePressedPeriod; + bool m_CanRepeatMousePressed; + bool m_IsRepeatingMousePressed; + double m_LastDrawTime; + + #if defined(ANT_WINDOWS) + typedef HCURSOR CCursor; + CCursor PixmapCursor(int _CurIdx); + #elif defined(ANT_UNIX) + typedef Cursor CCursor; + CCursor PixmapCursor(int _CurIdx); + Display * m_CurrentXDisplay; + Window m_CurrentXWindow; + #elif defined(ANT_OSX) + typedef NSCursor * CCursor; + CCursor PixmapCursor(int _CurIdx); + #endif // defined(ANT_UNIX) + bool m_CursorsCreated; + void CreateCursors(); + void FreeCursors(); + void SetCursor(CCursor _Cursor); + CCursor m_CursorArrow; + CCursor m_CursorMove; + CCursor m_CursorWE; + CCursor m_CursorNS; + CCursor m_CursorTopLeft; + CCursor m_CursorTopRight; + CCursor m_CursorBottomLeft; + CCursor m_CursorBottomRight; + CCursor m_CursorHelp; + CCursor m_CursorHand; + CCursor m_CursorCross; + CCursor m_CursorUpArrow; + CCursor m_CursorNo; + CCursor m_CursorIBeam; + CCursor m_RotoCursors[NB_ROTO_CURSORS]; + CCursor m_CursorCenter; + CCursor m_CursorPoint; + + TwCopyCDStringToClient m_CopyCDStringToClient; + TwCopyStdStringToClient m_CopyStdStringToClient; + size_t m_ClientStdStringStructSize; + TwType m_ClientStdStringBaseType; + +protected: + int m_NbMinimizedBars; + const char * m_LastError; + const char * m_CurrentDbgFile; + int m_CurrentDbgLine; + //bool m_Processing; +}; + +extern CTwMgr *g_TwMgr; + + +// --------------------------------------------------------------------------- +// Extra functions and TwTypes +// --------------------------------------------------------------------------- + + +bool TwGetKeyCode(int *_Code, int *_Modif, const char *_String); +bool TwGetKeyString(std::string *_String, int _Code, int _Modif); + +const TwType TW_TYPE_SHORTCUT = TwType(0xfff1); +const TwType TW_TYPE_HELP_GRP = TwType(0xfff2); +const TwType TW_TYPE_HELP_ATOM = TwType(0xfff3); +const TwType TW_TYPE_HELP_HEADER = TwType(0xfff4); +const TwType TW_TYPE_HELP_STRUCT = TwType(0xfff5); +const TwType TW_TYPE_BUTTON = TwType(0xfff6); +const TwType TW_TYPE_CDSTDSTRING = TwType(0xfff7); +const TwType TW_TYPE_STRUCT_BASE = TwType(0x10000000); +const TwType TW_TYPE_ENUM_BASE = TwType(0x20000000); +const TwType TW_TYPE_CSSTRING_BASE = TW_TYPE_CSSTRING(0); // defined as 0x30000000 (see AntTweakBar.h) +const TwType TW_TYPE_CSSTRING_MAX = TW_TYPE_CSSTRING(0xfffffff); +#define TW_CSSTRING_SIZE(type) ((int)((type)&0xfffffff)) +const TwType TW_TYPE_CUSTOM_BASE = TwType(0x40000000); +const TwType TW_TYPE_STDSTRING_VS2008 = TwType(0x2fff0000); +const TwType TW_TYPE_STDSTRING_VS2010 = TwType(0x2ffe0000); + +extern "C" int ANT_CALL TwSetLastError(const char *_StaticErrorMessage); + +//const TwGraphAPI TW_OPENGL_CORE = (TwGraphAPI)5; // WIP (note: OpenGL Core Profil requires OpenGL 3.2 or later) + +// Clipping helper +struct CRect +{ + int X, Y, W, H; + CRect() : X(0), Y(0), W(0), H(0) {} + CRect(int _X, int _Y, int _W, int _H) : X(_X), Y(_Y), W(_W), H(_H) {} + bool operator==(const CRect& _Rect) { return (Empty() && _Rect.Empty()) || (X==_Rect.X && Y==_Rect.Y && W==_Rect.W && H==_Rect.H); } + bool Empty(int _Margin=0) const { return (W<=_Margin || H<=_Margin); } + bool Subtract(const CRect& _Rect, std::vector& _OutRects) const; + bool Subtract(const std::vector& _Rects, std::vector& _OutRects) const; +}; + + +// --------------------------------------------------------------------------- +// Global bar attribs +// --------------------------------------------------------------------------- + + +enum EMgrAttribs +{ + MGR_HELP = 1, + MGR_FONT_SIZE, + MGR_FONT_STYLE, + MGR_ICON_POS, + MGR_ICON_ALIGN, + MGR_ICON_MARGIN, + MGR_FONT_RESIZABLE, + MGR_COLOR_SCHEME, + MGR_CONTAINED, + MGR_BUTTON_ALIGN, + MGR_OVERLAP +}; + + +// --------------------------------------------------------------------------- +// Color struct ext +// --------------------------------------------------------------------------- + + +struct CColorExt +{ + int R, G, B; + int H, L, S; + int A; + bool m_HLS, m_HasAlpha, m_OGL; + bool m_CanHaveAlpha; + bool m_IsColorF; + unsigned int m_PrevConvertedColor; + CTwMgr::CStructProxy*m_StructProxy; + void RGB2HLS(); + void HLS2RGB(); + static void ANT_CALL InitColor32CB(void *_ExtValue, void *_ClientData); + static void ANT_CALL InitColor3FCB(void *_ExtValue, void *_ClientData); + static void ANT_CALL InitColor4FCB(void *_ExtValue, void *_ClientData); + static void ANT_CALL CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); + static void ANT_CALL CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); + static void ANT_CALL SummaryCB(char *_SummaryString, size_t _SummaryMaxLength, const void *_ExtValue, void *_ClientData); + static void CreateTypes(); +}; + + +// --------------------------------------------------------------------------- +// Quaternion struct ext +// --------------------------------------------------------------------------- + + +struct CQuaternionExt +{ + double Qx, Qy, Qz, Qs; // Quat value + double Vx, Vy, Vz, Angle; // Not used + double Dx, Dy, Dz; // Dir value set when used as a direction + bool m_AAMode; // Axis & angle mode -> disabled + bool m_ShowVal; // Display values + bool m_IsFloat; // Quat/Dir uses floats + bool m_IsDir; // Mapped to a dir vector instead of a quat + double m_Dir[3]; // If not zero, display one direction vector + color32 m_DirColor; // Direction vector color + float m_Permute[3][3]; // Permute frame axis + CTwMgr::CStructProxy*m_StructProxy; + static void ANT_CALL InitQuat4FCB(void *_ExtValue, void *_ClientData); + static void ANT_CALL InitQuat4DCB(void *_ExtValue, void *_ClientData); + static void ANT_CALL InitDir3FCB(void *_ExtValue, void *_ClientData); + static void ANT_CALL InitDir3DCB(void *_ExtValue, void *_ClientData); + static void ANT_CALL CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); + static void ANT_CALL CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); + static void ANT_CALL SummaryCB(char *_SummaryString, size_t _SummaryMaxLength, const void *_ExtValue, void *_ClientData); + static void ANT_CALL DrawCB(int _W, int _H, void *_ExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp); + static bool ANT_CALL MouseMotionCB(int _MouseX, int _MouseY, int _W, int _H, void *_StructExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp); + static bool ANT_CALL MouseButtonCB(TwMouseButtonID _Button, bool _Pressed, int _MouseX, int _MouseY, int _W, int _H, void *_StructExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp); + static void ANT_CALL MouseLeaveCB(void *_StructExtValue, void *_ClientData, TwBar *_Bar); + static void CreateTypes(); + static TwType s_CustomType; + void ConvertToAxisAngle(); + void ConvertFromAxisAngle(); + void CopyToVar(); + static std::vector s_SphTri; + static std::vector s_SphCol; + static std::vector s_SphTriProj; + static std::vector s_SphColLight; + static std::vector s_ArrowTri[4]; + static std::vector s_ArrowTriProj[4]; + static std::vector s_ArrowNorm[4]; + static std::vector s_ArrowColLight[4]; + enum EArrowParts { ARROW_CONE, ARROW_CONE_CAP, ARROW_CYL, ARROW_CYL_CAP }; + static void CreateSphere(); + static void CreateArrow(); + static void ApplyQuat(float *outX, float *outY, float *outZ, float x, float y, float z, float qx, float qy, float qz, float qs); + static void QuatFromDir(double *outQx, double *outQy, double *outQz, double *outQs, double dx, double dy, double dz); + inline void Permute(float *outX, float *outY, float *outZ, float x, float y, float z); + inline void PermuteInv(float *outX, float *outY, float *outZ, float x, float y, float z); + inline void Permute(double *outX, double *outY, double *outZ, double x, double y, double z); + inline void PermuteInv(double *outX, double *outY, double *outZ, double x, double y, double z); + bool m_Highlighted; + bool m_Rotating; + double m_OrigQuat[4]; + float m_OrigX, m_OrigY; + double m_PrevX, m_PrevY; +}; + + +// --------------------------------------------------------------------------- +// CTwFPU objects set and restore the fpu precision if needed. +// (could be useful because DirectX changes it and AntTweakBar requires default double precision) +// --------------------------------------------------------------------------- + + +struct CTwFPU +{ + CTwFPU() + { + #ifdef ANT_WINDOWS + state0 = _controlfp(0, 0); + if( (state0&MCW_PC)==_PC_24 ) // we need at least _PC_53 + _controlfp(_PC_53, MCW_PC); + #else + state0 = 0; + #endif + } + ~CTwFPU() + { + #ifdef ANT_WINDOWS + if( (state0&MCW_PC)==_PC_24 ) + _controlfp(_PC_24, MCW_PC); + #else + state0 = 0; + #endif + } +private: + unsigned int state0; +}; + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_MGR_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.cpp new file mode 100644 index 0000000..558a3c4 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.cpp @@ -0,0 +1,907 @@ +// --------------------------------------------------------------------------- +// +// @file TwOpenGL.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + + +#include "TwPrecomp.h" +#include "LoadOGL.h" +#include "TwOpenGL.h" +#include "TwMgr.h" + +using namespace std; + +const char *g_ErrCantLoadOGL = "Cannot load OpenGL library dynamically"; +const char *g_ErrCantUnloadOGL = "Cannot unload OpenGL library"; + +GLuint g_SmallFontTexID = 0; +GLuint g_NormalFontTexID = 0; +GLuint g_LargeFontTexID = 0; + +// --------------------------------------------------------------------------- +// Extensions + +typedef void (APIENTRY * PFNGLBindBufferARB)(GLenum target, GLuint buffer); +typedef void (APIENTRY * PFNGLBindProgramARB)(GLenum target, GLuint program); +typedef GLuint (APIENTRY * PFNGLGetHandleARB)(GLenum pname); +typedef void (APIENTRY * PFNGLUseProgramObjectARB)(GLuint programObj); +typedef void (APIENTRY * PFNGLTexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLActiveTextureARB)(GLenum texture); +typedef void (APIENTRY * PFNGLClientActiveTextureARB)(GLenum texture); +typedef void (APIENTRY * PFNGLBlendEquation)(GLenum mode); +typedef void (APIENTRY * PFNGLBlendEquationSeparate)(GLenum srcMode, GLenum dstMode); +typedef void (APIENTRY * PFNGLBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (APIENTRY * PFNGLBindVertexArray)(GLuint array); +typedef void (APIENTRY * PFNGLEnableVertexAttribArray) (GLuint index); +typedef void (APIENTRY * PFNGLDisableVertexAttribArray) (GLuint index); +typedef void (APIENTRY * PFNGLGetVertexAttribiv) (GLuint, GLenum, GLint*); +PFNGLBindBufferARB _glBindBufferARB = NULL; +PFNGLBindProgramARB _glBindProgramARB = NULL; +PFNGLGetHandleARB _glGetHandleARB = NULL; +PFNGLUseProgramObjectARB _glUseProgramObjectARB = NULL; +PFNGLTexImage3D _glTexImage3D = NULL; +PFNGLActiveTextureARB _glActiveTextureARB = NULL; +PFNGLClientActiveTextureARB _glClientActiveTextureARB = NULL; +PFNGLBlendEquation _glBlendEquation = NULL; +PFNGLBlendEquationSeparate _glBlendEquationSeparate = NULL; +PFNGLBlendFuncSeparate _glBlendFuncSeparate = NULL; +PFNGLBindVertexArray _glBindVertexArray = NULL; +PFNGLEnableVertexAttribArray _glEnableVertexAttribArray = NULL; +PFNGLDisableVertexAttribArray _glDisableVertexAttribArray = NULL; +PFNGLGetVertexAttribiv _glGetVertexAttribiv = NULL; +#ifndef GL_ARRAY_BUFFER_ARB +# define GL_ARRAY_BUFFER_ARB 0x8892 +#endif +#ifndef GL_ELEMENT_ARRAY_BUFFER_ARB +# define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#endif +#ifndef GL_ARRAY_BUFFER_BINDING_ARB +# define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#endif +#ifndef GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB +# define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#endif +#ifndef GL_VERTEX_PROGRAM_ARB +# define GL_VERTEX_PROGRAM_ARB 0x8620 +#endif +#ifndef GL_FRAGMENT_PROGRAM_ARB +# define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#endif +#ifndef GL_PROGRAM_OBJECT_ARB +# define GL_PROGRAM_OBJECT_ARB 0x8B40 +#endif +#ifndef GL_TEXTURE_3D +# define GL_TEXTURE_3D 0x806F +#endif +#ifndef GL_TEXTURE0_ARB +# define GL_TEXTURE0_ARB 0x84C0 +#endif +#ifndef GL_ACTIVE_TEXTURE_ARB +# define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#endif +#ifndef GL_CLIENT_ACTIVE_TEXTURE_ARB +# define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#endif +#ifndef GL_MAX_TEXTURE_UNITS_ARB +# define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif +#ifndef GL_MAX_TEXTURE_COORDS +# define GL_MAX_TEXTURE_COORDS 0x8871 +#endif +#ifndef GL_TEXTURE_RECTANGLE_ARB +# define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#endif +#ifndef GL_FUNC_ADD +# define GL_FUNC_ADD 0x8006 +#endif +#ifndef GL_BLEND_EQUATION +# define GL_BLEND_EQUATION 0x8009 +#endif +#ifndef GL_BLEND_EQUATION_RGB +# define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#endif +#ifndef GL_BLEND_EQUATION_ALPHA +# define GL_BLEND_EQUATION_ALPHA 0x883D +#endif +#ifndef GL_BLEND_SRC_RGB +# define GL_BLEND_SRC_RGB 0x80C9 +#endif +#ifndef GL_BLEND_DST_RGB +# define GL_BLEND_DST_RGB 0x80C8 +#endif +#ifndef GL_BLEND_SRC_ALPHA +# define GL_BLEND_SRC_ALPHA 0x80CB +#endif +#ifndef GL_BLEND_DST_ALPHA +# define GL_BLEND_DST_ALPHA 0x80CA +#endif +#ifndef GL_VERTEX_ARRAY_BINDING +# define GL_VERTEX_ARRAY_BINDING 0x85B5 +#endif +#ifndef GL_MAX_VERTEX_ATTRIBS +# define GL_MAX_VERTEX_ATTRIBS 0x8869 +#endif +#ifndef GL_VERTEX_ATTRIB_ARRAY_ENABLED +# define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#endif + +// --------------------------------------------------------------------------- + +#ifdef _DEBUG + static void CheckGLError(const char *file, int line, const char *func) + { + int err=0; + char msg[256]; + while( (err=_glGetError())!=0 ) + { + sprintf(msg, "%s(%d) : [%s] GL_ERROR=0x%x\n", file, line, func, err); + #ifdef ANT_WINDOWS + OutputDebugString(msg); + #endif + fprintf(stderr, msg); + } + } +# ifdef __FUNCTION__ +# define CHECK_GL_ERROR CheckGLError(__FILE__, __LINE__, __FUNCTION__) +# else +# define CHECK_GL_ERROR CheckGLError(__FILE__, __LINE__, "") +# endif +#else +# define CHECK_GL_ERROR ((void)(0)) +#endif + +// --------------------------------------------------------------------------- + +static GLuint BindFont(const CTexFont *_Font) +{ + GLuint TexID = 0; + _glGenTextures(1, &TexID); + _glBindTexture(GL_TEXTURE_2D, TexID); + _glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + _glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); + _glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + _glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + _glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + _glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + _glPixelTransferf(GL_ALPHA_SCALE, 1); + _glPixelTransferf(GL_ALPHA_BIAS, 0); + _glPixelTransferf(GL_RED_BIAS, 1); + _glPixelTransferf(GL_GREEN_BIAS, 1); + _glPixelTransferf(GL_BLUE_BIAS, 1); + _glTexImage2D(GL_TEXTURE_2D, 0, 4, _Font->m_TexWidth, _Font->m_TexHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, _Font->m_TexBytes); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST); + _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + _glBindTexture(GL_TEXTURE_2D, 0); + _glPixelTransferf(GL_ALPHA_BIAS, 0); + _glPixelTransferf(GL_RED_BIAS, 0); + _glPixelTransferf(GL_GREEN_BIAS, 0); + _glPixelTransferf(GL_BLUE_BIAS, 0); + + return TexID; +} + +static void UnbindFont(GLuint _FontTexID) +{ + if( _FontTexID>0 ) + _glDeleteTextures(1, &_FontTexID); +} + +// --------------------------------------------------------------------------- + +int CTwGraphOpenGL::Init() +{ + m_Drawing = false; + m_FontTexID = 0; + m_FontTex = NULL; + m_MaxClipPlanes = -1; + + if( LoadOpenGL()==0 ) + { + g_TwMgr->SetLastError(g_ErrCantLoadOGL); + return 0; + } + + // Get extensions + _glBindBufferARB = reinterpret_cast(_glGetProcAddress("glBindBufferARB")); + _glBindProgramARB = reinterpret_cast(_glGetProcAddress("glBindProgramARB")); + _glGetHandleARB = reinterpret_cast(_glGetProcAddress("glGetHandleARB")); + _glUseProgramObjectARB = reinterpret_cast(_glGetProcAddress("glUseProgramObjectARB")); + _glTexImage3D = reinterpret_cast(_glGetProcAddress("glTexImage3D")); + _glActiveTextureARB = reinterpret_cast(_glGetProcAddress("glActiveTextureARB")); + _glClientActiveTextureARB = reinterpret_cast(_glGetProcAddress("glClientActiveTextureARB")); + _glBlendEquation = reinterpret_cast(_glGetProcAddress("glBlendEquation")); + _glBlendEquationSeparate = reinterpret_cast(_glGetProcAddress("glBlendEquationSeparate")); + _glBlendFuncSeparate = reinterpret_cast(_glGetProcAddress("glBlendFuncSeparate")); + _glBindVertexArray = reinterpret_cast(_glGetProcAddress("glBindVertexArray")); + _glEnableVertexAttribArray = reinterpret_cast(_glGetProcAddress("glEnableVertexAttribArray")); + _glDisableVertexAttribArray = reinterpret_cast(_glGetProcAddress("glDisableVertexAttribArray")); + _glGetVertexAttribiv = reinterpret_cast(_glGetProcAddress("glGetVertexAttribiv")); + + m_SupportTexRect = false; // updated in BeginDraw + + return 1; +} + +// --------------------------------------------------------------------------- + +int CTwGraphOpenGL::Shut() +{ + assert(m_Drawing==false); + + UnbindFont(m_FontTexID); + + int Res = 1; + if( UnloadOpenGL()==0 ) + { + g_TwMgr->SetLastError(g_ErrCantUnloadOGL); + Res = 0; + } + + return Res; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::BeginDraw(int _WndWidth, int _WndHeight) +{ + assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0); + m_Drawing = true; + m_WndWidth = _WndWidth; + m_WndHeight = _WndHeight; + + CHECK_GL_ERROR; + +//#if !defined(ANT_OSX) + static bool s_SupportTexRectChecked = false; + if (!s_SupportTexRectChecked) + { + const char *ext = (const char *)_glGetString(GL_EXTENSIONS); + if( ext!=0 && strlen(ext)>0 ) + m_SupportTexRect = (strstr(ext, "GL_ARB_texture_rectangle")!=NULL); + s_SupportTexRectChecked = true; + } +//#endif + + _glPushAttrib(GL_ALL_ATTRIB_BITS); + _glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); + + if( _glActiveTextureARB ) + { + _glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &m_PrevActiveTextureARB); + _glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE_ARB, &m_PrevClientActiveTextureARB); + GLint maxTexUnits = 1; + _glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxTexUnits); // was GL_MAX_TEXTURE_UNITS_ARB + if( maxTexUnits<1 ) + maxTexUnits = 1; + else if( maxTexUnits > MAX_TEXTURES ) + maxTexUnits = MAX_TEXTURES; + GLint i; + for( i=0; i0 && _WndHeight>0 ) + { + Vp[0] = 0; + Vp[1] = 0; + Vp[2] = _WndWidth; + Vp[3] = _WndHeight; + _glViewport(Vp[0], Vp[1], Vp[2], Vp[3]); + } + _glLoadIdentity(); + //_glOrtho(Vp[0], Vp[0]+Vp[2]-1, Vp[1]+Vp[3]-1, Vp[1], -1, 1); // Doesn't work + _glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1); + */ + if( _WndWidth>0 && _WndHeight>0 ) + { + Vp[0] = 0; + Vp[1] = 0; + Vp[2] = _WndWidth-1; + Vp[3] = _WndHeight-1; + _glViewport(Vp[0], Vp[1], Vp[2], Vp[3]); + } + _glLoadIdentity(); + _glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1); + _glGetIntegerv(GL_VIEWPORT, m_ViewportInit); + _glGetFloatv(GL_PROJECTION_MATRIX, m_ProjMatrixInit); + + _glGetFloatv(GL_LINE_WIDTH, &m_PrevLineWidth); + _glDisable(GL_POLYGON_STIPPLE); + _glLineWidth(1); + _glDisable(GL_LINE_SMOOTH); + _glDisable(GL_LINE_STIPPLE); + _glDisable(GL_CULL_FACE); + _glDisable(GL_DEPTH_TEST); + _glDisable(GL_LIGHTING); + _glEnable(GL_BLEND); + _glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + _glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &m_PrevTexEnv); + _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + _glGetIntegerv(GL_POLYGON_MODE, m_PrevPolygonMode); + _glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + _glDisable(GL_ALPHA_TEST); + //_glEnable(GL_ALPHA_TEST); + //_glAlphaFunc(GL_GREATER, 0); + _glDisable(GL_FOG); + _glDisable(GL_LOGIC_OP); + _glDisable(GL_SCISSOR_TEST); + if( m_MaxClipPlanes<0 ) + { + _glGetIntegerv(GL_MAX_CLIP_PLANES, &m_MaxClipPlanes); + if( m_MaxClipPlanes<0 || m_MaxClipPlanes>255 ) + m_MaxClipPlanes = 6; + } + for( GLint i=0; iMAX_VERTEX_ATTRIBS) + maxVertexAttribs=MAX_VERTEX_ATTRIBS; + + for(int i=0; i MAX_TEXTURES ) + maxTexUnits = MAX_TEXTURES; + GLint i; + for( i=0; iMAX_VERTEX_ATTRIBS) + maxVertexAttribs=MAX_VERTEX_ATTRIBS; + + for(int i=0; i_X1) + ++_X0; + if(_Y0<_Y1) + ++_Y1; + else if(_Y0>_Y1) + ++_Y0; + */ + //const GLfloat dx = +0.0f; + const GLfloat dx = +0.5f; + //GLfloat dy = -0.2f; + const GLfloat dy = -0.5f; + if( _AntiAliased ) + _glEnable(GL_LINE_SMOOTH); + else + _glDisable(GL_LINE_SMOOTH); + _glDisable(GL_TEXTURE_2D); + _glMatrixMode(GL_MODELVIEW); + _glLoadIdentity(); + _glBegin(GL_LINES); + _glColor4ub(GLubyte(_Color0>>16), GLubyte(_Color0>>8), GLubyte(_Color0), GLubyte(_Color0>>24)); + _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy); + _glColor4ub(GLubyte(_Color1>>16), GLubyte(_Color1>>8), GLubyte(_Color1), GLubyte(_Color1>>24)); + _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy); + //_glVertex2i(_X0, _Y0); + //_glVertex2i(_X1, _Y1); + _glEnd(); + _glDisable(GL_LINE_SMOOTH); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11) +{ + assert(m_Drawing==true); + + /* + // border adjustment + if(_X0<_X1) + ++_X1; + else if(_X0>_X1) + ++_X0; + if(_Y0<_Y1) + ++_Y1; + else if(_Y0>_Y1) + ++_Y0; + */ + // border adjustment + if(_X0<_X1) + ++_X1; + else if(_X0>_X1) + ++_X0; + if(_Y0<_Y1) + --_Y0; + else if(_Y0>_Y1) + --_Y1; + const GLfloat dx = +0.0f; + const GLfloat dy = +0.0f; + + _glDisable(GL_TEXTURE_2D); + _glMatrixMode(GL_MODELVIEW); + _glLoadIdentity(); + //GLubyte r = GLubyte(_Color>>16); + //GLubyte g = GLubyte(_Color>>8); + //GLubyte b = GLubyte(_Color); + //GLubyte a = GLubyte(_Color>>24); + //_glColor4ub(GLubyte(_Color>>16), GLubyte(_Color>>8), GLubyte(_Color), GLubyte(_Color>>24)); + //_glColor4ub(r, g, b, a); + _glBegin(GL_QUADS); + _glColor4ub(GLubyte(_Color00>>16), GLubyte(_Color00>>8), GLubyte(_Color00), GLubyte(_Color00>>24)); + _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy); + _glColor4ub(GLubyte(_Color10>>16), GLubyte(_Color10>>8), GLubyte(_Color10), GLubyte(_Color10>>24)); + _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y0+dy); + _glColor4ub(GLubyte(_Color11>>16), GLubyte(_Color11>>8), GLubyte(_Color11), GLubyte(_Color11>>24)); + _glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy); + _glColor4ub(GLubyte(_Color01>>16), GLubyte(_Color01>>8), GLubyte(_Color01), GLubyte(_Color01>>24)); + _glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y1+dy); + _glEnd(); +} + +// --------------------------------------------------------------------------- + +void *CTwGraphOpenGL::NewTextObj() +{ + return new CTextObj; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::DeleteTextObj(void *_TextObj) +{ + assert(_TextObj!=NULL); + delete static_cast(_TextObj); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + assert(_Font!=NULL); + + if( _Font != m_FontTex ) + { + UnbindFont(m_FontTexID); + m_FontTexID = BindFont(_Font); + m_FontTex = _Font; + } + CTextObj *TextObj = static_cast(_TextObj); + TextObj->m_TextVerts.resize(0); + TextObj->m_TextUVs.resize(0); + TextObj->m_BgVerts.resize(0); + TextObj->m_Colors.resize(0); + TextObj->m_BgColors.resize(0); + + int x, x1, y, y1, i, Len; + unsigned char ch; + const unsigned char *Text; + color32 LineColor = COLOR32_RED; + for( int Line=0; Line<_NbLines; ++Line ) + { + x = 0; + y = Line * (_Font->m_CharHeight+_Sep); + y1 = y+_Font->m_CharHeight; + Len = (int)_TextLines[Line].length(); + Text = (const unsigned char *)(_TextLines[Line].c_str()); + if( _LineColors!=NULL ) + LineColor = (_LineColors[Line]&0xff00ff00) | GLubyte(_LineColors[Line]>>16) | (GLubyte(_LineColors[Line])<<16); + + for( i=0; im_CharWidth[ch]; + _Font->m_CharHeight; + + TextObj->m_TextVerts.push_back(Vec2(x , y )); + TextObj->m_TextVerts.push_back(Vec2(x1, y )); + TextObj->m_TextVerts.push_back(Vec2(x , y1)); + TextObj->m_TextVerts.push_back(Vec2(x1, y )); + TextObj->m_TextVerts.push_back(Vec2(x1, y1)); + TextObj->m_TextVerts.push_back(Vec2(x , y1)); + + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV0[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV1[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch])); + + if( _LineColors!=NULL ) + { + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + } + + x = x1; + } + if( _BgWidth>0 ) + { + TextObj->m_BgVerts.push_back(Vec2(-1 , y )); + TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y )); + TextObj->m_BgVerts.push_back(Vec2(-1 , y1)); + TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y )); + TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y1)); + TextObj->m_BgVerts.push_back(Vec2(-1 , y1)); + + if( _LineBgColors!=NULL ) + { + color32 LineBgColor = (_LineBgColors[Line]&0xff00ff00) | GLubyte(_LineBgColors[Line]>>16) | (GLubyte(_LineBgColors[Line])<<16); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + } + } + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + CTextObj *TextObj = static_cast(_TextObj); + + if( TextObj->m_TextVerts.size()<4 && TextObj->m_BgVerts.size()<4 ) + return; // nothing to draw + + _glMatrixMode(GL_MODELVIEW); + _glLoadIdentity(); + _glTranslatef((GLfloat)_X, (GLfloat)_Y, 0); + _glEnableClientState(GL_VERTEX_ARRAY); + if( (_BgColor!=0 || TextObj->m_BgColors.size()==TextObj->m_BgVerts.size()) && TextObj->m_BgVerts.size()>=4 ) + { + _glDisable(GL_TEXTURE_2D); + _glVertexPointer(2, GL_FLOAT, 0, &(TextObj->m_BgVerts[0])); + if( TextObj->m_BgColors.size()==TextObj->m_BgVerts.size() && _BgColor==0 ) + { + _glEnableClientState(GL_COLOR_ARRAY); + _glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(TextObj->m_BgColors[0])); + } + else + { + _glDisableClientState(GL_COLOR_ARRAY); + _glColor4ub(GLubyte(_BgColor>>16), GLubyte(_BgColor>>8), GLubyte(_BgColor), GLubyte(_BgColor>>24)); + } + _glDrawArrays(GL_TRIANGLES, 0, (int)TextObj->m_BgVerts.size()); + } + _glEnable(GL_TEXTURE_2D); + _glBindTexture(GL_TEXTURE_2D, m_FontTexID); + _glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if( TextObj->m_TextVerts.size()>=4 ) + { + _glVertexPointer(2, GL_FLOAT, 0, &(TextObj->m_TextVerts[0])); + _glTexCoordPointer(2, GL_FLOAT, 0, &(TextObj->m_TextUVs[0])); + if( TextObj->m_Colors.size()==TextObj->m_TextVerts.size() && _Color==0 ) + { + _glEnableClientState(GL_COLOR_ARRAY); + _glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(TextObj->m_Colors[0])); + } + else + { + _glDisableClientState(GL_COLOR_ARRAY); + _glColor4ub(GLubyte(_Color>>16), GLubyte(_Color>>8), GLubyte(_Color), GLubyte(_Color>>24)); + } + + _glDrawArrays(GL_TRIANGLES, 0, (int)TextObj->m_TextVerts.size()); + } + + _glDisableClientState(GL_VERTEX_ARRAY); + _glDisableClientState(GL_TEXTURE_COORD_ARRAY); + _glDisableClientState(GL_COLOR_ARRAY); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY) +{ + if( _Width>0 && _Height>0 ) + { + GLint vp[4]; + vp[0] = _X0; + vp[1] = _Y0; + vp[2] = _Width-1; + vp[3] = _Height-1; + _glViewport(vp[0], m_WndHeight-vp[1]-vp[3], vp[2], vp[3]); + + GLint matrixMode = 0; + _glGetIntegerv(GL_MATRIX_MODE, &matrixMode); + _glMatrixMode(GL_PROJECTION); + _glLoadIdentity(); + _glOrtho(_OffsetX, _OffsetX+vp[2], vp[3]-_OffsetY, -_OffsetY, -1, 1); + _glMatrixMode(matrixMode); + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::RestoreViewport() +{ + _glViewport(m_ViewportInit[0], m_ViewportInit[1], m_ViewportInit[2], m_ViewportInit[3]); + + GLint matrixMode = 0; + _glGetIntegerv(GL_MATRIX_MODE, &matrixMode); + _glMatrixMode(GL_PROJECTION); + _glLoadMatrixf(m_ProjMatrixInit); + _glMatrixMode(matrixMode); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::SetScissor(int _X0, int _Y0, int _Width, int _Height) +{ + if( _Width>0 && _Height>0 ) + { + _glScissor(_X0-1, m_WndHeight-_Y0-_Height, _Width-1, _Height); + _glEnable(GL_SCISSOR_TEST); + } + else + _glDisable(GL_SCISSOR_TEST); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGL::DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode) +{ + assert(m_Drawing==true); + + const GLfloat dx = +0.0f; + const GLfloat dy = +0.0f; + + GLint prevCullFaceMode, prevFrontFace; + _glGetIntegerv(GL_CULL_FACE_MODE, &prevCullFaceMode); + _glGetIntegerv(GL_FRONT_FACE, &prevFrontFace); + GLboolean prevCullEnable = _glIsEnabled(GL_CULL_FACE); + _glCullFace(GL_BACK); + _glEnable(GL_CULL_FACE); + if( _CullMode==CULL_CW ) + _glFrontFace(GL_CCW); + else if( _CullMode==CULL_CCW ) + _glFrontFace(GL_CW); + else + _glDisable(GL_CULL_FACE); + + _glDisable(GL_TEXTURE_2D); + _glMatrixMode(GL_MODELVIEW); + _glLoadIdentity(); + _glBegin(GL_TRIANGLES); + for(int i=0; i<3*_NumTriangles; ++i) + { + color32 col = _Colors[i]; + _glColor4ub(GLubyte(col>>16), GLubyte(col>>8), GLubyte(col), GLubyte(col>>24)); + _glVertex2f((GLfloat)_Vertices[2*i+0]+dx, (GLfloat)_Vertices[2*i+1]+dy); + } + _glEnd(); + + _glCullFace(prevCullFaceMode); + _glFrontFace(prevFrontFace); + if( prevCullEnable ) + _glEnable(GL_CULL_FACE); + else + _glDisable(GL_CULL_FACE); +} + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.h b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.h new file mode 100644 index 0000000..e2334e6 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGL.h @@ -0,0 +1,99 @@ +// --------------------------------------------------------------------------- +// +// @file TwOpenGL.h +// @brief OpenGL graph functions +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// notes: Private header +// TAB=4 +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_OPENGL_INCLUDED +#define ANT_TW_OPENGL_INCLUDED + +#include "TwGraph.h" + +// --------------------------------------------------------------------------- + +class CTwGraphOpenGL : public ITwGraph +{ +public: + virtual int Init(); + virtual int Shut(); + virtual void BeginDraw(int _WndWidth, int _WndHeight); + virtual void EndDraw(); + virtual bool IsDrawing(); + virtual void Restore(); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased=false); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color, bool _AntiAliased=false) { DrawLine(_X0, _Y0, _X1, _Y1, _Color, _Color, _AntiAliased); } + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11); + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color) { DrawRect(_X0, _Y0, _X1, _Y1, _Color, _Color, _Color, _Color); } + virtual void DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode); + + virtual void * NewTextObj(); + virtual void DeleteTextObj(void *_TextObj); + virtual void BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth); + virtual void DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor); + + virtual void ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY); + virtual void RestoreViewport(); + virtual void SetScissor(int _X0, int _Y0, int _Width, int _Height); + +protected: + bool m_Drawing; + GLuint m_FontTexID; + const CTexFont * m_FontTex; + GLfloat m_PrevLineWidth; + GLint m_PrevTexEnv; + GLint m_PrevPolygonMode[2]; + GLint m_MaxClipPlanes; + GLint m_PrevTexture; + GLint m_PrevArrayBufferARB; + GLint m_PrevElementArrayBufferARB; + GLboolean m_PrevVertexProgramARB; + GLboolean m_PrevFragmentProgramARB; + GLuint m_PrevProgramObjectARB; + GLboolean m_PrevTexture3D; + enum EMaxTextures { MAX_TEXTURES = 128 }; + GLboolean m_PrevActiveTexture1D[MAX_TEXTURES]; + GLboolean m_PrevActiveTexture2D[MAX_TEXTURES]; + GLboolean m_PrevActiveTexture3D[MAX_TEXTURES]; + GLboolean m_PrevClientTexCoordArray[MAX_TEXTURES]; + GLint m_PrevActiveTextureARB; + GLint m_PrevClientActiveTextureARB; + bool m_SupportTexRect; + GLboolean m_PrevTexRectARB; + GLint m_PrevBlendEquation; + GLint m_PrevBlendEquationRGB; + GLint m_PrevBlendEquationAlpha; + GLint m_PrevBlendSrcRGB; + GLint m_PrevBlendDstRGB; + GLint m_PrevBlendSrcAlpha; + GLint m_PrevBlendDstAlpha; + GLuint m_PrevVertexArray; + GLint m_ViewportInit[4]; + GLfloat m_ProjMatrixInit[16]; + enum EMaxVtxAttribs { MAX_VERTEX_ATTRIBS = 128 }; + GLint m_PrevEnabledVertexAttrib[MAX_VERTEX_ATTRIBS]; + int m_WndWidth; + int m_WndHeight; + + struct Vec2 { GLfloat x, y; Vec2(){} Vec2(GLfloat _X, GLfloat _Y):x(_X),y(_Y){} Vec2(int _X, int _Y):x(GLfloat(_X)),y(GLfloat(_Y)){} }; + struct CTextObj + { + std::vector m_TextVerts; + std::vector m_TextUVs; + std::vector m_BgVerts; + std::vectorm_Colors; + std::vectorm_BgColors; + }; +}; + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_OPENGL_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.cpp new file mode 100644 index 0000000..d955c11 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.cpp @@ -0,0 +1,927 @@ +// --------------------------------------------------------------------------- +// +// @file TwOpenGLCore.cpp +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// --------------------------------------------------------------------------- + +/* +#pragma warning GL3 //// used for development +#define GL3_PROTOTYPES 1 //// +#include //// +#define ANT_OGL_HEADER_INCLUDED //// +*/ + +#if defined ANT_OSX +# include +# define ANT_OGL_HEADER_INCLUDED +#endif +#include "TwPrecomp.h" +#include "LoadOGLCore.h" +#include "TwOpenGLCore.h" +#include "TwMgr.h" + +using namespace std; + +extern const char *g_ErrCantLoadOGL; +extern const char *g_ErrCantUnloadOGL; + +// --------------------------------------------------------------------------- + +#ifdef _DEBUG + static void CheckGLCoreError(const char *file, int line, const char *func) + { + int err=0; + char msg[256]; + while( (err=_glGetError())!=0 ) + { + sprintf(msg, "%s(%d) : [%s] GL_CORE_ERROR=0x%x\n", file, line, func, err); + #ifdef ANT_WINDOWS + OutputDebugString(msg); + #endif + fprintf(stderr, msg); + } + } +# ifdef __FUNCTION__ +# define CHECK_GL_ERROR CheckGLCoreError(__FILE__, __LINE__, __FUNCTION__) +# else +# define CHECK_GL_ERROR CheckGLCoreError(__FILE__, __LINE__, "") +# endif +#else +# define CHECK_GL_ERROR ((void)(0)) +#endif + +// --------------------------------------------------------------------------- + +static GLuint BindFont(const CTexFont *_Font) +{ + GLuint TexID = 0; + _glGenTextures(1, &TexID); + _glBindTexture(GL_TEXTURE_2D, TexID); + _glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + _glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); + _glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + _glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + _glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + _glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + _glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, _Font->m_TexWidth, _Font->m_TexHeight, 0, GL_RED, GL_UNSIGNED_BYTE, _Font->m_TexBytes); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST); + _glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST); + _glBindTexture(GL_TEXTURE_2D, 0); + + return TexID; +} + +static void UnbindFont(GLuint _FontTexID) +{ + if( _FontTexID>0 ) + _glDeleteTextures(1, &_FontTexID); +} + +// --------------------------------------------------------------------------- + +static GLuint CompileShader(GLuint shader) +{ + _glCompileShader(shader); CHECK_GL_ERROR; + + GLint status; + _glGetShaderiv(shader, GL_COMPILE_STATUS, &status); CHECK_GL_ERROR; + if (status == GL_FALSE) + { + GLint infoLogLength; + _glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); CHECK_GL_ERROR; + + GLchar strInfoLog[256]; + _glGetShaderInfoLog(shader, sizeof(strInfoLog), NULL, strInfoLog); CHECK_GL_ERROR; +#ifdef ANT_WINDOWS + OutputDebugString("Compile failure: "); + OutputDebugString(strInfoLog); + OutputDebugString("\n"); +#endif + fprintf(stderr, "Compile failure: %s\n", strInfoLog); + shader = 0; + } + + return shader; +} + +static GLuint LinkProgram(GLuint program) +{ + _glLinkProgram(program); CHECK_GL_ERROR; + + GLint status; + _glGetProgramiv(program, GL_LINK_STATUS, &status); CHECK_GL_ERROR; + if (status == GL_FALSE) + { + GLint infoLogLength; + _glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); CHECK_GL_ERROR; + + GLchar strInfoLog[256]; + _glGetProgramInfoLog(program, sizeof(strInfoLog), NULL, strInfoLog); CHECK_GL_ERROR; +#ifdef ANT_WINDOWS + OutputDebugString("Linker failure: "); + OutputDebugString(strInfoLog); + OutputDebugString("\n"); +#endif + fprintf(stderr, "Linker failure: %s\n", strInfoLog); + program = 0; + } + + return program; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::ResizeTriBuffers(size_t _NewSize) +{ + m_TriBufferSize = _NewSize; + + _glBindVertexArray(m_TriVArray); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriVertices); + _glBufferData(GL_ARRAY_BUFFER, m_TriBufferSize*sizeof(Vec2), 0, GL_DYNAMIC_DRAW); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriUVs); + _glBufferData(GL_ARRAY_BUFFER, m_TriBufferSize*sizeof(Vec2), 0, GL_DYNAMIC_DRAW); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriColors); + _glBufferData(GL_ARRAY_BUFFER, m_TriBufferSize*sizeof(color32), 0, GL_DYNAMIC_DRAW); + + CHECK_GL_ERROR; +} + +// --------------------------------------------------------------------------- + +int CTwGraphOpenGLCore::Init() +{ + m_Drawing = false; + m_FontTexID = 0; + m_FontTex = NULL; + + if( LoadOpenGLCore()==0 ) + { + g_TwMgr->SetLastError(g_ErrCantLoadOGL); + return 0; + } + + // Create line/rect shaders + const GLchar *lineRectVS[] = { + "#version 150 core\n" + "in vec3 vertex;" + "in vec4 color;" + "out vec4 fcolor;" + "void main() { gl_Position = vec4(vertex, 1); fcolor = color; }" + }; + m_LineRectVS = _glCreateShader(GL_VERTEX_SHADER); + _glShaderSource(m_LineRectVS, 1, lineRectVS, NULL); + CompileShader(m_LineRectVS); + + const GLchar *lineRectFS[] = { + "#version 150 core\n" + "precision highp float;" + "in vec4 fcolor;" + "out vec4 outColor;" + "void main() { outColor = fcolor; }" + }; + m_LineRectFS = _glCreateShader(GL_FRAGMENT_SHADER); + _glShaderSource(m_LineRectFS, 1, lineRectFS, NULL); + CompileShader(m_LineRectFS); + + m_LineRectProgram = _glCreateProgram(); + _glAttachShader(m_LineRectProgram, m_LineRectVS); + _glAttachShader(m_LineRectProgram, m_LineRectFS); + _glBindAttribLocation(m_LineRectProgram, 0, "vertex"); + _glBindAttribLocation(m_LineRectProgram, 1, "color"); + LinkProgram(m_LineRectProgram); + + // Create line/rect vertex buffer + const GLfloat lineRectInitVertices[] = { 0,0,0, 0,0,0, 0,0,0, 0,0,0 }; + const color32 lineRectInitColors[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + _glGenVertexArrays(1, &m_LineRectVArray); + _glBindVertexArray(m_LineRectVArray); + _glGenBuffers(1, &m_LineRectVertices); + _glBindBuffer(GL_ARRAY_BUFFER, m_LineRectVertices); + _glBufferData(GL_ARRAY_BUFFER, sizeof(lineRectInitVertices), lineRectInitVertices, GL_DYNAMIC_DRAW); + _glGenBuffers(1, &m_LineRectColors); + _glBindBuffer(GL_ARRAY_BUFFER, m_LineRectColors); + _glBufferData(GL_ARRAY_BUFFER, sizeof(lineRectInitColors), lineRectInitColors, GL_DYNAMIC_DRAW); + + // Create triangles shaders + const GLchar *triVS[] = { + "#version 150 core\n" + "uniform vec2 offset;" + "uniform vec2 wndSize;" + "in vec2 vertex;" + "in vec4 color;" + "out vec4 fcolor;" + "void main() { gl_Position = vec4(2.0*(vertex.x+offset.x-0.5)/wndSize.x - 1.0, 1.0 - 2.0*(vertex.y+offset.y-0.5)/wndSize.y, 0, 1); fcolor = color; }" + }; + m_TriVS = _glCreateShader(GL_VERTEX_SHADER); + _glShaderSource(m_TriVS, 1, triVS, NULL); + CompileShader(m_TriVS); + + const GLchar *triUniVS[] = { + "#version 150 core\n" + "uniform vec2 offset;" + "uniform vec2 wndSize;" + "uniform vec4 color;" + "in vec2 vertex;" + "out vec4 fcolor;" + "void main() { gl_Position = vec4(2.0*(vertex.x+offset.x-0.5)/wndSize.x - 1.0, 1.0 - 2.0*(vertex.y+offset.y-0.5)/wndSize.y, 0, 1); fcolor = color; }" + }; + m_TriUniVS = _glCreateShader(GL_VERTEX_SHADER); + _glShaderSource(m_TriUniVS, 1, triUniVS, NULL); + CompileShader(m_TriUniVS); + + m_TriFS = m_TriUniFS = m_LineRectFS; + + m_TriProgram = _glCreateProgram(); + _glAttachShader(m_TriProgram, m_TriVS); + _glAttachShader(m_TriProgram, m_TriFS); + _glBindAttribLocation(m_TriProgram, 0, "vertex"); + _glBindAttribLocation(m_TriProgram, 1, "color"); + LinkProgram(m_TriProgram); + m_TriLocationOffset = _glGetUniformLocation(m_TriProgram, "offset"); + m_TriLocationWndSize = _glGetUniformLocation(m_TriProgram, "wndSize"); + + m_TriUniProgram = _glCreateProgram(); + _glAttachShader(m_TriUniProgram, m_TriUniVS); + _glAttachShader(m_TriUniProgram, m_TriUniFS); + _glBindAttribLocation(m_TriUniProgram, 0, "vertex"); + _glBindAttribLocation(m_TriUniProgram, 1, "color"); + LinkProgram(m_TriUniProgram); + m_TriUniLocationOffset = _glGetUniformLocation(m_TriUniProgram, "offset"); + m_TriUniLocationWndSize = _glGetUniformLocation(m_TriUniProgram, "wndSize"); + m_TriUniLocationColor = _glGetUniformLocation(m_TriUniProgram, "color"); + + const GLchar *triTexFS[] = { + "#version 150 core\n" + "precision highp float;" + "uniform sampler2D tex;" + "in vec2 fuv;" + "in vec4 fcolor;" + "out vec4 outColor;" + "void main() { outColor.rgb = fcolor.bgr; outColor.a = fcolor.a * texture2D(tex, fuv).r; }" + }; + m_TriTexFS = _glCreateShader(GL_FRAGMENT_SHADER); + _glShaderSource(m_TriTexFS, 1, triTexFS, NULL); + CompileShader(m_TriTexFS); + + const GLchar *triTexVS[] = { + "#version 150 core\n" + "uniform vec2 offset;" + "uniform vec2 wndSize;" + "in vec2 vertex;" + "in vec2 uv;" + "in vec4 color;" + "out vec2 fuv;" + "out vec4 fcolor;" + "void main() { gl_Position = vec4(2.0*(vertex.x+offset.x-0.5)/wndSize.x - 1.0, 1.0 - 2.0*(vertex.y+offset.y-0.5)/wndSize.y, 0, 1); fuv = uv; fcolor = color; }" + }; + m_TriTexVS = _glCreateShader(GL_VERTEX_SHADER); + _glShaderSource(m_TriTexVS, 1, triTexVS, NULL); + CompileShader(m_TriTexVS); + + const GLchar *triTexUniVS[] = { + "#version 150 core\n" + "uniform vec2 offset;" + "uniform vec2 wndSize;" + "uniform vec4 color;" + "in vec2 vertex;" + "in vec2 uv;" + "out vec4 fcolor;" + "out vec2 fuv;" + "void main() { gl_Position = vec4(2.0*(vertex.x+offset.x-0.5)/wndSize.x - 1.0, 1.0 - 2.0*(vertex.y+offset.y-0.5)/wndSize.y, 0, 1); fuv = uv; fcolor = color; }" + }; + m_TriTexUniVS = _glCreateShader(GL_VERTEX_SHADER); + _glShaderSource(m_TriTexUniVS, 1, triTexUniVS, NULL); + CompileShader(m_TriTexUniVS); + + m_TriTexUniFS = m_TriTexFS; + + m_TriTexProgram = _glCreateProgram(); + _glAttachShader(m_TriTexProgram, m_TriTexVS); + _glAttachShader(m_TriTexProgram, m_TriTexFS); + _glBindAttribLocation(m_TriTexProgram, 0, "vertex"); + _glBindAttribLocation(m_TriTexProgram, 1, "uv"); + _glBindAttribLocation(m_TriTexProgram, 2, "color"); + LinkProgram(m_TriTexProgram); + m_TriTexLocationOffset = _glGetUniformLocation(m_TriTexProgram, "offset"); + m_TriTexLocationWndSize = _glGetUniformLocation(m_TriTexProgram, "wndSize"); + m_TriTexLocationTexture = _glGetUniformLocation(m_TriTexProgram, "tex"); + + m_TriTexUniProgram = _glCreateProgram(); + _glAttachShader(m_TriTexUniProgram, m_TriTexUniVS); + _glAttachShader(m_TriTexUniProgram, m_TriTexUniFS); + _glBindAttribLocation(m_TriTexUniProgram, 0, "vertex"); + _glBindAttribLocation(m_TriTexUniProgram, 1, "uv"); + _glBindAttribLocation(m_TriTexUniProgram, 2, "color"); + LinkProgram(m_TriTexUniProgram); + m_TriTexUniLocationOffset = _glGetUniformLocation(m_TriTexUniProgram, "offset"); + m_TriTexUniLocationWndSize = _glGetUniformLocation(m_TriTexUniProgram, "wndSize"); + m_TriTexUniLocationColor = _glGetUniformLocation(m_TriTexUniProgram, "color"); + m_TriTexUniLocationTexture = _glGetUniformLocation(m_TriTexUniProgram, "tex"); + + // Create tri vertex buffer + _glGenVertexArrays(1, &m_TriVArray); + _glGenBuffers(1, &m_TriVertices); + _glGenBuffers(1, &m_TriUVs); + _glGenBuffers(1, &m_TriColors); + ResizeTriBuffers(16384); // set initial size + + CHECK_GL_ERROR; + return 1; +} + +// --------------------------------------------------------------------------- + +int CTwGraphOpenGLCore::Shut() +{ + assert(m_Drawing==false); + + UnbindFont(m_FontTexID); + + CHECK_GL_ERROR; + + _glDeleteProgram(m_LineRectProgram); m_LineRectProgram = 0; + _glDeleteShader(m_LineRectVS); m_LineRectVS = 0; + _glDeleteShader(m_LineRectFS); m_LineRectFS = 0; + + _glDeleteProgram(m_TriProgram); m_TriProgram = 0; + _glDeleteShader(m_TriVS); m_TriVS = 0; + + _glDeleteProgram(m_TriUniProgram); m_TriUniProgram = 0; + _glDeleteShader(m_TriUniVS); m_TriUniVS = 0; + + _glDeleteProgram(m_TriTexProgram); m_TriTexProgram = 0; + _glDeleteShader(m_TriTexVS); m_TriTexVS = 0; + _glDeleteShader(m_TriTexFS); m_TriTexFS = 0; + + _glDeleteProgram(m_TriTexUniProgram); m_TriTexUniProgram = 0; + _glDeleteShader(m_TriTexUniVS); m_TriTexUniVS = 0; + + _glDeleteBuffers(1, &m_LineRectVertices); m_LineRectVertices = 0; + _glDeleteBuffers(1, &m_LineRectColors); m_LineRectColors = 0; + _glDeleteVertexArrays(1, &m_LineRectVArray); m_LineRectVArray = 0; + + _glDeleteBuffers(1, &m_TriVertices); m_TriVertices = 0; + _glDeleteBuffers(1, &m_TriColors); m_TriColors = 0; + _glDeleteBuffers(1, &m_TriUVs); m_TriUVs = 0; + _glDeleteVertexArrays(1, &m_TriVArray); m_TriVArray = 0; + + CHECK_GL_ERROR; + + int Res = 1; + if( UnloadOpenGLCore()==0 ) + { + g_TwMgr->SetLastError(g_ErrCantUnloadOGL); + Res = 0; + } + + return Res; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::BeginDraw(int _WndWidth, int _WndHeight) +{ + CHECK_GL_ERROR; + assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0); + m_Drawing = true; + m_WndWidth = _WndWidth; + m_WndHeight = _WndHeight; + m_OffsetX = 0; + m_OffsetY = 0; + + _glGetIntegerv(GL_VIEWPORT, m_PrevViewport); CHECK_GL_ERROR; + if( _WndWidth>0 && _WndHeight>0 ) + { + GLint Vp[4]; + Vp[0] = 0; + Vp[1] = 0; + Vp[2] = _WndWidth-1; + Vp[3] = _WndHeight-1; + _glViewport(Vp[0], Vp[1], Vp[2], Vp[3]); + } + + m_PrevVArray = 0; + _glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&m_PrevVArray); CHECK_GL_ERROR; + _glBindVertexArray(0); CHECK_GL_ERROR; + + m_PrevLineWidth = 1; + _glGetFloatv(GL_LINE_WIDTH, &m_PrevLineWidth); CHECK_GL_ERROR; + _glLineWidth(1); CHECK_GL_ERROR; + + m_PrevLineSmooth = _glIsEnabled(GL_LINE_SMOOTH); + _glDisable(GL_LINE_SMOOTH); CHECK_GL_ERROR; + + m_PrevCullFace = _glIsEnabled(GL_CULL_FACE); + _glDisable(GL_CULL_FACE); CHECK_GL_ERROR; + + m_PrevDepthTest = _glIsEnabled(GL_DEPTH_TEST); + _glDisable(GL_DEPTH_TEST); CHECK_GL_ERROR; + + m_PrevBlend = _glIsEnabled(GL_BLEND); + _glEnable(GL_BLEND); CHECK_GL_ERROR; + + m_PrevScissorTest = _glIsEnabled(GL_SCISSOR_TEST); + _glDisable(GL_SCISSOR_TEST); CHECK_GL_ERROR; + + _glGetIntegerv(GL_SCISSOR_BOX, m_PrevScissorBox); CHECK_GL_ERROR; + + _glGetIntegerv(GL_BLEND_SRC, &m_PrevSrcBlend); CHECK_GL_ERROR; + _glGetIntegerv(GL_BLEND_DST, &m_PrevDstBlend); CHECK_GL_ERROR; + _glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CHECK_GL_ERROR; + + m_PrevTexture = 0; + _glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_PrevTexture); CHECK_GL_ERROR; + _glBindTexture(GL_TEXTURE_2D, 0); CHECK_GL_ERROR; + + m_PrevProgramObject = 0; + _glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&m_PrevProgramObject); CHECK_GL_ERROR; + _glBindVertexArray(0); CHECK_GL_ERROR; + _glUseProgram(0); CHECK_GL_ERROR; + + m_PrevActiveTexture = 0; + _glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&m_PrevActiveTexture); CHECK_GL_ERROR; + _glActiveTexture(GL_TEXTURE0); + + CHECK_GL_ERROR; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::EndDraw() +{ + assert(m_Drawing==true); + m_Drawing = false; + + _glLineWidth(m_PrevLineWidth); CHECK_GL_ERROR; + + if( m_PrevLineSmooth ) + { + _glEnable(GL_LINE_SMOOTH); CHECK_GL_ERROR; + } + else + { + _glDisable(GL_LINE_SMOOTH); CHECK_GL_ERROR; + } + + if( m_PrevCullFace ) + { + _glEnable(GL_CULL_FACE); CHECK_GL_ERROR; + } + else + { + _glDisable(GL_CULL_FACE); CHECK_GL_ERROR; + } + + if( m_PrevDepthTest ) + { + _glEnable(GL_DEPTH_TEST); CHECK_GL_ERROR; + } + else + { + _glDisable(GL_DEPTH_TEST); CHECK_GL_ERROR; + } + + if( m_PrevBlend ) + { + _glEnable(GL_BLEND); CHECK_GL_ERROR; + } + else + { + _glDisable(GL_BLEND); CHECK_GL_ERROR; + } + + if( m_PrevScissorTest ) + { + _glEnable(GL_SCISSOR_TEST); CHECK_GL_ERROR; + } + else + { + _glDisable(GL_SCISSOR_TEST); CHECK_GL_ERROR; + } + + _glScissor(m_PrevScissorBox[0], m_PrevScissorBox[1], m_PrevScissorBox[2], m_PrevScissorBox[3]); CHECK_GL_ERROR; + + _glBlendFunc(m_PrevSrcBlend, m_PrevDstBlend); CHECK_GL_ERROR; + + _glBindTexture(GL_TEXTURE_2D, m_PrevTexture); CHECK_GL_ERROR; + + _glUseProgram(m_PrevProgramObject); CHECK_GL_ERROR; + + _glBindVertexArray(m_PrevVArray); CHECK_GL_ERROR; + + _glViewport(m_PrevViewport[0], m_PrevViewport[1], m_PrevViewport[2], m_PrevViewport[3]); CHECK_GL_ERROR; + + CHECK_GL_ERROR; +} + +// --------------------------------------------------------------------------- + +bool CTwGraphOpenGLCore::IsDrawing() +{ + return m_Drawing; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::Restore() +{ + UnbindFont(m_FontTexID); + m_FontTexID = 0; + m_FontTex = NULL; +} + +// --------------------------------------------------------------------------- + +static inline float ToNormScreenX(float x, int wndWidth) +{ + return 2.0f*((float)x-0.5f)/wndWidth - 1.0f; +} + +static inline float ToNormScreenY(float y, int wndHeight) +{ + return 1.0f - 2.0f*((float)y-0.5f)/wndHeight; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased) +{ + CHECK_GL_ERROR; + assert(m_Drawing==true); + + //const GLfloat dx = +0.0f; + const GLfloat dx = 0; + //GLfloat dy = -0.2f; + const GLfloat dy = -0.5f; + if( _AntiAliased ) + _glEnable(GL_LINE_SMOOTH); + else + _glDisable(GL_LINE_SMOOTH); + + _glBindVertexArray(m_LineRectVArray); + + GLfloat x0 = ToNormScreenX(_X0+dx + m_OffsetX, m_WndWidth); + GLfloat y0 = ToNormScreenY(_Y0+dy + m_OffsetY, m_WndHeight); + GLfloat x1 = ToNormScreenX(_X1+dx + m_OffsetX, m_WndWidth); + GLfloat y1 = ToNormScreenY(_Y1+dy + m_OffsetY, m_WndHeight); + GLfloat vertices[] = { x0,y0,0, x1,y1,0 }; + _glBindBuffer(GL_ARRAY_BUFFER, m_LineRectVertices); + _glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + _glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(0); + + color32 colors[] = { _Color0, _Color1 }; + _glBindBuffer(GL_ARRAY_BUFFER, m_LineRectColors); + _glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(colors), colors); + _glVertexAttribPointer(1, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(1); + + _glUseProgram(m_LineRectProgram); + _glDrawArrays(GL_LINES, 0, 2); + + if( _AntiAliased ) + _glDisable(GL_LINE_SMOOTH); + + CHECK_GL_ERROR; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11) +{ + CHECK_GL_ERROR; + assert(m_Drawing==true); + + // border adjustment + if(_X0<_X1) + ++_X1; + else if(_X0>_X1) + ++_X0; + if(_Y0<_Y1) + --_Y0; + else if(_Y0>_Y1) + --_Y1; + + _glBindVertexArray(m_LineRectVArray); + + GLfloat x0 = ToNormScreenX((float)_X0 + m_OffsetX, m_WndWidth); + GLfloat y0 = ToNormScreenY((float)_Y0 + m_OffsetY, m_WndHeight); + GLfloat x1 = ToNormScreenX((float)_X1 + m_OffsetX, m_WndWidth); + GLfloat y1 = ToNormScreenY((float)_Y1 + m_OffsetY, m_WndHeight); + GLfloat vertices[] = { x0,y0,0, x1,y0,0, x0,y1,0, x1,y1,0 }; + _glBindBuffer(GL_ARRAY_BUFFER, m_LineRectVertices); + _glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + _glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(0); + + GLuint colors[] = { _Color00, _Color10, _Color01, _Color11 }; + _glBindBuffer(GL_ARRAY_BUFFER, m_LineRectColors); + _glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(colors), colors); + _glVertexAttribPointer(1, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(1); + + _glUseProgram(m_LineRectProgram); + _glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + CHECK_GL_ERROR; +} + +// --------------------------------------------------------------------------- + +void *CTwGraphOpenGLCore::NewTextObj() +{ + return new CTextObj; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::DeleteTextObj(void *_TextObj) +{ + assert(_TextObj!=NULL); + delete static_cast(_TextObj); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth) +{ + assert(m_Drawing==true); + assert(_TextObj!=NULL); + assert(_Font!=NULL); + + if( _Font != m_FontTex ) + { + UnbindFont(m_FontTexID); + m_FontTexID = BindFont(_Font); + m_FontTex = _Font; + } + CTextObj *TextObj = static_cast(_TextObj); + TextObj->m_TextVerts.resize(0); + TextObj->m_TextUVs.resize(0); + TextObj->m_BgVerts.resize(0); + TextObj->m_Colors.resize(0); + TextObj->m_BgColors.resize(0); + + int x, x1, y, y1, i, Len; + unsigned char ch; + const unsigned char *Text; + color32 LineColor = COLOR32_RED; + for( int Line=0; Line<_NbLines; ++Line ) + { + x = 0; + y = Line * (_Font->m_CharHeight+_Sep); + y1 = y+_Font->m_CharHeight; + Len = (int)_TextLines[Line].length(); + Text = (const unsigned char *)(_TextLines[Line].c_str()); + if( _LineColors!=NULL ) + LineColor = (_LineColors[Line]&0xff00ff00) | GLubyte(_LineColors[Line]>>16) | (GLubyte(_LineColors[Line])<<16); + + for( i=0; im_CharWidth[ch]; + + TextObj->m_TextVerts.push_back(Vec2(x , y )); + TextObj->m_TextVerts.push_back(Vec2(x1, y )); + TextObj->m_TextVerts.push_back(Vec2(x , y1)); + TextObj->m_TextVerts.push_back(Vec2(x1, y )); + TextObj->m_TextVerts.push_back(Vec2(x1, y1)); + TextObj->m_TextVerts.push_back(Vec2(x , y1)); + + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV0[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV0[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU1[ch], _Font->m_CharV1[ch])); + TextObj->m_TextUVs.push_back(Vec2(_Font->m_CharU0[ch], _Font->m_CharV1[ch])); + + if( _LineColors!=NULL ) + { + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + TextObj->m_Colors.push_back(LineColor); + } + + x = x1; + } + if( _BgWidth>0 ) + { + TextObj->m_BgVerts.push_back(Vec2(-1 , y )); + TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y )); + TextObj->m_BgVerts.push_back(Vec2(-1 , y1)); + TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y )); + TextObj->m_BgVerts.push_back(Vec2(_BgWidth+1, y1)); + TextObj->m_BgVerts.push_back(Vec2(-1 , y1)); + + if( _LineBgColors!=NULL ) + { + color32 LineBgColor = (_LineBgColors[Line]&0xff00ff00) | GLubyte(_LineBgColors[Line]>>16) | (GLubyte(_LineBgColors[Line])<<16); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + TextObj->m_BgColors.push_back(LineBgColor); + } + } + } +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor) +{ + CHECK_GL_ERROR; + assert(m_Drawing==true); + assert(_TextObj!=NULL); + CTextObj *TextObj = static_cast(_TextObj); + + if( TextObj->m_TextVerts.size()<4 && TextObj->m_BgVerts.size()<4 ) + return; // nothing to draw + + // draw character background triangles + if( (_BgColor!=0 || TextObj->m_BgColors.size()==TextObj->m_BgVerts.size()) && TextObj->m_BgVerts.size()>=4 ) + { + size_t numBgVerts = TextObj->m_BgVerts.size(); + if( numBgVerts > m_TriBufferSize ) + ResizeTriBuffers(numBgVerts + 2048); + + _glBindVertexArray(m_TriVArray); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriVertices); + _glBufferSubData(GL_ARRAY_BUFFER, 0, numBgVerts*sizeof(Vec2), &(TextObj->m_BgVerts[0])); + _glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(0); + _glDisableVertexAttribArray(1); + _glDisableVertexAttribArray(2); + + if( TextObj->m_BgColors.size()==TextObj->m_BgVerts.size() && _BgColor==0 ) + { + _glBindBuffer(GL_ARRAY_BUFFER, m_TriColors); + _glBufferSubData(GL_ARRAY_BUFFER, 0, numBgVerts*sizeof(color32), &(TextObj->m_BgColors[0])); + _glVertexAttribPointer(1, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(1); + + _glUseProgram(m_TriProgram); + _glUniform2f(m_TriLocationOffset, (float)_X, (float)_Y); + _glUniform2f(m_TriLocationWndSize, (float)m_WndWidth, (float)m_WndHeight); + } + else + { + _glUseProgram(m_TriUniProgram); + _glUniform4f(m_TriUniLocationColor, GLfloat((_BgColor>>16)&0xff)/256.0f, GLfloat((_BgColor>>8)&0xff)/256.0f, GLfloat(_BgColor&0xff)/256.0f, GLfloat((_BgColor>>24)&0xff)/256.0f); + _glUniform2f(m_TriUniLocationOffset, (float)_X, (float)_Y); + _glUniform2f(m_TriUniLocationWndSize, (float)m_WndWidth, (float)m_WndHeight); + } + + _glDrawArrays(GL_TRIANGLES, 0, (GLsizei)TextObj->m_BgVerts.size()); + } + + // draw character triangles + if( TextObj->m_TextVerts.size()>=4 ) + { + _glActiveTexture(GL_TEXTURE0); + _glBindTexture(GL_TEXTURE_2D, m_FontTexID); + size_t numTextVerts = TextObj->m_TextVerts.size(); + if( numTextVerts > m_TriBufferSize ) + ResizeTriBuffers(numTextVerts + 2048); + + _glBindVertexArray(m_TriVArray); + _glDisableVertexAttribArray(2); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriVertices); + _glBufferSubData(GL_ARRAY_BUFFER, 0, numTextVerts*sizeof(Vec2), &(TextObj->m_TextVerts[0])); + _glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(0); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriUVs); + _glBufferSubData(GL_ARRAY_BUFFER, 0, numTextVerts*sizeof(Vec2), &(TextObj->m_TextUVs[0])); + _glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL); + _glEnableVertexAttribArray(1); + + if( TextObj->m_Colors.size()==TextObj->m_TextVerts.size() && _Color==0 ) + { + _glBindBuffer(GL_ARRAY_BUFFER, m_TriColors); + _glBufferSubData(GL_ARRAY_BUFFER, 0, numTextVerts*sizeof(color32), &(TextObj->m_Colors[0])); + _glVertexAttribPointer(2, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(2); + + _glUseProgram(m_TriTexProgram); + _glUniform2f(m_TriTexLocationOffset, (float)_X, (float)_Y); + _glUniform2f(m_TriTexLocationWndSize, (float)m_WndWidth, (float)m_WndHeight); + _glUniform1i(m_TriTexLocationTexture, 0); + } + else + { + _glUseProgram(m_TriTexUniProgram); + _glUniform4f(m_TriTexUniLocationColor, GLfloat((_Color>>16)&0xff)/256.0f, GLfloat((_Color>>8)&0xff)/256.0f, GLfloat(_Color&0xff)/256.0f, GLfloat((_Color>>24)&0xff)/256.0f); + _glUniform2f(m_TriTexUniLocationOffset, (float)_X, (float)_Y); + _glUniform2f(m_TriTexUniLocationWndSize, (float)m_WndWidth, (float)m_WndHeight); + _glUniform1i(m_TriTexUniLocationTexture, 0); + } + + _glDrawArrays(GL_TRIANGLES, 0, (GLsizei)TextObj->m_TextVerts.size()); + } + + CHECK_GL_ERROR; +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY) +{ + // glViewport impacts the NDC; use glScissor instead + m_OffsetX = _X0 + _OffsetX; + m_OffsetY = _Y0 + _OffsetY; + SetScissor(_X0, _Y0, _Width, _Height); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::RestoreViewport() +{ + m_OffsetX = m_OffsetY = 0; + SetScissor(0, 0, 0, 0); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::SetScissor(int _X0, int _Y0, int _Width, int _Height) +{ + if( _Width>0 && _Height>0 ) + { + _glScissor(_X0-1, m_WndHeight-_Y0-_Height, _Width-1, _Height); + _glEnable(GL_SCISSOR_TEST); + } + else + _glDisable(GL_SCISSOR_TEST); +} + +// --------------------------------------------------------------------------- + +void CTwGraphOpenGLCore::DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode) +{ + assert(m_Drawing==true); + + const GLfloat dx = +0.0f; + const GLfloat dy = +0.0f; + + // Backup states + GLint prevCullFaceMode, prevFrontFace; + _glGetIntegerv(GL_CULL_FACE_MODE, &prevCullFaceMode); + _glGetIntegerv(GL_FRONT_FACE, &prevFrontFace); + GLboolean prevCullEnable = _glIsEnabled(GL_CULL_FACE); + _glCullFace(GL_BACK); + _glEnable(GL_CULL_FACE); + if( _CullMode==CULL_CW ) + _glFrontFace(GL_CCW); + else if( _CullMode==CULL_CCW ) + _glFrontFace(GL_CW); + else + _glDisable(GL_CULL_FACE); + + _glUseProgram(m_TriProgram); + _glBindVertexArray(m_TriVArray); + _glUniform2f(m_TriLocationOffset, (float)m_OffsetX+dx, (float)m_OffsetY+dy); + _glUniform2f(m_TriLocationWndSize, (float)m_WndWidth, (float)m_WndHeight); + _glDisableVertexAttribArray(2); + + size_t numVerts = 3*_NumTriangles; + if( numVerts > m_TriBufferSize ) + ResizeTriBuffers(numVerts + 2048); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriVertices); + _glBufferSubData(GL_ARRAY_BUFFER, 0, numVerts*2*sizeof(int), _Vertices); + _glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, NULL); + _glEnableVertexAttribArray(0); + + _glBindBuffer(GL_ARRAY_BUFFER, m_TriColors); + _glBufferSubData(GL_ARRAY_BUFFER, 0, numVerts*sizeof(color32), _Colors); + _glVertexAttribPointer(1, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 0, NULL); + _glEnableVertexAttribArray(1); + + _glDrawArrays(GL_TRIANGLES, 0, (GLsizei)numVerts); + + // Reset states + _glCullFace(prevCullFaceMode); + _glFrontFace(prevFrontFace); + if( prevCullEnable ) + _glEnable(GL_CULL_FACE); + else + _glDisable(GL_CULL_FACE); + + CHECK_GL_ERROR; +} + +// --------------------------------------------------------------------------- diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.h b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.h new file mode 100644 index 0000000..a615d8a --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwOpenGLCore.h @@ -0,0 +1,121 @@ +// --------------------------------------------------------------------------- +// +// @file TwOpenGLCore.h +// @brief OpenGL Core graph functions +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_OPENGL_CORE_INCLUDED +#define ANT_TW_OPENGL_CORE_INCLUDED + +#include "TwGraph.h" + +// --------------------------------------------------------------------------- + +class CTwGraphOpenGLCore : public ITwGraph +{ +public: + virtual int Init(); + virtual int Shut(); + virtual void BeginDraw(int _WndWidth, int _WndHeight); + virtual void EndDraw(); + virtual bool IsDrawing(); + virtual void Restore(); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased=false); + virtual void DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color, bool _AntiAliased=false) { DrawLine(_X0, _Y0, _X1, _Y1, _Color, _Color, _AntiAliased); } + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11); + virtual void DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color) { DrawRect(_X0, _Y0, _X1, _Y1, _Color, _Color, _Color, _Color); } + virtual void DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode); + + virtual void * NewTextObj(); + virtual void DeleteTextObj(void *_TextObj); + virtual void BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth); + virtual void DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor); + + virtual void ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY); + virtual void RestoreViewport(); + virtual void SetScissor(int _X0, int _Y0, int _Width, int _Height); + +protected: + bool m_Drawing; + GLuint m_FontTexID; + const CTexFont * m_FontTex; + + GLfloat m_PrevLineWidth; + GLint m_PrevActiveTexture; + GLint m_PrevTexture; + GLint m_PrevVArray; + GLboolean m_PrevLineSmooth; + GLboolean m_PrevCullFace; + GLboolean m_PrevDepthTest; + GLboolean m_PrevBlend; + GLint m_PrevSrcBlend; + GLint m_PrevDstBlend; + GLboolean m_PrevScissorTest; + GLint m_PrevScissorBox[4]; + GLint m_PrevViewport[4]; + GLuint m_PrevProgramObject; + + GLuint m_LineRectVS; + GLuint m_LineRectFS; + GLuint m_LineRectProgram; + GLuint m_LineRectVArray; + GLuint m_LineRectVertices; + GLuint m_LineRectColors; + GLuint m_TriVS; + GLuint m_TriFS; + GLuint m_TriProgram; + GLuint m_TriUniVS; + GLuint m_TriUniFS; + GLuint m_TriUniProgram; + GLuint m_TriTexVS; + GLuint m_TriTexFS; + GLuint m_TriTexProgram; + GLuint m_TriTexUniVS; + GLuint m_TriTexUniFS; + GLuint m_TriTexUniProgram; + GLuint m_TriVArray; + GLuint m_TriVertices; + GLuint m_TriUVs; + GLuint m_TriColors; + GLint m_TriLocationOffset; + GLint m_TriLocationWndSize; + GLint m_TriUniLocationOffset; + GLint m_TriUniLocationWndSize; + GLint m_TriUniLocationColor; + GLint m_TriTexLocationOffset; + GLint m_TriTexLocationWndSize; + GLint m_TriTexLocationTexture; + GLint m_TriTexUniLocationOffset; + GLint m_TriTexUniLocationWndSize; + GLint m_TriTexUniLocationColor; + GLint m_TriTexUniLocationTexture; + size_t m_TriBufferSize; + + int m_WndWidth; + int m_WndHeight; + int m_OffsetX; + int m_OffsetY; + + struct Vec2 { GLfloat x, y; Vec2(){} Vec2(GLfloat _X, GLfloat _Y):x(_X),y(_Y){} Vec2(int _X, int _Y):x(GLfloat(_X)),y(GLfloat(_Y)){} }; + struct CTextObj + { + std::vector m_TextVerts; + std::vector m_TextUVs; + std::vector m_BgVerts; + std::vectorm_Colors; + std::vectorm_BgColors; + }; + void ResizeTriBuffers(size_t _NewSize); +}; + +// --------------------------------------------------------------------------- + + +#endif // !defined ANT_TW_OPENGL_CORE_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.cpp b/Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.cpp new file mode 100644 index 0000000..6c9502e --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.cpp @@ -0,0 +1 @@ +#include "TwPrecomp.h" diff --git a/Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.h b/Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.h new file mode 100644 index 0000000..717f448 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/TwPrecomp.h @@ -0,0 +1,93 @@ +// --------------------------------------------------------------------------- +// +// @file TwPrecomp.h +// @brief Precompiled header +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +#if !defined ANT_TW_PRECOMP_INCLUDED +#define ANT_TW_PRECOMP_INCLUDED + + +#if defined _MSC_VER +# pragma warning(disable: 4514) // unreferenced inline function has been removed +# pragma warning(disable: 4710) // function not inlined +# pragma warning(disable: 4786) // template name truncated +# pragma warning(disable: 4530) // exceptions not handled +# define _CRT_SECURE_NO_DEPRECATE // visual 8 secure crt warning +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER<=1200 +# pragma warning(push, 3) +#endif +#include +#include +#include +#include +#include +#include +#if defined(_MSC_VER) && _MSC_VER<=1200 +# pragma warning(pop) +#endif + +#if defined(_UNIX) +# define ANT_UNIX +# include +# define GLX_GLXEXT_LEGACY +# include +# include +# include +# include +# undef _WIN32 +# undef WIN32 +# undef _WIN64 +# undef WIN64 +# undef _WINDOWS +# undef ANT_WINDOWS +# undef ANT_OSX +#elif defined(_MACOSX) +# define ANT_OSX +# include +# include +# include +# include +# undef _WIN32 +# undef WIN32 +# undef _WIN64 +# undef WIN64 +# undef _WINDOWS +# undef ANT_WINDOWS +# undef ANT_UNIX +#elif defined(_WINDOWS) || defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64) +# define ANT_WINDOWS +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +# endif +# include +# include +#endif + +#if !defined(ANT_OGL_HEADER_INCLUDED) +# if defined(ANT_OSX) +# include +# else +# include // must be included after windows.h +# endif +# define ANT_OGL_HEADER_INCLUDED +#endif + +#endif // !defined ANT_TW_PRECOMP_INCLUDED diff --git a/Extras/CDTestFramework/AntTweakBar/src/d3d10vs2003.h b/Extras/CDTestFramework/AntTweakBar/src/d3d10vs2003.h new file mode 100644 index 0000000..7f32914 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/d3d10vs2003.h @@ -0,0 +1,46 @@ +// Workaround to include D3D10.h with VS2003 +#ifndef __out +#define __out +#endif +#ifndef __in +#define __in +#endif +#ifndef __inout +#define __inout +#endif +#ifndef __in_opt +#define __in_opt +#endif +#ifndef __out_opt +#define __out_opt +#endif +#ifndef __inout_opt +#define __inout_opt +#endif +#ifndef __in_ecount +#define __in_ecount(x) +#endif +#ifndef __in_ecount_opt +#define __in_ecount_opt(x) +#endif +#ifndef __out_ecount +#define __out_ecount(x) +#endif +#ifndef __out_ecount_opt +#define __out_ecount_opt(x) +#endif +#ifndef __inout_ecount +#define __inout_ecount(x) +#endif +#ifndef __inout_ecount_opt +#define __inout_ecount_opt(x) +#endif +#ifndef __in_bcount_opt +#define __in_bcount_opt(x) +#endif +#ifndef __out_bcount_opt +#define __out_bcount_opt(x) +#endif +#ifndef __inout_bcount_opt +#define __inout_bcount_opt(x) +#endif diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/FontChars.txt b/Extras/CDTestFramework/AntTweakBar/src/res/FontChars.txt new file mode 100644 index 0000000..17757bb --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/res/FontChars.txt @@ -0,0 +1,232 @@ + !"#$%&'()*+,-./0123456789:;<=>? +@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ +`abcdefghijklmnopqrstuvwxyz{|}~√ +€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ + ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ +ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß +àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ + +032 +033 ! +034 " +035 # +036 $ +037 % +038 & +039 ' +040 ( +041 ) +042 * +043 + +044 , +045 - +046 . +047 / +048 0 +049 1 +050 2 +051 3 +052 4 +053 5 +054 6 +055 7 +056 8 +057 9 +058 : +059 ; +060 < +061 = +062 > +063 ? +064 @ +065 A +066 B +067 C +068 D +069 E +070 F +071 G +072 H +073 I +074 J +075 K +076 L +077 M +078 N +079 O +080 P +081 Q +082 R +083 S +084 T +085 U +086 V +087 W +088 X +089 Y +090 Z +091 [ +092 \ +093 ] +094 ^ +095 _ +096 ` +097 a +098 b +099 c +100 d +101 e +102 f +103 g +104 h +105 i +106 j +107 k +108 l +109 m +110 n +111 o +112 p +113 q +114 r +115 s +116 t +117 u +118 v +119 w +120 x +121 y +122 z +123 { +124 | +125 } +126 ~ +127 √ +128 € +129  +130 ‚ +131 ƒ +132 „ +133 … +134 † +135 ‡ +136 ˆ +137 ‰ +138 Å  +139 ‹ +140 Œ +141  +142 Ž +143  +144  +145 ‘ +146 ’ +147 “ +148 ” +149 • +150 – +151 — +152 ˜ +153 ™ +154 Å¡ +155 › +156 œ +157  +158 ž +159 Ÿ +160   +161 ¡ +162 ¢ +163 £ +164 ¤ +165 Â¥ +166 ¦ +167 § +168 ¨ +169 © +170 ª +171 « +172 ¬ +173 ­ +174 ® +175 ¯ +176 ° +177 ± +178 ² +179 ³ +180 ´ +181 µ +182 ¶ +183 · +184 ¸ +185 ¹ +186 º +187 » +188 ¼ +189 ½ +190 ¾ +191 ¿ +192 À +193 Á +194  +195 à +196 Ä +197 Å +198 Æ +199 Ç +200 È +201 É +202 Ê +203 Ë +204 Ì +205 Í +206 Î +207 Ï +208 Ð +209 Ñ +210 Ò +211 Ó +212 Ô +213 Õ +214 Ö +215 × +216 Ø +217 Ù +218 Ú +219 Û +220 Ü +221 Ý +222 Þ +223 ß +224 à +225 á +226 â +227 ã +228 ä +229 Ã¥ +230 æ +231 ç +232 è +233 é +234 ê +235 ë +236 ì +237 í +238 î +239 ï +240 ð +241 ñ +242 ò +243 ó +244 ô +245 õ +246 ö +247 ÷ +248 ø +249 ù +250 ú +251 û +252 ü +253 ý +254 þ +255 ÿ diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/FontFixed1.pgm b/Extras/CDTestFramework/AntTweakBar/src/res/FontFixed1.pgm new file mode 100644 index 0000000..ef7a41a --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/res/FontFixed1.pgm @@ -0,0 +1,28788 @@ +P2 +# CREATOR: GIMP PNM Filter Version 1.1 +257 112 +255 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +56 +255 +4 +0 +0 +0 +0 +0 +212 +44 +76 +180 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +109 +231 +218 +72 +0 +0 +0 +0 +0 +96 +227 +243 +170 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +158 +104 +0 +0 +0 +0 +153 +114 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +172 +128 +0 +0 +12 +164 +241 +234 +133 +1 +0 +0 +22 +179 +237 +255 +4 +0 +0 +0 +141 +220 +246 +236 +164 +22 +0 +0 +94 +216 +242 +243 +194 +56 +0 +0 +0 +0 +0 +186 +255 +4 +0 +0 +52 +255 +244 +244 +244 +91 +0 +0 +1 +120 +223 +244 +225 +62 +0 +0 +244 +244 +244 +244 +249 +242 +0 +0 +62 +200 +245 +242 +181 +35 +0 +0 +46 +196 +244 +232 +139 +2 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +104 +216 +246 +215 +62 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +56 +255 +4 +0 +0 +0 +0 +13 +239 +2 +131 +124 +0 +0 +110 +232 +255 +238 +202 +62 +0 +29 +254 +51 +99 +231 +0 +0 +0 +0 +0 +241 +53 +0 +34 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +45 +225 +4 +0 +0 +0 +0 +30 +237 +15 +0 +0 +0 +0 +99 +95 +52 +255 +11 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +38 +242 +19 +0 +0 +155 +188 +12 +29 +221 +103 +0 +0 +21 +101 +90 +255 +4 +0 +0 +0 +127 +46 +1 +15 +165 +192 +0 +0 +34 +24 +0 +5 +127 +233 +0 +0 +0 +0 +98 +197 +255 +4 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +121 +219 +45 +0 +22 +27 +0 +0 +0 +0 +0 +0 +170 +151 +0 +14 +242 +119 +4 +12 +160 +207 +0 +3 +224 +136 +5 +18 +188 +114 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +114 +38 +2 +133 +225 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +56 +255 +4 +0 +0 +0 +0 +67 +189 +0 +187 +69 +0 +26 +254 +100 +255 +8 +53 +44 +0 +30 +254 +49 +100 +235 +0 +1 +0 +0 +0 +206 +47 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +155 +133 +0 +0 +0 +0 +0 +0 +186 +110 +0 +0 +0 +0 +3 +103 +195 +255 +177 +75 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +156 +144 +0 +0 +5 +244 +63 +0 +0 +112 +200 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +60 +251 +0 +0 +0 +0 +0 +10 +127 +211 +0 +0 +0 +25 +215 +67 +255 +4 +0 +0 +52 +255 +4 +0 +0 +0 +0 +1 +235 +77 +0 +0 +0 +0 +0 +0 +0 +0 +0 +24 +250 +49 +0 +44 +255 +15 +0 +0 +64 +251 +0 +41 +255 +17 +0 +0 +68 +205 +0 +0 +0 +43 +216 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +47 +147 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +197 +97 +11 +0 +0 +0 +0 +0 +0 +0 +0 +69 +248 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +63 +240 +247 +248 +240 +254 +241 +0 +42 +255 +69 +255 +4 +0 +0 +0 +0 +112 +232 +221 +80 +97 +184 +0 +0 +14 +189 +196 +7 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +1 +233 +64 +0 +0 +0 +0 +0 +0 +117 +186 +0 +0 +0 +0 +3 +102 +194 +255 +177 +74 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +26 +244 +30 +0 +0 +37 +255 +37 +175 +0 +66 +244 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +126 +195 +0 +0 +0 +48 +241 +255 +190 +16 +0 +0 +0 +176 +90 +52 +255 +4 +0 +0 +52 +255 +228 +236 +162 +16 +0 +33 +255 +106 +220 +237 +172 +21 +0 +0 +0 +0 +0 +125 +203 +0 +0 +4 +205 +120 +6 +14 +160 +159 +0 +40 +255 +21 +0 +0 +69 +245 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +13 +102 +203 +225 +132 +0 +0 +240 +240 +240 +240 +240 +240 +0 +0 +84 +180 +237 +152 +52 +0 +0 +0 +0 +0 +11 +204 +150 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +190 +66 +54 +202 +0 +0 +2 +196 +220 +255 +106 +32 +0 +0 +0 +0 +13 +116 +184 +93 +4 +0 +0 +176 +114 +109 +159 +0 +52 +0 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +29 +255 +22 +0 +0 +0 +0 +0 +0 +72 +236 +0 +0 +0 +0 +99 +96 +52 +255 +11 +128 +0 +0 +240 +240 +243 +255 +240 +240 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +140 +161 +0 +0 +0 +49 +255 +33 +216 +0 +54 +255 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +68 +236 +45 +0 +0 +0 +0 +0 +27 +198 +133 +0 +0 +87 +189 +0 +52 +255 +4 +0 +0 +19 +40 +0 +29 +197 +168 +0 +49 +255 +146 +9 +15 +182 +176 +0 +0 +0 +0 +3 +226 +100 +0 +0 +0 +28 +210 +252 +255 +182 +7 +0 +2 +223 +142 +6 +20 +186 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +43 +216 +3 +0 +0 +0 +0 +158 +233 +162 +67 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +23 +115 +210 +208 +0 +0 +0 +0 +176 +192 +6 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +7 +239 +9 +118 +138 +0 +0 +0 +5 +109 +255 +153 +234 +112 +0 +0 +88 +179 +76 +110 +231 +220 +0 +28 +255 +16 +0 +176 +110 +68 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +46 +255 +8 +0 +0 +0 +0 +0 +0 +57 +253 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +244 +244 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +17 +241 +43 +0 +0 +0 +37 +255 +17 +0 +0 +66 +244 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +73 +233 +60 +0 +0 +0 +0 +0 +0 +0 +69 +238 +0 +16 +227 +40 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +69 +246 +0 +38 +255 +20 +0 +0 +69 +247 +0 +0 +0 +0 +79 +242 +11 +0 +0 +5 +214 +122 +7 +16 +162 +175 +0 +0 +46 +193 +239 +210 +125 +241 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +202 +215 +114 +23 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +2 +67 +162 +236 +0 +0 +0 +34 +255 +31 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +236 +244 +251 +240 +251 +244 +228 +0 +0 +0 +52 +255 +4 +76 +245 +0 +0 +11 +0 +29 +254 +51 +101 +0 +40 +255 +30 +0 +18 +222 +193 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +29 +255 +23 +0 +0 +0 +0 +0 +0 +72 +237 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +124 +178 +0 +0 +0 +0 +5 +245 +63 +0 +0 +111 +200 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +87 +233 +54 +0 +0 +0 +0 +0 +0 +0 +0 +70 +248 +0 +52 +255 +255 +255 +255 +255 +255 +0 +0 +0 +0 +0 +0 +68 +246 +0 +6 +248 +19 +0 +0 +65 +247 +0 +0 +0 +0 +185 +151 +0 +0 +0 +42 +255 +15 +0 +0 +59 +252 +0 +0 +0 +0 +0 +0 +124 +188 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +46 +147 +234 +180 +86 +0 +0 +244 +244 +244 +244 +244 +244 +0 +0 +39 +133 +226 +197 +97 +10 +0 +0 +0 +51 +255 +4 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +140 +115 +12 +235 +8 +0 +0 +32 +73 +55 +255 +11 +143 +215 +0 +0 +0 +0 +31 +255 +47 +97 +0 +1 +211 +174 +16 +6 +148 +252 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +1 +233 +65 +0 +0 +0 +0 +0 +0 +116 +187 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +44 +220 +3 +0 +0 +0 +0 +9 +234 +58 +0 +0 +0 +0 +0 +155 +186 +12 +28 +220 +103 +0 +0 +0 +8 +58 +255 +11 +8 +0 +0 +105 +232 +47 +0 +0 +0 +0 +0 +101 +32 +0 +25 +193 +173 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +70 +25 +0 +25 +193 +166 +0 +0 +165 +147 +7 +13 +176 +176 +0 +0 +0 +36 +254 +49 +0 +0 +0 +15 +245 +120 +4 +12 +157 +210 +0 +0 +37 +12 +0 +68 +239 +74 +0 +0 +0 +44 +220 +3 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +8 +92 +192 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +235 +142 +41 +0 +0 +0 +0 +0 +0 +4 +24 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +49 +244 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +222 +33 +87 +169 +0 +0 +0 +23 +186 +245 +255 +243 +186 +39 +0 +0 +0 +0 +0 +122 +239 +229 +0 +0 +30 +181 +245 +231 +147 +178 +0 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +155 +133 +0 +0 +0 +0 +0 +0 +185 +111 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +62 +241 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +108 +195 +0 +0 +0 +0 +0 +0 +13 +165 +241 +235 +134 +1 +0 +0 +0 +255 +255 +255 +255 +255 +0 +0 +255 +250 +244 +244 +244 +244 +0 +0 +143 +226 +244 +238 +163 +17 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +134 +236 +245 +236 +155 +13 +0 +0 +16 +167 +238 +242 +175 +22 +0 +0 +0 +139 +203 +0 +0 +0 +0 +0 +68 +203 +246 +243 +185 +39 +0 +0 +104 +235 +244 +212 +88 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +62 +241 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +6 +0 +0 +0 +0 +0 +0 +0 +0 +49 +244 +3 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +45 +225 +4 +0 +0 +0 +0 +29 +237 +16 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +120 +157 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +4 +223 +75 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +120 +157 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +158 +104 +0 +0 +0 +0 +153 +115 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +181 +63 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +31 +119 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +181 +63 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +28 +160 +229 +236 +163 +14 +0 +0 +0 +20 +252 +200 +0 +0 +0 +52 +255 +244 +243 +238 +177 +32 +0 +0 +0 +96 +213 +244 +234 +137 +0 +52 +255 +244 +239 +190 +68 +0 +0 +52 +255 +244 +244 +244 +244 +68 +0 +0 +52 +255 +244 +244 +244 +244 +0 +0 +0 +104 +217 +244 +222 +100 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +244 +246 +255 +244 +244 +0 +0 +0 +0 +137 +244 +246 +255 +4 +0 +52 +255 +4 +0 +0 +137 +216 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +163 +0 +0 +212 +255 +0 +52 +255 +166 +0 +0 +52 +255 +0 +0 +15 +168 +241 +236 +141 +2 +0 +52 +255 +244 +244 +239 +176 +33 +0 +0 +15 +168 +241 +236 +141 +2 +0 +52 +255 +244 +244 +236 +171 +30 +0 +0 +47 +189 +243 +241 +204 +73 +0 +0 +244 +244 +246 +255 +244 +244 +0 +52 +255 +4 +0 +0 +52 +255 +0 +125 +203 +0 +0 +0 +24 +254 +0 +236 +75 +0 +0 +0 +0 +152 +0 +44 +247 +51 +0 +0 +71 +241 +0 +220 +112 +0 +0 +0 +161 +179 +0 +0 +244 +244 +244 +244 +249 +254 +0 +0 +0 +52 +255 +244 +125 +0 +0 +35 +244 +23 +0 +0 +0 +0 +0 +0 +0 +171 +246 +255 +4 +0 +0 +0 +0 +41 +242 +200 +7 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +24 +227 +130 +13 +21 +206 +163 +0 +0 +0 +98 +207 +251 +26 +0 +0 +52 +255 +4 +0 +8 +147 +204 +0 +0 +100 +224 +51 +0 +22 +89 +0 +52 +255 +4 +7 +81 +238 +66 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +106 +221 +46 +0 +29 +89 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +133 +218 +26 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +202 +4 +36 +219 +255 +0 +52 +255 +242 +30 +0 +52 +255 +0 +0 +160 +175 +10 +24 +213 +112 +0 +52 +255 +4 +0 +20 +166 +204 +0 +0 +160 +175 +10 +24 +213 +112 +0 +52 +255 +4 +0 +17 +166 +201 +0 +8 +232 +119 +7 +3 +56 +63 +0 +0 +0 +0 +52 +255 +4 +0 +0 +52 +255 +4 +0 +0 +52 +255 +0 +48 +253 +19 +0 +0 +94 +226 +0 +197 +107 +0 +0 +0 +0 +184 +0 +0 +131 +201 +2 +8 +220 +101 +0 +74 +238 +18 +0 +52 +245 +33 +0 +0 +0 +0 +0 +1 +192 +148 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +168 +135 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +16 +218 +106 +178 +159 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +157 +170 +0 +0 +0 +88 +243 +0 +0 +0 +179 +121 +200 +105 +0 +0 +52 +255 +4 +0 +0 +63 +251 +0 +0 +227 +86 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +125 +186 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +1 +229 +84 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +130 +220 +27 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +141 +66 +115 +140 +255 +0 +52 +255 +150 +143 +0 +52 +255 +0 +6 +246 +54 +0 +0 +105 +204 +0 +52 +255 +4 +0 +0 +60 +253 +0 +6 +246 +54 +0 +0 +105 +204 +0 +52 +255 +4 +0 +0 +59 +252 +0 +46 +255 +15 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +225 +87 +0 +0 +165 +150 +0 +157 +139 +0 +234 +154 +0 +215 +0 +0 +7 +216 +102 +132 +187 +0 +0 +0 +176 +146 +0 +194 +127 +0 +0 +0 +0 +0 +0 +101 +223 +12 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +48 +239 +14 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +3 +184 +122 +0 +8 +193 +112 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +243 +67 +72 +217 +233 +162 +255 +0 +3 +12 +248 +51 +130 +186 +0 +0 +52 +255 +4 +0 +12 +158 +197 +0 +31 +255 +22 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +69 +240 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +32 +255 +22 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +130 +244 +29 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +61 +146 +188 +66 +255 +0 +52 +255 +37 +239 +16 +52 +255 +0 +38 +255 +15 +0 +0 +64 +244 +0 +52 +255 +4 +0 +24 +169 +202 +0 +38 +255 +15 +0 +0 +64 +244 +0 +52 +255 +4 +0 +16 +159 +188 +0 +11 +235 +176 +72 +17 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +148 +157 +0 +1 +234 +73 +0 +118 +170 +31 +225 +207 +0 +246 +0 +0 +0 +62 +237 +237 +32 +0 +0 +0 +31 +241 +124 +221 +8 +0 +0 +0 +0 +0 +25 +238 +68 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +184 +118 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +44 +101 +0 +0 +0 +14 +121 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +255 +32 +242 +102 +5 +147 +255 +0 +4 +86 +235 +1 +59 +250 +16 +0 +52 +255 +240 +241 +254 +223 +32 +0 +48 +255 +6 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +55 +255 +0 +52 +255 +240 +240 +240 +240 +22 +0 +0 +52 +255 +240 +240 +240 +202 +0 +48 +255 +6 +0 +138 +241 +248 +0 +52 +255 +240 +240 +240 +243 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +220 +235 +100 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +6 +209 +182 +52 +255 +0 +52 +255 +4 +169 +120 +52 +255 +0 +49 +255 +5 +0 +0 +54 +255 +0 +52 +255 +240 +240 +231 +169 +31 +0 +49 +255 +5 +0 +0 +54 +255 +0 +52 +255 +240 +244 +255 +173 +11 +0 +0 +38 +160 +229 +253 +188 +37 +0 +0 +0 +0 +52 +255 +4 +0 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +70 +227 +0 +51 +244 +7 +0 +78 +202 +83 +147 +220 +32 +251 +0 +0 +0 +14 +235 +202 +0 +0 +0 +0 +0 +124 +255 +75 +0 +0 +0 +0 +0 +0 +173 +156 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +64 +230 +7 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +255 +54 +255 +13 +0 +62 +255 +0 +4 +167 +167 +0 +4 +240 +92 +0 +52 +255 +4 +0 +18 +164 +181 +0 +31 +255 +22 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +69 +240 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +32 +255 +20 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +3 +0 +52 +255 +33 +86 +243 +35 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +4 +127 +89 +52 +255 +0 +52 +255 +4 +52 +230 +58 +255 +0 +38 +255 +15 +0 +0 +64 +244 +0 +52 +255 +4 +0 +0 +0 +0 +0 +38 +255 +15 +0 +0 +64 +247 +0 +52 +255 +4 +1 +87 +251 +67 +0 +0 +0 +0 +0 +32 +176 +207 +0 +0 +0 +0 +52 +255 +4 +0 +0 +51 +255 +4 +0 +0 +52 +255 +0 +0 +6 +242 +42 +121 +174 +0 +0 +39 +234 +136 +91 +168 +112 +218 +0 +0 +0 +153 +180 +211 +98 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +80 +228 +15 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +200 +101 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +255 +37 +243 +102 +5 +147 +255 +0 +11 +241 +250 +248 +248 +253 +173 +0 +52 +255 +4 +0 +0 +58 +249 +0 +0 +228 +84 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +126 +186 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +1 +230 +78 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +61 +250 +0 +0 +52 +255 +4 +0 +170 +199 +3 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +192 +149 +255 +0 +6 +247 +54 +0 +0 +104 +204 +0 +52 +255 +4 +0 +0 +0 +0 +0 +6 +247 +54 +0 +0 +104 +209 +0 +52 +255 +4 +0 +0 +151 +207 +0 +0 +0 +0 +0 +0 +61 +253 +0 +0 +0 +0 +52 +255 +4 +0 +0 +40 +255 +8 +0 +0 +56 +248 +0 +0 +0 +171 +112 +192 +97 +0 +0 +4 +250 +199 +35 +111 +196 +178 +0 +0 +66 +241 +28 +64 +236 +21 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +14 +228 +75 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +80 +218 +2 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +238 +80 +75 +219 +234 +164 +248 +0 +77 +249 +16 +0 +0 +87 +245 +0 +52 +255 +4 +0 +9 +145 +216 +0 +0 +102 +222 +50 +0 +22 +89 +0 +52 +255 +4 +7 +82 +239 +67 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +109 +215 +40 +0 +81 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +43 +112 +13 +3 +145 +201 +0 +0 +52 +255 +4 +0 +20 +233 +126 +0 +0 +52 +255 +11 +8 +8 +8 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +75 +246 +255 +0 +0 +163 +173 +9 +23 +212 +114 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +162 +173 +9 +23 +212 +123 +0 +52 +255 +4 +0 +0 +25 +246 +0 +14 +123 +29 +0 +18 +163 +202 +0 +0 +0 +0 +52 +255 +4 +0 +0 +5 +232 +107 +3 +9 +151 +190 +0 +0 +0 +93 +195 +248 +21 +0 +0 +0 +216 +233 +0 +54 +254 +139 +0 +10 +221 +108 +0 +0 +168 +163 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +151 +163 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +1 +214 +84 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +146 +193 +1 +0 +0 +0 +0 +0 +155 +179 +0 +0 +0 +11 +245 +0 +52 +255 +244 +243 +239 +184 +44 +0 +0 +0 +99 +214 +244 +237 +140 +0 +52 +255 +244 +240 +191 +69 +0 +0 +52 +255 +244 +244 +244 +244 +99 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +109 +219 +243 +223 +116 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +244 +246 +255 +244 +244 +0 +0 +27 +186 +240 +244 +204 +50 +0 +0 +52 +255 +4 +0 +0 +82 +251 +0 +0 +52 +255 +255 +255 +255 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +1 +213 +255 +0 +0 +16 +171 +241 +237 +143 +3 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +16 +170 +241 +254 +187 +6 +0 +52 +255 +4 +0 +0 +0 +138 +0 +9 +171 +229 +246 +240 +177 +33 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +51 +197 +244 +241 +177 +28 +0 +0 +0 +18 +252 +198 +0 +0 +0 +0 +176 +179 +0 +5 +247 +99 +0 +144 +199 +2 +0 +0 +27 +243 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +254 +247 +244 +244 +244 +244 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +96 +203 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +16 +216 +165 +31 +2 +24 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +87 +237 +57 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +5 +226 +68 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +19 +144 +222 +242 +159 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +58 +12 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +50 +248 +240 +123 +0 +0 +0 +0 +0 +0 +0 +71 +79 +0 +0 +0 +168 +241 +248 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +244 +244 +244 +244 +244 +244 +99 +0 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +9 +124 +20 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +140 +0 +127 +0 +0 +112 +174 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +4 +221 +0 +127 +0 +0 +0 +159 +98 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +2 +166 +243 +244 +102 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +49 +244 +3 +0 +0 +0 +0 +0 +49 +244 +3 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +11 +244 +246 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +158 +239 +209 +0 +0 +0 +0 +52 +255 +4 +0 +0 +11 +244 +233 +119 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +68 +162 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +46 +255 +24 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +37 +255 +46 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +96 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +149 +81 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +103 +213 +244 +239 +180 +36 +0 +52 +255 +122 +232 +241 +159 +9 +0 +0 +12 +151 +233 +244 +202 +40 +0 +0 +26 +183 +244 +223 +133 +255 +0 +0 +13 +156 +236 +241 +165 +12 +0 +19 +244 +246 +255 +244 +244 +102 +0 +0 +25 +182 +244 +221 +127 +255 +0 +52 +255 +111 +233 +235 +80 +0 +0 +0 +0 +244 +246 +255 +4 +0 +0 +0 +45 +244 +246 +255 +4 +0 +0 +0 +52 +255 +4 +0 +122 +210 +0 +0 +0 +52 +255 +4 +0 +0 +0 +255 +173 +246 +137 +195 +245 +114 +0 +52 +255 +111 +233 +235 +80 +0 +0 +0 +29 +182 +242 +237 +157 +11 +0 +52 +255 +121 +231 +241 +161 +10 +0 +0 +26 +183 +244 +222 +130 +255 +0 +0 +52 +255 +78 +217 +244 +175 +0 +0 +0 +109 +226 +245 +229 +114 +0 +19 +244 +246 +255 +244 +244 +152 +0 +52 +255 +4 +0 +52 +255 +4 +0 +51 +242 +9 +0 +0 +73 +228 +0 +226 +63 +0 +0 +0 +0 +140 +0 +13 +219 +93 +0 +0 +173 +156 +0 +40 +250 +19 +0 +0 +50 +245 +0 +0 +209 +244 +244 +246 +255 +0 +0 +0 +0 +0 +51 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +5 +8 +0 +1 +219 +10 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +93 +52 +2 +9 +162 +204 +0 +52 +255 +163 +9 +19 +198 +144 +0 +0 +174 +188 +24 +0 +53 +43 +0 +0 +193 +157 +7 +20 +200 +255 +0 +0 +173 +186 +16 +11 +179 +152 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +189 +167 +10 +19 +199 +255 +0 +52 +255 +121 +2 +133 +219 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +133 +204 +19 +0 +0 +0 +52 +255 +4 +0 +0 +0 +255 +51 +99 +255 +55 +96 +227 +0 +52 +255 +121 +2 +133 +219 +0 +0 +0 +198 +158 +8 +19 +198 +149 +0 +52 +255 +163 +9 +19 +198 +145 +0 +0 +192 +158 +8 +20 +198 +255 +0 +0 +52 +255 +169 +20 +2 +52 +0 +0 +31 +255 +62 +0 +20 +57 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +216 +84 +0 +0 +162 +139 +0 +166 +118 +0 +0 +0 +0 +195 +0 +0 +49 +235 +36 +104 +211 +9 +0 +0 +200 +106 +0 +0 +142 +163 +0 +0 +0 +0 +0 +149 +171 +0 +0 +0 +0 +0 +54 +255 +2 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +50 +255 +5 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +95 +232 +100 +0 +55 +175 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +61 +252 +0 +52 +255 +33 +0 +0 +81 +233 +0 +22 +255 +41 +0 +0 +0 +0 +0 +25 +255 +32 +0 +0 +82 +255 +0 +21 +255 +49 +0 +0 +70 +236 +0 +0 +0 +52 +255 +4 +0 +0 +0 +24 +255 +35 +0 +0 +82 +255 +0 +52 +255 +18 +0 +56 +254 +1 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +146 +227 +15 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +255 +8 +56 +255 +8 +56 +253 +0 +52 +255 +18 +0 +56 +254 +1 +0 +27 +255 +32 +0 +0 +81 +234 +0 +52 +255 +33 +0 +0 +81 +232 +0 +25 +255 +32 +0 +0 +81 +255 +0 +0 +52 +255 +41 +0 +0 +0 +0 +0 +26 +252 +96 +11 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +125 +173 +0 +8 +242 +48 +0 +106 +173 +0 +192 +118 +4 +246 +0 +0 +0 +106 +212 +234 +40 +0 +0 +0 +103 +199 +0 +3 +230 +67 +0 +0 +0 +0 +90 +216 +13 +0 +0 +0 +0 +1 +121 +226 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +22 +252 +74 +0 +0 +0 +0 +115 +225 +233 +149 +42 +25 +0 +15 +54 +177 +0 +136 +94 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +78 +197 +237 +240 +243 +255 +0 +52 +255 +6 +0 +0 +55 +254 +0 +47 +255 +7 +0 +0 +0 +0 +0 +48 +255 +6 +0 +0 +55 +255 +0 +47 +255 +240 +240 +240 +241 +247 +0 +0 +0 +52 +255 +4 +0 +0 +0 +48 +255 +7 +0 +0 +55 +255 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +187 +238 +80 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +255 +4 +52 +255 +4 +52 +255 +0 +55 +255 +4 +0 +52 +255 +4 +0 +48 +255 +6 +0 +0 +55 +254 +0 +52 +255 +6 +0 +0 +55 +254 +0 +48 +255 +6 +0 +0 +55 +255 +0 +0 +52 +255 +6 +0 +0 +0 +0 +0 +0 +84 +186 +239 +208 +75 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +35 +246 +13 +84 +213 +0 +0 +46 +228 +16 +202 +187 +49 +226 +0 +0 +0 +13 +239 +176 +0 +0 +0 +0 +15 +246 +36 +70 +225 +1 +0 +0 +0 +43 +233 +43 +0 +0 +0 +0 +33 +247 +247 +73 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +112 +254 +237 +0 +0 +0 +139 +14 +17 +117 +219 +229 +0 +0 +1 +219 +8 +211 +18 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +24 +251 +86 +5 +0 +65 +255 +0 +52 +255 +32 +0 +0 +80 +232 +0 +22 +255 +41 +0 +0 +0 +0 +0 +25 +255 +32 +0 +0 +81 +255 +0 +22 +255 +21 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +25 +255 +34 +0 +0 +81 +255 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +8 +84 +237 +29 +0 +0 +0 +51 +255 +5 +0 +0 +0 +255 +4 +52 +255 +4 +52 +255 +0 +56 +255 +4 +0 +52 +255 +4 +0 +27 +255 +32 +0 +0 +81 +234 +0 +52 +255 +32 +0 +0 +80 +233 +0 +26 +255 +32 +0 +0 +81 +255 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +4 +126 +237 +0 +0 +0 +51 +255 +4 +0 +0 +0 +48 +255 +8 +0 +66 +255 +4 +0 +0 +0 +199 +94 +173 +122 +0 +0 +2 +239 +110 +116 +189 +116 +166 +0 +0 +0 +166 +166 +222 +90 +0 +0 +0 +0 +166 +128 +162 +131 +0 +0 +0 +13 +216 +90 +0 +0 +0 +0 +0 +0 +3 +137 +210 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +14 +244 +89 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +154 +117 +188 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +33 +255 +68 +0 +26 +189 +255 +0 +52 +255 +160 +8 +17 +195 +143 +0 +0 +177 +185 +23 +0 +50 +42 +0 +0 +194 +158 +7 +19 +198 +255 +0 +0 +176 +162 +17 +0 +32 +76 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +191 +164 +10 +17 +195 +255 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +156 +194 +0 +0 +0 +24 +254 +67 +0 +0 +0 +255 +4 +52 +255 +4 +52 +255 +0 +56 +255 +4 +0 +52 +255 +4 +0 +0 +200 +158 +7 +19 +198 +151 +0 +52 +255 +160 +8 +17 +195 +146 +0 +0 +194 +158 +7 +19 +198 +255 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +31 +72 +8 +2 +124 +230 +0 +0 +0 +30 +255 +51 +0 +0 +0 +15 +251 +62 +0 +147 +255 +4 +0 +0 +0 +108 +195 +246 +32 +0 +0 +0 +182 +228 +42 +120 +228 +106 +0 +0 +103 +217 +11 +55 +238 +39 +0 +0 +0 +70 +222 +242 +36 +0 +0 +0 +172 +148 +0 +0 +0 +0 +0 +0 +0 +0 +57 +254 +1 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +49 +255 +8 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +78 +244 +107 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +114 +231 +243 +204 +108 +255 +0 +52 +255 +120 +232 +240 +159 +9 +0 +0 +14 +153 +234 +244 +206 +41 +0 +0 +28 +184 +244 +223 +132 +255 +0 +0 +14 +155 +234 +244 +218 +111 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +27 +184 +245 +221 +123 +255 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +118 +244 +246 +255 +244 +244 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +11 +217 +0 +0 +0 +0 +121 +240 +244 +114 +0 +255 +4 +52 +255 +4 +52 +255 +0 +56 +255 +4 +0 +52 +255 +4 +0 +0 +31 +184 +243 +238 +160 +12 +0 +52 +255 +120 +232 +241 +160 +10 +0 +0 +28 +185 +244 +223 +130 +255 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +35 +199 +242 +246 +204 +61 +0 +0 +0 +0 +141 +236 +229 +142 +0 +0 +120 +234 +191 +137 +255 +4 +0 +0 +0 +21 +251 +197 +0 +0 +0 +0 +122 +224 +0 +45 +255 +46 +0 +48 +241 +50 +0 +0 +118 +210 +0 +0 +0 +2 +227 +198 +0 +0 +0 +0 +255 +246 +244 +244 +244 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +10 +245 +27 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +72 +240 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +56 +254 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +199 +105 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +50 +255 +5 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +53 +255 +2 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +6 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +53 +55 +2 +15 +182 +162 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +121 +215 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +64 +244 +16 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +25 +255 +56 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +106 +232 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +75 +220 +246 +237 +162 +16 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +194 +246 +227 +68 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +203 +237 +92 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +133 +229 +206 +0 +0 +0 +0 +52 +255 +4 +0 +0 +11 +240 +221 +96 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +2 +187 +58 +108 +143 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +102 +10 +58 +54 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +97 +59 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +33 +222 +208 +8 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +60 +194 +183 +6 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +48 +240 +52 +240 +3 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +58 +199 +211 +11 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +184 +184 +143 +119 +77 +39 +156 +0 +0 +0 +73 +164 +22 +196 +26 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +42 +179 +3 +188 +30 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +4 +134 +230 +245 +210 +44 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +57 +219 +243 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +4 +195 +31 +94 +137 +0 +0 +109 +231 +221 +73 +0 +0 +0 +0 +0 +47 +189 +243 +241 +204 +73 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +26 +175 +241 +247 +255 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +244 +244 +244 +244 +249 +254 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +111 +129 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +111 +178 +0 +111 +129 +0 +0 +52 +255 +4 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +156 +224 +40 +191 +0 +0 +0 +196 +0 +196 +159 +147 +211 +0 +0 +0 +0 +125 +231 +62 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +143 +189 +126 +0 +0 +0 +171 +161 +0 +0 +1 +208 +134 +0 +127 +0 +137 +197 +27 +0 +51 +39 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +218 +103 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +254 +51 +101 +235 +0 +0 +0 +0 +8 +233 +119 +7 +3 +56 +63 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +181 +177 +20 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +1 +192 +148 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +206 +69 +0 +0 +0 +0 +0 +0 +62 +241 +1 +0 +0 +0 +0 +206 +94 +0 +206 +69 +0 +0 +62 +241 +1 +66 +241 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +174 +39 +188 +126 +0 +0 +0 +196 +0 +196 +55 +118 +196 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +15 +125 +8 +0 +0 +0 +29 +241 +39 +0 +85 +240 +17 +0 +127 +8 +244 +57 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +31 +249 +5 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +118 +244 +246 +255 +244 +244 +72 +0 +118 +244 +246 +255 +244 +244 +72 +0 +0 +0 +0 +0 +0 +0 +0 +0 +254 +50 +100 +234 +1 +57 +97 +0 +46 +255 +15 +0 +0 +0 +0 +0 +0 +0 +0 +0 +31 +0 +0 +0 +10 +252 +51 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +101 +223 +12 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +35 +255 +14 +0 +0 +0 +0 +0 +0 +118 +157 +0 +0 +0 +0 +35 +255 +18 +35 +255 +14 +0 +0 +120 +157 +0 +143 +157 +0 +0 +0 +0 +84 +234 +231 +76 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +196 +0 +196 +0 +0 +196 +0 +0 +0 +109 +226 +245 +229 +114 +0 +0 +0 +0 +30 +0 +0 +0 +0 +0 +103 +239 +220 +122 +231 +236 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +209 +244 +244 +246 +255 +0 +0 +0 +120 +167 +2 +213 +127 +0 +0 +127 +240 +255 +241 +240 +236 +18 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +74 +210 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +111 +234 +255 +210 +148 +92 +14 +0 +10 +232 +176 +72 +17 +0 +0 +0 +0 +0 +0 +55 +219 +0 +0 +0 +40 +255 +14 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +25 +238 +68 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +178 +63 +0 +0 +0 +0 +52 +255 +4 +52 +255 +4 +0 +0 +181 +63 +0 +225 +63 +0 +0 +0 +0 +234 +255 +255 +232 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +31 +255 +62 +0 +20 +57 +0 +0 +0 +0 +218 +54 +0 +0 +0 +5 +243 +62 +113 +255 +57 +106 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +149 +171 +0 +0 +0 +6 +214 +135 +237 +14 +0 +0 +127 +51 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +22 +240 +247 +250 +240 +150 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +129 +149 +89 +13 +0 +0 +0 +0 +0 +33 +152 +222 +253 +188 +37 +0 +0 +0 +85 +217 +46 +0 +0 +0 +49 +255 +6 +0 +52 +255 +240 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +173 +156 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +234 +255 +255 +232 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +26 +252 +96 +11 +0 +0 +0 +0 +0 +0 +46 +217 +85 +0 +0 +39 +255 +11 +62 +255 +6 +54 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +90 +216 +13 +0 +0 +0 +0 +68 +255 +121 +0 +0 +0 +127 +240 +255 +240 +240 +50 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +156 +126 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +113 +231 +221 +73 +73 +223 +225 +0 +0 +0 +0 +0 +27 +170 +207 +0 +0 +0 +229 +102 +0 +0 +0 +0 +40 +255 +14 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +80 +228 +15 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +84 +235 +233 +79 +0 +0 +244 +244 +244 +244 +244 +244 +244 +0 +244 +244 +244 +244 +244 +244 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +84 +186 +239 +208 +75 +0 +0 +0 +0 +0 +103 +229 +0 +0 +50 +255 +5 +53 +255 +240 +241 +0 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +43 +233 +43 +0 +0 +0 +0 +0 +0 +252 +60 +0 +0 +0 +127 +9 +247 +62 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +200 +85 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +116 +240 +243 +255 +240 +240 +71 +0 +0 +0 +0 +0 +0 +0 +0 +0 +254 +51 +102 +235 +229 +51 +101 +0 +0 +0 +0 +0 +0 +61 +253 +0 +0 +0 +29 +206 +115 +0 +0 +0 +10 +252 +51 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +14 +228 +75 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +4 +126 +237 +0 +0 +0 +0 +116 +206 +29 +0 +0 +39 +255 +11 +60 +255 +8 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +13 +216 +90 +0 +0 +0 +0 +0 +0 +0 +252 +60 +0 +0 +0 +127 +0 +146 +201 +26 +0 +50 +39 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +1 +243 +45 +0 +0 +0 +0 +52 +255 +4 +52 +255 +4 +0 +44 +220 +3 +44 +220 +3 +44 +0 +3 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +254 +47 +99 +235 +230 +47 +97 +0 +15 +135 +41 +5 +30 +171 +202 +0 +0 +0 +0 +12 +180 +0 +0 +0 +0 +181 +177 +19 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +151 +163 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +31 +72 +8 +2 +124 +230 +0 +0 +0 +0 +179 +12 +0 +0 +0 +6 +244 +62 +114 +255 +80 +0 +0 +1 +0 +0 +0 +0 +0 +0 +0 +0 +172 +148 +0 +0 +0 +0 +0 +0 +0 +0 +252 +60 +0 +0 +0 +127 +0 +6 +140 +231 +245 +213 +44 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +62 +241 +1 +0 +0 +0 +0 +0 +33 +253 +7 +0 +0 +0 +0 +62 +241 +1 +66 +241 +1 +0 +52 +255 +4 +52 +255 +4 +52 +0 +4 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +116 +239 +229 +79 +79 +231 +233 +0 +9 +166 +229 +252 +240 +177 +33 +0 +0 +0 +0 +0 +3 +0 +0 +0 +0 +26 +177 +242 +247 +255 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +254 +247 +244 +244 +244 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +35 +199 +242 +246 +204 +61 +0 +0 +0 +0 +2 +0 +0 +0 +0 +0 +105 +240 +221 +111 +222 +244 +0 +1 +0 +0 +0 +0 +0 +0 +0 +0 +255 +246 +244 +244 +244 +0 +0 +0 +0 +0 +252 +60 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +120 +157 +0 +0 +0 +0 +0 +0 +85 +212 +0 +0 +0 +0 +0 +120 +157 +0 +143 +157 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +181 +63 +0 +0 +0 +0 +30 +11 +195 +131 +0 +0 +0 +0 +0 +181 +63 +0 +225 +63 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +227 +245 +177 +12 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +58 +98 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +2 +8 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +20 +221 +50 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +103 +185 +255 +4 +0 +0 +0 +0 +106 +186 +255 +4 +0 +0 +0 +0 +0 +144 +235 +229 +126 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +49 +244 +3 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +86 +224 +245 +206 +0 +0 +0 +0 +0 +0 +0 +0 +0 +215 +116 +0 +0 +0 +164 +172 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +110 +227 +245 +223 +102 +0 +0 +0 +49 +244 +53 +244 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +122 +237 +237 +102 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +3 +244 +244 +244 +175 +0 +0 +0 +0 +116 +239 +227 +77 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +116 +235 +233 +108 +0 +0 +0 +0 +165 +239 +235 +132 +0 +0 +0 +0 +0 +173 +88 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +40 +184 +245 +255 +246 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +101 +185 +255 +4 +0 +0 +0 +0 +77 +219 +247 +201 +45 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +17 +0 +101 +238 +0 +0 +0 +0 +0 +49 +244 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +11 +245 +105 +1 +43 +0 +0 +0 +0 +0 +0 +0 +0 +0 +62 +241 +25 +0 +61 +236 +23 +0 +0 +0 +0 +52 +255 +4 +0 +0 +33 +255 +60 +0 +26 +51 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +53 +181 +236 +230 +161 +31 +0 +0 +0 +33 +1 +102 +238 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +53 +181 +236 +230 +161 +31 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +30 +254 +51 +99 +236 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +42 +3 +96 +248 +0 +0 +0 +0 +15 +2 +107 +236 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +5 +226 +255 +255 +255 +56 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +14 +244 +93 +2 +142 +209 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +222 +242 +72 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +14 +161 +243 +255 +236 +0 +0 +0 +47 +255 +11 +0 +0 +0 +0 +82 +25 +0 +0 +44 +64 +0 +0 +155 +165 +3 +210 +93 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +15 +230 +104 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +67 +255 +255 +253 +224 +140 +233 +0 +0 +3 +160 +237 +243 +255 +3 +0 +0 +0 +0 +31 +0 +0 +31 +0 +0 +0 +0 +0 +0 +0 +0 +0 +67 +255 +255 +251 +251 +255 +233 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +30 +254 +50 +100 +234 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +113 +173 +0 +0 +0 +0 +0 +244 +239 +67 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +45 +255 +255 +255 +255 +56 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +47 +255 +12 +0 +61 +253 +0 +0 +30 +0 +0 +30 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +108 +224 +0 +0 +0 +0 +0 +44 +255 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +174 +182 +65 +255 +13 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +79 +222 +204 +189 +221 +47 +0 +123 +185 +244 +166 +235 +176 +90 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +100 +237 +188 +46 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +222 +255 +110 +2 +21 +6 +156 +0 +0 +42 +255 +40 +100 +255 +4 +0 +0 +0 +55 +219 +0 +55 +218 +0 +0 +0 +0 +0 +0 +0 +0 +0 +222 +161 +255 +4 +86 +247 +157 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +114 +233 +220 +71 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +65 +191 +12 +0 +0 +0 +0 +0 +0 +107 +224 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +19 +250 +255 +255 +255 +56 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +12 +243 +94 +4 +144 +206 +0 +0 +218 +54 +0 +219 +54 +0 +0 +81 +176 +212 +160 +0 +28 +70 +0 +81 +176 +212 +168 +31 +8 +78 +0 +0 +35 +1 +114 +240 +0 +0 +0 +0 +0 +63 +242 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +22 +255 +48 +52 +255 +4 +0 +0 +172 +243 +255 +240 +240 +37 +0 +0 +17 +230 +49 +97 +201 +0 +0 +0 +0 +101 +255 +50 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +21 +249 +20 +108 +240 +103 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +255 +255 +14 +0 +0 +0 +67 +0 +0 +5 +182 +234 +147 +248 +3 +0 +0 +85 +219 +47 +85 +212 +43 +0 +186 +244 +244 +244 +244 +245 +252 +0 +255 +71 +255 +244 +232 +84 +67 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +240 +240 +243 +255 +240 +240 +0 +0 +0 +56 +182 +13 +0 +0 +0 +0 +0 +42 +1 +116 +239 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +105 +248 +255 +255 +56 +255 +0 +0 +0 +44 +220 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +81 +176 +212 +168 +49 +0 +0 +0 +72 +213 +242 +195 +40 +0 +0 +44 +213 +85 +48 +220 +85 +0 +0 +2 +56 +132 +204 +195 +104 +0 +0 +0 +12 +86 +169 +231 +170 +0 +0 +180 +240 +219 +87 +42 +91 +0 +0 +15 +210 +132 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +48 +255 +11 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +16 +229 +53 +101 +198 +0 +0 +168 +240 +243 +255 +240 +240 +123 +0 +0 +0 +0 +0 +0 +0 +0 +0 +30 +254 +67 +0 +93 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +255 +222 +111 +4 +17 +5 +67 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +229 +109 +0 +229 +89 +0 +0 +0 +0 +0 +0 +0 +52 +255 +0 +255 +71 +255 +9 +178 +76 +67 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +173 +242 +240 +240 +11 +0 +0 +0 +200 +241 +217 +82 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +0 +18 +107 +255 +56 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +89 +229 +0 +109 +229 +0 +150 +216 +167 +92 +18 +0 +0 +0 +92 +177 +230 +162 +79 +8 +0 +0 +21 +98 +143 +151 +148 +110 +60 +0 +0 +186 +168 +2 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +21 +255 +43 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +76 +223 +204 +189 +222 +49 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +117 +241 +119 +83 +210 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +224 +153 +197 +240 +202 +13 +157 +0 +0 +3 +240 +240 +240 +240 +11 +0 +0 +29 +207 +117 +29 +205 +112 +0 +0 +0 +0 +0 +0 +50 +248 +0 +224 +156 +228 +3 +22 +188 +166 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +11 +0 +62 +255 +4 +0 +0 +0 +0 +52 +255 +56 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +228 +240 +240 +240 +172 +0 +0 +113 +205 +29 +118 +207 +29 +0 +49 +4 +0 +0 +146 +255 +4 +0 +130 +71 +5 +87 +225 +232 +129 +0 +21 +53 +7 +0 +2 +174 +255 +0 +40 +255 +20 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +175 +172 +59 +255 +8 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +85 +25 +0 +0 +46 +62 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +43 +182 +246 +51 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +68 +240 +97 +7 +14 +129 +232 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +12 +180 +0 +12 +180 +0 +0 +0 +0 +0 +0 +0 +0 +0 +68 +240 +97 +7 +14 +129 +232 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +99 +3 +157 +255 +18 +0 +0 +0 +0 +52 +255 +56 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +179 +12 +0 +179 +12 +0 +0 +0 +0 +0 +44 +141 +255 +4 +0 +0 +0 +0 +28 +5 +88 +239 +0 +0 +0 +0 +0 +126 +102 +255 +0 +23 +252 +95 +8 +66 +99 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +13 +156 +235 +255 +231 +0 +0 +244 +246 +255 +244 +244 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +127 +213 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +53 +184 +236 +232 +164 +31 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +3 +0 +0 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +53 +184 +236 +232 +164 +31 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +244 +244 +244 +244 +244 +244 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +163 +243 +148 +208 +191 +0 +0 +0 +0 +52 +255 +56 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +2 +0 +0 +2 +0 +0 +0 +0 +0 +0 +136 +53 +255 +4 +0 +0 +0 +0 +0 +9 +168 +67 +0 +0 +0 +0 +84 +94 +52 +255 +0 +0 +101 +231 +249 +202 +68 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +1 +72 +10 +3 +120 +233 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +56 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +33 +65 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +240 +243 +255 +176 +0 +0 +0 +0 +28 +162 +38 +0 +0 +0 +0 +0 +174 +240 +243 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +2 +188 +234 +241 +201 +61 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +23 +116 +25 +116 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +2 +214 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +143 +245 +244 +244 +0 +0 +0 +0 +0 +0 +52 +255 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +116 +199 +178 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +0 +0 +51 +90 +0 +0 +0 +0 +0 +0 +0 +6 +119 +17 +0 +0 +0 +0 +4 +117 +84 +0 +0 +0 +0 +2 +196 +190 +20 +191 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +145 +237 +102 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +99 +44 +0 +0 +0 +0 +0 +0 +0 +48 +95 +0 +0 +0 +0 +0 +41 +128 +38 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +97 +35 +0 +0 +0 +0 +0 +0 +0 +57 +85 +0 +0 +0 +0 +0 +46 +127 +26 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +18 +217 +181 +17 +203 +0 +0 +0 +0 +74 +213 +6 +0 +0 +0 +0 +0 +0 +27 +229 +40 +0 +0 +0 +0 +29 +222 +209 +8 +0 +0 +0 +2 +195 +200 +27 +193 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +101 +212 +8 +0 +0 +0 +0 +0 +0 +29 +234 +61 +0 +0 +0 +0 +42 +226 +218 +16 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +143 +135 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +3 +172 +83 +0 +0 +0 +0 +0 +0 +158 +105 +0 +0 +0 +0 +0 +154 +91 +157 +84 +0 +0 +0 +34 +144 +63 +189 +101 +0 +0 +0 +48 +240 +52 +240 +3 +0 +0 +0 +32 +255 +96 +239 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +39 +201 +20 +0 +0 +0 +0 +0 +25 +203 +35 +0 +0 +0 +0 +24 +188 +62 +188 +22 +0 +0 +0 +48 +240 +52 +240 +3 +0 +0 +0 +0 +42 +195 +12 +0 +0 +0 +0 +0 +29 +198 +25 +0 +0 +0 +0 +22 +184 +66 +185 +14 +0 +0 +0 +48 +240 +52 +240 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +74 +110 +77 +192 +109 +0 +0 +0 +0 +0 +139 +130 +0 +0 +0 +0 +0 +0 +177 +92 +0 +0 +0 +0 +1 +183 +63 +107 +141 +0 +0 +0 +37 +141 +60 +187 +123 +0 +0 +0 +48 +240 +3 +48 +240 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +151 +143 +0 +0 +0 +0 +0 +1 +189 +104 +0 +0 +0 +0 +8 +200 +53 +93 +169 +0 +0 +0 +48 +240 +3 +48 +240 +3 +0 +0 +0 +42 +192 +5 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +20 +246 +100 +217 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +9 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +20 +252 +200 +0 +0 +0 +0 +0 +20 +252 +200 +0 +0 +0 +0 +0 +20 +252 +200 +0 +0 +0 +0 +0 +20 +252 +200 +0 +0 +0 +0 +0 +80 +255 +32 +0 +0 +0 +0 +0 +62 +238 +30 +0 +0 +0 +0 +0 +196 +247 +255 +244 +244 +0 +0 +0 +96 +213 +244 +234 +137 +0 +52 +255 +244 +244 +244 +244 +68 +0 +52 +255 +244 +244 +244 +244 +68 +0 +52 +255 +244 +244 +244 +244 +68 +0 +52 +255 +244 +244 +244 +236 +0 +0 +0 +244 +246 +255 +244 +244 +0 +0 +0 +244 +246 +255 +244 +244 +0 +0 +0 +244 +246 +255 +244 +244 +0 +0 +0 +244 +246 +255 +244 +244 +0 +0 +52 +255 +244 +239 +190 +68 +0 +0 +52 +255 +166 +0 +0 +52 +255 +0 +0 +15 +168 +241 +236 +141 +2 +0 +0 +15 +168 +241 +236 +141 +2 +0 +0 +15 +168 +241 +236 +141 +2 +0 +0 +15 +168 +241 +236 +141 +2 +0 +0 +15 +168 +241 +236 +141 +2 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +13 +166 +240 +239 +148 +152 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +220 +112 +0 +0 +0 +161 +179 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +100 +226 +247 +212 +58 +0 +0 +127 +0 +0 +98 +207 +251 +26 +0 +0 +0 +0 +98 +207 +251 +26 +0 +0 +0 +0 +98 +207 +251 +26 +0 +0 +0 +0 +98 +207 +251 +26 +0 +0 +0 +0 +160 +212 +112 +0 +0 +0 +0 +0 +91 +210 +42 +0 +0 +0 +0 +17 +242 +58 +255 +4 +0 +0 +0 +100 +223 +50 +0 +22 +89 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +7 +81 +238 +66 +0 +52 +255 +242 +30 +0 +52 +255 +0 +0 +160 +175 +10 +24 +213 +112 +0 +0 +160 +175 +10 +24 +213 +112 +0 +0 +160 +175 +10 +24 +213 +112 +0 +0 +160 +175 +10 +24 +213 +112 +0 +0 +160 +175 +10 +24 +213 +112 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +158 +169 +7 +42 +243 +176 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +74 +238 +18 +0 +52 +245 +33 +0 +52 +255 +4 +0 +0 +0 +0 +0 +20 +251 +87 +1 +120 +216 +0 +0 +127 +0 +0 +179 +121 +200 +105 +0 +0 +0 +0 +179 +121 +200 +105 +0 +0 +0 +0 +179 +121 +200 +105 +0 +0 +0 +0 +179 +121 +200 +105 +0 +0 +0 +3 +236 +97 +192 +0 +0 +0 +0 +0 +185 +107 +136 +0 +0 +0 +0 +86 +189 +52 +255 +4 +0 +0 +0 +227 +84 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +125 +186 +0 +52 +255 +150 +143 +0 +52 +255 +0 +6 +246 +54 +0 +0 +105 +204 +0 +6 +246 +54 +0 +0 +105 +204 +0 +6 +246 +54 +0 +0 +105 +204 +0 +6 +246 +54 +0 +0 +105 +204 +0 +6 +246 +54 +0 +0 +105 +204 +0 +0 +123 +22 +0 +0 +66 +81 +0 +5 +246 +57 +0 +52 +245 +208 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +176 +146 +0 +194 +127 +0 +0 +52 +255 +240 +240 +233 +177 +38 +0 +50 +255 +8 +69 +180 +160 +0 +0 +127 +0 +12 +248 +51 +130 +186 +0 +0 +0 +12 +248 +51 +130 +186 +0 +0 +0 +12 +248 +51 +130 +186 +0 +0 +0 +12 +248 +51 +130 +186 +0 +0 +0 +64 +222 +16 +250 +19 +0 +0 +0 +25 +230 +26 +227 +2 +0 +0 +0 +159 +125 +52 +255 +4 +0 +0 +31 +255 +21 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +69 +240 +0 +52 +255 +37 +239 +16 +52 +255 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +0 +130 +214 +25 +73 +235 +64 +0 +38 +255 +20 +12 +210 +108 +246 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +31 +241 +124 +221 +8 +0 +0 +52 +255 +4 +0 +18 +164 +208 +0 +52 +255 +30 +251 +36 +0 +0 +0 +127 +0 +86 +235 +1 +59 +250 +16 +0 +0 +86 +235 +1 +59 +250 +16 +0 +0 +86 +235 +1 +59 +250 +16 +0 +0 +86 +235 +1 +59 +250 +16 +0 +0 +144 +164 +0 +213 +96 +0 +0 +0 +117 +182 +0 +230 +68 +0 +0 +1 +231 +61 +52 +255 +240 +240 +0 +48 +255 +6 +0 +0 +0 +0 +0 +52 +255 +240 +240 +240 +240 +22 +0 +52 +255 +240 +240 +240 +240 +22 +0 +52 +255 +240 +240 +240 +240 +22 +0 +52 +255 +240 +240 +240 +187 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +239 +255 +240 +198 +0 +55 +255 +0 +52 +255 +4 +169 +120 +52 +255 +0 +49 +255 +5 +0 +0 +54 +255 +0 +49 +255 +5 +0 +0 +54 +255 +0 +49 +255 +5 +0 +0 +54 +255 +0 +49 +255 +5 +0 +0 +54 +255 +0 +49 +255 +5 +0 +0 +54 +255 +0 +0 +0 +124 +225 +235 +60 +0 +0 +49 +255 +6 +160 +101 +53 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +52 +255 +4 +0 +0 +52 +255 +0 +0 +0 +124 +255 +75 +0 +0 +0 +52 +255 +4 +0 +0 +59 +253 +0 +52 +255 +26 +245 +109 +2 +0 +0 +127 +0 +167 +167 +0 +4 +240 +92 +0 +0 +167 +167 +0 +4 +240 +92 +0 +0 +167 +167 +0 +4 +240 +92 +0 +0 +167 +167 +0 +4 +240 +92 +0 +0 +223 +105 +0 +154 +176 +0 +0 +0 +210 +130 +0 +179 +162 +0 +0 +49 +246 +6 +52 +255 +4 +0 +0 +31 +255 +23 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +69 +240 +0 +52 +255 +4 +52 +230 +58 +255 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +38 +255 +15 +0 +0 +64 +244 +0 +0 +0 +80 +241 +224 +31 +0 +0 +40 +255 +92 +164 +0 +63 +245 +0 +51 +255 +4 +0 +0 +52 +255 +0 +51 +255 +4 +0 +0 +52 +255 +0 +51 +255 +4 +0 +0 +52 +255 +0 +51 +255 +4 +0 +0 +52 +255 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +17 +161 +208 +0 +52 +255 +4 +47 +187 +209 +46 +0 +127 +7 +241 +250 +248 +248 +253 +173 +0 +7 +241 +250 +248 +248 +253 +173 +0 +7 +241 +250 +248 +248 +253 +173 +0 +7 +241 +250 +248 +248 +253 +173 +0 +48 +255 +249 +248 +250 +246 +10 +0 +49 +255 +249 +248 +250 +244 +11 +0 +122 +251 +240 +243 +255 +4 +0 +0 +0 +228 +88 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +126 +186 +0 +52 +255 +4 +0 +192 +149 +255 +0 +6 +247 +54 +0 +0 +104 +204 +0 +6 +247 +54 +0 +0 +104 +204 +0 +6 +247 +54 +0 +0 +104 +204 +0 +6 +247 +54 +0 +0 +104 +204 +0 +6 +247 +54 +0 +0 +104 +204 +0 +0 +87 +233 +51 +113 +224 +34 +0 +10 +253 +203 +12 +0 +100 +203 +0 +40 +255 +9 +0 +0 +57 +248 +0 +40 +255 +9 +0 +0 +57 +248 +0 +40 +255 +9 +0 +0 +57 +248 +0 +40 +255 +8 +0 +0 +56 +248 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +240 +240 +234 +178 +38 +0 +52 +255 +4 +0 +0 +116 +220 +0 +127 +74 +249 +16 +0 +0 +87 +245 +0 +74 +249 +16 +0 +0 +87 +245 +0 +74 +249 +16 +0 +0 +87 +245 +0 +74 +249 +16 +0 +0 +87 +245 +0 +128 +211 +0 +0 +15 +248 +80 +0 +143 +187 +0 +0 +5 +234 +94 +0 +195 +109 +0 +52 +255 +4 +0 +0 +0 +102 +228 +62 +5 +34 +99 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +8 +58 +255 +11 +8 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +7 +82 +239 +67 +0 +52 +255 +4 +0 +75 +246 +255 +0 +0 +163 +173 +9 +23 +212 +114 +0 +0 +163 +173 +9 +23 +212 +114 +0 +0 +163 +173 +9 +23 +212 +114 +0 +0 +163 +173 +9 +23 +212 +114 +0 +0 +163 +173 +9 +23 +212 +114 +0 +0 +166 +49 +0 +0 +108 +107 +0 +13 +237 +190 +15 +18 +206 +111 +0 +5 +232 +117 +10 +19 +158 +190 +0 +5 +232 +117 +10 +19 +158 +190 +0 +5 +232 +117 +10 +19 +158 +190 +0 +5 +232 +107 +3 +9 +151 +190 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +34 +8 +2 +118 +240 +0 +127 +155 +179 +0 +0 +0 +11 +245 +0 +155 +179 +0 +0 +0 +11 +245 +0 +155 +179 +0 +0 +0 +11 +245 +0 +155 +179 +0 +0 +0 +11 +245 +0 +208 +126 +0 +0 +0 +176 +160 +0 +232 +94 +0 +0 +0 +144 +188 +0 +251 +31 +0 +52 +255 +244 +244 +0 +0 +0 +99 +214 +255 +240 +135 +0 +52 +255 +244 +244 +244 +244 +99 +0 +52 +255 +244 +244 +244 +244 +99 +0 +52 +255 +244 +244 +244 +244 +99 +0 +52 +255 +244 +244 +244 +244 +22 +0 +0 +244 +246 +255 +244 +244 +0 +0 +0 +244 +246 +255 +244 +244 +0 +0 +0 +255 +255 +255 +255 +255 +0 +0 +0 +244 +246 +255 +244 +244 +0 +0 +52 +255 +244 +240 +191 +69 +0 +0 +52 +255 +4 +0 +1 +213 +255 +0 +0 +16 +171 +241 +237 +143 +3 +0 +0 +16 +171 +241 +237 +143 +3 +0 +0 +16 +171 +241 +237 +143 +3 +0 +0 +16 +171 +241 +237 +143 +3 +0 +0 +16 +171 +241 +237 +143 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +157 +99 +185 +245 +234 +140 +2 +0 +0 +51 +197 +249 +244 +177 +28 +0 +0 +51 +197 +249 +244 +177 +28 +0 +0 +51 +197 +249 +244 +177 +28 +0 +0 +51 +197 +244 +241 +177 +28 +0 +0 +0 +52 +255 +4 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +116 +240 +246 +211 +74 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +107 +120 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +17 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +13 +69 +194 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +233 +241 +107 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +104 +226 +228 +110 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +8 +195 +125 +0 +0 +0 +0 +0 +0 +0 +0 +98 +212 +15 +0 +0 +0 +2 +197 +213 +8 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +241 +45 +96 +248 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +2 +157 +139 +0 +0 +0 +0 +0 +0 +0 +0 +154 +142 +0 +0 +0 +0 +10 +199 +192 +5 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +111 +190 +2 +0 +0 +0 +0 +0 +0 +0 +50 +225 +29 +0 +0 +0 +0 +130 +241 +30 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +11 +187 +114 +0 +0 +0 +0 +0 +0 +0 +1 +161 +149 +1 +0 +0 +0 +24 +211 +193 +6 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +68 +217 +9 +0 +0 +0 +0 +0 +0 +0 +44 +223 +23 +0 +0 +0 +0 +88 +244 +31 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +64 +91 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +0 +18 +213 +67 +0 +0 +0 +0 +0 +0 +46 +220 +30 +0 +0 +0 +0 +115 +148 +123 +138 +0 +0 +0 +14 +196 +237 +203 +189 +27 +0 +0 +0 +240 +3 +49 +244 +3 +0 +0 +0 +105 +226 +228 +110 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +1 +155 +105 +0 +0 +0 +0 +0 +0 +121 +140 +0 +0 +0 +0 +0 +158 +74 +90 +145 +0 +0 +0 +0 +240 +3 +49 +244 +3 +0 +0 +0 +0 +158 +122 +0 +0 +0 +0 +0 +0 +12 +210 +56 +0 +0 +0 +0 +38 +200 +77 +175 +0 +0 +0 +49 +244 +53 +244 +3 +0 +0 +0 +3 +138 +202 +114 +121 +12 +0 +0 +86 +232 +214 +194 +37 +0 +0 +0 +0 +7 +172 +97 +0 +0 +0 +0 +0 +0 +144 +133 +0 +0 +0 +0 +6 +185 +54 +92 +153 +0 +0 +0 +25 +206 +234 +199 +174 +3 +0 +0 +49 +244 +3 +49 +244 +3 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +123 +138 +0 +0 +0 +0 +0 +0 +2 +195 +59 +0 +0 +0 +0 +11 +204 +78 +171 +0 +0 +0 +0 +49 +244 +53 +244 +3 +0 +0 +0 +0 +0 +51 +205 +26 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +49 +244 +53 +244 +3 +0 +0 +127 +0 +0 +0 +32 +105 +0 +0 +0 +0 +0 +0 +91 +46 +0 +0 +0 +0 +2 +113 +7 +1 +111 +7 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +6 +117 +7 +0 +0 +0 +0 +0 +57 +72 +0 +0 +0 +0 +0 +74 +38 +0 +93 +20 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +51 +110 +93 +212 +36 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +24 +0 +0 +0 +1 +109 +6 +0 +0 +0 +0 +0 +35 +80 +0 +0 +0 +0 +0 +49 +64 +0 +96 +15 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +103 +25 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +127 +0 +103 +213 +244 +239 +180 +36 +0 +0 +103 +213 +244 +240 +180 +36 +0 +0 +103 +213 +244 +239 +180 +36 +0 +0 +103 +213 +244 +239 +180 +36 +0 +0 +103 +213 +244 +239 +180 +36 +0 +0 +103 +213 +244 +239 +180 +36 +0 +0 +132 +239 +226 +131 +234 +236 +0 +0 +12 +151 +233 +244 +202 +40 +0 +0 +13 +156 +236 +241 +165 +12 +0 +0 +13 +156 +236 +241 +165 +12 +0 +0 +13 +156 +236 +241 +165 +12 +0 +0 +13 +156 +235 +241 +165 +12 +0 +0 +0 +244 +246 +255 +4 +0 +0 +0 +0 +244 +246 +255 +4 +0 +0 +0 +0 +244 +246 +255 +4 +0 +0 +0 +148 +244 +255 +4 +0 +0 +0 +0 +25 +178 +243 +251 +214 +9 +0 +52 +255 +111 +233 +235 +80 +0 +0 +0 +29 +182 +242 +237 +157 +11 +0 +0 +29 +182 +242 +237 +157 +11 +0 +0 +29 +182 +242 +237 +157 +11 +0 +0 +29 +182 +242 +237 +157 +11 +0 +0 +29 +182 +242 +237 +157 +11 +0 +0 +0 +0 +49 +244 +3 +0 +0 +0 +29 +181 +242 +238 +160 +192 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +40 +250 +19 +0 +0 +50 +245 +0 +52 +255 +121 +231 +241 +161 +10 +0 +93 +212 +0 +0 +0 +221 +87 +0 +127 +0 +93 +52 +2 +9 +162 +204 +0 +0 +93 +52 +2 +10 +165 +204 +0 +0 +93 +52 +2 +9 +162 +204 +0 +0 +93 +52 +2 +9 +162 +204 +0 +0 +93 +52 +2 +9 +162 +204 +0 +0 +93 +52 +2 +9 +159 +204 +0 +0 +48 +4 +120 +255 +57 +104 +0 +0 +174 +188 +24 +0 +53 +43 +0 +0 +173 +187 +16 +11 +178 +153 +0 +0 +173 +187 +16 +11 +178 +153 +0 +0 +173 +186 +16 +11 +179 +152 +0 +0 +173 +177 +14 +11 +179 +152 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +252 +4 +0 +0 +0 +0 +192 +167 +11 +4 +181 +123 +0 +52 +255 +121 +2 +133 +219 +0 +0 +0 +198 +158 +8 +19 +198 +149 +0 +0 +198 +158 +8 +19 +198 +149 +0 +0 +198 +158 +8 +19 +198 +149 +0 +0 +198 +158 +8 +19 +198 +149 +0 +0 +198 +158 +8 +19 +198 +149 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +198 +161 +9 +24 +239 +165 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +200 +106 +0 +0 +142 +163 +0 +52 +255 +163 +9 +19 +198 +145 +0 +11 +244 +36 +0 +48 +244 +10 +0 +127 +0 +0 +0 +0 +0 +61 +252 +0 +0 +0 +0 +0 +0 +62 +252 +0 +0 +0 +0 +0 +0 +61 +252 +0 +0 +0 +0 +0 +0 +61 +252 +0 +0 +0 +0 +0 +0 +61 +252 +0 +0 +0 +0 +0 +0 +57 +252 +0 +0 +0 +0 +55 +255 +6 +54 +0 +22 +255 +41 +0 +0 +0 +0 +0 +21 +255 +50 +0 +0 +67 +236 +0 +21 +255 +50 +0 +0 +67 +236 +0 +21 +255 +49 +0 +0 +70 +236 +0 +21 +255 +37 +0 +0 +70 +236 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +252 +4 +0 +0 +0 +25 +255 +35 +0 +0 +86 +217 +0 +52 +255 +18 +0 +56 +254 +1 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +0 +240 +240 +240 +240 +240 +240 +0 +27 +255 +31 +2 +168 +165 +235 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +103 +199 +0 +3 +230 +67 +0 +52 +255 +33 +0 +0 +81 +232 +0 +0 +162 +117 +0 +130 +165 +0 +0 +127 +0 +78 +197 +237 +240 +243 +255 +0 +0 +71 +189 +224 +224 +230 +255 +0 +0 +78 +197 +237 +240 +243 +255 +0 +0 +78 +197 +237 +240 +243 +255 +0 +0 +78 +197 +237 +240 +243 +255 +0 +0 +78 +197 +237 +240 +243 +255 +0 +0 +125 +231 +244 +255 +240 +241 +0 +50 +255 +7 +0 +0 +0 +0 +0 +47 +255 +225 +224 +224 +227 +239 +0 +47 +255 +225 +224 +224 +227 +239 +0 +47 +255 +240 +240 +240 +241 +247 +0 +47 +255 +240 +240 +240 +241 +247 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +252 +4 +0 +0 +0 +48 +255 +7 +0 +0 +56 +254 +0 +52 +255 +4 +0 +52 +255 +4 +0 +48 +255 +6 +0 +0 +55 +254 +0 +48 +255 +6 +0 +0 +55 +254 +0 +48 +255 +6 +0 +0 +55 +254 +0 +48 +255 +6 +0 +0 +55 +254 +0 +48 +255 +6 +0 +0 +55 +254 +0 +0 +0 +0 +0 +0 +0 +0 +0 +48 +255 +7 +152 +111 +54 +255 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +15 +246 +36 +70 +225 +1 +0 +52 +255 +6 +0 +0 +55 +254 +0 +0 +68 +197 +0 +212 +76 +0 +0 +127 +24 +251 +95 +6 +0 +62 +255 +0 +23 +250 +82 +2 +0 +65 +255 +0 +24 +251 +86 +5 +0 +65 +255 +0 +24 +251 +86 +5 +0 +65 +255 +0 +24 +251 +86 +5 +0 +65 +255 +0 +24 +251 +86 +5 +0 +65 +255 +0 +32 +255 +57 +53 +255 +8 +0 +0 +22 +255 +41 +0 +0 +0 +0 +0 +22 +255 +23 +0 +0 +0 +0 +0 +22 +255 +23 +0 +0 +0 +0 +0 +22 +255 +21 +0 +0 +0 +0 +0 +22 +255 +21 +0 +0 +0 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +252 +4 +0 +0 +0 +25 +255 +34 +0 +0 +83 +238 +0 +52 +255 +4 +0 +52 +255 +4 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +27 +255 +32 +0 +0 +81 +234 +0 +0 +0 +0 +48 +240 +3 +0 +0 +27 +255 +165 +129 +0 +81 +234 +0 +48 +255 +8 +0 +66 +255 +4 +0 +48 +255 +8 +0 +66 +255 +4 +0 +48 +255 +8 +0 +66 +255 +4 +0 +48 +255 +8 +0 +66 +255 +4 +0 +0 +0 +166 +128 +162 +131 +0 +0 +52 +255 +32 +0 +0 +80 +233 +0 +0 +2 +226 +62 +238 +5 +0 +0 +127 +33 +255 +38 +0 +4 +170 +255 +0 +33 +255 +69 +0 +26 +189 +255 +0 +33 +255 +68 +0 +26 +189 +255 +0 +33 +255 +68 +0 +26 +189 +255 +0 +33 +255 +68 +0 +26 +189 +255 +0 +33 +255 +68 +0 +26 +189 +255 +0 +38 +255 +39 +95 +255 +76 +1 +0 +0 +177 +185 +23 +0 +50 +42 +0 +0 +176 +165 +17 +0 +32 +76 +0 +0 +176 +165 +17 +0 +32 +76 +0 +0 +176 +162 +17 +0 +32 +76 +0 +0 +176 +162 +17 +0 +29 +79 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +252 +4 +0 +0 +0 +0 +194 +163 +8 +21 +202 +156 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +200 +158 +7 +19 +198 +151 +0 +0 +200 +158 +7 +19 +198 +151 +0 +0 +200 +158 +7 +19 +198 +151 +0 +0 +200 +158 +7 +19 +198 +151 +0 +0 +200 +158 +7 +19 +198 +151 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +216 +210 +7 +19 +198 +151 +0 +15 +251 +62 +0 +147 +255 +4 +0 +15 +251 +62 +0 +147 +255 +4 +0 +15 +251 +62 +0 +147 +255 +4 +0 +15 +251 +62 +0 +147 +255 +4 +0 +0 +0 +70 +222 +242 +36 +0 +0 +52 +255 +160 +8 +17 +195 +146 +0 +0 +0 +137 +215 +157 +0 +0 +0 +127 +0 +114 +219 +196 +189 +127 +255 +0 +0 +114 +231 +243 +204 +107 +255 +0 +0 +114 +231 +243 +204 +108 +255 +0 +0 +114 +231 +243 +204 +108 +255 +0 +0 +114 +231 +243 +204 +108 +255 +0 +0 +113 +230 +243 +205 +106 +255 +0 +0 +154 +245 +215 +95 +224 +242 +0 +0 +14 +153 +237 +255 +207 +42 +0 +0 +14 +155 +234 +244 +218 +111 +0 +0 +14 +155 +234 +244 +218 +111 +0 +0 +14 +155 +234 +244 +218 +111 +0 +0 +14 +153 +233 +244 +220 +120 +0 +0 +118 +244 +246 +255 +244 +244 +0 +0 +108 +224 +230 +255 +224 +224 +0 +0 +108 +224 +230 +255 +224 +224 +0 +22 +244 +244 +255 +244 +244 +34 +0 +0 +27 +180 +242 +238 +161 +13 +0 +52 +255 +4 +0 +52 +255 +4 +0 +0 +31 +184 +243 +238 +160 +12 +0 +0 +31 +184 +243 +238 +160 +12 +0 +0 +31 +184 +243 +238 +160 +12 +0 +0 +31 +184 +243 +238 +160 +12 +0 +0 +31 +184 +243 +238 +160 +12 +0 +0 +0 +0 +0 +0 +0 +0 +0 +95 +164 +178 +242 +238 +160 +12 +0 +0 +120 +234 +191 +137 +255 +4 +0 +0 +120 +234 +191 +137 +255 +4 +0 +0 +120 +234 +191 +137 +255 +4 +0 +0 +120 +234 +191 +137 +255 +4 +0 +0 +0 +2 +227 +198 +0 +0 +0 +52 +255 +120 +232 +241 +160 +10 +0 +0 +0 +43 +255 +72 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +187 +14 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +40 +4 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +199 +105 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +18 +232 +4 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +10 +1 +167 +67 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +64 +244 +16 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +0 +0 +132 +148 +0 +0 +0 +0 +127 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +64 +242 +213 +19 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +203 +237 +92 +0 +0 +0 +0 +52 +255 +4 +0 +0 +0 +0 +0 +11 +243 +209 +25 +0 +0 +0 +0 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 +127 +127 +127 +127 +127 +127 +127 +0 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/FontLargeAA.pgm b/Extras/CDTestFramework/AntTweakBar/src/res/FontLargeAA.pgm new file mode 100644 index 0000000..1b3600d --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/res/FontLargeAA.pgm @@ -0,0 +1,1197 @@ +P2 +# Created by Paint Shop Pro +276 120 +255 +127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 +4 4 4 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 +0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 59 245 125 175 225 21 +0 0 0 0 0 0 0 0 0 0 0 0 0 138 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 59 241 89 0 0 12 235 201 89 255 166 0 0 0 0 0 172 89 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 225 21 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 +0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 138 247 34 0 12 +232 89 138 225 21 0 0 0 0 138 125 7 199 34 0 0 0 0 138 125 0 0 0 0 138 +255 255 201 0 0 0 59 215 21 0 0 0 0 59 245 255 255 166 0 0 0 59 241 89 +0 7 206 201 0 0 89 251 89 0 59 215 21 172 89 59 192 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 166 0 0 138 255 251 89 0 0 0 0 0 +138 201 0 0 0 7 206 255 255 255 166 0 0 7 206 255 255 255 201 0 0 0 0 0 +0 138 251 89 0 0 175 255 255 255 255 225 21 0 0 12 235 255 255 125 89 255 +255 255 255 255 251 89 0 12 235 255 255 225 21 0 0 59 245 255 255 166 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 59 245 255 255 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 +4 4 4 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 89 247 +34 0 12 232 89 138 201 0 0 0 0 7 202 89 59 215 21 0 0 12 235 255 255 255 +166 0 59 241 89 12 235 125 0 0 172 89 0 0 0 0 7 206 166 0 89 251 89 0 0 +12 228 34 0 89 247 34 0 0 0 175 201 0 0 89 251 191 194 247 34 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 232 89 0 175 201 0 12 235 +125 0 0 138 255 255 201 0 0 0 12 182 0 0 59 245 125 0 12 206 21 0 12 235 +166 0 0 0 0 89 255 251 89 0 0 175 201 0 0 0 0 0 0 89 255 125 0 0 0 0 0 +0 0 0 89 251 89 12 235 166 0 7 206 201 0 59 245 125 0 12 235 166 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 89 166 0 0 138 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 +0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 89 247 34 0 12 +228 34 89 201 0 0 0 0 12 206 21 89 166 0 0 12 235 125 138 125 59 192 0 +89 247 34 7 206 166 0 89 201 0 0 0 0 0 12 235 125 0 12 232 89 0 0 12 228 +34 0 175 201 0 0 0 0 59 241 89 0 0 7 206 166 0 0 0 0 0 0 0 138 166 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 225 21 59 241 89 0 0 138 225 21 0 +0 0 175 201 0 0 0 0 0 0 0 7 206 201 0 0 0 0 0 0 175 201 0 0 0 59 241 132 +241 89 0 0 175 201 0 0 0 0 0 7 206 166 0 0 0 0 0 0 0 0 7 206 201 0 59 241 +89 0 0 138 225 21 138 225 21 0 0 138 225 21 89 255 125 0 0 89 255 125 0 +0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 138 201 0 0 0 0 0 0 0 0 +0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 +0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 89 247 34 0 0 0 0 0 0 0 +0 89 255 255 255 255 255 255 255 125 59 238 34 138 125 0 0 0 89 247 34 +7 206 166 7 202 89 0 0 0 0 0 0 175 225 21 138 225 21 0 0 0 0 0 12 235 125 +0 0 0 0 7 206 125 0 89 251 191 194 247 34 0 0 0 0 0 138 166 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 0 89 247 34 0 0 89 247 34 0 0 0 175 201 +0 0 0 0 0 0 0 12 235 166 0 0 0 0 0 59 245 125 0 0 12 235 125 59 241 89 +0 0 175 201 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 89 247 34 0 12 235 201 +0 0 175 201 0 138 225 21 0 0 89 247 34 89 255 125 0 0 89 255 125 0 0 0 +0 0 12 235 255 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 175 255 251 89 0 0 0 0 +0 0 0 0 138 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 +0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 89 247 34 0 0 0 0 0 +0 0 0 0 0 175 125 7 199 34 0 0 12 235 166 138 125 0 0 0 59 241 89 12 235 +125 89 201 12 235 255 251 89 0 0 7 206 255 166 0 59 241 89 0 0 0 59 238 +34 0 0 0 0 0 175 166 59 215 21 172 89 59 192 0 0 0 0 0 138 166 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 125 0 138 247 34 0 0 89 247 34 0 0 0 +175 201 0 0 0 0 0 0 0 89 251 89 0 0 0 89 255 247 34 0 0 7 206 166 0 59 +241 89 0 0 175 255 255 255 225 21 0 89 251 226 255 255 247 34 0 0 0 7 206 +166 0 0 0 12 235 255 255 201 0 0 89 255 125 0 0 138 247 34 0 0 0 0 0 0 +0 0 0 0 0 89 255 255 166 0 0 0 0 0 175 255 255 255 255 255 255 225 21 0 +0 0 0 59 245 255 201 0 0 0 0 0 175 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 +0 0 89 225 21 0 0 0 0 0 0 0 0 0 7 199 34 59 215 21 0 0 0 59 245 255 255 +201 0 0 0 138 255 255 201 12 228 34 175 166 0 138 201 0 12 235 125 89 255 +125 59 241 89 0 0 0 59 238 34 0 0 0 0 0 138 201 0 0 0 172 89 0 0 0 7 206 +255 255 255 255 255 255 247 34 0 0 0 0 89 255 255 255 166 0 0 0 0 0 59 +238 34 0 138 247 34 0 0 89 247 34 0 0 0 175 201 0 0 0 0 0 0 59 245 166 +0 0 0 0 0 0 12 235 166 0 138 201 0 0 59 241 89 0 0 0 0 0 12 235 201 0 138 +251 89 0 0 175 225 21 0 0 89 247 34 0 0 7 206 166 0 175 255 166 0 0 89 +255 255 255 223 247 34 0 0 0 0 0 0 0 0 0 0 175 247 34 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 225 21 0 0 175 225 21 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 +0 0 127 0 0 0 0 0 59 215 21 0 0 0 0 0 0 0 12 235 255 255 255 255 255 255 +166 0 0 0 0 138 125 175 225 21 0 0 0 0 0 138 166 7 206 125 0 89 247 34 +138 225 21 0 89 255 166 215 21 0 0 0 59 238 34 0 0 0 0 0 138 201 0 0 0 +0 0 0 0 0 0 0 0 0 138 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 201 0 +0 89 247 34 0 0 89 247 34 0 0 0 175 201 0 0 0 0 0 12 235 201 0 0 0 0 0 +0 0 0 138 225 21 175 255 255 255 255 255 255 125 0 0 0 0 0 138 247 34 89 +247 34 0 0 59 241 89 0 7 206 166 0 0 0 138 247 34 0 0 138 247 34 0 0 0 +0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 89 255 255 166 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 59 245 255 201 0 0 0 0 175 201 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 +127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 166 0 175 125 0 0 0 0 0 0 138 +125 89 247 34 0 0 0 0 12 228 34 7 206 125 0 89 247 34 138 247 34 0 0 89 +255 166 0 0 0 0 59 238 34 0 0 0 0 0 175 166 0 0 0 0 0 0 0 0 0 0 0 0 138 +166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 125 0 0 59 241 89 0 0 138 225 +21 0 0 0 175 201 0 0 0 0 12 235 201 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 +0 59 241 89 0 0 0 0 0 0 138 225 21 59 241 89 0 0 59 241 89 0 89 247 34 +0 0 0 138 247 34 0 0 89 251 89 0 0 0 0 7 206 166 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 12 235 255 225 21 0 0 175 255 255 255 255 255 255 225 21 0 0 175 +255 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 89 247 +34 0 0 0 0 0 0 0 0 0 175 125 7 199 34 0 0 0 89 201 0 138 125 175 201 0 +0 0 0 0 138 166 0 0 175 166 0 138 201 0 89 255 166 0 0 89 255 255 125 0 +0 0 12 235 125 0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 0 0 0 0 138 166 0 0 0 +0 0 138 255 125 0 0 0 0 0 0 175 247 34 59 238 34 0 0 0 175 201 0 12 235 +125 0 0 0 0 175 201 0 0 0 12 235 166 0 0 0 0 0 89 166 0 0 59 245 166 0 +0 0 0 0 59 241 89 0 59 215 21 0 12 235 166 0 7 206 201 0 0 175 225 21 7 +206 166 0 0 0 0 59 245 166 0 7 206 225 21 0 0 0 0 175 225 21 0 89 255 125 +0 0 12 235 201 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 138 201 +0 0 0 0 0 0 0 0 0 175 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 0 0 89 247 +34 0 0 0 0 0 0 0 0 7 199 34 59 215 21 0 0 0 12 235 255 255 255 201 0 0 +0 0 0 59 215 21 0 0 12 235 255 251 89 0 0 89 255 255 255 201 0 89 255 0 +0 0 0 175 201 0 0 0 0 59 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 +201 0 0 0 0 0 0 0 175 247 34 138 201 0 0 0 0 0 138 255 251 89 0 0 0 138 +255 255 255 255 166 0 89 255 255 255 255 255 247 34 12 235 255 255 255 +166 0 0 0 0 0 0 59 241 89 0 12 235 255 255 255 166 0 0 0 7 206 255 255 +225 21 0 138 247 34 0 0 0 0 0 59 245 255 255 201 0 0 0 175 255 255 201 +0 0 0 89 255 125 0 0 89 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 175 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 4 4 4 4 4 4 4 4 52 4 4 4 4 4 4 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 125 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 247 34 0 0 0 175 201 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 232 89 0 0 0 0 0 0 0 0 0 0 175 125 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 125 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 201 0 0 89 251 89 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 201 0 0 0 0 0 0 0 0 0 0 12 232 89 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 232 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 4 4 0 0 0 0 0 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 201 0 0 201 201 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 +4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 0 0 0 0 0 127 127 127 0 127 127 127 +127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 0 127 127 0 127 127 127 127 0 127 127 +127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +127 0 127 127 127 0 127 127 127 127 0 127 127 127 0 127 127 127 127 0 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 +4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 255 +201 0 138 201 0 0 0 0 89 255 255 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 127 0 0 0 0 175 255 255 255 247 34 0 0 0 0 0 7 206 251 89 0 0 12 0 +235 255 255 255 255 201 0 0 0 0 59 245 255 255 255 201 12 0 235 255 255 +255 255 166 0 0 0 12 235 255 255 255 255 255 127 12 235 255 255 255 255 +251 89 0 0 12 235 255 255 255 251 89 12 235 166 0 0 0 12 235 125 89 255 +255 255 201 0 0 175 255 255 225 21 12 235 166 0 0 7 206 251 102 0 235 166 +0 0 0 0 12 235 251 89 0 0 0 89 255 225 21 12 235 251 89 0 0 12 235 125 +0 0 0 138 255 255 166 0 0 0 12 235 255 255 255 251 89 0 0 0 0 175 255 255 +201 0 0 0 12 235 255 255 255 251 89 0 0 0 12 235 255 255 255 247 47 235 +255 255 255 255 255 255 255 138 0 235 125 0 0 0 59 245 133 206 166 0 0 +0 0 59 245 255 133 201 0 0 0 138 251 89 0 0 12 235 133 206 247 34 0 0 0 +175 229 216 225 21 0 0 0 138 247 124 255 255 255 255 255 255 125 7 206 +125 0 0 0 59 238 34 0 0 0 0 0 12 235 125 0 0 0 0 175 247 34 0 0 0 0 0 0 +0 0 0 0 127 0 0 59 245 166 0 0 0 59 245 166 0 0 0 0 59 245 255 166 0 0 +12 0 235 166 0 0 59 245 125 0 0 138 255 125 0 0 7 202 102 0 235 166 0 0 +59 245 225 21 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 0 89 255 166 +0 0 0 89 127 12 235 166 0 0 0 12 235 125 0 12 235 125 0 0 0 0 0 138 225 +21 12 235 166 0 7 206 225 21 12 0 235 166 0 0 0 0 12 235 255 166 0 0 7 +206 255 225 21 12 235 255 201 0 0 12 235 125 0 59 245 166 0 0 138 251 89 +0 12 235 166 0 0 138 251 89 0 89 255 125 0 0 89 255 125 0 12 235 166 0 +0 138 251 89 0 12 235 166 0 0 7 202 89 0 0 0 138 225 21 0 0 12 0 235 125 +0 0 0 59 245 125 138 225 21 0 0 0 138 225 151 34 247 34 0 0 175 255 125 +0 0 89 247 34 12 235 166 0 0 89 247 34 59 245 125 0 0 59 245 125 0 0 0 +0 0 138 247 34 7 206 125 0 0 0 7 206 125 0 0 0 0 0 12 235 125 0 0 0 138 +225 187 201 0 0 0 0 0 0 0 0 0 0 127 0 12 232 89 0 0 0 0 0 12 232 89 0 0 +0 138 225 151 225 21 0 12 0 235 166 0 0 12 235 166 0 12 235 166 0 0 0 0 +0 12 0 235 166 0 0 0 12 235 166 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 +0 0 12 235 166 0 0 0 0 0 0 12 235 166 0 0 0 12 235 125 0 12 235 125 0 0 +0 0 0 138 225 21 12 235 166 0 175 225 21 0 12 0 235 166 0 0 0 0 12 235 +166 238 34 0 59 215 187 225 21 12 235 166 245 125 0 12 235 125 12 235 125 +0 0 0 0 138 247 34 12 235 166 0 0 12 235 166 12 235 125 0 0 0 0 138 247 +34 12 235 166 0 0 12 235 166 0 89 247 34 0 0 0 0 0 0 0 0 138 225 21 0 0 +12 0 235 125 0 0 0 59 245 125 59 241 89 0 0 7 206 166 59 0 241 89 0 12 +232 194 201 0 0 138 225 21 0 89 251 89 12 235 166 0 0 138 247 34 7 206 +201 0 0 0 0 0 59 245 125 0 7 206 125 0 0 0 0 138 201 0 0 0 0 0 12 235 125 +0 0 59 241 89 12 235 166 0 0 0 0 0 0 0 0 0 127 0 175 166 0 59 245 255 255 +247 34 138 201 0 0 7 206 166 59 241 89 0 12 0 235 166 0 0 89 251 89 0 89 +247 34 0 0 0 0 0 12 0 235 166 0 0 0 0 138 225 21 12 235 166 0 0 0 0 0 12 +235 166 0 0 0 0 0 89 247 34 0 0 0 0 0 0 12 235 166 0 0 0 12 235 125 0 12 +235 125 0 0 0 0 0 138 225 21 12 235 166 175 247 34 0 0 12 0 235 166 0 0 +0 0 12 235 133 206 166 0 175 166 175 225 21 12 235 125 138 225 21 12 235 +125 89 247 34 0 0 0 0 59 245 125 12 235 166 0 0 12 235 166 89 247 34 0 +0 0 0 59 245 125 12 235 166 0 0 12 235 125 0 89 255 125 0 0 0 0 0 0 0 0 +138 225 21 0 0 12 0 235 125 0 0 0 59 245 125 7 206 201 0 0 59 241 89 7 +0 206 166 0 59 215 111 225 21 7 206 166 0 0 0 175 225 187 225 21 0 0 12 +235 166 89 247 34 0 0 0 0 7 206 201 0 0 7 206 125 0 0 0 0 89 225 21 0 0 +0 0 12 235 125 0 12 235 166 0 0 59 241 89 0 0 0 0 0 0 0 0 127 0 202 89 +12 235 125 0 12 228 34 59 215 0 0 59 241 89 7 206 166 0 12 0 235 255 255 +255 255 166 0 0 138 225 21 0 0 0 0 0 12 0 235 166 0 0 0 0 89 247 34 12 +235 255 255 255 255 247 34 12 235 255 255 255 255 247 0 163 225 21 0 0 +0 0 0 0 12 235 255 255 255 255 255 255 125 0 12 235 125 0 0 0 0 0 138 225 +21 12 235 255 247 34 0 0 0 12 0 235 166 0 0 0 0 12 235 125 89 225 34 228 +34 175 225 21 12 235 125 12 235 125 12 235 125 138 225 21 0 0 0 0 12 235 +166 12 235 166 0 0 175 247 34 138 225 21 0 0 0 0 12 235 166 12 235 166 +0 0 175 225 21 0 0 175 255 255 225 21 0 0 0 0 0 138 225 21 0 0 12 0 235 +125 0 0 0 59 245 125 0 138 247 34 0 138 225 21 0 0 175 201 0 138 201 12 +232 89 12 235 125 0 0 0 12 235 251 89 0 0 0 0 89 255 255 125 0 0 0 0 0 +138 247 34 0 0 7 206 125 0 0 0 0 12 232 89 0 0 0 0 12 235 125 7 206 201 +0 0 0 0 138 251 89 0 0 0 0 0 0 0 127 7 228 34 89 225 21 0 12 228 34 12 +228 0 0 138 225 21 0 138 225 21 12 0 235 166 0 0 12 235 201 0 138 225 21 +0 0 0 0 0 12 0 235 166 0 0 0 0 89 247 34 12 235 166 0 0 0 0 0 12 235 166 +0 0 0 0 0 138 225 21 0 12 235 255 255 127 12 235 166 0 0 0 12 235 125 0 +12 235 125 0 0 0 0 0 138 225 21 12 235 229 216 225 21 0 0 12 0 235 166 +0 0 0 0 12 235 125 12 235 223 201 0 175 225 21 12 235 125 0 138 225 34 +235 125 138 225 21 0 0 0 0 12 235 166 12 235 255 255 255 247 34 0 138 225 +21 0 0 0 0 12 235 166 12 235 255 255 255 166 0 0 0 0 0 0 89 255 255 247 +34 0 0 0 138 225 21 0 0 12 0 235 125 0 0 0 59 245 125 0 59 245 125 7 206 +166 0 0 0 89 247 34 175 125 7 206 125 89 247 34 0 0 0 12 235 251 89 0 0 +0 0 7 206 225 21 0 0 0 0 59 245 125 0 0 0 7 206 125 0 0 0 0 0 175 166 0 +0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 12 228 34 89 225 +21 0 12 228 34 59 215 0 7 206 255 255 255 255 251 89 12 0 235 166 0 0 0 +138 247 0 124 247 34 0 0 0 0 0 12 0 235 166 0 0 0 0 138 225 21 12 235 166 +0 0 0 0 0 12 235 166 0 0 0 0 0 89 247 34 0 0 0 0 175 127 12 235 166 0 0 +0 12 235 125 0 12 235 125 0 0 0 0 0 138 225 21 12 235 166 59 245 201 0 +0 12 0 235 166 0 0 0 0 12 235 125 0 138 251 89 0 175 225 21 12 235 125 +0 12 235 138 235 125 89 247 34 0 0 0 0 59 245 125 12 235 166 0 0 0 0 0 +89 247 34 0 0 0 0 59 245 125 12 235 166 0 175 247 34 0 0 0 0 0 0 0 59 245 +166 0 0 0 138 225 21 0 0 12 0 235 125 0 0 0 59 241 89 0 7 206 201 59 241 +89 0 0 0 59 241 102 232 89 0 138 201 138 225 21 0 0 0 175 201 175 225 21 +0 0 0 0 175 225 21 0 0 0 7 206 201 0 0 0 0 7 206 125 0 0 0 0 0 89 225 21 +0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 12 232 89 59 241 +89 0 89 247 34 89 201 0 59 241 89 0 0 7 206 166 12 0 235 166 0 0 0 138 +225 0 81 245 166 0 0 0 0 0 12 0 235 166 0 0 0 12 235 166 0 12 235 166 0 +0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 175 127 12 235 166 0 0 +0 12 235 125 0 12 235 125 0 0 0 0 0 138 225 21 12 235 166 0 89 255 166 +0 12 0 235 166 0 0 0 0 12 235 125 0 12 182 0 0 175 225 21 12 235 125 0 +0 138 232 245 125 12 235 125 0 0 0 0 138 247 34 12 235 166 0 0 0 0 0 12 +235 125 0 0 0 0 138 247 34 12 235 166 0 7 206 225 21 0 0 0 0 0 0 12 235 +166 0 0 0 138 225 21 0 0 12 0 235 166 0 0 0 89 251 89 0 0 138 247 163 225 +21 0 0 0 7 206 200 215 21 0 89 225 187 166 0 0 0 89 251 89 12 235 166 0 +0 0 0 175 225 21 0 0 0 138 247 34 0 0 0 0 7 206 125 0 0 0 0 0 12 232 89 +0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 12 175 166 0 89 +255 255 210 235 255 255 125 0 138 225 21 0 0 0 138 247 47 0 235 166 0 0 +59 245 166 0 0 138 255 125 0 0 7 202 102 0 235 166 0 0 12 235 225 21 0 +12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 0 138 255 125 0 0 0 175 127 12 +235 166 0 0 0 12 235 125 0 12 235 125 0 0 0 0 7 206 201 0 12 235 166 0 +0 138 255 125 12 0 235 166 0 0 0 12 0 235 125 0 0 0 0 0 175 225 21 12 235 +125 0 0 12 235 255 125 0 89 255 125 0 0 89 251 89 0 12 235 166 0 0 0 0 +0 0 89 255 125 0 0 89 255 125 0 12 235 166 0 0 12 235 201 0 138 166 0 0 +0 138 251 89 0 0 0 138 225 21 0 0 0 0 138 247 34 0 7 206 225 21 0 0 12 +235 255 166 0 0 0 0 0 175 255 201 0 0 12 235 255 125 0 0 12 235 166 0 0 +138 251 89 0 0 0 175 225 21 0 0 89 251 89 0 0 0 0 0 7 206 125 0 0 0 0 0 +0 175 166 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 59 241 +89 0 0 0 0 0 0 0 0 7 206 166 0 0 0 0 59 245 138 0 235 255 255 255 255 125 +0 0 0 0 59 245 255 255 255 201 12 0 235 255 255 255 255 166 0 0 0 12 235 +255 255 255 255 255 127 12 235 166 0 0 0 0 0 0 0 59 245 255 255 255 225 +21 12 235 166 0 0 0 12 235 125 89 255 255 255 210 127 235 255 255 225 21 +0 12 235 166 0 0 0 175 255 127 0 235 255 255 255 247 47 0 235 125 0 0 0 +0 0 175 225 21 12 235 125 0 0 0 138 255 125 0 0 0 175 255 255 201 0 0 0 +12 235 166 0 0 0 0 0 0 0 0 175 255 255 201 0 0 0 12 235 166 0 0 0 89 255 +225 34 235 255 255 255 247 34 0 0 0 0 138 225 21 0 0 0 0 0 138 255 255 +255 201 0 0 0 0 0 175 251 89 0 0 0 0 0 89 255 166 0 0 7 206 247 34 0 7 +206 225 21 0 0 7 206 225 21 0 0 175 225 21 0 0 138 255 255 255 255 255 +255 166 7 206 125 0 0 0 0 0 0 138 201 0 0 0 12 235 125 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 127 0 0 89 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 201 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 7 206 125 0 0 0 0 0 0 59 238 34 0 0 12 235 125 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 0 0 0 7 206 255 255 255 225 21 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 251 89 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 7 206 125 0 0 0 0 0 0 7 206 125 0 0 12 235 125 0 0 0 +0 0 0 0 0 0 0 245 255 255 255 255 255 255 127 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 +255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 255 201 0 0 0 0 0 0 89 89 255 255 +255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 59 245 166 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 89 247 34 0 0 0 0 0 0 0 0 0 0 12 235 +125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 12 235 +255 247 0 0 0 0 0 0 0 12 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 +0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 255 251 89 0 7 206 125 0 89 255 251 89 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 84 84 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 7 206 +125 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 +225 21 0 0 0 0 0 0 0 0 0 175 201 0 0 0 0 0 0 0 0 0 12 12 235 125 0 0 0 +0 0 59 245 102 0 89 247 34 12 235 125 0 0 0 0 0 12 235 125 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +59 241 89 0 0 0 7 206 125 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 4 4 4 4 4 4 4 100 252 252 84 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 +235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 12 0 +235 125 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 +0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 +125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 247 34 0 0 0 7 206 125 0 0 0 59 238 +34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 20 236 252 164 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 0 0 0 0 0 0 12 235 255 255 255 166 0 12 235 166 245 255 247 34 0 0 12 +235 255 255 247 34 0 34 235 255 255 255 225 21 0 12 235 255 255 225 29 +0 206 255 255 255 127 0 12 235 255 255 255 225 21 12 235 138 235 255 247 +34 0 12 235 102 175 255 247 34 12 235 125 0 59 245 201 0 12 235 125 12 +0 235 166 245 255 225 29 206 255 251 89 0 12 235 138 235 255 247 34 0 0 +12 235 255 255 201 0 0 12 235 166 245 255 251 89 0 0 12 235 255 255 255 +225 21 12 235 138 235 247 127 34 138 255 255 255 206 0 206 255 255 255 +201 59 241 89 0 0 89 247 42 206 201 0 0 0 138 225 187 201 0 0 138 225 21 +0 59 241 187 226 247 34 0 7 206 206 206 201 0 0 0 138 225 151 255 255 255 +255 247 0 0 89 247 34 0 0 0 7 206 125 0 0 0 59 238 34 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 4 4 4 4 4 4 4 148 252 236 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 12 206 +21 0 59 245 125 12 235 247 34 0 138 225 21 12 235 166 0 0 134 102 0 235 +166 0 0 138 225 21 12 235 125 0 0 175 201 12 0 235 125 0 0 12 235 166 0 +0 138 225 21 12 235 247 34 0 175 201 0 12 235 102 0 89 247 34 12 235 125 +12 235 166 0 0 12 235 125 12 0 235 225 21 12 235 251 89 0 175 201 0 12 +235 247 34 0 175 201 0 12 235 166 0 7 206 201 0 12 235 225 21 0 175 225 +21 12 235 166 0 0 138 225 21 12 235 247 34 0 0 89 247 34 0 12 206 34 0 +235 125 0 0 59 241 89 0 0 89 247 34 89 247 34 0 7 206 166 138 225 21 7 +206 251 89 0 89 225 138 34 235 201 0 138 225 21 89 247 34 0 7 206 166 0 +0 0 7 206 166 0 0 89 225 21 0 0 0 7 206 125 0 0 0 59 241 89 0 0 0 0 138 +251 89 0 0 7 202 89 0 0 4 4 4 4 4 4 52 252 252 108 4 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +0 0 0 0 0 0 0 0 7 206 102 12 235 125 0 0 59 241 89 138 225 21 0 0 0 34 +89 225 21 0 0 138 225 21 89 225 21 0 0 89 247 47 0 235 125 0 0 89 225 21 +0 0 138 225 21 12 235 125 0 0 89 247 34 12 235 102 0 89 247 34 12 235 138 +235 166 0 0 0 12 235 125 12 0 235 125 0 7 206 166 0 0 138 225 21 12 235 +125 0 0 89 247 34 138 225 21 0 0 59 238 34 12 235 125 0 0 59 241 89 89 +225 21 0 0 138 225 21 12 235 125 0 0 0 138 225 21 0 0 0 12 0 235 125 0 +0 59 241 89 0 0 89 247 34 12 235 125 0 59 241 89 59 238 34 12 228 198 166 +0 175 166 59 0 89 251 132 241 89 0 12 235 125 0 59 238 34 0 0 0 138 225 +21 0 12 235 166 0 0 0 0 7 206 125 0 0 0 0 175 201 0 0 0 138 166 12 235 +166 0 12 232 89 0 0 12 84 4 4 4 4 204 252 204 4 4 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 +0 0 0 59 245 255 255 255 102 12 235 125 0 0 12 235 125 175 201 0 0 0 0 +0 175 201 0 0 0 138 225 21 175 255 255 255 255 255 247 47 0 235 125 0 0 +175 201 0 0 0 138 225 21 12 235 125 0 0 89 247 34 12 235 102 0 89 247 34 +12 235 255 225 21 0 0 0 12 235 125 12 0 235 125 0 7 206 166 0 0 138 225 +21 12 235 125 0 0 89 247 34 175 201 0 0 0 12 232 89 12 235 125 0 0 12 235 +125 175 201 0 0 0 138 225 21 12 235 125 0 0 0 59 245 255 247 34 0 12 0 +235 125 0 0 59 241 89 0 0 89 247 34 0 175 201 0 138 201 0 12 235 125 89 +201 89 225 29 206 125 12 0 0 175 255 166 0 0 0 175 201 0 138 201 0 0 0 +89 251 89 0 138 247 34 0 0 0 0 0 7 206 125 0 0 0 0 0 89 255 125 7 202 89 +0 89 251 89 89 201 0 0 0 172 252 84 4 4 100 252 252 60 4 4 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 0 0 0 0 0 0 89 255 166 0 7 206 102 12 235 125 0 0 12 235 125 175 201 +0 0 0 0 0 175 201 0 0 0 138 225 21 175 201 0 0 0 0 0 12 0 235 125 0 0 175 +201 0 0 0 138 225 21 12 235 125 0 0 89 247 34 12 235 102 0 89 247 34 12 +235 138 235 201 0 0 0 12 235 125 12 0 235 125 0 7 206 166 0 0 138 225 21 +12 235 125 0 0 89 247 34 175 201 0 0 0 12 232 89 12 235 125 0 0 12 235 +125 175 201 0 0 0 138 225 21 12 235 125 0 0 0 0 0 138 255 255 201 12 0 +235 125 0 0 59 241 89 0 0 89 247 34 0 89 247 42 206 125 0 0 175 166 175 +125 12 232 102 232 89 0 0 0 175 255 201 0 0 0 89 247 47 235 125 0 0 12 +235 166 0 0 0 12 235 125 0 0 0 0 7 206 125 0 0 0 0 138 201 0 0 12 232 89 +0 0 59 245 225 21 0 0 0 196 252 244 60 20 236 252 156 4 4 4 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 0 0 0 0 0 0 175 201 0 0 7 206 102 12 235 125 0 0 59 241 89 138 225 21 +0 0 0 34 89 225 21 0 0 138 225 21 138 247 34 0 0 0 0 12 0 235 125 0 0 138 +225 21 0 0 138 225 21 12 235 125 0 0 89 247 34 12 235 102 0 89 247 34 12 +235 125 59 245 125 0 0 12 235 125 12 0 235 125 0 7 206 166 0 0 138 225 +21 12 235 125 0 0 89 247 34 138 225 21 0 0 89 247 34 12 235 125 0 0 59 +241 89 138 225 21 0 0 138 225 21 12 235 125 0 0 0 0 0 0 0 89 247 47 0 235 +125 0 0 59 241 89 0 0 89 247 34 0 12 235 166 238 34 0 0 138 210 228 34 +0 175 166 215 21 0 0 89 251 159 251 89 0 0 12 235 191 247 34 0 0 175 225 +21 0 0 0 0 138 225 21 0 0 0 7 206 125 0 0 0 12 232 89 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 20 220 252 236 180 252 244 28 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 +138 225 21 0 138 255 102 12 235 125 0 7 206 201 0 12 235 166 0 0 134 132 +0 245 125 0 59 245 225 21 12 235 201 0 0 12 206 34 0 235 125 0 0 59 245 +125 0 12 235 225 21 12 235 125 0 0 89 247 34 12 235 102 0 89 247 34 12 +235 125 0 138 251 89 0 12 235 125 12 0 235 125 0 7 206 166 0 0 138 225 +21 12 235 125 0 0 89 247 34 12 235 166 0 7 206 201 0 12 235 125 0 7 206 +201 0 59 245 125 0 12 235 225 21 12 235 125 0 0 0 138 125 0 0 138 225 29 +0 206 166 0 0 7 206 166 0 59 245 247 34 0 0 175 255 201 0 0 0 59 245 225 +21 0 89 255 201 0 0 12 235 166 0 175 225 21 0 0 138 255 166 0 0 89 251 +89 0 0 0 0 0 89 247 34 0 0 0 7 206 125 0 0 0 59 238 34 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 4 36 236 252 252 252 108 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 +7 206 255 255 171 206 102 12 232 226 255 255 225 21 0 0 12 235 255 255 +247 34 0 89 255 255 247 163 225 21 0 7 206 255 255 247 34 12 0 235 125 +0 0 0 89 255 255 247 163 225 21 12 235 125 0 0 89 247 34 12 235 102 0 89 +247 34 12 235 125 0 0 175 251 34 0 235 125 12 0 235 125 0 7 206 166 0 0 +138 225 21 12 235 125 0 0 89 247 34 0 12 235 255 255 201 0 0 12 235 255 +255 255 225 21 0 0 89 255 255 247 163 225 21 12 235 125 0 0 0 89 255 255 +255 247 34 0 0 89 255 255 127 0 59 245 255 225 111 247 34 0 0 59 245 125 +0 0 0 12 235 166 0 0 59 245 125 7 0 206 225 21 0 12 235 201 0 0 59 241 +89 0 0 175 255 255 255 255 247 0 0 89 247 34 0 0 0 7 206 125 0 0 0 59 238 +34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 60 252 252 204 4 4 4 4 4 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 +89 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 89 247 34 0 0 0 7 +206 125 0 0 0 59 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 76 252 60 4 4 +4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 34 0 12 232 89 0 0 +0 0 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 +0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 166 0 0 0 0 0 0 0 0 +0 0 0 12 235 125 0 0 0 7 206 125 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 76 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +12 235 255 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 255 251 89 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 +125 0 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 +247 34 0 0 0 0 0 0 0 0 0 0 0 0 89 255 251 89 0 7 206 125 0 89 255 247 34 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 0 127 127 127 0 127 127 127 127 127 127 127 0 +127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 +127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 125 0 175 166 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 206 125 0 175 166 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 225 21 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 125 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 125 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 166 0 138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 166 0 138 201 0 7 206 166 12 235 +125 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 175 125 +0 0 0 0 0 175 171 206 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 125 0 +31 206 130 255 166 175 247 34 0 0 89 255 125 175 247 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 247 34 138 166 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 59 241 132 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 59 241 132 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 +59 245 255 255 255 125 0 12 235 255 255 255 255 255 225 21 0 0 0 0 0 0 +0 0 175 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 0 0 +0 0 175 125 0 0 0 0 89 225 21 59 238 34 0 0 138 255 255 201 0 0 0 59 215 +21 0 0 0 0 0 0 0 0 0 12 235 255 255 255 247 34 0 0 0 0 0 0 0 12 235 255 +255 255 255 255 255 255 255 251 89 0 12 235 255 255 255 255 255 225 21 +0 89 255 255 255 255 255 255 125 0 12 235 255 255 255 255 255 225 21 0 +0 12 235 255 255 255 255 255 225 21 7 206 201 0 50 206 56 255 201 12 235 +125 0 0 138 225 29 206 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 7 202 89 89 255 225 21 0 89 255 255 255 225 81 245 201 0 138 251 +89 0 0 138 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 255 +255 255 255 225 21 0 0 0 138 255 166 7 206 225 21 0 0 0 138 247 34 0 0 +0 0 127 0 89 255 125 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 0 89 +247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 175 +125 0 0 0 0 0 0 0 0 0 0 0 59 241 89 12 235 125 0 0 172 89 0 0 0 0 0 0 0 +0 0 12 235 166 0 0 7 202 89 0 0 0 0 0 0 89 255 201 0 0 12 235 125 0 0 0 +0 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 138 247 34 0 12 146 0 0 0 0 0 +144 21 0 0 12 146 0 0 0 0 0 144 21 0 89 225 21 71 157 22 191 225 21 175 +201 0 7 206 125 59 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 59 196 199 47 206 184 89 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 +0 0 0 59 245 125 0 0 59 245 125 0 0 0 0 0 127 12 235 166 0 0 0 0 0 0 12 +146 0 0 0 0 0 144 21 0 0 0 0 0 0 0 175 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 12 235 255 255 255 255 127 34 235 255 255 255 255 225 21 0 +0 0 0 0 0 0 0 89 247 34 7 206 166 0 89 201 0 0 0 0 0 0 0 0 0 0 89 247 34 +0 0 0 0 0 0 0 0 59 115 12 235 166 0 0 0 12 235 125 0 0 0 0 0 0 12 146 0 +0 0 0 0 144 21 0 0 0 0 0 59 245 125 0 0 12 146 0 0 0 0 0 144 21 0 0 12 +146 0 0 0 0 0 144 21 0 7 202 89 117 104 0 29 202 89 59 215 21 59 215 21 +138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 175 125 0 59 192 89 223 125 172 89 0 138 255 255 255 201 12 182 +0 0 0 0 0 175 255 255 125 0 89 255 255 247 34 0 0 12 146 0 0 0 0 0 144 +21 0 138 255 255 255 255 247 34 138 247 34 7 206 201 0 0 0 0 0 0 127 89 +251 89 0 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 7 206 166 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 175 125 0 0 0 +0 0 0 0 0 0 0 0 89 247 34 7 206 166 7 202 89 0 0 0 0 0 0 0 0 0 0 89 255 +125 0 0 0 0 0 0 0 89 255 125 89 247 34 0 0 0 12 235 125 0 0 0 0 0 0 12 +146 0 0 0 0 0 144 21 0 0 0 0 7 206 201 0 0 0 12 146 0 0 0 0 0 144 21 0 +0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 +255 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 +125 0 59 192 12 228 34 172 89 89 247 34 0 12 206 29 206 201 0 0 7 206 166 +0 7 206 255 225 21 0 89 247 34 0 12 146 0 0 0 0 0 144 21 0 0 0 0 7 206 +166 0 12 235 166 89 247 34 0 0 0 0 0 0 127 245 255 255 255 255 255 201 +0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 59 245 255 255 255 127 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 175 125 0 0 0 0 0 0 0 +0 0 0 0 59 241 89 12 235 125 89 201 12 235 255 251 89 0 89 255 255 225 +21 0 175 255 255 225 21 0 0 0 89 251 89 0 138 225 21 0 0 0 12 235 255 255 +255 255 225 21 0 12 146 0 0 0 0 0 144 21 0 0 0 0 138 247 34 0 0 0 12 146 +0 0 0 0 0 144 21 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 12 235 255 255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 59 192 0 0 0 172 89 138 225 21 0 0 0 +0 7 206 225 21 138 225 21 0 0 89 251 89 0 0 12 235 125 0 12 146 0 0 0 0 +0 144 21 0 0 0 0 138 225 21 0 0 89 255 255 125 0 0 0 0 0 0 0 127 138 225 +21 0 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 59 241 89 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 0 12 235 255 255 255 255 +225 21 0 0 0 0 0 0 0 0 0 138 255 255 201 12 228 34 175 166 0 138 201 7 +206 125 7 206 166 0 0 0 89 255 255 247 34 59 241 89 0 0 138 225 21 0 0 +0 12 235 125 0 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 0 59 245 125 0 0 0 +0 12 146 0 0 0 0 0 144 21 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 59 245 255 255 255 207 235 255 255 255 255 255 255 +207 235 255 255 255 255 255 255 255 255 255 255 255 225 21 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 59 245 255 247 34 0 0 0 0 175 166 175 201 0 0 0 +59 245 255 255 255 255 255 125 0 12 146 0 0 0 0 0 144 21 0 0 0 89 251 89 +0 0 0 7 206 225 21 0 0 0 0 0 0 0 127 245 255 255 255 255 255 125 0 0 12 +146 0 0 0 0 0 144 21 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 138 166 7 206 125 0 89 247 94 241 89 0 138 201 0 0 0 0 0 59 245 166 +0 89 251 89 0 89 247 34 0 0 0 12 235 125 0 0 0 0 0 0 12 146 0 0 0 0 0 144 +21 0 0 7 206 201 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 12 146 0 0 0 0 0 +144 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 255 255 166 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 138 255 255 201 0 7 206 225 21 175 201 0 0 0 59 241 89 0 0 0 0 +0 0 12 146 0 0 0 0 0 144 21 0 0 12 235 166 0 0 0 0 0 175 225 21 0 0 0 0 +0 0 0 127 89 255 125 0 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 89 +247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 +175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 228 34 7 206 125 0 89 247 94 241 +89 0 138 201 0 0 0 0 0 12 235 166 0 0 89 255 125 12 235 166 0 0 0 12 235 +125 0 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 138 247 34 0 0 0 0 0 12 146 +0 0 0 0 0 144 21 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 59 245 255 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 247 42 206 201 0 0 89 +225 21 0 0 89 255 125 0 0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 0 175 225 21 +0 0 0 0 0 175 225 21 0 0 0 0 0 0 0 127 0 175 251 89 0 0 0 0 0 12 146 0 +0 0 0 0 144 21 0 59 245 166 0 0 138 225 21 0 0 0 59 245 166 138 251 89 +7 206 201 0 12 235 125 0 59 241 89 0 0 0 175 125 0 0 0 0 0 175 125 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 0 0 175 166 0 138 201 7 206 125 7 206 +166 138 166 0 0 0 138 251 89 0 0 0 59 115 0 89 255 201 0 0 12 235 125 0 +0 0 0 0 0 12 146 0 0 0 0 0 144 21 0 89 251 89 0 0 0 0 0 0 12 146 0 0 0 +0 0 144 21 0 0 12 146 0 0 0 0 0 144 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 138 125 0 0 138 225 34 182 0 0 0 7 206 166 0 +7 206 255 247 34 0 0 175 125 0 12 146 0 0 0 0 0 144 21 0 89 251 89 0 0 +0 0 0 0 175 225 21 0 0 0 0 0 0 0 127 0 0 138 255 255 255 255 125 0 12 235 +255 255 255 255 255 225 21 0 138 247 34 0 7 206 166 0 0 0 0 89 247 34 175 +201 0 7 206 201 0 12 235 125 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 59 215 21 0 0 12 235 255 251 89 0 89 255 255 225 +21 12 235 255 255 255 247 34 0 0 0 0 0 0 0 0 12 235 255 255 255 255 255 +255 255 255 251 89 0 12 235 255 255 255 255 255 225 21 0 138 255 255 255 +255 255 255 166 0 12 235 255 255 255 255 255 225 21 0 0 12 235 255 255 +255 255 255 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 89 255 255 255 247 34 0 0 0 0 0 0 0 175 255 255 125 0 138 255 255 +255 125 0 0 12 235 255 255 255 255 255 225 21 0 175 255 255 255 255 247 +0 0 0 175 225 21 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 175 166 0 255 255 201 0 0 0 0 0 175 166 12 232 89 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 +228 34 0 0 0 0 0 0 0 0 12 232 89 59 215 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 0 127 127 127 0 127 127 0 127 127 127 127 127 0 127 127 127 127 +127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 +0 127 127 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 245 255 255 255 255 255 255 225 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 225 21 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 247 +34 0 0 0 0 59 192 0 0 0 0 0 7 206 255 255 225 21 0 0 0 0 0 0 0 0 138 247 +34 0 0 89 251 89 0 7 206 125 0 0 7 206 255 255 255 166 0 89 251 89 138 +247 34 0 0 0 0 7 206 255 255 255 247 34 0 0 0 0 175 255 255 251 89 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 255 255 247 +34 0 0 0 0 0 0 0 0 0 0 0 0 89 255 255 247 34 0 0 0 0 0 0 0 0 0 0 0 0 12 +235 255 247 34 0 0 7 206 255 251 89 0 0 7 206 125 0 0 0 0 0 0 0 0 0 0 0 +0 89 255 255 255 255 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 0 +59 245 255 247 34 0 0 0 0 0 0 0 0 0 0 0 89 201 0 0 0 0 175 166 0 0 0 0 +0 0 89 201 0 0 0 0 175 166 0 0 0 0 0 59 245 255 201 0 0 0 59 241 89 0 0 +0 0 0 59 245 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 247 34 +0 0 0 0 59 192 0 0 0 0 0 175 201 0 0 144 21 0 0 0 0 0 0 0 0 7 206 166 0 +7 206 166 0 0 7 206 125 0 7 206 201 0 0 89 166 0 0 0 0 0 0 0 0 0 0 89 255 +125 0 0 0 59 245 166 0 0 0 0 0 0 12 206 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 89 255 125 0 0 0 59 245 166 0 0 0 0 0 0 0 0 0 0 59 +241 89 0 138 201 0 0 0 0 0 138 166 0 0 0 0 0 168 34 7 206 166 0 0 172 89 +0 175 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 255 255 166 89 225 21 +0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 251 89 0 0 12 235 125 0 138 225 21 0 0 +0 0 0 0 0 0 7 206 255 201 0 0 0 89 225 21 0 0 0 0 7 206 255 201 0 0 0 89 +225 21 0 0 0 0 12 206 21 12 235 125 0 0 175 166 0 0 0 0 0 0 59 245 125 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 175 255 255 255 +166 0 0 12 235 125 0 0 0 0 89 225 21 0 0 12 232 89 0 89 247 34 89 247 34 +0 0 7 206 125 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 89 225 21 0 0 0 0 +0 7 206 125 0 0 7 206 255 255 247 34 0 0 0 85 89 0 85 89 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 89 225 21 0 0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 0 89 201 +0 0 12 228 34 0 0 0 0 138 166 0 0 0 0 0 0 0 7 206 125 0 0 7 206 255 166 +0 0 0 0 0 0 0 0 0 12 235 125 0 0 89 247 34 175 255 255 255 166 89 225 21 +0 89 255 125 0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 89 225 21 0 12 232 89 59 +115 0 59 115 0 0 0 0 0 89 201 0 0 7 206 125 0 0 0 0 0 0 0 89 201 0 0 7 +206 125 0 0 0 0 0 0 0 0 12 232 89 0 59 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 225 21 0 0 138 247 94 192 12 182 +0 0 12 235 125 0 0 0 0 0 175 255 255 255 255 166 0 0 7 206 171 206 166 +0 0 0 7 206 125 0 7 206 251 89 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 59 245 +255 255 201 0 12 228 34 12 235 166 0 12 228 34 0 0 138 251 89 138 247 34 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 138 255 255 255 125 0 12 228 34 +0 0 0 0 0 0 0 0 59 241 89 0 138 201 0 0 0 0 0 138 166 0 0 0 0 0 0 0 175 +201 0 0 0 0 0 0 175 201 0 0 0 0 0 0 0 0 12 235 125 0 0 89 247 34 175 255 +255 255 166 89 225 21 0 89 255 125 0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 138 +225 21 0 12 235 125 12 235 166 59 245 166 0 0 0 0 89 201 0 0 89 225 21 +0 0 0 0 0 0 0 89 201 0 0 89 225 21 0 0 0 0 0 0 12 235 255 125 0 0 175 125 +0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 +225 21 0 12 235 125 59 192 0 0 0 0 12 235 125 0 0 0 0 0 59 215 21 59 238 +34 0 0 0 89 255 247 34 0 0 0 7 206 125 0 0 7 206 255 255 247 34 0 0 0 0 +0 0 0 0 59 192 0 12 235 166 0 7 176 21 0 175 125 59 238 34 0 12 228 34 +0 138 247 34 138 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 192 0 0 138 +201 0 89 247 34 0 175 125 0 0 0 0 0 0 0 0 0 89 255 255 225 21 0 7 206 255 +255 255 255 255 255 247 34 0 12 235 125 0 0 0 7 176 21 0 175 201 0 0 0 +0 0 0 0 0 12 235 125 0 0 89 247 34 89 255 255 255 166 89 225 21 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 89 225 21 0 12 232 89 0 12 235 166 12 +235 166 0 0 0 89 201 0 7 206 125 0 12 235 166 0 0 0 0 89 201 0 7 206 125 +89 255 255 255 125 0 0 0 0 7 206 125 89 225 21 0 138 225 21 0 0 0 138 255 +125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 247 34 0 59 241 89 59 +192 0 0 0 12 235 255 255 255 225 21 0 0 138 166 0 7 202 89 0 0 0 7 206 +166 0 0 0 0 0 0 0 0 7 206 125 0 12 235 201 0 0 0 0 0 0 0 0 89 166 0 89 +247 34 0 0 0 0 0 89 166 12 232 89 0 138 247 34 89 247 34 59 238 34 0 0 +12 235 255 255 255 255 255 255 247 34 89 255 255 255 166 89 166 0 0 138 +201 0 138 225 21 0 89 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 +0 0 0 0 7 206 255 255 255 247 34 0 59 245 255 247 34 0 0 0 0 0 0 0 0 12 +235 125 0 0 89 247 34 0 89 255 255 166 89 225 21 0 0 0 0 0 0 0 0 0 0 0 +0 0 89 255 255 255 166 0 12 235 125 0 138 225 21 0 0 12 235 125 12 235 +125 0 0 89 201 0 89 201 0 7 206 223 166 0 0 0 0 89 201 0 89 201 0 89 125 +0 138 225 21 12 182 0 7 206 133 206 125 0 89 232 215 21 0 7 206 247 34 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 247 34 0 59 241 89 59 +192 0 0 0 0 12 235 125 0 0 0 0 0 59 215 21 59 238 34 0 59 245 255 255 255 +255 225 21 0 0 0 0 0 59 241 89 0 0 138 225 21 0 0 0 0 0 0 0 89 166 0 89 +247 34 0 0 0 0 0 89 166 0 138 255 255 176 228 34 0 138 247 34 138 247 34 +0 0 0 0 0 0 0 0 59 238 34 0 0 0 0 0 89 166 0 0 138 255 255 225 21 0 0 89 +166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 89 247 34 0 0 0 138 166 89 225 +21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 255 247 34 0 0 12 235 +166 12 235 166 0 0 0 0 0 12 232 89 0 175 166 138 166 0 0 0 0 0 0 12 232 +89 0 0 0 0 138 201 0 0 89 255 255 201 89 225 21 89 225 81 215 21 0 138 +247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 247 34 0 12 235 +125 59 192 0 0 0 0 59 241 89 0 0 0 0 0 175 255 255 255 255 166 0 0 0 7 +206 166 0 0 0 0 7 206 125 0 12 235 201 0 7 206 166 0 0 0 0 0 0 0 0 59 192 +0 12 235 166 0 7 176 21 0 175 125 0 0 0 0 0 0 0 0 0 138 251 89 138 247 +34 0 0 0 0 0 0 0 59 238 34 0 0 0 0 0 59 192 0 0 138 201 59 245 166 0 0 +175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 89 247 34 0 0 0 138 166 +89 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 166 +59 245 166 0 0 0 0 0 0 138 201 0 138 201 0 138 166 0 0 0 0 0 0 138 201 +0 0 0 0 89 247 34 0 0 0 0 0 7 206 125 59 238 34 59 215 21 0 175 225 21 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 247 34 0 0 175 225 81 +192 12 182 0 7 206 125 0 0 0 0 0 89 225 21 0 0 12 232 89 0 0 7 206 166 +0 0 0 0 7 206 125 0 0 59 245 255 255 166 0 0 0 0 0 0 0 0 0 7 202 89 0 59 +245 255 255 166 0 12 228 34 0 0 0 0 0 0 0 0 0 0 85 89 0 85 89 0 0 0 0 0 +0 0 59 238 34 0 0 0 0 0 7 202 89 0 138 201 0 59 245 225 34 228 34 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 255 255 255 255 255 247 34 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 201 0 0 175 247 34 0 0 0 138 166 +89 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 115 0 +59 115 0 0 0 0 0 0 12 232 89 0 175 255 255 255 255 201 0 0 0 0 12 232 89 +0 0 0 138 201 0 0 0 0 0 0 0 89 201 0 89 255 255 255 255 247 34 138 251 +89 0 7 176 21 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 247 34 0 0 0 +175 255 255 255 166 0 89 255 255 255 255 255 247 34 0 0 0 0 0 0 0 0 0 0 +7 206 166 0 0 0 0 7 206 125 0 0 0 0 0 138 255 166 0 0 0 0 0 0 0 0 0 89 +225 21 0 0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 59 238 34 0 0 0 0 0 0 89 225 21 0 0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 12 235 191 255 255 166 238 34 0 0 0 138 166 89 225 21 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 201 0 0 +0 0 0 138 166 0 0 0 0 0 175 201 0 0 0 89 255 255 255 255 125 0 0 0 12 232 +89 0 0 0 0 59 215 21 0 0 138 255 255 255 225 21 0 0 0 0 0 0 0 0 0 0 0 0 +0 127 0 0 0 0 0 0 0 0 0 0 0 0 59 192 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 7 206 125 0 0 0 0 0 0 175 201 0 0 0 0 0 0 0 0 0 0 +89 255 125 0 0 0 59 245 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 89 255 125 0 0 0 59 245 166 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 12 235 125 0 0 0 0 0 0 0 0 138 166 89 225 21 0 0 0 0 0 0 0 0 0 175 +125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 59 192 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 125 0 7 199 34 +0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 7 206 255 255 255 247 34 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 255 +255 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 0 138 166 +89 225 21 0 0 0 0 0 0 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 7 206 125 0 7 206 255 255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 0 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 138 225 +21 0 0 0 0 0 12 235 125 0 0 0 0 19 172 255 190 11 0 0 0 0 138 255 201 7 +202 89 0 0 0 0 0 0 0 0 0 0 7 206 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 59 138 225 21 0 0 0 0 0 0 59 245 201 0 0 0 19 172 +255 190 11 0 0 0 0 0 0 0 0 0 7 206 225 21 0 0 0 59 245 201 19 172 255 190 +11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 251 89 89 201 0 0 0 0 0 175 +201 0 0 0 0 0 0 0 0 7 206 225 21 0 0 0 0 0 19 172 255 190 11 0 0 0 0 0 +175 255 166 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 89 255 125 0 0 0 0 0 0 0 12 175 247 34 0 0 0 19 172 255 +190 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 247 34 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 127 0 0 0 7 206 125 0 0 0 0 0 138 201 0 0 0 0 0 136 190 +45 196 145 0 0 0 59 215 21 175 255 166 0 0 0 175 225 29 206 166 0 0 7 202 +89 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 209 125 +0 0 0 0 0 0 138 225 21 0 0 0 136 190 45 196 145 0 0 0 175 225 29 206 166 +0 0 12 235 125 0 0 12 138 225 21 136 190 45 196 145 159 251 89 138 247 +34 0 0 0 0 0 0 0 0 0 0 0 175 125 59 245 247 34 0 0 0 0 0 12 232 89 0 0 +0 0 0 0 0 175 166 0 0 0 0 0 0 12 136 190 45 196 145 0 0 0 0 138 166 12 +235 255 125 0 0 0 0 7 206 166 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 12 232 89 0 0 0 0 0 0 138 201 0 0 0 0 0 136 190 45 +196 145 34 0 0 0 89 251 89 138 247 34 0 0 0 0 0 138 201 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 202 89 7 202 89 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 +255 125 0 0 0 0 127 0 0 7 206 251 89 0 0 0 0 7 206 251 89 0 0 0 0 7 206 +251 89 0 0 0 0 0 7 206 251 89 0 0 0 0 7 206 251 89 0 0 0 0 12 235 255 125 +0 0 0 0 0 89 255 255 255 255 255 255 255 255 125 0 0 0 59 245 255 255 255 +201 12 235 255 255 255 255 255 125 12 235 255 255 255 255 255 125 12 235 +255 255 255 255 255 125 12 235 255 255 255 255 255 125 89 255 255 255 201 +89 255 255 255 201 89 255 255 255 201 89 255 255 255 201 0 175 255 255 +255 255 201 0 0 0 12 235 251 89 0 0 12 235 125 0 0 0 138 255 255 166 0 +0 0 0 0 0 138 255 255 166 0 0 0 0 0 0 138 255 255 166 0 0 0 0 0 0 138 255 +255 166 0 0 0 0 0 0 138 255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 +255 255 201 89 251 89 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 +125 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 125 7 206 225 21 +0 0 0 138 247 0 235 166 0 0 0 0 0 0 138 225 21 7 206 166 0 0 0 127 0 0 +59 245 255 166 0 0 0 0 59 245 255 166 0 0 0 0 59 245 255 166 0 0 0 0 0 +59 245 255 166 0 0 0 0 59 245 255 166 0 0 0 0 59 245 255 166 0 0 0 0 0 +175 201 7 206 166 0 0 0 0 0 0 0 138 255 125 0 0 7 202 102 235 166 0 0 0 +0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 0 12 +235 125 0 0 12 235 125 0 0 12 235 125 0 0 12 235 125 0 0 175 201 0 0 7 +206 251 89 0 12 235 255 201 0 0 12 235 125 0 59 245 166 0 0 138 251 89 +0 0 59 245 166 0 0 138 251 89 0 0 59 245 166 0 0 138 251 89 0 0 59 245 +166 0 0 138 251 89 0 0 59 245 166 0 0 138 251 89 0 0 0 0 0 0 0 0 0 0 0 +0 59 245 166 0 0 89 255 166 0 12 235 125 0 0 0 59 245 125 12 235 125 0 +0 0 59 245 125 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 125 +0 59 245 125 0 0 59 245 125 12 235 166 0 0 0 0 0 12 235 125 0 0 175 201 +0 0 0 127 0 0 138 225 151 225 21 0 0 0 138 225 151 225 21 0 0 0 138 225 +151 225 21 0 0 0 0 138 225 151 225 21 0 0 0 138 225 151 225 21 0 0 0 138 +225 151 225 21 0 0 0 59 241 89 7 206 166 0 0 0 0 0 0 12 235 166 0 0 0 0 +0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 +166 0 0 0 0 0 0 12 235 125 0 0 12 235 125 0 0 12 235 125 0 0 12 235 125 +0 0 175 201 0 0 0 0 175 225 21 12 235 166 245 125 0 12 235 125 12 235 125 +0 0 0 0 138 247 34 12 235 125 0 0 0 0 138 247 34 12 235 125 0 0 0 0 138 +247 34 12 235 125 0 0 0 0 138 247 34 12 235 125 0 0 0 0 138 247 34 0 138 +225 21 0 0 0 175 201 0 12 235 125 0 0 7 202 159 247 34 12 235 125 0 0 0 +59 245 125 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 125 12 235 +125 0 0 0 59 245 125 0 0 138 247 34 7 206 201 0 12 235 255 255 255 251 +89 0 12 235 125 0 12 235 125 0 0 0 127 0 7 206 166 59 241 89 0 0 7 206 +166 59 241 89 0 0 7 206 166 59 241 89 0 0 0 7 206 166 59 241 89 0 0 7 206 +166 59 241 89 0 0 7 206 166 59 241 89 0 0 0 138 225 21 7 206 166 0 0 0 +0 0 0 89 247 34 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 +235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 0 12 235 125 0 0 12 235 125 0 0 +12 235 125 0 0 12 235 125 0 0 175 201 0 0 0 0 59 241 89 12 235 125 138 +225 21 12 235 125 89 247 34 0 0 0 0 59 245 125 89 247 34 0 0 0 0 59 245 +125 89 247 34 0 0 0 0 59 245 125 89 247 34 0 0 0 0 59 245 125 89 247 34 +0 0 0 0 59 245 125 0 0 175 225 21 0 175 225 21 0 89 247 34 0 0 138 166 +12 235 125 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 125 12 235 +125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 125 0 0 12 235 166 89 247 +34 0 12 235 166 0 0 138 251 89 12 235 133 206 255 125 0 0 0 0 127 0 59 +241 89 7 206 166 0 0 59 241 89 7 206 166 0 0 59 241 89 7 206 166 0 0 0 +59 241 89 7 206 166 0 0 59 241 89 7 206 166 0 0 59 241 89 7 206 166 0 0 +12 235 125 0 7 206 255 255 255 255 247 34 0 138 225 21 0 0 0 0 0 12 235 +255 255 255 255 247 34 12 235 255 255 255 255 247 34 12 235 255 255 255 +255 247 34 12 235 255 255 255 255 247 34 0 12 235 125 0 0 12 235 125 0 +0 12 235 125 0 0 12 235 125 0 206 255 255 255 247 34 0 12 235 125 12 235 +125 12 235 125 12 235 125 138 225 21 0 0 0 0 12 235 166 138 225 21 0 0 +0 0 12 235 166 138 225 21 0 0 0 0 12 235 166 138 225 21 0 0 0 0 12 235 +166 138 225 21 0 0 0 0 12 235 166 0 0 0 175 225 187 225 21 0 0 138 225 +21 0 59 215 21 7 206 166 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 +245 125 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 125 0 0 0 89 +255 255 125 0 0 12 235 166 0 0 12 235 166 12 235 125 0 7 206 201 0 0 0 +127 0 138 225 21 0 138 225 21 0 138 225 21 0 138 225 21 0 138 225 21 0 +138 225 21 0 0 138 225 21 0 138 225 21 0 138 225 21 0 138 225 21 0 138 +225 21 0 138 225 21 0 89 255 255 255 255 255 166 0 0 0 0 0 0 138 225 21 +0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 +0 12 235 166 0 0 0 0 0 0 12 235 125 0 0 12 235 125 0 0 12 235 125 0 0 12 +235 125 0 0 175 201 0 0 0 0 12 235 125 12 235 125 0 138 225 34 235 125 +138 225 21 0 0 0 0 12 235 166 138 225 21 0 0 0 0 12 235 166 138 225 21 +0 0 0 0 12 235 166 138 225 21 0 0 0 0 12 235 166 138 225 21 0 0 0 0 12 +235 166 0 0 0 0 175 225 21 0 0 0 138 225 21 7 202 89 0 7 206 166 12 235 +125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 125 12 235 125 0 0 0 59 245 +125 12 235 125 0 0 0 59 245 125 0 0 0 7 206 225 21 0 0 12 235 166 0 0 12 +235 166 12 235 125 0 0 59 241 89 0 0 127 7 206 255 255 255 255 251 89 7 +206 255 255 255 255 251 89 7 206 255 255 255 255 251 89 0 7 206 255 255 +255 255 251 89 7 206 255 255 255 255 251 89 7 206 255 255 255 255 251 89 +7 206 166 0 0 7 206 166 0 0 0 0 0 0 89 247 34 0 0 0 0 0 12 235 166 0 0 +0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 0 +12 235 125 0 0 12 235 125 0 0 12 235 125 0 0 12 235 125 0 0 175 201 0 0 +0 0 59 241 89 12 235 125 0 12 235 138 235 125 89 247 34 0 0 0 0 59 245 +125 89 247 34 0 0 0 0 59 245 125 89 247 34 0 0 0 0 59 245 125 89 247 34 +0 0 0 0 59 245 125 89 247 34 0 0 0 0 59 245 125 0 0 0 175 225 187 225 21 +0 0 138 247 34 175 125 0 0 12 235 125 12 235 125 0 0 0 59 241 89 12 235 +125 0 0 0 59 241 89 12 235 125 0 0 0 59 241 89 12 235 125 0 0 0 59 241 +89 0 0 0 0 175 225 21 0 0 12 235 166 0 0 175 247 34 12 235 125 0 0 12 235 +125 0 0 127 59 241 89 0 0 7 206 166 59 241 89 0 0 7 206 166 59 241 89 0 +0 7 206 166 0 59 241 89 0 0 7 206 166 59 241 89 0 0 7 206 166 59 241 89 +0 0 7 206 166 59 241 89 0 0 7 206 166 0 0 0 0 0 0 59 245 166 0 0 0 0 0 +12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 166 +0 0 0 0 0 0 12 235 125 0 0 12 235 125 0 0 12 235 125 0 0 12 235 125 0 0 +175 201 0 0 0 0 175 225 21 12 235 125 0 0 138 232 245 125 12 235 125 0 +0 0 0 138 247 34 12 235 125 0 0 0 0 138 247 34 12 235 125 0 0 0 0 138 247 +34 12 235 125 0 0 0 0 138 247 34 12 235 125 0 0 0 0 138 247 34 0 0 175 +225 21 0 175 225 21 0 59 245 191 201 0 0 0 89 225 21 12 235 166 0 0 0 89 +251 89 12 235 166 0 0 0 89 251 89 12 235 166 0 0 0 89 251 89 12 235 166 +0 0 0 89 251 89 0 0 0 0 175 225 21 0 0 12 235 255 255 255 247 34 0 12 235 +125 0 0 59 241 89 0 0 127 138 225 21 0 0 0 138 247 163 225 21 0 0 0 138 +247 163 225 21 0 0 0 138 247 34 138 225 21 0 0 0 138 247 163 225 21 0 0 +0 138 247 163 225 21 0 0 0 138 247 198 225 21 0 0 7 206 166 0 0 0 0 0 0 +0 138 255 125 0 0 7 202 102 235 166 0 0 0 0 0 12 235 166 0 0 0 0 0 12 235 +166 0 0 0 0 0 12 235 166 0 0 0 0 0 0 12 235 125 0 0 12 235 125 0 0 12 235 +125 0 0 12 235 125 0 0 175 201 0 0 7 206 251 89 0 12 235 125 0 0 12 235 +255 125 0 89 255 125 0 0 89 251 89 0 0 89 255 125 0 0 89 251 89 0 0 89 +255 125 0 0 89 251 89 0 0 89 255 125 0 0 89 251 89 0 0 89 255 125 0 0 89 +251 89 0 0 138 225 21 0 0 0 175 201 0 0 138 251 89 0 0 89 251 89 0 0 138 +247 34 0 7 206 225 21 0 138 247 34 0 7 206 225 21 0 138 247 34 0 7 206 +225 21 0 138 247 34 0 7 206 225 21 0 0 0 0 175 225 21 0 0 12 235 166 0 +0 0 0 0 12 235 125 0 0 175 225 21 0 0 127 206 166 0 0 0 0 59 245 255 166 +0 0 0 0 59 245 255 166 0 0 0 0 59 245 133 206 166 0 0 0 0 59 245 255 166 +0 0 0 0 59 245 255 166 0 0 0 0 59 245 255 125 0 0 0 7 206 255 255 255 255 +255 125 0 0 0 59 245 255 255 255 201 12 235 255 255 255 255 255 125 12 +235 255 255 255 255 255 125 12 235 255 255 255 255 255 125 12 235 255 255 +255 255 255 125 89 255 255 255 201 89 255 255 255 201 89 255 255 255 201 +89 255 255 255 201 0 175 255 255 255 255 225 21 0 0 12 235 125 0 0 0 138 +255 125 0 0 0 175 255 255 201 0 0 0 0 0 0 175 255 255 201 0 0 0 0 0 0 175 +255 255 201 0 0 0 0 0 0 175 255 255 201 0 0 0 0 0 0 175 255 255 201 0 0 +0 0 0 0 0 0 0 0 0 0 0 7 202 97 206 255 255 201 0 0 0 0 0 138 255 255 255 +201 0 0 0 0 138 255 255 255 201 0 0 0 0 138 255 255 255 201 0 0 0 0 138 +255 255 255 201 0 0 0 0 0 0 175 225 21 0 0 12 235 166 0 0 0 0 0 12 235 +133 206 255 225 21 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 138 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 138 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 175 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 225 21 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 127 0 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 7 206 225 21 +0 0 0 0 0 12 235 225 21 0 0 89 255 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 7 206 255 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 247 +34 0 0 0 0 0 0 0 138 251 89 0 0 59 245 247 34 0 0 0 0 0 0 0 0 0 175 247 +34 0 0 175 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 225 21 +0 0 0 0 0 0 0 138 255 125 0 0 0 12 235 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 251 89 0 0 0 0 0 0 +7 206 225 21 0 0 0 7 206 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 166 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 59 241 89 0 0 0 0 +0 89 247 34 0 0 7 206 138 235 125 0 0 89 255 225 21 175 125 0 0 0 0 0 0 +0 0 0 138 201 0 138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 +235 125 0 0 0 0 0 0 12 235 125 0 0 0 175 171 206 166 0 0 0 0 0 0 0 0 0 +7 206 166 0 59 245 255 166 238 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 125 59 +215 21 0 0 59 241 89 0 0 0 0 0 0 7 206 166 0 0 0 0 138 201 175 201 0 0 +0 12 235 251 89 89 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 7 206 166 0 0 0 0 0 0 89 247 34 0 0 0 0 89 225 151 201 0 0 0 0 +0 0 0 0 0 0 0 0 0 175 201 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 138 201 0 0 0 0 7 206 125 0 0 0 138 201 0 89 225 21 +12 228 34 138 255 201 0 0 0 138 247 34 175 225 21 0 138 201 0 138 201 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 225 21 0 0 0 0 0 89 225 +21 0 0 89 247 34 59 241 89 0 59 241 89 89 247 34 0 0 89 225 21 175 127 +215 21 206 247 42 206 0 138 255 247 42 206 125 0 0 138 166 12 235 251 89 +0 0 0 0 138 201 0 0 0 0 0 0 89 225 21 0 0 0 59 241 89 12 235 125 0 0 175 +125 59 245 247 34 0 0 12 235 125 89 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 59 238 34 0 0 0 0 0 175 166 0 0 0 0 12 232 89 7 206 125 0 +0 12 235 166 59 245 125 0 0 0 59 238 34 0 12 235 125 0 0 0 0 0 0 89 247 +34 138 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 255 247 34 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 251 89 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 34 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 12 235 255 255 255 166 0 12 235 255 +255 255 166 0 12 235 255 255 255 166 0 12 235 255 255 255 166 0 0 12 235 +255 255 255 166 0 12 235 255 255 255 166 0 12 235 255 255 255 166 0 175 +255 255 125 0 0 12 235 255 255 125 0 0 12 235 255 255 225 21 0 0 12 235 +255 255 225 21 0 12 235 255 255 225 21 0 12 235 255 255 225 21 0 12 235 +125 12 235 125 12 235 125 12 235 125 0 12 235 125 89 251 89 0 12 235 138 +235 255 247 34 0 0 12 235 255 255 201 0 0 0 12 235 255 255 201 0 0 0 12 +235 255 255 201 0 0 0 12 235 255 255 201 0 0 0 12 235 255 255 201 0 0 0 +0 0 0 175 247 34 0 0 0 12 235 255 255 255 166 0 59 241 89 0 0 89 247 34 +59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 42 +206 201 0 0 0 138 232 245 166 245 255 251 89 7 206 201 0 0 0 138 225 21 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 127 12 206 21 0 59 245 125 12 206 21 0 59 245 125 12 206 +21 0 59 245 125 12 206 21 0 59 245 125 0 12 206 21 0 59 245 125 12 206 +21 0 59 245 125 12 206 21 0 12 235 255 125 0 7 206 166 12 235 166 0 0 172 +102 0 235 125 0 0 175 201 0 12 235 125 0 0 175 201 12 235 125 0 0 175 201 +12 235 125 0 0 175 201 0 12 235 125 12 235 125 12 235 125 12 235 125 0 +0 0 0 0 175 201 0 12 235 247 34 0 175 201 0 12 235 166 0 7 206 201 0 12 +235 166 0 7 206 201 0 12 235 166 0 7 206 201 0 12 235 166 0 7 206 201 0 +12 235 166 0 7 206 201 0 0 0 0 0 175 247 34 0 0 12 235 166 0 12 235 201 +0 59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 +34 59 241 89 0 0 89 247 34 89 247 34 0 7 206 176 235 225 21 0 175 225 21 +89 247 34 0 7 206 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 7 206 166 0 0 0 0 7 +206 166 0 0 0 0 7 206 166 0 0 0 0 7 206 166 0 0 0 0 0 7 206 166 0 0 0 0 +7 206 166 0 0 0 0 0 175 201 0 0 0 89 225 138 225 21 0 0 0 0 89 225 21 0 +0 89 247 34 89 225 21 0 0 89 247 124 225 21 0 0 89 247 124 225 21 0 0 89 +247 34 12 235 125 12 235 125 12 235 125 12 235 125 0 89 255 255 255 255 +247 34 12 235 125 0 0 89 247 34 138 225 21 0 0 59 238 34 138 225 21 0 0 +59 238 34 138 225 21 0 0 59 238 34 138 225 21 0 0 59 238 34 138 225 21 +0 0 59 238 34 0 0 0 0 0 0 0 0 0 138 225 21 0 172 132 238 34 59 241 89 0 +0 89 247 34 59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 59 241 89 0 +0 89 247 34 12 235 125 0 59 238 47 235 125 0 0 59 241 89 12 235 125 0 59 +238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 59 245 255 255 255 166 0 59 245 255 255 +255 166 0 59 245 255 255 255 166 0 59 245 255 255 255 166 0 0 59 245 255 +255 255 166 0 59 245 255 255 255 166 0 89 255 255 255 255 255 255 255 255 +255 247 175 201 0 0 0 0 0 175 255 255 255 255 255 247 34 175 255 255 255 +255 255 247 198 255 255 255 255 255 247 198 255 255 255 255 255 247 34 +12 235 125 12 235 125 12 235 125 12 235 125 89 251 89 0 0 59 241 89 12 +235 125 0 0 89 247 34 175 201 0 0 0 12 232 89 175 201 0 0 0 12 232 89 175 +201 0 0 0 12 232 89 175 201 0 0 0 12 232 89 175 201 0 0 0 12 232 89 7 206 +255 255 255 255 255 255 251 226 201 0 89 166 12 232 89 59 241 89 0 0 89 +247 34 59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 59 241 89 0 0 89 +247 34 0 175 201 0 138 201 12 235 125 0 0 12 235 125 0 175 201 0 138 201 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 89 255 166 0 7 206 166 89 255 166 0 7 206 166 89 +255 166 0 7 206 166 89 255 166 0 7 206 166 0 89 255 166 0 7 206 166 89 +255 166 0 7 206 166 138 255 125 0 0 175 201 0 0 0 0 0 175 201 0 0 0 0 0 +175 201 0 0 0 0 0 0 175 201 0 0 0 0 0 175 201 0 0 0 0 0 175 201 0 0 0 0 +0 0 12 235 125 12 235 125 12 235 125 12 235 125 175 201 0 0 0 59 241 89 +12 235 125 0 0 89 247 34 175 201 0 0 0 12 232 89 175 201 0 0 0 12 232 89 +175 201 0 0 0 12 232 89 175 201 0 0 0 12 232 89 175 201 0 0 0 12 232 89 +0 0 0 0 0 0 0 0 0 175 201 7 176 21 12 232 89 59 241 89 0 0 89 247 34 59 +241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 0 +89 247 47 235 125 12 235 125 0 0 12 235 125 0 89 247 47 235 125 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 127 175 201 0 0 7 206 166 175 201 0 0 7 206 166 175 201 0 0 +7 206 166 175 201 0 0 7 206 166 0 175 201 0 0 7 206 166 175 201 0 0 7 206 +166 175 201 0 0 0 138 225 21 0 0 0 0 138 225 21 0 0 0 0 138 247 34 0 0 +0 0 0 138 247 34 0 0 0 0 138 247 34 0 0 0 0 138 247 34 0 0 0 0 0 12 235 +125 12 235 125 12 235 125 12 235 125 175 201 0 0 0 89 247 34 12 235 125 +0 0 89 247 34 138 225 21 0 0 89 247 34 138 225 21 0 0 89 247 34 138 225 +21 0 0 89 247 34 138 225 21 0 0 89 247 34 138 225 21 0 0 89 247 34 0 0 +0 0 175 247 34 0 0 138 225 151 125 0 89 247 34 59 241 89 0 0 89 247 34 +59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 59 241 89 0 0 89 247 34 +0 12 235 191 247 34 12 235 125 0 0 59 241 89 0 12 235 191 247 34 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 127 138 225 21 0 138 255 166 138 225 21 0 138 255 166 138 +225 21 0 138 255 166 138 225 21 0 138 255 166 0 138 225 21 0 138 255 166 +138 225 21 0 138 255 166 89 247 34 0 89 255 255 166 0 0 12 206 12 235 166 +0 0 127 102 0 235 201 0 0 12 206 21 12 235 201 0 0 12 206 34 235 201 0 +0 12 206 34 235 201 0 0 12 206 21 12 235 125 12 235 125 12 235 125 12 235 +125 89 255 125 0 7 206 166 0 12 235 125 0 0 89 247 34 12 235 166 0 7 206 +201 0 12 235 166 0 7 206 201 0 12 235 166 0 7 206 201 0 12 235 166 0 7 +206 201 0 12 235 166 0 7 206 201 0 0 0 0 0 175 247 34 0 0 12 235 201 0 +7 206 201 0 7 206 166 0 59 245 247 34 7 206 166 0 59 245 247 34 7 206 166 +0 59 245 247 34 7 206 166 0 59 245 247 34 0 0 138 255 166 0 12 235 125 +0 7 206 201 0 0 0 138 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 7 206 255 255 171 +206 166 7 206 255 255 171 206 166 7 206 255 255 171 206 166 7 206 255 255 +171 206 166 0 7 206 255 255 171 206 166 7 206 255 255 171 206 166 0 89 +255 255 201 0 0 175 255 255 247 34 0 12 235 255 255 166 0 0 7 206 255 255 +247 34 0 0 7 206 255 255 247 34 0 7 206 255 255 247 34 0 7 206 255 255 +247 34 0 12 235 125 12 235 125 12 235 125 12 235 125 0 89 255 255 255 201 +0 0 12 235 125 0 0 89 247 34 0 12 235 255 255 201 0 0 0 12 235 255 255 +201 0 0 0 12 235 255 255 201 0 0 0 12 235 255 255 201 0 0 0 12 235 255 +255 201 0 0 0 0 0 0 0 0 0 0 0 7 206 255 255 255 201 0 0 0 59 245 255 225 +111 247 34 0 59 245 255 225 111 247 34 0 59 245 255 225 111 247 34 0 59 +245 255 225 111 247 34 0 0 59 241 89 0 12 235 255 255 255 225 21 0 0 0 +59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 138 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 225 21 0 12 235 125 0 0 0 0 0 0 0 +138 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 166 0 0 12 235 125 0 0 0 0 0 0 7 206 +166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +12 235 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 247 34 0 0 12 235 125 0 0 0 0 0 0 89 247 +34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 0 127 127 0 127 127 0 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/FontNormal.pgm b/Extras/CDTestFramework/AntTweakBar/src/res/FontNormal.pgm new file mode 100644 index 0000000..f05e831 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/res/FontNormal.pgm @@ -0,0 +1,895 @@ +P2 +# Created by Paint Shop Pro +253 106 +255 +127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 255 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 +0 255 0 255 0 0 0 0 0 255 0 0 0 0 255 255 0 0 0 0 255 0 0 0 0 0 255 255 +255 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 0 255 0 255 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 255 255 255 0 0 0 0 0 +255 0 0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 0 0 0 255 0 0 255 +255 255 255 255 255 0 0 0 255 255 255 0 0 255 255 255 255 255 255 0 0 255 +255 255 255 0 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 127 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 255 255 +255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 +0 0 0 0 255 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 255 255 255 0 0 0 255 0 0 0 0 255 0 +255 0 0 0 0 255 0 0 0 0 255 255 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 +0 0 255 0 255 0 255 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 255 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 255 0 0 255 0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 255 0 0 0 0 0 0 255 0 0 0 0 +0 0 0 0 0 0 255 0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 0 255 +0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 255 +0 0 0 0 255 0 255 0 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 255 0 255 0 0 0 +0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 +0 255 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 255 255 255 255 0 0 255 255 +255 255 255 0 0 0 0 0 0 255 0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 +0 0 0 255 0 0 0 0 0 0 255 255 0 0 0 0 255 255 255 255 255 255 0 0 0 0 255 +255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 255 0 0 +0 0 0 0 0 0 0 0 255 0 255 0 0 0 0 0 255 255 0 0 0 0 255 255 0 0 255 0 0 +255 255 0 0 0 255 255 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 +255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 255 255 0 0 255 0 0 0 255 +0 0 0 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 255 255 255 +0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 255 255 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 255 255 0 +0 0 0 0 0 0 255 0 255 0 0 255 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 +0 0 0 255 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 0 0 0 0 0 255 255 +255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 255 +0 0 0 0 0 0 0 0 255 0 255 255 255 255 255 255 0 0 0 0 0 0 255 0 255 0 0 +0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 255 255 255 255 255 0 0 0 +0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 0 +0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 255 0 0 0 0 +0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 255 0 0 255 +0 255 0 0 0 255 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 +0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 255 +0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 +0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 +0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 255 0 255 0 0 0 0 0 255 0 255 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 255 +0 0 0 255 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 +0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 0 +255 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 +255 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 +0 0 255 0 0 0 255 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 255 0 0 0 0 0 +0 0 0 0 255 0 255 0 0 0 0 0 0 255 255 255 0 0 0 0 0 255 0 0 0 0 255 255 +0 0 0 255 255 255 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 +0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 255 255 +255 0 0 0 255 255 255 255 255 0 255 255 255 255 255 255 0 0 255 255 255 +255 0 0 0 0 0 0 255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 255 +0 0 0 0 0 0 255 255 255 255 0 0 0 255 255 255 0 0 0 0 255 0 0 0 255 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 0 +127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 0 127 127 127 0 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 0 127 127 127 +127 0 127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 255 0 0 0 0 0 255 255 255 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 255 +255 255 255 0 0 0 0 0 0 0 255 0 0 0 0 255 255 255 255 255 0 0 0 0 255 255 +255 255 0 255 255 255 255 255 0 0 0 255 255 255 255 255 255 0 255 255 255 +255 255 0 0 0 255 255 255 255 0 0 255 0 0 0 0 0 255 0 255 255 255 0 0 255 +255 255 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 255 0 0 0 0 255 255 0 255 +255 0 0 0 0 255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 255 0 0 0 0 +255 255 255 255 0 0 0 255 255 255 255 0 0 0 0 255 255 255 255 0 0 255 255 +255 255 255 255 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 +0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 255 255 255 +255 255 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 255 255 0 0 0 0 255 255 0 0 +0 0 255 0 255 0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 +0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 0 +0 255 0 0 0 0 0 255 0 255 0 0 0 255 0 0 255 0 0 0 0 0 255 255 0 0 0 0 255 +255 0 255 255 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 255 +0 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 255 0 0 255 +0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 +0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 127 0 255 0 255 255 255 255 0 255 0 0 0 0 255 0 255 0 0 0 255 0 0 +0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 +0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 255 0 0 +255 0 0 0 255 0 0 0 0 0 255 0 255 0 0 255 0 255 0 255 0 255 0 0 0 255 0 +255 0 0 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 +255 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 +0 255 0 0 0 255 0 0 255 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 0 +255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 255 0 0 +0 255 0 0 255 0 0 0 255 0 255 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 +0 0 0 255 0 0 255 0 0 0 0 0 255 0 255 0 255 0 0 0 0 255 0 0 0 0 0 255 0 +255 0 0 255 0 255 0 255 0 255 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 +0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 +255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 255 0 0 0 255 0 0 255 0 255 +0 0 255 0 0 0 0 255 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 255 +0 0 0 0 255 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 255 0 0 0 255 0 0 255 0 0 255 0 0 0 255 +0 0 255 255 255 255 255 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 255 255 +255 255 255 255 0 255 255 255 255 255 0 255 0 0 0 255 255 255 0 255 255 +255 255 255 255 255 0 0 255 0 0 0 0 0 255 0 255 255 0 0 0 0 0 255 0 0 0 +0 0 255 0 255 0 0 255 0 255 0 255 0 0 255 0 0 255 0 255 0 0 0 0 0 0 255 +0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 255 255 255 0 0 0 0 255 255 +255 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 255 0 0 0 +255 0 0 255 0 255 0 0 255 0 0 0 0 255 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 +0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 255 0 0 0 255 0 0 255 0 0 255 +0 0 0 255 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 255 +0 0 0 0 0 255 0 255 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 255 0 0 255 +0 255 0 0 0 255 0 255 0 255 0 0 0 0 0 0 255 0 255 255 255 255 255 0 0 255 +0 0 0 0 0 0 255 0 255 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 +0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 0 +255 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 +0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 127 255 0 255 0 0 0 255 0 0 255 0 0 255 255 255 255 255 0 0 255 0 0 0 +0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 +0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 255 0 0 +255 0 0 0 255 0 0 0 0 0 255 0 0 255 255 0 0 255 0 255 0 0 0 255 0 255 0 +255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 255 0 0 0 255 +0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 0 255 0 255 +0 0 0 0 0 255 255 0 0 0 255 255 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 +0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 255 0 255 255 255 255 +255 255 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 +0 0 0 255 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 +0 0 0 255 0 0 255 0 0 0 0 0 255 0 255 0 0 0 255 0 0 255 0 0 0 0 0 255 0 +0 0 0 0 0 255 0 255 0 0 0 0 255 255 0 0 255 0 0 0 0 255 0 0 255 0 0 0 0 +0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 255 +0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 +0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 +255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 255 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 255 255 255 +255 255 0 0 0 0 255 255 255 255 0 255 255 255 255 255 0 0 0 255 255 255 +255 255 255 0 255 0 0 0 0 0 0 0 255 255 255 255 255 0 255 0 0 0 0 0 255 +0 255 255 255 0 255 255 255 0 0 255 0 0 0 0 255 0 255 255 255 255 255 0 +255 0 0 0 0 0 0 255 0 255 0 0 0 0 255 255 0 0 0 255 255 255 255 0 0 0 255 +0 0 0 0 0 0 0 0 255 255 255 255 0 0 0 255 0 0 0 0 255 0 0 255 255 255 255 +0 0 0 0 0 255 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 +0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 255 255 255 255 +255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 255 255 255 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 0 255 0 0 +255 255 255 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +0 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 +0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 255 +0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 +0 0 0 255 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 255 255 255 0 0 255 0 255 255 +255 0 0 0 255 255 255 255 0 0 255 255 255 255 255 0 0 255 255 255 255 0 +0 255 255 255 255 0 255 255 255 255 255 0 255 0 255 255 255 0 0 255 0 255 +255 0 255 0 0 0 255 0 255 0 255 255 255 255 0 255 255 255 0 0 255 0 255 +255 255 0 0 0 255 255 255 255 0 0 255 0 255 255 255 0 0 0 255 255 255 255 +255 0 255 0 255 0 0 255 255 255 0 255 255 255 255 0 255 0 0 0 0 255 0 255 +0 0 0 255 0 255 0 0 0 255 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 255 +255 255 255 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +0 0 0 0 0 0 255 0 255 255 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 255 0 255 +0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 255 0 255 255 0 0 0 255 0 255 0 0 255 +0 255 0 0 255 0 0 255 0 255 0 0 0 255 0 0 0 255 0 255 255 0 0 0 255 0 255 +0 0 0 0 255 0 255 255 0 0 0 255 0 255 0 0 0 0 255 0 255 255 0 0 255 0 0 +0 0 0 255 0 0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 0 0 255 +0 0 255 0 255 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 0 255 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 255 +0 255 0 0 0 0 255 0 255 0 0 255 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 +0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 +0 0 255 0 255 0 0 0 255 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 255 0 255 +0 0 0 255 0 255 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 0 255 +0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 255 0 0 0 255 0 0 0 +255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 +0 255 255 255 255 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 255 0 255 +255 255 255 255 255 0 0 255 0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 +0 0 255 0 255 255 0 0 0 0 255 0 255 0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 +0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 +255 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 255 0 255 0 0 0 255 0 255 0 255 +0 255 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 0 0 255 255 0 0 0 0 0 0 +255 0 0 0 0 0 255 255 0 0 255 0 0 255 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 255 0 0 0 255 0 255 0 +0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 0 255 0 0 255 +0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 255 0 255 0 255 0 0 0 255 0 255 +0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 +0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 255 0 0 0 255 0 0 0 0 255 0 +0 255 0 255 0 0 0 255 0 255 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 255 +0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 255 +255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 255 +255 0 255 0 0 0 0 255 0 0 255 0 0 255 0 0 0 255 255 0 255 0 0 0 0 255 0 +255 0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 0 255 0 0 0 255 0 255 0 0 0 +0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 255 255 0 255 0 0 +0 0 0 0 255 0 0 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 0 0 255 0 0 +0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 +255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 255 255 255 255 0 255 255 +255 255 255 0 0 0 255 255 255 255 0 0 255 255 255 0 255 0 0 255 255 255 +255 0 0 0 255 0 0 0 255 255 255 0 255 0 255 0 0 0 0 255 0 255 0 0 255 0 +255 0 0 0 255 0 255 0 255 0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 0 0 255 +255 255 255 0 0 255 255 255 255 255 0 0 0 255 255 255 0 255 0 255 0 0 0 +255 255 255 0 0 0 0 255 255 0 0 255 255 255 0 255 0 0 0 255 0 0 0 0 0 255 +0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 255 255 255 0 0 0 255 +0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 +255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 +255 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 0 127 127 127 127 127 0 +127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 0 127 127 0 127 127 127 127 127 0 127 0 127 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +0 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 0 127 127 +127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 255 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 +0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 255 0 255 +0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 127 0 0 255 +255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 255 +255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 +255 0 0 255 0 0 0 255 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 255 255 255 +0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 0 0 0 255 255 255 +255 255 255 255 255 255 0 255 255 255 255 255 255 0 0 0 255 255 255 255 +255 255 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 0 255 0 0 +0 255 0 255 0 255 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 255 0 255 255 0 0 0 255 255 255 0 255 0 0 0 255 0 0 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 +255 0 0 255 255 0 0 255 0 0 0 0 0 255 0 127 0 255 0 0 0 0 0 0 0 255 0 0 +0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +255 255 255 255 0 0 255 255 255 255 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0 +255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 +0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 255 0 255 0 0 0 255 0 255 0 255 0 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +255 0 0 255 255 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 127 255 0 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 +0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 0 0 255 +0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 +0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 +0 255 0 255 0 0 255 255 255 0 0 255 0 0 0 0 255 255 255 255 0 255 255 255 +0 0 0 0 255 0 0 0 0 0 0 0 255 0 255 255 255 255 0 0 255 0 0 0 255 0 0 127 +255 255 255 255 255 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 +0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 0 +0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 255 0 0 +0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 255 0 255 +0 0 0 127 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 255 +255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 255 255 0 0 255 0 0 255 255 0 0 0 255 255 0 0 0 255 255 +255 255 0 0 0 255 0 0 0 255 0 0 0 0 0 255 255 255 255 255 0 0 0 255 0 0 +0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 +0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 +0 0 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 +0 0 0 255 0 0 0 0 0 255 0 0 0 0 127 255 255 255 255 255 255 0 0 0 255 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 255 0 0 0 0 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 +0 0 255 0 255 0 0 255 0 0 0 0 0 0 255 0 0 255 0 0 0 255 0 0 0 0 0 255 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 +0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +255 255 255 0 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 255 +0 255 0 0 0 0 255 255 255 255 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 255 0 +0 0 0 0 0 255 0 0 0 0 127 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 255 0 0 255 0 0 0 +0 0 0 255 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 +0 255 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 +0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 +0 0 255 0 0 0 0 127 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 255 0 +0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 255 0 0 255 0 255 +0 0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 +0 0 255 0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 +0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 255 0 0 0 0 0 +0 0 255 0 0 0 0 127 0 0 255 255 255 255 0 0 0 255 255 255 255 255 255 255 +255 255 0 0 255 0 0 0 255 0 0 0 0 0 255 0 255 0 0 255 0 0 255 0 0 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 255 0 +0 0 255 255 0 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 255 255 255 255 255 +255 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 0 255 255 255 +255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 0 0 0 255 255 255 +255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +255 255 0 0 0 0 0 0 0 0 255 255 255 255 0 255 255 255 255 0 0 0 255 255 +255 255 255 255 255 255 255 0 255 255 255 255 0 0 0 0 255 0 0 0 0 127 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 127 127 0 127 127 0 127 127 127 127 127 127 0 127 127 127 127 0 127 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 0 +127 127 0 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 +0 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 0 127 127 +127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 255 0 0 0 +0 0 255 0 0 0 0 0 255 255 255 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 +255 0 0 0 0 255 255 255 255 0 0 255 0 0 255 0 0 0 0 0 255 255 255 255 0 +0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 255 +255 255 0 0 0 255 255 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 255 255 +255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 255 +255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 +0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 +0 0 0 0 255 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 255 255 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 255 +0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 +255 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 255 0 0 0 255 0 0 +0 0 0 0 0 0 0 255 255 0 0 0 255 0 0 0 0 0 0 255 255 0 0 0 0 255 0 0 0 0 +0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 127 0 0 0 0 0 255 0 0 0 0 255 255 255 255 0 0 255 0 0 0 0 +0 255 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 +0 0 0 0 0 255 0 0 255 255 0 0 255 0 0 0 0 255 255 255 0 0 0 255 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 255 255 0 0 255 0 0 0 0 0 0 0 0 +0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 255 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 255 0 255 255 255 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 255 0 0 255 0 0 0 255 0 255 0 0 255 0 0 0 0 0 255 0 0 0 255 0 0 0 +0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 255 0 0 0 255 0 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 255 0 0 +0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 255 255 255 255 0 0 0 0 255 0 255 0 +0 0 0 255 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 +0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 +0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 255 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 255 255 255 255 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 255 0 0 +0 0 255 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 255 +0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 255 0 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 +0 0 0 255 0 0 255 0 0 255 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 +255 255 255 0 0 255 255 255 255 0 0 255 255 255 0 0 0 0 0 0 0 0 0 255 0 +0 0 0 255 0 0 255 255 255 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 255 255 +0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 255 255 0 0 0 0 +255 0 0 255 0 255 255 255 0 0 0 0 0 0 255 0 255 0 0 255 255 0 0 0 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 255 0 0 +0 255 0 255 0 0 0 255 255 255 255 255 0 0 0 255 0 0 255 0 0 0 255 255 255 +255 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 +0 255 0 0 0 255 255 255 0 255 0 0 255 0 0 0 0 255 255 255 255 255 255 255 +0 255 255 255 0 255 0 0 255 255 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 +0 0 0 0 255 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 +0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 255 0 0 0 0 +255 0 0 255 255 255 0 255 0 0 255 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 +255 0 0 0 0 0 0 255 255 255 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 +0 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 255 +0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 +0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 255 0 0 0 255 0 255 +0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 +0 255 255 0 0 0 0 0 0 0 0 0 0 255 0 0 255 255 0 0 255 0 0 0 0 0 0 0 0 0 +0 255 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 255 0 0 0 255 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 255 0 0 0 0 255 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 255 0 0 255 +255 255 255 255 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 255 0 0 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 255 0 0 0 0 255 255 255 255 0 255 255 255 255 255 255 0 0 0 0 +0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 +255 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 +0 0 0 0 255 255 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 0 255 0 0 0 +0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 255 255 255 255 0 0 0 0 255 +0 0 0 0 0 0 255 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 255 +255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 255 255 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 255 0 255 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +127 127 0 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 0 +127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 0 127 127 127 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 127 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 255 +0 0 0 0 0 255 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 255 255 0 +0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 255 255 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 +255 0 0 0 0 0 0 0 255 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 255 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 255 0 0 0 +255 0 255 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 255 0 +0 0 255 0 0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 255 255 0 255 0 0 0 0 0 +0 0 0 0 0 255 0 255 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 +0 255 0 0 255 0 0 0 0 0 255 0 255 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 +0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 255 0 0 0 0 0 0 0 255 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 +0 0 0 0 0 0 255 255 255 255 255 255 255 0 0 0 255 255 255 255 0 255 255 +255 255 255 255 0 255 255 255 255 255 255 0 255 255 255 255 255 255 0 255 +255 255 255 255 255 0 255 255 255 0 255 255 255 0 255 255 255 0 255 255 +255 0 0 255 255 255 255 0 0 0 255 255 0 0 0 0 255 0 0 0 255 255 255 255 +0 0 0 0 0 255 255 255 255 0 0 0 0 0 255 255 255 255 0 0 0 0 0 255 255 255 +255 0 0 0 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 +0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 127 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 +255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 +0 0 0 255 0 0 255 255 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 +255 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 255 0 0 0 +0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 255 0 0 0 255 0 0 255 +0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 127 0 0 255 0 255 0 0 0 +0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 +0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 +255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 255 0 255 0 255 0 0 0 255 0 255 +0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 +0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 255 +0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 +0 0 255 0 0 255 0 0 0 255 0 0 255 255 255 255 255 0 0 255 0 0 0 255 0 0 +0 0 0 0 0 0 0 0 0 127 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 +255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 +0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 +255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 +0 255 0 0 0 0 255 0 255 0 255 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 +0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 +0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 255 0 0 0 0 0 255 +0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 255 0 +255 0 0 0 255 0 0 0 0 255 0 255 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 +0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 255 255 255 255 +255 0 255 0 0 0 0 0 0 255 255 255 255 255 255 0 255 255 255 255 255 255 +0 255 255 255 255 255 255 0 255 255 255 255 255 255 0 0 255 0 0 0 255 0 +0 0 255 0 0 0 255 0 0 255 255 255 255 0 0 255 0 255 0 0 255 0 0 255 0 255 +0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 +0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 0 255 0 0 +0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 127 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 +255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 +255 255 255 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 +0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 +0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 255 0 255 0 0 0 0 0 0 255 0 255 0 +0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 +0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 255 0 255 0 0 0 0 0 255 +0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 255 +0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 127 0 255 +255 255 255 255 0 0 0 255 255 255 255 255 0 0 0 255 255 255 255 255 0 0 +0 255 255 255 255 255 0 0 0 255 255 255 255 255 0 0 0 255 255 255 255 255 +0 0 0 255 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 +0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 +0 0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 255 0 255 0 0 0 0 0 0 255 0 255 +0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 255 0 0 0 +0 0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 0 +255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 +255 0 0 0 0 255 255 255 255 255 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 +127 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 +0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 255 0 0 0 255 0 0 +0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 +0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 +255 0 0 0 0 255 255 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 +0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 +0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 +0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 +0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 127 255 0 0 0 0 0 255 0 255 0 0 0 +0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 255 255 255 255 255 0 0 0 255 255 255 255 0 +255 255 255 255 255 255 0 255 255 255 255 255 255 0 255 255 255 255 255 +255 0 255 255 255 255 255 255 0 255 255 255 0 255 255 255 0 255 255 255 +0 255 255 255 0 0 255 255 255 255 0 0 0 255 0 0 0 0 255 255 0 0 0 255 255 +255 255 0 0 0 0 0 255 255 255 255 0 0 0 0 0 255 255 255 255 0 0 0 0 0 255 +255 255 255 0 0 0 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 +255 255 255 0 0 0 0 0 255 255 255 0 0 0 0 0 255 255 255 0 0 0 0 0 255 255 +255 0 0 0 0 0 255 255 255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 +255 255 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 0 127 127 127 0 127 127 +127 0 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 255 0 0 0 0 0 0 255 0 0 +0 0 255 255 0 0 0 255 255 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 255 255 0 0 +0 0 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 +255 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 255 0 0 0 0 0 255 255 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 255 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 255 0 0 0 0 255 0 0 0 0 255 +0 0 255 0 255 0 255 255 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 +0 255 0 0 255 0 0 0 255 0 255 0 255 0 255 255 0 255 0 0 255 0 255 0 0 0 +255 0 255 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 255 +0 255 255 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +255 0 0 0 0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 0 255 0 +0 0 255 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +127 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 +0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 0 0 255 255 0 0 0 +0 255 255 255 255 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 255 255 +255 255 0 0 0 255 255 255 255 0 0 0 255 0 255 0 0 255 0 0 255 0 0 255 255 +0 255 0 0 255 0 255 255 255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 +0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 +0 0 0 255 0 0 0 0 0 0 255 255 255 255 0 0 255 0 0 0 0 255 0 255 0 0 0 0 +255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 255 0 255 0 255 255 +255 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 255 0 0 0 0 0 +255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 +255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 +0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 255 0 0 255 0 0 255 0 0 0 0 0 0 255 +0 255 255 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 +0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 255 +0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 +0 255 0 0 0 255 0 255 255 0 0 0 255 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 127 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 +255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 +255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 255 +0 0 255 0 0 255 0 0 255 255 255 255 255 0 255 0 0 0 0 255 0 255 0 0 0 0 +255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 +255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 255 0 255 0 0 0 0 255 0 255 0 0 +0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 255 0 0 255 0 0 0 +0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 255 255 255 255 0 0 +255 255 255 255 0 0 255 255 255 255 0 0 255 255 255 255 0 0 255 255 255 +255 0 0 255 255 255 255 0 0 255 255 255 255 255 255 255 255 255 0 255 0 +0 0 0 0 255 255 255 255 255 255 0 255 255 255 255 255 255 0 255 255 255 +255 255 255 0 255 255 255 255 255 255 0 0 255 0 255 0 0 255 0 0 255 0 255 +0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 +0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 255 255 255 255 +255 255 0 255 0 0 255 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 +0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 255 0 0 255 0 0 0 0 255 0 0 255 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 0 0 255 0 255 0 0 0 255 0 255 +0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 +0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 +0 255 0 0 0 0 0 0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 0 0 255 0 255 0 +0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 +0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 255 0 255 +0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 +0 255 0 0 255 0 0 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 +0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 +0 255 0 0 0 255 0 255 0 0 0 255 255 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 +0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 255 +0 0 255 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 +255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 +0 0 0 0 255 0 0 0 0 0 255 0 0 0 255 0 0 255 0 0 0 255 255 0 255 0 0 0 255 +255 0 255 0 0 0 255 255 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 0 0 0 0 +255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 255 255 255 255 0 0 255 +255 255 255 0 0 255 255 255 255 0 0 255 255 255 255 0 0 255 255 255 255 +0 0 255 255 255 255 0 0 255 255 255 0 0 255 255 255 0 0 0 255 255 255 255 +0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 255 +255 255 255 0 0 0 255 0 255 0 0 255 0 0 255 0 0 255 255 255 255 0 0 255 +0 0 0 0 255 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 255 255 255 +255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 0 0 0 255 0 0 0 0 +0 255 255 255 255 0 0 0 0 255 255 255 0 255 0 0 255 255 255 0 255 0 0 255 +255 255 0 255 0 0 255 255 255 0 255 0 0 0 255 0 0 0 255 255 255 255 255 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 +0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 0 127 0 127 127 0 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/FontNormalAA.pgm b/Extras/CDTestFramework/AntTweakBar/src/res/FontNormalAA.pgm new file mode 100644 index 0000000..bbf0a0f --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/res/FontNormalAA.pgm @@ -0,0 +1,1012 @@ +P2 +# Created by Paint Shop Pro +264 106 +255 +127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 +0 0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 +59 241 97 206 166 0 0 0 0 0 0 0 0 0 0 0 0 0 168 34 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 251 89 0 0 89 255 125 89 255 125 0 0 0 0 +7 199 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 +0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 59 238 42 +206 125 0 0 0 0 7 199 34 89 166 0 0 0 0 168 34 0 0 0 175 255 255 166 0 +0 7 202 89 0 0 0 0 59 245 255 251 89 0 0 0 59 238 34 0 12 232 89 0 0 89 +247 34 0 59 245 206 199 124 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 7 202 89 0 12 235 255 247 34 0 0 0 0 12 232 89 0 0 12 235 +255 255 251 89 0 7 206 255 255 255 125 0 0 0 0 138 251 89 0 0 59 245 255 +255 255 251 89 0 0 89 255 255 166 0 89 255 255 255 255 255 201 0 0 59 245 +255 255 125 0 0 12 235 255 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 255 255 247 34 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 +0 0 0 0 0 127 0 0 0 0 0 138 225 21 59 238 34 175 125 0 0 0 0 59 192 0 172 +89 0 0 59 245 255 255 251 89 89 247 34 12 228 34 0 138 166 0 0 0 0 12 235 +125 0 175 225 21 0 0 59 238 34 0 138 201 0 0 0 0 175 166 0 0 0 89 255 201 +0 0 0 0 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 215 21 0 175 +166 0 138 201 0 0 7 206 255 251 89 0 0 59 192 0 0 138 247 34 59 192 0 0 +89 251 89 0 0 59 245 251 89 0 0 59 241 89 0 0 0 0 0 89 247 34 0 0 0 0 0 +0 0 7 206 166 0 7 206 125 0 89 247 34 7 206 166 0 138 225 21 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 12 232 89 0 0 0 0 0 0 0 0 0 0 0 175 166 0 0 0 0 0 +0 0 89 125 0 0 175 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 +0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 12 206 +21 175 125 0 0 89 255 255 255 255 255 255 166 59 241 89 168 34 138 125 +89 225 21 7 202 89 12 228 34 0 0 0 0 12 232 89 0 138 201 0 0 0 12 206 21 +7 202 89 0 0 0 0 59 215 21 59 245 206 199 124 255 125 0 0 0 0 7 202 89 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 0 12 232 89 0 59 238 34 0 0 +0 59 241 89 0 0 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 12 232 132 241 89 +0 0 59 241 89 0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 89 247 34 0 12 232 89 0 +12 232 89 59 241 89 0 59 241 89 0 138 247 34 0 0 138 247 34 0 0 0 0 0 12 +235 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 138 255 166 0 0 0 0 0 0 0 0 0 138 +225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 +0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 172 +89 59 192 0 0 59 238 34 168 34 0 0 89 247 34 12 228 34 138 166 0 0 0 0 +0 0 138 251 159 247 34 0 0 0 0 0 0 59 238 34 0 0 0 0 7 202 89 0 0 7 199 +34 0 0 0 0 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 59 +241 89 0 59 241 89 0 0 0 59 241 89 0 0 0 0 0 0 89 247 34 0 0 0 0 138 201 +0 7 206 125 59 241 89 0 0 59 245 255 255 251 89 0 12 235 255 255 255 125 +0 0 0 0 7 206 166 0 0 0 175 251 89 138 201 0 59 241 89 0 12 235 125 0 138 +247 34 0 0 138 247 34 0 0 0 59 245 247 34 0 0 0 0 7 206 255 255 255 255 +255 255 125 0 0 0 0 138 255 201 0 0 0 0 0 0 89 251 89 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 +127 0 0 0 0 0 138 201 0 0 0 0 0 0 0 0 0 12 206 21 138 125 0 0 7 206 255 +247 34 0 0 0 175 255 255 166 59 215 21 175 255 255 125 0 0 138 171 206 +166 0 175 201 0 0 0 0 89 201 0 0 0 0 0 0 175 125 0 0 0 0 0 0 0 0 12 235 +255 255 255 255 255 255 125 0 0 0 0 138 255 255 251 89 0 0 0 0 0 59 215 +21 0 59 241 89 0 59 241 89 0 0 0 59 241 89 0 0 0 0 0 12 235 166 0 0 0 138 +255 255 125 0 175 201 0 59 241 89 0 0 0 0 0 0 175 247 34 59 241 89 0 89 +247 34 0 0 0 89 247 34 0 0 0 89 255 255 255 125 0 12 235 166 0 59 245 125 +0 0 0 0 0 0 0 0 0 0 0 175 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 89 251 89 0 0 7 206 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 201 +0 0 0 0 0 0 0 12 235 255 255 255 255 255 225 21 0 0 0 175 255 251 89 0 +0 0 0 0 175 125 89 225 21 59 238 34 89 225 21 12 235 166 175 166 0 0 0 +0 89 201 0 0 0 0 0 0 175 125 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 138 166 0 0 59 241 89 0 59 241 89 0 0 0 59 241 89 +0 0 0 0 12 235 166 0 0 0 0 0 0 59 241 97 206 255 255 255 255 255 125 0 +0 0 0 0 59 241 89 59 238 34 0 12 235 125 0 0 12 235 125 0 0 0 12 232 89 +0 59 245 125 0 89 255 255 232 241 89 0 0 0 0 0 0 0 0 0 0 0 0 59 245 247 +34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 255 201 0 0 0 0 7 206 125 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 4 +4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 125 12 206 21 +0 0 0 0 0 168 34 175 166 0 0 0 0 59 215 21 138 201 0 12 228 34 138 225 +21 0 12 235 251 89 0 0 0 0 59 215 21 0 0 0 0 12 232 89 0 0 0 0 0 0 0 0 +0 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 12 232 89 0 +59 238 34 0 0 0 59 241 89 0 0 0 12 235 166 0 0 0 0 0 0 0 12 235 125 0 0 +0 59 241 89 0 0 0 0 0 0 59 241 89 12 232 89 0 12 232 89 0 0 138 225 21 +0 0 0 59 238 34 0 7 206 166 0 0 0 0 89 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 12 235 247 34 0 0 7 206 255 255 255 255 255 255 125 0 0 138 255 166 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 +0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 0 0 0 0 +0 0 0 0 172 89 89 166 0 0 0 89 166 0 168 42 206 125 0 0 0 7 202 89 0 89 +225 21 59 238 34 89 251 89 0 0 175 255 201 0 0 0 0 7 202 89 0 0 0 0 59 +215 21 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 0 0 138 247 34 0 0 0 0 0 7 206 +201 0 12 228 34 0 0 0 175 166 0 138 201 0 0 0 0 59 241 89 0 0 12 235 166 +0 0 0 0 89 166 0 0 89 251 89 0 0 0 59 241 89 0 0 59 192 0 0 175 225 21 +0 175 201 0 138 225 21 0 12 235 125 0 0 0 0 12 235 166 0 59 241 89 0 0 +0 7 206 166 0 0 138 247 34 0 0 59 245 125 0 0 0 0 0 0 0 12 232 89 0 0 0 +0 0 0 0 0 0 0 0 175 166 0 0 0 0 0 0 0 0 7 206 166 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 +127 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 12 206 21 138 125 0 0 0 12 235 255 +255 255 166 0 0 0 0 138 201 0 0 0 175 255 255 125 0 0 138 255 255 255 125 +12 235 247 0 0 0 0 138 201 0 0 0 0 175 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 7 206 166 0 0 0 0 0 0 7 206 201 0 89 201 0 0 0 0 12 235 255 247 +34 0 0 7 206 255 255 255 225 21 89 255 255 255 255 255 166 59 245 255 255 +251 89 0 0 0 0 59 241 89 0 0 12 235 255 255 225 21 0 0 12 235 255 251 89 +0 0 175 225 21 0 0 0 0 0 59 245 255 255 125 0 0 89 255 255 166 0 0 0 138 +247 34 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 7 206 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 +0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 168 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 12 232 89 0 0 59 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 125 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +4 4 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 168 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 +255 125 89 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 201 0 0 0 0 +0 0 0 0 0 0 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 228 34 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 0 0 0 0 0 0 0 0 +127 127 127 127 0 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 0 127 127 127 127 +0 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 0 127 127 127 0 127 127 127 127 0 127 127 127 0 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 0 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 255 125 138 166 0 0 0 89 255 255 247 +34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 89 255 255 +255 255 166 0 0 0 0 0 12 235 225 21 0 0 59 245 255 255 255 251 89 0 0 0 +59 245 255 255 251 89 59 245 255 255 255 247 34 0 0 59 245 255 255 255 +255 127 81 245 255 255 255 255 127 0 0 59 245 255 255 255 166 0 59 241 +89 0 0 0 59 241 89 89 255 255 255 125 7 206 255 251 89 59 241 89 0 0 89 +255 166 59 241 89 0 0 0 0 59 245 225 21 0 0 7 206 251 89 59 245 247 34 +0 0 59 241 89 0 0 138 255 255 255 166 0 0 59 245 255 255 255 225 21 0 0 +0 138 255 255 255 166 0 0 59 245 255 255 255 251 89 0 0 0 59 245 255 255 +201 89 255 255 255 255 255 255 255 125 59 241 89 0 0 0 59 241 97 206 166 +0 0 0 0 175 201 175 201 0 0 7 206 201 0 0 0 175 171 206 225 21 0 0 59 245 +166 245 125 0 0 0 89 251 89 89 255 255 255 255 255 127 0 228 34 0 0 59 +215 21 0 0 0 0 12 228 34 0 0 0 59 245 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 0 175 225 21 0 0 0 175 225 21 0 0 0 89 232 241 89 0 0 59 +241 89 0 0 138 225 21 0 89 255 125 0 0 59 192 59 241 89 0 0 175 251 89 +0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 89 255 125 0 0 7 199 34 59 241 +89 0 0 0 59 241 89 0 59 241 89 0 0 0 59 241 89 59 241 89 0 59 241 89 0 +59 241 89 0 0 0 0 59 245 255 125 0 0 89 255 251 89 59 245 255 201 0 0 59 +241 89 0 138 251 89 0 12 235 166 0 59 241 89 0 7 206 225 21 0 138 251 89 +0 12 235 166 0 59 241 89 0 0 138 247 34 0 12 235 125 0 7 176 21 0 0 59 +241 89 0 0 0 59 241 89 0 0 0 59 241 89 138 225 21 0 0 12 235 125 89 225 +21 0 59 245 247 34 0 12 232 89 12 235 166 0 7 206 166 0 89 247 34 0 7 206 +125 0 0 0 0 0 7 206 166 12 228 34 0 0 7 202 89 0 0 0 0 12 228 34 0 0 12 +235 133 206 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 138 201 0 138 +255 255 255 125 138 166 0 0 7 206 166 175 166 0 0 59 241 89 0 0 89 247 +34 7 206 166 0 0 0 0 0 59 241 89 0 0 0 175 225 21 59 241 89 0 0 0 0 59 +241 89 0 0 0 0 7 206 166 0 0 0 0 0 0 59 241 89 0 0 0 59 241 89 0 59 241 +89 0 0 0 59 241 89 59 241 89 59 241 89 0 0 59 241 89 0 0 0 0 59 241 159 +225 21 0 175 166 241 89 59 241 132 241 89 0 59 241 89 12 235 166 0 0 0 +89 247 34 59 241 89 0 0 89 247 34 12 235 166 0 0 0 89 247 34 59 241 89 +0 0 59 241 89 0 59 238 34 0 0 0 0 0 0 59 241 89 0 0 0 59 241 89 0 0 0 59 +241 89 59 241 89 0 0 89 225 21 59 241 89 0 89 206 202 89 0 59 238 34 0 +89 251 89 138 225 21 0 0 175 201 0 138 225 21 0 0 0 0 0 175 225 21 12 228 +34 0 0 0 138 166 0 0 0 0 12 228 34 0 7 206 166 0 12 235 125 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 7 202 89 89 225 21 7 206 125 12 206 21 0 59 238 +34 89 247 34 0 59 241 89 0 0 175 201 0 59 241 89 0 0 0 0 0 59 241 89 0 +0 0 59 241 89 59 241 89 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 0 +59 241 89 0 0 0 59 241 89 0 59 241 89 0 0 0 59 241 89 59 241 102 232 89 +0 0 0 59 241 89 0 0 0 0 59 241 102 232 89 59 215 81 241 89 59 241 89 138 +225 21 59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 7 206 201 0 59 241 +89 0 0 0 59 241 89 59 241 89 0 0 175 201 0 0 12 235 166 0 0 0 0 0 0 59 +241 89 0 0 0 59 241 89 0 0 0 59 241 89 7 206 166 0 0 175 166 0 7 206 125 +0 175 125 175 166 0 138 201 0 0 0 175 255 251 89 0 0 0 59 245 166 241 89 +0 0 0 0 0 89 247 34 0 12 228 34 0 0 0 89 201 0 0 0 0 12 228 34 12 235 201 +0 0 0 59 245 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 59 215 21 175 125 +0 7 206 125 7 199 34 0 138 201 0 12 235 125 0 59 245 255 255 255 247 34 +0 59 241 89 0 0 0 0 0 59 241 89 0 0 0 59 241 89 59 245 255 255 255 255 +127 59 245 255 255 255 255 127 59 241 89 0 0 0 0 0 0 59 245 255 255 255 +255 255 251 89 0 59 241 89 0 0 0 59 241 89 59 245 255 247 34 0 0 0 59 241 +89 0 0 0 0 59 241 89 138 201 175 166 59 241 89 59 241 89 12 235 125 59 +241 89 59 241 89 0 0 0 12 235 125 59 245 255 255 255 201 0 0 59 241 89 +0 0 0 12 235 125 59 245 255 255 255 125 0 0 0 0 59 245 255 255 125 0 0 +0 59 241 89 0 0 0 59 241 89 0 0 0 59 241 89 0 138 225 21 59 241 89 0 0 +175 201 7 202 89 89 201 0 175 166 0 0 0 12 235 166 0 0 0 0 0 138 255 166 +0 0 0 0 0 59 245 125 0 0 12 228 34 0 0 0 12 228 34 0 0 0 12 228 34 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 59 215 21 175 125 0 7 +206 125 7 199 34 7 206 125 0 0 175 201 0 59 241 89 0 0 89 247 34 59 241 +89 0 0 0 0 0 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 0 59 241 89 0 0 +0 0 59 241 89 0 59 245 255 251 89 59 241 89 0 0 0 59 241 89 0 59 241 89 +0 0 0 59 241 89 59 241 89 175 225 21 0 0 59 241 89 0 0 0 0 59 241 89 12 +235 247 34 59 241 89 59 241 89 0 89 247 94 241 89 59 241 89 0 0 0 59 241 +89 59 241 89 0 0 0 0 0 59 241 89 0 0 0 59 241 89 59 241 89 12 235 166 0 +0 0 0 0 0 0 138 251 89 0 0 59 241 89 0 0 0 59 241 89 0 0 0 59 241 89 0 +12 232 89 138 225 21 0 0 89 225 81 215 21 12 228 47 232 89 0 0 0 175 255 +251 89 0 0 0 0 59 241 89 0 0 0 0 7 206 201 0 0 0 12 228 34 0 0 0 0 175 +125 0 0 0 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +12 228 34 89 201 0 7 206 125 59 215 21 59 245 255 255 255 255 247 34 59 +241 89 0 0 59 241 89 7 206 166 0 0 0 0 0 59 241 89 0 0 0 138 225 21 59 +241 89 0 0 0 0 59 241 89 0 0 0 0 7 206 166 0 0 0 59 241 89 59 241 89 0 +0 0 59 241 89 0 59 241 89 0 0 0 59 241 89 59 241 89 7 206 201 0 0 59 241 +89 0 0 0 0 59 241 89 0 175 166 0 59 241 89 59 241 89 0 7 206 200 241 89 +12 235 166 0 0 0 89 247 34 59 241 89 0 0 0 0 0 12 235 166 0 0 0 89 247 +34 59 241 89 0 59 245 125 0 0 0 0 0 0 12 232 89 0 0 59 241 89 0 0 0 12 +232 89 0 0 0 59 238 34 0 0 175 171 206 166 0 0 0 12 232 159 201 0 7 202 +132 215 21 0 0 89 247 34 175 225 21 0 0 0 59 241 89 0 0 0 0 138 225 21 +0 0 0 12 228 34 0 0 0 0 89 201 0 0 0 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 138 201 7 206 255 251 226 255 255 166 0 +138 201 0 0 0 12 235 125 59 241 89 0 0 138 247 34 0 89 255 125 0 0 59 192 +59 241 89 0 0 138 251 89 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 89 255 +125 0 0 59 241 89 59 241 89 0 0 0 59 241 89 0 59 241 89 0 0 0 89 247 34 +59 241 89 0 12 235 166 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 59 241 89 +59 241 89 0 0 59 245 251 89 0 138 251 89 0 59 245 166 0 59 241 89 0 0 0 +0 0 0 138 251 89 0 59 245 166 0 59 241 89 0 0 138 251 89 0 89 166 0 0 89 +247 34 0 0 59 241 89 0 0 0 0 138 225 21 0 7 206 166 0 0 0 89 255 251 89 +0 0 0 7 206 255 125 0 0 138 255 201 0 0 12 235 125 0 12 235 166 0 0 0 59 +241 89 0 0 0 89 251 89 0 0 0 0 12 228 34 0 0 0 0 12 228 34 0 0 12 228 34 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 7 206 225 21 0 +0 0 0 0 0 7 206 125 0 0 0 0 175 201 59 245 255 255 255 247 34 0 0 0 59 +245 255 255 251 89 59 245 255 255 255 225 21 0 0 59 245 255 255 255 255 +127 81 241 89 0 0 0 0 0 0 59 245 255 255 255 201 0 59 241 89 0 0 0 59 241 +89 89 255 255 255 138 235 255 255 125 0 59 241 89 0 0 89 255 201 59 245 +255 255 255 255 166 59 241 89 0 0 0 0 59 241 89 59 241 89 0 0 0 175 251 +89 0 0 138 255 255 255 166 0 0 59 241 89 0 0 0 0 0 0 0 138 255 255 255 +166 0 0 59 241 89 0 0 0 175 251 89 12 235 255 255 251 89 0 0 0 59 241 89 +0 0 0 0 0 59 245 255 251 89 0 0 0 0 12 235 201 0 0 0 0 0 138 251 89 0 0 +89 255 125 0 7 206 225 21 0 0 89 255 125 0 0 59 241 89 0 0 0 175 255 255 +255 255 255 127 0 228 34 0 0 0 0 0 175 125 0 0 12 228 34 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 89 255 255 255 255 125 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 +228 34 0 0 0 0 0 89 201 0 0 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 138 255 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 255 125 0 0 0 12 228 +124 255 255 247 34 0 0 0 0 0 0 0 0 0 245 255 255 255 255 255 255 0 0 0 +0 0 0 0 0 0 0 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 0 127 +127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 4 4 4 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 127 0 89 255 125 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 89 255 255 166 0 0 0 0 0 +0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 255 201 0 12 228 +34 0 0 89 255 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 116 116 +4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 0 59 241 89 0 0 0 0 0 0 0 0 0 59 241 89 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 12 235 125 0 0 0 0 0 0 +0 0 0 59 241 89 0 0 0 0 59 241 89 0 89 251 89 59 241 89 0 0 0 0 59 241 +89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 225 +21 0 0 12 228 34 0 0 0 0 138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 +4 4 28 244 252 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 +241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 59 241 89 0 +0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 59 241 +89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 +0 0 0 12 228 34 0 0 0 0 89 225 21 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 +4 180 252 164 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 7 206 255 255 255 +125 0 59 241 194 255 251 89 0 0 7 206 255 255 201 0 12 235 255 255 251 +89 0 12 235 255 251 89 7 206 255 255 247 34 0 12 235 255 255 251 89 59 +241 194 255 255 125 0 59 241 89 89 255 251 89 59 241 89 0 138 251 89 59 +241 89 59 241 159 255 255 125 89 255 255 166 0 59 241 194 255 255 125 0 +0 0 12 235 255 247 34 0 59 241 194 255 255 125 0 0 12 235 255 255 251 89 +59 241 159 255 201 0 138 255 255 247 34 206 255 255 255 166 59 241 89 0 +59 241 97 206 166 0 0 12 235 125 175 201 0 7 206 166 0 7 206 133 206 225 +21 0 89 255 255 166 0 0 12 235 125 138 255 255 255 255 166 0 0 138 166 +0 0 0 12 228 34 0 0 0 0 89 225 21 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 +76 252 244 20 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 89 247 34 +59 245 166 0 138 225 21 7 206 201 0 0 0 7 206 166 0 59 241 89 7 206 125 +0 89 225 21 59 241 89 0 0 7 206 166 0 59 241 89 59 245 166 0 89 247 34 +59 241 89 0 59 241 89 59 241 89 138 225 21 0 59 241 89 59 245 201 0 89 +255 201 0 89 247 34 59 245 166 0 89 247 34 0 7 206 166 0 138 225 21 59 +245 166 0 138 247 34 7 206 166 0 59 241 89 59 245 201 0 0 59 238 34 0 130 +34 59 241 89 0 0 59 241 89 0 59 241 89 89 247 34 0 89 247 34 138 225 21 +12 235 225 21 12 232 89 7 206 166 12 235 125 89 247 34 0 89 247 34 0 0 +0 89 247 34 0 0 138 166 0 0 0 12 228 34 0 0 0 0 89 225 21 0 0 7 206 247 +34 0 0 89 201 0 0 4 4 68 12 4 4 4 220 252 108 4 4 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 0 0 0 0 0 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 0 0 59 +241 89 0 59 241 89 59 238 34 0 59 238 34 59 241 89 0 0 59 241 89 0 59 241 +89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 159 201 0 0 0 59 +241 89 59 241 89 0 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 59 241 +89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 +0 59 241 89 0 0 0 59 241 89 0 0 59 241 89 0 59 241 89 12 235 125 0 175 +166 0 59 238 34 89 171 202 89 89 225 21 0 59 241 226 201 0 12 235 125 0 +175 166 0 0 0 12 235 125 0 0 59 238 34 0 0 0 12 228 34 0 0 0 0 7 206 125 +0 7 202 89 12 235 166 0 175 125 0 0 4 60 244 172 4 4 132 252 212 4 4 4 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 89 255 255 255 251 89 59 241 89 +0 59 241 89 59 238 34 0 0 0 59 238 34 0 59 241 89 59 245 255 255 255 251 +0 59 241 89 0 0 59 238 34 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 +59 241 89 59 245 255 225 21 0 0 59 241 89 59 241 89 0 59 241 89 0 59 241 +89 59 241 89 0 59 241 89 0 59 238 34 0 12 232 89 59 241 89 0 12 232 89 +59 238 34 0 59 241 89 59 241 89 0 0 0 175 255 255 201 0 59 241 89 0 0 59 +241 89 0 59 241 89 0 175 201 12 232 89 0 7 206 125 172 89 138 166 138 201 +0 0 0 138 247 34 0 0 175 201 12 232 89 0 0 7 206 166 0 0 175 225 21 0 0 +0 0 12 228 34 0 0 0 0 0 0 175 225 34 206 21 0 0 175 255 166 0 0 0 4 52 +244 252 140 36 244 252 60 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 59 +241 89 0 59 241 89 59 241 89 0 59 238 34 59 241 89 0 0 0 59 241 89 0 59 +241 89 59 238 34 0 0 0 0 59 241 89 0 0 59 241 89 0 59 241 89 59 241 89 +0 59 241 89 59 241 89 0 59 241 89 59 241 97 206 201 0 0 59 241 89 59 241 +89 0 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 59 241 89 0 59 241 89 +59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 0 0 0 0 59 245 +125 59 241 89 0 0 59 241 89 0 59 241 89 0 59 238 124 225 21 0 0 175 176 +206 21 59 215 187 125 0 0 59 245 255 201 0 0 89 247 124 225 21 0 0 138 +225 21 0 0 0 59 241 89 0 0 0 12 228 34 0 0 0 0 12 235 125 0 0 0 0 0 0 0 +0 0 0 0 0 4 4 76 252 252 220 252 164 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 0 0 0 0 0 89 247 34 0 89 251 89 59 241 89 0 175 201 0 7 206 201 0 0 0 +7 206 166 0 138 251 89 7 206 166 0 7 199 34 59 241 89 0 0 7 206 166 0 138 +251 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 12 235 166 +0 59 241 89 59 241 89 0 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 7 +206 166 0 138 225 21 59 241 89 0 138 225 21 7 206 166 0 89 251 89 59 241 +89 0 0 89 125 0 12 232 89 12 232 89 0 12 12 235 125 0 175 251 89 0 7 206 +255 125 0 0 0 89 255 201 0 7 206 247 34 0 7 206 166 59 245 125 0 7 206 +255 125 0 0 59 241 89 0 0 0 0 0 138 166 0 0 0 12 228 34 0 0 0 0 89 225 +21 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 100 252 252 244 28 4 4 4 4 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 0 0 0 0 0 0 0 175 255 255 232 241 89 59 245 255 255 247 34 +0 0 12 235 255 255 201 0 59 245 255 200 241 89 0 12 235 255 251 89 0 59 +241 89 0 0 0 12 235 255 200 241 89 59 241 89 0 59 241 89 59 241 89 0 59 +241 89 59 241 89 0 59 245 201 59 241 89 59 241 89 0 59 241 89 0 59 241 +89 59 241 89 0 59 241 89 0 0 12 235 255 247 34 0 59 245 166 255 247 34 +0 0 59 245 255 166 241 89 59 241 89 0 0 59 245 255 255 166 0 0 138 255 +255 125 0 89 255 255 166 241 89 0 0 138 247 34 0 0 0 59 245 125 0 0 138 +225 21 7 206 225 21 0 138 251 0 0 138 247 34 0 0 175 255 255 255 255 166 +0 0 138 166 0 0 0 12 228 34 0 0 0 0 89 225 21 0 0 0 0 0 0 0 0 0 0 0 0 4 +4 4 4 132 252 108 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 89 247 34 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 +0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 232 89 0 0 0 0 0 0 0 0 0 0 0 138 +201 0 0 0 12 228 34 0 0 0 0 138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 +116 4 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 166 255 255 +247 34 0 0 0 0 0 0 0 0 0 0 0 255 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 59 +241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 0 0 0 0 7 206 255 +201 0 12 228 34 0 0 89 255 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 +4 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 0 127 127 127 0 127 127 127 +127 127 127 0 127 127 0 127 127 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 0 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 127 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 89 247 34 138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 125 59 238 34 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 +225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +12 235 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 238 34 138 201 0 0 0 0 0 +0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 34 0 0 0 0 0 7 199 34 0 0 0 0 138 255 +201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 251 89 0 0 138 255 251 97 206 201 0 0 138 +251 102 235 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 +201 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 7 206 166 12 232 89 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 166 12 235 127 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 0 175 255 255 255 225 21 59 245 255 255 255 +255 255 125 0 0 0 0 0 0 0 7 206 255 247 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 7 199 34 0 0 0 0 0 7 199 34 0 0 0 138 225 21 175 166 0 0 175 255 255 +166 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 59 245 255 255 201 0 0 0 0 0 0 0 0 +59 245 255 255 255 255 255 255 255 255 125 0 59 245 255 255 255 255 255 +125 0 0 89 255 255 255 255 255 225 21 59 245 255 255 255 255 255 125 0 +0 0 59 245 255 255 255 255 255 125 7 206 166 0 0 175 171 206 166 89 247 +34 0 175 201 59 241 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +12 228 34 175 255 125 0 0 89 255 255 255 125 175 251 89 89 255 125 0 7 +206 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 255 255 255 +255 255 125 0 0 7 206 255 125 59 245 125 0 0 0 89 251 89 0 0 0 0 0 0 0 +127 7 206 225 21 0 0 0 0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 0 175 201 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 255 255 255 255 125 0 59 245 255 +255 255 255 125 0 0 0 0 0 0 0 89 247 34 12 228 34 0 138 166 0 0 0 0 0 0 +0 0 0 0 12 235 125 0 7 176 21 0 0 0 0 0 0 138 251 89 0 0 138 201 0 0 0 +0 0 0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 7 206 166 0 59 115 0 0 0 0 59 115 +0 0 0 59 115 0 0 0 0 59 115 0 89 201 0 12 232 89 89 201 7 202 89 12 232 +89 138 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 7 199 34 0 172 132 196 199 163 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 0 89 247 34 0 7 +206 125 0 0 0 0 0 0 0 0 127 89 247 34 0 0 0 0 0 59 115 0 0 0 0 59 115 0 +0 0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 34 0 +0 0 0 0 7 199 34 0 0 0 0 0 0 0 0 0 89 225 21 7 202 89 12 228 34 0 0 0 0 +0 0 0 0 0 0 59 238 34 0 0 0 0 0 0 0 130 34 59 241 89 0 0 0 138 201 0 0 +0 0 0 0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 175 225 21 0 59 115 0 0 0 0 59 +115 0 0 0 59 115 0 0 0 0 59 115 0 12 228 34 59 192 0 12 228 34 138 166 +59 215 21 175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 7 199 34 0 172 89 175 166 138 125 0 138 255 255 247 34 12 +146 0 0 0 0 89 255 255 255 125 12 235 255 255 125 0 0 0 59 115 0 0 0 0 +59 115 0 138 255 255 255 255 127 0 175 201 0 138 225 21 0 0 0 0 0 0 0 0 +127 245 255 255 255 255 255 125 0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 12 +232 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 34 0 0 0 0 0 7 199 +34 0 0 0 0 0 0 0 0 0 89 247 34 12 228 34 138 166 0 0 0 0 0 0 0 0 0 0 0 +12 235 166 0 0 0 0 0 0 175 225 21 138 225 21 0 0 0 138 201 0 0 0 0 0 0 +59 115 0 0 0 0 59 115 0 0 0 0 0 89 247 34 0 0 59 115 0 0 0 0 59 115 0 0 +0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 255 166 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 34 0 172 +89 0 0 138 125 59 238 34 0 130 34 7 206 201 0 0 59 241 89 0 12 235 255 +125 0 59 241 89 0 0 59 115 0 0 0 0 59 115 0 0 0 0 89 247 34 0 59 245 166 +241 89 0 0 0 0 0 0 0 0 0 127 138 225 21 0 0 0 0 0 59 115 0 0 0 0 59 115 +0 0 0 0 0 89 255 255 255 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 +34 0 0 0 0 0 7 199 34 0 0 0 0 0 0 0 0 0 0 175 255 255 166 59 215 21 175 +255 255 125 0 89 255 255 201 0 0 0 59 245 255 255 125 0 12 235 166 0 0 +138 225 21 0 0 0 138 255 255 255 255 247 34 0 59 115 0 0 0 0 59 115 0 0 +0 0 59 245 125 0 0 0 59 115 0 0 0 0 59 115 0 0 0 59 115 0 0 0 0 59 115 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 255 251 102 0 255 255 255 255 +255 0 245 255 255 255 255 255 255 255 255 255 255 127 21 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 59 241 89 0 0 0 0 0 138 247 34 138 201 0 0 0 175 +201 0 0 0 175 166 0 0 59 115 0 0 0 0 59 115 0 0 0 12 235 125 0 0 0 138 +255 166 0 0 0 0 0 0 0 0 0 0 127 245 255 255 255 255 225 21 0 59 115 0 0 +0 0 59 115 0 0 0 0 0 0 89 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 7 199 34 0 0 0 59 245 255 255 255 255 125 0 0 0 0 0 0 0 0 0 0 0 0 175 +125 89 225 21 59 238 47 232 89 7 206 125 0 0 0 0 0 138 251 89 12 235 166 +0 0 138 225 21 0 0 0 138 201 0 0 0 0 0 0 59 115 0 0 0 0 59 115 0 0 0 7 +206 201 0 0 0 0 59 115 0 0 0 0 59 115 0 0 0 59 115 0 0 0 0 59 115 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 255 251 89 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 255 255 201 0 +0 0 138 247 34 175 201 0 0 0 138 255 255 255 255 255 166 0 0 59 115 0 0 +0 0 59 115 0 0 7 206 166 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 127 89 251 +89 0 0 0 0 0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 138 201 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 7 199 34 0 0 0 0 0 7 199 34 0 0 0 0 0 0 0 0 0 +0 0 0 0 59 215 21 138 201 0 12 228 47 228 34 0 175 166 0 0 0 0 0 12 232 +89 0 0 175 225 21 59 241 89 0 0 0 138 201 0 0 0 0 0 0 59 115 0 0 0 0 59 +115 0 0 0 138 225 21 0 0 0 0 59 115 0 0 0 0 59 115 0 0 0 59 115 0 0 0 0 +59 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 255 166 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 +245 125 7 206 201 0 0 138 201 0 0 0 175 201 0 0 0 0 0 0 0 59 115 0 0 0 +0 59 115 0 0 138 225 21 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 127 7 206 +247 34 0 0 0 0 59 115 0 0 0 0 59 115 0 59 245 125 0 0 175 166 0 0 0 59 +245 125 175 225 29 206 166 0 89 247 34 7 206 166 0 0 0 7 199 34 0 0 0 0 +0 7 199 34 0 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 89 225 21 59 238 47 232 89 +7 206 125 0 89 166 0 0 89 247 34 0 0 0 130 34 0 138 255 125 0 0 138 201 +0 0 0 0 0 0 59 115 0 0 0 0 59 115 0 0 89 251 89 0 0 0 0 0 59 115 0 0 0 +0 59 115 0 0 0 59 115 0 0 0 0 59 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 89 125 0 12 232 89 12 146 0 0 0 59 241 89 0 12 235 247 +34 0 0 89 125 0 0 59 115 0 0 0 0 59 115 0 59 241 89 0 0 0 0 0 59 241 89 +0 0 0 0 0 0 0 0 0 0 127 0 0 175 255 255 255 225 21 59 245 255 255 255 255 +255 125 0 138 225 21 0 12 235 125 0 0 0 138 225 34 235 125 7 206 166 0 +89 247 34 7 206 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +138 201 0 0 0 175 255 255 125 0 89 255 255 201 0 0 12 235 255 255 251 89 +0 0 0 0 0 0 0 0 89 255 255 255 255 255 255 255 255 255 125 0 59 245 255 +255 255 255 255 125 0 0 175 255 255 255 255 255 247 34 59 245 255 255 255 +255 255 125 0 0 0 59 245 255 255 255 255 255 125 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 255 255 166 0 0 0 0 0 0 0 89 255 255 +255 125 59 245 255 255 201 0 0 0 59 245 255 255 255 255 255 125 0 175 255 +255 255 255 127 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 175 166 0 255 255 201 0 0 0 0 175 166 59 238 34 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 228 34 0 0 +0 0 0 0 0 12 228 34 138 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 +0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 0 127 127 127 0 127 127 127 127 127 +127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 127 0 127 127 0 127 127 0 127 127 127 127 0 +127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 +0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 245 255 255 255 255 255 +251 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 +0 0 0 138 125 0 0 0 0 59 245 255 255 125 0 0 0 0 0 0 0 0 138 225 21 0 0 +175 166 0 12 228 34 0 0 59 245 255 255 247 34 0 89 225 29 206 166 0 0 0 +0 0 89 255 255 255 255 125 0 0 0 7 206 255 255 247 34 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 255 255 255 255 125 0 0 0 0 0 0 0 +0 0 0 0 0 138 255 255 166 0 0 0 0 7 202 89 0 0 0 0 0 12 235 255 125 0 0 +175 255 255 225 21 0 0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 138 255 255 255 +255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 228 34 0 0 89 255 255 225 21 0 0 +0 0 0 0 0 0 0 0 0 138 166 0 0 0 89 225 21 0 0 0 0 0 138 166 0 0 0 89 225 +21 0 0 0 12 235 255 255 166 0 0 7 206 125 0 0 0 0 0 0 89 247 34 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 0 0 0 138 125 0 0 0 12 +235 125 0 59 115 0 0 0 0 0 0 0 0 7 206 125 0 59 215 21 0 12 228 34 0 12 +235 125 0 0 168 34 0 0 0 0 0 0 0 0 0 0 175 225 21 0 0 0 175 225 21 0 0 +0 0 0 138 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 225 +21 0 0 0 175 225 21 0 0 0 0 0 0 0 0 0 59 238 34 7 206 125 0 0 0 7 202 89 +0 0 0 0 7 199 34 59 238 34 0 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 89 255 255 255 125 175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 138 255 247 34 0 +59 241 89 0 175 201 0 0 0 0 0 0 0 0 0 7 206 255 166 0 0 12 232 89 0 0 0 +0 7 206 255 166 0 0 12 232 89 0 0 0 0 0 0 0 59 215 21 0 89 201 0 0 0 0 +0 0 0 89 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 7 +206 255 255 251 89 0 59 241 89 0 0 0 138 201 0 0 0 138 201 0 0 89 225 21 +175 125 0 0 12 228 34 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 0 +89 255 255 247 34 89 201 0 0 89 255 255 255 166 0 0 0 0 168 34 7 151 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 166 7 206 255 255 225 21 89 201 0 0 0 +0 0 0 0 0 0 89 166 0 0 138 166 0 0 0 7 202 89 0 0 0 0 0 0 0 59 238 34 0 +7 206 255 125 0 0 0 0 0 0 0 0 0 59 238 34 0 0 175 166 0 175 255 255 255 +125 175 125 0 138 247 34 0 0 0 0 0 0 0 0 0 0 12 228 34 0 89 201 0 0 89 +225 0 81 115 0 134 89 0 0 0 0 0 138 166 0 0 138 166 0 0 0 0 0 0 0 138 166 +0 0 138 166 0 0 0 0 0 0 59 245 247 34 0 12 232 89 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 89 201 0 7 206 201 138 125 +138 125 0 59 241 89 0 0 0 0 175 255 255 255 225 21 0 0 7 206 166 215 21 +0 0 12 228 34 0 0 138 255 255 251 89 0 0 0 0 0 0 0 0 0 12 206 21 59 241 +89 0 134 89 0 172 89 59 238 34 0 138 166 0 0 7 206 201 12 235 125 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 12 206 21 7 202 89 12 235 125 0 172 89 0 0 0 0 +0 0 0 0 59 238 34 7 206 125 12 235 255 255 255 255 255 255 125 0 0 0 12 +235 125 0 0 0 0 7 206 125 0 0 0 0 0 0 0 0 59 238 34 0 0 175 166 0 175 255 +255 255 125 175 125 0 138 247 34 0 0 0 0 0 0 0 0 0 0 12 228 34 0 89 201 +0 0 89 225 0 29 206 166 59 245 125 0 0 0 0 138 166 0 12 228 34 0 175 225 +21 0 0 0 138 166 0 12 228 42 206 255 255 166 0 0 0 0 12 228 34 138 166 +0 89 247 34 0 0 0 0 59 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 +0 0 138 201 0 59 241 89 138 125 0 0 59 245 255 255 255 125 0 0 138 166 +0 89 201 0 0 0 0 89 255 125 0 0 0 0 0 0 0 7 206 125 0 138 251 89 0 0 0 +0 0 0 0 0 89 166 0 138 201 0 0 0 0 0 89 166 59 215 21 0 175 166 0 59 245 +125 89 251 89 0 0 12 235 255 255 255 255 255 255 125 138 255 255 251 89 +127 166 0 7 202 89 12 232 89 0 89 166 0 0 0 0 0 0 0 0 0 138 255 255 166 +0 0 0 0 7 202 89 0 0 0 0 0 59 241 89 0 0 0 0 0 7 206 125 0 0 0 0 0 0 0 +0 59 238 34 0 0 175 166 0 89 255 255 255 125 175 125 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 12 228 34 0 59 241 89 0 175 201 0 0 0 175 201 7 206 201 0 0 0 +138 166 0 175 166 0 138 200 215 21 0 0 0 138 166 0 175 166 7 151 0 89 247 +34 0 0 0 59 238 47 228 34 59 219 209 34 0 0 0 89 255 125 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 59 238 34 138 125 0 0 0 59 +241 89 0 0 0 0 138 166 0 89 201 0 0 59 245 255 255 255 255 125 0 0 0 0 +0 59 238 34 0 7 206 125 0 0 0 0 0 0 0 0 89 166 0 138 201 0 0 0 0 0 89 166 +0 175 255 255 223 166 0 12 235 125 59 241 89 0 0 0 0 0 0 0 0 0 175 125 +0 0 0 0 0 138 125 0 7 206 255 255 125 0 0 59 157 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 7 202 89 0 0 0 0 7 206 255 255 255 166 7 206 255 255 201 0 +0 0 0 0 0 0 0 0 59 238 34 0 0 175 166 0 0 89 255 255 125 175 125 0 0 0 +0 0 0 0 0 0 0 0 0 0 89 255 255 251 89 0 89 255 255 225 21 0 0 0 175 225 +29 206 166 0 0 0 138 166 59 215 21 59 215 81 215 21 0 0 0 138 166 59 215 +21 0 0 0 89 225 21 59 245 255 255 125 138 166 7 202 97 199 34 0 0 89 251 +89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 21 59 241 +89 138 125 0 0 0 89 247 34 0 0 0 0 175 255 255 255 225 21 0 0 0 12 232 +89 0 0 0 12 228 34 0 12 235 225 21 59 215 21 0 0 0 0 0 0 0 0 12 206 21 +59 241 89 0 134 89 0 172 89 0 0 0 0 0 0 0 0 7 206 201 12 235 125 0 0 0 +0 0 0 0 0 175 125 0 0 0 0 0 12 206 21 7 202 89 7 206 125 0 172 89 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 59 238 34 0 0 175 166 0 0 0 0 175 125 175 125 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 166 59 245 125 0 0 0 0 0 0 +175 125 12 228 34 59 215 21 0 0 0 0 0 175 125 0 0 0 12 232 89 0 0 0 0 0 +59 238 34 175 125 7 199 34 0 0 175 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 127 0 0 0 0 0 138 225 21 7 206 201 138 125 138 125 7 202 89 0 0 0 +0 138 201 0 0 0 138 166 0 0 0 12 232 89 0 0 0 12 228 34 0 0 0 175 255 255 +166 0 0 0 0 0 0 0 0 0 0 138 166 0 89 255 255 247 34 89 201 0 0 0 0 0 0 +0 0 0 0 0 168 34 7 151 0 0 0 0 0 0 0 0 175 125 0 0 0 0 0 0 138 166 7 202 +89 0 89 247 124 201 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 255 255 255 +255 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 245 125 0 7 206 +166 0 0 0 0 175 125 175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 59 115 0 134 89 0 0 0 0 0 0 59 215 21 59 245 255 255 255 225 21 0 +0 0 59 215 21 0 0 59 238 34 0 0 0 0 0 0 175 125 7 206 255 255 255 251 89 +0 138 247 34 0 59 157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 138 225 +21 0 7 206 255 255 251 89 138 255 255 255 255 255 166 0 0 0 0 0 0 0 0 0 +0 12 232 89 0 0 0 12 228 34 0 0 0 0 0 59 241 89 0 0 0 0 0 0 0 0 0 0 175 +225 21 0 0 0 175 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 175 225 21 0 0 0 175 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 238 198 +255 251 194 166 0 0 0 0 175 125 175 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 125 0 0 0 0 89 225 21 0 0 0 +7 206 125 0 0 12 235 255 255 255 166 0 0 0 89 225 21 0 0 0 12 228 34 0 +0 0 175 255 255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 +0 0 0 0 138 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 228 +34 0 7 176 21 0 89 247 34 0 0 0 0 0 0 0 0 0 0 0 89 255 255 255 255 125 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 +255 255 255 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 238 34 0 0 0 0 0 0 0 0 175 +125 175 125 0 0 0 0 0 0 0 0 59 215 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +0 0 0 0 0 0 0 138 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +12 228 34 0 7 206 255 255 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 238 34 0 0 0 0 0 0 0 0 175 125 175 125 +0 0 0 0 0 0 59 245 251 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 0 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +0 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 127 127 0 +127 127 127 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 89 +255 125 0 0 0 0 0 0 12 235 201 0 0 0 0 12 235 251 89 0 0 0 0 175 255 125 +89 201 0 0 0 0 0 0 0 0 0 0 0 59 245 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 89 255 125 0 0 0 0 0 0 138 251 89 0 0 0 12 235 251 +89 0 0 0 0 0 0 0 0 7 206 225 21 0 0 0 89 255 125 0 89 255 225 21 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 247 34 172 89 0 0 0 0 7 206 225 21 0 0 +0 0 0 0 0 89 255 125 0 0 0 0 0 0 89 255 225 21 0 0 0 0 12 235 247 34 172 +89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 +255 125 0 0 0 0 0 0 0 7 206 225 21 0 0 0 0 89 255 225 21 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 89 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 +0 89 247 34 0 0 0 0 0 175 166 0 0 0 0 7 206 125 59 241 89 0 0 89 201 12 +235 247 34 0 0 7 206 166 59 241 89 0 0 12 228 34 59 215 21 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 238 34 0 0 0 0 89 247 34 0 0 0 7 +206 125 59 241 89 0 7 206 166 59 238 34 0 0 175 166 0 0 59 241 89 0 89 +247 34 138 201 59 238 34 138 201 0 0 0 0 0 0 0 0 0 0 0 175 125 89 255 201 +0 0 0 0 0 0 0 175 201 0 0 0 0 0 0 12 232 89 0 0 0 0 0 0 59 238 34 138 225 +21 0 0 0 175 125 89 255 201 0 0 0 0 59 238 34 138 201 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 89 247 34 0 0 0 0 0 0 138 201 0 0 0 0 +0 59 238 34 138 225 21 0 0 0 59 238 34 138 201 0 0 0 0 12 232 89 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 228 34 59 215 21 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 255 125 0 +0 0 0 127 0 0 12 235 225 21 0 0 0 0 12 235 225 21 0 0 0 0 12 235 225 21 +0 0 0 0 12 235 225 21 0 0 0 0 12 235 225 21 0 0 0 0 12 235 225 21 0 0 0 +0 0 175 255 255 255 255 255 255 255 166 0 0 138 255 255 255 251 89 59 245 +255 255 255 255 127 81 245 255 255 255 255 225 21 59 245 255 255 255 255 +127 81 245 255 255 255 255 127 111 255 255 255 125 89 255 255 255 125 89 +255 255 255 125 89 255 255 255 125 7 206 255 255 255 255 125 0 0 59 245 +247 34 0 0 59 241 89 0 0 0 138 255 255 255 166 0 0 0 0 138 255 255 255 +166 0 0 0 0 0 138 255 255 255 166 0 0 0 0 138 255 255 255 166 0 0 0 0 138 +255 255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 255 255 255 210 235 166 +59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 +241 89 59 241 89 0 0 0 59 241 132 245 125 0 0 0 89 251 89 12 232 89 0 0 +0 0 7 206 166 0 89 251 89 0 0 0 127 0 0 89 232 241 89 0 0 0 0 89 232 241 +89 0 0 0 0 89 232 241 89 0 0 0 0 89 232 241 89 0 0 0 0 89 232 241 89 0 +0 0 0 89 232 241 89 0 0 0 0 12 232 89 89 225 21 0 0 0 0 0 175 247 34 0 +0 59 192 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 0 0 59 241 +89 0 0 0 0 0 59 241 89 0 0 59 241 89 0 0 59 241 89 0 0 59 241 89 0 7 206 +166 0 0 59 245 201 0 59 245 255 201 0 0 59 241 89 0 0 138 251 89 0 12 235 +166 0 0 138 251 89 0 12 235 166 0 0 0 138 251 89 0 12 235 166 0 0 138 251 +89 0 12 235 166 0 0 138 251 89 0 12 235 166 0 0 0 138 166 0 0 0 12 228 +34 0 0 175 247 34 0 0 175 225 21 59 241 89 0 0 0 59 241 89 59 241 89 0 +0 0 59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 89 247 +34 0 7 206 125 0 12 232 89 0 0 0 0 59 241 89 0 12 232 89 0 0 0 127 0 7 +206 166 175 166 0 0 0 7 206 166 175 166 0 0 0 7 206 166 175 166 0 0 0 7 +206 166 175 166 0 0 0 7 206 166 175 166 0 0 0 0 175 166 175 166 0 0 0 0 +138 225 21 89 225 21 0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 0 0 59 241 +89 0 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 59 241 +89 0 0 59 241 89 0 0 59 241 89 0 7 206 166 0 0 0 59 245 125 59 241 132 +241 89 0 59 241 89 0 12 235 166 0 0 0 89 247 34 12 235 166 0 0 0 89 247 +34 0 12 235 166 0 0 0 89 247 34 12 235 166 0 0 0 89 247 34 12 235 166 0 +0 0 89 247 34 0 0 12 235 125 0 12 235 125 0 0 59 241 89 0 0 138 176 235 +166 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 +59 241 89 59 241 89 0 0 0 59 241 89 0 175 201 0 138 225 21 0 12 235 255 +255 255 225 21 59 238 34 0 138 225 21 0 0 0 127 0 59 238 34 89 247 34 0 +0 59 238 34 89 247 34 0 0 59 238 34 89 247 34 0 0 59 238 34 89 247 34 0 +0 59 238 34 89 247 34 0 0 59 241 89 89 225 21 0 0 7 206 125 0 89 225 21 +0 0 0 0 138 225 21 0 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 +89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 59 241 89 0 0 59 241 89 0 +0 59 241 89 0 7 206 166 0 0 0 7 206 166 59 241 89 138 225 21 59 241 89 +0 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 0 59 241 89 0 0 0 +59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 0 0 0 12 +235 138 235 125 0 0 0 138 225 21 0 59 215 21 175 201 59 241 89 0 0 0 59 +241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 +0 0 59 241 89 0 59 245 166 241 89 0 0 12 232 89 0 0 175 225 59 238 47 235 +225 21 0 0 0 0 127 0 138 201 0 12 235 125 0 0 138 201 0 12 235 125 0 0 +138 201 0 12 235 125 0 0 138 201 0 12 235 125 0 0 138 201 0 12 235 125 +0 0 138 225 21 12 235 125 0 0 89 247 34 0 89 255 255 255 255 251 89 138 +225 21 0 0 0 0 0 59 245 255 255 255 255 127 59 245 255 255 255 255 166 +0 59 245 255 255 255 255 127 59 245 255 255 255 255 127 0 59 241 89 0 0 +59 241 89 0 0 59 241 89 0 0 59 241 89 7 206 255 255 255 166 0 0 175 201 +59 241 89 12 235 125 59 241 89 0 59 241 89 0 0 0 12 235 125 59 241 89 0 +0 0 12 235 125 0 59 241 89 0 0 0 12 235 125 59 241 89 0 0 0 12 235 125 +59 241 89 0 0 0 12 235 125 0 0 0 0 12 235 125 0 0 0 0 138 225 21 7 199 +34 0 138 225 81 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 59 241 +89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 0 0 138 255 166 0 0 0 12 232 +89 0 0 89 247 59 238 34 0 59 245 125 0 0 0 127 7 206 125 0 0 175 201 0 +7 206 125 0 0 175 201 0 7 206 125 0 0 175 201 0 7 206 125 0 0 175 201 0 +7 206 125 0 0 175 201 0 7 206 125 0 0 175 201 0 7 206 255 255 255 255 225 +21 0 0 0 0 138 225 21 0 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 59 +241 89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 59 241 89 0 0 59 241 89 +0 0 59 241 89 0 7 206 166 0 0 0 7 206 166 59 241 89 0 89 247 94 241 89 +0 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 0 59 241 89 0 0 0 +59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 0 0 0 12 +235 138 235 125 0 0 0 138 225 21 175 125 0 0 175 201 59 241 89 0 0 0 59 +241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 0 0 59 241 89 59 241 89 0 +0 0 59 241 89 0 0 59 241 89 0 0 0 12 232 89 0 7 206 201 59 238 34 0 0 138 +201 0 0 0 127 59 245 255 255 255 255 247 34 59 245 255 255 255 255 247 +34 59 245 255 255 255 255 247 34 59 245 255 255 255 255 247 34 59 245 255 +255 255 255 247 34 59 245 255 255 255 255 247 34 59 241 89 0 0 89 225 21 +0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 +89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 59 241 89 0 0 59 241 89 0 +0 59 241 89 0 7 206 166 0 0 0 59 241 89 59 241 89 0 7 206 200 241 89 0 +12 235 166 0 0 0 89 247 34 12 235 166 0 0 0 89 247 34 0 12 235 166 0 0 +0 89 247 34 12 235 166 0 0 0 89 247 34 12 235 166 0 0 0 89 247 34 0 0 12 +235 125 0 12 235 125 0 0 59 241 159 166 0 0 12 235 166 12 232 89 0 0 0 +59 238 34 12 232 89 0 0 0 59 238 34 12 232 89 0 0 0 59 238 34 12 232 89 +0 0 0 59 238 34 0 0 59 241 89 0 0 0 12 235 255 255 255 201 0 59 238 34 +0 0 138 201 0 0 0 127 138 201 0 0 0 12 235 125 138 201 0 0 0 12 235 125 +138 201 0 0 0 12 235 125 138 201 0 0 0 12 235 125 138 201 0 0 0 12 235 +125 138 201 0 0 0 12 235 125 175 201 0 0 0 89 225 21 0 0 0 0 0 175 247 +34 0 0 59 192 59 241 89 0 0 0 0 59 241 89 0 0 0 0 0 59 241 89 0 0 0 0 59 +241 89 0 0 0 0 0 59 241 89 0 0 59 241 89 0 0 59 241 89 0 0 59 241 89 0 +7 206 166 0 0 59 245 201 0 59 241 89 0 0 59 245 251 89 0 0 138 251 89 0 +59 245 166 0 0 138 251 89 0 59 245 166 0 0 0 138 251 89 0 59 245 166 0 +0 138 251 89 0 59 245 166 0 0 138 251 89 0 59 245 166 0 0 0 138 166 0 0 +0 12 228 34 0 0 175 247 34 0 7 206 225 21 0 138 225 21 0 7 206 166 0 0 +138 225 21 0 7 206 166 0 0 138 225 21 0 7 206 166 0 0 138 225 21 0 7 206 +166 0 0 0 59 241 89 0 0 0 12 232 89 0 0 0 0 59 238 34 0 12 235 125 0 0 +0 127 206 125 0 0 0 0 175 206 206 125 0 0 0 0 175 206 206 125 0 0 0 0 175 +206 206 125 0 0 0 0 175 206 206 125 0 0 0 0 175 206 206 125 0 0 0 0 175 +232 245 125 0 0 0 89 255 255 255 255 255 166 0 0 138 255 255 255 251 89 +59 245 255 255 255 255 127 81 245 255 255 255 255 225 21 59 245 255 255 +255 255 127 81 245 255 255 255 255 127 111 255 255 255 125 89 255 255 255 +125 89 255 255 255 125 89 255 255 255 125 7 206 255 255 255 255 125 0 0 +59 241 89 0 0 0 175 251 89 0 0 0 138 255 255 255 166 0 0 0 0 138 255 255 +255 166 0 0 0 0 0 138 255 255 255 166 0 0 0 0 138 255 255 255 166 0 0 0 +0 138 255 255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 0 7 202 194 255 255 255 201 +0 0 0 0 59 245 255 251 89 0 0 0 0 59 245 255 251 89 0 0 0 0 59 245 255 +251 89 0 0 0 0 59 245 255 251 89 0 0 0 0 59 241 89 0 0 0 12 232 89 0 0 +0 0 59 238 47 235 255 166 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 12 228 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 +166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 166 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 +127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 0 +0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 201 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 7 206 +225 21 0 0 0 0 0 12 235 201 0 0 0 138 255 201 0 0 0 59 245 225 29 202 89 +0 0 0 0 0 0 0 0 138 166 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +7 206 225 21 0 0 0 0 0 12 235 201 0 0 0 89 255 225 21 0 0 0 0 0 0 0 0 175 +247 34 0 12 235 255 255 166 0 0 0 0 0 0 0 0 0 0 0 0 59 245 225 29 202 89 +0 0 138 251 89 0 0 0 0 0 7 206 225 21 0 0 0 89 255 225 21 0 0 59 245 225 +29 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 225 +21 0 0 0 0 0 89 255 125 0 0 0 89 255 225 21 0 0 0 0 0 0 0 0 0 0 0 0 138 +251 89 0 59 238 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 175 +166 0 0 0 0 7 206 166 0 0 0 89 225 21 175 201 0 7 202 89 138 255 166 0 +0 89 247 34 175 166 0 0 138 166 7 202 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 7 206 166 0 0 0 0 0 175 166 0 0 0 89 247 34 138 201 0 0 89 247 +34 175 201 0 0 138 201 0 175 200 215 34 235 247 47 232 0 138 255 225 111 +225 21 0 0 172 89 138 255 166 0 0 0 0 89 225 21 0 0 0 0 175 201 0 0 0 0 +89 247 34 138 201 0 0 172 89 138 255 166 0 0 59 238 34 138 201 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175 166 0 0 0 0 59 241 89 0 0 0 89 +247 34 138 201 0 0 0 59 238 34 138 201 0 0 0 89 247 34 0 0 59 238 34 0 +0 0 0 0 138 225 29 206 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 235 255 201 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 206 225 21 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 12 235 166 0 0 0 0 0 0 0 0 89 166 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 238 34 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 7 206 255 255 255 125 0 7 206 255 255 255 +125 0 7 206 255 255 255 125 0 7 206 255 255 255 125 0 7 206 255 255 255 +125 0 12 235 255 255 251 89 0 12 235 255 255 251 89 59 245 255 166 0 0 +59 245 255 255 201 0 12 235 255 251 89 0 0 12 235 255 251 89 0 0 12 235 +255 251 89 0 0 12 235 255 251 89 0 59 238 34 59 238 34 59 238 34 59 238 +34 0 59 241 89 175 225 21 0 59 241 194 255 255 125 0 0 12 235 255 247 34 +0 0 12 235 255 247 34 0 0 0 12 235 255 247 34 0 0 12 235 255 247 34 0 0 +12 235 255 247 34 0 0 0 0 0 12 235 166 0 0 0 0 7 206 255 255 225 21 0 59 +241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 59 241 +89 0 59 241 97 206 166 0 0 12 235 125 59 238 163 255 255 201 7 206 166 +0 0 12 235 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 89 247 34 0 0 0 0 89 247 +34 0 0 0 0 89 247 34 0 0 0 0 89 247 34 0 0 0 0 89 247 34 0 0 0 0 138 225 +21 0 0 0 0 89 255 225 21 0 138 201 59 245 125 0 0 0 7 206 125 0 89 225 +21 7 206 125 0 89 225 21 7 206 125 0 89 225 21 7 206 125 0 89 225 21 59 +238 34 59 238 34 59 238 34 59 238 34 0 0 0 0 12 235 125 0 59 245 166 0 +89 247 34 7 206 166 0 138 225 21 7 206 166 0 138 225 21 0 7 206 166 0 138 +225 21 7 206 166 0 138 225 21 7 206 166 0 138 225 21 0 0 0 0 0 0 0 0 0 +0 12 232 89 0 138 251 89 0 59 241 89 0 59 241 89 59 241 89 0 59 241 89 +59 241 89 0 59 241 89 0 59 241 89 0 59 241 89 89 247 34 0 89 247 34 59 +245 166 0 7 206 166 89 247 34 0 89 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +59 241 89 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 59 241 89 0 0 0 0 +59 241 89 0 0 0 0 59 238 34 0 0 0 0 12 232 89 0 0 59 238 127 225 21 0 0 +0 59 238 34 0 59 238 34 59 238 34 0 59 238 34 59 238 34 0 59 238 34 59 +238 34 0 59 238 34 59 238 34 59 238 34 59 238 34 59 238 34 0 138 255 255 +255 255 201 0 59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 +241 89 0 59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 +89 0 12 235 255 255 255 255 255 255 166 138 201 0 59 157 175 201 0 59 241 +89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 59 241 89 +0 59 241 89 12 235 125 0 175 166 0 59 238 34 0 0 138 225 34 235 125 0 175 +166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 127 0 89 255 255 255 251 89 0 89 255 255 255 251 +89 0 89 255 255 255 251 89 0 89 255 255 255 251 89 0 89 255 255 255 251 +89 0 138 255 255 255 247 34 0 175 255 255 255 255 255 255 255 255 251 127 +201 0 0 0 0 59 245 255 255 255 251 89 59 245 255 255 255 251 89 59 245 +255 255 255 251 89 59 245 255 255 255 251 89 59 238 34 59 238 34 59 238 +34 59 238 34 138 247 34 0 0 138 201 0 59 241 89 0 59 241 89 59 238 34 0 +12 232 89 59 238 34 0 12 232 89 0 59 238 34 0 12 232 89 59 238 34 0 12 +232 89 59 238 34 0 12 232 89 0 0 0 0 0 0 0 0 0 0 175 201 7 176 21 138 201 +0 59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 59 +241 89 0 59 241 89 0 175 201 12 232 89 0 59 238 34 0 0 138 225 21 175 201 +12 232 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 59 241 89 0 59 241 89 59 241 89 0 59 +241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 +138 247 34 0 59 238 34 138 225 21 0 12 232 89 0 0 0 0 138 201 0 0 0 0 59 +238 34 0 0 0 0 59 238 34 0 0 0 0 59 238 34 0 0 0 0 59 238 34 0 0 0 0 59 +238 34 59 238 34 59 238 34 59 238 34 175 201 0 0 0 138 166 0 59 241 89 +0 59 241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 59 241 89 0 59 +241 89 59 241 89 0 59 241 89 59 241 89 0 59 241 89 0 0 0 0 12 235 166 0 +0 0 138 201 134 89 0 175 166 0 59 241 89 0 59 241 89 59 241 89 0 59 241 +89 59 241 89 0 59 241 89 0 59 241 89 0 59 241 89 0 89 247 124 225 21 0 +59 238 34 0 0 138 201 0 89 247 124 225 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 89 247 +34 0 89 251 89 89 247 34 0 89 251 89 89 247 34 0 89 251 89 89 247 34 0 +89 251 89 89 247 34 0 89 251 89 175 201 0 0 175 247 34 175 201 0 0 59 245 +225 21 0 7 199 94 245 125 0 0 0 7 206 166 0 7 199 34 7 206 166 0 7 199 +34 7 206 166 0 7 199 34 7 206 166 0 7 199 34 59 238 34 59 238 34 59 238 +34 59 238 34 138 247 34 0 12 232 89 0 59 241 89 0 59 241 89 7 206 166 0 +138 225 21 7 206 166 0 138 225 21 0 7 206 166 0 138 225 21 7 206 166 0 +138 225 21 7 206 166 0 138 225 21 0 0 0 0 12 235 166 0 0 0 59 245 166 0 +59 241 89 0 12 235 125 0 175 251 89 12 235 125 0 175 251 89 12 235 125 +0 175 251 89 0 12 235 125 0 175 251 89 0 7 206 255 125 0 0 59 238 34 0 +12 235 125 0 7 206 255 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 175 255 255 232 +241 89 0 175 255 255 232 241 89 0 175 255 255 232 241 89 0 175 255 255 +232 241 89 0 175 255 255 232 241 89 12 235 255 255 166 238 34 12 235 255 +255 225 21 89 255 255 251 89 0 89 255 255 255 201 0 12 235 255 251 89 0 +0 12 235 255 251 89 0 0 12 235 255 251 89 0 0 12 235 255 251 89 0 59 238 +34 59 238 34 59 238 34 59 238 34 0 138 255 255 255 125 0 0 59 241 89 0 +59 241 89 0 12 235 255 247 34 0 0 12 235 255 247 34 0 0 0 12 235 255 247 +34 0 0 12 235 255 247 34 0 0 12 235 255 247 34 0 0 0 0 0 0 0 0 0 0 0 7 +206 255 255 225 21 0 0 0 89 255 255 166 241 89 0 89 255 255 166 241 89 +0 89 255 255 166 241 89 0 0 89 255 255 166 241 89 0 0 138 247 34 0 0 59 +245 166 255 255 166 0 0 0 138 247 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 215 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 232 89 0 0 0 59 238 34 0 0 0 0 0 +12 232 89 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 12 235 255 125 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 138 225 21 0 0 0 59 238 34 0 0 0 0 0 138 225 21 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 127 127 0 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 0 127 127 127 127 127 127 0 127 127 0 127 127 0 127 127 +0 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/FontSmall.pgm b/Extras/CDTestFramework/AntTweakBar/src/res/FontSmall.pgm new file mode 100644 index 0000000..23b1f89 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/res/FontSmall.pgm @@ -0,0 +1,603 @@ +P2 +# Created by Paint Shop Pro +211 84 +255 +127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 +0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 255 0 0 0 255 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 255 0 255 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 0 0 255 255 0 0 +0 255 0 0 0 0 255 255 0 0 0 255 0 0 255 0 0 255 0 0 255 0 255 0 255 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 255 0 0 0 255 0 0 255 255 +255 0 0 255 255 255 0 0 0 0 0 255 0 255 255 255 255 0 0 255 255 0 0 255 +255 255 255 0 0 255 255 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 127 0 0 0 0 255 0 255 0 255 0 0 0 255 0 0 255 0 0 255 255 255 255 +0 255 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 255 0 255 0 0 0 0 255 0 0 255 +255 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 255 +255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 255 255 0 255 0 0 0 0 255 0 0 0 0 0 +0 0 255 0 255 0 0 255 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 255 0 0 0 0 0 0 255 255 255 255 255 255 255 0 255 0 0 0 255 0 0 +255 0 255 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 255 0 255 0 255 0 255 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 +0 0 255 0 0 0 0 255 0 0 255 0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 +255 0 0 255 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 255 0 0 0 0 0 0 +0 0 0 255 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +127 0 0 0 0 255 0 0 0 0 0 0 0 255 0 255 0 0 0 255 255 0 0 0 0 255 255 0 +255 0 255 255 0 0 0 255 255 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 +0 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 +0 0 0 0 255 0 0 0 255 255 0 0 255 0 0 255 0 255 255 255 0 0 255 255 255 +0 0 0 0 255 0 0 0 255 255 0 0 0 255 255 255 0 0 255 0 0 255 0 0 0 255 255 +0 0 0 255 255 255 255 255 255 0 0 0 0 255 255 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 255 0 0 0 0 0 255 255 255 255 255 +255 0 0 0 255 255 0 0 0 0 0 255 0 255 0 0 255 0 255 0 0 255 0 0 0 0 255 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 255 0 0 0 0 0 255 0 +0 255 0 0 255 0 0 255 0 0 0 255 0 0 0 0 0 0 255 0 255 255 255 255 255 0 +0 0 255 0 255 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0 0 +255 0 255 0 0 0 0 255 0 255 0 0 255 0 255 0 0 255 255 0 0 0 255 0 0 0 0 +255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 +0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 255 0 +0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 0 255 0 0 255 0 0 255 0 0 0 255 255 +0 0 0 255 255 255 255 255 255 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 255 0 0 0 0 0 0 255 0 0 255 0 0 255 +255 255 255 0 0 0 0 255 0 0 0 255 255 0 0 0 255 255 0 0 255 0 0 255 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 255 +255 0 0 255 255 255 0 255 255 255 255 0 255 255 255 0 0 0 0 0 255 0 255 +255 255 0 0 0 255 255 0 0 255 0 0 0 0 0 255 255 0 0 0 255 255 0 0 0 255 +0 0 255 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 0 127 0 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 +127 127 127 0 127 127 127 127 127 0 127 0 127 127 0 127 127 127 0 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 0 127 127 127 0 127 0 127 +127 127 0 127 127 127 127 0 127 127 127 0 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 0 127 127 127 127 0 127 127 0 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 255 0 0 0 255 255 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 255 255 255 0 0 0 0 0 +255 255 0 0 0 255 255 255 0 0 0 0 0 255 255 255 0 0 255 255 255 255 0 0 +0 255 255 255 255 255 0 255 255 255 255 255 0 0 0 255 255 255 0 0 255 0 +0 0 0 255 0 255 255 255 0 0 255 255 0 255 0 0 0 255 0 255 0 0 0 255 255 +0 0 0 255 255 0 255 0 0 0 0 255 0 0 0 255 255 255 0 0 0 255 255 255 255 +0 0 0 0 255 255 255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 255 255 +255 255 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 255 0 0 255 0 +255 0 0 255 0 255 0 0 0 255 0 255 255 255 255 0 255 0 0 255 0 0 0 0 255 +0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 255 0 +0 0 255 0 0 0 0 255 255 0 0 0 255 0 0 255 0 0 0 255 0 0 0 255 0 255 0 0 +0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 255 +0 0 255 0 0 0 0 255 0 255 0 0 255 0 0 255 0 0 0 255 255 0 0 0 255 255 0 +255 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 +0 0 255 0 0 0 255 0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 255 0 +0 0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 0 0 0 255 +0 255 0 0 0 255 0 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 127 255 0 0 255 255 0 255 0 0 255 0 0 255 0 0 255 0 0 255 +0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 +0 0 0 0 0 255 0 0 0 0 255 0 0 255 0 0 0 0 255 0 255 0 255 0 0 0 255 0 0 +0 255 0 255 0 255 0 255 0 255 0 255 0 0 255 0 255 0 0 0 0 0 255 0 255 0 +0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 0 0 0 0 255 0 0 +0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 255 0 255 0 255 0 0 255 255 +0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 0 255 0 0 0 255 0 255 0 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 255 0 255 0 255 +0 0 255 0 0 255 0 0 255 255 255 255 0 0 255 0 0 0 0 0 0 255 0 0 0 0 255 +0 255 255 255 255 0 0 255 255 255 255 0 0 255 0 0 255 255 255 0 255 255 +255 255 255 255 0 0 255 0 0 0 0 255 0 255 255 0 0 0 0 255 0 0 0 255 0 255 +0 255 0 255 0 255 0 0 255 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 255 0 255 +0 0 0 0 0 255 0 255 255 255 255 0 0 0 255 255 255 0 0 0 0 255 0 0 0 255 +0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 255 0 255 0 255 0 0 255 255 0 0 0 +0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 255 0 255 0 255 0 255 255 255 +255 255 255 0 255 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 +0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 0 0 255 +0 255 0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 255 0 255 0 0 0 255 255 0 255 +0 0 0 0 0 255 0 255 255 255 255 0 0 255 0 0 0 0 0 255 0 255 0 255 0 0 0 +0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 255 +0 255 0 255 0 0 255 255 0 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 +0 0 255 255 255 0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 0 255 0 0 0 255 0 +255 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 +0 0 255 0 0 255 0 0 0 0 255 0 255 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 +255 0 255 0 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 0 0 0 255 0 0 0 255 +0 0 255 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 255 +255 0 0 0 0 255 0 0 0 255 0 0 255 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 255 +0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 127 0 255 0 0 0 0 0 0 255 0 0 0 0 255 0 255 255 255 255 0 0 0 0 255 +255 255 0 0 255 255 255 255 0 0 0 255 255 255 255 255 0 255 0 0 0 0 0 0 +0 255 255 255 255 0 255 0 0 0 0 255 0 255 255 255 0 255 255 0 0 255 0 0 +0 255 0 255 255 255 255 255 0 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 255 255 +255 0 0 0 255 0 0 0 0 0 0 0 255 255 255 0 0 0 255 0 0 0 255 0 255 255 255 +255 0 0 0 0 255 0 0 0 0 255 255 255 255 0 0 0 0 255 255 0 0 0 0 255 0 0 +0 255 0 0 255 0 0 255 0 0 0 255 0 0 0 255 255 255 255 0 255 0 0 0 0 255 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 +0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 +0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 +0 0 0 0 0 255 255 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 +0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 0 +127 127 127 127 127 127 0 127 127 127 0 127 127 127 0 127 127 127 127 127 +0 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 0 +127 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 +0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 0 127 +127 0 127 127 127 0 127 127 0 127 127 127 127 127 0 127 127 127 127 127 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 0 255 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 255 0 0 0 0 0 0 0 255 0 0 +0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 +255 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 4 4 +4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 +0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 +0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 4 4 4 4 12 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +127 0 0 0 0 0 255 255 0 0 255 255 255 0 0 0 255 255 0 0 255 255 255 0 0 +255 255 0 0 255 255 255 0 255 255 255 0 255 255 255 0 0 255 0 255 255 0 +255 0 0 255 0 255 0 255 255 255 0 255 255 0 0 255 255 255 0 0 0 255 255 +0 0 255 255 255 0 0 0 255 255 255 0 255 0 255 255 255 255 0 255 255 0 255 +0 0 255 0 255 0 0 0 255 0 255 0 0 255 0 0 255 0 255 0 255 0 255 0 0 0 255 +0 255 255 255 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 +255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 +255 0 255 0 0 255 0 255 0 0 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 +0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 255 0 0 255 0 255 0 0 255 0 0 +255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 255 0 +255 0 0 0 255 0 0 255 0 0 255 0 0 255 0 255 0 0 255 0 0 255 0 0 255 0 0 +255 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 255 +0 0 255 0 0 255 4 4 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 127 0 0 0 0 0 255 255 255 0 255 0 0 255 0 255 0 0 0 255 0 0 255 0 +255 255 255 255 0 255 0 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 +255 0 0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 +0 255 0 255 0 0 255 0 255 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 +0 0 255 0 255 0 255 0 255 0 0 255 0 0 0 255 0 255 0 0 0 255 0 0 255 0 0 +0 0 255 0 0 0 0 255 0 255 0 0 255 255 0 0 0 255 255 4 255 255 0 4 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 255 0 0 255 0 255 0 +0 255 0 255 0 0 0 255 0 0 255 0 255 0 0 0 0 255 0 0 255 0 0 255 0 255 0 +0 255 0 255 0 0 255 0 255 0 255 0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 +255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 0 0 255 0 255 0 +0 255 0 0 255 0 0 255 0 255 0 0 0 255 255 0 255 255 0 0 0 255 0 0 0 255 +0 255 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 +255 255 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +0 255 255 255 0 255 255 255 0 0 0 255 255 0 0 255 255 255 0 0 255 255 255 +0 255 0 0 0 255 255 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 +0 255 0 0 255 0 0 255 0 255 0 0 255 0 0 255 255 0 0 255 255 255 0 0 0 255 +255 255 0 255 0 0 255 255 255 0 0 255 0 0 255 255 255 0 0 0 255 0 0 0 0 +255 0 0 0 255 0 0 255 0 255 0 0 0 255 0 0 0 255 255 255 0 0 255 0 0 0 255 +0 0 0 255 0 0 0 0 0 0 0 0 0 0 20 0 255 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 +0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 4 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 0 127 127 127 127 0 +127 127 127 127 0 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 +127 0 127 127 127 127 0 127 127 127 127 0 127 0 127 127 0 127 127 127 127 +0 127 0 127 127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 +0 127 127 127 127 0 127 127 127 127 0 127 127 0 127 127 127 0 127 127 0 +127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 0 127 127 127 127 127 0 127 127 127 0 127 127 127 0 127 127 127 +0 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 +255 255 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 +0 255 0 0 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 255 255 255 0 0 255 255 255 255 255 255 255 0 0 0 0 0 0 255 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 255 255 0 0 +0 255 0 0 0 0 0 0 0 255 255 255 255 0 0 0 0 0 255 255 255 255 255 255 255 +0 0 255 255 255 255 255 255 255 0 255 255 255 255 0 0 255 255 255 255 255 +255 255 0 0 255 255 255 255 255 255 255 0 255 0 0 255 255 0 255 0 0 255 +0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 255 255 255 255 0 255 +0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 0 +0 255 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 +255 255 255 255 255 0 255 255 255 255 255 0 0 0 0 0 0 255 0 0 255 0 255 +0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 +255 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 255 +0 0 255 0 255 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +255 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 +0 0 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +255 255 255 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 255 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 255 0 255 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 +0 255 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 255 0 +255 255 255 0 255 0 0 0 255 255 0 255 255 0 0 0 255 0 0 0 0 0 255 0 255 +255 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 +255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 255 255 255 255 255 0 0 0 0 0 0 0 255 255 0 255 0 255 +255 0 255 255 0 0 0 255 255 255 0 0 255 0 0 255 0 0 0 255 255 255 255 0 +0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 255 0 0 255 0 0 255 0 0 255 0 +0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 255 255 255 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 255 +0 0 255 0 0 255 0 0 0 0 0 255 0 255 0 0 255 0 0 0 255 0 0 0 0 0 255 0 0 +0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 255 255 255 0 255 255 255 255 0 255 255 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 255 255 +255 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 255 +0 0 255 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 255 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 255 0 0 0 255 +0 0 0 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 255 0 0 255 0 0 0 0 0 +255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 127 0 255 255 255 0 0 255 255 255 255 255 255 255 0 0 255 +0 255 0 0 0 0 255 0 255 0 255 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 255 0 0 0 255 255 0 255 255 0 0 255 255 255 255 0 0 0 0 0 0 255 +255 255 255 255 255 255 0 0 255 255 255 255 255 255 255 0 255 255 255 255 +0 0 255 255 255 255 255 255 255 0 0 255 255 255 255 255 255 255 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 255 255 255 0 0 0 0 0 255 255 0 255 255 255 0 0 255 255 255 255 255 +255 255 0 255 255 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 255 0 0 0 255 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 0 127 127 +127 127 0 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 +127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 127 +127 127 127 127 0 127 127 127 127 127 0 127 127 0 127 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 127 0 127 127 127 127 0 127 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 0 127 0 127 +127 127 0 127 127 127 0 127 127 127 0 127 127 127 127 0 127 127 127 127 +127 127 127 0 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 +0 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 +0 127 127 127 0 127 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 0 0 0 0 255 0 0 0 255 0 0 0 0 255 255 0 0 0 0 0 0 0 255 0 +0 0 255 0 255 0 0 255 255 255 0 0 255 0 255 0 0 0 255 255 255 255 0 0 255 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 0 0 0 0 0 0 0 +0 255 0 0 0 0 0 0 0 0 0 0 255 255 255 0 255 255 255 0 0 255 0 0 0 0 0 0 +0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 255 0 0 0 0 0 0 0 0 255 +0 0 255 0 0 0 0 0 255 0 0 0 255 0 0 0 255 255 255 0 0 255 0 0 0 0 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 +0 255 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 255 +0 0 0 0 255 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 255 0 255 +0 0 0 0 0 0 0 0 0 0 255 255 0 255 0 0 255 0 0 0 0 0 0 255 255 0 255 0 0 +0 0 0 255 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +127 0 0 0 0 0 255 0 0 255 255 255 0 0 255 0 0 0 0 255 255 255 0 0 0 255 +0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 255 0 0 255 255 0 0 255 255 0 255 +0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 255 255 255 0 0 255 0 0 0 0 0 +0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 255 0 255 +255 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 255 0 255 0 255 0 0 0 255 +0 255 0 0 0 0 0 0 255 0 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 127 0 0 0 0 0 255 0 255 0 255 0 0 255 255 255 0 0 0 255 0 255 +0 0 0 0 255 0 0 0 0 0 255 255 255 0 0 0 0 0 0 0 255 0 255 0 0 0 0 255 0 +255 255 0 255 0 255 0 0 0 255 255 255 255 255 0 0 0 0 255 0 255 0 0 255 +0 255 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 0 0 255 255 255 0 255 255 +0 0 0 0 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 0 0 0 0 0 255 255 255 +0 255 255 0 0 0 255 0 255 0 0 255 255 0 0 255 255 0 0 0 255 0 255 0 255 +255 0 0 255 255 0 255 0 255 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 +255 0 255 0 255 0 0 0 255 0 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 0 +255 0 0 255 0 0 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 0 255 0 255 0 0 0 0 +0 0 0 255 0 255 255 0 255 0 255 255 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 +255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 255 0 0 255 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 255 0 255 0 255 0 0 0 0 255 +0 0 0 0 255 0 0 0 255 0 255 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +0 255 0 255 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 +255 255 255 0 0 0 0 0 0 255 0 0 255 255 0 0 255 0 0 0 0 0 255 0 255 0 0 +0 0 0 0 255 0 0 0 0 255 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 127 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 255 0 0 0 0 255 0 255 255 255 255 0 0 0 255 +0 0 0 255 0 0 0 0 255 0 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 +0 0 0 255 0 0 255 255 255 0 255 255 255 255 0 0 0 0 0 0 0 0 0 255 0 0 0 +255 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 0 0 255 0 255 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 255 +255 0 0 255 0 0 0 0 255 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 +0 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 127 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 +0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 127 127 127 127 0 127 0 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 0 127 127 127 127 +0 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 0 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 0 127 127 127 127 127 127 127 +0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +127 0 127 127 127 0 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 +127 127 0 127 127 127 0 127 127 127 0 127 127 127 127 0 127 127 127 127 +0 127 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 255 0 +0 0 0 0 255 0 0 0 0 0 0 255 0 255 0 0 0 255 0 255 255 0 0 0 255 0 0 255 +0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 +0 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 255 0 0 0 255 0 0 255 0 255 0 255 +0 255 0 0 0 0 0 0 0 0 0 255 0 255 255 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 +0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 255 0 0 0 0 255 0 255 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 255 +0 0 0 255 0 0 255 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 0 0 127 0 0 255 255 +0 0 0 0 0 255 255 0 0 0 0 0 255 255 0 0 0 0 0 255 255 0 0 0 0 0 255 255 +0 0 0 0 0 255 255 0 0 0 0 0 255 255 255 255 255 0 0 0 255 255 255 0 0 255 +255 255 255 255 0 255 255 255 255 255 0 255 255 255 255 255 0 255 255 255 +255 255 0 255 255 255 0 255 255 255 0 255 255 255 0 255 255 255 0 255 255 +255 255 0 0 0 255 0 0 0 0 255 0 0 0 255 255 255 0 0 0 0 0 255 255 255 0 +0 0 0 0 255 255 255 0 0 0 0 0 255 255 255 0 0 0 0 0 255 255 255 0 0 0 0 +0 0 0 0 0 0 0 0 255 255 255 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 +255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 255 0 255 0 0 0 0 255 0 0 +255 0 127 0 0 255 255 0 0 0 0 0 255 255 0 0 0 0 0 255 255 0 0 0 0 0 255 +255 0 0 0 0 0 255 255 0 0 0 0 0 255 255 0 0 0 0 255 0 255 0 0 0 0 0 255 +0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 +0 0 0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 255 0 0 0 255 0 +0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 +255 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 255 0 0 0 +0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 255 0 255 +0 0 255 255 255 0 0 255 0 0 255 0 127 0 255 0 0 255 0 0 0 255 0 0 255 0 +0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 +0 0 255 0 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 +0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 0 +0 255 0 255 0 255 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 255 0 0 0 255 +0 255 0 0 0 255 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 +255 0 255 0 0 0 0 255 0 0 255 0 255 0 0 255 0 0 255 0 255 0 255 0 0 127 +0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 +0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 255 0 255 255 255 255 0 255 0 0 0 +0 0 0 255 255 255 255 0 0 255 255 255 255 0 0 255 255 255 255 0 0 255 255 +255 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 255 255 255 0 0 255 +0 255 0 0 255 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 +0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 255 0 255 0 0 255 +0 0 255 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 +255 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 255 0 255 0 0 255 0 127 255 255 +255 255 255 255 0 255 255 255 255 255 255 0 255 255 255 255 255 255 0 255 +255 255 255 255 255 0 255 255 255 255 255 255 0 255 255 255 255 255 255 +0 0 255 255 255 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 +0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 +0 0 255 0 255 0 0 0 255 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 +0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 255 0 0 0 0 255 0 0 0 +255 0 255 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 +0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 0 0 255 0 255 0 0 255 0 127 255 0 +0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 +0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 255 0 0 0 0 0 255 0 0 0 255 0 255 +0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 +0 255 0 0 0 255 0 0 255 0 0 0 255 0 0 255 0 0 0 0 255 0 0 255 0 0 0 255 +0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 +0 0 255 0 0 0 0 255 0 255 0 0 0 255 0 0 0 255 0 0 255 0 0 0 0 255 0 255 +0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 0 0 255 0 0 0 255 255 +255 0 0 255 0 0 255 0 127 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 +0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 0 0 255 0 255 0 0 255 +255 255 255 0 0 0 255 255 255 0 0 255 255 255 255 255 0 255 255 255 255 +255 0 255 255 255 255 255 0 255 255 255 255 255 0 255 255 255 0 255 255 +255 0 255 255 255 0 255 255 255 0 255 255 255 255 0 0 0 255 0 0 0 0 255 +0 0 0 255 255 255 0 0 0 0 0 255 255 255 0 0 0 0 0 255 255 255 0 0 0 0 0 +255 255 255 0 0 0 0 0 255 255 255 0 0 0 0 255 0 0 0 255 0 255 0 255 255 +255 0 0 0 0 255 255 255 255 0 0 0 255 255 255 255 0 0 0 255 255 255 255 +0 0 0 255 255 255 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 255 0 0 127 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 +127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +0 127 127 127 0 127 127 127 0 127 127 127 0 127 127 127 127 127 127 0 127 +127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 127 0 127 127 127 127 127 127 127 0 127 +127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 +127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 127 0 127 127 127 +127 127 127 0 127 127 127 127 127 127 0 127 127 127 127 127 0 127 127 127 +127 0 127 127 127 127 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 127 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 255 255 0 255 0 +0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 +0 255 0 0 0 0 0 0 0 255 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 255 255 0 255 +0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 255 255 0 255 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 255 +0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 255 +0 0 0 0 255 0 0 0 255 0 255 0 255 0 255 255 0 0 255 0 255 0 0 255 0 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 255 0 255 0 0 255 0 +255 0 0 255 0 255 0 255 0 255 255 0 255 0 0 255 255 0 255 0 255 255 0 0 +0 255 0 0 0 0 255 0 0 0 255 0 255 0 255 0 255 255 0 255 0 0 255 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 255 0 255 0 0 255 0 255 0 +0 0 255 0 0 0 255 0 0 0 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 127 0 255 255 0 0 0 255 255 0 0 0 255 255 0 0 0 255 255 0 0 0 255 +255 0 0 0 255 255 0 0 255 255 255 0 255 255 0 0 0 255 255 0 0 255 255 0 +0 0 255 255 0 0 0 255 255 0 0 0 255 255 0 0 0 255 0 255 0 0 255 0 0 255 +0 0 0 0 255 0 255 255 255 0 0 0 255 255 0 0 0 255 255 0 0 0 255 255 0 0 +0 255 255 0 0 0 255 255 0 0 0 0 0 0 0 0 0 0 255 255 255 0 0 255 0 0 255 +0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 0 255 0 255 255 255 +0 0 255 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 255 0 0 0 +0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 0 0 255 0 0 255 +0 255 0 0 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 0 255 +0 255 0 0 255 0 0 255 0 0 255 255 255 0 255 0 0 255 0 255 0 0 255 0 255 +0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 0 255 255 255 255 255 +0 255 0 0 255 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 +0 0 255 0 255 0 0 255 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 127 0 255 255 255 0 0 255 255 255 0 0 255 255 255 0 0 255 255 255 +0 0 255 255 255 0 0 255 255 255 0 0 255 255 255 255 255 255 0 255 0 0 0 +255 255 255 255 0 255 255 255 255 0 255 255 255 255 0 255 255 255 255 0 +0 255 0 255 0 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 +255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 0 0 0 0 0 0 0 255 +0 255 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 0 +255 0 255 0 0 255 0 0 255 0 0 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 127 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 +255 0 255 0 0 255 0 255 0 0 255 0 0 0 0 255 0 0 0 255 0 0 0 0 255 0 0 0 +0 255 0 0 0 0 255 0 0 0 0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 255 0 255 +0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 0 +0 255 0 0 0 0 255 0 0 0 255 255 0 0 255 0 255 0 0 255 0 255 0 0 255 0 255 +0 0 255 0 255 0 0 255 0 0 255 0 255 0 0 255 0 0 255 0 0 255 0 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 255 255 255 0 0 255 255 255 0 0 255 +255 255 0 0 255 255 255 0 0 255 255 255 0 0 255 255 255 0 0 255 255 0 255 +255 255 0 0 255 255 0 0 255 255 255 0 0 255 255 255 0 0 255 255 255 0 0 +255 255 255 0 0 255 0 255 0 0 255 0 0 255 0 0 255 255 0 0 255 0 0 255 0 +0 255 255 0 0 0 255 255 0 0 0 255 255 0 0 0 255 255 0 0 0 255 255 0 0 0 +0 0 0 0 0 0 0 255 255 255 0 0 0 255 255 255 0 0 255 255 255 0 0 255 255 +255 0 0 255 255 255 0 0 0 255 0 0 0 255 255 255 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0 0 255 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 127 127 127 0 127 127 127 127 0 127 127 +127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 +127 127 127 127 127 0 127 127 127 0 127 127 127 127 0 127 127 127 127 0 +127 127 127 127 0 127 127 127 127 0 127 127 0 127 0 127 127 0 127 127 0 +127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 +127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 127 127 127 +127 0 127 127 127 127 127 0 127 127 127 127 0 127 127 127 127 0 127 127 +127 127 0 127 127 127 127 0 127 127 127 127 127 0 127 127 127 127 0 127 +127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/TwXCursors.h b/Extras/CDTestFramework/AntTweakBar/src/res/TwXCursors.h new file mode 100644 index 0000000..1c45636 --- /dev/null +++ b/Extras/CDTestFramework/AntTweakBar/src/res/TwXCursors.h @@ -0,0 +1,908 @@ +// --------------------------------------------------------------------------- +// +// @file TwXCursors.h +// @brief Bitmaps data for cursors +// @author Philippe Decaudin - http://www.antisphere.com +// @license This file is part of the AntTweakBar library. +// For conditions of distribution and use, see License.txt +// +// note: Private header +// +// --------------------------------------------------------------------------- + + +static int g_CurHot[][2] = +{ + {16, 15}, // curs00 + {16, 15}, // curs01 + {16, 15}, // curs02 + {16, 15}, // curs03 + {16, 15}, // curs04 + {16, 15}, // curs05 + {16, 15}, // curs06 + {16, 15}, // curs07 + {16, 15}, // curs08 + {16, 15}, // curs09 + {16, 15}, // curs10 + {16, 15}, // curs11 + {16, 15}, // curs12 + {16, 15} // curs13 +}; + + +static bool g_CurPict[][32*32] = +{ + { // curs00 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs01 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs02 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs03 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs04 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs05 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs06 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs07 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs08 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs09 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs10 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs11 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs12 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // curs13 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + + +static bool g_CurMask[][32*32] = +{ + { // mask00 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask01 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask02 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask03 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask04 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask05 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask06 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask07 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask08 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask09 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + { // mask10 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask11 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask12 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // mask13 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/cur00000.cur b/Extras/CDTestFramework/AntTweakBar/src/res/cur00000.cur new file mode 100644 index 0000000000000000000000000000000000000000..46c0fbcfe06a5e9a43bf303352a79c5fa5069632 GIT binary patch literal 326 zcmaJ*F%E)25S#-O8>3Xl3a+%Yv>*{*1~K-&$@mfc0i^|DoPmN0<}$mtyEA(SBnXHR z$Z)_V07n34Q7u$r&@q}ZP9ae;4U*GkEv7B7JL!>)7Ry;_=lu;lVuNQk)3y7aTW7s} usr)O@AC}PTl>B_j*N-gvnt53dWqup3`Q;`Hp$Fjr9T<^{F#m@Egrn!!mi=v@fJ55? zH7YzEa0BolEFludC+oA{T)|Js%xnwfFQg)60%E?|y1dMx3(44yk>$5hQ z=MsPOj6DnbHb_=8A4Ue~O5A}pEZ%Sj2Q~CCz>_^6GaY@SIu)v8rTRq|Vt=9MlaK1} TMcFlsp@O5+afde=J`bg18WxrOV!+9<0zpJy?4JuTZFWD1v01v_xF?hxh+y7Bc~h z!F$L#QW`h|H$_L>6{9bzU3@jG5s4C!wQTeZ$_pGy(`Q%fuct@;a&_U{K6hBJ2m9Y9 zr!CPyNImAi^bec#7I}^$-5@e_p&I+Th}X;ryQyWGKgBGeT6Rt937SA6&0;2f0WoNE Ao&W#< literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/cur00005.cur b/Extras/CDTestFramework/AntTweakBar/src/res/cur00005.cur new file mode 100644 index 0000000000000000000000000000000000000000..8e2142ebc032dab4efdb8fee230c16ed760634b5 GIT binary patch literal 326 zcmZvWJr06E6oh91!&WXfwrpu>X$QxmFpQ8&r=zS)?&Ah~%{V@wl0KsctKg)Ur}|v1wq}9yZBFPDy5M zbg`pV&bB4|lm3yE{1C9vc?M>iQ RFjn&{?qXK!$S>cF`~Y7~a!&vN literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/cur00006.cur b/Extras/CDTestFramework/AntTweakBar/src/res/cur00006.cur new file mode 100644 index 0000000000000000000000000000000000000000..02f5aad32e222c0986d3ee0fece0715a47be991d GIT binary patch literal 326 zcmY+8%?ZLl5QX2y9C8qnlL!jgqenZ?UaY_h60iVUu#^Q4mSJEk2wrj!pKn}4^ex}~ zF*7?r1_$qf3MIAE~rDN!B)jT>4v0-Tqi=q*pl%it~&4_j)~Z-HW)kdS(8IKVfjlr V&*CQHo$QsUDXhONYYjI1(Ho$ebOHbX literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/cur00007.cur b/Extras/CDTestFramework/AntTweakBar/src/res/cur00007.cur new file mode 100644 index 0000000000000000000000000000000000000000..59d9b7d6d2ba6411ee1c0ea3859799c4cfb249dd GIT binary patch literal 326 zcmZ9GI}(CG5JY>>&~h;`Az%XoLvJ7fhcZ$!uHrE~%HDv~fTHbLRH~S*H=nMl-T?|2 zVgyPATnsn@I15Q=gz0&7InSw3aXd)Qjk3wbaD&+sA)VB>qRGq-owmN%OC}N6mJ2?+ z{@eN2Mw-)RU&tT&$FKI#4ICeX=sDguOgphRrf`r}iCX%VoK}oA`3?&{uXlW=bXM6f M`^uk_U@r!K09kNuLI3~& literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/cur00008.cur b/Extras/CDTestFramework/AntTweakBar/src/res/cur00008.cur new file mode 100644 index 0000000000000000000000000000000000000000..0785b19f11f97f0211bd1e4e2158d3e6199bfdc6 GIT binary patch literal 326 zcmYk1O^U)m5QSg2E?fw4CBg{Fa+cmeujC05m;-o)IZA^Ik72+Q$ZWC@pI=1-Q_WYe zew%J7E2(Lul`8F$w3hS@lyrc^3F}7xb{Pr6Y`=r>QzNuKcjUct`c=-2G=~L^6%eML zd2~)b5&5i87d5Gc&~YtR<6*%UEa79k!5;omwyn#icG*@Q9x%ZDWZ$m#g+an+Wj|{6 b(1|hMk9XmL~W_ZJxC&i7gT(sSD4!I2*~&oxks|5tun;rX?Ixl6gj2WK~*V zhhYh$J=o&%bOU{0VB)^s-sO*^w)$|+r8nPwo&49W=}Aq{y$ou(upXHF$|^paNQZ^A TlWvZ+V_kJL&dtPI?7w;d-B)kB literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/cur00010.cur b/Extras/CDTestFramework/AntTweakBar/src/res/cur00010.cur new file mode 100644 index 0000000000000000000000000000000000000000..bb8b5f0a6d2026a8353572b98ce08569aba3d0fa GIT binary patch literal 326 zcmah@OA5j;5PcJ+WFZ(3#6_W5y37sg!3r(ZgQY8%UZK$5p$O7(lC)44;tTIH!!Q{@ zfnY6QaD*e^4B#r17H&e47tlmaqQn9Nm^p=SHBv^_z`W+g(#ESFyBTw3 zb4NbA0EY~4Y4E?w4O={Qc3;L84B}A^3q?wg8k$^;G z!0ZLlgA@Js;oUpUiCl^CB&&Z|bU?n1gG|HJUcV(`Qh>blSyE X!^Uv~C%dz1Skin5IWrOpWO2AIOIw@d11#CV34AgR|QWC-tu?l?}R) z3y<0?sg|70hDCG19x3>S-#9ppTc?2<8r4u?P<_peJrT@FH8$U-4InmyE)|nE-1)cF P%=?599m@_^JfQjpiz0Q= literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/AntTweakBar/src/res/cur00013.cur b/Extras/CDTestFramework/AntTweakBar/src/res/cur00013.cur new file mode 100644 index 0000000000000000000000000000000000000000..16356062761e23c7b2b3c6c6dd4e5f11ede2cb48 GIT binary patch literal 326 zcmZur!41P85Ho52 buffer; +int sizes[2]; +btScalar scales[2]; +btScalar offsets[2]; +btScalar wtrs[16]; +btVector3 eye; +btVector3 neardist; +btScalar ocarea; +btScalar qrarea; +GLuint texture; + OcclusionBuffer() + { + initialized=false; + neardist=btVector3(2,2,2); + ocarea=(btScalar)0; + qrarea=(btScalar)0; + } +void setup(int w,int h) + { + initialized=true; + sizes[0]=w; + sizes[1]=h; + scales[0]=w/2; + scales[1]=h/2; + offsets[0]=scales[0]+0.5; + offsets[1]=scales[1]+0.5; + glGenTextures(1,&texture); + clear(); + } +void clear() + { + buffer.resize(0); + buffer.resize(sizes[0]*sizes[1],0); + } +void initialize() + { + if(!initialized) + { + setup(128,128); + } + GLint v[4]; + GLdouble m[16],p[16]; + glGetIntegerv(GL_VIEWPORT,v); + glGetDoublev(GL_MODELVIEW_MATRIX,m); + glGetDoublev(GL_PROJECTION_MATRIX,p); + for(int i=0;i<16;++i) wtrs[i]=p[i]; + clear(); + } +void drawBuffer( btScalar l,btScalar t, + btScalar r,btScalar b) + { + btAlignedObjectArray data; + data.resize(buffer.size()); + for(int i=0;i +static int clip(const btVector4* pi,btVector4* po) + { + btScalar s[NP]; + int m=0; + for(int i=0;i0)&&(t<1)) + { + po[n][0] = a[0]+(b[0]-a[0])*t; + po[n][1] = a[1]+(b[1]-a[1])*t; + po[n][2] = a[2]+(b[2]-a[2])*t; + po[n][3] = a[3]+(b[3]-a[3])*t; + ++n; + } + if(s[j]>0) po[n++]=b; + } + return(n); + } + for(int i=0;i +inline bool draw( const btVector4& a, + const btVector4& b, + const btVector4& c, + const btScalar minarea) + { + const btScalar a2=(b-a).cross(c-a)[2]; + if(a2>0) + { + if(a20) + { + const int dx[]={ y[0]-y[1], + y[1]-y[2], + y[2]-y[0]}; + const int dy[]={ x[1]-x[0]-dx[0]*width, + x[2]-x[1]-dx[1]*width, + x[0]-x[2]-dx[2]*width}; + const int a=x[2]*y[0]+x[0]*y[1]-x[2]*y[1]-x[0]*y[2]+x[1]*y[2]-x[1]*y[0]; + const btScalar ia=1/(btScalar)a; + const btScalar dzx=ia*(y[2]*(z[1]-z[0])+y[1]*(z[0]-z[2])+y[0]*(z[2]-z[1])); + const btScalar dzy=ia*(x[2]*(z[0]-z[1])+x[0]*(z[1]-z[2])+x[1]*(z[2]-z[0]))-(dzx*width); + int c[]={ miy*x[1]+mix*y[0]-x[1]*y[0]-mix*y[1]+x[0]*y[1]-miy*x[0], + miy*x[2]+mix*y[1]-x[2]*y[1]-mix*y[2]+x[1]*y[2]-miy*x[1], + miy*x[0]+mix*y[2]-x[0]*y[2]-mix*y[0]+x[2]*y[0]-miy*x[2]}; + btScalar v=ia*((z[2]*c[0])+(z[0]*c[1])+(z[1]*c[2])); + btScalar* scan=&buffer[miy*sizes[1]]; + for(int iy=miy;iy=0)&&(c[1]>=0)&&(c[2]>=0)) + { + if(POLICY::Process(scan[ix],v)) return(true); + } + c[0]+=dx[0];c[1]+=dx[1];c[2]+=dx[2];v+=dzx; + } + c[0]+=dy[0];c[1]+=dy[1];c[2]+=dy[2];v+=dzy; + scan+=sizes[0]; + } + } + } + return(false); + } +template +inline bool clipDraw( const btVector4* p, + btScalar minarea) + { + btVector4 o[NP*2]; + const int n=clip(p,o); + bool earlyexit=false; + project(o,n); + for(int i=2;i(o[0],o[i-1],o[i],minarea); + } + return(earlyexit); + } +void appendOccluder( const btVector3& a, + const btVector3& b, + const btVector3& c) + { + const btVector4 p[]={transform(a),transform(b),transform(c)}; + clipDraw<3,WriteOCL>(p,ocarea); + } +void appendOccluder( const btVector3& a, + const btVector3& b, + const btVector3& c, + const btVector3& d) + { + const btVector4 p[]={transform(a),transform(b),transform(c),transform(d)}; + clipDraw<4,WriteOCL>(p,ocarea); + } +void appendOccluder( const btVector3& c, + const btVector3& e) + { + const btVector4 x[]={ transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]-e[2])), + transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]-e[2])), + transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]-e[2])), + transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]-e[2])), + transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]+e[2])), + transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]+e[2])), + transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]+e[2])), + transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]+e[2]))}; + static const int d[]={ 1,0,3,2, + 4,5,6,7, + 4,7,3,0, + 6,5,1,2, + 7,6,2,3, + 5,4,0,1}; + for(int i=0;i<(sizeof(d)/sizeof(d[0]));) + { + const btVector4 p[]={ x[d[i++]], + x[d[i++]], + x[d[i++]], + x[d[i++]]}; + clipDraw<4,WriteOCL>(p,ocarea); + } + } +inline bool queryOccluder( const btVector3& a, + const btVector3& b, + const btVector3& c) + { + const btVector4 p[]={transform(a),transform(b),transform(c)}; + return(clipDraw<3,QueryOCL>(p,qrarea)); + } +inline bool queryOccluder( const btVector3& a, + const btVector3& b, + const btVector3& c, + const btVector3& d) + { + const btVector4 p[]={transform(a),transform(b),transform(c),transform(d)}; + return(clipDraw<4,QueryOCL>(p,qrarea)); + } +inline bool queryOccluder( const btVector3& c, + const btVector3& e) + { + const btVector4 x[]={ transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]-e[2])), + transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]-e[2])), + transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]-e[2])), + transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]-e[2])), + transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]+e[2])), + transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]+e[2])), + transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]+e[2])), + transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]+e[2]))}; + for(int i=0;i<8;++i) + { + if((x[i][2]+x[i][3])<=0) return(true); + } + static const int d[]={ 1,0,3,2, + 4,5,6,7, + 4,7,3,0, + 6,5,1,2, + 7,6,2,3, + 5,4,0,1}; + for(int i=0;i<(sizeof(d)/sizeof(d[0]));) + { + const btVector4 p[]={ x[d[i++]], + x[d[i++]], + x[d[i++]], + x[d[i++]]}; + if(clipDraw<4,QueryOCL>(p,qrarea)) return(true); + } + return(false); + } +}; + +OcclusionBuffer ocb; + +BulletSAPCompleteBoxPruningTest::BulletSAPCompleteBoxPruningTest(int numBoxes,int method) : + mBar (null), + mNbBoxes (numBoxes), + mBoxes (null), + mBoxPtrs (null), + mBoxTime (null), + mAmplitude (100.0f), + m_method(method) +{ + btVector3 aabbMin(-200,-200,-200); + btVector3 aabbMax(200,200,200); + + int maxNumBoxes = numBoxes; + m_isdbvt=false; + bool disableRaycastAccelerator = true; + switch (method) + { + case 1: + m_broadphase = new btAxisSweep3(aabbMin,aabbMax,maxNumBoxes,0,disableRaycastAccelerator); + methodname = "btAxisSweep3"; + break; + case 2: + m_broadphase = new btAxisSweep3(aabbMin,aabbMax,maxNumBoxes,new btNullPairCache(),disableRaycastAccelerator); + methodname = "btAxisSweep3+btNullPairCache"; + break; + case 3: + m_broadphase = new btAxisSweep3(aabbMin,aabbMax,maxNumBoxes,new btSortedOverlappingPairCache(),disableRaycastAccelerator); + methodname = "btAxisSweep3+btSortedOverlappingPairCache"; + break; + case 4: + m_broadphase = new btSimpleBroadphase(maxNumBoxes,new btSortedOverlappingPairCache()); + methodname = "btSimpleBroadphase+btSortedOverlappingPairCache"; + break; + case 5: + m_broadphase = new btSimpleBroadphase(maxNumBoxes,new btNullPairCache()); + methodname = "btSimpleBroadphase+btNullPairCache"; + break; + +/* case 6: + { + methodname = "btMultiSapBroadphase"; + btMultiSapBroadphase* multiSap = new btMultiSapBroadphase(maxNumBoxes); + m_broadphase = multiSap; + + btVector3 tmpAabbMin,tmpAabbMax; + + float numP = (float) numParts; + + for (int i=0;igetOverlappingPairCache(),disableRaycastAccelerator); + multiSap->getBroadphaseArray().push_back(childBp); + } + } + } + + // btAxisSweep3* childBp = new btAxisSweep3(aabbMin,aabbMax,maxNumBoxes,multiSap->getOverlappingPairCache()); + // multiSap->getBroadphaseArray().push_back(childBp); + multiSap->buildTree(aabbMin,aabbMax); + + } + break; + */ + case 7: + { + btDbvtBroadphase* pbp=new btDbvtBroadphase(); + m_broadphase = pbp; + pbp->m_deferedcollide = true; /* Faster initialization, set to false after. */ + m_isdbvt = true; + methodname = "dynamic AABB tree, btDbvtBroadphase"; + } + break; + case 8: +// m_broadphase = new btAxisSweep3(aabbMin,aabbMax,maxNumBoxes); +// m_broadphase = new btSimpleBroadphase(maxNumBoxes,new btSortedOverlappingPairCache()); +// m_broadphase = new btCudaBroadphase(aabbMin, aabbMax, 8, 8, 8, 8192, 8192, 64, 16); +// m_broadphase = new btCudaBroadphase(aabbMin, aabbMax, 12, 12, 12, 8192, 8192, 64, 16); +// m_broadphase = new btCudaBroadphase(aabbMin, aabbMax, 16, 16, 16, 8192, 8192, 64, 16); +#ifdef USE_CUDA_BROADPHASE + m_broadphase = new btCudaBroadphase(aabbMin, aabbMax, 24, 24, 24,maxNumBoxes , maxNumBoxes, 64, 16); +// m_broadphase = new btCudaBroadphase(aabbMin, aabbMax, 32, 32, 32, 8192, 8192, 64, 16); + methodname = "btCudaBroadphase"; + break; + + case 9: + m_broadphase = new bt3DGridBroadphase(aabbMin, aabbMax, 24, 24, 24,maxNumBoxes , maxNumBoxes, 64, 16); + methodname = "bt3DGridBroadphase"; + break; +#endif //USE_CUDA_BROADPHASE + + default: + { + + btDbvtBroadphase* pbp=new btDbvtBroadphase(); + m_broadphase = pbp; + pbp->m_deferedcollide = true; /* Faster initialization, set to false after. */ + m_isdbvt = true; + methodname = "dynamic AABB tree, btDbvtBroadphase"; + + //m_broadphase = new btAxisSweep3(aabbMin,aabbMax,numBoxes,new btNullPairCache()); + //methodname = "btAxisSweep3+btNullPairCache"; + } + } +} + +BulletSAPCompleteBoxPruningTest::~BulletSAPCompleteBoxPruningTest() +{ + DELETEARRAY(mBoxTime); + DELETEARRAY(mBoxPtrs); + DELETEARRAY(mBoxes); + delete m_broadphase; +} + +void BulletSAPCompleteBoxPruningTest::Init() +{ + btClock clock; + m_firstTime = true; + SRand(0); + + + mBoxes = new AABB[mNbBoxes]; + mFlags = new bool[mNbBoxes]; + mBoxPtrs = new const AABB*[mNbBoxes]; + mBoxTime = new float[mNbBoxes]; + for(udword i=0;icreateProxy(aabbMin,aabbMax,shapeType,&mBoxes[i],1,1,0,0);//m_dispatcher); + m_proxies.push_back( proxy ); + + mBoxTime[i] = 2000.0f*UnitRandomFloat(); + } + printf("Initialization of %s with %u boxes: %ums\r\n",methodname,mNbBoxes,clock.getTimeMilliseconds()); +} + +void BulletSAPCompleteBoxPruningTest::Release() +{ + DELETEARRAY(mBoxTime); + DELETEARRAY(mBoxes); +} + +extern int doTree; +extern int percentUpdate; +extern float objectSpeed; +extern bool enableDraw; + +static void TW_CALL NormalMode(void* pdata) +{ +btDbvtBroadphase* pb=(btDbvtBroadphase*)pdata; +pb->m_deferedcollide = true; +} + +static void TW_CALL SlowSpeedMode(void* pdata) +{ +btDbvtBroadphase* pb=(btDbvtBroadphase*)pdata; +pb->m_deferedcollide = false; +} + +void BulletSAPCompleteBoxPruningTest::Select() +{ + // Create a tweak bar + { + mBar = TwNewBar("OPC_CompleteBoxPruning"); + TwAddVarRW(mBar, "Speed", TW_TYPE_FLOAT, &objectSpeed, " min=0.0 max=0.01 step=0.0001"); + TwAddVarRW(mBar, "Amplitude", TW_TYPE_FLOAT, &mAmplitude, " min=10.0 max=200.0 step=0.1"); + if(m_isdbvt) + { + btDbvtBroadphase* pbp=(btDbvtBroadphase*)m_broadphase; + TwAddVarRW(mBar, "Enable culling",TW_TYPE_BOOLCPP,&enableCulling,""); + TwAddVarRW(mBar, "Enable occlusion",TW_TYPE_BOOLCPP,&enableOcclusion,""); + TwAddVarRW(mBar, "Show culling",TW_TYPE_BOOLCPP,&showCulling,""); + TwAddVarRW(mBar, "Show occlusion",TW_TYPE_BOOLCPP,&showOcclusion,""); + TwAddVarRW(mBar, "Cull far plane",TW_TYPE_BOOLCPP,&cullFarPlane,""); + TwAddVarRW(mBar, "OC Min area",TW_TYPE_FLOAT,&ocb.ocarea,"min=0.0 max=1.0 step=0.001"); + TwAddVarRW(mBar, "QR Min area",TW_TYPE_FLOAT,&ocb.qrarea,"min=0.0 max=1.0 step=0.001"); + TwAddVarRW(mBar, "Dyn lkhd",TW_TYPE_INT32,&pbp->m_sets[0].m_lkhd,"min=-1 max=32"); + TwAddVarRW(mBar, "Fix lkhd",TW_TYPE_INT32,&pbp->m_sets[1].m_lkhd,"min=-1 max=32"); + TwAddVarRW(mBar, "Dyn opt/f(%)",TW_TYPE_INT32,&pbp->m_dupdates,"min=0 max=100"); + TwAddVarRW(mBar, "Fix opt/f(%)",TW_TYPE_INT32,&pbp->m_fupdates,"min=0 max=100"); + TwAddVarRW(mBar, "Cln opt/f(%)",TW_TYPE_INT32,&pbp->m_cupdates,"min=0 max=100"); + TwAddVarRW(mBar, "Prediction",TW_TYPE_FLOAT,&pbp->m_prediction,"min=0.0 max=2.0 step=0.1"); + TwAddVarRW(mBar, "Defered collide",TW_TYPE_BOOLCPP,&pbp->m_deferedcollide,""); + TwAddVarRO(mBar, "Dyn leafs",TW_TYPE_INT32,&pbp->m_sets[0].m_leaves,""); + TwAddVarRO(mBar, "Fix leafs",TW_TYPE_INT32,&pbp->m_sets[1].m_leaves,""); + TwAddVarRO(mBar, "Updates ratio",TW_TYPE_FLOAT,&pbp->m_updates_ratio,""); + TwAddVarRO(mBar, "Visible",TW_TYPE_INT32,&visiblecount,""); + TwAddButton(mBar,"Normal mode",&NormalMode,m_broadphase,""); + TwAddButton(mBar,"Slow speed mode",&SlowSpeedMode,m_broadphase,""); + } + } + printf("SubMethod: %s\r\n",methodname); +} + +void BulletSAPCompleteBoxPruningTest::Deselect() +{ + if(mBar) + { + TwDeleteBar(mBar); + mBar = null; + } +} + +bool BulletSAPCompleteBoxPruningTest::UpdateBoxes(int numBoxes) +{ + static bool once=true; + + for(udword i=0;i<(udword)numBoxes;i++) + { + mBoxTime[i] += objectSpeed; + + Point Center,Extents; + mBoxes[i].GetExtents(Extents); + + Center.x = cosf(mBoxTime[i]*2.17f)*mAmplitude + sinf(mBoxTime[i])*mAmplitude*0.5f; + Center.y = cosf(mBoxTime[i]*1.38f)*mAmplitude + sinf(mBoxTime[i]*mAmplitude); + Center.z = sinf(mBoxTime[i]*0.777f)*mAmplitude; + + mBoxes[i].SetCenterExtents(Center, Extents); + } + return true; +} + +void BulletSAPCompleteBoxPruningTest::PerformTest() +{ + int numUpdatedBoxes = (mNbBoxes*percentUpdate)/100; + if (m_firstTime) + { + numUpdatedBoxes = mNbBoxes; + } + mProfiler.Start(); + UpdateBoxes(numUpdatedBoxes); + + + mPairs.ResetPairs(); + + //CompleteBoxPruning(mNbBoxes, mBoxPtrs, mPairs, Axes(AXES_XZY)); + ///add batch query? + + + for (int i=0;iGetCenter(Center); + mBoxPtrs[i]->GetExtents(Extents); + btVector3 aabbMin(Center.x-Extents.x,Center.y-Extents.y,Center.z-Extents.z); + btVector3 aabbMax(Center.x+Extents.x,Center.y+Extents.y,Center.z+Extents.z); + m_broadphase->setAabb(m_proxies[i],aabbMin,aabbMax,0);//m_dispatcher); + } + +#ifndef BT_NO_PROFILE + if(sBulletProfilerToggle) + { + CProfileManager::Reset(); + } +#endif //BT_NO_PROFILE + + m_broadphase->calculateOverlappingPairs(0); + +#ifndef BT_NO_PROFILE + if(sBulletProfilerToggle) + { + CProfileManager::Increment_Frame_Counter(); + CProfileManager::dumpAll(); + } +#endif //BT_NO_PROFILE + + + mProfiler.End(); + mProfiler.Accum(); + + if (m_firstTime) + { + //initialization messes up timings + m_firstTime = false; + if(m_isdbvt) + { + ((btDbvtBroadphase*)m_broadphase)->m_deferedcollide=false; + } + mProfiler.Reset(); + } + + #if 0 + { + int missedpairs=0; + for(int i=0;iaabb,pb->aabb)) + { + btDbvtProxy* spa=pa; + btDbvtProxy* spb=pb; + if(spa>spb) btSwap(spa,spb); + if(!m_broadphase->getOverlappingPairCache()->findPair(spa,spb)) + { + ++missedpairs; + printf("Cannot find %i,%i\r\n",i,j); + } + } + } + } + if(missedpairs>0) printf("Missed pairs: %u\r\n",missedpairs); + } + #endif + +// printf("%d pairs colliding\r ", mPairs.GetNbPairs()); + + ZeroMemory(mFlags,sizeof(bool)*mNbBoxes); + + btOverlappingPairCache* pairCache = m_broadphase->getOverlappingPairCache(); + const btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr(); + + for(udword i=0;i<(udword)pairCache->getNumOverlappingPairs();i++) + { +// Flags[pairPtr[i].m_pProxy0->getUid()-1] = true; +// Flags[pairPtr[i].m_pProxy1->getUid()-1] = true; + int j; + j=((AABB*)pairPtr[i].m_pProxy0->m_clientObject)-mBoxes; + mFlags[j] = true; + j=((AABB*)pairPtr[i].m_pProxy1->m_clientObject)-mBoxes; + mFlags[j] = true; + } + + if(enableDraw) + { + btVector3 aabbMin(-200,-200,-200); + btVector3 aabbMax(200,200,200); + + btVector3 tmpAabbMin,tmpAabbMax; + glDisable(GL_DEPTH_TEST); + + + float numP = (float) numParts; + + for (int i=0;igetOverlappingPairCache()->getNumOverlappingPairs()); + +// m_broadphase)->printStats(); + + GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer); +} + +// +static void DrawVolume(const btDbvtVolume& volume,const btVector3& color) +{ +const btVector3 mins=volume.Mins(); +const btVector3 maxs=volume.Maxs(); +glColor3f(color.x(),color.y(),color.z()); +glVertex3f(mins.x(),mins.y(),mins.z()); +glVertex3f(maxs.x(),mins.y(),mins.z()); + +glVertex3f(maxs.x(),mins.y(),mins.z()); +glVertex3f(maxs.x(),maxs.y(),mins.z()); + +glVertex3f(maxs.x(),maxs.y(),mins.z()); +glVertex3f(mins.x(),maxs.y(),mins.z()); + +glVertex3f(mins.x(),maxs.y(),mins.z()); +glVertex3f(mins.x(),mins.y(),mins.z()); + +glVertex3f(mins.x(),mins.y(),maxs.z()); +glVertex3f(maxs.x(),mins.y(),maxs.z()); + +glVertex3f(maxs.x(),mins.y(),maxs.z()); +glVertex3f(maxs.x(),maxs.y(),maxs.z()); + +glVertex3f(maxs.x(),maxs.y(),maxs.z()); +glVertex3f(mins.x(),maxs.y(),maxs.z()); + +glVertex3f(mins.x(),maxs.y(),maxs.z()); +glVertex3f(mins.x(),mins.y(),maxs.z()); + +glVertex3f(mins.x(),mins.y(),mins.z()); +glVertex3f(mins.x(),mins.y(),maxs.z()); + +glVertex3f(maxs.x(),mins.y(),mins.z()); +glVertex3f(maxs.x(),mins.y(),maxs.z()); + +glVertex3f(maxs.x(),maxs.y(),mins.z()); +glVertex3f(maxs.x(),maxs.y(),maxs.z()); + +glVertex3f(mins.x(),maxs.y(),mins.z()); +glVertex3f(mins.x(),maxs.y(),maxs.z()); +} + +// +void BulletSAPCompleteBoxPruningTest::RenderAll() +{ +OBB CurrentBox; +CurrentBox.mRot.Identity(); +for(udword i=0;iqueryOccluder(node->volume.Center(),node->volume.Extents())); + } + void Process(const btDbvtNode* node,btScalar depth) + { + Process(node); + } + void Process(const btDbvtNode* leaf) + { + btBroadphaseProxy* proxy=(btBroadphaseProxy*)leaf->data; + int i=((AABB*)proxy->m_clientObject)-self->mBoxes; + if(self->mFlags[i]) glColor3f(1.0f, 0.0f, 0.0f); + else glColor3f(0.0f, 1.0f, 0.0f); + self->mBoxes[i].GetCenter(box.mCenter); + self->mBoxes[i].GetExtents(box.mExtents); + DrawOBB(box);drawn++; + if(ocb) + { + ocb->appendOccluder(btVector3(box.mCenter.x,box.mCenter.y,box.mCenter.z), + btVector3(box.mExtents.x,box.mExtents.y,box.mExtents.z)); + } + } + } srenderer; + srenderer.self=this; + srenderer.ocb=0; + if(enableOcclusion) + { + srenderer.ocb=&ocb; + btDbvt::collideOCL(pbp->m_sets[1].m_root,planes_n,planes_o,dir,acplanes,srenderer); + btDbvt::collideOCL(pbp->m_sets[0].m_root,planes_n,planes_o,dir,acplanes,srenderer); + } + else + { + btDbvt::collideKDOP(pbp->m_sets[1].m_root,planes_n,planes_o,acplanes,srenderer); + btDbvt::collideKDOP(pbp->m_sets[0].m_root,planes_n,planes_o,acplanes,srenderer); + } + visiblecount=srenderer.drawn; + if(showOcclusion&&enableOcclusion) + { + const btScalar ratio=((float)glutGet(GLUT_WINDOW_HEIGHT))/((float)glutGet(GLUT_WINDOW_WIDTH)); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1,1,-1,1,-1,1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + const float mm[]={ 1,0,0,0, + 0,1,0,0, + 0,0,0,1, + 0,0,0,1}; + glMultMatrixf(mm); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + const float size=0.6f; + const float orgx=0.3f; + const float orgy=0.25f; + const float left=orgx; + const float right=orgx+size; + const float top=orgy+size; + const float bottom=orgy; + ocb.drawBuffer(left,bottom,right,top); + } + if(showCulling) + { + const btScalar ratio=((float)glutGet(GLUT_WINDOW_HEIGHT))/((float)glutGet(GLUT_WINDOW_WIDTH)); + static const float scale=0.004; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1,1,-1*ratio,1*ratio,-1,1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + const float mm[]={ 1,0,0,0, + 0,0,1,0, + 0,1,0,0, + 0,0,0,1}; + glMultMatrixf(mm); + glScalef(scale,scale,scale); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glBegin(GL_LINES); + glColor4f(1,1,1,1); + + struct DebugRenderer : btDbvt::ICollide + { + OcclusionBuffer* ocb; + int sid; + bool AllLeafs(const btDbvtNode* node) + { + Process(node); + return(false); + } + bool Descent(const btDbvtNode* node) + { + return(ocb->queryOccluder(node->volume.Center(),node->volume.Extents())); + } + void Process(const btDbvtNode* node,btScalar depth) + { + Process(node); + } + void Process(const btDbvtNode* node) + { + if(ocb) + { + ocb->appendOccluder(node->volume.Center(),node->volume.Extents()); + } + if(sid>=0) + { + const float f=sid/1023.; + DrawVolume(node->volume,btVector3(1,f,f)); + sid=(sid+1)%1024; + } + else + { + if(node->isinternal()) + DrawVolume(node->volume,btVector3(0,1,0)); + else + DrawVolume(node->volume,btVector3(1,0,1)); + } + } + } drenderer; + if(enableOcclusion) + { + drenderer.ocb=&ocb; + drenderer.sid=0; + ocb.clear(); + btDbvt::collideOCL(pbp->m_sets[1].m_root,planes_n,planes_o,dir,acplanes,drenderer); + btDbvt::collideOCL(pbp->m_sets[0].m_root,planes_n,planes_o,dir,acplanes,drenderer); + } + else + { + drenderer.ocb=0; + drenderer.sid=-1; + btDbvt::collideKDOP(pbp->m_sets[1].m_root,planes_n,planes_o,acplanes,drenderer); + btDbvt::collideKDOP(pbp->m_sets[0].m_root,planes_n,planes_o,acplanes,drenderer); + } + glEnd(); + + glBegin(GL_LINES); + glColor4f(1,1,1,1); + glVertex3f(eye.x(),eye.y(),eye.z()); + glVertex3f(x00.x(),x00.y(),x00.z()); + glVertex3f(eye.x(),eye.y(),eye.z()); + glVertex3f(x10.x(),x10.y(),x10.z()); + glVertex3f(eye.x(),eye.y(),eye.z()); + glVertex3f(x01.x(),x01.y(),x01.z()); + glVertex3f(eye.x(),eye.y(),eye.z()); + glVertex3f(x11.x(),x11.y(),x11.z()); + + glVertex3f(x00.x(),x00.y(),x00.z()); + glVertex3f(x10.x(),x10.y(),x10.z()); + + glVertex3f(x10.x(),x10.y(),x10.z()); + glVertex3f(x11.x(),x11.y(),x11.z()); + + glVertex3f(x11.x(),x11.y(),x11.z()); + glVertex3f(x01.x(),x01.y(),x01.z()); + + glVertex3f(x01.x(),x01.y(),x01.z()); + glVertex3f(x00.x(),x00.y(),x00.z()); + glEnd(); + } + } +} + +void BulletSAPCompleteBoxPruningTest::KeyboardCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case 'p': + case 'P': + sBulletProfilerToggle = !sBulletProfilerToggle; + break; + default : break; + } +} + +void BulletSAPCompleteBoxPruningTest::MouseCallback(int button, int state, int x, int y) +{ +} + +void BulletSAPCompleteBoxPruningTest::MotionCallback(int x, int y) +{ +} diff --git a/Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.h b/Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.h new file mode 100644 index 0000000..e944d19 --- /dev/null +++ b/Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.h @@ -0,0 +1,65 @@ +/* +BulletSAPCompleteBoxPruningTest, Copyright (c) 2008 Erwin Coumans +Part of: +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BULLET_SAP_COMPLETEBOXPRUNING_H +#define BULLET_SAP_COMPLETEBOXPRUNING_H + +#include "LinearMath/btAlignedObjectArray.h" + +#include "CollisionTest.h" +#include "Profiling.h" + + class BulletSAPCompleteBoxPruningTest : public CollisionTest + { + public: + BulletSAPCompleteBoxPruningTest(int numBoxes,int method); + virtual ~BulletSAPCompleteBoxPruningTest(); + + virtual void Init(); + virtual void Release(); + virtual void PerformTest(); + void RenderAll(); + void Render(); + virtual void Select(); + virtual void Deselect(); + virtual void KeyboardCallback(unsigned char key, int x, int y); + virtual void MouseCallback(int button, int state, int x, int y); + virtual void MotionCallback(int x, int y); + + TwBar* mBar; //!< AntTweakBar + Profiler mProfiler; + + class btBroadphaseInterface* m_broadphase; + bool m_isdbvt; + btAlignedObjectArray m_proxies; + + udword mNbBoxes; + AABB* mBoxes; + bool* mFlags; + const char* methodname; + const AABB** mBoxPtrs; + Pairs mPairs; + float* mBoxTime; + float mAmplitude; + bool m_firstTime; + int m_method; + + private: + bool UpdateBoxes(int numBoxes); + }; + +#endif // BULLET_SAP_COMPLETEBOXPRUNING_H diff --git a/Extras/CDTestFramework/CDTestFramework.cpp b/Extras/CDTestFramework/CDTestFramework.cpp new file mode 100644 index 0000000..2b574c8 --- /dev/null +++ b/Extras/CDTestFramework/CDTestFramework.cpp @@ -0,0 +1,448 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" + +#include "CollisionTest.h" +#include "SphereMeshQuery.h" +#include "OBBMeshQuery.h" +#include "CapsuleMeshQuery.h" +#include "CompleteBoxPruning.h" +#include "BulletSAPCompleteBoxPruningTest.h" +#include "BulletSAPCompleteBoxPruningTest.h" +#include "BipartiteBoxPruning.h" +#include "OpcodeArraySAPTest.h" +#include "RenderingHelpers.h" +#include "Terrain.h" +#include "Camera.h" +#include "GLFontRenderer.h" +#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h" +#include "LinearMath/btQuickprof.h" + +#define NUM_SAP_BOXES 8192 +//#define NUM_SAP_BOXES 16384 +//#define NUM_SAP_BOXES 1024 + +int percentUpdate = 100; +//float objectSpeed = 0.005f; +float objectSpeed = 0.01f; +bool enableDraw = true; + +//Broadphase comparison +//Static case (updating 10% of objects to same position ( -> no swaps) +//number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP +//1024 0.35ms, 0.03ms, 0.15ms +//8192 21ms, 0.2ms, 5ms +//16384 92ms , 0.5ms, 28ms + +//Dynamic case, 10% objects are moving as fast as this testbed allows (0.01?) +//number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP +//1024 0.35ms, 0.2ms, 0.25ms +//8192 21ms , 15ms , 13ms +//16384 92ms, 80ms, 49ms + + +#define WINDOW_WIDTH 1024 +#define WINDOW_HEIGHT 768 + +static int gMouseX = 0; +static int gMouseY = 0; +static int gButton = 0; + +static TwBar* gMainBar = null; +enum TestIndex +{ +// TEST_SPHERE_MESH_QUERY, +// TEST_OBB_MESH_QUERY, +// TEST_CAPSULE_MESH_QUERY, +// TEST_COMPLETE_BOX_PRUNING=0, + TEST_COMPLETE_BOX_PRUNING_8192, +// TEST_BULLET_SAP_1024, +// TEST_BULLET_SAP_8192, +// TEST_BULLET_SAP_SORTEDPAIRS_8192, +// TEST_BULLET_MULTISAP_8192, +// TEST_BIPARTITE_BOX_PRUNING, + TEST_DBVT_8192, + TEST_BULLET_CUDA_8192, + TEST_BULLET_3DGRID_8192, + TEST_OPCODE_ARRAY_SAP, + MAX_NB_TESTS +}; + +//static int gTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192; +//static int gSelectedTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192; +static int gTest = TEST_BULLET_CUDA_8192; +static int gSelectedTest = TEST_BULLET_CUDA_8192; +static CollisionTest* gCollisionTests[MAX_NB_TESTS]; + +static GLFontRenderer gFnt; + +///////////////// + +static void KeyboardCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case 27: exit(0); break; + + case '+': + { + if(gTest!=MAX_NB_TESTS-1) + { + gCollisionTests[gTest]->Deselect(); + gTest++; + gSelectedTest++; + gCollisionTests[gTest]->Select(); + } + } + break; + + case '-': + { + if(gTest) + { + gCollisionTests[gTest]->Deselect(); + gTest--; + gSelectedTest--; + gCollisionTests[gTest]->Select(); + } + } + break; + + case 101: MoveCameraForward(); break; + case 103: MoveCameraBackward(); break; + case 100: MoveCameraRight(); break; + case 102: MoveCameraLeft(); break; + default: gCollisionTests[gTest]->KeyboardCallback(key, x, y); break; + } + + TwEventKeyboardGLUT(key, x, y); +} + +static void ArrowKeyCallback(int key, int x, int y) +{ + KeyboardCallback(key, x, y); + + TwEventSpecialGLUT(key, x, y); +} + +static void MouseCallback(int button, int state, int x, int y) +{ + gButton = button; + gMouseX = x; + gMouseY = y; + + if(!TwEventMouseButtonGLUT(button, state, x, y)) + { + gCollisionTests[gTest]->MouseCallback(button, state, x, y); + } +} + +static void MotionCallback(int x, int y) +{ + if(!TwEventMouseMotionGLUT(x, y)) + { + if(gButton==2) + { + int dx = gMouseX - x; + int dy = gMouseY - y; + + RotateCamera(dx, dy); + + gMouseX = x; + gMouseY = y; + } + else + gCollisionTests[gTest]->MotionCallback(x, y); + } +} + +static void RenderCallback() +{ + // Clear buffers + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Setup camera + glMatrixMode(GL_PROJECTION); + SetupCameraMatrix(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_LIGHTING); + + if(0 /*gRenderWireframe*/) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + gCollisionTests[gTest]->PerformTest(); + + // Draw tweak bars + TwDraw(); + + glutSwapBuffers(); + glutPostRedisplay(); + + if(gSelectedTest!=gTest) + { + gCollisionTests[gTest]->Deselect(); + gTest = gSelectedTest; + gCollisionTests[gTest]->Select(); + } +} + +static void ReshapeCallback(int width, int height) +{ + glViewport(0, 0, width, height); + + // Send the new window size to AntTweakBar + TwWindowSize(width, height); +} + +static void IdleCallback() +{ + glutPostRedisplay(); +} + +static void Terminate() +{ + ReleaseTerrain(); + + for(int i=0;iRelease(); + DELETESINGLE(gCollisionTests[i]); + } + + if(gMainBar) + { + TwDeleteBar(gMainBar); + gMainBar = null; + } + + TwTerminate(); +} + +int myGlutModifiers() +{ + return glutGetModifiers(); +} +int main(int argc, char** argv) +{ + { + ::SetPriorityClass(::GetCurrentProcess(),REALTIME_PRIORITY_CLASS); + /*btDbvt::benchmark(); + exit(0);*/ + } + // Initialize AntTweakBar + // (note that AntTweakBar could also be intialize after GLUT, no matter) + if(!TwInit(TW_OPENGL, NULL)) + { + // A fatal error occured + fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError()); + } + + // Initialize Glut + glutInit(&argc, argv); + glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + int mainHandle = glutCreateWindow("CD Test Framework"); + +/* HWND hWnd; + hWnd = FindWindow("GLUT", "CD Test Framework"); + RECT Rect; + GetWindowRect(hWnd, &Rect); +*/ + glutCreateMenu(NULL); + glutSetWindow(mainHandle); + glutDisplayFunc(RenderCallback); + glutReshapeFunc(ReshapeCallback); + glutIdleFunc(IdleCallback); + glutKeyboardFunc(KeyboardCallback); + glutSpecialFunc(ArrowKeyCallback); + glutMouseFunc(MouseCallback); + glutMotionFunc(MotionCallback); + atexit(Terminate); // Called after glutMainLoop ends + + glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT); + TwGLUTModifiersFunc(myGlutModifiers); + + // Setup default render states + glClearColor(0.3f, 0.4f, 0.5f, 1.0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_CULL_FACE); + glDepthFunc(GL_LEQUAL); + + // Setup lighting + glEnable(GL_LIGHTING); + float AmbientColor[] = { 0.0f, 0.1f, 0.2f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor); + float DiffuseColor[] = { 1.0f, 1.0f, 1.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor); + float SpecularColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor); + float Position[] = { -10.0f, 1000.0f, -4.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, Position); + glEnable(GL_LIGHT0); + + gFnt.init(); + gFnt.setScreenResolution(WINDOW_WIDTH, WINDOW_HEIGHT); + gFnt.setColor(1.0f, 1.0f, 1.0f, 1.0f); + + CreateTerrain(); + + // Create main tweak bar + { + gMainBar = TwNewBar("CollisionTests"); + TwEnumVal testEV[MAX_NB_TESTS] = { +// {TEST_SPHERE_MESH_QUERY, "Sphere-mesh query"}, +// {TEST_OBB_MESH_QUERY, "OBB-mesh query"}, +// {TEST_CAPSULE_MESH_QUERY, "Capsule-mesh query"}, +// {TEST_COMPLETE_BOX_PRUNING, "OPCODE SAP 1024"}, + {TEST_COMPLETE_BOX_PRUNING_8192, "OPCODE BOX PRUNING 8192"}, +// {TEST_BULLET_SAP_1024, "Bullet SAP HASHPAIR 1024"}, +// {TEST_BULLET_SAP_8192, "Bullet SAP HASHPAIR 8192"}, +// {TEST_BULLET_SAP_SORTEDPAIRS_8192, "Bullet SAP SORTEDPAIR 8192"}, +// {TEST_BULLET_MULTISAP_8192, "Bullet MultiSAP 8192"}, +// {TEST_BIPARTITE_BOX_PRUNING, "Bipartite box pruning"}, + {TEST_DBVT_8192, "Bullet DBVT 8192"}, + {TEST_BULLET_CUDA_8192, "Bullet CUDA 8192"}, + {TEST_BULLET_3DGRID_8192, "Bullet 3D Grid 8192"}, + {TEST_OPCODE_ARRAY_SAP, "OPCODE ARRAY SAP"}, + }; + TwType testType = TwDefineEnum("CollisionTest", testEV, MAX_NB_TESTS); + TwAddVarRW(gMainBar, "CollisionTests", testType, &gSelectedTest, ""); + TwAddVarRW(gMainBar, "% of updates",TW_TYPE_INT32,&percentUpdate,"min=0 max=100"); + TwAddVarRW(gMainBar, "Draw",TW_TYPE_BOOLCPP,&enableDraw,""); + } + + // Create tests + gTest = 0; +// gCollisionTests[TEST_SPHERE_MESH_QUERY] = new SphereMeshQuery; +// gCollisionTests[TEST_OBB_MESH_QUERY] = new OBBMeshQuery; +// gCollisionTests[TEST_CAPSULE_MESH_QUERY] = new CapsuleMeshQuery; +// gCollisionTests[TEST_COMPLETE_BOX_PRUNING] = new CompleteBoxPruningTest(NUM_SAP_BOXES); + // gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES); + gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES); +// gCollisionTests[TEST_BULLET_SAP_1024] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1); +// gCollisionTests[TEST_BULLET_SAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1); +// gCollisionTests[TEST_BULLET_SAP_SORTEDPAIRS_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,3); +// gCollisionTests[TEST_BULLET_MULTISAP_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,6); +// gCollisionTests[TEST_BIPARTITE_BOX_PRUNING] = new BipartiteBoxPruningTest; + gCollisionTests[TEST_DBVT_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,7); + gCollisionTests[TEST_BULLET_CUDA_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,8); + gCollisionTests[TEST_BULLET_3DGRID_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,9); + gCollisionTests[TEST_OPCODE_ARRAY_SAP] = new OpcodeArraySAPTest(NUM_SAP_BOXES); + + for(int i=0;iInit(); + gCollisionTests[gTest]->Select(); + + // + MotionCallback(0,0); + + // Run + glutMainLoop(); + + return 0; +} + + +#ifdef OLDIES + +#include "btBulletCollisionCommon.h" + +class BulletMeshInterface : public btStridingMeshInterface +{ + public: + /// get read and write access to a subpart of a triangle mesh + /// this subpart has a continuous array of vertices and indices + /// in this way the mesh can be handled as chunks of memory with striding + /// very similar to OpenGL vertexarray support + /// make a call to unLockVertexBase when the read and write access is finished + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) + { + numverts = gTerrainData->nbVerts; + (*vertexbase) = (unsigned char *)gTerrainData->verts; + type = PHY_FLOAT; + stride = sizeof(Point); + + numfaces = gTerrainData->nbFaces; + (*indexbase) = (unsigned char *)gTerrainData->faces; + indicestype = PHY_INTEGER; + indexstride = 3*sizeof(udword); // ?? + } + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const + { + numverts = gTerrainData->nbVerts; + (*vertexbase) = (unsigned char *)gTerrainData->verts; + type = PHY_FLOAT; + stride = sizeof(Point); + + numfaces = gTerrainData->nbFaces; + (*indexbase) = (unsigned char *)gTerrainData->faces; + indicestype = PHY_INTEGER; + indexstride = 3*sizeof(udword); // ?? + } + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart) + { + } + + virtual void unLockReadOnlyVertexBase(int subpart) const + { + } + + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const + { + return 1; + } + + virtual void preallocateVertices(int numverts) + { + } + virtual void preallocateIndices(int numindices) + { + } +}; + +void BuildBulletTree() +{ +/* BulletMeshInterface btMeshInterface; + + btOptimizedBvh* btTree = new btOptimizedBvh; + btTree->build(&btMeshInterface, true); + + + struct MyNodeOverlapCallback : public btNodeOverlapCallback + { + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) + { + } + }; + + MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); + + m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); +*/ + + +} + +#endif \ No newline at end of file diff --git a/Extras/CDTestFramework/CDTestFramework.h b/Extras/CDTestFramework/CDTestFramework.h new file mode 100644 index 0000000..b803cb3 --- /dev/null +++ b/Extras/CDTestFramework/CDTestFramework.h @@ -0,0 +1,20 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef CDTESTFRAMEWORK_H +#define CDTESTFRAMEWORK_H + +#endif // CDTESTFRAMEWORK_H diff --git a/Extras/CDTestFramework/CDTestFramework.sln b/Extras/CDTestFramework/CDTestFramework.sln new file mode 100644 index 0000000..647f8ad --- /dev/null +++ b/Extras/CDTestFramework/CDTestFramework.sln @@ -0,0 +1,96 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDTestFramework", "CDTestFramework.vcproj", "{0565DB39-45CC-416E-B549-BFC24F2666D1}" + ProjectSection(ProjectDependencies) = postProject + {9D492E35-44FF-5E48-AB83-8A1326AE11F8} = {9D492E35-44FF-5E48-AB83-8A1326AE11F8} + {FA38D972-5689-9844-94F8-B26C144B6AC4} = {FA38D972-5689-9844-94F8-B26C144B6AC4} + {DBE44CA3-2912-4441-8D99-AA2242688AD2} = {DBE44CA3-2912-4441-8D99-AA2242688AD2} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Opcode", "Opcode\Opcode.vcproj", "{DBE44CA3-2912-4441-8D99-AA2242688AD2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BulletCollision", "..\..\build\vs2008\BulletCollision.vcproj", "{9D492E35-44FF-5E48-AB83-8A1326AE11F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LinearMath", "..\..\build\vs2008\LinearMath.vcproj", "{FA38D972-5689-9844-94F8-B26C144B6AC4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + DebugDll|Win32 = DebugDll|Win32 + DebugDoublePrecision|Win32 = DebugDoublePrecision|Win32 + MinSizeRel|Win32 = MinSizeRel|Win32 + Release|Win32 = Release|Win32 + ReleaseDll|Win32 = ReleaseDll|Win32 + ReleaseDoublePrecision|Win32 = ReleaseDoublePrecision|Win32 + RelWithDebInfo|Win32 = RelWithDebInfo|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0565DB39-45CC-416E-B549-BFC24F2666D1}.Debug|Win32.ActiveCfg = Debug|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.Debug|Win32.Build.0 = Debug|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDll|Win32.ActiveCfg = Debug|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDll|Win32.Build.0 = Debug|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.MinSizeRel|Win32.ActiveCfg = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.MinSizeRel|Win32.Build.0 = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.Release|Win32.ActiveCfg = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.Release|Win32.Build.0 = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDll|Win32.ActiveCfg = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDll|Win32.Build.0 = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32 + {0565DB39-45CC-416E-B549-BFC24F2666D1}.RelWithDebInfo|Win32.Build.0 = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.Debug|Win32.ActiveCfg = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.Debug|Win32.Build.0 = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDll|Win32.ActiveCfg = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDll|Win32.Build.0 = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.MinSizeRel|Win32.ActiveCfg = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.MinSizeRel|Win32.Build.0 = Debug|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.Release|Win32.ActiveCfg = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.Release|Win32.Build.0 = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDll|Win32.ActiveCfg = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDll|Win32.Build.0 = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32 + {DBE44CA3-2912-4441-8D99-AA2242688AD2}.RelWithDebInfo|Win32.Build.0 = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.Debug|Win32.Build.0 = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.DebugDll|Win32.ActiveCfg = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.DebugDll|Win32.Build.0 = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.MinSizeRel|Win32.ActiveCfg = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.MinSizeRel|Win32.Build.0 = Debug|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.Release|Win32.ActiveCfg = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.Release|Win32.Build.0 = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.ReleaseDll|Win32.ActiveCfg = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.ReleaseDll|Win32.Build.0 = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32 + {9D492E35-44FF-5E48-AB83-8A1326AE11F8}.RelWithDebInfo|Win32.Build.0 = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.Debug|Win32.ActiveCfg = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.Debug|Win32.Build.0 = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.DebugDll|Win32.ActiveCfg = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.DebugDll|Win32.Build.0 = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.MinSizeRel|Win32.ActiveCfg = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.MinSizeRel|Win32.Build.0 = Debug|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.Release|Win32.ActiveCfg = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.Release|Win32.Build.0 = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.ReleaseDll|Win32.ActiveCfg = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.ReleaseDll|Win32.Build.0 = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32 + {FA38D972-5689-9844-94F8-B26C144B6AC4}.RelWithDebInfo|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Extras/CDTestFramework/CDTestFramework.txt b/Extras/CDTestFramework/CDTestFramework.txt new file mode 100644 index 0000000..6ff06a0 --- /dev/null +++ b/Extras/CDTestFramework/CDTestFramework.txt @@ -0,0 +1,31 @@ + +CD Test Framework +================= + +This is a very small app used to test various collision detection (CD) algorithms. +It will be first used as a demo/sample for Opcode 1.3 (a lot of people requested this), +and then I will also include benchmarks against competing libraries (Bullet, GIMPACT, etc). + +Update April 2, 2008 +Erwin Coumans added Bullet support for broadphase test (SAP, MultiSAP, other tests follow) +This CDTestFramework is now included in Bullet/Extras under the ZLib license. + +Current version includes tests for: +- sphere vs mesh queries +- OBB vs mesh queries +- capsule vs mesh queries +- complete box pruning +- bipartite box pruning + + +Pierre Terdiman +March 16, 2007 + +External libs used: + +Opcode 1.3 (http://www.codercorner.com/Opcode.htm) +AntTweakBar (http://www.antisphere.com/Wiki/tools:anttweakbar) +Bullet Physics Library (http://bulletphysics.com) + +Contact email: +pierre@codercorner.com \ No newline at end of file diff --git a/Extras/CDTestFramework/CDTestFramework.vcproj b/Extras/CDTestFramework/CDTestFramework.vcproj new file mode 100644 index 0000000..a59fdec --- /dev/null +++ b/Extras/CDTestFramework/CDTestFramework.vcproj @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/CDTestFramework/Camera.cpp b/Extras/CDTestFramework/Camera.cpp new file mode 100644 index 0000000..21ee727 --- /dev/null +++ b/Extras/CDTestFramework/Camera.cpp @@ -0,0 +1,156 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" +#include "Camera.h" + +static const float gCamSpeed = 1.0f; +//static Point gEye(3.0616338f, 1.1985892f, 2.5769043f); +//static Point gDir(-0.66853905,-0.14004262,-0.73037237); +static Point gEye(240, 205, 205); +static Point gDir(-1,-1,-1); +static Point gN; +static float gFOV = 60.0f; + +const Point& GetCameraPos() +{ + return gEye; +} + +const Point& GetCameraDir() +{ + return gDir; +} + +void MoveCameraForward() +{ + gEye += gDir * gCamSpeed; +} + +void MoveCameraBackward() +{ + gEye -= gDir * gCamSpeed; +} + +void MoveCameraRight() +{ + gEye -= gN * gCamSpeed; +} + +void MoveCameraLeft() +{ + gEye += gN * gCamSpeed; +} + + static const float NxPiF32 = 3.141592653589793f; + + float degToRad(float a) + { + return (float)0.01745329251994329547 * a; + } + + class NxQuat + { + public: + NxQuat(){} + + NxQuat(const float angle, const Point & axis) + { + x = axis.x; + y = axis.y; + z = axis.z; + + const float i_length = 1.0f / sqrtf( x*x + y*y + z*z ); + x = x * i_length; + y = y * i_length; + z = z * i_length; + + float Half = degToRad(angle * 0.5f); + + w = cosf(Half); + const float sin_theta_over_two = sinf(Half ); + x = x * sin_theta_over_two; + y = y * sin_theta_over_two; + z = z * sin_theta_over_two; + } + + void NxQuat::multiply(const NxQuat& left, const Point& right) + { + float a,b,c,d; + + a = - left.x*right.x - left.y*right.y - left.z *right.z; + b = left.w*right.x + left.y*right.z - right.y*left.z; + c = left.w*right.y + left.z*right.x - right.z*left.x; + d = left.w*right.z + left.x*right.y - right.x*left.y; + + w = a; + x = b; + y = c; + z = d; + } + + void NxQuat::rotate(Point & v) const + { + NxQuat myInverse; + myInverse.x = -x; + myInverse.y = -y; + myInverse.z = -z; + myInverse.w = w; + + NxQuat left; + left.multiply(*this,v); + v.x = left.w*myInverse.x + myInverse.w*left.x + left.y*myInverse.z - myInverse.y*left.z; + v.y = left.w*myInverse.y + myInverse.w*left.y + left.z*myInverse.x - myInverse.z*left.x; + v.z = left.w*myInverse.z + myInverse.w*left.z + left.x*myInverse.y - myInverse.x*left.y; + } + + float x,y,z,w; + }; + +void RotateCamera(int dx, int dy) +{ + gDir = gDir.Normalize(); + gN = gDir ^ Point(0,1,0); + + NxQuat qx(NxPiF32 * dx * 20/ 180.0f, Point(0,1,0)); + qx.rotate(gDir); + NxQuat qy(NxPiF32 * dy * 20/ 180.0f, gN); + qy.rotate(gDir); +} + +void SetupCameraMatrix() +{ + glLoadIdentity(); + gluPerspective(gFOV, ((float)glutGet(GLUT_WINDOW_WIDTH))/((float)glutGet(GLUT_WINDOW_HEIGHT)), 1.0f, 10000.0f); + gluLookAt(gEye.x, gEye.y, gEye.z, gEye.x + gDir.x, gEye.y + gDir.y, gEye.z + gDir.z, 0.0f, 1.0f, 0.0f); +} + +Point ComputeWorldRay(int xs, int ys) +{ + GLint viewPort[4]; + GLdouble modelMatrix[16]; + GLdouble projMatrix[16]; + glGetIntegerv(GL_VIEWPORT, viewPort); + glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); + glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + ys = viewPort[3] - ys - 1; + GLdouble wx0, wy0, wz0; + gluUnProject((GLdouble) xs, (GLdouble) ys, 0.0, modelMatrix, projMatrix, viewPort, &wx0, &wy0, &wz0); + GLdouble wx1, wy1, wz1; + gluUnProject((GLdouble) xs, (GLdouble) ys, 1.0, modelMatrix, projMatrix, viewPort, &wx1, &wy1, &wz1); + Point tmp(float(wx1-wx0), float(wy1-wy0), float(wz1-wz0)); + tmp.Normalize(); + return tmp; +} diff --git a/Extras/CDTestFramework/Camera.h b/Extras/CDTestFramework/Camera.h new file mode 100644 index 0000000..0696e68 --- /dev/null +++ b/Extras/CDTestFramework/Camera.h @@ -0,0 +1,32 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef CAMERA_H +#define CAMERA_H + + const Point& GetCameraPos(); + const Point& GetCameraDir(); + void RotateCamera(int dx, int dy); + + void MoveCameraForward(); + void MoveCameraBackward(); + void MoveCameraRight(); + void MoveCameraLeft(); + + void SetupCameraMatrix(); + Point ComputeWorldRay(int xs, int ys); + +#endif // CAMERA_H diff --git a/Extras/CDTestFramework/CapsuleMeshQuery.cpp b/Extras/CDTestFramework/CapsuleMeshQuery.cpp new file mode 100644 index 0000000..b1a6209 --- /dev/null +++ b/Extras/CDTestFramework/CapsuleMeshQuery.cpp @@ -0,0 +1,127 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "stdafx.h" +#include "IceHelpers.h" +#include "RenderingHelpers.h" +#include "Terrain.h" +#include "CapsuleMeshQuery.h" +#include "Camera.h" +#include "GLFontRenderer.h" + +CapsuleMeshQuery::CapsuleMeshQuery() : + mBar (null), + mDist (0.0f), + mValidHit (false) +{ +} + +CapsuleMeshQuery::~CapsuleMeshQuery() +{ +} + +void CapsuleMeshQuery::Init() +{ + mP0 = Point(0.0f, -4.0f, 0.0f); + mP1 = Point(0.0f, 4.0f, 0.0f); + + Matrix3x3 MX,MY; + RotX(MX, 45.0f); + RotY(MY, 45.0f); + + mWorld = MX * MY; + mWorld.SetTrans(0.0f, 4.0f, 0.0f); +} + +void CapsuleMeshQuery::Release() +{ +} + +void CapsuleMeshQuery::PerformTest() +{ + RenderTerrain(); + + mCapsule.mP0 = mP0 * mWorld; + mCapsule.mP1 = mP1 * mWorld; + mCapsule.mRadius = 1.0f; + DrawCapsule(mWorld, mP0, mP1, 1.0f); + + const Model* TM = GetTerrainModel(); + if(TM) + { + LSSCollider Collider; + + mProfiler.Start(); + bool Status = Collider.Collide(mCache, mCapsule, *TM, null, null); + mProfiler.End(); + mProfiler.Accum(); + + if(Status) + { + if(Collider.GetContactStatus()) + { + udword NbTris = Collider.GetNbTouchedPrimitives(); + const udword* Indices = Collider.GetTouchedPrimitives(); + + RenderTerrainTriangles(NbTris, Indices); + } + } + } + + // Raycast hit + if(mValidHit) + { + Point wp = mLocalHit + (Point)mWorld.GetTrans(); + DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f); + DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f); + DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f); + } + + char Buffer[4096]; + sprintf(Buffer, "Capsule-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles); + GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer); +} + +void CapsuleMeshQuery::KeyboardCallback(unsigned char key, int x, int y) +{ +} + +void CapsuleMeshQuery::MouseCallback(int button, int state, int x, int y) +{ + mValidHit = false; + if(!button && !state) + { + Point Dir = ComputeWorldRay(x, y); + + float s[2]; + if(RayCapsuleOverlap(GetCameraPos(), Dir, mCapsule, s)) + { + mValidHit = true; + mDist = s[0]; + Point hit = GetCameraPos() + Dir * mDist; + mLocalHit = hit - (Point)mWorld.GetTrans(); + } + } +} + +void CapsuleMeshQuery::MotionCallback(int x, int y) +{ + if(mValidHit) + { + Point Dir = ComputeWorldRay(x, y); + mWorld.SetTrans(GetCameraPos() + Dir*mDist - mLocalHit); + } +} diff --git a/Extras/CDTestFramework/CapsuleMeshQuery.h b/Extras/CDTestFramework/CapsuleMeshQuery.h new file mode 100644 index 0000000..590e369 --- /dev/null +++ b/Extras/CDTestFramework/CapsuleMeshQuery.h @@ -0,0 +1,49 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef CAPSULEMESHQUERY_H +#define CAPSULEMESHQUERY_H + +#include "CollisionTest.h" +#include "Profiling.h" + + class CapsuleMeshQuery : public CollisionTest + { + public: + CapsuleMeshQuery(); + virtual ~CapsuleMeshQuery(); + + virtual void Init(); + virtual void Release(); + virtual void PerformTest(); + virtual void KeyboardCallback(unsigned char key, int x, int y); + virtual void MouseCallback(int button, int state, int x, int y); + virtual void MotionCallback(int x, int y); + + TwBar* mBar; //!< AntTweakBar + Profiler mProfiler; + + Point mP0; + Point mP1; + Matrix4x4 mWorld; + LSS mCapsule; + LSSCache mCache; + + float mDist; + Point mLocalHit; + bool mValidHit; + }; + +#endif // CAPSULEMESHQUERY_H diff --git a/Extras/CDTestFramework/CollisionTest.cpp b/Extras/CDTestFramework/CollisionTest.cpp new file mode 100644 index 0000000..e487154 --- /dev/null +++ b/Extras/CDTestFramework/CollisionTest.cpp @@ -0,0 +1,38 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" +#include "CollisionTest.h" + +OpcodeSettings::OpcodeSettings() : + mPrimitiveTests (true), + mFirstContact (false), + mUseCache (false) +{ +} + +void OpcodeSettings::AddToTweakBar(TwBar* tbar) +{ + TwAddVarRW(tbar, "Primitive tests", TW_TYPE_BOOLCPP, &mPrimitiveTests, " group='Opcode' "); + TwAddVarRW(tbar, "First contact", TW_TYPE_BOOLCPP, &mFirstContact, " group='Opcode' "); + TwAddVarRW(tbar, "Temporal coherence", TW_TYPE_BOOLCPP, &mUseCache, " group='Opcode' "); +} + +void OpcodeSettings::SetupCollider(Collider& collider) const +{ + collider.SetFirstContact(mFirstContact); + collider.SetPrimitiveTests(mPrimitiveTests); + collider.SetTemporalCoherence(mUseCache); +} \ No newline at end of file diff --git a/Extras/CDTestFramework/CollisionTest.h b/Extras/CDTestFramework/CollisionTest.h new file mode 100644 index 0000000..addef25 --- /dev/null +++ b/Extras/CDTestFramework/CollisionTest.h @@ -0,0 +1,50 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef COLLISIONTEST_H +#define COLLISIONTEST_H + + class CollisionTest + { + public: + + CollisionTest() {} + virtual ~CollisionTest() {} + + virtual void Init() = 0; + virtual void Release() = 0; + virtual void PerformTest() = 0; + virtual void Select() {} + virtual void Deselect() {} + virtual void KeyboardCallback(unsigned char key, int x, int y) {} + virtual void MouseCallback(int button, int state, int x, int y) {} + virtual void MotionCallback(int x, int y) {} + }; + + class OpcodeSettings + { + public: + OpcodeSettings(); + + void AddToTweakBar(TwBar* tbar); + void SetupCollider(Collider& collider) const; + + bool mPrimitiveTests; + bool mFirstContact; + bool mUseCache; + }; + +#endif // COLLISIONTEST_H diff --git a/Extras/CDTestFramework/CompleteBoxPruning.cpp b/Extras/CDTestFramework/CompleteBoxPruning.cpp new file mode 100644 index 0000000..8eecede --- /dev/null +++ b/Extras/CDTestFramework/CompleteBoxPruning.cpp @@ -0,0 +1,168 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" +#include "CompleteBoxPruning.h" +#include "RenderingHelpers.h" +#include "GLFontRenderer.h" + +CompleteBoxPruningTest::CompleteBoxPruningTest(int numBoxes) : + mBar (null), + mNbBoxes (numBoxes), + mBoxes (null), + mBoxPtrs (null), + mBoxTime (null), + mSpeed (0.005f), + mAmplitude (100.0f) +{ +} + +CompleteBoxPruningTest::~CompleteBoxPruningTest() +{ + DELETEARRAY(mBoxTime); + DELETEARRAY(mBoxPtrs); + DELETEARRAY(mBoxes); +} + +void CompleteBoxPruningTest::Init() +{ + m_firstTime = true; + + SRand(0); + mBoxes = new AABB[mNbBoxes]; + mBoxPtrs = new const AABB*[mNbBoxes]; + mBoxTime = new float[mNbBoxes]; + for(udword i=0;i +#include +#include +#include + +#include "GLFontData.h" +#include "GLFontRenderer.h" + +bool GLFontRenderer::m_isInit=false; +unsigned int GLFontRenderer::m_textureObject=0; +int GLFontRenderer::m_screenWidth=640; +int GLFontRenderer::m_screenHeight=480; +float GLFontRenderer::m_color[4]={1.0f, 1.0f, 1.0f, 1.0f}; + +bool GLFontRenderer::init() +{ + glGenTextures(1, &m_textureObject); + if(m_textureObject == 0) return false; + + glBindTexture(GL_TEXTURE_2D, m_textureObject); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // expand to rgba + unsigned char* pNewSource = new unsigned char[OGL_FONT_TEXTURE_WIDTH*OGL_FONT_TEXTURE_HEIGHT*4]; + for(int i=0;i 0) + { + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, m_textureObject); + + + if(doOrthoProj) + { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, m_screenWidth, 0, m_screenHeight, -1, 1); + } + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glEnable(GL_BLEND); + + glColor4f(m_color[0], m_color[1], m_color[2], m_color[3]); + + const float glyphHeightUV = ((float)OGL_FONT_CHARS_PER_COL)/OGL_FONT_TEXTURE_HEIGHT*2-0.01f; + + float translate = 0.0f; + + float* pVertList = new float[num*3*6]; + float* pTextureCoordList = new float[num*2*6]; + int vertIndex = 0; + int textureCoordIndex = 0; + + float translateDown = 0.0f; + unsigned int count = 0; + + for(unsigned int i=0;iRB6|uMTbzJ;*3;m zO46G^Z*PYU((G2ZXk)tC)v8tN8r&AsQkfRx8f(!60tU>wcbx2Qz^n!w&HMR0=iWOr zNecM-{qYZJ@11+kdCqg5^PK0L^PJ~A=iJbT+qDu+(>%B)CN!-Zzx=C}`)l9E5k2R^ zAI#AXo%NH8x{Fr--^8;+|XYtoqokcinY&yy~O3Ro#=gtLpZfY{oC2_>7DED$!=jFC(-baFKENQz`Kx@6NA!-Sl#? zHls|_4*a@U+ezR}CE7wiA13`ZmuQt&ObUA=ub}g=B4AqR%j36gjw9ydciH7)S#7$V z1XY^0{_=Y^+#0`C(>{Ga;#qd*a)9t#i~pA^Fm2aui~tY9_Ah_zzglqT@_RmY&&TjC zWks1K&oF-T{%VQup4&Fw4Zz=CjR^37nP}^$z||r2&A&G}@FoY||*&85;5}k_fZTXZp4qp<%sgSo60oMRYPc)({)@!J<%cyrn3R3}(Zz zmvXP6kx1<2+-uZoi2W}28XOPD#&WNr(Marn-PcCV#(M&I@uINWFAAsqqA=Po3ZJ|b z+1U7EMu*M1@^GVOhK9{Zpur3doAthk1bf30=#fBgWTK*161WAE^tpn`Yp!4lyIU{? z>=sM`y9JZi|5$g-tM&FueR!olT6*mI7&k-Xx%wEF`WUzC!?Uy}^G-7e5LF%HPIYAU zrmPk(Go#sox`6f4uQV-FytK!(v*~sIB)@>Fe<#1uRFI|}EpryI>PL%=kPq1}?b%V> z))T)GVM|Z#m}^9{W^mLDWvlDGTWZYcs9EPVL!%`tJXZ&^O^X>2%r25JGvYHn+l=6t z-ZZAg=RQkn$NE3SY&}&H{S@3!IHGU%7Wp6gZ?+9ctW^pt zlC-5^Gdcp!=vI*#8ZlO&CE?YFS0iYVzm}c`e=WVq()>HCnLKJ$N4<&S%&*O$bw`g6 z$;?RkfTwuyg3Y}}fnN>%{&iDC28<)+7Lcu?3} z>_F)zAn5mbtzSO}0}vRWA6t-irPpJuJlB&SZ>L`E^;r8<@>lbtCnfhHImBT~=BvG4 z>o%1<`(*IXGo9M;HB3|tqJcrc0(M1vjk3W=Ngy*TRmxuqB>NRuZi>vE=iTQRm(Geq3rO=bB9wR(IbD^Ex0>paGa zO5wk!!46;SX8bXgFNjb59%LgL-(izEKDitp!7 zW(MM)TX)(Foi;*)X0+dk4m}qf99ZWAc2@+@?hIeCT@4|h^;TrTN*o9VCgt6$aQ8WR zBfcQ-<0}4ylXu{`b;r%X{lD(8SKzeQ-OqU5E4rU- z?p1X^^Q8M}Exvwpr2!k{q9o;S<#{H?%v z(i9R77D&$yx0`Vn+v#^ReQ>NgIGQL;n|xu1d%Bp|J!W)_y=@PA+cEaG(hDfkRxPfs z_a!c{3lkhO>Z+V>0cp_G=Vva;t1ZMk-3CS$^t1IIV^yW#_k1)w7J~Prb%U^5Mo@`e_Ld9WdArZk@1^t z{N>1`9**!;+j4`M-tX#Wp}j`iICDP2 z`$T-MqS{RI6;-xnabuC4bukz}jPS3w}BYThylM&asQ zgL*USD($3Ye6=(Fk9AKJ)E`h32 zLs2P;jzbw4BEcxO;=k%aLSCbOc~YWB7!Bu?P9IgfU81Ow2^I?T zr0!11Yq?&tR=Q7B8Ql%0srC3h@{Mn!w0T^PfMq>ffx(H~7Dlr!;hsqZS zC(+3#qggzovHasK0zsHZL~SpRtt~;)B1QSqo^%#?&Cq-#W`Ys)8pMrWgIF7^g)^BP zlLrwL$WhRz`q}j7Nf5>(f9v1lDHR;UU8X@}G7TC-_g@{&Hq~J~P9#Z9Fr)K98U<(sbdkIUn^!wz>flnxIasPl z`ugZdgJsA-v}b68o{3Q11M=SbQnxN-q5Jo!`kI1$tmbDhxDdHT7o*E>dnC9KY}JRdidyz#SPYD zKO-DW2R(XIk2}}|fD@rPHev?YgNYC3EMwK7!<gNOae_mec%K^%>_e(peQlLsHG~j!^_aeP)U%qi?EX@IKJi%~E>(+x6DYr7Q|Z|Op=HxW z@8Xfpx!b6#7r+|{D8#Ihr)YPoZmm2K&3btvsTav%jpedGst;*byRl(DWoD^@ z@;Uuw&Z?q44c6JJF4*sf4jbr#IbWxYLB5vutFvA1cBub)k*f_xhN3>n|3! zok9vlGn_wOkLKOdq~n|I63uyis)QT<*T*cJWWPI^lasgsn!TX;!#2&cUmvqg^Fo{E zxvx(%ILY~bxy{MaX{bU_j#tU(zJ|_Gv;7wxMGGP6t$g1MJYj&s(oEypiRsX2C3RfB080^9xxW_ zm{ge*IwyoS+Z|DXX(?BHn<~LKi7H`}lW#J(4-6uo+z#ieM5ef}@1-1`>=`)KQqj&b;1?jnD5I^-9)$RAb6`xZ&z6>_mT*U*@mK(i)Fl9j+% zxTD(lz}B-+87xEw^JtPo5JZ-@SC>Boi)V4>_RL)2H2{YMusCy5dKL9(pp0XlF{C9x z;0W{sNNULmn9Fiv79Exb55&XO!SW_W0Ibl+W6bnCz`{KXeO+X6Jbehg0>#C(}(}XRqi0Tw=Lr)~$p#?f{{SMdJ3$?&${C*GDyYZZxE-L+Z{!KUA zIs#NzrCN$^J@Hw)y<}~vj2(c6KrPie`4dLLmMAK19P=kj#M}~)M$Ovq0%V?pVbzRQ zCRgrwE2K7TRiCiY7Bs`pZBgZFLW|DoC!saH{LMf7Y|$&`AIziXt4Gttzx!wNg#JRw z@Ag4eh8@P45J9UM7e>N}GhQ96Y(nogF6wMK1%6x_%4o?6v)CvyX*cnh4PGPS&7{mA zRB}Zy%tR6Ee|rnc^dU@v86SeWN^__5nXp6Nv0U7|r3XzTH}v72x+NO@+-&}CcFN1=avp!}nOiJ?4*fB_@-awiK$SKx9atj`y)bF9n^eXCCM}*OY4J2kOWdStoJZ1FAzYC-B)*_a)nBLn}un1xm6^G*%l zY7K-upUOL_1mT^+rw@7BdJ-#h4EM~!NJdd~X;4U}%5T7#B(f$Hwo5c52EOWie4+~H z<9m(vpv0@?MJ|v{mM~G3^T>F832S*lYZePy0h5%{`i7Y#1HmH25OgH4{I36z-OCj8 ze!K3K-Y;{G^zk1&E^lt9oDEyGDhRV{R2dbX(T_+!pVyc35&BQd$OsxmY^?`fHLVY6 z86?nE_v=mlP&O*qWH6XNJ{PKj8SK-oi?E2IH}$RaKZs0ZG(WjxNB2rCFtH%H7eCOZ zIJ#k^l|Ftf{m*zqppxKz8KK6~?UELF>x%U8n#9=v@GvL@fMRsm8RC(q7VVchAIq!< zO8?{aMfxiWUL=sQ#kANHUfP$FZ)SI^)$(Or-BE$9OGIcjBoL zHiB_ZX&bD6OOdBgzOfFBabheXK=l9u(kF|w%uHkldQpC_|8XGfHAB66`c^1M(236V zKlm1c279rX+KdIn}8_8)H+d{{&Dz&3{d+-S}bmE$##O2LRPiXNA8CX}e zJqVk@iECCACC<}>$BXsgiQ?v_V_Kp&6+FybGv4!0>Ca3U(ZjGO7{PA6sas3jF2)o# zV-E3LUGSyq?5@d|s+F!mY_?`}(1>_w%ME1>x;X^QVjmV20vPl7jCGmZi}V8W+RbWB zuRMpfd1y6@0efxqpcy>4!@E87Ei-!PnprHyw^$4W))#FLeUqW9q!DW+ z?PB!k{S!uTzZu$Zg!U~xr8n)kNy+%`D+5q^x5D0}}?P1iOrA`%+kO+K~qoJY`^;CCk&Tu-2n)VU3b8 zm8|orffB5%lyMJ{D;97VlV%DnZj=(6IUf&76p@D3H`F`QEXISXh&i@w!;HU9@E&(H;B&Zk^v+=!(@i*1B8R(bUZ6X=R zi`l_DT1MNa_?9F9+Q)UxNBFMA-)#e+m9*WHgFst(o8HEx#kwFZZa%_jE%D7%+eSXH zfU{M*>0p2*YH6VR$5mZ1I#4vM)F47^&`A%i52W2 zirK2|!cuNkhr!x)>XcPEXw-RRG|564R@GRI!Hw0p6u+sqFfcB#Ww32EUd$x#ki?D; z@J#?9k0=@6SuzEH7TmEa2Lahc$(R%+BT|%%(NeONd{8A5IZZOa?BLz#sKs4B!n>A; zh_t>XS2B@S8J5_xosvy2tt}V=H8eg~U?XVsEb064n`&E*9OgR$y9_U82k#WvtN4~A zfD%}~i@*v11@>=p5K3SfgOV~0O3G*{=@LGul1fM4!2q+3ccX1F?)nkl*)CDEBI-TU z3oQGvGj{sTy~TMwdn05v)wU35%N-G2fETlkcZ%rS_|`!HC8B&65fuQ6=*2k*C8CT$ z@t6k1W3&`+J|9%^l!!9GO!96dD{OrOYl^6Jl=?~ZL+mICpEkh? z)}oHzR9iXF`y6=<;KfYxPI>k7O#qa<@?GRr04T3>au7;h8G~XHDT>KxDW;bXs+dY% z8DMtsZghBX*N^b7CH_w2mFkOKOp#Ynh+bb_^`~I%hpmj0 zb{8DqThDm7S29i>RSva^b4%!lH+wfz#m_`2_QrJ^Ge2CMWk`h*EaS zyD3ZQ`=Q{IDfi+x)iwfR#>H0QH99Q3m~FgMe%p~tdau9d@2=AJ|?F67i>Tf47AP$pu?yW;(PZofMFr8onhw;EmXk;Y z9kAfNHcvBo3wk9o`E2~A+WJwrF)|rGWo@VNVkUWKgZnw(1VA-7zDt7>05-T&ISAF@ z7y~8~DVWS?VRA1Y@CPQV2FC!igLk9j1n&9~-nGP1X>jKQR9Gn5eIuk!cvYYstIp$k z#IY>b;WyQG95_ZDf$71E*~U8s=7)UiAb=7WzKg&J00rjp9E1`W#-J=rgR(GM%F@jT zRTd>M3^0?t8_7es>qmHJ=fOU5k~qA9Vf;0#R2BPXh(oIFAhNNXsyl!eGs!!v?(2LL z09AE-m#Py0R^8Wf5UT1JgW?h?ipyvz?mj-K;;O1+fZ4&j(XkhIDDFr2t919FRNEfB z43jL(rjonyVs`M(zU&|QmL!1c%lJ;R6af3Of5<_ozKlsh7Sn(%MhjW(d{AVmzKj88 z8}CNjPTZHC)Q|8NWWl6-8WvtHfholh=FY!Cx;NO6CpAsg4B0f7K;R&wLt2~@4py>E zINXlzO1Hr-L!6T4ya@*zF(w?+8^ZRPZ$##VBQz`~AyM#P!pVEj8Ze__!ZCdxY!5Ib zC%qJRHjPF2O|@+YD+ZlPX~m1#!888ZZyAqz z&SriK-vmH4bG}P67XUW%59c6MGiMCSMx-bkqor&&@3{|dd9t2xbZOef8up^sS;>B#^owB)Or zPvSS#wg5RCbR@M3FJ_W=O6rAt696Ttd>2U-07~jxa}Y{W8H17%DN4#{DQP7i@aO6h z3@|%*H#*93*N^b7B`yRi_*_$!F7oUEsp>rFll z-pgAclzPoZ#KC!?lfSUIal^q}qk?als>Vud-2nj6w@TUK>_zrN>m`&P^4J$p4-xTx z{xNP?`NJ#R$N*DB(7W`M3VG@FQ;Y$u5r(yCghCU+_%xDY<%vxfcJz;$#0a|?_p6j} zO~c-=(sG}-w$86@c?UDA_qL?@#!TplN?&@I*pn;g!XSzSo=lx!@RV?K5Cib4-{&dX zf?Z17C8IT=;<@<(%i{TNkDXoW_Y0pln>ea&H07x%CDHOvdHt6@)d#B=}r z{I|qgoi{J`tZhZfuuz|MQfGQpEWDOLbA=b)mh?XbZC(i2F<*hZwpzdS!OV?qXx0ro z6idp48hF(r=kq%iY2(%P9<<;Jc?)K%>%3duYYHGt^IZ6@gP%%hYyv*k$}PRPOC=mL zrEa<8FxJId)@vA{$pX0Tb&*?yfV`k4_3mcYRQxuU6a(W8yf@5v^E>JDy z(MRSxQOV#i{BE}+8k~JwGBgbLy`6YVMu*{3+>R$0#?Ma7#Cra$Zv%VE$*t7V>5t%W zv7r9-k;q-;Q5n*KgWQUZs@WUjzE!zdPQxIkk?td0i>2%#9Qj#~Glx<;#m z78e5Hcsa6lDdckz8Uy?Sut~6K9@;}GTc1?;=pwA4a#Py4I5;lC>KJ5WZf86AMfd2k zU3>^-g(u+W?I%^|lKuSS(*OLq|Ha?hhT)y!wviU9}s7pmJ%`dhDH{|a`#SOw=U zriK{MubXY3Kv*00x84FJ3qV*;#Y5XEf9r9eNy0zb_1KOL45oCljpGT6&b zLD9a2Ai9OcCR1s`}RMF<@iC#(~)Bm|Ld_E9Wm+pr^#j$l6C5EqcFKW4&1q=>?b#&B1IZiJ^I2Mu-(#v9D zTK|K6$W4PkSdPK0NMKAglT`kRpuvIB-%4O9<#s$M=WUPw!G{Fq5Z0hS9-&nV9Xj?^ z%*~UHR-nxI5#X?r0boaJ#Y&{rGB?0!dTJB|K+9a&SbC5`fIN))Smh06A1y}H(>_*JCydYyF7z#ZAoyD>cN1t~{>Wx|) zT1Qq!(Hi<5p%bC#dr_fYIBaL&It#I3h!I}sJo}9BV&^$vgqIKl6L+<$ZYE;Q|FBc$ zRNY2J4a&P8PpMJ@Nl*x+Y31~#@V8@ry)%T#FWbHb{W8>KY+-qN0bpb;v@(p+lI9A~#rFD%x5URdOO&T3)yo zBM;(@9Ry}kY)z~b&!Ts=9BoC+)nyzg64)6dBMM>J%P@+A`YRzVaQXFGpb6IoT<^!F z#&{X8d^e-xCXEk$jWoiwLvfmpjte zGAx%gz_3NQ<&x6=pROcWE-7Er%qA}>?f>afkeEwa#USip&riC5VHm#hlX7t&{k?*u ziy8Fg!lX+WCOvbG;42Z9Y071}jPG~mk-D4#YxC%=Wxxk=DOU2mIxj^%1Kw$;;C@!0 zQMV*B5BuRDHk>*{7H4L6%G`+4$#Pb!SNn7WyxVX+itF3Bj^pabHG*pb*Et`=WE|Hu zxUR?bQCtaJ2CgsQ`Wmi(!_|vx5Z8a<`ZF#cMBqGJoHlz(XUz1THEXu7Y>q!L_v~}d z`+xYayyD!PHZA&kfqe29Oj|ymxk=>nKKv+7Hj8jxPY6{xEh3pU3{Y~jO~jJ*YNrsH zq|`VmL?CD9r4VU+)s>585yju;WT!>sa3Cio+e8RYhWP zKCR}-b>+?>Bp&VDs1|rTuB&j><6493c3k)2+JWnza2>#P7}rm5J&)_Zabk?c`an<6w9@ko2pTKnwuKyo|3xdY}yoNfS7B9}+Ev!m4Q`zL7VpghUw|cdusB;W^ zHH>Y0TmZ8o%aDinB1AD;sjnyfioeDV4h1nU6efudTfg`pnT2DfE&1=2{L9rGYy)(- zRH+0ZRZ0|4JlOk?bMz+svE7_({~#peBo4-4F|d_{KN0Ka>t#HdF8zqt!k`KDpW7Ls zx2@rF2S>4Sv@9rW<3O?ts9`PH16#y?0>pOQAmT*U@-wyLP9ttF(viT#g;P_fT4(J;^m1I8`KB=8 z_8t;tmXRvX3U?I|Ld6L$Nx7;K`n5{cr2C*%DR*1S-^iKv7k%^}h2@j>7d`d?2|a_8 z;FgD1vJY|6{-WzRFNu!aF3hI}cvx7EDaAVw<4&b5CO;ER{^VCt zRgSZw+GW(Adv$gh^*g(aPG`=CfzlR;sBARqH+ODhmC6kC4emACxz62dbozDn8l67# zUZc|mdyOzT?E~dd5beE2rwjHPou0hc=ybteqtlc38rjJ0y+(z|vDe5(p4)4L>Gv=c zQfy@UYxf#$?k^grz{#v(|NHD_f^9`qRyElpgDFnL zy65wZLRTy@k8MTHj%8;XO~eJjwxZxDw)MfkHf&js*eJz_>Kp)YZM~xX^|usFAtWum zr%MRtD5J9bV!Y%S292?Z^)b*bl*%#(_5ejkOK74T#U3E=Dt4S>(_5va?jE3BF4D}u zNOA8#rzqxjn6gKC7RUHxr+)CSWu%!ra{c+|{ZoFw>X`7 z;A5gL-i05OR(fJAaLE34+n;}QCh|c$F7W3EUe}*ryrTuc@#h!!1@tyKe}2Hb{`|HR zHDVoq{!y6SAOv>4^yde>>(4)m4ob!5{P`2GR4RY|JMfg}&!3U*ak4-Ebu?^-Mr?n6 zkuJ<^#h)L2z_6bFs5<$t!vEl(*--|E>CZndyy+Mg-V6mwF*MMhA7@()Vlg?0ZFoai zMuwC6v$C`>DE|D(eMj&YvHLSQG_eDe(wDAs*pRG87A; zAnXJP>jhy?3Sm7qVX{mwhD&TW(3=iB&QlbM9AR=`0@pl8^S2gs6Da*F+*84BjRbMa zz#$xpfK}mjGE6T3cqBA_NglTl2qYd zslqQZR8`?#5VjA5eNhPG$d#+Y-Pr8!oC=_-&{IIz&+vApD&&-!gna|QsbKp!x&^7i zon~k!tI#xq?Wzh*sluI7g*zCks&FR=YX@OFgfLoYNSLa^Rx{daM4R=dW@pWs(Ncx7 zW{m}uY3na@F-Xc>Ab?Q2K|Ae~Ve6Yrecb1+X8-gfSjEN_#C12W599g+uK#yevu|Cm z1zyFq;Grj$4Vno>c|n{g0!zhcF7(`XA(WYFPi-vOoH9_Ie%H z;|JaqYQwxVyFWotV&zJH(R(#m$7FCrV0Jy73j%36zgomEu^o2-5sXNd9_2Uq0{C;-mIROFtr36YMAbl1_0K*G_}Vz&`Z=|24!We6M9 z8mFVED4j$KQq(5MP!llF#YIRz?Qo5mhOKiPGO(iWwYes6%5j`s!X%cBfn|+Y>GJ7N z1!P?P4YZd$u7IK7N>Ro~sfTIOmGAdLEUGu)x=joG2-o}Yt|ZM7vDg1Ca{rWELMZe8 zl>VdFXjojs@usm#NSt+5Et{FgnRs6;GglZHs{Wbdn#tM+*RQ4E28RQu_ht=LYv*Mq4qq^dT&TC;x+wt29(ApG6|@ z`U(6H@_&&yA97a?^4~rskX`ucTsEU5klu;7&gFdC#-}BGg2Rp0c_p9j;?rV2ZNO79 zIEpj1hOq>RMP$fcCy&g7okkAU#p1KQ2>*?3l*lTy_w?mV1$m_}Lo#T=!hwO#IgU@A z$BW*=KA9!qq#I8Eo-7h`ss01ePZG=NT$2n90o9-!2;dOHweTqPiX9l9aE8)O+kKV0rIkGk-tBOoM(rf3At|y@<0J{-?Yd_ zZj{oI^2=TWxpxZk@2Z40TfEaE|N9*BKG+P;MEO}$kl$2*{H$q_Uy(!psnGX?pz1<2=2i~Rf?^0lvl z+&=~Ri!yRLa_*lN`Qr+PY?GKrMsl{zm^IkS%=0JqarEUt45ejX`elq__LhGc@XT*8#ZNzuG|2J$_&Jjt&6rXfHHu!l*O@Ub!{#X% z*2afjAWlK3PO=EV5sCDoWweV^?k=W4!hvGEdubhRhG!F@I*+?G>L%)qQ2_(_HiVX*=-j7ZJ|4m4N~eng1Hi35v*-SD>JA&pIMq0iM( zar>j`;=rQlAvv+?Fwf#Uu*g1=`>^BQ*WQ48$EmBw}5om!v^mv)yHScmHexX!y< z3&e5NY{L1dxPFG`FXH!~aTR}33;Ye#qzmx-PFyQ-{T;52xatv(1;97v?)`rc_18L@ zzmc3hec<0SxQ224H?C8;^8J62{~Mw4uYvL8Y1_8Gz2s&#!vK6+=m}GE5IU3wk5{gm zr%L&@8*1!hvqa{TO{ahNb@VM&j12Z~`Z@LHtPvcJ?F10#eG?U7naEi&?S3>#XmRR9 zU`!EgGqrt^XeUv_Ai)KI#Ijg3(oa-W3Ke}g&V{FxmjVN6voU7QwsYyr<&un^Mg}(` zOE@>e!Keq;^OZnl6}{VTld4nc;PnkuCdj&h)s)Em+1;E8<;!{};bukUJf zL`%%W_fNV3X6+Y0Id7_z;Y@_tidn`exVTpw=5N?JSsL@1mXU5ER!aq#A`!V>!wj|f z*|96V!1%B45>nHbK@)C#7Y!3w*8Svz(y$%pBpAYcW^q>!(!p~aPOezpE8`nIpNhMV z^QnyYqc0RktbhEhVC*`90KJBH_k_Q+%FI3zjZVkz5k^*ZDKRuHhu z45=UaXx4ke! z_Q4GKl$arpvl3jx?QxUttI|y;ZjO!5M2#%4OFe}*Tgqa+1n8Q?7Vrw@2+T)l+`{J$ z=;L-bsKyABz7~ofj>+jkxm}{?;i3?}K(hg1a!| zRs?qm!TW^ZFEdmTyblEL2f<$!f@w3!v3n1W$uUB^aqz5`cwcM{iTmDSAr2PLidwW? zc;J=A7BFJDqWa0wF~~s?EI721;e!C;uWC~}1l1@N+*L_xqgJO#7(FxFapERz=YNmG zHfc*<%R^%6rV4D7zXb8UaQX#f^2oP?QVpX(lp{XXxJIv}GpXFPy z8J6|h<|BO3;*0E9?ijnzj)sZ7N|&T4LNoS?F+xjxAKOCtK(0Ic&KaQ2sWCb>;aNYz zyOy}<$jzr%7=hd&QkWIZAND;wOkcN%sl0VUh2$VUhj_WO&=h za}a97B4dhm@gV`_jFw$)>-nH4R~r@?pbnie+ScM(Kf=3E{`|E|JPo_0Y4hwHhEa1I&PE(3+9)*(M+(lrj+flqb&UeM-jbdz|m%>bVvrJ=+4 zmWAAtxaDH5K2{7fbk{hv< zB5q-O0bzFR$E#7X5HO}3x6!p2kD0fsWaM+Il#%L*aeR_*sJZ5H+J_?+SA|#?w8Cdw z(reIH!T%hS=79e}I2TaoggN*v&6<6@7sF^buOd#`%{gylz!E05 zKGEqzNM?O!fIlDV^zx^nvz$M+^KbJ`V9NZhObRns+0);aaRy%6Np55=?qr!V=XXkB zA#3=)&L--7$1Y);le5(xHJ^; zW&FN^>p5Ja&qwr{E0HBm)a~>z>l;#~dD^Px>4 z%XCoFx`;~JzfDE!k10<|;#6}=urewogL2o*tCE_rg7}4W&_T&DkK_he+`dQ0w zC+>&zMZ2F3b`QR%Z%J{$`ro@XEsVWZmq|?U(6hlqcFeO96FT0KmZ;FdXM+drs2+*J z)-fS%qMcO3%3Z)~^4#Hf;yk+yeE`I^$|*I5iCANi_2@DYGQ}}AnQc7)R{|$hI0YZ$ z&x|iL1t0S-#3zK&|71HGN8xq_(q9lVCI8c}k$?{9qt zXk*%i&K?pth{cNX-snlTA6V(;#|`5n)LSzc@0H$~5xsRp^w!@pROziFQ2IupxBgc2 z)?tIf&CYP zUF6Kg-iPgS*v=>BvGW?ev0Vy##2VR5uJ|wu$KD)n;9~cYDkb}*BgtF(%*kKP26&ZB zB<9ABld=C&C5*)~_bOYeI~lJJm0*y8UV_85F+0qf6%zU)kN1bVkoCdmDr=TWpe)Wq zx5+x2)Ur-Pg1n&_==eleTx}qOQt{7sN`?qmyP{UJM{@Svb;BOPh5XOVX9|YShd$LI zI+)BtKA}?EOS-_Xk1R};j=+l0+-C1=pwk5oLjMf5zySq58M+{B@#IKa46n3C?yv<( zb&U3b1MgK_NWxc-FKXSPVuOD?n#fzfb1&d(Q&z${gP9wL zReO2yu4|YSIJg%b6oZr7H4n{0R1LRe*Dubo9*9@Tv2ZkE16XdB|4s} zTYx}ztvO|GGJdFYaDsw85MNdE;$9SAn28dzh=;LCgpAKVV-@BeDm-AUT9T>d8@9nf zKJC4gfWqEN5T*83LT(ojjqI)DG51izMp*9Z`7Ad(kg(;i5+3Ar{~WJkIN8S8_;K0e zERQ!=1}C1Khx>)c2CLMDE7+^Y4iE5Z;D(T52S{KRNa#La)mYvdA4clB#T+On!LKI# zb{qZ@Is_;O0<3P|OZ^YZm>3;_GXA!mntYd<$652UvX(BAfz=mrSK~?xDjiDUXxOTV2|q-s zPFu(lD=jbJ$0kl~1zWKgZt`_Lf5%btX!;4pN;vd*>@=p1|1E^Mtj4BOhb?B^!t^7E zqcfN3z?j>c@rYf%UT#sPCftg)D|!P7ki)gbJPA8OW{snOqMuo+v>hiorYw_^t5F$> z^sqGZ;BaOhy|~mw;1JpW*gO_DHxbD0&;rX%I4k113)kmx{Ro#+e|k+Vm61fLbpt4i zef@zVloKIvJ-ZF>d-0CKA|PUAH-Inp7u}rcsSW!qqT~y#g4Vr3KCDxS>LLOsCwoXb zD1#7rQ)D{9F3s9 zsbfU<=cOK{legHA)Ugrpo5shSVC0s4JbUCT+k5n;J@~YCI|3cjqbtjgO+0> zkarA-eGCfjIXdJqw_iECB!CnDk~fy^Ma=%Zm}O^-S$@Wt+9@%ZU;<})9Ylv?5BMEv zoS9c2pGBQdt`Bdc7b{9g7Ar#67~{!j7{!IO`H-v1$aBGfU7vz!Txxc%)GU^;_7W2H z>&Vy0vS;zx=9*@y-LYr!{b>6cAJdU}wx~wU*SdR5%FpndC@~|M3uf6zpJ_b4mf+PL-;&pVy`mrSKMSvBM z#}lmZP;WoJX1uNse)^GtU_XQtGh&GEKycK4!YVm(5?FvRMxgp!D0zapfy{`WXc)kk zvvXLSr>R&3%EkhyJS^!eQHQEJWlI9Ig;BUn%lEs-)BO4;E7<5{$HSf@&urjm1l#+i+0 zi+WpR9kxTEZvbvq<7~tgSzob3iD5?LIe?zoINNH^!!QfbfyTLwUhBR*4Cesa-#7;p zZpgzhr_s~sYb-Fwd}jc^Kv(#0wfc z*6(FCppse>-UGnkLnzl>P~rlfOMm8lu5>Si-MSD{qruYMcpR*0XTTf;46MuA(OO>g zb^={OAUpEc8z-eb#ekmYk6I@shF^alSck8%X9tD`E?9|fJylwdJ8Fm1gRa$hhB|1J zg(d1nCkhVg6>B7DtpqjyFjczVecIqY#oVWj?$ajqbZx3M?uKo4!?w6#&F)jH8@t_o z+UY*EyKuYQr`>Ms9ye^S8@A7V+V4IcaN!QRVTatOZu^NmIgDrFNe>=UrN96-bpC(7K+7k5*tnl{ZRBxCZyaTn~{<9c04rU{0 zptv80AaZArcc7?$m4{K_D1>Q@hYmtU#$_v-)Hrsd2H_tnB#+|_df^9Nk!iCUeg1egCx{LFIobv0kfF0e82qokE*rF}c{K_v>(ef}ilcII1y))noge|`TNq(zAF^5fiiIN)0X}EnTHMKgF z^(UW3H2gaNBbJsv@lfmoSV^$28vB%z-vR(Si$x)Bc!q9jpGQWs%y9ue4u`!GfAWXG z@GR6{IQ50R{l1oGgMEO2(DeJ-pFjF6KZ2UO?FNcOBI@ahw zaI8Nx_WV(FVEv(Sh~p_t?grLDI~(m!oDjWlOdiGv!4Qmv!~LP*fuPkNvY2qBKQw}b zpLY@t3zz^9-Xa7aMxeX(hx!MCgZ-gFCWPKKgoNvzg#7|00E8bT1RsVt$4W-~vEZzB zH&`$tQ2^3cL#IlgJB>;v@=z&F#)lSok?KL&sL=te_o!aeZvG$js-6-iHU-MQ5$)Uo zWq*jeWP>Fr`amn!2R`ygHX-zZR@jY|v3+{1Pb-9H zZlC8UL54BXf|%#G&t4ze=W^VnecmaE3fm{}|0~46)jy|e|IpIT(Edltfd4RVs{OwK z{K|sC^_n4Io$h=0|M@kUBdyD`N1=5Y+lS8p|NS$-)08qD{s#--asDRcBW%5d1vxN5 zwgzIU90#Ye{&6NOP9*s%FhOWIgG6Y=TheD>6SufT?3Abx9z2Kf0*C7Y!zf(<#?>jC zvL)Y(jqbEKZ4Eb;*i%$ku8{=e`KTnxGRc@EK^P41NP>DC)3#PX2f-=4G|QXC5S|T~ z;beZUL?yFZ%ndwYmkXZjIr%AYQGonJgyCxOnmA}S^(E{zQ2jF-c#_R!Fi|QySKR`! zXBTJSKMX_oM)spl)I#LWBix+M9V4u?FAi#9>)YZOjMBrPs`v+f2>)m{e!IiIahrW2 zq&!PAJ5cMhmV6KbhHtSJQg7qO2n+lX2mh!&aYbiLKO8L1pjrBGxEa6I97Gt8HWTh; zwJkV>65VYUr}^STr_t=u7cm}=!uVhE6qrx`#^*lEJ*s23&olI%HbP51HS+KYQFr(ieVH0_b~Kv zs%M>rROs`RV+QcGjLb*#yeXz((ZV((G-DjbY6hes)(HcU{rLS{=ppwJ=TicVQUvv* z`C8l_eD6fX7KA-l+RaH4^rnsxG;2<@^Mb6YLBnM#u@ZgR?{5asuB#Ais!VI&6x!_wpxF^fo&DMvPLkFXFB1GJAa!GPm zSuHC!Nf79v_-t;Hn9T3Vz4hSXfO1=PQ2v13=OUral;S1Jw@r_?nM2s?;Z<}O;mc5Y z6iG@U8l;x=DT)R>I|j=Rq83fboO-_Ge@D-fcbr<1Y^`9DlB0Gh=WoY1oKT3PFV0YC6$_J|796T0lwuYm)v6L}q}0vt znBss<>CSHpr8s{^q=S@BPU+Bt{1xv!?KY)O>GLawnV~*ZndWbsw(^7^C-EDrJVBeQ zymS?^N&gN^NI!{N?BKa@J}++cNTWt8EN(2eA7iTR$I&K}ZIt6M%{dO7r?JF=Q{4sO z>=4oS*-2m>2$mTfNsKsl&0O|H*M!h=gl-hf6t36D?4*O82VGn_#uuixC9!EsGTDP- zMP8Rcl0yWF6lz^ULw-tm24={#J~%Zht(>`V2fJ^ZVn- zO*iKs#Tl_ayV_PPWXMaX(eU-p*uls+`E(m+yiMYKM`(F9bZXadvV!>KL;s)y)%g1J zsEmy_#Om=7>pmY7$m?z)1<+;H;S4J9_aBx(nN`B-Ou)ujR-c5rvqY2^+}sW(*lJ~* zr-_HHcVaC*9NUN-tlPmRShO?!R0{x)_1iZ_-xim?uP9Oq>APuK`j#mA^cuQAqU?0( z=BjmXnZ{xW{;cIi2HI(nY`&~*ITE1_QNez3S8XV)HVpGOHLq$S;o-c-2` zo^|ilP)D#*`9ELf{%)9oGRr%c^XEOC-5?}$dFNsNyrZ*+KUJN_`D3r;L11Gi@NWGV z1U!E&?<+v|4P1wC{Tr@hxK85gn{+ASl>QbQBc}JFy{ajI8^;IK=VW_p!73i&-KK!C zp8p(ek?wZR2I<>^j5k+Ih0+w1mY9O1MuVS-m zKj_K22!u}&sFsJ13&?}x5rHFBB1;nXe)15$Rk1Ms7KiUk!p_?BLiENvk#1?vUOKKr zJ1&nkgJ~*0V%`6!NKd}lB7gd`74c*goMuiwZuQ4DRYF2qWQOa>yc^838M$%?R_|1= zW&^FYfnZ02I|j`Q5GrKgI3|d^cwft(l>Lqa_re8)DFWT+W_Mfuxbe|)a=f@=SW{b^+Q!^xhIj3@J@Nm7sc zZW(D6BDUB>C|K4P)P2+!!==9XV9F<#Szlg83R-m))vl_0VYh7cs~s)c==O zk1I@E)cK2qiRI_+6f{Do{9JGUi-g0?9SOB$uo?X_TM`;nA9~{ktN9#hO8MO{$6M+P z`cUy7`p@sFg)xI)q=&K{rH12lw%p}%X(>2{K@<9;?HL6JMvigH5tG9dj5sV9)CL+2b~D6rqOz?yaafV) zjwiOTIuE7`lFr@;lS}8&GwRUe7+prI>zCx{8L6&Yn4@QjL(f8Jyn@%(XKUzJsl{uA zsjN%aSrgXahR)Ss3#zsrKatoH+*uQyOauCCUre0M&XWwKl|%z64pdsK{cGII>_u8` zcZpb8IlEMbKNyEsB?U`pSq`o!C zaQh%!Xhmk-eD#q5GqTCR?p4^p;!98}xZL4b4J|ns(J;C0G*xd%4du*A{FIe<5{ zOPwiiu~RZHI<6tFDwVRl!TN7(io`roSalAIj8D4=lYyq5WV2q-0KJoZW1W4pG6_dK zNV5C5jTm{jLdQZdx$Qh&NmBY=atlGq?GL6vIE?x=Lc)2HA1ZmRv1&b974kOf)@Jb8 z3`pgAa2pl}xM(ksC(7(vc|vTlfu=L^qQJ4hJ(5lPD-^(=U{bvrKv zJM6p=tjBpFw&TtV!A>|Y1nYHP2que*2#`!=mkD18)}Ie1&B*~9a$*QJ?7R@0<-9P{ z5$Ar9;Hytcu-@E>{TE!+Y#i!g)ah-YQ9RJ2caqWW*s~uHlu?~1*JAPdpk%i5BH{n zB~1{QgG|42$7&$ZGB4o365HDuJ{9FH$USVGQi5zf)eCyDdw>fWXYj(8wq9!0?v;{F z8E;=}4p{*@+&N@ITY;|yO73c@VEEA&iyI_O*y>tN@%MHy9$#Ma zSa)B;0FMOdDjC}JhGH~_qyMd%gP>FsEN~!84s=R(R>4Vrx%uQsCC<*@FJqM5^?zES z!m)4MON#-9`!&%fx#6>+liNQr$Xa`4)nASyWcx#h2X{?4R$I0|ANB}&k$Ju`3*VLD zniZ^lv@lInEJvq+*(Eo0Ls=>l@n)sdXq+nDh`|sK6iu@j^~)nJoQa?!pZX4lReL`x z4xv~K>C3kgP#>aYFX#Vin;UX7(6IH(adOTnh<)VYv2yOy75#*xtcgwp$3QlXYVnI? z&27ExlA$Uw+F(76Y*A12(?Y!peXvWwc?9_e$GXCDX`#> z(*%~Yz@1SuvfkjKIdC@bK|W3p4!iytNU1KR-jlGu-#|?xB_YBpsB_%6gN_SZe->bz z=guC^p=C@0%VoC^%R`TuZVoS)gxpuftv(E`idg$^Re}TzIIfPOm-4izdcb}Sn6@Z^ zV(6$2!kCgOrRBoSywcfsR35hexJ+P?ceQ*b0zTlMh0TBpj`b@$&UW<3)hFzKXi;q5 z_IDiB28+wFB3d2tV&Rd4$hf(^6IE4XUAag9^3_i=FEalZbrw$b2c6tg+TQKR=EBm<;0yoG}2dP2IH06CamY zmJ*X(C3GVfTWBbMlGxe*%DCxJasTTQ>rq?c>`au&lwp0ILUU6S6@HkGV{SvA_!;g{v10EFHZ299S zQoJRJvoS)5ov~e#!s<2`yWu3`iHGeVM{;xH4RcT%pe5G>$TbsC0+rLX>{?=eBLR1O zD$d|LzZhb$gfFTJmMgqSK4pl(JYW>#mCO(2qmLYDrWrn@e|NvfQ=hBCUBqhF0zNsm zo3DzY>eG);l?bfS-j0|?yTwPWJGV(B;*Fo4`hO5?hj?u}5rg|xun zgtMXu^_^Vec`9UYE(CKc!aS4h%>8zLbJXi5`xUA>V{f%z@d0bTHrTINAmQtK z?bmbEE2j5S>T>mZiTzrkUZD?2?78Z7W;cx`wrkK6?>mYE_HmuS^$f0;aCuNa=i#~( zS2eCxxITm{hU;Ej58&#+wGY>KaoH^^*Po3nzgZ4$!KQepQ$m*LNpWlh55?>U|J~E* zdVlxzkK^!$g&OYvUIar(-vYos89ZI|Wbo;#CxgG{98bR*pAR}mNsx(s;&2WkpzC95UxvpMB(c5RT;s)^v@ZL)JHwsZywEZ+x*k%Bh!Tbr+B0xS1tWTiSCn4 z>V5JNNpz~n8X5HIPvJu%eVMIj0yxErZ6TE1fsZKsN9K+vgTLT>S_Nm;J{jz%SFy@E z6M8cE46PITF%R^u%-=p49LxiL7fM-`1FmubfscoE4QI-p3_cIDrJdf*Cj9~iXP$N8 z9)L+pg?-?~)=xGrw8EE(!bz1Gr|vW^eKvwY~ns>O6C4l6Z^2EL;@clzvDO}It`VFozTr-Yq zfqA$V;<^ggb-1FqHsHE<(v|D4F~D_M=z*N^dAj#4(2iwbMSs-Ev+lzdn?4UFdGAXP$xk$ZcSg@@$ zEBK(_2W4oPD9>Tbv=Nsv245O)us)=4cS-AP4AkZ(w7Q>8*KfE+d~k{L&jsCMw* z!v~B`zo__uZ3eW&(F?#XcFrh=NeWGJU`0-cL4LN*Lo+gFmayOw;nI_O%@8$Cee=*K24lw)J zQU8!Dw$)Sx#&4XVi|ELX1n$o$>j|88MU7B-a$znYo*rs3-y9} z68X=wf2@X#=d@4TenEK)TSZFzSyyg#J_->MLGi#cu!Ice?3JZSt!xplDXBwkOV7EO zM<+xeRp?)FT1I)qs#Fp{bB^V+pSk0A9A}cr>BiVEK^p;kEY^b5)~^+p@+a20{!gzF zSok;a*PPcfFU%)b$1^xvBlzm14(I6ACzA3I(ll%+dPvS`X zRf*xxnNQb(Xg46{ln!*!h%U0#%;Sg0e z2<_88a>YF(j`9ob0^Nlg(|rxrz<`n?%-Cqxhw(=2`eFk-qKd}^(44Skr^#3FO=mQ@ zRcbdwz^Lbjq|Ror&ZrBRWqc5cmxm@CICH*T7!$sEVs(+uY%!#S&fV;g(0RFsworl? zCnKV(BeB2Xc_j`<7h`e?j_$w2=BS93(?TXx$!xxqiJ;b}bUY4TcIb9pJAJyp^-mOfF2{e18CfK%QqwCu)$D>P{R?f)0kL_ zv5qPRk^P9uEwJ3)m-!OoKqIPtrO+6>1@60=6us7Ar7-tDu9XUjgGGCJnJ6w$S^3Nn*V+ z5BI545QU$R6&Pu#~!iWr}TC?P|b@Av{4?`cTNJVkSm!imEyZ z9{Q8bbMe>DnsXas0kV85l+AOA5EC&}2M+h?r^$1A_zBNv|Du5Bir+c$-2)qbj@`ES z>c?QqAG3pfYD$X%z}`~qx~tn)+tw*HzPf$E4aCU-RN-t{t!=%; zF+#;DFcM*`h&!lKE8ACtsd*+zsh`RuK7fO*GO#~jRb*`vwk({ZFQ)o2Xq%(x*l3}~ zh!P{;NAjpMRylEIf!!opNXYTzq?v1yhQ;V`=7@+bqjdr4p_1WEM|U z975aWVK~8&rKcVv>>pl2LIWSi%nN|cEet&o%${^$0qCWDU3J6Wd*2Vr@O7e{r*M>I zKMv2xysz7fQ;RaS-D|KZHFI_M!mr}zitg>-C=O&6b=QK{%!2N~ZxMJw_p(`dJGZ-M z34Z))P3ymYF5R2T`5ItdfvXC|C7cPNI%xz$0K3t+N^Y;xbSZ znzDWPRtBRj2GdbvE;j@*B9LOW;&eMA$5*(3e|%AJR7?^O=tb0@DvkV&P&xev{Iq+! zs(arBBSMwG^s{~Hde>U-dN)KLY|Y<8jpAhj#oh z=Enxi*KtF-ralrz7)ifmN&jUeX>Skvd>3v6ACNbGJNjU2PDeU=A*AL;A8gIl22#lg zwKe|$zlfpZ%5BXb?4iW8p#egT$l7%oWKHP~I&*TzzVE6!%&Xxn{HF|g1fmc@hqje;n*7!TUYGNy-A z!+pPPPgjL)Puyh@a{rzsg;uj~1QIzv#fs>Z9oc3Nw&Pg0=#TBJwyG zcv_1C)Eg|AM{tS(3VDHYJtle-1;Jl|Lh%wFi3cC2;Nm!r?3@9&Z4XER)`%@w0p+F? zf|3p>&l*rdeRczRGaBfBhNfvCnI12KZO@Ur40J#rP;vo`294Bv zC^h?JoIde7q{0G`Iq}5*Mu}N*u7C(@7?~_B)m+^_LxUl4IG*;_e}V)<;ji(e>?Fy5 zio#3rv>%~svg{jR=?HG8?;0Nb`Q~^`4QUv-CX0YCCNLZ*G z`eX<3qnPsTruH{Y_AhWvehVjI;}USmxDs%kK=>96T_!WnCs?>dp8X{y|0m*J!lmN6 z`fZ4Maj|s&lLJcrKc1IPxv_A`phn9(@YakHC*c0O{~wh6vWhV$SQ5FlpoGyjO!1RM z;}6iE##Va99sC3H>lfpDh@XgW9fD9Qg5@c#E6{8W(~4NaG4navbmiX|Clgz*I%xLY z44Kjt!!nTBi_+SU6i>`5!(g=-|5C(y#e_HnrTkSkZ{YM9bO)vQRW@DdlQS7>GK6!W z7}IPe^Nb1g=CJykyZvemN4~@a^d&nVI%y(AVMYd!q%X5~e3zY;H zKI)gur|7EmKt&#=T(|m=ftn$E9_h40`gT(85|>Wvsd_wPmoTA2BD;UR|8jJq@?@Y{ryUP{CntCCk%(qY*rS z^0*Z^DmOTHETprs*g^FdV)IrcyQ-h6+MP)Z{A44+CA&;=;hg9_e1JQhWz6+KMy^~Twy`kO2^1L}J&kJ9hhf+}e)Aq{Ov4%7W<|!Hh&O{ zRrWppE=D z#pJfFAS|8C1@;hovOr^!gU9-PY!;;Qp|t}^DoWoBW4U#=?I$#_12bBGUjGqWZoToL z$xcpcA3;nTzNWKdE7~CN)%*Mu21%)|ZEk~rPuJG9LG-R`_qRd*q-$&1AUV;snzli@ zdD^f?MAzlIut;0ogUS6q+c`VFqVxW0w!7F>n6?!a{yE-$WoaeWup z4{(XN8gNOt_T$1?f?zX~k|*Pjr=S1XU&^>tYub35eZs^^>9LxK^CPrMiR~M}NJD$h zX#2QPbF4pPvhnGIeev-rDxoUD1Zox&`_ifXFrkvsQ~IO*f_ln`@|3jQWZcStJ%ZIL zdSPD=zGe)pMbx%n;$Un3D}_~&WLk!3tU`U%PzlF$M&H5I$#!p$n2CJ8p=CpniKe@W zfk;mv%eqro^PxFLC;6XYl0SvhdT_=IsgaXwvdWPEgWxE z>(S7RK@#cIPYp5{Yd*H8m@O)X^nZKKpxoDtEF<)WC~OqH{{u~X481WUkBxK%AiCp1VzoLHyvzf{53`JP>B9sZyM_@uUFxO%DQH8C5u&{~ zj0ZsbWt<{7q!(DRVZ{mwyaR0o`hVkN#^Rn-c9;z*mBFh@FSU*25FKnr`_E{Ocv;bc zC>7-x88?X@uq&&tT3%dk)K>&GFd~vf{HVCIW8$dAvHly^mx1x8Gt)`eRH24gt@1m` zxPfN3Xv2W0*yxaKoukjw>8FeO3CyT1u7duF2)R{QXvM6JG(%Csa=m(b+ zgyCZ668*2}x9YhDhw_v3aHD($`>{xp&s*anl;V@OD z_)P+qMplxjQ##+*J;ufgM-I*QgYf8-u*o|C84zAzO(l>q+%GZr$mJ)Ez?bo2I`$!K z%uq3kwFPB0Rj4u(d!opPV1lMte@3BH>_cOV4G)KPoiG%Y%MaBdVO^jC1JNNEq`~?d zaM8|UC_1QhRh@ve3Xrg&xaBzRa`}4(60C-f^@1@EkgLSrF{m+xX1iSe;pJ(&MtnNL zIuCn!$eZFmXVu}xt#bMMMtb;bJQkT%{Ob4G>C=x5HsS+Fb*Qx{2p!`GV-mH;6XAQ& zM2T|wM`IFo#S?YK6Jd`X3LBQLJ+c z1}T~}?Jz8$Wi;~$9yYR($2r4)&Xw~=uo;srkBt0KtQs>7vy;?m^PkGX3UVWPtZqi-e~*U$r%;#0`iO8KHwq!Aw_6`8{eP+?ZbXHWMn zBiVlyLU0aMfrteZsa}ok>2MA&7oTDWR%HvN;0{@$dBQ>*)o9y2K{~%lxKRPY@LHix z0vxsghtltqvucQ0;?jZ{BxPp;oR;>(q~>%C%qFPjqhMBw*ko{uS&E%fSb0y~rG}A} z!BY`OdxmH*`whWEGa+8}G+V7fj~c@eM<+!ww6#oQ2@NdgiHj}=AC(sjb`#x4KCo!) z2cV%mO*-;Rk-IL2+~~XsWAnl=<7<%fv(fOMAcs+w%1+2ZZy7KB4wf%odKe#^*1mZ; zaseavNM15HtRF=-*ceAK!@8Fu?;vV^Xf_VY0_VYO2oVB?kB-hlBV>+~5fVL23o}?h z^(};uHw~mgZ&PVbI~{9yquVF#F9TBG6C$7yS_Cyf>0CBMoiL|@bBZcngGA2=okteJ z(NJW-@QOtxB3b)@U=yj(^l}=&R~i}ew~|re{YRq>TUjygFjn!{kp{s5RP}UFkg0*~ z1f`!r=Jx84K6@E@wLW_x`*pG3BKBLxe%<(0;qSquPD>{d5R4YoFy4=U7!J2>OQCfe zf33xSbCTJ)Jz1mw0p&?@{6)~ zfs%3R{wYS-d%5lO5uaYa5{mx%=NxAH8fr8q_nH9go6x9ETPr=)JJwV|h#s+sOJ$LF zF1QD8wx19m=Sxvvg@D&9-8W?Ns87OKuNPfcf>e>66NRP*8O!(kNN|dzUs2Mq6iE>8 zMpYn&SJv93kNY)?&t4lK$VH1R_Kn{}(mG0tM!;&nBcyU}weR{-(8=tVK^NzFprOLC zjVbECGw=+uXz`g>O6|6+er$u)7u*YkvA>jc6-$N>!>5cy5IzW+1$F=tBc+0Ge#%_naV((Fp1N2k=JmlgZfJb*E3SkqOU7x z>(>=@4i&V9&()ppi{o|Csy+jukhhO?{W!wbIVf5y)x%ged;5+cC`JccOFrr+(0D=` z?zR1d%npFfvp6oy8)zJ=R0}icskqzOX={EGkw(MWxXe@OR=??B+;tl3aw^H2Yu2gTyVuX|A*^NPW6u&-sH z9CQ@3SUIZEQSUMU6t(rTj=Wi^2Ij_wW8iggBAg<6lA zj?t8n^dpcIQxKykwf{K?&(*`&W(h)Oj;S=y*ct=C$x(o59yL6X0Tes1cDZa^kWM=) zJ@`hodTJgTHV9_*=C&)1y}sl#e^?#7>Upzm*8w>+>y40VIr@=Ol-SE>lr$d||Bkr` zVh^zVR@t2qOzB%hLGFv))*F ztT&b_BvK0hOw$s;T3s7(XUO5~y`-C%6~@>F$_ZICoU=>iKr&Qsl)tQ$?u(e1o66vH zWurMDLS*y!5}Y-&#b(1y0aUzT77OoWeV6C}?z5yw9?$JTfzQ+QXqzEvOx9vK! z1?R+g)C>dp)E$I-kXvhP)x+$5Q0mLkZi&j{OQJY94{RVJa9WD(e~EU>mjMwx+>nl)P#Jw| zXf0Qqu0t?VV|^N1-&>9gsCkmcQw3;uJk9M!lC9#@r_JIbICK(Hn!sF`O#Y22SbWdT z7b6?4S1)1^8YoUTcbaA*3OjepBan^*ZdSqovxc&CfawHiVn+fNBu$_`9EtLx5e*7p zD+-km$jfbK^V%p80j76PZo51Bht-^Nn<rusTc_1Q<5(djSMihka@435-=sL+L)A1UY5mIS9*dI4RE4Lk)f_wXb zok=Ox@e-Ch=~r2zuL>(qQZ<;AHCd3$1i|-J%H5$}US5&K5AL-fMwk>FwSlbO zhFmXf62tX=lu%Wm?!qX?;D~9y4D}hvZdjxAN)F>;C&7yAd&pZbCa3-SSAQxT?71^o zY`yr^pGxzR*-|P&?i^aZKh}DfJg3@I2@%Oh*U3G|hze-`>Q93`mV@#zrlT{z4VLJ+ z`)@7PH*x}Z+iinK{P9 z!hJ0R;?(>F+wmfJ)h|FmkjrhvwhTZYaZeVFXNxM;m5B4o5!T?ph4X^(>g@Dxm?9_n z7v>d+wrVhBbWALxxR8iS(T>SUN>Lv3dx{ZhqhDlxEH9JY%R3G^W|$%L?z9QA*wG6 z@5kreN=f(k{DUQqob2ft*8Zjj0aTm%jIP^E;#U|@unj>w*?oN8bC?U6WG4>vC{m6B zsvZQ;yMcEU-(MkmEWTx5i?4nOz8eWNcn#otFX1cT{R;T%!1rBD1^+#KXO0D`P92Ny zX8<%7-$xO`=!^Dl6)K`MPE_3pe+J0;#pylgFB&Uq3_IqFtB=|QbTB20O5m|AK)tA-MQ(?AM2q7-F0+(zErvAi6^R>;)P~hna8l(jpy|{Eo0cW{CQ}%#f_sTRP8>qb&He-SqP7r7Acz|^RAq6$29|rG+{#vPig2|W7+U?qMdj9}OBM(+z zBF*NvRAbE>rZfWt#v)!viT-S4vdn;$5nO)=6JoG=2HUU+Lg%glaywoHA|Shv25{ry zVIQwBxlms~CqNJ9)Khqje4?JJu!{WmBjqDArZvck45VKaQz{qHr#xo*pus@!z=og z12u(r9Hyxs4)>AW3}ZHJyOZ2%i3?Oy=YmPC<4c0$Ta$vJ;P{f}{ojqWLmze^`OeUR^a3We@O7I47N+qZD_0AnSmgT`^x# zanf`WM;^aLDMiEj4hxzRvzuHj_0O|C(w@5?(z@S-EQc)zD%6{i4q1IB2-4C$B-cto zz2fuIz8oxYsGa5>&#TEmOHC&xO_-Y7o?m0N{idA&E+TlAPPe)N133hGi{{ClVp2!) zJf+l(R9hwn-DaiC+-jFY2BBN|-2H%7-;Mf&6|AMpLYo<##gGlvpdHCwf~CV;ESFdd ziHZy5TJDa`iG#;G%<~GR3u_uC$YI}_$7%&r3&01nqLi2!$+Un3#!ZgEC{uGB-*VP{fWdTrHPyWq#Ufe2o)5a59X4h$>XH zgL0_Dl;gkGY$C#30AVcilpmRqp{0E*2C`~(F{VauM{`DKZ5e3HW*^}O-_w!@-^&-R4HgLTP+`^TIqHd`)t6JPet_zPjBd3Y9w~dJ z2Mwh9(gyOv5~}92a*bVCtH;|0N{*=p& z!Q@gb%g#AUhlxgJl0aJ3zhjV*_Sv<`Mi^QY3w{xjQbH;!PKLGReZo!nEf(hDw@#dd zgvbtIn!21pfUgQ&%oquU#fGj;7!#DhV8UXo8jDD4i!NNl_!*D-#&o#0b$cv>9(6t= zhP`%mct;n8Fbo_v8op>G^$M{L$OaIfNxBY$8M(HtYsxFXTTGYB7DADeW(ft$u4x?~ zbWLq7G1pReXqyW*RlT|tjiaR=cvZSP+5Hh?I5Y;RYoymUAud6jAieeg9un8_=(v^==qukitZp7YO|^`twC^N6gmAO^@5lil zJ4vg8o%Ip$dFmmM$E%GaRV z2xQpe+OZOEa=}@oSJvXl9~YVP0}cIV{hfM~AFLC5)HlEpLKOI0Qb+nyCj-;)y1sw_ zjKtNf(yk|zX6|udDuf85gc{oTC@2(+z9ioak?Y?_;|h+v-i7*!17f-t5P+bI<}es3 zPMYn;i%FVI1%MoA=Q7*_X{1}~Of14Ltzl7KidL+CRx&KvouT#V;K8_Tx3%d!6>VLz z)Sj-X#%u#mbkN{2xvgAiua<|Uj-l+$*3cI=`Hk=G=P-^d+ssA4jJBGNziogN*F&}z zrsqh%QOUfK{APHDXwPZY*#YPoYpmjy(0T55>HOji7T@B#eyEYOq5Avc*y5Lx!xtn2s@Yv^rZ_f~b`7#S9UPqYS zs7+Vy=w;C?@&yBLif5QV2+RSBmv7?&%Z+DFzKsto=OLd!aY#9E)&zClySC;gd<3#} z`JN-3Vm%V5MGigy0L!@m04(R6%X#tMAjk)TwwBw5L#=pTKil7k_4@cYeSuZV)$uo_ zsI4d^L%V?`vX79NQh7PNzf2`N_Nmg$5Kn<5btsS&D9VB8x?hJ=f=ZZ8UZXi(cInAhs$B!F?6MD+Ej1F9 z+5MZB!k?scFE`9W;4erQzekFXwO0LY7NoBo>2s5*C$m-$4>Z*FIe(}(LGEG+v%8dK z6HZqs*qx94p^IpegU2STo<_aInMh^Yz)9cd(^+?6U5cd91ysD96dRwWPN$Fh1}0I? zU#%?sF(qysQp%=CAM~S(gwAodN#`7muT>Fej#1nww>xsZrENF!}k{12wGb-t12=}JWGmgrK~9RZCN}k zPLcn$8R;SVMX!WtiAO#t z)dpcAA+I>c$>XxoJ-&n;Y-pHUE)6fBotJ;ek>NvNGl#FrKjZ_Od0R6LGK6Wvm*~G=27br|Zii1ON#AWxul799Se?zD!RP{MG~0Npq5KYsIZ9E$js6BXGIhQ&>RzajzbzS46Pw7Q zxhY-!zCz4)JbIBa4Jz}S40{7-XQ0F`e8Y!h`W(@@xEhvO7-uNP3f6GL$VaH>W6?fE zTF&c%MS(4xo=E)~ldi-=B8^#<7E~DKNL&A)T`uHvkGHg=J@qa{dkXs&f3KaUxVx3+ z95%;c*mLm#7bmszw}U(vd|c=gn`JZj0?e&!4v*qO>=kVcA(IZ}7pAok@1EbdP${)b zWf5I!J&nD;y3#s?Tc>NNA2*P&b?6IS$KtKiuOff~6A7$R)(?eQCx%?*PHQ4r??AwB`1`k#{iUT(x* z9&1SF?o^iDI3($e^;j*}oK-R}1ZwQy6exdca77;L><;0_+YPA@Os6I_5=yif%#| z3M?~IH)N~tz>=Xr(M^#)vSonH-BR3a3fn2SFAA3OVoO#Zn9{F<$F+FjGQOjPm10c&+6z$}1RoFv?v<_8O}U z%5MbQ!6?5GTnN||yG0xdi1smG9U1L@M1&<$-vNU2QPvL>j*fPWTS;ORCT?Za5XYzF zk5Kq^qA(JG4zW>=IF-$u5~c9+Q5443T}z-SV+gE18=<6v95CK`WtFE|Ox{gQxHhfc z;kcBwmix&@$x4lQ9t|!dnves zWc^hC!=xtHl~O*C+*!)?R)VXT1=RW`7(rvE(|s$P@AI=(UlX{Qqv`yuBRQs3LbJH zymQXZ4VJ(bE0_$uoEOrXG)gah!M7Z5{4)&^^6QY9K(??MB82OFW~I<^H?cX^B}CEl zjG|u{caqAQus-)X8Ir;{vgWlt>_!l4TaZ6n zsg^y&v)P(|gFNyUUioQ;0}q|q9g><6idaIuR?A-JIT&56zg4z@v2h-3xF&x!w_$Q6 z*yNW`0<k^!dH8Nmu_eXgAB3^!a&z|t!r zMI2Inad6iGR#Wj1tDjEZ*%(=O)PQoclc6n4?pq342iVIE(*s-hzB$OudYT-Ow!&^F zN!kie)mC}2Gh%Cg2c^?gd9{_=kbDNlK7-Qd8KGfI=wqv8qg`_9khs8gHR)V5*9%U~&Y%Og7h~6(oJnC<61i`Rh6?8Z%AKa3opx;&v`CHE-iLSW0 zfP3g=su=Xm37v(kau{`_5D()P@$EnXRfO^rBD}L}y;aKBA%73?+E>ml*dv7krB<52 zOZdQQ{szkpB^<_KUU`UGPhh+@U!9NbY-rs#z(rlFmseI?jpHu?Fff6AHTxKNO53hu zH@GvDCdxzmiegI@VtBBP0gd57u3FAl9;1Q5`4!eFawn}TW+>d0)+x^L`egHj8!BL? zBYm4QDTPq!WANyE9f>W2{zWDMri99TyYtNYrNNBm<6;i_&PsEw-)R!Lr6t;+^Q-mC z$!a_iGlYg|%bH(hwf*=pWT)vktR=$u$ig6q{JPha2YKh<`Yj4~6Uc8E)Y z#p$gHvc-9LW45z@!}Za${p;a2D3F_%BqqE33zJO3xxi9F^*f;bQa)hGE>FjYq6WNl z&M^dI=+65v^y&+?q3ZRw^#u*l`vcMYGIp;GgS{(gN6Ou02w+wR*-gWgNto3%OqqnK zO~aH)nA9{(nS@lg{*HdLI`>Ts9xy*>8s-;6)wxe!K&cRAdT0FWxcB*aASJXS|+2%2Xq52w!B~(p)Gx+eDG9Pkxf+n;pw0X1jO5G;b{(}B9nNM zkqs7dNdU(T6>$0sWQwHE3?#HcVrYVSuG4FGF&Ora)I)NmUy4tXUnueD0U zy6{a{EM*CEl=&NE>+=B&&hVZoH9XIm#EJE0^f$Tad0urPx4z z%B49uC^t+hsOTj90%ZnWtdO>rALA1kzrf#PB!{vnuyjaXZN}m6)wu6RAla|R!qD>~?KD|=?wUNJu1;;9-iY7Ms2DvcPEf;3E)y>gFF=xim zM5BDwr1=C}Pu4pj`G}>%IlO_#2>;_vAoXA;Rh|e>SP9aH7U>+n?uIi@!B2emOh{5Y zU#3W@k6UMzdM%bNJ*%aE2HHlJq9S@b?hnx2grB*%+_+{PfqpMJSYmE1H3v%)0JgO> zLF%wboecP)IB?kg#nZA>W>}X=oe6}(Z{w-98)-_AqLgB`#bc2F4SeraTrc2y7T1%w z9>?_vu5GyFqMx1$6g_+jcNKRP_tUta#=Rf+e%#OEeiru#?h)Lva(H-1;S{O^*qKFQ zl+dZb{kVp3*=GTEF;8Yr+o`mppN*17LxAHLYJe26w2E*eTLDJtpEW}Nw2Nn+qGKS| zX5lOPU=OJ5z$0MA>f@YIAK6qNn}7>aP~z>aczzn!VO+ry%d8`Z-;IVmDhFU^0hzhD=Hpt3s|eRJ zTq|&W7Z>Q92|8!uo`E~e8-ALOI}90qYR8@8t+-op=W*w8=Wyr7){8+OKj5|EdKA~Q z1UptQB^H!^R6VeFly+1dplnEEgpH{;kJ?LaCMG|J(G+GYI~^EIgj;<$yGX5{jNz#t zIzq2-gGXOLF>r~AbYLekpaw&`@xmb!Wn9kbK64;xWi8`F)m;F&gVF<{Fdi)Tvy>=} zL0~HDPM7=eQm7kT(5empp6D*S9#886MNPLwoPVj{^;1~Ox@PJ&Bh2kYcC;m6&mP_UsZ{@~Y zj`6nGc*`^1ZZzIp#@j68t;l$rY`nP(sJH}{qX3V35gv=Yq@)?4Dkfib1Ms4OE_VRi zE9ZcKPF|P^j-{l4%&i-~l+I0BH&Z&7wQ-ud1W7whG&{hmh~^*J`j5HDQ5)dHP3K-k zz`Dsz=MLb$F-=8HA~BC&B&J)ZiTs-2rHRJTc0R0bVh`3ZQ*Axq#tLl`O?y)0+YMeR z^24nwB-Mcx-R`-ta;o;gbqr?H{AqLWCKo&o3JWk2d&f6Py$;*JV2!d0Dp9+7Ek4q6 z+zSIByD$!sK8n;VNJ;Z2O>rbwlM3j2rb_rOfKWa1ZQC|l7vrP0hkr{Cs>3*mqlRy~ zKs;*WoR}qs)t6AIk^lo{7%`LdmB#7495~1OVYLdn!L&BQ+jeyg6y0w2L&?0Rmey)af%&KZ;4VUGQF& zhTn^}U65V%@~I(kSyUF30G0_&=LpY@@Rda0x4p;};@p-laAEWs!cem7$Uu?D?5`zk zhE1*IL#@RZ4Qws~Hxfc9<>L(ZRD{it8~yQ47=J=*j^$Ls{;=)E;&HQzt?Z-NL}rHx z<`p-QWn#XM?HUqGuxH~TSQ4?_Q?News8dei4I9T$vQ&A)ko0* z?V_qe2r~bkGP8|T1j_&2{AtXE%s^RVc^LLw#DsG<}a|q`vWXon3kXTI2gV!$U>7;ABfW` znG6%R*1&>p_!55(jL!?vv@fIw&4np$>x{I65Dc^%&+%C>+p<;jILF= za0qE{f)RBVtT%O7bmImKrUdP8N}*0rvqNE}a5(;SG5!QEFf6tLVkI;NEWIK8mXjdg zUM^4Dj^bD2&!@YqQIKP@>ij}jRHgm`j+bEc%R14ws;jHqK3%_=r2u)atwu*nS2Jjp zS;Bz<_adp-MvJ(bRj8^iUHeDWO3(kp@rmMuI{8=kfFk}k68xVGKfhSx>RwqqsV?xV zS_Jm|k$zt}1PhU#zXyIsCI-Je`P#j>b+pjtdDAb03NdqsKRA5ua3~ncvb|&5-QM&8 z2WgW0uBBTF+x1!h8$Q#s-}p|?-=m*Lz#rL%|9<%5;lBp|iVp{SM`3aJ)ZtU(_FayP z8bZzV>_6EZR$s)EHgK~0WOvW!VRlo)$6xywl;-#!>35*zd-!z;yiwHTuyHq^NZbc< zgnRa1DRD|Pv6dW7{a)ybKpp@6?1Y+OCGCHW(R^zR_PG7war=dYo?fhB=&z@}XXwNS zFud;V>F-hB3-w$)*%KxWeba{~v})&ZL zXkARFcWWu}V3;e?Zg|?G4HpY4HrQjDQObMW6?dt>{uYhx)|17Nx~4`RgtGK}-!Q~8 zOe#vOa;^R8AKRJ-@Y$zbwwBN7ZWgYR>NwNW*!%b%-sRKVx5xw{Eb+%A2c&@5+$KEy|8y zGK1K0dB$xmI!q3>*vSg?u^fghj61cPr3*SvCpw5J_8c>VwklCGXoYLi65CYtodFl; z5Yl`JK5Qd>$S5a(2g~_ZUQ37MrkGz%P?yG`<~LebLqNCO>cA$sVxAe_YCO*ILaDlR zvOr_J8x(lz65vc`R~wCz(Y&CgMoae{%%XbYvlwKlP*$^e7eoy?cM_)ojXQgKg+z#= zqf*U<2P41IaiBH>Qbec*Yq`3n<<N_fvWC6RWJNRK>8S{I?=ZYDF6t} zmEe?Ai!e`8d0~24nJ^J=wiYjWX>eT(qmFCX&vEigh7`sPx|g>Q(n zm^JA?@J6&O?zJfsjU*gxnCtB$af6KD-3JxUuM`y?*7^cf{e7Qdx~1&bvh2HJ+52tE zF~ku5eFyNMZ~@ARZ0KEmZ7kDm!Z-aF>IH}Y!UMuY|AmdVmM18@{374?3zm1t-uF}E z!O_=3QHyUD)BRh`^TqL{rAX%o-TNLu1UcGa+!~03J(&YVh2RyhR*Fv(OT+doZbho# zboA0v;9u}?8klLDu!DYfbNQ#_x z3LOnWoy8{*WPZCk;_yC?utzEUVF#+$rMyN?2%QH4jS-vj z2EySv6!bUs9l_6NY>e*`8iG^J0U~atg|cG%5q4vs^cd?}+8b}`Ebb=o+6|I=H>@$$ z6ydLBwq_M!eLM=Nc7s*$wz8~IUt|Uxh@bjC0c}`8As%DBIv0+0V0$okp!gy$OtI}T z9l@v>!Iz@N?E4E*^S%=>DvKbtZzo=N^b#dt@XQWc6s`UX-xcBZte>#L*sF_hgM?k8 zc<7hQFd(Oc3*na$A07$(&=OaaeOoptU8gvOVB4` z5jhe}t|q*GM%H;^8Yf1RnH$v(v++C=nT>y$9qN0S zWn-s}BR9?eQ2Y8pdyIT0p(a@TW=HX-IUGE7GB<;*#hO+YO+j_hVHpXDMpyua&+sI2Ck)j{RHglI0`An;JZX= z`Mid0gz|Z`7e6-Ne1f$L4x_+!Xjc0g2ldXN+>zQT;^`Ec+KWu+*{_%P!*V)_VsI*8 z@!7}ja#us2(;leWr*bNw4DBxf zn2nd>2)<88Y0$BK5r2M;2u#H^By!=s!<>UCsj(Z|=|~48*9;AWUBYz(on|2kRWVOX zhlK=t%+^u{!U;kuLLI0cR3sGjz1iZaZ1LatBL99EOOw78`;Yrdwt}gPK9R*)rI&=~;}e7`voJx{%BgZ2bsw zBHHTC zB>in95pqTv668pJ0ez>@v%3hu44fRmiCC+Jl7T}YNoi#$gw|*J?*$6HF5L?hT#4i4 z@ltzMQ-~qZi#4bLt>Hy2NoH_!2U_$k%b+lo;Yvss@`4tyt~X)VKI(09Gf>4sb{5p@ z9amr?VfP}Z1o&WTD@+&Ao=TQF2OD0a7|*OZ(yZ1 zP7asR=3%M*9~jG9Nw5%+V4^++^1$c^t&Fb>EFvrGB>!^GrP*jh)i^xz8i!y1Qt5)F z;TQS>B8@(I8-TDzidx%E-)8EuTjU5MJS-<>C{Q5(2o52WVH{6NG&xD?G^#}kXE`J5 zK7^i(169Eg8mck^+|Wi%2kik;92HF56{R>)cQ|l^V1>1DKs-hMHqvvCJI{=DlLBrK z=9sMH%}}-KdyCpyaW511*pMZ^rdO!N;Gva) z#@PLlqW*;vGoepm)K5@8LKjhJOwDNc2@1VG3f8hHtcloTCSv%;_6GDcKo=Kze0)sg zWB4xVrQqxHr|ko;E=-3zqt^il4Ynl*9Zj1MLu4*P1PtUQ0;0-lAIhyh`w?>aEO2W; z+d8+@cy_EsdF8>-#|bh=E(!_h_uauQ!Ds?j04Nukj64YPO_h2IzwR7>PvruH}F^RNF31cbX!p;yZQvQL@ z4R(8Lr?xZkI97Bp=EyycEk0Jb!1%!8KbIihQuhpRhOd2N)rIbIUA3F?&I3@;4enFM zBl*)1UuIpzI!H^V<&ktyM+REy1(Mj_9BfojF;8N{C>kjdC0AE}_Mr}oVQ)U$?7BsW zmi0N%V>P3P7tW8K{%fq1UYUCi$F~lIBq0Y28*I?CVb2nccSNsgOSNk#6q37vPy$5z zsyP}ZCZtB9M0?Jo{vPnW-V!JKX2UiRYb~%q&U7;<27>_FL}d(uq=+Q53k-&3SayOP zE|F9YGZNM$3+d?_lA0uBlnKmEvIG;FJk5ng+#dSTmdMi<(hL1)3*>1<^g=({9QC)K z(4eYsAO>EYNEstuSfF_2>Dn}TS{|jOAD=neiq-o+Kn9WbN*B!HRfcQbH$luw^?5{i z`?~OqO`1JodVcwk09m8@OA5zU*x;))g+X-9!_+5|iUttj#Hq4p1wyc+A+UUfc$@55 z*;%r38(?6k1H#2yV8LEwvF})hA4|yD)i_7tZX<(pk6UWDN^25eNHCdF$OV+7&~o1S zM#G0%Lcm6-vF}f%@58nT1F61YC3@8{$iXMl-O3kbam%tjnnX&)qjU?3K5xWR~VtM4EPTh|y!Np<=xmPq}Z zfKaU#%w{}}(n9jl`Zfl2KbHMQK($*v6o09IfyKUp0DV_F%4DQ*tIr^$-tI6*Gu3Zn z=~iYDqtPvGSEiKo7LNaj292Sv&Ni;sjUHn6?P6XtxYS2JyDI6?abbaAF7>D>1ORrNW=&PN*T65B+-lx`Q8)2A&jgrv3UDAPYQ;XJlM4t! z-gF_qs#<*mCr`_&x7fe9K$uyjT964Fw*pBl`AkY)4Fvb6f~q8hwp`4cF7B_<84{}P z&xj99BXEIhSJ!qXl0OVos>#s*RE)(w2iWg+qv^0J#Pq>xa0l(A4lH;SFyvwE6$8^k z+geFCQi)xK<$#7}PFAv9t6Tlfb5tmJy21>}`*_tKrh-S)lZiC|D-IzAUrF(wPZ1Bn@0F!YgQGlw^VjKE3}=|I__Hq@SqRGeZfOpC9O9_#Vqfw6CTiptVVuY^Ip8ydK z((S3Ngt&Y@G@Ytb6K<+f5C75VGEjU9vnngA$g4#bQt9tta2k&nyZXtWsGq?33ps#+ zj#VJ^!dfMJzv3_)d zt#ZKnZX$pkhW#4UL-4K?a~n|MfwRjYGPArDCB)*k*gAN47H&MWjH&$|^)CnpqiFT^ ze4m`!>}OK`*>KT=gEmI{{{ZT6xl@IHxRbtmM{=@;AW=P zZ6XF@7{|VN&?6t&ZNhlChm;qy-hPeLuflZ0pjJr7oyR-xd|OOS?bMP}|EgL1hv2rY zR!DXJO|$}v*`yJ$1k>u8flm7>2APAgmVuFnK5apH*7jt792#Z`K7pzDIJjA3_5IJ>kEy3eV zs{|ynU#?j%B+dHW(5$yR{yUm=I?woPHS6{sM1HMi9kYU=TQ9V2`#mZWpS3-_gC5!) zeazCbhTlVDo6qcgzqWC9{sMAYwh+az?Yi6n!*0^AM|JDfQN8*~NQn%+`k!F%cqO$uTXB&>2||v?yo2X_)6q83g&rF` z=cVB61JVKg*oT8hThgBsGfSjlOXCEEdk!K`aeN6Jo+F^)E7ZCns;3;p89UG>(g_>` zmJVRb!sn}f)5(oS_JL!)Zv7T@6^s|ac`x6Ti8wGZlS$=zi&_*7mcHPyd;XIsA6o&% zKly8g?8N6_>UCwc8J`K)0yc2&GW-g_Vh46I*u=uMqAO*8bvO2Ceb{0bW-P@biC5Dx zsFAEi91nku*tJftSf_i*Z^8kc()ujk8FtKbE@ueaaH@E0OI-Nl+;;f8k6L_L1?J_s%u9n&;;4&o~ygmRI337c>~&VG0BZ8=%)n)N!0h5$7c=SIO)EFvGo40)^< zcFZWPcmm$}eF>}NK_BnMn#}or1KdEvP7fm|XNQ9wjjYS0EVJnjnBi^iWi`*_B$$P% z)@(19jgx!O)BNC}VVPW(L`NW(CD>ksp|HK_BYi6jB{h99#YRHC_NEJT31c_TTYToeyO36gVadjH|9yi{3!HUZ&ZxH`jTb&L z(SWn>w8~rU$3BJ~XzZw7lRx##RBWi!UDy$c{li$0JjewmV9UGi5Fx*{25w}ut|#6b zW4VD`VdTI*VoKsi*3mQlEEVhJ-C{V>;A?w%x_=29j`~ zYByAcO7RJIwTeNXMm6juA+xinT~HPECpr&cj}9Tc+%=n;aj1`*^#=L|DcL95UhLV8 zoPJEIHWUNSIE6{h_u;DfCDTG;SN2c?*JeQK6BZ{rk3k@SJ;N)xKt^3)C9mC~yktf) zY_pROg!(3jdQ(%okRTQ2Ngt-tHb8sJ>zD-Wmi_X(A#HkUk7AvO&15UNCYYB1p@TS$ zuiTpYMjdtvvgUAz#HPIFQw)!WGP7){HY{WWn_)2Hj2X=Qb6c5Nu$8&Su$37GN~53nTuTg0!EnNCa%6MVDo36Wx6Ane z>F2}Wx`Z?Fea8iCI~(wba)n|NOCVve8ahLt-`8u`!yQ&A!5%pZ^yMzW>1BMti?4YN^e zjsNHN$(!y3({=^>O2-iYf^Ks3^1-sT$uxtGv+9xwg=&Zni`8clU2zJa4_Ww2e zWP1g^V%R6QyT8^xIRjCs2THts4xY6uD z?;pbTCax2>PT@L@>nyHhD%JlM`(*lX88lCTwI(xDpHR?qH;x%IvGX=?o+Y6EojDy zP%MGroq1Jd{aIw#O{_2(CEttn5@vorFpbh^GpnmB>-&*_;?}S@Tk}k$g+v4Km`>om zJRLg{$?*`}zClgy1p}A9gJNkB2hZ`DF@HlyMZSp)Kz;8aFI#XPV?eMYZ$|?%1&STj z-~|aB4jy3|jb7dbiKauJTu+NRxO6z>eBajmII@ug32rJ};baY|Z(yQE@#KB*3{J9r zZ4y}9uuKIe@8$@RYfiz3yHE$t^MvsQ@V7CzD0Ddr%c2Y{i4-y%ymvbXg_{P7(>TGE z-JT;2*2~uGY&J*J}=N@M$ ztM2P%b?iq_^30l>Y(gJ3n}jy|$(G}JEk z55A_2klF=A+|i1fVAJj*I<*CU={>BOV1>StH3EUdqIw#|d5q=(nbkck#@0;R;J{$+ zBpB2LvS1g62|RHJ85SFKHyQ$jd6cK`H^{(R!XtRdugQqFgbc_En5`=g;2G5tGK`i0 z9S+G7CJE3|V}yl#ga`}C$PLiaz#|#8N@@pD zr~pYwx)FnxN~I;?fpXuWORCZ!q~q%dnG@}7@S3y@#fD=7(N*0>UCj;CFHq}{K}R@D zp?GapbsKfFXk=HEl(Z7>Or!+V)8IMId1ed5Bzb2D9AayhKBNiMe z&fGzni275b4Z|oXD-=QR`yEo!aRR@>J-=pD?*nC00Mgd-C_agH4rwA*3$&dGt!)dG z#(fV^*1@fXO7T87YiW;0(XF6}Gh5({Y+u56nmf@*rhF=*Oehy(I%fR1y!1mB4v|X0z!@eKlv9gk=;7f^j zUs!ZI!?tEJ=s|<9kb5kQ39p>LWK6g!-VAUQgwerZkheO&=7e!roYBn)HpU=_ynsd= z{cUu$&D0c$#Kt$@Cd&7MRNrPpP_#QQi+*k>(AYh;J3}pHe681cL70cZ)POZ+__>OL zNB44SB1YqT;gZJ3v>4#DT8?^@+jYn)Vg16pF(`CKu0%KW>|`~epAzgK?k2U6JdDjyW) z1}n_qe<68>J;Zru=SCc@H5B}}dL-bt6C4+IxBsKC(4TL@nG}$Chv6z}h+7xJB;A>q ziGl-llY1wTK&2r|*(D(F9y{Kjddj<#O7xU=7XWP5VYpHX%E=uDhPj%@iFDuob z;clc2EFhTBQqHD3Mt=qgq6ZC*KewYZngp9lf+zJg{Pb<3W##KSDy6IglRYh)Ac80E zS(?pKOOas_#t`&Oi0ZT71l6U;#j$~hS>TXpV{_+7at3MMlMr8EHw{#ZQzSJ_u$BoH zh&$TIcs<-Uk^ORzF^1bF&~x<&#Zi6H0xKl;?gwHEif$IACXSlcMk@Cg+5s)Pk@&;;VPpI*n^KGp2kO7 zw>zlXGY9r22zDdNK~aFMedK?FB2BKsLJ(k&c3YGxQlxO*)euNRqQP3cJ=o1)!_>7n%+^x{+rureYqICqeDcDN<2HQOEuI}^9zO@zlz=InYW#X$?d z0>;V0)%gXqcSD$<=E70|C4pqD ziM4*1&XDUQi0`-k0@2KF2l{Xb2)Gxun_7;GKZLL{VembL`wN=52||iB(R8+E7jHow^)oRAoX_fH{JlC1$|$8Aj?S}_U=!!T3{+xo zy@D=nf;jGuN1~;WKWCcD`riRT$S&VUB~EfnVNN{`LzO_1Y#}wK)(2A^`LEbXv)Y(B zR>HE38RXkugqM=)GWa(Vvde_5GGSVoa8((zpH40lf8eugS9K;)>(laCQ}x;E`$2+TYhZtigp=@5vIo^ub3bYYt2M zErIf0WjS9>+rjLW_<7o`-p!0^GT<+im|VMh5A>PRBHrtTv1&nHDRqcccw$E=36*&$ zXura?KQC*kOyLiA8PKY(cU{T$YM`izGYhjJCtD0GJE+$J1dYhD~Deod*6jP25EV*fLc9ZF2(;yAVMSoPRl8-2K0n7W z9{`P)!YafJ&nuk`IM8M&yV&Y1wyz6fYZ`^wTDAiP8aw~RmspFDQe39)gMm+!E_?A9 z$k7UoN(&V8S|`rtu7*V>*l?>p@)3YOixR=+R{PyZ;>U>$34p;Wc&=fV}O?tR_Yll*bd?q{m&d_U)Ve*ZpI zW!~-6_;6LVSxb06Z#^43cH+Xp#9g_RRtc7#$IZa*-0=voG82egLN6@YWgb`>ILDlF zyh=j?4rSF<$n-LQTgq;vbWPM^(buk5bTTpfq>{CSTn^pkHKp1 zlt*FBW3ZP>Y&YxleJQ*AOqrpr>*Gm9`#9{5<2YkIIC9-DmYt8Cb;X)WV)(uLcJs;4 z%M;Gq^vtAo=x7F*trhGn_jOt@SUy1$U9wb1f1I%mjgvT=ahLOJBpnr~;|WL_GG3Y= zym;TdT7Tum`-8!Y_vf`w#_*bTqB92XJ#g=R=EeJW^Wy!Vn-}k=ru5?d<5yn1pA25S zKN!4t|9$V_ZTosQO6DR_1MiGN;~ndycyBhUV%z22Jn#8G{*U;R3|{g- zh+i9c$$#RbiC3^8_#$5W&o#kyFnrlRp4%2^;(NR15V%i>QN%vDaSQ*v_`ANS|iJpc8q2^L(`rbXV6Lg<6{F3wR`#*Pt|B{wcJK zY~lb6o)}$b>-n6M)y7`@&a1D|bI3>WKhzmvy1 zKF&vXe#nu?yW@A4Ud)%7wB|nc5(We>xAGlJW<0#(Z4(doj~#0X zNdFt>O(-@=zVNWmzG-6YI62)oc_T`LcTYTFonDFHH+THiVBe``{4R-@dnAn3Y%9#@}=u1r+%^b z(Npg|u>QMjD@`T#KF05Rf3p62@84BO?1D@qIq^8lm4j^JCC_9&doc@rZ*fVZ=kK~` zfEO!&^lk6t0i3Cy@4lva+ie%!*3e_F7d3dQnLSfp5#Q)D_wVMfhDMh^#i^zi4_5Jt znx-W@XnM^}%iDNGR&vKz&iwxS&$=kVD+zfe<6b^>wd)Ouss5?v-Y0maaB}_6v=zMV zU{jfN^}w$FrGLEL@fZ;bTe$A6m+p3UXm z+iqpwo=s%`-8|L4i?3GGId5ySw#u^Gu5CZynLCzT=-GB{<3YaUjT^mRq{sMk^w=@< z&>X?~#j!j3-?;SH6$9_%!3U0rZv4ZK(FO5@o_8fLXM6V5<2PVbKYaJnhTx3|=A(x?N-}l|>ku!zn&R>l0~&8Bv%Kvoo~7yMDH>90>8n9f ze2@j(JCy4jeMLRb=y3#xFBnn)4DaWi9$wYM!%fCRzB=Ca&^*5*@4iM7ZJa#D#OYNV zC)e=fz(3)w)sC;%1~Gcx>K@oHfztZEbN5>hDKEAsZC-2*@^OrOyv*d|M$+tx#M0$F zn5oDdr64?wlZ`h$Nt>m#{?q|}EFGh?-=Gq5^c6=Bzx99~ypw~iOM54-NjrQ%^!9zb z-?~g8(S+o99vi#i%eb4^-dMh3-SB~3&~?2|*JIu~JkdI4BSZtmJv zCpZoZ!qM+l@|lyD{DX3@`+Jp)vBox;Cpo{edn~tb-Jt^g<4zNW+i!mxzx9+tm!|u^ zv6?31ZsDy9sKAC-Zg)J)Oi1)ZGTVIBk%GQ5Z+Uv zC#iUO>nCo5$%en90>Q|*we;lfZ9b!;TbU9U8dqrWyzLPVyzm6V_68H-MW(E0ZLja> z@86a>Yy15>`d_ha)47VlwHcn0Q##OgX^)?F>K!~I^#fJtcT1N(*{kFyT@A|#9yWZ6|vMa}zvmd90dL9kbg`>O+2>cYh z@OO9v3s?d#zG6-CL*Px|d*Ex}24LFdO`5?@y?4{aQ}ef*12g70&FT9`Zn*oM`?o!E z&;D)y1|9{Efd)7Legc-jqH9->a4e_{)Kz!4YQNr!XHs zi8;fL6GkRZcO=;VhW<7C-!PClpodmRILG(#Iil^2+{Kqh&uQ_wQ;k`JubF@4Dvc z-Ctfa`0w9%T(h}D%*USG_|5&#ERwlR&V_SQkqqT&{a-Ghe-$0XBNte~=Qz^#u6I4X zEwyH3*O_C_7D$rg!c58S6GLc;-jE2o%w^#~R^B5WeMIJAS_Vt!s$(4R^D_acyB2FB{y^ z+iyz%yMJ?FJj0jCHtIOdT8`7?mwv``00ZvGa{nRc*Y>@#zw(BD-n`*m zmKtE@YTq{qpV?bRN0Xm|{KJkiuqNYOdK5`Ly!4NDVi5e*h=?&^@SV&Zo2UBDUbExZ z`9A7P&%T6%$j3Y~b~2s&*}1+QFU0bBXJ694gBRitOx!VW%p*I#KgHK(_Elfx-^(2UDeG_*`_xG{=mUQ2Z?!A2AbLpmNfT%A={C+E+ zmaOK?M_kw0kGMWLwU?tm_R!D7xn}YEqKkKI3?_mHrc49)Q5L!nan@H4n~ZGy$|)m^ zoZqB}&OLkH`y^h`bpd1AlQ|a4lJMRK6YJ;C+RnP;Qexv*_nozEaBR~BOZ!oB(qE&G z(ez9By+ObEgzQp^n>F0fkiH8Auh^^2LJsrpUwLx^Q-@P7ZXBFrWsmd!*WpeJhU@96 z6Zb2C_OK-JXIbz}|Dua|7bd^hA7}E+kN51#4c@pt`Sjl8*s;`&yS63S;q{Lm9x%@Y zS(`t`W+Fe(H~H-`ol}DIN7e??Kxp+zYn6CR3Y)qy{CVB z;-R1JeQ>}INU`MYh4&(vcyQp}2PYnSX8pGqr?#!{J%C{1p=Z0S_a5j!{d*G+{pv95 zqon_kv2Og5Nyy|r9_(bUec@noW+42Tm`Q{`2WFCEYatx{`-3xSer-z}Jv=zI_G>!7 zeEQz8*PiRpq>r6?t~s+j$lL9QpiCtCm(pB$2=YO`(7-c__V=&Wf13xXrDP&~P)Y~@ zO48?QzjI8kPcyQImre>?JT`InfIdBJR4q;1&9GZH+mFBQLA@_{igE8z*FAKqb7+|; zNp$qE@i?DmHF5p-cICNCJwR{_R=sI|<%-!LMh$?+ozb+P)W`$kc*2H9ojb zZk~VP*t!dMocQ7snQw16{afC5`Zz6We)R9!@PO++aB8@WqGNg-7kwv7iI1In#hRJK zd&Z8Rd@rx4zNk?oChwYf?3n|47XtZu;?vuBLW5U!H#Evd^6Y_GB$Mo%exH^CX=3B# zJimB=r!`18eL@*&aBmnD5tD=sw1a zdmec2QxEV;n2$u{`aWIafujnLmbi+%!n@#bp5)?*zrs5u!n2|d{~mbZ#AAmJ{4?R5 z>9gk%h#9Ypxf7d<&wQGq+{ZhQw+-@zHxs^e@{_;=A(&jiY#c z$$s;DU*i`%Ds-3gVqCEspKJ&mehd9uA$e!Hf=Dvs8w|Y#1pm5q*P0;Dv53c7` z9D_U*0p*}|@iyLV!v~JWj=Aqun^}av@4bo7sD;xDhO7;50{RR$YCz%S;mAe}BdN%% zoPPGeB6l<_KU|W4277>(Gs$hQBkhf>Bbi0yHDkXqkzMB98^H$_Pd(Fr z#r#MvaJ^zsP})#Y^)gBd!{r4t)Z&}#&%x{vd7BCR#U zV6niik6z7D_U^?|vr)k7e#ZKzoPCWiwROy_=rGF-7llrlQonY$7QuFJvX{;N-pBg- zpP9Ip@!jdX$@if@!*g!fFW7y-AnRXu5>6I45Dm@HK~44Zg=5+4gQ!|i(rQMiy}fG7 zo`6W^1EywKFWBzLuD;!IGMg0zhFyfG7WQmFena9J`j7LVME;wfD7hl)(;LO(PcbxvM>mJh@ z!^pY3hvxV-yWWx5IH8w^X=!@r#)%WY zh_&sDS#RMZj~DQHnzML!^?~1oe5OBg&isy3BxV8U#IxQou;Y1W_3t>=26flk10RB9 zmVH=dIe6E$LAKdxf0~?V(MJt0{xFu=F44A@lq}G2;fsZ5wP*AM{oS=y=;?A z>^=Cl!t$#dH$86hky$G}?Lj>%x2@GT@!_ZXmbW){%=2b}KDJSow=?$~basCBx^0O* zU*mG79M`_&>1~gBJ5oB_-MAAq2+ewtk?wrRUd{?^&D}MxpfyN5v$%#{b@6H5$uq`+ z#^Xl8|3blUzH7%%Ca!thQEPYq8s-r9JKo25)z$qkSzcb_oa=ZzLiD`SVOX(ldn#qso`jkyqzlgnq zAFaP@gm-ssukU(G-_-U;cD-fo$gT^HS$fgPGe3S23)KS-*~$crk2`qFJK5;mb*(-4 zZRUxC7yW&iK87jtQc*+CORu5RAN>2p3;X%1FIySLI;qEr6TAjSj2zV(`+aZc$&~(y z`nq%Wj=gL*(}e3bPdMK0*G^nDxci!?ZoBQaM$Xf7WsyDOgG_|O-q-2*&; z!i&E(-8%EWD*n7o{+#;8?BdvytWAFLTU5-&i8}`xpXC?V?7p#oTay{s4tgruLcd#0T-&o?L(T#!0Q~==la7Bxy(OEnm(3?YqB{)|ud!9`neJ>&9M; z|0iGY#_YkX)@JYjSYO|x*%rSR`L#cL=Z<49-0?4b_w>$U-vg9g*K)^pB%o(dUDuVFKtmDc*m#;el<5qYg37_L zJ^DD_tG|9PgM&l70Wau8q1a)>#f)Zl4F2$mGoOZdK=0E!^KM>8wV}Cl$K}s#8#G^- zKk6(#+40U5C%0>efwQai>0j+5KfP@OFSNb)^1-LKt@p+TCbkc*x%cwKTb3Rhx$g1} zKjr&Vs)~d}U%E8|9d!bDr!||GwQbMFc52%OGyG}oZ48XOWO?1jZ#J346BlAe=y&P+ zwq_cs%>_E{wEFd->%=n;_WxsauS^P-U-Aw5 z2BQ1_oBxt2uyv`=nfXbd^9}GVa6fngT#x-nz}vwz_pjl48sI>K!x<10mlIh${59Z$ z0yqY|56FD_XMIiul))(YEszCiuogVt>~reiyTAvt;B%k?#=&30c{A6|;Mc(^;CPS# zzx-*R^9Wc3KDZUk!T%PxA3O@41cOiF4!j0z1#bs8!~Fy(gDb$hfeT*Cd)rcA09=M2 zPd!T9uup+wKK@IEylb{T)1Tq=k5$1vdcptbDjDs7&H25O;GPoUl3;Z*9 z6g&wWbQ}lH0Gq*^z-id0z(LaWDewsR0r0`!fG>hS0iOUL2ggVc<~0ZUoZluc9|0c+ z74T^=PF|M4W#G5Km$1uleJMx*2Rwn>I`{#&1AG~L5ln*{K^csIw}Y($ZcgKR99RpU z;uRTn@B{D-a0}Q2Jn#|lKJaF+84Q7wz%k%y!txN<5B>(oe3r8ISKu390r2h+=Sk3Q z)ZYmalk=}{w>)w3`Vr*LL~r+L9SY*Ytd7~Zr(x%mn(^rKzR*?yPJxrez=jNikjI82$^$5@U8qZ5iw*5_} zjk@l5$TF9K=auig_2!$(=Gz=hw=s&RcfRDq$kS=35#mk9ll=akcFpc+{qq6ukaOD^d$-zQ;Oo#zXGqN zv$RF@6>NN!evxt{%iL^)S1roQG3ngRTa57Bw4ufFoKLjjPV;){wA@nBo;#e(rVcPYtiTuhv)$!x5v}ID9h{+}Ykn(@ii=d$o7^O;PZ-a&F9keha{h<*Xus4J z+He`N{^YzUkL_KVINnTzcLoPrSK}>2cu89cV)eBmyhL(!ed!x{x#cHr+;htv*E>T! z!k344aLbl04}pVLo$=R}lfZ)bmf)FoF5T+c&P_*nVZDeePkw|K=6@Wo5#fdTAID2h z5f9I6dLD0l>(O3kqr4vFvl!up;fpJul?X2kUmR~1o^9u-m1>MJ;}TWZr3>$rEZ+2bZwF={Sqk+Ch zxAf*!;Z^fz9Ct>(YU+=4S!4RL+#K?zQ>-dXYMm5z+wQnNKXQx6>#p^KDSt%n8F>qN z7|uTA0z+9}e?TtvN#y*Hk!+3mCAoEzDrKOJCZvHH%zEactKwn_tCM_1JJ$kPi$D7_a1y z4Tni5(~ry`S7D$?#FmG7JdTlakFmLr5SQC*W<#DR?3#qRiK zkdq%uGB2zT3Tx1x`TUg072we_d5-yGEv3t*i|bn(<^k}M$?@d)(AMj(4=g*=&sgSa z@FvUoe0kEAGo_IenNQ3kzyAXaJWA=)HW^uWJ{Zef175l`Q>)FC(u!Yud}#A2`A0U~ zCg_2lxNv9SRcCC+AU&#MHax!1kK8cwdNP?#rIX1z7Bb>>*N<}BKN8EDIR9$!vaXx< z)2jQ&~V<;hf0U0$5~ z1?0GPx6Z}Oo5-nW4DoLo>(cMyK`!~nCjXhp-#Hg2&mcGB)>Zs3AXj6j`Cwf5O31I@ zgLynY{i?|AxX4Ta73bJ;Gb?{8)q1s}l4_0o>n>l5@Jf|R0+R|7)98zgi(Q=MoSOrG zi%wU)FuHR?$ZfoO`qdjZW7`AAcN`x$xl!bY_#vZu zW7}2T+4YhN@=75s3zI+H?a2)CCM~5*)39tG(H-A;czt~XiDcScDHn0=X;b>hN}0p; zDcr{7Qh#E`!D>-#=Y+M=vD;r4o-s#g$4B8^fBn{>8XnOVwbMlvQ$kwgB z`;R)jV7@syY2y|fkHr5O#DmC0^UKCJa7cb;;L(l_l)Z5D9iJ}4@TjM?7L}*f!(R{H zK>6ldRmXziya`{sp4xIU15bH&Bz+4ed`4TSE;ha`g^y}<^R0LGOqcYu@{N}3OZ$7~ zM;;#YCTn`cw**h=;@7H`UimQ%uVk99L}GIfeLlRf-3-&Y-9MVXU9NKt`HNwu(=)!w zKQ;CJvqYq4`eorMvZ_mF@P;RG^`i(+>2f4qMLg!tGNHb>`a27+JSm@hhi@^^H+}?t z&ZkYfC|Sa3SZq9o;FZ0b|MJ$)t`yT)UIAXxNz!Wc=9S?w2}_y=E6Crte5=7DJxr1) zebvS~c3scsM{XXu(IH(DVcL4y?O8+q6-$o8Kv6o{;|p8AlAob}s=G`<>aN=0K$nkS zW*sbpyp%8lh@R!508j0W0eWQO%0*fJF$q;lh4~%Ft66>8Tv!?Z#qs71Z(u;gUizBw z5{ZMAN`5F6rdOQ4)MsrwmpwxGTzCgPH*=)?9))M?X|0$xsS?enc0H}aV^K|}XL+21 zN0O*}>gx;i#nqQOJd>|*l&|gn+2(8Fznk)9G$Kmg_n6#_{DDH8-L$ca@?1Z# z$}LEr$~mSpyuOcBu7!N8a?OyMt?h;j_(BHrW$h3A-Xb#W%I^{!-Z!|&Nn=J zqr9{EC%NI|8pxl^{4nu9ln;lJhX(q(=GoSt4Dw1IL*-hFl@Lw00`fy%I?}xbO&yG4ji%ziw^)7+qa%);B7v%58XOR+ZO$ zJjuGPB*Sjec{c8AA>ciL&2PupDfys}}% z^G4w%lbe#C^Xe<}jyQc)cuIy!rKP0=W8!#o@ZRyI_CFDorgnecICJ@%tIOZ)_@VJ^ z(u7~Stg-D>;tOk%^Vh@S+Jrj~YM=}XUL?qSx^NfPyj=~ z0d?w}52isG41+94fhO%!<9gh4odFdv3i2Qg98jmto&!}-0tJu(NzkN!n+G*e1_dw# z9I!}VKMN|L2(lmrT8xDjz$~bMBFKUyXfST{!89m=JV=8U7D zgDgma7Hd31&d&g?Kc~lppHp_JtjyZU= z%-^_!$@v}MuuZhuw)XiX%d2?>8CJBPQMzcnk<2Z?OVZXKa`e|4`P(^uP3Btg z!u|PhgFY^N=|7L~f(^|$UOvj}kuIeuuSdE}M|nNc#fL``P$5`3h!hvTMqA&?L8Lfd z@=Meo#uw>yedQpM#s{_>I6gly)PpE5*bs{26{EbO&5<}>CCbaV#+NwWEWB~gJEU_J zz4C1_%IlFI&R<0I^~jH*D6dC;6yRm@sqyQnoC>0h(z(5!XX|Ad-bZvEY0s6Bafum| zz)t3B$Upvx>#yzW8+TH{fseTS@*})n>CuStdX(ejU$*^qdZb%6%IlGC#VD^wx>ewr z*6g6kStXlEmv+6i^?O!4mN+Q!EUOt>SNh5>nOlS>W0sqHgwOe(Vf|)#GdQRdm(D{` zUXOGsM0q{@Ek}7h(xnE^8^42wkCyKfw&_#&+U>kemw9->@_JW!QkhETnr;794kX3J zGx=95=`kK2Y>eY&qr4vJQH=6>q(>#n>yaL_@N^!@97yU>ju+vX_0%WZ3!sWeyB^wd z;{0{k-lbO#B*nEmLs4GEOqM0q{hyKw-~DxdRFUXT1} zMtME*BQ+cGw?}@s@WS>kZ1R-Oc7EL+uZ+UuJW}-_2oEI1`%jPPR-Tj4ZlDQdptDi?| z_ZtiFRzHu_=CuNSk8W{Y-<2Qn{-*ziF*%1%bOuHFU`KM&BP4Tq0$H;vA#v57VG~jvO*V)9vSXx*A;JZ~N1p;hce2tI4e`N8S0dfSmn83SyWQrNru4;S9`<6F0mQ>Y|YUZ8`zVdFQ7{I_o@nk|CxfKr^E3Ou)bYpr^7 zIUybGdM16z+$?evVhwtNflp_+EpGwdO?y6|8xtN|pA??DFFh^fb&6j)r4vf_h?4T9 zdpwc)%8Gw02_^pm9=dEgx$roj!~rFpP_kQ8ZGB1u%NvDv$ZXdfGU2l2K;e=}=Bmh} z^Iq919op&bx+Wdq#gB93f^i@6;QTZ3&_KL_;lTdL*>AR*YT}QGFOtG zn`Zsln>0hRww>{kT{1TfPkX4eJp%)qY`If;=pI-2EB@9Urw9QP=Wj#)%4o5~GqkRB zk{#{;*Gzvr?#c5W>7IqBQb3$f>s7Cd(ihBEKeE8e7kYk*j{nPWr8T)pP5< zjJ!$16PTuW;@Eb@@x%6F8eZQ3=b6l|r&!(PUpDlE(nqocrc0l~ZNt@ocPQL24i5Ol zmAmBM+j(O!bCf5svZPSNFF7Z*5|H&n*gGpi%nT{fpx&-^%bz zo*hA7&4w?cEj~ZyP56Q*ReGdL)ABga)IQJ@7vI!BnDP=7tJUM{!c(%;IFUKo!{1SO zIyYv_DXZ(N!dq!ag9A-*?b)3Cm0_mTs~ptfsl0rWn9y_>6Bpma?Y2MCM3b53s=N$5 z%}0;K8-^F2X9^EA#rf;OGmB+M2;WSoFLIzMPTvB&AXS1^D89V3Eg9%Dpe%1_+u2IAu`sU$Lw+>D63im;qsIlQ|hWa*bCExS*?A!Om%ZpaOhDa+% zn=}`({ebJE=X~k$;HAyECK>?Z4aKYzbn|A6zH~-%Wv|U*=}{Ee_d))Fn=3befRjz( z^C@xZ)`U0trZ=6T^G&yIK@ld7m)b}C#`hd|-0|5$bVoxO?yTOS|0@h-lz*E>{;+V(GV&n3BXSf4={zle zR&ql2QGayj`qDEO=sC}6ADEI~?fJ1SUv+poFBLs76~{~5W!mws^HS}4kwI=(Ic<1s z`{NK6--M@t+?l=rn2O{1@JO!noXCNxI9>x@ z`?QpP*|y4_Dlu4{E>zMUVwaP^V7LfhrgUE=U6hEYf}z{|q_TDky;h7y=Ghq&zz}f2BIANtPyt1d1xe6k{4@`08gGGNkO2u$XAC(9s$dkjAO)I?x#vL* zltBRu0S7EH|Cj|8Py|_!1P$hEK9~k2kOyhdV&1v{W`GBZzy)dGfJNr>bD#=JAP>@@ z#d^mAm;oLb23e2-E!Kh-zznE>QQ(3!a6p|kG9OHXGAMu{-~f-bS84grG&RCdXB~46 zOoI|AfFa<3Mb>!dKviqPpa3!;2^y@6&x0A@fg*508noCWSOBx23QC{=G9Ur!?3v7g zDi{SWNP#AMO!J@y%Af#-fCCoUZ<_@bPy|_!1P%5leJ~A5AP>@@#XjvKm<1J31X+*- z4feEsFbzr|57MB;-u?oZ0ToaLS&#$`&O!KK8k9gDq(O`GAPZmycwiW0Kmycfh$pCm zQQ(3UXp-*p;L6B(sp0vsJT%XDmUq6fvs~DA!*ktYt;QgzV5Mq1gLOe!xQ&}W7>I+^7Abr6;Y{09zi||SeyyUCo!Bk3eOwDz^)0U@= zogJUG#|M^|Zu9Km6l>}0=H=VGv@55WI9^G-%KXgqm|fpqYpKCs-j^FrMZF#<;`qidC=4TqL&qc@cR!a1>WwYHeQ6@;Be+^(=o) z@zR8hr}*VxB)wdRdXZW%?@7A$xX10hsIz=Jxh(S0YPFQCr-P?f^T;?>R=JrdFE|$=Ua)UT+h9y? zA<7FY0)y=OMT4i0e8vS=n`uNWX}U>()AWu4ra`q_Z5k?mRr(ezjXLwO^g(!*!cc zeL)M><{9<;aoyAp7$cw%a4yQ)D^EMiW!-fx&rqG9hKkqeZ`~b@>I=$c9Ix8JbB)Jw zyg7IoN|fR}89aERe29ckj&pT*pYke>3f+J6hMbghs;4%+Ge6R~#6M}>czo;7kZNrb zhHd{k)4A?uB0Oiv&?4(c_FnaRxPxb3oE2ODJ9w-6I}_#gXipY8cxe-$IDcF4=mp$# z+DW(j0n>iD8fT>cneQ|?FYumE4><3f;cRstGJRoZy0H!j?`6lGus*-_&MlI4%SR)6 z@@To!*%GU#0fCi;vpn&5&KCTLB*Zf*Inp(>0XW+_K~_ zWfV@q8sC>c(+Wr0t;diEAN`Yzl z*n<~vum;B%uk?|waF1t#{ zEIhS6gx&m=KBZM>`@=*99)|>4dNq#1+F3t*w}QN?45`|@P?@qub+P8oAfL^o#0w z-YIz`-CfC@`xvhT0~V!Qr+eBzPmfBT+2@#A0@Id8ipS8W;Wc3(tZGOa*-_&nrA zqDaQNO0P)xxbxhaLzY&q`q-*fB86N%C3N@aSqvs^f?%7t^k+}rtf zoIH)ZWaoXR{CDd2T^G5;^RuhOA9-+G$g~li?iv3W|80S2mrJ5UK9u|J5b{!wbj%}HHj)yO`P5L|2vF6Sr4_8g%+&84(%-7=bspckrq;lYz z2>0<fP$y;_h*`yJ_!KlYpwjo%J}A z%fojax^6}_?euQPw~U3X59a%JX_99I=JFx z;faAEs$xZX=GGOjX!RM3c6g;n{<&@i`DN47w-)I`RTjJZff?j4eff#W#OTeJN!D53 zc>YDEr3~21tpLNY2bi5dF3m=fCq}e1!>@bI%U}h zHQ<3Fa6uY4piW))K@E7I2r?iEnzV}xU=~zC2^2sEBtesYV*$*9Dky;h$bbZB(7(=u z8TGSZ6u2M_98hPRF$bnW2^2sEBterg*@DJxpbAQ$05Tv6nv7ZJ!3?N?QIH2iAORYT z?dQP^sDM$B2SXqM8q9s>K@F5a0mNp@|7Ob!;YflebJ7LPYe5y1Kpv!l1M1Atea+K> z2a3Q2Y2bjm)<{4Ncv{Z@S&#xP)_E4e9GC_rPyj<90qU%K&4DTy1ujT|ChLUrpa#mI z0EU1A7Fjc$1r;!=^;3`nP1cs@K}~DSU>IaT0@PVwp957e3i4nGIAD=Ih*?n4UIcJK z8aQB){h3)%0i(bLDbQpeYXQsv4-A70NPs$fc|NEC4-A70NPq_Wpgx!eS02@G)^^h5 zdzJd<)5v8Cg*x6Y#c8yo~s#gm9D`tE4<=$KCe-C zOYk(`5y^NO_-os%u%BTaD9TGi!bo4F9p$=)68X0EvbVo^ z>)ED_>})6NZWj6B`?CtSz`8GT+dr~FYrToI$L;u)qr4$Yj0;aK%1f`#n~(5%r9(5y zb63}wdYm#S!vsIrhKWrt7oLf4nb%5;uC8wso@2>pSO89Fot!oe^)#_UOLq~-!f5N+PaR*x8Vq{SAKX= zp1Zof8F)o{dcF4f@O4R*D_dU|;C)Q9QfH@^U~c*`R4R>aIS$KTCf9<;`?$*t1ABb$ zhWh`+3U8%6Yy8k%U-MC3P@cu>%n#~+l$VBpiQ`R2cwzd*@%#uc*tUz+*MK)maTZF} z+t_-U{He-Si}@C_vVeDZe4Shto{W8x&~C^mjoa;~94B){c;P%h+~AeI&iyebSLxu{ z4Jh$C_3{3<4xaTljVQSv%vK&XqfO_RBIF+jfR8ovU^5ju*w~>*mdO z@a%cxIDO4dUUD^ksh=?~{=|)Z_@@2ko4EXS;f-&}<$jjSZ5fv`jQs6v*LV&dUeNwg zQEQ@^_OG43vZ4L!zD}2XFOq>UHwc3Q?TC8F)-uH*YbKwvUQ;<_F12eOrL1{a)?( zzSYYUlOc9|rPbz1XS+o^2%kqXc!ImV@!P3aE_n|A=Mi3zKH_zjYtBD+@{X75IDO?# zo=L|zUaf<-dOI`U$xE;1ZxbHBu_hQ+EIN1Y&r%+5bJwc@UnA zxSi!Yopa&8(L2p~o^!nSo9wl3b?$I-h8@o@!OuA_^Gt~S z>xb2lDeM0XKU$d(+^vUd}nsh@<5}=_ixPd8_JE`qtc8~r#@DBf8j%11} z`ya?>^XYWcWkXrk7=^1_PpU+>i)`;oQi_pl6|KfYT<-npw}^ThfW@^}vjJiG5) zG5OXRp1Qk;Je*(0)$11WqGIgUl@P|L{C2kItb_kj^*?Do_7oRy7rD|`8_;s!84l_{ za-K^uL75)4{wO@1<)ZF-R*$wY&0eyYal9FLW}eCDJuY4g$WdXG#L1h;&3^R1-fF_y z8Qx?r`E0u!dkO?b<)*Vxiu0HH4=>oiVCUZw2e!D4cEgHDC2Ki`=&fr@z?6=j$*$-d$mK5j>GFho`USdeUbqlKJC{*Dfb& zvt3u1fyeX6=DF%<_&d{?@vreWoR>sL854~l0?Rl{!s$cKa=j3WepJv*SB2M}cUqpx zcxOC#{t=#XLgTAj__vpTVZ{-*lb^}e;cK7S7^^n6-%mPy=6x30PoE5Uhx^a^2Rzzi z`=n+MeMNYow_d=DYu_sJ7ZZ7%MQnMTg?IJ^=6x1+5{S;j!^d;5fxn8g88pI+%V%dz zUu52E0~p5}g4dc<2(MrHo>QE^1$Z5k)K$V)Hu_j)qA-U0opJuw;Nhp{r@^V@`1sDl zv-|X4^lowOK7H}9eR?zAW!&cGn()&OqbYiol8tt3c}Vy5CH>4`#)qTusZDguSkjIs z^T=Dy>gPE}k>fg}ey{C5)KPaU$UQZ21WN5**oWwz|L%{*(r#-5UtVAo=g#`XJ^(yaX-}l5zeUSSm<@fSEnZ&*p1#YI zABy`fPvDULX*SfS4gMbb7U5C$)nWAHIRlgfYwGDhUwb?lwsUoN2%h3A)63riJiJvB z^5zI@;`%+_IkL)pT5epohCG`7%6psduFsF0FZZ_GI4U=`pEluj;kk9>ho1v5<)5~@ z?m9>H#he3>+(&=SO(RFYO&Nx1cwzkL9KXSUmqu<3{7#w|`WPZXKb#CV02aHx*Mmx)CCby{Ym1a5)2&g=_$KiG! zmss1!`GCT~p@Tz1s$-FQ$Q@%u&DYSz zbEoBxbb(=z1u4)Z9zK``Wl#V^AORZW^*opX6;K3OkOU3tfe)rtZ$KWTL5uca0nCD` z+6GVn8IS;rw2!l(0*W9DlAuAq;)7{W0(p=IE&A7aPy=O907Jk5i;OvDK?M{+1|&e8 zG1wfaf>GdtG;ly&<5(~a%Af!;AOY%(-RD3RjA|SYQlP~gXA#VSDi{TMFa#V>XYS{N zX;20QkO2u$XFfa!!kqZeyiOC2GAMu{g$dMIx0nM}FbeV@1zN1@EP^>O4Mss841ok_ zunsm4W`GBVK^CMyi#5STFb67N7z_aiEV52I3o4)pvLFfStQXILDi{SWNP#Bn?DL=o z%Af#-fCCoUbC?AcPy{YWf(CmuK9~k2kOyhdVy|ie%m5DzgA7Q3I{S8WpbAET3sRuT zKIc5Bfift7A>e>T_IzhS1r&h`(xAnj_yU*#9vB80@RyNu0&~>8QYnSme8$Mg$i991 zoRN{BaHx%Vp80LsRafKT{4uH@_TP`3W#?f>BUAl*n7bbZ65qH|TXmfI6}r#l%DC_H zFEzNHBkmX}=Lq0jg&ecill zCvPy7iPu+z_g(g4U+tCsEBz7wQvcQ7`TmBYeA61AZHILylgU-!r&7-HvXe63=d&tZaA(WFzK4JOUFXg3eocISG*{98W+zMf z6<5`tI+lK5#W;(LFx8LRbT-cTwsQ#=`CPST@C67Wbz*JN=^1|CoOc z`d;XXYumqe{~?<~uKXO_ZzOawYCk*uFXZNq=w7Xl9lgf6ZynM7TH;OTv5NoM=k+D; z@|T-E}8Z%9U~F`H}^Uq;l`b2Ngll!=Gl74<)a;HZ*uTwEHMZWNQkiYyZ7VA6xoyMJf@66{y zu86yp?!o+U?lFY|u1dAdCw>^?yVEgz^(ivq+jKRz{NZ^R_$3>t6iU z;rdM;I4`0F+2E|yzm*iIJMH?{-9D;+E9QoAzjt}> z@+ICS-cIj)@70H1eMl{$YU{e?b<0Y*BqN3jJCW-Z=NwBf3|s-rX++ z(O3MRgZr>ukMlqIg1+SVq5b>or7UwHhtYX=|7^!E1$de*4IW&(xVC(C_7|x?tthXi zi>*v4sJF`7&T%8{KkhQEOe<9!%nYVRra#cSw4^dp_v_@ijfdP=cbX5#lyb9jhk0S^ z*xAA6Na+KaOOwyVT?2R3#VcR``YRV>zw44tY5lFVSg9;Vp7W8vzOVHl7rDw}v0g8# zm2b~eYRG-Jh`hO&Dix7woGe(QbgH=?a%qz33&406{hklp8uH^-%xkWC5_8r0Vq3r3 z_0p!hZ}j>8eanvp(}4K#Wm7y2wlQkoY!9Wo%wGAMdLi@A)^sK_-HOCpavQHK@>Z*u zNv$FuMs6l=spVx;P;jZVQ6GZ-Am2FuD1R17Tx{FvW8{RR?$+dwabxA}but%u&GnIQ z^fE;^nJ-i-yAq$`i|&>DTdQs|Q&jISb9i|v=IYWLD3-rUdmApLd)-Z))R$c2>7Q-Q zB~?3W^H1S(;bn4Jc*jwAC_=H{eJLVuIirjD?0h60<=)4A-Sv>$@V_z15t)SkRVr^x z_6~n3SHqo|d<9{$;pfKWAMZayzWLgH`_^qZ@9Ky5-Sv_2rkM|kVDh26+_d1^?otf< z%hykgbhrC2*H!r#dXcT)%c2CD~7Pzb7E}1-U=ZEGoAKH1|0EJloNBRp_`WN8^ zvGEmhrMlu1j7PZhWa~PcdacLS+#%%mTx)xD`D5#g^3g*F>pjS+PsXHJ1(7Ktky#7c z{gCxB@?HA9{!<25Sg(a3O34>_MP)a-unx$Yn`bp z9TnbmE`2ij_!!f>)aH@L_Q_Y9-kthL2YBj%&+=dH{!Vd(fBQ4~C%%H)$uH(g@FQz# zq8a}?dE_^|$okf*ym{%%n&i(MJjfNM(x7L=S;?n* zw7zwQkD>+7wij!>a~aWG%1WR8cPV%0dh$T+N4tC~T{F2+>38hExOKwS+|_Uwzy4+Y z=?ow1UhpI9LQ)%>&WTg|k~YV}zmH{p)V!xCeq8=#;CB||X#FznI4(H{1@Er?-@RwC z)m*%1zg!$vU*Yi{aCr5m%|H8>RI=Ta(;kOwuSV(Txw9SqJC5}Bp{bqD+`y~DYsY^z z|I@idx-YrOtSffsqsFPL=VJzUVW?H^HgB@!E@)>I2#oKJ!i%g=8C$g{o%zN354^Z? z6qYeL>?}{R$>ip67hPMDZJholytwjaOQJ7lvHDXl?pPNxytsN(fam+3GRfpeyWdQj z@kJT=vcK$0f#R+_vqnzRxoPCr@4wP~yIA_$?j787?gM$V8K$_sHk(#MyPW7=`fBbX z{8TEL%w*E(Vvz$&zSY^8KfDLzH0f3OXq&_Jns(pl&A?YYe0nYQV4J8V!3Z4NcKkZa zqnj(@E?ip*=Peo^YbdEn4FNaxt$}G#=lSeeEk>f9311q(>h4zy+7?-?wk?g#O80@-TPRT;gUIsx zhO&1!UEK9v|B4T18Fz!kJnmnw^qj@r`K-5@G$=ate*aWw+^I9^ud@zus-hR0E)Cp; zIj#1(dzDb`R6aY?)6J#NV7!poILpdY^OD&I=VDi$aA#+tro7N*m2$(l3+tG!&(*&w z?pEg6vFlv6kLwI)DK{_wV%B$>W_@S%^5VRN_HuCF;9WP}dDA_Z#VZ%DY;JCDu5YSu z@&|o0@{nJh{&~49?v|+zZ4=kdr*kEEeu;G_f1h`k^Ihj4XJ_u`dY7}$W0kg!>X`Ch z$W7yJ^R>)v`a=`1e?j^?OtfDh;f-P4M?3~p;lJhjGPS7vPqeuDlzu7sF?)W~tUG4* zHupA_n{`&c!ga^E@U!lLyRQ7lo&6WiG~(LzD(-r(H^sNt^K!@dnl$y>vEr9+SHV|{ zpYyUvd0Po#-8oYHvbZCh4bPMxJz$@AX+m2jtaPwijax{kuBLTAgH?quBD4DQy| zPi(h3DCBN-Q78rjKmTuUuFC+ML2AAtt=`@w;<8QFH6?Shwl#KW8Vy zpu5bFSK)8#lLp2=FAwV1$hB;8Kej3_1FxuQ2unPJYx|k%+j`ioZ`kO27(Wl)uk9`k zwd4Ht;Ef-;i)ww>p@Y6}rYv#18F>B7zWOQC%icccQb+5oFQT1Yhn+P_%kFS2m~fzf z-6@;a22Q?H9{in>MWL-*;%W@MhqtKeeXSVj0YgQLMkpYZ>Oh@HQ(cjTu=r zJw13n(}-e`cM)Wg=#C$s%ov{4u6!2S<*(*0AUBzTt>V{~d%ntF6M0y!Bx{eWTvz2O z`3f5^vudMAVWg+CJf(9Pc$HF#PqbMbYels6fbkj6zasa1Q$i>tGR30r8Isc;pM~Qn z-z~#u$)-p{5g6R6!eZk1GtwW_kIs15@#P}&&82JWkNNw&eg1y`34h$#?2Pd5TCUcp zJ?Shbg^DFN=-aY<7zg)EL)CP6B^KzM2a$bs*(wuC` zyW2b3+sN;-)8MVK-!>-`5~i)NQ8Mj?tMW05yEAyM@C;L)k7J$SI7Tr${i9*qHo>NS zP_AqMa96`!wYs>n|8Db9V#S~FE^^-|N4zjSSLy%Y1xlSY{1DoP^M9}6d>Kf9x^#jH zD1a2GlU_ckf+BE13bZI^i(n2^!6{o==9>mZFa(;6jpu*|@*oA8%olu6 z10E=XEO5XgbEg_8g91o_CiBaAFbzr|4^p71`8}wB0vG}gSY-WS7F576$bbZ>vmP@G zJWv4by!g-il_4BS(9l{MsDM%6f+VPG?GRMJD9D2}aKJq4tTUhjiogYF;DANepl3h@ zjDkEE0tv9dy8JXKf-GpUZ!rhTAPZXT}+qO8){1#oe zzvC!#9ls=%`;Xs0Z_D^4(}CP^-oEFum3zt6UM^<(l4>&=TtA3g>CyGw@3>*h@7?!F zbFZuJ#ZSMwFR5#WYi960TmCrp#FqUZ{)-&`-to6z`l7jaoV>zuhwSC&?U~svx_+oTN=NA z`xeKV%O#C!Vh2-uL^r=M*2wCylO@3Ey_??jy~_k&e$l_Icc-j344k$Ju)> zGdj@aTK^o!`sX;}$X@=4r})hV@$tDH&;0^dg-PL49$@7t&%$so{QS!uek<*zSK*aj zdrbvlNUelPIu$SJiRzO*Vc8Sz&zR z9?$3%UttQ|8GGp!PkQA}dZj1Sn|z&(hw@Brl_$ST`3=)n`4FbD>~*hrj^a+&a&WD1 zRr-hdfXI>GO5-q3#GeiLK3DmnbhYW|IMMb`ZbNx+^@H&34S0JszOADt&Yz*z+jvP9 z)vIuYdZkZtwWlt8!lHIyug(8?lbI_h*@tfBkJ3k1g-P~;c=Cs^7=J_mH3zN`9+emIRIcP!`LFQVs~vZzena8D-Q-;u zUge$YY#5KQo`mgi=&$lyyf8drm}IYd6SljGtKwzT%g*s#{FOfnj}7Czsh6QUUBmJu zx$;2n$p>?lTiL4|hUsO~;qZ3brnhM~OuB2$ZVvy$^icn$xT-(XHM9@YN%PKZ)|TS} zSA|RA4#O|~$`{>-?M2X5nD$5Ell}kK@lZaO2+ya^`0pl7CO`MbraY)!Q23PZx~d+l zoV?@{_nI^d`|qHCH}*CiH<)r~-7yxRJ-`b`?S#ss{1Gqg=XF(j$zEkoJf(x&DZbL9 ztNfR}{1-3u_XSdZR$tPV3)62J|7>}gH*r$<`=I&obY0*YmPe&`SkI&*EXT4}`m3zS zf0YaQuY6EBQa*(BN#VEUYC5Q^VIREuIH0>cDZJ7nd+F70`J=eXU)2MJL*+){lK=Xx ztNhk)#Urd=Vf;=ezD?q*be21%v-B#R#R=MLlg^5((pmOOXYrKIa;K|}`@Nvn9BN;c4hoyn zMF{UDm%ZBA=h6<>&ava$d9HHzT=dI7m1FT0-l#wFH z6j!B>?xk1lMHzXhQ)y~-rcA%6dzH~Xc+>E7o#84y(kDIAr+Y+3-#qfLeCw*RBOT(Z zyh*3rsJ?{d=(3=HQ27#1ZbGO$$X@9$p2DYoS!GsN>C{zmke$*^_X-c;TDg~8>m?1s zr}P;<*S4!lW0eo-Rr%0W{gHI(YSZhr#vk$IpW0jWnXCBWy~>;9Du23$<1LGE-_IBa=+ggRo{KhivJ(q4L$2SItyDc`Ha@A+I8xZ3nk zKVb7IybsHP@<-uS7<5%Wm(R2LT?ww!Tvex(Z}zJ3ki8G{QSOz$$~);+8PRWD6)*i( zyu?$w$(^lB)21B=?ZrIL*{j&TaY_9xO9w;2D8#-I#5w0*D!|;dq zVLqu{R=O$-VVZ`&6&~3sJWAiN?#UmylfPko2=yy{Qm*zlX&<;M9?DmHb)4{C;SKGT zPwKCA4S7~>*Yl>)BfT@hbuPHh|G&^LJ*~ifB4_ooTJT>k|CEnmJD_WLuX^VO;a=n# z=4Y7x$}gp>z1n)Dbk)7CCjNo@#FilbTqTn`d$sBAVz06wdtH_Ps%wNNoU^;CYXr&k zBf9ZIX0{@ld#DgYf#nb%CpND}46qIN??0 zRpF7lR=`iZ!S*lWhwYWU+Htq|w%t1XK5WmVZwNiQW`k=!xDIpej#qde#=~CQ`6E4* z!2NV^o#7hxV@eCvPsK}arB8XGaI1dms`4RwaRk}P9d;}02(}&VoL7k_opPi2Nsq2! zy_Y}HHdf&X+v6~NCn(K?3m*J|yz#x3$k`7NHxpxmjQw(&a8lv{7BZEvewL;wG) zrw?gt;$ZVGwO8rYB>c+v>20f*m*gb|<<8cJIs8>Uoad@=q%N@Y4{^eL z3jGh$S^c>3Px)cv^1pYzQR|B?;SBq&&VDDXPj;TvfTwu1xGKD=@46}u-StCd45}H= z>1x|IyY3Ly54p4HH*ean)EnFFNEnXpc0>M`;OXjd#edhfJDTrv-Xdskr8|1B^w+(( zLU=DdwLsr&aP@=hg4J*08Rl~sUK@X#?@r!^C&^WDlYWImhK*J59?l6-G_3GJEOc{9DIlL&IbDY;JOf8>s+JZ zBCdPIPhM!p<SN7pma?LB|;O|F=@=a}~%4&G8epmG~w3j~(_{zT)SGBKUJByWB z?^gb5-lO(j^<8q+2VK<{*#6}aGk#XRk)5qSc5PE}{J+`z_V~D}YX6-FX()k?h%klH zo|acYTBZ+Rs6fx84^n8$(6ltlqccq=4@fi9JlYgWdnly_MTiBx;USCyhKJk$icygMzTdUanK?6^lv@~@psbQFeMLJUE7*H}KtAea-devt zcV#~Ax|DJ(ryjrbJp}F1_B;0%jy*Oo_53^iK|h!m=zQr1=1+V7-FC2E`d|m`833k# zT)(=QZGz(v=jVS{d*QiW<1ZtC(Z-NM@%{TVF>!De;8Q%E#ptUj@LBDAa6SL((lwmzXq0Rzg7dga?H~m ze`qgh>hY#i5984{`x#IFG9UVz;}CWl@7LmS#HYd^8eq}`=FyY1x$ZYFXuU3j?6hJ%gFsV>SfGx2Ys%-@AGi# z;dvB&!g-bXP)_?p=gf!k%G3}>*uif+)X{NLPjXHV*Rhf3_u8ZAv;nK`M3_jurFnvIMXfvXZ zeEDd%T<*Bw($r%)`nnvPbZ{@QTTa(rV(NFt2g;`${t*wqTYjFWk>92DxY^y$ae(76 z^{~CO{}WT6Zw0>>f%*c@&ChF(*ACY{%10naoN%xO%zEJZn|9z#sDkIrTrcbPG9Xy* zr7EQll8WfYjSwUX`NBJm%wTTjD?XF2Fs=0m?yAN@)@IQJ0KuZ*WZ$Vb1@4%Qzr{mOLC zPhLIrE92=`#?!Clryk}@zY^20jHhiZ2mMN#eq}oSN=&~pp8lXd6ixam#u@Pg;>9oY zEA!>}Lw@?zk#qd%zOSLj9r~5!q+fM89#89GzOG-@#oDi7VET0k7@_)JHwk$8yrQy1bdYE%H$> z?cn=H<|^zrfxCez$9kp?z)teAUP)88n=gFi?%DF57g7!?_v<`_w$o0Qhxs!f_)YS4 z^Dm^bYVB_yFv$bY0S~ava9m;g@XgfYnoFA=n(xJTd1#(zBxYs!g`S-N5;%D^I%GLo@$w4^8f_>!HaX#JP?)eb7UTemOVEj4uN@wBeiwxb3|mhaT|I^hc@e$F)A% z6Y$Vd-yWLz`>~Jo+Slu$#eVF^+;q|dIkZpqHJSW+JT&=-b7)i6`^KCW%IyuM2G-ul^2!M~k&kF0rJJHCDB4q4NV7H*buKKtGkEMG`te~5Cl zbJs0*2!8kO?@IY8&vFuTElj;^f37~3zj}>+pT7Z^>*`_PyW-DDdmyI&Z+Xp@_H}j5 z_XXGf{yP%CWYsrh9X#oRFN$6Nb+%ummke5jA@`~G!}vVS9{Ul~vT>3jw%zBXsP(65BwlDkV{ z)&t{N4)Sr0e$Z2&6+7qr{C2UE<)M8nCo#*-cA~LAG!1dpHHE&bkGRQXyCrt}TcQ@< z1G?`xY4;Bv`+kV~&p*HUU8(P;j)ju{r8mDL?;aA<|BPq($p_p|In+--^{}6Ef7S`T zyZ+K+vVUFnyC%{5r@MBF-e1*^6F(f(cC`4Pn0gscz2u`_%26-%xO!92J95%{@=gme z+sE?07i1iGCHxtwM`Df(jCaR@U`&q#l@6{3X8o`ph+(o~J+j`|PKXN;XF2>`z-KMo z0lT`*hd*5{?cu%hvNTP*-E;@rJCl1;AXLxnEquv#}V@Bc1$_8 zW1T^CDPt&o26jl_3Mn51e??UM5G{Mc8| zbA$%bTk*5&Meov;6GiT~8Gu9;8|B<1Tqc#&hEr`d;?g_w;+qw|-WaM|&wp ze^C!H^)jCMupCpazeCEwdNyH?`SMlLpL|2QUK$>nA@&`7N2%aHzj>E4uACtCd+E&& zN_!;Meus_Z=g4JoDofVi)tFox#!VVmC468PD;Nd~BbTqaUb;n0guC z)Nz8`$GQ3PeeXfoe|Q_)#Q?^uC#AgCzwv-c+Kn#+Ust2{e-gN7(Hr9TBi~;q<*I(} z1Zm&I9Jd+Iadz>Hr=&h!dS-^$_4zmJr5&{wepdR^7dpGdeqxk6#CZDm(b21gP_E{AbVp zrOY?P?3avZe&l0*l%t=ihnRX9&wR+|=1a_SF`j-RAN`=^=%06`-ah{i%kj_Y(w)hw0QyewU_RH{HQD`8duyeErOK5c%=F?or?h>n`!r_}|Qz zah){va-CnC5{{q^?BBuRvD+~7}v=-P0aSd zcs))>#J*X7{kZgFVzy^u`lavs{6Z z*R8}{?{b_VW_w~h^C2HG<)BY6`CXdpT&8m!OU!jE<%y|}@hk`VST5>g|Kd8EnCoZ8 zb3IKyuCFOaOg)TeeUK0BAw)TjbJRmjy^LqQM^HY#SDXai6rCo1#%{+%lyd1CqWYff z*u~qWd=)>FdkR_CR5t7Su6A$(@bbPhq~0`E%BAgNJ}vs^7&k~gF1dGy)MM?bcS=1H zvs{d4xyVPqQI7K^^$@!>(^+ovv)q)YKZ#jB#F%?f>(edYn1sn?G^pp=)IvI@&%%+H>FJU&&o2G3%f4 z+;=o}Tr1-U!+7c?AM>Fc^VND>z1ly+$d~W)j{>{(m|L&(Gsj!E ze!e(iQM$e$s&u;6*N`aG&qaBnZrXKPUyEOZqZ=Lo>4{&bz*^cQ~jdi?0`GUp+ z6)w&4R6Ftw4(oqLGbQLywmX>Z$uo20!Bj0;G6JL0>~NP8n@`(QllhkR^Dlw-Tn zdblrNCH^?7^BSqQPYv?ip*B=?@f}jHSN!f9($0uEjxwI}2Kl%Sq8!&nTF*d*YaicF zPr}~YZwpDeHCD={4}bm=DaU1-J}2_+g}2K1{e{l2$oNgH*Mql8eUp#vlyV%WsfU<; z3b*O;HUb>pG*0xs^vq82&*B+t#Xq0_havvC{kCt4e~9TH#?wFKW4S3u|7bn&t|4@$p(Rv0dT>JhfX;Po)fgSQb zzYY6Yo`&|Z+V4QchbQQ9hwYepul(dK;`qN`Bv7dja^_??04!eLQfZ_!;ctXJVHB@xT&U zcQT!JY>E!aI_I|=FPHkGKF+fhKl{A+kNI$&p)tlgq_ZA$etfT&`6)$xjAuTq2c9qb z*5mx;DLoErtkgNnKJXC_0RQIeL9w5h`Cf3vR?&Cx9X}QQA8#=r zr&P=5770G)dwM>7>?J*){;Kg#v6q2ABc%Guvjj!*NbeE>Sgrm=LaF>IVz`e$e4h0bhFaPW9@B`=S&CWNIpKAy64Lb6b z4z32?^_NjOpCiV2zw_>IRmyodF=;pbptj@Xe9+}1&2;Lu9DQ95PCB?3xbnpxnk-*) zk&JWwVKBXHSzc{!YnCGNC$8^v0 zT$<;-><6@?+Tm{i{>knepP=4%mj6uhCq_H%XS|D<&V5BE_}3m;T)}c(QdJ}U-=(iU z;t$e4-FW8H2Y%My0Pwx%Z;^497*UFtpO*3CrxRyO`j*$xKC17@f@;D`lZH75z`)?UveDz zYx@gg$LCh-`mjhw;pZe9V_}%!+!5-SbiA>$jAICM|-G;n0gt{{K&_1J^v>B zf5eH$Abp_Xg+lt1-uk1z4VNJf2$&;&sjhJrv5%8G4r7xdZ3T``+(oP$Pm5vZ*7us9ZaXJvW~Jn>0;5-gN3AAIjO!c>34;#``k9zIfI1 zG7eIICG-*}fOE^w@=*`t;Ww=3UIE7X&Rb5$zCH&J0K4VUSo>qd(eLVG(f(Ecy8iw` zr~dm8Kf3i>V&`ioa!$U!V)pFcO8cq)!OPO0h?yVjrF4s~7r%qUz?Cl^F71n$e8lXB z{XckA>V4i{ibU^EC!QmC`m7q!zv0~VqMw*@)Sq%$&-Uov&rpu~-20hGY`L`C|GK6_+AZ&6D5vjh{1uF+Uh**?%Fz#Q{_>tG>^b?; zqr@I!&U3_+`{fIIocrPg{dZ|rovQB<9$BEr#nUd+ zA*No&GavHNKb@8{{sCX}mi}HFG3_CyJ;lG)`QG!GwqyD%eZLVexJ~@H=BpFM?#dT$ z7e5ly9>y~t@-bh^(GKb%re4M~AJ-oLwNC#B_WFnXq*+gYys<{|oAuYnB>&Nm>v3Rv zP>%yFR}bXbkNSY$S+gbvY(Z;~moVxF>i_{Qq{%QKF}=?#puDN}B7H@Be}R z^5Y&s|BW8Xvs}~%y9Lv3#3qSX=e@(*x}F5B1P5%#VIy{wEpQ9{PpxY#-z!X8DQ9 z$8mAM(W|cGx%I1(?^j3P5j~wxT`Bx7P5&C;BMty_9ZY?hbC7AmpG&XU(JcA#e3bky zO+8^pU&O%)2V1}xAH|*zPOcVtV#+ffqSDWM9ex}5$oGFP_E?=fcU0>8Ki@3;E?tq@ zO+WQt_dQF-Ve+%Rv)shACj~uxpMM1S;mR73*Z26GZ}mNXZait`NBO`u?H|*@Vc?0| z{wC}EORB!ZzwuD<{@l;X{rp)AE2KRT^POnM^L(Ft+-Lsq%3n%5CFVYt=^PKedN|)O zp8I9Sb6-w=>S4azFB5Y-Vm$kUdmm03<(71w6OfPXmGNvh)W>pBKl($z#@+plM}Kf= zzvyNEaO6Tv2Y<-nH(5UDvx%W!28z0GM?6dcB|J{)GEkx1RbC z&-sDzYrgs=@hj&E?n8`UyeNJpre7IPe~^!UEjfI(_?4J`Wjg)p)kD8Bo_=LK{Yrl7 zVZQV$G5yMT`jzt&#}CrarH~$ zSBKwZ`RG?-`jzqYtE-3kx_%vmzvx$EyY_1jFwRS4ye8&&XZ+$XG7c`f=LYdh@vna+ zI9l{E8As2Wa~b+N&S&qvmh(i#rU!2o{H@3DllWZ=9*}w1tB-!AK0TlON-*^?p8BYV z`dCitBc?vayZVS(Pki6V_gVekQ3Eh_ay+GPSx(Awd?3wwp|3R$&uaCU$acWf)H#pX0zF?4!R^z(5C{10GPi&FJ^}Q;|X+-{buJ zKc1KMm@iuBYx!JX=$^-xR`7k)2xz`{dCK4KlD{uu;yt_f@AOyvs!23^p?`z_;b46bRXujWd zL;qSiuStUDds=h0?iBtJ(0sq@{;h+euN3bOJ@-y!McLM8B|Qk5?@#^mg|b#a)-*De|KZeepG45&k~hZ#}kS zYQ^>&9@6QcslWEr2SvZ(+zZv!-7n?q0L^=?zke7P{$9`rwauznc;8*3Zy0pEU}{Cx zJvT}ILEL}vzUY}NcM5+e=x@F}6L&lhi2h2P_s?53v*OHeJ|ObFpdWhlbol>ULU-W& z{d>1guef+dueJ{~&+Y9;b$jW>dGpehCm{c?3jYvjo_{~`^39?@i1XZv&9f_J{_R0Y zkAUVmH2u&1(+isC&1W9`tfY^CUb=Du^mhqej`K{O_a3(NZpps^G}ABKe2d82pl{mV z8#<^hDEWq<*?UyZuY%W6(GB|2UMqJu31B z)|cEDOrN?<${PXw_YYr0ej9{NUeEgYPUy~UCyG4-pt=5Bch2Kd{?Y9m@4ggzDs_VB zvoX)x$DCQQ?#4%iZs=rt()&}m%LFL@^aU&4pE^;(pd75za3bQ+M*#Ex8oJNO6FQWd zXW3>X+100#P7?Qp?*9fs(8Q^SX?MX6E7jH2m9i{E@?n3-FCOu3)<=XGxk(M{}r3cgL zrjakbI-PFhmG40M5Nk^%!+Fc^$S0DCyz+fWPnq}!I4B?cWp?>2b10K;GCjL|mN}YE zH;sJh{##uArj;)}i1dhMC+T0N=jLCXNza>qM>;)!{@t1My!rPb-8RgKWm%DI`%F_Q zlppCs$wc`OY@>e(nFs&(4e6<5#IVg|Ui>Wx`BJ*|XD8exwI|zVh+~Zz*}f(b3@<2k5Sl|4ZO& zT7c&*Rn8bZ)a4mh7!@+Te9pK+zFd6`9=?6$+vVjmn1#+aS6?6atW9;xm!DsEF4wz! z*w!=l$(R~Sfv+=cggcRzuRWB08SA>;+qP}n-GLELKOA>5dKi~7%e{P#L&%qHSIP`~ z`3%bH{{@%J*WuxF{gF>!(!*z%qE5!eTzv!JdwI!{6)S4rQenrweDyE_zR@KMUS6Pj zoJyG;;QQaj9W%<$nj-C%b(ML1p(N7ZTCl0SoSk(a{mRbp?X#Z_d-?dH37&lI!*^Rc zU$w7%gC0J&{pQmb@$wmxZQgu4!Iw%}aE_^R<`t9UdN0x!oO|l?<&`gse73(-Xb|bk zjz8tS%7F!W(?_)YpT|n~-H!je6b>h8A;(pMe)vDzl4bzuDTPS`k+hF($$4zr7iPL? zn~Y<6M&7isR5KGu$Gn9UolYM8m?q`BkZw6K9M9Y_4M7`V_9DF;Ps8x=u+yxhU3uEQ z$#yzOJ=UIWwu=AZF{Z8NA?l}KlsB1K~Fuq|A*5T8X8lc ze#H6*>7}Kk(5&lF*Ms~&Lew+HzdP~XT{0nO;IEd2~4qq>l`kn9u@wK7{qiSnJbnq?b3X*zsE^Ed^xjSD`+n8L-eCS#t^3P50 zM!Md=<@awN()Io+fBA-x{@WcpcDxDu^7(HR>98Mp%4+)e%iFVhON_JURuKh^I z{uk+%BaZ^f!?u~-PE4~Jd^#6X+HQ6}XlF>5a*UBr66vX~h?z_#^7_eUIxMI}+VZsn6Y1`$1KUw{`I2UY>D*_HA#WkwwvdR2 z{v+roX)9%#Nu=vhTGw-Cd@xPcgN^iL5GzP;e!Zym`83ssjs0w z8DK&^P)Bw-OtT#6HvGWH7A@M=Ts@WG8|^d=U*~9^c4M0fq`Uhr=8>I`3Uwj!2n~Xd+qsmf3^!w-zke#C>?aatt87DzaA2!<(T!@iF9Y5lec_5NI%!y@tu3_ z`AUWR|C>3kXSWw$XaIbs!pxgY<>|+kIf8Txs|8fEq-W1-IQP64<;1xnAExQ?gp{n! z%mC6MEo%d&X?a=CfJ&NSq+^I6zh^y`S??s6E~$F0lPzzWT}ZbL&YO|E{i+w~TsM!E zK8SQQBE#q!$typi<-79F7byRI(y!4L^R-j#e~|9;jdq3c&$(%Pc0WP+DeuG9cMSUz zNFRZDW2JXd9tGeQD$@@#{_RCN*9BviAL*6_dBgC?!%%rlbA;&*#koY!C$4_e^!30# zC!OP(C*4*Uw*pAl^{dl#`^eO980mV~quYkAUq>PKJqe^I&7?$7R?CyLY_^{+>ZkPv zrXoh;Ay0NY$3B?(aJC{dnegP}8v>tcOLE@%ReclpTVLpIYsUJX{VBUXRmed4f>Tbp zxaS+2^Y%*<=>{hP>;Md%jkLRrz0N)WeBtmYKHU97g&GU=Yv?=mI1Fm4I?UDPS1BvH{(I4nQ>^2=D_& z(QbwSeSmI22cQ}d1o#1?=vPC4K0r6115gbJ0{nncj5|YsUO*Qh0SE&E03Tok4%79avJ0R}(;QaDTL z19SsA0M&pXzz-P3dD9S}56}%r04f0nU=(L@gMc1DCm;d{0(^jBoLky}Za@N12`~T( zFod()UO*=x0tfZ-^puqaM@v>sC0p7QS&`X;5$wbyxU z(AKKKIIFMcTfc+ z&;0V`-$VVY7vTSO)}TFP57@iyC+(;08u)**t!#?Y@BFTZwwv>U8ESxBiL6+a+B338 zre2q3dG$HHjPtfqkx&x+laWi*vON!Lc`_A?e<`B}ob>z<8vF>klhhYl+Ui0eDc;l<+JN0pS%tEw^Nz^phN5Ixb;W6OR?Pf+M{}4ta49LPph-h z8rNC2XwY?(Tkas_I|At^q15i(CE(Zf;t28_IG1l*Wk>O@JXe2dAZ72x??k{J^&rc=MJ241Vzaf?9;@F9Sv4pzANF6aZL-@}AQafA zTy{I5e72o|P{TguedvGVWPL{)^2zt?Q@$AEYyzX8e)7o=L;h@4hn_eYyruZ<^#T0= zA6QdF0pL zK;Z8OSnsQ6!0qs(d^M_GoeSs2xRZ)~hCXJc_ZDpV>|e&)=U* z|Fh8d0cHSx=GlP+dbVFafj|PZ#DCz_*P+1K?K=^wg#5Tv0cKA3Q)CyJC6N-NEHKIE z_XkS@WglQhz`ET=QI|yxb3ei zG`OF7N_{1fB3sY*8GAB%{Ex6)A8k+ma%J>H_EV2C3#@VIrF`<)(*r$*Iw>_N7@X8l zQd_dKXlGGBKK6C^%#SRJoEV%mDLC$Bh0QJHKQ5YR2j}Ci&iMX8 z9obJkA62ixzWwx%x$kfAfQ*F6RnAs*rYg~WtS@v^8IlC^!SW2dz@7yil`^s{zRyHKlK!2b}X>j z@08e+t0%didJ5phNzP1_&z@oE8E2ItCv;?t#^X|xgTc~BaRga=KZq#~mQ6YvBZ;i( zkD_7D87Xim@Mxj$Z+k`pkpRvD@#BxE(ukUnvdSV>@fNE%VwFU!!id68LB!xsDpIs3 zC0dTa@9cKh6Y7Az52jdw5{2!8uT1&NRB4%-FsjP@su({3h0(qcKh#H0;YV5gU1;!! zBz0!?k08*V2mUp^6h?!TT=VKRex&Uk_s`j@^%kcT$GCj9`@5k3+?xJfyHbfj z(C;tB7*nR#o_f5|?TT|((&V~z1pNL&Rf?SyTIDoVGD{U5t_sGhbvLQb?dryzsthgH zPyrl|`qYhnwFEn1%$?`)~DP2%jTXKBi5${i$S~hiCK6zgr`CiC(s@+)q z&Q=`3W+Sv)byB&kYq>|nW9z1Uv+-$2JiNC6I302;nJo0LaD~}hEEW5ppgeXzg?_)5$6$!CF2pMUW5Lw`uSVd`c( zW}9*91vnDwfn0FG)~#Fjde6v!oxV_t`8x}9>L{eRUb{&-R6oZ15jAO&!q6HiQs+%n zJ7-#34Qs1uU6-=92CS_+Ct5cutJD2K7%}I~RMGt@uWu*5-?LlvOZ{ic8xj9TkRGgEQ*zj( zVA~&dUH92#X9p9JMJLMEmcsz&Iy^SO#81cqzpWoer$Zpbm(F-&lSaDP3;qdqkqcbMr)L{+*w!+@HJI@4`5|2{Gdc@srFSI!p()qs4SR8Ok;*pW_A1^BSe zIJW70wO_g*=XgU95^b9-c<6Iy9JTehu0jLgXBwXZ2ZWGcc>f*g*ICcln<7Dj<<$LK z<^@}!|NEcBd2m3lTT9D|i;Bxig$ShdJd!=$7@;8ez4p0AGP{g@QqPF7%?9v~E7SUY z0mH@!Aw(G(E!#z|{%-K^*%jraHtDeKyY^5o`7-sx7$Y=5yVd@jt9!>i$|g;j4lm!;%5W-w7HXBJ@!9QxGT~6*sX|||PaPKI&(Y=T=vpv#y2*T3c9OP@ckZ+?}0)R$ck*!O^s=LY(7EY7E+I7iHU zcw&95Md{pr!g?@69n42XoKOCHjkiQPzkDC$$2uqH*qLpw85#xuSm(s~{967D_+PRk z{Z`(ebuU@*yVW1{Y5(DS<(CXqLq6@th<;K|dDs`7{_M;vw%HB-cT-WDr&i54x9U(0 zs#ewU#L#xVHC>=B>iujr2|>^QFSDOUwrb}7X*KP z|JA2!F(uO8ewS&d4UnIw-nKFP8j;96dkdrj7$tf7;-1e4F2ph-pn~S$KUMs5eWI81;3rY6}zpx$kO`RzH!0_xFr4lKbXD z2IQgt!=Xx~Tj<{*w8&}d49x43Wc(lt^CLL(8T8@2AN-?w_|N*y448N3yumU-hPuID zQc_&TX~-7{ppBU6`H$mIZv75W|6UW4ZD;Fe`LzB~@b4K-`4d>s25~+x2_td|MmDS~ ztODD@tGaeVpNr`7XV-5cRQ_YkXDPQO5aay7-1~eNrpnx&Z7=QvApgMxJ5Xf#$Eni8 zRB@Rq@vFk1DnKtyu_6kv`Ae!I>|#sRVP$GkiP}8DqB^;Y$kx{t>Vdw3>y-RhMW3~b z7U9P(S!9+h!B3>@RQwoz{NNND4&{&kgUy>oAI~zf_4S2Dsn1gSrwFE)swkpL4EYJD zGMwQ1mA_Pe%2c43OJ$r_K$F&$t*V|w~-RG|VTzp;e zb;Y~N_BiYQ%(~AVZ>-P|}4&uBZRbayt`*DIy zKV+|q;0M~FHxudKx%U&U9qhNd9$Y^pLMh1aU+($q!T2fq*?yhN=9iC9e(EUtGk*s8 zGqsaH$CXBoD~_CqpTfwg@)InG;3uF`BhLGY93!&J(;G@cU)K3%+AEp$y3;IV9LtuE zghn9$!IZ#ZPR*vIUS%GdX$5T5H12&q(A^|YyX*`FeujAnCk{_z^cd^obPE|1v-1yx z5|GbxzKoLU{dG3K3iXm-&IQroa(?E0m>Z)R_U@N%d*}|Opij;`Cq>F4Wi~(aY>Ynq zL_BAnv?pJ`3=HP9Mtm)^lujc_N_%n*!%pcGc*GE{WP7f(6#3A~oSKRV35B%rBXJx@qFCjD*xLa83t(cp293FFS19u3gtX?QFAU-goS< zwIzX2HTZe4iPIB>nJj`a58(t_l^$O?#_I8%Z803`1i$+}jElJ@E6MQL3g;w!;PYzB zW~1 zRlB6TvhK3R!FyOfsq64LPi;o+=!a|2?D577r69k@+G9sdmQ{ODyob8H7N7anmb84n z{Ec5hK5GTrfmM)xh_m~F8H#}4t=kvV9(MyDUEf`h2RG)*08dOx%gTyNN{WiaMa)n4 zQ+c<{RA|S8!msUN`z7G9ElhBZmOVLglAuD>$-1hKCld4#&aZ{d4{9A%t`>s5ROL5~I5 z>me1g!CzbohDgM9Dt+ZE#iq3c_T=)9fPe4unKtr9{wier2JZ!(y=C)@sH}dwKUrg( z>6`37?A!_JSj*27Mw9oO;KY+}J~Sa8z^gGWsw}GXtzS{VDwt>$+^jlm^|GmUMpS=5 z_4`!RuV#OsCYMQ@p{~q&w>xA(Pci!UJoSqGq`fV&ErQ87H4b@C#+x^7I19j~cw|m$ zibXE{aIEs&_nGwP0QB(PBK={H`xx^3nA(!sk}9>_Pewkwzl1}+A>6O!@3}Kzn4X6hA0Rvb!bpxsae!vjck)41_Kq+7V>ud{P0u;c;{=)(U04eOPx&UE- z50JuMv=?9j!hit42S{O$o&+QS0e}Jw;vAz35C#~45uEe%0xW0&3JW4Y$N=Vy&(5mPN5>TYF0^+!AYzHMfD` zf`!YMEnG5t7W0jL602(9)vM22a$!Yi$?D35q44Ueg-aIBU$GDtu3o*g>f-s!S9s$o z=i2(G@`AM84JQ}mwDpmBTMAF#*)a8M|2^T^b4|+Z+4H|!D6dC);%=M2flWbb#7UR2 zu>?yJ6s`!5=k$OIli4T_hO5Vwsxt$DRpD`<4VeZ@BMlKec#j~_fu|H4 z3I{^G$1lZ)B>uihvuei~aFaTjnpAmnds7pFw2*XaZl+v~pDOURv^Tdku8kS7mX>&n zfqfGeGAou`SXHHCNUEyE%g*zVYQcp|LyMPXVwRr~m=!#9{B)zeIl87PX0*kP#^%Ph z#%NRHRWYL>7EOp6MZPo1*Boy%V$JdP`Uayl5v_?Cb;!FZzM;`07;S5eH)rI|7*npb zt#%)Br&BJ0W@4;wY-wwcHW_v8%{A0*)I^(_Bm>$tXH5O8lsle?L29Z0}?Iq`j+Tgqb=65wy``8=Kpt86c)MR;&HF zw6Ufo-WsoKGcImyWmV1piF>(6CZ75L5ooEK|b5^Ze@p((A8h2x3#gi?sp^s2_@+V}>w6vI@sK2{O$2&wkgSj+5L zGisZfl$v?mMax3Vh!-zgggl5jXwE#YO5#^t_ZK53CX>CoQO)yLRo|)>c)E=Tu`U9)p36c+}F)Tsl?fLCZQupVhZ%{6jXpw>~ zjkeU#s70|gE$vSGI6vAfLF7aI3VNwiK^OG^n$^q3Q&502%>bDfW&sue zRse1V?{+{3;0nNJ0487#>cI~v2Gk;tKf}+bAl?rc4;Y0HQ-A@$!+<1U2VfhZ1JDHE z6ZjMK0m6XG0Zo8SfX@NC0rvtP20RXU4)ANhtAKX^3OWu491l1fa6Vuf;{AXR;MYF` zUIsi5umKMO?ge}qupMv}U_ABUne|$sx)fz;23!T`1l$hTgt|-sY5~gu_aiO(Ta4(=6@Hs#SpboGCuz&!WX~2gAN&tTzhCJYTz>ff51MC1;fM&qu zfF*#l0p)8@xq_vw^{b+dZHwY9OSxi5G{r7la|MURafO)rOLg*RzvVN)X} zdWo2;G_fLHRnroSVGg;3<<%lmhUyHxB;H&POD?AGHHQ;(X(mRr9;4Q+m)5!}lxBpT50jd@^*Wurg zU7jiBidaV*^lzfSYp#@a!qQlCJN|aLqa_pd1vg(|7>C&jYsp#?A=Or}xETuwSV5{7 zO^&{wCZSryD^;PxZa=d#w=(03hXj4 z)MVP6Bebv?O)u7}{wNk{HaG4Baxajr0zB5L z&Rek9al$d`iugvI$Q0D<6ekAmTG*kcl5(25>+ItgM|We((Ap4hs>NxZj&V7<6*qiP z%SuqI7B5@6REDclRDDx>RiYt=N<5L_i`t{L=rGG<*U+j?@Wd@>iEgNB+lUeED8?>} zZE%=z?gx7Q#wM(QQQZ?r$r8N^4rs2&8hOb|r*wxRt)j7QZ4}GfA0sRkRn-=6i8bPO zp}q+gF2UvW)McO+u8%fh+-aDl9ssp8 znm7-OQm}qUQwSA8LlyS1F|Pd)ULI$6tyBL^U9ieghEoNWm^)X6^8xX#)C$f?=)a}W zD`S{xS}>5~9G)?7z7v5lbai%2+Rv+Ke`9PzBF_E9XUL_8#x%!;;f2f2!-04IBWd&2Q5rgkq=C9Xevc$r^pLtfb)#^yxVUT8h ztk{@{sjyCs;-n{`=i>hPs2)!fMKnKGXbRf-l9m0^oVo!BdLf2Es2VnjPdSHV>T8iN( zfFFmR8z2w9LEr>1UW!nIKSO*cWbQ>8cueqiq1*=Y!xgqb7ips~282AuQ0tb-i2p|dFgUBy{yiMd8z6W9Ck%T?hpx%>!#eg+{F93Q0{eVHh{{Y?v z6pv!>4mc5THXsa$0uq32fG+{=0em0uG~ju_9{}$FivL!q4hNhBI2W)2Py=WMYzN!~ zxC3w>pbzjg;Magx0DlD({~h~Uz*NBLfC~U?0PTS7fd2s85BNUdS-`IW!+`ezU&M!9NPsk$_VGa{=cARs)&=+W~h09sxWJ7y`TnDEzQceH?HcU^buhX8;xgRsb3R@EjUUfhtl5DZV3HiZ|KDV>MNVH|h?< zdeDbk-ox?!#u2!EJ`$@(znX||Q5=I?|6}oH#uQ~>WSfR}JdVeD^F;gwmU7%dvFYPMX=UfqiS$x9#eIy z9&ge&sw>o$xKCM&l~Wum({-vvwc=L2U9HDTs=duw-K<_sLQm-2n61L8Jr^>#Y04z% zZI&lV(l~?7uQ2C0teos~SvW9*B`7&!Nx~esf!OFqRJE^RoF?1aqTKB}q+VomYK`LB zp+#79+>%&xeOrSk0@IaCx3{&$n{jl#2-hXTp?Be!owKrbW4-y$k0&cQ)}9G=Zqjt%Uba~tl(q~Pi5lF zOnNJ?d9dBMa6Q&DI1v_>j<#4cSBF*Y2`+hYy31&6Mr&f{$8p5aSaW4s!y;U}Ij10G za`SS{b7?($i=K26mfm!p8=3Y17+`K=T_bn9qSQS(5vmgFC$G7rJ^tk3Mq{0Os6p|? zIO$5;ySN^=Losalm&Xz~-4Kmzi0Odi!nDJf=pMc3y`AWkw#(ZOY*Ddh#S%O_T2_0E z+RJ0eTMiY{CbGs6MXvc9_(RdXP5JV}?CB0?voKs42ys5DkTTsUWq1xAY zs0G-#*F+m)wYbjI3dsY*Tlb2@{mWi)&KXHMs}YUBx;+TtHU|=WwFXA!HU`G!v;{_angU5rOVDI?Ly$OW2UsHg zfA}>0L-}qjDDd5QiN5=$iE|1wVbasrHn!GGufr*9?ew)6wA$BBZ<&s%11}a#pFVT; z^qI2))6YDeKl7&t1JfH@xkimXATl<{WxUbYYAipmB1Ai~b=5?h`3^&CtPL-2VBV#^xSsY6 z)L%31PIxeu&U3uTqfI*bjBQJXXWzDD_~eQS3kkd;v2PQ^2Jbp+uF)EA$3jGx0Shk{ z!znuav=&!4#u_J87e)IaTSqN!KAcxVGK%(7Hj`OHv=#4mxFt}^sid{Iv}oBlgEfF> zi$*Tq?$DhM{(KJYrWZQ#1r9E9@bwPf=HTKn;@$MEPWp8Y&ZW7FDFhq@C;{LtEbL|U zcNND2^ZnT}z@dP{0Q|lPk0d?@C<5?Zk-8|(O=|f%6q-N4&T$Q0UoXjkhaWKwG8k=X&O4P}_Agy?1it(+{wYcxY zyB%2F$Ks$N!INIl%{6#SqNRQfAxhpBtXgqtrkdLM?hmdt5hpDexL#k{soHqEoD|pM zfTscRn9=nmC{B6T$ZZQS4-N4|+dB}|s-iXcYk4&_l1H>D(ZIkt=bk-vGcbLz7E3b& z@1!K~;up=VMdNI1U^CI}rq#f)AkMC9(LTt}E(wWxzP+RU7RL))(o=D@w?39hQ7X%q z9trXE7~b37)UePgY`@dbUFwGQ*42bIYRn;xyj`z_NOVomE~Jf+SvfCi?|47h_}V*2T4 zWDTJEAwSDA04JuOappfOADliDqqZKv6VuNMX34XCpIV@Sb;Jjx%DPQ0KiSaje(ro- zT`kUCtAVSZ74DE!!;4oA1@x7BKR|}ni|1ds4Dk#Dsp+j7n`?}?oHWV{W3BGy%UH9~ zSjFBTim6L@iRa% z1v#k?2#=BvDXT%L7C}9`tlQ2Dp6jmT{w74XjZ1?i|wJ%F$|(wBcmPu-@DS_+0m$NCU?kv6fRY zLV-i`ID4xFx`lA9J=g8G*;BiL<$^vZ!K|WXJ*N=+B}ALJe{=HOFB$JR>z)YcCgcpX zu*I#jbV97(NKVHb7vQGJF_j zI%OC~e)90q{l#m~N86$$`Fn3U>UHxW_U6Md^Cx!uDS2F5iAnQem^|bsCLR8AiTKle z^3(GW7GFAHH~tAvyc@S)ywshe*Q<*!S2M$&G%na(i%!8Bsl8^grpb;GP%(v0Uiku)(MhWRibh6xOlpLX&gFT=#lhhbvo zPn`@i?KcnoeqIhd0onzoxnbgY5RtrG`+#h7aCeU1qa#7Ehkgo=C{d^68Yf{=w z+gS#d z8;%K>1PB2t0P_J001E+&0OtWJ0gD0W113CL&*Z-Z|q}J;5+A;%y02 zer{-0@c-0dO1Cy4p=1+%B(m&b#ZKNyngl|4fuHIp9O^{}=gS&m$7v^_OzgMJDX!VYsgDMAPMG z*yXRQTO{Gxv#Y?fNO%~ApB?@Z`W#{F@w&Pa6S^eKy3k>_9(Dg@obIa@>U1Jxs~mne zEcPRQwxfTt6Q=&j&>403r#NBqGkjK>pJC`0{-5l=RKh>mZ6M!Eg@<8RzqVnv@MznX zWQ7$T#uM|o{kFx>vqXIBhEeAz%VHB4ZFdRkW3fqIZZ8?_hOGT49tEaVWzv`y1IKsKY18F{qng_Fbs_PyH~>G zcf&3}ZE*P+cKO}1liv+fo)6p84;L?aLR0Q|c-uLQ*KtZA9r-@u@Gw^TFsB>Jr)4>Y zpdX%-853?39`d1WrS<7BX=|QyM#4R4>qnoj%*i_6*thJgIn!sQ52zD3XUP)gW^1m2 z>xgD8!P!u zGEcfbeaZax?uoLmPI5Na$e4Ssh3?KR!wkdc;#-oqZNpAfU$@DoG7-mpCk_N>jEAhd z52pPe0~9cTr;xuae9s4n>pHIeiUEvwd5C4d=id7nQM_Tj7GL(lL4Gq%R`69XXQRnw z49_Z^LyG2D4BrxzuZgCQnNKy=U>n~YPakY#?dVrD@LQ!kPm%h-7TIWyZ7^yYVl`Ka z9@!nwo)P$z(VoC}BxA-#oS$RkU8~P7GH18WUVR^XblhWl-ZFQ$`L*qGe(2b%waicn zzQ0Zb@B%x^$|F#G8xG$S#BoneG!b3H`z^dGE}pN$*GjN0cg~+2L$pFUc1)j5&QLtL z$9EQ3Se{C{`}L1Jvs|`v$&$T1D4DxQooLG+;Vaf@)-~~5C}^IJc7vkes8-He4V**h zLsqYLX&YiNj#?TM?f6Ct?&G~2d5&7yIGlFGyX1VWh$^KGId3s*r#PnOkm#2lmSY-G5iU*hK|-flbkvT;wAJ9dKuy5v0An zUpX9LI^cl=9ys8E10Fcwfdd{m;DG}kIN*T;9ys8E10Fcwfdd{m;DG}kIN*T;9ys8E z10Fcwfdd{m;DG}kIN*T;9ys8E10Fcwfdd}+|J?(8Hz4J_zcRQ?ztb|N%@<~;`*Y~w zkCGo#@&A2-anLRNYQbI)-*;dni^%UGxbNB&Ibpuz<_8=E;CF#b0Q}AazyILA2S>~} zV!lJiv_k-VM~-pSOIc#RU&lQ7?giucj@{u7Fn%h4@qCw`bjYFSJ9HSBGJMCLe0%Rzn%K%4(hd*1>ORk^miKvLR!%t6QdsHCW< znCpJOprN8tp;Dq@VNzkT3paR4QBlXVoJwmfswqi9*@i|1Wi}=yniiQQDZe3-VOnBh zQet7A=bJ$z+wI-I|Fh3IyW_%_Z_S!D_+8%jd7k%OYi1TTw~Nt|=a<09^DY?qJF8#= zU@tU3ei1F{UmlG7e;Z)ryfJigh~KNrtNx3Uu>y}I%z67PTr{9O6W z-+LU3Is8XIF7*A%pI@H82&2CAL%w_c_x!Z{3yZ0rf5<0e{hpsouMfwZ{QtfMVFJia zdZfK#E4_H}()X`iY`zb;-UGAG9)B zf83%aFFkPt-+P1BhnD!T8!d^=RJ0w?>SzfTgrFs0QdJ#nC+}6tL)#r~8d?%#F=*$Y z<5?mwWB6CIXh}i$_ z?f->7kU0nn4)ITU9wsVz@q>%6Z=RU-M*=%9<_FqEYifuKP|*vr{cQoxe`npHb>V@h zfAxFOPk}?x&27o=Jb!5O`LE;rkJi?%?M5A2dt&YFzy0?Yyy$<$SUA|&Lw6hsr|vv- z-y!zb=kKqqt~rnQo-GLU%z-mvjt1M|i&QjP5)V3B5)VAuUTCAxlK6>0OXkIi_Byl< zw1hKkXbCTdpe6Cw^m(wI@NEOyo@ndQk~pkG8;>j5Zf-Z?s;tebDBhjX>)`>*;A}utZn_EFKmMi-yUtC|EeG3(N)!g@wQ#C8!F19Pb8_N%0ffwWkM+bKBd-pXz@Ba{bc|Y1~ySyL2quu5Gh=%r;_OqYL z>2zs7-1m0Zz<$W~J>4JU$^MI{%J+7EcmK`N;q@<+qz@|CwDb9C(fcM}=zFZ&W4ClY zxg>hVQwLYyc-=LR4tV*6==0liV@@q<|M;TCZ$@v|KVARP#ZkTHyt_a8fn7E3ud?@y z-1=m}P~Xz&xAs>aJ(pgSHOzPTvFh{B|9Eo2#<4fP_~ooG%D){j#I>kjOr*W@#>UO| zFLsvw5OZ=v#o2QwKOa4J^+&_+E`M*;b?Z0hcKu@Ah_-ikw#{7h(9BtTVsA(a@uMr%@vcI1{vpT58S zlJBe?`=jpedNi@~8y}ys_OM!?LPn3<CFxt?GNXdX(XtdcN|J z$BO8)>!@$5#!Oi;*P3$c#CI0FGCr&QTX$LqzZvpq>$jg++VRI2E5geEO3Cm4^}>RI z*8IX3YketMBlaD>)tox7b$OqJ*-I|2T4b#HLG3zsYTp}~(n9_Ehd-7Vk9>Lyb>W~^ zwLCGj`zt5DcxZhqZI^5Kur{whGgJEP29=xP{G`uk>^GxUPEyt{d%JYPq5Q?`*OstH zQ(q0+Fm6rE#5e3weMi*}7WrGoZ{9n-@8c6g@=B}Uo&V#BT|HkozI@VzRr>b$CB3`c zJm&7ZE-ZQc<<_40VYP#+*X;ddcgW%Om4C`k55#-@nTr?W$CG!h{_9(O%>V55(PQwr z6)+NIEqih0<4ezx;{-D`7wOZ4Sa@z9S_4{LH^9izk^?YZ_5shBs<$bQ1TnQ z_zd_`wAi5lxde3qz5WKj2?_%*DX)7v<@HRb^8J=UZSrPNCHWb6Jdeuvx~NV0#N0Rr z+eBIqS`W3Y#6#_Zm2C22-%IV?=A}wX^05!wmQU@19oR+MP1N39o3KyXZB+GvZPbAS zyQt%^0|)lP4p66$AE1sOuZA6`&YeC^oj!ehkVu%xp@UDFZ_3YB4LnPO~wY^=p&UU-K zbNc~ZBHFcMTDR`ePi!a3V*B=yk$6dz-5$XT0y|)^9Qcc3|Bmh3J9_bfM_2y-?+)gd z^Fg3{Pe{Oi`!5BskKo^)kVu>s4vU6e###J@zrSTu6#fx#^*8v9-QR_?uBihk&vaPE z04ie=LuE{5DA#m`a%V6&Mjk8FJYv%o%9Wu|o_Px8g=I_~hGWBUY#7cRhGWC1d>1)3 z8plTCywQ}`HJZwIkESxFkHc|T#yC7Tj&jc%M|oW1@ccMDHwlj?;qfHOHE$~Ac1^`T z%smwxFqJCtPQ~#650rSPV?P7uWPlsM2jGNl-~^8woB&?f-FGVSPLH6yNx{d;#?T`#Lp>ccQy0MrcL=c z7T}gkyi!uK30wmMzqI6-1A8}7)vyD5OVE~3yP7#?*REaQAJ|@SPc>-?_w2=ffP<== zd8oP?JVXq9beh=d056>eFJ0y)KR;dNs9(n39~+wy^?&H?N*w;p$4eJ4&R*_Yvufe|5^t!5!>jVUhBfF{9>?DVC#C#0v(#TPj*Uc9v36#VJ-)6yKbJ5n9$s9`sZ z%NTk~SoHOd(f0oR@4tUxyZ&Kzdu+RQQ#o#F_v;4_?tW7SXTN*isBZBC0%M5`vv){r z*Dm9RZi8>QYe2urj_x;iNS`(O);pS?k8U4kAFyz#JY{M2vUb_7Wv=?}SA+_bRWIrRiM;M0T-y)~B_@6GH_|SvXCd9|zF)ia4fBEv$|N71!+WCLS;DB|% zx&4lp|I<@`^N%+_LDUI8wFW66Q7I(T45Grr1CL0aN%Gu3^oEf~qh6OxKR_>_AEmwY zOY|0cC;bV1gs!8{(*qfWiDf1*_b@XV7n8%jz`n%3!R}-$*e}>~Y&(wU3b|9@Xz!4{8qk#Kg6Hl&+@H=Fkyhe31fum!mGl2!f|1U7$c^Lh2pznx%jDAEq*Ef zD0Y^5NCPENijl@kcS*A(m$XV+BfTlTC;ce3k=x4MeQUup!ULas*oB@zw`L|Y_cLB*9rG8qh<}5x6pjcti(YYt zG(Z`wFp8ikih&+4RMsk=D&y6B^;LDhIncV#nqiUaM)*fPgf;Ncw=>(BlWYOEntwo; zD9TbVxsx(TU8yDMV~nH5Z1Vp`Q&c&c+h~>vW4~pqxLiJuFW?LLBEFdKByTuk}q0@b5#R(8-|hMq9I|shA0v&nPRwT4ohm=Wr!+|7r5mMj(j+NWnj_odS8MyjT8O zJ}+O8gOqEOYn8T282Y|S$x+@?-c{aHK2|=YgN12RgG3hs$+&i~1;iyndfPTYpS{ zQeUqZ>F? z``Lr+I&K5^68AFq8uteG9HReK{&jvI{~3RbKgYKfx(n9}k}wq5n<(5P%z_^;5ta*& z2|2=Ap+wj&d?*|ejtbX`Vd7Bn7IC6@rre2t<*_kBvTqGt&_G% zW$@A_cznmreXAdbzt`Iv-Hj-NH5B8ZaSmVG*U{`@_A#SO-Zab!K--z-e4wq{^q9|^Z}`{Z zd#puUtE1J+8emPg=3^ba)&^^{Rf4tHVZCo10UDpRejw|S9l(-n=x%gRx;NdA9!TFn zv$RO7v`G)6M_`R^rpM8@(Ua(V==!OHArYuWBxEH|CY;kIx)xmJ7_-yP_2kUxdl?*#M}g*ah~ zkSDw%oDk}SGeQL7X_`1kTn!}XCEXyUOY@{0=|iCIVd)F$l++;gmIuim`3<>L?yR_# zHD#=XaV%zefk14f_6+_mL9 z1EmK6pDiHscwq9qK;!xRL%f@R2A;ir?c5bdSDH-+*~61DhSxkLV4+mo`Q_ z%;J9IGvgcM8q*069%+s>V=!wIFmD-Fw&k(b!B1bd&R9)k?s6%r5ltJqJ>7%uLrb(l z$J0~cgG=ccAcL3rkZHvxvJWH9gYjXc)3{Quk?RV+n#^bL&+)JDNBKrR9G*2)7%5ak zO`R2*gdnk#I8Yn`tX?24!`Qrt;MWnshcK$^q|Q0%*Nf+8}L~N+h4OLwa92 zB%PMdO6Q=lE=sNBHu9h4c5(+f0K9r85Q|TG> zgNV7+^b2$WVy+ZO`7PZ@2Qk+&oteJO4UEhTXQqPr)0qdEY|P4f<^yIwbBOtd`JTC+ z9m?IzWx$`ZxhJ_i?i21i_>YYr4Fx)ve;S@~t*`>?`+@j9@Jo}1ONr7H>0U(JgVHj@ z+Y8cqsaV(?-xm=ySYQMJYR7L@g7Z z28z8VyeYgZd@R%m4Z;PXjc7+q4HPwTxR@Yr5R2e(rHG+U@U`L6lTtPCEL5iD74kEf z(_?ZYyr>QQsH@T+n%z`JKubeDWRoWBMrl4gCWh z%(R0~ip-77EzBe)i+O~3mD$1^Wkgm3e~)70*$M0&?A>e{7>NvHiz}HxojR= zz!tLY;iE4hiZ60~_&&n^zYY}4`5oND}MYlpNeIg%_56RW?QF*sg4uw|% zF0E2Nf!B3}svfMRYBRMp+9qv??$b9JCC2+k1u}s%#sp}WbSRc`^OSkse9(FXoS8 zeH(egTiOBbuy$1YO1no-(;w8A>TZ3No}+Knw?Vtr>EVWscv%WXn-6~4iE$n?Y*1=3 zCRHC87eR(uSc}EXa%ic1<|XE3rkL4^@s%;VnZ3*>%t7WFb|f2zb;)2qWFxqN+>PMs zG_Eb*fsaBSkcm90n-DI{fPb$LIzqiK7k7wz#G_&#X#ldKf$}itV<)2g4IhW3(~XSZ=H`o-zhO z*9Moqu_Hlv9}=uS`B4bz?LDt_i+2LM#s5t;bT8>p?o-Uogv`R3H+VNY6_5xcS3we z3rWI!Fyo6tv9MLx0d71iTqpJvb42?Dy?6=Z- z&e~*^S|3;+TL-Kv>np+qxKYT5rZsJ&JJU`?-9RX_XxfEJLualxR?5IyP2`ffd$@Gu zC-b;P+$!!_t{58Y1LSnke2r8G&I*#l1_OP^h{@t#kad0rzWYfGL54O)nveQP zK63fK$jjXFD&Wi*Wi09>Pb)*!c&u+Ulwy+pmhLmkjl+np?~K-FiMh?}jJxq3$C|B& zuHH_@i<`g-(U7{(I(k3zDEl;4;3C%vm7ej^1nG98`zHDV9=Km{XdQD0Xb(lI%ouKBS>hYaly^aHWuGK!!DuD-IBcm&VO5KO-AOf+o z5S1A>FyI;EZDWTq49Y6SywBW&^|4#Mtyt?;YpQj>wa6;4-muP-zD5U8IcVC_gP^O% zLuD+0s#-`l~g^ z%7X8^tgi$4VSEr33EsB*y*-?cpoh}a>F4P@XrDs52yC;3_CW*viLoPB?7}#KXB$!H zIKX_toMO%)?%M*hW7%Z*QziQidp-9sx0&0+?d87q`%fpnCw~J}^EmjDdq;yt$sBZNMwFnt|h5D7+M(e2c zM#er~yA#T2A*w)YkdxGC-)I-K{>apa0X-`99ze(YjRnRU%wMH>i-*d3P8AT zh>Ae%CyW`un85aZh_3TY5Zi`r$4)|Syb3w-090_MW0kh@JNP|_kwbhfe-f3(^Y}ve zYlKdybq$x3pyV#fJrxOke;jJ=6zU9z)Nj=YR1>mwm%bc~vl5CvNB087^7I0|P`?A5 z^RThrpwff-qjr-*J2b>O+}`%2iO9hxi`I3BkGM0T zd!|cEz=8$Pm+wg<qHyWR)Ulz}LskNx9@W>in!1oHRNsG|q^i0e`8F<$L-c3Qw z6@zgb3

    %!OVi6`^+k{$#hye*2-n&0SRkKysZqPPM`^)qoCCf*(tPV7Bv&F#r5ahm*7%7d~xQtbe=3<~d;!vMV;1ancAWjOGidjhKGLgju*kC#4 zWF_Z8Ex`+Qp2rnnhKk?|TR0zbz%p((R}P-9;40xAH7%-jjhID>zmi2F_(*sV&GWp> z>wGk3ITk(~51&fpllWvlg-^x2Ut*eU-o-D+Dy)RRN;3ZlPS*2mh^v zYOE1z{S}dVWDm#BCXtdtq)^Ew*(Hb61=Y=PDME@wg)>3Qlst&#Dk(&cLUl7s&Xdbg z4R-QHUVD(9_NE@vgy2@1gt4UHL^*MFye5v!E2Nmb%kfl*S!fU){_$l=Uep3=B^$;UcLjF1 z{Mb>aI55HlMAh#{k18Vsl@Nj*c~DjjK#my1lgBEC0>t1-gQ#@GQwW&w5^mJd4n}8E z5KYBQRdX~YK|$sDQN!U!Mi-)@95reOygC6$Ovc#2M}Xxr1rI!}!av41_=M*&X2jvj zhNpRiJXSCf%#bXnKrg1r>Bv&%U`?}S7j%nTUJ2yPfqu!wDi_Fwa*o<<>W(+rA%p=5!S%# zP9R^d2d*~)^C&e0l@}Z8=nl1u>Quwk2sKiTLaxQDvZ|xD9;3zr7vr&tmAF1u18h8j z45l8;)CixYv=A*+vuSqCp>@%m$TcIhNG(dE!4oq0G8$FJSon3kmY^kqIg+&$ zIDNc$95+_PYQnHkS>rH8> zM;blN+5EpEGj&h@}bT^^05?}Xh#ya#H&3}RTV({DD>O| zMHK=)l?i{Y<(%lb8|uD^=l!u7;I#zwz6`pU2iE2RHv@U48%$Ouhd|jRH0PBeP#FnV z#AYU9vjVXhg`Ru;ap^=>84b3Mg#wO8geDqExEh~gq=LWGp^4`Jld_SEEl1|r@-Bt~ zqtGY{Au!?Dz)k1$|H4QVA<*&^JQ)P%H2m0ngPE!ltY@nkU9;&|%SxpqnBY#dnm7o?? zf(FD^1oGoRpL~e1axM!wXB}S%ogam)P)7!5L$*fLy%+IS2S#s_B7j~==%E)1z7U$L z3Epah8c##4WkF>ZLQ&Tu-ke~QLY0T+D%NzMLIt?P3Gb>fBH%Nm_vMH!8>)IvFryEv zS5C$d57Izw}(f!CVAY)){S4xOC@ZJh-@?S+Q+f#<5Am79QGPH18sIyec}OtMhP@Indu z^m6FKI^>r&j35e;7Ki9cLqxfeYZfAM$`LJfh!C6q>a>m+NWuuS;Okzjkq;xS0z)=o zv`%1&4lhrFXJ^5iz3^ZkMqUL^Z6f1O4knlW!JAHaqz*4kg6CynMZNy@Bz~2Giby6@ zbquOL3H}*L;L?zfR{8NI)32Qip`C45!36&rx{zD*K*w^~jn(lfg=!k|g>wJ8ka~>= zh@F5j>4@MgM5)`<5sh)A0)-@!_*4>Npb#tKLtUl`*|LrCLESb1?`+VwS2#37qg1m zQg*pZ} zNFl0x<^L&OwKCX$Kg2J6sur`s`>Tin=4wEc@$jerPNt&!by+c@E(F!2I8+6^{)(vs z@t1_Wp%6Ji6A&W~vqo6Cwz*uJ!;k2){XyohJBk zuNV>71b)`xrCEqNA0jSL|HuTJ6az^bpg?(WN2b39QsJ*D22(PY-T_=s@aLpHpkfp4 z1Rj#C)C(Ubbr6!Dk-W4JtliKeKlAykJx#@Ne&n3rlkM0ZyJE1jrSBmpHaWvHRQv!;*;eV&Y5HWjm#4&5~ek&umw*mBI> zN>q(<;FGyP+ycyG5meb0_-839w7W5{`=EI$|1C9%-(OKk(vzW8Qh}=JSkF1Y*6iQ7 zLQn)O+5*fi1=H;Y^6mq3RATjO5bY-r@Ac4WjqnA^2r)tpn_)K`xZBuigrnXZ33R5B zp~$~m4SC>45y0v^phg4~hnKKWQ848O=7j)%vw(O_epTuP6E%TDQ&2CfMMjnae5>GW z@D3NWT?o9w1*CAGa+-%qMHKu$59`nS5zPi1%Yx5W!Q&IKQnhLnyu1v#RVGFl1sLnid4bjLcP?-%{4A_Bi zcLM4_Rp@0BP__>D6{n$xRTi}`n542)6j-VddLs(lRET*>fZ8E-9viA1Nx;@BsNf`U zbQQ9>B;<0WPfqYt5>&7c^W_9zXQ5X%e}$A_Md^QZMeyGrd#-bQ5n`nv&g$i)sT51ID;iSPOxU<6lTtHce)2VVO>a~@qg~EaDt?-$G zxTn!y>70Xl<}b5}OSuF^x1t<4FB%#uprFWuR#X)lqPJ@hdxWziaOHbnz)0wD*xZqzNuu>jsBE|5uGGvSuehpHGSP1aC16Ly=aP5o#w^hJ?o&EE2 wv|I`Vz_6}vS7+er3|yUot21zQ2CmM))fu=t16OC@>I__+fvYp{2bzKZ1z>%CAOHXW literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/History.txt b/Extras/CDTestFramework/History.txt new file mode 100644 index 0000000..b0f93f2 --- /dev/null +++ b/Extras/CDTestFramework/History.txt @@ -0,0 +1,11 @@ + +========================= + +V 1.0 - March 16, 2007 + + - sphere vs mesh queries + - OBB vs mesh queries + - capsule vs mesh queries + - complete box pruning + - bipartite box pruning + diff --git a/Extras/CDTestFramework/IceHelpers.cpp b/Extras/CDTestFramework/IceHelpers.cpp new file mode 100644 index 0000000..1e2c422 --- /dev/null +++ b/Extras/CDTestFramework/IceHelpers.cpp @@ -0,0 +1,358 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" +#include "IceHelpers.h" + +// Misc functions borrowed & adapted from ICE + +void RotX(Matrix3x3& m, float angle) +{ + float Cos = cosf(angle); + float Sin = sinf(angle); + m.Identity(); + m.m[1][1] = m.m[2][2] = Cos; + m.m[2][1] = -Sin; + m.m[1][2] = Sin; +} + +void RotY(Matrix3x3& m, float angle) +{ + float Cos = cosf(angle); + float Sin = sinf(angle); + m.Identity(); + m.m[0][0] = m.m[2][2] = Cos; + m.m[2][0] = Sin; + m.m[0][2] = -Sin; +} + +void RotZ(Matrix3x3& m, float angle) +{ + float Cos = cosf(angle); + float Sin = sinf(angle); + m.Identity(); + m.m[0][0] = m.m[1][1] = Cos; + m.m[1][0] = -Sin; + m.m[0][1] = Sin; +} + +bool SegmentSphere(const Point& origin, const Point& dir, float length, const Point& center, float radius, float& dist, Point& hit_pos) +{ + // get the offset vector + Point offset = center - origin; + + // get the distance along the ray to the center point of the sphere + float ray_dist = dir | offset; + + // get the squared distances + float off2 = offset | offset; + float rd2 = radius * radius; + if(off2 <= rd2) + { + // we're in the sphere + hit_pos = origin; + dist = 0.0f; + return true; + } + + if(ray_dist <= 0 || (ray_dist - length) > radius) + { + // moving away from object or too far away + return false; + } + + // find hit distance squared + float d = rd2 - (off2 - ray_dist * ray_dist); + if(d<0.0f) + { + // ray passes by sphere without hitting + return false; + } + + // get the distance along the ray + dist = ray_dist - sqrtf(d); + if(dist > length) + { + // hit point beyond length + return false; + } + + // sort out the details + hit_pos = origin + dir * dist; + return true; +} + +bool /*Ctc::*/RayAABB2(const Point& min, const Point& max, const Point& origin, const Point& dir, Point& coord) +{ + BOOL Inside = TRUE; + Point MaxT; + MaxT.x=MaxT.y=MaxT.z=-1.0f; + + // Find candidate planes. + for(udword i=0;i<3;i++) + { + if(origin[i] < min[i]) + { + coord[i] = min[i]; + Inside = FALSE; + + // Calculate T distances to candidate planes + if(IR(dir[i])) MaxT[i] = (min[i] - origin[i]) / dir[i]; + } + else if(origin[i] > max[i]) + { + coord[i] = max[i]; + Inside = FALSE; + + // Calculate T distances to candidate planes + if(IR(dir[i])) MaxT[i] = (max[i] - origin[i]) / dir[i]; + } + } + + // Ray origin inside bounding box + if(Inside) + { + coord = origin; + return true; + } + + // Get largest of the maxT's for final choice of intersection + udword WhichPlane = 0; + if(MaxT[1] > MaxT[WhichPlane]) WhichPlane = 1; + if(MaxT[2] > MaxT[WhichPlane]) WhichPlane = 2; + + // Check final candidate actually inside box + if(IR(MaxT[WhichPlane])&0x80000000) return false; + + for(udword i=0;i<3;i++) + { + if(i!=WhichPlane) + { + coord[i] = origin[i] + MaxT[WhichPlane] * dir[i]; +#ifdef RAYAABB_EPSILON + if(coord[i] < min[i] - RAYAABB_EPSILON || coord[i] > max[i] + RAYAABB_EPSILON) return false; +#else + if(coord[i] < min[i] || coord[i] > max[i]) return false; +#endif + } + } + return true; // ray hits box +} + +static const bool gNormalize = true; + +udword /*Ctc::*/RayCapsuleOverlap(const Point& origin, const Point& dir, const LSS& capsule, float s[2]) +{ + // set up quadratic Q(t) = a*t^2 + 2*b*t + c + Point kU, kV, kW, capsDir; + capsule.ComputeDirection(capsDir); + kW = capsDir; + + float fWLength = kW.Magnitude(); + kW.Normalize(); + + // generate orthonormal basis + + float fInvLength; + if ( fabsf(kW.x) >= fabsf(kW.y) ) + { + // W.x or W.z is the largest magnitude component, swap them + fInvLength = 1.0f/sqrtf(kW.x*kW.x + kW.z*kW.z); + kU.x = -kW.z*fInvLength; + kU.y = 0.0f; + kU.z = +kW.x*fInvLength; + } + else + { + // W.y or W.z is the largest magnitude component, swap them + fInvLength = 1.0f/sqrtf(kW.y*kW.y + kW.z*kW.z); + kU.x = 0.0f; + kU.y = +kW.z*fInvLength; + kU.z = -kW.y*fInvLength; + } + kV = kW^kU; +kU.Normalize(); + if(gNormalize) + kV.Normalize(); + + // compute intersection + + Point kD(kU|dir, kV|dir, kW|dir); + float fDLength = kD.Magnitude(); + kD.Normalize(); + + float fInvDLength = 1.0f/fDLength; + Point kDiff = origin - capsule.mP0; + Point kP(kU|kDiff, kV|kDiff, kW|kDiff); + float fRadiusSqr = capsule.mRadius*capsule.mRadius; + + float fInv, fA, fB, fC, fDiscr, fRoot, fT, fTmp; + + // Is the velocity parallel to the capsule direction? (or zero) + if ( fabsf(kD.z) >= 1.0f - FLT_EPSILON || fDLength < FLT_EPSILON ) + { + + float fAxisDir = dir|capsDir; + + fDiscr = fRadiusSqr - kP.x*kP.x - kP.y*kP.y; + if ( fAxisDir < 0 && fDiscr >= 0.0f ) + { + // Velocity anti-parallel to the capsule direction + fRoot = sqrtf(fDiscr); + s[0] = (kP.z + fRoot)*fInvDLength; + s[1] = -(fWLength - kP.z + fRoot)*fInvDLength; + return 2; + } + else if ( fAxisDir > 0 && fDiscr >= 0.0f ) + { + // Velocity parallel to the capsule direction + fRoot = sqrtf(fDiscr); + s[0] = -(kP.z + fRoot)*fInvDLength; + s[1] = (fWLength - kP.z + fRoot)*fInvDLength; + return 2; + } + else + { + // sphere heading wrong direction, or no velocity at all + return 0; + } + } + + // test intersection with infinite cylinder + fA = kD.x*kD.x + kD.y*kD.y; + fB = kP.x*kD.x + kP.y*kD.y; + fC = kP.x*kP.x + kP.y*kP.y - fRadiusSqr; + fDiscr = fB*fB - fA*fC; + if ( fDiscr < 0.0f ) + { + // line does not intersect infinite cylinder + return 0; + } + + int iQuantity = 0; + + if ( fDiscr > 0.0f ) + { + // line intersects infinite cylinder in two places + fRoot = sqrtf(fDiscr); + fInv = 1.0f/fA; + fT = (-fB - fRoot)*fInv; + fTmp = kP.z + fT*kD.z; + if ( 0.0f <= fTmp && fTmp <= fWLength ) + s[iQuantity++] = fT*fInvDLength; + + fT = (-fB + fRoot)*fInv; + fTmp = kP.z + fT*kD.z; + if ( 0.0f <= fTmp && fTmp <= fWLength ) + s[iQuantity++] = fT*fInvDLength; + + if ( iQuantity == 2 ) + { + // line intersects capsule wall in two places + return 2; + } + } + else + { + // line is tangent to infinite cylinder + fT = -fB/fA; + fTmp = kP.z + fT*kD.z; + if ( 0.0f <= fTmp && fTmp <= fWLength ) + { + s[0] = fT*fInvDLength; + return 1; + } + } + + // test intersection with bottom hemisphere + // fA = 1 + fB += kP.z*kD.z; + fC += kP.z*kP.z; + fDiscr = fB*fB - fC; + if ( fDiscr > 0.0f ) + { + fRoot = sqrtf(fDiscr); + fT = -fB - fRoot; + fTmp = kP.z + fT*kD.z; + if ( fTmp <= 0.0f ) + { + s[iQuantity++] = fT*fInvDLength; + if ( iQuantity == 2 ) + return 2; + } + + fT = -fB + fRoot; + fTmp = kP.z + fT*kD.z; + if ( fTmp <= 0.0f ) + { + s[iQuantity++] = fT*fInvDLength; + if ( iQuantity == 2 ) + return 2; + } + } + else if ( fDiscr == 0.0f ) + { + fT = -fB; + fTmp = kP.z + fT*kD.z; + if ( fTmp <= 0.0f ) + { + s[iQuantity++] = fT*fInvDLength; + if ( iQuantity == 2 ) + return 2; + } + } + + // test intersection with top hemisphere + // fA = 1 + fB -= kD.z*fWLength; + fC += fWLength*(fWLength - 2.0f*kP.z); + + fDiscr = fB*fB - fC; + if ( fDiscr > 0.0f ) + { + fRoot = sqrtf(fDiscr); + fT = -fB - fRoot; + fTmp = kP.z + fT*kD.z; + if ( fTmp >= fWLength ) + { + s[iQuantity++] = fT*fInvDLength; + if ( iQuantity == 2 ) + return 2; + } + + fT = -fB + fRoot; + fTmp = kP.z + fT*kD.z; + if ( fTmp >= fWLength ) + { + s[iQuantity++] = fT*fInvDLength; + if ( iQuantity == 2 ) + return 2; + } + } + else if ( fDiscr == 0.0f ) + { + fT = -fB; + fTmp = kP.z + fT*kD.z; + if ( fTmp >= fWLength ) + { + s[iQuantity++] = fT*fInvDLength; + if ( iQuantity == 2 ) + return 2; + } + } + + return iQuantity; +} + diff --git a/Extras/CDTestFramework/IceHelpers.h b/Extras/CDTestFramework/IceHelpers.h new file mode 100644 index 0000000..0d260d5 --- /dev/null +++ b/Extras/CDTestFramework/IceHelpers.h @@ -0,0 +1,41 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef ICEHELPERS_H +#define ICEHELPERS_H + + void RotX(Matrix3x3& m, float angle); + void RotY(Matrix3x3& m, float angle); + void RotZ(Matrix3x3& m, float angle); + + udword RayCapsuleOverlap(const Point& origin, const Point& dir, const LSS& capsule, float s[2]); + bool SegmentSphere(const Point& origin, const Point& dir, float length, const Point& center, float radius, float& dist, Point& hit_pos); + bool RayAABB2(const Point& min, const Point& max, const Point& origin, const Point& dir, Point& coord); + + inline_ bool RayOBB(const Point& origin, const Point& dir, const OBB& box, float& dist, Point& hit_pos) + { + Point LocalOrigin = box.mRot * (origin - box.mCenter); + Point LocalDir = box.mRot * dir; + + Point LocalImpact; + if(RayAABB2(-box.mExtents, box.mExtents, LocalOrigin, LocalDir, LocalImpact)) + { + dist = LocalImpact.Distance(LocalOrigin); + hit_pos = LocalImpact * box.mRot + box.mCenter; + return true; + } + return false; + } + +#endif // ICEHELPERS_H diff --git a/Extras/CDTestFramework/License.txt b/Extras/CDTestFramework/License.txt new file mode 100644 index 0000000..290add7 --- /dev/null +++ b/Extras/CDTestFramework/License.txt @@ -0,0 +1,49 @@ + +//////////////////////////////////////////////////////////////////////////////////////////////// +//CDTestFramework re-distributed under the ZLib license with permission of Pierre Terdiman +//////////////////////////////////////////////////////////////////////////////////////////////// + +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//////////////////////////////////////////////////////////////////////////////////////////////// +DbvtTest.* and btDbvt.* are distributed under the ZLIb license, Copyright Nathanael Presson +//////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////// +BulletSAPCompleteBoxPruningTest.* distributed under the ZLib license, Copyright Erwin Coumans +//////////////////////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////////////////////// +//ICE and OPCODE 1.3 re-distributed under the ZLib license with permission of Pierre Terdiman +//////////////////////////////////////////////////////////////////////////////////////////////// + +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ \ No newline at end of file diff --git a/Extras/CDTestFramework/License.txt.bak b/Extras/CDTestFramework/License.txt.bak new file mode 100644 index 0000000..e69de29 diff --git a/Extras/CDTestFramework/OBBMeshQuery.cpp b/Extras/CDTestFramework/OBBMeshQuery.cpp new file mode 100644 index 0000000..2bf7371 --- /dev/null +++ b/Extras/CDTestFramework/OBBMeshQuery.cpp @@ -0,0 +1,157 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" +#include "OBBMeshQuery.h" +#include "Terrain.h" +#include "IceHelpers.h" +#include "RenderingHelpers.h" +#include "Camera.h" +#include "GLFontRenderer.h" + +OBBMeshQuery::OBBMeshQuery() : + mBar (null), + mAngleX (0.0f), + mAngleY (0.0f), + mAngleZ (0.0f), + mDist (0.0f), + mValidHit (false) +{ +} + +OBBMeshQuery::~OBBMeshQuery() +{ +} + +void OBBMeshQuery::Init() +{ + mBox.mCenter = Point(0.0f, 0.0f, 0.0f); + mBox.mExtents = Point(1.0f, 1.0f, 1.0f); + mBox.mRot.Identity(); +} + +void OBBMeshQuery::Release() +{ + Deselect(); +} + +void OBBMeshQuery::Select() +{ + // Create a tweak bar + { + mBar = TwNewBar("OBBMeshQuery"); + TwAddVarRW(mBar, "Extents.x", TW_TYPE_FLOAT, &mBox.mExtents.x, " min=0.01 max=200.0 step=0.05 group='Extents' "); + TwAddVarRW(mBar, "Extents.y", TW_TYPE_FLOAT, &mBox.mExtents.y, " min=0.01 max=200.0 step=0.05 group='Extents' "); + TwAddVarRW(mBar, "Extents.z", TW_TYPE_FLOAT, &mBox.mExtents.z, " min=0.01 max=200.0 step=0.05 group='Extents' "); + TwAddVarRW(mBar, "Rot.x", TW_TYPE_FLOAT, &mAngleX, " min=0.0 max=6.28 step=0.01 group='Rotation' "); + TwAddVarRW(mBar, "Rot.y", TW_TYPE_FLOAT, &mAngleY, " min=0.0 max=6.28 step=0.01 group='Rotation' "); + TwAddVarRW(mBar, "Rot.z", TW_TYPE_FLOAT, &mAngleZ, " min=0.0 max=6.28 step=0.01 group='Rotation' "); + + mSettings.AddToTweakBar(mBar); + +// mProfiler.AddToTweakBar(mBar); + } +} + +void OBBMeshQuery::Deselect() +{ + if(mBar) + { + TwDeleteBar(mBar); + mBar = null; + } +} + +void OBBMeshQuery::PerformTest() +{ + RenderTerrain(); + + Matrix3x3 MX,MY,MZ; + RotX(MX, mAngleX); + RotY(MY, mAngleY); + RotY(MZ, mAngleZ); + mBox.mRot = MX * MY * MZ; + + DrawOBB(mBox); + + const Model* TM = GetTerrainModel(); + if(TM) + { + OBBCollider Collider; + mSettings.SetupCollider(Collider); + + mProfiler.Start(); + bool Status = Collider.Collide(mCache, mBox, *TM, null, null); + mProfiler.End(); + mProfiler.Accum(); + + if(Status) + { + if(Collider.GetContactStatus()) + { + udword NbTris = Collider.GetNbTouchedPrimitives(); + const udword* Indices = Collider.GetTouchedPrimitives(); + + RenderTerrainTriangles(NbTris, Indices); + } + } + } + + // Raycast hit + if(mValidHit) + { + Point wp = mLocalHit + mBox.mCenter; + DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f); + DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f); + DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f); + } + + char Buffer[4096]; + sprintf(Buffer, "OBB-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles); + GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer); +} + +void OBBMeshQuery::KeyboardCallback(unsigned char key, int x, int y) +{ +} + +void OBBMeshQuery::MouseCallback(int button, int state, int x, int y) +{ + mValidHit = false; + if(!button && !state) + { + Point Dir = ComputeWorldRay(x, y); + + float d; + Point hit; + if(RayOBB(GetCameraPos(), Dir, mBox, d, hit)) + { + mValidHit = true; + mDist = d; + mLocalHit = hit - mBox.mCenter; + } + } +} + +void OBBMeshQuery::MotionCallback(int x, int y) +{ + if(mValidHit) + { + Point Dir = ComputeWorldRay(x, y); + mBox.mCenter = GetCameraPos() + Dir*mDist - mLocalHit; + } +} + + diff --git a/Extras/CDTestFramework/OBBMeshQuery.h b/Extras/CDTestFramework/OBBMeshQuery.h new file mode 100644 index 0000000..e274691 --- /dev/null +++ b/Extras/CDTestFramework/OBBMeshQuery.h @@ -0,0 +1,53 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef OBBMESHQUERY_H +#define OBBMESHQUERY_H + +#include "CollisionTest.h" +#include "Profiling.h" + + class OBBMeshQuery : public CollisionTest + { + public: + OBBMeshQuery(); + virtual ~OBBMeshQuery(); + + virtual void Init(); + virtual void Release(); + virtual void PerformTest(); + virtual void Select(); + virtual void Deselect(); + virtual void KeyboardCallback(unsigned char key, int x, int y); + virtual void MouseCallback(int button, int state, int x, int y); + virtual void MotionCallback(int x, int y); + + TwBar* mBar; //!< AntTweakBar + OBB mBox; + + float mAngleX; + float mAngleY; + float mAngleZ; + + OBBCache mCache; + OpcodeSettings mSettings; + Profiler mProfiler; + + float mDist; + Point mLocalHit; + bool mValidHit; + }; + +#endif // OBBMESHQUERY_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceAABB.cpp b/Extras/CDTestFramework/Opcode/Ice/IceAABB.cpp new file mode 100644 index 0000000..7ea20f2 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceAABB.cpp @@ -0,0 +1,422 @@ +/* + * ICE OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains AABB-related code. + * \file IceAABB.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * AABB class. + * \class AABB + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the sum of two AABBs. + * \param aabb [in] the other AABB + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABB& AABB::Add(const AABB& aabb) +{ + // Compute new min & max values + Point Min; GetMin(Min); + Point Tmp; aabb.GetMin(Tmp); + Min.Min(Tmp); + + Point Max; GetMax(Max); + aabb.GetMax(Tmp); + Max.Max(Tmp); + + // Update this + SetMinMax(Min, Max); + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Makes a cube from the AABB. + * \param cube [out] the cube AABB + * \return cube edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABB::MakeCube(AABB& cube) const +{ + Point Ext; GetExtents(Ext); + float Max = Ext.Max(); + + Point Cnt; GetCenter(Cnt); + cube.SetCenterExtents(Cnt, Point(Max, Max, Max)); + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Makes a sphere from the AABB. + * \param sphere [out] sphere containing the AABB + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABB::MakeSphere(Sphere& sphere) const +{ + GetExtents(sphere.mCenter); + sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds + GetCenter(sphere.mCenter); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks a box is inside another box. + * \param box [in] the other AABB + * \return true if current box is inside input box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABB::IsInside(const AABB& box) const +{ + if(box.GetMin(0)>GetMin(0)) return false; + if(box.GetMin(1)>GetMin(1)) return false; + if(box.GetMin(2)>GetMin(2)) return false; + if(box.GetMax(0) max.x) ? 2 : 0) // 2 = right + + ((local_eye.y < min.y) ? 4 : 0) // 4 = bottom + + ((local_eye.y > max.y) ? 8 : 0) // 8 = top + + ((local_eye.z < min.z) ? 16 : 0) // 16 = front + + ((local_eye.z > max.z) ? 32 : 0); // 32 = back + + // Look up number of vertices in outline + num = (sdword)gIndexList[pos][7]; + // Zero indicates invalid case + if(!num) return null; + + return &gIndexList[pos][0]; +} + +// calculateBoxArea: computes the screen-projected 2D area of an oriented 3D bounding box + +//const Point& eye, //eye point (in bbox object coordinates) +//const AABB& box, //3d bbox +//const Matrix4x4& mat, //free transformation for bbox +//float width, float height, int& num) +float AABB::ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const +{ + const sbyte* Outline = ComputeOutline(eye, num); + if(!Outline) return -1.0f; + + // Compute box vertices + Point vertexBox[8], dst[8]; + ComputePoints(vertexBox); + + // Transform all outline corners into 2D screen space + for(sdword i=0;i max.x) max.x = p.x; + if(p.x < min.x) min.x = p.x; + + if(p.y > max.y) max.y = p.y; + if(p.y < min.y) min.y = p.y; + + if(p.z > max.z) max.z = p.z; + if(p.z < min.z) min.z = p.z; + } + + // Forward declarations + class Sphere; + +//! Declarations of type-independent methods (most of them implemented in the .cpp) +#define AABB_COMMON_METHODS \ + AABB& Add(const AABB& aabb); \ + AABB& Sub(const AABB& aabb); \ + float MakeCube(AABB& cube) const; \ + void MakeSphere(Sphere& sphere) const; \ + const sbyte* ComputeOutline(const Point& local_eye, sdword& num) const; \ + float ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const; \ + bool IsInside(const AABB& box) const; \ + bool ComputePlanes(Plane* planes) const; \ + bool ComputePoints(Point* pts) const; \ + const Point* GetVertexNormals() const; \ + const udword* GetEdges() const; \ + const Point* GetEdgeNormals() const; \ + inline_ BOOL ContainsPoint(const Point& p) const \ + { \ + if(p.x > GetMax(0) || p.x < GetMin(0)) return FALSE; \ + if(p.y > GetMax(1) || p.y < GetMin(1)) return FALSE; \ + if(p.z > GetMax(2) || p.z < GetMin(2)) return FALSE; \ + return TRUE; \ + } + + enum AABBType + { + AABB_RENDER = 0, //!< AABB used for rendering. Not visible == not rendered. + AABB_UPDATE = 1, //!< AABB used for dynamic updates. Not visible == not updated. + + AABB_FORCE_DWORD = 0x7fffffff, + }; + +#ifdef USE_MINMAX + + struct ICEMATHS_API ShadowAABB + { + Point mMin; + Point mMax; + }; + + class ICEMATHS_API AABB : public Allocateable + { + public: + //! Constructor + inline_ AABB() {} + //! Destructor + inline_ ~AABB() {} + + //! Type-independent methods + AABB_COMMON_METHODS; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetMinMax(const Point& min, const Point& max) { mMin = min; mMax = max; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from center & extents vectors. + * \param c [in] the center point + * \param e [in] the extents vector + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetCenterExtents(const Point& c, const Point& e) { mMin = c - e; mMax = c + e; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() { Point p(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); mMin = -p; mMax = p;} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups a point AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetPoint(const Point& pt) { mMin = mMax = pt; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the size of the AABB. The size is defined as the longest extent. + * \return the size of the AABB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + float GetSize() const { Point e; GetExtents(e); return e.Max(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Extends the AABB. + * \param p [in] the next point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Extend(const Point& p) { ComputeMinMax(p, mMin, mMax); } + + // Data access + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mMin; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mMax; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mMin[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mMax[axis]; } + + //! Get box center + inline_ void GetCenter(Point& center) const { center = (mMax + mMin)*0.5f; } + //! Get box extents + inline_ void GetExtents(Point& extents) const { extents = (mMax - mMin)*0.5f; } + + //! Get component of the box's center along a given axis + inline_ float GetCenter(udword axis) const { return (mMax[axis] + mMin[axis])*0.5f; } + //! Get component of the box's extents along a given axis + inline_ float GetExtents(udword axis) const { return (mMax[axis] - mMin[axis])*0.5f; } + + //! Get box diagonal + inline_ void GetDiagonal(Point& diagonal) const { diagonal = mMax - mMin; } + inline_ float GetWidth() const { return mMax.x - mMin.x; } + inline_ float GetHeight() const { return mMax.y - mMin.y; } + inline_ float GetDepth() const { return mMax.z - mMin.z; } + + //! Volume + inline_ float GetVolume() const { return GetWidth() * GetHeight() * GetDepth(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the intersection between two AABBs. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a) const + { + if(mMax.x < a.mMin.x + || a.mMax.x < mMin.x + || mMax.y < a.mMin.y + || a.mMax.y < mMin.y + || mMax.z < a.mMin.z + || a.mMax.z < mMin.z) return FALSE; + + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the 1D-intersection between two AABBs, on a given axis. + * \param a [in] the other AABB + * \param axis [in] the axis (0, 1, 2) + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a, udword axis) const + { + if(mMax[axis] < a.mMin[axis] || a.mMax[axis] < mMin[axis]) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. + * Original code by Charles Bloom on the GD-Algorithm list. (I slightly modified it) + * \param mtx [in] the transform matrix + * \param aabb [out] the transformed AABB [can be *this] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const + { + // The three edges transformed: you can efficiently transform an X-only vector + // by just getting the "X" column of the matrix + Point vx,vy,vz; + mtx.GetRow(0, vx); vx *= (mMax.x - mMin.x); + mtx.GetRow(1, vy); vy *= (mMax.y - mMin.y); + mtx.GetRow(2, vz); vz *= (mMax.z - mMin.z); + + // Transform the min point + aabb.mMin = aabb.mMax = mMin * mtx; + + // Take the transformed min & axes and find new extents + // Using CPU code in the right place is faster... + if(IS_NEGATIVE_FLOAT(vx.x)) aabb.mMin.x += vx.x; else aabb.mMax.x += vx.x; + if(IS_NEGATIVE_FLOAT(vx.y)) aabb.mMin.y += vx.y; else aabb.mMax.y += vx.y; + if(IS_NEGATIVE_FLOAT(vx.z)) aabb.mMin.z += vx.z; else aabb.mMax.z += vx.z; + if(IS_NEGATIVE_FLOAT(vy.x)) aabb.mMin.x += vy.x; else aabb.mMax.x += vy.x; + if(IS_NEGATIVE_FLOAT(vy.y)) aabb.mMin.y += vy.y; else aabb.mMax.y += vy.y; + if(IS_NEGATIVE_FLOAT(vy.z)) aabb.mMin.z += vy.z; else aabb.mMax.z += vy.z; + if(IS_NEGATIVE_FLOAT(vz.x)) aabb.mMin.x += vz.x; else aabb.mMax.x += vz.x; + if(IS_NEGATIVE_FLOAT(vz.y)) aabb.mMin.y += vz.y; else aabb.mMax.y += vz.y; + if(IS_NEGATIVE_FLOAT(vz.z)) aabb.mMin.z += vz.z; else aabb.mMax.z += vz.z; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the AABB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Min, Max) boxes: min < max + if(mMin.x > mMax.x) return FALSE; + if(mMin.y > mMax.y) return FALSE; + if(mMin.z > mMax.z) return FALSE; + return TRUE; + } + + //! Operator for AABB *= float. Scales the extents, keeps same center. + inline_ AABB& operator*=(float s) + { + Point Center; GetCenter(Center); + Point Extents; GetExtents(Extents); + SetCenterExtents(Center, Extents * s); + return *this; + } + + //! Operator for AABB /= float. Scales the extents, keeps same center. + inline_ AABB& operator/=(float s) + { + Point Center; GetCenter(Center); + Point Extents; GetExtents(Extents); + SetCenterExtents(Center, Extents / s); + return *this; + } + + //! Operator for AABB += Point. Translates the box. + inline_ AABB& operator+=(const Point& trans) + { + mMin+=trans; + mMax+=trans; + return *this; + } + private: + Point mMin; //!< Min point + Point mMax; //!< Max point + }; + +#else + + class ICEMATHS_API AABB + { + public: + //! Constructor + inline_ AABB() {} + //! Destructor + inline_ ~AABB() {} + + //! Type-independent methods + AABB_COMMON_METHODS; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from center & extents vectors. + * \param c [in] the center point + * \param e [in] the extents vector + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetCenterExtents(const Point& c, const Point& e) { mCenter = c; mExtents = e; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups a point AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetPoint(const Point& pt) { mCenter = pt; mExtents.Zero(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the size of the AABB. The size is defined as the longest extent. + * \return the size of the AABB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + float GetSize() const { return mExtents.Max(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Extends the AABB. + * \param p [in] the next point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Extend(const Point& p) + { + Point Max = mCenter + mExtents; + Point Min = mCenter - mExtents; + + if(p.x > Max.x) Max.x = p.x; + if(p.x < Min.x) Min.x = p.x; + + if(p.y > Max.y) Max.y = p.y; + if(p.y < Min.y) Min.y = p.y; + + if(p.z > Max.z) Max.z = p.z; + if(p.z < Min.z) Min.z = p.z; + + SetMinMax(Min, Max); + } + // Data access + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } + + //! Get box center + inline_ void GetCenter(Point& center) const { center = mCenter; } + //! Get box extents + inline_ void GetExtents(Point& extents) const { extents = mExtents; } + + //! Get component of the box's center along a given axis + inline_ float GetCenter(udword axis) const { return mCenter[axis]; } + //! Get component of the box's extents along a given axis + inline_ float GetExtents(udword axis) const { return mExtents[axis]; } + + //! Get box diagonal + inline_ void GetDiagonal(Point& diagonal) const { diagonal = mExtents * 2.0f; } + inline_ float GetWidth() const { return mExtents.x * 2.0f; } + inline_ float GetHeight() const { return mExtents.y * 2.0f; } + inline_ float GetDepth() const { return mExtents.z * 2.0f; } + + //! Volume + inline_ float GetVolume() const { return mExtents.x * mExtents.y * mExtents.z * 8.0f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the intersection between two AABBs. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a) const + { + float tx = mCenter.x - a.mCenter.x; float ex = a.mExtents.x + mExtents.x; if(AIR(tx) > IR(ex)) return FALSE; + float ty = mCenter.y - a.mCenter.y; float ey = a.mExtents.y + mExtents.y; if(AIR(ty) > IR(ey)) return FALSE; + float tz = mCenter.z - a.mCenter.z; float ez = a.mExtents.z + mExtents.z; if(AIR(tz) > IR(ez)) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * The standard intersection method from Gamasutra. Just here to check its speed against the one above. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool GomezIntersect(const AABB& a) + { + Point T = mCenter - a.mCenter; // Vector from A to B + return ((fabsf(T.x) <= (a.mExtents.x + mExtents.x)) + && (fabsf(T.y) <= (a.mExtents.y + mExtents.y)) + && (fabsf(T.z) <= (a.mExtents.z + mExtents.z))); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the 1D-intersection between two AABBs, on a given axis. + * \param a [in] the other AABB + * \param axis [in] the axis (0, 1, 2) + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a, udword axis) const + { + float t = mCenter[axis] - a.mCenter[axis]; + float e = a.mExtents[axis] + mExtents[axis]; + if(AIR(t) > IR(e)) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. + * \param mtx [in] the transform matrix + * \param aabb [out] the transformed AABB [can be *this] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const + { + // Compute new center + aabb.mCenter = mCenter * mtx; + + // Compute new extents. FPU code & CPU code have been interleaved for improved performance. + Point Ex(mtx.m[0][0] * mExtents.x, mtx.m[0][1] * mExtents.x, mtx.m[0][2] * mExtents.x); + IR(Ex.x)&=0x7fffffff; IR(Ex.y)&=0x7fffffff; IR(Ex.z)&=0x7fffffff; + + Point Ey(mtx.m[1][0] * mExtents.y, mtx.m[1][1] * mExtents.y, mtx.m[1][2] * mExtents.y); + IR(Ey.x)&=0x7fffffff; IR(Ey.y)&=0x7fffffff; IR(Ey.z)&=0x7fffffff; + + Point Ez(mtx.m[2][0] * mExtents.z, mtx.m[2][1] * mExtents.z, mtx.m[2][2] * mExtents.z); + IR(Ez.x)&=0x7fffffff; IR(Ez.y)&=0x7fffffff; IR(Ez.z)&=0x7fffffff; + + aabb.mExtents.x = Ex.x + Ey.x + Ez.x; + aabb.mExtents.y = Ex.y + Ey.y + Ez.y; + aabb.mExtents.z = Ex.z + Ey.z + Ez.z; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the AABB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Center, Extents) boxes: Extents >= 0 + if(IS_NEGATIVE_FLOAT(mExtents.x)) return FALSE; + if(IS_NEGATIVE_FLOAT(mExtents.y)) return FALSE; + if(IS_NEGATIVE_FLOAT(mExtents.z)) return FALSE; + return TRUE; + } + + //! Operator for AABB *= float. Scales the extents, keeps same center. + inline_ AABB& operator*=(float s) { mExtents*=s; return *this; } + + //! Operator for AABB /= float. Scales the extents, keeps same center. + inline_ AABB& operator/=(float s) { mExtents/=s; return *this; } + + //! Operator for AABB += Point. Translates the box. + inline_ AABB& operator+=(const Point& trans) + { + mCenter+=trans; + return *this; + } + private: + Point mCenter; //!< AABB Center + Point mExtents; //!< x, y and z extents + }; + +#endif + + //! Computes the AABB around a set of vertices + inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts) + { + if(list) + { + Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT); + while(nb_pts--) + { +// _prefetch(list+1); // off by one ? + ComputeMinMax(*list++, Mini, Maxi); + } + aabb.SetMinMax(Mini, Maxi); + } + } + + //! Computes the AABB around a set of vertices after transform by a matrix + inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts, const Matrix4x4& world) + { + if(list) + { + Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT); + while(nb_pts--) + { +// _prefetch(list+1); // off by one ? + ComputeMinMax((*list++)*world, Mini, Maxi); + } + aabb.SetMinMax(Mini, Maxi); + } + } + +#endif // ICEAABB_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceAllocator.cpp b/Extras/CDTestFramework/Opcode/Ice/IceAllocator.cpp new file mode 100644 index 0000000..2b8abe8 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceAllocator.cpp @@ -0,0 +1,805 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an allocator base class. + * \file IceAllocator.cpp + * \author Pierre Terdiman + * \date December, 19, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "StdAfx.h" +#include + +using namespace Opcode; + +//#define ZERO_OVERHEAD_RELEASE +#define NEW_CODE +// For some reason dmalloc seems a lot slower than the system malloc? +//#define USE_DMALLOC + +#ifdef USE_DMALLOC + #include "dmalloc.h" + #define LOCAL_MALLOC dlmalloc + #define LOCAL_FREE dlfree +#else + #define LOCAL_MALLOC ::malloc + #define LOCAL_FREE ::free +#endif + + +// WARNING: this makes allocations a lot slower. Only use when tracking memory leaks. +//#define ALLOC_STRINGS + +// ### doesn't seem that useful +//#define FAST_BUFFER_SIZE 256*1024 + +#define DEBUG_IDENTIFIER 0xBeefBabe +#define DEBUG_DEALLOCATED 0xDeadDead + +#ifdef ALLOC_STRINGS +static const char* AllocString(const char* str) +{ + if(!str) return null; + char* mem = (char*)LOCAL_MALLOC(strlen(str)+1); + strcpy(mem, str); + return mem; +} + +static void FreeString(const char* str) +{ + if(str) LOCAL_FREE((void*)str); +} + +#endif + + class DefaultAllocator : public Allocator + { + public: + DefaultAllocator(); + virtual ~DefaultAllocator(); + + void reset(); + + override(Allocator) void* malloc(size_t size, MemoryType type); + override(Allocator) void* mallocDebug(size_t size, const char* filename, udword line, const char* class_name, MemoryType type); + override(Allocator) void* realloc(void* memory, size_t size); + override(Allocator) void* shrink(void* memory, size_t size); + override(Allocator) void free(void* memory); + + void DumpCurrentMemoryState() const; + + void** mMemBlockList; + udword mMemBlockListSize; +#ifdef NEW_CODE + udword mFirstFree; +#else + udword mMemBlockFirstFree; +#endif + udword mMemBlockUsed; + + sdword mNbAllocatedBytes; + sdword mHighWaterMark; + sdword mTotalNbAllocs; + sdword mNbAllocs; + sdword mNbReallocs; +#ifdef FAST_BUFFER_SIZE + udword mNbFastBytes; + udword mFastBufferOffset; + ubyte* mFastBuffer; +#endif + }; + +#define MEMBLOCKSTART 64 + + struct DebugBlock + { + udword mCheckValue; +#ifdef FAST_BUFFER_SIZE + MemoryType mType; +#endif + udword mSize; + const char* mFilename; + udword mLine; + udword mSlotIndex; + const char* mClassName; + }; + +#ifndef FAST_BUFFER_SIZE + ICE_COMPILE_TIME_ASSERT(sizeof(DebugBlock)==24); // Prevents surprises..... +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +DefaultAllocator::DefaultAllocator() : mNbAllocatedBytes(0), mHighWaterMark(0), mTotalNbAllocs(0), mNbAllocs(0), mNbReallocs(0) +{ + mMemBlockList = null; + +#ifdef _DEBUG + // Initialize the Memory blocks list (DEBUG mode only) + mMemBlockList = (void**)LOCAL_MALLOC(MEMBLOCKSTART*sizeof(void*)); + ZeroMemory(mMemBlockList, MEMBLOCKSTART*sizeof(void*)); + mMemBlockListSize = MEMBLOCKSTART; +#ifdef NEW_CODE + mFirstFree = INVALID_ID; +#else + mMemBlockFirstFree = 0; +#endif + mMemBlockUsed = 0; +#endif + + +#ifdef FAST_BUFFER_SIZE + mNbFastBytes = 0; + mFastBufferOffset = 0; + mFastBuffer = (ubyte*)LOCAL_MALLOC(FAST_BUFFER_SIZE); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +DefaultAllocator::~DefaultAllocator() +{ +#ifdef FAST_BUFFER_SIZE + mNbFastBytes = 0; + mFastBufferOffset = 0; + if(mFastBuffer) LOCAL_FREE(mFastBuffer); + mFastBuffer = null; +#endif + +#ifdef _DEBUG + + // Ok, it is a bad idea to use _F() here, because it internally uses the allocator (for the log string). So let's use good old C style here. + char Buffer[4096]; + + if(mNbAllocatedBytes) + { + sprintf(Buffer, "Memory leak detected: %d bytes non released\n", mNbAllocatedBytes); +// IceTrace(Buffer); +// IceTrace(_F("Memory leak detected: %d bytes non released\n", mNbAllocatedBytes)); + } + if(mNbAllocs) + { + sprintf(Buffer, "Remaining allocs: %d\n", mNbAllocs); +// IceTrace(Buffer); +// IceTrace(_F("Remaining allocs: %d\n", mNbAllocs)); + } +// IceTrace(_F("Nb alloc: %d\n", mTotalNbAllocs)); + sprintf(Buffer, "Total nb alloc: %d\n", mTotalNbAllocs); +// IceTrace(Buffer); + +// IceTrace(_F("Nb realloc: %d\n", mNbReallocs)); + sprintf(Buffer, "Nb realloc: %d\n", mNbReallocs); +// IceTrace(Buffer); + +// IceTrace(_F("High water mark: %d Kb\n", mHighWaterMark/1024)); + sprintf(Buffer, "High water mark: %d Kb\n", mHighWaterMark/1024); +// IceTrace(Buffer); + + // Scanning for memory leaks + if(mMemBlockList && mNbAllocs) + { + udword NbLeaks = 0; +// IceTrace("\n\n ICE Message Memory leaks detected :\n\n"); + +#ifdef NEW_CODE + for(udword i=0; imSize, DB->mClassName, DB->mFilename, DB->mLine)); + sprintf(Buffer, " Address 0x%.8X, %d bytes (%s), allocated in: %s(%d):\n\n", DB+1, DB->mSize, DB->mClassName, DB->mFilename, DB->mLine); +// IceTrace(Buffer); + + NbLeaks++; +// Free(cur+4); + } +#else + for(udword i=0, j=0; imSize, DB->mClassName, DB->mFilename, DB->mLine)); + sprintf(Buffer, " Address 0x%.8X, %d bytes (%s), allocated in: %s(%d):\n\n", DB+1, DB->mSize, DB->mClassName, DB->mFilename, DB->mLine); + IceTrace(Buffer); + + NbLeaks++; +// Free(cur+4); + } +#endif +// IceTrace(_F("\n Dump complete (%d leaks)\n\n", NbLeaks)); + sprintf(Buffer, "\n Dump complete (%d leaks)\n\n", NbLeaks); +// IceTrace(Buffer); + } + // Free the Memory Block list + if(mMemBlockList) LOCAL_FREE(mMemBlockList); + mMemBlockList = null; +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void DefaultAllocator::reset() +{ + mNbAllocatedBytes = 0; + mHighWaterMark = 0; + mNbAllocs = 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void* DefaultAllocator::malloc(udword size, MemoryType type) +{ +// return ::malloc(size); + +#ifdef _DEBUG + return mallocDebug(size, null, 0, "Undefined", type); +#endif + + if(!size) + { +#ifdef _DEBUG +// IceTrace("Warning: trying to allocate 0 bytes\n"); +#endif + return null; + } + + mTotalNbAllocs++; + mNbAllocs++; + + mNbAllocatedBytes+=size; + if(mNbAllocatedBytes>mHighWaterMark) mHighWaterMark = mNbAllocatedBytes; + +#ifdef ZERO_OVERHEAD_RELEASE + return LOCAL_MALLOC(size); +#else + void* ptr = (void*)LOCAL_MALLOC(size+8); + udword* blockStart = (udword*)ptr; + blockStart[0] = DEBUG_IDENTIFIER; + blockStart[1] = size; + return ((udword*)ptr)+2; +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void* DefaultAllocator::mallocDebug(size_t size, const char* filename, udword line, const char* class_name, MemoryType type) +{ +#ifdef _DEBUG + if(!size) + { +// IceTrace("Warning: trying to allocate 0 bytes\n"); + return null; + } + + // Catch improper use of alloc macro... + if(0 && class_name) + { + const char* c = class_name; + while(*c) + { + if(*c==']' || *c=='[') + { + int stop=0; + } + c++; + } + } + + // Make sure size is even + if(size&1) size++; + +#ifdef FAST_BUFFER_SIZE + // Allocate one debug block in front of each real allocation + void* ptr = null; + if(type==MEMORY_TEMP) + { + udword NeededSize = size + sizeof(DebugBlock); + if(mFastBufferOffset + NeededSize <= FAST_BUFFER_SIZE) + { + ptr = mFastBuffer + mFastBufferOffset; + mFastBufferOffset += NeededSize; + mNbFastBytes += NeededSize; + } + } + + if(!ptr) + { + ptr = (void*)LOCAL_MALLOC(size + sizeof(DebugBlock)); + type = MEMORY_PERSISTENT; + } +#else + // Allocate one debug block in front of each real allocation + void* ptr = (void*)LOCAL_MALLOC(size + sizeof(DebugBlock)); +#endif + ASSERT(IS_ALIGNED_2(udword(ptr))); + + // Fill debug block + DebugBlock* DB = (DebugBlock*)ptr; + DB->mCheckValue = DEBUG_IDENTIFIER; +#ifdef FAST_BUFFER_SIZE + DB->mType = type; +#endif + DB->mSize = size; + DB->mLine = line; + DB->mSlotIndex = INVALID_ID; +#ifdef ALLOC_STRINGS + DB->mFilename = AllocString(filename); + DB->mClassName = AllocString(class_name); +#else + DB->mFilename = filename; + DB->mClassName = class_name; +#endif + + // Update global stats + mTotalNbAllocs++; + mNbAllocs++; + mNbAllocatedBytes += size; + if(mNbAllocatedBytes>mHighWaterMark) + mHighWaterMark = mNbAllocatedBytes; + + // Insert the allocated block in the debug memory block list + if(mMemBlockList) + { +#ifdef NEW_CODE + if(mFirstFree!=INVALID_ID) + { + // Recycle old location + + udword NextFree = udword(mMemBlockList[mFirstFree]); + if(NextFree!=INVALID_ID) NextFree>>=1; + + mMemBlockList[mFirstFree] = ptr; + DB->mSlotIndex = mFirstFree; + + mFirstFree = NextFree; + } + else + { + if(mMemBlockUsed==mMemBlockListSize) + { + // Allocate a bigger block + void** tps = (void**)LOCAL_MALLOC((mMemBlockListSize+MEMBLOCKSTART)*sizeof(void*)); + // Copy already used part + CopyMemory(tps, mMemBlockList, mMemBlockListSize*sizeof(void*)); + // Initialize remaining part + void* Next = tps + mMemBlockListSize; + ZeroMemory(Next, MEMBLOCKSTART*sizeof(void*)); + + // Free previous memory, setup new pointer + LOCAL_FREE(mMemBlockList); + mMemBlockList = tps; + // Setup new size + mMemBlockListSize += MEMBLOCKSTART; + } + + mMemBlockList[mMemBlockUsed] = ptr; + DB->mSlotIndex = mMemBlockUsed++; + } +#else + // Store allocated pointer in first free slot + mMemBlockList[mMemBlockFirstFree] = ptr; + DB->mSlotIndex = mMemBlockFirstFree; + + // Count number of used slots + mMemBlockUsed++; + + // Resize if needed + if(mMemBlockUsed==mMemBlockListSize) + { + // Allocate a bigger block + void** tps = (void**)LOCAL_MALLOC((mMemBlockListSize+MEMBLOCKSTART)*sizeof(void*)); + // Copy already used part + CopyMemory(tps, mMemBlockList, mMemBlockListSize*sizeof(void*)); + // Initialize remaining part + void* Next = tps + mMemBlockListSize; + ZeroMemory(Next, MEMBLOCKSTART*sizeof(void*)); + + // Free previous memory, setup new pointer + LOCAL_FREE(mMemBlockList); + mMemBlockList = tps; + // -1 because we'll do a ++ just afterwards + mMemBlockFirstFree = mMemBlockListSize-1; + // Setup new size + mMemBlockListSize += MEMBLOCKSTART; + } + + // Look for first free ### recode this ugly thing + while(mMemBlockList[++mMemBlockFirstFree] && (mMemBlockFirstFreemCheckValue!=DEBUG_IDENTIFIER) + { + // Not a valid memory block + return null; + } + if(size>DB->mSize) + { + // New size should be smaller! + return null; + } + + // Try to shrink the block + void* Reduced = _expand(SystemPointer, size + sizeof(DebugBlock)); + if(!Reduced) return null; + + if(Reduced!=SystemPointer) + { + // Should not be possible?! + } + + // Update stats + mNbAllocatedBytes -= DB->mSize; + mNbAllocatedBytes += size; + // Setup new size + DB->mSize = size; + + return memory; // The pointer should not have changed! +#else + // Release codepath + udword* SystemPointer = ((udword*)memory)-2; + if(SystemPointer[0]!=DEBUG_IDENTIFIER) + { + // Not a valid memory block + return null; + } + if(size>SystemPointer[1]) + { + // New size should be smaller! + return null; + } + + // Try to shrink the block + void* Reduced = _expand(SystemPointer, size+8); + if(!Reduced) return null; + + if(Reduced!=SystemPointer) + { + // Should not be possible?! + } + + // Update stats + mNbAllocatedBytes -= SystemPointer[1]; + mNbAllocatedBytes += size; + // Setup new size + SystemPointer[1] = size; + + return memory; // The pointer should not have changed! +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void* DefaultAllocator::realloc(void* memory, udword size) +{ +// return ::realloc(memory, size); + + ASSERT(0); + return null; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void DefaultAllocator::free(void* memory) +{ + if(!memory) + { +#ifdef _DEBUG +// IceTrace("Warning: trying to free null pointer\n"); +#endif + return; + } + +#ifdef _DEBUG + DebugBlock* DB = ((DebugBlock*)memory)-1; + +// DebugBlock TmpDB = *DB; // Keep a local copy to have readable data when ::free() fails! + + // Check we allocated it + if(DB->mCheckValue!=DEBUG_IDENTIFIER) + { +// IceTrace("Error: free unknown memory!!\n"); + // ### should we really continue?? + return; + } + + // Update global stats + mNbAllocatedBytes -= DB->mSize; + mNbAllocs--; + +#ifdef NEW_CODE + // Remove the block from the Memory block list + if(mMemBlockList) + { + udword FreeSlot = DB->mSlotIndex; + ASSERT(mMemBlockList[FreeSlot]==DB); + + udword NextFree = mFirstFree; + if(NextFree!=INVALID_ID) + { + NextFree<<=1; + NextFree|=1; + } + + mMemBlockList[FreeSlot] = (void*)NextFree; + mFirstFree = FreeSlot; + } +#else + udword MemBlockFirstFree = DB->mSlotIndex; // The slot we are in + udword Line = DB->mLine; + const char* File = DB->mFilename; + + // Remove the block from the Memory block list + if(mMemBlockList) + { + ASSERT(mMemBlockList[MemBlockFirstFree]==DB); + mMemBlockList[MemBlockFirstFree] = null; + mMemBlockUsed--; + } +#endif + +#ifdef ALLOC_STRINGS + FreeString(DB->mClassName); + FreeString(DB->mFilename); +#endif + +#ifdef FAST_BUFFER_SIZE + if(DB->mType==MEMORY_TEMP) + { + mNbFastBytes -= DB->mSize + sizeof(DebugBlock); + if(mNbFastBytes==0) + { + mFastBufferOffset = 0; + } + return; + } +#endif + + // ### should be useless since we'll release the memory just afterwards + DB->mCheckValue = DEBUG_DEALLOCATED; + DB->mSize = 0; + DB->mClassName = null; + DB->mFilename = null; + DB->mSlotIndex = INVALID_ID; + DB->mLine = INVALID_ID; + + LOCAL_FREE(DB); +#else + // Release codepath + #ifdef ZERO_OVERHEAD_RELEASE + +// mNbAllocatedBytes -= ptr[1]; // ### use _msize() ? + mNbAllocs--; + LOCAL_FREE(memory); + + #else + + udword* ptr = ((udword*)memory)-2; + if(ptr[0]!=DEBUG_IDENTIFIER) + { + #ifdef _DEBUG + IceTrace("Error: free unknown memory!!\n"); + #endif + } + mNbAllocatedBytes -= ptr[1]; + if(mNbAllocatedBytes<0) + { + #ifdef _DEBUG + IceTrace(_F("Oops (%d)\n", ptr[1])); + #endif + } + mNbAllocs--; + ptr[0]=DEBUG_DEALLOCATED; + ptr[1]=0; + LOCAL_FREE(ptr); + + #endif +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline_ bool ValidAddress(const void* addy) +{ +#ifdef NEW_CODE + return (addy && !(udword(addy)&1)); +#else + return addy!=null; +#endif +} + +void DefaultAllocator::DumpCurrentMemoryState() const +{ +#ifdef _DEBUG + // Scanning for memory leaks + if(mMemBlockList && mMemBlockUsed) + { +// IceTrace("\n\n----ALLOCATOR MEMORY DUMP:\n\n"); + + // We can't just use the "const char*" stored in the debug blocks because they're not guaranteed to + // be unique for similar strings. For example if a Container is allocated from two different DLLs, + // the "Container" character string will be duplicated (one per DLL). So we need to group similar + // strings together using the actual characters, not just the string address. We also have to do this + // without allocating any new memory, since it would add new entries to the memory debug structure. + // + // The good news is that we don't care about speed too much in this function, since it's not supposed + // to be called all the time. + + struct Local + { + struct TmpStruct + { + const char* mName; + udword mSize; + }; + static int SortCB(const void* elem1, const void* elem2) + { + const TmpStruct* s1 = (const TmpStruct*)elem1; + const TmpStruct* s2 = (const TmpStruct*)elem2; + return strcmp(s1->mName, s2->mName); + } + }; + + Local::TmpStruct* SortedStrings = (Local::TmpStruct*)LOCAL_MALLOC(sizeof(Local::TmpStruct)*mMemBlockListSize); + udword NbStrings = 0; + udword TotalSize = 0; + for(udword i=0;imClassName) + { + SortedStrings[NbStrings].mName = DB->mClassName; // Memory by class +// SortedStrings[NbStrings].mName = DB->mFilename; // Memory by file + SortedStrings[NbStrings].mSize = DB->mSize; + TotalSize += DB->mSize; + NbStrings++; + } + } + } + qsort(SortedStrings, NbStrings, sizeof(Local::TmpStruct), Local::SortCB); + + // Strings are now sorted. They might still be duplicated, i.e. we may have two strings for the same + // class. So now we parse the list and collect used memory for all classes. Then we sort this again, + // to report results in order of increasing memory. + + udword NbClasses=0; + udword* Classes = (udword*)LOCAL_MALLOC(sizeof(udword)*NbStrings); + udword* Sizes = (udword*)LOCAL_MALLOC(sizeof(udword)*NbStrings); + + udword CurrentSize = SortedStrings[0].mSize; + const char* CurrentClass = SortedStrings[0].mName; + for(udword i=1;i<=NbStrings;i++) // One more time on purpose + { + const char* Current = null; + if(i!=NbStrings) + { + Current = SortedStrings[i].mName; + } + + if(Current && strcmp(Current, CurrentClass)==0) + { + // Same class + CurrentSize += SortedStrings[i].mSize; + } + else + { + // New class + + // Store previous class + if(CurrentClass) + { + Classes[NbClasses] = (udword)CurrentClass; // We can store this pointer now because it's unique in our new array + Sizes[NbClasses++] = CurrentSize; + } + + // Next one + if(Current) + { + CurrentClass = Current; + CurrentSize = SortedStrings[i].mSize; + } + } + } + + udword* Ranks0 = (udword*)LOCAL_MALLOC(sizeof(udword)*NbClasses); + udword* Ranks1 = (udword*)LOCAL_MALLOC(sizeof(udword)*NbClasses); + + StackRadixSort(RS, Ranks0, Ranks1); + const udword* Sorted = RS.Sort(Sizes, NbClasses).GetRanks(); + for(udword i=0;iDumpCurrentMemoryState(); +} + +void InitDefaultAllocator() +{ +// gDefault = ::new DefaultAllocator; +} + +void ReleaseDefaultAllocator() +{ +// if(gDefault) ::delete gDefault; +// gDefault = null; +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceAllocator.h b/Extras/CDTestFramework/Opcode/Ice/IceAllocator.h new file mode 100644 index 0000000..694d542 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceAllocator.h @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an allocator base class. + * \file IceAllocator.h + * \author Pierre Terdiman + * \date December, 19, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef ICEALLOCATOR_H +#define ICEALLOCATOR_H + + enum MemoryType + { + MEMORY_PERSISTENT, + MEMORY_TEMP, + }; + + class ICECORE_API Allocator + { + public: + virtual void* malloc(size_t size, MemoryType type) = 0; + virtual void* mallocDebug(size_t size, const char* filename, udword line, const char* class_name, MemoryType type) = 0; + virtual void* realloc(void* memory, size_t size) = 0; + virtual void* shrink(void* memory, size_t size) = 0; + virtual void free(void* memory) = 0; + }; + + FUNCTION ICECORE_API Allocator* GetAllocator(); + FUNCTION ICECORE_API bool SetAllocator(Allocator& allocator); + FUNCTION ICECORE_API void DumpMemory(); + + class ICECORE_API Allocateable + { + public: +#ifdef DONT_TRACK_MEMORY_LEAKS + inline_ void* operator new (size_t size, MemoryType type) { return GetAllocator()->malloc(size, type); } + inline_ void* operator new (size_t size, const char * filename, int line, const char* class_name, MemoryType type) { return GetAllocator()->mallocDebug(size, filename, line, class_name, type); } + inline_ void* operator new[] (size_t size, MemoryType type) { return GetAllocator()->malloc(size, type); } + inline_ void* operator new[] (size_t size, const char * filename, int line, const char* class_name, MemoryType type) { return GetAllocator()->mallocDebug(size, filename, line, class_name, type); } + inline_ void operator delete (void* p) { GetAllocator()->free(p); } + inline_ void operator delete (void* p, MemoryType) { GetAllocator()->free(p); } + inline_ void operator delete (void* p, const char*, int, const char*, MemoryType) { GetAllocator()->free(p); } + inline_ void operator delete[] (void* p) { GetAllocator()->free(p); } + inline_ void operator delete[] (void* p, MemoryType) { GetAllocator()->free(p); } + inline_ void operator delete[] (void* p, const char*, int, const char*, MemoryType) { GetAllocator()->free(p); } +#endif + }; + +#endif // ICEALLOCATOR_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceAssert.h b/Extras/CDTestFramework/Opcode/Ice/IceAssert.h new file mode 100644 index 0000000..386ec13 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceAssert.h @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains custom assertion code. + * \file IceAssert.h + * \author Pierre Terdiman + * \date January, 14, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef ICEASSERT_H +#define ICEASSERT_H + +// Leave the {} so that you can write this kind of things safely in release mode: +// if(condition) ASSERT() + +#ifndef ASSERT + #if defined( _DEBUG ) + FUNCTION ICECORE_API bool CustomAssertFunction(int, char*, int, char*, bool&); + + //! Custom ASSERT function. Various usages: + //! ASSERT(condition) + //! ASSERT(!"Not implemented") + //! ASSERT(condition && "error text") + #define ASSERT(exp) \ + { \ + static bool IgnoreAlways = false; \ + if(!IgnoreAlways) \ + { \ + if(CustomAssertFunction((int)(exp), #exp, __LINE__, __FILE__, IgnoreAlways)) \ + { \ + _asm { int 3 } \ + } \ + } \ + } + #else + #define ASSERT(exp) {} + #endif +#endif + +#ifndef assert + #define assert ASSERT +#endif + + #define ICE_COMPILE_TIME_ASSERT(exp) extern char ICE_Dummy[ (exp) ? 1 : -1 ] + +#endif // ICEASSERT_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceAxes.h b/Extras/CDTestFramework/Opcode/Ice/IceAxes.h new file mode 100644 index 0000000..37032dc --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceAxes.h @@ -0,0 +1,70 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains axes definition. + * \file IceAxes.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEAXES_H__ +#define __ICEAXES_H__ + + enum PointComponent + { + _X = 0, + _Y = 1, + _Z = 2, + _W = 3, + + _FORCE_DWORD = 0x7fffffff + }; + + enum AxisOrder + { + AXES_XYZ = (_X)|(_Y<<2)|(_Z<<4), + AXES_XZY = (_X)|(_Z<<2)|(_Y<<4), + AXES_YXZ = (_Y)|(_X<<2)|(_Z<<4), + AXES_YZX = (_Y)|(_Z<<2)|(_X<<4), + AXES_ZXY = (_Z)|(_X<<2)|(_Y<<4), + AXES_ZYX = (_Z)|(_Y<<2)|(_X<<4), + + AXES_FORCE_DWORD = 0x7fffffff + }; + + class ICEMATHS_API Axes + { + public: + + inline_ Axes(AxisOrder order) + { + mAxis0 = (order ) & 3; + mAxis1 = (order>>2) & 3; + mAxis2 = (order>>4) & 3; + } + inline_ ~Axes() {} + + udword mAxis0; + udword mAxis1; + udword mAxis2; + }; + +#endif // __ICEAXES_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceBitArray.cpp b/Extras/CDTestFramework/Opcode/Ice/IceBitArray.cpp new file mode 100644 index 0000000..1ec64c3 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceBitArray.cpp @@ -0,0 +1,73 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for bit arrays. + * \file IceBitArray.cpp + * \author Pierre Terdiman + * \date February, 5, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A simple array of bits stored as bytes. + * + * \class Container + * \author Pierre Terdiman + * \version 1.0 + * \date February, 5, 2000 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "StdAfx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BitArray::BitArray() : mSize(0), mBits(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BitArray::BitArray(udword nb_bits) : mSize(0), mBits(null) +{ + Init(nb_bits); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BitArray::~BitArray() +{ + ICE_FREE(mBits); + mSize = 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes the bit array for a given number of entries + * \param nb_bits [in] max number of entries in the array + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BitArray::Init(udword nb_bits) +{ + mSize = BitsToDwords(nb_bits); + // Get ram for n bits + ICE_FREE(mBits); + mBits = (udword*)ICE_ALLOC(sizeof(udword)*mSize); + // Set all bits to 0 + ClearAll(); + return true; +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceBitArray.h b/Extras/CDTestFramework/Opcode/Ice/IceBitArray.h new file mode 100644 index 0000000..60c60be --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceBitArray.h @@ -0,0 +1,82 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for bit arrays. + * \file IceBitArray.h + * \author Pierre Terdiman + * \date February, 5, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef ICEBITARRAY_H +#define ICEBITARRAY_H + + inline_ udword BitsToBytes(udword nb_bits) + { + return (nb_bits>>3) + ((nb_bits&7) ? 1 : 0); + } + + inline_ udword BitsToDwords(udword nb_bits) + { + return (nb_bits>>5) + ((nb_bits&31) ? 1 : 0); + } + + // Use that one instead of an array of bools. Takes less ram, nearly as fast [no bounds checkings and so on]. + class ICECORE_API BitArray + { + public: + //! Constructor + BitArray(); + BitArray(udword nb_bits); + //! Destructor + ~BitArray(); + + bool Init(udword nb_bits); + + // Data management + inline_ void SetBit(udword bit_number) { mBits[bit_number>>5] |= 1<<(bit_number&31); } + inline_ void ClearBit(udword bit_number) { mBits[bit_number>>5] &= ~(1<<(bit_number&31)); } + inline_ void ToggleBit(udword bit_number) { mBits[bit_number>>5] ^= 1<<(bit_number&31); } + + inline_ void ClearAll() { ZeroMemory(mBits, mSize*4); } + inline_ void SetAll() { FillMemory(mBits, mSize*4, 0xff); } + + // Data access + inline_ BOOL IsSet(udword bit_number) const { return mBits[bit_number>>5] & (1<<(bit_number&31)); } + + inline_ const udword* GetBits() const { return mBits; } + inline_ udword GetSize() const { return mSize; } + + protected: + udword* mBits; //!< Array of bits + udword mSize; //!< Size of the array in dwords + }; + + // - We consider square symmetric N*N matrices + // - A N*N symmetric matrix has N(N+1)/2 elements + // - A boolean version needs N(N+1)/16 bytes + // N NbBits NbBytes + // 4 10 - + // 8 36 4.5 + // 16 136 17 <= the one we select + // 32 528 66 + static ubyte BitMasks[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; + static ubyte NegBitMasks[] = { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F }; + class ICECORE_API BoolSquareSymmetricMatrix16 + { + public: + inline_ udword Index(udword x, udword y) const { if(x>y) Swap(x,y); return x + (y ? ((y-1)*y)>>1 : 0); } + + inline_ void Set(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] |= BitMasks[i&7]; } + inline_ void Clear(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] &= NegBitMasks[i&7]; } + inline_ void Toggle(udword x, udword y) { udword i = Index(x, y); mBits[i>>3] ^= BitMasks[i&7]; } + inline_ bool IsSet(udword x, udword y) const { udword i = Index(x, y); return (mBits[i>>3] & BitMasks[i&7])!=0; } + + inline_ void ClearAll() { ZeroMemory(mBits, 17); } + inline_ void SetAll() { FillMemory(mBits, 17, 0xff); } + + ubyte mBits[17]; + }; + +#endif // ICEBITARRAY_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceBoundingSphere.h b/Extras/CDTestFramework/Opcode/Ice/IceBoundingSphere.h new file mode 100644 index 0000000..053f007 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceBoundingSphere.h @@ -0,0 +1,158 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to compute the minimal bounding sphere. + * \file IceBoundingSphere.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEBOUNDINGSPHERE_H__ +#define __ICEBOUNDINGSPHERE_H__ + + enum BSphereMethod + { + BS_NONE, + BS_GEMS, + BS_MINIBALL, + + BS_FORCE_DWORD = 0x7fffffff + }; + + class ICEMATHS_API Sphere + { + public: + //! Constructor + inline_ Sphere() {} + //! Constructor + inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {} + //! Constructor + Sphere(udword nb_verts, const Point* verts); + //! Copy constructor + inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {} + //! Destructor + inline_ ~Sphere() {} + + BSphereMethod Compute(udword nb_verts, const Point* verts); + bool FastCompute(udword nb_verts, const Point* verts); + + // Access methods + inline_ const Point& GetCenter() const { return mCenter; } + inline_ float GetRadius() const { return mRadius; } + + inline_ const Point& Center() const { return mCenter; } + inline_ float Radius() const { return mRadius; } + + inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; } + inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; } + inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the sphere. + * \param p [in] the point to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Point& p) const + { + return mCenter.SquareDistance(p) <= mRadius*mRadius; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a sphere is contained within the sphere. + * \param sphere [in] the sphere to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Sphere& sphere) const + { + // If our radius is the smallest, we can't possibly contain the other sphere + if(mRadius < sphere.mRadius) return false; + // So r is always positive or null now + float r = mRadius - sphere.mRadius; + return mCenter.SquareDistance(sphere.mCenter) <= r*r; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a box is contained within the sphere. + * \param aabb [in] the box to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Contains(const AABB& aabb) const + { + // I assume if all 8 box vertices are inside the sphere, so does the whole box. + // Sounds ok but maybe there's a better way? + float R2 = mRadius * mRadius; +#ifdef USE_MIN_MAX + const Point& Max = ((ShadowAABB&)&aabb).mMax; + const Point& Min = ((ShadowAABB&)&aabb).mMin; +#else + Point Max; aabb.GetMax(Max); + Point Min; aabb.GetMin(Min); +#endif + Point p; + p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if the sphere intersects another sphere + * \param sphere [in] the other sphere + * \return true if spheres overlap + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Intersect(const Sphere& sphere) const + { + float r = mRadius + sphere.mRadius; + return mCenter.SquareDistance(sphere.mCenter) <= r*r; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the sphere is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for spheres: Radius >= 0.0f + if(mRadius < 0.0f) return FALSE; + return TRUE; + } + public: + Point mCenter; //!< Sphere center + float mRadius; //!< Sphere radius + }; + +#endif // __ICEBOUNDINGSPHERE_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceContainer.cpp b/Extras/CDTestFramework/Opcode/Ice/IceContainer.cpp new file mode 100644 index 0000000..2c3e9ac --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceContainer.cpp @@ -0,0 +1,423 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a simple container class. + * \file IceContainer.cpp + * \author Pierre Terdiman + * \date February, 5, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a list of 32-bits values. + * Use this class when you need to store an unknown number of values. The list is automatically + * resized and can contains 32-bits entities (dwords or floats) + * + * \class Container + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "StdAfx.h" + +using namespace Opcode; + +// Static members +#ifdef CONTAINER_STATS +udword Container::mNbContainers = 0; +udword Container::mUsedRam = 0; +LinkedList Container::mContainers; +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. No entries allocated there. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); + mContainers.AddElem(this); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. Also allocates a given number of entries. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null) +{ + SetGrowthFactor(growth_factor); +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); + mContainers.AddElem(this); +#endif + SetSize(size); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Copy constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); + mContainers.AddElem(this); +#endif + *this = object; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. Frees everything and leaves. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::~Container() +{ + Empty(); +#ifdef CONTAINER_STATS + mNbContainers--; + mUsedRam-=GetUsedRam(); + mContainers.RemElem(this); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes the container so that it uses an external memory buffer. The container doesn't own the memory, resizing is disabled. + * \param max_entries [in] max number of entries in the container + * \param entries [in] external memory buffer + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Container::InitSharedBuffers(udword max_entries, udword* entries) +{ + Empty(); // Make sure everything has been released + mMaxNbEntries = max_entries; + mEntries = entries; + mGrowthFactor = -1.0f; // Negative growth ==> resize is disabled +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Clears the container. All stored values are deleted, and it frees used ram. + * \see Reset() + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container& Container::Empty() +{ +#ifdef CONTAINER_STATS + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + if(mGrowthFactor>=0.0f) ICE_FREE(mEntries); // Release memory if we own it + mCurNbEntries = mMaxNbEntries = 0; + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Resizes the container. + * \param needed [in] assume the container can be added at least "needed" values + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::Resize(udword needed) +{ + // Check growth is allowed + if(mGrowthFactor<=0.0f) + { + ASSERT(!"Invalid operation - trying to resize a static buffer!"); + return false; + } + +#ifdef CONTAINER_STATS + // Subtract previous amount of bytes + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + + // Get more entries + mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2 + if(mMaxNbEntriesshrink(mEntries, sizeof(udword)*mCurNbEntries)) + return false; + +#ifdef CONTAINER_STATS + // Subtract previous amount of bytes + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + + // Get just enough entries + mMaxNbEntries = mCurNbEntries; + +#ifdef CONTAINER_STATS + // Add current amount of bytes + mUsedRam+=mMaxNbEntries*sizeof(udword); +#endif + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the container already contains a given value. + * \param entry [in] the value to look for in the container + * \param location [out] a possible pointer to store the entry location + * \see Add(udword entry) + * \see Add(float entry) + * \see Empty() + * \return true if the value has been found in the container, else false. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::Contains(udword entry, udword* location) const +{ + // Look for the entry + for(udword i=0;imMaxNbEntries) Resize(nb); + + // Add new entry + CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword)); + mCurNbEntries += nb; + } + return *this; + } + + inline_ Container& Add(const Container& container) + { + return Add(container.GetEntries(), container.GetNbEntries()); + } + + inline_ udword* Reserve(udword nb) + { + // Resize if needed + if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); + + // We expect the user to fill reserved memory with 'nb' udwords + udword* Reserved = &mEntries[mCurNbEntries]; + + // Meanwhile, we do as if it had been filled + mCurNbEntries += nb; + + // This is mainly used to avoid the copy when possible + return Reserved; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * A O(1) method to add a value in the container. The container is automatically resized if needed. + * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation + * costs a lot more than the call overhead... + * + * \param entry [in] a float to store in the container + * \see Add(udword entry) + * \see Empty() + * \see Contains(udword entry) + * \return Self-Reference + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ Container& Add(float entry) + { + // Resize if needed + if(mCurNbEntries==mMaxNbEntries) Resize(); + + // Add new entry + mEntries[mCurNbEntries++] = IR(entry); + return *this; + } + + inline_ Container& Add(const float* entries, udword nb) + { + // Resize if needed + if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); + + // Add new entry + CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float)); + mCurNbEntries+=nb; + return *this; + } + + //! Add unique [slow] + inline_ Container& AddUnique(udword entry) + { + if(!Contains(entry)) Add(entry); + return *this; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Clears the container. All stored values are deleted, and it frees used ram. + * \see Reset() + * \return Self-Reference + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Container& Empty(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again. + * That's a kind of temporal coherence. + * \see Empty() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Reset() + { + // Avoid the write if possible + // ### CMOV + if(mCurNbEntries) mCurNbEntries = 0; + } + + // HANDLE WITH CARE - I hope you know what you're doing + inline_ void ForceSize(udword size) + { + mCurNbEntries = size; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Sets the initial size of the container. If it already contains something, it's discarded. + * \param nb [in] Number of entries + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetSize(udword nb); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the container and get rid of unused bytes. + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Refit(); + + bool Shrink(); + + // Checks whether the container already contains a given value. + bool Contains(udword entry, udword* location=null) const; + // Deletes an entry - doesn't preserve insertion order. + bool Delete(udword entry); + // Deletes an entry - does preserve insertion order. + bool DeleteKeepingOrder(udword entry); + //! Deletes the very last entry. + inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; } + //! Deletes the entry whose index is given + inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; } + + // Helpers + Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP); + Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP); + // Data access. + inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries. + inline_ udword GetMaxNbEntries() const { return mMaxNbEntries; } //!< Returns max number of entries before resizing. + inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry. + inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries. + + inline_ udword GetFirst() const { return mEntries[0]; } + inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; } + + // Growth control + float GetGrowthFactor() const; //!< Returns the growth factor + void SetGrowthFactor(float growth); //!< Sets the growth factor + inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full + inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty + + //! Read-access as an array + inline_ udword operator[](udword i) const { ASSERT(i>=0 && i=0 && i>31); + return (float&)y; + } + + //! Computes 1.0f / sqrtf(x). + inline_ float frsqrt(float f) + { + float x = f * 0.5f; + udword y = 0x5f3759df - ((udword&)f >> 1); + // Iteration... + (float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) ); + // Result + return (float&)y; + } + + //! Computes 1.0f / sqrtf(x). Comes from NVIDIA. + inline_ float InvSqrt(const float& x) + { + udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1; + float y = *(float*)&tmp; + return y * (1.47f - 0.47f * x * y * y); + } + + //! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above. + //! See http://www.magic-software.com/3DGEDInvSqrt.html + inline_ float RSqrt(float number) + { + long i; + float x2, y; + const float threehalfs = 1.5f; + + x2 = number * 0.5f; + y = number; + i = * (long *) &y; + i = 0x5f3759df - (i >> 1); + y = * (float *) &i; + y = y * (threehalfs - (x2 * y * y)); + + return y; + } + + //! TO BE DOCUMENTED + inline_ float fsqrt(float f) + { + udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000; + // Iteration...? + // (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f; + // Result + return (float&)y; + } + + //! Returns the float ranged espilon value. + inline_ float fepsilon(float f) + { + udword b = (udword&)f & 0xff800000; + udword a = b | 0x00000001; + (float&)a -= (float&)b; + // Result + return (float&)a; + } + + //! Is the float valid ? + inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; } + inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; } + inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; } + inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; } + + inline_ bool IsValidFloat(float value) + { + if(IsNAN(value)) return false; + if(IsIndeterminate(value)) return false; + if(IsPlusInf(value)) return false; + if(IsMinusInf(value)) return false; + return true; + } + + #define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x)); + +/* + //! FPU precision setting function. + inline_ void SetFPU() + { + // This function evaluates whether the floating-point + // control word is set to single precision/round to nearest/ + // exceptions disabled. If these conditions don't hold, the + // function changes the control word to set them and returns + // TRUE, putting the old control word value in the passback + // location pointed to by pwOldCW. + { + uword wTemp, wSave; + + __asm fstcw wSave + if (wSave & 0x300 || // Not single mode + 0x3f != (wSave & 0x3f) || // Exceptions enabled + wSave & 0xC00) // Not round to nearest mode + { + __asm + { + mov ax, wSave + and ax, not 300h ;; single mode + or ax, 3fh ;; disable all exceptions + and ax, not 0xC00 ;; round to nearest mode + mov wTemp, ax + fldcw wTemp + } + } + } + } +*/ + //! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON) + inline_ float ComputeFloatEpsilon() + { + float f = 1.0f; + ((udword&)f)^=1; + return f - 1.0f; // You can check it's the same as FLT_EPSILON + } + + inline_ bool IsFloatZero(float x, float epsilon=1e-6f) + { + return x*x < epsilon; + } + + #define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0 + #define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0 + #define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0 + #define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0 + + #define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1 + #define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1 + #define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1 + #define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1 + + #define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2 + #define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2 + #define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2 + #define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2 + + #define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3 + #define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3 + #define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3 + #define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3 + + #define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4 + #define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4 + #define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4 + #define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4 + + #define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5 + #define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5 + #define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5 + #define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5 + + #define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6 + #define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6 + #define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6 + #define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6 + + #define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7 + #define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7 + #define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7 + #define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7 + + //! A global function to find MAX(a,b) using FCOMI/FCMOV + inline_ float FCMax2(float a, float b) + { + float Res; + _asm fld [a] + _asm fld [b] + FCOMI_ST1 + FCMOVB_ST1 + _asm fstp [Res] + _asm fcomp + return Res; + } + + //! A global function to find MIN(a,b) using FCOMI/FCMOV + inline_ float FCMin2(float a, float b) + { + float Res; + _asm fld [a] + _asm fld [b] + FCOMI_ST1 + FCMOVNB_ST1 + _asm fstp [Res] + _asm fcomp + return Res; + } + + //! A global function to find MAX(a,b,c) using FCOMI/FCMOV + inline_ float FCMax3(float a, float b, float c) + { + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + FCOMI_ST1 + FCMOVB_ST1 + FCOMI_ST2 + FCMOVB_ST2 + _asm fstp [Res] + _asm fcompp + return Res; + } + + //! A global function to find MIN(a,b,c) using FCOMI/FCMOV + inline_ float FCMin3(float a, float b, float c) + { + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + FCOMI_ST1 + FCMOVNB_ST1 + FCOMI_ST2 + FCMOVNB_ST2 + _asm fstp [Res] + _asm fcompp + return Res; + } + + //! A global function to find MAX(a,b,c,d) using FCOMI/FCMOV + inline_ float FCMax4(float a, float b, float c, float d) + { + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + _asm fld [d] + FCOMI_ST1 + FCMOVB_ST1 + FCOMI_ST2 + FCMOVB_ST2 + FCOMI_ST3 + FCMOVB_ST3 + _asm fstp [Res] + _asm fcompp + _asm fcomp + return Res; + } + + //! A global function to find MIN(a,b,c,d) using FCOMI/FCMOV + inline_ float FCMin4(float a, float b, float c, float d) + { + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + _asm fld [d] + FCOMI_ST1 + FCMOVNB_ST1 + FCOMI_ST2 + FCMOVNB_ST2 + FCOMI_ST3 + FCMOVNB_ST3 + _asm fstp [Res] + _asm fcompp + _asm fcomp + return Res; + } + + inline_ int ConvertToSortable(float f) + { + int& Fi = (int&)f; + int Fmask = (Fi>>31); + Fi ^= Fmask; + Fmask &= ~(1<<31); + Fi -= Fmask; + return Fi; + } + + inline_ udword EncodeFloat(const float val) + { + // We may need to check on -0 and 0 + // But it should make no practical difference. + udword ir = IR(val); + + if(ir & 0x80000000) //negative? + ir = ~ir;//reverse sequence of negative numbers + else + ir |= 0x80000000; // flip sign + + return ir; + } + + inline_ float DecodeFloat(udword ir) + { + udword rv; + + if(ir & 0x80000000) //positive? + rv = ir & ~0x80000000; //flip sign + else + rv = ~ir; //undo reversal + + return FR(rv); + } + + enum FPUMode + { + FPU_FLOOR = 0, + FPU_CEIL = 1, + FPU_BEST = 2, + + FPU_FORCE_DWORD = 0x7fffffff + }; + + FUNCTION ICECORE_API FPUMode GetFPUMode(); + FUNCTION ICECORE_API void SaveFPU(); + FUNCTION ICECORE_API void RestoreFPU(); + FUNCTION ICECORE_API void SetFPUFloorMode(); + FUNCTION ICECORE_API void SetFPUCeilMode(); + FUNCTION ICECORE_API void SetFPUBestMode(); + + FUNCTION ICECORE_API void SetFPUPrecision24(); + FUNCTION ICECORE_API void SetFPUPrecision53(); + FUNCTION ICECORE_API void SetFPUPrecision64(); + FUNCTION ICECORE_API void SetFPURoundingChop(); + FUNCTION ICECORE_API void SetFPURoundingUp(); + FUNCTION ICECORE_API void SetFPURoundingDown(); + FUNCTION ICECORE_API void SetFPURoundingNear(); + + FUNCTION ICECORE_API int intChop(const float& f); + FUNCTION ICECORE_API int intFloor(const float& f); + FUNCTION ICECORE_API int intCeil(const float& f); + + inline_ sdword MyFloor(float f) + { + return (sdword)f - (IR(f)>>31); + } + + class ICECORE_API FPUGuard + { + public: + FPUGuard(); + ~FPUGuard(); + private: + uword mControlWord; + }; + +#endif // ICEFPU_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceHPoint.cpp b/Extras/CDTestFramework/Opcode/Ice/IceHPoint.cpp new file mode 100644 index 0000000..32d8e59 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceHPoint.cpp @@ -0,0 +1,87 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for homogeneous points. + * \file IceHPoint.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Homogeneous point. + * + * Use it: + * - for clipping in homogeneous space (standard way) + * - to differentiate between points (w=1) and vectors (w=0). + * - in some cases you can also use it instead of Point for padding reasons. + * + * \class HPoint + * \author Pierre Terdiman + * \version 1.0 + * \warning No cross-product in 4D. + * \warning HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Point Mul = HPoint * Matrix3x3; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point HPoint::operator*(const Matrix3x3& mat) const +{ + return Point( + x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0], + x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1], + x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] ); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// HPoint Mul = HPoint * Matrix4x4; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HPoint HPoint::operator*(const Matrix4x4& mat) const +{ + return HPoint( + x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0], + x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1], + x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2], + x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// HPoint *= Matrix4x4 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HPoint& HPoint::operator*=(const Matrix4x4& mat) +{ + float xp = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0]; + float yp = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1]; + float zp = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2]; + float wp = x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]; + + x = xp; y = yp; z = zp; w = wp; + + return *this; +} + + diff --git a/Extras/CDTestFramework/Opcode/Ice/IceHPoint.h b/Extras/CDTestFramework/Opcode/Ice/IceHPoint.h new file mode 100644 index 0000000..b35ac9e --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceHPoint.h @@ -0,0 +1,173 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for homogeneous points. + * \file IceHPoint.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEHPOINT_H__ +#define __ICEHPOINT_H__ + + class ICEMATHS_API HPoint : public Point + { + public: + + //! Empty constructor + inline_ HPoint() {} + //! Constructor from floats + inline_ HPoint(float _x, float _y, float _z, float _w=0.0f) : Point(_x, _y, _z), w(_w) {} + //! Constructor from array + inline_ HPoint(const float f[4]) : Point(f), w(f[3]) {} + //! Constructor from a Point + inline_ HPoint(const Point& p, float _w=0.0f) : Point(p), w(_w) {} + //! Destructor + inline_ ~HPoint() {} + + //! Clear the point + inline_ HPoint& Zero() { x = y = z = w = 0.0f; return *this; } + + //! Assignment from values + inline_ HPoint& Set(float _x, float _y, float _z, float _w ) { x = _x; y = _y; z = _z; w = _w; return *this; } + //! Assignment from array + inline_ HPoint& Set(const float f[4]) { x = f[_X]; y = f[_Y]; z = f[_Z]; w = f[_W]; return *this; } + //! Assignment from another h-point + inline_ HPoint& Set(const HPoint& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; } + + //! Add a vector + inline_ HPoint& Add(float _x, float _y, float _z, float _w ) { x += _x; y += _y; z += _z; w += _w; return *this; } + //! Add a vector + inline_ HPoint& Add(const float f[4]) { x += f[_X]; y += f[_Y]; z += f[_Z]; w += f[_W]; return *this; } + + //! Subtract a vector + inline_ HPoint& Sub(float _x, float _y, float _z, float _w ) { x -= _x; y -= _y; z -= _z; w -= _w; return *this; } + //! Subtract a vector + inline_ HPoint& Sub(const float f[4]) { x -= f[_X]; y -= f[_Y]; z -= f[_Z]; w -= f[_W]; return *this; } + + //! Multiplies by a scalar + inline_ HPoint& Mul(float s) { x *= s; y *= s; z *= s; w *= s; return *this; } + + //! Returns MIN(x, y, z, w); + float Min() const { return MIN(x, MIN(y, MIN(z, w))); } + //! Returns MAX(x, y, z, w); + float Max() const { return MAX(x, MAX(y, MAX(z, w))); } + //! Sets each element to be componentwise minimum + HPoint& Min(const HPoint& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); w = MIN(w, p.w); return *this; } + //! Sets each element to be componentwise maximum + HPoint& Max(const HPoint& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); w = MAX(w, p.w); return *this; } + + //! Computes square magnitude + inline_ float SquareMagnitude() const { return x*x + y*y + z*z + w*w; } + //! Computes magnitude + inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z + w*w); } + + //! Normalize the vector + inline_ HPoint& Normalize() + { + float M = Magnitude(); + if(M) + { + M = 1.0f / M; + x *= M; + y *= M; + z *= M; + w *= M; + } + return *this; + } + + // Arithmetic operators + //! Operator for HPoint Negate = - HPoint; + inline_ HPoint operator-() const { return HPoint(-x, -y, -z, -w); } + + //! Operator for HPoint Plus = HPoint + HPoint; + inline_ HPoint operator+(const HPoint& p) const { return HPoint(x + p.x, y + p.y, z + p.z, w + p.w); } + //! Operator for HPoint Minus = HPoint - HPoint; + inline_ HPoint operator-(const HPoint& p) const { return HPoint(x - p.x, y - p.y, z - p.z, w - p.w); } + + //! Operator for HPoint Mul = HPoint * HPoint; + inline_ HPoint operator*(const HPoint& p) const { return HPoint(x * p.x, y * p.y, z * p.z, w * p.w); } + //! Operator for HPoint Scale = HPoint * float; + inline_ HPoint operator*(float s) const { return HPoint(x * s, y * s, z * s, w * s); } + //! Operator for HPoint Scale = float * HPoint; + inline_ friend HPoint operator*(float s, const HPoint& p) { return HPoint(s * p.x, s * p.y, s * p.z, s * p.w); } + + //! Operator for HPoint Div = HPoint / HPoint; + inline_ HPoint operator/(const HPoint& p) const { return HPoint(x / p.x, y / p.y, z / p.z, w / p.w); } + //! Operator for HPoint Scale = HPoint / float; + inline_ HPoint operator/(float s) const { s = 1.0f / s; return HPoint(x * s, y * s, z * s, w * s); } + //! Operator for HPoint Scale = float / HPoint; + inline_ friend HPoint operator/(float s, const HPoint& p) { return HPoint(s / p.x, s / p.y, s / p.z, s / p.w); } + + //! Operator for float DotProd = HPoint | HPoint; + inline_ float operator|(const HPoint& p) const { return x*p.x + y*p.y + z*p.z + w*p.w; } + // No cross-product in 4D + + //! Operator for HPoint += HPoint; + inline_ HPoint& operator+=(const HPoint& p) { x += p.x; y += p.y; z += p.z; w += p.w; return *this; } + //! Operator for HPoint += float; + inline_ HPoint& operator+=(float s) { x += s; y += s; z += s; w += s; return *this; } + + //! Operator for HPoint -= HPoint; + inline_ HPoint& operator-=(const HPoint& p) { x -= p.x; y -= p.y; z -= p.z; w -= p.w; return *this; } + //! Operator for HPoint -= float; + inline_ HPoint& operator-=(float s) { x -= s; y -= s; z -= s; w -= s; return *this; } + + //! Operator for HPoint *= HPoint; + inline_ HPoint& operator*=(const HPoint& p) { x *= p.x; y *= p.y; z *= p.z; w *= p.w; return *this; } + //! Operator for HPoint *= float; + inline_ HPoint& operator*=(float s) { x*=s; y*=s; z*=s; w*=s; return *this; } + + //! Operator for HPoint /= HPoint; + inline_ HPoint& operator/=(const HPoint& p) { x /= p.x; y /= p.y; z /= p.z; w /= p.w; return *this; } + //! Operator for HPoint /= float; + inline_ HPoint& operator/=(float s) { s = 1.0f / s; x*=s; y*=s; z*=s; w*=s; return *this; } + + // Arithmetic operators + + //! Operator for Point Mul = HPoint * Matrix3x3; + Point operator*(const Matrix3x3& mat) const; + //! Operator for HPoint Mul = HPoint * Matrix4x4; + HPoint operator*(const Matrix4x4& mat) const; + + // HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4 + //! Operator for HPoint *= Matrix4x4 + HPoint& operator*=(const Matrix4x4& mat); + + // Logical operators + + //! Operator for "if(HPoint==HPoint)" + inline_ bool operator==(const HPoint& p) const { return ( (x==p.x)&&(y==p.y)&&(z==p.z)&&(w==p.w)); } + //! Operator for "if(HPoint!=HPoint)" + inline_ bool operator!=(const HPoint& p) const { return ( (x!=p.x)||(y!=p.y)||(z!=p.z)||(w!=p.w)); } + + // Cast operators + + //! Cast a HPoint to a Point. w is discarded. + inline_ operator Point() const { return Point(x, y, z); } + + public: + float w; + }; + +#endif // __ICEHPOINT_H__ + diff --git a/Extras/CDTestFramework/Opcode/Ice/IceHashing.h b/Extras/CDTestFramework/Opcode/Ice/IceHashing.h new file mode 100644 index 0000000..45160f8 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceHashing.h @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains hashing code. + * \file IceHashing.h + * \author Pierre Terdiman + * \date May, 08, 1999 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef ICEHASHING_H +#define ICEHASHING_H + + #define HashSize(n) ((udword)1<<(n)) + #define HashMask(n) (HashSize(n)-1) + + ICECORE_API udword Hash(const char* str); + ICECORE_API udword Hash(ubyte* k, udword length, udword initval); + + // Bob Jenkin's hash + inline_ unsigned int Hash32Bits_0(unsigned int key) + { + key += (key << 12); + key ^= (key >> 22); + key += (key << 4); + key ^= (key >> 9); + key += (key << 10); + key ^= (key >> 2); + key += (key << 7); + key ^= (key >> 12); + return key; + } + + // Thomas Wang's hash + inline_ int Hash32Bits_1(int key) + { + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; + } + + // Thomas Wang's hash + inline_ __int64 Hash64Bits_0(__int64 key) + { + key += ~(key << 32); + key ^= (key >> 22); + key += ~(key << 13); + key ^= (key >> 8); + key += (key << 3); + key ^= (key >> 15); + key += ~(key << 27); + key ^= (key >> 31); + return key; + } + + inline_ __int64 Hash64Bits_1(__int64 key) + { + __int64 c1 = 0x6e5ea73858134343L; + __int64 c2 = 0xb34e8f99a2ec9ef5L; + key ^= ((c1 ^ key) >> 32); + key *= c1; + key ^= ((c2 ^ key) >> 31); + key *= c2; + key ^= ((c1 ^ key) >> 32); + return key; + } + + inline_ udword Hash(udword id0, udword id1) + { + return Hash32Bits_1( (id0&0xffff)|(id1<<16) ); + } + +#endif // ICEHASHING_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.cpp b/Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.cpp new file mode 100644 index 0000000..4657f08 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.cpp @@ -0,0 +1,564 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy indexed triangle class. + * \file IceIndexedTriangle.cpp + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an indexed triangle class. + * + * \class Triangle + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Flips the winding order. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Flip() +{ + Swap(mVRef[1], mVRef[2]); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle area. + * \param verts [in] the list of indexed vertices + * \return the area + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Area(const Point* verts) const +{ + if(!verts) return 0.0f; + const Point& p0 = verts[0]; + const Point& p1 = verts[1]; + const Point& p2 = verts[2]; + return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle perimeter. + * \param verts [in] the list of indexed vertices + * \return the perimeter + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Perimeter(const Point* verts) const +{ + if(!verts) return 0.0f; + const Point& p0 = verts[0]; + const Point& p1 = verts[1]; + const Point& p2 = verts[2]; + return p0.Distance(p1) + + p0.Distance(p2) + + p1.Distance(p2); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle compacity. + * \param verts [in] the list of indexed vertices + * \return the compacity + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Compacity(const Point* verts) const +{ + if(!verts) return 0.0f; + float P = Perimeter(verts); + if(P==0.0f) return 0.0f; + return (4.0f*PI*Area(verts)/(P*P)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle normal. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Normal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + normal = ((p2-p1)^(p0-p1)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle denormalized normal. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + normal = ((p2-p1)^(p0-p1)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle center. + * \param verts [in] the list of indexed vertices + * \param center [out] the computed center + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Center(const Point* verts, Point& center) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + center = (p0+p1+p2)*INV3; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the centered normal + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed centered normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + Point Center = (p0+p1+p2)*INV3; + normal = Center + ((p2-p1)^(p0-p1)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a random point within the triangle. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed centered normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::RandomPoint(const Point* verts, Point& random) const +{ + if(!verts) return; + + // Random barycentric coords + float Alpha = UnitRandomFloat(); + float Beta = UnitRandomFloat(); + float Gamma = UnitRandomFloat(); + float OneOverTotal = 1.0f / (Alpha + Beta + Gamma); + Alpha *= OneOverTotal; + Beta *= OneOverTotal; + Gamma *= OneOverTotal; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + random = Alpha*p0 + Beta*p1 + Gamma*p2; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes backface culling. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which culling must be computed + * \return true if the triangle is visible from the source point + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::IsVisible(const Point* verts, const Point& source) const +{ + // Checkings + if(!verts) return false; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute denormalized normal + Point Normal = (p2 - p1)^(p0 - p1); + + // Backface culling + return (Normal | source) >= 0.0f; + +// Same as: +// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); +// return PL.Distance(source) > PL.d; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes backface culling. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which culling must be computed + * \return true if the triangle is visible from the source point + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source) const +{ + // Checkings + if(!verts) return false; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute base +// Point Base = (p0 + p1 + p2)*INV3; + + // Compute denormalized normal + Point Normal = (p2 - p1)^(p0 - p1); + + // Backface culling +// return (Normal | (source - Base)) >= 0.0f; + return (Normal | (source - p0)) >= 0.0f; + +// Same as: (but a bit faster) +// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); +// return PL.Distance(source)>0.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the occlusion potential of the triangle. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which occlusion potential must be computed + * \return the occlusion potential + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view) const +{ + if(!verts) return 0.0f; + // Occlusion potential: -(A * (N|V) / d^2) + // A = polygon area + // N = polygon normal + // V = view vector + // d = distance viewpoint-center of polygon + + float A = Area(verts); + Point N; Normal(verts, N); + Point C; Center(verts, C); + float d = view.Distance(C); + return -(A*(N|view))/(d*d); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Replaces a vertex reference with another one. + * \param oldref [in] the vertex reference to replace + * \param newref [in] the new vertex reference + * \return true if success, else false if the input vertex reference doesn't belong to the triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::ReplaceVertex(udword oldref, udword newref) +{ + if(mVRef[0]==oldref) { mVRef[0] = newref; return true; } + else if(mVRef[1]==oldref) { mVRef[1] = newref; return true; } + else if(mVRef[2]==oldref) { mVRef[2] = newref; return true; } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the triangle is degenerate or not. A degenerate triangle has two common vertex references. This is a zero-area triangle. + * \return true if the triangle is degenerate + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::IsDegenerate() const +{ + if(mVRef[0]==mVRef[1]) return true; + if(mVRef[1]==mVRef[2]) return true; + if(mVRef[2]==mVRef[0]) return true; + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the input vertex reference belongs to the triangle or not. + * \param ref [in] the vertex reference to look for + * \return true if the triangle contains the vertex reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::HasVertex(udword ref) const +{ + if(mVRef[0]==ref) return true; + if(mVRef[1]==ref) return true; + if(mVRef[2]==ref) return true; + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the input vertex reference belongs to the triangle or not. + * \param ref [in] the vertex reference to look for + * \param index [out] the corresponding index in the triangle + * \return true if the triangle contains the vertex reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::HasVertex(udword ref, udword* index) const +{ + if(mVRef[0]==ref) { *index = 0; return true; } + if(mVRef[1]==ref) { *index = 1; return true; } + if(mVRef[2]==ref) { *index = 2; return true; } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Finds an edge in a tri, given two vertex references. + * \param vref0 [in] the edge's first vertex reference + * \param vref1 [in] the edge's second vertex reference + * \return the edge number between 0 and 2, or 0xff if input refs are wrong. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +ubyte IndexedTriangle::FindEdge(udword vref0, udword vref1) const +{ + if(mVRef[0]==vref0 && mVRef[1]==vref1) return 0; + else if(mVRef[0]==vref1 && mVRef[1]==vref0) return 0; + else if(mVRef[0]==vref0 && mVRef[2]==vref1) return 1; + else if(mVRef[0]==vref1 && mVRef[2]==vref0) return 1; + else if(mVRef[1]==vref0 && mVRef[2]==vref1) return 2; + else if(mVRef[1]==vref1 && mVRef[2]==vref0) return 2; + return 0xff; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the last reference given the first two. + * \param vref0 [in] the first vertex reference + * \param vref1 [in] the second vertex reference + * \return the last reference, or INVALID_ID if input refs are wrong. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword IndexedTriangle::OppositeVertex(udword vref0, udword vref1) const +{ + if(mVRef[0]==vref0 && mVRef[1]==vref1) return mVRef[2]; + else if(mVRef[0]==vref1 && mVRef[1]==vref0) return mVRef[2]; + else if(mVRef[0]==vref0 && mVRef[2]==vref1) return mVRef[1]; + else if(mVRef[0]==vref1 && mVRef[2]==vref0) return mVRef[1]; + else if(mVRef[1]==vref0 && mVRef[2]==vref1) return mVRef[0]; + else if(mVRef[1]==vref1 && mVRef[2]==vref0) return mVRef[0]; + return INVALID_ID; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the three sorted vertex references according to an edge number. + * edgenb = 0 => edge 0-1, returns references 0, 1, 2 + * edgenb = 1 => edge 0-2, returns references 0, 2, 1 + * edgenb = 2 => edge 1-2, returns references 1, 2, 0 + * + * \param edgenb [in] the edge number, 0, 1 or 2 + * \param vref0 [out] the returned first vertex reference + * \param vref1 [out] the returned second vertex reference + * \param vref2 [out] the returned third vertex reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const +{ + if(edgenb==0) + { + vref0 = mVRef[0]; + vref1 = mVRef[1]; + vref2 = mVRef[2]; + } + else if(edgenb==1) + { + vref0 = mVRef[0]; + vref1 = mVRef[2]; + vref2 = mVRef[1]; + } + else if(edgenb==2) + { + vref0 = mVRef[1]; + vref1 = mVRef[2]; + vref2 = mVRef[0]; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's smallest edge length. + * \param verts [in] the list of indexed vertices + * \return the smallest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::MinEdgeLength(const Point* verts) const +{ + if(!verts) return 0.0f; + + float Min = MAX_FLOAT; + float Length01 = verts[0].Distance(verts[1]); + float Length02 = verts[0].Distance(verts[2]); + float Length12 = verts[1].Distance(verts[2]); + if(Length01 < Min) Min = Length01; + if(Length02 < Min) Min = Length02; + if(Length12 < Min) Min = Length12; + return Min; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's largest edge length. + * \param verts [in] the list of indexed vertices + * \return the largest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::MaxEdgeLength(const Point* verts) const +{ + if(!verts) return 0.0f; + + float Max = MIN_FLOAT; + float Length01 = verts[0].Distance(verts[1]); + float Length02 = verts[0].Distance(verts[2]); + float Length12 = verts[1].Distance(verts[2]); + if(Length01 > Max) Max = Length01; + if(Length02 > Max) Max = Length02; + if(Length12 > Max) Max = Length12; + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a point on the triangle according to the stabbing information. + * \param verts [in] the list of indexed vertices + * \param u,v [in] point's barycentric coordinates + * \param pt [out] point on triangle + * \param nearvtx [out] index of nearest vertex + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx) const +{ + // Checkings + if(!verts) return; + + // Get face in local or global space + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute point coordinates + pt = (1.0f - u - v)*p0 + u*p1 + v*p2; + + // Compute nearest vertex if needed + if(nearvtx) + { + // Compute distance vector + Point d(p0.SquareDistance(pt), // Distance^2 from vertex 0 to point on the face + p1.SquareDistance(pt), // Distance^2 from vertex 1 to point on the face + p2.SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face + + // Get smallest distance + *nearvtx = mVRef[d.SmallestAxis()]; + } +} + + //************************************** + // Angle between two vectors (in radians) + // we use this formula + // uv = |u||v| cos(u,v) + // u ^ v = w + // |w| = |u||v| |sin(u,v)| + //************************************** + float Angle(const Point& u, const Point& v) + { + float NormU = u.Magnitude(); // |u| + float NormV = v.Magnitude(); // |v| + float Product = NormU*NormV; // |u||v| + if(Product==0.0f) return 0.0f; + float OneOverProduct = 1.0f / Product; + + // Cosinus + float Cosinus = (u|v) * OneOverProduct; + + // Sinus + Point w = u^v; + float NormW = w.Magnitude(); + + float AbsSinus = NormW * OneOverProduct; + + // Remove degeneracy + if(AbsSinus > 1.0f) AbsSinus = 1.0f; + if(AbsSinus < -1.0f) AbsSinus = -1.0f; + + if(Cosinus>=0.0f) return asinf(AbsSinus); + else return (PI-asinf(AbsSinus)); + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the angle between two triangles. + * \param tri [in] the other triangle + * \param verts [in] the list of indexed vertices + * \return the angle in radians + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Angle(const IndexedTriangle& tri, const Point* verts) const +{ + // Checkings + if(!verts) return 0.0f; + + // Compute face normals + Point n0, n1; + Normal(verts, n0); + tri.Normal(verts, n1); + + // Compute angle + float dp = n0|n1; + if(dp>1.0f) return 0.0f; + if(dp<-1.0f) return PI; + return acosf(dp); + +// return ::Angle(n0,n1); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks a triangle is the same as another one. + * \param tri [in] the other triangle + * \return true if same triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::Equal(const IndexedTriangle& tri) const +{ + // Test all vertex references + return (HasVertex(tri.mVRef[0]) && + HasVertex(tri.mVRef[1]) && + HasVertex(tri.mVRef[2])); +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.h b/Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.h new file mode 100644 index 0000000..3317a9b --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceIndexedTriangle.h @@ -0,0 +1,84 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy indexed triangle class. + * \file IceIndexedTriangle.h + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEINDEXEDTRIANGLE_H__ +#define __ICEINDEXEDTRIANGLE_H__ + + // Forward declarations + enum CubeIndex; + + // An indexed triangle class. + class ICEMATHS_API IndexedTriangle + { + public: + //! Constructor + inline_ IndexedTriangle() {} + //! Constructor + inline_ IndexedTriangle(udword r0, udword r1, udword r2) { mVRef[0]=r0; mVRef[1]=r1; mVRef[2]=r2; } + //! Copy constructor + inline_ IndexedTriangle(const IndexedTriangle& triangle) + { + mVRef[0] = triangle.mVRef[0]; + mVRef[1] = triangle.mVRef[1]; + mVRef[2] = triangle.mVRef[2]; + } + //! Destructor + inline_ ~IndexedTriangle() {} + //! Vertex-references + udword mVRef[3]; + + // Methods + void Flip(); + float Area(const Point* verts) const; + float Perimeter(const Point* verts) const; + float Compacity(const Point* verts) const; + void Normal(const Point* verts, Point& normal) const; + void DenormalizedNormal(const Point* verts, Point& normal) const; + void Center(const Point* verts, Point& center) const; + void CenteredNormal(const Point* verts, Point& normal) const; + void RandomPoint(const Point* verts, Point& random) const; + bool IsVisible(const Point* verts, const Point& source) const; + bool BackfaceCulling(const Point* verts, const Point& source) const; + float ComputeOcclusionPotential(const Point* verts, const Point& view) const; + bool ReplaceVertex(udword oldref, udword newref); + bool IsDegenerate() const; + bool HasVertex(udword ref) const; + bool HasVertex(udword ref, udword* index) const; + ubyte FindEdge(udword vref0, udword vref1) const; + udword OppositeVertex(udword vref0, udword vref1) const; + inline_ udword OppositeVertex(ubyte edgenb) const { return mVRef[2-edgenb]; } + void GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const; + float MinEdgeLength(const Point* verts) const; + float MaxEdgeLength(const Point* verts) const; + void ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx=null) const; + float Angle(const IndexedTriangle& tri, const Point* verts) const; + inline_ Plane PlaneEquation(const Point* verts) const { return Plane(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); } + bool Equal(const IndexedTriangle& tri) const; + CubeIndex ComputeCubeIndex(const Point* verts) const; + }; + +#endif // __ICEINDEXEDTRIANGLE_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceLSS.h b/Extras/CDTestFramework/Opcode/Ice/IceLSS.h new file mode 100644 index 0000000..d9816d5 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceLSS.h @@ -0,0 +1,91 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for line-swept spheres. + * \file IceLSS.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICELSS_H__ +#define __ICELSS_H__ + + class ICEMATHS_API LSS : public Segment + { + public: + //! Constructor + inline_ LSS() {} + //! Constructor + inline_ LSS(const Segment& seg, float radius) : Segment(seg), mRadius(radius) {} + //! Destructor + inline_ ~LSS() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes an OBB surrounding the LSS. + * \param box [out] the OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeOBB(OBB& box); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the LSS. + * \param pt [in] the point to test + * \return true if inside the LSS + * \warning point and LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Point& pt) const { return SquareDistance(pt) <= mRadius*mRadius; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a sphere is contained within the LSS. + * \param sphere [in] the sphere to test + * \return true if inside the LSS + * \warning sphere and LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Sphere& sphere) + { + float d = mRadius - sphere.mRadius; + if(d>=0.0f) return SquareDistance(sphere.mCenter) <= d*d; + else return false; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if an LSS is contained within the LSS. + * \param lss [in] the LSS to test + * \return true if inside the LSS + * \warning both LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const LSS& lss) + { + // We check the LSS contains the two spheres at the start and end of the sweep + return Contains(Sphere(lss.mP0, lss.mRadius)) && Contains(Sphere(lss.mP0, lss.mRadius)); + } + + float mRadius; //!< Sphere radius + }; + +#endif // __ICELSS_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.cpp b/Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.cpp new file mode 100644 index 0000000..8a981b5 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.cpp @@ -0,0 +1,64 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3x3 matrices. + * \file IceMatrix3x3.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 3x3 matrix. + * DirectX-compliant, ie row-column order, ie m[Row][Col]. + * Same as: + * m11 m12 m13 first row. + * m21 m22 m23 second row. + * m31 m32 m33 third row. + * Stored in memory as m11 m12 m13 m21... + * + * Multiplication rules: + * + * [x'y'z'] = [xyz][M] + * + * x' = x*m11 + y*m21 + z*m31 + * y' = x*m12 + y*m22 + z*m32 + * z' = x*m13 + y*m23 + z*m33 + * + * \class Matrix3x3 + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +// Cast operator +Matrix3x3::operator Matrix4x4() const +{ + return Matrix4x4( + m[0][0], m[0][1], m[0][2], 0.0f, + m[1][0], m[1][1], m[1][2], 0.0f, + m[2][0], m[2][1], m[2][2], 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.h b/Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.h new file mode 100644 index 0000000..a2da08a --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceMatrix3x3.h @@ -0,0 +1,512 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3x3 matrices. + * \file IceMatrix3x3.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEMATRIX3X3_H__ +#define __ICEMATRIX3X3_H__ + + // Forward declarations + class Quat; + + #define MATRIX3X3_EPSILON (1.0e-7f) + + class ICEMATHS_API Matrix3x3 + { + public: + //! Empty constructor + inline_ Matrix3x3() {} + //! Constructor from 9 values + inline_ Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; + } + //! Copy constructor + inline_ Matrix3x3(const Matrix3x3& mat) { CopyMemory(m, &mat.m, 9*sizeof(float)); } + //! Destructor + inline_ ~Matrix3x3() {} + + //! Assign values + inline_ void Set(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; + } + + //! Sets the scale from a Point. The point is put on the diagonal. + inline_ void SetScale(const Point& p) { m[0][0] = p.x; m[1][1] = p.y; m[2][2] = p.z; } + + //! Sets the scale from floats. Values are put on the diagonal. + inline_ void SetScale(float sx, float sy, float sz) { m[0][0] = sx; m[1][1] = sy; m[2][2] = sz; } + + //! Scales from a Point. Each row is multiplied by a component. + inline_ void Scale(const Point& p) + { + m[0][0] *= p.x; m[0][1] *= p.x; m[0][2] *= p.x; + m[1][0] *= p.y; m[1][1] *= p.y; m[1][2] *= p.y; + m[2][0] *= p.z; m[2][1] *= p.z; m[2][2] *= p.z; + } + + //! Scales from floats. Each row is multiplied by a value. + inline_ void Scale(float sx, float sy, float sz) + { + m[0][0] *= sx; m[0][1] *= sx; m[0][2] *= sx; + m[1][0] *= sy; m[1][1] *= sy; m[1][2] *= sy; + m[2][0] *= sz; m[2][1] *= sz; m[2][2] *= sz; + } + + //! Copy from a Matrix3x3 + inline_ void Copy(const Matrix3x3& source) { CopyMemory(m, source.m, 9*sizeof(float)); } + + // Row-column access + //! Returns a row. + inline_ void GetRow(const udword r, Point& p) const { p.x = m[r][0]; p.y = m[r][1]; p.z = m[r][2]; } + //! Returns a row. + inline_ const Point& GetRow(const udword r) const { return *(const Point*)&m[r][0]; } + //! Returns a row. + inline_ Point& GetRow(const udword r) { return *(Point*)&m[r][0]; } + //! Sets a row. + inline_ void SetRow(const udword r, const Point& p) { m[r][0] = p.x; m[r][1] = p.y; m[r][2] = p.z; } + //! Returns a column. + inline_ void GetCol(const udword c, Point& p) const { p.x = m[0][c]; p.y = m[1][c]; p.z = m[2][c]; } + //! Sets a column. + inline_ void SetCol(const udword c, const Point& p) { m[0][c] = p.x; m[1][c] = p.y; m[2][c] = p.z; } + + //! Computes the trace. The trace is the sum of the 3 diagonal components. + inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2]; } + //! Clears the matrix. + inline_ void Zero() { ZeroMemory(&m, sizeof(m)); } + //! Sets the identity matrix. + inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = 1.0f; } + //! Checks for identity + inline_ bool IsIdentity() const + { + if(IR(m[0][0])!=IEEE_1_0) return false; + if(IR(m[0][1])!=0) return false; + if(IR(m[0][2])!=0) return false; + + if(IR(m[1][0])!=0) return false; + if(IR(m[1][1])!=IEEE_1_0) return false; + if(IR(m[1][2])!=0) return false; + + if(IR(m[2][0])!=0) return false; + if(IR(m[2][1])!=0) return false; + if(IR(m[2][2])!=IEEE_1_0) return false; + + return true; + } + + //! Checks matrix validity + inline_ BOOL IsValid() const + { + for(udword j=0;j<3;j++) + { + for(udword i=0;i<3;i++) + { + if(!IsValidFloat(m[j][i])) return FALSE; + } + } + return TRUE; + } + + //! Makes a skew-symmetric matrix (a.k.a. Star(*) Matrix) + //! [ 0.0 -a.z a.y ] + //! [ a.z 0.0 -a.x ] + //! [ -a.y a.x 0.0 ] + //! This is also called a "cross matrix" since for any vectors A and B, + //! A^B = Skew(A) * B = - B * Skew(A); + inline_ void SkewSymmetric(const Point& a) + { + m[0][0] = 0.0f; + m[0][1] = -a.z; + m[0][2] = a.y; + + m[1][0] = a.z; + m[1][1] = 0.0f; + m[1][2] = -a.x; + + m[2][0] = -a.y; + m[2][1] = a.x; + m[2][2] = 0.0f; + } + + //! Negates the matrix + inline_ void Neg() + { + m[0][0] = -m[0][0]; m[0][1] = -m[0][1]; m[0][2] = -m[0][2]; + m[1][0] = -m[1][0]; m[1][1] = -m[1][1]; m[1][2] = -m[1][2]; + m[2][0] = -m[2][0]; m[2][1] = -m[2][1]; m[2][2] = -m[2][2]; + } + + //! Neg from another matrix + inline_ void Neg(const Matrix3x3& mat) + { + m[0][0] = -mat.m[0][0]; m[0][1] = -mat.m[0][1]; m[0][2] = -mat.m[0][2]; + m[1][0] = -mat.m[1][0]; m[1][1] = -mat.m[1][1]; m[1][2] = -mat.m[1][2]; + m[2][0] = -mat.m[2][0]; m[2][1] = -mat.m[2][1]; m[2][2] = -mat.m[2][2]; + } + + //! Add another matrix + inline_ void Add(const Matrix3x3& mat) + { + m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2]; + m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2]; + m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2]; + } + + //! Sub another matrix + inline_ void Sub(const Matrix3x3& mat) + { + m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2]; + m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2]; + m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2]; + } + //! Mac + inline_ void Mac(const Matrix3x3& a, const Matrix3x3& b, float s) + { + m[0][0] = a.m[0][0] + b.m[0][0] * s; + m[0][1] = a.m[0][1] + b.m[0][1] * s; + m[0][2] = a.m[0][2] + b.m[0][2] * s; + + m[1][0] = a.m[1][0] + b.m[1][0] * s; + m[1][1] = a.m[1][1] + b.m[1][1] * s; + m[1][2] = a.m[1][2] + b.m[1][2] * s; + + m[2][0] = a.m[2][0] + b.m[2][0] * s; + m[2][1] = a.m[2][1] + b.m[2][1] * s; + m[2][2] = a.m[2][2] + b.m[2][2] * s; + } + //! Mac + inline_ void Mac(const Matrix3x3& a, float s) + { + m[0][0] += a.m[0][0] * s; m[0][1] += a.m[0][1] * s; m[0][2] += a.m[0][2] * s; + m[1][0] += a.m[1][0] * s; m[1][1] += a.m[1][1] * s; m[1][2] += a.m[1][2] * s; + m[2][0] += a.m[2][0] * s; m[2][1] += a.m[2][1] * s; m[2][2] += a.m[2][2] * s; + } + + //! this = A * s + inline_ void Mult(const Matrix3x3& a, float s) + { + m[0][0] = a.m[0][0] * s; m[0][1] = a.m[0][1] * s; m[0][2] = a.m[0][2] * s; + m[1][0] = a.m[1][0] * s; m[1][1] = a.m[1][1] * s; m[1][2] = a.m[1][2] * s; + m[2][0] = a.m[2][0] * s; m[2][1] = a.m[2][1] * s; m[2][2] = a.m[2][2] * s; + } + + inline_ void Add(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] + b.m[0][0]; m[0][1] = a.m[0][1] + b.m[0][1]; m[0][2] = a.m[0][2] + b.m[0][2]; + m[1][0] = a.m[1][0] + b.m[1][0]; m[1][1] = a.m[1][1] + b.m[1][1]; m[1][2] = a.m[1][2] + b.m[1][2]; + m[2][0] = a.m[2][0] + b.m[2][0]; m[2][1] = a.m[2][1] + b.m[2][1]; m[2][2] = a.m[2][2] + b.m[2][2]; + } + + inline_ void Sub(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] - b.m[0][0]; m[0][1] = a.m[0][1] - b.m[0][1]; m[0][2] = a.m[0][2] - b.m[0][2]; + m[1][0] = a.m[1][0] - b.m[1][0]; m[1][1] = a.m[1][1] - b.m[1][1]; m[1][2] = a.m[1][2] - b.m[1][2]; + m[2][0] = a.m[2][0] - b.m[2][0]; m[2][1] = a.m[2][1] - b.m[2][1]; m[2][2] = a.m[2][2] - b.m[2][2]; + } + + //! this = a * b + inline_ void Mult(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[1][0] + a.m[0][2] * b.m[2][0]; + m[0][1] = a.m[0][0] * b.m[0][1] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[2][1]; + m[0][2] = a.m[0][0] * b.m[0][2] + a.m[0][1] * b.m[1][2] + a.m[0][2] * b.m[2][2]; + m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[1][2] * b.m[2][0]; + m[1][1] = a.m[1][0] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[2][1]; + m[1][2] = a.m[1][0] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[1][2] * b.m[2][2]; + m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[1][0] + a.m[2][2] * b.m[2][0]; + m[2][1] = a.m[2][0] * b.m[0][1] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[2][1]; + m[2][2] = a.m[2][0] * b.m[0][2] + a.m[2][1] * b.m[1][2] + a.m[2][2] * b.m[2][2]; + } + + //! this = transpose(a) * b + inline_ void MultAtB(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] * b.m[0][0] + a.m[1][0] * b.m[1][0] + a.m[2][0] * b.m[2][0]; + m[0][1] = a.m[0][0] * b.m[0][1] + a.m[1][0] * b.m[1][1] + a.m[2][0] * b.m[2][1]; + m[0][2] = a.m[0][0] * b.m[0][2] + a.m[1][0] * b.m[1][2] + a.m[2][0] * b.m[2][2]; + m[1][0] = a.m[0][1] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[2][1] * b.m[2][0]; + m[1][1] = a.m[0][1] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[2][1] * b.m[2][1]; + m[1][2] = a.m[0][1] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[2][1] * b.m[2][2]; + m[2][0] = a.m[0][2] * b.m[0][0] + a.m[1][2] * b.m[1][0] + a.m[2][2] * b.m[2][0]; + m[2][1] = a.m[0][2] * b.m[0][1] + a.m[1][2] * b.m[1][1] + a.m[2][2] * b.m[2][1]; + m[2][2] = a.m[0][2] * b.m[0][2] + a.m[1][2] * b.m[1][2] + a.m[2][2] * b.m[2][2]; + } + + //! this = a * transpose(b) + inline_ void MultABt(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[0][1] + a.m[0][2] * b.m[0][2]; + m[0][1] = a.m[0][0] * b.m[1][0] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[1][2]; + m[0][2] = a.m[0][0] * b.m[2][0] + a.m[0][1] * b.m[2][1] + a.m[0][2] * b.m[2][2]; + m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[0][1] + a.m[1][2] * b.m[0][2]; + m[1][1] = a.m[1][0] * b.m[1][0] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[1][2]; + m[1][2] = a.m[1][0] * b.m[2][0] + a.m[1][1] * b.m[2][1] + a.m[1][2] * b.m[2][2]; + m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[0][1] + a.m[2][2] * b.m[0][2]; + m[2][1] = a.m[2][0] * b.m[1][0] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[1][2]; + m[2][2] = a.m[2][0] * b.m[2][0] + a.m[2][1] * b.m[2][1] + a.m[2][2] * b.m[2][2]; + } + + //! Makes a rotation matrix mapping vector "from" to vector "to". + Matrix3x3& FromTo(const Point& from, const Point& to); + + //! Set a rotation matrix around the X axis. + //! 1 0 0 + //! RX = 0 cx sx + //! 0 -sx cx + void RotX(float angle); + //! Set a rotation matrix around the Y axis. + //! cy 0 -sy + //! RY = 0 1 0 + //! sy 0 cy + void RotY(float angle); + //! Set a rotation matrix around the Z axis. + //! cz sz 0 + //! RZ = -sz cz 0 + //! 0 0 1 + void RotZ(float angle); + //! cy sx.sy -sy.cx + //! RY.RX 0 cx sx + //! sy -sx.cy cx.cy + void RotYX(float y, float x); + + //! Make a rotation matrix about an arbitrary axis + Matrix3x3& Rot(float angle, const Point& axis); + + //! Transpose the matrix. + void Transpose() + { + IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]); + IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]); + IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); + } + + //! this = Transpose(a) + void Transpose(const Matrix3x3& a) + { + m[0][0] = a.m[0][0]; m[0][1] = a.m[1][0]; m[0][2] = a.m[2][0]; + m[1][0] = a.m[0][1]; m[1][1] = a.m[1][1]; m[1][2] = a.m[2][1]; + m[2][0] = a.m[0][2]; m[2][1] = a.m[1][2]; m[2][2] = a.m[2][2]; + } + + //! Compute the determinant of the matrix. We use the rule of Sarrus. + float Determinant() const + { + return (m[0][0]*m[1][1]*m[2][2] + m[0][1]*m[1][2]*m[2][0] + m[0][2]*m[1][0]*m[2][1]) + - (m[2][0]*m[1][1]*m[0][2] + m[2][1]*m[1][2]*m[0][0] + m[2][2]*m[1][0]*m[0][1]); + } +/* + //! Compute a cofactor. Used for matrix inversion. + float CoFactor(ubyte row, ubyte column) const + { + static sdword gIndex[3+2] = { 0, 1, 2, 0, 1 }; + return (m[gIndex[row+1]][gIndex[column+1]]*m[gIndex[row+2]][gIndex[column+2]] - m[gIndex[row+2]][gIndex[column+1]]*m[gIndex[row+1]][gIndex[column+2]]); + } +*/ + //! Invert the matrix. Determinant must be different from zero, else matrix can't be inverted. + Matrix3x3& Invert() + { + float Det = Determinant(); // Must be !=0 + float OneOverDet = 1.0f / Det; + + Matrix3x3 Temp; + Temp.m[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDet; + Temp.m[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDet; + Temp.m[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDet; + Temp.m[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDet; + Temp.m[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDet; + Temp.m[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDet; + Temp.m[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDet; + Temp.m[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDet; + Temp.m[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDet; + + *this = Temp; + + return *this; + } + + Matrix3x3& Normalize(); + + //! this = exp(a) + Matrix3x3& Exp(const Matrix3x3& a); + +void FromQuat(const Quat &q); +void FromQuatL2(const Quat &q, float l2); + + // Arithmetic operators + //! Operator for Matrix3x3 Plus = Matrix3x3 + Matrix3x3; + inline_ Matrix3x3 operator+(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0] + mat.m[0][0], m[0][1] + mat.m[0][1], m[0][2] + mat.m[0][2], + m[1][0] + mat.m[1][0], m[1][1] + mat.m[1][1], m[1][2] + mat.m[1][2], + m[2][0] + mat.m[2][0], m[2][1] + mat.m[2][1], m[2][2] + mat.m[2][2]); + } + + //! Operator for Matrix3x3 Minus = Matrix3x3 - Matrix3x3; + inline_ Matrix3x3 operator-(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0] - mat.m[0][0], m[0][1] - mat.m[0][1], m[0][2] - mat.m[0][2], + m[1][0] - mat.m[1][0], m[1][1] - mat.m[1][1], m[1][2] - mat.m[1][2], + m[2][0] - mat.m[2][0], m[2][1] - mat.m[2][1], m[2][2] - mat.m[2][2]); + } + + //! Operator for Matrix3x3 Mul = Matrix3x3 * Matrix3x3; + inline_ Matrix3x3 operator*(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0], + m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1], + m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2], + + m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0], + m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1], + m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2], + + m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0], + m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1], + m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2]); + } + + //! Operator for Point Mul = Matrix3x3 * Point; + inline_ Point operator*(const Point& v) const { return Point(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v); } + + //! Operator for Matrix3x3 Mul = Matrix3x3 * float; + inline_ Matrix3x3 operator*(float s) const + { + return Matrix3x3( + m[0][0]*s, m[0][1]*s, m[0][2]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s); + } + + //! Operator for Matrix3x3 Mul = float * Matrix3x3; + inline_ friend Matrix3x3 operator*(float s, const Matrix3x3& mat) + { + return Matrix3x3( + s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], + s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], + s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2]); + } + + //! Operator for Matrix3x3 Div = Matrix3x3 / float; + inline_ Matrix3x3 operator/(float s) const + { + if (s) s = 1.0f / s; + return Matrix3x3( + m[0][0]*s, m[0][1]*s, m[0][2]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s); + } + + //! Operator for Matrix3x3 Div = float / Matrix3x3; + inline_ friend Matrix3x3 operator/(float s, const Matrix3x3& mat) + { + return Matrix3x3( + s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], + s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], + s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2]); + } + + //! Operator for Matrix3x3 += Matrix3x3 + inline_ Matrix3x3& operator+=(const Matrix3x3& mat) + { + m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2]; + m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2]; + m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 -= Matrix3x3 + inline_ Matrix3x3& operator-=(const Matrix3x3& mat) + { + m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2]; + m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2]; + m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 *= Matrix3x3 + inline_ Matrix3x3& operator*=(const Matrix3x3& mat) + { + Point TempRow; + + GetRow(0, TempRow); + m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + + GetRow(1, TempRow); + m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + + GetRow(2, TempRow); + m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 *= float + inline_ Matrix3x3& operator*=(float s) + { + m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; + m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; + m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; + return *this; + } + + //! Operator for Matrix3x3 /= float + inline_ Matrix3x3& operator/=(float s) + { + if (s) s = 1.0f / s; + m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; + m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; + m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; + return *this; + } + + // Cast operators + //! Cast a Matrix3x3 to a Matrix4x4. + operator Matrix4x4() const; + //! Cast a Matrix3x3 to a Quat. + operator Quat() const; + + inline_ const Point& operator[](int row) const { return *(const Point*)&m[row][0]; } + inline_ Point& operator[](int row) { return *(Point*)&m[row][0]; } + + public: + + float m[3][3]; + }; + +#endif // __ICEMATRIX3X3_H__ + diff --git a/Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.cpp b/Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.cpp new file mode 100644 index 0000000..7e10f45 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.cpp @@ -0,0 +1,152 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 4x4 matrices. + * \file IceMatrix4x4.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 4x4 matrix. + * DirectX-compliant, ie row-column order, ie m[Row][Col]. + * Same as: + * m11 m12 m13 m14 first row. + * m21 m22 m23 m24 second row. + * m31 m32 m33 m34 third row. + * m41 m42 m43 m44 fourth row. + * Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1). + * Stored in memory as m11 m12 m13 m14 m21... + * + * Multiplication rules: + * + * [x'y'z'1] = [xyz1][M] + * + * x' = x*m11 + y*m21 + z*m31 + m41 + * y' = x*m12 + y*m22 + z*m32 + m42 + * z' = x*m13 + y*m23 + z*m33 + m43 + * 1' = 0 + 0 + 0 + m44 + * + * \class Matrix4x4 + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Inverts a PR matrix. (which only contains a rotation and a translation) + * This is faster and less subject to FPU errors than the generic inversion code. + * + * \relates Matrix4x4 + * \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) + * \param dest [out] destination matrix + * \param src [in] source matrix + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) +{ + dest.m[0][0] = src.m[0][0]; + dest.m[1][0] = src.m[0][1]; + dest.m[2][0] = src.m[0][2]; + dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]); + + dest.m[0][1] = src.m[1][0]; + dest.m[1][1] = src.m[1][1]; + dest.m[2][1] = src.m[1][2]; + dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]); + + dest.m[0][2] = src.m[2][0]; + dest.m[1][2] = src.m[2][1]; + dest.m[2][2] = src.m[2][2]; + dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]); + + dest.m[0][3] = 0.0f; + dest.m[1][3] = 0.0f; + dest.m[2][3] = 0.0f; + dest.m[3][3] = 1.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the cofactor of the Matrix at a specified location +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Matrix4x4::CoFactor(udword row, udword col) const +{ + return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] + + m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] + + m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3]) + - (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] + + m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] + + m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the determinant of the Matrix +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Matrix4x4::Determinant() const +{ + return m[0][0] * CoFactor(0, 0) + + m[0][1] * CoFactor(0, 1) + + m[0][2] * CoFactor(0, 2) + + m[0][3] * CoFactor(0, 3); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the inverse of the matrix +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Matrix4x4& Matrix4x4::Invert() +{ + float Det = Determinant(); + Matrix4x4 Temp; + + if(fabsf(Det) < MATRIX4X4_EPSILON) + return *this; // The matrix is not invertible! Singular case! + + float IDet = 1.0f / Det; + + Temp.m[0][0] = CoFactor(0,0) * IDet; + Temp.m[1][0] = CoFactor(0,1) * IDet; + Temp.m[2][0] = CoFactor(0,2) * IDet; + Temp.m[3][0] = CoFactor(0,3) * IDet; + Temp.m[0][1] = CoFactor(1,0) * IDet; + Temp.m[1][1] = CoFactor(1,1) * IDet; + Temp.m[2][1] = CoFactor(1,2) * IDet; + Temp.m[3][1] = CoFactor(1,3) * IDet; + Temp.m[0][2] = CoFactor(2,0) * IDet; + Temp.m[1][2] = CoFactor(2,1) * IDet; + Temp.m[2][2] = CoFactor(2,2) * IDet; + Temp.m[3][2] = CoFactor(2,3) * IDet; + Temp.m[0][3] = CoFactor(3,0) * IDet; + Temp.m[1][3] = CoFactor(3,1) * IDet; + Temp.m[2][3] = CoFactor(3,2) * IDet; + Temp.m[3][3] = CoFactor(3,3) * IDet; + + *this = Temp; + + return *this; +} + + diff --git a/Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.h b/Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.h new file mode 100644 index 0000000..8abc2a7 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceMatrix4x4.h @@ -0,0 +1,471 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 4x4 matrices. + * \file IceMatrix4x4.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEMATRIX4X4_H__ +#define __ICEMATRIX4X4_H__ + + // Forward declarations + class PRS; + class PR; + + #define MATRIX4X4_EPSILON (1.0e-7f) + + class ICEMATHS_API Matrix4x4 + { +// void LUBackwardSubstitution( sdword *indx, float* b ); +// void LUDecomposition( sdword* indx, float* d ); + + public: + //! Empty constructor. + inline_ Matrix4x4() {} + //! Constructor from 16 values + inline_ Matrix4x4( float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; + m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; + } + //! Copy constructor + inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); } + //! Destructor. + inline_ ~Matrix4x4() {} + + //! Assign values (rotation only) + inline_ Matrix4x4& Set( float m00, float m01, float m02, + float m10, float m11, float m12, + float m20, float m21, float m22) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; + return *this; + } + //! Assign values + inline_ Matrix4x4& Set( float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; + m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; + return *this; + } + + //! Copy from a Matrix4x4 + inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); } + + // Row-column access + //! Returns a row. + inline_ void GetRow(const udword r, HPoint& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; p.w=m[r][3]; } + //! Returns a row. + inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; } + //! Returns a row. + inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; } + //! Returns a row. + inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; } + //! Sets a row. + inline_ void SetRow(const udword r, const HPoint& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]=p.w; } + //! Sets a row. + inline_ void SetRow(const udword r, const Point& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]= (r!=3) ? 0.0f : 1.0f; } + //! Returns a column. + inline_ void GetCol(const udword c, HPoint& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; p.w=m[3][c]; } + //! Returns a column. + inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; } + //! Sets a column. + inline_ void SetCol(const udword c, const HPoint& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]=p.w; } + //! Sets a column. + inline_ void SetCol(const udword c, const Point& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]= (c!=3) ? 0.0f : 1.0f; } + + // Translation + //! Returns the translation part of the matrix. + inline_ const HPoint& GetTrans() const { return GetRow(3); } + //! Gets the translation part of the matrix + inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; } + //! Sets the translation part of the matrix, from a Point. + inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; } + //! Sets the translation part of the matrix, from a HPoint. + inline_ void SetTrans(const HPoint& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; m[3][3]=p.w; } + //! Sets the translation part of the matrix, from floats. + inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; } + + // Scale + //! Sets the scale from a Point. The point is put on the diagonal. + inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; } + //! Sets the scale from floats. Values are put on the diagonal. + inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; } + //! Scales from a Point. Each row is multiplied by a component. + void Scale(const Point& p) + { + m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z; + m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z; + m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z; + } + //! Scales from floats. Each row is multiplied by a value. + void Scale(float sx, float sy, float sz) + { + m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz; + m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz; + m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz; + } +/* + //! Returns a row. + inline_ HPoint GetRow(const udword row) const { return mRow[row]; } + //! Sets a row. + inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; } + //! Sets a row. + Matrix4x4& SetRow(const udword row, const Point& p) + { + m[row][0] = p.x; + m[row][1] = p.y; + m[row][2] = p.z; + m[row][3] = (row != 3) ? 0.0f : 1.0f; + return *this; + } + //! Returns a column. + HPoint GetCol(const udword col) const + { + HPoint Res; + Res.x = m[0][col]; + Res.y = m[1][col]; + Res.z = m[2][col]; + Res.w = m[3][col]; + return Res; + } + //! Sets a column. + Matrix4x4& SetCol(const udword col, const HPoint& p) + { + m[0][col] = p.x; + m[1][col] = p.y; + m[2][col] = p.z; + m[3][col] = p.w; + return *this; + } + //! Sets a column. + Matrix4x4& SetCol(const udword col, const Point& p) + { + m[0][col] = p.x; + m[1][col] = p.y; + m[2][col] = p.z; + m[3][col] = (col != 3) ? 0.0f : 1.0f; + return *this; + } +*/ + //! Computes the trace. The trace is the sum of the 4 diagonal components. + inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; } + //! Computes the trace of the upper 3x3 matrix. + inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; } + //! Clears the matrix. + inline_ void Zero() { ZeroMemory(&m, sizeof(m)); } + //! Sets the identity matrix. + inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; } + //! Checks for identity + inline_ bool IsIdentity() const + { + if(IR(m[0][0])!=IEEE_1_0) return false; + if(IR(m[0][1])!=0) return false; + if(IR(m[0][2])!=0) return false; + if(IR(m[0][3])!=0) return false; + + if(IR(m[1][0])!=0) return false; + if(IR(m[1][1])!=IEEE_1_0) return false; + if(IR(m[1][2])!=0) return false; + if(IR(m[1][3])!=0) return false; + + if(IR(m[2][0])!=0) return false; + if(IR(m[2][1])!=0) return false; + if(IR(m[2][2])!=IEEE_1_0) return false; + if(IR(m[2][3])!=0) return false; + + if(IR(m[3][0])!=0) return false; + if(IR(m[3][1])!=0) return false; + if(IR(m[3][2])!=0) return false; + if(IR(m[3][3])!=IEEE_1_0) return false; + return true; + } + + //! Checks matrix validity + inline_ BOOL IsValid() const + { + for(udword j=0;j<4;j++) + { + for(udword i=0;i<4;i++) + { + if(!IsValidFloat(m[j][i])) return FALSE; + } + } + return TRUE; + } + + //! Sets a rotation matrix around the X axis. + void RotX(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[1][1] = m[2][2] = Cos; m[2][1] = -Sin; m[1][2] = Sin; } + //! Sets a rotation matrix around the Y axis. + void RotY(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[2][2] = Cos; m[2][0] = Sin; m[0][2] = -Sin; } + //! Sets a rotation matrix around the Z axis. + void RotZ(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[1][1] = Cos; m[1][0] = -Sin; m[0][1] = Sin; } + + //! Makes a rotation matrix about an arbitrary axis + Matrix4x4& Rot(float angle, Point& p1, Point& p2); + + //! Transposes the matrix. + void Transpose() + { + IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]); + IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]); + IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]); + IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); + IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]); + IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(m[3][2]); + } + + //! Computes a cofactor. Used for matrix inversion. + float CoFactor(udword row, udword col) const; + //! Computes the determinant of the matrix. + float Determinant() const; + //! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted. + Matrix4x4& Invert(); +// Matrix& ComputeAxisMatrix(Point& axis, float angle); + + // Cast operators + //! Casts a Matrix4x4 to a Matrix3x3. + inline_ operator Matrix3x3() const + { + return Matrix3x3( + m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2]); + } + //! Casts a Matrix4x4 to a Quat. + operator Quat() const; + //! Casts a Matrix4x4 to a PR. + operator PR() const; + + // Arithmetic operators + //! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4; + inline_ Matrix4x4 operator+(const Matrix4x4& mat) const + { + return Matrix4x4( + m[0][0]+mat.m[0][0], m[0][1]+mat.m[0][1], m[0][2]+mat.m[0][2], m[0][3]+mat.m[0][3], + m[1][0]+mat.m[1][0], m[1][1]+mat.m[1][1], m[1][2]+mat.m[1][2], m[1][3]+mat.m[1][3], + m[2][0]+mat.m[2][0], m[2][1]+mat.m[2][1], m[2][2]+mat.m[2][2], m[2][3]+mat.m[2][3], + m[3][0]+mat.m[3][0], m[3][1]+mat.m[3][1], m[3][2]+mat.m[3][2], m[3][3]+mat.m[3][3]); + } + + //! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4; + inline_ Matrix4x4 operator-(const Matrix4x4& mat) const + { + return Matrix4x4( + m[0][0]-mat.m[0][0], m[0][1]-mat.m[0][1], m[0][2]-mat.m[0][2], m[0][3]-mat.m[0][3], + m[1][0]-mat.m[1][0], m[1][1]-mat.m[1][1], m[1][2]-mat.m[1][2], m[1][3]-mat.m[1][3], + m[2][0]-mat.m[2][0], m[2][1]-mat.m[2][1], m[2][2]-mat.m[2][2], m[2][3]-mat.m[2][3], + m[3][0]-mat.m[3][0], m[3][1]-mat.m[3][1], m[3][2]-mat.m[3][2], m[3][3]-mat.m[3][3]); + } + + //! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4; + inline_ Matrix4x4 operator*(const Matrix4x4& mat) const + { + return Matrix4x4( + m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0] + m[0][3]*mat.m[3][0], + m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1] + m[0][3]*mat.m[3][1], + m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2] + m[0][3]*mat.m[3][2], + m[0][0]*mat.m[0][3] + m[0][1]*mat.m[1][3] + m[0][2]*mat.m[2][3] + m[0][3]*mat.m[3][3], + + m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0] + m[1][3]*mat.m[3][0], + m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1] + m[1][3]*mat.m[3][1], + m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2] + m[1][3]*mat.m[3][2], + m[1][0]*mat.m[0][3] + m[1][1]*mat.m[1][3] + m[1][2]*mat.m[2][3] + m[1][3]*mat.m[3][3], + + m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0] + m[2][3]*mat.m[3][0], + m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1] + m[2][3]*mat.m[3][1], + m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2] + m[2][3]*mat.m[3][2], + m[2][0]*mat.m[0][3] + m[2][1]*mat.m[1][3] + m[2][2]*mat.m[2][3] + m[2][3]*mat.m[3][3], + + m[3][0]*mat.m[0][0] + m[3][1]*mat.m[1][0] + m[3][2]*mat.m[2][0] + m[3][3]*mat.m[3][0], + m[3][0]*mat.m[0][1] + m[3][1]*mat.m[1][1] + m[3][2]*mat.m[2][1] + m[3][3]*mat.m[3][1], + m[3][0]*mat.m[0][2] + m[3][1]*mat.m[1][2] + m[3][2]*mat.m[2][2] + m[3][3]*mat.m[3][2], + m[3][0]*mat.m[0][3] + m[3][1]*mat.m[1][3] + m[3][2]*mat.m[2][3] + m[3][3]*mat.m[3][3]); + } + + //! Operator for HPoint Mul = Matrix4x4 * HPoint; + inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); } + + //! Operator for Point Mul = Matrix4x4 * Point; + inline_ Point operator*(const Point& v) const + { + return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3], + m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3], + m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] ); + } + + //! Operator for Matrix4x4 Scale = Matrix4x4 * float; + inline_ Matrix4x4 operator*(float s) const + { + return Matrix4x4( + m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, + m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); + } + + //! Operator for Matrix4x4 Scale = float * Matrix4x4; + inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat) + { + return Matrix4x4( + s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3], + s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3], + s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3], + s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]); + } + + //! Operator for Matrix4x4 Div = Matrix4x4 / float; + inline_ Matrix4x4 operator/(float s) const + { + if(s) s = 1.0f / s; + + return Matrix4x4( + m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, + m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); + } + + //! Operator for Matrix4x4 Div = float / Matrix4x4; + inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat) + { + return Matrix4x4( + s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3], + s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3], + s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3], + s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]); + } + + //! Operator for Matrix4x4 += Matrix4x4; + inline_ Matrix4x4& operator+=(const Matrix4x4& mat) + { + m[0][0]+=mat.m[0][0]; m[0][1]+=mat.m[0][1]; m[0][2]+=mat.m[0][2]; m[0][3]+=mat.m[0][3]; + m[1][0]+=mat.m[1][0]; m[1][1]+=mat.m[1][1]; m[1][2]+=mat.m[1][2]; m[1][3]+=mat.m[1][3]; + m[2][0]+=mat.m[2][0]; m[2][1]+=mat.m[2][1]; m[2][2]+=mat.m[2][2]; m[2][3]+=mat.m[2][3]; + m[3][0]+=mat.m[3][0]; m[3][1]+=mat.m[3][1]; m[3][2]+=mat.m[3][2]; m[3][3]+=mat.m[3][3]; + return *this; + } + + //! Operator for Matrix4x4 -= Matrix4x4; + inline_ Matrix4x4& operator-=(const Matrix4x4& mat) + { + m[0][0]-=mat.m[0][0]; m[0][1]-=mat.m[0][1]; m[0][2]-=mat.m[0][2]; m[0][3]-=mat.m[0][3]; + m[1][0]-=mat.m[1][0]; m[1][1]-=mat.m[1][1]; m[1][2]-=mat.m[1][2]; m[1][3]-=mat.m[1][3]; + m[2][0]-=mat.m[2][0]; m[2][1]-=mat.m[2][1]; m[2][2]-=mat.m[2][2]; m[2][3]-=mat.m[2][3]; + m[3][0]-=mat.m[3][0]; m[3][1]-=mat.m[3][1]; m[3][2]-=mat.m[3][2]; m[3][3]-=mat.m[3][3]; + return *this; + } + + //! Operator for Matrix4x4 *= Matrix4x4; + Matrix4x4& operator*=(const Matrix4x4& mat) + { + HPoint TempRow; + + GetRow(0, TempRow); + m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[0][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + GetRow(1, TempRow); + m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[1][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + GetRow(2, TempRow); + m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[2][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + GetRow(3, TempRow); + m[3][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[3][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[3][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[3][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + return *this; + } + + //! Operator for Matrix4x4 *= float; + inline_ Matrix4x4& operator*=(float s) + { + m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; + m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; + m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; + m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; + return *this; + } + + //! Operator for Matrix4x4 /= float; + inline_ Matrix4x4& operator/=(float s) + { + if(s) s = 1.0f / s; + m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; + m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; + m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; + m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; + return *this; + } + + inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; } + inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; } + + public: + + float m[4][4]; + }; + + //! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix + inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot) + { + dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; + dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; + dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; + } + + //! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix + inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot) + { + dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; + dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; + dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; + } + + ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src); + +#endif // __ICEMATRIX4X4_H__ + diff --git a/Extras/CDTestFramework/Opcode/Ice/IceMemoryMacros.h b/Extras/CDTestFramework/Opcode/Ice/IceMemoryMacros.h new file mode 100644 index 0000000..3f24975 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceMemoryMacros.h @@ -0,0 +1,180 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains all memory macros. + * \file IceMemoryMacros.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef ICEMEMORYMACROS_H +#define ICEMEMORYMACROS_H + +#undef ZeroMemory +#undef CopyMemory +#undef MoveMemory +#undef FillMemory + + //! Clears a buffer. + //! \param addr [in] buffer address + //! \param size [in] buffer length + //! \see FillMemory + //! \see StoreDwords + //! \see CopyMemory + //! \see MoveMemory + inline_ void ZeroMemory(void* addr, regsize size) { memset(addr, 0, size); } + + //! Fills a buffer with a given byte. + //! \param addr [in] buffer address + //! \param size [in] buffer length + //! \param val [in] the byte value + //! \see StoreDwords + //! \see ZeroMemory + //! \see CopyMemory + //! \see MoveMemory + inline_ void FillMemory(void* dest, regsize size, ubyte val) { memset(dest, val, size); } + + //! Fills a buffer with a given dword. + //! \param addr [in] buffer address + //! \param nb [in] number of dwords to write + //! \param value [in] the dword value + //! \see FillMemory + //! \see ZeroMemory + //! \see CopyMemory + //! \see MoveMemory + //! \warning writes nb*4 bytes ! + inline_ void StoreDwords(udword* dest, udword nb, udword value) + { + // The asm code below **SHOULD** be equivalent to one of those C versions + // or the other if your compiled is good: (checked on VC++ 6.0) + // + // 1) while(nb--) *dest++ = value; + // + // 2) for(udword i=0;iRelease(); (x) = null; } + + //! Safe ICE-style release + #define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; } + +#ifdef ICEERROR_H + //! Standard alloc checking. HANDLE WITH CARE. Relies on strict coding rules. Probably shouldn't be used outside of ICE. + #define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY); +#else + #define CHECKALLOC(x) if(!x) return false; +#endif + + //! Standard allocation cycle + #define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr); + #define SAFE_ICE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = ICE_NEW(type)[count]; CHECKALLOC(ptr); + + //! Don't use inline for alloca !!! +#ifdef WIN32 + #define StackAlloc(x) _alloca(x) +#elif LINUX + #define StackAlloc(x) alloca(x) +#elif defined(__APPLE__) + #define StackAlloc(x) alloca(x) +#elif defined(_XBOX) + #define StackAlloc(x) _alloca(x) +#endif + +#ifdef _DEBUG +// #define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_TEMP) +// #define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #x, MEMORY_PERSISTENT) + #define ICE_ALLOC_TMP(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_TEMP) + #define ICE_ALLOC(x) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, "(undefined)", MEMORY_PERSISTENT) + #define ICE_ALLOC_TMP2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_TEMP) + #define ICE_ALLOC2(x, y) GetAllocator()->mallocDebug(x, __FILE__, __LINE__, #y, MEMORY_PERSISTENT) +#else + #define ICE_ALLOC_TMP(x) GetAllocator()->malloc(x, MEMORY_TEMP) + #define ICE_ALLOC(x) GetAllocator()->malloc(x, MEMORY_PERSISTENT) +#endif + #define ICE_FREE(x) if(x) { GetAllocator()->free(x); x = null; } + +#ifdef DONT_TRACK_MEMORY_LEAKS + #ifdef _DEBUG + #define ICE_NEW_TMP(x) new(__FILE__, __LINE__, #x, MEMORY_TEMP) x + #define ICE_NEW(x) new(__FILE__, __LINE__, #x, MEMORY_PERSISTENT) x + #else + #define ICE_NEW_TMP(x) new(MEMORY_TEMP) x + #define ICE_NEW(x) new(MEMORY_PERSISTENT) x + #endif +#else + #define ICE_NEW_TMP(x) new x + #define ICE_NEW(x) new x +#endif + +#endif // ICEMEMORYMACROS_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceOBB.cpp b/Extras/CDTestFramework/Opcode/Ice/IceOBB.cpp new file mode 100644 index 0000000..7956321 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceOBB.cpp @@ -0,0 +1,339 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains OBB-related code. + * \file IceOBB.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * An Oriented Bounding Box (OBB). + * \class OBB + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Tests if a point is contained within the OBB. + * \param p [in] the world point to test + * \return true if inside the OBB + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ContainsPoint(const Point& p) const +{ + // Point in OBB test using lazy evaluation and early exits + + // Translate to box space + Point RelPoint = p - mCenter; + + // Point * mRot maps from box space to world space + // mRot * Point maps from world space to box space (what we need here) + + float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z; + if(f >= mExtents.x || f <= -mExtents.x) return false; + + f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z; + if(f >= mExtents.y || f <= -mExtents.y) return false; + + f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z; + if(f >= mExtents.z || f <= -mExtents.z) return false; + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds an OBB from an AABB and a world transform. + * \param aabb [in] the aabb + * \param mat [in] the world transform + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBB::Create(const AABB& aabb, const Matrix4x4& mat) +{ + // Note: must be coherent with Rotate() + + aabb.GetCenter(mCenter); + aabb.GetExtents(mExtents); + // Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity). + + // So following what's done in Rotate: + // - x-form the center + mCenter *= mat; + // - combine rotation with identity, i.e. just use given matrix + mRot = mat; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the obb planes. + * \param planes [out] 6 box planes + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ComputePlanes(Plane* planes) const +{ + // Checkings + if(!planes) return false; + + Point Axis0 = mRot[0]; + Point Axis1 = mRot[1]; + Point Axis2 = mRot[2]; + + // Writes normals + planes[0].n = Axis0; + planes[1].n = -Axis0; + planes[2].n = Axis1; + planes[3].n = -Axis1; + planes[4].n = Axis2; + planes[5].n = -Axis2; + + // Compute a point on each plane + Point p0 = mCenter + Axis0 * mExtents.x; + Point p1 = mCenter - Axis0 * mExtents.x; + Point p2 = mCenter + Axis1 * mExtents.y; + Point p3 = mCenter - Axis1 * mExtents.y; + Point p4 = mCenter + Axis2 * mExtents.z; + Point p5 = mCenter - Axis2 * mExtents.z; + + // Compute d + planes[0].d = -(planes[0].n|p0); + planes[1].d = -(planes[1].n|p1); + planes[2].d = -(planes[2].n|p2); + planes[3].d = -(planes[3].n|p3); + planes[4].d = -(planes[4].n|p4); + planes[5].d = -(planes[5].n|p5); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the obb points. + * \param pts [out] 8 box points + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ComputePoints(Point* pts) const +{ + // Checkings + if(!pts) return false; + + Point Axis0 = mRot[0]; + Point Axis1 = mRot[1]; + Point Axis2 = mRot[2]; + + Axis0 *= mExtents.x; + Axis1 *= mExtents.y; + Axis2 *= mExtents.z; + + // 7+------+6 0 = --- + // /| /| 1 = +-- + // / | / | 2 = ++- + // / 4+---/--+5 3 = -+- + // 3+------+2 / y z 4 = --+ + // | / | / | / 5 = +-+ + // |/ |/ |/ 6 = +++ + // 0+------+1 *---x 7 = -++ + + pts[0] = mCenter - Axis0 - Axis1 - Axis2; + pts[1] = mCenter + Axis0 - Axis1 - Axis2; + pts[2] = mCenter + Axis0 + Axis1 - Axis2; + pts[3] = mCenter - Axis0 + Axis1 - Axis2; + pts[4] = mCenter - Axis0 - Axis1 + Axis2; + pts[5] = mCenter + Axis0 - Axis1 + Axis2; + pts[6] = mCenter + Axis0 + Axis1 + Axis2; + pts[7] = mCenter - Axis0 + Axis1 + Axis2; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes vertex normals. + * \param pts [out] 8 box points + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ComputeVertexNormals(Point* pts) const +{ + static float VertexNormals[] = + { + -INVSQRT3, -INVSQRT3, -INVSQRT3, + INVSQRT3, -INVSQRT3, -INVSQRT3, + INVSQRT3, INVSQRT3, -INVSQRT3, + -INVSQRT3, INVSQRT3, -INVSQRT3, + -INVSQRT3, -INVSQRT3, INVSQRT3, + INVSQRT3, -INVSQRT3, INVSQRT3, + INVSQRT3, INVSQRT3, INVSQRT3, + -INVSQRT3, INVSQRT3, INVSQRT3 + }; + + if(!pts) return false; + + const Point* VN = (const Point*)VertexNormals; + for(udword i=0;i<8;i++) + { + pts[i] = VN[i] * mRot; + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns edges. + * \return 24 indices (12 edges) indexing the list returned by ComputePoints() + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const udword* OBB::GetEdges() const +{ + static udword Indices[] = { + 0, 1, 1, 2, 2, 3, 3, 0, + 7, 6, 6, 5, 5, 4, 4, 7, + 1, 5, 6, 2, + 3, 7, 4, 0 + }; + return Indices; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns local edge normals. + * \return edge normals in local space + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const Point* OBB::GetLocalEdgeNormals() const +{ + static float EdgeNormals[] = + { + 0, -INVSQRT2, -INVSQRT2, // 0-1 + INVSQRT2, 0, -INVSQRT2, // 1-2 + 0, INVSQRT2, -INVSQRT2, // 2-3 + -INVSQRT2, 0, -INVSQRT2, // 3-0 + + 0, INVSQRT2, INVSQRT2, // 7-6 + INVSQRT2, 0, INVSQRT2, // 6-5 + 0, -INVSQRT2, INVSQRT2, // 5-4 + -INVSQRT2, 0, INVSQRT2, // 4-7 + + INVSQRT2, -INVSQRT2, 0, // 1-5 + INVSQRT2, INVSQRT2, 0, // 6-2 + -INVSQRT2, INVSQRT2, 0, // 3-7 + -INVSQRT2, -INVSQRT2, 0 // 4-0 + }; + return (const Point*)EdgeNormals; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns world edge normal + * \param edge_index [in] 0 <= edge index < 12 + * \param world_normal [out] edge normal in world space + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBB::ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const +{ + ASSERT(edge_index<12); + world_normal = GetLocalEdgeNormals()[edge_index] * mRot; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes an LSS surrounding the OBB. + * \param lss [out] the LSS + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBB::ComputeLSS(LSS& lss) const +{ + Point Axis0 = mRot[0]; + Point Axis1 = mRot[1]; + Point Axis2 = mRot[2]; + + switch(mExtents.LargestAxis()) + { + case 0: + lss.mRadius = (mExtents.y + mExtents.z)*0.5f; + lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius); + lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius); + break; + case 1: + lss.mRadius = (mExtents.x + mExtents.z)*0.5f; + lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius); + lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius); + break; + case 2: + lss.mRadius = (mExtents.x + mExtents.y)*0.5f; + lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius); + lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius); + break; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the OBB is inside another OBB. + * \param box [in] the other OBB + * \return TRUE if we're inside the other box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL OBB::IsInside(const OBB& box) const +{ + // Make a 4x4 from the box & inverse it + Matrix4x4 M0Inv; + { + Matrix4x4 M0 = box.mRot; + M0.SetTrans(box.mCenter); + InvertPRMatrix(M0Inv, M0); + } + + // With our inversed 4x4, create box1 in space of box0 + OBB _1in0; + Rotate(M0Inv, _1in0); + + // This should cancel out box0's rotation, i.e. it's now an AABB. + // => Center(0,0,0), Rot(identity) + + // The two boxes are in the same space so now we can compare them. + + // Create the AABB of (box1 in space of box0) + const Matrix3x3& mtx = _1in0.mRot; + + float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x; + if(f > _1in0.mCenter.x) return FALSE; + if(-f < _1in0.mCenter.x) return FALSE; + + f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y; + if(f > _1in0.mCenter.y) return FALSE; + if(-f < _1in0.mCenter.y) return FALSE; + + f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z; + if(f > _1in0.mCenter.z) return FALSE; + if(-f < _1in0.mCenter.z) return FALSE; + + return TRUE; +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceOBB.h b/Extras/CDTestFramework/Opcode/Ice/IceOBB.h new file mode 100644 index 0000000..28ad400 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceOBB.h @@ -0,0 +1,193 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains OBB-related code. (oriented bounding box) + * \file IceOBB.h + * \author Pierre Terdiman + * \date January, 13, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEOBB_H__ +#define __ICEOBB_H__ + + // Forward declarations + class LSS; + + class ICEMATHS_API OBB + { + public: + //! Constructor + inline_ OBB() {} + //! Constructor + inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {} + //! Destructor + inline_ ~OBB() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty OBB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() + { + mCenter.Zero(); + mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + mRot.Identity(); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the OBB. + * \param p [in] the world point to test + * \return true if inside the OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ContainsPoint(const Point& p) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds an OBB from an AABB and a world transform. + * \param aabb [in] the aabb + * \param mat [in] the world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Create(const AABB& aabb, const Matrix4x4& mat); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the OBB after an arbitrary transform by a 4x4 matrix. + * \param mtx [in] the transform matrix + * \param obb [out] the transformed OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const + { + // The extents remain constant + obb.mExtents = mExtents; + // The center gets x-formed + obb.mCenter = mCenter * mtx; + // Combine rotations + obb.mRot = mRot * Matrix3x3(mtx); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the OBB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f + if(mExtents.x < 0.0f) return FALSE; + if(mExtents.y < 0.0f) return FALSE; + if(mExtents.z < 0.0f) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the obb planes. + * \param planes [out] 6 box planes + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputePlanes(Plane* planes) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the obb points. + * \param pts [out] 8 box points + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputePoints(Point* pts) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes vertex normals. + * \param pts [out] 8 box points + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputeVertexNormals(Point* pts) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns edges. + * \return 24 indices (12 edges) indexing the list returned by ComputePoints() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + const udword* GetEdges() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns local edge normals. + * \return edge normals in local space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + const Point* GetLocalEdgeNormals() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns world edge normal + * \param edge_index [in] 0 <= edge index < 12 + * \param world_normal [out] edge normal in world space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes an LSS surrounding the OBB. + * \param lss [out] the LSS + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeLSS(LSS& lss) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the OBB is inside another OBB. + * \param box [in] the other OBB + * \return TRUE if we're inside the other box + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + BOOL IsInside(const OBB& box) const; + + inline_ const Point& GetCenter() const { return mCenter; } + inline_ const Point& GetExtents() const { return mExtents; } + inline_ const Matrix3x3& GetRot() const { return mRot; } + + inline_ void GetRotatedExtents(Matrix3x3& extents) const + { + extents = mRot; + extents.Scale(mExtents); + } + + Point mCenter; //!< B for Box + Point mExtents; //!< B for Bounding + Matrix3x3 mRot; //!< O for Oriented + + // Orientation is stored in row-major format, + // i.e. rows = eigen vectors of the covariance matrix + }; + +#endif // __ICEOBB_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IcePairs.h b/Extras/CDTestFramework/Opcode/Ice/IcePairs.h new file mode 100644 index 0000000..6817c33 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IcePairs.h @@ -0,0 +1,61 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a simple pair class. + * \file IcePairs.h + * \author Pierre Terdiman + * \date January, 13, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPAIRS_H__ +#define __ICEPAIRS_H__ + + //! A generic couple structure + struct ICECORE_API Pair + { + inline_ Pair() {} + inline_ Pair(udword i0, udword i1) : id0(i0), id1(i1) {} + + udword id0; //!< First index of the pair + udword id1; //!< Second index of the pair + }; + + class ICECORE_API Pairs : private Container + { + public: + // Constructor / Destructor + Pairs() {} + ~Pairs() {} + + inline_ udword GetNbPairs() const { return GetNbEntries()>>1; } + inline_ const Pair* GetPairs() const { return (const Pair*)GetEntries(); } + inline_ const Pair* GetPair(udword i) const { return (const Pair*)&GetEntries()[i+i]; } + + inline_ BOOL HasPairs() const { return IsNotEmpty(); } + + inline_ void ResetPairs() { Reset(); } + inline_ void DeleteLastPair() { DeleteLastEntry(); DeleteLastEntry(); } + + inline_ void AddPair(const Pair& p) { Add(p.id0).Add(p.id1); } + inline_ void AddPair(udword id0, udword id1) { Add(id0).Add(id1); } + }; + +#endif // __ICEPAIRS_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IcePlane.cpp b/Extras/CDTestFramework/Opcode/Ice/IcePlane.cpp new file mode 100644 index 0000000..b7fe652 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IcePlane.cpp @@ -0,0 +1,61 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for planes. + * \file IcePlane.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Plane class. + * \class Plane + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the plane equation from 3 points. + * \param p0 [in] first point + * \param p1 [in] second point + * \param p2 [in] third point + * \return Self-reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Plane& Plane::Set(const Point& p0, const Point& p1, const Point& p2) +{ + Point Edge0 = p1 - p0; + Point Edge1 = p2 - p0; + + n = Edge0 ^ Edge1; + n.Normalize(); + + d = -(p0 | n); + + return *this; +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IcePlane.h b/Extras/CDTestFramework/Opcode/Ice/IcePlane.h new file mode 100644 index 0000000..1f3669b --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IcePlane.h @@ -0,0 +1,129 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for planes. + * \file IcePlane.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPLANE_H__ +#define __ICEPLANE_H__ + + #define PLANE_EPSILON (1.0e-7f) + + class ICEMATHS_API Plane + { + public: + //! Constructor + inline_ Plane() { } + //! Constructor from a normal and a distance + inline_ Plane(float nx, float ny, float nz, float d) { Set(nx, ny, nz, d); } + //! Constructor from a point on the plane and a normal + inline_ Plane(const Point& p, const Point& n) { Set(p, n); } + //! Constructor from three points + inline_ Plane(const Point& p0, const Point& p1, const Point& p2) { Set(p0, p1, p2); } + //! Constructor from a normal and a distance + inline_ Plane(const Point& _n, float _d) { n = _n; d = _d; } + //! Copy constructor + inline_ Plane(const Plane& plane) : n(plane.n), d(plane.d) { } + //! Destructor + inline_ ~Plane() { } + + inline_ Plane& Zero() { n.Zero(); d = 0.0f; return *this; } + inline_ Plane& Set(float nx, float ny, float nz, float _d) { n.Set(nx, ny, nz); d = _d; return *this; } + inline_ Plane& Set(const Point& p, const Point& _n) { n = _n; d = - p | _n; return *this; } + Plane& Set(const Point& p0, const Point& p1, const Point& p2); + + inline_ float Distance(const Point& p) const { return (p | n) + d; } + inline_ bool Belongs(const Point& p) const { return fabsf(Distance(p)) < PLANE_EPSILON; } + + inline_ void Normalize() + { + float Denom = 1.0f / n.Magnitude(); + n.x *= Denom; + n.y *= Denom; + n.z *= Denom; + d *= Denom; + } + public: + // Members + Point n; //!< The normal to the plane + float d; //!< The distance from the origin + + // Cast operators + inline_ operator Point() const { return n; } + inline_ operator HPoint() const { return HPoint(n, d); } + + // Arithmetic operators + inline_ Plane operator*(const Matrix4x4& m) const + { + // Old code from Irion. Kept for reference. + Plane Ret(*this); + return Ret *= m; + } + + inline_ Plane& operator*=(const Matrix4x4& m) + { + // Old code from Irion. Kept for reference. + Point n2 = HPoint(n, 0.0f) * m; + d = -((Point) (HPoint( -d*n, 1.0f ) * m) | n2); + n = n2; + return *this; + } + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster. + * \param transformed [out] transformed plane + * \param plane [in] source plane + * \param transform [in] transform matrix + * \warning the plane normal must be unit-length + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void TransformPlane(Plane& transformed, const Plane& plane, const Matrix4x4& transform) + { + // Rotate the normal using the rotation part of the 4x4 matrix + transformed.n = plane.n * Matrix3x3(transform); + + // Compute new d + transformed.d = plane.d - (Point(transform.GetTrans())|transformed.n); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster. + * \param plane [in/out] source plane (transformed on return) + * \param transform [in] transform matrix + * \warning the plane normal must be unit-length + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void TransformPlane(Plane& plane, const Matrix4x4& transform) + { + // Rotate the normal using the rotation part of the 4x4 matrix + plane.n *= Matrix3x3(transform); + + // Compute new d + plane.d -= Point(transform.GetTrans())|plane.n; + } + +#endif // __ICEPLANE_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IcePoint.cpp b/Extras/CDTestFramework/Opcode/Ice/IcePoint.cpp new file mode 100644 index 0000000..5fcbd52 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IcePoint.cpp @@ -0,0 +1,209 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3D vectors. + * \file IcePoint.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 3D point. + * + * The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3". + * So the choice was between "Point" and "Vector3", the first one looked better (IMHO). + * + * Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3; + * This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out: + * + * \code + * Point P0,P1 = some 3D points; + * Point Delta = P1 - P0; + * \endcode + * + * This compiles fine, although you should have written: + * + * \code + * Point P0,P1 = some 3D points; + * Vector3 Delta = P1 - P0; + * \endcode + * + * Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake + * from the author or something you don't get. + * + * One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors. + * But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work. + * + * Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store + * your model's vertices and in most cases, you really want to use Points to save ram. + * + * \class Point + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Creates a positive unit random vector. + * \return Self-reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point& Point::PositiveUnitRandomVector() +{ + x = UnitRandomFloat(); + y = UnitRandomFloat(); + z = UnitRandomFloat(); + Normalize(); + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Creates a unit random vector. + * \return Self-reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point& Point::UnitRandomVector() +{ + x = UnitRandomFloat() - 0.5f; + y = UnitRandomFloat() - 0.5f; + z = UnitRandomFloat() - 0.5f; + Normalize(); + return *this; +} + +// Cast operator +// WARNING: not inlined +Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); } + +Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted) +{ + // Point EyePt = eye position + // Point p = current vertex + // Point n = vertex normal + // Point rv = refracted vector + // Eye vector - doesn't need to be normalized + Point Env; + Env.x = eye.x - x; + Env.y = eye.y - y; + Env.z = eye.z - z; + + float NDotE = n|Env; + float NDotN = n|n; + NDotE /= refractindex; + + // Refracted vector + refracted = n*NDotE - Env*NDotN; + + return *this; +} + +Point& Point::ProjectToPlane(const Plane& p) +{ + *this-= (p.d + (*this|p.n))*p.n; + return *this; +} + +void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const +{ + projected = HPoint(x, y, z, 1.0f) * mat; + projected.w = 1.0f / projected.w; + + projected.x*=projected.w; + projected.y*=projected.w; + projected.z*=projected.w; + + projected.x *= halfrenderwidth; projected.x += halfrenderwidth; + projected.y *= -halfrenderheight; projected.y += halfrenderheight; +} + +void Point::SetNotUsed() +{ + // We use a particular integer pattern : 0xffffffff everywhere. This is a NAN. + IR(x) = 0xffffffff; + IR(y) = 0xffffffff; + IR(z) = 0xffffffff; +} + +BOOL Point::IsNotUsed() const +{ + if(IR(x)!=0xffffffff) return FALSE; + if(IR(y)!=0xffffffff) return FALSE; + if(IR(z)!=0xffffffff) return FALSE; + return TRUE; +} + +Point& Point::Mult(const Matrix3x3& mat, const Point& a) +{ + x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; + y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; + z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; + return *this; +} + +Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2) +{ + x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2]; + y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2]; + z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2]; + return *this; +} + +Point& Point::Mac(const Matrix3x3& mat, const Point& a) +{ + x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; + y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; + z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; + return *this; +} + +Point& Point::TransMult(const Matrix3x3& mat, const Point& a) +{ + x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0]; + y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1]; + z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2]; + return *this; +} + +Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) +{ + x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x; + y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y; + z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z; + return *this; +} + +Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) +{ + float sx = r.x - linpos.x; + float sy = r.y - linpos.y; + float sz = r.z - linpos.z; + x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0]; + y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1]; + z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2]; + return *this; +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IcePoint.h b/Extras/CDTestFramework/Opcode/Ice/IcePoint.h new file mode 100644 index 0000000..a5b372b --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IcePoint.h @@ -0,0 +1,544 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3D vectors. + * \file IcePoint.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPOINT_H__ +#define __ICEPOINT_H__ + + // Forward declarations + class HPoint; + class Plane; + class Matrix3x3; + class Matrix4x4; + + #define CROSS2D(a, b) (a.x*b.y - b.x*a.y) + + const float EPSILON2 = 1.0e-20f; + + class ICEMATHS_API Point + { + public: + + //! Empty constructor + inline_ Point() {} + //! Constructor from a single float +// inline_ Point(float val) : x(val), y(val), z(val) {} +// Removed since it introduced the nasty "Point T = *Matrix4x4.GetTrans();" bug....... + //! Constructor from floats + inline_ Point(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} + //! Constructor from array + inline_ Point(const float f[3]) : x(f[_X]), y(f[_Y]), z(f[_Z]) {} + //! Copy constructor + inline_ Point(const Point& p) : x(p.x), y(p.y), z(p.z) {} + //! Destructor + inline_ ~Point() {} + + //! Clears the vector + inline_ Point& Zero() { x = y = z = 0.0f; return *this; } + + //! + infinity + inline_ Point& SetPlusInfinity() { x = y = z = MAX_FLOAT; return *this; } + //! - infinity + inline_ Point& SetMinusInfinity() { x = y = z = MIN_FLOAT; return *this; } + + //! Sets positive unit random vector + Point& PositiveUnitRandomVector(); + //! Sets unit random vector + Point& UnitRandomVector(); + + //! Assignment from values + inline_ Point& Set(float _x, float _y, float _z) { x = _x; y = _y; z = _z; return *this; } + //! Assignment from array + inline_ Point& Set(const float f[3]) { x = f[_X]; y = f[_Y]; z = f[_Z]; return *this; } + //! Assignment from another point + inline_ Point& Set(const Point& src) { x = src.x; y = src.y; z = src.z; return *this; } + + //! Adds a vector + inline_ Point& Add(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } + //! Adds a vector + inline_ Point& Add(float _x, float _y, float _z) { x += _x; y += _y; z += _z; return *this; } + //! Adds a vector + inline_ Point& Add(const float f[3]) { x += f[_X]; y += f[_Y]; z += f[_Z]; return *this; } + //! Adds vectors + inline_ Point& Add(const Point& p, const Point& q) { x = p.x+q.x; y = p.y+q.y; z = p.z+q.z; return *this; } + + //! Subtracts a vector + inline_ Point& Sub(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } + //! Subtracts a vector + inline_ Point& Sub(float _x, float _y, float _z) { x -= _x; y -= _y; z -= _z; return *this; } + //! Subtracts a vector + inline_ Point& Sub(const float f[3]) { x -= f[_X]; y -= f[_Y]; z -= f[_Z]; return *this; } + //! Subtracts vectors + inline_ Point& Sub(const Point& p, const Point& q) { x = p.x-q.x; y = p.y-q.y; z = p.z-q.z; return *this; } + + //! this = -this + inline_ Point& Neg() { x = -x; y = -y; z = -z; return *this; } + //! this = -a + inline_ Point& Neg(const Point& a) { x = -a.x; y = -a.y; z = -a.z; return *this; } + + //! Multiplies by a scalar + inline_ Point& Mult(float s) { x *= s; y *= s; z *= s; return *this; } + + //! this = a * scalar + inline_ Point& Mult(const Point& a, float scalar) + { + x = a.x * scalar; + y = a.y * scalar; + z = a.z * scalar; + return *this; + } + + //! this = a + b * scalar + inline_ Point& Mac(const Point& a, const Point& b, float scalar) + { + x = a.x + b.x * scalar; + y = a.y + b.y * scalar; + z = a.z + b.z * scalar; + return *this; + } + + //! this = this + a * scalar + inline_ Point& Mac(const Point& a, float scalar) + { + x += a.x * scalar; + y += a.y * scalar; + z += a.z * scalar; + return *this; + } + + //! this = a - b * scalar + inline_ Point& Msc(const Point& a, const Point& b, float scalar) + { + x = a.x - b.x * scalar; + y = a.y - b.y * scalar; + z = a.z - b.z * scalar; + return *this; + } + + //! this = this - a * scalar + inline_ Point& Msc(const Point& a, float scalar) + { + x -= a.x * scalar; + y -= a.y * scalar; + z -= a.z * scalar; + return *this; + } + + //! this = a + b * scalarb + c * scalarc + inline_ Point& Mac2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) + { + x = a.x + b.x * scalarb + c.x * scalarc; + y = a.y + b.y * scalarb + c.y * scalarc; + z = a.z + b.z * scalarb + c.z * scalarc; + return *this; + } + + //! this = a - b * scalarb - c * scalarc + inline_ Point& Msc2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) + { + x = a.x - b.x * scalarb - c.x * scalarc; + y = a.y - b.y * scalarb - c.y * scalarc; + z = a.z - b.z * scalarb - c.z * scalarc; + return *this; + } + + //! this = mat * a + inline_ Point& Mult(const Matrix3x3& mat, const Point& a); + + //! this = mat1 * a1 + mat2 * a2 + inline_ Point& Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2); + + //! this = this + mat * a + inline_ Point& Mac(const Matrix3x3& mat, const Point& a); + + //! this = transpose(mat) * a + inline_ Point& TransMult(const Matrix3x3& mat, const Point& a); + + //! Linear interpolate between two vectors: this = a + t * (b - a) + inline_ Point& Lerp(const Point& a, const Point& b, float t) + { + x = a.x + t * (b.x - a.x); + y = a.y + t * (b.y - a.y); + z = a.z + t * (b.z - a.z); + return *this; + } + + //! Hermite interpolate between p1 and p2. p0 and p3 are used for finding gradient at p1 and p2. + //! this = p0 * (2t^2 - t^3 - t)/2 + //! + p1 * (3t^3 - 5t^2 + 2)/2 + //! + p2 * (4t^2 - 3t^3 + t)/2 + //! + p3 * (t^3 - t^2)/2 + inline_ Point& Herp(const Point& p0, const Point& p1, const Point& p2, const Point& p3, float t) + { + float t2 = t * t; + float t3 = t2 * t; + float kp0 = (2.0f * t2 - t3 - t) * 0.5f; + float kp1 = (3.0f * t3 - 5.0f * t2 + 2.0f) * 0.5f; + float kp2 = (4.0f * t2 - 3.0f * t3 + t) * 0.5f; + float kp3 = (t3 - t2) * 0.5f; + x = p0.x * kp0 + p1.x * kp1 + p2.x * kp2 + p3.x * kp3; + y = p0.y * kp0 + p1.y * kp1 + p2.y * kp2 + p3.y * kp3; + z = p0.z * kp0 + p1.z * kp1 + p2.z * kp2 + p3.z * kp3; + return *this; + } + + //! this = rotpos * r + linpos + inline_ Point& Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); + + //! this = trans(rotpos) * (r - linpos) + inline_ Point& InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); + + //! Returns MIN(x, y, z); + inline_ float Min() const { return MIN(x, MIN(y, z)); } + //! Returns MAX(x, y, z); + inline_ float Max() const { return MAX(x, MAX(y, z)); } + //! Sets each element to be componentwise minimum + inline_ Point& Min(const Point& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); return *this; } + //! Sets each element to be componentwise maximum + inline_ Point& Max(const Point& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); return *this; } + + //! Clamps each element + inline_ Point& Clamp(float min, float max) + { + if(xmax) x=max; + if(ymax) y=max; + if(zmax) z=max; + return *this; + } + + //! Computes square magnitude + inline_ float SquareMagnitude() const { return x*x + y*y + z*z; } + //! Computes magnitude + inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z); } + //! Computes volume + inline_ float Volume() const { return x * y * z; } + + //! Checks the point is near zero + inline_ bool ApproxZero() const { return SquareMagnitude() < EPSILON2; } + + //! Tests for exact zero vector + inline_ BOOL IsZero() const + { + if(IR(x) || IR(y) || IR(z)) return FALSE; + return TRUE; + } + + //! Checks point validity + inline_ BOOL IsValid() const + { + if(!IsValidFloat(x)) return FALSE; + if(!IsValidFloat(y)) return FALSE; + if(!IsValidFloat(z)) return FALSE; + return TRUE; + } + + //! Slighty moves the point + void Tweak(udword coord_mask, udword tweak_mask) + { + if(coord_mask&1) { udword Dummy = IR(x); Dummy^=tweak_mask; x = FR(Dummy); } + if(coord_mask&2) { udword Dummy = IR(y); Dummy^=tweak_mask; y = FR(Dummy); } + if(coord_mask&4) { udword Dummy = IR(z); Dummy^=tweak_mask; z = FR(Dummy); } + } + + #define TWEAKMASK 0x3fffff + #define TWEAKNOTMASK ~TWEAKMASK + //! Slighty moves the point out + inline_ void TweakBigger() + { + udword Dummy = (IR(x)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); + Dummy = (IR(y)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); + Dummy = (IR(z)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); + } + + //! Slighty moves the point in + inline_ void TweakSmaller() + { + udword Dummy = (IR(x)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); + Dummy = (IR(y)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); + Dummy = (IR(z)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); + } + + //! Normalizes the vector + inline_ Point& Normalize() + { + float M = x*x + y*y + z*z; + if(M) + { + M = 1.0f / sqrtf(M); + x *= M; + y *= M; + z *= M; + } + return *this; + } + + //! Sets vector length + inline_ Point& SetLength(float length) + { + float NewLength = length / Magnitude(); + x *= NewLength; + y *= NewLength; + z *= NewLength; + return *this; + } + + //! Clamps vector length + inline_ Point& ClampLength(float limit_length) + { + if(limit_length>=0.0f) // Magnitude must be positive + { + float CurrentSquareLength = SquareMagnitude(); + + if(CurrentSquareLength > limit_length * limit_length) + { + float Coeff = limit_length / sqrtf(CurrentSquareLength); + x *= Coeff; + y *= Coeff; + z *= Coeff; + } + } + return *this; + } + + //! Computes distance to another point + inline_ float Distance(const Point& b) const + { + return sqrtf((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); + } + + //! Computes square distance to another point + inline_ float SquareDistance(const Point& b) const + { + return ((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); + } + + //! Dot product dp = this|a + inline_ float Dot(const Point& p) const { return p.x * x + p.y * y + p.z * z; } + + //! Cross product this = a x b + inline_ Point& Cross(const Point& a, const Point& b) + { + x = a.y * b.z - a.z * b.y; + y = a.z * b.x - a.x * b.z; + z = a.x * b.y - a.y * b.x; + return *this; + } + + //! Vector code ( bitmask = sign(z) | sign(y) | sign(x) ) + inline_ udword VectorCode() const + { + return (IR(x)>>31) | ((IR(y)&SIGN_BITMASK)>>30) | ((IR(z)&SIGN_BITMASK)>>29); + } + + //! Returns largest axis + inline_ PointComponent LargestAxis() const + { + const float* Vals = &x; + PointComponent m = _X; + if(Vals[_Y] > Vals[m]) m = _Y; + if(Vals[_Z] > Vals[m]) m = _Z; + return m; + } + + //! Returns closest axis + inline_ PointComponent ClosestAxis() const + { + const float* Vals = &x; + PointComponent m = _X; + if(AIR(Vals[_Y]) > AIR(Vals[m])) m = _Y; + if(AIR(Vals[_Z]) > AIR(Vals[m])) m = _Z; + return m; + } + + //! Returns smallest axis + inline_ PointComponent SmallestAxis() const + { + const float* Vals = &x; + PointComponent m = _X; + if(Vals[_Y] < Vals[m]) m = _Y; + if(Vals[_Z] < Vals[m]) m = _Z; + return m; + } + + //! Refracts the point + Point& Refract(const Point& eye, const Point& n, float refractindex, Point& refracted); + + //! Projects the point onto a plane + Point& ProjectToPlane(const Plane& p); + + //! Projects the point onto the screen + void ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const; + + //! Unfolds the point onto a plane according to edge(a,b) + Point& Unfold(Plane& p, Point& a, Point& b); + + //! Hash function from Ville Miettinen + inline_ udword GetHashValue() const + { + const udword* h = (const udword*)(this); + udword f = (h[0]+h[1]*11-(h[2]*17)) & 0x7fffffff; // avoid problems with +-0 + return (f>>22)^(f>>12)^(f); + } + + //! Stuff magic values in the point, marking it as explicitely not used. + void SetNotUsed(); + //! Checks the point is marked as not used + BOOL IsNotUsed() const; + + // Arithmetic operators + + //! Unary operator for Point Negate = - Point + inline_ Point operator-() const { return Point(-x, -y, -z); } + + //! Operator for Point Plus = Point + Point. + inline_ Point operator+(const Point& p) const { return Point(x + p.x, y + p.y, z + p.z); } + //! Operator for Point Minus = Point - Point. + inline_ Point operator-(const Point& p) const { return Point(x - p.x, y - p.y, z - p.z); } + + //! Operator for Point Mul = Point * Point. + inline_ Point operator*(const Point& p) const { return Point(x * p.x, y * p.y, z * p.z); } + //! Operator for Point Scale = Point * float. + inline_ Point operator*(float s) const { return Point(x * s, y * s, z * s ); } + //! Operator for Point Scale = float * Point. + inline_ friend Point operator*(float s, const Point& p) { return Point(s * p.x, s * p.y, s * p.z); } + + //! Operator for Point Div = Point / Point. + inline_ Point operator/(const Point& p) const { return Point(x / p.x, y / p.y, z / p.z); } + //! Operator for Point Scale = Point / float. + inline_ Point operator/(float s) const { s = 1.0f / s; return Point(x * s, y * s, z * s); } + //! Operator for Point Scale = float / Point. + inline_ friend Point operator/(float s, const Point& p) { return Point(s / p.x, s / p.y, s / p.z); } + + //! Operator for float DotProd = Point | Point. + inline_ float operator|(const Point& p) const { return x*p.x + y*p.y + z*p.z; } + //! Operator for Point VecProd = Point ^ Point. + inline_ Point operator^(const Point& p) const + { + return Point( + y * p.z - z * p.y, + z * p.x - x * p.z, + x * p.y - y * p.x ); + } + + //! Operator for Point += Point. + inline_ Point& operator+=(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } + //! Operator for Point += float. + inline_ Point& operator+=(float s) { x += s; y += s; z += s; return *this; } + + //! Operator for Point -= Point. + inline_ Point& operator-=(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } + //! Operator for Point -= float. + inline_ Point& operator-=(float s) { x -= s; y -= s; z -= s; return *this; } + + //! Operator for Point *= Point. + inline_ Point& operator*=(const Point& p) { x *= p.x; y *= p.y; z *= p.z; return *this; } + //! Operator for Point *= float. + inline_ Point& operator*=(float s) { x *= s; y *= s; z *= s; return *this; } + + //! Operator for Point /= Point. + inline_ Point& operator/=(const Point& p) { x /= p.x; y /= p.y; z /= p.z; return *this; } + //! Operator for Point /= float. + inline_ Point& operator/=(float s) { s = 1.0f/s; x *= s; y *= s; z *= s; return *this; } + + // Logical operators + + //! Operator for "if(Point==Point)" + inline_ bool operator==(const Point& p) const { return ( (IR(x)==IR(p.x))&&(IR(y)==IR(p.y))&&(IR(z)==IR(p.z))); } + //! Operator for "if(Point!=Point)" + inline_ bool operator!=(const Point& p) const { return ( (IR(x)!=IR(p.x))||(IR(y)!=IR(p.y))||(IR(z)!=IR(p.z))); } + + // Arithmetic operators + + //! Operator for Point Mul = Point * Matrix3x3. + inline_ Point operator*(const Matrix3x3& mat) const + { + class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining + const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; + + return Point( + x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0], + x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1], + x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] ); + } + + //! Operator for Point Mul = Point * Matrix4x4. + inline_ Point operator*(const Matrix4x4& mat) const + { + class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining + const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; + + return Point( + x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0], + x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1], + x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]); + } + + //! Operator for Point *= Matrix3x3. + inline_ Point& operator*=(const Matrix3x3& mat) + { + class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining + const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; + + float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0]; + float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1]; + float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2]; + + x = xp; y = yp; z = zp; + + return *this; + } + + //! Operator for Point *= Matrix4x4. + inline_ Point& operator*=(const Matrix4x4& mat) + { + class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining + const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; + + float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0]; + float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1]; + float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]; + + x = xp; y = yp; z = zp; + + return *this; + } + + // Cast operators + + //! Cast a Point to a HPoint. w is set to zero. + operator HPoint() const; + + inline_ operator const float*() const { return &x; } + inline_ operator float*() { return &x; } + + public: + float x, y, z; + }; + + FUNCTION ICEMATHS_API void Normalize1(Point& a); + FUNCTION ICEMATHS_API void Normalize2(Point& a); + +#endif //__ICEPOINT_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IcePreprocessor.h b/Extras/CDTestFramework/Opcode/Ice/IcePreprocessor.h new file mode 100644 index 0000000..f02501a --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IcePreprocessor.h @@ -0,0 +1,158 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains preprocessor stuff. This should be the first included header. + * \file IcePreprocessor.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef ICEPREPROCESSOR_H +#define ICEPREPROCESSOR_H + + // Check platform + #if defined( _WIN32 ) || defined( WIN32 ) + #pragma message("Compiling on Windows...") + #define PLATFORM_WINDOWS + #else + #pragma message("Compiling on unknown platform...") + #endif + + // Check compiler + #if defined(_MSC_VER) + #pragma message("Compiling with VC++...") + #define COMPILER_VISUAL_CPP + + #if _MSC_VER > 1300 + #pragma message("Compiling with VC7") + #define COMPILER_VC7 + #else + #pragma message("Compiling with VC6") + #define COMPILER_VC6 + #endif + #else + #pragma message("Compiling with unknown compiler...") + #endif + + // Check compiler options. If this file is included in user-apps, this + // shouldn't be needed, so that they can use what they like best. + #ifndef ICE_DONT_CHECK_COMPILER_OPTIONS + #ifdef COMPILER_VISUAL_CPP + #if defined(_CHAR_UNSIGNED) + #endif + + #if defined(_CPPRTTI) + #error Please disable RTTI... + #endif + + #if defined(_CPPUNWIND) + #error Please disable exceptions... + #endif + + #if defined(_MT) + // Multithreading + #endif + #endif + #endif + + // Check debug mode + #ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it. + #ifndef _DEBUG + #define _DEBUG + #endif + #endif + + #ifdef _DEBUG + // Here you may define items for debug builds + #endif + + #ifndef THIS_FILE + #define THIS_FILE __FILE__ + #endif + + #ifndef ICE_NO_DLL + #ifdef ICECORE_EXPORTS + #define ICECORE_API __declspec(dllexport) + #else + #define ICECORE_API __declspec(dllimport) + #endif + #else + #define ICECORE_API + #endif + + #define FUNCTION extern "C" + + // Cosmetic stuff [mainly useful with multiple inheritance] + #define override(base_class) virtual + + // Our own inline keyword, so that: + // - we can switch to __forceinline to check it's really better or not + // - we can remove __forceinline if the compiler doesn't support it +// #define inline_ __forceinline +// #define inline_ inline + + // Contributed by Bruce Mitchener + #if defined(COMPILER_VISUAL_CPP) + #define inline_ __forceinline +// #define inline_ inline + #elif defined(__GNUC__) && __GNUC__ < 3 + #define inline_ inline + #elif defined(__GNUC__) + #define inline_ inline __attribute__ ((always_inline)) + #else + #define inline_ inline + #endif + + // Down the hatch + #pragma inline_depth( 255 ) + + #ifdef COMPILER_VISUAL_CPP + #pragma intrinsic(memcmp) + #pragma intrinsic(memcpy) + #pragma intrinsic(memset) + #pragma intrinsic(strcat) + #pragma intrinsic(strcmp) + #pragma intrinsic(strcpy) + #pragma intrinsic(strlen) + #pragma intrinsic(abs) + #pragma intrinsic(labs) + #endif + + // ANSI compliance + #ifdef _DEBUG + // Remove painful warning in debug + inline_ bool ReturnsFalse(){ return false; } + #define for if(ReturnsFalse()){} else for + #else + #define for if(0){} else for + #endif + + // Don't override new/delete + #define DEFAULT_NEWDELETE + #define DONT_TRACK_MEMORY_LEAKS + + //! Macro used to give me a clue when it crashes in release and only the assembly is available + #define INCLUDE_GUARDIANS + #ifdef INCLUDE_GUARDIANS + #define GUARD(x) \ + { \ + static const char guard_text[] = x; \ + _asm push eax \ + _asm nop \ + _asm nop \ + _asm nop \ + _asm nop \ + _asm lea eax, guard_text \ + _asm nop \ + _asm nop \ + _asm nop \ + _asm nop \ + _asm pop eax \ + } + #else + #define GUARD(x) + #endif + +#endif // ICEPREPROCESSOR_H diff --git a/Extras/CDTestFramework/Opcode/Ice/IceRandom.cpp b/Extras/CDTestFramework/Opcode/Ice/IceRandom.cpp new file mode 100644 index 0000000..93bdd13 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceRandom.cpp @@ -0,0 +1,52 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for random generators. + * \file IceRandom.cpp + * \author Pierre Terdiman + * \date August, 9, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +void IceCore:: SRand(udword seed) +{ + srand(seed); +} + +udword IceCore::Rand() +{ + return rand(); +} + + +static BasicRandom gRandomGenerator(42); + +udword IceCore::GetRandomIndex(udword max_index) +{ + // We don't use rand() since it's limited to RAND_MAX + udword Index = gRandomGenerator.Randomize(); + return Index % max_index; +} + + diff --git a/Extras/CDTestFramework/Opcode/Ice/IceRandom.h b/Extras/CDTestFramework/Opcode/Ice/IceRandom.h new file mode 100644 index 0000000..67c3a9b --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceRandom.h @@ -0,0 +1,58 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for random generators. + * \file IceRandom.h + * \author Pierre Terdiman + * \date August, 9, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICERANDOM_H__ +#define __ICERANDOM_H__ + + FUNCTION ICECORE_API void SRand(udword seed); + FUNCTION ICECORE_API udword Rand(); + + //! Returns a unit random floating-point value + inline_ float UnitRandomFloat() { return float(Rand()) * ONE_OVER_RAND_MAX; } + + //! Returns a random index so that 0<= index < max_index + ICECORE_API udword GetRandomIndex(udword max_index); + + class ICECORE_API BasicRandom + { + public: + + //! Constructor + inline_ BasicRandom(udword seed=0) : mRnd(seed) {} + //! Destructor + inline_ ~BasicRandom() {} + + inline_ void SetSeed(udword seed) { mRnd = seed; } + inline_ udword GetCurrentValue() const { return mRnd; } + inline_ udword Randomize() { mRnd = mRnd * 2147001325 + 715136305; return mRnd; } + + private: + udword mRnd; + }; + +#endif // __ICERANDOM_H__ + diff --git a/Extras/CDTestFramework/Opcode/Ice/IceRay.cpp b/Extras/CDTestFramework/Opcode/Ice/IceRay.cpp new file mode 100644 index 0000000..ce93b91 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceRay.cpp @@ -0,0 +1,100 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for rays. + * \file IceRay.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Ray class. + * A ray is a half-line P(t) = mOrig + mDir * t, with 0 <= t <= +infinity + * \class Ray + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* + O = Origin = impact point + i = normalized vector along the x axis + j = normalized vector along the y axis = actually the normal vector in O + D = Direction vector, norm |D| = 1 + N = Projection of D on y axis, norm |N| = normal reaction + T = Projection of D on x axis, norm |T| = tangential reaction + R = Reflexion vector + + ^y + | + | + | + _ _ _| _ _ _ + * * *| + \ | / + \ |N / | + R\ | /D + \ | / | + \ | / + _________\|/______*_______>x + O T + + Let define theta = angle between D and N. Then cos(theta) = |N| / |D| = |N| since D is normalized. + + j|D = |j|*|D|*cos(theta) => |N| = j|D + + Then we simply have: + + D = N + T + + To compute tangential reaction : + + T = D - N + + To compute reflexion vector : + + R = N - T = N - (D-N) = 2*N - D +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +float Ray::SquareDistance(const Point& point, float* t) const +{ + Point Diff = point - mOrig; + float fT = Diff | mDir; + + if(fT<=0.0f) + { + fT = 0.0f; + } + else + { + fT /= mDir.SquareMagnitude(); + Diff -= fT*mDir; + } + + if(t) *t = fT; + + return Diff.SquareMagnitude(); +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceRay.h b/Extras/CDTestFramework/Opcode/Ice/IceRay.h new file mode 100644 index 0000000..7ea5773 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceRay.h @@ -0,0 +1,114 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for rays. + * \file IceRay.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICERAY_H__ +#define __ICERAY_H__ + + class ICEMATHS_API Ray + { + public: + //! Constructor + inline_ Ray() {} + //! Constructor + inline_ Ray(const Point& orig, const Point& dir) : mOrig(orig), mDir(dir) {} + //! Copy constructor + inline_ Ray(const Ray& ray) : mOrig(ray.mOrig), mDir(ray.mDir) {} + //! Destructor + inline_ ~Ray() {} + + float SquareDistance(const Point& point, float* t=null) const; + inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } + + Point mOrig; //!< Ray origin + Point mDir; //!< Normalized direction + }; + + inline_ void ComputeReflexionVector(Point& reflected, const Point& incoming_dir, const Point& outward_normal) + { + reflected = incoming_dir - outward_normal * 2.0f * (incoming_dir|outward_normal); + } + + inline_ void ComputeReflexionVector(Point& reflected, const Point& source, const Point& impact, const Point& normal) + { + Point V = impact - source; + reflected = V - normal * 2.0f * (V|normal); + } + + inline_ void DecomposeVector(Point& normal_compo, Point& tangent_compo, const Point& outward_dir, const Point& outward_normal) + { + normal_compo = outward_normal * (outward_dir|outward_normal); + tangent_compo = outward_dir - normal_compo; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a direction vector from world space to local space + * \param local_dir [out] direction vector in local space + * \param world_dir [in] direction vector in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalDirection(Point& local_dir, const Point& world_dir, const Matrix4x4& world) + { + // Get world direction back in local space +// Matrix3x3 InvWorld = world; +// local_dir = InvWorld * world_dir; + local_dir = Matrix3x3(world) * world_dir; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a position vector from world space to local space + * \param local_pt [out] position vector in local space + * \param world_pt [in] position vector in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalPoint(Point& local_pt, const Point& world_pt, const Matrix4x4& world) + { + // Get world vertex back in local space + Matrix4x4 InvWorld = world; + InvWorld.Invert(); + local_pt = world_pt * InvWorld; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a ray from world space to local space + * \param local_ray [out] ray in local space + * \param world_ray [in] ray in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalRay(Ray& local_ray, const Ray& world_ray, const Matrix4x4& world) + { + // Get world ray back in local space + ComputeLocalDirection(local_ray.mDir, world_ray.mDir, world); + ComputeLocalPoint(local_ray.mOrig, world_ray.mOrig, world); + } + +#endif // __ICERAY_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceRevisitedRadix.cpp b/Extras/CDTestFramework/Opcode/Ice/IceRevisitedRadix.cpp new file mode 100644 index 0000000..3cb3aac --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceRevisitedRadix.cpp @@ -0,0 +1,592 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains source code from the article "Radix Sort Revisited". + * \file IceRevisitedRadix.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Revisited Radix Sort. + * This is my new radix routine: + * - it uses indices and doesn't recopy the values anymore, hence wasting less ram + * - it creates all the histograms in one run instead of four + * - it sorts words faster than dwords and bytes faster than words + * - it correctly sorts negative floating-point values by patching the offsets + * - it automatically takes advantage of temporal coherence + * - multiple keys support is a side effect of temporal coherence + * - it may be worth recoding in asm... (mainly to use FCOMI, FCMOV, etc) [it's probably memory-bound anyway] + * + * History: + * - 08.15.98: very first version + * - 04.04.00: recoded for the radix article + * - 12.xx.00: code lifting + * - 09.18.01: faster CHECK_PASS_VALIDITY thanks to Mark D. Shattuck (who provided other tips, not included here) + * - 10.11.01: added local ram support + * - 01.20.02: bugfix! In very particular cases the last pass was skipped in the float code-path, leading to incorrect sorting...... + * - 01.02.02: - "mIndices" renamed => "mRanks". That's a rank sorter after all. + * - ranks are not "reset" anymore, but implicit on first calls + * - 07.05.02: offsets rewritten with one less indirection. + * - 11.03.02: "bool" replaced with RadixHint enum + * - 07.15.04: stack-based radix added + * - we want to use the radix sort but without making it static, and without allocating anything. + * - we internally allocate two arrays of ranks. Each of them has N udwords to sort N values. + * - 1Mb/2/sizeof(udword) = 131072 values max, at the same time. + * - 09.22.04: - adapted to MacOS by Chris Lamb + * - 01.12.06: - added optimizations suggested by Kyle Hubert + * + * \class RadixSort + * \author Pierre Terdiman + * \version 1.5 + * \date August, 15, 1998 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +To do: + - add an offset parameter between two input values (avoid some data recopy sometimes) + - unroll ? asm ? + - prefetch stuff the day I have a P3 + - make a version with 16-bits indices ? +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "StdAfx.h" + +using namespace Opcode; + +#define INVALIDATE_RANKS mCurrentSize|=0x80000000 +#define VALIDATE_RANKS mCurrentSize&=0x7fffffff +#define CURRENT_SIZE (mCurrentSize&0x7fffffff) +#define INVALID_RANKS (mCurrentSize&0x80000000) + +#define CHECK_RESIZE(n) \ + if(n!=mPreviousSize) \ + { \ + if(n>mCurrentSize) Resize(n); \ + else ResetRanks(); \ + mPreviousSize = n; \ + } + +#if defined(__APPLE__) || defined(_XBOX) + #define H0_OFFSET 768 + #define H1_OFFSET 512 + #define H2_OFFSET 256 + #define H3_OFFSET 0 + #define BYTES_INC (3-j) +#else + #define H0_OFFSET 0 + #define H1_OFFSET 256 + #define H2_OFFSET 512 + #define H3_OFFSET 768 + #define BYTES_INC j +#endif + +#define CREATE_HISTOGRAMS(type, buffer) \ + /* Clear counters/histograms */ \ + ZeroMemory(mHistogram, 256*4*sizeof(udword)); \ + \ + /* Prepare to count */ \ + const ubyte* p = (const ubyte*)input; \ + const ubyte* pe = &p[nb*4]; \ + udword* h0= &mHistogram[H0_OFFSET]; /* Histogram for first pass (LSB) */ \ + udword* h1= &mHistogram[H1_OFFSET]; /* Histogram for second pass */ \ + udword* h2= &mHistogram[H2_OFFSET]; /* Histogram for third pass */ \ + udword* h3= &mHistogram[H3_OFFSET]; /* Histogram for last pass (MSB) */ \ + \ + bool AlreadySorted = true; /* Optimism... */ \ + \ + if(INVALID_RANKS) \ + { \ + /* Prepare for temporal coherence */ \ + type* Running = (type*)buffer; \ + type PrevVal = *Running; \ + \ + while(p!=pe) \ + { \ + /* Read input buffer in previous sorted order */ \ + type Val = *Running++; \ + /* Check whether already sorted or not */ \ + if(ValCurSize) Resize(nb); + mCurrentSize = nb; + INVALIDATE_RANKS; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main sort routine. + * This one is for integer values. After the call, mRanks contains a list of indices in sorted order, i.e. in the order you may process your data. + * \param input [in] a list of integer values to sort + * \param nb [in] number of values to sort, must be < 2^31 + * \param hint [in] RADIX_SIGNED to handle negative values, RADIX_UNSIGNED if you know your input buffer only contains positive values + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RadixSort& RadixSort::Sort(const udword* input, udword nb, RadixHint hint) +{ + // Checkings + if(!input || !nb || nb&0x80000000) return *this; + + // Stats + mTotalCalls++; + + // Resize lists if needed + CheckResize(nb); + +#ifdef RADIX_LOCAL_RAM + // Allocate histograms & offsets on the stack + udword mHistogram[256*4]; +// udword mOffset[256]; + udword* mLink[256]; +#endif + + // Create histograms (counters). Counters for all passes are created in one run. + // Pros: read input buffer once instead of four times + // Cons: mHistogram is 4Kb instead of 1Kb + // We must take care of signed/unsigned values for temporal coherence.... I just + // have 2 code paths even if just a single opcode changes. Self-modifying code, someone? + if(hint==RADIX_UNSIGNED) { CREATE_HISTOGRAMS(udword, input); } + else { CREATE_HISTOGRAMS(sdword, input); } +/* + // Compute #negative values involved if needed + udword NbNegativeValues = 0; + if(hint==RADIX_SIGNED) + { + // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128 + // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte, + // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers. + udword* h3= &mHistogram[768]; + for(udword i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part + } +*/ + // Radix sort, j is the pass number (0=LSB, 3=MSB) + for(udword j=0;j<4;j++) + { + CHECK_PASS_VALIDITY(j); + + // Sometimes the fourth (negative) pass is skipped because all numbers are negative and the MSB is 0xFF (for example). This is + // not a problem, numbers are correctly sorted anyway. + if(PerformPass) + { + // Should we care about negative values? + if(j!=3 || hint==RADIX_UNSIGNED) + { + // Here we deal with positive values only + + // Create offsets +// mOffset[0] = 0; +// for(udword i=1;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; + mLink[0] = mRanks2; + for(udword i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + } + else + { + // This is a special case to correctly handle negative integers. They're sorted in the right order but at the wrong place. +/* + // Create biased offsets, in order for negative numbers to be sorted as well +// mOffset[0] = NbNegativeValues; // First positive number takes place after the negative ones +// for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + mLink[0] = &mRanks2[NbNegativeValues]; // First positive number takes place after the negative ones + for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + + // Fixing the wrong place for negative values +// mOffset[128] = 0; +// for(i=129;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; + mLink[128] = mRanks2; + for(udword i=129;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; +*/ + +// From Kyle Hubert: + +//mOffset[128] = 0; +mLink[128] = mRanks2; +//for(i=129;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; +for(udword i=129;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + +//mOffset[0] = mOffset[255] + CurCount[255]; +mLink[0] = mLink[255] + CurCount[255]; +//for(i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; +for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + + + } + + // Perform Radix Sort + const ubyte* InputBytes = (const ubyte*)input; + InputBytes += BYTES_INC; + if(INVALID_RANKS) + { +// for(udword i=0;i127;i--) mOffset[i] = mOffset[i+1] + CurCount[i]; +for(udword i=254;i>127;i--) mLink[i] = mLink[i+1] + CurCount[i]; +//mOffset[0] = mOffset[128] + CurCount[128]; +mLink[0] = mLink[128] + CurCount[128]; +//for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; +for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + + // Perform Radix Sort + if(INVALID_RANKS) + { + for(udword i=0;i>24; // Radix byte, same as above. AND is useless here (udword). + // ### cmp to be killed. Not good. Later. +// if(Radix<128) mRanks2[mOffset[Radix]++] = i; // Number is positive, same as above +// else mRanks2[--mOffset[Radix]] = i; // Number is negative, flip the sorting order + if(Radix<128) *mLink[Radix]++ = i; // Number is positive, same as above + else *(--mLink[Radix]) = i; // Number is negative, flip the sorting order + } + VALIDATE_RANKS; + } + else + { + for(udword i=0;i>24; // Radix byte, same as above. AND is useless here (udword). + // ### cmp to be killed. Not good. Later. +// if(Radix<128) mRanks2[mOffset[Radix]++] = mRanks[i]; // Number is positive, same as above +// else mRanks2[--mOffset[Radix]] = mRanks[i]; // Number is negative, flip the sorting order + if(Radix<128) *mLink[Radix]++ = mRanks[i]; // Number is positive, same as above + else *(--mLink[Radix]) = mRanks[i]; // Number is negative, flip the sorting order + } + } + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + udword* Tmp = mRanks; + mRanks = mRanks2; + mRanks2 = Tmp; + } + else + { + // The pass is useless, yet we still have to reverse the order of current list if all values are negative. + if(UniqueVal>=128) + { + if(INVALID_RANKS) + { + // ###Possible? + for(udword i=0;i=SqrLen) + { + fT = 1.0f; + Diff -= Dir; + } + else + { + fT /= SqrLen; + Diff -= fT*Dir; + } + } + + if(t) *t = fT; + + return Diff.SquareMagnitude(); +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceSegment.h b/Extras/CDTestFramework/Opcode/Ice/IceSegment.h new file mode 100644 index 0000000..6764c0c --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceSegment.h @@ -0,0 +1,71 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for segments. + * \file IceSegment.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICESEGMENT_H__ +#define __ICESEGMENT_H__ + + class ICEMATHS_API Segment + { + public: + //! Constructor + inline_ Segment() {} + //! Constructor + inline_ Segment(const Point& p0, const Point& p1) : mP0(p0), mP1(p1) {} + //! Copy constructor + inline_ Segment(const Segment& seg) : mP0(seg.mP0), mP1(seg.mP1) {} + //! Destructor + inline_ ~Segment() {} + + inline_ const Point& GetOrigin() const { return mP0; } + inline_ Point ComputeDirection() const { return mP1 - mP0; } + inline_ void ComputeDirection(Point& dir) const { dir = mP1 - mP0; } + inline_ float ComputeLength() const { return mP1.Distance(mP0); } + inline_ float ComputeSquareLength() const { return mP1.SquareDistance(mP0); } + + inline_ void SetOriginDirection(const Point& origin, const Point& direction) + { + mP0 = mP1 = origin; + mP1 += direction; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes a point on the segment + * \param pt [out] point on segment + * \param t [in] point's parameter [t=0 => pt = mP0, t=1 => pt = mP1] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputePoint(Point& pt, float t) const { pt = mP0 + t * (mP1 - mP0); } + + float SquareDistance(const Point& point, float* t=null) const; + inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } + + Point mP0; //!< Start of segment + Point mP1; //!< End of segment + }; + +#endif // __ICESEGMENT_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceTriangle.cpp b/Extras/CDTestFramework/Opcode/Ice/IceTriangle.cpp new file mode 100644 index 0000000..d95174d --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceTriangle.cpp @@ -0,0 +1,302 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy triangle class. + * \file IceTriangle.cpp + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a triangle class. + * + * \class Tri + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon) +{ + // Compute distance from current vertex to the plane + float Dist = plane.Distance(v); + // Compute side: + // 1 = the vertex is on the positive side of the plane + // -1 = the vertex is on the negative side of the plane + // 0 = the vertex is on the plane (within epsilon) + return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Flips the winding order. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Flip() +{ + Point Tmp = mVerts[1]; + mVerts[1] = mVerts[2]; + mVerts[2] = Tmp; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle area. + * \return the area + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Area() const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle perimeter. + * \return the perimeter + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Perimeter() const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + return p0.Distance(p1) + + p0.Distance(p2) + + p1.Distance(p2); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle compacity. + * \return the compacity + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Compacity() const +{ + float P = Perimeter(); + if(P==0.0f) return 0.0f; + return (4.0f*PI*Area()/(P*P)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle normal. + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Normal(Point& normal) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + normal = ((p0 - p1)^(p0 - p2)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle denormalized normal. + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::DenormalizedNormal(Point& normal) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + normal = ((p0 - p1)^(p0 - p2)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle center. + * \param center [out] the computed center + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Center(Point& center) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + center = (p0 + p1 + p2)*INV3; +} + +PartVal Triangle::TestAgainstPlane(const Plane& plane, float epsilon) const +{ + bool Pos = false, Neg = false; + + // Loop through all vertices + for(udword i=0;i<3;i++) + { + // Compute side: + sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon); + + if (Side < 0) Neg = true; + else if (Side > 0) Pos = true; + } + + if (!Pos && !Neg) return TRI_ON_PLANE; + else if (Pos && Neg) return TRI_INTERSECT; + else if (Pos && !Neg) return TRI_PLUS_SPACE; + else if (!Pos && Neg) return TRI_MINUS_SPACE; + + // What?! + return TRI_FORCEDWORD; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle moment. + * \param m [out] the moment + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* +void Triangle::ComputeMoment(Moment& m) +{ + // Compute the area of the triangle + m.mArea = Area(); + + // Compute the centroid + Center(m.mCentroid); + + // Second-order components. Handle zero-area faces. + Point& p = mVerts[0]; + Point& q = mVerts[1]; + Point& r = mVerts[2]; + if(m.mArea==0.0f) + { + // This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the + // sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices. + m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x); + m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y); + m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z); + m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y); + m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z); + m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z); + m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; + m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; + m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; + } + else + { + const float OneOverTwelve = 1.0f / 12.0f; + m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve; + m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve; + m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve; + m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve; + m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve; + m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve; + m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; + m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; + m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; + } +} +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's smallest edge length. + * \return the smallest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::MinEdgeLength() const +{ + float Min = MAX_FLOAT; + float Length01 = mVerts[0].Distance(mVerts[1]); + float Length02 = mVerts[0].Distance(mVerts[2]); + float Length12 = mVerts[1].Distance(mVerts[2]); + if(Length01 < Min) Min = Length01; + if(Length02 < Min) Min = Length02; + if(Length12 < Min) Min = Length12; + return Min; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's largest edge length. + * \return the largest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::MaxEdgeLength() const +{ + float Max = MIN_FLOAT; + float Length01 = mVerts[0].Distance(mVerts[1]); + float Length02 = mVerts[0].Distance(mVerts[2]); + float Length12 = mVerts[1].Distance(mVerts[2]); + if(Length01 > Max) Max = Length01; + if(Length02 > Max) Max = Length02; + if(Length12 > Max) Max = Length12; + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a point on the triangle according to the stabbing information. + * \param u,v [in] point's barycentric coordinates + * \param pt [out] point on triangle + * \param nearvtx [out] index of nearest vertex + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const +{ + // Compute point coordinates + pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2]; + + // Compute nearest vertex if needed + if(nearvtx) + { + // Compute distance vector + Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face + mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face + mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face + + // Get smallest distance + *nearvtx = d.SmallestAxis(); + } +} + +void Triangle::Inflate(float fat_coeff, bool constant_border) +{ + // Compute triangle center + Point TriangleCenter; + Center(TriangleCenter); + + // Don't normalize? + // Normalize => add a constant border, regardless of triangle size + // Don't => add more to big triangles + for(udword i=0;i<3;i++) + { + Point v = mVerts[i] - TriangleCenter; + + if(constant_border) v.Normalize(); + + mVerts[i] += v * fat_coeff; + } +} diff --git a/Extras/CDTestFramework/Opcode/Ice/IceTriangle.h b/Extras/CDTestFramework/Opcode/Ice/IceTriangle.h new file mode 100644 index 0000000..99a6467 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceTriangle.h @@ -0,0 +1,84 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy triangle class. + * \file IceTriangle.h + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICETRIANGLE_H__ +#define __ICETRIANGLE_H__ + + // Forward declarations + class Moment; + + // Partitioning values + enum PartVal + { + TRI_MINUS_SPACE = 0, //!< Triangle is in the negative space + TRI_PLUS_SPACE = 1, //!< Triangle is in the positive space + TRI_INTERSECT = 2, //!< Triangle intersects plane + TRI_ON_PLANE = 3, //!< Triangle and plane are coplanar + + TRI_FORCEDWORD = 0x7fffffff + }; + + // A triangle class. + class ICEMATHS_API Triangle + { + public: + //! Constructor + inline_ Triangle() {} + //! Constructor + inline_ Triangle(const Point& p0, const Point& p1, const Point& p2) { mVerts[0]=p0; mVerts[1]=p1; mVerts[2]=p2; } + //! Copy constructor + inline_ Triangle(const Triangle& triangle) + { + mVerts[0] = triangle.mVerts[0]; + mVerts[1] = triangle.mVerts[1]; + mVerts[2] = triangle.mVerts[2]; + } + //! Destructor + inline_ ~Triangle() {} + //! Vertices + Point mVerts[3]; + + // Methods + void Flip(); + float Area() const; + float Perimeter() const; + float Compacity() const; + void Normal(Point& normal) const; + void DenormalizedNormal(Point& normal) const; + void Center(Point& center) const; + inline_ Plane PlaneEquation() const { return Plane(mVerts[0], mVerts[1], mVerts[2]); } + + PartVal TestAgainstPlane(const Plane& plane, float epsilon) const; +// float Distance(Point& cp, Point& cq, Tri& tri); + void ComputeMoment(Moment& m); + float MinEdgeLength() const; + float MaxEdgeLength() const; + void ComputePoint(float u, float v, Point& pt, udword* nearvtx=null) const; + void Inflate(float fat_coeff, bool constant_border); + }; + +#endif // __ICETRIANGLE_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceTrilist.h b/Extras/CDTestFramework/Opcode/Ice/IceTrilist.h new file mode 100644 index 0000000..73d23b5 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceTrilist.h @@ -0,0 +1,77 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a triangle container. + * \file IceTrilist.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICETRILIST_H__ +#define __ICETRILIST_H__ + + class ICEMATHS_API TriList : public Container + { + public: + // Constructor / Destructor + TriList() {} + ~TriList() {} + + inline_ udword GetNbTriangles() const { return GetNbEntries()/9; } + inline_ Triangle* GetTriangles() const { return (Triangle*)GetEntries(); } + + void AddTri(const Triangle& tri) + { + Add(tri.mVerts[0].x).Add(tri.mVerts[0].y).Add(tri.mVerts[0].z); + Add(tri.mVerts[1].x).Add(tri.mVerts[1].y).Add(tri.mVerts[1].z); + Add(tri.mVerts[2].x).Add(tri.mVerts[2].y).Add(tri.mVerts[2].z); + } + + void AddTri(const Point& p0, const Point& p1, const Point& p2) + { + Add(p0.x).Add(p0.y).Add(p0.z); + Add(p1.x).Add(p1.y).Add(p1.z); + Add(p2.x).Add(p2.y).Add(p2.z); + } + }; + + class ICEMATHS_API TriangleList : public Container + { + public: + // Constructor / Destructor + TriangleList() {} + ~TriangleList() {} + + inline_ udword GetNbTriangles() const { return GetNbEntries()/3; } + inline_ IndexedTriangle* GetTriangles() const { return (IndexedTriangle*)GetEntries();} + + void AddTriangle(const IndexedTriangle& tri) + { + Add(tri.mVRef[0]).Add(tri.mVRef[1]).Add(tri.mVRef[2]); + } + + void AddTriangle(udword vref0, udword vref1, udword vref2) + { + Add(vref0).Add(vref1).Add(vref2); + } + }; + +#endif //__ICETRILIST_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/IceTypes.h b/Extras/CDTestFramework/Opcode/Ice/IceTypes.h new file mode 100644 index 0000000..9316d8d --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/IceTypes.h @@ -0,0 +1,181 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains custom types. + * \file IceTypes.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef ICETYPES_H +#define ICETYPES_H + + #define USE_HANDLE_MANAGER + + // Constants +#ifndef PI + #define PI 3.1415926535897932384626433832795028841971693993751f //!< PI +#endif + #define HALFPI 1.57079632679489661923f //!< 0.5 * PI + #define TWOPI 6.28318530717958647692f //!< 2.0 * PI + #define INVPI 0.31830988618379067154f //!< 1.0 / PI + + #define RADTODEG 57.2957795130823208768f //!< 180.0 / PI, convert radians to degrees + #define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians + + #define EXP 2.71828182845904523536f //!< e + #define INVLOG2 3.32192809488736234787f //!< 1.0 / log10(2) + #define LN2 0.693147180559945f //!< ln(2) + #define INVLN2 1.44269504089f //!< 1.0f / ln(2) + + #define INV3 0.33333333333333333333f //!< 1/3 + #define INV6 0.16666666666666666666f //!< 1/6 + #define INV7 0.14285714285714285714f //!< 1/7 + #define INV9 0.11111111111111111111f //!< 1/9 + #define INV255 0.00392156862745098039f //!< 1/255 + + #define SQRT2 1.41421356237f //!< sqrt(2) + #define INVSQRT2 0.707106781188f //!< 1 / sqrt(2) + + #define SQRT3 1.73205080757f //!< sqrt(3) + #define INVSQRT3 0.577350269189f //!< 1 / sqrt(3) + + #define null 0 //!< our own NULL pointer + + // Custom types used in ICE + typedef signed char sbyte; //!< sizeof(sbyte) must be 1 + typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1 + typedef signed short sword; //!< sizeof(sword) must be 2 + typedef unsigned short uword; //!< sizeof(uword) must be 2 + typedef signed int sdword; //!< sizeof(sdword) must be 4 + typedef unsigned int udword; //!< sizeof(udword) must be 4 +#ifdef WIN32 + typedef signed __int64 sqword; //!< sizeof(sqword) must be 8 + typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8 +#elif LINUX + typedef signed long long sqword; //!< sizeof(sqword) must be 8 + typedef unsigned long long uqword; //!< sizeof(uqword) must be 8 +#elif defined(__APPLE__) + typedef signed long long sqword; //!< sizeof(sqword) must be 8 + typedef unsigned long long uqword; //!< sizeof(uqword) must be 8 +#elif defined(_XBOX) + typedef signed __int64 sqword; //!< sizeof(sqword) must be 8 + typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8 +#endif + typedef float float32; //!< sizeof(float32) must be 4 + typedef double float64; //!< sizeof(float64) must be 8 + typedef size_t regsize; //!< sizeof(regsize) must be sizeof(void*) + + // For test purpose you can force one of those: +// typedef udword regsize; +// typedef uqword regsize; + + ICE_COMPILE_TIME_ASSERT(sizeof(bool)==1); // ...otherwise things might fail with VC++ 4.2 ! + ICE_COMPILE_TIME_ASSERT(sizeof(ubyte)==1); + ICE_COMPILE_TIME_ASSERT(sizeof(sbyte)==1); + ICE_COMPILE_TIME_ASSERT(sizeof(sword)==2); + ICE_COMPILE_TIME_ASSERT(sizeof(uword)==2); + ICE_COMPILE_TIME_ASSERT(sizeof(udword)==4); + ICE_COMPILE_TIME_ASSERT(sizeof(sdword)==4); + ICE_COMPILE_TIME_ASSERT(sizeof(uqword)==8); + ICE_COMPILE_TIME_ASSERT(sizeof(sqword)==8); + ICE_COMPILE_TIME_ASSERT(sizeof(float32)==4); + ICE_COMPILE_TIME_ASSERT(sizeof(float64)==8); + ICE_COMPILE_TIME_ASSERT(sizeof(regsize)==sizeof(void*)); + + //! TO BE DOCUMENTED + #define DECLARE_ICE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name + + typedef udword DynID; //!< Dynamic identifier +#ifdef USE_HANDLE_MANAGER + typedef udword KID; //!< Kernel ID +// DECLARE_ICE_HANDLE(KID); +#else + typedef uword KID; //!< Kernel ID +#endif + #define INVALID_ID 0xffffffff //!< Invalid dword ID (counterpart of null pointers) +#ifdef USE_HANDLE_MANAGER + #define INVALID_KID 0xffffffff //!< Invalid Kernel ID +#else + #define INVALID_KID 0xffff //!< Invalid Kernel ID +#endif + #define INVALID_NUMBER 0xDEADBEEF //!< Standard junk value + + // Define BOOL if needed + #ifndef BOOL + typedef int BOOL; //!< Another boolean type. + #endif + + //! Union of a float and a sdword + typedef union { + float f; //!< The float + sdword d; //!< The integer + }scell; + + //! Union of a float and a udword + typedef union { + float f; //!< The float + udword d; //!< The integer + }ucell; + + // Type ranges + #define MAX_SBYTE 0x7f //!< max possible sbyte value + #define MIN_SBYTE 0x80 //!< min possible sbyte value + #define MAX_UBYTE 0xff //!< max possible ubyte value + #define MIN_UBYTE 0x00 //!< min possible ubyte value + #define MAX_SWORD 0x7fff //!< max possible sword value + #define MIN_SWORD 0x8000 //!< min possible sword value + #define MAX_UWORD 0xffff //!< max possible uword value + #define MIN_UWORD 0x0000 //!< min possible uword value + #define MAX_SDWORD 0x7fffffff //!< max possible sdword value + #define MIN_SDWORD 0x80000000 //!< min possible sdword value + #define MAX_UDWORD 0xffffffff //!< max possible udword value + #define MIN_UDWORD 0x00000000 //!< min possible udword value + #define MAX_FLOAT FLT_MAX //!< max possible float value + #define MIN_FLOAT (-FLT_MAX) //!< min possible loat value + #define IEEE_1_0 0x3f800000 //!< integer representation of 1.0 + #define IEEE_255_0 0x437f0000 //!< integer representation of 255.0 + #define IEEE_MAX_FLOAT 0x7f7fffff //!< integer representation of MAX_FLOAT + #define IEEE_MIN_FLOAT 0xff7fffff //!< integer representation of MIN_FLOAT + #define IEEE_UNDERFLOW_LIMIT 0x1a000000 + + #define ONE_OVER_RAND_MAX (1.0f / float(RAND_MAX)) //!< Inverse of the max possible value returned by rand() + + typedef void** VTABLE; //!< A V-Table. + + #undef MIN + #undef MAX + #define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< Returns the min value between a and b + #define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< Returns the max value between a and b + #define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c + + template inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; } + template inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; } + template inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; } + template inline_ void TSetMax (T& a, const T& b) { if(a> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); + n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); + n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); + n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); + n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000); + // Etc for larger integers (64 bits in Java) + // NOTE: the >> operation must be unsigned! (>>> in java) + } + + //! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection) + inline_ udword CountBits(udword n) + { + // This relies of the fact that the count of n bits can NOT overflow + // an n bit integer. EG: 1 bit count takes a 1 bit integer, 2 bit counts + // 2 bit integer, 3 bit count requires only a 2 bit integer. + // So we add all bit pairs, then each nible, then each byte etc... + n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1); + n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2); + n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4); + n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8); + n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16); + // Etc for larger integers (64 bits in Java) + // NOTE: the >> operation must be unsigned! (>>> in java) + return n; + } + + //! Even faster? + inline_ udword CountBits2(udword bits) + { + bits = bits - ((bits >> 1) & 0x55555555); + bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333); + bits = ((bits >> 4) + bits) & 0x0F0F0F0F; + return (bits * 0x01010101) >> 24; + } + + // "Population Count (Ones Count) + // The population count of a binary integer value x is the number of one bits in the value. Although many machines have + // single instructions for this, the single instructions are usually microcoded loops that test a bit per cycle; a log-time + // algorithm coded in C is often faster. The following code uses a variable-precision SWAR algorithm to perform a tree + // reduction adding the bits in a 32-bit value:" + inline_ udword ones32(udword x) + { + /* 32-bit recursive reduction using SWAR... + but first step is mapping 2-bit values + into sum of 2 1-bit values in sneaky way + */ + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return (x & 0x0000003f); + // "It is worthwhile noting that the SWAR population count algorithm given above can be improved upon for the case of + // counting the population of multi-word bit sets. How? The last few steps in the reduction are using only a portion + // of the SWAR width to produce their results; thus, it would be possible to combine these steps across multiple words + // being reduced. One additional note: the AMD Athlon optimization guidelines suggest a very similar algorithm that + // replaces the last three lines with return((x * 0x01010101) >> 24);. For the Athlon (which has a very fast integer + // multiply), I would have expected AMD's code to be faster... but it is actually 6% slower according to my benchmarks + // using a 1.2GHz Athlon (a Thunderbird). Why? Well, it so happens that GCC doesn't use a multiply instruction - it + // writes out the equivalent shift and add sequence!" + } + + // "Trailing Zero Count + // Given the Least Significant 1 Bit and Population Count (Ones Count) algorithms, it is trivial to combine them to + // construct a trailing zero count (as pointed-out by Joe Bowbeer):" + inline_ udword tzc(sdword x) + { + return(ones32((x & -x) - 1)); + } + + //! Spread out bits. EG 00001111 -> 0101010101 + //! 00001010 -> 0100010000 + //! This is used to interleave two integers to produce a `Morton Key' + //! used in Space Filling Curves (See DrDobbs Journal, July 1999) + //! Order is important. + inline_ void SpreadBits(udword& n) + { + n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16); + n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8); + n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4); + n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2); + n = ( n & 0x11111111) | (( n & 0x22222222) << 1); + } + + // "Next Largest Power of 2 + // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm + // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with + // the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next + // largest power of 2. For a 32-bit value:" + inline_ udword NextPowerOfTwo(udword x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return x+1; + } + + //! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection) + inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); } + + //! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection) + inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); } + + //! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection) + inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<> 31; return (x^y)-y; } + + // "Integer Minimum or Maximum + // Given 2's complement integer values x and y, the minimum can be computed without any branches as + // x+(((y-x)>>(WORDBITS-1))&(y-x)). + // Logically, this works because the shift by (WORDBITS-1) replicates the sign bit to create a mask + // -- be aware, however, that the C language does not require that shifts are signed even if their + // operands are signed, so there is a potential portability problem. Additionally, one might think + // that a shift by any number greater than or equal to WORDBITS would have the same effect, but many + // instruction sets have shifts that behave strangely when such shift distances are specified. + // Of course, maximum can be computed using the same trick: + // x-(((x-y)>>(WORDBITS-1))&(x-y))." + + //!< Alternative min function + inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); } + //!< Alternative max function + inline_ sdword max_(sdword a, sdword b) { sdword delta = a-b; return a - (delta&(delta>>31)); } + + // "Integer Selection + // A branchless, lookup-free, alternative to code like if (a> (WORDBITS-1)) & (c^d)) ^ d). + // This code assumes that the shift is signed, which, of course, C does not promise." + inline_ sdword IntegerSelection(sdword a, sdword b, sdword c, sdword d) + { + return ((((a-b)>>31) & (c^d)) ^ d); + } + + // Determine if one of the bytes in a 4 byte word is zero + inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); } + + // To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0 + inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); } +// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); } + + // "Most Significant 1 Bit + // Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set) + // can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits. + // This process yields a bit vector with the same most significant 1 as x, but all 1's below it. + // Bitwise AND of the original value with the complement of the "folded" value shifted down by one + // yields the most significant bit. For a 32-bit value:" + inline_ udword msb32(udword x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return (x & ~(x >> 1)); + } + + // "Gray Code Conversion + // A Gray code is any binary coding sequence in which only a single bit position changes as we move from one value to the next. + // There are many such codes, but the traditional one is computed such that the Kth Gray code is K^(K>>1). + // + // The well-known algorithm for conversion from Gray to binary is a linear sequence of XORs that makes it seem each bit must be + // dealt with separately. Fortunately, that is equivalent to a parallel prefix XOR that can be computed using SWAR techniques + // in log time. For 32-bit Gray code values produced as described above, the conversion from Gray code back to unsigned binary is:" + inline_ udword g2b(udword gray) + { + gray ^= (gray >> 16); + gray ^= (gray >> 8); + gray ^= (gray >> 4); + gray ^= (gray >> 2); + gray ^= (gray >> 1); + return gray; + } + + /* + "Just call it repeatedly with various input values and always with the same variable as "memory". + The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1 + does no filtering at all. + + I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed + to the more typical FIR (Finite Impulse Response). + + Also, I'd say that you can make more intelligent and interesting filters than this, for example filters + that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter + to be applied before this one, of course." + + (JCAB on Flipcode) + */ + inline_ float FeedbackFilter(float val, float& memory, float sharpness) + { + ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter"); + if(sharpness<0.0f) sharpness = 0.0f; + else if(sharpness>1.0f) sharpness = 1.0f; + return memory = val * sharpness + memory * (1.0f - sharpness); + } + + //! "If you can guarantee that your input domain (i.e. value of x) is slightly + //! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the + //! following code to clamp the resulting value into [-32768,+32767] range:" + inline_ int ClampToInt16(int x) + { +// ASSERT(abs(x) < (int)((1<<31u)-32767)); + + int delta = 32767 - x; + x += (delta>>31) & delta; + delta = x + 32768; + x -= (delta>>31) & delta; + return x; + } + + // Generic functions + template inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; } + template inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((xhi) ? hi : x); } + + template inline_ void TSort(Type& a, Type& b) + { + if(a>b) TSwap(a, b); + } + + template inline_ void TSort(Type& a, Type& b, Type& c) + { + if(a>b) TSwap(a, b); + if(b>c) TSwap(b, c); + if(a>b) TSwap(a, b); + if(b>c) TSwap(b, c); + } + + // Prevent nasty user-manipulations (strategy borrowed from Charles Bloom) +// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); } + // ... actually this is better ! + #define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object); + + //! TO BE DOCUMENTED + #define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member) + + //! TO BE DOCUMENTED + #if !defined(_XBOX) + // Already defined on Xbox. + #define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) + #endif + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns the alignment of the input address. + * \fn Alignment() + * \param address [in] address to check + * \return the best alignment (e.g. 1 for odd addresses, etc) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + FUNCTION ICECORE_API udword Alignment(udword address); + + #define IS_ALIGNED_2(x) ((x&1)==0) + #define IS_ALIGNED_4(x) ((x&3)==0) + #define IS_ALIGNED_8(x) ((x&7)==0) + + // Updates a pointer with "stride" bytes + inline_ void UpdatePtr(void*& ptr, udword stride) { ptr = ((ubyte*)ptr) + stride; } + + // From Jon Watte IIRC + inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; } + + // Compute implicit coords from an index: + // The idea is to get back 2D coords from a 1D index. + // For example: + // + // 0 1 2 ... nbu-1 + // nbu nbu+1 i ... + // + // We have i, we're looking for the equivalent (u=2, v=1) location. + // i = u + v*nbu + // <=> i/nbu = u/nbu + v + // Since 0 <= u < nbu, u/nbu = 0 (integer) + // Hence: v = i/nbu + // Then we simply put it back in the original equation to compute u = i - v*nbu + inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu) + { + v = i / nbu; + u = i - (v * nbu); + } + + // In 3D: i = u + v*nbu + w*nbu*nbv + // <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w + // u/(nbu*nbv) is null since u/nbu was null already. + // v/nbv is null as well for the same reason. + // Hence w = i/(nbu*nbv) + // Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu + inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv) + { + w = i / (nbu_nbv); + Compute2DCoords(u, v, i - (w * nbu_nbv), nbu); + } + + // Calling fsincos instead of fsin+fcos. Twice faster. + inline_ void FSinCos(float& c, float& s, float f) + { + float LocalCos, LocalSin; + float Local = f; +#ifdef WIN32 + _asm fld Local + _asm fsincos + _asm fstp LocalCos + _asm fstp LocalSin +#elif LINUX + asm("fld Local\n\t" + "fsincos\n\t" + "fstp LocalCos\n\t" + "fstp LocalSin\n\t" + ); +#endif + c = LocalCos; + s = LocalSin; + } + + // Modulo3 macros. See http://www.codercorner.com/Modulo3.htm + #define GET_NEXT_INDICES(i, j, k) \ + k = 0x01000201; \ + k>>=(i<<3); \ + j = k & 0xff; \ + k>>=8; \ + k&=0xff; + + #define GET_NEXT_INDICES2(i, j, k) \ + j = ( 9 >> (i<<1)) & 3; \ + k = (18 >> (i<<1)) & 3; + + // 0=>1, 1=>2, 2=>0 + inline_ udword Modulo3(udword i) + { + ASSERT(i==0 || i==1 || i==2); + return (9 >> (i << 1)) & 3; + } + +#endif // ICEUTILS_H diff --git a/Extras/CDTestFramework/Opcode/Ice/_IceAABB.h b/Extras/CDTestFramework/Opcode/Ice/_IceAABB.h new file mode 100644 index 0000000..23375fa --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/_IceAABB.h @@ -0,0 +1,522 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains AABB-related code. (axis-aligned bounding box) + * \file IceAABB.h + * \author Pierre Terdiman + * \date January, 13, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEAABB_H__ +#define __ICEAABB_H__ + + // Forward declarations + class Sphere; + +//! Declarations of type-independent methods (most of them implemented in the .cpp) +#define AABB_COMMON_METHODS \ + AABB& Add(const AABB& aabb); \ + float MakeCube(AABB& cube) const; \ + void MakeSphere(Sphere& sphere) const; \ + const sbyte* ComputeOutline(const Point& local_eye, sdword& num) const; \ + float ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const; \ + bool IsInside(const AABB& box) const; \ + bool ComputePlanes(Plane* planes) const; \ + bool ComputePoints(Point* pts) const; \ + const Point* GetVertexNormals() const; \ + const udword* GetEdges() const; \ + const Point* GetEdgeNormals() const; \ + inline_ BOOL ContainsPoint(const Point& p) const \ + { \ + if(p.x > GetMax(0) || p.x < GetMin(0)) return FALSE; \ + if(p.y > GetMax(1) || p.y < GetMin(1)) return FALSE; \ + if(p.z > GetMax(2) || p.z < GetMin(2)) return FALSE; \ + return TRUE; \ + } + + enum AABBType + { + AABB_RENDER = 0, //!< AABB used for rendering. Not visible == not rendered. + AABB_UPDATE = 1, //!< AABB used for dynamic updates. Not visible == not updated. + + AABB_FORCE_DWORD = 0x7fffffff, + }; + +#ifdef USE_MINMAX + + struct ICEMATHS_API ShadowAABB + { + Point mMin; + Point mMax; + }; + + class ICEMATHS_API AABB + { + public: + //! Constructor + inline_ AABB() {} + //! Destructor + inline_ ~AABB() {} + + //! Type-independent methods + AABB_COMMON_METHODS; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetMinMax(const Point& min, const Point& max) { mMin = min; mMax = max; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from center & extents vectors. + * \param c [in] the center point + * \param e [in] the extents vector + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetCenterExtents(const Point& c, const Point& e) { mMin = c - e; mMax = c + e; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() { Point p(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); mMin = -p; mMax = p;} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups a point AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetPoint(const Point& pt) { mMin = mMax = pt; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the size of the AABB. The size is defined as the longest extent. + * \return the size of the AABB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + float GetSize() const { Point e; GetExtents(e); return e.Max(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Extends the AABB. + * \param p [in] the next point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Extend(const Point& p) + { + if(p.x > mMax.x) mMax.x = p.x; + if(p.x < mMin.x) mMin.x = p.x; + + if(p.y > mMax.y) mMax.y = p.y; + if(p.y < mMin.y) mMin.y = p.y; + + if(p.z > mMax.z) mMax.z = p.z; + if(p.z < mMin.z) mMin.z = p.z; + } + // Data access + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mMin; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mMax; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mMin[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mMax[axis]; } + + //! Get box center + inline_ void GetCenter(Point& center) const { center = (mMax + mMin)*0.5f; } + //! Get box extents + inline_ void GetExtents(Point& extents) const { extents = (mMax - mMin)*0.5f; } + + //! Get component of the box's center along a given axis + inline_ float GetCenter(udword axis) const { return (mMax[axis] + mMin[axis])*0.5f; } + //! Get component of the box's extents along a given axis + inline_ float GetExtents(udword axis) const { return (mMax[axis] - mMin[axis])*0.5f; } + + //! Get box diagonal + inline_ void GetDiagonal(Point& diagonal) const { diagonal = mMax - mMin; } + inline_ float GetWidth() const { return mMax.x - mMin.x; } + inline_ float GetHeight() const { return mMax.y - mMin.y; } + inline_ float GetDepth() const { return mMax.z - mMin.z; } + + //! Volume + inline_ float GetVolume() const { return GetWidth() * GetHeight() * GetDepth(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the intersection between two AABBs. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a) const + { + if(mMax.x < a.mMin.x + || a.mMax.x < mMin.x + || mMax.y < a.mMin.y + || a.mMax.y < mMin.y + || mMax.z < a.mMin.z + || a.mMax.z < mMin.z) return FALSE; + + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the 1D-intersection between two AABBs, on a given axis. + * \param a [in] the other AABB + * \param axis [in] the axis (0, 1, 2) + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a, udword axis) const + { + if(mMax[axis] < a.mMin[axis] || a.mMax[axis] < mMin[axis]) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. + * Original code by Charles Bloom on the GD-Algorithm list. (I slightly modified it) + * \param mtx [in] the transform matrix + * \param aabb [out] the transformed AABB [can be *this] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const + { + // The three edges transformed: you can efficiently transform an X-only vector + // by just getting the "X" column of the matrix + Point vx,vy,vz; + mtx.GetRow(0, vx); vx *= (mMax.x - mMin.x); + mtx.GetRow(1, vy); vy *= (mMax.y - mMin.y); + mtx.GetRow(2, vz); vz *= (mMax.z - mMin.z); + + // Transform the min point + aabb.mMin = aabb.mMax = mMin * mtx; + + // Take the transformed min & axes and find new extents + // Using CPU code in the right place is faster... + if(IS_NEGATIVE_FLOAT(vx.x)) aabb.mMin.x += vx.x; else aabb.mMax.x += vx.x; + if(IS_NEGATIVE_FLOAT(vx.y)) aabb.mMin.y += vx.y; else aabb.mMax.y += vx.y; + if(IS_NEGATIVE_FLOAT(vx.z)) aabb.mMin.z += vx.z; else aabb.mMax.z += vx.z; + if(IS_NEGATIVE_FLOAT(vy.x)) aabb.mMin.x += vy.x; else aabb.mMax.x += vy.x; + if(IS_NEGATIVE_FLOAT(vy.y)) aabb.mMin.y += vy.y; else aabb.mMax.y += vy.y; + if(IS_NEGATIVE_FLOAT(vy.z)) aabb.mMin.z += vy.z; else aabb.mMax.z += vy.z; + if(IS_NEGATIVE_FLOAT(vz.x)) aabb.mMin.x += vz.x; else aabb.mMax.x += vz.x; + if(IS_NEGATIVE_FLOAT(vz.y)) aabb.mMin.y += vz.y; else aabb.mMax.y += vz.y; + if(IS_NEGATIVE_FLOAT(vz.z)) aabb.mMin.z += vz.z; else aabb.mMax.z += vz.z; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the AABB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Min, Max) boxes: min < max + if(mMin.x > mMax.x) return FALSE; + if(mMin.y > mMax.y) return FALSE; + if(mMin.z > mMax.z) return FALSE; + return TRUE; + } + + //! Operator for AABB *= float. Scales the extents, keeps same center. + inline_ AABB& operator*=(float s) + { + Point Center; GetCenter(Center); + Point Extents; GetExtents(Extents); + SetCenterExtents(Center, Extents * s); + return *this; + } + + //! Operator for AABB /= float. Scales the extents, keeps same center. + inline_ AABB& operator/=(float s) + { + Point Center; GetCenter(Center); + Point Extents; GetExtents(Extents); + SetCenterExtents(Center, Extents / s); + return *this; + } + + //! Operator for AABB += Point. Translates the box. + inline_ AABB& operator+=(const Point& trans) + { + mMin+=trans; + mMax+=trans; + return *this; + } + private: + Point mMin; //!< Min point + Point mMax; //!< Max point + }; + +#else + + class ICEMATHS_API AABB + { + public: + //! Constructor + inline_ AABB() {} + //! Destructor + inline_ ~AABB() {} + + //! Type-independent methods + AABB_COMMON_METHODS; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from center & extents vectors. + * \param c [in] the center point + * \param e [in] the extents vector + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetCenterExtents(const Point& c, const Point& e) { mCenter = c; mExtents = e; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups a point AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetPoint(const Point& pt) { mCenter = pt; mExtents.Zero(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the size of the AABB. The size is defined as the longest extent. + * \return the size of the AABB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + float GetSize() const { return mExtents.Max(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Extends the AABB. + * \param p [in] the next point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Extend(const Point& p) + { + Point Max = mCenter + mExtents; + Point Min = mCenter - mExtents; + + if(p.x > Max.x) Max.x = p.x; + if(p.x < Min.x) Min.x = p.x; + + if(p.y > Max.y) Max.y = p.y; + if(p.y < Min.y) Min.y = p.y; + + if(p.z > Max.z) Max.z = p.z; + if(p.z < Min.z) Min.z = p.z; + + SetMinMax(Min, Max); + } + // Data access + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } + + //! Get box center + inline_ void GetCenter(Point& center) const { center = mCenter; } + //! Get box extents + inline_ void GetExtents(Point& extents) const { extents = mExtents; } + + //! Get component of the box's center along a given axis + inline_ float GetCenter(udword axis) const { return mCenter[axis]; } + //! Get component of the box's extents along a given axis + inline_ float GetExtents(udword axis) const { return mExtents[axis]; } + + //! Get box diagonal + inline_ void GetDiagonal(Point& diagonal) const { diagonal = mExtents * 2.0f; } + inline_ float GetWidth() const { return mExtents.x * 2.0f; } + inline_ float GetHeight() const { return mExtents.y * 2.0f; } + inline_ float GetDepth() const { return mExtents.z * 2.0f; } + + //! Volume + inline_ float GetVolume() const { return mExtents.x * mExtents.y * mExtents.z * 8.0f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the intersection between two AABBs. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a) const + { + float tx = mCenter.x - a.mCenter.x; float ex = a.mExtents.x + mExtents.x; if(AIR(tx) > IR(ex)) return FALSE; + float ty = mCenter.y - a.mCenter.y; float ey = a.mExtents.y + mExtents.y; if(AIR(ty) > IR(ey)) return FALSE; + float tz = mCenter.z - a.mCenter.z; float ez = a.mExtents.z + mExtents.z; if(AIR(tz) > IR(ez)) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * The standard intersection method from Gamasutra. Just here to check its speed against the one above. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool GomezIntersect(const AABB& a) + { + Point T = mCenter - a.mCenter; // Vector from A to B + return ((fabsf(T.x) <= (a.mExtents.x + mExtents.x)) + && (fabsf(T.y) <= (a.mExtents.y + mExtents.y)) + && (fabsf(T.z) <= (a.mExtents.z + mExtents.z))); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the 1D-intersection between two AABBs, on a given axis. + * \param a [in] the other AABB + * \param axis [in] the axis (0, 1, 2) + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a, udword axis) const + { + float t = mCenter[axis] - a.mCenter[axis]; + float e = a.mExtents[axis] + mExtents[axis]; + if(AIR(t) > IR(e)) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. + * \param mtx [in] the transform matrix + * \param aabb [out] the transformed AABB [can be *this] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const + { + // Compute new center + aabb.mCenter = mCenter * mtx; + + // Compute new extents. FPU code & CPU code have been interleaved for improved performance. + Point Ex(mtx.m[0][0] * mExtents.x, mtx.m[0][1] * mExtents.x, mtx.m[0][2] * mExtents.x); + IR(Ex.x)&=0x7fffffff; IR(Ex.y)&=0x7fffffff; IR(Ex.z)&=0x7fffffff; + + Point Ey(mtx.m[1][0] * mExtents.y, mtx.m[1][1] * mExtents.y, mtx.m[1][2] * mExtents.y); + IR(Ey.x)&=0x7fffffff; IR(Ey.y)&=0x7fffffff; IR(Ey.z)&=0x7fffffff; + + Point Ez(mtx.m[2][0] * mExtents.z, mtx.m[2][1] * mExtents.z, mtx.m[2][2] * mExtents.z); + IR(Ez.x)&=0x7fffffff; IR(Ez.y)&=0x7fffffff; IR(Ez.z)&=0x7fffffff; + + aabb.mExtents.x = Ex.x + Ey.x + Ez.x; + aabb.mExtents.y = Ex.y + Ey.y + Ez.y; + aabb.mExtents.z = Ex.z + Ey.z + Ez.z; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the AABB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Center, Extents) boxes: Extents >= 0 + if(IS_NEGATIVE_FLOAT(mExtents.x)) return FALSE; + if(IS_NEGATIVE_FLOAT(mExtents.y)) return FALSE; + if(IS_NEGATIVE_FLOAT(mExtents.z)) return FALSE; + return TRUE; + } + + //! Operator for AABB *= float. Scales the extents, keeps same center. + inline_ AABB& operator*=(float s) { mExtents*=s; return *this; } + + //! Operator for AABB /= float. Scales the extents, keeps same center. + inline_ AABB& operator/=(float s) { mExtents/=s; return *this; } + + //! Operator for AABB += Point. Translates the box. + inline_ AABB& operator+=(const Point& trans) + { + mCenter+=trans; + return *this; + } + private: + Point mCenter; //!< AABB Center + Point mExtents; //!< x, y and z extents + }; + +#endif + + inline_ void ComputeMinMax(const Point& p, Point& min, Point& max) + { + if(p.x > max.x) max.x = p.x; + if(p.x < min.x) min.x = p.x; + + if(p.y > max.y) max.y = p.y; + if(p.y < min.y) min.y = p.y; + + if(p.z > max.z) max.z = p.z; + if(p.z < min.z) min.z = p.z; + } + + inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts) + { + if(list) + { + Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT); + while(nb_pts--) + { +// _prefetch(list+1); // off by one ? + ComputeMinMax(*list++, Mini, Maxi); + } + aabb.SetMinMax(Mini, Maxi); + } + } + +#endif // __ICEAABB_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/_IceContainer.cpp b/Extras/CDTestFramework/Opcode/Ice/_IceContainer.cpp new file mode 100644 index 0000000..b5b6734 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/_IceContainer.cpp @@ -0,0 +1,361 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a simple container class. + * \file IceContainer.cpp + * \author Pierre Terdiman + * \date February, 5, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a list of 32-bits values. + * Use this class when you need to store an unknown number of values. The list is automatically + * resized and can contains 32-bits entities (dwords or floats) + * + * \class Container + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +// Static members +#ifdef CONTAINER_STATS +udword Container::mNbContainers = 0; +udword Container::mUsedRam = 0; +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. No entries allocated there. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. Also allocates a given number of entries. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(growth_factor) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); +#endif + SetSize(size); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Copy constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); +#endif + *this = object; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. Frees everything and leaves. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::~Container() +{ + Empty(); +#ifdef CONTAINER_STATS + mNbContainers--; + mUsedRam-=GetUsedRam(); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Clears the container. All stored values are deleted, and it frees used ram. + * \see Reset() + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container& Container::Empty() +{ +#ifdef CONTAINER_STATS + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + DELETEARRAY(mEntries); + mCurNbEntries = mMaxNbEntries = 0; + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Resizes the container. + * \param needed [in] assume the container can be added at least "needed" values + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::Resize(udword needed) +{ +#ifdef CONTAINER_STATS + // Subtract previous amount of bytes + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + + // Get more entries + mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2 + if(mMaxNbEntriesmMaxNbEntries) Resize(nb); + + // Add new entry + CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword)); + mCurNbEntries+=nb; + return *this; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * A O(1) method to add a value in the container. The container is automatically resized if needed. + * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation + * costs a lot more than the call overhead... + * + * \param entry [in] a float to store in the container + * \see Add(udword entry) + * \see Empty() + * \see Contains(udword entry) + * \return Self-Reference + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ Container& Add(float entry) + { + // Resize if needed + if(mCurNbEntries==mMaxNbEntries) Resize(); + + // Add new entry + mEntries[mCurNbEntries++] = IR(entry); + return *this; + } + + inline_ Container& Add(const float* entries, udword nb) + { + // Resize if needed + if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); + + // Add new entry + CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float)); + mCurNbEntries+=nb; + return *this; + } + + //! Add unique [slow] + inline_ Container& AddUnique(udword entry) + { + if(!Contains(entry)) Add(entry); + return *this; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Clears the container. All stored values are deleted, and it frees used ram. + * \see Reset() + * \return Self-Reference + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Container& Empty(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again. + * That's a kind of temporal coherence. + * \see Empty() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Reset() + { + // Avoid the write if possible + // ### CMOV + if(mCurNbEntries) mCurNbEntries = 0; + } + + // HANDLE WITH CARE + inline_ void ForceSize(udword size) + { + mCurNbEntries = size; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Sets the initial size of the container. If it already contains something, it's discarded. + * \param nb [in] Number of entries + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetSize(udword nb); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the container and get rid of unused bytes. + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Refit(); + + // Checks whether the container already contains a given value. + bool Contains(udword entry, udword* location=null) const; + // Deletes an entry - doesn't preserve insertion order. + bool Delete(udword entry); + // Deletes an entry - does preserve insertion order. + bool DeleteKeepingOrder(udword entry); + //! Deletes the very last entry. + inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; } + //! Deletes the entry whose index is given + inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; } + + // Helpers + Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP); + Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP); + // Data access. + inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries. + inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry + inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries. + + inline_ udword GetFirst() const { return mEntries[0]; } + inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; } + + // Growth control + inline_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor + inline_ void SetGrowthFactor(float growth) { mGrowthFactor = growth; } //!< Sets the growth factor + inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full + inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty + + //! Read-access as an array + inline_ udword operator[](udword i) const { ASSERT(i>=0 && i=0 && i>31); + return (float&)y; + } + + //! Computes 1.0f / sqrtf(x). + inline_ float frsqrt(float f) + { + float x = f * 0.5f; + udword y = 0x5f3759df - ((udword&)f >> 1); + // Iteration... + (float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) ); + // Result + return (float&)y; + } + + //! Computes 1.0f / sqrtf(x). Comes from NVIDIA. + inline_ float InvSqrt(const float& x) + { + udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1; + float y = *(float*)&tmp; + return y * (1.47f - 0.47f * x * y * y); + } + + //! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above. + //! See http://www.magic-software.com/3DGEDInvSqrt.html + inline_ float RSqrt(float number) + { + long i; + float x2, y; + const float threehalfs = 1.5f; + + x2 = number * 0.5f; + y = number; + i = * (long *) &y; + i = 0x5f3759df - (i >> 1); + y = * (float *) &i; + y = y * (threehalfs - (x2 * y * y)); + + return y; + } + + //! TO BE DOCUMENTED + inline_ float fsqrt(float f) + { + udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000; + // Iteration...? + // (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f; + // Result + return (float&)y; + } + + //! Returns the float ranged espilon value. + inline_ float fepsilon(float f) + { + udword b = (udword&)f & 0xff800000; + udword a = b | 0x00000001; + (float&)a -= (float&)b; + // Result + return (float&)a; + } + + //! Is the float valid ? + inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; } + inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; } + inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; } + inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; } + + inline_ bool IsValidFloat(float value) + { + if(IsNAN(value)) return false; + if(IsIndeterminate(value)) return false; + if(IsPlusInf(value)) return false; + if(IsMinusInf(value)) return false; + return true; + } + + #define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x)); + +/* + //! FPU precision setting function. + inline_ void SetFPU() + { + // This function evaluates whether the floating-point + // control word is set to single precision/round to nearest/ + // exceptions disabled. If these conditions don't hold, the + // function changes the control word to set them and returns + // TRUE, putting the old control word value in the passback + // location pointed to by pwOldCW. + { + uword wTemp, wSave; + + __asm fstcw wSave + if (wSave & 0x300 || // Not single mode + 0x3f != (wSave & 0x3f) || // Exceptions enabled + wSave & 0xC00) // Not round to nearest mode + { + __asm + { + mov ax, wSave + and ax, not 300h ;; single mode + or ax, 3fh ;; disable all exceptions + and ax, not 0xC00 ;; round to nearest mode + mov wTemp, ax + fldcw wTemp + } + } + } + } +*/ + //! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON) + inline_ float ComputeFloatEpsilon() + { + float f = 1.0f; + ((udword&)f)^=1; + return f - 1.0f; // You can check it's the same as FLT_EPSILON + } + + inline_ bool IsFloatZero(float x, float epsilon=1e-6f) + { + return x*x < epsilon; + } + + #define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0 + #define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0 + #define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0 + #define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0 + + #define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1 + #define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1 + #define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1 + #define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1 + + #define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2 + #define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2 + #define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2 + #define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2 + + #define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3 + #define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3 + #define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3 + #define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3 + + #define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4 + #define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4 + #define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4 + #define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4 + + #define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5 + #define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5 + #define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5 + #define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5 + + #define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6 + #define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6 + #define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6 + #define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6 + + #define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7 + #define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7 + #define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7 + #define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7 + + //! A global function to find MAX(a,b) using FCOMI/FCMOV + inline_ float FCMax2(float a, float b) + { + float Res; + _asm fld [a] + _asm fld [b] + FCOMI_ST1 + FCMOVB_ST1 + _asm fstp [Res] + _asm fcomp + return Res; + } + + //! A global function to find MIN(a,b) using FCOMI/FCMOV + inline_ float FCMin2(float a, float b) + { + float Res; + _asm fld [a] + _asm fld [b] + FCOMI_ST1 + FCMOVNB_ST1 + _asm fstp [Res] + _asm fcomp + return Res; + } + + //! A global function to find MAX(a,b,c) using FCOMI/FCMOV + inline_ float FCMax3(float a, float b, float c) + { + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + FCOMI_ST1 + FCMOVB_ST1 + FCOMI_ST2 + FCMOVB_ST2 + _asm fstp [Res] + _asm fcompp + return Res; + } + + //! A global function to find MIN(a,b,c) using FCOMI/FCMOV + inline_ float FCMin3(float a, float b, float c) + { + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + FCOMI_ST1 + FCMOVNB_ST1 + FCOMI_ST2 + FCMOVNB_ST2 + _asm fstp [Res] + _asm fcompp + return Res; + } + + inline_ int ConvertToSortable(float f) + { + int& Fi = (int&)f; + int Fmask = (Fi>>31); + Fi ^= Fmask; + Fmask &= ~(1<<31); + Fi -= Fmask; + return Fi; + } + + enum FPUMode + { + FPU_FLOOR = 0, + FPU_CEIL = 1, + FPU_BEST = 2, + + FPU_FORCE_DWORD = 0x7fffffff + }; + + FUNCTION ICECORE_API FPUMode GetFPUMode(); + FUNCTION ICECORE_API void SaveFPU(); + FUNCTION ICECORE_API void RestoreFPU(); + FUNCTION ICECORE_API void SetFPUFloorMode(); + FUNCTION ICECORE_API void SetFPUCeilMode(); + FUNCTION ICECORE_API void SetFPUBestMode(); + + FUNCTION ICECORE_API void SetFPUPrecision24(); + FUNCTION ICECORE_API void SetFPUPrecision53(); + FUNCTION ICECORE_API void SetFPUPrecision64(); + FUNCTION ICECORE_API void SetFPURoundingChop(); + FUNCTION ICECORE_API void SetFPURoundingUp(); + FUNCTION ICECORE_API void SetFPURoundingDown(); + FUNCTION ICECORE_API void SetFPURoundingNear(); + + FUNCTION ICECORE_API int intChop(const float& f); + FUNCTION ICECORE_API int intFloor(const float& f); + FUNCTION ICECORE_API int intCeil(const float& f); + +#endif // __ICEFPU_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/_IceMemoryMacros.h b/Extras/CDTestFramework/Opcode/Ice/_IceMemoryMacros.h new file mode 100644 index 0000000..c1867dc --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/_IceMemoryMacros.h @@ -0,0 +1,121 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains all memory macros. + * \file IceMemoryMacros.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEMEMORYMACROS_H__ +#define __ICEMEMORYMACROS_H__ + +#undef ZeroMemory +#undef CopyMemory +#undef MoveMemory +#undef FillMemory + + //! Clears a buffer. + //! \param addr [in] buffer address + //! \param size [in] buffer length + //! \see FillMemory + //! \see StoreDwords + //! \see CopyMemory + //! \see MoveMemory + inline_ void ZeroMemory(void* addr, udword size) { memset(addr, 0, size); } + + //! Fills a buffer with a given byte. + //! \param addr [in] buffer address + //! \param size [in] buffer length + //! \param val [in] the byte value + //! \see StoreDwords + //! \see ZeroMemory + //! \see CopyMemory + //! \see MoveMemory + inline_ void FillMemory(void* dest, udword size, ubyte val) { memset(dest, val, size); } + + //! Fills a buffer with a given dword. + //! \param addr [in] buffer address + //! \param nb [in] number of dwords to write + //! \param value [in] the dword value + //! \see FillMemory + //! \see ZeroMemory + //! \see CopyMemory + //! \see MoveMemory + //! \warning writes nb*4 bytes ! + inline_ void StoreDwords(udword* dest, udword nb, udword value) + { + // The asm code below **SHOULD** be equivalent to one of those C versions + // or the other if your compiled is good: (checked on VC++ 6.0) + // + // 1) while(nb--) *dest++ = value; + // + // 2) for(udword i=0;iRelease(); (x) = null; } //!< Safe D3D-style release + #define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; } //!< Safe ICE-style release + +#ifdef __ICEERROR_H__ + #define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY); //!< Standard alloc checking. HANDLE WITH CARE. +#else + #define CHECKALLOC(x) if(!x) return false; +#endif + + //! Standard allocation cycle + #define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr); + +#endif // __ICEMEMORYMACROS_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/_IcePreprocessor.h b/Extras/CDTestFramework/Opcode/Ice/_IcePreprocessor.h new file mode 100644 index 0000000..8019343 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/_IcePreprocessor.h @@ -0,0 +1,144 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains preprocessor stuff. This should be the first included header. + * \file IcePreprocessor.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPREPROCESSOR_H__ +#define __ICEPREPROCESSOR_H__ + + // Check platform + #if defined( _WIN32 ) || defined( WIN32 ) + #pragma message("Compiling on Windows...") + #define PLATFORM_WINDOWS + #else + #pragma message("Compiling on unknown platform...") + #endif + + // Check compiler + #if defined(_MSC_VER) + #pragma message("Compiling with VC++...") + #define COMPILER_VISUAL_CPP + #else + #pragma message("Compiling with unknown compiler...") + #endif + + // Check compiler options. If this file is included in user-apps, this + // shouldn't be needed, so that they can use what they like best. + #ifndef ICE_DONT_CHECK_COMPILER_OPTIONS + #ifdef COMPILER_VISUAL_CPP + #if defined(_CHAR_UNSIGNED) + #endif + + #if defined(_CPPRTTI) + #error Please disable RTTI... + #endif + + #if defined(_CPPUNWIND) + #error Please disable exceptions... + #endif + + #if defined(_MT) + // Multithreading + #endif + #endif + #endif + + // Check debug mode + #ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it. + #ifndef _DEBUG + #define _DEBUG + #endif + #endif + + #ifdef _DEBUG + // Here you may define items for debug builds + #endif + + #ifndef THIS_FILE + #define THIS_FILE __FILE__ + #endif + + #ifndef ICE_NO_DLL + #ifdef ICECORE_EXPORTS + #define ICECORE_API __declspec(dllexport) + #else + #define ICECORE_API __declspec(dllimport) + #endif + #else + #define ICECORE_API + #endif + + // Don't override new/delete +// #define DEFAULT_NEWDELETE + #define DONT_TRACK_MEMORY_LEAKS + + #define FUNCTION extern "C" + + // Cosmetic stuff [mainly useful with multiple inheritance] + #define override(base_class) virtual + + // Our own inline keyword, so that: + // - we can switch to __forceinline to check it's really better or not + // - we can remove __forceinline if the compiler doesn't support it +// #define inline_ __forceinline +// #define inline_ inline + + // Contributed by Bruce Mitchener + #if defined(COMPILER_VISUAL_CPP) + #define inline_ __forceinline +// #define inline_ inline + #elif defined(__GNUC__) && __GNUC__ < 3 + #define inline_ inline + #elif defined(__GNUC__) + #define inline_ inline __attribute__ ((always_inline)) + #else + #define inline_ inline + #endif + + // Down the hatch + #pragma inline_depth( 255 ) + + #ifdef COMPILER_VISUAL_CPP + #pragma intrinsic(memcmp) + #pragma intrinsic(memcpy) + #pragma intrinsic(memset) + #pragma intrinsic(strcat) + #pragma intrinsic(strcmp) + #pragma intrinsic(strcpy) + #pragma intrinsic(strlen) + #pragma intrinsic(abs) + #pragma intrinsic(labs) + #endif + + // ANSI compliance + #ifdef _DEBUG + // Remove painful warning in debug + inline_ bool __False__(){ return false; } + #define for if(__False__()){} else for + #else + #define for if(0){} else for + #endif + +#endif // __ICEPREPROCESSOR_H__ diff --git a/Extras/CDTestFramework/Opcode/Ice/_IceRevisitedRadix.cpp b/Extras/CDTestFramework/Opcode/Ice/_IceRevisitedRadix.cpp new file mode 100644 index 0000000..15e2468 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Ice/_IceRevisitedRadix.cpp @@ -0,0 +1,536 @@ +/* + * ICE / OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains source code from the article "Radix Sort Revisited". + * \file IceRevisitedRadix.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Revisited Radix Sort. + * This is my new radix routine: + * - it uses indices and doesn't recopy the values anymore, hence wasting less ram + * - it creates all the histograms in one run instead of four + * - it sorts words faster than dwords and bytes faster than words + * - it correctly sorts negative floating-point values by patching the offsets + * - it automatically takes advantage of temporal coherence + * - multiple keys support is a side effect of temporal coherence + * - it may be worth recoding in asm... (mainly to use FCOMI, FCMOV, etc) [it's probably memory-bound anyway] + * + * History: + * - 08.15.98: very first version + * - 04.04.00: recoded for the radix article + * - 12.xx.00: code lifting + * - 09.18.01: faster CHECK_PASS_VALIDITY thanks to Mark D. Shattuck (who provided other tips, not included here) + * - 10.11.01: added local ram support + * - 01.20.02: bugfix! In very particular cases the last pass was skipped in the float code-path, leading to incorrect sorting...... + * - 01.02.02: - "mIndices" renamed => "mRanks". That's a rank sorter after all. + * - ranks are not "reset" anymore, but implicit on first calls + * - 07.05.02: - offsets rewritten with one less indirection. + * - 11.03.02: - "bool" replaced with RadixHint enum + * + * \class RadixSort + * \author Pierre Terdiman + * \version 1.4 + * \date August, 15, 1998 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +To do: + - add an offset parameter between two input values (avoid some data recopy sometimes) + - unroll ? asm ? + - 11 bits trick & 3 passes as Michael did + - prefetch stuff the day I have a P3 + - make a version with 16-bits indices ? +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +#define INVALIDATE_RANKS mCurrentSize|=0x80000000 +#define VALIDATE_RANKS mCurrentSize&=0x7fffffff +#define CURRENT_SIZE (mCurrentSize&0x7fffffff) +#define INVALID_RANKS (mCurrentSize&0x80000000) + +#define CHECK_RESIZE(n) \ + if(n!=mPreviousSize) \ + { \ + if(n>mCurrentSize) Resize(n); \ + else ResetRanks(); \ + mPreviousSize = n; \ + } + +#define CREATE_HISTOGRAMS(type, buffer) \ + /* Clear counters/histograms */ \ + ZeroMemory(mHistogram, 256*4*sizeof(udword)); \ + \ + /* Prepare to count */ \ + ubyte* p = (ubyte*)input; \ + ubyte* pe = &p[nb*4]; \ + udword* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ \ + udword* h1= &mHistogram[256]; /* Histogram for second pass */ \ + udword* h2= &mHistogram[512]; /* Histogram for third pass */ \ + udword* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ \ + \ + bool AlreadySorted = true; /* Optimism... */ \ + \ + if(INVALID_RANKS) \ + { \ + /* Prepare for temporal coherence */ \ + type* Running = (type*)buffer; \ + type PrevVal = *Running; \ + \ + while(p!=pe) \ + { \ + /* Read input buffer in previous sorted order */ \ + type Val = *Running++; \ + /* Check whether already sorted or not */ \ + if(ValCurSize) Resize(nb); + mCurrentSize = nb; + INVALIDATE_RANKS; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main sort routine. + * This one is for integer values. After the call, mRanks contains a list of indices in sorted order, i.e. in the order you may process your data. + * \param input [in] a list of integer values to sort + * \param nb [in] number of values to sort, must be < 2^31 + * \param hint [in] RADIX_SIGNED to handle negative values, RADIX_UNSIGNED if you know your input buffer only contains positive values + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RadixSort& RadixSort::Sort(const udword* input, udword nb, RadixHint hint) +{ + // Checkings + if(!input || !nb || nb&0x80000000) return *this; + + // Stats + mTotalCalls++; + + // Resize lists if needed + CheckResize(nb); + +#ifdef RADIX_LOCAL_RAM + // Allocate histograms & offsets on the stack + udword mHistogram[256*4]; +// udword mOffset[256]; + udword* mLink[256]; +#endif + + // Create histograms (counters). Counters for all passes are created in one run. + // Pros: read input buffer once instead of four times + // Cons: mHistogram is 4Kb instead of 1Kb + // We must take care of signed/unsigned values for temporal coherence.... I just + // have 2 code paths even if just a single opcode changes. Self-modifying code, someone? + if(hint==RADIX_UNSIGNED) { CREATE_HISTOGRAMS(udword, input); } + else { CREATE_HISTOGRAMS(sdword, input); } + + // Compute #negative values involved if needed + udword NbNegativeValues = 0; + if(hint==RADIX_SIGNED) + { + // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128 + // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte, + // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers. + udword* h3= &mHistogram[768]; + for(udword i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part + } + + // Radix sort, j is the pass number (0=LSB, 3=MSB) + for(udword j=0;j<4;j++) + { + CHECK_PASS_VALIDITY(j); + + // Sometimes the fourth (negative) pass is skipped because all numbers are negative and the MSB is 0xFF (for example). This is + // not a problem, numbers are correctly sorted anyway. + if(PerformPass) + { + // Should we care about negative values? + if(j!=3 || hint==RADIX_UNSIGNED) + { + // Here we deal with positive values only + + // Create offsets +// mOffset[0] = 0; +// for(udword i=1;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; + mLink[0] = mRanks2; + for(udword i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + } + else + { + // This is a special case to correctly handle negative integers. They're sorted in the right order but at the wrong place. + + // Create biased offsets, in order for negative numbers to be sorted as well +// mOffset[0] = NbNegativeValues; // First positive number takes place after the negative ones + mLink[0] = &mRanks2[NbNegativeValues]; // First positive number takes place after the negative ones +// for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + + // Fixing the wrong place for negative values +// mOffset[128] = 0; + mLink[128] = mRanks2; +// for(i=129;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; + for(udword i=129;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + } + + // Perform Radix Sort + ubyte* InputBytes = (ubyte*)input; + InputBytes += j; + if(INVALID_RANKS) + { +// for(udword i=0;i>24; // Radix byte, same as above. AND is useless here (udword). + // ### cmp to be killed. Not good. Later. +// if(Radix<128) mRanks2[mOffset[Radix]++] = i; // Number is positive, same as above +// else mRanks2[--mOffset[Radix]] = i; // Number is negative, flip the sorting order + if(Radix<128) *mLink[Radix]++ = i; // Number is positive, same as above + else *(--mLink[Radix]) = i; // Number is negative, flip the sorting order + } + VALIDATE_RANKS; + } + else + { + for(udword i=0;i>24; // Radix byte, same as above. AND is useless here (udword). + // ### cmp to be killed. Not good. Later. +// if(Radix<128) mRanks2[mOffset[Radix]++] = mRanks[i]; // Number is positive, same as above +// else mRanks2[--mOffset[Radix]] = mRanks[i]; // Number is negative, flip the sorting order + if(Radix<128) *mLink[Radix]++ = mRanks[i]; // Number is positive, same as above + else *(--mLink[Radix]) = mRanks[i]; // Number is negative, flip the sorting order + } + } + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp; + } + else + { + // The pass is useless, yet we still have to reverse the order of current list if all values are negative. + if(UniqueVal>=128) + { + if(INVALID_RANKS) + { + // ###Possible? + for(udword i=0;i (b) ? (a) : (b)) //!< Returns the max value between a and b + #define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c + + template inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; } + template inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; } + template inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; } + template inline_ void TSetMax (T& a, const T& b) { if(a> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); + n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); + n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); + n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); + n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000); + // Etc for larger intergers (64 bits in Java) + // NOTE: the >> operation must be unsigned! (>>> in java) + } + + //! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection) + inline_ udword CountBits(udword n) + { + // This relies of the fact that the count of n bits can NOT overflow + // an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts + // 2 bit interger, 3 bit count requires only a 2 bit interger. + // So we add all bit pairs, then each nible, then each byte etc... + n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1); + n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2); + n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4); + n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8); + n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16); + // Etc for larger intergers (64 bits in Java) + // NOTE: the >> operation must be unsigned! (>>> in java) + return n; + } + + //! Even faster? + inline_ udword CountBits2(udword bits) + { + bits = bits - ((bits >> 1) & 0x55555555); + bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333); + bits = ((bits >> 4) + bits) & 0x0F0F0F0F; + return (bits * 0x01010101) >> 24; + } + + //! Spread out bits. EG 00001111 -> 0101010101 + //! 00001010 -> 0100010000 + //! This is used to interleve to intergers to produce a `Morten Key' + //! used in Space Filling Curves (See DrDobbs Journal, July 1999) + //! Order is important. + inline_ void SpreadBits(udword& n) + { + n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16); + n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8); + n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4); + n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2); + n = ( n & 0x11111111) | (( n & 0x22222222) << 1); + } + + // Next Largest Power of 2 + // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm + // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with + // the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next + // largest power of 2. For a 32-bit value: + inline_ udword nlpo2(udword x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return x+1; + } + + //! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection) + inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); } + + //! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection) + inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); } + + //! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection) + inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<> 31; return (x^y)-y; } + + //!< Alternative min function + inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); } + + // Determine if one of the bytes in a 4 byte word is zero + inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); } + + // To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0 + inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); } +// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); } + + // Most Significant 1 Bit + // Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set) + // can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits. + // This process yields a bit vector with the same most significant 1 as x, but all 1's below it. + // Bitwise AND of the original value with the complement of the "folded" value shifted down by one + // yields the most significant bit. For a 32-bit value: + inline_ udword msb32(udword x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return (x & ~(x >> 1)); + } + + /* + "Just call it repeatedly with various input values and always with the same variable as "memory". + The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1 + does no filtering at all. + + I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed + to the more typical FIR (Finite Impulse Response). + + Also, I'd say that you can make more intelligent and interesting filters than this, for example filters + that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter + to be applied before this one, of course." + + (JCAB on Flipcode) + */ + inline_ float FeedbackFilter(float val, float& memory, float sharpness) + { + ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter"); + if(sharpness<0.0f) sharpness = 0.0f; + else if(sharpness>1.0f) sharpness = 1.0f; + return memory = val * sharpness + memory * (1.0f - sharpness); + } + + //! If you can guarantee that your input domain (i.e. value of x) is slightly + //! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the + //! following code to clamp the resulting value into [-32768,+32767] range: + inline_ int ClampToInt16(int x) + { +// ASSERT(abs(x) < (int)((1<<31u)-32767)); + + int delta = 32767 - x; + x += (delta>>31) & delta; + delta = x + 32768; + x -= (delta>>31) & delta; + return x; + } + + // Generic functions + template inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; } + template inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((xhi) ? hi : x); } + + template inline_ void TSort(Type& a, Type& b) + { + if(a>b) TSwap(a, b); + } + + template inline_ void TSort(Type& a, Type& b, Type& c) + { + if(a>b) TSwap(a, b); + if(b>c) TSwap(b, c); + if(a>b) TSwap(a, b); + if(b>c) TSwap(b, c); + } + + // Prevent nasty user-manipulations (strategy borrowed from Charles Bloom) +// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); } + // ... actually this is better ! + #define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object); + + //! TO BE DOCUMENTED + #define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member) + //! TO BE DOCUMENTED + #define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns the alignment of the input address. + * \fn Alignment() + * \param address [in] address to check + * \return the best alignment (e.g. 1 for odd addresses, etc) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + FUNCTION ICECORE_API udword Alignment(udword address); + + #define IS_ALIGNED_2(x) ((x&1)==0) + #define IS_ALIGNED_4(x) ((x&3)==0) + #define IS_ALIGNED_8(x) ((x&7)==0) + + inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; } + + // Compute implicit coords from an index: + // The idea is to get back 2D coords from a 1D index. + // For example: + // + // 0 1 2 ... nbu-1 + // nbu nbu+1 i ... + // + // We have i, we're looking for the equivalent (u=2, v=1) location. + // i = u + v*nbu + // <=> i/nbu = u/nbu + v + // Since 0 <= u < nbu, u/nbu = 0 (integer) + // Hence: v = i/nbu + // Then we simply put it back in the original equation to compute u = i - v*nbu + inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu) + { + v = i / nbu; + u = i - (v * nbu); + } + + // In 3D: i = u + v*nbu + w*nbu*nbv + // <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w + // u/(nbu*nbv) is null since u/nbu was null already. + // v/nbv is null as well for the same reason. + // Hence w = i/(nbu*nbv) + // Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu + inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv) + { + w = i / (nbu_nbv); + Compute2DCoords(u, v, i - (w * nbu_nbv), nbu); + } + +#endif // __ICEUTILS_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_AABBCollider.cpp b/Extras/CDTestFramework/Opcode/OPC_AABBCollider.cpp new file mode 100644 index 0000000..568fd6b --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_AABBCollider.cpp @@ -0,0 +1,705 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an AABB collider. + * \file OPC_AABBCollider.cpp + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an AABB-vs-tree collider. + * + * \class AABBCollider + * \author Pierre Terdiman + * \version 1.3 + * \date January, 1st, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_BoxBoxOverlap.h" +#include "OPC_TriBoxOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(prim_index); + +//! AABB-triangle test +#define AABB_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index);\ + mLeafVerts[0] = *VP.Vertex[0]; \ + mLeafVerts[1] = *VP.Vertex[1]; \ + mLeafVerts[2] = *VP.Vertex[2]; \ + /* Perform triangle-box overlap test */ \ + if(TriBoxOverlap()) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollider::AABBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollider::~AABBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision AABB in world space + * \param model [in] Opcode model to collide with + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const Model& model) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - check temporal coherence + * + * \param cache [in/out] a box cache + * \param box [in] AABB in world space + * \return TRUE if we can return immediately + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL AABBCollider::InitQuery(AABBCache& cache, const CollisionAABB& box) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Keep track of the query box + mBox = box; + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the box (and set contact status if needed) + AABB_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence : + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the box (and set contact status if needed) + AABB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious): + if(IsCacheValid(cache) && mBox.IsInside(cache.FatBox)) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat box so that coherence will work for subsequent frames + mBox.mExtents *= cache.FatCoeff; + + // Update cache with query data (signature for cached faces) + cache.FatBox = mBox; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + // 5) Precompute min & max bounds if needed + mMin = box.mCenter - box.mExtents; + mMax = box.mCenter + box.mExtents; + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for vanilla AABB trees. + * \param cache [in/out] a box cache + * \param box [in] collision AABB in world space + * \param tree [in] AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree) +{ + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + if(InitQuery(cache, box)) return true; + + // Perform collision query + _Collide(tree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the AABB completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the AABB contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBCollider::AABBContainsBox(const Point& bc, const Point& be) +{ + if(mMin.x > bc.x - be.x) return FALSE; + if(mMin.y > bc.y - be.y) return FALSE; + if(mMin.z > bc.z - be.z) return FALSE; + + if(mMax.x < bc.x + be.x) return FALSE; + if(mMax.y < bc.y + be.y) return FALSE; + if(mMax.z < bc.z + be.z) return FALSE; + + return TRUE; +} + +#define TEST_BOX_IN_AABB(center, extents) \ + if(AABBContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + AABB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->IsLeaf()) + { + AABB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for vanilla AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBTreeNode* node) +{ + // Perform AABB-AABB overlap test + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!AABBAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf() || AABBContainsBox(Center, Extents)) + { + mFlags |= OPC_CONTACT; + mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _Collide(node->GetPos()); + _Collide(node->GetNeg()); + } +} + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridAABBCollider::HybridAABBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridAABBCollider::~HybridAABBCollider() +{ +} + +bool HybridAABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;imCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + AABB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + AABB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_AABBCollider.h b/Extras/CDTestFramework/Opcode/OPC_AABBCollider.h new file mode 100644 index 0000000..ca8aee9 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_AABBCollider.h @@ -0,0 +1,106 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an AABB collider. + * \file OPC_AABBCollider.h + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_AABBCOLLIDER_H__ +#define __OPC_AABBCOLLIDER_H__ + + struct OPCODE_API AABBCache : VolumeCache + { + AABBCache() : FatCoeff(1.1f) + { + FatBox.mCenter.Zero(); + FatBox.mExtents.Zero(); + } + + // Cached faces signature + CollisionAABB FatBox; //!< Box used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere + }; + + class OPCODE_API AABBCollider : public VolumeCollider + { + public: + // Constructor / Destructor + AABBCollider(); + virtual ~AABBCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision AABB in world space + * \param model [in] Opcode model to collide with + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(AABBCache& cache, const CollisionAABB& box, const Model& model); + // + bool Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree); + protected: + CollisionAABB mBox; //!< Query box in (center, extents) form + Point mMin; //!< Query box min point + Point mMax; //!< Query box max point + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL AABBContainsBox(const Point& bc, const Point& be); + inline_ BOOL AABBAABBOverlap(const Point& b, const Point& Pb); + inline_ BOOL TriBoxOverlap(); + // Init methods + BOOL InitQuery(AABBCache& cache, const CollisionAABB& box); + }; + + class OPCODE_API HybridAABBCollider : public AABBCollider + { + public: + // Constructor / Destructor + HybridAABBCollider(); + virtual ~HybridAABBCollider(); + + bool Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_AABBCOLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_AABBTree.cpp b/Extras/CDTestFramework/Opcode/OPC_AABBTree.cpp new file mode 100644 index 0000000..bb692bb --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_AABBTree.cpp @@ -0,0 +1,582 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a versatile AABB tree. + * \file OPC_AABBTree.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a generic AABB tree node. + * + * \class AABBTreeNode + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a generic AABB tree. + * This is a vanilla AABB tree, without any particular optimization. It contains anonymous references to + * user-provided primitives, which can theoretically be anything - triangles, boxes, etc. Each primitive + * is surrounded by an AABB, regardless of the primitive's nature. When the primitive is a triangle, the + * resulting tree can be converted into an optimized tree. If the primitive is a box, the resulting tree + * can be used for culling - VFC or occlusion -, assuming you cull on a mesh-by-mesh basis (modern way). + * + * \class AABBTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTreeNode::AABBTreeNode() : + mPos (null), +#ifndef OPC_NO_NEG_VANILLA_TREE + mNeg (null), +#endif + mNbPrimitives (0), + mNodePrimitives (null) +{ +#ifdef OPC_USE_TREE_COHERENCE + mBitmask = 0; +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTreeNode::~AABBTreeNode() +{ + // Opcode 1.3: + const AABBTreeNode* Pos = GetPos(); + const AABBTreeNode* Neg = GetNeg(); +#ifndef OPC_NO_NEG_VANILLA_TREE + if(!(mPos&1)) DELETESINGLE(Pos); + if(!(mNeg&1)) DELETESINGLE(Neg); +#else + if(!(mPos&1)) DELETEARRAY(Pos); +#endif + mNodePrimitives = null; // This was just a shortcut to the global list => no release + mNbPrimitives = 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Splits the node along a given axis. + * The list of indices is reorganized according to the split values. + * \param axis [in] splitting axis index + * \param builder [in] the tree builder + * \return the number of primitives assigned to the first child + * \warning this method reorganizes the internal list of primitives + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTreeNode::Split(udword axis, AABBTreeBuilder* builder) +{ + // Get node split value + float SplitValue = builder->GetSplittingValue(mNodePrimitives, mNbPrimitives, mBV, axis); + + udword NbPos = 0; + // Loop through all node-related primitives. Their indices range from mNodePrimitives[0] to mNodePrimitives[mNbPrimitives-1]. + // Those indices map the global list in the tree builder. + for(udword i=0;iGetSplittingValue(Index, axis); + + // Reorganize the list of indices in this order: positive - negative. + if(PrimitiveValue > SplitValue) + { + // Swap entries + udword Tmp = mNodePrimitives[i]; + mNodePrimitives[i] = mNodePrimitives[NbPos]; + mNodePrimitives[NbPos] = Tmp; + // Count primitives assigned to positive space + NbPos++; + } + } + return NbPos; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Subdivides the node. + * + * N + * / \ + * / \ + * N/2 N/2 + * / \ / \ + * N/4 N/4 N/4 N/4 + * (etc) + * + * A well-balanced tree should have a O(log n) depth. + * A degenerate tree would have a O(n) depth. + * Note a perfectly-balanced tree is not well-suited to collision detection anyway. + * + * \param builder [in] the tree builder + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeNode::Subdivide(AABBTreeBuilder* builder) +{ + // Checkings + if(!builder) return false; + + // Stop subdividing if we reach a leaf node. This is always performed here, + // else we could end in trouble if user overrides this. + if(mNbPrimitives==1) return true; + + // Let the user validate the subdivision + if(!builder->ValidateSubdivision(mNodePrimitives, mNbPrimitives, mBV)) return true; + + bool ValidSplit = true; // Optimism... + udword NbPos; + if(builder->mSettings.mRules & SPLIT_LARGEST_AXIS) + { + // Find the largest axis to split along + Point Extents; mBV.GetExtents(Extents); // Box extents + udword Axis = Extents.LargestAxis(); // Index of largest axis + + // Split along the axis + NbPos = Split(Axis, builder); + + // Check split validity + if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false; + } + else if(builder->mSettings.mRules & SPLIT_SPLATTER_POINTS) + { + // Compute the means + Point Means(0.0f, 0.0f, 0.0f); + for(udword i=0;iGetSplittingValue(Index, 0); + Means.y+=builder->GetSplittingValue(Index, 1); + Means.z+=builder->GetSplittingValue(Index, 2); + } + Means/=float(mNbPrimitives); + + // Compute variances + Point Vars(0.0f, 0.0f, 0.0f); + for(udword i=0;iGetSplittingValue(Index, 0); + float Cy = builder->GetSplittingValue(Index, 1); + float Cz = builder->GetSplittingValue(Index, 2); + Vars.x += (Cx - Means.x)*(Cx - Means.x); + Vars.y += (Cy - Means.y)*(Cy - Means.y); + Vars.z += (Cz - Means.z)*(Cz - Means.z); + } + Vars/=float(mNbPrimitives-1); + + // Choose axis with greatest variance + udword Axis = Vars.LargestAxis(); + + // Split along the axis + NbPos = Split(Axis, builder); + + // Check split validity + if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false; + } + else if(builder->mSettings.mRules & SPLIT_BALANCED) + { + // Test 3 axis, take the best + float Results[3]; + NbPos = Split(0, builder); Results[0] = float(NbPos)/float(mNbPrimitives); + NbPos = Split(1, builder); Results[1] = float(NbPos)/float(mNbPrimitives); + NbPos = Split(2, builder); Results[2] = float(NbPos)/float(mNbPrimitives); + Results[0]-=0.5f; Results[0]*=Results[0]; + Results[1]-=0.5f; Results[1]*=Results[1]; + Results[2]-=0.5f; Results[2]*=Results[2]; + udword Min=0; + if(Results[1]mSettings.mRules & SPLIT_BEST_AXIS) + { + // Test largest, then middle, then smallest axis... + + // Sort axis + Point Extents; mBV.GetExtents(Extents); // Box extents + udword SortedAxis[] = { 0, 1, 2 }; + float* Keys = (float*)&Extents.x; + for(udword j=0;j<3;j++) + { + for(udword i=0;i<2;i++) + { + if(Keys[SortedAxis[i]]mSettings.mRules & SPLIT_FIFTY) + { + // Don't even bother splitting (mainly a performance test) + NbPos = mNbPrimitives>>1; + } + else return false; // Unknown splitting rules + + // Check the subdivision has been successful + if(!ValidSplit) + { + // Here, all boxes lie in the same sub-space. Two strategies: + // - if the tree *must* be complete, make an arbitrary 50-50 split + // - else stop subdividing +// if(builder->mSettings.mRules&SPLIT_COMPLETE) + if(builder->mSettings.mLimit==1) + { + builder->IncreaseNbInvalidSplits(); + NbPos = mNbPrimitives>>1; + } + else return true; + } + + // Now create children and assign their pointers. + if(builder->mNodeBase) + { + // We use a pre-allocated linear pool for complete trees [Opcode 1.3] + AABBTreeNode* Pool = (AABBTreeNode*)builder->mNodeBase; + udword Count = builder->GetCount() - 1; // Count begins to 1... + // Set last bit to tell it shouldn't be freed ### pretty ugly, find a better way. Maybe one bit in mNbPrimitives + ASSERT(!(udword(&Pool[Count+0])&1)); + ASSERT(!(udword(&Pool[Count+1])&1)); + mPos = udword(&Pool[Count+0])|1; +#ifndef OPC_NO_NEG_VANILLA_TREE + mNeg = udword(&Pool[Count+1])|1; +#endif + } + else + { + // Non-complete trees and/or Opcode 1.2 allocate nodes on-the-fly +#ifndef OPC_NO_NEG_VANILLA_TREE + mPos = (udword)new AABBTreeNode; CHECKALLOC(mPos); + mNeg = (udword)new AABBTreeNode; CHECKALLOC(mNeg); +#else + AABBTreeNode* PosNeg = new AABBTreeNode[2]; + CHECKALLOC(PosNeg); + mPos = (udword)PosNeg; +#endif + } + + // Update stats + builder->IncreaseCount(2); + + // Assign children + AABBTreeNode* Pos = (AABBTreeNode*)GetPos(); + AABBTreeNode* Neg = (AABBTreeNode*)GetNeg(); + Pos->mNodePrimitives = &mNodePrimitives[0]; + Pos->mNbPrimitives = NbPos; + Neg->mNodePrimitives = &mNodePrimitives[NbPos]; + Neg->mNbPrimitives = mNbPrimitives - NbPos; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive hierarchy building in a top-down fashion. + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeNode::_BuildHierarchy(AABBTreeBuilder* builder) +{ + // 1) Compute the global box for current node. The box is stored in mBV. + builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV); + + // 2) Subdivide current node + Subdivide(builder); + + // 3) Recurse + AABBTreeNode* Pos = (AABBTreeNode*)GetPos(); + AABBTreeNode* Neg = (AABBTreeNode*)GetNeg(); + if(Pos) Pos->_BuildHierarchy(builder); + if(Neg) Neg->_BuildHierarchy(builder); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the tree (top-down). + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeNode::_Refit(AABBTreeBuilder* builder) +{ + // 1) Recompute the new global box for current node + builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV); + + // 2) Recurse + AABBTreeNode* Pos = (AABBTreeNode*)GetPos(); + AABBTreeNode* Neg = (AABBTreeNode*)GetNeg(); + if(Pos) Pos->_Refit(builder); + if(Neg) Neg->_Refit(builder); +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTree::AABBTree() : mIndices(null), mTotalNbNodes(0), mPool(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTree::~AABBTree() +{ + Release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases the tree. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTree::Release() +{ + DELETEARRAY(mPool); + DELETEARRAY(mIndices); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a generic AABB tree from a tree builder. + * \param builder [in] the tree builder + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::Build(AABBTreeBuilder* builder) +{ + // Checkings + if(!builder || !builder->mNbPrimitives) return false; + + // Release previous tree + Release(); + + // Init stats + builder->SetCount(1); + builder->SetNbInvalidSplits(0); + + // Initialize indices. This list will be modified during build. + mIndices = new udword[builder->mNbPrimitives]; + CHECKALLOC(mIndices); + // Identity permutation + for(udword i=0;imNbPrimitives;i++) mIndices[i] = i; + + // Setup initial node. Here we have a complete permutation of the app's primitives. + mNodePrimitives = mIndices; + mNbPrimitives = builder->mNbPrimitives; + + // Use a linear array for complete trees (since we can predict the final number of nodes) [Opcode 1.3] +// if(builder->mRules&SPLIT_COMPLETE) + if(builder->mSettings.mLimit==1) + { + // Allocate a pool of nodes + mPool = new AABBTreeNode[builder->mNbPrimitives*2 - 1]; + + builder->mNodeBase = mPool; // ### ugly ! + } + + // Build the hierarchy + _BuildHierarchy(builder); + + // Get back total number of nodes + mTotalNbNodes = builder->GetCount(); + + // For complete trees, check the correct number of nodes has been created [Opcode 1.3] + if(mPool) ASSERT(mTotalNbNodes==builder->mNbPrimitives*2 - 1); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the depth of the tree. + * A well-balanced tree should have a log(n) depth. A degenerate tree O(n) depth. + * \return depth of the tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTree::ComputeDepth() const +{ + return Walk(null, null); // Use the walking code without callback +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree, calling the user back for each node. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTree::Walk(WalkingCallback callback, void* user_data) const +{ + // Call it without callback to compute max depth + udword MaxDepth = 0; + udword CurrentDepth = 0; + + struct Local + { + static void _Walk(const AABBTreeNode* current_node, udword& max_depth, udword& current_depth, WalkingCallback callback, void* user_data) + { + // Checkings + if(!current_node) return; + // Entering a new node => increase depth + current_depth++; + // Keep track of max depth + if(current_depth>max_depth) max_depth = current_depth; + + // Callback + if(callback && !(callback)(current_node, current_depth, user_data)) return; + + // Recurse + if(current_node->GetPos()) { _Walk(current_node->GetPos(), max_depth, current_depth, callback, user_data); current_depth--; } + if(current_node->GetNeg()) { _Walk(current_node->GetNeg(), max_depth, current_depth, callback, user_data); current_depth--; } + } + }; + Local::_Walk(this, MaxDepth, CurrentDepth, callback, user_data); + return MaxDepth; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the tree in a top-down way. + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::Refit(AABBTreeBuilder* builder) +{ + if(!builder) return false; + _Refit(builder); + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the tree in a bottom-up way. + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::Refit2(AABBTreeBuilder* builder) +{ + // Checkings + if(!builder) return false; + + ASSERT(mPool); + + // Bottom-up update + Point Min,Max; + Point Min_,Max_; + udword Index = mTotalNbNodes; + while(Index--) + { + AABBTreeNode& Current = mPool[Index]; + + if(Current.IsLeaf()) + { + builder->ComputeGlobalBox(Current.GetPrimitives(), Current.GetNbPrimitives(), *(AABB*)Current.GetAABB()); + } + else + { + Current.GetPos()->GetAABB()->GetMin(Min); + Current.GetPos()->GetAABB()->GetMax(Max); + + Current.GetNeg()->GetAABB()->GetMin(Min_); + Current.GetNeg()->GetAABB()->GetMax(Max_); + + Min.Min(Min_); + Max.Max(Max_); + + ((AABB*)Current.GetAABB())->SetMinMax(Min, Max); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the number of bytes used by the tree. + * \return number of bytes used + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTree::GetUsedBytes() const +{ + udword TotalSize = mTotalNbNodes*GetNodeSize(); + if(mIndices) TotalSize+=mNbPrimitives*sizeof(udword); + return TotalSize; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the tree is a complete tree or not. + * A complete tree is made of 2*N-1 nodes, where N is the number of primitives in the tree. + * \return true for complete trees + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::IsComplete() const +{ + return (GetNbNodes()==GetNbPrimitives()*2-1); +} diff --git a/Extras/CDTestFramework/Opcode/OPC_AABBTree.h b/Extras/CDTestFramework/Opcode/OPC_AABBTree.h new file mode 100644 index 0000000..c63bfa3 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_AABBTree.h @@ -0,0 +1,146 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a versatile AABB tree. + * \file OPC_AABBTree.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_AABBTREE_H__ +#define __OPC_AABBTREE_H__ + +#ifdef OPC_NO_NEG_VANILLA_TREE + //! TO BE DOCUMENTED + #define IMPLEMENT_TREE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + ~base_class(); \ + /* Data access */ \ + inline_ const volume* Get##volume() const { return &mBV; } \ + /* Clear the last bit */ \ + inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \ + inline_ const base_class* GetNeg() const { const base_class* P = GetPos(); return P ? P+1 : null;} \ + \ + /* We don't need to test both nodes since we can't have one without the other */ \ + inline_ bool IsLeaf() const { return !GetPos(); } \ + \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + protected: \ + /* Tree-independent data */ \ + /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \ + /* Whatever happens we need the two children and the enclosing volume.*/ \ + volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \ + udword mPos; /* "Positive" & "Negative" children */ +#else + //! TO BE DOCUMENTED + #define IMPLEMENT_TREE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + ~base_class(); \ + /* Data access */ \ + inline_ const volume* Get##volume() const { return &mBV; } \ + /* Clear the last bit */ \ + inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \ + inline_ const base_class* GetNeg() const { return (const base_class*)(mNeg&~1); } \ + \ +/* inline_ bool IsLeaf() const { return (!GetPos() && !GetNeg()); } */ \ + /* We don't need to test both nodes since we can't have one without the other */ \ + inline_ bool IsLeaf() const { return !GetPos(); } \ + \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + protected: \ + /* Tree-independent data */ \ + /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \ + /* Whatever happens we need the two children and the enclosing volume.*/ \ + volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \ + udword mPos; /* "Positive" child */ \ + udword mNeg; /* "Negative" child */ +#endif + + typedef void (*CullingCallback) (udword nb_primitives, udword* node_primitives, BOOL need_clipping, void* user_data); + + class OPCODE_API AABBTreeNode + { + IMPLEMENT_TREE(AABBTreeNode, AABB) + public: + // Data access + inline_ const udword* GetPrimitives() const { return mNodePrimitives; } + inline_ udword GetNbPrimitives() const { return mNbPrimitives; } + + protected: + // Tree-dependent data + udword* mNodePrimitives; //!< Node-related primitives (shortcut to a position in mIndices below) + udword mNbPrimitives; //!< Number of primitives for this node + // Internal methods + udword Split(udword axis, AABBTreeBuilder* builder); + bool Subdivide(AABBTreeBuilder* builder); + void _BuildHierarchy(AABBTreeBuilder* builder); + void _Refit(AABBTreeBuilder* builder); + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called for each node by the walking code. + * \param current [in] current node + * \param depth [in] current node's depth + * \param user_data [in] user-defined data + * \return true to recurse through children, else false to bypass them + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef bool (*WalkingCallback) (const AABBTreeNode* current, udword depth, void* user_data); + + class OPCODE_API AABBTree : public AABBTreeNode + { + public: + // Constructor / Destructor + AABBTree(); + ~AABBTree(); + // Build + bool Build(AABBTreeBuilder* builder); + void Release(); + + // Data access + inline_ const udword* GetIndices() const { return mIndices; } //!< Catch the indices + inline_ udword GetNbNodes() const { return mTotalNbNodes; } //!< Catch the number of nodes + + // Infos + bool IsComplete() const; + // Stats + udword ComputeDepth() const; + udword GetUsedBytes() const; + udword Walk(WalkingCallback callback, void* user_data) const; + + bool Refit(AABBTreeBuilder* builder); + bool Refit2(AABBTreeBuilder* builder); + private: + udword* mIndices; //!< Indices in the app list. Indices are reorganized during build (permutation). + AABBTreeNode* mPool; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3] + // Stats + udword mTotalNbNodes; //!< Number of nodes in the tree. + }; + +#endif // __OPC_AABBTREE_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_ArraySAP.cpp b/Extras/CDTestFramework/Opcode/OPC_ArraySAP.cpp new file mode 100644 index 0000000..3c1e767 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_ArraySAP.cpp @@ -0,0 +1,1228 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an array-based version of the sweep-and-prune algorithm + * \file OPC_ArraySAP.cpp + * \author Pierre Terdiman + * \date December, 2, 2007 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "StdAfx.h" + +using namespace Opcode; + +//#include "SAP_Utils.h" + +#define INVALID_USER_ID 0xffff + +inline_ void Sort(uword& id0, uword& id1) { if(id0>id1) TSwap(id0, id1); } +inline_ void Sort(uword& id0, uword& id1, const void*& obj0, const void*& obj1) { if(id0>id1) { TSwap(id0, id1); TSwap(obj0, obj1); } } + + + struct Opcode::IAABB : public Allocateable + { + udword mMinX; + udword mMinY; + udword mMinZ; + udword mMaxX; + udword mMaxY; + udword mMaxZ; + + inline_ udword GetMin(udword i) const { return (&mMinX)[i]; } + inline_ udword GetMax(udword i) const { return (&mMaxX)[i]; } + }; + + + +/* + - already sorted for batch create? + - better axis selection batch create +*/ + +//#define USE_WORDS // Use words or dwords for box indices. Words save memory but seriously limit the max number of objects in the SAP. +#define USE_PREFETCH +#define USE_INTEGERS +#define PAIR_USER_DATA +#define USE_OVERLAP_TEST_ON_REMOVES // "Useless" but faster overall because seriously reduces number of calls (from ~10000 to ~3 sometimes!) +#define RELEASE_ON_RESET // Release memory instead of just doing a reset + +#include "OPC_ArraySAP.h" + +//#include "SAP_PairManager.h" +//#include "SAP_PairManager.cpp" + + +inline_ udword Hash(uword id0, uword id1) { return Hash32Bits_1( udword(id0)|(udword(id1)<<16) ); } +inline_ bool DifferentPair(const ASAP_Pair& p, uword id0, uword id1) { return (id0!=p.id0) || (id1!=p.id1); } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ASAP_PairManager::ASAP_PairManager() : + mHashSize (0), + mMask (0), + mHashTable (null), + mNext (null), + mNbActivePairs (0), + mActivePairs (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ASAP_PairManager::~ASAP_PairManager() +{ + Purge(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ASAP_PairManager::Purge() +{ + ICE_FREE(mNext); + ICE_FREE(mActivePairs); + ICE_FREE(mHashTable); + mHashSize = 0; + mMask = 0; + mNbActivePairs = 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const ASAP_Pair* ASAP_PairManager::FindPair(uword id0, uword id1) const +{ + if(!mHashTable) return null; // Nothing has been allocated yet + + // Order the ids + Sort(id0, id1); + + // Compute hash value for this pair + udword HashValue = Hash(id0, id1) & mMask; + + // Look for it in the table + udword Offset = mHashTable[HashValue]; + while(Offset!=INVALID_ID && DifferentPair(mActivePairs[Offset], id0, id1)) + { + ASSERT(mActivePairs[Offset].id0!=INVALID_USER_ID); + Offset = mNext[Offset]; // Better to have a separate array for this + } + if(Offset==INVALID_ID) return null; + ASSERT(Offset the pair is persistent + return &mActivePairs[Offset]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Internal version saving hash computation +inline_ ASAP_Pair* ASAP_PairManager::FindPair(uword id0, uword id1, udword hash_value) const +{ + if(!mHashTable) return null; // Nothing has been allocated yet + + // Look for it in the table + udword Offset = mHashTable[hash_value]; + while(Offset!=INVALID_ID && DifferentPair(mActivePairs[Offset], id0, id1)) + { + ASSERT(mActivePairs[Offset].id0!=INVALID_USER_ID); + Offset = mNext[Offset]; // Better to have a separate array for this + } + if(Offset==INVALID_ID) return null; + ASSERT(Offset the pair is persistent + return &mActivePairs[Offset]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const ASAP_Pair* ASAP_PairManager::AddPair(uword id0, uword id1, const void* object0, const void* object1) +{ + // Order the ids + Sort(id0, id1, object0, object1); + + udword HashValue = Hash(id0, id1) & mMask; + + ASAP_Pair* P = FindPair(id0, id1, HashValue); + if(P) + { + return P; // Persistent pair + } + + // This is a new pair + if(mNbActivePairs >= mHashSize) + { + // Get more entries + mHashSize = NextPowerOfTwo(mNbActivePairs+1); + mMask = mHashSize-1; + + ReallocPairs(); + + // Recompute hash value with new hash size + HashValue = Hash(id0, id1) & mMask; + } + + ASAP_Pair* p = &mActivePairs[mNbActivePairs]; + p->id0 = id0; // ### CMOVs would be nice here + p->id1 = id1; + p->object0 = object0; + p->object1 = object1; + + mNext[mNbActivePairs] = mHashTable[HashValue]; + mHashTable[HashValue] = mNbActivePairs++; + return p; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ASAP_PairManager::RemovePair(uword id0, uword id1, udword hash_value, udword pair_index) +{ + // Walk the hash table to fix mNext + udword Offset = mHashTable[hash_value]; + ASSERT(Offset!=INVALID_ID); + + udword Previous=INVALID_ID; + while(Offset!=pair_index) + { + Previous = Offset; + Offset = mNext[Offset]; + } + + // Let us go/jump us + if(Previous!=INVALID_ID) + { + ASSERT(mNext[Previous]==pair_index); + mNext[Previous] = mNext[pair_index]; + } + // else we were the first + else mHashTable[hash_value] = mNext[pair_index]; + // we're now free to reuse mNext[PairIndex] without breaking the list + +#ifdef _DEBUG + mNext[pair_index]=INVALID_ID; +#endif + // Invalidate entry + + // Fill holes + if(1) + { + // 1) Remove last pair + const udword LastPairIndex = mNbActivePairs-1; + if(LastPairIndex==pair_index) + { + mNbActivePairs--; + } + else + { + const ASAP_Pair* Last = &mActivePairs[LastPairIndex]; + const udword LastHashValue = Hash(Last->id0, Last->id1) & mMask; + + // Walk the hash table to fix mNext + udword Offset = mHashTable[LastHashValue]; + ASSERT(Offset!=INVALID_ID); + + udword Previous=INVALID_ID; + while(Offset!=LastPairIndex) + { + Previous = Offset; + Offset = mNext[Offset]; + } + + // Let us go/jump us + if(Previous!=INVALID_ID) + { + ASSERT(mNext[Previous]==LastPairIndex); + mNext[Previous] = mNext[LastPairIndex]; + } + // else we were the first + else mHashTable[LastHashValue] = mNext[LastPairIndex]; + // we're now free to reuse mNext[LastPairIndex] without breaking the list + +#ifdef _DEBUG + mNext[LastPairIndex]=INVALID_ID; +#endif + + // Don't invalidate entry since we're going to shrink the array + + // 2) Re-insert in free slot + mActivePairs[pair_index] = mActivePairs[LastPairIndex]; +#ifdef _DEBUG + ASSERT(mNext[pair_index]==INVALID_ID); +#endif + mNext[pair_index] = mHashTable[LastHashValue]; + mHashTable[LastHashValue] = pair_index; + + mNbActivePairs--; + } + } +} + +bool ASAP_PairManager::RemovePair(uword id0, uword id1) +{ + // Order the ids + Sort(id0, id1); + + const udword HashValue = Hash(id0, id1) & mMask; + const ASAP_Pair* P = FindPair(id0, id1, HashValue); + if(!P) return false; + ASSERT(P->id0==id0); + ASSERT(P->id1==id1); + + RemovePair(id0, id1, HashValue, GetPairIndex(P)); + + ShrinkMemory(); + return true; +} + +bool ASAP_PairManager::RemovePairs(const BitArray& array) +{ + udword i=0; + while(i only less efficient but still ok + for(udword i=0;i>2; } + }; + + class Opcode::ASAP_Box : public Allocateable + { + public: + inline_ ASAP_Box() {} + inline_ ~ASAP_Box() {} + + IndexType mMin[3]; + IndexType mMax[3]; + void* mObject; + udword mGUID; + + inline_ void SetInvalid() { mMin[0]=INVALID_INDEX; } + inline_ bool IsValid() const { return mMin[0]!=INVALID_INDEX; } + + inline_ ValType GetMaxValue(udword i, const ASAP_EndPoint* base) const + { + return base[mMax[i]].mValue; + } + + inline_ ValType GetMinValue(udword i, const ASAP_EndPoint* base) const + { + return base[mMin[i]].mValue; + } +#ifdef _DEBUG + bool HasBeenInserted() const + { + assert(mMin[0]!=INVALID_INDEX); + assert(mMax[0]!=INVALID_INDEX); + assert(mMin[1]!=INVALID_INDEX); + assert(mMax[1]!=INVALID_INDEX); + assert(mMin[2]!=INVALID_INDEX); + assert(mMax[2]!=INVALID_INDEX); + return true; + } +#endif + }; + +inline_ BOOL Intersect1D_Min(const SAP_AABB& a, const ASAP_Box& b, const ASAP_EndPoint* const base, udword axis) +{ + if(b.GetMaxValue(axis, base) < a.GetMin(axis)) + return FALSE; + return TRUE; +} + +inline_ BOOL Intersect2D(const ASAP_Box& c, const ASAP_Box& b, udword axis1, udword axis2) +{ + if( b.mMax[axis1] < c.mMin[axis1] || c.mMax[axis1] < b.mMin[axis1] + || b.mMax[axis2] < c.mMin[axis2] || c.mMax[axis2] < b.mMin[axis2]) return FALSE; + return TRUE; +} + + +ArraySAP::ArraySAP() +{ + mNbBoxes = 0; + mMaxNbBoxes = 0; + mBoxes = null; + mEndPoints[0] = mEndPoints[1] = mEndPoints[2] = null; + mFirstFree = INVALID_ID; +} + +ArraySAP::~ArraySAP() +{ + mNbBoxes = 0; + mMaxNbBoxes = 0; + DELETEARRAY(mBoxes); + for(udword i=0;i<3;i++) + { + DELETEARRAY(mEndPoints[i]); + } +} + +void ArraySAP::ResizeBoxArray() +{ + const udword NewMaxBoxes = mMaxNbBoxes ? mMaxNbBoxes*2 : 64; + + ASAP_Box* NewBoxes = ICE_NEW_TMP(ASAP_Box)[NewMaxBoxes]; + const udword NbSentinels=2; + ASAP_EndPoint* NewEndPointsX = ICE_NEW_TMP(ASAP_EndPoint)[NewMaxBoxes*2+NbSentinels]; + ASAP_EndPoint* NewEndPointsY = ICE_NEW_TMP(ASAP_EndPoint)[NewMaxBoxes*2+NbSentinels]; + ASAP_EndPoint* NewEndPointsZ = ICE_NEW_TMP(ASAP_EndPoint)[NewMaxBoxes*2+NbSentinels]; + + if(mNbBoxes) + { + CopyMemory(NewBoxes, mBoxes, sizeof(ASAP_Box)*mNbBoxes); + CopyMemory(NewEndPointsX, mEndPoints[0], sizeof(ASAP_EndPoint)*(mNbBoxes*2+NbSentinels)); + CopyMemory(NewEndPointsY, mEndPoints[1], sizeof(ASAP_EndPoint)*(mNbBoxes*2+NbSentinels)); + CopyMemory(NewEndPointsZ, mEndPoints[2], sizeof(ASAP_EndPoint)*(mNbBoxes*2+NbSentinels)); + } + else + { + // Initialize sentinels +#ifdef USE_INTEGERS + const udword Min = EncodeFloat(MIN_FLOAT); + const udword Max = EncodeFloat(MAX_FLOAT); +#else + const float Min = MIN_FLOAT; + const float Max = MAX_FLOAT; +#endif + NewEndPointsX[0].SetData(Min, INVALID_INDEX, FALSE); + NewEndPointsX[1].SetData(Max, INVALID_INDEX, TRUE); + NewEndPointsY[0].SetData(Min, INVALID_INDEX, FALSE); + NewEndPointsY[1].SetData(Max, INVALID_INDEX, TRUE); + NewEndPointsZ[0].SetData(Min, INVALID_INDEX, FALSE); + NewEndPointsZ[1].SetData(Max, INVALID_INDEX, TRUE); + } + DELETEARRAY(mBoxes); + DELETEARRAY(mEndPoints[2]); + DELETEARRAY(mEndPoints[1]); + DELETEARRAY(mEndPoints[0]); + mBoxes = NewBoxes; + mEndPoints[0] = NewEndPointsX; + mEndPoints[1] = NewEndPointsY; + mEndPoints[2] = NewEndPointsZ; + + mMaxNbBoxes = NewMaxBoxes; +} + +inline_ BOOL Intersect(const IAABB& a, const IAABB& b, udword axis) +{ + if(b.GetMax(axis) < a.GetMin(axis) || a.GetMax(axis) < b.GetMin(axis)) return FALSE; + return TRUE; +} + +// ### TODO: the sorts here might be useless, as the values have been sorted already +bool ArraySAP::CompleteBoxPruning2(udword nb, const IAABB* array, const Axes& axes, const CreateData* batched) +{ + // Checkings + if(!nb || !array) return false; + + // Catch axes + const udword Axis0 = axes.mAxis0; + const udword Axis1 = axes.mAxis1; + const udword Axis2 = axes.mAxis2; + + // Allocate some temporary data + udword* PosList = (udword*)ICE_ALLOC_TMP(sizeof(udword)*(nb+1)); + + // 1) Build main list using the primary axis + for(udword i=0;iSort(PosList, nb, RADIX_SIGNED).GetRanks(); + const udword* Sorted = RS->Sort(PosList, nb, RADIX_UNSIGNED).GetRanks(); + + // 3) Prune the list + const udword* const LastSorted = &Sorted[nb]; + const udword* RunningAddress = Sorted; + udword Index0, Index1; + while(RunningAddressmObject, Box1->mObject, Box0->mGUID, Box1->mGUID); + } + } + } + } + } + + ICE_FREE(PosList); + return true; +} + +bool ArraySAP::BipartiteBoxPruning2(udword nb0, const IAABB* array0, udword nb1, const IAABB* array1, const Axes& axes, const CreateData* batched, const udword* box_indices) +{ + // Checkings + if(!nb0 || !array0 || !nb1 || !array1) return false; + + // Catch axes + const udword Axis0 = axes.mAxis0; + const udword Axis1 = axes.mAxis1; + const udword Axis2 = axes.mAxis2; + + // Allocate some temporary data + udword* MinPosList0 = (udword*)ICE_ALLOC_TMP(sizeof(udword)*nb0); + udword* MinPosList1 = (udword*)ICE_ALLOC_TMP(sizeof(udword)*nb1); + + // 1) Build main lists using the primary axis + for(udword i=0;iSort(MinPosList0, nb0, RADIX_UNSIGNED).GetRanks(); + const udword* Sorted1 = RS1->Sort(MinPosList1, nb1, RADIX_UNSIGNED).GetRanks(); + + // 3) Prune the lists + udword Index0, Index1; + + const udword* const LastSorted0 = &Sorted0[nb0]; + const udword* const LastSorted1 = &Sorted1[nb1]; + const udword* RunningAddress0 = Sorted0; + const udword* RunningAddress1 = Sorted1; + + while(RunningAddress1mObject, Box1->mObject, Box0->mGUID, Box1->mGUID); + } + } + } + } + + //// + + while(RunningAddress0mObject, Box1->mObject, Box0->mGUID, Box1->mGUID); + } + } + + } + } + + ICE_FREE(MinPosList0); + ICE_FREE(MinPosList1); + return true; +} + +udword ArraySAP::AddObject(void* object, uword guid, const AABB& box) +{ + assert(!(size_t(object)&3)); // We will use the 2 LSBs + +#ifdef _DEBUG + int a = sizeof(ASAP_Box); // 32 + int b = sizeof(ASAP_EndPoint); // 8 +#endif + + udword BoxIndex; + if(mFirstFree!=INVALID_ID) + { + BoxIndex = mFirstFree; + mFirstFree = mBoxes[BoxIndex].mGUID; + } + else + { + if(mNbBoxes==mMaxNbBoxes) + ResizeBoxArray(); + BoxIndex = mNbBoxes; + } + + ASAP_Box* Box = &mBoxes[BoxIndex]; + // Initialize box + Box->mObject = object; + Box->mGUID = guid; + for(udword i=0;i<3;i++) + { + Box->mMin[i] = INVALID_INDEX; + Box->mMax[i] = INVALID_INDEX; + } + + mNbBoxes++; + + CreateData* CD = (CreateData*)mCreated.Reserve(sizeof(CreateData)/sizeof(udword)); + CD->mHandle = BoxIndex; + CD->mBox = box; + + return BoxIndex; +} + +void ArraySAP::InsertEndPoints(udword axis, const ASAP_EndPoint* end_points, udword nb_endpoints) +{ + ASAP_EndPoint* const BaseEP = mEndPoints[axis]; + + const udword OldSize = mNbBoxes*2 - nb_endpoints; + const udword NewSize = mNbBoxes*2; + + BaseEP[NewSize + 1] = BaseEP[OldSize + 1]; + + sdword WriteIdx = NewSize; + udword CurrInsIdx = 0; + + const ASAP_EndPoint* First = &BaseEP[0]; + const ASAP_EndPoint* Current = &BaseEP[OldSize]; + while(Current>=First) + { + const ASAP_EndPoint& Src = *Current; + const ASAP_EndPoint& Ins = end_points[CurrInsIdx]; + + // We need to make sure we insert maxs before mins to handle exactly equal endpoints correctly + const bool ShouldInsert = Ins.IsMax() ? (Src.mValue <= Ins.mValue) : (Src.mValue < Ins.mValue); + + const ASAP_EndPoint& Moved = ShouldInsert ? Ins : Src; + BaseEP[WriteIdx] = Moved; + mBoxes[Moved.GetOwner()].mMin[axis + Moved.IsMax()] = WriteIdx--; + + if(ShouldInsert) + { + CurrInsIdx++; + if(CurrInsIdx >= nb_endpoints) + break;//we just inserted the last endpoint + } + else + { + Current--; + } + } +} + +void ArraySAP::BatchCreate() +{ + udword NbBatched = mCreated.GetNbEntries(); + if(!NbBatched) return; // Early-exit if no object has been created + NbBatched /= sizeof(CreateData)/sizeof(udword); + const CreateData* Batched = (const CreateData*)mCreated.GetEntries(); + mCreated.Reset(); + + { + const udword NbEndPoints = NbBatched*2; + ASAP_EndPoint* NewEPSorted = ICE_NEW_TMP(ASAP_EndPoint)[NbEndPoints]; + ASAP_EndPoint* Buffer = (ASAP_EndPoint*)ICE_ALLOC_TMP(sizeof(ASAP_EndPoint)*NbEndPoints); + RadixSort RS; + + for(udword Axis=0;Axis<3;Axis++) + { + for(udword i=0;iHasBeenInserted()); + } + for(udword i=0;imMin[0]; + NewBoxes[i].mMaxX = Box->mMax[0]; + NewBoxes[i].mMinY = Box->mMin[1]; + NewBoxes[i].mMaxY = Box->mMax[1]; + NewBoxes[i].mMinZ = Box->mMin[2]; + NewBoxes[i].mMaxZ = Box->mMax[2]; + } + + CompleteBoxPruning2(NbBatched, NewBoxes, Axes(AXES_XZY), Batched); + + // the old boxes are not the first ones in the array + + const udword NbOldBoxes = mNbBoxes - NbBatched; + if(NbOldBoxes) + { + IAABB* OldBoxes = ICE_NEW_TMP(IAABB)[NbOldBoxes]; + udword* OldBoxesIndices = (udword*)ICE_ALLOC_TMP(sizeof(udword)*NbOldBoxes); + udword Offset=0; + udword i=0; + while(imObject) + if(Box->IsValid()) + { + OldBoxesIndices[Offset] = i; + + OldBoxes[Offset].mMinX = Box->mMin[0]; + OldBoxes[Offset].mMaxX = Box->mMax[0]; + OldBoxes[Offset].mMinY = Box->mMin[1]; + OldBoxes[Offset].mMaxY = Box->mMax[1]; + OldBoxes[Offset].mMinZ = Box->mMin[2]; + OldBoxes[Offset].mMaxZ = Box->mMax[2]; + Offset++; + } + } + i++; + } +// assert(i==NbOldBoxes); + BipartiteBoxPruning2(NbBatched, NewBoxes, Offset, OldBoxes, Axes(AXES_XZY), Batched, OldBoxesIndices); + + ICE_FREE(OldBoxesIndices); + DELETEARRAY(OldBoxes); + } + DELETEARRAY(NewBoxes); + } +#ifdef RELEASE_ON_RESET + mCreated.Empty(); +#endif +} + +void ArraySAP::BatchRemove() +{ + udword NbRemoved = mRemoved.GetNbEntries(); + if(!NbRemoved) return; // Early-exit if no object has been removed + const udword* Removed = mRemoved.GetEntries(); + mRemoved.Reset(); + + for(udword Axis=0;Axis<3;Axis++) + { + ASAP_EndPoint* const BaseEP = mEndPoints[Axis]; + udword MinMinIndex = MAX_UDWORD; + for(udword i=0;imMin[Axis]; + assert(MinIndexmMax[Axis]; + assert(MaxIndexmMin[Axis + BaseEP[DestIndex].IsMax()] = DestIndex; + } + } + DestIndex++; + ReadIndex++; + } + } + } + + BitArray BA(65536); + const udword Saved = NbRemoved; + while(NbRemoved--) + { + udword Index = *Removed++; + assert(IndexmGUID < 65536); + BA.SetBit(Object->mGUID); + + Object->mGUID = mFirstFree; +// Object->mObject = null; // ########### + Object->SetInvalid(); + mFirstFree = Index; + } + mNbBoxes -= Saved; + mPairs.RemovePairs(BA); + +#ifdef RELEASE_ON_RESET + mRemoved.Empty(); +#endif +} + +bool ArraySAP::RemoveObject(udword handle) +{ + mRemoved.Add(handle); + return true; +} + +#ifdef USE_INTEGERS +bool ArraySAP::UpdateObject(udword handle, const AABB& box_) +#else +bool ArraySAP::UpdateObject(udword handle, const AABB& box) +#endif +{ + const ASAP_Box* Object = mBoxes + handle; + assert(Object->HasBeenInserted()); + const void* UserObject = Object->mObject; + const udword UserGUID = Object->mGUID; + +#ifdef USE_INTEGERS + IAABB box; + box.mMinX = EncodeFloat(box_.GetMin(0)); + box.mMinY = EncodeFloat(box_.GetMin(1)); + box.mMinZ = EncodeFloat(box_.GetMin(2)); + box.mMaxX = EncodeFloat(box_.GetMax(0)); + box.mMaxY = EncodeFloat(box_.GetMax(1)); + box.mMaxZ = EncodeFloat(box_.GetMax(2)); +#endif + + for(udword Axis=0;Axis<3;Axis++) + { + const udword Axis1 = (1 << Axis) & 3; + const udword Axis2 = (1 << Axis1) & 3; + + ASAP_EndPoint* const BaseEP = mEndPoints[Axis]; + + // Update min + { + ASAP_EndPoint* CurrentMin = BaseEP + Object->mMin[Axis]; + ASSERT(!CurrentMin->IsMax()); + + const ValType Limit = box.GetMin(Axis); + if(Limit < CurrentMin->mValue) + { + CurrentMin->mValue = Limit; + + // Min is moving left: + ASAP_EndPoint Saved = *CurrentMin; + udword EPIndex = (size_t(CurrentMin) - size_t(BaseEP))/sizeof(ASAP_EndPoint); + const udword SavedIndex = EPIndex; + + while((--CurrentMin)->mValue > Limit) + { +#ifdef USE_PREFETCH + _prefetch(CurrentMin-1); +#endif + ASAP_Box* id1 = mBoxes + CurrentMin->GetOwner(); + const BOOL IsMax = CurrentMin->IsMax(); + if(IsMax) + { + // Our min passed a max => start overlap + if(Object!=id1 + && Intersect2D(*Object, *id1, Axis1, Axis2) + && Intersect1D_Min(box, *id1, BaseEP, Axis) + ) + AddPair(UserObject, id1->mObject, UserGUID, id1->mGUID); + } + + id1->mMin[Axis + IsMax] = EPIndex--; + *(CurrentMin+1) = *CurrentMin; + } + + if(SavedIndex!=EPIndex) + { + mBoxes[Saved.GetOwner()].mMin[Axis + Saved.IsMax()] = EPIndex; + BaseEP[EPIndex] = Saved; + } + } + else if(Limit > CurrentMin->mValue) + { + CurrentMin->mValue = Limit; + + // Min is moving right: + ASAP_EndPoint Saved = *CurrentMin; + udword EPIndex = (size_t(CurrentMin) - size_t(BaseEP))/sizeof(ASAP_EndPoint); + const udword SavedIndex = EPIndex; + + while((++CurrentMin)->mValue < Limit) + { +#ifdef USE_PREFETCH + _prefetch(CurrentMin+1); +#endif + ASAP_Box* id1 = mBoxes + CurrentMin->GetOwner(); + const BOOL IsMax = CurrentMin->IsMax(); + if(IsMax) + { + // Our min passed a max => stop overlap + if(Object!=id1 +#ifdef USE_OVERLAP_TEST_ON_REMOVES + && Intersect2D(*Object, *id1, Axis1, Axis2) +#endif + ) + RemovePair(UserObject, id1->mObject, UserGUID, id1->mGUID); + } + + id1->mMin[Axis + IsMax] = EPIndex++; + *(CurrentMin-1) = *CurrentMin; + } + + if(SavedIndex!=EPIndex) + { + mBoxes[Saved.GetOwner()].mMin[Axis + Saved.IsMax()] = EPIndex; + BaseEP[EPIndex] = Saved; + } + } + } + + // Update max + { + ASAP_EndPoint* CurrentMax = BaseEP + Object->mMax[Axis]; + ASSERT(CurrentMax->IsMax()); + + const ValType Limit = box.GetMax(Axis); + if(Limit > CurrentMax->mValue) + { + CurrentMax->mValue = Limit; + + // Max is moving right: + ASAP_EndPoint Saved = *CurrentMax; + udword EPIndex = (size_t(CurrentMax) - size_t(BaseEP))/sizeof(ASAP_EndPoint); + const udword SavedIndex = EPIndex; + + while((++CurrentMax)->mValue < Limit) + { +#ifdef USE_PREFETCH + _prefetch(CurrentMax+1); +#endif + ASAP_Box* id1 = mBoxes + CurrentMax->GetOwner(); + const BOOL IsMax = CurrentMax->IsMax(); + if(!IsMax) + { + // Our max passed a min => start overlap + if(Object!=id1 + && Intersect2D(*Object, *id1, Axis1, Axis2) + && Intersect1D_Min(box, *id1, BaseEP, Axis) + ) + AddPair(UserObject, id1->mObject, UserGUID, id1->mGUID); + } + + id1->mMin[Axis + IsMax] = EPIndex++; + *(CurrentMax-1) = *CurrentMax; + } + + if(SavedIndex!=EPIndex) + { + mBoxes[Saved.GetOwner()].mMin[Axis + Saved.IsMax()] = EPIndex; + BaseEP[EPIndex] = Saved; + } + } + else if(Limit < CurrentMax->mValue) + { + CurrentMax->mValue = Limit; + + // Max is moving left: + ASAP_EndPoint Saved = *CurrentMax; + udword EPIndex = (size_t(CurrentMax) - size_t(BaseEP))/sizeof(ASAP_EndPoint); + const udword SavedIndex = EPIndex; + + while((--CurrentMax)->mValue > Limit) + { +#ifdef USE_PREFETCH + _prefetch(CurrentMax-1); +#endif + ASAP_Box* id1 = mBoxes + CurrentMax->GetOwner(); + const BOOL IsMax = CurrentMax->IsMax(); + if(!IsMax) + { + // Our max passed a min => stop overlap + if(Object!=id1 +#ifdef USE_OVERLAP_TEST_ON_REMOVES + && Intersect2D(*Object, *id1, Axis1, Axis2) +#endif + ) + RemovePair(UserObject, id1->mObject, UserGUID, id1->mGUID); + } + + id1->mMin[Axis + IsMax] = EPIndex--; + *(CurrentMax+1) = *CurrentMax; + } + + if(SavedIndex!=EPIndex) + { + mBoxes[Saved.GetOwner()].mMin[Axis + Saved.IsMax()] = EPIndex; + BaseEP[EPIndex] = Saved; + } + } + } + } + return true; +} + +udword ArraySAP::DumpPairs(SAP_CreatePair create_cb, SAP_DeletePair delete_cb, void* cb_user_data, ASAP_Pair** pairs) +{ + BatchCreate(); + + const udword* Entries = mData.GetEntries(); + const udword* Last = Entries + mData.GetNbEntries(); + mData.Reset(); + + udword* ToRemove = (udword*)Entries; + while(Entries!=Last) + { + const udword ID = *Entries++; + ASAP_Pair* UP = mPairs.mActivePairs + ID; + + { + ASSERT(UP->IsInArray()); + if(UP->IsRemoved()) + { + // No need to call "ClearInArray" in this case, since the pair will get removed anyway + + // Remove + if(delete_cb && !UP->IsNew()) + { +#ifdef PAIR_USER_DATA + (delete_cb)(UP->GetObject0(), UP->GetObject1(), cb_user_data, UP->userData); +#else + (delete_cb)(UP->GetObject0(), UP->GetObject1(), cb_user_data, null); +#endif + } + + *ToRemove++ = udword(UP->id0)<<16|UP->id1; + } + else + { + UP->ClearInArray(); + // Add => already there... Might want to create user data, though + if(UP->IsNew()) + { + if(create_cb) + { +#ifdef PAIR_USER_DATA + UP->userData = (create_cb)(UP->GetObject0(), UP->GetObject1(), cb_user_data); +#else + (create_cb)(UP->GetObject0(), UP->GetObject1(), cb_user_data); +#endif + } + UP->ClearNew(); + } + } + } + } + + // #### try batch removal here + Entries = mData.GetEntries(); + while(Entries!=ToRemove) + { + const udword ID = *Entries++; + const udword id0 = ID>>16; + const udword id1 = ID&0xffff; + bool Status = mPairs.RemovePair(id0, id1); + ASSERT(Status); + } + +#ifdef RELEASE_ON_RESET + mData.Empty(); +#endif + + BatchRemove(); + + if(pairs) *pairs = mPairs.mActivePairs; + + return mPairs.mNbActivePairs; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_ArraySAP.h b/Extras/CDTestFramework/Opcode/OPC_ArraySAP.h new file mode 100644 index 0000000..db35571 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_ArraySAP.h @@ -0,0 +1,159 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an array-based version of the sweep-and-prune algorithm + * \file OPC_ArraySAP.h + * \author Pierre Terdiman + * \date December, 2, 2007 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef OPC_ARRAYSAP_H +#define OPC_ARRAYSAP_H + +#pragma pack(1) + struct OPCODE_API ASAP_Pair + { + uword id0; + uword id1; + const void* object0; + const void* object1; +//#ifdef PAIR_USER_DATA + void* userData; +//#endif + inline_ const void* GetObject0() const { return (const void*)(size_t(object0) & ~3); } + inline_ const void* GetObject1() const { return (const void*)(size_t(object1) & ~3); } + inline_ size_t IsInArray() const { return size_t(object0) & 1; } + inline_ size_t IsRemoved() const { return size_t(object1) & 1; } + inline_ size_t IsNew() const { return size_t(object0) & 2; } + private: + inline_ void SetInArray() { object0 = (const void*)(size_t(object0) | 1); } + inline_ void SetRemoved() { object1 = (const void*)(size_t(object1) | 1); } + inline_ void SetNew() { object0 = (const void*)(size_t(object0) | 2); } + inline_ void ClearInArray() { object0 = (const void*)(size_t(object0) & ~1); } + inline_ void ClearRemoved() { object1 = (const void*)(size_t(object1) & ~1); } + inline_ void ClearNew() { object0 = (const void*)(size_t(object0) & ~2); } + + friend class ArraySAP; + }; +#pragma pack() + + class OPCODE_API ASAP_PairManager + { + public: + ASAP_PairManager(); + ~ASAP_PairManager(); + + void Purge(); + void ShrinkMemory(); + + const ASAP_Pair* AddPair (uword id0, uword id1, const void* object0, const void* object1); + bool RemovePair (uword id0, uword id1); + bool RemovePairs (const BitArray& array); + const ASAP_Pair* FindPair (uword id0, uword id1) const; + inline_ udword GetPairIndex(const ASAP_Pair* pair) const + { + return ((udword)((size_t(pair) - size_t(mActivePairs)))/sizeof(ASAP_Pair)); + } + + udword mHashSize; + udword mMask; + udword mNbActivePairs; + udword* mHashTable; + udword* mNext; + ASAP_Pair* mActivePairs; + inline_ ASAP_Pair* FindPair(uword id0, uword id1, udword hash_value) const; + void RemovePair(uword id0, uword id1, udword hash_value, udword pair_index); + void ReallocPairs(); + }; + + typedef void* (*SAP_CreatePair)(const void* object0, const void* object1, void* user_data); + typedef void (*SAP_DeletePair)(const void* object0, const void* object1, void* user_data, void* pair_user_data); + + // Forward declarations + class ASAP_EndPoint; + class ASAP_Box; + struct IAABB; + struct CreateData; + + class OPCODE_API ArraySAP : public Allocateable + { + public: + ArraySAP(); + ~ArraySAP(); + + udword AddObject(void* object, uword guid, const AABB& box); + bool RemoveObject(udword handle); + bool UpdateObject(udword handle, const AABB& box); + + udword DumpPairs(SAP_CreatePair create_cb, SAP_DeletePair delete_cb, void* cb_user_data, ASAP_Pair** pairs=null); + private: + Container mData; + ASAP_PairManager mPairs; + + inline_ void AddPair(const void* object0, const void* object1, uword id0, uword id1) + { + ASSERT(object0); + ASAP_Pair* UP = (ASAP_Pair*)mPairs.AddPair(id0, id1, null, null); + ASSERT(UP); + + if(UP->object0) + { + // Persistent pair + } + else + { + // New pair + ASSERT(!(int(object0)&1)); + ASSERT(!(int(object1)&1)); + UP->object0 = object0; + UP->object1 = object1; + UP->SetInArray(); + mData.Add(mPairs.GetPairIndex(UP)); + UP->SetNew(); + } + UP->ClearRemoved(); + } + + inline_ void RemovePair(const void* object0, const void* object1, uword id0, uword id1) + { + ASAP_Pair* UP = (ASAP_Pair*)mPairs.FindPair(id0, id1); + if(UP) + { + if(!UP->IsInArray()) + { + UP->SetInArray(); + mData.Add(mPairs.GetPairIndex(UP)); + } + UP->SetRemoved(); + } + } + + udword mNbBoxes; + udword mMaxNbBoxes; + ASAP_Box* mBoxes; + ASAP_EndPoint* mEndPoints[3]; + udword mFirstFree; + + void ResizeBoxArray(); + // For batch creation + Container mCreated; + void BatchCreate(); + void InsertEndPoints(udword axis, const ASAP_EndPoint* end_points, udword nb_endpoints); + bool CompleteBoxPruning2(udword nb, const IAABB* array, const Axes& axes, const CreateData* batched); + bool BipartiteBoxPruning2(udword nb0, const IAABB* array0, udword nb1, const IAABB* array1, const Axes& axes, const CreateData* batched, const udword* box_indices); + // For batch removal + Container mRemoved; + void BatchRemove(); + }; + +#endif // OPC_ARRAYSAP_H diff --git a/Extras/CDTestFramework/Opcode/OPC_BaseModel.cpp b/Extras/CDTestFramework/Opcode/OPC_BaseModel.cpp new file mode 100644 index 0000000..bdb2ae8 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_BaseModel.cpp @@ -0,0 +1,147 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base model interface. + * \file OPC_BaseModel.cpp + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * The base class for collision models. + * + * \class BaseModel + * \author Pierre Terdiman + * \version 1.3 + * \date May, 18, 2003 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +OPCODECREATE::OPCODECREATE() +{ + mIMesh = null; + mSettings.mRules = SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER; + mSettings.mLimit = 1; // Mandatory for complete trees + mNoLeaf = true; + mQuantized = true; +#ifdef __MESHMERIZER_H__ + mCollisionHull = false; +#endif // __MESHMERIZER_H__ + mKeepOriginal = false; + mCanRemap = false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BaseModel::BaseModel() : mIMesh(null), mModelCode(0), mSource(null), mTree(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BaseModel::~BaseModel() +{ + ReleaseBase(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases everything. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void BaseModel::ReleaseBase() +{ + DELETESINGLE(mSource); + DELETESINGLE(mTree); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Creates an optimized tree according to user-settings, and setups mModelCode. + * \param no_leaf [in] true for "no leaf" tree + * \param quantized [in] true for quantized tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BaseModel::CreateTree(bool no_leaf, bool quantized) +{ + DELETESINGLE(mTree); + + // Setup model code + if(no_leaf) mModelCode |= OPC_NO_LEAF; + else mModelCode &= ~OPC_NO_LEAF; + + if(quantized) mModelCode |= OPC_QUANTIZED; + else mModelCode &= ~OPC_QUANTIZED; + + // Create the correct class + if(mModelCode & OPC_NO_LEAF) + { + if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedNoLeafTree; + else mTree = new AABBNoLeafTree; + } + else + { + if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedTree; + else mTree = new AABBCollisionTree; + } + CHECKALLOC(mTree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BaseModel::Refit() +{ + // Refit the optimized tree + return mTree->Refit(mIMesh); + +// Old code kept for reference : refit the source tree then rebuild ! +// if(!mSource) return false; +// // Ouch... +// mSource->Refit(&mTB); +// // Ouch... +// return mTree->Build(mSource); +} diff --git a/Extras/CDTestFramework/Opcode/OPC_BaseModel.h b/Extras/CDTestFramework/Opcode/OPC_BaseModel.h new file mode 100644 index 0000000..905fc92 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_BaseModel.h @@ -0,0 +1,184 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base model interface. + * \file OPC_BaseModel.h + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_BASEMODEL_H__ +#define __OPC_BASEMODEL_H__ + + //! Model creation structure + struct OPCODE_API OPCODECREATE + { + //! Constructor + OPCODECREATE(); + + MeshInterface* mIMesh; //!< Mesh interface (access to triangles & vertices) (*) + BuildSettings mSettings; //!< Builder's settings + bool mNoLeaf; //!< true => discard leaf nodes (else use a normal tree) + bool mQuantized; //!< true => quantize the tree (else use a normal tree) +#ifdef __MESHMERIZER_H__ + bool mCollisionHull; //!< true => use convex hull + GJK +#endif // __MESHMERIZER_H__ + bool mKeepOriginal; //!< true => keep a copy of the original tree (debug purpose) + bool mCanRemap; //!< true => allows OPCODE to reorganize client arrays + + // (*) This pointer is saved internally and used by OPCODE until collision structures are released, + // so beware of the object's lifetime. + }; + + enum ModelFlag + { + OPC_QUANTIZED = (1<<0), //!< Compressed/uncompressed tree + OPC_NO_LEAF = (1<<1), //!< Leaf/NoLeaf tree + OPC_SINGLE_NODE = (1<<2) //!< Special case for 1-node models + }; + + class OPCODE_API BaseModel + { + public: + // Constructor/Destructor + BaseModel(); + virtual ~BaseModel(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Build(const OPCODECREATE& create) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual udword GetUsedBytes() const = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Refit(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the source tree. + * \return generic tree + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const AABBTree* GetSourceTree() const { return mSource; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the tree. + * \return the collision tree + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const AABBOptimizedTree* GetTree() const { return mTree; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the tree. + * \return the collision tree + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ AABBOptimizedTree* GetTree() { return mTree; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of nodes in the tree. + * Should be 2*N-1 for normal trees and N-1 for optimized ones. + * \return number of nodes + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbNodes() const { return mTree->GetNbNodes(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks whether the tree has leaf nodes or not. + * \return true if the tree has leaf nodes (normal tree), else false (optimized tree) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL HasLeafNodes() const { return !(mModelCode & OPC_NO_LEAF); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks whether the tree is quantized or not. + * \return true if the tree is quantized + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsQuantized() const { return mModelCode & OPC_QUANTIZED; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks whether the model has a single node or not. This special case must be handled separately. + * \return true if the model has only 1 node + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL HasSingleNode() const { return mModelCode & OPC_SINGLE_NODE; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the model's code. + * \return model's code + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetModelCode() const { return mModelCode; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the mesh interface. + * \return mesh interface + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const MeshInterface* GetMeshInterface() const { return mIMesh; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Sets the mesh interface. + * \param imesh [in] mesh interface + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetMeshInterface(const MeshInterface* imesh) { mIMesh = imesh; } + + protected: + const MeshInterface* mIMesh; //!< User-defined mesh interface + udword mModelCode; //!< Model code = combination of ModelFlag(s) + AABBTree* mSource; //!< Original source tree + AABBOptimizedTree* mTree; //!< Optimized tree owned by the model + // Internal methods + void ReleaseBase(); + bool CreateTree(bool no_leaf, bool quantized); + }; + +#endif //__OPC_BASEMODEL_H__ \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/OPC_BoxBoxOverlap.h b/Extras/CDTestFramework/Opcode/OPC_BoxBoxOverlap.h new file mode 100644 index 0000000..63aa87e --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_BoxBoxOverlap.h @@ -0,0 +1,139 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * OBB-OBB overlap test using the separating axis theorem. + * - original code by Gomez / Gamasutra (similar to Gottschalk's one in RAPID) + * - optimized for AABB trees by computing the rotation matrix once (SOLID-fashion) + * - the fabs matrix is precomputed as well and epsilon-tweaked (RAPID-style, we found this almost mandatory) + * - Class III axes can be disabled... (SOLID & Intel fashion) + * - ...or enabled to perform some profiling + * - CPU comparisons used when appropriate + * - lazy evaluation sometimes saves some work in case of early exits (unlike SOLID) + * + * \param ea [in] extents from box A + * \param ca [in] center from box A + * \param eb [in] extents from box B + * \param cb [in] center from box B + * \return true if boxes overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb) +{ + // Stats + mNbBVBVTests++; + + float t,t2; + + // Class I : A's basis vectors + float Tx = (mR1to0.m[0][0]*cb.x + mR1to0.m[1][0]*cb.y + mR1to0.m[2][0]*cb.z) + mT1to0.x - ca.x; + t = ea.x + eb.x*mAR.m[0][0] + eb.y*mAR.m[1][0] + eb.z*mAR.m[2][0]; + if(GREATER(Tx, t)) return FALSE; + + float Ty = (mR1to0.m[0][1]*cb.x + mR1to0.m[1][1]*cb.y + mR1to0.m[2][1]*cb.z) + mT1to0.y - ca.y; + t = ea.y + eb.x*mAR.m[0][1] + eb.y*mAR.m[1][1] + eb.z*mAR.m[2][1]; + if(GREATER(Ty, t)) return FALSE; + + float Tz = (mR1to0.m[0][2]*cb.x + mR1to0.m[1][2]*cb.y + mR1to0.m[2][2]*cb.z) + mT1to0.z - ca.z; + t = ea.z + eb.x*mAR.m[0][2] + eb.y*mAR.m[1][2] + eb.z*mAR.m[2][2]; + if(GREATER(Tz, t)) return FALSE; + + // Class II : B's basis vectors + t = Tx*mR1to0.m[0][0] + Ty*mR1to0.m[0][1] + Tz*mR1to0.m[0][2]; t2 = ea.x*mAR.m[0][0] + ea.y*mAR.m[0][1] + ea.z*mAR.m[0][2] + eb.x; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mR1to0.m[1][0] + Ty*mR1to0.m[1][1] + Tz*mR1to0.m[1][2]; t2 = ea.x*mAR.m[1][0] + ea.y*mAR.m[1][1] + ea.z*mAR.m[1][2] + eb.y; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mR1to0.m[2][0] + Ty*mR1to0.m[2][1] + Tz*mR1to0.m[2][2]; t2 = ea.x*mAR.m[2][0] + ea.y*mAR.m[2][1] + ea.z*mAR.m[2][2] + eb.z; + if(GREATER(t, t2)) return FALSE; + + // Class III : 9 cross products + // Cool trick: always perform the full test for first level, regardless of settings. + // That way pathological cases (such as the pencils scene) are quickly rejected anyway ! + if(mFullBoxBoxTest || mNbBVBVTests==1) + { + t = Tz*mR1to0.m[0][1] - Ty*mR1to0.m[0][2]; t2 = ea.y*mAR.m[0][2] + ea.z*mAR.m[0][1] + eb.y*mAR.m[2][0] + eb.z*mAR.m[1][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B0 + t = Tz*mR1to0.m[1][1] - Ty*mR1to0.m[1][2]; t2 = ea.y*mAR.m[1][2] + ea.z*mAR.m[1][1] + eb.x*mAR.m[2][0] + eb.z*mAR.m[0][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B1 + t = Tz*mR1to0.m[2][1] - Ty*mR1to0.m[2][2]; t2 = ea.y*mAR.m[2][2] + ea.z*mAR.m[2][1] + eb.x*mAR.m[1][0] + eb.y*mAR.m[0][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B2 + t = Tx*mR1to0.m[0][2] - Tz*mR1to0.m[0][0]; t2 = ea.x*mAR.m[0][2] + ea.z*mAR.m[0][0] + eb.y*mAR.m[2][1] + eb.z*mAR.m[1][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B0 + t = Tx*mR1to0.m[1][2] - Tz*mR1to0.m[1][0]; t2 = ea.x*mAR.m[1][2] + ea.z*mAR.m[1][0] + eb.x*mAR.m[2][1] + eb.z*mAR.m[0][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B1 + t = Tx*mR1to0.m[2][2] - Tz*mR1to0.m[2][0]; t2 = ea.x*mAR.m[2][2] + ea.z*mAR.m[2][0] + eb.x*mAR.m[1][1] + eb.y*mAR.m[0][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B2 + t = Ty*mR1to0.m[0][0] - Tx*mR1to0.m[0][1]; t2 = ea.x*mAR.m[0][1] + ea.y*mAR.m[0][0] + eb.y*mAR.m[2][2] + eb.z*mAR.m[1][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B0 + t = Ty*mR1to0.m[1][0] - Tx*mR1to0.m[1][1]; t2 = ea.x*mAR.m[1][1] + ea.y*mAR.m[1][0] + eb.x*mAR.m[2][2] + eb.z*mAR.m[0][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B1 + t = Ty*mR1to0.m[2][0] - Tx*mR1to0.m[2][1]; t2 = ea.x*mAR.m[2][1] + ea.y*mAR.m[2][0] + eb.x*mAR.m[1][2] + eb.y*mAR.m[0][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B2 + } + return TRUE; +} + +//! A dedicated version when one box is constant +inline_ BOOL OBBCollider::BoxBoxOverlap(const Point& extents, const Point& center) +{ + // Stats + mNbVolumeBVTests++; + + float t,t2; + + // Class I : A's basis vectors + float Tx = mTBoxToModel.x - center.x; t = extents.x + mBBx1; if(GREATER(Tx, t)) return FALSE; + float Ty = mTBoxToModel.y - center.y; t = extents.y + mBBy1; if(GREATER(Ty, t)) return FALSE; + float Tz = mTBoxToModel.z - center.z; t = extents.z + mBBz1; if(GREATER(Tz, t)) return FALSE; + + // Class II : B's basis vectors + t = Tx*mRBoxToModel.m[0][0] + Ty*mRBoxToModel.m[0][1] + Tz*mRBoxToModel.m[0][2]; + t2 = extents.x*mAR.m[0][0] + extents.y*mAR.m[0][1] + extents.z*mAR.m[0][2] + mBoxExtents.x; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mRBoxToModel.m[1][0] + Ty*mRBoxToModel.m[1][1] + Tz*mRBoxToModel.m[1][2]; + t2 = extents.x*mAR.m[1][0] + extents.y*mAR.m[1][1] + extents.z*mAR.m[1][2] + mBoxExtents.y; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mRBoxToModel.m[2][0] + Ty*mRBoxToModel.m[2][1] + Tz*mRBoxToModel.m[2][2]; + t2 = extents.x*mAR.m[2][0] + extents.y*mAR.m[2][1] + extents.z*mAR.m[2][2] + mBoxExtents.z; + if(GREATER(t, t2)) return FALSE; + + // Class III : 9 cross products + // Cool trick: always perform the full test for first level, regardless of settings. + // That way pathological cases (such as the pencils scene) are quickly rejected anyway ! + if(mFullBoxBoxTest || mNbVolumeBVTests==1) + { + t = Tz*mRBoxToModel.m[0][1] - Ty*mRBoxToModel.m[0][2]; t2 = extents.y*mAR.m[0][2] + extents.z*mAR.m[0][1] + mBB_1; if(GREATER(t, t2)) return FALSE; // L = A0 x B0 + t = Tz*mRBoxToModel.m[1][1] - Ty*mRBoxToModel.m[1][2]; t2 = extents.y*mAR.m[1][2] + extents.z*mAR.m[1][1] + mBB_2; if(GREATER(t, t2)) return FALSE; // L = A0 x B1 + t = Tz*mRBoxToModel.m[2][1] - Ty*mRBoxToModel.m[2][2]; t2 = extents.y*mAR.m[2][2] + extents.z*mAR.m[2][1] + mBB_3; if(GREATER(t, t2)) return FALSE; // L = A0 x B2 + t = Tx*mRBoxToModel.m[0][2] - Tz*mRBoxToModel.m[0][0]; t2 = extents.x*mAR.m[0][2] + extents.z*mAR.m[0][0] + mBB_4; if(GREATER(t, t2)) return FALSE; // L = A1 x B0 + t = Tx*mRBoxToModel.m[1][2] - Tz*mRBoxToModel.m[1][0]; t2 = extents.x*mAR.m[1][2] + extents.z*mAR.m[1][0] + mBB_5; if(GREATER(t, t2)) return FALSE; // L = A1 x B1 + t = Tx*mRBoxToModel.m[2][2] - Tz*mRBoxToModel.m[2][0]; t2 = extents.x*mAR.m[2][2] + extents.z*mAR.m[2][0] + mBB_6; if(GREATER(t, t2)) return FALSE; // L = A1 x B2 + t = Ty*mRBoxToModel.m[0][0] - Tx*mRBoxToModel.m[0][1]; t2 = extents.x*mAR.m[0][1] + extents.y*mAR.m[0][0] + mBB_7; if(GREATER(t, t2)) return FALSE; // L = A2 x B0 + t = Ty*mRBoxToModel.m[1][0] - Tx*mRBoxToModel.m[1][1]; t2 = extents.x*mAR.m[1][1] + extents.y*mAR.m[1][0] + mBB_8; if(GREATER(t, t2)) return FALSE; // L = A2 x B1 + t = Ty*mRBoxToModel.m[2][0] - Tx*mRBoxToModel.m[2][1]; t2 = extents.x*mAR.m[2][1] + extents.y*mAR.m[2][0] + mBB_9; if(GREATER(t, t2)) return FALSE; // L = A2 x B2 + } + return TRUE; +} + +//! A special version for 2 axis-aligned boxes +inline_ BOOL AABBCollider::AABBAABBOverlap(const Point& extents, const Point& center) +{ + // Stats + mNbVolumeBVTests++; + + float tx = mBox.mCenter.x - center.x; float ex = extents.x + mBox.mExtents.x; if(GREATER(tx, ex)) return FALSE; + float ty = mBox.mCenter.y - center.y; float ey = extents.y + mBox.mExtents.y; if(GREATER(ty, ey)) return FALSE; + float tz = mBox.mCenter.z - center.z; float ez = extents.z + mBox.mExtents.z; if(GREATER(tz, ez)) return FALSE; + + return TRUE; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_BoxPruning.cpp b/Extras/CDTestFramework/Opcode/OPC_BoxPruning.cpp new file mode 100644 index 0000000..7d4f50d --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_BoxPruning.cpp @@ -0,0 +1,376 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for box pruning. + * \file IceBoxPruning.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + You could use a complex sweep-and-prune as implemented in I-Collide. + You could use a complex hashing scheme as implemented in V-Clip or recently in ODE it seems. + You could use a "Recursive Dimensional Clustering" algorithm as implemented in GPG2. + + Or you could use this. + Faster ? I don't know. Probably not. It would be a shame. But who knows ? + Easier ? Definitely. Enjoy the sheer simplicity. +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +*/ + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + + inline_ void FindRunningIndex(udword& index, float* array, udword* sorted, int last, float max) + { + int First=index; + while(First<=last) + { + index = (First+last)>>1; + + if(max>array[sorted[index]]) First = index+1; + else last = index-1; + } + } +// ### could be log(n) ! +// and maybe use cmp integers + +// InsertionSort has better coherence, RadixSort is better for one-shot queries. +#define PRUNING_SORTER RadixSort +//#define PRUNING_SORTER InsertionSort + +// Static for coherence +static PRUNING_SORTER* gCompletePruningSorter = null; +static PRUNING_SORTER* gBipartitePruningSorter0 = null; +static PRUNING_SORTER* gBipartitePruningSorter1 = null; +inline_ PRUNING_SORTER* GetCompletePruningSorter() +{ + if(!gCompletePruningSorter) gCompletePruningSorter = ICE_NEW(PRUNING_SORTER); + return gCompletePruningSorter; +} +inline_ PRUNING_SORTER* GetBipartitePruningSorter0() +{ + if(!gBipartitePruningSorter0) gBipartitePruningSorter0 = ICE_NEW(PRUNING_SORTER); + return gBipartitePruningSorter0; +} +inline_ PRUNING_SORTER* GetBipartitePruningSorter1() +{ + if(!gBipartitePruningSorter1) gBipartitePruningSorter1 = ICE_NEW(PRUNING_SORTER); + return gBipartitePruningSorter1; +} +void ReleasePruningSorters() +{ + DELETESINGLE(gBipartitePruningSorter1); + DELETESINGLE(gBipartitePruningSorter0); + DELETESINGLE(gCompletePruningSorter); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set. + * \param nb0 [in] number of boxes in the first set + * \param array0 [in] array of boxes for the first set + * \param nb1 [in] number of boxes in the second set + * \param array1 [in] array of boxes for the second set + * \param pairs [out] array of overlapping pairs + * \param axes [in] projection order (0,2,1 is often best) + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::BipartiteBoxPruning(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs, const Axes& axes) +{ + // Checkings + if(!nb0 || !array0 || !nb1 || !array1) return false; + + // Catch axes + udword Axis0 = axes.mAxis0; + udword Axis1 = axes.mAxis1; + udword Axis2 = axes.mAxis2; + + // Allocate some temporary data + float* MinPosList0 = new float[nb0]; + float* MinPosList1 = new float[nb1]; + + // 1) Build main lists using the primary axis + for(udword i=0;iGetMin(Axis0); + for(udword i=0;iGetMin(Axis0); + + // 2) Sort the lists + PRUNING_SORTER* RS0 = GetBipartitePruningSorter0(); + PRUNING_SORTER* RS1 = GetBipartitePruningSorter1(); + const udword* Sorted0 = RS0->Sort(MinPosList0, nb0).GetRanks(); + const udword* Sorted1 = RS1->Sort(MinPosList1, nb1).GetRanks(); + + // 3) Prune the lists + udword Index0, Index1; + + const udword* const LastSorted0 = &Sorted0[nb0]; + const udword* const LastSorted1 = &Sorted1[nb1]; + const udword* RunningAddress0 = Sorted0; + const udword* RunningAddress1 = Sorted1; + + while(RunningAddress1GetMax(Axis0)) + { + if(array0[Index0]->Intersect(*array1[Index1], Axis1)) + { + if(array0[Index0]->Intersect(*array1[Index1], Axis2)) + { + pairs.AddPair(Index0, Index1); + } + } + } + } + + //// + + while(RunningAddress0GetMax(Axis0)) + { + if(array0[Index1]->Intersect(*array1[Index0], Axis1)) + { + if(array0[Index1]->Intersect(*array1[Index0], Axis2)) + { + pairs.AddPair(Index1, Index0); + } + } + + } + } + + DELETEARRAY(MinPosList1); + DELETEARRAY(MinPosList0); + + return true; +} + +#define ORIGINAL_VERSION +//#define JOAKIM + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set. + * \param nb [in] number of boxes + * \param array [in] array of boxes + * \param pairs [out] array of overlapping pairs + * \param axes [in] projection order (0,2,1 is often best) + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::CompleteBoxPruning(udword nb, const AABB** array, Pairs& pairs, const Axes& axes) +{ + // Checkings + if(!nb || !array) return false; + + // Catch axes + udword Axis0 = axes.mAxis0; + udword Axis1 = axes.mAxis1; + udword Axis2 = axes.mAxis2; + +#ifdef ORIGINAL_VERSION + // Allocate some temporary data +// float* PosList = new float[nb]; + float* PosList = new float[nb+1]; + + // 1) Build main list using the primary axis + for(udword i=0;iGetMin(Axis0); +PosList[nb++] = MAX_FLOAT; + + // 2) Sort the list + PRUNING_SORTER* RS = GetCompletePruningSorter(); + const udword* Sorted = RS->Sort(PosList, nb).GetRanks(); + + // 3) Prune the list + const udword* const LastSorted = &Sorted[nb]; + const udword* RunningAddress = Sorted; + udword Index0, Index1; + while(RunningAddressGetMax(Axis0)) + while(PosList[Index1 = *RunningAddress2++]<=array[Index0]->GetMax(Axis0)) + { +// if(Index0!=Index1) +// { + if(array[Index0]->Intersect(*array[Index1], Axis1)) + { + if(array[Index0]->Intersect(*array[Index1], Axis2)) + { + pairs.AddPair(Index0, Index1); + } + } +// } + } + } + } + + DELETEARRAY(PosList); +#endif + +#ifdef JOAKIM + // Allocate some temporary data +// float* PosList = new float[nb]; + float* MinList = new float[nb+1]; + + // 1) Build main list using the primary axis + for(udword i=0;iGetMin(Axis0); + MinList[nb] = MAX_FLOAT; + + // 2) Sort the list + PRUNING_SORTER* RS = GetCompletePruningSorter(); + udword* Sorted = RS->Sort(MinList, nb+1).GetRanks(); + + // 3) Prune the list +// const udword* const LastSorted = &Sorted[nb]; +// const udword* const LastSorted = &Sorted[nb-1]; + const udword* RunningAddress = Sorted; + udword Index0, Index1; + +// while(RunningAddressGetMax(Axis0)) + +// float CurrentMin = array[Index0]->GetMin(Axis0); + float CurrentMax = array[Index0]->GetMax(Axis0); + + while(MinList[Index1 = *RunningAddress2] <= CurrentMax) +// while(PosList[Index1 = *RunningAddress] <= CurrentMax) + { +// if(Index0!=Index1) +// { + if(array[Index0]->Intersect(*array[Index1], Axis1)) + { + if(array[Index0]->Intersect(*array[Index1], Axis2)) + { + pairs.AddPair(Index0, Index1); + } + } +// } + + RunningAddress2++; +// RunningAddress++; + } + } + } + + DELETEARRAY(MinList); +#endif + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Brute-force versions are kept: +// - to check the optimized versions return the correct list of intersections +// - to check the speed of the optimized code against the brute-force one +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Brute-force bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set. + * \param nb0 [in] number of boxes in the first set + * \param array0 [in] array of boxes for the first set + * \param nb1 [in] number of boxes in the second set + * \param array1 [in] array of boxes for the second set + * \param pairs [out] array of overlapping pairs + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::BruteForceBipartiteBoxTest(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs) +{ + // Checkings + if(!nb0 || !array0 || !nb1 || !array1) return false; + + // Brute-force nb0*nb1 overlap tests + for(udword i=0;iIntersect(*array1[j])) pairs.AddPair(i, j); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set. + * \param nb [in] number of boxes + * \param array [in] array of boxes + * \param pairs [out] array of overlapping pairs + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::BruteForceCompleteBoxTest(udword nb, const AABB** array, Pairs& pairs) +{ + // Checkings + if(!nb || !array) return false; + + // Brute-force n(n-1)/2 overlap tests + for(udword i=0;iIntersect(*array[j])) pairs.AddPair(i, j); + } + } + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_BoxPruning.h b/Extras/CDTestFramework/Opcode/OPC_BoxPruning.h new file mode 100644 index 0000000..163fe4e --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_BoxPruning.h @@ -0,0 +1,40 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for box pruning. + * \file IceBoxPruning.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_BOXPRUNING_H__ +#define __OPC_BOXPRUNING_H__ + + // Optimized versions + FUNCTION OPCODE_API bool CompleteBoxPruning(udword nb, const AABB** array, Pairs& pairs, const Axes& axes); + FUNCTION OPCODE_API bool BipartiteBoxPruning(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs, const Axes& axes); + + // Brute-force versions + FUNCTION OPCODE_API bool BruteForceCompleteBoxTest(udword nb, const AABB** array, Pairs& pairs); + FUNCTION OPCODE_API bool BruteForceBipartiteBoxTest(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs); + +#endif //__OPC_BOXPRUNING_H__ \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/OPC_Collider.cpp b/Extras/CDTestFramework/Opcode/OPC_Collider.cpp new file mode 100644 index 0000000..bd62aec --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Collider.cpp @@ -0,0 +1,63 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base collider class. + * \file OPC_Collider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains the abstract class for colliders. + * + * \class Collider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Collider::Collider() : + mFlags (0), + mCurrentModel (null), + mIMesh (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Collider::~Collider() +{ +} diff --git a/Extras/CDTestFramework/Opcode/OPC_Collider.h b/Extras/CDTestFramework/Opcode/OPC_Collider.h new file mode 100644 index 0000000..594109b --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Collider.h @@ -0,0 +1,185 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base collider class. + * \file OPC_Collider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_COLLIDER_H__ +#define __OPC_COLLIDER_H__ + + enum CollisionFlag + { + OPC_FIRST_CONTACT = (1<<0), //!< Report all contacts (false) or only first one (true) + OPC_TEMPORAL_COHERENCE = (1<<1), //!< Use temporal coherence or not + OPC_CONTACT = (1<<2), //!< Final contact status after a collision query + OPC_TEMPORAL_HIT = (1<<3), //!< There has been an early exit due to temporal coherence + OPC_NO_PRIMITIVE_TESTS = (1<<4), //!< Keep or discard primitive-bv tests in leaf nodes (volume-mesh queries) + + OPC_CONTACT_FOUND = OPC_FIRST_CONTACT | OPC_CONTACT, + OPC_TEMPORAL_CONTACT = OPC_TEMPORAL_HIT | OPC_CONTACT, + + OPC_FORCE_DWORD = 0x7fffffff + }; + + class OPCODE_API Collider + { + public: + // Constructor / Destructor + Collider(); + virtual ~Collider(); + + // Collision report + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the last collision status after a collision query. + * \return true if a collision occured + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL GetContactStatus() const { return mFlags & OPC_CONTACT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the "first contact" mode. + * \return true if "first contact" mode is on + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL FirstContactEnabled() const { return mFlags & OPC_FIRST_CONTACT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the temporal coherence mode. + * \return true if temporal coherence is on + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL TemporalCoherenceEnabled() const { return mFlags & OPC_TEMPORAL_COHERENCE; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks a first contact has already been found. + * \return true if a first contact has been found and we can stop a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL ContactFound() const { return (mFlags&OPC_CONTACT_FOUND)==OPC_CONTACT_FOUND; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks there's been an early exit due to temporal coherence; + * \return true if a temporal hit has occured + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL TemporalHit() const { return mFlags & OPC_TEMPORAL_HIT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks primitive tests are enabled; + * \return true if primitive tests must be skipped + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL SkipPrimitiveTests() const { return mFlags & OPC_NO_PRIMITIVE_TESTS; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Reports all contacts (false) or first contact only (true) + * \param flag [in] true for first contact, false for all contacts + * \see SetTemporalCoherence(bool flag) + * \see ValidateSettings() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFirstContact(bool flag) + { + if(flag) mFlags |= OPC_FIRST_CONTACT; + else mFlags &= ~OPC_FIRST_CONTACT; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Enable/disable temporal coherence. + * \param flag [in] true to enable temporal coherence, false to discard it + * \see SetFirstContact(bool flag) + * \see ValidateSettings() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetTemporalCoherence(bool flag) + { + if(flag) mFlags |= OPC_TEMPORAL_COHERENCE; + else mFlags &= ~OPC_TEMPORAL_COHERENCE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Enable/disable primitive tests. + * \param flag [in] true to enable primitive tests, false to discard them + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetPrimitiveTests(bool flag) + { + if(!flag) mFlags |= OPC_NO_PRIMITIVE_TESTS; + else mFlags &= ~OPC_NO_PRIMITIVE_TESTS; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual const char* ValidateSettings() = 0; + + protected: + udword mFlags; //!< Bit flags + const BaseModel* mCurrentModel; //!< Current model for collision query (owner of touched faces) + // User mesh interface + const MeshInterface* mIMesh; //!< User-defined mesh interface + + // Internal methods + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups current collision model + * \param model [in] current collision model + * \return TRUE if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Setup(const BaseModel* model) + { + // Keep track of current model + mCurrentModel = model; + if(!mCurrentModel) return FALSE; + + mIMesh = model->GetMeshInterface(); + return mIMesh!=null; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Initializes a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual inline_ void InitQuery() { mFlags &= ~OPC_TEMPORAL_CONTACT; } + }; + +#endif // __OPC_COLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_Common.cpp b/Extras/CDTestFramework/Opcode/OPC_Common.cpp new file mode 100644 index 0000000..4f1a250 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Common.cpp @@ -0,0 +1,57 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains common classes & defs used in OPCODE. + * \file OPC_Common.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * An AABB dedicated to collision detection. + * We don't use the generic AABB class included in ICE, since it can be a Min/Max or a Center/Extents one (depends + * on compilation flags). Since the Center/Extents model is more efficient in collision detection, it was worth + * using an extra special class. + * + * \class CollisionAABB + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A quantized AABB. + * Center/Extent model, using 16-bits integers. + * + * \class QuantizedAABB + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; diff --git a/Extras/CDTestFramework/Opcode/OPC_Common.h b/Extras/CDTestFramework/Opcode/OPC_Common.h new file mode 100644 index 0000000..9510668 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Common.h @@ -0,0 +1,110 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains common classes & defs used in OPCODE. + * \file OPC_Common.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_COMMON_H__ +#define __OPC_COMMON_H__ + +// [GOTTFRIED]: Just a small change for readability. +#ifdef OPC_CPU_COMPARE + #define GREATER(x, y) AIR(x) > IR(y) +#else + #define GREATER(x, y) fabsf(x) > (y) +#endif + + class OPCODE_API CollisionAABB + { + public: + //! Constructor + inline_ CollisionAABB() {} + //! Constructor + inline_ CollisionAABB(const AABB& b) { b.GetCenter(mCenter); b.GetExtents(mExtents); } + //! Destructor + inline_ ~CollisionAABB() {} + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks a box is inside another box. + * \param box [in] the other box + * \return true if current box is inside input box + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsInside(const CollisionAABB& box) const + { + if(box.GetMin(0)>GetMin(0)) return FALSE; + if(box.GetMin(1)>GetMin(1)) return FALSE; + if(box.GetMin(2)>GetMin(2)) return FALSE; + if(box.GetMax(0)IsValid()) return false; + + // Look for degenerate faces. + udword NbDegenerate = create.mIMesh->CheckTopology(); + if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate); + // We continue nonetheless.... + + Release(); // Make sure previous tree has been discarded + + // 1-1) Setup mesh interface automatically + SetMeshInterface(create.mIMesh); + + bool Status = false; + AABBTree* LeafTree = null; + Internal Data; + + // 2) Build a generic AABB Tree. + mSource = new AABBTree; + CHECKALLOC(mSource); + + // 2-1) Setup a builder. Our primitives here are triangles from input mesh, + // so we use an AABBTreeOfTrianglesBuilder..... + { + AABBTreeOfTrianglesBuilder TB; + TB.mIMesh = create.mIMesh; + TB.mNbPrimitives = create.mIMesh->GetNbTriangles(); + TB.mSettings = create.mSettings; + TB.mSettings.mLimit = 16; // ### Hardcoded, but maybe we could let the user choose 8 / 16 / 32 ... + if(!mSource->Build(&TB)) goto FreeAndExit; + } + + // 2-2) Here's the trick : create *another* AABB tree using the leaves of the first one (which are boxes, this time) + struct Local + { + // A callback to count leaf nodes + static bool CountLeaves(const AABBTreeNode* current, udword depth, void* user_data) + { + if(current->IsLeaf()) + { + Internal* Data = (Internal*)user_data; + Data->mNbLeaves++; + } + return true; + } + + // A callback to setup leaf nodes in our internal structures + static bool SetupLeafData(const AABBTreeNode* current, udword depth, void* user_data) + { + if(current->IsLeaf()) + { + Internal* Data = (Internal*)user_data; + + // Get current leaf's box + Data->mLeaves[Data->mNbLeaves] = *current->GetAABB(); + + // Setup leaf data + udword Index = (udword(current->GetPrimitives()) - udword(Data->mBase))/sizeof(udword); + Data->mTriangles[Data->mNbLeaves].SetData(current->GetNbPrimitives(), Index); + + Data->mNbLeaves++; + } + return true; + } + }; + + // Walk the tree & count number of leaves + Data.mNbLeaves = 0; + mSource->Walk(Local::CountLeaves, &Data); + mNbLeaves = Data.mNbLeaves; // Keep track of it + + // Special case for 1-leaf meshes + if(mNbLeaves==1) + { + mModelCode |= OPC_SINGLE_NODE; + Status = true; + goto FreeAndExit; + } + + // Allocate our structures + Data.mLeaves = new AABB[Data.mNbLeaves]; CHECKALLOC(Data.mLeaves); + mTriangles = new LeafTriangles[Data.mNbLeaves]; CHECKALLOC(mTriangles); + + // Walk the tree again & setup leaf data + Data.mTriangles = mTriangles; + Data.mBase = mSource->GetIndices(); + Data.mNbLeaves = 0; // Reset for incoming walk + mSource->Walk(Local::SetupLeafData, &Data); + + // Handle source indices + { + bool MustKeepIndices = true; + if(create.mCanRemap) + { + // We try to get rid of source indices (saving more ram!) by reorganizing triangle arrays... + // Remap can fail when we use callbacks => keep track of indices in that case (it still + // works, only using more memory) + if(create.mIMesh->RemapClient(mSource->GetNbPrimitives(), mSource->GetIndices())) + { + MustKeepIndices = false; + } + } + + if(MustKeepIndices) + { + // Keep track of source indices (from vanilla tree) + mNbPrimitives = mSource->GetNbPrimitives(); + mIndices = new udword[mNbPrimitives]; + CopyMemory(mIndices, mSource->GetIndices(), mNbPrimitives*sizeof(udword)); + } + } + + // Now, create our optimized tree using previous leaf nodes + LeafTree = new AABBTree; + CHECKALLOC(LeafTree); + { + AABBTreeOfAABBsBuilder TB; // Now using boxes ! + TB.mSettings = create.mSettings; + TB.mSettings.mLimit = 1; // We now want a complete tree so that we can "optimize" it + TB.mNbPrimitives = Data.mNbLeaves; + TB.mAABBArray = Data.mLeaves; + if(!LeafTree->Build(&TB)) goto FreeAndExit; + } + + // 3) Create an optimized tree according to user-settings + if(!CreateTree(create.mNoLeaf, create.mQuantized)) goto FreeAndExit; + + // 3-2) Create optimized tree + if(!mTree->Build(LeafTree)) goto FreeAndExit; + + // Finally ok... + Status = true; + +FreeAndExit: // Allow me this one... + DELETESINGLE(LeafTree); + + // 3-3) Delete generic tree if needed + if(!create.mKeepOriginal) DELETESINGLE(mSource); + + return Status; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword HybridModel::GetUsedBytes() const +{ + udword UsedBytes = 0; + if(mTree) UsedBytes += mTree->GetUsedBytes(); + if(mIndices) UsedBytes += mNbPrimitives * sizeof(udword); // mIndices + if(mTriangles) UsedBytes += mNbLeaves * sizeof(LeafTriangles); // mTriangles + return UsedBytes; +} + +inline_ void ComputeMinMax_HM(Point& min, Point& max, const VertexPointers& vp) +{ + // Compute triangle's AABB = a leaf box +#ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much + min.x = FCMin3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + max.x = FCMax3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + + min.y = FCMin3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + max.y = FCMax3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + + min.z = FCMin3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); + max.z = FCMax3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); +#else + min = *vp.Vertex[0]; + max = *vp.Vertex[0]; + min.Min(*vp.Vertex[1]); + max.Max(*vp.Vertex[1]); + min.Min(*vp.Vertex[2]); + max.Max(*vp.Vertex[2]); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool HybridModel::Refit() +{ + if(!mIMesh) return false; + if(!mTree) return false; + + if(IsQuantized()) return false; + if(HasLeafNodes()) return false; + + const LeafTriangles* LT = GetLeafTriangles(); + const udword* Indices = GetIndices(); + + // Bottom-up update + VertexPointers VP; + Point Min,Max; + Point Min_,Max_; + udword Index = mTree->GetNbNodes(); + AABBNoLeafNode* Nodes = (AABBNoLeafNode*)((AABBNoLeafTree*)mTree)->GetNodes(); + while(Index--) + { + AABBNoLeafNode& Current = Nodes[Index]; + + if(Current.HasPosLeaf()) + { + const LeafTriangles& CurrentLeaf = LT[Current.GetPosPrimitive()]; + + Min.SetPlusInfinity(); + Max.SetMinusInfinity(); + + Point TmpMin, TmpMax; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, *T++); + ComputeMinMax_HM(TmpMin, TmpMax, VP); + Min.Min(TmpMin); + Max.Max(TmpMax); + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, BaseIndex++); + ComputeMinMax_HM(TmpMin, TmpMax, VP); + Min.Min(TmpMin); + Max.Max(TmpMax); + } + } + } + else + { + const CollisionAABB& CurrentBox = Current.GetPos()->mAABB; + CurrentBox.GetMin(Min); + CurrentBox.GetMax(Max); + } + + if(Current.HasNegLeaf()) + { + const LeafTriangles& CurrentLeaf = LT[Current.GetNegPrimitive()]; + + Min_.SetPlusInfinity(); + Max_.SetMinusInfinity(); + + Point TmpMin, TmpMax; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, *T++); + ComputeMinMax_HM(TmpMin, TmpMax, VP); + Min_.Min(TmpMin); + Max_.Max(TmpMax); + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, BaseIndex++); + ComputeMinMax_HM(TmpMin, TmpMax, VP); + Min_.Min(TmpMin); + Max_.Max(TmpMax); + } + } + } + else + { + const CollisionAABB& CurrentBox = Current.GetNeg()->mAABB; + CurrentBox.GetMin(Min_); + CurrentBox.GetMax(Max_); + } +#ifdef OPC_USE_FCOMI + Min.x = FCMin2(Min.x, Min_.x); + Max.x = FCMax2(Max.x, Max_.x); + Min.y = FCMin2(Min.y, Min_.y); + Max.y = FCMax2(Max.y, Max_.y); + Min.z = FCMin2(Min.z, Min_.z); + Max.z = FCMax2(Max.z, Max_.z); +#else + Min.Min(Min_); + Max.Max(Max_); +#endif + Current.mAABB.SetMinMax(Min, Max); + } + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_HybridModel.h b/Extras/CDTestFramework/Opcode/OPC_HybridModel.h new file mode 100644 index 0000000..117b9c3 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_HybridModel.h @@ -0,0 +1,115 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for hybrid models. + * \file OPC_HybridModel.h + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_HYBRIDMODEL_H__ +#define __OPC_HYBRIDMODEL_H__ + + //! Leaf descriptor + struct LeafTriangles + { + udword Data; //!< Packed data + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets number of triangles in the leaf. + * \return number of triangles N, with 0 < N <= 16 + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbTriangles() const { return (Data & 15)+1; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets triangle index for this leaf. Indexed model's array of indices retrieved with HybridModel::GetIndices() + * \return triangle index + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetTriangleIndex() const { return Data>>4; } + inline_ void SetData(udword nb, udword index) { ASSERT(nb>0 && nb<=16); nb--; Data = (index<<4)|(nb&15); } + }; + + class OPCODE_API HybridModel : public BaseModel + { + public: + // Constructor/Destructor + HybridModel(); + virtual ~HybridModel(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Build(const OPCODECREATE& create); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) udword GetUsedBytes() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Refit(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets array of triangles. + * \return array of triangles + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const LeafTriangles* GetLeafTriangles() const { return mTriangles; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets array of indices. + * \return array of indices + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const udword* GetIndices() const { return mIndices; } + + private: + udword mNbLeaves; //!< Number of leaf nodes in the model + LeafTriangles* mTriangles; //!< Array of mNbLeaves leaf descriptors + udword mNbPrimitives; //!< Number of primitives in the model + udword* mIndices; //!< Array of primitive indices + + // Internal methods + void Release(); + }; + +#endif // __OPC_HYBRIDMODEL_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_IceHook.h b/Extras/CDTestFramework/Opcode/OPC_IceHook.h new file mode 100644 index 0000000..4666d44 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_IceHook.h @@ -0,0 +1,92 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +// Should be included by Opcode.h if needed + + #define ICE_DONT_CHECK_COMPILER_OPTIONS + + // From Windows... + typedef int BOOL; + #ifndef FALSE + #define FALSE 0 + #endif + + #ifndef TRUE + #define TRUE 1 + #endif + + #include + #include + #include + #include + #include + #include + + #ifndef ASSERT + #define ASSERT(exp) {} + #endif + #define ICE_COMPILE_TIME_ASSERT(exp) extern char ICE_Dummy[ (exp) ? 1 : -1 ] + + #define Log {} + #define SetIceError false + #define EC_OUTOFMEMORY "Out of memory" + + #include ".\Ice\IcePreprocessor.h" + + #undef ICECORE_API + #define ICECORE_API OPCODE_API + + #include ".\Ice\IceTypes.h" + #include ".\Ice\IceFPU.h" + #include ".\Ice\IceMemoryMacros.h" + + namespace Opcode + { + namespace IceCore + { + #include ".\Ice\IceAllocator.h" + #include ".\Ice\IceUtils.h" + #include ".\Ice\IceBitArray.h" + #include ".\Ice\IceContainer.h" + #include ".\Ice\IcePairs.h" + #include ".\Ice\IceRevisitedRadix.h" + #include ".\Ice\IceRandom.h" + #include ".\Ice\IceHashing.h" + } + using namespace IceCore; + + #define ICEMATHS_API OPCODE_API + namespace IceMaths + { + #include ".\Ice\IceAxes.h" + #include ".\Ice\IcePoint.h" + #include ".\Ice\IceHPoint.h" + #include ".\Ice\IceMatrix3x3.h" + #include ".\Ice\IceMatrix4x4.h" + #include ".\Ice\IcePlane.h" + #include ".\Ice\IceRay.h" + #include ".\Ice\IceIndexedTriangle.h" + #include ".\Ice\IceTriangle.h" + #include ".\Ice\IceTriList.h" + #include ".\Ice\IceAABB.h" + #include ".\Ice\IceOBB.h" + #include ".\Ice\IceBoundingSphere.h" + #include ".\Ice\IceSegment.h" + #include ".\Ice\IceLSS.h" + } + using namespace IceMaths; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_LSSAABBOverlap.h b/Extras/CDTestFramework/Opcode/OPC_LSSAABBOverlap.h new file mode 100644 index 0000000..6e8e477 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_LSSAABBOverlap.h @@ -0,0 +1,539 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +// Following code from Magic-Software (http://www.magic-software.com/) +// A bit modified for Opcode + +inline_ float OPC_PointAABBSqrDist(const Point& point, const Point& center, const Point& extents) +{ + // Compute coordinates of point in box coordinate system + Point Closest = point - center; + + float SqrDistance = 0.0f; + + if(Closest.x < -extents.x) + { + float Delta = Closest.x + extents.x; + SqrDistance += Delta*Delta; + } + else if(Closest.x > extents.x) + { + float Delta = Closest.x - extents.x; + SqrDistance += Delta*Delta; + } + + if(Closest.y < -extents.y) + { + float Delta = Closest.y + extents.y; + SqrDistance += Delta*Delta; + } + else if(Closest.y > extents.y) + { + float Delta = Closest.y - extents.y; + SqrDistance += Delta*Delta; + } + + if(Closest.z < -extents.z) + { + float Delta = Closest.z + extents.z; + SqrDistance += Delta*Delta; + } + else if(Closest.z > extents.z) + { + float Delta = Closest.z - extents.z; + SqrDistance += Delta*Delta; + } + return SqrDistance; +} + +static void Face(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, const Point& rkPmE, float* pfLParam, float& rfSqrDistance) +{ + Point kPpE; + float fLSqr, fInv, fTmp, fParam, fT, fDelta; + + kPpE[i1] = rkPnt[i1] + extents[i1]; + kPpE[i2] = rkPnt[i2] + extents[i2]; + if(rkDir[i0]*kPpE[i1] >= rkDir[i1]*rkPmE[i0]) + { + if(rkDir[i0]*kPpE[i2] >= rkDir[i2]*rkPmE[i0]) + { + // v[i1] >= -e[i1], v[i2] >= -e[i2] (distance = 0) + if(pfLParam) + { + rkPnt[i0] = extents[i0]; + fInv = 1.0f/rkDir[i0]; + rkPnt[i1] -= rkDir[i1]*rkPmE[i0]*fInv; + rkPnt[i2] -= rkDir[i2]*rkPmE[i0]*fInv; + *pfLParam = -rkPmE[i0]*fInv; + } + } + else + { + // v[i1] >= -e[i1], v[i2] < -e[i2] + fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i2]*rkDir[i2]; + fTmp = fLSqr*kPpE[i1] - rkDir[i1]*(rkDir[i0]*rkPmE[i0] + rkDir[i2]*kPpE[i2]); + if(fTmp <= 2.0f*fLSqr*extents[i1]) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i1]*rkDir[i1]; + fTmp = kPpE[i1] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*fTmp + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + fTmp*fTmp + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = fT - extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + else + { + fLSqr += rkDir[i1]*rkDir[i1]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*rkPmE[i1] + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + rkPmE[i1]*rkPmE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + } + } + else + { + if ( rkDir[i0]*kPpE[i2] >= rkDir[i2]*rkPmE[i0] ) + { + // v[i1] < -e[i1], v[i2] >= -e[i2] + fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]; + fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1]); + if(fTmp <= 2.0f*fLSqr*extents[i2]) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i2]*rkDir[i2]; + fTmp = kPpE[i2] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*fTmp; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + fTmp*fTmp + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = fT - extents[i2]; + } + } + else + { + fLSqr += rkDir[i2]*rkDir[i2]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*rkPmE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + rkPmE[i2]*rkPmE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = extents[i2]; + } + } + } + else + { + // v[i1] < -e[i1], v[i2] < -e[i2] + fLSqr = rkDir[i0]*rkDir[i0]+rkDir[i2]*rkDir[i2]; + fTmp = fLSqr*kPpE[i1] - rkDir[i1]*(rkDir[i0]*rkPmE[i0] + rkDir[i2]*kPpE[i2]); + if(fTmp >= 0.0f) + { + // v[i1]-edge is closest + if ( fTmp <= 2.0f*fLSqr*extents[i1] ) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i1]*rkDir[i1]; + fTmp = kPpE[i1] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*fTmp + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + fTmp*fTmp + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = fT - extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + else + { + fLSqr += rkDir[i1]*rkDir[i1]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*rkPmE[i1] + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + rkPmE[i1]*rkPmE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + return; + } + + fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]; + fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1]); + if(fTmp >= 0.0f) + { + // v[i2]-edge is closest + if(fTmp <= 2.0f*fLSqr*extents[i2]) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i2]*rkDir[i2]; + fTmp = kPpE[i2] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*fTmp; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + fTmp*fTmp + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = fT - extents[i2]; + } + } + else + { + fLSqr += rkDir[i2]*rkDir[i2]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*rkPmE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + rkPmE[i2]*rkPmE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = extents[i2]; + } + } + return; + } + + // (v[i1],v[i2])-corner is closest + fLSqr += rkDir[i2]*rkDir[i2]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + } +} + +static void CaseNoZeros(Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) +{ + Point kPmE(rkPnt.x - extents.x, rkPnt.y - extents.y, rkPnt.z - extents.z); + + float fProdDxPy, fProdDyPx, fProdDzPx, fProdDxPz, fProdDzPy, fProdDyPz; + + fProdDxPy = rkDir.x*kPmE.y; + fProdDyPx = rkDir.y*kPmE.x; + if(fProdDyPx >= fProdDxPy) + { + fProdDzPx = rkDir.z*kPmE.x; + fProdDxPz = rkDir.x*kPmE.z; + if(fProdDzPx >= fProdDxPz) + { + // line intersects x = e0 + Face(0, 1, 2, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + else + { + // line intersects z = e2 + Face(2, 0, 1, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + } + else + { + fProdDzPy = rkDir.z*kPmE.y; + fProdDyPz = rkDir.y*kPmE.z; + if(fProdDzPy >= fProdDyPz) + { + // line intersects y = e1 + Face(1, 2, 0, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + else + { + // line intersects z = e2 + Face(2, 0, 1, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + } +} + +static void Case0(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) +{ + float fPmE0 = rkPnt[i0] - extents[i0]; + float fPmE1 = rkPnt[i1] - extents[i1]; + float fProd0 = rkDir[i1]*fPmE0; + float fProd1 = rkDir[i0]*fPmE1; + float fDelta, fInvLSqr, fInv; + + if(fProd0 >= fProd1) + { + // line intersects P[i0] = e[i0] + rkPnt[i0] = extents[i0]; + + float fPpE1 = rkPnt[i1] + extents[i1]; + fDelta = fProd0 - rkDir[i0]*fPpE1; + if(fDelta >= 0.0f) + { + fInvLSqr = 1.0f/(rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]); + rfSqrDistance += fDelta*fDelta*fInvLSqr; + if(pfLParam) + { + rkPnt[i1] = -extents[i1]; + *pfLParam = -(rkDir[i0]*fPmE0+rkDir[i1]*fPpE1)*fInvLSqr; + } + } + else + { + if(pfLParam) + { + fInv = 1.0f/rkDir[i0]; + rkPnt[i1] -= fProd0*fInv; + *pfLParam = -fPmE0*fInv; + } + } + } + else + { + // line intersects P[i1] = e[i1] + rkPnt[i1] = extents[i1]; + + float fPpE0 = rkPnt[i0] + extents[i0]; + fDelta = fProd1 - rkDir[i1]*fPpE0; + if(fDelta >= 0.0f) + { + fInvLSqr = 1.0f/(rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]); + rfSqrDistance += fDelta*fDelta*fInvLSqr; + if(pfLParam) + { + rkPnt[i0] = -extents[i0]; + *pfLParam = -(rkDir[i0]*fPpE0+rkDir[i1]*fPmE1)*fInvLSqr; + } + } + else + { + if(pfLParam) + { + fInv = 1.0f/rkDir[i1]; + rkPnt[i0] -= fProd1*fInv; + *pfLParam = -fPmE1*fInv; + } + } + } + + if(rkPnt[i2] < -extents[i2]) + { + fDelta = rkPnt[i2] + extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i2] = -extents[i2]; + } + else if ( rkPnt[i2] > extents[i2] ) + { + fDelta = rkPnt[i2] - extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i2] = extents[i2]; + } +} + +static void Case00(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) +{ + float fDelta; + + if(pfLParam) + *pfLParam = (extents[i0] - rkPnt[i0])/rkDir[i0]; + + rkPnt[i0] = extents[i0]; + + if(rkPnt[i1] < -extents[i1]) + { + fDelta = rkPnt[i1] + extents[i1]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i1] = -extents[i1]; + } + else if(rkPnt[i1] > extents[i1]) + { + fDelta = rkPnt[i1] - extents[i1]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i1] = extents[i1]; + } + + if(rkPnt[i2] < -extents[i2]) + { + fDelta = rkPnt[i2] + extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i1] = -extents[i2]; + } + else if(rkPnt[i2] > extents[i2]) + { + fDelta = rkPnt[i2] - extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i2] = extents[i2]; + } +} + +static void Case000(Point& rkPnt, const Point& extents, float& rfSqrDistance) +{ + float fDelta; + + if(rkPnt.x < -extents.x) + { + fDelta = rkPnt.x + extents.x; + rfSqrDistance += fDelta*fDelta; + rkPnt.x = -extents.x; + } + else if(rkPnt.x > extents.x) + { + fDelta = rkPnt.x - extents.x; + rfSqrDistance += fDelta*fDelta; + rkPnt.x = extents.x; + } + + if(rkPnt.y < -extents.y) + { + fDelta = rkPnt.y + extents.y; + rfSqrDistance += fDelta*fDelta; + rkPnt.y = -extents.y; + } + else if(rkPnt.y > extents.y) + { + fDelta = rkPnt.y - extents.y; + rfSqrDistance += fDelta*fDelta; + rkPnt.y = extents.y; + } + + if(rkPnt.z < -extents.z) + { + fDelta = rkPnt.z + extents.z; + rfSqrDistance += fDelta*fDelta; + rkPnt.z = -extents.z; + } + else if(rkPnt.z > extents.z) + { + fDelta = rkPnt.z - extents.z; + rfSqrDistance += fDelta*fDelta; + rkPnt.z = extents.z; + } +} + +static float SqrDistance(const Ray& rkLine, const Point& center, const Point& extents, float* pfLParam) +{ + // compute coordinates of line in box coordinate system + Point kDiff = rkLine.mOrig - center; + Point kPnt = kDiff; + Point kDir = rkLine.mDir; + + // Apply reflections so that direction vector has nonnegative components. + bool bReflect[3]; + for(int i=0;i<3;i++) + { + if(kDir[i]<0.0f) + { + kPnt[i] = -kPnt[i]; + kDir[i] = -kDir[i]; + bReflect[i] = true; + } + else + { + bReflect[i] = false; + } + } + + float fSqrDistance = 0.0f; + + if(kDir.x>0.0f) + { + if(kDir.y>0.0f) + { + if(kDir.z>0.0f) CaseNoZeros(kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,+,+) + else Case0(0, 1, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,+,0) + } + else + { + if(kDir.z>0.0f) Case0(0, 2, 1, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,0,+) + else Case00(0, 1, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,0,0) + } + } + else + { + if(kDir.y>0.0f) + { + if(kDir.z>0.0f) Case0(1, 2, 0, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,+,+) + else Case00(1, 0, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,+,0) + } + else + { + if(kDir.z>0.0f) Case00(2, 0, 1, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,0,+) + else + { + Case000(kPnt, extents, fSqrDistance); // (0,0,0) + if(pfLParam) *pfLParam = 0.0f; + } + } + } + return fSqrDistance; +} + +inline_ float OPC_SegmentOBBSqrDist(const Segment& segment, const Point& c0, const Point& e0) +{ + float fLP; + float fSqrDistance = SqrDistance(Ray(segment.GetOrigin(), segment.ComputeDirection()), c0, e0, &fLP); + if(fLP>=0.0f) + { + if(fLP<=1.0f) return fSqrDistance; + else return OPC_PointAABBSqrDist(segment.mP1, c0, e0); + } + else return OPC_PointAABBSqrDist(segment.mP0, c0, e0); +} + +inline_ BOOL LSSCollider::LSSAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbVolumeBVTests++; + + float s2 = OPC_SegmentOBBSqrDist(mSeg, center, extents); + if(s2Add(prim_index); + +//! LSS-triangle overlap test +#define LSS_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \ + \ + /* Perform LSS-tri overlap test */ \ + if(LSSTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +LSSCollider::LSSCollider() +{ +// mCenter.Zero(); +// mRadius2 = 0.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +LSSCollider::~LSSCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] an lss cache + * \param lss [in] collision lss in local space + * \param model [in] Opcode model to collide with + * \param worldl [in] lss world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool LSSCollider::Collide(LSSCache& cache, const LSS& lss, const Model& model, const Matrix4x4* worldl, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, lss, worldl, worldm)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * - check temporal coherence + * + * \param cache [in/out] an lss cache + * \param lss [in] lss in local space + * \param worldl [in] lss world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL LSSCollider::InitQuery(LSSCache& cache, const LSS& lss, const Matrix4x4* worldl, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute LSS in model space: + // - Precompute R^2 + mRadius2 = lss.mRadius * lss.mRadius; + // - Compute segment + mSeg.mP0 = lss.mP0; + mSeg.mP1 = lss.mP1; + // -> to world space + if(worldl) + { + mSeg.mP0 *= *worldl; + mSeg.mP1 *= *worldl; + } + // -> to model space + if(worldm) + { + // Invert model matrix + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + + mSeg.mP0 *= InvWorldM; + mSeg.mP1 *= InvWorldM; + } + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the LSS (and set contact status if needed) + LSS_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence : + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the LSS (and set contact status if needed) + LSS_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // We're interested in all contacts =>test the new real LSS N(ew) against the previous fat LSS P(revious): + + // ### rewrite this + + LSS Test(mSeg, lss.mRadius); // in model space + LSS Previous(cache.Previous, sqrtf(cache.Previous.mRadius)); + +// if(cache.Previous.Contains(Test)) + if(IsCacheValid(cache) && Previous.Contains(Test)) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat sphere so that coherence will work for subsequent frames + mRadius2 *= cache.FatCoeff; +// mRadius2 = (lss.mRadius * cache.FatCoeff)*(lss.mRadius * cache.FatCoeff); + + + // Update cache with query data (signature for cached faces) + cache.Previous.mP0 = mSeg.mP0; + cache.Previous.mP1 = mSeg.mP1; + cache.Previous.mRadius = mRadius2; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for vanilla AABB trees. + * \param cache [in/out] an lss cache + * \param lss [in] collision lss in world space + * \param tree [in] AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool LSSCollider::Collide(LSSCache& cache, const LSS& lss, const AABBTree* tree) +{ + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + if(InitQuery(cache, lss)) return true; + + // Perform collision query + _Collide(tree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the LSS completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the LSS contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL LSSCollider::LSSContainsBox(const Point& bc, const Point& be) +{ + // Not implemented + return FALSE; +} + +#define TEST_BOX_IN_LSS(center, extents) \ + if(LSSContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + LSS_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->IsLeaf()) + { + LSS_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for vanilla AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBTreeNode* node) +{ + // Perform LSS-AABB overlap test + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!LSSAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf() || LSSContainsBox(Center, Extents)) + { + mFlags |= OPC_CONTACT; + mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _Collide(node->GetPos()); + _Collide(node->GetNeg()); + } +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridLSSCollider::HybridLSSCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridLSSCollider::~HybridLSSCollider() +{ +} + +bool HybridLSSCollider::Collide(LSSCache& cache, const LSS& lss, const HybridModel& model, const Matrix4x4* worldl, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, lss, worldl, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;imCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + LSS_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + LSS_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_LSSCollider.h b/Extras/CDTestFramework/Opcode/OPC_LSSCollider.h new file mode 100644 index 0000000..43921b3 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_LSSCollider.h @@ -0,0 +1,108 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an LSS collider. + * \file OPC_LSSCollider.h + * \author Pierre Terdiman + * \date December, 28, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_LSSCOLLIDER_H__ +#define __OPC_LSSCOLLIDER_H__ + + struct OPCODE_API LSSCache : VolumeCache + { + LSSCache() + { + Previous.mP0 = Point(0.0f, 0.0f, 0.0f); + Previous.mP1 = Point(0.0f, 0.0f, 0.0f); + Previous.mRadius = 0.0f; + FatCoeff = 1.1f; + } + + // Cached faces signature + LSS Previous; //!< LSS used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat LSS + }; + + class OPCODE_API LSSCollider : public VolumeCollider + { + public: + // Constructor / Destructor + LSSCollider(); + virtual ~LSSCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] an lss cache + * \param lss [in] collision lss in local space + * \param model [in] Opcode model to collide with + * \param worldl [in] lss world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(LSSCache& cache, const LSS& lss, const Model& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + // + bool Collide(LSSCache& cache, const LSS& lss, const AABBTree* tree); + protected: + // LSS in model space + Segment mSeg; //!< Segment + float mRadius2; //!< LSS radius squared + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL LSSContainsBox(const Point& bc, const Point& be); + inline_ BOOL LSSAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL LSSTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(LSSCache& cache, const LSS& lss, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridLSSCollider : public LSSCollider + { + public: + // Constructor / Destructor + HybridLSSCollider(); + virtual ~HybridLSSCollider(); + + bool Collide(LSSCache& cache, const LSS& lss, const HybridModel& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_LSSCOLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_LSSTriOverlap.h b/Extras/CDTestFramework/Opcode/OPC_LSSTriOverlap.h new file mode 100644 index 0000000..b6171a8 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_LSSTriOverlap.h @@ -0,0 +1,696 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +// Following code from Magic-Software (http://www.magic-software.com/) +// A bit modified for Opcode + +static const float gs_fTolerance = 1e-05f; + +static float OPC_PointTriangleSqrDist(const Point& point, const Point& p0, const Point& p1, const Point& p2) +{ + // Hook + Point TriEdge0 = p1 - p0; + Point TriEdge1 = p2 - p0; + + Point kDiff = p0 - point; + float fA00 = TriEdge0.SquareMagnitude(); + float fA01 = TriEdge0 | TriEdge1; + float fA11 = TriEdge1.SquareMagnitude(); + float fB0 = kDiff | TriEdge0; + float fB1 = kDiff | TriEdge1; + float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11 - fA01*fA01); + float fS = fA01*fB1-fA11*fB0; + float fT = fA01*fB0-fA00*fB1; + float fSqrDist; + + if(fS + fT <= fDet) + { + if(fS < 0.0f) + { + if(fT < 0.0f) // region 4 + { + if(fB0 < 0.0f) + { + if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + if(fB1 >= 0.0f) fSqrDist = fC; + else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else // region 3 + { + if(fB1 >= 0.0f) fSqrDist = fC; + else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else if(fT < 0.0f) // region 5 + { + if(fB0 >= 0.0f) fSqrDist = fC; + else if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else // region 0 + { + // minimum at interior point + if(fDet==0.0f) + { + fSqrDist = MAX_FLOAT; + } + else + { + float fInvDet = 1.0f/fDet; + fS *= fInvDet; + fT *= fInvDet; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + } + else + { + float fTmp0, fTmp1, fNumer, fDenom; + + if(fS < 0.0f) // region 2 + { + fTmp0 = fA01 + fB0; + fTmp1 = fA11 + fB1; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else + { + fS = fNumer/fDenom; + fT = 1.0f - fS; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + else + { + if(fTmp1 <= 0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else if(fB1 >= 0.0f) fSqrDist = fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else if(fT < 0.0f) // region 6 + { + fTmp0 = fA01 + fB1; + fTmp1 = fA00 + fB0; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fT = fNumer/fDenom; + fS = 1.0f - fT; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + else + { + if(fTmp1 <= 0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(fB0 >= 0.0f) fSqrDist = fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + } + else // region 1 + { + fNumer = fA11 + fB1 - fA01 - fB0; + if(fNumer <= 0.0f) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else + { + fS = fNumer/fDenom; + fT = 1.0f - fS; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + } + } + return fabsf(fSqrDist); +} + +static float OPC_SegmentSegmentSqrDist(const Segment& rkSeg0, const Segment& rkSeg1) +{ + // Hook + Point rkSeg0Direction = rkSeg0.ComputeDirection(); + Point rkSeg1Direction = rkSeg1.ComputeDirection(); + + Point kDiff = rkSeg0.mP0 - rkSeg1.mP0; + float fA00 = rkSeg0Direction.SquareMagnitude(); + float fA01 = -rkSeg0Direction.Dot(rkSeg1Direction); + float fA11 = rkSeg1Direction.SquareMagnitude(); + float fB0 = kDiff.Dot(rkSeg0Direction); + float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11-fA01*fA01); + + float fB1, fS, fT, fSqrDist, fTmp; + + if(fDet>=gs_fTolerance) + { + // line segments are not parallel + fB1 = -kDiff.Dot(rkSeg1Direction); + fS = fA01*fB1-fA11*fB0; + fT = fA01*fB0-fA00*fB1; + + if(fS >= 0.0f) + { + if(fS <= fDet) + { + if(fT >= 0.0f) + { + if(fT <= fDet) // region 0 (interior) + { + // minimum at two interior points of 3D lines + float fInvDet = 1.0f/fDet; + fS *= fInvDet; + fT *= fInvDet; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + else // region 3 (side) + { + fTmp = fA01+fB0; + if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + } + else // region 7 (side) + { + if(fB0>=0.0f) fSqrDist = fC; + else if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + } + else + { + if ( fT >= 0.0 ) + { + if ( fT <= fDet ) // region 1 (side) + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + else // region 2 (corner) + { + fTmp = fA01+fB0; + if ( -fTmp <= fA00 ) + { + if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + else + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + } + } + else // region 8 (corner) + { + if ( -fB0 < fA00 ) + { + if(fB0>=0.0f) fSqrDist = fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + } + } + } + else + { + if ( fT >= 0.0f ) + { + if ( fT <= fDet ) // region 5 (side) + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + else // region 4 (corner) + { + fTmp = fA01+fB0; + if ( fTmp < 0.0f ) + { + if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + else + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + } + else // region 6 (corner) + { + if ( fB0 < 0.0f ) + { + if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + } + } + else + { + // line segments are parallel + if ( fA01 > 0.0f ) + { + // direction vectors form an obtuse angle + if ( fB0 >= 0.0f ) + { + fSqrDist = fC; + } + else if ( -fB0 <= fA00 ) + { + fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fB1 = -kDiff.Dot(rkSeg1Direction); + fTmp = fA00+fB0; + if ( -fTmp >= fA01 ) + { + fSqrDist = fA00+fA11+fC+2.0f*(fA01+fB0+fB1); + } + else + { + fT = -fTmp/fA01; + fSqrDist = fA00+2.0f*fB0+fC+fT*(fA11*fT+2.0f*(fA01+fB1)); + } + } + } + else + { + // direction vectors form an acute angle + if ( -fB0 >= fA00 ) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else if ( fB0 <= 0.0f ) + { + fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fB1 = -kDiff.Dot(rkSeg1Direction); + if ( fB0 >= -fA01 ) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fT = -fB0/fA01; + fSqrDist = fC+fT*(2.0f*fB1+fA11*fT); + } + } + } + } + return fabsf(fSqrDist); +} + +inline_ float OPC_SegmentRaySqrDist(const Segment& rkSeg0, const Ray& rkSeg1) +{ + return OPC_SegmentSegmentSqrDist(rkSeg0, Segment(rkSeg1.mOrig, rkSeg1.mOrig + rkSeg1.mDir)); +} + +static float OPC_SegmentTriangleSqrDist(const Segment& segment, const Point& p0, const Point& p1, const Point& p2) +{ + // Hook + const Point TriEdge0 = p1 - p0; + const Point TriEdge1 = p2 - p0; + + const Point& rkSegOrigin = segment.GetOrigin(); + Point rkSegDirection = segment.ComputeDirection(); + + Point kDiff = p0 - rkSegOrigin; + float fA00 = rkSegDirection.SquareMagnitude(); + float fA01 = -rkSegDirection.Dot(TriEdge0); + float fA02 = -rkSegDirection.Dot(TriEdge1); + float fA11 = TriEdge0.SquareMagnitude(); + float fA12 = TriEdge0.Dot(TriEdge1); + float fA22 = TriEdge1.Dot(TriEdge1); + float fB0 = -kDiff.Dot(rkSegDirection); + float fB1 = kDiff.Dot(TriEdge0); + float fB2 = kDiff.Dot(TriEdge1); + float fCof00 = fA11*fA22-fA12*fA12; + float fCof01 = fA02*fA12-fA01*fA22; + float fCof02 = fA01*fA12-fA02*fA11; + float fDet = fA00*fCof00+fA01*fCof01+fA02*fCof02; + + Ray kTriSeg; + Point kPt; + float fSqrDist, fSqrDist0; + + if(fabsf(fDet)>=gs_fTolerance) + { + float fCof11 = fA00*fA22-fA02*fA02; + float fCof12 = fA02*fA01-fA00*fA12; + float fCof22 = fA00*fA11-fA01*fA01; + float fInvDet = 1.0f/fDet; + float fRhs0 = -fB0*fInvDet; + float fRhs1 = -fB1*fInvDet; + float fRhs2 = -fB2*fInvDet; + + float fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; + float fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; + float fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; + + if ( fR < 0.0f ) + { + if ( fS+fT <= 1.0f ) + { + if ( fS < 0.0f ) + { + if ( fT < 0.0f ) // region 4m + { + // min on face s=0 or t=0 or r=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0 1 + { + if ( fS+fT <= 1.0f ) + { + if ( fS < 0.0f ) + { + if ( fT < 0.0f ) // region 4p + { + // min on face s=0 or t=0 or r=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0GetTriangle(triangle_index); + * // Setup pointers to vertices for the collision system + * triangle.Vertex[0] = MyMesh->GetVertex(Tri->mVRef[0]); + * triangle.Vertex[1] = MyMesh->GetVertex(Tri->mVRef[1]); + * triangle.Vertex[2] = MyMesh->GetVertex(Tri->mVRef[2]); + * } + * + * // Setup callbacks + * MeshInterface0->SetCallback(ColCallback, udword(Mesh0)); + * MeshInterface1->SetCallback(ColCallback, udword(Mesh1)); + * \endcode + * + * Of course, you should make this callback as fast as possible. And you're also not supposed + * to modify the geometry *after* the collision trees have been built. The alternative was to + * store the geometry & topology in the collision system as well (as in RAPID) but we have found + * this approach to waste a lot of ram in many cases. + * + * + * POINTERS: + * + * If you're internally using the following canonical structures: + * - a vertex made of three 32-bits floating point values + * - a triangle made of three 32-bits integer vertex references + * ...then you may want to use pointers instead of callbacks. This is the same, except OPCODE will directly + * use provided pointers to access the topology and geometry, without using a callback. It might be faster, + * but probably not as safe. Pointers have been introduced in OPCODE 1.2. + * + * Ex: + * + * \code + * // Setup pointers + * MeshInterface0->SetPointers(Mesh0->GetFaces(), Mesh0->GetVerts()); + * MeshInterface1->SetPointers(Mesh1->GetFaces(), Mesh1->GetVerts()); + * \endcode + * + * + * STRIDES: + * + * If your vertices are D3D-like entities interleaving a position, a normal and/or texture coordinates + * (i.e. if your vertices are FVFs), you might want to use a vertex stride to skip extra data OPCODE + * doesn't need. Using a stride shouldn't be notably slower than not using it, but it might increase + * cache misses. Please also note that you *shouldn't* read from AGP or video-memory buffers ! + * + * + * In any case, compilation flags are here to select callbacks/pointers/strides at compile time, so + * choose what's best for your application. All of this has been wrapped into this MeshInterface. + * + * \class MeshInterface + * \author Pierre Terdiman + * \version 1.3 + * \date November, 27, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +MeshInterface::MeshInterface() : +#ifdef OPC_USE_CALLBACKS + mUserData (null), + mObjCallback (null), +#else + mTris (null), + mVerts (null), + #ifdef OPC_USE_STRIDE + mTriStride (sizeof(IndexedTriangle)), + mVertexStride (sizeof(Point)), + #endif +#endif + mNbTris (0), + mNbVerts (0) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +MeshInterface::~MeshInterface() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the mesh interface is valid, i.e. things have been setup correctly. + * \return true if valid + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool MeshInterface::IsValid() const +{ + if(!mNbTris || !mNbVerts) return false; +#ifdef OPC_USE_CALLBACKS + if(!mObjCallback) return false; +#else + if(!mTris || !mVerts) return false; +#endif + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the mesh itself is valid. + * Currently we only look for degenerate faces. + * \return number of degenerate faces + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword MeshInterface::CheckTopology() const +{ + // Check topology. If the model contains degenerate faces, collision report can be wrong in some cases. + // e.g. it happens with the standard MAX teapot. So clean your meshes first... If you don't have a mesh cleaner + // you can try this: www.codercorner.com/Consolidation.zip + + udword NbDegenerate = 0; + + VertexPointers VP; + + // Using callbacks, we don't have access to vertex indices. Nevertheless we still can check for + // redundant vertex pointers, which cover all possibilities (callbacks/pointers/strides). + for(udword i=0;i= 0.0f; + } + }; + +#ifdef OPC_USE_CALLBACKS + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE to request vertices from the app. + * \param triangle_index [in] face index for which the system is requesting the vertices + * \param triangle [out] triangle's vertices (must be provided by the user) + * \param user_data [in] user-defined data from SetCallback() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef void (*RequestCallback) (udword triangle_index, VertexPointers& triangle, void* user_data); +#endif + + class OPCODE_API MeshInterface + { + public: + // Constructor / Destructor + MeshInterface(); + ~MeshInterface(); + // Common settings + inline_ udword GetNbTriangles() const { return mNbTris; } + inline_ udword GetNbVertices() const { return mNbVerts; } + inline_ void SetNbTriangles(udword nb) { mNbTris = nb; } + inline_ void SetNbVertices(udword nb) { mNbVerts = nb; } + +#ifdef OPC_USE_CALLBACKS + // Callback settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index. + * \param callback [in] user-defined callback + * \param user_data [in] user-defined data + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetCallback(RequestCallback callback, void* user_data); + inline_ void* GetUserData() const { return mUserData; } + inline_ RequestCallback GetCallback() const { return mObjCallback; } +#else + // Pointers settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object. + * \param tris [in] pointer to triangles + * \param verts [in] pointer to vertices + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetPointers(const IndexedTriangle* tris, const Point* verts); + inline_ const IndexedTriangle* GetTris() const { return mTris; } + inline_ const Point* GetVerts() const { return mVerts; } + + #ifdef OPC_USE_STRIDE + // Strides settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Strides control + * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices. + * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position. + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point)); + inline_ udword GetTriStride() const { return mTriStride; } + inline_ udword GetVertexStride() const { return mVertexStride; } + #endif +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Fetches a triangle given a triangle index. + * \param vp [out] required triangle's vertex pointers + * \param index [in] triangle index + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void GetTriangle(VertexPointers& vp, udword index) const + { +#ifdef OPC_USE_CALLBACKS + (mObjCallback)(index, vp, mUserData); +#else + #ifdef OPC_USE_STRIDE + const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); + vp.Vertex[0] = (const Point*)(((ubyte*)mVerts) + T->mVRef[0] * mVertexStride); + vp.Vertex[1] = (const Point*)(((ubyte*)mVerts) + T->mVRef[1] * mVertexStride); + vp.Vertex[2] = (const Point*)(((ubyte*)mVerts) + T->mVRef[2] * mVertexStride); + #else + const IndexedTriangle* T = &mTris[index]; + vp.Vertex[0] = &mVerts[T->mVRef[0]]; + vp.Vertex[1] = &mVerts[T->mVRef[1]]; + vp.Vertex[2] = &mVerts[T->mVRef[2]]; + #endif +#endif + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Remaps client's mesh according to a permutation. + * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles) + * \param permutation [in] list of triangle indices + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool RemapClient(udword nb_indices, const udword* permutation) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the mesh interface is valid, i.e. things have been setup correctly. + * \return true if valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool IsValid() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the mesh itself is valid. + * Currently we only look for degenerate faces. + * \return number of degenerate faces + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + udword CheckTopology() const; + private: + + udword mNbTris; //!< Number of triangles in the input model + udword mNbVerts; //!< Number of vertices in the input model +#ifdef OPC_USE_CALLBACKS + // User callback + void* mUserData; //!< User-defined data sent to callback + RequestCallback mObjCallback; //!< Object callback +#else + // User pointers + const IndexedTriangle* mTris; //!< Array of indexed triangles + const Point* mVerts; //!< Array of vertices + #ifdef OPC_USE_STRIDE + udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3] + udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3] + #endif +#endif + }; + +#endif //__OPC_MESHINTERFACE_H__ \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/OPC_Model.cpp b/Extras/CDTestFramework/Opcode/OPC_Model.cpp new file mode 100644 index 0000000..f8c4c87 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Model.cpp @@ -0,0 +1,231 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for OPCODE models. + * \file OPC_Model.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * The main collision wrapper, for all trees. Supported trees are: + * - Normal trees (2*N-1 nodes, full size) + * - No-leaf trees (N-1 nodes, full size) + * - Quantized trees (2*N-1 nodes, half size) + * - Quantized no-leaf trees (N-1 nodes, half size) + * + * Usage: + * + * 1) Create a static mesh interface using callbacks or pointers. (see OPC_MeshInterface.cpp). + * Keep it around in your app, since a pointer to this interface is saved internally and + * used until you release the collision structures. + * + * 2) Build a Model using a creation structure: + * + * \code + * Model Sample; + * + * OPCODECREATE OPCC; + * OPCC.IMesh = ...; + * OPCC.Rules = ...; + * OPCC.NoLeaf = ...; + * OPCC.Quantized = ...; + * OPCC.KeepOriginal = ...; + * bool Status = Sample.Build(OPCC); + * \endcode + * + * 3) Create a tree collider and set it up: + * + * \code + * AABBTreeCollider TC; + * TC.SetFirstContact(...); + * TC.SetFullBoxBoxTest(...); + * TC.SetFullPrimBoxTest(...); + * TC.SetTemporalCoherence(...); + * \endcode + * + * 4) Perform a collision query + * + * \code + * // Setup cache + * static BVTCache ColCache; + * ColCache.Model0 = &Model0; + * ColCache.Model1 = &Model1; + * + * // Collision query + * bool IsOk = TC.Collide(ColCache, World0, World1); + * + * // Get collision status => if true, objects overlap + * BOOL Status = TC.GetContactStatus(); + * + * // Number of colliding pairs and list of pairs + * udword NbPairs = TC.GetNbPairs(); + * const Pair* p = TC.GetPairs() + * \endcode + * + * 5) Stats + * + * \code + * Model0.GetUsedBytes() = number of bytes used for this collision tree + * TC.GetNbBVBVTests() = number of BV-BV overlap tests performed during last query + * TC.GetNbPrimPrimTests() = number of Triangle-Triangle overlap tests performed during last query + * TC.GetNbBVPrimTests() = number of Triangle-BV overlap tests performed during last query + * \endcode + * + * \class Model + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Model::Model() +{ +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + mHull = null; +#endif // __MESHMERIZER_H__ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Model::~Model() +{ + Release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases the model. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Model::Release() +{ + ReleaseBase(); +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + DELETESINGLE(mHull); +#endif // __MESHMERIZER_H__ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Model::Build(const OPCODECREATE& create) +{ + // 1) Checkings + if(!create.mIMesh || !create.mIMesh->IsValid()) return false; + + // For this model, we only support complete trees + if(create.mSettings.mLimit!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null); + + // Look for degenerate faces. + udword NbDegenerate = create.mIMesh->CheckTopology(); + if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate); + // We continue nonetheless.... + + Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam] + + // 1-1) Setup mesh interface automatically [Opcode 1.3] + SetMeshInterface(create.mIMesh); + + // Special case for 1-triangle meshes [Opcode 1.3] + udword NbTris = create.mIMesh->GetNbTriangles(); + if(NbTris==1) + { + // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway. + // It's a waste to use a "model" for this but at least it will work. + mModelCode |= OPC_SINGLE_NODE; + return true; + } + + // 2) Build a generic AABB Tree. + mSource = new AABBTree; + CHECKALLOC(mSource); + + // 2-1) Setup a builder. Our primitives here are triangles from input mesh, + // so we use an AABBTreeOfTrianglesBuilder..... + { + AABBTreeOfTrianglesBuilder TB; + TB.mIMesh = create.mIMesh; + TB.mSettings = create.mSettings; + TB.mNbPrimitives = NbTris; + if(!mSource->Build(&TB)) return false; + } + + // 3) Create an optimized tree according to user-settings + if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false; + + // 3-2) Create optimized tree + if(!mTree->Build(mSource)) return false; + + // 3-3) Delete generic tree if needed + if(!create.mKeepOriginal) DELETESINGLE(mSource); + +#ifdef __MESHMERIZER_H__ + // 4) Convex hull + if(create.mCollisionHull) + { + // Create hull + mHull = new CollisionHull; + CHECKALLOC(mHull); + + CONVEXHULLCREATE CHC; + // ### doesn't work with strides + CHC.NbVerts = create.mIMesh->GetNbVertices(); + CHC.Vertices = create.mIMesh->GetVerts(); + CHC.UnifyNormals = true; + CHC.ReduceVertices = true; + CHC.WordFaces = false; + mHull->Compute(CHC); + } +#endif // __MESHMERIZER_H__ + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword Model::GetUsedBytes() const +{ + if(!mTree) return 0; + return mTree->GetUsedBytes(); +} diff --git a/Extras/CDTestFramework/Opcode/OPC_Model.h b/Extras/CDTestFramework/Opcode/OPC_Model.h new file mode 100644 index 0000000..0124135 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Model.h @@ -0,0 +1,74 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for OPCODE models. + * \file OPC_Model.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_MODEL_H__ +#define __OPC_MODEL_H__ + + class OPCODE_API Model : public BaseModel + { + public: + // Constructor/Destructor + Model(); + virtual ~Model(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Build(const OPCODECREATE& create); + +#ifdef __MESHMERIZER_H__ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the collision hull. + * \return the collision hull if it exists + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const CollisionHull* GetHull() const { return mHull; } +#endif // __MESHMERIZER_H__ + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) udword GetUsedBytes() const; + + private: +#ifdef __MESHMERIZER_H__ + CollisionHull* mHull; //!< Possible convex hull +#endif // __MESHMERIZER_H__ + // Internal methods + void Release(); + }; + +#endif //__OPC_MODEL_H__ \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/OPC_OBBCollider.cpp b/Extras/CDTestFramework/Opcode/OPC_OBBCollider.cpp new file mode 100644 index 0000000..9930240 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_OBBCollider.cpp @@ -0,0 +1,776 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an OBB collider. + * \file OPC_OBBCollider.cpp + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an OBB-vs-tree collider. + * + * \class OBBCollider + * \author Pierre Terdiman + * \version 1.3 + * \date January, 1st, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_BoxBoxOverlap.h" +#include "OPC_TriBoxOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(prim_index); + +//! OBB-triangle test +#define OBB_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \ + /* Transform them in a common space */ \ + TransformPoint(mLeafVerts[0], *VP.Vertex[0], mRModelToBox, mTModelToBox); \ + TransformPoint(mLeafVerts[1], *VP.Vertex[1], mRModelToBox, mTModelToBox); \ + TransformPoint(mLeafVerts[2], *VP.Vertex[2], mRModelToBox, mTModelToBox); \ + /* Perform triangle-box overlap test */ \ + if(TriBoxOverlap()) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +OBBCollider::OBBCollider() : mFullBoxBoxTest(true) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +OBBCollider::~OBBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings and callbacks have been defined. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* OBBCollider::ValidateSettings() +{ + if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; + + return VolumeCollider::ValidateSettings(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision OBB in local space + * \param model [in] Opcode model to collide with + * \param worldb [in] OBB's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBBCollider::Collide(OBBCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box, worldb, worldm)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * - check temporal coherence + * + * \param cache [in/out] a box cache + * \param box [in] obb in local space + * \param worldb [in] obb's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL OBBCollider::InitQuery(OBBCache& cache, const OBB& box, const Matrix4x4* worldb, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute obb in world space + mBoxExtents = box.mExtents; + + Matrix4x4 WorldB; + + if(worldb) + { + WorldB = Matrix4x4( box.mRot * Matrix3x3(*worldb) ); + WorldB.SetTrans(box.mCenter * *worldb); + } + else + { + WorldB = box.mRot; + WorldB.SetTrans(box.mCenter); + } + + // Setup matrices + Matrix4x4 InvWorldB; + InvertPRMatrix(InvWorldB, WorldB); + + if(worldm) + { + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + + Matrix4x4 WorldBtoM = WorldB * InvWorldM; + Matrix4x4 WorldMtoB = *worldm * InvWorldB; + + mRModelToBox = WorldMtoB; WorldMtoB.GetTrans(mTModelToBox); + mRBoxToModel = WorldBtoM; WorldBtoM.GetTrans(mTBoxToModel); + } + else + { + mRModelToBox = InvWorldB; InvWorldB.GetTrans(mTModelToBox); + mRBoxToModel = WorldB; WorldB.GetTrans(mTBoxToModel); + } + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the box (and set contact status if needed) + OBB_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence: + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the box (and set contact status if needed) + OBB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // ### rewrite this + OBB TestBox(mTBoxToModel, mBoxExtents, mRBoxToModel); + + // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious): + if(IsCacheValid(cache) && TestBox.IsInside(cache.FatBox)) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat box so that coherence will work for subsequent frames + TestBox.mExtents *= cache.FatCoeff; + mBoxExtents *= cache.FatCoeff; + + // Update cache with query data (signature for cached faces) + cache.FatBox = TestBox; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + // Now we can precompute box-box data + + // Precompute absolute box-to-model rotation matrix + for(udword i=0;i<3;i++) + { + for(udword j=0;j<3;j++) + { + // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID) + mAR.m[i][j] = 1e-6f + fabsf(mRBoxToModel.m[i][j]); + } + } + + // Precompute bounds for box-in-box test + mB0 = mBoxExtents - mTModelToBox; + mB1 = - mBoxExtents - mTModelToBox; + + // Precompute box-box data - Courtesy of Erwin de Vries + mBBx1 = mBoxExtents.x*mAR.m[0][0] + mBoxExtents.y*mAR.m[1][0] + mBoxExtents.z*mAR.m[2][0]; + mBBy1 = mBoxExtents.x*mAR.m[0][1] + mBoxExtents.y*mAR.m[1][1] + mBoxExtents.z*mAR.m[2][1]; + mBBz1 = mBoxExtents.x*mAR.m[0][2] + mBoxExtents.y*mAR.m[1][2] + mBoxExtents.z*mAR.m[2][2]; + + mBB_1 = mBoxExtents.y*mAR.m[2][0] + mBoxExtents.z*mAR.m[1][0]; + mBB_2 = mBoxExtents.x*mAR.m[2][0] + mBoxExtents.z*mAR.m[0][0]; + mBB_3 = mBoxExtents.x*mAR.m[1][0] + mBoxExtents.y*mAR.m[0][0]; + mBB_4 = mBoxExtents.y*mAR.m[2][1] + mBoxExtents.z*mAR.m[1][1]; + mBB_5 = mBoxExtents.x*mAR.m[2][1] + mBoxExtents.z*mAR.m[0][1]; + mBB_6 = mBoxExtents.x*mAR.m[1][1] + mBoxExtents.y*mAR.m[0][1]; + mBB_7 = mBoxExtents.y*mAR.m[2][2] + mBoxExtents.z*mAR.m[1][2]; + mBB_8 = mBoxExtents.x*mAR.m[2][2] + mBoxExtents.z*mAR.m[0][2]; + mBB_9 = mBoxExtents.x*mAR.m[1][2] + mBoxExtents.y*mAR.m[0][2]; + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the OBB completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the OBB contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL OBBCollider::OBBContainsBox(const Point& bc, const Point& be) +{ + // I assume if all 8 box vertices are inside the OBB, so does the whole box. + // Sounds ok but maybe there's a better way? +/* +#define TEST_PT(a,b,c) \ + p.x=a; p.y=b; p.z=c; p+=bc; \ + f = p.x * mRModelToBox.m[0][0] + p.y * mRModelToBox.m[1][0] + p.z * mRModelToBox.m[2][0]; if(f>mB0.x || fmB0.y || fmB0.z || f NCx-NEx) return FALSE; + + float NCy = bc.x * mRModelToBox.m[0][1] + bc.y * mRModelToBox.m[1][1] + bc.z * mRModelToBox.m[2][1]; + float NEy = fabsf(mRModelToBox.m[0][1] * be.x) + fabsf(mRModelToBox.m[1][1] * be.y) + fabsf(mRModelToBox.m[2][1] * be.z); + + if(mB0.y < NCy+NEy) return FALSE; + if(mB1.y > NCy-NEy) return FALSE; + + float NCz = bc.x * mRModelToBox.m[0][2] + bc.y * mRModelToBox.m[1][2] + bc.z * mRModelToBox.m[2][2]; + float NEz = fabsf(mRModelToBox.m[0][2] * be.x) + fabsf(mRModelToBox.m[1][2] * be.y) + fabsf(mRModelToBox.m[2][2] * be.z); + + if(mB0.z < NCz+NEz) return FALSE; + if(mB1.z > NCz-NEz) return FALSE; + + return TRUE; +} + +#define TEST_BOX_IN_OBB(center, extents) \ + if(OBBContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + OBB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->IsLeaf()) + { + OBB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridOBBCollider::HybridOBBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridOBBCollider::~HybridOBBCollider() +{ +} + +bool HybridOBBCollider::Collide(OBBCache& cache, const OBB& box, const HybridModel& model, const Matrix4x4* worldb, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box, worldb, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;imCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + OBB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + OBB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_OBBCollider.h b/Extras/CDTestFramework/Opcode/OPC_OBBCollider.h new file mode 100644 index 0000000..58272cd --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_OBBCollider.h @@ -0,0 +1,151 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an OBB collider. + * \file OPC_OBBCollider.h + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_OBBCOLLIDER_H__ +#define __OPC_OBBCOLLIDER_H__ + + struct OPCODE_API OBBCache : VolumeCache + { + OBBCache() : FatCoeff(1.1f) + { + FatBox.mCenter.Zero(); + FatBox.mExtents.Zero(); + FatBox.mRot.Identity(); + } + + // Cached faces signature + OBB FatBox; //!< Box used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< extents multiplier used to create a fat box + }; + + class OPCODE_API OBBCollider : public VolumeCollider + { + public: + // Constructor / Destructor + OBBCollider(); + virtual ~OBBCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision OBB in local space + * \param model [in] Opcode model to collide with + * \param worldb [in] OBB's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(OBBCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: select between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Precomputed data + Matrix3x3 mAR; //!< Absolute rotation matrix + Matrix3x3 mRModelToBox; //!< Rotation from model space to obb space + Matrix3x3 mRBoxToModel; //!< Rotation from obb space to model space + Point mTModelToBox; //!< Translation from model space to obb space + Point mTBoxToModel; //!< Translation from obb space to model space + + Point mBoxExtents; + Point mB0; //!< - mTModelToBox + mBoxExtents + Point mB1; //!< - mTModelToBox - mBoxExtents + + float mBBx1; + float mBBy1; + float mBBz1; + + float mBB_1; + float mBB_2; + float mBB_3; + float mBB_4; + float mBB_5; + float mBB_6; + float mBB_7; + float mBB_8; + float mBB_9; + + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + // Settings + bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL OBBContainsBox(const Point& bc, const Point& be); + inline_ BOOL BoxBoxOverlap(const Point& extents, const Point& center); + inline_ BOOL TriBoxOverlap(); + // Init methods + BOOL InitQuery(OBBCache& cache, const OBB& box, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridOBBCollider : public OBBCollider + { + public: + // Constructor / Destructor + HybridOBBCollider(); + virtual ~HybridOBBCollider(); + + bool Collide(OBBCache& cache, const OBB& box, const HybridModel& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_OBBCOLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_OptimizedTree.cpp b/Extras/CDTestFramework/Opcode/OPC_OptimizedTree.cpp new file mode 100644 index 0000000..59eb562 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_OptimizedTree.cpp @@ -0,0 +1,791 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for optimized trees. Implements 4 trees: + * - normal + * - no leaf + * - quantized + * - no leaf / quantized + * + * \file OPC_OptimizedTree.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A standard AABB tree. + * + * \class AABBCollisionTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A no-leaf AABB tree. + * + * \class AABBNoLeafTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A quantized AABB tree. + * + * \class AABBQuantizedTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A quantized no-leaf AABB tree. + * + * \class AABBQuantizedNoLeafTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +//! Compilation flag: +//! - true to fix quantized boxes (i.e. make sure they enclose the original ones) +//! - false to see the effects of quantization errors (faster, but wrong results in some cases) +static bool gFixQuantized = true; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds an implicit tree from a standard one. An implicit tree is a complete tree (2*N-1 nodes) whose negative + * box pointers and primitive pointers have been made implicit, hence packing 3 pointers in one. + * + * Layout for implicit trees: + * Node: + * - box + * - data (32-bits value) + * + * if data's LSB = 1 => remaining bits are a primitive pointer + * else remaining bits are a P-node pointer, and N = P + 1 + * + * \relates AABBCollisionNode + * \fn _BuildCollisionTree(AABBCollisionNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) + * \param linear [in] base address of destination nodes + * \param box_id [in] index of destination node + * \param current_id [in] current running index + * \param current_node [in] current node from input tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static void _BuildCollisionTree(AABBCollisionNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) +{ + // Current node from input tree is "current_node". Must be flattened into "linear[boxid]". + + // Store the AABB + current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter); + current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents); + // Store remaining info + if(current_node->IsLeaf()) + { + // The input tree must be complete => i.e. one primitive/leaf + ASSERT(current_node->GetNbPrimitives()==1); + // Get the primitive index from the input tree + udword PrimitiveIndex = current_node->GetPrimitives()[0]; + // Setup box data as the primitive index, marked as leaf + linear[box_id].mData = (PrimitiveIndex<<1)|1; + } + else + { + // To make the negative one implicit, we must store P and N in successive order + udword PosID = current_id++; // Get a new id for positive child + udword NegID = current_id++; // Get a new id for negative child + // Setup box data as the forthcoming new P pointer + linear[box_id].mData = (udword)&linear[PosID]; + // Make sure it's not marked as leaf + ASSERT(!(linear[box_id].mData&1)); + // Recurse with new IDs + _BuildCollisionTree(linear, PosID, current_id, current_node->GetPos()); + _BuildCollisionTree(linear, NegID, current_id, current_node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a "no-leaf" tree from a standard one. This is a tree whose leaf nodes have been removed. + * + * Layout for no-leaf trees: + * + * Node: + * - box + * - P pointer => a node (LSB=0) or a primitive (LSB=1) + * - N pointer => a node (LSB=0) or a primitive (LSB=1) + * + * \relates AABBNoLeafNode + * \fn _BuildNoLeafTree(AABBNoLeafNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) + * \param linear [in] base address of destination nodes + * \param box_id [in] index of destination node + * \param current_id [in] current running index + * \param current_node [in] current node from input tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static void _BuildNoLeafTree(AABBNoLeafNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) +{ + const AABBTreeNode* P = current_node->GetPos(); + const AABBTreeNode* N = current_node->GetNeg(); + // Leaf nodes here?! + ASSERT(P); + ASSERT(N); + // Internal node => keep the box + current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter); + current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents); + + if(P->IsLeaf()) + { + // The input tree must be complete => i.e. one primitive/leaf + ASSERT(P->GetNbPrimitives()==1); + // Get the primitive index from the input tree + udword PrimitiveIndex = P->GetPrimitives()[0]; + // Setup prev box data as the primitive index, marked as leaf + linear[box_id].mPosData = (PrimitiveIndex<<1)|1; + } + else + { + // Get a new id for positive child + udword PosID = current_id++; + // Setup box data + linear[box_id].mPosData = (udword)&linear[PosID]; + // Make sure it's not marked as leaf + ASSERT(!(linear[box_id].mPosData&1)); + // Recurse + _BuildNoLeafTree(linear, PosID, current_id, P); + } + + if(N->IsLeaf()) + { + // The input tree must be complete => i.e. one primitive/leaf + ASSERT(N->GetNbPrimitives()==1); + // Get the primitive index from the input tree + udword PrimitiveIndex = N->GetPrimitives()[0]; + // Setup prev box data as the primitive index, marked as leaf + linear[box_id].mNegData = (PrimitiveIndex<<1)|1; + } + else + { + // Get a new id for negative child + udword NegID = current_id++; + // Setup box data + linear[box_id].mNegData = (udword)&linear[NegID]; + // Make sure it's not marked as leaf + ASSERT(!(linear[box_id].mNegData&1)); + // Recurse + _BuildNoLeafTree(linear, NegID, current_id, N); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollisionTree::AABBCollisionTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollisionTree::~AABBCollisionTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollisionTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbNodes = tree->GetNbNodes(); + if(NbNodes!=NbTriangles*2-1) return false; + + // Get nodes + if(mNbNodes!=NbNodes) // Same number of nodes => keep moving + { + mNbNodes = NbNodes; + DELETEARRAY(mNodes); + mNodes = new AABBCollisionNode[mNbNodes]; + CHECKALLOC(mNodes); + } + + // Build the tree + udword CurID = 1; + _BuildCollisionTree(mNodes, 0, CurID, tree); + ASSERT(CurID==mNbNodes); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollisionTree::Refit(const MeshInterface* mesh_interface) +{ + ASSERT(!"Not implemented since AABBCollisionTrees have twice as more nodes to refit as AABBNoLeafTrees!"); + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollisionTree::Walk(GenericWalkingCallback callback, void* user_data) const +{ + if(!callback) return false; + + struct Local + { + static void _Walk(const AABBCollisionNode* current_node, GenericWalkingCallback callback, void* user_data) + { + if(!current_node || !(callback)(current_node, user_data)) return; + + if(!current_node->IsLeaf()) + { + _Walk(current_node->GetPos(), callback, user_data); + _Walk(current_node->GetNeg(), callback, user_data); + } + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBNoLeafTree::AABBNoLeafTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBNoLeafTree::~AABBNoLeafTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBNoLeafTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbNodes = tree->GetNbNodes(); + if(NbNodes!=NbTriangles*2-1) return false; + + // Get nodes + if(mNbNodes!=NbTriangles-1) // Same number of nodes => keep moving + { + mNbNodes = NbTriangles-1; + DELETEARRAY(mNodes); + mNodes = new AABBNoLeafNode[mNbNodes]; + CHECKALLOC(mNodes); + } + + // Build the tree + udword CurID = 1; + _BuildNoLeafTree(mNodes, 0, CurID, tree); + ASSERT(CurID==mNbNodes); + + return true; +} + +inline_ void ComputeMinMax_OT(Point& min, Point& max, const VertexPointers& vp) +{ + // Compute triangle's AABB = a leaf box +#ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much + min.x = FCMin3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + max.x = FCMax3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + + min.y = FCMin3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + max.y = FCMax3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + + min.z = FCMin3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); + max.z = FCMax3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); +#else + min = *vp.Vertex[0]; + max = *vp.Vertex[0]; + min.Min(*vp.Vertex[1]); + max.Max(*vp.Vertex[1]); + min.Min(*vp.Vertex[2]); + max.Max(*vp.Vertex[2]); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBNoLeafTree::Refit(const MeshInterface* mesh_interface) +{ + // Checkings + if(!mesh_interface) return false; + + // Bottom-up update + VertexPointers VP; + Point Min,Max; + Point Min_,Max_; + udword Index = mNbNodes; + while(Index--) + { + AABBNoLeafNode& Current = mNodes[Index]; + + if(Current.HasPosLeaf()) + { + mesh_interface->GetTriangle(VP, Current.GetPosPrimitive()); + ComputeMinMax_OT(Min, Max, VP); + } + else + { + const CollisionAABB& CurrentBox = Current.GetPos()->mAABB; + CurrentBox.GetMin(Min); + CurrentBox.GetMax(Max); + } + + if(Current.HasNegLeaf()) + { + mesh_interface->GetTriangle(VP, Current.GetNegPrimitive()); + ComputeMinMax_OT(Min_, Max_, VP); + } + else + { + const CollisionAABB& CurrentBox = Current.GetNeg()->mAABB; + CurrentBox.GetMin(Min_); + CurrentBox.GetMax(Max_); + } +#ifdef OPC_USE_FCOMI + Min.x = FCMin2(Min.x, Min_.x); + Max.x = FCMax2(Max.x, Max_.x); + Min.y = FCMin2(Min.y, Min_.y); + Max.y = FCMax2(Max.y, Max_.y); + Min.z = FCMin2(Min.z, Min_.z); + Max.z = FCMax2(Max.z, Max_.z); +#else + Min.Min(Min_); + Max.Max(Max_); +#endif + Current.mAABB.SetMinMax(Min, Max); + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBNoLeafTree::Walk(GenericWalkingCallback callback, void* user_data) const +{ + if(!callback) return false; + + struct Local + { + static void _Walk(const AABBNoLeafNode* current_node, GenericWalkingCallback callback, void* user_data) + { + if(!current_node || !(callback)(current_node, user_data)) return; + + if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data); + if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data); + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} + +// Quantization notes: +// - We could use the highest bits of mData to store some more quantized bits. Dequantization code +// would be slightly more complex, but number of overlap tests would be reduced (and anyhow those +// bits are currently wasted). Of course it's not possible if we move to 16 bits mData. +// - Something like "16 bits floats" could be tested, to bypass the int-to-float conversion. +// - A dedicated BV-BV test could be used, dequantizing while testing for overlap. (i.e. it's some +// lazy-dequantization which may save some work in case of early exits). At the very least some +// muls could be saved by precomputing several more matrices. But maybe not worth the pain. +// - Do we need to dequantize anyway? Not doing the extents-related muls only implies the box has +// been scaled, for example. +// - The deeper we move into the hierarchy, the smaller the extents should be. May not need a fixed +// number of quantization bits. Even better, could probably be best delta-encoded. + + +// Find max values. Some people asked why I wasn't simply using the first node. Well, I can't. +// I'm not looking for (min, max) values like in a standard AABB, I'm looking for the extremal +// centers/extents in order to quantize them. The first node would only give a single center and +// a single extents. While extents would be the biggest, the center wouldn't. +#define FIND_MAX_VALUES \ + /* Get max values */ \ + Point CMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ + Point EMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ + for(udword i=0;iCMax.x) CMax.x = fabsf(Nodes[i].mAABB.mCenter.x); \ + if(fabsf(Nodes[i].mAABB.mCenter.y)>CMax.y) CMax.y = fabsf(Nodes[i].mAABB.mCenter.y); \ + if(fabsf(Nodes[i].mAABB.mCenter.z)>CMax.z) CMax.z = fabsf(Nodes[i].mAABB.mCenter.z); \ + if(fabsf(Nodes[i].mAABB.mExtents.x)>EMax.x) EMax.x = fabsf(Nodes[i].mAABB.mExtents.x); \ + if(fabsf(Nodes[i].mAABB.mExtents.y)>EMax.y) EMax.y = fabsf(Nodes[i].mAABB.mExtents.y); \ + if(fabsf(Nodes[i].mAABB.mExtents.z)>EMax.z) EMax.z = fabsf(Nodes[i].mAABB.mExtents.z); \ + } + +#define INIT_QUANTIZATION \ + udword nbc=15; /* Keep one bit for sign */ \ + udword nbe=15; /* Keep one bit for fix */ \ + if(!gFixQuantized) nbe++; \ + \ + /* Compute quantization coeffs */ \ + Point CQuantCoeff, EQuantCoeff; \ + CQuantCoeff.x = CMax.x!=0.0f ? float((1<Min[j]) mNodes[i].mAABB.mExtents[j]++; \ + else FixMe=false; \ + /* Prevent wrapping */ \ + if(!mNodes[i].mAABB.mExtents[j]) \ + { \ + mNodes[i].mAABB.mExtents[j]=0xffff; \ + FixMe=false; \ + } \ + }while(FixMe); \ + } \ + } + +#define REMAP_DATA(member) \ + /* Fix data */ \ + Data = Nodes[i].member; \ + if(!(Data&1)) \ + { \ + /* Compute box number */ \ + udword Nb = (Data - udword(Nodes))/Nodes[i].GetNodeSize(); \ + Data = udword(&mNodes[Nb]); \ + } \ + /* ...remapped */ \ + mNodes[i].member = Data; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedTree::AABBQuantizedTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedTree::~AABBQuantizedTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbNodes = tree->GetNbNodes(); + if(NbNodes!=NbTriangles*2-1) return false; + + // Get nodes + mNbNodes = NbNodes; + DELETEARRAY(mNodes); + AABBCollisionNode* Nodes = new AABBCollisionNode[mNbNodes]; + CHECKALLOC(Nodes); + + // Build the tree + udword CurID = 1; + _BuildCollisionTree(Nodes, 0, CurID, tree); + + // Quantize + { + mNodes = new AABBQuantizedNode[mNbNodes]; + CHECKALLOC(mNodes); + + // Get max values + FIND_MAX_VALUES + + // Quantization + INIT_QUANTIZATION + + // Quantize + udword Data; + for(udword i=0;iIsLeaf()) + { + _Walk(current_node->GetPos(), callback, user_data); + _Walk(current_node->GetNeg(), callback, user_data); + } + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedNoLeafTree::AABBQuantizedNoLeafTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedNoLeafTree::~AABBQuantizedNoLeafTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedNoLeafTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbNodes = tree->GetNbNodes(); + if(NbNodes!=NbTriangles*2-1) return false; + + // Get nodes + mNbNodes = NbTriangles-1; + DELETEARRAY(mNodes); + AABBNoLeafNode* Nodes = new AABBNoLeafNode[mNbNodes]; + CHECKALLOC(Nodes); + + // Build the tree + udword CurID = 1; + _BuildNoLeafTree(Nodes, 0, CurID, tree); + ASSERT(CurID==mNbNodes); + + // Quantize + { + mNodes = new AABBQuantizedNoLeafNode[mNbNodes]; + CHECKALLOC(mNodes); + + // Get max values + FIND_MAX_VALUES + + // Quantization + INIT_QUANTIZATION + + // Quantize + udword Data; + for(udword i=0;iHasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data); + if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data); + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_OptimizedTree.h b/Extras/CDTestFramework/Opcode/OPC_OptimizedTree.h new file mode 100644 index 0000000..e25db74 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_OptimizedTree.h @@ -0,0 +1,215 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for optimized trees. + * \file OPC_OptimizedTree.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_OPTIMIZEDTREE_H__ +#define __OPC_OPTIMIZEDTREE_H__ + + //! Common interface for a node of an implicit tree + #define IMPLEMENT_IMPLICIT_NODE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + inline_ base_class() : mData(0) {} \ + inline_ ~base_class() {} \ + /* Leaf test */ \ + inline_ BOOL IsLeaf() const { return mData&1; } \ + /* Data access */ \ + inline_ const base_class* GetPos() const { return (base_class*)mData; } \ + inline_ const base_class* GetNeg() const { return ((base_class*)mData)+1; } \ + inline_ udword GetPrimitive() const { return (mData>>1); } \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + \ + volume mAABB; \ + udword mData; + + //! Common interface for a node of a no-leaf tree + #define IMPLEMENT_NOLEAF_NODE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + inline_ base_class() : mPosData(0), mNegData(0) {} \ + inline_ ~base_class() {} \ + /* Leaf tests */ \ + inline_ BOOL HasPosLeaf() const { return mPosData&1; } \ + inline_ BOOL HasNegLeaf() const { return mNegData&1; } \ + /* Data access */ \ + inline_ const base_class* GetPos() const { return (base_class*)mPosData; } \ + inline_ const base_class* GetNeg() const { return (base_class*)mNegData; } \ + inline_ udword GetPosPrimitive() const { return (mPosData>>1); } \ + inline_ udword GetNegPrimitive() const { return (mNegData>>1); } \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + \ + volume mAABB; \ + udword mPosData; \ + udword mNegData; + + class OPCODE_API AABBCollisionNode + { + IMPLEMENT_IMPLICIT_NODE(AABBCollisionNode, CollisionAABB) + + inline_ float GetVolume() const { return mAABB.mExtents.x * mAABB.mExtents.y * mAABB.mExtents.z; } + inline_ float GetSize() const { return mAABB.mExtents.SquareMagnitude(); } + inline_ udword GetRadius() const + { + udword* Bits = (udword*)&mAABB.mExtents.x; + udword Max = Bits[0]; + if(Bits[1]>Max) Max = Bits[1]; + if(Bits[2]>Max) Max = Bits[2]; + return Max; + } + + // NB: using the square-magnitude or the true volume of the box, seems to yield better results + // (assuming UNC-like informed traversal methods). I borrowed this idea from PQP. The usual "size" + // otherwise, is the largest box extent. In SOLID that extent is computed on-the-fly each time it's + // needed (the best approach IMHO). In RAPID the rotation matrix is permuted so that Extent[0] is + // always the greatest, which saves looking for it at runtime. On the other hand, it yields matrices + // whose determinant is not 1, i.e. you can't encode them anymore as unit quaternions. Not a very + // good strategy. + }; + + class OPCODE_API AABBQuantizedNode + { + IMPLEMENT_IMPLICIT_NODE(AABBQuantizedNode, QuantizedAABB) + + inline_ uword GetSize() const + { + const uword* Bits = mAABB.mExtents; + uword Max = Bits[0]; + if(Bits[1]>Max) Max = Bits[1]; + if(Bits[2]>Max) Max = Bits[2]; + return Max; + } + // NB: for quantized nodes I don't feel like computing a square-magnitude with integers all + // over the place.......! + }; + + class OPCODE_API AABBNoLeafNode + { + IMPLEMENT_NOLEAF_NODE(AABBNoLeafNode, CollisionAABB) + }; + + class OPCODE_API AABBQuantizedNoLeafNode + { + IMPLEMENT_NOLEAF_NODE(AABBQuantizedNoLeafNode, QuantizedAABB) + }; + + //! Common interface for a collision tree + #define IMPLEMENT_COLLISION_TREE(base_class, node) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + virtual ~base_class(); \ + /* Builds from a standard tree */ \ + override(AABBOptimizedTree) bool Build(AABBTree* tree); \ + /* Refits the tree */ \ + override(AABBOptimizedTree) bool Refit(const MeshInterface* mesh_interface); \ + /* Walks the tree */ \ + override(AABBOptimizedTree) bool Walk(GenericWalkingCallback callback, void* user_data) const; \ + /* Data access */ \ + inline_ const node* GetNodes() const { return mNodes; } \ + /* Stats */ \ + override(AABBOptimizedTree) udword GetUsedBytes() const { return mNbNodes*sizeof(node); } \ + private: \ + node* mNodes; + + typedef bool (*GenericWalkingCallback) (const void* current, void* user_data); + + class OPCODE_API AABBOptimizedTree + { + public: + // Constructor / Destructor + AABBOptimizedTree() : + mNbNodes (0) + {} + virtual ~AABBOptimizedTree() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Build(AABBTree* tree) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Refit(const MeshInterface* mesh_interface) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Walk(GenericWalkingCallback callback, void* user_data) const = 0; + + // Data access + virtual udword GetUsedBytes() const = 0; + inline_ udword GetNbNodes() const { return mNbNodes; } + + protected: + udword mNbNodes; + }; + + class OPCODE_API AABBCollisionTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBCollisionTree, AABBCollisionNode) + }; + + class OPCODE_API AABBNoLeafTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBNoLeafTree, AABBNoLeafNode) + }; + + class OPCODE_API AABBQuantizedTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBQuantizedTree, AABBQuantizedNode) + + public: + Point mCenterCoeff; + Point mExtentsCoeff; + }; + + class OPCODE_API AABBQuantizedNoLeafTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBQuantizedNoLeafTree, AABBQuantizedNoLeafNode) + + public: + Point mCenterCoeff; + Point mExtentsCoeff; + }; + +#endif // __OPC_OPTIMIZEDTREE_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_Picking.cpp b/Extras/CDTestFramework/Opcode/OPC_Picking.cpp new file mode 100644 index 0000000..02a9ed7 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Picking.cpp @@ -0,0 +1,191 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to perform "picking". + * \file OPC_Picking.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#ifdef OPC_RAYHIT_CALLBACK + +/* + Possible RayCollider usages: + - boolean query (shadow feeler) + - closest hit + - all hits + - number of intersection (boolean) + +*/ + +bool Opcode::SetupAllHits(RayCollider& collider, CollisionFaces& contacts) +{ + struct Local + { + static void AllContacts(const CollisionFace& hit, void* user_data) + { + CollisionFaces* CF = (CollisionFaces*)user_data; + CF->AddFace(hit); + } + }; + + collider.SetFirstContact(false); + collider.SetHitCallback(Local::AllContacts); + collider.SetUserData(&contacts); + return true; +} + +bool Opcode::SetupClosestHit(RayCollider& collider, CollisionFace& closest_contact) +{ + struct Local + { + static void ClosestContact(const CollisionFace& hit, void* user_data) + { + CollisionFace* CF = (CollisionFace*)user_data; + if(hit.mDistancemDistance) *CF = hit; + } + }; + + collider.SetFirstContact(false); + collider.SetHitCallback(Local::ClosestContact); + collider.SetUserData(&closest_contact); + closest_contact.mDistance = MAX_FLOAT; + return true; +} + +bool Opcode::SetupShadowFeeler(RayCollider& collider) +{ + collider.SetFirstContact(true); + collider.SetHitCallback(null); + return true; +} + +bool Opcode::SetupInOutTest(RayCollider& collider) +{ + collider.SetFirstContact(false); + collider.SetHitCallback(null); + // Results with collider.GetNbIntersections() + return true; +} + +bool Opcode::Picking( +CollisionFace& picked_face, +const Ray& world_ray, const Model& model, const Matrix4x4* world, +float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data) +{ + struct Local + { + struct CullData + { + CollisionFace* Closest; + float MinLimit; + CullModeCallback Callback; + void* UserData; + Point ViewPoint; + const MeshInterface* IMesh; + }; + + // Called for each stabbed face + static void RenderCullingCallback(const CollisionFace& hit, void* user_data) + { + CullData* Data = (CullData*)user_data; + + // Discard face if we already have a closer hit + if(hit.mDistance>=Data->Closest->mDistance) return; + + // Discard face if hit point is smaller than min limit. This mainly happens when the face is in front + // of the near clip plane (or straddles it). If we keep the face nonetheless, the user can select an + // object that he may not even be able to see, which is very annoying. + if(hit.mDistance<=Data->MinLimit) return; + + // This is the index of currently stabbed triangle. + udword StabbedFaceIndex = hit.mFaceID; + + // We may keep it or not, depending on backface culling + bool KeepIt = true; + + // Catch *render* cull mode for this face + CullMode CM = (Data->Callback)(StabbedFaceIndex, Data->UserData); + + if(CM!=CULLMODE_NONE) // Don't even compute culling for double-sided triangles + { + // Compute backface culling for current face + + VertexPointers VP; + Data->IMesh->GetTriangle(VP, StabbedFaceIndex); + if(VP.BackfaceCulling(Data->ViewPoint)) + { + if(CM==CULLMODE_CW) KeepIt = false; + } + else + { + if(CM==CULLMODE_CCW) KeepIt = false; + } + } + + if(KeepIt) *Data->Closest = hit; + } + }; + + RayCollider RC; + RC.SetMaxDist(max_dist); + RC.SetTemporalCoherence(false); + RC.SetCulling(false); // We need all faces since some of them can be double-sided + RC.SetFirstContact(false); + RC.SetHitCallback(Local::RenderCullingCallback); + + picked_face.mFaceID = INVALID_ID; + picked_face.mDistance = MAX_FLOAT; + picked_face.mU = 0.0f; + picked_face.mV = 0.0f; + + Local::CullData Data; + Data.Closest = &picked_face; + Data.MinLimit = min_dist; + Data.Callback = callback; + Data.UserData = user_data; + Data.ViewPoint = view_point; + Data.IMesh = model.GetMeshInterface(); + + if(world) + { + // Get matrices + Matrix4x4 InvWorld; + InvertPRMatrix(InvWorld, *world); + + // Compute camera position in mesh space + Data.ViewPoint *= InvWorld; + } + + RC.SetUserData(&Data); + if(RC.Collide(world_ray, model, world)) + { + return picked_face.mFaceID!=INVALID_ID; + } + return false; +} + +#endif diff --git a/Extras/CDTestFramework/Opcode/OPC_Picking.h b/Extras/CDTestFramework/Opcode/OPC_Picking.h new file mode 100644 index 0000000..5c69f5d --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Picking.h @@ -0,0 +1,54 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to perform "picking". + * \file OPC_Picking.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_PICKING_H__ +#define __OPC_PICKING_H__ + +#ifdef OPC_RAYHIT_CALLBACK + + enum CullMode + { + CULLMODE_NONE = 0, + CULLMODE_CW = 1, + CULLMODE_CCW = 2 + }; + + typedef CullMode (*CullModeCallback)(udword triangle_index, void* user_data); + + OPCODE_API bool SetupAllHits (RayCollider& collider, CollisionFaces& contacts); + OPCODE_API bool SetupClosestHit (RayCollider& collider, CollisionFace& closest_contact); + OPCODE_API bool SetupShadowFeeler (RayCollider& collider); + OPCODE_API bool SetupInOutTest (RayCollider& collider); + + OPCODE_API bool Picking( + CollisionFace& picked_face, + const Ray& world_ray, const Model& model, const Matrix4x4* world, + float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data); +#endif + +#endif //__OPC_PICKING_H__ \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/OPC_PlanesAABBOverlap.h b/Extras/CDTestFramework/Opcode/OPC_PlanesAABBOverlap.h new file mode 100644 index 0000000..21ab91c --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_PlanesAABBOverlap.h @@ -0,0 +1,67 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Planes-AABB overlap test. + * - original code by Ville Miettinen, from Umbra/dPVS (released on the GD-Algorithms mailing list) + * - almost used "as-is", I even left the comments (hence the frustum-related notes) + * + * \param center [in] box center + * \param extents [in] box extents + * \param out_clip_mask [out] bitmask for active planes + * \param in_clip_mask [in] bitmask for active planes + * \return TRUE if boxes overlap planes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL PlanesCollider::PlanesAABBOverlap(const Point& center, const Point& extents, udword& out_clip_mask, udword in_clip_mask) +{ + // Stats + mNbVolumeBVTests++; + + const Plane* p = mPlanes; + + // Evaluate through all active frustum planes. We determine the relation + // between the AABB and a plane by using the concept of "near" and "far" + // vertices originally described by Zhang (and later by Möller). Our + // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point + // comparisons per plane. The routine early-exits if the AABB is found + // to be outside any of the planes. The loop also constructs a new output + // clip mask. Most FPUs have a native single-cycle fabsf() operation. + + udword Mask = 1; // current mask index (1,2,4,8,..) + udword TmpOutClipMask = 0; // initialize output clip mask into empty. + + while(Mask<=in_clip_mask) // keep looping while we have active planes left... + { + if(in_clip_mask & Mask) // if clip plane is active, process it.. + { + float NP = extents.x*fabsf(p->n.x) + extents.y*fabsf(p->n.y) + extents.z*fabsf(p->n.z); // ### fabsf could be precomputed + float MP = center.x*p->n.x + center.y*p->n.y + center.z*p->n.z + p->d; + + if(NP < MP) // near vertex behind the clip plane... + return FALSE; // .. so there is no intersection.. + if((-NP) < MP) // near and far vertices on different sides of plane.. + TmpOutClipMask |= Mask; // .. so update the clip mask... + } + Mask+=Mask; // mk = (1<Add(prim_index); + +//! Planes-triangle test +#define PLANES_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + mIMesh->GetTriangle(mVP, prim_index); \ + /* Perform triangle-box overlap test */ \ + if(PlanesTriOverlap(clip_mask)) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +PlanesCollider::PlanesCollider() : + mPlanes (null), + mNbPlanes (0) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +PlanesCollider::~PlanesCollider() +{ + DELETEARRAY(mPlanes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings and callbacks have been defined. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* PlanesCollider::ValidateSettings() +{ + if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; + + return VolumeCollider::ValidateSettings(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a planes cache + * \param planes [in] list of planes in world space + * \param nb_planes [in] number of planes + * \param model [in] Opcode model to collide with + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool PlanesCollider::Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const Model& model, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, planes, nb_planes, worldm)) return true; + + udword PlaneMask = (1<mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - compute planes in model space + * - check temporal coherence + * + * \param cache [in/out] a planes cache + * \param planes [in] list of planes + * \param nb_planes [in] number of planes + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrix must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL PlanesCollider::InitQuery(PlanesCache& cache, const Plane* planes, udword nb_planes, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute planes in model space + if(nb_planes>mNbPlanes) + { + DELETEARRAY(mPlanes); + mPlanes = new Plane[nb_planes]; + } + mNbPlanes = nb_planes; + + if(worldm) + { + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + +// for(udword i=0;iHasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the planes (and set contact status if needed) + udword clip_mask = (1< check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the planes (and set contact status if needed) + udword clip_mask = (1< we'll have to perform a normal query + } + else mTouchedPrimitives->Reset(); + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + return FALSE; +} + +#define TEST_CLIP_MASK \ + /* If the box is completely included, so are its children. We don't need to do extra tests, we */ \ + /* can immediately output a list of visible children. Those ones won't need to be clipped. */ \ + if(!OutClipMask) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBCollisionNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _Collide(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBQuantizedNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _Collide(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBNoLeafNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg(), OutClipMask); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBQuantizedNoLeafNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg(), OutClipMask); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); +} + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridPlanesCollider::HybridPlanesCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridPlanesCollider::~HybridPlanesCollider() +{ +} + +bool HybridPlanesCollider::Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const HybridModel& model, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, planes, nb_planes, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + udword clip_mask = (1<mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + udword clip_mask = (1<Distance(*mVP.Vertex[0]); + float d1 = p->Distance(*mVP.Vertex[1]); + float d2 = p->Distance(*mVP.Vertex[2]); + if(d0>0.0f && d1>0.0f && d2>0.0f) return FALSE; +// if(!(IR(d0)&SIGN_BITMASK) && !(IR(d1)&SIGN_BITMASK) && !(IR(d2)&SIGN_BITMASK)) return FALSE; + } + Mask+=Mask; + p++; + } +/* + for(udword i=0;i<6;i++) + { + float d0 = p[i].Distance(mLeafVerts[0]); + float d1 = p[i].Distance(mLeafVerts[1]); + float d2 = p[i].Distance(mLeafVerts[2]); + if(d0>0.0f && d1>0.0f && d2>0.0f) return false; + } +*/ + return TRUE; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_RayAABBOverlap.h b/Extras/CDTestFramework/Opcode/OPC_RayAABBOverlap.h new file mode 100644 index 0000000..0d2639c --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_RayAABBOverlap.h @@ -0,0 +1,81 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +// Opcode 1.1: ray-AABB overlap tests based on Woo's code +// Opcode 1.2: ray-AABB overlap tests based on the separating axis theorem +// +// The point of intersection is not computed anymore. The distance to impact is not needed anymore +// since we now have two different queries for segments or rays. + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a segment-AABB overlap test using the separating axis theorem. Segment is cached within the class. + * \param center [in] AABB center + * \param extents [in] AABB extents + * \return true on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::SegmentAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbRayBVTests++; + + float Dx = mData2.x - center.x; if(fabsf(Dx) > extents.x + mFDir.x) return FALSE; + float Dy = mData2.y - center.y; if(fabsf(Dy) > extents.y + mFDir.y) return FALSE; + float Dz = mData2.z - center.z; if(fabsf(Dz) > extents.z + mFDir.z) return FALSE; + + float f; + f = mData.y * Dz - mData.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; + f = mData.z * Dx - mData.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; + f = mData.x * Dy - mData.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a ray-AABB overlap test using the separating axis theorem. Ray is cached within the class. + * \param center [in] AABB center + * \param extents [in] AABB extents + * \return true on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::RayAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbRayBVTests++; + +// float Dx = mOrigin.x - center.x; if(fabsf(Dx) > extents.x && Dx*mDir.x>=0.0f) return FALSE; +// float Dy = mOrigin.y - center.y; if(fabsf(Dy) > extents.y && Dy*mDir.y>=0.0f) return FALSE; +// float Dz = mOrigin.z - center.z; if(fabsf(Dz) > extents.z && Dz*mDir.z>=0.0f) return FALSE; + + float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && Dx*mDir.x>=0.0f) return FALSE; + float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && Dy*mDir.y>=0.0f) return FALSE; + float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && Dz*mDir.z>=0.0f) return FALSE; + +// float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && ((SIR(Dx)-1)^SIR(mDir.x))>=0.0f) return FALSE; +// float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && ((SIR(Dy)-1)^SIR(mDir.y))>=0.0f) return FALSE; +// float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && ((SIR(Dz)-1)^SIR(mDir.z))>=0.0f) return FALSE; + + float f; + f = mDir.y * Dz - mDir.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; + f = mDir.z * Dx - mDir.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; + f = mDir.x * Dy - mDir.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; + + return TRUE; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_RayCollider.cpp b/Extras/CDTestFramework/Opcode/OPC_RayCollider.cpp new file mode 100644 index 0000000..07ceb32 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_RayCollider.cpp @@ -0,0 +1,771 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a ray collider. + * \file OPC_RayCollider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a ray-vs-tree collider. + * This class performs a stabbing query on an AABB tree, i.e. does a ray-mesh collision. + * + * HIGHER DISTANCE BOUND: + * + * If P0 and P1 are two 3D points, let's define: + * - d = distance between P0 and P1 + * - Origin = P0 + * - Direction = (P1 - P0) / d = normalized direction vector + * - A parameter t such as a point P on the line (P0,P1) is P = Origin + t * Direction + * - t = 0 --> P = P0 + * - t = d --> P = P1 + * + * Then we can define a general "ray" as: + * + * struct Ray + * { + * Point Origin; + * Point Direction; + * }; + * + * But it actually maps three different things: + * - a segment, when 0 <= t <= d + * - a half-line, when 0 <= t < +infinity, or -infinity < t <= d + * - a line, when -infinity < t < +infinity + * + * In Opcode, we support segment queries, which yield half-line queries by setting d = +infinity. + * We don't support line-queries. If you need them, shift the origin along the ray by an appropriate margin. + * + * In short, the lower bound is always 0, and you can setup the higher bound "d" with RayCollider::SetMaxDist(). + * + * Query |segment |half-line |line + * --------|-------------------|---------------|---------------- + * Usages |-shadow feelers |-raytracing |- + * |-sweep tests |-in/out tests | + * + * FIRST CONTACT: + * + * - You can setup "first contact" mode or "all contacts" mode with RayCollider::SetFirstContact(). + * - In "first contact" mode we return as soon as the ray hits one face. If can be useful e.g. for shadow feelers, where + * you want to know whether the path to the light is free or not (a boolean answer is enough). + * - In "all contacts" mode we return all faces hit by the ray. + * + * TEMPORAL COHERENCE: + * + * - You can enable or disable temporal coherence with RayCollider::SetTemporalCoherence(). + * - It currently only works in "first contact" mode. + * - If temporal coherence is enabled, the previously hit triangle is cached during the first query. Then, next queries + * start by colliding the ray against the cached triangle. If they still collide, we return immediately. + * + * CLOSEST HIT: + * + * - You can enable or disable "closest hit" with RayCollider::SetClosestHit(). + * - It currently only works in "all contacts" mode. + * - If closest hit is enabled, faces are sorted by distance on-the-fly and the closest one only is reported. + * + * BACKFACE CULLING: + * + * - You can enable or disable backface culling with RayCollider::SetCulling(). + * - If culling is enabled, ray will not hit back faces (only front faces). + * + * + * + * \class RayCollider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * This class describes a face hit by a ray or segment. + * This is a particular class dedicated to stabbing queries. + * + * \class CollisionFace + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * This class is a dedicated collection of CollisionFace. + * + * \class CollisionFaces + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_RayAABBOverlap.h" +#include "OPC_RayTriOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + mNbIntersections++; \ + /* Set contact status */ \ + mFlags |= flag; \ + /* In any case the contact has been found and recorded in mStabbedFace */ \ + mStabbedFace.mFaceID = prim_index; + +#ifdef OPC_RAYHIT_CALLBACK + + #define HANDLE_CONTACT(prim_index, flag) \ + SET_CONTACT(prim_index, flag) \ + \ + if(mHitCallback) (mHitCallback)(mStabbedFace, mUserData); + + #define UPDATE_CACHE \ + if(cache && GetContactStatus()) \ + { \ + *cache = mStabbedFace.mFaceID; \ + } +#else + + #define HANDLE_CONTACT(prim_index, flag) \ + SET_CONTACT(prim_index, flag) \ + \ + /* Now we can also record it in mStabbedFaces if available */ \ + if(mStabbedFaces) \ + { \ + /* If we want all faces or if that's the first one we hit */ \ + if(!mClosestHit || !mStabbedFaces->GetNbFaces()) \ + { \ + mStabbedFaces->AddFace(mStabbedFace); \ + } \ + else \ + { \ + /* We only keep closest hit */ \ + CollisionFace* Current = const_cast(mStabbedFaces->GetFaces()); \ + if(Current && mStabbedFace.mDistancemDistance) \ + { \ + *Current = mStabbedFace; \ + } \ + } \ + } + + #define UPDATE_CACHE \ + if(cache && GetContactStatus() && mStabbedFaces) \ + { \ + const CollisionFace* Current = mStabbedFaces->GetFaces(); \ + if(Current) *cache = Current->mFaceID; \ + else *cache = INVALID_ID; \ + } +#endif + +#define SEGMENT_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \ + \ + /* Perform ray-tri overlap test and return */ \ + if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + /* Intersection point is valid if dist < segment's length */ \ + /* We know dist>0 so we can use integers */ \ + if(IR(mStabbedFace.mDistance)GetTriangle(VP, prim_index); \ + \ + /* Perform ray-tri overlap test and return */ \ + if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + HANDLE_CONTACT(prim_index, flag) \ + } + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RayCollider::RayCollider() : + mNbRayBVTests (0), + mNbRayPrimTests (0), + mNbIntersections (0), + mCulling (true), +#ifdef OPC_RAYHIT_CALLBACK + mHitCallback (null), + mUserData (0), +#else + mClosestHit (false), + mStabbedFaces (null), +#endif + mMaxDist (MAX_FLOAT) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RayCollider::~RayCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings and callbacks have been defined. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* RayCollider::ValidateSettings() +{ + if(mMaxDist<0.0f) return "Higher distance bound must be positive!"; + if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; +#ifndef OPC_RAYHIT_CALLBACK + if(mClosestHit && FirstContactEnabled()) return "Closest hit doesn't work with ""First contact"" mode!"; + if(TemporalCoherenceEnabled() && mClosestHit) return "Temporal coherence can't guarantee to report closest hit!"; +#endif + if(SkipPrimitiveTests()) return "SkipPrimitiveTests not possible for RayCollider ! (not implemented)"; + return null; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic stabbing query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - in the user-provided destination array + * + * \param world_ray [in] stabbing ray in world space + * \param model [in] Opcode model to collide with + * \param world [in] model's world matrix, or null + * \param cache [in] a possibly cached face index, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool RayCollider::Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world, udword* cache) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(world_ray, world, cache)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + } + + // Update cache if needed + UPDATE_CACHE + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a stabbing query : + * - reset stats & contact status + * - compute ray in local space + * - check temporal coherence + * + * \param world_ray [in] stabbing ray in world space + * \param world [in] object's world matrix, or null + * \param face_id [in] index of previously stabbed triangle + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrix must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL RayCollider::InitQuery(const Ray& world_ray, const Matrix4x4* world, udword* face_id) +{ + // Reset stats & contact status + Collider::InitQuery(); + mNbRayBVTests = 0; + mNbRayPrimTests = 0; + mNbIntersections = 0; +#ifndef OPC_RAYHIT_CALLBACK + if(mStabbedFaces) mStabbedFaces->Reset(); +#endif + + // Compute ray in local space + // The (Origin/Dir) form is needed for the ray-triangle test anyway (even for segment tests) + if(world) + { + Matrix3x3 InvWorld = *world; + mDir = InvWorld * world_ray.mDir; + + Matrix4x4 World; + InvertPRMatrix(World, *world); + mOrigin = world_ray.mOrig * World; + } + else + { + mDir = world_ray.mDir; + mOrigin = world_ray.mOrig; + } + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + if(!SkipPrimitiveTests()) + { + // Perform overlap test between the unique triangle and the ray (and set contact status if needed) + SEGMENT_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // Check temporal coherence : + + // Test previously colliding primitives first + if(TemporalCoherenceEnabled() && FirstContactEnabled() && face_id && *face_id!=INVALID_ID) + { +#ifdef OLD_CODE +#ifndef OPC_RAYHIT_CALLBACK + if(!mClosestHit) +#endif + { + // Request vertices from the app + VertexPointers VP; + mIMesh->GetTriangle(VP, *face_id); + // Perform ray-cached tri overlap test + if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) + { + // Intersection point is valid if: + // - distance is positive (else it can just be a face behind the orig point) + // - distance is smaller than a given max distance (useful for shadow feelers) +// if(mStabbedFace.mDistance>0.0f && mStabbedFace.mDistanceAddFace(mStabbedFace); +#endif + return TRUE; + } + } + } +#else + // New code + // We handle both Segment/ray queries with the same segment code, and a possible infinite limit + SEGMENT_PRIM(*face_id, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; +#endif + } + + // Precompute data (moved after temporal coherence since only needed for ray-AABB) + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) + { + // For Segment-AABB overlap + mData = 0.5f * mDir * mMaxDist; + mData2 = mOrigin + mData; + + // Precompute mFDir; + mFDir.x = fabsf(mData.x); + mFDir.y = fabsf(mData.y); + mFDir.z = fabsf(mData.z); + } + else + { + // For Ray-AABB overlap +// udword x = SIR(mDir.x)-1; +// udword y = SIR(mDir.y)-1; +// udword z = SIR(mDir.z)-1; +// mData.x = FR(x); +// mData.y = FR(y); +// mData.z = FR(z); + + // Precompute mFDir; + mFDir.x = fabsf(mDir.x); + mFDir.y = fabsf(mDir.y); + mFDir.z = fabsf(mDir.z); + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Stabbing query for vanilla AABB trees. + * \param world_ray [in] stabbing ray in world space + * \param tree [in] AABB tree + * \param box_indices [out] indices of stabbed boxes + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool RayCollider::Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices) +{ + // ### bad design here + + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + // Basically this is only called to initialize precomputed data + if(InitQuery(world_ray)) return true; + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(tree, box_indices); + else _RayStab(tree, box_indices); + + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBCollisionNode* node) +{ + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->IsLeaf()) + { + SEGMENT_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + _SegmentStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + SEGMENT_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + _SegmentStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBNoLeafNode* node) +{ + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->HasPosLeaf()) + { + SEGMENT_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + SEGMENT_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(Center, Extents)) return; + + if(node->HasPosLeaf()) + { + SEGMENT_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + SEGMENT_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for vanilla AABB trees. + * \param node [in] current collision node + * \param box_indices [out] indices of stabbed boxes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBTreeNode* node, Container& box_indices) +{ + // Test the box against the segment + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!SegmentAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + box_indices.Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _SegmentStab(node->GetPos(), box_indices); + _SegmentStab(node->GetNeg(), box_indices); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBCollisionNode* node) +{ + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->IsLeaf()) + { + RAY_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _RayStab(node->GetPos()); + + if(ContactFound()) return; + + _RayStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + RAY_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _RayStab(node->GetPos()); + + if(ContactFound()) return; + + _RayStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBNoLeafNode* node) +{ + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->HasPosLeaf()) + { + RAY_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + RAY_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(Center, Extents)) return; + + if(node->HasPosLeaf()) + { + RAY_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + RAY_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for vanilla AABB trees. + * \param node [in] current collision node + * \param box_indices [out] indices of stabbed boxes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBTreeNode* node, Container& box_indices) +{ + // Test the box against the ray + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!RayAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + mFlags |= OPC_CONTACT; + box_indices.Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _RayStab(node->GetPos(), box_indices); + _RayStab(node->GetNeg(), box_indices); + } +} diff --git a/Extras/CDTestFramework/Opcode/OPC_RayCollider.h b/Extras/CDTestFramework/Opcode/OPC_RayCollider.h new file mode 100644 index 0000000..d347b18 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_RayCollider.h @@ -0,0 +1,234 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a ray collider. + * \file OPC_RayCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_RAYCOLLIDER_H__ +#define __OPC_RAYCOLLIDER_H__ + + class OPCODE_API CollisionFace + { + public: + //! Constructor + inline_ CollisionFace() {} + //! Destructor + inline_ ~CollisionFace() {} + + udword mFaceID; //!< Index of touched face + float mDistance; //!< Distance from collider to hitpoint + float mU, mV; //!< Impact barycentric coordinates + }; + + class OPCODE_API CollisionFaces : private Container + { + public: + //! Constructor + CollisionFaces() {} + //! Destructor + ~CollisionFaces() {} + + inline_ udword GetNbFaces() const { return GetNbEntries()>>2; } + inline_ const CollisionFace* GetFaces() const { return (const CollisionFace*)GetEntries(); } + + inline_ void Reset() { Container::Reset(); } + + inline_ void AddFace(const CollisionFace& face) { Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV); } + }; + +#ifdef OPC_RAYHIT_CALLBACK + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE to record a hit. + * \param hit [in] current hit + * \param user_data [in] user-defined data from SetCallback() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef void (*HitCallback) (const CollisionFace& hit, void* user_data); +#endif + + class OPCODE_API RayCollider : public Collider + { + public: + // Constructor / Destructor + RayCollider(); + virtual ~RayCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic stabbing query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - in the user-provided destination array + * + * \param world_ray [in] stabbing ray in world space + * \param model [in] Opcode model to collide with + * \param world [in] model's world matrix, or null + * \param cache [in] a possibly cached face index, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world=null, udword* cache=null); + // + bool Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices); + // Settings + +#ifndef OPC_RAYHIT_CALLBACK + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: enable or disable "closest hit" mode. + * \param flag [in] true to report closest hit only + * \see SetCulling(bool flag) + * \see SetMaxDist(float max_dist) + * \see SetDestination(StabbedFaces* sf) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetClosestHit(bool flag) { mClosestHit = flag; } +#endif + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: enable or disable backface culling. + * \param flag [in] true to enable backface culling + * \see SetClosestHit(bool flag) + * \see SetMaxDist(float max_dist) + * \see SetDestination(StabbedFaces* sf) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetCulling(bool flag) { mCulling = flag; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: sets the higher distance bound. + * \param max_dist [in] higher distance bound. Default = maximal value, for ray queries (else segment) + * \see SetClosestHit(bool flag) + * \see SetCulling(bool flag) + * \see SetDestination(StabbedFaces* sf) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetMaxDist(float max_dist=MAX_FLOAT) { mMaxDist = max_dist; } + +#ifdef OPC_RAYHIT_CALLBACK + inline_ void SetHitCallback(HitCallback cb) { mHitCallback = cb; } + inline_ void SetUserData(void* user_data) { mUserData = user_data; } +#else + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: sets the destination array for stabbed faces. + * \param cf [in] destination array, filled during queries + * \see SetClosestHit(bool flag) + * \see SetCulling(bool flag) + * \see SetMaxDist(float max_dist) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetDestination(CollisionFaces* cf) { mStabbedFaces = cf; } +#endif + // Stats + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Ray-BV overlap tests after a collision query. + * \see GetNbRayPrimTests() + * \see GetNbIntersections() + * \return the number of Ray-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbRayBVTests() const { return mNbRayBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Ray-Triangle overlap tests after a collision query. + * \see GetNbRayBVTests() + * \see GetNbIntersections() + * \return the number of Ray-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbRayPrimTests() const { return mNbRayPrimTests; } + + // In-out test + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of intersection found after a collision query. Can be used for in/out tests. + * \see GetNbRayBVTests() + * \see GetNbRayPrimTests() + * \return the number of valid intersections during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbIntersections() const { return mNbIntersections; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Ray in local space + Point mOrigin; //!< Ray origin + Point mDir; //!< Ray direction (normalized) + Point mFDir; //!< fabsf(mDir) + Point mData, mData2; + // Stabbed faces + CollisionFace mStabbedFace; //!< Current stabbed face +#ifdef OPC_RAYHIT_CALLBACK + HitCallback mHitCallback; //!< Callback used to record a hit + void* mUserData; //!< User-defined data +#else + CollisionFaces* mStabbedFaces; //!< List of stabbed faces +#endif + // Stats + udword mNbRayBVTests; //!< Number of Ray-BV tests + udword mNbRayPrimTests; //!< Number of Ray-Primitive tests + // In-out test + udword mNbIntersections; //!< Number of valid intersections + // Dequantization coeffs + Point mCenterCoeff; + Point mExtentsCoeff; + // Settings + float mMaxDist; //!< Valid segment on the ray +#ifndef OPC_RAYHIT_CALLBACK + bool mClosestHit; //!< Report closest hit only +#endif + bool mCulling; //!< Stab culled faces or not + // Internal methods + void _SegmentStab(const AABBCollisionNode* node); + void _SegmentStab(const AABBNoLeafNode* node); + void _SegmentStab(const AABBQuantizedNode* node); + void _SegmentStab(const AABBQuantizedNoLeafNode* node); + void _SegmentStab(const AABBTreeNode* node, Container& box_indices); + void _RayStab(const AABBCollisionNode* node); + void _RayStab(const AABBNoLeafNode* node); + void _RayStab(const AABBQuantizedNode* node); + void _RayStab(const AABBQuantizedNoLeafNode* node); + void _RayStab(const AABBTreeNode* node, Container& box_indices); + // Overlap tests + inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null); + }; + +#endif // __OPC_RAYCOLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_RayTriOverlap.h b/Extras/CDTestFramework/Opcode/OPC_RayTriOverlap.h new file mode 100644 index 0000000..11f2121 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_RayTriOverlap.h @@ -0,0 +1,106 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#define LOCAL_EPSILON 0.000001f + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a ray-triangle intersection test. + * Original code from Tomas Möller's "Fast Minimum Storage Ray-Triangle Intersection". + * It's been optimized a bit with integer code, and modified to return a non-intersection if distance from + * ray origin to triangle is negative. + * + * \param vert0 [in] triangle vertex + * \param vert1 [in] triangle vertex + * \param vert2 [in] triangle vertex + * \return true on overlap. mStabbedFace is filled with relevant info. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) +{ + // Stats + mNbRayPrimTests++; + + // Find vectors for two edges sharing vert0 + Point edge1 = vert1 - vert0; + Point edge2 = vert2 - vert0; + + // Begin calculating determinant - also used to calculate U parameter + Point pvec = mDir^edge2; + + // If determinant is near zero, ray lies in plane of triangle + float det = edge1|pvec; + + if(mCulling) + { + if(det 0. So we can use integer cmp. + + // Calculate distance from vert0 to ray origin + Point tvec = mOrigin - vert0; + + // Calculate U parameter and test bounds + mStabbedFace.mU = tvec|pvec; +// if(IR(u)&0x80000000 || u>det) return FALSE; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IR(det)) return FALSE; + + // Prepare to test V parameter + Point qvec = tvec^edge1; + + // Calculate V parameter and test bounds + mStabbedFace.mV = mDir|qvec; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>det) return FALSE; + + // Calculate t, scale parameters, ray intersects triangle + mStabbedFace.mDistance = edge2|qvec; + // Det > 0 so we can early exit here + // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) + if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; + // Else go on + float OneOverDet = 1.0f / det; + mStabbedFace.mDistance *= OneOverDet; + mStabbedFace.mU *= OneOverDet; + mStabbedFace.mV *= OneOverDet; + } + else + { + // the non-culling branch + if(det>-LOCAL_EPSILON && det1.0f) return FALSE; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IEEE_1_0) return FALSE; + + // prepare to test V parameter + Point qvec = tvec^edge1; + + // Calculate V parameter and test bounds + mStabbedFace.mV = (mDir|qvec) * OneOverDet; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>1.0f) return FALSE; + + // Calculate t, ray intersects triangle + mStabbedFace.mDistance = (edge2|qvec) * OneOverDet; + // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) + if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; + } + return TRUE; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_Settings.h b/Extras/CDTestFramework/Opcode/OPC_Settings.h new file mode 100644 index 0000000..1074a0d --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_Settings.h @@ -0,0 +1,58 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains compilation flags. + * \file OPC_Settings.h + * \author Pierre Terdiman + * \date May, 12, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SETTINGS_H__ +#define __OPC_SETTINGS_H__ + + //! Use CPU comparisons (comment that line to use standard FPU compares) + #define OPC_CPU_COMPARE + + //! Use FCOMI / FCMOV on Pentium-Pro based processors (comment that line to use plain C++) + #define OPC_USE_FCOMI + + //! Use epsilon value in tri-tri overlap test + #define OPC_TRITRI_EPSILON_TEST + + //! Use tree-coherence or not [not implemented yet] +// #define OPC_USE_TREE_COHERENCE + + //! Use callbacks or direct pointers. Using callbacks might be a bit slower (but probably not much) +// #define OPC_USE_CALLBACKS + + //! Support triangle and vertex strides or not. Using strides might be a bit slower (but probably not much) +// #define OPC_USE_STRIDE + + //! Discard negative pointer in vanilla trees + #define OPC_NO_NEG_VANILLA_TREE + + //! Use a callback in the ray collider + #define OPC_RAYHIT_CALLBACK + + // NB: no compilation flag to enable/disable stats since they're actually needed in the box/box overlap test + +#endif //__OPC_SETTINGS_H__ \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/OPC_SphereAABBOverlap.h b/Extras/CDTestFramework/Opcode/OPC_SphereAABBOverlap.h new file mode 100644 index 0000000..acc97ab --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_SphereAABBOverlap.h @@ -0,0 +1,145 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Sphere-AABB overlap test, based on Jim Arvo's code. + * \param center [in] box center + * \param extents [in] box extents + * \return TRUE on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL SphereCollider::SphereAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbVolumeBVTests++; + + float d = 0.0f; + + //find the square of the distance + //from the sphere to the box +#ifdef OLDIES + for(udword i=0;i<3;i++) + { + float tmp = mCenter[i] - center[i]; + float s = tmp + extents[i]; + + if(s<0.0f) d += s*s; + else + { + s = tmp - extents[i]; + if(s>0.0f) d += s*s; + } + } +#endif + +//#ifdef NEW_TEST + +// float tmp = mCenter.x - center.x; +// float s = tmp + extents.x; + + float tmp,s; + + tmp = mCenter.x - center.x; + s = tmp + extents.x; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.x; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } + + tmp = mCenter.y - center.y; + s = tmp + extents.y; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.y; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } + + tmp = mCenter.z - center.z; + s = tmp + extents.z; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.z; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } +//#endif + +#ifdef OLDIES +// Point Min = center - extents; +// Point Max = center + extents; + + float d = 0.0f; + + //find the square of the distance + //from the sphere to the box + for(udword i=0;i<3;i++) + { +float Min = center[i] - extents[i]; + +// if(mCenter[i]Max[i]) + if(mCenter[i]>Max) + { + float s = mCenter[i] - Max; + d += s*s; + } + } + } +#endif + return d <= mRadius2; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_SphereCollider.cpp b/Extras/CDTestFramework/Opcode/OPC_SphereCollider.cpp new file mode 100644 index 0000000..485bd00 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_SphereCollider.cpp @@ -0,0 +1,735 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a sphere collider. + * \file OPC_SphereCollider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a sphere-vs-tree collider. + * This class performs a collision test between a sphere and an AABB tree. You can use this to do a standard player vs world collision, + * in a Nettle/Telemachos way. It doesn't suffer from all reported bugs in those two classic codes - the "new" one by Paul Nettle is a + * debuggued version I think. Collision response can be driven by reported collision data - it works extremely well for me. In sake of + * efficiency, all meshes (that is, all AABB trees) should of course also be kept in an extra hierarchical structure (octree, whatever). + * + * \class SphereCollider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_SphereAABBOverlap.h" +#include "OPC_SphereTriOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(prim_index); + +//! Sphere-triangle overlap test +#define SPHERE_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \ + \ + /* Perform sphere-tri overlap test */ \ + if(SphereTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SphereCollider::SphereCollider() +{ + mCenter.Zero(); + mRadius2 = 0.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SphereCollider::~SphereCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a sphere cache + * \param sphere [in] collision sphere in local space + * \param model [in] Opcode model to collide with + * \param worlds [in] sphere's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool SphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const Model& model, const Matrix4x4* worlds, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, sphere, worlds, worldm)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * - check temporal coherence + * + * \param cache [in/out] a sphere cache + * \param sphere [in] sphere in local space + * \param worlds [in] sphere's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL SphereCollider::InitQuery(SphereCache& cache, const Sphere& sphere, const Matrix4x4* worlds, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute sphere in model space: + // - Precompute R^2 + mRadius2 = sphere.mRadius * sphere.mRadius; + // - Compute center position + mCenter = sphere.mCenter; + // -> to world space + if(worlds) mCenter *= *worlds; + // -> to model space + if(worldm) + { + // Invert model matrix + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + + mCenter *= InvWorldM; + } + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the sphere (and set contact status if needed) + SPHERE_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence : + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the sphere (and set contact status if needed) + SPHERE_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // We're interested in all contacts =>test the new real sphere N(ew) against the previous fat sphere P(revious): + float r = sqrtf(cache.FatRadius2) - sphere.mRadius; + if(IsCacheValid(cache) && cache.Center.SquareDistance(mCenter) < r*r) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat sphere so that coherence will work for subsequent frames + mRadius2 *= cache.FatCoeff; +// mRadius2 = (sphere.mRadius * cache.FatCoeff)*(sphere.mRadius * cache.FatCoeff); + + // Update cache with query data (signature for cached faces) + cache.Center = mCenter; + cache.FatRadius2 = mRadius2; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for vanilla AABB trees. + * \param cache [in/out] a sphere cache + * \param sphere [in] collision sphere in world space + * \param tree [in] AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool SphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const AABBTree* tree) +{ + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + if(InitQuery(cache, sphere)) return true; + + // Perform collision query + _Collide(tree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the sphere completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the sphere contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL SphereCollider::SphereContainsBox(const Point& bc, const Point& be) +{ + // I assume if all 8 box vertices are inside the sphere, so does the whole box. + // Sounds ok but maybe there's a better way? + Point p; + p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z+be.z; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x+be.x; p.y=bc.y-be.y; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z-be.z; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x+be.x; p.y=bc.y-be.y; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + + return TRUE; +} + +#define TEST_BOX_IN_SPHERE(center, extents) \ + if(SphereContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SPHERE_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->IsLeaf()) + { + SPHERE_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SPHERE_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SPHERE_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->HasPosLeaf()) { SPHERE_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SPHERE_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for vanilla AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBTreeNode* node) +{ + // Perform Sphere-AABB overlap test + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!SphereAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf() || SphereContainsBox(Center, Extents)) + { + mFlags |= OPC_CONTACT; + mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _Collide(node->GetPos()); + _Collide(node->GetNeg()); + } +} + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridSphereCollider::HybridSphereCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridSphereCollider::~HybridSphereCollider() +{ +} + +bool HybridSphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const HybridModel& model, const Matrix4x4* worlds, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, sphere, worlds, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;imCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + SPHERE_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + SPHERE_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_SphereCollider.h b/Extras/CDTestFramework/Opcode/OPC_SphereCollider.h new file mode 100644 index 0000000..d4aa861 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_SphereCollider.h @@ -0,0 +1,105 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a sphere collider. + * \file OPC_SphereCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SPHERECOLLIDER_H__ +#define __OPC_SPHERECOLLIDER_H__ + + struct OPCODE_API SphereCache : VolumeCache + { + SphereCache() : Center(0.0f,0.0f,0.0f), FatRadius2(0.0f), FatCoeff(1.1f) {} + ~SphereCache() {} + + // Cached faces signature + Point Center; //!< Sphere used when performing the query resulting in cached faces + float FatRadius2; //!< Sphere used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere + }; + + class OPCODE_API SphereCollider : public VolumeCollider + { + public: + // Constructor / Destructor + SphereCollider(); + virtual ~SphereCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a sphere cache + * \param sphere [in] collision sphere in local space + * \param model [in] Opcode model to collide with + * \param worlds [in] sphere's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(SphereCache& cache, const Sphere& sphere, const Model& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + + // + bool Collide(SphereCache& cache, const Sphere& sphere, const AABBTree* tree); + protected: + // Sphere in model space + Point mCenter; //!< Sphere center + float mRadius2; //!< Sphere radius squared + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL SphereContainsBox(const Point& bc, const Point& be); + inline_ BOOL SphereAABBOverlap(const Point& center, const Point& extents); + BOOL SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(SphereCache& cache, const Sphere& sphere, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridSphereCollider : public SphereCollider + { + public: + // Constructor / Destructor + HybridSphereCollider(); + virtual ~HybridSphereCollider(); + + bool Collide(SphereCache& cache, const Sphere& sphere, const HybridModel& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_SPHERECOLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_SphereTriOverlap.h b/Extras/CDTestFramework/Opcode/OPC_SphereTriOverlap.h new file mode 100644 index 0000000..4542e51 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_SphereTriOverlap.h @@ -0,0 +1,203 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +// This is collision detection. If you do another distance test for collision *response*, +// if might be useful to simply *skip* the test below completely, and report a collision. +// - if sphere-triangle overlap, result is ok +// - if they don't, we'll discard them during collision response with a similar test anyway +// Overall this approach should run faster. + +// Original code by David Eberly in Magic. +BOOL SphereCollider::SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) +{ + // Stats + mNbVolumePrimTests++; + + // Early exit if one of the vertices is inside the sphere + Point kDiff = vert2 - mCenter; + float fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + kDiff = vert1 - mCenter; + fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + kDiff = vert0 - mCenter; + fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + // Else do the full distance test + Point TriEdge0 = vert1 - vert0; + Point TriEdge1 = vert2 - vert0; + +//Point kDiff = vert0 - mCenter; + float fA00 = TriEdge0.SquareMagnitude(); + float fA01 = TriEdge0 | TriEdge1; + float fA11 = TriEdge1.SquareMagnitude(); + float fB0 = kDiff | TriEdge0; + float fB1 = kDiff | TriEdge1; +//float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11 - fA01*fA01); + float u = fA01*fB1-fA11*fB0; + float v = fA01*fB0-fA00*fB1; + float SqrDist; + + if(u + v <= fDet) + { + if(u < 0.0f) + { + if(v < 0.0f) // region 4 + { + if(fB0 < 0.0f) + { +// v = 0.0f; + if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + else + { +// u = 0.0f; + if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else // region 3 + { +// u = 0.0f; + if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else if(v < 0.0f) // region 5 + { +// v = 0.0f; + if(fB0>=0.0f) { /*u = 0.0f;*/ SqrDist = fC; } + else if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + else // region 0 + { + // minimum at interior point + if(fDet==0.0f) + { +// u = 0.0f; +// v = 0.0f; + SqrDist = MAX_FLOAT; + } + else + { + float fInvDet = 1.0f/fDet; + u *= fInvDet; + v *= fInvDet; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + } + else + { + float fTmp0, fTmp1, fNumer, fDenom; + + if(u < 0.0f) // region 2 + { + fTmp0 = fA01 + fB0; + fTmp1 = fA11 + fB1; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// u = 1.0f; +// v = 0.0f; + SqrDist = fA00+2.0f*fB0+fC; + } + else + { + u = fNumer/fDenom; + v = 1.0f - u; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + else + { +// u = 0.0f; + if(fTmp1 <= 0.0f) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else if(fB1 >= 0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else if(v < 0.0f) // region 6 + { + fTmp0 = fA01 + fB1; + fTmp1 = fA00 + fB0; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// v = 1.0f; +// u = 0.0f; + SqrDist = fA11+2.0f*fB1+fC; + } + else + { + v = fNumer/fDenom; + u = 1.0f - v; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + else + { +// v = 0.0f; + if(fTmp1 <= 0.0f) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else if(fB0 >= 0.0f) { /*u = 0.0f;*/ SqrDist = fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + } + else // region 1 + { + fNumer = fA11 + fB1 - fA01 - fB0; + if(fNumer <= 0.0f) + { +// u = 0.0f; +// v = 1.0f; + SqrDist = fA11+2.0f*fB1+fC; + } + else + { + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// u = 1.0f; +// v = 0.0f; + SqrDist = fA00+2.0f*fB0+fC; + } + else + { + u = fNumer/fDenom; + v = 1.0f - u; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + } + } + + return fabsf(SqrDist) < mRadius2; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.cpp b/Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.cpp new file mode 100644 index 0000000..8928076 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.cpp @@ -0,0 +1,673 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an implementation of the sweep-and-prune algorithm (moved from Z-Collide) + * \file OPC_SweepAndPrune.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +inline_ void Sort(udword& id0, udword& id1) +{ + if(id0>id1) Swap(id0, id1); +} + + class Opcode::SAP_Element + { + public: + inline_ SAP_Element() {} + inline_ SAP_Element(udword id, SAP_Element* next) : mID(id), mNext(next) {} + inline_ ~SAP_Element() {} + + udword mID; + SAP_Element* mNext; + }; + + class Opcode::SAP_Box + { + public: + SAP_EndPoint* Min[3]; + SAP_EndPoint* Max[3]; + }; + + class Opcode::SAP_EndPoint + { + public: + float Value; // Min or Max value + SAP_EndPoint* Previous; // Previous EndPoint whose Value is smaller than ours (or null) + SAP_EndPoint* Next; // Next EndPoint whose Value is greater than ours (or null) + udword Data; // Parent box ID *2 | MinMax flag + + inline_ void SetData(udword box_id, BOOL is_max) { Data = (box_id<<1)|is_max; } + inline_ BOOL IsMax() const { return Data & 1; } + inline_ udword GetBoxID() const { return Data>>1; } + + inline_ void InsertAfter(SAP_EndPoint* element) + { + if(this!=element && this!=element->Next) + { + // Remove + if(Previous) Previous->Next = Next; + if(Next) Next->Previous = Previous; + + // Insert + Next = element->Next; + if(Next) Next->Previous = this; + + element->Next = this; + Previous = element; + } + } + + inline_ void InsertBefore(SAP_EndPoint* element) + { + if(this!=element && this!=element->Previous) + { + // Remove + if(Previous) Previous->Next = Next; + if(Next) Next->Previous = Previous; + + // Insert + Previous = element->Previous; + element->Previous = this; + + Next = element; + if(Previous) Previous->Next = this; + } + } + }; + + + + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SAP_PairData::SAP_PairData() : + mNbElements (0), + mNbUsedElements (0), + mElementPool (null), + mFirstFree (null), + mNbObjects (0), + mArray (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SAP_PairData::~SAP_PairData() +{ + Release(); +} + +void SAP_PairData::Release() +{ + mNbElements = 0; + mNbUsedElements = 0; + mNbObjects = 0; + DELETEARRAY(mElementPool); + DELETEARRAY(mArray); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes. + * \param nb_objects [in] + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool SAP_PairData::Init(udword nb_objects) +{ + // Make sure everything has been released + Release(); + if(!nb_objects) return false; + + mArray = new SAP_Element*[nb_objects]; + CHECKALLOC(mArray); + ZeroMemory(mArray, nb_objects*sizeof(SAP_Element*)); + mNbObjects = nb_objects; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Remaps a pointer when pool gets resized. + * \param element [in/out] remapped element + * \param delta [in] offset in bytes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void Remap(SAP_Element*& element, udword delta) +{ + if(element) element = (SAP_Element*)(udword(element) + delta); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets a free element in the pool. + * \param id [in] element id + * \param next [in] next element + * \param remap [out] possible remapping offset + * \return the new element + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SAP_Element* SAP_PairData::GetFreeElem(udword id, SAP_Element* next, udword* remap) +{ + if(remap) *remap = 0; + + SAP_Element* FreeElem; + if(mFirstFree) + { + // Recycle + FreeElem = mFirstFree; + mFirstFree = mFirstFree->mNext; // First free = next free (or null) + } + else + { + if(mNbUsedElements==mNbElements) + { + // Resize + mNbElements = mNbElements ? (mNbElements<<1) : 2; + + SAP_Element* NewElems = new SAP_Element[mNbElements]; + + if(mNbUsedElements) CopyMemory(NewElems, mElementPool, mNbUsedElements*sizeof(SAP_Element)); + + // Remap everything + { + udword Delta = udword(NewElems) - udword(mElementPool); + + for(udword i=0;imID = id; + FreeElem->mNext = next; + + return FreeElem; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Frees an element of the pool. + * \param elem [in] element to free/recycle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void SAP_PairData::FreeElem(SAP_Element* elem) +{ + elem->mNext = mFirstFree; // Next free + mFirstFree = elem; +} + +// Add a pair to the set. +void SAP_PairData::AddPair(udword id1, udword id2) +{ + // Order the ids + Sort(id1, id2); + + ASSERT(id1=mNbObjects) return; + + // Select the right list from "mArray". + SAP_Element* Current = mArray[id1]; + + if(!Current) + { + // Empty slot => create new element + mArray[id1] = GetFreeElem(id2, null); + } + else if(Current->mID>id2) + { + // The list is not empty but all elements are greater than id2 => insert id2 in the front. + mArray[id1] = GetFreeElem(id2, mArray[id1]); + } + else + { + // Else find the correct location in the sorted list (ascending order) and insert id2 there. + while(Current->mNext) + { + if(Current->mNext->mID > id2) break; + + Current = Current->mNext; + } + + if(Current->mID==id2) return; // The pair already exists + +// Current->mNext = GetFreeElem(id2, Current->mNext); + udword Delta; + SAP_Element* E = GetFreeElem(id2, Current->mNext, &Delta); + if(Delta) Remap(Current, Delta); + Current->mNext = E; + } +} + +// Delete a pair from the set. +void SAP_PairData::RemovePair(udword id1, udword id2) +{ + // Order the ids. + Sort(id1, id2); + + // Exit if the pair doesn't exist in the set + if(id1>=mNbObjects) return; + + // Otherwise, select the correct list. + SAP_Element* Current = mArray[id1]; + + // If this list is empty, the pair doesn't exist. + if(!Current) return; + + // Otherwise, if id2 is the first element, delete it. + if(Current->mID==id2) + { + mArray[id1] = Current->mNext; + FreeElem(Current); + } + else + { + // If id2 is not the first element, start traversing the sorted list. + while(Current->mNext) + { + // If we have moved too far away without hitting id2, then the pair doesn't exist + if(Current->mNext->mID > id2) return; + + // Otherwise, delete id2. + if(Current->mNext->mID == id2) + { + SAP_Element* Temp = Current->mNext; + Current->mNext = Temp->mNext; + FreeElem(Temp); + return; + } + Current = Current->mNext; + } + } +} + +void SAP_PairData::DumpPairs(Pairs& pairs) const +{ + // ### Ugly and slow + for(udword i=0;imIDmID); + Current = Current->mNext; + } + } +} + +void SAP_PairData::DumpPairs(PairCallback callback, void* user_data) const +{ + if(!callback) return; + + // ### Ugly and slow + for(udword i=0;imIDmID, user_data)) return; + Current = Current->mNext; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SweepAndPrune::SweepAndPrune() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SweepAndPrune::~SweepAndPrune() +{ +} + +void SweepAndPrune::GetPairs(Pairs& pairs) const +{ + mPairs.DumpPairs(pairs); +} + +void SweepAndPrune::GetPairs(PairCallback callback, void* user_data) const +{ + mPairs.DumpPairs(callback, user_data); +} + +bool SweepAndPrune::Init(udword nb_objects, const AABB** boxes) +{ + // 1) Create sorted lists + mNbObjects = nb_objects; + + mBoxes = new SAP_Box[nb_objects]; +// for(udword i=0;iGetMin(Axis); + Data[i*2+1] = boxes[i]->GetMax(Axis); + } + RadixSort RS; + const udword* Sorted = RS.Sort(Data, nb_objects*2).GetRanks(); + + SAP_EndPoint* PreviousEndPoint = null; + + for(udword i=0;i>1; + + ASSERT(BoxIndexValue = SortedCoord; +// CurrentEndPoint->IsMax = SortedIndex&1; // ### could be implicit ? +// CurrentEndPoint->ID = BoxIndex; // ### could be implicit ? + CurrentEndPoint->SetData(BoxIndex, SortedIndex&1); // ### could be implicit ? + CurrentEndPoint->Previous = PreviousEndPoint; + CurrentEndPoint->Next = null; + if(PreviousEndPoint) PreviousEndPoint->Next = CurrentEndPoint; + + if(CurrentEndPoint->IsMax()) mBoxes[BoxIndex].Max[Axis] = CurrentEndPoint; + else mBoxes[BoxIndex].Min[Axis] = CurrentEndPoint; + + PreviousEndPoint = CurrentEndPoint; + } + } + + DELETEARRAY(Data); + + CheckListsIntegrity(); + + // 2) Quickly find starting pairs + + mPairs.Init(nb_objects); + + { + Pairs P; + CompleteBoxPruning(nb_objects, boxes, P, Axes(AXES_XZY)); + for(udword i=0;iid0; + udword id1 = PP->id1; + + if(id0!=id1 && boxes[id0]->Intersect(*boxes[id1])) + { + mPairs.AddPair(id0, id1); + } + else ASSERT(0); + } + } + + return true; +} + +bool SweepAndPrune::CheckListsIntegrity() +{ + for(udword Axis=0;Axis<3;Axis++) + { + // Find list head + SAP_EndPoint* Current = mList[Axis]; + while(Current->Previous) Current = Current->Previous; + + udword Nb = 0; + + SAP_EndPoint* Previous = null; + while(Current) + { + Nb++; + + if(Previous) + { + ASSERT(Previous->Value <= Current->Value); + if(Previous->Value > Current->Value) return false; + } + + ASSERT(Current->Previous==Previous); + if(Current->Previous!=Previous) return false; + + Previous = Current; + Current = Current->Next; + } + + ASSERT(Nb==mNbObjects*2); + } + return true; +} + +inline_ BOOL Intersect(const AABB& a, const SAP_Box& b) +{ + if(b.Max[0]->Value < a.GetMin(0) || a.GetMax(0) < b.Min[0]->Value + || b.Max[1]->Value < a.GetMin(1) || a.GetMax(1) < b.Min[1]->Value + || b.Max[2]->Value < a.GetMin(2) || a.GetMax(2) < b.Min[2]->Value) return FALSE; + + return TRUE; +} + + + +bool SweepAndPrune::UpdateObject(udword i, const AABB& box) +{ + for(udword Axis=0;Axis<3;Axis++) + { +// udword Base = (udword)&mList[Axis][0]; + + // Update min + { + SAP_EndPoint* const CurrentMin = mBoxes[i].Min[Axis]; + ASSERT(!CurrentMin->IsMax()); + + const float Limit = box.GetMin(Axis); + if(Limit == CurrentMin->Value) + { + } + else if(Limit < CurrentMin->Value) + { + CurrentMin->Value = Limit; + + // Min is moving left: + SAP_EndPoint* NewPos = CurrentMin; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Previous) && tmp->Value > Limit) + { + NewPos = tmp; + + if(NewPos->IsMax()) + { + // Our min passed a max => start overlap + //udword SortedIndex = (udword(CurrentMin) - Base)/sizeof(NS_EndPoint); + const udword id0 = CurrentMin->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1 && Intersect(box, mBoxes[id1])) mPairs.AddPair(id0, id1); + } + } + + CurrentMin->InsertBefore(NewPos); + } + else// if(Limit > CurrentMin->Value) + { + CurrentMin->Value = Limit; + + // Min is moving right: + SAP_EndPoint* NewPos = CurrentMin; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Next) && tmp->Value < Limit) + { + NewPos = tmp; + + if(NewPos->IsMax()) + { + // Our min passed a max => stop overlap + const udword id0 = CurrentMin->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1) mPairs.RemovePair(id0, id1); + } + } + + CurrentMin->InsertAfter(NewPos); + } + } + + // Update max + { + SAP_EndPoint* const CurrentMax = mBoxes[i].Max[Axis]; + ASSERT(CurrentMax->IsMax()); + + const float Limit = box.GetMax(Axis); + if(Limit == CurrentMax->Value) + { + } + else if(Limit > CurrentMax->Value) + { + CurrentMax->Value = Limit; + + // Max is moving right: + SAP_EndPoint* NewPos = CurrentMax; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Next) && tmp->Value < Limit) + { + NewPos = tmp; + + if(!NewPos->IsMax()) + { + // Our max passed a min => start overlap + const udword id0 = CurrentMax->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1 && Intersect(box, mBoxes[id1])) mPairs.AddPair(id0, id1); + } + } + + CurrentMax->InsertAfter(NewPos); + } + else// if(Limit < CurrentMax->Value) + { + CurrentMax->Value = Limit; + + // Max is moving left: + SAP_EndPoint* NewPos = CurrentMax; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Previous) && tmp->Value > Limit) + { + NewPos = tmp; + + if(!NewPos->IsMax()) + { + // Our max passed a min => stop overlap + const udword id0 = CurrentMax->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1) mPairs.RemovePair(id0, id1); + } + } + + CurrentMax->InsertBefore(NewPos); + } + } + } + + return true; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.h b/Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.h new file mode 100644 index 0000000..0221d28 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_SweepAndPrune.h @@ -0,0 +1,95 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an implementation of the sweep-and-prune algorithm (moved from Z-Collide) + * \file OPC_SweepAndPrune.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SWEEPANDPRUNE_H__ +#define __OPC_SWEEPANDPRUNE_H__ + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE for each colliding pairs. + * \param id0 [in] id of colliding object + * \param id1 [in] id of colliding object + * \param user_data [in] user-defined data + * \return TRUE to continue enumeration + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef BOOL (*PairCallback) (udword id0, udword id1, void* user_data); + + class SAP_Element; + class SAP_EndPoint; + class SAP_Box; + + class OPCODE_API SAP_PairData + { + public: + SAP_PairData(); + ~SAP_PairData(); + + bool Init(udword nb_objects); + + void AddPair(udword id1, udword id2); + void RemovePair(udword id1, udword id2); + + void DumpPairs(Pairs& pairs) const; + void DumpPairs(PairCallback callback, void* user_data) const; + private: + udword mNbElements; //!< Total number of elements in the pool + udword mNbUsedElements; //!< Number of used elements + SAP_Element* mElementPool; //!< Array of mNbElements elements + SAP_Element* mFirstFree; //!< First free element in the pool + + udword mNbObjects; //!< Max number of objects we can handle + SAP_Element** mArray; //!< Pointers to pool + // Internal methods + SAP_Element* GetFreeElem(udword id, SAP_Element* next, udword* remap=null); + inline_ void FreeElem(SAP_Element* elem); + void Release(); + }; + + class OPCODE_API SweepAndPrune + { + public: + SweepAndPrune(); + ~SweepAndPrune(); + + bool Init(udword nb_objects, const AABB** boxes); + bool UpdateObject(udword i, const AABB& box); + + void GetPairs(Pairs& pairs) const; + void GetPairs(PairCallback callback, void* user_data) const; + private: + SAP_PairData mPairs; + + udword mNbObjects; + SAP_Box* mBoxes; + SAP_EndPoint* mList[3]; + // Internal methods + bool CheckListsIntegrity(); + }; + +#endif //__OPC_SWEEPANDPRUNE_H__ \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/OPC_TreeBuilders.cpp b/Extras/CDTestFramework/Opcode/OPC_TreeBuilders.cpp new file mode 100644 index 0000000..7fbb4e3 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_TreeBuilders.cpp @@ -0,0 +1,264 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for tree builders. + * \file OPC_TreeBuilders.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A builder for AABB-trees of vertices. + * + * \class AABBTreeOfVerticesBuilder + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A builder for AABB-trees of AABBs. + * + * \class AABBTreeOfAABBsBuilder + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A builder for AABB-trees of triangles. + * + * \class AABBTreeOfTrianglesBuilder + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the AABB of a set of primitives. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [out] global AABB enclosing the set of input primitives + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeOfAABBsBuilder::ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const +{ + // Checkings + if(!primitives || !nb_prims) return false; + + // Initialize global box + global_box = mAABBArray[primitives[0]]; + + // Loop through boxes + for(udword i=1;iGetTriangle(VP, *primitives++); + // Update global box + Min.Min(*VP.Vertex[0]).Min(*VP.Vertex[1]).Min(*VP.Vertex[2]); + Max.Max(*VP.Vertex[0]).Max(*VP.Vertex[1]).Max(*VP.Vertex[2]); + } + global_box.SetMinMax(Min, Max); + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABBTreeOfTrianglesBuilder::GetSplittingValue(udword index, udword axis) const +{ +/* // Compute center of triangle + Point Center; + mTriList[index].Center(mVerts, Center); + // Return value + return Center[axis];*/ + + // Compute correct component from center of triangle +// return (mVerts[mTriList[index].mVRef[0]][axis] +// +mVerts[mTriList[index].mVRef[1]][axis] +// +mVerts[mTriList[index].mVRef[2]][axis])*INV3; + + VertexPointers VP; + mIMesh->GetTriangle(VP, index); + + // Compute correct component from center of triangle + return ((*VP.Vertex[0])[axis] + +(*VP.Vertex[1])[axis] + +(*VP.Vertex[2])[axis])*INV3; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given node. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [in] global AABB enclosing the set of input primitives + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABBTreeOfTrianglesBuilder::GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const +{ + if(mSettings.mRules&SPLIT_GEOM_CENTER) + { + // Loop through triangles + float SplitValue = 0.0f; + VertexPointers VP; + for(udword i=0;iGetTriangle(VP, primitives[i]); + // Update split value + SplitValue += (*VP.Vertex[0])[axis]; + SplitValue += (*VP.Vertex[1])[axis]; + SplitValue += (*VP.Vertex[2])[axis]; + } + return SplitValue / float(nb_prims*3); + } + else return AABBTreeBuilder::GetSplittingValue(primitives, nb_prims, global_box, axis); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the AABB of a set of primitives. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [out] global AABB enclosing the set of input primitives + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeOfVerticesBuilder::ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const +{ + // Checkings + if(!primitives || !nb_prims) return false; + + // Initialize global box + global_box.SetEmpty(); + + // Loop through vertices + for(udword i=0;iHasLeafNodes()!=cache.Model1->HasLeafNodes()) return false; + if(cache.Model0->IsQuantized()!=cache.Model1->IsQuantized()) return false; + + /* + + Rules: + - perform hull test + - when hulls collide, disable hull test + - if meshes overlap, reset countdown + - if countdown reaches 0, enable hull test + + */ + +#ifdef __MESHMERIZER_H__ + // Handle hulls + if(cache.HullTest) + { + if(cache.Model0->GetHull() && cache.Model1->GetHull()) + { + struct Local + { + static Point* SVCallback(const Point& sv, udword& previndex, udword user_data) + { + CollisionHull* Hull = (CollisionHull*)user_data; + previndex = Hull->ComputeSupportingVertex(sv, previndex); + return (Point*)&Hull->GetVerts()[previndex]; + } + }; + + bool Collide; + + if(0) + { + static GJKEngine GJK; + static bool GJKInitDone=false; + if(!GJKInitDone) + { + GJK.Enable(GJK_BACKUP_PROCEDURE); + GJK.Enable(GJK_DEGENERATE); + GJK.Enable(GJK_HILLCLIMBING); + GJKInitDone = true; + } + GJK.SetCallbackObj0(Local::SVCallback); + GJK.SetCallbackObj1(Local::SVCallback); + GJK.SetUserData0(udword(cache.Model0->GetHull())); + GJK.SetUserData1(udword(cache.Model1->GetHull())); + Collide = GJK.Collide(*world0, *world1, &cache.SepVector); + } + else + { + static SVEngine SVE; + SVE.SetCallbackObj0(Local::SVCallback); + SVE.SetCallbackObj1(Local::SVCallback); + SVE.SetUserData0(udword(cache.Model0->GetHull())); + SVE.SetUserData1(udword(cache.Model1->GetHull())); + Collide = SVE.Collide(*world0, *world1, &cache.SepVector); + } + + if(!Collide) + { + // Reset stats & contact status + mFlags &= ~OPC_CONTACT; + mNbBVBVTests = 0; + mNbPrimPrimTests = 0; + mNbBVPrimTests = 0; + mPairs.Reset(); + return true; + } + } + } + + // Here, hulls collide + cache.HullTest = false; +#endif // __MESHMERIZER_H__ + + // Checkings + if(!Setup(cache.Model0->GetMeshInterface(), cache.Model1->GetMeshInterface())) return false; + + // Simple double-dispatch + bool Status; + if(!cache.Model0->HasLeafNodes()) + { + if(cache.Model0->IsQuantized()) + { + const AABBQuantizedNoLeafTree* T0 = (const AABBQuantizedNoLeafTree*)cache.Model0->GetTree(); + const AABBQuantizedNoLeafTree* T1 = (const AABBQuantizedNoLeafTree*)cache.Model1->GetTree(); + Status = Collide(T0, T1, world0, world1, &cache); + } + else + { + const AABBNoLeafTree* T0 = (const AABBNoLeafTree*)cache.Model0->GetTree(); + const AABBNoLeafTree* T1 = (const AABBNoLeafTree*)cache.Model1->GetTree(); + Status = Collide(T0, T1, world0, world1, &cache); + } + } + else + { + if(cache.Model0->IsQuantized()) + { + const AABBQuantizedTree* T0 = (const AABBQuantizedTree*)cache.Model0->GetTree(); + const AABBQuantizedTree* T1 = (const AABBQuantizedTree*)cache.Model1->GetTree(); + Status = Collide(T0, T1, world0, world1, &cache); + } + else + { + const AABBCollisionTree* T0 = (const AABBCollisionTree*)cache.Model0->GetTree(); + const AABBCollisionTree* T1 = (const AABBCollisionTree*)cache.Model1->GetTree(); + Status = Collide(T0, T1, world0, world1, &cache); + } + } + +#ifdef __MESHMERIZER_H__ + if(Status) + { + // Reset counter as long as overlap occurs + if(GetContactStatus()) cache.ResetCountDown(); + + // Enable hull test again when counter reaches zero + cache.CountDown--; + if(!cache.CountDown) + { + cache.ResetCountDown(); + cache.HullTest = true; + } + } +#endif + return Status; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::InitQuery(const Matrix4x4* world0, const Matrix4x4* world1) +{ + // Reset stats & contact status + Collider::InitQuery(); + mNbBVBVTests = 0; + mNbPrimPrimTests = 0; + mNbBVPrimTests = 0; + mPairs.Reset(); + + // Setup matrices + Matrix4x4 InvWorld0, InvWorld1; + if(world0) InvertPRMatrix(InvWorld0, *world0); + else InvWorld0.Identity(); + + if(world1) InvertPRMatrix(InvWorld1, *world1); + else InvWorld1.Identity(); + + Matrix4x4 World0to1 = world0 ? (*world0 * InvWorld1) : InvWorld1; + Matrix4x4 World1to0 = world1 ? (*world1 * InvWorld0) : InvWorld0; + + mR0to1 = World0to1; World0to1.GetTrans(mT0to1); + mR1to0 = World1to0; World1to0.GetTrans(mT1to0); + + // Precompute absolute 1-to-0 rotation matrix + for(udword i=0;i<3;i++) + { + for(udword j=0;j<3;j++) + { + // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID) + mAR.m[i][j] = 1e-6f + fabsf(mR1to0.m[i][j]); + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Takes advantage of temporal coherence. + * \param cache [in] cache for a pair of previously colliding primitives + * \return true if we can return immediately + * \warning only works for "First Contact" mode + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::CheckTemporalCoherence(Pair* cache) +{ + // Checkings + if(!cache) return false; + + // Test previously colliding primitives first + if(TemporalCoherenceEnabled() && FirstContactEnabled()) + { + PrimTest(cache->id0, cache->id1); + if(GetContactStatus()) return true; + } + return false; +} + +#define UPDATE_CACHE \ + if(cache && GetContactStatus()) \ + { \ + cache->id0 = mPairs.GetEntry(0); \ + cache->id1 = mPairs.GetEntry(1); \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for normal AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Perform collision query + _Collide(tree0->GetNodes(), tree1->GetNodes()); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for no-leaf AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Perform collision query + _Collide(tree0->GetNodes(), tree1->GetNodes()); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for quantized AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Setup dequantization coeffs + mCenterCoeff0 = tree0->mCenterCoeff; + mExtentsCoeff0 = tree0->mExtentsCoeff; + mCenterCoeff1 = tree1->mCenterCoeff; + mExtentsCoeff1 = tree1->mExtentsCoeff; + + // Dequantize box A + const AABBQuantizedNode* N0 = tree0->GetNodes(); + const Point a(float(N0->mAABB.mExtents[0]) * mExtentsCoeff0.x, float(N0->mAABB.mExtents[1]) * mExtentsCoeff0.y, float(N0->mAABB.mExtents[2]) * mExtentsCoeff0.z); + const Point Pa(float(N0->mAABB.mCenter[0]) * mCenterCoeff0.x, float(N0->mAABB.mCenter[1]) * mCenterCoeff0.y, float(N0->mAABB.mCenter[2]) * mCenterCoeff0.z); + // Dequantize box B + const AABBQuantizedNode* N1 = tree1->GetNodes(); + const Point b(float(N1->mAABB.mExtents[0]) * mExtentsCoeff1.x, float(N1->mAABB.mExtents[1]) * mExtentsCoeff1.y, float(N1->mAABB.mExtents[2]) * mExtentsCoeff1.z); + const Point Pb(float(N1->mAABB.mCenter[0]) * mCenterCoeff1.x, float(N1->mAABB.mCenter[1]) * mCenterCoeff1.y, float(N1->mAABB.mCenter[2]) * mCenterCoeff1.z); + + // Perform collision query + _Collide(N0, N1, a, Pa, b, Pb); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for quantized no-leaf AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Setup dequantization coeffs + mCenterCoeff0 = tree0->mCenterCoeff; + mExtentsCoeff0 = tree0->mExtentsCoeff; + mCenterCoeff1 = tree1->mCenterCoeff; + mExtentsCoeff1 = tree1->mExtentsCoeff; + + // Perform collision query + _Collide(tree0->GetNodes(), tree1->GetNodes()); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Standard trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// The normal AABB tree can use 2 different descent rules (with different performances) +//#define ORIGINAL_CODE //!< UNC-like descent rules +#define ALTERNATIVE_CODE //!< Alternative descent rules + +#ifdef ORIGINAL_CODE +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param b0 [in] collision node from first tree + * \param b1 [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter)) return; + + if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; } + + if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize()))) + { + _Collide(b0->GetNeg(), b1); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1); + } + else + { + _Collide(b0, b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0, b1->GetPos()); + } +} +#endif + +#ifdef ALTERNATIVE_CODE +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param b0 [in] collision node from first tree + * \param b1 [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter)) + { + return; + } + + if(b0->IsLeaf()) + { + if(b1->IsLeaf()) + { + PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); + } + else + { + _Collide(b0, b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0, b1->GetPos()); + } + } + else if(b1->IsLeaf()) + { + _Collide(b0->GetNeg(), b1); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1); + } + else + { + _Collide(b0->GetNeg(), b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0->GetNeg(), b1->GetPos()); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1->GetPos()); + } +} +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// No-leaf trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Leaf-leaf test for two primitive indices. + * \param id0 [in] index from first leaf-triangle + * \param id1 [in] index from second leaf-triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::PrimTest(udword id0, udword id1) +{ + // Request vertices from the app + VertexPointers VP0; + VertexPointers VP1; + mIMesh0->GetTriangle(VP0, id0); + mIMesh1->GetTriangle(VP1, id1); + + // Transform from space 1 to space 0 + Point u0,u1,u2; + TransformPoint(u0, *VP1.Vertex[0], mR1to0, mT1to0); + TransformPoint(u1, *VP1.Vertex[1], mR1to0, mT1to0); + TransformPoint(u2, *VP1.Vertex[2], mR1to0, mT1to0); + + // Perform triangle-triangle overlap test + if(TriTriOverlap(*VP0.Vertex[0], *VP0.Vertex[1], *VP0.Vertex[2], u0, u1, u2)) + { + // Keep track of colliding pairs + mPairs.Add(id0).Add(id1); + // Set contact status + mFlags |= OPC_CONTACT; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Leaf-leaf test for a previously fetched triangle from tree A (in B's space) and a new leaf from B. + * \param id1 [in] leaf-triangle index from tree B + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void AABBTreeCollider::PrimTestTriIndex(udword id1) +{ + // Request vertices from the app + VertexPointers VP; + mIMesh1->GetTriangle(VP, id1); + + // Perform triangle-triangle overlap test + if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) + { + // Keep track of colliding pairs + mPairs.Add(mLeafIndex).Add(id1); + // Set contact status + mFlags |= OPC_CONTACT; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Leaf-leaf test for a previously fetched triangle from tree B (in A's space) and a new leaf from A. + * \param id0 [in] leaf-triangle index from tree A + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void AABBTreeCollider::PrimTestIndexTri(udword id0) +{ + // Request vertices from the app + VertexPointers VP; + mIMesh0->GetTriangle(VP, id0); + + // Perform triangle-triangle overlap test + if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) + { + // Keep track of colliding pairs + mPairs.Add(id0).Add(mLeafIndex); + // Set contact status + mFlags |= OPC_CONTACT; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from A and a branch from B. + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideTriBox(const AABBNoLeafNode* b) +{ + // Perform triangle-box overlap test + if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return; + + // Keep same triangle, deal with first child + if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + // Keep same triangle, deal with second child + if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from B and a branch from A. + * \param b [in] collision node from first tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideBoxTri(const AABBNoLeafNode* b) +{ + // Perform triangle-box overlap test + if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return; + + // Keep same triangle, deal with first child + if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive()); + else _CollideBoxTri(b->GetPos()); + + if(ContactFound()) return; + + // Keep same triangle, deal with second child + if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive()); + else _CollideBoxTri(b->GetNeg()); +} + +//! Request triangle vertices from the app and transform them +#define FETCH_LEAF(prim_index, imesh, rot, trans) \ + mLeafIndex = prim_index; \ + /* Request vertices from the app */ \ + VertexPointers VP; imesh->GetTriangle(VP, prim_index); \ + /* Transform them in a common space */ \ + TransformPoint(mLeafVerts[0], *VP.Vertex[0], rot, trans); \ + TransformPoint(mLeafVerts[1], *VP.Vertex[1], rot, trans); \ + TransformPoint(mLeafVerts[2], *VP.Vertex[2], rot, trans); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param a [in] collision node from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(a->mAABB.mExtents, a->mAABB.mCenter, b->mAABB.mExtents, b->mAABB.mCenter)) return; + + // Catch leaf status + BOOL BHasPosLeaf = b->HasPosLeaf(); + BOOL BHasNegLeaf = b->HasNegLeaf(); + + if(a->HasPosLeaf()) + { + FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetNeg()); + } + + if(ContactFound()) return; + + if(a->HasNegLeaf()) + { + FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantized trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param b0 [in] collision node from first tree + * \param b1 [in] collision node from second tree + * \param a [in] extent from box A + * \param Pa [in] center from box A + * \param b [in] extent from box B + * \param Pb [in] center from box B + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(a, Pa, b, Pb)) return; + + if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; } + + if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize()))) + { + // Dequantize box + const QuantizedAABB* Box = &b0->GetNeg()->mAABB; + const Point negPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); + const Point nega(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); + _Collide(b0->GetNeg(), b1, nega, negPa, b, Pb); + + if(ContactFound()) return; + + // Dequantize box + Box = &b0->GetPos()->mAABB; + const Point posPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); + const Point posa(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); + _Collide(b0->GetPos(), b1, posa, posPa, b, Pb); + } + else + { + // Dequantize box + const QuantizedAABB* Box = &b1->GetNeg()->mAABB; + const Point negPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); + const Point negb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); + _Collide(b0, b1->GetNeg(), a, Pa, negb, negPb); + + if(ContactFound()) return; + + // Dequantize box + Box = &b1->GetPos()->mAABB; + const Point posPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); + const Point posb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); + _Collide(b0, b1->GetPos(), a, Pa, posb, posPb); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantized no-leaf trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from A and a quantized branch from B. + * \param leaf [in] leaf triangle from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideTriBox(const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box + const QuantizedAABB* bb = &b->mAABB; + const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); + const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); + + // Perform triangle-box overlap test + if(!TriBoxOverlap(Pb, eb)) return; + + if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from B and a quantized branch from A. + * \param b [in] collision node from first tree + * \param leaf [in] leaf triangle from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideBoxTri(const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box + const QuantizedAABB* bb = &b->mAABB; + const Point Pa(float(bb->mCenter[0]) * mCenterCoeff0.x, float(bb->mCenter[1]) * mCenterCoeff0.y, float(bb->mCenter[2]) * mCenterCoeff0.z); + const Point ea(float(bb->mExtents[0]) * mExtentsCoeff0.x, float(bb->mExtents[1]) * mExtentsCoeff0.y, float(bb->mExtents[2]) * mExtentsCoeff0.z); + + // Perform triangle-box overlap test + if(!TriBoxOverlap(Pa, ea)) return; + + if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive()); + else _CollideBoxTri(b->GetPos()); + + if(ContactFound()) return; + + if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive()); + else _CollideBoxTri(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param a [in] collision node from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box A + const QuantizedAABB* ab = &a->mAABB; + const Point Pa(float(ab->mCenter[0]) * mCenterCoeff0.x, float(ab->mCenter[1]) * mCenterCoeff0.y, float(ab->mCenter[2]) * mCenterCoeff0.z); + const Point ea(float(ab->mExtents[0]) * mExtentsCoeff0.x, float(ab->mExtents[1]) * mExtentsCoeff0.y, float(ab->mExtents[2]) * mExtentsCoeff0.z); + // Dequantize box B + const QuantizedAABB* bb = &b->mAABB; + const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); + const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); + + // Perform BV-BV overlap test + if(!BoxBoxOverlap(ea, Pa, eb, Pb)) return; + + // Catch leaf status + BOOL BHasPosLeaf = b->HasPosLeaf(); + BOOL BHasNegLeaf = b->HasNegLeaf(); + + if(a->HasPosLeaf()) + { + FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetNeg()); + } + + if(ContactFound()) return; + + if(a->HasNegLeaf()) + { + FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetNeg()); + } +} diff --git a/Extras/CDTestFramework/Opcode/OPC_TreeCollider.h b/Extras/CDTestFramework/Opcode/OPC_TreeCollider.h new file mode 100644 index 0000000..f0d731d --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_TreeCollider.h @@ -0,0 +1,253 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a tree collider. + * \file OPC_TreeCollider.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_TREECOLLIDER_H__ +#define __OPC_TREECOLLIDER_H__ + + //! This structure holds cached information used by the algorithm. + //! Two model pointers and two colliding primitives are cached. Model pointers are assigned + //! to their respective meshes, and the pair of colliding primitives is used for temporal + //! coherence. That is, in case temporal coherence is enabled, those two primitives are + //! tested for overlap before everything else. If they still collide, we're done before + //! even entering the recursive collision code. + struct OPCODE_API BVTCache : Pair + { + //! Constructor + inline_ BVTCache() + { + ResetCache(); + ResetCountDown(); + } + + void ResetCache() + { + Model0 = null; + Model1 = null; + id0 = 0; + id1 = 1; +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + HullTest = true; + SepVector.pid = 0; + SepVector.qid = 0; + SepVector.SV = Point(1.0f, 0.0f, 0.0f); +#endif // __MESHMERIZER_H__ + } + + inline_ void ResetCountDown() + { +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + CountDown = 50; +#endif // __MESHMERIZER_H__ + } + + const Model* Model0; //!< Model for first object + const Model* Model1; //!< Model for second object + +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + SVCache SepVector; + udword CountDown; + bool HullTest; +#endif // __MESHMERIZER_H__ + }; + + class OPCODE_API AABBTreeCollider : public Collider + { + public: + // Constructor / Destructor + AABBTreeCollider(); + virtual ~AABBTreeCollider(); + // Generic collision query + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results with: + * - GetContactStatus() + * - GetNbPairs() + * - GetPairs() + * + * \param cache [in] collision cache for model pointers and a colliding pair of primitives + * \param world0 [in] world matrix for first object, or null + * \param world1 [in] world matrix for second object, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null); + + // Collision queries + bool Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullPrimBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullBoxBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; } + + // Stats + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-BV overlap tests after a collision query. + * \see GetNbPrimPrimTests() + * \see GetNbBVPrimTests() + * \return the number of BV-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Triangle-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbBVPrimTests() + * \return the number of Triangle-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbPrimPrimTests() + * \return the number of BV-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; } + + // Data access + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of contacts after a collision query. + * \see GetContactStatus() + * \see GetPairs() + * \return the number of contacts / colliding pairs. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the pairs of colliding triangles after a collision query. + * \see GetContactStatus() + * \see GetNbPairs() + * \return the list of colliding pairs (triangle indices) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Colliding pairs + Container mPairs; //!< Pairs of colliding primitives + // User mesh interfaces + const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0 + const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1 + // Stats + udword mNbBVBVTests; //!< Number of BV-BV tests + udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests + udword mNbBVPrimTests; //!< Number of BV-Primitive tests + // Precomputed data + Matrix3x3 mAR; //!< Absolute rotation matrix + Matrix3x3 mR0to1; //!< Rotation from object0 to object1 + Matrix3x3 mR1to0; //!< Rotation from object1 to object0 + Point mT0to1; //!< Translation from object0 to object1 + Point mT1to0; //!< Translation from object1 to object0 + // Dequantization coeffs + Point mCenterCoeff0; + Point mExtentsCoeff0; + Point mCenterCoeff1; + Point mExtentsCoeff1; + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + udword mLeafIndex; //!< Triangle index + // Settings + bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) + bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false) + // Internal methods + + // Standard AABB trees + void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1); + // Quantized AABB trees + void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb); + // No-leaf AABB trees + void _CollideTriBox(const AABBNoLeafNode* b); + void _CollideBoxTri(const AABBNoLeafNode* b); + void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b); + // Quantized no-leaf AABB trees + void _CollideTriBox(const AABBQuantizedNoLeafNode* b); + void _CollideBoxTri(const AABBQuantizedNoLeafNode* b); + void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b); + // Overlap tests + void PrimTest(udword id0, udword id1); + inline_ void PrimTestTriIndex(udword id1); + inline_ void PrimTestIndexTri(udword id0); + + inline_ BOOL BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb); + inline_ BOOL TriBoxOverlap(const Point& center, const Point& extents); + inline_ BOOL TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2); + // Init methods + void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null); + bool CheckTemporalCoherence(Pair* cache); + + inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1) + { + mIMesh0 = mi0; + mIMesh1 = mi1; + + if(!mIMesh0 || !mIMesh1) return FALSE; + + return TRUE; + } + }; + +#endif // __OPC_TREECOLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/OPC_TriBoxOverlap.h b/Extras/CDTestFramework/Opcode/OPC_TriBoxOverlap.h new file mode 100644 index 0000000..a9ac2be --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_TriBoxOverlap.h @@ -0,0 +1,356 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +//! This macro quickly finds the min & max values among 3 variables +#define FINDMINMAX(x0, x1, x2, min, max) \ + min = max = x0; \ + if(x1max) max=x1; \ + if(x2max) max=x2; + +//! TO BE DOCUMENTED +inline_ BOOL planeBoxOverlap(const Point& normal, const float d, const Point& maxbox) +{ + Point vmin, vmax; + for(udword q=0;q<=2;q++) + { + if(normal[q]>0.0f) { vmin[q]=-maxbox[q]; vmax[q]=maxbox[q]; } + else { vmin[q]=maxbox[q]; vmax[q]=-maxbox[q]; } + } + if((normal|vmin)+d>0.0f) return FALSE; + if((normal|vmax)+d>=0.0f) return TRUE; + + return FALSE; +} + +//! TO BE DOCUMENTED +#define AXISTEST_X01(a, b, fa, fb) \ + min = a*v0.y - b*v0.z; \ + max = a*v2.y - b*v2.z; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.y + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_X2(a, b, fa, fb) \ + min = a*v0.y - b*v0.z; \ + max = a*v1.y - b*v1.z; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.y + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Y02(a, b, fa, fb) \ + min = b*v0.z - a*v0.x; \ + max = b*v2.z - a*v2.x; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Y1(a, b, fa, fb) \ + min = b*v0.z - a*v0.x; \ + max = b*v1.z - a*v1.x; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Z12(a, b, fa, fb) \ + min = a*v1.x - b*v1.y; \ + max = a*v2.x - b*v2.y; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.y; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Z0(a, b, fa, fb) \ + min = a*v0.x - b*v0.y; \ + max = a*v1.x - b*v1.y; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.y; \ + if(min>rad || max<-rad) return FALSE; + +// compute triangle edges +// - edges lazy evaluated to take advantage of early exits +// - fabs precomputed (half less work, possible since extents are always >0) +// - customized macros to take advantage of the null component +// - axis vector discarded, possibly saves useless movs +#define IMPLEMENT_CLASS3_TESTS \ + float rad; \ + float min, max; \ + \ + const float fey0 = fabsf(e0.y); \ + const float fez0 = fabsf(e0.z); \ + AXISTEST_X01(e0.z, e0.y, fez0, fey0); \ + const float fex0 = fabsf(e0.x); \ + AXISTEST_Y02(e0.z, e0.x, fez0, fex0); \ + AXISTEST_Z12(e0.y, e0.x, fey0, fex0); \ + \ + const float fey1 = fabsf(e1.y); \ + const float fez1 = fabsf(e1.z); \ + AXISTEST_X01(e1.z, e1.y, fez1, fey1); \ + const float fex1 = fabsf(e1.x); \ + AXISTEST_Y02(e1.z, e1.x, fez1, fex1); \ + AXISTEST_Z0(e1.y, e1.x, fey1, fex1); \ + \ + const Point e2 = mLeafVerts[0] - mLeafVerts[2]; \ + const float fey2 = fabsf(e2.y); \ + const float fez2 = fabsf(e2.z); \ + AXISTEST_X2(e2.z, e2.y, fez2, fey2); \ + const float fex2 = fabsf(e2.x); \ + AXISTEST_Y1(e2.z, e2.x, fez2, fex2); \ + AXISTEST_Z12(e2.y, e2.x, fey2, fex2); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Triangle-Box overlap test using the separating axis theorem. + * This is the code from Tomas Möller, a bit optimized: + * - with some more lazy evaluation (faster path on PC) + * - with a tiny bit of assembly + * - with "SAT-lite" applied if needed + * - and perhaps with some more minor modifs... + * + * \param center [in] box center + * \param extents [in] box extents + * \return true if triangle & box overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::TriBoxOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbBVPrimTests++; + + // use separating axis theorem to test overlap between triangle and box + // need to test for overlap in these directions: + // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle + // we do not even need to test these) + // 2) normal of the triangle + // 3) crossproduct(edge from tri, {x,y,z}-directin) + // this gives 3x3=9 more tests + + // move everything so that the boxcenter is in (0,0,0) + Point v0, v1, v2; + v0.x = mLeafVerts[0].x - center.x; + v1.x = mLeafVerts[1].x - center.x; + v2.x = mLeafVerts[2].x - center.x; + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; + + // same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; + + // same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>extents.x || max<-extents.x) return FALSE; + + // Same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>extents.y || max<-extents.y) return FALSE; + + // Same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>extents.z || max<-extents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, extents)) return FALSE; + + // 3) "Class III" tests + if(mFullPrimBoxTest) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} + +//! A dedicated version where the box is constant +inline_ BOOL OBBCollider::TriBoxOverlap() +{ + // Stats + mNbVolumePrimTests++; + + // Hook + const Point& extents = mBoxExtents; + const Point& v0 = mLeafVerts[0]; + const Point& v1 = mLeafVerts[1]; + const Point& v2 = mLeafVerts[2]; + + // use separating axis theorem to test overlap between triangle and box + // need to test for overlap in these directions: + // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle + // we do not even need to test these) + // 2) normal of the triangle + // 3) crossproduct(edge from tri, {x,y,z}-directin) + // this gives 3x3=9 more tests + + // Box center is already in (0,0,0) + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>mBoxExtents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-mBoxExtents.x) return FALSE; + + if(FCMin3(v0.y, v1.y, v2.y)>mBoxExtents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-mBoxExtents.y) return FALSE; + + if(FCMin3(v0.z, v1.z, v2.z)>mBoxExtents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-mBoxExtents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>mBoxExtents.x || max<-mBoxExtents.x) return FALSE; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>mBoxExtents.y || max<-mBoxExtents.y) return FALSE; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>mBoxExtents.z || max<-mBoxExtents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, mBoxExtents)) return FALSE; + + // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} + +//! ...and another one, jeez +inline_ BOOL AABBCollider::TriBoxOverlap() +{ + // Stats + mNbVolumePrimTests++; + + // Hook + const Point& center = mBox.mCenter; + const Point& extents = mBox.mExtents; + + // use separating axis theorem to test overlap between triangle and box + // need to test for overlap in these directions: + // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle + // we do not even need to test these) + // 2) normal of the triangle + // 3) crossproduct(edge from tri, {x,y,z}-directin) + // this gives 3x3=9 more tests + + // move everything so that the boxcenter is in (0,0,0) + Point v0, v1, v2; + v0.x = mLeafVerts[0].x - center.x; + v1.x = mLeafVerts[1].x - center.x; + v2.x = mLeafVerts[2].x - center.x; + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; + + // same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; + + // same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>extents.x || max<-extents.x) return FALSE; + + // Same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>extents.y || max<-extents.y) return FALSE; + + // Same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>extents.z || max<-extents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, extents)) return FALSE; + + // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} diff --git a/Extras/CDTestFramework/Opcode/OPC_TriTriOverlap.h b/Extras/CDTestFramework/Opcode/OPC_TriTriOverlap.h new file mode 100644 index 0000000..d1968e5 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_TriTriOverlap.h @@ -0,0 +1,295 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//! if OPC_TRITRI_EPSILON_TEST is true then we do a check (if |dv|b) \ + { \ + const float c=a; \ + a=b; \ + b=c; \ + } + +//! Edge to edge test based on Franlin Antonio's gem: "Faster Line Segment Intersection", in Graphics Gems III, pp. 199-202 +#define EDGE_EDGE_TEST(V0, U0, U1) \ + Bx = U0[i0] - U1[i0]; \ + By = U0[i1] - U1[i1]; \ + Cx = V0[i0] - U0[i0]; \ + Cy = V0[i1] - U0[i1]; \ + f = Ay*Bx - Ax*By; \ + d = By*Cx - Bx*Cy; \ + if((f>0.0f && d>=0.0f && d<=f) || (f<0.0f && d<=0.0f && d>=f)) \ + { \ + const float e=Ax*Cy - Ay*Cx; \ + if(f>0.0f) \ + { \ + if(e>=0.0f && e<=f) return TRUE; \ + } \ + else \ + { \ + if(e<=0.0f && e>=f) return TRUE; \ + } \ + } + +//! TO BE DOCUMENTED +#define EDGE_AGAINST_TRI_EDGES(V0, V1, U0, U1, U2) \ +{ \ + float Bx,By,Cx,Cy,d,f; \ + const float Ax = V1[i0] - V0[i0]; \ + const float Ay = V1[i1] - V0[i1]; \ + /* test edge U0,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0, U0, U1); \ + /* test edge U1,U2 against V0,V1 */ \ + EDGE_EDGE_TEST(V0, U1, U2); \ + /* test edge U2,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0, U2, U0); \ +} + +//! TO BE DOCUMENTED +#define POINT_IN_TRI(V0, U0, U1, U2) \ +{ \ + /* is T1 completly inside T2? */ \ + /* check if V0 is inside tri(U0,U1,U2) */ \ + float a = U1[i1] - U0[i1]; \ + float b = -(U1[i0] - U0[i0]); \ + float c = -a*U0[i0] - b*U0[i1]; \ + float d0 = a*V0[i0] + b*V0[i1] + c; \ + \ + a = U2[i1] - U1[i1]; \ + b = -(U2[i0] - U1[i0]); \ + c = -a*U1[i0] - b*U1[i1]; \ + const float d1 = a*V0[i0] + b*V0[i1] + c; \ + \ + a = U0[i1] - U2[i1]; \ + b = -(U0[i0] - U2[i0]); \ + c = -a*U2[i0] - b*U2[i1]; \ + const float d2 = a*V0[i0] + b*V0[i1] + c; \ + if(d0*d1>0.0f) \ + { \ + if(d0*d2>0.0f) return TRUE; \ + } \ +} + +//! TO BE DOCUMENTED +BOOL CoplanarTriTri(const Point& n, const Point& v0, const Point& v1, const Point& v2, const Point& u0, const Point& u1, const Point& u2) +{ + float A[3]; + short i0,i1; + /* first project onto an axis-aligned plane, that maximizes the area */ + /* of the triangles, compute indices: i0,i1. */ + A[0] = fabsf(n[0]); + A[1] = fabsf(n[1]); + A[2] = fabsf(n[2]); + if(A[0]>A[1]) + { + if(A[0]>A[2]) + { + i0=1; /* A[0] is greatest */ + i1=2; + } + else + { + i0=0; /* A[2] is greatest */ + i1=1; + } + } + else /* A[0]<=A[1] */ + { + if(A[2]>A[1]) + { + i0=0; /* A[2] is greatest */ + i1=1; + } + else + { + i0=0; /* A[1] is greatest */ + i1=2; + } + } + + /* test all edges of triangle 1 against the edges of triangle 2 */ + EDGE_AGAINST_TRI_EDGES(v0, v1, u0, u1, u2); + EDGE_AGAINST_TRI_EDGES(v1, v2, u0, u1, u2); + EDGE_AGAINST_TRI_EDGES(v2, v0, u0, u1, u2); + + /* finally, test if tri1 is totally contained in tri2 or vice versa */ + POINT_IN_TRI(v0, u0, u1, u2); + POINT_IN_TRI(u0, v0, v1, v2); + + return FALSE; +} + +//! TO BE DOCUMENTED +#define NEWCOMPUTE_INTERVALS(VV0, VV1, VV2, D0, D1, D2, D0D1, D0D2, A, B, C, X0, X1) \ +{ \ + if(D0D1>0.0f) \ + { \ + /* here we know that D0D2<=0.0 */ \ + /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ + A=VV2; B=(VV0 - VV2)*D2; C=(VV1 - VV2)*D2; X0=D2 - D0; X1=D2 - D1; \ + } \ + else if(D0D2>0.0f) \ + { \ + /* here we know that d0d1<=0.0 */ \ + A=VV1; B=(VV0 - VV1)*D1; C=(VV2 - VV1)*D1; X0=D1 - D0; X1=D1 - D2; \ + } \ + else if(D1*D2>0.0f || D0!=0.0f) \ + { \ + /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ + A=VV0; B=(VV1 - VV0)*D0; C=(VV2 - VV0)*D0; X0=D0 - D1; X1=D0 - D2; \ + } \ + else if(D1!=0.0f) \ + { \ + A=VV1; B=(VV0 - VV1)*D1; C=(VV2 - VV1)*D1; X0=D1 - D0; X1=D1 - D2; \ + } \ + else if(D2!=0.0f) \ + { \ + A=VV2; B=(VV0 - VV2)*D2; C=(VV1 - VV2)*D2; X0=D2 - D0; X1=D2 - D1; \ + } \ + else \ + { \ + /* triangles are coplanar */ \ + return CoplanarTriTri(N1, V0, V1, V2, U0, U1, U2); \ + } \ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Triangle/triangle intersection test routine, + * by Tomas Moller, 1997. + * See article "A Fast Triangle-Triangle Intersection Test", + * Journal of Graphics Tools, 2(2), 1997 + * + * Updated June 1999: removed the divisions -- a little faster now! + * Updated October 1999: added {} to CROSS and SUB macros + * + * int NoDivTriTriIsect(float V0[3],float V1[3],float V2[3], + * float U0[3],float U1[3],float U2[3]) + * + * \param V0 [in] triangle 0, vertex 0 + * \param V1 [in] triangle 0, vertex 1 + * \param V2 [in] triangle 0, vertex 2 + * \param U0 [in] triangle 1, vertex 0 + * \param U1 [in] triangle 1, vertex 1 + * \param U2 [in] triangle 1, vertex 2 + * \return true if triangles overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2) +{ + // Stats + mNbPrimPrimTests++; + + // Compute plane equation of triangle(V0,V1,V2) + Point E1 = V1 - V0; + Point E2 = V2 - V0; + const Point N1 = E1 ^ E2; + const float d1 =-N1 | V0; + // Plane equation 1: N1.X+d1=0 + + // Put U0,U1,U2 into plane equation 1 to compute signed distances to the plane + float du0 = (N1|U0) + d1; + float du1 = (N1|U1) + d1; + float du2 = (N1|U2) + d1; + + // Coplanarity robustness check +#ifdef OPC_TRITRI_EPSILON_TEST + if(fabsf(du0)0.0f && du0du2>0.0f) // same sign on all of them + not equal 0 ? + return FALSE; // no intersection occurs + + // Compute plane of triangle (U0,U1,U2) + E1 = U1 - U0; + E2 = U2 - U0; + const Point N2 = E1 ^ E2; + const float d2=-N2 | U0; + // plane equation 2: N2.X+d2=0 + + // put V0,V1,V2 into plane equation 2 + float dv0 = (N2|V0) + d2; + float dv1 = (N2|V1) + d2; + float dv2 = (N2|V2) + d2; + +#ifdef OPC_TRITRI_EPSILON_TEST + if(fabsf(dv0)0.0f && dv0dv2>0.0f) // same sign on all of them + not equal 0 ? + return FALSE; // no intersection occurs + + // Compute direction of intersection line + const Point D = N1^N2; + + // Compute and index to the largest component of D + float max=fabsf(D[0]); + short index=0; + float bb=fabsf(D[1]); + float cc=fabsf(D[2]); + if(bb>max) max=bb,index=1; + if(cc>max) max=cc,index=2; + + // This is the simplified projection onto L + const float vp0 = V0[index]; + const float vp1 = V1[index]; + const float vp2 = V2[index]; + + const float up0 = U0[index]; + const float up1 = U1[index]; + const float up2 = U2[index]; + + // Compute interval for triangle 1 + float a,b,c,x0,x1; + NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1); + + // Compute interval for triangle 2 + float d,e,f,y0,y1; + NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1); + + const float xx=x0*x1; + const float yy=y0*y1; + const float xxyy=xx*yy; + + float isect1[2], isect2[2]; + + float tmp=a*xxyy; + isect1[0]=tmp+b*x1*yy; + isect1[1]=tmp+c*x0*yy; + + tmp=d*xxyy; + isect2[0]=tmp+e*xx*y1; + isect2[1]=tmp+f*xx*y0; + + SORT(isect1[0],isect1[1]); + SORT(isect2[0],isect2[1]); + + if(isect1[1]HasPosLeaf()) mTouchedPrimitives->Add(node->GetPosPrimitive()); \ + else _Dump(node->GetPos()); \ + \ + if(ContactFound()) return; \ + \ + if(node->HasNegLeaf()) mTouchedPrimitives->Add(node->GetNegPrimitive()); \ + else _Dump(node->GetNeg()); \ +} + +#define IMPLEMENT_LEAFDUMP(type) \ +void VolumeCollider::_Dump(const type* node) \ +{ \ + if(node->IsLeaf()) \ + { \ + mTouchedPrimitives->Add(node->GetPrimitive()); \ + } \ + else \ + { \ + _Dump(node->GetPos()); \ + \ + if(ContactFound()) return; \ + \ + _Dump(node->GetNeg()); \ + } \ +} + +IMPLEMENT_NOLEAFDUMP(AABBNoLeafNode) +IMPLEMENT_NOLEAFDUMP(AABBQuantizedNoLeafNode) + +IMPLEMENT_LEAFDUMP(AABBCollisionNode) +IMPLEMENT_LEAFDUMP(AABBQuantizedNode) diff --git a/Extras/CDTestFramework/Opcode/OPC_VolumeCollider.h b/Extras/CDTestFramework/Opcode/OPC_VolumeCollider.h new file mode 100644 index 0000000..e0eb626 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/OPC_VolumeCollider.h @@ -0,0 +1,147 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base volume collider class. + * \file OPC_VolumeCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_VOLUMECOLLIDER_H__ +#define __OPC_VOLUMECOLLIDER_H__ + + struct OPCODE_API VolumeCache + { + VolumeCache() : Model(null) {} + ~VolumeCache() {} + + Container TouchedPrimitives; //!< Indices of touched primitives + const BaseModel* Model; //!< Owner + }; + + class OPCODE_API VolumeCollider : public Collider + { + public: + // Constructor / Destructor + VolumeCollider(); + virtual ~VolumeCollider() = 0; + + // Collision report + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of touched primitives after a collision query. + * \see GetContactStatus() + * \see GetTouchedPrimitives() + * \return the number of touched primitives + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetNbEntries() : 0; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the list of touched primitives after a collision query. + * \see GetContactStatus() + * \see GetNbTouchedPrimitives() + * \return the list of touched primitives (primitive indices) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const udword* GetTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetEntries() : null; } + + // Stats + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Volume-BV overlap tests after a collision query. + * \see GetNbVolumePrimTests() + * \return the number of Volume-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbVolumeBVTests() const { return mNbVolumeBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Volume-Triangle overlap tests after a collision query. + * \see GetNbVolumeBVTests() + * \return the number of Volume-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbVolumePrimTests() const { return mNbVolumePrimTests; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Touched primitives + Container* mTouchedPrimitives; //!< List of touched primitives + + // Dequantization coeffs + Point mCenterCoeff; + Point mExtentsCoeff; + // Stats + udword mNbVolumeBVTests; //!< Number of Volume-BV tests + udword mNbVolumePrimTests; //!< Number of Volume-Primitive tests + // Internal methods + void _Dump(const AABBCollisionNode* node); + void _Dump(const AABBNoLeafNode* node); + void _Dump(const AABBQuantizedNode* node); + void _Dump(const AABBQuantizedNoLeafNode* node); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Initializes a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) inline_ void InitQuery() + { + // Reset stats & contact status + mNbVolumeBVTests = 0; + mNbVolumePrimTests = 0; + Collider::InitQuery(); + } + + inline_ BOOL IsCacheValid(VolumeCache& cache) + { + // We're going to do a volume-vs-model query. + if(cache.Model!=mCurrentModel) + { + // Cached list was for another model so we can't keep it + // Keep track of new owner and reset cache + cache.Model = mCurrentModel; + return FALSE; + } + else + { + // Same models, no problem + return TRUE; + } + } + }; + +#endif // __OPC_VOLUMECOLLIDER_H__ diff --git a/Extras/CDTestFramework/Opcode/Opcode.cpp b/Extras/CDTestFramework/Opcode/Opcode.cpp new file mode 100644 index 0000000..68511a6 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Opcode.cpp @@ -0,0 +1,74 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main file for Opcode.dll. + * \file Opcode.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* + Finding a good name is difficult! + Here's the draft for this lib.... Spooky, uh? + + VOID? Very Optimized Interference Detection + ZOID? Zappy's Optimized Interference Detection + CID? Custom/Clever Interference Detection + AID / ACID! Accurate Interference Detection + QUID? Quick Interference Detection + RIDE? Realtime Interference DEtection + WIDE? Wicked Interference DEtection (....) + GUID! + KID ! k-dop interference detection :) + OPCODE! OPtimized COllision DEtection +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +bool Opcode::InitOpcode() +{ + Log("// Initializing OPCODE\n\n"); +// LogAPIInfo(); + return true; +} + +void ReleasePruningSorters(); +bool Opcode::CloseOpcode() +{ + Log("// Closing OPCODE\n\n"); + + ReleasePruningSorters(); + + return true; +} + +#ifdef ICE_MAIN + +void ModuleAttach(HINSTANCE hinstance) +{ +} + +void ModuleDetach() +{ +} + +#endif \ No newline at end of file diff --git a/Extras/CDTestFramework/Opcode/Opcode.dsp b/Extras/CDTestFramework/Opcode/Opcode.dsp new file mode 100644 index 0000000..ddadef6 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Opcode.dsp @@ -0,0 +1,517 @@ +# Microsoft Developer Studio Project File - Name="Opcode" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Opcode - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Opcode.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Opcode.mak" CFG="Opcode - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Opcode - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Opcode - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Opcode - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPCODE_EXPORTS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPCODE_EXPORTS" /Yu"stdafx.h" /FD /QIfist /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /machine:I386 +# SUBTRACT LINK32 /debug + +!ELSEIF "$(CFG)" == "Opcode - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPCODE_EXPORTS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPCODE_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /QIfist /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug\Opcode_D.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Opcode - Win32 Release" +# Name "Opcode - Win32 Debug" +# Begin Group "API" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\OPC_BaseModel.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_BaseModel.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_HybridModel.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_HybridModel.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_IceHook.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Model.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Model.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Settings.h +# End Source File +# Begin Source File + +SOURCE=.\Opcode.cpp +# End Source File +# Begin Source File + +SOURCE=.\Opcode.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Trees" + +# PROP Default_Filter "" +# Begin Group "Collision queries" + +# PROP Default_Filter "" +# Begin Group "Base colliders" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\OPC_Collider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Collider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_VolumeCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_VolumeCollider.h +# End Source File +# End Group +# Begin Group "Standard colliders" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\OPC_AABBCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_AABBCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_OBBCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_OBBCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeCollider.h +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=.\OPC_AABBTree.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_AABBTree.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Common.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Common.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_MeshInterface.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_MeshInterface.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_OptimizedTree.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_OptimizedTree.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeBuilders.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeBuilders.h +# End Source File +# End Group +# Begin Group "Overlap tests" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\OPC_BoxBoxOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TriBoxOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TriTriOverlap.h +# End Source File +# End Group +# Begin Group "SweepAndPrune" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\OPC_BoxPruning.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_BoxPruning.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SweepAndPrune.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_SweepAndPrune.h +# End Source File +# End Group +# Begin Group "Usages" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\OPC_Picking.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Picking.h +# End Source File +# End Group +# Begin Group "Ice" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Ice\IceAABB.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceAABB.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceAxes.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceBoundingSphere.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceContainer.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceContainer.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceFPU.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceHPoint.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceHPoint.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceIndexedTriangle.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceIndexedTriangle.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceLSS.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix3x3.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix3x3.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix4x4.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix4x4.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMemoryMacros.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceOBB.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceOBB.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePairs.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePlane.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePlane.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePoint.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePoint.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePreprocessor.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRandom.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRandom.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRay.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRay.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRevisitedRadix.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRevisitedRadix.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceSegment.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceSegment.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTriangle.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTriangle.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTrilist.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTypes.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/Extras/CDTestFramework/Opcode/Opcode.dsw b/Extras/CDTestFramework/Opcode/Opcode.dsw new file mode 100644 index 0000000..bc37a2c --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Opcode.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Opcode"=.\Opcode.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/Extras/CDTestFramework/Opcode/Opcode.h b/Extras/CDTestFramework/Opcode/Opcode.h new file mode 100644 index 0000000..094b579 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Opcode.h @@ -0,0 +1,99 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main file for Opcode.dll. + * \file Opcode.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPCODE_H__ +#define __OPCODE_H__ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compilation messages +#if defined(OPCODE_EXPORTS) + #pragma message("Compiling OPCODE") +#elif !defined(OPCODE_EXPORTS) + #pragma message("Using OPCODE") + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Automatic linking + #ifndef BAN_OPCODE_AUTOLINK + #ifdef _DEBUG + #pragma comment(lib, "Opcode_D.lib") + #else + #pragma comment(lib, "Opcode.lib") + #endif + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Preprocessor +#ifndef ICE_NO_DLL + #ifdef OPCODE_EXPORTS + #define OPCODE_API __declspec(dllexport) + #else + #define OPCODE_API __declspec(dllimport) + #endif +#else + #define OPCODE_API +#endif + + #include "OPC_IceHook.h" + + namespace Opcode + { + // Bulk-of-the-work + #include "OPC_Settings.h" + #include "OPC_Common.h" + #include "OPC_MeshInterface.h" + // Builders + #include "OPC_TreeBuilders.h" + // Trees + #include "OPC_AABBTree.h" + #include "OPC_OptimizedTree.h" + // Models + #include "OPC_BaseModel.h" + #include "OPC_Model.h" + #include "OPC_HybridModel.h" + // Colliders + #include "OPC_Collider.h" + #include "OPC_VolumeCollider.h" + #include "OPC_TreeCollider.h" + #include "OPC_RayCollider.h" + #include "OPC_SphereCollider.h" + #include "OPC_OBBCollider.h" + #include "OPC_AABBCollider.h" + #include "OPC_LSSCollider.h" + #include "OPC_PlanesCollider.h" + // Usages + #include "OPC_Picking.h" + // Sweep-and-prune + #include "OPC_BoxPruning.h" + #include "OPC_SweepAndPrune.h" + #include "OPC_ArraySAP.h" + + FUNCTION OPCODE_API bool InitOpcode(); + FUNCTION OPCODE_API bool CloseOpcode(); + } + +#endif // __OPCODE_H__ diff --git a/Extras/CDTestFramework/Opcode/Opcode.sln b/Extras/CDTestFramework/Opcode/Opcode.sln new file mode 100644 index 0000000..269cc7d --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Opcode.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Opcode", "Opcode.vcproj", "{4B23B91D-D4D6-4ED6-9583-FE6CC3730F51}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {4B23B91D-D4D6-4ED6-9583-FE6CC3730F51}.Debug.ActiveCfg = Debug|Win32 + {4B23B91D-D4D6-4ED6-9583-FE6CC3730F51}.Debug.Build.0 = Debug|Win32 + {4B23B91D-D4D6-4ED6-9583-FE6CC3730F51}.Release.ActiveCfg = Release|Win32 + {4B23B91D-D4D6-4ED6-9583-FE6CC3730F51}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/Extras/CDTestFramework/Opcode/Opcode.vcproj b/Extras/CDTestFramework/Opcode/Opcode.vcproj new file mode 100644 index 0000000..1683de8 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/Opcode.vcproj @@ -0,0 +1,1416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/CDTestFramework/Opcode/ReadMe.txt b/Extras/CDTestFramework/Opcode/ReadMe.txt new file mode 100644 index 0000000..01ad45b --- /dev/null +++ b/Extras/CDTestFramework/Opcode/ReadMe.txt @@ -0,0 +1,188 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + OPCODE distribution 1.3 (june 2003) + ----------------------- + + New in Opcode 1.3: + - fixed the divide by 0 bug that was happening when all centers where located on a coordinate axis (thanks to Jorrit T) + - linearized "complete" vanilla AABB trees + - ANSI-compliant "for" loops (for the ones porting it to Linux...) + - callbacks & pointers moved to mesh interface + - support for triangle & vertex strides + - optimized the sphere-triangle overlap code a bit + - dynamic trees (refit) + - more builders + - ValidateSubdivision in builders + - LSS collider + - primitive-bv tests can now be skipped in most volume queries + - temporal coherence now also works for airborne objects + - temporal coherence completed for boxes / all contacts, LSS, etc + - ray-collider now uses a callback + - some common "usages" have been introduced (only picking for now) + - SPLIT_COMPLETE removed (now implicitely using mLimit = 1) + - hybrid collision models + - sweep-and-prune code added, moved from my old Z-Collide lib + - it now works with meshes made of only 1 triangle (except in mesh-mesh case!) + + Disclaimer: + + - I forced myself to actually *do* the release today no matter what. Else it would never have been done. That's + why the code may not be very polished. I also removed a *lot* of things (more usages, distance queries, etc...) + that weren't ready for prime-time (or that were linked to too many of my supporting libs) + + - Some comments may also be obsolete here and there. The old User Manual for Opcode 1.2 may not fit version 1.3 + either, since there's a new "mesh interface" to support strides, etc. + + - Everything in the "Ice" directory has been hacked out of my engine and edited until everything compiled. Don't + expect anything out there to be cute or something. In particular, some CPP files are not even included when not + needed, so you can expect some linker errors if you try messing around with them... + + Otherwise, it should be just like previous version, only better. In particular, hybrid models can be very + memory-friendly (sometimes using like 10 times less ram than the best trees from version 1.2). The possible + speed hit is often invisible (if it even exists), especially using temporal coherence in "all contacts" mode. + (Admittedly, this depends on your particular usage pattern / what you do on collided triangles). + + The sweep-and-prune code is similar to the "vanilla" version found in V-Collide (but that one's better IMHO...) + The simple "radix" version is often just as good, see for yourself. + + OPCODE distribution 1.2 (august 2002) + ----------------------- + + New in Opcode 1.2: + - new VolumeCollider base class + - simplified callback setup + - you can now use callbacks or pointers (setup at compile time) + - destination array not needed anymore in the RayCollider (faster in-out tests) + - renamed classes: AABBRayCollider => RayCollider, AABBSphereCollider => SphereCollider + - the sphere query now only returns a list of faces (extra info discarded). On the other hand it's a lot faster. + - OBB, AABB and planes queries. Original OBB and AABB queries contributed by Erwin de Vries. + - cosmetic changes in OPC_BoxBoxOverlap.h contributed by Gottfried Chen + - some inlining problems fixed + - faster ray-mesh tests using the separating axis theorem + - new split value in AABB tree construction (contributed by Igor Kravtchenko). Provides faster queries most of the time. + - improved temporal coherence for sphere & AABB queries (works in "All contacts" mode) + + Notes: + + - Everything in the "Ice code" directory (in VC++) is basically copy-pasted from my engine, with a lot + of code removed until there was no link error anymore. Don't expect those files to be cute or anything, + they've never been meant to be released and they're often updated/modified/messy. + - Some experimental features have been removed as well. Else I would never have released the 1.2... + - Not as polished/optimal as I would like it to be, but that's life. I promised myself to release it + before october 2002 (one YEAR later ?!).... That's the only reason why it's there. + - Some people reported ColDet was faster. Uh, come on. They were using Opcode in + "All contacts" mode whereas ColDet was doing "first contact"... + + OPCODE distribution 1.1 (october 2001) + ----------------------- + + New in Opcode 1.1: + - stabbing queries + - sphere queries + - abtract base class for colliders + - settings validation methods + - compilation flags now grouped in OPC_Settings.h + - smaller files, new VC++ virtual dirs (cleaner) + + Notes: + + - "override(baseclass)" is a personal cosmetic thing. It's the same as "virtual", but provides more info. + - I code in 1600*1200, so some lines may look a bit long.. + - This version is not as polished as the previous one due to lack of time. The stabbing & sphere queries + can still be optimized: for example by trying other atomic overlap tests. I'm using my first ray-AABB + code, but the newer one seems better. Tim Schröder's one is good as well. See: www.codercorner.com/RayAABB.cpp + - The trees can easily be compressed even more, I save this for later (lack of time, lack of time!) + - I removed various tests before releasing this one: + - a separation line, a.k.a. "front" in QuickCD, because gains were unclear + - distance queries in a PQP style, because it was way too slow + - support for deformable models, too slow as well + - You can easily use Opcode to do your player-vs-world collision detection, in a Nettle/Telemachos way. + If someone out there wants to donate some art / level for the cause, I'd be glad to release a demo. (current + demo uses copyrighted art I'm not allowed to spread) + - Sorry for the lack of real docs and/or solid examples. I just don't have enough time. + + OPCODE distribution 1.0 (march 2001) + ----------------------- + + - First release + + =============================================================================== + + WHAT ? + + OPCODE means OPtimized COllision DEtection. + So this is a collision detection package similar to RAPID. Here's a + quick list of features: + + - C++ interface, developed for Windows systems using VC++ 6.0 + - Works on arbitrary meshes (convex or non-convex), even polygon soups + - Current implementation uses AABB-trees + - Introduces Primitive-BV overlap tests during recursive collision queries (whereas + standard libraries only rely on Primitive-Primitive and BV-BV tests) + - Introduces no-leaf trees, i.e. collision trees whose leaf nodes have been removed + - Supports collision queries on quantized trees (decompressed on-the-fly) + - Supports "first contact" or "all contacts" modes (à la RAPID) + - Uses temporal coherence for "first contact" mode (~10 to 20 times faster, useful + in rigid body simulation during bisection) + - Memory footprint is 7.2 times smaller than RAPID's one, which is ideal for console + games with limited ram (actually, if you use the unmodified RAPID code using double + precision, it's more like 13 times smaller...) + - And yet it often runs faster than RAPID (according to RDTSC, sometimes more than 5 + times faster when objects are deeply overlapping) + - Performance is usually close to RAPID's one in close-proximity situations + - Stabbing, planes & volume queries (sphere, AABB, OBB, LSS) + - Sweep-and-prune + - Now works with deformable meshes + - Hybrid trees + + + What it can be used for: + - standard mesh-mesh collision detection (similar to RAPID, SOLID, QuickCD, PQP, ColDet...) + - N-body collisions (similar to V-Collide) + - camera-vs-world collisions (similar to Telemachos/Paul Nettle/Stan Melax articles) + - shadow feelers to speed up lightmap computations + - in-out tests to speed up voxelization processes + - picking + - rigid body simulation + - view frustum culling + - etc + + WHY ? + + - Because RAPID uses too many bytes. + - Because the idea was nice... + + WHEN ? + + It's been coded in march 2001 following a thread on the GD-Algorithms list. + + GDAlgorithms-list mailing list + GDAlgorithms-list@lists.sourceforge.net + http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list + + WHO ? + + Pierre Terdiman + June, 1, 2003 + + p.terdiman@wanadoo.fr + p.terdiman@codercorner.com + + http://www.codercorner.com + http://www.codercorner.com/Opcode.htm diff --git a/Extras/CDTestFramework/Opcode/StdAfx.cpp b/Extras/CDTestFramework/Opcode/StdAfx.cpp new file mode 100644 index 0000000..632a740 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/StdAfx.cpp @@ -0,0 +1,19 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//#define ICE_MAIN +#include "Stdafx.h" diff --git a/Extras/CDTestFramework/Opcode/StdAfx.h b/Extras/CDTestFramework/Opcode/StdAfx.h new file mode 100644 index 0000000..4b30a04 --- /dev/null +++ b/Extras/CDTestFramework/Opcode/StdAfx.h @@ -0,0 +1,33 @@ +/* + * OPCODE - Optimized Collision Detection + * http://www.codercorner.com/Opcode.htm + * + * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#if !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) +#define AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include "Opcode.h" + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) diff --git a/Extras/CDTestFramework/OpcodeArraySAPTest.cpp b/Extras/CDTestFramework/OpcodeArraySAPTest.cpp new file mode 100644 index 0000000..bfea328 --- /dev/null +++ b/Extras/CDTestFramework/OpcodeArraySAPTest.cpp @@ -0,0 +1,215 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" +#include "OpcodeArraySAPTest.h" +#include "RenderingHelpers.h" +#include "GLFontRenderer.h" + +static udword gNbCreatedPairs; +static udword gNbDeletedPairs; +static udword gTotalNbPairs; + +static void* CBData = (void*)0x12345678; +static void* PairUserData = (void*)0xDeadDead; + +static void* CreatePairCB(const void* object0, const void* object1, void* user_data) +{ + assert(user_data==CBData); + + gNbCreatedPairs++; + return PairUserData; +} + +static void DeletePairCB(const void* object0, const void* object1, void* user_data, void* pair_user_data) +{ + assert(user_data==CBData); + assert(pair_user_data==PairUserData); + + gNbDeletedPairs++; +} + +OpcodeArraySAPTest::OpcodeArraySAPTest(int numBoxes) : + mBar (null), + mNbBoxes (numBoxes), + mBoxes (null), + mHandles (null), + mBoxTime (null), + mAmplitude (100.0f) +{ +} + +OpcodeArraySAPTest::~OpcodeArraySAPTest() +{ + Release(); +} + +void OpcodeArraySAPTest::Init() +{ + m_firstTime = true; + + SRand(0); + mBoxes = new AABB[mNbBoxes]; + mBoxTime = new float[mNbBoxes]; + mHandles = new void*[mNbBoxes]; + for(udword i=0;i +#include "GL/glut.h" + +#include "RenderingHelpers.h" + +//////////////////////// + +void DrawLine(const Point& p0, const Point& p1, const Point& color, float line_width) +{ + glDisable(GL_LIGHTING); + glLineWidth(line_width); + glColor4f(color.x, color.y, color.z, 1.0f); + Point tmp[] = {p0, p1}; + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Point), &tmp[0].x); + glDrawArrays(GL_LINES, 0, 2); + glDisableClientState(GL_VERTEX_ARRAY); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_LIGHTING); +} + +void DrawTriangle(const Point& p0, const Point& p1, const Point& p2, const Point& color) +{ +// glDisable(GL_LIGHTING); + glColor4f(color.x, color.y, color.z, 1.0f); + Point tmp[] = {p0, p1, p2}; + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Point), &tmp[0].x); + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableClientState(GL_VERTEX_ARRAY); +// glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +// glEnable(GL_LIGHTING); +} + + +//////////////////////// + +static void SetupGLMatrix(const Point& pos) +{ + float glmat[16]; //4x4 column major matrix for OpenGL. + glmat[0] = 1.0f; + glmat[1] = 0.0f; + glmat[2] = 0.0f; + glmat[3] = 0.0f; + + glmat[4] = 0.0f; + glmat[5] = 1.0f; + glmat[6] = 0.0f; + glmat[7] = 0.0f; + + glmat[8] = 0.0f; + glmat[9] = 0.0f; + glmat[10] = 1.0f; + glmat[11] = 0.0f; + + glmat[12] = pos.x; + glmat[13] = pos.y; + glmat[14] = pos.z; + glmat[15] = 1.0f; + + glMultMatrixf(glmat); +} + +void SetupGLMatrix(const Point& pos, const Matrix3x3& rot) +{ + float glmat[16]; //4x4 column major matrix for OpenGL. + glmat[0] = rot.m[0][0]; + glmat[1] = rot.m[0][1]; + glmat[2] = rot.m[0][2]; + glmat[3] = 0.0f; + + glmat[4] = rot.m[1][0]; + glmat[5] = rot.m[1][1]; + glmat[6] = rot.m[1][2]; + glmat[7] = 0.0f; + + glmat[8] = rot.m[2][0]; + glmat[9] = rot.m[2][1]; + glmat[10] = rot.m[2][2]; + glmat[11] = 0.0f; + + glmat[12] = pos.x; + glmat[13] = pos.y; + glmat[14] = pos.z; + glmat[15] = 1.0f; + + glMultMatrixf(glmat); +} + +void SetupGLMatrix(const Matrix4x4& world) +{ + SetupGLMatrix(world.GetTrans(), world); +} + +//////////////////////// + +static void RenderSphere(float radius) +{ + glutSolidSphere(radius, 12, 12); // Radius / slices / stacks +} + +void DrawSphere(const Sphere& sphere) +{ + glPushMatrix(); + SetupGLMatrix(sphere.mCenter); + RenderSphere(sphere.mRadius); + glPopMatrix(); +} + +//////////////////////// + +static void RenderBox(int size) +{ + glutSolidCube(size); +} + +void DrawOBB(const OBB& obb) +{ + glPushMatrix(); + SetupGLMatrix(obb.mCenter, obb.mRot); + glScalef(obb.mExtents.x, obb.mExtents.y, obb.mExtents.z); + RenderBox(2); + glPopMatrix(); +} + +//////////////////////// + +static float gCylinderData[]={ + 1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f, + 0.866025f,0.500000f,1.0f,0.866025f,0.500000f,1.0f,0.866025f,0.500000f,0.0f,0.866025f,0.500000f,0.0f, + 0.500000f,0.866025f,1.0f,0.500000f,0.866025f,1.0f,0.500000f,0.866025f,0.0f,0.500000f,0.866025f,0.0f, + -0.0f,1.0f,1.0f,-0.0f,1.0f,1.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f, + -0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,0.0f,-0.500000f,0.866025f,0.0f, + -0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,0.0f,-0.866025f,0.500000f,0.0f, + -1.0f,-0.0f,1.0f,-1.0f,-0.0f,1.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f, + -0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,0.0f,-0.866025f,-0.500000f,0.0f, + -0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,0.0f,-0.500000f,-0.866025f,0.0f, + 0.0f,-1.0f,1.0f,0.0f,-1.0f,1.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f, + 0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,0.0f,0.500000f,-0.866025f,0.0f, + 0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,0.0f,0.866026f,-0.500000f,0.0f, + 1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f +}; + +static float gCylinderDataCapsTop[]={ + 0.866026f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,-1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,-1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.866025f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.866025f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -1.000000f,-0.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -1.000000f,-0.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + -0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 1.000000f,0.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 1.000000f,0.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f, + 0.866026f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f, +}; + +static float gCylinderDataCapsBottom[]={ + 1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -1.000000f,-0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -1.000000f,-0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.866025f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.866025f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + -0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.866026f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.866026f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, + 1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f, +}; + +static void RenderCylinder() +{ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderData); + glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderData+3); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 13*2); + + glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsTop); + glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsTop+3); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsBottom); + glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsBottom+3); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); +} + +void DrawCapsule(const Matrix4x4& world, const Point& p0, const Point& p1, float r) +{ + const float h = p0.Distance(p1); + + glPushMatrix(); + SetupGLMatrix(world); + + glPushMatrix(); + glTranslatef(0.0f, h*0.5f, 0.0f); + RenderSphere(r); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.0f,-h*0.5f, 0.0f); + RenderSphere(r); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.0f,h*0.5f, 0.0f); + glScalef(r,h,r); + glRotatef(90.0f,1.0f,0.0f,0.0f); + RenderCylinder(); + glPopMatrix(); + + glPopMatrix(); +} + + + +#ifdef TOSEE +#include "NxPhysics.h" +#include "DrawObjects.h" + +#include + +static float gPlaneData[]={ + -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f +}; + + +static void RenderPlane() +{ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gPlaneData); + glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gPlaneData+3); + glDrawArrays(GL_TRIANGLES, 0, 6); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); +} + +void SetupGLMatrix(const NxVec3& pos, const NxMat33& orient) +{ + float glmat[16]; //4x4 column major matrix for OpenGL. + orient.getColumnMajorStride4(&(glmat[0])); + pos.get(&(glmat[12])); + + //clear the elements we don't need: + glmat[3] = glmat[7] = glmat[11] = 0.0f; + glmat[15] = 1.0f; + + glMultMatrixf(&(glmat[0])); +} + +void DrawLine(const NxVec3& p0, const NxVec3& p1, const NxVec3& color, float lineWidth) +{ + glDisable(GL_LIGHTING); + glLineWidth(lineWidth); + glColor4f(color.x, color.y, color.z, 1.0f); + NxVec3 av3LineEndpoints[] = {p0, p1}; + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &av3LineEndpoints[0].x); + glDrawArrays(GL_LINES, 0, 2); + glDisableClientState(GL_VERTEX_ARRAY); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_LIGHTING); +} + +void DrawTriangle(const NxVec3& p0, const NxVec3& p1, const NxVec3& p2, const NxVec3& color) +{ + glDisable(GL_LIGHTING); + glColor4f(color.x, color.y, color.z, 1.0f); + NxVec3 av3LineEndpoints[] = {p0, p1, p2}; + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &av3LineEndpoints[0].x); + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableClientState(GL_VERTEX_ARRAY); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_LIGHTING); +} + +void DrawCircle(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius, const bool semicircle) +{ + NxF32 step = NxTwoPiF32/NxF32(nbSegments); + NxU32 segs = nbSegments; + if(semicircle) + { + segs /= 2; + } + + for(NxU32 i=0;igetGlobalPose(); + NxPlaneShape* planeShape = plane->isPlane(); + NxPlane p = planeShape->getPlane(); + pose.t.x += p.d; + pose.t.y += p.d; + pose.t.z += p.d; + + glPushMatrix(); + glDisable(GL_LIGHTING); + glColor4f(0.1f, 0.2f, 0.3f, 1.0f); + pose.t.y -= 0.1f; + SetupGLMatrix(pose.t, pose.M); + glScalef(1024,0,1024); + RenderPlane(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_LIGHTING); + glPopMatrix(); +} + +void DrawWireBox(const NxBox& obb, const NxVec3& color, float lineWidth) +{ + // Compute obb vertices + NxVec3 pp[8]; + NxComputeBoxPoints(obb, pp); + + // Draw all lines + const NxU32* Indices = NxGetBoxEdges(); + for(NxU32 i=0;i<12;i++) + { + NxU32 VRef0 = *Indices++; + NxU32 VRef1 = *Indices++; + DrawLine(pp[VRef0], pp[VRef1], color, lineWidth); + } +} + +void DrawWireBox(NxShape* box, const NxVec3& color, float lineWidth) +{ + NxBox obb; + box->isBox()->getWorldOBB(obb); + + DrawWireBox(obb, color, lineWidth); +} + + +void DrawWireSphere(NxShape* sphere, const NxVec3& color) +{ + NxMat34 pose = sphere->getGlobalPose(); + + glPushMatrix(); + NxReal r = sphere->isSphere()->getRadius(); + + NxVec3 c0; pose.M.getColumn(0, c0); + NxVec3 c1; pose.M.getColumn(1, c1); + NxVec3 c2; pose.M.getColumn(2, c2); + DrawCircle(20, pose, color, r); + + pose.M.setColumn(0, c1); + pose.M.setColumn(1, c2); + pose.M.setColumn(2, c0); + DrawCircle(20, pose, color, r); + + pose.M.setColumn(0, c2); + pose.M.setColumn(1, c0); + pose.M.setColumn(2, c1); + DrawCircle(20, pose, color, r); + + glPopMatrix(); +} + +void DrawSphere(NxShape* sphere) +{ + NxMat34 pose = sphere->getGlobalPose(); + + glPushMatrix(); + SetupGLMatrix(pose.t, pose.M); + NxReal r = sphere->isSphere()->getRadius(); + glScalef(r,r,r); + RenderSphere(); + glPopMatrix(); +} + +void DrawWireCapsule(NxShape* capsule, const NxVec3& color) +{ + NxMat34 pose = capsule->getGlobalPose(); + + NxReal r = capsule->isCapsule()->getRadius(); + NxReal h = capsule->isCapsule()->getHeight(); + + NxSegment SG; + pose.M.getColumn(1, SG.p1); + SG.p1 *= 0.5f*h; + SG.p0 = -SG.p1; + SG.p0 += pose.t; + SG.p1 += pose.t; + + NxVec3 c0; pose.M.getColumn(0, c0); + NxVec3 c1; pose.M.getColumn(1, c1); + NxVec3 c2; pose.M.getColumn(2, c2); + DrawLine(SG.p0 + c0*r, SG.p1 + c0*r, color); + DrawLine(SG.p0 - c0*r, SG.p1 - c0*r, color); + DrawLine(SG.p0 + c2*r, SG.p1 + c2*r, color); + DrawLine(SG.p0 - c2*r, SG.p1 - c2*r, color); + + pose.M.setColumn(0, -c1); + pose.M.setColumn(1, -c0); + pose.M.setColumn(2, c2); + pose.t = SG.p0; + DrawCircle(20, pose, color, r, true); //halfcircle -- flipped + + pose.M.setColumn(0, c1); + pose.M.setColumn(1, -c0); + pose.M.setColumn(2, c2); + pose.t = SG.p1; + DrawCircle(20, pose, color, r, true); + + pose.M.setColumn(0, -c1); + pose.M.setColumn(1, c2); + pose.M.setColumn(2, c0); + pose.t = SG.p0; + DrawCircle(20, pose, color, r, true);//halfcircle -- good + + pose.M.setColumn(0, c1); + pose.M.setColumn(1, c2); + pose.M.setColumn(2, c0); + pose.t = SG.p1; + DrawCircle(20, pose, color, r, true); + + pose.M.setColumn(0, c2); + pose.M.setColumn(1, c0); + pose.M.setColumn(2, c1); + pose.t = SG.p0; + DrawCircle(20, pose, color, r); //full circle + pose.t = SG.p1; + DrawCircle(20, pose, color, r); +} + +static void computeBasis(const NxVec3& dir, NxVec3& right, NxVec3& up) +{ + // Derive two remaining vectors + if(fabsf(dir.y)>0.9999f) right = NxVec3(1.0f, 0.0f, 0.0f); + else right = (NxVec3(0.0f, 1.0f, 0.0f) ^ dir); + right.normalize(); + up = dir ^ right; +} + +void DrawWireCapsule(const NxCapsule& capsule, const NxVec3& color) +{ + NxReal r = capsule.radius; + NxVec3 dir = capsule.p0 - capsule.p1; + NxReal h = dir.magnitude(); + NxMat34 pose; + pose.t = (capsule.p0 + capsule.p1)*0.5f; + + if(h!=0.0f) + { + dir/=h; + NxVec3 right, up; + computeBasis(dir, right, up); + pose.M.setColumn(0, right); + pose.M.setColumn(1, dir); + pose.M.setColumn(2, up); + } + else + { + pose.M.id(); + } + +// NxMat34 pose = capsule->getGlobalPose(); +// const NxReal & r = capsule->isCapsule()->getRadius(); +// const NxReal & h = capsule->isCapsule()->getHeight(); + + + + NxSegment SG; + pose.M.getColumn(1, SG.p1); + SG.p1 *= 0.5f*h; + SG.p0 = -SG.p1; + SG.p0 += pose.t; + SG.p1 += pose.t; + + NxVec3 c0; pose.M.getColumn(0, c0); + NxVec3 c1; pose.M.getColumn(1, c1); + NxVec3 c2; pose.M.getColumn(2, c2); + DrawLine(SG.p0 + c0*r, SG.p1 + c0*r, color); + DrawLine(SG.p0 - c0*r, SG.p1 - c0*r, color); + DrawLine(SG.p0 + c2*r, SG.p1 + c2*r, color); + DrawLine(SG.p0 - c2*r, SG.p1 - c2*r, color); + + pose.M.setColumn(0, -c1); + pose.M.setColumn(1, -c0); + pose.M.setColumn(2, c2); + pose.t = SG.p0; + DrawCircle(20, pose, color, r, true); //halfcircle -- flipped + + pose.M.setColumn(0, c1); + pose.M.setColumn(1, -c0); + pose.M.setColumn(2, c2); + pose.t = SG.p1; + DrawCircle(20, pose, color, r, true); + + pose.M.setColumn(0, -c1); + pose.M.setColumn(1, c2); + pose.M.setColumn(2, c0); + pose.t = SG.p0; + DrawCircle(20, pose, color, r, true);//halfcircle -- good + + pose.M.setColumn(0, c1); + pose.M.setColumn(1, c2); + pose.M.setColumn(2, c0); + pose.t = SG.p1; + DrawCircle(20, pose, color, r, true); + + pose.M.setColumn(0, c2); + pose.M.setColumn(1, c0); + pose.M.setColumn(2, c1); + pose.t = SG.p0; + DrawCircle(20, pose, color, r); //full circle + pose.t = SG.p1; + DrawCircle(20, pose, color, r); +} + +void DrawCapsule(const NxVec3& color, NxF32 r, NxF32 h) +{ + glColor4f(color.x, color.y, color.z, 1.0f); + + glPushMatrix(); + glTranslatef(0.0f, h*0.5f, 0.0f); + glScalef(r,r,r); + RenderSphere(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.0f,-h*0.5f, 0.0f); + glScalef(r,r,r); + RenderSphere(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.0f,h*0.5f, 0.0f); + glScalef(r,h,r); + glRotatef(90.0f,1.0f,0.0f,0.0f); + RenderCylinder(); + glPopMatrix(); +} + +typedef NxVec3 Point; +typedef struct _Triangle { NxU32 p0; NxU32 p1; NxU32 p2; } Triangle; + +void DrawWireConvex(NxShape* mesh, const NxVec3& color) +{ + if(mesh->userData == NULL) return; + + NxMat34 pose = mesh->getGlobalPose(); + + NxConvexMeshDesc meshDesc = *((NxConvexMeshDesc*)(mesh->userData)); +// mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc); + + NxU32 nbVerts = meshDesc.numVertices; + NxU32 nbTriangles = meshDesc.numTriangles; + + Point* points = (Point *)meshDesc.points; + Triangle* triangles = (Triangle *)meshDesc.triangles; + + glPushMatrix(); + + float glmat[16]; //4x4 column major matrix for OpenGL. + pose.M.getColumnMajorStride4(&(glmat[0])); + pose.t.get(&(glmat[12])); + + //clear the elements we don't need: + glmat[3] = glmat[7] = glmat[11] = 0.0f; + glmat[15] = 1.0f; + + glMultMatrixf(&(glmat[0])); + + while(nbTriangles--) + { + DrawLine(points[triangles->p0], points[triangles->p1], color); + DrawLine(points[triangles->p1], points[triangles->p2], color); + DrawLine(points[triangles->p2], points[triangles->p0], color); + triangles++; + } + + glPopMatrix(); +} + +void DrawTriangleList(int iTriangleCount, Triangle *pTriangles, Point *pPoints) +{ + static int iBufferSize=0; + static float *pfVertexBuffer=NULL; + static float *pfNormalBuffer=NULL; + + if(iBufferSize < iTriangleCount*3) + { + iBufferSize=3*iTriangleCount; + + delete[] pfVertexBuffer; + pfVertexBuffer = new float[iBufferSize*3]; + + delete[] pfNormalBuffer; + pfNormalBuffer = new float[iBufferSize*3]; + } + + float *pfDestinationVertex=pfVertexBuffer; + float *pfDestinationNormal=pfNormalBuffer; + + for(int iTriangle=0; iTrianglep0].x; + *pfDestinationVertex++=pPoints[pTriangles->p0].y; + *pfDestinationVertex++=pPoints[pTriangles->p0].z; + *pfDestinationVertex++=pPoints[pTriangles->p1].x; + *pfDestinationVertex++=pPoints[pTriangles->p1].y; + *pfDestinationVertex++=pPoints[pTriangles->p1].z; + *pfDestinationVertex++=pPoints[pTriangles->p2].x; + *pfDestinationVertex++=pPoints[pTriangles->p2].y; + *pfDestinationVertex++=pPoints[pTriangles->p2].z; + + NxVec3 edge1 = pPoints[pTriangles->p1] - pPoints[pTriangles->p0]; + NxVec3 edge2 = pPoints[pTriangles->p2] - pPoints[pTriangles->p0]; + NxVec3 normal = edge1.cross(edge2); + normal.normalize(); + + *pfDestinationNormal++=normal.x; + *pfDestinationNormal++=normal.y; + *pfDestinationNormal++=normal.z; + *pfDestinationNormal++=normal.x; + *pfDestinationNormal++=normal.y; + *pfDestinationNormal++=normal.z; + *pfDestinationNormal++=normal.x; + *pfDestinationNormal++=normal.y; + *pfDestinationNormal++=normal.z; + + pTriangles++; + } + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pfVertexBuffer); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, pfNormalBuffer); + + glDrawArrays(GL_TRIANGLES, 0, 3*iTriangleCount); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + +} + +void DrawConvex(NxShape* mesh) +{ + NxConvexMeshDesc meshDesc; + + // SRM : Please note that I looked into a crash issue posed by + // one of our customers, and this code (i.e. reinterpreting the + // NxShape's userData as an NxConvexMeshDesc * was crashing because + // in the SampleRaycastCar demo, it sets that pointer equal to the + // NxWheel because that is used in NxVehicle::handleContactPair(). Thus + // in order to allow this code not to crash on the PS3, we should + // simply force the shape to save its description here. + mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc); + /** + if(mesh->userData != NULL) + { + meshDesc = *((NxConvexMeshDesc*)(mesh->userData)); + } else { + mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc); + } + **/ + + NxMat34 pose = mesh->getGlobalPose(); + + NxU32 nbVerts = meshDesc.numVertices; + NxU32 nbTriangles = meshDesc.numTriangles; + + Point* points = (Point *)meshDesc.points; + Triangle* triangles = (Triangle *)meshDesc.triangles; + + glPushMatrix(); + + float glmat[16]; //4x4 column major matrix for OpenGL. + pose.M.getColumnMajorStride4(&(glmat[0])); + pose.t.get(&(glmat[12])); + + //clear the elements we don't need: + glmat[3] = glmat[7] = glmat[11] = 0.0f; + glmat[15] = 1.0f; + + glMultMatrixf(&(glmat[0])); + + DrawTriangleList(nbTriangles, triangles, points); + + glPopMatrix(); +} + +void DrawWireMesh(NxShape* mesh, const NxVec3& color) +{ + if(mesh->userData == NULL) return; + + NxMat34 pose = mesh->getGlobalPose(); + + NxTriangleMeshDesc meshDesc = *((NxTriangleMeshDesc*)(mesh->userData)); +// mesh->isTriangleMesh()->getTriangleMesh().saveToDesc(meshDesc); + + NxU32 nbVerts = meshDesc.numVertices; + NxU32 nbTriangles = meshDesc.numTriangles; + + Point* points = (Point *)meshDesc.points; + Triangle* triangles = (Triangle *)meshDesc.triangles; + + glPushMatrix(); + + float glmat[16]; //4x4 column major matrix for OpenGL. + pose.M.getColumnMajorStride4(&(glmat[0])); + pose.t.get(&(glmat[12])); + + //clear the elements we don't need: + glmat[3] = glmat[7] = glmat[11] = 0.0f; + glmat[15] = 1.0f; + + glMultMatrixf(&(glmat[0])); + + while(nbTriangles--) + { + DrawLine(points[triangles->p0], points[triangles->p1], color); + DrawLine(points[triangles->p1], points[triangles->p2], color); + DrawLine(points[triangles->p2], points[triangles->p0], color); + triangles++; + } + + glPopMatrix(); +} + +void DrawMesh(NxShape* mesh) +{ + if(mesh->userData == NULL) return; + + NxMat34 pose = mesh->getGlobalPose(); + + NxTriangleMeshDesc meshDesc = *((NxTriangleMeshDesc*)(mesh->userData)); +// mesh->isTriangleMesh()->getTriangleMesh().saveToDesc(meshDesc); + + NxU32 nbVerts = meshDesc.numVertices; + NxU32 nbTriangles = meshDesc.numTriangles; + + Point* points = (Point *)meshDesc.points; + Triangle* triangles = (Triangle *)meshDesc.triangles; + + glPushMatrix(); + + float glmat[16]; //4x4 column major matrix for OpenGL. + pose.M.getColumnMajorStride4(&(glmat[0])); + pose.t.get(&(glmat[12])); + + //clear the elements we don't need: + glmat[3] = glmat[7] = glmat[11] = 0.0f; + glmat[15] = 1.0f; + + glMultMatrixf(&(glmat[0])); + + if(meshDesc.heightFieldVerticalAxis != NX_NOT_HEIGHTFIELD) + { + glDisable(GL_LIGHT0); + glEnable(GL_LIGHT1); + } + + DrawTriangleList(nbTriangles, triangles, points); + + if(meshDesc.heightFieldVerticalAxis != NX_NOT_HEIGHTFIELD) + { + glDisable(GL_LIGHT1); + glEnable(GL_LIGHT0); + } + + glPopMatrix(); +} + +void DrawWheelShape(NxShape* wheel) +{ + if(wheel->is(NX_SHAPE_WHEEL) != NULL) + { + NxWheelShape* wheelShape = (NxWheelShape*)wheel; + glPushMatrix(); + + float glmat[16]; + wheel->getGlobalPose().getColumnMajor44(glmat); + + NxWheelShapeDesc wheelShapeDesc; + + float r = wheelShape->getRadius(); + float a = wheelShape->getSteerAngle(); + + glMultMatrixf(&(glmat[0])); + glTranslatef(-r/2,0,0); + glRotatef(90,0,1,0); + glRotatef(NxMath::radToDeg(a),0,1,0); + + glScalef(r, r, r); + RenderCylinder(); + glPopMatrix(); + } +} + +void DrawArrow(const NxVec3& posA, const NxVec3& posB, const NxVec3& color) +{ + NxVec3 vec = posB - posA; + NxVec3 t0, t1, t2; + NxNormalToTangents(vec, t1, t2); + + t0 = posB - posA; + t0.normalize(); + + NxVec3 lobe1 = posB - t0*0.15 + t1 * 0.15; + NxVec3 lobe2 = posB - t0*0.15 - t1 * 0.15; + NxVec3 lobe3 = posB - t0*0.15 + t2 * 0.15; + NxVec3 lobe4 = posB - t0*0.15 - t2 * 0.15; + + NxVec3 v3ArrowShape[] = { + NxVec3(posA), NxVec3(posB), + NxVec3(posB), NxVec3(lobe1), + NxVec3(posB), NxVec3(lobe2), + NxVec3(posB), NxVec3(lobe3), + NxVec3(posB), NxVec3(lobe4), + }; + + glDisable(GL_LIGHTING); + glLineWidth(3.0f); + glColor4f(color.x,color.y,color.z,1.0f); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &v3ArrowShape[0].x); + glDrawArrays(GL_LINES, 0, sizeof(v3ArrowShape)/sizeof(NxVec3)); + glDisableClientState(GL_VERTEX_ARRAY); + glColor4f(1.0f,1.0f,1.0f,1.0f); +} + +void DrawContactPoint(const NxVec3& pos, const NxReal radius, const NxVec3& color) +{ + NxMat34 pose; + pose.t = pos; + + NxVec3 c0; pose.M.getColumn(0, c0); + NxVec3 c1; pose.M.getColumn(1, c1); + NxVec3 c2; pose.M.getColumn(2, c2); + DrawCircle(20, pose, color, radius); + + pose.M.setColumn(0, c1); + pose.M.setColumn(1, c2); + pose.M.setColumn(2, c0); + DrawCircle(20, pose, color, radius); + + pose.M.setColumn(0, c2); + pose.M.setColumn(1, c0); + pose.M.setColumn(2, c1); + DrawCircle(20, pose, color, radius); +} + +void DrawWireShape(NxShape *shape, const NxVec3& color) +{ + switch(shape->getType()) + { + case NX_SHAPE_PLANE: + DrawWirePlane(shape, color); + break; + case NX_SHAPE_BOX: + DrawWireBox(shape, color); + break; + case NX_SHAPE_SPHERE: + DrawWireSphere(shape, color); + break; + case NX_SHAPE_CAPSULE: + DrawWireCapsule(shape, color); + break; + case NX_SHAPE_CONVEX: + DrawWireConvex(shape, color); + break; + case NX_SHAPE_MESH: + DrawWireMesh(shape, color); + break; + } +} + +void DrawShape(NxShape* shape) +{ + switch(shape->getType()) + { + case NX_SHAPE_PLANE: + DrawPlane(shape); + break; + case NX_SHAPE_BOX: + DrawBox(shape); + break; + case NX_SHAPE_SPHERE: + DrawSphere(shape); + break; + case NX_SHAPE_CAPSULE: + DrawCapsule(shape); + break; + case NX_SHAPE_CONVEX: + DrawConvex(shape); + break; + case NX_SHAPE_MESH: + DrawMesh(shape); + break; + case NX_SHAPE_WHEEL: + DrawWheelShape(shape); + break; + } +} + +void DrawActor(NxActor* actor, NxActor* gSelectedActor) +{ + NxShape*const* shapes = actor->getShapes(); + NxU32 nShapes = actor->getNbShapes(); + if (actor == gSelectedActor) + { + while (nShapes--) + { + DrawWireShape(shapes[nShapes], NxVec3(1,1,1)); + } + } + nShapes = actor->getNbShapes(); + while (nShapes--) + { + DrawShape(shapes[nShapes]); + } +} + +void DrawWireActor(NxActor* actor) +{ + NxShape*const* shapes = actor->getShapes(); + NxU32 nShapes = actor->getNbShapes(); + nShapes = actor->getNbShapes(); + while (nShapes--) + { + DrawWireShape(shapes[nShapes], NxVec3(1,1,1)); + } +} + +static void DrawActorShadow(NxActor* actor, const float* ShadowMat) +{ + glPushMatrix(); + glMultMatrixf(ShadowMat); + + glDisable(GL_LIGHTING); + glColor4f(0.05f, 0.1f, 0.15f, 1.0f); + + NxShape*const* shapes = actor->getShapes(); + NxU32 nShapes = actor->getNbShapes(); + while (nShapes--) + { + switch(shapes[nShapes]->getType()) + { + case NX_SHAPE_BOX: + DrawBox(shapes[nShapes]); + break; + case NX_SHAPE_SPHERE: + DrawSphere(shapes[nShapes]); + break; + case NX_SHAPE_CAPSULE: + DrawCapsule(shapes[nShapes]); + break; + case NX_SHAPE_CONVEX: + DrawConvex(shapes[nShapes]); + break; + } + } + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_LIGHTING); + + glPopMatrix(); +} + + +void DrawActorShadow(NxActor* actor) +{ + const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 }; + DrawActorShadow(actor, ShadowMat); +} + +void DrawActorShadow2(NxActor* actor) +{ + const static float ShadowMat[]={ 1,0,0,0, 1,0,-0.2,0, 0,0,1,0, 0,0,0,1 }; + DrawActorShadow(actor, ShadowMat); +} + +void DrawActorShadowZUp(NxActor* actor) +{ + const static float ShadowMat[]={ 1,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,1 }; + DrawActorShadow(actor, ShadowMat); +} + +void DrawCloth(NxCloth *cloth, bool shadows) +{ + NxMeshData meshData = cloth->getMeshData(); + + NxU32 numVertices = *meshData.numVerticesPtr; + NxU32 numTriangles = *meshData.numIndicesPtr / 3; + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, meshData.verticesPosBegin); + glNormalPointer(GL_FLOAT, 0, meshData.verticesNormalBegin); + +#ifdef __CELLOS_LV2__ + glDrawRangeElements(GL_TRIANGLES, 0, numVertices-1, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin); +#else + glDrawElements(GL_TRIANGLES, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin); +#endif + + if (shadows) { + const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 }; + glPushMatrix(); + glMultMatrixf(ShadowMat); + glDisable(GL_LIGHTING); + glColor4f(0.05f, 0.1f, 0.15f,1.0f); + +#ifdef __CELLOS_LV2__ + glDrawRangeElements(GL_TRIANGLES, 0, numVertices-1, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin); +#else + glDrawElements(GL_TRIANGLES, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin); +#endif + + glColor4f(1.0f, 1.0f, 1.0f,1.0f); + glEnable(GL_LIGHTING); + glPopMatrix(); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); +} + +#ifdef WIN32 +#include +typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int ); +PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0; +int vsyncState = 1; +#endif + +void toggleVSync() +{ +#ifdef WIN32 + if (wglSwapIntervalEXT == NULL) + { + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + if (strstr(extensions, "WGL_EXT_swap_control") != 0) + { + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" ); + } + } + if (wglSwapIntervalEXT != NULL) + { + vsyncState = 1 - vsyncState; + wglSwapIntervalEXT(vsyncState); + } +#endif +} +#endif diff --git a/Extras/CDTestFramework/RenderingHelpers.h b/Extras/CDTestFramework/RenderingHelpers.h new file mode 100644 index 0000000..24dcfb7 --- /dev/null +++ b/Extras/CDTestFramework/RenderingHelpers.h @@ -0,0 +1,26 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef RENDERINGHELPERS_H +#define RENDERINGHELPERS_H + +#include "Opcode.h" + + void DrawLine(const Point& p0, const Point& p1, const Point& color, float line_width); + void DrawTriangle(const Point& p0, const Point& p1, const Point& p2, const Point& color); + void DrawSphere(const Sphere& sphere); + void DrawOBB(const OBB& obb); + void DrawCapsule(const Matrix4x4& world, const Point& p0, const Point& p1, float r); + +#endif // RENDERINGHELPERS_H diff --git a/Extras/CDTestFramework/SphereMeshQuery.cpp b/Extras/CDTestFramework/SphereMeshQuery.cpp new file mode 100644 index 0000000..e78eadb --- /dev/null +++ b/Extras/CDTestFramework/SphereMeshQuery.cpp @@ -0,0 +1,141 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "stdafx.h" +#include "RenderingHelpers.h" +#include "IceHelpers.h" +#include "SphereMeshQuery.h" +#include "Terrain.h" +#include "Profiling.h" +#include "Camera.h" +#include "GLFontRenderer.h" + +SphereMeshQuery::SphereMeshQuery() : + mBar (null), + mDist (0.0f), + mValidHit (false) +{ +} + +SphereMeshQuery::~SphereMeshQuery() +{ +} + +void SphereMeshQuery::Init() +{ + mSphere.mCenter = Point(0.0f, 0.0f, 0.0f); + mSphere.mRadius = 1.0f; +} + +void SphereMeshQuery::Release() +{ + Deselect(); +} + +void SphereMeshQuery::Select() +{ + // Create a tweak bar + { + mBar = TwNewBar("SphereMeshQuery"); + TwAddVarRW(mBar, "Radius", TW_TYPE_FLOAT, &mSphere.mRadius, " min=0.01 max=200.0 step=0.05"); + + mSettings.AddToTweakBar(mBar); +// mProfiler.AddToTweakBar(mBar); + } +} + +void SphereMeshQuery::Deselect() +{ + if(mBar) + { + TwDeleteBar(mBar); + mBar = null; + } +} + +void SphereMeshQuery::PerformTest() +{ + RenderTerrain(); + + DrawSphere(mSphere); + + // OPCODE query + const Model* TM = GetTerrainModel(); + if(TM) + { + SphereCollider Collider; + mSettings.SetupCollider(Collider); + + mProfiler.Start(); + bool Status = Collider.Collide(mCache, mSphere, *TM, null, null); + mProfiler.End(); + mProfiler.Accum(); + + if(Status) + { + if(Collider.GetContactStatus()) + { + udword NbTris = Collider.GetNbTouchedPrimitives(); + const udword* Indices = Collider.GetTouchedPrimitives(); + + RenderTerrainTriangles(NbTris, Indices); + } + } + } + + // Raycast hit + if(mValidHit) + { + Point wp = mLocalHit + mSphere.mCenter; + DrawLine(wp, wp + Point(1.0f, 0.0f, 0.0f), Point(1,0,0), 1.0f); + DrawLine(wp, wp + Point(0.0f, 1.0f, 0.0f), Point(0,1,0), 1.0f); + DrawLine(wp, wp + Point(0.0f, 0.0f, 1.0f), Point(0,0,1), 1.0f); + } + + char Buffer[4096]; + sprintf(Buffer, "Sphere-mesh query = %5.1f us (%d cycles)\n", mProfiler.mMsTime, mProfiler.mCycles); + GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer); +} + +void SphereMeshQuery::KeyboardCallback(unsigned char key, int x, int y) +{ +} + +void SphereMeshQuery::MouseCallback(int button, int state, int x, int y) +{ + mValidHit = false; + if(!button && !state) + { + Point Dir = ComputeWorldRay(x, y); + + float d; + Point hit; + if(SegmentSphere(GetCameraPos(), Dir, 10000.0f, mSphere.mCenter, mSphere.mRadius, d, hit)) + { + mValidHit = true; + mDist = d; + mLocalHit = hit - mSphere.mCenter; + } + } +} + +void SphereMeshQuery::MotionCallback(int x, int y) +{ + if(mValidHit) + { + Point Dir = ComputeWorldRay(x, y); + mSphere.mCenter = GetCameraPos() + Dir*mDist - mLocalHit; + } +} diff --git a/Extras/CDTestFramework/SphereMeshQuery.h b/Extras/CDTestFramework/SphereMeshQuery.h new file mode 100644 index 0000000..e03eee7 --- /dev/null +++ b/Extras/CDTestFramework/SphereMeshQuery.h @@ -0,0 +1,48 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef SPHEREMESHQUERY_H +#define SPHEREMESHQUERY_H + +#include "CollisionTest.h" +#include "Profiling.h" + + class SphereMeshQuery : public CollisionTest + { + public: + SphereMeshQuery(); + virtual ~SphereMeshQuery(); + + virtual void Init(); + virtual void Release(); + virtual void PerformTest(); + virtual void Select(); + virtual void Deselect(); + virtual void KeyboardCallback(unsigned char key, int x, int y); + virtual void MouseCallback(int button, int state, int x, int y); + virtual void MotionCallback(int x, int y); + + TwBar* mBar; //!< AntTweakBar + Sphere mSphere; + + SphereCache mCache; + OpcodeSettings mSettings; + Profiler mProfiler; + + float mDist; + Point mLocalHit; + bool mValidHit; + }; + +#endif // SPHEREMESHQUERY_H diff --git a/Extras/CDTestFramework/Terrain.cpp b/Extras/CDTestFramework/Terrain.cpp new file mode 100644 index 0000000..c849ce3 --- /dev/null +++ b/Extras/CDTestFramework/Terrain.cpp @@ -0,0 +1,470 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include "stdafx.h" +#include "Terrain.h" + +inline float NxAngle(const Point& v0, const Point& v1) + { + float cos = v0|v1; // |v0|*|v1|*Cos(Angle) + float sin = (v0^v1).Magnitude(); // |v0|*|v1|*Sin(Angle) + return ::atan2(sin, cos); + } + +static float computeAngle(const Point* verts, const udword* refs, udword vref) +{ + udword e0=0,e2=0; + if(vref==refs[0]) + { + e0 = 2; + e2 = 1; + } + else if(vref==refs[1]) + { + e0 = 2; + e2 = 0; + } + else if(vref==refs[2]) + { + e0 = 0; + e2 = 1; + } + else + { + assert(0); + } + Point edge0 = verts[refs[e0]] - verts[vref]; + Point edge1 = verts[refs[e2]] - verts[vref]; + + return NxAngle(edge0, edge1); +} +static bool buildSmoothNormals( + udword nbTris, udword nbVerts, + const Point* verts, + const udword* dFaces, const uword* wFaces, + Point* normals, + bool flip) + { + // Checkings + if(!verts || !normals || !nbTris || !nbVerts) return false; + + // Get correct destination buffers + // - if available, write directly to user-provided buffers + // - else get some ram and keep track of it + Point* FNormals = new Point[nbTris]; + if(!FNormals) return false; + + // Compute face normals + udword c = (flip!=0); + for(udword i=0;i>=1; + if(!currentSize) return; + + // Compute new heights + float v0 = (value * float(rand()-RAND_MAX_OVER_TWO) * ONE_OVER_RAND_MAX); + float v1 = (value * float(rand()-RAND_MAX_OVER_TWO) * ONE_OVER_RAND_MAX); + float v2 = (value * float(rand()-RAND_MAX_OVER_TWO) * ONE_OVER_RAND_MAX); + float v3 = (value * float(rand()-RAND_MAX_OVER_TWO) * ONE_OVER_RAND_MAX); + float v4 = (value * float(rand()-RAND_MAX_OVER_TWO) * ONE_OVER_RAND_MAX); + + udword x1 = (x0+currentSize) % initSize; + udword x2 = (x0+currentSize+currentSize) % initSize; + udword y1 = (y0+currentSize) % initSize; + udword y2 = (y0+currentSize+currentSize) % initSize; + + if(!done[x1 + y0*initSize]) field[x1 + y0*initSize].y = v0 + 0.5f * (field[x0 + y0*initSize].y + field[x2 + y0*initSize].y); + if(!done[x0 + y1*initSize]) field[x0 + y1*initSize].y = v1 + 0.5f * (field[x0 + y0*initSize].y + field[x0 + y2*initSize].y); + if(!done[x2 + y1*initSize]) field[x2 + y1*initSize].y = v2 + 0.5f * (field[x2 + y0*initSize].y + field[x2 + y2*initSize].y); + if(!done[x1 + y2*initSize]) field[x1 + y2*initSize].y = v3 + 0.5f * (field[x0 + y2*initSize].y + field[x2 + y2*initSize].y); + if(!done[x1 + y1*initSize]) field[x1 + y1*initSize].y = v4 + 0.5f * (field[x0 + y1*initSize].y + field[x2 + y1*initSize].y); + + done[x1 + y0*initSize] = true; + done[x0 + y1*initSize] = true; + done[x2 + y1*initSize] = true; + done[x1 + y2*initSize] = true; + done[x1 + y1*initSize] = true; + + // Recurse through 4 corners + value *= 0.5f; + _Compute(done, field, x0, y0, currentSize, value, initSize); + _Compute(done, field, x0, y1, currentSize, value, initSize); + _Compute(done, field, x1, y0, currentSize, value, initSize); + _Compute(done, field, x1, y1, currentSize, value, initSize); + } + }; + + // Fractalize + srand(42); + bool* done = new bool[nbVerts]; + memset(done,0,nbVerts*sizeof(bool)); + verts[0].y = 10.0f; + verts[size-1].y = 10.0f; + verts[size*(size-1)].y = 10.0f; + verts[nbVerts-1].y = 10.0f; + Local::_Compute(done, verts, 0, 0, size, chaos, size); + for(udword i=0;iinit(TERRAIN_SIZE, TERRAIN_OFFSET, TERRAIN_WIDTH, TERRAIN_CHAOS); + + // Build OPCODE model + + gMeshInterface.SetNbTriangles(gTerrainData->nbFaces); + gMeshInterface.SetNbVertices(gTerrainData->nbVerts); + gMeshInterface.SetPointers((const IndexedTriangle*)gTerrainData->faces, gTerrainData->verts); + + OPCODECREATE Create; + Create.mIMesh = &gMeshInterface; + Create.mSettings.mLimit = 1; + Create.mSettings.mRules = SPLIT_SPLATTER_POINTS|SPLIT_GEOM_CENTER; + Create.mNoLeaf = true; + Create.mQuantized = true; + Create.mKeepOriginal = false; + Create.mCanRemap = false; + + gOpcodeModel = new Model; + if(!gOpcodeModel->Build(Create)) + { + } +} + +void RenderTerrain() +{ + if(gTerrainData) + renderTerrain(*gTerrainData, true); +} + +void RenderTerrainTriangles(udword nbTriangles, const udword* indices) +{ + if(gTerrainData) + renderTerrainTriangles(*gTerrainData, nbTriangles, indices); +} diff --git a/Extras/CDTestFramework/Terrain.h b/Extras/CDTestFramework/Terrain.h new file mode 100644 index 0000000..3f5f6f2 --- /dev/null +++ b/Extras/CDTestFramework/Terrain.h @@ -0,0 +1,47 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef TERRAIN_H +#define TERRAIN_H + + class TerrainData + { + public: + TerrainData(); + ~TerrainData(); + + void init(udword size, float offset, float width, float chaos, bool flat=false, const Point* pos=NULL); + void release(); + + udword size; + udword nbVerts; + udword nbFaces; + float offset; + float width; + float chaos; + Point* verts; + Point* colors; + Point* normals; + udword* faces; + }; + + void CreateTerrain(); + void ReleaseTerrain(); + + void RenderTerrain(); + void RenderTerrainTriangles(udword nbTriangles, const udword* indices); + + const Model* GetTerrainModel(); + +#endif diff --git a/Extras/CDTestFramework/convex1.bin b/Extras/CDTestFramework/convex1.bin new file mode 100644 index 0000000000000000000000000000000000000000..c7958bd36d37a97a119dfc3b285a8174d94740a0 GIT binary patch literal 2924 zcmYjRYfO~a7X8FwUD`M#wdshO`2$$ zs@L1g1!;fSq$;As*3S8;HGSDyQz|r2Ypd1PTJKHlBR8?uyH}mvX!3>QI&1H}_Bwmd zZbeay@{}#C+MqVw>$UM&WOh03{%g_d(`QoT3y*eV6 z-0Tq_r%#IC91Y@8W{|k{-eciYXcO+APKjS^cJa{jknk*iBG!GLA}oVJBINKLp)2bb zF~^VFY#x_IiN^)uxMKaA(|6rpa_q^lgOWLmA0udQdGZW4F~q7 zNY+;UpjP%=IO2eQaGFaKCG;aUd(A-!{ovd(2T15gY;ew`gnnqyef(HLKeVN~->)I>x9EjEN00n=uat~Re$!nO-${OJ z`|-z;XQ0Y^Qt}M%&o^j1+kD0h;|va;`K^(YX8^T$HjtBN2DNTP7*(EOoO!nSj2UJQ z&b({L$vcQzyqn0$JBwPpJK*q6A(nRy9Nt013i^%KDatgL>2#of`_(@$`VEIw8#JAw zbJe>IB=?C^{)MWyqNw_7K-~>Sk9P?%5K=?8CO0FYGdyR`0_skvJ-JW5a0%SmUMBB1 zoEc1tqMa`VI%lqrZwGNs6W@=}Fkhha=KJ|m2F;B!)YI*Q0H6U20)rfc>IrS6Og&9N zgF_aEBEwsh!JlqAj{pq|k685j)2E`1cwf^^Qwo$Vj*ME;E%oQQKl()?G&*K!EOBM4 zlUqN53~}ao3wfYrVn`e6XgZrj1dC)udyLswMg$Z@NvW z*GU7=F9}WF4KyP&E4z~-uTdvg>2}|CpgGHyugHBCtxXX6pG2U!dHDsGh)4cv)UiC= z1q~}#tuD-Wa>uFaKmYQ#sJNum*_UPxjyaEw)G1|a)~_1K5a&8oe4p}0{}0tR)zsQ2>3_?K_XXY9ih$PDH#8RCZyDx_*ae-^ z)ZEhg1*wNR>R40H0o~lTr5)2W?dLjjR8eTA3EjGFd&eMg;rdPDZtVbf$Ii}O{Zy^R ziMDwe=)I>e4AHqMBRhJAeh+U~qlZSsCwugSyM`@t_t2}Kd8;M#EugRO5pctnwi&aG z6U4nr+@`X!_^P|WJ-2qu_MVwQynOoNKJ(UU>VbRB@pYMI3QZm#`i){@heqVSP~dYr zch2+oi6UMO@iXXe%CD}3&yTYN1o=G-Z`Ud)zw6n(=G>*=FIXBA92!XZwF2VD(zoXT z@bJY;($$C<;*PZxn$g4hY&XIqqhnK3qLQdy#6Hv6UkPu10=_x7AR#&4nO}MxE<8Kd z2|RK6GHY5=8s$%Y_Nn8)1Gi;lm#q`as9q-Fk@WXzBl2hFtSBkY^75I2ZyM^KwgS)F zWM5gBkNz$6kyh>1X5?8_wXvvlbzbTWGx?y!lP>#rz}J*lZf;-u)iXckxsJK#?#Ccc z#fIvZ=JljSg&yd7XA=CH9lPopYx^iZtLN6)Zz7mk43LidT5sGf!au6g zYeq$J(|Z_a&Ga@+t2(Mztye144Z#5QNE@uJFD1P zOIz6a+EDKq+*PewX|HW;Xl`A1Sb#cL<6 zh}&LYx2tpR9Ix3OhhFpG9<;dGh}%)KDKFO?H-Fwviql;G?Q1EaxQS5QZ85knicrP6 Swe8S;;=d*6L(O?x(f$twJl7Kd literal 0 HcmV?d00001 diff --git a/Extras/CDTestFramework/stdafx.cpp b/Extras/CDTestFramework/stdafx.cpp new file mode 100644 index 0000000..b4e1e25 --- /dev/null +++ b/Extras/CDTestFramework/stdafx.cpp @@ -0,0 +1,23 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +// stdafx.cpp : source file that includes just the standard includes +// CDTestFramework.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Extras/CDTestFramework/stdafx.h b/Extras/CDTestFramework/stdafx.h new file mode 100644 index 0000000..64535de --- /dev/null +++ b/Extras/CDTestFramework/stdafx.h @@ -0,0 +1,23 @@ +/* +CDTestFramework http://codercorner.com +Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include // For _alloca +#include +#include "GL/glut.h" +#include "AntTweakBar.h" + +#include "Opcode.h" +using namespace Opcode; diff --git a/Extras/CMakeLists.txt b/Extras/CMakeLists.txt new file mode 100644 index 0000000..a92f647 --- /dev/null +++ b/Extras/CMakeLists.txt @@ -0,0 +1,7 @@ +SUBDIRS( Serialize ConvexDecomposition HACD GIMPACTUtils ) + +#Maya Dynamica plugin is moved to http://dynamica.googlecode.com + +IF (USE_GLUT AND GLUT_FOUND) + SUBDIRS (glui) +ENDIF () diff --git a/Extras/CUDA/btCudaBroadphase.cpp b/Extras/CUDA/btCudaBroadphase.cpp new file mode 100644 index 0000000..3f835d1 --- /dev/null +++ b/Extras/CUDA/btCudaBroadphase.cpp @@ -0,0 +1,207 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btQuickprof.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" + +#include "btCudaBroadphase.h" +#include "radixsort.cuh" + + + +#define BT_GPU_PREF(func) btCuda_##func +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "../../src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedDefs.h" +#undef BT_GPU_PREF + +extern "C" void btCuda_setParameters(bt3DGridBroadphaseParams* hostParams); + + + +#include + + + + +btCudaBroadphase::btCudaBroadphase( btOverlappingPairCache* overlappingPairCache, + const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerSmallProxy, + int maxSmallProxiesPerCell) : + btGpu3DGridBroadphase(overlappingPairCache, worldAabbMin, worldAabbMax, gridSizeX, gridSizeY, gridSizeZ, maxSmallProxies, maxLargeProxies, maxPairsPerSmallProxy, maxSmallProxiesPerCell) +{ + _initialize(); +} + + + +btCudaBroadphase::~btCudaBroadphase() +{ + //btSimpleBroadphase will free memory of btSortedOverlappingPairCache, because m_ownsPairCache + assert(m_bInitialized); + _finalize(); +} + + + +void btCudaBroadphase::_initialize() +{ + // allocate GPU data + btCuda_allocateArray((void**)&m_dBodiesHash[0], m_maxHandles * 2 * sizeof(unsigned int)); + btCuda_allocateArray((void**)&m_dBodiesHash[1], m_maxHandles * 2 * sizeof(unsigned int)); + + btCuda_allocateArray((void**)&m_dCellStart, m_params.m_numCells * sizeof(unsigned int)); + + btCuda_allocateArray((void**)&m_dPairBuff, m_maxHandles * m_maxPairsPerBody * sizeof(unsigned int)); + btCuda_copyArrayToDevice(m_dPairBuff, m_hPairBuff, m_maxHandles * m_maxPairsPerBody * sizeof(unsigned int)); // needed? + + btCuda_allocateArray((void**)&m_dPairBuffStartCurr, (m_maxHandles * 2 + 1) * sizeof(unsigned int)); + btCuda_copyArrayToDevice(m_dPairBuffStartCurr, m_hPairBuffStartCurr, (m_maxHandles * 2 + 1) * sizeof(unsigned int)); + + unsigned int numAABB = m_maxHandles + m_maxLargeHandles; + btCuda_allocateArray((void**)&m_dAABB, numAABB * sizeof(bt3DGrid3F1U) * 2); + + btCuda_allocateArray((void**)&m_dPairScan, (m_maxHandles + 1) * sizeof(unsigned int)); + + btCuda_allocateArray((void**)&m_dPairOut, m_maxHandles * m_maxPairsPerBody * sizeof(unsigned int)); +} + + + +void btCudaBroadphase::_finalize() +{ + assert(m_bInitialized); + btCuda_freeArray(m_dBodiesHash[0]); + btCuda_freeArray(m_dBodiesHash[1]); + btCuda_freeArray(m_dCellStart); + btCuda_freeArray(m_dPairBuffStartCurr); + btCuda_freeArray(m_dAABB); + btCuda_freeArray(m_dPairBuff); + btCuda_freeArray(m_dPairScan); + btCuda_freeArray(m_dPairOut); +} + + + +// +// overrides for CUDA version +// + + + +void btCudaBroadphase::prepareAABB() +{ + btGpu3DGridBroadphase::prepareAABB(); + btCuda_copyArrayToDevice(m_dAABB, m_hAABB, sizeof(bt3DGrid3F1U) * 2 * (m_numHandles + m_numLargeHandles)); + return; +} + + + +void btCudaBroadphase::setParameters(bt3DGridBroadphaseParams* hostParams) +{ + btCuda_setParameters(hostParams); + return; +} + + + +void btCudaBroadphase::calcHashAABB() +{ + BT_PROFILE("btCuda_calcHashAABB"); + btCuda_calcHashAABB(m_dAABB, m_dBodiesHash[0], m_numHandles); +// btCuda_copyArrayFromDevice((void*)m_hBodiesHash, (void*)m_dBodiesHash[0], sizeof(unsigned int) * 2 * m_numHandles); + return; +} + + + +void btCudaBroadphase::sortHash() +{ + BT_PROFILE("RadixSort-- CUDA"); + RadixSort((KeyValuePair*)m_dBodiesHash[0], (KeyValuePair*)m_dBodiesHash[1], m_numHandles, 32); + return; +} + + + +void btCudaBroadphase::findCellStart() +{ + BT_PROFILE("btCuda_findCellStart"); + btCuda_findCellStart(m_dBodiesHash[0], m_dCellStart, m_numHandles, m_params.m_numCells); +// btCuda_copyArrayFromDevice((void*)m_hBodiesHash, (void*)m_dBodiesHash[0], sizeof(unsigned int) * 2 * m_numHandles); +// btCuda_copyArrayFromDevice((void*)m_hCellStart, (void*)m_dCellStart, sizeof(unsigned int) * m_params.m_numCells); + return; +} + + + +void btCudaBroadphase::findOverlappingPairs() +{ + BT_PROFILE("btCuda_findOverlappingPairs"); + btCuda_findOverlappingPairs(m_dAABB, m_dBodiesHash[0], m_dCellStart, m_dPairBuff, m_dPairBuffStartCurr, m_numHandles); + return; +} + + + +void btCudaBroadphase::findPairsLarge() +{ + BT_PROFILE("btCuda_findPairsLarge"); + btCuda_findPairsLarge(m_dAABB, m_dBodiesHash[0], m_dCellStart, m_dPairBuff, m_dPairBuffStartCurr, m_numHandles, m_numLargeHandles); + return; +} + + + +void btCudaBroadphase::computePairCacheChanges() +{ + BT_PROFILE("btCuda_computePairCacheChanges"); + btCuda_computePairCacheChanges(m_dPairBuff, m_dPairBuffStartCurr, m_dPairScan, m_dAABB, m_numHandles); + return; +} + + + +void btCudaBroadphase::scanOverlappingPairBuff() +{ + btCuda_copyArrayFromDevice(m_hPairScan, m_dPairScan, sizeof(unsigned int)*(m_numHandles + 1)); + btGpu3DGridBroadphase::scanOverlappingPairBuff(); + btCuda_copyArrayToDevice(m_dPairScan, m_hPairScan, sizeof(unsigned int)*(m_numHandles + 1)); + return; +} + + + +void btCudaBroadphase::squeezeOverlappingPairBuff() +{ + BT_PROFILE("btCuda_squeezeOverlappingPairBuff"); + btCuda_squeezeOverlappingPairBuff(m_dPairBuff, m_dPairBuffStartCurr, m_dPairScan, m_dPairOut, m_dAABB, m_numHandles); + btCuda_copyArrayFromDevice(m_hPairOut, m_dPairOut, sizeof(unsigned int) * m_hPairScan[m_numHandles]); + return; +} + + + +void btCudaBroadphase::resetPool(btDispatcher* dispatcher) +{ + btGpu3DGridBroadphase::resetPool(dispatcher); + btCuda_copyArrayToDevice(m_dPairBuffStartCurr, m_hPairBuffStartCurr, (m_maxHandles * 2 + 1) * sizeof(unsigned int)); +} + + diff --git a/Extras/CUDA/btCudaBroadphase.cu b/Extras/CUDA/btCudaBroadphase.cu new file mode 100644 index 0000000..41e4c94 --- /dev/null +++ b/Extras/CUDA/btCudaBroadphase.cu @@ -0,0 +1,74 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include + +#include "cutil_math.h" +#include "math_constants.h" + + +#include + + + +#include "btCudaDefines.h" + + + +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "../../src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedDefs.h" + + + +__device__ inline bt3DGrid3F1U tex_fetch3F1U(float4 a) { return *((bt3DGrid3F1U*)(&a)); } + + + +void btCuda_exit(int val); + + + +texture particleHashTex; +texture cellStartTex; +texture pAABBTex; + + + +__constant__ bt3DGridBroadphaseParams params; + + + +extern "C" +{ + + + +void btCuda_setParameters(bt3DGridBroadphaseParams* hostParams) +{ + // copy parameters to constant memory + BT_GPU_SAFE_CALL(cudaMemcpyToSymbol(params, hostParams, sizeof(bt3DGridBroadphaseParams))); +} + + + +} // extern "C" + + + +#include "../../src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedCode.h" + + diff --git a/Extras/CUDA/btCudaBroadphase.h b/Extras/CUDA/btCudaBroadphase.h new file mode 100644 index 0000000..8e24e22 --- /dev/null +++ b/Extras/CUDA/btCudaBroadphase.h @@ -0,0 +1,69 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef CUDA_BROADPHASE_H +#define CUDA_BROADPHASE_H + + + +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" + +#include "../../src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedTypes.h" +#include "../../src/BulletMultiThreaded/btGpu3DGridBroadphase.h" + + + +///The btCudaBroadphase uses CUDA-capable GPU to compute overlapping pairs + +class btCudaBroadphase : public btGpu3DGridBroadphase +{ +protected: + // GPU data + unsigned int* m_dBodiesHash[2]; + unsigned int* m_dCellStart; + unsigned int* m_dPairBuff; + unsigned int* m_dPairBuffStartCurr; + bt3DGrid3F1U* m_dAABB; + unsigned int* m_dPairScan; + unsigned int* m_dPairOut; +public: + btCudaBroadphase( btOverlappingPairCache* overlappingPairCache, + const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerSmallProxies, + int maxSmallProxiesPerCell = 8); + virtual ~btCudaBroadphase(); +protected: + void _initialize(); + void _finalize(); + void allocateArray(void** devPtr, unsigned int size); + void freeArray(void* devPtr); +// overrides for CUDA version + virtual void setParameters(bt3DGridBroadphaseParams* hostParams); + virtual void prepareAABB(); + virtual void calcHashAABB(); + virtual void sortHash(); + virtual void findCellStart(); + virtual void findOverlappingPairs(); + virtual void findPairsLarge(); + virtual void computePairCacheChanges(); + virtual void scanOverlappingPairBuff(); + virtual void squeezeOverlappingPairBuff(); + virtual void resetPool(btDispatcher* dispatcher); +}; + +#endif //CUDA_BROADPHASE_H \ No newline at end of file diff --git a/Extras/CUDA/btCudaDefines.h b/Extras/CUDA/btCudaDefines.h new file mode 100644 index 0000000..aae8522 --- /dev/null +++ b/Extras/CUDA/btCudaDefines.h @@ -0,0 +1,138 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +// Common preprocessor definitions for CUDA compiler + + + +#ifndef BTCUDADEFINES_H +#define BTCUDADEFINES_H + + + +#ifdef __DEVICE_EMULATION__ + #define B_CUDA_USE_TEX 0 +#else + #define B_CUDA_USE_TEX 1 +#endif + + +#if B_CUDA_USE_TEX + #define BT_GPU_FETCH(t, i) tex_fetch3F1U(tex1Dfetch(t##Tex, i)) + #define BT_GPU_FETCH4(t, i) tex1Dfetch(t##Tex, i) +#else + #define BT_GPU_FETCH(t, i) t[i] + #define BT_GPU_FETCH4(t, i) t[i] +#endif + + + +#define BT_GPU___device__ __device__ +#define BT_GPU___devdata__ __device__ +#define BT_GPU___constant__ __constant__ +#define BT_GPU_max(a, b) max(a, b) +#define BT_GPU_min(a, b) min(a, b) +#define BT_GPU_params params +#define BT_GPU___mul24(a, b) __mul24(a, b) +#define BT_GPU___global__ __global__ +#define BT_GPU___shared__ __shared__ +#define BT_GPU___syncthreads() __syncthreads() +#define BT_GPU_make_uint2(x, y) make_uint2(x, y) +#define BT_GPU_make_int3(x, y, z) make_int3(x, y, z) +#define BT_GPU_make_float3(x, y, z) make_float3(x, y, z) +#define BT_GPU_make_float34(x) make_float3(x) +#define BT_GPU_make_float31(x) make_float3(x) +#define BT_GPU_make_float42(a, b) make_float4(a, b) +#define BT_GPU_make_float44(a, b, c, d) make_float4(a, b, c, d) +#define BT_GPU_PREF(func) btCuda_##func +#define BT_GPU_Memset cudaMemset +#define BT_GPU_MemcpyToSymbol(a, b, c) cudaMemcpyToSymbol(a, b, c) +#define BT_GPU_blockIdx blockIdx +#define BT_GPU_blockDim blockDim +#define BT_GPU_threadIdx threadIdx +#define BT_GPU_dot(a, b) dot(a, b) +#define BT_GPU_dot4(a, b) dot(a, b) +#define BT_GPU_cross(a, b) cross(a, b) +#define BT_GPU_BindTexture(a, b, c, d) cudaBindTexture(a, b, c, d) +#define BT_GPU_UnbindTexture(a) cudaUnbindTexture(a) +#define BT_GPU_EXECKERNEL(numb, numt, kfunc, args) kfunc<<>>args + + + +//! Check for CUDA error +#define BT_GPU_CHECK_ERROR(errorMessage) \ + do \ + { \ + cudaError_t err = cudaGetLastError(); \ + if(err != cudaSuccess) \ + { \ + fprintf(stderr,"Cuda error: %s in file '%s' in line %i : %s.\n",\ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err));\ + btCuda_exit(EXIT_FAILURE); \ + } \ + err = cudaThreadSynchronize(); \ + if(err != cudaSuccess) \ + { \ + fprintf(stderr,"Cuda error: %s in file '%s' in line %i : %s.\n",\ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err));\ + btCuda_exit(EXIT_FAILURE); \ + } \ + } \ + while(0) + + + +#define BT_GPU_SAFE_CALL_NO_SYNC(call) \ + do \ + { \ + cudaError err = call; \ + if(err != cudaSuccess) \ + { \ + fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \ + __FILE__, __LINE__, cudaGetErrorString( err) ); \ + btCuda_exit(EXIT_FAILURE); \ + } \ + } \ + while(0) + + + +#define BT_GPU_SAFE_CALL(call) \ + do \ + { \ + BT_GPU_SAFE_CALL_NO_SYNC(call); \ + cudaError err = cudaThreadSynchronize(); \ + if(err != cudaSuccess) \ + { \ + fprintf(stderr,"Cuda errorSync in file '%s' in line %i : %s.\n",\ + __FILE__, __LINE__, cudaGetErrorString( err) ); \ + btCuda_exit(EXIT_FAILURE); \ + } \ + } while (0) + + + +extern "C" void btCuda_exit(int val); + + + +#endif // BTCUDADEFINES_H + + + + + diff --git a/Extras/CUDA/btCudaUtils.cu b/Extras/CUDA/btCudaUtils.cu new file mode 100644 index 0000000..cdea10b --- /dev/null +++ b/Extras/CUDA/btCudaUtils.cu @@ -0,0 +1,84 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include + +#include +#include + +#include "cutil_math.h" +#include "math_constants.h" + +#include + + + + +#include "btCudaDefines.h" +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" + + +void btCuda_exit(int val) +{ + fprintf(stderr, "Press ENTER key to terminate the program\n"); + getchar(); + exit(val); +} + +void btCuda_allocateArray(void** devPtr, unsigned int size) +{ + BT_GPU_SAFE_CALL(cudaMalloc(devPtr, size)); +} + +void btCuda_freeArray(void* devPtr) +{ + BT_GPU_SAFE_CALL(cudaFree(devPtr)); +} + +void btCuda_copyArrayFromDevice(void* host, const void* device, unsigned int size) +{ + BT_GPU_SAFE_CALL(cudaMemcpy(host, device, size, cudaMemcpyDeviceToHost)); +} + +void btCuda_copyArrayToDevice(void* device, const void* host, unsigned int size) +{ + BT_GPU_SAFE_CALL(cudaMemcpy((char*)device, host, size, cudaMemcpyHostToDevice)); +} + + +void btCuda_registerGLBufferObject(unsigned int vbo) +{ + BT_GPU_SAFE_CALL(cudaGLRegisterBufferObject(vbo)); +} + +void* btCuda_mapGLBufferObject(unsigned int vbo) +{ + void *ptr; + BT_GPU_SAFE_CALL(cudaGLMapBufferObject(&ptr, vbo)); + return ptr; +} + +void btCuda_unmapGLBufferObject(unsigned int vbo) +{ + BT_GPU_SAFE_CALL(cudaGLUnmapBufferObject(vbo)); +} + + + +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedCode.h" + + diff --git a/Extras/CUDA/btGpuDemo2dCudaFunc.cu b/Extras/CUDA/btGpuDemo2dCudaFunc.cu new file mode 100644 index 0000000..aae708a --- /dev/null +++ b/Extras/CUDA/btGpuDemo2dCudaFunc.cu @@ -0,0 +1,42 @@ +/* +Impulse based Rigid body simulation using CUDA +Copyright (c) 2007 Takahiro Harada http://www.iii.u-tokyo.ac.jp/~takahiroharada/projects/impulseCUDA.html + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include + +#include "cutil_math.h" +#include "math_constants.h" + +#include + + + +#include "btCudaDefines.h" + + + +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "../../Demos/Gpu2dDemo/btGpuDemo2dSharedTypes.h" +#include "../../Demos/Gpu2dDemo/btGpuDemo2dSharedDefs.h" + + + +texture posTex; + + + +#include "../../Demos/Gpu2dDemo/btGpuDemo2dSharedCode.h" + diff --git a/Extras/CUDA/btGpuDemo3dCudaFunc.cu b/Extras/CUDA/btGpuDemo3dCudaFunc.cu new file mode 100644 index 0000000..2ce7006 --- /dev/null +++ b/Extras/CUDA/btGpuDemo3dCudaFunc.cu @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include + +#include "../../Extras/CUDA/cutil_math.h" +#include "math_constants.h" + +#include + +//---------------------------------------------------------------------------------------- + +#include "../../Extras/CUDA/btCudaDefines.h" + +//---------------------------------------------------------------------------------------- + +#include "../../src/BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "../../Demos/Gpu3dDemo/btGpuDemo3dSharedTypes.h" +#include "../../Demos/Gpu3dDemo/btGpuDemo3dSharedDefs.h" + +//---------------------------------------------------------------------------------------- + +texture posTex; + +//---------------------------------------------------------------------------------------- + +#include "../../Demos/Gpu3dDemo/btGpuDemo3dSharedCode.h" + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + diff --git a/Extras/CUDA/cutil_gl_error.h b/Extras/CUDA/cutil_gl_error.h new file mode 100644 index 0000000..3d1a5ad --- /dev/null +++ b/Extras/CUDA/cutil_gl_error.h @@ -0,0 +1,86 @@ +/* +* Copyright 1993-2006 NVIDIA Corporation. All rights reserved. +* +* NOTICE TO USER: +* +* This source code is subject to NVIDIA ownership rights under U.S. and +* international Copyright laws. +* +* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE +* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR +* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH +* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, +* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +* OR PERFORMANCE OF THIS SOURCE CODE. +* +* U.S. Government End Users. This source code is a "commercial item" as +* that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of +* "commercial computer software" and "commercial computer software +* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) +* and is provided to the U.S. Government only as a commercial end item. +* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through +* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the +* source code with only those rights set forth herein. +*/ + +#ifndef CUTIL_GL_ERROR +#define CUTIL_GL_ERROR + +/* CUda UTility Library */ + +// includes, system +#ifdef _WIN32 +# define WINDOWS_LEAN_AND_MEAN +# include +# include +# undef min +# undef max +#endif + +// includes, graphics +#if defined (__APPLE__) || defined(MACOSX) +#include +#include +#else +#include +#include +#endif + +//////////////////////////////////////////////////////////////////////////// +//! Check for OpenGL error +//! @return CUTTrue if no GL error has been encountered, otherwise 0 +//! @param file __FILE__ macro +//! @param line __LINE__ macro +//! @note The GL error is listed on stderr +//! @note This function should be used via the CHECK_ERROR_GL() macro +//////////////////////////////////////////////////////////////////////////// +CUTBoolean CUTIL_API +cutCheckErrorGL( const char* file, const int line) +{ + CUTBoolean ret_val = CUTTrue; + + // check for error + GLenum gl_error = glGetError(); + if (gl_error != GL_NO_ERROR) + { + fprintf(stderr, "GL Error in file '%s' in line %d :\n", file, line); + fprintf(stderr, "%s\n", gluErrorString(gl_error)); + ret_val = CUTFalse; + } + return ret_val; +} + +#ifdef _DEBUG + +#define CUT_CHECK_ERROR_GL() \ + if( CUTFalse == cutCheckErrorGL( __FILE__, __LINE__)) { \ + exit(EXIT_FAILURE); \ + } + +#endif // _DEBUG + +#endif // CUTIL_GL_ERROR diff --git a/Extras/CUDA/cutil_math.h b/Extras/CUDA/cutil_math.h new file mode 100644 index 0000000..55d655d --- /dev/null +++ b/Extras/CUDA/cutil_math.h @@ -0,0 +1,767 @@ + /* + * Copyright 1993-2007 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. Users and possessors of this source code + * are hereby granted a nonexclusive, royalty-free license to use this code + * in individual and commercial software. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + * + * Any use of this source code in individual and commercial software must + * include, in the user documentation and internal comments to the code, + * the above Disclaimer and U.S. Government End Users Notice. + */ + +/* + This file implements common mathematical operations on vector types + (float3, float4 etc.) since these are not provided as standard by CUDA. + + The syntax is modelled on the Cg standard library. +*/ + +#ifndef CUTIL_MATH_H +#define CUTIL_MATH_H + +#include "cuda_runtime.h" + +//////////////////////////////////////////////////////////////////////////////// +typedef unsigned int uint; +typedef unsigned short ushort; + +#ifndef __CUDACC__ +#include + +inline float fminf(float a, float b) +{ + return a < b ? a : b; +} + +inline float fmaxf(float a, float b) +{ + return a < b ? a : b; +} + +inline int max(int a, int b) +{ + return a > b ? a : b; +} + +inline int min(int a, int b) +{ + return a < b ? a : b; +} +#endif + +// float functions +//////////////////////////////////////////////////////////////////////////////// + +// lerp +inline __device__ __host__ float lerp(float a, float b, float t) +{ + return a + t*(b-a); +} + +// clamp +inline __device__ __host__ float clamp(float f, float a, float b) +{ + return fmaxf(a, fminf(f, b)); +} + +// int2 functions +//////////////////////////////////////////////////////////////////////////////// + +// negate +inline __host__ __device__ int2 operator-(int2 &a) +{ + return make_int2(-a.x, -a.y); +} + +// addition +inline __host__ __device__ int2 operator+(int2 a, int2 b) +{ + return make_int2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(int2 &a, int2 b) +{ + a.x += b.x; a.y += b.y; +} + +// subtract +inline __host__ __device__ int2 operator-(int2 a, int2 b) +{ + return make_int2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(int2 &a, int2 b) +{ + a.x -= b.x; a.y -= b.y; +} + +// multiply +inline __host__ __device__ int2 operator*(int2 a, int2 b) +{ + return make_int2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ int2 operator*(int2 a, int s) +{ + return make_int2(a.x * s, a.y * s); +} +inline __host__ __device__ int2 operator*(int s, int2 a) +{ + return make_int2(a.x * s, a.y * s); +} +inline __host__ __device__ void operator*=(int2 &a, int s) +{ + a.x *= s; a.y *= s; +} + +// float2 functions +//////////////////////////////////////////////////////////////////////////////// + +// additional constructors +inline __host__ __device__ float2 make_float2(float s) +{ + return make_float2(s, s); +} +inline __host__ __device__ float2 make_float2(int2 a) +{ + return make_float2(float(a.x), float(a.y)); +} + +// negate +inline __host__ __device__ float2 operator-(float2 &a) +{ + return make_float2(-a.x, -a.y); +} + +// addition +inline __host__ __device__ float2 operator+(float2 a, float2 b) +{ + return make_float2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(float2 &a, float2 b) +{ + a.x += b.x; a.y += b.y; +} + +// subtract +inline __host__ __device__ float2 operator-(float2 a, float2 b) +{ + return make_float2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(float2 &a, float2 b) +{ + a.x -= b.x; a.y -= b.y; +} + +// multiply +inline __host__ __device__ float2 operator*(float2 a, float2 b) +{ + return make_float2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ float2 operator*(float2 a, float s) +{ + return make_float2(a.x * s, a.y * s); +} +inline __host__ __device__ float2 operator*(float s, float2 a) +{ + return make_float2(a.x * s, a.y * s); +} +inline __host__ __device__ void operator*=(float2 &a, float s) +{ + a.x *= s; a.y *= s; +} + +// divide +inline __host__ __device__ float2 operator/(float2 a, float2 b) +{ + return make_float2(a.x / b.x, a.y / b.y); +} +inline __host__ __device__ float2 operator/(float2 a, float s) +{ + float inv = 1.0f / s; + return a * inv; +} +inline __host__ __device__ float2 operator/(float s, float2 a) +{ + float inv = 1.0f / s; + return a * inv; +} +inline __host__ __device__ void operator/=(float2 &a, float s) +{ + float inv = 1.0f / s; + a *= inv; +} + +// lerp +inline __device__ __host__ float2 lerp(float2 a, float2 b, float t) +{ + return a + t*(b-a); +} + +// clamp +inline __device__ __host__ float2 clamp(float2 v, float a, float b) +{ + return make_float2(clamp(v.x, a, b), clamp(v.y, a, b)); +} + +inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b) +{ + return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); +} + +// dot product +inline __host__ __device__ float dot(float2 a, float2 b) +{ + return a.x * b.x + a.y * b.y; +} + +// length +inline __host__ __device__ float length(float2 v) +{ + return sqrtf(dot(v, v)); +} + +// normalize +inline __host__ __device__ float2 normalize(float2 v) +{ + float invLen = 1.0f / sqrtf(dot(v, v)); + return v * invLen; +} + +// floor +inline __host__ __device__ float2 floor(const float2 v) +{ + return make_float2(floor(v.x), floor(v.y)); +} + +// reflect +inline __host__ __device__ float2 reflect(float2 i, float2 n) +{ + return i - 2.0f * n * dot(n,i); +} + +// float3 functions +//////////////////////////////////////////////////////////////////////////////// + +// additional constructors +inline __host__ __device__ float3 make_float3(float s) +{ + return make_float3(s, s, s); +} +inline __host__ __device__ float3 make_float3(float2 a) +{ + return make_float3(a.x, a.y, 0.0f); +} +inline __host__ __device__ float3 make_float3(float2 a, float s) +{ + return make_float3(a.x, a.y, s); +} +inline __host__ __device__ float3 make_float3(float4 a) +{ + return make_float3(a.x, a.y, a.z); // discards w +} +inline __host__ __device__ float3 make_float3(int3 a) +{ + return make_float3(float(a.x), float(a.y), float(a.z)); +} + +// negate +inline __host__ __device__ float3 operator-(float3 &a) +{ + return make_float3(-a.x, -a.y, -a.z); +} + +// min +static __inline__ __host__ __device__ float3 fminf(float3 a, float3 b) +{ + return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z)); +} + +// max +static __inline__ __host__ __device__ float3 fmaxf(float3 a, float3 b) +{ + return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z)); +} + +// addition +inline __host__ __device__ float3 operator+(float3 a, float3 b) +{ + return make_float3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ float3 operator+(float3 a, float b) +{ + return make_float3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ void operator+=(float3 &a, float3 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; +} + +// subtract +inline __host__ __device__ float3 operator-(float3 a, float3 b) +{ + return make_float3(a.x - b.x, a.y - b.y, a.z - b.z); +} +inline __host__ __device__ float3 operator-(float3 a, float b) +{ + return make_float3(a.x - b, a.y - b, a.z - b); +} +inline __host__ __device__ void operator-=(float3 &a, float3 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; +} + +// multiply +inline __host__ __device__ float3 operator*(float3 a, float3 b) +{ + return make_float3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ float3 operator*(float3 a, float s) +{ + return make_float3(a.x * s, a.y * s, a.z * s); +} +inline __host__ __device__ float3 operator*(float s, float3 a) +{ + return make_float3(a.x * s, a.y * s, a.z * s); +} +inline __host__ __device__ void operator*=(float3 &a, float s) +{ + a.x *= s; a.y *= s; a.z *= s; +} + +// divide +inline __host__ __device__ float3 operator/(float3 a, float3 b) +{ + return make_float3(a.x / b.x, a.y / b.y, a.z / b.z); +} +inline __host__ __device__ float3 operator/(float3 a, float s) +{ + float inv = 1.0f / s; + return a * inv; +} +inline __host__ __device__ float3 operator/(float s, float3 a) +{ + float inv = 1.0f / s; + return a * inv; +} +inline __host__ __device__ void operator/=(float3 &a, float s) +{ + float inv = 1.0f / s; + a *= inv; +} + +// lerp +inline __device__ __host__ float3 lerp(float3 a, float3 b, float t) +{ + return a + t*(b-a); +} + +// clamp +inline __device__ __host__ float3 clamp(float3 v, float a, float b) +{ + return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} + +inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b) +{ + return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} + +// dot product +inline __host__ __device__ float dot(float3 a, float3 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +// cross product +inline __host__ __device__ float3 cross(float3 a, float3 b) +{ + return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); +} + +// length +inline __host__ __device__ float length(float3 v) +{ + return sqrtf(dot(v, v)); +} + +// normalize +inline __host__ __device__ float3 normalize(float3 v) +{ + float invLen = 1.0f / sqrtf(dot(v, v)); + return v * invLen; +} + +// floor +inline __host__ __device__ float3 floor(const float3 v) +{ + return make_float3(floor(v.x), floor(v.y), floor(v.z)); +} + +// reflect +inline __host__ __device__ float3 reflect(float3 i, float3 n) +{ + return i - 2.0f * n * dot(n,i); +} + +// float4 functions +//////////////////////////////////////////////////////////////////////////////// + +// additional constructors +inline __host__ __device__ float4 make_float4(float s) +{ + return make_float4(s, s, s, s); +} +inline __host__ __device__ float4 make_float4(float3 a) +{ + return make_float4(a.x, a.y, a.z, 0.0f); +} +inline __host__ __device__ float4 make_float4(float3 a, float w) +{ + return make_float4(a.x, a.y, a.z, w); +} +inline __host__ __device__ float4 make_float4(int4 a) +{ + return make_float4(float(a.x), float(a.y), float(a.z), float(a.w)); +} + +// negate +inline __host__ __device__ float4 operator-(float4 &a) +{ + return make_float4(-a.x, -a.y, -a.z, -a.w); +} + +// min +static __inline__ __host__ __device__ float4 fminf(float4 a, float4 b) +{ + return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w)); +} + +// max +static __inline__ __host__ __device__ float4 fmaxf(float4 a, float4 b) +{ + return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w)); +} + +// addition +inline __host__ __device__ float4 operator+(float4 a, float4 b) +{ + return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +inline __host__ __device__ void operator+=(float4 &a, float4 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; +} + +// subtract +inline __host__ __device__ float4 operator-(float4 a, float4 b) +{ + return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +inline __host__ __device__ void operator-=(float4 &a, float4 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w; +} + +// multiply +inline __host__ __device__ float4 operator*(float4 a, float s) +{ + return make_float4(a.x * s, a.y * s, a.z * s, a.w * s); +} +inline __host__ __device__ float4 operator*(float s, float4 a) +{ + return make_float4(a.x * s, a.y * s, a.z * s, a.w * s); +} +inline __host__ __device__ void operator*=(float4 &a, float s) +{ + a.x *= s; a.y *= s; a.z *= s; a.w *= s; +} + +// divide +inline __host__ __device__ float4 operator/(float4 a, float4 b) +{ + return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); +} +inline __host__ __device__ float4 operator/(float4 a, float s) +{ + float inv = 1.0f / s; + return a * inv; +} +inline __host__ __device__ float4 operator/(float s, float4 a) +{ + float inv = 1.0f / s; + return a * inv; +} +inline __host__ __device__ void operator/=(float4 &a, float s) +{ + float inv = 1.0f / s; + a *= inv; +} + +// lerp +inline __device__ __host__ float4 lerp(float4 a, float4 b, float t) +{ + return a + t*(b-a); +} + +// clamp +inline __device__ __host__ float4 clamp(float4 v, float a, float b) +{ + return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); +} + +inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b) +{ + return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); +} + +// dot product +inline __host__ __device__ float dot(float4 a, float4 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +// length +inline __host__ __device__ float length(float4 r) +{ + return sqrtf(dot(r, r)); +} + +// normalize +inline __host__ __device__ float4 normalize(float4 v) +{ + float invLen = 1.0f / sqrtf(dot(v, v)); + return v * invLen; +} + +// floor +inline __host__ __device__ float4 floor(const float4 v) +{ + return make_float4(floor(v.x), floor(v.y), floor(v.z), floor(v.w)); +} + +// int3 functions +//////////////////////////////////////////////////////////////////////////////// + +// additional constructors +inline __host__ __device__ int3 make_int3(int s) +{ + return make_int3(s, s, s); +} +inline __host__ __device__ int3 make_int3(float3 a) +{ + return make_int3(int(a.x), int(a.y), int(a.z)); +} + +// negate +inline __host__ __device__ int3 operator-(int3 &a) +{ + return make_int3(-a.x, -a.y, -a.z); +} + +// min +inline __host__ __device__ int3 min(int3 a, int3 b) +{ + return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); +} + +// max +inline __host__ __device__ int3 max(int3 a, int3 b) +{ + return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); +} + +// addition +inline __host__ __device__ int3 operator+(int3 a, int3 b) +{ + return make_int3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(int3 &a, int3 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; +} + +// subtract +inline __host__ __device__ int3 operator-(int3 a, int3 b) +{ + return make_int3(a.x - b.x, a.y - b.y, a.z - b.z); +} + +inline __host__ __device__ void operator-=(int3 &a, int3 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; +} + +// multiply +inline __host__ __device__ int3 operator*(int3 a, int3 b) +{ + return make_int3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ int3 operator*(int3 a, int s) +{ + return make_int3(a.x * s, a.y * s, a.z * s); +} +inline __host__ __device__ int3 operator*(int s, int3 a) +{ + return make_int3(a.x * s, a.y * s, a.z * s); +} +inline __host__ __device__ void operator*=(int3 &a, int s) +{ + a.x *= s; a.y *= s; a.z *= s; +} + +// divide +inline __host__ __device__ int3 operator/(int3 a, int3 b) +{ + return make_int3(a.x / b.x, a.y / b.y, a.z / b.z); +} +inline __host__ __device__ int3 operator/(int3 a, int s) +{ + return make_int3(a.x / s, a.y / s, a.z / s); +} +inline __host__ __device__ int3 operator/(int s, int3 a) +{ + return make_int3(a.x / s, a.y / s, a.z / s); +} +inline __host__ __device__ void operator/=(int3 &a, int s) +{ + a.x /= s; a.y /= s; a.z /= s; +} + +// clamp +inline __device__ __host__ int clamp(int f, int a, int b) +{ + return max(a, min(f, b)); +} + +inline __device__ __host__ int3 clamp(int3 v, int a, int b) +{ + return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} + +inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b) +{ + return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} + + +// uint3 functions +//////////////////////////////////////////////////////////////////////////////// + +// additional constructors +inline __host__ __device__ uint3 make_uint3(uint s) +{ + return make_uint3(s, s, s); +} +inline __host__ __device__ uint3 make_uint3(float3 a) +{ + return make_uint3(uint(a.x), uint(a.y), uint(a.z)); +} + +// min +inline __host__ __device__ uint3 min(uint3 a, uint3 b) +{ + return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); +} + +// max +inline __host__ __device__ uint3 max(uint3 a, uint3 b) +{ + return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); +} + +// addition +inline __host__ __device__ uint3 operator+(uint3 a, uint3 b) +{ + return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(uint3 &a, uint3 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; +} + +// subtract +inline __host__ __device__ uint3 operator-(uint3 a, uint3 b) +{ + return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z); +} + +inline __host__ __device__ void operator-=(uint3 &a, uint3 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; +} + +// multiply +inline __host__ __device__ uint3 operator*(uint3 a, uint3 b) +{ + return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ uint3 operator*(uint3 a, uint s) +{ + return make_uint3(a.x * s, a.y * s, a.z * s); +} +inline __host__ __device__ uint3 operator*(uint s, uint3 a) +{ + return make_uint3(a.x * s, a.y * s, a.z * s); +} +inline __host__ __device__ void operator*=(uint3 &a, uint s) +{ + a.x *= s; a.y *= s; a.z *= s; +} + +// divide +inline __host__ __device__ uint3 operator/(uint3 a, uint3 b) +{ + return make_uint3(a.x / b.x, a.y / b.y, a.z / b.z); +} +inline __host__ __device__ uint3 operator/(uint3 a, uint s) +{ + return make_uint3(a.x / s, a.y / s, a.z / s); +} +inline __host__ __device__ uint3 operator/(uint s, uint3 a) +{ + return make_uint3(a.x / s, a.y / s, a.z / s); +} +inline __host__ __device__ void operator/=(uint3 &a, uint s) +{ + a.x /= s; a.y /= s; a.z /= s; +} + +// clamp +inline __device__ __host__ uint clamp(uint f, uint a, uint b) +{ + return max(a, min(f, b)); +} + +inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b) +{ + return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} + +inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b) +{ + return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} + +#endif diff --git a/Extras/CUDA/libbulletcuda.vcproj b/Extras/CUDA/libbulletcuda.vcproj new file mode 100644 index 0000000..7e0a3dd --- /dev/null +++ b/Extras/CUDA/libbulletcuda.vcproj @@ -0,0 +1,665 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/CUDA/radixsort.cu b/Extras/CUDA/radixsort.cu new file mode 100644 index 0000000..24c85c6 --- /dev/null +++ b/Extras/CUDA/radixsort.cu @@ -0,0 +1,79 @@ +/* + * Copyright 1993-2006 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + */ + +/* Radixsort project with key/value and arbitrary datset size support + * which demonstrates the use of CUDA in a multi phase sorting + * computation. + * Host code. + */ + +#include "radixsort.cuh" +#include "radixsort_kernel.cu" + +extern "C" +{ + +//////////////////////////////////////////////////////////////////////////////// +//! Perform a radix sort +//! Sorting performed in place on passed arrays. +//! +//! @param pData0 input and output array - data will be sorted +//! @param pData1 additional array to allow ping pong computation +//! @param elements number of elements to sort +//////////////////////////////////////////////////////////////////////////////// +void RadixSort(KeyValuePair *pData0, KeyValuePair *pData1, uint elements, uint bits) +{ + // Round element count to total number of threads for efficiency + uint elements_rounded_to_3072; + int modval = elements % 3072; + if( modval == 0 ) + elements_rounded_to_3072 = elements; + else + elements_rounded_to_3072 = elements + (3072 - (modval)); + + // Iterate over n bytes of y bit word, using each byte to sort the list in turn + for (uint shift = 0; shift < bits; shift += RADIX) + { + // Perform one round of radix sorting + + // Generate per radix group sums radix counts across a radix group + RadixSum<<>>(pData0, elements, elements_rounded_to_3072, shift); + // Prefix sum in radix groups, and then between groups throughout a block + RadixPrefixSum<<>>(); + // Sum the block offsets and then shuffle data into bins + RadixAddOffsetsAndShuffle<<>>(pData0, pData1, elements, elements_rounded_to_3072, shift); + + // Exchange data pointers + KeyValuePair* pTemp = pData0; + pData0 = pData1; + pData1 = pTemp; + } +} + +} diff --git a/Extras/CUDA/radixsort.cuh b/Extras/CUDA/radixsort.cuh new file mode 100644 index 0000000..538bb11 --- /dev/null +++ b/Extras/CUDA/radixsort.cuh @@ -0,0 +1,63 @@ +/* + * Copyright 1993-2006 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + */ + +/* Radixsort project which demonstrates the use of CUDA in a multi phase + * sorting computation. + * Type definitions. + */ + +#ifndef _RADIXSORT_H_ +#define _RADIXSORT_H_ + +#include + +#define SYNCIT __syncthreads() + +// Use 16 bit keys/values +#define SIXTEEN 0 + +typedef unsigned int uint; +typedef unsigned short ushort; + +#if SIXTEEN +typedef struct __align__(4) { + ushort key; + ushort value; +#else +typedef struct __align__(8) { + uint key; + uint value; +#endif +} KeyValuePair; + +extern "C" { + void RadixSort(KeyValuePair *pData0, KeyValuePair *pData1, uint elements, uint bits); +} + +#endif // #ifndef _RADIXSORT_H_ diff --git a/Extras/CUDA/radixsort_kernel.cu b/Extras/CUDA/radixsort_kernel.cu new file mode 100644 index 0000000..2025841 --- /dev/null +++ b/Extras/CUDA/radixsort_kernel.cu @@ -0,0 +1,577 @@ +/* + * Copyright 1993-2006 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + */ + +/* Radixsort project with key/value and arbitrary datset size support + * which demonstrates the use of CUDA in a multi phase sorting + * computation. + * Device code. + */ + +#ifndef _RADIXSORT_KERNEL_H_ +#define _RADIXSORT_KERNEL_H_ + +#include +#include "radixsort.cuh" + +#define SYNCIT __syncthreads() + +static const int NUM_SMS = 16; +static const int NUM_THREADS_PER_SM = 192; +static const int NUM_THREADS_PER_BLOCK = 64; +//static const int NUM_THREADS = NUM_THREADS_PER_SM * NUM_SMS; +static const int NUM_BLOCKS = (NUM_THREADS_PER_SM / NUM_THREADS_PER_BLOCK) * NUM_SMS; +static const int RADIX = 8; // Number of bits per radix sort pass +static const int RADICES = 1 << RADIX; // Number of radices +static const int RADIXMASK = RADICES - 1; // Mask for each radix sort pass +#if SIXTEEN +static const int RADIXBITS = 16; // Number of bits to sort over +#else +static const int RADIXBITS = 32; // Number of bits to sort over +#endif +static const int RADIXTHREADS = 16; // Number of threads sharing each radix counter +static const int RADIXGROUPS = NUM_THREADS_PER_BLOCK / RADIXTHREADS; // Number of radix groups per CTA +static const int TOTALRADIXGROUPS = NUM_BLOCKS * RADIXGROUPS; // Number of radix groups for each radix +static const int SORTRADIXGROUPS = TOTALRADIXGROUPS * RADICES; // Total radix count +static const int GRFELEMENTS = (NUM_THREADS_PER_BLOCK / RADIXTHREADS) * RADICES; +static const int GRFSIZE = GRFELEMENTS * sizeof(uint); + +// Prefix sum variables +static const int PREFIX_NUM_THREADS_PER_SM = NUM_THREADS_PER_SM; +static const int PREFIX_NUM_THREADS_PER_BLOCK = PREFIX_NUM_THREADS_PER_SM; +static const int PREFIX_NUM_BLOCKS = (PREFIX_NUM_THREADS_PER_SM / PREFIX_NUM_THREADS_PER_BLOCK) * NUM_SMS; +static const int PREFIX_BLOCKSIZE = SORTRADIXGROUPS / PREFIX_NUM_BLOCKS; +static const int PREFIX_GRFELEMENTS = PREFIX_BLOCKSIZE + 2 * PREFIX_NUM_THREADS_PER_BLOCK; +static const int PREFIX_GRFSIZE = PREFIX_GRFELEMENTS * sizeof(uint); + +// Shuffle variables +static const int SHUFFLE_GRFOFFSET = RADIXGROUPS * RADICES; +static const int SHUFFLE_GRFELEMENTS = SHUFFLE_GRFOFFSET + PREFIX_NUM_BLOCKS; +static const int SHUFFLE_GRFSIZE = SHUFFLE_GRFELEMENTS * sizeof(uint); + + +#define SDATA( index) CUT_BANK_CHECKER(sdata, index) + +// Prefix sum data +uint gRadixSum[TOTALRADIXGROUPS * RADICES]; +__device__ uint dRadixSum[TOTALRADIXGROUPS * RADICES]; +uint gRadixBlockSum[PREFIX_NUM_BLOCKS]; +__device__ uint dRadixBlockSum[PREFIX_NUM_BLOCKS]; + +extern __shared__ uint sRadixSum[]; + + + +//////////////////////////////////////////////////////////////////////////////// +//! Perform a radix sum on the list to be sorted. Each SM holds a set of +//! radix counters for each group of RADIXGROUPS thread in the GRF. +//! +//! @param pData input data +//! @param elements total number of elements +//! @param elements_rounded_to_3072 total number of elements rounded up to the +//! nearest multiple of 3072 +//! @param shift the shift (0 to 24) that we are using to obtain the correct +//! byte +//////////////////////////////////////////////////////////////////////////////// +__global__ void RadixSum(KeyValuePair *pData, uint elements, uint elements_rounded_to_3072, uint shift) +{ + uint pos = threadIdx.x; + + // Zero radix counts + while (pos < GRFELEMENTS) + { + sRadixSum[pos] = 0; + pos += NUM_THREADS_PER_BLOCK; + } + + // Sum up data + // Source addresses computed so that each thread is reading from a block of + // consecutive addresses so there are no conflicts between threads + // They then loop over their combined region and the next batch works elsewhere. + // So threads 0 to 16 work on memory 0 to 320. + // First reading 0,1,2,3...15 then 16,17,18,19...31 and so on + // optimising parallel access to shared memory by a thread accessing 16*threadID + // The next radix group runs from 320 to 640 and the same applies in that region + uint tmod = threadIdx.x % RADIXTHREADS; + uint tpos = threadIdx.x / RADIXTHREADS; + + // Take the rounded element list size so that all threads have a certain size dataset to work with + // and no zero size datasets confusing the issue + // By using a multiple of 3072 we ensure that all threads have elements + // to work with until the last phase, at which point we individually test + uint element_fraction = elements_rounded_to_3072 / TOTALRADIXGROUPS; + + // Generate range + // Note that it is possible for both pos and end to be past the end of the element set + // which will be caught later. + pos = (blockIdx.x * RADIXGROUPS + tpos) * element_fraction; + uint end = pos + element_fraction; + pos += tmod; + //printf("pos: %d\n", pos); + __syncthreads(); + + while (pos < end ) + { + uint key = 0; + + // Read first data element if we are in the set of elements + //if( pos < elements ) + //key = pData[pos].key; + KeyValuePair kvp; + // Read first data element, both items at once as the memory will want to coalesce like that anyway + if (pos < elements) + kvp = pData[pos]; + else + kvp.key = 0; + key = kvp.key; + + + // Calculate position of radix counter to increment + // There are RADICES radices in each pass (256) + // and hence this many counters for bin grouping + // Multiply by RADIXGROUPS (4) to spread through memory + // and into 4 radix groups + uint p = ((key >> shift) & RADIXMASK) * RADIXGROUPS; + + // Increment radix counters + // Each radix group has its own set of counters + // so we add the thread position [0-3], ie the group index. + // We slow down here and take at least 16 cycles to write to the summation boxes + // but other groups will only conflict with themselves and so can also be writing + // 16 cycles here at least avoids retries. + uint ppos = p + tpos; + + // If we are past the last element we don't want to do anything + // We do have to check each time, however, to ensure that all + // threads sync on each sync here. + if (tmod == 0 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 1 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 2 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 3 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 4 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 5 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 6 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 7 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 8 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 9 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 10 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 11 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 12 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 13 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 14 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 15 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + + pos += RADIXTHREADS; + + } + + __syncthreads(); + + __syncthreads(); + + // Output radix sums into separate memory regions for each radix group + // So this memory then is layed out: + // 0...... 192..... 384 ................ 192*256 + // ie all 256 bins for each radix group + // in there: + // 0.............192 + // 0 4 8 12... - block idx * 4 + // And in the block boxes we see the 4 radix groups for that block + // So 0-192 should contain bin 0 for each radix group, and so on + uint offset = blockIdx.x * RADIXGROUPS; + uint row = threadIdx.x / RADIXGROUPS; + uint column = threadIdx.x % RADIXGROUPS; + while (row < RADICES) + { + dRadixSum[offset + row * TOTALRADIXGROUPS + column] = sRadixSum[row * RADIXGROUPS + column]; + row += NUM_THREADS_PER_BLOCK / RADIXGROUPS; + } +} + +//////////////////////////////////////////////////////////////////////////////// +//! Performs first part of parallel prefix sum - individual sums of each radix +//! count. By the end of this we have prefix sums on a block level in dRadixSum +//! and totals for blocks in dRadixBlockSum. +//////////////////////////////////////////////////////////////////////////////// +__global__ void RadixPrefixSum() +{ + // Read radix groups in offset by one in the GRF so a zero can be inserted at the beginning + // and the final sum of all radix counts summed here is tacked onto the end for reading by + // the next stage + // Each block in this case is the full number of threads per SM (and hence the total number + // of radix groups), 192. We should then have the total set of offsets for an entire radix + // group by the end of this stage + // Device mem addressing + + uint brow = blockIdx.x * (RADICES / PREFIX_NUM_BLOCKS); + uint drow = threadIdx.x / TOTALRADIXGROUPS; // In default parameterisation this is always 0 + uint dcolumn = threadIdx.x % TOTALRADIXGROUPS; // And similarly this is always the same as threadIdx.x + uint dpos = (brow + drow) * TOTALRADIXGROUPS + dcolumn; + uint end = ((blockIdx.x + 1) * (RADICES / PREFIX_NUM_BLOCKS)) * TOTALRADIXGROUPS; + // Shared mem addressing + uint srow = threadIdx.x / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + uint scolumn = threadIdx.x % (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + uint spos = srow * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + scolumn; + + // Read (RADICES / PREFIX_NUM_BLOCKS) radix counts into the GRF alongside each other + while (dpos < end) + { + sRadixSum[spos] = dRadixSum[dpos]; + spos += (PREFIX_NUM_THREADS_PER_BLOCK / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK)) * + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + dpos += (TOTALRADIXGROUPS / PREFIX_NUM_THREADS_PER_BLOCK) * TOTALRADIXGROUPS; + } + __syncthreads(); + + // Perform preliminary sum on each thread's stretch of data + // Each thread having a block of 16, with spacers between 0...16 18...33 and so on + int pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + end = pos + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + uint sum = 0; + while (pos < end) + { + sum += sRadixSum[pos]; + sRadixSum[pos] = sum; + pos++; + } + __syncthreads(); + + + // Calculate internal offsets by performing a more traditional parallel + // prefix sum of the topmost member of each thread's work data. Right now, + // these are stored between the work data for each thread, allowing us to + // eliminate GRF conflicts as well as hold the offsets needed to complete the sum + // In other words we have: + // 0....15 16 17....32 33 34.... + // Where this first stage updates the intermediate values (so 16=15, 33=32 etc) + int m = (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + sRadixSum[pos] = sRadixSum[pos - 1]; + __syncthreads(); + // This stage then performs a parallel prefix sum (ie use powers of 2 to propagate in log n stages) + // to update 17, 34 etc with the totals to that point (so 34 becomes [34] + [17]) and so on. + while (m < PREFIX_NUM_THREADS_PER_BLOCK * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1)) + { + int p = pos - m; + uint t = ((p > 0) ? sRadixSum[p] : 0); + __syncthreads(); + sRadixSum[pos] += t; + __syncthreads(); + m *= 2; + } + __syncthreads(); + + + + // Add internal offsets to each thread's work data. + // So now we take 17 and add it to all values 18 to 33 so all offsets for that block + // are updated. + pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + end = pos + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + int p = pos - 1; + sum = ((p > 0) ? sRadixSum[p] : 0); + while (pos < end) + { + sRadixSum[pos] += sum; + pos++; + } + __syncthreads(); + + // Write summed data back out to global memory in the same way as we read it in + // We now have prefix sum values internal to groups + brow = blockIdx.x * (RADICES / PREFIX_NUM_BLOCKS); + drow = threadIdx.x / TOTALRADIXGROUPS; + dcolumn = threadIdx.x % TOTALRADIXGROUPS; + srow = threadIdx.x / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + scolumn = threadIdx.x % (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + dpos = (brow + drow) * TOTALRADIXGROUPS + dcolumn + 1; + spos = srow * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + scolumn; + end = ((blockIdx.x + 1) * RADICES / PREFIX_NUM_BLOCKS) * TOTALRADIXGROUPS; + while (dpos < end) + { + dRadixSum[dpos] = sRadixSum[spos]; + dpos += (TOTALRADIXGROUPS / PREFIX_NUM_THREADS_PER_BLOCK) * TOTALRADIXGROUPS; + spos += (PREFIX_NUM_THREADS_PER_BLOCK / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK)) * + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + } + + // Write last element to summation + // Storing block sums in a separate array + if (threadIdx.x == 0) { + dRadixBlockSum[blockIdx.x] = sRadixSum[PREFIX_NUM_THREADS_PER_BLOCK * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) - 1]; + dRadixSum[blockIdx.x * PREFIX_BLOCKSIZE] = 0; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +//! Initially perform prefix sum of block totals to obtain final set of offsets. +//! Then make use of radix sums to perform a shuffling of the data into the +//! correct bins. +//! +//! @param pSrc input data +//! @param pDst output data +//! @param elements total number of elements +//! @param shift the shift (0 to 24) that we are using to obtain the correct +//! byte +//////////////////////////////////////////////////////////////////////////////// +__global__ void RadixAddOffsetsAndShuffle(KeyValuePair* pSrc, KeyValuePair* pDst, uint elements, uint elements_rounded_to_3072, int shift) +{ + // Read offsets from previous blocks + if (threadIdx.x == 0) + sRadixSum[SHUFFLE_GRFOFFSET] = 0; + + if (threadIdx.x < PREFIX_NUM_BLOCKS - 1) + sRadixSum[SHUFFLE_GRFOFFSET + threadIdx.x + 1] = dRadixBlockSum[threadIdx.x]; + __syncthreads(); + + // Parallel prefix sum over block sums + int pos = threadIdx.x; + int n = 1; + while (n < PREFIX_NUM_BLOCKS) + { + int ppos = pos - n; + uint t0 = ((pos < PREFIX_NUM_BLOCKS) && (ppos >= 0)) ? sRadixSum[SHUFFLE_GRFOFFSET + ppos] : 0; + __syncthreads(); + if (pos < PREFIX_NUM_BLOCKS) + sRadixSum[SHUFFLE_GRFOFFSET + pos] += t0; + __syncthreads(); + n *= 2; + } + + // Read radix count data and add appropriate block offset + // for each radix at the memory location for this thread + // (where the other threads in the block will be reading + // as well, hence the large stride). + // There is one counter box per radix group per radix + // per block (4*256*3) + // We use 64 threads to read the 4 radix groups set of radices + // for the block. + int row = threadIdx.x / RADIXGROUPS; + int column = threadIdx.x % RADIXGROUPS; + int spos = row * RADIXGROUPS + column; + int dpos = row * TOTALRADIXGROUPS + column + blockIdx.x * RADIXGROUPS; + while (spos < SHUFFLE_GRFOFFSET) + { + sRadixSum[spos] = dRadixSum[dpos] + sRadixSum[SHUFFLE_GRFOFFSET + dpos / (TOTALRADIXGROUPS * RADICES / PREFIX_NUM_BLOCKS)]; + spos += NUM_THREADS_PER_BLOCK; + dpos += (NUM_THREADS_PER_BLOCK / RADIXGROUPS) * TOTALRADIXGROUPS; + } + __syncthreads(); + + //int pos; + // Shuffle data + // Each of the subbins for a block should be filled via the counters, properly interleaved + // Then, as we now iterate over each data value, we increment the subbins (each thread in the + // radix group in turn to avoid miss writes due to conflicts) and set locations correctly. + uint element_fraction = elements_rounded_to_3072 / TOTALRADIXGROUPS; + int tmod = threadIdx.x % RADIXTHREADS; + int tpos = threadIdx.x / RADIXTHREADS; + + pos = (blockIdx.x * RADIXGROUPS + tpos) * element_fraction; + uint end = pos + element_fraction; //(blockIdx.x * RADIXGROUPS + tpos + 1) * element_fraction; + pos += tmod; + + __syncthreads(); + + while (pos < end ) + { + KeyValuePair kvp; +#if 1 // old load + // Read first data element, both items at once as the memory will want to coalesce like that anyway + if (pos < elements) + { + kvp = pSrc[pos]; + } + else + kvp.key = 0; + +#else // casting to float2 to get it to combine loads + int2 kvpf2; + + // Read first data element, both items at once as the memory will want to coalesce like that anyway + if (pos < elements) + { + // kvp = pSrc[pos]; + kvpf2 = ((int2*)pSrc)[pos]; + // printf("kvp: %f %f kvpf2: %f %f\n", kvp.key, kvp.value, kvpf2.x, kvpf2.y); + } + else + //kvp.key = 0; + kvpf2.x = 0; + + kvp.key = kvpf2.x; + kvp.value = kvpf2.y; +#endif + + uint index; + + // Calculate position of radix counter to increment + uint p = ((kvp.key >> shift) & RADIXMASK) * RADIXGROUPS; + + // Move data, keeping counts updated. + // Increment radix counters, relying on hexadecathread + // warp to prevent this code from stepping all over itself. + uint ppos = p + tpos; + if (tmod == 0 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 1 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 2 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 3 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 4 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 5 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 6 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 7 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 8 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 9 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 10 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 11 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 12 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 13 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 14 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 15 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + + pos += RADIXTHREADS; + } + + __syncthreads(); +} + +#endif // #ifndef _RADIXSORT_KERNEL_H_ diff --git a/Extras/ConvexDecomposition/CMakeLists.txt b/Extras/ConvexDecomposition/CMakeLists.txt new file mode 100644 index 0000000..693e9d2 --- /dev/null +++ b/Extras/ConvexDecomposition/CMakeLists.txt @@ -0,0 +1,64 @@ +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/ConvexDecomposition ${BULLET_PHYSICS_SOURCE_DIR}/src +) + +SET(ConvexDecomposition_SRCS + bestfitobb.cpp + ConvexBuilder.cpp + cd_wavefront.cpp + fitsphere.cpp + meshvolume.cpp + raytri.cpp + vlookup.cpp + bestfit.cpp + cd_hull.cpp + ConvexDecomposition.cpp + concavity.cpp + float_math.cpp + planetri.cpp + splitplane.cpp +) + +SET(ConvexDecomposition_HDRS + ConvexDecomposition.h + cd_vector.h + concavity.h + bestfitobb.h + ConvexBuilder.h + cd_wavefront.h + fitsphere.h + meshvolume.h + raytri.h + vlookup.h + bestfit.h + cd_hull.h +) + +ADD_LIBRARY(ConvexDecomposition ${ConvexDecomposition_SRCS} ${ConvexDecomposition_HDRS}) +SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES SOVERSION ${BULLET_VERSION}) + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(ConvexDecomposition BulletCollision LinearMath) +ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_EXTRA_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #FILES_MATCHING requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS ConvexDecomposition DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS ConvexDecomposition DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES PUBLIC_HEADER "${ConvexDecomposition_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_EXTRA_LIBS) diff --git a/Extras/ConvexDecomposition/ConvexBuilder.cpp b/Extras/ConvexDecomposition/ConvexBuilder.cpp new file mode 100644 index 0000000..bf576af --- /dev/null +++ b/Extras/ConvexDecomposition/ConvexBuilder.cpp @@ -0,0 +1,373 @@ +#include "float_math.h" +#include "ConvexBuilder.h" +#include "meshvolume.h" +#include "bestfit.h" +#include +#include "cd_hull.h" + +#include "fitsphere.h" +#include "bestfitobb.h" + +unsigned int MAXDEPTH = 8 ; +float CONCAVE_PERCENT = 1.0f ; +float MERGE_PERCENT = 2.0f ; + +CHull::CHull(const ConvexResult &result) +{ + mResult = new ConvexResult(result); + mVolume = computeMeshVolume( result.mHullVertices, result.mHullTcount, result.mHullIndices ); + + mDiagonal = getBoundingRegion( result.mHullVcount, result.mHullVertices, sizeof(float)*3, mMin, mMax ); + + float dx = mMax[0] - mMin[0]; + float dy = mMax[1] - mMin[1]; + float dz = mMax[2] - mMin[2]; + + dx*=0.1f; // inflate 1/10th on each edge + dy*=0.1f; // inflate 1/10th on each edge + dz*=0.1f; // inflate 1/10th on each edge + + mMin[0]-=dx; + mMin[1]-=dy; + mMin[2]-=dz; + + mMax[0]+=dx; + mMax[1]+=dy; + mMax[2]+=dz; + + +} + +CHull::~CHull(void) +{ + delete mResult; +} + +bool CHull::overlap(const CHull &h) const +{ + return overlapAABB(mMin,mMax, h.mMin, h.mMax ); +} + + + + +ConvexBuilder::ConvexBuilder(ConvexDecompInterface *callback) +{ + mCallback = callback; +} + +ConvexBuilder::~ConvexBuilder(void) +{ + int i; + for (i=0;ioverlap(*b) ) return 0; // if their AABB's (with a little slop) don't overlap, then return. + + CHull *ret = 0; + + // ok..we are going to combine both meshes into a single mesh + // and then we are going to compute the concavity... + + VertexLookup vc = Vl_createVertexLookup(); + + UintVector indices; + + getMesh( *a->mResult, vc, indices ); + getMesh( *b->mResult, vc, indices ); + + unsigned int vcount = Vl_getVcount(vc); + const float *vertices = Vl_getVertices(vc); + unsigned int tcount = indices.size()/3; + + //don't do anything if hull is empty + if (!tcount) + { + Vl_releaseVertexLookup (vc); + return 0; + } + + HullResult hresult; + HullLibrary hl; + HullDesc desc; + + desc.SetHullFlag(QF_TRIANGLES); + + desc.mVcount = vcount; + desc.mVertices = vertices; + desc.mVertexStride = sizeof(float)*3; + + HullError hret = hl.CreateConvexHull(desc,hresult); + + if ( hret == QE_OK ) + { + + float combineVolume = computeMeshVolume( hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices ); + float sumVolume = a->mVolume + b->mVolume; + + float percent = (sumVolume*100) / combineVolume; + if ( percent >= (100.0f-MERGE_PERCENT) ) + { + ConvexResult cr(hresult.mNumOutputVertices, hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices); + ret = new CHull(cr); + } + } + + + Vl_releaseVertexLookup(vc); + + return ret; +} + +bool ConvexBuilder::combineHulls(void) +{ + + bool combine = false; + + sortChulls(mChulls); // sort the convex hulls, largest volume to least... + + CHullVector output; // the output hulls... + + + int i; + + for (i=0;imResult; // the high resolution hull... + + HullResult result; + HullLibrary hl; + HullDesc hdesc; + + hdesc.SetHullFlag(QF_TRIANGLES); + + hdesc.mVcount = c.mHullVcount; + hdesc.mVertices = c.mHullVertices; + hdesc.mVertexStride = sizeof(float)*3; + hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output + + if ( desc.mSkinWidth ) + { + hdesc.mSkinWidth = desc.mSkinWidth; + hdesc.SetHullFlag(QF_SKIN_WIDTH); // do skin width computation. + } + + HullError ret = hl.CreateConvexHull(hdesc,result); + + if ( ret == QE_OK ) + { + ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices); + + r.mHullVolume = computeMeshVolume( result.mOutputVertices, result.mNumFaces, result.mIndices ); // the volume of the hull. + + // compute the best fit OBB + computeBestFitOBB( result.mNumOutputVertices, result.mOutputVertices, sizeof(float)*3, r.mOBBSides, r.mOBBTransform ); + + r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] *r.mOBBSides[2]; // compute the OBB volume. + + fm_getTranslation( r.mOBBTransform, r.mOBBCenter ); // get the translation component of the 4x4 matrix. + + fm_matrixToQuat( r.mOBBTransform, r.mOBBOrientation ); // extract the orientation as a quaternion. + + r.mSphereRadius = computeBoundingSphere( result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter ); + r.mSphereVolume = fm_sphereVolume( r.mSphereRadius ); + + + mCallback->ConvexDecompResult(r); + } + + hl.ReleaseResult (result); + + + delete cr; + } + + ret = mChulls.size(); + + mChulls.clear(); + + return ret; +} + + +void ConvexBuilder::ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color) +{ + mCallback->ConvexDebugTri(p1,p2,p3,color); +} + +void ConvexBuilder::ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color) +{ + mCallback->ConvexDebugOBB(sides,matrix,color); +} +void ConvexBuilder::ConvexDebugPoint(const float *p,float dist,unsigned int color) +{ + mCallback->ConvexDebugPoint(p,dist,color); +} + +void ConvexBuilder::ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color) +{ + mCallback->ConvexDebugBound(bmin,bmax,color); +} + +void ConvexBuilder::ConvexDecompResult(ConvexResult &result) +{ + CHull *ch = new CHull(result); + mChulls.push_back(ch); +} + +void ConvexBuilder::sortChulls(CHullVector &hulls) +{ + hulls.quickSort(CHullSort()); + //hulls.heapSort(CHullSort()); +} + + diff --git a/Extras/ConvexDecomposition/ConvexBuilder.h b/Extras/ConvexDecomposition/ConvexBuilder.h new file mode 100644 index 0000000..b1d98cb --- /dev/null +++ b/Extras/ConvexDecomposition/ConvexBuilder.h @@ -0,0 +1,112 @@ +#ifndef CONVEX_BUILDER_H +#define CONVEX_BUILDER_H + +/*---------------------------------------------------------------------- +Copyright (c) 2004 Open Dynamics Framework Group +www.physicstools.org +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided +that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions +and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +Neither the name of the Open Dynamics Framework Group nor the names of its contributors may +be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +#include "ConvexDecomposition.h" +#include "vlookup.h" +#include "LinearMath/btAlignedObjectArray.h" + +using namespace ConvexDecomposition; + + +class CHull +{ +public: + CHull(const ConvexResult &result); + + ~CHull(void); + + bool overlap(const CHull &h) const; + + float mMin[3]; + float mMax[3]; + float mVolume; + float mDiagonal; // long edge.. + ConvexResult *mResult; +}; + +// Usage: std::sort( list.begin(), list.end(), StringSortRef() ); +class CHullSort +{ +public: + + inline bool operator()(const CHull *a,const CHull *b) const + { + return a->mVolume < b->mVolume; + } +}; + + +typedef btAlignedObjectArray< CHull * > CHullVector; + + + +class ConvexBuilder : public ConvexDecompInterface +{ +public: + ConvexBuilder(ConvexDecompInterface *callback); + + virtual ~ConvexBuilder(void); + + bool isDuplicate(unsigned int i1,unsigned int i2,unsigned int i3, + unsigned int ci1,unsigned int ci2,unsigned int ci3); + + void getMesh(const ConvexResult &cr,VertexLookup vc,UintVector &indices); + + CHull * canMerge(CHull *a,CHull *b); + + bool combineHulls(void); + + unsigned int process(const DecompDesc &desc); + + virtual void ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color); + + virtual void ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color); + virtual void ConvexDebugPoint(const float *p,float dist,unsigned int color); + + virtual void ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color); + + virtual void ConvexDecompResult(ConvexResult &result); + + void sortChulls(CHullVector &hulls); + + CHullVector mChulls; + ConvexDecompInterface *mCallback; +}; + +#endif //CONVEX_BUILDER_H + diff --git a/Extras/ConvexDecomposition/ConvexDecomposition.cpp b/Extras/ConvexDecomposition/ConvexDecomposition.cpp new file mode 100644 index 0000000..572d25f --- /dev/null +++ b/Extras/ConvexDecomposition/ConvexDecomposition.cpp @@ -0,0 +1,375 @@ +#include "float_math.h" + +#include +#include +#include +#include + + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +#include "ConvexDecomposition.h" +#include "cd_vector.h" +#include "cd_hull.h" +#include "bestfit.h" +#include "planetri.h" +#include "vlookup.h" +#include "splitplane.h" +#include "meshvolume.h" +#include "concavity.h" +#include "bestfitobb.h" +#include "float_math.h" +#include "fitsphere.h" + +#define SHOW_MESH 0 +#define MAKE_MESH 1 + + +using namespace ConvexDecomposition; + + + +namespace ConvexDecomposition +{ + +class FaceTri +{ +public: + FaceTri(void) { }; + FaceTri(const float *vertices,unsigned int i1,unsigned int i2,unsigned int i3) + { + mP1.Set( &vertices[i1*3] ); + mP2.Set( &vertices[i2*3] ); + mP3.Set( &vertices[i3*3] ); + } + + Vector3d mP1; + Vector3d mP2; + Vector3d mP3; + Vector3d mNormal; + +}; + + +void addTri(VertexLookup vl,UintVector &list,const Vector3d &p1,const Vector3d &p2,const Vector3d &p3) +{ + unsigned int i1 = Vl_getIndex(vl, p1.Ptr() ); + unsigned int i2 = Vl_getIndex(vl, p2.Ptr() ); + unsigned int i3 = Vl_getIndex(vl, p3.Ptr() ); + + // do *not* process degenerate triangles! + + if ( i1 != i2 && i1 != i3 && i2 != i3 ) + { + list.push_back(i1); + list.push_back(i2); + list.push_back(i3); + } +} + + +void calcConvexDecomposition(unsigned int vcount, + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float masterVolume, + unsigned int depth) + +{ + + float plane[4]; + + bool split = false; + + + if ( depth < MAXDEPTH ) + { + + float volume; + float c = computeConcavity( vcount, vertices, tcount, indices, callback, plane, volume ); + + if ( depth == 0 ) + { + masterVolume = volume; + } + + float percent = (c*100.0f)/masterVolume; + + if ( percent > CONCAVE_PERCENT ) // if great than 5% of the total volume is concave, go ahead and keep splitting. + { + split = true; + } + + } + + if ( depth >= MAXDEPTH || !split ) + { + +#if 1 + + HullResult result; + HullLibrary hl; + HullDesc desc; + + desc.SetHullFlag(QF_TRIANGLES); + + desc.mVcount = vcount; + desc.mVertices = vertices; + desc.mVertexStride = sizeof(float)*3; + + HullError ret = hl.CreateConvexHull(desc,result); + + if ( ret == QE_OK ) + { + + ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices); + + + callback->ConvexDecompResult(r); + } + + +#else + + static unsigned int colors[8] = + { + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFFFF00, + 0x00FFFF, + 0xFF00FF, + 0xFFFFFF, + 0xFF8040 + }; + + static int count = 0; + + count++; + + if ( count == 8 ) count = 0; + + assert( count >= 0 && count < 8 ); + + unsigned int color = colors[count]; + + const unsigned int *source = indices; + + for (unsigned int i=0; iConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color ); + + } +#endif + + hl.ReleaseResult (result); + return; + + } + + UintVector ifront; + UintVector iback; + + VertexLookup vfront = Vl_createVertexLookup(); + VertexLookup vback = Vl_createVertexLookup(); + + + bool showmesh = false; + #if SHOW_MESH + showmesh = true; + #endif + + if ( 0 ) + { + showmesh = true; + for (float x=-1; x<1; x+=0.10f) + { + for (float y=0; y<1; y+=0.10f) + { + for (float z=-1; z<1; z+=0.04f) + { + float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3]; + Vector3d p(x,y,z); + if ( d >= 0 ) + callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00); + else + callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000); + } + } + } + } + + if ( 1 ) + { + // ok..now we are going to 'split' all of the input triangles against this plane! + const unsigned int *source = indices; + for (unsigned int i=0; i 4 || bcount > 4 ) + { + result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount ); + } + + switch ( result ) + { + case PTR_FRONT: + + assert( fcount == 3 ); + + if ( showmesh ) + callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00 ); + + #if MAKE_MESH + + addTri( vfront, ifront, front[0], front[1], front[2] ); + + + #endif + + break; + case PTR_BACK: + assert( bcount == 3 ); + + if ( showmesh ) + callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00 ); + + #if MAKE_MESH + + addTri( vback, iback, back[0], back[1], back[2] ); + + #endif + + break; + case PTR_SPLIT: + + assert( fcount >= 3 && fcount <= 4); + assert( bcount >= 3 && bcount <= 4); + + #if MAKE_MESH + + addTri( vfront, ifront, front[0], front[1], front[2] ); + addTri( vback, iback, back[0], back[1], back[2] ); + + + if ( fcount == 4 ) + { + addTri( vfront, ifront, front[0], front[2], front[3] ); + } + + if ( bcount == 4 ) + { + addTri( vback, iback, back[0], back[2], back[3] ); + } + + #endif + + if ( showmesh ) + { + callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000 ); + callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000 ); + + if ( fcount == 4 ) + { + callback->ConvexDebugTri( front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000 ); + } + if ( bcount == 4 ) + { + callback->ConvexDebugTri( back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000 ); + } + } + + break; + } + } + + // ok... here we recursively call + if ( ifront.size() ) + { + unsigned int vcount = Vl_getVcount(vfront); + const float *vertices = Vl_getVertices(vfront); + unsigned int tcount = ifront.size()/3; + + calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth+1); + + } + + ifront.clear(); + + Vl_releaseVertexLookup(vfront); + + if ( iback.size() ) + { + unsigned int vcount = Vl_getVcount(vback); + const float *vertices = Vl_getVertices(vback); + unsigned int tcount = iback.size()/3; + + calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth+1); + + } + + iback.clear(); + Vl_releaseVertexLookup(vback); + + } +} + + + + +} diff --git a/Extras/ConvexDecomposition/ConvexDecomposition.h b/Extras/ConvexDecomposition/ConvexDecomposition.h new file mode 100644 index 0000000..2886c39 --- /dev/null +++ b/Extras/ConvexDecomposition/ConvexDecomposition.h @@ -0,0 +1,220 @@ +#ifndef CONVEX_DECOMPOSITION_H + +#define CONVEX_DECOMPOSITION_H + +/*---------------------------------------------------------------------- +Copyright (c) 2004 Open Dynamics Framework Group +www.physicstools.org +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided +that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions +and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +Neither the name of the Open Dynamics Framework Group nor the names of its contributors may +be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +#ifdef _WIN32 +#include //memcpy +#endif +#include +#include +#include "LinearMath/btAlignedObjectArray.h" + + + +extern unsigned int MAXDEPTH ; +extern float CONCAVE_PERCENT ; +extern float MERGE_PERCENT ; + + +typedef btAlignedObjectArray< unsigned int > UintVector; + + + +namespace ConvexDecomposition +{ + + class ConvexResult + { + public: + ConvexResult(void) + { + mHullVcount = 0; + mHullVertices = 0; + mHullTcount = 0; + mHullIndices = 0; + } + + ConvexResult(unsigned int hvcount,const float *hvertices,unsigned int htcount,const unsigned int *hindices) + { + mHullVcount = hvcount; + if ( mHullVcount ) + { + mHullVertices = new float[mHullVcount*sizeof(float)*3]; + memcpy(mHullVertices, hvertices, sizeof(float)*3*mHullVcount ); + } + else + { + mHullVertices = 0; + } + + mHullTcount = htcount; + + if ( mHullTcount ) + { + mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3]; + memcpy(mHullIndices,hindices, sizeof(unsigned int)*mHullTcount*3 ); + } + else + { + mHullIndices = 0; + } + + } + + ConvexResult(const ConvexResult &r) + { + mHullVcount = r.mHullVcount; + if ( mHullVcount ) + { + mHullVertices = new float[mHullVcount*sizeof(float)*3]; + memcpy(mHullVertices, r.mHullVertices, sizeof(float)*3*mHullVcount ); + } + else + { + mHullVertices = 0; + } + mHullTcount = r.mHullTcount; + if ( mHullTcount ) + { + mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3]; + memcpy(mHullIndices, r.mHullIndices, sizeof(unsigned int)*mHullTcount*3 ); + } + else + { + mHullIndices = 0; + } + } + + ~ConvexResult(void) + { + delete [] mHullVertices; + delete [] mHullIndices; + } + + // the convex hull. + unsigned int mHullVcount; + float * mHullVertices; + unsigned int mHullTcount; + unsigned int *mHullIndices; + + float mHullVolume; // the volume of the convex hull. + + float mOBBSides[3]; // the width, height and breadth of the best fit OBB + float mOBBCenter[3]; // the center of the OBB + float mOBBOrientation[4]; // the quaternion rotation of the OBB. + float mOBBTransform[16]; // the 4x4 transform of the OBB. + float mOBBVolume; // the volume of the OBB + + float mSphereRadius; // radius and center of best fit sphere + float mSphereCenter[3]; + float mSphereVolume; // volume of the best fit sphere + + + + }; + + class ConvexDecompInterface + { + public: + virtual ~ConvexDecompInterface() {}; + virtual void ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color) { }; + virtual void ConvexDebugPoint(const float *p,float dist,unsigned int color) { }; + virtual void ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color) { }; + virtual void ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color) { }; + + virtual void ConvexDecompResult(ConvexResult &result) = 0; + + + + }; + + // just to avoid passing a zillion parameters to the method the + // options are packed into this descriptor. + class DecompDesc + { + public: + DecompDesc(void) + { + mVcount = 0; + mVertices = 0; + mTcount = 0; + mIndices = 0; + mDepth = 5; + mCpercent = 5; + mPpercent = 5; + mMaxVertices = 32; + mSkinWidth = 0; + mCallback = 0; + } + + // describes the input triangle. + unsigned int mVcount; // the number of vertices in the source mesh. + const float *mVertices; // start of the vertex position array. Assumes a stride of 3 floats. + unsigned int mTcount; // the number of triangles in the source mesh. + unsigned int *mIndices; // the indexed triangle list array (zero index based) + + // options + unsigned int mDepth; // depth to split, a maximum of 10, generally not over 7. + float mCpercent; // the concavity threshold percentage. 0=20 is reasonable. + float mPpercent; // the percentage volume conservation threshold to collapse hulls. 0-30 is reasonable. + + // hull output limits. + unsigned int mMaxVertices; // maximum number of vertices in the output hull. Recommended 32 or less. + float mSkinWidth; // a skin width to apply to the output hulls. + + ConvexDecompInterface *mCallback; // the interface to receive back the results. + + }; + + // perform approximate convex decomposition on a mesh. + unsigned int performConvexDecomposition(const DecompDesc &desc); // returns the number of hulls produced. + + + void calcConvexDecomposition(unsigned int vcount, + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float masterVolume, + unsigned int depth); + + +} + + +#endif diff --git a/Extras/ConvexDecomposition/bestfit.cpp b/Extras/ConvexDecomposition/bestfit.cpp new file mode 100644 index 0000000..e6469f6 --- /dev/null +++ b/Extras/ConvexDecomposition/bestfit.cpp @@ -0,0 +1,466 @@ +#include "float_math.h" +#include +#include +#include +#include +#include + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// +// Geometric Tools, Inc. +// http://www.geometrictools.com +// Copyright (c) 1998-2006. All Rights Reserved +// +// The Wild Magic Library (WM3) source code is supplied under the terms of +// the license agreement +// http://www.geometrictools.com/License/WildMagic3License.pdf +// and may not be copied or disclosed except in accordance with the terms +// of that agreement. + +#include "bestfit.h" + +namespace BestFit +{ + +class Vec3 +{ +public: + Vec3(void) { }; + Vec3(float _x,float _y,float _z) { x = _x; y = _y; z = _z; }; + + + float dot(const Vec3 &v) + { + return x*v.x + y*v.y + z*v.z; // the dot product + } + + float x; + float y; + float z; +}; + + +class Eigen +{ +public: + + + void DecrSortEigenStuff(void) + { + Tridiagonal(); //diagonalize the matrix. + QLAlgorithm(); // + DecreasingSort(); + GuaranteeRotation(); + } + + void Tridiagonal(void) + { + float fM00 = mElement[0][0]; + float fM01 = mElement[0][1]; + float fM02 = mElement[0][2]; + float fM11 = mElement[1][1]; + float fM12 = mElement[1][2]; + float fM22 = mElement[2][2]; + + m_afDiag[0] = fM00; + m_afSubd[2] = 0; + if (fM02 != (float)0.0) + { + float fLength = sqrtf(fM01*fM01+fM02*fM02); + float fInvLength = ((float)1.0)/fLength; + fM01 *= fInvLength; + fM02 *= fInvLength; + float fQ = ((float)2.0)*fM01*fM12+fM02*(fM22-fM11); + m_afDiag[1] = fM11+fM02*fQ; + m_afDiag[2] = fM22-fM02*fQ; + m_afSubd[0] = fLength; + m_afSubd[1] = fM12-fM01*fQ; + mElement[0][0] = (float)1.0; + mElement[0][1] = (float)0.0; + mElement[0][2] = (float)0.0; + mElement[1][0] = (float)0.0; + mElement[1][1] = fM01; + mElement[1][2] = fM02; + mElement[2][0] = (float)0.0; + mElement[2][1] = fM02; + mElement[2][2] = -fM01; + m_bIsRotation = false; + } + else + { + m_afDiag[1] = fM11; + m_afDiag[2] = fM22; + m_afSubd[0] = fM01; + m_afSubd[1] = fM12; + mElement[0][0] = (float)1.0; + mElement[0][1] = (float)0.0; + mElement[0][2] = (float)0.0; + mElement[1][0] = (float)0.0; + mElement[1][1] = (float)1.0; + mElement[1][2] = (float)0.0; + mElement[2][0] = (float)0.0; + mElement[2][1] = (float)0.0; + mElement[2][2] = (float)1.0; + m_bIsRotation = true; + } + } + + bool QLAlgorithm(void) + { + const int iMaxIter = 32; + + for (int i0 = 0; i0 <3; i0++) + { + int i1; + for (i1 = 0; i1 < iMaxIter; i1++) + { + int i2; + for (i2 = i0; i2 <= (3-2); i2++) + { + float fTmp = fabsf(m_afDiag[i2]) + fabsf(m_afDiag[i2+1]); + if ( fabsf(m_afSubd[i2]) + fTmp == fTmp ) + break; + } + if (i2 == i0) + { + break; + } + + float fG = (m_afDiag[i0+1] - m_afDiag[i0])/(((float)2.0) * m_afSubd[i0]); + float fR = sqrtf(fG*fG+(float)1.0); + if (fG < (float)0.0) + { + fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG-fR); + } + else + { + fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG+fR); + } + float fSin = (float)1.0, fCos = (float)1.0, fP = (float)0.0; + for (int i3 = i2-1; i3 >= i0; i3--) + { + float fF = fSin*m_afSubd[i3]; + float fB = fCos*m_afSubd[i3]; + if (fabsf(fF) >= fabsf(fG)) + { + fCos = fG/fF; + fR = sqrtf(fCos*fCos+(float)1.0); + m_afSubd[i3+1] = fF*fR; + fSin = ((float)1.0)/fR; + fCos *= fSin; + } + else + { + fSin = fF/fG; + fR = sqrtf(fSin*fSin+(float)1.0); + m_afSubd[i3+1] = fG*fR; + fCos = ((float)1.0)/fR; + fSin *= fCos; + } + fG = m_afDiag[i3+1]-fP; + fR = (m_afDiag[i3]-fG)*fSin+((float)2.0)*fB*fCos; + fP = fSin*fR; + m_afDiag[i3+1] = fG+fP; + fG = fCos*fR-fB; + for (int i4 = 0; i4 < 3; i4++) + { + fF = mElement[i4][i3+1]; + mElement[i4][i3+1] = fSin*mElement[i4][i3]+fCos*fF; + mElement[i4][i3] = fCos*mElement[i4][i3]-fSin*fF; + } + } + m_afDiag[i0] -= fP; + m_afSubd[i0] = fG; + m_afSubd[i2] = (float)0.0; + } + if (i1 == iMaxIter) + { + return false; + } + } + return true; + } + + void DecreasingSort(void) + { + //sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1] + for (int i0 = 0, i1; i0 <= 3-2; i0++) + { + // locate maximum eigenvalue + i1 = i0; + float fMax = m_afDiag[i1]; + int i2; + for (i2 = i0+1; i2 < 3; i2++) + { + if (m_afDiag[i2] > fMax) + { + i1 = i2; + fMax = m_afDiag[i1]; + } + } + + if (i1 != i0) + { + // swap eigenvalues + m_afDiag[i1] = m_afDiag[i0]; + m_afDiag[i0] = fMax; + // swap eigenvectors + for (i2 = 0; i2 < 3; i2++) + { + float fTmp = mElement[i2][i0]; + mElement[i2][i0] = mElement[i2][i1]; + mElement[i2][i1] = fTmp; + m_bIsRotation = !m_bIsRotation; + } + } + } + } + + + void GuaranteeRotation(void) + { + if (!m_bIsRotation) + { + // change sign on the first column + for (int iRow = 0; iRow <3; iRow++) + { + mElement[iRow][0] = -mElement[iRow][0]; + } + } + } + + float mElement[3][3]; + float m_afDiag[3]; + float m_afSubd[3]; + bool m_bIsRotation; +}; + +} + + +using namespace BestFit; + + +bool getBestFitPlane(unsigned int vcount, + const float *points, + unsigned int vstride, + const float *weights, + unsigned int wstride, + float *plane) +{ + bool ret = false; + + Vec3 kOrigin(0,0,0); + + float wtotal = 0; + + if ( 1 ) + { + const char *source = (const char *) points; + const char *wsource = (const char *) weights; + + for (unsigned int i=0; i bmax[0] ) bmax[0] = p[0]; + if ( p[1] > bmax[1] ) bmax[1] = p[1]; + if ( p[2] > bmax[2] ) bmax[2] = p[2]; + + } + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + return sqrtf( dx*dx + dy*dy + dz*dz ); + +} + + +bool overlapAABB(const float *bmin1,const float *bmax1,const float *bmin2,const float *bmax2) // return true if the two AABB's overlap. +{ + if ( bmax2[0] < bmin1[0] ) return false; // if the maximum is less than our minimum on any axis + if ( bmax2[1] < bmin1[1] ) return false; + if ( bmax2[2] < bmin1[2] ) return false; + + if ( bmin2[0] > bmax1[0] ) return false; // if the minimum is greater than our maximum on any axis + if ( bmin2[1] > bmax1[1] ) return false; // if the minimum is greater than our maximum on any axis + if ( bmin2[2] > bmax1[2] ) return false; // if the minimum is greater than our maximum on any axis + + + return true; // the extents overlap +} + + diff --git a/Extras/ConvexDecomposition/bestfit.h b/Extras/ConvexDecomposition/bestfit.h new file mode 100644 index 0000000..f2e78e5 --- /dev/null +++ b/Extras/ConvexDecomposition/bestfit.h @@ -0,0 +1,65 @@ +#ifndef BEST_FIT_H + +#define BEST_FIT_H + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +// This routine was released in 'snippet' form +// by John W. Ratcliff mailto:jratcliff@infiniplex.net +// on March 22, 2006. +// +// This routine computes the 'best fit' plane equation to +// a set of input data points with an optional per vertex +// weighting component. +// +// The implementation for this was lifted directly from +// David Eberly's Magic Software implementation. + +// computes the best fit plane to a collection of data points. +// returns the plane equation as A,B,C,D format. (Ax+By+Cz+D) + +bool getBestFitPlane(unsigned int vcount, // number of input data points + const float *points, // starting address of points array. + unsigned int vstride, // stride between input points. + const float *weights, // *optional point weighting values. + unsigned int wstride, // weight stride for each vertex. + float *plane); + + +float getBoundingRegion(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax); // returns the diagonal distance +bool overlapAABB(const float *bmin1,const float *bmax1,const float *bmin2,const float *bmax2); // return true if the two AABB's overlap. + +#endif diff --git a/Extras/ConvexDecomposition/bestfitobb.cpp b/Extras/ConvexDecomposition/bestfitobb.cpp new file mode 100644 index 0000000..2d60fd0 --- /dev/null +++ b/Extras/ConvexDecomposition/bestfitobb.cpp @@ -0,0 +1,173 @@ +#include "float_math.h" + +#include +#include +#include +#include +#include + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +#include "bestfitobb.h" +#include "float_math.h" + +// computes the OBB for this set of points relative to this transform matrix. +void computeOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,const float *matrix) +{ + const char *src = (const char *) points; + + float bmin[3] = { 1e9, 1e9, 1e9 }; + float bmax[3] = { -1e9, -1e9, -1e9 }; + + for (unsigned int i=0; i bmax[0] ) bmax[0] = t[0]; + if ( t[1] > bmax[1] ) bmax[1] = t[1]; + if ( t[2] > bmax[2] ) bmax[2] = t[2]; + + src+=pstride; + } + + + sides[0] = bmax[0]; + sides[1] = bmax[1]; + sides[2] = bmax[2]; + + if ( fabsf(bmin[0]) > sides[0] ) sides[0] = fabsf(bmin[0]); + if ( fabsf(bmin[1]) > sides[1] ) sides[1] = fabsf(bmin[1]); + if ( fabsf(bmin[2]) > sides[2] ) sides[2] = fabsf(bmin[2]); + + sides[0]*=2.0f; + sides[1]*=2.0f; + sides[2]*=2.0f; + +} + +void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *matrix) +{ + + float bmin[3]; + float bmax[3]; + + fm_getAABB(vcount,points,pstride,bmin,bmax); + + float center[3]; + + center[0] = (bmax[0]-bmin[0])*0.5f + bmin[0]; + center[1] = (bmax[1]-bmin[1])*0.5f + bmin[1]; + center[2] = (bmax[2]-bmin[2])*0.5f + bmin[2]; + + float ax = 0; + float ay = 0; + float az = 0; + + float sweep = 45.0f; // 180 degree sweep on all three axes. + float steps = 8.0f; // 16 steps on each axis. + + float bestVolume = 1e9; + float angle[3]={0.f,0.f,0.f}; + + while ( sweep >= 1 ) + { + + bool found = false; + + float stepsize = sweep / steps; + + for (float x=ax-sweep; x<=ax+sweep; x+=stepsize) + { + for (float y=ay-sweep; y<=ay+sweep; y+=stepsize) + { + for (float z=az-sweep; z<=az+sweep; z+=stepsize) + { + float pmatrix[16]; + + fm_eulerMatrix( x*FM_DEG_TO_RAD, y*FM_DEG_TO_RAD, z*FM_DEG_TO_RAD, pmatrix ); + + pmatrix[3*4+0] = center[0]; + pmatrix[3*4+1] = center[1]; + pmatrix[3*4+2] = center[2]; + + float psides[3]; + + computeOBB( vcount, points, pstride, psides, pmatrix ); + + float volume = psides[0]*psides[1]*psides[2]; // the volume of the cube + + if ( volume <= bestVolume ) + { + bestVolume = volume; + + sides[0] = psides[0]; + sides[1] = psides[1]; + sides[2] = psides[2]; + + angle[0] = ax; + angle[1] = ay; + angle[2] = az; + + memcpy(matrix,pmatrix,sizeof(float)*16); + found = true; // yes, we found an improvement. + } + } + } + } + + if ( found ) + { + + ax = angle[0]; + ay = angle[1]; + az = angle[2]; + + sweep*=0.5f; // sweep 1/2 the distance as the last time. + } + else + { + break; // no improvement, so just + } + + } + +} diff --git a/Extras/ConvexDecomposition/bestfitobb.h b/Extras/ConvexDecomposition/bestfitobb.h new file mode 100644 index 0000000..3141f58 --- /dev/null +++ b/Extras/ConvexDecomposition/bestfitobb.h @@ -0,0 +1,43 @@ +#ifndef BEST_FIT_OBB_H + +#define BEST_FIT_OBB_H + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + + +void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *matrix); + +#endif diff --git a/Extras/ConvexDecomposition/cd_hull.cpp b/Extras/ConvexDecomposition/cd_hull.cpp new file mode 100644 index 0000000..0fc8b51 --- /dev/null +++ b/Extras/ConvexDecomposition/cd_hull.cpp @@ -0,0 +1,3261 @@ +#include "float_math.h" + +#include +#include +#include +#include +#include +#include + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +#include "cd_hull.h" + +using namespace ConvexDecomposition; + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +#define PI 3.14159264f + +//***************************************************** +//***************************************************** +//********* Stan Melax's vector math template needed +//********* to use his hull building code. +//***************************************************** +//***************************************************** + +#define DEG2RAD (PI / 180.0f) +#define RAD2DEG (180.0f / PI) +#define SQRT_OF_2 (1.4142135f) +#define OFFSET(Class,Member) (((char*) (&(((Class*)NULL)-> Member )))- ((char*)NULL)) + +namespace ConvexDecomposition +{ + + +int argmin(float a[],int n); +float sqr(float a); +float clampf(float a) ; +float Round(float a,float precision); +float Interpolate(const float &f0,const float &f1,float alpha) ; + +template +void Swap(T &a,T &b) +{ + T tmp = a; + a=b; + b=tmp; +} + + + +template +T Max(const T &a,const T &b) +{ + return (a>b)?a:b; +} + +template +T Min(const T &a,const T &b) +{ + return (a=0&&i<2);return ((float*)this)[i];} + const float& operator[](int i) const {assert(i>=0&&i<2);return ((float*)this)[i];} +}; +inline float2 operator-( const float2& a, const float2& b ){return float2(a.x-b.x,a.y-b.y);} +inline float2 operator+( const float2& a, const float2& b ){return float2(a.x+b.x,a.y+b.y);} + +//--------- 3D --------- + +class float3 // 3D +{ + public: + float x,y,z; + float3(){x=0;y=0;z=0;}; + float3(float _x,float _y,float _z){x=_x;y=_y;z=_z;}; + //operator float *() { return &x;}; + float& operator[](int i) {assert(i>=0&&i<3);return ((float*)this)[i];} + const float& operator[](int i) const {assert(i>=0&&i<3);return ((float*)this)[i];} +# ifdef PLUGIN_3DSMAX + float3(const Point3 &p):x(p.x),y(p.y),z(p.z){} + operator Point3(){return *((Point3*)this);} +# endif +}; + + +float3& operator+=( float3 &a, const float3& b ); +float3& operator-=( float3 &a ,const float3& b ); +float3& operator*=( float3 &v ,const float s ); +float3& operator/=( float3 &v, const float s ); + +float magnitude( const float3& v ); +float3 normalize( const float3& v ); +float3 safenormalize(const float3 &v); +float3 vabs(const float3 &v); +float3 operator+( const float3& a, const float3& b ); +float3 operator-( const float3& a, const float3& b ); +float3 operator-( const float3& v ); +float3 operator*( const float3& v, const float s ); +float3 operator*( const float s, const float3& v ); +float3 operator/( const float3& v, const float s ); +inline int operator==( const float3 &a, const float3 &b ) { return (a.x==b.x && a.y==b.y && a.z==b.z); } +inline int operator!=( const float3 &a, const float3 &b ) { return (a.x!=b.x || a.y!=b.y || a.z!=b.z); } +// due to ambiguity and inconsistent standards ther are no overloaded operators for mult such as va*vb. +float dot( const float3& a, const float3& b ); +float3 cmul( const float3 &a, const float3 &b); +float3 cross( const float3& a, const float3& b ); +float3 Interpolate(const float3 &v0,const float3 &v1,float alpha); +float3 Round(const float3& a,float precision); +float3 VectorMax(const float3 &a, const float3 &b); +float3 VectorMin(const float3 &a, const float3 &b); + + + +class float3x3 +{ + public: + float3 x,y,z; // the 3 rows of the Matrix + float3x3(){} + float3x3(float xx,float xy,float xz,float yx,float yy,float yz,float zx,float zy,float zz):x(xx,xy,xz),y(yx,yy,yz),z(zx,zy,zz){} + float3x3(float3 _x,float3 _y,float3 _z):x(_x),y(_y),z(_z){} + float3& operator[](int i) {assert(i>=0&&i<3);return (&x)[i];} + const float3& operator[](int i) const {assert(i>=0&&i<3);return (&x)[i];} + float& operator()(int r, int c) {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];} + const float& operator()(int r, int c) const {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];} +}; +float3x3 Transpose( const float3x3& m ); +float3 operator*( const float3& v , const float3x3& m ); +float3 operator*( const float3x3& m , const float3& v ); +float3x3 operator*( const float3x3& m , const float& s ); +float3x3 operator*( const float3x3& ma, const float3x3& mb ); +float3x3 operator/( const float3x3& a, const float& s ) ; +float3x3 operator+( const float3x3& a, const float3x3& b ); +float3x3 operator-( const float3x3& a, const float3x3& b ); +float3x3 &operator+=( float3x3& a, const float3x3& b ); +float3x3 &operator-=( float3x3& a, const float3x3& b ); +float3x3 &operator*=( float3x3& a, const float& s ); +float Determinant(const float3x3& m ); +float3x3 Inverse(const float3x3& a); // its just 3x3 so we simply do that cofactor method + + +//-------- 4D Math -------- + +class float4 +{ +public: + float x,y,z,w; + float4(){x=0;y=0;z=0;w=0;}; + float4(float _x,float _y,float _z,float _w){x=_x;y=_y;z=_z;w=_w;} + float4(const float3 &v,float _w){x=v.x;y=v.y;z=v.z;w=_w;} + //operator float *() { return &x;}; + float& operator[](int i) {assert(i>=0&&i<4);return ((float*)this)[i];} + const float& operator[](int i) const {assert(i>=0&&i<4);return ((float*)this)[i];} + const float3& xyz() const { return *((float3*)this);} + float3& xyz() { return *((float3*)this);} +}; + + +struct D3DXMATRIX; + +class float4x4 +{ + public: + float4 x,y,z,w; // the 4 rows + float4x4(){} + float4x4(const float4 &_x, const float4 &_y, const float4 &_z, const float4 &_w):x(_x),y(_y),z(_z),w(_w){} + float4x4(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33 ) + :x(m00,m01,m02,m03),y(m10,m11,m12,m13),z(m20,m21,m22,m23),w(m30,m31,m32,m33){} + float& operator()(int r, int c) {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} + const float& operator()(int r, int c) const {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} + operator float* () {return &x.x;} + operator const float* () const {return &x.x;} + operator struct D3DXMATRIX* () { return (struct D3DXMATRIX*) this;} + operator const struct D3DXMATRIX* () const { return (struct D3DXMATRIX*) this;} +}; + + +int operator==( const float4 &a, const float4 &b ); +float4 Homogenize(const float3 &v3,const float &w=1.0f); // Turns a 3D float3 4D vector4 by appending w +float4 cmul( const float4 &a, const float4 &b); +float4 operator*( const float4 &v, float s); +float4 operator*( float s, const float4 &v); +float4 operator+( const float4 &a, const float4 &b); +float4 operator-( const float4 &a, const float4 &b); +float4x4 operator*( const float4x4& a, const float4x4& b ); +float4 operator*( const float4& v, const float4x4& m ); +float4x4 Inverse(const float4x4 &m); +float4x4 MatrixRigidInverse(const float4x4 &m); +float4x4 MatrixTranspose(const float4x4 &m); +float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf ); +float4x4 MatrixTranslation(const float3 &t); +float4x4 MatrixRotationZ(const float angle_radians); +float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up); +int operator==( const float4x4 &a, const float4x4 &b ); + + +//-------- Quaternion ------------ + +class Quaternion :public float4 +{ + public: + Quaternion() { x = y = z = 0.0f; w = 1.0f; } + Quaternion( float3 v, float t ) { v = normalize(v); w = cosf(t/2.0f); v = v*sinf(t/2.0f); x = v.x; y = v.y; z = v.z; } + Quaternion(float _x, float _y, float _z, float _w){x=_x;y=_y;z=_z;w=_w;} + float angle() const { return acosf(w)*2.0f; } + float3 axis() const { float3 a(x,y,z); if(fabsf(angle())<0.0000001f) return float3(1,0,0); return a*(1/sinf(angle()/2.0f)); } + float3 xdir() const { return float3( 1-2*(y*y+z*z), 2*(x*y+w*z), 2*(x*z-w*y) ); } + float3 ydir() const { return float3( 2*(x*y-w*z),1-2*(x*x+z*z), 2*(y*z+w*x) ); } + float3 zdir() const { return float3( 2*(x*z+w*y), 2*(y*z-w*x),1-2*(x*x+y*y) ); } + float3x3 getmatrix() const { return float3x3( xdir(), ydir(), zdir() ); } + operator float3x3() { return getmatrix(); } + void Normalize(); +}; + +Quaternion& operator*=(Quaternion& a, float s ); +Quaternion operator*( const Quaternion& a, float s ); +Quaternion operator*( const Quaternion& a, const Quaternion& b); +Quaternion operator+( const Quaternion& a, const Quaternion& b ); +Quaternion normalize( Quaternion a ); +float dot( const Quaternion &a, const Quaternion &b ); +float3 operator*( const Quaternion& q, const float3& v ); +float3 operator*( const float3& v, const Quaternion& q ); +Quaternion slerp( Quaternion a, const Quaternion& b, float interp ); +Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha); +Quaternion RotationArc(float3 v0, float3 v1 ); // returns quat q where q*v0=v1 +Quaternion Inverse(const Quaternion &q); +float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v); + + +//------ Euler Angle ----- + +Quaternion YawPitchRoll( float yaw, float pitch, float roll ); +float Yaw( const Quaternion& q ); +float Pitch( const Quaternion& q ); +float Roll( Quaternion q ); +float Yaw( const float3& v ); +float Pitch( const float3& v ); + + +//------- Plane ---------- + +class Plane +{ + public: + float3 normal; + float dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 + Plane(const float3 &n,float d):normal(n),dist(d){} + Plane():normal(),dist(0){} + void Transform(const float3 &position, const Quaternion &orientation); +}; + +inline Plane PlaneFlip(const Plane &plane){return Plane(-plane.normal,-plane.dist);} +inline int operator==( const Plane &a, const Plane &b ) { return (a.normal==b.normal && a.dist==b.dist); } +inline int coplanar( const Plane &a, const Plane &b ) { return (a==b || a==PlaneFlip(b)); } + + +//--------- Utility Functions ------ + +float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1); +float3 PlaneProject(const Plane &plane, const float3 &point); +float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1 +float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a); +float3 ThreePlaneIntersection(const Plane &p0,const Plane &p1, const Plane &p2); +int PolyHit(const float3 *vert,const int n,const float3 &v0, const float3 &v1, float3 *impact=NULL, float3 *normal=NULL); +int BoxInside(const float3 &p,const float3 &bmin, const float3 &bmax) ; +int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact); +float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint=NULL, float3 *vpoint=NULL); +float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2); +float3 NormalOf(const float3 *vert, const int n); +Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir0, const float3 &dir1); + + +float sqr(float a) {return a*a;} +float clampf(float a) {return Min(1.0f,Max(0.0f,a));} + + +float Round(float a,float precision) +{ + return floorf(0.5f+a/precision)*precision; +} + + +float Interpolate(const float &f0,const float &f1,float alpha) +{ + return f0*(1-alpha) + f1*alpha; +} + + +int argmin(float a[],int n) +{ + int r=0; + for(int i=1;i=1.0) { + return a; + } + float theta = acosf(d); + if(theta==0.0f) { return(a);} + return a*(sinf(theta-interp*theta)/sinf(theta)) + b*(sinf(interp*theta)/sinf(theta)); +} + + +Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha) { + return slerp(q0,q1,alpha); +} + + +Quaternion YawPitchRoll( float yaw, float pitch, float roll ) +{ + roll *= DEG2RAD; + yaw *= DEG2RAD; + pitch *= DEG2RAD; + return Quaternion(float3(0.0f,0.0f,1.0f),yaw)*Quaternion(float3(1.0f,0.0f,0.0f),pitch)*Quaternion(float3(0.0f,1.0f,0.0f),roll); +} + +float Yaw( const Quaternion& q ) +{ + float3 v; + v=q.ydir(); + return (v.y==0.0&&v.x==0.0) ? 0.0f: atan2f(-v.x,v.y)*RAD2DEG; +} + +float Pitch( const Quaternion& q ) +{ + float3 v; + v=q.ydir(); + return atan2f(v.z,sqrtf(sqr(v.x)+sqr(v.y)))*RAD2DEG; +} + +float Roll( Quaternion q ) +{ + q = Quaternion(float3(0.0f,0.0f,1.0f),-Yaw(q)*DEG2RAD) *q; + q = Quaternion(float3(1.0f,0.0f,0.0f),-Pitch(q)*DEG2RAD) *q; + return atan2f(-q.xdir().z,q.xdir().x)*RAD2DEG; +} + +float Yaw( const float3& v ) +{ + return (v.y==0.0&&v.x==0.0) ? 0.0f: atan2f(-v.x,v.y)*RAD2DEG; +} + +float Pitch( const float3& v ) +{ + return atan2f(v.z,sqrtf(sqr(v.x)+sqr(v.y)))*RAD2DEG; +} + + +//------------- Plane -------------- + + +void Plane::Transform(const float3 &position, const Quaternion &orientation) { + // Transforms the plane to the space defined by the + // given position/orientation. + float3 newnormal; + float3 origin; + + newnormal = Inverse(orientation)*normal; + origin = Inverse(orientation)*(-normal*dist - position); + + normal = newnormal; + dist = -dot(newnormal, origin); +} + + + + +//--------- utility functions ------------- + +// RotationArc() +// Given two vectors v0 and v1 this function +// returns quaternion q where q*v0==v1. +// Routine taken from game programming gems. +Quaternion RotationArc(float3 v0,float3 v1){ + Quaternion q; + v0 = normalize(v0); // Comment these two lines out if you know its not needed. + v1 = normalize(v1); // If vector is already unit length then why do it again? + float3 c = cross(v0,v1); + float d = dot(v0,v1); + if(d<=-1.0f) { return Quaternion(1,0,0,0);} // 180 about x axis + float s = sqrtf((1+d)*2); + q.x = c.x / s; + q.y = c.y / s; + q.z = c.z / s; + q.w = s /2.0f; + return q; +} + + +float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v) +{ + // builds a 4x4 transformation matrix based on orientation q and translation v + float qx2 = q.x*q.x; + float qy2 = q.y*q.y; + float qz2 = q.z*q.z; + + float qxqy = q.x*q.y; + float qxqz = q.x*q.z; + float qxqw = q.x*q.w; + float qyqz = q.y*q.z; + float qyqw = q.y*q.w; + float qzqw = q.z*q.w; + + return float4x4( + 1-2*(qy2+qz2), + 2*(qxqy+qzqw), + 2*(qxqz-qyqw), + 0 , + 2*(qxqy-qzqw), + 1-2*(qx2+qz2), + 2*(qyqz+qxqw), + 0 , + 2*(qxqz+qyqw), + 2*(qyqz-qxqw), + 1-2*(qx2+qy2), + 0 , + v.x , + v.y , + v.z , + 1.0f ); +} + + +float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1) +{ + // returns the point where the line p0-p1 intersects the plane n&d + float3 dif; + dif = p1-p0; + float dn= dot(plane.normal,dif); + float t = -(plane.dist+dot(plane.normal,p0) )/dn; + return p0 + (dif*t); +} + +float3 PlaneProject(const Plane &plane, const float3 &point) +{ + return point - plane.normal * (dot(point,plane.normal)+plane.dist); +} + +float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a) +{ + float3 w; + w = p1-p0; + float t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z)); + return p0+ w*t; +} + + +float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a) +{ + float3 w; + w = p1-p0; + float t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z)); + return t; +} + + + +float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2) +{ + // return the normal of the triangle + // inscribed by v0, v1, and v2 + float3 cp=cross(v1-v0,v2-v1); + float m=magnitude(cp); + if(m==0) return float3(1,0,0); + return cp*(1.0f/m); +} + + + +int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax) +{ + return (p.x >= bmin.x && p.x <=bmax.x && + p.y >= bmin.y && p.y <=bmax.y && + p.z >= bmin.z && p.z <=bmax.z ); +} + + +int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax,float3 *impact) +{ + if(BoxInside(v0,bmin,bmax)) + { + *impact=v0; + return 1; + } + if(v0.x<=bmin.x && v1.x>=bmin.x) + { + float a = (bmin.x-v0.x)/(v1.x-v0.x); + //v.x = bmin.x; + float vy = (1-a) *v0.y + a*v1.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) + { + impact->x = bmin.x; + impact->y = vy; + impact->z = vz; + return 1; + } + } + else if(v0.x >= bmax.x && v1.x <= bmax.x) + { + float a = (bmax.x-v0.x)/(v1.x-v0.x); + //v.x = bmax.x; + float vy = (1-a) *v0.y + a*v1.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) + { + impact->x = bmax.x; + impact->y = vy; + impact->z = vz; + return 1; + } + } + if(v0.y<=bmin.y && v1.y>=bmin.y) + { + float a = (bmin.y-v0.y)/(v1.y-v0.y); + float vx = (1-a) *v0.x + a*v1.x; + //v.y = bmin.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) + { + impact->x = vx; + impact->y = bmin.y; + impact->z = vz; + return 1; + } + } + else if(v0.y >= bmax.y && v1.y <= bmax.y) + { + float a = (bmax.y-v0.y)/(v1.y-v0.y); + float vx = (1-a) *v0.x + a*v1.x; + // vy = bmax.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) + { + impact->x = vx; + impact->y = bmax.y; + impact->z = vz; + return 1; + } + } + if(v0.z<=bmin.z && v1.z>=bmin.z) + { + float a = (bmin.z-v0.z)/(v1.z-v0.z); + float vx = (1-a) *v0.x + a*v1.x; + float vy = (1-a) *v0.y + a*v1.y; + // v.z = bmin.z; + if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) + { + impact->x = vx; + impact->y = vy; + impact->z = bmin.z; + return 1; + } + } + else if(v0.z >= bmax.z && v1.z <= bmax.z) + { + float a = (bmax.z-v0.z)/(v1.z-v0.z); + float vx = (1-a) *v0.x + a*v1.x; + float vy = (1-a) *v0.y + a*v1.y; + // v.z = bmax.z; + if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) + { + impact->x = vx; + impact->y = vy; + impact->z = bmax.z; + return 1; + } + } + return 0; +} + + +float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint, float3 *vpoint) +{ + float3 cp; + cp = normalize(cross(udir,vdir)); + + float distu = -dot(cp,ustart); + float distv = -dot(cp,vstart); + float dist = (float)fabs(distu-distv); + if(upoint) + { + Plane plane; + plane.normal = normalize(cross(vdir,cp)); + plane.dist = -dot(plane.normal,vstart); + *upoint = PlaneLineIntersection(plane,ustart,ustart+udir); + } + if(vpoint) + { + Plane plane; + plane.normal = normalize(cross(udir,cp)); + plane.dist = -dot(plane.normal,ustart); + *vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir); + } + return dist; +} + + +Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir1, const float3 &dir2) +{ + // routine taken from game programming gems. + // Implement track ball functionality to spin stuf on the screen + // cop center of projection + // cor center of rotation + // dir1 old mouse direction + // dir2 new mouse direction + // pretend there is a sphere around cor. Then find the points + // where dir1 and dir2 intersect that sphere. Find the + // rotation that takes the first point to the second. + float m; + // compute plane + float3 nrml = cor - cop; + float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop + nrml = normalize(nrml); + float dist = -dot(nrml,cor); + float3 u= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir1); + u=u-cor; + u=u*fudgefactor; + m= magnitude(u); + if(m>1) + { + u/=m; + } + else + { + u=u - (nrml * sqrtf(1-m*m)); + } + float3 v= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir2); + v=v-cor; + v=v*fudgefactor; + m= magnitude(v); + if(m>1) + { + v/=m; + } + else + { + v=v - (nrml * sqrtf(1-m*m)); + } + return RotationArc(u,v); +} + + +int countpolyhit=0; +int PolyHit(const float3 *vert, const int n, const float3 &v0, const float3 &v1, float3 *impact, float3 *normal) +{ + countpolyhit++; + int i; + float3 nrml(0,0,0); + for(i=0;i0) + { + return 0; + } + + float3 the_point; + // By using the cached plane distances d0 and d1 + // we can optimize the following: + // the_point = planelineintersection(nrml,dist,v0,v1); + float a = d0/(d0-d1); + the_point = v0*(1-a) + v1*a; + + + int inside=1; + for(int j=0;inside && j= 0.0); + } + if(inside) + { + if(normal){*normal=nrml;} + if(impact){*impact=the_point;} + } + return inside; +} + +//************************************************************************** +//************************************************************************** +//*** Stan Melax's array template, needed to compile his hull generation code +//************************************************************************** +//************************************************************************** + +template class ArrayRet; +template class Array { + public: + Array(int s=0); + Array(Array &array); + Array(ArrayRet &array); + ~Array(); + void allocate(int s); + void SetSize(int s); + void Pack(); + Type& Add(Type); + void AddUnique(Type); + int Contains(Type); + void Insert(Type,int); + int IndexOf(Type); + void Remove(Type); + void DelIndex(int i); + Type * element; + int count; + int array_size; + const Type &operator[](int i) const { assert(i>=0 && i=0 && i &operator=(Array &array); + Array &operator=(ArrayRet &array); + // operator ArrayRet &() { return *(ArrayRet *)this;} // this worked but i suspect could be dangerous +}; + +template class ArrayRet:public Array +{ +}; + +template Array::Array(int s) +{ + count=0; + array_size = 0; + element = NULL; + if(s) + { + allocate(s); + } +} + + +template Array::Array(Array &array) +{ + count=0; + array_size = 0; + element = NULL; + for(int i=0;i Array::Array(ArrayRet &array) +{ + *this = array; +} +template Array &Array::operator=(ArrayRet &array) +{ + count=array.count; + array_size = array.array_size; + element = array.element; + array.element=NULL; + array.count=0; + array.array_size=0; + return *this; +} + + +template Array &Array::operator=(Array &array) +{ + count=0; + for(int i=0;i Array::~Array() +{ + if (element != NULL) + { + free(element); + } + count=0;array_size=0;element=NULL; +} + +template void Array::allocate(int s) +{ + assert(s>0); + assert(s>=count); + Type *old = element; + array_size =s; + element = (Type *) malloc( sizeof(Type)*array_size); + assert(element); + for(int i=0;i void Array::SetSize(int s) +{ + if(s==0) + { + if(element) + { + free(element); + element = NULL; + } + array_size = s; + } + else + { + allocate(s); + } + count=s; +} + +template void Array::Pack() +{ + allocate(count); +} + +template Type& Array::Add(Type t) +{ + assert(count<=array_size); + if(count==array_size) + { + allocate((array_size)?array_size *2:16); + } + element[count++] = t; + return element[count-1]; +} + +template int Array::Contains(Type t) +{ + int i; + int found=0; + for(i=0;i void Array::AddUnique(Type t) +{ + if(!Contains(t)) Add(t); +} + + +template void Array::DelIndex(int i) +{ + assert(i void Array::Remove(Type t) +{ + int i; + for(i=0;i void Array::Insert(Type t,int k) +{ + int i=count; + Add(t); // to allocate space + while(i>k) + { + element[i]=element[i-1]; + i--; + } + assert(i==k); + element[k]=t; +} + + +template int Array::IndexOf(Type t) +{ + int i; + for(i=0;i vertices; + Array edges; + Array facets; + ConvexH(int vertices_size,int edges_size,int facets_size); +}; + +typedef ConvexH::HalfEdge HalfEdge; + +ConvexH::ConvexH(int vertices_size,int edges_size,int facets_size) + :vertices(vertices_size) + ,edges(edges_size) + ,facets(facets_size) +{ + vertices.count=vertices_size; + edges.count = edges_size; + facets.count = facets_size; +} + +ConvexH *ConvexHDup(ConvexH *src) { + ConvexH *dst = new ConvexH(src->vertices.count,src->edges.count,src->facets.count); + memcpy(dst->vertices.element,src->vertices.element,sizeof(float3)*src->vertices.count); + memcpy(dst->edges.element,src->edges.element,sizeof(HalfEdge)*src->edges.count); + memcpy(dst->facets.element,src->facets.element,sizeof(Plane)*src->facets.count); + return dst; +} + + +int PlaneTest(const Plane &p, const REAL3 &v) { + REAL a = dot(v,p.normal)+p.dist; + int flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR); + return flag; +} + +int SplitTest(ConvexH &convex,const Plane &plane) { + int flag=0; + for(int i=0;i= convex.edges.count || convex.edges[inext].p != convex.edges[i].p) { + inext = estart; + } + assert(convex.edges[inext].p == convex.edges[i].p); + int nb = convex.edges[i].ea; + assert(nb!=255); + if(nb==255 || nb==-1) return 0; + assert(nb!=-1); + assert(i== convex.edges[nb].ea); + } + for(i=0;i= convex.edges.count || convex.edges[i1].p != convex.edges[i].p) { + i1 = estart; + } + int i2 = i1+1; + if(i2>= convex.edges.count || convex.edges[i2].p != convex.edges[i].p) { + i2 = estart; + } + if(i==i2) continue; // i sliced tangent to an edge and created 2 meaningless edges + REAL3 localnormal = TriNormal(convex.vertices[convex.edges[i ].v], + convex.vertices[convex.edges[i1].v], + convex.vertices[convex.edges[i2].v]); + assert(dot(localnormal,convex.facets[convex.edges[i].p].normal)>0); + if(dot(localnormal,convex.facets[convex.edges[i].p].normal)<=0)return 0; + } + return 1; +} + +// back to back quads +ConvexH *test_btbq() { + ConvexH *convex = new ConvexH(4,8,2); + convex->vertices[0] = REAL3(0,0,0); + convex->vertices[1] = REAL3(1,0,0); + convex->vertices[2] = REAL3(1,1,0); + convex->vertices[3] = REAL3(0,1,0); + convex->facets[0] = Plane(REAL3(0,0,1),0); + convex->facets[1] = Plane(REAL3(0,0,-1),0); + convex->edges[0] = HalfEdge(7,0,0); + convex->edges[1] = HalfEdge(6,1,0); + convex->edges[2] = HalfEdge(5,2,0); + convex->edges[3] = HalfEdge(4,3,0); + + convex->edges[4] = HalfEdge(3,0,1); + convex->edges[5] = HalfEdge(2,3,1); + convex->edges[6] = HalfEdge(1,2,1); + convex->edges[7] = HalfEdge(0,1,1); + AssertIntact(*convex); + return convex; +} +ConvexH *test_cube() { + ConvexH *convex = new ConvexH(8,24,6); + convex->vertices[0] = REAL3(0,0,0); + convex->vertices[1] = REAL3(0,0,1); + convex->vertices[2] = REAL3(0,1,0); + convex->vertices[3] = REAL3(0,1,1); + convex->vertices[4] = REAL3(1,0,0); + convex->vertices[5] = REAL3(1,0,1); + convex->vertices[6] = REAL3(1,1,0); + convex->vertices[7] = REAL3(1,1,1); + + convex->facets[0] = Plane(REAL3(-1,0,0),0); + convex->facets[1] = Plane(REAL3(1,0,0),-1); + convex->facets[2] = Plane(REAL3(0,-1,0),0); + convex->facets[3] = Plane(REAL3(0,1,0),-1); + convex->facets[4] = Plane(REAL3(0,0,-1),0); + convex->facets[5] = Plane(REAL3(0,0,1),-1); + + convex->edges[0 ] = HalfEdge(11,0,0); + convex->edges[1 ] = HalfEdge(23,1,0); + convex->edges[2 ] = HalfEdge(15,3,0); + convex->edges[3 ] = HalfEdge(16,2,0); + + convex->edges[4 ] = HalfEdge(13,6,1); + convex->edges[5 ] = HalfEdge(21,7,1); + convex->edges[6 ] = HalfEdge( 9,5,1); + convex->edges[7 ] = HalfEdge(18,4,1); + + convex->edges[8 ] = HalfEdge(19,0,2); + convex->edges[9 ] = HalfEdge( 6,4,2); + convex->edges[10] = HalfEdge(20,5,2); + convex->edges[11] = HalfEdge( 0,1,2); + + convex->edges[12] = HalfEdge(22,3,3); + convex->edges[13] = HalfEdge( 4,7,3); + convex->edges[14] = HalfEdge(17,6,3); + convex->edges[15] = HalfEdge( 2,2,3); + + convex->edges[16] = HalfEdge( 3,0,4); + convex->edges[17] = HalfEdge(14,2,4); + convex->edges[18] = HalfEdge( 7,6,4); + convex->edges[19] = HalfEdge( 8,4,4); + + convex->edges[20] = HalfEdge(10,1,5); + convex->edges[21] = HalfEdge( 5,5,5); + convex->edges[22] = HalfEdge(12,7,5); + convex->edges[23] = HalfEdge( 1,3,5); + + + return convex; +} +ConvexH *ConvexHMakeCube(const REAL3 &bmin, const REAL3 &bmax) { + ConvexH *convex = test_cube(); + convex->vertices[0] = REAL3(bmin.x,bmin.y,bmin.z); + convex->vertices[1] = REAL3(bmin.x,bmin.y,bmax.z); + convex->vertices[2] = REAL3(bmin.x,bmax.y,bmin.z); + convex->vertices[3] = REAL3(bmin.x,bmax.y,bmax.z); + convex->vertices[4] = REAL3(bmax.x,bmin.y,bmin.z); + convex->vertices[5] = REAL3(bmax.x,bmin.y,bmax.z); + convex->vertices[6] = REAL3(bmax.x,bmax.y,bmin.z); + convex->vertices[7] = REAL3(bmax.x,bmax.y,bmax.z); + + convex->facets[0] = Plane(REAL3(-1,0,0), bmin.x); + convex->facets[1] = Plane(REAL3(1,0,0), -bmax.x); + convex->facets[2] = Plane(REAL3(0,-1,0), bmin.y); + convex->facets[3] = Plane(REAL3(0,1,0), -bmax.y); + convex->facets[4] = Plane(REAL3(0,0,-1), bmin.z); + convex->facets[5] = Plane(REAL3(0,0,1), -bmax.z); + return convex; +} +ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) +{ + int i; + int vertcountunder=0; + int vertcountover =0; + Array vertscoplanar; // existing vertex members of convex that are coplanar + vertscoplanar.count=0; + Array edgesplit; // existing edges that members of convex that cross the splitplane + edgesplit.count=0; + + assert(convex.edges.count<480); + + EdgeFlag edgeflag[512]; + VertFlag vertflag[256]; + PlaneFlag planeflag[128]; + HalfEdge tmpunderedges[512]; + Plane tmpunderplanes[128]; + Coplanar coplanaredges[512]; + int coplanaredges_num=0; + + Array createdverts; + // do the side-of-plane tests + for(i=0;i= convex.edges.count || convex.edges[e1].p!=currentplane) { + enextface = e1; + e1=estart; + } + HalfEdge &edge0 = convex.edges[e0]; + HalfEdge &edge1 = convex.edges[e1]; + HalfEdge &edgea = convex.edges[edge0.ea]; + + + planeside |= vertflag[edge0.v].planetest; + //if((vertflag[edge0.v].planetest & vertflag[edge1.v].planetest) == COPLANAR) { + // assert(ecop==-1); + // ecop=e; + //} + + + if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == OVER){ + // both endpoints over plane + edgeflag[e0].undermap = -1; + } + else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == UNDER) { + // at least one endpoint under, the other coplanar or under + + edgeflag[e0].undermap = under_edge_count; + tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; + tmpunderedges[under_edge_count].p = underplanescount; + if(edge0.ea < e0) { + // connect the neighbors + assert(edgeflag[edge0.ea].undermap !=-1); + tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; + tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; + } + under_edge_count++; + } + else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == COPLANAR) { + // both endpoints coplanar + // must check a 3rd point to see if UNDER + int e2 = e1+1; + if(e2>=convex.edges.count || convex.edges[e2].p!=currentplane) { + e2 = estart; + } + assert(convex.edges[e2].p==currentplane); + HalfEdge &edge2 = convex.edges[e2]; + if(vertflag[edge2.v].planetest==UNDER) { + + edgeflag[e0].undermap = under_edge_count; + tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; + tmpunderedges[under_edge_count].p = underplanescount; + tmpunderedges[under_edge_count].ea = -1; + // make sure this edge is added to the "coplanar" list + coplanaredge = under_edge_count; + vout = vertflag[edge0.v].undermap; + vin = vertflag[edge1.v].undermap; + under_edge_count++; + } + else { + edgeflag[e0].undermap = -1; + } + } + else if(vertflag[edge0.v].planetest == UNDER && vertflag[edge1.v].planetest == OVER) { + // first is under 2nd is over + + edgeflag[e0].undermap = under_edge_count; + tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; + tmpunderedges[under_edge_count].p = underplanescount; + if(edge0.ea < e0) { + assert(edgeflag[edge0.ea].undermap !=-1); + // connect the neighbors + tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; + tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; + vout = tmpunderedges[edgeflag[edge0.ea].undermap].v; + } + else { + Plane &p0 = convex.facets[edge0.p]; + Plane &pa = convex.facets[edgea.p]; + createdverts.Add(ThreePlaneIntersection(p0,pa,slice)); + //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]))); + //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])); + vout = vertcountunder++; + } + under_edge_count++; + /// hmmm something to think about: i might be able to output this edge regarless of + // wheter or not we know v-in yet. ok i;ll try this now: + tmpunderedges[under_edge_count].v = vout; + tmpunderedges[under_edge_count].p = underplanescount; + tmpunderedges[under_edge_count].ea = -1; + coplanaredge = under_edge_count; + under_edge_count++; + + if(vin!=-1) { + // we previously processed an edge where we came under + // now we know about vout as well + + // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! + } + + } + else if(vertflag[edge0.v].planetest == COPLANAR && vertflag[edge1.v].planetest == OVER) { + // first is coplanar 2nd is over + + edgeflag[e0].undermap = -1; + vout = vertflag[edge0.v].undermap; + // I hate this but i have to make sure part of this face is UNDER before ouputting this vert + int k=estart; + assert(edge0.p == currentplane); + while(!(planeside&UNDER) && k= vertcountunderold); // for debugging only + } + if(vout!=-1) { + // we previously processed an edge where we went over + // now we know vin too + // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! + } + // output edge + tmpunderedges[under_edge_count].v = vin; + tmpunderedges[under_edge_count].p = underplanescount; + edgeflag[e0].undermap = under_edge_count; + if(e0>edge0.ea) { + assert(edgeflag[edge0.ea].undermap !=-1); + // connect the neighbors + tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; + tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; + } + assert(edgeflag[e0].undermap == under_edge_count); + under_edge_count++; + } + else if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == COPLANAR) { + // first is over next is coplanar + + edgeflag[e0].undermap = -1; + vin = vertflag[edge1.v].undermap; + assert(vin!=-1); + if(vout!=-1) { + // we previously processed an edge where we came under + // now we know both endpoints + // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! + } + + } + else { + assert(0); + } + + + e0=e1; + e1++; // do the modulo at the beginning of the loop + + } while(e0!=estart) ; + e0 = enextface; + if(planeside&UNDER) { + planeflag[currentplane].undermap = underplanescount; + tmpunderplanes[underplanescount] = convex.facets[currentplane]; + underplanescount++; + } + else { + planeflag[currentplane].undermap = 0; + } + if(vout>=0 && (planeside&UNDER)) { + assert(vin>=0); + assert(coplanaredge>=0); + assert(coplanaredge!=511); + coplanaredges[coplanaredges_num].ea = coplanaredge; + coplanaredges[coplanaredges_num].v0 = vin; + coplanaredges[coplanaredges_num].v1 = vout; + coplanaredges_num++; + } + } + + // add the new plane to the mix: + if(coplanaredges_num>0) { + tmpunderplanes[underplanescount++]=slice; + } + for(i=0;i=coplanaredges_num) + { + assert(jvertices.count;j++) + { + d = Max(d,dot(convex->vertices[j],planes[i].normal)+planes[i].dist); + } + if(i==0 || d>md) + { + p=i; + md=d; + } + } + return (md>epsilon)?p:-1; +} + +template +inline int maxdir(const T *p,int count,const T &dir) +{ + assert(count); + int m=0; + float currDotm = dot(p[0], dir); + for(int i=1;i currDotm) + { + currDotm = currDoti; + m=i; + } + } + return m; +} + + +template +int maxdirfiltered(const T *p,int count,const T &dir,Array &allow) +{ + assert(count); + int m=-1; + float currDotm = dot(p[0], dir); + for(int i=0;icurrDotm) + { + currDotm = currDoti; + m=i; + } + } + } + } + assert(m!=-1); + return m; +} + +float3 orth(const float3 &v) +{ + float3 a=cross(v,float3(0,0,1)); + float3 b=cross(v,float3(0,1,0)); + return normalize((magnitude(a)>magnitude(b))?a:b); +} + + +template +int maxdirsterid(const T *p,int count,const T &dir,Array &allow) +{ + int m=-1; + while(m==-1) + { + m = maxdirfiltered(p,count,dir,allow); + if(allow[m]==3) return m; + T u = orth(dir); + T v = cross(u,dir); + int ma=-1; + for(float x = 0.0f ; x<= 360.0f ; x+= 45.0f) + { + float s = sinf(DEG2RAD*(x)); + float c = cosf(DEG2RAD*(x)); + int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow); + if(ma==m && mb==m) + { + allow[m]=3; + return m; + } + if(ma!=-1 && ma!=mb) // Yuck - this is really ugly + { + int mc = ma; + for(float xx = x-40.0f ; xx <= x ; xx+= 5.0f) + { + float s = sinf(DEG2RAD*(xx)); + float c = cosf(DEG2RAD*(xx)); + int md = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow); + if(mc==m && md==m) + { + allow[m]=3; + return m; + } + mc=md; + } + } + ma=mb; + } + allow[m]=0; + m=-1; + } + assert(0); + return m; +} + + + + +int operator ==(const int3 &a,const int3 &b) +{ + for(int i=0;i<3;i++) + { + if(a[i]!=b[i]) return 0; + } + return 1; +} + +int3 roll3(int3 a) +{ + int tmp=a[0]; + a[0]=a[1]; + a[1]=a[2]; + a[2]=tmp; + return a; +} +int isa(const int3 &a,const int3 &b) +{ + return ( a==b || roll3(a)==b || a==roll3(b) ); +} +int b2b(const int3 &a,const int3 &b) +{ + return isa(a,int3(b[2],b[1],b[0])); +} +int above(float3* vertices,const int3& t, const float3 &p, float epsilon) +{ + float3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]); + return (dot(n,p-vertices[t[0]]) > epsilon); // EPSILON??? +} +int hasedge(const int3 &t, int a,int b) +{ + for(int i=0;i<3;i++) + { + int i1= (i+1)%3; + if(t[i]==a && t[i1]==b) return 1; + } + return 0; +} +int hasvert(const int3 &t, int v) +{ + return (t[0]==v || t[1]==v || t[2]==v) ; +} +int shareedge(const int3 &a,const int3 &b) +{ + int i; + for(i=0;i<3;i++) + { + int i1= (i+1)%3; + if(hasedge(a,b[i1],b[i])) return 1; + } + return 0; +} + +class btHullTriangle; + +//Array tris; + +class btHullTriangle : public int3 +{ +public: + int3 n; + int id; + int vmax; + float rise; + Array* tris; + btHullTriangle(int a,int b,int c, Array* pTris):int3(a,b,c),n(-1,-1,-1) + { + tris = pTris; + id = tris->count; + tris->Add(this); + vmax=-1; + rise = 0.0f; + } + ~btHullTriangle() + { + assert((*tris)[id]==this); + (*tris)[id]=NULL; + } + int &neib(int a,int b); +}; + + +int &btHullTriangle::neib(int a,int b) +{ + static int er=-1; + int i; + for(i=0;i<3;i++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + if((*this)[i]==a && (*this)[i1]==b) return n[i2]; + if((*this)[i]==b && (*this)[i1]==a) return n[i2]; + } + assert(0); + return er; +} +void b2bfix(btHullTriangle* s,btHullTriangle*t, Array& tris) +{ + int i; + for(i=0;i<3;i++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + int a = (*s)[i1]; + int b = (*s)[i2]; + assert(tris[s->neib(a,b)]->neib(b,a) == s->id); + assert(tris[t->neib(a,b)]->neib(b,a) == t->id); + tris[s->neib(a,b)]->neib(b,a) = t->neib(b,a); + tris[t->neib(b,a)]->neib(a,b) = s->neib(a,b); + } +} + +void removeb2b(btHullTriangle* s,btHullTriangle*t, Array& tris) +{ + b2bfix(s,t, tris); + delete s; + delete t; +} + +void checkit(btHullTriangle *t, Array& tris) +{ + int i; + assert(tris[t->id]==t); + for(i=0;i<3;i++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + int a = (*t)[i1]; + int b = (*t)[i2]; + assert(a!=b); + assert( tris[t->n[i]]->neib(b,a) == t->id); + } +} +void extrude(btHullTriangle *t0,int v, Array& tris) +{ + int3 t= *t0; + int n = tris.count; + btHullTriangle* ta = new btHullTriangle(v,t[1],t[2], &tris); + ta->n = int3(t0->n[0],n+1,n+2); + tris[t0->n[0]]->neib(t[1],t[2]) = n+0; + btHullTriangle* tb = new btHullTriangle(v,t[2],t[0], &tris); + tb->n = int3(t0->n[1],n+2,n+0); + tris[t0->n[1]]->neib(t[2],t[0]) = n+1; + btHullTriangle* tc = new btHullTriangle(v,t[0],t[1], &tris); + tc->n = int3(t0->n[2],n+0,n+1); + tris[t0->n[2]]->neib(t[0],t[1]) = n+2; + checkit(ta, tris); + checkit(tb, tris); + checkit(tc, tris); + if(hasvert(*tris[ta->n[0]],v)) removeb2b(ta,tris[ta->n[0]], tris); + if(hasvert(*tris[tb->n[0]],v)) removeb2b(tb,tris[tb->n[0]], tris); + if(hasvert(*tris[tc->n[0]],v)) removeb2b(tc,tris[tc->n[0]], tris); + delete t0; + +} + +btHullTriangle *extrudable(float epsilon, Array& tris) +{ + int i; + btHullTriangle *t=NULL; + for(i=0;iriserise)) + { + t = tris[i]; + } + } + return (t->rise >epsilon)?t:NULL ; +} + +class int4 +{ +public: + int x,y,z,w; + int4(){}; + int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;} + const int& operator[](int i) const {return (&x)[i];} + int& operator[](int i) {return (&x)[i];} +}; + + + +int4 FindSimplex(float3 *verts,int verts_count,Array &allow) +{ + float3 basis[3]; + basis[0] = float3( 0.01f, 0.02f, 1.0f ); + int p0 = maxdirsterid(verts,verts_count, basis[0],allow); + int p1 = maxdirsterid(verts,verts_count,-basis[0],allow); + basis[0] = verts[p0]-verts[p1]; + if(p0==p1 || basis[0]==float3(0,0,0)) + return int4(-1,-1,-1,-1); + basis[1] = cross(float3( 1, 0.02f, 0),basis[0]); + basis[2] = cross(float3(-0.02f, 1, 0),basis[0]); + basis[1] = normalize( (magnitude(basis[1])>magnitude(basis[2])) ? basis[1]:basis[2]); + int p2 = maxdirsterid(verts,verts_count,basis[1],allow); + if(p2 == p0 || p2 == p1) + { + p2 = maxdirsterid(verts,verts_count,-basis[1],allow); + } + if(p2 == p0 || p2 == p1) + return int4(-1,-1,-1,-1); + basis[1] = verts[p2] - verts[p0]; + basis[2] = normalize(cross(basis[1],basis[0])); + int p3 = maxdirsterid(verts,verts_count,basis[2],allow); + if(p3==p0||p3==p1||p3==p2) p3 = maxdirsterid(verts,verts_count,-basis[2],allow); + if(p3==p0||p3==p1||p3==p2) + return int4(-1,-1,-1,-1); + assert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3)); + if(dot(verts[p3]-verts[p0],cross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {Swap(p2,p3);} + return int4(p0,p1,p2,p3); +} + +int calchullgen(float3 *verts,int verts_count, int vlimit,Array& tris) +{ + if(verts_count <4) return 0; + if(vlimit==0) vlimit=1000000000; + int j; + float3 bmin(*verts),bmax(*verts); + Array isextreme(verts_count); + Array allow(verts_count); + for(j=0;jn=int3(2,3,1); + btHullTriangle *t1 = new btHullTriangle(p[3],p[2],p[0], &tris); t1->n=int3(3,2,0); + btHullTriangle *t2 = new btHullTriangle(p[0],p[1],p[3], &tris); t2->n=int3(0,1,3); + btHullTriangle *t3 = new btHullTriangle(p[1],p[0],p[2], &tris); t3->n=int3(1,0,2); + isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1; + checkit(t0, tris);checkit(t1, tris);checkit(t2, tris);checkit(t3, tris); + + for(j=0;jvmax<0); + float3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); + t->vmax = maxdirsterid(verts,verts_count,n,allow); + t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]); + } + btHullTriangle *te; + vlimit-=4; + while(vlimit >0 && (te=extrudable(epsilon, tris))) + { + // int3 ti=*te; + int v=te->vmax; + assert(!isextreme[v]); // wtf we've already done this vertex + isextreme[v]=1; + //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already + j=tris.count; + while(j--) { + if(!tris[j]) continue; + int3 t=*tris[j]; + if(above(verts,t,verts[v],0.01f*epsilon)) + { + extrude(tris[j],v, tris); + } + } + // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle + j=tris.count; + while(j--) + { + if(!tris[j]) continue; + if(!hasvert(*tris[j],v)) break; + int3 nt=*tris[j]; + if(above(verts,nt,center,0.01f*epsilon) || magnitude(cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]))< epsilon*epsilon*0.1f ) + { + btHullTriangle *nb = tris[tris[j]->n[0]]; + assert(nb);assert(!hasvert(*nb,v));assert(nb->idvmax>=0) break; + float3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); + t->vmax = maxdirsterid(verts,verts_count,n,allow); + if(isextreme[t->vmax]) + { + t->vmax=-1; // already done that vertex - algorithm needs to be able to terminate. + } + else + { + t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]); + } + } + vlimit --; + } + return 1; +} + +int calchull(float3 *verts,int verts_count, int *&tris_out, int &tris_count,int vlimit, Array& tris) +{ + int rc=calchullgen(verts,verts_count, vlimit, tris) ; + if(!rc) return 0; + Array ts; + for(int i=0;i &planes,float bevangle, Array& tris) +{ + int i,j; + planes.count=0; + int rc = calchullgen(verts,verts_count,vlimit, tris); + if(!rc) return 0; + for(i=0;in[j]id) continue; + btHullTriangle *s = tris[t->n[j]]; + REAL3 snormal = TriNormal(verts[(*s)[0]],verts[(*s)[1]],verts[(*s)[2]]); + if(dot(snormal,p.normal)>=cos(bevangle*DEG2RAD)) continue; + REAL3 n = normalize(snormal+p.normal); + planes.Add(Plane(n,-dot(n,verts[maxdir(verts,verts_count,n)]))); + } + } + + for(i=0;i=0) + { + ConvexH *tmp = c; + c = ConvexHCrop(*tmp,planes[k]); + if(c==NULL) {c=tmp; break;} // might want to debug this case better!!! + if(!AssertIntact(*c)) {c=tmp; break;} // might want to debug this case better too!!! + delete tmp; + } + + assert(AssertIntact(*c)); + //return c; + faces_out = (int*)malloc(sizeof(int)*(1+c->facets.count+c->edges.count)); // new int[1+c->facets.count+c->edges.count]; + faces_count_out=0; + i=0; + faces_out[faces_count_out++]=-1; + k=0; + while(iedges.count) + { + j=1; + while(j+iedges.count && c->edges[i].p==c->edges[i+j].p) { j++; } + faces_out[faces_count_out++]=j; + while(j--) + { + faces_out[faces_count_out++] = c->edges[i].v; + i++; + } + k++; + } + faces_out[0]=k; // number of faces. + assert(k==c->facets.count); + assert(faces_count_out == 1+c->facets.count+c->edges.count); + verts_out = c->vertices.element; // new float3[c->vertices.count]; + verts_count_out = c->vertices.count; + for(i=0;ivertices.count;i++) + { + verts_out[i] = float3(c->vertices[i]); + } + c->vertices.count=c->vertices.array_size=0; c->vertices.element=NULL; + delete c; + return 1; +} + +int overhullv(float3 *verts, int verts_count,int maxplanes, + float3 *&verts_out, int &verts_count_out, int *&faces_out, int &faces_count_out ,float inflate,float bevangle,int vlimit, Array& tris) +{ + if(!verts_count) return 0; + extern int calchullpbev(float3 *verts,int verts_count,int vlimit, Array &planes,float bevangle, Array& tris) ; + Array planes; + int rc=calchullpbev(verts,verts_count,vlimit,planes,bevangle, tris) ; + if(!rc) return 0; + return overhull(planes.element,planes.count,verts,verts_count,maxplanes,verts_out,verts_count_out,faces_out,faces_count_out,inflate); +} + + +bool ComputeHull(unsigned int vcount,const float *vertices,PHullResult &result,unsigned int vlimit,float inflate, Array& arrtris) +{ + + int index_count; + int *faces; + float3 *verts_out; + int verts_count_out; + + if(inflate==0.0f) + { + int *tris_out; + int tris_count; + int ret = calchull( (float3 *) vertices, (int) vcount, tris_out, tris_count, vlimit, arrtris ); + if(!ret) return false; + result.mIndexCount = (unsigned int) (tris_count*3); + result.mFaceCount = (unsigned int) tris_count; + result.mVertices = (float*) vertices; + result.mVcount = (unsigned int) vcount; + result.mIndices = (unsigned int *) tris_out; + return true; + } + + int ret = overhullv((float3*)vertices,vcount,35,verts_out,verts_count_out,faces,index_count,inflate,120.0f,vlimit, arrtris); + if(!ret) return false; + + Array tris; + int n=faces[0]; + int k=1; + for(int i=0;i tris; + ok = ComputeHull(ovcount,vsource,hr,desc.mMaxVertices,skinwidth, tris); + + if ( ok ) + { + + // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table. + float *vscratch = (float *) malloc( sizeof(float)*hr.mVcount*3); + BringOutYourDead(hr.mVertices,hr.mVcount, vscratch, ovcount, hr.mIndices, hr.mIndexCount ); + + ret = QE_OK; + + if ( desc.HasHullFlag(QF_TRIANGLES) ) // if he wants the results as triangle! + { + result.mPolygons = false; + result.mNumOutputVertices = ovcount; + result.mOutputVertices = (float *)malloc( sizeof(float)*ovcount*3); + result.mNumFaces = hr.mFaceCount; + result.mNumIndices = hr.mIndexCount; + + result.mIndices = (unsigned int *) malloc( sizeof(unsigned int)*hr.mIndexCount); + + memcpy(result.mOutputVertices, vscratch, sizeof(float)*3*ovcount ); + + if ( desc.HasHullFlag(QF_REVERSE_ORDER) ) + { + + const unsigned int *source = hr.mIndices; + unsigned int *dest = result.mIndices; + + for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + } + } + } + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + float center[3]; + + center[0] = dx*0.5f + bmin[0]; + center[1] = dy*0.5f + bmin[1]; + center[2] = dz*0.5f + bmin[2]; + + if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 ) + { + + float len = FLT_MAX; + + if ( dx > EPSILON && dx < len ) len = dx; + if ( dy > EPSILON && dy < len ) len = dy; + if ( dz > EPSILON && dz < len ) len = dz; + + if ( len == FLT_MAX ) + { + dx = dy = dz = 0.01f; // one centimeter + } + else + { + if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge. + if ( dy < EPSILON ) dy = len * 0.05f; + if ( dz < EPSILON ) dz = len * 0.05f; + } + + float x1 = center[0] - dx; + float x2 = center[0] + dx; + + float y1 = center[1] - dy; + float y2 = center[1] + dy; + + float z1 = center[2] - dz; + float z2 = center[2] + dz; + + addPoint(vcount,vertices,x1,y1,z1); + addPoint(vcount,vertices,x2,y1,z1); + addPoint(vcount,vertices,x2,y2,z1); + addPoint(vcount,vertices,x1,y2,z1); + addPoint(vcount,vertices,x1,y1,z2); + addPoint(vcount,vertices,x2,y1,z2); + addPoint(vcount,vertices,x2,y2,z2); + addPoint(vcount,vertices,x1,y2,z2); + + return true; // return cube + + + } + else + { + if ( scale ) + { + scale[0] = dx; + scale[1] = dy; + scale[2] = dz; + + recip[0] = 1 / dx; + recip[1] = 1 / dy; + recip[2] = 1 / dz; + + center[0]*=recip[0]; + center[1]*=recip[1]; + center[2]*=recip[2]; + + } + + } + + + + vtx = (const char *) svertices; + + for (unsigned int i=0; i dist2 ) + { + v[0] = px; + v[1] = py; + v[2] = pz; + } + + break; + } + } + + if ( j == vcount ) + { + float *dest = &vertices[vcount*3]; + dest[0] = px; + dest[1] = py; + dest[2] = pz; + vcount++; + } + } + } + + // ok..now make sure we didn't prune so many vertices it is now invalid. + if ( 1 ) + { + float bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; + float bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; + + for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + } + } + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) + { + float cx = dx*0.5f + bmin[0]; + float cy = dy*0.5f + bmin[1]; + float cz = dz*0.5f + bmin[2]; + + float len = FLT_MAX; + + if ( dx >= EPSILON && dx < len ) len = dx; + if ( dy >= EPSILON && dy < len ) len = dy; + if ( dz >= EPSILON && dz < len ) len = dz; + + if ( len == FLT_MAX ) + { + dx = dy = dz = 0.01f; // one centimeter + } + else + { + if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge. + if ( dy < EPSILON ) dy = len * 0.05f; + if ( dz < EPSILON ) dz = len * 0.05f; + } + + float x1 = cx - dx; + float x2 = cx + dx; + + float y1 = cy - dy; + float y2 = cy + dy; + + float z1 = cz - dz; + float z2 = cz + dz; + + vcount = 0; // add box + + addPoint(vcount,vertices,x1,y1,z1); + addPoint(vcount,vertices,x2,y1,z1); + addPoint(vcount,vertices,x2,y2,z1); + addPoint(vcount,vertices,x1,y2,z1); + addPoint(vcount,vertices,x1,y1,z2); + addPoint(vcount,vertices,x2,y1,z2); + addPoint(vcount,vertices,x2,y2,z2); + addPoint(vcount,vertices,x1,y2,z2); + + return true; + } + } + + return true; +} + +void HullLibrary::BringOutYourDead(const float *verts,unsigned int vcount, float *overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount) +{ + unsigned int *used = (unsigned int *)malloc(sizeof(unsigned int)*vcount); + memset(used,0,sizeof(unsigned int)*vcount); + + ocount = 0; + + for (unsigned int i=0; i= 0 && v < vcount ); + + if ( used[v] ) // if already remapped + { + indices[i] = used[v]-1; // index to new array + } + else + { + + indices[i] = ocount; // new index mapping + + overts[ocount*3+0] = verts[v*3+0]; // copy old vert to new vert array + overts[ocount*3+1] = verts[v*3+1]; + overts[ocount*3+2] = verts[v*3+2]; + + ocount++; // increment output vert count + + assert( ocount >=0 && ocount <= vcount ); + + used[v] = ocount; // assign new index remapping + } + } + + free(used); +} + +} diff --git a/Extras/ConvexDecomposition/cd_hull.h b/Extras/ConvexDecomposition/cd_hull.h new file mode 100644 index 0000000..420e241 --- /dev/null +++ b/Extras/ConvexDecomposition/cd_hull.h @@ -0,0 +1,153 @@ +#ifndef CD_HULL_H + +#define CD_HULL_H + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +namespace ConvexDecomposition +{ + +class HullResult +{ +public: + HullResult(void) + { + mPolygons = true; + mNumOutputVertices = 0; + mOutputVertices = 0; + mNumFaces = 0; + mNumIndices = 0; + mIndices = 0; + } + bool mPolygons; // true if indices represents polygons, false indices are triangles + unsigned int mNumOutputVertices; // number of vertices in the output hull + float *mOutputVertices; // array of vertices, 3 floats each x,y,z + unsigned int mNumFaces; // the number of faces produced + unsigned int mNumIndices; // the total number of indices + unsigned int *mIndices; // pointer to indices. + +// If triangles, then indices are array indexes into the vertex list. +// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. +}; + +enum HullFlag +{ + QF_TRIANGLES = (1<<0), // report results as triangles, not polygons. + QF_REVERSE_ORDER = (1<<1), // reverse order of the triangle indices. + QF_SKIN_WIDTH = (1<<2), // extrude hull based on this skin width + QF_DEFAULT = 0 +}; + + +class HullDesc +{ +public: + HullDesc(void) + { + mFlags = QF_DEFAULT; + mVcount = 0; + mVertices = 0; + mVertexStride = sizeof(float)*3; + mNormalEpsilon = 0.001f; + mMaxVertices = 4096; // maximum number of points to be considered for a convex hull. + mMaxFaces = 4096; + mSkinWidth = 0.01f; // default is one centimeter + }; + + HullDesc(HullFlag flag, + unsigned int vcount, + const float *vertices, + unsigned int stride) + { + mFlags = flag; + mVcount = vcount; + mVertices = vertices; + mVertexStride = stride; + mNormalEpsilon = 0.001f; + mMaxVertices = 4096; + mSkinWidth = 0.01f; // default is one centimeter + } + + bool HasHullFlag(HullFlag flag) const + { + if ( mFlags & flag ) return true; + return false; + } + + void SetHullFlag(HullFlag flag) + { + mFlags|=flag; + } + + void ClearHullFlag(HullFlag flag) + { + mFlags&=~flag; + } + + unsigned int mFlags; // flags to use when generating the convex hull. + unsigned int mVcount; // number of vertices in the input point cloud + const float *mVertices; // the array of vertices. + unsigned int mVertexStride; // the stride of each vertex, in bytes. + float mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on. + float mSkinWidth; + unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull! + unsigned int mMaxFaces; +}; + +enum HullError +{ + QE_OK, // success! + QE_FAIL // failed. +}; + +class HullLibrary +{ +public: + + HullError CreateConvexHull(const HullDesc &desc, // describes the input request + HullResult &result); // contains the resulst + + HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it. + +private: + + void BringOutYourDead(const float *verts,unsigned int vcount, float *overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount); + + bool CleanupVertices(unsigned int svcount, + const float *svertices, + unsigned int stride, + unsigned int &vcount, // output number of vertices + float *vertices, // location to store the results. + float normalepsilon, + float *scale); +}; + +} + +#endif + diff --git a/Extras/ConvexDecomposition/cd_vector.h b/Extras/ConvexDecomposition/cd_vector.h new file mode 100644 index 0000000..bd1eff2 --- /dev/null +++ b/Extras/ConvexDecomposition/cd_vector.h @@ -0,0 +1,1185 @@ +#ifndef CD_VECTOR_H + +#define CD_VECTOR_H + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +#pragma warning(disable:4786) + +#include +#include +#include + +namespace ConvexDecomposition +{ + + +const float DEG_TO_RAD = ((2.0f * 3.14152654f) / 360.0f); +const float RAD_TO_DEG = (360.0f / (2.0f * 3.141592654f)); + +class Vector3d +{ +public: + Vector3d(void) { }; // null constructor, does not inialize point. + + Vector3d(const Vector3d &a) // constructor copies existing vector. + { + x = a.x; + y = a.y; + z = a.z; + }; + + Vector3d(float a,float b,float c) // construct with initial point. + { + x = a; + y = b; + z = c; + }; + + Vector3d(const float *t) + { + x = t[0]; + y = t[1]; + z = t[2]; + }; + + Vector3d(const int *t) + { + x = t[0]; + y = t[1]; + z = t[2]; + }; + + bool operator==(const Vector3d &a) const + { + return( a.x == x && a.y == y && a.z == z ); + }; + + bool operator!=(const Vector3d &a) const + { + return( a.x != x || a.y != y || a.z != z ); + }; + +// Operators + Vector3d& operator = (const Vector3d& A) // ASSIGNMENT (=) + { x=A.x; y=A.y; z=A.z; + return(*this); }; + + Vector3d operator + (const Vector3d& A) const // ADDITION (+) + { Vector3d Sum(x+A.x, y+A.y, z+A.z); + return(Sum); }; + + Vector3d operator - (const Vector3d& A) const // SUBTRACTION (-) + { Vector3d Diff(x-A.x, y-A.y, z-A.z); + return(Diff); }; + + Vector3d operator * (const float s) const // MULTIPLY BY SCALAR (*) + { Vector3d Scaled(x*s, y*s, z*s); + return(Scaled); }; + + + Vector3d operator + (const float s) const // ADD CONSTANT TO ALL 3 COMPONENTS (*) + { Vector3d Scaled(x+s, y+s, z+s); + return(Scaled); }; + + + + + Vector3d operator / (const float s) const // DIVIDE BY SCALAR (/) + { + float r = 1.0f / s; + Vector3d Scaled(x*r, y*r, z*r); + return(Scaled); + }; + + void operator /= (float A) // ACCUMULATED VECTOR ADDITION (/=) + { x/=A; y/=A; z/=A; }; + + void operator += (const Vector3d A) // ACCUMULATED VECTOR ADDITION (+=) + { x+=A.x; y+=A.y; z+=A.z; }; + void operator -= (const Vector3d A) // ACCUMULATED VECTOR SUBTRACTION (+=) + { x-=A.x; y-=A.y; z-=A.z; }; + void operator *= (const float s) // ACCUMULATED SCALAR MULTIPLICATION (*=) (bpc 4/24/2000) + {x*=s; y*=s; z*=s;} + + void operator += (const float A) // ACCUMULATED VECTOR ADDITION (+=) + { x+=A; y+=A; z+=A; }; + + + Vector3d operator - (void) const // NEGATION (-) + { Vector3d Negated(-x, -y, -z); + return(Negated); }; + + float operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY. + { return( (i==0)?x:((i==1)?y:z) ); }; + float & operator [] (const int i) + { return( (i==0)?x:((i==1)?y:z) ); }; +// + + // accessor methods. + float GetX(void) const { return x; }; + float GetY(void) const { return y; }; + float GetZ(void) const { return z; }; + + float X(void) const { return x; }; + float Y(void) const { return y; }; + float Z(void) const { return z; }; + + void SetX(float t) { x = t; }; + void SetY(float t) { y = t; }; + void SetZ(float t) { z = t; }; + + bool IsSame(const Vector3d &v,float epsilon) const + { + float dx = fabsf( x - v.x ); + if ( dx > epsilon ) return false; + float dy = fabsf( y - v.y ); + if ( dy > epsilon ) return false; + float dz = fabsf( z - v.z ); + if ( dz > epsilon ) return false; + return true; + } + + + float ComputeNormal(const Vector3d &A, + const Vector3d &B, + const Vector3d &C) + { + float vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag; + + vx = (B.x - C.x); + vy = (B.y - C.y); + vz = (B.z - C.z); + + wx = (A.x - B.x); + wy = (A.y - B.y); + wz = (A.z - B.z); + + vw_x = vy * wz - vz * wy; + vw_y = vz * wx - vx * wz; + vw_z = vx * wy - vy * wx; + + mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + + if ( mag < 0.000001f ) + { + mag = 0; + } + else + { + mag = 1.0f/mag; + } + + x = vw_x * mag; + y = vw_y * mag; + z = vw_z * mag; + + return mag; + } + + + void ScaleSumScale(float c0,float c1,const Vector3d &pos) + { + x = (x*c0) + (pos.x*c1); + y = (y*c0) + (pos.y*c1); + z = (z*c0) + (pos.z*c1); + } + + void SwapYZ(void) + { + float t = y; + y = z; + z = t; + }; + + void Get(float *v) const + { + v[0] = x; + v[1] = y; + v[2] = z; + }; + + void Set(const int *p) + { + x = (float) p[0]; + y = (float) p[1]; + z = (float) p[2]; + } + + void Set(const float *p) + { + x = (float) p[0]; + y = (float) p[1]; + z = (float) p[2]; + } + + + void Set(float a,float b,float c) + { + x = a; + y = b; + z = c; + }; + + void Zero(void) + { + x = y = z = 0; + }; + + const float* Ptr() const { return &x; } + float* Ptr() { return &x; } + + +// return -(*this). + Vector3d negative(void) const + { + Vector3d result; + result.x = -x; + result.y = -y; + result.z = -z; + return result; + } + + float Magnitude(void) const + { + return float(sqrt(x * x + y * y + z * z)); + }; + + float FastMagnitude(void) const + { + return float(sqrtf(x * x + y * y + z * z)); + }; + + float FasterMagnitude(void) const + { + return float(sqrtf(x * x + y * y + z * z)); + }; + + void Lerp(const Vector3d& from,const Vector3d& to,float slerp) + { + x = ((to.x - from.x) * slerp) + from.x; + y = ((to.y - from.y) * slerp) + from.y; + z = ((to.z - from.z) * slerp) + from.z; + }; + + // Highly specialized interpolate routine. Will compute the interpolated position + // shifted forward or backwards along the ray defined between (from) and (to). + // Reason for existance is so that when a bullet collides with a wall, for + // example, you can generate a graphic effect slightly *before* it hit the + // wall so that the effect doesn't sort into the wall itself. + void Interpolate(const Vector3d &from,const Vector3d &to,float offset) + { + x = to.x-from.x; + y = to.y-from.y; + z = to.z-from.z; + float d = sqrtf( x*x + y*y + z*z ); + float recip = 1.0f / d; + x*=recip; + y*=recip; + z*=recip; // normalize vector + d+=offset; // shift along ray + x = x*d + from.x; + y = y*d + from.y; + z = z*d + from.z; + }; + + bool BinaryEqual(const Vector3d &p) const + { + const int *source = (const int *) &x; + const int *dest = (const int *) &p.x; + + if ( source[0] == dest[0] && + source[1] == dest[1] && + source[2] == dest[2] ) return true; + + return false; + }; + + /*bool BinaryEqual(const Vector3d &p) const + { + if ( x == p.x && y == p.y && z == p.z ) return true; + return false; + } + */ + + + +/** Computes the reflection vector between two vectors.*/ + void Reflection(const Vector3d &a,const Vector3d &b)// compute reflection vector. + { + Vector3d c; + Vector3d d; + + float dot = a.Dot(b) * 2.0f; + + c = b * dot; + + d = c - a; + + x = -d.x; + y = -d.y; + z = -d.z; + }; + + void AngleAxis(float angle,const Vector3d& axis) + { + x = axis.x*angle; + y = axis.y*angle; + z = axis.z*angle; + }; + + float Length(void) const // length of vector. + { + return float(sqrt( x*x + y*y + z*z )); + }; + + + float ComputePlane(const Vector3d &A, + const Vector3d &B, + const Vector3d &C) + { + float vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag; + + vx = (B.x - C.x); + vy = (B.y - C.y); + vz = (B.z - C.z); + + wx = (A.x - B.x); + wy = (A.y - B.y); + wz = (A.z - B.z); + + vw_x = vy * wz - vz * wy; + vw_y = vz * wx - vx * wz; + vw_z = vx * wy - vy * wx; + + mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + + if ( mag < 0.000001f ) + { + mag = 0; + } + else + { + mag = 1.0f/mag; + } + + x = vw_x * mag; + y = vw_y * mag; + z = vw_z * mag; + + + float D = 0.0f - ((x*A.x)+(y*A.y)+(z*A.z)); + + return D; + } + + + float FastLength(void) const // length of vector. + { + return float(sqrtf( x*x + y*y + z*z )); + }; + + + float FasterLength(void) const // length of vector. + { + return float(sqrtf( x*x + y*y + z*z )); + }; + + float Length2(void) const // squared distance, prior to square root. + { + float l2 = x*x+y*y+z*z; + return l2; + }; + + float Distance(const Vector3d &a) const // distance between two points. + { + Vector3d d(a.x-x,a.y-y,a.z-z); + return d.Length(); + } + + float FastDistance(const Vector3d &a) const // distance between two points. + { + Vector3d d(a.x-x,a.y-y,a.z-z); + return d.FastLength(); + } + + float FasterDistance(const Vector3d &a) const // distance between two points. + { + Vector3d d(a.x-x,a.y-y,a.z-z); + return d.FasterLength(); + } + + + float DistanceXY(const Vector3d &a) const + { + float dx = a.x - x; + float dy = a.y - y; + float dist = dx*dx + dy*dy; + return dist; + } + + float Distance2(const Vector3d &a) const // squared distance. + { + float dx = a.x - x; + float dy = a.y - y; + float dz = a.z - z; + return dx*dx + dy*dy + dz*dz; + }; + + float Partial(const Vector3d &p) const + { + return (x*p.y) - (p.x*y); + } + + float Area(const Vector3d &p1,const Vector3d &p2) const + { + float A = Partial(p1); + A+= p1.Partial(p2); + A+= p2.Partial(*this); + return A*0.5f; + } + + inline float Normalize(void) // normalize to a unit vector, returns distance. + { + float d = sqrtf( static_cast< float >( x*x + y*y + z*z ) ); + if ( d > 0 ) + { + float r = 1.0f / d; + x *= r; + y *= r; + z *= r; + } + else + { + x = y = z = 1; + } + return d; + }; + + inline float FastNormalize(void) // normalize to a unit vector, returns distance. + { + float d = sqrt( static_cast< float >( x*x + y*y + z*z ) ); + if ( d > 0 ) + { + float r = 1.0f / d; + x *= r; + y *= r; + z *= r; + } + else + { + x = y = z = 1; + } + return d; + }; + + inline float FasterNormalize(void) // normalize to a unit vector, returns distance. + { + float d = sqrtf( static_cast< float >( x*x + y*y + z*z ) ); + if ( d > 0 ) + { + float r = 1.0f / d; + x *= r; + y *= r; + z *= r; + } + else + { + x = y = z = 1; + } + return d; + }; + + + + + float Dot(const Vector3d &a) const // computes dot product. + { + return (x * a.x + y * a.y + z * a.z ); + }; + + + Vector3d Cross( const Vector3d& other ) const + { + Vector3d result( y*other.z - z*other.y, z*other.x - x*other.z, x*other.y - y*other.x ); + + return result; + } + + void Cross(const Vector3d &a,const Vector3d &b) // cross two vectors result in this one. + { + x = a.y*b.z - a.z*b.y; + y = a.z*b.x - a.x*b.z; + z = a.x*b.y - a.y*b.x; + }; + + /******************************************/ + // Check if next edge (b to c) turns inward + // + // Edge from a to b is already in face + // Edge from b to c is being considered for addition to face + /******************************************/ + bool Concave(const Vector3d& a,const Vector3d& b) + { + float vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag,nx,ny,nz,mag_a,mag_b; + + wx = b.x - a.x; + wy = b.y - a.y; + wz = b.z - a.z; + + mag_a = (float) sqrtf((wx * wx) + (wy * wy) + (wz * wz)); + + vx = x - b.x; + vy = y - b.y; + vz = z - b.z; + + mag_b = (float) sqrtf((vx * vx) + (vy * vy) + (vz * vz)); + + vw_x = (vy * wz) - (vz * wy); + vw_y = (vz * wx) - (vx * wz); + vw_z = (vx * wy) - (vy * wx); + + mag = (float) sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + + // Check magnitude of cross product, which is a sine function + // i.e., mag (a x b) = mag (a) * mag (b) * sin (theta); + // If sin (theta) small, then angle between edges is very close to + // 180, which we may want to call a concavity. Setting the + // CONCAVITY_TOLERANCE value greater than about 0.01 MAY cause + // face consolidation to get stuck on particular face. Most meshes + // convert properly with a value of 0.0 + + if (mag/(mag_a*mag_b) <= 0.0f ) return true; + + mag = 1.0f / mag; + + nx = vw_x * mag; + ny = vw_y * mag; + nz = vw_z * mag; + + // Dot product of tri normal with cross product result will + // yield positive number if edges are convex (+1.0 if two tris + // are coplanar), negative number if edges are concave (-1.0 if + // two tris are coplanar.) + + mag = ( x * nx) + ( y * ny) + ( z * nz); + + if (mag > 0.0f ) return false; + + return(true); + }; + + bool PointTestXY(const Vector3d &i,const Vector3d &j) const + { + if (((( i.y <= y ) && ( y < j.y )) || + (( j.y <= y ) && ( y < i.y ))) && + ( x < (j.x - i.x) * (y - i.y) / (j.y - i.y) + i.x)) return true; + return false; + } + + // test to see if this point is inside the triangle specified by + // these three points on the X/Y plane. + bool PointInTriXY(const Vector3d &p1, + const Vector3d &p2, + const Vector3d &p3) const + { + float ax = p3.x - p2.x; + float ay = p3.y - p2.y; + float bx = p1.x - p3.x; + float by = p1.y - p3.y; + float cx = p2.x - p1.x; + float cy = p2.y - p1.y; + float apx = x - p1.x; + float apy = y - p1.y; + float bpx = x - p2.x; + float bpy = y - p2.y; + float cpx = x - p3.x; + float cpy = y - p3.y; + + float aCROSSbp = ax*bpy - ay*bpx; + float cCROSSap = cx*apy - cy*apx; + float bCROSScp = bx*cpy - by*cpx; + + return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); + }; + + // test to see if this point is inside the triangle specified by + // these three points on the X/Y plane. + bool PointInTriYZ(const Vector3d &p1, + const Vector3d &p2, + const Vector3d &p3) const + { + float ay = p3.y - p2.y; + float az = p3.z - p2.z; + float by = p1.y - p3.y; + float bz = p1.z - p3.z; + float cy = p2.y - p1.y; + float cz = p2.z - p1.z; + float apy = y - p1.y; + float apz = z - p1.z; + float bpy = y - p2.y; + float bpz = z - p2.z; + float cpy = y - p3.y; + float cpz = z - p3.z; + + float aCROSSbp = ay*bpz - az*bpy; + float cCROSSap = cy*apz - cz*apy; + float bCROSScp = by*cpz - bz*cpy; + + return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); + }; + + + // test to see if this point is inside the triangle specified by + // these three points on the X/Y plane. + bool PointInTriXZ(const Vector3d &p1, + const Vector3d &p2, + const Vector3d &p3) const + { + float az = p3.z - p2.z; + float ax = p3.x - p2.x; + float bz = p1.z - p3.z; + float bx = p1.x - p3.x; + float cz = p2.z - p1.z; + float cx = p2.x - p1.x; + float apz = z - p1.z; + float apx = x - p1.x; + float bpz = z - p2.z; + float bpx = x - p2.x; + float cpz = z - p3.z; + float cpx = x - p3.x; + + float aCROSSbp = az*bpx - ax*bpz; + float cCROSSap = cz*apx - cx*apz; + float bCROSScp = bz*cpx - bx*cpz; + + return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); + }; + + // Given a point and a line (defined by two points), compute the closest point + // in the line. (The line is treated as infinitely long.) + void NearestPointInLine(const Vector3d &point, + const Vector3d &line0, + const Vector3d &line1) + { + Vector3d &nearestPoint = *this; + Vector3d lineDelta = line1 - line0; + + // Handle degenerate lines + if ( lineDelta == Vector3d(0, 0, 0) ) + { + nearestPoint = line0; + } + else + { + float delta = (point-line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); + nearestPoint = line0 + lineDelta*delta; + } + } + + // Given a point and a line segment (defined by two points), compute the closest point + // in the line. Cap the point at the endpoints of the line segment. + void NearestPointInLineSegment(const Vector3d &point, + const Vector3d &line0, + const Vector3d &line1) + { + Vector3d &nearestPoint = *this; + Vector3d lineDelta = line1 - line0; + + // Handle degenerate lines + if ( lineDelta == Vector3d(0, 0, 0) ) + { + nearestPoint = line0; + } + else + { + float delta = (point-line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); + + // Clamp the point to conform to the segment's endpoints + if ( delta < 0 ) + delta = 0; + else if ( delta > 1 ) + delta = 1; + + nearestPoint = line0 + lineDelta*delta; + } + } + + // Given a point and a plane (defined by three points), compute the closest point + // in the plane. (The plane is unbounded.) + void NearestPointInPlane(const Vector3d &point, + const Vector3d &triangle0, + const Vector3d &triangle1, + const Vector3d &triangle2) + { + Vector3d &nearestPoint = *this; + Vector3d lineDelta0 = triangle1 - triangle0; + Vector3d lineDelta1 = triangle2 - triangle0; + Vector3d pointDelta = point - triangle0; + Vector3d normal; + + // Get the normal of the polygon (doesn't have to be a unit vector) + normal.Cross(lineDelta0, lineDelta1); + + float delta = normal.Dot(pointDelta) / normal.Dot(normal); + nearestPoint = point - normal*delta; + } + + // Given a point and a plane (defined by a coplanar point and a normal), compute the closest point + // in the plane. (The plane is unbounded.) + void NearestPointInPlane(const Vector3d &point, + const Vector3d &planePoint, + const Vector3d &planeNormal) + { + Vector3d &nearestPoint = *this; + Vector3d pointDelta = point - planePoint; + + float delta = planeNormal.Dot(pointDelta) / planeNormal.Dot(planeNormal); + nearestPoint = point - planeNormal*delta; + } + + // Given a point and a triangle (defined by three points), compute the closest point + // in the triangle. Clamp the point so it's confined to the area of the triangle. + void NearestPointInTriangle(const Vector3d &point, + const Vector3d &triangle0, + const Vector3d &triangle1, + const Vector3d &triangle2) + { + static const Vector3d zeroVector(0, 0, 0); + + Vector3d &nearestPoint = *this; + + Vector3d lineDelta0 = triangle1 - triangle0; + Vector3d lineDelta1 = triangle2 - triangle0; + + // Handle degenerate triangles + if ( (lineDelta0 == zeroVector) || (lineDelta1 == zeroVector) ) + { + nearestPoint.NearestPointInLineSegment(point, triangle1, triangle2); + } + else if ( lineDelta0 == lineDelta1 ) + { + nearestPoint.NearestPointInLineSegment(point, triangle0, triangle1); + } + + else + { + Vector3d axis[3]; + axis[0].NearestPointInLine(triangle0, triangle1, triangle2); + axis[1].NearestPointInLine(triangle1, triangle0, triangle2); + axis[2].NearestPointInLine(triangle2, triangle0, triangle1); + + float axisDot[3]; + axisDot[0] = (triangle0-axis[0]).Dot(point-axis[0]); + axisDot[1] = (triangle1-axis[1]).Dot(point-axis[1]); + axisDot[2] = (triangle2-axis[2]).Dot(point-axis[2]); + + bool bForce = true; + float bestMagnitude2 = 0; + float closeMagnitude2; + Vector3d closePoint; + + if ( axisDot[0] < 0 ) + { + closePoint.NearestPointInLineSegment(point, triangle1, triangle2); + closeMagnitude2 = point.Distance2(closePoint); + if ( bForce || (bestMagnitude2 > closeMagnitude2) ) + { + bForce = false; + bestMagnitude2 = closeMagnitude2; + nearestPoint = closePoint; + } + } + if ( axisDot[1] < 0 ) + { + closePoint.NearestPointInLineSegment(point, triangle0, triangle2); + closeMagnitude2 = point.Distance2(closePoint); + if ( bForce || (bestMagnitude2 > closeMagnitude2) ) + { + bForce = false; + bestMagnitude2 = closeMagnitude2; + nearestPoint = closePoint; + } + } + if ( axisDot[2] < 0 ) + { + closePoint.NearestPointInLineSegment(point, triangle0, triangle1); + closeMagnitude2 = point.Distance2(closePoint); + if ( bForce || (bestMagnitude2 > closeMagnitude2) ) + { + bForce = false; + bestMagnitude2 = closeMagnitude2; + nearestPoint = closePoint; + } + } + + // If bForce is true at this point, it means the nearest point lies + // inside the triangle; use the nearest-point-on-a-plane equation + if ( bForce ) + { + Vector3d normal; + + // Get the normal of the polygon (doesn't have to be a unit vector) + normal.Cross(lineDelta0, lineDelta1); + + Vector3d pointDelta = point - triangle0; + float delta = normal.Dot(pointDelta) / normal.Dot(normal); + + nearestPoint = point - normal*delta; + } + } + } + + +//private: + + float x; + float y; + float z; +}; + + +class Vector2d +{ +public: + Vector2d(void) { }; // null constructor, does not inialize point. + + Vector2d(const Vector2d &a) // constructor copies existing vector. + { + x = a.x; + y = a.y; + }; + + Vector2d(const float *t) + { + x = t[0]; + y = t[1]; + }; + + + Vector2d(float a,float b) // construct with initial point. + { + x = a; + y = b; + }; + + const float* Ptr() const { return &x; } + float* Ptr() { return &x; } + + Vector2d & operator+=(const Vector2d &a) // += operator. + { + x+=a.x; + y+=a.y; + return *this; + }; + + Vector2d & operator-=(const Vector2d &a) + { + x-=a.x; + y-=a.y; + return *this; + }; + + Vector2d & operator*=(const Vector2d &a) + { + x*=a.x; + y*=a.y; + return *this; + }; + + Vector2d & operator/=(const Vector2d &a) + { + x/=a.x; + y/=a.y; + return *this; + }; + + bool operator==(const Vector2d &a) const + { + if ( a.x == x && a.y == y ) return true; + return false; + }; + + bool operator!=(const Vector2d &a) const + { + if ( a.x != x || a.y != y ) return true; + return false; + }; + + Vector2d operator+(Vector2d a) const + { + a.x+=x; + a.y+=y; + return a; + }; + + Vector2d operator-(Vector2d a) const + { + a.x = x-a.x; + a.y = y-a.y; + return a; + }; + + Vector2d operator - (void) const + { + return negative(); + }; + + Vector2d operator*(Vector2d a) const + { + a.x*=x; + a.y*=y; + return a; + }; + + Vector2d operator*(float c) const + { + Vector2d a; + + a.x = x * c; + a.y = y * c; + + return a; + }; + + Vector2d operator/(Vector2d a) const + { + a.x = x/a.x; + a.y = y/a.y; + return a; + }; + + + float Dot(const Vector2d &a) const // computes dot product. + { + return (x * a.x + y * a.y ); + }; + + float GetX(void) const { return x; }; + float GetY(void) const { return y; }; + + void SetX(float t) { x = t; }; + void SetY(float t) { y = t; }; + + void Set(float a,float b) + { + x = a; + y = b; + }; + + void Zero(void) + { + x = y = 0; + }; + + Vector2d negative(void) const + { + Vector2d result; + result.x = -x; + result.y = -y; + return result; + } + + float magnitude(void) const + { + return (float) sqrtf(x * x + y * y ); + } + + float fastmagnitude(void) const + { + return (float) sqrtf(x * x + y * y ); + } + + float fastermagnitude(void) const + { + return (float) sqrtf( x * x + y * y ); + } + + void Reflection(Vector2d &a,Vector2d &b); // compute reflection vector. + + float Length(void) const // length of vector. + { + return float(sqrtf( x*x + y*y )); + }; + + float FastLength(void) const // length of vector. + { + return float(sqrtf( x*x + y*y )); + }; + + float FasterLength(void) const // length of vector. + { + return float(sqrtf( x*x + y*y )); + }; + + float Length2(void) // squared distance, prior to square root. + { + return x*x+y*y; + } + + float Distance(const Vector2d &a) const // distance between two points. + { + float dx = a.x - x; + float dy = a.y - y; + float d = dx*dx+dy*dy; + return sqrtf(d); + }; + + float FastDistance(const Vector2d &a) const // distance between two points. + { + float dx = a.x - x; + float dy = a.y - y; + float d = dx*dx+dy*dy; + return sqrtf(d); + }; + + float FasterDistance(const Vector2d &a) const // distance between two points. + { + float dx = a.x - x; + float dy = a.y - y; + float d = dx*dx+dy*dy; + return sqrtf(d); + }; + + float Distance2(Vector2d &a) // squared distance. + { + float dx = a.x - x; + float dy = a.y - y; + return dx*dx + dy *dy; + }; + + void Lerp(const Vector2d& from,const Vector2d& to,float slerp) + { + x = ((to.x - from.x)*slerp) + from.x; + y = ((to.y - from.y)*slerp) + from.y; + }; + + + void Cross(const Vector2d &a,const Vector2d &b) // cross two vectors result in this one. + { + x = a.y*b.x - a.x*b.y; + y = a.x*b.x - a.x*b.x; + }; + + float Normalize(void) // normalize to a unit vector, returns distance. + { + float l = Length(); + if ( l != 0 ) + { + l = float( 1 ) / l; + x*=l; + y*=l; + } + else + { + x = y = 0; + } + return l; + }; + + float FastNormalize(void) // normalize to a unit vector, returns distance. + { + float l = FastLength(); + if ( l != 0 ) + { + l = float( 1 ) / l; + x*=l; + y*=l; + } + else + { + x = y = 0; + } + return l; + }; + + float FasterNormalize(void) // normalize to a unit vector, returns distance. + { + float l = FasterLength(); + if ( l != 0 ) + { + l = float( 1 ) / l; + x*=l; + y*=l; + } + else + { + x = y = 0; + } + return l; + }; + + + float x; + float y; +}; + +class Line +{ +public: + Line(const Vector3d &from,const Vector3d &to) + { + mP1 = from; + mP2 = to; + }; + // JWR Test for the intersection of two lines. + + bool Intersect(const Line& src,Vector3d §); +private: + Vector3d mP1; + Vector3d mP2; + +}; + + +typedef std::vector< Vector3d > Vector3dVector; +typedef std::vector< Vector2d > Vector2dVector; + +inline Vector3d operator * (float s, const Vector3d &v ) +{ + Vector3d Scaled(v.x*s, v.y*s, v.z*s); + return(Scaled); +} + +inline Vector2d operator * (float s, const Vector2d &v ) + { + Vector2d Scaled(v.x*s, v.y*s); + return(Scaled); + } + +} + +#endif diff --git a/Extras/ConvexDecomposition/cd_wavefront.cpp b/Extras/ConvexDecomposition/cd_wavefront.cpp new file mode 100644 index 0000000..54e8bdf --- /dev/null +++ b/Extras/ConvexDecomposition/cd_wavefront.cpp @@ -0,0 +1,860 @@ +#include +#include +#include +#include +#include + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// +#include "float_math.h" + +#include "cd_wavefront.h" + + +using namespace ConvexDecomposition; + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +#include + +namespace ConvexDecomposition +{ + +typedef std::vector< int > IntVector; +typedef std::vector< float > FloatVector; + +#if defined(__APPLE__) || defined(__CELLOS_LV2__) +#define stricmp(a, b) strcasecmp((a), (b)) +#endif + +/*******************************************************************/ +/******************** InParser.h ********************************/ +/*******************************************************************/ +class InPlaceParserInterface +{ +public: + virtual ~InPlaceParserInterface () {} ; + + virtual int ParseLine(int lineno,int argc,const char **argv) =0; // return TRUE to continue parsing, return FALSE to abort parsing process +}; + +enum SeparatorType +{ + ST_DATA, // is data + ST_HARD, // is a hard separator + ST_SOFT, // is a soft separator + ST_EOS // is a comment symbol, and everything past this character should be ignored +}; + +class InPlaceParser +{ +public: + InPlaceParser(void) + { + Init(); + } + + InPlaceParser(char *data,int len) + { + Init(); + SetSourceData(data,len); + } + + InPlaceParser(const char *fname) + { + Init(); + SetFile(fname); + } + + ~InPlaceParser(void); + + void Init(void) + { + mQuoteChar = 34; + mData = 0; + mLen = 0; + mMyAlloc = false; + for (int i=0; i<256; i++) + { + mHard[i] = ST_DATA; + mHardString[i*2] = i; + mHardString[i*2+1] = 0; + } + mHard[0] = ST_EOS; + mHard[32] = ST_SOFT; + mHard[9] = ST_SOFT; + mHard[13] = ST_SOFT; + mHard[10] = ST_SOFT; + } + + void SetFile(const char *fname); // use this file as source data to parse. + + void SetSourceData(char *data,int len) + { + mData = data; + mLen = len; + mMyAlloc = false; + }; + + int Parse(InPlaceParserInterface *callback); // returns true if entire file was parsed, false if it aborted for some reason + + int ProcessLine(int lineno,char *line,InPlaceParserInterface *callback); + + const char ** GetArglist(char *source,int &count); // convert source string into an arg list, this is a destructive parse. + + void SetHardSeparator(char c) // add a hard separator + { + mHard[(int)c] = ST_HARD; + } + + void SetHard(char c) // add a hard separator + { + mHard[(int)c] = ST_HARD; + } + + + void SetCommentSymbol(char c) // comment character, treated as 'end of string' + { + mHard[(int)c] = ST_EOS; + } + + void ClearHardSeparator(char c) + { + mHard[(int)c] = ST_DATA; + } + + + void DefaultSymbols(void); // set up default symbols for hard seperator and comment symbol of the '#' character. + + bool EOS(char c) + { + if ( mHard[(int)c] == ST_EOS ) + { + return true; + } + return false; + } + + void SetQuoteChar(char c) + { + mQuoteChar = c; + } + +private: + + + inline char * AddHard(int &argc,const char **argv,char *foo); + inline bool IsHard(char c); + inline char * SkipSpaces(char *foo); + inline bool IsWhiteSpace(char c); + inline bool IsNonSeparator(char c); // non seperator,neither hard nor soft + + bool mMyAlloc; // whether or not *I* allocated the buffer and am responsible for deleting it. + char *mData; // ascii data to parse. + int mLen; // length of data + SeparatorType mHard[256]; + char mHardString[256*2]; + char mQuoteChar; +}; + +/*******************************************************************/ +/******************** InParser.cpp ********************************/ +/*******************************************************************/ +void InPlaceParser::SetFile(const char *fname) +{ + if ( mMyAlloc ) + { + free(mData); + } + mData = 0; + mLen = 0; + mMyAlloc = false; + + + FILE *fph = fopen(fname,"rb"); + if ( fph ) + { + fseek(fph,0L,SEEK_END); + mLen = ftell(fph); + fseek(fph,0L,SEEK_SET); + if ( mLen ) + { + mData = (char *) malloc(sizeof(char)*(mLen+1)); + int ok = fread(mData, mLen, 1, fph); + if ( !ok ) + { + free(mData); + mData = 0; + } + else + { + mData[mLen] = 0; // zero byte terminate end of file marker. + mMyAlloc = true; + } + } + fclose(fph); + } +} + +InPlaceParser::~InPlaceParser(void) +{ + if ( mMyAlloc ) + { + free(mData); + } +} + +#define MAXARGS 512 + +bool InPlaceParser::IsHard(char c) +{ + return mHard[(int)c] == ST_HARD; +} + +char * InPlaceParser::AddHard(int &argc,const char **argv,char *foo) +{ + while ( IsHard(*foo) ) + { + const char *hard = &mHardString[*foo*2]; + if ( argc < MAXARGS ) + { + argv[argc++] = hard; + } + foo++; + } + return foo; +} + +bool InPlaceParser::IsWhiteSpace(char c) +{ + return mHard[(int)c] == ST_SOFT; +} + +char * InPlaceParser::SkipSpaces(char *foo) +{ + while ( !EOS(*foo) && IsWhiteSpace(*foo) ) foo++; + return foo; +} + +bool InPlaceParser::IsNonSeparator(char c) +{ + if ( !IsHard(c) && !IsWhiteSpace(c) && c != 0 ) return true; + return false; +} + + +int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *callback) +{ + int ret = 0; + + const char *argv[MAXARGS]; + int argc = 0; + + char *foo = line; + + while ( !EOS(*foo) && argc < MAXARGS ) + { + + foo = SkipSpaces(foo); // skip any leading spaces + + if ( EOS(*foo) ) break; + + if ( *foo == mQuoteChar ) // if it is an open quote + { + foo++; + if ( argc < MAXARGS ) + { + argv[argc++] = foo; + } + while ( !EOS(*foo) && *foo != mQuoteChar ) foo++; + if ( !EOS(*foo) ) + { + *foo = 0; // replace close quote with zero byte EOS + foo++; + } + } + else + { + + foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces + + if ( IsNonSeparator(*foo) ) // add non-hard argument. + { + bool quote = false; + if ( *foo == mQuoteChar ) + { + foo++; + quote = true; + } + + if ( argc < MAXARGS ) + { + argv[argc++] = foo; + } + + if ( quote ) + { + while (*foo && *foo != mQuoteChar ) foo++; + if ( *foo ) *foo = 32; + } + + // continue..until we hit an eos .. + while ( !EOS(*foo) ) // until we hit EOS + { + if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit + { + *foo = 0; + foo++; + break; + } + else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument + { + const char *hard = &mHardString[*foo*2]; + *foo = 0; + if ( argc < MAXARGS ) + { + argv[argc++] = hard; + } + foo++; + break; + } + foo++; + } // end of while loop... + } + } + } + + if ( argc ) + { + ret = callback->ParseLine(lineno, argc, argv ); + } + + return ret; +} + +int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if entire file was parsed, false if it aborted for some reason +{ + assert( callback ); + if ( !mData ) return 0; + + int ret = 0; + + int lineno = 0; + + char *foo = mData; + char *begin = foo; + + + while ( *foo ) + { + if ( *foo == 10 || *foo == 13 ) + { + lineno++; + *foo = 0; + + if ( *begin ) // if there is any data to parse at all... + { + int v = ProcessLine(lineno,begin,callback); + if ( v ) ret = v; + } + + foo++; + if ( *foo == 10 ) foo++; // skip line feed, if it is in the carraige-return line-feed format... + begin = foo; + } + else + { + foo++; + } + } + + lineno++; // lasst line. + + int v = ProcessLine(lineno,begin,callback); + if ( v ) ret = v; + return ret; +} + + +void InPlaceParser::DefaultSymbols(void) +{ + SetHardSeparator(','); + SetHardSeparator('('); + SetHardSeparator(')'); + SetHardSeparator('='); + SetHardSeparator('['); + SetHardSeparator(']'); + SetHardSeparator('{'); + SetHardSeparator('}'); + SetCommentSymbol('#'); +} + + +const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source string into an arg list, this is a destructive parse. +{ + const char **ret = 0; + + const char *argv[MAXARGS]; + int argc = 0; + + char *foo = line; + + while ( !EOS(*foo) && argc < MAXARGS ) + { + + foo = SkipSpaces(foo); // skip any leading spaces + + if ( EOS(*foo) ) break; + + if ( *foo == mQuoteChar ) // if it is an open quote + { + foo++; + if ( argc < MAXARGS ) + { + argv[argc++] = foo; + } + while ( !EOS(*foo) && *foo != mQuoteChar ) foo++; + if ( !EOS(*foo) ) + { + *foo = 0; // replace close quote with zero byte EOS + foo++; + } + } + else + { + + foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces + + if ( IsNonSeparator(*foo) ) // add non-hard argument. + { + bool quote = false; + if ( *foo == mQuoteChar ) + { + foo++; + quote = true; + } + + if ( argc < MAXARGS ) + { + argv[argc++] = foo; + } + + if ( quote ) + { + while (*foo && *foo != mQuoteChar ) foo++; + if ( *foo ) *foo = 32; + } + + // continue..until we hit an eos .. + while ( !EOS(*foo) ) // until we hit EOS + { + if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit + { + *foo = 0; + foo++; + break; + } + else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument + { + const char *hard = &mHardString[*foo*2]; + *foo = 0; + if ( argc < MAXARGS ) + { + argv[argc++] = hard; + } + foo++; + break; + } + foo++; + } // end of while loop... + } + } + } + + count = argc; + if ( argc ) + { + ret = argv; + } + + return ret; +} + +/*******************************************************************/ +/******************** Geometry.h ********************************/ +/*******************************************************************/ + +class GeometryVertex +{ +public: + float mPos[3]; + float mNormal[3]; + float mTexel[2]; +}; + + +class GeometryInterface +{ +public: + + virtual void NodeTriangle(const GeometryVertex *v1,const GeometryVertex *v2,const GeometryVertex *v3) {} + + virtual ~GeometryInterface () {} +}; + + +/*******************************************************************/ +/******************** Obj.h ********************************/ +/*******************************************************************/ + + +class OBJ : public InPlaceParserInterface +{ +public: + int LoadMesh(const char *fname,GeometryInterface *callback); + int ParseLine(int lineno,int argc,const char **argv); // return TRUE to continue parsing, return FALSE to abort parsing process +private: + + void getVertex(GeometryVertex &v,const char *face) const; + + FloatVector mVerts; + FloatVector mTexels; + FloatVector mNormals; + + GeometryInterface *mCallback; +}; + + +/*******************************************************************/ +/******************** Obj.cpp ********************************/ +/*******************************************************************/ + +int OBJ::LoadMesh(const char *fname,GeometryInterface *iface) +{ + int ret = 0; + + mVerts.clear(); + mTexels.clear(); + mNormals.clear(); + + mCallback = iface; + + InPlaceParser ipp(fname); + + ipp.Parse(this); + + + return ret; +} + +//static const char * GetArg(const char **argv,int i,int argc) +//{ + // const char * ret = 0; + // if ( i < argc ) ret = argv[i]; + // return ret; +//} + +void OBJ::getVertex(GeometryVertex &v,const char *face) const +{ + v.mPos[0] = 0; + v.mPos[1] = 0; + v.mPos[2] = 0; + + v.mTexel[0] = 0; + v.mTexel[1] = 0; + + v.mNormal[0] = 0; + v.mNormal[1] = 1; + v.mNormal[2] = 0; + + int index = atoi( face )-1; + + const char *texel = strstr(face,"/"); + + if ( texel ) + { + int tindex = atoi( texel+1) - 1; + + if ( tindex >=0 && tindex < (int)(mTexels.size()/2) ) + { + const float *t = &mTexels[tindex*2]; + + v.mTexel[0] = t[0]; + v.mTexel[1] = t[1]; + + } + + const char *normal = strstr(texel+1,"/"); + if ( normal ) + { + int nindex = atoi( normal+1 ) - 1; + + if (nindex >= 0 && nindex < (int)(mNormals.size()/3) ) + { + const float *n = &mNormals[nindex*3]; + + v.mNormal[0] = n[0]; + v.mNormal[1] = n[1]; + v.mNormal[2] = n[2]; + } + } + } + + if ( index >= 0 && index < (int)(mVerts.size()/3) ) + { + + const float *p = &mVerts[index*3]; + + v.mPos[0] = p[0]; + v.mPos[1] = p[1]; + v.mPos[2] = p[2]; + } + +} + +int OBJ::ParseLine(int lineno,int argc,const char **argv) // return TRUE to continue parsing, return FALSE to abort parsing process +{ + int ret = 0; + + if ( argc >= 1 ) + { + const char *foo = argv[0]; + if ( *foo != '#' ) + { + if ( strcmp(argv[0],"v") == 0 && argc == 4 ) + + //if ( stricmp(argv[0],"v") == 0 && argc == 4 ) + { + float vx = (float) atof( argv[1] ); + float vy = (float) atof( argv[2] ); + float vz = (float) atof( argv[3] ); + mVerts.push_back(vx); + mVerts.push_back(vy); + mVerts.push_back(vz); + } + else if ( strcmp(argv[0],"vt") == 0 && argc == 3 ) + + // else if ( stricmp(argv[0],"vt") == 0 && argc == 3 ) + { + float tx = (float) atof( argv[1] ); + float ty = (float) atof( argv[2] ); + mTexels.push_back(tx); + mTexels.push_back(ty); + } + // else if ( stricmp(argv[0],"vn") == 0 && argc == 4 ) + + else if ( strcmp(argv[0],"vn") == 0 && argc == 4 ) + { + float normalx = (float) atof(argv[1]); + float normaly = (float) atof(argv[2]); + float normalz = (float) atof(argv[3]); + mNormals.push_back(normalx); + mNormals.push_back(normaly); + mNormals.push_back(normalz); + } +// else if ( stricmp(argv[0],"f") == 0 && argc >= 4 ) + + else if ( strcmp(argv[0],"f") == 0 && argc >= 4 ) + { + GeometryVertex v[32]; + + int vcount = argc-1; + + for (int i=1; i p1( v[0].mPos ); + Vector3d p2( v[1].mPos ); + Vector3d p3( v[2].mPos ); + + Vector3d n; + n.ComputeNormal(p3,p2,p1); + + for (int i=0; iNodeTriangle(&v[0],&v[1],&v[2]); + + if ( vcount >=3 ) // do the fan + { + for (int i=2; i<(vcount-1); i++) + { + mCallback->NodeTriangle(&v[0],&v[i],&v[i+1]); + } + } + + } + } + } + + return ret; +} + + + + +class BuildMesh : public GeometryInterface +{ +public: + + int getIndex(const float *p) + { + + int vcount = mVertices.size()/3; + + if(vcount>0) + { + //New MS STL library checks indices in debug build, so zero causes an assert if it is empty. + const float *v = &mVertices[0]; + + for (int i=0; imPos) ); + mIndices.push_back( getIndex(v2->mPos) ); + mIndices.push_back( getIndex(v3->mPos) ); + } + + const FloatVector& GetVertices(void) const { return mVertices; }; + const IntVector& GetIndices(void) const { return mIndices; }; + +private: + FloatVector mVertices; + IntVector mIndices; +}; + + +WavefrontObj::WavefrontObj(void) +{ + mVertexCount = 0; + mTriCount = 0; + mIndices = 0; + mVertices = 0; +} + +WavefrontObj::~WavefrontObj(void) +{ + delete [] mIndices; + delete [] mVertices; +} + +unsigned int WavefrontObj::loadObj(const char *fname) // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. +{ + + unsigned int ret = 0; + + delete [] mVertices; + mVertices = 0; + delete [] mIndices; + mIndices = 0; + mVertexCount = 0; + mTriCount = 0; + + + BuildMesh bm; + + OBJ obj; + + obj.LoadMesh(fname,&bm); + + + const FloatVector &vlist = bm.GetVertices(); + const IntVector &indices = bm.GetIndices(); + if ( vlist.size() ) + { + mVertexCount = vlist.size()/3; + mVertices = new float[mVertexCount*3]; + memcpy( mVertices, &vlist[0], sizeof(float)*mVertexCount*3 ); + mTriCount = indices.size()/3; + mIndices = new int[mTriCount*3*sizeof(int)]; + memcpy(mIndices, &indices[0], sizeof(int)*mTriCount*3); + ret = mTriCount; + } + + + return ret; +} + +} diff --git a/Extras/ConvexDecomposition/cd_wavefront.h b/Extras/ConvexDecomposition/cd_wavefront.h new file mode 100644 index 0000000..ba5f90b --- /dev/null +++ b/Extras/ConvexDecomposition/cd_wavefront.h @@ -0,0 +1,62 @@ +#ifndef CD_WAVEFRONT_OBJ_H + + +#define CD_WAVEFRONT_OBJ_H + + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +namespace ConvexDecomposition +{ + +class WavefrontObj +{ +public: + + WavefrontObj(void); + ~WavefrontObj(void); + + unsigned int loadObj(const char *fname); // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. + + int mVertexCount; + int mTriCount; + int *mIndices; + float *mVertices; +}; + +} + +#endif diff --git a/Extras/ConvexDecomposition/concavity.cpp b/Extras/ConvexDecomposition/concavity.cpp new file mode 100644 index 0000000..f1a4660 --- /dev/null +++ b/Extras/ConvexDecomposition/concavity.cpp @@ -0,0 +1,795 @@ +#include "float_math.h" +#include +#include +#include +#include + +#include + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +#include "concavity.h" +#include "raytri.h" +#include "bestfit.h" +#include "cd_hull.h" +#include "meshvolume.h" +#include "cd_vector.h" +#include "splitplane.h" +#include "ConvexDecomposition.h" + + +#define WSCALE 4 +#define CONCAVE_THRESH 0.05f + +namespace ConvexDecomposition +{ + +unsigned int getDebugColor(void) +{ + static unsigned int colors[8] = + { + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFFFF00, + 0x00FFFF, + 0xFF00FF, + 0xFFFFFF, + 0xFF8040 + }; + + static int count = 0; + + count++; + + if ( count == 8 ) count = 0; + + assert( count >= 0 && count < 8 ); + + unsigned int color = colors[count]; + + return color; + +} + +class Wpoint +{ +public: + Wpoint(const Vector3d &p,float w) + { + mPoint = p; + mWeight = w; + } + + Vector3d mPoint; + float mWeight; +}; + +typedef std::vector< Wpoint > WpointVector; + + +static inline float DistToPt(const float *p,const float *plane) +{ + float x = p[0]; + float y = p[1]; + float z = p[2]; + float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3]; + return d; +} + + +static void intersect(const float *p1,const float *p2,float *split,const float *plane) +{ + + float dp1 = DistToPt(p1,plane); + + float dir[3]; + + dir[0] = p2[0] - p1[0]; + dir[1] = p2[1] - p1[1]; + dir[2] = p2[2] - p1[2]; + + float dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2]; + float dot2 = dp1 - plane[3]; + + float t = -(plane[3] + dot2 ) / dot1; + + split[0] = (dir[0]*t)+p1[0]; + split[1] = (dir[1]*t)+p1[1]; + split[2] = (dir[2]*t)+p1[2]; +} + + +class CTri +{ +public: + CTri(void) { }; + + CTri(const float *p1,const float *p2,const float *p3,unsigned int i1,unsigned int i2,unsigned int i3) + { + mProcessed = 0; + mI1 = i1; + mI2 = i2; + mI3 = i3; + + mP1.Set(p1); + mP2.Set(p2); + mP3.Set(p3); + + mPlaneD = mNormal.ComputePlane(mP1,mP2,mP3); + } + + float Facing(const CTri &t) + { + float d = mNormal.Dot(t.mNormal); + return d; + } + + // clip this line segment against this triangle. + bool clip(const Vector3d &start,Vector3d &end) const + { + Vector3d sect; + + bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr() ); + + if ( hit ) + { + end = sect; + } + return hit; + } + + bool Concave(const Vector3d &p,float &distance,Vector3d &n) const + { + n.NearestPointInTriangle(p,mP1,mP2,mP3); + distance = p.Distance(n); + return true; + } + + void addTri(unsigned int *indices,unsigned int i1,unsigned int i2,unsigned int i3,unsigned int &tcount) const + { + indices[tcount*3+0] = i1; + indices[tcount*3+1] = i2; + indices[tcount*3+2] = i3; + tcount++; + } + + float getVolume(ConvexDecompInterface *callback) const + { + unsigned int indices[8*3]; + + + unsigned int tcount = 0; + + addTri(indices,0,1,2,tcount); + addTri(indices,3,4,5,tcount); + + addTri(indices,0,3,4,tcount); + addTri(indices,0,4,1,tcount); + + addTri(indices,1,4,5,tcount); + addTri(indices,1,5,2,tcount); + + addTri(indices,0,3,5,tcount); + addTri(indices,0,5,2,tcount); + + const float *vertices = mP1.Ptr(); + + if ( callback ) + { + unsigned int color = getDebugColor(); + +#if 0 + Vector3d d1 = mNear1; + Vector3d d2 = mNear2; + Vector3d d3 = mNear3; + + callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00); + callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00); + callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00); + callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000); + callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000); + callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000); + + callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00); + callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00); + callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00); + +#else + for (unsigned int i=0; iConvexDebugTri(p1,p2,p3,color); + + } +#endif + } + + float v = computeMeshVolume(mP1.Ptr(), tcount, indices ); + + return v; + + } + + float raySect(const Vector3d &p,const Vector3d &dir,Vector3d §) const + { + float plane[4]; + + plane[0] = mNormal.x; + plane[1] = mNormal.y; + plane[2] = mNormal.z; + plane[3] = mPlaneD; + + Vector3d dest = p+dir*100000; + + intersect( p.Ptr(), dest.Ptr(), sect.Ptr(), plane ); + + return sect.Distance(p); // return the intersection distance. + + } + + float planeDistance(const Vector3d &p) const + { + float plane[4]; + + plane[0] = mNormal.x; + plane[1] = mNormal.y; + plane[2] = mNormal.z; + plane[3] = mPlaneD; + + return DistToPt( p.Ptr(), plane ); + + } + + bool samePlane(const CTri &t) const + { + const float THRESH = 0.001f; + float dd = fabsf( t.mPlaneD - mPlaneD ); + if ( dd > THRESH ) return false; + dd = fabsf( t.mNormal.x - mNormal.x ); + if ( dd > THRESH ) return false; + dd = fabsf( t.mNormal.y - mNormal.y ); + if ( dd > THRESH ) return false; + dd = fabsf( t.mNormal.z - mNormal.z ); + if ( dd > THRESH ) return false; + return true; + } + + bool hasIndex(unsigned int i) const + { + if ( i == mI1 || i == mI2 || i == mI3 ) return true; + return false; + } + + bool sharesEdge(const CTri &t) const + { + bool ret = false; + unsigned int count = 0; + + if ( t.hasIndex(mI1) ) count++; + if ( t.hasIndex(mI2) ) count++; + if ( t.hasIndex(mI3) ) count++; + + if ( count >= 2 ) ret = true; + + return ret; + } + + void debug(unsigned int color,ConvexDecompInterface *callback) + { + callback->ConvexDebugTri( mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color ); + callback->ConvexDebugTri( mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000 ); + callback->ConvexDebugTri( mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000 ); + callback->ConvexDebugTri( mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000 ); + callback->ConvexDebugPoint( mNear1.Ptr(), 0.01f, 0xFF0000 ); + callback->ConvexDebugPoint( mNear2.Ptr(), 0.01f, 0xFF0000 ); + callback->ConvexDebugPoint( mNear3.Ptr(), 0.01f, 0xFF0000 ); + } + + float area(void) + { + float a = mConcavity*mP1.Area(mP2,mP3); + return a; + } + + void addWeighted(WpointVector &list,ConvexDecompInterface *callback) + { + + Wpoint p1(mP1,mC1); + Wpoint p2(mP2,mC2); + Wpoint p3(mP3,mC3); + + Vector3d d1 = mNear1 - mP1; + Vector3d d2 = mNear2 - mP2; + Vector3d d3 = mNear3 - mP3; + + d1*=WSCALE; + d2*=WSCALE; + d3*=WSCALE; + + d1 = d1 + mP1; + d2 = d2 + mP2; + d3 = d3 + mP3; + + Wpoint p4(d1,mC1); + Wpoint p5(d2,mC2); + Wpoint p6(d3,mC3); + + list.push_back(p1); + list.push_back(p2); + list.push_back(p3); + + list.push_back(p4); + list.push_back(p5); + list.push_back(p6); + +#if 0 + callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00); + callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00); + callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00); + callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000); + callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000); + callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000); + + callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00); + callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00); + callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00); + + Vector3d np1 = mP1 + mNormal*0.05f; + Vector3d np2 = mP2 + mNormal*0.05f; + Vector3d np3 = mP3 + mNormal*0.05f; + + callback->ConvexDebugTri(mP1.Ptr(), np1.Ptr(), np1.Ptr(), 0xFF00FF ); + callback->ConvexDebugTri(mP2.Ptr(), np2.Ptr(), np2.Ptr(), 0xFF00FF ); + callback->ConvexDebugTri(mP3.Ptr(), np3.Ptr(), np3.Ptr(), 0xFF00FF ); + + callback->ConvexDebugPoint( np1.Ptr(), 0.01F, 0XFF00FF ); + callback->ConvexDebugPoint( np2.Ptr(), 0.01F, 0XFF00FF ); + callback->ConvexDebugPoint( np3.Ptr(), 0.01F, 0XFF00FF ); + +#endif + + + + } + + Vector3d mP1; + Vector3d mP2; + Vector3d mP3; + Vector3d mNear1; + Vector3d mNear2; + Vector3d mNear3; + Vector3d mNormal; + float mPlaneD; + float mConcavity; + float mC1; + float mC2; + float mC3; + unsigned int mI1; + unsigned int mI2; + unsigned int mI3; + int mProcessed; // already been added... +}; + +typedef std::vector< CTri > CTriVector; + +bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback,const CTriVector &input_mesh) +{ + + bool ret = false; + + float neardot = 0.707f; + + m.mConcavity = 0; + + //gLog->Display("*********** FEATURE MATCH *************\r\n"); + //gLog->Display("Plane: %0.4f,%0.4f,%0.4f %0.4f\r\n", m.mNormal.x, m.mNormal.y, m.mNormal.z, m.mPlaneD ); + //gLog->Display("*********************************************\r\n"); + + CTriVector::const_iterator i; + + CTri nearest; + + + for (i=tris.begin(); i!=tris.end(); ++i) + { + const CTri &t = (*i); + + + //gLog->Display(" HullPlane: %0.4f,%0.4f,%0.4f %0.4f\r\n", t.mNormal.x, t.mNormal.y, t.mNormal.z, t.mPlaneD ); + + if ( t.samePlane(m) ) + { + //gLog->Display("*** PLANE MATCH!!!\r\n"); + ret = false; + break; + } + + float dot = t.mNormal.Dot(m.mNormal); + + if ( dot > neardot ) + { + + float d1 = t.planeDistance( m.mP1 ); + float d2 = t.planeDistance( m.mP2 ); + float d3 = t.planeDistance( m.mP3 ); + + if ( d1 > 0.001f || d2 > 0.001f || d3 > 0.001f ) // can't be near coplaner! + { + + neardot = dot; + + Vector3d n1,n2,n3; + + t.raySect( m.mP1, m.mNormal, m.mNear1 ); + t.raySect( m.mP2, m.mNormal, m.mNear2 ); + t.raySect( m.mP3, m.mNormal, m.mNear3 ); + + nearest = t; + + ret = true; + } + + } + } + + if ( ret ) + { + if ( 0 ) + { + CTriVector::const_iterator i; + for (i=input_mesh.begin(); i!=input_mesh.end(); ++i) + { + const CTri &c = (*i); + if ( c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3 ) + { + c.clip( m.mP1, m.mNear1 ); + c.clip( m.mP2, m.mNear2 ); + c.clip( m.mP3, m.mNear3 ); + } + } + } + + //gLog->Display("*********************************************\r\n"); + //gLog->Display(" HullPlaneNearest: %0.4f,%0.4f,%0.4f %0.4f\r\n", nearest.mNormal.x, nearest.mNormal.y, nearest.mNormal.z, nearest.mPlaneD ); + + m.mC1 = m.mP1.Distance( m.mNear1 ); + m.mC2 = m.mP2.Distance( m.mNear2 ); + m.mC3 = m.mP3.Distance( m.mNear3 ); + + m.mConcavity = m.mC1; + + if ( m.mC2 > m.mConcavity ) m.mConcavity = m.mC2; + if ( m.mC3 > m.mConcavity ) m.mConcavity = m.mC3; + + #if 0 + callback->ConvexDebugTri( m.mP1.Ptr(), m.mP2.Ptr(), m.mP3.Ptr(), 0x00FF00 ); + callback->ConvexDebugTri( m.mNear1.Ptr(), m.mNear2.Ptr(), m.mNear3.Ptr(), 0xFF0000 ); + + callback->ConvexDebugTri( m.mP1.Ptr(), m.mP1.Ptr(), m.mNear1.Ptr(), 0xFFFF00 ); + callback->ConvexDebugTri( m.mP2.Ptr(), m.mP2.Ptr(), m.mNear2.Ptr(), 0xFFFF00 ); + callback->ConvexDebugTri( m.mP3.Ptr(), m.mP3.Ptr(), m.mNear3.Ptr(), 0xFFFF00 ); + #endif + + } + else + { + //gLog->Display("No match\r\n"); + } + + //gLog->Display("*********************************************\r\n"); + return ret; +} + +bool isFeatureTri(CTri &t,CTriVector &flist,float fc,ConvexDecompInterface *callback,unsigned int color) +{ + bool ret = false; + + if ( t.mProcessed == 0 ) // if not already processed + { + + float c = t.mConcavity / fc; // must be within 80% of the concavity of the parent. + + if ( c > 0.85f ) + { + // see if this triangle is a 'feature' triangle. Meaning it shares an + // edge with any existing feature triangle and is within roughly the same + // concavity of the parent. + if ( flist.size() ) + { + CTriVector::iterator i; + for (i=flist.begin(); i!=flist.end(); ++i) + { + CTri &ftri = (*i); + if ( ftri.sharesEdge(t) ) + { + t.mProcessed = 2; // it is now part of a feature. + flist.push_back(t); // add it to the feature list. +// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); + ret = true; + break; + } + } + } + else + { + t.mProcessed = 2; + flist.push_back(t); // add it to the feature list. +// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); + ret = true; + } + } + else + { + t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one.. + } + + } + return ret; +} + +float computeConcavity(unsigned int vcount, + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float *plane, // plane equation to split on + float &volume) +{ + + + float cret = 0; + volume = 1; + + HullResult result; + HullLibrary hl; + HullDesc desc; + + desc.mMaxFaces = 256; + desc.mMaxVertices = 256; + desc.SetHullFlag(QF_TRIANGLES); + + + desc.mVcount = vcount; + desc.mVertices = vertices; + desc.mVertexStride = sizeof(float)*3; + + HullError ret = hl.CreateConvexHull(desc,result); + + if ( ret == QE_OK ) + { +#if 0 + float bmin[3]; + float bmax[3]; + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + Vector3d center; + + center.x = bmin[0] + dx*0.5f; + center.y = bmin[1] + dy*0.5f; + center.z = bmin[2] + dz*0.5f; +#endif + + volume = computeMeshVolume2( result.mOutputVertices, result.mNumFaces, result.mIndices ); + +#if 1 + // ok..now..for each triangle on the original mesh.. + // we extrude the points to the nearest point on the hull. + const unsigned int *source = result.mIndices; + + CTriVector tris; + + for (unsigned int i=0; iConvexDebugTri(p1,p2,p3,0xFFFFFF); + + CTri t(p1,p2,p3,i1,i2,i3); // + tris.push_back(t); + } + + // we have not pre-computed the plane equation for each triangle in the convex hull.. + + float totalVolume = 0; + + CTriVector ftris; // 'feature' triangles. + + const unsigned int *src = indices; + + + float maxc=0; + + + if ( 1 ) + { + CTriVector input_mesh; + if ( 1 ) + { + const unsigned int *src = indices; + for (unsigned int i=0; i CONCAVE_THRESH ) + { + + if ( t.mConcavity > maxc ) + { + maxc = t.mConcavity; + maxctri = t; + } + + float v = t.getVolume(0); + totalVolume+=v; + ftris.push_back(t); + } + + } + } + + if ( ftris.size() && 0 ) + { + + // ok..now we extract the triangles which form the maximum concavity. + CTriVector major_feature; + float maxarea = 0; + + while ( maxc > CONCAVE_THRESH ) + { + + unsigned int color = getDebugColor(); // + + CTriVector flist; + + bool found; + + float totalarea = 0; + + do + { + found = false; + CTriVector::iterator i; + for (i=ftris.begin(); i!=ftris.end(); ++i) + { + CTri &t = (*i); + if ( isFeatureTri(t,flist,maxc,callback,color) ) + { + found = true; + totalarea+=t.area(); + } + } + } while ( found ); + + + if ( totalarea > maxarea ) + { + major_feature = flist; + maxarea = totalarea; + } + + maxc = 0; + + for (unsigned int i=0; i maxc ) + { + maxc = t.mConcavity; + } + } + } + } + + unsigned int color = getDebugColor(); + + WpointVector list; + for (unsigned int i=0; i +#include +#include +#include +#include + +#include "fitsphere.h" + + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// +/* +An Efficient Bounding Sphere +by Jack Ritter +from "Graphics Gems", Academic Press, 1990 +*/ + +/* Routine to calculate tight bounding sphere over */ +/* a set of points in 3D */ +/* This contains the routine find_bounding_sphere(), */ +/* the struct definition, and the globals used for parameters. */ +/* The abs() of all coordinates must be < BIGNUMBER */ +/* Code written by Jack Ritter and Lyle Rains. */ + +#define BIGNUMBER 100000000.0 /* hundred million */ + +static inline void Set(float *n,float x,float y,float z) +{ + n[0] = x; + n[1] = y; + n[2] = z; +} + +static inline void Copy(float *dest,const float *source) +{ + dest[0] = source[0]; + dest[1] = source[1]; + dest[2] = source[2]; +} + +float computeBoundingSphere(unsigned int vcount,const float *points,float *center) +{ + + float mRadius; + float mRadius2; + + float xmin[3]; + float xmax[3]; + float ymin[3]; + float ymax[3]; + float zmin[3]; + float zmax[3]; + float dia1[3]; + float dia2[3]; + + /* FIRST PASS: find 6 minima/maxima points */ + Set(xmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); + Set(xmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); + Set(ymin,BIGNUMBER,BIGNUMBER,BIGNUMBER); + Set(ymax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); + Set(zmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); + Set(zmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); + + for (unsigned i=0; ixmax[0]) + Copy(xmax,caller_p); + if (caller_p[1]ymax[1]) + Copy(ymax,caller_p); + if (caller_p[2]zmax[2]) + Copy(zmax,caller_p); + } + + /* Set xspan = distance between the 2 points xmin & xmax (squared) */ + float dx = xmax[0] - xmin[0]; + float dy = xmax[1] - xmin[1]; + float dz = xmax[2] - xmin[2]; + float xspan = dx*dx + dy*dy + dz*dz; + + /* Same for y & z spans */ + dx = ymax[0] - ymin[0]; + dy = ymax[1] - ymin[1]; + dz = ymax[2] - ymin[2]; + float yspan = dx*dx + dy*dy + dz*dz; + + dx = zmax[0] - zmin[0]; + dy = zmax[1] - zmin[1]; + dz = zmax[2] - zmin[2]; + float zspan = dx*dx + dy*dy + dz*dz; + + /* Set points dia1 & dia2 to the maximally separated pair */ + Copy(dia1,xmin); + Copy(dia2,xmax); /* assume xspan biggest */ + float maxspan = xspan; + + if (yspan>maxspan) + { + maxspan = yspan; + Copy(dia1,ymin); + Copy(dia2,ymax); + } + + if (zspan>maxspan) + { + Copy(dia1,zmin); + Copy(dia2,zmax); + } + + + /* dia1,dia2 is a diameter of initial sphere */ + /* calc initial center */ + center[0] = (dia1[0]+dia2[0])*0.5f; + center[1] = (dia1[1]+dia2[1])*0.5f; + center[2] = (dia1[2]+dia2[2])*0.5f; + + /* calculate initial radius**2 and radius */ + + dx = dia2[0]-center[0]; /* x component of radius vector */ + dy = dia2[1]-center[1]; /* y component of radius vector */ + dz = dia2[2]-center[2]; /* z component of radius vector */ + + mRadius2 = dx*dx + dy*dy + dz*dz; + mRadius = float(sqrt(mRadius2)); + + /* SECOND PASS: increment current sphere */ + + if ( 1 ) + { + for (unsigned i=0; i mRadius2) /* do r**2 test first */ + { /* this point is outside of current sphere */ + float old_to_p = float(sqrt(old_to_p_sq)); + /* calc radius of new sphere */ + mRadius = (mRadius + old_to_p) * 0.5f; + mRadius2 = mRadius*mRadius; /* for next r**2 compare */ + float old_to_new = old_to_p - mRadius; + + /* calc center of new sphere */ + + float recip = 1.0f /old_to_p; + + float cx = (mRadius*center[0] + old_to_new*caller_p[0]) * recip; + float cy = (mRadius*center[1] + old_to_new*caller_p[1]) * recip; + float cz = (mRadius*center[2] + old_to_new*caller_p[2]) * recip; + + Set(center,cx,cy,cz); + } + } + } + + return mRadius; +} + + diff --git a/Extras/ConvexDecomposition/fitsphere.h b/Extras/ConvexDecomposition/fitsphere.h new file mode 100644 index 0000000..cd4a565 --- /dev/null +++ b/Extras/ConvexDecomposition/fitsphere.h @@ -0,0 +1,43 @@ +#ifndef FIT_SPHERE_H + +#define FIT_SPHERE_H + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + + +float computeBoundingSphere(unsigned int vcount,const float *points,float *center); + +#endif diff --git a/Extras/ConvexDecomposition/float_math.cpp b/Extras/ConvexDecomposition/float_math.cpp new file mode 100644 index 0000000..38c699b --- /dev/null +++ b/Extras/ConvexDecomposition/float_math.cpp @@ -0,0 +1,257 @@ +#include "float_math.h" + +#include +#include +#include +#include +#include + + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +void fm_inverseRT(const float *matrix,const float *pos,float *t) // inverse rotate translate the point. +{ + + float _x = pos[0] - matrix[3*4+0]; + float _y = pos[1] - matrix[3*4+1]; + float _z = pos[2] - matrix[3*4+2]; + + // Multiply inverse-translated source vector by inverted rotation transform + + t[0] = (matrix[0*4+0] * _x) + (matrix[0*4+1] * _y) + (matrix[0*4+2] * _z); + t[1] = (matrix[1*4+0] * _x) + (matrix[1*4+1] * _y) + (matrix[1*4+2] * _z); + t[2] = (matrix[2*4+0] * _x) + (matrix[2*4+1] * _y) + (matrix[2*4+2] * _z); + +} + + +void fm_identity(float *matrix) // set 4x4 matrix to identity. +{ + matrix[0*4+0] = 1; + matrix[1*4+1] = 1; + matrix[2*4+2] = 1; + matrix[3*4+3] = 1; + + matrix[1*4+0] = 0; + matrix[2*4+0] = 0; + matrix[3*4+0] = 0; + + matrix[0*4+1] = 0; + matrix[2*4+1] = 0; + matrix[3*4+1] = 0; + + matrix[0*4+2] = 0; + matrix[1*4+2] = 0; + matrix[3*4+2] = 0; + + matrix[0*4+3] = 0; + matrix[1*4+3] = 0; + matrix[2*4+3] = 0; + +} + +void fm_eulerMatrix(float ax,float ay,float az,float *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) +{ + float quat[4]; + fm_eulerToQuat(ax,ay,az,quat); + fm_quatToMatrix(quat,matrix); +} + +void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax) +{ + + const unsigned char *source = (const unsigned char *) points; + + bmin[0] = points[0]; + bmin[1] = points[1]; + bmin[2] = points[2]; + + bmax[0] = points[0]; + bmax[1] = points[1]; + bmax[2] = points[2]; + + + for (unsigned int i=1; i bmax[0] ) bmax[0] = p[0]; + if ( p[1] > bmax[1] ) bmax[1] = p[1]; + if ( p[2] > bmax[2] ) bmax[2] = p[2]; + + } +} + + +void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat) // convert euler angles to quaternion. +{ + roll *= 0.5f; + pitch *= 0.5f; + yaw *= 0.5f; + + float cr = cosf(roll); + float cp = cosf(pitch); + float cy = cosf(yaw); + + float sr = sinf(roll); + float sp = sinf(pitch); + float sy = sinf(yaw); + + float cpcy = cp * cy; + float spsy = sp * sy; + float spcy = sp * cy; + float cpsy = cp * sy; + + quat[0] = ( sr * cpcy - cr * spsy); + quat[1] = ( cr * spcy + sr * cpsy); + quat[2] = ( cr * cpsy - sr * spcy); + quat[3] = cr * cpcy + sr * spsy; +} + +void fm_quatToMatrix(const float *quat,float *matrix) // convert quaterinion rotation to matrix, zeros out the translation component. +{ + + float xx = quat[0]*quat[0]; + float yy = quat[1]*quat[1]; + float zz = quat[2]*quat[2]; + float xy = quat[0]*quat[1]; + float xz = quat[0]*quat[2]; + float yz = quat[1]*quat[2]; + float wx = quat[3]*quat[0]; + float wy = quat[3]*quat[1]; + float wz = quat[3]*quat[2]; + + matrix[0*4+0] = 1 - 2 * ( yy + zz ); + matrix[1*4+0] = 2 * ( xy - wz ); + matrix[2*4+0] = 2 * ( xz + wy ); + + matrix[0*4+1] = 2 * ( xy + wz ); + matrix[1*4+1] = 1 - 2 * ( xx + zz ); + matrix[2*4+1] = 2 * ( yz - wx ); + + matrix[0*4+2] = 2 * ( xz - wy ); + matrix[1*4+2] = 2 * ( yz + wx ); + matrix[2*4+2] = 1 - 2 * ( xx + yy ); + + matrix[3*4+0] = matrix[3*4+1] = matrix[3*4+2] = 0.0f; + matrix[0*4+3] = matrix[1*4+3] = matrix[2*4+3] = 0.0f; + matrix[3*4+3] = 1.0f; + +} + + +void fm_quatRotate(const float *quat,const float *v,float *r) // rotate a vector directly by a quaternion. +{ + float left[4]; + + left[0] = quat[3]*v[0] + quat[1]*v[2] - v[1]*quat[2]; + left[1] = quat[3]*v[1] + quat[2]*v[0] - v[2]*quat[0]; + left[2] = quat[3]*v[2] + quat[0]*v[1] - v[0]*quat[1]; + left[3] = - quat[0]*v[0] - quat[1]*v[1] - quat[2]*v[2]; + + r[0] = (left[3]*-quat[0]) + (quat[3]*left[0]) + (left[1]*-quat[2]) - (-quat[1]*left[2]); + r[1] = (left[3]*-quat[1]) + (quat[3]*left[1]) + (left[2]*-quat[0]) - (-quat[2]*left[0]); + r[2] = (left[3]*-quat[2]) + (quat[3]*left[2]) + (left[0]*-quat[1]) - (-quat[0]*left[1]); + +} + + +void fm_getTranslation(const float *matrix,float *t) +{ + t[0] = matrix[3*4+0]; + t[1] = matrix[3*4+1]; + t[2] = matrix[3*4+2]; +} + +void fm_matrixToQuat(const float *matrix,float *quat) // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w +{ + + float tr = matrix[0*4+0] + matrix[1*4+1] + matrix[2*4+2]; + + // check the diagonal + + if (tr > 0.0f ) + { + float s = (float) sqrt ( (double) (tr + 1.0f) ); + quat[3] = s * 0.5f; + s = 0.5f / s; + quat[0] = (matrix[1*4+2] - matrix[2*4+1]) * s; + quat[1] = (matrix[2*4+0] - matrix[0*4+2]) * s; + quat[2] = (matrix[0*4+1] - matrix[1*4+0]) * s; + + } + else + { + // diagonal is negative + int nxt[3] = {1, 2, 0}; + float qa[4]; + + int i = 0; + + if (matrix[1*4+1] > matrix[0*4+0]) i = 1; + if (matrix[2*4+2] > matrix[i*4+i]) i = 2; + + int j = nxt[i]; + int k = nxt[j]; + + float s = sqrtf ( ((matrix[i*4+i] - (matrix[j*4+j] + matrix[k*4+k])) + 1.0f) ); + + qa[i] = s * 0.5f; + + if (s != 0.0f ) s = 0.5f / s; + + qa[3] = (matrix[j*4+k] - matrix[k*4+j]) * s; + qa[j] = (matrix[i*4+j] + matrix[j*4+i]) * s; + qa[k] = (matrix[i*4+k] + matrix[k*4+i]) * s; + + quat[0] = qa[0]; + quat[1] = qa[1]; + quat[2] = qa[2]; + quat[3] = qa[3]; + } + + +} + + +float fm_sphereVolume(float radius) // return's the volume of a sphere of this radius (4/3 PI * R cubed ) +{ + return (4.0f / 3.0f ) * FM_PI * radius * radius * radius; +} diff --git a/Extras/ConvexDecomposition/float_math.h b/Extras/ConvexDecomposition/float_math.h new file mode 100644 index 0000000..d6046d3 --- /dev/null +++ b/Extras/ConvexDecomposition/float_math.h @@ -0,0 +1,72 @@ +#ifndef FLOAT_MATH_H + +#define FLOAT_MATH_H + +#ifdef _WIN32 + #pragma warning(disable : 4324) // disable padding warning + #pragma warning(disable : 4244) // disable padding warning + #pragma warning(disable : 4267) // possible loss of data + #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. + #pragma warning(disable:4996) //Turn off warnings about deprecated C routines + #pragma warning(disable:4786) // Disable the "debug name too long" warning +#endif + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +// a set of routines that last you do common 3d math +// operations without any vector, matrix, or quaternion +// classes or templates. +// +// a vector (or point) is a 'float *' to 3 floating point numbers. +// a matrix is a 'float *' to an array of 16 floating point numbers representing a 4x4 transformation matrix compatible with D3D or OGL +// a quaternion is a 'float *' to 4 floats representing a quaternion x,y,z,w + +const float FM_PI = 3.141592654f; +const float FM_DEG_TO_RAD = ((2.0f * FM_PI) / 360.0f); +const float FM_RAD_TO_DEG = (360.0f / (2.0f * FM_PI)); + +void fm_identity(float *matrix); // set 4x4 matrix to identity. +void fm_inverseRT(const float *matrix,const float *pos,float *t); // inverse rotate translate the point. +void fm_eulerMatrix(float ax,float ay,float az,float *matrix); // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) +void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax); +void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat); // convert euler angles to quaternion. +void fm_quatToMatrix(const float *quat,float *matrix); // convert quaterinion rotation to matrix, translation set to zero. +void fm_quatRotate(const float *quat,const float *v,float *r); // rotate a vector directly by a quaternion. +void fm_getTranslation(const float *matrix,float *t); +void fm_matrixToQuat(const float *matrix,float *quat); // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w +float fm_sphereVolume(float radius); // return's the volume of a sphere of this radius (4/3 PI * R cubed ) + +#endif diff --git a/Extras/ConvexDecomposition/meshvolume.cpp b/Extras/ConvexDecomposition/meshvolume.cpp new file mode 100644 index 0000000..b9dfa17 --- /dev/null +++ b/Extras/ConvexDecomposition/meshvolume.cpp @@ -0,0 +1,128 @@ +#include "float_math.h" +#include "meshvolume.h" + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +inline float det(const float *p1,const float *p2,const float *p3) +{ + return p1[0]*p2[1]*p3[2] + p2[0]*p3[1]*p1[2] + p3[0]*p1[1]*p2[2] -p1[0]*p3[1]*p2[2] - p2[0]*p1[1]*p3[2] - p3[0]*p2[1]*p1[2]; +} + +float computeMeshVolume(const float *vertices,unsigned int tcount,const unsigned int *indices) +{ + float volume = 0; + + for (unsigned int i=0; i +#include +#include +#include + +#include "planetri.h" + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +static inline float DistToPt(const float *p,const float *plane) +{ + float x = p[0]; + float y = p[1]; + float z = p[2]; + float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3]; + return d; +} + + +static PlaneTriResult getSidePlane(const float *p,const float *plane,float epsilon) +{ + + float d = DistToPt(p,plane); + + if ( (d+epsilon) > 0 ) + return PTR_FRONT; // it is 'in front' within the provided epsilon value. + + return PTR_BACK; +} + +static void add(const float *p,float *dest,unsigned int tstride,unsigned int &pcount) +{ + char *d = (char *) dest; + d = d + pcount*tstride; + dest = (float *) d; + dest[0] = p[0]; + dest[1] = p[1]; + dest[2] = p[2]; + pcount++; + assert( pcount <= 4 ); +} + + +// assumes that the points are on opposite sides of the plane! +static void intersect(const float *p1,const float *p2,float *split,const float *plane) +{ + + float dp1 = DistToPt(p1,plane); + + float dir[3]; + + dir[0] = p2[0] - p1[0]; + dir[1] = p2[1] - p1[1]; + dir[2] = p2[2] - p1[2]; + + float dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2]; + float dot2 = dp1 - plane[3]; + + float t = -(plane[3] + dot2 ) / dot1; + + split[0] = (dir[0]*t)+p1[0]; + split[1] = (dir[1]*t)+p1[1]; + split[2] = (dir[2]*t)+p1[2]; + +} + +PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format + const float *triangle, // the source triangle. + unsigned int tstride, // stride in bytes of the input and output triangles + float epsilon, // the co-planer epsilon value. + float *front, // the triangle in front of the + unsigned int &fcount, // number of vertices in the 'front' triangle + float *back, // the triangle in back of the plane + unsigned int &bcount) // the number of vertices in the 'back' triangle. +{ + fcount = 0; + bcount = 0; + + const char *tsource = (const char *) triangle; + + // get the three vertices of the triangle. + const float *p1 = (const float *) (tsource); + const float *p2 = (const float *) (tsource+tstride); + const float *p3 = (const float *) (tsource+tstride*2); + + + PlaneTriResult r1 = getSidePlane(p1,plane,epsilon); // compute the side of the plane each vertex is on + PlaneTriResult r2 = getSidePlane(p2,plane,epsilon); + PlaneTriResult r3 = getSidePlane(p3,plane,epsilon); + + if ( r1 == r2 && r1 == r3 ) // if all three vertices are on the same side of the plane. + { + if ( r1 == PTR_FRONT ) // if all three are in front of the plane, then copy to the 'front' output triangle. + { + add(p1,front,tstride,fcount); + add(p2,front,tstride,fcount); + add(p3,front,tstride,fcount); + } + else + { + add(p1,back,tstride,bcount); // if all three are in 'abck' then copy to the 'back' output triangle. + add(p2,back,tstride,bcount); + add(p3,back,tstride,bcount); + } + return r1; // if all three points are on the same side of the plane return result + } + + // ok.. we need to split the triangle at the plane. + + // First test ray segment P1 to P2 + if ( r1 == r2 ) // if these are both on the same side... + { + if ( r1 == PTR_FRONT ) + { + add( p1, front, tstride, fcount ); + add( p2, front, tstride, fcount ); + } + else + { + add( p1, back, tstride, bcount ); + add( p2, back, tstride, bcount ); + } + } + else + { + float split[3]; // split the point + intersect(p1,p2,split,plane); + + if ( r1 == PTR_FRONT ) + { + + add(p1, front, tstride, fcount ); + add(split, front, tstride, fcount ); + + add(split, back, tstride, bcount ); + add(p2, back, tstride, bcount ); + + } + else + { + add(p1, back, tstride, bcount ); + add(split, back, tstride, bcount ); + + add(split, front, tstride, fcount ); + add(p2, front, tstride, fcount ); + } + + } + + // Next test ray segment P2 to P3 + if ( r2 == r3 ) // if these are both on the same side... + { + if ( r3 == PTR_FRONT ) + { + add( p3, front, tstride, fcount ); + } + else + { + add( p3, back, tstride, bcount ); + } + } + else + { + float split[3]; // split the point + intersect(p2,p3,split,plane); + + if ( r3 == PTR_FRONT ) + { + add(split, front, tstride, fcount ); + add(split, back, tstride, bcount ); + + add(p3, front, tstride, fcount ); + } + else + { + add(split, front, tstride, fcount ); + add(split, back, tstride, bcount ); + + add(p3, back, tstride, bcount ); + } + } + + // Next test ray segment P3 to P1 + if ( r3 != r1 ) // if these are both on the same side... + { + float split[3]; // split the point + + intersect(p3,p1,split,plane); + + if ( r1 == PTR_FRONT ) + { + add(split, front, tstride, fcount ); + add(split, back, tstride, bcount ); + } + else + { + add(split, front, tstride, fcount ); + add(split, back, tstride, bcount ); + } + } + + + + return PTR_SPLIT; +} diff --git a/Extras/ConvexDecomposition/planetri.h b/Extras/ConvexDecomposition/planetri.h new file mode 100644 index 0000000..780ac85 --- /dev/null +++ b/Extras/ConvexDecomposition/planetri.h @@ -0,0 +1,58 @@ +#ifndef PLANE_TRI_H + +#define PLANE_TRI_H + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + + +enum PlaneTriResult +{ + PTR_FRONT, + PTR_BACK, + PTR_SPLIT +}; + +PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format + const float *triangle, // the source position triangle. + unsigned int tstride, // stride in bytes between vertices of the triangle. + float epsilon, // the co-planer epsilon value. + float *front, // the triangle in front of the + unsigned int &fcount, // number of vertices in the 'front' triangle. + float *back, // the triangle in back of the plane + unsigned int &bcount); // the number of vertices in the 'back' triangle. + + +#endif diff --git a/Extras/ConvexDecomposition/premake4.lua b/Extras/ConvexDecomposition/premake4.lua new file mode 100644 index 0000000..8a91bea --- /dev/null +++ b/Extras/ConvexDecomposition/premake4.lua @@ -0,0 +1,9 @@ + project "ConvexDecomposition" + + kind "StaticLib" + targetdir "../../lib" + includedirs {".","../../src"} + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/Extras/ConvexDecomposition/raytri.cpp b/Extras/ConvexDecomposition/raytri.cpp new file mode 100644 index 0000000..83b076a --- /dev/null +++ b/Extras/ConvexDecomposition/raytri.cpp @@ -0,0 +1,134 @@ +#include "float_math.h" +#include +#include +#include +#include +#include + +#include "raytri.h" + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +/* a = b - c */ +#define vector(a,b,c) \ + (a)[0] = (b)[0] - (c)[0]; \ + (a)[1] = (b)[1] - (c)[1]; \ + (a)[2] = (b)[2] - (c)[2]; + + + +#define innerProduct(v,q) \ + ((v)[0] * (q)[0] + \ + (v)[1] * (q)[1] + \ + (v)[2] * (q)[2]) + +#define crossProduct(a,b,c) \ + (a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \ + (a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \ + (a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1]; + +bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t) +{ + + float e1[3],e2[3],h[3],s[3],q[3]; + float a,f,u,v; + + vector(e1,v1,v0); + vector(e2,v2,v0); + crossProduct(h,d,e2); + a = innerProduct(e1,h); + + if (a > -0.00001 && a < 0.00001) + return(false); + + f = 1/a; + vector(s,p,v0); + u = f * (innerProduct(s,h)); + + if (u < 0.0 || u > 1.0) + return(false); + + crossProduct(q,s,e1); + v = f * innerProduct(d,q); + if (v < 0.0 || u + v > 1.0) + return(false); + // at this stage we can compute t to find out where + // the intersection point is on the line + t = f * innerProduct(e2,q); + if (t > 0) // ray intersection + return(true); + else // this means that there is a line intersection + // but not a ray intersection + return (false); +} + + +bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect) +{ + float dir[3]; + + dir[0] = rayEnd[0] - rayStart[0]; + dir[1] = rayEnd[1] - rayStart[1]; + dir[2] = rayEnd[2] - rayStart[2]; + + float d = sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]); + float r = 1.0f / d; + + dir[0]*=r; + dir[1]*=r; + dir[2]*=r; + + + float t; + + bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t ); + + if ( ret ) + { + if ( t > d ) + { + sect[0] = rayStart[0] + dir[0]*t; + sect[1] = rayStart[1] + dir[1]*t; + sect[2] = rayStart[2] + dir[2]*t; + } + else + { + ret = false; + } + } + + return ret; +} diff --git a/Extras/ConvexDecomposition/raytri.h b/Extras/ConvexDecomposition/raytri.h new file mode 100644 index 0000000..76370c6 --- /dev/null +++ b/Extras/ConvexDecomposition/raytri.h @@ -0,0 +1,45 @@ +#ifndef RAY_TRI_H + +#define RAY_TRI_H + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + + +// returns true if the ray intersects the triangle. +bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect); +bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t); + +#endif diff --git a/Extras/ConvexDecomposition/splitplane.cpp b/Extras/ConvexDecomposition/splitplane.cpp new file mode 100644 index 0000000..2ae408e --- /dev/null +++ b/Extras/ConvexDecomposition/splitplane.cpp @@ -0,0 +1,306 @@ +#include "float_math.h" +#include +#include +#include +#include +#include +#include + + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +#include "splitplane.h" +#include "ConvexDecomposition.h" +#include "cd_vector.h" +#include "cd_hull.h" +#include "cd_wavefront.h" +#include "bestfit.h" +#include "planetri.h" +#include "vlookup.h" +#include "meshvolume.h" + +namespace ConvexDecomposition +{ + +static void computePlane(const float *A,const float *B,const float *C,float *plane) +{ + + float vx = (B[0] - C[0]); + float vy = (B[1] - C[1]); + float vz = (B[2] - C[2]); + + float wx = (A[0] - B[0]); + float wy = (A[1] - B[1]); + float wz = (A[2] - B[2]); + + float vw_x = vy * wz - vz * wy; + float vw_y = vz * wx - vx * wz; + float vw_z = vx * wy - vy * wx; + + float mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + + if ( mag < 0.000001f ) + { + mag = 0; + } + else + { + mag = 1.0f/mag; + } + + float x = vw_x * mag; + float y = vw_y * mag; + float z = vw_z * mag; + + + float D = 0.0f - ((x*A[0])+(y*A[1])+(z*A[2])); + + plane[0] = x; + plane[1] = y; + plane[2] = z; + plane[3] = D; + +} + +class Rect3d +{ +public: + Rect3d(void) { }; + + Rect3d(const float *bmin,const float *bmax) + { + + mMin[0] = bmin[0]; + mMin[1] = bmin[1]; + mMin[2] = bmin[2]; + + mMax[0] = bmax[0]; + mMax[1] = bmax[1]; + mMax[2] = bmax[2]; + + } + + void SetMin(const float *bmin) + { + mMin[0] = bmin[0]; + mMin[1] = bmin[1]; + mMin[2] = bmin[2]; + } + + void SetMax(const float *bmax) + { + mMax[0] = bmax[0]; + mMax[1] = bmax[1]; + mMax[2] = bmax[2]; + } + + void SetMin(float x,float y,float z) + { + mMin[0] = x; + mMin[1] = y; + mMin[2] = z; + } + + void SetMax(float x,float y,float z) + { + mMax[0] = x; + mMax[1] = y; + mMax[2] = z; + } + + float mMin[3]; + float mMax[3]; +}; + +void splitRect(unsigned int axis, + const Rect3d &source, + Rect3d &b1, + Rect3d &b2, + const float *midpoint) +{ + switch ( axis ) + { + case 0: + b1.SetMin(source.mMin); + b1.SetMax( midpoint[0], source.mMax[1], source.mMax[2] ); + + b2.SetMin( midpoint[0], source.mMin[1], source.mMin[2] ); + b2.SetMax(source.mMax); + + break; + case 1: + b1.SetMin(source.mMin); + b1.SetMax( source.mMax[0], midpoint[1], source.mMax[2] ); + + b2.SetMin( source.mMin[0], midpoint[1], source.mMin[2] ); + b2.SetMax(source.mMax); + + break; + case 2: + b1.SetMin(source.mMin); + b1.SetMax( source.mMax[0], source.mMax[1], midpoint[2] ); + + b2.SetMin( source.mMin[0], source.mMin[1], midpoint[2] ); + b2.SetMax(source.mMax); + + break; + } +} + +bool computeSplitPlane(unsigned int vcount, + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float *plane) +{ + float bmin[3] = { 1e9, 1e9, 1e9 }; + float bmax[3] = { -1e9, -1e9, -1e9 }; + + for (unsigned int i=0; i bmax[0] ) bmax[0] = p[0]; + if ( p[1] > bmax[1] ) bmax[1] = p[1]; + if ( p[2] > bmax[2] ) bmax[2] = p[2]; + + } + + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + + + float laxis = dx; + + unsigned int axis = 0; + + if ( dy > dx ) + { + axis = 1; + laxis = dy; + } + + if ( dz > dx && dz > dy ) + { + axis = 2; + laxis = dz; + } + + float p1[3]; + float p2[3]; + float p3[3]; + + p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f; + p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f; + p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f; + + Rect3d b(bmin,bmax); + + Rect3d b1,b2; + + splitRect(axis,b,b1,b2,p1); + + +// callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00); +// callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00); + + switch ( axis ) + { + case 0: + p2[1] = bmin[1]; + p2[2] = bmin[2]; + + if ( dz > dy ) + { + p3[1] = bmax[1]; + p3[2] = bmin[2]; + } + else + { + p3[1] = bmin[1]; + p3[2] = bmax[2]; + } + + break; + case 1: + p2[0] = bmin[0]; + p2[2] = bmin[2]; + + if ( dx > dz ) + { + p3[0] = bmax[0]; + p3[2] = bmin[2]; + } + else + { + p3[0] = bmin[0]; + p3[2] = bmax[2]; + } + + break; + case 2: + p2[0] = bmin[0]; + p2[1] = bmin[1]; + + if ( dx > dy ) + { + p3[0] = bmax[0]; + p3[1] = bmin[1]; + } + else + { + p3[0] = bmin[0]; + p3[1] = bmax[1]; + } + + break; + } + +// callback->ConvexDebugTri(p1,p2,p3,0xFF0000); + + computePlane(p1,p2,p3,plane); + + return true; + +} + + +} diff --git a/Extras/ConvexDecomposition/splitplane.h b/Extras/ConvexDecomposition/splitplane.h new file mode 100644 index 0000000..26fe2e3 --- /dev/null +++ b/Extras/ConvexDecomposition/splitplane.h @@ -0,0 +1,59 @@ +#ifndef SPLIT_PLANE_H + +#define SPLIT_PLANE_H + +//** Computes an 'optimal' split plane for the supplied mesh. +//** needs much improvement since it currently just splits along +//** the longest side of the AABB. +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + + +namespace ConvexDecomposition +{ + +class ConvexDecompInterface; + +bool computeSplitPlane(unsigned int vcount, + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float *plane); + + +} + +#endif diff --git a/Extras/ConvexDecomposition/vlookup.cpp b/Extras/ConvexDecomposition/vlookup.cpp new file mode 100644 index 0000000..3b9e928 --- /dev/null +++ b/Extras/ConvexDecomposition/vlookup.cpp @@ -0,0 +1,326 @@ +#include "float_math.h" +#include +#include +#include +#include + +#pragma warning(disable:4786) + +#include +#include +#include + + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + +// CodeSnippet provided by John W. Ratcliff +// on March 23, 2006. +// +// mailto: jratcliff@infiniplex.net +// +// Personal website: http://jratcliffscarab.blogspot.com +// Coding Website: http://codesuppository.blogspot.com +// FundRaising Blog: http://amillionpixels.blogspot.com +// Fundraising site: http://www.amillionpixels.us +// New Temple Site: http://newtemple.blogspot.com +// +// This snippet shows how to 'hide' the complexity of +// the STL by wrapping some useful piece of functionality +// around a handful of discrete API calls. +// +// This API allows you to create an indexed triangle list +// from a collection of raw input triangles. Internally +// it uses an STL set to build the lookup table very rapidly. +// +// Here is how you would use it to build an indexed triangle +// list from a raw list of triangles. +// +// (1) create a 'VertexLookup' interface by calling +// +// VertexLook vl = Vl_createVertexLookup(); +// +// (2) For each vertice in each triangle call: +// +// unsigned int i1 = Vl_getIndex(vl,p1); +// unsigned int i2 = Vl_getIndex(vl,p2); +// unsigned int i3 = Vl_getIndex(vl,p3); +// +// save the 3 indices into your triangle list array. +// +// (3) Get the vertex array by calling: +// +// const float *vertices = Vl_getVertices(vl); +// +// (4) Get the number of vertices so you can copy them into +// your own buffer. +// unsigned int vcount = Vl_getVcount(vl); +// +// (5) Release the VertexLookup interface when you are done with it. +// Vl_releaseVertexLookup(vl); +// +// Teaches the following lessons: +// +// How to wrap the complexity of STL and C++ classes around a +// simple API interface. +// +// How to use an STL set and custom comparator operator for +// a complex data type. +// +// How to create a template class. +// +// How to achieve significant performance improvements by +// taking advantage of built in STL containers in just +// a few lines of code. +// +// You could easily modify this code to support other vertex +// formats with any number of interpolants. + + + + +#include "vlookup.h" + +namespace Vlookup +{ + +class VertexPosition +{ +public: + VertexPosition(void) { }; + VertexPosition(const float *p) + { + mPos[0] = p[0]; + mPos[1] = p[1]; + mPos[2] = p[2]; + }; + + void Set(int index,const float *pos) + { + const float * p = &pos[index*3]; + + mPos[0] = p[0]; + mPos[1] = p[1]; + mPos[2] = p[2]; + + }; + + float GetX(void) const { return mPos[0]; }; + float GetY(void) const { return mPos[1]; }; + float GetZ(void) const { return mPos[2]; }; + + float mPos[3]; +}; + +typedef std::vector< VertexPosition > VertexVector; + +struct Tracker +{ + VertexPosition mFind; // vertice to locate. + VertexVector *mList; + + Tracker() + { + mList = 0; + } + + void SetSearch(const VertexPosition& match,VertexVector *list) + { + mFind = match; + mList = list; + }; +}; + +struct VertexID +{ + int mID; + Tracker* mTracker; + + VertexID(int ID, Tracker* Tracker) + { + mID = ID; + mTracker = Tracker; + } +}; + +class VertexLess +{ +public: + + bool operator()(VertexID v1,VertexID v2) const; + +private: + const VertexPosition& Get(VertexID index) const + { + if ( index.mID == -1 ) return index.mTracker->mFind; + VertexVector &vlist = *index.mTracker->mList; + return vlist[index.mID]; + } +}; + +template class VertexPool +{ +public: + typedef std::set VertexSet; + typedef std::vector< Type > VertexVector; + + int getVertex(const Type& vtx) + { + mTracker.SetSearch(vtx,&mVtxs); + VertexSet::iterator found; + found = mVertSet.find( VertexID(-1,&mTracker) ); + if ( found != mVertSet.end() ) + { + return found->mID; + } + int idx = (int)mVtxs.size(); + mVtxs.push_back( vtx ); + mVertSet.insert( VertexID(idx,&mTracker) ); + return idx; + }; + + + const float * GetPos(int idx) const + { + return mVtxs[idx].mPos; + } + + const Type& Get(int idx) const + { + return mVtxs[idx]; + }; + + unsigned int GetSize(void) const + { + return mVtxs.size(); + }; + + void Clear(int reservesize) // clear the vertice pool. + { + mVertSet.clear(); + mVtxs.clear(); + mVtxs.reserve(reservesize); + }; + + const VertexVector& GetVertexList(void) const { return mVtxs; }; + + void Set(const Type& vtx) + { + mVtxs.push_back(vtx); + } + + unsigned int GetVertexCount(void) const + { + return mVtxs.size(); + }; + + + Type * getBuffer(void) + { + return &mVtxs[0]; + }; + +private: + VertexSet mVertSet; // ordered list. + VertexVector mVtxs; // set of vertices. + Tracker mTracker; +}; + + +bool VertexLess::operator()(VertexID v1,VertexID v2) const +{ + + const VertexPosition& a = Get(v1); + const VertexPosition& b = Get(v2); + + int ixA = (int) (a.GetX()*10000.0f); + int ixB = (int) (b.GetX()*10000.0f); + + if ( ixA < ixB ) return true; + if ( ixA > ixB ) return false; + + int iyA = (int) (a.GetY()*10000.0f); + int iyB = (int) (b.GetY()*10000.0f); + + if ( iyA < iyB ) return true; + if ( iyA > iyB ) return false; + + int izA = (int) (a.GetZ()*10000.0f); + int izB = (int) (b.GetZ()*10000.0f); + + if ( izA < izB ) return true; + if ( izA > izB ) return false; + + + return false; +} + + + + +} + +using namespace Vlookup; + +VertexLookup Vl_createVertexLookup(void) +{ + VertexLookup ret = new VertexPool< VertexPosition >; + return ret; +} + +void Vl_releaseVertexLookup(VertexLookup vlook) +{ + VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; + delete vp; +} + +unsigned int Vl_getIndex(VertexLookup vlook,const float *pos) // get index. +{ + VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; + VertexPosition p(pos); + return vp->getVertex(p); +} + +const float * Vl_getVertices(VertexLookup vlook) +{ + VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; + return vp->GetPos(0); +} + + +unsigned int Vl_getVcount(VertexLookup vlook) +{ + VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; + return vp->GetVertexCount(); +} diff --git a/Extras/ConvexDecomposition/vlookup.h b/Extras/ConvexDecomposition/vlookup.h new file mode 100644 index 0000000..1a6e0a9 --- /dev/null +++ b/Extras/ConvexDecomposition/vlookup.h @@ -0,0 +1,119 @@ +#ifndef VLOOKUP_H + +#define VLOOKUP_H + + +/*---------------------------------------------------------------------- + Copyright (c) 2004 Open Dynamics Framework Group + www.physicstools.org + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of the Open Dynamics Framework Group nor the names of its contributors may + be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-----------------------------------------------------------------------*/ + +// http://codesuppository.blogspot.com +// +// mailto: jratcliff@infiniplex.net +// +// http://www.amillionpixels.us +// + + +// CodeSnippet provided by John W. Ratcliff +// on March 23, 2006. +// +// mailto: jratcliff@infiniplex.net +// +// Personal website: http://jratcliffscarab.blogspot.com +// Coding Website: http://codesuppository.blogspot.com +// FundRaising Blog: http://amillionpixels.blogspot.com +// Fundraising site: http://www.amillionpixels.us +// New Temple Site: http://newtemple.blogspot.com +// +// This snippet shows how to 'hide' the complexity of +// the STL by wrapping some useful piece of functionality +// around a handful of discrete API calls. +// +// This API allows you to create an indexed triangle list +// from a collection of raw input triangles. Internally +// it uses an STL set to build the lookup table very rapidly. +// +// Here is how you would use it to build an indexed triangle +// list from a raw list of triangles. +// +// (1) create a 'VertexLookup' interface by calling +// +// VertexLook vl = Vl_createVertexLookup(); +// +// (2) For each vertice in each triangle call: +// +// unsigned int i1 = Vl_getIndex(vl,p1); +// unsigned int i2 = Vl_getIndex(vl,p2); +// unsigned int i3 = Vl_getIndex(vl,p3); +// +// save the 3 indices into your triangle list array. +// +// (3) Get the vertex array by calling: +// +// const float *vertices = Vl_getVertices(vl); +// +// (4) Get the number of vertices so you can copy them into +// your own buffer. +// unsigned int vcount = Vl_getVcount(vl); +// +// (5) Release the VertexLookup interface when you are done with it. +// Vl_releaseVertexLookup(vl); +// +// Teaches the following lessons: +// +// How to wrap the complexity of STL and C++ classes around a +// simple API interface. +// +// How to use an STL set and custom comparator operator for +// a complex data type. +// +// How to create a template class. +// +// How to achieve significant performance improvements by +// taking advantage of built in STL containers in just +// a few lines of code. +// +// You could easily modify this code to support other vertex +// formats with any number of interpolants. +// +// Hide C++ classes from the rest of your application by +// keeping them in the CPP and wrapping them in a namespace +// Uses an STL set to create an index table for a bunch of vertex positions +// used typically to re-index a collection of raw triangle data. + + +typedef void * VertexLookup; + +VertexLookup Vl_createVertexLookup(void); +void Vl_releaseVertexLookup(VertexLookup vlook); + +unsigned int Vl_getIndex(VertexLookup vlook,const float *pos); // get index. +const float * Vl_getVertices(VertexLookup vlook); +unsigned int Vl_getVcount(VertexLookup vlook); + + +#endif diff --git a/Extras/GIMPACTUtils/CMakeLists.txt b/Extras/GIMPACTUtils/CMakeLists.txt new file mode 100644 index 0000000..5c9480a --- /dev/null +++ b/Extras/GIMPACTUtils/CMakeLists.txt @@ -0,0 +1,37 @@ +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/Extras/GIMPACT/include +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Extras/GIMPACTUtils +${BULLET_PHYSICS_SOURCE_DIR}/Extras/ConvexDecomposition +) + +ADD_LIBRARY(GIMPACTUtils +btGImpactConvexDecompositionShape.cpp btGImpactConvexDecompositionShape.h +) +SET_TARGET_PROPERTIES(GIMPACTUtils PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(GIMPACTUtils PROPERTIES SOVERSION ${BULLET_VERSION}) + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(GIMPACTUtils ConvexDecomposition BulletCollision) +ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_EXTRA_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #FILES_MATCHING requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS GIMPACTUtils DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS GIMPACTUtils DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(GIMPACTUtils PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(GIMPACTUtils PROPERTIES PUBLIC_HEADER "btGImpactConvexDecompositionShape.h") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_EXTRA_LIBS) diff --git a/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp new file mode 100644 index 0000000..f7022ed --- /dev/null +++ b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp @@ -0,0 +1,240 @@ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btGImpactConvexDecompositionShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" + +#include "ConvexBuilder.h" + +class GIM_ConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface +{ +protected: + btGImpactConvexDecompositionShape * m_compoundShape; + + btAlignedObjectArray m_convexShapes; + + +public: + int mBaseCount; + int mHullCount; + bool m_transformSubShapes; + + GIM_ConvexDecomposition(btGImpactConvexDecompositionShape * compoundShape,bool transformSubShapes) + { + mBaseCount = 0; + mHullCount = 0; + m_compoundShape = compoundShape; + m_transformSubShapes = transformSubShapes; + } + + virtual ~GIM_ConvexDecomposition() + { + int i; + for (i=0;i vertices; + + if(m_transformSubShapes) + { + + //const unsigned int *src = result.mHullIndices; + for (unsigned int i=0; isetMargin(m_compoundShape->getMargin()); + + if(m_transformSubShapes) + { + btTransform trans; + trans.setIdentity(); + trans.setOrigin(centroid); + + // add convex shape + + m_compoundShape->addChildShape(trans,convexShape); + } + else + { + btTransform trans; + trans.setIdentity(); + //trans.setOrigin(centroid); + + // add convex shape + + m_compoundShape->addChildShape(trans,convexShape); + + //m_compoundShape->addChildShape(convexShape); + } + } + + void processDecomposition(int part) + { + btGImpactMeshShapePart::TrimeshPrimitiveManager * trimeshInterface = + m_compoundShape->getTrimeshInterface(part); + + + trimeshInterface->lock(); + + //collect vertices + btAlignedObjectArray vertices; + vertices.reserve(trimeshInterface->get_vertex_count()*3); + + for(int vi = 0;viget_vertex_count();vi++) + { + btVector3 vec; + trimeshInterface->get_vertex(vi,vec); + vertices.push_back(vec[0]); + vertices.push_back(vec[1]); + vertices.push_back(vec[2]); + } + + + //collect indices + btAlignedObjectArray indices; + indices.reserve(trimeshInterface->get_primitive_count()*3); + + + for(int i = 0;iget_primitive_count();i++) + { + int i0, i1,i2; + trimeshInterface->get_indices(i,i0,i1,i2); + indices.push_back(i0); + indices.push_back(i1); + indices.push_back(i2); + } + + trimeshInterface->unlock(); + + + + unsigned int depth = 5; + float cpercent = 5; + float ppercent = 15; + unsigned int maxv = 16; + float skinWidth = 0.0f; + + + ConvexDecomposition::DecompDesc desc; + desc.mVcount = trimeshInterface->get_vertex_count(); + desc.mVertices = &vertices[0]; + desc.mTcount = trimeshInterface->get_primitive_count(); + desc.mIndices = &indices[0]; + desc.mDepth = depth; + desc.mCpercent = cpercent; + desc.mPpercent = ppercent; + desc.mMaxVertices = maxv; + desc.mSkinWidth = skinWidth; + desc.mCallback = this; + + //convexDecomposition.performConvexDecomposition(desc); + + ConvexBuilder cb(desc.mCallback); + cb.process(desc); + } + + + + +}; + + + +void btGImpactConvexDecompositionShape::buildConvexDecomposition(bool transformSubShapes) +{ + + m_decomposition = new GIM_ConvexDecomposition(this,transformSubShapes); + + int part_count = m_trimeshInterfaces.size(); + for (int i = 0;iprocessDecomposition(i); + } + + postUpdate(); +} + +btGImpactConvexDecompositionShape::~btGImpactConvexDecompositionShape() +{ + delete m_decomposition; +} +void btGImpactConvexDecompositionShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + + int part_count = m_trimeshInterfaces.size(); + for (int part = 0;part(ptr); + + trimeshInterface->lock(); + + btPrimitiveTriangle triangle; + + + int i = trimeshInterface->get_primitive_count(); + while(i--) + { + trimeshInterface->get_primitive_triangle(i,triangle); + callback->processTriangle(triangle.m_vertices,part,i); + } + + trimeshInterface->unlock(); + } + + +} diff --git a/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h new file mode 100644 index 0000000..4710861 --- /dev/null +++ b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h @@ -0,0 +1,87 @@ +/*! \file btGImpactConvexDecompositionShape.h +\author Francisco León Nájera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H +#define GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H + + +#include "BulletCollision/Gimpact/btGImpactShape.h" // box tree class + + + +//! This class creates a decomposition from a trimesh. +/*! + +*/ +class btGImpactConvexDecompositionShape : public btGImpactCompoundShape +{ +protected: + btAlignedObjectArray m_trimeshInterfaces; + + class GIM_ConvexDecomposition* m_decomposition; + + void buildConvexDecomposition(bool transformSubShapes); +public: + + btGImpactConvexDecompositionShape( + btStridingMeshInterface * meshInterface, + const btVector3 & mesh_scale, + btScalar margin = btScalar(0.01),bool children_has_transform = true) + :btGImpactCompoundShape(children_has_transform) + { + + m_collisionMargin = margin; + + btGImpactMeshShapePart::TrimeshPrimitiveManager triInterface; + triInterface.m_meshInterface = meshInterface; + triInterface.m_scale = mesh_scale; + triInterface.m_margin = btScalar(1.0); + + //add parts + int part_count = meshInterface->getNumSubParts(); + for (int i=0;i< part_count;i++ ) + { + triInterface.m_part = i; + m_trimeshInterfaces.push_back(triInterface); + } + + m_decomposition = 0; + + buildConvexDecomposition(children_has_transform); + } + + virtual ~btGImpactConvexDecompositionShape(); + + SIMD_FORCE_INLINE btGImpactMeshShapePart::TrimeshPrimitiveManager * getTrimeshInterface(int part) + { + return &m_trimeshInterfaces[part]; + } + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + +}; + + + + +#endif //GIMPACT_MESH_SHAPE_H diff --git a/Extras/HACD/CMakeLists.txt b/Extras/HACD/CMakeLists.txt new file mode 100644 index 0000000..4377e45 --- /dev/null +++ b/Extras/HACD/CMakeLists.txt @@ -0,0 +1,51 @@ +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/HACD +) + +SET(HACD_SRCS + hacdGraph.cpp + hacdHACD.cpp + hacdICHull.cpp + hacdManifoldMesh.cpp +) + +SET(HACD_HDRS + hacdCircularList.h + hacdGraph.h + hacdHACD.h + hacdICHull.h + hacdManifoldMesh.h + hacdVector.h + hacdVersion.h + hacdCircularList.inl + hacdVector.inl +) + +ADD_LIBRARY(HACD ${HACD_SRCS} ${HACD_HDRS}) +SET_TARGET_PROPERTIES(HACD PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(HACD PROPERTIES SOVERSION ${BULLET_VERSION}) + +#IF (BUILD_SHARED_LIBS) +# TARGET_LINK_LIBRARIES(HACD BulletCollision LinearMath) +#ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_EXTRA_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #FILES_MATCHING requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS HACD DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS HACD DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN "*.inl" PATTERN + ".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(HACD PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(HACD PROPERTIES PUBLIC_HEADER "${HACD_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_EXTRA_LIBS) diff --git a/Extras/HACD/hacdCircularList.h b/Extras/HACD/hacdCircularList.h new file mode 100644 index 0000000..d673536 --- /dev/null +++ b/Extras/HACD/hacdCircularList.h @@ -0,0 +1,80 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once +#ifndef HACD_CIRCULAR_LIST_H +#define HACD_CIRCULAR_LIST_H +#include +#include "hacdVersion.h" +namespace HACD +{ + //! CircularListElement class. + template < typename T > class CircularListElement + { + public: + T & GetData() { return m_data; } + const T & GetData() const { return m_data; } + CircularListElement * & GetNext() { return m_next; } + CircularListElement * & GetPrev() { return m_prev; } + const CircularListElement * & GetNext() const { return m_next; } + const CircularListElement * & GetPrev() const { return m_prev; } + //! Constructor + CircularListElement(const T & data) {m_data = data;} + CircularListElement(void){} + //! Destructor + ~CircularListElement(void){} + private: + T m_data; + CircularListElement * m_next; + CircularListElement * m_prev; + + CircularListElement(const CircularListElement & rhs); + }; + + + //! CircularList class. + template < typename T > class CircularList + { + public: + CircularListElement * & GetHead() { return m_head;} + const CircularListElement * GetHead() const { return m_head;} + bool IsEmpty() const { return (m_size == 0);} + size_t GetSize() const { return m_size; } + const T & GetData() const { return m_head->GetData(); } + T & GetData() { return m_head->GetData();} + bool Delete() ; + bool Delete(CircularListElement * element); + CircularListElement * Add(const T * data = 0); + CircularListElement * Add(const T & data); + bool Next(); + bool Prev(); + void Clear() { while(Delete());}; + const CircularList& operator=(const CircularList& rhs); + //! Constructor + CircularList() + { + m_head = 0; + m_size = 0; + } + CircularList(const CircularList& rhs); + //! Destructor + virtual ~CircularList(void) {Clear();}; + private: + CircularListElement * m_head; //!< a pointer to the head of the circular list + size_t m_size; //!< number of element in the circular list + + }; +} +#include "hacdCircularList.inl" +#endif diff --git a/Extras/HACD/hacdCircularList.inl b/Extras/HACD/hacdCircularList.inl new file mode 100644 index 0000000..1d48f4e --- /dev/null +++ b/Extras/HACD/hacdCircularList.inl @@ -0,0 +1,163 @@ +#pragma once +#ifndef HACD_CIRCULAR_LIST_INL +#define HACD_CIRCULAR_LIST_INL +#include +#include "hacdVersion.h" +namespace HACD +{ + template < typename T > + inline bool CircularList::Delete(CircularListElement * element) + { + if (!element) + { + return false; + } + if (m_size > 1) + { + CircularListElement * next = element->GetNext(); + CircularListElement * prev = element->GetPrev(); + delete element; + m_size--; + if (element == m_head) + { + m_head = next; + } + next->GetPrev() = prev; + prev->GetNext() = next; + return true; + } + else if (m_size == 1) + { + delete m_head; + m_size--; + m_head = 0; + return true; + } + else + { + return false; + } + } + + template < typename T > + inline bool CircularList::Delete() + { + if (m_size > 1) + { + CircularListElement * next = m_head->GetNext(); + CircularListElement * prev = m_head->GetPrev(); + delete m_head; + m_size--; + m_head = next; + next->GetPrev() = prev; + prev->GetNext() = next; + return true; + } + else if (m_size == 1) + { + delete m_head; + m_size--; + m_head = 0; + return true; + } + else + { + return false; + } + } + template < typename T > + inline CircularListElement * CircularList::Add(const T * data) + { + if (m_size == 0) + { + if (data) + { + m_head = new CircularListElement(*data); + } + else + { + m_head = new CircularListElement(); + } + m_head->GetNext() = m_head->GetPrev() = m_head; + } + else + { + CircularListElement * next = m_head->GetNext(); + CircularListElement * element = m_head; + if (data) + { + m_head = new CircularListElement(*data); + } + else + { + m_head = new CircularListElement; + } + m_head->GetNext() = next; + m_head->GetPrev() = element; + element->GetNext() = m_head; + next->GetPrev() = m_head; + } + m_size++; + return m_head; + } + template < typename T > + inline CircularListElement * CircularList::Add(const T & data) + { + const T * pData = &data; + return Add(pData); + } + template < typename T > + inline bool CircularList::Next() + { + if (m_size == 0) + { + return false; + } + m_head = m_head->GetNext(); + return true; + } + template < typename T > + inline bool CircularList::Prev() + { + if (m_size == 0) + { + return false; + } + m_head = m_head->GetPrev(); + return true; + } + template < typename T > + inline CircularList::CircularList(const CircularList& rhs) + { + if (rhs.m_size > 0) + { + CircularListElement * current = rhs.m_head; + do + { + current = current->GetNext(); + Add(current->GetData()); + } + while ( current != rhs.m_head ); + } + } + template < typename T > + inline const CircularList& CircularList::operator=(const CircularList& rhs) + { + if (&rhs != this) + { + Clear(); + if (rhs.m_size > 0) + { + CircularListElement * current = rhs.m_head; + do + { + current = current->GetNext(); + Add(current->GetData()); + } + while ( current != rhs.m_head ); + } + } + return (*this); + } +} +#endif diff --git a/Extras/HACD/hacdGraph.cpp b/Extras/HACD/hacdGraph.cpp new file mode 100644 index 0000000..bd7c73e --- /dev/null +++ b/Extras/HACD/hacdGraph.cpp @@ -0,0 +1,292 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "hacdGraph.h" +namespace HACD +{ + + GraphEdge::GraphEdge() + { + m_convexHull = 0; + m_v1 = -1; + m_v2 = -1; + m_name = -1; + m_error = 0; + m_surf = 0; + m_perimeter = 0; + m_concavity = 0; + m_volume = 0; + m_deleted = false; + } + + GraphVertex::GraphVertex() + { + m_convexHull = 0; + m_name = -1; + m_cc = -1; + m_error = 0; + m_surf = 0; + m_perimeter = 0; + m_concavity = 0; + m_volume = 0; + m_deleted = false; + } + + bool GraphVertex::DeleteEdge(long name) + { + std::set::iterator it = m_edges.find(name); + if (it != m_edges.end() ) + { + m_edges.erase(it); + return true; + } + return false; + } + + Graph::Graph() + { + m_nV = 0; + m_nE = 0; + m_nCCs = 0; + } + + Graph::~Graph() + { + } + + void Graph::Allocate(size_t nV, size_t nE) + { + m_nV = nV; + m_edges.reserve(nE); + m_vertices.resize(nV); + for(size_t i = 0; i < nV; i++) + { + m_vertices[i].m_name = static_cast(i); + } + } + + long Graph::AddVertex() + { + size_t name = m_vertices.size(); + m_vertices.resize(name+1); + m_vertices[name].m_name = static_cast(name); + m_nV++; + return static_cast(name); + } + + long Graph::AddEdge(long v1, long v2) + { + size_t name = m_edges.size(); + m_edges.push_back(GraphEdge()); + m_edges[name].m_name = static_cast(name); + m_edges[name].m_v1 = v1; + m_edges[name].m_v2 = v2; + m_vertices[v1].AddEdge(static_cast(name)); + m_vertices[v2].AddEdge(static_cast(name)); + m_nE++; + return static_cast(name); + } + + bool Graph::DeleteEdge(long name) + { + if (name < static_cast(m_edges.size())) + { + long v1 = m_edges[name].m_v1; + long v2 = m_edges[name].m_v2; + m_edges[name].m_deleted = true; + m_vertices[v1].DeleteEdge(name); + m_vertices[v2].DeleteEdge(name); + delete m_edges[name].m_convexHull; + m_edges[name].m_distPoints.clear(); + m_edges[name].m_boudaryEdges.clear(); + m_edges[name].m_convexHull = 0; + m_nE--; + return true; + } + return false; + } + bool Graph::DeleteVertex(long name) + { + if (name < static_cast(m_vertices.size())) + { + m_vertices[name].m_deleted = true; + m_vertices[name].m_edges.clear(); + m_vertices[name].m_ancestors = std::vector(); + delete m_vertices[name].m_convexHull; + m_vertices[name].m_distPoints.clear(); + m_vertices[name].m_boudaryEdges.clear(); + m_vertices[name].m_convexHull = 0; + m_nV--; + return true; + } + return false; + } + bool Graph::EdgeCollapse(long v1, long v2) + { + long edgeToDelete = GetEdgeID(v1, v2); + if (edgeToDelete >= 0) + { + // delete the edge (v1, v2) + DeleteEdge(edgeToDelete); + // add v2 to v1 ancestors + m_vertices[v1].m_ancestors.push_back(v2); + // add v2's ancestors to v1's ancestors + m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(), + m_vertices[v2].m_ancestors.begin(), + m_vertices[v2].m_ancestors.end()); + // update adjacency information + std::set & v1Edges = m_vertices[v1].m_edges; + std::set::const_iterator ed(m_vertices[v2].m_edges.begin()); + std::set::const_iterator itEnd(m_vertices[v2].m_edges.end()); + long b = -1; + for(; ed != itEnd; ++ed) + { + if (m_edges[*ed].m_v1 == v2) + { + b = m_edges[*ed].m_v2; + } + else + { + b = m_edges[*ed].m_v1; + } + if (GetEdgeID(v1, b) >= 0) + { + m_edges[*ed].m_deleted = true; + m_vertices[b].DeleteEdge(*ed); + m_nE--; + } + else + { + m_edges[*ed].m_v1 = v1; + m_edges[*ed].m_v2 = b; + v1Edges.insert(*ed); + } + } + // delete the vertex v2 + DeleteVertex(v2); + return true; + } + return false; + } + + long Graph::GetEdgeID(long v1, long v2) const + { + if (v1 < static_cast(m_vertices.size()) && !m_vertices[v1].m_deleted) + { + std::set::const_iterator ed(m_vertices[v1].m_edges.begin()); + std::set::const_iterator itEnd(m_vertices[v1].m_edges.end()); + for(; ed != itEnd; ++ed) + { + if ( (m_edges[*ed].m_v1 == v2) || + (m_edges[*ed].m_v2 == v2) ) + { + return m_edges[*ed].m_name; + } + } + } + return -1; + } + + void Graph::Print() const + { + std::cout << "-----------------------------" << std::endl; + std::cout << "vertices (" << m_nV << ")" << std::endl; + for (size_t v = 0; v < m_vertices.size(); ++v) + { + const GraphVertex & currentVertex = m_vertices[v]; + if (!m_vertices[v].m_deleted) + { + + std::cout << currentVertex.m_name << "\t"; + std::set::const_iterator ed(currentVertex.m_edges.begin()); + std::set::const_iterator itEnd(currentVertex.m_edges.end()); + for(; ed != itEnd; ++ed) + { + std::cout << "(" << m_edges[*ed].m_v1 << "," << m_edges[*ed].m_v2 << ") "; + } + std::cout << std::endl; + } + } + + std::cout << "vertices (" << m_nE << ")" << std::endl; + for (size_t e = 0; e < m_edges.size(); ++e) + { + const GraphEdge & currentEdge = m_edges[e]; + if (!m_edges[e].m_deleted) + { + std::cout << currentEdge.m_name << "\t(" + << m_edges[e].m_v1 << "," + << m_edges[e].m_v2 << ") "<< std::endl; + } + } + } + void Graph::Clear() + { + m_vertices.clear(); + m_edges.clear(); + m_nV = 0; + m_nE = 0; + } + + long Graph::ExtractCCs() + { + // all CCs to -1 + for (size_t v = 0; v < m_vertices.size(); ++v) + { + if (!m_vertices[v].m_deleted) + { + m_vertices[v].m_cc = -1; + } + } + + // we get the CCs + m_nCCs = 0; + long v2 = -1; + std::vector temp; + for (size_t v = 0; v < m_vertices.size(); ++v) + { + if (!m_vertices[v].m_deleted && m_vertices[v].m_cc == -1) + { + m_vertices[v].m_cc = static_cast(m_nCCs); + temp.clear(); + temp.push_back(m_vertices[v].m_name); + while (temp.size()) + { + long vertex = temp[temp.size()-1]; + temp.pop_back(); + std::set::const_iterator ed(m_vertices[vertex].m_edges.begin()); + std::set::const_iterator itEnd(m_vertices[vertex].m_edges.end()); + for(; ed != itEnd; ++ed) + { + if (m_edges[*ed].m_v1 == vertex) + { + v2 = m_edges[*ed].m_v2; + } + else + { + v2 = m_edges[*ed].m_v1; + } + if ( !m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1) + { + m_vertices[v2].m_cc = static_cast(m_nCCs); + temp.push_back(v2); + } + } + } + m_nCCs++; + } + } + return static_cast(m_nCCs); + } +} diff --git a/Extras/HACD/hacdGraph.h b/Extras/HACD/hacdGraph.h new file mode 100644 index 0000000..12b0d3c --- /dev/null +++ b/Extras/HACD/hacdGraph.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once +#ifndef HACD_GRAPH_H +#define HACD_GRAPH_H +#include "hacdVersion.h" +#include "hacdVector.h" +#include "hacdICHull.h" +#include +#include +#include + +namespace HACD +{ + class GraphVertex; + class GraphEdge; + class Graph; + class HACD; + + class GraphVertex + { + public: + bool AddEdge(long name) + { + m_edges.insert(name); + return true; + } + bool DeleteEdge(long name); + GraphVertex(); + ~GraphVertex(){ delete m_convexHull;}; + private: + long m_name; + long m_cc; + std::set m_edges; + bool m_deleted; + std::vector m_ancestors; + std::map m_distPoints; + + Real m_error; + double m_surf; + double m_volume; + double m_perimeter; + double m_concavity; + ICHull * m_convexHull; + std::set m_boudaryEdges; + + + friend class GraphEdge; + friend class Graph; + friend class HACD; + }; + + class GraphEdge + { + public: + GraphEdge(); + ~GraphEdge(){delete m_convexHull;}; + private: + long m_name; + long m_v1; + long m_v2; + std::map m_distPoints; + Real m_error; + double m_surf; + double m_volume; + double m_perimeter; + double m_concavity; + ICHull * m_convexHull; + std::set m_boudaryEdges; + bool m_deleted; + + + + friend class GraphVertex; + friend class Graph; + friend class HACD; + }; + + class Graph + { + public: + size_t GetNEdges() const { return m_nE;} + size_t GetNVertices() const { return m_nV;} + bool EdgeCollapse(long v1, long v2); + long AddVertex(); + long AddEdge(long v1, long v2); + bool DeleteEdge(long name); + bool DeleteVertex(long name); + long GetEdgeID(long v1, long v2) const; + void Clear(); + void Print() const; + long ExtractCCs(); + + Graph(); + virtual ~Graph(); + void Allocate(size_t nV, size_t nE); + + private: + size_t m_nCCs; + size_t m_nV; + size_t m_nE; + std::vector m_edges; + std::vector m_vertices; + + friend class HACD; + }; +} +#endif diff --git a/Extras/HACD/hacdHACD.cpp b/Extras/HACD/hacdHACD.cpp new file mode 100644 index 0000000..b7d16e5 --- /dev/null +++ b/Extras/HACD/hacdHACD.cpp @@ -0,0 +1,847 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif //_CRT_SECURE_NO_WARNINGS + +#include +#include "hacdGraph.h" +#include "hacdHACD.h" +#include "hacdICHull.h" +#include +#include +#include +#include + +bool gCancelRequest=false; +namespace HACD +{ + double HACD::Concavity(ICHull & ch, std::map & distPoints) + { + double concavity = 0.0; + double distance = 0.0; + std::map::iterator itDP(distPoints.begin()); + std::map::iterator itDPEnd(distPoints.end()); + for(; itDP != itDPEnd; ++itDP) + { + if (!(itDP->second).m_computed) + { + if (itDP->first >= 0) + { + distance = ch.ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], (itDP->second).m_computed, true); + } + else + { + distance = ch.ComputeDistance(itDP->first, m_facePoints[-itDP->first-1], m_faceNormals[-itDP->first-1], (itDP->second).m_computed, true); + } + } + else + { + distance = (itDP->second).m_dist; + } + if (concavity < distance) + { + concavity = distance; + } + } + return concavity; + } + + void HACD::CreateGraph() + { + // vertex to triangle adjacency information + std::vector< std::set > vertexToTriangles; + vertexToTriangles.resize(m_nPoints); + for(size_t t = 0; t < m_nTriangles; ++t) + { + vertexToTriangles[m_triangles[t].X()].insert(static_cast(t)); + vertexToTriangles[m_triangles[t].Y()].insert(static_cast(t)); + vertexToTriangles[m_triangles[t].Z()].insert(static_cast(t)); + } + + m_graph.Clear(); + m_graph.Allocate(m_nTriangles, 5 * m_nTriangles); + unsigned long long tr1[3]; + unsigned long long tr2[3]; + long i1, j1, k1, i2, j2, k2; + long t1, t2; + for (size_t v = 0; v < m_nPoints; v++) + { + std::set::const_iterator it1(vertexToTriangles[v].begin()), itEnd(vertexToTriangles[v].end()); + for(; it1 != itEnd; ++it1) + { + t1 = *it1; + i1 = m_triangles[t1].X(); + j1 = m_triangles[t1].Y(); + k1 = m_triangles[t1].Z(); + tr1[0] = GetEdgeIndex(i1, j1); + tr1[1] = GetEdgeIndex(j1, k1); + tr1[2] = GetEdgeIndex(k1, i1); + std::set::const_iterator it2(it1); + for(++it2; it2 != itEnd; ++it2) + { + t2 = *it2; + i2 = m_triangles[t2].X(); + j2 = m_triangles[t2].Y(); + k2 = m_triangles[t2].Z(); + tr2[0] = GetEdgeIndex(i2, j2); + tr2[1] = GetEdgeIndex(j2, k2); + tr2[2] = GetEdgeIndex(k2, i2); + int shared = 0; + for(int i = 0; i < 3; ++i) + { + for(int j = 0; j < 3; ++j) + { + if (tr1[i] == tr2[j]) + { + shared++; + } + } + } + if (shared == 1) // two triangles are connected if they share exactly one edge + { + m_graph.AddEdge(t1, t2); + } + } + } + } + if (m_ccConnectDist >= 0.0) + { + m_graph.ExtractCCs(); + if (m_graph.m_nCCs > 1) + { + std::vector< std::set > cc2V; + cc2V.resize(m_graph.m_nCCs); + long cc; + for(size_t t = 0; t < m_nTriangles; ++t) + { + cc = m_graph.m_vertices[t].m_cc; + cc2V[cc].insert(m_triangles[t].X()); + cc2V[cc].insert(m_triangles[t].Y()); + cc2V[cc].insert(m_triangles[t].Z()); + } + + for(size_t cc1 = 0; cc1 < m_graph.m_nCCs; ++cc1) + { + for(size_t cc2 = cc1+1; cc2 < m_graph.m_nCCs; ++cc2) + { + std::set::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end()); + for(; itV1 != itVEnd1; ++itV1) + { + double distC1C2 = std::numeric_limits::max(); + double dist; + t1 = -1; + t2 = -1; + std::set::const_iterator itV2(cc2V[cc2].begin()), itVEnd2(cc2V[cc2].end()); + for(; itV2 != itVEnd2; ++itV2) + { + dist = (m_points[*itV1] - m_points[*itV2]).GetNorm(); + if (dist < distC1C2) + { + distC1C2 = dist; + t1 = *vertexToTriangles[*itV1].begin(); + + std::set::const_iterator it2(vertexToTriangles[*itV2].begin()), + it2End(vertexToTriangles[*itV2].end()); + t2 = -1; + for(; it2 != it2End; ++it2) + { + if (*it2 != t1) + { + t2 = *it2; + break; + } + } + } + } + if (distC1C2 <= m_ccConnectDist && t1 > 0 && t2 > 0) + { + + m_graph.AddEdge(t1, t2); + } + } + } + } + } + } + } + void HACD::InitializeDualGraph() + { + long i, j, k; + Vec3 u, v, w, normal; + delete [] m_normals; + m_normals = new Vec3[m_nPoints]; + if (m_addFacesPoints) + { + delete [] m_facePoints; + delete [] m_faceNormals; + m_facePoints = new Vec3[m_nTriangles]; + m_faceNormals = new Vec3[m_nTriangles]; + } + memset(m_normals, 0, sizeof(Vec3) * m_nPoints); + for(unsigned long f = 0; f < m_nTriangles; f++) + { + if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0); + + if (gCancelRequest) + return; + + i = m_triangles[f].X(); + j = m_triangles[f].Y(); + k = m_triangles[f].Z(); + + m_graph.m_vertices[f].m_distPoints[i].m_distOnly = false; + m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false; + m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false; + + ICHull * ch = new ICHull; + m_graph.m_vertices[f].m_convexHull = ch; + ch->AddPoint(m_points[i], i); + ch->AddPoint(m_points[j], j); + ch->AddPoint(m_points[k], k); + ch->SetDistPoints(&m_graph.m_vertices[f].m_distPoints); + + u = m_points[j] - m_points[i]; + v = m_points[k] - m_points[i]; + w = m_points[k] - m_points[j]; + normal = u ^ v; + + m_normals[i] += normal; + m_normals[j] += normal; + m_normals[k] += normal; + + m_graph.m_vertices[f].m_surf = normal.GetNorm(); + m_graph.m_vertices[f].m_perimeter = u.GetNorm() + v.GetNorm() + w.GetNorm(); + + normal.Normalize(); + + m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i,j)); + m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j,k)); + m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k,i)); + if(m_addFacesPoints) + { + m_faceNormals[f] = normal; + m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0; + m_graph.m_vertices[f].m_distPoints[-static_cast(f)-1].m_distOnly = true; + } + if (m_addExtraDistPoints) + {// we need a kd-tree structure to accelerate this part! + long i1, j1, k1; + Vec3 u1, v1, normal1; + normal = -normal; + double distance = 0.0; + double distMin = 0.0; + size_t faceIndex = m_nTriangles; + Vec3 seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0); + long nhit = 0; + for(size_t f1 = 0; f1 < m_nTriangles; f1++) + { + i1 = m_triangles[f1].X(); + j1 = m_triangles[f1].Y(); + k1 = m_triangles[f1].Z(); + u1 = m_points[j1] - m_points[i1]; + v1 = m_points[k1] - m_points[i1]; + normal1 = (u1 ^ v1); + if (normal * normal1 > 0.0) + { + nhit = IntersectRayTriangle(Vec3(seedPoint.X(), seedPoint.Y(), seedPoint.Z()), + Vec3(normal.X(), normal.Y(), normal.Z()), + Vec3(m_points[i1].X(), m_points[i1].Y(), m_points[i1].Z()), + Vec3(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()), + Vec3(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()), + distance); + if ((nhit==1) && ((distMin > distance) || (faceIndex == m_nTriangles))) + { + distMin = distance; + faceIndex = f1; + } + + } + } + if (faceIndex < m_nTriangles ) + { + i1 = m_triangles[faceIndex].X(); + j1 = m_triangles[faceIndex].Y(); + k1 = m_triangles[faceIndex].Z(); + m_graph.m_vertices[f].m_distPoints[i1].m_distOnly = true; + m_graph.m_vertices[f].m_distPoints[j1].m_distOnly = true; + m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true; + if (m_addFacesPoints) + { + m_graph.m_vertices[f].m_distPoints[-static_cast(faceIndex)-1].m_distOnly = true; + } + } + } + } + for (size_t v = 0; v < m_nPoints; v++) + { + m_normals[v].Normalize(); + } + } + + void HACD::NormalizeData() + { + if (m_nPoints == 0) + { + return; + } + m_barycenter = m_points[0]; + Vec3 min = m_points[0]; + Vec3 max = m_points[0]; + Real x, y, z; + for (size_t v = 1; v < m_nPoints ; v++) + { + m_barycenter += m_points[v]; + x = m_points[v].X(); + y = m_points[v].Y(); + z = m_points[v].Z(); + if ( x < min.X()) min.X() = x; + else if ( x > max.X()) max.X() = x; + if ( y < min.Y()) min.Y() = y; + else if ( y > max.Y()) max.Y() = y; + if ( z < min.Z()) min.Z() = z; + else if ( z > max.Z()) max.Z() = z; + } + m_barycenter /= static_cast(m_nPoints); + m_diag = (max-min).GetNorm(); + const Real invDiag = static_cast(2.0 * m_scale / m_diag); + if (m_diag != 0.0) + { + for (size_t v = 0; v < m_nPoints ; v++) + { + m_points[v] = (m_points[v] - m_barycenter) * invDiag; + } + } + } + void HACD::DenormalizeData() + { + if (m_nPoints == 0) + { + return; + } + if (m_diag != 0.0) + { + const Real diag = static_cast(m_diag / (2.0 * m_scale)); + for (size_t v = 0; v < m_nPoints ; v++) + { + m_points[v] = m_points[v] * diag + m_barycenter; + } + } + } + HACD::HACD(void) + { + m_convexHulls = 0; + m_triangles = 0; + m_points = 0; + m_normals = 0; + m_nTriangles = 0; + m_nPoints = 0; + m_nClusters = 0; + m_concavity = 0.0; + m_diag = 1.0; + m_barycenter = Vec3(0.0, 0.0,0.0); + m_alpha = 0.1; + m_beta = 0.1; + m_nVerticesPerCH = 30; + m_callBack = 0; + m_addExtraDistPoints = false; + m_addNeighboursDistPoints = false; + m_scale = 1000.0; + m_partition = 0; + m_nMinClusters = 3; + m_facePoints = 0; + m_faceNormals = 0; + m_ccConnectDist = 30; + } + HACD::~HACD(void) + { + delete [] m_normals; + delete [] m_convexHulls; + delete [] m_partition; + delete [] m_facePoints; + delete [] m_faceNormals; + } + int iteration = 0; + void HACD::ComputeEdgeCost(size_t e) + { + GraphEdge & gE = m_graph.m_edges[e]; + long v1 = gE.m_v1; + long v2 = gE.m_v2; + + if (m_graph.m_vertices[v2].m_distPoints.size()>m_graph.m_vertices[v1].m_distPoints.size()) + { + gE.m_v1 = v2; + gE.m_v2 = v1; + //std::swap(v1, v2); + std::swap(v1, v2); + } + GraphVertex & gV1 = m_graph.m_vertices[v1]; + GraphVertex & gV2 = m_graph.m_vertices[v2]; + + // delete old convex-hull + delete gE.m_convexHull; + // create the edge's convex-hull + ICHull * ch = new ICHull; + gE.m_convexHull = ch; + (*ch) = (*gV1.m_convexHull); + + // update distPoints + gE.m_distPoints = gV1.m_distPoints; + std::map::iterator itDP(gV2.m_distPoints.begin()); + std::map::iterator itDPEnd(gV2.m_distPoints.end()); + std::map::iterator itDP1; + + for(; itDP != itDPEnd; ++itDP) + { + itDP1 = gE.m_distPoints.find(itDP->first); + if (itDP1 == gE.m_distPoints.end()) + { + gE.m_distPoints[itDP->first].m_distOnly = (itDP->second).m_distOnly; + if ( !(itDP->second).m_distOnly ) + { + ch->AddPoint(m_points[itDP->first], itDP->first); + } + } + else + { + if ( (itDP1->second).m_distOnly && !(itDP->second).m_distOnly) + { + gE.m_distPoints[itDP->first].m_distOnly = false; + ch->AddPoint(m_points[itDP->first], itDP->first); + } + } + } + + ch->SetDistPoints(&gE.m_distPoints); + // create the convex-hull + while (ch->Process() == ICHullErrorInconsistent) // if we face problems when constructing the visual-hull. really ugly!!!! + { +// if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0); + ch = new ICHull; + CircularList & verticesCH = (gE.m_convexHull)->GetMesh().m_vertices; + size_t nV = verticesCH.GetSize(); + long ptIndex = 0; + verticesCH.Next(); + for(size_t v = 1; v < nV; ++v) + { + ptIndex = verticesCH.GetHead()->GetData().m_name; + ch->AddPoint(m_points[ptIndex], ptIndex); + verticesCH.Next(); + } + delete gE.m_convexHull; + gE.m_convexHull = ch; + } + double volume = 0.0; + double concavity = 0.0; + if (ch->IsFlat()) + { + bool insideHull; + std::map::iterator itDP(gE.m_distPoints.begin()); + std::map::iterator itDPEnd(gE.m_distPoints.end()); + for(; itDP != itDPEnd; ++itDP) + { + if (itDP->first >= 0) + { + concavity = std::max(concavity, ch->ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], insideHull, false)); + } + } + } + else + { + if (m_addNeighboursDistPoints) + { // add distance points from adjacent clusters + std::set eEdges; + std::set_union(gV1.m_edges.begin(), + gV1.m_edges.end(), + gV2.m_edges.begin(), + gV2.m_edges.end(), + std::inserter( eEdges, eEdges.begin() ) ); + + std::set::const_iterator ed(eEdges.begin()); + std::set::const_iterator itEnd(eEdges.end()); + long a, b, c; + for(; ed != itEnd; ++ed) + { + a = m_graph.m_edges[*ed].m_v1; + b = m_graph.m_edges[*ed].m_v2; + if ( a != v2 && a != v1) + { + c = a; + } + else if ( b != v2 && b != v1) + { + c = b; + } + else + { + c = -1; + } + if ( c > 0) + { + GraphVertex & gVC = m_graph.m_vertices[c]; + std::map::iterator itDP(gVC.m_distPoints.begin()); + std::map::iterator itDPEnd(gVC.m_distPoints.end()); + std::map::iterator itDP1; + for(; itDP != itDPEnd; ++itDP) + { + itDP1 = gE.m_distPoints.find(itDP->first); + if (itDP1 == gE.m_distPoints.end()) + { + if (itDP->first >= 0 && itDP1 == gE.m_distPoints.end() && ch->IsInside(m_points[itDP->first])) + { + gE.m_distPoints[itDP->first].m_distOnly = true; + } + else if (itDP->first < 0 && ch->IsInside(m_facePoints[-itDP->first-1])) + { + gE.m_distPoints[itDP->first].m_distOnly = true; + } + } + } + } + } + } + concavity = Concavity(*ch, gE.m_distPoints); + } + + // compute boudary edges + double perimeter = 0.0; + double surf = 1.0; + if (m_alpha > 0.0) + { + gE.m_boudaryEdges.clear(); + std::set_symmetric_difference (gV1.m_boudaryEdges.begin(), + gV1.m_boudaryEdges.end(), + gV2.m_boudaryEdges.begin(), + gV2.m_boudaryEdges.end(), + std::inserter( gE.m_boudaryEdges, + gE.m_boudaryEdges.begin() ) ); + + std::set::const_iterator itBE(gE.m_boudaryEdges.begin()); + std::set::const_iterator itBEEnd(gE.m_boudaryEdges.end()); + for(; itBE != itBEEnd; ++itBE) + { + perimeter += (m_points[static_cast((*itBE) >> 32)] - + m_points[static_cast((*itBE) & 0xFFFFFFFFULL)]).GetNorm(); + } + surf = gV1.m_surf + gV2.m_surf; + } + double ratio = perimeter * perimeter / (4.0 * sc_pi * surf); + gE.m_volume = (m_beta == 0.0)?0.0:ch->ComputeVolume()/pow(m_scale, 3.0); // cluster's volume + gE.m_surf = surf; // cluster's area + gE.m_perimeter = perimeter; // cluster's perimeter + gE.m_concavity = concavity; // cluster's concavity + gE.m_error = static_cast(concavity + m_alpha * ratio + m_beta * volume); // cluster's priority + } + bool HACD::InitializePriorityQueue() + { + m_pqueue.reserve(m_graph.m_nE + 100); + for (size_t e=0; e < m_graph.m_nE; ++e) + { + ComputeEdgeCost(static_cast(e)); + m_pqueue.push(GraphEdgePriorityQueue(static_cast(e), m_graph.m_edges[e].m_error)); + } + return true; + } + void HACD::Simplify() + { + long v1 = -1; + long v2 = -1; + double progressOld = -1.0; + double progress = 0.0; + double globalConcavity = 0.0; + char msg[1024]; + double ptgStep = 1.0; + while ( (globalConcavity < m_concavity) && + (m_graph.GetNVertices() > m_nMinClusters) && + (m_graph.GetNEdges() > 0)) + { + progress = 100.0-m_graph.GetNVertices() * 100.0 / m_nTriangles; + if (fabs(progress-progressOld) > ptgStep && m_callBack) + { + sprintf(msg, "%3.2f %% V = %lu \t C = %f \t \t \r", progress, static_cast(m_graph.GetNVertices()), globalConcavity); + (*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices()); + progressOld = progress; + if (progress > 99.0) + { + ptgStep = 0.01; + } + else if (progress > 90.0) + { + ptgStep = 0.1; + } + } + + GraphEdgePriorityQueue currentEdge(0,0.0); + bool done = false; + do + { + done = false; + if (m_pqueue.size() == 0) + { + done = true; + break; + } + currentEdge = m_pqueue.top(); + m_pqueue.pop(); + } + while ( m_graph.m_edges[currentEdge.m_name].m_deleted || + m_graph.m_edges[currentEdge.m_name].m_error != currentEdge.m_priority); + + + if (m_graph.m_edges[currentEdge.m_name].m_concavity < m_concavity && !done) + { + globalConcavity = std::max(globalConcavity ,m_graph.m_edges[currentEdge.m_name].m_concavity); + v1 = m_graph.m_edges[currentEdge.m_name].m_v1; + v2 = m_graph.m_edges[currentEdge.m_name].m_v2; + // update vertex info + m_graph.m_vertices[v1].m_error = m_graph.m_edges[currentEdge.m_name].m_error; + m_graph.m_vertices[v1].m_surf = m_graph.m_edges[currentEdge.m_name].m_surf; + m_graph.m_vertices[v1].m_volume = m_graph.m_edges[currentEdge.m_name].m_volume; + m_graph.m_vertices[v1].m_concavity = m_graph.m_edges[currentEdge.m_name].m_concavity; + m_graph.m_vertices[v1].m_perimeter = m_graph.m_edges[currentEdge.m_name].m_perimeter; + m_graph.m_vertices[v1].m_distPoints = m_graph.m_edges[currentEdge.m_name].m_distPoints; + (*m_graph.m_vertices[v1].m_convexHull) = (*m_graph.m_edges[currentEdge.m_name].m_convexHull); + (m_graph.m_vertices[v1].m_convexHull)->SetDistPoints(&(m_graph.m_vertices[v1].m_distPoints)); + m_graph.m_vertices[v1].m_boudaryEdges = m_graph.m_edges[currentEdge.m_name].m_boudaryEdges; + + // We apply the optimal ecol +// std::cout << "v1 " << v1 << " v2 " << v2 << std::endl; + m_graph.EdgeCollapse(v1, v2); + // recompute the adjacent edges costs + std::set::const_iterator itE(m_graph.m_vertices[v1].m_edges.begin()), + itEEnd(m_graph.m_vertices[v1].m_edges.end()); + for(; itE != itEEnd; ++itE) + { + size_t e = *itE; + ComputeEdgeCost(static_cast(e)); + m_pqueue.push(GraphEdgePriorityQueue(static_cast(e), m_graph.m_edges[e].m_error)); + } + } + else + { + break; + } + } + while (!m_pqueue.empty()) + { + m_pqueue.pop(); + } + + m_cVertices.clear(); + m_nClusters = m_graph.GetNVertices(); + m_cVertices.reserve(m_nClusters); + for (size_t p=0, v = 0; v != m_graph.m_vertices.size(); ++v) + { + if (!m_graph.m_vertices[v].m_deleted) + { + if (m_callBack) + { + char msg[1024]; + sprintf(msg, "\t CH \t %lu \t %lf \t %lf\n", static_cast(p), m_graph.m_vertices[v].m_concavity, m_graph.m_vertices[v].m_error); + (*m_callBack)(msg, 0.0, 0.0, m_nClusters); + p++; + } + m_cVertices.push_back(static_cast(v)); + } + } + if (m_callBack) + { + sprintf(msg, "# clusters = %lu \t C = %f\n", static_cast(m_nClusters), globalConcavity); + (*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices()); + } + + } + + bool HACD::Compute(bool fullCH, bool exportDistPoints) + { + gCancelRequest = false; + + if ( !m_points || !m_triangles || !m_nPoints || !m_nTriangles) + { + return false; + } + size_t nV = m_nTriangles; + if (m_callBack) + { + std::ostringstream msg; + msg << "+ Mesh" << std::endl; + msg << "\t # vertices \t" << m_nPoints << std::endl; + msg << "\t # triangles \t" << m_nTriangles << std::endl; + msg << "+ Parameters" << std::endl; + msg << "\t min # of clusters \t" << m_nMinClusters << std::endl; + msg << "\t max concavity \t" << m_concavity << std::endl; + msg << "\t compacity weigth \t" << m_alpha << std::endl; + msg << "\t volume weigth \t" << m_beta << std::endl; + msg << "\t # vertices per convex-hull \t" << m_nVerticesPerCH << std::endl; + msg << "\t scale \t" << m_scale << std::endl; + msg << "\t add extra distance points \t" << m_addExtraDistPoints << std::endl; + msg << "\t add neighbours distance points \t" << m_addNeighboursDistPoints << std::endl; + msg << "\t add face distance points \t" << m_addFacesPoints << std::endl; + msg << "\t produce full convex-hulls \t" << fullCH << std::endl; + msg << "\t max. distance to connect CCs \t" << m_ccConnectDist << std::endl; + (*m_callBack)(msg.str().c_str(), 0.0, 0.0, nV); + } + if (m_callBack) (*m_callBack)("+ Normalizing Data\n", 0.0, 0.0, nV); + NormalizeData(); + if (m_callBack) (*m_callBack)("+ Creating Graph\n", 0.0, 0.0, nV); + CreateGraph(); + // Compute the surfaces and perimeters of all the faces + if (m_callBack) (*m_callBack)("+ Initializing Dual Graph\n", 0.0, 0.0, nV); + if (gCancelRequest) + return false; + + InitializeDualGraph(); + if (m_callBack) (*m_callBack)("+ Initializing Priority Queue\n", 0.0, 0.0, nV); + if (gCancelRequest) + return false; + + InitializePriorityQueue(); + // we simplify the graph + if (m_callBack) (*m_callBack)("+ Simplification ...\n", 0.0, 0.0, m_nTriangles); + Simplify(); + if (m_callBack) (*m_callBack)("+ Denormalizing Data\n", 0.0, 0.0, m_nClusters); + DenormalizeData(); + if (m_callBack) (*m_callBack)("+ Computing final convex-hulls\n", 0.0, 0.0, m_nClusters); + delete [] m_convexHulls; + m_convexHulls = new ICHull[m_nClusters]; + delete [] m_partition; + m_partition = new long [m_nTriangles]; + for (size_t p = 0; p != m_cVertices.size(); ++p) + { + size_t v = m_cVertices[p]; + m_partition[v] = static_cast(p); + for(size_t a = 0; a < m_graph.m_vertices[v].m_ancestors.size(); a++) + { + m_partition[m_graph.m_vertices[v].m_ancestors[a]] = static_cast(p); + } + // compute the convex-hull + const std::map & pointsCH = m_graph.m_vertices[v].m_distPoints; + std::map::const_iterator itCH(pointsCH.begin()); + std::map::const_iterator itCHEnd(pointsCH.end()); + for(; itCH != itCHEnd; ++itCH) + { + if (!(itCH->second).m_distOnly) + { + m_convexHulls[p].AddPoint(m_points[itCH->first], itCH->first); + } + } + m_convexHulls[p].SetDistPoints(&m_graph.m_vertices[v].m_distPoints); + if (fullCH) + { + m_convexHulls[p].Process(); + } + else + { + m_convexHulls[p].Process(static_cast(m_nVerticesPerCH)); + } + if (exportDistPoints) + { + itCH = pointsCH.begin(); + for(; itCH != itCHEnd; ++itCH) + { + if ((itCH->second).m_distOnly) + { + if (itCH->first >= 0) + { + m_convexHulls[p].AddPoint(m_points[itCH->first], itCH->first); + } + else + { + m_convexHulls[p].AddPoint(m_facePoints[-itCH->first-1], itCH->first); + } + } + } + } + } + return true; + } + + size_t HACD::GetNTrianglesCH(size_t numCH) const + { + if (numCH >= m_nClusters) + { + return 0; + } + return m_convexHulls[numCH].GetMesh().GetNTriangles(); + } + size_t HACD::GetNPointsCH(size_t numCH) const + { + if (numCH >= m_nClusters) + { + return 0; + } + return m_convexHulls[numCH].GetMesh().GetNVertices(); + } + + bool HACD::GetCH(size_t numCH, Vec3 * const points, Vec3 * const triangles) + { + if (numCH >= m_nClusters) + { + return false; + } + m_convexHulls[numCH].GetMesh().GetIFS(points, triangles); + return true; + } + + bool HACD::Save(const char * fileName, bool uniColor, long numCluster) const + { + std::ofstream fout(fileName); + if (fout.is_open()) + { + if (m_callBack) + { + char msg[1024]; + sprintf(msg, "Saving %s\n", fileName); + (*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices()); + } + Material mat; + if (numCluster < 0) + { + for (size_t p = 0; p != m_nClusters; ++p) + { + if (!uniColor) + { + mat.m_diffuseColor.X() = mat.m_diffuseColor.Y() = mat.m_diffuseColor.Z() = 0.0; + while (mat.m_diffuseColor.X() == mat.m_diffuseColor.Y() || + mat.m_diffuseColor.Z() == mat.m_diffuseColor.Y() || + mat.m_diffuseColor.Z() == mat.m_diffuseColor.X() ) + { + mat.m_diffuseColor.X() = (rand()%100) / 100.0; + mat.m_diffuseColor.Y() = (rand()%100) / 100.0; + mat.m_diffuseColor.Z() = (rand()%100) / 100.0; + } + } + m_convexHulls[p].GetMesh().SaveVRML2(fout, mat); + } + } + else if (numCluster < static_cast(m_cVertices.size())) + { + m_convexHulls[numCluster].GetMesh().SaveVRML2(fout, mat); + } + fout.close(); + return true; + } + else + { + if (m_callBack) + { + char msg[1024]; + sprintf(msg, "Error saving %s\n", fileName); + (*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices()); + } + return false; + } + } +} diff --git a/Extras/HACD/hacdHACD.h b/Extras/HACD/hacdHACD.h new file mode 100644 index 0000000..c49e370 --- /dev/null +++ b/Extras/HACD/hacdHACD.h @@ -0,0 +1,282 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once +#ifndef HACD_HACD_H +#define HACD_HACD_H +#include "hacdVersion.h" +#include "hacdVector.h" +#include "hacdGraph.h" +#include "hacdICHull.h" +#include +#include +#include +#include + +namespace HACD +{ + const double sc_pi = 3.14159265; + class HACD; + + // just to be able to set the capcity of the container + + template, class _Pr = std::less > + class reservable_priority_queue: public std::priority_queue<_Ty, _Container, _Pr> + { + typedef typename std::priority_queue<_Ty, _Container, _Pr>::size_type size_type; + public: + reservable_priority_queue(size_type capacity = 0) { reserve(capacity); }; + void reserve(size_type capacity) { this->c.reserve(capacity); } + size_type capacity() const { return this->c.capacity(); } + }; + + //! priority queque element + class GraphEdgePriorityQueue + { + public: + //! Constructor + //! @param name edge's id + //! @param priority edge's priority + GraphEdgePriorityQueue(long name, Real priority) + { + m_name = name; + m_priority = priority; + } + //! Destructor + ~GraphEdgePriorityQueue(void){} + private: + long m_name; //!< edge name + Real m_priority; //!< priority + //! Operator < for GraphEdgePQ + friend bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs); + //! Operator > for GraphEdgePQ + friend bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs); + friend class HACD; + }; + inline bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs) + { + return lhs.m_priority(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs) + { + return lhs.m_priority>rhs.m_priority; + } + typedef bool (*CallBackFunction)(const char *, double, double, size_t); + + //! Provides an implementation of the Hierarchical Approximate Convex Decomposition (HACD) technique described in "A Simple and Efficient Approach for 3D Mesh Approximate Convex Decomposition" Game Programming Gems 8 - Chapter 2.8, p.202. A short version of the chapter was published in ICIP09 and is available at ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf + class HACD + { + public: + + //! Gives the triangles partitionas an array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle + //! @return triangles partition + const long * const GetPartition() const { return m_partition;} + //! Sets the scale factor + //! @param scale scale factor + void SetScaleFactor(double scale) { m_scale = scale;} + //! Gives the scale factor + //! @return scale factor + const double GetScaleFactor() const { return m_scale;} + //! Sets the call-back function + //! @param callBack pointer to the call-back function + void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;} + //! Gives the call-back function + //! @return pointer to the call-back function + const CallBackFunction GetCallBack() const { return m_callBack;} + + //! Specifies whether faces points should be added when computing the concavity + //! @param addFacesPoints true = faces points should be added + void SetAddFacesPoints(bool addFacesPoints) { m_addFacesPoints = addFacesPoints;} + //! Specifies wheter faces points should be added when computing the concavity + //! @return true = faces points should be added + const bool GetAddFacesPoints() const { return m_addFacesPoints;} + //! Specifies whether extra points should be added when computing the concavity + //! @param addExteraDistPoints true = extra points should be added + void SetAddExtraDistPoints(bool addExtraDistPoints) { m_addExtraDistPoints = addExtraDistPoints;} + //! Specifies wheter extra points should be added when computing the concavity + //! @return true = extra points should be added + const bool GetAddExtraDistPoints() const { return m_addExtraDistPoints;} + //! Specifies whether extra points should be added when computing the concavity + //! @param addExteraDistPoints true = extra points should be added + void SetAddNeighboursDistPoints(bool addNeighboursDistPoints) { m_addNeighboursDistPoints = addNeighboursDistPoints;} + //! Specifies wheter extra points should be added when computing the concavity + //! @return true = extra points should be added + const bool GetAddNeighboursDistPoints() const { return m_addNeighboursDistPoints;} + //! Sets the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations) + //! @param points pointer to the input points + void SetPoints(Vec3 * points) { m_points = points;} + //! Gives the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations) + //! @return pointer to the input points + const Vec3 * GetPoints() const { return m_points;} + //! Sets the triangles of the input mesh. + //! @param triangles points pointer to the input points + void SetTriangles(Vec3 * triangles) { m_triangles = triangles;} + //! Gives the triangles in the input mesh + //! @return pointer to the input triangles + const Vec3 * GetTriangles() const { return m_triangles;} + //! Sets the number of points in the input mesh. + //! @param nPoints number of points the input mesh + void SetNPoints(size_t nPoints) { m_nPoints = nPoints;} + //! Gives the number of points in the input mesh. + //! @return number of points the input mesh + const size_t GetNPoints() const { return m_nPoints;} + //! Sets the number of triangles in the input mesh. + //! @param nTriangles number of triangles in the input mesh + void SetNTriangles(size_t nTriangles) { m_nTriangles = nTriangles;} + //! Gives the number of triangles in the input mesh. + //! @return number of triangles the input mesh + const size_t GetNTriangles() const { return m_nTriangles;} + //! Sets the minimum number of clusters to be generated. + //! @param nClusters minimum number of clusters + void SetNClusters(size_t nClusters) { m_nMinClusters = nClusters;} + //! Gives the number of generated clusters. + //! @return number of generated clusters + const size_t GetNClusters() const { return m_nClusters;} + //! Sets the maximum allowed concavity. + //! @param concavity maximum concavity + void SetConcavity(double concavity) { m_concavity = concavity;} + //! Gives the maximum allowed concavity. + //! @return maximum concavity + double GetConcavity() const { return m_concavity;} + //! Sets the maximum allowed distance to get CCs connected. + //! @param concavity maximum distance to get CCs connected + void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist;} + //! Gives the maximum allowed distance to get CCs connected. + //! @return maximum distance to get CCs connected + double GetConnectDist() const { return m_ccConnectDist;} + //! Sets the volume weight. + //! @param beta volume weight + void SetVolumeWeight(double beta) { m_beta = beta;} + //! Gives the volume weight. + //! @return volume weight + double GetVolumeWeight() const { return m_beta;} + //! Sets the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf). + //! @param alpha compacity weight + void SetCompacityWeight(double alpha) { m_alpha = alpha;} + //! Gives the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf). + //! @return compacity weight + double GetCompacityWeight() const { return m_alpha;} + //! Sets the maximum number of vertices for each generated convex-hull. + //! @param nVerticesPerCH maximum # vertices per CH + void SetNVerticesPerCH(size_t nVerticesPerCH) { m_nVerticesPerCH = nVerticesPerCH;} + //! Gives the maximum number of vertices for each generated convex-hull. + //! @return maximum # vertices per CH + const size_t GetNVerticesPerCH() const { return m_nVerticesPerCH;} + //! Gives the number of vertices for the cluster number numCH. + //! @return number of vertices + size_t GetNPointsCH(size_t numCH) const; + //! Gives the number of triangles for the cluster number numCH. + //! @param numCH cluster's number + //! @return number of triangles + size_t GetNTrianglesCH(size_t numCH) const; + //! Gives the vertices and the triangles of the cluster number numCH. + //! @param numCH cluster's number + //! @param points pointer to the vector of points to be filled + //! @param triangles pointer to the vector of triangles to be filled + //! @return true if sucess + bool GetCH(size_t numCH, Vec3 * const points, Vec3 * const triangles); + //! Computes the HACD decomposition. + //! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices + //! @param exportDistPoints specifies wheter distance points should ne exported or not (used only for debugging). + //! @return true if sucess + bool Compute(bool fullCH=false, bool exportDistPoints=false); + //! Saves the generated convex-hulls in a VRML 2.0 file. + //! @param fileName the output file name + //! @param uniColor specifies whether the different convex-hulls should have the same color or not + //! @param numCluster specifies the cluster to be saved, if numCluster < 0 export all clusters + //! @return true if sucess + bool Save(const char * fileName, bool uniColor, long numCluster=-1) const; + //! Shifts and scales to the data to have all the coordinates between 0.0 and 1000.0. + void NormalizeData(); + //! Inverse the operations applied by NormalizeData(). + void DenormalizeData(); + //! Constructor. + HACD(void); + //! Destructor. + ~HACD(void); + + private: + //! Gives the edge index. + //! @param a first vertex id + //! @param b second vertex id + //! @return edge's index + static unsigned long long GetEdgeIndex(unsigned long long a, unsigned long long b) + { + if (a > b) return (a << 32) + b; + else return (b << 32) + a; + } + //! Computes the concavity of a cluster. + //! @param ch the cluster's convex-hull + //! @param distPoints the cluster's points + //! @return cluster's concavity + double Concavity(ICHull & ch, std::map & distPoints); + //! Computes the perimeter of a cluster. + //! @param triIndices the cluster's triangles + //! @param distPoints the cluster's points + //! @return cluster's perimeter + double ComputePerimeter(const std::vector & triIndices) const; + //! Creates the Graph by associating to each mesh triangle a vertex in the graph and to each couple of adjacent triangles an edge in the graph. + void CreateGraph(); + //! Initializes the graph costs and computes the vertices normals + void InitializeDualGraph(); + //! Computes the cost of an edge + //! @param e edge's id + void ComputeEdgeCost(size_t e); + //! Initializes the priority queue + //! @param fast specifies whether fast mode is used + //! @return true if success + bool InitializePriorityQueue(); + //! Cleans the intersection between convex-hulls + void CleanClusters(); + //! Computes convex-hulls from partition information + //! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices + void ComputeConvexHulls(bool fullCH); + //! Simplifies the graph + //! @param fast specifies whether fast mode is used + void Simplify(); + + private: + double m_scale; //>! scale factor used for NormalizeData() and DenormalizeData() + Vec3 * m_triangles; //>! pointer the triangles array + Vec3 * m_points; //>! pointer the points array + Vec3 * m_facePoints; //>! pointer to the faces points array + Vec3 * m_faceNormals; //>! pointer to the faces normals array + Vec3 * m_normals; //>! pointer the normals array + size_t m_nTriangles; //>! number of triangles in the original mesh + size_t m_nPoints; //>! number of vertices in the original mesh + size_t m_nClusters; //>! number of clusters + size_t m_nMinClusters; //>! minimum number of clusters + double m_ccConnectDist; //>! maximum allowed distance to connect CCs + double m_concavity; //>! maximum concavity + double m_alpha; //>! compacity weigth + double m_beta; //>! volume weigth + double m_diag; //>! length of the BB diagonal + Vec3 m_barycenter; //>! barycenter of the mesh + std::vector< long > m_cVertices; //>! array of vertices each belonging to a different cluster + ICHull * m_convexHulls; //>! convex-hulls associated with the final HACD clusters + Graph m_graph; //>! simplification graph + size_t m_nVerticesPerCH; //>! maximum number of vertices per convex-hull + reservable_priority_queue, + std::greater::value_type> > m_pqueue; //!> priority queue + HACD(const HACD & rhs); + CallBackFunction m_callBack; //>! call-back function + long * m_partition; //>! array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle + bool m_addFacesPoints; //>! specifies whether to add faces points or not + bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not + bool m_addNeighboursDistPoints; //>! specifies whether to add extra points from adjacent clusters or not + + }; +} +#endif diff --git a/Extras/HACD/hacdICHull.cpp b/Extras/HACD/hacdICHull.cpp new file mode 100644 index 0000000..42c50b7 --- /dev/null +++ b/Extras/HACD/hacdICHull.cpp @@ -0,0 +1,1010 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "hacdICHull.h" +#include +namespace HACD +{ + const long ICHull::sc_dummyIndex = std::numeric_limits::max(); + ICHull::ICHull(void) + { + m_distPoints = 0; + m_isFlat = false; + m_dummyVertex = 0; + } + bool ICHull::AddPoints(const Vec3 * points, size_t nPoints) + { + if (!points) + { + return false; + } + CircularListElement * vertex = NULL; + for (size_t i = 0; i < nPoints; i++) + { + vertex = m_mesh.AddVertex(); + vertex->GetData().m_pos.X() = points[i].X(); + vertex->GetData().m_pos.Y() = points[i].Y(); + vertex->GetData().m_pos.Z() = points[i].Z(); + vertex->GetData().m_name = static_cast(i); + } + return true; + } + bool ICHull::AddPoints(std::vector< Vec3 > points) + { + CircularListElement * vertex = NULL; + for (size_t i = 0; i < points.size(); i++) + { + vertex = m_mesh.AddVertex(); + vertex->GetData().m_pos.X() = points[i].X(); + vertex->GetData().m_pos.Y() = points[i].Y(); + vertex->GetData().m_pos.Z() = points[i].Z(); + } + return true; + } + + bool ICHull::AddPoint(const Vec3 & point, long id) + { + if (AddPoints(&point, 1)) + { + m_mesh.m_vertices.GetData().m_name = id; + return true; + } + return false; + } + + ICHullError ICHull::Process() + { + unsigned long addedPoints = 0; + if (m_mesh.GetNVertices() < 3) + { + return ICHullErrorNotEnoughPoints; + } + if (m_mesh.GetNVertices() == 3) + { + m_isFlat = true; + CircularListElement * t1 = m_mesh.AddTriangle(); + CircularListElement * t2 = m_mesh.AddTriangle(); + CircularListElement * v0 = m_mesh.m_vertices.GetHead(); + CircularListElement * v1 = v0->GetNext(); + CircularListElement * v2 = v1->GetNext(); + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1-p0) ^ (p2-p0); + m_normal.Normalize(); + t1->GetData().m_vertices[0] = v0; + t1->GetData().m_vertices[1] = v1; + t1->GetData().m_vertices[2] = v2; + t2->GetData().m_vertices[0] = v1; + t2->GetData().m_vertices[1] = v2; + t2->GetData().m_vertices[2] = v2; + return ICHullErrorOK; + } + if (m_isFlat) + { + m_mesh.m_edges.Clear(); + m_mesh.m_triangles.Clear(); + m_isFlat = false; + } + if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron + { + ICHullError res = DoubleTriangle(); + if (res != ICHullErrorOK) + { + return res; + } + else + { + addedPoints += 3; + } + } + CircularList & vertices = m_mesh.GetVertices(); + // go to the first added and not processed vertex + while (!(vertices.GetHead()->GetPrev()->GetData().m_tag)) + { + vertices.Prev(); + } + while (!vertices.GetData().m_tag) // not processed + { + vertices.GetData().m_tag = true; + if (ProcessPoint()) + { + addedPoints++; + CleanUp(addedPoints); + vertices.Next(); + if (!GetMesh().CheckConsistancy()) + { + return ICHullErrorInconsistent; + } + } + } + if (m_isFlat) + { + std::vector< CircularListElement * > trianglesToDuplicate; + size_t nT = m_mesh.GetNTriangles(); + for(size_t f = 0; f < nT; f++) + { + TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); + if( currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex ) + { + m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead()); + for(int k = 0; k < 3; k++) + { + for(int h = 0; h < 2; h++) + { + if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) + { + currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; + break; + } + } + } + } + else + { + trianglesToDuplicate.push_back(m_mesh.m_triangles.GetHead()); + } + m_mesh.m_triangles.Next(); + } + size_t nE = m_mesh.GetNEdges(); + for(size_t e = 0; e < nE; e++) + { + TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData(); + if( currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) + { + m_edgesToDelete.push_back(m_mesh.m_edges.GetHead()); + } + m_mesh.m_edges.Next(); + } + m_mesh.m_vertices.Delete(m_dummyVertex); + m_dummyVertex = 0; + size_t nV = m_mesh.GetNVertices(); + CircularList & vertices = m_mesh.GetVertices(); + for(size_t v = 0; v < nV; ++v) + { + vertices.GetData().m_tag = false; + vertices.Next(); + } + CleanEdges(); + CleanTriangles(); + CircularListElement * newTriangle; + for(size_t t = 0; t < trianglesToDuplicate.size(); t++) + { + newTriangle = m_mesh.AddTriangle(); + newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; + newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; + newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; + } + } + return ICHullErrorOK; + } + ICHullError ICHull::Process(unsigned long nPointsCH) + { + unsigned long addedPoints = 0; + if (nPointsCH < 3 || m_mesh.GetNVertices() < 3) + { + return ICHullErrorNotEnoughPoints; + } + if (m_mesh.GetNVertices() == 3) + { + m_isFlat = true; + CircularListElement * t1 = m_mesh.AddTriangle(); + CircularListElement * t2 = m_mesh.AddTriangle(); + CircularListElement * v0 = m_mesh.m_vertices.GetHead(); + CircularListElement * v1 = v0->GetNext(); + CircularListElement * v2 = v1->GetNext(); + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1-p0) ^ (p2-p0); + m_normal.Normalize(); + t1->GetData().m_vertices[0] = v0; + t1->GetData().m_vertices[1] = v1; + t1->GetData().m_vertices[2] = v2; + t2->GetData().m_vertices[0] = v1; + t2->GetData().m_vertices[1] = v0; + t2->GetData().m_vertices[2] = v2; + return ICHullErrorOK; + } + + if (m_isFlat) + { + m_mesh.m_triangles.Clear(); + m_mesh.m_edges.Clear(); + m_isFlat = false; + } + + if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron + { + ICHullError res = DoubleTriangle(); + if (res != ICHullErrorOK) + { + return res; + } + else + { + addedPoints += 3; + } + } + CircularList & vertices = m_mesh.GetVertices(); + while (!vertices.GetData().m_tag && addedPoints < nPointsCH) // not processed + { + if (!FindMaxVolumePoint()) + { + break; + } + vertices.GetData().m_tag = true; + if (ProcessPoint()) + { + addedPoints++; + CleanUp(addedPoints); + if (!GetMesh().CheckConsistancy()) + { + return ICHullErrorInconsistent; + } + vertices.Next(); + } + } + // delete remaining points + while (!vertices.GetData().m_tag) + { + vertices.Delete(); + } + if (m_isFlat) + { + std::vector< CircularListElement * > trianglesToDuplicate; + size_t nT = m_mesh.GetNTriangles(); + for(size_t f = 0; f < nT; f++) + { + TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); + if( currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex ) + { + m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead()); + for(int k = 0; k < 3; k++) + { + for(int h = 0; h < 2; h++) + { + if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) + { + currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; + break; + } + } + } + } + else + { + trianglesToDuplicate.push_back(m_mesh.m_triangles.GetHead()); + } + m_mesh.m_triangles.Next(); + } + size_t nE = m_mesh.GetNEdges(); + for(size_t e = 0; e < nE; e++) + { + TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData(); + if( currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) + { + m_edgesToDelete.push_back(m_mesh.m_edges.GetHead()); + } + m_mesh.m_edges.Next(); + } + m_mesh.m_vertices.Delete(m_dummyVertex); + m_dummyVertex = 0; + size_t nV = m_mesh.GetNVertices(); + CircularList & vertices = m_mesh.GetVertices(); + for(size_t v = 0; v < nV; ++v) + { + vertices.GetData().m_tag = false; + vertices.Next(); + } + CleanEdges(); + CleanTriangles(); + CircularListElement * newTriangle; + for(size_t t = 0; t < trianglesToDuplicate.size(); t++) + { + newTriangle = m_mesh.AddTriangle(); + newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; + newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; + newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; + } + } + return ICHullErrorOK; + } + bool ICHull::FindMaxVolumePoint() + { + CircularList & vertices = m_mesh.GetVertices(); + CircularListElement * vMaxVolume = 0; + CircularListElement * vHeadPrev = vertices.GetHead()->GetPrev(); + + double maxVolume = 0.0; + double volume = 0.0; + + while (!vertices.GetData().m_tag) // not processed + { + if (ComputePointVolume(volume, false)) + { + if ( maxVolume < volume) + { + maxVolume = volume; + vMaxVolume = vertices.GetHead(); + } + vertices.Next(); + } + } + CircularListElement * vHead = vHeadPrev->GetNext(); + vertices.GetHead() = vHead; + + if (!vMaxVolume) + { + return false; + } + + if (vMaxVolume != vHead) + { + Vec3 pos = vHead->GetData().m_pos; + long id = vHead->GetData().m_name; + vHead->GetData().m_pos = vMaxVolume->GetData().m_pos; + vHead->GetData().m_name = vMaxVolume->GetData().m_name; + vMaxVolume->GetData().m_pos = pos; + vHead->GetData().m_name = id; + } + + + return true; + } + ICHullError ICHull::DoubleTriangle() + { + // find three non colinear points + m_isFlat = false; + CircularList & vertices = m_mesh.GetVertices(); + CircularListElement * v0 = vertices.GetHead(); + while( Colinear(v0->GetData().m_pos, + v0->GetNext()->GetData().m_pos, + v0->GetNext()->GetNext()->GetData().m_pos)) + { + if ( (v0 = v0->GetNext()) == vertices.GetHead()) + { + return ICHullErrorCoplanarPoints; + } + } + CircularListElement * v1 = v0->GetNext(); + CircularListElement * v2 = v1->GetNext(); + // mark points as processed + v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true; + + // create two triangles + CircularListElement * f0 = MakeFace(v0, v1, v2, 0); + MakeFace(v2, v1, v0, f0); + + // find a fourth non-coplanar point to form tetrahedron + CircularListElement * v3 = v2->GetNext(); + vertices.GetHead() = v3; + + double vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + while (vol == 0.0 && !v3->GetNext()->GetData().m_tag) + { + v3 = v3->GetNext(); + vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + } + if (vol == 0.0) + { + // compute the barycenter + Vec3 bary(0.0,0.0,0.0); + CircularListElement * vBary = v0; + do + { + bary += vBary->GetData().m_pos; + } + while ( (vBary = vBary->GetNext()) != v0); + bary /= static_cast(vertices.GetSize()); + + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1-p0) ^ (p2-p0); + m_normal.Normalize(); + // add dummy vertex placed at (bary + normal) + vertices.GetHead() = v2; + Vec3 newPt = bary + m_normal; + AddPoint(newPt, sc_dummyIndex); + m_dummyVertex = vertices.GetHead(); + m_isFlat = true; + v3 = v2->GetNext(); + vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + return ICHullErrorOK; + } + else if (v3 != vertices.GetHead()) + { + TMMVertex temp; + temp.m_name = v3->GetData().m_name; + temp.m_pos = v3->GetData().m_pos; + v3->GetData().m_name = vertices.GetHead()->GetData().m_name; + v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos; + vertices.GetHead()->GetData().m_name = temp.m_name; + vertices.GetHead()->GetData().m_pos = temp.m_pos; + } + return ICHullErrorOK; + } + CircularListElement * ICHull::MakeFace(CircularListElement * v0, + CircularListElement * v1, + CircularListElement * v2, + CircularListElement * fold) + { + CircularListElement * e0; + CircularListElement * e1; + CircularListElement * e2; + long index = 0; + if (!fold) // if first face to be created + { + e0 = m_mesh.AddEdge(); // create the three edges + e1 = m_mesh.AddEdge(); + e2 = m_mesh.AddEdge(); + } + else // otherwise re-use existing edges (in reverse order) + { + e0 = fold->GetData().m_edges[2]; + e1 = fold->GetData().m_edges[1]; + e2 = fold->GetData().m_edges[0]; + index = 1; + } + e0->GetData().m_vertices[0] = v0; e0->GetData().m_vertices[1] = v1; + e1->GetData().m_vertices[0] = v1; e1->GetData().m_vertices[1] = v2; + e2->GetData().m_vertices[0] = v2; e2->GetData().m_vertices[1] = v0; + // create the new face + CircularListElement * f = m_mesh.AddTriangle(); + f->GetData().m_edges[0] = e0; f->GetData().m_edges[1] = e1; f->GetData().m_edges[2] = e2; + f->GetData().m_vertices[0] = v0; f->GetData().m_vertices[1] = v1; f->GetData().m_vertices[2] = v2; + // link edges to face f + e0->GetData().m_triangles[index] = e1->GetData().m_triangles[index] = e2->GetData().m_triangles[index] = f; + return f; + } + CircularListElement * ICHull::MakeConeFace(CircularListElement * e, CircularListElement * p) + { + // create two new edges if they don't already exist + CircularListElement * newEdges[2]; + for(int i = 0; i < 2; ++i) + { + if ( !( newEdges[i] = e->GetData().m_vertices[i]->GetData().m_duplicate ) ) + { // if the edge doesn't exits add it and mark the vertex as duplicated + newEdges[i] = m_mesh.AddEdge(); + newEdges[i]->GetData().m_vertices[0] = e->GetData().m_vertices[i]; + newEdges[i]->GetData().m_vertices[1] = p; + e->GetData().m_vertices[i]->GetData().m_duplicate = newEdges[i]; + } + } + // make the new face + CircularListElement * newFace = m_mesh.AddTriangle(); + newFace->GetData().m_edges[0] = e; + newFace->GetData().m_edges[1] = newEdges[0]; + newFace->GetData().m_edges[2] = newEdges[1]; + MakeCCW(newFace, e, p); + for(int i=0; i < 2; ++i) + { + for(int j=0; j < 2; ++j) + { + if ( ! newEdges[i]->GetData().m_triangles[j] ) + { + newEdges[i]->GetData().m_triangles[j] = newFace; + break; + } + } + } + return newFace; + } + bool ICHull::ComputePointVolume(double &totalVolume, bool markVisibleFaces) + { + // mark visible faces + CircularListElement * fHead = m_mesh.GetTriangles().GetHead(); + CircularListElement * f = fHead; + CircularList & vertices = m_mesh.GetVertices(); + CircularListElement * vertex0 = vertices.GetHead(); + bool visible = false; + Vec3 pos0 = Vec3(vertex0->GetData().m_pos.X(), + vertex0->GetData().m_pos.Y(), + vertex0->GetData().m_pos.Z()); + double vol = 0.0; + totalVolume = 0.0; + Vec3 ver0, ver1, ver2; + do + { + ver0.X() = f->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = f->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = f->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = f->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = f->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = f->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = f->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z(); + vol = Volume(ver0, ver1, ver2, pos0); + if ( vol < 0.0 ) + { + vol = fabs(vol); + totalVolume += vol; + if (markVisibleFaces) + { + f->GetData().m_visible = true; + m_trianglesToDelete.push_back(f); + } + visible = true; + } + f = f->GetNext(); + } + while (f != fHead); + + if (m_trianglesToDelete.size() == m_mesh.m_triangles.GetSize()) + { + for(size_t i = 0; i < m_trianglesToDelete.size(); i++) + { + m_trianglesToDelete[i]->GetData().m_visible = false; + } + visible = false; + } + // if no faces visible from p then p is inside the hull + if (!visible && markVisibleFaces) + { + vertices.Delete(); + m_trianglesToDelete.clear(); + return false; + } + return true; + } + bool ICHull::ProcessPoint() + { + double totalVolume = 0.0; + if (!ComputePointVolume(totalVolume, true)) + { + return false; + } + // Mark edges in interior of visible region for deletion. + // Create a new face based on each border edge + CircularListElement * v0 = m_mesh.GetVertices().GetHead(); + CircularListElement * eHead = m_mesh.GetEdges().GetHead(); + CircularListElement * e = eHead; + CircularListElement * tmp = 0; + long nvisible = 0; + m_edgesToDelete.clear(); + m_edgesToUpdate.clear(); + do + { + tmp = e->GetNext(); + nvisible = 0; + for(int k = 0; k < 2; k++) + { + if ( e->GetData().m_triangles[k]->GetData().m_visible ) + { + nvisible++; + } + } + if ( nvisible == 2) + { + m_edgesToDelete.push_back(e); + } + else if ( nvisible == 1) + { + e->GetData().m_newFace = MakeConeFace(e, v0); + m_edgesToUpdate.push_back(e); + } + e = tmp; + } + while (e != eHead); + return true; + } + bool ICHull::MakeCCW(CircularListElement * f, + CircularListElement * e, + CircularListElement * v) + { + // the visible face adjacent to e + CircularListElement * fv; + if (e->GetData().m_triangles[0]->GetData().m_visible) + { + fv = e->GetData().m_triangles[0]; + } + else + { + fv = e->GetData().m_triangles[1]; + } + + // set vertex[0] and vertex[1] to have the same orientation as the corresponding vertices of fv. + long i; // index of e->m_vertices[0] in fv + CircularListElement * v0 = e->GetData().m_vertices[0]; + CircularListElement * v1 = e->GetData().m_vertices[1]; + for(i = 0; fv->GetData().m_vertices[i] != v0; i++); + + if ( fv->GetData().m_vertices[(i+1) % 3] != e->GetData().m_vertices[1] ) + { + f->GetData().m_vertices[0] = v1; + f->GetData().m_vertices[1] = v0; + } + else + { + f->GetData().m_vertices[0] = v0; + f->GetData().m_vertices[1] = v1; + // swap edges + CircularListElement * tmp = f->GetData().m_edges[0]; + f->GetData().m_edges[0] = f->GetData().m_edges[1]; + f->GetData().m_edges[1] = tmp; + } + f->GetData().m_vertices[2] = v; + return true; + } + bool ICHull::CleanUp(unsigned long & addedPoints) + { + bool r0 = CleanEdges(); + bool r1 = CleanTriangles(); + bool r2 = CleanVertices(addedPoints); + return r0 && r1 && r2; + } + bool ICHull::CleanEdges() + { + // integrate the new faces into the data structure + CircularListElement * e; + const std::vector *>::iterator itEndUpdate = m_edgesToUpdate.end(); + for(std::vector *>::iterator it = m_edgesToUpdate.begin(); it != itEndUpdate; ++it) + { + e = *it; + if ( e->GetData().m_newFace ) + { + if ( e->GetData().m_triangles[0]->GetData().m_visible) + { + e->GetData().m_triangles[0] = e->GetData().m_newFace; + } + else + { + e->GetData().m_triangles[1] = e->GetData().m_newFace; + } + e->GetData().m_newFace = 0; + } + } + // delete edges maked for deletion + CircularList & edges = m_mesh.GetEdges(); + const std::vector *>::iterator itEndDelete = m_edgesToDelete.end(); + for(std::vector *>::iterator it = m_edgesToDelete.begin(); it != itEndDelete; ++it) + { + edges.Delete(*it); + } + m_edgesToDelete.clear(); + m_edgesToUpdate.clear(); + return true; + } + bool ICHull::CleanTriangles() + { + CircularList & triangles = m_mesh.GetTriangles(); + const std::vector *>::iterator itEndDelete = m_trianglesToDelete.end(); + for(std::vector *>::iterator it = m_trianglesToDelete.begin(); it != itEndDelete; ++it) + { + if (m_distPoints) + { + if (m_isFlat) + { + // to be updated + } + else + { + std::set::const_iterator itPEnd((*it)->GetData().m_incidentPoints.end()); + std::set::const_iterator itP((*it)->GetData().m_incidentPoints.begin()); + std::map::iterator itPoint; + for(; itP != itPEnd; ++itP) + { + itPoint = m_distPoints->find(*itP); + if (itPoint != m_distPoints->end()) + { + itPoint->second.m_computed = false; + } + } + } + } + triangles.Delete(*it); + } + m_trianglesToDelete.clear(); + return true; + } + bool ICHull::CleanVertices(unsigned long & addedPoints) + { + // mark all vertices incident to some undeleted edge as on the hull + CircularList & edges = m_mesh.GetEdges(); + CircularListElement * e = edges.GetHead(); + size_t nE = edges.GetSize(); + for(size_t i = 0; i < nE; i++) + { + e->GetData().m_vertices[0]->GetData().m_onHull = true; + e->GetData().m_vertices[1]->GetData().m_onHull = true; + e = e->GetNext(); + } + // delete all the vertices that have been processed but are not on the hull + CircularList & vertices = m_mesh.GetVertices(); + CircularListElement * vHead = vertices.GetHead(); + CircularListElement * v = vHead; + v = v->GetPrev(); + do + { + if (v->GetData().m_tag && !v->GetData().m_onHull) + { + CircularListElement * tmp = v->GetPrev(); + vertices.Delete(v); + v = tmp; + addedPoints--; + } + else + { + v->GetData().m_duplicate = 0; + v->GetData().m_onHull = false; + v = v->GetPrev(); + } + } + while (v->GetData().m_tag && v != vHead); + return true; + } + void ICHull::Clear() + { + m_mesh.Clear(); + m_edgesToDelete = std::vector *>(); + m_edgesToUpdate = std::vector *>(); + m_trianglesToDelete= std::vector *>(); + m_isFlat = false; + } + const ICHull & ICHull::operator=(ICHull & rhs) + { + if (&rhs != this) + { + m_mesh.Copy(rhs.m_mesh); + m_edgesToDelete = rhs.m_edgesToDelete; + m_edgesToUpdate = rhs.m_edgesToUpdate; + m_trianglesToDelete = rhs.m_trianglesToDelete; + m_isFlat = rhs.m_isFlat; + } + return (*this); + } + double ICHull::ComputeVolume() + { + size_t nV = m_mesh.m_vertices.GetSize(); + if (nV == 0 || m_isFlat) + { + return 0.0; + } + Vec3 bary(0.0, 0.0, 0.0); + for(size_t v = 0; v < nV; v++) + { + bary.X() += m_mesh.m_vertices.GetHead()->GetData().m_pos.X(); + bary.Y() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Y(); + bary.Z() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Z(); + m_mesh.m_vertices.Next(); + } + bary /= static_cast(nV); + + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2; + double totalVolume = 0.0; + for(size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + totalVolume += Volume(ver0, ver1, ver2, bary); + m_mesh.m_triangles.Next(); + } + return totalVolume; + } + bool ICHull::IsInside(const Vec3 & pt0) + { + const Vec3 pt(pt0.X(), pt0.Y(), pt0.Z()); + if (m_isFlat) + { + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2, a, b, c; + double u,v; + for(size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + a = ver1 - ver0; + b = ver2 - ver0; + c = pt - ver0; + u = c * a; + v = c * b; + if ( u >= 0.0 && u <= 1.0 && v >= 0.0 && u+v <= 1.0) + { + return true; + } + m_mesh.m_triangles.Next(); + } + return false; + } + else + { + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2; + for(size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + if (Volume(ver0, ver1, ver2, pt) < 0.0) + { + return false; + } + m_mesh.m_triangles.Next(); + } + return true; + } + } + double ICHull::ComputeDistance(long name, const Vec3 & pt, const Vec3 & normal, bool & insideHull, bool updateIncidentPoints) + { + Vec3 ptNormal(static_cast(normal.X()), + static_cast(normal.Y()), + static_cast(normal.Z())); + Vec3 p0( static_cast(pt.X()), + static_cast(pt.Y()), + static_cast(pt.Z())); + + if (m_isFlat) + { + double distance = 0.0; + Vec3 chNormal(static_cast(m_normal.X()), + static_cast(m_normal.Y()), + static_cast(m_normal.Z())); + ptNormal -= (ptNormal * chNormal) * chNormal; + if (ptNormal.GetNorm() > 0.0) + { + ptNormal.Normalize(); + long nameVE1; + long nameVE2; + Vec3 pa, pb, d0, d1, d2, d3; + Vec3 p1 = p0 + ptNormal; + Vec3 p2, p3; + double mua, mub, s; + const double EPS = 0.00000000001; + size_t nE = m_mesh.GetNEdges(); + for(size_t e = 0; e < nE; e++) + { + TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData(); + nameVE1 = currentEdge.m_vertices[0]->GetData().m_name; + nameVE2 = currentEdge.m_vertices[1]->GetData().m_name; + if (currentEdge.m_triangles[0] == 0 || currentEdge.m_triangles[1] == 0) + { + if ( nameVE1==name || nameVE2==name ) + { + return 0.0; + } + /* + if (debug) std::cout << "V" << name + << " E " << nameVE1 << " " << nameVE2 << std::endl; + */ + + p2.X() = currentEdge.m_vertices[0]->GetData().m_pos.X(); + p2.Y() = currentEdge.m_vertices[0]->GetData().m_pos.Y(); + p2.Z() = currentEdge.m_vertices[0]->GetData().m_pos.Z(); + p3.X() = currentEdge.m_vertices[1]->GetData().m_pos.X(); + p3.Y() = currentEdge.m_vertices[1]->GetData().m_pos.Y(); + p3.Z() = currentEdge.m_vertices[1]->GetData().m_pos.Z(); + d0 = p3 - p2; + if (d0.GetNorm() > 0.0) + { + if (IntersectLineLine(p0, p1, p2, p3, pa, pb, mua, mub)) + { + d1 = pa - p2; + d2 = pa - pb; + d3 = pa - p0; + mua = d1.GetNorm()/d0.GetNorm(); + mub = d1*d0; + s = d3*ptNormal; + if (d2.GetNorm() < EPS && mua <= 1.0 && mub>=0.0 && s>0.0) + { + distance = std::max(distance, d3.GetNorm()); + } + } + } + } + m_mesh.m_edges.Next(); + } + } + return distance; + } + else + { + Vec3 ptNormal(static_cast(normal.X()), + static_cast(normal.Y()), + static_cast(normal.Z())); + + Vec3 impact; + long nhit; + double dist; + double distance = 0.0; + size_t nT = m_mesh.GetNTriangles(); + insideHull = false; + CircularListElement * face = 0; + Vec3 ver0, ver1, ver2; + for(size_t f = 0; f < nT; f++) + { + TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); + /* + if (debug) std::cout << "T " << currentTriangle.m_vertices[0]->GetData().m_name << " " + << currentTriangle.m_vertices[1]->GetData().m_name << " " + << currentTriangle.m_vertices[2]->GetData().m_name << std::endl; + */ + if (currentTriangle.m_vertices[0]->GetData().m_name == name || + currentTriangle.m_vertices[1]->GetData().m_name == name || + currentTriangle.m_vertices[2]->GetData().m_name == name) + { + nhit = 1; + dist = 0.0; + } + else + { + ver0.X() = currentTriangle.m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = currentTriangle.m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = currentTriangle.m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = currentTriangle.m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = currentTriangle.m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = currentTriangle.m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = currentTriangle.m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = currentTriangle.m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = currentTriangle.m_vertices[2]->GetData().m_pos.Z(); + nhit = IntersectRayTriangle(p0, ptNormal, ver0, ver1, ver2, dist); + } + + if (nhit == 1 && distance <= dist) + { + distance = dist; + insideHull = true; + face = m_mesh.m_triangles.GetHead(); +/* + std::cout << name << " -> T " << currentTriangle.m_vertices[0]->GetData().m_name << " " + << currentTriangle.m_vertices[1]->GetData().m_name << " " + << currentTriangle.m_vertices[2]->GetData().m_name << " Dist " + << dist << " P " << currentTriangle.m_normal * normal << std::endl; +*/ + if (dist > 0.1) + { + break; + } + } + m_mesh.m_triangles.Next(); + } + if (updateIncidentPoints && face && m_distPoints) + { + (*m_distPoints)[name].m_dist = static_cast(distance); + face->GetData().m_incidentPoints.insert(name); + } + return distance; + } + } +} + diff --git a/Extras/HACD/hacdICHull.h b/Extras/HACD/hacdICHull.h new file mode 100644 index 0000000..fbe4ef6 --- /dev/null +++ b/Extras/HACD/hacdICHull.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once +#ifndef HACD_ICHULL_H +#define HACD_ICHULL_H +#include "hacdVersion.h" +#include "hacdManifoldMesh.h" +#include "hacdVector.h" +#include +#include +namespace HACD +{ + class DPoint; + class HACD; + //! Incremental Convex Hull algorithm (cf. http://maven.smith.edu/~orourke/books/ftp.html ). + enum ICHullError + { + ICHullErrorOK = 0, + ICHullErrorCoplanarPoints, + ICHullErrorNoVolume, + ICHullErrorInconsistent, + ICHullErrorNotEnoughPoints + }; + class ICHull + { + public: + //! + bool IsFlat() { return m_isFlat;} + //! + std::map * GetDistPoints() const { return m_distPoints;} + //! + void SetDistPoints(std::map * distPoints) { m_distPoints = distPoints;} + //! Returns the computed mesh + TMMesh & GetMesh() { return m_mesh;} + //! Add one point to the convex-hull + bool AddPoint(const Vec3 & point) {return AddPoints(&point, 1);} + //! Add one point to the convex-hull + bool AddPoint(const Vec3 & point, long id); + //! Add points to the convex-hull + bool AddPoints(const Vec3 * points, size_t nPoints); + bool AddPoints(std::vector< Vec3 > points); + //! + ICHullError Process(); + //! + ICHullError Process(unsigned long nPointsCH); + //! + double ComputeVolume(); + //! + bool IsInside(const Vec3 & pt0); + //! + double ComputeDistance(long name, const Vec3 & pt, const Vec3 & normal, bool & insideHull, bool updateIncidentPoints); + //! + const ICHull & operator=(ICHull & rhs); + + //! Constructor + ICHull(void); + //! Destructor + virtual ~ICHull(void) {}; + + private: + //! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up. + ICHullError DoubleTriangle(); + //! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face. + CircularListElement * MakeFace(CircularListElement * v0, + CircularListElement * v1, + CircularListElement * v2, + CircularListElement * fold); + //! + CircularListElement * MakeConeFace(CircularListElement * e, CircularListElement * v); + //! + bool ProcessPoint(); + //! + bool ComputePointVolume(double &totalVolume, bool markVisibleFaces); + //! + bool FindMaxVolumePoint(); + //! + bool CleanEdges(); + //! + bool CleanVertices(unsigned long & addedPoints); + //! + bool CleanTriangles(); + //! + bool CleanUp(unsigned long & addedPoints); + //! + bool MakeCCW(CircularListElement * f, + CircularListElement * e, + CircularListElement * v); + void Clear(); + private: + static const long sc_dummyIndex; + static const double sc_distMin; + TMMesh m_mesh; + std::vector *> m_edgesToDelete; + std::vector *> m_edgesToUpdate; + std::vector *> m_trianglesToDelete; + std::map * m_distPoints; + CircularListElement * m_dummyVertex; + Vec3 m_normal; + bool m_isFlat; + + + ICHull(const ICHull & rhs); + + friend class HACD; + }; + +} +#endif diff --git a/Extras/HACD/hacdManifoldMesh.cpp b/Extras/HACD/hacdManifoldMesh.cpp new file mode 100644 index 0000000..399fda0 --- /dev/null +++ b/Extras/HACD/hacdManifoldMesh.cpp @@ -0,0 +1,577 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "hacdManifoldMesh.h" +using namespace std; + + +namespace HACD +{ + Material::Material(void) + { + m_diffuseColor.X() = 0.5; + m_diffuseColor.Y() = 0.5; + m_diffuseColor.Z() = 0.5; + m_specularColor.X() = 0.5; + m_specularColor.Y() = 0.5; + m_specularColor.Z() = 0.5; + m_ambientIntensity = 0.4; + m_emissiveColor.X() = 0.0; + m_emissiveColor.Y() = 0.0; + m_emissiveColor.Z() = 0.0; + m_shininess = 0.4; + m_transparency = 0.0; + } + + TMMVertex::TMMVertex(void) + { + m_name = 0; + m_id = 0; + m_duplicate = 0; + m_onHull = false; + m_tag = false; + } + TMMVertex::~TMMVertex(void) + { + } + TMMEdge::TMMEdge(void) + { + m_id = 0; + m_triangles[0] = m_triangles[1] = m_newFace = 0; + m_vertices[0] = m_vertices[1] = 0; + } + TMMEdge::~TMMEdge(void) + { + } + TMMTriangle::TMMTriangle(void) + { + m_id = 0; + for(int i = 0; i < 3; i++) + { + m_edges[i] = 0; + m_vertices[0] = 0; + } + m_visible = false; + } + TMMTriangle::~TMMTriangle(void) + { + } + TMMesh::TMMesh(void) + { + m_barycenter = Vec3(0,0,0); + m_diag = 1; + } + TMMesh::~TMMesh(void) + { + } + + void TMMesh::Print() + { + size_t nV = m_vertices.GetSize(); + std::cout << "-----------------------------" << std::endl; + std::cout << "vertices (" << nV << ")" << std::endl; + for(size_t v = 0; v < nV; v++) + { + const TMMVertex & currentVertex = m_vertices.GetData(); + std::cout << currentVertex.m_id << ", " + << currentVertex.m_pos.X() << ", " + << currentVertex.m_pos.Y() << ", " + << currentVertex.m_pos.Z() << std::endl; + m_vertices.Next(); + } + + + size_t nE = m_edges.GetSize(); + std::cout << "edges (" << nE << ")" << std::endl; + for(size_t e = 0; e < nE; e++) + { + const TMMEdge & currentEdge = m_edges.GetData(); + const CircularListElement * v0 = currentEdge.m_vertices[0]; + const CircularListElement * v1 = currentEdge.m_vertices[1]; + const CircularListElement * f0 = currentEdge.m_triangles[0]; + const CircularListElement * f1 = currentEdge.m_triangles[1]; + + std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ")" << std::endl; + std::cout << "-> F0 (" << f0->GetData().m_vertices[0]->GetData().m_name << ", " + << f0->GetData().m_vertices[1]->GetData().m_name << ", " + << f0->GetData().m_vertices[2]->GetData().m_name <<")" << std::endl; + std::cout << "-> F1 (" << f1->GetData().m_vertices[0]->GetData().m_name << ", " + << f1->GetData().m_vertices[1]->GetData().m_name << ", " + << f1->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl; + m_edges.Next(); + } + size_t nT = m_triangles.GetSize(); + std::cout << "triangles (" << nT << ")" << std::endl; + for(size_t t = 0; t < nT; t++) + { + const TMMTriangle & currentTriangle = m_triangles.GetData(); + const CircularListElement * v0 = currentTriangle.m_vertices[0]; + const CircularListElement * v1 = currentTriangle.m_vertices[1]; + const CircularListElement * v2 = currentTriangle.m_vertices[2]; + const CircularListElement * e0 = currentTriangle.m_edges[0]; + const CircularListElement * e1 = currentTriangle.m_edges[1]; + const CircularListElement * e2 = currentTriangle.m_edges[2]; + + std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ", "<< v2->GetData().m_name << ")" << std::endl; + + std::cout << "-> E0 (" << e0->GetData().m_vertices[0]->GetData().m_name << ", " + << e0->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; + std::cout << "-> E1 (" << e1->GetData().m_vertices[0]->GetData().m_name << ", " + << e1->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; + std::cout << "-> E2 (" << e2->GetData().m_vertices[0]->GetData().m_name << ", " + << e2->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; + m_triangles.Next(); + } + } + bool TMMesh::Save(const char *fileName) + { + std::ofstream fout(fileName); + std::cout << "Saving " << fileName << std::endl; + if (SaveVRML2(fout)) + { + fout.close(); + return true; + } + return false; + } + bool TMMesh::SaveVRML2(std::ofstream &fout) + { + return SaveVRML2(fout, Material()); + } + bool TMMesh::SaveVRML2(std::ofstream &fout, const Material & material) + { + if (fout.is_open()) + { + size_t nV = m_vertices.GetSize(); + size_t nT = m_triangles.GetSize(); + fout <<"#VRML V2.0 utf8" << std::endl; + fout <<"" << std::endl; + fout <<"# Vertices: " << nV << std::endl; + fout <<"# Triangles: " << nT << std::endl; + fout <<"" << std::endl; + fout <<"Group {" << std::endl; + fout <<" children [" << std::endl; + fout <<" Shape {" << std::endl; + fout <<" appearance Appearance {" << std::endl; + fout <<" material Material {" << std::endl; + fout <<" diffuseColor " << material.m_diffuseColor.X() << " " + << material.m_diffuseColor.Y() << " " + << material.m_diffuseColor.Z() << std::endl; + fout <<" ambientIntensity " << material.m_ambientIntensity << std::endl; + fout <<" specularColor " << material.m_specularColor.X() << " " + << material.m_specularColor.Y() << " " + << material.m_specularColor.Z() << std::endl; + fout <<" emissiveColor " << material.m_emissiveColor.X() << " " + << material.m_emissiveColor.Y() << " " + << material.m_emissiveColor.Z() << std::endl; + fout <<" shininess " << material.m_shininess << std::endl; + fout <<" transparency " << material.m_transparency << std::endl; + fout <<" }" << std::endl; + fout <<" }" << std::endl; + fout <<" geometry IndexedFaceSet {" << std::endl; + fout <<" ccw TRUE" << std::endl; + fout <<" solid TRUE" << std::endl; + fout <<" convex TRUE" << std::endl; + if (GetNVertices() > 0) { + fout <<" coord DEF co Coordinate {" << std::endl; + fout <<" point [" << std::endl; + for(size_t v = 0; v < nV; v++) + { + TMMVertex & currentVertex = m_vertices.GetData(); + fout <<" " << currentVertex.m_pos.X() << " " + << currentVertex.m_pos.Y() << " " + << currentVertex.m_pos.Z() << "," << std::endl; + currentVertex.m_id = v; + m_vertices.Next(); + } + fout <<" ]" << std::endl; + fout <<" }" << std::endl; + } + if (GetNTriangles() > 0) { + fout <<" coordIndex [ " << std::endl; + for(size_t f = 0; f < nT; f++) + { + TMMTriangle & currentTriangle = m_triangles.GetData(); + fout <<" " << currentTriangle.m_vertices[0]->GetData().m_id << ", " + << currentTriangle.m_vertices[1]->GetData().m_id << ", " + << currentTriangle.m_vertices[2]->GetData().m_id << ", -1," << std::endl; + m_triangles.Next(); + } + fout <<" ]" << std::endl; + } + fout <<" }" << std::endl; + fout <<" }" << std::endl; + fout <<" ]" << std::endl; + fout <<"}" << std::endl; + } + return true; + } + void TMMesh::GetIFS(Vec3 * const points, Vec3 * const triangles) + { + size_t nV = m_vertices.GetSize(); + size_t nT = m_triangles.GetSize(); + + for(size_t v = 0; v < nV; v++) + { + points[v] = m_vertices.GetData().m_pos; + m_vertices.GetData().m_id = v; + m_vertices.Next(); + } + for(size_t f = 0; f < nT; f++) + { + TMMTriangle & currentTriangle = m_triangles.GetData(); + triangles[f].X() = static_cast(currentTriangle.m_vertices[0]->GetData().m_id); + triangles[f].Y() = static_cast(currentTriangle.m_vertices[1]->GetData().m_id); + triangles[f].Z() = static_cast(currentTriangle.m_vertices[2]->GetData().m_id); + m_triangles.Next(); + } + } + void TMMesh::Clear() + { + m_vertices.Clear(); + m_edges.Clear(); + m_triangles.Clear(); + } + void TMMesh::Copy(TMMesh & mesh) + { + Clear(); + // updating the id's + size_t nV = mesh.m_vertices.GetSize(); + size_t nE = mesh. m_edges.GetSize(); + size_t nT = mesh.m_triangles.GetSize(); + for(size_t v = 0; v < nV; v++) + { + mesh.m_vertices.GetData().m_id = v; + mesh.m_vertices.Next(); + } + for(size_t e = 0; e < nE; e++) + { + mesh.m_edges.GetData().m_id = e; + mesh.m_edges.Next(); + + } + for(size_t f = 0; f < nT; f++) + { + mesh.m_triangles.GetData().m_id = f; + mesh.m_triangles.Next(); + } + // copying data + m_vertices = mesh.m_vertices; + m_edges = mesh.m_edges; + m_triangles = mesh.m_triangles; + + // generating mapping + CircularListElement ** vertexMap = new CircularListElement * [nV]; + CircularListElement ** edgeMap = new CircularListElement * [nE]; + CircularListElement ** triangleMap = new CircularListElement * [nT]; + for(size_t v = 0; v < nV; v++) + { + vertexMap[v] = m_vertices.GetHead(); + m_vertices.Next(); + } + for(size_t e = 0; e < nE; e++) + { + edgeMap[e] = m_edges.GetHead(); + m_edges.Next(); + } + for(size_t f = 0; f < nT; f++) + { + triangleMap[f] = m_triangles.GetHead(); + m_triangles.Next(); + } + + // updating pointers + for(size_t v = 0; v < nV; v++) + { + if (vertexMap[v]->GetData().m_duplicate) + { + vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id]; + } + } + for(size_t e = 0; e < nE; e++) + { + if (edgeMap[e]->GetData().m_newFace) + { + edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id]; + } + if (nT > 0) + { + for(int f = 0; f < 2; f++) + { + if (edgeMap[e]->GetData().m_triangles[f]) + { + edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id]; + } + } + } + for(int v = 0; v < 2; v++) + { + if (edgeMap[e]->GetData().m_vertices[v]) + { + edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id]; + } + } + } + for(size_t f = 0; f < nT; f++) + { + if (nE > 0) + { + for(int e = 0; e < 3; e++) + { + if (triangleMap[f]->GetData().m_edges[e]) + { + triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id]; + } + } + } + for(int v = 0; v < 3; v++) + { + if (triangleMap[f]->GetData().m_vertices[v]) + { + triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id]; + } + } + } + delete [] vertexMap; + delete [] edgeMap; + delete [] triangleMap; + + } + long IntersectRayTriangle(const Vec3 & P0, const Vec3 & dir, + const Vec3 & V0, const Vec3 & V1, + const Vec3 & V2, double &t) + { + Vec3 edge1, edge2, edge3; + double det, invDet; + edge1 = V1 - V2; + edge2 = V2 - V0; + Vec3 pvec = dir ^ edge2; + det = edge1 * pvec; + if (det == 0.0) + return 0; + invDet = 1.0/det; + Vec3 tvec = P0 - V0; + Vec3 qvec = tvec ^ edge1; + t = (edge2 * qvec) * invDet; + if (t < 0.0) + { + return 0; + } + edge3 = V0 - V1; + Vec3 I(P0 + t * dir); + Vec3 s0 = (I-V0) ^ edge3; + Vec3 s1 = (I-V1) ^ edge1; + Vec3 s2 = (I-V2) ^ edge2; + if (s0*s1 > -1e-9 && s2*s1 > -1e-9) + { + return 1; + } + return 0; + } + + bool IntersectLineLine(const Vec3 & p1, const Vec3 & p2, + const Vec3 & p3, const Vec3 & p4, + Vec3 & pa, Vec3 & pb, + double & mua, double & mub) + { + Vec3 p13,p43,p21; + double d1343,d4321,d1321,d4343,d2121; + double numer,denom; + + p13.X() = p1.X() - p3.X(); + p13.Y() = p1.Y() - p3.Y(); + p13.Z() = p1.Z() - p3.Z(); + p43.X() = p4.X() - p3.X(); + p43.Y() = p4.Y() - p3.Y(); + p43.Z() = p4.Z() - p3.Z(); + if (p43.X()==0.0 && p43.Y()==0.0 && p43.Z()==0.0) + return false; + p21.X() = p2.X() - p1.X(); + p21.Y() = p2.Y() - p1.Y(); + p21.Z() = p2.Z() - p1.Z(); + if (p21.X()==0.0 && p21.Y()==0.0 && p21.Z()==0.0) + return false; + + d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z(); + d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z(); + d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z(); + d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z(); + d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z(); + + denom = d2121 * d4343 - d4321 * d4321; + if (denom==0.0) + return false; + numer = d1343 * d4321 - d1321 * d4343; + + mua = numer / denom; + mub = (d1343 + d4321 * (mua)) / d4343; + + pa.X() = p1.X() + mua * p21.X(); + pa.Y() = p1.Y() + mua * p21.Y(); + pa.Z() = p1.Z() + mua * p21.Z(); + pb.X() = p3.X() + mub * p43.X(); + pb.Y() = p3.Y() + mub * p43.Y(); + pb.Z() = p3.Z() + mub * p43.Z(); + + return true; + } + + long IntersectRayTriangle2(const Vec3 & P0, const Vec3 & dir, + const Vec3 & V0, const Vec3 & V1, + const Vec3 & V2, double &r) + { + Vec3 u, v, n; // triangle vectors + Vec3 w0, w; // ray vectors + double a, b; // params to calc ray-plane intersect + + // get triangle edge vectors and plane normal + u = V1 - V0; + v = V2 - V0; + n = u ^ v; // cross product + if (n.GetNorm() == 0.0) // triangle is degenerate + return -1; // do not deal with this case + + w0 = P0 - V0; + a = - n * w0; + b = n * dir; + if (fabs(b) <= 0.0) { // ray is parallel to triangle plane + if (a == 0.0) // ray lies in triangle plane + return 2; + else return 0; // ray disjoint from plane + } + + // get intersect point of ray with triangle plane + r = a / b; + if (r < 0.0) // ray goes away from triangle + return 0; // => no intersect + // for a segment, also test if (r > 1.0) => no intersect + + Vec3 I = P0 + r * dir; // intersect point of ray and plane + + // is I inside T? + double uu, uv, vv, wu, wv, D; + uu = u * u; + uv = u * v; + vv = v * v; + w = I - V0; + wu = w * u; + wv = w * v; + D = uv * uv - uu * vv; + + // get and test parametric coords + double s, t; + s = (uv * wv - vv * wu) / D; + if (s < 0.0 || s > 1.0) // I is outside T + return 0; + t = (uv * wu - uu * wv) / D; + if (t < 0.0 || (s + t) > 1.0) // I is outside T + return 0; + return 1; // I is in T + } + + + bool TMMesh::CheckConsistancy() + { + size_t nE = m_edges.GetSize(); + size_t nT = m_triangles.GetSize(); + for(size_t e = 0; e < nE; e++) + { + for(int f = 0; f < 2; f++) + { + if (!m_edges.GetHead()->GetData().m_triangles[f]) + { + return false; + } + } + m_edges.Next(); + } + + for(size_t f = 0; f < nT; f++) + { + for(int e = 0; e < 3; e++) + { + int found = 0; + for(int k = 0; k < 2; k++) + { + if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead()) + { + found++; + } + } + if (found != 1) + { + return false; + } + } + m_triangles.Next(); + } + + return true; + } + bool TMMesh::Normalize() + { + size_t nV = m_vertices.GetSize(); + if (nV == 0) + { + return false; + } + m_barycenter = m_vertices.GetHead()->GetData().m_pos; + Vec3 min = m_barycenter; + Vec3 max = m_barycenter; + Real x, y, z; + for(size_t v = 1; v < nV; v++) + { + m_barycenter += m_vertices.GetHead()->GetData().m_pos; + x = m_vertices.GetHead()->GetData().m_pos.X(); + y = m_vertices.GetHead()->GetData().m_pos.Y(); + z = m_vertices.GetHead()->GetData().m_pos.Z(); + if ( x < min.X()) min.X() = x; + else if ( x > max.X()) max.X() = x; + if ( y < min.Y()) min.Y() = y; + else if ( y > max.Y()) max.Y() = y; + if ( z < min.Z()) min.Z() = z; + else if ( z > max.Z()) max.Z() = z; + m_vertices.Next(); + } + m_barycenter /= static_cast(nV); + m_diag = static_cast(0.001 * (max-min).GetNorm()); + const Real invDiag = static_cast(1.0 / m_diag); + if (m_diag != 0.0) + { + for(size_t v = 0; v < nV; v++) + { + m_vertices.GetHead()->GetData().m_pos = (m_vertices.GetHead()->GetData().m_pos - m_barycenter) * invDiag; + m_vertices.Next(); + } + } + return true; + } + bool TMMesh::Denormalize() + { + size_t nV = m_vertices.GetSize(); + if (nV == 0) + { + return false; + } + if (m_diag != 0.0) + { + for(size_t v = 0; v < nV; v++) + { + m_vertices.GetHead()->GetData().m_pos = m_vertices.GetHead()->GetData().m_pos * m_diag + m_barycenter; + m_vertices.Next(); + } + } + return false; + } +} diff --git a/Extras/HACD/hacdManifoldMesh.h b/Extras/HACD/hacdManifoldMesh.h new file mode 100644 index 0000000..5d2ecec --- /dev/null +++ b/Extras/HACD/hacdManifoldMesh.h @@ -0,0 +1,250 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) +All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once +#ifndef HACD_MANIFOLD_MESH_H +#define HACD_MANIFOLD_MESH_H +#include +#include +#include "hacdVersion.h" +#include "hacdCircularList.h" +#include "hacdVector.h" +#include +namespace HACD +{ + class TMMTriangle; + class TMMEdge; + class TMMesh; + class ICHull; + class HACD; + + class DPoint + { + public: + DPoint(Real dist=0, bool computed=false, bool distOnly=false) + :m_dist(dist), + m_computed(computed), + m_distOnly(distOnly){}; + ~DPoint(){}; + private: + Real m_dist; + bool m_computed; + bool m_distOnly; + friend class TMMTriangle; + friend class TMMesh; + friend class GraphVertex; + friend class GraphEdge; + friend class Graph; + friend class ICHull; + friend class HACD; + }; + + //! Vertex data structure used in a triangular manifold mesh (TMM). + class TMMVertex + { + public: + TMMVertex(void); + ~TMMVertex(void); + + private: + Vec3 m_pos; + long m_name; + size_t m_id; + CircularListElement * m_duplicate; // pointer to incident cone edge (or NULL) + bool m_onHull; + bool m_tag; + TMMVertex(const TMMVertex & rhs); + + friend class HACD; + friend class ICHull; + friend class TMMesh; + friend class TMMTriangle; + friend class TMMEdge; + }; + + //! Edge data structure used in a triangular manifold mesh (TMM). + class TMMEdge + { + public: + TMMEdge(void); + ~TMMEdge(void); + private: + size_t m_id; + CircularListElement * m_triangles[2]; + CircularListElement * m_vertices[2]; + CircularListElement * m_newFace; + + + TMMEdge(const TMMEdge & rhs); + + friend class HACD; + friend class ICHull; + friend class TMMTriangle; + friend class TMMVertex; + friend class TMMesh; + }; + + //! Triangle data structure used in a triangular manifold mesh (TMM). + class TMMTriangle + { + public: + TMMTriangle(void); + ~TMMTriangle(void); + private: + size_t m_id; + CircularListElement * m_edges[3]; + CircularListElement * m_vertices[3]; + std::set m_incidentPoints; + bool m_visible; + + TMMTriangle(const TMMTriangle & rhs); + + friend class HACD; + friend class ICHull; + friend class TMMesh; + friend class TMMVertex; + friend class TMMEdge; + }; + + class Material + { + public: + Material(void); + ~Material(void){} +// private: + Vec3 m_diffuseColor; + double m_ambientIntensity; + Vec3 m_specularColor; + Vec3 m_emissiveColor; + double m_shininess; + double m_transparency; + + friend class TMMesh; + friend class HACD; + }; + + //! triangular manifold mesh data structure. + class TMMesh + { + public: + + //! Returns the number of vertices> + inline size_t GetNVertices() const { return m_vertices.GetSize();} + //! Returns the number of edges + inline size_t GetNEdges() const { return m_edges.GetSize();} + //! Returns the number of triangles + inline size_t GetNTriangles() const { return m_triangles.GetSize();} + //! Returns the vertices circular list + inline const CircularList & GetVertices() const { return m_vertices;} + //! Returns the edges circular list + inline const CircularList & GetEdges() const { return m_edges;} + //! Returns the triangles circular list + inline const CircularList & GetTriangles() const { return m_triangles;} + //! Returns the vertices circular list + inline CircularList & GetVertices() { return m_vertices;} + //! Returns the edges circular list + inline CircularList & GetEdges() { return m_edges;} + //! Returns the triangles circular list + inline CircularList & GetTriangles() { return m_triangles;} + //! Add vertex to the mesh + CircularListElement * AddVertex() {return m_vertices.Add();} + //! Add vertex to the mesh + CircularListElement * AddEdge() {return m_edges.Add();} + //! Add vertex to the mesh + CircularListElement * AddTriangle() {return m_triangles.Add();} + //! Print mesh information + void Print(); + //! + void GetIFS(Vec3 * const points, Vec3 * const triangles); + //! Save mesh + bool Save(const char *fileName); + //! Save mesh to VRML 2.0 format + bool SaveVRML2(std::ofstream &fout); + //! Save mesh to VRML 2.0 format + bool SaveVRML2(std::ofstream &fout, const Material & material); + //! + void Clear(); + //! + void Copy(TMMesh & mesh); + //! + bool CheckConsistancy(); + //! + bool Normalize(); + //! + bool Denormalize(); + //! Constructor + TMMesh(void); + //! Destructor + virtual ~TMMesh(void); + + private: + CircularList m_vertices; + CircularList m_edges; + CircularList m_triangles; + Real m_diag; //>! length of the BB diagonal + Vec3 m_barycenter; //>! barycenter of the mesh + + // not defined + TMMesh(const TMMesh & rhs); + friend class ICHull; + friend class HACD; + }; + //! IntersectRayTriangle(): intersect a ray with a 3D triangle + //! Input: a ray R, and a triangle T + //! Output: *I = intersection point (when it exists) + //! 0 = disjoint (no intersect) + //! 1 = intersect in unique point I1 + long IntersectRayTriangle( const Vec3 & P0, const Vec3 & dir, + const Vec3 & V0, const Vec3 & V1, + const Vec3 & V2, double &t); + + // intersect_RayTriangle(): intersect a ray with a 3D triangle + // Input: a ray R, and a triangle T + // Output: *I = intersection point (when it exists) + // Return: -1 = triangle is degenerate (a segment or point) + // 0 = disjoint (no intersect) + // 1 = intersect in unique point I1 + // 2 = are in the same plane + long IntersectRayTriangle2(const Vec3 & P0, const Vec3 & dir, + const Vec3 & V0, const Vec3 & V1, + const Vec3 & V2, double &r); + + /* + Calculate the line segment PaPb that is the shortest route between + two lines P1P2 and P3P4. Calculate also the values of mua and mub where + Pa = P1 + mua (P2 - P1) + Pb = P3 + mub (P4 - P3) + Return FALSE if no solution exists. + */ + bool IntersectLineLine(const Vec3 & p1, const Vec3 & p2, + const Vec3 & p3, const Vec3 & p4, + Vec3 & pa, Vec3 & pb, + double & mua, double &mub); +} +#endif diff --git a/Extras/HACD/hacdVector.h b/Extras/HACD/hacdVector.h new file mode 100644 index 0000000..4006c4b --- /dev/null +++ b/Extras/HACD/hacdVector.h @@ -0,0 +1,67 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once +#ifndef HACD_VECTOR_H +#define HACD_VECTOR_H +#include +#include +#include "hacdVersion.h" + +namespace HACD +{ + typedef double Real; + //! Vector dim 3. + template < typename T > class Vec3 + { + public: + T & X(); + T & Y(); + T & Z(); + const T & X() const; + const T & Y() const; + const T & Z() const; + void Normalize(); + T GetNorm() const; + void operator= (const Vec3 & rhs); + void operator+=(const Vec3 & rhs); + void operator-=(const Vec3 & rhs); + void operator-=(T a); + void operator+=(T a); + void operator/=(T a); + void operator*=(T a); + Vec3 operator^ (const Vec3 & rhs) const; + T operator* (const Vec3 & rhs) const; + Vec3 operator+ (const Vec3 & rhs) const; + Vec3 operator- (const Vec3 & rhs) const; + Vec3 operator- () const; + Vec3 operator* (T rhs) const; + Vec3 operator/ (T rhs) const; + Vec3(); + Vec3(T a); + Vec3(T x, T y, T z); + Vec3(const Vec3 & rhs); + /*virtual*/ ~Vec3(void); + + private: + T m_data[3]; + }; + template + const bool Colinear(const Vec3 & a, const Vec3 & b, const Vec3 & c); + template + const T Volume(const Vec3 & a, const Vec3 & b, const Vec3 & c, const Vec3 & d); + +} +#include "hacdVector.inl" // template implementation +#endif diff --git a/Extras/HACD/hacdVector.inl b/Extras/HACD/hacdVector.inl new file mode 100644 index 0000000..3532741 --- /dev/null +++ b/Extras/HACD/hacdVector.inl @@ -0,0 +1,178 @@ +#pragma once +#ifndef HACD_VECTOR_INL +#define HACD_VECTOR_INL +namespace HACD +{ + template + inline Vec3 operator*(T lhs, const Vec3 & rhs) + { + return Vec3(lhs * rhs.X(), lhs * rhs.Y(), lhs * rhs.Z()); + } + template + inline T & Vec3::X() + { + return m_data[0]; + } + template + inline T & Vec3::Y() + { + return m_data[1]; + } + template + inline T & Vec3::Z() + { + return m_data[2]; + } + template + inline const T & Vec3::X() const + { + return m_data[0]; + } + template + inline const T & Vec3::Y() const + { + return m_data[1]; + } + template + inline const T & Vec3::Z() const + { + return m_data[2]; + } + template + inline void Vec3::Normalize() + { + T n = sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]); + if (n != 0.0) (*this) /= n; + } + template + inline T Vec3::GetNorm() const + { + return sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]); + } + template + inline void Vec3::operator= (const Vec3 & rhs) + { + this->m_data[0] = rhs.m_data[0]; + this->m_data[1] = rhs.m_data[1]; + this->m_data[2] = rhs.m_data[2]; + } + template + inline void Vec3::operator+=(const Vec3 & rhs) + { + this->m_data[0] += rhs.m_data[0]; + this->m_data[1] += rhs.m_data[1]; + this->m_data[2] += rhs.m_data[2]; + } + template + inline void Vec3::operator-=(const Vec3 & rhs) + { + this->m_data[0] -= rhs.m_data[0]; + this->m_data[1] -= rhs.m_data[1]; + this->m_data[2] -= rhs.m_data[2]; + } + template + inline void Vec3::operator-=(T a) + { + this->m_data[0] -= a; + this->m_data[1] -= a; + this->m_data[2] -= a; + } + template + inline void Vec3::operator+=(T a) + { + this->m_data[0] += a; + this->m_data[1] += a; + this->m_data[2] += a; + } + template + inline void Vec3::operator/=(T a) + { + this->m_data[0] /= a; + this->m_data[1] /= a; + this->m_data[2] /= a; + } + template + inline void Vec3::operator*=(T a) + { + this->m_data[0] *= a; + this->m_data[1] *= a; + this->m_data[2] *= a; + } + template + inline Vec3 Vec3::operator^ (const Vec3 & rhs) const + { + return Vec3(m_data[1] * rhs.m_data[2] - m_data[2] * rhs.m_data[1], + m_data[2] * rhs.m_data[0] - m_data[0] * rhs.m_data[2], + m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0]); + } + template + inline T Vec3::operator*(const Vec3 & rhs) const + { + return (m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1] + m_data[2] * rhs.m_data[2]); + } + template + inline Vec3 Vec3::operator+(const Vec3 & rhs) const + { + return Vec3(m_data[0] + rhs.m_data[0],m_data[1] + rhs.m_data[1],m_data[2] + rhs.m_data[2]); + } + template + inline Vec3 Vec3::operator-(const Vec3 & rhs) const + { + return Vec3(m_data[0] - rhs.m_data[0],m_data[1] - rhs.m_data[1],m_data[2] - rhs.m_data[2]) ; + } + template + inline Vec3 Vec3::operator-() const + { + return Vec3(-m_data[0],-m_data[1],-m_data[2]) ; + } + + template + inline Vec3 Vec3::operator*(T rhs) const + { + return Vec3(rhs * this->m_data[0], rhs * this->m_data[1], rhs * this->m_data[2]); + } + template + inline Vec3 Vec3::operator/ (T rhs) const + { + return Vec3(m_data[0] / rhs, m_data[1] / rhs, m_data[2] / rhs); + } + template + inline Vec3::Vec3(T a) + { + m_data[0] = m_data[1] = m_data[2] = a; + } + template + inline Vec3::Vec3(T x, T y, T z) + { + m_data[0] = x; + m_data[1] = y; + m_data[2] = z; + } + template + inline Vec3::Vec3(const Vec3 & rhs) + { + m_data[0] = rhs.m_data[0]; + m_data[1] = rhs.m_data[1]; + m_data[2] = rhs.m_data[2]; + } + template + inline Vec3::~Vec3(void){}; + + template + inline Vec3::Vec3() {} + + template + inline const bool Colinear(const Vec3 & a, const Vec3 & b, const Vec3 & c) + { + return ((c.Z() - a.Z()) * (b.Y() - a.Y()) - (b.Z() - a.Z()) * (c.Y() - a.Y()) == 0.0 /*EPS*/) && + ((b.Z() - a.Z()) * (c.X() - a.X()) - (b.X() - a.X()) * (c.Z() - a.Z()) == 0.0 /*EPS*/) && + ((b.X() - a.X()) * (c.Y() - a.Y()) - (b.Y() - a.Y()) * (c.X() - a.X()) == 0.0 /*EPS*/); + } + + template + inline const T Volume(const Vec3 & a, const Vec3 & b, const Vec3 & c, const Vec3 & d) + { + return (a-d) * ((b-d) ^ (c-d)); + } +} +#endif //HACD_VECTOR_INL \ No newline at end of file diff --git a/Extras/HACD/hacdVersion.h b/Extras/HACD/hacdVersion.h new file mode 100644 index 0000000..3ce69b6 --- /dev/null +++ b/Extras/HACD/hacdVersion.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) + All rights reserved. + + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once +#ifndef HACD_VERSION_H +#define HACD_VERSION_H +#define HACD_VERSION_MAJOR 0 +#define HACD_VERSION_MINOR 0 +#endif \ No newline at end of file diff --git a/Extras/HACD/premake4.lua b/Extras/HACD/premake4.lua new file mode 100644 index 0000000..127d890 --- /dev/null +++ b/Extras/HACD/premake4.lua @@ -0,0 +1,9 @@ + project "HACD" + + kind "StaticLib" + targetdir "../../lib" + includedirs {"."} + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/Extras/Makefile.am b/Extras/Makefile.am new file mode 100644 index 0000000..f4cd5ea --- /dev/null +++ b/Extras/Makefile.am @@ -0,0 +1,95 @@ +noinst_LIBRARIES = libgimpactutils.a libconvexdecomposition.a libHACD.a libglui.a + +libglui_a_CXXFLAGS = ${CXXFLAGS} -Iglui +libglui_a_SOURCES =\ + glui/glui_spinner.cpp\ + glui/glui_treepanel.cpp\ + glui/arcball.cpp\ + glui/glui_scrollbar.cpp\ + glui/glui_filebrowser.cpp\ + glui/glui_node.cpp\ + glui/glui_edittext.cpp\ + glui/glui_statictext.cpp\ + glui/glui_bitmaps.cpp\ + glui/algebra3.cpp\ + glui/glui_string.cpp\ + glui/glui_button.cpp\ + glui/glui_add_controls.cpp\ + glui/glui_control.cpp\ + glui/glui.cpp\ + glui/glui_listbox.cpp\ + glui/glui_checkbox.cpp\ + glui/glui_commandline.cpp\ + glui/glui_textbox.cpp\ + glui/glui_column.cpp\ + glui/glui_mouse_iaction.cpp\ + glui/glui_radio.cpp\ + glui/glui_translation.cpp\ + glui/glui_tree.cpp\ + glui/glui_rotation.cpp\ + glui/glui_panel.cpp\ + glui/glui_rollout.cpp\ + glui/glui_separator.cpp\ + glui/glui_bitmap_img_data.cpp\ + glui/quaternion.cpp\ + glui/glui_window.cpp\ + glui/glui_list.cpp\ + glui/GL/glui.h\ + glui/quaternion.h\ + glui/glui_internal.h\ + glui/glui_internal_control.h\ + glui/arcball.h\ + glui/algebra3.h + +libconvexdecomposition_a_CXXFLAGS = ${CXXFLAGS} -IConvexDecomposition/ -I../src +libconvexdecomposition_a_SOURCES =\ + ConvexDecomposition/concavity.cpp\ + ConvexDecomposition/ConvexDecomposition.cpp\ + ConvexDecomposition/vlookup.cpp\ + ConvexDecomposition/bestfit.cpp\ + ConvexDecomposition/ConvexBuilder.cpp\ + ConvexDecomposition/cd_hull.cpp\ + ConvexDecomposition/raytri.cpp\ + ConvexDecomposition/splitplane.cpp\ + ConvexDecomposition/float_math.cpp\ + ConvexDecomposition/planetri.cpp\ + ConvexDecomposition/cd_wavefront.cpp\ + ConvexDecomposition/bestfitobb.cpp\ + ConvexDecomposition/meshvolume.cpp\ + ConvexDecomposition/fitsphere.cpp\ + ConvexDecomposition/fitsphere.h\ + ConvexDecomposition/vlookup.h\ + ConvexDecomposition/concavity.h\ + ConvexDecomposition/ConvexDecomposition.h\ + ConvexDecomposition/bestfit.h\ + ConvexDecomposition/cd_vector.h\ + ConvexDecomposition/ConvexBuilder.h\ + ConvexDecomposition/cd_hull.h\ + ConvexDecomposition/raytri.h\ + ConvexDecomposition/splitplane.h\ + ConvexDecomposition/float_math.h\ + ConvexDecomposition/planetri.h\ + ConvexDecomposition/cd_wavefront.h\ + ConvexDecomposition/bestfitobb.h\ + ConvexDecomposition/meshvolume.h + +libHACD_a_CXXFLAGS = ${CXXFLAGS} -IHACD/ -I../src +libHACD_a_SOURCES =\ + HACD/hacdGraph.cpp\ + HACD/hacdHACD.cpp\ + HACD/hacdICHull.cpp\ + HACD/hacdManifoldMesh.cpp\ + HACD/hacdCircularList.h\ + HACD/hacdGraph.h\ + HACD/hacdHACD.h\ + HACD/hacdICHull.h\ + HACD/hacdManifoldMesh.h\ + HACD/hacdVector.h\ + HACD/hacdVersion.h\ + HACD/hacdCircularList.inl\ + HACD/hacdVector.inl + + +libgimpactutils_a_CXXFLAGS = ${CXXFLAGS} -I../src -IGIMPACTUtils -IConvexDecomposition +libgimpactutils_a_SOURCES = GIMPACTUtils/btGImpactConvexDecompositionShape.cpp GIMPACTUtils/btGImpactConvexDecompositionShape.h + diff --git a/Extras/Makefile.in b/Extras/Makefile.in new file mode 100644 index 0000000..01df287 --- /dev/null +++ b/Extras/Makefile.in @@ -0,0 +1,1406 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = Extras +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libHACD_a_AR = $(AR) $(ARFLAGS) +libHACD_a_LIBADD = +am_libHACD_a_OBJECTS = libHACD_a-hacdGraph.$(OBJEXT) \ + libHACD_a-hacdHACD.$(OBJEXT) libHACD_a-hacdICHull.$(OBJEXT) \ + libHACD_a-hacdManifoldMesh.$(OBJEXT) +libHACD_a_OBJECTS = $(am_libHACD_a_OBJECTS) +libconvexdecomposition_a_AR = $(AR) $(ARFLAGS) +libconvexdecomposition_a_LIBADD = +am_libconvexdecomposition_a_OBJECTS = \ + libconvexdecomposition_a-concavity.$(OBJEXT) \ + libconvexdecomposition_a-ConvexDecomposition.$(OBJEXT) \ + libconvexdecomposition_a-vlookup.$(OBJEXT) \ + libconvexdecomposition_a-bestfit.$(OBJEXT) \ + libconvexdecomposition_a-ConvexBuilder.$(OBJEXT) \ + libconvexdecomposition_a-cd_hull.$(OBJEXT) \ + libconvexdecomposition_a-raytri.$(OBJEXT) \ + libconvexdecomposition_a-splitplane.$(OBJEXT) \ + libconvexdecomposition_a-float_math.$(OBJEXT) \ + libconvexdecomposition_a-planetri.$(OBJEXT) \ + libconvexdecomposition_a-cd_wavefront.$(OBJEXT) \ + libconvexdecomposition_a-bestfitobb.$(OBJEXT) \ + libconvexdecomposition_a-meshvolume.$(OBJEXT) \ + libconvexdecomposition_a-fitsphere.$(OBJEXT) +libconvexdecomposition_a_OBJECTS = \ + $(am_libconvexdecomposition_a_OBJECTS) +libgimpactutils_a_AR = $(AR) $(ARFLAGS) +libgimpactutils_a_LIBADD = +am_libgimpactutils_a_OBJECTS = \ + libgimpactutils_a-btGImpactConvexDecompositionShape.$(OBJEXT) +libgimpactutils_a_OBJECTS = $(am_libgimpactutils_a_OBJECTS) +libglui_a_AR = $(AR) $(ARFLAGS) +libglui_a_LIBADD = +am_libglui_a_OBJECTS = libglui_a-glui_spinner.$(OBJEXT) \ + libglui_a-glui_treepanel.$(OBJEXT) libglui_a-arcball.$(OBJEXT) \ + libglui_a-glui_scrollbar.$(OBJEXT) \ + libglui_a-glui_filebrowser.$(OBJEXT) \ + libglui_a-glui_node.$(OBJEXT) \ + libglui_a-glui_edittext.$(OBJEXT) \ + libglui_a-glui_statictext.$(OBJEXT) \ + libglui_a-glui_bitmaps.$(OBJEXT) libglui_a-algebra3.$(OBJEXT) \ + libglui_a-glui_string.$(OBJEXT) \ + libglui_a-glui_button.$(OBJEXT) \ + libglui_a-glui_add_controls.$(OBJEXT) \ + libglui_a-glui_control.$(OBJEXT) libglui_a-glui.$(OBJEXT) \ + libglui_a-glui_listbox.$(OBJEXT) \ + libglui_a-glui_checkbox.$(OBJEXT) \ + libglui_a-glui_commandline.$(OBJEXT) \ + libglui_a-glui_textbox.$(OBJEXT) \ + libglui_a-glui_column.$(OBJEXT) \ + libglui_a-glui_mouse_iaction.$(OBJEXT) \ + libglui_a-glui_radio.$(OBJEXT) \ + libglui_a-glui_translation.$(OBJEXT) \ + libglui_a-glui_tree.$(OBJEXT) \ + libglui_a-glui_rotation.$(OBJEXT) \ + libglui_a-glui_panel.$(OBJEXT) \ + libglui_a-glui_rollout.$(OBJEXT) \ + libglui_a-glui_separator.$(OBJEXT) \ + libglui_a-glui_bitmap_img_data.$(OBJEXT) \ + libglui_a-quaternion.$(OBJEXT) libglui_a-glui_window.$(OBJEXT) \ + libglui_a-glui_list.$(OBJEXT) +libglui_a_OBJECTS = $(am_libglui_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libHACD_a_SOURCES) $(libconvexdecomposition_a_SOURCES) \ + $(libgimpactutils_a_SOURCES) $(libglui_a_SOURCES) +DIST_SOURCES = $(libHACD_a_SOURCES) \ + $(libconvexdecomposition_a_SOURCES) \ + $(libgimpactutils_a_SOURCES) $(libglui_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libgimpactutils.a libconvexdecomposition.a libHACD.a libglui.a +libglui_a_CXXFLAGS = ${CXXFLAGS} -Iglui +libglui_a_SOURCES = \ + glui/glui_spinner.cpp\ + glui/glui_treepanel.cpp\ + glui/arcball.cpp\ + glui/glui_scrollbar.cpp\ + glui/glui_filebrowser.cpp\ + glui/glui_node.cpp\ + glui/glui_edittext.cpp\ + glui/glui_statictext.cpp\ + glui/glui_bitmaps.cpp\ + glui/algebra3.cpp\ + glui/glui_string.cpp\ + glui/glui_button.cpp\ + glui/glui_add_controls.cpp\ + glui/glui_control.cpp\ + glui/glui.cpp\ + glui/glui_listbox.cpp\ + glui/glui_checkbox.cpp\ + glui/glui_commandline.cpp\ + glui/glui_textbox.cpp\ + glui/glui_column.cpp\ + glui/glui_mouse_iaction.cpp\ + glui/glui_radio.cpp\ + glui/glui_translation.cpp\ + glui/glui_tree.cpp\ + glui/glui_rotation.cpp\ + glui/glui_panel.cpp\ + glui/glui_rollout.cpp\ + glui/glui_separator.cpp\ + glui/glui_bitmap_img_data.cpp\ + glui/quaternion.cpp\ + glui/glui_window.cpp\ + glui/glui_list.cpp\ + glui/GL/glui.h\ + glui/quaternion.h\ + glui/glui_internal.h\ + glui/glui_internal_control.h\ + glui/arcball.h\ + glui/algebra3.h + +libconvexdecomposition_a_CXXFLAGS = ${CXXFLAGS} -IConvexDecomposition/ -I../src +libconvexdecomposition_a_SOURCES = \ + ConvexDecomposition/concavity.cpp\ + ConvexDecomposition/ConvexDecomposition.cpp\ + ConvexDecomposition/vlookup.cpp\ + ConvexDecomposition/bestfit.cpp\ + ConvexDecomposition/ConvexBuilder.cpp\ + ConvexDecomposition/cd_hull.cpp\ + ConvexDecomposition/raytri.cpp\ + ConvexDecomposition/splitplane.cpp\ + ConvexDecomposition/float_math.cpp\ + ConvexDecomposition/planetri.cpp\ + ConvexDecomposition/cd_wavefront.cpp\ + ConvexDecomposition/bestfitobb.cpp\ + ConvexDecomposition/meshvolume.cpp\ + ConvexDecomposition/fitsphere.cpp\ + ConvexDecomposition/fitsphere.h\ + ConvexDecomposition/vlookup.h\ + ConvexDecomposition/concavity.h\ + ConvexDecomposition/ConvexDecomposition.h\ + ConvexDecomposition/bestfit.h\ + ConvexDecomposition/cd_vector.h\ + ConvexDecomposition/ConvexBuilder.h\ + ConvexDecomposition/cd_hull.h\ + ConvexDecomposition/raytri.h\ + ConvexDecomposition/splitplane.h\ + ConvexDecomposition/float_math.h\ + ConvexDecomposition/planetri.h\ + ConvexDecomposition/cd_wavefront.h\ + ConvexDecomposition/bestfitobb.h\ + ConvexDecomposition/meshvolume.h + +libHACD_a_CXXFLAGS = ${CXXFLAGS} -IHACD/ -I../src +libHACD_a_SOURCES = \ + HACD/hacdGraph.cpp\ + HACD/hacdHACD.cpp\ + HACD/hacdICHull.cpp\ + HACD/hacdManifoldMesh.cpp\ + HACD/hacdCircularList.h\ + HACD/hacdGraph.h\ + HACD/hacdHACD.h\ + HACD/hacdICHull.h\ + HACD/hacdManifoldMesh.h\ + HACD/hacdVector.h\ + HACD/hacdVersion.h\ + HACD/hacdCircularList.inl\ + HACD/hacdVector.inl + +libgimpactutils_a_CXXFLAGS = ${CXXFLAGS} -I../src -IGIMPACTUtils -IConvexDecomposition +libgimpactutils_a_SOURCES = GIMPACTUtils/btGImpactConvexDecompositionShape.cpp GIMPACTUtils/btGImpactConvexDecompositionShape.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Extras/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Extras/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libHACD.a: $(libHACD_a_OBJECTS) $(libHACD_a_DEPENDENCIES) + -rm -f libHACD.a + $(libHACD_a_AR) libHACD.a $(libHACD_a_OBJECTS) $(libHACD_a_LIBADD) + $(RANLIB) libHACD.a +libconvexdecomposition.a: $(libconvexdecomposition_a_OBJECTS) $(libconvexdecomposition_a_DEPENDENCIES) + -rm -f libconvexdecomposition.a + $(libconvexdecomposition_a_AR) libconvexdecomposition.a $(libconvexdecomposition_a_OBJECTS) $(libconvexdecomposition_a_LIBADD) + $(RANLIB) libconvexdecomposition.a +libgimpactutils.a: $(libgimpactutils_a_OBJECTS) $(libgimpactutils_a_DEPENDENCIES) + -rm -f libgimpactutils.a + $(libgimpactutils_a_AR) libgimpactutils.a $(libgimpactutils_a_OBJECTS) $(libgimpactutils_a_LIBADD) + $(RANLIB) libgimpactutils.a +libglui.a: $(libglui_a_OBJECTS) $(libglui_a_DEPENDENCIES) + -rm -f libglui.a + $(libglui_a_AR) libglui.a $(libglui_a_OBJECTS) $(libglui_a_LIBADD) + $(RANLIB) libglui.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libHACD_a-hacdGraph.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libHACD_a-hacdHACD.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libHACD_a-hacdICHull.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libHACD_a-hacdManifoldMesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-ConvexBuilder.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-ConvexDecomposition.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-bestfit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-bestfitobb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-cd_hull.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-cd_wavefront.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-concavity.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-fitsphere.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-float_math.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-meshvolume.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-planetri.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-raytri.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-splitplane.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libconvexdecomposition_a-vlookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgimpactutils_a-btGImpactConvexDecompositionShape.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-algebra3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-arcball.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_add_controls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_bitmap_img_data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_bitmaps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_button.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_checkbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_column.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_commandline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_control.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_edittext.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_filebrowser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_listbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_mouse_iaction.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_node.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_panel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_radio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_rollout.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_rotation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_scrollbar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_separator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_spinner.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_statictext.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_string.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_textbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_translation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_tree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_treepanel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-glui_window.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglui_a-quaternion.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +libHACD_a-hacdGraph.o: HACD/hacdGraph.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdGraph.o -MD -MP -MF $(DEPDIR)/libHACD_a-hacdGraph.Tpo -c -o libHACD_a-hacdGraph.o `test -f 'HACD/hacdGraph.cpp' || echo '$(srcdir)/'`HACD/hacdGraph.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdGraph.Tpo $(DEPDIR)/libHACD_a-hacdGraph.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdGraph.cpp' object='libHACD_a-hacdGraph.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdGraph.o `test -f 'HACD/hacdGraph.cpp' || echo '$(srcdir)/'`HACD/hacdGraph.cpp + +libHACD_a-hacdGraph.obj: HACD/hacdGraph.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdGraph.obj -MD -MP -MF $(DEPDIR)/libHACD_a-hacdGraph.Tpo -c -o libHACD_a-hacdGraph.obj `if test -f 'HACD/hacdGraph.cpp'; then $(CYGPATH_W) 'HACD/hacdGraph.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdGraph.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdGraph.Tpo $(DEPDIR)/libHACD_a-hacdGraph.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdGraph.cpp' object='libHACD_a-hacdGraph.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdGraph.obj `if test -f 'HACD/hacdGraph.cpp'; then $(CYGPATH_W) 'HACD/hacdGraph.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdGraph.cpp'; fi` + +libHACD_a-hacdHACD.o: HACD/hacdHACD.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdHACD.o -MD -MP -MF $(DEPDIR)/libHACD_a-hacdHACD.Tpo -c -o libHACD_a-hacdHACD.o `test -f 'HACD/hacdHACD.cpp' || echo '$(srcdir)/'`HACD/hacdHACD.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdHACD.Tpo $(DEPDIR)/libHACD_a-hacdHACD.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdHACD.cpp' object='libHACD_a-hacdHACD.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdHACD.o `test -f 'HACD/hacdHACD.cpp' || echo '$(srcdir)/'`HACD/hacdHACD.cpp + +libHACD_a-hacdHACD.obj: HACD/hacdHACD.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdHACD.obj -MD -MP -MF $(DEPDIR)/libHACD_a-hacdHACD.Tpo -c -o libHACD_a-hacdHACD.obj `if test -f 'HACD/hacdHACD.cpp'; then $(CYGPATH_W) 'HACD/hacdHACD.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdHACD.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdHACD.Tpo $(DEPDIR)/libHACD_a-hacdHACD.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdHACD.cpp' object='libHACD_a-hacdHACD.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdHACD.obj `if test -f 'HACD/hacdHACD.cpp'; then $(CYGPATH_W) 'HACD/hacdHACD.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdHACD.cpp'; fi` + +libHACD_a-hacdICHull.o: HACD/hacdICHull.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdICHull.o -MD -MP -MF $(DEPDIR)/libHACD_a-hacdICHull.Tpo -c -o libHACD_a-hacdICHull.o `test -f 'HACD/hacdICHull.cpp' || echo '$(srcdir)/'`HACD/hacdICHull.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdICHull.Tpo $(DEPDIR)/libHACD_a-hacdICHull.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdICHull.cpp' object='libHACD_a-hacdICHull.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdICHull.o `test -f 'HACD/hacdICHull.cpp' || echo '$(srcdir)/'`HACD/hacdICHull.cpp + +libHACD_a-hacdICHull.obj: HACD/hacdICHull.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdICHull.obj -MD -MP -MF $(DEPDIR)/libHACD_a-hacdICHull.Tpo -c -o libHACD_a-hacdICHull.obj `if test -f 'HACD/hacdICHull.cpp'; then $(CYGPATH_W) 'HACD/hacdICHull.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdICHull.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdICHull.Tpo $(DEPDIR)/libHACD_a-hacdICHull.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdICHull.cpp' object='libHACD_a-hacdICHull.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdICHull.obj `if test -f 'HACD/hacdICHull.cpp'; then $(CYGPATH_W) 'HACD/hacdICHull.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdICHull.cpp'; fi` + +libHACD_a-hacdManifoldMesh.o: HACD/hacdManifoldMesh.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdManifoldMesh.o -MD -MP -MF $(DEPDIR)/libHACD_a-hacdManifoldMesh.Tpo -c -o libHACD_a-hacdManifoldMesh.o `test -f 'HACD/hacdManifoldMesh.cpp' || echo '$(srcdir)/'`HACD/hacdManifoldMesh.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdManifoldMesh.Tpo $(DEPDIR)/libHACD_a-hacdManifoldMesh.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdManifoldMesh.cpp' object='libHACD_a-hacdManifoldMesh.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdManifoldMesh.o `test -f 'HACD/hacdManifoldMesh.cpp' || echo '$(srcdir)/'`HACD/hacdManifoldMesh.cpp + +libHACD_a-hacdManifoldMesh.obj: HACD/hacdManifoldMesh.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -MT libHACD_a-hacdManifoldMesh.obj -MD -MP -MF $(DEPDIR)/libHACD_a-hacdManifoldMesh.Tpo -c -o libHACD_a-hacdManifoldMesh.obj `if test -f 'HACD/hacdManifoldMesh.cpp'; then $(CYGPATH_W) 'HACD/hacdManifoldMesh.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdManifoldMesh.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libHACD_a-hacdManifoldMesh.Tpo $(DEPDIR)/libHACD_a-hacdManifoldMesh.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='HACD/hacdManifoldMesh.cpp' object='libHACD_a-hacdManifoldMesh.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libHACD_a_CXXFLAGS) $(CXXFLAGS) -c -o libHACD_a-hacdManifoldMesh.obj `if test -f 'HACD/hacdManifoldMesh.cpp'; then $(CYGPATH_W) 'HACD/hacdManifoldMesh.cpp'; else $(CYGPATH_W) '$(srcdir)/HACD/hacdManifoldMesh.cpp'; fi` + +libconvexdecomposition_a-concavity.o: ConvexDecomposition/concavity.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-concavity.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-concavity.Tpo -c -o libconvexdecomposition_a-concavity.o `test -f 'ConvexDecomposition/concavity.cpp' || echo '$(srcdir)/'`ConvexDecomposition/concavity.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-concavity.Tpo $(DEPDIR)/libconvexdecomposition_a-concavity.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/concavity.cpp' object='libconvexdecomposition_a-concavity.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-concavity.o `test -f 'ConvexDecomposition/concavity.cpp' || echo '$(srcdir)/'`ConvexDecomposition/concavity.cpp + +libconvexdecomposition_a-concavity.obj: ConvexDecomposition/concavity.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-concavity.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-concavity.Tpo -c -o libconvexdecomposition_a-concavity.obj `if test -f 'ConvexDecomposition/concavity.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/concavity.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/concavity.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-concavity.Tpo $(DEPDIR)/libconvexdecomposition_a-concavity.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/concavity.cpp' object='libconvexdecomposition_a-concavity.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-concavity.obj `if test -f 'ConvexDecomposition/concavity.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/concavity.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/concavity.cpp'; fi` + +libconvexdecomposition_a-ConvexDecomposition.o: ConvexDecomposition/ConvexDecomposition.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-ConvexDecomposition.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-ConvexDecomposition.Tpo -c -o libconvexdecomposition_a-ConvexDecomposition.o `test -f 'ConvexDecomposition/ConvexDecomposition.cpp' || echo '$(srcdir)/'`ConvexDecomposition/ConvexDecomposition.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-ConvexDecomposition.Tpo $(DEPDIR)/libconvexdecomposition_a-ConvexDecomposition.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/ConvexDecomposition.cpp' object='libconvexdecomposition_a-ConvexDecomposition.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-ConvexDecomposition.o `test -f 'ConvexDecomposition/ConvexDecomposition.cpp' || echo '$(srcdir)/'`ConvexDecomposition/ConvexDecomposition.cpp + +libconvexdecomposition_a-ConvexDecomposition.obj: ConvexDecomposition/ConvexDecomposition.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-ConvexDecomposition.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-ConvexDecomposition.Tpo -c -o libconvexdecomposition_a-ConvexDecomposition.obj `if test -f 'ConvexDecomposition/ConvexDecomposition.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/ConvexDecomposition.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/ConvexDecomposition.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-ConvexDecomposition.Tpo $(DEPDIR)/libconvexdecomposition_a-ConvexDecomposition.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/ConvexDecomposition.cpp' object='libconvexdecomposition_a-ConvexDecomposition.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-ConvexDecomposition.obj `if test -f 'ConvexDecomposition/ConvexDecomposition.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/ConvexDecomposition.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/ConvexDecomposition.cpp'; fi` + +libconvexdecomposition_a-vlookup.o: ConvexDecomposition/vlookup.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-vlookup.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-vlookup.Tpo -c -o libconvexdecomposition_a-vlookup.o `test -f 'ConvexDecomposition/vlookup.cpp' || echo '$(srcdir)/'`ConvexDecomposition/vlookup.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-vlookup.Tpo $(DEPDIR)/libconvexdecomposition_a-vlookup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/vlookup.cpp' object='libconvexdecomposition_a-vlookup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-vlookup.o `test -f 'ConvexDecomposition/vlookup.cpp' || echo '$(srcdir)/'`ConvexDecomposition/vlookup.cpp + +libconvexdecomposition_a-vlookup.obj: ConvexDecomposition/vlookup.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-vlookup.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-vlookup.Tpo -c -o libconvexdecomposition_a-vlookup.obj `if test -f 'ConvexDecomposition/vlookup.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/vlookup.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/vlookup.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-vlookup.Tpo $(DEPDIR)/libconvexdecomposition_a-vlookup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/vlookup.cpp' object='libconvexdecomposition_a-vlookup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-vlookup.obj `if test -f 'ConvexDecomposition/vlookup.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/vlookup.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/vlookup.cpp'; fi` + +libconvexdecomposition_a-bestfit.o: ConvexDecomposition/bestfit.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-bestfit.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-bestfit.Tpo -c -o libconvexdecomposition_a-bestfit.o `test -f 'ConvexDecomposition/bestfit.cpp' || echo '$(srcdir)/'`ConvexDecomposition/bestfit.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-bestfit.Tpo $(DEPDIR)/libconvexdecomposition_a-bestfit.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/bestfit.cpp' object='libconvexdecomposition_a-bestfit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-bestfit.o `test -f 'ConvexDecomposition/bestfit.cpp' || echo '$(srcdir)/'`ConvexDecomposition/bestfit.cpp + +libconvexdecomposition_a-bestfit.obj: ConvexDecomposition/bestfit.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-bestfit.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-bestfit.Tpo -c -o libconvexdecomposition_a-bestfit.obj `if test -f 'ConvexDecomposition/bestfit.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/bestfit.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/bestfit.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-bestfit.Tpo $(DEPDIR)/libconvexdecomposition_a-bestfit.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/bestfit.cpp' object='libconvexdecomposition_a-bestfit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-bestfit.obj `if test -f 'ConvexDecomposition/bestfit.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/bestfit.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/bestfit.cpp'; fi` + +libconvexdecomposition_a-ConvexBuilder.o: ConvexDecomposition/ConvexBuilder.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-ConvexBuilder.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-ConvexBuilder.Tpo -c -o libconvexdecomposition_a-ConvexBuilder.o `test -f 'ConvexDecomposition/ConvexBuilder.cpp' || echo '$(srcdir)/'`ConvexDecomposition/ConvexBuilder.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-ConvexBuilder.Tpo $(DEPDIR)/libconvexdecomposition_a-ConvexBuilder.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/ConvexBuilder.cpp' object='libconvexdecomposition_a-ConvexBuilder.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-ConvexBuilder.o `test -f 'ConvexDecomposition/ConvexBuilder.cpp' || echo '$(srcdir)/'`ConvexDecomposition/ConvexBuilder.cpp + +libconvexdecomposition_a-ConvexBuilder.obj: ConvexDecomposition/ConvexBuilder.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-ConvexBuilder.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-ConvexBuilder.Tpo -c -o libconvexdecomposition_a-ConvexBuilder.obj `if test -f 'ConvexDecomposition/ConvexBuilder.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/ConvexBuilder.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/ConvexBuilder.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-ConvexBuilder.Tpo $(DEPDIR)/libconvexdecomposition_a-ConvexBuilder.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/ConvexBuilder.cpp' object='libconvexdecomposition_a-ConvexBuilder.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-ConvexBuilder.obj `if test -f 'ConvexDecomposition/ConvexBuilder.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/ConvexBuilder.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/ConvexBuilder.cpp'; fi` + +libconvexdecomposition_a-cd_hull.o: ConvexDecomposition/cd_hull.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-cd_hull.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-cd_hull.Tpo -c -o libconvexdecomposition_a-cd_hull.o `test -f 'ConvexDecomposition/cd_hull.cpp' || echo '$(srcdir)/'`ConvexDecomposition/cd_hull.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-cd_hull.Tpo $(DEPDIR)/libconvexdecomposition_a-cd_hull.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/cd_hull.cpp' object='libconvexdecomposition_a-cd_hull.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-cd_hull.o `test -f 'ConvexDecomposition/cd_hull.cpp' || echo '$(srcdir)/'`ConvexDecomposition/cd_hull.cpp + +libconvexdecomposition_a-cd_hull.obj: ConvexDecomposition/cd_hull.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-cd_hull.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-cd_hull.Tpo -c -o libconvexdecomposition_a-cd_hull.obj `if test -f 'ConvexDecomposition/cd_hull.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/cd_hull.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/cd_hull.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-cd_hull.Tpo $(DEPDIR)/libconvexdecomposition_a-cd_hull.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/cd_hull.cpp' object='libconvexdecomposition_a-cd_hull.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-cd_hull.obj `if test -f 'ConvexDecomposition/cd_hull.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/cd_hull.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/cd_hull.cpp'; fi` + +libconvexdecomposition_a-raytri.o: ConvexDecomposition/raytri.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-raytri.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-raytri.Tpo -c -o libconvexdecomposition_a-raytri.o `test -f 'ConvexDecomposition/raytri.cpp' || echo '$(srcdir)/'`ConvexDecomposition/raytri.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-raytri.Tpo $(DEPDIR)/libconvexdecomposition_a-raytri.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/raytri.cpp' object='libconvexdecomposition_a-raytri.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-raytri.o `test -f 'ConvexDecomposition/raytri.cpp' || echo '$(srcdir)/'`ConvexDecomposition/raytri.cpp + +libconvexdecomposition_a-raytri.obj: ConvexDecomposition/raytri.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-raytri.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-raytri.Tpo -c -o libconvexdecomposition_a-raytri.obj `if test -f 'ConvexDecomposition/raytri.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/raytri.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/raytri.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-raytri.Tpo $(DEPDIR)/libconvexdecomposition_a-raytri.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/raytri.cpp' object='libconvexdecomposition_a-raytri.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-raytri.obj `if test -f 'ConvexDecomposition/raytri.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/raytri.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/raytri.cpp'; fi` + +libconvexdecomposition_a-splitplane.o: ConvexDecomposition/splitplane.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-splitplane.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-splitplane.Tpo -c -o libconvexdecomposition_a-splitplane.o `test -f 'ConvexDecomposition/splitplane.cpp' || echo '$(srcdir)/'`ConvexDecomposition/splitplane.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-splitplane.Tpo $(DEPDIR)/libconvexdecomposition_a-splitplane.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/splitplane.cpp' object='libconvexdecomposition_a-splitplane.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-splitplane.o `test -f 'ConvexDecomposition/splitplane.cpp' || echo '$(srcdir)/'`ConvexDecomposition/splitplane.cpp + +libconvexdecomposition_a-splitplane.obj: ConvexDecomposition/splitplane.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-splitplane.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-splitplane.Tpo -c -o libconvexdecomposition_a-splitplane.obj `if test -f 'ConvexDecomposition/splitplane.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/splitplane.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/splitplane.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-splitplane.Tpo $(DEPDIR)/libconvexdecomposition_a-splitplane.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/splitplane.cpp' object='libconvexdecomposition_a-splitplane.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-splitplane.obj `if test -f 'ConvexDecomposition/splitplane.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/splitplane.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/splitplane.cpp'; fi` + +libconvexdecomposition_a-float_math.o: ConvexDecomposition/float_math.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-float_math.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-float_math.Tpo -c -o libconvexdecomposition_a-float_math.o `test -f 'ConvexDecomposition/float_math.cpp' || echo '$(srcdir)/'`ConvexDecomposition/float_math.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-float_math.Tpo $(DEPDIR)/libconvexdecomposition_a-float_math.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/float_math.cpp' object='libconvexdecomposition_a-float_math.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-float_math.o `test -f 'ConvexDecomposition/float_math.cpp' || echo '$(srcdir)/'`ConvexDecomposition/float_math.cpp + +libconvexdecomposition_a-float_math.obj: ConvexDecomposition/float_math.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-float_math.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-float_math.Tpo -c -o libconvexdecomposition_a-float_math.obj `if test -f 'ConvexDecomposition/float_math.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/float_math.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/float_math.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-float_math.Tpo $(DEPDIR)/libconvexdecomposition_a-float_math.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/float_math.cpp' object='libconvexdecomposition_a-float_math.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-float_math.obj `if test -f 'ConvexDecomposition/float_math.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/float_math.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/float_math.cpp'; fi` + +libconvexdecomposition_a-planetri.o: ConvexDecomposition/planetri.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-planetri.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-planetri.Tpo -c -o libconvexdecomposition_a-planetri.o `test -f 'ConvexDecomposition/planetri.cpp' || echo '$(srcdir)/'`ConvexDecomposition/planetri.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-planetri.Tpo $(DEPDIR)/libconvexdecomposition_a-planetri.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/planetri.cpp' object='libconvexdecomposition_a-planetri.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-planetri.o `test -f 'ConvexDecomposition/planetri.cpp' || echo '$(srcdir)/'`ConvexDecomposition/planetri.cpp + +libconvexdecomposition_a-planetri.obj: ConvexDecomposition/planetri.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-planetri.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-planetri.Tpo -c -o libconvexdecomposition_a-planetri.obj `if test -f 'ConvexDecomposition/planetri.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/planetri.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/planetri.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-planetri.Tpo $(DEPDIR)/libconvexdecomposition_a-planetri.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/planetri.cpp' object='libconvexdecomposition_a-planetri.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-planetri.obj `if test -f 'ConvexDecomposition/planetri.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/planetri.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/planetri.cpp'; fi` + +libconvexdecomposition_a-cd_wavefront.o: ConvexDecomposition/cd_wavefront.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-cd_wavefront.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-cd_wavefront.Tpo -c -o libconvexdecomposition_a-cd_wavefront.o `test -f 'ConvexDecomposition/cd_wavefront.cpp' || echo '$(srcdir)/'`ConvexDecomposition/cd_wavefront.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-cd_wavefront.Tpo $(DEPDIR)/libconvexdecomposition_a-cd_wavefront.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/cd_wavefront.cpp' object='libconvexdecomposition_a-cd_wavefront.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-cd_wavefront.o `test -f 'ConvexDecomposition/cd_wavefront.cpp' || echo '$(srcdir)/'`ConvexDecomposition/cd_wavefront.cpp + +libconvexdecomposition_a-cd_wavefront.obj: ConvexDecomposition/cd_wavefront.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-cd_wavefront.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-cd_wavefront.Tpo -c -o libconvexdecomposition_a-cd_wavefront.obj `if test -f 'ConvexDecomposition/cd_wavefront.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/cd_wavefront.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/cd_wavefront.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-cd_wavefront.Tpo $(DEPDIR)/libconvexdecomposition_a-cd_wavefront.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/cd_wavefront.cpp' object='libconvexdecomposition_a-cd_wavefront.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-cd_wavefront.obj `if test -f 'ConvexDecomposition/cd_wavefront.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/cd_wavefront.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/cd_wavefront.cpp'; fi` + +libconvexdecomposition_a-bestfitobb.o: ConvexDecomposition/bestfitobb.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-bestfitobb.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-bestfitobb.Tpo -c -o libconvexdecomposition_a-bestfitobb.o `test -f 'ConvexDecomposition/bestfitobb.cpp' || echo '$(srcdir)/'`ConvexDecomposition/bestfitobb.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-bestfitobb.Tpo $(DEPDIR)/libconvexdecomposition_a-bestfitobb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/bestfitobb.cpp' object='libconvexdecomposition_a-bestfitobb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-bestfitobb.o `test -f 'ConvexDecomposition/bestfitobb.cpp' || echo '$(srcdir)/'`ConvexDecomposition/bestfitobb.cpp + +libconvexdecomposition_a-bestfitobb.obj: ConvexDecomposition/bestfitobb.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-bestfitobb.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-bestfitobb.Tpo -c -o libconvexdecomposition_a-bestfitobb.obj `if test -f 'ConvexDecomposition/bestfitobb.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/bestfitobb.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/bestfitobb.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-bestfitobb.Tpo $(DEPDIR)/libconvexdecomposition_a-bestfitobb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/bestfitobb.cpp' object='libconvexdecomposition_a-bestfitobb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-bestfitobb.obj `if test -f 'ConvexDecomposition/bestfitobb.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/bestfitobb.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/bestfitobb.cpp'; fi` + +libconvexdecomposition_a-meshvolume.o: ConvexDecomposition/meshvolume.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-meshvolume.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-meshvolume.Tpo -c -o libconvexdecomposition_a-meshvolume.o `test -f 'ConvexDecomposition/meshvolume.cpp' || echo '$(srcdir)/'`ConvexDecomposition/meshvolume.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-meshvolume.Tpo $(DEPDIR)/libconvexdecomposition_a-meshvolume.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/meshvolume.cpp' object='libconvexdecomposition_a-meshvolume.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-meshvolume.o `test -f 'ConvexDecomposition/meshvolume.cpp' || echo '$(srcdir)/'`ConvexDecomposition/meshvolume.cpp + +libconvexdecomposition_a-meshvolume.obj: ConvexDecomposition/meshvolume.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-meshvolume.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-meshvolume.Tpo -c -o libconvexdecomposition_a-meshvolume.obj `if test -f 'ConvexDecomposition/meshvolume.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/meshvolume.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/meshvolume.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-meshvolume.Tpo $(DEPDIR)/libconvexdecomposition_a-meshvolume.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/meshvolume.cpp' object='libconvexdecomposition_a-meshvolume.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-meshvolume.obj `if test -f 'ConvexDecomposition/meshvolume.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/meshvolume.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/meshvolume.cpp'; fi` + +libconvexdecomposition_a-fitsphere.o: ConvexDecomposition/fitsphere.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-fitsphere.o -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-fitsphere.Tpo -c -o libconvexdecomposition_a-fitsphere.o `test -f 'ConvexDecomposition/fitsphere.cpp' || echo '$(srcdir)/'`ConvexDecomposition/fitsphere.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-fitsphere.Tpo $(DEPDIR)/libconvexdecomposition_a-fitsphere.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/fitsphere.cpp' object='libconvexdecomposition_a-fitsphere.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-fitsphere.o `test -f 'ConvexDecomposition/fitsphere.cpp' || echo '$(srcdir)/'`ConvexDecomposition/fitsphere.cpp + +libconvexdecomposition_a-fitsphere.obj: ConvexDecomposition/fitsphere.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -MT libconvexdecomposition_a-fitsphere.obj -MD -MP -MF $(DEPDIR)/libconvexdecomposition_a-fitsphere.Tpo -c -o libconvexdecomposition_a-fitsphere.obj `if test -f 'ConvexDecomposition/fitsphere.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/fitsphere.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/fitsphere.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libconvexdecomposition_a-fitsphere.Tpo $(DEPDIR)/libconvexdecomposition_a-fitsphere.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ConvexDecomposition/fitsphere.cpp' object='libconvexdecomposition_a-fitsphere.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libconvexdecomposition_a_CXXFLAGS) $(CXXFLAGS) -c -o libconvexdecomposition_a-fitsphere.obj `if test -f 'ConvexDecomposition/fitsphere.cpp'; then $(CYGPATH_W) 'ConvexDecomposition/fitsphere.cpp'; else $(CYGPATH_W) '$(srcdir)/ConvexDecomposition/fitsphere.cpp'; fi` + +libgimpactutils_a-btGImpactConvexDecompositionShape.o: GIMPACTUtils/btGImpactConvexDecompositionShape.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgimpactutils_a_CXXFLAGS) $(CXXFLAGS) -MT libgimpactutils_a-btGImpactConvexDecompositionShape.o -MD -MP -MF $(DEPDIR)/libgimpactutils_a-btGImpactConvexDecompositionShape.Tpo -c -o libgimpactutils_a-btGImpactConvexDecompositionShape.o `test -f 'GIMPACTUtils/btGImpactConvexDecompositionShape.cpp' || echo '$(srcdir)/'`GIMPACTUtils/btGImpactConvexDecompositionShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libgimpactutils_a-btGImpactConvexDecompositionShape.Tpo $(DEPDIR)/libgimpactutils_a-btGImpactConvexDecompositionShape.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='GIMPACTUtils/btGImpactConvexDecompositionShape.cpp' object='libgimpactutils_a-btGImpactConvexDecompositionShape.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgimpactutils_a_CXXFLAGS) $(CXXFLAGS) -c -o libgimpactutils_a-btGImpactConvexDecompositionShape.o `test -f 'GIMPACTUtils/btGImpactConvexDecompositionShape.cpp' || echo '$(srcdir)/'`GIMPACTUtils/btGImpactConvexDecompositionShape.cpp + +libgimpactutils_a-btGImpactConvexDecompositionShape.obj: GIMPACTUtils/btGImpactConvexDecompositionShape.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgimpactutils_a_CXXFLAGS) $(CXXFLAGS) -MT libgimpactutils_a-btGImpactConvexDecompositionShape.obj -MD -MP -MF $(DEPDIR)/libgimpactutils_a-btGImpactConvexDecompositionShape.Tpo -c -o libgimpactutils_a-btGImpactConvexDecompositionShape.obj `if test -f 'GIMPACTUtils/btGImpactConvexDecompositionShape.cpp'; then $(CYGPATH_W) 'GIMPACTUtils/btGImpactConvexDecompositionShape.cpp'; else $(CYGPATH_W) '$(srcdir)/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libgimpactutils_a-btGImpactConvexDecompositionShape.Tpo $(DEPDIR)/libgimpactutils_a-btGImpactConvexDecompositionShape.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='GIMPACTUtils/btGImpactConvexDecompositionShape.cpp' object='libgimpactutils_a-btGImpactConvexDecompositionShape.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgimpactutils_a_CXXFLAGS) $(CXXFLAGS) -c -o libgimpactutils_a-btGImpactConvexDecompositionShape.obj `if test -f 'GIMPACTUtils/btGImpactConvexDecompositionShape.cpp'; then $(CYGPATH_W) 'GIMPACTUtils/btGImpactConvexDecompositionShape.cpp'; else $(CYGPATH_W) '$(srcdir)/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp'; fi` + +libglui_a-glui_spinner.o: glui/glui_spinner.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_spinner.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_spinner.Tpo -c -o libglui_a-glui_spinner.o `test -f 'glui/glui_spinner.cpp' || echo '$(srcdir)/'`glui/glui_spinner.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_spinner.Tpo $(DEPDIR)/libglui_a-glui_spinner.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_spinner.cpp' object='libglui_a-glui_spinner.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_spinner.o `test -f 'glui/glui_spinner.cpp' || echo '$(srcdir)/'`glui/glui_spinner.cpp + +libglui_a-glui_spinner.obj: glui/glui_spinner.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_spinner.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_spinner.Tpo -c -o libglui_a-glui_spinner.obj `if test -f 'glui/glui_spinner.cpp'; then $(CYGPATH_W) 'glui/glui_spinner.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_spinner.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_spinner.Tpo $(DEPDIR)/libglui_a-glui_spinner.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_spinner.cpp' object='libglui_a-glui_spinner.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_spinner.obj `if test -f 'glui/glui_spinner.cpp'; then $(CYGPATH_W) 'glui/glui_spinner.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_spinner.cpp'; fi` + +libglui_a-glui_treepanel.o: glui/glui_treepanel.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_treepanel.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_treepanel.Tpo -c -o libglui_a-glui_treepanel.o `test -f 'glui/glui_treepanel.cpp' || echo '$(srcdir)/'`glui/glui_treepanel.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_treepanel.Tpo $(DEPDIR)/libglui_a-glui_treepanel.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_treepanel.cpp' object='libglui_a-glui_treepanel.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_treepanel.o `test -f 'glui/glui_treepanel.cpp' || echo '$(srcdir)/'`glui/glui_treepanel.cpp + +libglui_a-glui_treepanel.obj: glui/glui_treepanel.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_treepanel.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_treepanel.Tpo -c -o libglui_a-glui_treepanel.obj `if test -f 'glui/glui_treepanel.cpp'; then $(CYGPATH_W) 'glui/glui_treepanel.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_treepanel.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_treepanel.Tpo $(DEPDIR)/libglui_a-glui_treepanel.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_treepanel.cpp' object='libglui_a-glui_treepanel.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_treepanel.obj `if test -f 'glui/glui_treepanel.cpp'; then $(CYGPATH_W) 'glui/glui_treepanel.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_treepanel.cpp'; fi` + +libglui_a-arcball.o: glui/arcball.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-arcball.o -MD -MP -MF $(DEPDIR)/libglui_a-arcball.Tpo -c -o libglui_a-arcball.o `test -f 'glui/arcball.cpp' || echo '$(srcdir)/'`glui/arcball.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-arcball.Tpo $(DEPDIR)/libglui_a-arcball.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/arcball.cpp' object='libglui_a-arcball.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-arcball.o `test -f 'glui/arcball.cpp' || echo '$(srcdir)/'`glui/arcball.cpp + +libglui_a-arcball.obj: glui/arcball.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-arcball.obj -MD -MP -MF $(DEPDIR)/libglui_a-arcball.Tpo -c -o libglui_a-arcball.obj `if test -f 'glui/arcball.cpp'; then $(CYGPATH_W) 'glui/arcball.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/arcball.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-arcball.Tpo $(DEPDIR)/libglui_a-arcball.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/arcball.cpp' object='libglui_a-arcball.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-arcball.obj `if test -f 'glui/arcball.cpp'; then $(CYGPATH_W) 'glui/arcball.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/arcball.cpp'; fi` + +libglui_a-glui_scrollbar.o: glui/glui_scrollbar.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_scrollbar.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_scrollbar.Tpo -c -o libglui_a-glui_scrollbar.o `test -f 'glui/glui_scrollbar.cpp' || echo '$(srcdir)/'`glui/glui_scrollbar.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_scrollbar.Tpo $(DEPDIR)/libglui_a-glui_scrollbar.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_scrollbar.cpp' object='libglui_a-glui_scrollbar.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_scrollbar.o `test -f 'glui/glui_scrollbar.cpp' || echo '$(srcdir)/'`glui/glui_scrollbar.cpp + +libglui_a-glui_scrollbar.obj: glui/glui_scrollbar.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_scrollbar.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_scrollbar.Tpo -c -o libglui_a-glui_scrollbar.obj `if test -f 'glui/glui_scrollbar.cpp'; then $(CYGPATH_W) 'glui/glui_scrollbar.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_scrollbar.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_scrollbar.Tpo $(DEPDIR)/libglui_a-glui_scrollbar.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_scrollbar.cpp' object='libglui_a-glui_scrollbar.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_scrollbar.obj `if test -f 'glui/glui_scrollbar.cpp'; then $(CYGPATH_W) 'glui/glui_scrollbar.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_scrollbar.cpp'; fi` + +libglui_a-glui_filebrowser.o: glui/glui_filebrowser.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_filebrowser.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_filebrowser.Tpo -c -o libglui_a-glui_filebrowser.o `test -f 'glui/glui_filebrowser.cpp' || echo '$(srcdir)/'`glui/glui_filebrowser.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_filebrowser.Tpo $(DEPDIR)/libglui_a-glui_filebrowser.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_filebrowser.cpp' object='libglui_a-glui_filebrowser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_filebrowser.o `test -f 'glui/glui_filebrowser.cpp' || echo '$(srcdir)/'`glui/glui_filebrowser.cpp + +libglui_a-glui_filebrowser.obj: glui/glui_filebrowser.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_filebrowser.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_filebrowser.Tpo -c -o libglui_a-glui_filebrowser.obj `if test -f 'glui/glui_filebrowser.cpp'; then $(CYGPATH_W) 'glui/glui_filebrowser.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_filebrowser.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_filebrowser.Tpo $(DEPDIR)/libglui_a-glui_filebrowser.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_filebrowser.cpp' object='libglui_a-glui_filebrowser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_filebrowser.obj `if test -f 'glui/glui_filebrowser.cpp'; then $(CYGPATH_W) 'glui/glui_filebrowser.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_filebrowser.cpp'; fi` + +libglui_a-glui_node.o: glui/glui_node.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_node.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_node.Tpo -c -o libglui_a-glui_node.o `test -f 'glui/glui_node.cpp' || echo '$(srcdir)/'`glui/glui_node.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_node.Tpo $(DEPDIR)/libglui_a-glui_node.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_node.cpp' object='libglui_a-glui_node.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_node.o `test -f 'glui/glui_node.cpp' || echo '$(srcdir)/'`glui/glui_node.cpp + +libglui_a-glui_node.obj: glui/glui_node.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_node.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_node.Tpo -c -o libglui_a-glui_node.obj `if test -f 'glui/glui_node.cpp'; then $(CYGPATH_W) 'glui/glui_node.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_node.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_node.Tpo $(DEPDIR)/libglui_a-glui_node.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_node.cpp' object='libglui_a-glui_node.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_node.obj `if test -f 'glui/glui_node.cpp'; then $(CYGPATH_W) 'glui/glui_node.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_node.cpp'; fi` + +libglui_a-glui_edittext.o: glui/glui_edittext.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_edittext.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_edittext.Tpo -c -o libglui_a-glui_edittext.o `test -f 'glui/glui_edittext.cpp' || echo '$(srcdir)/'`glui/glui_edittext.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_edittext.Tpo $(DEPDIR)/libglui_a-glui_edittext.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_edittext.cpp' object='libglui_a-glui_edittext.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_edittext.o `test -f 'glui/glui_edittext.cpp' || echo '$(srcdir)/'`glui/glui_edittext.cpp + +libglui_a-glui_edittext.obj: glui/glui_edittext.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_edittext.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_edittext.Tpo -c -o libglui_a-glui_edittext.obj `if test -f 'glui/glui_edittext.cpp'; then $(CYGPATH_W) 'glui/glui_edittext.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_edittext.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_edittext.Tpo $(DEPDIR)/libglui_a-glui_edittext.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_edittext.cpp' object='libglui_a-glui_edittext.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_edittext.obj `if test -f 'glui/glui_edittext.cpp'; then $(CYGPATH_W) 'glui/glui_edittext.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_edittext.cpp'; fi` + +libglui_a-glui_statictext.o: glui/glui_statictext.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_statictext.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_statictext.Tpo -c -o libglui_a-glui_statictext.o `test -f 'glui/glui_statictext.cpp' || echo '$(srcdir)/'`glui/glui_statictext.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_statictext.Tpo $(DEPDIR)/libglui_a-glui_statictext.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_statictext.cpp' object='libglui_a-glui_statictext.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_statictext.o `test -f 'glui/glui_statictext.cpp' || echo '$(srcdir)/'`glui/glui_statictext.cpp + +libglui_a-glui_statictext.obj: glui/glui_statictext.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_statictext.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_statictext.Tpo -c -o libglui_a-glui_statictext.obj `if test -f 'glui/glui_statictext.cpp'; then $(CYGPATH_W) 'glui/glui_statictext.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_statictext.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_statictext.Tpo $(DEPDIR)/libglui_a-glui_statictext.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_statictext.cpp' object='libglui_a-glui_statictext.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_statictext.obj `if test -f 'glui/glui_statictext.cpp'; then $(CYGPATH_W) 'glui/glui_statictext.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_statictext.cpp'; fi` + +libglui_a-glui_bitmaps.o: glui/glui_bitmaps.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_bitmaps.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_bitmaps.Tpo -c -o libglui_a-glui_bitmaps.o `test -f 'glui/glui_bitmaps.cpp' || echo '$(srcdir)/'`glui/glui_bitmaps.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_bitmaps.Tpo $(DEPDIR)/libglui_a-glui_bitmaps.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_bitmaps.cpp' object='libglui_a-glui_bitmaps.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_bitmaps.o `test -f 'glui/glui_bitmaps.cpp' || echo '$(srcdir)/'`glui/glui_bitmaps.cpp + +libglui_a-glui_bitmaps.obj: glui/glui_bitmaps.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_bitmaps.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_bitmaps.Tpo -c -o libglui_a-glui_bitmaps.obj `if test -f 'glui/glui_bitmaps.cpp'; then $(CYGPATH_W) 'glui/glui_bitmaps.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_bitmaps.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_bitmaps.Tpo $(DEPDIR)/libglui_a-glui_bitmaps.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_bitmaps.cpp' object='libglui_a-glui_bitmaps.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_bitmaps.obj `if test -f 'glui/glui_bitmaps.cpp'; then $(CYGPATH_W) 'glui/glui_bitmaps.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_bitmaps.cpp'; fi` + +libglui_a-algebra3.o: glui/algebra3.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-algebra3.o -MD -MP -MF $(DEPDIR)/libglui_a-algebra3.Tpo -c -o libglui_a-algebra3.o `test -f 'glui/algebra3.cpp' || echo '$(srcdir)/'`glui/algebra3.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-algebra3.Tpo $(DEPDIR)/libglui_a-algebra3.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/algebra3.cpp' object='libglui_a-algebra3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-algebra3.o `test -f 'glui/algebra3.cpp' || echo '$(srcdir)/'`glui/algebra3.cpp + +libglui_a-algebra3.obj: glui/algebra3.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-algebra3.obj -MD -MP -MF $(DEPDIR)/libglui_a-algebra3.Tpo -c -o libglui_a-algebra3.obj `if test -f 'glui/algebra3.cpp'; then $(CYGPATH_W) 'glui/algebra3.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/algebra3.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-algebra3.Tpo $(DEPDIR)/libglui_a-algebra3.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/algebra3.cpp' object='libglui_a-algebra3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-algebra3.obj `if test -f 'glui/algebra3.cpp'; then $(CYGPATH_W) 'glui/algebra3.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/algebra3.cpp'; fi` + +libglui_a-glui_string.o: glui/glui_string.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_string.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_string.Tpo -c -o libglui_a-glui_string.o `test -f 'glui/glui_string.cpp' || echo '$(srcdir)/'`glui/glui_string.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_string.Tpo $(DEPDIR)/libglui_a-glui_string.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_string.cpp' object='libglui_a-glui_string.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_string.o `test -f 'glui/glui_string.cpp' || echo '$(srcdir)/'`glui/glui_string.cpp + +libglui_a-glui_string.obj: glui/glui_string.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_string.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_string.Tpo -c -o libglui_a-glui_string.obj `if test -f 'glui/glui_string.cpp'; then $(CYGPATH_W) 'glui/glui_string.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_string.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_string.Tpo $(DEPDIR)/libglui_a-glui_string.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_string.cpp' object='libglui_a-glui_string.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_string.obj `if test -f 'glui/glui_string.cpp'; then $(CYGPATH_W) 'glui/glui_string.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_string.cpp'; fi` + +libglui_a-glui_button.o: glui/glui_button.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_button.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_button.Tpo -c -o libglui_a-glui_button.o `test -f 'glui/glui_button.cpp' || echo '$(srcdir)/'`glui/glui_button.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_button.Tpo $(DEPDIR)/libglui_a-glui_button.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_button.cpp' object='libglui_a-glui_button.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_button.o `test -f 'glui/glui_button.cpp' || echo '$(srcdir)/'`glui/glui_button.cpp + +libglui_a-glui_button.obj: glui/glui_button.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_button.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_button.Tpo -c -o libglui_a-glui_button.obj `if test -f 'glui/glui_button.cpp'; then $(CYGPATH_W) 'glui/glui_button.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_button.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_button.Tpo $(DEPDIR)/libglui_a-glui_button.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_button.cpp' object='libglui_a-glui_button.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_button.obj `if test -f 'glui/glui_button.cpp'; then $(CYGPATH_W) 'glui/glui_button.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_button.cpp'; fi` + +libglui_a-glui_add_controls.o: glui/glui_add_controls.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_add_controls.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_add_controls.Tpo -c -o libglui_a-glui_add_controls.o `test -f 'glui/glui_add_controls.cpp' || echo '$(srcdir)/'`glui/glui_add_controls.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_add_controls.Tpo $(DEPDIR)/libglui_a-glui_add_controls.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_add_controls.cpp' object='libglui_a-glui_add_controls.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_add_controls.o `test -f 'glui/glui_add_controls.cpp' || echo '$(srcdir)/'`glui/glui_add_controls.cpp + +libglui_a-glui_add_controls.obj: glui/glui_add_controls.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_add_controls.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_add_controls.Tpo -c -o libglui_a-glui_add_controls.obj `if test -f 'glui/glui_add_controls.cpp'; then $(CYGPATH_W) 'glui/glui_add_controls.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_add_controls.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_add_controls.Tpo $(DEPDIR)/libglui_a-glui_add_controls.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_add_controls.cpp' object='libglui_a-glui_add_controls.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_add_controls.obj `if test -f 'glui/glui_add_controls.cpp'; then $(CYGPATH_W) 'glui/glui_add_controls.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_add_controls.cpp'; fi` + +libglui_a-glui_control.o: glui/glui_control.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_control.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_control.Tpo -c -o libglui_a-glui_control.o `test -f 'glui/glui_control.cpp' || echo '$(srcdir)/'`glui/glui_control.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_control.Tpo $(DEPDIR)/libglui_a-glui_control.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_control.cpp' object='libglui_a-glui_control.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_control.o `test -f 'glui/glui_control.cpp' || echo '$(srcdir)/'`glui/glui_control.cpp + +libglui_a-glui_control.obj: glui/glui_control.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_control.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_control.Tpo -c -o libglui_a-glui_control.obj `if test -f 'glui/glui_control.cpp'; then $(CYGPATH_W) 'glui/glui_control.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_control.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_control.Tpo $(DEPDIR)/libglui_a-glui_control.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_control.cpp' object='libglui_a-glui_control.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_control.obj `if test -f 'glui/glui_control.cpp'; then $(CYGPATH_W) 'glui/glui_control.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_control.cpp'; fi` + +libglui_a-glui.o: glui/glui.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui.o -MD -MP -MF $(DEPDIR)/libglui_a-glui.Tpo -c -o libglui_a-glui.o `test -f 'glui/glui.cpp' || echo '$(srcdir)/'`glui/glui.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui.Tpo $(DEPDIR)/libglui_a-glui.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui.cpp' object='libglui_a-glui.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui.o `test -f 'glui/glui.cpp' || echo '$(srcdir)/'`glui/glui.cpp + +libglui_a-glui.obj: glui/glui.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui.Tpo -c -o libglui_a-glui.obj `if test -f 'glui/glui.cpp'; then $(CYGPATH_W) 'glui/glui.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui.Tpo $(DEPDIR)/libglui_a-glui.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui.cpp' object='libglui_a-glui.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui.obj `if test -f 'glui/glui.cpp'; then $(CYGPATH_W) 'glui/glui.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui.cpp'; fi` + +libglui_a-glui_listbox.o: glui/glui_listbox.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_listbox.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_listbox.Tpo -c -o libglui_a-glui_listbox.o `test -f 'glui/glui_listbox.cpp' || echo '$(srcdir)/'`glui/glui_listbox.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_listbox.Tpo $(DEPDIR)/libglui_a-glui_listbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_listbox.cpp' object='libglui_a-glui_listbox.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_listbox.o `test -f 'glui/glui_listbox.cpp' || echo '$(srcdir)/'`glui/glui_listbox.cpp + +libglui_a-glui_listbox.obj: glui/glui_listbox.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_listbox.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_listbox.Tpo -c -o libglui_a-glui_listbox.obj `if test -f 'glui/glui_listbox.cpp'; then $(CYGPATH_W) 'glui/glui_listbox.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_listbox.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_listbox.Tpo $(DEPDIR)/libglui_a-glui_listbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_listbox.cpp' object='libglui_a-glui_listbox.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_listbox.obj `if test -f 'glui/glui_listbox.cpp'; then $(CYGPATH_W) 'glui/glui_listbox.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_listbox.cpp'; fi` + +libglui_a-glui_checkbox.o: glui/glui_checkbox.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_checkbox.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_checkbox.Tpo -c -o libglui_a-glui_checkbox.o `test -f 'glui/glui_checkbox.cpp' || echo '$(srcdir)/'`glui/glui_checkbox.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_checkbox.Tpo $(DEPDIR)/libglui_a-glui_checkbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_checkbox.cpp' object='libglui_a-glui_checkbox.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_checkbox.o `test -f 'glui/glui_checkbox.cpp' || echo '$(srcdir)/'`glui/glui_checkbox.cpp + +libglui_a-glui_checkbox.obj: glui/glui_checkbox.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_checkbox.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_checkbox.Tpo -c -o libglui_a-glui_checkbox.obj `if test -f 'glui/glui_checkbox.cpp'; then $(CYGPATH_W) 'glui/glui_checkbox.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_checkbox.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_checkbox.Tpo $(DEPDIR)/libglui_a-glui_checkbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_checkbox.cpp' object='libglui_a-glui_checkbox.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_checkbox.obj `if test -f 'glui/glui_checkbox.cpp'; then $(CYGPATH_W) 'glui/glui_checkbox.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_checkbox.cpp'; fi` + +libglui_a-glui_commandline.o: glui/glui_commandline.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_commandline.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_commandline.Tpo -c -o libglui_a-glui_commandline.o `test -f 'glui/glui_commandline.cpp' || echo '$(srcdir)/'`glui/glui_commandline.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_commandline.Tpo $(DEPDIR)/libglui_a-glui_commandline.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_commandline.cpp' object='libglui_a-glui_commandline.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_commandline.o `test -f 'glui/glui_commandline.cpp' || echo '$(srcdir)/'`glui/glui_commandline.cpp + +libglui_a-glui_commandline.obj: glui/glui_commandline.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_commandline.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_commandline.Tpo -c -o libglui_a-glui_commandline.obj `if test -f 'glui/glui_commandline.cpp'; then $(CYGPATH_W) 'glui/glui_commandline.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_commandline.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_commandline.Tpo $(DEPDIR)/libglui_a-glui_commandline.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_commandline.cpp' object='libglui_a-glui_commandline.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_commandline.obj `if test -f 'glui/glui_commandline.cpp'; then $(CYGPATH_W) 'glui/glui_commandline.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_commandline.cpp'; fi` + +libglui_a-glui_textbox.o: glui/glui_textbox.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_textbox.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_textbox.Tpo -c -o libglui_a-glui_textbox.o `test -f 'glui/glui_textbox.cpp' || echo '$(srcdir)/'`glui/glui_textbox.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_textbox.Tpo $(DEPDIR)/libglui_a-glui_textbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_textbox.cpp' object='libglui_a-glui_textbox.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_textbox.o `test -f 'glui/glui_textbox.cpp' || echo '$(srcdir)/'`glui/glui_textbox.cpp + +libglui_a-glui_textbox.obj: glui/glui_textbox.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_textbox.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_textbox.Tpo -c -o libglui_a-glui_textbox.obj `if test -f 'glui/glui_textbox.cpp'; then $(CYGPATH_W) 'glui/glui_textbox.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_textbox.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_textbox.Tpo $(DEPDIR)/libglui_a-glui_textbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_textbox.cpp' object='libglui_a-glui_textbox.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_textbox.obj `if test -f 'glui/glui_textbox.cpp'; then $(CYGPATH_W) 'glui/glui_textbox.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_textbox.cpp'; fi` + +libglui_a-glui_column.o: glui/glui_column.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_column.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_column.Tpo -c -o libglui_a-glui_column.o `test -f 'glui/glui_column.cpp' || echo '$(srcdir)/'`glui/glui_column.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_column.Tpo $(DEPDIR)/libglui_a-glui_column.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_column.cpp' object='libglui_a-glui_column.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_column.o `test -f 'glui/glui_column.cpp' || echo '$(srcdir)/'`glui/glui_column.cpp + +libglui_a-glui_column.obj: glui/glui_column.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_column.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_column.Tpo -c -o libglui_a-glui_column.obj `if test -f 'glui/glui_column.cpp'; then $(CYGPATH_W) 'glui/glui_column.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_column.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_column.Tpo $(DEPDIR)/libglui_a-glui_column.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_column.cpp' object='libglui_a-glui_column.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_column.obj `if test -f 'glui/glui_column.cpp'; then $(CYGPATH_W) 'glui/glui_column.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_column.cpp'; fi` + +libglui_a-glui_mouse_iaction.o: glui/glui_mouse_iaction.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_mouse_iaction.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_mouse_iaction.Tpo -c -o libglui_a-glui_mouse_iaction.o `test -f 'glui/glui_mouse_iaction.cpp' || echo '$(srcdir)/'`glui/glui_mouse_iaction.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_mouse_iaction.Tpo $(DEPDIR)/libglui_a-glui_mouse_iaction.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_mouse_iaction.cpp' object='libglui_a-glui_mouse_iaction.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_mouse_iaction.o `test -f 'glui/glui_mouse_iaction.cpp' || echo '$(srcdir)/'`glui/glui_mouse_iaction.cpp + +libglui_a-glui_mouse_iaction.obj: glui/glui_mouse_iaction.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_mouse_iaction.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_mouse_iaction.Tpo -c -o libglui_a-glui_mouse_iaction.obj `if test -f 'glui/glui_mouse_iaction.cpp'; then $(CYGPATH_W) 'glui/glui_mouse_iaction.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_mouse_iaction.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_mouse_iaction.Tpo $(DEPDIR)/libglui_a-glui_mouse_iaction.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_mouse_iaction.cpp' object='libglui_a-glui_mouse_iaction.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_mouse_iaction.obj `if test -f 'glui/glui_mouse_iaction.cpp'; then $(CYGPATH_W) 'glui/glui_mouse_iaction.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_mouse_iaction.cpp'; fi` + +libglui_a-glui_radio.o: glui/glui_radio.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_radio.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_radio.Tpo -c -o libglui_a-glui_radio.o `test -f 'glui/glui_radio.cpp' || echo '$(srcdir)/'`glui/glui_radio.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_radio.Tpo $(DEPDIR)/libglui_a-glui_radio.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_radio.cpp' object='libglui_a-glui_radio.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_radio.o `test -f 'glui/glui_radio.cpp' || echo '$(srcdir)/'`glui/glui_radio.cpp + +libglui_a-glui_radio.obj: glui/glui_radio.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_radio.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_radio.Tpo -c -o libglui_a-glui_radio.obj `if test -f 'glui/glui_radio.cpp'; then $(CYGPATH_W) 'glui/glui_radio.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_radio.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_radio.Tpo $(DEPDIR)/libglui_a-glui_radio.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_radio.cpp' object='libglui_a-glui_radio.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_radio.obj `if test -f 'glui/glui_radio.cpp'; then $(CYGPATH_W) 'glui/glui_radio.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_radio.cpp'; fi` + +libglui_a-glui_translation.o: glui/glui_translation.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_translation.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_translation.Tpo -c -o libglui_a-glui_translation.o `test -f 'glui/glui_translation.cpp' || echo '$(srcdir)/'`glui/glui_translation.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_translation.Tpo $(DEPDIR)/libglui_a-glui_translation.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_translation.cpp' object='libglui_a-glui_translation.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_translation.o `test -f 'glui/glui_translation.cpp' || echo '$(srcdir)/'`glui/glui_translation.cpp + +libglui_a-glui_translation.obj: glui/glui_translation.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_translation.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_translation.Tpo -c -o libglui_a-glui_translation.obj `if test -f 'glui/glui_translation.cpp'; then $(CYGPATH_W) 'glui/glui_translation.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_translation.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_translation.Tpo $(DEPDIR)/libglui_a-glui_translation.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_translation.cpp' object='libglui_a-glui_translation.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_translation.obj `if test -f 'glui/glui_translation.cpp'; then $(CYGPATH_W) 'glui/glui_translation.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_translation.cpp'; fi` + +libglui_a-glui_tree.o: glui/glui_tree.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_tree.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_tree.Tpo -c -o libglui_a-glui_tree.o `test -f 'glui/glui_tree.cpp' || echo '$(srcdir)/'`glui/glui_tree.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_tree.Tpo $(DEPDIR)/libglui_a-glui_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_tree.cpp' object='libglui_a-glui_tree.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_tree.o `test -f 'glui/glui_tree.cpp' || echo '$(srcdir)/'`glui/glui_tree.cpp + +libglui_a-glui_tree.obj: glui/glui_tree.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_tree.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_tree.Tpo -c -o libglui_a-glui_tree.obj `if test -f 'glui/glui_tree.cpp'; then $(CYGPATH_W) 'glui/glui_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_tree.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_tree.Tpo $(DEPDIR)/libglui_a-glui_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_tree.cpp' object='libglui_a-glui_tree.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_tree.obj `if test -f 'glui/glui_tree.cpp'; then $(CYGPATH_W) 'glui/glui_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_tree.cpp'; fi` + +libglui_a-glui_rotation.o: glui/glui_rotation.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_rotation.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_rotation.Tpo -c -o libglui_a-glui_rotation.o `test -f 'glui/glui_rotation.cpp' || echo '$(srcdir)/'`glui/glui_rotation.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_rotation.Tpo $(DEPDIR)/libglui_a-glui_rotation.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_rotation.cpp' object='libglui_a-glui_rotation.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_rotation.o `test -f 'glui/glui_rotation.cpp' || echo '$(srcdir)/'`glui/glui_rotation.cpp + +libglui_a-glui_rotation.obj: glui/glui_rotation.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_rotation.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_rotation.Tpo -c -o libglui_a-glui_rotation.obj `if test -f 'glui/glui_rotation.cpp'; then $(CYGPATH_W) 'glui/glui_rotation.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_rotation.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_rotation.Tpo $(DEPDIR)/libglui_a-glui_rotation.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_rotation.cpp' object='libglui_a-glui_rotation.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_rotation.obj `if test -f 'glui/glui_rotation.cpp'; then $(CYGPATH_W) 'glui/glui_rotation.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_rotation.cpp'; fi` + +libglui_a-glui_panel.o: glui/glui_panel.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_panel.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_panel.Tpo -c -o libglui_a-glui_panel.o `test -f 'glui/glui_panel.cpp' || echo '$(srcdir)/'`glui/glui_panel.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_panel.Tpo $(DEPDIR)/libglui_a-glui_panel.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_panel.cpp' object='libglui_a-glui_panel.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_panel.o `test -f 'glui/glui_panel.cpp' || echo '$(srcdir)/'`glui/glui_panel.cpp + +libglui_a-glui_panel.obj: glui/glui_panel.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_panel.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_panel.Tpo -c -o libglui_a-glui_panel.obj `if test -f 'glui/glui_panel.cpp'; then $(CYGPATH_W) 'glui/glui_panel.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_panel.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_panel.Tpo $(DEPDIR)/libglui_a-glui_panel.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_panel.cpp' object='libglui_a-glui_panel.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_panel.obj `if test -f 'glui/glui_panel.cpp'; then $(CYGPATH_W) 'glui/glui_panel.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_panel.cpp'; fi` + +libglui_a-glui_rollout.o: glui/glui_rollout.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_rollout.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_rollout.Tpo -c -o libglui_a-glui_rollout.o `test -f 'glui/glui_rollout.cpp' || echo '$(srcdir)/'`glui/glui_rollout.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_rollout.Tpo $(DEPDIR)/libglui_a-glui_rollout.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_rollout.cpp' object='libglui_a-glui_rollout.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_rollout.o `test -f 'glui/glui_rollout.cpp' || echo '$(srcdir)/'`glui/glui_rollout.cpp + +libglui_a-glui_rollout.obj: glui/glui_rollout.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_rollout.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_rollout.Tpo -c -o libglui_a-glui_rollout.obj `if test -f 'glui/glui_rollout.cpp'; then $(CYGPATH_W) 'glui/glui_rollout.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_rollout.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_rollout.Tpo $(DEPDIR)/libglui_a-glui_rollout.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_rollout.cpp' object='libglui_a-glui_rollout.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_rollout.obj `if test -f 'glui/glui_rollout.cpp'; then $(CYGPATH_W) 'glui/glui_rollout.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_rollout.cpp'; fi` + +libglui_a-glui_separator.o: glui/glui_separator.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_separator.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_separator.Tpo -c -o libglui_a-glui_separator.o `test -f 'glui/glui_separator.cpp' || echo '$(srcdir)/'`glui/glui_separator.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_separator.Tpo $(DEPDIR)/libglui_a-glui_separator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_separator.cpp' object='libglui_a-glui_separator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_separator.o `test -f 'glui/glui_separator.cpp' || echo '$(srcdir)/'`glui/glui_separator.cpp + +libglui_a-glui_separator.obj: glui/glui_separator.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_separator.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_separator.Tpo -c -o libglui_a-glui_separator.obj `if test -f 'glui/glui_separator.cpp'; then $(CYGPATH_W) 'glui/glui_separator.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_separator.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_separator.Tpo $(DEPDIR)/libglui_a-glui_separator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_separator.cpp' object='libglui_a-glui_separator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_separator.obj `if test -f 'glui/glui_separator.cpp'; then $(CYGPATH_W) 'glui/glui_separator.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_separator.cpp'; fi` + +libglui_a-glui_bitmap_img_data.o: glui/glui_bitmap_img_data.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_bitmap_img_data.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_bitmap_img_data.Tpo -c -o libglui_a-glui_bitmap_img_data.o `test -f 'glui/glui_bitmap_img_data.cpp' || echo '$(srcdir)/'`glui/glui_bitmap_img_data.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_bitmap_img_data.Tpo $(DEPDIR)/libglui_a-glui_bitmap_img_data.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_bitmap_img_data.cpp' object='libglui_a-glui_bitmap_img_data.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_bitmap_img_data.o `test -f 'glui/glui_bitmap_img_data.cpp' || echo '$(srcdir)/'`glui/glui_bitmap_img_data.cpp + +libglui_a-glui_bitmap_img_data.obj: glui/glui_bitmap_img_data.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_bitmap_img_data.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_bitmap_img_data.Tpo -c -o libglui_a-glui_bitmap_img_data.obj `if test -f 'glui/glui_bitmap_img_data.cpp'; then $(CYGPATH_W) 'glui/glui_bitmap_img_data.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_bitmap_img_data.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_bitmap_img_data.Tpo $(DEPDIR)/libglui_a-glui_bitmap_img_data.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_bitmap_img_data.cpp' object='libglui_a-glui_bitmap_img_data.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_bitmap_img_data.obj `if test -f 'glui/glui_bitmap_img_data.cpp'; then $(CYGPATH_W) 'glui/glui_bitmap_img_data.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_bitmap_img_data.cpp'; fi` + +libglui_a-quaternion.o: glui/quaternion.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-quaternion.o -MD -MP -MF $(DEPDIR)/libglui_a-quaternion.Tpo -c -o libglui_a-quaternion.o `test -f 'glui/quaternion.cpp' || echo '$(srcdir)/'`glui/quaternion.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-quaternion.Tpo $(DEPDIR)/libglui_a-quaternion.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/quaternion.cpp' object='libglui_a-quaternion.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-quaternion.o `test -f 'glui/quaternion.cpp' || echo '$(srcdir)/'`glui/quaternion.cpp + +libglui_a-quaternion.obj: glui/quaternion.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-quaternion.obj -MD -MP -MF $(DEPDIR)/libglui_a-quaternion.Tpo -c -o libglui_a-quaternion.obj `if test -f 'glui/quaternion.cpp'; then $(CYGPATH_W) 'glui/quaternion.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/quaternion.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-quaternion.Tpo $(DEPDIR)/libglui_a-quaternion.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/quaternion.cpp' object='libglui_a-quaternion.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-quaternion.obj `if test -f 'glui/quaternion.cpp'; then $(CYGPATH_W) 'glui/quaternion.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/quaternion.cpp'; fi` + +libglui_a-glui_window.o: glui/glui_window.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_window.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_window.Tpo -c -o libglui_a-glui_window.o `test -f 'glui/glui_window.cpp' || echo '$(srcdir)/'`glui/glui_window.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_window.Tpo $(DEPDIR)/libglui_a-glui_window.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_window.cpp' object='libglui_a-glui_window.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_window.o `test -f 'glui/glui_window.cpp' || echo '$(srcdir)/'`glui/glui_window.cpp + +libglui_a-glui_window.obj: glui/glui_window.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_window.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_window.Tpo -c -o libglui_a-glui_window.obj `if test -f 'glui/glui_window.cpp'; then $(CYGPATH_W) 'glui/glui_window.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_window.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_window.Tpo $(DEPDIR)/libglui_a-glui_window.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_window.cpp' object='libglui_a-glui_window.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_window.obj `if test -f 'glui/glui_window.cpp'; then $(CYGPATH_W) 'glui/glui_window.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_window.cpp'; fi` + +libglui_a-glui_list.o: glui/glui_list.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_list.o -MD -MP -MF $(DEPDIR)/libglui_a-glui_list.Tpo -c -o libglui_a-glui_list.o `test -f 'glui/glui_list.cpp' || echo '$(srcdir)/'`glui/glui_list.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_list.Tpo $(DEPDIR)/libglui_a-glui_list.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_list.cpp' object='libglui_a-glui_list.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_list.o `test -f 'glui/glui_list.cpp' || echo '$(srcdir)/'`glui/glui_list.cpp + +libglui_a-glui_list.obj: glui/glui_list.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -MT libglui_a-glui_list.obj -MD -MP -MF $(DEPDIR)/libglui_a-glui_list.Tpo -c -o libglui_a-glui_list.obj `if test -f 'glui/glui_list.cpp'; then $(CYGPATH_W) 'glui/glui_list.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_list.cpp'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libglui_a-glui_list.Tpo $(DEPDIR)/libglui_a-glui_list.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='glui/glui_list.cpp' object='libglui_a-glui_list.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglui_a_CXXFLAGS) $(CXXFLAGS) -c -o libglui_a-glui_list.obj `if test -f 'glui/glui_list.cpp'; then $(CYGPATH_W) 'glui/glui_list.cpp'; else $(CYGPATH_W) '$(srcdir)/glui/glui_list.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Extras/Serialize/BlenderSerialize/CMakeLists.txt b/Extras/Serialize/BlenderSerialize/CMakeLists.txt new file mode 100644 index 0000000..5b74d74 --- /dev/null +++ b/Extras/Serialize/BlenderSerialize/CMakeLists.txt @@ -0,0 +1,7 @@ +INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/src +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BlenderSerialize +) + +ADD_LIBRARY(BlenderSerialize dna249.cpp dna249-64bit.cpp bBlenderFile.cpp bBlenderFile.h bMain.cpp bMain.h ) diff --git a/Extras/Serialize/BlenderSerialize/bBlenderFile.cpp b/Extras/Serialize/BlenderSerialize/bBlenderFile.cpp new file mode 100644 index 0000000..9405fe1 --- /dev/null +++ b/Extras/Serialize/BlenderSerialize/bBlenderFile.cpp @@ -0,0 +1,225 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "bBlenderFile.h" +#include "bMain.h" +#include "bDefines.h" +#include "bDNA.h" +#include +#include + +// 32 && 64 bit versions +extern unsigned char DNAstr[]; +extern int DNAlen; + +extern unsigned char DNAstr64[]; +extern int DNAlen64; + + +using namespace bParse; + +bBlenderFile::bBlenderFile(const char* fileName) +:bFile(fileName, "BLENDER") +{ + mMain= new bMain(this, fileName, mVersion); +} + + + +bBlenderFile::bBlenderFile(char *memoryBuffer, int len) +:bFile(memoryBuffer,len, "BLENDER"), +mMain(0) +{ + mMain= new bMain(this, "memoryBuf", mVersion); +} + + +bBlenderFile::~bBlenderFile() +{ + delete mMain; +} + + +bMain* bBlenderFile::getMain() +{ + return mMain; +} + +// ----------------------------------------------------- // +void bBlenderFile::parseData() +{ +// printf ("Building datablocks\n"); +// printf ("Chunk size = %d\n",CHUNK_HEADER_LEN); +// printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags)); + + const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0; + + + + char *dataPtr = mFileBuffer+mDataStart; + + bChunkInd dataChunk; + dataChunk.code = 0; + + + //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); + int seek = getNextBlock(&dataChunk, dataPtr, mFlags); + //dataPtr += ChunkUtils::getOffset(mFlags); + char *dataPtrHead = 0; + + while (dataChunk.code != DNA1) + { + + + + + // one behind + if (dataChunk.code == SDNA) break; + //if (dataChunk.code == DNA1) break; + + // same as (BHEAD+DATA dependency) + dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); + char *id = readStruct(dataPtrHead, dataChunk); + + // lookup maps + if (id) + { + m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk); + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id); + + m_chunks.push_back(dataChunk); + // block it + bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code); + if (listID) + listID->push_back((bStructHandle*)id); + } + + if (dataChunk.code == GLOB) + { + m_glob = (bStructHandle*) id; + } + + // next please! + dataPtr += seek; + + seek = getNextBlock(&dataChunk, dataPtr, mFlags); + if (seek < 0) + break; + } + +} + +void bBlenderFile::addDataBlock(char* dataBlock) +{ + mMain->addDatablock(dataBlock); +} + + + + + +// 32 && 64 bit versions +extern unsigned char DNAstr[]; +extern int DNAlen; + +//unsigned char DNAstr[]={0}; +//int DNAlen=0; + + +extern unsigned char DNAstr64[]; +extern int DNAlen64; + + +void bBlenderFile::writeDNA(FILE* fp) +{ + + bChunkInd dataChunk; + dataChunk.code = DNA1; + dataChunk.dna_nr = 0; + dataChunk.nr = 1; + + if (VOID_IS_8) + { + dataChunk.len = DNAlen64; + dataChunk.oldPtr = DNAstr64; + fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + fwrite(DNAstr64, DNAlen64,1,fp); + } + else + { + dataChunk.len = DNAlen; + dataChunk.oldPtr = DNAstr; + fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + fwrite(DNAstr, DNAlen,1,fp); + } +} + +void bBlenderFile::parse(int verboseMode) +{ + if (VOID_IS_8) + { + parseInternal(verboseMode,(char*)DNAstr64,DNAlen64); + } + else + { + parseInternal(verboseMode,(char*)DNAstr,DNAlen); + } +} + +// experimental +int bBlenderFile::write(const char* fileName, bool fixupPointers) +{ + FILE *fp = fopen(fileName, "wb"); + if (fp) + { + char header[SIZEOFBLENDERHEADER] ; + memcpy(header, m_headerString, 7); + int endian= 1; + endian= ((char*)&endian)[0]; + + if (endian) + { + header[7] = '_'; + } else + { + header[7] = '-'; + } + if (VOID_IS_8) + { + header[8]='V'; + } else + { + header[8]='v'; + } + + header[9] = '2'; + header[10] = '4'; + header[11] = '9'; + + fwrite(header,SIZEOFBLENDERHEADER,1,fp); + + writeChunks(fp, fixupPointers); + + writeDNA(fp); + + fclose(fp); + + } else + { + printf("Error: cannot open file %s for writing\n",fileName); + return 0; + } + return 1; +} \ No newline at end of file diff --git a/Extras/Serialize/BlenderSerialize/bBlenderFile.h b/Extras/Serialize/BlenderSerialize/bBlenderFile.h new file mode 100644 index 0000000..3c163b9 --- /dev/null +++ b/Extras/Serialize/BlenderSerialize/bBlenderFile.h @@ -0,0 +1,63 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B_BLENDER_FILE_H +#define B_BLENDER_FILE_H + + +#include "bFile.h" + +namespace bParse { + + // ----------------------------------------------------- // + class bBlenderFile : public bFile + { + + protected: + bMain* mMain; + + bStructHandle* m_glob; + + + public: + + bBlenderFile(const char* fileName); + + bBlenderFile(char *memoryBuffer, int len); + + virtual ~bBlenderFile(); + + bMain* getMain(); + + virtual void addDataBlock(char* dataBlock); + + bStructHandle* getFileGlobal() + { + return m_glob; + } + + // experimental + virtual int write(const char* fileName, bool fixupPointers = false); + + virtual void parse(int verboseMode); + + virtual void parseData(); + + virtual void writeDNA(FILE* fp); + + }; +}; + +#endif //B_BLENDER_FILE_H diff --git a/Extras/Serialize/BlenderSerialize/bMain.cpp b/Extras/Serialize/BlenderSerialize/bMain.cpp new file mode 100644 index 0000000..fa672fb --- /dev/null +++ b/Extras/Serialize/BlenderSerialize/bMain.cpp @@ -0,0 +1,392 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "bMain.h" +#include "bBlenderFile.h" +#include "bDefines.h" +#include "bChunk.h" +#include "bDNA.h" + +using namespace bParse; + + +// ----------------------------------------------------- // +bMain::bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion) + : mFP(filePtr), + mVersion(fileVersion), + mName(baseName) +{ + mData.insert(ID_SCE,bListBasePtr()); + mData.insert(ID_LI,bListBasePtr()); + mData.insert(ID_OB,bListBasePtr()); + mData.insert(ID_ME,bListBasePtr()); + mData.insert(ID_CU,bListBasePtr()); + mData.insert(ID_MB,bListBasePtr()); + mData.insert(ID_MA,bListBasePtr()); + mData.insert(ID_TE,bListBasePtr()); + mData.insert(ID_IM,bListBasePtr()); + mData.insert(ID_WV,bListBasePtr()); + mData.insert(ID_LT,bListBasePtr()); + mData.insert(ID_LA,bListBasePtr()); + mData.insert(ID_CA,bListBasePtr()); + mData.insert(ID_IP,bListBasePtr()); + mData.insert(ID_KE,bListBasePtr()); + mData.insert(ID_WO,bListBasePtr()); + mData.insert(ID_SCR,bListBasePtr()); + mData.insert(ID_VF,bListBasePtr()); + mData.insert(ID_TXT,bListBasePtr()); + mData.insert(ID_SO,bListBasePtr()); + mData.insert(ID_GR,bListBasePtr()); + mData.insert(ID_AR,bListBasePtr()); + mData.insert(ID_AC,bListBasePtr()); + mData.insert(ID_NT,bListBasePtr()); + mData.insert(ID_BR,bListBasePtr()); + mData.insert(ID_SCRIPT, bListBasePtr()); +} + + +// ----------------------------------------------------- // +bMain::~bMain() +{ + // allocated data blocks! + + int sz = mPool.size(); + for (int i=0;ifirst) + return; + + base->first = mFP->findLibPointer(base->first); + if (!base->first) + { + base->last = 0; + return; + } + + void *prev = 0; + Link *l = (Link*)base->first; + while (l) + { + l->next = mFP->findLibPointer(l->next); + l->prev = l->next; + prev = l->next; + l = (Link*)l->next; + } +} + +// ------------------------------------------------------------// +bListBasePtr* bMain::getListBasePtr(int listBaseCode) +{ + bListBasePtr *ptr = _findCode(listBaseCode); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::_findCode(int code) +{ + + bListBasePtr* lbPtr = mData.find(code); + return lbPtr; +} + + +// ------------------------------------------------------------// +bListBasePtr *bMain::getScene() +{ + bListBasePtr *ptr = _findCode(ID_SCE); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getLibrary() +{ + bListBasePtr *ptr = _findCode(ID_LI); + if (!ptr) + return 0; + return ptr; +} +// ------------------------------------------------------------// +bListBasePtr *bMain::getObject() +{ + bListBasePtr *ptr = _findCode(ID_OB); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getMesh() +{ + bListBasePtr *ptr = _findCode(ID_ME); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getCurve() +{ + bListBasePtr *ptr = _findCode(ID_CU); + if (!ptr) + return 0; + return ptr; +} + + + +// ------------------------------------------------------------// +bListBasePtr *bMain::getMball() +{ + bListBasePtr *ptr = _findCode(ID_MB); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getMat() +{ + bListBasePtr *ptr = _findCode(ID_MA); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getTex() +{ + bListBasePtr *ptr = _findCode(ID_TE); + if (!ptr) + return 0; + return ptr; +} + + +// ------------------------------------------------------------// +bListBasePtr *bMain::getImage() +{ + bListBasePtr *ptr = _findCode(ID_IM); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getWave() +{ + bListBasePtr *ptr = _findCode(ID_WV); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getLatt() +{ + bListBasePtr *ptr = _findCode(ID_LT); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getLamp() +{ + bListBasePtr *ptr = _findCode(ID_LA); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getCamera() +{ + bListBasePtr *ptr = _findCode(ID_CA); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getIpo() +{ + bListBasePtr *ptr = _findCode(ID_IP); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getKey() +{ + bListBasePtr *ptr = _findCode(ID_KE); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getWorld() +{ + bListBasePtr *ptr = _findCode(ID_WO); + if (!ptr) + return 0; + return ptr; +} + + +// ------------------------------------------------------------// +bListBasePtr *bMain::getScreen() +{ + bListBasePtr *ptr = _findCode(ID_SCR); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getScript() +{ + bListBasePtr *ptr = _findCode(ID_SCRIPT); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getVfont() +{ + bListBasePtr *ptr = _findCode(ID_VF); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getText() +{ + bListBasePtr *ptr = _findCode(ID_TXT); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getSound() +{ + bListBasePtr *ptr = _findCode(ID_SO); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getGroup() +{ + bListBasePtr *ptr = _findCode(ID_GR); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getArmature() +{ + bListBasePtr *ptr = _findCode(ID_AR); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getAction() +{ + bListBasePtr *ptr = _findCode(ID_AC); + if (!ptr) + return 0; + return ptr; +} + + +// ------------------------------------------------------------// +bListBasePtr *bMain::getNodetree() +{ + bListBasePtr *ptr = _findCode(ID_NT); + if (!ptr) + return 0; + return ptr; +} + +// ------------------------------------------------------------// +bListBasePtr *bMain::getBrush() +{ + bListBasePtr *ptr = _findCode(ID_BR); + if (!ptr) + return 0; + return ptr; +} + + + +//eof diff --git a/Extras/Serialize/BlenderSerialize/bMain.h b/Extras/Serialize/BlenderSerialize/bMain.h new file mode 100644 index 0000000..f8e9afc --- /dev/null +++ b/Extras/Serialize/BlenderSerialize/bMain.h @@ -0,0 +1,110 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BMAIN_H__ +#define __BMAIN_H__ + +#include "bCommon.h" +#include "bChunk.h" +#include "LinearMath/btHashMap.h" + + +namespace bParse +{ + class bDNA; + + class bBlenderFile; +}; + + + +namespace bParse { + + + // ----------------------------------------------------- // + + typedef btHashMap bMainDataMap; + + + + // ----------------------------------------------------- // + class bMain + { + //private: + public: + bBlenderFile* mFP; + bListBasePtr mPool; + + int mVersion; + const char* mName; + + bMainDataMap mData; + + + + + bListBasePtr *_findCode(int code); + + public: + bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion); + ~bMain(); + + int getVersion(); + const char *getName(); + + bListBasePtr *getListBasePtr(int listBaseCode); + + + bListBasePtr *getScene(); + bListBasePtr *getLibrary(); + bListBasePtr *getObject(); + bListBasePtr *getMesh(); + bListBasePtr *getCurve(); + bListBasePtr *getMball(); + bListBasePtr *getMat(); + bListBasePtr *getTex(); + bListBasePtr *getImage(); + bListBasePtr *getWave(); + bListBasePtr *getLatt(); + bListBasePtr *getLamp(); + bListBasePtr *getCamera(); + bListBasePtr *getIpo(); + bListBasePtr *getKey(); + bListBasePtr *getWorld(); + bListBasePtr *getScreen(); + bListBasePtr *getScript(); + bListBasePtr *getVfont(); + bListBasePtr *getText(); + bListBasePtr *getSound(); + bListBasePtr *getGroup(); + bListBasePtr *getArmature(); + bListBasePtr *getAction(); + bListBasePtr *getNodetree(); + bListBasePtr *getBrush(); + + + + // tracking allocated memory + void addDatablock(void *allocated); + + + // -- + + void linkList(void *listBasePtr); + }; +} + + +#endif//__BMAIN_H__ diff --git a/Extras/Serialize/BlenderSerialize/dna249-64bit.cpp b/Extras/Serialize/BlenderSerialize/dna249-64bit.cpp new file mode 100644 index 0000000..7c56c2c --- /dev/null +++ b/Extras/Serialize/BlenderSerialize/dna249-64bit.cpp @@ -0,0 +1,1411 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +unsigned char DNAstr64[]= { +83,68,78,65,78,65,77,69,119,9,0,0,42,110,101,120,116,0,42,112,114,101,118,0,42,100,97,116,97,0,42,102,105, +114,115,116,0,42,108,97,115,116,0,120,0,121,0,122,0,119,0,120,109,105,110,0,120,109,97,120,0,121,109,105,110, +0,121,109,97,120,0,42,112,111,105,110,116,101,114,0,103,114,111,117,112,0,118,97,108,0,118,97,108,50,0,110,97, +109,101,91,51,50,93,0,116,121,112,101,0,115,117,98,116,121,112,101,0,102,108,97,103,0,115,97,118,101,100,0,100, +97,116,97,0,108,101,110,0,116,111,116,97,108,108,101,110,0,42,110,101,119,105,100,0,42,108,105,98,0,110,97,109, +101,91,50,52,93,0,117,115,0,105,99,111,110,95,105,100,0,42,112,114,111,112,101,114,116,105,101,115,0,105,100,0, +42,105,100,98,108,111,99,107,0,42,102,105,108,101,100,97,116,97,0,110,97,109,101,91,50,52,48,93,0,102,105,108, +101,110,97,109,101,91,50,52,48,93,0,116,111,116,0,112,97,100,0,42,112,97,114,101,110,116,0,119,91,50,93,0, +104,91,50,93,0,99,104,97,110,103,101,100,91,50,93,0,112,97,100,48,0,112,97,100,49,0,42,114,101,99,116,91, +50,93,0,42,111,98,0,98,108,111,99,107,116,121,112,101,0,97,100,114,99,111,100,101,0,110,97,109,101,91,49,50, +56,93,0,42,98,112,0,42,98,101,122,116,0,109,97,120,114,99,116,0,116,111,116,114,99,116,0,118,97,114,116,121, +112,101,0,116,111,116,118,101,114,116,0,105,112,111,0,101,120,116,114,97,112,0,114,116,0,98,105,116,109,97,115,107, +0,115,108,105,100,101,95,109,105,110,0,115,108,105,100,101,95,109,97,120,0,99,117,114,118,97,108,0,42,100,114,105, +118,101,114,0,99,117,114,118,101,0,99,117,114,0,115,104,111,119,107,101,121,0,109,117,116,101,105,112,111,0,112,111, +115,0,114,101,108,97,116,105,118,101,0,116,111,116,101,108,101,109,0,112,97,100,50,0,42,119,101,105,103,104,116,115, +0,118,103,114,111,117,112,91,51,50,93,0,115,108,105,100,101,114,109,105,110,0,115,108,105,100,101,114,109,97,120,0, +42,114,101,102,107,101,121,0,101,108,101,109,115,116,114,91,51,50,93,0,101,108,101,109,115,105,122,101,0,98,108,111, +99,107,0,42,105,112,111,0,42,102,114,111,109,0,116,111,116,107,101,121,0,115,108,117,114,112,104,0,42,42,115,99, +114,105,112,116,115,0,42,102,108,97,103,0,97,99,116,115,99,114,105,112,116,0,116,111,116,115,99,114,105,112,116,0, +42,108,105,110,101,0,42,102,111,114,109,97,116,0,98,108,101,110,0,108,105,110,101,110,111,0,115,116,97,114,116,0, +101,110,100,0,102,108,97,103,115,0,99,111,108,111,114,91,52,93,0,112,97,100,91,52,93,0,42,110,97,109,101,0, +110,108,105,110,101,115,0,108,105,110,101,115,0,42,99,117,114,108,0,42,115,101,108,108,0,99,117,114,99,0,115,101, +108,99,0,109,97,114,107,101,114,115,0,42,117,110,100,111,95,98,117,102,0,117,110,100,111,95,112,111,115,0,117,110, +100,111,95,108,101,110,0,42,99,111,109,112,105,108,101,100,0,109,116,105,109,101,0,115,105,122,101,0,115,101,101,107, +0,112,97,115,115,101,112,97,114,116,97,108,112,104,97,0,97,110,103,108,101,0,99,108,105,112,115,116,97,0,99,108, +105,112,101,110,100,0,108,101,110,115,0,111,114,116,104,111,95,115,99,97,108,101,0,100,114,97,119,115,105,122,101,0, +115,104,105,102,116,120,0,115,104,105,102,116,121,0,89,70,95,100,111,102,100,105,115,116,0,89,70,95,97,112,101,114, +116,117,114,101,0,89,70,95,98,107,104,116,121,112,101,0,89,70,95,98,107,104,98,105,97,115,0,89,70,95,98,107, +104,114,111,116,0,115,99,114,105,112,116,108,105,110,107,0,42,100,111,102,95,111,98,0,102,114,97,109,101,110,114,0, +102,114,97,109,101,115,0,111,102,102,115,101,116,0,115,102,114,97,0,102,105,101,95,105,109,97,0,99,121,99,108,0, +111,107,0,109,117,108,116,105,95,105,110,100,101,120,0,108,97,121,101,114,0,112,97,115,115,0,109,101,110,117,110,114, +0,105,98,117,102,115,0,42,103,112,117,116,101,120,116,117,114,101,0,42,97,110,105,109,0,42,114,114,0,115,111,117, +114,99,101,0,108,97,115,116,102,114,97,109,101,0,116,112,97,103,101,102,108,97,103,0,116,111,116,98,105,110,100,0, +120,114,101,112,0,121,114,101,112,0,116,119,115,116,97,0,116,119,101,110,100,0,98,105,110,100,99,111,100,101,0,42, +114,101,112,98,105,110,100,0,42,112,97,99,107,101,100,102,105,108,101,0,42,112,114,101,118,105,101,119,0,108,97,115, +116,117,112,100,97,116,101,0,108,97,115,116,117,115,101,100,0,97,110,105,109,115,112,101,101,100,0,103,101,110,95,120, +0,103,101,110,95,121,0,103,101,110,95,116,121,112,101,0,97,115,112,120,0,97,115,112,121,0,42,118,110,111,100,101, +0,116,101,120,99,111,0,109,97,112,116,111,0,109,97,112,116,111,110,101,103,0,98,108,101,110,100,116,121,112,101,0, +42,111,98,106,101,99,116,0,42,116,101,120,0,117,118,110,97,109,101,91,51,50,93,0,112,114,111,106,120,0,112,114, +111,106,121,0,112,114,111,106,122,0,109,97,112,112,105,110,103,0,111,102,115,91,51,93,0,115,105,122,101,91,51,93, +0,116,101,120,102,108,97,103,0,99,111,108,111,114,109,111,100,101,108,0,112,109,97,112,116,111,0,112,109,97,112,116, +111,110,101,103,0,110,111,114,109,97,112,115,112,97,99,101,0,119,104,105,99,104,95,111,117,116,112,117,116,0,112,97, +100,91,50,93,0,114,0,103,0,98,0,107,0,100,101,102,95,118,97,114,0,99,111,108,102,97,99,0,110,111,114,102, +97,99,0,118,97,114,102,97,99,0,100,105,115,112,102,97,99,0,119,97,114,112,102,97,99,0,110,97,109,101,91,49, +54,48,93,0,42,104,97,110,100,108,101,0,42,112,110,97,109,101,0,42,115,116,110,97,109,101,115,0,115,116,121,112, +101,115,0,118,97,114,115,0,42,118,97,114,115,116,114,0,42,114,101,115,117,108,116,0,42,99,102,114,97,0,100,97, +116,97,91,51,50,93,0,40,42,100,111,105,116,41,40,41,0,40,42,105,110,115,116,97,110,99,101,95,105,110,105,116, +41,40,41,0,40,42,99,97,108,108,98,97,99,107,41,40,41,0,118,101,114,115,105,111,110,0,97,0,105,112,111,116, +121,112,101,0,42,105,109,97,0,42,99,117,98,101,91,54,93,0,105,109,97,116,91,52,93,91,52,93,0,111,98,105, +109,97,116,91,51,93,91,51,93,0,115,116,121,112,101,0,118,105,101,119,115,99,97,108,101,0,110,111,116,108,97,121, +0,99,117,98,101,114,101,115,0,100,101,112,116,104,0,114,101,99,97,108,99,0,108,97,115,116,115,105,122,101,0,110, +111,105,115,101,115,105,122,101,0,116,117,114,98,117,108,0,98,114,105,103,104,116,0,99,111,110,116,114,97,115,116,0, +114,102,97,99,0,103,102,97,99,0,98,102,97,99,0,102,105,108,116,101,114,115,105,122,101,0,109,103,95,72,0,109, +103,95,108,97,99,117,110,97,114,105,116,121,0,109,103,95,111,99,116,97,118,101,115,0,109,103,95,111,102,102,115,101, +116,0,109,103,95,103,97,105,110,0,100,105,115,116,95,97,109,111,117,110,116,0,110,115,95,111,117,116,115,99,97,108, +101,0,118,110,95,119,49,0,118,110,95,119,50,0,118,110,95,119,51,0,118,110,95,119,52,0,118,110,95,109,101,120, +112,0,118,110,95,100,105,115,116,109,0,118,110,95,99,111,108,116,121,112,101,0,110,111,105,115,101,100,101,112,116,104, +0,110,111,105,115,101,116,121,112,101,0,110,111,105,115,101,98,97,115,105,115,0,110,111,105,115,101,98,97,115,105,115, +50,0,105,109,97,102,108,97,103,0,99,114,111,112,120,109,105,110,0,99,114,111,112,121,109,105,110,0,99,114,111,112, +120,109,97,120,0,99,114,111,112,121,109,97,120,0,120,114,101,112,101,97,116,0,121,114,101,112,101,97,116,0,101,120, +116,101,110,100,0,99,104,101,99,107,101,114,100,105,115,116,0,110,97,98,108,97,0,105,117,115,101,114,0,42,110,111, +100,101,116,114,101,101,0,42,112,108,117,103,105,110,0,42,99,111,98,97,0,42,101,110,118,0,117,115,101,95,110,111, +100,101,115,0,112,97,100,91,55,93,0,108,111,99,91,51,93,0,114,111,116,91,51,93,0,109,97,116,91,52,93,91, +52,93,0,109,105,110,91,51,93,0,109,97,120,91,51,93,0,112,97,100,51,0,109,111,100,101,0,116,111,116,101,120, +0,115,104,100,119,114,0,115,104,100,119,103,0,115,104,100,119,98,0,115,104,100,119,112,97,100,0,101,110,101,114,103, +121,0,100,105,115,116,0,115,112,111,116,115,105,122,101,0,115,112,111,116,98,108,101,110,100,0,104,97,105,110,116,0, +97,116,116,49,0,97,116,116,50,0,42,99,117,114,102,97,108,108,111,102,102,0,102,97,108,108,111,102,102,95,116,121, +112,101,0,115,104,97,100,115,112,111,116,115,105,122,101,0,98,105,97,115,0,115,111,102,116,0,98,117,102,115,105,122, +101,0,115,97,109,112,0,98,117,102,102,101,114,115,0,102,105,108,116,101,114,116,121,112,101,0,98,117,102,102,108,97, +103,0,98,117,102,116,121,112,101,0,114,97,121,95,115,97,109,112,0,114,97,121,95,115,97,109,112,121,0,114,97,121, +95,115,97,109,112,122,0,114,97,121,95,115,97,109,112,95,116,121,112,101,0,97,114,101,97,95,115,104,97,112,101,0, +97,114,101,97,95,115,105,122,101,0,97,114,101,97,95,115,105,122,101,121,0,97,114,101,97,95,115,105,122,101,122,0, +97,100,97,112,116,95,116,104,114,101,115,104,0,114,97,121,95,115,97,109,112,95,109,101,116,104,111,100,0,116,101,120, +97,99,116,0,115,104,97,100,104,97,108,111,115,116,101,112,0,115,117,110,95,101,102,102,101,99,116,95,116,121,112,101, +0,115,107,121,98,108,101,110,100,116,121,112,101,0,104,111,114,105,122,111,110,95,98,114,105,103,104,116,110,101,115,115, +0,115,112,114,101,97,100,0,115,117,110,95,98,114,105,103,104,116,110,101,115,115,0,115,117,110,95,115,105,122,101,0, +98,97,99,107,115,99,97,116,116,101,114,101,100,95,108,105,103,104,116,0,115,117,110,95,105,110,116,101,110,115,105,116, +121,0,97,116,109,95,116,117,114,98,105,100,105,116,121,0,97,116,109,95,105,110,115,99,97,116,116,101,114,105,110,103, +95,102,97,99,116,111,114,0,97,116,109,95,101,120,116,105,110,99,116,105,111,110,95,102,97,99,116,111,114,0,97,116, +109,95,100,105,115,116,97,110,99,101,95,102,97,99,116,111,114,0,115,107,121,98,108,101,110,100,102,97,99,0,115,107, +121,95,101,120,112,111,115,117,114,101,0,115,107,121,95,99,111,108,111,114,115,112,97,99,101,0,112,97,100,52,0,89, +70,95,110,117,109,112,104,111,116,111,110,115,0,89,70,95,110,117,109,115,101,97,114,99,104,0,89,70,95,112,104,100, +101,112,116,104,0,89,70,95,117,115,101,113,109,99,0,89,70,95,98,117,102,115,105,122,101,0,89,70,95,112,97,100, +0,89,70,95,99,97,117,115,116,105,99,98,108,117,114,0,89,70,95,108,116,114,97,100,105,117,115,0,89,70,95,103, +108,111,119,105,110,116,0,89,70,95,103,108,111,119,111,102,115,0,89,70,95,103,108,111,119,116,121,112,101,0,89,70, +95,112,97,100,50,0,42,109,116,101,120,91,49,56,93,0,115,112,101,99,114,0,115,112,101,99,103,0,115,112,101,99, +98,0,109,105,114,114,0,109,105,114,103,0,109,105,114,98,0,97,109,98,114,0,97,109,98,98,0,97,109,98,103,0, +97,109,98,0,101,109,105,116,0,97,110,103,0,115,112,101,99,116,114,97,0,114,97,121,95,109,105,114,114,111,114,0, +97,108,112,104,97,0,114,101,102,0,115,112,101,99,0,122,111,102,102,115,0,97,100,100,0,116,114,97,110,115,108,117, +99,101,110,99,121,0,102,114,101,115,110,101,108,95,109,105,114,0,102,114,101,115,110,101,108,95,109,105,114,95,105,0, +102,114,101,115,110,101,108,95,116,114,97,0,102,114,101,115,110,101,108,95,116,114,97,95,105,0,102,105,108,116,101,114, +0,116,120,95,108,105,109,105,116,0,116,120,95,102,97,108,108,111,102,102,0,114,97,121,95,100,101,112,116,104,0,114, +97,121,95,100,101,112,116,104,95,116,114,97,0,104,97,114,0,115,101,101,100,49,0,115,101,101,100,50,0,103,108,111, +115,115,95,109,105,114,0,103,108,111,115,115,95,116,114,97,0,115,97,109,112,95,103,108,111,115,115,95,109,105,114,0, +115,97,109,112,95,103,108,111,115,115,95,116,114,97,0,97,100,97,112,116,95,116,104,114,101,115,104,95,109,105,114,0, +97,100,97,112,116,95,116,104,114,101,115,104,95,116,114,97,0,97,110,105,115,111,95,103,108,111,115,115,95,109,105,114, +0,100,105,115,116,95,109,105,114,0,102,97,100,101,116,111,95,109,105,114,0,115,104,97,100,101,95,102,108,97,103,0, +109,111,100,101,95,108,0,102,108,97,114,101,99,0,115,116,97,114,99,0,108,105,110,101,99,0,114,105,110,103,99,0, +104,97,115,105,122,101,0,102,108,97,114,101,115,105,122,101,0,115,117,98,115,105,122,101,0,102,108,97,114,101,98,111, +111,115,116,0,115,116,114,97,110,100,95,115,116,97,0,115,116,114,97,110,100,95,101,110,100,0,115,116,114,97,110,100, +95,101,97,115,101,0,115,116,114,97,110,100,95,115,117,114,102,110,111,114,0,115,116,114,97,110,100,95,109,105,110,0, +115,116,114,97,110,100,95,119,105,100,116,104,102,97,100,101,0,115,116,114,97,110,100,95,117,118,110,97,109,101,91,51, +50,93,0,115,98,105,97,115,0,108,98,105,97,115,0,115,104,97,100,95,97,108,112,104,97,0,115,101,112,116,101,120, +0,114,103,98,115,101,108,0,112,114,95,116,121,112,101,0,112,114,95,98,97,99,107,0,112,114,95,108,97,109,112,0, +109,108,95,102,108,97,103,0,100,105,102,102,95,115,104,97,100,101,114,0,115,112,101,99,95,115,104,97,100,101,114,0, +114,111,117,103,104,110,101,115,115,0,114,101,102,114,97,99,0,112,97,114,97,109,91,52,93,0,114,109,115,0,100,97, +114,107,110,101,115,115,0,42,114,97,109,112,95,99,111,108,0,42,114,97,109,112,95,115,112,101,99,0,114,97,109,112, +105,110,95,99,111,108,0,114,97,109,112,105,110,95,115,112,101,99,0,114,97,109,112,98,108,101,110,100,95,99,111,108, +0,114,97,109,112,98,108,101,110,100,95,115,112,101,99,0,114,97,109,112,95,115,104,111,119,0,114,97,109,112,102,97, +99,95,99,111,108,0,114,97,109,112,102,97,99,95,115,112,101,99,0,42,103,114,111,117,112,0,102,114,105,99,116,105, +111,110,0,102,104,0,114,101,102,108,101,99,116,0,102,104,100,105,115,116,0,120,121,102,114,105,99,116,0,100,121,110, +97,109,111,100,101,0,115,115,115,95,114,97,100,105,117,115,91,51,93,0,115,115,115,95,99,111,108,91,51,93,0,115, +115,115,95,101,114,114,111,114,0,115,115,115,95,115,99,97,108,101,0,115,115,115,95,105,111,114,0,115,115,115,95,99, +111,108,102,97,99,0,115,115,115,95,116,101,120,102,97,99,0,115,115,115,95,102,114,111,110,116,0,115,115,115,95,98, +97,99,107,0,115,115,115,95,102,108,97,103,0,115,115,115,95,112,114,101,115,101,116,0,89,70,95,97,114,0,89,70, +95,97,103,0,89,70,95,97,98,0,89,70,95,100,115,99,97,108,101,0,89,70,95,100,112,119,114,0,89,70,95,100, +115,109,112,0,89,70,95,112,114,101,115,101,116,0,89,70,95,100,106,105,116,0,103,112,117,109,97,116,101,114,105,97, +108,0,110,97,109,101,91,50,53,54,93,0,115,99,97,108,101,0,42,98,98,0,105,49,0,106,49,0,107,49,0,105, +50,0,106,50,0,107,50,0,115,101,108,99,111,108,49,0,115,101,108,99,111,108,50,0,113,117,97,116,91,52,93,0, +101,120,112,120,0,101,120,112,121,0,101,120,112,122,0,114,97,100,0,114,97,100,50,0,115,0,42,109,97,116,0,42, +105,109,97,116,0,101,108,101,109,115,0,100,105,115,112,0,42,42,109,97,116,0,116,111,116,99,111,108,0,119,105,114, +101,115,105,122,101,0,114,101,110,100,101,114,115,105,122,101,0,116,104,114,101,115,104,0,118,101,99,91,51,93,91,51, +93,0,97,108,102,97,0,119,101,105,103,104,116,0,114,97,100,105,117,115,0,104,49,0,104,50,0,102,49,0,102,50, +0,102,51,0,104,105,100,101,0,118,101,99,91,52,93,0,109,97,116,95,110,114,0,112,110,116,115,117,0,112,110,116, +115,118,0,114,101,115,111,108,117,0,114,101,115,111,108,118,0,111,114,100,101,114,117,0,111,114,100,101,114,118,0,102, +108,97,103,117,0,102,108,97,103,118,0,42,107,110,111,116,115,117,0,42,107,110,111,116,115,118,0,116,105,108,116,95, +105,110,116,101,114,112,0,114,97,100,105,117,115,95,105,110,116,101,114,112,0,99,104,97,114,105,100,120,0,107,101,114, +110,0,104,0,110,117,114,98,0,42,98,101,118,111,98,106,0,42,116,97,112,101,114,111,98,106,0,42,116,101,120,116, +111,110,99,117,114,118,101,0,42,112,97,116,104,0,42,107,101,121,0,98,101,118,0,112,97,116,104,108,101,110,0,98, +101,118,114,101,115,111,108,0,119,105,100,116,104,0,101,120,116,49,0,101,120,116,50,0,114,101,115,111,108,117,95,114, +101,110,0,114,101,115,111,108,118,95,114,101,110,0,115,112,97,99,101,109,111,100,101,0,115,112,97,99,105,110,103,0, +108,105,110,101,100,105,115,116,0,115,104,101,97,114,0,102,115,105,122,101,0,119,111,114,100,115,112,97,99,101,0,117, +108,112,111,115,0,117,108,104,101,105,103,104,116,0,120,111,102,0,121,111,102,0,108,105,110,101,119,105,100,116,104,0, +42,115,116,114,0,102,97,109,105,108,121,91,50,52,93,0,42,118,102,111,110,116,0,42,118,102,111,110,116,98,0,42, +118,102,111,110,116,105,0,42,118,102,111,110,116,98,105,0,115,101,112,99,104,97,114,0,116,111,116,98,111,120,0,97, +99,116,98,111,120,0,42,116,98,0,115,101,108,115,116,97,114,116,0,115,101,108,101,110,100,0,42,115,116,114,105,110, +102,111,0,99,117,114,105,110,102,111,0,101,102,102,101,99,116,0,42,109,102,97,99,101,0,42,109,116,102,97,99,101, +0,42,116,102,97,99,101,0,42,109,118,101,114,116,0,42,109,101,100,103,101,0,42,100,118,101,114,116,0,42,109,99, +111,108,0,42,109,115,116,105,99,107,121,0,42,116,101,120,99,111,109,101,115,104,0,42,109,115,101,108,101,99,116,0, +118,100,97,116,97,0,101,100,97,116,97,0,102,100,97,116,97,0,116,111,116,101,100,103,101,0,116,111,116,102,97,99, +101,0,116,111,116,115,101,108,101,99,116,0,97,99,116,95,102,97,99,101,0,99,117,98,101,109,97,112,115,105,122,101, +0,115,109,111,111,116,104,114,101,115,104,0,115,117,98,100,105,118,0,115,117,98,100,105,118,114,0,115,117,98,115,117, +114,102,116,121,112,101,0,42,109,114,0,42,112,118,0,42,116,112,97,103,101,0,117,118,91,52,93,91,50,93,0,99, +111,108,91,52,93,0,116,114,97,110,115,112,0,116,105,108,101,0,117,110,119,114,97,112,0,118,49,0,118,50,0,118, +51,0,118,52,0,101,100,99,111,100,101,0,99,114,101,97,115,101,0,98,119,101,105,103,104,116,0,100,101,102,95,110, +114,0,42,100,119,0,116,111,116,119,101,105,103,104,116,0,99,111,91,51,93,0,110,111,91,51,93,0,112,97,100,91, +51,93,0,117,118,91,50,93,0,99,111,91,50,93,0,105,110,100,101,120,0,102,0,105,0,115,91,50,53,54,93,0, +118,91,52,93,0,109,105,100,0,118,91,50,93,0,42,102,97,99,101,115,0,42,99,111,108,102,97,99,101,115,0,42, +101,100,103,101,115,0,42,101,100,103,101,95,98,111,117,110,100,97,114,121,95,115,116,97,116,101,115,0,42,118,101,114, +116,95,101,100,103,101,95,109,97,112,0,42,118,101,114,116,95,102,97,99,101,95,109,97,112,0,42,109,97,112,95,109, +101,109,0,42,118,101,114,116,115,0,108,101,118,101,108,115,0,108,101,118,101,108,95,99,111,117,110,116,0,99,117,114, +114,101,110,116,0,110,101,119,108,118,108,0,101,100,103,101,108,118,108,0,112,105,110,108,118,108,0,114,101,110,100,101, +114,108,118,108,0,117,115,101,95,99,111,108,0,42,101,100,103,101,95,102,108,97,103,115,0,42,101,100,103,101,95,99, +114,101,97,115,101,115,0,42,118,101,114,116,95,109,97,112,0,42,101,100,103,101,95,109,97,112,0,42,111,108,100,95, +102,97,99,101,115,0,42,111,108,100,95,101,100,103,101,115,0,42,101,114,114,111,114,0,109,111,100,105,102,105,101,114, +0,115,117,98,100,105,118,84,121,112,101,0,114,101,110,100,101,114,76,101,118,101,108,115,0,42,101,109,67,97,99,104, +101,0,42,109,67,97,99,104,101,0,100,101,102,97,120,105,115,0,112,97,100,91,54,93,0,108,101,110,103,116,104,0, +114,97,110,100,111,109,105,122,101,0,115,101,101,100,0,42,111,98,95,97,114,109,0,42,115,116,97,114,116,95,99,97, +112,0,42,101,110,100,95,99,97,112,0,42,99,117,114,118,101,95,111,98,0,42,111,102,102,115,101,116,95,111,98,0, +111,102,102,115,101,116,91,51,93,0,115,99,97,108,101,91,51,93,0,109,101,114,103,101,95,100,105,115,116,0,102,105, +116,95,116,121,112,101,0,111,102,102,115,101,116,95,116,121,112,101,0,99,111,117,110,116,0,97,120,105,115,0,116,111, +108,101,114,97,110,99,101,0,42,109,105,114,114,111,114,95,111,98,0,115,112,108,105,116,95,97,110,103,108,101,0,118, +97,108,117,101,0,114,101,115,0,118,97,108,95,102,108,97,103,115,0,108,105,109,95,102,108,97,103,115,0,101,95,102, +108,97,103,115,0,98,101,118,101,108,95,97,110,103,108,101,0,100,101,102,103,114,112,95,110,97,109,101,91,51,50,93, +0,42,116,101,120,116,117,114,101,0,115,116,114,101,110,103,116,104,0,100,105,114,101,99,116,105,111,110,0,109,105,100, +108,101,118,101,108,0,116,101,120,109,97,112,112,105,110,103,0,42,109,97,112,95,111,98,106,101,99,116,0,117,118,108, +97,121,101,114,95,110,97,109,101,91,51,50,93,0,117,118,108,97,121,101,114,95,116,109,112,0,42,112,114,111,106,101, +99,116,111,114,115,91,49,48,93,0,42,105,109,97,103,101,0,110,117,109,95,112,114,111,106,101,99,116,111,114,115,0, +97,115,112,101,99,116,120,0,97,115,112,101,99,116,121,0,112,101,114,99,101,110,116,0,102,97,99,101,67,111,117,110, +116,0,102,97,99,0,114,101,112,101,97,116,0,42,111,98,106,101,99,116,99,101,110,116,101,114,0,115,116,97,114,116, +120,0,115,116,97,114,116,121,0,104,101,105,103,104,116,0,110,97,114,114,111,119,0,115,112,101,101,100,0,100,97,109, +112,0,102,97,108,108,111,102,102,0,116,105,109,101,111,102,102,115,0,108,105,102,101,116,105,109,101,0,100,101,102,111, +114,109,102,108,97,103,0,109,117,108,116,105,0,42,112,114,101,118,67,111,115,0,112,97,114,101,110,116,105,110,118,91, +52,93,91,52,93,0,99,101,110,116,91,51,93,0,42,105,110,100,101,120,97,114,0,116,111,116,105,110,100,101,120,0, +102,111,114,99,101,0,42,99,108,111,116,104,79,98,106,101,99,116,0,42,115,105,109,95,112,97,114,109,115,0,42,99, +111,108,108,95,112,97,114,109,115,0,42,112,111,105,110,116,95,99,97,99,104,101,0,42,120,0,42,120,110,101,119,0, +42,120,111,108,100,0,42,99,117,114,114,101,110,116,95,120,110,101,119,0,42,99,117,114,114,101,110,116,95,120,0,42, +99,117,114,114,101,110,116,95,118,0,42,109,102,97,99,101,115,0,110,117,109,118,101,114,116,115,0,110,117,109,102,97, +99,101,115,0,97,98,115,111,114,112,116,105,111,110,0,116,105,109,101,0,42,98,118,104,116,114,101,101,0,42,100,109, +0,111,112,101,114,97,116,105,111,110,0,118,101,114,116,101,120,0,116,111,116,105,110,102,108,117,101,110,99,101,0,103, +114,105,100,115,105,122,101,0,110,101,101,100,98,105,110,100,0,42,98,105,110,100,119,101,105,103,104,116,115,0,42,98, +105,110,100,99,111,115,0,116,111,116,99,97,103,101,118,101,114,116,0,42,100,121,110,103,114,105,100,0,42,100,121,110, +105,110,102,108,117,101,110,99,101,115,0,42,100,121,110,118,101,114,116,115,0,42,112,97,100,50,0,100,121,110,103,114, +105,100,115,105,122,101,0,100,121,110,99,101,108,108,109,105,110,91,51,93,0,100,121,110,99,101,108,108,119,105,100,116, +104,0,98,105,110,100,109,97,116,91,52,93,91,52,93,0,42,112,115,121,115,0,116,111,116,100,109,118,101,114,116,0, +116,111,116,100,109,101,100,103,101,0,116,111,116,100,109,102,97,99,101,0,112,115,121,115,0,114,116,91,50,93,0,42, +102,97,99,101,112,97,0,118,103,114,111,117,112,0,112,114,111,116,101,99,116,0,42,102,115,115,0,42,116,97,114,103, +101,116,0,42,97,117,120,84,97,114,103,101,116,0,118,103,114,111,117,112,95,110,97,109,101,91,51,50,93,0,107,101, +101,112,68,105,115,116,0,115,104,114,105,110,107,84,121,112,101,0,115,104,114,105,110,107,79,112,116,115,0,112,114,111, +106,65,120,105,115,0,115,117,98,115,117,114,102,76,101,118,101,108,115,0,42,111,114,105,103,105,110,0,102,97,99,116, +111,114,0,108,105,109,105,116,91,50,93,0,111,114,105,103,105,110,79,112,116,115,0,112,110,116,115,119,0,111,112,110, +116,115,117,0,111,112,110,116,115,118,0,111,112,110,116,115,119,0,116,121,112,101,117,0,116,121,112,101,118,0,116,121, +112,101,119,0,102,117,0,102,118,0,102,119,0,100,117,0,100,118,0,100,119,0,42,100,101,102,0,118,101,99,91,56, +93,91,51,93,0,112,97,114,116,121,112,101,0,112,97,114,49,0,112,97,114,50,0,112,97,114,51,0,112,97,114,115, +117,98,115,116,114,91,51,50,93,0,42,116,114,97,99,107,0,42,112,114,111,120,121,0,42,112,114,111,120,121,95,103, +114,111,117,112,0,42,112,114,111,120,121,95,102,114,111,109,0,42,97,99,116,105,111,110,0,42,112,111,115,101,108,105, +98,0,42,112,111,115,101,0,99,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,115,0,100,101,102,98,97, +115,101,0,109,111,100,105,102,105,101,114,115,0,100,108,111,99,91,51,93,0,111,114,105,103,91,51,93,0,100,115,105, +122,101,91,51,93,0,100,114,111,116,91,51,93,0,111,98,109,97,116,91,52,93,91,52,93,0,99,111,110,115,116,105, +110,118,91,52,93,91,52,93,0,108,97,121,0,99,111,108,98,105,116,115,0,116,114,97,110,115,102,108,97,103,0,105, +112,111,102,108,97,103,0,116,114,97,99,107,102,108,97,103,0,117,112,102,108,97,103,0,110,108,97,102,108,97,103,0, +112,114,111,116,101,99,116,102,108,97,103,0,105,112,111,119,105,110,0,115,99,97,102,108,97,103,0,115,99,97,118,105, +115,102,108,97,103,0,98,111,117,110,100,116,121,112,101,0,100,117,112,111,110,0,100,117,112,111,102,102,0,100,117,112, +115,116,97,0,100,117,112,101,110,100,0,115,102,0,99,116,105,109,101,0,109,97,115,115,0,100,97,109,112,105,110,103, +0,105,110,101,114,116,105,97,0,102,111,114,109,102,97,99,116,111,114,0,114,100,97,109,112,105,110,103,0,115,105,122, +101,102,97,99,0,109,97,114,103,105,110,0,109,97,120,95,118,101,108,0,109,105,110,95,118,101,108,0,109,95,99,111, +110,116,97,99,116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,0,100,116,0,100,116,120,0, +97,99,116,99,111,108,0,101,109,112,116,121,95,100,114,97,119,116,121,112,101,0,112,97,100,49,91,51,93,0,101,109, +112,116,121,95,100,114,97,119,115,105,122,101,0,100,117,112,102,97,99,101,115,99,97,0,112,114,111,112,0,115,101,110, +115,111,114,115,0,99,111,110,116,114,111,108,108,101,114,115,0,97,99,116,117,97,116,111,114,115,0,98,98,115,105,122, +101,91,51,93,0,97,99,116,100,101,102,0,103,97,109,101,102,108,97,103,0,103,97,109,101,102,108,97,103,50,0,42, +98,115,111,102,116,0,115,111,102,116,102,108,97,103,0,97,110,105,115,111,116,114,111,112,105,99,70,114,105,99,116,105, +111,110,91,51,93,0,99,111,110,115,116,114,97,105,110,116,115,0,110,108,97,115,116,114,105,112,115,0,104,111,111,107, +115,0,112,97,114,116,105,99,108,101,115,121,115,116,101,109,0,42,112,100,0,42,115,111,102,116,0,42,100,117,112,95, +103,114,111,117,112,0,102,108,117,105,100,115,105,109,70,108,97,103,0,114,101,115,116,114,105,99,116,102,108,97,103,0, +115,104,97,112,101,110,114,0,115,104,97,112,101,102,108,97,103,0,114,101,99,97,108,99,111,0,98,111,100,121,95,116, +121,112,101,0,42,102,108,117,105,100,115,105,109,83,101,116,116,105,110,103,115,0,42,100,101,114,105,118,101,100,68,101, +102,111,114,109,0,42,100,101,114,105,118,101,100,70,105,110,97,108,0,108,97,115,116,68,97,116,97,77,97,115,107,0, +115,116,97,116,101,0,105,110,105,116,95,115,116,97,116,101,0,103,112,117,108,97,109,112,0,99,117,114,105,110,100,101, +120,0,97,99,116,105,118,101,0,100,101,102,108,101,99,116,0,102,111,114,99,101,102,105,101,108,100,0,112,100,101,102, +95,100,97,109,112,0,112,100,101,102,95,114,100,97,109,112,0,112,100,101,102,95,112,101,114,109,0,112,100,101,102,95, +102,114,105,99,116,0,112,100,101,102,95,114,102,114,105,99,116,0,102,95,115,116,114,101,110,103,116,104,0,102,95,112, +111,119,101,114,0,102,95,100,105,115,116,0,102,95,100,97,109,112,0,109,97,120,100,105,115,116,0,109,105,110,100,105, +115,116,0,109,97,120,114,97,100,0,109,105,110,114,97,100,0,102,95,112,111,119,101,114,95,114,0,112,100,101,102,95, +115,98,100,97,109,112,0,112,100,101,102,95,115,98,105,102,116,0,112,100,101,102,95,115,98,111,102,116,0,99,108,117, +109,112,95,102,97,99,0,99,108,117,109,112,95,112,111,119,0,107,105,110,107,95,102,114,101,113,0,107,105,110,107,95, +115,104,97,112,101,0,107,105,110,107,95,97,109,112,0,102,114,101,101,95,101,110,100,0,116,101,120,95,110,97,98,108, +97,0,116,101,120,95,109,111,100,101,0,107,105,110,107,0,107,105,110,107,95,97,120,105,115,0,114,116,50,0,42,114, +110,103,0,102,95,110,111,105,115,101,0,115,105,109,102,114,97,109,101,0,115,116,97,114,116,102,114,97,109,101,0,101, +110,100,102,114,97,109,101,0,101,100,105,116,102,114,97,109,101,0,108,105,110,83,116,105,102,102,0,97,110,103,83,116, +105,102,102,0,118,111,108,117,109,101,0,118,105,116,101,114,97,116,105,111,110,115,0,112,105,116,101,114,97,116,105,111, +110,115,0,100,105,116,101,114,97,116,105,111,110,115,0,99,105,116,101,114,97,116,105,111,110,115,0,107,83,82,72,82, +95,67,76,0,107,83,75,72,82,95,67,76,0,107,83,83,72,82,95,67,76,0,107,83,82,95,83,80,76,84,95,67, +76,0,107,83,75,95,83,80,76,84,95,67,76,0,107,83,83,95,83,80,76,84,95,67,76,0,107,86,67,70,0,107, +68,80,0,107,68,71,0,107,76,70,0,107,80,82,0,107,86,67,0,107,68,70,0,107,77,84,0,107,67,72,82,0, +107,75,72,82,0,107,83,72,82,0,107,65,72,82,0,99,111,108,108,105,115,105,111,110,102,108,97,103,115,0,110,117, +109,99,108,117,115,116,101,114,105,116,101,114,97,116,105,111,110,115,0,119,101,108,100,105,110,103,0,42,112,97,114,116, +105,99,108,101,115,0,116,111,116,112,111,105,110,116,0,116,111,116,115,112,114,105,110,103,0,42,98,112,111,105,110,116, +0,42,98,115,112,114,105,110,103,0,109,115,103,95,108,111,99,107,0,109,115,103,95,118,97,108,117,101,0,110,111,100, +101,109,97,115,115,0,110,97,109,101,100,86,71,95,77,97,115,115,91,51,50,93,0,103,114,97,118,0,109,101,100,105, +97,102,114,105,99,116,0,114,107,108,105,109,105,116,0,112,104,121,115,105,99,115,95,115,112,101,101,100,0,103,111,97, +108,115,112,114,105,110,103,0,103,111,97,108,102,114,105,99,116,0,109,105,110,103,111,97,108,0,109,97,120,103,111,97, +108,0,100,101,102,103,111,97,108,0,118,101,114,116,103,114,111,117,112,0,110,97,109,101,100,86,71,95,83,111,102,116, +103,111,97,108,91,51,50,93,0,102,117,122,122,121,110,101,115,115,0,105,110,115,112,114,105,110,103,0,105,110,102,114, +105,99,116,0,110,97,109,101,100,86,71,95,83,112,114,105,110,103,95,75,91,51,50,93,0,101,102,114,97,0,105,110, +116,101,114,118,97,108,0,108,111,99,97,108,0,115,111,108,118,101,114,102,108,97,103,115,0,42,42,107,101,121,115,0, +116,111,116,112,111,105,110,116,107,101,121,0,115,101,99,111,110,100,115,112,114,105,110,103,0,99,111,108,98,97,108,108, +0,98,97,108,108,100,97,109,112,0,98,97,108,108,115,116,105,102,102,0,115,98,99,95,109,111,100,101,0,97,101,114, +111,101,100,103,101,0,109,105,110,108,111,111,112,115,0,109,97,120,108,111,111,112,115,0,99,104,111,107,101,0,115,111, +108,118,101,114,95,73,68,0,112,108,97,115,116,105,99,0,115,112,114,105,110,103,112,114,101,108,111,97,100,0,42,115, +99,114,97,116,99,104,0,115,104,101,97,114,115,116,105,102,102,0,105,110,112,117,115,104,0,42,112,111,105,110,116,99, +97,99,104,101,0,115,104,111,119,95,97,100,118,97,110,99,101,100,111,112,116,105,111,110,115,0,114,101,115,111,108,117, +116,105,111,110,120,121,122,0,112,114,101,118,105,101,119,114,101,115,120,121,122,0,114,101,97,108,115,105,122,101,0,103, +117,105,68,105,115,112,108,97,121,77,111,100,101,0,114,101,110,100,101,114,68,105,115,112,108,97,121,77,111,100,101,0, +118,105,115,99,111,115,105,116,121,86,97,108,117,101,0,118,105,115,99,111,115,105,116,121,77,111,100,101,0,118,105,115, +99,111,115,105,116,121,69,120,112,111,110,101,110,116,0,103,114,97,118,120,0,103,114,97,118,121,0,103,114,97,118,122, +0,97,110,105,109,83,116,97,114,116,0,97,110,105,109,69,110,100,0,103,115,116,97,114,0,109,97,120,82,101,102,105, +110,101,0,105,110,105,86,101,108,120,0,105,110,105,86,101,108,121,0,105,110,105,86,101,108,122,0,42,111,114,103,77, +101,115,104,0,42,109,101,115,104,83,117,114,102,97,99,101,0,42,109,101,115,104,66,66,0,115,117,114,102,100,97,116, +97,80,97,116,104,91,50,52,48,93,0,98,98,83,116,97,114,116,91,51,93,0,98,98,83,105,122,101,91,51,93,0, +116,121,112,101,70,108,97,103,115,0,100,111,109,97,105,110,78,111,118,101,99,103,101,110,0,118,111,108,117,109,101,73, +110,105,116,84,121,112,101,0,112,97,114,116,83,108,105,112,86,97,108,117,101,0,103,101,110,101,114,97,116,101,84,114, +97,99,101,114,115,0,103,101,110,101,114,97,116,101,80,97,114,116,105,99,108,101,115,0,115,117,114,102,97,99,101,83, +109,111,111,116,104,105,110,103,0,115,117,114,102,97,99,101,83,117,98,100,105,118,115,0,112,97,114,116,105,99,108,101, +73,110,102,83,105,122,101,0,112,97,114,116,105,99,108,101,73,110,102,65,108,112,104,97,0,102,97,114,70,105,101,108, +100,83,105,122,101,0,42,109,101,115,104,83,117,114,102,78,111,114,109,97,108,115,0,99,112,115,84,105,109,101,83,116, +97,114,116,0,99,112,115,84,105,109,101,69,110,100,0,99,112,115,81,117,97,108,105,116,121,0,97,116,116,114,97,99, +116,102,111,114,99,101,83,116,114,101,110,103,116,104,0,97,116,116,114,97,99,116,102,111,114,99,101,82,97,100,105,117, +115,0,118,101,108,111,99,105,116,121,102,111,114,99,101,83,116,114,101,110,103,116,104,0,118,101,108,111,99,105,116,121, +102,111,114,99,101,82,97,100,105,117,115,0,108,97,115,116,103,111,111,100,102,114,97,109,101,0,109,105,115,116,121,112, +101,0,104,111,114,114,0,104,111,114,103,0,104,111,114,98,0,104,111,114,107,0,122,101,110,114,0,122,101,110,103,0, +122,101,110,98,0,122,101,110,107,0,97,109,98,107,0,102,97,115,116,99,111,108,0,101,120,112,111,115,117,114,101,0, +101,120,112,0,114,97,110,103,101,0,108,105,110,102,97,99,0,108,111,103,102,97,99,0,103,114,97,118,105,116,121,0, +97,99,116,105,118,105,116,121,66,111,120,82,97,100,105,117,115,0,115,107,121,116,121,112,101,0,111,99,99,108,117,115, +105,111,110,82,101,115,0,112,104,121,115,105,99,115,69,110,103,105,110,101,0,116,105,99,114,97,116,101,0,109,97,120, +108,111,103,105,99,115,116,101,112,0,112,104,121,115,117,98,115,116,101,112,0,109,97,120,112,104,121,115,116,101,112,0, +109,105,115,105,0,109,105,115,116,115,116,97,0,109,105,115,116,100,105,115,116,0,109,105,115,116,104,105,0,115,116,97, +114,114,0,115,116,97,114,103,0,115,116,97,114,98,0,115,116,97,114,107,0,115,116,97,114,115,105,122,101,0,115,116, +97,114,109,105,110,100,105,115,116,0,115,116,97,114,100,105,115,116,0,115,116,97,114,99,111,108,110,111,105,115,101,0, +100,111,102,115,116,97,0,100,111,102,101,110,100,0,100,111,102,109,105,110,0,100,111,102,109,97,120,0,97,111,100,105, +115,116,0,97,111,100,105,115,116,102,97,99,0,97,111,101,110,101,114,103,121,0,97,111,98,105,97,115,0,97,111,109, +111,100,101,0,97,111,115,97,109,112,0,97,111,109,105,120,0,97,111,99,111,108,111,114,0,97,111,95,97,100,97,112, +116,95,116,104,114,101,115,104,0,97,111,95,97,100,97,112,116,95,115,112,101,101,100,95,102,97,99,0,97,111,95,97, +112,112,114,111,120,95,101,114,114,111,114,0,97,111,95,97,112,112,114,111,120,95,99,111,114,114,101,99,116,105,111,110, +0,97,111,95,115,97,109,112,95,109,101,116,104,111,100,0,97,111,95,103,97,116,104,101,114,95,109,101,116,104,111,100, +0,97,111,95,97,112,112,114,111,120,95,112,97,115,115,101,115,0,42,97,111,115,112,104,101,114,101,0,42,97,111,116, +97,98,108,101,115,0,104,101,109,105,114,101,115,0,109,97,120,105,116,101,114,0,100,114,97,119,116,121,112,101,0,115, +117,98,115,104,111,111,116,112,0,115,117,98,115,104,111,111,116,101,0,110,111,100,101,108,105,109,0,109,97,120,115,117, +98,108,97,109,112,0,112,97,109,97,0,112,97,109,105,0,101,108,109,97,0,101,108,109,105,0,109,97,120,110,111,100, +101,0,99,111,110,118,101,114,103,101,110,99,101,0,114,97,100,102,97,99,0,103,97,109,109,97,0,115,101,108,99,111, +108,0,115,120,0,115,121,0,42,108,112,70,111,114,109,97,116,0,42,108,112,80,97,114,109,115,0,99,98,70,111,114, +109,97,116,0,99,98,80,97,114,109,115,0,102,99,99,84,121,112,101,0,102,99,99,72,97,110,100,108,101,114,0,100, +119,75,101,121,70,114,97,109,101,69,118,101,114,121,0,100,119,81,117,97,108,105,116,121,0,100,119,66,121,116,101,115, +80,101,114,83,101,99,111,110,100,0,100,119,70,108,97,103,115,0,100,119,73,110,116,101,114,108,101,97,118,101,69,118, +101,114,121,0,97,118,105,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,42,99,100,80,97,114,109,115,0,42, +112,97,100,0,99,100,83,105,122,101,0,113,116,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,99,111,100,101, +99,0,97,117,100,105,111,95,99,111,100,101,99,0,118,105,100,101,111,95,98,105,116,114,97,116,101,0,97,117,100,105, +111,95,98,105,116,114,97,116,101,0,103,111,112,95,115,105,122,101,0,114,99,95,109,105,110,95,114,97,116,101,0,114, +99,95,109,97,120,95,114,97,116,101,0,114,99,95,98,117,102,102,101,114,95,115,105,122,101,0,109,117,120,95,112,97, +99,107,101,116,95,115,105,122,101,0,109,117,120,95,114,97,116,101,0,109,105,120,114,97,116,101,0,109,97,105,110,0, +42,109,97,116,95,111,118,101,114,114,105,100,101,0,42,108,105,103,104,116,95,111,118,101,114,114,105,100,101,0,108,97, +121,95,122,109,97,115,107,0,108,97,121,102,108,97,103,0,112,97,115,115,102,108,97,103,0,112,97,115,115,95,120,111, +114,0,42,97,118,105,99,111,100,101,99,100,97,116,97,0,42,113,116,99,111,100,101,99,100,97,116,97,0,102,102,99, +111,100,101,99,100,97,116,97,0,99,102,114,97,0,112,115,102,114,97,0,112,101,102,114,97,0,105,109,97,103,101,115, +0,102,114,97,109,97,112,116,111,0,116,104,114,101,97,100,115,0,102,114,97,109,101,108,101,110,0,98,108,117,114,102, +97,99,0,101,100,103,101,82,0,101,100,103,101,71,0,101,100,103,101,66,0,102,117,108,108,115,99,114,101,101,110,0, +120,112,108,97,121,0,121,112,108,97,121,0,102,114,101,113,112,108,97,121,0,97,116,116,114,105,98,0,114,116,49,0, +115,116,101,114,101,111,109,111,100,101,0,100,105,109,101,110,115,105,111,110,115,112,114,101,115,101,116,0,109,97,120,105, +109,115,105,122,101,0,120,115,99,104,0,121,115,99,104,0,120,112,97,114,116,115,0,121,112,97,114,116,115,0,119,105, +110,112,111,115,0,112,108,97,110,101,115,0,105,109,116,121,112,101,0,115,117,98,105,109,116,121,112,101,0,113,117,97, +108,105,116,121,0,114,112,97,100,0,114,112,97,100,49,0,114,112,97,100,50,0,115,99,101,109,111,100,101,0,114,101, +110,100,101,114,101,114,0,111,99,114,101,115,0,97,108,112,104,97,109,111,100,101,0,111,115,97,0,102,114,115,95,115, +101,99,0,101,100,103,101,105,110,116,0,115,97,102,101,116,121,0,98,111,114,100,101,114,0,100,105,115,112,114,101,99, +116,0,108,97,121,101,114,115,0,97,99,116,108,97,121,0,120,97,115,112,0,121,97,115,112,0,102,114,115,95,115,101, +99,95,98,97,115,101,0,103,97,117,115,115,0,112,111,115,116,109,117,108,0,112,111,115,116,103,97,109,109,97,0,112, +111,115,116,104,117,101,0,112,111,115,116,115,97,116,0,100,105,116,104,101,114,95,105,110,116,101,110,115,105,116,121,0, +98,97,107,101,95,111,115,97,0,98,97,107,101,95,102,105,108,116,101,114,0,98,97,107,101,95,109,111,100,101,0,98, +97,107,101,95,102,108,97,103,0,98,97,107,101,95,110,111,114,109,97,108,95,115,112,97,99,101,0,98,97,107,101,95, +113,117,97,100,95,115,112,108,105,116,0,98,97,107,101,95,109,97,120,100,105,115,116,0,98,97,107,101,95,98,105,97, +115,100,105,115,116,0,98,97,107,101,95,112,97,100,0,71,73,113,117,97,108,105,116,121,0,71,73,99,97,99,104,101, +0,71,73,109,101,116,104,111,100,0,71,73,112,104,111,116,111,110,115,0,71,73,100,105,114,101,99,116,0,89,70,95, +65,65,0,89,70,101,120,112,111,114,116,120,109,108,0,89,70,95,110,111,98,117,109,112,0,89,70,95,99,108,97,109, +112,114,103,98,0,121,102,112,97,100,49,0,71,73,100,101,112,116,104,0,71,73,99,97,117,115,100,101,112,116,104,0, +71,73,112,105,120,101,108,115,112,101,114,115,97,109,112,108,101,0,71,73,112,104,111,116,111,110,99,111,117,110,116,0, +71,73,109,105,120,112,104,111,116,111,110,115,0,71,73,112,104,111,116,111,110,114,97,100,105,117,115,0,89,70,95,114, +97,121,100,101,112,116,104,0,89,70,95,65,65,112,97,115,115,101,115,0,89,70,95,65,65,115,97,109,112,108,101,115, +0,121,102,112,97,100,50,0,71,73,115,104,97,100,111,119,113,117,97,108,105,116,121,0,71,73,114,101,102,105,110,101, +109,101,110,116,0,71,73,112,111,119,101,114,0,71,73,105,110,100,105,114,112,111,119,101,114,0,89,70,95,103,97,109, +109,97,0,89,70,95,101,120,112,111,115,117,114,101,0,89,70,95,114,97,121,98,105,97,115,0,89,70,95,65,65,112, +105,120,101,108,115,105,122,101,0,89,70,95,65,65,116,104,114,101,115,104,111,108,100,0,98,97,99,107,98,117,102,91, +49,54,48,93,0,112,105,99,91,49,54,48,93,0,115,116,97,109,112,0,115,116,97,109,112,95,102,111,110,116,95,105, +100,0,115,116,97,109,112,95,117,100,97,116,97,91,49,54,48,93,0,102,103,95,115,116,97,109,112,91,52,93,0,98, +103,95,115,116,97,109,112,91,52,93,0,115,105,109,112,108,105,102,121,95,115,117,98,115,117,114,102,0,115,105,109,112, +108,105,102,121,95,115,104,97,100,111,119,115,97,109,112,108,101,115,0,115,105,109,112,108,105,102,121,95,112,97,114,116, +105,99,108,101,115,0,115,105,109,112,108,105,102,121,95,97,111,115,115,115,0,99,105,110,101,111,110,119,104,105,116,101, +0,99,105,110,101,111,110,98,108,97,99,107,0,99,105,110,101,111,110,103,97,109,109,97,0,106,112,50,95,112,114,101, +115,101,116,0,106,112,50,95,100,101,112,116,104,0,114,112,97,100,51,0,100,111,109,101,114,101,115,0,100,111,109,101, +109,111,100,101,0,100,111,109,101,97,110,103,108,101,0,100,111,109,101,116,105,108,116,0,100,111,109,101,114,101,115,98, +117,102,0,42,100,111,109,101,116,101,120,116,0,112,97,114,116,105,99,108,101,95,112,101,114,99,0,115,117,98,115,117, +114,102,95,109,97,120,0,115,104,97,100,98,117,102,115,97,109,112,108,101,95,109,97,120,0,97,111,95,101,114,114,111, +114,0,99,111,108,91,51,93,0,102,114,97,109,101,0,110,97,109,101,91,54,52,93,0,42,98,114,117,115,104,0,116, +111,111,108,0,115,101,97,109,95,98,108,101,101,100,0,110,111,114,109,97,108,95,97,110,103,108,101,0,115,116,101,112, +0,105,110,118,101,114,116,0,116,111,116,114,101,107,101,121,0,116,111,116,97,100,100,107,101,121,0,98,114,117,115,104, +116,121,112,101,0,98,114,117,115,104,91,55,93,0,101,109,105,116,116,101,114,100,105,115,116,0,100,114,97,119,95,116, +105,109,101,100,0,110,97,109,101,91,51,54,93,0,109,97,116,91,51,93,91,51,93,0,99,111,114,110,101,114,116,121, +112,101,0,101,100,105,116,98,117,116,102,108,97,103,0,106,111,105,110,116,114,105,108,105,109,105,116,0,100,101,103,114, +0,116,117,114,110,0,101,120,116,114,95,111,102,102,115,0,100,111,117,98,108,105,109,105,116,0,115,101,103,109,101,110, +116,115,0,114,105,110,103,115,0,118,101,114,116,105,99,101,115,0,117,110,119,114,97,112,112,101,114,0,117,118,99,97, +108,99,95,114,97,100,105,117,115,0,117,118,99,97,108,99,95,99,117,98,101,115,105,122,101,0,117,118,99,97,108,99, +95,109,97,114,103,105,110,0,117,118,99,97,108,99,95,109,97,112,100,105,114,0,117,118,99,97,108,99,95,109,97,112, +97,108,105,103,110,0,117,118,99,97,108,99,95,102,108,97,103,0,97,117,116,111,105,107,95,99,104,97,105,110,108,101, +110,0,105,109,97,112,97,105,110,116,0,112,97,114,116,105,99,108,101,0,115,101,108,101,99,116,95,116,104,114,101,115, +104,0,99,108,101,97,110,95,116,104,114,101,115,104,0,114,101,116,111,112,111,95,109,111,100,101,0,114,101,116,111,112, +111,95,112,97,105,110,116,95,116,111,111,108,0,108,105,110,101,95,100,105,118,0,101,108,108,105,112,115,101,95,100,105, +118,0,114,101,116,111,112,111,95,104,111,116,115,112,111,116,0,109,117,108,116,105,114,101,115,95,115,117,98,100,105,118, +95,116,121,112,101,0,115,107,103,101,110,95,114,101,115,111,108,117,116,105,111,110,0,115,107,103,101,110,95,116,104,114, +101,115,104,111,108,100,95,105,110,116,101,114,110,97,108,0,115,107,103,101,110,95,116,104,114,101,115,104,111,108,100,95, +101,120,116,101,114,110,97,108,0,115,107,103,101,110,95,108,101,110,103,116,104,95,114,97,116,105,111,0,115,107,103,101, +110,95,108,101,110,103,116,104,95,108,105,109,105,116,0,115,107,103,101,110,95,97,110,103,108,101,95,108,105,109,105,116, +0,115,107,103,101,110,95,99,111,114,114,101,108,97,116,105,111,110,95,108,105,109,105,116,0,115,107,103,101,110,95,115, +121,109,109,101,116,114,121,95,108,105,109,105,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,97,110,103, +108,101,95,119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,108,101,110,103,116,104,95, +119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,100,105,115,116,97,110,99,101,95,119, +101,105,103,104,116,0,115,107,103,101,110,95,111,112,116,105,111,110,115,0,115,107,103,101,110,95,112,111,115,116,112,114, +111,0,115,107,103,101,110,95,112,111,115,116,112,114,111,95,112,97,115,115,101,115,0,115,107,103,101,110,95,115,117,98, +100,105,118,105,115,105,111,110,115,91,51,93,0,115,107,103,101,110,95,109,117,108,116,105,95,108,101,118,101,108,0,42, +115,107,103,101,110,95,116,101,109,112,108,97,116,101,0,98,111,110,101,95,115,107,101,116,99,104,105,110,103,0,98,111, +110,101,95,115,107,101,116,99,104,105,110,103,95,99,111,110,118,101,114,116,0,115,107,103,101,110,95,115,117,98,100,105, +118,105,115,105,111,110,95,110,117,109,98,101,114,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,111,112,116, +105,111,110,115,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,114,111,108,108,0,115,107,103,101,110,95,115, +105,100,101,95,115,116,114,105,110,103,91,56,93,0,115,107,103,101,110,95,110,117,109,95,115,116,114,105,110,103,91,56, +93,0,101,100,103,101,95,109,111,100,101,0,112,97,100,51,91,50,93,0,100,105,114,0,118,105,101,119,0,42,115,101, +115,115,105,111,110,0,42,99,117,109,97,112,0,100,114,97,119,98,114,117,115,104,0,115,109,111,111,116,104,98,114,117, +115,104,0,112,105,110,99,104,98,114,117,115,104,0,105,110,102,108,97,116,101,98,114,117,115,104,0,103,114,97,98,98, +114,117,115,104,0,108,97,121,101,114,98,114,117,115,104,0,102,108,97,116,116,101,110,98,114,117,115,104,0,112,105,118, +111,116,91,51,93,0,98,114,117,115,104,95,116,121,112,101,0,116,101,120,110,114,0,116,101,120,114,101,112,116,0,116, +101,120,102,97,100,101,0,116,101,120,115,101,112,0,97,118,101,114,97,103,105,110,103,0,116,97,98,108,101,116,95,115, +105,122,101,0,116,97,98,108,101,116,95,115,116,114,101,110,103,116,104,0,115,121,109,109,0,114,97,107,101,0,97,120, +105,115,108,111,99,107,0,42,99,97,109,101,114,97,0,42,119,111,114,108,100,0,42,115,101,116,0,98,97,115,101,0, +42,98,97,115,97,99,116,0,99,117,114,115,111,114,91,51,93,0,116,119,99,101,110,116,91,51,93,0,116,119,109,105, +110,91,51,93,0,116,119,109,97,120,91,51,93,0,101,100,105,116,98,117,116,115,105,122,101,0,115,101,108,101,99,116, +109,111,100,101,0,112,114,111,112,111,114,116,105,111,110,97,108,0,112,114,111,112,95,109,111,100,101,0,97,117,116,111, +109,101,114,103,101,0,112,97,100,53,0,112,97,100,54,0,97,117,116,111,107,101,121,95,109,111,100,101,0,42,101,100, +0,42,114,97,100,105,111,0,102,114,97,109,105,110,103,0,42,116,111,111,108,115,101,116,116,105,110,103,115,0,97,117, +100,105,111,0,116,114,97,110,115,102,111,114,109,95,115,112,97,99,101,115,0,106,117,109,112,102,114,97,109,101,0,115, +110,97,112,95,109,111,100,101,0,115,110,97,112,95,102,108,97,103,0,115,110,97,112,95,116,97,114,103,101,116,0,42, +116,104,101,68,97,103,0,100,97,103,105,115,118,97,108,105,100,0,100,97,103,102,108,97,103,115,0,115,99,117,108,112, +116,100,97,116,97,0,102,114,97,109,101,95,115,116,101,112,0,122,111,111,109,0,98,108,101,110,100,0,120,105,109,0, +121,105,109,0,115,112,97,99,101,116,121,112,101,0,98,108,111,99,107,115,99,97,108,101,0,42,97,114,101,97,0,98, +108,111,99,107,104,97,110,100,108,101,114,91,56,93,0,118,105,101,119,109,97,116,91,52,93,91,52,93,0,118,105,101, +119,105,110,118,91,52,93,91,52,93,0,112,101,114,115,109,97,116,91,52,93,91,52,93,0,112,101,114,115,105,110,118, +91,52,93,91,52,93,0,119,105,110,109,97,116,49,91,52,93,91,52,93,0,118,105,101,119,109,97,116,49,91,52,93, +91,52,93,0,118,105,101,119,113,117,97,116,91,52,93,0,122,102,97,99,0,108,97,121,95,117,115,101,100,0,112,101, +114,115,112,0,42,111,98,95,99,101,110,116,114,101,0,42,98,103,112,105,99,0,42,108,111,99,97,108,118,100,0,42, +114,105,0,42,114,101,116,111,112,111,95,118,105,101,119,95,100,97,116,97,0,42,100,101,112,116,104,115,0,111,98,95, +99,101,110,116,114,101,95,98,111,110,101,91,51,50,93,0,108,111,99,97,108,118,105,101,119,0,108,97,121,97,99,116, +0,115,99,101,110,101,108,111,99,107,0,97,114,111,117,110,100,0,99,97,109,122,111,111,109,0,112,105,118,111,116,95, +108,97,115,116,0,103,114,105,100,0,103,114,105,100,118,105,101,119,0,112,105,120,115,105,122,101,0,110,101,97,114,0, +102,97,114,0,99,97,109,100,120,0,99,97,109,100,121,0,103,114,105,100,108,105,110,101,115,0,118,105,101,119,98,117, +116,0,103,114,105,100,102,108,97,103,0,109,111,100,101,115,101,108,101,99,116,0,116,119,116,121,112,101,0,116,119,109, +111,100,101,0,116,119,102,108,97,103,0,116,119,100,114,97,119,102,108,97,103,0,116,119,109,97,116,91,52,93,91,52, +93,0,99,108,105,112,91,52,93,91,52,93,0,42,99,108,105,112,98,98,0,97,102,116,101,114,100,114,97,119,0,122, +98,117,102,0,120,114,97,121,0,102,108,97,103,50,0,103,114,105,100,115,117,98,100,105,118,0,107,101,121,102,108,97, +103,115,0,110,100,111,102,109,111,100,101,0,110,100,111,102,102,105,108,116,101,114,0,42,112,114,111,112,101,114,116,105, +101,115,95,115,116,111,114,97,103,101,0,42,103,112,100,0,108,118,105,101,119,113,117,97,116,91,52,93,0,108,112,101, +114,115,112,0,108,118,105,101,119,0,118,101,114,116,0,104,111,114,0,109,97,115,107,0,109,105,110,91,50,93,0,109, +97,120,91,50,93,0,109,105,110,122,111,111,109,0,109,97,120,122,111,111,109,0,115,99,114,111,108,108,0,107,101,101, +112,116,111,116,0,107,101,101,112,97,115,112,101,99,116,0,107,101,101,112,122,111,111,109,0,111,108,100,119,105,110,120, +0,111,108,100,119,105,110,121,0,99,117,114,115,111,114,91,50,93,0,114,111,119,98,117,116,0,118,50,100,0,42,101, +100,105,116,105,112,111,0,105,112,111,107,101,121,0,97,99,116,110,97,109,101,91,51,50,93,0,99,111,110,115,116,110, +97,109,101,91,51,50,93,0,98,111,110,101,110,97,109,101,91,51,50,93,0,116,111,116,105,112,111,0,112,105,110,0, +98,117,116,111,102,115,0,99,104,97,110,110,101,108,0,108,111,99,107,0,109,101,100,105,97,110,91,51,93,0,99,117, +114,115,101,110,115,0,99,117,114,97,99,116,0,97,108,105,103,110,0,116,97,98,111,0,109,97,105,110,98,0,109,97, +105,110,98,111,0,42,108,111,99,107,112,111,105,110,0,116,101,120,102,114,111,109,0,115,104,111,119,103,114,111,117,112, +0,109,111,100,101,108,116,121,112,101,0,115,99,114,105,112,116,98,108,111,99,107,0,114,101,95,97,108,105,103,110,0, +111,108,100,107,101,121,112,114,101,115,115,0,116,97,98,91,55,93,0,114,101,110,100,101,114,95,115,105,122,101,0,99, +104,97,110,115,104,111,119,110,0,122,101,98,114,97,0,42,102,105,108,101,108,105,115,116,0,116,111,116,102,105,108,101, +0,116,105,116,108,101,91,50,52,93,0,100,105,114,91,50,52,48,93,0,102,105,108,101,91,56,48,93,0,111,102,115, +0,115,111,114,116,0,109,97,120,110,97,109,101,108,101,110,0,99,111,108,108,117,109,115,0,102,95,102,112,0,102,112, +95,115,116,114,91,56,93,0,42,108,105,98,102,105,108,101,100,97,116,97,0,114,101,116,118,97,108,0,109,101,110,117, +0,97,99,116,0,40,42,114,101,116,117,114,110,102,117,110,99,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110, +99,95,101,118,101,110,116,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110,99,95,97,114,103,115,41,40,41,0, +42,97,114,103,49,0,42,97,114,103,50,0,42,109,101,110,117,112,0,42,112,117,112,109,101,110,117,0,111,111,112,115, +0,118,105,115,105,102,108,97,103,0,116,114,101,101,0,42,116,114,101,101,115,116,111,114,101,0,115,101,97,114,99,104, +95,115,116,114,105,110,103,91,51,50,93,0,115,101,97,114,99,104,95,116,115,101,0,115,101,97,114,99,104,95,102,108, +97,103,115,0,100,111,95,0,111,117,116,108,105,110,101,118,105,115,0,115,116,111,114,101,102,108,97,103,0,100,101,112, +115,95,102,108,97,103,115,0,105,109,97,110,114,0,99,117,114,116,105,108,101,0,105,109,116,121,112,101,110,114,0,100, +116,95,117,118,0,115,116,105,99,107,121,0,100,116,95,117,118,115,116,114,101,116,99,104,0,112,97,100,91,53,93,0, +99,101,110,116,120,0,99,101,110,116,121,0,97,117,116,111,115,110,97,112,0,42,116,101,120,116,0,116,111,112,0,118, +105,101,119,108,105,110,101,115,0,102,111,110,116,95,105,100,0,108,104,101,105,103,104,116,0,108,101,102,116,0,115,104, +111,119,108,105,110,101,110,114,115,0,116,97,98,110,117,109,98,101,114,0,99,117,114,114,116,97,98,95,115,101,116,0, +115,104,111,119,115,121,110,116,97,120,0,111,118,101,114,119,114,105,116,101,0,112,105,120,95,112,101,114,95,108,105,110, +101,0,116,120,116,115,99,114,111,108,108,0,116,120,116,98,97,114,0,119,111,114,100,119,114,97,112,0,100,111,112,108, +117,103,105,110,115,0,42,112,121,95,100,114,97,119,0,42,112,121,95,101,118,101,110,116,0,42,112,121,95,98,117,116, +116,111,110,0,42,112,121,95,98,114,111,119,115,101,114,99,97,108,108,98,97,99,107,0,42,112,121,95,103,108,111,98, +97,108,100,105,99,116,0,108,97,115,116,115,112,97,99,101,0,115,99,114,105,112,116,110,97,109,101,91,50,53,54,93, +0,115,99,114,105,112,116,97,114,103,91,50,53,54,93,0,42,115,99,114,105,112,116,0,42,98,117,116,95,114,101,102, +115,0,114,101,100,114,97,119,115,0,42,105,100,0,97,115,112,101,99,116,0,42,99,117,114,102,111,110,116,0,42,101, +100,105,116,116,114,101,101,0,116,114,101,101,116,121,112,101,0,42,102,105,108,101,115,0,97,99,116,105,118,101,95,102, +105,108,101,0,110,117,109,116,105,108,101,115,120,0,110,117,109,116,105,108,101,115,121,0,115,101,108,115,116,97,116,101, +0,118,105,101,119,114,101,99,116,0,98,111,111,107,109,97,114,107,114,101,99,116,0,115,99,114,111,108,108,112,111,115, +0,115,99,114,111,108,108,104,101,105,103,104,116,0,115,99,114,111,108,108,97,114,101,97,0,97,99,116,105,118,101,95, +98,111,111,107,109,97,114,107,0,112,114,118,95,119,0,112,114,118,95,104,0,42,105,109,103,0,111,117,116,108,105,110, +101,91,52,93,0,110,101,117,116,114,97,108,91,52,93,0,97,99,116,105,111,110,91,52,93,0,115,101,116,116,105,110, +103,91,52,93,0,115,101,116,116,105,110,103,49,91,52,93,0,115,101,116,116,105,110,103,50,91,52,93,0,110,117,109, +91,52,93,0,116,101,120,116,102,105,101,108,100,91,52,93,0,116,101,120,116,102,105,101,108,100,95,104,105,91,52,93, +0,112,111,112,117,112,91,52,93,0,116,101,120,116,91,52,93,0,116,101,120,116,95,104,105,91,52,93,0,109,101,110, +117,95,98,97,99,107,91,52,93,0,109,101,110,117,95,105,116,101,109,91,52,93,0,109,101,110,117,95,104,105,108,105, +116,101,91,52,93,0,109,101,110,117,95,116,101,120,116,91,52,93,0,109,101,110,117,95,116,101,120,116,95,104,105,91, +52,93,0,98,117,116,95,100,114,97,119,116,121,112,101,0,105,99,111,110,102,105,108,101,91,56,48,93,0,98,97,99, +107,91,52,93,0,104,101,97,100,101,114,91,52,93,0,112,97,110,101,108,91,52,93,0,115,104,97,100,101,49,91,52, +93,0,115,104,97,100,101,50,91,52,93,0,104,105,108,105,116,101,91,52,93,0,103,114,105,100,91,52,93,0,119,105, +114,101,91,52,93,0,115,101,108,101,99,116,91,52,93,0,108,97,109,112,91,52,93,0,97,99,116,105,118,101,91,52, +93,0,103,114,111,117,112,91,52,93,0,103,114,111,117,112,95,97,99,116,105,118,101,91,52,93,0,116,114,97,110,115, +102,111,114,109,91,52,93,0,118,101,114,116,101,120,91,52,93,0,118,101,114,116,101,120,95,115,101,108,101,99,116,91, +52,93,0,101,100,103,101,91,52,93,0,101,100,103,101,95,115,101,108,101,99,116,91,52,93,0,101,100,103,101,95,115, +101,97,109,91,52,93,0,101,100,103,101,95,115,104,97,114,112,91,52,93,0,101,100,103,101,95,102,97,99,101,115,101, +108,91,52,93,0,102,97,99,101,91,52,93,0,102,97,99,101,95,115,101,108,101,99,116,91,52,93,0,102,97,99,101, +95,100,111,116,91,52,93,0,110,111,114,109,97,108,91,52,93,0,98,111,110,101,95,115,111,108,105,100,91,52,93,0, +98,111,110,101,95,112,111,115,101,91,52,93,0,115,116,114,105,112,91,52,93,0,115,116,114,105,112,95,115,101,108,101, +99,116,91,52,93,0,99,102,114,97,109,101,91,52,93,0,118,101,114,116,101,120,95,115,105,122,101,0,102,97,99,101, +100,111,116,95,115,105,122,101,0,98,112,97,100,91,50,93,0,115,121,110,116,97,120,108,91,52,93,0,115,121,110,116, +97,120,110,91,52,93,0,115,121,110,116,97,120,98,91,52,93,0,115,121,110,116,97,120,118,91,52,93,0,115,121,110, +116,97,120,99,91,52,93,0,109,111,118,105,101,91,52,93,0,105,109,97,103,101,91,52,93,0,115,99,101,110,101,91, +52,93,0,97,117,100,105,111,91,52,93,0,101,102,102,101,99,116,91,52,93,0,112,108,117,103,105,110,91,52,93,0, +116,114,97,110,115,105,116,105,111,110,91,52,93,0,109,101,116,97,91,52,93,0,101,100,105,116,109,101,115,104,95,97, +99,116,105,118,101,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,91,52,93,0,104,97,110,100,108,101, +95,118,101,114,116,101,120,95,115,101,108,101,99,116,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,95, +115,105,122,101,0,104,112,97,100,91,55,93,0,115,111,108,105,100,91,52,93,0,116,117,105,0,116,98,117,116,115,0, +116,118,51,100,0,116,102,105,108,101,0,116,105,112,111,0,116,105,110,102,111,0,116,115,110,100,0,116,97,99,116,0, +116,110,108,97,0,116,115,101,113,0,116,105,109,97,0,116,105,109,97,115,101,108,0,116,101,120,116,0,116,111,111,112, +115,0,116,116,105,109,101,0,116,110,111,100,101,0,116,97,114,109,91,50,48,93,0,98,112,97,100,91,52,93,0,98, +112,97,100,49,91,52,93,0,115,112,101,99,91,52,93,0,100,117,112,102,108,97,103,0,115,97,118,101,116,105,109,101, +0,116,101,109,112,100,105,114,91,49,54,48,93,0,102,111,110,116,100,105,114,91,49,54,48,93,0,114,101,110,100,101, +114,100,105,114,91,49,54,48,93,0,116,101,120,116,117,100,105,114,91,49,54,48,93,0,112,108,117,103,116,101,120,100, +105,114,91,49,54,48,93,0,112,108,117,103,115,101,113,100,105,114,91,49,54,48,93,0,112,121,116,104,111,110,100,105, +114,91,49,54,48,93,0,115,111,117,110,100,100,105,114,91,49,54,48,93,0,121,102,101,120,112,111,114,116,100,105,114, +91,49,54,48,93,0,118,101,114,115,105,111,110,115,0,118,114,109,108,102,108,97,103,0,103,97,109,101,102,108,97,103, +115,0,119,104,101,101,108,108,105,110,101,115,99,114,111,108,108,0,117,105,102,108,97,103,0,108,97,110,103,117,97,103, +101,0,117,115,101,114,112,114,101,102,0,118,105,101,119,122,111,111,109,0,99,111,110,115,111,108,101,95,98,117,102,102, +101,114,0,99,111,110,115,111,108,101,95,111,117,116,0,109,105,120,98,117,102,115,105,122,101,0,102,111,110,116,115,105, +122,101,0,101,110,99,111,100,105,110,103,0,116,114,97,110,115,111,112,116,115,0,109,101,110,117,116,104,114,101,115,104, +111,108,100,49,0,109,101,110,117,116,104,114,101,115,104,111,108,100,50,0,102,111,110,116,110,97,109,101,91,50,53,54, +93,0,116,104,101,109,101,115,0,117,110,100,111,115,116,101,112,115,0,117,110,100,111,109,101,109,111,114,121,0,103,112, +95,109,97,110,104,97,116,116,101,110,100,105,115,116,0,103,112,95,101,117,99,108,105,100,101,97,110,100,105,115,116,0, +103,112,95,101,114,97,115,101,114,0,103,112,95,115,101,116,116,105,110,103,115,0,116,98,95,108,101,102,116,109,111,117, +115,101,0,116,98,95,114,105,103,104,116,109,111,117,115,101,0,108,105,103,104,116,91,51,93,0,116,119,95,104,111,116, +115,112,111,116,0,116,119,95,102,108,97,103,0,116,119,95,104,97,110,100,108,101,115,105,122,101,0,116,119,95,115,105, +122,101,0,116,101,120,116,105,109,101,111,117,116,0,116,101,120,99,111,108,108,101,99,116,114,97,116,101,0,109,101,109, +99,97,99,104,101,108,105,109,105,116,0,112,114,101,102,101,116,99,104,102,114,97,109,101,115,0,102,114,97,109,101,115, +101,114,118,101,114,112,111,114,116,0,112,97,100,95,114,111,116,95,97,110,103,108,101,0,111,98,99,101,110,116,101,114, +95,100,105,97,0,114,118,105,115,105,122,101,0,114,118,105,98,114,105,103,104,116,0,114,101,99,101,110,116,95,102,105, +108,101,115,0,115,109,111,111,116,104,95,118,105,101,119,116,120,0,103,108,114,101,115,108,105,109,105,116,0,110,100,111, +102,95,112,97,110,0,110,100,111,102,95,114,111,116,97,116,101,0,99,117,114,115,115,105,122,101,0,112,97,100,91,56, +93,0,118,101,114,115,101,109,97,115,116,101,114,91,49,54,48,93,0,118,101,114,115,101,117,115,101,114,91,49,54,48, +93,0,103,108,97,108,112,104,97,99,108,105,112,0,97,117,116,111,107,101,121,95,102,108,97,103,0,99,111,98,97,95, +119,101,105,103,104,116,0,118,101,114,116,98,97,115,101,0,101,100,103,101,98,97,115,101,0,97,114,101,97,98,97,115, +101,0,42,115,99,101,110,101,0,101,110,100,120,0,101,110,100,121,0,115,105,122,101,120,0,115,105,122,101,121,0,115, +99,101,110,101,110,114,0,115,99,114,101,101,110,110,114,0,102,117,108,108,0,109,97,105,110,119,105,110,0,119,105,110, +97,107,116,0,104,97,110,100,108,101,114,91,56,93,0,42,110,101,119,118,0,118,101,99,0,42,118,49,0,42,118,50, +0,112,97,110,101,108,110,97,109,101,91,54,52,93,0,116,97,98,110,97,109,101,91,54,52,93,0,100,114,97,119,110, +97,109,101,91,54,52,93,0,111,102,115,120,0,111,102,115,121,0,99,111,110,116,114,111,108,0,115,110,97,112,0,111, +108,100,95,111,102,115,120,0,111,108,100,95,111,102,115,121,0,115,111,114,116,99,111,117,110,116,101,114,0,42,112,97, +110,101,108,116,97,98,0,42,118,51,0,42,118,52,0,42,102,117,108,108,0,119,105,110,109,97,116,91,52,93,91,52, +93,0,104,101,97,100,114,99,116,0,119,105,110,114,99,116,0,104,101,97,100,119,105,110,0,119,105,110,0,104,101,97, +100,101,114,116,121,112,101,0,98,117,116,115,112,97,99,101,116,121,112,101,0,119,105,110,120,0,119,105,110,121,0,104, +101,97,100,95,115,119,97,112,0,104,101,97,100,95,101,113,117,97,108,0,119,105,110,95,115,119,97,112,0,119,105,110, +95,101,113,117,97,108,0,104,101,97,100,98,117,116,108,101,110,0,104,101,97,100,98,117,116,111,102,115,0,99,117,114, +115,111,114,0,115,112,97,99,101,100,97,116,97,0,117,105,98,108,111,99,107,115,0,112,97,110,101,108,115,0,115,117, +98,118,115,116,114,91,52,93,0,115,117,98,118,101,114,115,105,111,110,0,112,97,100,115,0,109,105,110,118,101,114,115, +105,111,110,0,109,105,110,115,117,98,118,101,114,115,105,111,110,0,100,105,115,112,108,97,121,109,111,100,101,0,42,99, +117,114,115,99,114,101,101,110,0,42,99,117,114,115,99,101,110,101,0,102,105,108,101,102,108,97,103,115,0,103,108,111, +98,97,108,102,0,110,97,109,101,91,56,48,93,0,42,105,98,117,102,0,42,105,98,117,102,95,99,111,109,112,0,42, +115,101,49,0,42,115,101,50,0,42,115,101,51,0,110,114,0,98,111,116,116,111,109,0,114,105,103,104,116,0,120,111, +102,115,0,121,111,102,115,0,108,105,102,116,91,51,93,0,103,97,109,109,97,91,51,93,0,103,97,105,110,91,51,93, +0,115,97,116,117,114,97,116,105,111,110,0,42,103,117,105,0,100,105,114,91,49,54,48,93,0,100,111,110,101,0,115, +116,97,114,116,115,116,105,108,108,0,101,110,100,115,116,105,108,108,0,42,115,116,114,105,112,100,97,116,97,0,111,114, +120,0,111,114,121,0,42,99,114,111,112,0,42,116,114,97,110,115,102,111,114,109,0,42,99,111,108,111,114,95,98,97, +108,97,110,99,101,0,42,116,115,116,114,105,112,100,97,116,97,0,42,116,115,116,114,105,112,100,97,116,97,95,115,116, +97,114,116,115,116,105,108,108,0,42,116,115,116,114,105,112,100,97,116,97,95,101,110,100,115,116,105,108,108,0,42,105, +98,117,102,95,115,116,97,114,116,115,116,105,108,108,0,42,105,98,117,102,95,101,110,100,115,116,105,108,108,0,42,105, +110,115,116,97,110,99,101,95,112,114,105,118,97,116,101,95,100,97,116,97,0,42,42,99,117,114,114,101,110,116,95,112, +114,105,118,97,116,101,95,100,97,116,97,0,42,116,109,112,0,115,116,97,114,116,111,102,115,0,101,110,100,111,102,115, +0,109,97,99,104,105,110,101,0,115,116,97,114,116,100,105,115,112,0,101,110,100,100,105,115,112,0,109,117,108,0,104, +97,110,100,115,105,122,101,0,97,110,105,109,95,112,114,101,115,101,101,107,0,42,115,116,114,105,112,0,102,97,99,102, +48,0,102,97,99,102,49,0,42,115,101,113,49,0,42,115,101,113,50,0,42,115,101,113,51,0,115,101,113,98,97,115, +101,0,42,115,111,117,110,100,0,42,104,100,97,117,100,105,111,0,108,101,118,101,108,0,112,97,110,0,115,116,114,111, +98,101,0,42,101,102,102,101,99,116,100,97,116,97,0,97,110,105,109,95,115,116,97,114,116,111,102,115,0,97,110,105, +109,95,101,110,100,111,102,115,0,98,108,101,110,100,95,109,111,100,101,0,98,108,101,110,100,95,111,112,97,99,105,116, +121,0,42,111,108,100,98,97,115,101,112,0,42,112,97,114,115,101,113,0,42,115,101,113,98,97,115,101,112,0,109,101, +116,97,115,116,97,99,107,0,101,100,103,101,87,105,100,116,104,0,102,111,114,119,97,114,100,0,119,105,112,101,116,121, +112,101,0,102,77,105,110,105,0,102,67,108,97,109,112,0,102,66,111,111,115,116,0,100,68,105,115,116,0,100,81,117, +97,108,105,116,121,0,98,78,111,67,111,109,112,0,83,99,97,108,101,120,73,110,105,0,83,99,97,108,101,121,73,110, +105,0,83,99,97,108,101,120,70,105,110,0,83,99,97,108,101,121,70,105,110,0,120,73,110,105,0,120,70,105,110,0, +121,73,110,105,0,121,70,105,110,0,114,111,116,73,110,105,0,114,111,116,70,105,110,0,105,110,116,101,114,112,111,108, +97,116,105,111,110,0,42,102,114,97,109,101,77,97,112,0,103,108,111,98,97,108,83,112,101,101,100,0,108,97,115,116, +86,97,108,105,100,70,114,97,109,101,0,98,108,101,110,100,70,114,97,109,101,115,0,98,117,116,116,121,112,101,0,117, +115,101,114,106,105,116,0,115,116,97,0,116,111,116,112,97,114,116,0,110,111,114,109,102,97,99,0,111,98,102,97,99, +0,114,97,110,100,102,97,99,0,116,101,120,102,97,99,0,114,97,110,100,108,105,102,101,0,102,111,114,99,101,91,51, +93,0,118,101,99,116,115,105,122,101,0,109,97,120,108,101,110,0,100,101,102,118,101,99,91,51,93,0,109,117,108,116, +91,52,93,0,108,105,102,101,91,52,93,0,99,104,105,108,100,91,52,93,0,109,97,116,91,52,93,0,116,101,120,109, +97,112,0,99,117,114,109,117,108,116,0,115,116,97,116,105,99,115,116,101,112,0,111,109,97,116,0,116,105,109,101,116, +101,120,0,115,112,101,101,100,116,101,120,0,102,108,97,103,50,110,101,103,0,118,101,114,116,103,114,111,117,112,95,118, +0,118,103,114,111,117,112,110,97,109,101,91,51,50,93,0,118,103,114,111,117,112,110,97,109,101,95,118,91,51,50,93, +0,42,107,101,121,115,0,109,105,110,102,97,99,0,117,115,101,100,0,117,115,101,100,101,108,101,109,0,100,120,0,100, +121,0,108,105,110,107,0,111,116,121,112,101,0,111,108,100,0,42,112,111,105,110,0,42,111,108,100,112,111,105,110,0, +114,101,115,101,116,100,105,115,116,0,108,97,115,116,118,97,108,0,42,109,97,0,107,101,121,0,113,117,97,108,0,113, +117,97,108,50,0,116,97,114,103,101,116,78,97,109,101,91,51,50,93,0,116,111,103,103,108,101,78,97,109,101,91,51, +50,93,0,118,97,108,117,101,91,51,50,93,0,109,97,120,118,97,108,117,101,91,51,50,93,0,100,101,108,97,121,0, +100,117,114,97,116,105,111,110,0,109,97,116,101,114,105,97,108,78,97,109,101,91,51,50,93,0,100,97,109,112,116,105, +109,101,114,0,112,114,111,112,110,97,109,101,91,51,50,93,0,109,97,116,110,97,109,101,91,51,50,93,0,97,120,105, +115,102,108,97,103,0,42,102,114,111,109,79,98,106,101,99,116,0,115,117,98,106,101,99,116,91,51,50,93,0,98,111, +100,121,91,51,50,93,0,112,117,108,115,101,0,102,114,101,113,0,116,111,116,108,105,110,107,115,0,42,42,108,105,110, +107,115,0,116,97,112,0,106,111,121,105,110,100,101,120,0,97,120,105,115,95,115,105,110,103,108,101,0,97,120,105,115, +102,0,98,117,116,116,111,110,0,104,97,116,0,104,97,116,102,0,112,114,101,99,105,115,105,111,110,0,115,116,114,91, +49,50,56,93,0,109,111,100,117,108,101,91,54,52,93,0,42,109,121,110,101,119,0,105,110,112,117,116,115,0,116,111, +116,115,108,105,110,107,115,0,42,42,115,108,105,110,107,115,0,118,97,108,111,0,115,116,97,116,101,95,109,97,115,107, +0,42,97,99,116,0,102,114,97,109,101,80,114,111,112,91,51,50,93,0,98,108,101,110,100,105,110,0,112,114,105,111, +114,105,116,121,0,101,110,100,95,114,101,115,101,116,0,115,116,114,105,100,101,97,120,105,115,0,115,116,114,105,100,101, +108,101,110,103,116,104,0,115,110,100,110,114,0,112,97,100,49,91,50,93,0,109,97,107,101,99,111,112,121,0,99,111, +112,121,109,97,100,101,0,112,97,100,50,91,49,93,0,116,114,97,99,107,0,42,109,101,0,108,105,110,86,101,108,111, +99,105,116,121,91,51,93,0,97,110,103,86,101,108,111,99,105,116,121,91,51,93,0,108,111,99,97,108,102,108,97,103, +0,100,121,110,95,111,112,101,114,97,116,105,111,110,0,102,111,114,99,101,108,111,99,91,51,93,0,102,111,114,99,101, +114,111,116,91,51,93,0,108,105,110,101,97,114,118,101,108,111,99,105,116,121,91,51,93,0,97,110,103,117,108,97,114, +118,101,108,111,99,105,116,121,91,51,93,0,42,114,101,102,101,114,101,110,99,101,0,98,117,116,115,116,97,0,98,117, +116,101,110,100,0,109,105,110,0,109,97,120,0,118,105,115,105,102,97,99,0,114,111,116,100,97,109,112,0,109,105,110, +108,111,99,91,51,93,0,109,97,120,108,111,99,91,51,93,0,109,105,110,114,111,116,91,51,93,0,109,97,120,114,111, +116,91,51,93,0,109,97,116,112,114,111,112,91,51,50,93,0,100,105,115,116,114,105,98,117,116,105,111,110,0,105,110, +116,95,97,114,103,95,49,0,105,110,116,95,97,114,103,95,50,0,102,108,111,97,116,95,97,114,103,95,49,0,102,108, +111,97,116,95,97,114,103,95,50,0,116,111,80,114,111,112,78,97,109,101,91,51,50,93,0,42,116,111,79,98,106,101, +99,116,0,98,111,100,121,84,121,112,101,0,102,105,108,101,110,97,109,101,91,54,52,93,0,108,111,97,100,97,110,105, +110,97,109,101,91,54,52,93,0,105,110,116,95,97,114,103,0,102,108,111,97,116,95,97,114,103,0,103,111,0,97,99, +99,101,108,108,101,114,97,116,105,111,110,0,109,97,120,115,112,101,101,100,0,109,97,120,114,111,116,115,112,101,101,100, +0,109,97,120,116,105,108,116,115,112,101,101,100,0,116,105,108,116,100,97,109,112,0,115,112,101,101,100,100,97,109,112, +0,42,115,97,109,112,108,101,0,42,115,116,114,101,97,109,0,42,110,101,119,112,97,99,107,101,100,102,105,108,101,0, +42,115,110,100,95,115,111,117,110,100,0,112,97,110,110,105,110,103,0,97,116,116,101,110,117,97,116,105,111,110,0,112, +105,116,99,104,0,109,105,110,95,103,97,105,110,0,109,97,120,95,103,97,105,110,0,100,105,115,116,97,110,99,101,0, +115,116,114,101,97,109,108,101,110,0,99,104,97,110,110,101,108,115,0,104,105,103,104,112,114,105,111,0,112,97,100,91, +49,48,93,0,103,97,105,110,0,100,111,112,112,108,101,114,102,97,99,116,111,114,0,100,111,112,112,108,101,114,118,101, +108,111,99,105,116,121,0,110,117,109,115,111,117,110,100,115,98,108,101,110,100,101,114,0,110,117,109,115,111,117,110,100, +115,103,97,109,101,101,110,103,105,110,101,0,42,108,97,109,112,114,101,110,0,103,111,98,106,101,99,116,0,100,117,112, +108,105,95,111,102,115,91,51,93,0,99,104,105,108,100,98,97,115,101,0,114,111,108,108,0,104,101,97,100,91,51,93, +0,116,97,105,108,91,51,93,0,98,111,110,101,95,109,97,116,91,51,93,91,51,93,0,97,114,109,95,104,101,97,100, +91,51,93,0,97,114,109,95,116,97,105,108,91,51,93,0,97,114,109,95,109,97,116,91,52,93,91,52,93,0,120,119, +105,100,116,104,0,122,119,105,100,116,104,0,101,97,115,101,49,0,101,97,115,101,50,0,114,97,100,95,104,101,97,100, +0,114,97,100,95,116,97,105,108,0,98,111,110,101,98,97,115,101,0,99,104,97,105,110,98,97,115,101,0,112,97,116, +104,102,108,97,103,0,108,97,121,101,114,95,112,114,111,116,101,99,116,101,100,0,103,104,111,115,116,101,112,0,103,104, +111,115,116,115,105,122,101,0,103,104,111,115,116,116,121,112,101,0,112,97,116,104,115,105,122,101,0,103,104,111,115,116, +115,102,0,103,104,111,115,116,101,102,0,112,97,116,104,115,102,0,112,97,116,104,101,102,0,112,97,116,104,98,99,0, +112,97,116,104,97,99,0,99,111,110,115,116,102,108,97,103,0,105,107,102,108,97,103,0,115,101,108,101,99,116,102,108, +97,103,0,97,103,114,112,95,105,110,100,101,120,0,42,98,111,110,101,0,42,99,104,105,108,100,0,105,107,116,114,101, +101,0,42,98,95,98,111,110,101,95,109,97,116,115,0,42,100,117,97,108,95,113,117,97,116,0,42,98,95,98,111,110, +101,95,100,117,97,108,95,113,117,97,116,115,0,99,104,97,110,95,109,97,116,91,52,93,91,52,93,0,112,111,115,101, +95,109,97,116,91,52,93,91,52,93,0,112,111,115,101,95,104,101,97,100,91,51,93,0,112,111,115,101,95,116,97,105, +108,91,51,93,0,108,105,109,105,116,109,105,110,91,51,93,0,108,105,109,105,116,109,97,120,91,51,93,0,115,116,105, +102,102,110,101,115,115,91,51,93,0,105,107,115,116,114,101,116,99,104,0,42,99,117,115,116,111,109,0,99,104,97,110, +98,97,115,101,0,112,114,111,120,121,95,108,97,121,101,114,0,115,116,114,105,100,101,95,111,102,102,115,101,116,91,51, +93,0,99,121,99,108,105,99,95,111,102,102,115,101,116,91,51,93,0,97,103,114,111,117,112,115,0,97,99,116,105,118, +101,95,103,114,111,117,112,0,99,117,115,116,111,109,67,111,108,0,99,115,0,42,103,114,112,0,114,101,115,101,114,118, +101,100,49,0,103,114,111,117,112,115,0,97,99,116,105,118,101,95,109,97,114,107,101,114,0,97,99,116,110,114,0,97, +99,116,119,105,100,116,104,0,116,105,109,101,115,108,105,100,101,0,110,97,109,101,91,51,48,93,0,111,119,110,115,112, +97,99,101,0,116,97,114,115,112,97,99,101,0,101,110,102,111,114,99,101,0,104,101,97,100,116,97,105,108,0,42,116, +97,114,0,115,117,98,116,97,114,103,101,116,91,51,50,93,0,109,97,116,114,105,120,91,52,93,91,52,93,0,115,112, +97,99,101,0,42,112,114,111,112,0,116,97,114,110,117,109,0,116,97,114,103,101,116,115,0,105,116,101,114,97,116,105, +111,110,115,0,114,111,111,116,98,111,110,101,0,109,97,120,95,114,111,111,116,98,111,110,101,0,42,112,111,108,101,116, +97,114,0,112,111,108,101,115,117,98,116,97,114,103,101,116,91,51,50,93,0,112,111,108,101,97,110,103,108,101,0,111, +114,105,101,110,116,119,101,105,103,104,116,0,103,114,97,98,116,97,114,103,101,116,91,51,93,0,114,101,115,101,114,118, +101,100,50,0,109,105,110,109,97,120,102,108,97,103,0,115,116,117,99,107,0,99,97,99,104,101,91,51,93,0,108,111, +99,107,102,108,97,103,0,102,111,108,108,111,119,102,108,97,103,0,118,111,108,109,111,100,101,0,112,108,97,110,101,0, +111,114,103,108,101,110,103,116,104,0,98,117,108,103,101,0,112,105,118,88,0,112,105,118,89,0,112,105,118,90,0,97, +120,88,0,97,120,89,0,97,120,90,0,109,105,110,76,105,109,105,116,91,54,93,0,109,97,120,76,105,109,105,116,91, +54,93,0,101,120,116,114,97,70,122,0,105,110,118,109,97,116,91,52,93,91,52,93,0,102,114,111,109,0,116,111,0, +109,97,112,91,51,93,0,101,120,112,111,0,102,114,111,109,95,109,105,110,91,51,93,0,102,114,111,109,95,109,97,120, +91,51,93,0,116,111,95,109,105,110,91,51,93,0,116,111,95,109,97,120,91,51,93,0,122,109,105,110,0,122,109,97, +120,0,112,97,100,91,57,93,0,99,104,97,110,110,101,108,91,51,50,93,0,110,111,95,114,111,116,95,97,120,105,115, +0,115,116,114,105,100,101,95,97,120,105,115,0,99,117,114,109,111,100,0,97,99,116,115,116,97,114,116,0,97,99,116, +101,110,100,0,97,99,116,111,102,102,115,0,115,116,114,105,100,101,108,101,110,0,98,108,101,110,100,111,117,116,0,115, +116,114,105,100,101,99,104,97,110,110,101,108,91,51,50,93,0,111,102,102,115,95,98,111,110,101,91,51,50,93,0,104, +97,115,105,110,112,117,116,0,104,97,115,111,117,116,112,117,116,0,100,97,116,97,116,121,112,101,0,115,111,99,107,101, +116,116,121,112,101,0,42,110,101,119,95,115,111,99,107,0,110,115,0,108,105,109,105,116,0,115,116,97,99,107,95,105, +110,100,101,120,0,105,110,116,101,114,110,0,115,116,97,99,107,95,105,110,100,101,120,95,101,120,116,0,108,111,99,120, +0,108,111,99,121,0,111,119,110,95,105,110,100,101,120,0,116,111,95,105,110,100,101,120,0,42,116,111,115,111,99,107, +0,42,108,105,110,107,0,42,110,101,119,95,110,111,100,101,0,117,115,101,114,110,97,109,101,91,51,50,93,0,108,97, +115,116,121,0,111,117,116,112,117,116,115,0,42,115,116,111,114,97,103,101,0,109,105,110,105,119,105,100,116,104,0,99, +117,115,116,111,109,49,0,99,117,115,116,111,109,50,0,99,117,115,116,111,109,51,0,99,117,115,116,111,109,52,0,110, +101,101,100,95,101,120,101,99,0,101,120,101,99,0,116,111,116,114,0,98,117,116,114,0,112,114,118,114,0,42,116,121, +112,101,105,110,102,111,0,42,102,114,111,109,110,111,100,101,0,42,116,111,110,111,100,101,0,42,102,114,111,109,115,111, +99,107,0,110,111,100,101,115,0,108,105,110,107,115,0,42,115,116,97,99,107,0,42,116,104,114,101,97,100,115,116,97, +99,107,0,105,110,105,116,0,115,116,97,99,107,115,105,122,101,0,99,117,114,95,105,110,100,101,120,0,97,108,108,116, +121,112,101,115,0,42,111,119,110,116,121,112,101,0,42,115,101,108,105,110,0,42,115,101,108,111,117,116,0,40,42,116, +105,109,101,99,117,114,115,111,114,41,40,41,0,40,42,115,116,97,116,115,95,100,114,97,119,41,40,41,0,40,42,116, +101,115,116,95,98,114,101,97,107,41,40,41,0,99,121,99,108,105,99,0,109,111,118,105,101,0,115,97,109,112,108,101, +115,0,109,105,110,115,112,101,101,100,0,112,101,114,99,101,110,116,120,0,112,101,114,99,101,110,116,121,0,98,111,107, +101,104,0,99,117,114,118,101,100,0,105,109,97,103,101,95,105,110,95,119,105,100,116,104,0,105,109,97,103,101,95,105, +110,95,104,101,105,103,104,116,0,99,101,110,116,101,114,95,120,0,99,101,110,116,101,114,95,121,0,115,112,105,110,0, +105,116,101,114,0,119,114,97,112,0,115,105,103,109,97,95,99,111,108,111,114,0,115,105,103,109,97,95,115,112,97,99, +101,0,104,117,101,0,115,97,116,0,116,49,0,116,50,0,116,51,0,102,115,116,114,101,110,103,116,104,0,102,97,108, +112,104,97,0,107,101,121,91,52,93,0,120,49,0,120,50,0,121,49,0,121,50,0,99,111,108,110,97,109,101,91,51, +50,93,0,98,107,116,121,112,101,0,114,111,116,97,116,105,111,110,0,112,114,101,118,105,101,119,0,103,97,109,99,111, +0,110,111,95,122,98,117,102,0,102,115,116,111,112,0,109,97,120,98,108,117,114,0,98,116,104,114,101,115,104,0,42, +100,105,99,116,0,42,110,111,100,101,0,97,110,103,108,101,95,111,102,115,0,99,111,108,109,111,100,0,109,105,120,0, +116,104,114,101,115,104,111,108,100,0,102,97,100,101,0,109,0,99,0,106,105,116,0,112,114,111,106,0,102,105,116,0, +115,104,111,114,116,121,0,109,105,110,116,97,98,108,101,0,109,97,120,116,97,98,108,101,0,101,120,116,95,105,110,91, +50,93,0,101,120,116,95,111,117,116,91,50,93,0,42,99,117,114,118,101,0,42,116,97,98,108,101,0,42,112,114,101, +109,117,108,116,97,98,108,101,0,99,117,114,114,0,99,108,105,112,114,0,99,109,91,52,93,0,98,108,97,99,107,91, +51,93,0,119,104,105,116,101,91,51,93,0,98,119,109,117,108,91,51,93,0,115,97,109,112,108,101,91,51,93,0,111, +102,102,115,101,116,91,50,93,0,105,110,110,101,114,114,97,100,105,117,115,0,114,97,116,101,0,114,103,98,91,51,93, +0,99,108,111,110,101,0,97,99,116,105,118,101,95,114,110,100,0,97,99,116,105,118,101,95,99,108,111,110,101,0,97, +99,116,105,118,101,95,109,97,115,107,0,42,108,97,121,101,114,115,0,116,111,116,108,97,121,101,114,0,109,97,120,108, +97,121,101,114,0,116,111,116,115,105,122,101,0,42,112,111,111,108,0,101,100,105,116,102,108,97,103,0,118,101,108,91, +51,93,0,114,111,116,91,52,93,0,97,118,101,91,51,93,0,110,117,109,0,112,97,114,101,110,116,0,112,97,91,52, +93,0,119,91,52,93,0,102,117,118,91,52,93,0,102,111,102,102,115,101,116,0,114,97,110,100,91,51,93,0,42,115, +116,105,99,107,95,111,98,0,112,114,101,118,95,115,116,97,116,101,0,42,104,97,105,114,0,105,95,114,111,116,91,52, +93,0,114,95,114,111,116,91,52,93,0,114,95,97,118,101,91,51,93,0,114,95,118,101,91,51,93,0,100,105,101,116, +105,109,101,0,98,97,110,107,0,115,105,122,101,109,117,108,0,110,117,109,95,100,109,99,97,99,104,101,0,98,112,105, +0,97,108,105,118,101,0,108,111,111,112,0,100,105,115,116,114,0,112,104,121,115,116,121,112,101,0,114,111,116,109,111, +100,101,0,97,118,101,109,111,100,101,0,114,101,97,99,116,101,118,101,110,116,0,100,114,97,119,0,100,114,97,119,95, +97,115,0,100,114,97,119,95,115,105,122,101,0,99,104,105,108,100,116,121,112,101,0,100,114,97,119,95,115,116,101,112, +0,114,101,110,95,115,116,101,112,0,104,97,105,114,95,115,116,101,112,0,107,101,121,115,95,115,116,101,112,0,97,100, +97,112,116,95,97,110,103,108,101,0,97,100,97,112,116,95,112,105,120,0,114,111,116,102,114,111,109,0,105,110,116,101, +103,114,97,116,111,114,0,110,98,101,116,119,101,101,110,0,98,111,105,100,110,101,105,103,104,98,111,117,114,115,0,98, +98,95,97,108,105,103,110,0,98,98,95,117,118,95,115,112,108,105,116,0,98,98,95,97,110,105,109,0,98,98,95,115, +112,108,105,116,95,111,102,102,115,101,116,0,98,98,95,116,105,108,116,0,98,98,95,114,97,110,100,95,116,105,108,116, +0,98,98,95,111,102,102,115,101,116,91,50,93,0,115,105,109,112,108,105,102,121,95,102,108,97,103,0,115,105,109,112, +108,105,102,121,95,114,101,102,115,105,122,101,0,115,105,109,112,108,105,102,121,95,114,97,116,101,0,115,105,109,112,108, +105,102,121,95,116,114,97,110,115,105,116,105,111,110,0,115,105,109,112,108,105,102,121,95,118,105,101,119,112,111,114,116, +0,116,105,109,101,116,119,101,97,107,0,106,105,116,102,97,99,0,107,101,121,101,100,95,116,105,109,101,0,101,102,102, +95,104,97,105,114,0,103,114,105,100,95,114,101,115,0,112,97,114,116,102,97,99,0,116,97,110,102,97,99,0,116,97, +110,112,104,97,115,101,0,114,101,97,99,116,102,97,99,0,97,118,101,102,97,99,0,112,104,97,115,101,102,97,99,0, +114,97,110,100,114,111,116,102,97,99,0,114,97,110,100,112,104,97,115,101,102,97,99,0,114,97,110,100,115,105,122,101, +0,114,101,97,99,116,115,104,97,112,101,0,97,99,99,91,51,93,0,100,114,97,103,102,97,99,0,98,114,111,119,110, +102,97,99,0,100,97,109,112,102,97,99,0,97,98,115,108,101,110,103,116,104,0,114,97,110,100,108,101,110,103,116,104, +0,99,104,105,108,100,95,110,98,114,0,114,101,110,95,99,104,105,108,100,95,110,98,114,0,112,97,114,101,110,116,115, +0,99,104,105,108,100,115,105,122,101,0,99,104,105,108,100,114,97,110,100,115,105,122,101,0,99,104,105,108,100,114,97, +100,0,99,104,105,108,100,102,108,97,116,0,99,104,105,108,100,115,112,114,101,97,100,0,99,108,117,109,112,102,97,99, +0,99,108,117,109,112,112,111,119,0,114,111,117,103,104,49,0,114,111,117,103,104,49,95,115,105,122,101,0,114,111,117, +103,104,50,0,114,111,117,103,104,50,95,115,105,122,101,0,114,111,117,103,104,50,95,116,104,114,101,115,0,114,111,117, +103,104,95,101,110,100,0,114,111,117,103,104,95,101,110,100,95,115,104,97,112,101,0,98,114,97,110,99,104,95,116,104, +114,101,115,0,100,114,97,119,95,108,105,110,101,91,50,93,0,109,97,120,95,108,97,116,95,97,99,99,0,109,97,120, +95,116,97,110,95,97,99,99,0,97,118,101,114,97,103,101,95,118,101,108,0,98,97,110,107,105,110,103,0,109,97,120, +95,98,97,110,107,0,103,114,111,117,110,100,122,0,98,111,105,100,102,97,99,91,56,93,0,98,111,105,100,114,117,108, +101,91,56,93,0,42,101,102,102,95,103,114,111,117,112,0,42,100,117,112,95,111,98,0,42,98,98,95,111,98,0,42, +112,100,50,0,42,112,97,114,116,0,42,101,100,105,116,0,42,42,112,97,116,104,99,97,99,104,101,0,42,42,99,104, +105,108,100,99,97,99,104,101,0,112,97,116,104,99,97,99,104,101,98,117,102,115,0,99,104,105,108,100,99,97,99,104, +101,98,117,102,115,0,42,116,97,114,103,101,116,95,111,98,0,42,107,101,121,101,100,95,111,98,0,42,108,97,116,116, +105,99,101,0,101,102,102,101,99,116,111,114,115,0,114,101,97,99,116,101,118,101,110,116,115,0,116,111,116,99,104,105, +108,100,0,116,111,116,99,97,99,104,101,100,0,116,111,116,99,104,105,108,100,99,97,99,104,101,0,116,97,114,103,101, +116,95,112,115,121,115,0,107,101,121,101,100,95,112,115,121,115,0,116,111,116,107,101,121,101,100,0,98,97,107,101,115, +112,97,99,101,0,98,98,95,117,118,110,97,109,101,91,51,93,91,51,50,93,0,118,103,114,111,117,112,91,49,50,93, +0,118,103,95,110,101,103,0,114,116,51,0,42,114,101,110,100,101,114,100,97,116,97,0,42,99,97,99,104,101,0,67, +100,105,115,0,67,118,105,0,91,51,93,0,115,116,114,117,99,116,117,114,97,108,0,98,101,110,100,105,110,103,0,109, +97,120,95,98,101,110,100,0,109,97,120,95,115,116,114,117,99,116,0,109,97,120,95,115,104,101,97,114,0,97,118,103, +95,115,112,114,105,110,103,95,108,101,110,0,116,105,109,101,115,99,97,108,101,0,101,102,102,95,102,111,114,99,101,95, +115,99,97,108,101,0,101,102,102,95,119,105,110,100,95,115,99,97,108,101,0,115,105,109,95,116,105,109,101,95,111,108, +100,0,115,116,101,112,115,80,101,114,70,114,97,109,101,0,112,114,101,114,111,108,108,0,109,97,120,115,112,114,105,110, +103,108,101,110,0,115,111,108,118,101,114,95,116,121,112,101,0,118,103,114,111,117,112,95,98,101,110,100,0,118,103,114, +111,117,112,95,109,97,115,115,0,118,103,114,111,117,112,95,115,116,114,117,99,116,0,112,114,101,115,101,116,115,0,42, +99,111,108,108,105,115,105,111,110,95,108,105,115,116,0,101,112,115,105,108,111,110,0,115,101,108,102,95,102,114,105,99, +116,105,111,110,0,115,101,108,102,101,112,115,105,108,111,110,0,115,101,108,102,95,108,111,111,112,95,99,111,117,110,116, +0,108,111,111,112,95,99,111,117,110,116,0,112,114,101,115,115,117,114,101,0,42,112,111,105,110,116,115,0,116,111,116, +112,111,105,110,116,115,0,116,104,105,99,107,110,101,115,115,0,115,116,114,111,107,101,115,0,102,114,97,109,101,110,117, +109,0,42,97,99,116,102,114,97,109,101,0,103,115,116,101,112,0,105,110,102,111,91,49,50,56,93,0,115,98,117,102, +102,101,114,95,115,105,122,101,0,115,98,117,102,102,101,114,95,115,102,108,97,103,0,42,115,98,117,102,102,101,114,0, +0,0,0,84,89,80,69,100,1,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,0,117,115,104,111, +114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118, +111,105,100,0,76,105,110,107,0,76,105,110,107,68,97,116,97,0,76,105,115,116,66,97,115,101,0,118,101,99,50,115, +0,118,101,99,50,105,0,118,101,99,50,102,0,118,101,99,50,100,0,118,101,99,51,105,0,118,101,99,51,102,0,118, +101,99,51,100,0,118,101,99,52,105,0,118,101,99,52,102,0,118,101,99,52,100,0,114,99,116,105,0,114,99,116,102, +0,73,68,80,114,111,112,101,114,116,121,68,97,116,97,0,73,68,80,114,111,112,101,114,116,121,0,73,68,0,76,105, +98,114,97,114,121,0,70,105,108,101,68,97,116,97,0,80,114,101,118,105,101,119,73,109,97,103,101,0,73,112,111,68, +114,105,118,101,114,0,79,98,106,101,99,116,0,73,112,111,67,117,114,118,101,0,66,80,111,105,110,116,0,66,101,122, +84,114,105,112,108,101,0,73,112,111,0,75,101,121,66,108,111,99,107,0,75,101,121,0,83,99,114,105,112,116,76,105, +110,107,0,84,101,120,116,76,105,110,101,0,84,101,120,116,77,97,114,107,101,114,0,84,101,120,116,0,80,97,99,107, +101,100,70,105,108,101,0,67,97,109,101,114,97,0,73,109,97,103,101,85,115,101,114,0,73,109,97,103,101,0,71,80, +85,84,101,120,116,117,114,101,0,97,110,105,109,0,82,101,110,100,101,114,82,101,115,117,108,116,0,77,84,101,120,0, +84,101,120,0,80,108,117,103,105,110,84,101,120,0,67,66,68,97,116,97,0,67,111,108,111,114,66,97,110,100,0,69, +110,118,77,97,112,0,73,109,66,117,102,0,98,78,111,100,101,84,114,101,101,0,84,101,120,77,97,112,112,105,110,103, +0,76,97,109,112,0,67,117,114,118,101,77,97,112,112,105,110,103,0,87,97,118,101,0,77,97,116,101,114,105,97,108, +0,71,114,111,117,112,0,86,70,111,110,116,0,86,70,111,110,116,68,97,116,97,0,77,101,116,97,69,108,101,109,0, +66,111,117,110,100,66,111,120,0,77,101,116,97,66,97,108,108,0,78,117,114,98,0,67,104,97,114,73,110,102,111,0, +84,101,120,116,66,111,120,0,67,117,114,118,101,0,80,97,116,104,0,77,101,115,104,0,77,70,97,99,101,0,77,84, +70,97,99,101,0,84,70,97,99,101,0,77,86,101,114,116,0,77,69,100,103,101,0,77,68,101,102,111,114,109,86,101, +114,116,0,77,67,111,108,0,77,83,116,105,99,107,121,0,77,83,101,108,101,99,116,0,67,117,115,116,111,109,68,97, +116,97,0,77,117,108,116,105,114,101,115,0,80,97,114,116,105,97,108,86,105,115,105,98,105,108,105,116,121,0,77,68, +101,102,111,114,109,87,101,105,103,104,116,0,77,84,101,120,80,111,108,121,0,77,76,111,111,112,85,86,0,77,76,111, +111,112,67,111,108,0,77,70,108,111,97,116,80,114,111,112,101,114,116,121,0,77,73,110,116,80,114,111,112,101,114,116, +121,0,77,83,116,114,105,110,103,80,114,111,112,101,114,116,121,0,79,114,105,103,83,112,97,99,101,70,97,99,101,0, +77,117,108,116,105,114,101,115,67,111,108,0,77,117,108,116,105,114,101,115,67,111,108,70,97,99,101,0,77,117,108,116, +105,114,101,115,70,97,99,101,0,77,117,108,116,105,114,101,115,69,100,103,101,0,77,117,108,116,105,114,101,115,76,101, +118,101,108,0,77,117,108,116,105,114,101,115,77,97,112,78,111,100,101,0,77,111,100,105,102,105,101,114,68,97,116,97, +0,83,117,98,115,117,114,102,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,77,111,100,105, +102,105,101,114,68,97,116,97,0,67,117,114,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,66,117,105,108,100, +77,111,100,105,102,105,101,114,68,97,116,97,0,77,97,115,107,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114, +114,97,121,77,111,100,105,102,105,101,114,68,97,116,97,0,77,105,114,114,111,114,77,111,100,105,102,105,101,114,68,97, +116,97,0,69,100,103,101,83,112,108,105,116,77,111,100,105,102,105,101,114,68,97,116,97,0,66,101,118,101,108,77,111, +100,105,102,105,101,114,68,97,116,97,0,66,77,101,115,104,77,111,100,105,102,105,101,114,68,97,116,97,0,68,105,115, +112,108,97,99,101,77,111,100,105,102,105,101,114,68,97,116,97,0,85,86,80,114,111,106,101,99,116,77,111,100,105,102, +105,101,114,68,97,116,97,0,68,101,99,105,109,97,116,101,77,111,100,105,102,105,101,114,68,97,116,97,0,83,109,111, +111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67,97,115,116,77,111,100,105,102,105,101,114,68,97,116,97, +0,87,97,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114,109,97,116,117,114,101,77,111,100,105,102,105, +101,114,68,97,116,97,0,72,111,111,107,77,111,100,105,102,105,101,114,68,97,116,97,0,83,111,102,116,98,111,100,121, +77,111,100,105,102,105,101,114,68,97,116,97,0,67,108,111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67, +108,111,116,104,0,67,108,111,116,104,83,105,109,83,101,116,116,105,110,103,115,0,67,108,111,116,104,67,111,108,108,83, +101,116,116,105,110,103,115,0,80,111,105,110,116,67,97,99,104,101,0,67,111,108,108,105,115,105,111,110,77,111,100,105, +102,105,101,114,68,97,116,97,0,66,86,72,84,114,101,101,0,83,117,114,102,97,99,101,77,111,100,105,102,105,101,114, +68,97,116,97,0,68,101,114,105,118,101,100,77,101,115,104,0,66,86,72,84,114,101,101,70,114,111,109,77,101,115,104, +0,66,111,111,108,101,97,110,77,111,100,105,102,105,101,114,68,97,116,97,0,77,68,101,102,73,110,102,108,117,101,110, +99,101,0,77,68,101,102,67,101,108,108,0,77,101,115,104,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97, +116,97,0,80,97,114,116,105,99,108,101,83,121,115,116,101,109,77,111,100,105,102,105,101,114,68,97,116,97,0,80,97, +114,116,105,99,108,101,83,121,115,116,101,109,0,80,97,114,116,105,99,108,101,73,110,115,116,97,110,99,101,77,111,100, +105,102,105,101,114,68,97,116,97,0,69,120,112,108,111,100,101,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108, +117,105,100,115,105,109,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108,117,105,100,115,105,109,83,101,116,116,105, +110,103,115,0,83,104,114,105,110,107,119,114,97,112,77,111,100,105,102,105,101,114,68,97,116,97,0,83,105,109,112,108, +101,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,0,98,68,101,102, +111,114,109,71,114,111,117,112,0,98,65,99,116,105,111,110,0,98,80,111,115,101,0,66,117,108,108,101,116,83,111,102, +116,66,111,100,121,0,80,97,114,116,68,101,102,108,101,99,116,0,83,111,102,116,66,111,100,121,0,79,98,72,111,111, +107,0,82,78,71,0,83,66,86,101,114,116,101,120,0,66,111,100,121,80,111,105,110,116,0,66,111,100,121,83,112,114, +105,110,103,0,83,66,83,99,114,97,116,99,104,0,87,111,114,108,100,0,82,97,100,105,111,0,66,97,115,101,0,65, +118,105,67,111,100,101,99,68,97,116,97,0,81,117,105,99,107,116,105,109,101,67,111,100,101,99,68,97,116,97,0,70, +70,77,112,101,103,67,111,100,101,99,68,97,116,97,0,65,117,100,105,111,68,97,116,97,0,83,99,101,110,101,82,101, +110,100,101,114,76,97,121,101,114,0,82,101,110,100,101,114,68,97,116,97,0,82,101,110,100,101,114,80,114,111,102,105, +108,101,0,71,97,109,101,70,114,97,109,105,110,103,0,84,105,109,101,77,97,114,107,101,114,0,73,109,97,103,101,80, +97,105,110,116,83,101,116,116,105,110,103,115,0,66,114,117,115,104,0,80,97,114,116,105,99,108,101,66,114,117,115,104, +68,97,116,97,0,80,97,114,116,105,99,108,101,69,100,105,116,83,101,116,116,105,110,103,115,0,84,114,97,110,115,102, +111,114,109,79,114,105,101,110,116,97,116,105,111,110,0,84,111,111,108,83,101,116,116,105,110,103,115,0,66,114,117,115, +104,68,97,116,97,0,83,99,117,108,112,116,68,97,116,97,0,83,99,117,108,112,116,83,101,115,115,105,111,110,0,83, +99,101,110,101,0,68,97,103,70,111,114,101,115,116,0,66,71,112,105,99,0,86,105,101,119,51,68,0,83,112,97,99, +101,76,105,110,107,0,83,99,114,65,114,101,97,0,82,101,110,100,101,114,73,110,102,111,0,82,101,116,111,112,111,86, +105,101,119,68,97,116,97,0,86,105,101,119,68,101,112,116,104,115,0,98,71,80,100,97,116,97,0,86,105,101,119,50, +68,0,83,112,97,99,101,73,110,102,111,0,83,112,97,99,101,73,112,111,0,83,112,97,99,101,66,117,116,115,0,83, +112,97,99,101,83,101,113,0,83,112,97,99,101,70,105,108,101,0,100,105,114,101,110,116,114,121,0,66,108,101,110,100, +72,97,110,100,108,101,0,83,112,97,99,101,79,111,112,115,0,84,114,101,101,83,116,111,114,101,0,84,114,101,101,83, +116,111,114,101,69,108,101,109,0,83,112,97,99,101,73,109,97,103,101,0,83,112,97,99,101,78,108,97,0,83,112,97, +99,101,84,101,120,116,0,83,99,114,105,112,116,0,83,112,97,99,101,83,99,114,105,112,116,0,83,112,97,99,101,84, +105,109,101,0,83,112,97,99,101,78,111,100,101,0,83,112,97,99,101,73,109,97,83,101,108,0,70,105,108,101,76,105, +115,116,0,84,104,101,109,101,85,73,0,84,104,101,109,101,83,112,97,99,101,0,84,104,101,109,101,87,105,114,101,67, +111,108,111,114,0,98,84,104,101,109,101,0,83,111,108,105,100,76,105,103,104,116,0,85,115,101,114,68,101,102,0,98, +83,99,114,101,101,110,0,83,99,114,86,101,114,116,0,83,99,114,69,100,103,101,0,80,97,110,101,108,0,70,105,108, +101,71,108,111,98,97,108,0,83,116,114,105,112,69,108,101,109,0,84,83,116,114,105,112,69,108,101,109,0,83,116,114, +105,112,67,114,111,112,0,83,116,114,105,112,84,114,97,110,115,102,111,114,109,0,83,116,114,105,112,67,111,108,111,114, +66,97,108,97,110,99,101,0,83,116,114,105,112,67,111,108,111,114,66,97,108,97,110,99,101,71,85,73,72,101,108,112, +101,114,0,83,116,114,105,112,80,114,111,120,121,0,83,116,114,105,112,0,80,108,117,103,105,110,83,101,113,0,83,101, +113,117,101,110,99,101,0,98,83,111,117,110,100,0,104,100,97,117,100,105,111,0,77,101,116,97,83,116,97,99,107,0, +69,100,105,116,105,110,103,0,87,105,112,101,86,97,114,115,0,71,108,111,119,86,97,114,115,0,84,114,97,110,115,102, +111,114,109,86,97,114,115,0,83,111,108,105,100,67,111,108,111,114,86,97,114,115,0,83,112,101,101,100,67,111,110,116, +114,111,108,86,97,114,115,0,69,102,102,101,99,116,0,66,117,105,108,100,69,102,102,0,80,97,114,116,69,102,102,0, +80,97,114,116,105,99,108,101,0,87,97,118,101,69,102,102,0,79,111,112,115,0,98,80,114,111,112,101,114,116,121,0, +98,78,101,97,114,83,101,110,115,111,114,0,98,77,111,117,115,101,83,101,110,115,111,114,0,98,84,111,117,99,104,83, +101,110,115,111,114,0,98,75,101,121,98,111,97,114,100,83,101,110,115,111,114,0,98,80,114,111,112,101,114,116,121,83, +101,110,115,111,114,0,98,65,99,116,117,97,116,111,114,83,101,110,115,111,114,0,98,68,101,108,97,121,83,101,110,115, +111,114,0,98,67,111,108,108,105,115,105,111,110,83,101,110,115,111,114,0,98,82,97,100,97,114,83,101,110,115,111,114, +0,98,82,97,110,100,111,109,83,101,110,115,111,114,0,98,82,97,121,83,101,110,115,111,114,0,98,77,101,115,115,97, +103,101,83,101,110,115,111,114,0,98,83,101,110,115,111,114,0,98,67,111,110,116,114,111,108,108,101,114,0,98,74,111, +121,115,116,105,99,107,83,101,110,115,111,114,0,98,69,120,112,114,101,115,115,105,111,110,67,111,110,116,0,98,80,121, +116,104,111,110,67,111,110,116,0,98,65,99,116,117,97,116,111,114,0,98,65,100,100,79,98,106,101,99,116,65,99,116, +117,97,116,111,114,0,98,65,99,116,105,111,110,65,99,116,117,97,116,111,114,0,98,83,111,117,110,100,65,99,116,117, +97,116,111,114,0,98,67,68,65,99,116,117,97,116,111,114,0,98,69,100,105,116,79,98,106,101,99,116,65,99,116,117, +97,116,111,114,0,98,83,99,101,110,101,65,99,116,117,97,116,111,114,0,98,80,114,111,112,101,114,116,121,65,99,116, +117,97,116,111,114,0,98,79,98,106,101,99,116,65,99,116,117,97,116,111,114,0,98,73,112,111,65,99,116,117,97,116, +111,114,0,98,67,97,109,101,114,97,65,99,116,117,97,116,111,114,0,98,67,111,110,115,116,114,97,105,110,116,65,99, +116,117,97,116,111,114,0,98,71,114,111,117,112,65,99,116,117,97,116,111,114,0,98,82,97,110,100,111,109,65,99,116, +117,97,116,111,114,0,98,77,101,115,115,97,103,101,65,99,116,117,97,116,111,114,0,98,71,97,109,101,65,99,116,117, +97,116,111,114,0,98,86,105,115,105,98,105,108,105,116,121,65,99,116,117,97,116,111,114,0,98,84,119,111,68,70,105, +108,116,101,114,65,99,116,117,97,116,111,114,0,98,80,97,114,101,110,116,65,99,116,117,97,116,111,114,0,98,83,116, +97,116,101,65,99,116,117,97,116,111,114,0,70,114,101,101,67,97,109,101,114,97,0,98,83,97,109,112,108,101,0,98, +83,111,117,110,100,76,105,115,116,101,110,101,114,0,83,112,97,99,101,83,111,117,110,100,0,71,114,111,117,112,79,98, +106,101,99,116,0,66,111,110,101,0,98,65,114,109,97,116,117,114,101,0,98,80,111,115,101,67,104,97,110,110,101,108, +0,98,65,99,116,105,111,110,71,114,111,117,112,0,98,65,99,116,105,111,110,67,104,97,110,110,101,108,0,83,112,97, +99,101,65,99,116,105,111,110,0,98,67,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,0,98,67,111,110, +115,116,114,97,105,110,116,0,98,67,111,110,115,116,114,97,105,110,116,84,97,114,103,101,116,0,98,80,121,116,104,111, +110,67,111,110,115,116,114,97,105,110,116,0,98,75,105,110,101,109,97,116,105,99,67,111,110,115,116,114,97,105,110,116, +0,98,84,114,97,99,107,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,111,116,97,116,101,76,105,107,101,67, +111,110,115,116,114,97,105,110,116,0,98,76,111,99,97,116,101,76,105,107,101,67,111,110,115,116,114,97,105,110,116,0, +98,77,105,110,77,97,120,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,107,101,67,111,110,115,116, +114,97,105,110,116,0,98,65,99,116,105,111,110,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,107,84,114,97, +99,107,67,111,110,115,116,114,97,105,110,116,0,98,70,111,108,108,111,119,80,97,116,104,67,111,110,115,116,114,97,105, +110,116,0,98,83,116,114,101,116,99,104,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,105,103,105,100,66,111, +100,121,74,111,105,110,116,67,111,110,115,116,114,97,105,110,116,0,98,67,108,97,109,112,84,111,67,111,110,115,116,114, +97,105,110,116,0,98,67,104,105,108,100,79,102,67,111,110,115,116,114,97,105,110,116,0,98,84,114,97,110,115,102,111, +114,109,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116, +0,98,82,111,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,109,105,116,67, +111,110,115,116,114,97,105,110,116,0,98,68,105,115,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98, +83,104,114,105,110,107,119,114,97,112,67,111,110,115,116,114,97,105,110,116,0,98,65,99,116,105,111,110,77,111,100,105, +102,105,101,114,0,98,65,99,116,105,111,110,83,116,114,105,112,0,98,78,111,100,101,83,116,97,99,107,0,98,78,111, +100,101,83,111,99,107,101,116,0,98,78,111,100,101,76,105,110,107,0,98,78,111,100,101,0,98,78,111,100,101,80,114, +101,118,105,101,119,0,98,78,111,100,101,84,121,112,101,0,78,111,100,101,73,109,97,103,101,65,110,105,109,0,78,111, +100,101,66,108,117,114,68,97,116,97,0,78,111,100,101,68,66,108,117,114,68,97,116,97,0,78,111,100,101,66,105,108, +97,116,101,114,97,108,66,108,117,114,68,97,116,97,0,78,111,100,101,72,117,101,83,97,116,0,78,111,100,101,73,109, +97,103,101,70,105,108,101,0,78,111,100,101,67,104,114,111,109,97,0,78,111,100,101,84,119,111,88,89,115,0,78,111, +100,101,84,119,111,70,108,111,97,116,115,0,78,111,100,101,71,101,111,109,101,116,114,121,0,78,111,100,101,86,101,114, +116,101,120,67,111,108,0,78,111,100,101,68,101,102,111,99,117,115,0,78,111,100,101,83,99,114,105,112,116,68,105,99, +116,0,78,111,100,101,71,108,97,114,101,0,78,111,100,101,84,111,110,101,109,97,112,0,78,111,100,101,76,101,110,115, +68,105,115,116,0,84,101,120,78,111,100,101,79,117,116,112,117,116,0,67,117,114,118,101,77,97,112,80,111,105,110,116, +0,67,117,114,118,101,77,97,112,0,66,114,117,115,104,67,108,111,110,101,0,67,117,115,116,111,109,68,97,116,97,76, +97,121,101,114,0,72,97,105,114,75,101,121,0,80,97,114,116,105,99,108,101,75,101,121,0,67,104,105,108,100,80,97, +114,116,105,99,108,101,0,80,97,114,116,105,99,108,101,68,97,116,97,0,80,97,114,116,105,99,108,101,83,101,116,116, +105,110,103,115,0,80,97,114,116,105,99,108,101,69,100,105,116,0,80,97,114,116,105,99,108,101,67,97,99,104,101,75, +101,121,0,76,105,110,107,78,111,100,101,0,98,71,80,68,115,112,111,105,110,116,0,98,71,80,68,115,116,114,111,107, +101,0,98,71,80,68,102,114,97,109,101,0,98,71,80,68,108,97,121,101,114,0,0,84,76,69,78,1,0,1,0,2, +0,2,0,4,0,4,0,4,0,4,0,8,0,0,0,16,0,24,0,16,0,4,0,8,0,8,0,16,0,12,0,12, +0,24,0,16,0,16,0,32,0,16,0,16,0,32,0,96,0,72,0,72,2,0,0,40,0,-112,0,48,4,112,0,36, +0,56,0,112,0,-128,0,-96,0,24,0,40,0,48,0,-80,0,24,0,-88,0,32,0,-72,1,0,0,0,0,0,0,-112, +0,64,1,120,1,24,0,8,3,-56,0,0,0,-56,0,-120,0,-16,1,56,1,80,0,-16,2,104,0,96,1,0,0,-128, +0,104,0,-72,0,80,0,8,0,16,0,-96,1,0,0,-112,1,20,0,48,0,64,0,24,0,12,0,16,0,4,0,8, +0,8,0,32,0,112,0,48,0,8,0,16,0,8,0,8,0,4,0,4,0,0,1,32,0,16,0,64,0,24,0,12, +0,96,0,0,0,64,0,88,0,104,0,112,0,80,0,112,0,-112,0,80,0,72,0,120,0,72,0,-88,0,-48,0,72, +0,104,0,120,0,-48,0,120,0,-56,0,64,0,96,0,0,0,-120,0,32,0,20,0,-112,0,0,0,80,0,0,0,0, +0,80,0,8,0,8,0,0,1,96,0,-104,1,80,0,80,0,80,0,-72,1,-128,0,120,0,-104,0,48,0,-128,0,72, +0,120,0,-120,0,16,1,-32,0,0,0,16,0,0,0,0,0,0,0,-32,1,40,0,40,0,-72,0,-104,0,56,0,16, +0,88,0,-24,3,64,0,16,0,88,0,16,0,24,1,8,0,72,0,88,0,-16,0,8,0,-8,0,0,0,64,6,0, +0,64,0,88,3,48,0,8,1,0,0,0,0,0,0,32,0,-120,0,48,0,120,1,-16,0,-40,0,-8,1,0,0,0, +0,48,1,16,0,16,0,32,1,-64,0,-112,0,120,2,56,0,-80,0,0,1,-72,2,0,0,-104,0,-48,0,16,0,64, +14,56,0,40,12,-88,0,32,0,40,0,-16,0,40,0,80,0,48,0,16,0,8,0,64,0,0,0,0,1,32,1,-56, +1,8,1,72,1,0,0,32,0,48,0,12,0,24,0,48,0,16,0,32,0,24,0,32,0,72,1,0,0,64,0,64, +0,80,0,48,0,8,0,48,0,72,0,104,0,40,0,8,0,72,0,44,0,40,0,108,0,72,0,96,0,104,0,60, +0,-128,0,80,0,80,0,16,0,96,0,32,0,20,0,88,0,24,0,80,0,112,0,84,0,32,0,96,0,64,0,56, +0,112,0,-116,0,4,0,24,0,16,0,8,0,40,0,0,0,88,0,-64,0,40,0,24,1,-104,0,-48,1,88,0,88, +0,-48,0,56,0,80,0,-128,0,80,0,112,0,56,0,48,0,48,0,72,0,48,0,72,0,48,0,24,0,56,0,104, +0,16,0,112,0,96,0,28,0,28,0,28,0,56,0,24,0,72,0,-88,0,40,0,-112,0,48,0,-8,0,0,0,0, +0,16,0,40,0,28,0,12,0,12,0,16,1,40,0,8,0,8,0,64,0,32,0,24,0,16,0,24,0,32,0,8, +0,32,0,12,0,56,0,24,0,72,0,24,0,56,0,72,0,8,1,16,2,0,0,0,0,0,0,16,0,32,0,40, +0,-64,0,83,84,82,67,57,1,0,0,10,0,2,0,10,0,0,0,10,0,1,0,11,0,3,0,11,0,0,0,11, +0,1,0,9,0,2,0,12,0,2,0,9,0,3,0,9,0,4,0,13,0,2,0,2,0,5,0,2,0,6,0,14, +0,2,0,4,0,5,0,4,0,6,0,15,0,2,0,7,0,5,0,7,0,6,0,16,0,2,0,8,0,5,0,8, +0,6,0,17,0,3,0,4,0,5,0,4,0,6,0,4,0,7,0,18,0,3,0,7,0,5,0,7,0,6,0,7, +0,7,0,19,0,3,0,8,0,5,0,8,0,6,0,8,0,7,0,20,0,4,0,4,0,5,0,4,0,6,0,4, +0,7,0,4,0,8,0,21,0,4,0,7,0,5,0,7,0,6,0,7,0,7,0,7,0,8,0,22,0,4,0,8, +0,5,0,8,0,6,0,8,0,7,0,8,0,8,0,23,0,4,0,4,0,9,0,4,0,10,0,4,0,11,0,4, +0,12,0,24,0,4,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,25,0,4,0,9,0,13,0,12, +0,14,0,4,0,15,0,4,0,16,0,26,0,10,0,26,0,0,0,26,0,1,0,0,0,17,0,0,0,18,0,0, +0,19,0,2,0,20,0,4,0,21,0,25,0,22,0,4,0,23,0,4,0,24,0,27,0,9,0,9,0,0,0,9, +0,1,0,27,0,25,0,28,0,26,0,0,0,27,0,2,0,28,0,2,0,20,0,4,0,29,0,26,0,30,0,28, +0,8,0,27,0,31,0,27,0,32,0,29,0,33,0,0,0,34,0,0,0,35,0,4,0,36,0,4,0,37,0,28, +0,38,0,30,0,6,0,4,0,39,0,4,0,40,0,2,0,41,0,2,0,42,0,2,0,43,0,4,0,44,0,31, +0,6,0,32,0,45,0,2,0,46,0,2,0,47,0,2,0,18,0,2,0,20,0,0,0,48,0,33,0,21,0,33, +0,0,0,33,0,1,0,34,0,49,0,35,0,50,0,24,0,51,0,24,0,52,0,2,0,46,0,2,0,47,0,2, +0,53,0,2,0,54,0,2,0,55,0,2,0,56,0,2,0,20,0,2,0,57,0,7,0,11,0,7,0,12,0,4, +0,58,0,7,0,59,0,7,0,60,0,7,0,61,0,31,0,62,0,36,0,7,0,27,0,31,0,12,0,63,0,24, +0,64,0,2,0,46,0,2,0,65,0,2,0,66,0,2,0,37,0,37,0,16,0,37,0,0,0,37,0,1,0,7, +0,67,0,7,0,61,0,2,0,18,0,2,0,47,0,2,0,68,0,2,0,20,0,4,0,69,0,4,0,70,0,9, +0,2,0,7,0,71,0,0,0,17,0,0,0,72,0,7,0,73,0,7,0,74,0,38,0,12,0,27,0,31,0,37, +0,75,0,0,0,76,0,4,0,77,0,7,0,61,0,12,0,78,0,36,0,79,0,27,0,80,0,2,0,18,0,2, +0,81,0,2,0,82,0,2,0,20,0,39,0,5,0,27,0,83,0,2,0,84,0,2,0,85,0,2,0,86,0,4, +0,37,0,40,0,6,0,40,0,0,0,40,0,1,0,0,0,87,0,0,0,88,0,4,0,23,0,4,0,89,0,41, +0,10,0,41,0,0,0,41,0,1,0,4,0,90,0,4,0,91,0,4,0,92,0,4,0,43,0,4,0,14,0,4, +0,93,0,0,0,94,0,0,0,95,0,42,0,15,0,27,0,31,0,0,0,96,0,4,0,93,0,4,0,97,0,12, +0,98,0,40,0,99,0,40,0,100,0,4,0,101,0,4,0,102,0,12,0,103,0,0,0,104,0,4,0,105,0,4, +0,106,0,9,0,107,0,8,0,108,0,43,0,5,0,4,0,109,0,4,0,110,0,4,0,93,0,4,0,37,0,9, +0,2,0,44,0,20,0,27,0,31,0,2,0,18,0,2,0,20,0,7,0,111,0,7,0,112,0,7,0,113,0,7, +0,114,0,7,0,115,0,7,0,116,0,7,0,117,0,7,0,118,0,7,0,119,0,7,0,120,0,7,0,121,0,2, +0,122,0,2,0,123,0,7,0,124,0,36,0,79,0,39,0,125,0,32,0,126,0,45,0,12,0,4,0,127,0,4, +0,-128,0,4,0,-127,0,4,0,-126,0,2,0,-125,0,2,0,-124,0,2,0,20,0,2,0,-123,0,2,0,-122,0,2, +0,-121,0,2,0,-120,0,2,0,-119,0,46,0,32,0,27,0,31,0,0,0,34,0,12,0,-118,0,47,0,-117,0,48, +0,-116,0,49,0,-115,0,2,0,-123,0,2,0,20,0,2,0,-114,0,2,0,18,0,2,0,37,0,2,0,43,0,4, +0,-113,0,2,0,-112,0,2,0,-111,0,2,0,-110,0,2,0,-109,0,2,0,-108,0,2,0,-107,0,4,0,-106,0,4, +0,-105,0,43,0,-104,0,30,0,-103,0,7,0,-102,0,4,0,-101,0,2,0,-100,0,2,0,-99,0,2,0,-98,0,2, +0,-97,0,7,0,-96,0,7,0,-95,0,9,0,-94,0,50,0,31,0,2,0,-93,0,2,0,-92,0,2,0,-91,0,2, +0,-90,0,32,0,-89,0,51,0,-88,0,0,0,-87,0,0,0,-86,0,0,0,-85,0,0,0,-84,0,0,0,-83,0,7, +0,-82,0,7,0,-81,0,2,0,-80,0,2,0,-79,0,2,0,-78,0,2,0,-77,0,2,0,-76,0,2,0,-75,0,2, +0,-74,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7,0,-69,0,7,0,57,0,7,0,-68,0,7, +0,-67,0,7,0,-66,0,7,0,-65,0,7,0,-64,0,52,0,15,0,0,0,-63,0,9,0,-62,0,0,0,-61,0,0, +0,-60,0,4,0,-59,0,4,0,-58,0,9,0,-57,0,7,0,-56,0,7,0,-55,0,7,0,-54,0,4,0,-53,0,9, +0,-52,0,9,0,-51,0,4,0,-50,0,4,0,37,0,53,0,6,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, +0,-49,0,7,0,67,0,4,0,64,0,54,0,5,0,2,0,20,0,2,0,36,0,2,0,64,0,2,0,-48,0,53, +0,-54,0,55,0,17,0,32,0,-89,0,46,0,-47,0,56,0,-46,0,7,0,-45,0,7,0,-44,0,2,0,18,0,2, +0,-43,0,7,0,113,0,7,0,114,0,7,0,-42,0,4,0,-41,0,2,0,-40,0,2,0,-39,0,4,0,-123,0,4, +0,-113,0,2,0,-38,0,2,0,-37,0,51,0,56,0,27,0,31,0,7,0,-36,0,7,0,-35,0,7,0,-34,0,7, +0,-33,0,7,0,-32,0,7,0,-31,0,7,0,-30,0,7,0,-29,0,7,0,-28,0,7,0,-27,0,7,0,-26,0,7, +0,-25,0,7,0,-24,0,7,0,-23,0,7,0,-22,0,7,0,-21,0,7,0,-20,0,7,0,-19,0,7,0,-18,0,7, +0,-17,0,2,0,-16,0,2,0,-15,0,2,0,-14,0,2,0,-13,0,2,0,-12,0,2,0,-11,0,2,0,-10,0,2, +0,20,0,2,0,18,0,2,0,-43,0,7,0,-9,0,7,0,-8,0,7,0,-7,0,7,0,-6,0,2,0,-5,0,2, +0,-4,0,2,0,-3,0,2,0,-125,0,4,0,23,0,4,0,-128,0,4,0,-127,0,4,0,-126,0,7,0,-2,0,7, +0,-1,0,7,0,-67,0,45,0,0,1,57,0,1,1,36,0,79,0,46,0,-47,0,52,0,2,1,54,0,3,1,55, +0,4,1,30,0,-103,0,0,0,5,1,0,0,6,1,58,0,8,0,7,0,7,1,7,0,8,1,7,0,-81,0,4, +0,20,0,7,0,9,1,7,0,10,1,7,0,11,1,32,0,45,0,59,0,80,0,27,0,31,0,2,0,18,0,2, +0,12,1,4,0,13,1,2,0,-79,0,2,0,14,1,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7, +0,15,1,7,0,16,1,7,0,17,1,7,0,18,1,7,0,19,1,7,0,20,1,7,0,21,1,7,0,22,1,7, +0,23,1,7,0,24,1,7,0,25,1,60,0,26,1,2,0,27,1,2,0,70,0,7,0,113,0,7,0,114,0,7, +0,28,1,7,0,29,1,7,0,30,1,2,0,31,1,2,0,32,1,2,0,33,1,2,0,34,1,0,0,35,1,0, +0,36,1,2,0,37,1,2,0,38,1,2,0,39,1,2,0,40,1,2,0,41,1,7,0,42,1,7,0,43,1,7, +0,44,1,7,0,45,1,2,0,46,1,2,0,43,0,2,0,47,1,2,0,48,1,2,0,49,1,2,0,50,1,7, +0,51,1,7,0,52,1,7,0,53,1,7,0,54,1,7,0,55,1,7,0,56,1,7,0,57,1,7,0,58,1,7, +0,59,1,7,0,60,1,7,0,61,1,7,0,62,1,2,0,63,1,2,0,64,1,4,0,65,1,4,0,66,1,2, +0,67,1,2,0,68,1,2,0,69,1,2,0,70,1,7,0,71,1,7,0,72,1,7,0,73,1,7,0,74,1,2, +0,75,1,2,0,76,1,50,0,77,1,36,0,79,0,30,0,-103,0,39,0,125,0,61,0,2,0,27,0,31,0,36, +0,79,0,62,0,-127,0,27,0,31,0,2,0,-79,0,2,0,20,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, +0,78,1,7,0,79,1,7,0,80,1,7,0,81,1,7,0,82,1,7,0,83,1,7,0,84,1,7,0,85,1,7, +0,86,1,7,0,87,1,7,0,88,1,7,0,89,1,7,0,90,1,7,0,91,1,7,0,92,1,7,0,93,1,7, +0,94,1,7,0,95,1,7,0,96,1,7,0,97,1,7,0,98,1,7,0,99,1,7,0,100,1,7,0,101,1,7, +0,102,1,7,0,103,1,7,0,104,1,2,0,105,1,2,0,106,1,2,0,107,1,0,0,108,1,0,0,109,1,7, +0,110,1,7,0,111,1,2,0,112,1,2,0,113,1,7,0,114,1,7,0,115,1,7,0,116,1,7,0,117,1,2, +0,118,1,2,0,119,1,4,0,13,1,4,0,120,1,2,0,121,1,2,0,122,1,2,0,123,1,2,0,124,1,7, +0,125,1,7,0,126,1,7,0,127,1,7,0,-128,1,7,0,-127,1,7,0,-126,1,7,0,-125,1,7,0,-124,1,7, +0,-123,1,7,0,-122,1,0,0,-121,1,7,0,-120,1,7,0,-119,1,7,0,-118,1,4,0,-117,1,0,0,-116,1,0, +0,47,1,0,0,-115,1,0,0,5,1,2,0,-114,1,2,0,-113,1,2,0,64,1,2,0,-112,1,2,0,-111,1,2, +0,-110,1,7,0,-109,1,7,0,-108,1,7,0,-107,1,7,0,-106,1,7,0,-105,1,2,0,-93,0,2,0,-92,0,54, +0,-104,1,54,0,-103,1,0,0,-102,1,0,0,-101,1,0,0,-100,1,0,0,-99,1,2,0,-98,1,2,0,12,1,7, +0,-97,1,7,0,-96,1,50,0,77,1,57,0,1,1,36,0,79,0,63,0,-95,1,30,0,-103,0,7,0,-94,1,7, +0,-93,1,7,0,-92,1,7,0,-91,1,7,0,-90,1,2,0,-89,1,2,0,70,0,7,0,-88,1,7,0,-87,1,7, +0,-86,1,7,0,-85,1,7,0,-84,1,7,0,-83,1,7,0,-82,1,7,0,-81,1,7,0,-80,1,2,0,-79,1,2, +0,-78,1,7,0,-77,1,7,0,-76,1,7,0,-75,1,7,0,-74,1,7,0,-73,1,4,0,-72,1,4,0,-71,1,4, +0,-70,1,39,0,125,0,12,0,-69,1,64,0,6,0,27,0,31,0,0,0,-68,1,7,0,-67,1,7,0,37,0,65, +0,2,0,43,0,-104,0,66,0,26,0,66,0,0,0,66,0,1,0,67,0,-66,1,4,0,-65,1,4,0,-64,1,4, +0,-63,1,4,0,-62,1,4,0,-61,1,4,0,-60,1,2,0,18,0,2,0,20,0,2,0,-59,1,2,0,-58,1,7, +0,5,0,7,0,6,0,7,0,7,0,7,0,-57,1,7,0,-56,1,7,0,-55,1,7,0,-54,1,7,0,-53,1,7, +0,-52,1,7,0,-51,1,7,0,23,0,7,0,-50,1,7,0,-49,1,68,0,15,0,27,0,31,0,67,0,-66,1,12, +0,-48,1,12,0,-47,1,36,0,79,0,62,0,-46,1,2,0,20,0,2,0,-45,1,4,0,-80,0,7,0,7,1,7, +0,-81,0,7,0,8,1,7,0,-44,1,7,0,-43,1,7,0,-42,1,35,0,10,0,7,0,-41,1,7,0,-40,1,7, +0,-39,1,7,0,-38,1,2,0,-37,1,2,0,-36,1,0,0,-35,1,0,0,-34,1,0,0,-33,1,0,0,-32,1,34, +0,7,0,7,0,-31,1,7,0,-40,1,7,0,-39,1,2,0,-35,1,2,0,-32,1,7,0,-38,1,7,0,37,0,69, +0,21,0,69,0,0,0,69,0,1,0,2,0,18,0,2,0,-30,1,2,0,-32,1,2,0,20,0,2,0,-29,1,2, +0,-28,1,2,0,-27,1,2,0,-26,1,2,0,-25,1,2,0,-24,1,2,0,-23,1,2,0,-22,1,7,0,-21,1,7, +0,-20,1,34,0,49,0,35,0,50,0,2,0,-19,1,2,0,-18,1,4,0,-17,1,70,0,5,0,2,0,-16,1,2, +0,-30,1,0,0,20,0,0,0,37,0,2,0,70,0,71,0,4,0,7,0,5,0,7,0,6,0,7,0,8,0,7, +0,-15,1,72,0,57,0,27,0,31,0,67,0,-66,1,12,0,-14,1,12,0,-47,1,32,0,-13,1,32,0,-12,1,32, +0,-11,1,36,0,79,0,73,0,-10,1,38,0,-9,1,62,0,-46,1,12,0,-8,1,7,0,7,1,7,0,-81,0,7, +0,8,1,4,0,-80,0,2,0,-7,1,2,0,-45,1,2,0,20,0,2,0,-6,1,7,0,-5,1,7,0,-4,1,7, +0,-3,1,2,0,-27,1,2,0,-26,1,2,0,-2,1,2,0,-1,1,4,0,70,0,2,0,23,0,2,0,98,0,2, +0,67,0,2,0,0,2,7,0,1,2,7,0,2,2,7,0,3,2,7,0,4,2,7,0,5,2,7,0,6,2,7, +0,7,2,7,0,8,2,7,0,9,2,7,0,10,2,0,0,11,2,0,0,12,2,64,0,13,2,64,0,14,2,64, +0,15,2,64,0,16,2,4,0,17,2,4,0,18,2,4,0,19,2,4,0,37,0,71,0,20,2,4,0,21,2,4, +0,22,2,70,0,23,2,70,0,24,2,74,0,39,0,27,0,31,0,67,0,-66,1,12,0,25,2,36,0,79,0,38, +0,-9,1,62,0,-46,1,75,0,26,2,76,0,27,2,77,0,28,2,78,0,29,2,79,0,30,2,80,0,31,2,81, +0,32,2,82,0,33,2,74,0,34,2,83,0,35,2,84,0,36,2,84,0,37,2,84,0,38,2,4,0,54,0,4, +0,39,2,4,0,40,2,4,0,41,2,4,0,42,2,4,0,-80,0,7,0,7,1,7,0,-81,0,7,0,8,1,7, +0,43,2,7,0,37,0,2,0,44,2,2,0,20,0,2,0,45,2,2,0,46,2,2,0,-45,1,2,0,47,2,85, +0,48,2,86,0,49,2,9,0,-94,0,77,0,8,0,9,0,50,2,7,0,51,2,4,0,52,2,0,0,20,0,0, +0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,75,0,8,0,4,0,56,2,4,0,57,2,4,0,58,2,4, +0,59,2,0,0,37,0,0,0,-30,1,0,0,60,2,0,0,20,0,79,0,5,0,4,0,56,2,4,0,57,2,0, +0,61,2,0,0,62,2,2,0,20,0,87,0,2,0,4,0,63,2,7,0,-39,1,80,0,3,0,87,0,64,2,4, +0,65,2,4,0,20,0,78,0,6,0,7,0,66,2,2,0,67,2,0,0,20,0,0,0,-30,1,0,0,62,2,0, +0,68,2,81,0,4,0,0,0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,88,0,6,0,46,0,50,2,0, +0,20,0,0,0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,89,0,1,0,7,0,69,2,90,0,5,0,0, +0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,4,0,37,0,82,0,1,0,7,0,70,2,83,0,2,0,4, +0,71,2,4,0,18,0,76,0,7,0,7,0,51,2,46,0,50,2,0,0,20,0,0,0,53,2,2,0,13,1,2, +0,54,2,2,0,55,2,91,0,1,0,7,0,72,2,92,0,1,0,4,0,73,2,93,0,1,0,0,0,74,2,94, +0,1,0,7,0,51,2,95,0,4,0,7,0,-49,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,96,0,1,0,95, +0,52,2,97,0,5,0,4,0,75,2,4,0,76,2,0,0,20,0,0,0,-30,1,0,0,-74,0,98,0,2,0,4, +0,77,2,4,0,76,2,99,0,14,0,99,0,0,0,99,0,1,0,97,0,78,2,96,0,79,2,98,0,80,2,0, +0,81,2,12,0,82,2,12,0,83,2,100,0,84,2,4,0,54,0,4,0,40,2,4,0,39,2,4,0,37,0,78, +0,85,2,85,0,14,0,12,0,86,2,78,0,85,2,0,0,87,2,0,0,88,2,0,0,89,2,0,0,90,2,0, +0,91,2,0,0,92,2,0,0,93,2,0,0,20,0,84,0,36,2,84,0,38,2,2,0,94,2,0,0,95,2,86, +0,8,0,4,0,96,2,4,0,97,2,75,0,98,2,79,0,99,2,4,0,40,2,4,0,39,2,4,0,54,0,4, +0,37,0,101,0,6,0,101,0,0,0,101,0,1,0,4,0,18,0,4,0,13,1,0,0,17,0,0,0,100,2,102, +0,7,0,101,0,101,2,2,0,102,2,2,0,86,2,2,0,103,2,2,0,93,0,9,0,104,2,9,0,105,2,103, +0,3,0,101,0,101,2,32,0,-89,0,0,0,17,0,104,0,5,0,101,0,101,2,32,0,-89,0,0,0,17,0,2, +0,106,2,0,0,107,2,105,0,5,0,101,0,101,2,7,0,91,0,7,0,108,2,4,0,109,2,4,0,110,2,106, +0,5,0,101,0,101,2,32,0,111,2,0,0,72,0,4,0,13,1,4,0,20,0,107,0,13,0,101,0,101,2,32, +0,112,2,32,0,113,2,32,0,114,2,32,0,115,2,7,0,116,2,7,0,117,2,7,0,108,2,7,0,118,2,4, +0,119,2,4,0,120,2,4,0,93,0,4,0,121,2,108,0,5,0,101,0,101,2,2,0,122,2,2,0,20,0,7, +0,123,2,32,0,124,2,109,0,3,0,101,0,101,2,7,0,125,2,4,0,93,0,110,0,10,0,101,0,101,2,7, +0,126,2,4,0,127,2,4,0,37,0,2,0,93,0,2,0,-128,2,2,0,-127,2,2,0,-126,2,7,0,-125,2,0, +0,-124,2,111,0,3,0,101,0,101,2,7,0,37,0,4,0,18,0,112,0,11,0,101,0,101,2,51,0,-123,2,7, +0,-122,2,4,0,-121,2,0,0,-124,2,7,0,-120,2,4,0,-119,2,32,0,-118,2,0,0,-117,2,4,0,-116,2,4, +0,37,0,113,0,10,0,101,0,101,2,32,0,-115,2,46,0,-114,2,4,0,93,0,4,0,-113,2,7,0,-112,2,7, +0,-111,2,0,0,-117,2,4,0,-116,2,4,0,37,0,114,0,3,0,101,0,101,2,7,0,-110,2,4,0,-109,2,115, +0,5,0,101,0,101,2,7,0,-108,2,0,0,-124,2,2,0,20,0,2,0,-107,2,116,0,8,0,101,0,101,2,32, +0,-89,0,7,0,-108,2,7,0,-38,1,7,0,109,0,0,0,-124,2,2,0,20,0,2,0,18,0,117,0,21,0,101, +0,101,2,32,0,-106,2,0,0,-124,2,51,0,-123,2,32,0,-118,2,2,0,20,0,2,0,37,0,7,0,-105,2,7, +0,-104,2,7,0,-103,2,7,0,-5,1,7,0,-102,2,7,0,-101,2,7,0,-100,2,7,0,-99,2,4,0,-119,2,4, +0,-116,2,0,0,-117,2,7,0,-98,2,7,0,-97,2,7,0,43,0,118,0,7,0,101,0,101,2,2,0,-96,2,2, +0,-95,2,4,0,70,0,32,0,-89,0,7,0,-94,2,0,0,-124,2,119,0,9,0,101,0,101,2,32,0,-89,0,7, +0,-93,2,7,0,-92,2,7,0,-99,2,4,0,-91,2,4,0,-90,2,7,0,-89,2,0,0,17,0,120,0,1,0,101, +0,101,2,121,0,5,0,101,0,101,2,122,0,-88,2,123,0,-87,2,124,0,-86,2,125,0,-85,2,126,0,14,0,101, +0,101,2,78,0,-84,2,78,0,-83,2,78,0,-82,2,78,0,-81,2,78,0,-80,2,78,0,-79,2,75,0,-78,2,4, +0,-77,2,4,0,-76,2,2,0,-75,2,2,0,37,0,7,0,-74,2,127,0,-73,2,-128,0,3,0,101,0,101,2,-127, +0,-72,2,-126,0,-73,2,-125,0,4,0,101,0,101,2,32,0,-89,0,4,0,-71,2,4,0,37,0,-124,0,2,0,4, +0,-70,2,7,0,-39,1,-123,0,2,0,4,0,-127,0,4,0,-69,2,-122,0,20,0,101,0,101,2,32,0,-89,0,0, +0,-124,2,2,0,-68,2,2,0,-67,2,2,0,20,0,2,0,37,0,7,0,-66,2,7,0,-65,2,4,0,54,0,4, +0,-64,2,-123,0,-63,2,-124,0,-62,2,4,0,-61,2,4,0,-60,2,4,0,-59,2,4,0,-69,2,7,0,-58,2,7, +0,-57,2,7,0,-56,2,-121,0,8,0,101,0,101,2,-120,0,-55,2,-127,0,-72,2,4,0,-54,2,4,0,-53,2,4, +0,-52,2,2,0,20,0,2,0,57,0,-119,0,5,0,101,0,101,2,32,0,45,0,2,0,-51,2,2,0,20,0,2, +0,-50,2,-118,0,5,0,101,0,101,2,4,0,-49,2,2,0,20,0,2,0,-48,2,7,0,-47,2,-117,0,3,0,101, +0,101,2,-116,0,-46,2,125,0,-85,2,-115,0,10,0,101,0,101,2,32,0,-45,2,32,0,-44,2,0,0,-43,2,7, +0,-42,2,2,0,-41,2,2,0,-40,2,0,0,-39,2,0,0,-38,2,0,0,107,2,-114,0,9,0,101,0,101,2,32, +0,-37,2,0,0,-43,2,7,0,-36,2,7,0,-35,2,0,0,13,1,0,0,122,2,0,0,-34,2,0,0,37,0,-113, +0,24,0,27,0,31,0,2,0,-29,1,2,0,-28,1,2,0,-33,2,2,0,20,0,2,0,-32,2,2,0,-31,2,2, +0,-30,2,2,0,70,0,0,0,-29,2,0,0,-28,2,0,0,-27,2,0,0,18,0,4,0,37,0,7,0,-26,2,7, +0,-25,2,7,0,-24,2,7,0,-23,2,7,0,-22,2,7,0,-21,2,34,0,-20,2,36,0,79,0,38,0,-9,1,80, +0,31,2,-112,0,3,0,-112,0,0,0,-112,0,1,0,0,0,17,0,67,0,3,0,7,0,-19,2,4,0,20,0,4, +0,37,0,32,0,111,0,27,0,31,0,2,0,18,0,2,0,-18,2,4,0,-17,2,4,0,-16,2,4,0,-15,2,0, +0,-14,2,32,0,38,0,32,0,-13,2,32,0,-12,2,32,0,-11,2,32,0,-10,2,36,0,79,0,73,0,-10,1,67, +0,-66,1,-111,0,-9,2,-111,0,-8,2,-110,0,-7,2,9,0,2,0,12,0,-6,2,12,0,25,2,12,0,-47,1,12, +0,-5,2,12,0,-4,2,62,0,-46,1,7,0,7,1,7,0,-3,2,7,0,-2,2,7,0,-81,0,7,0,-1,2,7, +0,8,1,7,0,0,3,7,0,1,3,7,0,-93,2,7,0,2,3,7,0,-45,0,4,0,3,3,2,0,20,0,2, +0,4,3,2,0,5,3,2,0,6,3,2,0,7,3,2,0,8,3,2,0,9,3,2,0,10,3,2,0,11,3,2, +0,12,3,2,0,13,3,2,0,14,3,4,0,15,3,4,0,16,3,4,0,17,3,4,0,18,3,7,0,19,3,7, +0,20,3,7,0,21,3,7,0,22,3,7,0,23,3,7,0,24,3,7,0,25,3,7,0,26,3,7,0,27,3,7, +0,28,3,7,0,29,3,7,0,30,3,0,0,31,3,0,0,32,3,0,0,-45,1,0,0,33,3,0,0,34,3,0, +0,35,3,7,0,36,3,7,0,37,3,39,0,125,0,12,0,38,3,12,0,39,3,12,0,40,3,12,0,41,3,7, +0,42,3,2,0,71,2,2,0,43,3,7,0,52,2,4,0,44,3,4,0,45,3,-109,0,46,3,2,0,47,3,2, +0,-38,0,7,0,48,3,12,0,49,3,12,0,50,3,12,0,51,3,12,0,52,3,-108,0,53,3,-107,0,54,3,63, +0,55,3,2,0,56,3,2,0,57,3,2,0,58,3,2,0,59,3,7,0,44,2,2,0,60,3,2,0,61,3,-116, +0,62,3,-127,0,63,3,-127,0,64,3,4,0,65,3,4,0,66,3,4,0,67,3,4,0,70,0,9,0,-94,0,12, +0,68,3,-106,0,14,0,-106,0,0,0,-106,0,1,0,32,0,38,0,7,0,-93,2,7,0,9,1,7,0,-92,2,7, +0,-99,2,0,0,17,0,4,0,-91,2,4,0,-90,2,4,0,69,3,2,0,18,0,2,0,70,3,7,0,-89,2,-108, +0,36,0,2,0,71,3,2,0,72,3,2,0,20,0,2,0,-99,2,7,0,73,3,7,0,74,3,7,0,75,3,7, +0,76,3,7,0,77,3,7,0,78,3,7,0,79,3,7,0,80,3,7,0,81,3,7,0,82,3,7,0,83,3,7, +0,84,3,7,0,85,3,7,0,86,3,7,0,87,3,7,0,88,3,7,0,89,3,7,0,90,3,7,0,91,3,7, +0,92,3,7,0,93,3,7,0,94,3,7,0,95,3,7,0,96,3,2,0,97,3,2,0,98,3,2,0,99,3,2, +0,100,3,51,0,-88,0,-105,0,101,3,7,0,102,3,4,0,110,2,125,0,5,0,4,0,20,0,4,0,103,3,4, +0,104,3,4,0,105,3,4,0,106,3,-104,0,1,0,7,0,-31,1,-109,0,30,0,4,0,20,0,7,0,107,3,7, +0,108,3,7,0,109,3,4,0,110,3,4,0,111,3,4,0,112,3,4,0,113,3,7,0,114,3,7,0,115,3,7, +0,116,3,7,0,117,3,7,0,118,3,7,0,119,3,7,0,120,3,7,0,121,3,7,0,122,3,7,0,123,3,7, +0,124,3,7,0,125,3,7,0,126,3,7,0,127,3,7,0,-128,3,7,0,-127,3,7,0,-126,3,7,0,-125,3,4, +0,-124,3,4,0,-123,3,7,0,-122,3,7,0,27,3,-107,0,49,0,-120,0,-121,3,4,0,-120,3,4,0,-119,3,-103, +0,-118,3,-102,0,-117,3,0,0,37,0,0,0,-116,3,2,0,-115,3,7,0,-114,3,0,0,-113,3,7,0,-112,3,7, +0,-111,3,7,0,-110,3,7,0,-109,3,7,0,-108,3,7,0,-107,3,7,0,-106,3,7,0,-105,3,7,0,-104,3,2, +0,-103,3,0,0,-102,3,2,0,-101,3,7,0,-100,3,7,0,-99,3,0,0,-98,3,4,0,-126,0,4,0,-97,3,4, +0,-96,3,2,0,-95,3,2,0,-94,3,-104,0,-93,3,4,0,-92,3,4,0,81,0,7,0,-91,3,7,0,-90,3,7, +0,-89,3,7,0,-88,3,2,0,-87,3,2,0,-86,3,2,0,-85,3,2,0,-84,3,2,0,-83,3,2,0,-82,3,2, +0,-81,3,2,0,-80,3,-101,0,-79,3,7,0,-78,3,7,0,-77,3,125,0,-76,3,-116,0,48,0,2,0,18,0,2, +0,-75,3,2,0,-74,3,2,0,-73,3,7,0,-72,3,2,0,-71,3,2,0,-70,3,7,0,-69,3,2,0,-68,3,2, +0,-67,3,7,0,-66,3,7,0,-65,3,7,0,-64,3,7,0,-63,3,7,0,-62,3,7,0,-61,3,4,0,-60,3,7, +0,-59,3,7,0,-58,3,7,0,-57,3,74,0,-56,3,74,0,-55,3,74,0,-54,3,0,0,-53,3,7,0,-52,3,7, +0,-51,3,36,0,79,0,2,0,-50,3,0,0,-49,3,0,0,-48,3,7,0,-47,3,4,0,-46,3,7,0,-45,3,7, +0,-44,3,4,0,-43,3,4,0,20,0,7,0,-42,3,7,0,-41,3,7,0,-40,3,78,0,-39,3,7,0,-38,3,7, +0,-37,3,7,0,-36,3,7,0,-35,3,7,0,-34,3,7,0,-33,3,7,0,-32,3,4,0,-31,3,-100,0,71,0,27, +0,31,0,2,0,-79,0,2,0,14,1,2,0,47,1,2,0,-30,3,7,0,-29,3,7,0,-28,3,7,0,-27,3,7, +0,-26,3,7,0,-25,3,7,0,-24,3,7,0,-23,3,7,0,-22,3,7,0,84,1,7,0,86,1,7,0,85,1,7, +0,-21,3,4,0,-20,3,7,0,-19,3,7,0,-18,3,7,0,-17,3,7,0,-16,3,7,0,-15,3,7,0,-14,3,7, +0,-13,3,2,0,-12,3,2,0,13,1,2,0,-11,3,2,0,-10,3,2,0,-9,3,2,0,-8,3,2,0,-7,3,2, +0,-6,3,7,0,-5,3,7,0,-4,3,7,0,-3,3,7,0,-2,3,7,0,-1,3,7,0,0,4,7,0,1,4,7, +0,2,4,7,0,3,4,7,0,4,4,7,0,5,4,7,0,6,4,2,0,7,4,2,0,8,4,2,0,9,4,2, +0,10,4,7,0,11,4,7,0,12,4,7,0,13,4,7,0,14,4,2,0,15,4,2,0,16,4,2,0,17,4,2, +0,18,4,7,0,19,4,7,0,20,4,7,0,21,4,7,0,22,4,2,0,23,4,2,0,24,4,2,0,25,4,2, +0,43,0,7,0,26,4,7,0,27,4,36,0,79,0,50,0,77,1,30,0,-103,0,39,0,125,0,-99,0,16,0,2, +0,28,4,2,0,29,4,2,0,30,4,2,0,20,0,2,0,31,4,2,0,32,4,2,0,33,4,2,0,34,4,2, +0,35,4,2,0,36,4,2,0,37,4,2,0,38,4,4,0,39,4,7,0,40,4,7,0,41,4,7,0,42,4,-98, +0,8,0,-98,0,0,0,-98,0,1,0,4,0,3,3,4,0,43,4,4,0,20,0,2,0,44,4,2,0,45,4,32, +0,-89,0,-97,0,13,0,9,0,46,4,9,0,47,4,4,0,48,4,4,0,49,4,4,0,50,4,4,0,51,4,4, +0,52,4,4,0,53,4,4,0,54,4,4,0,55,4,4,0,56,4,4,0,37,0,0,0,57,4,-96,0,5,0,9, +0,58,4,9,0,59,4,4,0,60,4,4,0,70,0,0,0,61,4,-95,0,13,0,4,0,18,0,4,0,62,4,4, +0,63,4,4,0,64,4,4,0,65,4,4,0,66,4,4,0,93,0,4,0,67,4,4,0,68,4,4,0,69,4,4, +0,70,4,4,0,71,4,26,0,30,0,-94,0,4,0,4,0,72,4,7,0,73,4,2,0,20,0,2,0,68,2,-93, +0,11,0,-93,0,0,0,-93,0,1,0,0,0,17,0,62,0,74,4,63,0,75,4,4,0,3,3,4,0,76,4,4, +0,77,4,4,0,37,0,4,0,78,4,4,0,79,4,-92,0,-126,0,-97,0,80,4,-96,0,81,4,-95,0,82,4,4, +0,83,4,4,0,-126,0,4,0,-97,3,4,0,84,4,4,0,85,4,4,0,86,4,4,0,87,4,2,0,20,0,2, +0,88,4,7,0,20,3,7,0,89,4,7,0,90,4,7,0,91,4,7,0,92,4,7,0,93,4,2,0,94,4,2, +0,95,4,2,0,96,4,2,0,97,4,2,0,-39,0,2,0,98,4,2,0,99,4,2,0,100,3,2,0,100,4,2, +0,101,4,2,0,34,1,2,0,109,0,2,0,102,4,2,0,103,4,2,0,104,4,2,0,105,4,2,0,106,4,2, +0,107,4,2,0,108,4,2,0,109,4,2,0,110,4,2,0,35,1,2,0,111,4,2,0,112,4,2,0,113,4,2, +0,114,4,4,0,115,4,4,0,13,1,2,0,116,4,2,0,117,4,2,0,118,4,2,0,119,4,2,0,120,4,2, +0,121,4,24,0,122,4,24,0,123,4,23,0,124,4,12,0,125,4,2,0,126,4,2,0,37,0,7,0,127,4,7, +0,-128,4,7,0,-127,4,7,0,-126,4,7,0,-125,4,7,0,-124,4,7,0,-123,4,7,0,-122,4,7,0,-121,4,2, +0,-120,4,2,0,-119,4,2,0,-118,4,2,0,-117,4,2,0,-116,4,2,0,-115,4,7,0,-114,4,7,0,-113,4,7, +0,-112,4,2,0,-111,4,2,0,-110,4,2,0,-109,4,2,0,-108,4,2,0,-107,4,2,0,-106,4,2,0,-105,4,2, +0,-104,4,2,0,-103,4,2,0,-102,4,4,0,-101,4,4,0,-100,4,4,0,-99,4,4,0,-98,4,4,0,-97,4,7, +0,-96,4,4,0,-95,4,4,0,-94,4,4,0,-93,4,4,0,-92,4,7,0,-91,4,7,0,-90,4,7,0,-89,4,7, +0,-88,4,7,0,-87,4,7,0,-86,4,7,0,-85,4,7,0,-84,4,7,0,-83,4,0,0,-82,4,0,0,-81,4,4, +0,-80,4,2,0,-79,4,2,0,12,1,0,0,-78,4,7,0,-77,4,7,0,-76,4,4,0,-75,4,4,0,-74,4,7, +0,-73,4,7,0,-72,4,2,0,-71,4,2,0,-70,4,7,0,-69,4,2,0,-68,4,2,0,-67,4,4,0,-66,4,2, +0,-65,4,2,0,-64,4,2,0,-63,4,2,0,-62,4,7,0,-61,4,7,0,70,0,42,0,-60,4,-91,0,9,0,-91, +0,0,0,-91,0,1,0,0,0,17,0,2,0,-59,4,2,0,-58,4,2,0,-57,4,2,0,43,0,7,0,-56,4,7, +0,70,0,-90,0,5,0,7,0,-55,4,0,0,18,0,0,0,43,0,0,0,70,0,0,0,12,1,-89,0,5,0,-89, +0,0,0,-89,0,1,0,4,0,-54,4,0,0,-53,4,4,0,20,0,-88,0,5,0,-87,0,-52,4,2,0,20,0,2, +0,-51,4,2,0,-50,4,2,0,-49,4,-86,0,4,0,2,0,109,0,2,0,-122,2,2,0,-48,4,2,0,-47,4,-85, +0,7,0,2,0,20,0,2,0,-46,4,2,0,-45,4,2,0,-44,4,-86,0,-43,4,7,0,-42,4,4,0,-41,4,-84, +0,4,0,-84,0,0,0,-84,0,1,0,0,0,-40,4,7,0,-39,4,-83,0,56,0,2,0,-38,4,2,0,-37,4,7, +0,-36,4,7,0,-35,4,2,0,-48,4,2,0,-34,4,7,0,-33,4,7,0,-32,4,2,0,-31,4,2,0,-30,4,2, +0,-29,4,2,0,-28,4,7,0,-27,4,7,0,-26,4,7,0,-25,4,7,0,37,0,2,0,-24,4,2,0,-23,4,2, +0,-22,4,2,0,-21,4,-88,0,-20,4,-85,0,-19,4,7,0,-18,4,7,0,-17,4,0,0,-16,4,0,0,-15,4,0, +0,-14,4,0,0,-13,4,0,0,-12,4,0,0,-11,4,2,0,-10,4,7,0,-9,4,7,0,-8,4,7,0,-7,4,7, +0,-6,4,7,0,-5,4,7,0,-4,4,7,0,-3,4,7,0,-2,4,7,0,-1,4,7,0,0,5,2,0,1,5,0, +0,2,5,0,0,3,5,0,0,4,5,0,0,5,5,32,0,6,5,0,0,7,5,0,0,8,5,0,0,9,5,0, +0,10,5,0,0,11,5,0,0,12,5,0,0,13,5,0,0,14,5,0,0,15,5,-82,0,6,0,2,0,109,0,0, +0,-122,2,0,0,16,5,0,0,17,5,0,0,20,0,0,0,-74,0,-81,0,26,0,-80,0,18,5,50,0,77,1,60, +0,19,5,-82,0,20,5,-82,0,21,5,-82,0,22,5,-82,0,23,5,-82,0,24,5,-82,0,25,5,-82,0,26,5,7, +0,27,5,2,0,28,5,2,0,47,1,2,0,29,5,2,0,1,2,0,0,30,5,0,0,31,5,0,0,32,5,0, +0,33,5,0,0,93,0,0,0,34,5,0,0,35,5,0,0,36,5,0,0,37,5,0,0,38,5,0,0,-74,0,-79, +0,43,0,27,0,31,0,32,0,39,5,-100,0,40,5,-79,0,41,5,46,0,-47,0,12,0,42,5,-98,0,43,5,7, +0,44,5,7,0,45,5,7,0,46,5,7,0,47,5,4,0,3,3,7,0,48,5,2,0,49,5,2,0,50,5,2, +0,51,5,2,0,52,5,2,0,53,5,2,0,54,5,2,0,55,5,2,0,5,1,57,0,1,1,9,0,56,5,-99, +0,57,5,-90,0,58,5,-83,0,59,5,-92,0,-73,0,-94,0,60,5,39,0,125,0,12,0,103,0,12,0,61,5,2, +0,62,5,2,0,63,5,2,0,64,5,2,0,65,5,-78,0,66,5,2,0,67,5,2,0,68,5,2,0,64,1,2, +0,-38,0,-81,0,69,5,4,0,70,5,4,0,37,0,-77,0,9,0,46,0,-47,0,45,0,0,1,7,0,8,2,7, +0,9,2,7,0,109,0,7,0,71,5,7,0,72,5,2,0,73,5,2,0,74,5,-76,0,75,0,-75,0,0,0,-75, +0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,7,0,79,5,7,0,80,5,7,0,81,5,7, +0,82,5,7,0,83,5,7,0,84,5,7,0,85,5,7,0,20,1,7,0,86,5,4,0,87,5,2,0,88,5,2, +0,17,5,32,0,39,5,32,0,89,5,-77,0,90,5,-76,0,91,5,-73,0,92,5,-72,0,93,5,-71,0,94,5,0, +0,95,5,2,0,30,4,2,0,96,5,4,0,3,3,4,0,97,5,2,0,98,5,2,0,99,5,2,0,100,5,0, +0,101,5,0,0,43,0,7,0,115,0,7,0,102,5,7,0,103,5,7,0,104,5,7,0,105,5,7,0,106,5,7, +0,107,5,7,0,108,5,7,0,-82,0,7,0,44,5,2,0,109,5,2,0,110,5,2,0,111,5,2,0,112,5,2, +0,-119,0,2,0,29,5,2,0,113,5,2,0,114,5,2,0,115,5,2,0,116,5,7,0,117,5,7,0,118,5,67, +0,119,5,12,0,120,5,2,0,121,5,2,0,53,2,2,0,122,5,2,0,20,0,2,0,123,5,2,0,124,5,2, +0,125,5,0,0,126,5,0,0,127,5,9,0,-128,5,-70,0,-127,5,7,0,-126,5,2,0,-125,5,2,0,-124,5,2, +0,53,5,2,0,54,5,-69,0,19,0,24,0,36,0,24,0,64,0,23,0,-123,5,23,0,-122,5,23,0,-121,5,7, +0,-120,5,7,0,-119,5,7,0,-118,5,7,0,-117,5,2,0,-116,5,2,0,-115,5,2,0,-114,5,2,0,-113,5,2, +0,-112,5,2,0,-111,5,4,0,20,0,7,0,-110,5,2,0,99,5,0,0,107,2,-75,0,6,0,-75,0,0,0,-75, +0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-68,0,6,0,-75,0,0,0,-75,0,1,0,4, +0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-67,0,27,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7, +0,76,5,-74,0,77,5,2,0,78,5,4,0,-109,5,4,0,70,0,-69,0,-108,5,9,0,-107,5,12,0,-106,5,36, +0,79,0,27,0,80,0,0,0,-105,5,0,0,-104,5,0,0,-103,5,2,0,-102,5,2,0,-101,5,2,0,-100,5,2, +0,-99,5,2,0,65,0,2,0,46,0,2,0,-119,0,2,0,-98,5,4,0,20,0,7,0,-97,5,24,0,36,0,-66, +0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-73,0,92,5,2,0,78,5,2, +0,-96,5,2,0,-95,5,2,0,-94,5,2,0,-93,5,-69,0,-108,5,2,0,-92,5,2,0,-119,0,2,0,-101,5,2, +0,-91,5,9,0,-90,5,2,0,29,5,0,0,-89,5,0,0,-88,5,2,0,-87,5,2,0,-86,5,2,0,12,3,2, +0,-85,5,2,0,-84,5,0,0,37,0,0,0,20,0,0,0,47,1,0,0,-83,5,-65,0,16,0,-75,0,0,0,-75, +0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69,0,-108,5,7,0,8,2,7,0,9,2,2, +0,-92,5,2,0,-82,5,2,0,-81,5,2,0,-80,5,4,0,20,0,7,0,71,5,-70,0,-127,5,-64,0,33,0,-75, +0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-63,0,-79,5,4,0,-78,5,0, +0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-74,5,2,0,20,0,2,0,-73,5,2,0,-72,5,2, +0,-71,5,2,0,-70,5,2,0,43,0,4,0,70,0,0,0,-69,5,-62,0,-68,5,2,0,-67,5,2,0,-66,5,2, +0,-65,5,2,0,-48,0,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9,0,-60,5,2,0,-59,5,0, +0,-58,5,-61,0,23,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, +0,-108,5,12,0,-57,5,2,0,-101,5,2,0,-56,5,2,0,20,0,2,0,57,0,9,0,-90,5,12,0,-55,5,-60, +0,-54,5,0,0,-53,5,-59,0,-52,5,4,0,-51,5,4,0,-50,5,2,0,18,0,2,0,-49,5,2,0,-48,5,2, +0,-47,5,-58,0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, +0,-108,5,46,0,-114,2,45,0,0,1,60,0,19,5,2,0,13,1,2,0,-119,0,2,0,-46,5,2,0,-45,5,4, +0,20,0,2,0,49,5,2,0,-44,5,2,0,-98,5,2,0,-101,5,7,0,71,5,0,0,-43,5,0,0,-42,5,0, +0,-41,5,0,0,-40,5,7,0,8,2,7,0,9,2,7,0,-39,5,7,0,-38,5,-70,0,-127,5,-57,0,11,0,-75, +0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,2,0,-119,0,2,0,-98,5,2, +0,-37,5,2,0,20,0,-69,0,-108,5,-56,0,24,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, +0,77,5,2,0,78,5,42,0,-36,5,4,0,-35,5,4,0,-34,5,2,0,93,0,2,0,-119,0,4,0,-33,5,4, +0,-32,5,4,0,-31,5,4,0,-30,5,4,0,-29,5,4,0,-28,5,4,0,-27,5,4,0,-26,5,7,0,-25,5,23, +0,-24,5,23,0,-23,5,4,0,-22,5,4,0,-21,5,-55,0,10,0,27,0,31,0,9,0,-20,5,9,0,-19,5,9, +0,-18,5,9,0,-17,5,9,0,-16,5,4,0,93,0,4,0,-15,5,0,0,-14,5,0,0,-13,5,-54,0,10,0,-75, +0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-55,0,-12,5,2,0,93,0,2,0,-119,0,4, +0,43,0,9,0,-11,5,-53,0,8,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-69, +0,-108,5,4,0,20,0,4,0,-10,5,-52,0,21,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, +0,77,5,2,0,78,5,-69,0,-108,5,27,0,-9,5,27,0,80,0,2,0,20,0,2,0,-119,0,7,0,-8,5,9, +0,-7,5,7,0,8,2,7,0,9,2,57,0,1,1,57,0,-6,5,4,0,-5,5,2,0,-89,5,2,0,37,0,-70, +0,-127,5,-51,0,42,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, +0,-108,5,-50,0,-4,5,0,0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-66,5,2,0,20,0,2, +0,-73,5,9,0,-7,5,4,0,-3,5,4,0,-2,5,4,0,-1,5,4,0,0,6,23,0,1,6,23,0,2,6,7, +0,3,6,7,0,4,6,7,0,5,6,7,0,-8,5,2,0,-67,5,2,0,-48,0,2,0,102,1,2,0,6,6,2, +0,37,0,2,0,43,0,2,0,7,6,2,0,8,6,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9, +0,-60,5,2,0,-59,5,0,0,-58,5,56,0,9,6,-49,0,20,0,0,0,10,6,0,0,11,6,0,0,12,6,0, +0,13,6,0,0,14,6,0,0,15,6,0,0,16,6,0,0,17,6,0,0,18,6,0,0,19,6,0,0,20,6,0, +0,21,6,0,0,22,6,0,0,23,6,0,0,24,6,0,0,25,6,0,0,26,6,0,0,27,6,0,0,68,2,0, +0,28,6,-48,0,54,0,0,0,29,6,0,0,20,6,0,0,21,6,0,0,30,6,0,0,31,6,0,0,32,6,0, +0,33,6,0,0,34,6,0,0,35,6,0,0,36,6,0,0,37,6,0,0,38,6,0,0,39,6,0,0,40,6,0, +0,41,6,0,0,42,6,0,0,43,6,0,0,44,6,0,0,45,6,0,0,46,6,0,0,47,6,0,0,48,6,0, +0,49,6,0,0,50,6,0,0,51,6,0,0,52,6,0,0,53,6,0,0,54,6,0,0,55,6,0,0,56,6,0, +0,57,6,0,0,58,6,0,0,95,0,0,0,59,6,0,0,60,6,0,0,61,6,0,0,62,6,0,0,63,6,0, +0,64,6,0,0,65,6,0,0,66,6,0,0,67,6,0,0,68,6,0,0,69,6,0,0,70,6,0,0,71,6,0, +0,72,6,0,0,73,6,0,0,74,6,0,0,75,6,0,0,76,6,0,0,77,6,0,0,78,6,0,0,79,6,-47, +0,5,0,0,0,80,6,0,0,37,6,0,0,39,6,2,0,20,0,2,0,37,0,-46,0,22,0,-46,0,0,0,-46, +0,1,0,0,0,17,0,-49,0,81,6,-48,0,82,6,-48,0,83,6,-48,0,84,6,-48,0,85,6,-48,0,86,6,-48, +0,87,6,-48,0,88,6,-48,0,89,6,-48,0,90,6,-48,0,91,6,-48,0,92,6,-48,0,93,6,-48,0,94,6,-48, +0,95,6,-48,0,96,6,-47,0,97,6,0,0,98,6,0,0,99,6,-45,0,5,0,4,0,20,0,4,0,37,0,7, +0,52,2,7,0,100,6,7,0,-31,1,-44,0,66,0,4,0,20,0,4,0,101,6,4,0,102,6,0,0,103,6,0, +0,104,6,0,0,105,6,0,0,106,6,0,0,107,6,0,0,108,6,0,0,109,6,0,0,110,6,0,0,111,6,2, +0,112,6,2,0,113,6,4,0,114,6,4,0,115,6,4,0,116,6,4,0,117,6,2,0,118,6,2,0,119,6,2, +0,120,6,2,0,121,6,4,0,122,6,4,0,123,6,2,0,124,6,2,0,125,6,2,0,126,6,2,0,127,6,0, +0,-128,6,12,0,-127,6,2,0,-126,6,2,0,-125,6,2,0,-124,6,2,0,-123,6,2,0,-122,6,2,0,-121,6,2, +0,-120,6,2,0,-119,6,-45,0,-118,6,2,0,-117,6,2,0,-116,6,2,0,-115,6,2,0,-114,6,4,0,-113,6,4, +0,-112,6,4,0,-111,6,4,0,-110,6,2,0,-109,6,2,0,-108,6,2,0,-107,6,2,0,-106,6,2,0,-105,6,2, +0,-104,6,2,0,-103,6,2,0,-102,6,2,0,-101,6,2,0,-100,6,2,0,-99,6,2,0,37,0,0,0,-98,6,0, +0,-97,6,0,0,-96,6,7,0,-95,6,2,0,55,5,2,0,-94,6,54,0,-93,6,-43,0,18,0,27,0,31,0,12, +0,-92,6,12,0,-91,6,12,0,-90,6,-79,0,-89,6,2,0,-105,2,2,0,-88,6,2,0,-104,2,2,0,-87,6,2, +0,-86,6,2,0,-85,6,2,0,-84,6,2,0,-83,6,2,0,-82,6,2,0,37,0,2,0,-81,6,2,0,-80,6,2, +0,-79,6,-42,0,5,0,-42,0,0,0,-42,0,1,0,-42,0,-78,6,13,0,-77,6,4,0,20,0,-41,0,7,0,-41, +0,0,0,-41,0,1,0,-42,0,-76,6,-42,0,-75,6,2,0,123,4,2,0,20,0,4,0,37,0,-40,0,17,0,-40, +0,0,0,-40,0,1,0,0,0,-74,6,0,0,-73,6,0,0,-72,6,2,0,-71,6,2,0,-70,6,2,0,-86,6,2, +0,-85,6,2,0,20,0,2,0,70,3,2,0,-69,6,2,0,-68,6,2,0,-67,6,2,0,-66,6,4,0,-65,6,-40, +0,-64,6,-74,0,30,0,-74,0,0,0,-74,0,1,0,-42,0,-76,6,-42,0,-75,6,-42,0,-63,6,-42,0,-62,6,-43, +0,-61,6,7,0,-60,6,23,0,52,0,23,0,-59,6,23,0,-58,6,2,0,-57,6,2,0,-56,6,2,0,-55,6,0, +0,75,5,0,0,-54,6,2,0,-53,6,2,0,-52,6,0,0,-51,6,0,0,-50,6,0,0,-49,6,0,0,-48,6,2, +0,-47,6,2,0,-46,6,2,0,-45,6,2,0,20,0,39,0,125,0,12,0,-44,6,12,0,-43,6,12,0,-42,6,-39, +0,11,0,0,0,-41,6,2,0,-40,6,2,0,-39,6,2,0,-38,6,2,0,-37,6,2,0,-36,6,2,0,107,4,9, +0,-35,6,9,0,-34,6,4,0,-33,6,4,0,-32,6,-38,0,1,0,0,0,-31,6,-37,0,8,0,56,0,-30,6,56, +0,-29,6,-37,0,-28,6,-37,0,-27,6,-37,0,-26,6,2,0,-123,0,2,0,20,0,4,0,-25,6,-36,0,4,0,4, +0,-35,5,4,0,-24,6,4,0,-31,5,4,0,-23,6,-35,0,2,0,4,0,-22,6,4,0,-21,6,-34,0,9,0,7, +0,-20,6,7,0,-19,6,7,0,-18,6,4,0,20,0,4,0,13,1,7,0,-19,3,7,0,-17,6,4,0,37,0,-33, +0,-16,6,-32,0,6,0,0,0,-15,6,0,0,-75,5,48,0,-116,0,2,0,109,0,2,0,111,4,4,0,37,0,-31, +0,21,0,-31,0,0,0,-31,0,1,0,4,0,57,0,4,0,23,0,4,0,28,0,4,0,-14,6,4,0,-13,6,4, +0,-12,6,-38,0,-11,6,0,0,-15,6,4,0,-10,6,4,0,-9,6,-32,0,-12,2,-36,0,-8,6,-35,0,-7,6,-34, +0,-6,6,-37,0,-5,6,-37,0,-4,6,-37,0,-3,6,56,0,-2,6,56,0,-1,6,-30,0,12,0,0,0,-68,1,9, +0,-62,0,0,0,-61,0,4,0,-58,0,4,0,-50,0,9,0,-57,0,7,0,-55,0,7,0,-54,0,9,0,0,7,9, +0,1,7,9,0,-53,0,9,0,-51,0,-29,0,43,0,-29,0,0,0,-29,0,1,0,9,0,2,7,9,0,26,0,0, +0,27,0,4,0,20,0,4,0,18,0,4,0,23,0,4,0,91,0,4,0,3,7,4,0,4,7,4,0,-13,6,4, +0,-12,6,4,0,5,7,4,0,-39,0,4,0,6,7,4,0,7,7,7,0,8,7,7,0,9,7,4,0,-126,0,4, +0,10,7,-31,0,11,7,36,0,79,0,-79,0,-89,6,48,0,-116,0,7,0,12,7,7,0,13,7,-30,0,2,1,-29, +0,14,7,-29,0,15,7,-29,0,16,7,12,0,17,7,-28,0,18,7,-27,0,19,7,7,0,20,7,7,0,21,7,4, +0,-84,6,7,0,22,7,9,0,23,7,4,0,24,7,4,0,25,7,4,0,26,7,7,0,27,7,-26,0,4,0,-26, +0,0,0,-26,0,1,0,12,0,28,7,-29,0,29,7,-25,0,6,0,12,0,30,7,12,0,17,7,12,0,31,7,2, +0,20,0,2,0,37,0,4,0,57,0,-24,0,4,0,7,0,32,7,7,0,112,0,2,0,33,7,2,0,34,7,-23, +0,6,0,7,0,35,7,7,0,36,7,7,0,37,7,7,0,38,7,4,0,39,7,4,0,40,7,-22,0,12,0,7, +0,41,7,7,0,42,7,7,0,43,7,7,0,44,7,7,0,45,7,7,0,46,7,7,0,47,7,7,0,48,7,7, +0,49,7,7,0,50,7,4,0,-110,2,4,0,51,7,-21,0,2,0,7,0,-55,4,7,0,37,0,-20,0,7,0,7, +0,52,7,7,0,53,7,4,0,93,0,4,0,108,2,4,0,54,7,4,0,55,7,4,0,37,0,-19,0,6,0,-19, +0,0,0,-19,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,-18,0,8,0,-18,0,0,0,-18, +0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,7,0,23,0,7,0,-126,0,-17,0,45,0,-17, +0,0,0,-17,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,2,0,-103,3,2,0,57,7,7, +0,58,7,7,0,92,0,7,0,-97,2,4,0,59,7,4,0,81,0,4,0,110,2,7,0,60,7,7,0,61,7,7, +0,62,7,7,0,63,7,7,0,64,7,7,0,65,7,7,0,-100,2,7,0,-1,0,7,0,66,7,7,0,67,7,7, +0,37,0,7,0,68,7,7,0,69,7,7,0,70,7,2,0,71,7,2,0,72,7,2,0,73,7,2,0,74,7,2, +0,75,7,2,0,76,7,2,0,77,7,2,0,78,7,2,0,123,5,2,0,79,7,2,0,-47,1,2,0,80,7,0, +0,81,7,0,0,82,7,7,0,-45,0,-16,0,83,7,63,0,-95,1,-15,0,16,0,-15,0,0,0,-15,0,1,0,2, +0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,7,0,-105,2,7,0,-104,2,7,0,-103,2,7,0,-5,1,7, +0,-102,2,7,0,-101,2,7,0,84,7,7,0,-100,2,7,0,-98,2,7,0,-97,2,-59,0,5,0,2,0,18,0,2, +0,-25,6,2,0,20,0,2,0,85,7,27,0,-9,5,-60,0,3,0,4,0,69,0,4,0,86,7,-59,0,2,0,-14, +0,12,0,-14,0,0,0,-14,0,1,0,2,0,18,0,2,0,20,0,2,0,31,3,2,0,-32,1,7,0,5,0,7, +0,6,0,7,0,87,7,7,0,88,7,27,0,-9,5,12,0,89,7,-13,0,11,0,-13,0,0,0,-13,0,1,0,0, +0,17,0,2,0,18,0,2,0,90,7,4,0,22,0,4,0,91,7,2,0,20,0,2,0,37,0,9,0,92,7,9, +0,93,7,-12,0,5,0,0,0,17,0,7,0,20,1,7,0,94,7,4,0,95,7,4,0,37,0,-11,0,4,0,2, +0,18,0,2,0,20,0,2,0,43,0,2,0,70,0,-10,0,4,0,0,0,17,0,62,0,96,7,7,0,20,1,7, +0,37,0,-9,0,6,0,2,0,97,7,2,0,98,7,2,0,18,0,2,0,99,7,0,0,100,7,0,0,101,7,-8, +0,5,0,4,0,18,0,4,0,37,0,0,0,17,0,0,0,102,7,0,0,103,7,-7,0,3,0,4,0,18,0,4, +0,37,0,0,0,17,0,-6,0,4,0,2,0,104,7,2,0,105,7,2,0,20,0,2,0,37,0,-5,0,6,0,0, +0,17,0,0,0,106,7,2,0,107,7,2,0,-100,2,2,0,13,1,2,0,70,0,-4,0,5,0,0,0,17,0,7, +0,112,0,7,0,-17,3,2,0,20,0,2,0,122,2,-3,0,3,0,0,0,17,0,4,0,110,2,4,0,104,7,-2, +0,7,0,0,0,17,0,7,0,-17,3,0,0,108,7,0,0,109,7,2,0,13,1,2,0,43,0,4,0,110,7,-1, +0,3,0,32,0,111,7,0,0,112,7,0,0,113,7,0,1,18,0,0,1,0,0,0,1,1,0,2,0,18,0,2, +0,90,7,2,0,20,0,2,0,114,7,2,0,115,7,2,0,116,7,2,0,43,0,2,0,70,0,0,0,17,0,9, +0,2,0,1,1,117,7,32,0,45,0,2,0,-47,4,2,0,20,7,2,0,118,7,2,0,37,0,2,1,11,0,0, +0,17,0,0,0,18,0,0,0,119,7,2,0,20,0,2,0,122,2,2,0,120,7,4,0,121,7,4,0,122,7,4, +0,123,7,4,0,124,7,4,0,125,7,3,1,1,0,0,0,126,7,4,1,4,0,42,0,-36,5,0,0,127,7,4, +0,13,1,4,0,20,0,1,1,18,0,1,1,0,0,1,1,1,0,1,1,-128,7,2,0,18,0,2,0,20,0,2, +0,-127,7,2,0,116,7,2,0,90,7,2,0,-126,7,2,0,70,0,2,0,12,1,0,0,17,0,9,0,2,0,5, +1,117,7,0,1,-125,7,2,0,15,0,2,0,-124,7,4,0,-123,7,6,1,3,0,4,0,-74,2,4,0,37,0,32, +0,45,0,7,1,12,0,-111,0,-122,7,2,0,18,0,2,0,20,0,4,0,58,7,4,0,92,0,0,0,17,0,0, +0,-121,7,2,0,-120,7,2,0,-119,7,2,0,-118,7,2,0,-117,7,7,0,-116,7,8,1,10,0,2,0,20,0,2, +0,-115,7,4,0,58,7,4,0,92,0,2,0,-114,7,-28,0,18,7,2,0,18,0,2,0,-113,7,2,0,-112,7,2, +0,-111,7,9,1,7,0,2,0,20,0,2,0,-115,7,4,0,58,7,4,0,92,0,2,0,18,0,2,0,-110,7,7, +0,109,3,10,1,11,0,4,0,-74,2,2,0,18,0,2,0,20,0,32,0,45,0,74,0,-109,7,0,0,17,0,7, +0,-108,7,7,0,-107,7,7,0,21,3,2,0,-106,7,2,0,-105,7,11,1,5,0,2,0,18,0,2,0,20,0,4, +0,37,0,-79,0,-89,6,32,0,39,5,12,1,5,0,4,0,20,0,4,0,18,0,0,0,17,0,0,0,102,7,32, +0,45,0,13,1,13,0,2,0,20,0,2,0,18,0,2,0,90,7,2,0,22,3,7,0,-104,7,7,0,-103,7,7, +0,7,1,7,0,8,1,7,0,-3,2,7,0,0,3,7,0,-102,7,7,0,-101,7,32,0,-100,7,14,1,10,0,2, +0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,0,0,-121,7,2,0,43,0,2,0,64,0,2, +0,-99,7,2,0,-98,7,15,1,8,0,32,0,45,0,7,0,-103,2,7,0,-97,7,7,0,-96,7,7,0,-108,2,2, +0,20,0,2,0,122,2,7,0,-95,7,16,1,12,0,2,0,18,0,2,0,13,1,2,0,20,0,2,0,-100,2,2, +0,-74,2,2,0,-94,7,4,0,37,0,7,0,-93,7,7,0,-92,7,7,0,-91,7,7,0,-90,7,0,0,-89,7,17, +1,10,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,2,0,68,2,2,0,64,0,2, +0,-99,7,2,0,-98,7,63,0,-95,1,18,1,7,0,4,0,110,2,4,0,-88,7,4,0,-87,7,4,0,-86,7,7, +0,-85,7,7,0,-84,7,0,0,108,7,19,1,7,0,0,0,-83,7,32,0,-82,7,0,0,112,7,2,0,-81,7,2, +0,43,0,4,0,70,0,0,0,113,7,20,1,6,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0, +0,-80,7,0,0,-79,7,21,1,1,0,4,0,20,0,22,1,6,0,0,0,95,0,2,0,18,0,2,0,20,0,4, +0,-78,7,7,0,-77,7,42,0,-36,5,23,1,4,0,0,0,-74,0,2,0,20,0,4,0,18,0,32,0,45,0,24, +1,2,0,4,0,18,0,4,0,-121,5,5,1,10,0,5,1,0,0,5,1,1,0,5,1,-128,7,2,0,18,0,2, +0,20,0,2,0,90,7,2,0,-76,7,0,0,17,0,9,0,2,0,32,0,45,0,25,1,10,0,7,0,21,3,7, +0,-75,7,7,0,-74,7,7,0,-73,7,7,0,-72,7,4,0,20,0,7,0,-94,7,7,0,-71,7,7,0,-70,7,7, +0,37,0,-28,0,20,0,27,0,31,0,0,0,-63,0,26,1,-69,7,9,0,-68,7,43,0,-104,0,43,0,-67,7,9, +0,-66,7,36,0,79,0,7,0,109,3,7,0,-65,7,7,0,-64,7,7,0,-63,7,7,0,-62,7,7,0,-61,7,7, +0,-60,7,4,0,93,0,4,0,-59,7,0,0,-58,7,0,0,-57,7,0,0,-56,7,27,1,6,0,27,0,31,0,7, +0,-55,7,7,0,-54,7,7,0,-53,7,2,0,-52,7,2,0,-51,7,28,1,14,0,-75,0,0,0,-75,0,1,0,4, +0,75,5,7,0,76,5,-74,0,77,5,-69,0,-108,5,-28,0,18,7,2,0,13,1,2,0,-115,7,2,0,8,2,2, +0,9,2,2,0,20,0,2,0,-98,5,4,0,70,0,29,1,6,0,29,1,0,0,29,1,1,0,32,0,45,0,9, +0,-50,7,4,0,-38,0,4,0,37,0,63,0,4,0,27,0,31,0,12,0,-49,7,4,0,-121,0,7,0,-48,7,30, +1,25,0,30,1,0,0,30,1,1,0,30,1,38,0,12,0,-47,7,0,0,17,0,7,0,-46,7,7,0,-45,7,7, +0,-44,7,7,0,-43,7,4,0,20,0,7,0,-42,7,7,0,-41,7,7,0,-40,7,7,0,20,1,7,0,-39,1,7, +0,-39,7,7,0,108,2,7,0,-38,7,7,0,-37,7,7,0,-36,7,7,0,-35,7,7,0,-34,7,7,0,-81,0,2, +0,-121,0,2,0,-31,4,31,1,19,0,27,0,31,0,12,0,-33,7,12,0,-32,7,4,0,20,0,4,0,30,4,2, +0,-96,2,2,0,-31,7,2,0,-121,0,2,0,-30,7,2,0,-29,7,2,0,-28,7,2,0,-27,7,2,0,-26,7,4, +0,-25,7,4,0,-24,7,4,0,-23,7,4,0,-22,7,4,0,-21,7,4,0,-20,7,32,1,34,0,32,1,0,0,32, +1,1,0,12,0,49,3,0,0,17,0,2,0,20,0,2,0,-19,7,2,0,-18,7,2,0,-17,7,2,0,10,3,2, +0,-16,7,4,0,-7,1,4,0,-23,7,4,0,-22,7,30,1,-15,7,32,1,38,0,32,1,-14,7,12,0,-13,7,9, +0,-12,7,9,0,-11,7,9,0,-10,7,7,0,7,1,7,0,-81,0,7,0,-57,1,7,0,-9,7,7,0,-8,7,7, +0,2,3,7,0,-7,7,7,0,-6,7,7,0,-5,7,7,0,-4,7,7,0,-3,7,7,0,-2,7,7,0,-10,1,32, +0,-1,7,-110,0,9,0,12,0,0,8,2,0,20,0,2,0,1,8,7,0,20,3,7,0,2,8,7,0,3,8,12, +0,4,8,4,0,5,8,4,0,37,0,33,1,7,0,33,1,0,0,33,1,1,0,12,0,-58,7,4,0,20,0,4, +0,6,8,0,0,17,0,-47,0,7,8,34,1,8,0,34,1,0,0,34,1,1,0,33,1,8,8,36,0,79,0,12, +0,-6,2,4,0,20,0,0,0,17,0,4,0,9,8,-111,0,6,0,27,0,31,0,12,0,0,8,12,0,10,8,12, +0,103,0,4,0,11,8,4,0,37,0,35,1,16,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, +0,77,5,2,0,78,5,-69,0,-108,5,-111,0,-9,2,0,0,13,1,0,0,-37,5,2,0,20,0,2,0,12,8,2, +0,-101,5,2,0,-98,5,2,0,13,8,7,0,14,8,36,1,5,0,36,1,0,0,36,1,1,0,36,0,79,0,2, +0,20,0,0,0,15,8,37,1,12,0,37,1,0,0,37,1,1,0,9,0,2,0,2,0,18,0,2,0,20,0,0, +0,16,8,0,0,17,8,0,0,15,8,7,0,18,8,7,0,19,8,4,0,37,0,36,0,79,0,38,1,9,0,38, +1,0,0,38,1,1,0,32,0,20,8,0,0,21,8,7,0,22,8,2,0,23,8,2,0,20,0,2,0,18,0,2, +0,37,0,39,1,7,0,42,0,-36,5,26,0,24,8,4,0,20,0,4,0,25,8,12,0,26,8,32,0,20,8,0, +0,21,8,40,1,12,0,32,0,20,8,2,0,27,8,2,0,20,0,2,0,28,8,2,0,29,8,0,0,21,8,32, +0,30,8,0,0,31,8,7,0,32,8,7,0,-39,1,7,0,33,8,7,0,34,8,41,1,6,0,32,0,20,8,4, +0,9,8,4,0,35,8,4,0,93,0,4,0,37,0,0,0,21,8,42,1,4,0,32,0,20,8,4,0,20,0,4, +0,9,8,0,0,21,8,43,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,44,1,10,0,32, +0,20,8,4,0,36,8,7,0,-127,0,4,0,20,0,2,0,-42,5,2,0,37,8,2,0,43,0,2,0,70,0,7, +0,38,8,0,0,21,8,45,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,46,1,10,0,32, +0,20,8,2,0,18,0,2,0,-95,3,4,0,91,0,4,0,92,0,7,0,-97,7,7,0,-96,7,4,0,37,0,-111, +0,-122,7,0,0,21,8,47,1,4,0,32,0,20,8,4,0,7,3,4,0,39,8,0,0,21,8,48,1,5,0,32, +0,20,8,7,0,-127,0,4,0,40,8,4,0,7,3,4,0,8,3,49,1,6,0,32,0,20,8,4,0,41,8,4, +0,42,8,7,0,43,8,7,0,44,8,0,0,21,8,50,1,16,0,32,0,20,8,32,0,-14,7,4,0,18,0,7, +0,45,8,7,0,46,8,7,0,47,8,7,0,48,8,7,0,49,8,7,0,50,8,7,0,51,8,7,0,52,8,7, +0,53,8,2,0,20,0,2,0,37,0,2,0,43,0,2,0,70,0,51,1,3,0,32,0,20,8,4,0,20,0,4, +0,123,5,52,1,5,0,32,0,20,8,4,0,20,0,4,0,37,0,7,0,54,8,0,0,21,8,53,1,10,0,32, +0,20,8,0,0,21,8,2,0,55,8,2,0,56,8,0,0,57,8,0,0,58,8,7,0,59,8,7,0,60,8,7, +0,61,8,7,0,62,8,54,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7,0,63,8,7, +0,64,8,2,0,20,0,2,0,123,5,55,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7, +0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,56,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7, +0,12,0,7,0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,57,1,7,0,32,0,20,8,0,0,21,8,7, +0,20,1,7,0,30,1,2,0,20,0,2,0,13,1,4,0,37,0,58,1,5,0,32,0,-45,2,7,0,20,1,2, +0,-41,2,0,0,-39,2,0,0,65,8,59,1,10,0,59,1,0,0,59,1,1,0,2,0,18,0,2,0,20,0,0, +0,66,8,7,0,-36,0,7,0,-35,0,2,0,-58,7,2,0,67,8,32,0,45,0,60,1,22,0,60,1,0,0,60, +1,1,0,2,0,20,0,2,0,13,1,2,0,68,8,2,0,69,8,36,0,79,0,-111,0,-122,7,32,0,-89,0,7, +0,91,0,7,0,92,0,7,0,70,8,7,0,71,8,7,0,72,8,7,0,73,8,7,0,-107,2,7,0,-67,1,7, +0,-120,7,7,0,74,8,0,0,75,8,0,0,76,8,12,0,-4,2,61,1,8,0,7,0,-31,1,7,0,-97,7,7, +0,-96,7,9,0,2,0,2,0,77,8,2,0,78,8,2,0,79,8,2,0,80,8,62,1,18,0,62,1,0,0,62, +1,1,0,62,1,81,8,0,0,17,0,61,1,82,8,2,0,18,0,2,0,20,0,2,0,83,8,2,0,84,8,2, +0,85,8,2,0,86,8,4,0,43,0,7,0,87,8,7,0,88,8,4,0,89,8,4,0,90,8,62,1,91,8,63, +1,92,8,64,1,32,0,64,1,0,0,64,1,1,0,64,1,93,8,0,0,17,0,0,0,94,8,2,0,18,0,2, +0,20,0,2,0,-14,6,2,0,20,7,2,0,95,8,2,0,-119,0,2,0,84,8,2,0,-25,6,12,0,-127,7,12, +0,96,8,27,0,-9,5,9,0,97,8,7,0,87,8,7,0,88,8,7,0,-5,1,7,0,98,8,2,0,99,8,2, +0,100,8,7,0,101,8,7,0,102,8,2,0,103,8,2,0,104,8,24,0,105,8,24,0,106,8,24,0,107,8,65, +1,-103,0,66,1,108,8,63,1,6,0,63,1,0,0,63,1,1,0,64,1,109,8,64,1,110,8,62,1,111,8,62, +1,91,8,57,0,16,0,27,0,31,0,12,0,112,8,12,0,113,8,61,1,114,8,12,0,115,8,4,0,18,0,4, +0,116,8,4,0,117,8,4,0,118,8,12,0,119,8,66,1,120,8,62,1,121,8,62,1,122,8,9,0,123,8,9, +0,124,8,4,0,125,8,67,1,6,0,4,0,-128,0,4,0,-126,0,4,0,-25,6,0,0,126,8,0,0,127,8,2, +0,37,0,68,1,16,0,2,0,-86,6,2,0,-85,6,2,0,-128,8,2,0,-74,7,2,0,-127,8,2,0,68,0,7, +0,-108,2,7,0,-126,8,7,0,-125,8,2,0,34,1,0,0,-124,8,0,0,42,4,2,0,-123,8,2,0,37,0,4, +0,-122,8,4,0,-121,8,69,1,9,0,7,0,-120,8,7,0,-119,8,7,0,-60,7,7,0,112,0,7,0,-118,8,7, +0,71,5,2,0,-117,8,0,0,-116,8,0,0,37,0,70,1,4,0,7,0,-115,8,7,0,-114,8,2,0,-117,8,2, +0,37,0,71,1,3,0,7,0,-113,8,7,0,-112,8,7,0,15,0,72,1,7,0,0,0,-68,1,2,0,109,4,2, +0,110,4,2,0,111,4,2,0,62,4,4,0,-126,0,4,0,-97,3,73,1,7,0,7,0,-111,8,7,0,-110,8,7, +0,-109,8,7,0,4,2,7,0,-108,8,7,0,-107,8,7,0,-106,8,74,1,4,0,2,0,-105,8,2,0,-104,8,2, +0,-103,8,2,0,-102,8,75,1,2,0,7,0,5,0,7,0,6,0,76,1,2,0,0,0,-87,0,0,0,-101,8,77, +1,1,0,0,0,17,0,78,1,10,0,0,0,-100,8,0,0,-99,8,0,0,-98,8,0,0,-97,8,2,0,-128,8,2, +0,-96,8,7,0,-95,8,7,0,-94,8,7,0,-93,8,7,0,-67,1,79,1,2,0,9,0,-92,8,9,0,-91,8,80, +1,11,0,0,0,111,4,0,0,18,0,0,0,-117,8,0,0,112,0,0,0,-90,8,0,0,109,0,0,0,-74,0,7, +0,-89,8,7,0,-88,8,7,0,-87,8,7,0,-86,8,81,1,8,0,7,0,97,7,7,0,-127,0,7,0,42,4,7, +0,72,2,7,0,-85,8,7,0,-49,0,7,0,-84,8,4,0,18,0,82,1,4,0,2,0,-83,8,2,0,-82,8,2, +0,-81,8,2,0,37,0,83,1,1,0,0,0,17,0,84,1,4,0,7,0,5,0,7,0,6,0,2,0,20,0,2, +0,-80,8,85,1,10,0,2,0,-120,3,2,0,20,0,7,0,-17,3,7,0,-79,8,7,0,-78,8,7,0,-77,8,7, +0,-76,8,84,1,-75,8,84,1,-74,8,84,1,-73,8,60,0,9,0,4,0,20,0,4,0,64,0,24,0,-72,8,24, +0,-71,8,85,1,-70,8,7,0,-69,8,7,0,-68,8,7,0,-67,8,7,0,-66,8,86,1,4,0,46,0,-114,2,7, +0,-65,8,7,0,92,1,7,0,37,0,-87,0,13,0,27,0,31,0,2,0,20,0,2,0,72,5,4,0,109,0,7, +0,-64,8,7,0,1,2,7,0,-63,8,7,0,-62,8,7,0,92,1,2,0,47,1,2,0,37,0,50,0,77,1,86, +1,-61,8,87,1,10,0,4,0,18,0,4,0,-127,0,4,0,20,0,4,0,70,3,4,0,-60,8,4,0,-59,8,4, +0,-58,8,0,0,95,0,0,0,17,0,9,0,2,0,84,0,6,0,87,1,-57,8,4,0,-56,8,4,0,-55,8,4, +0,-54,8,4,0,37,0,9,0,-53,8,88,1,5,0,7,0,66,2,7,0,-74,2,7,0,-39,1,2,0,-52,8,2, +0,37,0,89,1,5,0,7,0,66,2,7,0,-51,8,7,0,-50,8,7,0,-49,8,7,0,-74,2,90,1,7,0,4, +0,-48,8,4,0,-47,8,4,0,-46,8,7,0,-45,8,7,0,-44,8,7,0,-43,8,7,0,-42,8,91,1,26,0,32, +0,-41,8,89,1,66,3,89,1,-40,8,88,1,-39,8,89,1,83,7,7,0,-38,8,7,0,-37,8,7,0,-36,8,7, +0,-35,8,7,0,-44,8,7,0,-43,8,7,0,-74,2,7,0,-97,2,7,0,-34,8,7,0,-33,8,7,0,109,0,7, +0,-32,8,4,0,-48,8,4,0,-31,8,4,0,37,0,4,0,81,0,4,0,-30,8,2,0,20,0,2,0,-29,8,2, +0,-28,8,2,0,100,3,92,1,112,0,27,0,31,0,4,0,20,0,2,0,18,0,2,0,55,8,2,0,-27,8,2, +0,-26,8,2,0,-25,8,2,0,-24,8,2,0,-23,8,2,0,-22,8,2,0,-21,8,2,0,-20,8,2,0,-19,8,2, +0,-18,8,2,0,-17,8,2,0,-16,8,2,0,-15,8,2,0,-14,8,2,0,-13,8,2,0,-47,1,2,0,76,7,2, +0,51,7,2,0,-12,8,2,0,-11,8,2,0,98,3,2,0,99,3,2,0,-10,8,2,0,-9,8,2,0,-8,8,2, +0,-7,8,2,0,-6,8,2,0,-5,8,7,0,-4,8,7,0,-3,8,7,0,-2,8,2,0,-1,8,2,0,0,9,7, +0,1,9,7,0,2,9,7,0,3,9,7,0,58,7,7,0,92,0,7,0,-97,2,7,0,64,7,7,0,4,9,7, +0,5,9,7,0,6,9,7,0,7,9,7,0,57,0,4,0,59,7,4,0,57,7,4,0,8,9,7,0,60,7,7, +0,61,7,7,0,62,7,7,0,9,9,7,0,10,9,7,0,11,9,7,0,12,9,7,0,13,9,7,0,14,9,7, +0,15,9,7,0,16,9,7,0,21,3,7,0,109,0,7,0,17,9,7,0,18,9,7,0,19,9,7,0,20,9,7, +0,21,9,7,0,22,9,7,0,108,2,7,0,23,9,7,0,24,9,4,0,25,9,4,0,26,9,7,0,27,9,7, +0,28,9,7,0,29,9,7,0,30,9,7,0,31,9,7,0,32,9,7,0,33,9,7,0,34,9,7,0,94,3,7, +0,92,3,7,0,93,3,7,0,35,9,7,0,36,9,7,0,37,9,7,0,38,9,7,0,39,9,7,0,40,9,7, +0,41,9,7,0,42,9,7,0,43,9,7,0,28,3,7,0,44,9,7,0,45,9,7,0,46,9,7,0,47,9,7, +0,48,9,7,0,49,9,7,0,50,9,0,0,51,9,63,0,55,3,63,0,52,9,32,0,53,9,32,0,54,9,36, +0,79,0,-108,0,53,3,-108,0,55,9,-120,0,37,0,-120,0,0,0,-120,0,1,0,92,1,56,9,91,1,-121,3,90, +1,-14,7,93,1,57,9,94,1,58,9,94,1,59,9,12,0,60,9,12,0,61,9,-107,0,54,3,32,0,62,9,32, +0,63,9,32,0,64,9,12,0,65,9,12,0,66,9,7,0,-45,0,7,0,83,4,4,0,110,2,4,0,20,0,4, +0,59,7,4,0,67,9,4,0,68,9,4,0,69,9,4,0,57,0,2,0,-38,0,2,0,70,9,2,0,71,9,2, +0,72,9,2,0,47,3,2,0,73,9,0,0,74,9,2,0,75,9,2,0,76,9,2,0,77,9,9,0,78,9,125, +0,-76,3,123,0,34,0,95,1,79,9,7,0,-106,3,7,0,80,9,7,0,81,9,7,0,-14,3,7,0,82,9,7, +0,31,3,7,0,21,3,7,0,83,9,7,0,3,2,7,0,84,9,7,0,85,9,7,0,86,9,7,0,87,9,7, +0,88,9,7,0,89,9,7,0,-105,3,7,0,90,9,7,0,91,9,7,0,92,9,7,0,-104,3,7,0,-108,3,7, +0,-107,3,4,0,93,9,4,0,93,0,4,0,94,9,4,0,95,9,2,0,96,9,2,0,97,9,2,0,98,9,2, +0,99,9,2,0,100,9,2,0,37,0,4,0,70,0,124,0,8,0,95,1,101,9,7,0,102,9,7,0,103,9,7, +0,-94,1,7,0,104,9,4,0,93,0,2,0,105,9,2,0,106,9,96,1,4,0,7,0,5,0,7,0,6,0,7, +0,7,0,7,0,107,9,97,1,6,0,97,1,0,0,97,1,1,0,96,1,108,9,4,0,109,9,2,0,110,9,2, +0,20,0,98,1,5,0,98,1,0,0,98,1,1,0,12,0,111,9,4,0,112,9,4,0,20,0,99,1,9,0,99, +1,0,0,99,1,1,0,12,0,-128,0,98,1,113,9,4,0,20,0,2,0,110,9,2,0,114,9,7,0,94,0,0, +0,115,9,-70,0,5,0,12,0,125,4,4,0,20,0,2,0,116,9,2,0,117,9,9,0,118,9,69,78,68,66,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +int DNAlen64= sizeof(DNAstr64); diff --git a/Extras/Serialize/BlenderSerialize/dna249.cpp b/Extras/Serialize/BlenderSerialize/dna249.cpp new file mode 100644 index 0000000..97881b4 --- /dev/null +++ b/Extras/Serialize/BlenderSerialize/dna249.cpp @@ -0,0 +1,1411 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +unsigned char DNAstr[]= { +83,68,78,65,78,65,77,69,119,9,0,0,42,110,101,120,116,0,42,112,114,101,118,0,42,100,97,116,97,0,42,102,105, +114,115,116,0,42,108,97,115,116,0,120,0,121,0,122,0,119,0,120,109,105,110,0,120,109,97,120,0,121,109,105,110, +0,121,109,97,120,0,42,112,111,105,110,116,101,114,0,103,114,111,117,112,0,118,97,108,0,118,97,108,50,0,110,97, +109,101,91,51,50,93,0,116,121,112,101,0,115,117,98,116,121,112,101,0,102,108,97,103,0,115,97,118,101,100,0,100, +97,116,97,0,108,101,110,0,116,111,116,97,108,108,101,110,0,42,110,101,119,105,100,0,42,108,105,98,0,110,97,109, +101,91,50,52,93,0,117,115,0,105,99,111,110,95,105,100,0,42,112,114,111,112,101,114,116,105,101,115,0,105,100,0, +42,105,100,98,108,111,99,107,0,42,102,105,108,101,100,97,116,97,0,110,97,109,101,91,50,52,48,93,0,102,105,108, +101,110,97,109,101,91,50,52,48,93,0,116,111,116,0,112,97,100,0,42,112,97,114,101,110,116,0,119,91,50,93,0, +104,91,50,93,0,99,104,97,110,103,101,100,91,50,93,0,112,97,100,48,0,112,97,100,49,0,42,114,101,99,116,91, +50,93,0,42,111,98,0,98,108,111,99,107,116,121,112,101,0,97,100,114,99,111,100,101,0,110,97,109,101,91,49,50, +56,93,0,42,98,112,0,42,98,101,122,116,0,109,97,120,114,99,116,0,116,111,116,114,99,116,0,118,97,114,116,121, +112,101,0,116,111,116,118,101,114,116,0,105,112,111,0,101,120,116,114,97,112,0,114,116,0,98,105,116,109,97,115,107, +0,115,108,105,100,101,95,109,105,110,0,115,108,105,100,101,95,109,97,120,0,99,117,114,118,97,108,0,42,100,114,105, +118,101,114,0,99,117,114,118,101,0,99,117,114,0,115,104,111,119,107,101,121,0,109,117,116,101,105,112,111,0,112,111, +115,0,114,101,108,97,116,105,118,101,0,116,111,116,101,108,101,109,0,112,97,100,50,0,42,119,101,105,103,104,116,115, +0,118,103,114,111,117,112,91,51,50,93,0,115,108,105,100,101,114,109,105,110,0,115,108,105,100,101,114,109,97,120,0, +42,114,101,102,107,101,121,0,101,108,101,109,115,116,114,91,51,50,93,0,101,108,101,109,115,105,122,101,0,98,108,111, +99,107,0,42,105,112,111,0,42,102,114,111,109,0,116,111,116,107,101,121,0,115,108,117,114,112,104,0,42,42,115,99, +114,105,112,116,115,0,42,102,108,97,103,0,97,99,116,115,99,114,105,112,116,0,116,111,116,115,99,114,105,112,116,0, +42,108,105,110,101,0,42,102,111,114,109,97,116,0,98,108,101,110,0,108,105,110,101,110,111,0,115,116,97,114,116,0, +101,110,100,0,102,108,97,103,115,0,99,111,108,111,114,91,52,93,0,112,97,100,91,52,93,0,42,110,97,109,101,0, +110,108,105,110,101,115,0,108,105,110,101,115,0,42,99,117,114,108,0,42,115,101,108,108,0,99,117,114,99,0,115,101, +108,99,0,109,97,114,107,101,114,115,0,42,117,110,100,111,95,98,117,102,0,117,110,100,111,95,112,111,115,0,117,110, +100,111,95,108,101,110,0,42,99,111,109,112,105,108,101,100,0,109,116,105,109,101,0,115,105,122,101,0,115,101,101,107, +0,112,97,115,115,101,112,97,114,116,97,108,112,104,97,0,97,110,103,108,101,0,99,108,105,112,115,116,97,0,99,108, +105,112,101,110,100,0,108,101,110,115,0,111,114,116,104,111,95,115,99,97,108,101,0,100,114,97,119,115,105,122,101,0, +115,104,105,102,116,120,0,115,104,105,102,116,121,0,89,70,95,100,111,102,100,105,115,116,0,89,70,95,97,112,101,114, +116,117,114,101,0,89,70,95,98,107,104,116,121,112,101,0,89,70,95,98,107,104,98,105,97,115,0,89,70,95,98,107, +104,114,111,116,0,115,99,114,105,112,116,108,105,110,107,0,42,100,111,102,95,111,98,0,102,114,97,109,101,110,114,0, +102,114,97,109,101,115,0,111,102,102,115,101,116,0,115,102,114,97,0,102,105,101,95,105,109,97,0,99,121,99,108,0, +111,107,0,109,117,108,116,105,95,105,110,100,101,120,0,108,97,121,101,114,0,112,97,115,115,0,109,101,110,117,110,114, +0,105,98,117,102,115,0,42,103,112,117,116,101,120,116,117,114,101,0,42,97,110,105,109,0,42,114,114,0,115,111,117, +114,99,101,0,108,97,115,116,102,114,97,109,101,0,116,112,97,103,101,102,108,97,103,0,116,111,116,98,105,110,100,0, +120,114,101,112,0,121,114,101,112,0,116,119,115,116,97,0,116,119,101,110,100,0,98,105,110,100,99,111,100,101,0,42, +114,101,112,98,105,110,100,0,42,112,97,99,107,101,100,102,105,108,101,0,42,112,114,101,118,105,101,119,0,108,97,115, +116,117,112,100,97,116,101,0,108,97,115,116,117,115,101,100,0,97,110,105,109,115,112,101,101,100,0,103,101,110,95,120, +0,103,101,110,95,121,0,103,101,110,95,116,121,112,101,0,97,115,112,120,0,97,115,112,121,0,42,118,110,111,100,101, +0,116,101,120,99,111,0,109,97,112,116,111,0,109,97,112,116,111,110,101,103,0,98,108,101,110,100,116,121,112,101,0, +42,111,98,106,101,99,116,0,42,116,101,120,0,117,118,110,97,109,101,91,51,50,93,0,112,114,111,106,120,0,112,114, +111,106,121,0,112,114,111,106,122,0,109,97,112,112,105,110,103,0,111,102,115,91,51,93,0,115,105,122,101,91,51,93, +0,116,101,120,102,108,97,103,0,99,111,108,111,114,109,111,100,101,108,0,112,109,97,112,116,111,0,112,109,97,112,116, +111,110,101,103,0,110,111,114,109,97,112,115,112,97,99,101,0,119,104,105,99,104,95,111,117,116,112,117,116,0,112,97, +100,91,50,93,0,114,0,103,0,98,0,107,0,100,101,102,95,118,97,114,0,99,111,108,102,97,99,0,110,111,114,102, +97,99,0,118,97,114,102,97,99,0,100,105,115,112,102,97,99,0,119,97,114,112,102,97,99,0,110,97,109,101,91,49, +54,48,93,0,42,104,97,110,100,108,101,0,42,112,110,97,109,101,0,42,115,116,110,97,109,101,115,0,115,116,121,112, +101,115,0,118,97,114,115,0,42,118,97,114,115,116,114,0,42,114,101,115,117,108,116,0,42,99,102,114,97,0,100,97, +116,97,91,51,50,93,0,40,42,100,111,105,116,41,40,41,0,40,42,105,110,115,116,97,110,99,101,95,105,110,105,116, +41,40,41,0,40,42,99,97,108,108,98,97,99,107,41,40,41,0,118,101,114,115,105,111,110,0,97,0,105,112,111,116, +121,112,101,0,42,105,109,97,0,42,99,117,98,101,91,54,93,0,105,109,97,116,91,52,93,91,52,93,0,111,98,105, +109,97,116,91,51,93,91,51,93,0,115,116,121,112,101,0,118,105,101,119,115,99,97,108,101,0,110,111,116,108,97,121, +0,99,117,98,101,114,101,115,0,100,101,112,116,104,0,114,101,99,97,108,99,0,108,97,115,116,115,105,122,101,0,110, +111,105,115,101,115,105,122,101,0,116,117,114,98,117,108,0,98,114,105,103,104,116,0,99,111,110,116,114,97,115,116,0, +114,102,97,99,0,103,102,97,99,0,98,102,97,99,0,102,105,108,116,101,114,115,105,122,101,0,109,103,95,72,0,109, +103,95,108,97,99,117,110,97,114,105,116,121,0,109,103,95,111,99,116,97,118,101,115,0,109,103,95,111,102,102,115,101, +116,0,109,103,95,103,97,105,110,0,100,105,115,116,95,97,109,111,117,110,116,0,110,115,95,111,117,116,115,99,97,108, +101,0,118,110,95,119,49,0,118,110,95,119,50,0,118,110,95,119,51,0,118,110,95,119,52,0,118,110,95,109,101,120, +112,0,118,110,95,100,105,115,116,109,0,118,110,95,99,111,108,116,121,112,101,0,110,111,105,115,101,100,101,112,116,104, +0,110,111,105,115,101,116,121,112,101,0,110,111,105,115,101,98,97,115,105,115,0,110,111,105,115,101,98,97,115,105,115, +50,0,105,109,97,102,108,97,103,0,99,114,111,112,120,109,105,110,0,99,114,111,112,121,109,105,110,0,99,114,111,112, +120,109,97,120,0,99,114,111,112,121,109,97,120,0,120,114,101,112,101,97,116,0,121,114,101,112,101,97,116,0,101,120, +116,101,110,100,0,99,104,101,99,107,101,114,100,105,115,116,0,110,97,98,108,97,0,105,117,115,101,114,0,42,110,111, +100,101,116,114,101,101,0,42,112,108,117,103,105,110,0,42,99,111,98,97,0,42,101,110,118,0,117,115,101,95,110,111, +100,101,115,0,112,97,100,91,55,93,0,108,111,99,91,51,93,0,114,111,116,91,51,93,0,109,97,116,91,52,93,91, +52,93,0,109,105,110,91,51,93,0,109,97,120,91,51,93,0,112,97,100,51,0,109,111,100,101,0,116,111,116,101,120, +0,115,104,100,119,114,0,115,104,100,119,103,0,115,104,100,119,98,0,115,104,100,119,112,97,100,0,101,110,101,114,103, +121,0,100,105,115,116,0,115,112,111,116,115,105,122,101,0,115,112,111,116,98,108,101,110,100,0,104,97,105,110,116,0, +97,116,116,49,0,97,116,116,50,0,42,99,117,114,102,97,108,108,111,102,102,0,102,97,108,108,111,102,102,95,116,121, +112,101,0,115,104,97,100,115,112,111,116,115,105,122,101,0,98,105,97,115,0,115,111,102,116,0,98,117,102,115,105,122, +101,0,115,97,109,112,0,98,117,102,102,101,114,115,0,102,105,108,116,101,114,116,121,112,101,0,98,117,102,102,108,97, +103,0,98,117,102,116,121,112,101,0,114,97,121,95,115,97,109,112,0,114,97,121,95,115,97,109,112,121,0,114,97,121, +95,115,97,109,112,122,0,114,97,121,95,115,97,109,112,95,116,121,112,101,0,97,114,101,97,95,115,104,97,112,101,0, +97,114,101,97,95,115,105,122,101,0,97,114,101,97,95,115,105,122,101,121,0,97,114,101,97,95,115,105,122,101,122,0, +97,100,97,112,116,95,116,104,114,101,115,104,0,114,97,121,95,115,97,109,112,95,109,101,116,104,111,100,0,116,101,120, +97,99,116,0,115,104,97,100,104,97,108,111,115,116,101,112,0,115,117,110,95,101,102,102,101,99,116,95,116,121,112,101, +0,115,107,121,98,108,101,110,100,116,121,112,101,0,104,111,114,105,122,111,110,95,98,114,105,103,104,116,110,101,115,115, +0,115,112,114,101,97,100,0,115,117,110,95,98,114,105,103,104,116,110,101,115,115,0,115,117,110,95,115,105,122,101,0, +98,97,99,107,115,99,97,116,116,101,114,101,100,95,108,105,103,104,116,0,115,117,110,95,105,110,116,101,110,115,105,116, +121,0,97,116,109,95,116,117,114,98,105,100,105,116,121,0,97,116,109,95,105,110,115,99,97,116,116,101,114,105,110,103, +95,102,97,99,116,111,114,0,97,116,109,95,101,120,116,105,110,99,116,105,111,110,95,102,97,99,116,111,114,0,97,116, +109,95,100,105,115,116,97,110,99,101,95,102,97,99,116,111,114,0,115,107,121,98,108,101,110,100,102,97,99,0,115,107, +121,95,101,120,112,111,115,117,114,101,0,115,107,121,95,99,111,108,111,114,115,112,97,99,101,0,112,97,100,52,0,89, +70,95,110,117,109,112,104,111,116,111,110,115,0,89,70,95,110,117,109,115,101,97,114,99,104,0,89,70,95,112,104,100, +101,112,116,104,0,89,70,95,117,115,101,113,109,99,0,89,70,95,98,117,102,115,105,122,101,0,89,70,95,112,97,100, +0,89,70,95,99,97,117,115,116,105,99,98,108,117,114,0,89,70,95,108,116,114,97,100,105,117,115,0,89,70,95,103, +108,111,119,105,110,116,0,89,70,95,103,108,111,119,111,102,115,0,89,70,95,103,108,111,119,116,121,112,101,0,89,70, +95,112,97,100,50,0,42,109,116,101,120,91,49,56,93,0,115,112,101,99,114,0,115,112,101,99,103,0,115,112,101,99, +98,0,109,105,114,114,0,109,105,114,103,0,109,105,114,98,0,97,109,98,114,0,97,109,98,98,0,97,109,98,103,0, +97,109,98,0,101,109,105,116,0,97,110,103,0,115,112,101,99,116,114,97,0,114,97,121,95,109,105,114,114,111,114,0, +97,108,112,104,97,0,114,101,102,0,115,112,101,99,0,122,111,102,102,115,0,97,100,100,0,116,114,97,110,115,108,117, +99,101,110,99,121,0,102,114,101,115,110,101,108,95,109,105,114,0,102,114,101,115,110,101,108,95,109,105,114,95,105,0, +102,114,101,115,110,101,108,95,116,114,97,0,102,114,101,115,110,101,108,95,116,114,97,95,105,0,102,105,108,116,101,114, +0,116,120,95,108,105,109,105,116,0,116,120,95,102,97,108,108,111,102,102,0,114,97,121,95,100,101,112,116,104,0,114, +97,121,95,100,101,112,116,104,95,116,114,97,0,104,97,114,0,115,101,101,100,49,0,115,101,101,100,50,0,103,108,111, +115,115,95,109,105,114,0,103,108,111,115,115,95,116,114,97,0,115,97,109,112,95,103,108,111,115,115,95,109,105,114,0, +115,97,109,112,95,103,108,111,115,115,95,116,114,97,0,97,100,97,112,116,95,116,104,114,101,115,104,95,109,105,114,0, +97,100,97,112,116,95,116,104,114,101,115,104,95,116,114,97,0,97,110,105,115,111,95,103,108,111,115,115,95,109,105,114, +0,100,105,115,116,95,109,105,114,0,102,97,100,101,116,111,95,109,105,114,0,115,104,97,100,101,95,102,108,97,103,0, +109,111,100,101,95,108,0,102,108,97,114,101,99,0,115,116,97,114,99,0,108,105,110,101,99,0,114,105,110,103,99,0, +104,97,115,105,122,101,0,102,108,97,114,101,115,105,122,101,0,115,117,98,115,105,122,101,0,102,108,97,114,101,98,111, +111,115,116,0,115,116,114,97,110,100,95,115,116,97,0,115,116,114,97,110,100,95,101,110,100,0,115,116,114,97,110,100, +95,101,97,115,101,0,115,116,114,97,110,100,95,115,117,114,102,110,111,114,0,115,116,114,97,110,100,95,109,105,110,0, +115,116,114,97,110,100,95,119,105,100,116,104,102,97,100,101,0,115,116,114,97,110,100,95,117,118,110,97,109,101,91,51, +50,93,0,115,98,105,97,115,0,108,98,105,97,115,0,115,104,97,100,95,97,108,112,104,97,0,115,101,112,116,101,120, +0,114,103,98,115,101,108,0,112,114,95,116,121,112,101,0,112,114,95,98,97,99,107,0,112,114,95,108,97,109,112,0, +109,108,95,102,108,97,103,0,100,105,102,102,95,115,104,97,100,101,114,0,115,112,101,99,95,115,104,97,100,101,114,0, +114,111,117,103,104,110,101,115,115,0,114,101,102,114,97,99,0,112,97,114,97,109,91,52,93,0,114,109,115,0,100,97, +114,107,110,101,115,115,0,42,114,97,109,112,95,99,111,108,0,42,114,97,109,112,95,115,112,101,99,0,114,97,109,112, +105,110,95,99,111,108,0,114,97,109,112,105,110,95,115,112,101,99,0,114,97,109,112,98,108,101,110,100,95,99,111,108, +0,114,97,109,112,98,108,101,110,100,95,115,112,101,99,0,114,97,109,112,95,115,104,111,119,0,114,97,109,112,102,97, +99,95,99,111,108,0,114,97,109,112,102,97,99,95,115,112,101,99,0,42,103,114,111,117,112,0,102,114,105,99,116,105, +111,110,0,102,104,0,114,101,102,108,101,99,116,0,102,104,100,105,115,116,0,120,121,102,114,105,99,116,0,100,121,110, +97,109,111,100,101,0,115,115,115,95,114,97,100,105,117,115,91,51,93,0,115,115,115,95,99,111,108,91,51,93,0,115, +115,115,95,101,114,114,111,114,0,115,115,115,95,115,99,97,108,101,0,115,115,115,95,105,111,114,0,115,115,115,95,99, +111,108,102,97,99,0,115,115,115,95,116,101,120,102,97,99,0,115,115,115,95,102,114,111,110,116,0,115,115,115,95,98, +97,99,107,0,115,115,115,95,102,108,97,103,0,115,115,115,95,112,114,101,115,101,116,0,89,70,95,97,114,0,89,70, +95,97,103,0,89,70,95,97,98,0,89,70,95,100,115,99,97,108,101,0,89,70,95,100,112,119,114,0,89,70,95,100, +115,109,112,0,89,70,95,112,114,101,115,101,116,0,89,70,95,100,106,105,116,0,103,112,117,109,97,116,101,114,105,97, +108,0,110,97,109,101,91,50,53,54,93,0,115,99,97,108,101,0,42,98,98,0,105,49,0,106,49,0,107,49,0,105, +50,0,106,50,0,107,50,0,115,101,108,99,111,108,49,0,115,101,108,99,111,108,50,0,113,117,97,116,91,52,93,0, +101,120,112,120,0,101,120,112,121,0,101,120,112,122,0,114,97,100,0,114,97,100,50,0,115,0,42,109,97,116,0,42, +105,109,97,116,0,101,108,101,109,115,0,100,105,115,112,0,42,42,109,97,116,0,116,111,116,99,111,108,0,119,105,114, +101,115,105,122,101,0,114,101,110,100,101,114,115,105,122,101,0,116,104,114,101,115,104,0,118,101,99,91,51,93,91,51, +93,0,97,108,102,97,0,119,101,105,103,104,116,0,114,97,100,105,117,115,0,104,49,0,104,50,0,102,49,0,102,50, +0,102,51,0,104,105,100,101,0,118,101,99,91,52,93,0,109,97,116,95,110,114,0,112,110,116,115,117,0,112,110,116, +115,118,0,114,101,115,111,108,117,0,114,101,115,111,108,118,0,111,114,100,101,114,117,0,111,114,100,101,114,118,0,102, +108,97,103,117,0,102,108,97,103,118,0,42,107,110,111,116,115,117,0,42,107,110,111,116,115,118,0,116,105,108,116,95, +105,110,116,101,114,112,0,114,97,100,105,117,115,95,105,110,116,101,114,112,0,99,104,97,114,105,100,120,0,107,101,114, +110,0,104,0,110,117,114,98,0,42,98,101,118,111,98,106,0,42,116,97,112,101,114,111,98,106,0,42,116,101,120,116, +111,110,99,117,114,118,101,0,42,112,97,116,104,0,42,107,101,121,0,98,101,118,0,112,97,116,104,108,101,110,0,98, +101,118,114,101,115,111,108,0,119,105,100,116,104,0,101,120,116,49,0,101,120,116,50,0,114,101,115,111,108,117,95,114, +101,110,0,114,101,115,111,108,118,95,114,101,110,0,115,112,97,99,101,109,111,100,101,0,115,112,97,99,105,110,103,0, +108,105,110,101,100,105,115,116,0,115,104,101,97,114,0,102,115,105,122,101,0,119,111,114,100,115,112,97,99,101,0,117, +108,112,111,115,0,117,108,104,101,105,103,104,116,0,120,111,102,0,121,111,102,0,108,105,110,101,119,105,100,116,104,0, +42,115,116,114,0,102,97,109,105,108,121,91,50,52,93,0,42,118,102,111,110,116,0,42,118,102,111,110,116,98,0,42, +118,102,111,110,116,105,0,42,118,102,111,110,116,98,105,0,115,101,112,99,104,97,114,0,116,111,116,98,111,120,0,97, +99,116,98,111,120,0,42,116,98,0,115,101,108,115,116,97,114,116,0,115,101,108,101,110,100,0,42,115,116,114,105,110, +102,111,0,99,117,114,105,110,102,111,0,101,102,102,101,99,116,0,42,109,102,97,99,101,0,42,109,116,102,97,99,101, +0,42,116,102,97,99,101,0,42,109,118,101,114,116,0,42,109,101,100,103,101,0,42,100,118,101,114,116,0,42,109,99, +111,108,0,42,109,115,116,105,99,107,121,0,42,116,101,120,99,111,109,101,115,104,0,42,109,115,101,108,101,99,116,0, +118,100,97,116,97,0,101,100,97,116,97,0,102,100,97,116,97,0,116,111,116,101,100,103,101,0,116,111,116,102,97,99, +101,0,116,111,116,115,101,108,101,99,116,0,97,99,116,95,102,97,99,101,0,99,117,98,101,109,97,112,115,105,122,101, +0,115,109,111,111,116,104,114,101,115,104,0,115,117,98,100,105,118,0,115,117,98,100,105,118,114,0,115,117,98,115,117, +114,102,116,121,112,101,0,42,109,114,0,42,112,118,0,42,116,112,97,103,101,0,117,118,91,52,93,91,50,93,0,99, +111,108,91,52,93,0,116,114,97,110,115,112,0,116,105,108,101,0,117,110,119,114,97,112,0,118,49,0,118,50,0,118, +51,0,118,52,0,101,100,99,111,100,101,0,99,114,101,97,115,101,0,98,119,101,105,103,104,116,0,100,101,102,95,110, +114,0,42,100,119,0,116,111,116,119,101,105,103,104,116,0,99,111,91,51,93,0,110,111,91,51,93,0,112,97,100,91, +51,93,0,117,118,91,50,93,0,99,111,91,50,93,0,105,110,100,101,120,0,102,0,105,0,115,91,50,53,54,93,0, +118,91,52,93,0,109,105,100,0,118,91,50,93,0,42,102,97,99,101,115,0,42,99,111,108,102,97,99,101,115,0,42, +101,100,103,101,115,0,42,101,100,103,101,95,98,111,117,110,100,97,114,121,95,115,116,97,116,101,115,0,42,118,101,114, +116,95,101,100,103,101,95,109,97,112,0,42,118,101,114,116,95,102,97,99,101,95,109,97,112,0,42,109,97,112,95,109, +101,109,0,42,118,101,114,116,115,0,108,101,118,101,108,115,0,108,101,118,101,108,95,99,111,117,110,116,0,99,117,114, +114,101,110,116,0,110,101,119,108,118,108,0,101,100,103,101,108,118,108,0,112,105,110,108,118,108,0,114,101,110,100,101, +114,108,118,108,0,117,115,101,95,99,111,108,0,42,101,100,103,101,95,102,108,97,103,115,0,42,101,100,103,101,95,99, +114,101,97,115,101,115,0,42,118,101,114,116,95,109,97,112,0,42,101,100,103,101,95,109,97,112,0,42,111,108,100,95, +102,97,99,101,115,0,42,111,108,100,95,101,100,103,101,115,0,42,101,114,114,111,114,0,109,111,100,105,102,105,101,114, +0,115,117,98,100,105,118,84,121,112,101,0,114,101,110,100,101,114,76,101,118,101,108,115,0,42,101,109,67,97,99,104, +101,0,42,109,67,97,99,104,101,0,100,101,102,97,120,105,115,0,112,97,100,91,54,93,0,108,101,110,103,116,104,0, +114,97,110,100,111,109,105,122,101,0,115,101,101,100,0,42,111,98,95,97,114,109,0,42,115,116,97,114,116,95,99,97, +112,0,42,101,110,100,95,99,97,112,0,42,99,117,114,118,101,95,111,98,0,42,111,102,102,115,101,116,95,111,98,0, +111,102,102,115,101,116,91,51,93,0,115,99,97,108,101,91,51,93,0,109,101,114,103,101,95,100,105,115,116,0,102,105, +116,95,116,121,112,101,0,111,102,102,115,101,116,95,116,121,112,101,0,99,111,117,110,116,0,97,120,105,115,0,116,111, +108,101,114,97,110,99,101,0,42,109,105,114,114,111,114,95,111,98,0,115,112,108,105,116,95,97,110,103,108,101,0,118, +97,108,117,101,0,114,101,115,0,118,97,108,95,102,108,97,103,115,0,108,105,109,95,102,108,97,103,115,0,101,95,102, +108,97,103,115,0,98,101,118,101,108,95,97,110,103,108,101,0,100,101,102,103,114,112,95,110,97,109,101,91,51,50,93, +0,42,116,101,120,116,117,114,101,0,115,116,114,101,110,103,116,104,0,100,105,114,101,99,116,105,111,110,0,109,105,100, +108,101,118,101,108,0,116,101,120,109,97,112,112,105,110,103,0,42,109,97,112,95,111,98,106,101,99,116,0,117,118,108, +97,121,101,114,95,110,97,109,101,91,51,50,93,0,117,118,108,97,121,101,114,95,116,109,112,0,42,112,114,111,106,101, +99,116,111,114,115,91,49,48,93,0,42,105,109,97,103,101,0,110,117,109,95,112,114,111,106,101,99,116,111,114,115,0, +97,115,112,101,99,116,120,0,97,115,112,101,99,116,121,0,112,101,114,99,101,110,116,0,102,97,99,101,67,111,117,110, +116,0,102,97,99,0,114,101,112,101,97,116,0,42,111,98,106,101,99,116,99,101,110,116,101,114,0,115,116,97,114,116, +120,0,115,116,97,114,116,121,0,104,101,105,103,104,116,0,110,97,114,114,111,119,0,115,112,101,101,100,0,100,97,109, +112,0,102,97,108,108,111,102,102,0,116,105,109,101,111,102,102,115,0,108,105,102,101,116,105,109,101,0,100,101,102,111, +114,109,102,108,97,103,0,109,117,108,116,105,0,42,112,114,101,118,67,111,115,0,112,97,114,101,110,116,105,110,118,91, +52,93,91,52,93,0,99,101,110,116,91,51,93,0,42,105,110,100,101,120,97,114,0,116,111,116,105,110,100,101,120,0, +102,111,114,99,101,0,42,99,108,111,116,104,79,98,106,101,99,116,0,42,115,105,109,95,112,97,114,109,115,0,42,99, +111,108,108,95,112,97,114,109,115,0,42,112,111,105,110,116,95,99,97,99,104,101,0,42,120,0,42,120,110,101,119,0, +42,120,111,108,100,0,42,99,117,114,114,101,110,116,95,120,110,101,119,0,42,99,117,114,114,101,110,116,95,120,0,42, +99,117,114,114,101,110,116,95,118,0,42,109,102,97,99,101,115,0,110,117,109,118,101,114,116,115,0,110,117,109,102,97, +99,101,115,0,97,98,115,111,114,112,116,105,111,110,0,116,105,109,101,0,42,98,118,104,116,114,101,101,0,42,100,109, +0,111,112,101,114,97,116,105,111,110,0,118,101,114,116,101,120,0,116,111,116,105,110,102,108,117,101,110,99,101,0,103, +114,105,100,115,105,122,101,0,110,101,101,100,98,105,110,100,0,42,98,105,110,100,119,101,105,103,104,116,115,0,42,98, +105,110,100,99,111,115,0,116,111,116,99,97,103,101,118,101,114,116,0,42,100,121,110,103,114,105,100,0,42,100,121,110, +105,110,102,108,117,101,110,99,101,115,0,42,100,121,110,118,101,114,116,115,0,42,112,97,100,50,0,100,121,110,103,114, +105,100,115,105,122,101,0,100,121,110,99,101,108,108,109,105,110,91,51,93,0,100,121,110,99,101,108,108,119,105,100,116, +104,0,98,105,110,100,109,97,116,91,52,93,91,52,93,0,42,112,115,121,115,0,116,111,116,100,109,118,101,114,116,0, +116,111,116,100,109,101,100,103,101,0,116,111,116,100,109,102,97,99,101,0,112,115,121,115,0,114,116,91,50,93,0,42, +102,97,99,101,112,97,0,118,103,114,111,117,112,0,112,114,111,116,101,99,116,0,42,102,115,115,0,42,116,97,114,103, +101,116,0,42,97,117,120,84,97,114,103,101,116,0,118,103,114,111,117,112,95,110,97,109,101,91,51,50,93,0,107,101, +101,112,68,105,115,116,0,115,104,114,105,110,107,84,121,112,101,0,115,104,114,105,110,107,79,112,116,115,0,112,114,111, +106,65,120,105,115,0,115,117,98,115,117,114,102,76,101,118,101,108,115,0,42,111,114,105,103,105,110,0,102,97,99,116, +111,114,0,108,105,109,105,116,91,50,93,0,111,114,105,103,105,110,79,112,116,115,0,112,110,116,115,119,0,111,112,110, +116,115,117,0,111,112,110,116,115,118,0,111,112,110,116,115,119,0,116,121,112,101,117,0,116,121,112,101,118,0,116,121, +112,101,119,0,102,117,0,102,118,0,102,119,0,100,117,0,100,118,0,100,119,0,42,100,101,102,0,118,101,99,91,56, +93,91,51,93,0,112,97,114,116,121,112,101,0,112,97,114,49,0,112,97,114,50,0,112,97,114,51,0,112,97,114,115, +117,98,115,116,114,91,51,50,93,0,42,116,114,97,99,107,0,42,112,114,111,120,121,0,42,112,114,111,120,121,95,103, +114,111,117,112,0,42,112,114,111,120,121,95,102,114,111,109,0,42,97,99,116,105,111,110,0,42,112,111,115,101,108,105, +98,0,42,112,111,115,101,0,99,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,115,0,100,101,102,98,97, +115,101,0,109,111,100,105,102,105,101,114,115,0,100,108,111,99,91,51,93,0,111,114,105,103,91,51,93,0,100,115,105, +122,101,91,51,93,0,100,114,111,116,91,51,93,0,111,98,109,97,116,91,52,93,91,52,93,0,99,111,110,115,116,105, +110,118,91,52,93,91,52,93,0,108,97,121,0,99,111,108,98,105,116,115,0,116,114,97,110,115,102,108,97,103,0,105, +112,111,102,108,97,103,0,116,114,97,99,107,102,108,97,103,0,117,112,102,108,97,103,0,110,108,97,102,108,97,103,0, +112,114,111,116,101,99,116,102,108,97,103,0,105,112,111,119,105,110,0,115,99,97,102,108,97,103,0,115,99,97,118,105, +115,102,108,97,103,0,98,111,117,110,100,116,121,112,101,0,100,117,112,111,110,0,100,117,112,111,102,102,0,100,117,112, +115,116,97,0,100,117,112,101,110,100,0,115,102,0,99,116,105,109,101,0,109,97,115,115,0,100,97,109,112,105,110,103, +0,105,110,101,114,116,105,97,0,102,111,114,109,102,97,99,116,111,114,0,114,100,97,109,112,105,110,103,0,115,105,122, +101,102,97,99,0,109,97,114,103,105,110,0,109,97,120,95,118,101,108,0,109,105,110,95,118,101,108,0,109,95,99,111, +110,116,97,99,116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,0,100,116,0,100,116,120,0, +97,99,116,99,111,108,0,101,109,112,116,121,95,100,114,97,119,116,121,112,101,0,112,97,100,49,91,51,93,0,101,109, +112,116,121,95,100,114,97,119,115,105,122,101,0,100,117,112,102,97,99,101,115,99,97,0,112,114,111,112,0,115,101,110, +115,111,114,115,0,99,111,110,116,114,111,108,108,101,114,115,0,97,99,116,117,97,116,111,114,115,0,98,98,115,105,122, +101,91,51,93,0,97,99,116,100,101,102,0,103,97,109,101,102,108,97,103,0,103,97,109,101,102,108,97,103,50,0,42, +98,115,111,102,116,0,115,111,102,116,102,108,97,103,0,97,110,105,115,111,116,114,111,112,105,99,70,114,105,99,116,105, +111,110,91,51,93,0,99,111,110,115,116,114,97,105,110,116,115,0,110,108,97,115,116,114,105,112,115,0,104,111,111,107, +115,0,112,97,114,116,105,99,108,101,115,121,115,116,101,109,0,42,112,100,0,42,115,111,102,116,0,42,100,117,112,95, +103,114,111,117,112,0,102,108,117,105,100,115,105,109,70,108,97,103,0,114,101,115,116,114,105,99,116,102,108,97,103,0, +115,104,97,112,101,110,114,0,115,104,97,112,101,102,108,97,103,0,114,101,99,97,108,99,111,0,98,111,100,121,95,116, +121,112,101,0,42,102,108,117,105,100,115,105,109,83,101,116,116,105,110,103,115,0,42,100,101,114,105,118,101,100,68,101, +102,111,114,109,0,42,100,101,114,105,118,101,100,70,105,110,97,108,0,108,97,115,116,68,97,116,97,77,97,115,107,0, +115,116,97,116,101,0,105,110,105,116,95,115,116,97,116,101,0,103,112,117,108,97,109,112,0,99,117,114,105,110,100,101, +120,0,97,99,116,105,118,101,0,100,101,102,108,101,99,116,0,102,111,114,99,101,102,105,101,108,100,0,112,100,101,102, +95,100,97,109,112,0,112,100,101,102,95,114,100,97,109,112,0,112,100,101,102,95,112,101,114,109,0,112,100,101,102,95, +102,114,105,99,116,0,112,100,101,102,95,114,102,114,105,99,116,0,102,95,115,116,114,101,110,103,116,104,0,102,95,112, +111,119,101,114,0,102,95,100,105,115,116,0,102,95,100,97,109,112,0,109,97,120,100,105,115,116,0,109,105,110,100,105, +115,116,0,109,97,120,114,97,100,0,109,105,110,114,97,100,0,102,95,112,111,119,101,114,95,114,0,112,100,101,102,95, +115,98,100,97,109,112,0,112,100,101,102,95,115,98,105,102,116,0,112,100,101,102,95,115,98,111,102,116,0,99,108,117, +109,112,95,102,97,99,0,99,108,117,109,112,95,112,111,119,0,107,105,110,107,95,102,114,101,113,0,107,105,110,107,95, +115,104,97,112,101,0,107,105,110,107,95,97,109,112,0,102,114,101,101,95,101,110,100,0,116,101,120,95,110,97,98,108, +97,0,116,101,120,95,109,111,100,101,0,107,105,110,107,0,107,105,110,107,95,97,120,105,115,0,114,116,50,0,42,114, +110,103,0,102,95,110,111,105,115,101,0,115,105,109,102,114,97,109,101,0,115,116,97,114,116,102,114,97,109,101,0,101, +110,100,102,114,97,109,101,0,101,100,105,116,102,114,97,109,101,0,108,105,110,83,116,105,102,102,0,97,110,103,83,116, +105,102,102,0,118,111,108,117,109,101,0,118,105,116,101,114,97,116,105,111,110,115,0,112,105,116,101,114,97,116,105,111, +110,115,0,100,105,116,101,114,97,116,105,111,110,115,0,99,105,116,101,114,97,116,105,111,110,115,0,107,83,82,72,82, +95,67,76,0,107,83,75,72,82,95,67,76,0,107,83,83,72,82,95,67,76,0,107,83,82,95,83,80,76,84,95,67, +76,0,107,83,75,95,83,80,76,84,95,67,76,0,107,83,83,95,83,80,76,84,95,67,76,0,107,86,67,70,0,107, +68,80,0,107,68,71,0,107,76,70,0,107,80,82,0,107,86,67,0,107,68,70,0,107,77,84,0,107,67,72,82,0, +107,75,72,82,0,107,83,72,82,0,107,65,72,82,0,99,111,108,108,105,115,105,111,110,102,108,97,103,115,0,110,117, +109,99,108,117,115,116,101,114,105,116,101,114,97,116,105,111,110,115,0,119,101,108,100,105,110,103,0,42,112,97,114,116, +105,99,108,101,115,0,116,111,116,112,111,105,110,116,0,116,111,116,115,112,114,105,110,103,0,42,98,112,111,105,110,116, +0,42,98,115,112,114,105,110,103,0,109,115,103,95,108,111,99,107,0,109,115,103,95,118,97,108,117,101,0,110,111,100, +101,109,97,115,115,0,110,97,109,101,100,86,71,95,77,97,115,115,91,51,50,93,0,103,114,97,118,0,109,101,100,105, +97,102,114,105,99,116,0,114,107,108,105,109,105,116,0,112,104,121,115,105,99,115,95,115,112,101,101,100,0,103,111,97, +108,115,112,114,105,110,103,0,103,111,97,108,102,114,105,99,116,0,109,105,110,103,111,97,108,0,109,97,120,103,111,97, +108,0,100,101,102,103,111,97,108,0,118,101,114,116,103,114,111,117,112,0,110,97,109,101,100,86,71,95,83,111,102,116, +103,111,97,108,91,51,50,93,0,102,117,122,122,121,110,101,115,115,0,105,110,115,112,114,105,110,103,0,105,110,102,114, +105,99,116,0,110,97,109,101,100,86,71,95,83,112,114,105,110,103,95,75,91,51,50,93,0,101,102,114,97,0,105,110, +116,101,114,118,97,108,0,108,111,99,97,108,0,115,111,108,118,101,114,102,108,97,103,115,0,42,42,107,101,121,115,0, +116,111,116,112,111,105,110,116,107,101,121,0,115,101,99,111,110,100,115,112,114,105,110,103,0,99,111,108,98,97,108,108, +0,98,97,108,108,100,97,109,112,0,98,97,108,108,115,116,105,102,102,0,115,98,99,95,109,111,100,101,0,97,101,114, +111,101,100,103,101,0,109,105,110,108,111,111,112,115,0,109,97,120,108,111,111,112,115,0,99,104,111,107,101,0,115,111, +108,118,101,114,95,73,68,0,112,108,97,115,116,105,99,0,115,112,114,105,110,103,112,114,101,108,111,97,100,0,42,115, +99,114,97,116,99,104,0,115,104,101,97,114,115,116,105,102,102,0,105,110,112,117,115,104,0,42,112,111,105,110,116,99, +97,99,104,101,0,115,104,111,119,95,97,100,118,97,110,99,101,100,111,112,116,105,111,110,115,0,114,101,115,111,108,117, +116,105,111,110,120,121,122,0,112,114,101,118,105,101,119,114,101,115,120,121,122,0,114,101,97,108,115,105,122,101,0,103, +117,105,68,105,115,112,108,97,121,77,111,100,101,0,114,101,110,100,101,114,68,105,115,112,108,97,121,77,111,100,101,0, +118,105,115,99,111,115,105,116,121,86,97,108,117,101,0,118,105,115,99,111,115,105,116,121,77,111,100,101,0,118,105,115, +99,111,115,105,116,121,69,120,112,111,110,101,110,116,0,103,114,97,118,120,0,103,114,97,118,121,0,103,114,97,118,122, +0,97,110,105,109,83,116,97,114,116,0,97,110,105,109,69,110,100,0,103,115,116,97,114,0,109,97,120,82,101,102,105, +110,101,0,105,110,105,86,101,108,120,0,105,110,105,86,101,108,121,0,105,110,105,86,101,108,122,0,42,111,114,103,77, +101,115,104,0,42,109,101,115,104,83,117,114,102,97,99,101,0,42,109,101,115,104,66,66,0,115,117,114,102,100,97,116, +97,80,97,116,104,91,50,52,48,93,0,98,98,83,116,97,114,116,91,51,93,0,98,98,83,105,122,101,91,51,93,0, +116,121,112,101,70,108,97,103,115,0,100,111,109,97,105,110,78,111,118,101,99,103,101,110,0,118,111,108,117,109,101,73, +110,105,116,84,121,112,101,0,112,97,114,116,83,108,105,112,86,97,108,117,101,0,103,101,110,101,114,97,116,101,84,114, +97,99,101,114,115,0,103,101,110,101,114,97,116,101,80,97,114,116,105,99,108,101,115,0,115,117,114,102,97,99,101,83, +109,111,111,116,104,105,110,103,0,115,117,114,102,97,99,101,83,117,98,100,105,118,115,0,112,97,114,116,105,99,108,101, +73,110,102,83,105,122,101,0,112,97,114,116,105,99,108,101,73,110,102,65,108,112,104,97,0,102,97,114,70,105,101,108, +100,83,105,122,101,0,42,109,101,115,104,83,117,114,102,78,111,114,109,97,108,115,0,99,112,115,84,105,109,101,83,116, +97,114,116,0,99,112,115,84,105,109,101,69,110,100,0,99,112,115,81,117,97,108,105,116,121,0,97,116,116,114,97,99, +116,102,111,114,99,101,83,116,114,101,110,103,116,104,0,97,116,116,114,97,99,116,102,111,114,99,101,82,97,100,105,117, +115,0,118,101,108,111,99,105,116,121,102,111,114,99,101,83,116,114,101,110,103,116,104,0,118,101,108,111,99,105,116,121, +102,111,114,99,101,82,97,100,105,117,115,0,108,97,115,116,103,111,111,100,102,114,97,109,101,0,109,105,115,116,121,112, +101,0,104,111,114,114,0,104,111,114,103,0,104,111,114,98,0,104,111,114,107,0,122,101,110,114,0,122,101,110,103,0, +122,101,110,98,0,122,101,110,107,0,97,109,98,107,0,102,97,115,116,99,111,108,0,101,120,112,111,115,117,114,101,0, +101,120,112,0,114,97,110,103,101,0,108,105,110,102,97,99,0,108,111,103,102,97,99,0,103,114,97,118,105,116,121,0, +97,99,116,105,118,105,116,121,66,111,120,82,97,100,105,117,115,0,115,107,121,116,121,112,101,0,111,99,99,108,117,115, +105,111,110,82,101,115,0,112,104,121,115,105,99,115,69,110,103,105,110,101,0,116,105,99,114,97,116,101,0,109,97,120, +108,111,103,105,99,115,116,101,112,0,112,104,121,115,117,98,115,116,101,112,0,109,97,120,112,104,121,115,116,101,112,0, +109,105,115,105,0,109,105,115,116,115,116,97,0,109,105,115,116,100,105,115,116,0,109,105,115,116,104,105,0,115,116,97, +114,114,0,115,116,97,114,103,0,115,116,97,114,98,0,115,116,97,114,107,0,115,116,97,114,115,105,122,101,0,115,116, +97,114,109,105,110,100,105,115,116,0,115,116,97,114,100,105,115,116,0,115,116,97,114,99,111,108,110,111,105,115,101,0, +100,111,102,115,116,97,0,100,111,102,101,110,100,0,100,111,102,109,105,110,0,100,111,102,109,97,120,0,97,111,100,105, +115,116,0,97,111,100,105,115,116,102,97,99,0,97,111,101,110,101,114,103,121,0,97,111,98,105,97,115,0,97,111,109, +111,100,101,0,97,111,115,97,109,112,0,97,111,109,105,120,0,97,111,99,111,108,111,114,0,97,111,95,97,100,97,112, +116,95,116,104,114,101,115,104,0,97,111,95,97,100,97,112,116,95,115,112,101,101,100,95,102,97,99,0,97,111,95,97, +112,112,114,111,120,95,101,114,114,111,114,0,97,111,95,97,112,112,114,111,120,95,99,111,114,114,101,99,116,105,111,110, +0,97,111,95,115,97,109,112,95,109,101,116,104,111,100,0,97,111,95,103,97,116,104,101,114,95,109,101,116,104,111,100, +0,97,111,95,97,112,112,114,111,120,95,112,97,115,115,101,115,0,42,97,111,115,112,104,101,114,101,0,42,97,111,116, +97,98,108,101,115,0,104,101,109,105,114,101,115,0,109,97,120,105,116,101,114,0,100,114,97,119,116,121,112,101,0,115, +117,98,115,104,111,111,116,112,0,115,117,98,115,104,111,111,116,101,0,110,111,100,101,108,105,109,0,109,97,120,115,117, +98,108,97,109,112,0,112,97,109,97,0,112,97,109,105,0,101,108,109,97,0,101,108,109,105,0,109,97,120,110,111,100, +101,0,99,111,110,118,101,114,103,101,110,99,101,0,114,97,100,102,97,99,0,103,97,109,109,97,0,115,101,108,99,111, +108,0,115,120,0,115,121,0,42,108,112,70,111,114,109,97,116,0,42,108,112,80,97,114,109,115,0,99,98,70,111,114, +109,97,116,0,99,98,80,97,114,109,115,0,102,99,99,84,121,112,101,0,102,99,99,72,97,110,100,108,101,114,0,100, +119,75,101,121,70,114,97,109,101,69,118,101,114,121,0,100,119,81,117,97,108,105,116,121,0,100,119,66,121,116,101,115, +80,101,114,83,101,99,111,110,100,0,100,119,70,108,97,103,115,0,100,119,73,110,116,101,114,108,101,97,118,101,69,118, +101,114,121,0,97,118,105,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,42,99,100,80,97,114,109,115,0,42, +112,97,100,0,99,100,83,105,122,101,0,113,116,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,99,111,100,101, +99,0,97,117,100,105,111,95,99,111,100,101,99,0,118,105,100,101,111,95,98,105,116,114,97,116,101,0,97,117,100,105, +111,95,98,105,116,114,97,116,101,0,103,111,112,95,115,105,122,101,0,114,99,95,109,105,110,95,114,97,116,101,0,114, +99,95,109,97,120,95,114,97,116,101,0,114,99,95,98,117,102,102,101,114,95,115,105,122,101,0,109,117,120,95,112,97, +99,107,101,116,95,115,105,122,101,0,109,117,120,95,114,97,116,101,0,109,105,120,114,97,116,101,0,109,97,105,110,0, +42,109,97,116,95,111,118,101,114,114,105,100,101,0,42,108,105,103,104,116,95,111,118,101,114,114,105,100,101,0,108,97, +121,95,122,109,97,115,107,0,108,97,121,102,108,97,103,0,112,97,115,115,102,108,97,103,0,112,97,115,115,95,120,111, +114,0,42,97,118,105,99,111,100,101,99,100,97,116,97,0,42,113,116,99,111,100,101,99,100,97,116,97,0,102,102,99, +111,100,101,99,100,97,116,97,0,99,102,114,97,0,112,115,102,114,97,0,112,101,102,114,97,0,105,109,97,103,101,115, +0,102,114,97,109,97,112,116,111,0,116,104,114,101,97,100,115,0,102,114,97,109,101,108,101,110,0,98,108,117,114,102, +97,99,0,101,100,103,101,82,0,101,100,103,101,71,0,101,100,103,101,66,0,102,117,108,108,115,99,114,101,101,110,0, +120,112,108,97,121,0,121,112,108,97,121,0,102,114,101,113,112,108,97,121,0,97,116,116,114,105,98,0,114,116,49,0, +115,116,101,114,101,111,109,111,100,101,0,100,105,109,101,110,115,105,111,110,115,112,114,101,115,101,116,0,109,97,120,105, +109,115,105,122,101,0,120,115,99,104,0,121,115,99,104,0,120,112,97,114,116,115,0,121,112,97,114,116,115,0,119,105, +110,112,111,115,0,112,108,97,110,101,115,0,105,109,116,121,112,101,0,115,117,98,105,109,116,121,112,101,0,113,117,97, +108,105,116,121,0,114,112,97,100,0,114,112,97,100,49,0,114,112,97,100,50,0,115,99,101,109,111,100,101,0,114,101, +110,100,101,114,101,114,0,111,99,114,101,115,0,97,108,112,104,97,109,111,100,101,0,111,115,97,0,102,114,115,95,115, +101,99,0,101,100,103,101,105,110,116,0,115,97,102,101,116,121,0,98,111,114,100,101,114,0,100,105,115,112,114,101,99, +116,0,108,97,121,101,114,115,0,97,99,116,108,97,121,0,120,97,115,112,0,121,97,115,112,0,102,114,115,95,115,101, +99,95,98,97,115,101,0,103,97,117,115,115,0,112,111,115,116,109,117,108,0,112,111,115,116,103,97,109,109,97,0,112, +111,115,116,104,117,101,0,112,111,115,116,115,97,116,0,100,105,116,104,101,114,95,105,110,116,101,110,115,105,116,121,0, +98,97,107,101,95,111,115,97,0,98,97,107,101,95,102,105,108,116,101,114,0,98,97,107,101,95,109,111,100,101,0,98, +97,107,101,95,102,108,97,103,0,98,97,107,101,95,110,111,114,109,97,108,95,115,112,97,99,101,0,98,97,107,101,95, +113,117,97,100,95,115,112,108,105,116,0,98,97,107,101,95,109,97,120,100,105,115,116,0,98,97,107,101,95,98,105,97, +115,100,105,115,116,0,98,97,107,101,95,112,97,100,0,71,73,113,117,97,108,105,116,121,0,71,73,99,97,99,104,101, +0,71,73,109,101,116,104,111,100,0,71,73,112,104,111,116,111,110,115,0,71,73,100,105,114,101,99,116,0,89,70,95, +65,65,0,89,70,101,120,112,111,114,116,120,109,108,0,89,70,95,110,111,98,117,109,112,0,89,70,95,99,108,97,109, +112,114,103,98,0,121,102,112,97,100,49,0,71,73,100,101,112,116,104,0,71,73,99,97,117,115,100,101,112,116,104,0, +71,73,112,105,120,101,108,115,112,101,114,115,97,109,112,108,101,0,71,73,112,104,111,116,111,110,99,111,117,110,116,0, +71,73,109,105,120,112,104,111,116,111,110,115,0,71,73,112,104,111,116,111,110,114,97,100,105,117,115,0,89,70,95,114, +97,121,100,101,112,116,104,0,89,70,95,65,65,112,97,115,115,101,115,0,89,70,95,65,65,115,97,109,112,108,101,115, +0,121,102,112,97,100,50,0,71,73,115,104,97,100,111,119,113,117,97,108,105,116,121,0,71,73,114,101,102,105,110,101, +109,101,110,116,0,71,73,112,111,119,101,114,0,71,73,105,110,100,105,114,112,111,119,101,114,0,89,70,95,103,97,109, +109,97,0,89,70,95,101,120,112,111,115,117,114,101,0,89,70,95,114,97,121,98,105,97,115,0,89,70,95,65,65,112, +105,120,101,108,115,105,122,101,0,89,70,95,65,65,116,104,114,101,115,104,111,108,100,0,98,97,99,107,98,117,102,91, +49,54,48,93,0,112,105,99,91,49,54,48,93,0,115,116,97,109,112,0,115,116,97,109,112,95,102,111,110,116,95,105, +100,0,115,116,97,109,112,95,117,100,97,116,97,91,49,54,48,93,0,102,103,95,115,116,97,109,112,91,52,93,0,98, +103,95,115,116,97,109,112,91,52,93,0,115,105,109,112,108,105,102,121,95,115,117,98,115,117,114,102,0,115,105,109,112, +108,105,102,121,95,115,104,97,100,111,119,115,97,109,112,108,101,115,0,115,105,109,112,108,105,102,121,95,112,97,114,116, +105,99,108,101,115,0,115,105,109,112,108,105,102,121,95,97,111,115,115,115,0,99,105,110,101,111,110,119,104,105,116,101, +0,99,105,110,101,111,110,98,108,97,99,107,0,99,105,110,101,111,110,103,97,109,109,97,0,106,112,50,95,112,114,101, +115,101,116,0,106,112,50,95,100,101,112,116,104,0,114,112,97,100,51,0,100,111,109,101,114,101,115,0,100,111,109,101, +109,111,100,101,0,100,111,109,101,97,110,103,108,101,0,100,111,109,101,116,105,108,116,0,100,111,109,101,114,101,115,98, +117,102,0,42,100,111,109,101,116,101,120,116,0,112,97,114,116,105,99,108,101,95,112,101,114,99,0,115,117,98,115,117, +114,102,95,109,97,120,0,115,104,97,100,98,117,102,115,97,109,112,108,101,95,109,97,120,0,97,111,95,101,114,114,111, +114,0,99,111,108,91,51,93,0,102,114,97,109,101,0,110,97,109,101,91,54,52,93,0,42,98,114,117,115,104,0,116, +111,111,108,0,115,101,97,109,95,98,108,101,101,100,0,110,111,114,109,97,108,95,97,110,103,108,101,0,115,116,101,112, +0,105,110,118,101,114,116,0,116,111,116,114,101,107,101,121,0,116,111,116,97,100,100,107,101,121,0,98,114,117,115,104, +116,121,112,101,0,98,114,117,115,104,91,55,93,0,101,109,105,116,116,101,114,100,105,115,116,0,100,114,97,119,95,116, +105,109,101,100,0,110,97,109,101,91,51,54,93,0,109,97,116,91,51,93,91,51,93,0,99,111,114,110,101,114,116,121, +112,101,0,101,100,105,116,98,117,116,102,108,97,103,0,106,111,105,110,116,114,105,108,105,109,105,116,0,100,101,103,114, +0,116,117,114,110,0,101,120,116,114,95,111,102,102,115,0,100,111,117,98,108,105,109,105,116,0,115,101,103,109,101,110, +116,115,0,114,105,110,103,115,0,118,101,114,116,105,99,101,115,0,117,110,119,114,97,112,112,101,114,0,117,118,99,97, +108,99,95,114,97,100,105,117,115,0,117,118,99,97,108,99,95,99,117,98,101,115,105,122,101,0,117,118,99,97,108,99, +95,109,97,114,103,105,110,0,117,118,99,97,108,99,95,109,97,112,100,105,114,0,117,118,99,97,108,99,95,109,97,112, +97,108,105,103,110,0,117,118,99,97,108,99,95,102,108,97,103,0,97,117,116,111,105,107,95,99,104,97,105,110,108,101, +110,0,105,109,97,112,97,105,110,116,0,112,97,114,116,105,99,108,101,0,115,101,108,101,99,116,95,116,104,114,101,115, +104,0,99,108,101,97,110,95,116,104,114,101,115,104,0,114,101,116,111,112,111,95,109,111,100,101,0,114,101,116,111,112, +111,95,112,97,105,110,116,95,116,111,111,108,0,108,105,110,101,95,100,105,118,0,101,108,108,105,112,115,101,95,100,105, +118,0,114,101,116,111,112,111,95,104,111,116,115,112,111,116,0,109,117,108,116,105,114,101,115,95,115,117,98,100,105,118, +95,116,121,112,101,0,115,107,103,101,110,95,114,101,115,111,108,117,116,105,111,110,0,115,107,103,101,110,95,116,104,114, +101,115,104,111,108,100,95,105,110,116,101,114,110,97,108,0,115,107,103,101,110,95,116,104,114,101,115,104,111,108,100,95, +101,120,116,101,114,110,97,108,0,115,107,103,101,110,95,108,101,110,103,116,104,95,114,97,116,105,111,0,115,107,103,101, +110,95,108,101,110,103,116,104,95,108,105,109,105,116,0,115,107,103,101,110,95,97,110,103,108,101,95,108,105,109,105,116, +0,115,107,103,101,110,95,99,111,114,114,101,108,97,116,105,111,110,95,108,105,109,105,116,0,115,107,103,101,110,95,115, +121,109,109,101,116,114,121,95,108,105,109,105,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,97,110,103, +108,101,95,119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,108,101,110,103,116,104,95, +119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,100,105,115,116,97,110,99,101,95,119, +101,105,103,104,116,0,115,107,103,101,110,95,111,112,116,105,111,110,115,0,115,107,103,101,110,95,112,111,115,116,112,114, +111,0,115,107,103,101,110,95,112,111,115,116,112,114,111,95,112,97,115,115,101,115,0,115,107,103,101,110,95,115,117,98, +100,105,118,105,115,105,111,110,115,91,51,93,0,115,107,103,101,110,95,109,117,108,116,105,95,108,101,118,101,108,0,42, +115,107,103,101,110,95,116,101,109,112,108,97,116,101,0,98,111,110,101,95,115,107,101,116,99,104,105,110,103,0,98,111, +110,101,95,115,107,101,116,99,104,105,110,103,95,99,111,110,118,101,114,116,0,115,107,103,101,110,95,115,117,98,100,105, +118,105,115,105,111,110,95,110,117,109,98,101,114,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,111,112,116, +105,111,110,115,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,114,111,108,108,0,115,107,103,101,110,95,115, +105,100,101,95,115,116,114,105,110,103,91,56,93,0,115,107,103,101,110,95,110,117,109,95,115,116,114,105,110,103,91,56, +93,0,101,100,103,101,95,109,111,100,101,0,112,97,100,51,91,50,93,0,100,105,114,0,118,105,101,119,0,42,115,101, +115,115,105,111,110,0,42,99,117,109,97,112,0,100,114,97,119,98,114,117,115,104,0,115,109,111,111,116,104,98,114,117, +115,104,0,112,105,110,99,104,98,114,117,115,104,0,105,110,102,108,97,116,101,98,114,117,115,104,0,103,114,97,98,98, +114,117,115,104,0,108,97,121,101,114,98,114,117,115,104,0,102,108,97,116,116,101,110,98,114,117,115,104,0,112,105,118, +111,116,91,51,93,0,98,114,117,115,104,95,116,121,112,101,0,116,101,120,110,114,0,116,101,120,114,101,112,116,0,116, +101,120,102,97,100,101,0,116,101,120,115,101,112,0,97,118,101,114,97,103,105,110,103,0,116,97,98,108,101,116,95,115, +105,122,101,0,116,97,98,108,101,116,95,115,116,114,101,110,103,116,104,0,115,121,109,109,0,114,97,107,101,0,97,120, +105,115,108,111,99,107,0,42,99,97,109,101,114,97,0,42,119,111,114,108,100,0,42,115,101,116,0,98,97,115,101,0, +42,98,97,115,97,99,116,0,99,117,114,115,111,114,91,51,93,0,116,119,99,101,110,116,91,51,93,0,116,119,109,105, +110,91,51,93,0,116,119,109,97,120,91,51,93,0,101,100,105,116,98,117,116,115,105,122,101,0,115,101,108,101,99,116, +109,111,100,101,0,112,114,111,112,111,114,116,105,111,110,97,108,0,112,114,111,112,95,109,111,100,101,0,97,117,116,111, +109,101,114,103,101,0,112,97,100,53,0,112,97,100,54,0,97,117,116,111,107,101,121,95,109,111,100,101,0,42,101,100, +0,42,114,97,100,105,111,0,102,114,97,109,105,110,103,0,42,116,111,111,108,115,101,116,116,105,110,103,115,0,97,117, +100,105,111,0,116,114,97,110,115,102,111,114,109,95,115,112,97,99,101,115,0,106,117,109,112,102,114,97,109,101,0,115, +110,97,112,95,109,111,100,101,0,115,110,97,112,95,102,108,97,103,0,115,110,97,112,95,116,97,114,103,101,116,0,42, +116,104,101,68,97,103,0,100,97,103,105,115,118,97,108,105,100,0,100,97,103,102,108,97,103,115,0,115,99,117,108,112, +116,100,97,116,97,0,102,114,97,109,101,95,115,116,101,112,0,122,111,111,109,0,98,108,101,110,100,0,120,105,109,0, +121,105,109,0,115,112,97,99,101,116,121,112,101,0,98,108,111,99,107,115,99,97,108,101,0,42,97,114,101,97,0,98, +108,111,99,107,104,97,110,100,108,101,114,91,56,93,0,118,105,101,119,109,97,116,91,52,93,91,52,93,0,118,105,101, +119,105,110,118,91,52,93,91,52,93,0,112,101,114,115,109,97,116,91,52,93,91,52,93,0,112,101,114,115,105,110,118, +91,52,93,91,52,93,0,119,105,110,109,97,116,49,91,52,93,91,52,93,0,118,105,101,119,109,97,116,49,91,52,93, +91,52,93,0,118,105,101,119,113,117,97,116,91,52,93,0,122,102,97,99,0,108,97,121,95,117,115,101,100,0,112,101, +114,115,112,0,42,111,98,95,99,101,110,116,114,101,0,42,98,103,112,105,99,0,42,108,111,99,97,108,118,100,0,42, +114,105,0,42,114,101,116,111,112,111,95,118,105,101,119,95,100,97,116,97,0,42,100,101,112,116,104,115,0,111,98,95, +99,101,110,116,114,101,95,98,111,110,101,91,51,50,93,0,108,111,99,97,108,118,105,101,119,0,108,97,121,97,99,116, +0,115,99,101,110,101,108,111,99,107,0,97,114,111,117,110,100,0,99,97,109,122,111,111,109,0,112,105,118,111,116,95, +108,97,115,116,0,103,114,105,100,0,103,114,105,100,118,105,101,119,0,112,105,120,115,105,122,101,0,110,101,97,114,0, +102,97,114,0,99,97,109,100,120,0,99,97,109,100,121,0,103,114,105,100,108,105,110,101,115,0,118,105,101,119,98,117, +116,0,103,114,105,100,102,108,97,103,0,109,111,100,101,115,101,108,101,99,116,0,116,119,116,121,112,101,0,116,119,109, +111,100,101,0,116,119,102,108,97,103,0,116,119,100,114,97,119,102,108,97,103,0,116,119,109,97,116,91,52,93,91,52, +93,0,99,108,105,112,91,52,93,91,52,93,0,42,99,108,105,112,98,98,0,97,102,116,101,114,100,114,97,119,0,122, +98,117,102,0,120,114,97,121,0,102,108,97,103,50,0,103,114,105,100,115,117,98,100,105,118,0,107,101,121,102,108,97, +103,115,0,110,100,111,102,109,111,100,101,0,110,100,111,102,102,105,108,116,101,114,0,42,112,114,111,112,101,114,116,105, +101,115,95,115,116,111,114,97,103,101,0,42,103,112,100,0,108,118,105,101,119,113,117,97,116,91,52,93,0,108,112,101, +114,115,112,0,108,118,105,101,119,0,118,101,114,116,0,104,111,114,0,109,97,115,107,0,109,105,110,91,50,93,0,109, +97,120,91,50,93,0,109,105,110,122,111,111,109,0,109,97,120,122,111,111,109,0,115,99,114,111,108,108,0,107,101,101, +112,116,111,116,0,107,101,101,112,97,115,112,101,99,116,0,107,101,101,112,122,111,111,109,0,111,108,100,119,105,110,120, +0,111,108,100,119,105,110,121,0,99,117,114,115,111,114,91,50,93,0,114,111,119,98,117,116,0,118,50,100,0,42,101, +100,105,116,105,112,111,0,105,112,111,107,101,121,0,97,99,116,110,97,109,101,91,51,50,93,0,99,111,110,115,116,110, +97,109,101,91,51,50,93,0,98,111,110,101,110,97,109,101,91,51,50,93,0,116,111,116,105,112,111,0,112,105,110,0, +98,117,116,111,102,115,0,99,104,97,110,110,101,108,0,108,111,99,107,0,109,101,100,105,97,110,91,51,93,0,99,117, +114,115,101,110,115,0,99,117,114,97,99,116,0,97,108,105,103,110,0,116,97,98,111,0,109,97,105,110,98,0,109,97, +105,110,98,111,0,42,108,111,99,107,112,111,105,110,0,116,101,120,102,114,111,109,0,115,104,111,119,103,114,111,117,112, +0,109,111,100,101,108,116,121,112,101,0,115,99,114,105,112,116,98,108,111,99,107,0,114,101,95,97,108,105,103,110,0, +111,108,100,107,101,121,112,114,101,115,115,0,116,97,98,91,55,93,0,114,101,110,100,101,114,95,115,105,122,101,0,99, +104,97,110,115,104,111,119,110,0,122,101,98,114,97,0,42,102,105,108,101,108,105,115,116,0,116,111,116,102,105,108,101, +0,116,105,116,108,101,91,50,52,93,0,100,105,114,91,50,52,48,93,0,102,105,108,101,91,56,48,93,0,111,102,115, +0,115,111,114,116,0,109,97,120,110,97,109,101,108,101,110,0,99,111,108,108,117,109,115,0,102,95,102,112,0,102,112, +95,115,116,114,91,56,93,0,42,108,105,98,102,105,108,101,100,97,116,97,0,114,101,116,118,97,108,0,109,101,110,117, +0,97,99,116,0,40,42,114,101,116,117,114,110,102,117,110,99,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110, +99,95,101,118,101,110,116,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110,99,95,97,114,103,115,41,40,41,0, +42,97,114,103,49,0,42,97,114,103,50,0,42,109,101,110,117,112,0,42,112,117,112,109,101,110,117,0,111,111,112,115, +0,118,105,115,105,102,108,97,103,0,116,114,101,101,0,42,116,114,101,101,115,116,111,114,101,0,115,101,97,114,99,104, +95,115,116,114,105,110,103,91,51,50,93,0,115,101,97,114,99,104,95,116,115,101,0,115,101,97,114,99,104,95,102,108, +97,103,115,0,100,111,95,0,111,117,116,108,105,110,101,118,105,115,0,115,116,111,114,101,102,108,97,103,0,100,101,112, +115,95,102,108,97,103,115,0,105,109,97,110,114,0,99,117,114,116,105,108,101,0,105,109,116,121,112,101,110,114,0,100, +116,95,117,118,0,115,116,105,99,107,121,0,100,116,95,117,118,115,116,114,101,116,99,104,0,112,97,100,91,53,93,0, +99,101,110,116,120,0,99,101,110,116,121,0,97,117,116,111,115,110,97,112,0,42,116,101,120,116,0,116,111,112,0,118, +105,101,119,108,105,110,101,115,0,102,111,110,116,95,105,100,0,108,104,101,105,103,104,116,0,108,101,102,116,0,115,104, +111,119,108,105,110,101,110,114,115,0,116,97,98,110,117,109,98,101,114,0,99,117,114,114,116,97,98,95,115,101,116,0, +115,104,111,119,115,121,110,116,97,120,0,111,118,101,114,119,114,105,116,101,0,112,105,120,95,112,101,114,95,108,105,110, +101,0,116,120,116,115,99,114,111,108,108,0,116,120,116,98,97,114,0,119,111,114,100,119,114,97,112,0,100,111,112,108, +117,103,105,110,115,0,42,112,121,95,100,114,97,119,0,42,112,121,95,101,118,101,110,116,0,42,112,121,95,98,117,116, +116,111,110,0,42,112,121,95,98,114,111,119,115,101,114,99,97,108,108,98,97,99,107,0,42,112,121,95,103,108,111,98, +97,108,100,105,99,116,0,108,97,115,116,115,112,97,99,101,0,115,99,114,105,112,116,110,97,109,101,91,50,53,54,93, +0,115,99,114,105,112,116,97,114,103,91,50,53,54,93,0,42,115,99,114,105,112,116,0,42,98,117,116,95,114,101,102, +115,0,114,101,100,114,97,119,115,0,42,105,100,0,97,115,112,101,99,116,0,42,99,117,114,102,111,110,116,0,42,101, +100,105,116,116,114,101,101,0,116,114,101,101,116,121,112,101,0,42,102,105,108,101,115,0,97,99,116,105,118,101,95,102, +105,108,101,0,110,117,109,116,105,108,101,115,120,0,110,117,109,116,105,108,101,115,121,0,115,101,108,115,116,97,116,101, +0,118,105,101,119,114,101,99,116,0,98,111,111,107,109,97,114,107,114,101,99,116,0,115,99,114,111,108,108,112,111,115, +0,115,99,114,111,108,108,104,101,105,103,104,116,0,115,99,114,111,108,108,97,114,101,97,0,97,99,116,105,118,101,95, +98,111,111,107,109,97,114,107,0,112,114,118,95,119,0,112,114,118,95,104,0,42,105,109,103,0,111,117,116,108,105,110, +101,91,52,93,0,110,101,117,116,114,97,108,91,52,93,0,97,99,116,105,111,110,91,52,93,0,115,101,116,116,105,110, +103,91,52,93,0,115,101,116,116,105,110,103,49,91,52,93,0,115,101,116,116,105,110,103,50,91,52,93,0,110,117,109, +91,52,93,0,116,101,120,116,102,105,101,108,100,91,52,93,0,116,101,120,116,102,105,101,108,100,95,104,105,91,52,93, +0,112,111,112,117,112,91,52,93,0,116,101,120,116,91,52,93,0,116,101,120,116,95,104,105,91,52,93,0,109,101,110, +117,95,98,97,99,107,91,52,93,0,109,101,110,117,95,105,116,101,109,91,52,93,0,109,101,110,117,95,104,105,108,105, +116,101,91,52,93,0,109,101,110,117,95,116,101,120,116,91,52,93,0,109,101,110,117,95,116,101,120,116,95,104,105,91, +52,93,0,98,117,116,95,100,114,97,119,116,121,112,101,0,105,99,111,110,102,105,108,101,91,56,48,93,0,98,97,99, +107,91,52,93,0,104,101,97,100,101,114,91,52,93,0,112,97,110,101,108,91,52,93,0,115,104,97,100,101,49,91,52, +93,0,115,104,97,100,101,50,91,52,93,0,104,105,108,105,116,101,91,52,93,0,103,114,105,100,91,52,93,0,119,105, +114,101,91,52,93,0,115,101,108,101,99,116,91,52,93,0,108,97,109,112,91,52,93,0,97,99,116,105,118,101,91,52, +93,0,103,114,111,117,112,91,52,93,0,103,114,111,117,112,95,97,99,116,105,118,101,91,52,93,0,116,114,97,110,115, +102,111,114,109,91,52,93,0,118,101,114,116,101,120,91,52,93,0,118,101,114,116,101,120,95,115,101,108,101,99,116,91, +52,93,0,101,100,103,101,91,52,93,0,101,100,103,101,95,115,101,108,101,99,116,91,52,93,0,101,100,103,101,95,115, +101,97,109,91,52,93,0,101,100,103,101,95,115,104,97,114,112,91,52,93,0,101,100,103,101,95,102,97,99,101,115,101, +108,91,52,93,0,102,97,99,101,91,52,93,0,102,97,99,101,95,115,101,108,101,99,116,91,52,93,0,102,97,99,101, +95,100,111,116,91,52,93,0,110,111,114,109,97,108,91,52,93,0,98,111,110,101,95,115,111,108,105,100,91,52,93,0, +98,111,110,101,95,112,111,115,101,91,52,93,0,115,116,114,105,112,91,52,93,0,115,116,114,105,112,95,115,101,108,101, +99,116,91,52,93,0,99,102,114,97,109,101,91,52,93,0,118,101,114,116,101,120,95,115,105,122,101,0,102,97,99,101, +100,111,116,95,115,105,122,101,0,98,112,97,100,91,50,93,0,115,121,110,116,97,120,108,91,52,93,0,115,121,110,116, +97,120,110,91,52,93,0,115,121,110,116,97,120,98,91,52,93,0,115,121,110,116,97,120,118,91,52,93,0,115,121,110, +116,97,120,99,91,52,93,0,109,111,118,105,101,91,52,93,0,105,109,97,103,101,91,52,93,0,115,99,101,110,101,91, +52,93,0,97,117,100,105,111,91,52,93,0,101,102,102,101,99,116,91,52,93,0,112,108,117,103,105,110,91,52,93,0, +116,114,97,110,115,105,116,105,111,110,91,52,93,0,109,101,116,97,91,52,93,0,101,100,105,116,109,101,115,104,95,97, +99,116,105,118,101,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,91,52,93,0,104,97,110,100,108,101, +95,118,101,114,116,101,120,95,115,101,108,101,99,116,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,95, +115,105,122,101,0,104,112,97,100,91,55,93,0,115,111,108,105,100,91,52,93,0,116,117,105,0,116,98,117,116,115,0, +116,118,51,100,0,116,102,105,108,101,0,116,105,112,111,0,116,105,110,102,111,0,116,115,110,100,0,116,97,99,116,0, +116,110,108,97,0,116,115,101,113,0,116,105,109,97,0,116,105,109,97,115,101,108,0,116,101,120,116,0,116,111,111,112, +115,0,116,116,105,109,101,0,116,110,111,100,101,0,116,97,114,109,91,50,48,93,0,98,112,97,100,91,52,93,0,98, +112,97,100,49,91,52,93,0,115,112,101,99,91,52,93,0,100,117,112,102,108,97,103,0,115,97,118,101,116,105,109,101, +0,116,101,109,112,100,105,114,91,49,54,48,93,0,102,111,110,116,100,105,114,91,49,54,48,93,0,114,101,110,100,101, +114,100,105,114,91,49,54,48,93,0,116,101,120,116,117,100,105,114,91,49,54,48,93,0,112,108,117,103,116,101,120,100, +105,114,91,49,54,48,93,0,112,108,117,103,115,101,113,100,105,114,91,49,54,48,93,0,112,121,116,104,111,110,100,105, +114,91,49,54,48,93,0,115,111,117,110,100,100,105,114,91,49,54,48,93,0,121,102,101,120,112,111,114,116,100,105,114, +91,49,54,48,93,0,118,101,114,115,105,111,110,115,0,118,114,109,108,102,108,97,103,0,103,97,109,101,102,108,97,103, +115,0,119,104,101,101,108,108,105,110,101,115,99,114,111,108,108,0,117,105,102,108,97,103,0,108,97,110,103,117,97,103, +101,0,117,115,101,114,112,114,101,102,0,118,105,101,119,122,111,111,109,0,99,111,110,115,111,108,101,95,98,117,102,102, +101,114,0,99,111,110,115,111,108,101,95,111,117,116,0,109,105,120,98,117,102,115,105,122,101,0,102,111,110,116,115,105, +122,101,0,101,110,99,111,100,105,110,103,0,116,114,97,110,115,111,112,116,115,0,109,101,110,117,116,104,114,101,115,104, +111,108,100,49,0,109,101,110,117,116,104,114,101,115,104,111,108,100,50,0,102,111,110,116,110,97,109,101,91,50,53,54, +93,0,116,104,101,109,101,115,0,117,110,100,111,115,116,101,112,115,0,117,110,100,111,109,101,109,111,114,121,0,103,112, +95,109,97,110,104,97,116,116,101,110,100,105,115,116,0,103,112,95,101,117,99,108,105,100,101,97,110,100,105,115,116,0, +103,112,95,101,114,97,115,101,114,0,103,112,95,115,101,116,116,105,110,103,115,0,116,98,95,108,101,102,116,109,111,117, +115,101,0,116,98,95,114,105,103,104,116,109,111,117,115,101,0,108,105,103,104,116,91,51,93,0,116,119,95,104,111,116, +115,112,111,116,0,116,119,95,102,108,97,103,0,116,119,95,104,97,110,100,108,101,115,105,122,101,0,116,119,95,115,105, +122,101,0,116,101,120,116,105,109,101,111,117,116,0,116,101,120,99,111,108,108,101,99,116,114,97,116,101,0,109,101,109, +99,97,99,104,101,108,105,109,105,116,0,112,114,101,102,101,116,99,104,102,114,97,109,101,115,0,102,114,97,109,101,115, +101,114,118,101,114,112,111,114,116,0,112,97,100,95,114,111,116,95,97,110,103,108,101,0,111,98,99,101,110,116,101,114, +95,100,105,97,0,114,118,105,115,105,122,101,0,114,118,105,98,114,105,103,104,116,0,114,101,99,101,110,116,95,102,105, +108,101,115,0,115,109,111,111,116,104,95,118,105,101,119,116,120,0,103,108,114,101,115,108,105,109,105,116,0,110,100,111, +102,95,112,97,110,0,110,100,111,102,95,114,111,116,97,116,101,0,99,117,114,115,115,105,122,101,0,112,97,100,91,56, +93,0,118,101,114,115,101,109,97,115,116,101,114,91,49,54,48,93,0,118,101,114,115,101,117,115,101,114,91,49,54,48, +93,0,103,108,97,108,112,104,97,99,108,105,112,0,97,117,116,111,107,101,121,95,102,108,97,103,0,99,111,98,97,95, +119,101,105,103,104,116,0,118,101,114,116,98,97,115,101,0,101,100,103,101,98,97,115,101,0,97,114,101,97,98,97,115, +101,0,42,115,99,101,110,101,0,101,110,100,120,0,101,110,100,121,0,115,105,122,101,120,0,115,105,122,101,121,0,115, +99,101,110,101,110,114,0,115,99,114,101,101,110,110,114,0,102,117,108,108,0,109,97,105,110,119,105,110,0,119,105,110, +97,107,116,0,104,97,110,100,108,101,114,91,56,93,0,42,110,101,119,118,0,118,101,99,0,42,118,49,0,42,118,50, +0,112,97,110,101,108,110,97,109,101,91,54,52,93,0,116,97,98,110,97,109,101,91,54,52,93,0,100,114,97,119,110, +97,109,101,91,54,52,93,0,111,102,115,120,0,111,102,115,121,0,99,111,110,116,114,111,108,0,115,110,97,112,0,111, +108,100,95,111,102,115,120,0,111,108,100,95,111,102,115,121,0,115,111,114,116,99,111,117,110,116,101,114,0,42,112,97, +110,101,108,116,97,98,0,42,118,51,0,42,118,52,0,42,102,117,108,108,0,119,105,110,109,97,116,91,52,93,91,52, +93,0,104,101,97,100,114,99,116,0,119,105,110,114,99,116,0,104,101,97,100,119,105,110,0,119,105,110,0,104,101,97, +100,101,114,116,121,112,101,0,98,117,116,115,112,97,99,101,116,121,112,101,0,119,105,110,120,0,119,105,110,121,0,104, +101,97,100,95,115,119,97,112,0,104,101,97,100,95,101,113,117,97,108,0,119,105,110,95,115,119,97,112,0,119,105,110, +95,101,113,117,97,108,0,104,101,97,100,98,117,116,108,101,110,0,104,101,97,100,98,117,116,111,102,115,0,99,117,114, +115,111,114,0,115,112,97,99,101,100,97,116,97,0,117,105,98,108,111,99,107,115,0,112,97,110,101,108,115,0,115,117, +98,118,115,116,114,91,52,93,0,115,117,98,118,101,114,115,105,111,110,0,112,97,100,115,0,109,105,110,118,101,114,115, +105,111,110,0,109,105,110,115,117,98,118,101,114,115,105,111,110,0,100,105,115,112,108,97,121,109,111,100,101,0,42,99, +117,114,115,99,114,101,101,110,0,42,99,117,114,115,99,101,110,101,0,102,105,108,101,102,108,97,103,115,0,103,108,111, +98,97,108,102,0,110,97,109,101,91,56,48,93,0,42,105,98,117,102,0,42,105,98,117,102,95,99,111,109,112,0,42, +115,101,49,0,42,115,101,50,0,42,115,101,51,0,110,114,0,98,111,116,116,111,109,0,114,105,103,104,116,0,120,111, +102,115,0,121,111,102,115,0,108,105,102,116,91,51,93,0,103,97,109,109,97,91,51,93,0,103,97,105,110,91,51,93, +0,115,97,116,117,114,97,116,105,111,110,0,42,103,117,105,0,100,105,114,91,49,54,48,93,0,100,111,110,101,0,115, +116,97,114,116,115,116,105,108,108,0,101,110,100,115,116,105,108,108,0,42,115,116,114,105,112,100,97,116,97,0,111,114, +120,0,111,114,121,0,42,99,114,111,112,0,42,116,114,97,110,115,102,111,114,109,0,42,99,111,108,111,114,95,98,97, +108,97,110,99,101,0,42,116,115,116,114,105,112,100,97,116,97,0,42,116,115,116,114,105,112,100,97,116,97,95,115,116, +97,114,116,115,116,105,108,108,0,42,116,115,116,114,105,112,100,97,116,97,95,101,110,100,115,116,105,108,108,0,42,105, +98,117,102,95,115,116,97,114,116,115,116,105,108,108,0,42,105,98,117,102,95,101,110,100,115,116,105,108,108,0,42,105, +110,115,116,97,110,99,101,95,112,114,105,118,97,116,101,95,100,97,116,97,0,42,42,99,117,114,114,101,110,116,95,112, +114,105,118,97,116,101,95,100,97,116,97,0,42,116,109,112,0,115,116,97,114,116,111,102,115,0,101,110,100,111,102,115, +0,109,97,99,104,105,110,101,0,115,116,97,114,116,100,105,115,112,0,101,110,100,100,105,115,112,0,109,117,108,0,104, +97,110,100,115,105,122,101,0,97,110,105,109,95,112,114,101,115,101,101,107,0,42,115,116,114,105,112,0,102,97,99,102, +48,0,102,97,99,102,49,0,42,115,101,113,49,0,42,115,101,113,50,0,42,115,101,113,51,0,115,101,113,98,97,115, +101,0,42,115,111,117,110,100,0,42,104,100,97,117,100,105,111,0,108,101,118,101,108,0,112,97,110,0,115,116,114,111, +98,101,0,42,101,102,102,101,99,116,100,97,116,97,0,97,110,105,109,95,115,116,97,114,116,111,102,115,0,97,110,105, +109,95,101,110,100,111,102,115,0,98,108,101,110,100,95,109,111,100,101,0,98,108,101,110,100,95,111,112,97,99,105,116, +121,0,42,111,108,100,98,97,115,101,112,0,42,112,97,114,115,101,113,0,42,115,101,113,98,97,115,101,112,0,109,101, +116,97,115,116,97,99,107,0,101,100,103,101,87,105,100,116,104,0,102,111,114,119,97,114,100,0,119,105,112,101,116,121, +112,101,0,102,77,105,110,105,0,102,67,108,97,109,112,0,102,66,111,111,115,116,0,100,68,105,115,116,0,100,81,117, +97,108,105,116,121,0,98,78,111,67,111,109,112,0,83,99,97,108,101,120,73,110,105,0,83,99,97,108,101,121,73,110, +105,0,83,99,97,108,101,120,70,105,110,0,83,99,97,108,101,121,70,105,110,0,120,73,110,105,0,120,70,105,110,0, +121,73,110,105,0,121,70,105,110,0,114,111,116,73,110,105,0,114,111,116,70,105,110,0,105,110,116,101,114,112,111,108, +97,116,105,111,110,0,42,102,114,97,109,101,77,97,112,0,103,108,111,98,97,108,83,112,101,101,100,0,108,97,115,116, +86,97,108,105,100,70,114,97,109,101,0,98,108,101,110,100,70,114,97,109,101,115,0,98,117,116,116,121,112,101,0,117, +115,101,114,106,105,116,0,115,116,97,0,116,111,116,112,97,114,116,0,110,111,114,109,102,97,99,0,111,98,102,97,99, +0,114,97,110,100,102,97,99,0,116,101,120,102,97,99,0,114,97,110,100,108,105,102,101,0,102,111,114,99,101,91,51, +93,0,118,101,99,116,115,105,122,101,0,109,97,120,108,101,110,0,100,101,102,118,101,99,91,51,93,0,109,117,108,116, +91,52,93,0,108,105,102,101,91,52,93,0,99,104,105,108,100,91,52,93,0,109,97,116,91,52,93,0,116,101,120,109, +97,112,0,99,117,114,109,117,108,116,0,115,116,97,116,105,99,115,116,101,112,0,111,109,97,116,0,116,105,109,101,116, +101,120,0,115,112,101,101,100,116,101,120,0,102,108,97,103,50,110,101,103,0,118,101,114,116,103,114,111,117,112,95,118, +0,118,103,114,111,117,112,110,97,109,101,91,51,50,93,0,118,103,114,111,117,112,110,97,109,101,95,118,91,51,50,93, +0,42,107,101,121,115,0,109,105,110,102,97,99,0,117,115,101,100,0,117,115,101,100,101,108,101,109,0,100,120,0,100, +121,0,108,105,110,107,0,111,116,121,112,101,0,111,108,100,0,42,112,111,105,110,0,42,111,108,100,112,111,105,110,0, +114,101,115,101,116,100,105,115,116,0,108,97,115,116,118,97,108,0,42,109,97,0,107,101,121,0,113,117,97,108,0,113, +117,97,108,50,0,116,97,114,103,101,116,78,97,109,101,91,51,50,93,0,116,111,103,103,108,101,78,97,109,101,91,51, +50,93,0,118,97,108,117,101,91,51,50,93,0,109,97,120,118,97,108,117,101,91,51,50,93,0,100,101,108,97,121,0, +100,117,114,97,116,105,111,110,0,109,97,116,101,114,105,97,108,78,97,109,101,91,51,50,93,0,100,97,109,112,116,105, +109,101,114,0,112,114,111,112,110,97,109,101,91,51,50,93,0,109,97,116,110,97,109,101,91,51,50,93,0,97,120,105, +115,102,108,97,103,0,42,102,114,111,109,79,98,106,101,99,116,0,115,117,98,106,101,99,116,91,51,50,93,0,98,111, +100,121,91,51,50,93,0,112,117,108,115,101,0,102,114,101,113,0,116,111,116,108,105,110,107,115,0,42,42,108,105,110, +107,115,0,116,97,112,0,106,111,121,105,110,100,101,120,0,97,120,105,115,95,115,105,110,103,108,101,0,97,120,105,115, +102,0,98,117,116,116,111,110,0,104,97,116,0,104,97,116,102,0,112,114,101,99,105,115,105,111,110,0,115,116,114,91, +49,50,56,93,0,109,111,100,117,108,101,91,54,52,93,0,42,109,121,110,101,119,0,105,110,112,117,116,115,0,116,111, +116,115,108,105,110,107,115,0,42,42,115,108,105,110,107,115,0,118,97,108,111,0,115,116,97,116,101,95,109,97,115,107, +0,42,97,99,116,0,102,114,97,109,101,80,114,111,112,91,51,50,93,0,98,108,101,110,100,105,110,0,112,114,105,111, +114,105,116,121,0,101,110,100,95,114,101,115,101,116,0,115,116,114,105,100,101,97,120,105,115,0,115,116,114,105,100,101, +108,101,110,103,116,104,0,115,110,100,110,114,0,112,97,100,49,91,50,93,0,109,97,107,101,99,111,112,121,0,99,111, +112,121,109,97,100,101,0,112,97,100,50,91,49,93,0,116,114,97,99,107,0,42,109,101,0,108,105,110,86,101,108,111, +99,105,116,121,91,51,93,0,97,110,103,86,101,108,111,99,105,116,121,91,51,93,0,108,111,99,97,108,102,108,97,103, +0,100,121,110,95,111,112,101,114,97,116,105,111,110,0,102,111,114,99,101,108,111,99,91,51,93,0,102,111,114,99,101, +114,111,116,91,51,93,0,108,105,110,101,97,114,118,101,108,111,99,105,116,121,91,51,93,0,97,110,103,117,108,97,114, +118,101,108,111,99,105,116,121,91,51,93,0,42,114,101,102,101,114,101,110,99,101,0,98,117,116,115,116,97,0,98,117, +116,101,110,100,0,109,105,110,0,109,97,120,0,118,105,115,105,102,97,99,0,114,111,116,100,97,109,112,0,109,105,110, +108,111,99,91,51,93,0,109,97,120,108,111,99,91,51,93,0,109,105,110,114,111,116,91,51,93,0,109,97,120,114,111, +116,91,51,93,0,109,97,116,112,114,111,112,91,51,50,93,0,100,105,115,116,114,105,98,117,116,105,111,110,0,105,110, +116,95,97,114,103,95,49,0,105,110,116,95,97,114,103,95,50,0,102,108,111,97,116,95,97,114,103,95,49,0,102,108, +111,97,116,95,97,114,103,95,50,0,116,111,80,114,111,112,78,97,109,101,91,51,50,93,0,42,116,111,79,98,106,101, +99,116,0,98,111,100,121,84,121,112,101,0,102,105,108,101,110,97,109,101,91,54,52,93,0,108,111,97,100,97,110,105, +110,97,109,101,91,54,52,93,0,105,110,116,95,97,114,103,0,102,108,111,97,116,95,97,114,103,0,103,111,0,97,99, +99,101,108,108,101,114,97,116,105,111,110,0,109,97,120,115,112,101,101,100,0,109,97,120,114,111,116,115,112,101,101,100, +0,109,97,120,116,105,108,116,115,112,101,101,100,0,116,105,108,116,100,97,109,112,0,115,112,101,101,100,100,97,109,112, +0,42,115,97,109,112,108,101,0,42,115,116,114,101,97,109,0,42,110,101,119,112,97,99,107,101,100,102,105,108,101,0, +42,115,110,100,95,115,111,117,110,100,0,112,97,110,110,105,110,103,0,97,116,116,101,110,117,97,116,105,111,110,0,112, +105,116,99,104,0,109,105,110,95,103,97,105,110,0,109,97,120,95,103,97,105,110,0,100,105,115,116,97,110,99,101,0, +115,116,114,101,97,109,108,101,110,0,99,104,97,110,110,101,108,115,0,104,105,103,104,112,114,105,111,0,112,97,100,91, +49,48,93,0,103,97,105,110,0,100,111,112,112,108,101,114,102,97,99,116,111,114,0,100,111,112,112,108,101,114,118,101, +108,111,99,105,116,121,0,110,117,109,115,111,117,110,100,115,98,108,101,110,100,101,114,0,110,117,109,115,111,117,110,100, +115,103,97,109,101,101,110,103,105,110,101,0,42,108,97,109,112,114,101,110,0,103,111,98,106,101,99,116,0,100,117,112, +108,105,95,111,102,115,91,51,93,0,99,104,105,108,100,98,97,115,101,0,114,111,108,108,0,104,101,97,100,91,51,93, +0,116,97,105,108,91,51,93,0,98,111,110,101,95,109,97,116,91,51,93,91,51,93,0,97,114,109,95,104,101,97,100, +91,51,93,0,97,114,109,95,116,97,105,108,91,51,93,0,97,114,109,95,109,97,116,91,52,93,91,52,93,0,120,119, +105,100,116,104,0,122,119,105,100,116,104,0,101,97,115,101,49,0,101,97,115,101,50,0,114,97,100,95,104,101,97,100, +0,114,97,100,95,116,97,105,108,0,98,111,110,101,98,97,115,101,0,99,104,97,105,110,98,97,115,101,0,112,97,116, +104,102,108,97,103,0,108,97,121,101,114,95,112,114,111,116,101,99,116,101,100,0,103,104,111,115,116,101,112,0,103,104, +111,115,116,115,105,122,101,0,103,104,111,115,116,116,121,112,101,0,112,97,116,104,115,105,122,101,0,103,104,111,115,116, +115,102,0,103,104,111,115,116,101,102,0,112,97,116,104,115,102,0,112,97,116,104,101,102,0,112,97,116,104,98,99,0, +112,97,116,104,97,99,0,99,111,110,115,116,102,108,97,103,0,105,107,102,108,97,103,0,115,101,108,101,99,116,102,108, +97,103,0,97,103,114,112,95,105,110,100,101,120,0,42,98,111,110,101,0,42,99,104,105,108,100,0,105,107,116,114,101, +101,0,42,98,95,98,111,110,101,95,109,97,116,115,0,42,100,117,97,108,95,113,117,97,116,0,42,98,95,98,111,110, +101,95,100,117,97,108,95,113,117,97,116,115,0,99,104,97,110,95,109,97,116,91,52,93,91,52,93,0,112,111,115,101, +95,109,97,116,91,52,93,91,52,93,0,112,111,115,101,95,104,101,97,100,91,51,93,0,112,111,115,101,95,116,97,105, +108,91,51,93,0,108,105,109,105,116,109,105,110,91,51,93,0,108,105,109,105,116,109,97,120,91,51,93,0,115,116,105, +102,102,110,101,115,115,91,51,93,0,105,107,115,116,114,101,116,99,104,0,42,99,117,115,116,111,109,0,99,104,97,110, +98,97,115,101,0,112,114,111,120,121,95,108,97,121,101,114,0,115,116,114,105,100,101,95,111,102,102,115,101,116,91,51, +93,0,99,121,99,108,105,99,95,111,102,102,115,101,116,91,51,93,0,97,103,114,111,117,112,115,0,97,99,116,105,118, +101,95,103,114,111,117,112,0,99,117,115,116,111,109,67,111,108,0,99,115,0,42,103,114,112,0,114,101,115,101,114,118, +101,100,49,0,103,114,111,117,112,115,0,97,99,116,105,118,101,95,109,97,114,107,101,114,0,97,99,116,110,114,0,97, +99,116,119,105,100,116,104,0,116,105,109,101,115,108,105,100,101,0,110,97,109,101,91,51,48,93,0,111,119,110,115,112, +97,99,101,0,116,97,114,115,112,97,99,101,0,101,110,102,111,114,99,101,0,104,101,97,100,116,97,105,108,0,42,116, +97,114,0,115,117,98,116,97,114,103,101,116,91,51,50,93,0,109,97,116,114,105,120,91,52,93,91,52,93,0,115,112, +97,99,101,0,42,112,114,111,112,0,116,97,114,110,117,109,0,116,97,114,103,101,116,115,0,105,116,101,114,97,116,105, +111,110,115,0,114,111,111,116,98,111,110,101,0,109,97,120,95,114,111,111,116,98,111,110,101,0,42,112,111,108,101,116, +97,114,0,112,111,108,101,115,117,98,116,97,114,103,101,116,91,51,50,93,0,112,111,108,101,97,110,103,108,101,0,111, +114,105,101,110,116,119,101,105,103,104,116,0,103,114,97,98,116,97,114,103,101,116,91,51,93,0,114,101,115,101,114,118, +101,100,50,0,109,105,110,109,97,120,102,108,97,103,0,115,116,117,99,107,0,99,97,99,104,101,91,51,93,0,108,111, +99,107,102,108,97,103,0,102,111,108,108,111,119,102,108,97,103,0,118,111,108,109,111,100,101,0,112,108,97,110,101,0, +111,114,103,108,101,110,103,116,104,0,98,117,108,103,101,0,112,105,118,88,0,112,105,118,89,0,112,105,118,90,0,97, +120,88,0,97,120,89,0,97,120,90,0,109,105,110,76,105,109,105,116,91,54,93,0,109,97,120,76,105,109,105,116,91, +54,93,0,101,120,116,114,97,70,122,0,105,110,118,109,97,116,91,52,93,91,52,93,0,102,114,111,109,0,116,111,0, +109,97,112,91,51,93,0,101,120,112,111,0,102,114,111,109,95,109,105,110,91,51,93,0,102,114,111,109,95,109,97,120, +91,51,93,0,116,111,95,109,105,110,91,51,93,0,116,111,95,109,97,120,91,51,93,0,122,109,105,110,0,122,109,97, +120,0,112,97,100,91,57,93,0,99,104,97,110,110,101,108,91,51,50,93,0,110,111,95,114,111,116,95,97,120,105,115, +0,115,116,114,105,100,101,95,97,120,105,115,0,99,117,114,109,111,100,0,97,99,116,115,116,97,114,116,0,97,99,116, +101,110,100,0,97,99,116,111,102,102,115,0,115,116,114,105,100,101,108,101,110,0,98,108,101,110,100,111,117,116,0,115, +116,114,105,100,101,99,104,97,110,110,101,108,91,51,50,93,0,111,102,102,115,95,98,111,110,101,91,51,50,93,0,104, +97,115,105,110,112,117,116,0,104,97,115,111,117,116,112,117,116,0,100,97,116,97,116,121,112,101,0,115,111,99,107,101, +116,116,121,112,101,0,42,110,101,119,95,115,111,99,107,0,110,115,0,108,105,109,105,116,0,115,116,97,99,107,95,105, +110,100,101,120,0,105,110,116,101,114,110,0,115,116,97,99,107,95,105,110,100,101,120,95,101,120,116,0,108,111,99,120, +0,108,111,99,121,0,111,119,110,95,105,110,100,101,120,0,116,111,95,105,110,100,101,120,0,42,116,111,115,111,99,107, +0,42,108,105,110,107,0,42,110,101,119,95,110,111,100,101,0,117,115,101,114,110,97,109,101,91,51,50,93,0,108,97, +115,116,121,0,111,117,116,112,117,116,115,0,42,115,116,111,114,97,103,101,0,109,105,110,105,119,105,100,116,104,0,99, +117,115,116,111,109,49,0,99,117,115,116,111,109,50,0,99,117,115,116,111,109,51,0,99,117,115,116,111,109,52,0,110, +101,101,100,95,101,120,101,99,0,101,120,101,99,0,116,111,116,114,0,98,117,116,114,0,112,114,118,114,0,42,116,121, +112,101,105,110,102,111,0,42,102,114,111,109,110,111,100,101,0,42,116,111,110,111,100,101,0,42,102,114,111,109,115,111, +99,107,0,110,111,100,101,115,0,108,105,110,107,115,0,42,115,116,97,99,107,0,42,116,104,114,101,97,100,115,116,97, +99,107,0,105,110,105,116,0,115,116,97,99,107,115,105,122,101,0,99,117,114,95,105,110,100,101,120,0,97,108,108,116, +121,112,101,115,0,42,111,119,110,116,121,112,101,0,42,115,101,108,105,110,0,42,115,101,108,111,117,116,0,40,42,116, +105,109,101,99,117,114,115,111,114,41,40,41,0,40,42,115,116,97,116,115,95,100,114,97,119,41,40,41,0,40,42,116, +101,115,116,95,98,114,101,97,107,41,40,41,0,99,121,99,108,105,99,0,109,111,118,105,101,0,115,97,109,112,108,101, +115,0,109,105,110,115,112,101,101,100,0,112,101,114,99,101,110,116,120,0,112,101,114,99,101,110,116,121,0,98,111,107, +101,104,0,99,117,114,118,101,100,0,105,109,97,103,101,95,105,110,95,119,105,100,116,104,0,105,109,97,103,101,95,105, +110,95,104,101,105,103,104,116,0,99,101,110,116,101,114,95,120,0,99,101,110,116,101,114,95,121,0,115,112,105,110,0, +105,116,101,114,0,119,114,97,112,0,115,105,103,109,97,95,99,111,108,111,114,0,115,105,103,109,97,95,115,112,97,99, +101,0,104,117,101,0,115,97,116,0,116,49,0,116,50,0,116,51,0,102,115,116,114,101,110,103,116,104,0,102,97,108, +112,104,97,0,107,101,121,91,52,93,0,120,49,0,120,50,0,121,49,0,121,50,0,99,111,108,110,97,109,101,91,51, +50,93,0,98,107,116,121,112,101,0,114,111,116,97,116,105,111,110,0,112,114,101,118,105,101,119,0,103,97,109,99,111, +0,110,111,95,122,98,117,102,0,102,115,116,111,112,0,109,97,120,98,108,117,114,0,98,116,104,114,101,115,104,0,42, +100,105,99,116,0,42,110,111,100,101,0,97,110,103,108,101,95,111,102,115,0,99,111,108,109,111,100,0,109,105,120,0, +116,104,114,101,115,104,111,108,100,0,102,97,100,101,0,109,0,99,0,106,105,116,0,112,114,111,106,0,102,105,116,0, +115,104,111,114,116,121,0,109,105,110,116,97,98,108,101,0,109,97,120,116,97,98,108,101,0,101,120,116,95,105,110,91, +50,93,0,101,120,116,95,111,117,116,91,50,93,0,42,99,117,114,118,101,0,42,116,97,98,108,101,0,42,112,114,101, +109,117,108,116,97,98,108,101,0,99,117,114,114,0,99,108,105,112,114,0,99,109,91,52,93,0,98,108,97,99,107,91, +51,93,0,119,104,105,116,101,91,51,93,0,98,119,109,117,108,91,51,93,0,115,97,109,112,108,101,91,51,93,0,111, +102,102,115,101,116,91,50,93,0,105,110,110,101,114,114,97,100,105,117,115,0,114,97,116,101,0,114,103,98,91,51,93, +0,99,108,111,110,101,0,97,99,116,105,118,101,95,114,110,100,0,97,99,116,105,118,101,95,99,108,111,110,101,0,97, +99,116,105,118,101,95,109,97,115,107,0,42,108,97,121,101,114,115,0,116,111,116,108,97,121,101,114,0,109,97,120,108, +97,121,101,114,0,116,111,116,115,105,122,101,0,42,112,111,111,108,0,101,100,105,116,102,108,97,103,0,118,101,108,91, +51,93,0,114,111,116,91,52,93,0,97,118,101,91,51,93,0,110,117,109,0,112,97,114,101,110,116,0,112,97,91,52, +93,0,119,91,52,93,0,102,117,118,91,52,93,0,102,111,102,102,115,101,116,0,114,97,110,100,91,51,93,0,42,115, +116,105,99,107,95,111,98,0,112,114,101,118,95,115,116,97,116,101,0,42,104,97,105,114,0,105,95,114,111,116,91,52, +93,0,114,95,114,111,116,91,52,93,0,114,95,97,118,101,91,51,93,0,114,95,118,101,91,51,93,0,100,105,101,116, +105,109,101,0,98,97,110,107,0,115,105,122,101,109,117,108,0,110,117,109,95,100,109,99,97,99,104,101,0,98,112,105, +0,97,108,105,118,101,0,108,111,111,112,0,100,105,115,116,114,0,112,104,121,115,116,121,112,101,0,114,111,116,109,111, +100,101,0,97,118,101,109,111,100,101,0,114,101,97,99,116,101,118,101,110,116,0,100,114,97,119,0,100,114,97,119,95, +97,115,0,100,114,97,119,95,115,105,122,101,0,99,104,105,108,100,116,121,112,101,0,100,114,97,119,95,115,116,101,112, +0,114,101,110,95,115,116,101,112,0,104,97,105,114,95,115,116,101,112,0,107,101,121,115,95,115,116,101,112,0,97,100, +97,112,116,95,97,110,103,108,101,0,97,100,97,112,116,95,112,105,120,0,114,111,116,102,114,111,109,0,105,110,116,101, +103,114,97,116,111,114,0,110,98,101,116,119,101,101,110,0,98,111,105,100,110,101,105,103,104,98,111,117,114,115,0,98, +98,95,97,108,105,103,110,0,98,98,95,117,118,95,115,112,108,105,116,0,98,98,95,97,110,105,109,0,98,98,95,115, +112,108,105,116,95,111,102,102,115,101,116,0,98,98,95,116,105,108,116,0,98,98,95,114,97,110,100,95,116,105,108,116, +0,98,98,95,111,102,102,115,101,116,91,50,93,0,115,105,109,112,108,105,102,121,95,102,108,97,103,0,115,105,109,112, +108,105,102,121,95,114,101,102,115,105,122,101,0,115,105,109,112,108,105,102,121,95,114,97,116,101,0,115,105,109,112,108, +105,102,121,95,116,114,97,110,115,105,116,105,111,110,0,115,105,109,112,108,105,102,121,95,118,105,101,119,112,111,114,116, +0,116,105,109,101,116,119,101,97,107,0,106,105,116,102,97,99,0,107,101,121,101,100,95,116,105,109,101,0,101,102,102, +95,104,97,105,114,0,103,114,105,100,95,114,101,115,0,112,97,114,116,102,97,99,0,116,97,110,102,97,99,0,116,97, +110,112,104,97,115,101,0,114,101,97,99,116,102,97,99,0,97,118,101,102,97,99,0,112,104,97,115,101,102,97,99,0, +114,97,110,100,114,111,116,102,97,99,0,114,97,110,100,112,104,97,115,101,102,97,99,0,114,97,110,100,115,105,122,101, +0,114,101,97,99,116,115,104,97,112,101,0,97,99,99,91,51,93,0,100,114,97,103,102,97,99,0,98,114,111,119,110, +102,97,99,0,100,97,109,112,102,97,99,0,97,98,115,108,101,110,103,116,104,0,114,97,110,100,108,101,110,103,116,104, +0,99,104,105,108,100,95,110,98,114,0,114,101,110,95,99,104,105,108,100,95,110,98,114,0,112,97,114,101,110,116,115, +0,99,104,105,108,100,115,105,122,101,0,99,104,105,108,100,114,97,110,100,115,105,122,101,0,99,104,105,108,100,114,97, +100,0,99,104,105,108,100,102,108,97,116,0,99,104,105,108,100,115,112,114,101,97,100,0,99,108,117,109,112,102,97,99, +0,99,108,117,109,112,112,111,119,0,114,111,117,103,104,49,0,114,111,117,103,104,49,95,115,105,122,101,0,114,111,117, +103,104,50,0,114,111,117,103,104,50,95,115,105,122,101,0,114,111,117,103,104,50,95,116,104,114,101,115,0,114,111,117, +103,104,95,101,110,100,0,114,111,117,103,104,95,101,110,100,95,115,104,97,112,101,0,98,114,97,110,99,104,95,116,104, +114,101,115,0,100,114,97,119,95,108,105,110,101,91,50,93,0,109,97,120,95,108,97,116,95,97,99,99,0,109,97,120, +95,116,97,110,95,97,99,99,0,97,118,101,114,97,103,101,95,118,101,108,0,98,97,110,107,105,110,103,0,109,97,120, +95,98,97,110,107,0,103,114,111,117,110,100,122,0,98,111,105,100,102,97,99,91,56,93,0,98,111,105,100,114,117,108, +101,91,56,93,0,42,101,102,102,95,103,114,111,117,112,0,42,100,117,112,95,111,98,0,42,98,98,95,111,98,0,42, +112,100,50,0,42,112,97,114,116,0,42,101,100,105,116,0,42,42,112,97,116,104,99,97,99,104,101,0,42,42,99,104, +105,108,100,99,97,99,104,101,0,112,97,116,104,99,97,99,104,101,98,117,102,115,0,99,104,105,108,100,99,97,99,104, +101,98,117,102,115,0,42,116,97,114,103,101,116,95,111,98,0,42,107,101,121,101,100,95,111,98,0,42,108,97,116,116, +105,99,101,0,101,102,102,101,99,116,111,114,115,0,114,101,97,99,116,101,118,101,110,116,115,0,116,111,116,99,104,105, +108,100,0,116,111,116,99,97,99,104,101,100,0,116,111,116,99,104,105,108,100,99,97,99,104,101,0,116,97,114,103,101, +116,95,112,115,121,115,0,107,101,121,101,100,95,112,115,121,115,0,116,111,116,107,101,121,101,100,0,98,97,107,101,115, +112,97,99,101,0,98,98,95,117,118,110,97,109,101,91,51,93,91,51,50,93,0,118,103,114,111,117,112,91,49,50,93, +0,118,103,95,110,101,103,0,114,116,51,0,42,114,101,110,100,101,114,100,97,116,97,0,42,99,97,99,104,101,0,67, +100,105,115,0,67,118,105,0,91,51,93,0,115,116,114,117,99,116,117,114,97,108,0,98,101,110,100,105,110,103,0,109, +97,120,95,98,101,110,100,0,109,97,120,95,115,116,114,117,99,116,0,109,97,120,95,115,104,101,97,114,0,97,118,103, +95,115,112,114,105,110,103,95,108,101,110,0,116,105,109,101,115,99,97,108,101,0,101,102,102,95,102,111,114,99,101,95, +115,99,97,108,101,0,101,102,102,95,119,105,110,100,95,115,99,97,108,101,0,115,105,109,95,116,105,109,101,95,111,108, +100,0,115,116,101,112,115,80,101,114,70,114,97,109,101,0,112,114,101,114,111,108,108,0,109,97,120,115,112,114,105,110, +103,108,101,110,0,115,111,108,118,101,114,95,116,121,112,101,0,118,103,114,111,117,112,95,98,101,110,100,0,118,103,114, +111,117,112,95,109,97,115,115,0,118,103,114,111,117,112,95,115,116,114,117,99,116,0,112,114,101,115,101,116,115,0,42, +99,111,108,108,105,115,105,111,110,95,108,105,115,116,0,101,112,115,105,108,111,110,0,115,101,108,102,95,102,114,105,99, +116,105,111,110,0,115,101,108,102,101,112,115,105,108,111,110,0,115,101,108,102,95,108,111,111,112,95,99,111,117,110,116, +0,108,111,111,112,95,99,111,117,110,116,0,112,114,101,115,115,117,114,101,0,42,112,111,105,110,116,115,0,116,111,116, +112,111,105,110,116,115,0,116,104,105,99,107,110,101,115,115,0,115,116,114,111,107,101,115,0,102,114,97,109,101,110,117, +109,0,42,97,99,116,102,114,97,109,101,0,103,115,116,101,112,0,105,110,102,111,91,49,50,56,93,0,115,98,117,102, +102,101,114,95,115,105,122,101,0,115,98,117,102,102,101,114,95,115,102,108,97,103,0,42,115,98,117,102,102,101,114,0, +0,0,0,84,89,80,69,100,1,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,0,117,115,104,111, +114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118, +111,105,100,0,76,105,110,107,0,76,105,110,107,68,97,116,97,0,76,105,115,116,66,97,115,101,0,118,101,99,50,115, +0,118,101,99,50,105,0,118,101,99,50,102,0,118,101,99,50,100,0,118,101,99,51,105,0,118,101,99,51,102,0,118, +101,99,51,100,0,118,101,99,52,105,0,118,101,99,52,102,0,118,101,99,52,100,0,114,99,116,105,0,114,99,116,102, +0,73,68,80,114,111,112,101,114,116,121,68,97,116,97,0,73,68,80,114,111,112,101,114,116,121,0,73,68,0,76,105, +98,114,97,114,121,0,70,105,108,101,68,97,116,97,0,80,114,101,118,105,101,119,73,109,97,103,101,0,73,112,111,68, +114,105,118,101,114,0,79,98,106,101,99,116,0,73,112,111,67,117,114,118,101,0,66,80,111,105,110,116,0,66,101,122, +84,114,105,112,108,101,0,73,112,111,0,75,101,121,66,108,111,99,107,0,75,101,121,0,83,99,114,105,112,116,76,105, +110,107,0,84,101,120,116,76,105,110,101,0,84,101,120,116,77,97,114,107,101,114,0,84,101,120,116,0,80,97,99,107, +101,100,70,105,108,101,0,67,97,109,101,114,97,0,73,109,97,103,101,85,115,101,114,0,73,109,97,103,101,0,71,80, +85,84,101,120,116,117,114,101,0,97,110,105,109,0,82,101,110,100,101,114,82,101,115,117,108,116,0,77,84,101,120,0, +84,101,120,0,80,108,117,103,105,110,84,101,120,0,67,66,68,97,116,97,0,67,111,108,111,114,66,97,110,100,0,69, +110,118,77,97,112,0,73,109,66,117,102,0,98,78,111,100,101,84,114,101,101,0,84,101,120,77,97,112,112,105,110,103, +0,76,97,109,112,0,67,117,114,118,101,77,97,112,112,105,110,103,0,87,97,118,101,0,77,97,116,101,114,105,97,108, +0,71,114,111,117,112,0,86,70,111,110,116,0,86,70,111,110,116,68,97,116,97,0,77,101,116,97,69,108,101,109,0, +66,111,117,110,100,66,111,120,0,77,101,116,97,66,97,108,108,0,78,117,114,98,0,67,104,97,114,73,110,102,111,0, +84,101,120,116,66,111,120,0,67,117,114,118,101,0,80,97,116,104,0,77,101,115,104,0,77,70,97,99,101,0,77,84, +70,97,99,101,0,84,70,97,99,101,0,77,86,101,114,116,0,77,69,100,103,101,0,77,68,101,102,111,114,109,86,101, +114,116,0,77,67,111,108,0,77,83,116,105,99,107,121,0,77,83,101,108,101,99,116,0,67,117,115,116,111,109,68,97, +116,97,0,77,117,108,116,105,114,101,115,0,80,97,114,116,105,97,108,86,105,115,105,98,105,108,105,116,121,0,77,68, +101,102,111,114,109,87,101,105,103,104,116,0,77,84,101,120,80,111,108,121,0,77,76,111,111,112,85,86,0,77,76,111, +111,112,67,111,108,0,77,70,108,111,97,116,80,114,111,112,101,114,116,121,0,77,73,110,116,80,114,111,112,101,114,116, +121,0,77,83,116,114,105,110,103,80,114,111,112,101,114,116,121,0,79,114,105,103,83,112,97,99,101,70,97,99,101,0, +77,117,108,116,105,114,101,115,67,111,108,0,77,117,108,116,105,114,101,115,67,111,108,70,97,99,101,0,77,117,108,116, +105,114,101,115,70,97,99,101,0,77,117,108,116,105,114,101,115,69,100,103,101,0,77,117,108,116,105,114,101,115,76,101, +118,101,108,0,77,117,108,116,105,114,101,115,77,97,112,78,111,100,101,0,77,111,100,105,102,105,101,114,68,97,116,97, +0,83,117,98,115,117,114,102,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,77,111,100,105, +102,105,101,114,68,97,116,97,0,67,117,114,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,66,117,105,108,100, +77,111,100,105,102,105,101,114,68,97,116,97,0,77,97,115,107,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114, +114,97,121,77,111,100,105,102,105,101,114,68,97,116,97,0,77,105,114,114,111,114,77,111,100,105,102,105,101,114,68,97, +116,97,0,69,100,103,101,83,112,108,105,116,77,111,100,105,102,105,101,114,68,97,116,97,0,66,101,118,101,108,77,111, +100,105,102,105,101,114,68,97,116,97,0,66,77,101,115,104,77,111,100,105,102,105,101,114,68,97,116,97,0,68,105,115, +112,108,97,99,101,77,111,100,105,102,105,101,114,68,97,116,97,0,85,86,80,114,111,106,101,99,116,77,111,100,105,102, +105,101,114,68,97,116,97,0,68,101,99,105,109,97,116,101,77,111,100,105,102,105,101,114,68,97,116,97,0,83,109,111, +111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67,97,115,116,77,111,100,105,102,105,101,114,68,97,116,97, +0,87,97,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114,109,97,116,117,114,101,77,111,100,105,102,105, +101,114,68,97,116,97,0,72,111,111,107,77,111,100,105,102,105,101,114,68,97,116,97,0,83,111,102,116,98,111,100,121, +77,111,100,105,102,105,101,114,68,97,116,97,0,67,108,111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67, +108,111,116,104,0,67,108,111,116,104,83,105,109,83,101,116,116,105,110,103,115,0,67,108,111,116,104,67,111,108,108,83, +101,116,116,105,110,103,115,0,80,111,105,110,116,67,97,99,104,101,0,67,111,108,108,105,115,105,111,110,77,111,100,105, +102,105,101,114,68,97,116,97,0,66,86,72,84,114,101,101,0,83,117,114,102,97,99,101,77,111,100,105,102,105,101,114, +68,97,116,97,0,68,101,114,105,118,101,100,77,101,115,104,0,66,86,72,84,114,101,101,70,114,111,109,77,101,115,104, +0,66,111,111,108,101,97,110,77,111,100,105,102,105,101,114,68,97,116,97,0,77,68,101,102,73,110,102,108,117,101,110, +99,101,0,77,68,101,102,67,101,108,108,0,77,101,115,104,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97, +116,97,0,80,97,114,116,105,99,108,101,83,121,115,116,101,109,77,111,100,105,102,105,101,114,68,97,116,97,0,80,97, +114,116,105,99,108,101,83,121,115,116,101,109,0,80,97,114,116,105,99,108,101,73,110,115,116,97,110,99,101,77,111,100, +105,102,105,101,114,68,97,116,97,0,69,120,112,108,111,100,101,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108, +117,105,100,115,105,109,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108,117,105,100,115,105,109,83,101,116,116,105, +110,103,115,0,83,104,114,105,110,107,119,114,97,112,77,111,100,105,102,105,101,114,68,97,116,97,0,83,105,109,112,108, +101,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,0,98,68,101,102, +111,114,109,71,114,111,117,112,0,98,65,99,116,105,111,110,0,98,80,111,115,101,0,66,117,108,108,101,116,83,111,102, +116,66,111,100,121,0,80,97,114,116,68,101,102,108,101,99,116,0,83,111,102,116,66,111,100,121,0,79,98,72,111,111, +107,0,82,78,71,0,83,66,86,101,114,116,101,120,0,66,111,100,121,80,111,105,110,116,0,66,111,100,121,83,112,114, +105,110,103,0,83,66,83,99,114,97,116,99,104,0,87,111,114,108,100,0,82,97,100,105,111,0,66,97,115,101,0,65, +118,105,67,111,100,101,99,68,97,116,97,0,81,117,105,99,107,116,105,109,101,67,111,100,101,99,68,97,116,97,0,70, +70,77,112,101,103,67,111,100,101,99,68,97,116,97,0,65,117,100,105,111,68,97,116,97,0,83,99,101,110,101,82,101, +110,100,101,114,76,97,121,101,114,0,82,101,110,100,101,114,68,97,116,97,0,82,101,110,100,101,114,80,114,111,102,105, +108,101,0,71,97,109,101,70,114,97,109,105,110,103,0,84,105,109,101,77,97,114,107,101,114,0,73,109,97,103,101,80, +97,105,110,116,83,101,116,116,105,110,103,115,0,66,114,117,115,104,0,80,97,114,116,105,99,108,101,66,114,117,115,104, +68,97,116,97,0,80,97,114,116,105,99,108,101,69,100,105,116,83,101,116,116,105,110,103,115,0,84,114,97,110,115,102, +111,114,109,79,114,105,101,110,116,97,116,105,111,110,0,84,111,111,108,83,101,116,116,105,110,103,115,0,66,114,117,115, +104,68,97,116,97,0,83,99,117,108,112,116,68,97,116,97,0,83,99,117,108,112,116,83,101,115,115,105,111,110,0,83, +99,101,110,101,0,68,97,103,70,111,114,101,115,116,0,66,71,112,105,99,0,86,105,101,119,51,68,0,83,112,97,99, +101,76,105,110,107,0,83,99,114,65,114,101,97,0,82,101,110,100,101,114,73,110,102,111,0,82,101,116,111,112,111,86, +105,101,119,68,97,116,97,0,86,105,101,119,68,101,112,116,104,115,0,98,71,80,100,97,116,97,0,86,105,101,119,50, +68,0,83,112,97,99,101,73,110,102,111,0,83,112,97,99,101,73,112,111,0,83,112,97,99,101,66,117,116,115,0,83, +112,97,99,101,83,101,113,0,83,112,97,99,101,70,105,108,101,0,100,105,114,101,110,116,114,121,0,66,108,101,110,100, +72,97,110,100,108,101,0,83,112,97,99,101,79,111,112,115,0,84,114,101,101,83,116,111,114,101,0,84,114,101,101,83, +116,111,114,101,69,108,101,109,0,83,112,97,99,101,73,109,97,103,101,0,83,112,97,99,101,78,108,97,0,83,112,97, +99,101,84,101,120,116,0,83,99,114,105,112,116,0,83,112,97,99,101,83,99,114,105,112,116,0,83,112,97,99,101,84, +105,109,101,0,83,112,97,99,101,78,111,100,101,0,83,112,97,99,101,73,109,97,83,101,108,0,70,105,108,101,76,105, +115,116,0,84,104,101,109,101,85,73,0,84,104,101,109,101,83,112,97,99,101,0,84,104,101,109,101,87,105,114,101,67, +111,108,111,114,0,98,84,104,101,109,101,0,83,111,108,105,100,76,105,103,104,116,0,85,115,101,114,68,101,102,0,98, +83,99,114,101,101,110,0,83,99,114,86,101,114,116,0,83,99,114,69,100,103,101,0,80,97,110,101,108,0,70,105,108, +101,71,108,111,98,97,108,0,83,116,114,105,112,69,108,101,109,0,84,83,116,114,105,112,69,108,101,109,0,83,116,114, +105,112,67,114,111,112,0,83,116,114,105,112,84,114,97,110,115,102,111,114,109,0,83,116,114,105,112,67,111,108,111,114, +66,97,108,97,110,99,101,0,83,116,114,105,112,67,111,108,111,114,66,97,108,97,110,99,101,71,85,73,72,101,108,112, +101,114,0,83,116,114,105,112,80,114,111,120,121,0,83,116,114,105,112,0,80,108,117,103,105,110,83,101,113,0,83,101, +113,117,101,110,99,101,0,98,83,111,117,110,100,0,104,100,97,117,100,105,111,0,77,101,116,97,83,116,97,99,107,0, +69,100,105,116,105,110,103,0,87,105,112,101,86,97,114,115,0,71,108,111,119,86,97,114,115,0,84,114,97,110,115,102, +111,114,109,86,97,114,115,0,83,111,108,105,100,67,111,108,111,114,86,97,114,115,0,83,112,101,101,100,67,111,110,116, +114,111,108,86,97,114,115,0,69,102,102,101,99,116,0,66,117,105,108,100,69,102,102,0,80,97,114,116,69,102,102,0, +80,97,114,116,105,99,108,101,0,87,97,118,101,69,102,102,0,79,111,112,115,0,98,80,114,111,112,101,114,116,121,0, +98,78,101,97,114,83,101,110,115,111,114,0,98,77,111,117,115,101,83,101,110,115,111,114,0,98,84,111,117,99,104,83, +101,110,115,111,114,0,98,75,101,121,98,111,97,114,100,83,101,110,115,111,114,0,98,80,114,111,112,101,114,116,121,83, +101,110,115,111,114,0,98,65,99,116,117,97,116,111,114,83,101,110,115,111,114,0,98,68,101,108,97,121,83,101,110,115, +111,114,0,98,67,111,108,108,105,115,105,111,110,83,101,110,115,111,114,0,98,82,97,100,97,114,83,101,110,115,111,114, +0,98,82,97,110,100,111,109,83,101,110,115,111,114,0,98,82,97,121,83,101,110,115,111,114,0,98,77,101,115,115,97, +103,101,83,101,110,115,111,114,0,98,83,101,110,115,111,114,0,98,67,111,110,116,114,111,108,108,101,114,0,98,74,111, +121,115,116,105,99,107,83,101,110,115,111,114,0,98,69,120,112,114,101,115,115,105,111,110,67,111,110,116,0,98,80,121, +116,104,111,110,67,111,110,116,0,98,65,99,116,117,97,116,111,114,0,98,65,100,100,79,98,106,101,99,116,65,99,116, +117,97,116,111,114,0,98,65,99,116,105,111,110,65,99,116,117,97,116,111,114,0,98,83,111,117,110,100,65,99,116,117, +97,116,111,114,0,98,67,68,65,99,116,117,97,116,111,114,0,98,69,100,105,116,79,98,106,101,99,116,65,99,116,117, +97,116,111,114,0,98,83,99,101,110,101,65,99,116,117,97,116,111,114,0,98,80,114,111,112,101,114,116,121,65,99,116, +117,97,116,111,114,0,98,79,98,106,101,99,116,65,99,116,117,97,116,111,114,0,98,73,112,111,65,99,116,117,97,116, +111,114,0,98,67,97,109,101,114,97,65,99,116,117,97,116,111,114,0,98,67,111,110,115,116,114,97,105,110,116,65,99, +116,117,97,116,111,114,0,98,71,114,111,117,112,65,99,116,117,97,116,111,114,0,98,82,97,110,100,111,109,65,99,116, +117,97,116,111,114,0,98,77,101,115,115,97,103,101,65,99,116,117,97,116,111,114,0,98,71,97,109,101,65,99,116,117, +97,116,111,114,0,98,86,105,115,105,98,105,108,105,116,121,65,99,116,117,97,116,111,114,0,98,84,119,111,68,70,105, +108,116,101,114,65,99,116,117,97,116,111,114,0,98,80,97,114,101,110,116,65,99,116,117,97,116,111,114,0,98,83,116, +97,116,101,65,99,116,117,97,116,111,114,0,70,114,101,101,67,97,109,101,114,97,0,98,83,97,109,112,108,101,0,98, +83,111,117,110,100,76,105,115,116,101,110,101,114,0,83,112,97,99,101,83,111,117,110,100,0,71,114,111,117,112,79,98, +106,101,99,116,0,66,111,110,101,0,98,65,114,109,97,116,117,114,101,0,98,80,111,115,101,67,104,97,110,110,101,108, +0,98,65,99,116,105,111,110,71,114,111,117,112,0,98,65,99,116,105,111,110,67,104,97,110,110,101,108,0,83,112,97, +99,101,65,99,116,105,111,110,0,98,67,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,0,98,67,111,110, +115,116,114,97,105,110,116,0,98,67,111,110,115,116,114,97,105,110,116,84,97,114,103,101,116,0,98,80,121,116,104,111, +110,67,111,110,115,116,114,97,105,110,116,0,98,75,105,110,101,109,97,116,105,99,67,111,110,115,116,114,97,105,110,116, +0,98,84,114,97,99,107,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,111,116,97,116,101,76,105,107,101,67, +111,110,115,116,114,97,105,110,116,0,98,76,111,99,97,116,101,76,105,107,101,67,111,110,115,116,114,97,105,110,116,0, +98,77,105,110,77,97,120,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,107,101,67,111,110,115,116, +114,97,105,110,116,0,98,65,99,116,105,111,110,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,107,84,114,97, +99,107,67,111,110,115,116,114,97,105,110,116,0,98,70,111,108,108,111,119,80,97,116,104,67,111,110,115,116,114,97,105, +110,116,0,98,83,116,114,101,116,99,104,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,105,103,105,100,66,111, +100,121,74,111,105,110,116,67,111,110,115,116,114,97,105,110,116,0,98,67,108,97,109,112,84,111,67,111,110,115,116,114, +97,105,110,116,0,98,67,104,105,108,100,79,102,67,111,110,115,116,114,97,105,110,116,0,98,84,114,97,110,115,102,111, +114,109,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116, +0,98,82,111,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,109,105,116,67, +111,110,115,116,114,97,105,110,116,0,98,68,105,115,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98, +83,104,114,105,110,107,119,114,97,112,67,111,110,115,116,114,97,105,110,116,0,98,65,99,116,105,111,110,77,111,100,105, +102,105,101,114,0,98,65,99,116,105,111,110,83,116,114,105,112,0,98,78,111,100,101,83,116,97,99,107,0,98,78,111, +100,101,83,111,99,107,101,116,0,98,78,111,100,101,76,105,110,107,0,98,78,111,100,101,0,98,78,111,100,101,80,114, +101,118,105,101,119,0,98,78,111,100,101,84,121,112,101,0,78,111,100,101,73,109,97,103,101,65,110,105,109,0,78,111, +100,101,66,108,117,114,68,97,116,97,0,78,111,100,101,68,66,108,117,114,68,97,116,97,0,78,111,100,101,66,105,108, +97,116,101,114,97,108,66,108,117,114,68,97,116,97,0,78,111,100,101,72,117,101,83,97,116,0,78,111,100,101,73,109, +97,103,101,70,105,108,101,0,78,111,100,101,67,104,114,111,109,97,0,78,111,100,101,84,119,111,88,89,115,0,78,111, +100,101,84,119,111,70,108,111,97,116,115,0,78,111,100,101,71,101,111,109,101,116,114,121,0,78,111,100,101,86,101,114, +116,101,120,67,111,108,0,78,111,100,101,68,101,102,111,99,117,115,0,78,111,100,101,83,99,114,105,112,116,68,105,99, +116,0,78,111,100,101,71,108,97,114,101,0,78,111,100,101,84,111,110,101,109,97,112,0,78,111,100,101,76,101,110,115, +68,105,115,116,0,84,101,120,78,111,100,101,79,117,116,112,117,116,0,67,117,114,118,101,77,97,112,80,111,105,110,116, +0,67,117,114,118,101,77,97,112,0,66,114,117,115,104,67,108,111,110,101,0,67,117,115,116,111,109,68,97,116,97,76, +97,121,101,114,0,72,97,105,114,75,101,121,0,80,97,114,116,105,99,108,101,75,101,121,0,67,104,105,108,100,80,97, +114,116,105,99,108,101,0,80,97,114,116,105,99,108,101,68,97,116,97,0,80,97,114,116,105,99,108,101,83,101,116,116, +105,110,103,115,0,80,97,114,116,105,99,108,101,69,100,105,116,0,80,97,114,116,105,99,108,101,67,97,99,104,101,75, +101,121,0,76,105,110,107,78,111,100,101,0,98,71,80,68,115,112,111,105,110,116,0,98,71,80,68,115,116,114,111,107, +101,0,98,71,80,68,102,114,97,109,101,0,98,71,80,68,108,97,121,101,114,0,0,84,76,69,78,1,0,1,0,2, +0,2,0,4,0,4,0,4,0,4,0,8,0,0,0,8,0,12,0,8,0,4,0,8,0,8,0,16,0,12,0,12, +0,24,0,16,0,16,0,32,0,16,0,16,0,20,0,76,0,52,0,40,2,0,0,32,0,-116,0,80,3,92,0,36, +0,56,0,84,0,112,0,120,0,16,0,24,0,40,0,120,0,20,0,-124,0,32,0,-128,1,0,0,0,0,0,0,-120, +0,16,1,84,1,24,0,8,3,-88,0,0,0,124,0,-124,0,-128,1,8,1,56,0,108,2,76,0,68,1,0,0,108, +0,104,0,-120,0,56,0,8,0,16,0,56,1,0,0,24,1,20,0,44,0,60,0,24,0,12,0,12,0,4,0,8, +0,8,0,24,0,76,0,32,0,8,0,12,0,8,0,8,0,4,0,4,0,0,1,32,0,16,0,64,0,24,0,12, +0,56,0,0,0,52,0,68,0,88,0,96,0,68,0,96,0,116,0,64,0,60,0,108,0,60,0,-108,0,-104,0,60, +0,92,0,104,0,-72,0,100,0,-76,0,52,0,68,0,0,0,-124,0,28,0,20,0,100,0,0,0,60,0,0,0,0, +0,64,0,8,0,8,0,-40,0,76,0,64,1,64,0,64,0,60,0,-92,1,108,0,104,0,116,0,40,0,84,0,56, +0,120,0,-128,0,-8,0,-48,0,0,0,16,0,0,0,0,0,0,0,108,1,40,0,28,0,-80,0,-112,0,52,0,16, +0,72,0,-48,3,56,0,16,0,80,0,12,0,-72,0,8,0,72,0,80,0,-24,0,8,0,-88,0,0,0,124,5,0, +0,60,0,28,3,36,0,-52,0,0,0,0,0,0,0,20,0,-120,0,36,0,88,1,-36,0,-56,0,-56,1,0,0,0, +0,8,1,12,0,12,0,8,1,-76,0,-128,0,80,2,36,0,-92,0,-36,0,-124,2,0,0,-104,0,-48,0,16,0,56, +14,56,0,32,12,120,0,20,0,24,0,-28,0,32,0,80,0,28,0,16,0,8,0,60,0,0,0,-4,0,-16,0,-88, +1,-60,0,28,1,0,0,16,0,28,0,12,0,24,0,48,0,16,0,28,0,16,0,24,0,56,1,0,0,56,0,44, +0,64,0,48,0,8,0,44,0,72,0,104,0,40,0,8,0,72,0,44,0,40,0,108,0,68,0,76,0,80,0,60, +0,-128,0,76,0,60,0,12,0,92,0,28,0,20,0,80,0,16,0,76,0,108,0,84,0,28,0,96,0,60,0,56, +0,108,0,-116,0,4,0,20,0,12,0,8,0,40,0,0,0,68,0,-80,0,24,0,4,1,116,0,-104,1,72,0,64, +0,-64,0,44,0,64,0,116,0,60,0,104,0,52,0,44,0,44,0,68,0,44,0,64,0,44,0,20,0,52,0,96, +0,12,0,108,0,92,0,28,0,28,0,28,0,52,0,20,0,60,0,-116,0,36,0,120,0,24,0,-52,0,0,0,0, +0,16,0,40,0,28,0,12,0,12,0,16,1,40,0,8,0,8,0,64,0,32,0,24,0,8,0,24,0,32,0,8, +0,32,0,12,0,44,0,20,0,68,0,24,0,56,0,72,0,-4,0,-32,1,0,0,0,0,0,0,16,0,20,0,24, +0,-84,0,83,84,82,67,57,1,0,0,10,0,2,0,10,0,0,0,10,0,1,0,11,0,3,0,11,0,0,0,11, +0,1,0,9,0,2,0,12,0,2,0,9,0,3,0,9,0,4,0,13,0,2,0,2,0,5,0,2,0,6,0,14, +0,2,0,4,0,5,0,4,0,6,0,15,0,2,0,7,0,5,0,7,0,6,0,16,0,2,0,8,0,5,0,8, +0,6,0,17,0,3,0,4,0,5,0,4,0,6,0,4,0,7,0,18,0,3,0,7,0,5,0,7,0,6,0,7, +0,7,0,19,0,3,0,8,0,5,0,8,0,6,0,8,0,7,0,20,0,4,0,4,0,5,0,4,0,6,0,4, +0,7,0,4,0,8,0,21,0,4,0,7,0,5,0,7,0,6,0,7,0,7,0,7,0,8,0,22,0,4,0,8, +0,5,0,8,0,6,0,8,0,7,0,8,0,8,0,23,0,4,0,4,0,9,0,4,0,10,0,4,0,11,0,4, +0,12,0,24,0,4,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,25,0,4,0,9,0,13,0,12, +0,14,0,4,0,15,0,4,0,16,0,26,0,10,0,26,0,0,0,26,0,1,0,0,0,17,0,0,0,18,0,0, +0,19,0,2,0,20,0,4,0,21,0,25,0,22,0,4,0,23,0,4,0,24,0,27,0,9,0,9,0,0,0,9, +0,1,0,27,0,25,0,28,0,26,0,0,0,27,0,2,0,28,0,2,0,20,0,4,0,29,0,26,0,30,0,28, +0,8,0,27,0,31,0,27,0,32,0,29,0,33,0,0,0,34,0,0,0,35,0,4,0,36,0,4,0,37,0,28, +0,38,0,30,0,6,0,4,0,39,0,4,0,40,0,2,0,41,0,2,0,42,0,2,0,43,0,4,0,44,0,31, +0,6,0,32,0,45,0,2,0,46,0,2,0,47,0,2,0,18,0,2,0,20,0,0,0,48,0,33,0,21,0,33, +0,0,0,33,0,1,0,34,0,49,0,35,0,50,0,24,0,51,0,24,0,52,0,2,0,46,0,2,0,47,0,2, +0,53,0,2,0,54,0,2,0,55,0,2,0,56,0,2,0,20,0,2,0,57,0,7,0,11,0,7,0,12,0,4, +0,58,0,7,0,59,0,7,0,60,0,7,0,61,0,31,0,62,0,36,0,7,0,27,0,31,0,12,0,63,0,24, +0,64,0,2,0,46,0,2,0,65,0,2,0,66,0,2,0,37,0,37,0,16,0,37,0,0,0,37,0,1,0,7, +0,67,0,7,0,61,0,2,0,18,0,2,0,47,0,2,0,68,0,2,0,20,0,4,0,69,0,4,0,70,0,9, +0,2,0,7,0,71,0,0,0,17,0,0,0,72,0,7,0,73,0,7,0,74,0,38,0,12,0,27,0,31,0,37, +0,75,0,0,0,76,0,4,0,77,0,7,0,61,0,12,0,78,0,36,0,79,0,27,0,80,0,2,0,18,0,2, +0,81,0,2,0,82,0,2,0,20,0,39,0,5,0,27,0,83,0,2,0,84,0,2,0,85,0,2,0,86,0,4, +0,37,0,40,0,6,0,40,0,0,0,40,0,1,0,0,0,87,0,0,0,88,0,4,0,23,0,4,0,89,0,41, +0,10,0,41,0,0,0,41,0,1,0,4,0,90,0,4,0,91,0,4,0,92,0,4,0,43,0,4,0,14,0,4, +0,93,0,0,0,94,0,0,0,95,0,42,0,15,0,27,0,31,0,0,0,96,0,4,0,93,0,4,0,97,0,12, +0,98,0,40,0,99,0,40,0,100,0,4,0,101,0,4,0,102,0,12,0,103,0,0,0,104,0,4,0,105,0,4, +0,106,0,9,0,107,0,8,0,108,0,43,0,5,0,4,0,109,0,4,0,110,0,4,0,93,0,4,0,37,0,9, +0,2,0,44,0,20,0,27,0,31,0,2,0,18,0,2,0,20,0,7,0,111,0,7,0,112,0,7,0,113,0,7, +0,114,0,7,0,115,0,7,0,116,0,7,0,117,0,7,0,118,0,7,0,119,0,7,0,120,0,7,0,121,0,2, +0,122,0,2,0,123,0,7,0,124,0,36,0,79,0,39,0,125,0,32,0,126,0,45,0,12,0,4,0,127,0,4, +0,-128,0,4,0,-127,0,4,0,-126,0,2,0,-125,0,2,0,-124,0,2,0,20,0,2,0,-123,0,2,0,-122,0,2, +0,-121,0,2,0,-120,0,2,0,-119,0,46,0,32,0,27,0,31,0,0,0,34,0,12,0,-118,0,47,0,-117,0,48, +0,-116,0,49,0,-115,0,2,0,-123,0,2,0,20,0,2,0,-114,0,2,0,18,0,2,0,37,0,2,0,43,0,4, +0,-113,0,2,0,-112,0,2,0,-111,0,2,0,-110,0,2,0,-109,0,2,0,-108,0,2,0,-107,0,4,0,-106,0,4, +0,-105,0,43,0,-104,0,30,0,-103,0,7,0,-102,0,4,0,-101,0,2,0,-100,0,2,0,-99,0,2,0,-98,0,2, +0,-97,0,7,0,-96,0,7,0,-95,0,9,0,-94,0,50,0,31,0,2,0,-93,0,2,0,-92,0,2,0,-91,0,2, +0,-90,0,32,0,-89,0,51,0,-88,0,0,0,-87,0,0,0,-86,0,0,0,-85,0,0,0,-84,0,0,0,-83,0,7, +0,-82,0,7,0,-81,0,2,0,-80,0,2,0,-79,0,2,0,-78,0,2,0,-77,0,2,0,-76,0,2,0,-75,0,2, +0,-74,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7,0,-69,0,7,0,57,0,7,0,-68,0,7, +0,-67,0,7,0,-66,0,7,0,-65,0,7,0,-64,0,52,0,15,0,0,0,-63,0,9,0,-62,0,0,0,-61,0,0, +0,-60,0,4,0,-59,0,4,0,-58,0,9,0,-57,0,7,0,-56,0,7,0,-55,0,7,0,-54,0,4,0,-53,0,9, +0,-52,0,9,0,-51,0,4,0,-50,0,4,0,37,0,53,0,6,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, +0,-49,0,7,0,67,0,4,0,64,0,54,0,5,0,2,0,20,0,2,0,36,0,2,0,64,0,2,0,-48,0,53, +0,-54,0,55,0,17,0,32,0,-89,0,46,0,-47,0,56,0,-46,0,7,0,-45,0,7,0,-44,0,2,0,18,0,2, +0,-43,0,7,0,113,0,7,0,114,0,7,0,-42,0,4,0,-41,0,2,0,-40,0,2,0,-39,0,4,0,-123,0,4, +0,-113,0,2,0,-38,0,2,0,-37,0,51,0,56,0,27,0,31,0,7,0,-36,0,7,0,-35,0,7,0,-34,0,7, +0,-33,0,7,0,-32,0,7,0,-31,0,7,0,-30,0,7,0,-29,0,7,0,-28,0,7,0,-27,0,7,0,-26,0,7, +0,-25,0,7,0,-24,0,7,0,-23,0,7,0,-22,0,7,0,-21,0,7,0,-20,0,7,0,-19,0,7,0,-18,0,7, +0,-17,0,2,0,-16,0,2,0,-15,0,2,0,-14,0,2,0,-13,0,2,0,-12,0,2,0,-11,0,2,0,-10,0,2, +0,20,0,2,0,18,0,2,0,-43,0,7,0,-9,0,7,0,-8,0,7,0,-7,0,7,0,-6,0,2,0,-5,0,2, +0,-4,0,2,0,-3,0,2,0,-125,0,4,0,23,0,4,0,-128,0,4,0,-127,0,4,0,-126,0,7,0,-2,0,7, +0,-1,0,7,0,-67,0,45,0,0,1,57,0,1,1,36,0,79,0,46,0,-47,0,52,0,2,1,54,0,3,1,55, +0,4,1,30,0,-103,0,0,0,5,1,0,0,6,1,58,0,8,0,7,0,7,1,7,0,8,1,7,0,-81,0,4, +0,20,0,7,0,9,1,7,0,10,1,7,0,11,1,32,0,45,0,59,0,80,0,27,0,31,0,2,0,18,0,2, +0,12,1,4,0,13,1,2,0,-79,0,2,0,14,1,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7, +0,15,1,7,0,16,1,7,0,17,1,7,0,18,1,7,0,19,1,7,0,20,1,7,0,21,1,7,0,22,1,7, +0,23,1,7,0,24,1,7,0,25,1,60,0,26,1,2,0,27,1,2,0,70,0,7,0,113,0,7,0,114,0,7, +0,28,1,7,0,29,1,7,0,30,1,2,0,31,1,2,0,32,1,2,0,33,1,2,0,34,1,0,0,35,1,0, +0,36,1,2,0,37,1,2,0,38,1,2,0,39,1,2,0,40,1,2,0,41,1,7,0,42,1,7,0,43,1,7, +0,44,1,7,0,45,1,2,0,46,1,2,0,43,0,2,0,47,1,2,0,48,1,2,0,49,1,2,0,50,1,7, +0,51,1,7,0,52,1,7,0,53,1,7,0,54,1,7,0,55,1,7,0,56,1,7,0,57,1,7,0,58,1,7, +0,59,1,7,0,60,1,7,0,61,1,7,0,62,1,2,0,63,1,2,0,64,1,4,0,65,1,4,0,66,1,2, +0,67,1,2,0,68,1,2,0,69,1,2,0,70,1,7,0,71,1,7,0,72,1,7,0,73,1,7,0,74,1,2, +0,75,1,2,0,76,1,50,0,77,1,36,0,79,0,30,0,-103,0,39,0,125,0,61,0,2,0,27,0,31,0,36, +0,79,0,62,0,-127,0,27,0,31,0,2,0,-79,0,2,0,20,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, +0,78,1,7,0,79,1,7,0,80,1,7,0,81,1,7,0,82,1,7,0,83,1,7,0,84,1,7,0,85,1,7, +0,86,1,7,0,87,1,7,0,88,1,7,0,89,1,7,0,90,1,7,0,91,1,7,0,92,1,7,0,93,1,7, +0,94,1,7,0,95,1,7,0,96,1,7,0,97,1,7,0,98,1,7,0,99,1,7,0,100,1,7,0,101,1,7, +0,102,1,7,0,103,1,7,0,104,1,2,0,105,1,2,0,106,1,2,0,107,1,0,0,108,1,0,0,109,1,7, +0,110,1,7,0,111,1,2,0,112,1,2,0,113,1,7,0,114,1,7,0,115,1,7,0,116,1,7,0,117,1,2, +0,118,1,2,0,119,1,4,0,13,1,4,0,120,1,2,0,121,1,2,0,122,1,2,0,123,1,2,0,124,1,7, +0,125,1,7,0,126,1,7,0,127,1,7,0,-128,1,7,0,-127,1,7,0,-126,1,7,0,-125,1,7,0,-124,1,7, +0,-123,1,7,0,-122,1,0,0,-121,1,7,0,-120,1,7,0,-119,1,7,0,-118,1,4,0,-117,1,0,0,-116,1,0, +0,47,1,0,0,-115,1,0,0,5,1,2,0,-114,1,2,0,-113,1,2,0,64,1,2,0,-112,1,2,0,-111,1,2, +0,-110,1,7,0,-109,1,7,0,-108,1,7,0,-107,1,7,0,-106,1,7,0,-105,1,2,0,-93,0,2,0,-92,0,54, +0,-104,1,54,0,-103,1,0,0,-102,1,0,0,-101,1,0,0,-100,1,0,0,-99,1,2,0,-98,1,2,0,12,1,7, +0,-97,1,7,0,-96,1,50,0,77,1,57,0,1,1,36,0,79,0,63,0,-95,1,30,0,-103,0,7,0,-94,1,7, +0,-93,1,7,0,-92,1,7,0,-91,1,7,0,-90,1,2,0,-89,1,2,0,70,0,7,0,-88,1,7,0,-87,1,7, +0,-86,1,7,0,-85,1,7,0,-84,1,7,0,-83,1,7,0,-82,1,7,0,-81,1,7,0,-80,1,2,0,-79,1,2, +0,-78,1,7,0,-77,1,7,0,-76,1,7,0,-75,1,7,0,-74,1,7,0,-73,1,4,0,-72,1,4,0,-71,1,4, +0,-70,1,39,0,125,0,12,0,-69,1,64,0,6,0,27,0,31,0,0,0,-68,1,7,0,-67,1,7,0,37,0,65, +0,2,0,43,0,-104,0,66,0,26,0,66,0,0,0,66,0,1,0,67,0,-66,1,4,0,-65,1,4,0,-64,1,4, +0,-63,1,4,0,-62,1,4,0,-61,1,4,0,-60,1,2,0,18,0,2,0,20,0,2,0,-59,1,2,0,-58,1,7, +0,5,0,7,0,6,0,7,0,7,0,7,0,-57,1,7,0,-56,1,7,0,-55,1,7,0,-54,1,7,0,-53,1,7, +0,-52,1,7,0,-51,1,7,0,23,0,7,0,-50,1,7,0,-49,1,68,0,15,0,27,0,31,0,67,0,-66,1,12, +0,-48,1,12,0,-47,1,36,0,79,0,62,0,-46,1,2,0,20,0,2,0,-45,1,4,0,-80,0,7,0,7,1,7, +0,-81,0,7,0,8,1,7,0,-44,1,7,0,-43,1,7,0,-42,1,35,0,10,0,7,0,-41,1,7,0,-40,1,7, +0,-39,1,7,0,-38,1,2,0,-37,1,2,0,-36,1,0,0,-35,1,0,0,-34,1,0,0,-33,1,0,0,-32,1,34, +0,7,0,7,0,-31,1,7,0,-40,1,7,0,-39,1,2,0,-35,1,2,0,-32,1,7,0,-38,1,7,0,37,0,69, +0,21,0,69,0,0,0,69,0,1,0,2,0,18,0,2,0,-30,1,2,0,-32,1,2,0,20,0,2,0,-29,1,2, +0,-28,1,2,0,-27,1,2,0,-26,1,2,0,-25,1,2,0,-24,1,2,0,-23,1,2,0,-22,1,7,0,-21,1,7, +0,-20,1,34,0,49,0,35,0,50,0,2,0,-19,1,2,0,-18,1,4,0,-17,1,70,0,5,0,2,0,-16,1,2, +0,-30,1,0,0,20,0,0,0,37,0,2,0,70,0,71,0,4,0,7,0,5,0,7,0,6,0,7,0,8,0,7, +0,-15,1,72,0,57,0,27,0,31,0,67,0,-66,1,12,0,-14,1,12,0,-47,1,32,0,-13,1,32,0,-12,1,32, +0,-11,1,36,0,79,0,73,0,-10,1,38,0,-9,1,62,0,-46,1,12,0,-8,1,7,0,7,1,7,0,-81,0,7, +0,8,1,4,0,-80,0,2,0,-7,1,2,0,-45,1,2,0,20,0,2,0,-6,1,7,0,-5,1,7,0,-4,1,7, +0,-3,1,2,0,-27,1,2,0,-26,1,2,0,-2,1,2,0,-1,1,4,0,70,0,2,0,23,0,2,0,98,0,2, +0,67,0,2,0,0,2,7,0,1,2,7,0,2,2,7,0,3,2,7,0,4,2,7,0,5,2,7,0,6,2,7, +0,7,2,7,0,8,2,7,0,9,2,7,0,10,2,0,0,11,2,0,0,12,2,64,0,13,2,64,0,14,2,64, +0,15,2,64,0,16,2,4,0,17,2,4,0,18,2,4,0,19,2,4,0,37,0,71,0,20,2,4,0,21,2,4, +0,22,2,70,0,23,2,70,0,24,2,74,0,39,0,27,0,31,0,67,0,-66,1,12,0,25,2,36,0,79,0,38, +0,-9,1,62,0,-46,1,75,0,26,2,76,0,27,2,77,0,28,2,78,0,29,2,79,0,30,2,80,0,31,2,81, +0,32,2,82,0,33,2,74,0,34,2,83,0,35,2,84,0,36,2,84,0,37,2,84,0,38,2,4,0,54,0,4, +0,39,2,4,0,40,2,4,0,41,2,4,0,42,2,4,0,-80,0,7,0,7,1,7,0,-81,0,7,0,8,1,7, +0,43,2,7,0,37,0,2,0,44,2,2,0,20,0,2,0,45,2,2,0,46,2,2,0,-45,1,2,0,47,2,85, +0,48,2,86,0,49,2,9,0,-94,0,77,0,8,0,9,0,50,2,7,0,51,2,4,0,52,2,0,0,20,0,0, +0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,75,0,8,0,4,0,56,2,4,0,57,2,4,0,58,2,4, +0,59,2,0,0,37,0,0,0,-30,1,0,0,60,2,0,0,20,0,79,0,5,0,4,0,56,2,4,0,57,2,0, +0,61,2,0,0,62,2,2,0,20,0,87,0,2,0,4,0,63,2,7,0,-39,1,80,0,3,0,87,0,64,2,4, +0,65,2,4,0,20,0,78,0,6,0,7,0,66,2,2,0,67,2,0,0,20,0,0,0,-30,1,0,0,62,2,0, +0,68,2,81,0,4,0,0,0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,88,0,6,0,46,0,50,2,0, +0,20,0,0,0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,89,0,1,0,7,0,69,2,90,0,5,0,0, +0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,4,0,37,0,82,0,1,0,7,0,70,2,83,0,2,0,4, +0,71,2,4,0,18,0,76,0,7,0,7,0,51,2,46,0,50,2,0,0,20,0,0,0,53,2,2,0,13,1,2, +0,54,2,2,0,55,2,91,0,1,0,7,0,72,2,92,0,1,0,4,0,73,2,93,0,1,0,0,0,74,2,94, +0,1,0,7,0,51,2,95,0,4,0,7,0,-49,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,96,0,1,0,95, +0,52,2,97,0,5,0,4,0,75,2,4,0,76,2,0,0,20,0,0,0,-30,1,0,0,-74,0,98,0,2,0,4, +0,77,2,4,0,76,2,99,0,14,0,99,0,0,0,99,0,1,0,97,0,78,2,96,0,79,2,98,0,80,2,0, +0,81,2,12,0,82,2,12,0,83,2,100,0,84,2,4,0,54,0,4,0,40,2,4,0,39,2,4,0,37,0,78, +0,85,2,85,0,14,0,12,0,86,2,78,0,85,2,0,0,87,2,0,0,88,2,0,0,89,2,0,0,90,2,0, +0,91,2,0,0,92,2,0,0,93,2,0,0,20,0,84,0,36,2,84,0,38,2,2,0,94,2,0,0,95,2,86, +0,8,0,4,0,96,2,4,0,97,2,75,0,98,2,79,0,99,2,4,0,40,2,4,0,39,2,4,0,54,0,4, +0,37,0,101,0,6,0,101,0,0,0,101,0,1,0,4,0,18,0,4,0,13,1,0,0,17,0,0,0,100,2,102, +0,7,0,101,0,101,2,2,0,102,2,2,0,86,2,2,0,103,2,2,0,93,0,9,0,104,2,9,0,105,2,103, +0,3,0,101,0,101,2,32,0,-89,0,0,0,17,0,104,0,5,0,101,0,101,2,32,0,-89,0,0,0,17,0,2, +0,106,2,0,0,107,2,105,0,5,0,101,0,101,2,7,0,91,0,7,0,108,2,4,0,109,2,4,0,110,2,106, +0,5,0,101,0,101,2,32,0,111,2,0,0,72,0,4,0,13,1,4,0,20,0,107,0,13,0,101,0,101,2,32, +0,112,2,32,0,113,2,32,0,114,2,32,0,115,2,7,0,116,2,7,0,117,2,7,0,108,2,7,0,118,2,4, +0,119,2,4,0,120,2,4,0,93,0,4,0,121,2,108,0,5,0,101,0,101,2,2,0,122,2,2,0,20,0,7, +0,123,2,32,0,124,2,109,0,3,0,101,0,101,2,7,0,125,2,4,0,93,0,110,0,10,0,101,0,101,2,7, +0,126,2,4,0,127,2,4,0,37,0,2,0,93,0,2,0,-128,2,2,0,-127,2,2,0,-126,2,7,0,-125,2,0, +0,-124,2,111,0,3,0,101,0,101,2,7,0,37,0,4,0,18,0,112,0,11,0,101,0,101,2,51,0,-123,2,7, +0,-122,2,4,0,-121,2,0,0,-124,2,7,0,-120,2,4,0,-119,2,32,0,-118,2,0,0,-117,2,4,0,-116,2,4, +0,37,0,113,0,10,0,101,0,101,2,32,0,-115,2,46,0,-114,2,4,0,93,0,4,0,-113,2,7,0,-112,2,7, +0,-111,2,0,0,-117,2,4,0,-116,2,4,0,37,0,114,0,3,0,101,0,101,2,7,0,-110,2,4,0,-109,2,115, +0,5,0,101,0,101,2,7,0,-108,2,0,0,-124,2,2,0,20,0,2,0,-107,2,116,0,8,0,101,0,101,2,32, +0,-89,0,7,0,-108,2,7,0,-38,1,7,0,109,0,0,0,-124,2,2,0,20,0,2,0,18,0,117,0,21,0,101, +0,101,2,32,0,-106,2,0,0,-124,2,51,0,-123,2,32,0,-118,2,2,0,20,0,2,0,37,0,7,0,-105,2,7, +0,-104,2,7,0,-103,2,7,0,-5,1,7,0,-102,2,7,0,-101,2,7,0,-100,2,7,0,-99,2,4,0,-119,2,4, +0,-116,2,0,0,-117,2,7,0,-98,2,7,0,-97,2,7,0,43,0,118,0,7,0,101,0,101,2,2,0,-96,2,2, +0,-95,2,4,0,70,0,32,0,-89,0,7,0,-94,2,0,0,-124,2,119,0,9,0,101,0,101,2,32,0,-89,0,7, +0,-93,2,7,0,-92,2,7,0,-99,2,4,0,-91,2,4,0,-90,2,7,0,-89,2,0,0,17,0,120,0,1,0,101, +0,101,2,121,0,5,0,101,0,101,2,122,0,-88,2,123,0,-87,2,124,0,-86,2,125,0,-85,2,126,0,14,0,101, +0,101,2,78,0,-84,2,78,0,-83,2,78,0,-82,2,78,0,-81,2,78,0,-80,2,78,0,-79,2,75,0,-78,2,4, +0,-77,2,4,0,-76,2,2,0,-75,2,2,0,37,0,7,0,-74,2,127,0,-73,2,-128,0,3,0,101,0,101,2,-127, +0,-72,2,-126,0,-73,2,-125,0,4,0,101,0,101,2,32,0,-89,0,4,0,-71,2,4,0,37,0,-124,0,2,0,4, +0,-70,2,7,0,-39,1,-123,0,2,0,4,0,-127,0,4,0,-69,2,-122,0,20,0,101,0,101,2,32,0,-89,0,0, +0,-124,2,2,0,-68,2,2,0,-67,2,2,0,20,0,2,0,37,0,7,0,-66,2,7,0,-65,2,4,0,54,0,4, +0,-64,2,-123,0,-63,2,-124,0,-62,2,4,0,-61,2,4,0,-60,2,4,0,-59,2,4,0,-69,2,7,0,-58,2,7, +0,-57,2,7,0,-56,2,-121,0,8,0,101,0,101,2,-120,0,-55,2,-127,0,-72,2,4,0,-54,2,4,0,-53,2,4, +0,-52,2,2,0,20,0,2,0,57,0,-119,0,5,0,101,0,101,2,32,0,45,0,2,0,-51,2,2,0,20,0,2, +0,-50,2,-118,0,5,0,101,0,101,2,4,0,-49,2,2,0,20,0,2,0,-48,2,7,0,-47,2,-117,0,3,0,101, +0,101,2,-116,0,-46,2,125,0,-85,2,-115,0,10,0,101,0,101,2,32,0,-45,2,32,0,-44,2,0,0,-43,2,7, +0,-42,2,2,0,-41,2,2,0,-40,2,0,0,-39,2,0,0,-38,2,0,0,107,2,-114,0,9,0,101,0,101,2,32, +0,-37,2,0,0,-43,2,7,0,-36,2,7,0,-35,2,0,0,13,1,0,0,122,2,0,0,-34,2,0,0,37,0,-113, +0,24,0,27,0,31,0,2,0,-29,1,2,0,-28,1,2,0,-33,2,2,0,20,0,2,0,-32,2,2,0,-31,2,2, +0,-30,2,2,0,70,0,0,0,-29,2,0,0,-28,2,0,0,-27,2,0,0,18,0,4,0,37,0,7,0,-26,2,7, +0,-25,2,7,0,-24,2,7,0,-23,2,7,0,-22,2,7,0,-21,2,34,0,-20,2,36,0,79,0,38,0,-9,1,80, +0,31,2,-112,0,3,0,-112,0,0,0,-112,0,1,0,0,0,17,0,67,0,3,0,7,0,-19,2,4,0,20,0,4, +0,37,0,32,0,111,0,27,0,31,0,2,0,18,0,2,0,-18,2,4,0,-17,2,4,0,-16,2,4,0,-15,2,0, +0,-14,2,32,0,38,0,32,0,-13,2,32,0,-12,2,32,0,-11,2,32,0,-10,2,36,0,79,0,73,0,-10,1,67, +0,-66,1,-111,0,-9,2,-111,0,-8,2,-110,0,-7,2,9,0,2,0,12,0,-6,2,12,0,25,2,12,0,-47,1,12, +0,-5,2,12,0,-4,2,62,0,-46,1,7,0,7,1,7,0,-3,2,7,0,-2,2,7,0,-81,0,7,0,-1,2,7, +0,8,1,7,0,0,3,7,0,1,3,7,0,-93,2,7,0,2,3,7,0,-45,0,4,0,3,3,2,0,20,0,2, +0,4,3,2,0,5,3,2,0,6,3,2,0,7,3,2,0,8,3,2,0,9,3,2,0,10,3,2,0,11,3,2, +0,12,3,2,0,13,3,2,0,14,3,4,0,15,3,4,0,16,3,4,0,17,3,4,0,18,3,7,0,19,3,7, +0,20,3,7,0,21,3,7,0,22,3,7,0,23,3,7,0,24,3,7,0,25,3,7,0,26,3,7,0,27,3,7, +0,28,3,7,0,29,3,7,0,30,3,0,0,31,3,0,0,32,3,0,0,-45,1,0,0,33,3,0,0,34,3,0, +0,35,3,7,0,36,3,7,0,37,3,39,0,125,0,12,0,38,3,12,0,39,3,12,0,40,3,12,0,41,3,7, +0,42,3,2,0,71,2,2,0,43,3,7,0,52,2,4,0,44,3,4,0,45,3,-109,0,46,3,2,0,47,3,2, +0,-38,0,7,0,48,3,12,0,49,3,12,0,50,3,12,0,51,3,12,0,52,3,-108,0,53,3,-107,0,54,3,63, +0,55,3,2,0,56,3,2,0,57,3,2,0,58,3,2,0,59,3,7,0,44,2,2,0,60,3,2,0,61,3,-116, +0,62,3,-127,0,63,3,-127,0,64,3,4,0,65,3,4,0,66,3,4,0,67,3,4,0,70,0,9,0,-94,0,12, +0,68,3,-106,0,14,0,-106,0,0,0,-106,0,1,0,32,0,38,0,7,0,-93,2,7,0,9,1,7,0,-92,2,7, +0,-99,2,0,0,17,0,4,0,-91,2,4,0,-90,2,4,0,69,3,2,0,18,0,2,0,70,3,7,0,-89,2,-108, +0,36,0,2,0,71,3,2,0,72,3,2,0,20,0,2,0,-99,2,7,0,73,3,7,0,74,3,7,0,75,3,7, +0,76,3,7,0,77,3,7,0,78,3,7,0,79,3,7,0,80,3,7,0,81,3,7,0,82,3,7,0,83,3,7, +0,84,3,7,0,85,3,7,0,86,3,7,0,87,3,7,0,88,3,7,0,89,3,7,0,90,3,7,0,91,3,7, +0,92,3,7,0,93,3,7,0,94,3,7,0,95,3,7,0,96,3,2,0,97,3,2,0,98,3,2,0,99,3,2, +0,100,3,51,0,-88,0,-105,0,101,3,7,0,102,3,4,0,110,2,125,0,5,0,4,0,20,0,4,0,103,3,4, +0,104,3,4,0,105,3,4,0,106,3,-104,0,1,0,7,0,-31,1,-109,0,30,0,4,0,20,0,7,0,107,3,7, +0,108,3,7,0,109,3,4,0,110,3,4,0,111,3,4,0,112,3,4,0,113,3,7,0,114,3,7,0,115,3,7, +0,116,3,7,0,117,3,7,0,118,3,7,0,119,3,7,0,120,3,7,0,121,3,7,0,122,3,7,0,123,3,7, +0,124,3,7,0,125,3,7,0,126,3,7,0,127,3,7,0,-128,3,7,0,-127,3,7,0,-126,3,7,0,-125,3,4, +0,-124,3,4,0,-123,3,7,0,-122,3,7,0,27,3,-107,0,49,0,-120,0,-121,3,4,0,-120,3,4,0,-119,3,-103, +0,-118,3,-102,0,-117,3,0,0,37,0,0,0,-116,3,2,0,-115,3,7,0,-114,3,0,0,-113,3,7,0,-112,3,7, +0,-111,3,7,0,-110,3,7,0,-109,3,7,0,-108,3,7,0,-107,3,7,0,-106,3,7,0,-105,3,7,0,-104,3,2, +0,-103,3,0,0,-102,3,2,0,-101,3,7,0,-100,3,7,0,-99,3,0,0,-98,3,4,0,-126,0,4,0,-97,3,4, +0,-96,3,2,0,-95,3,2,0,-94,3,-104,0,-93,3,4,0,-92,3,4,0,81,0,7,0,-91,3,7,0,-90,3,7, +0,-89,3,7,0,-88,3,2,0,-87,3,2,0,-86,3,2,0,-85,3,2,0,-84,3,2,0,-83,3,2,0,-82,3,2, +0,-81,3,2,0,-80,3,-101,0,-79,3,7,0,-78,3,7,0,-77,3,125,0,-76,3,-116,0,48,0,2,0,18,0,2, +0,-75,3,2,0,-74,3,2,0,-73,3,7,0,-72,3,2,0,-71,3,2,0,-70,3,7,0,-69,3,2,0,-68,3,2, +0,-67,3,7,0,-66,3,7,0,-65,3,7,0,-64,3,7,0,-63,3,7,0,-62,3,7,0,-61,3,4,0,-60,3,7, +0,-59,3,7,0,-58,3,7,0,-57,3,74,0,-56,3,74,0,-55,3,74,0,-54,3,0,0,-53,3,7,0,-52,3,7, +0,-51,3,36,0,79,0,2,0,-50,3,0,0,-49,3,0,0,-48,3,7,0,-47,3,4,0,-46,3,7,0,-45,3,7, +0,-44,3,4,0,-43,3,4,0,20,0,7,0,-42,3,7,0,-41,3,7,0,-40,3,78,0,-39,3,7,0,-38,3,7, +0,-37,3,7,0,-36,3,7,0,-35,3,7,0,-34,3,7,0,-33,3,7,0,-32,3,4,0,-31,3,-100,0,71,0,27, +0,31,0,2,0,-79,0,2,0,14,1,2,0,47,1,2,0,-30,3,7,0,-29,3,7,0,-28,3,7,0,-27,3,7, +0,-26,3,7,0,-25,3,7,0,-24,3,7,0,-23,3,7,0,-22,3,7,0,84,1,7,0,86,1,7,0,85,1,7, +0,-21,3,4,0,-20,3,7,0,-19,3,7,0,-18,3,7,0,-17,3,7,0,-16,3,7,0,-15,3,7,0,-14,3,7, +0,-13,3,2,0,-12,3,2,0,13,1,2,0,-11,3,2,0,-10,3,2,0,-9,3,2,0,-8,3,2,0,-7,3,2, +0,-6,3,7,0,-5,3,7,0,-4,3,7,0,-3,3,7,0,-2,3,7,0,-1,3,7,0,0,4,7,0,1,4,7, +0,2,4,7,0,3,4,7,0,4,4,7,0,5,4,7,0,6,4,2,0,7,4,2,0,8,4,2,0,9,4,2, +0,10,4,7,0,11,4,7,0,12,4,7,0,13,4,7,0,14,4,2,0,15,4,2,0,16,4,2,0,17,4,2, +0,18,4,7,0,19,4,7,0,20,4,7,0,21,4,7,0,22,4,2,0,23,4,2,0,24,4,2,0,25,4,2, +0,43,0,7,0,26,4,7,0,27,4,36,0,79,0,50,0,77,1,30,0,-103,0,39,0,125,0,-99,0,16,0,2, +0,28,4,2,0,29,4,2,0,30,4,2,0,20,0,2,0,31,4,2,0,32,4,2,0,33,4,2,0,34,4,2, +0,35,4,2,0,36,4,2,0,37,4,2,0,38,4,4,0,39,4,7,0,40,4,7,0,41,4,7,0,42,4,-98, +0,8,0,-98,0,0,0,-98,0,1,0,4,0,3,3,4,0,43,4,4,0,20,0,2,0,44,4,2,0,45,4,32, +0,-89,0,-97,0,13,0,9,0,46,4,9,0,47,4,4,0,48,4,4,0,49,4,4,0,50,4,4,0,51,4,4, +0,52,4,4,0,53,4,4,0,54,4,4,0,55,4,4,0,56,4,4,0,37,0,0,0,57,4,-96,0,5,0,9, +0,58,4,9,0,59,4,4,0,60,4,4,0,70,0,0,0,61,4,-95,0,13,0,4,0,18,0,4,0,62,4,4, +0,63,4,4,0,64,4,4,0,65,4,4,0,66,4,4,0,93,0,4,0,67,4,4,0,68,4,4,0,69,4,4, +0,70,4,4,0,71,4,26,0,30,0,-94,0,4,0,4,0,72,4,7,0,73,4,2,0,20,0,2,0,68,2,-93, +0,11,0,-93,0,0,0,-93,0,1,0,0,0,17,0,62,0,74,4,63,0,75,4,4,0,3,3,4,0,76,4,4, +0,77,4,4,0,37,0,4,0,78,4,4,0,79,4,-92,0,-126,0,-97,0,80,4,-96,0,81,4,-95,0,82,4,4, +0,83,4,4,0,-126,0,4,0,-97,3,4,0,84,4,4,0,85,4,4,0,86,4,4,0,87,4,2,0,20,0,2, +0,88,4,7,0,20,3,7,0,89,4,7,0,90,4,7,0,91,4,7,0,92,4,7,0,93,4,2,0,94,4,2, +0,95,4,2,0,96,4,2,0,97,4,2,0,-39,0,2,0,98,4,2,0,99,4,2,0,100,3,2,0,100,4,2, +0,101,4,2,0,34,1,2,0,109,0,2,0,102,4,2,0,103,4,2,0,104,4,2,0,105,4,2,0,106,4,2, +0,107,4,2,0,108,4,2,0,109,4,2,0,110,4,2,0,35,1,2,0,111,4,2,0,112,4,2,0,113,4,2, +0,114,4,4,0,115,4,4,0,13,1,2,0,116,4,2,0,117,4,2,0,118,4,2,0,119,4,2,0,120,4,2, +0,121,4,24,0,122,4,24,0,123,4,23,0,124,4,12,0,125,4,2,0,126,4,2,0,37,0,7,0,127,4,7, +0,-128,4,7,0,-127,4,7,0,-126,4,7,0,-125,4,7,0,-124,4,7,0,-123,4,7,0,-122,4,7,0,-121,4,2, +0,-120,4,2,0,-119,4,2,0,-118,4,2,0,-117,4,2,0,-116,4,2,0,-115,4,7,0,-114,4,7,0,-113,4,7, +0,-112,4,2,0,-111,4,2,0,-110,4,2,0,-109,4,2,0,-108,4,2,0,-107,4,2,0,-106,4,2,0,-105,4,2, +0,-104,4,2,0,-103,4,2,0,-102,4,4,0,-101,4,4,0,-100,4,4,0,-99,4,4,0,-98,4,4,0,-97,4,7, +0,-96,4,4,0,-95,4,4,0,-94,4,4,0,-93,4,4,0,-92,4,7,0,-91,4,7,0,-90,4,7,0,-89,4,7, +0,-88,4,7,0,-87,4,7,0,-86,4,7,0,-85,4,7,0,-84,4,7,0,-83,4,0,0,-82,4,0,0,-81,4,4, +0,-80,4,2,0,-79,4,2,0,12,1,0,0,-78,4,7,0,-77,4,7,0,-76,4,4,0,-75,4,4,0,-74,4,7, +0,-73,4,7,0,-72,4,2,0,-71,4,2,0,-70,4,7,0,-69,4,2,0,-68,4,2,0,-67,4,4,0,-66,4,2, +0,-65,4,2,0,-64,4,2,0,-63,4,2,0,-62,4,7,0,-61,4,7,0,70,0,42,0,-60,4,-91,0,9,0,-91, +0,0,0,-91,0,1,0,0,0,17,0,2,0,-59,4,2,0,-58,4,2,0,-57,4,2,0,43,0,7,0,-56,4,7, +0,70,0,-90,0,5,0,7,0,-55,4,0,0,18,0,0,0,43,0,0,0,70,0,0,0,12,1,-89,0,5,0,-89, +0,0,0,-89,0,1,0,4,0,-54,4,0,0,-53,4,4,0,20,0,-88,0,5,0,-87,0,-52,4,2,0,20,0,2, +0,-51,4,2,0,-50,4,2,0,-49,4,-86,0,4,0,2,0,109,0,2,0,-122,2,2,0,-48,4,2,0,-47,4,-85, +0,7,0,2,0,20,0,2,0,-46,4,2,0,-45,4,2,0,-44,4,-86,0,-43,4,7,0,-42,4,4,0,-41,4,-84, +0,4,0,-84,0,0,0,-84,0,1,0,0,0,-40,4,7,0,-39,4,-83,0,56,0,2,0,-38,4,2,0,-37,4,7, +0,-36,4,7,0,-35,4,2,0,-48,4,2,0,-34,4,7,0,-33,4,7,0,-32,4,2,0,-31,4,2,0,-30,4,2, +0,-29,4,2,0,-28,4,7,0,-27,4,7,0,-26,4,7,0,-25,4,7,0,37,0,2,0,-24,4,2,0,-23,4,2, +0,-22,4,2,0,-21,4,-88,0,-20,4,-85,0,-19,4,7,0,-18,4,7,0,-17,4,0,0,-16,4,0,0,-15,4,0, +0,-14,4,0,0,-13,4,0,0,-12,4,0,0,-11,4,2,0,-10,4,7,0,-9,4,7,0,-8,4,7,0,-7,4,7, +0,-6,4,7,0,-5,4,7,0,-4,4,7,0,-3,4,7,0,-2,4,7,0,-1,4,7,0,0,5,2,0,1,5,0, +0,2,5,0,0,3,5,0,0,4,5,0,0,5,5,32,0,6,5,0,0,7,5,0,0,8,5,0,0,9,5,0, +0,10,5,0,0,11,5,0,0,12,5,0,0,13,5,0,0,14,5,0,0,15,5,-82,0,6,0,2,0,109,0,0, +0,-122,2,0,0,16,5,0,0,17,5,0,0,20,0,0,0,-74,0,-81,0,26,0,-80,0,18,5,50,0,77,1,60, +0,19,5,-82,0,20,5,-82,0,21,5,-82,0,22,5,-82,0,23,5,-82,0,24,5,-82,0,25,5,-82,0,26,5,7, +0,27,5,2,0,28,5,2,0,47,1,2,0,29,5,2,0,1,2,0,0,30,5,0,0,31,5,0,0,32,5,0, +0,33,5,0,0,93,0,0,0,34,5,0,0,35,5,0,0,36,5,0,0,37,5,0,0,38,5,0,0,-74,0,-79, +0,43,0,27,0,31,0,32,0,39,5,-100,0,40,5,-79,0,41,5,46,0,-47,0,12,0,42,5,-98,0,43,5,7, +0,44,5,7,0,45,5,7,0,46,5,7,0,47,5,4,0,3,3,7,0,48,5,2,0,49,5,2,0,50,5,2, +0,51,5,2,0,52,5,2,0,53,5,2,0,54,5,2,0,55,5,2,0,5,1,57,0,1,1,9,0,56,5,-99, +0,57,5,-90,0,58,5,-83,0,59,5,-92,0,-73,0,-94,0,60,5,39,0,125,0,12,0,103,0,12,0,61,5,2, +0,62,5,2,0,63,5,2,0,64,5,2,0,65,5,-78,0,66,5,2,0,67,5,2,0,68,5,2,0,64,1,2, +0,-38,0,-81,0,69,5,4,0,70,5,4,0,37,0,-77,0,9,0,46,0,-47,0,45,0,0,1,7,0,8,2,7, +0,9,2,7,0,109,0,7,0,71,5,7,0,72,5,2,0,73,5,2,0,74,5,-76,0,75,0,-75,0,0,0,-75, +0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,7,0,79,5,7,0,80,5,7,0,81,5,7, +0,82,5,7,0,83,5,7,0,84,5,7,0,85,5,7,0,20,1,7,0,86,5,4,0,87,5,2,0,88,5,2, +0,17,5,32,0,39,5,32,0,89,5,-77,0,90,5,-76,0,91,5,-73,0,92,5,-72,0,93,5,-71,0,94,5,0, +0,95,5,2,0,30,4,2,0,96,5,4,0,3,3,4,0,97,5,2,0,98,5,2,0,99,5,2,0,100,5,0, +0,101,5,0,0,43,0,7,0,115,0,7,0,102,5,7,0,103,5,7,0,104,5,7,0,105,5,7,0,106,5,7, +0,107,5,7,0,108,5,7,0,-82,0,7,0,44,5,2,0,109,5,2,0,110,5,2,0,111,5,2,0,112,5,2, +0,-119,0,2,0,29,5,2,0,113,5,2,0,114,5,2,0,115,5,2,0,116,5,7,0,117,5,7,0,118,5,67, +0,119,5,12,0,120,5,2,0,121,5,2,0,53,2,2,0,122,5,2,0,20,0,2,0,123,5,2,0,124,5,2, +0,125,5,0,0,126,5,0,0,127,5,9,0,-128,5,-70,0,-127,5,7,0,-126,5,2,0,-125,5,2,0,-124,5,2, +0,53,5,2,0,54,5,-69,0,19,0,24,0,36,0,24,0,64,0,23,0,-123,5,23,0,-122,5,23,0,-121,5,7, +0,-120,5,7,0,-119,5,7,0,-118,5,7,0,-117,5,2,0,-116,5,2,0,-115,5,2,0,-114,5,2,0,-113,5,2, +0,-112,5,2,0,-111,5,4,0,20,0,7,0,-110,5,2,0,99,5,0,0,107,2,-75,0,6,0,-75,0,0,0,-75, +0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-68,0,6,0,-75,0,0,0,-75,0,1,0,4, +0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-67,0,27,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7, +0,76,5,-74,0,77,5,2,0,78,5,4,0,-109,5,4,0,70,0,-69,0,-108,5,9,0,-107,5,12,0,-106,5,36, +0,79,0,27,0,80,0,0,0,-105,5,0,0,-104,5,0,0,-103,5,2,0,-102,5,2,0,-101,5,2,0,-100,5,2, +0,-99,5,2,0,65,0,2,0,46,0,2,0,-119,0,2,0,-98,5,4,0,20,0,7,0,-97,5,24,0,36,0,-66, +0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-73,0,92,5,2,0,78,5,2, +0,-96,5,2,0,-95,5,2,0,-94,5,2,0,-93,5,-69,0,-108,5,2,0,-92,5,2,0,-119,0,2,0,-101,5,2, +0,-91,5,9,0,-90,5,2,0,29,5,0,0,-89,5,0,0,-88,5,2,0,-87,5,2,0,-86,5,2,0,12,3,2, +0,-85,5,2,0,-84,5,0,0,37,0,0,0,20,0,0,0,47,1,0,0,-83,5,-65,0,16,0,-75,0,0,0,-75, +0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69,0,-108,5,7,0,8,2,7,0,9,2,2, +0,-92,5,2,0,-82,5,2,0,-81,5,2,0,-80,5,4,0,20,0,7,0,71,5,-70,0,-127,5,-64,0,33,0,-75, +0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-63,0,-79,5,4,0,-78,5,0, +0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-74,5,2,0,20,0,2,0,-73,5,2,0,-72,5,2, +0,-71,5,2,0,-70,5,2,0,43,0,4,0,70,0,0,0,-69,5,-62,0,-68,5,2,0,-67,5,2,0,-66,5,2, +0,-65,5,2,0,-48,0,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9,0,-60,5,2,0,-59,5,0, +0,-58,5,-61,0,23,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, +0,-108,5,12,0,-57,5,2,0,-101,5,2,0,-56,5,2,0,20,0,2,0,57,0,9,0,-90,5,12,0,-55,5,-60, +0,-54,5,0,0,-53,5,-59,0,-52,5,4,0,-51,5,4,0,-50,5,2,0,18,0,2,0,-49,5,2,0,-48,5,2, +0,-47,5,-58,0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, +0,-108,5,46,0,-114,2,45,0,0,1,60,0,19,5,2,0,13,1,2,0,-119,0,2,0,-46,5,2,0,-45,5,4, +0,20,0,2,0,49,5,2,0,-44,5,2,0,-98,5,2,0,-101,5,7,0,71,5,0,0,-43,5,0,0,-42,5,0, +0,-41,5,0,0,-40,5,7,0,8,2,7,0,9,2,7,0,-39,5,7,0,-38,5,-70,0,-127,5,-57,0,11,0,-75, +0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,2,0,-119,0,2,0,-98,5,2, +0,-37,5,2,0,20,0,-69,0,-108,5,-56,0,24,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, +0,77,5,2,0,78,5,42,0,-36,5,4,0,-35,5,4,0,-34,5,2,0,93,0,2,0,-119,0,4,0,-33,5,4, +0,-32,5,4,0,-31,5,4,0,-30,5,4,0,-29,5,4,0,-28,5,4,0,-27,5,4,0,-26,5,7,0,-25,5,23, +0,-24,5,23,0,-23,5,4,0,-22,5,4,0,-21,5,-55,0,10,0,27,0,31,0,9,0,-20,5,9,0,-19,5,9, +0,-18,5,9,0,-17,5,9,0,-16,5,4,0,93,0,4,0,-15,5,0,0,-14,5,0,0,-13,5,-54,0,10,0,-75, +0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-55,0,-12,5,2,0,93,0,2,0,-119,0,4, +0,43,0,9,0,-11,5,-53,0,8,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-69, +0,-108,5,4,0,20,0,4,0,-10,5,-52,0,21,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, +0,77,5,2,0,78,5,-69,0,-108,5,27,0,-9,5,27,0,80,0,2,0,20,0,2,0,-119,0,7,0,-8,5,9, +0,-7,5,7,0,8,2,7,0,9,2,57,0,1,1,57,0,-6,5,4,0,-5,5,2,0,-89,5,2,0,37,0,-70, +0,-127,5,-51,0,42,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, +0,-108,5,-50,0,-4,5,0,0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-66,5,2,0,20,0,2, +0,-73,5,9,0,-7,5,4,0,-3,5,4,0,-2,5,4,0,-1,5,4,0,0,6,23,0,1,6,23,0,2,6,7, +0,3,6,7,0,4,6,7,0,5,6,7,0,-8,5,2,0,-67,5,2,0,-48,0,2,0,102,1,2,0,6,6,2, +0,37,0,2,0,43,0,2,0,7,6,2,0,8,6,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9, +0,-60,5,2,0,-59,5,0,0,-58,5,56,0,9,6,-49,0,20,0,0,0,10,6,0,0,11,6,0,0,12,6,0, +0,13,6,0,0,14,6,0,0,15,6,0,0,16,6,0,0,17,6,0,0,18,6,0,0,19,6,0,0,20,6,0, +0,21,6,0,0,22,6,0,0,23,6,0,0,24,6,0,0,25,6,0,0,26,6,0,0,27,6,0,0,68,2,0, +0,28,6,-48,0,54,0,0,0,29,6,0,0,20,6,0,0,21,6,0,0,30,6,0,0,31,6,0,0,32,6,0, +0,33,6,0,0,34,6,0,0,35,6,0,0,36,6,0,0,37,6,0,0,38,6,0,0,39,6,0,0,40,6,0, +0,41,6,0,0,42,6,0,0,43,6,0,0,44,6,0,0,45,6,0,0,46,6,0,0,47,6,0,0,48,6,0, +0,49,6,0,0,50,6,0,0,51,6,0,0,52,6,0,0,53,6,0,0,54,6,0,0,55,6,0,0,56,6,0, +0,57,6,0,0,58,6,0,0,95,0,0,0,59,6,0,0,60,6,0,0,61,6,0,0,62,6,0,0,63,6,0, +0,64,6,0,0,65,6,0,0,66,6,0,0,67,6,0,0,68,6,0,0,69,6,0,0,70,6,0,0,71,6,0, +0,72,6,0,0,73,6,0,0,74,6,0,0,75,6,0,0,76,6,0,0,77,6,0,0,78,6,0,0,79,6,-47, +0,5,0,0,0,80,6,0,0,37,6,0,0,39,6,2,0,20,0,2,0,37,0,-46,0,22,0,-46,0,0,0,-46, +0,1,0,0,0,17,0,-49,0,81,6,-48,0,82,6,-48,0,83,6,-48,0,84,6,-48,0,85,6,-48,0,86,6,-48, +0,87,6,-48,0,88,6,-48,0,89,6,-48,0,90,6,-48,0,91,6,-48,0,92,6,-48,0,93,6,-48,0,94,6,-48, +0,95,6,-48,0,96,6,-47,0,97,6,0,0,98,6,0,0,99,6,-45,0,5,0,4,0,20,0,4,0,37,0,7, +0,52,2,7,0,100,6,7,0,-31,1,-44,0,66,0,4,0,20,0,4,0,101,6,4,0,102,6,0,0,103,6,0, +0,104,6,0,0,105,6,0,0,106,6,0,0,107,6,0,0,108,6,0,0,109,6,0,0,110,6,0,0,111,6,2, +0,112,6,2,0,113,6,4,0,114,6,4,0,115,6,4,0,116,6,4,0,117,6,2,0,118,6,2,0,119,6,2, +0,120,6,2,0,121,6,4,0,122,6,4,0,123,6,2,0,124,6,2,0,125,6,2,0,126,6,2,0,127,6,0, +0,-128,6,12,0,-127,6,2,0,-126,6,2,0,-125,6,2,0,-124,6,2,0,-123,6,2,0,-122,6,2,0,-121,6,2, +0,-120,6,2,0,-119,6,-45,0,-118,6,2,0,-117,6,2,0,-116,6,2,0,-115,6,2,0,-114,6,4,0,-113,6,4, +0,-112,6,4,0,-111,6,4,0,-110,6,2,0,-109,6,2,0,-108,6,2,0,-107,6,2,0,-106,6,2,0,-105,6,2, +0,-104,6,2,0,-103,6,2,0,-102,6,2,0,-101,6,2,0,-100,6,2,0,-99,6,2,0,37,0,0,0,-98,6,0, +0,-97,6,0,0,-96,6,7,0,-95,6,2,0,55,5,2,0,-94,6,54,0,-93,6,-43,0,18,0,27,0,31,0,12, +0,-92,6,12,0,-91,6,12,0,-90,6,-79,0,-89,6,2,0,-105,2,2,0,-88,6,2,0,-104,2,2,0,-87,6,2, +0,-86,6,2,0,-85,6,2,0,-84,6,2,0,-83,6,2,0,-82,6,2,0,37,0,2,0,-81,6,2,0,-80,6,2, +0,-79,6,-42,0,5,0,-42,0,0,0,-42,0,1,0,-42,0,-78,6,13,0,-77,6,4,0,20,0,-41,0,7,0,-41, +0,0,0,-41,0,1,0,-42,0,-76,6,-42,0,-75,6,2,0,123,4,2,0,20,0,4,0,37,0,-40,0,17,0,-40, +0,0,0,-40,0,1,0,0,0,-74,6,0,0,-73,6,0,0,-72,6,2,0,-71,6,2,0,-70,6,2,0,-86,6,2, +0,-85,6,2,0,20,0,2,0,70,3,2,0,-69,6,2,0,-68,6,2,0,-67,6,2,0,-66,6,4,0,-65,6,-40, +0,-64,6,-74,0,30,0,-74,0,0,0,-74,0,1,0,-42,0,-76,6,-42,0,-75,6,-42,0,-63,6,-42,0,-62,6,-43, +0,-61,6,7,0,-60,6,23,0,52,0,23,0,-59,6,23,0,-58,6,2,0,-57,6,2,0,-56,6,2,0,-55,6,0, +0,75,5,0,0,-54,6,2,0,-53,6,2,0,-52,6,0,0,-51,6,0,0,-50,6,0,0,-49,6,0,0,-48,6,2, +0,-47,6,2,0,-46,6,2,0,-45,6,2,0,20,0,39,0,125,0,12,0,-44,6,12,0,-43,6,12,0,-42,6,-39, +0,11,0,0,0,-41,6,2,0,-40,6,2,0,-39,6,2,0,-38,6,2,0,-37,6,2,0,-36,6,2,0,107,4,9, +0,-35,6,9,0,-34,6,4,0,-33,6,4,0,-32,6,-38,0,1,0,0,0,-31,6,-37,0,8,0,56,0,-30,6,56, +0,-29,6,-37,0,-28,6,-37,0,-27,6,-37,0,-26,6,2,0,-123,0,2,0,20,0,4,0,-25,6,-36,0,4,0,4, +0,-35,5,4,0,-24,6,4,0,-31,5,4,0,-23,6,-35,0,2,0,4,0,-22,6,4,0,-21,6,-34,0,9,0,7, +0,-20,6,7,0,-19,6,7,0,-18,6,4,0,20,0,4,0,13,1,7,0,-19,3,7,0,-17,6,4,0,37,0,-33, +0,-16,6,-32,0,6,0,0,0,-15,6,0,0,-75,5,48,0,-116,0,2,0,109,0,2,0,111,4,4,0,37,0,-31, +0,21,0,-31,0,0,0,-31,0,1,0,4,0,57,0,4,0,23,0,4,0,28,0,4,0,-14,6,4,0,-13,6,4, +0,-12,6,-38,0,-11,6,0,0,-15,6,4,0,-10,6,4,0,-9,6,-32,0,-12,2,-36,0,-8,6,-35,0,-7,6,-34, +0,-6,6,-37,0,-5,6,-37,0,-4,6,-37,0,-3,6,56,0,-2,6,56,0,-1,6,-30,0,12,0,0,0,-68,1,9, +0,-62,0,0,0,-61,0,4,0,-58,0,4,0,-50,0,9,0,-57,0,7,0,-55,0,7,0,-54,0,9,0,0,7,9, +0,1,7,9,0,-53,0,9,0,-51,0,-29,0,43,0,-29,0,0,0,-29,0,1,0,9,0,2,7,9,0,26,0,0, +0,27,0,4,0,20,0,4,0,18,0,4,0,23,0,4,0,91,0,4,0,3,7,4,0,4,7,4,0,-13,6,4, +0,-12,6,4,0,5,7,4,0,-39,0,4,0,6,7,4,0,7,7,7,0,8,7,7,0,9,7,4,0,-126,0,4, +0,10,7,-31,0,11,7,36,0,79,0,-79,0,-89,6,48,0,-116,0,7,0,12,7,7,0,13,7,-30,0,2,1,-29, +0,14,7,-29,0,15,7,-29,0,16,7,12,0,17,7,-28,0,18,7,-27,0,19,7,7,0,20,7,7,0,21,7,4, +0,-84,6,7,0,22,7,9,0,23,7,4,0,24,7,4,0,25,7,4,0,26,7,7,0,27,7,-26,0,4,0,-26, +0,0,0,-26,0,1,0,12,0,28,7,-29,0,29,7,-25,0,6,0,12,0,30,7,12,0,17,7,12,0,31,7,2, +0,20,0,2,0,37,0,4,0,57,0,-24,0,4,0,7,0,32,7,7,0,112,0,2,0,33,7,2,0,34,7,-23, +0,6,0,7,0,35,7,7,0,36,7,7,0,37,7,7,0,38,7,4,0,39,7,4,0,40,7,-22,0,12,0,7, +0,41,7,7,0,42,7,7,0,43,7,7,0,44,7,7,0,45,7,7,0,46,7,7,0,47,7,7,0,48,7,7, +0,49,7,7,0,50,7,4,0,-110,2,4,0,51,7,-21,0,2,0,7,0,-55,4,7,0,37,0,-20,0,7,0,7, +0,52,7,7,0,53,7,4,0,93,0,4,0,108,2,4,0,54,7,4,0,55,7,4,0,37,0,-19,0,6,0,-19, +0,0,0,-19,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,-18,0,8,0,-18,0,0,0,-18, +0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,7,0,23,0,7,0,-126,0,-17,0,45,0,-17, +0,0,0,-17,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,2,0,-103,3,2,0,57,7,7, +0,58,7,7,0,92,0,7,0,-97,2,4,0,59,7,4,0,81,0,4,0,110,2,7,0,60,7,7,0,61,7,7, +0,62,7,7,0,63,7,7,0,64,7,7,0,65,7,7,0,-100,2,7,0,-1,0,7,0,66,7,7,0,67,7,7, +0,37,0,7,0,68,7,7,0,69,7,7,0,70,7,2,0,71,7,2,0,72,7,2,0,73,7,2,0,74,7,2, +0,75,7,2,0,76,7,2,0,77,7,2,0,78,7,2,0,123,5,2,0,79,7,2,0,-47,1,2,0,80,7,0, +0,81,7,0,0,82,7,7,0,-45,0,-16,0,83,7,63,0,-95,1,-15,0,16,0,-15,0,0,0,-15,0,1,0,2, +0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,7,0,-105,2,7,0,-104,2,7,0,-103,2,7,0,-5,1,7, +0,-102,2,7,0,-101,2,7,0,84,7,7,0,-100,2,7,0,-98,2,7,0,-97,2,-59,0,5,0,2,0,18,0,2, +0,-25,6,2,0,20,0,2,0,85,7,27,0,-9,5,-60,0,3,0,4,0,69,0,4,0,86,7,-59,0,2,0,-14, +0,12,0,-14,0,0,0,-14,0,1,0,2,0,18,0,2,0,20,0,2,0,31,3,2,0,-32,1,7,0,5,0,7, +0,6,0,7,0,87,7,7,0,88,7,27,0,-9,5,12,0,89,7,-13,0,11,0,-13,0,0,0,-13,0,1,0,0, +0,17,0,2,0,18,0,2,0,90,7,4,0,22,0,4,0,91,7,2,0,20,0,2,0,37,0,9,0,92,7,9, +0,93,7,-12,0,5,0,0,0,17,0,7,0,20,1,7,0,94,7,4,0,95,7,4,0,37,0,-11,0,4,0,2, +0,18,0,2,0,20,0,2,0,43,0,2,0,70,0,-10,0,4,0,0,0,17,0,62,0,96,7,7,0,20,1,7, +0,37,0,-9,0,6,0,2,0,97,7,2,0,98,7,2,0,18,0,2,0,99,7,0,0,100,7,0,0,101,7,-8, +0,5,0,4,0,18,0,4,0,37,0,0,0,17,0,0,0,102,7,0,0,103,7,-7,0,3,0,4,0,18,0,4, +0,37,0,0,0,17,0,-6,0,4,0,2,0,104,7,2,0,105,7,2,0,20,0,2,0,37,0,-5,0,6,0,0, +0,17,0,0,0,106,7,2,0,107,7,2,0,-100,2,2,0,13,1,2,0,70,0,-4,0,5,0,0,0,17,0,7, +0,112,0,7,0,-17,3,2,0,20,0,2,0,122,2,-3,0,3,0,0,0,17,0,4,0,110,2,4,0,104,7,-2, +0,7,0,0,0,17,0,7,0,-17,3,0,0,108,7,0,0,109,7,2,0,13,1,2,0,43,0,4,0,110,7,-1, +0,3,0,32,0,111,7,0,0,112,7,0,0,113,7,0,1,18,0,0,1,0,0,0,1,1,0,2,0,18,0,2, +0,90,7,2,0,20,0,2,0,114,7,2,0,115,7,2,0,116,7,2,0,43,0,2,0,70,0,0,0,17,0,9, +0,2,0,1,1,117,7,32,0,45,0,2,0,-47,4,2,0,20,7,2,0,118,7,2,0,37,0,2,1,11,0,0, +0,17,0,0,0,18,0,0,0,119,7,2,0,20,0,2,0,122,2,2,0,120,7,4,0,121,7,4,0,122,7,4, +0,123,7,4,0,124,7,4,0,125,7,3,1,1,0,0,0,126,7,4,1,4,0,42,0,-36,5,0,0,127,7,4, +0,13,1,4,0,20,0,1,1,18,0,1,1,0,0,1,1,1,0,1,1,-128,7,2,0,18,0,2,0,20,0,2, +0,-127,7,2,0,116,7,2,0,90,7,2,0,-126,7,2,0,70,0,2,0,12,1,0,0,17,0,9,0,2,0,5, +1,117,7,0,1,-125,7,2,0,15,0,2,0,-124,7,4,0,-123,7,6,1,3,0,4,0,-74,2,4,0,37,0,32, +0,45,0,7,1,12,0,-111,0,-122,7,2,0,18,0,2,0,20,0,4,0,58,7,4,0,92,0,0,0,17,0,0, +0,-121,7,2,0,-120,7,2,0,-119,7,2,0,-118,7,2,0,-117,7,7,0,-116,7,8,1,10,0,2,0,20,0,2, +0,-115,7,4,0,58,7,4,0,92,0,2,0,-114,7,-28,0,18,7,2,0,18,0,2,0,-113,7,2,0,-112,7,2, +0,-111,7,9,1,7,0,2,0,20,0,2,0,-115,7,4,0,58,7,4,0,92,0,2,0,18,0,2,0,-110,7,7, +0,109,3,10,1,11,0,4,0,-74,2,2,0,18,0,2,0,20,0,32,0,45,0,74,0,-109,7,0,0,17,0,7, +0,-108,7,7,0,-107,7,7,0,21,3,2,0,-106,7,2,0,-105,7,11,1,5,0,2,0,18,0,2,0,20,0,4, +0,37,0,-79,0,-89,6,32,0,39,5,12,1,5,0,4,0,20,0,4,0,18,0,0,0,17,0,0,0,102,7,32, +0,45,0,13,1,13,0,2,0,20,0,2,0,18,0,2,0,90,7,2,0,22,3,7,0,-104,7,7,0,-103,7,7, +0,7,1,7,0,8,1,7,0,-3,2,7,0,0,3,7,0,-102,7,7,0,-101,7,32,0,-100,7,14,1,10,0,2, +0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,0,0,-121,7,2,0,43,0,2,0,64,0,2, +0,-99,7,2,0,-98,7,15,1,8,0,32,0,45,0,7,0,-103,2,7,0,-97,7,7,0,-96,7,7,0,-108,2,2, +0,20,0,2,0,122,2,7,0,-95,7,16,1,12,0,2,0,18,0,2,0,13,1,2,0,20,0,2,0,-100,2,2, +0,-74,2,2,0,-94,7,4,0,37,0,7,0,-93,7,7,0,-92,7,7,0,-91,7,7,0,-90,7,0,0,-89,7,17, +1,10,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,2,0,68,2,2,0,64,0,2, +0,-99,7,2,0,-98,7,63,0,-95,1,18,1,7,0,4,0,110,2,4,0,-88,7,4,0,-87,7,4,0,-86,7,7, +0,-85,7,7,0,-84,7,0,0,108,7,19,1,7,0,0,0,-83,7,32,0,-82,7,0,0,112,7,2,0,-81,7,2, +0,43,0,4,0,70,0,0,0,113,7,20,1,6,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0, +0,-80,7,0,0,-79,7,21,1,1,0,4,0,20,0,22,1,6,0,0,0,95,0,2,0,18,0,2,0,20,0,4, +0,-78,7,7,0,-77,7,42,0,-36,5,23,1,4,0,0,0,-74,0,2,0,20,0,4,0,18,0,32,0,45,0,24, +1,2,0,4,0,18,0,4,0,-121,5,5,1,10,0,5,1,0,0,5,1,1,0,5,1,-128,7,2,0,18,0,2, +0,20,0,2,0,90,7,2,0,-76,7,0,0,17,0,9,0,2,0,32,0,45,0,25,1,10,0,7,0,21,3,7, +0,-75,7,7,0,-74,7,7,0,-73,7,7,0,-72,7,4,0,20,0,7,0,-94,7,7,0,-71,7,7,0,-70,7,7, +0,37,0,-28,0,20,0,27,0,31,0,0,0,-63,0,26,1,-69,7,9,0,-68,7,43,0,-104,0,43,0,-67,7,9, +0,-66,7,36,0,79,0,7,0,109,3,7,0,-65,7,7,0,-64,7,7,0,-63,7,7,0,-62,7,7,0,-61,7,7, +0,-60,7,4,0,93,0,4,0,-59,7,0,0,-58,7,0,0,-57,7,0,0,-56,7,27,1,6,0,27,0,31,0,7, +0,-55,7,7,0,-54,7,7,0,-53,7,2,0,-52,7,2,0,-51,7,28,1,14,0,-75,0,0,0,-75,0,1,0,4, +0,75,5,7,0,76,5,-74,0,77,5,-69,0,-108,5,-28,0,18,7,2,0,13,1,2,0,-115,7,2,0,8,2,2, +0,9,2,2,0,20,0,2,0,-98,5,4,0,70,0,29,1,6,0,29,1,0,0,29,1,1,0,32,0,45,0,9, +0,-50,7,4,0,-38,0,4,0,37,0,63,0,4,0,27,0,31,0,12,0,-49,7,4,0,-121,0,7,0,-48,7,30, +1,25,0,30,1,0,0,30,1,1,0,30,1,38,0,12,0,-47,7,0,0,17,0,7,0,-46,7,7,0,-45,7,7, +0,-44,7,7,0,-43,7,4,0,20,0,7,0,-42,7,7,0,-41,7,7,0,-40,7,7,0,20,1,7,0,-39,1,7, +0,-39,7,7,0,108,2,7,0,-38,7,7,0,-37,7,7,0,-36,7,7,0,-35,7,7,0,-34,7,7,0,-81,0,2, +0,-121,0,2,0,-31,4,31,1,19,0,27,0,31,0,12,0,-33,7,12,0,-32,7,4,0,20,0,4,0,30,4,2, +0,-96,2,2,0,-31,7,2,0,-121,0,2,0,-30,7,2,0,-29,7,2,0,-28,7,2,0,-27,7,2,0,-26,7,4, +0,-25,7,4,0,-24,7,4,0,-23,7,4,0,-22,7,4,0,-21,7,4,0,-20,7,32,1,34,0,32,1,0,0,32, +1,1,0,12,0,49,3,0,0,17,0,2,0,20,0,2,0,-19,7,2,0,-18,7,2,0,-17,7,2,0,10,3,2, +0,-16,7,4,0,-7,1,4,0,-23,7,4,0,-22,7,30,1,-15,7,32,1,38,0,32,1,-14,7,12,0,-13,7,9, +0,-12,7,9,0,-11,7,9,0,-10,7,7,0,7,1,7,0,-81,0,7,0,-57,1,7,0,-9,7,7,0,-8,7,7, +0,2,3,7,0,-7,7,7,0,-6,7,7,0,-5,7,7,0,-4,7,7,0,-3,7,7,0,-2,7,7,0,-10,1,32, +0,-1,7,-110,0,9,0,12,0,0,8,2,0,20,0,2,0,1,8,7,0,20,3,7,0,2,8,7,0,3,8,12, +0,4,8,4,0,5,8,4,0,37,0,33,1,7,0,33,1,0,0,33,1,1,0,12,0,-58,7,4,0,20,0,4, +0,6,8,0,0,17,0,-47,0,7,8,34,1,8,0,34,1,0,0,34,1,1,0,33,1,8,8,36,0,79,0,12, +0,-6,2,4,0,20,0,0,0,17,0,4,0,9,8,-111,0,6,0,27,0,31,0,12,0,0,8,12,0,10,8,12, +0,103,0,4,0,11,8,4,0,37,0,35,1,16,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, +0,77,5,2,0,78,5,-69,0,-108,5,-111,0,-9,2,0,0,13,1,0,0,-37,5,2,0,20,0,2,0,12,8,2, +0,-101,5,2,0,-98,5,2,0,13,8,7,0,14,8,36,1,5,0,36,1,0,0,36,1,1,0,36,0,79,0,2, +0,20,0,0,0,15,8,37,1,12,0,37,1,0,0,37,1,1,0,9,0,2,0,2,0,18,0,2,0,20,0,0, +0,16,8,0,0,17,8,0,0,15,8,7,0,18,8,7,0,19,8,4,0,37,0,36,0,79,0,38,1,9,0,38, +1,0,0,38,1,1,0,32,0,20,8,0,0,21,8,7,0,22,8,2,0,23,8,2,0,20,0,2,0,18,0,2, +0,37,0,39,1,7,0,42,0,-36,5,26,0,24,8,4,0,20,0,4,0,25,8,12,0,26,8,32,0,20,8,0, +0,21,8,40,1,12,0,32,0,20,8,2,0,27,8,2,0,20,0,2,0,28,8,2,0,29,8,0,0,21,8,32, +0,30,8,0,0,31,8,7,0,32,8,7,0,-39,1,7,0,33,8,7,0,34,8,41,1,6,0,32,0,20,8,4, +0,9,8,4,0,35,8,4,0,93,0,4,0,37,0,0,0,21,8,42,1,4,0,32,0,20,8,4,0,20,0,4, +0,9,8,0,0,21,8,43,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,44,1,10,0,32, +0,20,8,4,0,36,8,7,0,-127,0,4,0,20,0,2,0,-42,5,2,0,37,8,2,0,43,0,2,0,70,0,7, +0,38,8,0,0,21,8,45,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,46,1,10,0,32, +0,20,8,2,0,18,0,2,0,-95,3,4,0,91,0,4,0,92,0,7,0,-97,7,7,0,-96,7,4,0,37,0,-111, +0,-122,7,0,0,21,8,47,1,4,0,32,0,20,8,4,0,7,3,4,0,39,8,0,0,21,8,48,1,5,0,32, +0,20,8,7,0,-127,0,4,0,40,8,4,0,7,3,4,0,8,3,49,1,6,0,32,0,20,8,4,0,41,8,4, +0,42,8,7,0,43,8,7,0,44,8,0,0,21,8,50,1,16,0,32,0,20,8,32,0,-14,7,4,0,18,0,7, +0,45,8,7,0,46,8,7,0,47,8,7,0,48,8,7,0,49,8,7,0,50,8,7,0,51,8,7,0,52,8,7, +0,53,8,2,0,20,0,2,0,37,0,2,0,43,0,2,0,70,0,51,1,3,0,32,0,20,8,4,0,20,0,4, +0,123,5,52,1,5,0,32,0,20,8,4,0,20,0,4,0,37,0,7,0,54,8,0,0,21,8,53,1,10,0,32, +0,20,8,0,0,21,8,2,0,55,8,2,0,56,8,0,0,57,8,0,0,58,8,7,0,59,8,7,0,60,8,7, +0,61,8,7,0,62,8,54,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7,0,63,8,7, +0,64,8,2,0,20,0,2,0,123,5,55,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7, +0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,56,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7, +0,12,0,7,0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,57,1,7,0,32,0,20,8,0,0,21,8,7, +0,20,1,7,0,30,1,2,0,20,0,2,0,13,1,4,0,37,0,58,1,5,0,32,0,-45,2,7,0,20,1,2, +0,-41,2,0,0,-39,2,0,0,65,8,59,1,10,0,59,1,0,0,59,1,1,0,2,0,18,0,2,0,20,0,0, +0,66,8,7,0,-36,0,7,0,-35,0,2,0,-58,7,2,0,67,8,32,0,45,0,60,1,22,0,60,1,0,0,60, +1,1,0,2,0,20,0,2,0,13,1,2,0,68,8,2,0,69,8,36,0,79,0,-111,0,-122,7,32,0,-89,0,7, +0,91,0,7,0,92,0,7,0,70,8,7,0,71,8,7,0,72,8,7,0,73,8,7,0,-107,2,7,0,-67,1,7, +0,-120,7,7,0,74,8,0,0,75,8,0,0,76,8,12,0,-4,2,61,1,8,0,7,0,-31,1,7,0,-97,7,7, +0,-96,7,9,0,2,0,2,0,77,8,2,0,78,8,2,0,79,8,2,0,80,8,62,1,18,0,62,1,0,0,62, +1,1,0,62,1,81,8,0,0,17,0,61,1,82,8,2,0,18,0,2,0,20,0,2,0,83,8,2,0,84,8,2, +0,85,8,2,0,86,8,4,0,43,0,7,0,87,8,7,0,88,8,4,0,89,8,4,0,90,8,62,1,91,8,63, +1,92,8,64,1,32,0,64,1,0,0,64,1,1,0,64,1,93,8,0,0,17,0,0,0,94,8,2,0,18,0,2, +0,20,0,2,0,-14,6,2,0,20,7,2,0,95,8,2,0,-119,0,2,0,84,8,2,0,-25,6,12,0,-127,7,12, +0,96,8,27,0,-9,5,9,0,97,8,7,0,87,8,7,0,88,8,7,0,-5,1,7,0,98,8,2,0,99,8,2, +0,100,8,7,0,101,8,7,0,102,8,2,0,103,8,2,0,104,8,24,0,105,8,24,0,106,8,24,0,107,8,65, +1,-103,0,66,1,108,8,63,1,6,0,63,1,0,0,63,1,1,0,64,1,109,8,64,1,110,8,62,1,111,8,62, +1,91,8,57,0,16,0,27,0,31,0,12,0,112,8,12,0,113,8,61,1,114,8,12,0,115,8,4,0,18,0,4, +0,116,8,4,0,117,8,4,0,118,8,12,0,119,8,66,1,120,8,62,1,121,8,62,1,122,8,9,0,123,8,9, +0,124,8,4,0,125,8,67,1,6,0,4,0,-128,0,4,0,-126,0,4,0,-25,6,0,0,126,8,0,0,127,8,2, +0,37,0,68,1,16,0,2,0,-86,6,2,0,-85,6,2,0,-128,8,2,0,-74,7,2,0,-127,8,2,0,68,0,7, +0,-108,2,7,0,-126,8,7,0,-125,8,2,0,34,1,0,0,-124,8,0,0,42,4,2,0,-123,8,2,0,37,0,4, +0,-122,8,4,0,-121,8,69,1,9,0,7,0,-120,8,7,0,-119,8,7,0,-60,7,7,0,112,0,7,0,-118,8,7, +0,71,5,2,0,-117,8,0,0,-116,8,0,0,37,0,70,1,4,0,7,0,-115,8,7,0,-114,8,2,0,-117,8,2, +0,37,0,71,1,3,0,7,0,-113,8,7,0,-112,8,7,0,15,0,72,1,7,0,0,0,-68,1,2,0,109,4,2, +0,110,4,2,0,111,4,2,0,62,4,4,0,-126,0,4,0,-97,3,73,1,7,0,7,0,-111,8,7,0,-110,8,7, +0,-109,8,7,0,4,2,7,0,-108,8,7,0,-107,8,7,0,-106,8,74,1,4,0,2,0,-105,8,2,0,-104,8,2, +0,-103,8,2,0,-102,8,75,1,2,0,7,0,5,0,7,0,6,0,76,1,2,0,0,0,-87,0,0,0,-101,8,77, +1,1,0,0,0,17,0,78,1,10,0,0,0,-100,8,0,0,-99,8,0,0,-98,8,0,0,-97,8,2,0,-128,8,2, +0,-96,8,7,0,-95,8,7,0,-94,8,7,0,-93,8,7,0,-67,1,79,1,2,0,9,0,-92,8,9,0,-91,8,80, +1,11,0,0,0,111,4,0,0,18,0,0,0,-117,8,0,0,112,0,0,0,-90,8,0,0,109,0,0,0,-74,0,7, +0,-89,8,7,0,-88,8,7,0,-87,8,7,0,-86,8,81,1,8,0,7,0,97,7,7,0,-127,0,7,0,42,4,7, +0,72,2,7,0,-85,8,7,0,-49,0,7,0,-84,8,4,0,18,0,82,1,4,0,2,0,-83,8,2,0,-82,8,2, +0,-81,8,2,0,37,0,83,1,1,0,0,0,17,0,84,1,4,0,7,0,5,0,7,0,6,0,2,0,20,0,2, +0,-80,8,85,1,10,0,2,0,-120,3,2,0,20,0,7,0,-17,3,7,0,-79,8,7,0,-78,8,7,0,-77,8,7, +0,-76,8,84,1,-75,8,84,1,-74,8,84,1,-73,8,60,0,9,0,4,0,20,0,4,0,64,0,24,0,-72,8,24, +0,-71,8,85,1,-70,8,7,0,-69,8,7,0,-68,8,7,0,-67,8,7,0,-66,8,86,1,4,0,46,0,-114,2,7, +0,-65,8,7,0,92,1,7,0,37,0,-87,0,13,0,27,0,31,0,2,0,20,0,2,0,72,5,4,0,109,0,7, +0,-64,8,7,0,1,2,7,0,-63,8,7,0,-62,8,7,0,92,1,2,0,47,1,2,0,37,0,50,0,77,1,86, +1,-61,8,87,1,10,0,4,0,18,0,4,0,-127,0,4,0,20,0,4,0,70,3,4,0,-60,8,4,0,-59,8,4, +0,-58,8,0,0,95,0,0,0,17,0,9,0,2,0,84,0,6,0,87,1,-57,8,4,0,-56,8,4,0,-55,8,4, +0,-54,8,4,0,37,0,9,0,-53,8,88,1,5,0,7,0,66,2,7,0,-74,2,7,0,-39,1,2,0,-52,8,2, +0,37,0,89,1,5,0,7,0,66,2,7,0,-51,8,7,0,-50,8,7,0,-49,8,7,0,-74,2,90,1,7,0,4, +0,-48,8,4,0,-47,8,4,0,-46,8,7,0,-45,8,7,0,-44,8,7,0,-43,8,7,0,-42,8,91,1,26,0,32, +0,-41,8,89,1,66,3,89,1,-40,8,88,1,-39,8,89,1,83,7,7,0,-38,8,7,0,-37,8,7,0,-36,8,7, +0,-35,8,7,0,-44,8,7,0,-43,8,7,0,-74,2,7,0,-97,2,7,0,-34,8,7,0,-33,8,7,0,109,0,7, +0,-32,8,4,0,-48,8,4,0,-31,8,4,0,37,0,4,0,81,0,4,0,-30,8,2,0,20,0,2,0,-29,8,2, +0,-28,8,2,0,100,3,92,1,112,0,27,0,31,0,4,0,20,0,2,0,18,0,2,0,55,8,2,0,-27,8,2, +0,-26,8,2,0,-25,8,2,0,-24,8,2,0,-23,8,2,0,-22,8,2,0,-21,8,2,0,-20,8,2,0,-19,8,2, +0,-18,8,2,0,-17,8,2,0,-16,8,2,0,-15,8,2,0,-14,8,2,0,-13,8,2,0,-47,1,2,0,76,7,2, +0,51,7,2,0,-12,8,2,0,-11,8,2,0,98,3,2,0,99,3,2,0,-10,8,2,0,-9,8,2,0,-8,8,2, +0,-7,8,2,0,-6,8,2,0,-5,8,7,0,-4,8,7,0,-3,8,7,0,-2,8,2,0,-1,8,2,0,0,9,7, +0,1,9,7,0,2,9,7,0,3,9,7,0,58,7,7,0,92,0,7,0,-97,2,7,0,64,7,7,0,4,9,7, +0,5,9,7,0,6,9,7,0,7,9,7,0,57,0,4,0,59,7,4,0,57,7,4,0,8,9,7,0,60,7,7, +0,61,7,7,0,62,7,7,0,9,9,7,0,10,9,7,0,11,9,7,0,12,9,7,0,13,9,7,0,14,9,7, +0,15,9,7,0,16,9,7,0,21,3,7,0,109,0,7,0,17,9,7,0,18,9,7,0,19,9,7,0,20,9,7, +0,21,9,7,0,22,9,7,0,108,2,7,0,23,9,7,0,24,9,4,0,25,9,4,0,26,9,7,0,27,9,7, +0,28,9,7,0,29,9,7,0,30,9,7,0,31,9,7,0,32,9,7,0,33,9,7,0,34,9,7,0,94,3,7, +0,92,3,7,0,93,3,7,0,35,9,7,0,36,9,7,0,37,9,7,0,38,9,7,0,39,9,7,0,40,9,7, +0,41,9,7,0,42,9,7,0,43,9,7,0,28,3,7,0,44,9,7,0,45,9,7,0,46,9,7,0,47,9,7, +0,48,9,7,0,49,9,7,0,50,9,0,0,51,9,63,0,55,3,63,0,52,9,32,0,53,9,32,0,54,9,36, +0,79,0,-108,0,53,3,-108,0,55,9,-120,0,37,0,-120,0,0,0,-120,0,1,0,92,1,56,9,91,1,-121,3,90, +1,-14,7,93,1,57,9,94,1,58,9,94,1,59,9,12,0,60,9,12,0,61,9,-107,0,54,3,32,0,62,9,32, +0,63,9,32,0,64,9,12,0,65,9,12,0,66,9,7,0,-45,0,7,0,83,4,4,0,110,2,4,0,20,0,4, +0,59,7,4,0,67,9,4,0,68,9,4,0,69,9,4,0,57,0,2,0,-38,0,2,0,70,9,2,0,71,9,2, +0,72,9,2,0,47,3,2,0,73,9,0,0,74,9,2,0,75,9,2,0,76,9,2,0,77,9,9,0,78,9,125, +0,-76,3,123,0,34,0,95,1,79,9,7,0,-106,3,7,0,80,9,7,0,81,9,7,0,-14,3,7,0,82,9,7, +0,31,3,7,0,21,3,7,0,83,9,7,0,3,2,7,0,84,9,7,0,85,9,7,0,86,9,7,0,87,9,7, +0,88,9,7,0,89,9,7,0,-105,3,7,0,90,9,7,0,91,9,7,0,92,9,7,0,-104,3,7,0,-108,3,7, +0,-107,3,4,0,93,9,4,0,93,0,4,0,94,9,4,0,95,9,2,0,96,9,2,0,97,9,2,0,98,9,2, +0,99,9,2,0,100,9,2,0,37,0,4,0,70,0,124,0,8,0,95,1,101,9,7,0,102,9,7,0,103,9,7, +0,-94,1,7,0,104,9,4,0,93,0,2,0,105,9,2,0,106,9,96,1,4,0,7,0,5,0,7,0,6,0,7, +0,7,0,7,0,107,9,97,1,6,0,97,1,0,0,97,1,1,0,96,1,108,9,4,0,109,9,2,0,110,9,2, +0,20,0,98,1,5,0,98,1,0,0,98,1,1,0,12,0,111,9,4,0,112,9,4,0,20,0,99,1,9,0,99, +1,0,0,99,1,1,0,12,0,-128,0,98,1,113,9,4,0,20,0,2,0,110,9,2,0,114,9,7,0,94,0,0, +0,115,9,-70,0,5,0,12,0,125,4,4,0,20,0,2,0,116,9,2,0,117,9,9,0,118,9,69,78,68,66,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +int DNAlen= sizeof(DNAstr); diff --git a/Extras/Serialize/BulletFileLoader/CMakeLists.txt b/Extras/Serialize/BulletFileLoader/CMakeLists.txt new file mode 100644 index 0000000..51e33e4 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/CMakeLists.txt @@ -0,0 +1,49 @@ +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src +) + +SET(BulletFileLoader_SRCS +bChunk.cpp +bDNA.cpp +bFile.cpp +btBulletFile.cpp +) + +SET(BulletFileLoader_HDRS +bChunk.h +bCommon.h +bDefines.h +bDNA.h +bFile.h +btBulletFile.h +) + +ADD_LIBRARY(BulletFileLoader ${BulletFileLoader_SRCS} ${BulletFileLoader_HDRS}) + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletFileLoader LinearMath) +ENDIF (BUILD_SHARED_LIBS) + +SET_TARGET_PROPERTIES(BulletFileLoader PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletFileLoader PROPERTIES SOVERSION ${BULLET_VERSION}) + +IF (INSTALL_EXTRA_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #FILES_MATCHING requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletFileLoader DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletFileLoader DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletFileLoader PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletFileLoader PROPERTIES PUBLIC_HEADER "${BulletFileLoader_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_EXTRA_LIBS) diff --git a/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h b/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h new file mode 100644 index 0000000..90ea886 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h @@ -0,0 +1,1051 @@ +/* Copyright (C) 2011 Erwin Coumans & Charlie C +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ +// Auto generated from Bullet/Extras/HeaderGenerator/bulletGenerate.py +#ifndef __BULLET_H__ +#define __BULLET_H__ +namespace Bullet { + +// put an empty struct in the case +typedef struct bInvalidHandle { + int unused; +}bInvalidHandle; + + class PointerArray; + class btPhysicsSystem; + class ListBase; + class btVector3FloatData; + class btVector3DoubleData; + class btMatrix3x3FloatData; + class btMatrix3x3DoubleData; + class btTransformFloatData; + class btTransformDoubleData; + class btBvhSubtreeInfoData; + class btOptimizedBvhNodeFloatData; + class btOptimizedBvhNodeDoubleData; + class btQuantizedBvhNodeData; + class btQuantizedBvhFloatData; + class btQuantizedBvhDoubleData; + class btCollisionShapeData; + class btStaticPlaneShapeData; + class btConvexInternalShapeData; + class btPositionAndRadius; + class btMultiSphereShapeData; + class btIntIndexData; + class btShortIntIndexData; + class btShortIntIndexTripletData; + class btCharIndexTripletData; + class btMeshPartData; + class btStridingMeshInterfaceData; + class btTriangleMeshShapeData; + class btScaledTriangleMeshShapeData; + class btCompoundShapeChildData; + class btCompoundShapeData; + class btCylinderShapeData; + class btCapsuleShapeData; + class btTriangleInfoData; + class btTriangleInfoMapData; + class btGImpactMeshShapeData; + class btConvexHullShapeData; + class btCollisionObjectDoubleData; + class btCollisionObjectFloatData; + class btDynamicsWorldDoubleData; + class btDynamicsWorldFloatData; + class btRigidBodyFloatData; + class btRigidBodyDoubleData; + class btConstraintInfo1; + class btTypedConstraintData; + class btPoint2PointConstraintFloatData; + class btPoint2PointConstraintDoubleData; + class btHingeConstraintDoubleData; + class btHingeConstraintFloatData; + class btConeTwistConstraintData; + class btGeneric6DofConstraintData; + class btGeneric6DofSpringConstraintData; + class btSliderConstraintData; + class btContactSolverInfoDoubleData; + class btContactSolverInfoFloatData; + class SoftBodyMaterialData; + class SoftBodyNodeData; + class SoftBodyLinkData; + class SoftBodyFaceData; + class SoftBodyTetraData; + class SoftRigidAnchorData; + class SoftBodyConfigData; + class SoftBodyPoseData; + class SoftBodyClusterData; + class btSoftBodyJointData; + class btSoftBodyFloatData; +// -------------------------------------------------- // + class PointerArray + { + public: + int m_size; + int m_capacity; + void *m_data; + }; + + +// -------------------------------------------------- // + class btPhysicsSystem + { + public: + PointerArray m_collisionShapes; + PointerArray m_collisionObjects; + PointerArray m_constraints; + }; + + +// -------------------------------------------------- // + class ListBase + { + public: + void *first; + void *last; + }; + + +// -------------------------------------------------- // + class btVector3FloatData + { + public: + float m_floats[4]; + }; + + +// -------------------------------------------------- // + class btVector3DoubleData + { + public: + double m_floats[4]; + }; + + +// -------------------------------------------------- // + class btMatrix3x3FloatData + { + public: + btVector3FloatData m_el[3]; + }; + + +// -------------------------------------------------- // + class btMatrix3x3DoubleData + { + public: + btVector3DoubleData m_el[3]; + }; + + +// -------------------------------------------------- // + class btTransformFloatData + { + public: + btMatrix3x3FloatData m_basis; + btVector3FloatData m_origin; + }; + + +// -------------------------------------------------- // + class btTransformDoubleData + { + public: + btMatrix3x3DoubleData m_basis; + btVector3DoubleData m_origin; + }; + + +// -------------------------------------------------- // + class btBvhSubtreeInfoData + { + public: + int m_rootNodeIndex; + int m_subtreeSize; + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; + }; + + +// -------------------------------------------------- // + class btOptimizedBvhNodeFloatData + { + public: + btVector3FloatData m_aabbMinOrg; + btVector3FloatData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btOptimizedBvhNodeDoubleData + { + public: + btVector3DoubleData m_aabbMinOrg; + btVector3DoubleData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btQuantizedBvhNodeData + { + public: + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; + int m_escapeIndexOrTriangleIndex; + }; + + +// -------------------------------------------------- // + class btQuantizedBvhFloatData + { + public: + btVector3FloatData m_bvhAabbMin; + btVector3FloatData m_bvhAabbMax; + btVector3FloatData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeFloatData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + btBvhSubtreeInfoData *m_subTreeInfoPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + }; + + +// -------------------------------------------------- // + class btQuantizedBvhDoubleData + { + public: + btVector3DoubleData m_bvhAabbMin; + btVector3DoubleData m_bvhAabbMax; + btVector3DoubleData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeDoubleData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + btBvhSubtreeInfoData *m_subTreeInfoPtr; + }; + + +// -------------------------------------------------- // + class btCollisionShapeData + { + public: + char *m_name; + int m_shapeType; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btStaticPlaneShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btVector3FloatData m_localScaling; + btVector3FloatData m_planeNormal; + float m_planeConstant; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btConvexInternalShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btVector3FloatData m_localScaling; + btVector3FloatData m_implicitShapeDimensions; + float m_collisionMargin; + int m_padding; + }; + + +// -------------------------------------------------- // + class btPositionAndRadius + { + public: + btVector3FloatData m_pos; + float m_radius; + }; + + +// -------------------------------------------------- // + class btMultiSphereShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + btPositionAndRadius *m_localPositionArrayPtr; + int m_localPositionArraySize; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btIntIndexData + { + public: + int m_value; + }; + + +// -------------------------------------------------- // + class btShortIntIndexData + { + public: + short m_value; + char m_pad[2]; + }; + + +// -------------------------------------------------- // + class btShortIntIndexTripletData + { + public: + short m_values[3]; + char m_pad[2]; + }; + + +// -------------------------------------------------- // + class btCharIndexTripletData + { + public: + char m_values[3]; + char m_pad; + }; + + +// -------------------------------------------------- // + class btMeshPartData + { + public: + btVector3FloatData *m_vertices3f; + btVector3DoubleData *m_vertices3d; + btIntIndexData *m_indices32; + btShortIntIndexTripletData *m_3indices16; + btCharIndexTripletData *m_3indices8; + btShortIntIndexData *m_indices16; + int m_numTriangles; + int m_numVertices; + }; + + +// -------------------------------------------------- // + class btStridingMeshInterfaceData + { + public: + btMeshPartData *m_meshPartsPtr; + btVector3FloatData m_scaling; + int m_numMeshParts; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btTriangleMeshShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btStridingMeshInterfaceData m_meshInterface; + btQuantizedBvhFloatData *m_quantizedFloatBvh; + btQuantizedBvhDoubleData *m_quantizedDoubleBvh; + btTriangleInfoMapData *m_triangleInfoMap; + float m_collisionMargin; + char m_pad3[4]; + }; + + +// -------------------------------------------------- // + class btScaledTriangleMeshShapeData + { + public: + btTriangleMeshShapeData m_trimeshShapeData; + btVector3FloatData m_localScaling; + }; + + +// -------------------------------------------------- // + class btCompoundShapeChildData + { + public: + btTransformFloatData m_transform; + btCollisionShapeData *m_childShape; + int m_childShapeType; + float m_childMargin; + }; + + +// -------------------------------------------------- // + class btCompoundShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btCompoundShapeChildData *m_childShapePtr; + int m_numChildShapes; + float m_collisionMargin; + }; + + +// -------------------------------------------------- // + class btCylinderShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btCapsuleShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btTriangleInfoData + { + public: + int m_flags; + float m_edgeV0V1Angle; + float m_edgeV1V2Angle; + float m_edgeV2V0Angle; + }; + + +// -------------------------------------------------- // + class btTriangleInfoMapData + { + public: + int *m_hashTablePtr; + int *m_nextPtr; + btTriangleInfoData *m_valueArrayPtr; + int *m_keyArrayPtr; + float m_convexEpsilon; + float m_planarEpsilon; + float m_equalVertexThreshold; + float m_edgeDistanceThreshold; + float m_zeroAreaThreshold; + int m_nextSize; + int m_hashTableSize; + int m_numValues; + int m_numKeys; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btGImpactMeshShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btStridingMeshInterfaceData m_meshInterface; + btVector3FloatData m_localScaling; + float m_collisionMargin; + int m_gimpactSubType; + }; + + +// -------------------------------------------------- // + class btConvexHullShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + btVector3FloatData *m_unscaledPointsFloatPtr; + btVector3DoubleData *m_unscaledPointsDoublePtr; + int m_numUnscaledPoints; + char m_padding3[4]; + }; + + +// -------------------------------------------------- // + class btCollisionObjectDoubleData + { + public: + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + btTransformDoubleData m_worldTransform; + btTransformDoubleData m_interpolationWorldTransform; + btVector3DoubleData m_interpolationLinearVelocity; + btVector3DoubleData m_interpolationAngularVelocity; + btVector3DoubleData m_anisotropicFriction; + double m_contactProcessingThreshold; + double m_deactivationTime; + double m_friction; + double m_rollingFriction; + double m_restitution; + double m_hitFraction; + double m_ccdSweptSphereRadius; + double m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btCollisionObjectFloatData + { + public: + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + btTransformFloatData m_worldTransform; + btTransformFloatData m_interpolationWorldTransform; + btVector3FloatData m_interpolationLinearVelocity; + btVector3FloatData m_interpolationAngularVelocity; + btVector3FloatData m_anisotropicFriction; + float m_contactProcessingThreshold; + float m_deactivationTime; + float m_friction; + float m_rollingFriction; + float m_restitution; + float m_hitFraction; + float m_ccdSweptSphereRadius; + float m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btDynamicsWorldDoubleData + { + public: + btContactSolverInfoDoubleData m_solverInfo; + btVector3DoubleData m_gravity; + }; + + +// -------------------------------------------------- // + class btDynamicsWorldFloatData + { + public: + btContactSolverInfoFloatData m_solverInfo; + btVector3FloatData m_gravity; + }; + + +// -------------------------------------------------- // + class btRigidBodyFloatData + { + public: + btCollisionObjectFloatData m_collisionObjectData; + btMatrix3x3FloatData m_invInertiaTensorWorld; + btVector3FloatData m_linearVelocity; + btVector3FloatData m_angularVelocity; + btVector3FloatData m_angularFactor; + btVector3FloatData m_linearFactor; + btVector3FloatData m_gravity; + btVector3FloatData m_gravity_acceleration; + btVector3FloatData m_invInertiaLocal; + btVector3FloatData m_totalForce; + btVector3FloatData m_totalTorque; + float m_inverseMass; + float m_linearDamping; + float m_angularDamping; + float m_additionalDampingFactor; + float m_additionalLinearDampingThresholdSqr; + float m_additionalAngularDampingThresholdSqr; + float m_additionalAngularDampingFactor; + float m_linearSleepingThreshold; + float m_angularSleepingThreshold; + int m_additionalDamping; + }; + + +// -------------------------------------------------- // + class btRigidBodyDoubleData + { + public: + btCollisionObjectDoubleData m_collisionObjectData; + btMatrix3x3DoubleData m_invInertiaTensorWorld; + btVector3DoubleData m_linearVelocity; + btVector3DoubleData m_angularVelocity; + btVector3DoubleData m_angularFactor; + btVector3DoubleData m_linearFactor; + btVector3DoubleData m_gravity; + btVector3DoubleData m_gravity_acceleration; + btVector3DoubleData m_invInertiaLocal; + btVector3DoubleData m_totalForce; + btVector3DoubleData m_totalTorque; + double m_inverseMass; + double m_linearDamping; + double m_angularDamping; + double m_additionalDampingFactor; + double m_additionalLinearDampingThresholdSqr; + double m_additionalAngularDampingThresholdSqr; + double m_additionalAngularDampingFactor; + double m_linearSleepingThreshold; + double m_angularSleepingThreshold; + int m_additionalDamping; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btConstraintInfo1 + { + public: + int m_numConstraintRows; + int nub; + }; + + +// -------------------------------------------------- // + class btTypedConstraintData + { + public: + bInvalidHandle *m_rbA; + bInvalidHandle *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + float m_appliedImpulse; + float m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + float m_breakingImpulseThreshold; + int m_isEnabled; + }; + + +// -------------------------------------------------- // + class btPoint2PointConstraintFloatData + { + public: + btTypedConstraintData m_typeConstraintData; + btVector3FloatData m_pivotInA; + btVector3FloatData m_pivotInB; + }; + + +// -------------------------------------------------- // + class btPoint2PointConstraintDoubleData + { + public: + btTypedConstraintData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; + }; + + +// -------------------------------------------------- // + class btHingeConstraintDoubleData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + }; + + +// -------------------------------------------------- // + class btHingeConstraintFloatData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + }; + + +// -------------------------------------------------- // + class btConeTwistConstraintData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + float m_swingSpan1; + float m_swingSpan2; + float m_twistSpan; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + float m_damping; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btGeneric6DofConstraintData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + btVector3FloatData m_linearUpperLimit; + btVector3FloatData m_linearLowerLimit; + btVector3FloatData m_angularUpperLimit; + btVector3FloatData m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; + }; + + +// -------------------------------------------------- // + class btGeneric6DofSpringConstraintData + { + public: + btGeneric6DofConstraintData m_6dofData; + int m_springEnabled[6]; + float m_equilibriumPoint[6]; + float m_springStiffness[6]; + float m_springDamping[6]; + }; + + +// -------------------------------------------------- // + class btSliderConstraintData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + float m_linearUpperLimit; + float m_linearLowerLimit; + float m_angularUpperLimit; + float m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; + }; + + +// -------------------------------------------------- // + class btContactSolverInfoDoubleData + { + public: + double m_tau; + double m_damping; + double m_friction; + double m_timeStep; + double m_restitution; + double m_maxErrorReduction; + double m_sor; + double m_erp; + double m_erp2; + double m_globalCfm; + double m_splitImpulsePenetrationThreshold; + double m_splitImpulseTurnErp; + double m_linearSlop; + double m_warmstartingFactor; + double m_maxGyroscopicForce; + double m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btContactSolverInfoFloatData + { + public: + float m_tau; + float m_damping; + float m_friction; + float m_timeStep; + float m_restitution; + float m_maxErrorReduction; + float m_sor; + float m_erp; + float m_erp2; + float m_globalCfm; + float m_splitImpulsePenetrationThreshold; + float m_splitImpulseTurnErp; + float m_linearSlop; + float m_warmstartingFactor; + float m_maxGyroscopicForce; + float m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class SoftBodyMaterialData + { + public: + float m_linearStiffness; + float m_angularStiffness; + float m_volumeStiffness; + int m_flags; + }; + + +// -------------------------------------------------- // + class SoftBodyNodeData + { + public: + SoftBodyMaterialData *m_material; + btVector3FloatData m_position; + btVector3FloatData m_previousPosition; + btVector3FloatData m_velocity; + btVector3FloatData m_accumulatedForce; + btVector3FloatData m_normal; + float m_inverseMass; + float m_area; + int m_attach; + int m_pad; + }; + + +// -------------------------------------------------- // + class SoftBodyLinkData + { + public: + SoftBodyMaterialData *m_material; + int m_nodeIndices[2]; + float m_restLength; + int m_bbending; + }; + + +// -------------------------------------------------- // + class SoftBodyFaceData + { + public: + btVector3FloatData m_normal; + SoftBodyMaterialData *m_material; + int m_nodeIndices[3]; + float m_restArea; + }; + + +// -------------------------------------------------- // + class SoftBodyTetraData + { + public: + btVector3FloatData m_c0[4]; + SoftBodyMaterialData *m_material; + int m_nodeIndices[4]; + float m_restVolume; + float m_c1; + float m_c2; + int m_pad; + }; + + +// -------------------------------------------------- // + class SoftRigidAnchorData + { + public: + btMatrix3x3FloatData m_c0; + btVector3FloatData m_c1; + btVector3FloatData m_localFrame; + bInvalidHandle *m_rigidBody; + int m_nodeIndex; + float m_c2; + }; + + +// -------------------------------------------------- // + class SoftBodyConfigData + { + public: + int m_aeroModel; + float m_baumgarte; + float m_damping; + float m_drag; + float m_lift; + float m_pressure; + float m_volume; + float m_dynamicFriction; + float m_poseMatch; + float m_rigidContactHardness; + float m_kineticContactHardness; + float m_softContactHardness; + float m_anchorHardness; + float m_softRigidClusterHardness; + float m_softKineticClusterHardness; + float m_softSoftClusterHardness; + float m_softRigidClusterImpulseSplit; + float m_softKineticClusterImpulseSplit; + float m_softSoftClusterImpulseSplit; + float m_maxVolume; + float m_timeScale; + int m_velocityIterations; + int m_positionIterations; + int m_driftIterations; + int m_clusterIterations; + int m_collisionFlags; + }; + + +// -------------------------------------------------- // + class SoftBodyPoseData + { + public: + btMatrix3x3FloatData m_rot; + btMatrix3x3FloatData m_scale; + btMatrix3x3FloatData m_aqq; + btVector3FloatData m_com; + btVector3FloatData *m_positions; + float *m_weights; + int m_numPositions; + int m_numWeigts; + int m_bvolume; + int m_bframe; + float m_restVolume; + int m_pad; + }; + + +// -------------------------------------------------- // + class SoftBodyClusterData + { + public: + btTransformFloatData m_framexform; + btMatrix3x3FloatData m_locii; + btMatrix3x3FloatData m_invwi; + btVector3FloatData m_com; + btVector3FloatData m_vimpulses[2]; + btVector3FloatData m_dimpulses[2]; + btVector3FloatData m_lv; + btVector3FloatData m_av; + btVector3FloatData *m_framerefs; + int *m_nodeIndices; + float *m_masses; + int m_numFrameRefs; + int m_numNodes; + int m_numMasses; + float m_idmass; + float m_imass; + int m_nvimpulses; + int m_ndimpulses; + float m_ndamping; + float m_ldamping; + float m_adamping; + float m_matching; + float m_maxSelfCollisionImpulse; + float m_selfCollisionImpulseFactor; + int m_containsAnchor; + int m_collide; + int m_clusterIndex; + }; + + +// -------------------------------------------------- // + class btSoftBodyJointData + { + public: + void *m_bodyA; + void *m_bodyB; + btVector3FloatData m_refs[2]; + float m_cfm; + float m_erp; + float m_split; + int m_delete; + btVector3FloatData m_relPosition[2]; + int m_bodyAtype; + int m_bodyBtype; + int m_jointType; + int m_pad; + }; + + +// -------------------------------------------------- // + class btSoftBodyFloatData + { + public: + btCollisionObjectFloatData m_collisionObjectData; + SoftBodyPoseData *m_pose; + SoftBodyMaterialData **m_materials; + SoftBodyNodeData *m_nodes; + SoftBodyLinkData *m_links; + SoftBodyFaceData *m_faces; + SoftBodyTetraData *m_tetrahedra; + SoftRigidAnchorData *m_anchors; + SoftBodyClusterData *m_clusters; + btSoftBodyJointData *m_joints; + int m_numMaterials; + int m_numNodes; + int m_numLinks; + int m_numFaces; + int m_numTetrahedra; + int m_numAnchors; + int m_numClusters; + int m_numJoints; + SoftBodyConfigData m_config; + }; + + +} +#endif//__BULLET_H__ \ No newline at end of file diff --git a/Extras/Serialize/BulletFileLoader/bChunk.cpp b/Extras/Serialize/BulletFileLoader/bChunk.cpp new file mode 100644 index 0000000..564e550 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bChunk.cpp @@ -0,0 +1,75 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "bChunk.h" +#include "bDefines.h" +#include "bFile.h" + +#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#include +#endif +#include + + +using namespace bParse; + + +// ----------------------------------------------------- // +short ChunkUtils::swapShort(short sht) +{ + SWITCH_SHORT(sht); + return sht; +} + +// ----------------------------------------------------- // +int ChunkUtils::swapInt(int inte) +{ + SWITCH_INT(inte); + return inte; +} + +// ----------------------------------------------------- // +long64 ChunkUtils::swapLong64(long64 lng) +{ + SWITCH_LONGINT(lng); + return lng; +} + +// ----------------------------------------------------- // +int ChunkUtils::getOffset(int flags) +{ + // if the file is saved in a + // different format, get the + // file's chunk size + int res = CHUNK_HEADER_LEN; + + if (VOID_IS_8) + { + if (flags &FD_BITS_VARIES) + res = sizeof(bChunkPtr4); + } + else + { + if (flags &FD_BITS_VARIES) + res = sizeof(bChunkPtr8); + } + return res; +} + + + + + +//eof diff --git a/Extras/Serialize/BulletFileLoader/bChunk.h b/Extras/Serialize/BulletFileLoader/bChunk.h new file mode 100644 index 0000000..77039bc --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bChunk.h @@ -0,0 +1,92 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BCHUNK_H__ +#define __BCHUNK_H__ + +#if defined (_WIN32) && ! defined (__MINGW32__) + #define long64 __int64 +#elif defined (__MINGW32__) + #include + #define long64 int64_t +#else + #define long64 long long +#endif + + +namespace bParse { + + + // ----------------------------------------------------- // + class bChunkPtr4 + { + public: + bChunkPtr4(){} + int code; + int len; + union + { + int m_uniqueInt; + }; + int dna_nr; + int nr; + }; + + // ----------------------------------------------------- // + class bChunkPtr8 + { + public: + bChunkPtr8(){} + int code, len; + union + { + long64 oldPrev; + int m_uniqueInts[2]; + }; + int dna_nr, nr; + }; + + // ----------------------------------------------------- // + class bChunkInd + { + public: + bChunkInd(){} + int code, len; + void *oldPtr; + int dna_nr, nr; + }; + + + // ----------------------------------------------------- // + class ChunkUtils + { + public: + + // file chunk offset + static int getOffset(int flags); + + // endian utils + static short swapShort(short sht); + static int swapInt(int inte); + static long64 swapLong64(long64 lng); + + }; + + + const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd))); + const bool VOID_IS_8 = ((sizeof(void*)==8)); +} + +#endif//__BCHUNK_H__ diff --git a/Extras/Serialize/BulletFileLoader/bCommon.h b/Extras/Serialize/BulletFileLoader/bCommon.h new file mode 100644 index 0000000..b01d2b8 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bCommon.h @@ -0,0 +1,39 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BCOMMON_H__ +#define __BCOMMON_H__ + + +#include +//#include "bLog.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btHashMap.h" + +namespace bParse { + + class bMain; + class bFileData; + class bFile; + class bDNA; + + // delete void* undefined + typedef struct bStructHandle {int unused;}bStructHandle; + typedef btAlignedObjectArray bListBasePtr; + typedef btHashMap bPtrMap; +} + + +#endif//__BCOMMON_H__ diff --git a/Extras/Serialize/BulletFileLoader/bDNA.cpp b/Extras/Serialize/BulletFileLoader/bDNA.cpp new file mode 100644 index 0000000..d534777 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bDNA.cpp @@ -0,0 +1,635 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include + +#include "bDNA.h" +#include "bChunk.h" +#include +#include +#include + +//this define will force traversal of structures, to check backward (and forward) compatibility +//#define TEST_BACKWARD_FORWARD_COMPATIBILITY + + +using namespace bParse; + + +// ----------------------------------------------------- // +bDNA::bDNA() + : mPtrLen(0) +{ + // -- +} + +// ----------------------------------------------------- // +bDNA::~bDNA() +{ + // -- +} + +// ----------------------------------------------------- // +bool bDNA::lessThan(bDNA *file) +{ + return ( m_Names.size() < file->m_Names.size()); +} + +// ----------------------------------------------------- // +char *bDNA::getName(int ind) +{ + assert(ind <= (int)m_Names.size()); + return m_Names[ind].m_name; +} + + +// ----------------------------------------------------- // +char *bDNA::getType(int ind) +{ + assert(ind<= (int)mTypes.size()); + return mTypes[ind]; +} + + +// ----------------------------------------------------- // +short *bDNA::getStruct(int ind) +{ + assert(ind <= (int)mStructs.size()); + return mStructs[ind]; +} + + +// ----------------------------------------------------- // +short bDNA::getLength(int ind) +{ + assert(ind <= (int)mTlens.size()); + return mTlens[ind]; +} + + +// ----------------------------------------------------- // +int bDNA::getReverseType(short type) +{ + + int* intPtr = mStructReverse.find(type); + if (intPtr) + return *intPtr; + + return -1; +} + +// ----------------------------------------------------- // +int bDNA::getReverseType(const char *type) +{ + + btHashString key(type); + int* valuePtr = mTypeLookup.find(key); + if (valuePtr) + return *valuePtr; + + return -1; +} + +// ----------------------------------------------------- // +int bDNA::getNumStructs() +{ + return (int)mStructs.size(); +} + +// ----------------------------------------------------- // +bool bDNA::flagNotEqual(int dna_nr) +{ + assert(dna_nr <= (int)mCMPFlags.size()); + return mCMPFlags[dna_nr] == FDF_STRUCT_NEQU; +} + +// ----------------------------------------------------- // +bool bDNA::flagEqual(int dna_nr) +{ + assert(dna_nr <= (int)mCMPFlags.size()); + int flag = mCMPFlags[dna_nr]; + return flag == FDF_STRUCT_EQU; +} + +// ----------------------------------------------------- // +bool bDNA::flagNone(int dna_nr) +{ + assert(dna_nr <= (int)mCMPFlags.size()); + return mCMPFlags[dna_nr] == FDF_NONE; +} + +// ----------------------------------------------------- // +int bDNA::getPointerSize() +{ + return mPtrLen; +} + +// ----------------------------------------------------- // +void bDNA::initRecurseCmpFlags(int iter) +{ + // iter is FDF_STRUCT_NEQU + + short *oldStrc = mStructs[iter]; + short type = oldStrc[0]; + + for (int i=0; i<(int)mStructs.size(); i++) + { + if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU ) + { + short *curStruct = mStructs[i]; + int eleLen = curStruct[1]; + curStruct+=2; + + for (int j=0; jgetReverseType(typeName); + if (newLookup == -1) + { + mCMPFlags[i] = FDF_NONE; + continue; + } + short *curStruct = memDNA->mStructs[newLookup]; +#else + // memory for file + + if (oldLookup < memDNA->mStructs.size()) + { + short *curStruct = memDNA->mStructs[oldLookup]; +#endif + + + + // rebuild... + mCMPFlags[i] = FDF_STRUCT_NEQU; + +#ifndef TEST_BACKWARD_FORWARD_COMPATIBILITY + + if (curStruct[1] == oldStruct[1]) + { + // type len same ... + if (mTlens[oldStruct[0]] == memDNA->mTlens[curStruct[0]]) + { + bool isSame = true; + int elementLength = oldStruct[1]; + + + curStruct+=2; + oldStruct+=2; + + + for (int j=0; jmTypes[curStruct[0]])!=0) + { + isSame=false; + break; + } + + // name the same + if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name)!=0) + { + isSame=false; + break; + } + } + // flag valid == + if (isSame) + mCMPFlags[i] = FDF_STRUCT_EQU; + } + } +#endif + } + } + + + + + + // recurse in + for ( i=0; i<(int)mStructs.size(); i++) + { + if (mCMPFlags[i] == FDF_STRUCT_NEQU) + initRecurseCmpFlags(i); + } +} + + + + +static int name_is_array(char* name, int* dim1, int* dim2) { + int len = strlen(name); + /*fprintf(stderr,"[%s]",name);*/ + /*if (len >= 1) { + if (name[len-1] != ']') + return 1; + } + return 0;*/ + char *bp; + int num; + if (dim1) { + *dim1 = 1; + } + if (dim2) { + *dim2 = 1; + } + bp = strchr(name, '['); + if (!bp) { + return 0; + } + num = 0; + while (++bp < name+len-1) { + const char c = *bp; + if (c == ']') { + break; + } + if (c <= '9' && c >= '0') { + num *= 10; + num += (c - '0'); + } else { + printf("array parse error.\n"); + return 0; + } + } + if (dim2) { + *dim2 = num; + } + + /* find second dim, if any. */ + bp = strchr(bp, '['); + if (!bp) { + return 1; /* at least we got the first dim. */ + } + num = 0; + while (++bp < name+len-1) { + const char c = *bp; + if (c == ']') { + break; + } + if (c <= '9' && c >= '0') { + num *= 10; + num += (c - '0'); + } else { + printf("array2 parse error.\n"); + return 1; + } + } + if (dim1) { + if (dim2) { + *dim1 = *dim2; + *dim2 = num; + } else { + *dim1 = num; + } + } + + return 1; +} + + +// ----------------------------------------------------- // +void bDNA::init(char *data, int len, bool swap) +{ + int *intPtr=0;short *shtPtr=0; + char *cp = 0;int dataLen =0;long nr=0; + intPtr = (int*)data; + + /* + SDNA (4 bytes) (magic number) + NAME (4 bytes) + (4 bytes) amount of names (int) + + + */ + + if (strncmp(data, "SDNA", 4)==0) + { + // skip ++ NAME + intPtr++; intPtr++; + } + + + + // Parse names + if (swap) dataLen = ChunkUtils::swapInt(*intPtr); + else dataLen = *intPtr; + intPtr++; + + cp = (char*)intPtr; + int i; + for ( i=0; i amount of types (int) + + + */ + + intPtr = (int*)cp; + assert(strncmp(cp, "TYPE", 4)==0); intPtr++; + + if (swap) dataLen = ChunkUtils::swapInt(*intPtr); + else dataLen = *intPtr; + intPtr++; + + cp = (char*)intPtr; + for ( i=0; i (short) the lengths of types + + */ + + // Parse type lens + intPtr = (int*)cp; + assert(strncmp(cp, "TLEN", 4)==0); intPtr++; + + dataLen = (int)mTypes.size(); + + shtPtr = (short*)intPtr; + for ( i=0; i amount of structs (int) + + + + + + + */ + + intPtr = (int*)shtPtr; + cp = (char*)intPtr; + assert(strncmp(cp, "STRC", 4)==0); intPtr++; + + if (swap) dataLen = ChunkUtils::swapInt(*intPtr); + else dataLen = *intPtr; + intPtr++; + + + shtPtr = (short*)intPtr; + for ( i=0; itypes_count; ++i) { + /* if (!bf->types[i].is_struct)*/ + { + printf("%3d: sizeof(%s%s)=%d", + i, + bf->types[i].is_struct ? "struct " : "atomic ", + bf->types[i].name, bf->types[i].size); + if (bf->types[i].is_struct) { + int j; + printf(", %d fields: { ", bf->types[i].fieldtypes_count); + for (j=0; jtypes[i].fieldtypes_count; ++j) { + printf("%s %s", + bf->types[bf->types[i].fieldtypes[j]].name, + bf->names[bf->types[i].fieldnames[j]]); + if (j == bf->types[i].fieldtypes_count-1) { + printf(";}"); + } else { + printf("; "); + } + } + } + printf("\n\n"); + + } + } +#endif + +} + + + + +//eof + + diff --git a/Extras/Serialize/BulletFileLoader/bDNA.h b/Extras/Serialize/BulletFileLoader/bDNA.h new file mode 100644 index 0000000..691080b --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bDNA.h @@ -0,0 +1,110 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BDNA_H__ +#define __BDNA_H__ + + +#include "bCommon.h" + +namespace bParse { + + struct bNameInfo + { + char* m_name; + bool m_isPointer; + int m_dim0; + int m_dim1; + }; + + class bDNA + { + public: + bDNA(); + ~bDNA(); + + void init(char *data, int len, bool swap=false); + + int getArraySize(char* str); + int getArraySizeNew(short name) + { + const bNameInfo& nameInfo = m_Names[name]; + return nameInfo.m_dim0*nameInfo.m_dim1; + } + int getElementSize(short type, short name) + { + const bNameInfo& nameInfo = m_Names[name]; + int size = nameInfo.m_isPointer ? mPtrLen*nameInfo.m_dim0*nameInfo.m_dim1 : mTlens[type]*nameInfo.m_dim0*nameInfo.m_dim1; + return size; + } + + int getNumNames() const + { + return m_Names.size(); + } + + char *getName(int ind); + char *getType(int ind); + short *getStruct(int ind); + short getLength(int ind); + int getReverseType(short type); + int getReverseType(const char *type); + + + int getNumStructs(); + + // + bool lessThan(bDNA* other); + + void initCmpFlags(bDNA *memDNA); + bool flagNotEqual(int dna_nr); + bool flagEqual(int dna_nr); + bool flagNone(int dna_nr); + + + int getPointerSize(); + + void dumpTypeDefinitions(); + + + private: + enum FileDNAFlags + { + FDF_NONE=0, + FDF_STRUCT_NEQU, + FDF_STRUCT_EQU + }; + + void initRecurseCmpFlags(int i); + + btAlignedObjectArray mCMPFlags; + + btAlignedObjectArray m_Names; + btAlignedObjectArray mTypes; + btAlignedObjectArray mStructs; + btAlignedObjectArray mTlens; + btHashMap mStructReverse; + btHashMap mTypeLookup; + + int mPtrLen; + + + + + }; +} + + +#endif//__BDNA_H__ diff --git a/Extras/Serialize/BulletFileLoader/bDefines.h b/Extras/Serialize/BulletFileLoader/bDefines.h new file mode 100644 index 0000000..238df7d --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bDefines.h @@ -0,0 +1,140 @@ +/* Copyright (C) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef __B_DEFINES_H__ +#define __B_DEFINES_H__ + + +// MISC defines, see BKE_global.h, BKE_utildefines.h +#define SIZEOFBLENDERHEADER 12 + + +// ------------------------------------------------------------ +#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +# define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#else +# define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) +#endif + + +// ------------------------------------------------------------ +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +# define MAKE_ID2(c, d) ( (c)<<8 | (d) ) +# define MOST_SIG_BYTE 0 +# define BBIG_ENDIAN +#else +# define MAKE_ID2(c, d) ( (d)<<8 | (c) ) +# define MOST_SIG_BYTE 1 +# define BLITTLE_ENDIAN +#endif + +// ------------------------------------------------------------ +#define ID_SCE MAKE_ID2('S', 'C') +#define ID_LI MAKE_ID2('L', 'I') +#define ID_OB MAKE_ID2('O', 'B') +#define ID_ME MAKE_ID2('M', 'E') +#define ID_CU MAKE_ID2('C', 'U') +#define ID_MB MAKE_ID2('M', 'B') +#define ID_MA MAKE_ID2('M', 'A') +#define ID_TE MAKE_ID2('T', 'E') +#define ID_IM MAKE_ID2('I', 'M') +#define ID_IK MAKE_ID2('I', 'K') +#define ID_WV MAKE_ID2('W', 'V') +#define ID_LT MAKE_ID2('L', 'T') +#define ID_SE MAKE_ID2('S', 'E') +#define ID_LF MAKE_ID2('L', 'F') +#define ID_LA MAKE_ID2('L', 'A') +#define ID_CA MAKE_ID2('C', 'A') +#define ID_IP MAKE_ID2('I', 'P') +#define ID_KE MAKE_ID2('K', 'E') +#define ID_WO MAKE_ID2('W', 'O') +#define ID_SCR MAKE_ID2('S', 'R') +#define ID_VF MAKE_ID2('V', 'F') +#define ID_TXT MAKE_ID2('T', 'X') +#define ID_SO MAKE_ID2('S', 'O') +#define ID_SAMPLE MAKE_ID2('S', 'A') +#define ID_GR MAKE_ID2('G', 'R') +#define ID_ID MAKE_ID2('I', 'D') +#define ID_AR MAKE_ID2('A', 'R') +#define ID_AC MAKE_ID2('A', 'C') +#define ID_SCRIPT MAKE_ID2('P', 'Y') +#define ID_FLUIDSIM MAKE_ID2('F', 'S') +#define ID_NT MAKE_ID2('N', 'T') +#define ID_BR MAKE_ID2('B', 'R') + + +#define ID_SEQ MAKE_ID2('S', 'Q') +#define ID_CO MAKE_ID2('C', 'O') +#define ID_PO MAKE_ID2('A', 'C') +#define ID_NLA MAKE_ID2('N', 'L') + +#define ID_VS MAKE_ID2('V', 'S') +#define ID_VN MAKE_ID2('V', 'N') + + +// ------------------------------------------------------------ +#define FORM MAKE_ID('F','O','R','M') +#define DDG1 MAKE_ID('3','D','G','1') +#define DDG2 MAKE_ID('3','D','G','2') +#define DDG3 MAKE_ID('3','D','G','3') +#define DDG4 MAKE_ID('3','D','G','4') +#define GOUR MAKE_ID('G','O','U','R') +#define BLEN MAKE_ID('B','L','E','N') +#define DER_ MAKE_ID('D','E','R','_') +#define V100 MAKE_ID('V','1','0','0') +#define DATA MAKE_ID('D','A','T','A') +#define GLOB MAKE_ID('G','L','O','B') +#define IMAG MAKE_ID('I','M','A','G') +#define TEST MAKE_ID('T','E','S','T') +#define USER MAKE_ID('U','S','E','R') + + +// ------------------------------------------------------------ +#define DNA1 MAKE_ID('D','N','A','1') +#define REND MAKE_ID('R','E','N','D') +#define ENDB MAKE_ID('E','N','D','B') +#define NAME MAKE_ID('N','A','M','E') +#define SDNA MAKE_ID('S','D','N','A') +#define TYPE MAKE_ID('T','Y','P','E') +#define TLEN MAKE_ID('T','L','E','N') +#define STRC MAKE_ID('S','T','R','C') + + +// ------------------------------------------------------------ +#define SWITCH_INT(a) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \ + s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; } + +// ------------------------------------------------------------ +#define SWITCH_SHORT(a) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; } + +// ------------------------------------------------------------ +#define SWITCH_LONGINT(a) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \ + s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \ + s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \ + s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; } + +#endif//__B_DEFINES_H__ diff --git a/Extras/Serialize/BulletFileLoader/bFile.cpp b/Extras/Serialize/BulletFileLoader/bFile.cpp new file mode 100644 index 0000000..22ea915 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bFile.cpp @@ -0,0 +1,1429 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include "bFile.h" +#include "bCommon.h" +#include "bChunk.h" +#include "bDNA.h" +#include +#include +#include +#include "bDefines.h" +#include "LinearMath/btSerializer.h" +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btMinMax.h" + +#define SIZEOFBLENDERHEADER 12 +#define MAX_ARRAY_LENGTH 512 +using namespace bParse; +#define MAX_STRLEN 1024 + +const char* getCleanName(const char* memName, char* buffer) +{ + int slen = strlen(memName); + assert(slen 0) + { + if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) ==0) + dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags)); + else dna.oldPtr = 0; + } + else dna.oldPtr = 0; + } + // Some Bullet files are missing the DNA1 block + // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME + // In Bullet tests its SDNA + NAME + else if (strncmp(tempBuffer, "SDNANAME", 8) ==0) + { + dna.oldPtr = blenderData + i; + dna.len = mFileLen-i; + + // Also no REND block, so exit now. + if (mVersion==276) break; + } + + if (mDataStart && dna.oldPtr) break; + tempBuffer++; + } + if (!dna.oldPtr || !dna.len) + { + //printf("Failed to find DNA1+SDNA pair\n"); + mFlags &= ~FD_OK; + return; + } + + + mFileDNA = new bDNA(); + mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0); + + if (mVersion==276) + { + int i; + for (i=0;igetNumNames();i++) + { + if (strcmp(mFileDNA->getName(i),"int")==0) + { + mFlags |= FD_BROKEN_DNA; + } + } + if ((mFlags&FD_BROKEN_DNA)!=0) + { + //printf("warning: fixing some broken DNA version\n"); + } + } + + + + if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) + mFileDNA->dumpTypeDefinitions(); + + mMemoryDNA = new bDNA(); + int littleEndian= 1; + littleEndian= ((char*)&littleEndian)[0]; + + mMemoryDNA->init(memDna,memDnaLength,littleEndian==0); + + + + + ///@todo we need a better version check, add version/sub version info from FileGlobal into memory DNA/header files + if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames()) + { + mFlags |= FD_VERSION_VARIES; + //printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform"); + } + + // as long as it kept up to date it will be ok!! + if (mMemoryDNA->lessThan(mFileDNA)) + { + //printf ("Warning, file DNA is newer than built in."); + } + + mFileDNA->initCmpFlags(mMemoryDNA); + + parseData(); + + resolvePointers(verboseMode); + + updateOldPointers(); + + +} + + + +// ----------------------------------------------------- // +void bFile::swap(char *head, bChunkInd& dataChunk) +{ + char *data = head; + short *strc = mFileDNA->getStruct(dataChunk.dna_nr); + int len = mFileDNA->getLength(strc[0]); + + for (int i=0; iflagEqual(dataChunk.dna_nr)) + { + // Ouch! need to rebuild the struct + short *oldStruct,*curStruct; + char *oldType, *newType; + int oldLen, curLen, reverseOld; + + + oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); + oldType = mFileDNA->getType(oldStruct[0]); + oldLen = mFileDNA->getLength(oldStruct[0]); + + if ((mFlags&FD_BROKEN_DNA)!=0) + { + if ((strcmp(oldType,"btQuantizedBvhNodeData")==0)&&oldLen==20) + { + return 0; + } + if ((strcmp(oldType,"btShortIntIndexData")==0)) + { + int allocLen = 2; + char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; + memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1); + short* dest = (short*) dataAlloc; + const short* src = (short*) head; + for (int i=0;igetReverseType(oldType); + + if ((reverseOld!=-1)) + { + // make sure it's here + //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); + + // + curStruct = mMemoryDNA->getStruct(reverseOld); + newType = mMemoryDNA->getType(curStruct[0]); + curLen = mMemoryDNA->getLength(curStruct[0]); + + + + // make sure it's the same + assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); + + + numallocs++; + // numBlocks * length + + int allocLen = (curLen); + char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; + memset(dataAlloc, 0, (dataChunk.nr*allocLen)); + + // track allocated + addDataBlock(dataAlloc); + + char *cur = dataAlloc; + char *old = head; + for (int block=0; blockgetStruct(dataChunk.dna_nr); + oldType = mFileDNA->getType(oldStruct[0]); + printf("%s equal structure, just memcpy\n",oldType); +#endif // + } + + + char *dataAlloc = new char[(dataChunk.len)+1]; + memset(dataAlloc, 0, dataChunk.len+1); + + + // track allocated + addDataBlock(dataAlloc); + + memcpy(dataAlloc, head, dataChunk.len); + return dataAlloc; + +} + + +// ----------------------------------------------------- // +void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers) +{ + if (old_dna == -1) return; + if (new_dna == -1) return; + + //disable this, because we need to fixup pointers/ListBase + if (0)//mFileDNA->flagEqual(old_dna)) + { + short *strc = mFileDNA->getStruct(old_dna); + int len = mFileDNA->getLength(strc[0]); + + memcpy(strcPtr, dtPtr, len); + return; + } + + // Ok, now build the struct + char *memType, *memName, *cpc, *cpo; + short *fileStruct, *filePtrOld, *memoryStruct, *firstStruct; + int elementLength, size, revType, old_nr, new_nr, fpLen; + short firstStructType; + + + // File to memory lookup + memoryStruct = mMemoryDNA->getStruct(new_dna); + fileStruct = mFileDNA->getStruct(old_dna); + firstStruct = fileStruct; + + + filePtrOld = fileStruct; + firstStructType = mMemoryDNA->getStruct(0)[0]; + + // Get number of elements + elementLength = memoryStruct[1]; + memoryStruct+=2; + + cpc = strcPtr; cpo = 0; + for (int ele=0; elegetType(memoryStruct[0]); + memName = mMemoryDNA->getName(memoryStruct[1]); + + + size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]); + revType = mMemoryDNA->getReverseType(memoryStruct[0]); + + if (revType != -1 && memoryStruct[0]>=firstStructType && memName[0] != '*') + { + cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld); + if (cpo) + { + int arrayLen = mFileDNA->getArraySizeNew(filePtrOld[1]); + old_nr = mFileDNA->getReverseType(memType); + new_nr = revType; + fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]); + if (arrayLen==1) + { + parseStruct(cpc, cpo, old_nr, new_nr,fixupPointers); + } else + { + char* tmpCpc = cpc; + char* tmpCpo = cpo; + + for (int i=0;i3 && type <8) + { + char c; + char *cp = data; + for (int i=0; igetPointerSize(); + int ptrMem = mMemoryDNA->getPointerSize(); + + if (!src && !dst) + return; + + + if (ptrFile == ptrMem) + { + memcpy(dst, src, ptrMem); + } + else if (ptrMem==4 && ptrFile==8) + { + btPointerUid* oldPtr = (btPointerUid*)src; + btPointerUid* newPtr = (btPointerUid*)dst; + + if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) + { + //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers + //so it can be used to distinguish between .blend and .bullet + newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; + } else + { + //deal with pointers the Blender .blend style way, see + //readfile.c in the Blender source tree + long64 longValue = *((long64*)src); + //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros + if (mFlags & FD_ENDIAN_SWAP) + SWITCH_LONGINT(longValue); + *((int*)dst) = (int)(longValue>>3); + } + + } + else if (ptrMem==8 && ptrFile==4) + { + btPointerUid* oldPtr = (btPointerUid*)src; + btPointerUid* newPtr = (btPointerUid*)dst; + if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) + { + newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; + newPtr->m_uniqueIds[1] = 0; + } else + { + *((long64*)dst)= *((int*)src); + } + } + else + { + printf ("%d %d\n", ptrFile,ptrMem); + assert(0 && "Invalid pointer len"); + } + + +} + + +// ----------------------------------------------------- // +void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers) +{ + // find the matching memory dna data + // to the file being loaded. Fill the + // memory with the file data... + + int len = dna_addr[1]; + dna_addr+=2; + + for (int i=0; igetType(dna_addr[0]); + const char* name = mFileDNA->getName(dna_addr[1]); + + + + int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]); + + if ((mFlags&FD_BROKEN_DNA)!=0) + { + if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0)) + { + eleLen = 0; + } + } + + if (strcmp(lookupName, name)==0) + { + //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str()); + int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]); + //assert(arrayLenold == arrayLen); + + if (name[0] == '*') + { + // cast pointers + int ptrFile = mFileDNA->getPointerSize(); + int ptrMem = mMemoryDNA->getPointerSize(); + safeSwapPtr(strcData,data); + + if (fixupPointers) + { + if (arrayLen > 1) + { + //void **sarray = (void**)strcData; + //void **darray = (void**)data; + + char *cpc, *cpo; + cpc = (char*)strcData; + cpo = (char*)data; + + for (int a=0; agetStruct(old_nr); + int elementLength = old[1]; + old+=2; + + for (int i=0; igetType(old[0]); + char* name = mFileDNA->getName(old[1]); + int len = mFileDNA->getElementSize(old[0], old[1]); + + if (strcmp(lookupName, name)==0) + { + if (strcmp(type, lookupType)==0) + { + if (foundPos) + *foundPos = old; + return data; + } + return 0; + } + data+=len; + } + return 0; +} + + +// ----------------------------------------------------- // +void bFile::swapStruct(int dna_nr, char *data) +{ + if (dna_nr == -1) return; + + short *strc = mFileDNA->getStruct(dna_nr); + //short *firstStrc = strc; + + int elementLen= strc[1]; + strc+=2; + + short first = mFileDNA->getStruct(0)[0]; + + char *buf = data; + for (int i=0; igetType(strc[0]); + char *name = mFileDNA->getName(strc[1]); + + int size = mFileDNA->getElementSize(strc[0], strc[1]); + if (strc[0] >= first && name[0]!='*') + { + int old_nr = mFileDNA->getReverseType(type); + int arrayLen = mFileDNA->getArraySizeNew(strc[1]); + if (arrayLen==1) + { + swapStruct(old_nr,buf); + } else + { + char* tmpBuf = buf; + for (int i=0;igetArraySize(name); + int arrayLen = mFileDNA->getArraySizeNew(strc[1]); + //assert(arrayLenOld == arrayLen); + swapData(buf, strc[0], arrayLen); + } + buf+=size; + } +} + +void bFile::resolvePointersMismatch() +{ +// printf("resolvePointersStructMismatch\n"); + + int i; + + for (i=0;i< m_pointerFixupArray.size();i++) + { + char* cur = m_pointerFixupArray.at(i); + void** ptrptr = (void**) cur; + void* ptr = *ptrptr; + ptr = findLibPointer(ptr); + if (ptr) + { + //printf("Fixup pointer!\n"); + *(ptrptr) = ptr; + } else + { +// printf("pointer not found: %x\n",cur); + } + } + + + for (i=0; igetPointerSize(); + int ptrFile = mFileDNA->getPointerSize(); + + + int blockLen = block->len / ptrFile; + + void *onptr = findLibPointer(*ptrptr); + if (onptr) + { + char *newPtr = new char[blockLen * ptrMem]; + addDataBlock(newPtr); + memset(newPtr, 0, blockLen * ptrMem); + + void **onarray = (void**)onptr; + char *oldPtr = (char*)onarray; + + int p = 0; + while (blockLen-- > 0) + { + btPointerUid dp = {0}; + safeSwapPtr((char*)dp.m_uniqueIds, oldPtr); + + void **tptr = (void**)(newPtr + p * ptrMem); + *tptr = findLibPointer(dp.m_ptr); + + oldPtr += ptrFile; + ++p; + } + + *ptrptr = newPtr; + } + } + } +} + + +///this loop only works fine if the Blender DNA structure of the file matches the headerfiles +void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode) +{ + bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + + short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); + short oldLen = fileDna->getLength(oldStruct[0]); + //char* structType = fileDna->getType(oldStruct[0]); + + char* cur = (char*)findLibPointer(dataChunk.oldPtr); + for (int block=0; blockgetStruct(0)[0]; + + + char* elemPtr= strcPtr; + + short int* oldStruct = fileDna->getStruct(dna_nr); + + int elementLength = oldStruct[1]; + oldStruct+=2; + + int totalSize = 0; + + for (int ele=0; elegetType(oldStruct[0]); + memName = fileDna->getName(oldStruct[1]); + + + + int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); + if (memName[0] == '*') + { + if (arrayLen > 1) + { + void **array= (void**)elemPtr; + for (int a=0; a ",&memName[1]); + printf("%d ", array[a]); + printf("\n",&memName[1]); + } + + array[a] = findLibPointer(array[a]); + } + } + else + { + void** ptrptr = (void**) elemPtr; + void* ptr = *ptrptr; + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + for (int i=0;i ",&memName[1]); + printf("%d ", ptr); + printf("\n",&memName[1]); + } + ptr = findLibPointer(ptr); + + if (ptr) + { + // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + *(ptrptr) = ptr; + if (memName[1] == '*' && ptrptr && *ptrptr) + { + // This will only work if the given **array is continuous + void **array= (void**)*(ptrptr); + void *np= array[0]; + int n=0; + while (np) + { + np= findLibPointer(array[n]); + if (np) array[n]= np; + n++; + } + } + } else + { + // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + } + } + } else + { + int revType = fileDna->getReverseType(oldStruct[0]); + if (oldStruct[0]>=firstStructType) //revType != -1 && + { + char cleanName[MAX_STRLEN]; + getCleanName(memName,cleanName); + + int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); + int byteOffset = 0; + + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + for (int i=0;i1) + { + printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen); + } else + { + printf("<%s type=\"%s\">\n",cleanName,memType); + } + } + + for (int i=0;i\n",cleanName); + } + } else + { + //export a simple type + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + + if (arrayLen>MAX_ARRAY_LENGTH) + { + printf("too long\n"); + } else + { + //printf("%s %s\n",memType,memName); + + bool isIntegerType = (strcmp(memType,"char")==0) || (strcmp(memType,"int")==0) || (strcmp(memType,"short")==0); + + if (isIntegerType) + { + const char* newtype="int"; + int dbarray[MAX_ARRAY_LENGTH]; + int* dbPtr = 0; + char* tmp = elemPtr; + dbPtr = &dbarray[0]; + if (dbPtr) + { + char cleanName[MAX_STRLEN]; + getCleanName(memName,cleanName); + + int i; + getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); + for (i=0;i",cleanName,memType); + else + printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); + for (i=0;i\n",cleanName); + } + } else + { + const char* newtype="double"; + double dbarray[MAX_ARRAY_LENGTH]; + double* dbPtr = 0; + char* tmp = elemPtr; + dbPtr = &dbarray[0]; + if (dbPtr) + { + int i; + getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); + for (i=0;i",memName,memType); + } + else + { + printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); + } + for (i=0;i\n",cleanName); + } + } + } + + } + } + } + + int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]); + totalSize += size; + elemPtr+=size; + + } + + return totalSize; +} + + +///Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory structures +void bFile::resolvePointers(int verboseMode) +{ + bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + + //char *dataPtr = mFileBuffer+mDataStart; + + if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES)) + { + resolvePointersMismatch(); + } + + { + + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + printf("\n"); + int numitems = m_chunks.size(); + printf("\n", btGetVersion(), numitems); + } + for (int i=0;iflagEqual(dataChunk.dna_nr)) + { + //dataChunk.len + short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); + char* oldType = fileDna->getType(oldStruct[0]); + + if (verboseMode & FD_VERBOSE_EXPORT_XML) + printf(" <%s pointer=%d>\n",oldType,dataChunk.oldPtr); + + resolvePointersChunk(dataChunk, verboseMode); + + if (verboseMode & FD_VERBOSE_EXPORT_XML) + printf(" \n",oldType); + } else + { + //printf("skipping mStruct\n"); + } + } + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + printf("\n"); + } + } + + +} + + +// ----------------------------------------------------- // +void* bFile::findLibPointer(void *ptr) +{ + + bStructHandle** ptrptr = getLibPointers().find(ptr); + if (ptrptr) + return *ptrptr; + return 0; +} + + +void bFile::updateOldPointers() +{ + int i; + + for (i=0;igetStruct(dataChunk.dna_nr); + char* typeName = dna->getType(newStruct[0]); + printf("%3d: %s ",i,typeName); + + printf("code=%s ",codestr); + + printf("ptr=%p ",dataChunk.oldPtr); + printf("len=%d ",dataChunk.len); + printf("nr=%d ",dataChunk.nr); + if (dataChunk.nr!=1) + { + printf("not 1\n"); + } + printf("\n"); + + + + + } + +#if 0 + IDFinderData ifd; + ifd.success = 0; + ifd.IDname = NULL; + ifd.just_print_it = 1; + for (i=0; im_blocks.size(); ++i) + { + BlendBlock* bb = bf->m_blocks[i]; + printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", bb->tag, bb,bf->types[bb->type_index].name,bb->m_array_entries_.size()); + block_ID_finder(bb, bf, &ifd); + printf("\n"); + } +#endif + +} + + +void bFile::writeChunks(FILE* fp, bool fixupPointers) +{ + bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + + for (int i=0;igetStruct(dataChunk.dna_nr); + oldType = fileDna->getType(oldStruct[0]); + oldLen = fileDna->getLength(oldStruct[0]); + ///don't try to convert Link block data, just memcpy it. Other data can be converted. + reverseOld = mMemoryDNA->getReverseType(oldType); + + + if ((reverseOld!=-1)) + { + // make sure it's here + //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); + // + curStruct = mMemoryDNA->getStruct(reverseOld); + newType = mMemoryDNA->getType(curStruct[0]); + // make sure it's the same + assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); + + + curLen = mMemoryDNA->getLength(curStruct[0]); + dataChunk.dna_nr = reverseOld; + if (strcmp("Link",oldType)!=0) + { + dataChunk.len = curLen * dataChunk.nr; + } else + { +// printf("keep length of link = %d\n",dataChunk.len); + } + + //write the structure header + fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + + + + short int* curStruct1; + curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr); + assert(curStruct1 == curStruct); + + char* cur = fixupPointers ? (char*)findLibPointer(dataChunk.oldPtr) : (char*)dataChunk.oldPtr; + + //write the actual contents of the structure(s) + fwrite(cur,dataChunk.len,1,fp); + } else + { + printf("serious error, struct mismatch: don't write\n"); + } + } + +} + +// ----------------------------------------------------- // +int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags) +{ + bool swap = false; + bool varies = false; + + if (flags &FD_ENDIAN_SWAP) swap = true; + if (flags &FD_BITS_VARIES) varies = true; + + if (VOID_IS_8) + { + if (varies) + { + bChunkPtr4 head; + memcpy(&head, dataPtr, sizeof(bChunkPtr4)); + + + bChunkPtr8 chunk; + + chunk.code = head.code; + chunk.len = head.len; + chunk.m_uniqueInts[0] = head.m_uniqueInt; + chunk.m_uniqueInts[1] = 0; + chunk.dna_nr = head.dna_nr; + chunk.nr = head.nr; + + if (swap) + { + if ((chunk.code & 0xFFFF)==0) + chunk.code >>=16; + + SWITCH_INT(chunk.len); + SWITCH_INT(chunk.dna_nr); + SWITCH_INT(chunk.nr); + } + + + memcpy(dataChunk, &chunk, sizeof(bChunkInd)); + } + else + { + bChunkPtr8 c; + memcpy(&c, dataPtr, sizeof(bChunkPtr8)); + + if (swap) + { + if ((c.code & 0xFFFF)==0) + c.code >>=16; + + SWITCH_INT(c.len); + SWITCH_INT(c.dna_nr); + SWITCH_INT(c.nr); + } + + memcpy(dataChunk, &c, sizeof(bChunkInd)); + } + } + else + { + if (varies) + { + bChunkPtr8 head; + memcpy(&head, dataPtr, sizeof(bChunkPtr8)); + + + bChunkPtr4 chunk; + chunk.code = head.code; + chunk.len = head.len; + + if (head.m_uniqueInts[0]==head.m_uniqueInts[1]) + { + chunk.m_uniqueInt = head.m_uniqueInts[0]; + } else + { + long64 oldPtr =0; + memcpy(&oldPtr, &head.m_uniqueInts[0], 8); + if (swap) + SWITCH_LONGINT(oldPtr); + chunk.m_uniqueInt = (int)(oldPtr >> 3); + } + + + chunk.dna_nr = head.dna_nr; + chunk.nr = head.nr; + + if (swap) + { + if ((chunk.code & 0xFFFF)==0) + chunk.code >>=16; + + SWITCH_INT(chunk.len); + SWITCH_INT(chunk.dna_nr); + SWITCH_INT(chunk.nr); + } + + memcpy(dataChunk, &chunk, sizeof(bChunkInd)); + } + else + { + bChunkPtr4 c; + memcpy(&c, dataPtr, sizeof(bChunkPtr4)); + + if (swap) + { + if ((c.code & 0xFFFF)==0) + c.code >>=16; + + SWITCH_INT(c.len); + SWITCH_INT(c.dna_nr); + SWITCH_INT(c.nr); + } + memcpy(dataChunk, &c, sizeof(bChunkInd)); + } + } + + if (dataChunk->len < 0) + return -1; + +#if 0 + print ("----------"); + print (dataChunk->code); + print (dataChunk->len); + print (dataChunk->old); + print (dataChunk->dna_nr); + print (dataChunk->nr); +#endif + return (dataChunk->len+ChunkUtils::getOffset(flags)); +} + + + +//eof diff --git a/Extras/Serialize/BulletFileLoader/bFile.h b/Extras/Serialize/BulletFileLoader/bFile.h new file mode 100644 index 0000000..0da7367 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/bFile.h @@ -0,0 +1,164 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BFILE_H__ +#define __BFILE_H__ + +#include "bCommon.h" +#include "bChunk.h" +#include + +namespace bParse { + + // ----------------------------------------------------- // + enum bFileFlags + { + FD_INVALID =0, + FD_OK =1, + FD_VOID_IS_8 =2, + FD_ENDIAN_SWAP =4, + FD_FILE_64 =8, + FD_BITS_VARIES =16, + FD_VERSION_VARIES = 32, + FD_DOUBLE_PRECISION =64, + FD_BROKEN_DNA = 128 + }; + + enum bFileVerboseMode + { + FD_VERBOSE_EXPORT_XML = 1, + FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2, + FD_VERBOSE_DUMP_CHUNKS = 4, + FD_VERBOSE_DUMP_FILE_INFO=8, + }; + // ----------------------------------------------------- // + class bFile + { + protected: + + char m_headerString[7]; + + bool mOwnsBuffer; + char* mFileBuffer; + int mFileLen; + int mVersion; + + + bPtrMap mLibPointers; + + int mDataStart; + bDNA* mFileDNA; + bDNA* mMemoryDNA; + + btAlignedObjectArray m_pointerFixupArray; + btAlignedObjectArray m_pointerPtrFixupArray; + + btAlignedObjectArray m_chunks; + btHashMap m_chunkPtrPtrMap; + + // + + bPtrMap mDataPointers; + + + int mFlags; + + // //////////////////////////////////////////////////////////////////////////// + + // buffer offset util + int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags); + void safeSwapPtr(char *dst, const char *src); + + virtual void parseHeader(); + + virtual void parseData() = 0; + + void resolvePointersMismatch(); + void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode); + + int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion); + //void swapPtr(char *dst, char *src); + + void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers); + void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers); + char* getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos); + + + void swap(char *head, class bChunkInd& ch); + + void swapData(char *data, short type, int arraySize); + void swapStruct(int dna_nr, char *data); + + + + + char* readStruct(char *head, class bChunkInd& chunk); + char *getAsString(int code); + + void parseInternal(int verboseMode, char* memDna,int memDnaLength); + + public: + bFile(const char *filename, const char headerString[7]); + + //todo: make memoryBuffer const char + //bFile( const char *memoryBuffer, int len); + bFile( char *memoryBuffer, int len, const char headerString[7]); + virtual ~bFile(); + + bDNA* getFileDNA() + { + return mFileDNA; + } + + virtual void addDataBlock(char* dataBlock) = 0; + + int getFlags() const + { + return mFlags; + } + + bPtrMap& getLibPointers() + { + return mLibPointers; + } + + void* findLibPointer(void *ptr); + + bool ok(); + + virtual void parse(int verboseMode) = 0; + + virtual int write(const char* fileName, bool fixupPointers=false) = 0; + + virtual void writeChunks(FILE* fp, bool fixupPointers ); + + virtual void writeDNA(FILE* fp) = 0; + + void updateOldPointers(); + void resolvePointers(int verboseMode); + + void dumpChunks(bDNA* dna); + + int getVersion() const + { + return mVersion; + } + + + }; +} + + +#endif//__BFILE_H__ diff --git a/Extras/Serialize/BulletFileLoader/btBulletFile.cpp b/Extras/Serialize/BulletFileLoader/btBulletFile.cpp new file mode 100644 index 0000000..d2f8bf0 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/btBulletFile.cpp @@ -0,0 +1,406 @@ +/* +bParse +Copyright (c) 2006-2010 Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletFile.h" +#include "bDefines.h" +#include "bDNA.h" + +#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#include +#endif +#include + + +// 32 && 64 bit versions +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#ifdef _WIN64 +extern char sBulletDNAstr64[]; +extern int sBulletDNAlen64; +#else +extern char sBulletDNAstr[]; +extern int sBulletDNAlen; +#endif //_WIN64 +#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + +extern char sBulletDNAstr64[]; +extern int sBulletDNAlen64; +extern char sBulletDNAstr[]; +extern int sBulletDNAlen; + +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + +using namespace bParse; + +btBulletFile::btBulletFile() +:bFile("", "BULLET ") +{ + mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it" + + m_DnaCopy = 0; + + +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#ifdef _WIN64 + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16); + memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); + mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64); +#else//_WIN64 + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16); + memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); + mMemoryDNA->init(m_DnaCopy,sBulletDNAlen); +#endif//_WIN64 +#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { + m_DnaCopy = (char*) btAlignedAlloc(sBulletDNAlen64,16); + memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); + mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64); + } + else + { + m_DnaCopy =(char*) btAlignedAlloc(sBulletDNAlen,16); + memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); + mMemoryDNA->init(m_DnaCopy,sBulletDNAlen); + } +#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +} + + + +btBulletFile::btBulletFile(const char* fileName) +:bFile(fileName, "BULLET ") +{ + m_DnaCopy = 0; +} + + + +btBulletFile::btBulletFile(char *memoryBuffer, int len) +:bFile(memoryBuffer,len, "BULLET ") +{ + m_DnaCopy = 0; +} + + +btBulletFile::~btBulletFile() +{ + if (m_DnaCopy) + btAlignedFree(m_DnaCopy); + + + while (m_dataBlocks.size()) + { + char* dataBlock = m_dataBlocks[m_dataBlocks.size()-1]; + delete[] dataBlock; + m_dataBlocks.pop_back(); + } + +} + + + +// ----------------------------------------------------- // +void btBulletFile::parseData() +{ +// printf ("Building datablocks"); +// printf ("Chunk size = %d",CHUNK_HEADER_LEN); +// printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags)); + + const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0; + + //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0; + + + mDataStart = 12; + + char *dataPtr = mFileBuffer+mDataStart; + + bChunkInd dataChunk; + dataChunk.code = 0; + + + //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); + int seek = getNextBlock(&dataChunk, dataPtr, mFlags); + //dataPtr += ChunkUtils::getOffset(mFlags); + char *dataPtrHead = 0; + + while (dataChunk.code != DNA1) + { + if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE) ) + { + + // one behind + if (dataChunk.code == SDNA) break; + //if (dataChunk.code == DNA1) break; + + // same as (BHEAD+DATA dependency) + dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); + if (dataChunk.dna_nr>=0) + { + char *id = readStruct(dataPtrHead, dataChunk); + + // lookup maps + if (id) + { + m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk); + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id); + + m_chunks.push_back(dataChunk); + // block it + //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code); + //if (listID) + // listID->push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_SOFTBODY_CODE) + { + m_softBodies.push_back((bStructHandle*) id); + } + + if (dataChunk.code == BT_RIGIDBODY_CODE) + { + m_rigidBodies.push_back((bStructHandle*) id); + } + + if (dataChunk.code == BT_DYNAMICSWORLD_CODE) + { + m_dynamicsWorldInfo.push_back((bStructHandle*) id); + } + + if (dataChunk.code == BT_CONSTRAINT_CODE) + { + m_constraints.push_back((bStructHandle*) id); + } + + if (dataChunk.code == BT_QUANTIZED_BVH_CODE) + { + m_bvhs.push_back((bStructHandle*) id); + } + + if (dataChunk.code == BT_TRIANLGE_INFO_MAP) + { + m_triangleInfoMaps.push_back((bStructHandle*) id); + } + + if (dataChunk.code == BT_COLLISIONOBJECT_CODE) + { + m_collisionObjects.push_back((bStructHandle*) id); + } + + if (dataChunk.code == BT_SHAPE_CODE) + { + m_collisionShapes.push_back((bStructHandle*) id); + } + + // if (dataChunk.code == GLOB) + // { + // m_glob = (bStructHandle*) id; + // } + } else + { + printf("unknown chunk\n"); + + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead); + } + } else + { + printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n"); + } + + // next please! + dataPtr += seek; + + seek = getNextBlock(&dataChunk, dataPtr, mFlags); + if (seek < 0) + break; + } + +} + +void btBulletFile::addDataBlock(char* dataBlock) +{ + m_dataBlocks.push_back(dataBlock); + +} + + + + +void btBulletFile::writeDNA(FILE* fp) +{ + + bChunkInd dataChunk; + dataChunk.code = DNA1; + dataChunk.dna_nr = 0; + dataChunk.nr = 1; +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { +#ifdef _WIN64 + dataChunk.len = sBulletDNAlen64; + dataChunk.oldPtr = sBulletDNAstr64; + fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp); +#else + btAssert(0); +#endif + } + else + { +#ifndef _WIN64 + dataChunk.len = sBulletDNAlen; + dataChunk.oldPtr = sBulletDNAstr; + fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + fwrite(sBulletDNAstr, sBulletDNAlen,1,fp); +#else//_WIN64 + btAssert(0); +#endif//_WIN64 + } +#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { + dataChunk.len = sBulletDNAlen64; + dataChunk.oldPtr = sBulletDNAstr64; + fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp); + } + else + { + dataChunk.len = sBulletDNAlen; + dataChunk.oldPtr = sBulletDNAstr; + fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + fwrite(sBulletDNAstr, sBulletDNAlen,1,fp); + } +#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +} + + +void btBulletFile::parse(int verboseMode) +{ +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { +#ifdef _WIN64 + + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16); + memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); + parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64); +#else + btAssert(0); +#endif + } + else + { +#ifndef _WIN64 + + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16); + memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); + parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen); +#else + btAssert(0); +#endif + } +#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16); + memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); + parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen64); + } + else + { + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16); + memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); + parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen); + } +#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +} + +// experimental +int btBulletFile::write(const char* fileName, bool fixupPointers) +{ + FILE *fp = fopen(fileName, "wb"); + if (fp) + { + char header[SIZEOFBLENDERHEADER] ; + memcpy(header, m_headerString, 7); + int endian= 1; + endian= ((char*)&endian)[0]; + + if (endian) + { + header[7] = '_'; + } else + { + header[7] = '-'; + } + if (VOID_IS_8) + { + header[8]='V'; + } else + { + header[8]='v'; + } + + header[9] = '2'; + header[10] = '7'; + header[11] = '5'; + + fwrite(header,SIZEOFBLENDERHEADER,1,fp); + + writeChunks(fp, fixupPointers); + + writeDNA(fp); + + fclose(fp); + + } else + { + printf("Error: cannot open file %s for writing\n",fileName); + return 0; + } + return 1; +} + + + +void btBulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code) +{ + + bParse::bChunkInd dataChunk; + dataChunk.code = code; + dataChunk.nr = 1; + dataChunk.len = len; + dataChunk.dna_nr = mMemoryDNA->getReverseType(structType); + dataChunk.oldPtr = oldPtr; + + ///Perform structure size validation + short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr); + int elemBytes; + elemBytes= mMemoryDNA->getLength(structInfo[0]); +// int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]); + assert(len==elemBytes); + + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data); + m_chunks.push_back(dataChunk); +} \ No newline at end of file diff --git a/Extras/Serialize/BulletFileLoader/btBulletFile.h b/Extras/Serialize/BulletFileLoader/btBulletFile.h new file mode 100644 index 0000000..c4d7356 --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/btBulletFile.h @@ -0,0 +1,83 @@ +/* +bParse +Copyright (c) 2006-2010 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BULLET_FILE_H +#define BT_BULLET_FILE_H + + +#include "bFile.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "bDefines.h" + +#include "LinearMath/btSerializer.h" + + + +namespace bParse { + + // ----------------------------------------------------- // + class btBulletFile : public bFile + { + + + protected: + + char* m_DnaCopy; + + public: + + btAlignedObjectArray m_softBodies; + + btAlignedObjectArray m_rigidBodies; + + btAlignedObjectArray m_collisionObjects; + + btAlignedObjectArray m_collisionShapes; + + btAlignedObjectArray m_constraints; + + btAlignedObjectArray m_bvhs; + + btAlignedObjectArray m_triangleInfoMaps; + + btAlignedObjectArray m_dynamicsWorldInfo; + + btAlignedObjectArray m_dataBlocks; + btBulletFile(); + + btBulletFile(const char* fileName); + + btBulletFile(char *memoryBuffer, int len); + + virtual ~btBulletFile(); + + virtual void addDataBlock(char* dataBlock); + + + // experimental + virtual int write(const char* fileName, bool fixupPointers=false); + + virtual void parse(int verboseMode); + + virtual void parseData(); + + virtual void writeDNA(FILE* fp); + + void addStruct(const char* structType,void* data, int len, void* oldPtr, int code); + + }; +}; + +#endif //BT_BULLET_FILE_H diff --git a/Extras/Serialize/BulletFileLoader/premake4.lua b/Extras/Serialize/BulletFileLoader/premake4.lua new file mode 100644 index 0000000..b9480ed --- /dev/null +++ b/Extras/Serialize/BulletFileLoader/premake4.lua @@ -0,0 +1,12 @@ + project "BulletFileLoader" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + "../../../src" + } + + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/Extras/Serialize/BulletWorldImporter/CMakeLists.txt b/Extras/Serialize/BulletWorldImporter/CMakeLists.txt new file mode 100644 index 0000000..666ac21 --- /dev/null +++ b/Extras/Serialize/BulletWorldImporter/CMakeLists.txt @@ -0,0 +1,40 @@ +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader +) + +ADD_LIBRARY( +BulletWorldImporter +btBulletWorldImporter.cpp +btBulletWorldImporter.h +btWorldImporter.cpp +btWorldImporter.h +) + +SET_TARGET_PROPERTIES(BulletWorldImporter PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletWorldImporter PROPERTIES SOVERSION ${BULLET_VERSION}) + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath) +ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_EXTRA_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #FILES_MATCHING requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletWorldImporter DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletWorldImporter DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletWorldImporter PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletWorldImporter PROPERTIES PUBLIC_HEADER "btBulletWorldImporter.h") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_EXTRA_LIBS) diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp new file mode 100644 index 0000000..bde40c9 --- /dev/null +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp @@ -0,0 +1,326 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btBulletWorldImporter.h" +#include "../BulletFileLoader/btBulletFile.h" + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/Gimpact/btGImpactShape.h" + + + +//#define USE_INTERNAL_EDGE_UTILITY +#ifdef USE_INTERNAL_EDGE_UTILITY +#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h" +#endif //USE_INTERNAL_EDGE_UTILITY + +btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world) + :btWorldImporter(world) +{ +} + +btBulletWorldImporter::~btBulletWorldImporter() +{ +} + + +bool btBulletWorldImporter::loadFile( const char* fileName) +{ + bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName); + + bool result = loadFileFromMemory(bulletFile2); + + delete bulletFile2; + + return result; + +} + + + +bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len) +{ + bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer,len); + + bool result = loadFileFromMemory(bulletFile2); + + delete bulletFile2; + + return result; +} + + + + +bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFile2) +{ + bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0; + + if (ok) + bulletFile2->parse(m_verboseMode); + else + return false; + + if (m_verboseMode & bParse::FD_VERBOSE_DUMP_CHUNKS) + { + bulletFile2->dumpChunks(bulletFile2->getFileDNA()); + } + + return convertAllObjects(bulletFile2); + +} + +bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2) +{ + + m_shapeMap.clear(); + m_bodyMap.clear(); + + int i; + + for (i=0;im_bvhs.size();i++) + { + btOptimizedBvh* bvh = createOptimizedBvh(); + + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i]; + bvh->deSerializeDouble(*bvhData); + } else + { + btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i]; + bvh->deSerializeFloat(*bvhData); + } + m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh); + } + + + + + + for (i=0;im_collisionShapes.size();i++) + { + btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i]; + btCollisionShape* shape = convertCollisionShape(shapeData); + if (shape) + { + // printf("shapeMap.insert(%x,%x)\n",shapeData,shape); + m_shapeMap.insert(shapeData,shape); + } + + if (shape&& shapeData->m_name) + { + char* newname = duplicateName(shapeData->m_name); + m_objectNameMap.insert(shape,newname); + m_nameShapeMap.insert(newname,shape); + } + } + + + + + + for (int i=0;im_dynamicsWorldInfo.size();i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btDynamicsWorldDoubleData* solverInfoData = (btDynamicsWorldDoubleData*)bulletFile2->m_dynamicsWorldInfo[i]; + btContactSolverInfo solverInfo; + + btVector3 gravity; + gravity.deSerializeDouble(solverInfoData->m_gravity); + + solverInfo.m_tau = btScalar(solverInfoData->m_solverInfo.m_tau); + solverInfo.m_damping = btScalar(solverInfoData->m_solverInfo.m_damping); + solverInfo.m_friction = btScalar(solverInfoData->m_solverInfo.m_friction); + solverInfo.m_timeStep = btScalar(solverInfoData->m_solverInfo.m_timeStep); + + solverInfo.m_restitution = btScalar(solverInfoData->m_solverInfo.m_restitution); + solverInfo.m_maxErrorReduction = btScalar(solverInfoData->m_solverInfo.m_maxErrorReduction); + solverInfo.m_sor = btScalar(solverInfoData->m_solverInfo.m_sor); + solverInfo.m_erp = btScalar(solverInfoData->m_solverInfo.m_erp); + + solverInfo.m_erp2 = btScalar(solverInfoData->m_solverInfo.m_erp2); + solverInfo.m_globalCfm = btScalar(solverInfoData->m_solverInfo.m_globalCfm); + solverInfo.m_splitImpulsePenetrationThreshold = btScalar(solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold); + solverInfo.m_splitImpulseTurnErp = btScalar(solverInfoData->m_solverInfo.m_splitImpulseTurnErp); + + solverInfo.m_linearSlop = btScalar(solverInfoData->m_solverInfo.m_linearSlop); + solverInfo.m_warmstartingFactor = btScalar(solverInfoData->m_solverInfo.m_warmstartingFactor); + solverInfo.m_maxGyroscopicForce = btScalar(solverInfoData->m_solverInfo.m_maxGyroscopicForce); + solverInfo.m_singleAxisRollingFrictionThreshold = btScalar(solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold); + + solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations; + solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode; + solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold; + solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize; + + solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse; + + setDynamicsWorldInfo(gravity,solverInfo); + } else + { + btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i]; + btContactSolverInfo solverInfo; + + btVector3 gravity; + gravity.deSerializeFloat(solverInfoData->m_gravity); + + solverInfo.m_tau = solverInfoData->m_solverInfo.m_tau; + solverInfo.m_damping = solverInfoData->m_solverInfo.m_damping; + solverInfo.m_friction = solverInfoData->m_solverInfo.m_friction; + solverInfo.m_timeStep = solverInfoData->m_solverInfo.m_timeStep; + + solverInfo.m_restitution = solverInfoData->m_solverInfo.m_restitution; + solverInfo.m_maxErrorReduction = solverInfoData->m_solverInfo.m_maxErrorReduction; + solverInfo.m_sor = solverInfoData->m_solverInfo.m_sor; + solverInfo.m_erp = solverInfoData->m_solverInfo.m_erp; + + solverInfo.m_erp2 = solverInfoData->m_solverInfo.m_erp2; + solverInfo.m_globalCfm = solverInfoData->m_solverInfo.m_globalCfm; + solverInfo.m_splitImpulsePenetrationThreshold = solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold; + solverInfo.m_splitImpulseTurnErp = solverInfoData->m_solverInfo.m_splitImpulseTurnErp; + + solverInfo.m_linearSlop = solverInfoData->m_solverInfo.m_linearSlop; + solverInfo.m_warmstartingFactor = solverInfoData->m_solverInfo.m_warmstartingFactor; + solverInfo.m_maxGyroscopicForce = solverInfoData->m_solverInfo.m_maxGyroscopicForce; + solverInfo.m_singleAxisRollingFrictionThreshold = solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold; + + solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations; + solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode; + solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold; + solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize; + + solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse; + + setDynamicsWorldInfo(gravity,solverInfo); + } + } + + + for (i=0;im_rigidBodies.size();i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i]; + convertRigidBodyDouble(colObjData); + } else + { + btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i]; + convertRigidBodyFloat(colObjData); + } + + + } + + for (i=0;im_collisionObjects.size();i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btCollisionObjectDoubleData* colObjData = (btCollisionObjectDoubleData*)bulletFile2->m_collisionObjects[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeDouble(colObjData->m_worldTransform); + + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); + body->setFriction(btScalar(colObjData->m_friction)); + body->setRestitution(btScalar(colObjData->m_restitution)); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData,body); + } else + { + printf("error: no shape found\n"); + } + + } else + { + btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeFloat(colObjData->m_worldTransform); + + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData,body); + } else + { + printf("error: no shape found\n"); + } + } + + } + + + for (i=0;im_constraints.size();i++) + { + btTypedConstraintData* constraintData = (btTypedConstraintData*)bulletFile2->m_constraints[i]; + btCollisionObject** colAptr = m_bodyMap.find(constraintData->m_rbA); + btCollisionObject** colBptr = m_bodyMap.find(constraintData->m_rbB); + + btRigidBody* rbA = 0; + btRigidBody* rbB = 0; + + if (colAptr) + { + rbA = btRigidBody::upcast(*colAptr); + if (!rbA) + rbA = &getFixedBody(); + } + if (colBptr) + { + rbB = btRigidBody::upcast(*colBptr); + if (!rbB) + rbB = &getFixedBody(); + } + if (!rbA && !rbB) + continue; + + bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)!=0; + convertConstraint(constraintData, rbA,rbB,isDoublePrecisionData, bulletFile2->getVersion()); + + } + + return true; +} + diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h new file mode 100644 index 0000000..4a38318 --- /dev/null +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h @@ -0,0 +1,66 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BULLET_WORLD_IMPORTER_H +#define BULLET_WORLD_IMPORTER_H + + +#include "btWorldImporter.h" + + +class btBulletFile; + + + + +namespace bParse +{ + class btBulletFile; + +}; + + + +///The btBulletWorldImporter is a starting point to import .bullet files. +///note that not all data is converted yet. You are expected to override or modify this class. +///See Bullet/Demos/SerializeDemo for a derived class that extract btSoftBody objects too. +class btBulletWorldImporter : public btWorldImporter +{ + + +public: + + btBulletWorldImporter(btDynamicsWorld* world=0); + + virtual ~btBulletWorldImporter(); + + bool loadFile(const char* fileName); + + ///the memoryBuffer might be modified (for example if endian swaps are necessary) + bool loadFileFromMemory(char *memoryBuffer, int len); + + bool loadFileFromMemory(bParse::btBulletFile* file); + + //call make sure bulletFile2 has been parsed, either using btBulletFile::parse or btBulletWorldImporter::loadFileFromMemory + virtual bool convertAllObjects(bParse::btBulletFile* file); + + + + +}; + +#endif //BULLET_WORLD_IMPORTER_H + diff --git a/Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp new file mode 100644 index 0000000..44c7730 --- /dev/null +++ b/Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp @@ -0,0 +1,1422 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btWorldImporter.h" +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/Gimpact/btGImpactShape.h" + +btWorldImporter::btWorldImporter(btDynamicsWorld* world) +:m_dynamicsWorld(world), +m_verboseMode(0) +{ + +} + +btWorldImporter::~btWorldImporter() +{ +} + +void btWorldImporter::deleteAllData() +{ + int i; + for (i=0;iremoveConstraint(m_allocatedConstraints[i]); + delete m_allocatedConstraints[i]; + } + m_allocatedConstraints.clear(); + + + for (i=0;iremoveRigidBody(btRigidBody::upcast(m_allocatedRigidBodies[i])); + delete m_allocatedRigidBodies[i]; + } + + m_allocatedRigidBodies.clear(); + + + for (i=0;im_numMeshParts;a++) + { + btMeshPartData* curPart = &curData->m_meshPartsPtr[a]; + if(curPart->m_vertices3f) + delete [] curPart->m_vertices3f; + + if(curPart->m_vertices3d) + delete [] curPart->m_vertices3d; + + if(curPart->m_indices32) + delete [] curPart->m_indices32; + + if(curPart->m_3indices16) + delete [] curPart->m_3indices16; + + if(curPart->m_indices16) + delete [] curPart->m_indices16; + + if (curPart->m_3indices8) + delete [] curPart->m_3indices8; + + } + delete [] curData->m_meshPartsPtr; + delete curData; + } + m_allocatedbtStridingMeshInterfaceDatas.clear(); + + for (i=0;im_shapeType) + { + case STATIC_PLANE_PROXYTYPE: + { + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; + btVector3 planeNormal,localScaling; + planeNormal.deSerializeFloat(planeData->m_planeNormal); + localScaling.deSerializeFloat(planeData->m_localScaling); + shape = createPlaneShape(planeNormal,planeData->m_planeConstant); + shape->setLocalScaling(localScaling); + + break; + } + case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*) shapeData; + btCollisionShapeData* colShapeData = (btCollisionShapeData*) &scaledMesh->m_trimeshShapeData; + colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; + btCollisionShape* childShape = convertCollisionShape(colShapeData); + btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape; + btVector3 localScaling; + localScaling.deSerializeFloat(scaledMesh->m_localScaling); + + shape = createScaledTrangleMeshShape(meshShape, localScaling); + break; + } + case GIMPACT_SHAPE_PROXYTYPE: + { + btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData; + if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE) + { + btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface); + btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); + + + btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface); + btVector3 localScaling; + localScaling.deSerializeFloat(gimpactData->m_localScaling); + gimpactShape->setLocalScaling(localScaling); + gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin)); + gimpactShape->updateBound(); + shape = gimpactShape; + } else + { + printf("unsupported gimpact sub type\n"); + } + break; + } + + case CYLINDER_SHAPE_PROXYTYPE: + case CAPSULE_SHAPE_PROXYTYPE: + case BOX_SHAPE_PROXYTYPE: + case SPHERE_SHAPE_PROXYTYPE: + case MULTI_SPHERE_SHAPE_PROXYTYPE: + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; + btVector3 implicitShapeDimensions; + implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin); + switch (shapeData->m_shapeType) + { + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* box= (btBoxShape*)createBoxShape(implicitShapeDimensions/localScaling+margin); + //box->initializePolyhedralFeatures(); + shape = box; + + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + shape = createSphereShape(implicitShapeDimensions.getX()); + break; + } + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData; + switch (capData->m_upAxis) + { + case 0: + { + shape = createCapsuleShapeX(implicitShapeDimensions.getY()+bsd->m_collisionMargin*2,2*implicitShapeDimensions.getX()); + break; + } + case 1: + { + shape = createCapsuleShapeY(implicitShapeDimensions.getX()+bsd->m_collisionMargin*2,2*implicitShapeDimensions.getY()); + break; + } + case 2: + { + shape = createCapsuleShapeZ(implicitShapeDimensions.getX()+bsd->m_collisionMargin*2,2*implicitShapeDimensions.getZ()); + break; + } + default: + { + printf("error: wrong up axis for btCapsuleShape\n"); + } + bsd->m_collisionMargin = 0.f; + + }; + + break; + } + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData; + btVector3 halfExtents = implicitShapeDimensions+margin; + switch (cylData->m_upAxis) + { + case 0: + { + shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX()); + break; + } + case 1: + { + shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY()); + break; + } + case 2: + { + shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cylinder up axis\n"); + } + + }; + + + + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; + int numSpheres = mss->m_localPositionArraySize; + + btAlignedObjectArray tmpPos; + btAlignedObjectArray radii; + radii.resize(numSpheres); + tmpPos.resize(numSpheres); + int i; + for ( i=0;im_localPositionArrayPtr[i].m_pos); + radii[i] = mss->m_localPositionArrayPtr[i].m_radius; + } + shape = createMultiSphereShape(&tmpPos[0],&radii[0],numSpheres); + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + // int sz = sizeof(btConvexHullShapeData); + // int sz2 = sizeof(btConvexInternalShapeData); + // int sz3 = sizeof(btCollisionShapeData); + btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; + int numPoints = convexData->m_numUnscaledPoints; + + btAlignedObjectArray tmpPoints; + tmpPoints.resize(numPoints); + int i; + for ( i=0;im_unscaledPointsDoublePtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); +#else + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); +#endif //BT_USE_DOUBLE_PRECISION + } + btConvexHullShape* hullShape = createConvexHullShape(); + for (i=0;iaddPoint(tmpPoints[i]); + } + hullShape->setMargin(bsd->m_collisionMargin); + //hullShape->initializePolyhedralFeatures(); + shape = hullShape; + break; + } + default: + { + printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType); + } + } + + if (shape) + { + shape->setMargin(bsd->m_collisionMargin); + + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + shape->setLocalScaling(localScaling); + + } + break; + } + case TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData; + btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface); + btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); + if (!meshInterface->getNumSubParts()) + { + return 0; + } + + btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); + meshInterface->setScaling(scaling); + + + btOptimizedBvh* bvh = 0; +#if 1 + if (trimesh->m_quantizedFloatBvh) + { + btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh); + if (bvhPtr && *bvhPtr) + { + bvh = *bvhPtr; + } else + { + bvh = createOptimizedBvh(); + bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh); + } + } + if (trimesh->m_quantizedDoubleBvh) + { + btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh); + if (bvhPtr && *bvhPtr) + { + bvh = *bvhPtr; + } else + { + bvh = createOptimizedBvh(); + bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh); + } + } +#endif + + + btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh); + trimeshShape->setMargin(trimesh->m_collisionMargin); + shape = trimeshShape; + + if (trimesh->m_triangleInfoMap) + { + btTriangleInfoMap* map = createTriangleInfoMap(); + map->deSerialize(*trimesh->m_triangleInfoMap); + trimeshShape->setTriangleInfoMap(map); + +#ifdef USE_INTERNAL_EDGE_UTILITY + gContactAddedCallback = btAdjustInternalEdgeContactsCallback; +#endif //USE_INTERNAL_EDGE_UTILITY + + } + + //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin); + break; + } + case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; + btCompoundShape* compoundShape = createCompoundShape(); + + btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0]; + + + btAlignedObjectArray childShapes; + for (int i=0;im_numChildShapes;i++) + { + btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i]; + + btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape; + + btCollisionShape* childShape = convertCollisionShape(cd); + if (childShape) + { + btTransform localTransform; + localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); + compoundShape->addChildShape(localTransform,childShape); + } else + { +#ifdef _DEBUG + printf("error: couldn't create childShape for compoundShape\n"); +#endif + } + + } + shape = compoundShape; + + break; + } + case SOFTBODY_SHAPE_PROXYTYPE: + { + return 0; + } + default: + { +#ifdef _DEBUG + printf("unsupported shape type (%d)\n",shapeData->m_shapeType); +#endif + } + } + + return shape; + +} + + + +char* btWorldImporter::duplicateName(const char* name) +{ + if (name) + { + int l = (int)strlen(name); + char* newName = new char[l+1]; + memcpy(newName,name,l); + newName[l] = 0; + m_allocatedNames.push_back(newName); + return newName; + } + return 0; +} + + + +void btWorldImporter::convertConstraint(btTypedConstraintData* constraintData,btRigidBody* rbA, btRigidBody* rbB ,bool isDoublePrecisionData, int fileVersion) +{ + btTypedConstraint* constraint = 0; + + switch (constraintData->m_objectType) + { + case POINT2POINT_CONSTRAINT_TYPE: + { + if (isDoublePrecisionData) + { + btPoint2PointConstraintDoubleData* p2pData = (btPoint2PointConstraintDoubleData*)constraintData; + if (rbA && rbB) + { + btVector3 pivotInA,pivotInB; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + pivotInB.deSerializeDouble(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB); + } else + { + btVector3 pivotInA; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA,pivotInA); + } + } else + { + btPoint2PointConstraintFloatData* p2pData = (btPoint2PointConstraintFloatData*)constraintData; + if (rbA&& rbB) + { + btVector3 pivotInA,pivotInB; + pivotInA.deSerializeFloat(p2pData->m_pivotInA); + pivotInB.deSerializeFloat(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB); + + } else + { + btVector3 pivotInA; + pivotInA.deSerializeFloat(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA,pivotInA); + } + + } + + break; + } + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* hinge = 0; + + if (isDoublePrecisionData) + { + btHingeConstraintDoubleData* hingeData = (btHingeConstraintDoubleData*)constraintData; + if (rbA&& rbB) + { + btTransform rbAFrame,rbBFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + rbBFrame.deSerializeDouble(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0); + } else + { + btTransform rbAFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true,hingeData->m_motorTargetVelocity,hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly!=0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor)); + } else + { + btHingeConstraintFloatData* hingeData = (btHingeConstraintFloatData*)constraintData; + if (rbA&& rbB) + { + btTransform rbAFrame,rbBFrame; + rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); + rbBFrame.deSerializeFloat(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0); + } else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true,hingeData->m_motorTargetVelocity,hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly!=0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor)); + } + + constraint = hinge; + break; + + } + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData; + btConeTwistConstraint* coneTwist = 0; + + if (rbA&& rbB) + { + btTransform rbAFrame,rbBFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + rbBFrame.deSerializeFloat(coneData->m_rbBFrame); + coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame); + } else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + coneTwist = createConeTwistConstraint(*rbA,rbAFrame); + } + coneTwist->setLimit(coneData->m_swingSpan1,coneData->m_swingSpan2,coneData->m_twistSpan,coneData->m_limitSoftness,coneData->m_biasFactor,coneData->m_relaxationFactor); + coneTwist->setDamping(coneData->m_damping); + + constraint = coneTwist; + break; + } + + case D6_SPRING_CONSTRAINT_TYPE: + { + + btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData; + // int sz = sizeof(btGeneric6DofSpringConstraintData); + btGeneric6DofSpringConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame,rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame); + dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0); + } else + { + printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion>280) + { + for (i=0;i<6;i++) + { + dof->setStiffness(i,dofData->m_springStiffness[i]); + dof->setEquilibriumPoint(i,dofData->m_equilibriumPoint[i]); + dof->enableSpring(i,dofData->m_springEnabled[i]!=0); + dof->setDamping(i,dofData->m_springDamping[i]); + } + } + } + + constraint = dof; + break; + } + case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData; + btGeneric6DofConstraint* dof = 0; + + if (rbA&& rbB) + { + btTransform rbAFrame,rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); + } else + { + if (rbB) + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); + } else + { + printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); + } + } + + if (dof) + { + btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); + + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + } + + constraint = dof; + break; + } + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData; + btSliderConstraint* slider = 0; + if (rbA&& rbB) + { + btTransform rbAFrame,rbBFrame; + rbAFrame.deSerializeFloat(sliderData->m_rbAFrame); + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); + } else + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); + } + slider->setLowerLinLimit(sliderData->m_linearLowerLimit); + slider->setUpperLinLimit(sliderData->m_linearUpperLimit); + slider->setLowerAngLimit(sliderData->m_angularLowerLimit); + slider->setUpperAngLimit(sliderData->m_angularUpperLimit); + slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0); + constraint = slider; + break; + } + + default: + { + printf("unknown constraint type\n"); + } + }; + + if (constraint) + { + constraint->setDbgDrawSize(constraintData->m_dbgDrawSize); + ///those fields didn't exist and set to zero for pre-280 versions, so do a check here + if (fileVersion>=280) + { + constraint->setBreakingImpulseThreshold(constraintData->m_breakingImpulseThreshold); + constraint->setEnabled(constraintData->m_isEnabled!=0); + constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); + } + + if (constraintData->m_name) + { + char* newname = duplicateName(constraintData->m_name); + m_nameConstraintMap.insert(newname,constraint); + m_objectNameMap.insert(constraint,newname); + } + if(m_dynamicsWorld) + m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0); + } + + +} + + + + + + + + + + + +btTriangleIndexVertexArray* btWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData) +{ + btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer(); + + for (int i=0;iaddIndexedMesh(meshPart,meshPart.m_indexType); + } + } + + return meshInterface; +} + + +btStridingMeshInterfaceData* btWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData) +{ + //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter + btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData; + + newData->m_scaling = interfaceData->m_scaling; + newData->m_numMeshParts = interfaceData->m_numMeshParts; + newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts]; + + for(int i = 0;i < newData->m_numMeshParts;i++) + { + btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i]; + btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i]; + + curNewPart->m_numTriangles = curPart->m_numTriangles; + curNewPart->m_numVertices = curPart->m_numVertices; + + if(curPart->m_vertices3f) + { + curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices]; + memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices); + } + else + curNewPart->m_vertices3f = NULL; + + if(curPart->m_vertices3d) + { + curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices]; + memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices); + } + else + curNewPart->m_vertices3d = NULL; + + int numIndices = curNewPart->m_numTriangles * 3; + ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time + ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized + bool uninitialized3indices8Workaround =false; + + if(curPart->m_indices32) + { + uninitialized3indices8Workaround=true; + curNewPart->m_indices32 = new btIntIndexData[numIndices]; + memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices); + } + else + curNewPart->m_indices32 = NULL; + + if(curPart->m_3indices16) + { + uninitialized3indices8Workaround=true; + curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles]; + memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles); + } + else + curNewPart->m_3indices16 = NULL; + + if(curPart->m_indices16) + { + uninitialized3indices8Workaround=true; + curNewPart->m_indices16 = new btShortIntIndexData[numIndices]; + memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices); + } + else + curNewPart->m_indices16 = NULL; + + if(!uninitialized3indices8Workaround && curPart->m_3indices8) + { + curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles]; + memcpy(curNewPart->m_3indices8,curPart->m_3indices8,sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles); + } + else + curNewPart->m_3indices8 = NULL; + + } + + m_allocatedbtStridingMeshInterfaceDatas.push_back(newData); + + return(newData); +} + +#ifdef USE_INTERNAL_EDGE_UTILITY +extern ContactAddedCallback gContactAddedCallback; + +static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) +{ + + btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); + return true; +} +#endif //USE_INTERNAL_EDGE_UTILITY + + + + +btCollisionObject* btWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName) +{ + return createRigidBody(false,0,startTransform,shape,bodyName); +} + +void btWorldImporter::setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo) +{ + if (m_dynamicsWorld) + { + m_dynamicsWorld->setGravity(gravity); + m_dynamicsWorld->getSolverInfo() = solverInfo; + } + +} + +btRigidBody* btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName) +{ + btVector3 localInertia; + localInertia.setZero(); + + if (mass) + shape->calculateLocalInertia(mass,localInertia); + + btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + body->setWorldTransform(startTransform); + + if (m_dynamicsWorld) + m_dynamicsWorld->addRigidBody(body); + + if (bodyName) + { + char* newname = duplicateName(bodyName); + m_objectNameMap.insert(body,newname); + m_nameBodyMap.insert(newname,body); + } + m_allocatedRigidBodies.push_back(body); + return body; + +} + +btCollisionShape* btWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant) +{ + btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} +btCollisionShape* btWorldImporter::createBoxShape(const btVector3& halfExtents) +{ + btBoxShape* shape = new btBoxShape(halfExtents); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} +btCollisionShape* btWorldImporter::createSphereShape(btScalar radius) +{ + btSphereShape* shape = new btSphereShape(radius); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + + +btCollisionShape* btWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height) +{ + btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height) +{ + btCapsuleShape* shape = new btCapsuleShape(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height) +{ + btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCylinderShapeX(btScalar radius,btScalar height) +{ + btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCylinderShapeY(btScalar radius,btScalar height) +{ + btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height) +{ + btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btTriangleIndexVertexArray* btWorldImporter::createTriangleMeshContainer() +{ + btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray(); + m_allocatedTriangleIndexArrays.push_back(in); + return in; +} + +btOptimizedBvh* btWorldImporter::createOptimizedBvh() +{ + btOptimizedBvh* bvh = new btOptimizedBvh(); + m_allocatedBvhs.push_back(bvh); + return bvh; +} + + +btTriangleInfoMap* btWorldImporter::createTriangleInfoMap() +{ + btTriangleInfoMap* tim = new btTriangleInfoMap(); + m_allocatedTriangleInfoMaps.push_back(tim); + return tim; +} + +btBvhTriangleMeshShape* btWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh) +{ + if (bvh) + { + btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false); + bvhTriMesh->setOptimizedBvh(bvh); + m_allocatedCollisionShapes.push_back(bvhTriMesh); + return bvhTriMesh; + } + + btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true); + m_allocatedCollisionShapes.push_back(ts); + return ts; + +} +btCollisionShape* btWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh) +{ + return 0; +} +btGImpactMeshShape* btWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh) +{ + btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh); + m_allocatedCollisionShapes.push_back(shape); + return shape; + +} +btConvexHullShape* btWorldImporter::createConvexHullShape() +{ + btConvexHullShape* shape = new btConvexHullShape(); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCompoundShape* btWorldImporter::createCompoundShape() +{ + btCompoundShape* shape = new btCompoundShape(); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + + +btScaledBvhTriangleMeshShape* btWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScaling) +{ + btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape,localScaling); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btMultiSphereShape* btWorldImporter::createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres) +{ + btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btRigidBody& btWorldImporter::getFixedBody() +{ + static btRigidBody s_fixed(0, 0,0); + s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + return s_fixed; +} + +btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) +{ + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,rbB,pivotInA,pivotInB); + m_allocatedConstraints.push_back(p2p); + return p2p; +} + +btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) +{ + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,pivotInA); + m_allocatedConstraints.push_back(p2p); + return p2p; +} + + +btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA) +{ + btHingeConstraint* hinge = new btHingeConstraint(rbA,rbB,rbAFrame,rbBFrame,useReferenceFrameA); + m_allocatedConstraints.push_back(hinge); + return hinge; +} + +btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA) +{ + btHingeConstraint* hinge = new btHingeConstraint(rbA,rbAFrame,useReferenceFrameA); + m_allocatedConstraints.push_back(hinge); + return hinge; +} + +btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame) +{ + btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbB,rbAFrame,rbBFrame); + m_allocatedConstraints.push_back(cone); + return cone; +} + +btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) +{ + btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbAFrame); + m_allocatedConstraints.push_back(cone); + return cone; +} + + +btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) +{ + btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA); + m_allocatedConstraints.push_back(dof); + return dof; +} + +btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) +{ + btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbB,frameInB,useLinearReferenceFrameB); + m_allocatedConstraints.push_back(dof); + return dof; +} + +btGeneric6DofSpringConstraint* btWorldImporter::createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) +{ + btGeneric6DofSpringConstraint* dof = new btGeneric6DofSpringConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA); + m_allocatedConstraints.push_back(dof); + return dof; +} + + +btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) +{ + btSliderConstraint* slider = new btSliderConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA); + m_allocatedConstraints.push_back(slider); + return slider; +} + +btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA) +{ + btSliderConstraint* slider = new btSliderConstraint(rbB,frameInB,useLinearReferenceFrameA); + m_allocatedConstraints.push_back(slider); + return slider; +} + + + // query for data +int btWorldImporter::getNumCollisionShapes() const +{ + return m_allocatedCollisionShapes.size(); +} + +btCollisionShape* btWorldImporter::getCollisionShapeByIndex(int index) +{ + return m_allocatedCollisionShapes[index]; +} + +btCollisionShape* btWorldImporter::getCollisionShapeByName(const char* name) +{ + btCollisionShape** shapePtr = m_nameShapeMap.find(name); + if (shapePtr&& *shapePtr) + { + return *shapePtr; + } + return 0; +} + +btRigidBody* btWorldImporter::getRigidBodyByName(const char* name) +{ + btRigidBody** bodyPtr = m_nameBodyMap.find(name); + if (bodyPtr && *bodyPtr) + { + return *bodyPtr; + } + return 0; +} + +btTypedConstraint* btWorldImporter::getConstraintByName(const char* name) +{ + btTypedConstraint** constraintPtr = m_nameConstraintMap.find(name); + if (constraintPtr && *constraintPtr) + { + return *constraintPtr; + } + return 0; +} + +const char* btWorldImporter::getNameForPointer(const void* ptr) const +{ + const char*const * namePtr = m_objectNameMap.find(ptr); + if (namePtr && *namePtr) + return *namePtr; + return 0; +} + + +int btWorldImporter::getNumRigidBodies() const +{ + return m_allocatedRigidBodies.size(); +} + +btCollisionObject* btWorldImporter::getRigidBodyByIndex(int index) const +{ + return m_allocatedRigidBodies[index]; +} +int btWorldImporter::getNumConstraints() const +{ + return m_allocatedConstraints.size(); +} + +btTypedConstraint* btWorldImporter::getConstraintByIndex(int index) const +{ + return m_allocatedConstraints[index]; +} + +int btWorldImporter::getNumBvhs() const +{ + return m_allocatedBvhs.size(); +} + btOptimizedBvh* btWorldImporter::getBvhByIndex(int index) const +{ + return m_allocatedBvhs[index]; +} + +int btWorldImporter::getNumTriangleInfoMaps() const +{ + return m_allocatedTriangleInfoMaps.size(); +} + +btTriangleInfoMap* btWorldImporter::getTriangleInfoMapByIndex(int index) const +{ + return m_allocatedTriangleInfoMaps[index]; +} + + +void btWorldImporter::convertRigidBodyFloat( btRigidBodyFloatData* colObjData) +{ + btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f); + btVector3 localInertia; + localInertia.setZero(); + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeFloat(colObjData->m_collisionObjectData.m_worldTransform); + + // startTransform.setBasis(btMatrix3x3::getIdentity()); + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + if (shape->isNonMoving()) + { + mass = 0.f; + } + if (mass) + { + shape->calculateLocalInertia(mass,localInertia); + } + bool isDynamic = mass!=0.f; + btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name); + body->setFriction(colObjData->m_collisionObjectData.m_friction); + body->setRestitution(colObjData->m_collisionObjectData.m_restitution); + + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData,body); + } else + { + printf("error: no shape found\n"); + } +} + +void btWorldImporter::convertRigidBodyDouble( btRigidBodyDoubleData* colObjData) +{ + btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f); + btVector3 localInertia; + localInertia.setZero(); + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeDouble(colObjData->m_collisionObjectData.m_worldTransform); + + // startTransform.setBasis(btMatrix3x3::getIdentity()); + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + if (shape->isNonMoving()) + { + mass = 0.f; + } + if (mass) + { + shape->calculateLocalInertia(mass,localInertia); + } + bool isDynamic = mass!=0.f; + btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name); + body->setFriction(colObjData->m_collisionObjectData.m_friction); + body->setRestitution(colObjData->m_collisionObjectData.m_restitution); + + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData,body); + } else + { + printf("error: no shape found\n"); + } +} diff --git a/Extras/Serialize/BulletWorldImporter/btWorldImporter.h b/Extras/Serialize/BulletWorldImporter/btWorldImporter.h new file mode 100644 index 0000000..b321db7 --- /dev/null +++ b/Extras/Serialize/BulletWorldImporter/btWorldImporter.h @@ -0,0 +1,201 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_WORLD_IMPORTER_H +#define BT_WORLD_IMPORTER_H + +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btHashMap.h" + +class btCollisionShape; +class btCollisionObject; +class btRigidBody; +class btTypedConstraint; +class btDynamicsWorld; +struct ConstraintInput; +class btRigidBodyColladaInfo; +struct btCollisionShapeData; +class btTriangleIndexVertexArray; +class btStridingMeshInterface; +struct btStridingMeshInterfaceData; +class btGImpactMeshShape; +class btOptimizedBvh; +struct btTriangleInfoMap; +class btBvhTriangleMeshShape; +class btPoint2PointConstraint; +class btHingeConstraint; +class btConeTwistConstraint; +class btGeneric6DofConstraint; +class btGeneric6DofSpringConstraint; +class btSliderConstraint; +struct btContactSolverInfo; +struct btTypedConstraintData; + +struct btRigidBodyDoubleData; +struct btRigidBodyFloatData; + +#ifdef BT_USE_DOUBLE_PRECISION +#define btRigidBodyData btRigidBodyDoubleData +#else +#define btRigidBodyData btRigidBodyFloatData +#endif//BT_USE_DOUBLE_PRECISION + + +class btWorldImporter +{ +protected: + btDynamicsWorld* m_dynamicsWorld; + + int m_verboseMode; + + btAlignedObjectArray m_allocatedCollisionShapes; + btAlignedObjectArray m_allocatedRigidBodies; + btAlignedObjectArray m_allocatedConstraints; + btAlignedObjectArray m_allocatedBvhs; + btAlignedObjectArray m_allocatedTriangleInfoMaps; + btAlignedObjectArray m_allocatedTriangleIndexArrays; + btAlignedObjectArray m_allocatedbtStridingMeshInterfaceDatas; + + btAlignedObjectArray m_allocatedNames; + + btAlignedObjectArray m_indexArrays; + btAlignedObjectArray m_shortIndexArrays; + btAlignedObjectArray m_charIndexArrays; + + btAlignedObjectArray m_floatVertexArrays; + btAlignedObjectArray m_doubleVertexArrays; + + + btHashMap m_bvhMap; + btHashMap m_timMap; + + btHashMap m_nameShapeMap; + btHashMap m_nameBodyMap; + btHashMap m_nameConstraintMap; + btHashMap m_objectNameMap; + + btHashMap m_shapeMap; + btHashMap m_bodyMap; + + + //methods + + static btRigidBody& getFixedBody(); + + char* duplicateName(const char* name); + + btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData ); + void convertConstraint(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, bool isDoublePrecisionData, int fileVersion); + void convertRigidBodyFloat(btRigidBodyFloatData* colObjData); + void convertRigidBodyDouble( btRigidBodyDoubleData* colObjData); + +public: + + btWorldImporter(btDynamicsWorld* world); + + virtual ~btWorldImporter(); + + ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load. + ///make sure you don't use the dynamics world containing objects after you call this method + virtual void deleteAllData(); + + void setVerboseMode(int verboseMode) + { + m_verboseMode = verboseMode; + } + + int getVerboseMode() const + { + return m_verboseMode; + } + + // query for data + int getNumCollisionShapes() const; + btCollisionShape* getCollisionShapeByIndex(int index); + int getNumRigidBodies() const; + btCollisionObject* getRigidBodyByIndex(int index) const; + int getNumConstraints() const; + btTypedConstraint* getConstraintByIndex(int index) const; + int getNumBvhs() const; + btOptimizedBvh* getBvhByIndex(int index) const; + int getNumTriangleInfoMaps() const; + btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const; + + // queris involving named objects + btCollisionShape* getCollisionShapeByName(const char* name); + btRigidBody* getRigidBodyByName(const char* name); + btTypedConstraint* getConstraintByName(const char* name); + const char* getNameForPointer(const void* ptr) const; + + ///those virtuals are called by load and can be overridden by the user + + virtual void setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo); + + //bodies + virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape,const char* bodyName); + virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName); + + ///shapes + + virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant); + virtual btCollisionShape* createBoxShape(const btVector3& halfExtents); + virtual btCollisionShape* createSphereShape(btScalar radius); + virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height); + + virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height); + virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height); + virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height); + virtual class btTriangleIndexVertexArray* createTriangleMeshContainer(); + virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh); + virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh); + virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh); + virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData); + + virtual class btConvexHullShape* createConvexHullShape(); + virtual class btCompoundShape* createCompoundShape(); + virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape); + + virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres); + + virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData); + + ///acceleration and connectivity structures + virtual btOptimizedBvh* createOptimizedBvh(); + virtual btTriangleInfoMap* createTriangleInfoMap(); + + ///constraints + virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB); + virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA); + virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA=false); + virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA=false); + virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame); + virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame); + virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); + virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA); + + + +}; + + +#endif //BT_WORLD_IMPORTER_H \ No newline at end of file diff --git a/Extras/Serialize/BulletWorldImporter/premake4.lua b/Extras/Serialize/BulletWorldImporter/premake4.lua new file mode 100644 index 0000000..170bc65 --- /dev/null +++ b/Extras/Serialize/BulletWorldImporter/premake4.lua @@ -0,0 +1,13 @@ + project "BulletWorldImporter" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + "../BulletFileLoader", + "../../../src" + } + + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/Extras/Serialize/BulletXmlWorldImporter/CMakeLists.txt b/Extras/Serialize/BulletXmlWorldImporter/CMakeLists.txt new file mode 100644 index 0000000..6f311af --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/CMakeLists.txt @@ -0,0 +1,47 @@ +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader + ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter +) + +ADD_LIBRARY( + BulletXmlWorldImporter + btBulletXmlWorldImporter.cpp + btBulletXmlWorldImporter.h + string_split.cpp + string_split.h + tinyxml.cpp + tinyxml.h + tinystr.cpp + tinystr.h + tinyxmlerror.cpp + tinyxmlparser.cpp +) + +SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES SOVERSION ${BULLET_VERSION}) + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletXmlWorldImporter BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath) +ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_EXTRA_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #FILES_MATCHING requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletXmlWorldImporter DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletXmlWorldImporter DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES PUBLIC_HEADER "btBulletXmlWorldImporter.h") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_EXTRA_LIBS) diff --git a/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp new file mode 100644 index 0000000..5419572 --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp @@ -0,0 +1,870 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletXmlWorldImporter.h" +#include "tinyxml.h" +#include "btBulletDynamicsCommon.h" +#include "string_split.h" + + +btBulletXmlWorldImporter::btBulletXmlWorldImporter(btDynamicsWorld* world) + :btWorldImporter(world), + m_fileVersion(-1), + m_fileOk(false) +{ + +} + +btBulletXmlWorldImporter::~btBulletXmlWorldImporter() +{ + +} + + +static int get_double_attribute_by_name(const TiXmlElement* pElement, const char* attribName,double* value) +{ + if ( !pElement ) + return 0; + + const TiXmlAttribute* pAttrib=pElement->FirstAttribute(); + while (pAttrib) + { + if (pAttrib->Name()==attribName) + if (pAttrib->QueryDoubleValue(value)==TIXML_SUCCESS) + return 1; + pAttrib=pAttrib->Next(); + } + return 0; +} + + +static int get_int_attribute_by_name(const TiXmlElement* pElement, const char* attribName,int* value) +{ + if ( !pElement ) + return 0; + + const TiXmlAttribute* pAttrib=pElement->FirstAttribute(); + while (pAttrib) + { + if (!strcmp(pAttrib->Name(),attribName)) + if (pAttrib->QueryIntValue(value)==TIXML_SUCCESS) + return 1; +// if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval); + pAttrib=pAttrib->Next(); + } + return 0; +} + +void stringToFloatArray(const std::string& string, btAlignedObjectArray& floats) +{ + btAlignedObjectArray pieces; + + bullet_utils::split( pieces, string, " "); + for (unsigned int i = 0; i < pieces.size(); ++i) + { + assert(pieces[i]!=""); + floats.push_back((float)atof(pieces[i].c_str())); + } + +} + +static btVector3FloatData TextToVector3Data(const char* txt) +{ + btAssert(txt); + btAlignedObjectArray floats; + stringToFloatArray(txt, floats); + assert(floats.size()==4); + + btVector3FloatData vec4; + vec4.m_floats[0] = floats[0]; + vec4.m_floats[1] = floats[1]; + vec4.m_floats[2] = floats[2]; + vec4.m_floats[3] = floats[3]; + return vec4; +} + +void btBulletXmlWorldImporter::deSerializeVector3FloatData(TiXmlNode* pParent,btAlignedObjectArray& vectors) +{ + TiXmlNode* flNode = pParent->FirstChild("m_floats"); + btAssert(flNode); + while (flNode && flNode->FirstChild()) + { + TiXmlText* pText = flNode->FirstChild()->ToText(); +// printf("value = %s\n",pText->Value()); + btVector3FloatData vec4 = TextToVector3Data(pText->Value()); + vectors.push_back(vec4); + flNode = flNode->NextSibling(); + } + +} + + +#define SET_INT_VALUE(xmlnode, targetdata, argname) \ + btAssert((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement());\ + if ((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement())\ + (targetdata)->argname= (int)atof(xmlnode->FirstChild(#argname)->ToElement()->GetText()); + + +#define SET_FLOAT_VALUE(xmlnode, targetdata, argname) \ + btAssert((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement());\ + if ((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement())\ + (targetdata)->argname= (float)atof(xmlnode->FirstChild(#argname)->ToElement()->GetText()); + + +#define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype) \ + {\ + TiXmlNode* node = xmlnode->FirstChild(#argname);\ + btAssert(node);\ + if (node)\ + {\ + const char* txt = (node)->ToElement()->GetText();\ + (targetdata).argname= (pointertype) (int) atof(txt);\ + }\ + } + +#define SET_VECTOR4_VALUE(xmlnode, targetdata, argname) \ + {\ + TiXmlNode* flNode = xmlnode->FirstChild(#argname);\ + btAssert(flNode);\ + if (flNode && flNode->FirstChild())\ + {\ + const char* txt= flNode->FirstChild()->ToElement()->GetText();\ + btVector3FloatData vec4 = TextToVector3Data(txt);\ + (targetdata)->argname.m_floats[0] = vec4.m_floats[0];\ + (targetdata)->argname.m_floats[1] = vec4.m_floats[1];\ + (targetdata)->argname.m_floats[2] = vec4.m_floats[2];\ + (targetdata)->argname.m_floats[3] = vec4.m_floats[3];\ + }\ + } + + +#define SET_MATRIX33_VALUE(n, targetdata, argname) \ +{\ + TiXmlNode* xmlnode = n->FirstChild(#argname);\ + btAssert(xmlnode);\ + if (xmlnode)\ + {\ + TiXmlNode* eleNode = xmlnode->FirstChild("m_el");\ + btAssert(eleNode);\ + if (eleNode&& eleNode->FirstChild())\ + {\ + const char* txt= eleNode->FirstChild()->ToElement()->GetText();\ + btVector3FloatData vec4 = TextToVector3Data(txt);\ + (targetdata)->argname.m_el[0].m_floats[0] = vec4.m_floats[0];\ + (targetdata)->argname.m_el[0].m_floats[1] = vec4.m_floats[1];\ + (targetdata)->argname.m_el[0].m_floats[2] = vec4.m_floats[2];\ + (targetdata)->argname.m_el[0].m_floats[3] = vec4.m_floats[3];\ + \ + TiXmlNode* n1 = eleNode->FirstChild()->NextSibling();\ + btAssert(n1);\ + if (n1)\ + {\ + const char* txt= n1->ToElement()->GetText();\ + btVector3FloatData vec4 = TextToVector3Data(txt);\ + (targetdata)->argname.m_el[1].m_floats[0] = vec4.m_floats[0];\ + (targetdata)->argname.m_el[1].m_floats[1] = vec4.m_floats[1];\ + (targetdata)->argname.m_el[1].m_floats[2] = vec4.m_floats[2];\ + (targetdata)->argname.m_el[1].m_floats[3] = vec4.m_floats[3];\ + \ + TiXmlNode* n2 = n1->NextSibling();\ + btAssert(n2);\ + if (n2)\ + {\ + const char* txt= n2->ToElement()->GetText();\ + btVector3FloatData vec4 = TextToVector3Data(txt);\ + (targetdata)->argname.m_el[2].m_floats[0] = vec4.m_floats[0];\ + (targetdata)->argname.m_el[2].m_floats[1] = vec4.m_floats[1];\ + (targetdata)->argname.m_el[2].m_floats[2] = vec4.m_floats[2];\ + (targetdata)->argname.m_el[2].m_floats[3] = vec4.m_floats[3];\ + }\ + }\ + }\ + }\ +}\ + +#define SET_TRANSFORM_VALUE(n, targetdata, argname) \ +{\ + TiXmlNode* trNode = n->FirstChild(#argname);\ + btAssert(trNode);\ + if (trNode)\ + {\ + SET_VECTOR4_VALUE(trNode,&(targetdata)->argname,m_origin)\ + SET_MATRIX33_VALUE(trNode, &(targetdata)->argname,m_basis)\ + }\ +}\ + + +void btBulletXmlWorldImporter::deSerializeCollisionShapeData(TiXmlNode* pParent, btCollisionShapeData* colShapeData) +{ + SET_INT_VALUE(pParent,colShapeData,m_shapeType) + colShapeData->m_name = 0; +} + + + +void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(TiXmlNode* pParent) +{ + int ptr; + get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr); + + btConvexHullShapeData* convexHullData = (btConvexHullShapeData*)btAlignedAlloc(sizeof(btConvexHullShapeData), 16); + + TiXmlNode* xmlConvexInt = pParent->FirstChild("m_convexInternalShapeData"); + btAssert(xmlConvexInt); + + TiXmlNode* xmlColShape = xmlConvexInt ->FirstChild("m_collisionShapeData"); + btAssert(xmlColShape); + + deSerializeCollisionShapeData(xmlColShape,&convexHullData->m_convexInternalShapeData.m_collisionShapeData); + + SET_FLOAT_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_collisionMargin) + SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_localScaling) + SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_implicitShapeDimensions) + + SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsFloatPtr,btVector3FloatData*); + SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsDoublePtr,btVector3DoubleData*); + SET_INT_VALUE(pParent,convexHullData,m_numUnscaledPoints); + + m_collisionShapeData.push_back((btCollisionShapeData*)convexHullData); + m_pointerLookup.insert((void*)ptr,convexHullData); +} + +void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(TiXmlNode* pParent) +{ + int ptr; + get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr); + + int numChildren = 0; + btAlignedObjectArray* compoundChildArrayPtr = new btAlignedObjectArray; + { + TiXmlNode* transNode = pParent->FirstChild("m_transform"); + TiXmlNode* colShapeNode = pParent->FirstChild("m_childShape"); + TiXmlNode* marginNode = pParent->FirstChild("m_childMargin"); + TiXmlNode* childTypeNode = pParent->FirstChild("m_childShapeType"); + + int i=0; + while (transNode && colShapeNode && marginNode && childTypeNode) + { + compoundChildArrayPtr->expandNonInitializing(); + SET_VECTOR4_VALUE (transNode,&compoundChildArrayPtr->at(i).m_transform,m_origin) + SET_MATRIX33_VALUE(transNode,&compoundChildArrayPtr->at(i).m_transform,m_basis) + + const char* txt = (colShapeNode)->ToElement()->GetText(); + compoundChildArrayPtr->at(i).m_childShape = (btCollisionShapeData*) (int) atof(txt); + + btAssert(childTypeNode->ToElement()); + if (childTypeNode->ToElement()) + { + compoundChildArrayPtr->at(i).m_childShapeType = (int)atof(childTypeNode->ToElement()->GetText()); + } + + btAssert(marginNode->ToElement()); + if (marginNode->ToElement()) + { + compoundChildArrayPtr->at(i).m_childMargin = (float)atof(marginNode->ToElement()->GetText()); + } + + transNode = transNode->NextSibling("m_transform"); + colShapeNode = colShapeNode->NextSibling("m_childShape"); + marginNode = marginNode->NextSibling("m_childMargin"); + childTypeNode = childTypeNode->NextSibling("m_childShapeType"); + i++; + } + + numChildren = i; + + } + + btAssert(numChildren); + if (numChildren) + { + m_compoundShapeChildDataArrays.push_back(compoundChildArrayPtr); + btCompoundShapeChildData* cd = &compoundChildArrayPtr->at(0); + m_pointerLookup.insert((void*)ptr,cd); + } + +} + +void btBulletXmlWorldImporter::deSerializeCompoundShapeData(TiXmlNode* pParent) +{ + int ptr; + get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr); + + btCompoundShapeData* compoundData = (btCompoundShapeData*) btAlignedAlloc(sizeof(btCompoundShapeData),16); + + TiXmlNode* xmlColShape = pParent ->FirstChild("m_collisionShapeData"); + btAssert(xmlColShape); + deSerializeCollisionShapeData(xmlColShape,&compoundData->m_collisionShapeData); + + SET_INT_VALUE(pParent, compoundData,m_numChildShapes); + + TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData"); + btAssert(xmlShapeData ); + + { + TiXmlNode* node = pParent->FirstChild("m_childShapePtr");\ + btAssert(node); + while (node) + { + const char* txt = (node)->ToElement()->GetText(); + compoundData->m_childShapePtr = (btCompoundShapeChildData*) (int) atof(txt); + node = node->NextSibling("m_childShapePtr"); + } + //SET_POINTER_VALUE(xmlColShape, *compoundData,m_childShapePtr,btCompoundShapeChildData*); + + } + SET_FLOAT_VALUE(pParent, compoundData,m_collisionMargin); + + m_collisionShapeData.push_back((btCollisionShapeData*)compoundData); + m_pointerLookup.insert((void*)ptr,compoundData); + +} + +void btBulletXmlWorldImporter::deSerializeStaticPlaneShapeData(TiXmlNode* pParent) +{ + int ptr; + get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr); + + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) btAlignedAlloc(sizeof(btStaticPlaneShapeData),16); + + TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData"); + btAssert(xmlShapeData ); + deSerializeCollisionShapeData(xmlShapeData,&planeData->m_collisionShapeData); + + SET_VECTOR4_VALUE(pParent, planeData,m_localScaling); + SET_VECTOR4_VALUE(pParent, planeData,m_planeNormal); + SET_FLOAT_VALUE(pParent, planeData,m_planeConstant); + + m_collisionShapeData.push_back((btCollisionShapeData*)planeData); + m_pointerLookup.insert((void*)ptr,planeData); + +} + +void btBulletXmlWorldImporter::deSerializeDynamicsWorldData(TiXmlNode* pParent) +{ + btContactSolverInfo solverInfo; + //btVector3 gravity(0,0,0); + + //setDynamicsWorldInfo(gravity,solverInfo); + + //gravity and world info +} + +void btBulletXmlWorldImporter::deSerializeConvexInternalShapeData(TiXmlNode* pParent) +{ + int ptr=0; + get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr); + + + btConvexInternalShapeData* convexShape = (btConvexInternalShapeData*) btAlignedAlloc(sizeof(btConvexInternalShapeData),16); + memset(convexShape,0,sizeof(btConvexInternalShapeData)); + + TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData"); + btAssert(xmlShapeData ); + + deSerializeCollisionShapeData(xmlShapeData,&convexShape->m_collisionShapeData); + + + SET_FLOAT_VALUE(pParent,convexShape,m_collisionMargin) + SET_VECTOR4_VALUE(pParent,convexShape,m_localScaling) + SET_VECTOR4_VALUE(pParent,convexShape,m_implicitShapeDimensions) + + m_collisionShapeData.push_back((btCollisionShapeData*)convexShape); + m_pointerLookup.insert((void*)ptr,convexShape); + +} + +/* +enum btTypedConstraintType +{ + POINT2POINT_CONSTRAINT_TYPE=3, + HINGE_CONSTRAINT_TYPE, + CONETWIST_CONSTRAINT_TYPE, +// D6_CONSTRAINT_TYPE, + SLIDER_CONSTRAINT_TYPE, + CONTACT_CONSTRAINT_TYPE, + D6_SPRING_CONSTRAINT_TYPE, + GEAR_CONSTRAINT_TYPE, + MAX_CONSTRAINT_TYPE +}; +*/ + + +void btBulletXmlWorldImporter::deSerializeGeneric6DofConstraintData(TiXmlNode* pParent) +{ + int ptr=0; + get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr); + + btGeneric6DofConstraintData* dof6Data = (btGeneric6DofConstraintData*)btAlignedAlloc(sizeof(btGeneric6DofConstraintData),16); + + + TiXmlNode* n = pParent->FirstChild("m_typeConstraintData"); + if (n) + { + SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbA,btRigidBodyData*); + SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbB,btRigidBodyData*); + dof6Data->m_typeConstraintData.m_name = 0;//tbd + SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_objectType); + SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintType); + SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintId); + SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_needsFeedback); + SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_appliedImpulse); + SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_dbgDrawSize); + SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_disableCollisionsBetweenLinkedBodies); + SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_overrideNumSolverIterations); + SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_breakingImpulseThreshold); + SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_isEnabled); + + } + + SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbAFrame); + SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbBFrame); + SET_VECTOR4_VALUE(pParent, dof6Data, m_linearUpperLimit); + SET_VECTOR4_VALUE(pParent, dof6Data, m_linearLowerLimit); + SET_VECTOR4_VALUE(pParent, dof6Data, m_angularUpperLimit); + SET_VECTOR4_VALUE(pParent, dof6Data, m_angularLowerLimit); + SET_INT_VALUE(pParent, dof6Data,m_useLinearReferenceFrameA); + SET_INT_VALUE(pParent, dof6Data,m_useOffsetForConstraintFrame); + + m_constraintData.push_back((btTypedConstraintData*)dof6Data); + m_pointerLookup.insert((void*)ptr,dof6Data); +} + +void btBulletXmlWorldImporter::deSerializeRigidBodyFloatData(TiXmlNode* pParent) +{ + int ptr=0; + if (!get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr)) + { + m_fileOk = false; + return; + } + + btRigidBodyData* rbData = (btRigidBodyData*)btAlignedAlloc(sizeof(btRigidBodyData),16); + + TiXmlNode* n = pParent->FirstChild("m_collisionObjectData"); + + if (n) + { + SET_POINTER_VALUE(n,rbData->m_collisionObjectData,m_collisionShape, void*); + SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_worldTransform); + SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_interpolationWorldTransform); + SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationLinearVelocity) + SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationAngularVelocity) + SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_anisotropicFriction) + SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_contactProcessingThreshold); + SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_deactivationTime); + SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_friction); + SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_restitution); + SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_hitFraction); + SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdSweptSphereRadius); + SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdMotionThreshold); + SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_hasAnisotropicFriction); + SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_collisionFlags); + SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_islandTag1); + SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_companionId); + SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_activationState1); + SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_internalType); + SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_checkCollideWith); + } + +// SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity); + + SET_MATRIX33_VALUE(pParent,rbData,m_invInertiaTensorWorld); + + + SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity) + SET_VECTOR4_VALUE(pParent,rbData,m_angularVelocity) + SET_VECTOR4_VALUE(pParent,rbData,m_angularFactor) + SET_VECTOR4_VALUE(pParent,rbData,m_linearFactor) + SET_VECTOR4_VALUE(pParent,rbData,m_gravity) + SET_VECTOR4_VALUE(pParent,rbData,m_gravity_acceleration ) + SET_VECTOR4_VALUE(pParent,rbData,m_invInertiaLocal) + SET_VECTOR4_VALUE(pParent,rbData,m_totalTorque) + SET_VECTOR4_VALUE(pParent,rbData,m_totalForce) + SET_FLOAT_VALUE(pParent,rbData,m_inverseMass); + SET_FLOAT_VALUE(pParent,rbData,m_linearDamping); + SET_FLOAT_VALUE(pParent,rbData,m_angularDamping); + SET_FLOAT_VALUE(pParent,rbData,m_additionalDampingFactor); + SET_FLOAT_VALUE(pParent,rbData,m_additionalLinearDampingThresholdSqr); + SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingThresholdSqr); + SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingFactor); + SET_FLOAT_VALUE(pParent,rbData,m_angularSleepingThreshold); + SET_FLOAT_VALUE(pParent,rbData,m_linearSleepingThreshold); + SET_INT_VALUE(pParent,rbData,m_additionalDamping); + + + m_rigidBodyData.push_back(rbData); + m_pointerLookup.insert((void*)ptr,rbData); + +// rbData->m_collisionObjectData.m_collisionShape = (void*) (int)atof(txt); +} + +/* + TETRAHEDRAL_SHAPE_PROXYTYPE, + CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE, + , + CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE, + CUSTOM_POLYHEDRAL_SHAPE_TYPE, +//implicit convex shapes +IMPLICIT_CONVEX_SHAPES_START_HERE, + SPHERE_SHAPE_PROXYTYPE, + MULTI_SPHERE_SHAPE_PROXYTYPE, + CAPSULE_SHAPE_PROXYTYPE, + CONE_SHAPE_PROXYTYPE, + CONVEX_SHAPE_PROXYTYPE, + CYLINDER_SHAPE_PROXYTYPE, + UNIFORM_SCALING_SHAPE_PROXYTYPE, + MINKOWSKI_SUM_SHAPE_PROXYTYPE, + MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, + BOX_2D_SHAPE_PROXYTYPE, + CONVEX_2D_SHAPE_PROXYTYPE, + CUSTOM_CONVEX_SHAPE_TYPE, +//concave shapes +CONCAVE_SHAPES_START_HERE, + //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! + TRIANGLE_MESH_SHAPE_PROXYTYPE, + SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE, + ///used for demo integration FAST/Swift collision library and Bullet + FAST_CONCAVE_MESH_PROXYTYPE, + //terrain + TERRAIN_SHAPE_PROXYTYPE, +///Used for GIMPACT Trimesh integration + GIMPACT_SHAPE_PROXYTYPE, +///Multimaterial mesh + MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, + + , + , + CUSTOM_CONCAVE_SHAPE_TYPE, +CONCAVE_SHAPES_END_HERE, + + , + + SOFTBODY_SHAPE_PROXYTYPE, + HFFLUID_SHAPE_PROXYTYPE, + HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE, + INVALID_SHAPE_PROXYTYPE, + + MAX_BROADPHASE_COLLISION_TYPES +*/ + +void btBulletXmlWorldImporter::fixupConstraintData(btTypedConstraintData* tcd) +{ + if (tcd->m_rbA) + { + btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbA); + btAssert(ptrptr); + tcd->m_rbA = ptrptr? *ptrptr : 0; + } + if (tcd->m_rbB) + { + btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbB); + btAssert(ptrptr); + tcd->m_rbB = ptrptr? *ptrptr : 0; + } + +} + +void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* shapeData) +{ + + switch (shapeData->m_shapeType) + { + + case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShapeData* compound = (btCompoundShapeData*) shapeData; + + void** cdptr = m_pointerLookup.find((void*)compound->m_childShapePtr); + btCompoundShapeChildData** c = (btCompoundShapeChildData**)cdptr; + btAssert(c); + if (c) + { + compound->m_childShapePtr = *c; + } else + { + compound->m_childShapePtr = 0; + } + break; + } + + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexHullShapeData* convexData = (btConvexHullShapeData*)shapeData; + btVector3FloatData** ptrptr = (btVector3FloatData**)m_pointerLookup.find((void*)convexData->m_unscaledPointsFloatPtr); + btAssert(ptrptr); + if (ptrptr) + { + convexData->m_unscaledPointsFloatPtr = *ptrptr; + } else + { + convexData->m_unscaledPointsFloatPtr = 0; + } + break; + } + + case BOX_SHAPE_PROXYTYPE: + case TRIANGLE_SHAPE_PROXYTYPE: + case STATIC_PLANE_PROXYTYPE: + case EMPTY_SHAPE_PROXYTYPE: + break; + + default: + { + btAssert(0); + } + } +} + + +void btBulletXmlWorldImporter::auto_serialize_root_level_children(TiXmlNode* pParent) +{ + int numChildren = 0; + btAssert(pParent); + if (pParent) + { + TiXmlNode*pChild; + for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling(), numChildren++) + { +// printf("child Name=%s\n", pChild->Value()); + if (!strcmp(pChild->Value(),"btVector3FloatData")) + { + int ptr; + get_int_attribute_by_name(pChild->ToElement(),"pointer",&ptr); + + btAlignedObjectArray v; + deSerializeVector3FloatData(pChild,v); + int numVectors = v.size(); + btVector3FloatData* vectors= (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*numVectors,16); + for (int i=0;iValue(),"btGeneric6DofConstraintData")) + { + deSerializeGeneric6DofConstraintData(pChild); + continue; + } + + if (!strcmp(pChild->Value(),"btStaticPlaneShapeData")) + { + deSerializeStaticPlaneShapeData(pChild); + continue; + } + + if (!strcmp(pChild->Value(),"btCompoundShapeData")) + { + deSerializeCompoundShapeData(pChild); + continue; + } + + if (!strcmp(pChild->Value(),"btCompoundShapeChildData")) + { + deSerializeCompoundShapeChildData(pChild); + continue; + } + + if (!strcmp(pChild->Value(),"btConvexHullShapeData")) + { + deSerializeConvexHullShapeData(pChild); + continue; + } + + if (!strcmp(pChild->Value(),"btDynamicsWorldFloatData")) + { + deSerializeDynamicsWorldData(pChild); + continue; + } + + + if (!strcmp(pChild->Value(),"btConvexInternalShapeData")) + { + deSerializeConvexInternalShapeData(pChild); + continue; + } + if (!strcmp(pChild->Value(),"btRigidBodyFloatData")) + { + deSerializeRigidBodyFloatData(pChild); + continue; + } + + //printf("Error: btBulletXmlWorldImporter doesn't support %s yet\n", pChild->Value()); + // btAssert(0); + } + } + + ///================================================================= + ///fixup pointers in various places, in the right order + + //fixup compoundshape child data + for (int i=0;i* childDataArray = m_compoundShapeChildDataArrays[i]; + for (int c=0;csize();c++) + { + btCompoundShapeChildData* childData = &childDataArray->at(c); + btCollisionShapeData** ptrptr = (btCollisionShapeData**)m_pointerLookup[childData->m_childShape]; + btAssert(ptrptr); + if (ptrptr) + { + childData->m_childShape = *ptrptr; + } + } + } + + for (int i=0;im_collisionShapeData.size();i++) + { + btCollisionShapeData* shapeData = m_collisionShapeData[i]; + fixupCollisionDataPointers(shapeData); + + } + + ///now fixup pointers + for (int i=0;im_collisionObjectData.m_collisionShape); + //btAssert(ptrptr); + rbData->m_collisionObjectData.m_broadphaseHandle = 0; + rbData->m_collisionObjectData.m_rootCollisionShape = 0; + rbData->m_collisionObjectData.m_name = 0;//tbd + if (ptrptr) + { + rbData->m_collisionObjectData.m_collisionShape = *ptrptr; + } + } + + + + for (int i=0;im_collisionShapeData.size();i++) + { + btCollisionShapeData* shapeData = m_collisionShapeData[i]; + btCollisionShape* shape = convertCollisionShape(shapeData); + if (shape) + { + m_shapeMap.insert(shapeData,shape); + } + if (shape&& shapeData->m_name) + { + char* newname = duplicateName(shapeData->m_name); + m_objectNameMap.insert(shape,newname); + m_nameShapeMap.insert(newname,shape); + } + } + + for (int i=0;im_rbA); + if (ptrptr) + { + rbA = btRigidBody::upcast(*ptrptr); + } + } + { + btCollisionObject** ptrptr = m_bodyMap.find(tcd->m_rbB); + if (ptrptr) + { + rbB = btRigidBody::upcast(*ptrptr); + } + } + if (rbA || rbB) + { + convertConstraint(tcd,rbA,rbB,isDoublePrecision, m_fileVersion); + } + + } +} + +void btBulletXmlWorldImporter::auto_serialize(TiXmlNode* pParent) +{ +// TiXmlElement* root = pParent->FirstChildElement("bullet_physics"); + if (pParent) + { + TiXmlNode*pChild; + for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) + { + if (pChild->Type()==TiXmlNode::TINYXML_ELEMENT) + { +// printf("root Name=%s\n", pChild->Value()); + auto_serialize_root_level_children(pChild); + } + } + } else + { + printf("ERROR: no bullet_physics element\n"); + } +} + + + + +bool btBulletXmlWorldImporter::loadFile(const char* fileName) +{ + TiXmlDocument doc(fileName); + + bool loadOkay = doc.LoadFile(); + //dump_to_stdout(&doc,0); + + + if (loadOkay) + { + if (get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"version", &m_fileVersion)) + { + if (m_fileVersion==281) + { + m_fileOk = true; + int itemcount; + get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"itemcount", &itemcount); + + auto_serialize(&doc); + return m_fileOk; + + } + } + } + return false; +} + + + + diff --git a/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h new file mode 100644 index 0000000..034d191 --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h @@ -0,0 +1,82 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BULLET_XML_WORLD_IMPORTER_H +#define BT_BULLET_XML_WORLD_IMPORTER_H + +#include "LinearMath/btScalar.h" + +class btDynamicsWorld; +class TiXmlNode; +struct btConvexInternalShapeData; +struct btCollisionShapeData; +#ifdef BT_USE_DOUBLE_PRECISION +struct btRigidBodyDoubleData; +#define btRigidBodyData btRigidBodyDoubleData +#else +struct btRigidBodyFloatData; +#define btRigidBodyData btRigidBodyFloatData +#endif//BT_USE_DOUBLE_PRECISION +struct btTypedConstraintData; +struct btCompoundShapeChildData; + +#include "LinearMath/btAlignedObjectArray.h" +#include "btWorldImporter.h" + +class btBulletXmlWorldImporter : public btWorldImporter +{ + +protected: + btAlignedObjectArray m_collisionShapeData; + btAlignedObjectArray* > m_compoundShapeChildDataArrays; + btAlignedObjectArray m_rigidBodyData; + btAlignedObjectArray m_constraintData; + btHashMap m_pointerLookup; + int m_fileVersion; + bool m_fileOk; + + void auto_serialize_root_level_children(TiXmlNode* pParent); + void auto_serialize(TiXmlNode* pParent); + + void deSerializeVector3FloatData(TiXmlNode* pParent,btAlignedObjectArray& vectors); + + void fixupCollisionDataPointers(btCollisionShapeData* shapeData); + void fixupConstraintData(btTypedConstraintData* tcd); + + //collision shapes data + void deSerializeCollisionShapeData(TiXmlNode* pParent,btCollisionShapeData* colShapeData); + void deSerializeConvexInternalShapeData(TiXmlNode* pParent); + void deSerializeStaticPlaneShapeData(TiXmlNode* pParent); + void deSerializeCompoundShapeData(TiXmlNode* pParent); + void deSerializeCompoundShapeChildData(TiXmlNode* pParent); + void deSerializeConvexHullShapeData(TiXmlNode* pParent); + void deSerializeDynamicsWorldData(TiXmlNode* parent); + + ///bodies + void deSerializeRigidBodyFloatData(TiXmlNode* pParent); + + ///constraints + void deSerializeGeneric6DofConstraintData(TiXmlNode* pParent); + + public: + btBulletXmlWorldImporter(btDynamicsWorld* world); + + virtual ~btBulletXmlWorldImporter(); + + bool loadFile(const char* fileName); + +}; + +#endif //BT_BULLET_XML_WORLD_IMPORTER_H diff --git a/Extras/Serialize/BulletXmlWorldImporter/premake4.lua b/Extras/Serialize/BulletXmlWorldImporter/premake4.lua new file mode 100644 index 0000000..3813883 --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/premake4.lua @@ -0,0 +1,14 @@ + project "BulletXmlWorldImporter" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + "../BulletWorldImporter", + "../BulletFileLoader", + "../../../src" + } + + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/Extras/Serialize/BulletXmlWorldImporter/string_split.cpp b/Extras/Serialize/BulletXmlWorldImporter/string_split.cpp new file mode 100644 index 0000000..b3ae620 --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/string_split.cpp @@ -0,0 +1,250 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +//#include +#include +#include +#include + +#include "string_split.h" + +///todo: remove stl dependency + +namespace bullet_utils +{ + void split( btAlignedObjectArray&pieces, const std::string& vector_str, const std::string& separator) + { + char** strArray = str_split(vector_str.c_str(),separator.c_str()); + int numSubStr = str_array_len(strArray); + for (int i=0;i +#include "LinearMath/btAlignedObjectArray.h" + +#include + +namespace bullet_utils +{ + void split( btAlignedObjectArray&pieces, const std::string& vector_str, const std::string& separator); +}; + +///The string split C code is by Lars Wirzenius +///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char + + +/* Split a string into substrings. Return dynamic array of dynamically + allocated substrings, or NULL if there was an error. Caller is + expected to free the memory, for example with str_array_free. */ +char** str_split(const char* input, const char* sep); + +/* Free a dynamic array of dynamic strings. */ +void str_array_free(char** array); + +/* Return length of a NULL-delimited array of strings. */ +size_t str_array_len(char** array); + +#endif //STRING_SPLIT_H + diff --git a/Extras/Serialize/BulletXmlWorldImporter/tinystr.cpp b/Extras/Serialize/BulletXmlWorldImporter/tinystr.cpp new file mode 100644 index 0000000..590df2d --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/tinystr.cpp @@ -0,0 +1,111 @@ +/* +www.sourceforge.net/projects/tinyxml + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TIXML_USE_STL + +#include "tinystr.h" + +// Error value for find primitive +const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); + + +// Null rep. +TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; + + +void TiXmlString::reserve (size_type cap) +{ + if (cap > capacity()) + { + TiXmlString tmp; + tmp.init(length(), cap); + memcpy(tmp.start(), data(), length()); + swap(tmp); + } +} + + +TiXmlString& TiXmlString::assign(const char* str, size_type len) +{ + size_type cap = capacity(); + if (len > cap || cap > 3*(len + 8)) + { + TiXmlString tmp; + tmp.init(len); + memcpy(tmp.start(), str, len); + swap(tmp); + } + else + { + memmove(start(), str, len); + set_size(len); + } + return *this; +} + + +TiXmlString& TiXmlString::append(const char* str, size_type len) +{ + size_type newsize = length() + len; + if (newsize > capacity()) + { + reserve (newsize + capacity()); + } + memmove(finish(), str, len); + set_size(newsize); + return *this; +} + + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) +{ + TiXmlString tmp; + tmp.reserve(a.length() + b.length()); + tmp += a; + tmp += b; + return tmp; +} + +TiXmlString operator + (const TiXmlString & a, const char* b) +{ + TiXmlString tmp; + TiXmlString::size_type b_len = static_cast( strlen(b) ); + tmp.reserve(a.length() + b_len); + tmp += a; + tmp.append(b, b_len); + return tmp; +} + +TiXmlString operator + (const char* a, const TiXmlString & b) +{ + TiXmlString tmp; + TiXmlString::size_type a_len = static_cast( strlen(a) ); + tmp.reserve(a_len + b.length()); + tmp.append(a, a_len); + tmp += b; + return tmp; +} + + +#endif // TIXML_USE_STL diff --git a/Extras/Serialize/BulletXmlWorldImporter/tinystr.h b/Extras/Serialize/BulletXmlWorldImporter/tinystr.h new file mode 100644 index 0000000..c3cac34 --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/tinystr.h @@ -0,0 +1,305 @@ +/* +www.sourceforge.net/projects/tinyxml + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#include +#include + +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit +#elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit +#else + #define TIXML_EXPLICIT +#endif + + +/* + TiXmlString is an emulation of a subset of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) : rep_(0) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) + { + init( static_cast( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } + + private: + + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; + +} ; + + +inline bool operator == (const TiXmlString & a, const TiXmlString & b) +{ + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare +} +inline bool operator < (const TiXmlString & a, const TiXmlString & b) +{ + return strcmp(a.c_str(), b.c_str()) < 0; +} + +inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } +inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } +inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } +inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } + +inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } +inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } +inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } +inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); +TiXmlString operator + (const TiXmlString & a, const char* b); +TiXmlString operator + (const char* a, const TiXmlString & b); + + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } + +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/Extras/Serialize/BulletXmlWorldImporter/tinyxml.cpp b/Extras/Serialize/BulletXmlWorldImporter/tinyxml.cpp new file mode 100644 index 0000000..df75e72 --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/tinyxml.cpp @@ -0,0 +1,1886 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include + +#ifdef TIXML_USE_STL +#include +#include +#endif + +#include "tinyxml.h" + +FILE* TiXmlFOpen( const char* filename, const char* mode ); + +bool TiXmlBase::condenseWhiteSpace = true; + +// Microsoft compiler security +FILE* TiXmlFOpen( const char* filename, const char* mode ) +{ + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + FILE* fp = 0; + errno_t err = fopen_s( &fp, filename, mode ); + if ( !err && fp ) + return fp; + return 0; + #else + return fopen( filename, mode ); + #endif +} + +void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) +{ + int i=0; + + while( i<(int)str.length() ) + { + unsigned char c = (unsigned char) str[i]; + + if ( c == '&' + && i < ( (int)str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while ( i<(int)str.length()-1 ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 ) + { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); + #else + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + #endif + + //*ME: warning C4267: convert 'size_t' to 'int' + //*ME: Int-Cast to make compiler happy ... + outString->append( buf, (int)strlen( buf ) ); + ++i; + } + else + { + //char realc = (char) c; + //outString->append( &realc, 1 ); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } +} + + +TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; +} + + +TiXmlNode::~TiXmlNode() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNode::CopyTo( TiXmlNode* target ) const +{ + target->SetValue (value.c_str() ); + target->userData = userData; + target->location = location; +} + + +void TiXmlNode::Clear() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) +{ + assert( node->parent == 0 || node->parent == this ); + assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); + + if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + delete node; + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) +{ + if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) + { + if ( GetDocument() ) + GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) +{ + if ( !replaceThis ) + return 0; + + if ( replaceThis->parent != this ) + return 0; + + if ( withThis.ToDocument() ) { + // A document can never be a child. Thanks to Noam. + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) +{ + if ( !removeThis ) { + return false; + } + + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + delete removeThis; + return true; +} + +const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + + +const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +void TiXmlElement::RemoveAttribute( const char * name ) +{ + #ifdef TIXML_USE_STL + TIXML_STRING str( name ); + TiXmlAttribute* node = attributeSet.Find( str ); + #else + TiXmlAttribute* node = attributeSet.Find( name ); + #endif + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +const TiXmlElement* TiXmlNode::FirstChildElement() const +{ + const TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement() const +{ + const TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlDocument* TiXmlNode::GetDocument() const +{ + const TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + + +TiXmlElement::TiXmlElement (const char * _value) + : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + + +#ifdef TIXML_USE_STL +TiXmlElement::TiXmlElement( const std::string& _value ) + : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} +#endif + + +TiXmlElement::TiXmlElement( const TiXmlElement& copy) + : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) +{ + firstChild = lastChild = 0; + copy.CopyTo( this ); +} + + +TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base ) +{ + ClearThis(); + base.CopyTo( this ); + return *this; +} + + +TiXmlElement::~TiXmlElement() +{ + ClearThis(); +} + + +void TiXmlElement::ClearThis() +{ + Clear(); + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + + +const char* TiXmlElement::Attribute( const char* name ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return node->Value(); + return 0; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( attrib ) + return &attrib->ValueStr(); + return 0; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, int* i ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const char* result = 0; + + if ( attrib ) { + result = attrib->Value(); + if ( i ) { + attrib->QueryIntValue( i ); + } + } + return result; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const std::string* result = 0; + + if ( attrib ) { + result = &attrib->ValueStr(); + if ( i ) { + attrib->QueryIntValue( i ); + } + } + return result; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, double* d ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const char* result = 0; + + if ( attrib ) { + result = attrib->Value(); + if ( d ) { + attrib->QueryDoubleValue( d ); + } + } + return result; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + const std::string* result = 0; + + if ( attrib ) { + result = &attrib->ValueStr(); + if ( d ) { + attrib->QueryDoubleValue( d ); + } + } + return result; +} +#endif + + +int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryIntValue( ival ); +} + + +int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + int ival = 0; + int result = node->QueryIntValue( &ival ); + *value = (unsigned)ival; + return result; +} + + +int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + int result = TIXML_WRONG_TYPE; + if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) ) + { + *bval = true; + result = TIXML_SUCCESS; + } + else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN ) + || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) ) + { + *bval = false; + result = TIXML_SUCCESS; + } + return result; +} + + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryIntValue( ival ); +} +#endif + + +int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryDoubleValue( dval ); +} + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const +{ + const TiXmlAttribute* attrib = attributeSet.Find( name ); + if ( !attrib ) + return TIXML_NO_ATTRIBUTE; + return attrib->QueryDoubleValue( dval ); +} +#endif + + +void TiXmlElement::SetAttribute( const char * name, int val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetIntValue( val ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, int val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetIntValue( val ); + } +} +#endif + + +void TiXmlElement::SetDoubleAttribute( const char * name, double val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetDoubleValue( val ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetDoubleAttribute( const std::string& name, double val ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); + if ( attrib ) { + attrib->SetDoubleValue( val ); + } +} +#endif + + +void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname ); + if ( attrib ) { + attrib->SetValue( cvalue ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value ) +{ + TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name ); + if ( attrib ) { + attrib->SetValue( _value ); + } +} +#endif + + +void TiXmlElement::Print( FILE* cfile, int depth ) const +{ + int i; + assert( cfile ); + for ( i=0; iNext() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i", value.c_str() ); + } +} + + +void TiXmlElement::CopyTo( TiXmlElement* target ) const +{ + // superclass: + TiXmlNode::CopyTo( target ); + + // Element class: + // Clone the attributes, then clone the children. + const TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + target->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + +bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this, attributeSet.First() ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +TiXmlNode* TiXmlElement::Clone() const +{ + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +const char* TiXmlElement::GetText() const +{ + const TiXmlNode* child = this->FirstChild(); + if ( child ) { + const TiXmlText* childText = child->ToText(); + if ( childText ) { + return childText->Value(); + } + } + return 0; +} + + +TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + ClearError(); +} + +TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} + + +#ifdef TIXML_USE_STL +TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} +#endif + + +TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) +{ + copy.CopyTo( this ); +} + + +TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy ) +{ + Clear(); + copy.CopyTo( this ); + return *this; +} + + +bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) +{ + return LoadFile( Value(), encoding ); +} + + +bool TiXmlDocument::SaveFile() const +{ + return SaveFile( Value() ); +} + +bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) +{ + TIXML_STRING filename( _filename ); + value = filename; + + // reading in binary mode so that tinyxml can normalize the EOL + FILE* file = TiXmlFOpen( value.c_str (), "rb" ); + + if ( file ) + { + bool result = LoadFile( file, encoding ); + fclose( file ); + return result; + } + else + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } +} + +bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) +{ + if ( !file ) + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Delete the existing data: + Clear(); + location.Clear(); + + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length <= 0 ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Subtle bug here. TinyXml did use fgets. But from the XML spec: + // 2.11 End-of-Line Handling + // + // + // ...the XML processor MUST behave as if it normalized all line breaks in external + // parsed entities (including the document entity) on input, before parsing, by translating + // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to + // a single #xA character. + // + // + // It is not clear fgets does that, and certainly isn't clear it works cross platform. + // Generally, you expect fgets to translate from the convention of the OS to the c/unix + // convention, and not work generally. + + /* + while( fgets( buf, sizeof(buf), file ) ) + { + data += buf; + } + */ + + char* buf = new char[ length+1 ]; + buf[0] = 0; + + if ( fread( buf, length, 1, file ) != 1 ) { + delete [] buf; + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Process the buffer in place to normalize new lines. (See comment above.) + // Copies from the 'p' to 'q' pointer, where p can advance faster if + // a newline-carriage return is hit. + // + // Wikipedia: + // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or + // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... + // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others + // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS + // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 + + const char* p = buf; // the read head + char* q = buf; // the write head + const char CR = 0x0d; + const char LF = 0x0a; + + buf[length] = 0; + while( *p ) { + assert( p < (buf+length) ); + assert( q <= (buf+length) ); + assert( q <= p ); + + if ( *p == CR ) { + *q++ = LF; + p++; + if ( *p == LF ) { // check for CR+LF (and skip LF) + p++; + } + } + else { + *q++ = *p++; + } + } + assert( q <= (buf+length) ); + *q = 0; + + Parse( buf, 0, encoding ); + + delete [] buf; + return !Error(); +} + + +bool TiXmlDocument::SaveFile( const char * filename ) const +{ + // The old c stuff lives on... + FILE* fp = TiXmlFOpen( filename, "w" ); + if ( fp ) + { + bool result = SaveFile( fp ); + fclose( fp ); + return result; + } + return false; +} + + +bool TiXmlDocument::SaveFile( FILE* fp ) const +{ + if ( useMicrosoftBOM ) + { + const unsigned char TIXML_UTF_LEAD_0 = 0xefU; + const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; + const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + + fputc( TIXML_UTF_LEAD_0, fp ); + fputc( TIXML_UTF_LEAD_1, fp ); + fputc( TIXML_UTF_LEAD_2, fp ); + } + Print( fp, 0 ); + return (ferror(fp) == 0); +} + + +void TiXmlDocument::CopyTo( TiXmlDocument* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->error = error; + target->errorId = errorId; + target->errorDesc = errorDesc; + target->tabsize = tabsize; + target->errorLocation = errorLocation; + target->useMicrosoftBOM = useMicrosoftBOM; + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlDocument::Clone() const +{ + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlDocument::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } +} + + +bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +const TiXmlAttribute* TiXmlAttribute::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + +/* +TiXmlAttribute* TiXmlAttribute::Next() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} +*/ + +const TiXmlAttribute* TiXmlAttribute::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + +/* +TiXmlAttribute* TiXmlAttribute::Previous() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} +*/ + +void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + TIXML_STRING n, v; + + EncodeString( name, &n ); + EncodeString( value, &v ); + + if (value.find ('\"') == TIXML_STRING::npos) { + if ( cfile ) { + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; + } + } + else { + if ( cfile ) { + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; + } + } +} + + +int TiXmlAttribute::QueryIntValue( int* ival ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +int TiXmlAttribute::QueryDoubleValue( double* dval ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +void TiXmlAttribute::SetIntValue( int _value ) +{ + char buf [64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); + #else + sprintf (buf, "%d", _value); + #endif + SetValue (buf); +} + +void TiXmlAttribute::SetDoubleValue( double _value ) +{ + char buf [256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value); + #else + sprintf (buf, "%g", _value); + #endif + SetValue (buf); +} + +int TiXmlAttribute::IntValue() const +{ + return atoi (value.c_str ()); +} + +double TiXmlAttribute::DoubleValue() const +{ + return atof (value.c_str ()); +} + + +TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) +{ + copy.CopyTo( this ); +} + + +TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base ) +{ + Clear(); + base.CopyTo( this ); + return *this; +} + + +void TiXmlComment::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlComment::CopyTo( TiXmlComment* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlComment::Clone() const +{ + TiXmlComment* clone = new TiXmlComment(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlText::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + if ( cdata ) + { + int i; + fprintf( cfile, "\n" ); + for ( i=0; i\n", value.c_str() ); // unformatted output + } + else + { + TIXML_STRING buffer; + EncodeString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); + } +} + + +void TiXmlText::CopyTo( TiXmlText* target ) const +{ + TiXmlNode::CopyTo( target ); + target->cdata = cdata; +} + + +bool TiXmlText::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlText::Clone() const +{ + TiXmlText* clone = 0; + clone = new TiXmlText( "" ); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlDeclaration::TiXmlDeclaration( const char * _version, + const char * _encoding, + const char * _standalone ) + : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +#ifdef TIXML_USE_STL +TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ) + : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} +#endif + + +TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) + : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) +{ + copy.CopyTo( this ); +} + + +TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) +{ + Clear(); + copy.CopyTo( this ); + return *this; +} + + +void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + if ( cfile ) fprintf( cfile, "" ); + if ( str ) (*str) += "?>"; +} + + +void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->version = version; + target->encoding = encoding; + target->standalone = standalone; +} + + +bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlDeclaration::Clone() const +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlUnknown::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlUnknown::Clone() const +{ + TiXmlUnknown* clone = new TiXmlUnknown(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlAttributeSet::TiXmlAttributeSet() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSet::~TiXmlAttributeSet() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) +{ + #ifdef TIXML_USE_STL + assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. + #else + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + #endif + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + + +#ifdef TIXML_USE_STL +TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + +TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name ) +{ + TiXmlAttribute* attrib = Find( _name ); + if ( !attrib ) { + attrib = new TiXmlAttribute(); + Add( attrib ); + attrib->SetName( _name ); + } + return attrib; +} +#endif + + +TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; +} + + +TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name ) +{ + TiXmlAttribute* attrib = Find( _name ); + if ( !attrib ) { + attrib = new TiXmlAttribute(); + Add( attrib ); + attrib->SetName( _name ); + } + return attrib; +} + + +#ifdef TIXML_USE_STL +std::istream& operator>> (std::istream & in, TiXmlNode & base) +{ + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); + return in; +} +#endif + + +#ifdef TIXML_USE_STL +std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out << printer.Str(); + + return out; +} + + +std::string& operator<< (std::string& out, const TiXmlNode& base ) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out.append( printer.Str() ); + + return out; +} +#endif + + +TiXmlHandle TiXmlHandle::FirstChild() const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement() const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) +{ + DoIndent(); + buffer += "<"; + buffer += element.Value(); + + for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) + { + buffer += " "; + attrib->Print( 0, 0, &buffer ); + } + + if ( !element.FirstChild() ) + { + buffer += " />"; + DoLineBreak(); + } + else + { + buffer += ">"; + if ( element.FirstChild()->ToText() + && element.LastChild() == element.FirstChild() + && element.FirstChild()->ToText()->CDATA() == false ) + { + simpleTextPrint = true; + // no DoLineBreak()! + } + else + { + DoLineBreak(); + } + } + ++depth; + return true; +} + + +bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) +{ + --depth; + if ( !element.FirstChild() ) + { + // nothing. + } + else + { + if ( simpleTextPrint ) + { + simpleTextPrint = false; + } + else + { + DoIndent(); + } + buffer += ""; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlText& text ) +{ + if ( text.CDATA() ) + { + DoIndent(); + buffer += ""; + DoLineBreak(); + } + else if ( simpleTextPrint ) + { + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + } + else + { + DoIndent(); + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) +{ + DoIndent(); + declaration.Print( 0, 0, &buffer ); + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlComment& comment ) +{ + DoIndent(); + buffer += ""; + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) +{ + DoIndent(); + buffer += "<"; + buffer += unknown.Value(); + buffer += ">"; + DoLineBreak(); + return true; +} + diff --git a/Extras/Serialize/BulletXmlWorldImporter/tinyxml.h b/Extras/Serialize/BulletXmlWorldImporter/tinyxml.h new file mode 100644 index 0000000..d051548 --- /dev/null +++ b/Extras/Serialize/BulletXmlWorldImporter/tinyxml.h @@ -0,0 +1,1805 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include + #include + #include + #define TIXML_STRING std::string +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE +#define TIXML_SAFE + +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SSCANF sscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SSCANF sscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SSCANF sscanf + #else + #define TIXML_SNPRINTF snprintf + #define TIXML_SSCANF sscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 6; +const int TIXML_PATCH_VERSION = 2; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +/** + Implements the interface to the "Visitor pattern" (see the Accept() method.) + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simply called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + + You should never change the document from a callback. + + @sa TiXmlNode::Accept() +*/ +class TiXmlVisitor +{ +public: + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } + /// Visit an unknown node + virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } +}; + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, std::string + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + or they will be transformed into entities! + */ + static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + TINYXML_DOCUMENT, + TINYXML_ELEMENT, + TINYXML_COMMENT, + TINYXML_UNKNOWN, + TINYXML_TEXT, + TINYXML_DECLARATION, + TINYXML_TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + const TIXML_STRING& ValueTStr() const { return value; } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT, + TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* FindOrCreate( const char* _name ); + +# ifdef TIXML_USE_STL + TiXmlAttribute* Find( const std::string& _name ) const; + TiXmlAttribute* FindOrCreate( const std::string& _name ); +# endif + + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + TiXmlElement& operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute(). + int QueryUnsignedAttribute( const char* name, unsigned* _value ) const; + /** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). + Note that '1', 'true', or 'yes' are considered true, while '0', 'false' + and 'no' are considered false. + */ + int QueryBoolAttribute( const char* name, bool* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + #ifdef TIXML_USE_STL + /// QueryStringAttribute examines the attribute - see QueryIntAttribute(). + int QueryStringAttribute( const char* name, std::string* _value ) const { + const char* cstr = Attribute( name ); + if ( cstr ) { + *_value = std::string( cstr ); + return TIXML_SUCCESS; + } + return TIXML_NO_ATTRIBUTE; + } + + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + NOTE: This method doesn't work correctly for 'string' types that contain spaces. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + std::stringstream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + + int QueryValueAttribute( const std::string& name, std::string* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + *outValue = node->ValueStr(); + return TIXML_SUCCESS; + } + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const std::string* Attribute( const std::string& name ) const; + const std::string* Attribute( const std::string& name, int* i ) const; + const std::string* Attribute( const std::string& name, double* d ) const; + int QueryIntAttribute( const std::string& name, int* _value ) const; + int QueryDoubleAttribute( const std::string& name, double* _value ) const; + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + ///< STL std::string form. + void SetDoubleAttribute( const std::string& name, double value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + TiXmlComment& operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); } + TiXmlText& operator=( const TiXmlText& base ) { base.CopyTo( this ); return *this; } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + TiXmlDeclaration& operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); } + TiXmlUnknown& operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); return *this; } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + TiXmlDocument& operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { Print( stdout, 0 ); } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } + +private: + TiXmlNode* node; +}; + + +/** Print to memory functionality. The TiXmlPrinter is useful when you need to: + + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) + + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. + + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); + + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim +*/ +class TiXmlPrinter : public TiXmlVisitor +{ +public: + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const std::string& Str() { return buffer; } + #endif + +private: + void DoIndent() { + for( int i=0; i +#include + +#include "tinyxml.h" + +//#define DEBUG_PARSER +#if defined( DEBUG_PARSER ) +# if defined( DEBUG ) && defined( _MSC_VER ) +# include +# define TIXML_LOG OutputDebugString +# else +# define TIXML_LOG printf +# endif +#endif + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] = +{ + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } +}; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// Including the basic of this table, which determines the #bytes in the +// sequence from the lead byte. 1 placed for invalid sequences -- +// although the result will be junk, pass it through as much as possible. +// Beware of the non-characters in UTF-8: +// ef bb bf (Microsoft "lead bytes") +// ef bf be +// ef bf bf + +const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + +const int TiXmlBase::utf8ByteTable[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid +}; + + +void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) + *length = 1; + else if ( input < 0x800 ) + *length = 2; + else if ( input < 0x10000 ) + *length = 3; + else if ( input < 0x200000 ) + *length = 4; + else + { *length = 0; return; } // This code won't covert this correctly anyway. + + output += *length; + + // Scary scary fall throughs. + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + } +} + + +/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalpha( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalpha( anyByte ); +// } +} + + +/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalnum( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalnum( anyByte ); +// } +} + + +class TiXmlParsingData +{ + friend class TiXmlDocument; + public: + void Stamp( const char* now, TiXmlEncoding encoding ); + + const TiXmlCursor& Cursor() const { return cursor; } + + private: + // Only used by the document! + TiXmlParsingData( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const char* stamp; + int tabsize; +}; + + +void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Treat p as unsigned, so we have a happy compiler. + const unsigned char* pU = (const unsigned char*)p; + + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*pU) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + case TIXML_UTF_LEAD_0: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( *(p+1) && *(p+2) ) + { + // In these cases, don't advance the column. These are + // 0-width spaces. + if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) + p += 3; + else + { p +=3; ++col; } // A normal character. + } + } + else + { + ++p; + ++col; + } + break; + + default: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // Eat the 1 to 4 byte utf8 character. + int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; + if ( step == 0 ) + step = 1; // Error case from bad encoding, but handle gracefully. + p += step; + + // Just advance one column, of course. + ++col; + } + else + { + ++p; + ++col; + } + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) +{ + if ( !p || !*p ) + { + return 0; + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + while ( *p ) + { + const unsigned char* pU = (const unsigned char*)p; + + // Skip the stupid Microsoft UTF-8 Byte order marks + if ( *(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==TIXML_UTF_LEAD_1 + && *(pU+2)==TIXML_UTF_LEAD_2 ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbeU ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbfU ) + { + p += 3; + continue; + } + + if ( IsWhiteSpace( *p ) ) // Still using old rules for white space. + ++p; + else + break; + } + } + else + { + while ( *p && IsWhiteSpace( *p ) ) + ++p; + } + + return p; +} + +#ifdef TIXML_USE_STL +/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + // At this scope, we can't get to a document. So fail silently. + if ( !IsWhiteSpace( c ) || c <= 0 ) + return true; + + *tag += (char) in->get(); + } +} + +/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) +{ + //assert( character > 0 && character < 128 ); // else it won't work in utf-8 + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + if ( c <= 0 ) // Silent failure: can't get document at this scope + return false; + + in->get(); + *tag += (char) c; + } + return false; +} +#endif + +// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The +// "assign" optimization removes over 10% of the execution time. +// +const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) +{ + // Oddly, not supported on some comilers, + //name->clear(); + // So use this: + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // Of course, in unicode, tinyxml has no idea what a letter *is*. The + // algorithm is generous. + // + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) + { + const char* start = p; + while( p && *p + && ( IsAlphaNum( (unsigned char ) *p, encoding ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + //(*name) += *p; // expensive + ++p; + } + if ( p-start > 0 ) { + name->assign( start, p-start ); + } + return p; + } + return 0; +} + +const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) +{ + // Presume an entity, and pull it out. + TIXML_STRING ent; + int i; + *length = 0; + + if ( *(p+1) && *(p+1) == '#' && *(p+2) ) + { + unsigned long ucs = 0; + ptrdiff_t delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) + { + // Hexadecimal. + if ( !*(p+3) ) return 0; + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != 'x' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else if ( *q >= 'a' && *q <= 'f' ) + ucs += mult * (*q - 'a' + 10); + else if ( *q >= 'A' && *q <= 'F' ) + ucs += mult * (*q - 'A' + 10 ); + else + return 0; + mult *= 16; + --q; + } + } + else + { + // Decimal. + if ( !*(p+2) ) return 0; + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != '#' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else + return 0; + mult *= 10; + --q; + } + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + } + else + { + *value = (char)ucs; + *length = 1; + } + return p + delta + 1; + } + + // Now try to match it. + for( i=0; iappend( cArr, len ); + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p, encoding ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( IsWhiteSpace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (*text) += ' '; + whitespace = false; + } + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + if ( len == 1 ) + (*text) += cArr[0]; // more efficient + else + text->append( cArr, len ); + } + } + } + if ( p && *p ) + p += strlen( endTag ); + return ( p && *p ) ? p : 0; +} + +#ifdef TIXML_USE_STL + +void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + while ( in->good() ) + { + int tagIndex = (int) tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + if ( c <= 0 ) + { + SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + break; + } + (*tag) += (char) c; + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); +} + +#endif + +const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + if ( encoding == TIXML_ENCODING_UNKNOWN ) + { + // Check for the Microsoft UTF-8 lead bytes. + const unsigned char* pU = (const unsigned char*)p; + if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 + && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 + && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) + { + encoding = TIXML_ENCODING_UTF8; + useMicrosoftBOM = true; + } + } + + p = SkipWhiteSpace( p, encoding ); + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, &data, encoding ); + LinkEndChild( node ); + } + else + { + break; + } + + // Did we get encoding info? + if ( encoding == TIXML_ENCODING_UNKNOWN + && node->ToDeclaration() ) + { + TiXmlDeclaration* dec = node->ToDeclaration(); + const char* enc = dec->Encoding(); + assert( enc ); + + if ( *enc == 0 ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice + else + encoding = TIXML_ENCODING_LEGACY; + } + + p = SkipWhiteSpace( p, encoding ); + } + + // Was this empty? + if ( !firstChild ) { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); + return 0; + } + + // All is well. + return p; +} + +void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + data->Stamp( pError, encoding ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) +{ + TiXmlNode* returnNode = 0; + + p = SkipWhiteSpace( p, encoding ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + p = SkipWhiteSpace( p, encoding ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: "; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + if ( document ) + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // [ 1475201 ] TinyXML parses entities in comments + // Oops - ReadText doesn't work, because we don't want to parse the entities. + // p = ReadText( p, &value, false, endTag, false, encoding ); + // + // from the XML spec: + /* + [Definition: Comments may appear anywhere in a document outside other markup; in addition, + they may appear within the document type declaration at places allowed by the grammar. + They are not part of the document's character data; an XML processor MAY, but need not, + make it possible for an application to retrieve the text of comments. For compatibility, + the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity + references MUST NOT be recognized within comments. + + An example of a comment: + + + */ + + value = ""; + // Keep all the white space. + while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) + { + value.append( p, 1 ); + ++p; + } + if ( p && *p ) + p += strlen( endTag ); + + return p; +} + + +const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) return 0; + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + const char* end; + const char SINGLE_QUOTE = '\''; + const char DOUBLE_QUOTE = '\"'; + + if ( *p == SINGLE_QUOTE ) + { + ++p; + end = "\'"; // single quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else if ( *p == DOUBLE_QUOTE ) + { + ++p; + end = "\""; // double quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !IsWhiteSpace( *p ) // whitespace + && *p != '/' && *p != '>' ) // tag end + { + if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { + // [ 1451649 ] Attribute values with trailing quotes not handled correctly + // We did not have an opening quote but seem to have a + // closing one. Give up and throw an error. + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( !cdata && (c == '<' ) ) + { + return; + } + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + in->get(); // "commits" the peek made above + + if ( cdata && c == '>' && tag->size() >= 3 ) { + size_t len = tag->size(); + if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { + // terminator of cdata. + return; + } + } + } +} +#endif + +const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + value = ""; + TiXmlDocument* document = GetDocument(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + + const char* const startTag = ""; + + if ( cdata || StringEqual( p, startTag, false, encoding ) ) + { + cdata = true; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + if ( document ) + document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // Keep all the white space, ignore the encoding, etc. + while ( p && *p + && !StringEqual( p, endTag, false, encoding ) + ) + { + value += *p; + ++p; + } + + TIXML_STRING dummy; + p = ReadText( p, &dummy, false, endTag, false, encoding ); + return p; + } + else + { + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false, encoding ); + if ( p && *p ) + return p-1; // don't truncate the '<' + return 0; + } +} + +#ifdef TIXML_USE_STL +void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) +{ + p = SkipWhiteSpace( p, _encoding ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); + return 0; + } + if ( data ) + { + data->Stamp( p, _encoding ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p, _encoding ); + if ( StringEqual( p, "version", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlText::Blank() const +{ + for ( unsigned i=0; i +#include "bDNA.h" +#include "bBlenderFile.h" +#include "btBulletFile.h" +#include "bCommon.h" +#include +#include +#include + +bool isBulletFile = false; + +using namespace bParse; +typedef std::string bString; + +/////////////////////////////////////////////////////////////////////////////// +typedef std::map bStringMap; +typedef std::vector bVariableList; +typedef std::vector bStringList; + + +/////////////////////////////////////////////////////////////////////////////// +static FILE *dump = 0; +static bDNA *mDNA =0; +static bStringMap mStructs; + + +/////////////////////////////////////////////////////////////////////////////// +class bVariable +{ +public: + bVariable(); + ~bVariable(); + + + bString dataType; + bString variableName; + + + bString functionName; + bString classCtor; + + bString memberVariable; + bString memberDataType; + bString functionArgs; + + + void initialize(bString dataType, bString variable, bStringMap refDataTable); + + bool isPtr; + bool isFunctionPtr; + bool isPtrToPtr; + bool isArray; + bool isCharArray; + bool isListBase; + bool isPadding; + bool isCommentedOut; + bool isGeneratedType; + bool isbString; +}; + +/////////////////////////////////////////////////////////////////////////////// +bool dataTypeStandard(bString dataType) +{ + if (dataType == "char") + return true; + if (dataType == "short") + return true; + if (dataType == "int") + return true; + if (dataType == "long") + return true; + if (dataType == "float") + return true; + if (dataType == "double") + return true; + if (dataType == "void") + return true; + if (dataType == "btScalar") + return true; + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +void writeTemplate(short *structData) +{ + bString type = mDNA->getType(structData[0]); + bString className=type; + bString prefix = isBulletFile? "bullet_" : "blender_"; + + int thisLen = structData[1]; + structData+=2; + + bString fileName = prefix+type; + + bVariableList dataTypes; + bStringMap includeFiles; + + + for (int dataVal =0; dataValgetType(structData[0]); + bString dataName = mDNA->getName(structData[1]); + { + bString newDataType = ""; + bString newDataName = ""; + + bStringMap::iterator addB = mStructs.find(dataType); + if (addB != mStructs.end()) + { + newDataType = addB->second; + newDataName = dataName; + } + + else + { + if (dataTypeStandard(dataType)) + { + newDataType = dataType; + newDataName = dataName; + } + else + { + // Unresolved + // set it to an empty struct + // if it's not a ptr generate an error + newDataType = "bInvalidHandle"; + newDataName = dataName; + + if (dataName[0] != '*') + { + } + + } + } + + if (!newDataType.empty() && !newDataName.empty()) + { + bVariable var = bVariable(); + var.initialize(newDataType, newDataName, mStructs); + dataTypes.push_back(var); + } + } + + + bStringMap::iterator include = mStructs.find(dataType); + if (include != mStructs.end()) + { + if (dataName[0] != '*') + { + if (includeFiles.find(dataType)== includeFiles.end()) + { + includeFiles[dataType]=prefix+dataType; + } + } + } + } + + + fprintf(dump, "###############################################################\n"); + fprintf(dump, "%s = bStructClass()\n", fileName.c_str()); + fprintf(dump, "%s.name = '%s'\n", fileName.c_str(), className.c_str()); + fprintf(dump, "%s.filename = '%s'\n", fileName.c_str(), fileName.c_str()); + + bVariableList::iterator vars = dataTypes.begin(); + while (vars!= dataTypes.end()) + { + fprintf(dump, "%s.dataTypes.append('%s %s')\n", fileName.c_str(), vars->dataType.c_str(), vars->variableName.c_str()); + vars++; + } + + bStringMap::iterator inc = includeFiles.begin(); + while (inc != includeFiles.end()) + { + fprintf(dump, "%s.includes.append('%s.h')\n", fileName.c_str(), inc->second.c_str()); + inc++; + } + fprintf(dump, "DataTypeList.append(%s)\n", fileName.c_str()); +} + + +/////////////////////////////////////////////////////////////////////////////// +char data[]={ +"\n" +"class bStructClass:\n" +" def __init__(self):\n" +" self.name = \"\";\n" +" self.filename = \"\";\n" +" self.includes = []\n" +" self.dataTypes = []\n" +"\n\n" +"DataTypeList = []\n" +}; + + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc,char** argv) +{ + using namespace bParse; + dump = fopen("dump.py", "w"); + + if (!dump) return 0; + fprintf(dump, "%s\n", data); + + + char* filename = "../../../Demos/SerializeDemo/testFile.bullet"; + + if (argc==2) + filename = argv[1]; + + bString fileStr(filename); + bString extension(".bullet"); + + int index2 = fileStr.find(extension); + if (index2>=0) + isBulletFile=true; + + + FILE* fp = fopen (filename,"rb"); + + if (!fp) + { + printf("error: file not found %s\n",filename); + exit(0); + } + + char* memBuf = 0; + int len = 0; + + long currentpos = ftell(fp); /* save current cursor position */ + long newpos; + int bytesRead; + + fseek(fp, 0, SEEK_END); /* seek to end */ + newpos = ftell(fp); /* find position of end -- this is the length */ + fseek(fp, currentpos, SEEK_SET); /* restore previous cursor position */ + + len = newpos; + + memBuf = (char*)malloc(len); + bytesRead = fread(memBuf,len,1,fp); + + bool swap = false; + + + if (isBulletFile) + { + btBulletFile f(memBuf,len); + swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0; + } else + { + bBlenderFile f(memBuf,len); + swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0; + } + + + + + + char *blenderData = memBuf; + int sdnaPos=0; + int mDataStart = 12; + + char *tempBuffer = blenderData; + for (int i=0; iinitMemory(); + + mDNA->init(memBuf+sdnaPos, len-sdnaPos, swap); + + + for (int i=0; igetNumStructs(); i++) + { + short *structData = mDNA->getStruct(i); + bString type = mDNA->getType(structData[0]); + + bString className = type; + mStructs[type]=className; + } + + + for (int i=0; igetNumStructs(); i++) + { + short *structData = mDNA->getStruct(i); + writeTemplate(structData); + } + + delete mDNA; + fclose(dump); + return 0; +} +/////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +int _getArraySize(char* str) +{ + int a, mul=1; + char stri[100], *cp=0; + int len = (int)strlen(str); + + memcpy(stri, str, len+1); + for (a=0; a + +///work-in-progress +///This ReadBulletSample is kept as simple as possible without dependencies to the Bullet SDK. +///It can be used to load .bullet data for other physics SDKs +///For a more complete example how to load and convert Bullet data using the Bullet SDK check out +///the Bullet/Demos/SerializeDemo and Bullet/Serialize/BulletWorldImporter + +using namespace Bullet; + +enum LocalBroadphaseNativeTypes +{ + // polyhedral convex shapes + BOX_SHAPE_PROXYTYPE, + TRIANGLE_SHAPE_PROXYTYPE, + TETRAHEDRAL_SHAPE_PROXYTYPE, + CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE, + CONVEX_HULL_SHAPE_PROXYTYPE, + CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE, + CUSTOM_POLYHEDRAL_SHAPE_TYPE, +//implicit convex shapes +IMPLICIT_CONVEX_SHAPES_START_HERE, + SPHERE_SHAPE_PROXYTYPE, + MULTI_SPHERE_SHAPE_PROXYTYPE, + CAPSULE_SHAPE_PROXYTYPE, + CONE_SHAPE_PROXYTYPE, + CONVEX_SHAPE_PROXYTYPE, + CYLINDER_SHAPE_PROXYTYPE, + UNIFORM_SCALING_SHAPE_PROXYTYPE, + MINKOWSKI_SUM_SHAPE_PROXYTYPE, + MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, + BOX_2D_SHAPE_PROXYTYPE, + CONVEX_2D_SHAPE_PROXYTYPE, + CUSTOM_CONVEX_SHAPE_TYPE, +//concave shapes +CONCAVE_SHAPES_START_HERE, + //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! + TRIANGLE_MESH_SHAPE_PROXYTYPE, + SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE, + ///used for demo integration FAST/Swift collision library and Bullet + FAST_CONCAVE_MESH_PROXYTYPE, + //terrain + TERRAIN_SHAPE_PROXYTYPE, +///Used for GIMPACT Trimesh integration + GIMPACT_SHAPE_PROXYTYPE, +///Multimaterial mesh + MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, + + EMPTY_SHAPE_PROXYTYPE, + STATIC_PLANE_PROXYTYPE, + CUSTOM_CONCAVE_SHAPE_TYPE, +CONCAVE_SHAPES_END_HERE, + + COMPOUND_SHAPE_PROXYTYPE, + + SOFTBODY_SHAPE_PROXYTYPE, + HFFLUID_SHAPE_PROXYTYPE, + HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE, + INVALID_SHAPE_PROXYTYPE, + + MAX_BROADPHASE_COLLISION_TYPES + +}; + +btBulletDataExtractor::btBulletDataExtractor() +{ +} + +btBulletDataExtractor::~btBulletDataExtractor() +{ +} + +void btBulletDataExtractor::convertAllObjects(bParse::btBulletFile* bulletFile2) +{ + int i; + + for (i=0;im_collisionShapes.size();i++) + { + btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i]; + if (shapeData->m_name) + printf("converting shape %s\n", shapeData->m_name); + void* shape = convertCollisionShape(shapeData); + } + +} + + + +void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shapeData ) +{ + void* shape = 0; + + switch (shapeData->m_shapeType) + { + case STATIC_PLANE_PROXYTYPE: + { + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; + void* shape = createPlaneShape(planeData->m_planeNormal,planeData->m_planeConstant, planeData->m_localScaling); + break; + } + + case CYLINDER_SHAPE_PROXYTYPE: + case CAPSULE_SHAPE_PROXYTYPE: + case BOX_SHAPE_PROXYTYPE: + case SPHERE_SHAPE_PROXYTYPE: + case MULTI_SPHERE_SHAPE_PROXYTYPE: + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; + + switch (shapeData->m_shapeType) + { + case BOX_SHAPE_PROXYTYPE: + { + shape = createBoxShape(bsd->m_implicitShapeDimensions, bsd->m_localScaling,bsd->m_collisionMargin); + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + shape = createSphereShape(bsd->m_implicitShapeDimensions.m_floats[0],bsd->m_localScaling, bsd->m_collisionMargin); + break; + } +#if 0 + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData; + switch (capData->m_upAxis) + { + case 0: + { + shape = createCapsuleShapeX(implicitShapeDimensions.getY(),2*implicitShapeDimensions.getX()); + break; + } + case 1: + { + shape = createCapsuleShapeY(implicitShapeDimensions.getX(),2*implicitShapeDimensions.getY()); + break; + } + case 2: + { + shape = createCapsuleShapeZ(implicitShapeDimensions.getX(),2*implicitShapeDimensions.getZ()); + break; + } + default: + { + printf("error: wrong up axis for btCapsuleShape\n"); + } + + }; + + break; + } + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData; + btVector3 halfExtents = implicitShapeDimensions+margin; + switch (cylData->m_upAxis) + { + case 0: + { + shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX()); + break; + } + case 1: + { + shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY()); + break; + } + case 2: + { + shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cylinder up axis\n"); + } + + }; + + + + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; + int numSpheres = mss->m_localPositionArraySize; + int i; + for ( i=0;im_localPositionArrayPtr[i].m_pos); + radii[i] = mss->m_localPositionArrayPtr[i].m_radius; + } + shape = new btMultiSphereShape(&tmpPos[0],&radii[0],numSpheres); + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; + int numPoints = convexData->m_numUnscaledPoints; + + btAlignedObjectArray tmpPoints; + tmpPoints.resize(numPoints); + int i; + for ( i=0;im_unscaledPointsFloatPtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); + } + shape = createConvexHullShape(); + + return shape; + break; + } +#endif + + default: + { + printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType); + } + } + + break; + } +#if 0 + case TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData; + btTriangleIndexVertexArray* meshInterface = createMeshInterface(trimesh->m_meshInterface); + if (!meshInterface->getNumSubParts()) + { + return 0; + } + + btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); + meshInterface->setScaling(scaling); + + + btOptimizedBvh* bvh = 0; + + btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh); + trimeshShape->setMargin(trimesh->m_collisionMargin); + shape = trimeshShape; + + if (trimesh->m_triangleInfoMap) + { + btTriangleInfoMap* map = createTriangleInfoMap(); + map->deSerialize(*trimesh->m_triangleInfoMap); + trimeshShape->setTriangleInfoMap(map); + +#ifdef USE_INTERNAL_EDGE_UTILITY + gContactAddedCallback = btAdjustInternalEdgeContactsCallback; +#endif //USE_INTERNAL_EDGE_UTILITY + + } + + //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin); + break; + } + case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; + btCompoundShape* compoundShape = createCompoundShape(); + + + btAlignedObjectArray childShapes; + for (int i=0;im_numChildShapes;i++) + { + btCollisionShape* childShape = convertCollisionShape(compoundData->m_childShapePtr[i].m_childShape); + if (childShape) + { + btTransform localTransform; + localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); + compoundShape->addChildShape(localTransform,childShape); + } else + { + printf("error: couldn't create childShape for compoundShape\n"); + } + + } + shape = compoundShape; + + break; + } + + case GIMPACT_SHAPE_PROXYTYPE: + { + btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData; + if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE) + { + btTriangleIndexVertexArray* meshInterface = createMeshInterface(gimpactData->m_meshInterface); + btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface); + btVector3 localScaling; + localScaling.deSerializeFloat(gimpactData->m_localScaling); + gimpactShape->setLocalScaling(localScaling); + gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin)); + gimpactShape->updateBound(); + shape = gimpactShape; + } else + { + printf("unsupported gimpact sub type\n"); + } + break; + } + case SOFTBODY_SHAPE_PROXYTYPE: + { + return 0; + } +#endif + default: + { + printf("unsupported shape type (%d)\n",shapeData->m_shapeType); + } + } + + return shape; + +} + +void* btBulletDataExtractor::createBoxShape( const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin) +{ + printf("createBoxShape with halfDimensions %f,%f,%f\n",halfDimensions.m_floats[0], halfDimensions.m_floats[1],halfDimensions.m_floats[2]); + return 0; +} + +void* btBulletDataExtractor::createSphereShape( float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin) +{ + printf("createSphereShape with radius %f\n",radius); + return 0; +} + + +void* btBulletDataExtractor::createPlaneShape( const btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling) +{ + printf("createPlaneShape with normal %f,%f,%f and planeConstant\n",planeNormal.m_floats[0], planeNormal.m_floats[1],planeNormal.m_floats[2],planeConstant); + return 0; +} + diff --git a/Extras/Serialize/ReadBulletSample/BulletDataExtractor.h b/Extras/Serialize/ReadBulletSample/BulletDataExtractor.h new file mode 100644 index 0000000..f30b216 --- /dev/null +++ b/Extras/Serialize/ReadBulletSample/BulletDataExtractor.h @@ -0,0 +1,32 @@ +#ifndef BULLET_DATA_EXTRACTOR_H +#define BULLET_DATA_EXTRACTOR_H + + +#include "../BulletFileLoader/autogenerated/bullet.h" + +namespace bParse +{ + class btBulletFile; +}; + +class btBulletDataExtractor +{ + public: + + btBulletDataExtractor(); + + virtual ~btBulletDataExtractor(); + + virtual void convertAllObjects(bParse::btBulletFile* bulletFile); + + virtual void* convertCollisionShape( Bullet::btCollisionShapeData* shapeData ); + + virtual void* createPlaneShape( const Bullet::btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling); + + virtual void* createBoxShape( const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin); + + virtual void* createSphereShape( float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin); + +}; + +#endif //BULLET_DATA_EXTRACTOR_H \ No newline at end of file diff --git a/Extras/Serialize/ReadBulletSample/CMakeLists.txt b/Extras/Serialize/ReadBulletSample/CMakeLists.txt new file mode 100644 index 0000000..e819b9e --- /dev/null +++ b/Extras/Serialize/ReadBulletSample/CMakeLists.txt @@ -0,0 +1,33 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + +LINK_LIBRARIES( + BulletFileLoader +) +IF (WIN32) + SET(ADDITIONAL_SRC + ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc + ) +ENDIF() + +SET(READBULLET_SRC + main.cpp + BulletDataExtractor.cpp + BulletDataExtractor.h + ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btSerializer.cpp + ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btAlignedAllocator.cpp +) + +ADD_EXECUTABLE(AppReadBulletSample + ${READBULLET_SRC} + ${ADDITIONAL_SRC} +) + + +IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) + SET_TARGET_PROPERTIES(AppReadBulletSample PROPERTIES DEBUG_POSTFIX "_Debug") + SET_TARGET_PROPERTIES(AppReadBulletSample PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") + SET_TARGET_PROPERTIES(AppReadBulletSample PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") +ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) \ No newline at end of file diff --git a/Extras/Serialize/ReadBulletSample/main.cpp b/Extras/Serialize/ReadBulletSample/main.cpp new file mode 100644 index 0000000..20719ed --- /dev/null +++ b/Extras/Serialize/ReadBulletSample/main.cpp @@ -0,0 +1,63 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include +#include "../BulletFileLoader/btBulletFile.h" +#include "BulletDataExtractor.h" + +///This ReadBulletSample is kept as simple as possible without dependencies to the Bullet SDK. +///It can be used to load .bullet data for other physics SDKs +///For a more complete example how to load and convert Bullet data using the Bullet SDK check out +///the Bullet/Demos/SerializeDemo and Bullet/Serialize/BulletWorldImporter + +int main(int argc, char** argv) +{ + const char* fileName="testFile.bullet"; + bool verboseDumpAllTypes = false; + + bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName); + + bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0; + + if (ok) + bulletFile2->parse(verboseDumpAllTypes); + else + { + printf("Error loading file %s.\n",fileName); + exit(0); + } + ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0; + if (!ok) + { + printf("Error parsing file %s.\n",fileName); + exit(0); + } + + if (verboseDumpAllTypes) + { + bulletFile2->dumpChunks(bulletFile2->getFileDNA()); + } + + + btBulletDataExtractor extractor; + + extractor.convertAllObjects(bulletFile2); + + delete bulletFile2; + + return 0; +} + diff --git a/Extras/Serialize/makesdna/CMakeLists.txt b/Extras/Serialize/makesdna/CMakeLists.txt new file mode 100644 index 0000000..9f5d5c6 --- /dev/null +++ b/Extras/Serialize/makesdna/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 2.4) + +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + +INCLUDE_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/src ) + +#FILE(GLOB INC_FILES ../*.h) + +SET (INC_FILES + DNA_rigidbody.h + + ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btVector3.h + ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btMatrix3x3.h + ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btTransform.h + ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletCollision/CollisionShapes/btCollisionShape.h + ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletCollision/CollisionShapes/btConvexInternalShape.h + ${BULLET_PHYSICS_SOURCE_DIR}/src/BulletCollision/CollisionDispatch/btCollisionObject.h +) + +# Build makesdna executable +SET(SRC makesdna.cpp) +ADD_EXECUTABLE(makesdna ${SRC} ${INC_FILES}) + +# Output BulletDNA.c +ADD_CUSTOM_COMMAND( + OUTPUT ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btSerializer.cpp + COMMAND ${CMAKE_CFG_INTDIR}/makesdna ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btSerializer.cpp ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/CommonSerialize/ + DEPENDS makesdna +) + +# Build bf_dna library +SET(SRC ${BULLET_PHYSICS_SOURCE_DIR}/src/LinearMath/btSerializer.cpp) +ADD_LIBRARY(BulletDNA ${SRC} ${INC_FILES}) + +MESSAGE(STATUS "Configuring makesdna") diff --git a/Extras/Serialize/makesdna/DNA_rigidbody.h b/Extras/Serialize/makesdna/DNA_rigidbody.h new file mode 100644 index 0000000..010ed1b --- /dev/null +++ b/Extras/Serialize/makesdna/DNA_rigidbody.h @@ -0,0 +1,29 @@ + +#ifndef DNA_RIGIDBODY_H +#define DNA_RIGIDBODY_H + + +struct PointerArray +{ + int m_size; + int m_capacity; + void *m_data; +}; + + +struct btPhysicsSystem +{ + PointerArray m_collisionShapes; + PointerArray m_collisionObjects; + PointerArray m_constraints; +}; + +///we need this to compute the pointer sizes +struct ListBase +{ + void *first; + void *last; +}; + + +#endif diff --git a/Extras/Serialize/makesdna/makesdna.cpp b/Extras/Serialize/makesdna/makesdna.cpp new file mode 100644 index 0000000..ed015ce --- /dev/null +++ b/Extras/Serialize/makesdna/makesdna.cpp @@ -0,0 +1,1251 @@ +/// Current makesdna.cpp is a from Blender, but we will completely rewrite it in C++ under a ZLib license +/// The Original version is at https://svn.blender.org/svnroot/bf-blender/trunk/blender/source/blender/makesdna/intern/makesdna.c + +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * + * Struct muncher for making SDNA + * + * Originally by Ton, some mods by Frank, and some cleaning and + * extension by Nzc. + * + * Makesdna creates a .c file with a long string of numbers that + * encode the Blender file format. It is fast, because it is basically + * a binary dump. There are some details to mind when reconstructing + * the file (endianness and byte-alignment). + * + * This little program scans all structs that need to be serialized, + * and determined the names and types of all members. It calculates + * how much memory (on disk or in ram) is needed to store that struct, + * and the offsets for reaching a particular one. + * + * There is a facility to get verbose output from sdna. Search for + * debugSDNA. This int can be set to 0 (no output) to some int. Higher + * numbers give more output. + * */ + + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) && !defined(FREE_WINDOWS) + +/* The __intXX are built-in types of the visual complier! So we don't + * need to include anything else here. */ + +typedef signed __int8 int8_t; +typedef signed __int16 int16_t; +typedef signed __int32 int32_t; +typedef signed __int64 int64_t; + +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +#ifndef _INTPTR_T_DEFINED +#ifdef _WIN64 +typedef __int64 intptr_t; +#else +typedef long intptr_t; +#endif +#define _INTPTR_T_DEFINED +#endif + +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned long uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif + +#elif defined(__linux__) || defined(__NetBSD__) + + /* Linux-i386, Linux-Alpha, Linux-ppc */ +#include + +#elif defined (__APPLE__) + +#include + +#elif defined(FREE_WINDOWS) + +#include + +#else + + /* FreeBSD, Irix, Solaris */ +#include + +#endif /* ifdef platform for types */ + +#ifdef __cplusplus +} +#endif + + +#include +#include +#include + +//#include "DNA_sdna_types.h" +// include files for automatic dependancies +#include "DNA_rigidbody.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" +#include "BulletCollision/CollisionShapes/btConvexInternalShape.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btTriangleInfoMap.h" +#include "BulletCollision/Gimpact/btGImpactShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" +#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" +#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" +#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" +#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h" +#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/Dynamics/btDynamicsWorld.h" + +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletSoftBody/btSoftBodyData.h" + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define SDNA_MAX_FILENAME_LENGTH 255 + +/* Included the path relative from /source/blender/ here, so we can move */ +/* headers around with more freedom. */ +char *includefiles[] = { + + // if you add files here, please add them at the end + // of makesdna.c (this file) as well + "../makesdna/DNA_rigidbody.h", + "../../../src/LinearMath/btVector3.h", + "../../../src/LinearMath/btMatrix3x3.h", + "../../../src/LinearMath/btTransform.h", + "../../../src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h", + "../../../src/BulletCollision/CollisionShapes/btCollisionShape.h", + "../../../src/BulletCollision/CollisionShapes/btStaticPlaneShape.h", + "../../../src/BulletCollision/CollisionShapes/btConvexInternalShape.h", + "../../../src/BulletCollision/CollisionShapes/btMultiSphereShape.h", + "../../../src/BulletCollision/CollisionShapes/btStridingMeshInterface.h", + "../../../src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h", + "../../../src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h", + "../../../src/BulletCollision/CollisionShapes/btCompoundShape.h", + "../../../src/BulletCollision/CollisionShapes/btCylinderShape.h", + "../../../src/BulletCollision/CollisionShapes/btCapsuleShape.h", + "../../../src/BulletCollision/CollisionShapes/btTriangleInfoMap.h", + "../../../src/BulletCollision/Gimpact/btGImpactShape.h", + "../../../src/BulletCollision/CollisionShapes/btConvexHullShape.h", + "../../../src/BulletCollision/CollisionDispatch/btCollisionObject.h", + "../../../src/BulletDynamics/Dynamics/btDynamicsWorld.h", + "../../../src/BulletDynamics/Dynamics/btRigidBody.h", + "../../../src/BulletDynamics/ConstraintSolver/btTypedConstraint.h", + "../../../src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h", + "../../../src/BulletDynamics/ConstraintSolver/btHingeConstraint.h", + "../../../src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h", + "../../../src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h", + "../../../src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h", + "../../../src/BulletDynamics/ConstraintSolver/btSliderConstraint.h", + "../../../src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h", + "../../../src/BulletSoftBody/btSoftBodyData.h", + // empty string to indicate end of includefiles + "" +}; + +void* malloc_and_setzero(int numbytes) +{ + char* buf = (char*)malloc(numbytes); + memset(buf,0,numbytes); + return buf; +} + +int maxdata= 500000, maxnr= 50000; +int nr_names=0; +int nr_types=0; +int nr_structs=0; +char **names, *namedata; /* at adress names[a] is string a */ +char **types, *typedata; /* at adress types[a] is string a */ +short *typelens; /* at typelens[a] is de length of type a */ +short *alphalens; /* contains sizes as they are calculated on the DEC Alpha (64 bits) */ +short **structs, *structdata; /* at sp= structs[a] is the first adress of a struct definition + sp[0] is type number + sp[1] is amount of elements + sp[2] sp[3] is typenr, namenr (etc) */ +/* + * debugSDNA: + * - 0 = no output, except errors + * - 1 = detail actions + * - 2 = full trace, tell which names and types were found + * - 4 = full trace, plus all gritty details + */ +int debugSDNA = 0; +int additional_slen_offset; + +/* ************************************************************************** */ +/* Functions */ +/* ************************************************************************** */ + +/** + * Add type to struct indexed by , if it was not yet found. + */ +int add_type(char *str, int len); + +/** + * Add variable to + */ +int add_name(char *str); + +/** + * Search whether this structure type was already found, and if not, + * add it. + */ +short *add_struct(int namecode); + +/** + * Remove comments from this buffer. Assumes that the buffer refers to + * ascii-code text. + */ +int preprocess_include(char *maindata, int len); + +/** + * Scan this file for serializable types. + */ +int convert_include(char *filename); + +/** + * Determine how many bytes are needed for an array. + */ +int arraysize(char *astr, int len); + +/** + * Determine how many bytes are needed for each struct. + */ +static int calculate_structlens(int); + +/** + * Construct the DNA.c file + */ +void dna_write(FILE *file, void *pntr, int size); + +/** + * Report all structures found so far, and print their lenghts. + */ +void printStructLenghts(void); + + + +/* ************************************************************************** */ +/* Implementation */ +/* ************************************************************************** */ + +/* ************************* MAKEN DNA ********************** */ + +int add_type(char *str, int len) +{ + int nr; + char *cp; + + if(str[0]==0) return -1; + + /* search through type array */ + for(nr=0; nr=maxnr) { + printf("too many types\n"); + return nr_types-1;; + } + nr_types++; + + return nr_types-1; +} + +/** + * + * Because of the weird way of tokenizing, we have to 'cast' function + * pointers to ... (*f)(), whatever the original signature. In fact, + * we add name and type at the same time... There are two special + * cases, unfortunately. These are explicitly checked. + * + * */ +int add_name(char *str) +{ + int nr, i, j, k; + char *cp; + char buf[255]; /* stupid limit, change it :) */ + char *name; + + additional_slen_offset = 0; + + if((str[0]==0) /* || (str[1]==0) */) return -1; + + if (str[0] == '(' && str[1] == '*') { + if (debugSDNA > 3) printf("\t\t\t\t*** Function pointer found\n"); + /* functionpointer: transform the type (sometimes) */ + i = 0; + j = 0; + + while (str[i] != ')') { + buf[i] = str[i]; + i++; + } + + /* Another number we need is the extra slen offset. This extra + * offset is the overshoot after a space. If there is no + * space, no overshoot should be calculated. */ + j = i; /* j at first closing brace */ + + if (debugSDNA > 3) printf("first brace after offset %d\n", i); + + j++; /* j beyond closing brace ? */ + while ((str[j] != 0) && (str[j] != ')' )) { + if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]); + j++; + } + if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]); + if (debugSDNA > 3) printf("special after offset %d\n", j); + + if (str[j] == 0 ) { + if (debugSDNA > 3) printf("offsetting for space\n"); + /* get additional offset */ + k = 0; + while (str[j] != ')') { + j++; + k++; + } + if (debugSDNA > 3) printf("extra offset %d\n", k); + additional_slen_offset = k; + } else if (str[j] == ')' ) { + if (debugSDNA > 3) printf("offsetting for brace\n"); + ; /* don't get extra offset */ + } else { + printf("Error during tokening function pointer argument list\n"); + } + + /* + * Put )(void) at the end? Maybe )(). Should check this with + * old sdna. Actually, sometimes )(), sometimes )(void...) + * Alas.. such is the nature of braindamage :( + * + * Sorted it out: always do )(), except for headdraw and + * windraw, part of ScrArea. This is important, because some + * linkers will treat different fp's differently when called + * !!! This has to do with interference in byte-alignment and + * the way args are pushed on the stack. + * + * */ + buf[i] = 0; + if (debugSDNA > 3) printf("Name before chomping: %s\n", buf); + if ( (strncmp(buf,"(*headdraw", 10) == 0) + || (strncmp(buf,"(*windraw", 9) == 0) ) { + buf[i] = ')'; + buf[i+1] = '('; + buf[i+2] = 'v'; + buf[i+3] = 'o'; + buf[i+4] = 'i'; + buf[i+5] = 'd'; + buf[i+6] = ')'; + buf[i+7] = 0; + } else { + buf[i] = ')'; + buf[i+1] = '('; + buf[i+2] = ')'; + buf[i+3] = 0; + } + /* now precede with buf*/ + if (debugSDNA > 3) printf("\t\t\t\t\tProposing fp name %s\n", buf); + name = buf; + } else { + /* normal field: old code */ + name = str; + } + + /* search name array */ + for(nr=0; nr=maxnr) { + printf("too many names\n"); + return nr_names-1; + } + nr_names++; + + return nr_names-1; +} + +short *add_struct(int namecode) +{ + int len; + short *sp; + + if(nr_structs==0) { + structs[0]= structdata; + } + else { + sp= structs[nr_structs-1]; + len= sp[1]; + structs[nr_structs]= sp+ 2*len+2; + } + + sp= structs[nr_structs]; + sp[0]= namecode; + + if(nr_structs>=maxnr) { + printf("too many structs\n"); + return sp; + } + nr_structs++; + + return sp; +} + +int preprocess_include(char *maindata, int len) +{ + int a, newlen, comment = 0; + char *cp, *temp, *md; + + temp= (char*) malloc_and_setzero(len); + memcpy(temp, maindata, len); + + // remove all c++ comments + /* replace all enters/tabs/etc with spaces */ + cp= temp; + a= len; + comment = 0; + while(a--) { + if(cp[0]=='/' && cp[1]=='/') { + comment = 1; + } else if (*cp<32) { + comment = 0; + } + if (comment || *cp<32 || *cp>128 ) *cp= 32; + cp++; + } + + + /* data from temp copy to maindata, remove comments and double spaces */ + cp= temp; + md= maindata; + newlen= 0; + comment= 0; + a= len; + while(a--) { + + if(cp[0]=='/' && cp[1]=='*') { + comment= 1; + cp[0]=cp[1]= 32; + } + if(cp[0]=='*' && cp[1]=='/') { + comment= 0; + cp[0]=cp[1]= 32; + } + + /* do not copy when: */ + if(comment); + else if( cp[0]==' ' && cp[1]==' ' ); + else if( cp[-1]=='*' && cp[0]==' ' ); /* pointers with a space */ + else { + md[0]= cp[0]; + md++; + newlen++; + } + cp++; + } + + free(temp); + return newlen; +} + +static void *read_file_data(char *filename, int *len_r) +{ +#ifdef WIN32 + FILE *fp= fopen(filename, "rb"); +#else + FILE *fp= fopen(filename, "r"); +#endif + void *data; + + if (!fp) { + *len_r= -1; + return NULL; + } + + fseek(fp, 0L, SEEK_END); + *len_r= ftell(fp); + fseek(fp, 0L, SEEK_SET); + + data= malloc_and_setzero(*len_r); + if (!data) { + *len_r= -1; + fclose(fp); + return NULL; + } + + if (fread(data, *len_r, 1, fp)!=1) { + *len_r= -1; + free(data); + fclose(fp); + return NULL; + } + + fclose(fp); + return data; +} + + +const char* skipStructTypes[]= +{ + "btContactSolverInfoData", + "btRigidBodyConstructionInfo", + "Euler", + "btConstraintInfo2", + "btConstraintSetting", + "btTriangleInfo", + "" +}; + +int skipStruct(const char* structType) +{ + int i=0; + while (strlen(skipStructTypes[i])) + { + if (strcmp(structType,skipStructTypes[i])==0) + { + return 1; + } + i++; + } + return 0; +} + +int convert_include(char *filename) +{ + /* read include file, skip structs with a '#' before it. + store all data in temporal arrays. + */ + int filelen, count, overslaan, slen, type, name, strct; + short *structpoin, *sp; + char *maindata, *mainend, *md, *md1; + + md= maindata= (char*)read_file_data(filename, &filelen); + if (filelen==-1) { + printf("Can't read file %s\n", filename); + return 1; + } + + filelen= preprocess_include(maindata, filelen); + mainend= maindata+filelen-1; + + /* we look for '{' and then back to 'struct' */ + count= 0; + overslaan= 0; + while(count 1) printf("\t|\t|-- detected struct %s\n", types[strct]); + + /* first lets make it all nice strings */ + md1= md+1; + while(*md1 != '}') { + if(md1>mainend) break; + + if(*md1==',' || *md1==' ') *md1= 0; + md1++; + } + + /* read types and names until first character that is not '}' */ + md1= md+1; + while( *md1 != '}' ) { + if(md1>mainend) break; + + /* skip when it says 'struct' or 'unsigned' or 'const' */ + if(*md1) { + if( strncmp(md1, "struct", 6)==0 ) md1+= 7; + if( strncmp(md1, "unsigned", 8)==0 ) md1+= 9; + if( strncmp(md1, "const", 5)==0 ) md1+= 6; + + /* we've got a type! */ + type= add_type(md1, 0); + + if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1); + + md1+= strlen(md1); + + + /* read until ';' */ + while( *md1 != ';' ) { + if(md1>mainend) break; + + if(*md1) { + /* We've got a name. slen needs + * correction for function + * pointers! */ + slen= (int) strlen(md1); + if( md1[slen-1]==';' ) { + md1[slen-1]= 0; + + + name= add_name(md1); + slen += additional_slen_offset; + sp[0]= type; + sp[1]= name; + + if ((debugSDNA>1) && (names[name] != 0 )) printf("%s |", names[name]); + + structpoin[1]++; + sp+= 2; + + md1+= slen; + break; + } + + + name= add_name(md1); + slen += additional_slen_offset; + + sp[0]= type; + sp[1]= name; + if ((debugSDNA > 1) && (names[name] != 0 )) printf("%s ||", names[name]); + + structpoin[1]++; + sp+= 2; + + md1+= slen; + } + md1++; + } + + if (debugSDNA > 1) printf(")\n"); + + } + md1++; + } + } + } + } + } + count++; + md++; + } + + free(maindata); + + return 0; +} + +int arraysize(char *astr, int len) +{ + int a, mul=1; + char str[100], *cp=0; + + memcpy(str, astr, len+1); + + for(a=0; a= firststruct) { + if(sizeof(void *)==8 && (len % 8) ) { + printf("Align struct error: %s %s\n", types[structtype],cp); + dna_error = 1; + } + } + + /* 2-4 aligned/ */ + if(typelens[type]>3 && (len % 4) ) { + printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%4); + dna_error = 1; + } + else if(typelens[type]==2 && (len % 2) ) { + printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%2); + dna_error = 1; + } + + len += mul*typelens[type]; + alphalen += mul * alphalens[type]; + + } else { + len= 0; + alphalen = 0; + break; + } + } + + if (len==0) { + unknown++; + } else { + typelens[structtype]= len; + alphalens[structtype]= alphalen; + // two ways to detect if a struct contains a pointer: + // has_pointer is set or alphalen != len + if (has_pointer || alphalen != len) { + if (alphalen % 8) { + printf("alphalen = %d len = %d\n",alphalen,len); + printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen%8); + dna_error = 1; + } + } + + if(len % 4) { + printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len%4); + dna_error = 1; + } + + } + } + } + + if(unknown==lastunknown) break; + } + + if(unknown) { + printf("ERROR: still %d structs unknown\n", unknown); + + if (debugSDNA) { + printf("*** Known structs : \n"); + + for(a=0; a= MAX_DNA_LINE_LENGTH) { + fprintf(file, "\n"); + linelength = 0; + } + } +} + +void printStructLenghts(void) +{ + int a, unknown= nr_structs, lastunknown, structtype; + short *structpoin; + printf("\n\n*** All detected structs:\n"); + + while(unknown) { + lastunknown= unknown; + unknown= 0; + + /* check all structs... */ + for(a=0; a -1) { + fflush(stdout); + printf("Running makesdna at debug level %d\n", debugSDNA); + + } + + /* the longest known struct is 50k, so we assume 100k is sufficent! */ + namedata= (char*)malloc_and_setzero(maxdata); + typedata= (char*)malloc_and_setzero(maxdata); + structdata= (short*)malloc_and_setzero(maxdata); + + /* a maximum of 5000 variables, must be sufficient? */ + names= (char**)malloc_and_setzero(sizeof(char *)*maxnr); + types= (char**)malloc_and_setzero(sizeof(char *)*maxnr); + typelens= (short*) malloc_and_setzero(sizeof(short)*maxnr); + alphalens= (short*)malloc_and_setzero(sizeof(short)*maxnr); + structs= (short**)malloc_and_setzero(sizeof(short)*maxnr); + + /* insertion of all known types */ + /* watch it: uint is not allowed! use in structs an unsigned int */ + add_type("char", 1); /* 0 */ + add_type("uchar", 1); /* 1 */ + add_type("short", 2); /* 2 */ + add_type("ushort", 2); /* 3 */ + add_type("int", 4); /* 4 */ + add_type("long", 4); /* 5 */ /* should it be 8 on 64 bits? */ + add_type("ulong", 4); /* 6 */ + add_type("float", 4); /* 7 */ + add_type("double", 8); /* 8 */ + add_type("void", 0); /* 9 */ + + // the defines above shouldn't be output in the padding file... + firststruct = nr_types; + + /* add all include files defined in the global array */ + /* Since the internal file+path name buffer has limited length, I do a */ + /* little test first... */ + /* Mind the breaking condition here! */ + if (debugSDNA) printf("\tStart of header scan:\n"); + for (i = 0; strlen(includefiles[i]); i++) { + sprintf(str, "%s%s", baseDirectory, includefiles[i]); + if (debugSDNA) printf("\t|-- Converting %s\n", str); + if (convert_include(str)) { + return (1); + } + } + if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); + + if (calculate_structlens(firststruct)) { + // error + return(1); + } + + + /* FOR DEBUG */ + if (debugSDNA > 1) + { + int a,b; +/* short *elem; */ + short num_types; + + printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs); + for(a=0; a -1) printf("Writing file ... "); + + if(nr_names==0 || nr_structs==0); + else { + strcpy(str, "SDNA"); + dna_write(file, str, 4); + + /* write names */ + strcpy(str, "NAME"); + dna_write(file, str, 4); + len= nr_names; + dna_write(file, &len, 4); + + /* calculate size of datablock with strings */ + cp= names[nr_names-1]; + cp+= strlen(names[nr_names-1]) + 1; /* +1: null-terminator */ + len= (intptr_t) (cp - (char*) names[0]); + len= (len+3) & ~3; + dna_write(file, names[0], len); + + /* write TYPES */ + strcpy(str, "TYPE"); + dna_write(file, str, 4); + len= nr_types; + dna_write(file, &len, 4); + + /* calculate datablock size */ + cp= types[nr_types-1]; + cp+= strlen(types[nr_types-1]) + 1; /* +1: null-terminator */ + len= (intptr_t) (cp - (char*) types[0]); + len= (len+3) & ~3; + + dna_write(file, types[0], len); + + /* WRITE TYPELENGTHS */ + strcpy(str, "TLEN"); + dna_write(file, str, 4); + + len= 2*nr_types; + if(nr_types & 1) len+= 2; + dna_write(file, typelens, len); + + /* WRITE STRUCTS */ + strcpy(str, "STRC"); + dna_write(file, str, 4); + len= nr_structs; + dna_write(file, &len, 4); + + /* calc datablock size */ + sp= structs[nr_structs-1]; + sp+= 2+ 2*( sp[1] ); + len= (intptr_t) ((char*) sp - (char*) structs[0]); + len= (len+3) & ~3; + + dna_write(file, structs[0], len); + + /* a simple dna padding test */ + if (0) { + FILE *fp; + int a; + + fp= fopen("padding.c", "w"); + if(fp==NULL); + else { + + // add all include files defined in the global array + for (i = 0; strlen(includefiles[i]); i++) { + fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]); + } + + fprintf(fp, "main(){\n"); + sp = typelens; + sp += firststruct; + for(a=firststruct; a -1) printf("done.\n"); + + return(0); +} + +/* ************************* END MAKE DNA ********************** */ + +static void make_bad_file(char *file) +{ + FILE *fp= fopen(file, "w"); + fprintf(fp, "ERROR! Cannot make correct DNA.c file, STUPID!\n"); + fclose(fp); +} + +#ifndef BASE_HEADER +#define BASE_HEADER "../" +#endif + +int main(int argc, char ** argv) +{ +// printf("btCollisionObject=%d\n",sizeof(btCollisionObject)); +// printf("btCollisionObjectData=%d\n",sizeof(btCollisionObjectData)); +// printf("btTransform=%d\n",sizeof(btTransform)); +// printf("btTransformData=%d\n",sizeof(btTransformData)); +// +// btCollisionObject* bla = new btCollisionObject(); +// btCollisionObjectData* bla2 = new btCollisionObjectData(); + + //int offsetof(bla,m_hasAnisotropicFriction); +/* + btTransformData m_worldTransform; + btTransform m_interpolationWorldTransform; + btVector3 m_interpolationLinearVelocity; + btVector3 m_interpolationAngularVelocity; + btVector3 m_anisotropicFriction; + bool m_hasAnisotropicFriction; + btScalar m_contactProcessingThreshold; + btBroadphaseProxy *m_broadphaseHandle; + btCollisionShape *m_collisionShape; + btCollisionShape *m_rootCollisionShape; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + btScalar m_deactivationTime; + btScalar m_friction; + btScalar m_restitution; + void* m_userObjectPointer; + int m_internalType; + btScalar m_hitFraction; + btScalar m_ccdSweptSphereRadius; + btScalar m_ccdMotionThreshold; + bool m_checkCollideWith; + char m_pad[7]; +*/ + + FILE *file; + int return_status = 0; + + if (argc!=2 && argc!=3) { + printf("Usage: %s outfile.c [base directory]\n", argv[0]); + return_status = 1; + } else { + file = fopen(argv[1], "w"); + if (!file) { + printf ("Unable to open file: %s\n", argv[1]); + return_status = 1; + } else { + char baseDirectory[256]; + + if (argc==3) { + strcpy(baseDirectory, argv[2]); + } else { + strcpy(baseDirectory, BASE_HEADER); + } + + if (sizeof(void*)==8) + { + fprintf (file, "char sBulletDNAstr64[]= {\n"); + } else + { + fprintf (file, "char sBulletDNAstr[]= {\n"); + } + + if (make_structDNA(baseDirectory, file)) { + // error + fclose(file); + make_bad_file(argv[1]); + return_status = 1; + } else { + fprintf(file, "};\n"); + if (sizeof(void*)==8) + { + fprintf(file, "int sBulletDNAlen64= sizeof(sBulletDNAstr64);\n"); + } else + { + fprintf(file, "int sBulletDNAlen= sizeof(sBulletDNAstr);\n"); + } + + fclose(file); + } + } + } + + + return(return_status); +} + + +/* end of list */ diff --git a/Extras/glui/CMakeLists.txt b/Extras/glui/CMakeLists.txt new file mode 100644 index 0000000..c2018a7 --- /dev/null +++ b/Extras/glui/CMakeLists.txt @@ -0,0 +1,66 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + +ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS) + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/glut) + +# You shouldn't have to modify anything below this line +######################################################## + + +# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system +# This should be the case. +INCLUDE (${CMAKE_ROOT}/Modules/FindGLU.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindGLUT.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindOpenGL.cmake) + + +IF (WIN32) + # This is the Windows code for which Opengl, and Glut are not properly installed + # since I can't install them I must cheat and copy libraries around + INCLUDE_DIRECTORIES(${GLUT_ROOT}) + # LINK_DIRECTORIES(${GLUT_ROOT}\\lib) + # IF (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") + # LINK_LIBRARIES(${GLUT_ROOT}\\lib\\glut32 ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) + # TARGET_LINK_LIBRARIES(table ${GLUT_ROOT}\\lib\\glut32) +# +# ADD_CUSTOM_COMMAND(TARGET table POST_BUILD COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2005\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2003\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs6\\Debug) +# ELSE (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# LINK_LIBRARIES(${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY}) +# ENDIF(${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# TARGET_LINK_LIBRARIES(table ${OPENGL_gl_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${OPENGL_glu_LIBRARY}) +ELSE (WIN32) + # This is the lines for linux. This should always work if everything is installed and working fine. +# SET(CMAKE_BUILD_TYPE Debug) +# SET(CMAKE_CXX_FLAGS_DEBUG "-g") + INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) +# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) +ENDIF (WIN32) + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/Extras/glui +) + +ADD_LIBRARY(GLUI + arcball.h glui_checkbox.cpp glui_internal.h glui_panel.cpp glui_spinner.cpp glui_treepanel.cpp +GL glui.cpp glui_column.cpp glui_internal_control.h glui_radio.cpp glui_statictext.cpp glui_window.cpp +glui_add_controls.cpp glui_commandline.cpp glui_list.cpp glui_rollout.cpp glui_string.cpp quaternion.cpp +algebra3.cpp glui_bitmap_img_data.cpp glui_control.cpp glui_listbox.cpp glui_rotation.cpp glui_textbox.cpp quaternion.h +algebra3.h glui_bitmaps.cpp glui_edittext.cpp glui_mouse_iaction.cpp glui_scrollbar.cpp glui_translation.cpp +arcball.cpp glui_button.cpp glui_filebrowser.cpp glui_node.cpp glui_separator.cpp glui_tree.cpp + +) + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(GLUI ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) +ENDIF (BUILD_SHARED_LIBS) diff --git a/Extras/glui/GL/glui.h b/Extras/glui/GL/glui.h new file mode 100644 index 0000000..4ef2d3b --- /dev/null +++ b/Extras/glui/GL/glui.h @@ -0,0 +1,2723 @@ +/**************************************************************************** + + GLUI User Interface Toolkit (LGPL) + ---------------------------------- + + glui.h - Main (and only) external header for + GLUI User Interface Toolkit + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#ifndef GLUI_GLUI_H +#define GLUI_GLUI_H + +#ifdef WIN32 + #pragma warning(disable : 4324) // disable padding warning + #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. + #pragma warning(disable:4996) //Turn off warnings about deprecated C routines + #pragma warning(disable:4786) // Disable the "debug name too long" warning +#endif + + +#ifdef WIN32//for glut.h +#include +#endif + +#if defined(GLUI_FREEGLUT) || defined(BT_USE_FREEGLUT) + + // FreeGLUT does not yet work perfectly with GLUI + // - use at your own risk. + #include + +#elif defined(GLUI_OPENGLUT) + + // OpenGLUT does not yet work properly with GLUI + // - use at your own risk. + + #include + +#else + +#if defined(__APPLE__) && !defined (VMDMESA) + #include + #include + #include +#else +// #include "../../freeglut/gl/glut.h" + #include + #endif + +#endif + +#include +#include +#include +#include +#include + +#define GLUI_VERSION 2.3f /********** Current version **********/ + +#if defined(_WIN32) +#if !defined(GLUI_NO_LIB_PRAGMA) +//#pragma comment(lib, "glui32.lib") // Link automatically with GLUI library +#endif +#endif + +/********** Do some basic defines *******/ + +#ifndef Byte +#define Byte unsigned char +#endif + +#ifndef _RGBC_ +class RGBc { +public: + Byte r, g, b; + + void set(Byte r,Byte g,Byte b) {this->r=r;this->g=g;this->b=b;} + + RGBc( void ) {} + RGBc( Byte r, Byte g, Byte b ) { set( r, g, b ); } +}; +#define _RGBC_ +#endif + +/********** List of GLUT callbacks ********/ + +enum GLUI_Glut_CB_Types +{ + GLUI_GLUT_RESHAPE, + GLUI_GLUT_KEYBOARD, + GLUI_GLUT_DISPLAY, + GLUI_GLUT_MOUSE, + GLUI_GLUT_MOTION, + GLUI_GLUT_SPECIAL, + GLUI_GLUT_SPECIAL_UP, + GLUI_GLUT_PASSIVE_MOTION, + GLUI_GLUT_ENTRY, + GLUI_GLUT_VISIBILITY +}; + +/********* Constants for window placement **********/ + +#define GLUI_XOFF 6 +#define GLUI_YOFF 6 +#define GLUI_ITEMSPACING 3 +#define GLUI_CHECKBOX_SIZE 13 +#define GLUI_RADIOBUTTON_SIZE 13 +#define GLUI_BUTTON_SIZE 20 +#define GLUI_STATICTEXT_SIZE 13 +#define GLUI_SEPARATOR_HEIGHT 8 +#define GLUI_DEFAULT_CONTROL_WIDTH 100 +#define GLUI_DEFAULT_CONTROL_HEIGHT 13 +#define GLUI_EDITTEXT_BOXINNERMARGINX 3 +#define GLUI_EDITTEXT_HEIGHT 20 +#define GLUI_EDITTEXT_WIDTH 130 +#define GLUI_EDITTEXT_MIN_INT_WIDTH 35 +#define GLUI_EDITTEXT_MIN_TEXT_WIDTH 50 +#define GLUI_PANEL_NAME_DROP 8 +#define GLUI_PANEL_EMBOSS_TOP 4 +/* #define GLUI_ROTATION_WIDTH 60 */ +/* #define GLUI_ROTATION_HEIGHT 78 */ +#define GLUI_ROTATION_WIDTH 50 +#define GLUI_ROTATION_HEIGHT (GLUI_ROTATION_WIDTH+18) +#define GLUI_MOUSE_INTERACTION_WIDTH 50 +#define GLUI_MOUSE_INTERACTION_HEIGHT (GLUI_MOUSE_INTERACTION_WIDTH)+18 + +/** Different panel control types **/ +#define GLUI_PANEL_NONE 0 +#define GLUI_PANEL_EMBOSSED 1 +#define GLUI_PANEL_RAISED 2 + +/** Max # of els in control's float_array **/ +#define GLUI_DEF_MAX_ARRAY 30 + +/********* The control's 'active' behavior *********/ +#define GLUI_CONTROL_ACTIVE_MOUSEDOWN 1 +#define GLUI_CONTROL_ACTIVE_PERMANENT 2 + +/********* Control alignment types **********/ +#define GLUI_ALIGN_CENTER 1 +#define GLUI_ALIGN_RIGHT 2 +#define GLUI_ALIGN_LEFT 3 + +/********** Limit types - how to limit spinner values *********/ +#define GLUI_LIMIT_NONE 0 +#define GLUI_LIMIT_CLAMP 1 +#define GLUI_LIMIT_WRAP 2 + +/********** Translation control types ********************/ +#define GLUI_TRANSLATION_XY 0 +#define GLUI_TRANSLATION_Z 1 +#define GLUI_TRANSLATION_X 2 +#define GLUI_TRANSLATION_Y 3 + +#define GLUI_TRANSLATION_LOCK_NONE 0 +#define GLUI_TRANSLATION_LOCK_X 1 +#define GLUI_TRANSLATION_LOCK_Y 2 + +/********** How was a control activated? *****************/ +#define GLUI_ACTIVATE_MOUSE 1 +#define GLUI_ACTIVATE_TAB 2 + +/********** What type of live variable does a control have? **********/ +#define GLUI_LIVE_NONE 0 +#define GLUI_LIVE_INT 1 +#define GLUI_LIVE_FLOAT 2 +#define GLUI_LIVE_TEXT 3 +#define GLUI_LIVE_STRING 6 +#define GLUI_LIVE_DOUBLE 4 +#define GLUI_LIVE_FLOAT_ARRAY 5 + +/************* Textbox and List Defaults - JVK ******************/ +#define GLUI_TEXTBOX_HEIGHT 130 +#define GLUI_TEXTBOX_WIDTH 130 +#define GLUI_LIST_HEIGHT 130 +#define GLUI_LIST_WIDTH 130 +#define GLUI_DOUBLE_CLICK 1 +#define GLUI_SINGLE_CLICK 0 +#define GLUI_TAB_WIDTH 50 /* In pixels */ +#define GLUI_TEXTBOX_BOXINNERMARGINX 3 +#define GLUI_TEXTBOX_MIN_TEXT_WIDTH 50 +#define GLUI_LIST_BOXINNERMARGINX 3 +#define GLUI_LIST_MIN_TEXT_WIDTH 50 + +/*********************** TreePanel Defaults - JVK *****************************/ +#define GLUI_TREEPANEL_DEFAULTS 0 // bar, standard bar color +#define GLUI_TREEPANEL_ALTERNATE_COLOR 1 // Alternate between 8 different bar colors +#define GLUI_TREEPANEL_ENABLE_BAR 2 // enable the bar +#define GLUI_TREEPANEL_DISABLE_BAR 4 // disable the bar +#define GLUI_TREEPANEL_DISABLE_DEEPEST_BAR 8 // disable only the deepest bar +#define GLUI_TREEPANEL_CONNECT_CHILDREN_ONLY 16 // disable only the bar of the last child of each root +#define GLUI_TREEPANEL_DISPLAY_HIERARCHY 32 // display some sort of hierachy in the tree node title +#define GLUI_TREEPANEL_HIERARCHY_NUMERICDOT 64 // display hierarchy in 1.3.2 (etc... ) format +#define GLUI_TREEPANEL_HIERARCHY_LEVEL_ONLY 128 // display hierarchy as only the level depth + +/******************* GLUI Scrollbar Defaults - JVK ***************************/ +#define GLUI_SCROLL_ARROW_WIDTH 16 +#define GLUI_SCROLL_ARROW_HEIGHT 16 +#define GLUI_SCROLL_BOX_MIN_HEIGHT 5 +#define GLUI_SCROLL_BOX_STD_HEIGHT 16 +#define GLUI_SCROLL_STATE_NONE 0 +#define GLUI_SCROLL_STATE_UP 1 +#define GLUI_SCROLL_STATE_DOWN 2 +#define GLUI_SCROLL_STATE_BOTH 3 +#define GLUI_SCROLL_STATE_SCROLL 4 +#define GLUI_SCROLL_DEFAULT_GROWTH_EXP 1.05f +#define GLUI_SCROLL_VERTICAL 0 +#define GLUI_SCROLL_HORIZONTAL 1 + + +/** Size of the character width hash table for faster lookups. + Make sure to keep this a power of two to avoid the slow divide. + This is also a speed/memory tradeoff; 128 is enough for low ASCII. +*/ +#define CHAR_WIDTH_HASH_SIZE 128 + +/********** Translation codes **********/ + +enum TranslationCodes +{ + GLUI_TRANSLATION_MOUSE_NONE = 0, + GLUI_TRANSLATION_MOUSE_UP, + GLUI_TRANSLATION_MOUSE_DOWN, + GLUI_TRANSLATION_MOUSE_LEFT, + GLUI_TRANSLATION_MOUSE_RIGHT, + GLUI_TRANSLATION_MOUSE_UP_LEFT, + GLUI_TRANSLATION_MOUSE_UP_RIGHT, + GLUI_TRANSLATION_MOUSE_DOWN_LEFT, + GLUI_TRANSLATION_MOUSE_DOWN_RIGHT +}; + +/************ A string type for us to use **********/ + +typedef std::string GLUI_String; +GLUI_String& glui_format_str(GLUI_String &str, const char* fmt, ...); + +/********* Pre-declare classes as needed *********/ + +class GLUI; +class GLUI_Control; +class GLUI_Listbox; +class GLUI_StaticText; +class GLUI_EditText; +class GLUI_Panel; +class GLUI_Spinner; +class GLUI_RadioButton; +class GLUI_RadioGroup; +class GLUI_Glut_Window; +class GLUI_TreePanel; +class GLUI_Scrollbar; +class GLUI_List; + +class Arcball; + +/*** Flags for GLUI class constructor ***/ +#define GLUI_SUBWINDOW ((long)(1<<1)) +#define GLUI_SUBWINDOW_TOP ((long)(1<<2)) +#define GLUI_SUBWINDOW_BOTTOM ((long)(1<<3)) +#define GLUI_SUBWINDOW_LEFT ((long)(1<<4)) +#define GLUI_SUBWINDOW_RIGHT ((long)(1<<5)) + +/*** Codes for different type of edittext boxes and spinners ***/ +#define GLUI_EDITTEXT_TEXT 1 +#define GLUI_EDITTEXT_INT 2 +#define GLUI_EDITTEXT_FLOAT 3 +#define GLUI_SPINNER_INT GLUI_EDITTEXT_INT +#define GLUI_SPINNER_FLOAT GLUI_EDITTEXT_FLOAT +#define GLUI_SCROLL_INT GLUI_EDITTEXT_INT +#define GLUI_SCROLL_FLOAT GLUI_EDITTEXT_FLOAT +// This is only for deprecated interface +#define GLUI_EDITTEXT_STRING 4 + +/*** Definition of callbacks ***/ +typedef void (*GLUI_Update_CB) (int id); +typedef void (*GLUI_Control_CB)(GLUI_Control *); +typedef void (*Int1_CB) (int); +typedef void (*Int2_CB) (int, int); +typedef void (*Int3_CB) (int, int, int); +typedef void (*Int4_CB) (int, int, int, int); + +/************************************************************/ +/** + Callback Adapter Class + Allows us to support different types of callbacks; + like a GLUI_Update_CB function pointer--which takes an int; + and a GLUI_Control_CB function pointer--which takes a GUI_Control object. +*/ +class GLUI_CB +{ +public: + GLUI_CB() : idCB(0),objCB(0) {} + GLUI_CB(GLUI_Update_CB cb) : idCB(cb),objCB(0) {} + GLUI_CB(GLUI_Control_CB cb) : idCB(0),objCB(cb) {} + // (Compiler generated copy constructor) + + /** This control just activated. Fire our callback.*/ + void operator()(GLUI_Control *ctrl) const; + bool operator!() const { return !idCB && !objCB; } + operator bool() const { return !(!(*this)); } +private: + GLUI_Update_CB idCB; + GLUI_Control_CB objCB; +}; + +/************************************************************/ +/* */ +/* Base class, for hierarchical relationships */ +/* */ +/************************************************************/ + +class GLUI_Control; +class GLUI_Column; +class GLUI_Panel; +class GLUI_FileBrowser; +class GLUI_Scrollbar; +class GLUI_Listbox; +class GLUI_List; +class GLUI_Rollout; +class GLUI_Tree; + + +/** + GLUI_Node is a node in a sort of tree of GLUI controls. + Each GLUI_Node has a list of siblings (in a circular list) + and a linked list of children. + + Everything onscreen is a GLUI_Node--windows, buttons, etc. + The nodes are traversed for event processing, sizing, redraws, etc. +*/ +class GLUI_Node +{ + friend class GLUI_Tree; /* JVK */ + friend class GLUI_Rollout; + friend class GLUI_Main; + +public: + GLUI_Node(); + virtual ~GLUI_Node() {} + + GLUI_Node *first_sibling(); + GLUI_Node *last_sibling(); + GLUI_Node *prev(); + GLUI_Node *next(); + + GLUI_Node *first_child() { return child_head; } + GLUI_Node *last_child() { return child_tail; } + GLUI_Node *parent() { return parent_node; } + + /** Link in a new child control */ + virtual int add_control( GLUI_Control *control ); + + void link_this_to_parent_last (GLUI_Node *parent ); + void link_this_to_parent_first(GLUI_Node *parent ); + void link_this_to_sibling_next(GLUI_Node *sibling ); + void link_this_to_sibling_prev(GLUI_Node *sibling ); + void unlink(); + + void dump( FILE *out, const char *name ); + + virtual GLUI_Panel* dynamicCastGLUI_Panel() + { + return 0; + } + + virtual GLUI_Column* dynamicCastGLUI_Column() + { + return 0; + } + virtual GLUI_EditText* dynamicCastGLUI_EditText() + { + return 0; + } + virtual GLUI_Rollout* dynamicCastGLUI_Rollout() + { + return 0; + } + + virtual GLUI_Tree* dynamicCastGLUI_Tree() + { + return 0; + } + + virtual GLUI_List* dynamicCastGLUI_List() + { + return 0; + } + + virtual GLUI_FileBrowser* dynamicCastGLUI_FileBrowser() + { + return 0; + } + + virtual GLUI_Scrollbar* dynamicCastGLUI_Scrollbar() + { + return 0; + } + + virtual GLUI_Listbox* dynamicCastGLUI_Listbox() + { + return 0; + } + + virtual GLUI_TreePanel* dynamicCastGLUI_TreePanel() + { + return 0; + } + + + +protected: + static void add_child_to_control(GLUI_Node *parent,GLUI_Control *child); + GLUI_Node *parent_node; + GLUI_Node *child_head; + GLUI_Node *child_tail; + GLUI_Node *next_sibling; + GLUI_Node *prev_sibling; +}; + + +/************************************************************/ +/* */ +/* Standard Bitmap stuff */ +/* */ +/************************************************************/ + +enum GLUI_StdBitmaps_Codes +{ + GLUI_STDBITMAP_CHECKBOX_OFF = 0, + GLUI_STDBITMAP_CHECKBOX_ON, + GLUI_STDBITMAP_RADIOBUTTON_OFF, + GLUI_STDBITMAP_RADIOBUTTON_ON, + GLUI_STDBITMAP_UP_ARROW, + GLUI_STDBITMAP_DOWN_ARROW, + GLUI_STDBITMAP_LEFT_ARROW, + GLUI_STDBITMAP_RIGHT_ARROW, + GLUI_STDBITMAP_SPINNER_UP_OFF, + GLUI_STDBITMAP_SPINNER_UP_ON, + GLUI_STDBITMAP_SPINNER_DOWN_OFF, + GLUI_STDBITMAP_SPINNER_DOWN_ON, + GLUI_STDBITMAP_CHECKBOX_OFF_DIS, /*** Disactivated control bitmaps ***/ + GLUI_STDBITMAP_CHECKBOX_ON_DIS, + GLUI_STDBITMAP_RADIOBUTTON_OFF_DIS, + GLUI_STDBITMAP_RADIOBUTTON_ON_DIS, + GLUI_STDBITMAP_SPINNER_UP_DIS, + GLUI_STDBITMAP_SPINNER_DOWN_DIS, + GLUI_STDBITMAP_LISTBOX_UP, + GLUI_STDBITMAP_LISTBOX_DOWN, + GLUI_STDBITMAP_LISTBOX_UP_DIS, + GLUI_STDBITMAP_NUM_ITEMS +}; + +/************************************************************/ +/* */ +/* Class GLUI_Bitmap */ +/* */ +/************************************************************/ + +/** + GLUI_Bitmap is a simple 2D texture map. It's used + to represent small textures like checkboxes, arrows, etc. + via the GLUI_StdBitmaps class. +*/ +class GLUI_Bitmap +{ + friend class GLUI_StdBitmaps; + +public: + GLUI_Bitmap(); + ~GLUI_Bitmap(); + + /** Create bitmap from greyscale byte image */ + void init_grey(unsigned char *array); + + /** Create bitmap from color int image */ + void init(int *array); + +private: + /** RGB pixel data */ + unsigned char *pixels; + int w, h; +}; + + +/************************************************************/ +/* */ +/* Class GLUI_StdBitmap */ +/* */ +/************************************************************/ + +/** + Keeps an array of GLUI_Bitmap objects to represent all the + images used in the UI: checkboxes, arrows, etc. +*/ +class GLUI_StdBitmaps +{ +public: + GLUI_StdBitmaps(); + ~GLUI_StdBitmaps(); + + /** Return the width (in pixels) of the n'th standard bitmap. */ + int width (int n) const; + /** Return the height (in pixels) of the n'th standard bitmap. */ + int height(int n) const; + + /** Draw the n'th standard bitmap (one of the enums + listed in GLUI_StdBitmaps_Codes) at pixel corner (x,y). + */ + void draw(int n, int x, int y) const; + +private: + GLUI_Bitmap bitmaps[GLUI_STDBITMAP_NUM_ITEMS]; +}; + +/************************************************************/ +/* */ +/* Master GLUI Class */ +/* */ +/************************************************************/ + +/** + The master manages our interaction with GLUT. + There's only one GLUI_Master_Object. +*/ +class GLUI_Master_Object +{ + + friend void glui_idle_func(); + +public: + + GLUI_Master_Object(); + ~GLUI_Master_Object(); + + GLUI_Node gluis; + GLUI_Control *active_control, *curr_left_button_glut_menu; + GLUI *active_control_glui; + int glui_id_counter; + + GLUI_Glut_Window *find_glut_window( int window_id ); + + void set_glutIdleFunc(void (*f)(void)); + + /************** + void (*glut_keyboard_CB)(unsigned char, int, int); + void (*glut_reshape_CB)(int, int); + void (*glut_special_CB)(int, int, int); + void (*glut_mouse_CB)(int,int,int,int); + + void (*glut_passive_motion_CB)(int,int); + void (*glut_visibility_CB)(int); + void (*glut_motion_CB)(int,int); + void (*glut_display_CB)(void); + void (*glut_entry_CB)(int); + **********/ + + void set_left_button_glut_menu_control( GLUI_Control *control ); + + /********** GLUT callthroughs **********/ + /* These are the glut callbacks that we do not handle */ + + void set_glutReshapeFunc (void (*f)(int width, int height)); + void set_glutKeyboardFunc(void (*f)(unsigned char key, int x, int y)); + void set_glutSpecialFunc (void (*f)(int key, int x, int y)); + void set_glutSpecialUpFunc(void (*f)(int key, int x, int y)); + + void set_glutMouseFunc (void (*f)(int, int, int, int )); + + void set_glutDisplayFunc(void (*f)(void)) {glutDisplayFunc(f);} + void set_glutTimerFunc(unsigned int millis, void (*f)(int value), int value) + { ::glutTimerFunc(millis,f,value);} + void set_glutOverlayDisplayFunc(void(*f)(void)){glutOverlayDisplayFunc(f);} + void set_glutSpaceballMotionFunc(Int3_CB f) {glutSpaceballMotionFunc(f);} + void set_glutSpaceballRotateFunc(Int3_CB f) {glutSpaceballRotateFunc(f);} + void set_glutSpaceballButtonFunc(Int2_CB f) {glutSpaceballButtonFunc(f);} + void set_glutTabletMotionFunc(Int2_CB f) {glutTabletMotionFunc(f);} + void set_glutTabletButtonFunc(Int4_CB f) {glutTabletButtonFunc(f);} + /* void set_glutWindowStatusFunc(Int1_CB f) {glutWindowStatusFunc(f);} */ + void set_glutMenuStatusFunc(Int3_CB f) {glutMenuStatusFunc(f);} + void set_glutMenuStateFunc(Int1_CB f) {glutMenuStateFunc(f);} + void set_glutButtonBoxFunc(Int2_CB f) {glutButtonBoxFunc(f);} + void set_glutDialsFunc(Int2_CB f) {glutDialsFunc(f);} + + + GLUI *create_glui( const char *name, long flags=0, int x=-1, int y=-1 ); + GLUI *create_glui_subwindow( int parent_window, long flags=0 ); + GLUI *find_glui_by_window_id( int window_id ); + void get_viewport_area( int *x, int *y, int *w, int *h ); + void auto_set_viewport(); + void close_all(); + void sync_live_all(); + + void reshape(); + + float get_version() { return GLUI_VERSION; } + + void glui_setIdleFuncIfNecessary(void); + +private: + GLUI_Node glut_windows; + void (*glut_idle_CB)(void); + + void add_cb_to_glut_window(int window,int cb_type,void *cb); +}; + +/** + This is the only GLUI_Master_Object in existence. +*/ +extern GLUI_Master_Object GLUI_Master; + +/************************************************************/ +/* */ +/* Class for managing a GLUT window */ +/* */ +/************************************************************/ + +/** + A top-level window. The GLUI_Master GLUT callback can route events + to the callbacks in this class, for arbitrary use by external users. + (see GLUI_Master_Object::set_glutKeyboardFunc). + + This entire approach seems to be superceded by the "subwindow" flavor + of GLUI. +*/ +class GLUI_Glut_Window : public GLUI_Node +{ +public: + GLUI_Glut_Window(); + + int glut_window_id; + + /*********** Pointers to GLUT callthrough functions *****/ + void (*glut_keyboard_CB)(unsigned char, int, int); + void (*glut_special_CB)(int, int, int); + void (*glut_special_up_CB)(int, int, int); + void (*glut_reshape_CB)(int, int); + void (*glut_passive_motion_CB)(int,int); + void (*glut_mouse_CB)(int,int,int,int); + void (*glut_visibility_CB)(int); + void (*glut_motion_CB)(int,int); + void (*glut_display_CB)(void); + void (*glut_entry_CB)(int); +}; + +/************************************************************/ +/* */ +/* Main Window GLUI class (not user-level) */ +/* */ +/************************************************************/ + +/** + A GLUI_Main handles GLUT events for one window, routing them to the + appropriate controls. The central user-visible "GLUI" class + inherits from this class; users should not allocate GLUT_Main objects. + + There's a separate GLUI_Main object for: + - Each top-level window with GUI stuff in it. + - Each "subwindow" of another top-level window. + + All the GLUI_Main objects are listed in GLUI_Master.gluis. + A better name for this class might be "GLUI_Environment"; + this class provides the window-level context for every control. +*/ +class GLUI_Main : public GLUI_Node +{ + /********** Friend classes *************/ + + friend class GLUI_Control; + friend class GLUI_Rotation; + friend class GLUI_Translation; + friend class GLUI; + friend class GLUI_Master_Object; + + /*********** Friend functions **********/ + + friend void glui_mouse_func(int button, int state, int x, int y); + friend void glui_keyboard_func(unsigned char key, int x, int y); + friend void glui_special_func(int key, int x, int y); + friend void glui_special_up_func(int key, int x, int y); + friend void glui_passive_motion_func(int x, int y); + friend void glui_reshape_func( int w, int h ); + friend void glui_visibility_func(int state); + friend void glui_motion_func(int x, int y); + friend void glui_entry_func(int state); + friend void glui_display_func( void ); + friend void glui_idle_func(void); + + friend void glui_parent_window_reshape_func( int w, int h ); + friend void glui_parent_window_keyboard_func( unsigned char, int, int ); + friend void glui_parent_window_special_func( int, int, int ); + friend void glui_parent_window_mouse_func( int, int, int, int ); + +protected: + /*** Variables ***/ + int main_gfx_window_id; + int mouse_button_down; + int glut_window_id; + int top_level_glut_window_id; + GLUI_Control *active_control; + GLUI_Control *mouse_over_control; + GLUI_Panel *main_panel; + enum buffer_mode_t { + buffer_front=1, ///< Draw updated controls directly to screen. + buffer_back=2 ///< Double buffering: postpone updates until next redraw. + }; + buffer_mode_t buffer_mode; ///< Current drawing mode + int curr_cursor; + int w, h; + long flags; + bool closing; + int parent_window; + int glui_id; + + /********** Misc functions *************/ + + GLUI_Control *find_control( int x, int y ); + GLUI_Control *find_next_control( GLUI_Control *control ); + GLUI_Control *find_next_control_rec( GLUI_Control *control ); + GLUI_Control *find_next_control_( GLUI_Control *control ); + GLUI_Control *find_prev_control( GLUI_Control *control ); + void create_standalone_window( const char *name, int x=-1, int y=-1 ); + void create_subwindow( int parent,int window_alignment ); + void setup_default_glut_callbacks( void ); + + void mouse(int button, int state, int x, int y); + void keyboard(unsigned char key, int x, int y); + void special(int key, int x, int y); + void special_up(int key, int x, int y); + void passive_motion(int x, int y); + void reshape( int w, int h ); + void visibility(int state); + void motion(int x, int y); + void entry(int state); + void display( void ); + void idle(void); + int needs_idle(void); + + void (*glut_mouse_CB)(int, int, int, int); + void (*glut_keyboard_CB)(unsigned char, int, int); + void (*glut_special_CB)(int, int, int); + void (*glut_reshape_CB)(int, int); + + + /*********** Controls ************/ + + virtual int add_control( GLUI_Node *parent, GLUI_Control *control ); + + + /********** Constructors and Destructors ***********/ + + GLUI_Main( void ); + +public: + GLUI_StdBitmaps std_bitmaps; + GLUI_String window_name; + RGBc bkgd_color; + float bkgd_color_f[3]; + + void *font; + int curr_modifiers; + + void adjust_glut_xy( int &x, int &y ) { (void)x; y = h-y; } + void activate_control( GLUI_Control *control, int how ); + void align_controls( GLUI_Control *control ); + void deactivate_current_control( void ); + + /** Draw a 3D-look pushed-out box around this rectangle */ + void draw_raised_box( int x, int y, int w, int h ); + /** Draw a 3D-look pushed-in box around this rectangle */ + void draw_lowered_box( int x, int y, int w, int h ); + + /** Return true if this control should redraw itself immediately (front buffer); + Or queue up a redraw and return false if it shouldn't (back buffer). + */ + bool should_redraw_now(GLUI_Control *ctl); + + int getMainWindowId() + { + return main_gfx_window_id; + } + /** Switch to the appropriate draw buffer now. Returns the old draw buffer. + This routine should probably only be called from inside the GLUI_DrawingSentinal, + in glui_internal_control.h + */ + int set_current_draw_buffer(); + /** Go back to using this draw buffer. Undoes set_current_draw_buffer. */ + void restore_draw_buffer( int buffer_state ); + + /** Pack, resize the window, and redraw all the controls. */ + void refresh(); + + /** Redraw the main graphics window */ + void post_update_main_gfx(); + + /** Recompute the sizes and positions of all controls */ + void pack_controls(); + + void close_internal(); + void check_subwindow_position(); + void set_ortho_projection(); + void set_viewport(); + int get_glut_window_id( void ) { return glut_window_id; } /* JVK */ +}; + +/************************************************************/ +/* */ +/* GLUI_Control: base class for all controls */ +/* */ +/************************************************************/ + +//get rid of the dynamic_cast/RTTI requirements, just do a virtual function + + +/** + All the GUI objects inherit from GLUI_Control: buttons, + checkboxes, labels, edit boxes, scrollbars, etc. + Most of the work of this class is in routing events, + like keystrokes, mouseclicks, redraws, and sizing events. + + Yes, this is a huge and hideous class. It needs to be + split up into simpler subobjects. None of the data members + should be directly accessed by users (they should be protected, + not public); only subclasses. +*/ +class GLUI_Control : public GLUI_Node +{ +public: + +/** Onscreen coordinates */ + int w, h; /* dimensions of control */ + int x_abs, y_abs; + int x_off, y_off_top, y_off_bot; /* INNER margins, by which child + controls are indented */ + int contain_x, contain_y; + int contain_w, contain_h; + /* if this is a container control (e.g., + radiogroup or panel) this indicated dimensions + of inner area in which controls reside */ + +/** "activation" for tabbing between controls. */ + int active_type; ///< "GLUI_CONTROL_ACTIVE_..." + bool active; ///< If true, we've got the focus + bool can_activate; ///< If false, remove from tab order. + bool spacebar_mouse_click; ///< Spacebar simulates click. + +/** Callbacks */ + long user_id; ///< Integer to pass to callback function. + GLUI_CB callback; ///< User callback function, or NULL. + +/** Variable value storage */ + float float_val; /**< Our float value */ + int int_val; /**< Our integer value */ + float float_array_val[GLUI_DEF_MAX_ARRAY]; + int float_array_size; + GLUI_String text; /**< The text inside this control */ + +/** "Live variable" updating */ + void *ptr_val; /**< A pointer to the user's live variable value */ + int live_type; + bool live_inited; + /* These variables store the last value that live variable was known to have. */ + int last_live_int; + float last_live_float; + GLUI_String last_live_text; + float last_live_float_array[GLUI_DEF_MAX_ARRAY]; + +/** Properties of our control */ + GLUI *glui; /**< Our containing event handler (NEVER NULL during event processing!) */ + bool is_container; /**< Is this a container class (e.g., panel) */ + int alignment; + bool enabled; /**< Is this control grayed out? */ + GLUI_String name; /**< The name of this control */ + void *font; /**< Our glutbitmap font */ + bool collapsible, is_open; + GLUI_Node collapsed_node; + bool hidden; /* Collapsed controls (and children) are hidden */ + int char_widths[CHAR_WIDTH_HASH_SIZE][2]; /* Character width hash table */ + +public: + /*** Get/Set values ***/ + virtual void set_name( const char *string ); + virtual void set_int_val( int new_int ) { int_val = new_int; output_live(true); } + virtual void set_float_val( float new_float ) { float_val = new_float; output_live(true); } + virtual void set_ptr_val( void *new_ptr ) { ptr_val = new_ptr; output_live(true); } + virtual void set_float_array_val( float *array_ptr ); + + virtual float get_float_val( void ) { return float_val; } + virtual int get_int_val( void ) { return int_val; } + virtual void get_float_array_val( float *array_ptr ); + virtual int get_id( void ) const { return user_id; } + virtual void set_id( int id ) { user_id=id; } + + virtual int mouse_down_handler( int local_x, int local_y ) { (void)local_x; (void)local_y; return false; } + virtual int mouse_up_handler( int local_x, int local_y, bool inside ) { (void)local_x; (void)local_y; (void)inside; return false; } + virtual int mouse_held_down_handler( int local_x, int local_y, bool inside) { (void)local_x; (void)local_y; (void)inside; return false; } + virtual int key_handler( unsigned char key, int modifiers ) { (void)key; (void)modifiers; return false; } + virtual int special_handler( int key,int modifiers ) { (void)key; (void)modifiers; return false; } + virtual int special_up_handler( int key,int modifiers ) { (void)key; (void)modifiers; return false; } + + virtual void update_size( void ) { } + virtual void idle( void ) { } + virtual int mouse_over( int state, int x, int y ) { (void)state; (void)x; (void)y; return false; } + + virtual void enable( void ); + virtual void disable( void ); + virtual void activate( int how ) { (void)how; active = true; } + virtual void deactivate( void ) { active = false; } + + /** Hide (shrink into a rollout) and unhide (expose from a rollout) */ + void hide_internal( int recurse ); + void unhide_internal( int recurse ); + + + /** Return true if it currently makes sense to draw this class. */ + int can_draw( void ) { return (glui != NULL && hidden == false); } + + /** Redraw this control. + In single-buffering mode (drawing to GL_FRONT), this is just + a call to translate_and_draw_front (after a can_draw() check). + In double-buffering mode (drawing to GL_BACK), this queues up + a redraw and returns false, since you shouldn't draw yet. + */ + void redraw(void); + + /** Redraw everybody in our window. */ + void redraw_window(void); + + virtual void align( void ); + void pack( int x, int y ); /* Recalculate positions and offsets */ + void pack_old( int x, int y ); + void draw_recursive( int x, int y ); + int set_to_glut_window( void ); + void restore_window( int orig ); + void translate_and_draw_front( void ); + void translate_to_origin( void ) + {glTranslatef((float)x_abs+.5f,(float)y_abs+.5f,0.0f);} + virtual void draw( int x, int y )=0; + void set_font( void *new_font ); + void *get_font( void ); + int string_width( const char *text ); + int string_width( const GLUI_String &str ) + { return string_width(str.c_str()); } + int char_width( char c ); + + void draw_name( int x, int y ); + void draw_box_inwards_outline( int x_min, int x_max, + int y_min, int y_max ); + void draw_box( int x_min, int x_max, int y_min, int y_max, + float r, float g, float b ); + void draw_bkgd_box( int x_min, int x_max, int y_min, int y_max ); + void draw_emboss_box( int x_min, int x_max,int y_min,int y_max); + void draw_string( const char *text ); + void draw_string( const GLUI_String &s ) + { draw_string(s.c_str()); } + void draw_char( char c ); + void draw_active_box( int x_min, int x_max, int y_min, int y_max ); + void set_to_bkgd_color( void ); + + void set_w( int new_w ); + void set_h( int new_w ); + void set_alignment( int new_align ); + void sync_live( int recurse, int draw ); /* Reads live variable */ + void init_live( void ); + void output_live( int update_main_gfx ); /** Writes live variable **/ + virtual void set_text( const char *t ) { (void)t; } + void execute_callback( void ); + void get_this_column_dims( int *col_x, int *col_y, + int *col_w, int *col_h, + int *col_x_off, int *col_y_off ); + virtual bool needs_idle( void ) const; + virtual bool wants_tabs() const { return false; } + + GLUI_Control(void) + { + x_off = GLUI_XOFF; + y_off_top = GLUI_YOFF; + y_off_bot = GLUI_YOFF; + x_abs = GLUI_XOFF; + y_abs = GLUI_YOFF; + active = false; + enabled = true; + int_val = 0; + last_live_int = 0; + float_array_size = 0; + glui_format_str(name, "Control: %p", this); + float_val = 0.0; + last_live_float = 0.0; + ptr_val = NULL; + glui = NULL; + w = GLUI_DEFAULT_CONTROL_WIDTH; + h = GLUI_DEFAULT_CONTROL_HEIGHT; + font = NULL; + active_type = GLUI_CONTROL_ACTIVE_MOUSEDOWN; + alignment = GLUI_ALIGN_LEFT; + is_container = false; + can_activate = true; /* By default, you can activate a control */ + spacebar_mouse_click = true; /* Does spacebar simulate a mouse click? */ + live_type = GLUI_LIVE_NONE; + text = ""; + // last_live_text == ""; + live_inited = false; + collapsible = false; + is_open = true; + hidden = false; + memset(char_widths, -1, sizeof(char_widths)); /* JVK */ + int i; + for( i=0; iint_val = 1; set_color(red, green, blue); } } + void disable_bar() { if (column) { column->int_val = 0; } } + void set_child_number(int c) { child_number = c; } + void set_level_color(float r, float g, float b) { + lred = r; + lgreen = g; + lblue = b; + } + void set_color(float r, float g, float b) { + red = r; + green = g; + blue = b; + } + + virtual GLUI_Tree* dynamicCastGLUI_Tree() + { + return this; + } +protected: + void common_init() + { + currently_inside = false; + initially_inside = false; + can_activate = true; + is_container = true; + h = GLUI_DEFAULT_CONTROL_HEIGHT + 7; + w = GLUI_DEFAULT_CONTROL_WIDTH; + y_off_top = 21; + collapsible = true; + red = .5; + green = .5; + blue = .5; + lred = 0; + lgreen = 0; + lblue = 0; + column = NULL; + is_current = 0; + child_number = 0; + format = 0; + panel = NULL; + name = ""; + level_name = ""; + level = 0; + + }; +}; + + +/************************************************************/ +/* */ +/* TreePanel class (container) JVK */ +/* */ +/************************************************************/ + +/** + Manages, maintains, and formats a tree of GLUI_Tree objects. + These are shown in a heirarchical, collapsible display. + + FIXME: There's an infinite loop in the traversal code (OSL 2006/06) +*/ +class GLUI_TreePanel : public GLUI_Panel +{ +public: + GLUI_TreePanel(GLUI_Node *parent, const char *name, + bool open=false, int inset=0); + + int max_levels; + int next_id; + int format; + float red; + float green; + float blue; + float lred; + float lgreen; + float lblue; + int root_children; + /* These variables allow the tree panel to traverse the tree + using only two function calls. (Well, four, if you count + going in reverse */ + + GLUI_Tree *curr_branch; /* Current Branch */ + GLUI_Panel *curr_root; /* Current Root */ + +public: + void set_color(float r, float g, float b); + void set_level_color(float r, float g, float b); + void set_format(int f) { format = f; } + + /* Adds branch to curr_root */ + GLUI_Tree * ab(const char *name, GLUI_Tree *root = NULL); + /* Goes up one level, resets curr_root and curr_branch to parents*/ + void fb(GLUI_Tree *branch= NULL); + /* Deletes the curr_branch, goes up one level using fb */ + void db(GLUI_Tree *branch = NULL); + /* Finds the very last branch of curr_root, resets vars */ + void descendBranch(GLUI_Panel *root = NULL); + /* Resets curr_root and curr branch to TreePanel and lastChild */ + void resetToRoot(GLUI_Panel *new_root = NULL); + void next( void ); + void refresh( void ); + void expand_all( void ); + void collapse_all( void ); + void update_all( void ); + void initNode(GLUI_Tree *temp); + void formatNode(GLUI_Tree *temp); + virtual GLUI_TreePanel* dynamicCastGLUI_TreePanel() + { + return this; + } + +protected: + int uniqueID( void ) { next_id++; return next_id - 1; } + void common_init() + { + GLUI_Panel(); + next_id = 0; + curr_root = this; + curr_branch = NULL; + red = .5; + green = .5; + blue = .5; + root_children = 0; + } +}; + +/************************************************************/ +/* */ +/* User-Level GLUI class */ +/* */ +/************************************************************/ + +class GLUI_Rotation; +class GLUI_Translation; + +/** + The main user-visible interface object to GLUI. + +*/ +class GLUI : public GLUI_Main +{ +public: +/** DEPRECATED interface for creating new GLUI objects */ + int add_control( GLUI_Control *control ) { return main_panel->add_control(control); } + + void add_column( int draw_bar = true ); + void add_column_to_panel( GLUI_Panel *panel, int draw_bar = true ); + + void add_separator( void ); + void add_separator_to_panel( GLUI_Panel *panel ); + + GLUI_RadioGroup + *add_radiogroup( int *live_var=NULL, + int user_id=-1,GLUI_CB callback=GLUI_CB()); + + GLUI_RadioGroup + *add_radiogroup_to_panel( GLUI_Panel *panel, + int *live_var=NULL, + int user_id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_RadioButton + *add_radiobutton_to_group( GLUI_RadioGroup *group, + const char *name ); + + GLUI_Listbox *add_listbox( const char *name, int *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_Listbox *add_listbox_to_panel( GLUI_Panel *panel, + const char *name, int *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB()); + + GLUI_Rotation *add_rotation( const char *name, float *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_Rotation *add_rotation_to_panel( GLUI_Panel *panel, + const char *name, float *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB()); + + GLUI_Translation *add_translation( const char *name, + int trans_type, float *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_Translation *add_translation_to_panel( + GLUI_Panel *panel, const char *name, + int trans_type, float *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB()); + + GLUI_Checkbox *add_checkbox( const char *name, + int *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB()); + GLUI_Checkbox *add_checkbox_to_panel( GLUI_Panel *panel, const char *name, + int *live_var=NULL, int id=-1, + GLUI_CB callback=GLUI_CB()); + + GLUI_Button *add_button( const char *name, int id=-1, + GLUI_CB callback=GLUI_CB()); + GLUI_Button *add_button_to_panel( GLUI_Panel *panel, const char *name, + int id=-1, GLUI_CB callback=GLUI_CB() ); + + GLUI_StaticText *add_statictext( const char *name ); + GLUI_StaticText *add_statictext_to_panel( GLUI_Panel *panel, const char *name ); + + GLUI_EditText *add_edittext( const char *name, + int data_type=GLUI_EDITTEXT_TEXT, + void*live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_EditText *add_edittext_to_panel( GLUI_Panel *panel, + const char *name, + int data_type=GLUI_EDITTEXT_TEXT, + void *live_var=NULL, int id=-1, + GLUI_CB callback=GLUI_CB() ); + GLUI_EditText *add_edittext( const char *name, GLUI_String& live_var, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_EditText *add_edittext_to_panel( GLUI_Panel *panel, const char *name, + GLUI_String& live_var, int id=-1, + GLUI_CB callback=GLUI_CB() ); + + GLUI_Spinner *add_spinner( const char *name, + int data_type=GLUI_SPINNER_INT, + void *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_Spinner *add_spinner_to_panel( GLUI_Panel *panel, + const char *name, + int data_type=GLUI_SPINNER_INT, + void *live_var=NULL, + int id=-1, + GLUI_CB callback=GLUI_CB() ); + + GLUI_Panel *add_panel( const char *name, int type=GLUI_PANEL_EMBOSSED ); + GLUI_Panel *add_panel_to_panel( GLUI_Panel *panel, const char *name, + int type=GLUI_PANEL_EMBOSSED ); + + + GLUI_Rollout *add_rollout( const char *name, int open=true, + int type=GLUI_PANEL_EMBOSSED); + GLUI_Rollout *add_rollout_to_panel( GLUI_Panel *panel, const char *name, + int open=true, + int type=GLUI_PANEL_EMBOSSED); + + +/** Set the window where our widgets should be displayed. */ + void set_main_gfx_window( int window_id ); + int get_glut_window_id( void ) { return glut_window_id; } + + void enable( void ) { main_panel->enable(); } + void disable( void ); + + void sync_live( void ); + + void close( void ); + + void show( void ); + void hide( void ); + + /***** GLUT callback setup functions *****/ + /* + void set_glutDisplayFunc(void (*f)(void)); + void set_glutReshapeFunc(void (*f)(int width, int height)); + void set_glutKeyboardFunc(void (*f)(unsigned char key, int x, int y)); + void set_glutSpecialFunc(void (*f)(int key, int x, int y)); + void set_glutMouseFunc(void (*f)(int button, int state, int x, int y)); + void set_glutMotionFunc(void (*f)(int x, int y)); + void set_glutPassiveMotionFunc(void (*f)(int x, int y)); + void set_glutEntryFunc(void (*f)(int state)); + void set_glutVisibilityFunc(void (*f)(int state)); + void set_glutInit( int *argcp, const char **argv ); + void set_glutInitWindowSize(int width, int height); + void set_glutInitWindowPosition(int x, int y); + void set_glutInitDisplayMode(unsigned int mode); + int set_glutCreateWindow(const char *name); + */ + + /***** Constructors and desctructors *****/ + + int init( const char *name, long flags, int x, int y, int parent_window ); +protected: + virtual int add_control( GLUI_Node *parent, GLUI_Control *control ) { + return GLUI_Main::add_control( parent, control ); + } +}; + +/************************************************************/ +/* */ +/* EditText class */ +/* */ +/************************************************************/ + +class GLUI_EditText : public GLUI_Control +{ +public: + int has_limits; + int data_type; + GLUI_String orig_text; + int insertion_pt; + int title_x_offset; + int text_x_offset; + int substring_start; /*substring that gets displayed in box*/ + int substring_end; + int sel_start, sel_end; /* current selection */ + int num_periods; + int last_insertion_pt; + float float_low, float_high; + int int_low, int_high; + GLUI_Spinner *spinner; + int debug; + int draw_text_only; + + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + int key_handler( unsigned char key,int modifiers ); + int special_handler( int key, int modifiers ); + + void activate( int how ); + void deactivate( void ); + + void draw( int x, int y ); + + int mouse_over( int state, int x, int y ); + + int find_word_break( int start, int direction ); + int substring_width( int start, int end ); + void clear_substring( int start, int end ); + int find_insertion_pt( int x, int y ); + int update_substring_bounds( void ); + void update_and_draw_text( void ); + void draw_text( int x, int y ); + void draw_insertion_pt( void ); + void set_numeric_text( void ); + void update_x_offsets( void ); + void update_size( void ); + + void set_float_limits( float low,float high,int limit_type=GLUI_LIMIT_CLAMP); + void set_int_limits( int low, int high, int limit_type=GLUI_LIMIT_CLAMP ); + void set_float_val( float new_val ); + void set_int_val( int new_val ); + void set_text( const char *text ); + void set_text( const GLUI_String &s) { set_text(s.c_str()); } + const char *get_text() { return text.c_str(); } + + void dump( FILE *out, const char *text ); + + // Constructor, no live variable + GLUI_EditText( GLUI_Node *parent, const char *name, + int text_type=GLUI_EDITTEXT_TEXT, + int id=-1, GLUI_CB callback=GLUI_CB() ); + // Constructor, int live variable + GLUI_EditText( GLUI_Node *parent, const char *name, + int *live_var, + int id=-1, GLUI_CB callback=GLUI_CB() ); + // Constructor, float live variable + GLUI_EditText( GLUI_Node *parent, const char *name, + float *live_var, + int id=-1, GLUI_CB callback=GLUI_CB() ); + // Constructor, char* live variable + GLUI_EditText( GLUI_Node *parent, const char *name, + char *live_var, + int id=-1, GLUI_CB callback=GLUI_CB() ); + // Constructor, std::string live variable + GLUI_EditText( GLUI_Node *parent, const char *name, + std::string &live_var, + int id=-1, GLUI_CB callback=GLUI_CB() ); + + // Deprecated constructor, only called internally + GLUI_EditText( GLUI_Node *parent, const char *name, + int text_type, void *live_var, + int id, GLUI_CB callback ); + // Deprecated constructor, only called internally + GLUI_EditText( void ) { common_init(); } + + virtual GLUI_EditText* dynamicCastGLUI_EditText() + { + return this; + } + + +protected: + void common_init( void ) { + h = GLUI_EDITTEXT_HEIGHT; + w = GLUI_EDITTEXT_WIDTH; + title_x_offset = 0; + text_x_offset = 55; + insertion_pt = -1; + last_insertion_pt = -1; + name = ""; + substring_start = 0; + data_type = GLUI_EDITTEXT_TEXT; + substring_end = 2; + num_periods = 0; + has_limits = GLUI_LIMIT_NONE; + sel_start = 0; + sel_end = 0; + active_type = GLUI_CONTROL_ACTIVE_PERMANENT; + can_activate = true; + spacebar_mouse_click = false; + spinner = NULL; + debug = false; + draw_text_only = false; + } + void common_construct( GLUI_Node *parent, const char *name, + int data_type, int live_type, void *live_var, + int id, GLUI_CB callback ); +}; + +/************************************************************/ +/* */ +/* CommandLine class */ +/* */ +/************************************************************/ + +class GLUI_CommandLine : public GLUI_EditText +{ +public: + typedef GLUI_EditText Super; + + enum { HIST_SIZE = 100 }; + std::vector hist_list; + int curr_hist; + int oldest_hist; + int newest_hist; + bool commit_flag; + +public: + int key_handler( unsigned char key,int modifiers ); + int special_handler( int key,int modifiers ); + void deactivate( void ); + + virtual const char *get_history( int command_number ) const + { return hist_list[command_number - oldest_hist].c_str(); } + virtual GLUI_String& get_history_str( int command_number ) + { return hist_list[command_number - oldest_hist]; } + virtual const GLUI_String& get_history_str( int command_number ) const + { return hist_list[command_number - oldest_hist]; } + virtual void recall_history( int history_number ); + virtual void scroll_history( int direction ); + virtual void add_to_history( const char *text ); + virtual void reset_history( void ); + + void dump( FILE *out, const char *text ); + + + GLUI_CommandLine( GLUI_Node *parent, const char *name, void *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_CommandLine( void ) { common_init(); } +protected: + void common_init() { + hist_list.resize(HIST_SIZE); + curr_hist = 0; + oldest_hist = 0; + newest_hist = 0; + commit_flag = false; + } +}; + +/************************************************************/ +/* */ +/* RadioGroup class (container) */ +/* */ +/************************************************************/ + +class GLUI_RadioGroup : public GLUI_Control +{ +public: + int num_buttons; + + void draw( int x, int y ); + void set_name( const char *text ); + void set_int_val( int int_val ); + void set_selected( int int_val ); + + void draw_group( int translate ); + + GLUI_RadioGroup( GLUI_Node *parent, int *live_var=NULL, + int user_id=-1,GLUI_CB callback=GLUI_CB() ); + GLUI_RadioGroup( void ) { common_init(); } + +protected: + void common_init( void ) { + x_off = 0; + y_off_top = 0; + y_off_bot = 0; + is_container = true; + w = 300; + h = 300; + num_buttons = 0; + name = ""; + can_activate = false; + live_type = GLUI_LIVE_INT; + } +}; + +/************************************************************/ +/* */ +/* RadioButton class (container) */ +/* */ +/************************************************************/ + +class GLUI_RadioButton : public GLUI_Control +{ +public: + int orig_value; + bool currently_inside; + int text_x_offset; + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + + void draw( int x, int y ); + void update_size( void ); + + void draw_active_area( void ); + void draw_checked( void ); + void draw_unchecked( void ); + void draw_O( void ); + + GLUI_RadioButton( GLUI_RadioGroup *group, const char *name ); + GLUI_RadioGroup *group; + +protected: + void common_init() + { + glui_format_str( name, "RadioButton: %p", (void *) this ); + h = GLUI_RADIOBUTTON_SIZE; + group = NULL; + orig_value = -1; + text_x_offset = 18; + can_activate = true; + } +}; + + +/************************************************************/ +/* */ +/* Separator class (container) */ +/* */ +/************************************************************/ + +class GLUI_Separator : public GLUI_Control +{ +public: + void draw( int x, int y ); + + GLUI_Separator( GLUI_Node *parent ); + GLUI_Separator( void ) { common_init(); } + +protected: + void common_init() { + w = 100; + h = GLUI_SEPARATOR_HEIGHT; + can_activate = false; + } +}; + +#define GLUI_SPINNER_ARROW_WIDTH 12 +#define GLUI_SPINNER_ARROW_HEIGHT 8 +#define GLUI_SPINNER_ARROW_Y 2 + +#define GLUI_SPINNER_STATE_NONE 0 +#define GLUI_SPINNER_STATE_UP 1 +#define GLUI_SPINNER_STATE_DOWN 2 +#define GLUI_SPINNER_STATE_BOTH 3 + +#define GLUI_SPINNER_DEFAULT_GROWTH_EXP 1.05f + +/************************************************************/ +/* */ +/* Spinner class (container) */ +/* */ +/************************************************************/ + +class GLUI_Spinner : public GLUI_Control +{ +public: + // Constructor, no live var + GLUI_Spinner( GLUI_Node* parent, const char *name, + int data_type=GLUI_SPINNER_INT, int id=-1, GLUI_CB callback=GLUI_CB() ); + // Constructor, int live var + GLUI_Spinner( GLUI_Node* parent, const char *name, + int *live_var, int id=-1, GLUI_CB callback=GLUI_CB() ); + // Constructor, float live var + GLUI_Spinner( GLUI_Node* parent, const char *name, + float *live_var, int id=-1, GLUI_CB callback=GLUI_CB() ); + // Deprecated constructor + GLUI_Spinner( GLUI_Node* parent, const char *name, + int data_type, + void *live_var, + int id=-1, GLUI_CB callback=GLUI_CB() ); + // Deprecated constructor + GLUI_Spinner( void ) { common_init(); } + + bool currently_inside; + int state; + float growth, growth_exp; + int last_x, last_y; + int data_type; + int callback_count; + int last_int_val; + float last_float_val; + int first_callback; + float user_speed; + + GLUI_EditText *edittext; + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + int key_handler( unsigned char key,int modifiers ); + int special_handler( int key,int modifiers ); + + void draw( int x, int y ); + void draw_pressed( void ); + void draw_unpressed( void ); + void draw_text( int sunken ); + + void update_size( void ); + + void set_float_limits( float low,float high,int limit_type=GLUI_LIMIT_CLAMP); + void set_int_limits( int low, int high,int limit_type=GLUI_LIMIT_CLAMP); + int find_arrow( int local_x, int local_y ); + void do_drag( int x, int y ); + void do_callbacks( void ); + void do_click( void ); + void idle( void ); + bool needs_idle( void ) const; + + const char *get_text( void ); + + void set_float_val( float new_val ); + void set_int_val( int new_val ); + float get_float_val( void ); + int get_int_val( void ); + void increase_growth( void ); + void reset_growth( void ); + + void set_speed( float speed ) { user_speed = speed; } + +protected: + void common_init() { + glui_format_str( name, "Spinner: %p", this ); + h = GLUI_EDITTEXT_HEIGHT; + w = GLUI_EDITTEXT_WIDTH; + x_off = 0; + y_off_top = 0; + y_off_bot = 0; + can_activate = true; + state = GLUI_SPINNER_STATE_NONE; + edittext = NULL; + growth_exp = GLUI_SPINNER_DEFAULT_GROWTH_EXP; + callback_count = 0; + first_callback = true; + user_speed = 1.0; + } + void common_construct( GLUI_Node* parent, const char *name, + int data_type, void *live_var, + int id, GLUI_CB callback ); +}; + +/************************************************************/ +/* */ +/* StaticText class */ +/* */ +/************************************************************/ + +class GLUI_StaticText : public GLUI_Control +{ +public: + void set_text( const char *text ); + void draw( int x, int y ); + void draw_text( void ); + void update_size( void ); + void erase_text( void ); + + GLUI_StaticText(GLUI_Node *parent, const char *name); + GLUI_StaticText( void ) { common_init(); } + +protected: + void common_init() { + h = GLUI_STATICTEXT_SIZE; + name = ""; + can_activate = false; + } +}; + +/************************************************************/ +/* */ +/* TextBox class - JVK */ +/* */ +/************************************************************/ + +class GLUI_TextBox : public GLUI_Control +{ +public: + /* GLUI Textbox - JVK */ + GLUI_TextBox(GLUI_Node *parent, GLUI_String &live_var, + bool scroll = false, int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_TextBox( GLUI_Node *parent, + bool scroll = false, int id=-1, + GLUI_CB callback=GLUI_CB() ); + + GLUI_String orig_text; + int insertion_pt; + int substring_start; /*substring that gets displayed in box*/ + int substring_end; + int sel_start, sel_end; /* current selection */ + int last_insertion_pt; + int debug; + int draw_text_only; + int tab_width; + int start_line; + int num_lines; + int curr_line; + int visible_lines; + int insert_x; /* Similar to "insertion_pt", these variables keep */ + int insert_y; /* track of where the ptr is, but in pixels */ + int keygoal_x; /* where up down keys would like to put insertion pt*/ + GLUI_Scrollbar *scrollbar; + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + int key_handler( unsigned char key,int modifiers ); + int special_handler( int key,int modifiers ); + + void activate( int how ); + void deactivate( void ); + + void enable( void ); + void disable( void ); + + void draw( int x, int y ); + + int mouse_over( int state, int x, int y ); + + int get_box_width(); + int find_word_break( int start, int direction ); + int substring_width( int start, int end, int initial_width=0 ); + void clear_substring( int start, int end ); + int find_insertion_pt( int x, int y ); + int update_substring_bounds( void ); + void update_and_draw_text( void ); + void draw_text( int x, int y ); + void draw_insertion_pt( void ); + void update_x_offsets( void ); + void update_size( void ); + + void set_text( const char *text ); + const char *get_text( void ) { return text.c_str(); } + + void dump( FILE *out, const char *text ); + void set_tab_w(int w) { tab_width = w; } + void set_start_line(int l) { start_line = l; } + static void scrollbar_callback(GLUI_Control*); + + bool wants_tabs( void ) const { return true; } + +protected: + void common_init() + { + h = GLUI_TEXTBOX_HEIGHT; + w = GLUI_TEXTBOX_WIDTH; + tab_width = GLUI_TAB_WIDTH; + num_lines = 0; + visible_lines = 0; + start_line = 0; + curr_line = 0; + insert_y = -1; + insert_x = -1; + insertion_pt = -1; + last_insertion_pt = -1; + name[0] = '\0'; + substring_start = 0; + substring_end = 2; + sel_start = 0; + sel_end = 0; + active_type = GLUI_CONTROL_ACTIVE_PERMANENT; + can_activate = true; + spacebar_mouse_click = false; + scrollbar = NULL; + debug = false; + draw_text_only = false; + } + void common_construct( + GLUI_Node *parent, GLUI_String *live_var, + bool scroll, int id, GLUI_CB callback); +}; + +/************************************************************/ +/* */ +/* List class - JVK */ +/* */ +/************************************************************/ + +class GLUI_List_Item : public GLUI_Node +{ +public: + GLUI_String text; + int id; +}; + +/************************************************************/ +/* */ +/* List class - JVK */ +/* */ +/************************************************************/ + +class GLUI_List : public GLUI_Control +{ +public: + /* GLUI List - JVK */ + GLUI_List( GLUI_Node *parent, bool scroll = false, + int id=-1, GLUI_CB callback=GLUI_CB() ); + /*, GLUI_Control *object = NULL + ,GLUI_InterObject_CB obj_cb = NULL);*/ + + GLUI_List( GLUI_Node *parent, + GLUI_String& live_var, bool scroll = false, + int id=-1, + GLUI_CB callback=GLUI_CB() + /*,GLUI_Control *object = NULL */ + /*,GLUI_InterObject_CB obj_cb = NULL*/); + + + GLUI_String orig_text; + int debug; + int draw_text_only; + int start_line; + int num_lines; + int curr_line; + int visible_lines; + GLUI_Scrollbar *scrollbar; + GLUI_List_Item items_list; + GLUI_Control *associated_object; + GLUI_CB obj_cb; + int cb_click_type; + int last_line; + int last_click_time; + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + int key_handler( unsigned char key,int modifiers ); + int special_handler( int key,int modifiers ); + + void activate( int how ); + void deactivate( void ); + + void draw( int x, int y ); + + int mouse_over( int state, int x, int y ); + + int get_box_width(); + int find_word_break( int start, int direction ); + int substring_width( const char *t, int start, int end ); + int find_line( int x, int y ); + void update_and_draw_text( void ); + void draw_text( const char *t, int selected, int x, int y ); + void update_size( void ); + + + int add_item( int id, const char *text ); + int delete_item( const char *text ); + int delete_item( int id ); + int delete_all(); + + GLUI_List_Item *get_item_ptr( const char *text ); + GLUI_List_Item *get_item_ptr( int id ); + + void dump( FILE *out, const char *text ); + void set_start_line(int l) { start_line = l; } + static void scrollbar_callback(GLUI_Control*); + int get_current_item() { return curr_line; } + void set_click_type(int d) { + cb_click_type = d; } + void set_object_callback(GLUI_CB cb=GLUI_CB(), GLUI_Control*obj=NULL) + { obj_cb=cb; associated_object=obj; } + + virtual GLUI_List* dynamicCastGLUI_List() + { + return this; + } + +protected: + void common_init() + { + h = GLUI_LIST_HEIGHT; + w = GLUI_LIST_WIDTH; + num_lines = 0; + visible_lines = 0; + start_line = 0; + curr_line = 0; + name[0] = '\0'; + active_type = GLUI_CONTROL_ACTIVE_PERMANENT; + can_activate = true; + spacebar_mouse_click = false; + scrollbar = NULL; + debug = false; + draw_text_only = false; + cb_click_type = GLUI_SINGLE_CLICK; + last_line = -1; + last_click_time = 0; + associated_object = NULL; + }; + void common_construct( + GLUI_Node *parent, + GLUI_String* live_var, bool scroll, + int id, + GLUI_CB callback + /*,GLUI_Control *object*/ + /*,GLUI_InterObject_CB obj_cb*/); +}; + +/************************************************************/ +/* */ +/* Scrollbar class - JVK */ +/* */ +/************************************************************/ + +class GLUI_Scrollbar : public GLUI_Control +{ +public: + // Constructor, no live var + GLUI_Scrollbar( GLUI_Node *parent, + const char *name, + int horz_vert=GLUI_SCROLL_HORIZONTAL, + int data_type=GLUI_SCROLL_INT, + int id=-1, GLUI_CB callback=GLUI_CB() + /*,GLUI_Control *object = NULL*/ + /*,GLUI_InterObject_CB obj_cb = NULL*/ + ); + + // Constructor, int live var + GLUI_Scrollbar( GLUI_Node *parent, const char *name, int horz_vert, + int *live_var, + int id=-1, GLUI_CB callback=GLUI_CB() + /*,GLUI_Control *object = NULL*/ + /*,GLUI_InterObject_CB obj_cb = NULL*/ + ); + + // Constructor, float live var + GLUI_Scrollbar( GLUI_Node *parent, const char *name, int horz_vert, + float *live_var, + int id=-1, GLUI_CB callback=GLUI_CB() + /*,GLUI_Control *object = NULL*/ + /*,GLUI_InterObject_CB obj_cb = NULL*/ + ); + + bool currently_inside; + int state; + float growth, growth_exp; + int last_x, last_y; + int data_type; + int callback_count; + int last_int_val; ///< Used to prevent repeated callbacks. + float last_float_val; + int first_callback; + float user_speed; + float float_min, float_max; + int int_min, int_max; + int horizontal; + double last_update_time; ///< GLUI_Time() we last advanced scrollbar. + double velocity_limit; ///< Maximum distance to advance per second. + int box_length; + int box_start_position; + int box_end_position; + int track_length; + + + /* Rather than directly access an Editbox or Textbox for + changing variables, a pointer to some object is defined + along with a static callback in the form func(void *, int) - + the int is the new value, the void * must be cast to that + particular object type before use. + */ + void * associated_object; /* Lets the Spinner manage it's own callbacks */ + GLUI_CB object_cb; /* function pointer to object call_back */ + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + int key_handler( unsigned char key,int modifiers ); + int special_handler( int key,int modifiers ); + + void draw( int x, int y ); + void draw_pressed( void ); + void draw_unpressed( void ); + void draw_text( int sunken ); + + void update_size( void ); + + void set_int_limits( int low, int high,int limit_type=GLUI_LIMIT_CLAMP); + void set_float_limits( float low,float high,int limit_type=GLUI_LIMIT_CLAMP); + int find_arrow( int local_x, int local_y ); + void do_drag( int x, int y ); + void do_callbacks( void ); + void draw_scroll( void ); + void do_click( void ); + void idle( void ); + bool needs_idle( void ) const; + void set_int_val( int new_val ); + void set_float_val( float new_val ); + void increase_growth( void ); + void reset_growth( void ); + + void set_speed( float speed ) { user_speed = speed; }; + void update_scroll_parameters(); + void set_object_callback(GLUI_CB cb=GLUI_CB(), GLUI_Control*obj=NULL) + { object_cb=cb; associated_object=obj; } + + virtual GLUI_Scrollbar* dynamicCastGLUI_Scrollbar() + { + return this; + } + +protected: + void common_init ( void ); + void common_construct( + GLUI_Node *parent, + const char *name, + int horz_vert, + int data_type, void* live_var, + int id, GLUI_CB callback + /*,GLUI_Control *object + ,GLUI_InterObject_CB obj_cb*/ + ); + + virtual void draw_scroll_arrow(int arrowtype, int x, int y); + virtual void draw_scroll_box(int x, int y, int w, int h); +}; + +/************************************************************/ +/* */ +/* Listbox class */ +/* */ +/************************************************************/ + +class GLUI_Listbox_Item : public GLUI_Node +{ +public: + GLUI_String text; + int id; +}; + +class GLUI_Listbox : public GLUI_Control +{ +public: + GLUI_String curr_text; + GLUI_Listbox_Item items_list; + int depressed; + + int orig_value; + bool currently_inside; + int text_x_offset, title_x_offset; + int glut_menu_id; + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + int key_handler( unsigned char key,int modifiers ); + int special_handler( int key,int modifiers ); + + void update_size( void ); + void draw( int x, int y ); + int mouse_over( int state, int x, int y ); + + void set_int_val( int new_val ); + void dump( FILE *output ); + + int add_item( int id, const char *text ); + int delete_item( const char *text ); + int delete_item( int id ); + int sort_items( void ); + + int do_selection( int item ); + + GLUI_Listbox_Item *get_item_ptr( const char *text ); + GLUI_Listbox_Item *get_item_ptr( int id ); + + + GLUI_Listbox( GLUI_Node *parent, + const char *name, int *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_Listbox( void ) { common_init(); } + + virtual GLUI_Listbox* dynamicCastGLUI_Listbox() + { + return this; + } + +protected: + /** Change w and return true if we need to be widened to fit the current item. */ + bool recalculate_item_width( void ); + void common_init() { + glui_format_str( name, "Listbox: %p", this ); + w = GLUI_EDITTEXT_WIDTH; + h = GLUI_EDITTEXT_HEIGHT; + orig_value = -1; + title_x_offset = 0; + text_x_offset = 55; + can_activate = true; + curr_text = ""; + live_type = GLUI_LIVE_INT; /* This has an integer live var */ + depressed = false; + glut_menu_id = -1; + } + + ~GLUI_Listbox(); +}; + +/************************************************************/ +/* */ +/* Mouse_Interaction class */ +/* */ +/************************************************************/ + +/** + This is the superclass of translation and rotation widgets. +*/ +class GLUI_Mouse_Interaction : public GLUI_Control +{ +public: + /*int get_main_area_size( void ) { return MIN( h-18, */ + int draw_active_area_only; + + int mouse_down_handler( int local_x, int local_y ); + int mouse_up_handler( int local_x, int local_y, bool inside ); + int mouse_held_down_handler( int local_x, int local_y, bool inside ); + int special_handler( int key, int modifiers ); + void update_size( void ); + void draw( int x, int y ); + void draw_active_area( void ); + + /*** The following methods (starting with "iaction_") need to + be overloaded ***/ + virtual int iaction_mouse_down_handler( int local_x, int local_y ) = 0; + virtual int iaction_mouse_up_handler( int local_x, int local_y, bool inside )=0; + virtual int iaction_mouse_held_down_handler( int local_x, int local_y, bool inside )=0; + virtual int iaction_special_handler( int key, int modifiers )=0; + virtual void iaction_draw_active_area_persp( void )=0; + virtual void iaction_draw_active_area_ortho( void )=0; + virtual void iaction_dump( FILE *output )=0; + virtual void iaction_init( void ) = 0; + + GLUI_Mouse_Interaction( void ) { + glui_format_str( name, "Mouse_Interaction: %p", this ); + w = GLUI_MOUSE_INTERACTION_WIDTH; + h = GLUI_MOUSE_INTERACTION_HEIGHT; + can_activate = true; + live_type = GLUI_LIVE_NONE; + alignment = GLUI_ALIGN_CENTER; + draw_active_area_only = false; + } +}; + +/************************************************************/ +/* */ +/* Rotation class */ +/* */ +/************************************************************/ + +/** + An onscreen rotation controller--allows the user to interact with + a 3D rotation via a spaceball-like interface. +*/ +class GLUI_Rotation : public GLUI_Mouse_Interaction +{ +public: + Arcball *ball; + GLUquadricObj *quadObj; + bool can_spin, spinning; + float damping; + + int iaction_mouse_down_handler( int local_x, int local_y ); + int iaction_mouse_up_handler( int local_x, int local_y, bool inside ); + int iaction_mouse_held_down_handler( int local_x, int local_y, bool inside ); + int iaction_special_handler( int key, int modifiers ); + void iaction_init( void ) { init_ball(); } + void iaction_draw_active_area_persp( void ); + void iaction_draw_active_area_ortho( void ); + void iaction_dump( FILE *output ); + + /* void update_size( void ); */ + /* void draw( int x, int y ); */ + /* int mouse_over( int state, int x, int y ); */ + + void setup_texture( void ); + void setup_lights( void ); + void draw_ball( float radius ); + + void init_ball( void ); + + void reset( void ); + + bool needs_idle( void ) const; + void idle( void ); + + void copy_float_array_to_ball( void ); + void copy_ball_to_float_array( void ); + + void set_spin( float damp_factor ); + + GLUI_Rotation( GLUI_Node *parent, const char *name, float *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_Rotation(void) { common_init(); } + +protected: + void common_init(); +}; + +/************************************************************/ +/* */ +/* Translation class */ +/* */ +/************************************************************/ + +/** + An onscreen translation controller--allows the user to interact with + a 3D translation. +*/ +class GLUI_Translation : public GLUI_Mouse_Interaction +{ +public: + int trans_type; /* Is this an XY or a Z controller? */ + int down_x, down_y; + float scale_factor; + GLUquadricObj *quadObj; + int trans_mouse_code; + float orig_x, orig_y, orig_z; + int locked; + + int iaction_mouse_down_handler( int local_x, int local_y ); + int iaction_mouse_up_handler( int local_x, int local_y, bool inside ); + int iaction_mouse_held_down_handler( int local_x, int local_y, bool inside ); + int iaction_special_handler( int key, int modifiers ); + void iaction_init( void ) { } + void iaction_draw_active_area_persp( void ); + void iaction_draw_active_area_ortho( void ); + void iaction_dump( FILE *output ); + + void set_speed( float s ) { scale_factor = s; } + + void setup_texture( void ); + void setup_lights( void ); + void draw_2d_arrow( int radius, int filled, int orientation ); + void draw_2d_x_arrows( int radius ); + void draw_2d_y_arrows( int radius ); + void draw_2d_z_arrows( int radius ); + void draw_2d_xy_arrows( int radius ); + + int get_mouse_code( int x, int y ); + + /* Float array is either a single float (for single-axis controls), + or two floats for X and Y (if an XY controller) */ + + float get_z( void ) { return float_array_val[0]; } + float get_x( void ) { return float_array_val[0]; } + float get_y( void ) { + if ( trans_type == GLUI_TRANSLATION_XY ) return float_array_val[1]; + else return float_array_val[0]; + } + + void set_z( float val ); + void set_x( float val ); + void set_y( float val ); + void set_one_val( float val, int index ); + + GLUI_Translation( GLUI_Node *parent, const char *name, + int trans_type, float *live_var=NULL, + int id=-1, GLUI_CB callback=GLUI_CB() ); + GLUI_Translation( void ) { common_init(); } + +protected: + void common_init() { + locked = GLUI_TRANSLATION_LOCK_NONE; + glui_format_str( name, "Translation: %p", this ); + w = GLUI_MOUSE_INTERACTION_WIDTH; + h = GLUI_MOUSE_INTERACTION_HEIGHT; + can_activate = true; + live_type = GLUI_LIVE_FLOAT_ARRAY; + float_array_size = 0; + alignment = GLUI_ALIGN_CENTER; + trans_type = GLUI_TRANSLATION_XY; + scale_factor = 1.0; + quadObj = NULL; + trans_mouse_code = GLUI_TRANSLATION_MOUSE_NONE; + } +}; + +/********** Misc functions *********************/ +int _glutBitmapWidthString( void *font, const char *s ); +void _glutBitmapString( void *font, const char *s ); + +/********** Our own callbacks for glut *********/ +/* These are the callbacks that we pass to glut. They take + some action if necessary, then (possibly) call the user-level + glut callbacks. +*/ + +void glui_display_func( void ); +void glui_reshape_func( int w, int h ); +void glui_keyboard_func(unsigned char key, int x, int y); +void glui_special_func(int key, int x, int y); +void glui_mouse_func(int button, int state, int x, int y); +void glui_motion_func(int x, int y); +void glui_passive_motion_func(int x, int y); +void glui_entry_func(int state); +void glui_visibility_func(int state); +void glui_idle_func(void); + +void glui_parent_window_reshape_func( int w, int h ); +void glui_parent_window_keyboard_func(unsigned char key, int x, int y); +void glui_parent_window_mouse_func(int, int, int, int ); +void glui_parent_window_special_func(int key, int x, int y); + +#endif diff --git a/Extras/glui/algebra3.cpp b/Extras/glui/algebra3.cpp new file mode 100644 index 0000000..5101480 --- /dev/null +++ b/Extras/glui/algebra3.cpp @@ -0,0 +1,1609 @@ +/* + + algebra3.cpp, algebra3.h - C++ Vector and Matrix Algebra routines + + GLUI User Interface Toolkit (LGPL) + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/************************************************************************** + + There are three vector classes and two matrix classes: vec2, vec3, + vec4, mat3, and mat4. + + All the standard arithmetic operations are defined, with '*' + for dot product of two vectors and multiplication of two matrices, + and '^' for cross product of two vectors. + + Additional functions include length(), normalize(), homogenize for + vectors, and print(), set(), apply() for all classes. + + There is a function transpose() for matrices, but note that it + does not actually change the matrix, + + When multiplied with a matrix, a vector is treated as a row vector + if it precedes the matrix (v*M), and as a column vector if it + follows the matrix (M*v). + + Matrices are stored in row-major form. + + A vector of one dimension (2d, 3d, or 4d) can be cast to a vector + of a higher or lower dimension. If casting to a higher dimension, + the new component is set by default to 1.0, unless a value is + specified: + vec3 a(1.0, 2.0, 3.0 ); + vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0}; + When casting to a lower dimension, the vector is homogenized in + the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the + resulting vector is {X/W, Y/W, Z/W}. It is up to the user to + insure the fourth component is not zero before casting. + + There are also the following function for building matrices: + identity2D(), translation2D(), rotation2D(), + scaling2D(), identity3D(), translation3D(), + rotation3D(), rotation3Drad(), scaling3D(), + perspective3D() + + + --------------------------------------------------------------------- + + Author: Jean-Francois DOUEg + Revised: Paul Rademacher + Version 3.2 - Feb 1998 + Revised: Nigel Stewart (GLUI Code Cleaning) + +**************************************************************************/ + +#include "algebra3.h" +#include "glui_internal.h" +#include + +#ifdef VEC_ERROR_FATAL +#ifndef VEC_ERROR +#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); exit(1); } +#endif +#else +#ifndef VEC_ERROR +#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); } +#endif +#endif + +/**************************************************************** + * * + * vec2 Member functions * + * * + ****************************************************************/ + +/******************** vec2 CONSTRUCTORS ********************/ + +vec2::vec2() +{ + n[VX] = n[VY] = 0.0; +} + +vec2::vec2(float x, float y) +{ + n[VX] = x; + n[VY] = y; +} + +vec2::vec2(const vec2 &v) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; +} + +vec2::vec2(const vec3 &v) // it is up to caller to avoid divide-by-zero +{ + n[VX] = v.n[VX]/v.n[VZ]; + n[VY] = v.n[VY]/v.n[VZ]; +} + +vec2::vec2(const vec3 &v, int dropAxis) +{ + switch (dropAxis) + { + case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; break; + case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; break; + default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; break; + } +} + +/******************** vec2 ASSIGNMENT OPERATORS ******************/ + +vec2 & vec2::operator=(const vec2 &v) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + return *this; +} + +vec2 & vec2::operator+=(const vec2 &v) +{ + n[VX] += v.n[VX]; + n[VY] += v.n[VY]; + return *this; +} + +vec2 & vec2::operator-=(const vec2 &v) +{ + n[VX] -= v.n[VX]; + n[VY] -= v.n[VY]; + return *this; +} + +vec2 &vec2::operator*=(float d) +{ + n[VX] *= d; + n[VY] *= d; + return *this; +} + +vec2 &vec2::operator/=(float d) +{ + float d_inv = 1.0f/d; + n[VX] *= d_inv; + n[VY] *= d_inv; + return *this; +} + +float &vec2::operator[](int i) +{ + if (i < VX || i > VY) + //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("vec2 [] operator: illegal access" ); + return n[i]; +} + +const float &vec2::operator[](int i) const +{ + if (i < VX || i > VY) + //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("vec2 [] operator: illegal access" ); + + return n[i]; +} + +/******************** vec2 SPECIAL FUNCTIONS ********************/ + +float vec2::length() const +{ + return (float) sqrt(length2()); +} + +float vec2::length2() const +{ + return n[VX]*n[VX] + n[VY]*n[VY]; +} + +vec2 &vec2::normalize() // it is up to caller to avoid divide-by-zero +{ + *this /= length(); + return *this; +} + +vec2 &vec2::apply(V_FCT_PTR fct) +{ + n[VX] = (*fct)(n[VX]); + n[VY] = (*fct)(n[VY]); + return *this; +} + +void vec2::set( float x, float y ) +{ + n[VX] = x; n[VY] = y; +} + +/******************** vec2 FRIENDS *****************************/ + +vec2 operator-(const vec2 &a) +{ + return vec2(-a.n[VX],-a.n[VY]); +} + +vec2 operator+(const vec2 &a, const vec2& b) +{ + return vec2(a.n[VX]+b.n[VX], a.n[VY]+b.n[VY]); +} + +vec2 operator-(const vec2 &a, const vec2& b) +{ + return vec2(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY]); +} + +vec2 operator*(const vec2 &a, float d) +{ + return vec2(d*a.n[VX], d*a.n[VY]); +} + +vec2 operator*(float d, const vec2 &a) +{ + return a*d; +} + +vec2 operator*(const mat3 &a, const vec2 &v) +{ + vec3 av; + + av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ]; + av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ]; + av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ]; + + return av; +} + +vec2 operator*(const vec2 &v, const mat3 &a) +{ + return a.transpose() * v; +} + +vec3 operator*(const mat3 &a, const vec3 &v) +{ + vec3 av; + + av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ]*v.n[VZ]; + av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ]*v.n[VZ]; + av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ]*v.n[VZ]; + + return av; +} + +vec3 operator*(const vec3 &v, const mat3 &a) +{ + return a.transpose() * v; +} + +float operator*(const vec2 &a, const vec2 &b) +{ + return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY]; +} + +vec2 operator/(const vec2 &a, float d) +{ + float d_inv = 1.0f/d; + return vec2(a.n[VX]*d_inv, a.n[VY]*d_inv); +} + +vec3 operator^(const vec2 &a, const vec2 &b) +{ + return vec3(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]); +} + +int operator==(const vec2 &a, const vec2 &b) +{ + return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]); +} + +int operator!=(const vec2 &a, const vec2 &b) +{ + return !(a == b); +} + +/*ostream& operator << (ostream& s, vec2& v) +{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << " |"; } +*/ + +/*istream& operator >> (istream& s, vec2& v) { + vec2 v_tmp; + char c = ' '; + + while (isspace(c)) + s >> c; + // The vectors can be formatted either as x y or | x y | + if (c == '|') { + s >> v_tmp[VX] >> v_tmp[VY]; + while (s >> c && isspace(c)) ; + if (c != '|') + ;//s.set(_bad); + } + else { + s.putback(c); + s >> v_tmp[VX] >> v_tmp[VY]; + } + if (s) + v = v_tmp; + return s; +} +*/ + +void swap(vec2 &a, vec2 &b) +{ + vec2 tmp(a); + a = b; + b = tmp; +} + +vec2 min_vec(const vec2 &a, const vec2 &b) +{ + return vec2(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY])); +} + +vec2 max_vec(const vec2 &a, const vec2 &b) +{ + return vec2(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY])); +} + +vec2 prod(const vec2 &a, const vec2 &b) +{ + return vec2(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]); +} + +/**************************************************************** + * * + * vec3 Member functions * + * * + ****************************************************************/ + +// CONSTRUCTORS + +vec3::vec3() +{ + n[VX] = n[VY] = n[VZ] = 0.0; +} + +vec3::vec3(float x, float y, float z) +{ + n[VX] = x; + n[VY] = y; + n[VZ] = z; +} + +vec3::vec3(const vec3 &v) +{ + n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ]; +} + +vec3::vec3(const vec2 &v) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + n[VZ] = 1.0; +} + +vec3::vec3(const vec2 &v, float d) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + n[VZ] = d; +} + +vec3::vec3(const vec4 &v) // it is up to caller to avoid divide-by-zero +{ + n[VX] = v.n[VX] / v.n[VW]; + n[VY] = v.n[VY] / v.n[VW]; + n[VZ] = v.n[VZ] / v.n[VW]; +} + +vec3::vec3(const vec4 &v, int dropAxis) +{ + switch (dropAxis) + { + case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break; + case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break; + case VZ: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VW]; break; + default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ]; break; + } +} + + +// ASSIGNMENT OPERATORS + +vec3 &vec3::operator=(const vec3 &v) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + n[VZ] = v.n[VZ]; + return *this; +} + +vec3 &vec3::operator+=(const vec3 &v) +{ + n[VX] += v.n[VX]; + n[VY] += v.n[VY]; + n[VZ] += v.n[VZ]; + return *this; +} + +vec3 &vec3::operator-=(const vec3& v) +{ + n[VX] -= v.n[VX]; + n[VY] -= v.n[VY]; + n[VZ] -= v.n[VZ]; + return *this; +} + +vec3 &vec3::operator*=(float d) +{ + n[VX] *= d; + n[VY] *= d; + n[VZ] *= d; + return *this; +} + +vec3 &vec3::operator/=(float d) +{ + float d_inv = 1.0f/d; + n[VX] *= d_inv; + n[VY] *= d_inv; + n[VZ] *= d_inv; + return *this; +} + +float &vec3::operator[](int i) +{ + if (i < VX || i > VZ) + //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("vec3 [] operator: illegal access" ); + + return n[i]; +} + +const float &vec3::operator[](int i) const +{ + if (i < VX || i > VZ) + //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("vec3 [] operator: illegal access" ); + + return n[i]; +} + +// SPECIAL FUNCTIONS + +float vec3::length() const +{ + return (float) sqrt(length2()); +} + +float vec3::length2() const +{ + return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ]; +} + +vec3 &vec3::normalize() // it is up to caller to avoid divide-by-zero +{ + *this /= length(); + return *this; +} + +vec3 &vec3::homogenize(void) // it is up to caller to avoid divide-by-zero +{ + n[VX] /= n[VZ]; + n[VY] /= n[VZ]; + n[VZ] = 1.0; + return *this; +} + +vec3 &vec3::apply(V_FCT_PTR fct) +{ + n[VX] = (*fct)(n[VX]); + n[VY] = (*fct)(n[VY]); + n[VZ] = (*fct)(n[VZ]); + return *this; +} + +void vec3::set(float x, float y, float z) // set vector +{ + n[VX] = x; + n[VY] = y; + n[VZ] = z; +} + +void vec3::print(FILE *file, const char *name) const // print vector to a file +{ + fprintf( file, "%s: <%f, %f, %f>\n", name, n[VX], n[VY], n[VZ] ); +} + +// FRIENDS + +vec3 operator-(const vec3 &a) +{ + return vec3(-a.n[VX],-a.n[VY],-a.n[VZ]); +} + +vec3 operator+(const vec3 &a, const vec3 &b) +{ + return vec3(a.n[VX]+ b.n[VX], a.n[VY] + b.n[VY], a.n[VZ] + b.n[VZ]); +} + +vec3 operator-(const vec3 &a, const vec3 &b) +{ + return vec3(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY], a.n[VZ]-b.n[VZ]); +} + +vec3 operator*(const vec3 &a, float d) +{ + return vec3(d*a.n[VX], d*a.n[VY], d*a.n[VZ]); +} + +vec3 operator*(float d, const vec3 &a) +{ + return a*d; +} + +vec3 operator*(const mat4 &a, const vec3 &v) +{ + return a*vec4(v); +} + +vec3 operator*(const vec3 &v, mat4 &a) +{ + return a.transpose()*v; +} + +float operator*(const vec3 &a, const vec3 &b) +{ + return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ]; +} + +vec3 operator/(const vec3 &a, float d) +{ + float d_inv = 1.0f/d; + return vec3(a.n[VX]*d_inv, a.n[VY]*d_inv, a.n[VZ]*d_inv); +} + +vec3 operator^(const vec3 &a, const vec3 &b) +{ + return + vec3(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY], + a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ], + a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]); +} + +int operator==(const vec3 &a, const vec3 &b) +{ + return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]); +} + +int operator!=(const vec3 &a, const vec3 &b) +{ + return !(a == b); +} + +/*ostream& operator << (ostream& s, vec3& v) +{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << " |"; } + +istream& operator >> (istream& s, vec3& v) { + vec3 v_tmp; + char c = ' '; + + while (isspace(c)) + s >> c; + // The vectors can be formatted either as x y z or | x y z | + if (c == '|') { + s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ]; + while (s >> c && isspace(c)) ; + if (c != '|') + ;//s.set(_bad); + } + else { + s.putback(c); + s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ]; + } + if (s) + v = v_tmp; + return s; +} +*/ + +void swap(vec3 &a, vec3 &b) +{ + vec3 tmp(a); + a = b; + b = tmp; +} + +vec3 min_vec(const vec3 &a, const vec3 &b) +{ + return vec3( + MIN(a.n[VX], b.n[VX]), + MIN(a.n[VY], b.n[VY]), + MIN(a.n[VZ], b.n[VZ])); +} + +vec3 max_vec(const vec3 &a, const vec3 &b) +{ + return vec3( + MAX(a.n[VX], b.n[VX]), + MAX(a.n[VY], b.n[VY]), + MAX(a.n[VZ], b.n[VZ])); +} + +vec3 prod(const vec3 &a, const vec3 &b) +{ + return vec3(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]); +} + +/**************************************************************** + * * + * vec4 Member functions * + * * + ****************************************************************/ + +// CONSTRUCTORS + +vec4::vec4() +{ + n[VX] = n[VY] = n[VZ] = 0.0; + n[VW] = 1.0; +} + +vec4::vec4(float x, float y, float z, float w) +{ + n[VX] = x; + n[VY] = y; + n[VZ] = z; + n[VW] = w; +} + +vec4::vec4(const vec4 &v) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + n[VZ] = v.n[VZ]; + n[VW] = v.n[VW]; +} + +vec4::vec4(const vec3 &v) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + n[VZ] = v.n[VZ]; + n[VW] = 1.0; +} + +vec4::vec4(const vec3 &v, float d) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + n[VZ] = v.n[VZ]; + n[VW] = d; +} + +// ASSIGNMENT OPERATORS + +vec4 &vec4::operator=(const vec4 &v) +{ + n[VX] = v.n[VX]; + n[VY] = v.n[VY]; + n[VZ] = v.n[VZ]; + n[VW] = v.n[VW]; + return *this; +} + +vec4 &vec4::operator+=(const vec4 &v) +{ + n[VX] += v.n[VX]; + n[VY] += v.n[VY]; + n[VZ] += v.n[VZ]; + n[VW] += v.n[VW]; + return *this; +} + +vec4 &vec4::operator-=(const vec4 &v) +{ + n[VX] -= v.n[VX]; + n[VY] -= v.n[VY]; + n[VZ] -= v.n[VZ]; + n[VW] -= v.n[VW]; + return *this; +} + +vec4 &vec4::operator*=(float d) +{ + n[VX] *= d; + n[VY] *= d; + n[VZ] *= d; + n[VW] *= d; + return *this; +} + +vec4 &vec4::operator/=(float d) +{ + float d_inv = 1.0f/d; + n[VX] *= d_inv; + n[VY] *= d_inv; + n[VZ] *= d_inv; + n[VW] *= d_inv; + return *this; +} + +float &vec4::operator[](int i) +{ + if (i < VX || i > VW) + //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("vec4 [] operator: illegal access" ); + + return n[i]; +} + +const float &vec4::operator[](int i) const +{ + if (i < VX || i > VW) + //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("vec4 [] operator: illegal access" ); + + return n[i]; +} + +// SPECIAL FUNCTIONS + +float vec4::length() const +{ + return (float) sqrt(length2()); +} + +float vec4::length2() const +{ + return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ] + n[VW]*n[VW]; +} + +vec4 &vec4::normalize() // it is up to caller to avoid divide-by-zero +{ + *this /= length(); + return *this; +} + +vec4 &vec4::homogenize() // it is up to caller to avoid divide-by-zero +{ + n[VX] /= n[VW]; + n[VY] /= n[VW]; + n[VZ] /= n[VW]; + n[VW] = 1.0; + return *this; +} + +vec4 &vec4::apply(V_FCT_PTR fct) +{ + n[VX] = (*fct)(n[VX]); + n[VY] = (*fct)(n[VY]); + n[VZ] = (*fct)(n[VZ]); + n[VW] = (*fct)(n[VW]); + return *this; +} + +void vec4::print(FILE *file, const char *name) const // print vector to a file +{ + fprintf( file, "%s: <%f, %f, %f, %f>\n", name, n[VX], n[VY], n[VZ], n[VW]); +} + +void vec4::set(float x, float y, float z, float a) +{ + n[0] = x; + n[1] = y; + n[2] = z; + n[3] = a; +} + + +// FRIENDS + +vec4 operator-(const vec4 &a) +{ + return vec4(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]); +} + +vec4 operator+(const vec4 &a, const vec4 &b) +{ + return vec4( + a.n[VX] + b.n[VX], + a.n[VY] + b.n[VY], + a.n[VZ] + b.n[VZ], + a.n[VW] + b.n[VW]); +} + +vec4 operator-(const vec4 &a, const vec4 &b) +{ + return vec4( + a.n[VX] - b.n[VX], + a.n[VY] - b.n[VY], + a.n[VZ] - b.n[VZ], + a.n[VW] - b.n[VW]); +} + +vec4 operator*(const vec4 &a, float d) +{ + return vec4(d*a.n[VX], d*a.n[VY], d*a.n[VZ], d*a.n[VW]); +} + +vec4 operator*(float d, const vec4 &a) +{ + return a*d; +} + +vec4 operator*(const mat4 &a, const vec4 &v) +{ + #define ROWCOL(i) \ + a.v[i].n[0]*v.n[VX] + \ + a.v[i].n[1]*v.n[VY] + \ + a.v[i].n[2]*v.n[VZ] + \ + a.v[i].n[3]*v.n[VW] + + return vec4(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3)); + + #undef ROWCOL +} + +vec4 operator*(const vec4 &v, const mat4 &a) +{ + return a.transpose()*v; +} + +float operator*(const vec4 &a, const vec4 &b) +{ + return + a.n[VX]*b.n[VX] + + a.n[VY]*b.n[VY] + + a.n[VZ]*b.n[VZ] + + a.n[VW]*b.n[VW]; +} + +vec4 operator/(const vec4 &a, float d) +{ + float d_inv = 1.0f/d; + return vec4( + a.n[VX]*d_inv, + a.n[VY]*d_inv, + a.n[VZ]*d_inv, + a.n[VW]*d_inv); +} + +int operator==(const vec4 &a, const vec4 &b) +{ + return + (a.n[VX] == b.n[VX]) && + (a.n[VY] == b.n[VY]) && + (a.n[VZ] == b.n[VZ]) && + (a.n[VW] == b.n[VW]); +} + +int operator!=(const vec4 &a, const vec4 &b) +{ + return !(a == b); +} + +/*ostream& operator << (ostream& s, vec4& v) +{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << ' ' + << v.n[VW] << " |"; } + +istream& operator >> (istream& s, vec4& v) { + vec4 v_tmp; + char c = ' '; + + while (isspace(c)) + s >> c; + // The vectors can be formatted either as x y z w or | x y z w | + if (c == '|') { + s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW]; + while (s >> c && isspace(c)) ; + if (c != '|') + ;//s.set(_bad); + } + else { + s.putback(c); + s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW]; + } + if (s) + v = v_tmp; + return s; +} +*/ + +void swap(vec4 &a, vec4 &b) +{ + vec4 tmp(a); + a = b; + b = tmp; +} + +vec4 min_vec(const vec4 &a, const vec4 &b) +{ + return vec4( + MIN(a.n[VX], b.n[VX]), + MIN(a.n[VY], b.n[VY]), + MIN(a.n[VZ], b.n[VZ]), + MIN(a.n[VW], b.n[VW])); +} + +vec4 max_vec(const vec4 &a, const vec4 &b) +{ + return vec4( + MAX(a.n[VX], b.n[VX]), + MAX(a.n[VY], b.n[VY]), + MAX(a.n[VZ], b.n[VZ]), + MAX(a.n[VW], b.n[VW])); +} + +vec4 prod(const vec4 &a, const vec4 &b) +{ + return vec4( + a.n[VX] * b.n[VX], + a.n[VY] * b.n[VY], + a.n[VZ] * b.n[VZ], + a.n[VW] * b.n[VW]); +} + +/**************************************************************** + * * + * mat3 member functions * + * * + ****************************************************************/ + +// CONSTRUCTORS + +mat3::mat3() +{ + *this = identity2D(); +} + +mat3::mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2) +{ + set(v0, v1, v2); +} + +mat3::mat3(const mat3 &m) +{ + v[0] = m.v[0]; + v[1] = m.v[1]; + v[2] = m.v[2]; +} + +// ASSIGNMENT OPERATORS + +mat3 &mat3::operator=(const mat3 &m) +{ + v[0] = m.v[0]; + v[1] = m.v[1]; + v[2] = m.v[2]; + return *this; +} + +mat3 &mat3::operator+=(const mat3& m) +{ + v[0] += m.v[0]; + v[1] += m.v[1]; + v[2] += m.v[2]; + return *this; +} + +mat3 &mat3::operator-=(const mat3& m) +{ + v[0] -= m.v[0]; + v[1] -= m.v[1]; + v[2] -= m.v[2]; + return *this; +} + +mat3 &mat3::operator*=(float d) +{ + v[0] *= d; + v[1] *= d; + v[2] *= d; + return *this; +} + +mat3 &mat3::operator/=(float d) +{ + v[0] /= d; + v[1] /= d; + v[2] /= d; + return *this; +} + +vec3 &mat3::operator[](int i) +{ + if (i < VX || i > VZ) + //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("mat3 [] operator: illegal access" ); + + return v[i]; +} + +const vec3 &mat3::operator[](int i) const +{ + if (i < VX || i > VZ) + //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("mat3 [] operator: illegal access" ); + + return v[i]; +} + +void mat3::set(const vec3 &v0, const vec3 &v1, const vec3 &v2) +{ + v[0] = v0; + v[1] = v1; + v[2] = v2; +} + +// SPECIAL FUNCTIONS + +mat3 mat3::transpose() const +{ + return mat3( + vec3(v[0][0], v[1][0], v[2][0]), + vec3(v[0][1], v[1][1], v[2][1]), + vec3(v[0][2], v[1][2], v[2][2])); +} + +mat3 mat3::inverse() const // Gauss-Jordan elimination with partial pivoting +{ + mat3 a(*this); // As a evolves from original mat into identity + mat3 b(identity2D()); // b evolves from identity into inverse(a) + int i, j, i1; + + // Loop over cols of a from left to right, eliminating above and below diag + for (j=0; j<3; j++) // Find largest pivot in column j among rows j..2 + { + i1 = j; // Row with largest pivot candidate + for (i=j+1; i<3; i++) + if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j])) + i1 = i; + + // Swap rows i1 and j in a and b to put pivot on diagonal + swap(a.v[i1], a.v[j]); + swap(b.v[i1], b.v[j]); + + // Scale row j to have a unit diagonal + if (a.v[j].n[j]==0.) + VEC_ERROR("mat3::inverse: singular matrix; can't invert\n"); + + b.v[j] /= a.v[j].n[j]; + a.v[j] /= a.v[j].n[j]; + + // Eliminate off-diagonal elems in col j of a, doing identical ops to b + for (i=0; i<3; i++) + if (i!=j) + { + b.v[i] -= a.v[i].n[j]*b.v[j]; + a.v[i] -= a.v[i].n[j]*a.v[j]; + } + } + + return b; +} + +mat3 &mat3::apply(V_FCT_PTR fct) +{ + v[VX].apply(fct); + v[VY].apply(fct); + v[VZ].apply(fct); + return *this; +} + + +// FRIENDS + +mat3 operator-(const mat3 &a) +{ + return mat3(-a.v[0], -a.v[1], -a.v[2]); +} + +mat3 operator+(const mat3 &a, const mat3 &b) +{ + return mat3(a.v[0]+b.v[0], a.v[1]+b.v[1], a.v[2]+b.v[2]); +} + +mat3 operator-(const mat3 &a, const mat3 &b) +{ + return mat3(a.v[0]-b.v[0], a.v[1]-b.v[1], a.v[2]-b.v[2]); +} + +mat3 operator*(const mat3 &a, const mat3 &b) +{ + #define ROWCOL(i, j) \ + a.v[i].n[0]*b.v[0][j] + a.v[i].n[1]*b.v[1][j] + a.v[i].n[2]*b.v[2][j] + + return mat3( + vec3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)), + vec3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)), + vec3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2))); + + #undef ROWCOL +} + +mat3 operator*(const mat3 &a, float d) +{ + return mat3(a.v[0]*d, a.v[1]*d, a.v[2]*d); +} + +mat3 operator*(float d, const mat3 &a) +{ + return a*d; +} + +mat3 operator/(const mat3 &a, float d) +{ + return mat3(a.v[0]/d, a.v[1]/d, a.v[2]/d); +} + +int operator==(const mat3 &a, const mat3 &b) +{ + return + (a.v[0] == b.v[0]) && + (a.v[1] == b.v[1]) && + (a.v[2] == b.v[2]); +} + +int operator!=(const mat3 &a, const mat3 &b) +{ + return !(a == b); +} + +/*ostream& operator << (ostream& s, mat3& m) +{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ]; } + +istream& operator >> (istream& s, mat3& m) { + mat3 m_tmp; + + s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ]; + if (s) + m = m_tmp; + return s; +} +*/ + +void swap(mat3 &a, mat3 &b) +{ + mat3 tmp(a); + a = b; + b = tmp; +} + +void mat3::print(FILE *file, const char *name) const +{ + int i, j; + + fprintf( stderr, "%s:\n", name ); + + for( i = 0; i < 3; i++ ) + { + fprintf( stderr, " " ); + for( j = 0; j < 3; j++ ) + { + fprintf( stderr, "%f ", v[i][j] ); + } + fprintf( stderr, "\n" ); + } +} + + + +/**************************************************************** + * * + * mat4 member functions * + * * + ****************************************************************/ + +// CONSTRUCTORS + +mat4::mat4() +{ + *this = identity3D(); +} + +mat4::mat4(const vec4& v0, const vec4& v1, const vec4& v2, const vec4& v3) +{ + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; +} + +mat4::mat4(const mat4 &m) +{ + v[0] = m.v[0]; + v[1] = m.v[1]; + v[2] = m.v[2]; + v[3] = m.v[3]; +} + +mat4::mat4( + float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33 ) +{ + v[0][0] = a00; v[0][1] = a01; v[0][2] = a02; v[0][3] = a03; + v[1][0] = a10; v[1][1] = a11; v[1][2] = a12; v[1][3] = a13; + v[2][0] = a20; v[2][1] = a21; v[2][2] = a22; v[2][3] = a23; + v[3][0] = a30; v[3][1] = a31; v[3][2] = a32; v[3][3] = a33; +} + +// ASSIGNMENT OPERATORS + +mat4 &mat4::operator=(const mat4 &m) +{ + v[0] = m.v[0]; + v[1] = m.v[1]; + v[2] = m.v[2]; + v[3] = m.v[3]; + return *this; +} + +mat4 &mat4::operator+=(const mat4 &m) +{ + v[0] += m.v[0]; + v[1] += m.v[1]; + v[2] += m.v[2]; + v[3] += m.v[3]; + return *this; +} + +mat4 &mat4::operator-=(const mat4 &m) +{ + v[0] -= m.v[0]; + v[1] -= m.v[1]; + v[2] -= m.v[2]; + v[3] -= m.v[3]; + return *this; +} + +mat4 &mat4::operator*=(float d) +{ + v[0] *= d; + v[1] *= d; + v[2] *= d; + v[3] *= d; + return *this; +} + +mat4 &mat4::operator/=(float d) +{ + v[0] /= d; + v[1] /= d; + v[2] /= d; + v[3] /= d; + return *this; +} + +vec4 &mat4::operator[](int i) +{ + if (i < VX || i > VW) + //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("mat4 [] operator: illegal access" ); + return v[i]; +} + +const vec4 &mat4::operator[](int i) const +{ + if (i < VX || i > VW) + //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n') + VEC_ERROR("mat4 [] operator: illegal access" ); + return v[i]; +} + +// SPECIAL FUNCTIONS; + +mat4 mat4::transpose() const +{ + return mat4( + vec4(v[0][0], v[1][0], v[2][0], v[3][0]), + vec4(v[0][1], v[1][1], v[2][1], v[3][1]), + vec4(v[0][2], v[1][2], v[2][2], v[3][2]), + vec4(v[0][3], v[1][3], v[2][3], v[3][3])); +} + +mat4 mat4::inverse() const // Gauss-Jordan elimination with partial pivoting +{ + mat4 a(*this); // As a evolves from original mat into identity + mat4 b(identity3D()); // b evolves from identity into inverse(a) + int i, j, i1; + + // Loop over cols of a from left to right, eliminating above and below diag + for (j=0; j<4; j++) // Find largest pivot in column j among rows j..3 + { + i1 = j; // Row with largest pivot candidate + for (i=j+1; i<4; i++) + if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j])) + i1 = i; + + // Swap rows i1 and j in a and b to put pivot on diagonal + swap(a.v[i1], a.v[j]); + swap(b.v[i1], b.v[j]); + + // Scale row j to have a unit diagonal + if (a.v[j].n[j]==0.) + VEC_ERROR("mat4::inverse: singular matrix; can't invert\n"); + + b.v[j] /= a.v[j].n[j]; + a.v[j] /= a.v[j].n[j]; + + // Eliminate off-diagonal elems in col j of a, doing identical ops to b + for (i=0; i<4; i++) + if (i!=j) + { + b.v[i] -= a.v[i].n[j]*b.v[j]; + a.v[i] -= a.v[i].n[j]*a.v[j]; + } + } + + return b; +} + +mat4 &mat4::apply(V_FCT_PTR fct) +{ + v[VX].apply(fct); + v[VY].apply(fct); + v[VZ].apply(fct); + v[VW].apply(fct); + return *this; +} + +void mat4::print(FILE *file, const char *name) const +{ + int i, j; + + fprintf( stderr, "%s:\n", name ); + + for( i = 0; i < 4; i++ ) + { + fprintf( stderr, " " ); + for( j = 0; j < 4; j++ ) + { + fprintf( stderr, "%f ", v[i][j] ); + } + fprintf( stderr, "\n" ); + } +} + +void mat4::swap_rows(int i, int j) +{ + vec4 t; + + t = v[i]; + v[i] = v[j]; + v[j] = t; +} + +void mat4::swap_cols(int i, int j) +{ + float t; + int k; + + for (k=0; k<4; k++) + { + t = v[k][i]; + v[k][i] = v[k][j]; + v[k][j] = t; + } +} + + +// FRIENDS + +mat4 operator-(const mat4 &a) +{ + return mat4(-a.v[0],-a.v[1],-a.v[2],-a.v[3]); +} + +mat4 operator+(const mat4 &a, const mat4 &b) +{ + return mat4( + a.v[0] + b.v[0], + a.v[1] + b.v[1], + a.v[2] + b.v[2], + a.v[3] + b.v[3]); +} + +mat4 operator-(const mat4 &a, const mat4 &b) +{ + return mat4( + a.v[0] - b.v[0], + a.v[1] - b.v[1], + a.v[2] - b.v[2], + a.v[3] - b.v[3]); +} + +mat4 operator*(const mat4 &a, const mat4 &b) +{ + #define ROWCOL(i, j) \ + a.v[i].n[0]*b.v[0][j] + \ + a.v[i].n[1]*b.v[1][j] + \ + a.v[i].n[2]*b.v[2][j] + \ + a.v[i].n[3]*b.v[3][j] + + return mat4( + vec4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)), + vec4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)), + vec4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)), + vec4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3)) + ); + + #undef ROWCOL +} + +mat4 operator*(const mat4 &a, float d) +{ + return mat4(a.v[0]*d, a.v[1]*d, a.v[2]*d, a.v[3]*d); +} + +mat4 operator*(float d, const mat4 &a) +{ + return a*d; +} + +mat4 operator/(const mat4 &a, float d) +{ + return mat4(a.v[0]/d, a.v[1]/d, a.v[2]/d, a.v[3]/d); +} + +int operator==(const mat4 &a, const mat4 &b) +{ + return + (a.v[0] == b.v[0]) && + (a.v[1] == b.v[1]) && + (a.v[2] == b.v[2]) && + (a.v[3] == b.v[3]); +} + +int operator!=(const mat4 &a, const mat4 &b) +{ + return !(a == b); +} + +/*ostream& operator << (ostream& s, mat4& m) +{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ] << '\n' << m.v[VW]; } + +istream& operator >> (istream& s, mat4& m) +{ + mat4 m_tmp; + + s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ] >> m_tmp[VW]; + if (s) + m = m_tmp; + return s; +} +*/ + +void swap(mat4 &a, mat4 &b) +{ + mat4 tmp(a); + a = b; + b = tmp; +} + +/**************************************************************** + * * + * 2D functions and 3D functions * + * * + ****************************************************************/ + +mat3 identity2D() +{ + return mat3( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0)); +} + +mat3 translation2D(const vec2 &v) +{ + return mat3( + vec3(1.0, 0.0, v[VX]), + vec3(0.0, 1.0, v[VY]), + vec3(0.0, 0.0, 1.0)); +} + +mat3 rotation2D(const vec2 &Center, float angleDeg) +{ + float angleRad = (float) (angleDeg * M_PI / 180.0); + float c = (float) cos(angleRad); + float s = (float) sin(angleRad); + + return mat3( + vec3(c, -s, Center[VX] * (1.0f-c) + Center[VY] * s), + vec3(s, c, Center[VY] * (1.0f-c) - Center[VX] * s), + vec3(0.0, 0.0, 1.0)); +} + +mat3 scaling2D(const vec2 &scaleVector) +{ + return mat3( + vec3(scaleVector[VX], 0.0, 0.0), + vec3(0.0, scaleVector[VY], 0.0), + vec3(0.0, 0.0, 1.0)); +} + +mat4 identity3D() +{ + return mat4( + vec4(1.0, 0.0, 0.0, 0.0), + vec4(0.0, 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(0.0, 0.0, 0.0, 1.0)); +} + +mat4 translation3D(const vec3 &v) +{ + return mat4( + vec4(1.0, 0.0, 0.0, v[VX]), + vec4(0.0, 1.0, 0.0, v[VY]), + vec4(0.0, 0.0, 1.0, v[VZ]), + vec4(0.0, 0.0, 0.0, 1.0)); +} + +mat4 rotation3D(const vec3 &Axis, float angleDeg) +{ + float angleRad = (float) (angleDeg * M_PI / 180.0); + float c = (float) cos(angleRad); + float s = (float) sin(angleRad); + float t = 1.0f - c; + + vec3 axis(Axis); + axis.normalize(); + + return mat4( + vec4(t * axis[VX] * axis[VX] + c, + t * axis[VX] * axis[VY] - s * axis[VZ], + t * axis[VX] * axis[VZ] + s * axis[VY], + 0.0), + vec4(t * axis[VX] * axis[VY] + s * axis[VZ], + t * axis[VY] * axis[VY] + c, + t * axis[VY] * axis[VZ] - s * axis[VX], + 0.0), + vec4(t * axis[VX] * axis[VZ] - s * axis[VY], + t * axis[VY] * axis[VZ] + s * axis[VX], + t * axis[VZ] * axis[VZ] + c, + 0.0), + vec4(0.0, 0.0, 0.0, 1.0)); +} + +mat4 rotation3Drad(const vec3 &Axis, float angleRad) +{ + float c = (float) cos(angleRad); + float s = (float) sin(angleRad); + float t = 1.0f - c; + + vec3 axis(Axis); + axis.normalize(); + + return mat4( + vec4(t * axis[VX] * axis[VX] + c, + t * axis[VX] * axis[VY] - s * axis[VZ], + t * axis[VX] * axis[VZ] + s * axis[VY], + 0.0), + vec4(t * axis[VX] * axis[VY] + s * axis[VZ], + t * axis[VY] * axis[VY] + c, + t * axis[VY] * axis[VZ] - s * axis[VX], + 0.0), + vec4(t * axis[VX] * axis[VZ] - s * axis[VY], + t * axis[VY] * axis[VZ] + s * axis[VX], + t * axis[VZ] * axis[VZ] + c, + 0.0), + vec4(0.0, 0.0, 0.0, 1.0)); +} + +mat4 scaling3D(const vec3 &scaleVector) +{ + return mat4( + vec4(scaleVector[VX], 0.0, 0.0, 0.0), + vec4(0.0, scaleVector[VY], 0.0, 0.0), + vec4(0.0, 0.0, scaleVector[VZ], 0.0), + vec4(0.0, 0.0, 0.0, 1.0)); +} + +mat4 perspective3D(float d) +{ + return mat4( + vec4(1.0f, 0.0f, 0.0f, 0.0f), + vec4(0.0f, 1.0f, 0.0f, 0.0f), + vec4(0.0f, 0.0f, 1.0f, 0.0f), + vec4(0.0f, 0.0f, 1.0f/d, 0.0f)); +} diff --git a/Extras/glui/algebra3.h b/Extras/glui/algebra3.h new file mode 100644 index 0000000..9875b3a --- /dev/null +++ b/Extras/glui/algebra3.h @@ -0,0 +1,475 @@ +/* + + algebra3.cpp, algebra3.h - C++ Vector and Matrix Algebra routines + + GLUI User Interface Toolkit (LGPL) + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/************************************************************************** + + There are three vector classes and two matrix classes: vec2, vec3, + vec4, mat3, and mat4. + + All the standard arithmetic operations are defined, with '*' + for dot product of two vectors and multiplication of two matrices, + and '^' for cross product of two vectors. + + Additional functions include length(), normalize(), homogenize for + vectors, and print(), set(), apply() for all classes. + + There is a function transpose() for matrices, but note that it + does not actually change the matrix, + + When multiplied with a matrix, a vector is treated as a row vector + if it precedes the matrix (v*M), and as a column vector if it + follows the matrix (M*v). + + Matrices are stored in row-major form. + + A vector of one dimension (2d, 3d, or 4d) can be cast to a vector + of a higher or lower dimension. If casting to a higher dimension, + the new component is set by default to 1.0, unless a value is + specified: + vec3 a(1.0, 2.0, 3.0 ); + vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0}; + When casting to a lower dimension, the vector is homogenized in + the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the + resulting vector is {X/W, Y/W, Z/W}. It is up to the user to + insure the fourth component is not zero before casting. + + There are also the following function for building matrices: + identity2D(), translation2D(), rotation2D(), + scaling2D(), identity3D(), translation3D(), + rotation3D(), rotation3Drad(), scaling3D(), + perspective3D() + + NOTE: When compiling for Windows, include this file first, to avoid + certain name conflicts + + --------------------------------------------------------------------- + + Author: Jean-Francois DOUEg + Revised: Paul Rademacher + Version 3.2 - Feb 1998 + Revised: Nigel Stewart (GLUI Code Cleaning) + +**************************************************************************/ + +#ifndef GLUI_ALGEBRA3_H +#define GLUI_ALGEBRA3_H + +#include +#include +#include + +// this line defines a new type: pointer to a function which returns a +// float and takes as argument a float +typedef float (*V_FCT_PTR)(float); + +class vec2; +class vec3; +class vec4; +class mat3; +class mat4; + +#ifndef M_PI +#define M_PI 3.141592654 +#endif + +enum {VX, VY, VZ, VW}; // axes +enum {PA, PB, PC, PD}; // planes +enum {RED, GREEN, BLUE, ALPHA}; // colors +enum {KA, KD, KS, ES}; // phong coefficients + +/**************************************************************** + * * + * 2D Vector * + * * + ****************************************************************/ + +class vec2 +{ + friend class vec3; + +protected: + + float n[2]; + +public: + + // Constructors + + vec2(); + vec2(float x, float y); + vec2(const vec2 &v); // copy constructor + vec2(const vec3 &v); // cast v3 to v2 + vec2(const vec3 &v, int dropAxis); // cast v3 to v2 + + // Assignment operators + + vec2 &operator = (const vec2 &v); // assignment of a vec2 + vec2 &operator += (const vec2 &v); // incrementation by a vec2 + vec2 &operator -= (const vec2 &v); // decrementation by a vec2 + vec2 &operator *= (float d); // multiplication by a constant + vec2 &operator /= (float d); // division by a constant + + // special functions + + float length() const; // length of a vec2 + float length2() const; // squared length of a vec2 + vec2 &normalize(); // normalize a vec2 + vec2 &apply(V_FCT_PTR fct); // apply a func. to each component + void set(float x, float y); // set vector + + float &operator [] (int i); // indexing + const float &operator [] (int i) const; // indexing + + // friends + + friend vec2 operator - (const vec2 &v); // -v1 + friend vec2 operator + (const vec2 &a, const vec2 &b); // v1 + v2 + friend vec2 operator - (const vec2 &a, const vec2 &b); // v1 - v2 + friend vec2 operator * (const vec2 &a, float d); // v1 * 3.0 + friend vec2 operator * (float d, const vec2 &a); // 3.0 * v1 + friend vec2 operator * (const mat3 &a, const vec2 &v); // M . v + friend vec2 operator * (const vec2 &v, const mat3 &a); // v . M + friend float operator * (const vec2 &a, const vec2 &b); // dot product + friend vec2 operator / (const vec2 &a, float d); // v1 / 3.0 + friend vec3 operator ^ (const vec2 &a, const vec2 &b); // cross product + friend int operator == (const vec2 &a, const vec2 &b); // v1 == v2 ? + friend int operator != (const vec2 &a, const vec2 &b); // v1 != v2 ? + //friend ostream& operator << (ostream& s, vec2& v); // output to stream + //friend istream& operator >> (istream& s, vec2& v); // input from strm. + friend void swap(vec2 &a, vec2 &b); // swap v1 & v2 + friend vec2 min_vec(const vec2 &a, const vec2 &b); // min(v1, v2) + friend vec2 max_vec(const vec2 &a, const vec2 &b); // max(v1, v2) + friend vec2 prod (const vec2 &a, const vec2 &b); // term by term * +}; + +/**************************************************************** + * * + * 3D Vector * + * * + ****************************************************************/ + +class vec3 +{ + friend class vec2; + friend class vec4; + friend class mat3; + +protected: + + float n[3]; + +public: + + // Constructors + + vec3(); + vec3(float x, float y, float z); + vec3(const vec3 &v); // copy constructor + vec3(const vec2 &v); // cast v2 to v3 + vec3(const vec2 &v, float d); // cast v2 to v3 + vec3(const vec4 &v); // cast v4 to v3 + vec3(const vec4 &v, int dropAxis); // cast v4 to v3 + + // Assignment operators + + vec3 &operator = (const vec3 &v); // assignment of a vec3 + vec3 &operator += (const vec3 &v); // incrementation by a vec3 + vec3 &operator -= (const vec3 &v); // decrementation by a vec3 + vec3 &operator *= (float d); // multiplication by a constant + vec3 &operator /= (float d); // division by a constant + + // special functions + + float length() const; // length of a vec3 + float length2() const; // squared length of a vec3 + vec3& normalize(); // normalize a vec3 + vec3& homogenize(); // homogenize (div by Z) + vec3& apply(V_FCT_PTR fct); // apply a func. to each component + void set(float x, float y, float z); // set vector + + void print(FILE *file, const char *name) const; // print vector to a file + + + float &operator [] (int i); // indexing + const float &operator [] (int i) const; // indexing + + // friends + + friend vec3 operator - (const vec3 &v); // -v1 + friend vec3 operator + (const vec3 &a, const vec3 &b); // v1 + v2 + friend vec3 operator - (const vec3 &a, const vec3 &b); // v1 - v2 + friend vec3 operator * (const vec3 &a, float d); // v1 * 3.0 + friend vec3 operator * (float d, const vec3 &a); // 3.0 * v1 + friend vec3 operator * (const mat4 &a, const vec3 &v); // M . v + friend vec3 operator * (const vec3 &v, const mat4 &a); // v . M + friend float operator * (const vec3 &a, const vec3 &b); // dot product + friend vec3 operator / (const vec3 &a, float d); // v1 / 3.0 + friend vec3 operator ^ (const vec3 &a, const vec3 &b); // cross product + friend int operator == (const vec3 &a, const vec3 &b); // v1 == v2 ? + friend int operator != (const vec3 &a, const vec3 &b); // v1 != v2 ? + //friend ostream& operator << (ostream& s, vec3& v); // output to stream + //friend istream& operator >> (istream& s, vec3& v); // input from strm. + friend void swap(vec3 &a, vec3 &b); // swap v1 & v2 + friend vec3 min_vec(const vec3 &a, const vec3 &b); // min(v1, v2) + friend vec3 max_vec(const vec3 &a, const vec3 &b); // max(v1, v2) + friend vec3 prod(const vec3 &a, const vec3 &b); // term by term * + + // necessary friend declarations + + friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform + friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform + friend mat3 operator * (const mat3 &a, const mat3 &b); // matrix 3 product +}; + +/**************************************************************** + * * + * 4D Vector * + * * + ****************************************************************/ + +class vec4 +{ + friend class vec3; + friend class mat4; + +protected: + + float n[4]; + +public: + + // Constructors + + vec4(); + vec4(float x, float y, float z, float w); + vec4(const vec4 &v); // copy constructor + vec4(const vec3 &v); // cast vec3 to vec4 + vec4(const vec3 &v, float d); // cast vec3 to vec4 + + // Assignment operators + + vec4 &operator = (const vec4 &v); // assignment of a vec4 + vec4 &operator += (const vec4 &v); // incrementation by a vec4 + vec4 &operator -= (const vec4 &v); // decrementation by a vec4 + vec4 &operator *= (float d); // multiplication by a constant + vec4 &operator /= (float d); // division by a constant + + // special functions + + float length() const; // length of a vec4 + float length2() const; // squared length of a vec4 + vec4 &normalize(); // normalize a vec4 + vec4 &apply(V_FCT_PTR fct); // apply a func. to each component + vec4 &homogenize(); + + void print(FILE *file, const char *name) const; // print vector to a file + + void set(float x, float y, float z, float a); + + float &operator [] (int i); // indexing + const float &operator [] (int i) const; // indexing + + // friends + + friend vec4 operator - (const vec4 &v); // -v1 + friend vec4 operator + (const vec4 &a, const vec4 &b); // v1 + v2 + friend vec4 operator - (const vec4 &a, const vec4 &b); // v1 - v2 + friend vec4 operator * (const vec4 &a, float d); // v1 * 3.0 + friend vec4 operator * (float d, const vec4 &a); // 3.0 * v1 + friend vec4 operator * (const mat4 &a, const vec4 &v); // M . v + friend vec4 operator * (const vec4 &v, const mat4 &a); // v . M + friend float operator * (const vec4 &a, const vec4 &b); // dot product + friend vec4 operator / (const vec4 &a, float d); // v1 / 3.0 + friend int operator == (const vec4 &a, const vec4 &b); // v1 == v2 ? + friend int operator != (const vec4 &a, const vec4 &b); // v1 != v2 ? + //friend ostream& operator << (ostream& s, vec4& v); // output to stream + //friend istream& operator >> (istream& s, vec4& v); // input from strm. + friend void swap(vec4 &a, vec4 &b); // swap v1 & v2 + friend vec4 min_vec(const vec4 &a, const vec4 &b); // min(v1, v2) + friend vec4 max_vec(const vec4 &a, const vec4 &b); // max(v1, v2) + friend vec4 prod (const vec4 &a, const vec4 &b); // term by term * + + // necessary friend declarations + + friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform + friend mat4 operator * (const mat4 &a, const mat4 &b); // matrix 4 product +}; + +/**************************************************************** + * * + * 3x3 Matrix * + * * + ****************************************************************/ + +class mat3 +{ +protected: + + vec3 v[3]; + +public: + + // Constructors + + mat3(); + mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2); + mat3(const mat3 &m); + + // Assignment operators + + mat3 &operator = (const mat3 &m); // assignment of a mat3 + mat3 &operator += (const mat3 &m); // incrementation by a mat3 + mat3 &operator -= (const mat3 &m); // decrementation by a mat3 + mat3 &operator *= (float d); // multiplication by a constant + mat3 &operator /= (float d); // division by a constant + + // special functions + + mat3 transpose() const; // transpose + mat3 inverse() const; // inverse + mat3 &apply(V_FCT_PTR fct); // apply a func. to each element + + void print(FILE *file, const char *name ) const; // print matrix to a file + + void set(const vec3 &v0, const vec3 &v1, const vec3 &v2); + + vec3 &operator [] (int i); // indexing + const vec3 &operator [] (int i) const; // indexing + + // friends + + friend mat3 operator - (const mat3 &a); // -m1 + friend mat3 operator + (const mat3 &a, const mat3 &b); // m1 + m2 + friend mat3 operator - (const mat3 &a, const mat3 &b); // m1 - m2 + friend mat3 operator * (const mat3 &a, const mat3 &b); // m1 * m2 + friend mat3 operator * (const mat3 &a, float d); // m1 * 3.0 + friend mat3 operator * (float d, const mat3 &a); // 3.0 * m1 + friend mat3 operator / (const mat3 &a, float d); // m1 / 3.0 + friend int operator == (const mat3 &a, const mat3 &b); // m1 == m2 ? + friend int operator != (const mat3 &a, const mat3 &b); // m1 != m2 ? + //friend ostream& operator << (ostream& s, mat3& m); // output to stream + //friend istream& operator >> (istream& s, mat3& m); // input from strm. + friend void swap(mat3 &a, mat3 &b); // swap m1 & m2 + + // necessary friend declarations + + friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform + friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform +}; + +/**************************************************************** + * * + * 4x4 Matrix * + * * + ****************************************************************/ + +class mat4 +{ +protected: + + vec4 v[4]; + +public: + + // Constructors + + mat4(); + mat4(const vec4 &v0, const vec4 &v1, const vec4 &v2, const vec4 &v3); + mat4(const mat4 &m); + mat4(float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33 ); + + + // Assignment operators + + mat4 &operator = (const mat4 &m); // assignment of a mat4 + mat4 &operator += (const mat4 &m); // incrementation by a mat4 + mat4 &operator -= (const mat4 &m); // decrementation by a mat4 + mat4 &operator *= (float d); // multiplication by a constant + mat4 &operator /= (float d); // division by a constant + + // special functions + + mat4 transpose() const; // transpose + mat4 inverse() const; // inverse + mat4 &apply(V_FCT_PTR fct); // apply a func. to each element + + void print(FILE *file, const char *name) const; // print matrix to a file + + vec4 &operator [] (int i); // indexing + const vec4 &operator [] (int i) const; // indexing + + void swap_rows(int i, int j); // swap rows i and j + void swap_cols(int i, int j); // swap cols i and j + + // friends + + friend mat4 operator - (const mat4 &a); // -m1 + friend mat4 operator + (const mat4 &a, const mat4 &b); // m1 + m2 + friend mat4 operator - (const mat4 &a, const mat4 &b); // m1 - m2 + friend mat4 operator * (const mat4 &a, const mat4 &b); // m1 * m2 + friend mat4 operator * (const mat4 &a, float d); // m1 * 4.0 + friend mat4 operator * (float d, const mat4 &a); // 4.0 * m1 + friend mat4 operator / (const mat4 &a, float d); // m1 / 3.0 + friend int operator == (const mat4 &a, const mat4 &b); // m1 == m2 ? + friend int operator != (const mat4 &a, const mat4 &b); // m1 != m2 ? + //friend ostream& operator << (ostream& s, mat4& m); // output to stream + //friend istream& operator >> (istream& s, mat4& m); // input from strm. + friend void swap(mat4 &a, mat4 &b); // swap m1 & m2 + + // necessary friend declarations + + friend vec4 operator * (const mat4 &a, const vec4 &v); // linear transform + //friend vec4 operator * (const vec4& v, const mat4& a); // linear transform + friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform + friend vec3 operator * (const vec3 &v, const mat4 &a); // linear transform +}; + +/**************************************************************** + * * + * 2D functions and 3D functions * + * * + ****************************************************************/ + +mat3 identity2D (); // identity 2D +mat3 translation2D(const vec2 &v); // translation 2D +mat3 rotation2D (const vec2 &Center, float angleDeg); // rotation 2D +mat3 scaling2D (const vec2 &scaleVector); // scaling 2D +mat4 identity3D (); // identity 3D +mat4 translation3D(const vec3 &v); // translation 3D +mat4 rotation3D (const vec3 &Axis, float angleDeg); // rotation 3D +mat4 rotation3Drad(const vec3 &Axis, float angleRad); // rotation 3D +mat4 scaling3D (const vec3 &scaleVector); // scaling 3D +mat4 perspective3D(float d); // perspective 3D + +vec3 operator * (const vec3 &v, const mat3 &a); +vec2 operator * (const vec2 &v, const mat3 &a); +vec3 operator * (const vec3 &v, const mat4 &a); +vec4 operator * (const vec4 &v, const mat4 &a); + +#endif diff --git a/Extras/glui/arcball.cpp b/Extras/glui/arcball.cpp new file mode 100644 index 0000000..63c983e --- /dev/null +++ b/Extras/glui/arcball.cpp @@ -0,0 +1,237 @@ +/********************************************************************** + + arcball.cpp + + + -------------------------------------------------- + + GLUI User Interface Toolkit (LGPL) + Copyright (c) 1998 Paul Rademacher + Feb 1998, Paul Rademacher (rademach@cs.unc.edu) + Oct 2003, Nigel Stewart - GLUI Code Cleaning + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +**********************************************************************/ + +#include "arcball.h" + +#include + + +/**************************************** Arcball::Arcball() ****/ +/* Default (void) constructor for Arcball */ + +Arcball::Arcball() +{ + rot_ptr = &rot; + init(); +} + +/**************************************** Arcball::Arcball() ****/ +/* Takes as argument a mat4 to use instead of the internal rot */ + +Arcball::Arcball(mat4 *mtx) +{ + rot_ptr = mtx; +} + + +/**************************************** Arcball::Arcball() ****/ +/* A constructor that accepts the screen center and arcball radius*/ + +Arcball::Arcball(const vec2 &_center, float _radius) +{ + rot_ptr = &rot; + init(); + set_params(_center, _radius); +} + + +/************************************** Arcball::set_params() ****/ + +void Arcball::set_params(const vec2 &_center, float _radius) +{ + center = _center; + radius = _radius; +} + +/*************************************** Arcball::init() **********/ + +void Arcball::init() +{ + center.set( 0.0, 0.0 ); + radius = 1.0; + q_now = quat_identity(); + *rot_ptr = identity3D(); + q_increment = quat_identity(); + rot_increment = identity3D(); + is_mouse_down = false; + is_spinning = false; + damp_factor = 0.0; + zero_increment = true; +} + +/*********************************** Arcball::mouse_to_sphere() ****/ + +vec3 Arcball::mouse_to_sphere(const vec2 &p) +{ + float mag; + vec2 v2 = (p - center) / radius; + vec3 v3( v2[0], v2[1], 0.0 ); + + mag = v2*v2; + + if ( mag > 1.0 ) + v3.normalize(); + else + v3[VZ] = (float) sqrt( 1.0 - mag ); + + /* Now we add constraints - X takes precedence over Y */ + if ( constraint_x ) + { + v3 = constrain_vector( v3, vec3( 1.0, 0.0, 0.0 )); + } + else if ( constraint_y ) + { + v3 = constrain_vector( v3, vec3( 0.0, 1.0, 0.0 )); + } + + return v3; +} + + +/************************************ Arcball::constrain_vector() ****/ + +vec3 Arcball::constrain_vector(const vec3 &vector, const vec3 &axis) +{ + return (vector-(vector*axis)*axis).normalize(); +} + +/************************************ Arcball::mouse_down() **********/ + +void Arcball::mouse_down(int x, int y) +{ + down_pt.set( (float)x, (float) y ); + is_mouse_down = true; + + q_increment = quat_identity(); + rot_increment = identity3D(); + zero_increment = true; +} + + +/************************************ Arcball::mouse_up() **********/ + +void Arcball::mouse_up() +{ + q_now = q_drag * q_now; + is_mouse_down = false; +} + + +/********************************** Arcball::mouse_motion() **********/ + +void Arcball::mouse_motion(int x, int y, int shift, int ctrl, int alt) +{ + /* Set the X constraint if CONTROL key is pressed, Y if ALT key */ + set_constraints( ctrl != 0, alt != 0 ); + + vec2 new_pt( (float)x, (float) y ); + vec3 v0 = mouse_to_sphere( down_pt ); + vec3 v1 = mouse_to_sphere( new_pt ); + + vec3 cross = v0^v1; + + q_drag.set( cross, v0 * v1 ); + + // *rot_ptr = (q_drag * q_now).to_mat4(); + mat4 temp = q_drag.to_mat4(); + *rot_ptr = *rot_ptr * temp; + + down_pt = new_pt; + + /* We keep a copy of the current incremental rotation (= q_drag) */ + q_increment = q_drag; + rot_increment = q_increment.to_mat4(); + + set_constraints(false, false); + + if ( q_increment.s < .999999 ) + { + is_spinning = true; + zero_increment = false; + } + else + { + is_spinning = false; + zero_increment = true; + } +} + + +/********************************** Arcball::mouse_motion() **********/ + +void Arcball::mouse_motion(int x, int y) +{ + mouse_motion(x, y, 0, 0, 0); +} + + +/***************************** Arcball::set_constraints() **********/ + +void Arcball::set_constraints(bool _constraint_x, bool _constraint_y) +{ + constraint_x = _constraint_x; + constraint_y = _constraint_y; +} + +/***************************** Arcball::idle() *********************/ + +void Arcball::idle() +{ + if (is_mouse_down) + { + is_spinning = false; + zero_increment = true; + } + + if (damp_factor < 1.0f) + q_increment.scale_angle(1.0f - damp_factor); + + rot_increment = q_increment.to_mat4(); + + if (q_increment.s >= .999999f) + { + is_spinning = false; + zero_increment = true; + } +} + + +/************************ Arcball::set_damping() *********************/ + +void Arcball::set_damping(float d) +{ + damp_factor = d; +} + + + + + diff --git a/Extras/glui/arcball.h b/Extras/glui/arcball.h new file mode 100644 index 0000000..18edd05 --- /dev/null +++ b/Extras/glui/arcball.h @@ -0,0 +1,97 @@ +/********************************************************************** + + arcball.h + + GLUI User Interface Toolkit (LGPL) + Copyright (c) 1998 Paul Rademacher + Feb 1998, Paul Rademacher (rademach@cs.unc.edu) + Oct 2003, Nigel Stewart - GLUI Code Cleaning + + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + --------------------------------------------------------------------- + + A C++ class that implements the Arcball, as described by Ken + Shoemake in Graphics Gems IV. + This class takes as input mouse events (mouse down, mouse drag, + mouse up), and creates the appropriate quaternions and 4x4 matrices + to represent the rotation given by the mouse. + + This class is used as follows: + - initialize [either in the constructor or with set_params()], the + center position (x,y) of the arcball on the screen, and the radius + - on mouse down, call mouse_down(x,y) with the mouse position + - as the mouse is dragged, repeatedly call mouse_motion() with the + current x and y positions. One can optionally pass in the current + state of the SHIFT, ALT, and CONTROL keys (passing zero if keys + are not pressed, non-zero otherwise), which constrains + the rotation to certain axes (X for CONTROL, Y for ALT). + - when the mouse button is released, call mouse_up() + + Axis constraints can also be explicitly set with the + set_constraints() function. + + The current rotation is stored in the 4x4 float matrix 'rot'. + It is also stored in the quaternion 'q_now'. + +**********************************************************************/ + +#ifndef GLUI_ARCBALL_H +#define GLUI_ARCBALL_H + +#include "glui_internal.h" +#include "algebra3.h" +#include "quaternion.h" + +class Arcball +{ +public: + Arcball(); + Arcball(mat4 *mtx); + Arcball(const vec2 ¢er, float radius); + + void set_damping(float d); + void idle(); + void mouse_down(int x, int y); + void mouse_up(); + void mouse_motion(int x, int y, int shift, int ctrl, int alt); + void mouse_motion(int x, int y); + void set_constraints(bool constrain_x, bool constrain_y); + void set_params(const vec2 ¢er, float radius); + void reset_mouse(); + void init(); + + vec3 constrain_vector(const vec3 &vector, const vec3 &axis); + vec3 mouse_to_sphere(const vec2 &p); + + //public: + int is_mouse_down; /* true for down, false for up */ + int is_spinning; + quat q_now, q_down, q_drag, q_increment; + vec2 down_pt; + mat4 rot, rot_increment; + mat4 *rot_ptr; + + bool constraint_x, constraint_y; + vec2 center; + float radius, damp_factor; + int zero_increment; +}; + +#endif diff --git a/Extras/glui/glui.cpp b/Extras/glui/glui.cpp new file mode 100644 index 0000000..239b12f --- /dev/null +++ b/Extras/glui/glui.cpp @@ -0,0 +1,2171 @@ +/**************************************************************************** + + GLUI User Interface Toolkit (LGPL) + --------------------------- + + glui.cpp + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ +#include "glui_internal_control.h" + + +/** + Note: moving this routine here from glui_add_controls.cpp prevents the linker + from touching glui_add_controls.o in non-deprecated programs, which + descreases the linked size of small GLUI programs substantially (100K+). (OSL 2006/06) +*/ +void GLUI_Node::add_child_to_control(GLUI_Node *parent,GLUI_Control *child) +{ + GLUI_Control *parent_control; + + /*** Collapsible nodes have to be handled differently, b/c the first and + last children are swapped in and out ***/ + parent_control = ((GLUI_Control*)parent); + if ( parent_control->collapsible == true ) { + if ( NOT parent_control->is_open ) { + /** Swap in the original first and last children **/ + parent_control->child_head = parent_control->collapsed_node.child_head; + parent_control->child_tail = parent_control->collapsed_node.child_tail; + + /*** Link this control ***/ + child->link_this_to_parent_last( parent_control ); + + /** Swap the children back out ***/ + parent_control->collapsed_node.child_head = parent_control->child_head; + parent_control->collapsed_node.child_tail = parent_control->child_tail; + parent_control->child_head = NULL; + parent_control->child_tail = NULL; + } + else { + child->link_this_to_parent_last( parent_control ); + } + } + else { + child->link_this_to_parent_last( parent_control ); + } + child->glui = (GLUI*) parent_control->glui; + child->update_size(); + child->enabled = parent_control->enabled; + child->glui->refresh(); + + /** Now set the 'hidden' var based on the parent **/ + if ( parent_control->hidden OR + (parent_control->collapsible AND NOT parent_control->is_open ) ) + { + child->hidden = true; + } +} + + +/************************************ GLUI_Node::add_control() **************/ + +int GLUI_Node::add_control( GLUI_Control *child ) +{ + add_child_to_control(this,child); + return true; +} + +/************************************ GLUI_Main::add_control() **************/ + +int GLUI_Main::add_control( GLUI_Node *parent, GLUI_Control *control ) +{ + add_child_to_control(parent,control); + return true; +} + + + +/*** This object must be used to create a GLUI ***/ + +GLUI_Master_Object GLUI_Master; + +/************************************ finish_drawing() *********** + Probably a silly routine. Called after all event handling callbacks. +*/ + +static void finish_drawing(void) +{ + glFinish(); +} + +/************************************ GLUI_CB::operator()() ************/ +void GLUI_CB::operator()(GLUI_Control*ctrl) const +{ + if (idCB) idCB(ctrl->user_id); + if (objCB) objCB(ctrl); +} + + +/************************************************ GLUI::GLUI() **********/ + +int GLUI::init( const char *text, long flags, int x, int y, int parent_window ) +{ + int old_glut_window; + + this->flags = flags; + + window_name = text; + + buffer_mode = buffer_back; ///< New smooth way + //buffer_mode = buffer_front; ///< Old flickery way (a bit faster). + + /*** We copy over the current window callthroughs ***/ + /*** (I think this might actually only be needed for subwindows) ***/ + /* glut_keyboard_CB = GLUI_Master.glut_keyboard_CB; + glut_reshape_CB = GLUI_Master.glut_reshape_CB; + glut_special_CB = GLUI_Master.glut_special_CB; + glut_mouse_CB = GLUI_Master.glut_mouse_CB;*/ + + + if ( (flags & GLUI_SUBWINDOW) != GLUI_SUBWINDOW ) { /* not a subwindow, creating a new top-level window */ + old_glut_window = glutGetWindow(); + + create_standalone_window( window_name.c_str(), x, y ); + setup_default_glut_callbacks(); + + if ( old_glut_window > 0 ) + glutSetWindow( old_glut_window ); + + top_level_glut_window_id = glut_window_id; + } + else /* *is* a subwindow */ + { + old_glut_window = glutGetWindow(); + + create_subwindow( parent_window, flags ); + setup_default_glut_callbacks(); + + if ( old_glut_window > 0 ) + glutSetWindow( old_glut_window ); + + top_level_glut_window_id = parent_window; + + /* + glutReshapeFunc( glui_parent_window_reshape_func ); + glutSpecialFunc( glui_parent_window_special_func ); + glutKeyboardFunc( glui_parent_window_keyboard_func ); + glutMouseFunc( glui_parent_window_mouse_func ); + */ + + } + + return true; +} + + +/**************************** GLUI_Main::create_standalone_window() ********/ + +void GLUI_Main::create_standalone_window( const char *name, int x, int y ) +{ + glutInitWindowSize( 100, 100 ); + if ( x >= 0 OR y >= 0 ) + glutInitWindowPosition( x, y ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glut_window_id = glutCreateWindow( name ); +} + + +/******************************** GLUI_Main::create_subwindow() **********/ + +void GLUI_Main::create_subwindow( int parent_window, int window_alignment ) +{ + glut_window_id = glutCreateSubWindow(parent_window, 0,0, 100, 100); + this->parent_window = parent_window; +} + + +/**************************** GLUI_Main::setup_default_glut_callbacks() *****/ + +void GLUI_Main::setup_default_glut_callbacks( void ) +{ + glutDisplayFunc( glui_display_func ); + glutReshapeFunc( glui_reshape_func ); + glutKeyboardFunc( glui_keyboard_func ); + glutSpecialFunc( glui_special_func ); + glutMouseFunc( glui_mouse_func ); + glutMotionFunc( glui_motion_func ); + glutPassiveMotionFunc( glui_passive_motion_func ); + glutEntryFunc( glui_entry_func ); + glutVisibilityFunc( glui_visibility_func ); + /* glutIdleFunc( glui_idle_func ); // FIXME! 100% CPU usage! */ +} + + +/********************************************** glui_display_func() ********/ + +void glui_display_func(void) +{ + GLUI *glui; + + /* printf( "display func\n" ); */ + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->display(); + /* + Do not do anything after the above line, b/c the GLUI + window might have just closed itself + */ + } +} + + +/********************************************** glui_reshape_func() ********/ + +void glui_reshape_func(int w,int h ) +{ + GLUI *glui; + GLUI_Glut_Window *glut_window; + int current_window; + + /*printf( "glui_reshape_func(): %d w/h: %d/%d\n", glutGetWindow(), w, h ); */ + + current_window = glutGetWindow(); + + /*** First check if this is main glut window ***/ + glut_window = GLUI_Master.find_glut_window( current_window ); + if ( glut_window ) { + if (glut_window->glut_reshape_CB) glut_window->glut_reshape_CB(w,h); + + /*** Now send reshape events to all subwindows ***/ + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while(glui) { + if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND + glui->parent_window == current_window ) { + glutSetWindow( glui->get_glut_window_id()); + glui->reshape(w,h); + /* glui->check_subwindow_position(); */ + } + glui = (GLUI*) glui->next(); + } + } + else { + /*** A standalone GLUI window ***/ + + glui = GLUI_Master.find_glui_by_window_id( current_window ); + + if ( glui ) { + glui->reshape(w,h); + } + } +} + +/********************************************** glui_keyboard_func() ********/ + +void glui_keyboard_func(unsigned char key, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + /*printf( "key: %d\n", current_window ); */ + + if ( glut_window ) { /** Was event in a GLUT window? **/ + if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) { + glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() ); + + GLUI_Master.active_control_glui->keyboard(key,x,y); + finish_drawing(); + + glutSetWindow( current_window ); + } + else { + if (glut_window->glut_keyboard_CB) + glut_window->glut_keyboard_CB( key, x, y ); + } + } + else { /*** Nope, event was in a standalone GLUI window **/ + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->keyboard(key,x,y); + finish_drawing(); + } + } +} + + + + +void glui_special_up_func(int key, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + if (glut_window) /** Was event in a GLUT window? **/ + { + if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) + { + glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() ); + + GLUI_Master.active_control_glui->special_up(key,x,y); + finish_drawing(); + + glutSetWindow( current_window ); + } + else + { + if (glut_window->glut_special_up_CB) + glut_window->glut_special_up_CB( key, x, y ); + } + } + else /*** Nope, event was in a standalone GLUI window **/ + { + glui = GLUI_Master.find_glui_by_window_id(glutGetWindow()); + + if ( glui ) + { + glui->special_up(key,x,y); + finish_drawing(); + } + } +} + + + +/************************************************ glui_special_func() ********/ + +void glui_special_func(int key, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + if (glut_window) /** Was event in a GLUT window? **/ + { + if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) + { + glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() ); + + GLUI_Master.active_control_glui->special(key,x,y); + finish_drawing(); + + glutSetWindow( current_window ); + } + else + { + if (glut_window->glut_special_CB) + glut_window->glut_special_CB( key, x, y ); + } + } + else /*** Nope, event was in a standalone GLUI window **/ + { + glui = GLUI_Master.find_glui_by_window_id(glutGetWindow()); + + if ( glui ) + { + glui->special(key,x,y); + finish_drawing(); + } + } +} + +/********************************************** glui_mouse_func() ********/ + +void glui_mouse_func(int button, int state, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + if ( glut_window ) { /** Was event in a GLUT window? **/ + if ( GLUI_Master.active_control_glui != NULL ) + GLUI_Master.active_control_glui->deactivate_current_control(); + + if (glut_window->glut_mouse_CB) + glut_window->glut_mouse_CB( button, state, x, y ); + finish_drawing(); + } + else { /** Nope - event was in a GLUI standalone window **/ + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + if ( glui ) { + glui->passive_motion( 0,0 ); + glui->mouse( button, state, x, y ); + finish_drawing(); + } + } +} + + +/********************************************** glui_motion_func() ********/ + +void glui_motion_func(int x, int y) +{ + GLUI *glui; + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->motion(x,y); + finish_drawing(); + } + +} + + +/**************************************** glui_passive_motion_func() ********/ + +void glui_passive_motion_func(int x, int y) +{ + GLUI *glui; + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->passive_motion(x,y); + finish_drawing(); + } +} + + +/********************************************** glui_entry_func() ********/ + +void glui_entry_func(int state) +{ + GLUI *glui; + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->entry(state); + } +} + + +/******************************************** glui_visibility_func() ********/ + +void glui_visibility_func(int state) +{ + GLUI *glui; + + /* printf( "IN GLUI VISIBILITY()\n" ); */ + /* fflush( stdout ); */ + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->visibility(state); + } +} + + +/********************************************** glui_idle_func() ********/ +/* Send idle event to each glui, then to the main window */ + +void glui_idle_func(void) +{ + GLUI *glui; + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + glui->idle(); + finish_drawing(); + + glui = (GLUI*) glui->next(); + } + + if ( GLUI_Master.glut_idle_CB ) { + /*** We set the current glut window before calling the user's + idle function, even though glut explicitly says the window id is + undefined in an idle callback. ***/ + + /** Check what the current window is first ***/ + + /*** Arbitrarily set the window id to the main gfx window of the + first glui window ***/ + /* int current_window, new_window; */ + /* current_window = glutGetWindow(); */ + /* if (GLUI_Master.gluis.first_child() != NULL ) { */ + /* new_window = ((GLUI_Main*)GLUI_Master.gluis.first_child())-> */ + /* main_gfx_window_id; */ + /* if ( new_window > 0 AND new_window != old_window ) { */ + /* --- Window is changed only if its not already the current window ---*/ + /* glutSetWindow( new_window ); */ + /* } */ + /*} */ + + GLUI_Master.glut_idle_CB(); + } +} + +/*********************************** GLUI_Master_Object::GLUI_Master_Object() ******/ + +GLUI_Master_Object::GLUI_Master_Object() +: glui_id_counter(1), + glut_idle_CB(NULL) +{ +} + +GLUI_Master_Object::~GLUI_Master_Object() +{ +} + +/*********************************** GLUI_Master_Object::create_glui() ******/ + +GLUI *GLUI_Master_Object::create_glui( const char *name, long flags,int x,int y ) +{ + GLUI *new_glui = new GLUI; + new_glui->init( name, flags, x, y, -1 ); + new_glui->link_this_to_parent_last( &this->gluis ); + return new_glui; +} + + +/************************** GLUI_Master_Object::create_glui_subwindow() ******/ + +GLUI *GLUI_Master_Object::create_glui_subwindow( int parent_window, + long flags ) +{ + GLUI *new_glui = new GLUI; + GLUI_String new_name; + glui_format_str( new_name, "subwin_%p", this ); + + new_glui->init( new_name.c_str(), flags | GLUI_SUBWINDOW, 0,0, + parent_window ); + new_glui->main_panel->set_int_val( GLUI_PANEL_EMBOSSED ); + new_glui->link_this_to_parent_last( &this->gluis ); + return new_glui; +} + + +/********************** GLUI_Master_Object::find_glui_by_window_id() ********/ + +GLUI *GLUI_Master_Object::find_glui_by_window_id( int window_id ) +{ + GLUI_Node *node; + + node = gluis.first_child(); + while( node ) { + if ( ((GLUI*)node)->get_glut_window_id() == window_id ) + return (GLUI*) node; + + node = node->next(); + } + return NULL; +} + + +/******************************************** GLUI_Main::display() **********/ + +void GLUI_Main::display( void ) +{ + int win_w, win_h; + + /* SUBTLE: on freeGLUT, the correct window is always already set. + But older versions of GLUT need this call, or else subwindows + don't update properly when resizing or damage-painting. + */ + glutSetWindow( glut_window_id ); + + /* Set up OpenGL state for widget drawing */ + glDisable( GL_DEPTH_TEST ); + glCullFace( GL_BACK ); + glDisable( GL_CULL_FACE ); + glDisable( GL_LIGHTING ); + set_current_draw_buffer(); + + /**** This function is used as a special place to do 'safe' processing, + e.g., handling window close requests. + That is, we can't close the window directly in the callback, so + we set a flag, post a redisplay message (which eventually calls + this function), then close the window safely in here. ****/ + if ( closing ) { + close_internal(); + return; + } + + /* if ( TEST_AND( this->flags, GLUI_SUBWINDOW )) + check_subwindow_position(); + */ + + win_w = glutGet( GLUT_WINDOW_WIDTH ); + win_h = glutGet( GLUT_WINDOW_HEIGHT ); + + /*** Check here if the window needs resizing ***/ + if ( win_w != main_panel->w OR win_h != main_panel->h ) { + glutReshapeWindow( main_panel->w, main_panel->h ); + return; + } + + /******* Draw GLUI window ******/ + glClearColor( (float) bkgd_color.r / 255.0, + (float) bkgd_color.g / 255.0, + (float) bkgd_color.b / 255.0, + 1.0 ); + glClear( GL_COLOR_BUFFER_BIT ); /* | GL_DEPTH_BUFFER_BIT ); */ + + set_ortho_projection(); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + /*** Rotate image so y increases downward. + In normal OpenGL, y increases upward. ***/ + glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 ); + glRotatef( 180.0, 0.0, 1.0, 0.0 ); + glRotatef( 180.0, 0.0, 0.0, 1.0 ); + glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 ); + + // Recursively draw the main panel + // main_panel->draw_bkgd_box( 0, 0, win_w, win_h ); + main_panel->draw_recursive( 0, 0 ); + + switch (buffer_mode) { + case buffer_front: /* Make sure drawing gets to screen */ + glFlush(); + break; + case buffer_back: /* Bring back buffer to front */ + glutSwapBuffers(); + break; + } +} + + + + +/*************************************** _glutBitmapWidthString() **********/ + +int _glutBitmapWidthString( void *font, const char *s ) +{ + const char *p = s; + int width = 0; + + while( *p != '\0' ) { + width += glutBitmapWidth( font, *p ); + p++; + } + + return width; +} + +/************************************ _glutBitmapString *********************/ +/* Displays the contents of a string using GLUT's bitmap character function */ +/* Does not handle newlines */ + +void _glutBitmapString( void *font, const char *s ) +{ + const char *p = s; + + while( *p != '\0' ) { + glutBitmapCharacter( font, *p ); + p++; + } +} + + + +/****************************** GLUI_Main::reshape() **************/ + +void GLUI_Main::reshape( int reshape_w, int reshape_h ) +{ + int new_w, new_h; + + pack_controls(); + + new_w = main_panel->w;/* + 1; */ + new_h = main_panel->h;/* + 1; */ + + if ( reshape_w != new_w OR reshape_h != new_h ) { + this->w = new_w; + this->h = new_h; + + glutReshapeWindow( new_w, new_h ); + } + else { + } + + if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) { + check_subwindow_position(); + + /***** if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) { + } + ****/ + } + + glViewport( 0, 0, new_w, new_h ); + + /* printf( "%d: %d\n", glutGetWindow(), this->flags ); */ + + glutPostRedisplay(); +} + + +/****************************** GLUI_Main::keyboard() **************/ + +void GLUI_Main::keyboard(unsigned char key, int x, int y) +{ + GLUI_Control *new_control; + + curr_modifiers = glutGetModifiers(); + + /*** If it's a tab or shift tab, we don't pass it on to the controls. + Instead, we use it to cycle through active controls ***/ + if ( key == '\t' AND !mouse_button_down AND + (!active_control || !active_control->wants_tabs())) { + if ( curr_modifiers & GLUT_ACTIVE_SHIFT ) { + new_control = find_prev_control( active_control ); + } + else { + new_control = find_next_control( active_control ); + } + + /* if ( new_control ) + printf( "new_control: %s\n", new_control->name ); + */ + + deactivate_current_control(); + activate_control( new_control, GLUI_ACTIVATE_TAB ); + } + else if ( key == ' ' AND active_control + AND active_control->spacebar_mouse_click ) { + /*** If the user presses the spacebar, and a non-edittext control + is active, we send it a mouse down event followed by a mouse up + event (simulated mouse-click) ***/ + + active_control->mouse_down_handler( 0, 0 ); + active_control->mouse_up_handler( 0, 0, true ); + } else { + /*** Pass the keystroke onto the active control, if any ***/ + if ( active_control != NULL ) + active_control->key_handler( key, curr_modifiers ); + } +} + + + +void GLUI_Main::special_up(int key, int x, int y) +{ + curr_modifiers = glutGetModifiers(); + + /*** Pass the keystroke onto the active control, if any ***/ + if ( active_control != NULL ) + active_control->special_up_handler( key, glutGetModifiers() ); +} + + +/****************************** GLUI_Main::special() **************/ + +void GLUI_Main::special(int key, int x, int y) +{ + curr_modifiers = glutGetModifiers(); + + /*** Pass the keystroke onto the active control, if any ***/ + if ( active_control != NULL ) + active_control->special_handler( key, glutGetModifiers() ); +} + + + +/****************************** GLUI_Main::mouse() **************/ + +void GLUI_Main::mouse(int button, int state, int x, int y) +{ + int callthrough; + GLUI_Control *control; + + /* printf( "MOUSE: %d %d\n", button, state ); */ + + callthrough = true; + + curr_modifiers = glutGetModifiers(); + + if ( button == GLUT_LEFT ) { + control = find_control( x, y ); + + /*if ( control ) printf( "control: %s\n", control->name.c_str() ); */ + + if ( mouse_button_down AND active_control != NULL AND + state == GLUT_UP ) + { + /** We just released the mouse, which was depressed at some control **/ + + callthrough = active_control-> + mouse_up_handler( x, y, control==active_control); + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); + + if ( active_control AND + active_control->active_type == GLUI_CONTROL_ACTIVE_MOUSEDOWN AND 0) + { + /*** This is a control that needs to be deactivated when the + mouse button is released ****/ + deactivate_current_control(); + } + } + else { + if ( control ) { + if ( NOT mouse_button_down AND state == GLUT_DOWN ) { + /*** We just pressed the mouse down at some control ***/ + + if ( active_control != control ) { + if ( active_control != NULL ) { + /** There is an active control still - deactivate it ***/ + deactivate_current_control(); + } + } + + if ( control->enabled ) { + activate_control( control, GLUI_ACTIVATE_MOUSE ); + callthrough = control->mouse_down_handler( x, y ); + } + } + } + } + + if ( state == GLUT_DOWN ) + mouse_button_down = true; + else if ( state == GLUT_UP ) + mouse_button_down = false; + } + + /** + NO CALLTHROUGH NEEDED FOR MOUSE EVENTS + if ( callthrough AND glut_mouse_CB ) + glut_mouse_CB( button, state, x, y ); + **/ + + callthrough=callthrough; /* To get rid of compiler warnings */ +} + + +/****************************** GLUI_Main::motion() **************/ + +void GLUI_Main::motion(int x, int y) +{ + int callthrough; + GLUI_Control *control; + + /* printf( "MOTION: %d %d\n", x, y ); */ + + callthrough = true; + + control = find_control(x,y); + + if ( mouse_button_down AND active_control != NULL ) { + callthrough = + active_control->mouse_held_down_handler(x,y,control==active_control); + } + + /** + NO CALLTHROUGH NEEDED FOR MOUSE EVENTS + + if ( callthrough AND glut_motion_CB ) + glut_motion_CB(x,y); + **/ + + callthrough=callthrough; /* To get rid of compiler warnings */ +} + + +/*********************** GLUI_Main::passive_motion() **************/ + +void GLUI_Main::passive_motion(int x, int y) +{ + GLUI_Control *control; + + control = find_control( x, y ); + + /* printf( "%p %p\n", control, mouse_over_control ); */ + + if ( control != mouse_over_control ) { + if ( mouse_over_control ) { + mouse_over_control->mouse_over( false, x, y ); + } + + if ( control ) { + control->mouse_over( true, x, y ); + mouse_over_control = control; + } + } + + /* + if ( curr_cursor != GLUT_CURSOR_INHERIT ) { + curr_cursor = GLUT_CURSOR_INHERIT; + glutSetCursor( GLUT_CURSOR_INHERIT ); + }*/ + +} + + +/****************************** GLUI_Main::entry() **************/ + +void GLUI_Main::entry(int state) +{ + /*if ( NOT active_control OR ( active_control AND ( active_control->type == GLUI_CONTROL_EDITTEXT + OR active_control->type == GLUI_CONTROL_SPINNER) ) )*/ + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); +} + + +/****************************** GLUI_Main::visibility() **************/ + +void GLUI_Main::visibility(int state) +{ +} + + +/****************************** GLUI_Main::idle() **************/ + +void GLUI_Main::idle(void) +{ + /*** Pass the idle event onto the active control, if any ***/ + + /* printf( "IDLE \t" ); */ + + if ( active_control != NULL ) { + /* First we check if the control actually needs the idle right now. + Otherwise, let's avoid wasting cycles and OpenGL context switching */ + + if ( active_control->needs_idle() ) { + /*** Set the current glut window to the glui window */ + /*** But don't change the window if we're already at that window ***/ + + if ( glut_window_id > 0 AND glutGetWindow() != glut_window_id ) { + glutSetWindow( glut_window_id ); + } + + active_control->idle(); + } + } +} + +int GLUI_Main::needs_idle( void ) +{ + return active_control != NULL && active_control->needs_idle(); +} + + +/******************************************* GLUI_Main::find_control() ******/ + +GLUI_Control *GLUI_Main::find_control( int x, int y ) +{ + GLUI_Control *node, *last_container; + + last_container = NULL; + + node = main_panel; + while( node != NULL ) { + if ( !node->dynamicCastGLUI_Column() AND + PT_IN_BOX( x, y, + node->x_abs, node->x_abs + node->w, + node->y_abs, node->y_abs + node->h ) + ) + { + /*** Point is inside current node ***/ + + if ( node->first_child() == NULL ) { + /*** SPECIAL CASE: for edittext boxes, we make sure click is + in box, and not on name string. This should be generalized + for all controls later... ***/ + if ( node->dynamicCastGLUI_EditText() ) { + if ( x < node->x_abs + ((GLUI_EditText*)node)->text_x_offset ) + return (GLUI_Control*) node->parent(); + } + + return node; /* point is inside this node, and node has no children, + so return this node as the selected node */ + } + else { + /*** This is a container class ***/ + last_container = node; + node = (GLUI_Control*) node->first_child(); /* Descend into child */ + } + + } + else { + node = (GLUI_Control*) node->next(); + } + } + + /** No leaf-level nodes found to accept the mouse click, so + return the last container control found which DOES accept the click **/ + + if ( last_container ) { + /* printf( "ctrl: '%s'\n", last_container->name ); */ + + return last_container; + } + else { + return NULL; + } +} + + +/************************************* GLUI_Main::pack_controls() ***********/ + +void GLUI_Main::pack_controls( void ) +{ + main_panel->pack(0,0); + + /**** Now align controls within their bounds ****/ + align_controls( main_panel ); + + /*** If this is a subwindow, expand panel to fit parent window ***/ + if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) { + int parent_h, parent_w; + int orig_window; + + orig_window = glutGetWindow(); + glutSetWindow( this->top_level_glut_window_id ); + parent_h = glutGet( GLUT_WINDOW_HEIGHT ); + parent_w = glutGet( GLUT_WINDOW_WIDTH ); + + glutSetWindow( orig_window ); + + /* printf( "%d %d\n", parent_h, parent_w ); */ + + if ( 1 ) { + if ( TEST_AND(this->flags,GLUI_SUBWINDOW_TOP )) { + main_panel->w = MAX( main_panel->w, parent_w ); + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + main_panel->h = MAX( main_panel->h, parent_h ); + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_BOTTOM )) { + main_panel->w = MAX( main_panel->w, parent_w ); + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) { + main_panel->h = MAX( main_panel->h, parent_h ); + } + } + } + + this->w = main_panel->w; + this->h = main_panel->h; +} + + +/************************************ GLUI_Main::align_controls() **********/ + +void GLUI_Main::align_controls( GLUI_Control *control ) +{ + GLUI_Control *child; + + control->align(); + + child = (GLUI_Control*) control->first_child(); + + while( child != NULL ) { + align_controls( child ); + + child = (GLUI_Control*)child->next(); + } +} + + + +/*********************************** GLUI::set_main_gfx_window() ************/ + +void GLUI::set_main_gfx_window( int window_id ) +{ + main_gfx_window_id = window_id; +} + + +/********************************* GLUI_Main::post_update_main_gfx() ********/ + +void GLUI_Main::post_update_main_gfx( void ) +{ + int old_window; + + if ( main_gfx_window_id > 0 ) { + old_window = glutGetWindow(); + glutSetWindow( main_gfx_window_id ); + glutPostRedisplay(); + if( old_window > 0 ) + glutSetWindow( old_window ); + } +} + +/********************************* GLUI_Main::should_redraw_now() ********/ +/** Return true if this control should redraw itself immediately (front buffer); + Or queue up a redraw and return false if it shouldn't (back buffer). + + Called from GLUI_Control::redraw. +*/ +bool GLUI_Main::should_redraw_now(GLUI_Control *ctl) +{ + switch (buffer_mode) { + case buffer_front: return true; /* always draw in front-buffer mode */ + case buffer_back: { + int orig = ctl->set_to_glut_window(); + glutPostRedisplay(); /* redraw soon */ + ctl->restore_window(orig); + return false; /* don't draw now. */ + } + } + return false; /* never executed */ +} + +/********************************* GLUI_Main::set_current_draw_buffer() ********/ + +int GLUI_Main::set_current_draw_buffer( void ) +{ + /* Save old buffer */ + GLint state; + glGetIntegerv( GL_DRAW_BUFFER, &state ); + /* Switch to new buffer */ + switch (buffer_mode) { + case buffer_front: glDrawBuffer(GL_FRONT); break; + case buffer_back: glDrawBuffer(GL_BACK); break; /* might not be needed... */ + } + return (int)state; +} + + +/********************************* GLUI_Main::restore_draw_buffer() **********/ + +void GLUI_Main::restore_draw_buffer( int buffer_state ) +{ + glDrawBuffer( buffer_state ); +} + + +/******************************************** GLUI_Main::GLUI_Main() ********/ + +GLUI_Main::GLUI_Main( void ) +{ + mouse_button_down = false; + w = 0; + h = 0; + active_control = NULL; + mouse_over_control = NULL; + main_gfx_window_id = -1; + glut_window_id = -1; + curr_modifiers = 0; + closing = false; + parent_window = -1; + glui_id = GLUI_Master.glui_id_counter; + GLUI_Master.glui_id_counter++; + + font = GLUT_BITMAP_HELVETICA_12; + curr_cursor = GLUT_CURSOR_LEFT_ARROW; + + int r=200, g=200, b=200; + bkgd_color.set( r,g,b ); + bkgd_color_f[0] = r / 255.0; + bkgd_color_f[1] = g / 255.0; + bkgd_color_f[2] = b / 255.0; + + /*** Create the main panel ***/ + main_panel = new GLUI_Panel; + main_panel->set_int_val( GLUI_PANEL_NONE ); + main_panel->glui = (GLUI*) this; + main_panel->name = "\0"; +} + +/************************************ GLUI_Main::draw_raised_box() **********/ + +void GLUI_Main::draw_raised_box( int x, int y, int w, int h ) +{ + w = w+x; + h = h+y; + + glColor3ub( bkgd_color.r, bkgd_color.g, bkgd_color.b ); + glBegin( GL_LINE_LOOP ); + glVertex2i( x+1, y+1 ); glVertex2i( w-1, y+1 ); + glVertex2i( w-1, h-1 ); glVertex2i( x+1, h-1 ); + glEnd(); + + glColor3d( 1.0, 1.0, 1.0 ); + glBegin( GL_LINE_STRIP ); + glVertex2i( x, h ); glVertex2i( x, y ); glVertex2i( w, y ); + glEnd(); + + glColor3d( 0.0, 0.0, 0.0 ); + glBegin( GL_LINE_STRIP ); + glVertex2i( w, y ); glVertex2i( w, h ); glVertex2i( x, h ); + glEnd(); + + glColor3d( .5, .5, .5 ); + glBegin( GL_LINE_STRIP ); + glVertex2i( w-1, y+1 ); glVertex2i( w-1, h-1 ); glVertex2i( x+1, h-1 ); + glEnd(); +} + + +/************************************ GLUI_Main::draw_lowered_box() **********/ +/* Not quite perfect... **/ + +void GLUI_Main::draw_lowered_box( int x, int y, int w, int h ) +{ + w = w+x; + h = h+y; + + glColor3ub( bkgd_color.r, bkgd_color.g, bkgd_color.b ); + glBegin( GL_LINE_LOOP ); + glVertex2i( x+1, y+1 ); glVertex2i( w-1, y+1 ); + glVertex2i( w-1, h-1 ); glVertex2i( x+1, h-1 ); + glEnd(); + + glColor3d( 0.0, 0.0, 0.0 ); + glBegin( GL_LINE_STRIP ); + glVertex2i( x, h ); glVertex2i( x, y ); glVertex2i( w, y ); + glEnd(); + + glColor3d( 1.0, 1.0, 1.0 ); + glBegin( GL_LINE_STRIP ); + glVertex2i( w, y ); glVertex2i( w, h ); glVertex2i( x, h ); + glEnd(); + + glColor3d( .5, .5, .5 ); + glBegin( GL_LINE_STRIP ); + glVertex2i( w-1, y+1 ); glVertex2i( w-1, h-1 ); glVertex2i( x+1, h-1 ); + glEnd(); +} + + +/************************************* GLUI_Main::activate_control() *********/ + +void GLUI_Main::activate_control( GLUI_Control *control, int how ) +{ + /** Are we not activating a control in the same window as the + previous active control? */ + if ( GLUI_Master.active_control_glui AND + this != (GLUI_Main*) GLUI_Master.active_control_glui ) { + GLUI_Master.active_control_glui->deactivate_current_control(); + } + + /******* Now activate it *****/ + if ( control != NULL AND control->can_activate AND control->enabled ) { + active_control = control; + + control->activate(how); + + /*if ( NOT active_control->is_container OR */ + /* active_control->type == GLUI_CONTROL_ROLLOUT) { */ + active_control->redraw(); + /*} */ + } + else { + active_control = NULL; + } + + /* printf( "activate: %d\n", glutGetWindow() ); */ + GLUI_Master.active_control = active_control; + GLUI_Master.active_control_glui = (GLUI*) this; +} + + +/************************* GLUI_Main::deactivate_current_control() **********/ + +void GLUI_Main::deactivate_current_control( void ) +{ + int orig; + + if ( active_control != NULL ) { + orig = active_control->set_to_glut_window(); + + active_control->deactivate(); + + /** If this isn't a container control, then redraw it in its + deactivated state. Container controls, such as panels, look + the same activated or not **/ + + /*if ( NOT active_control->is_container OR */ + /* active_control->type == GLUI_CONTROL_ROLLOUT ) { */ + active_control->redraw(); + /*} */ + + active_control->restore_window( orig ); + + active_control = NULL; + } + + /* printf( "deactivate: %d\n", glutGetWindow() ); */ + GLUI_Master.active_control = NULL; + GLUI_Master.active_control_glui = NULL; +} + + +/****************************** GLUI_Main::find_next_control() **************/ + +GLUI_Control *GLUI_Main::find_next_control_( GLUI_Control *control ) +{ + /*** THIS IS NOT find_next_control()! This is an unused older + version (look at the underscore at the end) ***/ + + if ( control == NULL ) + return find_next_control_rec( main_panel ); + else + return find_next_control_rec( control ); +} + +/****************************** GLUI_Main::find_next_control() **************/ + +GLUI_Control *GLUI_Main::find_next_control_rec( GLUI_Control *control ) +{ + GLUI_Control *child = NULL, *rec_control, *sibling; + + /*** Recursively investigate children ***/ + child = (GLUI_Control*) control->first_child(); + if ( child ) { + /*** If we can activate the first child, then do so ***/ + if ( child->can_activate AND child->enabled ) + return child; + else /*** Recurse into first child ***/ + rec_control = find_next_control_rec( child ); + + if ( rec_control ) + return rec_control; + } + + /*** At this point, either we don't have children, or the child cannot + be activated. So let's try the next sibling ***/ + + sibling = (GLUI_Control*) control->next(); + if ( sibling ) { + if ( sibling->can_activate AND sibling->enabled ) + return sibling; + else /*** Recurse into sibling ***/ + rec_control = find_next_control_rec( sibling ); + + if ( rec_control ) + return rec_control; + } + + return NULL; +} + + +/****************************** GLUI_Main::find_next_control() **************/ + +GLUI_Control *GLUI_Main::find_next_control( GLUI_Control *control ) +{ + GLUI_Control *tmp_control = NULL; + int back_up; + + if ( control == NULL ) + control = main_panel; + + while( control != NULL ) { + /** see if this control has a child **/ + tmp_control = (GLUI_Control*) control->first_child(); + + if ( tmp_control != NULL ) { + if ( tmp_control->can_activate AND tmp_control->enabled ) + return tmp_control; + + control = tmp_control; /* Descend into child */ + continue; + } + + /*** At this point, control has no children ***/ + + /** see if this control has a next sibling **/ + tmp_control = (GLUI_Control*) control->next(); + + if ( tmp_control != NULL ) { + if ( tmp_control->can_activate AND tmp_control->enabled ) + return tmp_control; + + control = tmp_control; + continue; + } + + /** back up until we find a sibling of an ancestor **/ + back_up = true; + while ( control->parent() AND back_up ) { + control = (GLUI_Control*) control->parent(); + + if ( control->next() ) { + control = (GLUI_Control*) control->next(); + if ( control->can_activate AND control->enabled ) + return control; + else + back_up = false; + + /*** if ( control->is_container ) { + tmp_control = control; + control = NULL; + break; + } + else { + back_up = false; + } + ***/ + } + } + + /** Check if we've cycled back to the top... if so, return NULL **/ + if ( control == main_panel ) { + return NULL; + } + } + /* + if ( tmp_control != NULL AND tmp_control->can_activate AND + tmp_control->enabled ) { + return tmp_control; + }*/ + + return NULL; +} + + +/****************************** GLUI_Main::find_prev_control() **************/ + +GLUI_Control *GLUI_Main::find_prev_control( GLUI_Control *control ) +{ + GLUI_Control *tmp_control, *next_control; + + if ( control == NULL ) { /* here we find the last valid control */ + next_control = main_panel; + + do { + tmp_control = next_control; + next_control = find_next_control( tmp_control ); + } while( next_control != NULL ); + + return tmp_control; + } + else { /* here we find the actual previous control */ + next_control = main_panel; + + do { + tmp_control = next_control; + next_control = find_next_control( tmp_control ); + } while( next_control != NULL AND next_control != control ); + + if ( next_control == NULL OR tmp_control == main_panel ) + return NULL; + else + return tmp_control; + } +} + +/************************* GLUI_Master_Object::set_glutIdleFunc() ***********/ + +void GLUI_Master_Object::set_glutIdleFunc(void (*f)(void)) +{ + glut_idle_CB = f; + GLUI_Master.glui_setIdleFuncIfNecessary(); +} + + +/**************************************** GLUI::disable() ********************/ + +void GLUI::disable( void ) +{ + deactivate_current_control(); + main_panel->disable(); +} + + +/******************************************** GLUI::sync_live() **************/ + +void GLUI::sync_live( void ) +{ + main_panel->sync_live(true, true); +} + + +/********************************* GLUI_Master_Object::sync_live_all() *****/ + +void GLUI_Master_Object::sync_live_all( void ) +{ + GLUI *glui; + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + + glui->sync_live(); /** sync it **/ + + glui = (GLUI*) glui->next(); + } +} + + +/************************************* GLUI_Master_Object::close() **********/ + +void GLUI_Master_Object::close_all( void ) +{ + GLUI *glui; + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + + glui->close(); /** Set flag to close **/ + + glui = (GLUI*) glui->next(); + } +} + + +/************************************* GLUI_Main::close_internal() **********/ + +void GLUI_Main::close_internal( void ) +{ + glutDestroyWindow(glutGetWindow()); /** Close this window **/ + + this->unlink(); + + if ( GLUI_Master.active_control_glui == this ) { + GLUI_Master.active_control = NULL; + GLUI_Master.active_control_glui = NULL; + } + + if ( parent_window != -1 ) { + glutSetWindow( parent_window ); + int win_w = glutGet( GLUT_WINDOW_WIDTH ); + int win_h = glutGet( GLUT_WINDOW_HEIGHT ); + glutReshapeWindow(win_w+1, win_h); + glutReshapeWindow(win_w-1, win_h); + } + + delete this->main_panel; + + delete this; +} + + +/************************************************** GLUI::close() **********/ + +void GLUI::close( void ) +{ + int old_glut_window; + + closing = true; + + old_glut_window = glutGetWindow(); + glutSetWindow( get_glut_window_id() ); + glutPostRedisplay(); + + glutSetWindow( old_glut_window ); +} + + +/************************** GLUI_Main::check_subwindow_position() **********/ + +void GLUI_Main::check_subwindow_position( void ) +{ + /*** Reposition this window if subwindow ***/ + if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) { + + int parent_w, parent_h, new_x, new_y; + int old_window = glutGetWindow(); + + glutSetWindow( glut_window_id ); + + glutSetWindow( glutGet( GLUT_WINDOW_PARENT )); + parent_w = glutGet( GLUT_WINDOW_WIDTH ); + parent_h = glutGet( GLUT_WINDOW_HEIGHT ); + + glutSetWindow( glut_window_id ); + + if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) { + new_x = parent_w - this->w; + new_y = 0; + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + new_x = 0; + new_y = 0; + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_BOTTOM )) { + new_x = 0; + new_y = parent_h - this->h; + } + else { /*** GLUI_SUBWINDOW_TOP ***/ + new_x = 0; + new_y = 0; + } + + /** Now make adjustments based on presence of other subwindows **/ + GLUI *curr_glui; + curr_glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( curr_glui ) { + if ( TEST_AND( curr_glui->flags, GLUI_SUBWINDOW) AND + curr_glui->parent_window == this->parent_window ) { + + if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) { + } + else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) { + } + else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) { + } + else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) AND + ( TEST_AND( this->flags,GLUI_SUBWINDOW_LEFT ) OR + TEST_AND( this->flags,GLUI_SUBWINDOW_RIGHT ) ) ) { + /** If we are a RIGHT or LEFT subwindow, and there exists some + TOP subwindow, bump our position down **/ + + new_y += curr_glui->h; + } + + /** CHeck multiple subwins at same position **/ + /** We check the glui_id's: only the glui with the higher + ID number (meaning it was created later) gets bumped over **/ + if ( curr_glui != this AND this->glui_id > curr_glui->glui_id ) { + if ( TEST_AND( this->flags,GLUI_SUBWINDOW_LEFT ) AND + TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) { + new_x += curr_glui->w; + } + else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_TOP ) AND + TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) ) { + new_y += curr_glui->h; + } + else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_BOTTOM ) AND + TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) { + new_y -= curr_glui->h; + } + else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_RIGHT ) AND + TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) { + new_x -= curr_glui->w; + } + + } + } + + curr_glui = (GLUI*) curr_glui->next(); + } + + + + CLAMP( new_x, 0, new_x ); + CLAMP( new_y, 0, new_y ); + + glutPositionWindow( new_x, new_y ); + /* glutPostRedisplay(); */ + + glutSetWindow( old_window ); + } +} + + +/********************************* GLUI_Master_Object::reshape() **********/ +/* This gets called by the user from a GLUT reshape callback. So we look */ +/* for subwindows that belong to the current window */ + +void GLUI_Master_Object::reshape( void ) +{ + GLUI *glui; + int current_window; + + current_window = glutGetWindow(); + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND + glui->parent_window == current_window ) { + glutSetWindow( glui->get_glut_window_id()); + glui->check_subwindow_position(); + } + + glui = (GLUI*) glui->next(); + } + + glutSetWindow(current_window); +} + + +/**************************** GLUI_Master_Object::set_glutReshapeFunc() *****/ + +void GLUI_Master_Object::set_glutReshapeFunc(void (*f)(int width, int height)) +{ + glutReshapeFunc( glui_reshape_func ); + add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_RESHAPE, (void*) f); +} + + +/**************************** GLUI_Master_Object::set_glutKeyboardFunc() ****/ + +void GLUI_Master_Object::set_glutKeyboardFunc(void (*f)(unsigned char key, + int x, int y)) +{ + glutKeyboardFunc( glui_keyboard_func ); + add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_KEYBOARD, (void*) f); +} + + +/*********************** GLUI_Master_Object::set_glutSpecialFunc() **********/ + + + +void GLUI_Master_Object::set_glutSpecialUpFunc(void (*f)(int key, + int x, int y)) +{ + glutSpecialUpFunc( glui_special_up_func ); + add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_SPECIAL_UP, (void*) f); +} + + +void GLUI_Master_Object::set_glutSpecialFunc(void (*f)(int key, + int x, int y)) +{ + glutSpecialFunc( glui_special_func ); + add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_SPECIAL, (void*) f); +} + + +/*********************** GLUI_Master_Object::set_glutMouseFunc() **********/ + +void GLUI_Master_Object::set_glutMouseFunc(void (*f)(int button, int state, + int x, int y)) +{ + glutMouseFunc( glui_mouse_func ); + add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_MOUSE, (void*) f); +} + + +/****************************** glui_parent_window_reshape_func() **********/ +/* This is the reshape callback for a window that contains subwindows */ + +void glui_parent_window_reshape_func( int w, int h ) +{ + int current_window; + GLUI *glui; + int first = true; + + /* printf( "glui_parent_window_reshape_func: %d\n", glutGetWindow() ); */ + + current_window = glutGetWindow(); + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND + glui->parent_window == current_window ) { + glutSetWindow( glui->get_glut_window_id()); + glui->check_subwindow_position(); + glutSetWindow( current_window ); + + if ( first ) { + if (glui->glut_reshape_CB) glui->glut_reshape_CB( w, h ); + + first = false; + } + } + + glui = (GLUI*) glui->next(); + } +} + + +/****************************** glui_parent_window_keyboard_func() **********/ + +void glui_parent_window_keyboard_func(unsigned char key, int x, int y) +{ + /* printf( "glui_parent_window_keyboard_func: %d\n", glutGetWindow() ); */ + + int current_window; + GLUI *glui; + + current_window = glutGetWindow(); + + if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) { + glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() ); + + GLUI_Master.active_control_glui->keyboard(key,x,y); + + glutSetWindow( current_window ); + } + else { + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND + glui->parent_window == current_window AND + glui->glut_keyboard_CB ) + { + glui->glut_keyboard_CB( key, x, y ); + break; + } + + glui = (GLUI*) glui->next(); + } + } +} + + +/****************************** glui_parent_window_special_func() **********/ + +void glui_parent_window_special_func(int key, int x, int y) +{ + /*printf( "glui_parent_window_special_func: %d\n", glutGetWindow() ); */ + + int current_window; + GLUI *glui; + + /** If clicking in the main area of a window w/subwindows, + deactivate any current control **/ + if ( GLUI_Master.active_control_glui != NULL ) + GLUI_Master.active_control_glui->deactivate_current_control(); + + /*** Now pass on the mouse event ***/ + + current_window = glutGetWindow(); + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND + glui->parent_window == current_window ) + { + glutSetWindow( glui->get_glut_window_id()); + if (glui->glut_special_CB) glui->glut_special_CB( key, x, y ); + break; + } + + glui = (GLUI*) glui->next(); + } +} + + +/****************************** glui_parent_window_mouse_func() **********/ + +void glui_parent_window_mouse_func(int button, int state, int x, int y) +{ + int current_window; + GLUI *glui; + + /** If clicking in the main area of a window w/subwindows, + deactivate any current control **/ + if ( GLUI_Master.active_control_glui != NULL ) + GLUI_Master.active_control_glui->deactivate_current_control(); + + + /*** Now pass on the mouse event ***/ + + current_window = glutGetWindow(); + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND + glui->parent_window == current_window AND + glui->glut_mouse_CB) + { + glutSetWindow( glui->get_glut_window_id()); + glui->glut_mouse_CB( button, state, x, y ); + break; + } + + glui = (GLUI*) glui->next(); + } +} + + +/************************** GLUI_Master_Object::find_glut_window() **********/ + +GLUI_Glut_Window *GLUI_Master_Object::find_glut_window( int window_id ) +{ + GLUI_Glut_Window *window; + + window = (GLUI_Glut_Window*) glut_windows.first_child(); + while( window ) { + if ( window->glut_window_id == window_id ) + return window; + + window = (GLUI_Glut_Window*) window->next(); + } + + /*** Window not found - return NULL ***/ + return NULL; +} + + +/******************** GLUI_Master_Object::add_cb_to_glut_window() **********/ + +void GLUI_Master_Object::add_cb_to_glut_window(int window_id, + int cb_type,void *cb) +{ + GLUI_Glut_Window *window; + + window = find_glut_window( window_id ); + if ( NOT window ) { + /*** Allocate new window structure ***/ + + window = new GLUI_Glut_Window; + window->glut_window_id = window_id; + window->link_this_to_parent_last( (GLUI_Node*) &this->glut_windows ); + } + + switch( cb_type ) { + case GLUI_GLUT_RESHAPE: + window->glut_reshape_CB = (void(*)(int,int)) cb; + break; + case GLUI_GLUT_DISPLAY: + window->glut_display_CB = (void(*)()) cb; + break; + case GLUI_GLUT_KEYBOARD: + window->glut_keyboard_CB = (void(*)(unsigned char,int,int)) cb; + break; + case GLUI_GLUT_SPECIAL: + window->glut_special_CB = (void(*)(int,int,int)) cb; + break; + case GLUI_GLUT_SPECIAL_UP: + window->glut_special_up_CB = (void(*)(int,int,int)) cb; + break; + case GLUI_GLUT_MOUSE: + window->glut_mouse_CB = (void(*)(int,int,int,int)) cb; + break; + case GLUI_GLUT_MOTION: + window->glut_motion_CB = (void(*)(int,int)) cb; + break; + case GLUI_GLUT_PASSIVE_MOTION: + window->glut_passive_motion_CB = (void(*)(int,int)) cb; + break; + case GLUI_GLUT_ENTRY: + window->glut_entry_CB = (void(*)(int)) cb; + break; + case GLUI_GLUT_VISIBILITY: + window->glut_visibility_CB= (void(*)(int)) cb; + break; + } +} + + +/************* GLUI_Master_Object::set_left_button_glut_menu_control() *****/ + +void GLUI_Master_Object::set_left_button_glut_menu_control( + GLUI_Control *control ) +{ + curr_left_button_glut_menu = control; +} + + +/******************************* GLUI_Main::set_ortho_projection() **********/ + +void GLUI_Main::set_ortho_projection( void ) +{ + int win_h, win_w; + + win_w = glutGet( GLUT_WINDOW_WIDTH ); + win_h = glutGet( GLUT_WINDOW_HEIGHT ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + /* gluOrtho2D( 0.0, (float) win_w, 0.0, (float) win_h ); */ + glOrtho( 0.0, (float)win_w, 0.0, (float) win_h, -1000.0, 1000.0 ); + + glMatrixMode( GL_MODELVIEW ); + + return; /****-----------------------------------------------***/ + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + /*** Rotate image so y increases upwards, contrary to OpenGL axes ***/ + glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 ); + glRotatef( 180.0, 0.0, 1.0, 0.0 ); + glRotatef( 180.0, 0.0, 0.0, 1.0 ); + glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 ); +} + + +/******************************* GLUI_Main::set_viewport() **********/ + +void GLUI_Main::set_viewport( void ) +{ + glViewport( 0, 0, main_panel->w, main_panel->h ); +} + + +/****************************** GLUI_Main::refresh() ****************/ + +void GLUI_Main::refresh( void ) +{ + int orig; + + /****** GLUI_Glut_Window *glut_window; + int current_window; + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + if ( glut_window ) { + glut_window->glut_reshape_CB(w,h); + ******/ + + orig = glutGetWindow(); + + pack_controls(); + + if ( glut_window_id > 0 ) + glutSetWindow( glut_window_id ); + + + if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) { + /*** GLUI subwindow ***/ + + check_subwindow_position(); + } + else { + /*** Standalone GLUI window ***/ + + glutReshapeWindow( this->h, this->w ); + + } + + glutPostRedisplay(); + glutSetWindow( orig); +} + + + +/***************** GLUI_Master_Object::get_main_gfx_viewport() ***********/ + +void GLUI_Master_Object::get_viewport_area( int *x, int *y, + int *w, int *h ) +{ + GLUI *curr_glui; + int curr_x, curr_y, curr_w, curr_h; + int curr_window; + + curr_window = glutGetWindow(); + curr_x = 0; + curr_y = 0; + curr_w = glutGet( GLUT_WINDOW_WIDTH ); + curr_h = glutGet( GLUT_WINDOW_HEIGHT ); + + curr_glui = (GLUI*) gluis.first_child(); + while( curr_glui ) { + if ( TEST_AND( curr_glui->flags, GLUI_SUBWINDOW) AND + curr_glui->parent_window == curr_window ) { + + /* printf( "%s -> %d %d %d\n", curr_glui->window_name.c_str(), curr_glui->flags, + curr_glui->w, curr_glui->h );*/ + + if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) { + curr_x += curr_glui->w; + curr_w -= curr_glui->w; + } + else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) { + curr_y += curr_glui->h; + curr_h -= curr_glui->h; + } + else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) { + curr_w -= curr_glui->w; + } + else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) ) { + curr_h -= curr_glui->h; + } + } + + curr_glui = (GLUI*) curr_glui->next(); + } + + curr_x = MAX( 0, curr_x ); + curr_y = MAX( 0, curr_y ); + curr_w = MAX( 0, curr_w ); + curr_h = MAX( 0, curr_h ); + + *x = curr_x; + *y = curr_y; + *w = curr_w; + *h = curr_h; +} + + +/*****************GLUI_Master_Object::auto_set_main_gfx_viewport() **********/ + +void GLUI_Master_Object::auto_set_viewport( void ) +{ + int x, y, w, h; + + get_viewport_area( &x, &y, &w, &h ); + glViewport( MAX(x,0), MAX(y,0), MAX(w,0), MAX(h,0) ); +} + + + +/***************************************** GLUI::show() **********************/ + +void GLUI::show( void ) +{ + int orig_window; + + orig_window = main_panel->set_to_glut_window(); + + glutShowWindow(); + + main_panel->restore_window(orig_window); +} + + + +/***************************************** GLUI::hide() **********************/ + +void GLUI::hide( void ) +{ + int orig_window; + + this->deactivate_current_control(); + + orig_window = main_panel->set_to_glut_window(); + + glutHideWindow(); + + main_panel->restore_window(orig_window); +} + + +/**************** GLUI_DrawingSentinal **************/ +GLUI_DrawingSentinal::GLUI_DrawingSentinal(GLUI_Control *c_) + :c(c_) +{ + orig_win = c->set_to_glut_window(); + orig_buf = c->glui->set_current_draw_buffer(); +} +GLUI_DrawingSentinal::~GLUI_DrawingSentinal() { + c->glui->restore_draw_buffer(orig_buf); + c->restore_window(orig_win); +} + + +void GLUI_Master_Object::glui_setIdleFuncIfNecessary( void ) +{ + GLUI *glui; + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + int necessary; + if (this->glut_idle_CB) + necessary = true; + else { + necessary = false; + while( glui ) { + if( glui->needs_idle() ) { + necessary = true; + break; + } + glui = (GLUI*) glui->next(); + } + } + if( necessary ) + glutIdleFunc( glui_idle_func ); + else + glutIdleFunc( NULL ); +} diff --git a/Extras/glui/glui_add_controls.cpp b/Extras/glui/glui_add_controls.cpp new file mode 100644 index 0000000..20ed43d --- /dev/null +++ b/Extras/glui/glui_add_controls.cpp @@ -0,0 +1,319 @@ +/**************************************************************************** + + GLUI User Interface Toolkit (LGPL) + --------------------------- + + glui_add_controls.cpp - Routines for adding controls to a GLUI window + +Note: these routines are all deprecated. Keeping them all here +prevents the linker from dragging in all the .o files, even for controls +that aren't used. + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "GL/glui.h" +#include "glui_internal.h" + + +/*********************************** GLUI:: add_checkbox() ************/ + +GLUI_Checkbox *GLUI:: add_checkbox( const char *name, int *value_ptr, + int id, GLUI_CB callback ) +{ + return add_checkbox_to_panel( main_panel, + name, value_ptr, id, callback ); +} + + +/*********************************** GLUI:: add_checkbox_to_panel() **********/ + +GLUI_Checkbox *GLUI::add_checkbox_to_panel( GLUI_Panel *panel, + const char *name, int *value_ptr, + int id, + GLUI_CB callback ) +{ + return new GLUI_Checkbox( panel, name, value_ptr, id, callback ); +} + +/********************************************* GLUI::add_panel() *************/ + +GLUI_Panel *GLUI::add_panel( const char *name, int type ) +{ + return add_panel_to_panel( main_panel, name, type ); +} + + +/**************************************** GLUI::add_panel_to_panel() *********/ + +GLUI_Panel *GLUI::add_panel_to_panel( GLUI_Panel *parent_panel, + const char *name, int type ) +{ + return new GLUI_Panel( parent_panel, name, type ); +} + + +/***************************** GLUI::add_radiogroup() ***************/ + +GLUI_RadioGroup *GLUI::add_radiogroup( int *value_ptr, + int user_id, GLUI_CB callback) +{ + return add_radiogroup_to_panel( main_panel, value_ptr, + user_id, callback ); +} + + +/***************************** GLUI::add_radiogroup_to_panel() ***************/ + +GLUI_RadioGroup *GLUI::add_radiogroup_to_panel( + GLUI_Panel *panel, int *value_ptr, + int user_id, GLUI_CB callback + ) +{ + return new GLUI_RadioGroup( panel, value_ptr, user_id, callback ); +} + + +/***************************** GLUI::add_radiobutton_to_group() *************/ + +GLUI_RadioButton *GLUI::add_radiobutton_to_group( GLUI_RadioGroup *group, + const char *name ) +{ + return new GLUI_RadioButton( group, name ); +} + + +/********************************** GLUI::add_statictext() ************/ + +GLUI_StaticText *GLUI::add_statictext( const char *name ) +{ + return add_statictext_to_panel( main_panel, name ); +} + + +/******************************* GLUI::add_statictext_to_panel() **********/ + +GLUI_StaticText *GLUI::add_statictext_to_panel( GLUI_Panel *panel, + const char *name ) +{ + return new GLUI_StaticText( panel, name ); +} + + +/***************************************** GLUI:: add_button() ************/ + +GLUI_Button *GLUI:: add_button( const char *name, + int id, GLUI_CB callback ) +{ + return add_button_to_panel( main_panel, + name, id, callback ); +} + +/*********************************** GLUI:: add_button_to_panel() **********/ + +GLUI_Button *GLUI::add_button_to_panel( GLUI_Panel *panel, + const char *name, + int id, + GLUI_CB callback ) +{ + return new GLUI_Button( panel, name, id, callback ); +} + +/********************************** GLUI::add_separator() ************/ + +void GLUI::add_separator( void ) +{ + add_separator_to_panel( main_panel ); +} + + +/******************************* GLUI::add_separator_to_panel() **********/ + +void GLUI::add_separator_to_panel( GLUI_Panel *panel ) +{ + new GLUI_Separator( panel ); +} + + +/********************************** GLUI::add_edittext() ************/ + +GLUI_EditText *GLUI::add_edittext( const char *name, + int data_type, void *data, + int id, GLUI_CB callback) +{ + return add_edittext_to_panel( main_panel, name, data_type, data, + id, callback ); +} + + +/******************************* GLUI::add_edittext_to_panel() **********/ + +GLUI_EditText *GLUI::add_edittext_to_panel( GLUI_Panel *panel, + const char *name, + int data_type, void *data, + int id, GLUI_CB callback) +{ + return new GLUI_EditText( panel, name, data_type, data, id, callback ); +} + +/********************************** GLUI::add_edittext() ************/ + +GLUI_EditText *GLUI::add_edittext( const char *name, + GLUI_String & data, + int id, GLUI_CB callback) +{ + return add_edittext_to_panel( main_panel, name, data, id, callback ); +} + + +/******************************* GLUI::add_edittext_to_panel() **********/ + +GLUI_EditText* +GLUI::add_edittext_to_panel( GLUI_Panel *panel, const char *name, + GLUI_String& data, + int id, GLUI_CB callback) +{ + return new GLUI_EditText( panel, name, GLUI_EDITTEXT_STRING, &data, id, callback ); +} + +/********************************** GLUI::add_spinner() ************/ + +GLUI_Spinner *GLUI::add_spinner( const char *name, + int data_type, void *data, + int id, GLUI_CB callback) +{ + return add_spinner_to_panel( main_panel, name, data_type, data, + id, callback ); +} + + +/******************************* GLUI::add_spinner_to_panel() **********/ + +GLUI_Spinner *GLUI::add_spinner_to_panel( + GLUI_Panel *panel, const char *name, + int data_type, void *data, + int id, GLUI_CB callback +) +{ + return new GLUI_Spinner( panel, name, data_type, data, id, callback ); +} + + +/********************************** GLUI::add_column() ************/ + +void GLUI::add_column( int draw_bar ) +{ + add_column_to_panel( main_panel, draw_bar ); +} + + +/******************************* GLUI::add_column_to_panel() **********/ + +void GLUI::add_column_to_panel( GLUI_Panel *panel, int draw_bar ) +{ + new GLUI_Column( panel, draw_bar ); +} + + +/*********************************** GLUI:: add_listbox() ************/ + +GLUI_Listbox *GLUI:: add_listbox( const char *name, int *value_ptr, + int id, GLUI_CB callback ) +{ + return add_listbox_to_panel( main_panel, + name, value_ptr, id, callback ); +} + + +/*********************************** GLUI:: add_listbox_to_panel() **********/ + +GLUI_Listbox *GLUI::add_listbox_to_panel( GLUI_Panel *panel, + const char *name, int *value_ptr, + int id, + GLUI_CB callback ) +{ + return new GLUI_Listbox( panel, name, value_ptr, id, callback ); +} + + +/*********************************** GLUI:: add_rotation() ************/ + +GLUI_Rotation *GLUI:: add_rotation( const char *name, float *value_ptr, + int id, GLUI_CB callback ) +{ + return add_rotation_to_panel( main_panel, name, value_ptr, id, callback ); +} + + +/*********************************** GLUI:: add_rotation_to_panel() **********/ + +GLUI_Rotation *GLUI::add_rotation_to_panel( GLUI_Panel *panel, + const char *name, float *value_ptr, + int id, + GLUI_CB callback ) +{ + return new GLUI_Rotation( panel, name, value_ptr, id, callback ); +} + + +/*********************************** GLUI:: add_translation() ************/ + +GLUI_Translation *GLUI:: add_translation( const char *name, int trans_type, + float *value_ptr, int id, + GLUI_CB callback ) +{ + return add_translation_to_panel( main_panel,name,trans_type, + value_ptr, id, callback ); +} + + +/*********************************** GLUI:: add_translation_to_panel() **********/ + +GLUI_Translation *GLUI::add_translation_to_panel( + GLUI_Panel *panel, const char *name, + int trans_type, float *value_ptr, + int id, GLUI_CB callback + ) +{ + return new GLUI_Translation(panel, name, trans_type, value_ptr, id, callback); +} + + +/********************************** GLUI::add_rollout() **************/ + +GLUI_Rollout *GLUI::add_rollout( const char *name, int open, int type) +{ + return add_rollout_to_panel( main_panel, name, open, type); +} + + +/****************************** GLUI::add_rollout_to_panel() *********/ + +GLUI_Rollout *GLUI::add_rollout_to_panel(GLUI_Panel *panel, const char *name, + int open, int type) +{ + return new GLUI_Rollout( panel, name, open, type ); +} + + + diff --git a/Extras/glui/glui_bitmap_img_data.cpp b/Extras/glui/glui_bitmap_img_data.cpp new file mode 100644 index 0000000..bfcef31 --- /dev/null +++ b/Extras/glui/glui_bitmap_img_data.cpp @@ -0,0 +1,138 @@ +/** + Bitmaps for all GLUI images. + + These were converted from original PPM images + (mostly lost) with the tools/ppm2array program. + + The images here are extracted in typical OpenGL + bottom-to-top fashion. + + FIXME: don't use greyscale brightness here--this prevents + people changing the background color. Instead, use a code + indicating the underlying purpose of the pixel: + 0 = shadows; outlines; UI elements (check boxes, arrows) + 64 = disabled shadows and UI elements + 128 = shadowing, disabled + 192 = disabled white; background + 255 = highlights; checkbox/radio background + + I'm thinking the way to do this would be to have an +enum { + BG = 0, // Background shines through-- totally alpha transparent + BS, // Background of scrollbar/spin box-- opaque gray + SB, // Shadowed-black element-- strong alpha blend to black + SD, // Shadowed-dark element-- weak alpha blend to black + HL, // Highlight-light-- weak alpha blend to white + HW, // Highlight-white-- strong alpha blend to white + UB, // User-interface black-- arrows, checkboxes, radio buttons + UW, // User-interface white-- backgrounds of checkboxes and radio buttons +}; + + Orion Sky Lawlor, olawlor@acm.org, 2006/05/04 (LGPL) +*/ + +/*----------------------- checkboxes --------------------------*/ +unsigned char glui_img_checkbox_0[] = { 13, 13, /* width, height */ +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 255, +}; + + +unsigned char glui_img_checkbox_0_dis[] = { 13, 13, /* width, height */ +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 255, +}; + + +unsigned char glui_img_checkbox_1[] = { 13, 13, /* width, height */ +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 255, 0, 255, 255, 255, 255, 255, 192, 255, 128, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 192, 255, 128, 0, 255, 0, 0, 0, 0, 0, 255, 255, 255, 192, 255, 128, 0, 255, 0, 0, 255, 0, 0, 0, 255, 255, 192, 255, 128, 0, 255, 0, 255, 255, 255, 0, 0, 0, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 0, 255, 192, 255, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 255, +}; + + +unsigned char glui_img_checkbox_1_dis[] = { 13, 13, /* width, height */ +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 192, 64, 192, 192, 192, 192, 192, 192, 255, 128, 64, 192, 192, 64, 64, 64, 192, 192, 192, 192, 192, 255, 128, 64, 192, 64, 64, 64, 64, 64, 192, 192, 192, 192, 255, 128, 64, 192, 64, 64, 192, 64, 64, 64, 192, 192, 192, 255, 128, 64, 192, 64, 192, 192, 192, 64, 64, 64, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 64, 64, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 64, 192, 192, 255, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 255, +}; + + +/*------------------------------- arrows -------------------------------------*/ +unsigned char glui_img_downarrow[] = { 16, 16, /* width, height */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 0, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 0, 0, 0, 0, 0, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 0, 0, 0, 0, 0, 0, 0, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, +}; + + +unsigned char glui_img_leftarrow[] = { 16, 16, /* width, height */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 0, 0, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, +}; + +unsigned char glui_img_rightarrow[] = { 16, 16, /* width, height */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 0, 0, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, +}; + +unsigned char glui_img_uparrow[] = { 16, 16, /* width, height */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 0, 0, 0, 0, 0, 0, 0, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 0, 0, 0, 0, 0, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 0, 0, 0, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 0, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 128, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, +}; + +/*------------------ listboxes ---------------------*/ +unsigned char glui_img_listbox_down[] = { 11, 17, /* width, height */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 127, 191, 191, 191, 127, 0, 127, 191, 191, 191, 127, 127, 127, 191, 191, 127, 0, 127, 191, 191, 127, 127, 127, 127, 127, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, +}; + + +unsigned char glui_img_listbox_up[] = { 11, 17, /* width, height */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 0, 191, 191, 191, 127, 0, 191, 255, 191, 191, 0, 0, 0, 191, 191, 127, 0, 191, 255, 191, 0, 0, 0, 0, 0, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 0, 191, 255, 255, 255, 255, 255, 255, 255, 255, 127, 0, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 0, +}; + +unsigned char glui_img_listbox_up_dis[] = { 11, 17, /* width, height */ +127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 191, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 254, 191, 191, 191, 127, 127, 191, 255, 191, 191, 127, 127, 254, 191, 191, 127, 127, 191, 255, 191, 127, 127, 127, 127, 254, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 191, 191, 191, 191, 191, 191, 191, 127, 127, 191, 255, 255, 255, 255, 255, 255, 255, 255, 127, 127, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, +}; + +/*--------------------------- radio buttons -------------------------*/ +unsigned char glui_img_radiobutton_0[] = { 14, 14, /* width, height */ +192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 255, 255, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 192, 128, 192, 192, 255, 255, 255, 255, 192, 192, 255, 192, 192, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 192, 192, 128, 0, 0, 255, 255, 255, 255, 0, 0, 255, 192, 192, 192, 192, 192, 128, 128, 0, 0, 0, 0, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 128, 128, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, +}; + + +unsigned char glui_img_radiobutton_0_dis[] = { 14, 14, /* width, height */ +192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 255, 255, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 192, 128, 192, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 192, 192, 128, 64, 64, 192, 192, 192, 192, 64, 64, 255, 192, 192, 192, 192, 192, 128, 128, 64, 64, 64, 64, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 128, 128, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, +}; + + +unsigned char glui_img_radiobutton_1[] = { 14, 14, /* width, height */ +192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 255, 255, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 192, 128, 192, 192, 255, 255, 255, 255, 192, 192, 255, 192, 192, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 192, 128, 0, 255, 255, 255, 0, 0, 255, 255, 255, 192, 255, 192, 192, 128, 0, 255, 255, 0, 0, 0, 0, 255, 255, 192, 255, 192, 192, 128, 0, 255, 255, 0, 0, 0, 0, 255, 255, 192, 255, 192, 192, 128, 0, 255, 255, 255, 0, 0, 255, 255, 255, 192, 255, 192, 192, 192, 128, 0, 255, 255, 255, 255, 255, 255, 192, 255, 192, 192, 192, 192, 128, 0, 0, 255, 255, 255, 255, 0, 0, 255, 192, 192, 192, 192, 192, 128, 128, 0, 0, 0, 0, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 128, 128, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, +}; + + +unsigned char glui_img_radiobutton_1_dis[] = { 14, 14, /* width, height */ +192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 255, 255, 192, 192, 192, 192, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 255, 255, 192, 192, 192, 192, 192, 128, 192, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 192, 128, 64, 192, 192, 192, 64, 64, 192, 192, 192, 192, 255, 192, 192, 128, 64, 192, 192, 64, 64, 64, 64, 192, 192, 192, 255, 192, 192, 128, 64, 192, 192, 64, 64, 64, 64, 192, 192, 192, 255, 192, 192, 128, 64, 192, 192, 192, 64, 64, 192, 192, 192, 192, 255, 192, 192, 192, 128, 64, 192, 192, 192, 192, 192, 192, 192, 255, 192, 192, 192, 192, 128, 64, 64, 192, 192, 192, 192, 64, 64, 255, 192, 192, 192, 192, 192, 128, 128, 64, 64, 64, 64, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 128, 128, 128, 128, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, +}; + + + +/*----------------- spinners ----------------------------*/ +unsigned char glui_img_spindown_0[] = { 12, 8, /* width, height */ +255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 255, 191, 191, 191, 191, 0, 127, 191, 191, 191, 127, 0, 255, 191, 191, 191, 0, 0, 0, 127, 191, 191, 127, 0, 255, 191, 191, 0, 0, 0, 0, 0, 127, 191, 127, 0, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, +}; + + +unsigned char glui_img_spindown_1[] = { 12, 8, /* width, height */ +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 191, 255, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 191, 255, 0, 127, 191, 191, 191, 127, 0, 191, 191, 191, 191, 255, 0, 127, 191, 191, 127, 0, 0, 0, 191, 191, 191, 255, 0, 127, 191, 127, 0, 0, 0, 0, 0, 191, 191, 255, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 191, 255, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 191, 255, +}; + + +unsigned char glui_img_spindown_dis[] = { 12, 8, /* width, height */ +255, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 255, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 64, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 64, 255, 191, 191, 191, 191, 127, 255, 191, 191, 191, 127, 64, 255, 191, 191, 191, 127, 127, 127, 255, 191, 191, 127, 64, 255, 191, 191, 127, 127, 127, 127, 127, 255, 191, 127, 64, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 64, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 64, +}; + + +unsigned char glui_img_spinup_0[] = { 12, 8, /* width, height */ +255, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 255, 191, 191, 0, 0, 0, 0, 0, 127, 191, 127, 0, 255, 191, 191, 191, 0, 0, 0, 127, 191, 191, 127, 0, 255, 191, 191, 191, 191, 0, 127, 191, 191, 191, 127, 0, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 0, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +}; + + +unsigned char glui_img_spinup_1[] = { 12, 8, /* width, height */ + 0, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 191, 255, 0, 127, 191, 127, 0, 0, 0, 0, 0, 191, 191, 255, 0, 127, 191, 191, 127, 0, 0, 0, 191, 191, 191, 255, 0, 127, 191, 191, 191, 127, 0, 191, 191, 191, 191, 255, 0, 127, 191, 191, 191, 191, 191, 191, 191, 191, 191, 255, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 191, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, +}; + + +unsigned char glui_img_spinup_dis[] = { 12, 8, /* width, height */ +255, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 64, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 64, 255, 191, 191, 127, 127, 127, 127, 127, 255, 191, 127, 64, 255, 191, 191, 191, 127, 127, 127, 255, 191, 191, 127, 64, 255, 191, 191, 191, 191, 127, 255, 191, 191, 191, 127, 64, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 127, 64, 255, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 64, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +}; + diff --git a/Extras/glui/glui_bitmaps.cpp b/Extras/glui/glui_bitmaps.cpp new file mode 100644 index 0000000..35d338e --- /dev/null +++ b/Extras/glui/glui_bitmaps.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_bitmaps.cpp + +Draws the hardcoded images listed in glui_bitmap_img_data with OpenGL. + +FIXME: upload the images to a texture. This will allow them to be: + - Drawn with alpha blending + - Drawn at random sizes and angles onscreen + - Drawn much faster than with glDrawPixels + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "GL/glui.h" +#include "glui_internal.h" +#include + +/************ Image Bitmap arrays **********/ + +extern unsigned char glui_img_checkbox_0[]; +extern unsigned char glui_img_checkbox_1[]; +extern unsigned char glui_img_radiobutton_0[]; +extern unsigned char glui_img_radiobutton_1[]; +extern unsigned char glui_img_uparrow[]; +extern unsigned char glui_img_downarrow[]; +extern unsigned char glui_img_leftarrow[]; +extern unsigned char glui_img_rightarrow[]; +extern unsigned char glui_img_spinup_0[]; +extern unsigned char glui_img_spinup_1[]; +extern unsigned char glui_img_spindown_0[]; +extern unsigned char glui_img_spindown_1[]; +extern unsigned char glui_img_checkbox_0_dis[]; +extern unsigned char glui_img_checkbox_1_dis[]; +extern unsigned char glui_img_radiobutton_0_dis[]; +extern unsigned char glui_img_radiobutton_1_dis[]; +extern unsigned char glui_img_spinup_dis[]; +extern unsigned char glui_img_spindown_dis[]; +extern unsigned char glui_img_listbox_up[]; +extern unsigned char glui_img_listbox_down[]; +extern unsigned char glui_img_listbox_up_dis[]; + + +// These must be in the same order as the GLUI_STDBITMAP enums from glui.h! +unsigned char *bitmap_arrays[] = { + glui_img_checkbox_0, + glui_img_checkbox_1, + glui_img_radiobutton_0, + glui_img_radiobutton_1, + glui_img_uparrow, + glui_img_downarrow, + glui_img_leftarrow, + glui_img_rightarrow, + glui_img_spinup_0, + glui_img_spinup_1, + glui_img_spindown_0, + glui_img_spindown_1, + glui_img_checkbox_0_dis, + glui_img_checkbox_1_dis, + glui_img_radiobutton_0_dis, + glui_img_radiobutton_1_dis, + glui_img_spinup_dis, + glui_img_spindown_dis, + glui_img_listbox_up, + glui_img_listbox_down, + glui_img_listbox_up_dis, +}; + + +/************************************ GLUI_Bitmap::load_from_array() ********/ + +GLUI_Bitmap::GLUI_Bitmap() +: pixels(NULL), + w(0), + h(0) +{ +} + +GLUI_Bitmap::~GLUI_Bitmap() +{ + if (pixels) + { + free(pixels); + pixels = NULL; + } +} + +/* Create bitmap from greyscale byte array */ +void GLUI_Bitmap::init_grey(unsigned char *array) +{ + w = array[0]; h = array[1]; + pixels = (unsigned char *) malloc(w*h*3); + assert(pixels); + + for(int i = 0; i=0 && i=0 && i=0 && iadd_control( this ); +} + + +/****************************** GLUI_Button::mouse_down_handler() **********/ + +int GLUI_Button::mouse_down_handler( int local_x, int local_y ) +{ + int_val = 1; /** A button always in unpressed before here, so + now we invariably set it to 'depressed' **/ + + currently_inside = true; + redraw(); + + return false; +} + + +/****************************** GLUI_Button::mouse_up_handler() **********/ + +int GLUI_Button::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + set_int_val( 0 ); /** A button always turns off after you press it **/ + + currently_inside = false; + redraw(); + + if ( inside ) { + /*** Invoke the user's callback ***/ + execute_callback(); + } + + return false; +} + + +/****************************** GLUI_Button::mouse_held_down_handler() ******/ + +int GLUI_Button::mouse_held_down_handler( int local_x, int local_y, + bool new_inside) +{ + if (new_inside != currently_inside) { + currently_inside = new_inside; + redraw(); + } + + return false; +} + + +/****************************** GLUI_Button::key_handler() **********/ + +int GLUI_Button::key_handler( unsigned char key,int modifiers ) +{ + return false; +} + +/********************************************** GLUI_Button::draw() **********/ + +void GLUI_Button::draw( int x, int y ) +{ + if (currently_inside) draw_pressed(); + else { + glui->draw_raised_box( 0, 0, w, h ); + draw_text( 0 ); + } +} + + +/************************************** GLUI_Button::draw_pressed() ******/ + +void GLUI_Button::draw_pressed( void ) +{ + glColor3f( 0.0, 0.0, 0.0 ); + + draw_text( 1 ); + + glBegin( GL_LINE_LOOP ); + glVertex2i( 0, 0 ); glVertex2i( w, 0 ); + glVertex2i( w, h ); glVertex2i( 0, h ); + glEnd(); + + glBegin( GL_LINE_LOOP ); + glVertex2i( 1, 1 ); glVertex2i( w-1, 1 ); + glVertex2i( w-1, h-1 ); glVertex2i( 1, h-1 ); + glEnd(); +} + + +/**************************************** GLUI_Button::draw_text() **********/ + +void GLUI_Button::draw_text( int sunken ) +{ + int string_width; + + glColor3ub( glui->bkgd_color.r, glui->bkgd_color.g, glui->bkgd_color.b ); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( 2, 2 ); glVertex2i( w-2, 2 ); + glVertex2i( w-2, h-2 ); glVertex2i( 2, h-2 ); + glEnd(); + + glColor3ub( 0,0,0 ); + + string_width = _glutBitmapWidthString( glui->font, + this->name.c_str() ); + if ( NOT sunken ) { + draw_name( MAX((w-string_width),0)/2, 13); + } + else { + draw_name( MAX((w-string_width),0)/2 + 1, 13 + 1); + } + + if ( active ) { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0x5555 ); + + glColor3f( 0., 0., 0. ); + + glBegin( GL_LINE_LOOP ); + glVertex2i( 3, 3 ); glVertex2i( w-3, 3 ); + glVertex2i( w-3, h-3 ); glVertex2i( 3, h-3 ); + glEnd(); + + glDisable( GL_LINE_STIPPLE ); + } +} + + +/************************************** GLUI_Button::update_size() **********/ + +void GLUI_Button::update_size( void ) +{ + int text_size; + + if ( NOT glui ) + return; + + text_size = string_width( name ); + + if ( w < text_size + 16 ) + w = text_size + 16 ; +} diff --git a/Extras/glui/glui_checkbox.cpp b/Extras/glui/glui_checkbox.cpp new file mode 100644 index 0000000..ed77b36 --- /dev/null +++ b/Extras/glui/glui_checkbox.cpp @@ -0,0 +1,188 @@ + +/**************************************************************************** + + GLUI User Interface Toolkit (LGPL) + --------------------------- + + glui_checkbox - GLUI_Checkbox control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +/****************************** GLUI_Checkbox::GLUI_Checkbox() **********/ + +GLUI_Checkbox::GLUI_Checkbox( GLUI_Node *parent, + const char *name, int *value_ptr, + int id, + GLUI_CB cb ) +{ + common_init(); + + set_ptr_val( value_ptr ); + set_name( name ); + user_id = id; + callback = cb; + + parent->add_control( this ); + + init_live(); +} + +/****************************** GLUI_Checkbox::mouse_down_handler() **********/ + +int GLUI_Checkbox::mouse_down_handler( int local_x, int local_y ) +{ + orig_value = int_val; + int_val = !int_val; + + currently_inside = true; + redraw(); + + return false; +} + + +/****************************** GLUI_Checkbox::mouse_up_handler() **********/ + +int GLUI_Checkbox::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + if ( NOT inside ) { /* undo effect on value */ + int_val = orig_value; + } + else { + set_int_val( int_val ); + + /*** Invoke the callback ***/ + execute_callback(); + } + + return false; +} + + +/****************************** GLUI_Checkbox::mouse_held_down_handler() ******/ + +int GLUI_Checkbox::mouse_held_down_handler( int local_x, int local_y, + bool inside) +{ + /********** Toggle checked and unchecked bitmap if we're entering or + leaving the checkbox area **********/ + if ( inside != currently_inside ) { + int_val = !int_val; + currently_inside = inside; + redraw(); + } + + return false; +} + + +/****************************** GLUI_Checkbox::key_handler() **********/ + +int GLUI_Checkbox::key_handler( unsigned char key,int modifiers ) +{ + return false; +} + + +/****************************** GLUI_Checkbox::draw() **********/ + +void GLUI_Checkbox::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + if ( int_val != 0 ) { + if ( enabled ) + glui->std_bitmaps.draw( GLUI_STDBITMAP_CHECKBOX_ON, 0, 0 ); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_CHECKBOX_ON_DIS, 0, 0 ); + } + else { + if ( enabled ) + glui->std_bitmaps.draw( GLUI_STDBITMAP_CHECKBOX_OFF, 0, 0 ); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_CHECKBOX_OFF_DIS, 0, 0 ); + } + + draw_active_area(); + + draw_name( text_x_offset, 10); +} + +/**************************** GLUI_Checkbox::draw_active_area() **************/ + +void GLUI_Checkbox::draw_active_area( void ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int text_width, left, right; + + text_width = _glutBitmapWidthString( glui->font, name.c_str() ); + left = text_x_offset-3; + right = left + 7 + text_width; + + if ( active ) { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0x5555 ); + glColor3f( 0., 0., 0. ); + } else { + glColor3ub( glui->bkgd_color.r, glui->bkgd_color.g, glui->bkgd_color.b ); + } + + glBegin( GL_LINE_LOOP ); + glVertex2i(left,0); glVertex2i( right,0); + glVertex2i(right,h+1); glVertex2i( left,h+1); + glEnd(); + + glDisable( GL_LINE_STIPPLE ); +} + + +/************************************ GLUI_Checkbox::update_size() **********/ + +void GLUI_Checkbox::update_size( void ) +{ + int text_size; + + if ( NOT glui ) + return; + + text_size = _glutBitmapWidthString( glui->font, name.c_str() ); + + /* if ( w < text_x_offset + text_size + 6 ) */ + w = text_x_offset + text_size + 6 ; +} + + +/********************************* GLUI_Checkbox::set_int_val() **************/ + +void GLUI_Checkbox::set_int_val( int new_val ) +{ + int_val = new_val; + + /*** Update the variable we're (possibly) pointing to ***/ + output_live(true); + redraw(); +} diff --git a/Extras/glui/glui_column.cpp b/Extras/glui/glui_column.cpp new file mode 100644 index 0000000..29901bc --- /dev/null +++ b/Extras/glui/glui_column.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** + GLUI User Interface Toolkit + --------------------------- + + glui_column.cpp - GLUI_Column control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +/******************************** GLUI_Column::GLUI_Column() ************/ + +GLUI_Column::GLUI_Column( GLUI_Node *parent, int draw_bar ) +{ + common_init(); + int_val = draw_bar; /* Whether to draw vertical bar or not */ + + parent->add_control( this ); +} + +/**************************************** GLUI_Column::draw() ************/ + +void GLUI_Column::draw( int x, int y ) +{ + int panel_x, panel_y, panel_w, panel_h, panel_x_off, panel_y_off; + int y_diff; + + if ( int_val == 1 ) { /* Draw a vertical bar */ + GLUI_DRAWINGSENTINAL_IDIOM + if ( parent() != NULL ) { + get_this_column_dims(&panel_x, &panel_y, &panel_w, &panel_h, + &panel_x_off, &panel_y_off); + + y_diff = y_abs - panel_y; + + if ( 0 ) { + glLineWidth(1.0); + glBegin( GL_LINES ); + glColor3f( .5, .5, .5 ); + glVertex2i( -GLUI_XOFF+1, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); + glVertex2i( -GLUI_XOFF+1, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); + + glColor3f( 1.0, 1.0, 1.0 ); + glVertex2i( -GLUI_XOFF+2, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); + glVertex2i( -GLUI_XOFF+2, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); + glEnd(); + } + else { + glLineWidth(1.0); + glBegin( GL_LINES ); + glColor3f( .5, .5, .5 ); + glVertex2i( -2, 0 ); + glVertex2i( -2, h ); + /*glVertex2i( 0, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); */ + /*glVertex2i( 0, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); */ + + glColor3f( 1.0, 1.0, 1.0 ); + glVertex2i( -1, 0 ); + glVertex2i( -1, h ); + /*glVertex2i( 1, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); */ + /*glVertex2i( 1, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); */ + glEnd(); + } + } + } +} + diff --git a/Extras/glui/glui_commandline.cpp b/Extras/glui/glui_commandline.cpp new file mode 100644 index 0000000..7586598 --- /dev/null +++ b/Extras/glui/glui_commandline.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_commandline.cpp - GLUI_CommandLine control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher, 2005 William Baxter + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA + + This program is -not- in the public domain. + +*****************************************************************************/ + +#include "GL/glui.h" +#include "glui_internal.h" + +/****************************** GLUI_CommandLine::GLUI_CommandLine() **********/ +GLUI_CommandLine::GLUI_CommandLine( GLUI_Node *parent, const char *name, + void *data, int id, GLUI_CB cb ) +{ + common_init(); + set_name( name ); + + data_type = GLUI_EDITTEXT_TEXT; + ptr_val = data; + user_id = id; + callback = cb; + + live_type = GLUI_LIVE_TEXT; + + parent->add_control( this ); + + init_live(); +} + +/****************************** GLUI_CommandLine::key_handler() **********/ + +int GLUI_CommandLine::key_handler( unsigned char key,int modifiers ) +{ + int ret; + + if ( NOT glui ) + return false; + + if ( debug ) + dump( stdout, "-> CMD_TEXT KEY HANDLER" ); + + if ( key == 13 ) { /* RETURN */ + commit_flag = true; + } + + ret = Super::key_handler( key, modifiers ); + + if ( debug ) + dump( stdout, "<- CMD_TEXT KEY HANDLER" ); + + return ret; +} + + +/****************************** GLUI_CommandLine::deactivate() **********/ + +void GLUI_CommandLine::deactivate( void ) +{ + // if the commit_flag is set, add the current command to + // history and call deactivate as normal + + // Trick deactivate into calling callback if and only if commit_flag set. + // A bit subtle, but deactivate checks that orig_text and text + // are the same to decide whether or not to call the callback. + // Force them to be different for commit, and the same for no commit. + if (commit_flag) { + add_to_history(text.c_str()); + orig_text = ""; + Super::deactivate( ); + set_text( "" ); + commit_flag = false; + } + else { + orig_text = text; + } +} + +/**************************** GLUI_CommandLine::special_handler() **********/ + +int GLUI_CommandLine::special_handler( int key,int modifiers ) +{ + if ( NOT glui ) + return false; + + if ( debug ) + printf( "CMD_TEXT SPECIAL:%d - mod:%d subs:%d/%d ins:%d sel:%d/%d\n", + key, modifiers, substring_start, substring_end,insertion_pt, + sel_start, sel_end ); + + if ( key == GLUT_KEY_UP ) // PREVIOUS HISTORY + { + scroll_history(-1); + } + else if ( key == GLUT_KEY_DOWN ) // NEXT HISTORY + { + scroll_history(+1); + } + else { + return Super::special_handler( key, modifiers ); + } + return false; +} + + + +/**************************** GLUI_CommandLine::scroll_history() ********/ + +void GLUI_CommandLine::scroll_history( int direction ) +{ + recall_history(curr_hist + direction); +} + +/**************************** GLUI_CommandLine::recall_history() ********/ + +void GLUI_CommandLine::recall_history( int hist_num ) +{ + if (hist_num < oldest_hist OR + hist_num > newest_hist OR + hist_num == curr_hist) + return; + + // Commit the current text first before we blow it away! + if (curr_hist == newest_hist) { + get_history_str(newest_hist) = text; + } + + curr_hist = hist_num; + set_text(get_history_str(curr_hist)); + sel_end = sel_start = insertion_pt = (int)text.length(); + update_and_draw_text(); +} + +/**************************** GLUI_CommandLine::add_to_history() ********/ + +void GLUI_CommandLine::add_to_history( const char *cmd ) +{ + if (cmd[0]=='\0') return; // don't add if it's empty + + curr_hist = newest_hist; + get_history_str(newest_hist) = text; + + newest_hist = ++curr_hist; + if ( newest_hist >= HIST_SIZE ) + { + // bump oldest off the list + hist_list.erase(hist_list.begin()); + hist_list.push_back(""); + + oldest_hist++; + } +} + +/**************************** GLUI_CommandLine::reset_history() ********/ + +void GLUI_CommandLine::reset_history( void ) +{ + oldest_hist = newest_hist = curr_hist = 0; +} + + + +/*************************************** GLUI_CommandLine::dump() **************/ + +void GLUI_CommandLine::dump( FILE *out, const char *name ) +{ + fprintf( out, + "%s (commandline@%p): ins_pt:%d subs:%d/%d sel:%d/%d len:%d\n", + name, this, + insertion_pt, substring_start, substring_end, sel_start, sel_end, + (int)text.length()); +} + + diff --git a/Extras/glui/glui_control.cpp b/Extras/glui/glui_control.cpp new file mode 100644 index 0000000..576a2a9 --- /dev/null +++ b/Extras/glui/glui_control.cpp @@ -0,0 +1,1203 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_control.cpp - top-level GLUI_Control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +int _glui_draw_border_only = 0; + +/*************************** Drawing Utility routines *********************/ + +/* Redraw this control. */ +void GLUI_Control::redraw(void) { + if (glui==NULL || hidden) return; + if (glui->should_redraw_now(this)) + translate_and_draw_front(); +} + +/** Redraw everybody in our window. */ +void GLUI_Control::redraw_window(void) { + if (glui==NULL || hidden) return; + if ( glui->get_glut_window_id() == -1 ) return; + int orig = set_to_glut_window(); + glutPostRedisplay(); + restore_window(orig); +} + + + +/* GLUI_Control::translate_and_draw_front() ********/ + +void GLUI_Control::translate_and_draw_front() +{ + GLUI_DRAWINGSENTINAL_IDIOM + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + translate_to_origin(); + draw(0,0); + glPopMatrix(); +} + + +/********** GLUI_Control::set_to_bkgd_color() ********/ + +void GLUI_Control::set_to_bkgd_color( void ) +{ + if ( NOT glui ) + return; + + glColor3ub( glui->bkgd_color.r, glui->bkgd_color.g, glui->bkgd_color.b ); +} + +/******** GLUI_Control::draw_box_inwards_outline() ********/ + +void GLUI_Control::draw_box_inwards_outline( int x_min, int x_max, int y_min, int y_max ) +{ + glBegin( GL_LINES ); + glColor3f( .5, .5, .5 ); + glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min ); + glVertex2i( x_min, y_min ); glVertex2i( x_min, y_max ); + + glColor3f( 1., 1., 1. ); + glVertex2i( x_min, y_max ); glVertex2i( x_max, y_max ); + glVertex2i( x_max, y_max ); glVertex2i( x_max, y_min ); + + if ( enabled ) + glColor3f( 0., 0., 0. ); + else + glColor3f( .25, .25, .25 ); + + glVertex2i( x_min+1, y_min+1 ); glVertex2i( x_max-1, y_min+1 ); + glVertex2i( x_min+1, y_min+1 ); glVertex2i( x_min+1, y_max-1 ); + + glColor3f( .75, .75, .75 ); + glVertex2i( x_min+1, y_max-1 ); glVertex2i( x_max-1, y_max-1 ); + glVertex2i( x_max-1, y_max-1 ); glVertex2i( x_max-1, y_min+1 ); + glEnd(); +} + + +/******* GLUI_Control::draw_box() **********/ + +void GLUI_Control::draw_box( int x_min, int x_max, int y_min, int y_max, float r, float g, float b) +{ + if ( r == 1.0 AND g == 1.0 AND b == 1.0 AND NOT enabled AND glui ) { + draw_bkgd_box( x_min, x_max, y_min, y_max ); + return; + } + + glColor3f( r, g, b ); + glBegin( GL_QUADS ); + glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min ); + glVertex2i( x_max, y_max ); glVertex2i( x_min, y_max ); + glEnd(); +} + + +/******* GLUI_Control::draw_bkgd_box() **********/ + +void GLUI_Control::draw_bkgd_box( int x_min, int x_max, int y_min, int y_max ) +{ + set_to_bkgd_color(); + + glBegin( GL_QUADS ); + glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min ); + glVertex2i( x_max, y_max ); glVertex2i( x_min, y_max ); + glEnd(); +} + + +/**** GLUI_Control::draw_active_area() ********/ + +void GLUI_Control::draw_active_box( int x_min, int x_max, int y_min, int y_max ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + if ( active ) { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0x5555 ); + glColor3f( 0., 0., 0. ); + } else { + set_to_bkgd_color(); + } + + glBegin( GL_LINE_LOOP ); + glVertex2i(x_min, y_min); glVertex2i( x_max, y_min ); + glVertex2i(x_max, y_max); glVertex2i( x_min, y_max ); + glEnd(); + + glDisable( GL_LINE_STIPPLE ); +} + + +/**** GLUI_Control::draw_emboss_box() ********/ + +void GLUI_Control::draw_emboss_box(int x_min,int x_max,int y_min,int y_max) +{ + glLineWidth( 1.0 ); + glColor3f( 1.0, 1.0, 1.0 ); + + glBegin( GL_LINE_LOOP ); + glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min ); + glVertex2i( x_max, y_max ); glVertex2i( x_min, y_max ); + glEnd(); + + glBegin( GL_LINE_LOOP ); + glVertex2i( x_min+1, y_min+1 ); glVertex2i( x_max-1, y_min+1 ); + glVertex2i( x_max-1, y_max-1 ); glVertex2i( x_min+1, y_max-1 ); + glEnd(); + + glColor3f( .5, .5, .5 ); + glBegin( GL_LINE_LOOP ); + glVertex2i( x_min, y_min ); + glVertex2i( x_max-1, y_min ); + glVertex2i( x_max-1, y_max-1 ); + glVertex2i( x_min, y_max-1 ); + glEnd(); +} + + + +/******* GLUT_Control::draw_recursive() **********/ + +void GLUI_Control::draw_recursive( int x, int y ) +{ + GLUI_Control *node; + + /* printf( "%s %d\n", this->name.c_str(), this->hidden );*/ + if ( NOT can_draw() ) + return; + + /*if ( 1 ) { -- Debugging to check control width + glColor3f( 1.0, 0.0, 0.0 ); + glBegin( GL_LINES ); + glVertex2i( x_abs, y_abs );00 + glVertex2i( x_abs+w, y_abs ); + + glEnd(); + }*/ + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + + glTranslatef( (float) this->x_abs + .5, + (float) this->y_abs + .5, + 0.0 ); + + if ( NOT _glui_draw_border_only ) { + if ( NOT strcmp( name.c_str(), "Rollout" ) ) { + } + + this->draw( this->x_off, this->y_off_top ); + } + else + { + if ( this->dynamicCastGLUI_Column() ) { + /* printf( "%s w/h: %d/%d\n", (char*) name, w, h ); */ + /*w = 2; */ + } + + /* The following draws the area of each control */ + glColor3f( 1.0, 0.0, 0.0 ); + glBegin( GL_LINE_LOOP ); + glVertex2i( 0, 0 ); glVertex2i( w, 0 ); + glVertex2i( w, h ); glVertex2i( 0, h ); + glEnd(); + } + glPopMatrix(); + + node = (GLUI_Control*) first_child(); + while( node ) { + node->draw_recursive( node->x_abs, node->y_abs ); + node = (GLUI_Control*) node->next(); + } +} + + +/****** GLUI_Control::set_to_glut_window() *********/ +/* Sets the current window to the glut window associated with this control */ + +int GLUI_Control::set_to_glut_window() +{ + int orig_window; + + if ( NOT glui) + return 1; + + orig_window = glutGetWindow(); + + glutSetWindow( glui->get_glut_window_id()); + + return orig_window; +} + + +/********** GLUI_Control::restore_window() *********/ + +void GLUI_Control::restore_window(int orig) +{ + if ( orig > 0 ) + glutSetWindow( orig ); +} + + + +/****************************** Text ***************************/ + +/*************** GLUI_Control::set_font() **********/ + +void GLUI_Control::set_font(void *new_font) +{ + font = new_font; + redraw(); +} + + +/********** GLUI_Control::draw_string() ************/ + +void GLUI_Control::draw_string( const char *text ) +{ + _glutBitmapString( get_font(), text ); +} + + +/**************** GLUI_Control::draw_char() ********/ + +void GLUI_Control::draw_char(char c) +{ + glutBitmapCharacter( get_font(), c ); +} + + +/*********** GLUI_Control::string_width() **********/ + +int GLUI_Control::string_width(const char *text) +{ + return _glutBitmapWidthString( get_font(), text ); +} + + +/************* GLUI_Control::char_width() **********/ + +int GLUI_Control::char_width(char c) +{ /* Hash table for faster character width lookups - JVK + Speeds up the textbox a little bit. + */ + int hash_index = c % CHAR_WIDTH_HASH_SIZE; + if (char_widths[hash_index][0] != c) { + char_widths[hash_index][0] = c; + char_widths[hash_index][1] = glutBitmapWidth( get_font(), c ); + } + return char_widths[hash_index][1]; +} + + +/*************** GLUI_Control::get_font() **********/ + +void *GLUI_Control::get_font( void ) +{ + /*** Does this control have its own font? ***/ + if ( this->font != NULL ) + return this->font; + + /*** Does the parent glui have a font? ***/ + if ( glui ) + return glui->font; + + /*** Return the default font ***/ + return GLUT_BITMAP_HELVETICA_12; +} + + +/************* GLUI_Control::draw_name() ***********/ +/* This draws the name of the control as either black (if enabled), or */ +/* embossed if disabled. */ + +void GLUI_Control::draw_name(int x, int y) +{ + if ( NOT can_draw() ) + return; + + if ( enabled ) + { + set_to_bkgd_color(); + glRasterPos2i(x+1, y+1); + draw_string(name); + glColor3b( 0, 0, 0 ); + glRasterPos2i(x, y); + draw_string(name); + } + else + { /* Control is disabled - emboss the string */ + glColor3f( 1.0f, 1.0f, 1.0f ); + glRasterPos2i(x+1, y+1); + draw_string(name); + glColor3f( .4f, .4f, .4f ); + glRasterPos2i(x, y); + draw_string(name); + } +} + + +/**************************** Layout and Packing *********************/ + +/****** GLUI_Control::align() **************/ + +void GLUI_Control::align() +{ + int col_x, col_y, col_w, col_h, col_x_off, col_y_off; + int orig_x_abs; + + orig_x_abs = x_abs; + + /* Fix alignment bug relating to columns */ + /*return; */ + + if ( NOT parent() ) + return; /* Clearly this shouldn't happen, though */ + + get_this_column_dims(&col_x, &col_y, &col_w, &col_h, + &col_x_off, &col_y_off); + + if ( this->dynamicCastGLUI_Column() ) { + /* if ( this->prev() != NULL ) { + ((GLUI_Control*)prev())->get_this_column_dims(&col_x, &col_y, &col_w, &col_h, + &col_x_off, &col_y_off); + + x_abs = col_x + col_w; + } + else { + x_abs = ((GLUI_Control*)parent())->x_abs; + } + */ + return; + } + + if ( alignment == GLUI_ALIGN_LEFT ) { + x_abs = col_x + col_x_off; + } + else if ( alignment == GLUI_ALIGN_RIGHT ) { + x_abs = col_x + col_w - col_x_off - this->w; + } + else if ( alignment == GLUI_ALIGN_CENTER ) { + x_abs = col_x + (col_w - this->w) / 2; + } + + if ( this->is_container ) { + /*** Shift all child columns ***/ + int delta = x_abs - orig_x_abs; + + GLUI_Control *node; + + node = (GLUI_Control*) this->first_child(); + while( node != NULL ) { + if ( node->dynamicCastGLUI_Column() ) { + node->x_abs += delta; + } + + node = (GLUI_Control*) node->next(); + } + } + +} + + +/************** GLUI_Control::pack() ************/ +/* Recalculate positions and offsets */ + +void GLUI_Control::pack_old(int x, int y) +{ + GLUI_Control *node; + int max_w, curr_y, curr_x, max_y; + int x_in = x, y_in =y; + int x_margin, y_margin_top, y_margin_bot; + int y_top_column; + int column_x; + GLUI_Column *curr_column = NULL; + this->update_size(); + x_margin = this->x_off; + y_margin_top = this->y_off_top; + y_margin_bot = this->y_off_bot; + this->x_abs = x_in; + this->y_abs = y_in; + max_w = -1; + max_y = -1; + curr_x = this->x_abs + x_margin; + curr_y = this->y_abs + y_margin_top; + /*** Record start of this set of columns ***/ + y_top_column = curr_y; + column_x = 0; + if ( this == glui->main_panel ) { + x=x; + } + /*** Iterate over children, packing them first ***/ + node = (GLUI_Control*) this->first_child(); + while( node != NULL ) { + if ( node->dynamicCastGLUI_Panel() && !node->collapsible) { + /* Pad some space above fixed size panels */ + curr_y += GLUI_ITEMSPACING; + } + else if ( node->dynamicCastGLUI_Column()) { + curr_column = (GLUI_Column*) node; + if ( 1 ) { + column_x += max_w + 2 * x_margin; + curr_x += max_w + 2 * x_margin; + } + else { + column_x += max_w + 0 * x_margin; + curr_x += max_w + 0 * x_margin; + } + /*node->pack( curr_x, curr_y ); */ + node->x_abs = curr_x; + node->y_abs = y_top_column; + node->w = 2; + node->h = curr_y - y_top_column; + curr_x += x_margin * 3 + 40; + curr_y = y_top_column; + max_w = 0; + node = (GLUI_Control*) node->next(); + continue; + } + node->pack( curr_x, curr_y ); + if ( node->dynamicCastGLUI_Panel() && !node->collapsible) + /* Pad some space below fixed size panels */ + curr_y += GLUI_ITEMSPACING; + curr_y += node->h; + if ( node->w > max_w ) { + max_w = node->w; + if ( curr_column != NULL ) + curr_column->w = max_w; + } + node = (GLUI_Control*) node->next(); + if ( node ) { + curr_y += GLUI_ITEMSPACING; + } + if ( curr_y > max_y ) + max_y = curr_y; + } + if ( this->is_container ) { + max_y += y_margin_bot; /*** Add bottom border inside box */ + if ( this->first_child() ) { + if ( this->dynamicCastGLUI_Rollout() ) { + /** We don't want the rollout to shrink in width when it's + closed **/ + this->w = MAX(this->w, column_x + max_w + 2 * x_margin ); + } + else { + this->w = column_x + max_w + 2 * x_margin; + } + this->h = (max_y - y_in); + } + else { /* An empty container, so just assign default w & h */ + this->w = GLUI_DEFAULT_CONTROL_WIDTH; + this->h = GLUI_DEFAULT_CONTROL_HEIGHT; + } + /** Expand panel if necessary (e.g., to include all the text in + a panel label) **/ + this->update_size(); + } +} + +/*** GLUI_Control::get_this_column_dims() **********/ +/* Gets the x,y,w,h,and x/y offsets of the column to which a control belongs */ + +void GLUI_Control::get_this_column_dims( int *col_x, int *col_y, + int *col_w, int *col_h, + int *col_x_off, int *col_y_off ) +{ + GLUI_Control *node, *parent_ptr; + int parent_h, parent_y_abs; + + parent_ptr = (GLUI_Control*) parent(); + + if ( parent_ptr==NULL ) + return; + + parent_h = parent_ptr->h; + parent_y_abs = parent_ptr->y_abs; + + if ( parent_ptr->dynamicCastGLUI_Panel() AND + parent_ptr->int_val == GLUI_PANEL_EMBOSSED AND + parent_ptr->name != "" ) { + parent_h -= GLUI_PANEL_EMBOSS_TOP; + parent_y_abs += GLUI_PANEL_EMBOSS_TOP; + } + + if ( 0 ) { + GLUI_Node *first, *last, *curr; + + /** Look for first control in this column **/ + first = this; + while (first->prev() AND !(first->prev())->dynamicCastGLUI_Column() ) + first = first->prev(); + + /** Look for last control in this column **/ + last = this; + while ( last->next() AND !(first->next())->dynamicCastGLUI_Column() ) + last = last->next(); + + curr = first; + int max_w = -1; + do { + if ( ((GLUI_Control*)curr)->w > max_w ) + max_w = ((GLUI_Control*)curr)->w; + + if ( curr == last ) + break; + + curr = curr->next(); + } while( curr != NULL ); + + *col_x = ((GLUI_Control*)first)->x_abs; + *col_y = ((GLUI_Control*)first)->y_abs; + *col_w = max_w; + if ( parent() ) { + *col_h = ((GLUI_Control*)parent())->h; + *col_x_off = ((GLUI_Control*)parent())->x_off; + } + else { + *col_h = 10; + *col_x_off = 0; + } + *col_y_off = 0; + + return; + } + + if ( 1 ) { /* IS THIS WRONG? */ + /*** Look for preceding column ***/ + node = (GLUI_Control*) this->prev(); + while( node ) { + if ( node->dynamicCastGLUI_Column() ) { + *col_x = node->x_abs; + *col_y = parent_y_abs; + *col_w = node->w; + *col_h = parent_h; + *col_x_off = node->x_off; + *col_y_off = 0; + + return; + } + + node = (GLUI_Control*) node->prev(); + } + + /*** Nope, Look for next column ***/ + node = (GLUI_Control*) this->next(); + while( node ) { + if ( node->dynamicCastGLUI_Column() ) { + *col_x = parent_ptr->x_abs; + *col_y = parent_y_abs; + *col_w = node->x_abs - parent_ptr->x_abs; + *col_h = parent_h; + *col_x_off = node->x_off; + *col_y_off = 0; + + return; + } + + node = (GLUI_Control*) node->next(); + } + + /*** This is single-column panel, so return panel dims ***/ + *col_x = parent_ptr->x_abs; + *col_y = parent_y_abs; + *col_w = parent_ptr->w; + *col_h = parent_h; + *col_x_off = parent_ptr->x_off; + *col_y_off = 0; + } +} + + +void GLUI_Control::pack( int x, int y ) +{ + GLUI_Control *node; + int max_w, curr_y, curr_x, max_y; + int x_in = x, y_in =y; + int x_margin, y_margin_top, y_margin_bot; + int y_top_column; + int column_x; + GLUI_Column *curr_column = NULL; + + this->update_size(); + + x_margin = this->x_off; + y_margin_top = this->y_off_top; + y_margin_bot = this->y_off_bot; + + this->x_abs = x_in; + this->y_abs = y_in; + + max_w = 0; + max_y = 0; + curr_x = this->x_abs + x_margin; + curr_y = this->y_abs + y_margin_top; + + /*** Record start of this set of columns ***/ + + y_top_column = curr_y; + column_x = curr_x; + + /*** Iterate over children, packing them first ***/ + + node = (GLUI_Control*) this->first_child(); + while( node != NULL ) { + if ( node->dynamicCastGLUI_Panel() && !node->collapsible) { + /* Pad some space above fixed-size panels */ + curr_y += GLUI_ITEMSPACING; + } + else if ( node->dynamicCastGLUI_Column() ) { + curr_column = (GLUI_Column*) node; + curr_x += max_w + 1 * x_margin; + column_x = curr_x; + + node->x_abs = curr_x; + node->y_abs = y_top_column; + node->w = 2; + node->h = curr_y - y_top_column; + + curr_x += x_margin * 1; + curr_y = y_top_column; + max_w = 0; + + node = (GLUI_Control*) node->next(); + continue; + } + + node->pack( curr_x, curr_y ); + + if ( node->dynamicCastGLUI_Panel() && !node->collapsible) + /* Pad some space below fixed-size panels */ + curr_y += GLUI_ITEMSPACING; + + curr_y += node->h; + + if ( node->w > max_w ) { + max_w = node->w; + if ( curr_column != NULL ) + curr_column->w = max_w + x_margin; + } + + if ( curr_y > max_y ) { + max_y = curr_y; + if ( curr_column != NULL ) + curr_column->h = max_y - y_top_column; + } + + node = (GLUI_Control*) node->next(); + + if ( node ) { + curr_y += GLUI_ITEMSPACING; + } + + } + + if ( this->is_container ) { + max_y += y_margin_bot; /*** Add bottom border inside box */ + + if ( this->first_child() ) { + this->w = column_x + max_w + 2 * x_margin - x_in; + this->h = (max_y - y_in); + } + else { /* An empty container, so just assign default w & h */ + if ( !this->dynamicCastGLUI_Rollout() && + !this->dynamicCastGLUI_Tree() ) { + this->w = GLUI_DEFAULT_CONTROL_WIDTH; + this->h = GLUI_DEFAULT_CONTROL_HEIGHT; + } + } + + /** Expand panel if necessary (e.g., to include all the text in + a panel label) **/ + this->update_size(); + + + /*** Now we step through the GLUI_Columns, setting the 'h' ***/ + node = (GLUI_Control*) this->first_child(); + while( node != NULL ) { + if ( node->dynamicCastGLUI_Column() ) { + node->h = this->h - y_margin_bot - y_margin_top; + } + + node = (GLUI_Control*) node->next(); + } + } +} + + + +/******************************** Live Variables **************************/ +/*********** GLUI_Control::sync_live() ************/ +/* Reads live variable and sets control to its current value */ +/* This function is recursive, and operates on control's children */ + +void GLUI_Control::sync_live(int recurse, int draw_it) +{ + GLUI_Node *node; + int sync_it=true; + int i; + float *fp; + bool changed = false; + + /*** If this is currently active control, and mouse button is down, + don't sync ***/ + if ( glui ) + { + if ( this == glui->active_control AND glui->mouse_button_down ) + sync_it = false; + + /*** Actually, just disable syncing if button is down ***/ + /*** Nope, go ahead and sync if mouse is down - this allows syncing in + callbacks ***/ + if ( 0 ) { /* THIS CODE BELOW SHOULD NOT BE EXECUTED */ + if ( glui->mouse_button_down ) { + /* printf( "Can't sync\n" ); */ + return; + } + } + } + + /*** If this control has a live variable, we check its current value + against the stored value in the control ***/ + + if ( ptr_val != NULL ) { + if ( live_type == GLUI_LIVE_NONE OR NOT sync_it ) { + } + else if ( live_type == GLUI_LIVE_INT ) { + if ( *((int*)ptr_val) != last_live_int ) { + set_int_val( *((int*)ptr_val) ); + last_live_int = *((int*)ptr_val); + changed = true; + } + } + else if ( live_type == GLUI_LIVE_FLOAT ) { + if ( *((float*)ptr_val) != last_live_float ) { + set_float_val( *((float*)ptr_val) ); + last_live_float = *((float*)ptr_val); + changed = true; + } + } + else if ( live_type == GLUI_LIVE_TEXT ) { + if ( last_live_text.compare((const char*)ptr_val) != 0 ) { + set_text( (char*) ptr_val ); + last_live_text = (const char*)ptr_val; + changed = true; + } + } + else if ( live_type == GLUI_LIVE_STRING ) { + if ( last_live_text.compare(((std::string*) ptr_val)->c_str()) != 0 ) { + set_text( ((std::string*) ptr_val)->c_str()); + last_live_text = *((std::string*) ptr_val); + changed = true; + } + } + else if ( live_type == GLUI_LIVE_FLOAT_ARRAY ) { + /*** Step through the arrays, and see if they're the same ***/ + + fp = (float*) ptr_val; + for ( i=0; ifirst_child(); + while( node ) { + ((GLUI_Control*) node)->sync_live(true, true); + node = node->next(); + } + + if ( collapsible == true AND is_open == false ) { + /** Here we have a collapsed control (e.g., a rollout that is closed **/ + /** We need to go in and sync all the collapsed controls inside **/ + + node = this->collapsed_node.first_child(); + while( node ) { + ((GLUI_Control*) node)->sync_live(true, false); + node = node->next(); + } + } + } +} + + +/********** GLUI_Control::output_live() ************/ +/* Writes current value of control to live variable. */ + +void GLUI_Control::output_live(int update_main_gfx) +{ + int i; + float *fp; + + if ( ptr_val == NULL ) + return; + + if ( NOT live_inited ) + return; + + if ( live_type == GLUI_LIVE_NONE ) { + } + else if ( live_type == GLUI_LIVE_INT ) { + *((int*)ptr_val) = int_val; + last_live_int = int_val; + } + else if ( live_type == GLUI_LIVE_FLOAT ) { + *((float*)ptr_val) = float_val; + last_live_float = float_val; + } + else if ( live_type == GLUI_LIVE_TEXT ) { + strncpy( (char*) ptr_val, text.c_str(), text.length()+1); + last_live_text = text; + } + else if ( live_type == GLUI_LIVE_STRING ) { + (*(std::string*)ptr_val)= text.c_str(); + last_live_text = text; + } + else if ( live_type == GLUI_LIVE_FLOAT_ARRAY ) { + fp = (float*) ptr_val; + + for( i=0; iglui != NULL ) { + this->glui->post_update_main_gfx(); + } +} + + +/****** GLUI_Control::execute_callback() **********/ + +void GLUI_Control::execute_callback() +{ + int old_window; + + old_window = glutGetWindow(); + + if ( glui AND glui->main_gfx_window_id != -1 ) + glutSetWindow( glui->main_gfx_window_id ); + + this->callback( this ); +// if ( this->callback ) +// this->callback( this->user_id ); + + glutSetWindow( old_window ); +} + + +/************** GLUI_Control::init_live() **********/ +/* Reads in value of a live variable. Called once, when ctrl is created */ + +void GLUI_Control::init_live() +{ + int i; + float *fp; + + if ( ptr_val == NULL ) + return; + + if ( live_type == GLUI_LIVE_NONE ) { + } + else if ( live_type == GLUI_LIVE_INT ) { + set_int_val( *((int*)ptr_val) ); + last_live_int = *((int*)ptr_val); + } + else if ( live_type == GLUI_LIVE_FLOAT ) { + set_float_val( *((float*)ptr_val) ); + last_live_float = *((float*)ptr_val); + } + else if ( live_type == GLUI_LIVE_TEXT ) { + set_text( (const char*) ptr_val ); + last_live_text = (const char*) ptr_val; + } + else if ( live_type == GLUI_LIVE_STRING ) { + set_text( ((std::string*) ptr_val)->c_str() ); + last_live_text = ((std::string*) ptr_val)->c_str(); + } + else if ( live_type == GLUI_LIVE_FLOAT_ARRAY ) { + set_float_array_val( (float*) ptr_val ); + + fp = (float*) ptr_val; + + for( i=0; ienable(); + node = (GLUI_Control*) node->next(); + } +} + + +/***** GLUI_Control::disable() ****************/ + +void GLUI_Control::disable() +{ + GLUI_Control *node; + + enabled = false; + + if ( NOT glui ) + return; + + if ( glui->active_control == this ) + glui->deactivate_current_control(); + redraw(); + + /*** Now recursively disable all buttons below it ***/ + node = (GLUI_Control*) first_child(); + while(node) { + node->disable(); + node = (GLUI_Control*) node->next(); + } +} + +/******* GLUI_Control::set_w() **************/ + +void GLUI_Control::set_w(int new_w) +{ + w = new_w; + update_size(); /* Make sure control is big enough to fit text */ + if (glui) glui->refresh(); +} + + +/**** GLUI_Control::set_h() **************/ + +void GLUI_Control::set_h(int new_h) +{ + h = new_h; + update_size(); /* Make sure control is big enough to fit text */ + if (glui) glui->refresh(); +} + + +/***** GLUI_Control::set_alignment() ******/ + +void GLUI_Control::set_alignment(int new_align) +{ + alignment = new_align; + + if ( glui ) + { + glui->align_controls(this); + redraw_window(); + } +} + + +/***** GLUI_Control::needs_idle() *********/ +/* This method gets overloaded by specific classes, e.g. Spinner. */ +/* It returns whether or not a control needs to receive an idle event or not */ +/* For example, a spinner only needs idle events when the user is holding */ +/* the mouse down in one of the arrows. Otherwise, don't waste cycles */ +/* and OpenGL context switching by calling its idle. */ + +bool GLUI_Control::needs_idle() const +{ + return false; +} + + +/********* GLUI_Control::~GLUI_Control() **********/ + +GLUI_Control::~GLUI_Control() +{ + GLUI_Control *item = (GLUI_Control*) this->first_child(); + + while (item) + { + GLUI_Control *tmp = item; + item = (GLUI_Control*) item->next(); + delete tmp; + } +} + +/********* GLUI_Control::hide_internal() ********/ +/** Sets hidden==true for this control and all its siblings. */ +/** If recurse is true, we go to children as well */ + +void GLUI_Control::hide_internal( int recurse ) +{ + GLUI_Node *node; + + node = (GLUI_Node *) this; + while( node != NULL ) { + ((GLUI_Control*)node)->hidden = true; + + if ( recurse AND node->first_child() != NULL ) + ((GLUI_Control*) node->first_child())->hide_internal(true); + + node = node->next(); + } + + node = this->collapsed_node.first_child(); + while( node != NULL ) { + ((GLUI_Control*)node)->hidden = true; + + if ( recurse AND node->first_child() != NULL ) + ((GLUI_Control*) node->first_child())->hide_internal(true); + + node = node->next(); + } +} + + +/********* GLUI_Control::unhide_internal() ********/ +/** Sets hidden==false for this control and all its siblings. */ +/** If recurse is true, we go to children as well */ + +void GLUI_Control::unhide_internal( int recurse ) +{ + GLUI_Node *node; + + node = (GLUI_Node *) this; + while( node != NULL ) { + /* printf( "unhide: %s [%d]\n", ((GLUI_Control*)node)->name.c_str(), + ((GLUI_Control*)node)->hidden );*/ + ((GLUI_Control*)node)->hidden = false; + + if ( recurse AND node->first_child() != NULL ) + ((GLUI_Control*) node->first_child())->unhide_internal(true); + + node = node->next(); + } + + node = this->collapsed_node.first_child(); + while( node != NULL ) { + ((GLUI_Control*)node)->hidden = false; + + if ( recurse AND node->first_child() != NULL ) + ((GLUI_Control*) node->first_child())->unhide_internal(true); + + node = node->next(); + } +} diff --git a/Extras/glui/glui_edittext.cpp b/Extras/glui/glui_edittext.cpp new file mode 100644 index 0000000..9066fde --- /dev/null +++ b/Extras/glui/glui_edittext.cpp @@ -0,0 +1,1198 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_edittext.cpp - GLUI_EditText control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" +#include + +/****************************** GLUI_EditText::GLUI_EditText() **********/ + +GLUI_EditText::GLUI_EditText( GLUI_Node *parent, const char *name, + int data_type, void *live_var, + int id, GLUI_CB callback ) +{ + if (data_type == GLUI_EDITTEXT_TEXT) { + live_type = GLUI_LIVE_TEXT; + } + else if (data_type == GLUI_EDITTEXT_STRING) { + data_type = GLUI_EDITTEXT_TEXT; // EDITTEXT_STRING doesn't really exist. + // Except as a signal to make a string. + // It's a backwards-compat hack. + live_type = GLUI_LIVE_STRING; + } + else if (data_type == GLUI_EDITTEXT_INT) { + live_type = GLUI_LIVE_INT; + } + else if (data_type == GLUI_EDITTEXT_FLOAT) { + live_type = GLUI_LIVE_FLOAT; + } + common_construct( parent, name, data_type, live_type, live_var, id, callback ); +} + +/****************************** GLUI_EditText::GLUI_EditText() **********/ + +GLUI_EditText::GLUI_EditText( GLUI_Node *parent, const char *name, + int text_type, int id, GLUI_CB callback ) +{ + common_construct( parent, name, text_type, GLUI_LIVE_NONE, 0, id, callback); +} + +/****************************** GLUI_EditText::GLUI_EditText() **********/ + +GLUI_EditText::GLUI_EditText( GLUI_Node *parent, const char *name, + int *live_var, + int id, GLUI_CB callback ) +{ + common_construct( parent, name, GLUI_EDITTEXT_INT, GLUI_LIVE_INT, live_var, id, callback); +} + +/****************************** GLUI_EditText::GLUI_EditText() **********/ + +GLUI_EditText::GLUI_EditText( GLUI_Node *parent, const char *name, + float *live_var, + int id, GLUI_CB callback ) +{ + common_construct( parent, name, GLUI_EDITTEXT_FLOAT, GLUI_LIVE_FLOAT, live_var, id, callback); +} + +/****************************** GLUI_EditText::GLUI_EditText() **********/ + +GLUI_EditText::GLUI_EditText( GLUI_Node *parent, const char *name, + char *live_var, + int id, GLUI_CB callback ) +{ + common_construct( parent, name, GLUI_EDITTEXT_TEXT, GLUI_LIVE_TEXT, live_var, id, callback); +} + +/****************************** GLUI_EditText::GLUI_EditText() **********/ + +GLUI_EditText::GLUI_EditText( GLUI_Node *parent, const char *name, + std::string &live_var, + int id, GLUI_CB callback ) +{ + common_construct( parent, name, GLUI_EDITTEXT_TEXT, GLUI_LIVE_STRING, &live_var, id, callback); +} + +/****************************** GLUI_EditText::common_construct() **********/ + +void GLUI_EditText::common_construct( GLUI_Node *parent, const char *name, + int data_t, int live_t, void *data, int id, + GLUI_CB cb ) +{ + common_init(); + set_name( name ); + + live_type = live_t; + data_type = data_t; + ptr_val = data; + user_id = id; + callback = cb; + + + if ( live_type == GLUI_LIVE_INT) { + if ( data == NULL ) + set_int_val(int_val); /** Set to some default, in case of no live var **/ + } + else if ( live_type == GLUI_LIVE_FLOAT ) { + num_periods = 1; + if ( data == NULL ) + set_float_val(float_val); /** Set to some default, in case of no live var **/ + } + + parent->add_control( this ); + + init_live(); +} + +/****************************** GLUI_EditText::mouse_down_handler() **********/ + +int GLUI_EditText::mouse_down_handler( int local_x, int local_y ) +{ + int tmp_insertion_pt; + + if ( debug ) dump( stdout, "-> MOUSE DOWN" ); + + tmp_insertion_pt = find_insertion_pt( local_x, local_y ); + if ( tmp_insertion_pt == -1 ) { + if ( glui ) + glui->deactivate_current_control( ); + return false; + } + + insertion_pt = tmp_insertion_pt; + + sel_start = sel_end = insertion_pt; + + if ( can_draw()) + update_and_draw_text(); + + if ( debug ) dump( stdout, "<- MOUSE UP" ); + + return true; +} + + +/******************************** GLUI_EditText::mouse_up_handler() **********/ + +int GLUI_EditText::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + return false; +} + + +/***************************** GLUI_EditText::mouse_held_down_handler() ******/ + +int GLUI_EditText::mouse_held_down_handler( int local_x, int local_y, + bool new_inside) +{ + int tmp_pt; + + if ( NOT new_inside ) + return false; + + if ( debug ) dump( stdout, "-> HELD DOWN" ); + + tmp_pt = find_insertion_pt( local_x, local_y ); + + if ( tmp_pt == -1 AND sel_end != 0 ) { /* moved mouse past left edge */ + special_handler( GLUT_KEY_LEFT, GLUT_ACTIVE_SHIFT ); + } + else if ( tmp_pt == substring_end+1 AND sel_end != (int) text.length()) { + /* moved mouse past right edge */ + special_handler( GLUT_KEY_RIGHT, GLUT_ACTIVE_SHIFT ); + } + else if ( tmp_pt != -1 AND tmp_pt != sel_end ) { + sel_end = insertion_pt = tmp_pt; + + update_and_draw_text(); + } + + if ( debug ) + dump( stdout, "<- HELD DOWN" ); + + return false; +} + + +/****************************** GLUI_EditText::key_handler() **********/ + +int GLUI_EditText::key_handler( unsigned char key,int modifiers ) +{ + int i, regular_key; + /* int has_selection; */ + + if ( NOT glui ) + return false; + + if ( debug ) + dump( stdout, "-> KEY HANDLER" ); + + regular_key = false; + bool ctrl_down = (modifiers & GLUT_ACTIVE_CTRL)!=0; + /* has_selection = (sel_start != sel_end); */ + + if ( key == CTRL('m') ) { /* RETURN */ + /* glui->deactivate_current_control(); */ + deactivate(); /** Force callbacks, etc **/ + activate(GLUI_ACTIVATE_TAB); /** Reselect all text **/ + redraw(); + return true; + } + else if ( key == CTRL('[')) { /* ESCAPE */ + glui->deactivate_current_control(); + return true; + } + else if ( (key == 127 AND !ctrl_down) OR /* FORWARD DELETE */ + ( key == CTRL('d') AND modifiers == GLUT_ACTIVE_CTRL) ) + { + if ( sel_start == sel_end ) { /* no selection */ + if ( insertion_pt < (int)text.length() ) { + /*** See if we're deleting a period in a float data-type box ***/ + if ( data_type == GLUI_EDITTEXT_FLOAT AND text[insertion_pt]=='.' ) + num_periods--; + + /*** Shift over string first ***/ + text.erase(insertion_pt,1); + } + } + else { /* There is a selection */ + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + } + else if ( ((key == 127) AND ctrl_down) OR // Delete word forward + ((key == 'd') AND (modifiers == GLUT_ACTIVE_ALT)) ) + { + if ( sel_start == sel_end ) { /* no selection */ + sel_start = insertion_pt; + sel_end = find_word_break( insertion_pt, +1 ); + } + + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + else if ( key == CTRL('h') ) { /* BACKSPACE */ + if ( sel_start == sel_end ) { /* no selection */ + if ( insertion_pt > 0 ) { + /*** See if we're deleting a period in a float data-type box ***/ + if ( data_type == GLUI_EDITTEXT_FLOAT AND text[insertion_pt-1]=='.' ) + num_periods--; + + /*** Shift over string first ***/ + insertion_pt--; + text.erase(insertion_pt,1); + } + } + else { /* There is a selection */ + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + } + else if ( modifiers == GLUT_ACTIVE_CTRL ) /* CTRL ONLY */ + { + /* Ctrl-key bindings */ + if ( key == CTRL('a') ) { + return special_handler( GLUT_KEY_HOME, 0 ); + } + else if ( key == CTRL('e') ) { + return special_handler( GLUT_KEY_END, 0 ); + } + else if ( key == CTRL('b') ) { + return special_handler( GLUT_KEY_LEFT, 0 ); + } + else if ( key == CTRL('f') ) { + return special_handler( GLUT_KEY_RIGHT, 0 ); + } + else if ( key == CTRL('p') ) { + return special_handler( GLUT_KEY_UP, 0 ); + } + else if ( key == CTRL('n') ) { + return special_handler( GLUT_KEY_DOWN, 0 ); + } + else if ( key == CTRL('u') ) { /* ERASE LINE */ + insertion_pt = 0; + text.erase(0,text.length()); + sel_start = sel_end = 0; + } + else if ( key == CTRL('k') ) { /* KILL TO END OF LINE */ + sel_start = sel_end = insertion_pt; + text.erase(insertion_pt,GLUI_String::npos); + } + } + else if ( modifiers == GLUT_ACTIVE_ALT ) /* ALT ONLY */ + { + if ( key == 'b' ) { // Backward word + return special_handler ( GLUT_KEY_LEFT, GLUT_ACTIVE_CTRL ); + } + if ( key == 'f' ) { // Forward word + return special_handler ( GLUT_KEY_RIGHT, GLUT_ACTIVE_CTRL ); + } + } + else if ( (modifiers & GLUT_ACTIVE_CTRL) OR + (modifiers & GLUT_ACTIVE_ALT) ) + { + /** ignore other keys with modifiers */ + return true; + } + else { /* Regular key */ + regular_key = true; + + /** Check if we only accept numbers **/ + if (data_type == GLUI_EDITTEXT_FLOAT ) { + if ( (key < '0' OR key > '9') AND key != '.' AND key != '-' ) + return true; + + if ( key == '-' ) { /* User typed a '-' */ + + /* If user has first character selected, then '-' is allowed */ + if ( NOT ( MIN(sel_start,sel_end) == 0 AND + MAX(sel_start,sel_end) > 0 ) ) { + + /* User does not have 1st char selected */ + if (insertion_pt != 0 OR text[0] == '-' ) { + return true; /* Can only place negative at beginning of text, + and only one of them */ + } + } + } + + if ( key == '.' ) { + /*printf( "PERIOD: %d\n", num_periods ); */ + + if ( num_periods > 0 ) { + /** We're trying to type a period, but the text already contains + a period. Check whether the period is contained within + is current selection (thus it will be safely replaced) **/ + + int period_found = false; + if ( sel_start != sel_end ) { + for( i=MIN(sel_end,sel_start); i '9') AND key != '-' ) + return true; + + if ( key == '-' ) { /* User typed a '-' */ + + /* If user has first character selected, then '-' is allowed */ + if ( NOT ( MIN(sel_start,sel_end) == 0 AND + MAX(sel_start,sel_end) > 0 ) ) { + + /* User does not have 1st char selected */ + if (insertion_pt != 0 OR text[0] == '-' ) { + return true; /* Can only place negative at beginning of text, + and only one of them */ + } + } + } + } + + /** This is just to get rid of warnings - the flag regular_key is + set if the key was not a backspace, return, whatever. But I + believe if we're here, we know it was a regular key anyway */ + if ( regular_key ) { + } + + /**** If there's a current selection, erase it ******/ + if ( sel_start != sel_end ) { + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + + /******** We insert the character into the string ***/ + + text.insert(insertion_pt,1,key); + + /******** Move the insertion point and substring_end one over ******/ + insertion_pt++; + substring_end++; + + sel_start = sel_end = insertion_pt; + } + + /******** Now redraw text ***********/ + /* Hack to prevent text box from being cleared first **/ + /** int substring_change = update_substring_bounds(); + draw_text_only = + (NOT substring_change AND NOT has_selection AND regular_key ); + */ + + draw_text_only = false; /** Well, hack is not yet working **/ + update_and_draw_text(); + draw_text_only = false; + + + if ( debug ) + dump( stdout, "<- KEY HANDLER" ); + + /*** Now look to see if this string has a period ***/ + num_periods = 0; + for( i=0; i<(int)text.length(); i++ ) + if ( text[i] == '.' ) + num_periods++; + + return true; +} + + +/****************************** GLUI_EditText::activate() **********/ + +void GLUI_EditText::activate( int how ) +{ + if ( debug ) + dump( stdout, "-> ACTIVATE" ); + + active = true; + + if ( how == GLUI_ACTIVATE_MOUSE ) + return; /* Don't select everything if activated with mouse */ + + orig_text = text; + + sel_start = 0; + sel_end = (int)text.length(); + insertion_pt = 0; + + if ( debug ) + dump( stdout, "<- ACTIVATE" ); +} + + +/****************************** GLUI_EditText::deactivate() **********/ + +void GLUI_EditText::deactivate( void ) +{ + int new_int_val; + float new_float_val; + + active = false; + + if ( NOT glui ) + return; + + if ( debug ) + dump( stdout, "-> DISACTIVATE" ); + + sel_start = sel_end = insertion_pt = -1; + + /***** Retrieve the current value from the text *****/ + /***** The live variable will be updated by set_text() ****/ + if ( data_type == GLUI_EDITTEXT_FLOAT ) { + if ( text.length() == 0 ) /* zero-length string - make it "0.0" */ + text = "0.0"; + + new_float_val = atof( text.c_str() ); + + set_float_val( new_float_val ); + } + else if ( data_type == GLUI_EDITTEXT_INT ) { + if ( text.length() == 0 ) /* zero-length string - make it "0" */ + text = "0"; + + new_int_val = atoi( text.c_str() ); + + set_int_val( new_int_val ); + } + else + if ( data_type == GLUI_EDITTEXT_TEXT ) { + set_text(text); /* This will force callbacks and gfx refresh */ + } + + update_substring_bounds(); + + /******** redraw text without insertion point ***********/ + redraw(); + + /***** Now do callbacks if value changed ******/ + if ( orig_text != text ) { + this->execute_callback(); + + if ( 0 ) { + /* THE CODE BELOW IS FROM WHEN SPINNER ALSO MAINTAINED CALLBACKS */ + if ( spinner == NULL ) { /** Are we independent of a spinner? **/ + if ( callback ) { + callback( this ); + } + } + else { /* We're attached to a spinner */ + spinner->do_callbacks(); /* Let the spinner do the callback stuff */ + } + } + } + + if ( debug ) + dump( stdout, "<- DISACTIVATE" ); +} + +/****************************** GLUI_EditText::draw() **********/ + +void GLUI_EditText::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int name_x; + + name_x = MAX(text_x_offset - string_width(this->name) - 3,0); + draw_name( name_x , 13); + + glBegin( GL_LINES ); + glColor3f( .5, .5, .5 ); + glVertex2i( text_x_offset, 0 ); glVertex2i( w, 0 ); + glVertex2i( text_x_offset, 0 ); glVertex2i( text_x_offset, h ); + + glColor3f( 1., 1., 1. ); + glVertex2i( text_x_offset, h ); glVertex2i( w, h ); + glVertex2i( w, h ); glVertex2i( w, 0 ); + + if ( enabled ) + glColor3f( 0., 0., 0. ); + else + glColor3f( .25, .25, .25 ); + glVertex2i( text_x_offset+1, 1 ); glVertex2i( w-1, 1 ); + glVertex2i( text_x_offset+1, 1 ); glVertex2i( text_x_offset+1, h-1 ); + + glColor3f( .75, .75, .75 ); + glVertex2i( text_x_offset+1, h-1 ); glVertex2i( w-1, h-1 ); + glVertex2i( w-1, h-1 ); glVertex2i( w-1, 1 ); + glEnd(); + + /** Find where to draw the text **/ + update_substring_bounds(); + draw_text(0,0); + + draw_insertion_pt(); +} + + + +/************************** GLUI_EditText::update_substring_bounds() *********/ + +int GLUI_EditText::update_substring_bounds( void ) +{ + int box_width; + int text_len = (int)text.length(); + int old_start, old_end; + + old_start = substring_start; + old_end = substring_end; + + /*** Calculate the width of the usable area of the edit box ***/ + box_width = MAX( this->w - this->text_x_offset + - 4 /* 2 * the two-line box border */ + - 2 * GLUI_EDITTEXT_BOXINNERMARGINX, 0 ); + + CLAMP( substring_end, 0, MAX(text_len-1,0) ); + CLAMP( substring_start, 0, MAX(text_len-1,0) ); + + if ( debug ) dump( stdout, "-> UPDATE SS" ); + + if ( insertion_pt >= 0 AND + insertion_pt < substring_start ) { /* cursor moved left */ + substring_start = insertion_pt; + + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_end--; + } + else if ( insertion_pt > substring_end ) { /* cursor moved right */ + substring_end = insertion_pt-1; + + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_start++; + } + else { /* cursor is within old substring bounds */ + if ( last_insertion_pt > insertion_pt ) { /* cursor moved left */ + } + else { + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_end--; + + while(substring_end < text_len-1 + AND substring_width( substring_start, substring_end ) <= box_width) + substring_end++; + } + } + + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_end--; + + last_insertion_pt = insertion_pt; + + /*** No selection if not enabled ***/ + if ( NOT enabled ) { + sel_start = sel_end = 0; + } + + if ( debug ) dump( stdout, "<- UPDATE SS" ); + + if ( substring_start == old_start AND substring_end == old_end ) + return false; /*** bounds did not change ***/ + else + return true; /*** bounds did change ***/ +} + + +/********************************* GLUI_EditText::update_x_offsets() *********/ + +void GLUI_EditText::update_x_offsets( void ) +{ +} + + +/********************************* GLUI_EditText::draw_text() ****************/ + +void GLUI_EditText::draw_text( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int text_x, i, sel_lo, sel_hi; + + if ( debug ) dump( stdout, "-> DRAW_TEXT" ); + + if ( NOT draw_text_only ) { + if ( enabled ) + glColor3f( 1., 1., 1. ); + else + set_to_bkgd_color(); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( text_x_offset+2, 2 ); glVertex2i( w-2, 2 ); + glVertex2i( w-2, h-2 ); glVertex2i( text_x_offset+2, h-2 ); + glEnd(); + } + + /** Find where to draw the text **/ + + text_x = text_x_offset + 2 + GLUI_EDITTEXT_BOXINNERMARGINX; + + /*printf( "text_x: %d substr_width: %d start/end: %d/%d\n", + text_x, substring_width( substring_start, substring_end ), + substring_start, substring_end ); + */ + /** Find lower and upper selection bounds **/ + sel_lo = MIN(sel_start, sel_end ); + sel_hi = MAX(sel_start, sel_end ); + + int sel_x_start, sel_x_end, delta; + + /** Draw selection area dark **/ + if ( sel_start != sel_end ) { + sel_x_start = text_x; + sel_x_end = text_x; + for( i=substring_start; i<=substring_end; i++ ) { + delta = char_width( text[i] ); + + if ( i < sel_lo ) { + sel_x_start += delta; + sel_x_end += delta; + } + else if ( i < sel_hi ) { + sel_x_end += delta; + } + } + + glColor3f( 0.0f, 0.0f, .6f ); + glBegin( GL_QUADS ); + glVertex2i( sel_x_start, 2 ); glVertex2i( sel_x_end, 2 ); + glVertex2i( sel_x_end, h-2 ); glVertex2i( sel_x_start, h-2 ); + glEnd(); + } + + + if ( sel_start == sel_end ) { /* No current selection */ + if ( enabled ) + glColor3b( 0, 0, 0 ); + else + glColor3b( 32, 32, 32 ); + + glRasterPos2i( text_x, 13); + for( i=substring_start; i<=substring_end; i++ ) { + glutBitmapCharacter( get_font(), this->text[i] ); + } + } + else { /* There is a selection */ + int x = text_x; + for( i=substring_start; i<=substring_end; i++ ) { + if ( IN_BOUNDS( i, sel_lo, sel_hi-1)) { /* This character is selected */ + glColor3f( 1., 1., 1. ); + glRasterPos2i( x, 13); + glutBitmapCharacter( get_font(), this->text[i] ); + } + else { + glColor3f( 0., 0., 0. ); + glRasterPos2i( x, 13); + glutBitmapCharacter( get_font(), this->text[i] ); + } + + x += char_width( text[i] ); + } + } + + if ( debug ) dump( stdout, "<- DRAW_TEXT" ); +} + + +/******************************** GLUI_EditText::find_insertion_pt() *********/ +/* This function returns the character numer *before which* the insertion */ +/* point goes */ + +int GLUI_EditText::find_insertion_pt( int x, int y ) +{ + int curr_x, i; + + /*** See if we clicked outside box ***/ + if ( x < this->x_abs + text_x_offset ) + return -1; + + /* We move from right to left, looking to see if the mouse was clicked + to the right of the ith character */ + + curr_x = this->x_abs + text_x_offset + + substring_width( substring_start, substring_end ) + + 2 /* The edittext box has a 2-pixel margin */ + + GLUI_EDITTEXT_BOXINNERMARGINX; /** plus this many pixels blank space + between the text and the box **/ + + /*** See if we clicked in an empty box ***/ + if ( (int) text.length() == 0 ) + return 0; + + /** find mouse click in text **/ + for( i=substring_end; i>=substring_start; i-- ) { + curr_x -= char_width( text[i] ); + + if ( x > curr_x ) { + /* printf( "-> %d\n", i ); */ + + return i+1; + } + } + + return 0; + + /* Well, the mouse wasn't after any of the characters...see if it's + before the beginning of the substring */ + if ( 0 ) { + if ( x > (x_abs + text_x_offset + 2 ) ) + return substring_start; + + return -1; /* Nothing found */ + } +} + + +/******************************** GLUI_EditText::draw_insertion_pt() *********/ + +void GLUI_EditText::draw_insertion_pt( void ) +{ + int curr_x, i; + + if ( NOT can_draw() ) + return; + + /*** Don't draw insertion pt if control is disabled ***/ + if ( NOT enabled ) + return; + + if ( debug ) dump( stdout, "-> DRAW_INS_PT" ); + + if ( sel_start != sel_end OR insertion_pt < 0 ) { + return; /* Don't draw insertion point if there is a current selection */ + } + + /* printf( "insertion pt: %d\n", insertion_pt ); */ + + curr_x = this->x_abs + text_x_offset + + substring_width( substring_start, substring_end ) + + 2 /* The edittext box has a 2-pixel margin */ + + GLUI_EDITTEXT_BOXINNERMARGINX; /** plus this many pixels blank space + between the text and the box **/ + + for( i=substring_end; i>=insertion_pt; i-- ) { + curr_x -= char_width( text[i] ); + } + + glColor3f( 0.0, 0.0, 0.0 ); + glBegin( GL_LINE_LOOP ); + /*** + glVertex2i( curr_x, y_abs + 4 ); + glVertex2i( curr_x, y_abs + 4 ); + glVertex2i( curr_x, y_abs + h - 3 ); + glVertex2i( curr_x, y_abs + h - 3 ); + ***/ + curr_x -= x_abs; + glVertex2i( curr_x, 0 + 4 ); + glVertex2i( curr_x, 0 + 4 ); + glVertex2i( curr_x, 0 + h - 3 ); + glVertex2i( curr_x, 0 + h - 3 ); + glEnd(); + + if ( debug ) dump( stdout, "-> DRAW_INS_PT" ); +} + + + +/******************************** GLUI_EditText::substring_width() *********/ + +int GLUI_EditText::substring_width( int start, int end ) +{ + int i, width; + + width = 0; + + for( i=start; i<=end; i++ ) + width += char_width( text[i] ); + + return width; +} + + +/***************************** GLUI_EditText::update_and_draw_text() ********/ + +void GLUI_EditText::update_and_draw_text( void ) +{ + if ( NOT can_draw() ) + return; + + update_substring_bounds(); + /* printf( "ss: %d/%d\n", substring_start, substring_end ); */ + + redraw(); +} + + +/********************************* GLUI_EditText::special_handler() **********/ + +int GLUI_EditText::special_handler( int key,int modifiers ) +{ + if ( NOT glui ) + return false; + + if ( debug ) + printf( "SPECIAL:%d - mod:%d subs:%d/%d ins:%d sel:%d/%d\n", + key, modifiers, substring_start, substring_end,insertion_pt, + sel_start, sel_end ); + + if ( key == GLUT_KEY_LEFT ) { + if ( (modifiers & GLUT_ACTIVE_CTRL) != 0 ) { + insertion_pt = find_word_break( insertion_pt, -1 ); + } + else { + insertion_pt--; + } + } + else if ( key == GLUT_KEY_RIGHT ) { + if ( (modifiers & GLUT_ACTIVE_CTRL) != 0 ) { + insertion_pt = find_word_break( insertion_pt, +1 ); + } + else { + insertion_pt++; + } + } + else if ( key == GLUT_KEY_HOME ) { + insertion_pt = 0; + } + else if ( key == GLUT_KEY_END ) { + insertion_pt = (int) text.length(); + } + + /*** Update selection if shift key is down ***/ + if ( (modifiers & GLUT_ACTIVE_SHIFT ) != 0 ) + sel_end = insertion_pt; + else + sel_start = sel_end = insertion_pt; + + + CLAMP( insertion_pt, 0, (int) text.length()); /* Make sure insertion_pt + is in bounds */ + CLAMP( sel_start, 0, (int) text.length()); /* Make sure insertion_pt + is in bounds */ + CLAMP( sel_end, 0, (int) text.length()); /* Make sure insertion_pt + is in bounds */ + + /******** Now redraw text ***********/ + if ( can_draw()) + update_and_draw_text(); + + return true; +} + + +/****************************** GLUI_EditText::find_word_break() **********/ +/* It looks either left or right (depending on value of 'direction' */ +/* for the beginning of the next 'word', where word are characters */ +/* separated by one of the following tokens: " :-.," */ +/* If there is no next word in the specified direction, this returns */ +/* the beginning of 'text', or the very end. */ + +int GLUI_EditText::find_word_break( int start, int direction ) +{ + int i, j; + const char *breaks = " :-.,"; + int num_break_chars = (int)strlen(breaks), text_len = (int)text.length(); + int new_pt; + + /** If we're moving left, we have to start two back, in case we're either + already at the beginning of a word, or on a separating token. + Otherwise, this function would just return the word we're already at **/ + if ( direction == -1 ) { + start -= 2; + } + + /***** Iterate over text in the specified direction *****/ + for ( i=start; i >= 0 AND i < text_len; i += direction ) { + + /** For each character in text, iterate over list of separating tokens **/ + for( j=0; j 0 ) /* Return the end of string */ + return text_len; + else /* Return the beginning of the text */ + return 0; +} + + +/********************************** GLUI_EditText::clear_substring() ********/ + +void GLUI_EditText::clear_substring( int start, int end ) +{ + int i; + + /* + printf( "clearing: %d-%d '", start,end); + for(i=start;ifloat_val = this->float_val; + spinner->int_val = this->int_val; + } + + /*** Now update the live variable ***/ + output_live(true); +} + + +/******************************* GLUI_EditText::set_float_val() ************/ + +void GLUI_EditText::set_float_val( float new_val ) +{ + if ( has_limits == GLUI_LIMIT_CLAMP ) { + /*** Clamp the new value to the existing limits ***/ + + CLAMP( new_val, float_low, float_high ); + } + else if ( has_limits == GLUI_LIMIT_WRAP ) { + /*** Clamp the value cyclically to the limits - that is, if the + value exceeds the max, set it the the minimum, and conversely ***/ + + if ( new_val < float_low ) + new_val = float_high; + if ( new_val > float_high ) + new_val = float_low; + } + + float_val = new_val; + int_val = (int) new_val; /* Mirror the value as an int, too */ + + set_numeric_text(); +} + + +/********************************** GLUI_EditText::set_int_val() ************/ + +void GLUI_EditText::set_int_val( int new_val ) +{ + if ( has_limits == GLUI_LIMIT_CLAMP ) { + /*** Clamp the new value to the existing limits ***/ + + CLAMP( new_val, int_low, int_high ); + } + else if ( has_limits == GLUI_LIMIT_WRAP ) { + /*** Clamp the value cyclically to the limits - that is, if the + value exceeds the max, set it the the minimum, and conversely ***/ + + if ( new_val < int_low ) + new_val = int_high; + if ( new_val > int_high ) + new_val = int_low; + } + + int_val = new_val; + float_val = (float) new_val; /* We mirror the value as a float, too */ + + set_numeric_text(); +} + + +/********************************* GLUI_EditText::set_float_limits() *********/ + +void GLUI_EditText::set_float_limits( float low, float high, int limit_type ) +{ + has_limits = limit_type; + float_low = low; + float_high = high; + + if ( NOT IN_BOUNDS( float_val, float_low, float_high )) + set_float_val( float_low ); + + int_low = (int) float_low; + int_high = (int) float_high; +} + + +/*********************************** GLUI_EditText::set_int_limits() *********/ + +void GLUI_EditText::set_int_limits( int low, int high, int limit_type ) +{ + has_limits = limit_type; + int_low = low; + int_high = high; + + if ( NOT IN_BOUNDS( int_val, int_low, int_high )) + set_int_val( int_low ); + + float_low = (float) int_low; + float_high = (float) int_high; +} + + +/************************************ GLUI_EditText::set_numeric_text() ******/ + +void GLUI_EditText::set_numeric_text( void ) +{ + char buf_num[200]; + int i, text_len; + + if ( data_type == GLUI_EDITTEXT_FLOAT ) { + sprintf( buf_num, "%#g", float_val ); + + num_periods = 0; + text_len = (int) strlen(buf_num); + for ( i=0; i 0 ) { + text_len = (int) strlen(buf_num); + for ( i=text_len-1; i>0; i-- ) { + if ( buf_num[i] == '0' AND buf_num[i-1] != '.' ) + buf_num[i] = '\0'; + else + break; + } + } + set_text( buf_num ); + } + else { + sprintf( buf_num, "%d", int_val ); + set_text( buf_num ); + } + +} + + +/*************************************** GLUI_EditText::dump() **************/ + +void GLUI_EditText::dump( FILE *out, const char *name ) +{ + fprintf( out, + "%s (edittext@%p): ins_pt:%d subs:%d/%d sel:%d/%d len:%d\n", + name, this, + insertion_pt, + substring_start, + substring_end, + sel_start, + sel_end, + (int) text.length()); +} + + +/**************************************** GLUI_EditText::mouse_over() ********/ + +int GLUI_EditText::mouse_over( int state, int x, int y ) +{ + if ( state ) { + /* curr_cursor = GLUT_CURSOR_TEXT; */ + glutSetCursor( GLUT_CURSOR_TEXT ); + } + else { + /* printf( "OUT\n" ); */ + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); + } + + return true; +} diff --git a/Extras/glui/glui_filebrowser.cpp b/Extras/glui/glui_filebrowser.cpp new file mode 100644 index 0000000..81361cb --- /dev/null +++ b/Extras/glui/glui_filebrowser.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_filebrowser.cpp - GLUI_FileBrowser control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. + +*****************************************************************************/ + +#include "GL/glui.h" +#include "glui_internal.h" +#include + +#ifdef __GNUC__ +#include +#include +#endif + +#ifdef _WIN32 +#include +#endif + +#include + +GLUI_FileBrowser::GLUI_FileBrowser( GLUI_Node *parent, + const char *name, + int type, + int id, + GLUI_CB cb) +{ + common_init(); + + set_name( name ); + user_id = id; + int_val = type; + callback = cb; + + parent->add_control( this ); + list = new GLUI_List(this, true, 1); + list->set_object_callback( GLUI_FileBrowser::dir_list_callback, this ); + list->set_click_type(GLUI_DOUBLE_CLICK); + this->fbreaddir(this->current_dir.c_str()); +} + +/****************************** GLUI_FileBrowser::draw() **********/ + +void GLUI_FileBrowser::dir_list_callback(GLUI_Control *glui_object) { + GLUI_List *list = glui_object->dynamicCastGLUI_List(); + if (!list) + return; + GLUI_FileBrowser* me = list->associated_object->dynamicCastGLUI_FileBrowser(); + if (!me) + return; + int this_item; + const char *selected; + this_item = list->get_current_item(); + if (this_item > 0) { /* file or directory selected */ + selected = list->get_item_ptr( this_item )->text.c_str(); + if (selected[0] == '/' || selected[0] == '\\') { + if (me->allow_change_dir) { +#ifdef __GNUC__ + chdir(selected+1); +#endif +#ifdef _WIN32 + SetCurrentDirectory(selected+1); +#endif + me->fbreaddir("."); + } + } else { + me->file = selected; + me->execute_callback(); + } + } +} + + + +void GLUI_FileBrowser::fbreaddir(const char *d) { + GLUI_String item; + int i = 0; + + if (!d) + return; + +#ifdef _WIN32 + + WIN32_FIND_DATA FN; + HANDLE hFind; + //char search_arg[MAX_PATH], new_file_path[MAX_PATH]; + //sprintf(search_arg, "%s\\*.*", path_name); + + hFind = FindFirstFile("*.*", &FN); + if (list) { + list->delete_all(); + if (hFind != INVALID_HANDLE_VALUE) { + do { + int len = int(strlen(FN.cFileName)); + if (FN.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + item = '\\'; + item += FN.cFileName; + } else { + item = FN.cFileName; + } + list->add_item(i,item.c_str()); + i++; + } while (FindNextFile(hFind, &FN) != 0); + + if (GetLastError() == ERROR_NO_MORE_FILES) + FindClose(&FN); + else + perror("fbreaddir"); + } + } + +#elif defined(__GNUC__) + + DIR *dir; + struct dirent *dirp; + struct stat dr; + + if (list) { + list->delete_all(); + if ((dir = opendir(d)) == NULL) + perror("fbreaddir:"); + else { + while ((dirp = readdir(dir)) != NULL) /* open directory */ + { + if (!lstat(dirp->d_name,&dr) && S_ISDIR(dr.st_mode)) /* dir is directory */ + item = dirp->d_name + GLUI_String("/"); + else + item = dirp->d_name; + + list->add_item(i,item.c_str()); + i++; + } + closedir(dir); + } + } +#endif +} + +void ProcessFiles(const char *path_name) +{ + +} + + +void GLUI_FileBrowser::set_w(int w) +{ + if (list) list->set_w(w); +} + +void GLUI_FileBrowser::set_h(int h) +{ + if (list) list->set_h(h); +} diff --git a/Extras/glui/glui_internal.h b/Extras/glui/glui_internal.h new file mode 100644 index 0000000..147b65c --- /dev/null +++ b/Extras/glui/glui_internal.h @@ -0,0 +1,107 @@ +#ifndef GLUI_INTERNAL_H +#define GLUI_INTERNAL_H + +#include +#include + + + +#ifndef AND +#define AND && +#define OR || +#define NOT ! +#endif + +#ifndef MAX +#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define MIN(a,b) ((a)<(b) ? (a) : (b)) +#endif + +#ifndef ABS +#define ABS(a) ((a)>=0 ? (a) : (-(a))) +#endif + +/******************** bit comparisons and operations ***************/ +#ifndef TEST_BIT +#define TEST_BIT( x, b ) (((x) & (1<<(b))) != 0 ) +#define SET_BIT( x, b ) ((x) |= (1 << (b))) +#define CLEAR_BIT( x, b ) ((x) &= ~(1 << (b))) +#define TOGGLE_BIT( x, b ) ((TEST_BIT(x,b)) ?(CLEAR_BIT(x,b)):(SET_BIT(x,b))) +#endif + +#ifndef TEST_AND +#define TEST_AND( a, b ) ((a&b)==b) +#endif + + +#ifndef M_PI +#define M_PI 3.141592654 +#endif + +/*********** flush the stdout and stderr output streams *************/ +#ifndef flushout +#define flushout fflush(stdout) +#define flusherr fflush(stderr) +#endif + +/********** Debugging functions *************************************/ +#ifndef error_return +#define error_return( c ); {fprintf(stderr,c);return;} +#endif + +/************************* floating-point random ********************/ +#ifndef randf +#define randf() ((float) rand() / (float)RAND_MAX ) +#endif + +#ifndef SIGN +#define SIGN(x) ((x)>=0 ? 1 : -1) +#endif + +/****************** conversion between degrees and radians **********/ +#ifndef DEG2RAD +#define DEG2RAD(x) ((x)/180.0*M_PI) +#define RAD2DEG(x) ((x)/M_PI*180.0) +#endif + +/***************** clamp a value to some fixed interval *************/ +#ifndef CLAMP +#define CLAMP(x,lo,hi) {if ((x) < (lo)) {(x)=(lo);} else if((x) > (hi)) {(x)=(hi);}} +#endif + +/************ check if a value lies within a closed interval *********/ +#ifndef IN_BOUNDS +#define IN_BOUNDS( x, lo, hi ) ( (x) >= (lo) AND (x) <= (hi) ) +#endif + +/************ check if a 2D point lies within a 2D box ***************/ +#ifndef PT_IN_BOX +#define PT_IN_BOX( x, y, lo_x, hi_x, lo_y, hi_y ) \ +( IN_BOUNDS(x,lo_x,hi_x) AND IN_BOUNDS(y,lo_y,hi_y) ) +#endif + +/****** check if value lies on proper side of another value *****/ +/*** if side is positive => proper side is positive, else negative **/ +#ifndef CHECK_PROPER_SIDE +#define CHECK_PROPER_SIDE(x,val,side) ((side) > 0 ? (x) > (val) : (x) < (val)) +#endif + + +/***** Small value when we want to do a comparison to 'close to zero' *****/ +#ifndef FUDGE +#define FUDGE .00001 +#endif + + +/******************* swap two values, using a temp variable *********/ +#ifndef SWAP2 +#define SWAP2(a,b,t) {t=a;a=b;b=t;} +#endif + +#define VEC3_TO_ARRAY(v,a) a[0]=v[0], a[1]=v[1], a[2]=v[2] + +/**** Return the ASCII control code given the non-control ASCII character */ +#define CTRL(c) ( (c>=('a'-1)) ? (c-'a'+1) : (c-'A'+1) ) + + +#endif /* GLUI_INTERNAL_H */ diff --git a/Extras/glui/glui_internal_control.h b/Extras/glui/glui_internal_control.h new file mode 100644 index 0000000..7e363aa --- /dev/null +++ b/Extras/glui/glui_internal_control.h @@ -0,0 +1,45 @@ +/* + Header file for use by GLUI controls. + Everything you need is right here. + + +*/ +#ifndef __GLUI_INTERNAL_CONTROL_H +#define __GLUI_INTERNAL_CONTROL_H + +/* This is the main GLUI external header */ +#include "GL/glui.h" + +/* Here's some utility routines */ +#include "glui_internal.h" + + +/** + A GLUI_Control-drawing sentinal object. + On creation, saves the current draw buffer and window. + On destruction, restores draw buffer and window. + This is way nicer than calling save/restore manually. +*/ +class GLUI_DrawingSentinal { + int orig_buf, orig_win; + GLUI_Control *c; +public: + /** The constructor sets up the drawing system */ + GLUI_DrawingSentinal(GLUI_Control *c_); + /** The destructor cleans up drawing back how it was */ + ~GLUI_DrawingSentinal(); + + // Do-nothing routine to avoid compiler warning about unused variable + inline void avoid_warning(void) {} +}; +/** Just drop a GLUI_DRAWINGSENTINAL_IDIOM at the start of your draw methods, +and they'll return if we can't be drawn, and +automatically save and restore all needed state. +*/ +#define GLUI_DRAWINGSENTINAL_IDIOM if (NOT can_draw()) return; GLUI_DrawingSentinal drawSentinal(this); drawSentinal.avoid_warning(); + + +/** Return the time, in seconds. */ +inline double GLUI_Time(void) {return 0.001*glutGet(GLUT_ELAPSED_TIME);} + +#endif diff --git a/Extras/glui/glui_list.cpp b/Extras/glui/glui_list.cpp new file mode 100644 index 0000000..f0ffd47 --- /dev/null +++ b/Extras/glui/glui_list.cpp @@ -0,0 +1,542 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_list.cpp - GLUI_List control class + + + -------------------------------------------------- + + Copyright (c) 2004 John Kew + + This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. + +*****************************************************************************/ + + + +#include "glui_internal_control.h" +#include +#include + +/****************************** GLUI_List::GLUI_List() **********/ + +GLUI_List::GLUI_List( GLUI_Node *parent, bool scroll, + int id, GLUI_CB callback + /*,GLUI_Control *object + GLUI_InterObject_CB obj_cb*/) +{ + common_construct(parent, NULL, scroll, id, callback/*, object, obj_cb*/); +} + +/****************************** GLUI_List::GLUI_List() **********/ + +GLUI_List::GLUI_List( GLUI_Node *parent, + GLUI_String& live_var, bool scroll, + int id, + GLUI_CB callback + /* ,GLUI_Control *object + ,GLUI_InterObject_CB obj_cb*/ ) +{ + common_construct(parent, &live_var, scroll, id, callback/*, object, obj_cb*/); +} + +/****************************** GLUI_List::common_construct() **********/ + +void GLUI_List::common_construct( + GLUI_Node *parent, + GLUI_String* data, bool scroll, + int id, + GLUI_CB callback + /*,GLUI_Control *object + , GLUI_InterObject_CB obj_cb*/) +{ + common_init(); + GLUI_Node *list_panel = parent; + + if (scroll) { + GLUI_Panel *p = new GLUI_Panel(parent,"",GLUI_PANEL_NONE); + p->x_off = 1; + list_panel = p; + } + this->ptr_val = data; + if (data) { + this->live_type = GLUI_LIVE_STRING; + } + this->user_id = id; + this->callback = callback; + this->name = "list"; + list_panel->add_control( this ); + if (scroll) + { + new GLUI_Column(list_panel, false); + scrollbar = + new GLUI_Scrollbar(list_panel, + "scrollbar", + GLUI_SCROLL_VERTICAL, + GLUI_SCROLL_INT); + scrollbar->set_object_callback(GLUI_List::scrollbar_callback, this); + scrollbar->set_alignment(GLUI_ALIGN_LEFT); + // scrollbar->can_activate = false; //kills ability to mouse drag too + } + init_live(); +} + +/****************************** GLUI_List::mouse_down_handler() **********/ +int GLUI_List::mouse_down_handler( int local_x, int local_y ) +{ + int tmp_line; + unsigned long int ms; + timeb time; + ftime(&time); + ms = time.millitm + (time.time)*1000; + + tmp_line = find_line( local_x-x_abs, local_y-y_abs-5 ); + if ( tmp_line == -1 ) { + if ( glui ) + glui->deactivate_current_control( ); + return false; + } + + if (tmp_line < num_lines) { + curr_line = tmp_line; + if (scrollbar) + scrollbar->set_int_val(curr_line); + this->execute_callback(); + if (associated_object != NULL) + if (cb_click_type == GLUI_SINGLE_CLICK) { + if (obj_cb) { + // obj_cb(associated_object, user_id); + obj_cb(this); + } + } else { + if (last_line == curr_line && (ms - last_click_time) < 300) { + //obj_cb(associated_object, user_id); + obj_cb(this); + } else { + last_click_time = ms; + last_line = curr_line; + } + } + if ( can_draw()) + update_and_draw_text(); + } + + return true; +} + + + + +/******************************** GLUI_List::mouse_up_handler() **********/ + +int GLUI_List::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + return false; +} + + +/***************************** GLUI_List::mouse_held_down_handler() ******/ + +int GLUI_List::mouse_held_down_handler( int local_x, int local_y, + bool new_inside) +{ + return false; +} + + +/****************************** GLUI_List::key_handler() **********/ + +int GLUI_List::key_handler( unsigned char key,int modifiers ) +{ + + + draw_text_only = false; /** Well, hack is not yet working **/ + update_and_draw_text(); + draw_text_only = false; + + return true; +} + + +/****************************** GLUI_List::activate() **********/ + +void GLUI_List::activate( int how ) +{ +// if ( debug ) +// dump( stdout, "-> ACTIVATE" ); + active = true; + + if ( how == GLUI_ACTIVATE_MOUSE ) + return; /* Don't select everything if activated with mouse */ + +} + + +/****************************** GLUI_List::deactivate() **********/ + +void GLUI_List::deactivate( void ) +{ + active = false; + redraw(); +} + +/****************************** GLUI_List::draw() **********/ + +void GLUI_List::draw( int x, int y ) +{ + int line = 0; + int box_width; + GLUI_List_Item *item; + + GLUI_DRAWINGSENTINAL_IDIOM + + /* Bevelled Border */ + glBegin( GL_LINES ); + glColor3f( .5, .5, .5 ); + glVertex2i( 0, 0 ); glVertex2i( w, 0 ); + glVertex2i( 0, 0 ); glVertex2i( 0, h ); + + glColor3f( 1., 1., 1. ); + glVertex2i( 0, h ); glVertex2i( w, h ); + glVertex2i( w, h ); glVertex2i( w, 0 ); + + if ( enabled ) + glColor3f( 0., 0., 0. ); + else + glColor3f( .25, .25, .25 ); + glVertex2i( 1, 1 ); glVertex2i( w-1, 1 ); + glVertex2i( 1, 1 ); glVertex2i( 1, h-1 ); + + glColor3f( .75, .75, .75 ); + glVertex2i( 1, h-1 ); glVertex2i( w-1, h-1 ); + glVertex2i( w-1, h-1 ); glVertex2i( w-1, 1 ); + glEnd(); + + /* Draw Background if enabled*/ + if (enabled) { + glColor3f( 1., 1., 1. ); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( 2, 2 ); glVertex2i( w-2, 2 ); + glVertex2i( w-2, h-2 ); glVertex2i(2, h-2 ); + glEnd(); + } else { + glColor3f( .8, .8, .8 ); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( 2, 2 ); glVertex2i( w-2, 2 ); + glVertex2i( w-2, h-2 ); glVertex2i(2, h-2 ); + glEnd(); + } + + /* Figure out how wide the box is */ + box_width = get_box_width(); + + /* Figure out which lines are visible*/ + + visible_lines = (int)(h-20)/15; + + item = (GLUI_List_Item *) items_list.first_child(); + + line = 0; + while (item) { + if (line < start_line) { + line++; + item = (GLUI_List_Item *) item->next(); + continue; + } + if (line >= start_line && line <= (start_line+visible_lines)) { + if (curr_line == line) + draw_text(item->text.c_str(),1,0,(line - start_line)*15); + else + draw_text(item->text.c_str(),0,0,(line - start_line)*15); + } + line++; + item = (GLUI_List_Item *) item->next(); + } + + if (scrollbar) { + scrollbar->set_int_limits(MAX(0,num_lines-visible_lines), 0); + glPushMatrix(); + glTranslatef(scrollbar->x_abs-x_abs, scrollbar->y_abs-y_abs,0.0); + scrollbar->draw_scroll(); + glPopMatrix(); + } +} + +/********************************* GLUI_List::draw_text() ****************/ + +void GLUI_List::draw_text(const char *t, int selected, int x, int y ) +{ + int text_x, i, x_pos; + int box_width; + + GLUI_DRAWINGSENTINAL_IDIOM + + /** Find where to draw the text **/ + + text_x = 2 + GLUI_LIST_BOXINNERMARGINX; + + /** Draw selection area dark **/ + if ( enabled && selected ) { + glColor3f( 0.0f, 0.0f, .6f ); + glBegin( GL_QUADS ); + glVertex2i(text_x, y+5 ); glVertex2i( w-text_x, y+5 ); + glVertex2i(w-text_x, y+19 ); glVertex2i(text_x, y+19 ); + glEnd(); + } + box_width = get_box_width(); + + if ( !selected || !enabled ) { /* No current selection */ + x_pos = text_x; /* or control disabled */ + if ( enabled ) + glColor3b( 0, 0, 0 ); + else + glColor3b( 32, 32, 32 ); + + glRasterPos2i( text_x, y+15); + i = 0; + while( t[i] != '\0' && substring_width(t,0,i) < box_width) { + glutBitmapCharacter( get_font(), t[i] ); + x_pos += char_width( t[i] ); + i++; + } + } + else { /* There is a selection */ + i = 0; + x_pos = text_x; + glColor3f( 1., 1., 1. ); + glRasterPos2i( text_x, y+15); + while( t[i] != '\0' && substring_width(t,0,i) < box_width) { + glutBitmapCharacter( get_font(), t[i] ); + x_pos += char_width( t[i] ); + i++; + } + } +} + + +int GLUI_List::find_line(int x, int y) { + return start_line + ((int)(y/15)); +} + +int GLUI_List::get_box_width() { + return MAX( this->w + - 6 /* 2 * the two-line box border */ + - 2 * GLUI_LIST_BOXINNERMARGINX, 0 ); + +} + +/******************************** GLUI_List::substring_width() *********/ +int GLUI_List::substring_width( const char *t, int start, int end ) +{ + int i, width; + + width = 0; + + for( i=start; i<=end; i++ ) + width += char_width( t[i] ); + + return width; +} + + +/***************************** GLUI_List::update_and_draw_text() ********/ + +void GLUI_List::update_and_draw_text( void ) +{ + if ( NOT can_draw() ) + return; + + //update_substring_bounds(); + /* printf( "ss: %d/%d\n", substring_start, substring_end ); */ + + redraw(); +} + + +/********************************* GLUI_List::special_handler() **********/ + +int GLUI_List::special_handler( int key,int modifiers ) +{ + if ( NOT glui ) + return false; + + if ( key == GLUT_KEY_DOWN ) { + if (curr_line < num_lines) { + curr_line++; + if (curr_line > start_line+visible_lines) + start_line++; + } + } else if ( key == GLUT_KEY_UP ) { + if (curr_line > 0) { + curr_line--; + if (curr_line < start_line) + start_line--; + } + } + + if (scrollbar) + scrollbar->set_int_val(curr_line); + redraw(); + return true; +} + + +/************************************ GLUI_List::update_size() **********/ + +void GLUI_List::update_size( void ) +{ + if ( NOT glui ) + return; + + if ( w < GLUI_LIST_MIN_TEXT_WIDTH ) + w = GLUI_LIST_MIN_TEXT_WIDTH; +} + +/**************************************** GLUI_Listbox::add_item() **********/ + +int GLUI_List::add_item( int id, const char *new_text ) +{ + GLUI_List_Item *new_node = new GLUI_List_Item; + GLUI_List_Item *head; + + new_node->text = new_text; + new_node->id = id; + + head = (GLUI_List_Item*) items_list.first_child(); + new_node->link_this_to_parent_last( &items_list ); + + if ( head == NULL ) { + /*** This is first item added ***/ + + int_val = id+1; /** Different than id **/ + // do_selection( id ); + last_live_int = id; + + if( glui ) + glui->post_update_main_gfx(); + } + num_lines++; + if (scrollbar) + scrollbar->set_int_limits(MAX(num_lines-visible_lines,0), 0); + + return true; +} + +/************************************** GLUI_Listbox::delete_() **********/ + +int GLUI_List::delete_all() +{ + GLUI_List_Item *item; + + item = (GLUI_List_Item *) items_list.first_child(); + while( item ) { + item->unlink(); + delete item; + item = (GLUI_List_Item *) items_list.first_child(); + } + + num_lines = 0; + curr_line = 0; + + return true; +} + + +/************************************** GLUI_Listbox::delete_item() **********/ + +int GLUI_List::delete_item( const char *text ) +{ + GLUI_List_Item *node = get_item_ptr( text ); + + if ( node ) { + node->unlink(); + delete node; + num_lines--; + return true; + } + else { + return false; + } +} + + +/************************************** GLUI_Listbox::delete_item() **********/ + +int GLUI_List::delete_item( int id ) +{ + GLUI_List_Item *node = get_item_ptr( id ); + + if ( node ) { + node->unlink(); + delete node; + num_lines--; + return true; + } + else { + return false; + } +} + + +/************************************ GLUI_Listbox::get_item_ptr() **********/ + +GLUI_List_Item *GLUI_List::get_item_ptr( const char *text ) +{ + GLUI_List_Item *item; + + item = (GLUI_List_Item *) items_list.first_child(); + while( item ) { + if ( item->text == text ) + return item; + + item = (GLUI_List_Item *) item->next(); + } + + return NULL; +} + + +/************************************ GLUI_Listbox::get_item_ptr() **********/ + +GLUI_List_Item *GLUI_List::get_item_ptr( int id ) +{ + GLUI_List_Item *item; + + item = (GLUI_List_Item *) items_list.first_child(); + while( item ) { + if ( item->id == id ) + return item; + + item = (GLUI_List_Item *) item->next(); + } + + return NULL; +} + +/**************************************** GLUI_List::mouse_over() ********/ + +int GLUI_List::mouse_over( int state, int x, int y ) +{ + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); + + return true; +} + +void GLUI_List::scrollbar_callback(GLUI_Control *my_scrollbar) { + GLUI_Scrollbar *sb = my_scrollbar->dynamicCastGLUI_Scrollbar(); + if (!sb) return; + GLUI_List* me = (GLUI_List*) sb->associated_object; + if (me->scrollbar == NULL) + return; + int new_start_line = sb->get_int_val(); // TODO!! + me->start_line = new_start_line; + + if ( me->can_draw() ) + me->update_and_draw_text(); +} diff --git a/Extras/glui/glui_listbox.cpp b/Extras/glui/glui_listbox.cpp new file mode 100644 index 0000000..1bf1276 --- /dev/null +++ b/Extras/glui/glui_listbox.cpp @@ -0,0 +1,448 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_listbox - GLUI_ListBox control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +/****************************** GLUI_Listbox::GLUI_Listbox() **********/ +GLUI_Listbox::GLUI_Listbox( GLUI_Node *parent, + const char *name, int *value_ptr, + int id, + GLUI_CB cb) +{ + common_init(); + set_ptr_val( value_ptr ); + user_id = id; + set_name( name ); + callback = cb; + + parent->add_control( this ); + + init_live(); +} + + +/****************************** GLUI_Listbox::mouse_down_handler() **********/ + +int GLUI_Listbox::mouse_down_handler( int local_x, int local_y ) +{ + return false; +} + + +/****************************** GLUI_Listbox::mouse_up_handler() **********/ + +int GLUI_Listbox::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + + return false; +} + + +/****************************** GLUI_Listbox::mouse_held_down_handler() ******/ + +int GLUI_Listbox::mouse_held_down_handler( int local_x, int local_y, + bool inside) +{ + + return false; +} + + +/****************************** GLUI_Listbox::key_handler() **********/ + +int GLUI_Listbox::key_handler( unsigned char key,int modifiers ) +{ + return false; +} + + +/****************************** GLUI_Listbox::draw() **********/ + +void GLUI_Listbox::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int name_x; + + /* draw_active_area(); */ + + name_x = MAX(text_x_offset - string_width(this->name) - 3,0); + draw_name( name_x , 13); + draw_box_inwards_outline( text_x_offset, w, + 0, h ); + + if ( NOT active ) { + draw_box( text_x_offset+3, w-2, 2, h-2, 1.0, 1.0, 1.0 ); + if ( NOT enabled ) + glColor3b( 32, 32, 32 ); + else + glColor3f( 0.0, 0.0, 0.0 ); + glRasterPos2i( text_x_offset+5, 13 ); + draw_string( curr_text ); + } + else { + draw_box( text_x_offset+3, w-2, 2, h-2, .0, .0, .6 ); + glColor3f( 1.0, 1.0, 1.0 ); + glRasterPos2i( text_x_offset+5, 13 ); + draw_string( curr_text ); + } + + + if ( enabled ) { + glui->std_bitmaps. + draw(GLUI_STDBITMAP_LISTBOX_UP, + w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1, + 2 ); + } + else { + glui->std_bitmaps. + draw(GLUI_STDBITMAP_LISTBOX_UP_DIS, + w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1, + 2 ); + } +} + + +/************************************ GLUI_Listbox::update_si() **********/ +void GLUI_Listbox::update_size( void ) +{ + recalculate_item_width(); +} + +/********************************* GLUI_Listbox::set_int_val() **************/ + +void GLUI_Listbox::set_int_val( int new_val ) +{ + /* int_val = new_val; */ + + do_selection( new_val ); + + /*** Update the variable we're (possibly) pointing to, and update the main gfx ***/ + output_live(true); +} + +/**************************************** GLUI_Listbox::add_item() **********/ + +int GLUI_Listbox::add_item( int id, const char *new_text ) +{ + GLUI_Listbox_Item *new_node = new GLUI_Listbox_Item; + GLUI_Listbox_Item *head; + + new_node->text = new_text; + new_node->id = id; + + head = (GLUI_Listbox_Item*) items_list.first_child(); + new_node->link_this_to_parent_last( &items_list ); + + if ( head == NULL ) { + /*** This is first item added ***/ + + int_val = id+1; /** Different than id **/ + do_selection( id ); + last_live_int = id; + + if( glui ) + glui->post_update_main_gfx(); + } + if (recalculate_item_width()) glui->refresh(); + + return true; +} + + +/************************************** GLUI_Listbox::delete_item() **********/ + +int GLUI_Listbox::delete_item( const char *text ) +{ + GLUI_Listbox_Item *node = get_item_ptr(text); + + if (node) + { + node->unlink(); + delete node; + return true; + } + if (recalculate_item_width()) glui->refresh(); + + return false; +} + + +/************************************** GLUI_Listbox::delete_item() **********/ + +int GLUI_Listbox::delete_item(int id) +{ + GLUI_Listbox_Item *node = get_item_ptr(id); + + if (node) + { + node->unlink(); + delete node; + return true; + } + if (recalculate_item_width()) glui->refresh(); + + return false; +} + + +/************************************** GLUI_Listbox::sort_items() **********/ + +int GLUI_Listbox::sort_items( void ) +{ + return false; +} + + +/********************************************* GLUI_Listbox::dump() **********/ + +void GLUI_Listbox::dump( FILE *output ) +{ + GLUI_Listbox_Item *item; + + /* printf( "%p\n", (char*) name ); */ + + fprintf( output, "Listbox: %s\n", name.c_str() ); + + item = (GLUI_Listbox_Item *) items_list.first_child(); + while( item ) { + fprintf( output, " %3d : %s\n", item->id, item->text.c_str() ); + + item = (GLUI_Listbox_Item *) item->next(); + } +} + + +/************************************ GLUI_Listbox::get_item_ptr() **********/ + +GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( const char *text ) +{ + GLUI_Listbox_Item *item; + + item = (GLUI_Listbox_Item *) items_list.first_child(); + while( item ) { + if ( item->text == text ) + return item; + + item = (GLUI_Listbox_Item *) item->next(); + } + + return NULL; +} + + +/************************************ GLUI_Listbox::get_item_ptr() **********/ + +GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( int id ) +{ + GLUI_Listbox_Item *item; + + item = (GLUI_Listbox_Item *) items_list.first_child(); + while( item ) { + if ( item->id == id ) + return item; + + item = (GLUI_Listbox_Item *) item->next(); + } + + return NULL; +} + + +/************************************ GLUI_Listbox::mouse_over() **********/ + +static void listbox_callback( int i ) +{ + int old_val; + + if ( NOT GLUI_Master.curr_left_button_glut_menu OR + !GLUI_Master.curr_left_button_glut_menu->dynamicCastGLUI_Listbox() ) + return; + + old_val = ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val; + ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->set_int_val(i); + + /**** If value changed, execute callback ****/ + if ( old_val != + ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val ) { + ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->execute_callback(); + } +} + + +/*************************************** GLUI_Listbox::mouse_over() **********/ + +int GLUI_Listbox::mouse_over( int state, int x, int y ) +{ + GLUI_Listbox_Item *item; + + /* printf( "x/y: %d/%d\n", x, y ); */ + + if ( state AND enabled AND x > x_abs + text_x_offset) { + /**** Build a GLUT menu for this listbox ***/ + + /* printf( "%d %d\n", x, y ); */ + + glut_menu_id = glutCreateMenu(listbox_callback); + + item = (GLUI_Listbox_Item *) items_list.first_child(); + while( item ) { + glutAddMenuEntry( item->text.c_str(), item->id ); + item = (GLUI_Listbox_Item *) item->next(); + } + + glutAttachMenu( GLUT_LEFT_BUTTON); + + GLUI_Master.set_left_button_glut_menu_control( this ); + } + else if ( glut_menu_id != -1 ) { + /* printf( "OUT\n" ); */ + glutDetachMenu( GLUT_LEFT_BUTTON ); + glutDestroyMenu( glut_menu_id ); + glut_menu_id = -1; + } + + return true; +} + + +/************************************ GLUI_Listbox::do_selection() **********/ + +int GLUI_Listbox::do_selection( int item_num ) +{ + GLUI_Listbox_Item *item, *sel_item; + + /*** Is this item already selected? ***/ + if ( item_num == int_val ) + return false; + + sel_item = NULL; + item = (GLUI_Listbox_Item *) items_list.first_child(); + while( item ) { + if ( item->id == item_num ) { + sel_item = item; + break; + } + + item = (GLUI_Listbox_Item *) item->next(); + } + + if ( NOT sel_item ) + return false; + + /* printf( "-> %s\n", (char*) sel_item->text ); */ + + int_val = item_num; + curr_text = sel_item->text; + redraw(); + + return true; +} + + +/*********************************** GLUI_Listbox::~GLUI_Listbox() **********/ + +GLUI_Listbox::~GLUI_Listbox() +{ + GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child(); + + while (item) + { + GLUI_Listbox_Item *tmp = item; + item = (GLUI_Listbox_Item *) item->next(); + delete tmp; + } +} + +/****************************** GLUI_Listbox::special_handler() **********/ + +int GLUI_Listbox::special_handler( int key,int modifiers ) +{ + GLUI_Listbox_Item *node, *new_node; + + node = get_item_ptr( int_val ); + new_node = NULL; + + if ( key == GLUT_KEY_DOWN ) { + new_node = (GLUI_Listbox_Item*) node->next(); + } + else if ( key == GLUT_KEY_UP ) { + new_node = (GLUI_Listbox_Item*) node->prev(); + } + else if ( key == GLUT_KEY_HOME ) { + new_node = (GLUI_Listbox_Item*) items_list.first_child(); + } + else if ( key == GLUT_KEY_END ) { + new_node = (GLUI_Listbox_Item*) items_list.last_child(); + } + + if ( new_node != NULL AND new_node != node ) { + node = new_node; + set_int_val( node->id ); + execute_callback(); + return true; + } + else { + return false; + } +} + + +/************************* GLUI_Listbox::recalculate_item_width( void ) ***********/ +/** Change w and return true if we need to be widened to fit the current items. */ +bool GLUI_Listbox::recalculate_item_width( void ) +{ + int item_text_size; + + if ( NOT glui ) + return false; + + /* Find the title size */ + text_x_offset = string_width( name ); + + /* Find the longest item string ***/ + item_text_size = 0; + + GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child(); + while( item ) { + item_text_size = MAX(item_text_size,string_width(item->text)); + item = (GLUI_Listbox_Item *) item->next(); + } + + /* Sum up our layout: name, item, and drop-down marker */ + int new_wid=text_x_offset+MAX(GLUI_EDITTEXT_MIN_TEXT_WIDTH,item_text_size)+20; + if ( w != new_wid) { + w = new_wid; + return true; /* we gotta be shortened or widened */ + } + else { + return false; /* our current width is OK */ + } +} diff --git a/Extras/glui/glui_mouse_iaction.cpp b/Extras/glui/glui_mouse_iaction.cpp new file mode 100644 index 0000000..0acd69f --- /dev/null +++ b/Extras/glui/glui_mouse_iaction.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_mouse_iaction - GLUI Mouse Interaction control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +/********************** GLUI_Mouse_Interaction::mouse_down_handler() ******/ + +int GLUI_Mouse_Interaction::mouse_down_handler( int local_x, int local_y ) +{ + /* int win_h = glutGet( GLUT_WINDOW_HEIGHT ); */ + + /* iaction_mouse_down_handler( local_x, local_y ); */ + iaction_mouse_down_handler( local_x-x_abs, local_y-y_abs ); + /*local_x-x_abs, ((glui->h-local_y)-y_abs) ); */ + redraw(); + + return false; +} + + +/**************************** GLUI_Mouse_Interaction::mouse_up_handler() */ + +int GLUI_Mouse_Interaction::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + iaction_mouse_up_handler( local_x-x_abs, local_y-y_abs, inside ); + return false; +} + + +/****************************** GLUI_Mouse_Interaction::mouse_held_down_handler() ******/ + +int GLUI_Mouse_Interaction::mouse_held_down_handler( int local_x, int local_y, + bool inside) +{ + iaction_mouse_held_down_handler( local_x-x_abs, local_y-y_abs , inside ); + + redraw(); + + /** Tell the main graphics window to update iteself **/ + if( glui ) + glui->post_update_main_gfx(); + + execute_callback(); + + return false; +} + + + +/****************************** GLUI_Mouse_Interaction::draw() **********/ + +void GLUI_Mouse_Interaction::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int text_width = string_width( this->name ); + int x_left = this->w/2 - text_width/2; + + if ( NOT draw_active_area_only ) { + draw_name( x_left, h-4 ); + draw_active_box( x_left-4, x_left+string_width( name )+4, + h, h-14 ); + } + + draw_active_area(); +} + + +/************************************ GLUI_Mouse_Interaction::update_size() **********/ + +void GLUI_Mouse_Interaction::update_size( void ) +{ + if ( NOT glui ) + return; + + int text_width = string_width( this->name ); + + if ( w < text_width+6 ) + w = text_width+6; + + if ( h - 18 > w ) + w = h - 18; + + iaction_init(); +} + + +/****************************** GLUI_Mouse_Interaction::special_handler() **********/ + +int GLUI_Mouse_Interaction::special_handler( int key,int modifiers ) +{ + int center_x, center_y; + int drag_x, drag_y; + + center_x = w/2; + center_y = (h-18)/2; + drag_x = 0; + drag_y = 0; + + if ( key == GLUT_KEY_LEFT ) + drag_x = -6; + else if ( key == GLUT_KEY_RIGHT ) + drag_x = 6; + else if ( key == GLUT_KEY_UP ) + drag_y = -6; + else if ( key == GLUT_KEY_DOWN ) + drag_y = 6; + + if ( drag_x != 0 OR drag_y != 0 ) { + mouse_down_handler( center_x, center_y ); + mouse_held_down_handler( center_x + drag_x, center_y + drag_y,true ); + mouse_up_handler( center_x + drag_x, center_y + drag_y, true ); + } + + return false; +} + + +/****************************** GLUI_Mouse_Interaction::draw_active_area() **********/ + +void GLUI_Mouse_Interaction::draw_active_area( void ) +{ + int win_h = glutGet( GLUT_WINDOW_HEIGHT ), win_w = glutGet(GLUT_WINDOW_WIDTH); + + int text_height = 18; /* what a kludge */ + + int viewport_size = h-text_height; /*MIN(w,h); */ + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 ); + glRotatef( 180.0, 0.0, 1.0, 0.0 ); + glRotatef( 180.0, 0.0, 0.0, 1.0 ); + glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 ); + + glTranslatef( (float) this->x_abs + .5, (float) this->y_abs + .5, 0.0 ); + + glTranslatef( (float)this->w/2.0, (float)viewport_size/2.0 + 2.0 , 0.0 ); + + /*** Draw the interaction control's orthographic elements ***/ + iaction_draw_active_area_ortho(); + + /*** Setup and draw the interaction control's perspective elements ***/ + + /*** Set the viewport to just the square of the drawing area ***/ + /* glViewport( this->x_abs , glui->main_panel->h - this->y_abs - this->h,*/ + /*glViewport( this->x_abs+1+(this->w/2-viewport_size/2), + this->h-this->y_abs-viewport_size-1, + viewport_size, viewport_size );*/ + + viewport_size -= 4; + int offset = 0; + if ( ((this->w-viewport_size) % 2) == 1 ) + offset = 1; + + glViewport( this->x_abs + (this->w-viewport_size)/2 + offset, + win_h - this->y_abs - this->h + text_height, + viewport_size, viewport_size ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + double xy=1.00,zc=50.0; /* X-Y size, and Z origin */ + glFrustum( -1.0*xy, 1.0*xy, -xy, xy, zc*0.7, zc*1.3 ); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -zc ); + glScalef(xy,xy,1.0); // xy); + + /* glutSolidTeapot( 1.0 ); */ + iaction_draw_active_area_persp(); + + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); + + glui->set_viewport(); + glui->set_ortho_projection(); + + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); +} + diff --git a/Extras/glui/glui_node.cpp b/Extras/glui/glui_node.cpp new file mode 100644 index 0000000..a943332 --- /dev/null +++ b/Extras/glui/glui_node.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_node.cpp - linked-list tree structure + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "GL/glui.h" +#include "glui_internal.h" + +/********************************************* GLUI_Node::GLUI_Node() *******/ + +GLUI_Node::GLUI_Node() +: + parent_node(NULL), + child_head(NULL), + child_tail(NULL), + next_sibling(NULL), + prev_sibling(NULL) +{ +} + +/********************************************* GLUI_Node::first() *******/ +/* Returns first sibling in 'this' node's sibling list */ + +GLUI_Node *GLUI_Node::first_sibling( void ) +{ + if ( parent_node == NULL ) + return this; /* root node has no siblings */ + else + return parent_node->child_head; +} + + +/******************************************** GLUI_Node::next() ********/ +/* Returns next sibling in 'this' node's sibling list */ + +GLUI_Node *GLUI_Node::next( void ) +{ + return next_sibling; +} + + +/******************************************** GLUI_Node::prev() ********/ +/* Returns prev sibling in 'this' node's sibling list */ + +GLUI_Node *GLUI_Node::prev( void ) +{ + return prev_sibling; +} + + +/********************************************* GLUI_Node::last() *******/ +/* Returns last sibling in 'this' node's sibling list */ + +GLUI_Node *GLUI_Node::last_sibling( void ) +{ + if ( parent_node == NULL ) + return this; /* root node has no siblings */ + else + return parent_node->child_tail; +} + + +/*************************** GLUI_Node::link_this_to_parent_last() *******/ +/* Links as last child of parent */ + +void GLUI_Node::link_this_to_parent_last( GLUI_Node *new_parent ) +{ + if ( new_parent->child_tail == NULL ) { /* parent has no children */ + new_parent->child_head = this; + new_parent->child_tail = this; + this->parent_node = new_parent; + } + else { /* parent has children */ + new_parent->child_tail->next_sibling = this; + this->prev_sibling = new_parent->child_tail; + new_parent->child_tail = this; + this->parent_node = new_parent; + } +} + + +/*************************** GLUI_Node::link_this_to_parent_first() *******/ +/* Links as first child of parent */ + +void GLUI_Node::link_this_to_parent_first( GLUI_Node *new_parent ) +{ + if ( new_parent->child_head == NULL ) { /* parent has no children */ + new_parent->child_head = this; + new_parent->child_tail = this; + this->parent_node = new_parent; + } + else { /* parent has children */ + new_parent->child_head->prev_sibling = this; + this->next_sibling = new_parent->child_head; + new_parent->child_head = this; + this->parent_node = new_parent; + } +} + +/**************************** GLUI_Node::link_this_to_sibling_next() *****/ + +void GLUI_Node::link_this_to_sibling_next( GLUI_Node *sibling ) +{ + if ( sibling->next_sibling == NULL ) { /* node has no next sibling */ + sibling->next_sibling = this; + this->prev_sibling = sibling; + + /* This was the parent's last child, so update that as well */ + if ( sibling->parent_node != NULL ) { + sibling->parent_node->child_tail = this; + } + } + else { /* node already has a next sibling */ + sibling->next_sibling->prev_sibling = this; + this->next_sibling = sibling->next_sibling; + sibling->next_sibling = this; + this->prev_sibling = sibling; + } + + this->parent_node = sibling->parent_node; +} + + +/**************************** GLUI_Node::link_this_to_sibling_prev() *****/ + +void GLUI_Node::link_this_to_sibling_prev( GLUI_Node *sibling ) +{ + if ( sibling->prev_sibling == NULL ) { /* node has no prev sibling */ + sibling->prev_sibling = this; + this->next_sibling = sibling; + + /* This was the parent's first child, so update that as well */ + if ( sibling->parent_node != NULL ) { + sibling->parent_node->child_head = this; + } + } + else { /* node already has a prev sibling */ + sibling->prev_sibling->next_sibling = this; + this->prev_sibling = sibling->prev_sibling; + sibling->prev_sibling = this; + this->next_sibling = sibling; + } + + this->parent_node = sibling->parent_node; +} + +/**************************************** GLUI_Node::unlink() **************/ + +void GLUI_Node::unlink( void ) +{ + /* Unlink from prev sibling */ + if ( this->prev_sibling != NULL ) { + this->prev_sibling->next_sibling = this->next_sibling; + } + else { /* No prev sibling: this was parent's first child */ + this->parent_node->child_head = this->next_sibling; + } + + /* Unlink from next sibling */ + if ( this->next_sibling != NULL ) { + this->next_sibling->prev_sibling = this->prev_sibling; + } + else { /* No next sibling: this was parent's last child */ + this->parent_node->child_tail = this->prev_sibling; + } + + this->parent_node = NULL; + this->next_sibling = NULL; + this->prev_sibling = NULL; + this->child_head = NULL; + this->child_tail = NULL; +} + +/**************************************** GLUI_Node::dump() **************/ + +void GLUI_Node::dump( FILE *out, const char *name ) +{ + fprintf( out, "GLUI_node: %s\n", name ); + fprintf( out, " parent: %p child_head: %p child_tail: %p\n", + (void *) parent_node, + (void *) child_head, + (void *) child_tail ); + fprintf( out, " next: %p prev: %p\n", + (void *) next_sibling, + (void *) prev_sibling ); +} diff --git a/Extras/glui/glui_panel.cpp b/Extras/glui/glui_panel.cpp new file mode 100644 index 0000000..3aa61ae --- /dev/null +++ b/Extras/glui/glui_panel.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_panel.cpp - GLUI_Panel control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +GLUI_Panel::GLUI_Panel( GLUI_Node *parent, const char *name, int type ) +{ + common_init(); + set_name( name ); + user_id = -1; + int_val = type; + + parent->add_control( this ); +} + +/****************************** GLUI_Panel::draw() **********/ + +void GLUI_Panel::draw( int x, int y ) +{ + int top; + GLUI_DRAWINGSENTINAL_IDIOM + + if ( int_val == GLUI_PANEL_RAISED ) { + top = 0; + glLineWidth( 1.0 ); + glColor3f( 1.0, 1.0, 1.0 ); + glBegin( GL_LINE_LOOP ); + glVertex2i( 0, top ); glVertex2i( w, top ); + glVertex2i( 0, top ); glVertex2i( 0, h ); + glEnd(); + + glColor3f( .5, .5, .5 ); + glBegin( GL_LINE_LOOP ); + glVertex2i( w, top ); + glVertex2i( w, h ); + glVertex2i( 0, h ); + glVertex2i( w, h ); + glEnd(); + + /** ORIGINAL RAISED PANEL METHOD - A LITTLE TOO HIGH ** + glLineWidth(1.0); + glBegin( GL_LINES ); + glColor3f( 1.0, 1.0, 1.0 ); + glVertex2i( 1, 1 ); glVertex2i( w-2, 1 ); + glVertex2i( 1, 1 ); glVertex2i( 1, h-2 ); + + glColor3f( .5, .5, .5 ); + glVertex2i( w-1, 1 ); glVertex2i( w-1, h-1 ); + glVertex2i( 1, h-1 ); glVertex2i( w-1, h-1 ); + + glColor3f( 0.0, 0.0, 0.0 ); + glVertex2i( 0, h ); glVertex2i( w, h ); + glVertex2i( w, 0 ); glVertex2i( w, h ); + glEnd(); + + -- Touch up the lines a bit (needed in some opengl implementations + glBegin( GL_POINTS ); + glColor3f( .5, .5, .5 ); + glVertex2i( w-1, h-1 ); + glColor3f( 0.0, 0.0, 0.0 ); + glVertex2i( w, h ); + glEnd(); + **/ + } + else if ( int_val == GLUI_PANEL_EMBOSSED ) { + if ( parent_node == NULL || name == "" ) { + top = 0; + } + else { + top = GLUI_PANEL_EMBOSS_TOP; + } + + glLineWidth( 1.0 ); + glColor3f( 1.0, 1.0, 1.0 ); + glBegin( GL_LINE_LOOP ); + glVertex2i( 0, top ); glVertex2i( w, top ); + glVertex2i( w, h ); glVertex2i( 0, h ); + + glVertex2i( 1, top+1 ); glVertex2i( w-1, top+1 ); + glVertex2i( w-1, h-1 ); glVertex2i( 1, h-1 ); + glEnd(); + + glColor3f( .5, .5, .5 ); + glBegin( GL_LINE_LOOP ); + glVertex2i( 0, top ); + glVertex2i( w-1, top ); + glVertex2i( w-1, h-1 ); + glVertex2i( 0, h-1 ); + glEnd(); + + /**** Only display text in embossed panel ****/ + if ( parent_node != NULL && name != "" ) { /* Only draw non-null strings */ + int left = 7, height=GLUI_PANEL_NAME_DROP+1; + int str_width; + + str_width = string_width(name); + + if ( glui ) + glColor3ub(glui->bkgd_color.r,glui->bkgd_color.g,glui->bkgd_color.b); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( left-3, 0 ); glVertex2i( left+str_width+3, 0 ); + glVertex2i( left+str_width+3, height ); glVertex2i( left-3, height ); + glEnd(); + + draw_name( left, GLUI_PANEL_NAME_DROP ); + } + } + + glLineWidth( 1.0 ); +} + +/****************************** GLUI_Panel::set_name() **********/ + +void GLUI_Panel::set_name( const char *new_name ) +{ + name = new_name ? new_name : ""; + + update_size(); + + if ( glui ) + glui->refresh(); +} + + +/****************************** GLUI_Panel::set_type() **********/ + +void GLUI_Panel::set_type( int new_type ) +{ + if ( new_type != int_val ) { + int_val = new_type; + update_size(); + redraw(); + } +} + + +/************************************** GLUI_Panel::update_size() **********/ + +void GLUI_Panel::update_size( void ) +{ + int text_size; + + if ( NOT glui ) + return; + + text_size = string_width(name); + + if ( w < text_size + 16 ) + w = text_size + 16 ; + + if ( name != "" AND int_val == GLUI_PANEL_EMBOSSED ) { + this->y_off_top = GLUI_YOFF + 8; + } + else { + this->y_off_top = GLUI_YOFF; + } +} diff --git a/Extras/glui/glui_radio.cpp b/Extras/glui/glui_radio.cpp new file mode 100644 index 0000000..aef1668 --- /dev/null +++ b/Extras/glui/glui_radio.cpp @@ -0,0 +1,362 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_radio.cpp - GLUI_RadioGroup and GLUI_RadioButton control classes + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" +#include + +/****************************** GLUI_RadioGroup::GLUI_RadioGroup() **********/ + +GLUI_RadioGroup::GLUI_RadioGroup(GLUI_Node *parent, + int *value_ptr, + int id, GLUI_CB cb) +{ + common_init(); + GLUI_String buf; + + set_ptr_val( value_ptr ); + if ( value_ptr ) { + int_val = *value_ptr; /** Can't call set_int_val(), b/c that + function will try to call the + callback, etc */ + /** Actually, maybe not **/ + last_live_int = *value_ptr; + } + + user_id = id; + glui_format_str( buf, "RadioGroup: %p", this ); + set_name( buf.c_str() ); + callback = cb; + + parent->add_control( this ); + + init_live(); +} + + +/****************************** GLUI_RadioGroup::draw() **********/ + +void GLUI_RadioGroup::draw( int x, int y ) +{ + if ( NOT can_draw() ) + return; + + draw_group(false); +} + + +/********************* GLUI_RadioGroup::draw_group(int translate) **********/ + +void GLUI_RadioGroup::draw_group( int translate ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + GLUI_RadioButton *button; + this->int_val = int_val; + + glMatrixMode(GL_MODELVIEW ); + + button = (GLUI_RadioButton*) first_child(); + while( button != NULL ) { + glPushMatrix(); + if (translate) { + button->translate_to_origin(); + } + else { + glTranslatef(button->x_abs-x_abs, + button->y_abs-y_abs,0.0); + } + + if ( button->int_val ) + button->draw_checked(); + else + button->draw_unchecked(); + + glPopMatrix(); + + button = (GLUI_RadioButton*) button->next(); + } +} + + +/****************************** GLUI_RadioGroup::set_name() **********/ + +void GLUI_RadioGroup::set_name( const char *text ) +{ + name = text; + + if ( glui ) + glui->refresh(); +} + + +/********************************* GLUI_RadioGroup::set_selected() **********/ + +void GLUI_RadioGroup::set_selected( int int_val ) +{ + GLUI_RadioButton *button; + + this->int_val = int_val; + + button = (GLUI_RadioButton*) first_child(); + while( button != NULL ) { + if ( int_val == -1 ) { /*** All buttons in group are deselected ***/ + button->set_int_val(0); + } + else if ( int_val == button->user_id ) { /*** This is selected button ***/ + button->set_int_val(1); + } + else { /*** This is NOT selected button ***/ + button->set_int_val(0); + + } + button = (GLUI_RadioButton*) button->next(); + } + redraw(); +} + + +/************************ GLUI_RadioButton::GLUI_RadioButton() **********/ + +GLUI_RadioButton::GLUI_RadioButton( GLUI_RadioGroup *grp, const char *name ) +{ + common_init(); + + set_int_val( 0 ); + + /** A radio button's user id is always its ordinal number (zero-indexed) + within the group */ + user_id = grp->num_buttons; + set_name( name ); + group = grp; + + group->num_buttons++; /* Increments radiogroup's button count */ + group->add_control( this ); + + /*** Now update button states ***/ + group->set_int_val( group->int_val ); /* This tells the group to + reset itself to its + current value, thereby + updating all its buttons */ +} + + +/************************ GLUI_RadioButton::mouse_down_handler() **********/ + +int GLUI_RadioButton::mouse_down_handler( int local_x, int local_y ) +{ + if ( NOT group ) + return false; + + orig_value = group->int_val; + + currently_inside = true; + + group->set_selected( this->user_id ); + redraw(); + + return false; +} + +/********************** GLUI_RadioButton::mouse_held_down_handler() ******/ + +int GLUI_RadioButton::mouse_held_down_handler( int local_x, int local_y, + bool inside) +{ + if (inside != currently_inside) { + if (inside) group->set_selected( this->user_id ); + else group->set_selected( orig_value ); + currently_inside = inside; + redraw(); + } + + return false; +} + + +/*************************** GLUI_RadioButton::mouse_up_handler() **********/ + +int GLUI_RadioButton::mouse_up_handler( int local_x, int local_y, + bool inside ) +{ + if ( NOT group ) + return false; + + if ( NOT inside ) { + group->set_selected( orig_value ); + redraw(); + } + else { + /** Now we update the radio button group. We tell the group + handler to set the currently-selected item to this button, which + is reference by its user_id/ordinal number within group **/ + + group->set_selected( this->user_id ); + redraw(); + + /*** Now update the linked variable, and call the callback, + but ONLY if the value of the radio group actually changed ***/ + if ( group->int_val != orig_value ) { + group->output_live(true); /** Output live and update gfx ***/ + + group->execute_callback(); + } + } + + return false; +} + +/****************************** GLUI_RadioButton::draw() **********/ + +void GLUI_RadioButton::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + if ( NOT group OR NOT can_draw() ) + return; + + /*** See if we're the currently-selected button. If so, draw ***/ + if ( group->int_val == this->user_id ) { + if ( enabled ) + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON, 0, 0 ); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON_DIS, 0, 0 ); + } + else { + if ( enabled ) + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF, 0, 0 ); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF_DIS, 0, 0 ); + } + + draw_active_area(); + + draw_name( text_x_offset, 10 ); +} + + +/************************************ GLUI_RadioButton::draw_checked() ******/ + +void GLUI_RadioButton::draw_checked( void ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + if ( enabled ) + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON, 0, 0 ); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON_DIS, 0, 0 ); + draw_active_area(); +} + + +/*********************************** GLUI_RadioButton::draw_unchecked() ******/ + +void GLUI_RadioButton::draw_unchecked( void ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + if ( enabled ) + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF, 0, 0 ); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF_DIS, 0, 0 ); + draw_active_area(); +} + + +/**************************************** GLUI_RadioButton::draw_O() ********/ + +void GLUI_RadioButton::draw_O( void ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int i, j; + + glBegin( GL_POINTS ); + for(i=3; i<=GLUI_RADIOBUTTON_SIZE-3; i++ ) + for(j=3; j<=GLUI_RADIOBUTTON_SIZE-3; j++ ) + glVertex2i(i,j); + glEnd(); +} + + +/******************************** GLUI_RadioButton::update_size() **********/ + +void GLUI_RadioButton::update_size( void ) +{ + int text_size; + + if ( NOT glui ) + return; + + text_size = _glutBitmapWidthString( glui->font, name.c_str() ); + + /* if ( w < text_x_offset + text_size + 6 ) */ + w = text_x_offset + text_size + 6 ; +} + + +/************************* GLUI_RadioButton::draw_active_area() **************/ + +void GLUI_RadioButton::draw_active_area( void ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int text_width, left, right; + + text_width = _glutBitmapWidthString( glui->font, name.c_str() ); + left = text_x_offset-3; + right = left + 7 + text_width; + + if ( active ) { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0x5555 ); + glColor3f( 0., 0., 0. ); + } else { + glColor3ub( glui->bkgd_color.r, glui->bkgd_color.g, glui->bkgd_color.b ); + } + + glBegin( GL_LINE_LOOP ); + glVertex2i(left,0); glVertex2i( right,0); + glVertex2i(right,h+1); glVertex2i( left,h+1); + glEnd(); + + glDisable( GL_LINE_STIPPLE ); +} + + +/********************************* GLUI_RadioGroup::set_int_val() **********/ + +void GLUI_RadioGroup::set_int_val( int new_val ) +{ + if ( new_val == int_val ) + return; + + set_selected( new_val ); + redraw(); + + output_live(true); + +} diff --git a/Extras/glui/glui_rollout.cpp b/Extras/glui/glui_rollout.cpp new file mode 100644 index 0000000..d29e006 --- /dev/null +++ b/Extras/glui/glui_rollout.cpp @@ -0,0 +1,275 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_panel.cpp - GLUI_Panel control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +enum {rollout_height_pixels=GLUI_DEFAULT_CONTROL_HEIGHT + 7}; + +/****************************** GLUI_Rollout::GLUI_Rollout() **********/ + +GLUI_Rollout::GLUI_Rollout( GLUI_Node *parent, const char *name, + int open, int type ) +{ + common_init(); + set_name( name ); + user_id = -1; + int_val = type; + + if ( NOT open ) { + is_open = false; + h = rollout_height_pixels; + } + + parent->add_control( this ); +} + +/****************************** GLUI_Rollout::open() **********/ + +void GLUI_Rollout::open( void ) +{ + if ( NOT glui ) + return; + + if ( is_open ) + return; + is_open = true; + + GLUI_DRAWINGSENTINAL_IDIOM + + /* Copy hidden children into our private list "collapsed_node" */ + child_head = collapsed_node.child_head; + child_tail = collapsed_node.child_tail; + collapsed_node.child_head = NULL; + collapsed_node.child_tail = NULL; + + if ( child_head != NULL ) { + ((GLUI_Control*) child_head)->unhide_internal( true ); + } + + glui->refresh(); +} + + +/****************************** GLUI_Rollout::close() **********/ + +void GLUI_Rollout::close( void ) +{ + if ( NOT glui ) + return; + + if ( NOT is_open ) + return; + is_open = false; + + GLUI_DRAWINGSENTINAL_IDIOM + + if ( child_head != NULL ) { + ((GLUI_Control*) child_head)->hide_internal( true ); + } + + /* Move all children into a private list of hidden children */ + collapsed_node.child_head = first_child(); + collapsed_node.child_tail = last_child(); + child_head = NULL; + child_tail = NULL; + + this->h = rollout_height_pixels; + + glui->refresh(); +} + + +/**************************** GLUI_Rollout::mouse_down_handler() **********/ + + +int GLUI_Rollout::mouse_down_handler( int local_x, int local_y ) +{ + if ( local_y - y_abs > rollout_height_pixels ) { + initially_inside = currently_inside = false; + return false; + } + + currently_inside = true; + initially_inside = true; + redraw(); + + return false; +} + + +/**************************** GLUI_Rollout::mouse_held_down_handler() ****/ + +int GLUI_Rollout::mouse_held_down_handler( + int local_x, int local_y, + bool new_inside ) +{ + if ( NOT initially_inside ) + return false; + + if ( local_y - y_abs> rollout_height_pixels ) + new_inside = false; + + if (new_inside != currently_inside) { + currently_inside = new_inside; + redraw(); + } + + return false; +} + + +/**************************** GLUI_Rollout::mouse_down_handler() **********/ + +int GLUI_Rollout::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + if ( currently_inside ) { + if ( is_open ) + close(); + else + open(); + } + + currently_inside = false; + initially_inside = false; + redraw(); + + return false; +} + + +/********************************* GLUI_Rollout::draw() ***********/ + +void GLUI_Rollout::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + int left, right, top, bottom; + + left = 5; + right = w-left; + top = 3; + bottom = 3+16; + + if ( is_open ) + draw_emboss_box( 0, w, top+3, h ); + else + draw_emboss_box( 0, w, top+3, h-7 ); + + glui->draw_raised_box( left, top, w-left*2, 16 ); + + if ( glui ) + glColor3ub(glui->bkgd_color.r,glui->bkgd_color.g,glui->bkgd_color.b); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( left+1, top+1 ); glVertex2i( right-1, top+1 ); + glVertex2i( right-1, bottom-1 ); glVertex2i( left+1, bottom-1 ); + glEnd(); + + draw_name( left+8, top+11 ); + + if ( active ) + /*draw_active_box( left+4, left+string_width( name.c_str() )+12, */ + draw_active_box( left+4, right-17, + top+2, bottom-2 ); + + + /** Draw '+' or '-' **/ + + glBegin( GL_LINES ); + if ( is_open ) { + if ( enabled ) glColor3f( 0.0, 0.0, 0.0 ); + else glColor3f( 0.5, 0.5, 0.5 ); + glVertex2i(right-14,(top+bottom)/2); glVertex2i(right-5,(top+bottom)/2); + + glColor3f( 1.0, 1.0, 1.0 ); + glVertex2i(right-14,1+(top+bottom)/2);glVertex2i(right-5,1+(top+bottom)/2); + } + else + { + glColor3f( 1.0, 1.0, 1.0 ); + glVertex2i(right-9,top+3); glVertex2i(right-9,bottom-4); + glVertex2i(right-14,(top+bottom)/2); glVertex2i(right-5,(top+bottom)/2); + + if ( enabled ) glColor3f( 0.0, 0.0, 0.0 ); + else glColor3f( 0.5, 0.5, 0.5 ); + glVertex2i(right-14,-1+(top+bottom)/2); + glVertex2i(right-5,-1+(top+bottom)/2); + glVertex2i(right-10,top+3); + glVertex2i(right-10,bottom-4); + } + glEnd(); + + glLineWidth( 1.0 ); + + if (currently_inside) {draw_pressed(); /* heavy black outline when pressed */ } +} + + +/***************************** GLUI_Rollout::update_size() **********/ + +void GLUI_Rollout::update_size( void ) +{ + int text_size; + + if ( NOT glui ) + return; + + text_size = string_width(name); + + if ( w < text_size + 36 ) + w = text_size + 36; +} + + +/**************************** GLUI_Rollout::draw_pressed() ***********/ + +void GLUI_Rollout::draw_pressed( void ) +{ + int left, right, top, bottom; + + left = 5; + right = w-left; + top = 3; + bottom = 3+16; + + + glColor3f( 0.0, 0.0, 0.0 ); + + glBegin( GL_LINE_LOOP ); + glVertex2i( left, top ); glVertex2i( right, top ); + glVertex2i( right, bottom ); glVertex2i( left,bottom ); + glEnd(); + + glBegin( GL_LINE_LOOP ); + glVertex2i( left+1, top+1 ); glVertex2i( right-1, top+1 ); + glVertex2i( right-1, bottom-1 ); glVertex2i( left+1,bottom-1 ); + glEnd(); +} diff --git a/Extras/glui/glui_rotation.cpp b/Extras/glui/glui_rotation.cpp new file mode 100644 index 0000000..b02d743 --- /dev/null +++ b/Extras/glui/glui_rotation.cpp @@ -0,0 +1,473 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_rotation - GLUI_Rotation control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "GL/glui.h" +#include "arcball.h" +#include "algebra3.h" + +/*************************** GLUI_Rotation::iaction_mouse_down_handler() ***/ + +int GLUI_Rotation::iaction_mouse_down_handler( int local_x, int local_y ) +{ + copy_float_array_to_ball(); + + init_ball(); + + local_y = (int) floor(2.0 * ball->center[1] - local_y); + + ball->mouse_down( local_x, local_y ); + + /* printf( "%d %d - %f %f\n", local_x, local_y, ball->center[0], ball->center[1] ); */ + + copy_ball_to_float_array(); + + spinning = false; + + return false; +} + + +/*********************** GLUI_Rotation::iaction_mouse_up_handler() **********/ + +int GLUI_Rotation::iaction_mouse_up_handler( int local_x, int local_y, + bool inside ) +{ + copy_float_array_to_ball(); + + ball->mouse_up(); + + return false; +} + + +/******************* GLUI_Rotation::iaction_mouse_held_down_handler() ******/ + +int GLUI_Rotation::iaction_mouse_held_down_handler( int local_x, int local_y, + bool inside) +{ + if ( NOT glui ) + return 0; + + copy_float_array_to_ball(); + + local_y = (int) floor(2.0 * ball->center[1] - local_y); + + /* printf( "%d %d\n", local_x, local_y ); */ + + ball->mouse_motion( local_x, local_y, 0, + (glui->curr_modifiers & GLUT_ACTIVE_ALT) != 0, + (glui->curr_modifiers & GLUT_ACTIVE_CTRL) != 0 ); + + copy_ball_to_float_array(); + + if ( can_spin ) + spinning = true; + + return false; +} + + +/******************** GLUI_Rotation::iaction_draw_active_area_persp() **************/ + +void GLUI_Rotation::iaction_draw_active_area_persp( void ) +{ + /********** arcball *******/ + copy_float_array_to_ball(); + + setup_texture(); + setup_lights(); + + glEnable(GL_CULL_FACE ); + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + + mat4 tmp_rot = *ball->rot_ptr; + glMultMatrixf( (float*) &tmp_rot[0][0] ); + + /*** Draw the checkered box ***/ + /*glDisable( GL_TEXTURE_2D ); */ + draw_ball(1.35); // 1.96 ); + + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D,0); /* unhook our checkerboard texture */ + glDisable( GL_TEXTURE_2D ); + glDisable( GL_LIGHTING ); + glDisable( GL_CULL_FACE ); +} + + +/******************** GLUI_Rotation::iaction_draw_active_area_ortho() **********/ + +void GLUI_Rotation::iaction_draw_active_area_ortho( void ) +{ + float radius; + radius = (float)(h-22)/2.0; /*MIN((float)w/2.0, (float)h/2.0); */ + + /********* Draw emboss circles around arcball control *********/ + int k; + glLineWidth( 1.0 ); + glBegin( GL_LINE_LOOP); + for( k=0; k<60; k++ ) { + float phi = 2*M_PI*(float)k/60.0; + vec2 p( cos(phi) * (2.0 + radius), sin(phi) * (2.0 + radius)); + if ( p[1] < -p[0] ) glColor3ub( 128,128,128 ); + else glColor3ub( 255,255,255 ); + glVertex2fv((float*)&p[0]); + } + glEnd(); + + glBegin( GL_LINE_LOOP); + for( k=0; k<60; k++ ) { + float phi = 2*M_PI*(float)k/60.0; + vec2 p( cos(phi) * (1.0 + radius), sin(phi) * (1.0 + radius)); + if ( enabled ) { + if ( p[1] < -p[0] ) glColor3ub( 0,0,0); + else glColor3ub( 192,192,192); + } + else + { + if ( p[1] < -p[0] ) glColor3ub( 180,180,180); + else glColor3ub( 192,192,192); + } + glVertex2fv((float*)&p[0]); + } + glEnd(); +} + + +/******************************** GLUI_Rotation::iaction_dump() **********/ + +void GLUI_Rotation::iaction_dump( FILE *output ) +{ +} + + +/******************** GLUI_Rotation::iaction_special_handler() **********/ + +int GLUI_Rotation::iaction_special_handler( int key,int modifiers ) +{ + + return false; +} + +/********************************** GLUI_Rotation::init_ball() **********/ + +void GLUI_Rotation::init_ball( void ) +{ + /*printf( "%f %f %f", float( MIN(w/2,h/2)), (float) w/2, (float) h/2 ); */ + + ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)), + (float) 2.0*(h-18) ); + /*ball->set_damping( .05 ); */ + /*float( MIN(w/2,h/2))*2.0 ); */ + /* ball->reset_mouse(); */ +} + + +/****************************** GLUI_Rotation::setup_texture() *********/ + +void GLUI_Rotation::setup_texture( void ) +{ + static GLuint tex=0u; + GLenum t=GL_TEXTURE_2D; + glEnable(t); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + glColor3f( 1.0, 1.0, 1.0 ); + if (tex!=0u) { + /* (OSL 2006/06) Just use glBindTexture to avoid having to re-upload the whole checkerboard every frame. */ + glBindTexture(t,tex); + return; + } /* Else need to make a new checkerboard texture */ + glGenTextures(1,&tex); + glBindTexture(t,tex); + glEnable(t); + + unsigned int i, j; + int dark, light; /*** Dark and light colors for ball checkerboard ***/ + +/* Note: you can change the number of checkers across there sphere in draw_ball */ +#define CHECKBOARD_SIZE 64 /* pixels across whole texture */ +#define CHECKBOARD_REPEAT 32u /* pixels across one black/white sector */ + unsigned char texture_image[CHECKBOARD_SIZE] [CHECKBOARD_SIZE] [3]; + unsigned char c; + for( i=0; iinit(); /** reset quaternion, etc. **/ + ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)), + (float) 2.0*(h-18) ); + + set_spin( this->damping ); + + copy_ball_to_float_array(); + + translate_and_draw_front(); + + output_live(true); /*** Output live and draw main grx window ***/ +} + + +/****************************** GLUI_Rotation::needs_idle() *********/ + +bool GLUI_Rotation::needs_idle( void ) const +{ + return can_spin; +} + + +/****************************** GLUI_Rotation::idle() ***************/ + +void GLUI_Rotation::idle( void ) +{ + spinning = ball->is_spinning?true:false; + + if ( can_spin AND spinning ) { + copy_float_array_to_ball(); + ball->idle(); + + *ball->rot_ptr = *ball->rot_ptr * ball->rot_increment; + + mat4 tmp_rot; + tmp_rot = *ball->rot_ptr; + + copy_ball_to_float_array(); + + draw_active_area_only = true; + translate_and_draw_front(); + draw_active_area_only = false; + + output_live(true); /** output live and update gfx **/ + } + else { + } +} + + +/********************** GLUI_Rotation::copy_float_array_to_ball() *********/ + +void GLUI_Rotation::copy_float_array_to_ball( void ) +{ + int i; + float *fp_src, *fp_dst; + + fp_src = &float_array_val[0]; + fp_dst = &((*ball->rot_ptr)[0][0]); + + for( i=0; i<16; i++ ) { + *fp_dst = *fp_src; + + fp_src++; + fp_dst++; + } +} + + +/********************** GLUI_Rotation::copy_ball_to_float_array() *********/ + +void GLUI_Rotation::copy_ball_to_float_array( void ) +{ + mat4 tmp_rot; + tmp_rot = *ball->rot_ptr; + + set_float_array_val( (float*) &tmp_rot[0][0] ); +} + + +/************************ GLUI_Rotation::set_spin() **********************/ + +void GLUI_Rotation::set_spin( float damp_factor ) +{ + if ( damp_factor == 0.0 ) + can_spin = false; + else + can_spin = true; + + ball->set_damping( 1.0 - damp_factor ); + + this->damping = damp_factor; +} + + +/************** GLUI_Rotation::GLUI_Rotation() ********************/ + +GLUI_Rotation::GLUI_Rotation( GLUI_Node *parent, + const char *name, float *value_ptr, + int id, + GLUI_CB cb ) +{ + common_init(); + set_ptr_val( value_ptr ); + user_id = id; + set_name( name ); + callback = cb; + parent->add_control( this ); + init_live(); + + /*** Init the live 4x4 matrix. This is different than the standard + live variable behavior, since the original value of the 4x4 matrix + is ignored and reset to Identity ***/ +/* +NO! WVB + if ( value_ptr != NULL ) { + int i, j, index; + for( i=0; i<4; i++ ) { + for( j=0; j<4; j++ ) { + index = i*4+j; + if ( i==j ) + value_ptr[index] = 1.0; + else + value_ptr[index] = 0.0; + } + } + } +*/ + /*init_ball(); */ + + +} + + +/************** GLUI_Rotation::common_init() ********************/ + +void GLUI_Rotation::common_init( void ) +{ + glui_format_str( name, "Rotation: %p", this ); +// type = GLUI_CONTROL_ROTATION; + w = GLUI_ROTATION_WIDTH; + h = GLUI_ROTATION_HEIGHT; + can_activate = true; + live_type = GLUI_LIVE_FLOAT_ARRAY; + float_array_size = 16; + quadObj = NULL; + alignment = GLUI_ALIGN_CENTER; + can_spin = false; + spinning = false; + damping = 0.0; + ball = new Arcball; + + reset(); +} diff --git a/Extras/glui/glui_scrollbar.cpp b/Extras/glui/glui_scrollbar.cpp new file mode 100644 index 0000000..f0fb137 --- /dev/null +++ b/Extras/glui/glui_scrollbar.cpp @@ -0,0 +1,832 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_scrollbar.cpp - GLUI_Scrollbar class + + -------------------------------------------------- + + Copyright (c) 2004 John Kew, 1998 Paul Rademacher + + This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. + +*****************************************************************************/ + +#include "glui_internal_control.h" +#include +#include + +/*static int __debug=0; */ + +#define GLUI_SCROLL_GROWTH_STEPS 800 +#define GLUI_SCROLL_MIN_GROWTH_STEPS 100 +#define GLUI_SCROLL_CALLBACK_INTERVAL 1 /* Execute the user's callback every this many clicks */ + +enum { + GLUI_SCROLL_ARROW_UP, + GLUI_SCROLL_ARROW_DOWN, + GLUI_SCROLL_ARROW_LEFT, + GLUI_SCROLL_ARROW_RIGHT +}; + + +/****************************** GLUI_Scrollbar::GLUI_Scrollbar() **********/ +// Constructor, no live var +GLUI_Scrollbar::GLUI_Scrollbar( GLUI_Node *parent, + const char *name, + int horz_vert, + int data_type, + int id, GLUI_CB callback + /*,GLUI_Control *object + ,GLUI_InterObject_CB obj_cb*/ + ) +{ + common_construct(parent, name, horz_vert, data_type, NULL, id, callback/*, object, obj_cb*/); +} + +/****************************** GLUI_Scrollbar::GLUI_Scrollbar() **********/ +// Constructor, int live var +GLUI_Scrollbar::GLUI_Scrollbar( GLUI_Node *parent, const char *name, + int horz_vert, + int *live_var, + int id, GLUI_CB callback + /*,GLUI_Control *object + ,GLUI_InterObject_CB obj_cb*/ + ) +{ + common_construct(parent, name, horz_vert, GLUI_SCROLL_INT, live_var, id, callback/*, object, obj_cb*/); +} + +/****************************** GLUI_Scrollbar::GLUI_Scrollbar() **********/ +// Constructor, float live var +GLUI_Scrollbar::GLUI_Scrollbar( GLUI_Node *parent, const char *name, + int horz_vert, + float *live_var, + int id, GLUI_CB callback + /*,GLUI_Control *object + ,GLUI_InterObject_CB obj_cb*/ + ) +{ + common_construct(parent, name, horz_vert, GLUI_SCROLL_FLOAT, live_var, id, callback/*, object, obj_cb*/); +} + +/****************************** GLUI_Scrollbar::common_init() **********/ +void GLUI_Scrollbar::common_init(void) +{ + horizontal = true; + h = GLUI_SCROLL_ARROW_HEIGHT; + w = GLUI_TEXTBOX_WIDTH; + alignment = GLUI_ALIGN_CENTER; + x_off = 0; + y_off_top = 0; + y_off_bot = 0; + can_activate = true; + state = GLUI_SCROLL_STATE_NONE; + growth_exp = GLUI_SCROLL_DEFAULT_GROWTH_EXP; + callback_count = 0; + first_callback = true; + user_speed = 1.0; + float_min = 0.0; + float_max = 0.0; + int_min = 0; + int_max = 0; + associated_object = NULL; + last_update_time=0; + velocity_limit=50.0; /* Change value by at most 50 per second */ + box_length = 0; + box_start_position = 0; + box_end_position = 0; + track_length = 0; +} + +/****************************** GLUI_Scrollbar::common_construct() **********/ +void GLUI_Scrollbar::common_construct( + GLUI_Node *parent, + const char *name, + int horz_vert, + int data_type, + void *data, + int id, GLUI_CB callback + /*,GLUI_Control *object, + GLUI_InterObject_CB obj_cb*/ + ) +{ + common_init(); + + // make sure limits are wide enough to hold live value + if (data_type==GLUI_SCROLL_FLOAT) { + float lo = 0.0f, hi=1.0f; + if (data) { + float d = *(float*)(data); + lo = MIN(lo, d); + hi = MAX(hi, d); + } + this->set_float_limits(lo,hi); + this->set_float_val(lo); + this->live_type = GLUI_LIVE_FLOAT; + } else { + int lo = 0, hi=100; + if (data) { + int d = *(int*)(data); + lo = MIN(lo, d); + hi = MAX(hi, d); + } + this->set_int_limits(lo,hi); + this->set_int_val(0); + this->live_type = GLUI_LIVE_INT; + } + this->data_type = data_type; + this->set_ptr_val( data ); + this->set_name(name); + this->user_id = id; + this->callback = callback; + //this->associated_object = object; + //this->object_cb = obj_cb; + this->horizontal=(horz_vert==GLUI_SCROLL_HORIZONTAL); + if (this->horizontal) { + this->h = GLUI_SCROLL_ARROW_HEIGHT; + this->w = GLUI_TEXTBOX_WIDTH; + } else { + this->h = GLUI_TEXTBOX_HEIGHT; + this->w = GLUI_SCROLL_ARROW_WIDTH; + } + parent->add_control( this ); + this->init_live(); +} + +/****************************** GLUI_Scrollbar::mouse_down_handler() **********/ + +int GLUI_Scrollbar::mouse_down_handler( int local_x, int local_y ) +{ + last_update_time=GLUI_Time()-1.0; + this->state = find_arrow( local_x, local_y ); + GLUI_Master.glui_setIdleFuncIfNecessary(); + + /* printf( "spinner: mouse down : %d/%d arrow:%d\n", local_x, local_y, + find_arrow( local_x, local_y )); + */ + + if ( state != GLUI_SCROLL_STATE_UP AND state != GLUI_SCROLL_STATE_DOWN) + return true; + + reset_growth(); + + /*** ints and floats behave a bit differently. When you click on + an int spinner, you expect the value to immediately go up by 1, whereas + for a float it'll go up only by a fractional amount. Therefore, we + go ahead and increment by one for int spinners ***/ +#if 1 + if ( data_type == GLUI_SCROLL_INT ) { + // Allow for possibility of reversed limits + int lo = MIN(int_min,int_max); + int hi = MAX(int_min,int_max); + int increase = int_min < int_max ? 1 : -1; + int new_val = int_val; + if ( state == GLUI_SCROLL_STATE_UP ) { + new_val += increase; + } else if ( state == GLUI_SCROLL_STATE_DOWN ) { + new_val -= increase; + } + if (new_val >= lo && new_val <= hi && new_val!=int_val) { + set_int_val(new_val); + do_callbacks(); + } + } +#endif + do_click(); + redraw(); + + return false; +} + + +/******************************** GLUI_Scrollbar::mouse_up_handler() **********/ + +int GLUI_Scrollbar::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + state = GLUI_SCROLL_STATE_NONE; + GLUI_Master.glui_setIdleFuncIfNecessary(); + + /* printf("spinner: mouse up : %d/%d inside: %d\n",local_x,local_y,inside); */ + + /*glutSetCursor( GLUT_CURSOR_INHERIT ); */ + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); + + redraw(); + + /* do_callbacks(); --- stub */ + /* if ( callback ) */ + /* callback( this->user_id ); */ + + return false; +} + + +/***************************** GLUI_Scrollbar::mouse_held_down_handler() ******/ + +int GLUI_Scrollbar::mouse_held_down_handler( int local_x, int local_y, + bool new_inside) +{ + int new_state; + if ( state == GLUI_SCROLL_STATE_NONE ) + return false; + + /* printf("spinner: mouse held: %d/%d inside: %d\n",local_x,local_y, + new_inside); + */ + + if ( state == GLUI_SCROLL_STATE_SCROLL) { /* dragging? */ + do_drag( local_x-x_abs, local_y-y_abs ); + } + else { /* not dragging */ + new_state = find_arrow( local_x, local_y ); + + if ( new_state == state ) { + /** Still in same arrow **/ + do_click(); + } + } + redraw(); + + return false; +} + + +/****************************** GLUI_Scrollbar::key_handler() **********/ + +int GLUI_Scrollbar::key_handler( unsigned char key,int modifiers ) +{ + return true; +} + + +/****************************** GLUI_Scrollbar::draw() **********/ + +void GLUI_Scrollbar::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + if ( horizontal ) { + draw_scroll_arrow(GLUI_SCROLL_ARROW_LEFT, 0, 0); + draw_scroll_arrow(GLUI_SCROLL_ARROW_RIGHT, w-GLUI_SCROLL_ARROW_WIDTH, 0); + } else { + draw_scroll_arrow(GLUI_SCROLL_ARROW_UP, 0, 0); + draw_scroll_arrow(GLUI_SCROLL_ARROW_DOWN, 0, h-GLUI_SCROLL_ARROW_HEIGHT); + } + draw_scroll(); +} + + +/****************************** GLUI_Scrollbar::draw_scroll_arrow() **********/ + +void GLUI_Scrollbar::draw_scroll_arrow(int arrowtype, int x, int y) +{ + float offset=0; + float L=3.5f,HC=7.f,R=10.5f; + float T=4.5f,VC=8.f,B=11.5; + const float verts[][6]={ + { L,10.5f, R, 10.5f, HC, 6.5f }, // up arrow + { L,6.5f, R, 6.5f, HC,10.5f }, // down arrow + { R-2,T, R-2, B, L+1, VC }, // left arrow + { L+2,T, L+2, B, R-1, VC } // right arrow + }; + + const float *tri = NULL; + + switch (arrowtype) + { + case GLUI_SCROLL_ARROW_UP: + tri = verts[0]; + if (state & GLUI_SCROLL_STATE_UP) offset = 1; + break; + + case GLUI_SCROLL_ARROW_DOWN: + tri = verts[1]; + if (state & GLUI_SCROLL_STATE_DOWN) offset = 1; + break; + + case GLUI_SCROLL_ARROW_LEFT: + tri = verts[2]; + if (state & GLUI_SCROLL_STATE_DOWN) offset = 1; + break; + + case GLUI_SCROLL_ARROW_RIGHT: + tri = verts[3]; + if (state & GLUI_SCROLL_STATE_UP) offset = 1; + break; + + default: + return; /* tri is NULL */ + } + + glColor3ubv(&glui->bkgd_color.r); + glRecti(x,y,x+GLUI_SCROLL_ARROW_WIDTH,y+GLUI_SCROLL_ARROW_HEIGHT); + if (!offset) { + glui->draw_raised_box(x,y+1,GLUI_SCROLL_ARROW_WIDTH-1,GLUI_SCROLL_ARROW_HEIGHT-1); + } else { + glColor3ub(128,128,128); + glBegin(GL_LINE_LOOP); + int x2=x+GLUI_SCROLL_ARROW_WIDTH, y2=y+GLUI_SCROLL_ARROW_HEIGHT; + glVertex2i(x ,y); + glVertex2i(x2,y); + glVertex2i(x2,y2); + glVertex2i(x ,y2); + glEnd(); + } + + GLubyte black[]={0,0,0}; + GLubyte white[]={255,255,255}; + GLubyte gray[]={128,128,128}; + GLubyte *color=black; + if (!enabled) { + offset = 1; + color = white; + } + glTranslatef(x+offset,y+offset,0); + glColor3ubv(color); + glBegin(GL_TRIANGLES); + glVertex2fv(tri); glVertex2fv(tri+2), glVertex2fv(tri+4); + glEnd(); + glTranslatef(-(x+offset),-(y+offset),0); + + if (!enabled) { // once more! + glTranslatef(x,y,0); + glColor3ubv(gray); + glBegin(GL_TRIANGLES); + glVertex2fv(tri); glVertex2fv(tri+2), glVertex2fv(tri+4); + glEnd(); + glTranslatef(-x,-y,0); + } +} + + +void GLUI_Scrollbar::draw_scroll() { + update_scroll_parameters(); + + // Draw track using a checkerboard background + const unsigned char scroll_bg[] = { + 0xD4, 0xD0, 0xC8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xD4, 0xD0, 0xC8 + }; + glColor3f( 1.0, 1.0, 1.0 ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glEnable( GL_TEXTURE_2D); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, + scroll_bg); + + float y0 = horizontal? 0 : GLUI_SCROLL_ARROW_HEIGHT; + float y1 = horizontal? h : h-GLUI_SCROLL_ARROW_HEIGHT; + float x0 = horizontal? GLUI_SCROLL_ARROW_WIDTH : 0; + float x1 = horizontal? w-GLUI_SCROLL_ARROW_WIDTH : w; + x0-=0.5; y0+=0.5; + x1-=0.5; y1+=0.5; + float dy = y1-y0; + float dx = x1-x0; + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(x0,y0); + glTexCoord2f(dx*0.5f,0); glVertex2f(x1,y0); + glTexCoord2f(dx*0.5f,dy*0.5f); glVertex2f(x1,y1); + glTexCoord2f(0, dy*0.5f); glVertex2f(x0,y1); + glEnd(); + glDisable(GL_TEXTURE_2D); + + // Draw scroll box + int box = box_start_position; + if (horizontal) { + box += GLUI_SCROLL_ARROW_WIDTH; + draw_scroll_box(box,1,box_length,h); + } else { + box += GLUI_SCROLL_ARROW_HEIGHT+1; + draw_scroll_box(0,box,w,box_length); + } +} + +/****************************** GLUI_Scrollbar::draw_scroll_box() **********/ + +void GLUI_Scrollbar::draw_scroll_box(int x, int y, int w, int h) +{ + if (!enabled) return; + glColor3ubv(&glui->bkgd_color.r); + glRecti(x,y,x+w,y+h); + glui->draw_raised_box(x,y, w-1, h-1); + + if (active) { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0x5555 ); + glColor3f( 0., 0., 0. ); + glBegin(GL_LINE_LOOP); + int x1 = x+2, y1 = y+2, x2 = x+w-4, y2 = y+h-4; + glVertex2i(x1,y1); + glVertex2i(x2,y1); + glVertex2i(x2,y2); + glVertex2i(x1,y2); + glEnd(); + glDisable( GL_LINE_STIPPLE ); + } +} + + + +/**************************** update_scroll_parameters ***********/ + +void GLUI_Scrollbar::update_scroll_parameters() { + track_length = horizontal? + this->w-GLUI_SCROLL_ARROW_WIDTH*2 : + this->h-GLUI_SCROLL_ARROW_HEIGHT*2; + if (data_type==GLUI_SCROLL_INT) + { + if (int_max==int_min) + box_length=track_length; + else { + const int MIN_TAB = GLUI_SCROLL_BOX_STD_HEIGHT; + //box_length = int(track_length/float(visible_range)); + //if (box_length < MIN_TAB) + box_length = MIN_TAB; + } + float pixels_per_unit = (track_length-box_length)/float(int_max-int_min); + if (horizontal) + box_start_position = int((int_val-int_min)*pixels_per_unit); + else + box_start_position = int((int_max-int_val)*pixels_per_unit); + box_end_position = box_start_position+box_length; + } + else if (data_type==GLUI_SCROLL_FLOAT) + { + if (float_max==float_min) + box_length=track_length; + else { + box_length = GLUI_SCROLL_BOX_STD_HEIGHT; + } + float pixels_per_unit = (track_length-box_length)/float(float_max-float_min); + if (horizontal) + box_start_position = int((float_val-float_min)*pixels_per_unit); + else + box_start_position = int((float_max-float_val)*pixels_per_unit); + box_end_position = box_start_position+box_length; + } +} + + +/********************************* GLUI_Scrollbar::special_handler() **********/ + +int GLUI_Scrollbar::special_handler( int key,int modifiers ) +{ + if ( !horizontal && key == GLUT_KEY_UP ) { + mouse_down_handler( x_abs + w - GLUI_SCROLL_ARROW_WIDTH + 1, + y_abs + 1 ); + mouse_up_handler( x_abs + w - GLUI_SCROLL_ARROW_WIDTH + 1, + y_abs + 1, true ); + } + else if ( !horizontal && key == GLUT_KEY_DOWN ) { + mouse_down_handler(x_abs + w - GLUI_SCROLL_ARROW_WIDTH + 1, + y_abs+1+GLUI_SCROLL_ARROW_HEIGHT); + mouse_up_handler( x_abs + w - GLUI_SCROLL_ARROW_WIDTH + 1, + y_abs+1 +GLUI_SCROLL_ARROW_HEIGHT, + true ); + } + if ( horizontal && key == GLUT_KEY_LEFT ) { + mouse_down_handler( x_abs + 1,y_abs + 1 ); + mouse_up_handler( x_abs + 1, y_abs + 1, true ); + } + else if ( horizontal && key == GLUT_KEY_RIGHT ) { + mouse_down_handler(x_abs + w - GLUI_SCROLL_ARROW_WIDTH + 1, + y_abs+1); + mouse_up_handler( x_abs + w - GLUI_SCROLL_ARROW_WIDTH + 1, + y_abs+1, + true ); + } + else if ( key == GLUT_KEY_HOME ) { /** Set value to limit top - + or increment by 10 **/ + } + else if ( key == GLUT_KEY_END ) { + } + + return true; +} + + +/************************************ GLUI_Scrollbar::update_size() **********/ + +void GLUI_Scrollbar::update_size( void ) +{ + if (horizontal) { + h = GLUI_SCROLL_ARROW_HEIGHT; + if (associated_object) { + this->w = ((GLUI_Control *)associated_object)->w; + } + } + else { + w = GLUI_SCROLL_ARROW_WIDTH; + if (associated_object) { + this->h = ((GLUI_Control *)associated_object)->h; + } + } +} + + +/************************************ GLUI_Scrollbar::find_arrow() ************/ + +int GLUI_Scrollbar::find_arrow( int local_x, int local_y ) +{ + + local_x = local_x-x_abs; + local_y = local_y-y_abs; + + if (horizontal) + { + if ( local_y >= h-GLUI_SCROLL_ARROW_HEIGHT-3 && local_y <= h) + { + update_scroll_parameters(); + if ( local_x >= 0 AND local_x <= (GLUI_SCROLL_ARROW_WIDTH+box_start_position) ) + { + return GLUI_SCROLL_STATE_DOWN; + } + if ( local_x >= (GLUI_SCROLL_ARROW_WIDTH+box_end_position) + AND local_x <= (w+GLUI_SCROLL_ARROW_WIDTH) ) + { + return GLUI_SCROLL_STATE_UP; + } + return GLUI_SCROLL_STATE_SCROLL; + } + } + else + { + if ( local_x >= w-GLUI_SCROLL_ARROW_WIDTH-3 && local_x <= w) + { + update_scroll_parameters(); + if ( local_y >= 0 AND local_y <= (GLUI_SCROLL_ARROW_HEIGHT+box_start_position) ) + { + return GLUI_SCROLL_STATE_UP; + } + if ( local_y >= (GLUI_SCROLL_ARROW_HEIGHT+box_end_position) + AND local_y <= (h+GLUI_SCROLL_ARROW_HEIGHT) ) + { + return GLUI_SCROLL_STATE_DOWN; + } + return GLUI_SCROLL_STATE_SCROLL; + } + } + + return GLUI_SCROLL_STATE_NONE; +} + +/***************************************** GLUI_Scrollbar::do_click() **********/ + +void GLUI_Scrollbar::do_click( void ) +{ + int direction = 0; + + if ( state == GLUI_SCROLL_STATE_UP ) + direction = +1; + else if ( state == GLUI_SCROLL_STATE_DOWN ) + direction = -1; + + if (data_type==GLUI_SCROLL_INT&&int_min>int_max) direction*=-1; + if (data_type==GLUI_SCROLL_FLOAT&&float_min>float_max) direction*=-1; + + increase_growth(); + + float modifier_factor = 1.0; + float incr = growth * modifier_factor * user_speed ; + + double frame_time=GLUI_Time()-last_update_time; + double frame_limit=velocity_limit*frame_time; + if (incr>frame_limit) incr=frame_limit; /* don't scroll faster than limit */ + last_update_time=GLUI_Time(); + + float new_val = float_val; + + new_val += direction * incr; + if (1 || data_type==GLUI_SCROLL_FLOAT) set_float_val(new_val); + if (0 && data_type==GLUI_SCROLL_INT) set_int_val((int)new_val); + //printf("do_click: incr %f val=%f float_val=%f\n",incr,new_val,float_val); + + /*** Now update live variable and do callback. We don't want + to do the callback on each iteration of this function, just on every + i^th iteration, where i is given by GLUI_SCROLL_CALLBACK_INTERVAL ****/ + callback_count++; + if ( (callback_count % GLUI_SCROLL_CALLBACK_INTERVAL ) == 0 ) + do_callbacks(); + +} + + +/***************************************** GLUI_Scrollbar::do_drag() **********/ + +void GLUI_Scrollbar::do_drag( int x, int y ) +{ + int direction = 0; + float incr, modifier_factor; + /* int delta_x; */ + int new_int_val = int_val; + float new_float_val = float_val; + + int free_len = track_length-box_length; + if (free_len == 0) return; + + modifier_factor = 1.0; + if ( state == GLUI_SCROLL_STATE_SCROLL) { + update_scroll_parameters(); + + int hbox = box_length/2; + if (horizontal) { + int track_v = x-GLUI_SCROLL_ARROW_WIDTH; + new_int_val = int_min + (track_v-hbox)*(int_max-int_min)/free_len; + new_float_val = float_min + (track_v-hbox)*(float_max-float_min)/float(free_len); + } else { + int track_v = y-GLUI_SCROLL_ARROW_HEIGHT; + new_int_val = int_max - (track_v-hbox)*(int_max-int_min)/free_len; + new_float_val = float_max - (track_v-hbox)*(float_max-float_min)/float(free_len); + } + } + else { + if ( state == GLUI_SCROLL_STATE_UP ) + direction = +1; + else if ( state == GLUI_SCROLL_STATE_DOWN ) + direction = -1; + incr = growth * direction * modifier_factor * user_speed; + new_int_val += direction; + new_float_val += direction * (float_max-float_min)/free_len; + } + last_y = y; + last_x = x; + + /*** Now update live variable and do callback. We don't want + to do the callback on each iteration of this function, just on every + i^th iteration, where i is given by GLUI_SCROLL_CALLBACK_INTERVAL ****/ + if(data_type==GLUI_SCROLL_INT) + set_int_val(new_int_val); + else if (data_type==GLUI_SCROLL_FLOAT) + set_float_val(new_float_val); + + callback_count++; + if ( (callback_count % GLUI_SCROLL_CALLBACK_INTERVAL ) == 0 ) + do_callbacks(); +} + + +/***************************************** GLUI_Scrollbar::needs_idle() ******/ + +bool GLUI_Scrollbar::needs_idle( void ) const +{ + if (state == GLUI_SCROLL_STATE_UP OR state == GLUI_SCROLL_STATE_DOWN ) { + return true; + } + else { + return false; + } +} + +/***************************************** GLUI_Scrollbar::idle() **********/ + +void GLUI_Scrollbar::idle( void ) +{ + if ( NOT needs_idle() ) + return; + else + do_click(); +} + + +/************************************ GLUI_Scrollbar::do_callbacks() **********/ + +void GLUI_Scrollbar::do_callbacks( void ) +{ + + /* *******************************************/ + + if ( NOT first_callback ) { + if ( data_type == GLUI_SCROLL_INT AND int_val == last_int_val ) { + return; + } + if ( data_type == GLUI_SPINNER_FLOAT AND float_val == last_float_val ) { + return; + } + } + + if (associated_object == NULL) { + this->execute_callback(); + } + else { // Use internal Callbacks + if (object_cb) { + //object_cb(associated_object, int_val); + object_cb(this); + } + } + last_int_val = int_val; + last_float_val = float_val; + first_callback = false; +} + + +/********************************** GLUI_Scrollbar::set_float_val() ************/ + +void GLUI_Scrollbar::set_float_val( float new_val ) +{ + // Allow for the possibility that the limits are reversed + float hi = MAX(float_min,float_max); + float lo = MIN(float_min,float_max); + if (new_val > hi) + new_val = hi; + if (new_val < lo) + new_val = lo; + last_float_val = float_val; + float_val = new_val; + int_val = (int)new_val; + + redraw(); + + /*** Now update the live variable ***/ + output_live(true); +} + + +/********************************** GLUI_Scrollbar::set_int_val() ************/ + +void GLUI_Scrollbar::set_int_val( int new_val ) +{ + // Allow for the possibility that the limits are reversed + int hi = MAX(int_min,int_max); + int lo = MIN(int_min,int_max); + if (new_val > hi) + new_val = hi; + if (new_val < lo) + new_val = lo; + last_int_val = int_val; + float_val = int_val = new_val; + + redraw(); + + /*** Now update the live variable ***/ + output_live(true); +} + +/*********************************** GLUI_Scrollbar::set_float_limits() *********/ + +void GLUI_Scrollbar::set_float_limits( float low, float high, int limit_type ) +{ + if (limit_type != GLUI_LIMIT_CLAMP) { + // error! + } + float_min = low; + float_max = high; + // Allow for possiblitly of reversed limits + float lo = MIN(low,high); + float hi = MAX(low,high); + if (float_valhi) set_float_val(hi); +} + + +/*********************************** GLUI_Scrollbar::set_int_limits() *********/ + +void GLUI_Scrollbar::set_int_limits( int low, int high, int limit_type ) +{ + if (limit_type != GLUI_LIMIT_CLAMP) { + // error! + } + int_min = low; + int_max = high; + // Allow for possiblitly of reversed limits + int lo = MIN(low,high); + int hi = MAX(low,high); + if (int_valhi) set_int_val(hi); + float_min = low; + float_max = high; +} + + +/*********************************** GLUI_Scrollbar::reset_growth() *************/ + +void GLUI_Scrollbar::reset_growth( void ) +{ + growth = fabs(float_max - float_min) / float(GLUI_SCROLL_GROWTH_STEPS); + if (data_type == GLUI_SCROLL_INT && growth<1) growth=1; +} + + +/******************************* GLUI_Scrollbar::increase_growth() *************/ + +void GLUI_Scrollbar::increase_growth( void ) +{ + float range=0; + if (data_type==GLUI_SCROLL_FLOAT) + range = fabs(float_max-float_min); + else + range = fabs(float(int_max-int_min)); + if ( growth < (range / float(GLUI_SCROLL_MIN_GROWTH_STEPS)) ) + growth *= growth_exp; + return; +} + + + diff --git a/Extras/glui/glui_separator.cpp b/Extras/glui/glui_separator.cpp new file mode 100644 index 0000000..87907d8 --- /dev/null +++ b/Extras/glui/glui_separator.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_separator.cpp - GLUI_Separator control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +/****************************** GLUI_Separator::GLUI_Separator() **********/ + +GLUI_Separator::GLUI_Separator( GLUI_Node *parent ) +{ + common_init(); + parent->add_control( this ); +} + +/****************************** GLUI_Separator::draw() **********/ + +void GLUI_Separator::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + int width, indent; + int cont_x, cont_y, cont_w, cont_h, cont_x_off, cont_y_off; + + if ( parent() != NULL ) { + get_this_column_dims(&cont_x, &cont_y, &cont_w, &cont_h, + &cont_x_off, &cont_y_off); + + width = cont_w - cont_x_off*2; + } + else { + width = this->w; + } + + indent = (int) floor(width * .05); + + glLineWidth( 1.0 ); + glBegin( GL_LINES ); + glColor3f( .5, .5, .5 ); + glVertex2i( indent, GLUI_SEPARATOR_HEIGHT/2-1 ); + glVertex2i( width-indent, GLUI_SEPARATOR_HEIGHT/2-1 ); + + glColor3f( 1., 1., 1. ); + glVertex2i( indent, GLUI_SEPARATOR_HEIGHT/2 ); + glVertex2i( width-indent, GLUI_SEPARATOR_HEIGHT/2 ); + glEnd(); +} + + diff --git a/Extras/glui/glui_spinner.cpp b/Extras/glui/glui_spinner.cpp new file mode 100644 index 0000000..9867739 --- /dev/null +++ b/Extras/glui/glui_spinner.cpp @@ -0,0 +1,630 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_spinner.cpp - GLUI_Spinner class + + + notes: + spinner does not explicitly keep track of the current value - this is all + handled by the underlying edittext control + -> thus, spinner->sync_live() has no meaning, nor spinner->output_live + -> BUT, edittext will alter this spinner's float_val and int_val, + so that spinner->get/set will work + + +FIXME: there's a heck of a lot of duplication between this and glui_scrollbar.cpp. + (OSL, 2006/06) + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" +#include +#include + +/*static int __debug=0; */ + +#define GLUI_SPINNER_GROWTH_STEPS 800 +#define GLUI_SPINNER_MIN_GROWTH_STEPS 100 +#define GLUI_SPINNER_CALLBACK_INTERVAL 1 + + + + +/****************************** GLUI_Spinner::GLUI_Spinner() ****************/ + +GLUI_Spinner::GLUI_Spinner( GLUI_Node* parent, const char *name, + int data_type, int id, GLUI_CB callback ) +{ + common_construct(parent, name, data_type, NULL, id, callback); +} + +/****************************** GLUI_Spinner::GLUI_Spinner() ****************/ + +GLUI_Spinner::GLUI_Spinner( GLUI_Node* parent, const char *name, + int *live_var, int id, GLUI_CB callback ) +{ + common_construct(parent, name, GLUI_SPINNER_INT, live_var, id, callback); +} + +/****************************** GLUI_Spinner::GLUI_Spinner() ****************/ + +GLUI_Spinner::GLUI_Spinner( GLUI_Node* parent, const char *name, + float *live_var, int id, GLUI_CB callback ) +{ + common_construct(parent, name, GLUI_SPINNER_FLOAT, live_var, id, callback); +} + +/****************************** GLUI_Spinner::GLUI_Spinner() ****************/ + +GLUI_Spinner::GLUI_Spinner( GLUI_Node *parent, const char *name, + int data_t, void *live_var, + int id, GLUI_CB callback ) +{ + common_construct(parent, name, data_t, live_var, id, callback); +} + +/****************************** GLUI_Spinner::common_construct() ************/ + +void GLUI_Spinner::common_construct( GLUI_Node* parent, const char *name, + int data_t, void *data, + int id, GLUI_CB cb ) +{ + common_init(); + + if ( NOT strcmp( name, "Spinner Test" )) + id=id; + + int text_type; + if ( data_t == GLUI_SPINNER_INT ) { + text_type = GLUI_EDITTEXT_INT; + } + else if ( data_t == GLUI_SPINNER_FLOAT ) { + text_type = GLUI_EDITTEXT_FLOAT; + } + else { + assert(0); /* Did not pass in a valid data type */ + } + + user_id = id; + data_type = data_t; + callback = cb; + set_name( name ); + //glui = parent->get_glui(); + + parent->add_control( this ); + + GLUI_EditText *txt = + new GLUI_EditText( this, name, text_type, data, id, cb); + + edittext = txt; /* Link the edittext to the spinner */ + /* control->ptr_val = data; */ + + edittext->spinner = this; /* Link the spinner to the edittext */ + +} + +/****************************** GLUI_Spinner::mouse_down_handler() **********/ + +int GLUI_Spinner::mouse_down_handler( int local_x, int local_y ) +{ + this->state = find_arrow( local_x, local_y ); + GLUI_Master.glui_setIdleFuncIfNecessary(); + + /* printf( "spinner: mouse down : %d/%d arrow:%d\n", local_x, local_y, + find_arrow( local_x, local_y )); + */ + + if ( state != GLUI_SPINNER_STATE_UP AND state != GLUI_SPINNER_STATE_DOWN ) + return true; + + reset_growth(); + redraw(); + + /*** ints and floats behave a bit differently. When you click on + an int spinner, you expect the value to immediately go up by 1, whereas + for a float it'll go up only by a fractional amount. Therefore, we + go ahead and increment by one for int spinners ***/ + if ( data_type == GLUI_SPINNER_INT ) { + if ( state == GLUI_SPINNER_STATE_UP ) + edittext->set_float_val( edittext->float_val + 1.0 ); + else if ( state == GLUI_SPINNER_STATE_DOWN ) + edittext->set_float_val( edittext->float_val - .9 ); + } + + do_click(); + + return false; +} + + +/******************************** GLUI_Spinner::mouse_up_handler() **********/ + +int GLUI_Spinner::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + state = GLUI_SPINNER_STATE_NONE; + GLUI_Master.glui_setIdleFuncIfNecessary(); + + /* printf("spinner: mouse up : %d/%d inside: %d\n",local_x,local_y,inside); */ + + /*glutSetCursor( GLUT_CURSOR_INHERIT ); */ + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); + redraw(); + + /* do_callbacks(); --- stub */ + /* if ( callback ) */ + /* callback( this->user_id ); */ + + return false; +} + + +/***************************** GLUI_Spinner::mouse_held_down_handler() ******/ + +int GLUI_Spinner::mouse_held_down_handler( int local_x, int local_y, + bool new_inside) +{ + int new_state; + + if ( state == GLUI_SPINNER_STATE_NONE ) + return false; + + /* printf("spinner: mouse held: %d/%d inside: %d\n",local_x,local_y, + new_inside); + */ + + if ( state == GLUI_SPINNER_STATE_BOTH ) { /* dragging? */ + do_drag( local_x, local_y ); + } + else { /* not dragging */ + new_state = find_arrow( local_x, local_y ); + + if ( new_state == state ) { + /** Still in same arrow **/ + do_click(); + } + else { + if ( new_inside OR 1) { + /** The state changed, but we're still inside - that + means we moved off the arrow: begin dragging **/ + state = GLUI_SPINNER_STATE_BOTH; + } + else { + /*** Here check y of mouse position to determine whether to + drag ***/ + + /* ... */ + } + } + + /*** We switched to up/down dragging ***/ + if ( state == GLUI_SPINNER_STATE_BOTH ) { + glutSetCursor( GLUT_CURSOR_UP_DOWN ); + last_x = local_x; + last_y = local_y; + + /** If the spinner has limits, we reset the growth value, since + reset_growth() will compute a new growth value for dragging + vs. clicking. If the spinner has no limits, then we just let the + growth remain at whatever the user has incremented it up to **/ + if ( edittext->has_limits != GLUI_LIMIT_NONE ) + reset_growth(); + } + + redraw(); + } + + return false; +} + + +/****************************** GLUI_Spinner::key_handler() **********/ + +int GLUI_Spinner::key_handler( unsigned char key,int modifiers ) +{ + + + return true; +} + + +/****************************** GLUI_Spinner::draw() **********/ + +void GLUI_Spinner::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + if ( enabled ) { + /*** Draw the up arrow either pressed or unrpessed ***/ + if ( state == GLUI_SPINNER_STATE_UP OR state == GLUI_SPINNER_STATE_BOTH ) + glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_UP_ON, + w-GLUI_SPINNER_ARROW_WIDTH-1, + GLUI_SPINNER_ARROW_Y); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_UP_OFF, + w-GLUI_SPINNER_ARROW_WIDTH-1, + GLUI_SPINNER_ARROW_Y); + + /*** Draw the down arrow either pressed or unrpessed ***/ + if (state == GLUI_SPINNER_STATE_DOWN OR state == GLUI_SPINNER_STATE_BOTH) + glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_DOWN_ON, + w-GLUI_SPINNER_ARROW_WIDTH-1, + GLUI_SPINNER_ARROW_HEIGHT+GLUI_SPINNER_ARROW_Y); + else + glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_DOWN_OFF, + w-GLUI_SPINNER_ARROW_WIDTH-1, + GLUI_SPINNER_ARROW_HEIGHT+GLUI_SPINNER_ARROW_Y); + } + else { /**** The spinner is disabled ****/ + glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_UP_DIS, + w-GLUI_SPINNER_ARROW_WIDTH-1, + GLUI_SPINNER_ARROW_Y); + glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_DOWN_DIS, + w-GLUI_SPINNER_ARROW_WIDTH-1, + GLUI_SPINNER_ARROW_HEIGHT+GLUI_SPINNER_ARROW_Y); + } + + if ( active ) { + glColor3ub( 0, 0, 0 ); + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0x5555 ); + } + else { + glColor3ub( glui->bkgd_color.r,glui->bkgd_color.g,glui->bkgd_color.b ); + } + + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( w-GLUI_SPINNER_ARROW_WIDTH-2, 0 ); + glVertex2i( w, 0 ); + glVertex2i( w, h ); + glVertex2i( w-GLUI_SPINNER_ARROW_WIDTH-2, h ); + glEnd(); + glDisable( GL_LINE_STIPPLE ); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); +} + + +/********************************* GLUI_Spinner::special_handler() **********/ + +int GLUI_Spinner::special_handler( int key,int modifiers ) +{ + if ( key == GLUT_KEY_UP ) { /** Simulate a click in the up arrow **/ + mouse_down_handler( x_abs + w - GLUI_SPINNER_ARROW_WIDTH + 1, + y_abs + GLUI_SPINNER_ARROW_Y+1 ); + mouse_up_handler( x_abs + w - GLUI_SPINNER_ARROW_WIDTH + 1, + y_abs + GLUI_SPINNER_ARROW_Y+1, true ); + } + else if ( key == GLUT_KEY_DOWN ) { /** Simulate a click in the up arrow **/ + mouse_down_handler(x_abs + w - GLUI_SPINNER_ARROW_WIDTH + 1, + y_abs+GLUI_SPINNER_ARROW_Y+1+GLUI_SPINNER_ARROW_HEIGHT); + mouse_up_handler( x_abs + w - GLUI_SPINNER_ARROW_WIDTH + 1, + y_abs+GLUI_SPINNER_ARROW_Y+1 +GLUI_SPINNER_ARROW_HEIGHT, + true ); + } + else if ( key == GLUT_KEY_HOME ) { /** Set value to limit top - + or increment by 10 **/ + } + else if ( key == GLUT_KEY_END ) { + } + + return true; +} + + +/******************************* GLUI_Spinner::set_float_val() ************/ + +void GLUI_Spinner::set_float_val( float new_val ) +{ + if ( NOT edittext ) + return; + + edittext->set_float_val( new_val ); +} + + +/********************************** GLUI_Spinner::set_int_val() ************/ + +void GLUI_Spinner::set_int_val( int new_val ) +{ + if ( NOT edittext ) + return; + + edittext->set_int_val( new_val ); +} + + +/************************************ GLUI_Spinner::update_size() **********/ + +void GLUI_Spinner::update_size( void ) +{ + if (!edittext) return; + /*edittext->w = this->w - GLUI_SPINNER_ARROW_WIDTH-3; */ + this->w = edittext->w + GLUI_SPINNER_ARROW_WIDTH + 3; +} + + +/************************************ GLUI_Spinner::find_arrow() ************/ + +int GLUI_Spinner::find_arrow( int local_x, int local_y ) +{ + local_x -= x_abs; + local_y -= y_abs; + + if ( local_x >= (w - GLUI_SPINNER_ARROW_WIDTH) AND + local_x <= w ) { + + if ( local_y >= GLUI_SPINNER_ARROW_Y AND + local_y <= (GLUI_SPINNER_ARROW_Y+GLUI_SPINNER_ARROW_HEIGHT) ) + return GLUI_SPINNER_STATE_UP; + + if ( local_y >= GLUI_SPINNER_ARROW_Y+GLUI_SPINNER_ARROW_HEIGHT AND + local_y <= (GLUI_SPINNER_ARROW_Y+GLUI_SPINNER_ARROW_HEIGHT*2) ) + return GLUI_SPINNER_STATE_DOWN; + + } + + return GLUI_SPINNER_STATE_NONE; +} + + +/***************************************** GLUI_Spinner::do_click() **********/ + +void GLUI_Spinner::do_click( void ) +{ + int direction = 0; + float incr; + float modifier_factor; + + if ( state == GLUI_SPINNER_STATE_UP ) + direction = +1; + else if ( state == GLUI_SPINNER_STATE_DOWN ) + direction = -1; + + increase_growth(); + + modifier_factor = 1.0; + if ( glui ) { + if ( glui->curr_modifiers & GLUT_ACTIVE_SHIFT ) + modifier_factor = 100.0f; + else if ( glui->curr_modifiers & GLUT_ACTIVE_CTRL ) + modifier_factor = .01f; + } + + if ( this->data_type == GLUI_SPINNER_FLOAT OR 1) { + incr = growth * direction * modifier_factor * user_speed; + edittext->set_float_val( edittext->float_val + incr ); + /** Remember, edittext mirrors the float and int values ***/ + } + + /*** Now update live variable and do callback. We don't want + to do the callback on each iteration of this function, just on every + i^th iteration, where i is given by GLUI_SPINNER_CALLBACK_INTERVAL ****/ + callback_count++; + if ( (callback_count % GLUI_SPINNER_CALLBACK_INTERVAL ) == 0 ) + do_callbacks(); +} + + +/***************************************** GLUI_Spinner::do_drag() **********/ + +void GLUI_Spinner::do_drag( int x, int y ) +{ + int delta_y; + float incr, modifier_factor; + /* int delta_x; */ + + modifier_factor = 1.0f; + if ( glui ) { + if ( glui->curr_modifiers & GLUT_ACTIVE_SHIFT ) + modifier_factor = 100.0f; + else if ( glui->curr_modifiers & GLUT_ACTIVE_CTRL ) + modifier_factor = .01f; + } + + /* delta_x = x - last_x; */ + delta_y = -(y - last_y); + + if ( this->data_type == GLUI_SPINNER_FLOAT OR 1 ) { + incr = growth * delta_y * modifier_factor * user_speed; + edittext->set_float_val( edittext->float_val + incr ); + /** Remember, edittext mirrors the float and int values ***/ + } + + last_x = x; + last_y = y; + + /*** Now update live variable and do callback. We don't want + to do the callback on each iteration of this function, just on every + i^th iteration, where i is given by GLUI_SPINNER_CALLBACK_INTERVAL ****/ + + callback_count++; + if ( (callback_count % GLUI_SPINNER_CALLBACK_INTERVAL ) == 0 ) + do_callbacks(); +} + + +/***************************************** GLUI_Spinner::needs_idle() ******/ + +bool GLUI_Spinner::needs_idle( void ) const +{ + if (state == GLUI_SPINNER_STATE_UP OR state == GLUI_SPINNER_STATE_DOWN ) { + return true; + } + else { + return false; + } +} + +/***************************************** GLUI_Spinner::idle() **********/ + +void GLUI_Spinner::idle( void ) +{ + if ( NOT needs_idle() ) + return; + else + do_click(); +} + + +/************************************ GLUI_Spinner::do_callbacks() **********/ + +void GLUI_Spinner::do_callbacks( void ) +{ + /*** This is not necessary, b/c edittext automatically updates us ***/ + if ( NOT edittext ) + return; + this->float_val = edittext->float_val; + this->int_val = edittext->int_val; + /* *******************************************/ + + if ( NOT first_callback ) { + if ( data_type == GLUI_SPINNER_INT AND int_val == last_int_val ) { + return; + } + + if ( data_type == GLUI_SPINNER_FLOAT AND float_val == last_float_val ) { + return; + } + } + + this->execute_callback(); + + last_int_val = int_val; + last_float_val = float_val; + first_callback = false; +} + + +/********************************* GLUI_Spinner::set_float_limits() *********/ + +void GLUI_Spinner::set_float_limits( float low, float high, int limit_type ) +{ + if ( NOT edittext ) + return; + + edittext->set_float_limits( low, high, limit_type ); +} + + +/*********************************** GLUI_Spinner::set_int_limits() *********/ + +void GLUI_Spinner::set_int_limits( int low, int high, int limit_type ) +{ + if ( NOT edittext ) + return; + + edittext->set_int_limits( low, high, limit_type ); +} + + +/*********************************** GLUI_Spinner:reset_growth() *************/ + +void GLUI_Spinner::reset_growth( void ) +{ + float lo, hi; + + if ( edittext->has_limits == GLUI_LIMIT_NONE ) { + if ( data_type == GLUI_SPINNER_FLOAT ) + growth = sqrt(ABS(edittext->float_val)) * .05f; + else if ( data_type == GLUI_SPINNER_INT ) + growth = .4f; + } + else { + if ( data_type == GLUI_SPINNER_FLOAT ) { + lo = edittext->float_low; + hi = edittext->float_high; + growth = (hi-lo) / GLUI_SPINNER_GROWTH_STEPS; + } + else if ( data_type == GLUI_SPINNER_INT ) { + lo = (float) edittext->int_low; + hi = (float) edittext->int_high; + + growth = (hi-lo) / GLUI_SPINNER_GROWTH_STEPS; + } + } + + if ( growth == 0.0f ) + growth = .001f; +} + + +/******************************* GLUI_Spinner:increase_growth() *************/ + +void GLUI_Spinner::increase_growth( void ) +{ + float hi = 0.0,lo = 0.0; + + if ( data_type == GLUI_SPINNER_FLOAT ) { + lo = edittext->float_low; + hi = edittext->float_high; + } + else if ( data_type == GLUI_SPINNER_INT ) { + lo = (float) edittext->int_low; + hi = (float) edittext->int_high; + } + + if ( growth < (hi-lo) / GLUI_SPINNER_MIN_GROWTH_STEPS ) + growth *= growth_exp; + + /* printf( "growth: %f\n", growth ); */ +} + + +/*************************************** GLUI_Spinner:get_text() *************/ + +const char *GLUI_Spinner::get_text( void ) +{ + if (edittext) + return edittext->text.c_str(); + else + return ""; +} + + +/********************************** GLUI_Spinner:get_float_val() *************/ + +float GLUI_Spinner::get_float_val( void ) +{ + if (edittext) + return edittext->float_val; + else + return 0.0f; +} + + +/********************************** GLUI_Spinner:get_int_val() *************/ + +int GLUI_Spinner::get_int_val( void ) +{ + if (edittext) + return edittext->int_val; + else + return 0; +} + + diff --git a/Extras/glui/glui_statictext.cpp b/Extras/glui/glui_statictext.cpp new file mode 100644 index 0000000..21ffa13 --- /dev/null +++ b/Extras/glui/glui_statictext.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_statictext.cpp - GLUI_StaticText Control + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" + +/****************************** GLUI_StaticText::GLUI_StaticText() **********/ +GLUI_StaticText::GLUI_StaticText( GLUI_Node *parent, const char *name ) +{ + common_init(); + set_name( name ); + parent->add_control( this ); +} + +/****************************** GLUI_StaticText::draw() **********/ + +void GLUI_StaticText::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + + draw_text(); +} + + +/****************************** GLUI_StaticText::set_text() **********/ + +void GLUI_StaticText::set_text( const char *text ) +{ + set_name( text ); + redraw(); +} + + +/************************************ GLUI_StaticText::update_size() **********/ + +void GLUI_StaticText::update_size( void ) +{ + int text_size; + + if ( NOT glui ) + return; + + text_size = string_width( name ); + + if ( w < text_size ) + w = text_size; +} + + +/****************************** GLUI_StaticText::draw_text() **********/ + +void GLUI_StaticText::draw_text( void ) +{ + if ( NOT can_draw() ) + return; + + erase_text(); + draw_name( 0, 9 ); +} + + +/****************************** GLUI_StaticText::erase_text() **********/ + +void GLUI_StaticText::erase_text( void ) +{ + if ( NOT can_draw() ) + return; + + set_to_bkgd_color(); + glDisable( GL_CULL_FACE ); + glBegin( GL_TRIANGLES ); + glVertex2i( 0,0 ); glVertex2i( w, 0 ); glVertex2i( w, h ); + glVertex2i( 0, 0 ); glVertex2i( w, h ); glVertex2i( 0, h ); + glEnd(); +} + + + diff --git a/Extras/glui/glui_string.cpp b/Extras/glui/glui_string.cpp new file mode 100644 index 0000000..b2fe2eb --- /dev/null +++ b/Extras/glui/glui_string.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui.cpp + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher (this file, Bill Baxter 2005) + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA + + This program is -not- in the public domain. + +*****************************************************************************/ + +#include "GL/glui.h" +#include + +#if defined (_MSC_VER) && (_MSC_VER < 1500) +#define vsnprintf _vsnprintf +#endif + +GLUI_String& glui_format_str(GLUI_String& str, const char* fmt, ...) +{ + const size_t ISIZE = 128; + char stackbuf[ISIZE]; + size_t bufsz = ISIZE; + char *buf = stackbuf; + str = ""; + va_list arg; + while (1) { + va_start(arg, fmt); + int ret = vsnprintf(buf,299,fmt,arg); + va_end(arg); + if (ret>=0) { + break; + } + // else make a bigger buf, try again + bufsz <<= 1; + if (buf==stackbuf) buf = (char*)malloc(sizeof(char)*bufsz); + else buf = (char*)realloc(buf, sizeof(char)*bufsz); + } + if (buf!=stackbuf) free(buf); + str=buf; + return str; +} diff --git a/Extras/glui/glui_textbox.cpp b/Extras/glui/glui_textbox.cpp new file mode 100644 index 0000000..342e009 --- /dev/null +++ b/Extras/glui/glui_textbox.cpp @@ -0,0 +1,1108 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_textbox.cpp - GLUI_TextBox control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher, 2004 John Kew + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "glui_internal_control.h" +#include + + +static const int LINE_HEIGHT = 15; + +/****************************** GLUI_TextBox::GLUI_TextBox() **********/ + +GLUI_TextBox::GLUI_TextBox(GLUI_Node *parent, GLUI_String &live_var, + bool scroll, int id, GLUI_CB callback ) +{ + common_construct(parent, &live_var, scroll, id, callback); +} + +/****************************** GLUI_TextBox::GLUI_TextBox() **********/ + +GLUI_TextBox::GLUI_TextBox( GLUI_Node *parent, bool scroll, int id, + GLUI_CB callback ) +{ + common_construct(parent, NULL, scroll, id, callback); +} + +/****************************** GLUI_TextBox::common_construct() **********/ +void GLUI_TextBox::common_construct( + GLUI_Node *parent, GLUI_String *data, + bool scroll, int id, GLUI_CB callback) +{ + common_init(); + + GLUI_Node *tb_panel = parent; + + if (scroll) { + GLUI_Panel *p = new GLUI_Panel(parent,"",GLUI_PANEL_NONE); + p->x_off = 1; + tb_panel = p; + } + this->ptr_val = data; + if (data) { + this->live_type = GLUI_LIVE_STRING; + } else { + this->live_type = GLUI_LIVE_NONE; + } + this->user_id = id; + this->callback = callback; + this->name = "textbox"; + tb_panel->add_control( this ); + if (scroll) { + new GLUI_Column(tb_panel, false); + scrollbar = + new GLUI_Scrollbar(tb_panel, + "scrollbar", + GLUI_SCROLL_VERTICAL, + GLUI_SCROLL_INT); + scrollbar->set_object_callback(GLUI_TextBox::scrollbar_callback, this); + scrollbar->set_alignment(GLUI_ALIGN_LEFT); + // scrollbar->can_activate = false; //kills ability to mouse drag too + } + init_live(); +} + +/****************************** GLUI_TextBox::mouse_down_handler() **********/ + +int GLUI_TextBox::mouse_down_handler( int local_x, int local_y ) +{ + int tmp_insertion_pt; + + if ( debug ) dump( stdout, "-> MOUSE DOWN" ); + + tmp_insertion_pt = find_insertion_pt( local_x, local_y ); + if ( tmp_insertion_pt == -1 ) { + if ( glui ) + glui->deactivate_current_control( ); + return false; + } + + insertion_pt = tmp_insertion_pt; + + sel_start = sel_end = insertion_pt; + + keygoal_x = insert_x; + + if ( can_draw()) + update_and_draw_text(); + + if ( debug ) dump( stdout, "<- MOUSE UP" ); + + return true; +} + + +/******************************** GLUI_TextBox::mouse_up_handler() **********/ + +int GLUI_TextBox::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + return false; +} + + +/***************************** GLUI_TextBox::mouse_held_down_handler() ******/ + +int GLUI_TextBox::mouse_held_down_handler( int local_x, int local_y, + bool new_inside) +{ + int tmp_pt; + + if ( NOT new_inside ) return false; + + if ( debug ) dump( stdout, "-> HELD DOWN" ); + + tmp_pt = find_insertion_pt( local_x, local_y ); + keygoal_x = insert_x; + + if ( tmp_pt == -1 AND sel_end != 0 ) { /* moved mouse past left edge */ + special_handler( GLUT_KEY_LEFT, GLUT_ACTIVE_SHIFT ); + } + else if ( tmp_pt == substring_end+1 AND sel_end != (int) text.length()) { + /* moved mouse past right edge */ + special_handler( GLUT_KEY_RIGHT, GLUT_ACTIVE_SHIFT ); + } + else if ( tmp_pt != -1 AND tmp_pt != sel_end ) { + sel_end = insertion_pt = tmp_pt; + + update_and_draw_text(); + } + + if ( debug ) + dump( stdout, "<- HELD DOWN" ); + + return false; +} + + +/****************************** GLUI_TextBox::key_handler() **********/ +int GLUI_TextBox::key_handler( unsigned char key,int modifiers ) +{ + int regular_key; + /* int has_selection; */ + + if ( NOT glui ) + return false; + + if ( debug ) + dump( stdout, "-> KEY HANDLER" ); + + regular_key = false; + bool ctrl_down = (modifiers & GLUT_ACTIVE_CTRL)!=0; + /* has_selection = (sel_start != sel_end); */ + + if ( key == CTRL('[')) { /* ESCAPE */ + glui->deactivate_current_control(); + return true; + } + else if ( (key == 127 AND !ctrl_down) OR /* FORWARD DELETE */ + ( key == CTRL('d') AND modifiers == GLUT_ACTIVE_CTRL) ) + { + if ( sel_start == sel_end ) { /* no selection */ + if ( insertion_pt < (int)text.length() ) { + text.erase(insertion_pt,1); + } + } + else { /* There is a selection */ + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + } + else if ( ((key == 127) AND ctrl_down) OR // Delete word forward + ((key == 'd') AND (modifiers == GLUT_ACTIVE_ALT)) ) + { + if ( sel_start == sel_end ) { /* no selection */ + sel_start = insertion_pt; + sel_end = find_word_break( insertion_pt, +1 ); + } + + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + else if ( key == CTRL('h') ) { /* BACKSPACE */ + if ( sel_start == sel_end ) { /* no selection */ + if ( insertion_pt > 0 ) { + insertion_pt--; + text.erase(insertion_pt,1); + } + } + else { /* There is a selection */ + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + } + else if ( modifiers == GLUT_ACTIVE_CTRL ) /* CTRL ONLY */ + { + /* Ctrl-key bindings */ + if ( key == CTRL('a') ) { + return special_handler( GLUT_KEY_HOME, 0 ); + } + else if ( key == CTRL('e') ) { + return special_handler( GLUT_KEY_END, 0 ); + } + else if ( key == CTRL('b') ) { + return special_handler( GLUT_KEY_LEFT, 0 ); + } + else if ( key == CTRL('f') ) { + return special_handler( GLUT_KEY_RIGHT, 0 ); + } + else if ( key == CTRL('p') ) { + return special_handler( GLUT_KEY_UP, 0 ); + } + else if ( key == CTRL('n') ) { + return special_handler( GLUT_KEY_DOWN, 0 ); + } + else if ( key == CTRL('u') ) { /* ERASE LINE */ + insertion_pt = 0; + text.erase(0,text.length()); + sel_start = sel_end = 0; + } + else if ( key == CTRL('k') ) { /* KILL TO END OF LINE */ + sel_start = sel_end = insertion_pt; + text.erase(insertion_pt,GLUI_String::npos); + } + } + else if ( modifiers == GLUT_ACTIVE_ALT ) /* ALT ONLY */ + { + if ( key == 'b' ) { // Backward word + return special_handler ( GLUT_KEY_LEFT, GLUT_ACTIVE_CTRL ); + } + if ( key == 'f' ) { // Forward word + return special_handler ( GLUT_KEY_RIGHT, GLUT_ACTIVE_CTRL ); + } + } + else if ( (modifiers & GLUT_ACTIVE_CTRL) OR + (modifiers & GLUT_ACTIVE_ALT) ) + { + /** ignore other keys with modifiers */ + return true; + } + else { /* Regular key */ + if ( key == 13 ) /* RETURNS are written as newlines*/ + key = '\n'; + + regular_key = true; + + /** This is just to get rid of warnings - the flag regular_key is + set if the key was not a backspace, return, whatever. But I + believe if we're here, we know it was a regular key anyway */ + if ( regular_key ) { + } + + /**** If there's a current selection, erase it ******/ + if ( sel_start != sel_end ) { + clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); + insertion_pt = MIN(sel_start,sel_end); + sel_start = sel_end = insertion_pt; + } + + /******** We insert the character into the string ***/ + + text.insert(insertion_pt,1,key); + + /******** Move the insertion point and substring_end one over ******/ + insertion_pt++; + substring_end++; + + sel_start = sel_end = insertion_pt; + } + + /******** Now redraw text ***********/ + /* Hack to prevent text box from being cleared first **/ + /** int substring_change = update_substring_bounds(); + draw_text_only = + (NOT substring_change AND NOT has_selection AND regular_key ); + */ + + draw_text_only = false; /** Well, hack is not yet working **/ + update_and_draw_text(); + draw_text_only = false; + + + if ( debug ) + dump( stdout, "<- KEY HANDLER" ); + + return true; +} + +/****************************** GLUI_TextBox::enable() **********/ + +void GLUI_TextBox::enable( void ) +{ + GLUI_Control::enable(); + scrollbar->enable(); +} + +/****************************** GLUI_TextBox::disable() **********/ + +void GLUI_TextBox::disable( void ) +{ + GLUI_Control::disable(); + scrollbar->disable(); +} + +/****************************** GLUI_TextBox::activate() **********/ + +void GLUI_TextBox::activate( int how ) +{ + if ( debug ) + dump( stdout, "-> ACTIVATE" ); + active = true; + + if ( how == GLUI_ACTIVATE_MOUSE ) + return; /* Don't select everything if activated with mouse */ + + orig_text = text; + + sel_start = 0; + sel_end = int(text.length()); + insertion_pt = 0; + if ( debug ) + dump( stdout, "<- ACTIVATE" ); +} + + +/****************************** GLUI_TextBox::deactivate() **********/ + +void GLUI_TextBox::deactivate( void ) +{ + active = false; + + if ( NOT glui ) + return; + + if ( debug ) + dump( stdout, "-> DISACTIVATE" ); + + sel_start = sel_end = insertion_pt = -1; + + /***** Retrieve the current value from the text *****/ + /***** The live variable will be updated by set_text() ****/ + set_text(text.c_str()); /* This will force callbacks and gfx refresh */ + + update_substring_bounds(); + + /******** redraw text without insertion point ***********/ + redraw(); + + /***** Now do callbacks if value changed ******/ + if ( orig_text != text ) { + this->execute_callback(); + + + } + + + if ( debug ) + dump( stdout, "<- DISACTIVATE" ); +} + +/****************************** GLUI_TextBox::draw() **********/ + +void GLUI_TextBox::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int line = 0; + int text_length; + int box_width; + int i; + + /* Bevelled Border */ + glBegin( GL_LINES ); + glColor3f( .5, .5, .5 ); + glVertex2i( 0, 0 ); glVertex2i( w, 0 ); + glVertex2i( 0, 0 ); glVertex2i( 0, h ); + + glColor3f( 1., 1., 1. ); + glVertex2i( 0, h ); glVertex2i( w, h ); + glVertex2i( w, h ); glVertex2i( w, 0 ); + + if ( enabled ) + glColor3f( 0., 0., 0. ); + else + glColor3f( .25, .25, .25 ); + glVertex2i( 1, 1 ); glVertex2i( w-1, 1 ); + glVertex2i( 1, 1 ); glVertex2i( 1, h-1 ); + + glColor3f( .75, .75, .75 ); + glVertex2i( 1, h-1 ); glVertex2i( w-1, h-1 ); + glVertex2i( w-1, h-1 ); glVertex2i( w-1, 1 ); + glEnd(); + + /* Draw Background if enabled*/ + if (enabled) { + glColor3f( 1., 1., 1. ); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( 2, 2 ); glVertex2i( w-2, 2 ); + glVertex2i( w-2, h-2 ); glVertex2i(2, h-2 ); + glEnd(); + } else { + glColor3f( .8, .8, .8 ); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( 2, 2 ); glVertex2i( w-2, 2 ); + glVertex2i( w-2, h-2 ); glVertex2i(2, h-2 ); + glEnd(); + } + + /* Begin Drawing Lines of Text */ + substring_start = 0; + substring_end = 0; + text_length = int(text.length())-1; + + /* Figure out how wide the box is */ + box_width = get_box_width(); + + /* Get the first line substring */ + while (substring_width(substring_start, substring_end+1 ) < box_width && + substring_end < text_length && text[substring_end+1] != '\n') + substring_end++; + + /* Figure out which lines are visible*/ + + visible_lines = (int)(h-20)/LINE_HEIGHT; + if (start_line < (curr_line-visible_lines)) { + for (i = 0; ((curr_line-i)*LINE_HEIGHT+20) > h; i++); + start_line = i; + } else if ( start_line > curr_line) { + start_line = curr_line; + } + line = 0; + do { + if (line && substring_end < text_length) { + substring_start = substring_end+1; + while (substring_width(substring_start, substring_end+1 ) < box_width && + substring_end < text_length && text[substring_end+1] != '\n') + substring_end++; + } + if (text[substring_end+1] == '\n') { /* Skip newline */ + substring_end++; + } + if (line < start_line || (line > curr_line && curr_line > (start_line + visible_lines))) { + line++; + continue; + } + if ((line - start_line) <= visible_lines) + draw_text(0,(line - start_line)*LINE_HEIGHT); /* tabs and other nasties are handled by substring_width */ + line++; + } while (substring_end < text_length); + + num_lines = line; + + draw_insertion_pt(); + if (scrollbar) { + scrollbar->set_int_limits(MAX(0,num_lines/*-1*/-visible_lines),0); + glPushMatrix(); + glTranslatef(scrollbar->x_abs-x_abs, scrollbar->y_abs-y_abs,0.0); + scrollbar->draw_scroll(); + glPopMatrix(); + } +} + + + +/************************** GLUI_TextBox::update_substring_bounds() *********/ + +int GLUI_TextBox::update_substring_bounds( void ) +{ + int box_width; + int text_len = int(text.length()); + int old_start, old_end; + + old_start = substring_start; + old_end = substring_end; + + /*** Calculate the width of the usable area of the edit box ***/ + box_width = get_box_width(); + + CLAMP( substring_end, 0, MAX(text_len-1,0) ); + CLAMP( substring_start, 0, MAX(text_len-1,0) ); + + if ( debug ) dump( stdout, "-> UPDATE SS" ); + + if ( insertion_pt >= 0 AND + insertion_pt < substring_start ) { /* cursor moved left */ + substring_start = insertion_pt; + + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_end--; + } + else if ( insertion_pt > substring_end ) { /* cursor moved right */ + substring_end = insertion_pt-1; + + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_start++; + } + else { /* cursor is within old substring bounds */ + if ( last_insertion_pt > insertion_pt ) { /* cursor moved left */ + } + else { + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_end--; + + while(substring_width( substring_start, substring_end+1 ) <= box_width + AND substring_end < text_len-1 ) + substring_end++; + } + } + + while ( substring_width( substring_start, substring_end ) > box_width ) + substring_end--; + + last_insertion_pt = insertion_pt; + + /*** No selection if not enabled ***/ + if ( NOT enabled ) { + sel_start = sel_end = 0; + } + + if ( debug ) dump( stdout, "<- UPDATE SS" ); + + if ( substring_start == old_start AND substring_end == old_end ) + return false; /*** bounds did not change ***/ + else + return true; /*** bounds did change ***/ + +} + + +/********************************* GLUI_TextBox::update_x_offsets() *********/ + +void GLUI_TextBox::update_x_offsets( void ) +{ +} + + +/********************************* GLUI_TextBox::draw_text() ****************/ + +void GLUI_TextBox::draw_text( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int text_x, i, sel_lo, sel_hi, x_pos; + + if ( debug ) dump( stdout, "-> DRAW_TEXT" ); + + /** Find where to draw the text **/ + + text_x = 2 + GLUI_TEXTBOX_BOXINNERMARGINX; + + /** Find lower and upper selection bounds **/ + sel_lo = MIN(sel_start, sel_end ); + sel_hi = MAX(sel_start, sel_end ); + + int sel_x_start, sel_x_end, delta; + + /** Draw selection area dark **/ + if ( sel_start != sel_end ) { + sel_x_start = text_x; + sel_x_end = text_x; + delta = 0; + for( i=substring_start; sel_x_end < (w - text_x) && i<=substring_end; i++ ) { + delta = 0; + if (text[i] == '\t') // Character is a tab, go to next tab stop + while (((delta + sel_x_end) < (w - text_x)) && + (delta == 0 || delta % tab_width)) + delta++; + else + delta = char_width( text[i] ); + + if ( i < sel_lo ) { + sel_x_start += delta; + sel_x_end += delta; + } + else if ( i < sel_hi ) { + sel_x_end += delta; + } + } + + glColor3f( 0.0f, 0.0f, .6f ); + glRecti(sel_x_start, y+5, sel_x_end, y+20); + } + + + if ( sel_start == sel_end ) { // No current selection + x_pos = text_x; + if ( enabled ) + glColor3b( 0, 0, 0 ); + else + glColor3b( 32, 32, 32 ); + + glRasterPos2i( text_x, y+LINE_HEIGHT); + for( i=substring_start; i<=substring_end; i++ ) { + if (this->text[i] == '\t') { // Character is a tab, go to next tab stop + x_pos = ((x_pos-text_x)/tab_width)*tab_width+tab_width+text_x; + glRasterPos2i( x_pos, y+LINE_HEIGHT); // Reposition pen after tab + } else { + glutBitmapCharacter( get_font(), this->text[i] ); + x_pos += char_width( this->text[i] ); + } + } + } + else { // There is a selection + x_pos = text_x; + for( i=substring_start; i<=substring_end; i++ ) { + if ( IN_BOUNDS( i, sel_lo, sel_hi-1)) { // This character is selected + glColor3f( 1., 1., 1. ); + glRasterPos2i( x_pos, y+LINE_HEIGHT); + if (this->text[i] == '\t') { // Character is a tab, go to next tab stop + x_pos = ((x_pos-text_x)/tab_width)*tab_width+tab_width+text_x; + } + else + glutBitmapCharacter( get_font(), this->text[i] ); + } + else { + glColor3f( 0., 0., 0. ); + glRasterPos2i( x_pos, y+LINE_HEIGHT); + if (this->text[i] == '\t') { // Character is a tab, go to next tab stop + x_pos = ((x_pos-text_x)/tab_width)*tab_width+tab_width+text_x; + glRasterPos2i( x_pos, y+LINE_HEIGHT); // Reposition pen after tab + } else + glutBitmapCharacter( get_font(), this->text[i] ); + } + + x_pos += char_width( text[i] ); + } + } + + if ( debug ) dump( stdout, "<- DRAW_TEXT" ); +} + + +/******************************** GLUI_TextBox::find_insertion_pt() *********/ +/* This function returns the character number *before which* the insertion */ +/* point goes */ + +int GLUI_TextBox::find_insertion_pt( int x, int y ) +{ + /*** See if we clicked outside box ***/ + if ( x < this->x_abs || y < this->y_abs) + return -1; + + /*** See if we clicked in an empty box ***/ + if ( text.empty() ) + return 0; + + /* update insert variables */ + insert_x = x; + insert_y = y; + + int text_length = int(text.length())-1; + int box_width = get_box_width(); + + int sol = 0; + int eol = 0; + int line = 0; + + int y_off = y - (y_abs + 2 + GLUI_TEXTBOX_BOXINNERMARGINX); + int x_off = x - (x_abs + 2 + GLUI_TEXTBOX_BOXINNERMARGINX); + + /* Find the line clicked, + The possibility of long lines getting wrapped complicates this. */ + while ((line-start_line+1)*LINE_HEIGHT < y_off && eol < text_length) + { + while (eol < text_length && text[eol] != '\n' && + substring_width(sol, eol+1) <= box_width) + { + eol++; + } + if (text[eol]=='\n' && eol=x_off) { + // did we go far enough? (see if click was >1/2 width of last char) + int decision_pt = prev_w+(total_w-prev_w)/2; + if (x_off>decision_pt) eol++; + } + return eol; + +#if 0 + while (eol < text_length && text[eol] != '\n' && + substring_width(sol, eol+1) < box_width ) + { + eol++; + } + + + /* We move from right to left, looking to see if the mouse was clicked + to the right of the ith character */ +#if 0 + int curr_x = this->x_abs + + substring_width( sol, eol ) + + 2 /* The edittext box has a 2-pixel margin */ + + GLUI_TEXTBOX_BOXINNERMARGINX; /** plus this many pixels blank space + between the text and the box **/ +#endif + + /** find mouse click in text **/ + + if (x_off > substring_width(sol, eol)) + return eol; + + for(i = sol; i <= eol+1; i++) { + if (x_off <= substring_width(sol, i)) + return i+1; + } + return 0; +#endif +} + + +int GLUI_TextBox::get_box_width() +{ + return MAX( this->w + - 4 /* 2 * the two-line box border */ + - 2 * GLUI_TEXTBOX_BOXINNERMARGINX, 0 ); + +} + +/******************************** GLUI_TextBox::draw_insertion_pt() *********/ + +void GLUI_TextBox::draw_insertion_pt( void ) +{ + int curr_x, box_width, text_length, eol, sol, line; + + if ( NOT can_draw() ) + return; + + /*** Don't draw insertion pt if control is disabled ***/ + if ( NOT enabled ) + return; + + if ( sel_start != sel_end OR insertion_pt < 0 ) { + return; /* Don't draw insertion point if there is a current selection */ + } + + if ( debug ) dump( stdout, "-> DRAW_INS_PT" ); + + /* printf( "insertion pt: %d\n", insertion_pt ); */ + + box_width = get_box_width(); + + // This function is unable to distinguish whether an insertion + // point on a line break should be drawn on the line before or the line after. + // This depends on the sequence of operations used to get there, and this + // function just doesn't have that information. If curr_line were kept up + // to date elsewhere that could be used here to disambiguate, but arrow keys + // and such do not update it. + + sol = 0; + eol = 0; + text_length = int(text.length())-1; + + //while (eol < text_length && text[eol] != '\n' + // && substring_width(sol, eol + 1) < box_width ) + // eol++; + line = 0; + while (eol < insertion_pt && eol <= text_length) + { + if (text[eol] == '\n' || substring_width(sol, eol + 1) >= box_width) + { + eol++; + if (text[eol]=='\n'||eol!=insertion_pt + ||(eol==insertion_pt && eol>0 && text[eol-1]=='\n')) { + sol = eol; + line++; + } + } + else { + eol++; + } + } + + //glColor3f(1,0,0); + //glRecti(0, curr_line*LINE_HEIGHT, 3, (curr_line+1)*LINE_HEIGHT); + + curr_line = line; + + if (scrollbar) + scrollbar->set_int_val(start_line); + if (curr_line < start_line || curr_line > (start_line + visible_lines)) /* Insertion pt out of draw area */ + return; + + curr_x = this->x_abs + + 2 /* The edittext box has a 2-pixel margin */ + + GLUI_TEXTBOX_BOXINNERMARGINX; /** plus this many pixels blank space + between the text and the box **/ + + curr_x += substring_width(sol,insertion_pt-1); + if (insertion_pt == text.length() && text[text.length()-1] == '\n' + || curr_x-this->x_abs > (w - 2 - GLUI_TEXTBOX_BOXINNERMARGINX)) { // Insert on the next line + curr_x = this->x_abs + GLUI_TEXTBOX_BOXINNERMARGINX; + line++; + } + /* update insertion coordinates */ + insert_x = curr_x+5; /* I hate magic numbers too, these offset the imagined insertion point */ + insert_y = (curr_line-start_line+2)*LINE_HEIGHT; + + + glColor3f( 0.0, 0.0, 0.0 ); + glBegin( GL_LINE_LOOP ); + + curr_x -= x_abs; + glVertex2i( curr_x+1, (curr_line-start_line)*LINE_HEIGHT + 4 ); + glVertex2i( curr_x, (curr_line-start_line)*LINE_HEIGHT + 4 ); + glVertex2i( curr_x+1, (curr_line-start_line)*LINE_HEIGHT + 16 ); + glVertex2i( curr_x, (curr_line-start_line)*LINE_HEIGHT + 16 ); + glEnd(); + + + if ( debug ) dump( stdout, "-> DRAW_INS_PT" ); +} + + + + +/******************************** GLUI_TextBox::substring_width() *********/ +int GLUI_TextBox::substring_width( int start, int end, int initial_width ) +{ + // This function only works properly if start is really the start of a line. + // Otherwise tabs will be messed up. + int i, width = initial_width; + + for( i=start; i<=end; i++ ) + if (text[i] == '\t') { // Character is a tab, jump to next tab stop + width += tab_width-(width%tab_width); + //while (width == 0 || width % tab_width) + // width++; + } + else + width += char_width( text[i] ); + + return width; +} + + +/***************************** GLUI_TextBox::update_and_draw_text() ********/ + +void GLUI_TextBox::update_and_draw_text( void ) +{ + //update_substring_bounds(); + /* printf( "ss: %d/%d\n", substring_start, substring_end ); */ + + redraw(); +} + + +/********************************* GLUI_TextBox::special_handler() **********/ + +int GLUI_TextBox::special_handler( int key,int modifiers ) +{ + int tmp_insertion_pt; + if ( NOT glui ) + return false; + + if ( debug ) + printf( "SPECIAL:%d - mod:%d subs:%d/%d ins:%d sel:%d/%d\n", + key, modifiers, substring_start, substring_end,insertion_pt, + sel_start, sel_end ); + + if ( key == GLUT_KEY_DOWN ) { + if (insert_x == -1 || insert_y == -1) + return false; + tmp_insertion_pt = find_insertion_pt( keygoal_x, insert_y+LINE_HEIGHT); + if (tmp_insertion_pt < 0) + return false; + insertion_pt = tmp_insertion_pt; + sel_end = insertion_pt; + if (!(modifiers & GLUT_ACTIVE_SHIFT)) { + sel_start = sel_end; + } + if ( can_draw()) + update_and_draw_text(); + } else if ( key == GLUT_KEY_UP ) { + if (insert_x == -1 || insert_y == -1) + return false; + tmp_insertion_pt = find_insertion_pt( keygoal_x, insert_y-LINE_HEIGHT); + if (tmp_insertion_pt < 0) + return false; + insertion_pt = tmp_insertion_pt; + sel_end = insertion_pt; + if (!(modifiers & GLUT_ACTIVE_SHIFT)) { + sel_start = sel_end; + } + if ( can_draw()) + update_and_draw_text(); + } else if ( key == GLUT_KEY_LEFT ) { + if ( (modifiers & GLUT_ACTIVE_CTRL) != 0 ) { + insertion_pt = find_word_break( insertion_pt, -1 ); + } + else { + insertion_pt--; + } + // update keygoal_x! + } + else if ( key == GLUT_KEY_RIGHT ) { + if ( (modifiers & GLUT_ACTIVE_CTRL) != 0 ) { + insertion_pt = find_word_break( insertion_pt, +1 ); + } + else { + insertion_pt++; + } + // update keygoal_x! + } + else if ( key == GLUT_KEY_HOME ) { + insertion_pt = 0; + // update keygoal_x! + } + else if ( key == GLUT_KEY_END ) { + insertion_pt = int(text.length()); + // update keygoal_x! + } + + /*** Update selection if shift key is down ***/ + if ( (modifiers & GLUT_ACTIVE_SHIFT ) != 0 ) + sel_end = insertion_pt; + else + sel_start = sel_end = insertion_pt; + + + CLAMP( insertion_pt, 0, (int)text.length()); /* Make sure insertion_pt + is in bounds */ + CLAMP( sel_start, 0, (int)text.length()); /* Make sure insertion_pt + is in bounds */ + CLAMP( sel_end, 0, (int)text.length()); /* Make sure insertion_pt + is in bounds */ + + /******** Now redraw text ***********/ + if ( can_draw()) + update_and_draw_text(); + + return true; +} + + +/****************************** GLUI_TextBox::find_word_break() **********/ +/* It looks either left or right (depending on value of 'direction' */ +/* for the beginning of the next 'word', where word are characters */ +/* separated by one of the following tokens: " :-.," */ +/* If there is no next word in the specified direction, this returns */ +/* the beginning of 'text', or the very end. */ + +int GLUI_TextBox::find_word_break( int start, int direction ) +{ + int i, j; + char breaks[] = " \n\t:-.,"; + int num_break_chars = (int)strlen(breaks), text_len = int(text.length()); + int new_pt; + + /** If we're moving left, we have to start two back, in case we're either + already at the beginning of a word, or on a separating token. + Otherwise, this function would just return the word we're already at **/ + if ( direction == -1 ) { + start -= 2; + } + + /***** Iterate over text in the specified direction *****/ + for ( i=start; i >= 0 AND i < text_len; i += direction ) { + + /** For each character in text, iterate over list of separating tokens **/ + for( j=0; j 0 ) /* Return the end of string */ + return text_len; + else /* Return the beginning of the text */ + return 0; +} + + +/********************************** GLUI_TextBox::clear_substring() ********/ + +void GLUI_TextBox::clear_substring( int start, int end ) +{ + text.erase(start,end-start); +} + + + +/************************************ GLUI_TextBox::update_size() **********/ + +void GLUI_TextBox::update_size( void ) +{ + if ( NOT glui ) + return; + + if ( w < GLUI_TEXTBOX_MIN_TEXT_WIDTH ) + w = GLUI_TEXTBOX_MIN_TEXT_WIDTH; +} + + +/****************************** GLUI_TextBox::set_text() **********/ + +void GLUI_TextBox::set_text( const char *new_text ) +{ + text = new_text; + + substring_start = 0; + substring_end = int(text.length()) - 1; + insertion_pt = -1; + sel_start = 0; + sel_end = 0; + visible_lines = 0; + start_line = 0; + curr_line = 0; + num_lines = 0; + + if ( can_draw() ) + update_and_draw_text(); + + /*** Now update the live variable ***/ + output_live(true); +} + + +/*************************************** GLUI_TextBox::dump() **************/ + +void GLUI_TextBox::dump( FILE *out, const char *name ) +{ + fprintf( out, + "%s (edittext@%p): line:%d ins_pt:%d subs:%d/%d sel:%d/%d len:%zu\n", + name, this, curr_line, + insertion_pt, substring_start, substring_end, sel_start, sel_end, + text.length()); +} + + +/**************************************** GLUI_TextBox::mouse_over() ********/ + +int GLUI_TextBox::mouse_over( int state, int x, int y ) +{ + if ( state && enabled) { + /* curr_cursor = GLUT_CURSOR_TEXT; */ + glutSetCursor( GLUT_CURSOR_TEXT ); + } + else { + /* printf( "OUT\n" ); */ + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); + } + + return true; +} + +void GLUI_TextBox::scrollbar_callback(GLUI_Control *my_scrollbar) { + GLUI_Scrollbar *sb = my_scrollbar->dynamicCastGLUI_Scrollbar(); + if (!sb) return; + GLUI_TextBox* me = (GLUI_TextBox*) sb->associated_object; + if (me->scrollbar == NULL) + return; + int new_start_line = sb->get_int_val(); // ?? + me->start_line = new_start_line; + if (new_start_line < (me->curr_line - me->visible_lines)) + me->curr_line = new_start_line + me->visible_lines; + if (new_start_line > me->curr_line) + me->curr_line = new_start_line; + if ( me->can_draw() ) + me->update_and_draw_text(); +} diff --git a/Extras/glui/glui_translation.cpp b/Extras/glui/glui_translation.cpp new file mode 100644 index 0000000..43e82d8 --- /dev/null +++ b/Extras/glui/glui_translation.cpp @@ -0,0 +1,559 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_translation - GLUI_Translation control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#include "GL/glui.h" +#include "glui_internal.h" +#include "algebra3.h" + +/********************** GLUI_Translation::GLUI_Translation() ***/ + +GLUI_Translation::GLUI_Translation( + GLUI_Node *parent, const char *name, + int trans_t, float *value_ptr, + int id, GLUI_CB cb ) +{ + common_init(); + + set_ptr_val( value_ptr ); + user_id = id; + set_name( name ); + callback = cb; + parent->add_control( this ); + //init_live(); + + trans_type = trans_t; + + if ( trans_type == GLUI_TRANSLATION_XY ) { + float_array_size = 2; + } + else if ( trans_type == GLUI_TRANSLATION_X ) { + float_array_size = 1; + } + else if ( trans_type == GLUI_TRANSLATION_Y ) { + float_array_size = 1; + } + else if ( trans_type == GLUI_TRANSLATION_Z ) { + float_array_size = 1; + } + init_live(); +} + +/********************** GLUI_Translation::iaction_mouse_down_handler() ***/ +/* These are really in local coords (5/10/99) */ + +int GLUI_Translation::iaction_mouse_down_handler( int local_x, + int local_y ) +{ + int center_x, center_y; + + down_x = local_x; + down_y = local_y; + + if ( trans_type == GLUI_TRANSLATION_XY ) { + orig_x = float_array_val[0]; + orig_y = float_array_val[1]; + + /** Check if the Alt key is down, which means lock to an axis **/ + + center_x = w/2; + center_y = (h-18)/2; + + if ( glui->curr_modifiers & GLUT_ACTIVE_ALT ) { + if ( ABS(local_y-center_y) > ABS(local_x-center_x) ) { + locked = GLUI_TRANSLATION_LOCK_Y; + glutSetCursor( GLUT_CURSOR_UP_DOWN ); + } + else { + locked = GLUI_TRANSLATION_LOCK_X; + glutSetCursor( GLUT_CURSOR_LEFT_RIGHT ); + } + } + else { + locked = GLUI_TRANSLATION_LOCK_NONE; + glutSetCursor( GLUT_CURSOR_SPRAY ); + } + } + else if ( trans_type == GLUI_TRANSLATION_X ) { + glutSetCursor( GLUT_CURSOR_LEFT_RIGHT ); + orig_x = float_array_val[0]; + } + else if ( trans_type == GLUI_TRANSLATION_Y ) { + glutSetCursor( GLUT_CURSOR_UP_DOWN ); + orig_y = float_array_val[0]; + } + else if ( trans_type == GLUI_TRANSLATION_Z ) { + glutSetCursor( GLUT_CURSOR_UP_DOWN ); + orig_z = float_array_val[0]; + } + + trans_mouse_code = 1; + redraw(); + + return false; +} + + +/*********************** GLUI_Translation::iaction_mouse_up_handler() **********/ + +int GLUI_Translation::iaction_mouse_up_handler( int local_x, int local_y, + bool inside ) +{ + trans_mouse_code = GLUI_TRANSLATION_MOUSE_NONE; + locked = GLUI_TRANSLATION_LOCK_NONE; + + redraw(); + + return false; +} + + +/******************* GLUI_Translation::iaction_mouse_held_down_handler() ******/ + +int GLUI_Translation::iaction_mouse_held_down_handler( int local_x, int local_y, + bool inside) +{ + float x_off, y_off; + float off_array[2]; + + x_off = scale_factor * (float)(local_x - down_x); + y_off = -scale_factor * (float)(local_y - down_y); + + if ( glui->curr_modifiers & GLUT_ACTIVE_SHIFT ) { + x_off *= 100.0f; + y_off *= 100.0f; + } + else if ( glui->curr_modifiers & GLUT_ACTIVE_CTRL ) { + x_off *= .01f; + y_off *= .01f; + } + + + if ( trans_type == GLUI_TRANSLATION_XY ) { + + if ( locked == GLUI_TRANSLATION_LOCK_X ) + y_off = 0.0; + else if ( locked == GLUI_TRANSLATION_LOCK_Y ) + x_off = 0.0; + + off_array[0] = x_off + orig_x; + off_array[1] = y_off + orig_y; + } + else if ( trans_type == GLUI_TRANSLATION_X ) { + off_array[0] = x_off + orig_x; + } + else if ( trans_type == GLUI_TRANSLATION_Y ) { + off_array[0] = y_off + orig_y; + } + else if ( trans_type == GLUI_TRANSLATION_Z ) { + off_array[0] = y_off + orig_z; + } + + set_float_array_val( (float*) &off_array[0] ); + + return false; +} + + +/******************** GLUI_Translation::iaction_draw_active_area_persp() **************/ + +void GLUI_Translation::iaction_draw_active_area_persp( void ) +{ +} + + +/******************** GLUI_Translation::iaction_draw_active_area_ortho() **********/ + +void GLUI_Translation::iaction_draw_active_area_ortho( void ) +{ + /********* Draw emboss circles around arcball control *********/ + float radius; + radius = (float)(h-22)/2.0; /* MIN((float)w/2.0, (float)h/2.0); */ + glLineWidth( 1.0 ); + + draw_emboss_box( (int) -radius-2, (int)radius+2, + (int)-radius-2, (int)radius+2 ); + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glTranslatef( .5, .5, .5 ); + /* glScalef( radius-1.0, radius-1.0, radius-1.0 ); */ + if ( trans_type == GLUI_TRANSLATION_Z ) + draw_2d_z_arrows((int)radius-1); + else if ( trans_type == GLUI_TRANSLATION_XY ) + draw_2d_xy_arrows((int)radius-1); + else if ( trans_type == GLUI_TRANSLATION_X ) + draw_2d_x_arrows((int)radius-1); + else if ( trans_type == GLUI_TRANSLATION_Y ) + draw_2d_y_arrows((int)radius-1); + + glPopMatrix(); +} + + +/******************************** GLUI_Translation::iaction_dump() **********/ + +void GLUI_Translation::iaction_dump( FILE *output ) +{ +} + + +/******************** GLUI_Translation::iaction_special_handler() **********/ + +int GLUI_Translation::iaction_special_handler( int key,int modifiers ) +{ + + return false; +} + + + +/*************************** GLUI_Translation::draw_2d_z_arrows() **************/ + +void GLUI_Translation::draw_2d_z_arrows( int radius ) +{ + if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) { + draw_2d_arrow(radius, true, 2); + draw_2d_arrow(radius, true, 0); + } + else { + draw_2d_arrow(radius, false, 2); + draw_2d_arrow(radius, false, 0); + } +} + + +/*************************** GLUI_Translation::draw_2d_x_arrows() **************/ + +void GLUI_Translation::draw_2d_x_arrows( int radius ) +{ + if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) { + draw_2d_arrow(radius, true, 1); + draw_2d_arrow(radius, true, 3); + } + else { + draw_2d_arrow(radius, false, 1); + draw_2d_arrow(radius, false, 3); + } +} + + +/*************************** GLUI_Translation::draw_2d_y_arrows() **************/ + +void GLUI_Translation::draw_2d_y_arrows( int radius ) +{ + if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) { + draw_2d_arrow(radius, true, 0); + draw_2d_arrow(radius, true, 2); + } + else { + draw_2d_arrow(radius, false, 0); + draw_2d_arrow(radius, false, 2); + } +} + + +/************************** GLUI_Translation::draw_2d_xy_arrows() **************/ + +void GLUI_Translation::draw_2d_xy_arrows( int radius) +{ + if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) { + if ( locked == GLUI_TRANSLATION_LOCK_X ) { + draw_2d_arrow(radius, false, 0); + draw_2d_arrow(radius, false, 2); + draw_2d_arrow(radius, true, 1); + draw_2d_arrow(radius, true, 3); + } + else if ( locked == GLUI_TRANSLATION_LOCK_Y ) { + draw_2d_arrow(radius, false, 1); + draw_2d_arrow(radius, false, 3); + draw_2d_arrow(radius, true, 0); + draw_2d_arrow(radius, true, 2); + } + else { + draw_2d_arrow(radius, true, 0); + draw_2d_arrow(radius, true, 1); + draw_2d_arrow(radius, true, 2); + draw_2d_arrow(radius, true, 3); + } + } + else { + draw_2d_arrow(radius, false, 0); + draw_2d_arrow(radius, false, 1); + draw_2d_arrow(radius, false, 2); + draw_2d_arrow(radius, false, 3); + } + + return; +} + + +/*************************** GLUI_Translation::draw_2d_arrow() **************/ +/* ori: 0=up, 1=left, 2=down, 3=right */ +/* */ +/* */ +/* 0, y2 */ +/* / \ */ +/* / \ */ +/* / \ */ +/* / \ */ +/* / \ */ +/* / \ */ +/* / \ */ +/* / \ */ +/* -x2,y1 -x1b,y1 x1b,y1 x2,y1 */ +/* | | */ +/* | | */ +/* | | */ +/* | | */ +/* | | */ +/* -x1a,y0 x1a,y0 */ +/* */ + + +void GLUI_Translation::draw_2d_arrow( int radius, int filled, int orientation ) +{ + float x1 = .2, x2 = .4, y1 = .54, y2 = .94, y0; + float x1a, x1b; +/* + vec3 col1( 0.0, 0.0, 0.0 ), col2( .45, .45, .45 ), + col3( .7, .7, .7 ), col4( 1.0, 1.0, 1.0 ); + vec3 c1, c2, c3, c4, c5, c6; +*/ + vec3 white(1.0,1.0,1.0), black(0.0,0.0,0.0), gray(.45,.45,.45), + bkgd(.7,.7,.7); + int c_off=0; /* color index offset */ + + if ( glui ) + bkgd.set(glui->bkgd_color_f[0], + glui->bkgd_color_f[1], + glui->bkgd_color_f[2]); + + /* bkgd[0] = 255.0; bkgd[1] = 0; */ + + /** The following 8 colors define the shading of an octagon, in + clockwise order, starting from the upstroke on the left **/ + /** This is for an outside and inside octagons **/ + vec3 colors_out[]={white, white, white, gray, black, black, black, gray}; + vec3 colors_in[] ={bkgd,white,bkgd,gray,gray,gray,gray,gray}; + +#define SET_COL_OUT(i) glColor3fv((float*) &colors_out[(i)%8][0]); +#define SET_COL_IN(i) glColor3fv((float*) &colors_in[(i)%8][0]); + + x1 = (float)radius * .2; + x2 = x1 * 2; + y1 = (float)radius * .54; + y2 = y1 + x2; + x1a = x1; + x1b = x1; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + +#define DRAW_SEG( xa,ya,xb,yb ) glVertex2f(xa,ya); glVertex2f(xb,yb); + + glScalef( -1.0, 1.0, 1.0 ); + + if ( orientation == 2 ) { + c_off = 4; + } + else if ( orientation == 0 ) { + c_off = 0; + glRotatef( 180.0, 0.0, 0.0, 1.0 ); + } + else if ( orientation == 1 ) { + c_off = 2; + glRotatef( 90.0, 0.0, 0.0, 1.0 ); + } + else if ( orientation == 3 ) { + c_off = 6; + glRotatef( -90.0, 0.0, 0.0, 1.0 ); + } + + if ( trans_type == GLUI_TRANSLATION_Z ) + y0 = 0.0; + else if ( trans_type == GLUI_TRANSLATION_XY ) + y0 = x1; + else + y0 = 0.0; + + + if ( trans_type == GLUI_TRANSLATION_Z ) { + if ( orientation == 0 ) { + y1 += 2.0; + y2 += 0.0; + + x1b -= 2.0; + x2 -= 2.0; + x1a += 2.0; + } + else if ( orientation == 2 ) { + y1 -= 6.0; + x1a += 2.0; + x1b += 4.0; + x2 += 6.0; + } + } + + /*** Fill in inside of arrow ***/ + if ( NOT filled ) { /*** Means button is up - control is not clicked ***/ + /*glColor3f( .8, .8, .8 ); */ + set_to_bkgd_color(); + glColor3f( bkgd[0]+.07, bkgd[1]+.07, bkgd[2]+.07 ); + } + else { /*** Button is down on control ***/ + glColor3f( .6, .6, .6 ); + c_off += 4; /* Indents the shadows - goes from a raised look to embossed */ + } + + /*** Check if control is enabled or not ***/ + if ( NOT enabled ) { + set_to_bkgd_color(); + /*c_off += 4; -- Indents the shadows - goes from a raised look to embossed */ + colors_out[0] = colors_out[1] = colors_out[2] = colors_out[7] = gray; + colors_out[3] = colors_out[4] = colors_out[5] = colors_out[6] = white; + colors_in[0] = colors_in[1] = colors_in[2] = colors_in[7] = white; + colors_in[3] = colors_in[4] = colors_in[5] = colors_in[6] = gray; + + } + + glBegin( GL_POLYGON ); + glVertex2f( 0.0, 0.0 ); glVertex2f( -x1a, 0.0 ); + glVertex2f( -x1a, 0.0 ); glVertex2f( -x1b, y1 ); + glVertex2f( x1b, y1); glVertex2f( x1a, 0.0 ); + glVertex2f( x1a, 0.0 ); glVertex2f( 0.0, 0.0 ); + glEnd(); + glBegin( GL_TRIANGLES ); + glVertex2f( -x2, y1 ); glVertex2f( 0.0, y2 ); glVertex2f( x2, y1 ); + glEnd(); + + glLineWidth( 1.0 ); + /*** Draw arrow outline ***/ + glBegin( GL_LINES ); + + SET_COL_IN(1+c_off); DRAW_SEG( 0.0, y2-1.0, -x2, y1-1.0 ); + SET_COL_IN(6+c_off); DRAW_SEG( -x2+2.0, y1+1.0, -x1b+1.0, y1+1.0 ); + SET_COL_IN(0+c_off); DRAW_SEG( -x1b+1.0, y1+1.0, -x1a+1.0, y0 ); + SET_COL_IN(3+c_off); DRAW_SEG( 0.0, y2-1.0, x2, y1-1.0 ); + SET_COL_IN(6+c_off); DRAW_SEG( x2-1.0, y1+1.0, x1b-1.0, y1+1.0 ); + SET_COL_IN(4+c_off); DRAW_SEG( x1b-1.0, y1+1.0, x1a-1.0, y0 ); + + SET_COL_OUT(0+c_off); DRAW_SEG( -x1a, y0, -x1b, y1 ); + SET_COL_OUT(6+c_off); DRAW_SEG( -x1b, y1, -x2, y1 ); + SET_COL_OUT(1+c_off); DRAW_SEG( -x2, y1, 0.0, y2 ); + SET_COL_OUT(3+c_off); DRAW_SEG( 0.0, y2, x2, y1 ); + SET_COL_OUT(6+c_off); DRAW_SEG( x2, y1, x1b, y1 ); + SET_COL_OUT(4+c_off); DRAW_SEG( x1b, y1, x1a, y0 ); + + glEnd(); + +#undef DRAW_SEG + + glPopMatrix(); +} + + +/*************************** GLUI_Translation::get_mouse_code() *************/ + +int GLUI_Translation::get_mouse_code( int x, int y ) +{ + if ( x == 0 AND y < 0 ) + return GLUI_TRANSLATION_MOUSE_DOWN; + else if ( x == 0 AND y > 0 ) + return GLUI_TRANSLATION_MOUSE_UP; + else if ( x > 0 AND y == 0 ) + return GLUI_TRANSLATION_MOUSE_LEFT; + else if ( x < 0 AND y == 0 ) + return GLUI_TRANSLATION_MOUSE_RIGHT; + else if ( x < 0 AND y < 0 ) + return GLUI_TRANSLATION_MOUSE_DOWN_LEFT; + else if ( x < 0 AND y > 0 ) + return GLUI_TRANSLATION_MOUSE_DOWN_RIGHT; + else if ( x > 0 AND y < 0 ) + return GLUI_TRANSLATION_MOUSE_UP_LEFT; + else if ( x > 0 AND y > 0 ) + return GLUI_TRANSLATION_MOUSE_UP_RIGHT; + + + return GLUI_TRANSLATION_MOUSE_NONE; +} + + +/*********************************** GLUI_Translation::set_x() ******/ + +void GLUI_Translation::set_x( float val ) +{ + set_one_val( val, 0 ); +} + + +/*********************************** GLUI_Translation::set_y() ******/ + +void GLUI_Translation::set_y( float val ) +{ + if ( trans_type == GLUI_TRANSLATION_XY ) + set_one_val( val, 1 ); + else + set_one_val( val, 0 ); +} + + +/*********************************** GLUI_Translation::set_z() ******/ + +void GLUI_Translation::set_z( float val ) +{ + set_one_val( val, 0 ); +} + + +/******************************* GLUI_Translation::set_one_val() ****/ + +void GLUI_Translation::set_one_val( float val, int index ) +{ + float *fp; + + float_array_val[index] = val; /* set value in array */ + + /*** The code below is like output_live, except it only operates on + a single member of the float array (given by 'index') instead of + outputting the entire array ****/ + + if ( ptr_val == NULL OR NOT live_inited ) + return; + + fp = (float*) ptr_val; + fp[index] = float_array_val[index]; + last_live_float_array[index] = float_array_val[index]; + + /** Update the main gfx window? **/ + if ( this->glui != NULL ) { + this->glui->post_update_main_gfx(); + } +} diff --git a/Extras/glui/glui_tree.cpp b/Extras/glui/glui_tree.cpp new file mode 100644 index 0000000..f253fa4 --- /dev/null +++ b/Extras/glui/glui_tree.cpp @@ -0,0 +1,278 @@ +/**************************************************************************** + + GLUI User Interface Toolkit + --------------------------- + + glui_panel.cpp - GLUI_Panel control class + + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. + +*****************************************************************************/ + +#include "glui_internal_control.h" + + +/****************************** GLUI_Tree::GLUI_Tree() **********/ +GLUI_Tree::GLUI_Tree(GLUI_Node *parent, const char *name, + int open, int inset) +{ + common_init(); + GLUI_StaticText *inset_label; + GLUI_Column *col; + + this->set_name( name ); + this->user_id = -1; + + if ( NOT open ) { + this->is_open = false; + this->h = GLUI_DEFAULT_CONTROL_HEIGHT + 7; + } + + parent->add_control( this ); + inset_label = new GLUI_StaticText(this,""); + inset_label->set_w(inset); + col = new GLUI_Column(this,true); + this->set_column(col); + this->set_alignment(GLUI_ALIGN_LEFT); +} + + +/****************************** GLUI_Tree::open() **********/ + +void GLUI_Tree::open( void ) +{ + if ( is_open ) + return; + is_open = true; + + GLUI_DRAWINGSENTINAL_IDIOM + + child_head = collapsed_node.child_head; + child_tail = collapsed_node.child_tail; + + collapsed_node.child_head = NULL; + collapsed_node.child_tail = NULL; + + if ( child_head != NULL ) { + ((GLUI_Control*) child_head)->unhide_internal( true ); + } + + glui->refresh(); +} + + +/****************************** GLUI_Tree::close() **********/ + +void GLUI_Tree::close( void ) +{ + if ( NOT glui ) + return; + + if ( NOT is_open ) + return; + is_open = false; + + GLUI_DRAWINGSENTINAL_IDIOM + + if ( child_head != NULL ) { + ((GLUI_Control*) child_head)->hide_internal( true ); + } + + collapsed_node.child_head = first_child(); + collapsed_node.child_tail = last_child(); + + child_head = NULL; + child_tail = NULL; + + this->h = GLUI_DEFAULT_CONTROL_HEIGHT + 7; + + glui->refresh(); +} + + +/**************************** GLUI_Tree::mouse_down_handler() **********/ + + +int GLUI_Tree::mouse_down_handler( int local_x, int local_y ) +{ + if ( local_y - y_abs > 18 ) { + initially_inside = currently_inside = false; + return false; + } + + currently_inside = true; + initially_inside = true; + redraw(); + + return false; +} + +/**************************** GLUI_Tree::mouse_held_down_handler() ****/ + +int GLUI_Tree::mouse_held_down_handler( + int local_x, int local_y, + bool new_inside ) +{ + if ( NOT initially_inside ) + return false; + + if ( local_y - y_abs> 18 ) + new_inside = false; + + if (currently_inside != new_inside) + redraw(); + + return false; +} + + +/**************************** GLUI_Tree::mouse_down_handler() **********/ + +int GLUI_Tree::mouse_up_handler( int local_x, int local_y, bool inside ) +{ + if ( currently_inside ) { + if ( is_open ) + close(); + else + open(); + } + + currently_inside = false; + initially_inside = false; + redraw(); + + return false; +} + + +/********************************* GLUI_Tree::draw() ***********/ + +void GLUI_Tree::draw( int x, int y ) +{ + GLUI_DRAWINGSENTINAL_IDIOM + int left, right, top, bottom, delta_x; + + left = 5; + right = w-left; + top = 3; + bottom = 3+16; + delta_x = 0; + + glui->draw_raised_box( left, top, 16, 16 ); + + if ( glui ) + glColor3ub(glui->bkgd_color.r,glui->bkgd_color.g,glui->bkgd_color.b); + glDisable( GL_CULL_FACE ); + glBegin( GL_QUADS ); + glVertex2i( left+17, top+1 ); glVertex2i( right-1, top+1 ); + glVertex2i( right-1, bottom-1 ); glVertex2i( left+17, bottom-1 ); + glEnd(); + + if (format & GLUI_TREEPANEL_DISPLAY_HIERARCHY) { + delta_x = string_width( level_name ) + char_width(' '); + glColor3f( lred, lgreen, lblue); /* The hierarchy is drawn in bold */ + glRasterPos2i(left + 25, top + 11); + draw_string(level_name); + glRasterPos2i(left + 24, top + 11); + draw_string(level_name); + } + + draw_name( delta_x+left+24, top+11 ); + + if ( active ) + draw_active_box( left+22, delta_x+left+string_width( name )+32, + top, bottom-2 ); + + + /** Draw '+' or '-' **/ + + glBegin( GL_LINES ); + if ( is_open ) { + if ( enabled ) + if (is_current) + glColor3f( 0, 0, 1 ); + else + glColor3f( 0.0, 0.0, 0.0 ); + else + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2i(left+4,(top+bottom)/2); glVertex2i(left+13,(top+bottom)/2); + + glColor3f( 1.0, 1.0, 1.0 ); + glVertex2i(left+4,1+(top+bottom)/2);glVertex2i(left+13,1+(top+bottom)/2); + } + else + { + glColor3f( 1.0, 1.0, 1.0 ); + glVertex2i(left+9,top+3); glVertex2i(left+9,bottom-4); + glVertex2i(left+4,(top+bottom)/2); glVertex2i(left+13,(top+bottom)/2); + + if ( enabled ) + if (is_current) + glColor3f( 0, 0, 1 ); + else + glColor3f( 0.0, 0.0, 0.0 ); + else + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2i(left+4,-1+(top+bottom)/2); + glVertex2i(left+13,-1+(top+bottom)/2); + glVertex2i(left+8,top+3); + glVertex2i(left+8,bottom-4); + } + glEnd(); + + glLineWidth( 1.0 ); + + if (currently_inside) draw_pressed(); +} + + +/***************************** GLUI_Tree::update_size() **********/ + +void GLUI_Tree::update_size( void ) +{ + int text_size = 0, delta_x = 0; + + if ( NOT glui ) + return; + + text_size = string_width(name); + + if (format & GLUI_TREEPANEL_DISPLAY_HIERARCHY) { + delta_x = string_width( level_name ); + } + + if ( w < text_size + 36 + delta_x) + w = text_size + 36 + delta_x; +} + + +/**************************** GLUI_Tree::draw_pressed() ***********/ + +void GLUI_Tree::draw_pressed( void ) +{ + int left, right, top, bottom; + + left = 5; + right = w-left; + top = 3; + bottom = 3+16; + + glColor3f( 0.0, 0.0, 0.0 ); + + glBegin( GL_LINE_LOOP ); + glVertex2i( left, top ); glVertex2i( right, top ); + glVertex2i( right, bottom ); glVertex2i( left,bottom ); + glEnd(); + + glBegin( GL_LINE_LOOP ); + glVertex2i( left+1, top+1 ); glVertex2i( right-1, top+1 ); + glVertex2i( right-1, bottom-1 ); glVertex2i( left+1,bottom-1 ); + glEnd(); +} diff --git a/Extras/glui/glui_treepanel.cpp b/Extras/glui/glui_treepanel.cpp new file mode 100644 index 0000000..27c659c --- /dev/null +++ b/Extras/glui/glui_treepanel.cpp @@ -0,0 +1,388 @@ +#include "GL/glui.h" + + +/****************************** GLUI_TreePanel::GLUI_TreePanel() *********/ + +GLUI_TreePanel::GLUI_TreePanel(GLUI_Node *parent, const char *name, + bool open, int inset) +{ + common_init(); + + set_name( name ); + user_id = -1; + + if ( !open ) { + is_open = false; + h = GLUI_DEFAULT_CONTROL_HEIGHT + 7; + } + + parent->add_control( this ); +} + +/****************************** GLUI_TreePanel::set_color() *********/ + +void GLUI_TreePanel::set_color(float r, float g, float b) +{ + red = r; + green = g; + blue = b; + redraw(); +} + +/************************ GLUI_TreePanel::set_level_color() *********/ + +void GLUI_TreePanel::set_level_color(float r, float g, float b) +{ + lred = r; + lgreen = g; + lblue = b; + redraw(); +} + +/****************************** GLUI_TreePanel::ab() *********/ + +/* Adds branch to curr_root */ +GLUI_Tree *GLUI_TreePanel::ab(const char *name, GLUI_Tree *root) +{ + GLUI_Tree *temp; + + + if (root != NULL) { + resetToRoot(root); + } + + temp = new GLUI_Tree(curr_root, name); + initNode(temp); + formatNode(temp); + + curr_root = temp; + curr_branch = NULL; /* Currently at leaf */ + + if (temp->dynamicCastGLUI_Tree()) + ((GLUI_Tree *)temp)->set_current(true); + //refresh(); + // glui->deactivate_current_control(); + //glui->activate_control( temp, GLUI_ACTIVATE_TAB ); + return temp; + +} + +/****************************** GLUI_TreePanel::fb() *********/ + +/* Goes up one level, resets curr_root and curr_branch to parents*/ +void GLUI_TreePanel::fb(GLUI_Tree *branch) +{ + if (((GLUI_Panel *)branch) == ((GLUI_Panel *)this)) + return; + + if (((GLUI_Panel *)curr_branch) == ((GLUI_Panel *)this)) { + resetToRoot(); + return; + } + if (((GLUI_Panel *)curr_root) == ((GLUI_Panel *)this)) { + resetToRoot(); + return; + } + + if (branch != NULL) { + + if ( branch->dynamicCastGLUI_Tree() ) + ((GLUI_Tree *)branch)->set_current(false); + + curr_branch = (GLUI_Tree *)branch->next(); + curr_root = (GLUI_Panel *)branch->parent(); + + if (curr_branch == NULL && (curr_root->collapsed_node).first_child() != NULL) + curr_branch = (GLUI_Tree *)(curr_root->collapsed_node).first_child(); + + + if ( curr_root->dynamicCastGLUI_Tree() ) + ((GLUI_Tree *)curr_root)->set_current(true); + + } else { + if (curr_root != NULL) { /* up one parent */ + + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree *)curr_root)->set_current(false); + + curr_branch = (GLUI_Tree *) curr_root->next(); + curr_root = (GLUI_Panel *) curr_root->parent(); + + if (curr_branch == NULL && (curr_root->collapsed_node).first_child() != NULL) + curr_branch = (GLUI_Tree *)(curr_root->collapsed_node).first_child(); + + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree *)curr_root)->set_current(true); + + } + + } + //refresh(); +} + + +/****************************** GLUI_TreePanel::refresh() *********/ + +void GLUI_TreePanel::refresh() +{ + glui->deactivate_current_control(); + glui->activate_control( curr_root, GLUI_ACTIVATE_TAB ); + + redraw(); +} + +/****************************** GLUI_TreePanel::initNode() *********/ + +void GLUI_TreePanel::initNode(GLUI_Tree *temp) +{ + if (temp == NULL) + return; + int level = temp->get_level(); + int child_number = 1; + + GLUI_Tree *ptree = temp->parent()->dynamicCastGLUI_Tree(); + if (ptree) { + level = ptree->get_level() + 1; + GLUI_Tree *prevTree = temp->prev()->dynamicCastGLUI_Tree(); + if (prevTree) { + child_number = prevTree->get_child_number() + 1; + } + } else if (temp->dynamicCastGLUI_Tree() && + temp->parent()->dynamicCastGLUI_TreePanel()) { + child_number = ++root_children; + } + temp->set_id(uniqueID()); // -1 if unset + temp->set_level(level); + temp->set_child_number(child_number); +} + +/****************************** GLUI_TreePanel::formatNode() *********/ + +void GLUI_TreePanel::formatNode(GLUI_Tree *temp) +{ + if (temp == NULL) + return; + int level = temp->get_level(); + int child_number = temp->get_child_number(); + GLUI_String level_name=""; + GLUI_String full_name=""; + + temp->level_name == ""; + + if (format & GLUI_TREEPANEL_DISPLAY_HIERARCHY) { + if (format & GLUI_TREEPANEL_HIERARCHY_LEVEL_ONLY) { + glui_format_str(level_name, "%d", level); + } + if (format & GLUI_TREEPANEL_HIERARCHY_NUMERICDOT) { + if ( temp->parent()->dynamicCastGLUI_Tree() ) + glui_format_str(level_name, "%s.%d", + ((GLUI_Tree *)(temp->parent()))->level_name.c_str(), + child_number); + else + glui_format_str(level_name, "%d", child_number); + } + } + + temp->set_level_color(lred, lgreen, lblue); + temp->set_format(format); + temp->level_name = level_name; + + if (format & GLUI_TREEPANEL_ALTERNATE_COLOR) { + switch (level%8) { + case (7): temp->set_color(.5,.5,.5); break; + case (6): temp->set_color(.3,.5,.5); break; + case (5): temp->set_color(.5,.3,.5); break; + case (4): temp->set_color(.3,.3,.5); break; + case (3): temp->set_color(.5,.5,.3); break; + case (2): temp->set_color(.3,.5,.3); break; + case (1): temp->set_color(.5,.3,.3); break; + default: temp->set_color(.3,.3,.3); + } + } else { + temp->set_color(red,green,blue); + } + + if (format & GLUI_TREEPANEL_DISABLE_BAR) { + temp->disable_bar(); + } else { + if (format & GLUI_TREEPANEL_DISABLE_DEEPEST_BAR) { + temp->disable_bar(); + if ( curr_root->dynamicCastGLUI_Tree() ) + ((GLUI_Tree *)curr_root)->enable_bar(); + } else + if (format & GLUI_TREEPANEL_CONNECT_CHILDREN_ONLY) { + temp->disable_bar(); + if (temp->prev() && temp->prev()->dynamicCastGLUI_Tree() ) + { + ((GLUI_Tree *)temp->prev())->enable_bar(); + } + } + } +} + +/****************************** GLUI_TreePanel::update_all() *********/ + +void GLUI_TreePanel::update_all() +{ + printf("GLUI_TreePanel::update_all() doesn't work yet. - JVK\n"); + return; + GLUI_Panel *saved_root = curr_root; + GLUI_Tree *saved_branch = curr_branch; + root_children = 0; + resetToRoot(this); + if (curr_branch && curr_branch->dynamicCastGLUI_Tree()) + formatNode((GLUI_Tree *)curr_branch); + next(); + while (curr_root && curr_branch != this->first_child()) { + if (curr_branch && curr_branch->dynamicCastGLUI_Tree()) { + formatNode((GLUI_Tree *)curr_branch); + } + next(); + } + curr_root = saved_root; + curr_branch = saved_branch; +} + +/****************************** GLUI_TreePanel::expand_all() *********/ + +void GLUI_TreePanel::expand_all() +{ + GLUI_Panel *saved_root = curr_root; + GLUI_Tree *saved_branch = curr_branch; + + resetToRoot(this); + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree*)curr_root)->open(); + next(); + while (curr_root != NULL && curr_branch != this->first_child()) { + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree*)curr_root)->open(); + next(); + } + + curr_root = saved_root; + curr_branch = saved_branch; +} + +/****************************** GLUI_TreePanel::collapse_all() *********/ + +void GLUI_TreePanel::collapse_all() +{ + GLUI_Panel *saved_root = curr_root; + GLUI_Tree *saved_branch = curr_branch; + + resetToRoot(this); + next(); + while (curr_root != NULL && curr_branch != this->first_child()) { + if (curr_root->dynamicCastGLUI_Tree() && + curr_branch == NULL) { /* we want to close everything leaf-first */ + ((GLUI_Tree*)curr_root)->close(); + /* Rather than simply next(), we need to manually move the + curr_root because this node has been moved to the + collapsed_node list */ + curr_branch = (GLUI_Tree *)curr_root->next(); + curr_root = (GLUI_Panel *)curr_root->parent(); + } else + next(); + } + + curr_root = saved_root; + curr_branch = saved_branch; + +} + +/****************************** GLUI_TreePanel::db() *********/ + +/* Deletes the curr_root */ +void GLUI_TreePanel::db(GLUI_Tree *root) +{ + GLUI_Tree *temp_branch; + GLUI_Panel *temp_root; + + if (((GLUI_Control *)root) == ((GLUI_Control *)this)) + return; + + if (root != NULL) { + curr_root = (GLUI_Tree *)root; + curr_branch = NULL; + } + + if (curr_root == NULL || ((GLUI_Panel *)curr_root) == ((GLUI_Panel *)this)) { + resetToRoot(); + return; + } + + + temp_branch = (GLUI_Tree *)curr_root->next(); /* Next branch, if any */ + temp_root = (GLUI_Panel *)curr_root->parent(); /* new root */ + curr_root->unlink(); + delete curr_root; + curr_branch = (GLUI_Tree *) temp_branch; + curr_root = (GLUI_Panel *) temp_root; + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree *)curr_root)->open(); + + if ((format & GLUI_TREEPANEL_DISABLE_DEEPEST_BAR) == GLUI_TREEPANEL_DISABLE_DEEPEST_BAR) { + if (curr_root->dynamicCastGLUI_Tree() && ((GLUI_Tree *)curr_root->next()) == NULL) + ((GLUI_Tree *)curr_root)->disable_bar(); + } + //refresh(); +} + +/****************************** GLUI_TreePanel::descendBranch() *********/ + +/* Finds the very last branch of curr_root, resets vars */ +void GLUI_TreePanel::descendBranch(GLUI_Panel *root) { + if (root) + resetToRoot(root); + else + resetToRoot(curr_root); + if (curr_branch != NULL && curr_branch != ((GLUI_Panel *)this)) { + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree *)curr_root)->set_current(false); + descendBranch(curr_branch); + } +} + +/****************************** GLUI_TreePanel::next() *********/ + +void GLUI_TreePanel::next() +{ + if (curr_root == NULL) + resetToRoot(this); + + if (curr_branch == NULL && (curr_root->collapsed_node).first_child() != NULL) + curr_branch = (GLUI_Tree *)(curr_root->collapsed_node).first_child(); + + + if (curr_branch != NULL && curr_branch != ((GLUI_Panel *)this)) { /* Descend into branch */ + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree *)curr_root)->set_current(false); + resetToRoot(curr_branch); + } else if (curr_branch == NULL) { + fb(NULL); /* Backup and move on */ + } +} + +/****************************** GLUI_TreePanel::resetToRoot() *********/ + +/* Resets curr_root and curr branch to TreePanel and lastChild */ +void GLUI_TreePanel::resetToRoot(GLUI_Panel *new_root) +{ + GLUI_Panel *root = this; + if (new_root != NULL) + root = new_root; + curr_root = root; + if (curr_root->dynamicCastGLUI_Tree()) + ((GLUI_Tree *)curr_root)->set_current(true); + curr_branch = (GLUI_Tree *)root->first_child(); + + /* since Trees are collapsable, we need to check the collapsed nodes + in case the curr_root is collapsed */ + if (curr_branch == NULL && (root->collapsed_node).first_child() != NULL) { + curr_branch = (GLUI_Tree *)(root->collapsed_node).first_child(); + } + while (curr_branch && curr_branch->dynamicCastGLUI_Tree()) { + curr_branch=(GLUI_Tree *)curr_branch->next(); + } +} diff --git a/Extras/glui/glui_window.cpp b/Extras/glui/glui_window.cpp new file mode 100644 index 0000000..02c2d0d --- /dev/null +++ b/Extras/glui/glui_window.cpp @@ -0,0 +1,44 @@ +/* + + glui_window.cpp - GLUI_Button control class + + GLUI User Interface Toolkit (LGPL) + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "GL/glui.h" +#include "glui_internal.h" + +GLUI_Glut_Window::GLUI_Glut_Window() +: GLUI_Node(), + + glut_window_id(0), + glut_keyboard_CB(NULL), + glut_special_CB(NULL), + glut_reshape_CB(NULL), + glut_passive_motion_CB(NULL), + glut_mouse_CB(NULL), + glut_visibility_CB(NULL), + glut_motion_CB(NULL), + glut_display_CB(NULL), + glut_entry_CB(NULL) +{ +} diff --git a/Extras/glui/quaternion.cpp b/Extras/glui/quaternion.cpp new file mode 100644 index 0000000..d73523e --- /dev/null +++ b/Extras/glui/quaternion.cpp @@ -0,0 +1,243 @@ +/*********************************************************************** + + quaternion.cpp - A quaternion class + + ------------------------------------------------------------------- + + GLUI User Interface Toolkit (LGPL) + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +************************************************************************ + + Feb 1998, Paul Rademacher (rademach@cs.unc.edu) + Oct 2003, Nigel Stewart - GLUI Code Cleaning + +************************************************************************/ +#include "glui_internal_control.h" +#include "quaternion.h" +#include +#include "glui_internal.h" + +/******************************************* constructors **************/ + +quat::quat() +{ + *this = quat_identity(); +} + +quat::quat(const float x, const float y, const float z, const float w) +{ + v.set( x, y, z ); + s = w; +} + +quat::quat(const vec3 &_v, const float _s) +{ + set( _v, _s ); +} + +quat::quat(const float _s, const vec3 &_v) +{ + set( _v, _s ); +} + +quat::quat(const float *d) +{ + v[0] = d[0]; + v[1] = d[1]; + v[2] = d[2]; + s = d[3]; +} + +quat::quat(const double *d) +{ + v[0] = (float) d[0]; + v[1] = (float) d[1]; + v[2] = (float) d[2]; + s = (float) d[3]; +} + +quat::quat(const quat &q) +{ + v = q.v; + s = q.s; +} + +void quat::set(const vec3 &_v, const float _s) +{ + v = _v; + s = _s; +} + +quat &quat::operator=(const quat &q) +{ + v = q.v; + s = q.s; + return *this; +} + +/******** quat friends ************/ + +quat operator + (const quat &a, const quat &b) +{ + return quat( a.s+b.s, a.v+b.v ); +} + +quat operator - (const quat &a, const quat &b) +{ + return quat( a.s-b.s, a.v-b.v ); +} + +quat operator - (const quat &a ) +{ + return quat( -a.s, -a.v ); +} + +quat operator * ( const quat &a, const quat &b) +{ + return quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + a.v^b.v ); +} + +quat operator * ( const quat &a, const float t) +{ + return quat( a.v * t, a.s * t ); +} + +quat operator * ( const float t, const quat &a ) +{ + return quat( a.v * t, a.s * t ); +} + +mat4 quat::to_mat4() const +{ + float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; + + float t = 2.0f / (v*v + s*s); + + xs = v[VX]*t; ys = v[VY]*t; zs = v[VZ]*t; + wx = s*xs; wy = s*ys; wz = s*zs; + xx = v[VX]*xs; xy = v[VX]*ys; xz = v[VX]*zs; + yy = v[VY]*ys; yz = v[VY]*zs; zz = v[VZ]*zs; + + mat4 matrix( + 1.0f-(yy+zz), xy+wz, xz-wy, 0.0f, + xy-wz, 1.0f-(xx+zz), yz+wx, 0.0f, + xz+wy, yz-wx, 1.0f-(xx+yy), 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f ); + + return matrix; +} + +/************************************************* quat_identity() *****/ +/* Returns quaternion identity element */ + +quat quat_identity() +{ + return quat( vec3( 0.0, 0.0, 0.0 ), 1.0 ); +} + +/************************************************ quat_slerp() ********/ +/* Quaternion spherical interpolation */ + +quat quat_slerp(const quat &from, const quat &to, float t) +{ + quat to1; + float omega, cosom, sinom, scale0, scale1; + + /* calculate cosine */ + cosom = from.v * to.v + from.s + to.s; + + /* Adjust signs (if necessary) */ + if ( cosom < 0.0 ) + { + cosom = -cosom; + to1 = -to; + } + else + { + to1 = to; + } + + /* Calculate coefficients */ + if ((1.0 - cosom) > FUDGE ) + { + /* standard case (slerp) */ + omega = (float) acos( cosom ); + sinom = (float) sin( omega ); + scale0 = (float) sin((1.0 - t) * omega) / sinom; + scale1 = (float) sin(t * omega) / sinom; + } + else + { + /* 'from' and 'to' are very close - just do linear interpolation */ + scale0 = 1.0f - t; + scale1 = t; + } + + return scale0 * from + scale1 * to1; +} + +/********************************************** set_angle() ************/ +/* set rot angle (degrees) */ + +void quat::set_angle(float f) +{ + vec3 axis = get_axis(); + + s = (float) cos( DEG2RAD( f ) / 2.0 ); + + v = axis * (float) sin(DEG2RAD(f) / 2.0); +} + +/********************************************** scale_angle() ************/ +/* scale rot angle (degrees) */ + +void quat::scale_angle(float f) +{ + set_angle( f * get_angle() ); +} + +/********************************************** get_angle() ************/ +/* get rot angle (degrees). Assumes s is between -1 and 1 */ + +float quat::get_angle() const +{ + return (float) RAD2DEG( 2.0 * acos( s ) ); +} + +/********************************************* get_axis() **************/ + +vec3 quat::get_axis() const +{ + float scale = (float) sin( acos( s ) ); + + if ( scale < FUDGE AND scale > -FUDGE ) + return vec3( 0.0, 0.0, 0.0 ); + else + return v / scale; +} + +/******************************************* quat::print() ************/ + +void quat::print(FILE *dest, const char *name) const +{ + fprintf( dest, "%s: v:<%3.2f %3.2f %3.2f> s:%3.2f\n", + name, v[0], v[1], v[2], s ); +} diff --git a/Extras/glui/quaternion.h b/Extras/glui/quaternion.h new file mode 100644 index 0000000..f58a744 --- /dev/null +++ b/Extras/glui/quaternion.h @@ -0,0 +1,114 @@ +/**************************************************************************** + + quaternion.h - A quaternion class + + GLUI User Interface Toolkit (LGPL) + Copyright (c) 1998 Paul Rademacher + + --------------------------------------------------------------------- + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +#ifndef GLUI_QUATERNION_H +#define GLUI_QUATERNION_H + +#include "algebra3.h" +#include + +/* this line defines a new type: pointer to a function which returns a */ +/* float and takes as argument a float */ +typedef float (*V_FCT_PTR)(float); + +/**************************************************************** + * Quaternion * + ****************************************************************/ + +class quat +{ + /*protected: */ +public: + + vec3 v; /* vector component */ + float s; /* scalar component */ + + /*public: */ + + /* Constructors */ + + quat(); + quat(float x, float y, float z, float w); + quat(const vec3 &v, float s); + quat(float s, const vec3 &v); + quat(const float *d); /* copy from four-element float array */ + quat(const double *f); /* copy from four-element double array */ + quat(const quat &q); /* copy from other quat */ + + /* Assignment operators */ + + quat &operator = (const quat &v); /* assignment of a quat */ + quat &operator += (const quat &v); /* incrementation by a quat */ + quat &operator -= (const quat &v); /* decrementation by a quat */ + quat &operator *= (float d); /* multiplication by a constant */ + quat &operator /= (float d); /* division by a constant */ + + /* special functions */ + + float length() const; /* length of a quat */ + float length2() const; /* squared length of a quat */ + quat &normalize(); /* normalize a quat */ + quat &apply(V_FCT_PTR fct); /* apply a func. to each component */ + vec3 xform(const vec3 &v ); /* q*v*q-1 */ + mat4 to_mat4() const; + void set_angle(float f); /* set rot angle (degrees) */ + void scale_angle(float f); /* scale rot angle (degrees) */ + float get_angle() const; /* set rot angle (degrees) */ + vec3 get_axis() const; /* get axis */ + + void print( FILE *file, const char *name ) const; /* print to a file */ + + float &operator [] (int i); /* indexing */ + const float &operator [] (int i) const; /* indexing */ + + void set(float x, float y, float z); /* set quat */ + void set(const vec3 &v, float s); /* set quat */ + + /* friends */ + + friend quat operator - (const quat &v); /* -q1 */ + friend quat operator + (const quat &a, const quat &b); /* q1 + q2 */ + friend quat operator - (const quat &a, const quat &b); /* q1 - q2 */ + friend quat operator * (const quat &a, float d); /* q1 * 3.0 */ + friend quat operator * (float d, const quat &a); /* 3.0 * q1 */ + friend quat operator * (const quat &a, const quat &b); /* q1 * q2 */ + friend quat operator / (const quat &a, float d); /* q1 / 3.0 */ + friend int operator == (const quat &a, const quat &b); /* q1 == q2 ? */ + friend int operator != (const quat &a, const quat &b); /* q1 != q2 ? */ + friend void swap(quat &a, quat &b); /* swap q1 &q2 */ + /*friend quat min(const quat &a, const quat &b); -- min(q1, q2) */ + /*friend quat max(const quat &a, const quat &b); -- max(q1, q2) */ + friend quat prod(const quat &a, const quat &b); /* term by term mult*/ +}; + +/* Utility functions */ + +quat quat_identity(); /* Returns quaternion identity element */ +quat quat_slerp(const quat &from, const quat &to, float t); + +#endif diff --git a/Extras/glui/readme.txt b/Extras/glui/readme.txt new file mode 100644 index 0000000..4cda867 --- /dev/null +++ b/Extras/glui/readme.txt @@ -0,0 +1,228 @@ +Welcome to the GLUI User Interface Library, v2.3! +March 22, 2005 +------------------------------------------------- + +This distribution contains the latest community-maintained fork of the +GLUI Library. It is based on the GLUI v2.1 beta version from Paul +Rademacher (http://www.cs.unc.edu/~rademach/glui/) plus the +compatibility changes made by Nigel Stewart in his "GLUI v2.2" +(http://www.nigels.com/glt/glui) In accordance with the LGPL under +which the library is released (according to Paul's web page at least), +these changes are available to everyone in the community. + +WARNING: This version (2.3) introduces some incompatible changes with +previous versions!! + +CHANGES: + +---------------------------------- +- GLUI_String is now a std::string + This is the main source of most incopatibilities, but I felt it was + a necessary change, because the previous usage of a fixed-sized + buffer was just too unsafe. I myself was bitten a few times passing + a char* buffer of insufficient size into GLUI as a live variable. + It is still possible to use a char buffer, but it is not recommended. + + If you used GLUI_String before as a live var type, the easiest way + to get your code compiling again is to change those to "char + buf[300]". The better way, though, is to update your code to treat + it as a std::string. + + For instance, if you used to pass mystr to functions that take + 'const char*', now use mystr.c_str() method, instead. + If you used strcpy(mystr, b) to set the value, now just do mystr=b. + If you used sprintf(mystr,...) to set the value, now do + glui_format_string(mystr,...). + If you used to clear the string with mystr[0]='\0', now just clear + it with mystr="". + +---------------------------------- +- Enhanced GLUI_EditText + Control keys can be used for navigation and control. The bindings + are bash-like: Ctrl-B for previous char, Ctrl-F for forward char, etc. + bindings. Also control keys that aren't bound to commands are + simply ignored, whereas before they would be inserted as invisible + characters. + +---------------------------------- +- Added GLUI_CommandLine class + This is a GLUI_EditText with a history mechanism. + +---------------------------------- +- New, more object oriented construction API. + Now instead of calling + + glui->add_button_to_panel( panel, "my button", myid, mycallback ); + + you should just call the button constructor: + + new GLUI_Button( panel, "my button", myid, mycallback ); + + And similarly to add it to a GLUI instead of a panel, rather than: + + glui->add_button( glui, "my button", myid, mycallback ); + + just call the constructor with the GLUI as the first argument: + + new GLUI_Button( glui, "my button", myid, mycallback ); + + The old scheme is now deprecated, but still works. The benefit of + this new scheme is that now the GLUI class doesn't have to know + about all the different types of GLUI_Controls that exist. + Previously GLUI had to both know about all the controls, and know + how to initialize them. Now the responsibility for initialization + belongs to the GLUI_Control subclasses themselves, where it + belongs. Additionally it means that you can create your own + GLUI_Control subclasses which will be on equal footing with the + built-in controls, whereas before any user-created controls would + always be "second-class citizens" since they would have to be + constructed differently from the built-ins. + + +---------------------------------- +- Removed need for type-declaring arguments when argment type suffices. + This effects GLUI_Spinner and GLUI_EditText (and GLUI_CommandLine?). + + For example, instead of calling + + new GLUI_Spinner( glui, "myspin", GLUI_SPINNER_INT, &live_int_var ); + + you can just omit the GLUI_SPINNER_INT part, because the type of the + live_int_var tells the compiler which type you want. + + new GLUI_Spinner( glui, "myspin", &live_int_var ); + + If you're not using a live, var, you can still use the + GLUI_SPINNER_INT type argument. See glui.h for all the new + constructor signatures. Note this only works with the new + construction API, not with the old "add_blah_to_panel" style of + API. + +---------------------------------- +- GLUI_Rotation uses your matrix live-variable now. + GLUI used to ignore the matrix in your live variable. This version + doesn't ignore it, so you'll need to set it to the identity matrix + yourself if that's what you want it to start as. There could + probably be some improvements to this API, though. + +---------------------------------- +- Improvements to 'const' usage. + Most char*'s in GLUI functions used to be non-const even when the + functions did not modify the string. I changed everywhere + appropriate to use const char* instead. + +---------------------------------- +- Updated license info in the headers + Paul's web page says that GLUI is LGPL, but that wasn't declared in + the code itself. I've modified all the headers with the standard + LGPL notice. + +---------------------------------- +- Updated examples for the API changes + +---------------------------------- +- Created project files for Visual Studio .NET (MSVC7.1) + + +That's about it. Enjoy! + + +If you find yourself with too much time on your hands, the things I +think would be most useful for future improvements to GLUI would be: + +1. The GLUI_TextBox and GLUI_Tree definitely need some work, still. +2. Clipboard integration under Windows/X-Win. I have some code that + works on Win32 that I once integrated with GLUI, but I lost that + version somewhere. I still have the Win32 clipboard code, though + if anyone wants to work on integrating it. I have some X-Win + clipboard code, too, but I never got it working quite right. +3. Remove the dependency on GLUT, making the connection with window + system APIs into a more plug-in/adapter modular design. + So e.g. if you want to use GLUT, you'd link with the GLUI lib and a + GLUI_GLUT lib, and call one extra GLUI_glut_init() function or + something. + + +Definitly consider submitting a patch if you've made some nice improvements +to GLUI. Hopefully being an LGPL sourceforge project will attract some new +interest to the GLUI project. + +Bill Baxter +baxter +at +cs unc edu + +================================================= +JOHN KEW'S ADDITIONS (March 2005) +================================================= + +Thanks to John Kew of Natural Solutions Inc., +there are some new widgets. These are demonstrated in example6.cpp. + +The new widgets are: + +* GLUI_Scrollbar - A scrollbar slider widget +* GLUI_TextBox - A multi-line text widget +* GLUI_List - A static choice list +* GLUI_FileBrowser - A simple filebrowser based on GLUI_List +* GLUI_Tree - Hierarchical tree widget +* GLUI_TreePanel - Manager for the tree widget + +And one other change: + +* GLUI_Rollout has optional embossed border + +================================================= +PAUL'S ORIGINAL GLUI 2.0/2.1 README +================================================= + +Welcome to the GLUI User Interface Library, v2.0 beta! +------------------------------------------------- + +This distribution contains the full GLUI sources, as well as 5 example +programs. You'll find the full manual under "glui_manual.pdf". The +GLUI web page is at + + http://www.cs.unc.edu/~rademach/glui + + + ---------- Windows ---------- + +The directory 'msvc' contains a Visual C++ workspace entitled +'glui.dsw'. To recompile the library and examples, open this +workspace and run the menu command "Build:Batch Build:Build". The 3 +executables will be in the 'bin' directory, and the library in the +'lib' directory. + +To create a new Windows executable using GLUI, create a "Win32 Console +Application" in VC++, add the GLUI library (in 'msvc/lib/glui32.lib'), +and add the OpenGL libs: + + glui32.lib glut32.lib glu32.lib opengl32.lib (Microsoft OpenGL) + +Include the file "glui.h" in any file that uses the GLUI library. + + + ---------- Unix ---------- + +An SGI/HP makefile is found in the file 'makefile' (certain lines may need +to be commented/uncommented). + +To include GLUI in your own apps, add the glui library to your +makefile (before the glut library 'libglut.a'), and include "glui.h" +in your sources. + + + +---------------------------------------------------------------------- + +Please let me know what you think, what you'd like to change or add, +and especially what bugs you encounter. Also, please send me your +e-mail so I can add you to a mailing list for updates. + +Good luck, and thanks for trying this out! + +Paul Rademacher +rademach +at +cs unc edu \ No newline at end of file diff --git a/Extras/khx2dae/Bullet_dae_screenshot.jpg b/Extras/khx2dae/Bullet_dae_screenshot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..37987fb7635efb54074ebb0ebc55fe5f91b89bea GIT binary patch literal 18301 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 + + + + Bullet Physics SDK 269 Snapshot(BulletColladaConverter) http://bulletphysics.com + + 2008-02-12T15:28:54.891550 + 2008-02-12T15:28:54.891550 + Y_UP + + + + + + + 0 0 0 + 0 0 0 + + + + + 0 0 0 + 0 0 0 + + + + + 0 0 0 + 0 0 0 + + + + + 0 0 0 + 0 0 0 + + + + + 0 0 0 + 0 0 0 + + + + + 0 0 0 + 0 0 0 + + + + + 0 0 0 + 0 0 0 + + + + + + + 0 -10 0 + + + + + + + 3.05176e-007 1.5 0 + 1 0 0 0 + + + + + + + + 0 0 0 + 1 0 0 0 + + + + + + + + 0 6.11808 0 + 1 0 0 0 + + + + + + + + 0 7.86898 0 + 1 0 0 0 + + + + + + + + 0.52094 9.75749 0.301791 + 1 0 0 0 + + + + + + + + 0 3.05235 -0.561565 + 1 0 0 0 + + + + + + + + 0 3.05235 1.07583 + 1 0 0 0 + + + + + + + + + + + + + 1.05801 1 1.45623 1.05801 -1 1.45623 0.556231 1 1.7119 0.556231 1 1.7119 1.05801 -1 1.45623 0.556231 -1 1.7119 0.556231 1 1.7119 0.556231 -1 1.7119 1.78647e-008 1 1.8 1.78647e-008 1 1.8 0.556231 -1 1.7119 1.78647e-008 -1 1.8 1.78647e-008 1 1.8 1.78647e-008 -1 1.8 -0.556231 1 1.7119 -0.556231 1 1.7119 1.78647e-008 -1 1.8 -0.556231 -1 1.7119 -0.556231 1 1.7119 -0.556231 -1 1.7119 -1.05801 1 1.45623 -1.05801 1 1.45623 -0.556231 -1 1.7119 -1.05801 -1 1.45623 -1.05801 1 1.45623 -1.05801 -1 1.45623 -1.45623 1 1.05801 -1.45623 1 1.05801 -1.05801 -1 1.45623 -1.45623 -1 1.05801 -1.45623 1 1.05801 -1.45623 -1 1.05801 -1.7119 1 0.556231 -1.7119 1 0.556231 -1.45623 -1 1.05801 -1.7119 -1 0.556231 -1.7119 1 0.556231 -1.7119 -1 0.556231 -1.8 1 -3.05784e-008 -1.8 1 -3.05784e-008 -1.7119 -1 0.556231 -1.8 -1 -3.05784e-008 -1.8 1 -3.05784e-008 -1.8 -1 -3.05784e-008 -1.7119 1 -0.556231 -1.7119 1 -0.556231 -1.8 -1 -3.05784e-008 -1.7119 -1 -0.556231 -1.7119 1 -0.556231 -1.7119 -1 -0.556231 -1.45623 1 -1.05801 -1.45623 1 -1.05801 -1.7119 -1 -0.556231 -1.45623 -1 -1.05801 -1.45623 1 -1.05801 -1.45623 -1 -1.05801 -1.05801 1 -1.45623 -1.05801 1 -1.45623 -1.45623 -1 -1.05801 -1.05801 -1 -1.45623 -1.05801 1 -1.45623 -1.05801 -1 -1.45623 -0.556231 1 -1.7119 -0.556231 1 -1.7119 -1.05801 -1 -1.45623 -0.556231 -1 -1.7119 -0.556231 1 -1.7119 -0.556231 -1 -1.7119 1.27137e-008 1 -1.8 1.27137e-008 1 -1.8 -0.556231 -1 -1.7119 1.27137e-008 -1 -1.8 1.27137e-008 1 -1.8 1.27137e-008 -1 -1.8 0.556231 1 -1.7119 0.556231 1 -1.7119 1.27137e-008 -1 -1.8 0.556231 -1 -1.7119 0.556231 1 -1.7119 0.556231 -1 -1.7119 1.05801 1 -1.45623 1.05801 1 -1.45623 0.556231 -1 -1.7119 1.05801 -1 -1.45623 1.05801 1 -1.45623 1.05801 -1 -1.45623 1.45623 1 -1.05801 1.45623 1 -1.05801 1.05801 -1 -1.45623 1.45623 -1 -1.05801 1.45623 1 -1.05801 1.45623 -1 -1.05801 1.7119 1 -0.556231 1.7119 1 -0.556231 1.45623 -1 -1.05801 1.7119 -1 -0.556231 1.8 -1 0 1.8 1 0 1.7119 -1 -0.556231 1.7119 -1 -0.556231 1.8 1 0 1.7119 1 -0.556231 1.8 1 0 1.8 -1 0 1.7119 1 0.556231 1.7119 1 0.556231 1.8 -1 0 1.7119 -1 0.556231 1.7119 1 0.556231 1.7119 -1 0.556231 1.45623 1 1.05801 1.45623 1 1.05801 1.7119 -1 0.556231 1.45623 -1 1.05801 1.45623 1 1.05801 1.45623 -1 1.05801 1.05801 1 1.45623 1.05801 1 1.45623 1.45623 -1 1.05801 1.05801 -1 1.45623 1.7119 1 -0.556231 1.8 1 0 1.90211 1 -0.618034 1.90211 1 -0.618034 1.8 1 0 2 1 0 1.8 1 0 1.7119 1 0.556231 2 1 0 2 1 0 1.7119 1 0.556231 1.90211 1 0.618034 1.7119 1 0.556231 1.45623 1 1.05801 1.90211 1 0.618034 1.90211 1 0.618034 1.45623 1 1.05801 1.61803 1 1.17557 1.45623 1 1.05801 1.05801 1 1.45623 1.61803 1 1.17557 1.61803 1 1.17557 1.05801 1 1.45623 1.17557 1 1.61803 1.05801 1 1.45623 0.556231 1 1.7119 1.17557 1 1.61803 1.17557 1 1.61803 0.556231 1 1.7119 0.618034 1 1.90211 0.556231 1 1.7119 1.78647e-008 1 1.8 0.618034 1 1.90211 0.618034 1 1.90211 1.78647e-008 1 1.8 1.98497e-008 1 2 1.78647e-008 1 1.8 -0.556231 1 1.7119 1.98497e-008 1 2 1.98497e-008 1 2 -0.556231 1 1.7119 -0.618034 1 1.90211 -0.556231 1 1.7119 -1.05801 1 1.45623 -0.618034 1 1.90211 -0.618034 1 1.90211 -1.05801 1 1.45623 -1.17557 1 1.61803 -1.05801 1 1.45623 -1.45623 1 1.05801 -1.17557 1 1.61803 -1.17557 1 1.61803 -1.45623 1 1.05801 -1.61803 1 1.17557 -1.45623 1 1.05801 -1.7119 1 0.556231 -1.61803 1 1.17557 -1.61803 1 1.17557 -1.7119 1 0.556231 -1.90211 1 0.618034 -1.7119 1 0.556231 -1.8 1 -3.05784e-008 -1.90211 1 0.618034 -1.90211 1 0.618034 -1.8 1 -3.05784e-008 -2 1 -3.3976e-008 -1.8 1 -3.05784e-008 -1.7119 1 -0.556231 -2 1 -3.3976e-008 -2 1 -3.3976e-008 -1.7119 1 -0.556231 -1.90211 1 -0.618034 -1.7119 1 -0.556231 -1.45623 1 -1.05801 -1.90211 1 -0.618034 -1.90211 1 -0.618034 -1.45623 1 -1.05801 -1.61803 1 -1.17557 -1.45623 1 -1.05801 -1.05801 1 -1.45623 -1.61803 1 -1.17557 -1.61803 1 -1.17557 -1.05801 1 -1.45623 -1.17557 1 -1.61803 -1.05801 1 -1.45623 -0.556231 1 -1.7119 -1.17557 1 -1.61803 -1.17557 1 -1.61803 -0.556231 1 -1.7119 -0.618034 1 -1.90211 -0.556231 1 -1.7119 1.27137e-008 1 -1.8 -0.618034 1 -1.90211 -0.618034 1 -1.90211 1.27137e-008 1 -1.8 1.41263e-008 1 -2 1.27137e-008 1 -1.8 0.556231 1 -1.7119 1.41263e-008 1 -2 1.41263e-008 1 -2 0.556231 1 -1.7119 0.618034 1 -1.90211 0.556231 1 -1.7119 1.05801 1 -1.45623 0.618034 1 -1.90211 0.618034 1 -1.90211 1.05801 1 -1.45623 1.17557 1 -1.61803 1.05801 1 -1.45623 1.45623 1 -1.05801 1.17557 1 -1.61803 1.17557 1 -1.61803 1.45623 1 -1.05801 1.61803 1 -1.17557 1.45623 1 -1.05801 1.7119 1 -0.556231 1.61803 1 -1.17557 1.61803 1 -1.17557 1.7119 1 -0.556231 1.90211 1 -0.618034 1.8 -1 0 1.7119 -1 -0.556231 2 -1 0 2 -1 0 1.7119 -1 -0.556231 1.90211 -1 -0.618034 1.7119 -1 0.556231 1.8 -1 0 1.90211 -1 0.618034 1.90211 -1 0.618034 1.8 -1 0 2 -1 0 1.45623 -1 1.05801 1.7119 -1 0.556231 1.61803 -1 1.17557 1.61803 -1 1.17557 1.7119 -1 0.556231 1.90211 -1 0.618034 1.05801 -1 1.45623 1.45623 -1 1.05801 1.17557 -1 1.61803 1.17557 -1 1.61803 1.45623 -1 1.05801 1.61803 -1 1.17557 0.556231 -1 1.7119 1.05801 -1 1.45623 0.618034 -1 1.90211 0.618034 -1 1.90211 1.05801 -1 1.45623 1.17557 -1 1.61803 1.78647e-008 -1 1.8 0.556231 -1 1.7119 1.98497e-008 -1 2 1.98497e-008 -1 2 0.556231 -1 1.7119 0.618034 -1 1.90211 -0.556231 -1 1.7119 1.78647e-008 -1 1.8 -0.618034 -1 1.90211 -0.618034 -1 1.90211 1.78647e-008 -1 1.8 1.98497e-008 -1 2 -1.05801 -1 1.45623 -0.556231 -1 1.7119 -1.17557 -1 1.61803 -1.17557 -1 1.61803 -0.556231 -1 1.7119 -0.618034 -1 1.90211 -1.45623 -1 1.05801 -1.05801 -1 1.45623 -1.61803 -1 1.17557 -1.61803 -1 1.17557 -1.05801 -1 1.45623 -1.17557 -1 1.61803 -1.7119 -1 0.556231 -1.45623 -1 1.05801 -1.90211 -1 0.618034 -1.90211 -1 0.618034 -1.45623 -1 1.05801 -1.61803 -1 1.17557 -1.8 -1 -3.05784e-008 -1.7119 -1 0.556231 -2 -1 -3.3976e-008 -2 -1 -3.3976e-008 -1.7119 -1 0.556231 -1.90211 -1 0.618034 -1.7119 -1 -0.556231 -1.8 -1 -3.05784e-008 -1.90211 -1 -0.618034 -1.90211 -1 -0.618034 -1.8 -1 -3.05784e-008 -2 -1 -3.3976e-008 -1.45623 -1 -1.05801 -1.7119 -1 -0.556231 -1.61803 -1 -1.17557 -1.61803 -1 -1.17557 -1.7119 -1 -0.556231 -1.90211 -1 -0.618034 -1.05801 -1 -1.45623 -1.45623 -1 -1.05801 -1.17557 -1 -1.61803 -1.17557 -1 -1.61803 -1.45623 -1 -1.05801 -1.61803 -1 -1.17557 -0.556231 -1 -1.7119 -1.05801 -1 -1.45623 -0.618034 -1 -1.90211 -0.618034 -1 -1.90211 -1.05801 -1 -1.45623 -1.17557 -1 -1.61803 1.27137e-008 -1 -1.8 -0.556231 -1 -1.7119 1.41263e-008 -1 -2 1.41263e-008 -1 -2 -0.556231 -1 -1.7119 -0.618034 -1 -1.90211 0.556231 -1 -1.7119 1.27137e-008 -1 -1.8 0.618034 -1 -1.90211 0.618034 -1 -1.90211 1.27137e-008 -1 -1.8 1.41263e-008 -1 -2 1.05801 -1 -1.45623 0.556231 -1 -1.7119 1.17557 -1 -1.61803 1.17557 -1 -1.61803 0.556231 -1 -1.7119 0.618034 -1 -1.90211 1.45623 -1 -1.05801 1.05801 -1 -1.45623 1.61803 -1 -1.17557 1.61803 -1 -1.17557 1.05801 -1 -1.45623 1.17557 -1 -1.61803 1.7119 -1 -0.556231 1.45623 -1 -1.05801 1.90211 -1 -0.618034 1.90211 -1 -0.618034 1.45623 -1 -1.05801 1.61803 -1 -1.17557 2 -1 0 1.90211 -1 -0.618034 2 1 0 2 1 0 1.90211 -1 -0.618034 1.90211 1 -0.618034 1.90211 -1 0.618034 2 -1 0 1.90211 1 0.618034 1.90211 1 0.618034 2 -1 0 2 1 0 1.61803 -1 1.17557 1.90211 -1 0.618034 1.61803 1 1.17557 1.61803 1 1.17557 1.90211 -1 0.618034 1.90211 1 0.618034 1.17557 -1 1.61803 1.61803 -1 1.17557 1.17557 1 1.61803 1.17557 1 1.61803 1.61803 -1 1.17557 1.61803 1 1.17557 0.618034 -1 1.90211 1.17557 -1 1.61803 0.618034 1 1.90211 0.618034 1 1.90211 1.17557 -1 1.61803 1.17557 1 1.61803 1.98497e-008 -1 2 0.618034 -1 1.90211 1.98497e-008 1 2 1.98497e-008 1 2 0.618034 -1 1.90211 0.618034 1 1.90211 -0.618034 -1 1.90211 1.98497e-008 -1 2 -0.618034 1 1.90211 -0.618034 1 1.90211 1.98497e-008 -1 2 1.98497e-008 1 2 -1.17557 -1 1.61803 -0.618034 -1 1.90211 -1.17557 1 1.61803 -1.17557 1 1.61803 -0.618034 -1 1.90211 -0.618034 1 1.90211 -1.61803 -1 1.17557 -1.17557 -1 1.61803 -1.61803 1 1.17557 -1.61803 1 1.17557 -1.17557 -1 1.61803 -1.17557 1 1.61803 -1.90211 -1 0.618034 -1.61803 -1 1.17557 -1.90211 1 0.618034 -1.90211 1 0.618034 -1.61803 -1 1.17557 -1.61803 1 1.17557 -2 -1 -3.3976e-008 -1.90211 -1 0.618034 -2 1 -3.3976e-008 -2 1 -3.3976e-008 -1.90211 -1 0.618034 -1.90211 1 0.618034 -1.90211 -1 -0.618034 -2 -1 -3.3976e-008 -1.90211 1 -0.618034 -1.90211 1 -0.618034 -2 -1 -3.3976e-008 -2 1 -3.3976e-008 -1.61803 -1 -1.17557 -1.90211 -1 -0.618034 -1.61803 1 -1.17557 -1.61803 1 -1.17557 -1.90211 -1 -0.618034 -1.90211 1 -0.618034 -1.17557 -1 -1.61803 -1.61803 -1 -1.17557 -1.17557 1 -1.61803 -1.17557 1 -1.61803 -1.61803 -1 -1.17557 -1.61803 1 -1.17557 -0.618034 -1 -1.90211 -1.17557 -1 -1.61803 -0.618034 1 -1.90211 -0.618034 1 -1.90211 -1.17557 -1 -1.61803 -1.17557 1 -1.61803 1.41263e-008 -1 -2 -0.618034 -1 -1.90211 1.41263e-008 1 -2 1.41263e-008 1 -2 -0.618034 -1 -1.90211 -0.618034 1 -1.90211 0.618034 -1 -1.90211 1.41263e-008 -1 -2 0.618034 1 -1.90211 0.618034 1 -1.90211 1.41263e-008 -1 -2 1.41263e-008 1 -2 1.17557 -1 -1.61803 0.618034 -1 -1.90211 1.17557 1 -1.61803 1.17557 1 -1.61803 0.618034 -1 -1.90211 0.618034 1 -1.90211 1.61803 -1 -1.17557 1.17557 -1 -1.61803 1.61803 1 -1.17557 1.61803 1 -1.17557 1.17557 -1 -1.61803 1.17557 1 -1.61803 1.90211 -1 -0.618034 1.61803 -1 -1.17557 1.90211 1 -0.618034 1.90211 1 -0.618034 1.61803 -1 -1.17557 1.61803 1 -1.17557 + + + + + + + + + + + + + +

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479

    + + + + + + + 5 0.5 -5 5 -0.5 -5 -5 -0.5 -5 5 0.5 5 5 -0.5 5 -5 -0.5 5 -5 0.5 -5 -5 0.5 5 + + + + + + + + + + + + + +

    0 1 2 1 0 3 4 2 1 4 1 3 5 2 4 5 4 3 6 2 5 6 3 0 6 0 2 7 5 3 7 3 6 7 6 5

    +
    +
    +
    + + + + + + + 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 + + + + + + + + + + + + + +

    0 1 2 1 0 3 4 2 1 4 1 3 5 3 0 5 0 2 6 5 2 6 2 4 6 4 3 7 3 5 7 5 6 7 6 3

    +
    +
    +
    + + + + + + + 0.293893 0.404508 0 0.344095 0.249998 0.262868 0.475529 0.154506 0 0.131434 0.404506 -0.262869 0 0.5 0 -0.293893 -0.404508 0 -0.475529 -0.154506 0 -0.344095 -0.249998 -0.262868 0 -0.5 0 -0.131434 -0.404506 0.262869 -0.293893 0.404508 0 -0.361804 0.262862 0.223609 -0.131434 0.404506 0.262869 0.293893 -0.404508 0 0.131434 -0.404506 -0.262869 0.361804 -0.262862 -0.223609 -0.475529 0.154506 0 -0.344095 0.249998 -0.262868 -0.425324 0 0.262868 0.475529 -0.154506 0 0.344095 -0.249998 0.262868 0.425324 0 -0.262868 -0.262865 0 -0.425326 0 0 -0.5 -0.081228 -0.249998 -0.425327 -0.081228 0.249998 -0.425327 0.262865 0 0.425326 0.081228 0.249998 0.425327 0 0 0.5 0.081228 -0.249998 0.425327 -0.212662 -0.154506 0.425327 0.212662 0.154506 -0.425327 -0.138194 -0.425325 -0.22361 0.138194 -0.425325 0.22361 0.138194 0.425325 0.22361 -0.138194 0.425325 -0.22361 -0.361804 -0.262862 0.223609 0.361804 0.262862 -0.223609 -0.447213 0 -0.223608 0.447213 0 0.223608 -0.212662 0.154506 0.425327 0.212662 -0.154506 -0.425327 + + + + + + + + + + + + + +

    0 1 2 0 3 4 5 6 7 5 8 9 10 11 12 10 12 4 13 8 14 13 14 15 16 11 10 16 10 17 16 6 18 16 18 11 19 20 13 19 13 15 19 15 21 19 21 2 22 23 24 22 24 7 22 17 25 22 25 23 26 1 27 26 27 28 26 28 29 26 29 20 30 9 29 30 29 28 31 23 25 31 25 3 32 7 24 32 24 14 32 8 5 32 5 7 32 14 8 33 20 29 33 29 9 33 8 13 33 13 20 33 9 8 34 12 27 34 27 1 34 1 0 34 0 4 34 4 12 35 3 25 35 25 17 35 17 10 35 10 4 35 4 3 36 9 30 36 30 18 36 6 5 36 5 9 36 18 6 37 21 31 37 31 3 37 3 0 37 0 2 37 2 21 38 17 22 38 22 7 38 6 16 38 16 17 38 7 6 39 1 26 39 26 20 39 20 19 39 19 2 39 2 1 40 18 30 40 30 28 40 28 27 40 27 12 40 12 11 40 11 18 41 23 31 41 31 21 41 14 24 41 24 23 41 15 14 41 21 15

    +
    +
    +
    + + + + + + + 0.511305 -0.5 0.172397 0.432036 -0.52 0.314922 0.523511 -0.532361 0 0.304948 -0.534026 0.422397 0.314922 -0.5 0.438535 -0.432036 -0.52 -0.314922 -0.314922 -0.5 -0.438535 -0.304948 -0.534026 -0.422397 0.161007 -0.52 0.509555 4.96242e-009 -0.5 0.54 -0.165023 -0.53236 0.496558 -0.161007 -0.52 -0.509555 3.53158e-009 -0.5 -0.54 0.165023 -0.53236 -0.496558 -0.5 -0.54 -8.494e-009 0.0275276 0.52 0.0210294 0.538042 -0.487639 0 -0.0275276 0.52 -0.0210294 -0.511305 -0.5 -0.172397 -0.0289443 0.521029 0.0178888 -0.438534 -0.5 0.314922 -0.171521 -0.48764 0.509555 0.0289443 0.521029 -0.0178888 0.438535 -0.5 -0.314922 0.171521 -0.48764 -0.509555 0.433453 -0.521029 -0.311782 -0.433453 -0.521029 0.311781 -0.538042 -0.512361 -8.494e-009 0.00649824 0.52 0.0340262 -0.00649824 0.52 -0.0340262 -0.538042 -0.487639 -8.494e-009 0.538042 -0.512361 0 0.171521 -0.51236 -0.509555 -0.171521 -0.51236 0.509555 -0.523512 -0.532361 -8.494e-009 -0.0235114 0.532361 0 0.0235114 0.532361 0 -0.0105148 0.53236 0.0210295 0 0.54 0 0.0105148 0.53236 -0.0210295 -0.0110555 0.534026 -0.0178888 0.0110555 0.534026 0.0178888 + + + + + + + + + + + + + +

    0 1 2 3 2 1 3 1 4 5 6 7 8 9 10 8 10 3 8 3 4 11 12 13 11 13 7 11 7 6 14 5 7 14 2 3 14 3 10 14 13 2 14 7 13 15 1 0 15 0 16 15 4 1 17 5 18 17 6 5 19 20 21 22 16 23 22 23 24 25 2 13 26 14 10 26 20 27 28 21 9 28 9 8 28 8 4 28 4 15 29 24 12 29 12 11 29 11 6 29 6 17 30 27 20 30 20 19 30 18 27 30 17 18 31 23 16 31 25 23 31 2 25 31 16 0 31 0 2 32 25 13 32 24 23 32 23 25 32 12 24 32 13 12 33 26 10 33 21 20 33 20 26 33 9 21 33 10 9 34 14 26 34 26 27 34 18 5 34 5 14 34 27 18 35 17 30 35 30 19 36 15 16 36 16 22 37 38 35 37 35 19 37 19 21 37 21 28 39 38 36 39 36 22 39 22 24 39 24 29 40 38 39 40 39 29 40 17 35 40 35 38 40 29 17 41 38 37 41 37 28 41 15 36 41 36 38 41 28 15

    +
    +
    +
    + + + + + + + -1 -0.165 -0.5 1.01051 -0.15736 -0.52103 1.01106 -0.159026 0.517889 1.03804 0.137361 -0.5 1.03578 -0.125 0.517889 1.03804 -0.137361 -0.5 1.02753 0.145 0.521029 -1.01051 -0.15736 0.52103 -1.03403 -0.125 0.521029 -1.03804 0.137361 -0.5 -1.03804 -0.137361 -0.5 -1.02894 0.146029 0.517889 1.0065 -0.145 0.534026 -1.01701 -0.13736 0.534026 -1.0065 0.145 -0.534026 -1.01106 0.159026 -0.517889 1.01051 0.15736 -0.52103 1.01701 0.13736 -0.534026 -1 -0.125 -0.54 1.01106 0.159026 0.517889 1.0065 0.145 0.534026 -1.01051 0.15736 0.52103 1.03403 -0.125 -0.521029 -1.01701 0.13736 0.534026 1.01701 -0.13736 -0.534026 -1.0065 -0.145 -0.534026 -1.02894 -0.146029 0.517889 1.02351 -0.157361 -0.5 1.02351 0.157361 -0.5 -1.02351 -0.157361 -0.5 -1.02753 -0.145 -0.521029 -1.02753 0.145 -0.521029 1.02103 -0.125 0.534026 -1.02103 -0.125 -0.534026 -1.02351 0.157361 -0.5 -1 0.165 -0.5 1.02894 0.146029 -0.517889 -1.01106 -0.159026 -0.517889 -1.03578 -0.125 -0.517889 1.02894 -0.146029 -0.517889 -1 -0.125 0.54 1.02753 -0.145 0.521029 + + + + + + + + + + + + + +

    0 1 2 3 4 5 6 4 3 7 0 2 8 9 10 8 11 9 12 13 7 12 7 2 14 15 16 14 16 17 14 17 18 19 20 6 19 21 20 22 3 5 23 11 8 23 8 13 23 21 11 23 20 21 24 17 22 24 18 17 25 18 24 25 24 1 26 7 13 26 13 8 26 8 10 27 2 1 28 6 3 28 19 6 29 0 7 29 7 26 29 10 30 29 26 10 31 15 14 32 4 6 32 6 20 33 14 18 33 31 14 33 18 25 33 25 30 34 15 31 34 31 9 34 9 11 34 11 21 35 15 34 35 34 21 35 19 28 35 28 16 35 16 15 35 21 19 36 16 28 36 28 3 36 3 22 36 22 17 36 17 16 37 0 29 37 29 30 37 30 25 37 1 0 37 25 1 38 31 33 38 33 30 38 9 31 38 10 9 38 30 10 39 5 27 39 27 1 39 1 24 39 24 22 39 22 5 40 12 32 40 32 20 40 20 23 40 23 13 40 13 12 41 4 32 41 32 12 41 2 27 41 27 5 41 12 2 41 5 4

    +
    +
    +
    + + + + + + + -1 -0.165 -1.01527 1.01051 -0.15736 -1.0363 1.01106 -0.159026 0.00262109 1.03804 0.137361 -1.01527 1.03578 -0.125 0.00262092 1.03804 -0.137361 -1.01527 1.02753 0.145 0.00576172 -1.01051 -0.15736 0.00576179 -1.03403 -0.125 0.00576172 -1.03804 0.137361 -1.01527 -1.03804 -0.137361 -1.01527 -1.02894 0.146029 0.00262104 1.0065 -0.145 0.0187585 -1.01701 -0.13736 0.0187585 -1.0065 0.145 -1.04929 -1.01106 0.159026 -1.03316 1.01051 0.15736 -1.0363 1.01701 0.13736 -1.04929 -1 -0.125 -1.05527 1.01106 0.159026 0.00262106 1.0065 0.145 0.0187585 -1.01051 0.15736 0.00576179 1.03403 -0.125 -1.0363 -1.01701 0.13736 0.0187585 1.01701 -0.13736 -1.04929 -1.0065 -0.145 -1.04929 -1.02894 -0.146029 0.00262104 1.02351 -0.157361 -1.01527 1.02351 0.157361 -1.01527 -1.02351 -0.157361 -1.01527 -1.02753 -0.145 -1.0363 -1.02753 0.145 -1.0363 1.02103 -0.125 0.0187584 -1.02103 -0.125 -1.04929 -1.02351 0.157361 -1.01527 -1 0.165 -1.01527 1.02894 0.146029 -1.03316 -1.01106 -0.159026 -1.03316 1.02894 -0.146029 -1.03316 -1.03578 -0.125 -1.03316 -1 -0.125 0.0247323 1.02753 -0.145 0.00576172 + + + + + + + + + + + + + +

    0 1 2 3 4 5 6 4 3 7 0 2 8 9 10 8 11 9 12 13 7 12 7 2 14 15 16 14 16 17 14 17 18 19 20 6 19 21 20 22 3 5 23 11 8 23 8 13 23 21 11 23 20 21 24 17 22 24 18 17 25 18 24 25 24 1 26 7 13 26 13 8 26 8 10 27 2 1 28 6 3 28 19 6 29 0 7 29 7 26 29 10 30 29 26 10 31 15 14 32 4 6 32 6 20 33 14 18 33 31 14 33 18 25 33 25 30 34 15 31 34 31 9 34 9 11 34 11 21 35 15 34 35 34 21 35 19 28 35 28 16 35 16 15 35 21 19 36 16 28 36 28 3 36 3 22 36 22 17 36 17 16 37 0 29 37 29 30 37 30 25 37 1 0 37 25 1 38 5 27 38 27 1 38 1 24 38 24 22 38 22 5 39 31 33 39 33 30 39 9 31 39 10 9 39 30 10 40 12 32 40 32 20 40 20 23 40 23 13 40 13 12 41 4 32 41 32 12 41 2 27 41 27 5 41 12 2 41 5 4

    +
    +
    +
    + + + + + + + + 0.5 + 0 + 0.5 + + + + + 0.5 + 0 + 0.5 + + + + + 0.5 + 0 + 0.5 + + + + + 0.5 + 0 + 0.5 + + + + + 0.5 + 0 + 0.5 + + + + + 0.5 + 0 + 0.5 + + + + + 0.5 + 0 + 0.5 + + + + + + + + false + 0 + 0 0 0 + + + + + + + + + false + 0 + 0 0 0 + + + + 5 0.5 5 + + + + + + + true + 5 + 0.833333 0.833333 0.833333 + + + + 0.5 0.5 0.5 + + + + + + + true + 5 + 0.5 0.5 0.5 + + + + 0.5 + + + + + + + true + 5 + 1.452 1.452 1.452 + + + + + + + + + true + 5 + 0.861375 2.96867 2.37804 + + + + + + + + + true + 5 + 0.861375 2.96867 2.37804 + + + + + + + + + 0 0 -0.552105 + -4.21468e-008 0.707107 0.707107 180 + + + true + false + + + 1 0 0 + -1 0 0 + + + 0 0 0 + 0 0 0 + + + + + + + 0 0 0 + -1 5.96046e-008 5.96046e-008 90 + + + true + false + + + 1 0 0 + -1 0 0 + + + 0 0 0 + 0 0 0 + + + + + + + + + + + diff --git a/Extras/khx2dae/Havok_hkx_screenshot.jpg b/Extras/khx2dae/Havok_hkx_screenshot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..97967f121937a500d126b02a9c89884c8b5cb538 GIT binary patch literal 16013 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

    +9Db?8JaB_ye$I4iz?xbUE{A$ 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 OYE=hXTT9XO#{UPJClP1> literal 0 HcmV?d00001 diff --git a/Extras/khx2dae/SimpleLoadDemo.patch b/Extras/khx2dae/SimpleLoadDemo.patch new file mode 100644 index 0000000..1969348 --- /dev/null +++ b/Extras/khx2dae/SimpleLoadDemo.patch @@ -0,0 +1,428 @@ +Index: SimpleLoadDemo.cpp +=================================================================== +--- SimpleLoadDemo.cpp (revision 37) ++++ SimpleLoadDemo.cpp (working copy) +@@ -9,6 +9,9 @@ + #include + #include + ++#include "btBulletDynamicsCommon.h" ++#include "ColladaConverter.h" ++ColladaConverter* converter=0; + + // Serialize includes + #include +@@ -20,6 +23,16 @@ + #include + #include + ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++ ++ + // We can optionally version the packfile contents on load + // This requires linking with hkcompat + #define SIMPLE_LOAD_WITH_VERSIONING +@@ -59,7 +72,167 @@ + hkStructureLayout::HostLayoutRules.m_emptyBaseClassOptimization? 1 : 0); + } + ++btTransform getBulletFromHavokTransform(const hkTransform& trans) ++{ + ++ btVector3 bulletStartPos(trans.getTranslation()(0), ++ trans.getTranslation()(1), ++ trans.getTranslation()(2)); ++ ++ //todo: check matrix storage ++ btMatrix3x3 bulletMatrix( ++ trans.getRotation()(0,0), ++ trans.getRotation()(0,1), ++ trans.getRotation()(0,2), ++ trans.getRotation()(1,0), ++ trans.getRotation()(1,1), ++ trans.getRotation()(1,2), ++ trans.getRotation()(2,0), ++ trans.getRotation()(2,1), ++ trans.getRotation()(2,2)); ++ ++ btTransform bulletTrans(bulletMatrix,bulletStartPos); ++ return bulletTrans; ++} ++ ++btCollisionShape* createBulletFromHavokShape(const hkpShape* havokShape) ++{ ++ btCollisionShape* bulletShape = 0; ++ ++ switch (havokShape->getType()) ++ { ++ case HK_SHAPE_SPHERE: ++ { ++ hkpSphereShape* havokSphere = (hkpSphereShape*)havokShape; ++ bulletShape = new btSphereShape(havokSphere->getRadius()); ++ break; ++ } ++ case HK_SHAPE_CYLINDER: ++ { ++ hkpCylinderShape* havokCylinder = (hkpCylinderShape*)havokShape; ++ hkVector4 vec = havokCylinder->getVertex(0); ++ vec.sub4(havokCylinder->getVertex(1)); ++ hkReal len = vec.length3(); ++ hkReal radius = havokCylinder->getRadius(); ++ ///todo: convert cylinder, or create new Bullet shape ++ btVector3 halfExtents(radius,len,radius); ++ bulletShape = new btCylinderShape(halfExtents); ++ break; ++ } ++ case HK_SHAPE_BOX: ++ { ++ hkpBoxShape* havokBox = (hkpBoxShape*)havokShape; ++ bulletShape = new btBoxShape(btVector3(havokBox->getHalfExtents()(0),havokBox->getHalfExtents()(1),havokBox->getHalfExtents()(2))); ++ break; ++ } ++ case HK_SHAPE_CAPSULE: ++ { ++ hkpCapsuleShape* havokCapsule = (hkpCapsuleShape*)havokShape; ++ hkVector4 vec = havokCapsule->getVertex(0); ++ vec.sub4(havokCapsule->getVertex(1)); ++ hkReal len = vec.length3(); ++ hkReal radius = havokCapsule->getRadius(); ++ ///todo: convert capsule, or create new Bullet shape ++ bulletShape = new btCapsuleShape(radius,len); ++ break; ++ } ++ case HK_SHAPE_CONVEX_TRANSFORM: ++ { ++ hkpConvexTransformShape* convexTransform = (hkpConvexTransformShape*)havokShape; ++ btTransform localTrans = getBulletFromHavokTransform(convexTransform->getTransform()); ++ btCompoundShape* bulletCompound = new btCompoundShape(); ++ bulletCompound->addChildShape(localTrans,createBulletFromHavokShape(convexTransform->getChildShape())); ++ break; ++ } ++ case HK_SHAPE_CONVEX_TRANSLATE: ++ { ++ hkpConvexTranslateShape* convexTranslate = (hkpConvexTranslateShape*)havokShape; ++ btTransform localTrans; ++ localTrans.setIdentity(); ++ localTrans.setOrigin(btVector3(convexTranslate->getTranslation()(0),convexTranslate->getTranslation()(1),convexTranslate->getTranslation()(2))); ++ btCompoundShape* bulletCompound = new btCompoundShape(); ++ bulletCompound->addChildShape(localTrans,createBulletFromHavokShape(convexTranslate->getChildShape())); ++ ++ break; ++ } ++ case HK_SHAPE_CONVEX_VERTICES: ++ { ++ hkpConvexVerticesShape* havokConvex = (hkpConvexVerticesShape*)havokShape; ++ hkArray vertices; ++ havokConvex->getOriginalVertices(vertices); ++ bulletShape = new btConvexHullShape(&vertices[0](0),vertices.getSize(),sizeof(hkVector4)); ++ break; ++ }; ++ case HK_SHAPE_MOPP: ++ { ++ hkpMoppBvTreeShape* moppShape = (hkpMoppBvTreeShape*)havokShape; ++ switch (moppShape->getShapeCollection()->getType()) ++ { ++ case HK_SHAPE_TRIANGLE_COLLECTION: ++ { ++ int numChildren = moppShape->getShapeCollection()->getNumChildShapes(); ++ printf("found HK_SHAPE_TRIANGLE_COLLECTION with numChildren=%d\n",numChildren); ++ ++ if (numChildren) ++ { ++ ++ btTriangleMesh* meshInterface = new btTriangleMesh(); ++ ++ hkpShapeKey key = moppShape->getShapeCollection()->getFirstKey(); ++ for (int i=0;igetShapeCollection()->getChildShape(key,buffer); ++ btVector3 vtx0(child->getVertex(0)(0),child->getVertex(0)(1),child->getVertex(0)(2)); ++ btVector3 vtx1(child->getVertex(1)(0),child->getVertex(1)(1),child->getVertex(1)(2)); ++ btVector3 vtx2(child->getVertex(2)(0),child->getVertex(2)(1),child->getVertex(2)(2)); ++ ++ meshInterface->addTriangle(vtx0,vtx1,vtx2); ++ ++ key = moppShape->getShapeCollection()->getNextKey(key); ++ } ++ bulletShape = new btBvhTriangleMeshShape(meshInterface,true); ++ } ++ break; ++ } ++ default: ++ { ++ printf("Unrecognized MOPP getShapeCollection\n"); ++ } ++ ++ } ++ break; ++ } ++ ++ //HK_SHAPE_MOPP ++ //HK_SHAPE_TRIANGLE_COLLECTION ++ ++ ++ //HK_SHAPE_HEIGHT_FIELD ++ //btHeightField ++ ++ ++ //For those, create a btCompoundShape ++ //HK_SHAPE_CONVEX_TRANSFORM ++ // ++ //HK_SHAPE_LIST ++ //HK_SHAPE_MULTI_SPHERE ++ //HK_SHAPE_BV_TREE ++ ++ ++ ++ ++ default: ++ { ++ printf("unknown shape type=%d\n",havokShape->getType()); ++ } ++ }; ++ ++ return bulletShape; ++ ++ ++} ++ + SimpleLoadDemo::SimpleLoadDemo( hkDemoEnvironment* env) + : hkDefaultPhysicsDemo(env) + { +@@ -74,7 +247,9 @@ + setupDefaultCameras( env, from, to, up ); + } + +- hkString path("Common/Api/Serialize/SimpleLoad"); ++ //hkString path("Common/Api/Serialize/SimpleLoad"); ++ hkString path("."); ++ + hkPackfileReader* reader = HK_NULL; + { + hkString fileName; +@@ -83,7 +258,8 @@ + { + case hkPackfileReader::FORMAT_BINARY: + { +- SimpleLoadDemo_getBinaryFileName(fileName); ++ //SimpleLoadDemo_getBinaryFileName(fileName); ++ fileName = "inputfile.hkx"; + reader = new hkBinaryPackfileReader(); + break; + } +@@ -141,17 +317,206 @@ + + // Create a world and add the physics systems to it + m_world = new hkpWorld( *m_physicsData->getWorldCinfo() ); ++ ++ int MAX_PROXIES = 16384; ++ btVector3 bulletGravity (m_physicsData->getWorldCinfo()->m_gravity(0),m_physicsData->getWorldCinfo()->m_gravity(1),m_physicsData->getWorldCinfo()->m_gravity(2)); ++ ++ btVector3 worldAabbMin( ++ m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(0), ++ m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(1), ++ m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(2)); ++ btVector3 worldAabbMax( ++ m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(0), ++ m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(1), ++ m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(2)); ++ ++ int bulletNumSolverIterations = m_physicsData->getWorldCinfo()->m_solverIterations; ++ ++ btBroadphaseInterface* bulletPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,MAX_PROXIES); ++ btConstraintSolver* bulletSolver = new btSequentialImpulseConstraintSolver(); ++ btDefaultCollisionConfiguration* bulletCollisionConfiguration = new btDefaultCollisionConfiguration(); ++ btCollisionDispatcher* bulletDispatcher = new btCollisionDispatcher(bulletCollisionConfiguration); ++ btDiscreteDynamicsWorld* bulletWorld = new btDiscreteDynamicsWorld(bulletDispatcher,bulletPairCache,bulletSolver,bulletCollisionConfiguration); ++ //bulletNumSolverIterations is not exported, but just to show how to use the Bullet API ++ bulletWorld->getSolverInfo().m_numIterations = bulletNumSolverIterations; ++ ++ + m_world->lock(); + + // Register all collision agents + hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); + ++ printf("Number of Physics Systems:%d\n",m_physicsData->getPhysicsSystems().getSize()); ++ ++ converter = new ColladaConverter(bulletWorld); ++ + // Add all the physics systems to the world + for ( int i = 0; i < m_physicsData->getPhysicsSystems().getSize(); ++i ) + { +- m_world->addPhysicsSystem( m_physicsData->getPhysicsSystems()[i] ); ++ hkpPhysicsSystem* physSystem = m_physicsData->getPhysicsSystems()[i]; ++ m_world->addPhysicsSystem( physSystem ); ++ int numRigidBodies = physSystem->getRigidBodies().getSize(); ++ printf("Number of Rigid Bodies:%d\n",numRigidBodies); ++ for (int r=0;rgetRigidBodies()[r]; ++ bool isDynamic = !hrb->isFixedOrKeyframed(); ++ btTransform bulletTrans = getBulletFromHavokTransform(hrb->getCollidable()->getTransform()); ++ ++ const hkpShape* havokShape = hrb->getCollidable()->getShape(); ++ btCollisionShape* bulletShape = createBulletFromHavokShape(havokShape); ++ ++ if (bulletShape) ++ { ++ btRigidBody* body = converter->createRigidBody(isDynamic,hrb->getMass(),bulletTrans,bulletShape); ++ hrb->setUserData((hkUlong)body); ++ } ++ } ++ ++ int numConstraints = physSystem->getConstraints().getSize(); ++ printf("Number of Constraints:%d\n",numConstraints); ++ ++ for (int c=0;cgetConstraints()[c]; ++ switch (constraint->getData()->getType()) ++ { ++ ++ case hkpConstraintData::CONSTRAINT_TYPE_BALLANDSOCKET: ++ { ++ printf("TODO: create ballsocket constraint\n"); ++ break; ++ } ++ case hkpConstraintData::CONSTRAINT_TYPE_HINGE: ++ { ++ printf("TODO: create hinge constraint\n"); ++ break; ++ } ++ case hkpConstraintData::CONSTRAINT_TYPE_PRISMATIC: ++ { ++ printf("TODO: create prismatic (slider) constraint\n"); ++ break; ++ } ++ case hkpConstraintData::CONSTRAINT_TYPE_GENERIC: ++ { ++ printf("TODO: create generic constraint\n"); ++ break; ++ } ++ case hkpConstraintData::CONSTRAINT_TYPE_LIMITEDHINGE: ++ { ++ hkpLimitedHingeConstraintData* limHingeData = (hkpLimitedHingeConstraintData*)constraint->getData(); ++ ++ hkpConstraintData::ConstraintInfo infoOut; ++ limHingeData->getConstraintInfo(infoOut); ++ ++ int i=0; ++ ++ btTransform localAttachmentFrameRef; ++ localAttachmentFrameRef.setIdentity(); ++ btTransform localAttachmentFrameOther; ++ localAttachmentFrameOther.setIdentity(); ++ ++ if (infoOut.m_atoms) ++ { ++ while (infoOut.m_atoms[i].getType() != hkpConstraintAtom::TYPE_INVALID) ++ { ++ switch (infoOut.m_atoms[i].getType()) ++ { ++ ++ case hkpConstraintAtom::TYPE_SET_LOCAL_TRANSFORMS: ++ { ++ localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA); ++ localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB); ++ ++ break; ++ } ++ case hkpConstraintAtom::TYPE_SET_LOCAL_TRANSLATIONS: ++ { ++ //??? ++ localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA); ++ localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB); ++ break; ++ } ++ case hkpConstraintAtom::TYPE_SET_LOCAL_ROTATIONS: ++ { ++ //??? ++ localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA); ++ localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB); ++ break; ++ } ++ ++ default: ++ { ++ printf("unhandled constraint atom\n"); ++ } ++ }; ++ i++; ++ } ++ ++ } ++ ++ ++ ++ bool disableCollisionsBetweenLinkedBodies = true; ++ btRigidBody* body0 = (btRigidBody*) constraint->getRigidBodyA()->getUserData(); ++ btRigidBody* body1 = (btRigidBody*) constraint->getRigidBodyB()->getUserData(); ++ //if (body0 || body1) ++ { ++ ++ ++ btVector3 linearMinLimits(0,0,0); ++ btVector3 linMaxLimits(0,0,0); ++ btVector3 angularMinLimits(1,0,0); ++ btVector3 angularMaxLimits(-1,0,0); ++ btTypedConstraint* constraint = converter->createUniversalD6Constraint(body0,body1,localAttachmentFrameRef,localAttachmentFrameOther,linearMinLimits,linMaxLimits,angularMinLimits,angularMaxLimits,disableCollisionsBetweenLinkedBodies); ++ if (constraint) ++ { ++ printf("create limited hinge constraint\n"); ++ } else ++ { ++ printf("unable to create limited hinge constraint\n"); ++ } ++ } ++ ++ break; ++ } ++ ++ //CONSTRAINT_TYPE_LIMITEDHINGE = 2, ++ //CONSTRAINT_TYPE_POINTTOPATH = 3, ++ //CONSTRAINT_TYPE_RAGDOLL = 7, ++ //CONSTRAINT_TYPE_STIFFSPRING = 8, ++ //CONSTRAINT_TYPE_WHEEL = 9, ++ //CONSTRAINT_TYPE_CONTACT = 11, ++ //CONSTRAINT_TYPE_BREAKABLE = 12, ++ //CONSTRAINT_TYPE_MALLEABLE = 13, ++ //CONSTRAINT_TYPE_POINTTOPLANE = 14, ++ //CONSTRAINT_TYPE_PULLEY = 15, ++ //CONSTRAINT_TYPE_ROTATIONAL = 16, ++ //CONSTRAINT_TYPE_HINGE_LIMITS = 18, ++ //CONSTRAINT_TYPE_RAGDOLL_LIMITS = 19, ++ //CONSTRAINT_TYPE_CUSTOM = 20, ++ // Constraint Chains ++ //BEGIN_CONSTRAINT_CHAIN_TYPES = 100, ++ //CONSTRAINT_TYPE_STIFF_SPRING_CHAIN = 100, ++ //CONSTRAINT_TYPE_BALL_SOCKET_CHAIN = 101, ++ //CONSTRAINT_TYPE_POWERED_CHAIN = 102 ++ default: ++ { ++ printf("Unrecognized constraint type=$d\n",constraint->getData()->getType()); ++ } ++ ++ }; ++ } ++ + } + ++ ++ ++ //Export the Bullet dynamics world to COLLADA .dae XML ++ ++ converter ->save("havokToCollada.dae"); ++ ++ + // Setup graphics - this creates graphics objects for all rigid bodies and phantoms in the world + setupGraphics(); + diff --git a/Extras/khx2dae/readme.txt b/Extras/khx2dae/readme.txt new file mode 100644 index 0000000..76ec94b --- /dev/null +++ b/Extras/khx2dae/readme.txt @@ -0,0 +1,6 @@ + +hkx2dae converts Havok HKX files to COLLADA Physics .dae files. So Havok tools can be used with any COLLADA Physics enabled application, such as the Bullet physics engine. +Use the patch in combination with the free Havok 5.5 version to add COLLADA Physics export to the Havok SimpleLoad serialization sample (hk550\Demo\Demos\Common\Api\Serialize\SimpleLoad). + +For precompiled binary and further information, visit: +http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=12&t=2218 diff --git a/Extras/premake4.lua b/Extras/premake4.lua new file mode 100644 index 0000000..a3f0a6d --- /dev/null +++ b/Extras/premake4.lua @@ -0,0 +1,8 @@ + +include "HACD" +include "ConvexDecomposition" + +include "Serialize/BulletFileLoader" +include "Serialize/BulletWorldImporter" +include "Serialize/BulletXmlWorldImporter" + diff --git a/Extras/sph/READ_ME.txt b/Extras/sph/READ_ME.txt new file mode 100644 index 0000000..59546ca --- /dev/null +++ b/Extras/sph/READ_ME.txt @@ -0,0 +1,35 @@ + +FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU +Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + +A fast CPU and GPU fluid simulator. See website above for details. + +Notes +(April 2009) +------------------- + +- Press 'h' for help screen. This shows keyboard cmds available. + +- By default, GPU simulation is off. + When running the fluid_gpu.exe, press 'g' to start/stop GPU simulation. + +- Disabling shadows in common_defs.h will greatly speed up the simulation + (You can also press 's' to render without shadows) + +- As of April 2009, CUDA builds only under Visual Studio 2005, not VS 2008. + To enable the CUDA build in VS2005, set the BUILD_CUDA define in common_defs.h + Be sure this is turned off if you build with VS2008. + +- The GPU integrator is not yet complete. Integration always takes place on the CPU, in both CPU and GPU modes. (As a result, this forces a bus transfer to and from the GPU per cycle. Once the integrator is finished, GPU simulation performance should increase significantly.) + +- Occassionally, the GPU simulation with crash cuda, causing the screen to blink and particles to move randomly. This is believed to be due to a not-yet-found out of bounds condition. + +ZLib License +------------------- +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/Extras/sph/cmp.sh b/Extras/sph/cmp.sh new file mode 100644 index 0000000..97c0352 --- /dev/null +++ b/Extras/sph/cmp.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +g++ -O3 -L./common -I./common -L./particles -I./particles -lGL -lglut common/matrix.cpp common/mdebug.cpp common/merror.cpp common/vector.cpp common/mtime.cpp particles/particle.cpp particles/particle_system.cpp GLee.c main.cpp +g++ -g -L./common -I./common -L./particles -I./particles -lGL -lglut common/matrix.cpp common/mdebug.cpp common/merror.cpp common/vector.cpp common/mtime.cpp particles/particle.cpp particles/particle_system.cpp GLee.c main.cpp -o sph_sim.debug + diff --git a/Extras/sph/common/GLee.c b/Extras/sph/common/GLee.c new file mode 100644 index 0000000..245b04d --- /dev/null +++ b/Extras/sph/common/GLee.c @@ -0,0 +1,18170 @@ +/*************************************************************************** +* +* GLee.c +* GLee (OpenGL Easy Extension library) +* Version : 5.4 +* +* Copyright (c)2009 Ben Woodhouse All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer as +* the first lines of this file unmodified. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BEN WOODHOUSE ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL BEN WOODHOUSE BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +* Web: http://elf-stone.com/glee.php +* +* [This file was automatically generated by GLeeGen 7.0 +* +***************************************************************************/ + +#ifdef _MSC_VER + #pragma optimize( "g", off ) +#endif + +#include +#include +#include +#include "GLee.h" + +#if defined(__APPLE__) || defined(__APPLE_CC__) + #include +#endif + +typedef GLuint(*GLEE_LINK_FUNCTION)(void); + +GLboolean __GLeeInited=GL_FALSE; + +#ifndef _WIN32 + #define __stdcall /* nothing */ +#endif + +void * __GLeeGetProcAddress(const char *extname) +{ +#ifdef WIN32 + return (void*)wglGetProcAddress(extname); +#elif defined(__APPLE__) || defined(__APPLE_CC__) + CFBundleRef bundle; + CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true); + + CFStringRef functionName = CFStringCreateWithCString(kCFAllocatorDefault, extname, kCFStringEncodingASCII); + + void *function; + + bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); + assert(bundle != NULL); + + function = CFBundleGetFunctionPointerForName(bundle, functionName); + + CFRelease(bundleURL); + CFRelease(functionName); + CFRelease(bundle); + + return function; +#else + return (void*)glXGetProcAddressARB((const GLubyte *)extname); +#endif +} + + + + +/* Extension querying variables */ + +GLboolean _GLEE_VERSION_1_2 = GL_FALSE; +GLboolean _GLEE_ARB_imaging = GL_FALSE; +GLboolean _GLEE_VERSION_1_3 = GL_FALSE; +GLboolean _GLEE_VERSION_1_4 = GL_FALSE; +GLboolean _GLEE_VERSION_1_5 = GL_FALSE; +GLboolean _GLEE_VERSION_2_0 = GL_FALSE; +GLboolean _GLEE_VERSION_2_1 = GL_FALSE; +GLboolean _GLEE_VERSION_3_0 = GL_FALSE; +GLboolean _GLEE_ARB_multitexture = GL_FALSE; +GLboolean _GLEE_ARB_transpose_matrix = GL_FALSE; +GLboolean _GLEE_ARB_multisample = GL_FALSE; +GLboolean _GLEE_ARB_texture_env_add = GL_FALSE; +GLboolean _GLEE_ARB_texture_cube_map = GL_FALSE; +GLboolean _GLEE_ARB_texture_compression = GL_FALSE; +GLboolean _GLEE_ARB_texture_border_clamp = GL_FALSE; +GLboolean _GLEE_ARB_point_parameters = GL_FALSE; +GLboolean _GLEE_ARB_vertex_blend = GL_FALSE; +GLboolean _GLEE_ARB_matrix_palette = GL_FALSE; +GLboolean _GLEE_ARB_texture_env_combine = GL_FALSE; +GLboolean _GLEE_ARB_texture_env_crossbar = GL_FALSE; +GLboolean _GLEE_ARB_texture_env_dot3 = GL_FALSE; +GLboolean _GLEE_ARB_texture_mirrored_repeat = GL_FALSE; +GLboolean _GLEE_ARB_depth_texture = GL_FALSE; +GLboolean _GLEE_ARB_shadow = GL_FALSE; +GLboolean _GLEE_ARB_shadow_ambient = GL_FALSE; +GLboolean _GLEE_ARB_window_pos = GL_FALSE; +GLboolean _GLEE_ARB_vertex_program = GL_FALSE; +GLboolean _GLEE_ARB_fragment_program = GL_FALSE; +GLboolean _GLEE_ARB_vertex_buffer_object = GL_FALSE; +GLboolean _GLEE_ARB_occlusion_query = GL_FALSE; +GLboolean _GLEE_ARB_shader_objects = GL_FALSE; +GLboolean _GLEE_ARB_vertex_shader = GL_FALSE; +GLboolean _GLEE_ARB_fragment_shader = GL_FALSE; +GLboolean _GLEE_ARB_shading_language_100 = GL_FALSE; +GLboolean _GLEE_ARB_texture_non_power_of_two = GL_FALSE; +GLboolean _GLEE_ARB_point_sprite = GL_FALSE; +GLboolean _GLEE_ARB_fragment_program_shadow = GL_FALSE; +GLboolean _GLEE_ARB_draw_buffers = GL_FALSE; +GLboolean _GLEE_ARB_texture_rectangle = GL_FALSE; +GLboolean _GLEE_ARB_color_buffer_float = GL_FALSE; +GLboolean _GLEE_ARB_half_float_pixel = GL_FALSE; +GLboolean _GLEE_ARB_texture_float = GL_FALSE; +GLboolean _GLEE_ARB_pixel_buffer_object = GL_FALSE; +GLboolean _GLEE_ARB_depth_buffer_float = GL_FALSE; +GLboolean _GLEE_ARB_draw_instanced = GL_FALSE; +GLboolean _GLEE_ARB_framebuffer_object = GL_FALSE; +GLboolean _GLEE_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean _GLEE_ARB_geometry_shader4 = GL_FALSE; +GLboolean _GLEE_ARB_half_float_vertex = GL_FALSE; +GLboolean _GLEE_ARB_instanced_arrays = GL_FALSE; +GLboolean _GLEE_ARB_map_buffer_range = GL_FALSE; +GLboolean _GLEE_ARB_texture_buffer_object = GL_FALSE; +GLboolean _GLEE_ARB_texture_compression_rgtc = GL_FALSE; +GLboolean _GLEE_ARB_texture_rg = GL_FALSE; +GLboolean _GLEE_ARB_vertex_array_object = GL_FALSE; +GLboolean _GLEE_EXT_abgr = GL_FALSE; +GLboolean _GLEE_EXT_blend_color = GL_FALSE; +GLboolean _GLEE_EXT_polygon_offset = GL_FALSE; +GLboolean _GLEE_EXT_texture = GL_FALSE; +GLboolean _GLEE_EXT_texture3D = GL_FALSE; +GLboolean _GLEE_SGIS_texture_filter4 = GL_FALSE; +GLboolean _GLEE_EXT_subtexture = GL_FALSE; +GLboolean _GLEE_EXT_copy_texture = GL_FALSE; +GLboolean _GLEE_EXT_histogram = GL_FALSE; +GLboolean _GLEE_EXT_convolution = GL_FALSE; +GLboolean _GLEE_SGI_color_matrix = GL_FALSE; +GLboolean _GLEE_SGI_color_table = GL_FALSE; +GLboolean _GLEE_SGIS_pixel_texture = GL_FALSE; +GLboolean _GLEE_SGIX_pixel_texture = GL_FALSE; +GLboolean _GLEE_SGIS_texture4D = GL_FALSE; +GLboolean _GLEE_SGI_texture_color_table = GL_FALSE; +GLboolean _GLEE_EXT_cmyka = GL_FALSE; +GLboolean _GLEE_EXT_texture_object = GL_FALSE; +GLboolean _GLEE_SGIS_detail_texture = GL_FALSE; +GLboolean _GLEE_SGIS_sharpen_texture = GL_FALSE; +GLboolean _GLEE_EXT_packed_pixels = GL_FALSE; +GLboolean _GLEE_SGIS_texture_lod = GL_FALSE; +GLboolean _GLEE_SGIS_multisample = GL_FALSE; +GLboolean _GLEE_EXT_rescale_normal = GL_FALSE; +GLboolean _GLEE_EXT_vertex_array = GL_FALSE; +GLboolean _GLEE_EXT_misc_attribute = GL_FALSE; +GLboolean _GLEE_SGIS_generate_mipmap = GL_FALSE; +GLboolean _GLEE_SGIX_clipmap = GL_FALSE; +GLboolean _GLEE_SGIX_shadow = GL_FALSE; +GLboolean _GLEE_SGIS_texture_edge_clamp = GL_FALSE; +GLboolean _GLEE_SGIS_texture_border_clamp = GL_FALSE; +GLboolean _GLEE_EXT_blend_minmax = GL_FALSE; +GLboolean _GLEE_EXT_blend_subtract = GL_FALSE; +GLboolean _GLEE_EXT_blend_logic_op = GL_FALSE; +GLboolean _GLEE_SGIX_interlace = GL_FALSE; +GLboolean _GLEE_SGIX_pixel_tiles = GL_FALSE; +GLboolean _GLEE_SGIS_texture_select = GL_FALSE; +GLboolean _GLEE_SGIX_sprite = GL_FALSE; +GLboolean _GLEE_SGIX_texture_multi_buffer = GL_FALSE; +GLboolean _GLEE_EXT_point_parameters = GL_FALSE; +GLboolean _GLEE_SGIS_point_parameters = GL_FALSE; +GLboolean _GLEE_SGIX_instruments = GL_FALSE; +GLboolean _GLEE_SGIX_texture_scale_bias = GL_FALSE; +GLboolean _GLEE_SGIX_framezoom = GL_FALSE; +GLboolean _GLEE_SGIX_tag_sample_buffer = GL_FALSE; +GLboolean _GLEE_FfdMaskSGIX = GL_FALSE; +GLboolean _GLEE_SGIX_polynomial_ffd = GL_FALSE; +GLboolean _GLEE_SGIX_reference_plane = GL_FALSE; +GLboolean _GLEE_SGIX_flush_raster = GL_FALSE; +GLboolean _GLEE_SGIX_depth_texture = GL_FALSE; +GLboolean _GLEE_SGIS_fog_function = GL_FALSE; +GLboolean _GLEE_SGIX_fog_offset = GL_FALSE; +GLboolean _GLEE_HP_image_transform = GL_FALSE; +GLboolean _GLEE_HP_convolution_border_modes = GL_FALSE; +GLboolean _GLEE_INGR_palette_buffer = GL_FALSE; +GLboolean _GLEE_SGIX_texture_add_env = GL_FALSE; +GLboolean _GLEE_EXT_color_subtable = GL_FALSE; +GLboolean _GLEE_PGI_vertex_hints = GL_FALSE; +GLboolean _GLEE_PGI_misc_hints = GL_FALSE; +GLboolean _GLEE_EXT_paletted_texture = GL_FALSE; +GLboolean _GLEE_EXT_clip_volume_hint = GL_FALSE; +GLboolean _GLEE_SGIX_list_priority = GL_FALSE; +GLboolean _GLEE_SGIX_ir_instrument1 = GL_FALSE; +GLboolean _GLEE_SGIX_calligraphic_fragment = GL_FALSE; +GLboolean _GLEE_SGIX_texture_lod_bias = GL_FALSE; +GLboolean _GLEE_SGIX_shadow_ambient = GL_FALSE; +GLboolean _GLEE_EXT_index_texture = GL_FALSE; +GLboolean _GLEE_EXT_index_material = GL_FALSE; +GLboolean _GLEE_EXT_index_func = GL_FALSE; +GLboolean _GLEE_EXT_index_array_formats = GL_FALSE; +GLboolean _GLEE_EXT_compiled_vertex_array = GL_FALSE; +GLboolean _GLEE_EXT_cull_vertex = GL_FALSE; +GLboolean _GLEE_SGIX_ycrcb = GL_FALSE; +GLboolean _GLEE_SGIX_fragment_lighting = GL_FALSE; +GLboolean _GLEE_IBM_rasterpos_clip = GL_FALSE; +GLboolean _GLEE_HP_texture_lighting = GL_FALSE; +GLboolean _GLEE_EXT_draw_range_elements = GL_FALSE; +GLboolean _GLEE_WIN_phong_shading = GL_FALSE; +GLboolean _GLEE_WIN_specular_fog = GL_FALSE; +GLboolean _GLEE_EXT_light_texture = GL_FALSE; +GLboolean _GLEE_SGIX_blend_alpha_minmax = GL_FALSE; +GLboolean _GLEE_SGIX_impact_pixel_texture = GL_FALSE; +GLboolean _GLEE_EXT_bgra = GL_FALSE; +GLboolean _GLEE_SGIX_async = GL_FALSE; +GLboolean _GLEE_SGIX_async_pixel = GL_FALSE; +GLboolean _GLEE_SGIX_async_histogram = GL_FALSE; +GLboolean _GLEE_INTEL_texture_scissor = GL_FALSE; +GLboolean _GLEE_INTEL_parallel_arrays = GL_FALSE; +GLboolean _GLEE_HP_occlusion_test = GL_FALSE; +GLboolean _GLEE_EXT_pixel_transform = GL_FALSE; +GLboolean _GLEE_EXT_pixel_transform_color_table = GL_FALSE; +GLboolean _GLEE_EXT_shared_texture_palette = GL_FALSE; +GLboolean _GLEE_EXT_separate_specular_color = GL_FALSE; +GLboolean _GLEE_EXT_secondary_color = GL_FALSE; +GLboolean _GLEE_EXT_texture_perturb_normal = GL_FALSE; +GLboolean _GLEE_EXT_multi_draw_arrays = GL_FALSE; +GLboolean _GLEE_EXT_fog_coord = GL_FALSE; +GLboolean _GLEE_REND_screen_coordinates = GL_FALSE; +GLboolean _GLEE_EXT_coordinate_frame = GL_FALSE; +GLboolean _GLEE_EXT_texture_env_combine = GL_FALSE; +GLboolean _GLEE_APPLE_specular_vector = GL_FALSE; +GLboolean _GLEE_APPLE_transform_hint = GL_FALSE; +GLboolean _GLEE_SGIX_fog_scale = GL_FALSE; +GLboolean _GLEE_SUNX_constant_data = GL_FALSE; +GLboolean _GLEE_SUN_global_alpha = GL_FALSE; +GLboolean _GLEE_SUN_triangle_list = GL_FALSE; +GLboolean _GLEE_SUN_vertex = GL_FALSE; +GLboolean _GLEE_EXT_blend_func_separate = GL_FALSE; +GLboolean _GLEE_INGR_color_clamp = GL_FALSE; +GLboolean _GLEE_INGR_interlace_read = GL_FALSE; +GLboolean _GLEE_EXT_stencil_wrap = GL_FALSE; +GLboolean _GLEE_EXT_422_pixels = GL_FALSE; +GLboolean _GLEE_NV_texgen_reflection = GL_FALSE; +GLboolean _GLEE_EXT_texture_cube_map = GL_FALSE; +GLboolean _GLEE_SUN_convolution_border_modes = GL_FALSE; +GLboolean _GLEE_EXT_texture_env_add = GL_FALSE; +GLboolean _GLEE_EXT_texture_lod_bias = GL_FALSE; +GLboolean _GLEE_EXT_texture_filter_anisotropic = GL_FALSE; +GLboolean _GLEE_EXT_vertex_weighting = GL_FALSE; +GLboolean _GLEE_NV_light_max_exponent = GL_FALSE; +GLboolean _GLEE_NV_vertex_array_range = GL_FALSE; +GLboolean _GLEE_NV_register_combiners = GL_FALSE; +GLboolean _GLEE_NV_fog_distance = GL_FALSE; +GLboolean _GLEE_NV_texgen_emboss = GL_FALSE; +GLboolean _GLEE_NV_blend_square = GL_FALSE; +GLboolean _GLEE_NV_texture_env_combine4 = GL_FALSE; +GLboolean _GLEE_MESA_resize_buffers = GL_FALSE; +GLboolean _GLEE_MESA_window_pos = GL_FALSE; +GLboolean _GLEE_EXT_texture_compression_s3tc = GL_FALSE; +GLboolean _GLEE_IBM_cull_vertex = GL_FALSE; +GLboolean _GLEE_IBM_multimode_draw_arrays = GL_FALSE; +GLboolean _GLEE_IBM_vertex_array_lists = GL_FALSE; +GLboolean _GLEE_SGIX_subsample = GL_FALSE; +GLboolean _GLEE_SGIX_ycrcb_subsample = GL_FALSE; +GLboolean _GLEE_SGIX_ycrcba = GL_FALSE; +GLboolean _GLEE_SGI_depth_pass_instrument = GL_FALSE; +GLboolean _GLEE_3DFX_texture_compression_FXT1 = GL_FALSE; +GLboolean _GLEE_3DFX_multisample = GL_FALSE; +GLboolean _GLEE_3DFX_tbuffer = GL_FALSE; +GLboolean _GLEE_EXT_multisample = GL_FALSE; +GLboolean _GLEE_SGIX_vertex_preclip = GL_FALSE; +GLboolean _GLEE_SGIX_convolution_accuracy = GL_FALSE; +GLboolean _GLEE_SGIX_resample = GL_FALSE; +GLboolean _GLEE_SGIS_point_line_texgen = GL_FALSE; +GLboolean _GLEE_SGIS_texture_color_mask = GL_FALSE; +GLboolean _GLEE_EXT_texture_env_dot3 = GL_FALSE; +GLboolean _GLEE_ATI_texture_mirror_once = GL_FALSE; +GLboolean _GLEE_NV_fence = GL_FALSE; +GLboolean _GLEE_IBM_texture_mirrored_repeat = GL_FALSE; +GLboolean _GLEE_NV_evaluators = GL_FALSE; +GLboolean _GLEE_NV_packed_depth_stencil = GL_FALSE; +GLboolean _GLEE_NV_register_combiners2 = GL_FALSE; +GLboolean _GLEE_NV_texture_compression_vtc = GL_FALSE; +GLboolean _GLEE_NV_texture_rectangle = GL_FALSE; +GLboolean _GLEE_NV_texture_shader = GL_FALSE; +GLboolean _GLEE_NV_texture_shader2 = GL_FALSE; +GLboolean _GLEE_NV_vertex_array_range2 = GL_FALSE; +GLboolean _GLEE_NV_vertex_program = GL_FALSE; +GLboolean _GLEE_SGIX_texture_coordinate_clamp = GL_FALSE; +GLboolean _GLEE_SGIX_scalebias_hint = GL_FALSE; +GLboolean _GLEE_OML_interlace = GL_FALSE; +GLboolean _GLEE_OML_subsample = GL_FALSE; +GLboolean _GLEE_OML_resample = GL_FALSE; +GLboolean _GLEE_NV_copy_depth_to_color = GL_FALSE; +GLboolean _GLEE_ATI_envmap_bumpmap = GL_FALSE; +GLboolean _GLEE_ATI_fragment_shader = GL_FALSE; +GLboolean _GLEE_ATI_pn_triangles = GL_FALSE; +GLboolean _GLEE_ATI_vertex_array_object = GL_FALSE; +GLboolean _GLEE_EXT_vertex_shader = GL_FALSE; +GLboolean _GLEE_ATI_vertex_streams = GL_FALSE; +GLboolean _GLEE_ATI_element_array = GL_FALSE; +GLboolean _GLEE_SUN_mesh_array = GL_FALSE; +GLboolean _GLEE_SUN_slice_accum = GL_FALSE; +GLboolean _GLEE_NV_multisample_filter_hint = GL_FALSE; +GLboolean _GLEE_NV_depth_clamp = GL_FALSE; +GLboolean _GLEE_NV_occlusion_query = GL_FALSE; +GLboolean _GLEE_NV_point_sprite = GL_FALSE; +GLboolean _GLEE_NV_texture_shader3 = GL_FALSE; +GLboolean _GLEE_NV_vertex_program1_1 = GL_FALSE; +GLboolean _GLEE_EXT_shadow_funcs = GL_FALSE; +GLboolean _GLEE_EXT_stencil_two_side = GL_FALSE; +GLboolean _GLEE_ATI_text_fragment_shader = GL_FALSE; +GLboolean _GLEE_APPLE_client_storage = GL_FALSE; +GLboolean _GLEE_APPLE_element_array = GL_FALSE; +GLboolean _GLEE_APPLE_fence = GL_FALSE; +GLboolean _GLEE_APPLE_vertex_array_object = GL_FALSE; +GLboolean _GLEE_APPLE_vertex_array_range = GL_FALSE; +GLboolean _GLEE_APPLE_ycbcr_422 = GL_FALSE; +GLboolean _GLEE_S3_s3tc = GL_FALSE; +GLboolean _GLEE_ATI_draw_buffers = GL_FALSE; +GLboolean _GLEE_ATI_pixel_format_float = GL_FALSE; +GLboolean _GLEE_ATI_texture_env_combine3 = GL_FALSE; +GLboolean _GLEE_ATI_texture_float = GL_FALSE; +GLboolean _GLEE_NV_float_buffer = GL_FALSE; +GLboolean _GLEE_NV_fragment_program = GL_FALSE; +GLboolean _GLEE_NV_half_float = GL_FALSE; +GLboolean _GLEE_NV_pixel_data_range = GL_FALSE; +GLboolean _GLEE_NV_primitive_restart = GL_FALSE; +GLboolean _GLEE_NV_texture_expand_normal = GL_FALSE; +GLboolean _GLEE_NV_vertex_program2 = GL_FALSE; +GLboolean _GLEE_ATI_map_object_buffer = GL_FALSE; +GLboolean _GLEE_ATI_separate_stencil = GL_FALSE; +GLboolean _GLEE_ATI_vertex_attrib_array_object = GL_FALSE; +GLboolean _GLEE_OES_read_format = GL_FALSE; +GLboolean _GLEE_EXT_depth_bounds_test = GL_FALSE; +GLboolean _GLEE_EXT_texture_mirror_clamp = GL_FALSE; +GLboolean _GLEE_EXT_blend_equation_separate = GL_FALSE; +GLboolean _GLEE_MESA_pack_invert = GL_FALSE; +GLboolean _GLEE_MESA_ycbcr_texture = GL_FALSE; +GLboolean _GLEE_EXT_pixel_buffer_object = GL_FALSE; +GLboolean _GLEE_NV_fragment_program_option = GL_FALSE; +GLboolean _GLEE_NV_fragment_program2 = GL_FALSE; +GLboolean _GLEE_NV_vertex_program2_option = GL_FALSE; +GLboolean _GLEE_NV_vertex_program3 = GL_FALSE; +GLboolean _GLEE_EXT_framebuffer_object = GL_FALSE; +GLboolean _GLEE_GREMEDY_string_marker = GL_FALSE; +GLboolean _GLEE_EXT_packed_depth_stencil = GL_FALSE; +GLboolean _GLEE_EXT_stencil_clear_tag = GL_FALSE; +GLboolean _GLEE_EXT_texture_sRGB = GL_FALSE; +GLboolean _GLEE_EXT_framebuffer_blit = GL_FALSE; +GLboolean _GLEE_EXT_framebuffer_multisample = GL_FALSE; +GLboolean _GLEE_MESAX_texture_stack = GL_FALSE; +GLboolean _GLEE_EXT_timer_query = GL_FALSE; +GLboolean _GLEE_EXT_gpu_program_parameters = GL_FALSE; +GLboolean _GLEE_APPLE_flush_buffer_range = GL_FALSE; +GLboolean _GLEE_EXT_gpu_shader4 = GL_FALSE; +GLboolean _GLEE_EXT_draw_instanced = GL_FALSE; +GLboolean _GLEE_EXT_packed_float = GL_FALSE; +GLboolean _GLEE_EXT_texture_array = GL_FALSE; +GLboolean _GLEE_EXT_texture_buffer_object = GL_FALSE; +GLboolean _GLEE_EXT_texture_compression_latc = GL_FALSE; +GLboolean _GLEE_EXT_texture_compression_rgtc = GL_FALSE; +GLboolean _GLEE_EXT_texture_shared_exponent = GL_FALSE; +GLboolean _GLEE_NV_depth_buffer_float = GL_FALSE; +GLboolean _GLEE_NV_framebuffer_multisample_coverage = GL_FALSE; +GLboolean _GLEE_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean _GLEE_NV_geometry_shader4 = GL_FALSE; +GLboolean _GLEE_NV_parameter_buffer_object = GL_FALSE; +GLboolean _GLEE_EXT_draw_buffers2 = GL_FALSE; +GLboolean _GLEE_NV_transform_feedback = GL_FALSE; +GLboolean _GLEE_EXT_bindable_uniform = GL_FALSE; +GLboolean _GLEE_EXT_texture_integer = GL_FALSE; +GLboolean _GLEE_GREMEDY_frame_terminator = GL_FALSE; +GLboolean _GLEE_NV_conditional_render = GL_FALSE; +GLboolean _GLEE_NV_present_video = GL_FALSE; +GLboolean _GLEE_EXT_transform_feedback = GL_FALSE; +GLboolean _GLEE_EXT_direct_state_access = GL_FALSE; +GLboolean _GLEE_EXT_vertex_array_bgra = GL_FALSE; +GLboolean _GLEE_EXT_texture_swizzle = GL_FALSE; +GLboolean _GLEE_NV_explicit_multisample = GL_FALSE; +GLboolean _GLEE_NV_transform_feedback2 = GL_FALSE; +GLboolean _GLEE_SGIX_texture_select = GL_FALSE; +GLboolean _GLEE_INGR_blend_func_separate = GL_FALSE; +GLboolean _GLEE_SGIX_depth_pass_instrument = GL_FALSE; +GLboolean _GLEE_SGIX_igloo_interface = GL_FALSE; +GLboolean _GLEE_EXT_fragment_lighting = GL_FALSE; +GLboolean _GLEE_EXT_geometry_shader4 = GL_FALSE; +GLboolean _GLEE_EXT_scene_marker = GL_FALSE; +GLboolean _GLEE_EXT_texture_compression_dxt1 = GL_FALSE; +GLboolean _GLEE_EXT_texture_env = GL_FALSE; +GLboolean _GLEE_IBM_static_data = GL_FALSE; +GLboolean _GLEE_NV_gpu_program4 = GL_FALSE; +GLboolean _GLEE_OES_byte_coordinates = GL_FALSE; +GLboolean _GLEE_OES_compressed_paletted_texture = GL_FALSE; +GLboolean _GLEE_OES_single_precision = GL_FALSE; +GLboolean _GLEE_SGIX_pixel_texture_bits = GL_FALSE; +GLboolean _GLEE_SGIX_texture_range = GL_FALSE; + +/* GL Extension names */ + +char __GLeeGLExtensionNames[322][39]={ + "GL_VERSION_1_2", + "GL_ARB_imaging", + "GL_VERSION_1_3", + "GL_VERSION_1_4", + "GL_VERSION_1_5", + "GL_VERSION_2_0", + "GL_VERSION_2_1", + "GL_VERSION_3_0", + "GL_ARB_multitexture", + "GL_ARB_transpose_matrix", + "GL_ARB_multisample", + "GL_ARB_texture_env_add", + "GL_ARB_texture_cube_map", + "GL_ARB_texture_compression", + "GL_ARB_texture_border_clamp", + "GL_ARB_point_parameters", + "GL_ARB_vertex_blend", + "GL_ARB_matrix_palette", + "GL_ARB_texture_env_combine", + "GL_ARB_texture_env_crossbar", + "GL_ARB_texture_env_dot3", + "GL_ARB_texture_mirrored_repeat", + "GL_ARB_depth_texture", + "GL_ARB_shadow", + "GL_ARB_shadow_ambient", + "GL_ARB_window_pos", + "GL_ARB_vertex_program", + "GL_ARB_fragment_program", + "GL_ARB_vertex_buffer_object", + "GL_ARB_occlusion_query", + "GL_ARB_shader_objects", + "GL_ARB_vertex_shader", + "GL_ARB_fragment_shader", + "GL_ARB_shading_language_100", + "GL_ARB_texture_non_power_of_two", + "GL_ARB_point_sprite", + "GL_ARB_fragment_program_shadow", + "GL_ARB_draw_buffers", + "GL_ARB_texture_rectangle", + "GL_ARB_color_buffer_float", + "GL_ARB_half_float_pixel", + "GL_ARB_texture_float", + "GL_ARB_pixel_buffer_object", + "GL_ARB_depth_buffer_float", + "GL_ARB_draw_instanced", + "GL_ARB_framebuffer_object", + "GL_ARB_framebuffer_sRGB", + "GL_ARB_geometry_shader4", + "GL_ARB_half_float_vertex", + "GL_ARB_instanced_arrays", + "GL_ARB_map_buffer_range", + "GL_ARB_texture_buffer_object", + "GL_ARB_texture_compression_rgtc", + "GL_ARB_texture_rg", + "GL_ARB_vertex_array_object", + "GL_EXT_abgr", + "GL_EXT_blend_color", + "GL_EXT_polygon_offset", + "GL_EXT_texture", + "GL_EXT_texture3D", + "GL_SGIS_texture_filter4", + "GL_EXT_subtexture", + "GL_EXT_copy_texture", + "GL_EXT_histogram", + "GL_EXT_convolution", + "GL_SGI_color_matrix", + "GL_SGI_color_table", + "GL_SGIS_pixel_texture", + "GL_SGIX_pixel_texture", + "GL_SGIS_texture4D", + "GL_SGI_texture_color_table", + "GL_EXT_cmyka", + "GL_EXT_texture_object", + "GL_SGIS_detail_texture", + "GL_SGIS_sharpen_texture", + "GL_EXT_packed_pixels", + "GL_SGIS_texture_lod", + "GL_SGIS_multisample", + "GL_EXT_rescale_normal", + "GL_EXT_vertex_array", + "GL_EXT_misc_attribute", + "GL_SGIS_generate_mipmap", + "GL_SGIX_clipmap", + "GL_SGIX_shadow", + "GL_SGIS_texture_edge_clamp", + "GL_SGIS_texture_border_clamp", + "GL_EXT_blend_minmax", + "GL_EXT_blend_subtract", + "GL_EXT_blend_logic_op", + "GL_SGIX_interlace", + "GL_SGIX_pixel_tiles", + "GL_SGIS_texture_select", + "GL_SGIX_sprite", + "GL_SGIX_texture_multi_buffer", + "GL_EXT_point_parameters", + "GL_SGIS_point_parameters", + "GL_SGIX_instruments", + "GL_SGIX_texture_scale_bias", + "GL_SGIX_framezoom", + "GL_SGIX_tag_sample_buffer", + "GL_FfdMaskSGIX", + "GL_SGIX_polynomial_ffd", + "GL_SGIX_reference_plane", + "GL_SGIX_flush_raster", + "GL_SGIX_depth_texture", + "GL_SGIS_fog_function", + "GL_SGIX_fog_offset", + "GL_HP_image_transform", + "GL_HP_convolution_border_modes", + "GL_INGR_palette_buffer", + "GL_SGIX_texture_add_env", + "GL_EXT_color_subtable", + "GL_PGI_vertex_hints", + "GL_PGI_misc_hints", + "GL_EXT_paletted_texture", + "GL_EXT_clip_volume_hint", + "GL_SGIX_list_priority", + "GL_SGIX_ir_instrument1", + "GL_SGIX_calligraphic_fragment", + "GL_SGIX_texture_lod_bias", + "GL_SGIX_shadow_ambient", + "GL_EXT_index_texture", + "GL_EXT_index_material", + "GL_EXT_index_func", + "GL_EXT_index_array_formats", + "GL_EXT_compiled_vertex_array", + "GL_EXT_cull_vertex", + "GL_SGIX_ycrcb", + "GL_SGIX_fragment_lighting", + "GL_IBM_rasterpos_clip", + "GL_HP_texture_lighting", + "GL_EXT_draw_range_elements", + "GL_WIN_phong_shading", + "GL_WIN_specular_fog", + "GL_EXT_light_texture", + "GL_SGIX_blend_alpha_minmax", + "GL_SGIX_impact_pixel_texture", + "GL_EXT_bgra", + "GL_SGIX_async", + "GL_SGIX_async_pixel", + "GL_SGIX_async_histogram", + "GL_INTEL_texture_scissor", + "GL_INTEL_parallel_arrays", + "GL_HP_occlusion_test", + "GL_EXT_pixel_transform", + "GL_EXT_pixel_transform_color_table", + "GL_EXT_shared_texture_palette", + "GL_EXT_separate_specular_color", + "GL_EXT_secondary_color", + "GL_EXT_texture_perturb_normal", + "GL_EXT_multi_draw_arrays", + "GL_EXT_fog_coord", + "GL_REND_screen_coordinates", + "GL_EXT_coordinate_frame", + "GL_EXT_texture_env_combine", + "GL_APPLE_specular_vector", + "GL_APPLE_transform_hint", + "GL_SGIX_fog_scale", + "GL_SUNX_constant_data", + "GL_SUN_global_alpha", + "GL_SUN_triangle_list", + "GL_SUN_vertex", + "GL_EXT_blend_func_separate", + "GL_INGR_color_clamp", + "GL_INGR_interlace_read", + "GL_EXT_stencil_wrap", + "GL_EXT_422_pixels", + "GL_NV_texgen_reflection", + "GL_EXT_texture_cube_map", + "GL_SUN_convolution_border_modes", + "GL_EXT_texture_env_add", + "GL_EXT_texture_lod_bias", + "GL_EXT_texture_filter_anisotropic", + "GL_EXT_vertex_weighting", + "GL_NV_light_max_exponent", + "GL_NV_vertex_array_range", + "GL_NV_register_combiners", + "GL_NV_fog_distance", + "GL_NV_texgen_emboss", + "GL_NV_blend_square", + "GL_NV_texture_env_combine4", + "GL_MESA_resize_buffers", + "GL_MESA_window_pos", + "GL_EXT_texture_compression_s3tc", + "GL_IBM_cull_vertex", + "GL_IBM_multimode_draw_arrays", + "GL_IBM_vertex_array_lists", + "GL_SGIX_subsample", + "GL_SGIX_ycrcb_subsample", + "GL_SGIX_ycrcba", + "GL_SGI_depth_pass_instrument", + "GL_3DFX_texture_compression_FXT1", + "GL_3DFX_multisample", + "GL_3DFX_tbuffer", + "GL_EXT_multisample", + "GL_SGIX_vertex_preclip", + "GL_SGIX_convolution_accuracy", + "GL_SGIX_resample", + "GL_SGIS_point_line_texgen", + "GL_SGIS_texture_color_mask", + "GL_EXT_texture_env_dot3", + "GL_ATI_texture_mirror_once", + "GL_NV_fence", + "GL_IBM_texture_mirrored_repeat", + "GL_NV_evaluators", + "GL_NV_packed_depth_stencil", + "GL_NV_register_combiners2", + "GL_NV_texture_compression_vtc", + "GL_NV_texture_rectangle", + "GL_NV_texture_shader", + "GL_NV_texture_shader2", + "GL_NV_vertex_array_range2", + "GL_NV_vertex_program", + "GL_SGIX_texture_coordinate_clamp", + "GL_SGIX_scalebias_hint", + "GL_OML_interlace", + "GL_OML_subsample", + "GL_OML_resample", + "GL_NV_copy_depth_to_color", + "GL_ATI_envmap_bumpmap", + "GL_ATI_fragment_shader", + "GL_ATI_pn_triangles", + "GL_ATI_vertex_array_object", + "GL_EXT_vertex_shader", + "GL_ATI_vertex_streams", + "GL_ATI_element_array", + "GL_SUN_mesh_array", + "GL_SUN_slice_accum", + "GL_NV_multisample_filter_hint", + "GL_NV_depth_clamp", + "GL_NV_occlusion_query", + "GL_NV_point_sprite", + "GL_NV_texture_shader3", + "GL_NV_vertex_program1_1", + "GL_EXT_shadow_funcs", + "GL_EXT_stencil_two_side", + "GL_ATI_text_fragment_shader", + "GL_APPLE_client_storage", + "GL_APPLE_element_array", + "GL_APPLE_fence", + "GL_APPLE_vertex_array_object", + "GL_APPLE_vertex_array_range", + "GL_APPLE_ycbcr_422", + "GL_S3_s3tc", + "GL_ATI_draw_buffers", + "GL_ATI_pixel_format_float", + "GL_ATI_texture_env_combine3", + "GL_ATI_texture_float", + "GL_NV_float_buffer", + "GL_NV_fragment_program", + "GL_NV_half_float", + "GL_NV_pixel_data_range", + "GL_NV_primitive_restart", + "GL_NV_texture_expand_normal", + "GL_NV_vertex_program2", + "GL_ATI_map_object_buffer", + "GL_ATI_separate_stencil", + "GL_ATI_vertex_attrib_array_object", + "GL_OES_read_format", + "GL_EXT_depth_bounds_test", + "GL_EXT_texture_mirror_clamp", + "GL_EXT_blend_equation_separate", + "GL_MESA_pack_invert", + "GL_MESA_ycbcr_texture", + "GL_EXT_pixel_buffer_object", + "GL_NV_fragment_program_option", + "GL_NV_fragment_program2", + "GL_NV_vertex_program2_option", + "GL_NV_vertex_program3", + "GL_EXT_framebuffer_object", + "GL_GREMEDY_string_marker", + "GL_EXT_packed_depth_stencil", + "GL_EXT_stencil_clear_tag", + "GL_EXT_texture_sRGB", + "GL_EXT_framebuffer_blit", + "GL_EXT_framebuffer_multisample", + "GL_MESAX_texture_stack", + "GL_EXT_timer_query", + "GL_EXT_gpu_program_parameters", + "GL_APPLE_flush_buffer_range", + "GL_EXT_gpu_shader4", + "GL_EXT_draw_instanced", + "GL_EXT_packed_float", + "GL_EXT_texture_array", + "GL_EXT_texture_buffer_object", + "GL_EXT_texture_compression_latc", + "GL_EXT_texture_compression_rgtc", + "GL_EXT_texture_shared_exponent", + "GL_NV_depth_buffer_float", + "GL_NV_framebuffer_multisample_coverage", + "GL_EXT_framebuffer_sRGB", + "GL_NV_geometry_shader4", + "GL_NV_parameter_buffer_object", + "GL_EXT_draw_buffers2", + "GL_NV_transform_feedback", + "GL_EXT_bindable_uniform", + "GL_EXT_texture_integer", + "GL_GREMEDY_frame_terminator", + "GL_NV_conditional_render", + "GL_NV_present_video", + "GL_EXT_transform_feedback", + "GL_EXT_direct_state_access", + "GL_EXT_vertex_array_bgra", + "GL_EXT_texture_swizzle", + "GL_NV_explicit_multisample", + "GL_NV_transform_feedback2", + "GL_SGIX_texture_select", + "GL_INGR_blend_func_separate", + "GL_SGIX_depth_pass_instrument", + "GL_SGIX_igloo_interface", + "GL_EXT_fragment_lighting", + "GL_EXT_geometry_shader4", + "GL_EXT_scene_marker", + "GL_EXT_texture_compression_dxt1", + "GL_EXT_texture_env", + "GL_IBM_static_data", + "GL_NV_gpu_program4", + "GL_OES_byte_coordinates", + "GL_OES_compressed_paletted_texture", + "GL_OES_single_precision", + "GL_SGIX_pixel_texture_bits", + "GL_SGIX_texture_range" +}; +int __GLeeGLNumExtensions=322; + +/* GL_VERSION_1_2 */ + +#ifdef __GLEE_GL_VERSION_1_2 +#ifndef GLEE_C_DEFINED_glBlendColor +#define GLEE_C_DEFINED_glBlendColor + void __stdcall GLee_Lazy_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {if (GLeeInit()) glBlendColor(red, green, blue, alpha);} + GLEEPFNGLBLENDCOLORPROC GLeeFuncPtr_glBlendColor=GLee_Lazy_glBlendColor; +#endif +#ifndef GLEE_C_DEFINED_glBlendEquation +#define GLEE_C_DEFINED_glBlendEquation + void __stdcall GLee_Lazy_glBlendEquation(GLenum mode) {if (GLeeInit()) glBlendEquation(mode);} + GLEEPFNGLBLENDEQUATIONPROC GLeeFuncPtr_glBlendEquation=GLee_Lazy_glBlendEquation; +#endif +#ifndef GLEE_C_DEFINED_glDrawRangeElements +#define GLEE_C_DEFINED_glDrawRangeElements + void __stdcall GLee_Lazy_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices) {if (GLeeInit()) glDrawRangeElements(mode, start, end, count, type, indices);} + GLEEPFNGLDRAWRANGEELEMENTSPROC GLeeFuncPtr_glDrawRangeElements=GLee_Lazy_glDrawRangeElements; +#endif +#ifndef GLEE_C_DEFINED_glColorTable +#define GLEE_C_DEFINED_glColorTable + void __stdcall GLee_Lazy_glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table) {if (GLeeInit()) glColorTable(target, internalformat, width, format, type, table);} + GLEEPFNGLCOLORTABLEPROC GLeeFuncPtr_glColorTable=GLee_Lazy_glColorTable; +#endif +#ifndef GLEE_C_DEFINED_glColorTableParameterfv +#define GLEE_C_DEFINED_glColorTableParameterfv + void __stdcall GLee_Lazy_glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glColorTableParameterfv(target, pname, params);} + GLEEPFNGLCOLORTABLEPARAMETERFVPROC GLeeFuncPtr_glColorTableParameterfv=GLee_Lazy_glColorTableParameterfv; +#endif +#ifndef GLEE_C_DEFINED_glColorTableParameteriv +#define GLEE_C_DEFINED_glColorTableParameteriv + void __stdcall GLee_Lazy_glColorTableParameteriv(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glColorTableParameteriv(target, pname, params);} + GLEEPFNGLCOLORTABLEPARAMETERIVPROC GLeeFuncPtr_glColorTableParameteriv=GLee_Lazy_glColorTableParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glCopyColorTable +#define GLEE_C_DEFINED_glCopyColorTable + void __stdcall GLee_Lazy_glCopyColorTable(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyColorTable(target, internalformat, x, y, width);} + GLEEPFNGLCOPYCOLORTABLEPROC GLeeFuncPtr_glCopyColorTable=GLee_Lazy_glCopyColorTable; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTable +#define GLEE_C_DEFINED_glGetColorTable + void __stdcall GLee_Lazy_glGetColorTable(GLenum target, GLenum format, GLenum type, GLvoid * table) {if (GLeeInit()) glGetColorTable(target, format, type, table);} + GLEEPFNGLGETCOLORTABLEPROC GLeeFuncPtr_glGetColorTable=GLee_Lazy_glGetColorTable; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableParameterfv +#define GLEE_C_DEFINED_glGetColorTableParameterfv + void __stdcall GLee_Lazy_glGetColorTableParameterfv(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetColorTableParameterfv(target, pname, params);} + GLEEPFNGLGETCOLORTABLEPARAMETERFVPROC GLeeFuncPtr_glGetColorTableParameterfv=GLee_Lazy_glGetColorTableParameterfv; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableParameteriv +#define GLEE_C_DEFINED_glGetColorTableParameteriv + void __stdcall GLee_Lazy_glGetColorTableParameteriv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetColorTableParameteriv(target, pname, params);} + GLEEPFNGLGETCOLORTABLEPARAMETERIVPROC GLeeFuncPtr_glGetColorTableParameteriv=GLee_Lazy_glGetColorTableParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glColorSubTable +#define GLEE_C_DEFINED_glColorSubTable + void __stdcall GLee_Lazy_glColorSubTable(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid * data) {if (GLeeInit()) glColorSubTable(target, start, count, format, type, data);} + GLEEPFNGLCOLORSUBTABLEPROC GLeeFuncPtr_glColorSubTable=GLee_Lazy_glColorSubTable; +#endif +#ifndef GLEE_C_DEFINED_glCopyColorSubTable +#define GLEE_C_DEFINED_glCopyColorSubTable + void __stdcall GLee_Lazy_glCopyColorSubTable(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyColorSubTable(target, start, x, y, width);} + GLEEPFNGLCOPYCOLORSUBTABLEPROC GLeeFuncPtr_glCopyColorSubTable=GLee_Lazy_glCopyColorSubTable; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionFilter1D +#define GLEE_C_DEFINED_glConvolutionFilter1D + void __stdcall GLee_Lazy_glConvolutionFilter1D(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * image) {if (GLeeInit()) glConvolutionFilter1D(target, internalformat, width, format, type, image);} + GLEEPFNGLCONVOLUTIONFILTER1DPROC GLeeFuncPtr_glConvolutionFilter1D=GLee_Lazy_glConvolutionFilter1D; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionFilter2D +#define GLEE_C_DEFINED_glConvolutionFilter2D + void __stdcall GLee_Lazy_glConvolutionFilter2D(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * image) {if (GLeeInit()) glConvolutionFilter2D(target, internalformat, width, height, format, type, image);} + GLEEPFNGLCONVOLUTIONFILTER2DPROC GLeeFuncPtr_glConvolutionFilter2D=GLee_Lazy_glConvolutionFilter2D; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameterf +#define GLEE_C_DEFINED_glConvolutionParameterf + void __stdcall GLee_Lazy_glConvolutionParameterf(GLenum target, GLenum pname, GLfloat params) {if (GLeeInit()) glConvolutionParameterf(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERFPROC GLeeFuncPtr_glConvolutionParameterf=GLee_Lazy_glConvolutionParameterf; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameterfv +#define GLEE_C_DEFINED_glConvolutionParameterfv + void __stdcall GLee_Lazy_glConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glConvolutionParameterfv(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERFVPROC GLeeFuncPtr_glConvolutionParameterfv=GLee_Lazy_glConvolutionParameterfv; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameteri +#define GLEE_C_DEFINED_glConvolutionParameteri + void __stdcall GLee_Lazy_glConvolutionParameteri(GLenum target, GLenum pname, GLint params) {if (GLeeInit()) glConvolutionParameteri(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERIPROC GLeeFuncPtr_glConvolutionParameteri=GLee_Lazy_glConvolutionParameteri; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameteriv +#define GLEE_C_DEFINED_glConvolutionParameteriv + void __stdcall GLee_Lazy_glConvolutionParameteriv(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glConvolutionParameteriv(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERIVPROC GLeeFuncPtr_glConvolutionParameteriv=GLee_Lazy_glConvolutionParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glCopyConvolutionFilter1D +#define GLEE_C_DEFINED_glCopyConvolutionFilter1D + void __stdcall GLee_Lazy_glCopyConvolutionFilter1D(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyConvolutionFilter1D(target, internalformat, x, y, width);} + GLEEPFNGLCOPYCONVOLUTIONFILTER1DPROC GLeeFuncPtr_glCopyConvolutionFilter1D=GLee_Lazy_glCopyConvolutionFilter1D; +#endif +#ifndef GLEE_C_DEFINED_glCopyConvolutionFilter2D +#define GLEE_C_DEFINED_glCopyConvolutionFilter2D + void __stdcall GLee_Lazy_glCopyConvolutionFilter2D(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyConvolutionFilter2D(target, internalformat, x, y, width, height);} + GLEEPFNGLCOPYCONVOLUTIONFILTER2DPROC GLeeFuncPtr_glCopyConvolutionFilter2D=GLee_Lazy_glCopyConvolutionFilter2D; +#endif +#ifndef GLEE_C_DEFINED_glGetConvolutionFilter +#define GLEE_C_DEFINED_glGetConvolutionFilter + void __stdcall GLee_Lazy_glGetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid * image) {if (GLeeInit()) glGetConvolutionFilter(target, format, type, image);} + GLEEPFNGLGETCONVOLUTIONFILTERPROC GLeeFuncPtr_glGetConvolutionFilter=GLee_Lazy_glGetConvolutionFilter; +#endif +#ifndef GLEE_C_DEFINED_glGetConvolutionParameterfv +#define GLEE_C_DEFINED_glGetConvolutionParameterfv + void __stdcall GLee_Lazy_glGetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetConvolutionParameterfv(target, pname, params);} + GLEEPFNGLGETCONVOLUTIONPARAMETERFVPROC GLeeFuncPtr_glGetConvolutionParameterfv=GLee_Lazy_glGetConvolutionParameterfv; +#endif +#ifndef GLEE_C_DEFINED_glGetConvolutionParameteriv +#define GLEE_C_DEFINED_glGetConvolutionParameteriv + void __stdcall GLee_Lazy_glGetConvolutionParameteriv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetConvolutionParameteriv(target, pname, params);} + GLEEPFNGLGETCONVOLUTIONPARAMETERIVPROC GLeeFuncPtr_glGetConvolutionParameteriv=GLee_Lazy_glGetConvolutionParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glGetSeparableFilter +#define GLEE_C_DEFINED_glGetSeparableFilter + void __stdcall GLee_Lazy_glGetSeparableFilter(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span) {if (GLeeInit()) glGetSeparableFilter(target, format, type, row, column, span);} + GLEEPFNGLGETSEPARABLEFILTERPROC GLeeFuncPtr_glGetSeparableFilter=GLee_Lazy_glGetSeparableFilter; +#endif +#ifndef GLEE_C_DEFINED_glSeparableFilter2D +#define GLEE_C_DEFINED_glSeparableFilter2D + void __stdcall GLee_Lazy_glSeparableFilter2D(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * row, const GLvoid * column) {if (GLeeInit()) glSeparableFilter2D(target, internalformat, width, height, format, type, row, column);} + GLEEPFNGLSEPARABLEFILTER2DPROC GLeeFuncPtr_glSeparableFilter2D=GLee_Lazy_glSeparableFilter2D; +#endif +#ifndef GLEE_C_DEFINED_glGetHistogram +#define GLEE_C_DEFINED_glGetHistogram + void __stdcall GLee_Lazy_glGetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) {if (GLeeInit()) glGetHistogram(target, reset, format, type, values);} + GLEEPFNGLGETHISTOGRAMPROC GLeeFuncPtr_glGetHistogram=GLee_Lazy_glGetHistogram; +#endif +#ifndef GLEE_C_DEFINED_glGetHistogramParameterfv +#define GLEE_C_DEFINED_glGetHistogramParameterfv + void __stdcall GLee_Lazy_glGetHistogramParameterfv(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetHistogramParameterfv(target, pname, params);} + GLEEPFNGLGETHISTOGRAMPARAMETERFVPROC GLeeFuncPtr_glGetHistogramParameterfv=GLee_Lazy_glGetHistogramParameterfv; +#endif +#ifndef GLEE_C_DEFINED_glGetHistogramParameteriv +#define GLEE_C_DEFINED_glGetHistogramParameteriv + void __stdcall GLee_Lazy_glGetHistogramParameteriv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetHistogramParameteriv(target, pname, params);} + GLEEPFNGLGETHISTOGRAMPARAMETERIVPROC GLeeFuncPtr_glGetHistogramParameteriv=GLee_Lazy_glGetHistogramParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glGetMinmax +#define GLEE_C_DEFINED_glGetMinmax + void __stdcall GLee_Lazy_glGetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) {if (GLeeInit()) glGetMinmax(target, reset, format, type, values);} + GLEEPFNGLGETMINMAXPROC GLeeFuncPtr_glGetMinmax=GLee_Lazy_glGetMinmax; +#endif +#ifndef GLEE_C_DEFINED_glGetMinmaxParameterfv +#define GLEE_C_DEFINED_glGetMinmaxParameterfv + void __stdcall GLee_Lazy_glGetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMinmaxParameterfv(target, pname, params);} + GLEEPFNGLGETMINMAXPARAMETERFVPROC GLeeFuncPtr_glGetMinmaxParameterfv=GLee_Lazy_glGetMinmaxParameterfv; +#endif +#ifndef GLEE_C_DEFINED_glGetMinmaxParameteriv +#define GLEE_C_DEFINED_glGetMinmaxParameteriv + void __stdcall GLee_Lazy_glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetMinmaxParameteriv(target, pname, params);} + GLEEPFNGLGETMINMAXPARAMETERIVPROC GLeeFuncPtr_glGetMinmaxParameteriv=GLee_Lazy_glGetMinmaxParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glHistogram +#define GLEE_C_DEFINED_glHistogram + void __stdcall GLee_Lazy_glHistogram(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) {if (GLeeInit()) glHistogram(target, width, internalformat, sink);} + GLEEPFNGLHISTOGRAMPROC GLeeFuncPtr_glHistogram=GLee_Lazy_glHistogram; +#endif +#ifndef GLEE_C_DEFINED_glMinmax +#define GLEE_C_DEFINED_glMinmax + void __stdcall GLee_Lazy_glMinmax(GLenum target, GLenum internalformat, GLboolean sink) {if (GLeeInit()) glMinmax(target, internalformat, sink);} + GLEEPFNGLMINMAXPROC GLeeFuncPtr_glMinmax=GLee_Lazy_glMinmax; +#endif +#ifndef GLEE_C_DEFINED_glResetHistogram +#define GLEE_C_DEFINED_glResetHistogram + void __stdcall GLee_Lazy_glResetHistogram(GLenum target) {if (GLeeInit()) glResetHistogram(target);} + GLEEPFNGLRESETHISTOGRAMPROC GLeeFuncPtr_glResetHistogram=GLee_Lazy_glResetHistogram; +#endif +#ifndef GLEE_C_DEFINED_glResetMinmax +#define GLEE_C_DEFINED_glResetMinmax + void __stdcall GLee_Lazy_glResetMinmax(GLenum target) {if (GLeeInit()) glResetMinmax(target);} + GLEEPFNGLRESETMINMAXPROC GLeeFuncPtr_glResetMinmax=GLee_Lazy_glResetMinmax; +#endif +#ifndef GLEE_C_DEFINED_glTexImage3D +#define GLEE_C_DEFINED_glTexImage3D + void __stdcall GLee_Lazy_glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);} + GLEEPFNGLTEXIMAGE3DPROC GLeeFuncPtr_glTexImage3D=GLee_Lazy_glTexImage3D; +#endif +#ifndef GLEE_C_DEFINED_glTexSubImage3D +#define GLEE_C_DEFINED_glTexSubImage3D + void __stdcall GLee_Lazy_glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);} + GLEEPFNGLTEXSUBIMAGE3DPROC GLeeFuncPtr_glTexSubImage3D=GLee_Lazy_glTexSubImage3D; +#endif +#ifndef GLEE_C_DEFINED_glCopyTexSubImage3D +#define GLEE_C_DEFINED_glCopyTexSubImage3D + void __stdcall GLee_Lazy_glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);} + GLEEPFNGLCOPYTEXSUBIMAGE3DPROC GLeeFuncPtr_glCopyTexSubImage3D=GLee_Lazy_glCopyTexSubImage3D; +#endif +#endif + +/* GL_ARB_imaging */ + +#ifdef __GLEE_GL_ARB_imaging +#endif + +/* GL_VERSION_1_3 */ + +#ifdef __GLEE_GL_VERSION_1_3 +#ifndef GLEE_C_DEFINED_glActiveTexture +#define GLEE_C_DEFINED_glActiveTexture + void __stdcall GLee_Lazy_glActiveTexture(GLenum texture) {if (GLeeInit()) glActiveTexture(texture);} + GLEEPFNGLACTIVETEXTUREPROC GLeeFuncPtr_glActiveTexture=GLee_Lazy_glActiveTexture; +#endif +#ifndef GLEE_C_DEFINED_glClientActiveTexture +#define GLEE_C_DEFINED_glClientActiveTexture + void __stdcall GLee_Lazy_glClientActiveTexture(GLenum texture) {if (GLeeInit()) glClientActiveTexture(texture);} + GLEEPFNGLCLIENTACTIVETEXTUREPROC GLeeFuncPtr_glClientActiveTexture=GLee_Lazy_glClientActiveTexture; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1d +#define GLEE_C_DEFINED_glMultiTexCoord1d + void __stdcall GLee_Lazy_glMultiTexCoord1d(GLenum target, GLdouble s) {if (GLeeInit()) glMultiTexCoord1d(target, s);} + GLEEPFNGLMULTITEXCOORD1DPROC GLeeFuncPtr_glMultiTexCoord1d=GLee_Lazy_glMultiTexCoord1d; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1dv +#define GLEE_C_DEFINED_glMultiTexCoord1dv + void __stdcall GLee_Lazy_glMultiTexCoord1dv(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord1dv(target, v);} + GLEEPFNGLMULTITEXCOORD1DVPROC GLeeFuncPtr_glMultiTexCoord1dv=GLee_Lazy_glMultiTexCoord1dv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1f +#define GLEE_C_DEFINED_glMultiTexCoord1f + void __stdcall GLee_Lazy_glMultiTexCoord1f(GLenum target, GLfloat s) {if (GLeeInit()) glMultiTexCoord1f(target, s);} + GLEEPFNGLMULTITEXCOORD1FPROC GLeeFuncPtr_glMultiTexCoord1f=GLee_Lazy_glMultiTexCoord1f; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1fv +#define GLEE_C_DEFINED_glMultiTexCoord1fv + void __stdcall GLee_Lazy_glMultiTexCoord1fv(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord1fv(target, v);} + GLEEPFNGLMULTITEXCOORD1FVPROC GLeeFuncPtr_glMultiTexCoord1fv=GLee_Lazy_glMultiTexCoord1fv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1i +#define GLEE_C_DEFINED_glMultiTexCoord1i + void __stdcall GLee_Lazy_glMultiTexCoord1i(GLenum target, GLint s) {if (GLeeInit()) glMultiTexCoord1i(target, s);} + GLEEPFNGLMULTITEXCOORD1IPROC GLeeFuncPtr_glMultiTexCoord1i=GLee_Lazy_glMultiTexCoord1i; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1iv +#define GLEE_C_DEFINED_glMultiTexCoord1iv + void __stdcall GLee_Lazy_glMultiTexCoord1iv(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord1iv(target, v);} + GLEEPFNGLMULTITEXCOORD1IVPROC GLeeFuncPtr_glMultiTexCoord1iv=GLee_Lazy_glMultiTexCoord1iv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1s +#define GLEE_C_DEFINED_glMultiTexCoord1s + void __stdcall GLee_Lazy_glMultiTexCoord1s(GLenum target, GLshort s) {if (GLeeInit()) glMultiTexCoord1s(target, s);} + GLEEPFNGLMULTITEXCOORD1SPROC GLeeFuncPtr_glMultiTexCoord1s=GLee_Lazy_glMultiTexCoord1s; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1sv +#define GLEE_C_DEFINED_glMultiTexCoord1sv + void __stdcall GLee_Lazy_glMultiTexCoord1sv(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord1sv(target, v);} + GLEEPFNGLMULTITEXCOORD1SVPROC GLeeFuncPtr_glMultiTexCoord1sv=GLee_Lazy_glMultiTexCoord1sv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2d +#define GLEE_C_DEFINED_glMultiTexCoord2d + void __stdcall GLee_Lazy_glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {if (GLeeInit()) glMultiTexCoord2d(target, s, t);} + GLEEPFNGLMULTITEXCOORD2DPROC GLeeFuncPtr_glMultiTexCoord2d=GLee_Lazy_glMultiTexCoord2d; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2dv +#define GLEE_C_DEFINED_glMultiTexCoord2dv + void __stdcall GLee_Lazy_glMultiTexCoord2dv(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord2dv(target, v);} + GLEEPFNGLMULTITEXCOORD2DVPROC GLeeFuncPtr_glMultiTexCoord2dv=GLee_Lazy_glMultiTexCoord2dv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2f +#define GLEE_C_DEFINED_glMultiTexCoord2f + void __stdcall GLee_Lazy_glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) {if (GLeeInit()) glMultiTexCoord2f(target, s, t);} + GLEEPFNGLMULTITEXCOORD2FPROC GLeeFuncPtr_glMultiTexCoord2f=GLee_Lazy_glMultiTexCoord2f; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2fv +#define GLEE_C_DEFINED_glMultiTexCoord2fv + void __stdcall GLee_Lazy_glMultiTexCoord2fv(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord2fv(target, v);} + GLEEPFNGLMULTITEXCOORD2FVPROC GLeeFuncPtr_glMultiTexCoord2fv=GLee_Lazy_glMultiTexCoord2fv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2i +#define GLEE_C_DEFINED_glMultiTexCoord2i + void __stdcall GLee_Lazy_glMultiTexCoord2i(GLenum target, GLint s, GLint t) {if (GLeeInit()) glMultiTexCoord2i(target, s, t);} + GLEEPFNGLMULTITEXCOORD2IPROC GLeeFuncPtr_glMultiTexCoord2i=GLee_Lazy_glMultiTexCoord2i; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2iv +#define GLEE_C_DEFINED_glMultiTexCoord2iv + void __stdcall GLee_Lazy_glMultiTexCoord2iv(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord2iv(target, v);} + GLEEPFNGLMULTITEXCOORD2IVPROC GLeeFuncPtr_glMultiTexCoord2iv=GLee_Lazy_glMultiTexCoord2iv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2s +#define GLEE_C_DEFINED_glMultiTexCoord2s + void __stdcall GLee_Lazy_glMultiTexCoord2s(GLenum target, GLshort s, GLshort t) {if (GLeeInit()) glMultiTexCoord2s(target, s, t);} + GLEEPFNGLMULTITEXCOORD2SPROC GLeeFuncPtr_glMultiTexCoord2s=GLee_Lazy_glMultiTexCoord2s; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2sv +#define GLEE_C_DEFINED_glMultiTexCoord2sv + void __stdcall GLee_Lazy_glMultiTexCoord2sv(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord2sv(target, v);} + GLEEPFNGLMULTITEXCOORD2SVPROC GLeeFuncPtr_glMultiTexCoord2sv=GLee_Lazy_glMultiTexCoord2sv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3d +#define GLEE_C_DEFINED_glMultiTexCoord3d + void __stdcall GLee_Lazy_glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {if (GLeeInit()) glMultiTexCoord3d(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3DPROC GLeeFuncPtr_glMultiTexCoord3d=GLee_Lazy_glMultiTexCoord3d; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3dv +#define GLEE_C_DEFINED_glMultiTexCoord3dv + void __stdcall GLee_Lazy_glMultiTexCoord3dv(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord3dv(target, v);} + GLEEPFNGLMULTITEXCOORD3DVPROC GLeeFuncPtr_glMultiTexCoord3dv=GLee_Lazy_glMultiTexCoord3dv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3f +#define GLEE_C_DEFINED_glMultiTexCoord3f + void __stdcall GLee_Lazy_glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {if (GLeeInit()) glMultiTexCoord3f(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3FPROC GLeeFuncPtr_glMultiTexCoord3f=GLee_Lazy_glMultiTexCoord3f; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3fv +#define GLEE_C_DEFINED_glMultiTexCoord3fv + void __stdcall GLee_Lazy_glMultiTexCoord3fv(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord3fv(target, v);} + GLEEPFNGLMULTITEXCOORD3FVPROC GLeeFuncPtr_glMultiTexCoord3fv=GLee_Lazy_glMultiTexCoord3fv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3i +#define GLEE_C_DEFINED_glMultiTexCoord3i + void __stdcall GLee_Lazy_glMultiTexCoord3i(GLenum target, GLint s, GLint t, GLint r) {if (GLeeInit()) glMultiTexCoord3i(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3IPROC GLeeFuncPtr_glMultiTexCoord3i=GLee_Lazy_glMultiTexCoord3i; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3iv +#define GLEE_C_DEFINED_glMultiTexCoord3iv + void __stdcall GLee_Lazy_glMultiTexCoord3iv(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord3iv(target, v);} + GLEEPFNGLMULTITEXCOORD3IVPROC GLeeFuncPtr_glMultiTexCoord3iv=GLee_Lazy_glMultiTexCoord3iv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3s +#define GLEE_C_DEFINED_glMultiTexCoord3s + void __stdcall GLee_Lazy_glMultiTexCoord3s(GLenum target, GLshort s, GLshort t, GLshort r) {if (GLeeInit()) glMultiTexCoord3s(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3SPROC GLeeFuncPtr_glMultiTexCoord3s=GLee_Lazy_glMultiTexCoord3s; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3sv +#define GLEE_C_DEFINED_glMultiTexCoord3sv + void __stdcall GLee_Lazy_glMultiTexCoord3sv(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord3sv(target, v);} + GLEEPFNGLMULTITEXCOORD3SVPROC GLeeFuncPtr_glMultiTexCoord3sv=GLee_Lazy_glMultiTexCoord3sv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4d +#define GLEE_C_DEFINED_glMultiTexCoord4d + void __stdcall GLee_Lazy_glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {if (GLeeInit()) glMultiTexCoord4d(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4DPROC GLeeFuncPtr_glMultiTexCoord4d=GLee_Lazy_glMultiTexCoord4d; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4dv +#define GLEE_C_DEFINED_glMultiTexCoord4dv + void __stdcall GLee_Lazy_glMultiTexCoord4dv(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord4dv(target, v);} + GLEEPFNGLMULTITEXCOORD4DVPROC GLeeFuncPtr_glMultiTexCoord4dv=GLee_Lazy_glMultiTexCoord4dv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4f +#define GLEE_C_DEFINED_glMultiTexCoord4f + void __stdcall GLee_Lazy_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {if (GLeeInit()) glMultiTexCoord4f(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4FPROC GLeeFuncPtr_glMultiTexCoord4f=GLee_Lazy_glMultiTexCoord4f; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4fv +#define GLEE_C_DEFINED_glMultiTexCoord4fv + void __stdcall GLee_Lazy_glMultiTexCoord4fv(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord4fv(target, v);} + GLEEPFNGLMULTITEXCOORD4FVPROC GLeeFuncPtr_glMultiTexCoord4fv=GLee_Lazy_glMultiTexCoord4fv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4i +#define GLEE_C_DEFINED_glMultiTexCoord4i + void __stdcall GLee_Lazy_glMultiTexCoord4i(GLenum target, GLint s, GLint t, GLint r, GLint q) {if (GLeeInit()) glMultiTexCoord4i(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4IPROC GLeeFuncPtr_glMultiTexCoord4i=GLee_Lazy_glMultiTexCoord4i; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4iv +#define GLEE_C_DEFINED_glMultiTexCoord4iv + void __stdcall GLee_Lazy_glMultiTexCoord4iv(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord4iv(target, v);} + GLEEPFNGLMULTITEXCOORD4IVPROC GLeeFuncPtr_glMultiTexCoord4iv=GLee_Lazy_glMultiTexCoord4iv; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4s +#define GLEE_C_DEFINED_glMultiTexCoord4s + void __stdcall GLee_Lazy_glMultiTexCoord4s(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) {if (GLeeInit()) glMultiTexCoord4s(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4SPROC GLeeFuncPtr_glMultiTexCoord4s=GLee_Lazy_glMultiTexCoord4s; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4sv +#define GLEE_C_DEFINED_glMultiTexCoord4sv + void __stdcall GLee_Lazy_glMultiTexCoord4sv(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord4sv(target, v);} + GLEEPFNGLMULTITEXCOORD4SVPROC GLeeFuncPtr_glMultiTexCoord4sv=GLee_Lazy_glMultiTexCoord4sv; +#endif +#ifndef GLEE_C_DEFINED_glLoadTransposeMatrixf +#define GLEE_C_DEFINED_glLoadTransposeMatrixf + void __stdcall GLee_Lazy_glLoadTransposeMatrixf(const GLfloat * m) {if (GLeeInit()) glLoadTransposeMatrixf(m);} + GLEEPFNGLLOADTRANSPOSEMATRIXFPROC GLeeFuncPtr_glLoadTransposeMatrixf=GLee_Lazy_glLoadTransposeMatrixf; +#endif +#ifndef GLEE_C_DEFINED_glLoadTransposeMatrixd +#define GLEE_C_DEFINED_glLoadTransposeMatrixd + void __stdcall GLee_Lazy_glLoadTransposeMatrixd(const GLdouble * m) {if (GLeeInit()) glLoadTransposeMatrixd(m);} + GLEEPFNGLLOADTRANSPOSEMATRIXDPROC GLeeFuncPtr_glLoadTransposeMatrixd=GLee_Lazy_glLoadTransposeMatrixd; +#endif +#ifndef GLEE_C_DEFINED_glMultTransposeMatrixf +#define GLEE_C_DEFINED_glMultTransposeMatrixf + void __stdcall GLee_Lazy_glMultTransposeMatrixf(const GLfloat * m) {if (GLeeInit()) glMultTransposeMatrixf(m);} + GLEEPFNGLMULTTRANSPOSEMATRIXFPROC GLeeFuncPtr_glMultTransposeMatrixf=GLee_Lazy_glMultTransposeMatrixf; +#endif +#ifndef GLEE_C_DEFINED_glMultTransposeMatrixd +#define GLEE_C_DEFINED_glMultTransposeMatrixd + void __stdcall GLee_Lazy_glMultTransposeMatrixd(const GLdouble * m) {if (GLeeInit()) glMultTransposeMatrixd(m);} + GLEEPFNGLMULTTRANSPOSEMATRIXDPROC GLeeFuncPtr_glMultTransposeMatrixd=GLee_Lazy_glMultTransposeMatrixd; +#endif +#ifndef GLEE_C_DEFINED_glSampleCoverage +#define GLEE_C_DEFINED_glSampleCoverage + void __stdcall GLee_Lazy_glSampleCoverage(GLclampf value, GLboolean invert) {if (GLeeInit()) glSampleCoverage(value, invert);} + GLEEPFNGLSAMPLECOVERAGEPROC GLeeFuncPtr_glSampleCoverage=GLee_Lazy_glSampleCoverage; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexImage3D +#define GLEE_C_DEFINED_glCompressedTexImage3D + void __stdcall GLee_Lazy_glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXIMAGE3DPROC GLeeFuncPtr_glCompressedTexImage3D=GLee_Lazy_glCompressedTexImage3D; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexImage2D +#define GLEE_C_DEFINED_glCompressedTexImage2D + void __stdcall GLee_Lazy_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXIMAGE2DPROC GLeeFuncPtr_glCompressedTexImage2D=GLee_Lazy_glCompressedTexImage2D; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexImage1D +#define GLEE_C_DEFINED_glCompressedTexImage1D + void __stdcall GLee_Lazy_glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexImage1D(target, level, internalformat, width, border, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXIMAGE1DPROC GLeeFuncPtr_glCompressedTexImage1D=GLee_Lazy_glCompressedTexImage1D; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexSubImage3D +#define GLEE_C_DEFINED_glCompressedTexSubImage3D + void __stdcall GLee_Lazy_glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DPROC GLeeFuncPtr_glCompressedTexSubImage3D=GLee_Lazy_glCompressedTexSubImage3D; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexSubImage2D +#define GLEE_C_DEFINED_glCompressedTexSubImage2D + void __stdcall GLee_Lazy_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DPROC GLeeFuncPtr_glCompressedTexSubImage2D=GLee_Lazy_glCompressedTexSubImage2D; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexSubImage1D +#define GLEE_C_DEFINED_glCompressedTexSubImage1D + void __stdcall GLee_Lazy_glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DPROC GLeeFuncPtr_glCompressedTexSubImage1D=GLee_Lazy_glCompressedTexSubImage1D; +#endif +#ifndef GLEE_C_DEFINED_glGetCompressedTexImage +#define GLEE_C_DEFINED_glGetCompressedTexImage + void __stdcall GLee_Lazy_glGetCompressedTexImage(GLenum target, GLint level, GLvoid * img) {if (GLeeInit()) glGetCompressedTexImage(target, level, img);} + GLEEPFNGLGETCOMPRESSEDTEXIMAGEPROC GLeeFuncPtr_glGetCompressedTexImage=GLee_Lazy_glGetCompressedTexImage; +#endif +#endif + +/* GL_VERSION_1_4 */ + +#ifdef __GLEE_GL_VERSION_1_4 +#ifndef GLEE_C_DEFINED_glBlendFuncSeparate +#define GLEE_C_DEFINED_glBlendFuncSeparate + void __stdcall GLee_Lazy_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {if (GLeeInit()) glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);} + GLEEPFNGLBLENDFUNCSEPARATEPROC GLeeFuncPtr_glBlendFuncSeparate=GLee_Lazy_glBlendFuncSeparate; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordf +#define GLEE_C_DEFINED_glFogCoordf + void __stdcall GLee_Lazy_glFogCoordf(GLfloat coord) {if (GLeeInit()) glFogCoordf(coord);} + GLEEPFNGLFOGCOORDFPROC GLeeFuncPtr_glFogCoordf=GLee_Lazy_glFogCoordf; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordfv +#define GLEE_C_DEFINED_glFogCoordfv + void __stdcall GLee_Lazy_glFogCoordfv(const GLfloat * coord) {if (GLeeInit()) glFogCoordfv(coord);} + GLEEPFNGLFOGCOORDFVPROC GLeeFuncPtr_glFogCoordfv=GLee_Lazy_glFogCoordfv; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordd +#define GLEE_C_DEFINED_glFogCoordd + void __stdcall GLee_Lazy_glFogCoordd(GLdouble coord) {if (GLeeInit()) glFogCoordd(coord);} + GLEEPFNGLFOGCOORDDPROC GLeeFuncPtr_glFogCoordd=GLee_Lazy_glFogCoordd; +#endif +#ifndef GLEE_C_DEFINED_glFogCoorddv +#define GLEE_C_DEFINED_glFogCoorddv + void __stdcall GLee_Lazy_glFogCoorddv(const GLdouble * coord) {if (GLeeInit()) glFogCoorddv(coord);} + GLEEPFNGLFOGCOORDDVPROC GLeeFuncPtr_glFogCoorddv=GLee_Lazy_glFogCoorddv; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordPointer +#define GLEE_C_DEFINED_glFogCoordPointer + void __stdcall GLee_Lazy_glFogCoordPointer(GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glFogCoordPointer(type, stride, pointer);} + GLEEPFNGLFOGCOORDPOINTERPROC GLeeFuncPtr_glFogCoordPointer=GLee_Lazy_glFogCoordPointer; +#endif +#ifndef GLEE_C_DEFINED_glMultiDrawArrays +#define GLEE_C_DEFINED_glMultiDrawArrays + void __stdcall GLee_Lazy_glMultiDrawArrays(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount) {if (GLeeInit()) glMultiDrawArrays(mode, first, count, primcount);} + GLEEPFNGLMULTIDRAWARRAYSPROC GLeeFuncPtr_glMultiDrawArrays=GLee_Lazy_glMultiDrawArrays; +#endif +#ifndef GLEE_C_DEFINED_glMultiDrawElements +#define GLEE_C_DEFINED_glMultiDrawElements + void __stdcall GLee_Lazy_glMultiDrawElements(GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount) {if (GLeeInit()) glMultiDrawElements(mode, count, type, indices, primcount);} + GLEEPFNGLMULTIDRAWELEMENTSPROC GLeeFuncPtr_glMultiDrawElements=GLee_Lazy_glMultiDrawElements; +#endif +#ifndef GLEE_C_DEFINED_glPointParameterf +#define GLEE_C_DEFINED_glPointParameterf + void __stdcall GLee_Lazy_glPointParameterf(GLenum pname, GLfloat param) {if (GLeeInit()) glPointParameterf(pname, param);} + GLEEPFNGLPOINTPARAMETERFPROC GLeeFuncPtr_glPointParameterf=GLee_Lazy_glPointParameterf; +#endif +#ifndef GLEE_C_DEFINED_glPointParameterfv +#define GLEE_C_DEFINED_glPointParameterfv + void __stdcall GLee_Lazy_glPointParameterfv(GLenum pname, const GLfloat * params) {if (GLeeInit()) glPointParameterfv(pname, params);} + GLEEPFNGLPOINTPARAMETERFVPROC GLeeFuncPtr_glPointParameterfv=GLee_Lazy_glPointParameterfv; +#endif +#ifndef GLEE_C_DEFINED_glPointParameteri +#define GLEE_C_DEFINED_glPointParameteri + void __stdcall GLee_Lazy_glPointParameteri(GLenum pname, GLint param) {if (GLeeInit()) glPointParameteri(pname, param);} + GLEEPFNGLPOINTPARAMETERIPROC GLeeFuncPtr_glPointParameteri=GLee_Lazy_glPointParameteri; +#endif +#ifndef GLEE_C_DEFINED_glPointParameteriv +#define GLEE_C_DEFINED_glPointParameteriv + void __stdcall GLee_Lazy_glPointParameteriv(GLenum pname, const GLint * params) {if (GLeeInit()) glPointParameteriv(pname, params);} + GLEEPFNGLPOINTPARAMETERIVPROC GLeeFuncPtr_glPointParameteriv=GLee_Lazy_glPointParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3b +#define GLEE_C_DEFINED_glSecondaryColor3b + void __stdcall GLee_Lazy_glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {if (GLeeInit()) glSecondaryColor3b(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3BPROC GLeeFuncPtr_glSecondaryColor3b=GLee_Lazy_glSecondaryColor3b; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3bv +#define GLEE_C_DEFINED_glSecondaryColor3bv + void __stdcall GLee_Lazy_glSecondaryColor3bv(const GLbyte * v) {if (GLeeInit()) glSecondaryColor3bv(v);} + GLEEPFNGLSECONDARYCOLOR3BVPROC GLeeFuncPtr_glSecondaryColor3bv=GLee_Lazy_glSecondaryColor3bv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3d +#define GLEE_C_DEFINED_glSecondaryColor3d + void __stdcall GLee_Lazy_glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {if (GLeeInit()) glSecondaryColor3d(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3DPROC GLeeFuncPtr_glSecondaryColor3d=GLee_Lazy_glSecondaryColor3d; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3dv +#define GLEE_C_DEFINED_glSecondaryColor3dv + void __stdcall GLee_Lazy_glSecondaryColor3dv(const GLdouble * v) {if (GLeeInit()) glSecondaryColor3dv(v);} + GLEEPFNGLSECONDARYCOLOR3DVPROC GLeeFuncPtr_glSecondaryColor3dv=GLee_Lazy_glSecondaryColor3dv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3f +#define GLEE_C_DEFINED_glSecondaryColor3f + void __stdcall GLee_Lazy_glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {if (GLeeInit()) glSecondaryColor3f(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3FPROC GLeeFuncPtr_glSecondaryColor3f=GLee_Lazy_glSecondaryColor3f; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3fv +#define GLEE_C_DEFINED_glSecondaryColor3fv + void __stdcall GLee_Lazy_glSecondaryColor3fv(const GLfloat * v) {if (GLeeInit()) glSecondaryColor3fv(v);} + GLEEPFNGLSECONDARYCOLOR3FVPROC GLeeFuncPtr_glSecondaryColor3fv=GLee_Lazy_glSecondaryColor3fv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3i +#define GLEE_C_DEFINED_glSecondaryColor3i + void __stdcall GLee_Lazy_glSecondaryColor3i(GLint red, GLint green, GLint blue) {if (GLeeInit()) glSecondaryColor3i(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3IPROC GLeeFuncPtr_glSecondaryColor3i=GLee_Lazy_glSecondaryColor3i; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3iv +#define GLEE_C_DEFINED_glSecondaryColor3iv + void __stdcall GLee_Lazy_glSecondaryColor3iv(const GLint * v) {if (GLeeInit()) glSecondaryColor3iv(v);} + GLEEPFNGLSECONDARYCOLOR3IVPROC GLeeFuncPtr_glSecondaryColor3iv=GLee_Lazy_glSecondaryColor3iv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3s +#define GLEE_C_DEFINED_glSecondaryColor3s + void __stdcall GLee_Lazy_glSecondaryColor3s(GLshort red, GLshort green, GLshort blue) {if (GLeeInit()) glSecondaryColor3s(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3SPROC GLeeFuncPtr_glSecondaryColor3s=GLee_Lazy_glSecondaryColor3s; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3sv +#define GLEE_C_DEFINED_glSecondaryColor3sv + void __stdcall GLee_Lazy_glSecondaryColor3sv(const GLshort * v) {if (GLeeInit()) glSecondaryColor3sv(v);} + GLEEPFNGLSECONDARYCOLOR3SVPROC GLeeFuncPtr_glSecondaryColor3sv=GLee_Lazy_glSecondaryColor3sv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3ub +#define GLEE_C_DEFINED_glSecondaryColor3ub + void __stdcall GLee_Lazy_glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {if (GLeeInit()) glSecondaryColor3ub(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3UBPROC GLeeFuncPtr_glSecondaryColor3ub=GLee_Lazy_glSecondaryColor3ub; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3ubv +#define GLEE_C_DEFINED_glSecondaryColor3ubv + void __stdcall GLee_Lazy_glSecondaryColor3ubv(const GLubyte * v) {if (GLeeInit()) glSecondaryColor3ubv(v);} + GLEEPFNGLSECONDARYCOLOR3UBVPROC GLeeFuncPtr_glSecondaryColor3ubv=GLee_Lazy_glSecondaryColor3ubv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3ui +#define GLEE_C_DEFINED_glSecondaryColor3ui + void __stdcall GLee_Lazy_glSecondaryColor3ui(GLuint red, GLuint green, GLuint blue) {if (GLeeInit()) glSecondaryColor3ui(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3UIPROC GLeeFuncPtr_glSecondaryColor3ui=GLee_Lazy_glSecondaryColor3ui; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3uiv +#define GLEE_C_DEFINED_glSecondaryColor3uiv + void __stdcall GLee_Lazy_glSecondaryColor3uiv(const GLuint * v) {if (GLeeInit()) glSecondaryColor3uiv(v);} + GLEEPFNGLSECONDARYCOLOR3UIVPROC GLeeFuncPtr_glSecondaryColor3uiv=GLee_Lazy_glSecondaryColor3uiv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3us +#define GLEE_C_DEFINED_glSecondaryColor3us + void __stdcall GLee_Lazy_glSecondaryColor3us(GLushort red, GLushort green, GLushort blue) {if (GLeeInit()) glSecondaryColor3us(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3USPROC GLeeFuncPtr_glSecondaryColor3us=GLee_Lazy_glSecondaryColor3us; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3usv +#define GLEE_C_DEFINED_glSecondaryColor3usv + void __stdcall GLee_Lazy_glSecondaryColor3usv(const GLushort * v) {if (GLeeInit()) glSecondaryColor3usv(v);} + GLEEPFNGLSECONDARYCOLOR3USVPROC GLeeFuncPtr_glSecondaryColor3usv=GLee_Lazy_glSecondaryColor3usv; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColorPointer +#define GLEE_C_DEFINED_glSecondaryColorPointer + void __stdcall GLee_Lazy_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glSecondaryColorPointer(size, type, stride, pointer);} + GLEEPFNGLSECONDARYCOLORPOINTERPROC GLeeFuncPtr_glSecondaryColorPointer=GLee_Lazy_glSecondaryColorPointer; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2d +#define GLEE_C_DEFINED_glWindowPos2d + void __stdcall GLee_Lazy_glWindowPos2d(GLdouble x, GLdouble y) {if (GLeeInit()) glWindowPos2d(x, y);} + GLEEPFNGLWINDOWPOS2DPROC GLeeFuncPtr_glWindowPos2d=GLee_Lazy_glWindowPos2d; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2dv +#define GLEE_C_DEFINED_glWindowPos2dv + void __stdcall GLee_Lazy_glWindowPos2dv(const GLdouble * v) {if (GLeeInit()) glWindowPos2dv(v);} + GLEEPFNGLWINDOWPOS2DVPROC GLeeFuncPtr_glWindowPos2dv=GLee_Lazy_glWindowPos2dv; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2f +#define GLEE_C_DEFINED_glWindowPos2f + void __stdcall GLee_Lazy_glWindowPos2f(GLfloat x, GLfloat y) {if (GLeeInit()) glWindowPos2f(x, y);} + GLEEPFNGLWINDOWPOS2FPROC GLeeFuncPtr_glWindowPos2f=GLee_Lazy_glWindowPos2f; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2fv +#define GLEE_C_DEFINED_glWindowPos2fv + void __stdcall GLee_Lazy_glWindowPos2fv(const GLfloat * v) {if (GLeeInit()) glWindowPos2fv(v);} + GLEEPFNGLWINDOWPOS2FVPROC GLeeFuncPtr_glWindowPos2fv=GLee_Lazy_glWindowPos2fv; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2i +#define GLEE_C_DEFINED_glWindowPos2i + void __stdcall GLee_Lazy_glWindowPos2i(GLint x, GLint y) {if (GLeeInit()) glWindowPos2i(x, y);} + GLEEPFNGLWINDOWPOS2IPROC GLeeFuncPtr_glWindowPos2i=GLee_Lazy_glWindowPos2i; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2iv +#define GLEE_C_DEFINED_glWindowPos2iv + void __stdcall GLee_Lazy_glWindowPos2iv(const GLint * v) {if (GLeeInit()) glWindowPos2iv(v);} + GLEEPFNGLWINDOWPOS2IVPROC GLeeFuncPtr_glWindowPos2iv=GLee_Lazy_glWindowPos2iv; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2s +#define GLEE_C_DEFINED_glWindowPos2s + void __stdcall GLee_Lazy_glWindowPos2s(GLshort x, GLshort y) {if (GLeeInit()) glWindowPos2s(x, y);} + GLEEPFNGLWINDOWPOS2SPROC GLeeFuncPtr_glWindowPos2s=GLee_Lazy_glWindowPos2s; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2sv +#define GLEE_C_DEFINED_glWindowPos2sv + void __stdcall GLee_Lazy_glWindowPos2sv(const GLshort * v) {if (GLeeInit()) glWindowPos2sv(v);} + GLEEPFNGLWINDOWPOS2SVPROC GLeeFuncPtr_glWindowPos2sv=GLee_Lazy_glWindowPos2sv; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3d +#define GLEE_C_DEFINED_glWindowPos3d + void __stdcall GLee_Lazy_glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glWindowPos3d(x, y, z);} + GLEEPFNGLWINDOWPOS3DPROC GLeeFuncPtr_glWindowPos3d=GLee_Lazy_glWindowPos3d; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3dv +#define GLEE_C_DEFINED_glWindowPos3dv + void __stdcall GLee_Lazy_glWindowPos3dv(const GLdouble * v) {if (GLeeInit()) glWindowPos3dv(v);} + GLEEPFNGLWINDOWPOS3DVPROC GLeeFuncPtr_glWindowPos3dv=GLee_Lazy_glWindowPos3dv; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3f +#define GLEE_C_DEFINED_glWindowPos3f + void __stdcall GLee_Lazy_glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glWindowPos3f(x, y, z);} + GLEEPFNGLWINDOWPOS3FPROC GLeeFuncPtr_glWindowPos3f=GLee_Lazy_glWindowPos3f; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3fv +#define GLEE_C_DEFINED_glWindowPos3fv + void __stdcall GLee_Lazy_glWindowPos3fv(const GLfloat * v) {if (GLeeInit()) glWindowPos3fv(v);} + GLEEPFNGLWINDOWPOS3FVPROC GLeeFuncPtr_glWindowPos3fv=GLee_Lazy_glWindowPos3fv; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3i +#define GLEE_C_DEFINED_glWindowPos3i + void __stdcall GLee_Lazy_glWindowPos3i(GLint x, GLint y, GLint z) {if (GLeeInit()) glWindowPos3i(x, y, z);} + GLEEPFNGLWINDOWPOS3IPROC GLeeFuncPtr_glWindowPos3i=GLee_Lazy_glWindowPos3i; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3iv +#define GLEE_C_DEFINED_glWindowPos3iv + void __stdcall GLee_Lazy_glWindowPos3iv(const GLint * v) {if (GLeeInit()) glWindowPos3iv(v);} + GLEEPFNGLWINDOWPOS3IVPROC GLeeFuncPtr_glWindowPos3iv=GLee_Lazy_glWindowPos3iv; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3s +#define GLEE_C_DEFINED_glWindowPos3s + void __stdcall GLee_Lazy_glWindowPos3s(GLshort x, GLshort y, GLshort z) {if (GLeeInit()) glWindowPos3s(x, y, z);} + GLEEPFNGLWINDOWPOS3SPROC GLeeFuncPtr_glWindowPos3s=GLee_Lazy_glWindowPos3s; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3sv +#define GLEE_C_DEFINED_glWindowPos3sv + void __stdcall GLee_Lazy_glWindowPos3sv(const GLshort * v) {if (GLeeInit()) glWindowPos3sv(v);} + GLEEPFNGLWINDOWPOS3SVPROC GLeeFuncPtr_glWindowPos3sv=GLee_Lazy_glWindowPos3sv; +#endif +#endif + +/* GL_VERSION_1_5 */ + +#ifdef __GLEE_GL_VERSION_1_5 +#ifndef GLEE_C_DEFINED_glGenQueries +#define GLEE_C_DEFINED_glGenQueries + void __stdcall GLee_Lazy_glGenQueries(GLsizei n, GLuint * ids) {if (GLeeInit()) glGenQueries(n, ids);} + GLEEPFNGLGENQUERIESPROC GLeeFuncPtr_glGenQueries=GLee_Lazy_glGenQueries; +#endif +#ifndef GLEE_C_DEFINED_glDeleteQueries +#define GLEE_C_DEFINED_glDeleteQueries + void __stdcall GLee_Lazy_glDeleteQueries(GLsizei n, const GLuint * ids) {if (GLeeInit()) glDeleteQueries(n, ids);} + GLEEPFNGLDELETEQUERIESPROC GLeeFuncPtr_glDeleteQueries=GLee_Lazy_glDeleteQueries; +#endif +#ifndef GLEE_C_DEFINED_glIsQuery +#define GLEE_C_DEFINED_glIsQuery + GLboolean __stdcall GLee_Lazy_glIsQuery(GLuint id) {if (GLeeInit()) return glIsQuery(id); return (GLboolean)0;} + GLEEPFNGLISQUERYPROC GLeeFuncPtr_glIsQuery=GLee_Lazy_glIsQuery; +#endif +#ifndef GLEE_C_DEFINED_glBeginQuery +#define GLEE_C_DEFINED_glBeginQuery + void __stdcall GLee_Lazy_glBeginQuery(GLenum target, GLuint id) {if (GLeeInit()) glBeginQuery(target, id);} + GLEEPFNGLBEGINQUERYPROC GLeeFuncPtr_glBeginQuery=GLee_Lazy_glBeginQuery; +#endif +#ifndef GLEE_C_DEFINED_glEndQuery +#define GLEE_C_DEFINED_glEndQuery + void __stdcall GLee_Lazy_glEndQuery(GLenum target) {if (GLeeInit()) glEndQuery(target);} + GLEEPFNGLENDQUERYPROC GLeeFuncPtr_glEndQuery=GLee_Lazy_glEndQuery; +#endif +#ifndef GLEE_C_DEFINED_glGetQueryiv +#define GLEE_C_DEFINED_glGetQueryiv + void __stdcall GLee_Lazy_glGetQueryiv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetQueryiv(target, pname, params);} + GLEEPFNGLGETQUERYIVPROC GLeeFuncPtr_glGetQueryiv=GLee_Lazy_glGetQueryiv; +#endif +#ifndef GLEE_C_DEFINED_glGetQueryObjectiv +#define GLEE_C_DEFINED_glGetQueryObjectiv + void __stdcall GLee_Lazy_glGetQueryObjectiv(GLuint id, GLenum pname, GLint * params) {if (GLeeInit()) glGetQueryObjectiv(id, pname, params);} + GLEEPFNGLGETQUERYOBJECTIVPROC GLeeFuncPtr_glGetQueryObjectiv=GLee_Lazy_glGetQueryObjectiv; +#endif +#ifndef GLEE_C_DEFINED_glGetQueryObjectuiv +#define GLEE_C_DEFINED_glGetQueryObjectuiv + void __stdcall GLee_Lazy_glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint * params) {if (GLeeInit()) glGetQueryObjectuiv(id, pname, params);} + GLEEPFNGLGETQUERYOBJECTUIVPROC GLeeFuncPtr_glGetQueryObjectuiv=GLee_Lazy_glGetQueryObjectuiv; +#endif +#ifndef GLEE_C_DEFINED_glBindBuffer +#define GLEE_C_DEFINED_glBindBuffer + void __stdcall GLee_Lazy_glBindBuffer(GLenum target, GLuint buffer) {if (GLeeInit()) glBindBuffer(target, buffer);} + GLEEPFNGLBINDBUFFERPROC GLeeFuncPtr_glBindBuffer=GLee_Lazy_glBindBuffer; +#endif +#ifndef GLEE_C_DEFINED_glDeleteBuffers +#define GLEE_C_DEFINED_glDeleteBuffers + void __stdcall GLee_Lazy_glDeleteBuffers(GLsizei n, const GLuint * buffers) {if (GLeeInit()) glDeleteBuffers(n, buffers);} + GLEEPFNGLDELETEBUFFERSPROC GLeeFuncPtr_glDeleteBuffers=GLee_Lazy_glDeleteBuffers; +#endif +#ifndef GLEE_C_DEFINED_glGenBuffers +#define GLEE_C_DEFINED_glGenBuffers + void __stdcall GLee_Lazy_glGenBuffers(GLsizei n, GLuint * buffers) {if (GLeeInit()) glGenBuffers(n, buffers);} + GLEEPFNGLGENBUFFERSPROC GLeeFuncPtr_glGenBuffers=GLee_Lazy_glGenBuffers; +#endif +#ifndef GLEE_C_DEFINED_glIsBuffer +#define GLEE_C_DEFINED_glIsBuffer + GLboolean __stdcall GLee_Lazy_glIsBuffer(GLuint buffer) {if (GLeeInit()) return glIsBuffer(buffer); return (GLboolean)0;} + GLEEPFNGLISBUFFERPROC GLeeFuncPtr_glIsBuffer=GLee_Lazy_glIsBuffer; +#endif +#ifndef GLEE_C_DEFINED_glBufferData +#define GLEE_C_DEFINED_glBufferData + void __stdcall GLee_Lazy_glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {if (GLeeInit()) glBufferData(target, size, data, usage);} + GLEEPFNGLBUFFERDATAPROC GLeeFuncPtr_glBufferData=GLee_Lazy_glBufferData; +#endif +#ifndef GLEE_C_DEFINED_glBufferSubData +#define GLEE_C_DEFINED_glBufferSubData + void __stdcall GLee_Lazy_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {if (GLeeInit()) glBufferSubData(target, offset, size, data);} + GLEEPFNGLBUFFERSUBDATAPROC GLeeFuncPtr_glBufferSubData=GLee_Lazy_glBufferSubData; +#endif +#ifndef GLEE_C_DEFINED_glGetBufferSubData +#define GLEE_C_DEFINED_glGetBufferSubData + void __stdcall GLee_Lazy_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data) {if (GLeeInit()) glGetBufferSubData(target, offset, size, data);} + GLEEPFNGLGETBUFFERSUBDATAPROC GLeeFuncPtr_glGetBufferSubData=GLee_Lazy_glGetBufferSubData; +#endif +#ifndef GLEE_C_DEFINED_glMapBuffer +#define GLEE_C_DEFINED_glMapBuffer + GLvoid* __stdcall GLee_Lazy_glMapBuffer(GLenum target, GLenum access) {if (GLeeInit()) return glMapBuffer(target, access); return (GLvoid*)0;} + GLEEPFNGLMAPBUFFERPROC GLeeFuncPtr_glMapBuffer=GLee_Lazy_glMapBuffer; +#endif +#ifndef GLEE_C_DEFINED_glUnmapBuffer +#define GLEE_C_DEFINED_glUnmapBuffer + GLboolean __stdcall GLee_Lazy_glUnmapBuffer(GLenum target) {if (GLeeInit()) return glUnmapBuffer(target); return (GLboolean)0;} + GLEEPFNGLUNMAPBUFFERPROC GLeeFuncPtr_glUnmapBuffer=GLee_Lazy_glUnmapBuffer; +#endif +#ifndef GLEE_C_DEFINED_glGetBufferParameteriv +#define GLEE_C_DEFINED_glGetBufferParameteriv + void __stdcall GLee_Lazy_glGetBufferParameteriv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetBufferParameteriv(target, pname, params);} + GLEEPFNGLGETBUFFERPARAMETERIVPROC GLeeFuncPtr_glGetBufferParameteriv=GLee_Lazy_glGetBufferParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glGetBufferPointerv +#define GLEE_C_DEFINED_glGetBufferPointerv + void __stdcall GLee_Lazy_glGetBufferPointerv(GLenum target, GLenum pname, GLvoid* * params) {if (GLeeInit()) glGetBufferPointerv(target, pname, params);} + GLEEPFNGLGETBUFFERPOINTERVPROC GLeeFuncPtr_glGetBufferPointerv=GLee_Lazy_glGetBufferPointerv; +#endif +#endif + +/* GL_VERSION_2_0 */ + +#ifdef __GLEE_GL_VERSION_2_0 +#ifndef GLEE_C_DEFINED_glBlendEquationSeparate +#define GLEE_C_DEFINED_glBlendEquationSeparate + void __stdcall GLee_Lazy_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {if (GLeeInit()) glBlendEquationSeparate(modeRGB, modeAlpha);} + GLEEPFNGLBLENDEQUATIONSEPARATEPROC GLeeFuncPtr_glBlendEquationSeparate=GLee_Lazy_glBlendEquationSeparate; +#endif +#ifndef GLEE_C_DEFINED_glDrawBuffers +#define GLEE_C_DEFINED_glDrawBuffers + void __stdcall GLee_Lazy_glDrawBuffers(GLsizei n, const GLenum * bufs) {if (GLeeInit()) glDrawBuffers(n, bufs);} + GLEEPFNGLDRAWBUFFERSPROC GLeeFuncPtr_glDrawBuffers=GLee_Lazy_glDrawBuffers; +#endif +#ifndef GLEE_C_DEFINED_glStencilOpSeparate +#define GLEE_C_DEFINED_glStencilOpSeparate + void __stdcall GLee_Lazy_glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {if (GLeeInit()) glStencilOpSeparate(face, sfail, dpfail, dppass);} + GLEEPFNGLSTENCILOPSEPARATEPROC GLeeFuncPtr_glStencilOpSeparate=GLee_Lazy_glStencilOpSeparate; +#endif +#ifndef GLEE_C_DEFINED_glStencilFuncSeparate +#define GLEE_C_DEFINED_glStencilFuncSeparate + void __stdcall GLee_Lazy_glStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) {if (GLeeInit()) glStencilFuncSeparate(frontfunc, backfunc, ref, mask);} + GLEEPFNGLSTENCILFUNCSEPARATEPROC GLeeFuncPtr_glStencilFuncSeparate=GLee_Lazy_glStencilFuncSeparate; +#endif +#ifndef GLEE_C_DEFINED_glStencilMaskSeparate +#define GLEE_C_DEFINED_glStencilMaskSeparate + void __stdcall GLee_Lazy_glStencilMaskSeparate(GLenum face, GLuint mask) {if (GLeeInit()) glStencilMaskSeparate(face, mask);} + GLEEPFNGLSTENCILMASKSEPARATEPROC GLeeFuncPtr_glStencilMaskSeparate=GLee_Lazy_glStencilMaskSeparate; +#endif +#ifndef GLEE_C_DEFINED_glAttachShader +#define GLEE_C_DEFINED_glAttachShader + void __stdcall GLee_Lazy_glAttachShader(GLuint program, GLuint shader) {if (GLeeInit()) glAttachShader(program, shader);} + GLEEPFNGLATTACHSHADERPROC GLeeFuncPtr_glAttachShader=GLee_Lazy_glAttachShader; +#endif +#ifndef GLEE_C_DEFINED_glBindAttribLocation +#define GLEE_C_DEFINED_glBindAttribLocation + void __stdcall GLee_Lazy_glBindAttribLocation(GLuint program, GLuint index, const GLchar * name) {if (GLeeInit()) glBindAttribLocation(program, index, name);} + GLEEPFNGLBINDATTRIBLOCATIONPROC GLeeFuncPtr_glBindAttribLocation=GLee_Lazy_glBindAttribLocation; +#endif +#ifndef GLEE_C_DEFINED_glCompileShader +#define GLEE_C_DEFINED_glCompileShader + void __stdcall GLee_Lazy_glCompileShader(GLuint shader) {if (GLeeInit()) glCompileShader(shader);} + GLEEPFNGLCOMPILESHADERPROC GLeeFuncPtr_glCompileShader=GLee_Lazy_glCompileShader; +#endif +#ifndef GLEE_C_DEFINED_glCreateProgram +#define GLEE_C_DEFINED_glCreateProgram + GLuint __stdcall GLee_Lazy_glCreateProgram(void) {if (GLeeInit()) return glCreateProgram(); return (GLuint)0;} + GLEEPFNGLCREATEPROGRAMPROC GLeeFuncPtr_glCreateProgram=GLee_Lazy_glCreateProgram; +#endif +#ifndef GLEE_C_DEFINED_glCreateShader +#define GLEE_C_DEFINED_glCreateShader + GLuint __stdcall GLee_Lazy_glCreateShader(GLenum type) {if (GLeeInit()) return glCreateShader(type); return (GLuint)0;} + GLEEPFNGLCREATESHADERPROC GLeeFuncPtr_glCreateShader=GLee_Lazy_glCreateShader; +#endif +#ifndef GLEE_C_DEFINED_glDeleteProgram +#define GLEE_C_DEFINED_glDeleteProgram + void __stdcall GLee_Lazy_glDeleteProgram(GLuint program) {if (GLeeInit()) glDeleteProgram(program);} + GLEEPFNGLDELETEPROGRAMPROC GLeeFuncPtr_glDeleteProgram=GLee_Lazy_glDeleteProgram; +#endif +#ifndef GLEE_C_DEFINED_glDeleteShader +#define GLEE_C_DEFINED_glDeleteShader + void __stdcall GLee_Lazy_glDeleteShader(GLuint shader) {if (GLeeInit()) glDeleteShader(shader);} + GLEEPFNGLDELETESHADERPROC GLeeFuncPtr_glDeleteShader=GLee_Lazy_glDeleteShader; +#endif +#ifndef GLEE_C_DEFINED_glDetachShader +#define GLEE_C_DEFINED_glDetachShader + void __stdcall GLee_Lazy_glDetachShader(GLuint program, GLuint shader) {if (GLeeInit()) glDetachShader(program, shader);} + GLEEPFNGLDETACHSHADERPROC GLeeFuncPtr_glDetachShader=GLee_Lazy_glDetachShader; +#endif +#ifndef GLEE_C_DEFINED_glDisableVertexAttribArray +#define GLEE_C_DEFINED_glDisableVertexAttribArray + void __stdcall GLee_Lazy_glDisableVertexAttribArray(GLuint index) {if (GLeeInit()) glDisableVertexAttribArray(index);} + GLEEPFNGLDISABLEVERTEXATTRIBARRAYPROC GLeeFuncPtr_glDisableVertexAttribArray=GLee_Lazy_glDisableVertexAttribArray; +#endif +#ifndef GLEE_C_DEFINED_glEnableVertexAttribArray +#define GLEE_C_DEFINED_glEnableVertexAttribArray + void __stdcall GLee_Lazy_glEnableVertexAttribArray(GLuint index) {if (GLeeInit()) glEnableVertexAttribArray(index);} + GLEEPFNGLENABLEVERTEXATTRIBARRAYPROC GLeeFuncPtr_glEnableVertexAttribArray=GLee_Lazy_glEnableVertexAttribArray; +#endif +#ifndef GLEE_C_DEFINED_glGetActiveAttrib +#define GLEE_C_DEFINED_glGetActiveAttrib + void __stdcall GLee_Lazy_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name) {if (GLeeInit()) glGetActiveAttrib(program, index, bufSize, length, size, type, name);} + GLEEPFNGLGETACTIVEATTRIBPROC GLeeFuncPtr_glGetActiveAttrib=GLee_Lazy_glGetActiveAttrib; +#endif +#ifndef GLEE_C_DEFINED_glGetActiveUniform +#define GLEE_C_DEFINED_glGetActiveUniform + void __stdcall GLee_Lazy_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name) {if (GLeeInit()) glGetActiveUniform(program, index, bufSize, length, size, type, name);} + GLEEPFNGLGETACTIVEUNIFORMPROC GLeeFuncPtr_glGetActiveUniform=GLee_Lazy_glGetActiveUniform; +#endif +#ifndef GLEE_C_DEFINED_glGetAttachedShaders +#define GLEE_C_DEFINED_glGetAttachedShaders + void __stdcall GLee_Lazy_glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * obj) {if (GLeeInit()) glGetAttachedShaders(program, maxCount, count, obj);} + GLEEPFNGLGETATTACHEDSHADERSPROC GLeeFuncPtr_glGetAttachedShaders=GLee_Lazy_glGetAttachedShaders; +#endif +#ifndef GLEE_C_DEFINED_glGetAttribLocation +#define GLEE_C_DEFINED_glGetAttribLocation + GLint __stdcall GLee_Lazy_glGetAttribLocation(GLuint program, const GLchar * name) {if (GLeeInit()) return glGetAttribLocation(program, name); return (GLint)0;} + GLEEPFNGLGETATTRIBLOCATIONPROC GLeeFuncPtr_glGetAttribLocation=GLee_Lazy_glGetAttribLocation; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramiv +#define GLEE_C_DEFINED_glGetProgramiv + void __stdcall GLee_Lazy_glGetProgramiv(GLuint program, GLenum pname, GLint * params) {if (GLeeInit()) glGetProgramiv(program, pname, params);} + GLEEPFNGLGETPROGRAMIVPROC GLeeFuncPtr_glGetProgramiv=GLee_Lazy_glGetProgramiv; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramInfoLog +#define GLEE_C_DEFINED_glGetProgramInfoLog + void __stdcall GLee_Lazy_glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog) {if (GLeeInit()) glGetProgramInfoLog(program, bufSize, length, infoLog);} + GLEEPFNGLGETPROGRAMINFOLOGPROC GLeeFuncPtr_glGetProgramInfoLog=GLee_Lazy_glGetProgramInfoLog; +#endif +#ifndef GLEE_C_DEFINED_glGetShaderiv +#define GLEE_C_DEFINED_glGetShaderiv + void __stdcall GLee_Lazy_glGetShaderiv(GLuint shader, GLenum pname, GLint * params) {if (GLeeInit()) glGetShaderiv(shader, pname, params);} + GLEEPFNGLGETSHADERIVPROC GLeeFuncPtr_glGetShaderiv=GLee_Lazy_glGetShaderiv; +#endif +#ifndef GLEE_C_DEFINED_glGetShaderInfoLog +#define GLEE_C_DEFINED_glGetShaderInfoLog + void __stdcall GLee_Lazy_glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog) {if (GLeeInit()) glGetShaderInfoLog(shader, bufSize, length, infoLog);} + GLEEPFNGLGETSHADERINFOLOGPROC GLeeFuncPtr_glGetShaderInfoLog=GLee_Lazy_glGetShaderInfoLog; +#endif +#ifndef GLEE_C_DEFINED_glGetShaderSource +#define GLEE_C_DEFINED_glGetShaderSource + void __stdcall GLee_Lazy_glGetShaderSource(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source) {if (GLeeInit()) glGetShaderSource(shader, bufSize, length, source);} + GLEEPFNGLGETSHADERSOURCEPROC GLeeFuncPtr_glGetShaderSource=GLee_Lazy_glGetShaderSource; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformLocation +#define GLEE_C_DEFINED_glGetUniformLocation + GLint __stdcall GLee_Lazy_glGetUniformLocation(GLuint program, const GLchar * name) {if (GLeeInit()) return glGetUniformLocation(program, name); return (GLint)0;} + GLEEPFNGLGETUNIFORMLOCATIONPROC GLeeFuncPtr_glGetUniformLocation=GLee_Lazy_glGetUniformLocation; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformfv +#define GLEE_C_DEFINED_glGetUniformfv + void __stdcall GLee_Lazy_glGetUniformfv(GLuint program, GLint location, GLfloat * params) {if (GLeeInit()) glGetUniformfv(program, location, params);} + GLEEPFNGLGETUNIFORMFVPROC GLeeFuncPtr_glGetUniformfv=GLee_Lazy_glGetUniformfv; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformiv +#define GLEE_C_DEFINED_glGetUniformiv + void __stdcall GLee_Lazy_glGetUniformiv(GLuint program, GLint location, GLint * params) {if (GLeeInit()) glGetUniformiv(program, location, params);} + GLEEPFNGLGETUNIFORMIVPROC GLeeFuncPtr_glGetUniformiv=GLee_Lazy_glGetUniformiv; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribdv +#define GLEE_C_DEFINED_glGetVertexAttribdv + void __stdcall GLee_Lazy_glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble * params) {if (GLeeInit()) glGetVertexAttribdv(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBDVPROC GLeeFuncPtr_glGetVertexAttribdv=GLee_Lazy_glGetVertexAttribdv; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribfv +#define GLEE_C_DEFINED_glGetVertexAttribfv + void __stdcall GLee_Lazy_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetVertexAttribfv(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBFVPROC GLeeFuncPtr_glGetVertexAttribfv=GLee_Lazy_glGetVertexAttribfv; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribiv +#define GLEE_C_DEFINED_glGetVertexAttribiv + void __stdcall GLee_Lazy_glGetVertexAttribiv(GLuint index, GLenum pname, GLint * params) {if (GLeeInit()) glGetVertexAttribiv(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBIVPROC GLeeFuncPtr_glGetVertexAttribiv=GLee_Lazy_glGetVertexAttribiv; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribPointerv +#define GLEE_C_DEFINED_glGetVertexAttribPointerv + void __stdcall GLee_Lazy_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid* * pointer) {if (GLeeInit()) glGetVertexAttribPointerv(index, pname, pointer);} + GLEEPFNGLGETVERTEXATTRIBPOINTERVPROC GLeeFuncPtr_glGetVertexAttribPointerv=GLee_Lazy_glGetVertexAttribPointerv; +#endif +#ifndef GLEE_C_DEFINED_glIsProgram +#define GLEE_C_DEFINED_glIsProgram + GLboolean __stdcall GLee_Lazy_glIsProgram(GLuint program) {if (GLeeInit()) return glIsProgram(program); return (GLboolean)0;} + GLEEPFNGLISPROGRAMPROC GLeeFuncPtr_glIsProgram=GLee_Lazy_glIsProgram; +#endif +#ifndef GLEE_C_DEFINED_glIsShader +#define GLEE_C_DEFINED_glIsShader + GLboolean __stdcall GLee_Lazy_glIsShader(GLuint shader) {if (GLeeInit()) return glIsShader(shader); return (GLboolean)0;} + GLEEPFNGLISSHADERPROC GLeeFuncPtr_glIsShader=GLee_Lazy_glIsShader; +#endif +#ifndef GLEE_C_DEFINED_glLinkProgram +#define GLEE_C_DEFINED_glLinkProgram + void __stdcall GLee_Lazy_glLinkProgram(GLuint program) {if (GLeeInit()) glLinkProgram(program);} + GLEEPFNGLLINKPROGRAMPROC GLeeFuncPtr_glLinkProgram=GLee_Lazy_glLinkProgram; +#endif +#ifndef GLEE_C_DEFINED_glShaderSource +#define GLEE_C_DEFINED_glShaderSource + void __stdcall GLee_Lazy_glShaderSource(GLuint shader, GLsizei count, const GLchar* * string, const GLint * length) {if (GLeeInit()) glShaderSource(shader, count, string, length);} + GLEEPFNGLSHADERSOURCEPROC GLeeFuncPtr_glShaderSource=GLee_Lazy_glShaderSource; +#endif +#ifndef GLEE_C_DEFINED_glUseProgram +#define GLEE_C_DEFINED_glUseProgram + void __stdcall GLee_Lazy_glUseProgram(GLuint program) {if (GLeeInit()) glUseProgram(program);} + GLEEPFNGLUSEPROGRAMPROC GLeeFuncPtr_glUseProgram=GLee_Lazy_glUseProgram; +#endif +#ifndef GLEE_C_DEFINED_glUniform1f +#define GLEE_C_DEFINED_glUniform1f + void __stdcall GLee_Lazy_glUniform1f(GLint location, GLfloat v0) {if (GLeeInit()) glUniform1f(location, v0);} + GLEEPFNGLUNIFORM1FPROC GLeeFuncPtr_glUniform1f=GLee_Lazy_glUniform1f; +#endif +#ifndef GLEE_C_DEFINED_glUniform2f +#define GLEE_C_DEFINED_glUniform2f + void __stdcall GLee_Lazy_glUniform2f(GLint location, GLfloat v0, GLfloat v1) {if (GLeeInit()) glUniform2f(location, v0, v1);} + GLEEPFNGLUNIFORM2FPROC GLeeFuncPtr_glUniform2f=GLee_Lazy_glUniform2f; +#endif +#ifndef GLEE_C_DEFINED_glUniform3f +#define GLEE_C_DEFINED_glUniform3f + void __stdcall GLee_Lazy_glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {if (GLeeInit()) glUniform3f(location, v0, v1, v2);} + GLEEPFNGLUNIFORM3FPROC GLeeFuncPtr_glUniform3f=GLee_Lazy_glUniform3f; +#endif +#ifndef GLEE_C_DEFINED_glUniform4f +#define GLEE_C_DEFINED_glUniform4f + void __stdcall GLee_Lazy_glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {if (GLeeInit()) glUniform4f(location, v0, v1, v2, v3);} + GLEEPFNGLUNIFORM4FPROC GLeeFuncPtr_glUniform4f=GLee_Lazy_glUniform4f; +#endif +#ifndef GLEE_C_DEFINED_glUniform1i +#define GLEE_C_DEFINED_glUniform1i + void __stdcall GLee_Lazy_glUniform1i(GLint location, GLint v0) {if (GLeeInit()) glUniform1i(location, v0);} + GLEEPFNGLUNIFORM1IPROC GLeeFuncPtr_glUniform1i=GLee_Lazy_glUniform1i; +#endif +#ifndef GLEE_C_DEFINED_glUniform2i +#define GLEE_C_DEFINED_glUniform2i + void __stdcall GLee_Lazy_glUniform2i(GLint location, GLint v0, GLint v1) {if (GLeeInit()) glUniform2i(location, v0, v1);} + GLEEPFNGLUNIFORM2IPROC GLeeFuncPtr_glUniform2i=GLee_Lazy_glUniform2i; +#endif +#ifndef GLEE_C_DEFINED_glUniform3i +#define GLEE_C_DEFINED_glUniform3i + void __stdcall GLee_Lazy_glUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {if (GLeeInit()) glUniform3i(location, v0, v1, v2);} + GLEEPFNGLUNIFORM3IPROC GLeeFuncPtr_glUniform3i=GLee_Lazy_glUniform3i; +#endif +#ifndef GLEE_C_DEFINED_glUniform4i +#define GLEE_C_DEFINED_glUniform4i + void __stdcall GLee_Lazy_glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {if (GLeeInit()) glUniform4i(location, v0, v1, v2, v3);} + GLEEPFNGLUNIFORM4IPROC GLeeFuncPtr_glUniform4i=GLee_Lazy_glUniform4i; +#endif +#ifndef GLEE_C_DEFINED_glUniform1fv +#define GLEE_C_DEFINED_glUniform1fv + void __stdcall GLee_Lazy_glUniform1fv(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform1fv(location, count, value);} + GLEEPFNGLUNIFORM1FVPROC GLeeFuncPtr_glUniform1fv=GLee_Lazy_glUniform1fv; +#endif +#ifndef GLEE_C_DEFINED_glUniform2fv +#define GLEE_C_DEFINED_glUniform2fv + void __stdcall GLee_Lazy_glUniform2fv(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform2fv(location, count, value);} + GLEEPFNGLUNIFORM2FVPROC GLeeFuncPtr_glUniform2fv=GLee_Lazy_glUniform2fv; +#endif +#ifndef GLEE_C_DEFINED_glUniform3fv +#define GLEE_C_DEFINED_glUniform3fv + void __stdcall GLee_Lazy_glUniform3fv(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform3fv(location, count, value);} + GLEEPFNGLUNIFORM3FVPROC GLeeFuncPtr_glUniform3fv=GLee_Lazy_glUniform3fv; +#endif +#ifndef GLEE_C_DEFINED_glUniform4fv +#define GLEE_C_DEFINED_glUniform4fv + void __stdcall GLee_Lazy_glUniform4fv(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform4fv(location, count, value);} + GLEEPFNGLUNIFORM4FVPROC GLeeFuncPtr_glUniform4fv=GLee_Lazy_glUniform4fv; +#endif +#ifndef GLEE_C_DEFINED_glUniform1iv +#define GLEE_C_DEFINED_glUniform1iv + void __stdcall GLee_Lazy_glUniform1iv(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform1iv(location, count, value);} + GLEEPFNGLUNIFORM1IVPROC GLeeFuncPtr_glUniform1iv=GLee_Lazy_glUniform1iv; +#endif +#ifndef GLEE_C_DEFINED_glUniform2iv +#define GLEE_C_DEFINED_glUniform2iv + void __stdcall GLee_Lazy_glUniform2iv(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform2iv(location, count, value);} + GLEEPFNGLUNIFORM2IVPROC GLeeFuncPtr_glUniform2iv=GLee_Lazy_glUniform2iv; +#endif +#ifndef GLEE_C_DEFINED_glUniform3iv +#define GLEE_C_DEFINED_glUniform3iv + void __stdcall GLee_Lazy_glUniform3iv(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform3iv(location, count, value);} + GLEEPFNGLUNIFORM3IVPROC GLeeFuncPtr_glUniform3iv=GLee_Lazy_glUniform3iv; +#endif +#ifndef GLEE_C_DEFINED_glUniform4iv +#define GLEE_C_DEFINED_glUniform4iv + void __stdcall GLee_Lazy_glUniform4iv(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform4iv(location, count, value);} + GLEEPFNGLUNIFORM4IVPROC GLeeFuncPtr_glUniform4iv=GLee_Lazy_glUniform4iv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix2fv +#define GLEE_C_DEFINED_glUniformMatrix2fv + void __stdcall GLee_Lazy_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix2fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX2FVPROC GLeeFuncPtr_glUniformMatrix2fv=GLee_Lazy_glUniformMatrix2fv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix3fv +#define GLEE_C_DEFINED_glUniformMatrix3fv + void __stdcall GLee_Lazy_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix3fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX3FVPROC GLeeFuncPtr_glUniformMatrix3fv=GLee_Lazy_glUniformMatrix3fv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix4fv +#define GLEE_C_DEFINED_glUniformMatrix4fv + void __stdcall GLee_Lazy_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix4fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX4FVPROC GLeeFuncPtr_glUniformMatrix4fv=GLee_Lazy_glUniformMatrix4fv; +#endif +#ifndef GLEE_C_DEFINED_glValidateProgram +#define GLEE_C_DEFINED_glValidateProgram + void __stdcall GLee_Lazy_glValidateProgram(GLuint program) {if (GLeeInit()) glValidateProgram(program);} + GLEEPFNGLVALIDATEPROGRAMPROC GLeeFuncPtr_glValidateProgram=GLee_Lazy_glValidateProgram; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1d +#define GLEE_C_DEFINED_glVertexAttrib1d + void __stdcall GLee_Lazy_glVertexAttrib1d(GLuint index, GLdouble x) {if (GLeeInit()) glVertexAttrib1d(index, x);} + GLEEPFNGLVERTEXATTRIB1DPROC GLeeFuncPtr_glVertexAttrib1d=GLee_Lazy_glVertexAttrib1d; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1dv +#define GLEE_C_DEFINED_glVertexAttrib1dv + void __stdcall GLee_Lazy_glVertexAttrib1dv(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib1dv(index, v);} + GLEEPFNGLVERTEXATTRIB1DVPROC GLeeFuncPtr_glVertexAttrib1dv=GLee_Lazy_glVertexAttrib1dv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1f +#define GLEE_C_DEFINED_glVertexAttrib1f + void __stdcall GLee_Lazy_glVertexAttrib1f(GLuint index, GLfloat x) {if (GLeeInit()) glVertexAttrib1f(index, x);} + GLEEPFNGLVERTEXATTRIB1FPROC GLeeFuncPtr_glVertexAttrib1f=GLee_Lazy_glVertexAttrib1f; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1fv +#define GLEE_C_DEFINED_glVertexAttrib1fv + void __stdcall GLee_Lazy_glVertexAttrib1fv(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib1fv(index, v);} + GLEEPFNGLVERTEXATTRIB1FVPROC GLeeFuncPtr_glVertexAttrib1fv=GLee_Lazy_glVertexAttrib1fv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1s +#define GLEE_C_DEFINED_glVertexAttrib1s + void __stdcall GLee_Lazy_glVertexAttrib1s(GLuint index, GLshort x) {if (GLeeInit()) glVertexAttrib1s(index, x);} + GLEEPFNGLVERTEXATTRIB1SPROC GLeeFuncPtr_glVertexAttrib1s=GLee_Lazy_glVertexAttrib1s; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1sv +#define GLEE_C_DEFINED_glVertexAttrib1sv + void __stdcall GLee_Lazy_glVertexAttrib1sv(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib1sv(index, v);} + GLEEPFNGLVERTEXATTRIB1SVPROC GLeeFuncPtr_glVertexAttrib1sv=GLee_Lazy_glVertexAttrib1sv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2d +#define GLEE_C_DEFINED_glVertexAttrib2d + void __stdcall GLee_Lazy_glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {if (GLeeInit()) glVertexAttrib2d(index, x, y);} + GLEEPFNGLVERTEXATTRIB2DPROC GLeeFuncPtr_glVertexAttrib2d=GLee_Lazy_glVertexAttrib2d; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2dv +#define GLEE_C_DEFINED_glVertexAttrib2dv + void __stdcall GLee_Lazy_glVertexAttrib2dv(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib2dv(index, v);} + GLEEPFNGLVERTEXATTRIB2DVPROC GLeeFuncPtr_glVertexAttrib2dv=GLee_Lazy_glVertexAttrib2dv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2f +#define GLEE_C_DEFINED_glVertexAttrib2f + void __stdcall GLee_Lazy_glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {if (GLeeInit()) glVertexAttrib2f(index, x, y);} + GLEEPFNGLVERTEXATTRIB2FPROC GLeeFuncPtr_glVertexAttrib2f=GLee_Lazy_glVertexAttrib2f; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2fv +#define GLEE_C_DEFINED_glVertexAttrib2fv + void __stdcall GLee_Lazy_glVertexAttrib2fv(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib2fv(index, v);} + GLEEPFNGLVERTEXATTRIB2FVPROC GLeeFuncPtr_glVertexAttrib2fv=GLee_Lazy_glVertexAttrib2fv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2s +#define GLEE_C_DEFINED_glVertexAttrib2s + void __stdcall GLee_Lazy_glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {if (GLeeInit()) glVertexAttrib2s(index, x, y);} + GLEEPFNGLVERTEXATTRIB2SPROC GLeeFuncPtr_glVertexAttrib2s=GLee_Lazy_glVertexAttrib2s; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2sv +#define GLEE_C_DEFINED_glVertexAttrib2sv + void __stdcall GLee_Lazy_glVertexAttrib2sv(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib2sv(index, v);} + GLEEPFNGLVERTEXATTRIB2SVPROC GLeeFuncPtr_glVertexAttrib2sv=GLee_Lazy_glVertexAttrib2sv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3d +#define GLEE_C_DEFINED_glVertexAttrib3d + void __stdcall GLee_Lazy_glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glVertexAttrib3d(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3DPROC GLeeFuncPtr_glVertexAttrib3d=GLee_Lazy_glVertexAttrib3d; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3dv +#define GLEE_C_DEFINED_glVertexAttrib3dv + void __stdcall GLee_Lazy_glVertexAttrib3dv(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib3dv(index, v);} + GLEEPFNGLVERTEXATTRIB3DVPROC GLeeFuncPtr_glVertexAttrib3dv=GLee_Lazy_glVertexAttrib3dv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3f +#define GLEE_C_DEFINED_glVertexAttrib3f + void __stdcall GLee_Lazy_glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glVertexAttrib3f(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3FPROC GLeeFuncPtr_glVertexAttrib3f=GLee_Lazy_glVertexAttrib3f; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3fv +#define GLEE_C_DEFINED_glVertexAttrib3fv + void __stdcall GLee_Lazy_glVertexAttrib3fv(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib3fv(index, v);} + GLEEPFNGLVERTEXATTRIB3FVPROC GLeeFuncPtr_glVertexAttrib3fv=GLee_Lazy_glVertexAttrib3fv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3s +#define GLEE_C_DEFINED_glVertexAttrib3s + void __stdcall GLee_Lazy_glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {if (GLeeInit()) glVertexAttrib3s(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3SPROC GLeeFuncPtr_glVertexAttrib3s=GLee_Lazy_glVertexAttrib3s; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3sv +#define GLEE_C_DEFINED_glVertexAttrib3sv + void __stdcall GLee_Lazy_glVertexAttrib3sv(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib3sv(index, v);} + GLEEPFNGLVERTEXATTRIB3SVPROC GLeeFuncPtr_glVertexAttrib3sv=GLee_Lazy_glVertexAttrib3sv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4Nbv +#define GLEE_C_DEFINED_glVertexAttrib4Nbv + void __stdcall GLee_Lazy_glVertexAttrib4Nbv(GLuint index, const GLbyte * v) {if (GLeeInit()) glVertexAttrib4Nbv(index, v);} + GLEEPFNGLVERTEXATTRIB4NBVPROC GLeeFuncPtr_glVertexAttrib4Nbv=GLee_Lazy_glVertexAttrib4Nbv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4Niv +#define GLEE_C_DEFINED_glVertexAttrib4Niv + void __stdcall GLee_Lazy_glVertexAttrib4Niv(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttrib4Niv(index, v);} + GLEEPFNGLVERTEXATTRIB4NIVPROC GLeeFuncPtr_glVertexAttrib4Niv=GLee_Lazy_glVertexAttrib4Niv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4Nsv +#define GLEE_C_DEFINED_glVertexAttrib4Nsv + void __stdcall GLee_Lazy_glVertexAttrib4Nsv(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib4Nsv(index, v);} + GLEEPFNGLVERTEXATTRIB4NSVPROC GLeeFuncPtr_glVertexAttrib4Nsv=GLee_Lazy_glVertexAttrib4Nsv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4Nub +#define GLEE_C_DEFINED_glVertexAttrib4Nub + void __stdcall GLee_Lazy_glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {if (GLeeInit()) glVertexAttrib4Nub(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4NUBPROC GLeeFuncPtr_glVertexAttrib4Nub=GLee_Lazy_glVertexAttrib4Nub; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4Nubv +#define GLEE_C_DEFINED_glVertexAttrib4Nubv + void __stdcall GLee_Lazy_glVertexAttrib4Nubv(GLuint index, const GLubyte * v) {if (GLeeInit()) glVertexAttrib4Nubv(index, v);} + GLEEPFNGLVERTEXATTRIB4NUBVPROC GLeeFuncPtr_glVertexAttrib4Nubv=GLee_Lazy_glVertexAttrib4Nubv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4Nuiv +#define GLEE_C_DEFINED_glVertexAttrib4Nuiv + void __stdcall GLee_Lazy_glVertexAttrib4Nuiv(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttrib4Nuiv(index, v);} + GLEEPFNGLVERTEXATTRIB4NUIVPROC GLeeFuncPtr_glVertexAttrib4Nuiv=GLee_Lazy_glVertexAttrib4Nuiv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4Nusv +#define GLEE_C_DEFINED_glVertexAttrib4Nusv + void __stdcall GLee_Lazy_glVertexAttrib4Nusv(GLuint index, const GLushort * v) {if (GLeeInit()) glVertexAttrib4Nusv(index, v);} + GLEEPFNGLVERTEXATTRIB4NUSVPROC GLeeFuncPtr_glVertexAttrib4Nusv=GLee_Lazy_glVertexAttrib4Nusv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4bv +#define GLEE_C_DEFINED_glVertexAttrib4bv + void __stdcall GLee_Lazy_glVertexAttrib4bv(GLuint index, const GLbyte * v) {if (GLeeInit()) glVertexAttrib4bv(index, v);} + GLEEPFNGLVERTEXATTRIB4BVPROC GLeeFuncPtr_glVertexAttrib4bv=GLee_Lazy_glVertexAttrib4bv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4d +#define GLEE_C_DEFINED_glVertexAttrib4d + void __stdcall GLee_Lazy_glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glVertexAttrib4d(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4DPROC GLeeFuncPtr_glVertexAttrib4d=GLee_Lazy_glVertexAttrib4d; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4dv +#define GLEE_C_DEFINED_glVertexAttrib4dv + void __stdcall GLee_Lazy_glVertexAttrib4dv(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib4dv(index, v);} + GLEEPFNGLVERTEXATTRIB4DVPROC GLeeFuncPtr_glVertexAttrib4dv=GLee_Lazy_glVertexAttrib4dv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4f +#define GLEE_C_DEFINED_glVertexAttrib4f + void __stdcall GLee_Lazy_glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glVertexAttrib4f(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4FPROC GLeeFuncPtr_glVertexAttrib4f=GLee_Lazy_glVertexAttrib4f; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4fv +#define GLEE_C_DEFINED_glVertexAttrib4fv + void __stdcall GLee_Lazy_glVertexAttrib4fv(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib4fv(index, v);} + GLEEPFNGLVERTEXATTRIB4FVPROC GLeeFuncPtr_glVertexAttrib4fv=GLee_Lazy_glVertexAttrib4fv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4iv +#define GLEE_C_DEFINED_glVertexAttrib4iv + void __stdcall GLee_Lazy_glVertexAttrib4iv(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttrib4iv(index, v);} + GLEEPFNGLVERTEXATTRIB4IVPROC GLeeFuncPtr_glVertexAttrib4iv=GLee_Lazy_glVertexAttrib4iv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4s +#define GLEE_C_DEFINED_glVertexAttrib4s + void __stdcall GLee_Lazy_glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {if (GLeeInit()) glVertexAttrib4s(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4SPROC GLeeFuncPtr_glVertexAttrib4s=GLee_Lazy_glVertexAttrib4s; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4sv +#define GLEE_C_DEFINED_glVertexAttrib4sv + void __stdcall GLee_Lazy_glVertexAttrib4sv(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib4sv(index, v);} + GLEEPFNGLVERTEXATTRIB4SVPROC GLeeFuncPtr_glVertexAttrib4sv=GLee_Lazy_glVertexAttrib4sv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4ubv +#define GLEE_C_DEFINED_glVertexAttrib4ubv + void __stdcall GLee_Lazy_glVertexAttrib4ubv(GLuint index, const GLubyte * v) {if (GLeeInit()) glVertexAttrib4ubv(index, v);} + GLEEPFNGLVERTEXATTRIB4UBVPROC GLeeFuncPtr_glVertexAttrib4ubv=GLee_Lazy_glVertexAttrib4ubv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4uiv +#define GLEE_C_DEFINED_glVertexAttrib4uiv + void __stdcall GLee_Lazy_glVertexAttrib4uiv(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttrib4uiv(index, v);} + GLEEPFNGLVERTEXATTRIB4UIVPROC GLeeFuncPtr_glVertexAttrib4uiv=GLee_Lazy_glVertexAttrib4uiv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4usv +#define GLEE_C_DEFINED_glVertexAttrib4usv + void __stdcall GLee_Lazy_glVertexAttrib4usv(GLuint index, const GLushort * v) {if (GLeeInit()) glVertexAttrib4usv(index, v);} + GLEEPFNGLVERTEXATTRIB4USVPROC GLeeFuncPtr_glVertexAttrib4usv=GLee_Lazy_glVertexAttrib4usv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribPointer +#define GLEE_C_DEFINED_glVertexAttribPointer + void __stdcall GLee_Lazy_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexAttribPointer(index, size, type, normalized, stride, pointer);} + GLEEPFNGLVERTEXATTRIBPOINTERPROC GLeeFuncPtr_glVertexAttribPointer=GLee_Lazy_glVertexAttribPointer; +#endif +#endif + +/* GL_VERSION_2_1 */ + +#ifdef __GLEE_GL_VERSION_2_1 +#ifndef GLEE_C_DEFINED_glUniformMatrix2x3fv +#define GLEE_C_DEFINED_glUniformMatrix2x3fv + void __stdcall GLee_Lazy_glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix2x3fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX2X3FVPROC GLeeFuncPtr_glUniformMatrix2x3fv=GLee_Lazy_glUniformMatrix2x3fv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix3x2fv +#define GLEE_C_DEFINED_glUniformMatrix3x2fv + void __stdcall GLee_Lazy_glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix3x2fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX3X2FVPROC GLeeFuncPtr_glUniformMatrix3x2fv=GLee_Lazy_glUniformMatrix3x2fv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix2x4fv +#define GLEE_C_DEFINED_glUniformMatrix2x4fv + void __stdcall GLee_Lazy_glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix2x4fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX2X4FVPROC GLeeFuncPtr_glUniformMatrix2x4fv=GLee_Lazy_glUniformMatrix2x4fv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix4x2fv +#define GLEE_C_DEFINED_glUniformMatrix4x2fv + void __stdcall GLee_Lazy_glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix4x2fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX4X2FVPROC GLeeFuncPtr_glUniformMatrix4x2fv=GLee_Lazy_glUniformMatrix4x2fv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix3x4fv +#define GLEE_C_DEFINED_glUniformMatrix3x4fv + void __stdcall GLee_Lazy_glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix3x4fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX3X4FVPROC GLeeFuncPtr_glUniformMatrix3x4fv=GLee_Lazy_glUniformMatrix3x4fv; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix4x3fv +#define GLEE_C_DEFINED_glUniformMatrix4x3fv + void __stdcall GLee_Lazy_glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix4x3fv(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX4X3FVPROC GLeeFuncPtr_glUniformMatrix4x3fv=GLee_Lazy_glUniformMatrix4x3fv; +#endif +#endif + +/* GL_VERSION_3_0 */ + +#ifdef __GLEE_GL_VERSION_3_0 +#ifndef GLEE_C_DEFINED_glColorMaski +#define GLEE_C_DEFINED_glColorMaski + void __stdcall GLee_Lazy_glColorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) {if (GLeeInit()) glColorMaski(index, r, g, b, a);} + GLEEPFNGLCOLORMASKIPROC GLeeFuncPtr_glColorMaski=GLee_Lazy_glColorMaski; +#endif +#ifndef GLEE_C_DEFINED_glGetBooleani_v +#define GLEE_C_DEFINED_glGetBooleani_v + void __stdcall GLee_Lazy_glGetBooleani_v(GLenum target, GLuint index, GLboolean * data) {if (GLeeInit()) glGetBooleani_v(target, index, data);} + GLEEPFNGLGETBOOLEANI_VPROC GLeeFuncPtr_glGetBooleani_v=GLee_Lazy_glGetBooleani_v; +#endif +#ifndef GLEE_C_DEFINED_glGetIntegeri_v +#define GLEE_C_DEFINED_glGetIntegeri_v + void __stdcall GLee_Lazy_glGetIntegeri_v(GLenum target, GLuint index, GLint * data) {if (GLeeInit()) glGetIntegeri_v(target, index, data);} + GLEEPFNGLGETINTEGERI_VPROC GLeeFuncPtr_glGetIntegeri_v=GLee_Lazy_glGetIntegeri_v; +#endif +#ifndef GLEE_C_DEFINED_glEnablei +#define GLEE_C_DEFINED_glEnablei + void __stdcall GLee_Lazy_glEnablei(GLenum target, GLuint index) {if (GLeeInit()) glEnablei(target, index);} + GLEEPFNGLENABLEIPROC GLeeFuncPtr_glEnablei=GLee_Lazy_glEnablei; +#endif +#ifndef GLEE_C_DEFINED_glDisablei +#define GLEE_C_DEFINED_glDisablei + void __stdcall GLee_Lazy_glDisablei(GLenum target, GLuint index) {if (GLeeInit()) glDisablei(target, index);} + GLEEPFNGLDISABLEIPROC GLeeFuncPtr_glDisablei=GLee_Lazy_glDisablei; +#endif +#ifndef GLEE_C_DEFINED_glIsEnabledi +#define GLEE_C_DEFINED_glIsEnabledi + GLboolean __stdcall GLee_Lazy_glIsEnabledi(GLenum target, GLuint index) {if (GLeeInit()) return glIsEnabledi(target, index); return (GLboolean)0;} + GLEEPFNGLISENABLEDIPROC GLeeFuncPtr_glIsEnabledi=GLee_Lazy_glIsEnabledi; +#endif +#ifndef GLEE_C_DEFINED_glBeginTransformFeedback +#define GLEE_C_DEFINED_glBeginTransformFeedback + void __stdcall GLee_Lazy_glBeginTransformFeedback(GLenum primitiveMode) {if (GLeeInit()) glBeginTransformFeedback(primitiveMode);} + GLEEPFNGLBEGINTRANSFORMFEEDBACKPROC GLeeFuncPtr_glBeginTransformFeedback=GLee_Lazy_glBeginTransformFeedback; +#endif +#ifndef GLEE_C_DEFINED_glEndTransformFeedback +#define GLEE_C_DEFINED_glEndTransformFeedback + void __stdcall GLee_Lazy_glEndTransformFeedback(void) {if (GLeeInit()) glEndTransformFeedback();} + GLEEPFNGLENDTRANSFORMFEEDBACKPROC GLeeFuncPtr_glEndTransformFeedback=GLee_Lazy_glEndTransformFeedback; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferRange +#define GLEE_C_DEFINED_glBindBufferRange + void __stdcall GLee_Lazy_glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {if (GLeeInit()) glBindBufferRange(target, index, buffer, offset, size);} + GLEEPFNGLBINDBUFFERRANGEPROC GLeeFuncPtr_glBindBufferRange=GLee_Lazy_glBindBufferRange; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferBase +#define GLEE_C_DEFINED_glBindBufferBase + void __stdcall GLee_Lazy_glBindBufferBase(GLenum target, GLuint index, GLuint buffer) {if (GLeeInit()) glBindBufferBase(target, index, buffer);} + GLEEPFNGLBINDBUFFERBASEPROC GLeeFuncPtr_glBindBufferBase=GLee_Lazy_glBindBufferBase; +#endif +#ifndef GLEE_C_DEFINED_glTransformFeedbackVaryings +#define GLEE_C_DEFINED_glTransformFeedbackVaryings + void __stdcall GLee_Lazy_glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLint * locations, GLenum bufferMode) {if (GLeeInit()) glTransformFeedbackVaryings(program, count, locations, bufferMode);} + GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC GLeeFuncPtr_glTransformFeedbackVaryings=GLee_Lazy_glTransformFeedbackVaryings; +#endif +#ifndef GLEE_C_DEFINED_glGetTransformFeedbackVarying +#define GLEE_C_DEFINED_glGetTransformFeedbackVarying + void __stdcall GLee_Lazy_glGetTransformFeedbackVarying(GLuint program, GLuint index, GLint * location) {if (GLeeInit()) glGetTransformFeedbackVarying(program, index, location);} + GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGPROC GLeeFuncPtr_glGetTransformFeedbackVarying=GLee_Lazy_glGetTransformFeedbackVarying; +#endif +#ifndef GLEE_C_DEFINED_glClampColor +#define GLEE_C_DEFINED_glClampColor + void __stdcall GLee_Lazy_glClampColor(GLenum target, GLenum clamp) {if (GLeeInit()) glClampColor(target, clamp);} + GLEEPFNGLCLAMPCOLORPROC GLeeFuncPtr_glClampColor=GLee_Lazy_glClampColor; +#endif +#ifndef GLEE_C_DEFINED_glBeginConditionalRender +#define GLEE_C_DEFINED_glBeginConditionalRender + void __stdcall GLee_Lazy_glBeginConditionalRender(GLuint id, GLenum mode) {if (GLeeInit()) glBeginConditionalRender(id, mode);} + GLEEPFNGLBEGINCONDITIONALRENDERPROC GLeeFuncPtr_glBeginConditionalRender=GLee_Lazy_glBeginConditionalRender; +#endif +#ifndef GLEE_C_DEFINED_glEndConditionalRender +#define GLEE_C_DEFINED_glEndConditionalRender + void __stdcall GLee_Lazy_glEndConditionalRender(void) {if (GLeeInit()) glEndConditionalRender();} + GLEEPFNGLENDCONDITIONALRENDERPROC GLeeFuncPtr_glEndConditionalRender=GLee_Lazy_glEndConditionalRender; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI1i +#define GLEE_C_DEFINED_glVertexAttribI1i + void __stdcall GLee_Lazy_glVertexAttribI1i(GLuint index, GLint x) {if (GLeeInit()) glVertexAttribI1i(index, x);} + GLEEPFNGLVERTEXATTRIBI1IPROC GLeeFuncPtr_glVertexAttribI1i=GLee_Lazy_glVertexAttribI1i; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2i +#define GLEE_C_DEFINED_glVertexAttribI2i + void __stdcall GLee_Lazy_glVertexAttribI2i(GLuint index, GLint x, GLint y) {if (GLeeInit()) glVertexAttribI2i(index, x, y);} + GLEEPFNGLVERTEXATTRIBI2IPROC GLeeFuncPtr_glVertexAttribI2i=GLee_Lazy_glVertexAttribI2i; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3i +#define GLEE_C_DEFINED_glVertexAttribI3i + void __stdcall GLee_Lazy_glVertexAttribI3i(GLuint index, GLint x, GLint y, GLint z) {if (GLeeInit()) glVertexAttribI3i(index, x, y, z);} + GLEEPFNGLVERTEXATTRIBI3IPROC GLeeFuncPtr_glVertexAttribI3i=GLee_Lazy_glVertexAttribI3i; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4i +#define GLEE_C_DEFINED_glVertexAttribI4i + void __stdcall GLee_Lazy_glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) {if (GLeeInit()) glVertexAttribI4i(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIBI4IPROC GLeeFuncPtr_glVertexAttribI4i=GLee_Lazy_glVertexAttribI4i; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI1ui +#define GLEE_C_DEFINED_glVertexAttribI1ui + void __stdcall GLee_Lazy_glVertexAttribI1ui(GLuint index, GLuint x) {if (GLeeInit()) glVertexAttribI1ui(index, x);} + GLEEPFNGLVERTEXATTRIBI1UIPROC GLeeFuncPtr_glVertexAttribI1ui=GLee_Lazy_glVertexAttribI1ui; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2ui +#define GLEE_C_DEFINED_glVertexAttribI2ui + void __stdcall GLee_Lazy_glVertexAttribI2ui(GLuint index, GLuint x, GLuint y) {if (GLeeInit()) glVertexAttribI2ui(index, x, y);} + GLEEPFNGLVERTEXATTRIBI2UIPROC GLeeFuncPtr_glVertexAttribI2ui=GLee_Lazy_glVertexAttribI2ui; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3ui +#define GLEE_C_DEFINED_glVertexAttribI3ui + void __stdcall GLee_Lazy_glVertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z) {if (GLeeInit()) glVertexAttribI3ui(index, x, y, z);} + GLEEPFNGLVERTEXATTRIBI3UIPROC GLeeFuncPtr_glVertexAttribI3ui=GLee_Lazy_glVertexAttribI3ui; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4ui +#define GLEE_C_DEFINED_glVertexAttribI4ui + void __stdcall GLee_Lazy_glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {if (GLeeInit()) glVertexAttribI4ui(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIBI4UIPROC GLeeFuncPtr_glVertexAttribI4ui=GLee_Lazy_glVertexAttribI4ui; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI1iv +#define GLEE_C_DEFINED_glVertexAttribI1iv + void __stdcall GLee_Lazy_glVertexAttribI1iv(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI1iv(index, v);} + GLEEPFNGLVERTEXATTRIBI1IVPROC GLeeFuncPtr_glVertexAttribI1iv=GLee_Lazy_glVertexAttribI1iv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2iv +#define GLEE_C_DEFINED_glVertexAttribI2iv + void __stdcall GLee_Lazy_glVertexAttribI2iv(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI2iv(index, v);} + GLEEPFNGLVERTEXATTRIBI2IVPROC GLeeFuncPtr_glVertexAttribI2iv=GLee_Lazy_glVertexAttribI2iv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3iv +#define GLEE_C_DEFINED_glVertexAttribI3iv + void __stdcall GLee_Lazy_glVertexAttribI3iv(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI3iv(index, v);} + GLEEPFNGLVERTEXATTRIBI3IVPROC GLeeFuncPtr_glVertexAttribI3iv=GLee_Lazy_glVertexAttribI3iv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4iv +#define GLEE_C_DEFINED_glVertexAttribI4iv + void __stdcall GLee_Lazy_glVertexAttribI4iv(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI4iv(index, v);} + GLEEPFNGLVERTEXATTRIBI4IVPROC GLeeFuncPtr_glVertexAttribI4iv=GLee_Lazy_glVertexAttribI4iv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI1uiv +#define GLEE_C_DEFINED_glVertexAttribI1uiv + void __stdcall GLee_Lazy_glVertexAttribI1uiv(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI1uiv(index, v);} + GLEEPFNGLVERTEXATTRIBI1UIVPROC GLeeFuncPtr_glVertexAttribI1uiv=GLee_Lazy_glVertexAttribI1uiv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2uiv +#define GLEE_C_DEFINED_glVertexAttribI2uiv + void __stdcall GLee_Lazy_glVertexAttribI2uiv(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI2uiv(index, v);} + GLEEPFNGLVERTEXATTRIBI2UIVPROC GLeeFuncPtr_glVertexAttribI2uiv=GLee_Lazy_glVertexAttribI2uiv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3uiv +#define GLEE_C_DEFINED_glVertexAttribI3uiv + void __stdcall GLee_Lazy_glVertexAttribI3uiv(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI3uiv(index, v);} + GLEEPFNGLVERTEXATTRIBI3UIVPROC GLeeFuncPtr_glVertexAttribI3uiv=GLee_Lazy_glVertexAttribI3uiv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4uiv +#define GLEE_C_DEFINED_glVertexAttribI4uiv + void __stdcall GLee_Lazy_glVertexAttribI4uiv(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI4uiv(index, v);} + GLEEPFNGLVERTEXATTRIBI4UIVPROC GLeeFuncPtr_glVertexAttribI4uiv=GLee_Lazy_glVertexAttribI4uiv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4bv +#define GLEE_C_DEFINED_glVertexAttribI4bv + void __stdcall GLee_Lazy_glVertexAttribI4bv(GLuint index, const GLbyte * v) {if (GLeeInit()) glVertexAttribI4bv(index, v);} + GLEEPFNGLVERTEXATTRIBI4BVPROC GLeeFuncPtr_glVertexAttribI4bv=GLee_Lazy_glVertexAttribI4bv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4sv +#define GLEE_C_DEFINED_glVertexAttribI4sv + void __stdcall GLee_Lazy_glVertexAttribI4sv(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttribI4sv(index, v);} + GLEEPFNGLVERTEXATTRIBI4SVPROC GLeeFuncPtr_glVertexAttribI4sv=GLee_Lazy_glVertexAttribI4sv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4ubv +#define GLEE_C_DEFINED_glVertexAttribI4ubv + void __stdcall GLee_Lazy_glVertexAttribI4ubv(GLuint index, const GLubyte * v) {if (GLeeInit()) glVertexAttribI4ubv(index, v);} + GLEEPFNGLVERTEXATTRIBI4UBVPROC GLeeFuncPtr_glVertexAttribI4ubv=GLee_Lazy_glVertexAttribI4ubv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4usv +#define GLEE_C_DEFINED_glVertexAttribI4usv + void __stdcall GLee_Lazy_glVertexAttribI4usv(GLuint index, const GLushort * v) {if (GLeeInit()) glVertexAttribI4usv(index, v);} + GLEEPFNGLVERTEXATTRIBI4USVPROC GLeeFuncPtr_glVertexAttribI4usv=GLee_Lazy_glVertexAttribI4usv; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribIPointer +#define GLEE_C_DEFINED_glVertexAttribIPointer + void __stdcall GLee_Lazy_glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexAttribIPointer(index, size, type, stride, pointer);} + GLEEPFNGLVERTEXATTRIBIPOINTERPROC GLeeFuncPtr_glVertexAttribIPointer=GLee_Lazy_glVertexAttribIPointer; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribIiv +#define GLEE_C_DEFINED_glGetVertexAttribIiv + void __stdcall GLee_Lazy_glGetVertexAttribIiv(GLuint index, GLenum pname, GLint * params) {if (GLeeInit()) glGetVertexAttribIiv(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBIIVPROC GLeeFuncPtr_glGetVertexAttribIiv=GLee_Lazy_glGetVertexAttribIiv; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribIuiv +#define GLEE_C_DEFINED_glGetVertexAttribIuiv + void __stdcall GLee_Lazy_glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint * params) {if (GLeeInit()) glGetVertexAttribIuiv(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBIUIVPROC GLeeFuncPtr_glGetVertexAttribIuiv=GLee_Lazy_glGetVertexAttribIuiv; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformuiv +#define GLEE_C_DEFINED_glGetUniformuiv + void __stdcall GLee_Lazy_glGetUniformuiv(GLuint program, GLint location, GLuint * params) {if (GLeeInit()) glGetUniformuiv(program, location, params);} + GLEEPFNGLGETUNIFORMUIVPROC GLeeFuncPtr_glGetUniformuiv=GLee_Lazy_glGetUniformuiv; +#endif +#ifndef GLEE_C_DEFINED_glBindFragDataLocation +#define GLEE_C_DEFINED_glBindFragDataLocation + void __stdcall GLee_Lazy_glBindFragDataLocation(GLuint program, GLuint color, const GLchar * name) {if (GLeeInit()) glBindFragDataLocation(program, color, name);} + GLEEPFNGLBINDFRAGDATALOCATIONPROC GLeeFuncPtr_glBindFragDataLocation=GLee_Lazy_glBindFragDataLocation; +#endif +#ifndef GLEE_C_DEFINED_glGetFragDataLocation +#define GLEE_C_DEFINED_glGetFragDataLocation + GLint __stdcall GLee_Lazy_glGetFragDataLocation(GLuint program, const GLchar * name) {if (GLeeInit()) return glGetFragDataLocation(program, name); return (GLint)0;} + GLEEPFNGLGETFRAGDATALOCATIONPROC GLeeFuncPtr_glGetFragDataLocation=GLee_Lazy_glGetFragDataLocation; +#endif +#ifndef GLEE_C_DEFINED_glUniform1ui +#define GLEE_C_DEFINED_glUniform1ui + void __stdcall GLee_Lazy_glUniform1ui(GLint location, GLuint v0) {if (GLeeInit()) glUniform1ui(location, v0);} + GLEEPFNGLUNIFORM1UIPROC GLeeFuncPtr_glUniform1ui=GLee_Lazy_glUniform1ui; +#endif +#ifndef GLEE_C_DEFINED_glUniform2ui +#define GLEE_C_DEFINED_glUniform2ui + void __stdcall GLee_Lazy_glUniform2ui(GLint location, GLuint v0, GLuint v1) {if (GLeeInit()) glUniform2ui(location, v0, v1);} + GLEEPFNGLUNIFORM2UIPROC GLeeFuncPtr_glUniform2ui=GLee_Lazy_glUniform2ui; +#endif +#ifndef GLEE_C_DEFINED_glUniform3ui +#define GLEE_C_DEFINED_glUniform3ui + void __stdcall GLee_Lazy_glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) {if (GLeeInit()) glUniform3ui(location, v0, v1, v2);} + GLEEPFNGLUNIFORM3UIPROC GLeeFuncPtr_glUniform3ui=GLee_Lazy_glUniform3ui; +#endif +#ifndef GLEE_C_DEFINED_glUniform4ui +#define GLEE_C_DEFINED_glUniform4ui + void __stdcall GLee_Lazy_glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {if (GLeeInit()) glUniform4ui(location, v0, v1, v2, v3);} + GLEEPFNGLUNIFORM4UIPROC GLeeFuncPtr_glUniform4ui=GLee_Lazy_glUniform4ui; +#endif +#ifndef GLEE_C_DEFINED_glUniform1uiv +#define GLEE_C_DEFINED_glUniform1uiv + void __stdcall GLee_Lazy_glUniform1uiv(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform1uiv(location, count, value);} + GLEEPFNGLUNIFORM1UIVPROC GLeeFuncPtr_glUniform1uiv=GLee_Lazy_glUniform1uiv; +#endif +#ifndef GLEE_C_DEFINED_glUniform2uiv +#define GLEE_C_DEFINED_glUniform2uiv + void __stdcall GLee_Lazy_glUniform2uiv(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform2uiv(location, count, value);} + GLEEPFNGLUNIFORM2UIVPROC GLeeFuncPtr_glUniform2uiv=GLee_Lazy_glUniform2uiv; +#endif +#ifndef GLEE_C_DEFINED_glUniform3uiv +#define GLEE_C_DEFINED_glUniform3uiv + void __stdcall GLee_Lazy_glUniform3uiv(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform3uiv(location, count, value);} + GLEEPFNGLUNIFORM3UIVPROC GLeeFuncPtr_glUniform3uiv=GLee_Lazy_glUniform3uiv; +#endif +#ifndef GLEE_C_DEFINED_glUniform4uiv +#define GLEE_C_DEFINED_glUniform4uiv + void __stdcall GLee_Lazy_glUniform4uiv(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform4uiv(location, count, value);} + GLEEPFNGLUNIFORM4UIVPROC GLeeFuncPtr_glUniform4uiv=GLee_Lazy_glUniform4uiv; +#endif +#ifndef GLEE_C_DEFINED_glTexParameterIiv +#define GLEE_C_DEFINED_glTexParameterIiv + void __stdcall GLee_Lazy_glTexParameterIiv(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glTexParameterIiv(target, pname, params);} + GLEEPFNGLTEXPARAMETERIIVPROC GLeeFuncPtr_glTexParameterIiv=GLee_Lazy_glTexParameterIiv; +#endif +#ifndef GLEE_C_DEFINED_glTexParameterIuiv +#define GLEE_C_DEFINED_glTexParameterIuiv + void __stdcall GLee_Lazy_glTexParameterIuiv(GLenum target, GLenum pname, const GLuint * params) {if (GLeeInit()) glTexParameterIuiv(target, pname, params);} + GLEEPFNGLTEXPARAMETERIUIVPROC GLeeFuncPtr_glTexParameterIuiv=GLee_Lazy_glTexParameterIuiv; +#endif +#ifndef GLEE_C_DEFINED_glGetTexParameterIiv +#define GLEE_C_DEFINED_glGetTexParameterIiv + void __stdcall GLee_Lazy_glGetTexParameterIiv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetTexParameterIiv(target, pname, params);} + GLEEPFNGLGETTEXPARAMETERIIVPROC GLeeFuncPtr_glGetTexParameterIiv=GLee_Lazy_glGetTexParameterIiv; +#endif +#ifndef GLEE_C_DEFINED_glGetTexParameterIuiv +#define GLEE_C_DEFINED_glGetTexParameterIuiv + void __stdcall GLee_Lazy_glGetTexParameterIuiv(GLenum target, GLenum pname, GLuint * params) {if (GLeeInit()) glGetTexParameterIuiv(target, pname, params);} + GLEEPFNGLGETTEXPARAMETERIUIVPROC GLeeFuncPtr_glGetTexParameterIuiv=GLee_Lazy_glGetTexParameterIuiv; +#endif +#ifndef GLEE_C_DEFINED_glClearBufferiv +#define GLEE_C_DEFINED_glClearBufferiv + void __stdcall GLee_Lazy_glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value) {if (GLeeInit()) glClearBufferiv(buffer, drawbuffer, value);} + GLEEPFNGLCLEARBUFFERIVPROC GLeeFuncPtr_glClearBufferiv=GLee_Lazy_glClearBufferiv; +#endif +#ifndef GLEE_C_DEFINED_glClearBufferuiv +#define GLEE_C_DEFINED_glClearBufferuiv + void __stdcall GLee_Lazy_glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value) {if (GLeeInit()) glClearBufferuiv(buffer, drawbuffer, value);} + GLEEPFNGLCLEARBUFFERUIVPROC GLeeFuncPtr_glClearBufferuiv=GLee_Lazy_glClearBufferuiv; +#endif +#ifndef GLEE_C_DEFINED_glClearBufferfv +#define GLEE_C_DEFINED_glClearBufferfv + void __stdcall GLee_Lazy_glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value) {if (GLeeInit()) glClearBufferfv(buffer, drawbuffer, value);} + GLEEPFNGLCLEARBUFFERFVPROC GLeeFuncPtr_glClearBufferfv=GLee_Lazy_glClearBufferfv; +#endif +#ifndef GLEE_C_DEFINED_glClearBufferfi +#define GLEE_C_DEFINED_glClearBufferfi + void __stdcall GLee_Lazy_glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {if (GLeeInit()) glClearBufferfi(buffer, drawbuffer, depth, stencil);} + GLEEPFNGLCLEARBUFFERFIPROC GLeeFuncPtr_glClearBufferfi=GLee_Lazy_glClearBufferfi; +#endif +#ifndef GLEE_C_DEFINED_glGetStringi +#define GLEE_C_DEFINED_glGetStringi + const GLubyte * __stdcall GLee_Lazy_glGetStringi(GLenum name, GLuint index) {if (GLeeInit()) return glGetStringi(name, index); return (const GLubyte *)0;} + GLEEPFNGLGETSTRINGIPROC GLeeFuncPtr_glGetStringi=GLee_Lazy_glGetStringi; +#endif +#endif + +/* GL_ARB_multitexture */ + +#ifdef __GLEE_GL_ARB_multitexture +#ifndef GLEE_C_DEFINED_glActiveTextureARB +#define GLEE_C_DEFINED_glActiveTextureARB + void __stdcall GLee_Lazy_glActiveTextureARB(GLenum texture) {if (GLeeInit()) glActiveTextureARB(texture);} + GLEEPFNGLACTIVETEXTUREARBPROC GLeeFuncPtr_glActiveTextureARB=GLee_Lazy_glActiveTextureARB; +#endif +#ifndef GLEE_C_DEFINED_glClientActiveTextureARB +#define GLEE_C_DEFINED_glClientActiveTextureARB + void __stdcall GLee_Lazy_glClientActiveTextureARB(GLenum texture) {if (GLeeInit()) glClientActiveTextureARB(texture);} + GLEEPFNGLCLIENTACTIVETEXTUREARBPROC GLeeFuncPtr_glClientActiveTextureARB=GLee_Lazy_glClientActiveTextureARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1dARB +#define GLEE_C_DEFINED_glMultiTexCoord1dARB + void __stdcall GLee_Lazy_glMultiTexCoord1dARB(GLenum target, GLdouble s) {if (GLeeInit()) glMultiTexCoord1dARB(target, s);} + GLEEPFNGLMULTITEXCOORD1DARBPROC GLeeFuncPtr_glMultiTexCoord1dARB=GLee_Lazy_glMultiTexCoord1dARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1dvARB +#define GLEE_C_DEFINED_glMultiTexCoord1dvARB + void __stdcall GLee_Lazy_glMultiTexCoord1dvARB(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord1dvARB(target, v);} + GLEEPFNGLMULTITEXCOORD1DVARBPROC GLeeFuncPtr_glMultiTexCoord1dvARB=GLee_Lazy_glMultiTexCoord1dvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1fARB +#define GLEE_C_DEFINED_glMultiTexCoord1fARB + void __stdcall GLee_Lazy_glMultiTexCoord1fARB(GLenum target, GLfloat s) {if (GLeeInit()) glMultiTexCoord1fARB(target, s);} + GLEEPFNGLMULTITEXCOORD1FARBPROC GLeeFuncPtr_glMultiTexCoord1fARB=GLee_Lazy_glMultiTexCoord1fARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1fvARB +#define GLEE_C_DEFINED_glMultiTexCoord1fvARB + void __stdcall GLee_Lazy_glMultiTexCoord1fvARB(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord1fvARB(target, v);} + GLEEPFNGLMULTITEXCOORD1FVARBPROC GLeeFuncPtr_glMultiTexCoord1fvARB=GLee_Lazy_glMultiTexCoord1fvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1iARB +#define GLEE_C_DEFINED_glMultiTexCoord1iARB + void __stdcall GLee_Lazy_glMultiTexCoord1iARB(GLenum target, GLint s) {if (GLeeInit()) glMultiTexCoord1iARB(target, s);} + GLEEPFNGLMULTITEXCOORD1IARBPROC GLeeFuncPtr_glMultiTexCoord1iARB=GLee_Lazy_glMultiTexCoord1iARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1ivARB +#define GLEE_C_DEFINED_glMultiTexCoord1ivARB + void __stdcall GLee_Lazy_glMultiTexCoord1ivARB(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord1ivARB(target, v);} + GLEEPFNGLMULTITEXCOORD1IVARBPROC GLeeFuncPtr_glMultiTexCoord1ivARB=GLee_Lazy_glMultiTexCoord1ivARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1sARB +#define GLEE_C_DEFINED_glMultiTexCoord1sARB + void __stdcall GLee_Lazy_glMultiTexCoord1sARB(GLenum target, GLshort s) {if (GLeeInit()) glMultiTexCoord1sARB(target, s);} + GLEEPFNGLMULTITEXCOORD1SARBPROC GLeeFuncPtr_glMultiTexCoord1sARB=GLee_Lazy_glMultiTexCoord1sARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1svARB +#define GLEE_C_DEFINED_glMultiTexCoord1svARB + void __stdcall GLee_Lazy_glMultiTexCoord1svARB(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord1svARB(target, v);} + GLEEPFNGLMULTITEXCOORD1SVARBPROC GLeeFuncPtr_glMultiTexCoord1svARB=GLee_Lazy_glMultiTexCoord1svARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2dARB +#define GLEE_C_DEFINED_glMultiTexCoord2dARB + void __stdcall GLee_Lazy_glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t) {if (GLeeInit()) glMultiTexCoord2dARB(target, s, t);} + GLEEPFNGLMULTITEXCOORD2DARBPROC GLeeFuncPtr_glMultiTexCoord2dARB=GLee_Lazy_glMultiTexCoord2dARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2dvARB +#define GLEE_C_DEFINED_glMultiTexCoord2dvARB + void __stdcall GLee_Lazy_glMultiTexCoord2dvARB(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord2dvARB(target, v);} + GLEEPFNGLMULTITEXCOORD2DVARBPROC GLeeFuncPtr_glMultiTexCoord2dvARB=GLee_Lazy_glMultiTexCoord2dvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2fARB +#define GLEE_C_DEFINED_glMultiTexCoord2fARB + void __stdcall GLee_Lazy_glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) {if (GLeeInit()) glMultiTexCoord2fARB(target, s, t);} + GLEEPFNGLMULTITEXCOORD2FARBPROC GLeeFuncPtr_glMultiTexCoord2fARB=GLee_Lazy_glMultiTexCoord2fARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2fvARB +#define GLEE_C_DEFINED_glMultiTexCoord2fvARB + void __stdcall GLee_Lazy_glMultiTexCoord2fvARB(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord2fvARB(target, v);} + GLEEPFNGLMULTITEXCOORD2FVARBPROC GLeeFuncPtr_glMultiTexCoord2fvARB=GLee_Lazy_glMultiTexCoord2fvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2iARB +#define GLEE_C_DEFINED_glMultiTexCoord2iARB + void __stdcall GLee_Lazy_glMultiTexCoord2iARB(GLenum target, GLint s, GLint t) {if (GLeeInit()) glMultiTexCoord2iARB(target, s, t);} + GLEEPFNGLMULTITEXCOORD2IARBPROC GLeeFuncPtr_glMultiTexCoord2iARB=GLee_Lazy_glMultiTexCoord2iARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2ivARB +#define GLEE_C_DEFINED_glMultiTexCoord2ivARB + void __stdcall GLee_Lazy_glMultiTexCoord2ivARB(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord2ivARB(target, v);} + GLEEPFNGLMULTITEXCOORD2IVARBPROC GLeeFuncPtr_glMultiTexCoord2ivARB=GLee_Lazy_glMultiTexCoord2ivARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2sARB +#define GLEE_C_DEFINED_glMultiTexCoord2sARB + void __stdcall GLee_Lazy_glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t) {if (GLeeInit()) glMultiTexCoord2sARB(target, s, t);} + GLEEPFNGLMULTITEXCOORD2SARBPROC GLeeFuncPtr_glMultiTexCoord2sARB=GLee_Lazy_glMultiTexCoord2sARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2svARB +#define GLEE_C_DEFINED_glMultiTexCoord2svARB + void __stdcall GLee_Lazy_glMultiTexCoord2svARB(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord2svARB(target, v);} + GLEEPFNGLMULTITEXCOORD2SVARBPROC GLeeFuncPtr_glMultiTexCoord2svARB=GLee_Lazy_glMultiTexCoord2svARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3dARB +#define GLEE_C_DEFINED_glMultiTexCoord3dARB + void __stdcall GLee_Lazy_glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r) {if (GLeeInit()) glMultiTexCoord3dARB(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3DARBPROC GLeeFuncPtr_glMultiTexCoord3dARB=GLee_Lazy_glMultiTexCoord3dARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3dvARB +#define GLEE_C_DEFINED_glMultiTexCoord3dvARB + void __stdcall GLee_Lazy_glMultiTexCoord3dvARB(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord3dvARB(target, v);} + GLEEPFNGLMULTITEXCOORD3DVARBPROC GLeeFuncPtr_glMultiTexCoord3dvARB=GLee_Lazy_glMultiTexCoord3dvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3fARB +#define GLEE_C_DEFINED_glMultiTexCoord3fARB + void __stdcall GLee_Lazy_glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) {if (GLeeInit()) glMultiTexCoord3fARB(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3FARBPROC GLeeFuncPtr_glMultiTexCoord3fARB=GLee_Lazy_glMultiTexCoord3fARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3fvARB +#define GLEE_C_DEFINED_glMultiTexCoord3fvARB + void __stdcall GLee_Lazy_glMultiTexCoord3fvARB(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord3fvARB(target, v);} + GLEEPFNGLMULTITEXCOORD3FVARBPROC GLeeFuncPtr_glMultiTexCoord3fvARB=GLee_Lazy_glMultiTexCoord3fvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3iARB +#define GLEE_C_DEFINED_glMultiTexCoord3iARB + void __stdcall GLee_Lazy_glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r) {if (GLeeInit()) glMultiTexCoord3iARB(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3IARBPROC GLeeFuncPtr_glMultiTexCoord3iARB=GLee_Lazy_glMultiTexCoord3iARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3ivARB +#define GLEE_C_DEFINED_glMultiTexCoord3ivARB + void __stdcall GLee_Lazy_glMultiTexCoord3ivARB(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord3ivARB(target, v);} + GLEEPFNGLMULTITEXCOORD3IVARBPROC GLeeFuncPtr_glMultiTexCoord3ivARB=GLee_Lazy_glMultiTexCoord3ivARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3sARB +#define GLEE_C_DEFINED_glMultiTexCoord3sARB + void __stdcall GLee_Lazy_glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r) {if (GLeeInit()) glMultiTexCoord3sARB(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3SARBPROC GLeeFuncPtr_glMultiTexCoord3sARB=GLee_Lazy_glMultiTexCoord3sARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3svARB +#define GLEE_C_DEFINED_glMultiTexCoord3svARB + void __stdcall GLee_Lazy_glMultiTexCoord3svARB(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord3svARB(target, v);} + GLEEPFNGLMULTITEXCOORD3SVARBPROC GLeeFuncPtr_glMultiTexCoord3svARB=GLee_Lazy_glMultiTexCoord3svARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4dARB +#define GLEE_C_DEFINED_glMultiTexCoord4dARB + void __stdcall GLee_Lazy_glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {if (GLeeInit()) glMultiTexCoord4dARB(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4DARBPROC GLeeFuncPtr_glMultiTexCoord4dARB=GLee_Lazy_glMultiTexCoord4dARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4dvARB +#define GLEE_C_DEFINED_glMultiTexCoord4dvARB + void __stdcall GLee_Lazy_glMultiTexCoord4dvARB(GLenum target, const GLdouble * v) {if (GLeeInit()) glMultiTexCoord4dvARB(target, v);} + GLEEPFNGLMULTITEXCOORD4DVARBPROC GLeeFuncPtr_glMultiTexCoord4dvARB=GLee_Lazy_glMultiTexCoord4dvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4fARB +#define GLEE_C_DEFINED_glMultiTexCoord4fARB + void __stdcall GLee_Lazy_glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {if (GLeeInit()) glMultiTexCoord4fARB(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4FARBPROC GLeeFuncPtr_glMultiTexCoord4fARB=GLee_Lazy_glMultiTexCoord4fARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4fvARB +#define GLEE_C_DEFINED_glMultiTexCoord4fvARB + void __stdcall GLee_Lazy_glMultiTexCoord4fvARB(GLenum target, const GLfloat * v) {if (GLeeInit()) glMultiTexCoord4fvARB(target, v);} + GLEEPFNGLMULTITEXCOORD4FVARBPROC GLeeFuncPtr_glMultiTexCoord4fvARB=GLee_Lazy_glMultiTexCoord4fvARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4iARB +#define GLEE_C_DEFINED_glMultiTexCoord4iARB + void __stdcall GLee_Lazy_glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q) {if (GLeeInit()) glMultiTexCoord4iARB(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4IARBPROC GLeeFuncPtr_glMultiTexCoord4iARB=GLee_Lazy_glMultiTexCoord4iARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4ivARB +#define GLEE_C_DEFINED_glMultiTexCoord4ivARB + void __stdcall GLee_Lazy_glMultiTexCoord4ivARB(GLenum target, const GLint * v) {if (GLeeInit()) glMultiTexCoord4ivARB(target, v);} + GLEEPFNGLMULTITEXCOORD4IVARBPROC GLeeFuncPtr_glMultiTexCoord4ivARB=GLee_Lazy_glMultiTexCoord4ivARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4sARB +#define GLEE_C_DEFINED_glMultiTexCoord4sARB + void __stdcall GLee_Lazy_glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) {if (GLeeInit()) glMultiTexCoord4sARB(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4SARBPROC GLeeFuncPtr_glMultiTexCoord4sARB=GLee_Lazy_glMultiTexCoord4sARB; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4svARB +#define GLEE_C_DEFINED_glMultiTexCoord4svARB + void __stdcall GLee_Lazy_glMultiTexCoord4svARB(GLenum target, const GLshort * v) {if (GLeeInit()) glMultiTexCoord4svARB(target, v);} + GLEEPFNGLMULTITEXCOORD4SVARBPROC GLeeFuncPtr_glMultiTexCoord4svARB=GLee_Lazy_glMultiTexCoord4svARB; +#endif +#endif + +/* GL_ARB_transpose_matrix */ + +#ifdef __GLEE_GL_ARB_transpose_matrix +#ifndef GLEE_C_DEFINED_glLoadTransposeMatrixfARB +#define GLEE_C_DEFINED_glLoadTransposeMatrixfARB + void __stdcall GLee_Lazy_glLoadTransposeMatrixfARB(const GLfloat * m) {if (GLeeInit()) glLoadTransposeMatrixfARB(m);} + GLEEPFNGLLOADTRANSPOSEMATRIXFARBPROC GLeeFuncPtr_glLoadTransposeMatrixfARB=GLee_Lazy_glLoadTransposeMatrixfARB; +#endif +#ifndef GLEE_C_DEFINED_glLoadTransposeMatrixdARB +#define GLEE_C_DEFINED_glLoadTransposeMatrixdARB + void __stdcall GLee_Lazy_glLoadTransposeMatrixdARB(const GLdouble * m) {if (GLeeInit()) glLoadTransposeMatrixdARB(m);} + GLEEPFNGLLOADTRANSPOSEMATRIXDARBPROC GLeeFuncPtr_glLoadTransposeMatrixdARB=GLee_Lazy_glLoadTransposeMatrixdARB; +#endif +#ifndef GLEE_C_DEFINED_glMultTransposeMatrixfARB +#define GLEE_C_DEFINED_glMultTransposeMatrixfARB + void __stdcall GLee_Lazy_glMultTransposeMatrixfARB(const GLfloat * m) {if (GLeeInit()) glMultTransposeMatrixfARB(m);} + GLEEPFNGLMULTTRANSPOSEMATRIXFARBPROC GLeeFuncPtr_glMultTransposeMatrixfARB=GLee_Lazy_glMultTransposeMatrixfARB; +#endif +#ifndef GLEE_C_DEFINED_glMultTransposeMatrixdARB +#define GLEE_C_DEFINED_glMultTransposeMatrixdARB + void __stdcall GLee_Lazy_glMultTransposeMatrixdARB(const GLdouble * m) {if (GLeeInit()) glMultTransposeMatrixdARB(m);} + GLEEPFNGLMULTTRANSPOSEMATRIXDARBPROC GLeeFuncPtr_glMultTransposeMatrixdARB=GLee_Lazy_glMultTransposeMatrixdARB; +#endif +#endif + +/* GL_ARB_multisample */ + +#ifdef __GLEE_GL_ARB_multisample +#ifndef GLEE_C_DEFINED_glSampleCoverageARB +#define GLEE_C_DEFINED_glSampleCoverageARB + void __stdcall GLee_Lazy_glSampleCoverageARB(GLclampf value, GLboolean invert) {if (GLeeInit()) glSampleCoverageARB(value, invert);} + GLEEPFNGLSAMPLECOVERAGEARBPROC GLeeFuncPtr_glSampleCoverageARB=GLee_Lazy_glSampleCoverageARB; +#endif +#endif + +/* GL_ARB_texture_env_add */ + +#ifdef __GLEE_GL_ARB_texture_env_add +#endif + +/* GL_ARB_texture_cube_map */ + +#ifdef __GLEE_GL_ARB_texture_cube_map +#endif + +/* GL_ARB_texture_compression */ + +#ifdef __GLEE_GL_ARB_texture_compression +#ifndef GLEE_C_DEFINED_glCompressedTexImage3DARB +#define GLEE_C_DEFINED_glCompressedTexImage3DARB + void __stdcall GLee_Lazy_glCompressedTexImage3DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexImage3DARB(target, level, internalformat, width, height, depth, border, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXIMAGE3DARBPROC GLeeFuncPtr_glCompressedTexImage3DARB=GLee_Lazy_glCompressedTexImage3DARB; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexImage2DARB +#define GLEE_C_DEFINED_glCompressedTexImage2DARB + void __stdcall GLee_Lazy_glCompressedTexImage2DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexImage2DARB(target, level, internalformat, width, height, border, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC GLeeFuncPtr_glCompressedTexImage2DARB=GLee_Lazy_glCompressedTexImage2DARB; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexImage1DARB +#define GLEE_C_DEFINED_glCompressedTexImage1DARB + void __stdcall GLee_Lazy_glCompressedTexImage1DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexImage1DARB(target, level, internalformat, width, border, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXIMAGE1DARBPROC GLeeFuncPtr_glCompressedTexImage1DARB=GLee_Lazy_glCompressedTexImage1DARB; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexSubImage3DARB +#define GLEE_C_DEFINED_glCompressedTexSubImage3DARB + void __stdcall GLee_Lazy_glCompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC GLeeFuncPtr_glCompressedTexSubImage3DARB=GLee_Lazy_glCompressedTexSubImage3DARB; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexSubImage2DARB +#define GLEE_C_DEFINED_glCompressedTexSubImage2DARB + void __stdcall GLee_Lazy_glCompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC GLeeFuncPtr_glCompressedTexSubImage2DARB=GLee_Lazy_glCompressedTexSubImage2DARB; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTexSubImage1DARB +#define GLEE_C_DEFINED_glCompressedTexSubImage1DARB + void __stdcall GLee_Lazy_glCompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data) {if (GLeeInit()) glCompressedTexSubImage1DARB(target, level, xoffset, width, format, imageSize, data);} + GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC GLeeFuncPtr_glCompressedTexSubImage1DARB=GLee_Lazy_glCompressedTexSubImage1DARB; +#endif +#ifndef GLEE_C_DEFINED_glGetCompressedTexImageARB +#define GLEE_C_DEFINED_glGetCompressedTexImageARB + void __stdcall GLee_Lazy_glGetCompressedTexImageARB(GLenum target, GLint level, GLvoid * img) {if (GLeeInit()) glGetCompressedTexImageARB(target, level, img);} + GLEEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC GLeeFuncPtr_glGetCompressedTexImageARB=GLee_Lazy_glGetCompressedTexImageARB; +#endif +#endif + +/* GL_ARB_texture_border_clamp */ + +#ifdef __GLEE_GL_ARB_texture_border_clamp +#endif + +/* GL_ARB_point_parameters */ + +#ifdef __GLEE_GL_ARB_point_parameters +#ifndef GLEE_C_DEFINED_glPointParameterfARB +#define GLEE_C_DEFINED_glPointParameterfARB + void __stdcall GLee_Lazy_glPointParameterfARB(GLenum pname, GLfloat param) {if (GLeeInit()) glPointParameterfARB(pname, param);} + GLEEPFNGLPOINTPARAMETERFARBPROC GLeeFuncPtr_glPointParameterfARB=GLee_Lazy_glPointParameterfARB; +#endif +#ifndef GLEE_C_DEFINED_glPointParameterfvARB +#define GLEE_C_DEFINED_glPointParameterfvARB + void __stdcall GLee_Lazy_glPointParameterfvARB(GLenum pname, const GLfloat * params) {if (GLeeInit()) glPointParameterfvARB(pname, params);} + GLEEPFNGLPOINTPARAMETERFVARBPROC GLeeFuncPtr_glPointParameterfvARB=GLee_Lazy_glPointParameterfvARB; +#endif +#endif + +/* GL_ARB_vertex_blend */ + +#ifdef __GLEE_GL_ARB_vertex_blend +#ifndef GLEE_C_DEFINED_glWeightbvARB +#define GLEE_C_DEFINED_glWeightbvARB + void __stdcall GLee_Lazy_glWeightbvARB(GLint size, const GLbyte * weights) {if (GLeeInit()) glWeightbvARB(size, weights);} + GLEEPFNGLWEIGHTBVARBPROC GLeeFuncPtr_glWeightbvARB=GLee_Lazy_glWeightbvARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightsvARB +#define GLEE_C_DEFINED_glWeightsvARB + void __stdcall GLee_Lazy_glWeightsvARB(GLint size, const GLshort * weights) {if (GLeeInit()) glWeightsvARB(size, weights);} + GLEEPFNGLWEIGHTSVARBPROC GLeeFuncPtr_glWeightsvARB=GLee_Lazy_glWeightsvARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightivARB +#define GLEE_C_DEFINED_glWeightivARB + void __stdcall GLee_Lazy_glWeightivARB(GLint size, const GLint * weights) {if (GLeeInit()) glWeightivARB(size, weights);} + GLEEPFNGLWEIGHTIVARBPROC GLeeFuncPtr_glWeightivARB=GLee_Lazy_glWeightivARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightfvARB +#define GLEE_C_DEFINED_glWeightfvARB + void __stdcall GLee_Lazy_glWeightfvARB(GLint size, const GLfloat * weights) {if (GLeeInit()) glWeightfvARB(size, weights);} + GLEEPFNGLWEIGHTFVARBPROC GLeeFuncPtr_glWeightfvARB=GLee_Lazy_glWeightfvARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightdvARB +#define GLEE_C_DEFINED_glWeightdvARB + void __stdcall GLee_Lazy_glWeightdvARB(GLint size, const GLdouble * weights) {if (GLeeInit()) glWeightdvARB(size, weights);} + GLEEPFNGLWEIGHTDVARBPROC GLeeFuncPtr_glWeightdvARB=GLee_Lazy_glWeightdvARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightubvARB +#define GLEE_C_DEFINED_glWeightubvARB + void __stdcall GLee_Lazy_glWeightubvARB(GLint size, const GLubyte * weights) {if (GLeeInit()) glWeightubvARB(size, weights);} + GLEEPFNGLWEIGHTUBVARBPROC GLeeFuncPtr_glWeightubvARB=GLee_Lazy_glWeightubvARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightusvARB +#define GLEE_C_DEFINED_glWeightusvARB + void __stdcall GLee_Lazy_glWeightusvARB(GLint size, const GLushort * weights) {if (GLeeInit()) glWeightusvARB(size, weights);} + GLEEPFNGLWEIGHTUSVARBPROC GLeeFuncPtr_glWeightusvARB=GLee_Lazy_glWeightusvARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightuivARB +#define GLEE_C_DEFINED_glWeightuivARB + void __stdcall GLee_Lazy_glWeightuivARB(GLint size, const GLuint * weights) {if (GLeeInit()) glWeightuivARB(size, weights);} + GLEEPFNGLWEIGHTUIVARBPROC GLeeFuncPtr_glWeightuivARB=GLee_Lazy_glWeightuivARB; +#endif +#ifndef GLEE_C_DEFINED_glWeightPointerARB +#define GLEE_C_DEFINED_glWeightPointerARB + void __stdcall GLee_Lazy_glWeightPointerARB(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glWeightPointerARB(size, type, stride, pointer);} + GLEEPFNGLWEIGHTPOINTERARBPROC GLeeFuncPtr_glWeightPointerARB=GLee_Lazy_glWeightPointerARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexBlendARB +#define GLEE_C_DEFINED_glVertexBlendARB + void __stdcall GLee_Lazy_glVertexBlendARB(GLint count) {if (GLeeInit()) glVertexBlendARB(count);} + GLEEPFNGLVERTEXBLENDARBPROC GLeeFuncPtr_glVertexBlendARB=GLee_Lazy_glVertexBlendARB; +#endif +#endif + +/* GL_ARB_matrix_palette */ + +#ifdef __GLEE_GL_ARB_matrix_palette +#ifndef GLEE_C_DEFINED_glCurrentPaletteMatrixARB +#define GLEE_C_DEFINED_glCurrentPaletteMatrixARB + void __stdcall GLee_Lazy_glCurrentPaletteMatrixARB(GLint index) {if (GLeeInit()) glCurrentPaletteMatrixARB(index);} + GLEEPFNGLCURRENTPALETTEMATRIXARBPROC GLeeFuncPtr_glCurrentPaletteMatrixARB=GLee_Lazy_glCurrentPaletteMatrixARB; +#endif +#ifndef GLEE_C_DEFINED_glMatrixIndexubvARB +#define GLEE_C_DEFINED_glMatrixIndexubvARB + void __stdcall GLee_Lazy_glMatrixIndexubvARB(GLint size, const GLubyte * indices) {if (GLeeInit()) glMatrixIndexubvARB(size, indices);} + GLEEPFNGLMATRIXINDEXUBVARBPROC GLeeFuncPtr_glMatrixIndexubvARB=GLee_Lazy_glMatrixIndexubvARB; +#endif +#ifndef GLEE_C_DEFINED_glMatrixIndexusvARB +#define GLEE_C_DEFINED_glMatrixIndexusvARB + void __stdcall GLee_Lazy_glMatrixIndexusvARB(GLint size, const GLushort * indices) {if (GLeeInit()) glMatrixIndexusvARB(size, indices);} + GLEEPFNGLMATRIXINDEXUSVARBPROC GLeeFuncPtr_glMatrixIndexusvARB=GLee_Lazy_glMatrixIndexusvARB; +#endif +#ifndef GLEE_C_DEFINED_glMatrixIndexuivARB +#define GLEE_C_DEFINED_glMatrixIndexuivARB + void __stdcall GLee_Lazy_glMatrixIndexuivARB(GLint size, const GLuint * indices) {if (GLeeInit()) glMatrixIndexuivARB(size, indices);} + GLEEPFNGLMATRIXINDEXUIVARBPROC GLeeFuncPtr_glMatrixIndexuivARB=GLee_Lazy_glMatrixIndexuivARB; +#endif +#ifndef GLEE_C_DEFINED_glMatrixIndexPointerARB +#define GLEE_C_DEFINED_glMatrixIndexPointerARB + void __stdcall GLee_Lazy_glMatrixIndexPointerARB(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glMatrixIndexPointerARB(size, type, stride, pointer);} + GLEEPFNGLMATRIXINDEXPOINTERARBPROC GLeeFuncPtr_glMatrixIndexPointerARB=GLee_Lazy_glMatrixIndexPointerARB; +#endif +#endif + +/* GL_ARB_texture_env_combine */ + +#ifdef __GLEE_GL_ARB_texture_env_combine +#endif + +/* GL_ARB_texture_env_crossbar */ + +#ifdef __GLEE_GL_ARB_texture_env_crossbar +#endif + +/* GL_ARB_texture_env_dot3 */ + +#ifdef __GLEE_GL_ARB_texture_env_dot3 +#endif + +/* GL_ARB_texture_mirrored_repeat */ + +#ifdef __GLEE_GL_ARB_texture_mirrored_repeat +#endif + +/* GL_ARB_depth_texture */ + +#ifdef __GLEE_GL_ARB_depth_texture +#endif + +/* GL_ARB_shadow */ + +#ifdef __GLEE_GL_ARB_shadow +#endif + +/* GL_ARB_shadow_ambient */ + +#ifdef __GLEE_GL_ARB_shadow_ambient +#endif + +/* GL_ARB_window_pos */ + +#ifdef __GLEE_GL_ARB_window_pos +#ifndef GLEE_C_DEFINED_glWindowPos2dARB +#define GLEE_C_DEFINED_glWindowPos2dARB + void __stdcall GLee_Lazy_glWindowPos2dARB(GLdouble x, GLdouble y) {if (GLeeInit()) glWindowPos2dARB(x, y);} + GLEEPFNGLWINDOWPOS2DARBPROC GLeeFuncPtr_glWindowPos2dARB=GLee_Lazy_glWindowPos2dARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2dvARB +#define GLEE_C_DEFINED_glWindowPos2dvARB + void __stdcall GLee_Lazy_glWindowPos2dvARB(const GLdouble * v) {if (GLeeInit()) glWindowPos2dvARB(v);} + GLEEPFNGLWINDOWPOS2DVARBPROC GLeeFuncPtr_glWindowPos2dvARB=GLee_Lazy_glWindowPos2dvARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2fARB +#define GLEE_C_DEFINED_glWindowPos2fARB + void __stdcall GLee_Lazy_glWindowPos2fARB(GLfloat x, GLfloat y) {if (GLeeInit()) glWindowPos2fARB(x, y);} + GLEEPFNGLWINDOWPOS2FARBPROC GLeeFuncPtr_glWindowPos2fARB=GLee_Lazy_glWindowPos2fARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2fvARB +#define GLEE_C_DEFINED_glWindowPos2fvARB + void __stdcall GLee_Lazy_glWindowPos2fvARB(const GLfloat * v) {if (GLeeInit()) glWindowPos2fvARB(v);} + GLEEPFNGLWINDOWPOS2FVARBPROC GLeeFuncPtr_glWindowPos2fvARB=GLee_Lazy_glWindowPos2fvARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2iARB +#define GLEE_C_DEFINED_glWindowPos2iARB + void __stdcall GLee_Lazy_glWindowPos2iARB(GLint x, GLint y) {if (GLeeInit()) glWindowPos2iARB(x, y);} + GLEEPFNGLWINDOWPOS2IARBPROC GLeeFuncPtr_glWindowPos2iARB=GLee_Lazy_glWindowPos2iARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2ivARB +#define GLEE_C_DEFINED_glWindowPos2ivARB + void __stdcall GLee_Lazy_glWindowPos2ivARB(const GLint * v) {if (GLeeInit()) glWindowPos2ivARB(v);} + GLEEPFNGLWINDOWPOS2IVARBPROC GLeeFuncPtr_glWindowPos2ivARB=GLee_Lazy_glWindowPos2ivARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2sARB +#define GLEE_C_DEFINED_glWindowPos2sARB + void __stdcall GLee_Lazy_glWindowPos2sARB(GLshort x, GLshort y) {if (GLeeInit()) glWindowPos2sARB(x, y);} + GLEEPFNGLWINDOWPOS2SARBPROC GLeeFuncPtr_glWindowPos2sARB=GLee_Lazy_glWindowPos2sARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2svARB +#define GLEE_C_DEFINED_glWindowPos2svARB + void __stdcall GLee_Lazy_glWindowPos2svARB(const GLshort * v) {if (GLeeInit()) glWindowPos2svARB(v);} + GLEEPFNGLWINDOWPOS2SVARBPROC GLeeFuncPtr_glWindowPos2svARB=GLee_Lazy_glWindowPos2svARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3dARB +#define GLEE_C_DEFINED_glWindowPos3dARB + void __stdcall GLee_Lazy_glWindowPos3dARB(GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glWindowPos3dARB(x, y, z);} + GLEEPFNGLWINDOWPOS3DARBPROC GLeeFuncPtr_glWindowPos3dARB=GLee_Lazy_glWindowPos3dARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3dvARB +#define GLEE_C_DEFINED_glWindowPos3dvARB + void __stdcall GLee_Lazy_glWindowPos3dvARB(const GLdouble * v) {if (GLeeInit()) glWindowPos3dvARB(v);} + GLEEPFNGLWINDOWPOS3DVARBPROC GLeeFuncPtr_glWindowPos3dvARB=GLee_Lazy_glWindowPos3dvARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3fARB +#define GLEE_C_DEFINED_glWindowPos3fARB + void __stdcall GLee_Lazy_glWindowPos3fARB(GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glWindowPos3fARB(x, y, z);} + GLEEPFNGLWINDOWPOS3FARBPROC GLeeFuncPtr_glWindowPos3fARB=GLee_Lazy_glWindowPos3fARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3fvARB +#define GLEE_C_DEFINED_glWindowPos3fvARB + void __stdcall GLee_Lazy_glWindowPos3fvARB(const GLfloat * v) {if (GLeeInit()) glWindowPos3fvARB(v);} + GLEEPFNGLWINDOWPOS3FVARBPROC GLeeFuncPtr_glWindowPos3fvARB=GLee_Lazy_glWindowPos3fvARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3iARB +#define GLEE_C_DEFINED_glWindowPos3iARB + void __stdcall GLee_Lazy_glWindowPos3iARB(GLint x, GLint y, GLint z) {if (GLeeInit()) glWindowPos3iARB(x, y, z);} + GLEEPFNGLWINDOWPOS3IARBPROC GLeeFuncPtr_glWindowPos3iARB=GLee_Lazy_glWindowPos3iARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3ivARB +#define GLEE_C_DEFINED_glWindowPos3ivARB + void __stdcall GLee_Lazy_glWindowPos3ivARB(const GLint * v) {if (GLeeInit()) glWindowPos3ivARB(v);} + GLEEPFNGLWINDOWPOS3IVARBPROC GLeeFuncPtr_glWindowPos3ivARB=GLee_Lazy_glWindowPos3ivARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3sARB +#define GLEE_C_DEFINED_glWindowPos3sARB + void __stdcall GLee_Lazy_glWindowPos3sARB(GLshort x, GLshort y, GLshort z) {if (GLeeInit()) glWindowPos3sARB(x, y, z);} + GLEEPFNGLWINDOWPOS3SARBPROC GLeeFuncPtr_glWindowPos3sARB=GLee_Lazy_glWindowPos3sARB; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3svARB +#define GLEE_C_DEFINED_glWindowPos3svARB + void __stdcall GLee_Lazy_glWindowPos3svARB(const GLshort * v) {if (GLeeInit()) glWindowPos3svARB(v);} + GLEEPFNGLWINDOWPOS3SVARBPROC GLeeFuncPtr_glWindowPos3svARB=GLee_Lazy_glWindowPos3svARB; +#endif +#endif + +/* GL_ARB_vertex_program */ + +#ifdef __GLEE_GL_ARB_vertex_program +#ifndef GLEE_C_DEFINED_glVertexAttrib1dARB +#define GLEE_C_DEFINED_glVertexAttrib1dARB + void __stdcall GLee_Lazy_glVertexAttrib1dARB(GLuint index, GLdouble x) {if (GLeeInit()) glVertexAttrib1dARB(index, x);} + GLEEPFNGLVERTEXATTRIB1DARBPROC GLeeFuncPtr_glVertexAttrib1dARB=GLee_Lazy_glVertexAttrib1dARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1dvARB +#define GLEE_C_DEFINED_glVertexAttrib1dvARB + void __stdcall GLee_Lazy_glVertexAttrib1dvARB(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib1dvARB(index, v);} + GLEEPFNGLVERTEXATTRIB1DVARBPROC GLeeFuncPtr_glVertexAttrib1dvARB=GLee_Lazy_glVertexAttrib1dvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1fARB +#define GLEE_C_DEFINED_glVertexAttrib1fARB + void __stdcall GLee_Lazy_glVertexAttrib1fARB(GLuint index, GLfloat x) {if (GLeeInit()) glVertexAttrib1fARB(index, x);} + GLEEPFNGLVERTEXATTRIB1FARBPROC GLeeFuncPtr_glVertexAttrib1fARB=GLee_Lazy_glVertexAttrib1fARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1fvARB +#define GLEE_C_DEFINED_glVertexAttrib1fvARB + void __stdcall GLee_Lazy_glVertexAttrib1fvARB(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib1fvARB(index, v);} + GLEEPFNGLVERTEXATTRIB1FVARBPROC GLeeFuncPtr_glVertexAttrib1fvARB=GLee_Lazy_glVertexAttrib1fvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1sARB +#define GLEE_C_DEFINED_glVertexAttrib1sARB + void __stdcall GLee_Lazy_glVertexAttrib1sARB(GLuint index, GLshort x) {if (GLeeInit()) glVertexAttrib1sARB(index, x);} + GLEEPFNGLVERTEXATTRIB1SARBPROC GLeeFuncPtr_glVertexAttrib1sARB=GLee_Lazy_glVertexAttrib1sARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1svARB +#define GLEE_C_DEFINED_glVertexAttrib1svARB + void __stdcall GLee_Lazy_glVertexAttrib1svARB(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib1svARB(index, v);} + GLEEPFNGLVERTEXATTRIB1SVARBPROC GLeeFuncPtr_glVertexAttrib1svARB=GLee_Lazy_glVertexAttrib1svARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2dARB +#define GLEE_C_DEFINED_glVertexAttrib2dARB + void __stdcall GLee_Lazy_glVertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y) {if (GLeeInit()) glVertexAttrib2dARB(index, x, y);} + GLEEPFNGLVERTEXATTRIB2DARBPROC GLeeFuncPtr_glVertexAttrib2dARB=GLee_Lazy_glVertexAttrib2dARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2dvARB +#define GLEE_C_DEFINED_glVertexAttrib2dvARB + void __stdcall GLee_Lazy_glVertexAttrib2dvARB(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib2dvARB(index, v);} + GLEEPFNGLVERTEXATTRIB2DVARBPROC GLeeFuncPtr_glVertexAttrib2dvARB=GLee_Lazy_glVertexAttrib2dvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2fARB +#define GLEE_C_DEFINED_glVertexAttrib2fARB + void __stdcall GLee_Lazy_glVertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) {if (GLeeInit()) glVertexAttrib2fARB(index, x, y);} + GLEEPFNGLVERTEXATTRIB2FARBPROC GLeeFuncPtr_glVertexAttrib2fARB=GLee_Lazy_glVertexAttrib2fARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2fvARB +#define GLEE_C_DEFINED_glVertexAttrib2fvARB + void __stdcall GLee_Lazy_glVertexAttrib2fvARB(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib2fvARB(index, v);} + GLEEPFNGLVERTEXATTRIB2FVARBPROC GLeeFuncPtr_glVertexAttrib2fvARB=GLee_Lazy_glVertexAttrib2fvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2sARB +#define GLEE_C_DEFINED_glVertexAttrib2sARB + void __stdcall GLee_Lazy_glVertexAttrib2sARB(GLuint index, GLshort x, GLshort y) {if (GLeeInit()) glVertexAttrib2sARB(index, x, y);} + GLEEPFNGLVERTEXATTRIB2SARBPROC GLeeFuncPtr_glVertexAttrib2sARB=GLee_Lazy_glVertexAttrib2sARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2svARB +#define GLEE_C_DEFINED_glVertexAttrib2svARB + void __stdcall GLee_Lazy_glVertexAttrib2svARB(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib2svARB(index, v);} + GLEEPFNGLVERTEXATTRIB2SVARBPROC GLeeFuncPtr_glVertexAttrib2svARB=GLee_Lazy_glVertexAttrib2svARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3dARB +#define GLEE_C_DEFINED_glVertexAttrib3dARB + void __stdcall GLee_Lazy_glVertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glVertexAttrib3dARB(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3DARBPROC GLeeFuncPtr_glVertexAttrib3dARB=GLee_Lazy_glVertexAttrib3dARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3dvARB +#define GLEE_C_DEFINED_glVertexAttrib3dvARB + void __stdcall GLee_Lazy_glVertexAttrib3dvARB(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib3dvARB(index, v);} + GLEEPFNGLVERTEXATTRIB3DVARBPROC GLeeFuncPtr_glVertexAttrib3dvARB=GLee_Lazy_glVertexAttrib3dvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3fARB +#define GLEE_C_DEFINED_glVertexAttrib3fARB + void __stdcall GLee_Lazy_glVertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glVertexAttrib3fARB(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3FARBPROC GLeeFuncPtr_glVertexAttrib3fARB=GLee_Lazy_glVertexAttrib3fARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3fvARB +#define GLEE_C_DEFINED_glVertexAttrib3fvARB + void __stdcall GLee_Lazy_glVertexAttrib3fvARB(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib3fvARB(index, v);} + GLEEPFNGLVERTEXATTRIB3FVARBPROC GLeeFuncPtr_glVertexAttrib3fvARB=GLee_Lazy_glVertexAttrib3fvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3sARB +#define GLEE_C_DEFINED_glVertexAttrib3sARB + void __stdcall GLee_Lazy_glVertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z) {if (GLeeInit()) glVertexAttrib3sARB(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3SARBPROC GLeeFuncPtr_glVertexAttrib3sARB=GLee_Lazy_glVertexAttrib3sARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3svARB +#define GLEE_C_DEFINED_glVertexAttrib3svARB + void __stdcall GLee_Lazy_glVertexAttrib3svARB(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib3svARB(index, v);} + GLEEPFNGLVERTEXATTRIB3SVARBPROC GLeeFuncPtr_glVertexAttrib3svARB=GLee_Lazy_glVertexAttrib3svARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4NbvARB +#define GLEE_C_DEFINED_glVertexAttrib4NbvARB + void __stdcall GLee_Lazy_glVertexAttrib4NbvARB(GLuint index, const GLbyte * v) {if (GLeeInit()) glVertexAttrib4NbvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4NBVARBPROC GLeeFuncPtr_glVertexAttrib4NbvARB=GLee_Lazy_glVertexAttrib4NbvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4NivARB +#define GLEE_C_DEFINED_glVertexAttrib4NivARB + void __stdcall GLee_Lazy_glVertexAttrib4NivARB(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttrib4NivARB(index, v);} + GLEEPFNGLVERTEXATTRIB4NIVARBPROC GLeeFuncPtr_glVertexAttrib4NivARB=GLee_Lazy_glVertexAttrib4NivARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4NsvARB +#define GLEE_C_DEFINED_glVertexAttrib4NsvARB + void __stdcall GLee_Lazy_glVertexAttrib4NsvARB(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib4NsvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4NSVARBPROC GLeeFuncPtr_glVertexAttrib4NsvARB=GLee_Lazy_glVertexAttrib4NsvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4NubARB +#define GLEE_C_DEFINED_glVertexAttrib4NubARB + void __stdcall GLee_Lazy_glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {if (GLeeInit()) glVertexAttrib4NubARB(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4NUBARBPROC GLeeFuncPtr_glVertexAttrib4NubARB=GLee_Lazy_glVertexAttrib4NubARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4NubvARB +#define GLEE_C_DEFINED_glVertexAttrib4NubvARB + void __stdcall GLee_Lazy_glVertexAttrib4NubvARB(GLuint index, const GLubyte * v) {if (GLeeInit()) glVertexAttrib4NubvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4NUBVARBPROC GLeeFuncPtr_glVertexAttrib4NubvARB=GLee_Lazy_glVertexAttrib4NubvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4NuivARB +#define GLEE_C_DEFINED_glVertexAttrib4NuivARB + void __stdcall GLee_Lazy_glVertexAttrib4NuivARB(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttrib4NuivARB(index, v);} + GLEEPFNGLVERTEXATTRIB4NUIVARBPROC GLeeFuncPtr_glVertexAttrib4NuivARB=GLee_Lazy_glVertexAttrib4NuivARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4NusvARB +#define GLEE_C_DEFINED_glVertexAttrib4NusvARB + void __stdcall GLee_Lazy_glVertexAttrib4NusvARB(GLuint index, const GLushort * v) {if (GLeeInit()) glVertexAttrib4NusvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4NUSVARBPROC GLeeFuncPtr_glVertexAttrib4NusvARB=GLee_Lazy_glVertexAttrib4NusvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4bvARB +#define GLEE_C_DEFINED_glVertexAttrib4bvARB + void __stdcall GLee_Lazy_glVertexAttrib4bvARB(GLuint index, const GLbyte * v) {if (GLeeInit()) glVertexAttrib4bvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4BVARBPROC GLeeFuncPtr_glVertexAttrib4bvARB=GLee_Lazy_glVertexAttrib4bvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4dARB +#define GLEE_C_DEFINED_glVertexAttrib4dARB + void __stdcall GLee_Lazy_glVertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glVertexAttrib4dARB(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4DARBPROC GLeeFuncPtr_glVertexAttrib4dARB=GLee_Lazy_glVertexAttrib4dARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4dvARB +#define GLEE_C_DEFINED_glVertexAttrib4dvARB + void __stdcall GLee_Lazy_glVertexAttrib4dvARB(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib4dvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4DVARBPROC GLeeFuncPtr_glVertexAttrib4dvARB=GLee_Lazy_glVertexAttrib4dvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4fARB +#define GLEE_C_DEFINED_glVertexAttrib4fARB + void __stdcall GLee_Lazy_glVertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glVertexAttrib4fARB(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4FARBPROC GLeeFuncPtr_glVertexAttrib4fARB=GLee_Lazy_glVertexAttrib4fARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4fvARB +#define GLEE_C_DEFINED_glVertexAttrib4fvARB + void __stdcall GLee_Lazy_glVertexAttrib4fvARB(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib4fvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4FVARBPROC GLeeFuncPtr_glVertexAttrib4fvARB=GLee_Lazy_glVertexAttrib4fvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4ivARB +#define GLEE_C_DEFINED_glVertexAttrib4ivARB + void __stdcall GLee_Lazy_glVertexAttrib4ivARB(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttrib4ivARB(index, v);} + GLEEPFNGLVERTEXATTRIB4IVARBPROC GLeeFuncPtr_glVertexAttrib4ivARB=GLee_Lazy_glVertexAttrib4ivARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4sARB +#define GLEE_C_DEFINED_glVertexAttrib4sARB + void __stdcall GLee_Lazy_glVertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {if (GLeeInit()) glVertexAttrib4sARB(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4SARBPROC GLeeFuncPtr_glVertexAttrib4sARB=GLee_Lazy_glVertexAttrib4sARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4svARB +#define GLEE_C_DEFINED_glVertexAttrib4svARB + void __stdcall GLee_Lazy_glVertexAttrib4svARB(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib4svARB(index, v);} + GLEEPFNGLVERTEXATTRIB4SVARBPROC GLeeFuncPtr_glVertexAttrib4svARB=GLee_Lazy_glVertexAttrib4svARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4ubvARB +#define GLEE_C_DEFINED_glVertexAttrib4ubvARB + void __stdcall GLee_Lazy_glVertexAttrib4ubvARB(GLuint index, const GLubyte * v) {if (GLeeInit()) glVertexAttrib4ubvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4UBVARBPROC GLeeFuncPtr_glVertexAttrib4ubvARB=GLee_Lazy_glVertexAttrib4ubvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4uivARB +#define GLEE_C_DEFINED_glVertexAttrib4uivARB + void __stdcall GLee_Lazy_glVertexAttrib4uivARB(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttrib4uivARB(index, v);} + GLEEPFNGLVERTEXATTRIB4UIVARBPROC GLeeFuncPtr_glVertexAttrib4uivARB=GLee_Lazy_glVertexAttrib4uivARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4usvARB +#define GLEE_C_DEFINED_glVertexAttrib4usvARB + void __stdcall GLee_Lazy_glVertexAttrib4usvARB(GLuint index, const GLushort * v) {if (GLeeInit()) glVertexAttrib4usvARB(index, v);} + GLEEPFNGLVERTEXATTRIB4USVARBPROC GLeeFuncPtr_glVertexAttrib4usvARB=GLee_Lazy_glVertexAttrib4usvARB; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribPointerARB +#define GLEE_C_DEFINED_glVertexAttribPointerARB + void __stdcall GLee_Lazy_glVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexAttribPointerARB(index, size, type, normalized, stride, pointer);} + GLEEPFNGLVERTEXATTRIBPOINTERARBPROC GLeeFuncPtr_glVertexAttribPointerARB=GLee_Lazy_glVertexAttribPointerARB; +#endif +#ifndef GLEE_C_DEFINED_glEnableVertexAttribArrayARB +#define GLEE_C_DEFINED_glEnableVertexAttribArrayARB + void __stdcall GLee_Lazy_glEnableVertexAttribArrayARB(GLuint index) {if (GLeeInit()) glEnableVertexAttribArrayARB(index);} + GLEEPFNGLENABLEVERTEXATTRIBARRAYARBPROC GLeeFuncPtr_glEnableVertexAttribArrayARB=GLee_Lazy_glEnableVertexAttribArrayARB; +#endif +#ifndef GLEE_C_DEFINED_glDisableVertexAttribArrayARB +#define GLEE_C_DEFINED_glDisableVertexAttribArrayARB + void __stdcall GLee_Lazy_glDisableVertexAttribArrayARB(GLuint index) {if (GLeeInit()) glDisableVertexAttribArrayARB(index);} + GLEEPFNGLDISABLEVERTEXATTRIBARRAYARBPROC GLeeFuncPtr_glDisableVertexAttribArrayARB=GLee_Lazy_glDisableVertexAttribArrayARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramStringARB +#define GLEE_C_DEFINED_glProgramStringARB + void __stdcall GLee_Lazy_glProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid * string) {if (GLeeInit()) glProgramStringARB(target, format, len, string);} + GLEEPFNGLPROGRAMSTRINGARBPROC GLeeFuncPtr_glProgramStringARB=GLee_Lazy_glProgramStringARB; +#endif +#ifndef GLEE_C_DEFINED_glBindProgramARB +#define GLEE_C_DEFINED_glBindProgramARB + void __stdcall GLee_Lazy_glBindProgramARB(GLenum target, GLuint program) {if (GLeeInit()) glBindProgramARB(target, program);} + GLEEPFNGLBINDPROGRAMARBPROC GLeeFuncPtr_glBindProgramARB=GLee_Lazy_glBindProgramARB; +#endif +#ifndef GLEE_C_DEFINED_glDeleteProgramsARB +#define GLEE_C_DEFINED_glDeleteProgramsARB + void __stdcall GLee_Lazy_glDeleteProgramsARB(GLsizei n, const GLuint * programs) {if (GLeeInit()) glDeleteProgramsARB(n, programs);} + GLEEPFNGLDELETEPROGRAMSARBPROC GLeeFuncPtr_glDeleteProgramsARB=GLee_Lazy_glDeleteProgramsARB; +#endif +#ifndef GLEE_C_DEFINED_glGenProgramsARB +#define GLEE_C_DEFINED_glGenProgramsARB + void __stdcall GLee_Lazy_glGenProgramsARB(GLsizei n, GLuint * programs) {if (GLeeInit()) glGenProgramsARB(n, programs);} + GLEEPFNGLGENPROGRAMSARBPROC GLeeFuncPtr_glGenProgramsARB=GLee_Lazy_glGenProgramsARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameter4dARB +#define GLEE_C_DEFINED_glProgramEnvParameter4dARB + void __stdcall GLee_Lazy_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glProgramEnvParameter4dARB(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMENVPARAMETER4DARBPROC GLeeFuncPtr_glProgramEnvParameter4dARB=GLee_Lazy_glProgramEnvParameter4dARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameter4dvARB +#define GLEE_C_DEFINED_glProgramEnvParameter4dvARB + void __stdcall GLee_Lazy_glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble * params) {if (GLeeInit()) glProgramEnvParameter4dvARB(target, index, params);} + GLEEPFNGLPROGRAMENVPARAMETER4DVARBPROC GLeeFuncPtr_glProgramEnvParameter4dvARB=GLee_Lazy_glProgramEnvParameter4dvARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameter4fARB +#define GLEE_C_DEFINED_glProgramEnvParameter4fARB + void __stdcall GLee_Lazy_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glProgramEnvParameter4fARB(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMENVPARAMETER4FARBPROC GLeeFuncPtr_glProgramEnvParameter4fARB=GLee_Lazy_glProgramEnvParameter4fARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameter4fvARB +#define GLEE_C_DEFINED_glProgramEnvParameter4fvARB + void __stdcall GLee_Lazy_glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat * params) {if (GLeeInit()) glProgramEnvParameter4fvARB(target, index, params);} + GLEEPFNGLPROGRAMENVPARAMETER4FVARBPROC GLeeFuncPtr_glProgramEnvParameter4fvARB=GLee_Lazy_glProgramEnvParameter4fvARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameter4dARB +#define GLEE_C_DEFINED_glProgramLocalParameter4dARB + void __stdcall GLee_Lazy_glProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glProgramLocalParameter4dARB(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMLOCALPARAMETER4DARBPROC GLeeFuncPtr_glProgramLocalParameter4dARB=GLee_Lazy_glProgramLocalParameter4dARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameter4dvARB +#define GLEE_C_DEFINED_glProgramLocalParameter4dvARB + void __stdcall GLee_Lazy_glProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble * params) {if (GLeeInit()) glProgramLocalParameter4dvARB(target, index, params);} + GLEEPFNGLPROGRAMLOCALPARAMETER4DVARBPROC GLeeFuncPtr_glProgramLocalParameter4dvARB=GLee_Lazy_glProgramLocalParameter4dvARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameter4fARB +#define GLEE_C_DEFINED_glProgramLocalParameter4fARB + void __stdcall GLee_Lazy_glProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glProgramLocalParameter4fARB(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMLOCALPARAMETER4FARBPROC GLeeFuncPtr_glProgramLocalParameter4fARB=GLee_Lazy_glProgramLocalParameter4fARB; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameter4fvARB +#define GLEE_C_DEFINED_glProgramLocalParameter4fvARB + void __stdcall GLee_Lazy_glProgramLocalParameter4fvARB(GLenum target, GLuint index, const GLfloat * params) {if (GLeeInit()) glProgramLocalParameter4fvARB(target, index, params);} + GLEEPFNGLPROGRAMLOCALPARAMETER4FVARBPROC GLeeFuncPtr_glProgramLocalParameter4fvARB=GLee_Lazy_glProgramLocalParameter4fvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramEnvParameterdvARB +#define GLEE_C_DEFINED_glGetProgramEnvParameterdvARB + void __stdcall GLee_Lazy_glGetProgramEnvParameterdvARB(GLenum target, GLuint index, GLdouble * params) {if (GLeeInit()) glGetProgramEnvParameterdvARB(target, index, params);} + GLEEPFNGLGETPROGRAMENVPARAMETERDVARBPROC GLeeFuncPtr_glGetProgramEnvParameterdvARB=GLee_Lazy_glGetProgramEnvParameterdvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramEnvParameterfvARB +#define GLEE_C_DEFINED_glGetProgramEnvParameterfvARB + void __stdcall GLee_Lazy_glGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat * params) {if (GLeeInit()) glGetProgramEnvParameterfvARB(target, index, params);} + GLEEPFNGLGETPROGRAMENVPARAMETERFVARBPROC GLeeFuncPtr_glGetProgramEnvParameterfvARB=GLee_Lazy_glGetProgramEnvParameterfvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramLocalParameterdvARB +#define GLEE_C_DEFINED_glGetProgramLocalParameterdvARB + void __stdcall GLee_Lazy_glGetProgramLocalParameterdvARB(GLenum target, GLuint index, GLdouble * params) {if (GLeeInit()) glGetProgramLocalParameterdvARB(target, index, params);} + GLEEPFNGLGETPROGRAMLOCALPARAMETERDVARBPROC GLeeFuncPtr_glGetProgramLocalParameterdvARB=GLee_Lazy_glGetProgramLocalParameterdvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramLocalParameterfvARB +#define GLEE_C_DEFINED_glGetProgramLocalParameterfvARB + void __stdcall GLee_Lazy_glGetProgramLocalParameterfvARB(GLenum target, GLuint index, GLfloat * params) {if (GLeeInit()) glGetProgramLocalParameterfvARB(target, index, params);} + GLEEPFNGLGETPROGRAMLOCALPARAMETERFVARBPROC GLeeFuncPtr_glGetProgramLocalParameterfvARB=GLee_Lazy_glGetProgramLocalParameterfvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramivARB +#define GLEE_C_DEFINED_glGetProgramivARB + void __stdcall GLee_Lazy_glGetProgramivARB(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetProgramivARB(target, pname, params);} + GLEEPFNGLGETPROGRAMIVARBPROC GLeeFuncPtr_glGetProgramivARB=GLee_Lazy_glGetProgramivARB; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramStringARB +#define GLEE_C_DEFINED_glGetProgramStringARB + void __stdcall GLee_Lazy_glGetProgramStringARB(GLenum target, GLenum pname, GLvoid * string) {if (GLeeInit()) glGetProgramStringARB(target, pname, string);} + GLEEPFNGLGETPROGRAMSTRINGARBPROC GLeeFuncPtr_glGetProgramStringARB=GLee_Lazy_glGetProgramStringARB; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribdvARB +#define GLEE_C_DEFINED_glGetVertexAttribdvARB + void __stdcall GLee_Lazy_glGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble * params) {if (GLeeInit()) glGetVertexAttribdvARB(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBDVARBPROC GLeeFuncPtr_glGetVertexAttribdvARB=GLee_Lazy_glGetVertexAttribdvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribfvARB +#define GLEE_C_DEFINED_glGetVertexAttribfvARB + void __stdcall GLee_Lazy_glGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetVertexAttribfvARB(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBFVARBPROC GLeeFuncPtr_glGetVertexAttribfvARB=GLee_Lazy_glGetVertexAttribfvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribivARB +#define GLEE_C_DEFINED_glGetVertexAttribivARB + void __stdcall GLee_Lazy_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint * params) {if (GLeeInit()) glGetVertexAttribivARB(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBIVARBPROC GLeeFuncPtr_glGetVertexAttribivARB=GLee_Lazy_glGetVertexAttribivARB; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribPointervARB +#define GLEE_C_DEFINED_glGetVertexAttribPointervARB + void __stdcall GLee_Lazy_glGetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid* * pointer) {if (GLeeInit()) glGetVertexAttribPointervARB(index, pname, pointer);} + GLEEPFNGLGETVERTEXATTRIBPOINTERVARBPROC GLeeFuncPtr_glGetVertexAttribPointervARB=GLee_Lazy_glGetVertexAttribPointervARB; +#endif +#ifndef GLEE_C_DEFINED_glIsProgramARB +#define GLEE_C_DEFINED_glIsProgramARB + GLboolean __stdcall GLee_Lazy_glIsProgramARB(GLuint program) {if (GLeeInit()) return glIsProgramARB(program); return (GLboolean)0;} + GLEEPFNGLISPROGRAMARBPROC GLeeFuncPtr_glIsProgramARB=GLee_Lazy_glIsProgramARB; +#endif +#endif + +/* GL_ARB_fragment_program */ + +#ifdef __GLEE_GL_ARB_fragment_program +#endif + +/* GL_ARB_vertex_buffer_object */ + +#ifdef __GLEE_GL_ARB_vertex_buffer_object +#ifndef GLEE_C_DEFINED_glBindBufferARB +#define GLEE_C_DEFINED_glBindBufferARB + void __stdcall GLee_Lazy_glBindBufferARB(GLenum target, GLuint buffer) {if (GLeeInit()) glBindBufferARB(target, buffer);} + GLEEPFNGLBINDBUFFERARBPROC GLeeFuncPtr_glBindBufferARB=GLee_Lazy_glBindBufferARB; +#endif +#ifndef GLEE_C_DEFINED_glDeleteBuffersARB +#define GLEE_C_DEFINED_glDeleteBuffersARB + void __stdcall GLee_Lazy_glDeleteBuffersARB(GLsizei n, const GLuint * buffers) {if (GLeeInit()) glDeleteBuffersARB(n, buffers);} + GLEEPFNGLDELETEBUFFERSARBPROC GLeeFuncPtr_glDeleteBuffersARB=GLee_Lazy_glDeleteBuffersARB; +#endif +#ifndef GLEE_C_DEFINED_glGenBuffersARB +#define GLEE_C_DEFINED_glGenBuffersARB + void __stdcall GLee_Lazy_glGenBuffersARB(GLsizei n, GLuint * buffers) {if (GLeeInit()) glGenBuffersARB(n, buffers);} + GLEEPFNGLGENBUFFERSARBPROC GLeeFuncPtr_glGenBuffersARB=GLee_Lazy_glGenBuffersARB; +#endif +#ifndef GLEE_C_DEFINED_glIsBufferARB +#define GLEE_C_DEFINED_glIsBufferARB + GLboolean __stdcall GLee_Lazy_glIsBufferARB(GLuint buffer) {if (GLeeInit()) return glIsBufferARB(buffer); return (GLboolean)0;} + GLEEPFNGLISBUFFERARBPROC GLeeFuncPtr_glIsBufferARB=GLee_Lazy_glIsBufferARB; +#endif +#ifndef GLEE_C_DEFINED_glBufferDataARB +#define GLEE_C_DEFINED_glBufferDataARB + void __stdcall GLee_Lazy_glBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage) {if (GLeeInit()) glBufferDataARB(target, size, data, usage);} + GLEEPFNGLBUFFERDATAARBPROC GLeeFuncPtr_glBufferDataARB=GLee_Lazy_glBufferDataARB; +#endif +#ifndef GLEE_C_DEFINED_glBufferSubDataARB +#define GLEE_C_DEFINED_glBufferSubDataARB + void __stdcall GLee_Lazy_glBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data) {if (GLeeInit()) glBufferSubDataARB(target, offset, size, data);} + GLEEPFNGLBUFFERSUBDATAARBPROC GLeeFuncPtr_glBufferSubDataARB=GLee_Lazy_glBufferSubDataARB; +#endif +#ifndef GLEE_C_DEFINED_glGetBufferSubDataARB +#define GLEE_C_DEFINED_glGetBufferSubDataARB + void __stdcall GLee_Lazy_glGetBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data) {if (GLeeInit()) glGetBufferSubDataARB(target, offset, size, data);} + GLEEPFNGLGETBUFFERSUBDATAARBPROC GLeeFuncPtr_glGetBufferSubDataARB=GLee_Lazy_glGetBufferSubDataARB; +#endif +#ifndef GLEE_C_DEFINED_glMapBufferARB +#define GLEE_C_DEFINED_glMapBufferARB + GLvoid* __stdcall GLee_Lazy_glMapBufferARB(GLenum target, GLenum access) {if (GLeeInit()) return glMapBufferARB(target, access); return (GLvoid*)0;} + GLEEPFNGLMAPBUFFERARBPROC GLeeFuncPtr_glMapBufferARB=GLee_Lazy_glMapBufferARB; +#endif +#ifndef GLEE_C_DEFINED_glUnmapBufferARB +#define GLEE_C_DEFINED_glUnmapBufferARB + GLboolean __stdcall GLee_Lazy_glUnmapBufferARB(GLenum target) {if (GLeeInit()) return glUnmapBufferARB(target); return (GLboolean)0;} + GLEEPFNGLUNMAPBUFFERARBPROC GLeeFuncPtr_glUnmapBufferARB=GLee_Lazy_glUnmapBufferARB; +#endif +#ifndef GLEE_C_DEFINED_glGetBufferParameterivARB +#define GLEE_C_DEFINED_glGetBufferParameterivARB + void __stdcall GLee_Lazy_glGetBufferParameterivARB(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetBufferParameterivARB(target, pname, params);} + GLEEPFNGLGETBUFFERPARAMETERIVARBPROC GLeeFuncPtr_glGetBufferParameterivARB=GLee_Lazy_glGetBufferParameterivARB; +#endif +#ifndef GLEE_C_DEFINED_glGetBufferPointervARB +#define GLEE_C_DEFINED_glGetBufferPointervARB + void __stdcall GLee_Lazy_glGetBufferPointervARB(GLenum target, GLenum pname, GLvoid* * params) {if (GLeeInit()) glGetBufferPointervARB(target, pname, params);} + GLEEPFNGLGETBUFFERPOINTERVARBPROC GLeeFuncPtr_glGetBufferPointervARB=GLee_Lazy_glGetBufferPointervARB; +#endif +#endif + +/* GL_ARB_occlusion_query */ + +#ifdef __GLEE_GL_ARB_occlusion_query +#ifndef GLEE_C_DEFINED_glGenQueriesARB +#define GLEE_C_DEFINED_glGenQueriesARB + void __stdcall GLee_Lazy_glGenQueriesARB(GLsizei n, GLuint * ids) {if (GLeeInit()) glGenQueriesARB(n, ids);} + GLEEPFNGLGENQUERIESARBPROC GLeeFuncPtr_glGenQueriesARB=GLee_Lazy_glGenQueriesARB; +#endif +#ifndef GLEE_C_DEFINED_glDeleteQueriesARB +#define GLEE_C_DEFINED_glDeleteQueriesARB + void __stdcall GLee_Lazy_glDeleteQueriesARB(GLsizei n, const GLuint * ids) {if (GLeeInit()) glDeleteQueriesARB(n, ids);} + GLEEPFNGLDELETEQUERIESARBPROC GLeeFuncPtr_glDeleteQueriesARB=GLee_Lazy_glDeleteQueriesARB; +#endif +#ifndef GLEE_C_DEFINED_glIsQueryARB +#define GLEE_C_DEFINED_glIsQueryARB + GLboolean __stdcall GLee_Lazy_glIsQueryARB(GLuint id) {if (GLeeInit()) return glIsQueryARB(id); return (GLboolean)0;} + GLEEPFNGLISQUERYARBPROC GLeeFuncPtr_glIsQueryARB=GLee_Lazy_glIsQueryARB; +#endif +#ifndef GLEE_C_DEFINED_glBeginQueryARB +#define GLEE_C_DEFINED_glBeginQueryARB + void __stdcall GLee_Lazy_glBeginQueryARB(GLenum target, GLuint id) {if (GLeeInit()) glBeginQueryARB(target, id);} + GLEEPFNGLBEGINQUERYARBPROC GLeeFuncPtr_glBeginQueryARB=GLee_Lazy_glBeginQueryARB; +#endif +#ifndef GLEE_C_DEFINED_glEndQueryARB +#define GLEE_C_DEFINED_glEndQueryARB + void __stdcall GLee_Lazy_glEndQueryARB(GLenum target) {if (GLeeInit()) glEndQueryARB(target);} + GLEEPFNGLENDQUERYARBPROC GLeeFuncPtr_glEndQueryARB=GLee_Lazy_glEndQueryARB; +#endif +#ifndef GLEE_C_DEFINED_glGetQueryivARB +#define GLEE_C_DEFINED_glGetQueryivARB + void __stdcall GLee_Lazy_glGetQueryivARB(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetQueryivARB(target, pname, params);} + GLEEPFNGLGETQUERYIVARBPROC GLeeFuncPtr_glGetQueryivARB=GLee_Lazy_glGetQueryivARB; +#endif +#ifndef GLEE_C_DEFINED_glGetQueryObjectivARB +#define GLEE_C_DEFINED_glGetQueryObjectivARB + void __stdcall GLee_Lazy_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint * params) {if (GLeeInit()) glGetQueryObjectivARB(id, pname, params);} + GLEEPFNGLGETQUERYOBJECTIVARBPROC GLeeFuncPtr_glGetQueryObjectivARB=GLee_Lazy_glGetQueryObjectivARB; +#endif +#ifndef GLEE_C_DEFINED_glGetQueryObjectuivARB +#define GLEE_C_DEFINED_glGetQueryObjectuivARB + void __stdcall GLee_Lazy_glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint * params) {if (GLeeInit()) glGetQueryObjectuivARB(id, pname, params);} + GLEEPFNGLGETQUERYOBJECTUIVARBPROC GLeeFuncPtr_glGetQueryObjectuivARB=GLee_Lazy_glGetQueryObjectuivARB; +#endif +#endif + +/* GL_ARB_shader_objects */ + +#ifdef __GLEE_GL_ARB_shader_objects +#ifndef GLEE_C_DEFINED_glDeleteObjectARB +#define GLEE_C_DEFINED_glDeleteObjectARB + void __stdcall GLee_Lazy_glDeleteObjectARB(GLhandleARB obj) {if (GLeeInit()) glDeleteObjectARB(obj);} + GLEEPFNGLDELETEOBJECTARBPROC GLeeFuncPtr_glDeleteObjectARB=GLee_Lazy_glDeleteObjectARB; +#endif +#ifndef GLEE_C_DEFINED_glGetHandleARB +#define GLEE_C_DEFINED_glGetHandleARB + GLhandleARB __stdcall GLee_Lazy_glGetHandleARB(GLenum pname) {if (GLeeInit()) return glGetHandleARB(pname); return (GLhandleARB)0;} + GLEEPFNGLGETHANDLEARBPROC GLeeFuncPtr_glGetHandleARB=GLee_Lazy_glGetHandleARB; +#endif +#ifndef GLEE_C_DEFINED_glDetachObjectARB +#define GLEE_C_DEFINED_glDetachObjectARB + void __stdcall GLee_Lazy_glDetachObjectARB(GLhandleARB containerObj, GLhandleARB attachedObj) {if (GLeeInit()) glDetachObjectARB(containerObj, attachedObj);} + GLEEPFNGLDETACHOBJECTARBPROC GLeeFuncPtr_glDetachObjectARB=GLee_Lazy_glDetachObjectARB; +#endif +#ifndef GLEE_C_DEFINED_glCreateShaderObjectARB +#define GLEE_C_DEFINED_glCreateShaderObjectARB + GLhandleARB __stdcall GLee_Lazy_glCreateShaderObjectARB(GLenum shaderType) {if (GLeeInit()) return glCreateShaderObjectARB(shaderType); return (GLhandleARB)0;} + GLEEPFNGLCREATESHADEROBJECTARBPROC GLeeFuncPtr_glCreateShaderObjectARB=GLee_Lazy_glCreateShaderObjectARB; +#endif +#ifndef GLEE_C_DEFINED_glShaderSourceARB +#define GLEE_C_DEFINED_glShaderSourceARB + void __stdcall GLee_Lazy_glShaderSourceARB(GLhandleARB shaderObj, GLsizei count, const GLcharARB* * string, const GLint * length) {if (GLeeInit()) glShaderSourceARB(shaderObj, count, string, length);} + GLEEPFNGLSHADERSOURCEARBPROC GLeeFuncPtr_glShaderSourceARB=GLee_Lazy_glShaderSourceARB; +#endif +#ifndef GLEE_C_DEFINED_glCompileShaderARB +#define GLEE_C_DEFINED_glCompileShaderARB + void __stdcall GLee_Lazy_glCompileShaderARB(GLhandleARB shaderObj) {if (GLeeInit()) glCompileShaderARB(shaderObj);} + GLEEPFNGLCOMPILESHADERARBPROC GLeeFuncPtr_glCompileShaderARB=GLee_Lazy_glCompileShaderARB; +#endif +#ifndef GLEE_C_DEFINED_glCreateProgramObjectARB +#define GLEE_C_DEFINED_glCreateProgramObjectARB + GLhandleARB __stdcall GLee_Lazy_glCreateProgramObjectARB(void) {if (GLeeInit()) return glCreateProgramObjectARB(); return (GLhandleARB)0;} + GLEEPFNGLCREATEPROGRAMOBJECTARBPROC GLeeFuncPtr_glCreateProgramObjectARB=GLee_Lazy_glCreateProgramObjectARB; +#endif +#ifndef GLEE_C_DEFINED_glAttachObjectARB +#define GLEE_C_DEFINED_glAttachObjectARB + void __stdcall GLee_Lazy_glAttachObjectARB(GLhandleARB containerObj, GLhandleARB obj) {if (GLeeInit()) glAttachObjectARB(containerObj, obj);} + GLEEPFNGLATTACHOBJECTARBPROC GLeeFuncPtr_glAttachObjectARB=GLee_Lazy_glAttachObjectARB; +#endif +#ifndef GLEE_C_DEFINED_glLinkProgramARB +#define GLEE_C_DEFINED_glLinkProgramARB + void __stdcall GLee_Lazy_glLinkProgramARB(GLhandleARB programObj) {if (GLeeInit()) glLinkProgramARB(programObj);} + GLEEPFNGLLINKPROGRAMARBPROC GLeeFuncPtr_glLinkProgramARB=GLee_Lazy_glLinkProgramARB; +#endif +#ifndef GLEE_C_DEFINED_glUseProgramObjectARB +#define GLEE_C_DEFINED_glUseProgramObjectARB + void __stdcall GLee_Lazy_glUseProgramObjectARB(GLhandleARB programObj) {if (GLeeInit()) glUseProgramObjectARB(programObj);} + GLEEPFNGLUSEPROGRAMOBJECTARBPROC GLeeFuncPtr_glUseProgramObjectARB=GLee_Lazy_glUseProgramObjectARB; +#endif +#ifndef GLEE_C_DEFINED_glValidateProgramARB +#define GLEE_C_DEFINED_glValidateProgramARB + void __stdcall GLee_Lazy_glValidateProgramARB(GLhandleARB programObj) {if (GLeeInit()) glValidateProgramARB(programObj);} + GLEEPFNGLVALIDATEPROGRAMARBPROC GLeeFuncPtr_glValidateProgramARB=GLee_Lazy_glValidateProgramARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform1fARB +#define GLEE_C_DEFINED_glUniform1fARB + void __stdcall GLee_Lazy_glUniform1fARB(GLint location, GLfloat v0) {if (GLeeInit()) glUniform1fARB(location, v0);} + GLEEPFNGLUNIFORM1FARBPROC GLeeFuncPtr_glUniform1fARB=GLee_Lazy_glUniform1fARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform2fARB +#define GLEE_C_DEFINED_glUniform2fARB + void __stdcall GLee_Lazy_glUniform2fARB(GLint location, GLfloat v0, GLfloat v1) {if (GLeeInit()) glUniform2fARB(location, v0, v1);} + GLEEPFNGLUNIFORM2FARBPROC GLeeFuncPtr_glUniform2fARB=GLee_Lazy_glUniform2fARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform3fARB +#define GLEE_C_DEFINED_glUniform3fARB + void __stdcall GLee_Lazy_glUniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {if (GLeeInit()) glUniform3fARB(location, v0, v1, v2);} + GLEEPFNGLUNIFORM3FARBPROC GLeeFuncPtr_glUniform3fARB=GLee_Lazy_glUniform3fARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform4fARB +#define GLEE_C_DEFINED_glUniform4fARB + void __stdcall GLee_Lazy_glUniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {if (GLeeInit()) glUniform4fARB(location, v0, v1, v2, v3);} + GLEEPFNGLUNIFORM4FARBPROC GLeeFuncPtr_glUniform4fARB=GLee_Lazy_glUniform4fARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform1iARB +#define GLEE_C_DEFINED_glUniform1iARB + void __stdcall GLee_Lazy_glUniform1iARB(GLint location, GLint v0) {if (GLeeInit()) glUniform1iARB(location, v0);} + GLEEPFNGLUNIFORM1IARBPROC GLeeFuncPtr_glUniform1iARB=GLee_Lazy_glUniform1iARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform2iARB +#define GLEE_C_DEFINED_glUniform2iARB + void __stdcall GLee_Lazy_glUniform2iARB(GLint location, GLint v0, GLint v1) {if (GLeeInit()) glUniform2iARB(location, v0, v1);} + GLEEPFNGLUNIFORM2IARBPROC GLeeFuncPtr_glUniform2iARB=GLee_Lazy_glUniform2iARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform3iARB +#define GLEE_C_DEFINED_glUniform3iARB + void __stdcall GLee_Lazy_glUniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) {if (GLeeInit()) glUniform3iARB(location, v0, v1, v2);} + GLEEPFNGLUNIFORM3IARBPROC GLeeFuncPtr_glUniform3iARB=GLee_Lazy_glUniform3iARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform4iARB +#define GLEE_C_DEFINED_glUniform4iARB + void __stdcall GLee_Lazy_glUniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {if (GLeeInit()) glUniform4iARB(location, v0, v1, v2, v3);} + GLEEPFNGLUNIFORM4IARBPROC GLeeFuncPtr_glUniform4iARB=GLee_Lazy_glUniform4iARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform1fvARB +#define GLEE_C_DEFINED_glUniform1fvARB + void __stdcall GLee_Lazy_glUniform1fvARB(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform1fvARB(location, count, value);} + GLEEPFNGLUNIFORM1FVARBPROC GLeeFuncPtr_glUniform1fvARB=GLee_Lazy_glUniform1fvARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform2fvARB +#define GLEE_C_DEFINED_glUniform2fvARB + void __stdcall GLee_Lazy_glUniform2fvARB(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform2fvARB(location, count, value);} + GLEEPFNGLUNIFORM2FVARBPROC GLeeFuncPtr_glUniform2fvARB=GLee_Lazy_glUniform2fvARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform3fvARB +#define GLEE_C_DEFINED_glUniform3fvARB + void __stdcall GLee_Lazy_glUniform3fvARB(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform3fvARB(location, count, value);} + GLEEPFNGLUNIFORM3FVARBPROC GLeeFuncPtr_glUniform3fvARB=GLee_Lazy_glUniform3fvARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform4fvARB +#define GLEE_C_DEFINED_glUniform4fvARB + void __stdcall GLee_Lazy_glUniform4fvARB(GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glUniform4fvARB(location, count, value);} + GLEEPFNGLUNIFORM4FVARBPROC GLeeFuncPtr_glUniform4fvARB=GLee_Lazy_glUniform4fvARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform1ivARB +#define GLEE_C_DEFINED_glUniform1ivARB + void __stdcall GLee_Lazy_glUniform1ivARB(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform1ivARB(location, count, value);} + GLEEPFNGLUNIFORM1IVARBPROC GLeeFuncPtr_glUniform1ivARB=GLee_Lazy_glUniform1ivARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform2ivARB +#define GLEE_C_DEFINED_glUniform2ivARB + void __stdcall GLee_Lazy_glUniform2ivARB(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform2ivARB(location, count, value);} + GLEEPFNGLUNIFORM2IVARBPROC GLeeFuncPtr_glUniform2ivARB=GLee_Lazy_glUniform2ivARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform3ivARB +#define GLEE_C_DEFINED_glUniform3ivARB + void __stdcall GLee_Lazy_glUniform3ivARB(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform3ivARB(location, count, value);} + GLEEPFNGLUNIFORM3IVARBPROC GLeeFuncPtr_glUniform3ivARB=GLee_Lazy_glUniform3ivARB; +#endif +#ifndef GLEE_C_DEFINED_glUniform4ivARB +#define GLEE_C_DEFINED_glUniform4ivARB + void __stdcall GLee_Lazy_glUniform4ivARB(GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glUniform4ivARB(location, count, value);} + GLEEPFNGLUNIFORM4IVARBPROC GLeeFuncPtr_glUniform4ivARB=GLee_Lazy_glUniform4ivARB; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix2fvARB +#define GLEE_C_DEFINED_glUniformMatrix2fvARB + void __stdcall GLee_Lazy_glUniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix2fvARB(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX2FVARBPROC GLeeFuncPtr_glUniformMatrix2fvARB=GLee_Lazy_glUniformMatrix2fvARB; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix3fvARB +#define GLEE_C_DEFINED_glUniformMatrix3fvARB + void __stdcall GLee_Lazy_glUniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix3fvARB(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX3FVARBPROC GLeeFuncPtr_glUniformMatrix3fvARB=GLee_Lazy_glUniformMatrix3fvARB; +#endif +#ifndef GLEE_C_DEFINED_glUniformMatrix4fvARB +#define GLEE_C_DEFINED_glUniformMatrix4fvARB + void __stdcall GLee_Lazy_glUniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glUniformMatrix4fvARB(location, count, transpose, value);} + GLEEPFNGLUNIFORMMATRIX4FVARBPROC GLeeFuncPtr_glUniformMatrix4fvARB=GLee_Lazy_glUniformMatrix4fvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetObjectParameterfvARB +#define GLEE_C_DEFINED_glGetObjectParameterfvARB + void __stdcall GLee_Lazy_glGetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetObjectParameterfvARB(obj, pname, params);} + GLEEPFNGLGETOBJECTPARAMETERFVARBPROC GLeeFuncPtr_glGetObjectParameterfvARB=GLee_Lazy_glGetObjectParameterfvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetObjectParameterivARB +#define GLEE_C_DEFINED_glGetObjectParameterivARB + void __stdcall GLee_Lazy_glGetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params) {if (GLeeInit()) glGetObjectParameterivARB(obj, pname, params);} + GLEEPFNGLGETOBJECTPARAMETERIVARBPROC GLeeFuncPtr_glGetObjectParameterivARB=GLee_Lazy_glGetObjectParameterivARB; +#endif +#ifndef GLEE_C_DEFINED_glGetInfoLogARB +#define GLEE_C_DEFINED_glGetInfoLogARB + void __stdcall GLee_Lazy_glGetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog) {if (GLeeInit()) glGetInfoLogARB(obj, maxLength, length, infoLog);} + GLEEPFNGLGETINFOLOGARBPROC GLeeFuncPtr_glGetInfoLogARB=GLee_Lazy_glGetInfoLogARB; +#endif +#ifndef GLEE_C_DEFINED_glGetAttachedObjectsARB +#define GLEE_C_DEFINED_glGetAttachedObjectsARB + void __stdcall GLee_Lazy_glGetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount, GLsizei * count, GLhandleARB * obj) {if (GLeeInit()) glGetAttachedObjectsARB(containerObj, maxCount, count, obj);} + GLEEPFNGLGETATTACHEDOBJECTSARBPROC GLeeFuncPtr_glGetAttachedObjectsARB=GLee_Lazy_glGetAttachedObjectsARB; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformLocationARB +#define GLEE_C_DEFINED_glGetUniformLocationARB + GLint __stdcall GLee_Lazy_glGetUniformLocationARB(GLhandleARB programObj, const GLcharARB * name) {if (GLeeInit()) return glGetUniformLocationARB(programObj, name); return (GLint)0;} + GLEEPFNGLGETUNIFORMLOCATIONARBPROC GLeeFuncPtr_glGetUniformLocationARB=GLee_Lazy_glGetUniformLocationARB; +#endif +#ifndef GLEE_C_DEFINED_glGetActiveUniformARB +#define GLEE_C_DEFINED_glGetActiveUniformARB + void __stdcall GLee_Lazy_glGetActiveUniformARB(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name) {if (GLeeInit()) glGetActiveUniformARB(programObj, index, maxLength, length, size, type, name);} + GLEEPFNGLGETACTIVEUNIFORMARBPROC GLeeFuncPtr_glGetActiveUniformARB=GLee_Lazy_glGetActiveUniformARB; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformfvARB +#define GLEE_C_DEFINED_glGetUniformfvARB + void __stdcall GLee_Lazy_glGetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params) {if (GLeeInit()) glGetUniformfvARB(programObj, location, params);} + GLEEPFNGLGETUNIFORMFVARBPROC GLeeFuncPtr_glGetUniformfvARB=GLee_Lazy_glGetUniformfvARB; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformivARB +#define GLEE_C_DEFINED_glGetUniformivARB + void __stdcall GLee_Lazy_glGetUniformivARB(GLhandleARB programObj, GLint location, GLint * params) {if (GLeeInit()) glGetUniformivARB(programObj, location, params);} + GLEEPFNGLGETUNIFORMIVARBPROC GLeeFuncPtr_glGetUniformivARB=GLee_Lazy_glGetUniformivARB; +#endif +#ifndef GLEE_C_DEFINED_glGetShaderSourceARB +#define GLEE_C_DEFINED_glGetShaderSourceARB + void __stdcall GLee_Lazy_glGetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source) {if (GLeeInit()) glGetShaderSourceARB(obj, maxLength, length, source);} + GLEEPFNGLGETSHADERSOURCEARBPROC GLeeFuncPtr_glGetShaderSourceARB=GLee_Lazy_glGetShaderSourceARB; +#endif +#endif + +/* GL_ARB_vertex_shader */ + +#ifdef __GLEE_GL_ARB_vertex_shader +#ifndef GLEE_C_DEFINED_glBindAttribLocationARB +#define GLEE_C_DEFINED_glBindAttribLocationARB + void __stdcall GLee_Lazy_glBindAttribLocationARB(GLhandleARB programObj, GLuint index, const GLcharARB * name) {if (GLeeInit()) glBindAttribLocationARB(programObj, index, name);} + GLEEPFNGLBINDATTRIBLOCATIONARBPROC GLeeFuncPtr_glBindAttribLocationARB=GLee_Lazy_glBindAttribLocationARB; +#endif +#ifndef GLEE_C_DEFINED_glGetActiveAttribARB +#define GLEE_C_DEFINED_glGetActiveAttribARB + void __stdcall GLee_Lazy_glGetActiveAttribARB(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name) {if (GLeeInit()) glGetActiveAttribARB(programObj, index, maxLength, length, size, type, name);} + GLEEPFNGLGETACTIVEATTRIBARBPROC GLeeFuncPtr_glGetActiveAttribARB=GLee_Lazy_glGetActiveAttribARB; +#endif +#ifndef GLEE_C_DEFINED_glGetAttribLocationARB +#define GLEE_C_DEFINED_glGetAttribLocationARB + GLint __stdcall GLee_Lazy_glGetAttribLocationARB(GLhandleARB programObj, const GLcharARB * name) {if (GLeeInit()) return glGetAttribLocationARB(programObj, name); return (GLint)0;} + GLEEPFNGLGETATTRIBLOCATIONARBPROC GLeeFuncPtr_glGetAttribLocationARB=GLee_Lazy_glGetAttribLocationARB; +#endif +#endif + +/* GL_ARB_fragment_shader */ + +#ifdef __GLEE_GL_ARB_fragment_shader +#endif + +/* GL_ARB_shading_language_100 */ + +#ifdef __GLEE_GL_ARB_shading_language_100 +#endif + +/* GL_ARB_texture_non_power_of_two */ + +#ifdef __GLEE_GL_ARB_texture_non_power_of_two +#endif + +/* GL_ARB_point_sprite */ + +#ifdef __GLEE_GL_ARB_point_sprite +#endif + +/* GL_ARB_fragment_program_shadow */ + +#ifdef __GLEE_GL_ARB_fragment_program_shadow +#endif + +/* GL_ARB_draw_buffers */ + +#ifdef __GLEE_GL_ARB_draw_buffers +#ifndef GLEE_C_DEFINED_glDrawBuffersARB +#define GLEE_C_DEFINED_glDrawBuffersARB + void __stdcall GLee_Lazy_glDrawBuffersARB(GLsizei n, const GLenum * bufs) {if (GLeeInit()) glDrawBuffersARB(n, bufs);} + GLEEPFNGLDRAWBUFFERSARBPROC GLeeFuncPtr_glDrawBuffersARB=GLee_Lazy_glDrawBuffersARB; +#endif +#endif + +/* GL_ARB_texture_rectangle */ + +#ifdef __GLEE_GL_ARB_texture_rectangle +#endif + +/* GL_ARB_color_buffer_float */ + +#ifdef __GLEE_GL_ARB_color_buffer_float +#ifndef GLEE_C_DEFINED_glClampColorARB +#define GLEE_C_DEFINED_glClampColorARB + void __stdcall GLee_Lazy_glClampColorARB(GLenum target, GLenum clamp) {if (GLeeInit()) glClampColorARB(target, clamp);} + GLEEPFNGLCLAMPCOLORARBPROC GLeeFuncPtr_glClampColorARB=GLee_Lazy_glClampColorARB; +#endif +#endif + +/* GL_ARB_half_float_pixel */ + +#ifdef __GLEE_GL_ARB_half_float_pixel +#endif + +/* GL_ARB_texture_float */ + +#ifdef __GLEE_GL_ARB_texture_float +#endif + +/* GL_ARB_pixel_buffer_object */ + +#ifdef __GLEE_GL_ARB_pixel_buffer_object +#endif + +/* GL_ARB_depth_buffer_float */ + +#ifdef __GLEE_GL_ARB_depth_buffer_float +#endif + +/* GL_ARB_draw_instanced */ + +#ifdef __GLEE_GL_ARB_draw_instanced +#ifndef GLEE_C_DEFINED_glDrawArraysInstancedARB +#define GLEE_C_DEFINED_glDrawArraysInstancedARB + void __stdcall GLee_Lazy_glDrawArraysInstancedARB(GLenum mode, GLint first, GLsizei count, GLsizei primcount) {if (GLeeInit()) glDrawArraysInstancedARB(mode, first, count, primcount);} + GLEEPFNGLDRAWARRAYSINSTANCEDARBPROC GLeeFuncPtr_glDrawArraysInstancedARB=GLee_Lazy_glDrawArraysInstancedARB; +#endif +#ifndef GLEE_C_DEFINED_glDrawElementsInstancedARB +#define GLEE_C_DEFINED_glDrawElementsInstancedARB + void __stdcall GLee_Lazy_glDrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount) {if (GLeeInit()) glDrawElementsInstancedARB(mode, count, type, indices, primcount);} + GLEEPFNGLDRAWELEMENTSINSTANCEDARBPROC GLeeFuncPtr_glDrawElementsInstancedARB=GLee_Lazy_glDrawElementsInstancedARB; +#endif +#endif + +/* GL_ARB_framebuffer_object */ + +#ifdef __GLEE_GL_ARB_framebuffer_object +#ifndef GLEE_C_DEFINED_glIsRenderbuffer +#define GLEE_C_DEFINED_glIsRenderbuffer + GLboolean __stdcall GLee_Lazy_glIsRenderbuffer(GLuint renderbuffer) {if (GLeeInit()) return glIsRenderbuffer(renderbuffer); return (GLboolean)0;} + GLEEPFNGLISRENDERBUFFERPROC GLeeFuncPtr_glIsRenderbuffer=GLee_Lazy_glIsRenderbuffer; +#endif +#ifndef GLEE_C_DEFINED_glBindRenderbuffer +#define GLEE_C_DEFINED_glBindRenderbuffer + void __stdcall GLee_Lazy_glBindRenderbuffer(GLenum target, GLuint renderbuffer) {if (GLeeInit()) glBindRenderbuffer(target, renderbuffer);} + GLEEPFNGLBINDRENDERBUFFERPROC GLeeFuncPtr_glBindRenderbuffer=GLee_Lazy_glBindRenderbuffer; +#endif +#ifndef GLEE_C_DEFINED_glDeleteRenderbuffers +#define GLEE_C_DEFINED_glDeleteRenderbuffers + void __stdcall GLee_Lazy_glDeleteRenderbuffers(GLsizei n, const GLuint * renderbuffers) {if (GLeeInit()) glDeleteRenderbuffers(n, renderbuffers);} + GLEEPFNGLDELETERENDERBUFFERSPROC GLeeFuncPtr_glDeleteRenderbuffers=GLee_Lazy_glDeleteRenderbuffers; +#endif +#ifndef GLEE_C_DEFINED_glGenRenderbuffers +#define GLEE_C_DEFINED_glGenRenderbuffers + void __stdcall GLee_Lazy_glGenRenderbuffers(GLsizei n, GLuint * renderbuffers) {if (GLeeInit()) glGenRenderbuffers(n, renderbuffers);} + GLEEPFNGLGENRENDERBUFFERSPROC GLeeFuncPtr_glGenRenderbuffers=GLee_Lazy_glGenRenderbuffers; +#endif +#ifndef GLEE_C_DEFINED_glRenderbufferStorage +#define GLEE_C_DEFINED_glRenderbufferStorage + void __stdcall GLee_Lazy_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glRenderbufferStorage(target, internalformat, width, height);} + GLEEPFNGLRENDERBUFFERSTORAGEPROC GLeeFuncPtr_glRenderbufferStorage=GLee_Lazy_glRenderbufferStorage; +#endif +#ifndef GLEE_C_DEFINED_glGetRenderbufferParameteriv +#define GLEE_C_DEFINED_glGetRenderbufferParameteriv + void __stdcall GLee_Lazy_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetRenderbufferParameteriv(target, pname, params);} + GLEEPFNGLGETRENDERBUFFERPARAMETERIVPROC GLeeFuncPtr_glGetRenderbufferParameteriv=GLee_Lazy_glGetRenderbufferParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glIsFramebuffer +#define GLEE_C_DEFINED_glIsFramebuffer + GLboolean __stdcall GLee_Lazy_glIsFramebuffer(GLuint framebuffer) {if (GLeeInit()) return glIsFramebuffer(framebuffer); return (GLboolean)0;} + GLEEPFNGLISFRAMEBUFFERPROC GLeeFuncPtr_glIsFramebuffer=GLee_Lazy_glIsFramebuffer; +#endif +#ifndef GLEE_C_DEFINED_glBindFramebuffer +#define GLEE_C_DEFINED_glBindFramebuffer + void __stdcall GLee_Lazy_glBindFramebuffer(GLenum target, GLuint framebuffer) {if (GLeeInit()) glBindFramebuffer(target, framebuffer);} + GLEEPFNGLBINDFRAMEBUFFERPROC GLeeFuncPtr_glBindFramebuffer=GLee_Lazy_glBindFramebuffer; +#endif +#ifndef GLEE_C_DEFINED_glDeleteFramebuffers +#define GLEE_C_DEFINED_glDeleteFramebuffers + void __stdcall GLee_Lazy_glDeleteFramebuffers(GLsizei n, const GLuint * framebuffers) {if (GLeeInit()) glDeleteFramebuffers(n, framebuffers);} + GLEEPFNGLDELETEFRAMEBUFFERSPROC GLeeFuncPtr_glDeleteFramebuffers=GLee_Lazy_glDeleteFramebuffers; +#endif +#ifndef GLEE_C_DEFINED_glGenFramebuffers +#define GLEE_C_DEFINED_glGenFramebuffers + void __stdcall GLee_Lazy_glGenFramebuffers(GLsizei n, GLuint * framebuffers) {if (GLeeInit()) glGenFramebuffers(n, framebuffers);} + GLEEPFNGLGENFRAMEBUFFERSPROC GLeeFuncPtr_glGenFramebuffers=GLee_Lazy_glGenFramebuffers; +#endif +#ifndef GLEE_C_DEFINED_glCheckFramebufferStatus +#define GLEE_C_DEFINED_glCheckFramebufferStatus + GLenum __stdcall GLee_Lazy_glCheckFramebufferStatus(GLenum target) {if (GLeeInit()) return glCheckFramebufferStatus(target); return (GLenum)0;} + GLEEPFNGLCHECKFRAMEBUFFERSTATUSPROC GLeeFuncPtr_glCheckFramebufferStatus=GLee_Lazy_glCheckFramebufferStatus; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTexture1D +#define GLEE_C_DEFINED_glFramebufferTexture1D + void __stdcall GLee_Lazy_glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {if (GLeeInit()) glFramebufferTexture1D(target, attachment, textarget, texture, level);} + GLEEPFNGLFRAMEBUFFERTEXTURE1DPROC GLeeFuncPtr_glFramebufferTexture1D=GLee_Lazy_glFramebufferTexture1D; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTexture2D +#define GLEE_C_DEFINED_glFramebufferTexture2D + void __stdcall GLee_Lazy_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {if (GLeeInit()) glFramebufferTexture2D(target, attachment, textarget, texture, level);} + GLEEPFNGLFRAMEBUFFERTEXTURE2DPROC GLeeFuncPtr_glFramebufferTexture2D=GLee_Lazy_glFramebufferTexture2D; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTexture3D +#define GLEE_C_DEFINED_glFramebufferTexture3D + void __stdcall GLee_Lazy_glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {if (GLeeInit()) glFramebufferTexture3D(target, attachment, textarget, texture, level, zoffset);} + GLEEPFNGLFRAMEBUFFERTEXTURE3DPROC GLeeFuncPtr_glFramebufferTexture3D=GLee_Lazy_glFramebufferTexture3D; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferRenderbuffer +#define GLEE_C_DEFINED_glFramebufferRenderbuffer + void __stdcall GLee_Lazy_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {if (GLeeInit()) glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);} + GLEEPFNGLFRAMEBUFFERRENDERBUFFERPROC GLeeFuncPtr_glFramebufferRenderbuffer=GLee_Lazy_glFramebufferRenderbuffer; +#endif +#ifndef GLEE_C_DEFINED_glGetFramebufferAttachmentParameteriv +#define GLEE_C_DEFINED_glGetFramebufferAttachmentParameteriv + void __stdcall GLee_Lazy_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint * params) {if (GLeeInit()) glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);} + GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GLeeFuncPtr_glGetFramebufferAttachmentParameteriv=GLee_Lazy_glGetFramebufferAttachmentParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glGenerateMipmap +#define GLEE_C_DEFINED_glGenerateMipmap + void __stdcall GLee_Lazy_glGenerateMipmap(GLenum target) {if (GLeeInit()) glGenerateMipmap(target);} + GLEEPFNGLGENERATEMIPMAPPROC GLeeFuncPtr_glGenerateMipmap=GLee_Lazy_glGenerateMipmap; +#endif +#ifndef GLEE_C_DEFINED_glBlitFramebuffer +#define GLEE_C_DEFINED_glBlitFramebuffer + void __stdcall GLee_Lazy_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {if (GLeeInit()) glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);} + GLEEPFNGLBLITFRAMEBUFFERPROC GLeeFuncPtr_glBlitFramebuffer=GLee_Lazy_glBlitFramebuffer; +#endif +#ifndef GLEE_C_DEFINED_glRenderbufferStorageMultisample +#define GLEE_C_DEFINED_glRenderbufferStorageMultisample + void __stdcall GLee_Lazy_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glRenderbufferStorageMultisample(target, samples, internalformat, width, height);} + GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC GLeeFuncPtr_glRenderbufferStorageMultisample=GLee_Lazy_glRenderbufferStorageMultisample; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureLayer +#define GLEE_C_DEFINED_glFramebufferTextureLayer + void __stdcall GLee_Lazy_glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {if (GLeeInit()) glFramebufferTextureLayer(target, attachment, texture, level, layer);} + GLEEPFNGLFRAMEBUFFERTEXTURELAYERPROC GLeeFuncPtr_glFramebufferTextureLayer=GLee_Lazy_glFramebufferTextureLayer; +#endif +#endif + +/* GL_ARB_framebuffer_sRGB */ + +#ifdef __GLEE_GL_ARB_framebuffer_sRGB +#endif + +/* GL_ARB_geometry_shader4 */ + +#ifdef __GLEE_GL_ARB_geometry_shader4 +#ifndef GLEE_C_DEFINED_glProgramParameteriARB +#define GLEE_C_DEFINED_glProgramParameteriARB + void __stdcall GLee_Lazy_glProgramParameteriARB(GLuint program, GLenum pname, GLint value) {if (GLeeInit()) glProgramParameteriARB(program, pname, value);} + GLEEPFNGLPROGRAMPARAMETERIARBPROC GLeeFuncPtr_glProgramParameteriARB=GLee_Lazy_glProgramParameteriARB; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureARB +#define GLEE_C_DEFINED_glFramebufferTextureARB + void __stdcall GLee_Lazy_glFramebufferTextureARB(GLenum target, GLenum attachment, GLuint texture, GLint level) {if (GLeeInit()) glFramebufferTextureARB(target, attachment, texture, level);} + GLEEPFNGLFRAMEBUFFERTEXTUREARBPROC GLeeFuncPtr_glFramebufferTextureARB=GLee_Lazy_glFramebufferTextureARB; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureLayerARB +#define GLEE_C_DEFINED_glFramebufferTextureLayerARB + void __stdcall GLee_Lazy_glFramebufferTextureLayerARB(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {if (GLeeInit()) glFramebufferTextureLayerARB(target, attachment, texture, level, layer);} + GLEEPFNGLFRAMEBUFFERTEXTURELAYERARBPROC GLeeFuncPtr_glFramebufferTextureLayerARB=GLee_Lazy_glFramebufferTextureLayerARB; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureFaceARB +#define GLEE_C_DEFINED_glFramebufferTextureFaceARB + void __stdcall GLee_Lazy_glFramebufferTextureFaceARB(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face) {if (GLeeInit()) glFramebufferTextureFaceARB(target, attachment, texture, level, face);} + GLEEPFNGLFRAMEBUFFERTEXTUREFACEARBPROC GLeeFuncPtr_glFramebufferTextureFaceARB=GLee_Lazy_glFramebufferTextureFaceARB; +#endif +#endif + +/* GL_ARB_half_float_vertex */ + +#ifdef __GLEE_GL_ARB_half_float_vertex +#endif + +/* GL_ARB_instanced_arrays */ + +#ifdef __GLEE_GL_ARB_instanced_arrays +#ifndef GLEE_C_DEFINED_glVertexAttribDivisor +#define GLEE_C_DEFINED_glVertexAttribDivisor + void __stdcall GLee_Lazy_glVertexAttribDivisor(GLuint index, GLuint divisor) {if (GLeeInit()) glVertexAttribDivisor(index, divisor);} + GLEEPFNGLVERTEXATTRIBDIVISORPROC GLeeFuncPtr_glVertexAttribDivisor=GLee_Lazy_glVertexAttribDivisor; +#endif +#endif + +/* GL_ARB_map_buffer_range */ + +#ifdef __GLEE_GL_ARB_map_buffer_range +#ifndef GLEE_C_DEFINED_glMapBufferRange +#define GLEE_C_DEFINED_glMapBufferRange + void __stdcall GLee_Lazy_glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {if (GLeeInit()) glMapBufferRange(target, offset, length, access);} + GLEEPFNGLMAPBUFFERRANGEPROC GLeeFuncPtr_glMapBufferRange=GLee_Lazy_glMapBufferRange; +#endif +#ifndef GLEE_C_DEFINED_glFlushMappedBufferRange +#define GLEE_C_DEFINED_glFlushMappedBufferRange + void __stdcall GLee_Lazy_glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) {if (GLeeInit()) glFlushMappedBufferRange(target, offset, length);} + GLEEPFNGLFLUSHMAPPEDBUFFERRANGEPROC GLeeFuncPtr_glFlushMappedBufferRange=GLee_Lazy_glFlushMappedBufferRange; +#endif +#endif + +/* GL_ARB_texture_buffer_object */ + +#ifdef __GLEE_GL_ARB_texture_buffer_object +#ifndef GLEE_C_DEFINED_glTexBufferARB +#define GLEE_C_DEFINED_glTexBufferARB + void __stdcall GLee_Lazy_glTexBufferARB(GLenum target, GLenum internalformat, GLuint buffer) {if (GLeeInit()) glTexBufferARB(target, internalformat, buffer);} + GLEEPFNGLTEXBUFFERARBPROC GLeeFuncPtr_glTexBufferARB=GLee_Lazy_glTexBufferARB; +#endif +#endif + +/* GL_ARB_texture_compression_rgtc */ + +#ifdef __GLEE_GL_ARB_texture_compression_rgtc +#endif + +/* GL_ARB_texture_rg */ + +#ifdef __GLEE_GL_ARB_texture_rg +#endif + +/* GL_ARB_vertex_array_object */ + +#ifdef __GLEE_GL_ARB_vertex_array_object +#ifndef GLEE_C_DEFINED_glBindVertexArray +#define GLEE_C_DEFINED_glBindVertexArray + void __stdcall GLee_Lazy_glBindVertexArray(GLuint array) {if (GLeeInit()) glBindVertexArray(array);} + GLEEPFNGLBINDVERTEXARRAYPROC GLeeFuncPtr_glBindVertexArray=GLee_Lazy_glBindVertexArray; +#endif +#ifndef GLEE_C_DEFINED_glDeleteVertexArrays +#define GLEE_C_DEFINED_glDeleteVertexArrays + void __stdcall GLee_Lazy_glDeleteVertexArrays(GLsizei n, const GLuint * arrays) {if (GLeeInit()) glDeleteVertexArrays(n, arrays);} + GLEEPFNGLDELETEVERTEXARRAYSPROC GLeeFuncPtr_glDeleteVertexArrays=GLee_Lazy_glDeleteVertexArrays; +#endif +#ifndef GLEE_C_DEFINED_glGenVertexArrays +#define GLEE_C_DEFINED_glGenVertexArrays + void __stdcall GLee_Lazy_glGenVertexArrays(GLsizei n, GLuint * arrays) {if (GLeeInit()) glGenVertexArrays(n, arrays);} + GLEEPFNGLGENVERTEXARRAYSPROC GLeeFuncPtr_glGenVertexArrays=GLee_Lazy_glGenVertexArrays; +#endif +#ifndef GLEE_C_DEFINED_glIsVertexArray +#define GLEE_C_DEFINED_glIsVertexArray + GLboolean __stdcall GLee_Lazy_glIsVertexArray(GLuint array) {if (GLeeInit()) return glIsVertexArray(array); return (GLboolean)0;} + GLEEPFNGLISVERTEXARRAYPROC GLeeFuncPtr_glIsVertexArray=GLee_Lazy_glIsVertexArray; +#endif +#endif + +/* GL_EXT_abgr */ + +#ifdef __GLEE_GL_EXT_abgr +#endif + +/* GL_EXT_blend_color */ + +#ifdef __GLEE_GL_EXT_blend_color +#ifndef GLEE_C_DEFINED_glBlendColorEXT +#define GLEE_C_DEFINED_glBlendColorEXT + void __stdcall GLee_Lazy_glBlendColorEXT(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {if (GLeeInit()) glBlendColorEXT(red, green, blue, alpha);} + GLEEPFNGLBLENDCOLOREXTPROC GLeeFuncPtr_glBlendColorEXT=GLee_Lazy_glBlendColorEXT; +#endif +#endif + +/* GL_EXT_polygon_offset */ + +#ifdef __GLEE_GL_EXT_polygon_offset +#ifndef GLEE_C_DEFINED_glPolygonOffsetEXT +#define GLEE_C_DEFINED_glPolygonOffsetEXT + void __stdcall GLee_Lazy_glPolygonOffsetEXT(GLfloat factor, GLfloat bias) {if (GLeeInit()) glPolygonOffsetEXT(factor, bias);} + GLEEPFNGLPOLYGONOFFSETEXTPROC GLeeFuncPtr_glPolygonOffsetEXT=GLee_Lazy_glPolygonOffsetEXT; +#endif +#endif + +/* GL_EXT_texture */ + +#ifdef __GLEE_GL_EXT_texture +#endif + +/* GL_EXT_texture3D */ + +#ifdef __GLEE_GL_EXT_texture3D +#ifndef GLEE_C_DEFINED_glTexImage3DEXT +#define GLEE_C_DEFINED_glTexImage3DEXT + void __stdcall GLee_Lazy_glTexImage3DEXT(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexImage3DEXT(target, level, internalformat, width, height, depth, border, format, type, pixels);} + GLEEPFNGLTEXIMAGE3DEXTPROC GLeeFuncPtr_glTexImage3DEXT=GLee_Lazy_glTexImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glTexSubImage3DEXT +#define GLEE_C_DEFINED_glTexSubImage3DEXT + void __stdcall GLee_Lazy_glTexSubImage3DEXT(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);} + GLEEPFNGLTEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glTexSubImage3DEXT=GLee_Lazy_glTexSubImage3DEXT; +#endif +#endif + +/* GL_SGIS_texture_filter4 */ + +#ifdef __GLEE_GL_SGIS_texture_filter4 +#ifndef GLEE_C_DEFINED_glGetTexFilterFuncSGIS +#define GLEE_C_DEFINED_glGetTexFilterFuncSGIS + void __stdcall GLee_Lazy_glGetTexFilterFuncSGIS(GLenum target, GLenum filter, GLfloat * weights) {if (GLeeInit()) glGetTexFilterFuncSGIS(target, filter, weights);} + GLEEPFNGLGETTEXFILTERFUNCSGISPROC GLeeFuncPtr_glGetTexFilterFuncSGIS=GLee_Lazy_glGetTexFilterFuncSGIS; +#endif +#ifndef GLEE_C_DEFINED_glTexFilterFuncSGIS +#define GLEE_C_DEFINED_glTexFilterFuncSGIS + void __stdcall GLee_Lazy_glTexFilterFuncSGIS(GLenum target, GLenum filter, GLsizei n, const GLfloat * weights) {if (GLeeInit()) glTexFilterFuncSGIS(target, filter, n, weights);} + GLEEPFNGLTEXFILTERFUNCSGISPROC GLeeFuncPtr_glTexFilterFuncSGIS=GLee_Lazy_glTexFilterFuncSGIS; +#endif +#endif + +/* GL_EXT_subtexture */ + +#ifdef __GLEE_GL_EXT_subtexture +#ifndef GLEE_C_DEFINED_glTexSubImage1DEXT +#define GLEE_C_DEFINED_glTexSubImage1DEXT + void __stdcall GLee_Lazy_glTexSubImage1DEXT(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexSubImage1DEXT(target, level, xoffset, width, format, type, pixels);} + GLEEPFNGLTEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glTexSubImage1DEXT=GLee_Lazy_glTexSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glTexSubImage2DEXT +#define GLEE_C_DEFINED_glTexSubImage2DEXT + void __stdcall GLee_Lazy_glTexSubImage2DEXT(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexSubImage2DEXT(target, level, xoffset, yoffset, width, height, format, type, pixels);} + GLEEPFNGLTEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glTexSubImage2DEXT=GLee_Lazy_glTexSubImage2DEXT; +#endif +#endif + +/* GL_EXT_copy_texture */ + +#ifdef __GLEE_GL_EXT_copy_texture +#ifndef GLEE_C_DEFINED_glCopyTexImage1DEXT +#define GLEE_C_DEFINED_glCopyTexImage1DEXT + void __stdcall GLee_Lazy_glCopyTexImage1DEXT(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {if (GLeeInit()) glCopyTexImage1DEXT(target, level, internalformat, x, y, width, border);} + GLEEPFNGLCOPYTEXIMAGE1DEXTPROC GLeeFuncPtr_glCopyTexImage1DEXT=GLee_Lazy_glCopyTexImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTexImage2DEXT +#define GLEE_C_DEFINED_glCopyTexImage2DEXT + void __stdcall GLee_Lazy_glCopyTexImage2DEXT(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {if (GLeeInit()) glCopyTexImage2DEXT(target, level, internalformat, x, y, width, height, border);} + GLEEPFNGLCOPYTEXIMAGE2DEXTPROC GLeeFuncPtr_glCopyTexImage2DEXT=GLee_Lazy_glCopyTexImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTexSubImage1DEXT +#define GLEE_C_DEFINED_glCopyTexSubImage1DEXT + void __stdcall GLee_Lazy_glCopyTexSubImage1DEXT(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyTexSubImage1DEXT(target, level, xoffset, x, y, width);} + GLEEPFNGLCOPYTEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glCopyTexSubImage1DEXT=GLee_Lazy_glCopyTexSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTexSubImage2DEXT +#define GLEE_C_DEFINED_glCopyTexSubImage2DEXT + void __stdcall GLee_Lazy_glCopyTexSubImage2DEXT(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyTexSubImage2DEXT(target, level, xoffset, yoffset, x, y, width, height);} + GLEEPFNGLCOPYTEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glCopyTexSubImage2DEXT=GLee_Lazy_glCopyTexSubImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTexSubImage3DEXT +#define GLEE_C_DEFINED_glCopyTexSubImage3DEXT + void __stdcall GLee_Lazy_glCopyTexSubImage3DEXT(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyTexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, x, y, width, height);} + GLEEPFNGLCOPYTEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glCopyTexSubImage3DEXT=GLee_Lazy_glCopyTexSubImage3DEXT; +#endif +#endif + +/* GL_EXT_histogram */ + +#ifdef __GLEE_GL_EXT_histogram +#ifndef GLEE_C_DEFINED_glGetHistogramEXT +#define GLEE_C_DEFINED_glGetHistogramEXT + void __stdcall GLee_Lazy_glGetHistogramEXT(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) {if (GLeeInit()) glGetHistogramEXT(target, reset, format, type, values);} + GLEEPFNGLGETHISTOGRAMEXTPROC GLeeFuncPtr_glGetHistogramEXT=GLee_Lazy_glGetHistogramEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetHistogramParameterfvEXT +#define GLEE_C_DEFINED_glGetHistogramParameterfvEXT + void __stdcall GLee_Lazy_glGetHistogramParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetHistogramParameterfvEXT(target, pname, params);} + GLEEPFNGLGETHISTOGRAMPARAMETERFVEXTPROC GLeeFuncPtr_glGetHistogramParameterfvEXT=GLee_Lazy_glGetHistogramParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetHistogramParameterivEXT +#define GLEE_C_DEFINED_glGetHistogramParameterivEXT + void __stdcall GLee_Lazy_glGetHistogramParameterivEXT(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetHistogramParameterivEXT(target, pname, params);} + GLEEPFNGLGETHISTOGRAMPARAMETERIVEXTPROC GLeeFuncPtr_glGetHistogramParameterivEXT=GLee_Lazy_glGetHistogramParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMinmaxEXT +#define GLEE_C_DEFINED_glGetMinmaxEXT + void __stdcall GLee_Lazy_glGetMinmaxEXT(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) {if (GLeeInit()) glGetMinmaxEXT(target, reset, format, type, values);} + GLEEPFNGLGETMINMAXEXTPROC GLeeFuncPtr_glGetMinmaxEXT=GLee_Lazy_glGetMinmaxEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMinmaxParameterfvEXT +#define GLEE_C_DEFINED_glGetMinmaxParameterfvEXT + void __stdcall GLee_Lazy_glGetMinmaxParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMinmaxParameterfvEXT(target, pname, params);} + GLEEPFNGLGETMINMAXPARAMETERFVEXTPROC GLeeFuncPtr_glGetMinmaxParameterfvEXT=GLee_Lazy_glGetMinmaxParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMinmaxParameterivEXT +#define GLEE_C_DEFINED_glGetMinmaxParameterivEXT + void __stdcall GLee_Lazy_glGetMinmaxParameterivEXT(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetMinmaxParameterivEXT(target, pname, params);} + GLEEPFNGLGETMINMAXPARAMETERIVEXTPROC GLeeFuncPtr_glGetMinmaxParameterivEXT=GLee_Lazy_glGetMinmaxParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glHistogramEXT +#define GLEE_C_DEFINED_glHistogramEXT + void __stdcall GLee_Lazy_glHistogramEXT(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) {if (GLeeInit()) glHistogramEXT(target, width, internalformat, sink);} + GLEEPFNGLHISTOGRAMEXTPROC GLeeFuncPtr_glHistogramEXT=GLee_Lazy_glHistogramEXT; +#endif +#ifndef GLEE_C_DEFINED_glMinmaxEXT +#define GLEE_C_DEFINED_glMinmaxEXT + void __stdcall GLee_Lazy_glMinmaxEXT(GLenum target, GLenum internalformat, GLboolean sink) {if (GLeeInit()) glMinmaxEXT(target, internalformat, sink);} + GLEEPFNGLMINMAXEXTPROC GLeeFuncPtr_glMinmaxEXT=GLee_Lazy_glMinmaxEXT; +#endif +#ifndef GLEE_C_DEFINED_glResetHistogramEXT +#define GLEE_C_DEFINED_glResetHistogramEXT + void __stdcall GLee_Lazy_glResetHistogramEXT(GLenum target) {if (GLeeInit()) glResetHistogramEXT(target);} + GLEEPFNGLRESETHISTOGRAMEXTPROC GLeeFuncPtr_glResetHistogramEXT=GLee_Lazy_glResetHistogramEXT; +#endif +#ifndef GLEE_C_DEFINED_glResetMinmaxEXT +#define GLEE_C_DEFINED_glResetMinmaxEXT + void __stdcall GLee_Lazy_glResetMinmaxEXT(GLenum target) {if (GLeeInit()) glResetMinmaxEXT(target);} + GLEEPFNGLRESETMINMAXEXTPROC GLeeFuncPtr_glResetMinmaxEXT=GLee_Lazy_glResetMinmaxEXT; +#endif +#endif + +/* GL_EXT_convolution */ + +#ifdef __GLEE_GL_EXT_convolution +#ifndef GLEE_C_DEFINED_glConvolutionFilter1DEXT +#define GLEE_C_DEFINED_glConvolutionFilter1DEXT + void __stdcall GLee_Lazy_glConvolutionFilter1DEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * image) {if (GLeeInit()) glConvolutionFilter1DEXT(target, internalformat, width, format, type, image);} + GLEEPFNGLCONVOLUTIONFILTER1DEXTPROC GLeeFuncPtr_glConvolutionFilter1DEXT=GLee_Lazy_glConvolutionFilter1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionFilter2DEXT +#define GLEE_C_DEFINED_glConvolutionFilter2DEXT + void __stdcall GLee_Lazy_glConvolutionFilter2DEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * image) {if (GLeeInit()) glConvolutionFilter2DEXT(target, internalformat, width, height, format, type, image);} + GLEEPFNGLCONVOLUTIONFILTER2DEXTPROC GLeeFuncPtr_glConvolutionFilter2DEXT=GLee_Lazy_glConvolutionFilter2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameterfEXT +#define GLEE_C_DEFINED_glConvolutionParameterfEXT + void __stdcall GLee_Lazy_glConvolutionParameterfEXT(GLenum target, GLenum pname, GLfloat params) {if (GLeeInit()) glConvolutionParameterfEXT(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERFEXTPROC GLeeFuncPtr_glConvolutionParameterfEXT=GLee_Lazy_glConvolutionParameterfEXT; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameterfvEXT +#define GLEE_C_DEFINED_glConvolutionParameterfvEXT + void __stdcall GLee_Lazy_glConvolutionParameterfvEXT(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glConvolutionParameterfvEXT(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERFVEXTPROC GLeeFuncPtr_glConvolutionParameterfvEXT=GLee_Lazy_glConvolutionParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameteriEXT +#define GLEE_C_DEFINED_glConvolutionParameteriEXT + void __stdcall GLee_Lazy_glConvolutionParameteriEXT(GLenum target, GLenum pname, GLint params) {if (GLeeInit()) glConvolutionParameteriEXT(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERIEXTPROC GLeeFuncPtr_glConvolutionParameteriEXT=GLee_Lazy_glConvolutionParameteriEXT; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameterivEXT +#define GLEE_C_DEFINED_glConvolutionParameterivEXT + void __stdcall GLee_Lazy_glConvolutionParameterivEXT(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glConvolutionParameterivEXT(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERIVEXTPROC GLeeFuncPtr_glConvolutionParameterivEXT=GLee_Lazy_glConvolutionParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyConvolutionFilter1DEXT +#define GLEE_C_DEFINED_glCopyConvolutionFilter1DEXT + void __stdcall GLee_Lazy_glCopyConvolutionFilter1DEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyConvolutionFilter1DEXT(target, internalformat, x, y, width);} + GLEEPFNGLCOPYCONVOLUTIONFILTER1DEXTPROC GLeeFuncPtr_glCopyConvolutionFilter1DEXT=GLee_Lazy_glCopyConvolutionFilter1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyConvolutionFilter2DEXT +#define GLEE_C_DEFINED_glCopyConvolutionFilter2DEXT + void __stdcall GLee_Lazy_glCopyConvolutionFilter2DEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyConvolutionFilter2DEXT(target, internalformat, x, y, width, height);} + GLEEPFNGLCOPYCONVOLUTIONFILTER2DEXTPROC GLeeFuncPtr_glCopyConvolutionFilter2DEXT=GLee_Lazy_glCopyConvolutionFilter2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetConvolutionFilterEXT +#define GLEE_C_DEFINED_glGetConvolutionFilterEXT + void __stdcall GLee_Lazy_glGetConvolutionFilterEXT(GLenum target, GLenum format, GLenum type, GLvoid * image) {if (GLeeInit()) glGetConvolutionFilterEXT(target, format, type, image);} + GLEEPFNGLGETCONVOLUTIONFILTEREXTPROC GLeeFuncPtr_glGetConvolutionFilterEXT=GLee_Lazy_glGetConvolutionFilterEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetConvolutionParameterfvEXT +#define GLEE_C_DEFINED_glGetConvolutionParameterfvEXT + void __stdcall GLee_Lazy_glGetConvolutionParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetConvolutionParameterfvEXT(target, pname, params);} + GLEEPFNGLGETCONVOLUTIONPARAMETERFVEXTPROC GLeeFuncPtr_glGetConvolutionParameterfvEXT=GLee_Lazy_glGetConvolutionParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetConvolutionParameterivEXT +#define GLEE_C_DEFINED_glGetConvolutionParameterivEXT + void __stdcall GLee_Lazy_glGetConvolutionParameterivEXT(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetConvolutionParameterivEXT(target, pname, params);} + GLEEPFNGLGETCONVOLUTIONPARAMETERIVEXTPROC GLeeFuncPtr_glGetConvolutionParameterivEXT=GLee_Lazy_glGetConvolutionParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetSeparableFilterEXT +#define GLEE_C_DEFINED_glGetSeparableFilterEXT + void __stdcall GLee_Lazy_glGetSeparableFilterEXT(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span) {if (GLeeInit()) glGetSeparableFilterEXT(target, format, type, row, column, span);} + GLEEPFNGLGETSEPARABLEFILTEREXTPROC GLeeFuncPtr_glGetSeparableFilterEXT=GLee_Lazy_glGetSeparableFilterEXT; +#endif +#ifndef GLEE_C_DEFINED_glSeparableFilter2DEXT +#define GLEE_C_DEFINED_glSeparableFilter2DEXT + void __stdcall GLee_Lazy_glSeparableFilter2DEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * row, const GLvoid * column) {if (GLeeInit()) glSeparableFilter2DEXT(target, internalformat, width, height, format, type, row, column);} + GLEEPFNGLSEPARABLEFILTER2DEXTPROC GLeeFuncPtr_glSeparableFilter2DEXT=GLee_Lazy_glSeparableFilter2DEXT; +#endif +#endif + +/* GL_SGI_color_matrix */ + +#ifdef __GLEE_GL_SGI_color_matrix +#endif + +/* GL_SGI_color_table */ + +#ifdef __GLEE_GL_SGI_color_table +#ifndef GLEE_C_DEFINED_glColorTableSGI +#define GLEE_C_DEFINED_glColorTableSGI + void __stdcall GLee_Lazy_glColorTableSGI(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table) {if (GLeeInit()) glColorTableSGI(target, internalformat, width, format, type, table);} + GLEEPFNGLCOLORTABLESGIPROC GLeeFuncPtr_glColorTableSGI=GLee_Lazy_glColorTableSGI; +#endif +#ifndef GLEE_C_DEFINED_glColorTableParameterfvSGI +#define GLEE_C_DEFINED_glColorTableParameterfvSGI + void __stdcall GLee_Lazy_glColorTableParameterfvSGI(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glColorTableParameterfvSGI(target, pname, params);} + GLEEPFNGLCOLORTABLEPARAMETERFVSGIPROC GLeeFuncPtr_glColorTableParameterfvSGI=GLee_Lazy_glColorTableParameterfvSGI; +#endif +#ifndef GLEE_C_DEFINED_glColorTableParameterivSGI +#define GLEE_C_DEFINED_glColorTableParameterivSGI + void __stdcall GLee_Lazy_glColorTableParameterivSGI(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glColorTableParameterivSGI(target, pname, params);} + GLEEPFNGLCOLORTABLEPARAMETERIVSGIPROC GLeeFuncPtr_glColorTableParameterivSGI=GLee_Lazy_glColorTableParameterivSGI; +#endif +#ifndef GLEE_C_DEFINED_glCopyColorTableSGI +#define GLEE_C_DEFINED_glCopyColorTableSGI + void __stdcall GLee_Lazy_glCopyColorTableSGI(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyColorTableSGI(target, internalformat, x, y, width);} + GLEEPFNGLCOPYCOLORTABLESGIPROC GLeeFuncPtr_glCopyColorTableSGI=GLee_Lazy_glCopyColorTableSGI; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableSGI +#define GLEE_C_DEFINED_glGetColorTableSGI + void __stdcall GLee_Lazy_glGetColorTableSGI(GLenum target, GLenum format, GLenum type, GLvoid * table) {if (GLeeInit()) glGetColorTableSGI(target, format, type, table);} + GLEEPFNGLGETCOLORTABLESGIPROC GLeeFuncPtr_glGetColorTableSGI=GLee_Lazy_glGetColorTableSGI; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableParameterfvSGI +#define GLEE_C_DEFINED_glGetColorTableParameterfvSGI + void __stdcall GLee_Lazy_glGetColorTableParameterfvSGI(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetColorTableParameterfvSGI(target, pname, params);} + GLEEPFNGLGETCOLORTABLEPARAMETERFVSGIPROC GLeeFuncPtr_glGetColorTableParameterfvSGI=GLee_Lazy_glGetColorTableParameterfvSGI; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableParameterivSGI +#define GLEE_C_DEFINED_glGetColorTableParameterivSGI + void __stdcall GLee_Lazy_glGetColorTableParameterivSGI(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetColorTableParameterivSGI(target, pname, params);} + GLEEPFNGLGETCOLORTABLEPARAMETERIVSGIPROC GLeeFuncPtr_glGetColorTableParameterivSGI=GLee_Lazy_glGetColorTableParameterivSGI; +#endif +#endif + +/* GL_SGIS_pixel_texture */ + +#ifdef __GLEE_GL_SGIS_pixel_texture +#ifndef GLEE_C_DEFINED_glPixelTexGenParameteriSGIS +#define GLEE_C_DEFINED_glPixelTexGenParameteriSGIS + void __stdcall GLee_Lazy_glPixelTexGenParameteriSGIS(GLenum pname, GLint param) {if (GLeeInit()) glPixelTexGenParameteriSGIS(pname, param);} + GLEEPFNGLPIXELTEXGENPARAMETERISGISPROC GLeeFuncPtr_glPixelTexGenParameteriSGIS=GLee_Lazy_glPixelTexGenParameteriSGIS; +#endif +#ifndef GLEE_C_DEFINED_glPixelTexGenParameterivSGIS +#define GLEE_C_DEFINED_glPixelTexGenParameterivSGIS + void __stdcall GLee_Lazy_glPixelTexGenParameterivSGIS(GLenum pname, const GLint * params) {if (GLeeInit()) glPixelTexGenParameterivSGIS(pname, params);} + GLEEPFNGLPIXELTEXGENPARAMETERIVSGISPROC GLeeFuncPtr_glPixelTexGenParameterivSGIS=GLee_Lazy_glPixelTexGenParameterivSGIS; +#endif +#ifndef GLEE_C_DEFINED_glPixelTexGenParameterfSGIS +#define GLEE_C_DEFINED_glPixelTexGenParameterfSGIS + void __stdcall GLee_Lazy_glPixelTexGenParameterfSGIS(GLenum pname, GLfloat param) {if (GLeeInit()) glPixelTexGenParameterfSGIS(pname, param);} + GLEEPFNGLPIXELTEXGENPARAMETERFSGISPROC GLeeFuncPtr_glPixelTexGenParameterfSGIS=GLee_Lazy_glPixelTexGenParameterfSGIS; +#endif +#ifndef GLEE_C_DEFINED_glPixelTexGenParameterfvSGIS +#define GLEE_C_DEFINED_glPixelTexGenParameterfvSGIS + void __stdcall GLee_Lazy_glPixelTexGenParameterfvSGIS(GLenum pname, const GLfloat * params) {if (GLeeInit()) glPixelTexGenParameterfvSGIS(pname, params);} + GLEEPFNGLPIXELTEXGENPARAMETERFVSGISPROC GLeeFuncPtr_glPixelTexGenParameterfvSGIS=GLee_Lazy_glPixelTexGenParameterfvSGIS; +#endif +#ifndef GLEE_C_DEFINED_glGetPixelTexGenParameterivSGIS +#define GLEE_C_DEFINED_glGetPixelTexGenParameterivSGIS + void __stdcall GLee_Lazy_glGetPixelTexGenParameterivSGIS(GLenum pname, GLint * params) {if (GLeeInit()) glGetPixelTexGenParameterivSGIS(pname, params);} + GLEEPFNGLGETPIXELTEXGENPARAMETERIVSGISPROC GLeeFuncPtr_glGetPixelTexGenParameterivSGIS=GLee_Lazy_glGetPixelTexGenParameterivSGIS; +#endif +#ifndef GLEE_C_DEFINED_glGetPixelTexGenParameterfvSGIS +#define GLEE_C_DEFINED_glGetPixelTexGenParameterfvSGIS + void __stdcall GLee_Lazy_glGetPixelTexGenParameterfvSGIS(GLenum pname, GLfloat * params) {if (GLeeInit()) glGetPixelTexGenParameterfvSGIS(pname, params);} + GLEEPFNGLGETPIXELTEXGENPARAMETERFVSGISPROC GLeeFuncPtr_glGetPixelTexGenParameterfvSGIS=GLee_Lazy_glGetPixelTexGenParameterfvSGIS; +#endif +#endif + +/* GL_SGIX_pixel_texture */ + +#ifdef __GLEE_GL_SGIX_pixel_texture +#ifndef GLEE_C_DEFINED_glPixelTexGenSGIX +#define GLEE_C_DEFINED_glPixelTexGenSGIX + void __stdcall GLee_Lazy_glPixelTexGenSGIX(GLenum mode) {if (GLeeInit()) glPixelTexGenSGIX(mode);} + GLEEPFNGLPIXELTEXGENSGIXPROC GLeeFuncPtr_glPixelTexGenSGIX=GLee_Lazy_glPixelTexGenSGIX; +#endif +#endif + +/* GL_SGIS_texture4D */ + +#ifdef __GLEE_GL_SGIS_texture4D +#ifndef GLEE_C_DEFINED_glTexImage4DSGIS +#define GLEE_C_DEFINED_glTexImage4DSGIS + void __stdcall GLee_Lazy_glTexImage4DSGIS(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexImage4DSGIS(target, level, internalformat, width, height, depth, size4d, border, format, type, pixels);} + GLEEPFNGLTEXIMAGE4DSGISPROC GLeeFuncPtr_glTexImage4DSGIS=GLee_Lazy_glTexImage4DSGIS; +#endif +#ifndef GLEE_C_DEFINED_glTexSubImage4DSGIS +#define GLEE_C_DEFINED_glTexSubImage4DSGIS + void __stdcall GLee_Lazy_glTexSubImage4DSGIS(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTexSubImage4DSGIS(target, level, xoffset, yoffset, zoffset, woffset, width, height, depth, size4d, format, type, pixels);} + GLEEPFNGLTEXSUBIMAGE4DSGISPROC GLeeFuncPtr_glTexSubImage4DSGIS=GLee_Lazy_glTexSubImage4DSGIS; +#endif +#endif + +/* GL_SGI_texture_color_table */ + +#ifdef __GLEE_GL_SGI_texture_color_table +#endif + +/* GL_EXT_cmyka */ + +#ifdef __GLEE_GL_EXT_cmyka +#endif + +/* GL_EXT_texture_object */ + +#ifdef __GLEE_GL_EXT_texture_object +#ifndef GLEE_C_DEFINED_glAreTexturesResidentEXT +#define GLEE_C_DEFINED_glAreTexturesResidentEXT + GLboolean __stdcall GLee_Lazy_glAreTexturesResidentEXT(GLsizei n, const GLuint * textures, GLboolean * residences) {if (GLeeInit()) return glAreTexturesResidentEXT(n, textures, residences); return (GLboolean)0;} + GLEEPFNGLARETEXTURESRESIDENTEXTPROC GLeeFuncPtr_glAreTexturesResidentEXT=GLee_Lazy_glAreTexturesResidentEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindTextureEXT +#define GLEE_C_DEFINED_glBindTextureEXT + void __stdcall GLee_Lazy_glBindTextureEXT(GLenum target, GLuint texture) {if (GLeeInit()) glBindTextureEXT(target, texture);} + GLEEPFNGLBINDTEXTUREEXTPROC GLeeFuncPtr_glBindTextureEXT=GLee_Lazy_glBindTextureEXT; +#endif +#ifndef GLEE_C_DEFINED_glDeleteTexturesEXT +#define GLEE_C_DEFINED_glDeleteTexturesEXT + void __stdcall GLee_Lazy_glDeleteTexturesEXT(GLsizei n, const GLuint * textures) {if (GLeeInit()) glDeleteTexturesEXT(n, textures);} + GLEEPFNGLDELETETEXTURESEXTPROC GLeeFuncPtr_glDeleteTexturesEXT=GLee_Lazy_glDeleteTexturesEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenTexturesEXT +#define GLEE_C_DEFINED_glGenTexturesEXT + void __stdcall GLee_Lazy_glGenTexturesEXT(GLsizei n, GLuint * textures) {if (GLeeInit()) glGenTexturesEXT(n, textures);} + GLEEPFNGLGENTEXTURESEXTPROC GLeeFuncPtr_glGenTexturesEXT=GLee_Lazy_glGenTexturesEXT; +#endif +#ifndef GLEE_C_DEFINED_glIsTextureEXT +#define GLEE_C_DEFINED_glIsTextureEXT + GLboolean __stdcall GLee_Lazy_glIsTextureEXT(GLuint texture) {if (GLeeInit()) return glIsTextureEXT(texture); return (GLboolean)0;} + GLEEPFNGLISTEXTUREEXTPROC GLeeFuncPtr_glIsTextureEXT=GLee_Lazy_glIsTextureEXT; +#endif +#ifndef GLEE_C_DEFINED_glPrioritizeTexturesEXT +#define GLEE_C_DEFINED_glPrioritizeTexturesEXT + void __stdcall GLee_Lazy_glPrioritizeTexturesEXT(GLsizei n, const GLuint * textures, const GLclampf * priorities) {if (GLeeInit()) glPrioritizeTexturesEXT(n, textures, priorities);} + GLEEPFNGLPRIORITIZETEXTURESEXTPROC GLeeFuncPtr_glPrioritizeTexturesEXT=GLee_Lazy_glPrioritizeTexturesEXT; +#endif +#endif + +/* GL_SGIS_detail_texture */ + +#ifdef __GLEE_GL_SGIS_detail_texture +#ifndef GLEE_C_DEFINED_glDetailTexFuncSGIS +#define GLEE_C_DEFINED_glDetailTexFuncSGIS + void __stdcall GLee_Lazy_glDetailTexFuncSGIS(GLenum target, GLsizei n, const GLfloat * points) {if (GLeeInit()) glDetailTexFuncSGIS(target, n, points);} + GLEEPFNGLDETAILTEXFUNCSGISPROC GLeeFuncPtr_glDetailTexFuncSGIS=GLee_Lazy_glDetailTexFuncSGIS; +#endif +#ifndef GLEE_C_DEFINED_glGetDetailTexFuncSGIS +#define GLEE_C_DEFINED_glGetDetailTexFuncSGIS + void __stdcall GLee_Lazy_glGetDetailTexFuncSGIS(GLenum target, GLfloat * points) {if (GLeeInit()) glGetDetailTexFuncSGIS(target, points);} + GLEEPFNGLGETDETAILTEXFUNCSGISPROC GLeeFuncPtr_glGetDetailTexFuncSGIS=GLee_Lazy_glGetDetailTexFuncSGIS; +#endif +#endif + +/* GL_SGIS_sharpen_texture */ + +#ifdef __GLEE_GL_SGIS_sharpen_texture +#ifndef GLEE_C_DEFINED_glSharpenTexFuncSGIS +#define GLEE_C_DEFINED_glSharpenTexFuncSGIS + void __stdcall GLee_Lazy_glSharpenTexFuncSGIS(GLenum target, GLsizei n, const GLfloat * points) {if (GLeeInit()) glSharpenTexFuncSGIS(target, n, points);} + GLEEPFNGLSHARPENTEXFUNCSGISPROC GLeeFuncPtr_glSharpenTexFuncSGIS=GLee_Lazy_glSharpenTexFuncSGIS; +#endif +#ifndef GLEE_C_DEFINED_glGetSharpenTexFuncSGIS +#define GLEE_C_DEFINED_glGetSharpenTexFuncSGIS + void __stdcall GLee_Lazy_glGetSharpenTexFuncSGIS(GLenum target, GLfloat * points) {if (GLeeInit()) glGetSharpenTexFuncSGIS(target, points);} + GLEEPFNGLGETSHARPENTEXFUNCSGISPROC GLeeFuncPtr_glGetSharpenTexFuncSGIS=GLee_Lazy_glGetSharpenTexFuncSGIS; +#endif +#endif + +/* GL_EXT_packed_pixels */ + +#ifdef __GLEE_GL_EXT_packed_pixels +#endif + +/* GL_SGIS_texture_lod */ + +#ifdef __GLEE_GL_SGIS_texture_lod +#endif + +/* GL_SGIS_multisample */ + +#ifdef __GLEE_GL_SGIS_multisample +#ifndef GLEE_C_DEFINED_glSampleMaskSGIS +#define GLEE_C_DEFINED_glSampleMaskSGIS + void __stdcall GLee_Lazy_glSampleMaskSGIS(GLclampf value, GLboolean invert) {if (GLeeInit()) glSampleMaskSGIS(value, invert);} + GLEEPFNGLSAMPLEMASKSGISPROC GLeeFuncPtr_glSampleMaskSGIS=GLee_Lazy_glSampleMaskSGIS; +#endif +#ifndef GLEE_C_DEFINED_glSamplePatternSGIS +#define GLEE_C_DEFINED_glSamplePatternSGIS + void __stdcall GLee_Lazy_glSamplePatternSGIS(GLenum pattern) {if (GLeeInit()) glSamplePatternSGIS(pattern);} + GLEEPFNGLSAMPLEPATTERNSGISPROC GLeeFuncPtr_glSamplePatternSGIS=GLee_Lazy_glSamplePatternSGIS; +#endif +#endif + +/* GL_EXT_rescale_normal */ + +#ifdef __GLEE_GL_EXT_rescale_normal +#endif + +/* GL_EXT_vertex_array */ + +#ifdef __GLEE_GL_EXT_vertex_array +#ifndef GLEE_C_DEFINED_glArrayElementEXT +#define GLEE_C_DEFINED_glArrayElementEXT + void __stdcall GLee_Lazy_glArrayElementEXT(GLint i) {if (GLeeInit()) glArrayElementEXT(i);} + GLEEPFNGLARRAYELEMENTEXTPROC GLeeFuncPtr_glArrayElementEXT=GLee_Lazy_glArrayElementEXT; +#endif +#ifndef GLEE_C_DEFINED_glColorPointerEXT +#define GLEE_C_DEFINED_glColorPointerEXT + void __stdcall GLee_Lazy_glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer) {if (GLeeInit()) glColorPointerEXT(size, type, stride, count, pointer);} + GLEEPFNGLCOLORPOINTEREXTPROC GLeeFuncPtr_glColorPointerEXT=GLee_Lazy_glColorPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glDrawArraysEXT +#define GLEE_C_DEFINED_glDrawArraysEXT + void __stdcall GLee_Lazy_glDrawArraysEXT(GLenum mode, GLint first, GLsizei count) {if (GLeeInit()) glDrawArraysEXT(mode, first, count);} + GLEEPFNGLDRAWARRAYSEXTPROC GLeeFuncPtr_glDrawArraysEXT=GLee_Lazy_glDrawArraysEXT; +#endif +#ifndef GLEE_C_DEFINED_glEdgeFlagPointerEXT +#define GLEE_C_DEFINED_glEdgeFlagPointerEXT + void __stdcall GLee_Lazy_glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean * pointer) {if (GLeeInit()) glEdgeFlagPointerEXT(stride, count, pointer);} + GLEEPFNGLEDGEFLAGPOINTEREXTPROC GLeeFuncPtr_glEdgeFlagPointerEXT=GLee_Lazy_glEdgeFlagPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetPointervEXT +#define GLEE_C_DEFINED_glGetPointervEXT + void __stdcall GLee_Lazy_glGetPointervEXT(GLenum pname, GLvoid* * params) {if (GLeeInit()) glGetPointervEXT(pname, params);} + GLEEPFNGLGETPOINTERVEXTPROC GLeeFuncPtr_glGetPointervEXT=GLee_Lazy_glGetPointervEXT; +#endif +#ifndef GLEE_C_DEFINED_glIndexPointerEXT +#define GLEE_C_DEFINED_glIndexPointerEXT + void __stdcall GLee_Lazy_glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer) {if (GLeeInit()) glIndexPointerEXT(type, stride, count, pointer);} + GLEEPFNGLINDEXPOINTEREXTPROC GLeeFuncPtr_glIndexPointerEXT=GLee_Lazy_glIndexPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glNormalPointerEXT +#define GLEE_C_DEFINED_glNormalPointerEXT + void __stdcall GLee_Lazy_glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer) {if (GLeeInit()) glNormalPointerEXT(type, stride, count, pointer);} + GLEEPFNGLNORMALPOINTEREXTPROC GLeeFuncPtr_glNormalPointerEXT=GLee_Lazy_glNormalPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glTexCoordPointerEXT +#define GLEE_C_DEFINED_glTexCoordPointerEXT + void __stdcall GLee_Lazy_glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer) {if (GLeeInit()) glTexCoordPointerEXT(size, type, stride, count, pointer);} + GLEEPFNGLTEXCOORDPOINTEREXTPROC GLeeFuncPtr_glTexCoordPointerEXT=GLee_Lazy_glTexCoordPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexPointerEXT +#define GLEE_C_DEFINED_glVertexPointerEXT + void __stdcall GLee_Lazy_glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer) {if (GLeeInit()) glVertexPointerEXT(size, type, stride, count, pointer);} + GLEEPFNGLVERTEXPOINTEREXTPROC GLeeFuncPtr_glVertexPointerEXT=GLee_Lazy_glVertexPointerEXT; +#endif +#endif + +/* GL_EXT_misc_attribute */ + +#ifdef __GLEE_GL_EXT_misc_attribute +#endif + +/* GL_SGIS_generate_mipmap */ + +#ifdef __GLEE_GL_SGIS_generate_mipmap +#endif + +/* GL_SGIX_clipmap */ + +#ifdef __GLEE_GL_SGIX_clipmap +#endif + +/* GL_SGIX_shadow */ + +#ifdef __GLEE_GL_SGIX_shadow +#endif + +/* GL_SGIS_texture_edge_clamp */ + +#ifdef __GLEE_GL_SGIS_texture_edge_clamp +#endif + +/* GL_SGIS_texture_border_clamp */ + +#ifdef __GLEE_GL_SGIS_texture_border_clamp +#endif + +/* GL_EXT_blend_minmax */ + +#ifdef __GLEE_GL_EXT_blend_minmax +#ifndef GLEE_C_DEFINED_glBlendEquationEXT +#define GLEE_C_DEFINED_glBlendEquationEXT + void __stdcall GLee_Lazy_glBlendEquationEXT(GLenum mode) {if (GLeeInit()) glBlendEquationEXT(mode);} + GLEEPFNGLBLENDEQUATIONEXTPROC GLeeFuncPtr_glBlendEquationEXT=GLee_Lazy_glBlendEquationEXT; +#endif +#endif + +/* GL_EXT_blend_subtract */ + +#ifdef __GLEE_GL_EXT_blend_subtract +#endif + +/* GL_EXT_blend_logic_op */ + +#ifdef __GLEE_GL_EXT_blend_logic_op +#endif + +/* GL_SGIX_interlace */ + +#ifdef __GLEE_GL_SGIX_interlace +#endif + +/* GL_SGIX_pixel_tiles */ + +#ifdef __GLEE_GL_SGIX_pixel_tiles +#endif + +/* GL_SGIS_texture_select */ + +#ifdef __GLEE_GL_SGIS_texture_select +#endif + +/* GL_SGIX_sprite */ + +#ifdef __GLEE_GL_SGIX_sprite +#ifndef GLEE_C_DEFINED_glSpriteParameterfSGIX +#define GLEE_C_DEFINED_glSpriteParameterfSGIX + void __stdcall GLee_Lazy_glSpriteParameterfSGIX(GLenum pname, GLfloat param) {if (GLeeInit()) glSpriteParameterfSGIX(pname, param);} + GLEEPFNGLSPRITEPARAMETERFSGIXPROC GLeeFuncPtr_glSpriteParameterfSGIX=GLee_Lazy_glSpriteParameterfSGIX; +#endif +#ifndef GLEE_C_DEFINED_glSpriteParameterfvSGIX +#define GLEE_C_DEFINED_glSpriteParameterfvSGIX + void __stdcall GLee_Lazy_glSpriteParameterfvSGIX(GLenum pname, const GLfloat * params) {if (GLeeInit()) glSpriteParameterfvSGIX(pname, params);} + GLEEPFNGLSPRITEPARAMETERFVSGIXPROC GLeeFuncPtr_glSpriteParameterfvSGIX=GLee_Lazy_glSpriteParameterfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glSpriteParameteriSGIX +#define GLEE_C_DEFINED_glSpriteParameteriSGIX + void __stdcall GLee_Lazy_glSpriteParameteriSGIX(GLenum pname, GLint param) {if (GLeeInit()) glSpriteParameteriSGIX(pname, param);} + GLEEPFNGLSPRITEPARAMETERISGIXPROC GLeeFuncPtr_glSpriteParameteriSGIX=GLee_Lazy_glSpriteParameteriSGIX; +#endif +#ifndef GLEE_C_DEFINED_glSpriteParameterivSGIX +#define GLEE_C_DEFINED_glSpriteParameterivSGIX + void __stdcall GLee_Lazy_glSpriteParameterivSGIX(GLenum pname, const GLint * params) {if (GLeeInit()) glSpriteParameterivSGIX(pname, params);} + GLEEPFNGLSPRITEPARAMETERIVSGIXPROC GLeeFuncPtr_glSpriteParameterivSGIX=GLee_Lazy_glSpriteParameterivSGIX; +#endif +#endif + +/* GL_SGIX_texture_multi_buffer */ + +#ifdef __GLEE_GL_SGIX_texture_multi_buffer +#endif + +/* GL_EXT_point_parameters */ + +#ifdef __GLEE_GL_EXT_point_parameters +#ifndef GLEE_C_DEFINED_glPointParameterfEXT +#define GLEE_C_DEFINED_glPointParameterfEXT + void __stdcall GLee_Lazy_glPointParameterfEXT(GLenum pname, GLfloat param) {if (GLeeInit()) glPointParameterfEXT(pname, param);} + GLEEPFNGLPOINTPARAMETERFEXTPROC GLeeFuncPtr_glPointParameterfEXT=GLee_Lazy_glPointParameterfEXT; +#endif +#ifndef GLEE_C_DEFINED_glPointParameterfvEXT +#define GLEE_C_DEFINED_glPointParameterfvEXT + void __stdcall GLee_Lazy_glPointParameterfvEXT(GLenum pname, const GLfloat * params) {if (GLeeInit()) glPointParameterfvEXT(pname, params);} + GLEEPFNGLPOINTPARAMETERFVEXTPROC GLeeFuncPtr_glPointParameterfvEXT=GLee_Lazy_glPointParameterfvEXT; +#endif +#endif + +/* GL_SGIS_point_parameters */ + +#ifdef __GLEE_GL_SGIS_point_parameters +#ifndef GLEE_C_DEFINED_glPointParameterfSGIS +#define GLEE_C_DEFINED_glPointParameterfSGIS + void __stdcall GLee_Lazy_glPointParameterfSGIS(GLenum pname, GLfloat param) {if (GLeeInit()) glPointParameterfSGIS(pname, param);} + GLEEPFNGLPOINTPARAMETERFSGISPROC GLeeFuncPtr_glPointParameterfSGIS=GLee_Lazy_glPointParameterfSGIS; +#endif +#ifndef GLEE_C_DEFINED_glPointParameterfvSGIS +#define GLEE_C_DEFINED_glPointParameterfvSGIS + void __stdcall GLee_Lazy_glPointParameterfvSGIS(GLenum pname, const GLfloat * params) {if (GLeeInit()) glPointParameterfvSGIS(pname, params);} + GLEEPFNGLPOINTPARAMETERFVSGISPROC GLeeFuncPtr_glPointParameterfvSGIS=GLee_Lazy_glPointParameterfvSGIS; +#endif +#endif + +/* GL_SGIX_instruments */ + +#ifdef __GLEE_GL_SGIX_instruments +#ifndef GLEE_C_DEFINED_glGetInstrumentsSGIX +#define GLEE_C_DEFINED_glGetInstrumentsSGIX + GLint __stdcall GLee_Lazy_glGetInstrumentsSGIX(void) {if (GLeeInit()) return glGetInstrumentsSGIX(); return (GLint)0;} + GLEEPFNGLGETINSTRUMENTSSGIXPROC GLeeFuncPtr_glGetInstrumentsSGIX=GLee_Lazy_glGetInstrumentsSGIX; +#endif +#ifndef GLEE_C_DEFINED_glInstrumentsBufferSGIX +#define GLEE_C_DEFINED_glInstrumentsBufferSGIX + void __stdcall GLee_Lazy_glInstrumentsBufferSGIX(GLsizei size, GLint * buffer) {if (GLeeInit()) glInstrumentsBufferSGIX(size, buffer);} + GLEEPFNGLINSTRUMENTSBUFFERSGIXPROC GLeeFuncPtr_glInstrumentsBufferSGIX=GLee_Lazy_glInstrumentsBufferSGIX; +#endif +#ifndef GLEE_C_DEFINED_glPollInstrumentsSGIX +#define GLEE_C_DEFINED_glPollInstrumentsSGIX + GLint __stdcall GLee_Lazy_glPollInstrumentsSGIX(GLint * marker_p) {if (GLeeInit()) return glPollInstrumentsSGIX(marker_p); return (GLint)0;} + GLEEPFNGLPOLLINSTRUMENTSSGIXPROC GLeeFuncPtr_glPollInstrumentsSGIX=GLee_Lazy_glPollInstrumentsSGIX; +#endif +#ifndef GLEE_C_DEFINED_glReadInstrumentsSGIX +#define GLEE_C_DEFINED_glReadInstrumentsSGIX + void __stdcall GLee_Lazy_glReadInstrumentsSGIX(GLint marker) {if (GLeeInit()) glReadInstrumentsSGIX(marker);} + GLEEPFNGLREADINSTRUMENTSSGIXPROC GLeeFuncPtr_glReadInstrumentsSGIX=GLee_Lazy_glReadInstrumentsSGIX; +#endif +#ifndef GLEE_C_DEFINED_glStartInstrumentsSGIX +#define GLEE_C_DEFINED_glStartInstrumentsSGIX + void __stdcall GLee_Lazy_glStartInstrumentsSGIX(void) {if (GLeeInit()) glStartInstrumentsSGIX();} + GLEEPFNGLSTARTINSTRUMENTSSGIXPROC GLeeFuncPtr_glStartInstrumentsSGIX=GLee_Lazy_glStartInstrumentsSGIX; +#endif +#ifndef GLEE_C_DEFINED_glStopInstrumentsSGIX +#define GLEE_C_DEFINED_glStopInstrumentsSGIX + void __stdcall GLee_Lazy_glStopInstrumentsSGIX(GLint marker) {if (GLeeInit()) glStopInstrumentsSGIX(marker);} + GLEEPFNGLSTOPINSTRUMENTSSGIXPROC GLeeFuncPtr_glStopInstrumentsSGIX=GLee_Lazy_glStopInstrumentsSGIX; +#endif +#endif + +/* GL_SGIX_texture_scale_bias */ + +#ifdef __GLEE_GL_SGIX_texture_scale_bias +#endif + +/* GL_SGIX_framezoom */ + +#ifdef __GLEE_GL_SGIX_framezoom +#ifndef GLEE_C_DEFINED_glFrameZoomSGIX +#define GLEE_C_DEFINED_glFrameZoomSGIX + void __stdcall GLee_Lazy_glFrameZoomSGIX(GLint factor) {if (GLeeInit()) glFrameZoomSGIX(factor);} + GLEEPFNGLFRAMEZOOMSGIXPROC GLeeFuncPtr_glFrameZoomSGIX=GLee_Lazy_glFrameZoomSGIX; +#endif +#endif + +/* GL_SGIX_tag_sample_buffer */ + +#ifdef __GLEE_GL_SGIX_tag_sample_buffer +#ifndef GLEE_C_DEFINED_glTagSampleBufferSGIX +#define GLEE_C_DEFINED_glTagSampleBufferSGIX + void __stdcall GLee_Lazy_glTagSampleBufferSGIX(void) {if (GLeeInit()) glTagSampleBufferSGIX();} + GLEEPFNGLTAGSAMPLEBUFFERSGIXPROC GLeeFuncPtr_glTagSampleBufferSGIX=GLee_Lazy_glTagSampleBufferSGIX; +#endif +#endif + +/* GL_FfdMaskSGIX */ + +#ifdef __GLEE_GL_FfdMaskSGIX +#endif + +/* GL_SGIX_polynomial_ffd */ + +#ifdef __GLEE_GL_SGIX_polynomial_ffd +#ifndef GLEE_C_DEFINED_glDeformationMap3dSGIX +#define GLEE_C_DEFINED_glDeformationMap3dSGIX + void __stdcall GLee_Lazy_glDeformationMap3dSGIX(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble * points) {if (GLeeInit()) glDeformationMap3dSGIX(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, w1, w2, wstride, worder, points);} + GLEEPFNGLDEFORMATIONMAP3DSGIXPROC GLeeFuncPtr_glDeformationMap3dSGIX=GLee_Lazy_glDeformationMap3dSGIX; +#endif +#ifndef GLEE_C_DEFINED_glDeformationMap3fSGIX +#define GLEE_C_DEFINED_glDeformationMap3fSGIX + void __stdcall GLee_Lazy_glDeformationMap3fSGIX(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat * points) {if (GLeeInit()) glDeformationMap3fSGIX(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, w1, w2, wstride, worder, points);} + GLEEPFNGLDEFORMATIONMAP3FSGIXPROC GLeeFuncPtr_glDeformationMap3fSGIX=GLee_Lazy_glDeformationMap3fSGIX; +#endif +#ifndef GLEE_C_DEFINED_glDeformSGIX +#define GLEE_C_DEFINED_glDeformSGIX + void __stdcall GLee_Lazy_glDeformSGIX(GLbitfield mask) {if (GLeeInit()) glDeformSGIX(mask);} + GLEEPFNGLDEFORMSGIXPROC GLeeFuncPtr_glDeformSGIX=GLee_Lazy_glDeformSGIX; +#endif +#ifndef GLEE_C_DEFINED_glLoadIdentityDeformationMapSGIX +#define GLEE_C_DEFINED_glLoadIdentityDeformationMapSGIX + void __stdcall GLee_Lazy_glLoadIdentityDeformationMapSGIX(GLbitfield mask) {if (GLeeInit()) glLoadIdentityDeformationMapSGIX(mask);} + GLEEPFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC GLeeFuncPtr_glLoadIdentityDeformationMapSGIX=GLee_Lazy_glLoadIdentityDeformationMapSGIX; +#endif +#endif + +/* GL_SGIX_reference_plane */ + +#ifdef __GLEE_GL_SGIX_reference_plane +#ifndef GLEE_C_DEFINED_glReferencePlaneSGIX +#define GLEE_C_DEFINED_glReferencePlaneSGIX + void __stdcall GLee_Lazy_glReferencePlaneSGIX(const GLdouble * equation) {if (GLeeInit()) glReferencePlaneSGIX(equation);} + GLEEPFNGLREFERENCEPLANESGIXPROC GLeeFuncPtr_glReferencePlaneSGIX=GLee_Lazy_glReferencePlaneSGIX; +#endif +#endif + +/* GL_SGIX_flush_raster */ + +#ifdef __GLEE_GL_SGIX_flush_raster +#ifndef GLEE_C_DEFINED_glFlushRasterSGIX +#define GLEE_C_DEFINED_glFlushRasterSGIX + void __stdcall GLee_Lazy_glFlushRasterSGIX(void) {if (GLeeInit()) glFlushRasterSGIX();} + GLEEPFNGLFLUSHRASTERSGIXPROC GLeeFuncPtr_glFlushRasterSGIX=GLee_Lazy_glFlushRasterSGIX; +#endif +#endif + +/* GL_SGIX_depth_texture */ + +#ifdef __GLEE_GL_SGIX_depth_texture +#endif + +/* GL_SGIS_fog_function */ + +#ifdef __GLEE_GL_SGIS_fog_function +#ifndef GLEE_C_DEFINED_glFogFuncSGIS +#define GLEE_C_DEFINED_glFogFuncSGIS + void __stdcall GLee_Lazy_glFogFuncSGIS(GLsizei n, const GLfloat * points) {if (GLeeInit()) glFogFuncSGIS(n, points);} + GLEEPFNGLFOGFUNCSGISPROC GLeeFuncPtr_glFogFuncSGIS=GLee_Lazy_glFogFuncSGIS; +#endif +#ifndef GLEE_C_DEFINED_glGetFogFuncSGIS +#define GLEE_C_DEFINED_glGetFogFuncSGIS + void __stdcall GLee_Lazy_glGetFogFuncSGIS(GLfloat * points) {if (GLeeInit()) glGetFogFuncSGIS(points);} + GLEEPFNGLGETFOGFUNCSGISPROC GLeeFuncPtr_glGetFogFuncSGIS=GLee_Lazy_glGetFogFuncSGIS; +#endif +#endif + +/* GL_SGIX_fog_offset */ + +#ifdef __GLEE_GL_SGIX_fog_offset +#endif + +/* GL_HP_image_transform */ + +#ifdef __GLEE_GL_HP_image_transform +#ifndef GLEE_C_DEFINED_glImageTransformParameteriHP +#define GLEE_C_DEFINED_glImageTransformParameteriHP + void __stdcall GLee_Lazy_glImageTransformParameteriHP(GLenum target, GLenum pname, GLint param) {if (GLeeInit()) glImageTransformParameteriHP(target, pname, param);} + GLEEPFNGLIMAGETRANSFORMPARAMETERIHPPROC GLeeFuncPtr_glImageTransformParameteriHP=GLee_Lazy_glImageTransformParameteriHP; +#endif +#ifndef GLEE_C_DEFINED_glImageTransformParameterfHP +#define GLEE_C_DEFINED_glImageTransformParameterfHP + void __stdcall GLee_Lazy_glImageTransformParameterfHP(GLenum target, GLenum pname, GLfloat param) {if (GLeeInit()) glImageTransformParameterfHP(target, pname, param);} + GLEEPFNGLIMAGETRANSFORMPARAMETERFHPPROC GLeeFuncPtr_glImageTransformParameterfHP=GLee_Lazy_glImageTransformParameterfHP; +#endif +#ifndef GLEE_C_DEFINED_glImageTransformParameterivHP +#define GLEE_C_DEFINED_glImageTransformParameterivHP + void __stdcall GLee_Lazy_glImageTransformParameterivHP(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glImageTransformParameterivHP(target, pname, params);} + GLEEPFNGLIMAGETRANSFORMPARAMETERIVHPPROC GLeeFuncPtr_glImageTransformParameterivHP=GLee_Lazy_glImageTransformParameterivHP; +#endif +#ifndef GLEE_C_DEFINED_glImageTransformParameterfvHP +#define GLEE_C_DEFINED_glImageTransformParameterfvHP + void __stdcall GLee_Lazy_glImageTransformParameterfvHP(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glImageTransformParameterfvHP(target, pname, params);} + GLEEPFNGLIMAGETRANSFORMPARAMETERFVHPPROC GLeeFuncPtr_glImageTransformParameterfvHP=GLee_Lazy_glImageTransformParameterfvHP; +#endif +#ifndef GLEE_C_DEFINED_glGetImageTransformParameterivHP +#define GLEE_C_DEFINED_glGetImageTransformParameterivHP + void __stdcall GLee_Lazy_glGetImageTransformParameterivHP(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetImageTransformParameterivHP(target, pname, params);} + GLEEPFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC GLeeFuncPtr_glGetImageTransformParameterivHP=GLee_Lazy_glGetImageTransformParameterivHP; +#endif +#ifndef GLEE_C_DEFINED_glGetImageTransformParameterfvHP +#define GLEE_C_DEFINED_glGetImageTransformParameterfvHP + void __stdcall GLee_Lazy_glGetImageTransformParameterfvHP(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetImageTransformParameterfvHP(target, pname, params);} + GLEEPFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC GLeeFuncPtr_glGetImageTransformParameterfvHP=GLee_Lazy_glGetImageTransformParameterfvHP; +#endif +#endif + +/* GL_HP_convolution_border_modes */ + +#ifdef __GLEE_GL_HP_convolution_border_modes +#endif + +/* GL_INGR_palette_buffer */ + +#ifdef __GLEE_GL_INGR_palette_buffer +#endif + +/* GL_SGIX_texture_add_env */ + +#ifdef __GLEE_GL_SGIX_texture_add_env +#endif + +/* GL_EXT_color_subtable */ + +#ifdef __GLEE_GL_EXT_color_subtable +#ifndef GLEE_C_DEFINED_glColorSubTableEXT +#define GLEE_C_DEFINED_glColorSubTableEXT + void __stdcall GLee_Lazy_glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid * data) {if (GLeeInit()) glColorSubTableEXT(target, start, count, format, type, data);} + GLEEPFNGLCOLORSUBTABLEEXTPROC GLeeFuncPtr_glColorSubTableEXT=GLee_Lazy_glColorSubTableEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyColorSubTableEXT +#define GLEE_C_DEFINED_glCopyColorSubTableEXT + void __stdcall GLee_Lazy_glCopyColorSubTableEXT(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyColorSubTableEXT(target, start, x, y, width);} + GLEEPFNGLCOPYCOLORSUBTABLEEXTPROC GLeeFuncPtr_glCopyColorSubTableEXT=GLee_Lazy_glCopyColorSubTableEXT; +#endif +#endif + +/* GL_PGI_vertex_hints */ + +#ifdef __GLEE_GL_PGI_vertex_hints +#endif + +/* GL_PGI_misc_hints */ + +#ifdef __GLEE_GL_PGI_misc_hints +#ifndef GLEE_C_DEFINED_glHintPGI +#define GLEE_C_DEFINED_glHintPGI + void __stdcall GLee_Lazy_glHintPGI(GLenum target, GLint mode) {if (GLeeInit()) glHintPGI(target, mode);} + GLEEPFNGLHINTPGIPROC GLeeFuncPtr_glHintPGI=GLee_Lazy_glHintPGI; +#endif +#endif + +/* GL_EXT_paletted_texture */ + +#ifdef __GLEE_GL_EXT_paletted_texture +#ifndef GLEE_C_DEFINED_glColorTableEXT +#define GLEE_C_DEFINED_glColorTableEXT + void __stdcall GLee_Lazy_glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid * table) {if (GLeeInit()) glColorTableEXT(target, internalFormat, width, format, type, table);} + GLEEPFNGLCOLORTABLEEXTPROC GLeeFuncPtr_glColorTableEXT=GLee_Lazy_glColorTableEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableEXT +#define GLEE_C_DEFINED_glGetColorTableEXT + void __stdcall GLee_Lazy_glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * data) {if (GLeeInit()) glGetColorTableEXT(target, format, type, data);} + GLEEPFNGLGETCOLORTABLEEXTPROC GLeeFuncPtr_glGetColorTableEXT=GLee_Lazy_glGetColorTableEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableParameterivEXT +#define GLEE_C_DEFINED_glGetColorTableParameterivEXT + void __stdcall GLee_Lazy_glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetColorTableParameterivEXT(target, pname, params);} + GLEEPFNGLGETCOLORTABLEPARAMETERIVEXTPROC GLeeFuncPtr_glGetColorTableParameterivEXT=GLee_Lazy_glGetColorTableParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetColorTableParameterfvEXT +#define GLEE_C_DEFINED_glGetColorTableParameterfvEXT + void __stdcall GLee_Lazy_glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetColorTableParameterfvEXT(target, pname, params);} + GLEEPFNGLGETCOLORTABLEPARAMETERFVEXTPROC GLeeFuncPtr_glGetColorTableParameterfvEXT=GLee_Lazy_glGetColorTableParameterfvEXT; +#endif +#endif + +/* GL_EXT_clip_volume_hint */ + +#ifdef __GLEE_GL_EXT_clip_volume_hint +#endif + +/* GL_SGIX_list_priority */ + +#ifdef __GLEE_GL_SGIX_list_priority +#ifndef GLEE_C_DEFINED_glGetListParameterfvSGIX +#define GLEE_C_DEFINED_glGetListParameterfvSGIX + void __stdcall GLee_Lazy_glGetListParameterfvSGIX(GLuint list, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetListParameterfvSGIX(list, pname, params);} + GLEEPFNGLGETLISTPARAMETERFVSGIXPROC GLeeFuncPtr_glGetListParameterfvSGIX=GLee_Lazy_glGetListParameterfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glGetListParameterivSGIX +#define GLEE_C_DEFINED_glGetListParameterivSGIX + void __stdcall GLee_Lazy_glGetListParameterivSGIX(GLuint list, GLenum pname, GLint * params) {if (GLeeInit()) glGetListParameterivSGIX(list, pname, params);} + GLEEPFNGLGETLISTPARAMETERIVSGIXPROC GLeeFuncPtr_glGetListParameterivSGIX=GLee_Lazy_glGetListParameterivSGIX; +#endif +#ifndef GLEE_C_DEFINED_glListParameterfSGIX +#define GLEE_C_DEFINED_glListParameterfSGIX + void __stdcall GLee_Lazy_glListParameterfSGIX(GLuint list, GLenum pname, GLfloat param) {if (GLeeInit()) glListParameterfSGIX(list, pname, param);} + GLEEPFNGLLISTPARAMETERFSGIXPROC GLeeFuncPtr_glListParameterfSGIX=GLee_Lazy_glListParameterfSGIX; +#endif +#ifndef GLEE_C_DEFINED_glListParameterfvSGIX +#define GLEE_C_DEFINED_glListParameterfvSGIX + void __stdcall GLee_Lazy_glListParameterfvSGIX(GLuint list, GLenum pname, const GLfloat * params) {if (GLeeInit()) glListParameterfvSGIX(list, pname, params);} + GLEEPFNGLLISTPARAMETERFVSGIXPROC GLeeFuncPtr_glListParameterfvSGIX=GLee_Lazy_glListParameterfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glListParameteriSGIX +#define GLEE_C_DEFINED_glListParameteriSGIX + void __stdcall GLee_Lazy_glListParameteriSGIX(GLuint list, GLenum pname, GLint param) {if (GLeeInit()) glListParameteriSGIX(list, pname, param);} + GLEEPFNGLLISTPARAMETERISGIXPROC GLeeFuncPtr_glListParameteriSGIX=GLee_Lazy_glListParameteriSGIX; +#endif +#ifndef GLEE_C_DEFINED_glListParameterivSGIX +#define GLEE_C_DEFINED_glListParameterivSGIX + void __stdcall GLee_Lazy_glListParameterivSGIX(GLuint list, GLenum pname, const GLint * params) {if (GLeeInit()) glListParameterivSGIX(list, pname, params);} + GLEEPFNGLLISTPARAMETERIVSGIXPROC GLeeFuncPtr_glListParameterivSGIX=GLee_Lazy_glListParameterivSGIX; +#endif +#endif + +/* GL_SGIX_ir_instrument1 */ + +#ifdef __GLEE_GL_SGIX_ir_instrument1 +#endif + +/* GL_SGIX_calligraphic_fragment */ + +#ifdef __GLEE_GL_SGIX_calligraphic_fragment +#endif + +/* GL_SGIX_texture_lod_bias */ + +#ifdef __GLEE_GL_SGIX_texture_lod_bias +#endif + +/* GL_SGIX_shadow_ambient */ + +#ifdef __GLEE_GL_SGIX_shadow_ambient +#endif + +/* GL_EXT_index_texture */ + +#ifdef __GLEE_GL_EXT_index_texture +#endif + +/* GL_EXT_index_material */ + +#ifdef __GLEE_GL_EXT_index_material +#ifndef GLEE_C_DEFINED_glIndexMaterialEXT +#define GLEE_C_DEFINED_glIndexMaterialEXT + void __stdcall GLee_Lazy_glIndexMaterialEXT(GLenum face, GLenum mode) {if (GLeeInit()) glIndexMaterialEXT(face, mode);} + GLEEPFNGLINDEXMATERIALEXTPROC GLeeFuncPtr_glIndexMaterialEXT=GLee_Lazy_glIndexMaterialEXT; +#endif +#endif + +/* GL_EXT_index_func */ + +#ifdef __GLEE_GL_EXT_index_func +#ifndef GLEE_C_DEFINED_glIndexFuncEXT +#define GLEE_C_DEFINED_glIndexFuncEXT + void __stdcall GLee_Lazy_glIndexFuncEXT(GLenum func, GLclampf ref) {if (GLeeInit()) glIndexFuncEXT(func, ref);} + GLEEPFNGLINDEXFUNCEXTPROC GLeeFuncPtr_glIndexFuncEXT=GLee_Lazy_glIndexFuncEXT; +#endif +#endif + +/* GL_EXT_index_array_formats */ + +#ifdef __GLEE_GL_EXT_index_array_formats +#endif + +/* GL_EXT_compiled_vertex_array */ + +#ifdef __GLEE_GL_EXT_compiled_vertex_array +#ifndef GLEE_C_DEFINED_glLockArraysEXT +#define GLEE_C_DEFINED_glLockArraysEXT + void __stdcall GLee_Lazy_glLockArraysEXT(GLint first, GLsizei count) {if (GLeeInit()) glLockArraysEXT(first, count);} + GLEEPFNGLLOCKARRAYSEXTPROC GLeeFuncPtr_glLockArraysEXT=GLee_Lazy_glLockArraysEXT; +#endif +#ifndef GLEE_C_DEFINED_glUnlockArraysEXT +#define GLEE_C_DEFINED_glUnlockArraysEXT + void __stdcall GLee_Lazy_glUnlockArraysEXT(void) {if (GLeeInit()) glUnlockArraysEXT();} + GLEEPFNGLUNLOCKARRAYSEXTPROC GLeeFuncPtr_glUnlockArraysEXT=GLee_Lazy_glUnlockArraysEXT; +#endif +#endif + +/* GL_EXT_cull_vertex */ + +#ifdef __GLEE_GL_EXT_cull_vertex +#ifndef GLEE_C_DEFINED_glCullParameterdvEXT +#define GLEE_C_DEFINED_glCullParameterdvEXT + void __stdcall GLee_Lazy_glCullParameterdvEXT(GLenum pname, GLdouble * params) {if (GLeeInit()) glCullParameterdvEXT(pname, params);} + GLEEPFNGLCULLPARAMETERDVEXTPROC GLeeFuncPtr_glCullParameterdvEXT=GLee_Lazy_glCullParameterdvEXT; +#endif +#ifndef GLEE_C_DEFINED_glCullParameterfvEXT +#define GLEE_C_DEFINED_glCullParameterfvEXT + void __stdcall GLee_Lazy_glCullParameterfvEXT(GLenum pname, GLfloat * params) {if (GLeeInit()) glCullParameterfvEXT(pname, params);} + GLEEPFNGLCULLPARAMETERFVEXTPROC GLeeFuncPtr_glCullParameterfvEXT=GLee_Lazy_glCullParameterfvEXT; +#endif +#endif + +/* GL_SGIX_ycrcb */ + +#ifdef __GLEE_GL_SGIX_ycrcb +#endif + +/* GL_SGIX_fragment_lighting */ + +#ifdef __GLEE_GL_SGIX_fragment_lighting +#ifndef GLEE_C_DEFINED_glFragmentColorMaterialSGIX +#define GLEE_C_DEFINED_glFragmentColorMaterialSGIX + void __stdcall GLee_Lazy_glFragmentColorMaterialSGIX(GLenum face, GLenum mode) {if (GLeeInit()) glFragmentColorMaterialSGIX(face, mode);} + GLEEPFNGLFRAGMENTCOLORMATERIALSGIXPROC GLeeFuncPtr_glFragmentColorMaterialSGIX=GLee_Lazy_glFragmentColorMaterialSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightfSGIX +#define GLEE_C_DEFINED_glFragmentLightfSGIX + void __stdcall GLee_Lazy_glFragmentLightfSGIX(GLenum light, GLenum pname, GLfloat param) {if (GLeeInit()) glFragmentLightfSGIX(light, pname, param);} + GLEEPFNGLFRAGMENTLIGHTFSGIXPROC GLeeFuncPtr_glFragmentLightfSGIX=GLee_Lazy_glFragmentLightfSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightfvSGIX +#define GLEE_C_DEFINED_glFragmentLightfvSGIX + void __stdcall GLee_Lazy_glFragmentLightfvSGIX(GLenum light, GLenum pname, const GLfloat * params) {if (GLeeInit()) glFragmentLightfvSGIX(light, pname, params);} + GLEEPFNGLFRAGMENTLIGHTFVSGIXPROC GLeeFuncPtr_glFragmentLightfvSGIX=GLee_Lazy_glFragmentLightfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightiSGIX +#define GLEE_C_DEFINED_glFragmentLightiSGIX + void __stdcall GLee_Lazy_glFragmentLightiSGIX(GLenum light, GLenum pname, GLint param) {if (GLeeInit()) glFragmentLightiSGIX(light, pname, param);} + GLEEPFNGLFRAGMENTLIGHTISGIXPROC GLeeFuncPtr_glFragmentLightiSGIX=GLee_Lazy_glFragmentLightiSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightivSGIX +#define GLEE_C_DEFINED_glFragmentLightivSGIX + void __stdcall GLee_Lazy_glFragmentLightivSGIX(GLenum light, GLenum pname, const GLint * params) {if (GLeeInit()) glFragmentLightivSGIX(light, pname, params);} + GLEEPFNGLFRAGMENTLIGHTIVSGIXPROC GLeeFuncPtr_glFragmentLightivSGIX=GLee_Lazy_glFragmentLightivSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightModelfSGIX +#define GLEE_C_DEFINED_glFragmentLightModelfSGIX + void __stdcall GLee_Lazy_glFragmentLightModelfSGIX(GLenum pname, GLfloat param) {if (GLeeInit()) glFragmentLightModelfSGIX(pname, param);} + GLEEPFNGLFRAGMENTLIGHTMODELFSGIXPROC GLeeFuncPtr_glFragmentLightModelfSGIX=GLee_Lazy_glFragmentLightModelfSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightModelfvSGIX +#define GLEE_C_DEFINED_glFragmentLightModelfvSGIX + void __stdcall GLee_Lazy_glFragmentLightModelfvSGIX(GLenum pname, const GLfloat * params) {if (GLeeInit()) glFragmentLightModelfvSGIX(pname, params);} + GLEEPFNGLFRAGMENTLIGHTMODELFVSGIXPROC GLeeFuncPtr_glFragmentLightModelfvSGIX=GLee_Lazy_glFragmentLightModelfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightModeliSGIX +#define GLEE_C_DEFINED_glFragmentLightModeliSGIX + void __stdcall GLee_Lazy_glFragmentLightModeliSGIX(GLenum pname, GLint param) {if (GLeeInit()) glFragmentLightModeliSGIX(pname, param);} + GLEEPFNGLFRAGMENTLIGHTMODELISGIXPROC GLeeFuncPtr_glFragmentLightModeliSGIX=GLee_Lazy_glFragmentLightModeliSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightModelivSGIX +#define GLEE_C_DEFINED_glFragmentLightModelivSGIX + void __stdcall GLee_Lazy_glFragmentLightModelivSGIX(GLenum pname, const GLint * params) {if (GLeeInit()) glFragmentLightModelivSGIX(pname, params);} + GLEEPFNGLFRAGMENTLIGHTMODELIVSGIXPROC GLeeFuncPtr_glFragmentLightModelivSGIX=GLee_Lazy_glFragmentLightModelivSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialfSGIX +#define GLEE_C_DEFINED_glFragmentMaterialfSGIX + void __stdcall GLee_Lazy_glFragmentMaterialfSGIX(GLenum face, GLenum pname, GLfloat param) {if (GLeeInit()) glFragmentMaterialfSGIX(face, pname, param);} + GLEEPFNGLFRAGMENTMATERIALFSGIXPROC GLeeFuncPtr_glFragmentMaterialfSGIX=GLee_Lazy_glFragmentMaterialfSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialfvSGIX +#define GLEE_C_DEFINED_glFragmentMaterialfvSGIX + void __stdcall GLee_Lazy_glFragmentMaterialfvSGIX(GLenum face, GLenum pname, const GLfloat * params) {if (GLeeInit()) glFragmentMaterialfvSGIX(face, pname, params);} + GLEEPFNGLFRAGMENTMATERIALFVSGIXPROC GLeeFuncPtr_glFragmentMaterialfvSGIX=GLee_Lazy_glFragmentMaterialfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialiSGIX +#define GLEE_C_DEFINED_glFragmentMaterialiSGIX + void __stdcall GLee_Lazy_glFragmentMaterialiSGIX(GLenum face, GLenum pname, GLint param) {if (GLeeInit()) glFragmentMaterialiSGIX(face, pname, param);} + GLEEPFNGLFRAGMENTMATERIALISGIXPROC GLeeFuncPtr_glFragmentMaterialiSGIX=GLee_Lazy_glFragmentMaterialiSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialivSGIX +#define GLEE_C_DEFINED_glFragmentMaterialivSGIX + void __stdcall GLee_Lazy_glFragmentMaterialivSGIX(GLenum face, GLenum pname, const GLint * params) {if (GLeeInit()) glFragmentMaterialivSGIX(face, pname, params);} + GLEEPFNGLFRAGMENTMATERIALIVSGIXPROC GLeeFuncPtr_glFragmentMaterialivSGIX=GLee_Lazy_glFragmentMaterialivSGIX; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentLightfvSGIX +#define GLEE_C_DEFINED_glGetFragmentLightfvSGIX + void __stdcall GLee_Lazy_glGetFragmentLightfvSGIX(GLenum light, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetFragmentLightfvSGIX(light, pname, params);} + GLEEPFNGLGETFRAGMENTLIGHTFVSGIXPROC GLeeFuncPtr_glGetFragmentLightfvSGIX=GLee_Lazy_glGetFragmentLightfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentLightivSGIX +#define GLEE_C_DEFINED_glGetFragmentLightivSGIX + void __stdcall GLee_Lazy_glGetFragmentLightivSGIX(GLenum light, GLenum pname, GLint * params) {if (GLeeInit()) glGetFragmentLightivSGIX(light, pname, params);} + GLEEPFNGLGETFRAGMENTLIGHTIVSGIXPROC GLeeFuncPtr_glGetFragmentLightivSGIX=GLee_Lazy_glGetFragmentLightivSGIX; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentMaterialfvSGIX +#define GLEE_C_DEFINED_glGetFragmentMaterialfvSGIX + void __stdcall GLee_Lazy_glGetFragmentMaterialfvSGIX(GLenum face, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetFragmentMaterialfvSGIX(face, pname, params);} + GLEEPFNGLGETFRAGMENTMATERIALFVSGIXPROC GLeeFuncPtr_glGetFragmentMaterialfvSGIX=GLee_Lazy_glGetFragmentMaterialfvSGIX; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentMaterialivSGIX +#define GLEE_C_DEFINED_glGetFragmentMaterialivSGIX + void __stdcall GLee_Lazy_glGetFragmentMaterialivSGIX(GLenum face, GLenum pname, GLint * params) {if (GLeeInit()) glGetFragmentMaterialivSGIX(face, pname, params);} + GLEEPFNGLGETFRAGMENTMATERIALIVSGIXPROC GLeeFuncPtr_glGetFragmentMaterialivSGIX=GLee_Lazy_glGetFragmentMaterialivSGIX; +#endif +#ifndef GLEE_C_DEFINED_glLightEnviSGIX +#define GLEE_C_DEFINED_glLightEnviSGIX + void __stdcall GLee_Lazy_glLightEnviSGIX(GLenum pname, GLint param) {if (GLeeInit()) glLightEnviSGIX(pname, param);} + GLEEPFNGLLIGHTENVISGIXPROC GLeeFuncPtr_glLightEnviSGIX=GLee_Lazy_glLightEnviSGIX; +#endif +#endif + +/* GL_IBM_rasterpos_clip */ + +#ifdef __GLEE_GL_IBM_rasterpos_clip +#endif + +/* GL_HP_texture_lighting */ + +#ifdef __GLEE_GL_HP_texture_lighting +#endif + +/* GL_EXT_draw_range_elements */ + +#ifdef __GLEE_GL_EXT_draw_range_elements +#ifndef GLEE_C_DEFINED_glDrawRangeElementsEXT +#define GLEE_C_DEFINED_glDrawRangeElementsEXT + void __stdcall GLee_Lazy_glDrawRangeElementsEXT(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices) {if (GLeeInit()) glDrawRangeElementsEXT(mode, start, end, count, type, indices);} + GLEEPFNGLDRAWRANGEELEMENTSEXTPROC GLeeFuncPtr_glDrawRangeElementsEXT=GLee_Lazy_glDrawRangeElementsEXT; +#endif +#endif + +/* GL_WIN_phong_shading */ + +#ifdef __GLEE_GL_WIN_phong_shading +#endif + +/* GL_WIN_specular_fog */ + +#ifdef __GLEE_GL_WIN_specular_fog +#endif + +/* GL_EXT_light_texture */ + +#ifdef __GLEE_GL_EXT_light_texture +#ifndef GLEE_C_DEFINED_glApplyTextureEXT +#define GLEE_C_DEFINED_glApplyTextureEXT + void __stdcall GLee_Lazy_glApplyTextureEXT(GLenum mode) {if (GLeeInit()) glApplyTextureEXT(mode);} + GLEEPFNGLAPPLYTEXTUREEXTPROC GLeeFuncPtr_glApplyTextureEXT=GLee_Lazy_glApplyTextureEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureLightEXT +#define GLEE_C_DEFINED_glTextureLightEXT + void __stdcall GLee_Lazy_glTextureLightEXT(GLenum pname) {if (GLeeInit()) glTextureLightEXT(pname);} + GLEEPFNGLTEXTURELIGHTEXTPROC GLeeFuncPtr_glTextureLightEXT=GLee_Lazy_glTextureLightEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureMaterialEXT +#define GLEE_C_DEFINED_glTextureMaterialEXT + void __stdcall GLee_Lazy_glTextureMaterialEXT(GLenum face, GLenum mode) {if (GLeeInit()) glTextureMaterialEXT(face, mode);} + GLEEPFNGLTEXTUREMATERIALEXTPROC GLeeFuncPtr_glTextureMaterialEXT=GLee_Lazy_glTextureMaterialEXT; +#endif +#endif + +/* GL_SGIX_blend_alpha_minmax */ + +#ifdef __GLEE_GL_SGIX_blend_alpha_minmax +#endif + +/* GL_SGIX_impact_pixel_texture */ + +#ifdef __GLEE_GL_SGIX_impact_pixel_texture +#endif + +/* GL_EXT_bgra */ + +#ifdef __GLEE_GL_EXT_bgra +#endif + +/* GL_SGIX_async */ + +#ifdef __GLEE_GL_SGIX_async +#ifndef GLEE_C_DEFINED_glAsyncMarkerSGIX +#define GLEE_C_DEFINED_glAsyncMarkerSGIX + void __stdcall GLee_Lazy_glAsyncMarkerSGIX(GLuint marker) {if (GLeeInit()) glAsyncMarkerSGIX(marker);} + GLEEPFNGLASYNCMARKERSGIXPROC GLeeFuncPtr_glAsyncMarkerSGIX=GLee_Lazy_glAsyncMarkerSGIX; +#endif +#ifndef GLEE_C_DEFINED_glFinishAsyncSGIX +#define GLEE_C_DEFINED_glFinishAsyncSGIX + GLint __stdcall GLee_Lazy_glFinishAsyncSGIX(GLuint * markerp) {if (GLeeInit()) return glFinishAsyncSGIX(markerp); return (GLint)0;} + GLEEPFNGLFINISHASYNCSGIXPROC GLeeFuncPtr_glFinishAsyncSGIX=GLee_Lazy_glFinishAsyncSGIX; +#endif +#ifndef GLEE_C_DEFINED_glPollAsyncSGIX +#define GLEE_C_DEFINED_glPollAsyncSGIX + GLint __stdcall GLee_Lazy_glPollAsyncSGIX(GLuint * markerp) {if (GLeeInit()) return glPollAsyncSGIX(markerp); return (GLint)0;} + GLEEPFNGLPOLLASYNCSGIXPROC GLeeFuncPtr_glPollAsyncSGIX=GLee_Lazy_glPollAsyncSGIX; +#endif +#ifndef GLEE_C_DEFINED_glGenAsyncMarkersSGIX +#define GLEE_C_DEFINED_glGenAsyncMarkersSGIX + GLuint __stdcall GLee_Lazy_glGenAsyncMarkersSGIX(GLsizei range) {if (GLeeInit()) return glGenAsyncMarkersSGIX(range); return (GLuint)0;} + GLEEPFNGLGENASYNCMARKERSSGIXPROC GLeeFuncPtr_glGenAsyncMarkersSGIX=GLee_Lazy_glGenAsyncMarkersSGIX; +#endif +#ifndef GLEE_C_DEFINED_glDeleteAsyncMarkersSGIX +#define GLEE_C_DEFINED_glDeleteAsyncMarkersSGIX + void __stdcall GLee_Lazy_glDeleteAsyncMarkersSGIX(GLuint marker, GLsizei range) {if (GLeeInit()) glDeleteAsyncMarkersSGIX(marker, range);} + GLEEPFNGLDELETEASYNCMARKERSSGIXPROC GLeeFuncPtr_glDeleteAsyncMarkersSGIX=GLee_Lazy_glDeleteAsyncMarkersSGIX; +#endif +#ifndef GLEE_C_DEFINED_glIsAsyncMarkerSGIX +#define GLEE_C_DEFINED_glIsAsyncMarkerSGIX + GLboolean __stdcall GLee_Lazy_glIsAsyncMarkerSGIX(GLuint marker) {if (GLeeInit()) return glIsAsyncMarkerSGIX(marker); return (GLboolean)0;} + GLEEPFNGLISASYNCMARKERSGIXPROC GLeeFuncPtr_glIsAsyncMarkerSGIX=GLee_Lazy_glIsAsyncMarkerSGIX; +#endif +#endif + +/* GL_SGIX_async_pixel */ + +#ifdef __GLEE_GL_SGIX_async_pixel +#endif + +/* GL_SGIX_async_histogram */ + +#ifdef __GLEE_GL_SGIX_async_histogram +#endif + +/* GL_INTEL_texture_scissor */ + +#ifdef __GLEE_GL_INTEL_texture_scissor +#endif + +/* GL_INTEL_parallel_arrays */ + +#ifdef __GLEE_GL_INTEL_parallel_arrays +#ifndef GLEE_C_DEFINED_glVertexPointervINTEL +#define GLEE_C_DEFINED_glVertexPointervINTEL + void __stdcall GLee_Lazy_glVertexPointervINTEL(GLint size, GLenum type, const GLvoid* * pointer) {if (GLeeInit()) glVertexPointervINTEL(size, type, pointer);} + GLEEPFNGLVERTEXPOINTERVINTELPROC GLeeFuncPtr_glVertexPointervINTEL=GLee_Lazy_glVertexPointervINTEL; +#endif +#ifndef GLEE_C_DEFINED_glNormalPointervINTEL +#define GLEE_C_DEFINED_glNormalPointervINTEL + void __stdcall GLee_Lazy_glNormalPointervINTEL(GLenum type, const GLvoid* * pointer) {if (GLeeInit()) glNormalPointervINTEL(type, pointer);} + GLEEPFNGLNORMALPOINTERVINTELPROC GLeeFuncPtr_glNormalPointervINTEL=GLee_Lazy_glNormalPointervINTEL; +#endif +#ifndef GLEE_C_DEFINED_glColorPointervINTEL +#define GLEE_C_DEFINED_glColorPointervINTEL + void __stdcall GLee_Lazy_glColorPointervINTEL(GLint size, GLenum type, const GLvoid* * pointer) {if (GLeeInit()) glColorPointervINTEL(size, type, pointer);} + GLEEPFNGLCOLORPOINTERVINTELPROC GLeeFuncPtr_glColorPointervINTEL=GLee_Lazy_glColorPointervINTEL; +#endif +#ifndef GLEE_C_DEFINED_glTexCoordPointervINTEL +#define GLEE_C_DEFINED_glTexCoordPointervINTEL + void __stdcall GLee_Lazy_glTexCoordPointervINTEL(GLint size, GLenum type, const GLvoid* * pointer) {if (GLeeInit()) glTexCoordPointervINTEL(size, type, pointer);} + GLEEPFNGLTEXCOORDPOINTERVINTELPROC GLeeFuncPtr_glTexCoordPointervINTEL=GLee_Lazy_glTexCoordPointervINTEL; +#endif +#endif + +/* GL_HP_occlusion_test */ + +#ifdef __GLEE_GL_HP_occlusion_test +#endif + +/* GL_EXT_pixel_transform */ + +#ifdef __GLEE_GL_EXT_pixel_transform +#ifndef GLEE_C_DEFINED_glPixelTransformParameteriEXT +#define GLEE_C_DEFINED_glPixelTransformParameteriEXT + void __stdcall GLee_Lazy_glPixelTransformParameteriEXT(GLenum target, GLenum pname, GLint param) {if (GLeeInit()) glPixelTransformParameteriEXT(target, pname, param);} + GLEEPFNGLPIXELTRANSFORMPARAMETERIEXTPROC GLeeFuncPtr_glPixelTransformParameteriEXT=GLee_Lazy_glPixelTransformParameteriEXT; +#endif +#ifndef GLEE_C_DEFINED_glPixelTransformParameterfEXT +#define GLEE_C_DEFINED_glPixelTransformParameterfEXT + void __stdcall GLee_Lazy_glPixelTransformParameterfEXT(GLenum target, GLenum pname, GLfloat param) {if (GLeeInit()) glPixelTransformParameterfEXT(target, pname, param);} + GLEEPFNGLPIXELTRANSFORMPARAMETERFEXTPROC GLeeFuncPtr_glPixelTransformParameterfEXT=GLee_Lazy_glPixelTransformParameterfEXT; +#endif +#ifndef GLEE_C_DEFINED_glPixelTransformParameterivEXT +#define GLEE_C_DEFINED_glPixelTransformParameterivEXT + void __stdcall GLee_Lazy_glPixelTransformParameterivEXT(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glPixelTransformParameterivEXT(target, pname, params);} + GLEEPFNGLPIXELTRANSFORMPARAMETERIVEXTPROC GLeeFuncPtr_glPixelTransformParameterivEXT=GLee_Lazy_glPixelTransformParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glPixelTransformParameterfvEXT +#define GLEE_C_DEFINED_glPixelTransformParameterfvEXT + void __stdcall GLee_Lazy_glPixelTransformParameterfvEXT(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glPixelTransformParameterfvEXT(target, pname, params);} + GLEEPFNGLPIXELTRANSFORMPARAMETERFVEXTPROC GLeeFuncPtr_glPixelTransformParameterfvEXT=GLee_Lazy_glPixelTransformParameterfvEXT; +#endif +#endif + +/* GL_EXT_pixel_transform_color_table */ + +#ifdef __GLEE_GL_EXT_pixel_transform_color_table +#endif + +/* GL_EXT_shared_texture_palette */ + +#ifdef __GLEE_GL_EXT_shared_texture_palette +#endif + +/* GL_EXT_separate_specular_color */ + +#ifdef __GLEE_GL_EXT_separate_specular_color +#endif + +/* GL_EXT_secondary_color */ + +#ifdef __GLEE_GL_EXT_secondary_color +#ifndef GLEE_C_DEFINED_glSecondaryColor3bEXT +#define GLEE_C_DEFINED_glSecondaryColor3bEXT + void __stdcall GLee_Lazy_glSecondaryColor3bEXT(GLbyte red, GLbyte green, GLbyte blue) {if (GLeeInit()) glSecondaryColor3bEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3BEXTPROC GLeeFuncPtr_glSecondaryColor3bEXT=GLee_Lazy_glSecondaryColor3bEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3bvEXT +#define GLEE_C_DEFINED_glSecondaryColor3bvEXT + void __stdcall GLee_Lazy_glSecondaryColor3bvEXT(const GLbyte * v) {if (GLeeInit()) glSecondaryColor3bvEXT(v);} + GLEEPFNGLSECONDARYCOLOR3BVEXTPROC GLeeFuncPtr_glSecondaryColor3bvEXT=GLee_Lazy_glSecondaryColor3bvEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3dEXT +#define GLEE_C_DEFINED_glSecondaryColor3dEXT + void __stdcall GLee_Lazy_glSecondaryColor3dEXT(GLdouble red, GLdouble green, GLdouble blue) {if (GLeeInit()) glSecondaryColor3dEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3DEXTPROC GLeeFuncPtr_glSecondaryColor3dEXT=GLee_Lazy_glSecondaryColor3dEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3dvEXT +#define GLEE_C_DEFINED_glSecondaryColor3dvEXT + void __stdcall GLee_Lazy_glSecondaryColor3dvEXT(const GLdouble * v) {if (GLeeInit()) glSecondaryColor3dvEXT(v);} + GLEEPFNGLSECONDARYCOLOR3DVEXTPROC GLeeFuncPtr_glSecondaryColor3dvEXT=GLee_Lazy_glSecondaryColor3dvEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3fEXT +#define GLEE_C_DEFINED_glSecondaryColor3fEXT + void __stdcall GLee_Lazy_glSecondaryColor3fEXT(GLfloat red, GLfloat green, GLfloat blue) {if (GLeeInit()) glSecondaryColor3fEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3FEXTPROC GLeeFuncPtr_glSecondaryColor3fEXT=GLee_Lazy_glSecondaryColor3fEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3fvEXT +#define GLEE_C_DEFINED_glSecondaryColor3fvEXT + void __stdcall GLee_Lazy_glSecondaryColor3fvEXT(const GLfloat * v) {if (GLeeInit()) glSecondaryColor3fvEXT(v);} + GLEEPFNGLSECONDARYCOLOR3FVEXTPROC GLeeFuncPtr_glSecondaryColor3fvEXT=GLee_Lazy_glSecondaryColor3fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3iEXT +#define GLEE_C_DEFINED_glSecondaryColor3iEXT + void __stdcall GLee_Lazy_glSecondaryColor3iEXT(GLint red, GLint green, GLint blue) {if (GLeeInit()) glSecondaryColor3iEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3IEXTPROC GLeeFuncPtr_glSecondaryColor3iEXT=GLee_Lazy_glSecondaryColor3iEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3ivEXT +#define GLEE_C_DEFINED_glSecondaryColor3ivEXT + void __stdcall GLee_Lazy_glSecondaryColor3ivEXT(const GLint * v) {if (GLeeInit()) glSecondaryColor3ivEXT(v);} + GLEEPFNGLSECONDARYCOLOR3IVEXTPROC GLeeFuncPtr_glSecondaryColor3ivEXT=GLee_Lazy_glSecondaryColor3ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3sEXT +#define GLEE_C_DEFINED_glSecondaryColor3sEXT + void __stdcall GLee_Lazy_glSecondaryColor3sEXT(GLshort red, GLshort green, GLshort blue) {if (GLeeInit()) glSecondaryColor3sEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3SEXTPROC GLeeFuncPtr_glSecondaryColor3sEXT=GLee_Lazy_glSecondaryColor3sEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3svEXT +#define GLEE_C_DEFINED_glSecondaryColor3svEXT + void __stdcall GLee_Lazy_glSecondaryColor3svEXT(const GLshort * v) {if (GLeeInit()) glSecondaryColor3svEXT(v);} + GLEEPFNGLSECONDARYCOLOR3SVEXTPROC GLeeFuncPtr_glSecondaryColor3svEXT=GLee_Lazy_glSecondaryColor3svEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3ubEXT +#define GLEE_C_DEFINED_glSecondaryColor3ubEXT + void __stdcall GLee_Lazy_glSecondaryColor3ubEXT(GLubyte red, GLubyte green, GLubyte blue) {if (GLeeInit()) glSecondaryColor3ubEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3UBEXTPROC GLeeFuncPtr_glSecondaryColor3ubEXT=GLee_Lazy_glSecondaryColor3ubEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3ubvEXT +#define GLEE_C_DEFINED_glSecondaryColor3ubvEXT + void __stdcall GLee_Lazy_glSecondaryColor3ubvEXT(const GLubyte * v) {if (GLeeInit()) glSecondaryColor3ubvEXT(v);} + GLEEPFNGLSECONDARYCOLOR3UBVEXTPROC GLeeFuncPtr_glSecondaryColor3ubvEXT=GLee_Lazy_glSecondaryColor3ubvEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3uiEXT +#define GLEE_C_DEFINED_glSecondaryColor3uiEXT + void __stdcall GLee_Lazy_glSecondaryColor3uiEXT(GLuint red, GLuint green, GLuint blue) {if (GLeeInit()) glSecondaryColor3uiEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3UIEXTPROC GLeeFuncPtr_glSecondaryColor3uiEXT=GLee_Lazy_glSecondaryColor3uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3uivEXT +#define GLEE_C_DEFINED_glSecondaryColor3uivEXT + void __stdcall GLee_Lazy_glSecondaryColor3uivEXT(const GLuint * v) {if (GLeeInit()) glSecondaryColor3uivEXT(v);} + GLEEPFNGLSECONDARYCOLOR3UIVEXTPROC GLeeFuncPtr_glSecondaryColor3uivEXT=GLee_Lazy_glSecondaryColor3uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3usEXT +#define GLEE_C_DEFINED_glSecondaryColor3usEXT + void __stdcall GLee_Lazy_glSecondaryColor3usEXT(GLushort red, GLushort green, GLushort blue) {if (GLeeInit()) glSecondaryColor3usEXT(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3USEXTPROC GLeeFuncPtr_glSecondaryColor3usEXT=GLee_Lazy_glSecondaryColor3usEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3usvEXT +#define GLEE_C_DEFINED_glSecondaryColor3usvEXT + void __stdcall GLee_Lazy_glSecondaryColor3usvEXT(const GLushort * v) {if (GLeeInit()) glSecondaryColor3usvEXT(v);} + GLEEPFNGLSECONDARYCOLOR3USVEXTPROC GLeeFuncPtr_glSecondaryColor3usvEXT=GLee_Lazy_glSecondaryColor3usvEXT; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColorPointerEXT +#define GLEE_C_DEFINED_glSecondaryColorPointerEXT + void __stdcall GLee_Lazy_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glSecondaryColorPointerEXT(size, type, stride, pointer);} + GLEEPFNGLSECONDARYCOLORPOINTEREXTPROC GLeeFuncPtr_glSecondaryColorPointerEXT=GLee_Lazy_glSecondaryColorPointerEXT; +#endif +#endif + +/* GL_EXT_texture_perturb_normal */ + +#ifdef __GLEE_GL_EXT_texture_perturb_normal +#ifndef GLEE_C_DEFINED_glTextureNormalEXT +#define GLEE_C_DEFINED_glTextureNormalEXT + void __stdcall GLee_Lazy_glTextureNormalEXT(GLenum mode) {if (GLeeInit()) glTextureNormalEXT(mode);} + GLEEPFNGLTEXTURENORMALEXTPROC GLeeFuncPtr_glTextureNormalEXT=GLee_Lazy_glTextureNormalEXT; +#endif +#endif + +/* GL_EXT_multi_draw_arrays */ + +#ifdef __GLEE_GL_EXT_multi_draw_arrays +#ifndef GLEE_C_DEFINED_glMultiDrawArraysEXT +#define GLEE_C_DEFINED_glMultiDrawArraysEXT + void __stdcall GLee_Lazy_glMultiDrawArraysEXT(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount) {if (GLeeInit()) glMultiDrawArraysEXT(mode, first, count, primcount);} + GLEEPFNGLMULTIDRAWARRAYSEXTPROC GLeeFuncPtr_glMultiDrawArraysEXT=GLee_Lazy_glMultiDrawArraysEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiDrawElementsEXT +#define GLEE_C_DEFINED_glMultiDrawElementsEXT + void __stdcall GLee_Lazy_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount) {if (GLeeInit()) glMultiDrawElementsEXT(mode, count, type, indices, primcount);} + GLEEPFNGLMULTIDRAWELEMENTSEXTPROC GLeeFuncPtr_glMultiDrawElementsEXT=GLee_Lazy_glMultiDrawElementsEXT; +#endif +#endif + +/* GL_EXT_fog_coord */ + +#ifdef __GLEE_GL_EXT_fog_coord +#ifndef GLEE_C_DEFINED_glFogCoordfEXT +#define GLEE_C_DEFINED_glFogCoordfEXT + void __stdcall GLee_Lazy_glFogCoordfEXT(GLfloat coord) {if (GLeeInit()) glFogCoordfEXT(coord);} + GLEEPFNGLFOGCOORDFEXTPROC GLeeFuncPtr_glFogCoordfEXT=GLee_Lazy_glFogCoordfEXT; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordfvEXT +#define GLEE_C_DEFINED_glFogCoordfvEXT + void __stdcall GLee_Lazy_glFogCoordfvEXT(const GLfloat * coord) {if (GLeeInit()) glFogCoordfvEXT(coord);} + GLEEPFNGLFOGCOORDFVEXTPROC GLeeFuncPtr_glFogCoordfvEXT=GLee_Lazy_glFogCoordfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glFogCoorddEXT +#define GLEE_C_DEFINED_glFogCoorddEXT + void __stdcall GLee_Lazy_glFogCoorddEXT(GLdouble coord) {if (GLeeInit()) glFogCoorddEXT(coord);} + GLEEPFNGLFOGCOORDDEXTPROC GLeeFuncPtr_glFogCoorddEXT=GLee_Lazy_glFogCoorddEXT; +#endif +#ifndef GLEE_C_DEFINED_glFogCoorddvEXT +#define GLEE_C_DEFINED_glFogCoorddvEXT + void __stdcall GLee_Lazy_glFogCoorddvEXT(const GLdouble * coord) {if (GLeeInit()) glFogCoorddvEXT(coord);} + GLEEPFNGLFOGCOORDDVEXTPROC GLeeFuncPtr_glFogCoorddvEXT=GLee_Lazy_glFogCoorddvEXT; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordPointerEXT +#define GLEE_C_DEFINED_glFogCoordPointerEXT + void __stdcall GLee_Lazy_glFogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glFogCoordPointerEXT(type, stride, pointer);} + GLEEPFNGLFOGCOORDPOINTEREXTPROC GLeeFuncPtr_glFogCoordPointerEXT=GLee_Lazy_glFogCoordPointerEXT; +#endif +#endif + +/* GL_REND_screen_coordinates */ + +#ifdef __GLEE_GL_REND_screen_coordinates +#endif + +/* GL_EXT_coordinate_frame */ + +#ifdef __GLEE_GL_EXT_coordinate_frame +#ifndef GLEE_C_DEFINED_glTangent3bEXT +#define GLEE_C_DEFINED_glTangent3bEXT + void __stdcall GLee_Lazy_glTangent3bEXT(GLbyte tx, GLbyte ty, GLbyte tz) {if (GLeeInit()) glTangent3bEXT(tx, ty, tz);} + GLEEPFNGLTANGENT3BEXTPROC GLeeFuncPtr_glTangent3bEXT=GLee_Lazy_glTangent3bEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3bvEXT +#define GLEE_C_DEFINED_glTangent3bvEXT + void __stdcall GLee_Lazy_glTangent3bvEXT(const GLbyte * v) {if (GLeeInit()) glTangent3bvEXT(v);} + GLEEPFNGLTANGENT3BVEXTPROC GLeeFuncPtr_glTangent3bvEXT=GLee_Lazy_glTangent3bvEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3dEXT +#define GLEE_C_DEFINED_glTangent3dEXT + void __stdcall GLee_Lazy_glTangent3dEXT(GLdouble tx, GLdouble ty, GLdouble tz) {if (GLeeInit()) glTangent3dEXT(tx, ty, tz);} + GLEEPFNGLTANGENT3DEXTPROC GLeeFuncPtr_glTangent3dEXT=GLee_Lazy_glTangent3dEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3dvEXT +#define GLEE_C_DEFINED_glTangent3dvEXT + void __stdcall GLee_Lazy_glTangent3dvEXT(const GLdouble * v) {if (GLeeInit()) glTangent3dvEXT(v);} + GLEEPFNGLTANGENT3DVEXTPROC GLeeFuncPtr_glTangent3dvEXT=GLee_Lazy_glTangent3dvEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3fEXT +#define GLEE_C_DEFINED_glTangent3fEXT + void __stdcall GLee_Lazy_glTangent3fEXT(GLfloat tx, GLfloat ty, GLfloat tz) {if (GLeeInit()) glTangent3fEXT(tx, ty, tz);} + GLEEPFNGLTANGENT3FEXTPROC GLeeFuncPtr_glTangent3fEXT=GLee_Lazy_glTangent3fEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3fvEXT +#define GLEE_C_DEFINED_glTangent3fvEXT + void __stdcall GLee_Lazy_glTangent3fvEXT(const GLfloat * v) {if (GLeeInit()) glTangent3fvEXT(v);} + GLEEPFNGLTANGENT3FVEXTPROC GLeeFuncPtr_glTangent3fvEXT=GLee_Lazy_glTangent3fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3iEXT +#define GLEE_C_DEFINED_glTangent3iEXT + void __stdcall GLee_Lazy_glTangent3iEXT(GLint tx, GLint ty, GLint tz) {if (GLeeInit()) glTangent3iEXT(tx, ty, tz);} + GLEEPFNGLTANGENT3IEXTPROC GLeeFuncPtr_glTangent3iEXT=GLee_Lazy_glTangent3iEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3ivEXT +#define GLEE_C_DEFINED_glTangent3ivEXT + void __stdcall GLee_Lazy_glTangent3ivEXT(const GLint * v) {if (GLeeInit()) glTangent3ivEXT(v);} + GLEEPFNGLTANGENT3IVEXTPROC GLeeFuncPtr_glTangent3ivEXT=GLee_Lazy_glTangent3ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3sEXT +#define GLEE_C_DEFINED_glTangent3sEXT + void __stdcall GLee_Lazy_glTangent3sEXT(GLshort tx, GLshort ty, GLshort tz) {if (GLeeInit()) glTangent3sEXT(tx, ty, tz);} + GLEEPFNGLTANGENT3SEXTPROC GLeeFuncPtr_glTangent3sEXT=GLee_Lazy_glTangent3sEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangent3svEXT +#define GLEE_C_DEFINED_glTangent3svEXT + void __stdcall GLee_Lazy_glTangent3svEXT(const GLshort * v) {if (GLeeInit()) glTangent3svEXT(v);} + GLEEPFNGLTANGENT3SVEXTPROC GLeeFuncPtr_glTangent3svEXT=GLee_Lazy_glTangent3svEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3bEXT +#define GLEE_C_DEFINED_glBinormal3bEXT + void __stdcall GLee_Lazy_glBinormal3bEXT(GLbyte bx, GLbyte by, GLbyte bz) {if (GLeeInit()) glBinormal3bEXT(bx, by, bz);} + GLEEPFNGLBINORMAL3BEXTPROC GLeeFuncPtr_glBinormal3bEXT=GLee_Lazy_glBinormal3bEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3bvEXT +#define GLEE_C_DEFINED_glBinormal3bvEXT + void __stdcall GLee_Lazy_glBinormal3bvEXT(const GLbyte * v) {if (GLeeInit()) glBinormal3bvEXT(v);} + GLEEPFNGLBINORMAL3BVEXTPROC GLeeFuncPtr_glBinormal3bvEXT=GLee_Lazy_glBinormal3bvEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3dEXT +#define GLEE_C_DEFINED_glBinormal3dEXT + void __stdcall GLee_Lazy_glBinormal3dEXT(GLdouble bx, GLdouble by, GLdouble bz) {if (GLeeInit()) glBinormal3dEXT(bx, by, bz);} + GLEEPFNGLBINORMAL3DEXTPROC GLeeFuncPtr_glBinormal3dEXT=GLee_Lazy_glBinormal3dEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3dvEXT +#define GLEE_C_DEFINED_glBinormal3dvEXT + void __stdcall GLee_Lazy_glBinormal3dvEXT(const GLdouble * v) {if (GLeeInit()) glBinormal3dvEXT(v);} + GLEEPFNGLBINORMAL3DVEXTPROC GLeeFuncPtr_glBinormal3dvEXT=GLee_Lazy_glBinormal3dvEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3fEXT +#define GLEE_C_DEFINED_glBinormal3fEXT + void __stdcall GLee_Lazy_glBinormal3fEXT(GLfloat bx, GLfloat by, GLfloat bz) {if (GLeeInit()) glBinormal3fEXT(bx, by, bz);} + GLEEPFNGLBINORMAL3FEXTPROC GLeeFuncPtr_glBinormal3fEXT=GLee_Lazy_glBinormal3fEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3fvEXT +#define GLEE_C_DEFINED_glBinormal3fvEXT + void __stdcall GLee_Lazy_glBinormal3fvEXT(const GLfloat * v) {if (GLeeInit()) glBinormal3fvEXT(v);} + GLEEPFNGLBINORMAL3FVEXTPROC GLeeFuncPtr_glBinormal3fvEXT=GLee_Lazy_glBinormal3fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3iEXT +#define GLEE_C_DEFINED_glBinormal3iEXT + void __stdcall GLee_Lazy_glBinormal3iEXT(GLint bx, GLint by, GLint bz) {if (GLeeInit()) glBinormal3iEXT(bx, by, bz);} + GLEEPFNGLBINORMAL3IEXTPROC GLeeFuncPtr_glBinormal3iEXT=GLee_Lazy_glBinormal3iEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3ivEXT +#define GLEE_C_DEFINED_glBinormal3ivEXT + void __stdcall GLee_Lazy_glBinormal3ivEXT(const GLint * v) {if (GLeeInit()) glBinormal3ivEXT(v);} + GLEEPFNGLBINORMAL3IVEXTPROC GLeeFuncPtr_glBinormal3ivEXT=GLee_Lazy_glBinormal3ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3sEXT +#define GLEE_C_DEFINED_glBinormal3sEXT + void __stdcall GLee_Lazy_glBinormal3sEXT(GLshort bx, GLshort by, GLshort bz) {if (GLeeInit()) glBinormal3sEXT(bx, by, bz);} + GLEEPFNGLBINORMAL3SEXTPROC GLeeFuncPtr_glBinormal3sEXT=GLee_Lazy_glBinormal3sEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormal3svEXT +#define GLEE_C_DEFINED_glBinormal3svEXT + void __stdcall GLee_Lazy_glBinormal3svEXT(const GLshort * v) {if (GLeeInit()) glBinormal3svEXT(v);} + GLEEPFNGLBINORMAL3SVEXTPROC GLeeFuncPtr_glBinormal3svEXT=GLee_Lazy_glBinormal3svEXT; +#endif +#ifndef GLEE_C_DEFINED_glTangentPointerEXT +#define GLEE_C_DEFINED_glTangentPointerEXT + void __stdcall GLee_Lazy_glTangentPointerEXT(GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glTangentPointerEXT(type, stride, pointer);} + GLEEPFNGLTANGENTPOINTEREXTPROC GLeeFuncPtr_glTangentPointerEXT=GLee_Lazy_glTangentPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glBinormalPointerEXT +#define GLEE_C_DEFINED_glBinormalPointerEXT + void __stdcall GLee_Lazy_glBinormalPointerEXT(GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glBinormalPointerEXT(type, stride, pointer);} + GLEEPFNGLBINORMALPOINTEREXTPROC GLeeFuncPtr_glBinormalPointerEXT=GLee_Lazy_glBinormalPointerEXT; +#endif +#endif + +/* GL_EXT_texture_env_combine */ + +#ifdef __GLEE_GL_EXT_texture_env_combine +#endif + +/* GL_APPLE_specular_vector */ + +#ifdef __GLEE_GL_APPLE_specular_vector +#endif + +/* GL_APPLE_transform_hint */ + +#ifdef __GLEE_GL_APPLE_transform_hint +#endif + +/* GL_SGIX_fog_scale */ + +#ifdef __GLEE_GL_SGIX_fog_scale +#endif + +/* GL_SUNX_constant_data */ + +#ifdef __GLEE_GL_SUNX_constant_data +#ifndef GLEE_C_DEFINED_glFinishTextureSUNX +#define GLEE_C_DEFINED_glFinishTextureSUNX + void __stdcall GLee_Lazy_glFinishTextureSUNX(void) {if (GLeeInit()) glFinishTextureSUNX();} + GLEEPFNGLFINISHTEXTURESUNXPROC GLeeFuncPtr_glFinishTextureSUNX=GLee_Lazy_glFinishTextureSUNX; +#endif +#endif + +/* GL_SUN_global_alpha */ + +#ifdef __GLEE_GL_SUN_global_alpha +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactorbSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactorbSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactorbSUN(GLbyte factor) {if (GLeeInit()) glGlobalAlphaFactorbSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORBSUNPROC GLeeFuncPtr_glGlobalAlphaFactorbSUN=GLee_Lazy_glGlobalAlphaFactorbSUN; +#endif +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactorsSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactorsSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactorsSUN(GLshort factor) {if (GLeeInit()) glGlobalAlphaFactorsSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORSSUNPROC GLeeFuncPtr_glGlobalAlphaFactorsSUN=GLee_Lazy_glGlobalAlphaFactorsSUN; +#endif +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactoriSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactoriSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactoriSUN(GLint factor) {if (GLeeInit()) glGlobalAlphaFactoriSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORISUNPROC GLeeFuncPtr_glGlobalAlphaFactoriSUN=GLee_Lazy_glGlobalAlphaFactoriSUN; +#endif +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactorfSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactorfSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactorfSUN(GLfloat factor) {if (GLeeInit()) glGlobalAlphaFactorfSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORFSUNPROC GLeeFuncPtr_glGlobalAlphaFactorfSUN=GLee_Lazy_glGlobalAlphaFactorfSUN; +#endif +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactordSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactordSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactordSUN(GLdouble factor) {if (GLeeInit()) glGlobalAlphaFactordSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORDSUNPROC GLeeFuncPtr_glGlobalAlphaFactordSUN=GLee_Lazy_glGlobalAlphaFactordSUN; +#endif +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactorubSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactorubSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactorubSUN(GLubyte factor) {if (GLeeInit()) glGlobalAlphaFactorubSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORUBSUNPROC GLeeFuncPtr_glGlobalAlphaFactorubSUN=GLee_Lazy_glGlobalAlphaFactorubSUN; +#endif +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactorusSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactorusSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactorusSUN(GLushort factor) {if (GLeeInit()) glGlobalAlphaFactorusSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORUSSUNPROC GLeeFuncPtr_glGlobalAlphaFactorusSUN=GLee_Lazy_glGlobalAlphaFactorusSUN; +#endif +#ifndef GLEE_C_DEFINED_glGlobalAlphaFactoruiSUN +#define GLEE_C_DEFINED_glGlobalAlphaFactoruiSUN + void __stdcall GLee_Lazy_glGlobalAlphaFactoruiSUN(GLuint factor) {if (GLeeInit()) glGlobalAlphaFactoruiSUN(factor);} + GLEEPFNGLGLOBALALPHAFACTORUISUNPROC GLeeFuncPtr_glGlobalAlphaFactoruiSUN=GLee_Lazy_glGlobalAlphaFactoruiSUN; +#endif +#endif + +/* GL_SUN_triangle_list */ + +#ifdef __GLEE_GL_SUN_triangle_list +#ifndef GLEE_C_DEFINED_glReplacementCodeuiSUN +#define GLEE_C_DEFINED_glReplacementCodeuiSUN + void __stdcall GLee_Lazy_glReplacementCodeuiSUN(GLuint code) {if (GLeeInit()) glReplacementCodeuiSUN(code);} + GLEEPFNGLREPLACEMENTCODEUISUNPROC GLeeFuncPtr_glReplacementCodeuiSUN=GLee_Lazy_glReplacementCodeuiSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeusSUN +#define GLEE_C_DEFINED_glReplacementCodeusSUN + void __stdcall GLee_Lazy_glReplacementCodeusSUN(GLushort code) {if (GLeeInit()) glReplacementCodeusSUN(code);} + GLEEPFNGLREPLACEMENTCODEUSSUNPROC GLeeFuncPtr_glReplacementCodeusSUN=GLee_Lazy_glReplacementCodeusSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeubSUN +#define GLEE_C_DEFINED_glReplacementCodeubSUN + void __stdcall GLee_Lazy_glReplacementCodeubSUN(GLubyte code) {if (GLeeInit()) glReplacementCodeubSUN(code);} + GLEEPFNGLREPLACEMENTCODEUBSUNPROC GLeeFuncPtr_glReplacementCodeubSUN=GLee_Lazy_glReplacementCodeubSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuivSUN +#define GLEE_C_DEFINED_glReplacementCodeuivSUN + void __stdcall GLee_Lazy_glReplacementCodeuivSUN(const GLuint * code) {if (GLeeInit()) glReplacementCodeuivSUN(code);} + GLEEPFNGLREPLACEMENTCODEUIVSUNPROC GLeeFuncPtr_glReplacementCodeuivSUN=GLee_Lazy_glReplacementCodeuivSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeusvSUN +#define GLEE_C_DEFINED_glReplacementCodeusvSUN + void __stdcall GLee_Lazy_glReplacementCodeusvSUN(const GLushort * code) {if (GLeeInit()) glReplacementCodeusvSUN(code);} + GLEEPFNGLREPLACEMENTCODEUSVSUNPROC GLeeFuncPtr_glReplacementCodeusvSUN=GLee_Lazy_glReplacementCodeusvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeubvSUN +#define GLEE_C_DEFINED_glReplacementCodeubvSUN + void __stdcall GLee_Lazy_glReplacementCodeubvSUN(const GLubyte * code) {if (GLeeInit()) glReplacementCodeubvSUN(code);} + GLEEPFNGLREPLACEMENTCODEUBVSUNPROC GLeeFuncPtr_glReplacementCodeubvSUN=GLee_Lazy_glReplacementCodeubvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodePointerSUN +#define GLEE_C_DEFINED_glReplacementCodePointerSUN + void __stdcall GLee_Lazy_glReplacementCodePointerSUN(GLenum type, GLsizei stride, const GLvoid* * pointer) {if (GLeeInit()) glReplacementCodePointerSUN(type, stride, pointer);} + GLEEPFNGLREPLACEMENTCODEPOINTERSUNPROC GLeeFuncPtr_glReplacementCodePointerSUN=GLee_Lazy_glReplacementCodePointerSUN; +#endif +#endif + +/* GL_SUN_vertex */ + +#ifdef __GLEE_GL_SUN_vertex +#ifndef GLEE_C_DEFINED_glColor4ubVertex2fSUN +#define GLEE_C_DEFINED_glColor4ubVertex2fSUN + void __stdcall GLee_Lazy_glColor4ubVertex2fSUN(GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y) {if (GLeeInit()) glColor4ubVertex2fSUN(r, g, b, a, x, y);} + GLEEPFNGLCOLOR4UBVERTEX2FSUNPROC GLeeFuncPtr_glColor4ubVertex2fSUN=GLee_Lazy_glColor4ubVertex2fSUN; +#endif +#ifndef GLEE_C_DEFINED_glColor4ubVertex2fvSUN +#define GLEE_C_DEFINED_glColor4ubVertex2fvSUN + void __stdcall GLee_Lazy_glColor4ubVertex2fvSUN(const GLubyte * c, const GLfloat * v) {if (GLeeInit()) glColor4ubVertex2fvSUN(c, v);} + GLEEPFNGLCOLOR4UBVERTEX2FVSUNPROC GLeeFuncPtr_glColor4ubVertex2fvSUN=GLee_Lazy_glColor4ubVertex2fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glColor4ubVertex3fSUN +#define GLEE_C_DEFINED_glColor4ubVertex3fSUN + void __stdcall GLee_Lazy_glColor4ubVertex3fSUN(GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glColor4ubVertex3fSUN(r, g, b, a, x, y, z);} + GLEEPFNGLCOLOR4UBVERTEX3FSUNPROC GLeeFuncPtr_glColor4ubVertex3fSUN=GLee_Lazy_glColor4ubVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glColor4ubVertex3fvSUN +#define GLEE_C_DEFINED_glColor4ubVertex3fvSUN + void __stdcall GLee_Lazy_glColor4ubVertex3fvSUN(const GLubyte * c, const GLfloat * v) {if (GLeeInit()) glColor4ubVertex3fvSUN(c, v);} + GLEEPFNGLCOLOR4UBVERTEX3FVSUNPROC GLeeFuncPtr_glColor4ubVertex3fvSUN=GLee_Lazy_glColor4ubVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glColor3fVertex3fSUN +#define GLEE_C_DEFINED_glColor3fVertex3fSUN + void __stdcall GLee_Lazy_glColor3fVertex3fSUN(GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glColor3fVertex3fSUN(r, g, b, x, y, z);} + GLEEPFNGLCOLOR3FVERTEX3FSUNPROC GLeeFuncPtr_glColor3fVertex3fSUN=GLee_Lazy_glColor3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glColor3fVertex3fvSUN +#define GLEE_C_DEFINED_glColor3fVertex3fvSUN + void __stdcall GLee_Lazy_glColor3fVertex3fvSUN(const GLfloat * c, const GLfloat * v) {if (GLeeInit()) glColor3fVertex3fvSUN(c, v);} + GLEEPFNGLCOLOR3FVERTEX3FVSUNPROC GLeeFuncPtr_glColor3fVertex3fvSUN=GLee_Lazy_glColor3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glNormal3fVertex3fSUN(GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glNormal3fVertex3fSUN(nx, ny, nz, x, y, z);} + GLEEPFNGLNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glNormal3fVertex3fSUN=GLee_Lazy_glNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glNormal3fVertex3fvSUN(const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glNormal3fVertex3fvSUN(n, v);} + GLEEPFNGLNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glNormal3fVertex3fvSUN=GLee_Lazy_glNormal3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glColor4fNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glColor4fNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glColor4fNormal3fVertex3fSUN(GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glColor4fNormal3fVertex3fSUN(r, g, b, a, nx, ny, nz, x, y, z);} + GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glColor4fNormal3fVertex3fSUN=GLee_Lazy_glColor4fNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glColor4fNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glColor4fNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glColor4fNormal3fVertex3fvSUN(const GLfloat * c, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glColor4fNormal3fVertex3fvSUN(c, n, v);} + GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glColor4fNormal3fVertex3fvSUN=GLee_Lazy_glColor4fNormal3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fVertex3fSUN +#define GLEE_C_DEFINED_glTexCoord2fVertex3fSUN + void __stdcall GLee_Lazy_glTexCoord2fVertex3fSUN(GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glTexCoord2fVertex3fSUN(s, t, x, y, z);} + GLEEPFNGLTEXCOORD2FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fVertex3fSUN=GLee_Lazy_glTexCoord2fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fVertex3fvSUN +#define GLEE_C_DEFINED_glTexCoord2fVertex3fvSUN + void __stdcall GLee_Lazy_glTexCoord2fVertex3fvSUN(const GLfloat * tc, const GLfloat * v) {if (GLeeInit()) glTexCoord2fVertex3fvSUN(tc, v);} + GLEEPFNGLTEXCOORD2FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fVertex3fvSUN=GLee_Lazy_glTexCoord2fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4fVertex4fSUN +#define GLEE_C_DEFINED_glTexCoord4fVertex4fSUN + void __stdcall GLee_Lazy_glTexCoord4fVertex4fSUN(GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glTexCoord4fVertex4fSUN(s, t, p, q, x, y, z, w);} + GLEEPFNGLTEXCOORD4FVERTEX4FSUNPROC GLeeFuncPtr_glTexCoord4fVertex4fSUN=GLee_Lazy_glTexCoord4fVertex4fSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4fVertex4fvSUN +#define GLEE_C_DEFINED_glTexCoord4fVertex4fvSUN + void __stdcall GLee_Lazy_glTexCoord4fVertex4fvSUN(const GLfloat * tc, const GLfloat * v) {if (GLeeInit()) glTexCoord4fVertex4fvSUN(tc, v);} + GLEEPFNGLTEXCOORD4FVERTEX4FVSUNPROC GLeeFuncPtr_glTexCoord4fVertex4fvSUN=GLee_Lazy_glTexCoord4fVertex4fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fColor4ubVertex3fSUN +#define GLEE_C_DEFINED_glTexCoord2fColor4ubVertex3fSUN + void __stdcall GLee_Lazy_glTexCoord2fColor4ubVertex3fSUN(GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glTexCoord2fColor4ubVertex3fSUN(s, t, r, g, b, a, x, y, z);} + GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fColor4ubVertex3fSUN=GLee_Lazy_glTexCoord2fColor4ubVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fColor4ubVertex3fvSUN +#define GLEE_C_DEFINED_glTexCoord2fColor4ubVertex3fvSUN + void __stdcall GLee_Lazy_glTexCoord2fColor4ubVertex3fvSUN(const GLfloat * tc, const GLubyte * c, const GLfloat * v) {if (GLeeInit()) glTexCoord2fColor4ubVertex3fvSUN(tc, c, v);} + GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fColor4ubVertex3fvSUN=GLee_Lazy_glTexCoord2fColor4ubVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fColor3fVertex3fSUN +#define GLEE_C_DEFINED_glTexCoord2fColor3fVertex3fSUN + void __stdcall GLee_Lazy_glTexCoord2fColor3fVertex3fSUN(GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glTexCoord2fColor3fVertex3fSUN(s, t, r, g, b, x, y, z);} + GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fColor3fVertex3fSUN=GLee_Lazy_glTexCoord2fColor3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fColor3fVertex3fvSUN +#define GLEE_C_DEFINED_glTexCoord2fColor3fVertex3fvSUN + void __stdcall GLee_Lazy_glTexCoord2fColor3fVertex3fvSUN(const GLfloat * tc, const GLfloat * c, const GLfloat * v) {if (GLeeInit()) glTexCoord2fColor3fVertex3fvSUN(tc, c, v);} + GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fColor3fVertex3fvSUN=GLee_Lazy_glTexCoord2fColor3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glTexCoord2fNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glTexCoord2fNormal3fVertex3fSUN(GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glTexCoord2fNormal3fVertex3fSUN(s, t, nx, ny, nz, x, y, z);} + GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fNormal3fVertex3fSUN=GLee_Lazy_glTexCoord2fNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glTexCoord2fNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glTexCoord2fNormal3fVertex3fvSUN(const GLfloat * tc, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glTexCoord2fNormal3fVertex3fvSUN(tc, n, v);} + GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fNormal3fVertex3fvSUN=GLee_Lazy_glTexCoord2fNormal3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fColor4fNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glTexCoord2fColor4fNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glTexCoord2fColor4fNormal3fVertex3fSUN(GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glTexCoord2fColor4fNormal3fVertex3fSUN(s, t, r, g, b, a, nx, ny, nz, x, y, z);} + GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fSUN=GLee_Lazy_glTexCoord2fColor4fNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2fColor4fNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glTexCoord2fColor4fNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glTexCoord2fColor4fNormal3fVertex3fvSUN(const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glTexCoord2fColor4fNormal3fVertex3fvSUN(tc, c, n, v);} + GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fvSUN=GLee_Lazy_glTexCoord2fColor4fNormal3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4fColor4fNormal3fVertex4fSUN +#define GLEE_C_DEFINED_glTexCoord4fColor4fNormal3fVertex4fSUN + void __stdcall GLee_Lazy_glTexCoord4fColor4fNormal3fVertex4fSUN(GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glTexCoord4fColor4fNormal3fVertex4fSUN(s, t, p, q, r, g, b, a, nx, ny, nz, x, y, z, w);} + GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fSUN=GLee_Lazy_glTexCoord4fColor4fNormal3fVertex4fSUN; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4fColor4fNormal3fVertex4fvSUN +#define GLEE_C_DEFINED_glTexCoord4fColor4fNormal3fVertex4fvSUN + void __stdcall GLee_Lazy_glTexCoord4fColor4fNormal3fVertex4fvSUN(const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glTexCoord4fColor4fNormal3fVertex4fvSUN(tc, c, n, v);} + GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fvSUN=GLee_Lazy_glTexCoord4fColor4fNormal3fVertex4fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiVertex3fSUN(GLuint rc, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiVertex3fSUN(rc, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiVertex3fSUN=GLee_Lazy_glReplacementCodeuiVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiVertex3fvSUN(const GLuint * rc, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiVertex3fvSUN(rc, v);} + GLEEPFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiVertex3fvSUN=GLee_Lazy_glReplacementCodeuiVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiColor4ubVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiColor4ubVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiColor4ubVertex3fSUN(GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiColor4ubVertex3fSUN(rc, r, g, b, a, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fSUN=GLee_Lazy_glReplacementCodeuiColor4ubVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiColor4ubVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiColor4ubVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiColor4ubVertex3fvSUN(const GLuint * rc, const GLubyte * c, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiColor4ubVertex3fvSUN(rc, c, v);} + GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fvSUN=GLee_Lazy_glReplacementCodeuiColor4ubVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiColor3fVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiColor3fVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiColor3fVertex3fSUN(GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiColor3fVertex3fSUN(rc, r, g, b, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fSUN=GLee_Lazy_glReplacementCodeuiColor3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiColor3fVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiColor3fVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiColor3fVertex3fvSUN(const GLuint * rc, const GLfloat * c, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiColor3fVertex3fvSUN(rc, c, v);} + GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fvSUN=GLee_Lazy_glReplacementCodeuiColor3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiNormal3fVertex3fSUN(GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiNormal3fVertex3fSUN(rc, nx, ny, nz, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fSUN=GLee_Lazy_glReplacementCodeuiNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiNormal3fVertex3fvSUN(const GLuint * rc, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiNormal3fVertex3fvSUN(rc, n, v);} + GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fvSUN=GLee_Lazy_glReplacementCodeuiNormal3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiColor4fNormal3fVertex3fSUN(GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiColor4fNormal3fVertex3fSUN(rc, r, g, b, a, nx, ny, nz, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fSUN=GLee_Lazy_glReplacementCodeuiColor4fNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiColor4fNormal3fVertex3fvSUN(const GLuint * rc, const GLfloat * c, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiColor4fNormal3fVertex3fvSUN(rc, c, n, v);} + GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fvSUN=GLee_Lazy_glReplacementCodeuiColor4fNormal3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiTexCoord2fVertex3fSUN(GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiTexCoord2fVertex3fSUN(rc, s, t, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fSUN=GLee_Lazy_glReplacementCodeuiTexCoord2fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiTexCoord2fVertex3fvSUN(const GLuint * rc, const GLfloat * tc, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiTexCoord2fVertex3fvSUN(rc, tc, v);} + GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fvSUN=GLee_Lazy_glReplacementCodeuiTexCoord2fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN(GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN(rc, s, t, nx, ny, nz, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN=GLee_Lazy_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN(const GLuint * rc, const GLfloat * tc, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN(rc, tc, n, v);} + GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN=GLee_Lazy_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN +#define GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN + void __stdcall GLee_Lazy_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN(GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN(rc, s, t, r, g, b, a, nx, ny, nz, x, y, z);} + GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN=GLee_Lazy_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +#endif +#ifndef GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN +#define GLEE_C_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN + void __stdcall GLee_Lazy_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN(const GLuint * rc, const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v) {if (GLeeInit()) glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN(rc, tc, c, n, v);} + GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN=GLee_Lazy_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +#endif +#endif + +/* GL_EXT_blend_func_separate */ + +#ifdef __GLEE_GL_EXT_blend_func_separate +#ifndef GLEE_C_DEFINED_glBlendFuncSeparateEXT +#define GLEE_C_DEFINED_glBlendFuncSeparateEXT + void __stdcall GLee_Lazy_glBlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {if (GLeeInit()) glBlendFuncSeparateEXT(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);} + GLEEPFNGLBLENDFUNCSEPARATEEXTPROC GLeeFuncPtr_glBlendFuncSeparateEXT=GLee_Lazy_glBlendFuncSeparateEXT; +#endif +#endif + +/* GL_INGR_color_clamp */ + +#ifdef __GLEE_GL_INGR_color_clamp +#endif + +/* GL_INGR_interlace_read */ + +#ifdef __GLEE_GL_INGR_interlace_read +#endif + +/* GL_EXT_stencil_wrap */ + +#ifdef __GLEE_GL_EXT_stencil_wrap +#endif + +/* GL_EXT_422_pixels */ + +#ifdef __GLEE_GL_EXT_422_pixels +#endif + +/* GL_NV_texgen_reflection */ + +#ifdef __GLEE_GL_NV_texgen_reflection +#endif + +/* GL_EXT_texture_cube_map */ + +#ifdef __GLEE_GL_EXT_texture_cube_map +#endif + +/* GL_SUN_convolution_border_modes */ + +#ifdef __GLEE_GL_SUN_convolution_border_modes +#endif + +/* GL_EXT_texture_env_add */ + +#ifdef __GLEE_GL_EXT_texture_env_add +#endif + +/* GL_EXT_texture_lod_bias */ + +#ifdef __GLEE_GL_EXT_texture_lod_bias +#endif + +/* GL_EXT_texture_filter_anisotropic */ + +#ifdef __GLEE_GL_EXT_texture_filter_anisotropic +#endif + +/* GL_EXT_vertex_weighting */ + +#ifdef __GLEE_GL_EXT_vertex_weighting +#ifndef GLEE_C_DEFINED_glVertexWeightfEXT +#define GLEE_C_DEFINED_glVertexWeightfEXT + void __stdcall GLee_Lazy_glVertexWeightfEXT(GLfloat weight) {if (GLeeInit()) glVertexWeightfEXT(weight);} + GLEEPFNGLVERTEXWEIGHTFEXTPROC GLeeFuncPtr_glVertexWeightfEXT=GLee_Lazy_glVertexWeightfEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexWeightfvEXT +#define GLEE_C_DEFINED_glVertexWeightfvEXT + void __stdcall GLee_Lazy_glVertexWeightfvEXT(const GLfloat * weight) {if (GLeeInit()) glVertexWeightfvEXT(weight);} + GLEEPFNGLVERTEXWEIGHTFVEXTPROC GLeeFuncPtr_glVertexWeightfvEXT=GLee_Lazy_glVertexWeightfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexWeightPointerEXT +#define GLEE_C_DEFINED_glVertexWeightPointerEXT + void __stdcall GLee_Lazy_glVertexWeightPointerEXT(GLsizei size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexWeightPointerEXT(size, type, stride, pointer);} + GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC GLeeFuncPtr_glVertexWeightPointerEXT=GLee_Lazy_glVertexWeightPointerEXT; +#endif +#endif + +/* GL_NV_light_max_exponent */ + +#ifdef __GLEE_GL_NV_light_max_exponent +#endif + +/* GL_NV_vertex_array_range */ + +#ifdef __GLEE_GL_NV_vertex_array_range +#ifndef GLEE_C_DEFINED_glFlushVertexArrayRangeNV +#define GLEE_C_DEFINED_glFlushVertexArrayRangeNV + void __stdcall GLee_Lazy_glFlushVertexArrayRangeNV(void) {if (GLeeInit()) glFlushVertexArrayRangeNV();} + GLEEPFNGLFLUSHVERTEXARRAYRANGENVPROC GLeeFuncPtr_glFlushVertexArrayRangeNV=GLee_Lazy_glFlushVertexArrayRangeNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayRangeNV +#define GLEE_C_DEFINED_glVertexArrayRangeNV + void __stdcall GLee_Lazy_glVertexArrayRangeNV(GLsizei length, const GLvoid * pointer) {if (GLeeInit()) glVertexArrayRangeNV(length, pointer);} + GLEEPFNGLVERTEXARRAYRANGENVPROC GLeeFuncPtr_glVertexArrayRangeNV=GLee_Lazy_glVertexArrayRangeNV; +#endif +#endif + +/* GL_NV_register_combiners */ + +#ifdef __GLEE_GL_NV_register_combiners +#ifndef GLEE_C_DEFINED_glCombinerParameterfvNV +#define GLEE_C_DEFINED_glCombinerParameterfvNV + void __stdcall GLee_Lazy_glCombinerParameterfvNV(GLenum pname, const GLfloat * params) {if (GLeeInit()) glCombinerParameterfvNV(pname, params);} + GLEEPFNGLCOMBINERPARAMETERFVNVPROC GLeeFuncPtr_glCombinerParameterfvNV=GLee_Lazy_glCombinerParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glCombinerParameterfNV +#define GLEE_C_DEFINED_glCombinerParameterfNV + void __stdcall GLee_Lazy_glCombinerParameterfNV(GLenum pname, GLfloat param) {if (GLeeInit()) glCombinerParameterfNV(pname, param);} + GLEEPFNGLCOMBINERPARAMETERFNVPROC GLeeFuncPtr_glCombinerParameterfNV=GLee_Lazy_glCombinerParameterfNV; +#endif +#ifndef GLEE_C_DEFINED_glCombinerParameterivNV +#define GLEE_C_DEFINED_glCombinerParameterivNV + void __stdcall GLee_Lazy_glCombinerParameterivNV(GLenum pname, const GLint * params) {if (GLeeInit()) glCombinerParameterivNV(pname, params);} + GLEEPFNGLCOMBINERPARAMETERIVNVPROC GLeeFuncPtr_glCombinerParameterivNV=GLee_Lazy_glCombinerParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glCombinerParameteriNV +#define GLEE_C_DEFINED_glCombinerParameteriNV + void __stdcall GLee_Lazy_glCombinerParameteriNV(GLenum pname, GLint param) {if (GLeeInit()) glCombinerParameteriNV(pname, param);} + GLEEPFNGLCOMBINERPARAMETERINVPROC GLeeFuncPtr_glCombinerParameteriNV=GLee_Lazy_glCombinerParameteriNV; +#endif +#ifndef GLEE_C_DEFINED_glCombinerInputNV +#define GLEE_C_DEFINED_glCombinerInputNV + void __stdcall GLee_Lazy_glCombinerInputNV(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage) {if (GLeeInit()) glCombinerInputNV(stage, portion, variable, input, mapping, componentUsage);} + GLEEPFNGLCOMBINERINPUTNVPROC GLeeFuncPtr_glCombinerInputNV=GLee_Lazy_glCombinerInputNV; +#endif +#ifndef GLEE_C_DEFINED_glCombinerOutputNV +#define GLEE_C_DEFINED_glCombinerOutputNV + void __stdcall GLee_Lazy_glCombinerOutputNV(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum) {if (GLeeInit()) glCombinerOutputNV(stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum);} + GLEEPFNGLCOMBINEROUTPUTNVPROC GLeeFuncPtr_glCombinerOutputNV=GLee_Lazy_glCombinerOutputNV; +#endif +#ifndef GLEE_C_DEFINED_glFinalCombinerInputNV +#define GLEE_C_DEFINED_glFinalCombinerInputNV + void __stdcall GLee_Lazy_glFinalCombinerInputNV(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage) {if (GLeeInit()) glFinalCombinerInputNV(variable, input, mapping, componentUsage);} + GLEEPFNGLFINALCOMBINERINPUTNVPROC GLeeFuncPtr_glFinalCombinerInputNV=GLee_Lazy_glFinalCombinerInputNV; +#endif +#ifndef GLEE_C_DEFINED_glGetCombinerInputParameterfvNV +#define GLEE_C_DEFINED_glGetCombinerInputParameterfvNV + void __stdcall GLee_Lazy_glGetCombinerInputParameterfvNV(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetCombinerInputParameterfvNV(stage, portion, variable, pname, params);} + GLEEPFNGLGETCOMBINERINPUTPARAMETERFVNVPROC GLeeFuncPtr_glGetCombinerInputParameterfvNV=GLee_Lazy_glGetCombinerInputParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetCombinerInputParameterivNV +#define GLEE_C_DEFINED_glGetCombinerInputParameterivNV + void __stdcall GLee_Lazy_glGetCombinerInputParameterivNV(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params) {if (GLeeInit()) glGetCombinerInputParameterivNV(stage, portion, variable, pname, params);} + GLEEPFNGLGETCOMBINERINPUTPARAMETERIVNVPROC GLeeFuncPtr_glGetCombinerInputParameterivNV=GLee_Lazy_glGetCombinerInputParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetCombinerOutputParameterfvNV +#define GLEE_C_DEFINED_glGetCombinerOutputParameterfvNV + void __stdcall GLee_Lazy_glGetCombinerOutputParameterfvNV(GLenum stage, GLenum portion, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetCombinerOutputParameterfvNV(stage, portion, pname, params);} + GLEEPFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC GLeeFuncPtr_glGetCombinerOutputParameterfvNV=GLee_Lazy_glGetCombinerOutputParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetCombinerOutputParameterivNV +#define GLEE_C_DEFINED_glGetCombinerOutputParameterivNV + void __stdcall GLee_Lazy_glGetCombinerOutputParameterivNV(GLenum stage, GLenum portion, GLenum pname, GLint * params) {if (GLeeInit()) glGetCombinerOutputParameterivNV(stage, portion, pname, params);} + GLEEPFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC GLeeFuncPtr_glGetCombinerOutputParameterivNV=GLee_Lazy_glGetCombinerOutputParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetFinalCombinerInputParameterfvNV +#define GLEE_C_DEFINED_glGetFinalCombinerInputParameterfvNV + void __stdcall GLee_Lazy_glGetFinalCombinerInputParameterfvNV(GLenum variable, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetFinalCombinerInputParameterfvNV(variable, pname, params);} + GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC GLeeFuncPtr_glGetFinalCombinerInputParameterfvNV=GLee_Lazy_glGetFinalCombinerInputParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetFinalCombinerInputParameterivNV +#define GLEE_C_DEFINED_glGetFinalCombinerInputParameterivNV + void __stdcall GLee_Lazy_glGetFinalCombinerInputParameterivNV(GLenum variable, GLenum pname, GLint * params) {if (GLeeInit()) glGetFinalCombinerInputParameterivNV(variable, pname, params);} + GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC GLeeFuncPtr_glGetFinalCombinerInputParameterivNV=GLee_Lazy_glGetFinalCombinerInputParameterivNV; +#endif +#endif + +/* GL_NV_fog_distance */ + +#ifdef __GLEE_GL_NV_fog_distance +#endif + +/* GL_NV_texgen_emboss */ + +#ifdef __GLEE_GL_NV_texgen_emboss +#endif + +/* GL_NV_blend_square */ + +#ifdef __GLEE_GL_NV_blend_square +#endif + +/* GL_NV_texture_env_combine4 */ + +#ifdef __GLEE_GL_NV_texture_env_combine4 +#endif + +/* GL_MESA_resize_buffers */ + +#ifdef __GLEE_GL_MESA_resize_buffers +#ifndef GLEE_C_DEFINED_glResizeBuffersMESA +#define GLEE_C_DEFINED_glResizeBuffersMESA + void __stdcall GLee_Lazy_glResizeBuffersMESA(void) {if (GLeeInit()) glResizeBuffersMESA();} + GLEEPFNGLRESIZEBUFFERSMESAPROC GLeeFuncPtr_glResizeBuffersMESA=GLee_Lazy_glResizeBuffersMESA; +#endif +#endif + +/* GL_MESA_window_pos */ + +#ifdef __GLEE_GL_MESA_window_pos +#ifndef GLEE_C_DEFINED_glWindowPos2dMESA +#define GLEE_C_DEFINED_glWindowPos2dMESA + void __stdcall GLee_Lazy_glWindowPos2dMESA(GLdouble x, GLdouble y) {if (GLeeInit()) glWindowPos2dMESA(x, y);} + GLEEPFNGLWINDOWPOS2DMESAPROC GLeeFuncPtr_glWindowPos2dMESA=GLee_Lazy_glWindowPos2dMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2dvMESA +#define GLEE_C_DEFINED_glWindowPos2dvMESA + void __stdcall GLee_Lazy_glWindowPos2dvMESA(const GLdouble * v) {if (GLeeInit()) glWindowPos2dvMESA(v);} + GLEEPFNGLWINDOWPOS2DVMESAPROC GLeeFuncPtr_glWindowPos2dvMESA=GLee_Lazy_glWindowPos2dvMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2fMESA +#define GLEE_C_DEFINED_glWindowPos2fMESA + void __stdcall GLee_Lazy_glWindowPos2fMESA(GLfloat x, GLfloat y) {if (GLeeInit()) glWindowPos2fMESA(x, y);} + GLEEPFNGLWINDOWPOS2FMESAPROC GLeeFuncPtr_glWindowPos2fMESA=GLee_Lazy_glWindowPos2fMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2fvMESA +#define GLEE_C_DEFINED_glWindowPos2fvMESA + void __stdcall GLee_Lazy_glWindowPos2fvMESA(const GLfloat * v) {if (GLeeInit()) glWindowPos2fvMESA(v);} + GLEEPFNGLWINDOWPOS2FVMESAPROC GLeeFuncPtr_glWindowPos2fvMESA=GLee_Lazy_glWindowPos2fvMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2iMESA +#define GLEE_C_DEFINED_glWindowPos2iMESA + void __stdcall GLee_Lazy_glWindowPos2iMESA(GLint x, GLint y) {if (GLeeInit()) glWindowPos2iMESA(x, y);} + GLEEPFNGLWINDOWPOS2IMESAPROC GLeeFuncPtr_glWindowPos2iMESA=GLee_Lazy_glWindowPos2iMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2ivMESA +#define GLEE_C_DEFINED_glWindowPos2ivMESA + void __stdcall GLee_Lazy_glWindowPos2ivMESA(const GLint * v) {if (GLeeInit()) glWindowPos2ivMESA(v);} + GLEEPFNGLWINDOWPOS2IVMESAPROC GLeeFuncPtr_glWindowPos2ivMESA=GLee_Lazy_glWindowPos2ivMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2sMESA +#define GLEE_C_DEFINED_glWindowPos2sMESA + void __stdcall GLee_Lazy_glWindowPos2sMESA(GLshort x, GLshort y) {if (GLeeInit()) glWindowPos2sMESA(x, y);} + GLEEPFNGLWINDOWPOS2SMESAPROC GLeeFuncPtr_glWindowPos2sMESA=GLee_Lazy_glWindowPos2sMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos2svMESA +#define GLEE_C_DEFINED_glWindowPos2svMESA + void __stdcall GLee_Lazy_glWindowPos2svMESA(const GLshort * v) {if (GLeeInit()) glWindowPos2svMESA(v);} + GLEEPFNGLWINDOWPOS2SVMESAPROC GLeeFuncPtr_glWindowPos2svMESA=GLee_Lazy_glWindowPos2svMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3dMESA +#define GLEE_C_DEFINED_glWindowPos3dMESA + void __stdcall GLee_Lazy_glWindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glWindowPos3dMESA(x, y, z);} + GLEEPFNGLWINDOWPOS3DMESAPROC GLeeFuncPtr_glWindowPos3dMESA=GLee_Lazy_glWindowPos3dMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3dvMESA +#define GLEE_C_DEFINED_glWindowPos3dvMESA + void __stdcall GLee_Lazy_glWindowPos3dvMESA(const GLdouble * v) {if (GLeeInit()) glWindowPos3dvMESA(v);} + GLEEPFNGLWINDOWPOS3DVMESAPROC GLeeFuncPtr_glWindowPos3dvMESA=GLee_Lazy_glWindowPos3dvMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3fMESA +#define GLEE_C_DEFINED_glWindowPos3fMESA + void __stdcall GLee_Lazy_glWindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glWindowPos3fMESA(x, y, z);} + GLEEPFNGLWINDOWPOS3FMESAPROC GLeeFuncPtr_glWindowPos3fMESA=GLee_Lazy_glWindowPos3fMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3fvMESA +#define GLEE_C_DEFINED_glWindowPos3fvMESA + void __stdcall GLee_Lazy_glWindowPos3fvMESA(const GLfloat * v) {if (GLeeInit()) glWindowPos3fvMESA(v);} + GLEEPFNGLWINDOWPOS3FVMESAPROC GLeeFuncPtr_glWindowPos3fvMESA=GLee_Lazy_glWindowPos3fvMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3iMESA +#define GLEE_C_DEFINED_glWindowPos3iMESA + void __stdcall GLee_Lazy_glWindowPos3iMESA(GLint x, GLint y, GLint z) {if (GLeeInit()) glWindowPos3iMESA(x, y, z);} + GLEEPFNGLWINDOWPOS3IMESAPROC GLeeFuncPtr_glWindowPos3iMESA=GLee_Lazy_glWindowPos3iMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3ivMESA +#define GLEE_C_DEFINED_glWindowPos3ivMESA + void __stdcall GLee_Lazy_glWindowPos3ivMESA(const GLint * v) {if (GLeeInit()) glWindowPos3ivMESA(v);} + GLEEPFNGLWINDOWPOS3IVMESAPROC GLeeFuncPtr_glWindowPos3ivMESA=GLee_Lazy_glWindowPos3ivMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3sMESA +#define GLEE_C_DEFINED_glWindowPos3sMESA + void __stdcall GLee_Lazy_glWindowPos3sMESA(GLshort x, GLshort y, GLshort z) {if (GLeeInit()) glWindowPos3sMESA(x, y, z);} + GLEEPFNGLWINDOWPOS3SMESAPROC GLeeFuncPtr_glWindowPos3sMESA=GLee_Lazy_glWindowPos3sMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos3svMESA +#define GLEE_C_DEFINED_glWindowPos3svMESA + void __stdcall GLee_Lazy_glWindowPos3svMESA(const GLshort * v) {if (GLeeInit()) glWindowPos3svMESA(v);} + GLEEPFNGLWINDOWPOS3SVMESAPROC GLeeFuncPtr_glWindowPos3svMESA=GLee_Lazy_glWindowPos3svMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4dMESA +#define GLEE_C_DEFINED_glWindowPos4dMESA + void __stdcall GLee_Lazy_glWindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glWindowPos4dMESA(x, y, z, w);} + GLEEPFNGLWINDOWPOS4DMESAPROC GLeeFuncPtr_glWindowPos4dMESA=GLee_Lazy_glWindowPos4dMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4dvMESA +#define GLEE_C_DEFINED_glWindowPos4dvMESA + void __stdcall GLee_Lazy_glWindowPos4dvMESA(const GLdouble * v) {if (GLeeInit()) glWindowPos4dvMESA(v);} + GLEEPFNGLWINDOWPOS4DVMESAPROC GLeeFuncPtr_glWindowPos4dvMESA=GLee_Lazy_glWindowPos4dvMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4fMESA +#define GLEE_C_DEFINED_glWindowPos4fMESA + void __stdcall GLee_Lazy_glWindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glWindowPos4fMESA(x, y, z, w);} + GLEEPFNGLWINDOWPOS4FMESAPROC GLeeFuncPtr_glWindowPos4fMESA=GLee_Lazy_glWindowPos4fMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4fvMESA +#define GLEE_C_DEFINED_glWindowPos4fvMESA + void __stdcall GLee_Lazy_glWindowPos4fvMESA(const GLfloat * v) {if (GLeeInit()) glWindowPos4fvMESA(v);} + GLEEPFNGLWINDOWPOS4FVMESAPROC GLeeFuncPtr_glWindowPos4fvMESA=GLee_Lazy_glWindowPos4fvMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4iMESA +#define GLEE_C_DEFINED_glWindowPos4iMESA + void __stdcall GLee_Lazy_glWindowPos4iMESA(GLint x, GLint y, GLint z, GLint w) {if (GLeeInit()) glWindowPos4iMESA(x, y, z, w);} + GLEEPFNGLWINDOWPOS4IMESAPROC GLeeFuncPtr_glWindowPos4iMESA=GLee_Lazy_glWindowPos4iMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4ivMESA +#define GLEE_C_DEFINED_glWindowPos4ivMESA + void __stdcall GLee_Lazy_glWindowPos4ivMESA(const GLint * v) {if (GLeeInit()) glWindowPos4ivMESA(v);} + GLEEPFNGLWINDOWPOS4IVMESAPROC GLeeFuncPtr_glWindowPos4ivMESA=GLee_Lazy_glWindowPos4ivMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4sMESA +#define GLEE_C_DEFINED_glWindowPos4sMESA + void __stdcall GLee_Lazy_glWindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w) {if (GLeeInit()) glWindowPos4sMESA(x, y, z, w);} + GLEEPFNGLWINDOWPOS4SMESAPROC GLeeFuncPtr_glWindowPos4sMESA=GLee_Lazy_glWindowPos4sMESA; +#endif +#ifndef GLEE_C_DEFINED_glWindowPos4svMESA +#define GLEE_C_DEFINED_glWindowPos4svMESA + void __stdcall GLee_Lazy_glWindowPos4svMESA(const GLshort * v) {if (GLeeInit()) glWindowPos4svMESA(v);} + GLEEPFNGLWINDOWPOS4SVMESAPROC GLeeFuncPtr_glWindowPos4svMESA=GLee_Lazy_glWindowPos4svMESA; +#endif +#endif + +/* GL_EXT_texture_compression_s3tc */ + +#ifdef __GLEE_GL_EXT_texture_compression_s3tc +#endif + +/* GL_IBM_cull_vertex */ + +#ifdef __GLEE_GL_IBM_cull_vertex +#endif + +/* GL_IBM_multimode_draw_arrays */ + +#ifdef __GLEE_GL_IBM_multimode_draw_arrays +#ifndef GLEE_C_DEFINED_glMultiModeDrawArraysIBM +#define GLEE_C_DEFINED_glMultiModeDrawArraysIBM + void __stdcall GLee_Lazy_glMultiModeDrawArraysIBM(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride) {if (GLeeInit()) glMultiModeDrawArraysIBM(mode, first, count, primcount, modestride);} + GLEEPFNGLMULTIMODEDRAWARRAYSIBMPROC GLeeFuncPtr_glMultiModeDrawArraysIBM=GLee_Lazy_glMultiModeDrawArraysIBM; +#endif +#ifndef GLEE_C_DEFINED_glMultiModeDrawElementsIBM +#define GLEE_C_DEFINED_glMultiModeDrawElementsIBM + void __stdcall GLee_Lazy_glMultiModeDrawElementsIBM(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid* const * indices, GLsizei primcount, GLint modestride) {if (GLeeInit()) glMultiModeDrawElementsIBM(mode, count, type, indices, primcount, modestride);} + GLEEPFNGLMULTIMODEDRAWELEMENTSIBMPROC GLeeFuncPtr_glMultiModeDrawElementsIBM=GLee_Lazy_glMultiModeDrawElementsIBM; +#endif +#endif + +/* GL_IBM_vertex_array_lists */ + +#ifdef __GLEE_GL_IBM_vertex_array_lists +#ifndef GLEE_C_DEFINED_glColorPointerListIBM +#define GLEE_C_DEFINED_glColorPointerListIBM + void __stdcall GLee_Lazy_glColorPointerListIBM(GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride) {if (GLeeInit()) glColorPointerListIBM(size, type, stride, pointer, ptrstride);} + GLEEPFNGLCOLORPOINTERLISTIBMPROC GLeeFuncPtr_glColorPointerListIBM=GLee_Lazy_glColorPointerListIBM; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColorPointerListIBM +#define GLEE_C_DEFINED_glSecondaryColorPointerListIBM + void __stdcall GLee_Lazy_glSecondaryColorPointerListIBM(GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride) {if (GLeeInit()) glSecondaryColorPointerListIBM(size, type, stride, pointer, ptrstride);} + GLEEPFNGLSECONDARYCOLORPOINTERLISTIBMPROC GLeeFuncPtr_glSecondaryColorPointerListIBM=GLee_Lazy_glSecondaryColorPointerListIBM; +#endif +#ifndef GLEE_C_DEFINED_glEdgeFlagPointerListIBM +#define GLEE_C_DEFINED_glEdgeFlagPointerListIBM + void __stdcall GLee_Lazy_glEdgeFlagPointerListIBM(GLint stride, const GLboolean* * pointer, GLint ptrstride) {if (GLeeInit()) glEdgeFlagPointerListIBM(stride, pointer, ptrstride);} + GLEEPFNGLEDGEFLAGPOINTERLISTIBMPROC GLeeFuncPtr_glEdgeFlagPointerListIBM=GLee_Lazy_glEdgeFlagPointerListIBM; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordPointerListIBM +#define GLEE_C_DEFINED_glFogCoordPointerListIBM + void __stdcall GLee_Lazy_glFogCoordPointerListIBM(GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride) {if (GLeeInit()) glFogCoordPointerListIBM(type, stride, pointer, ptrstride);} + GLEEPFNGLFOGCOORDPOINTERLISTIBMPROC GLeeFuncPtr_glFogCoordPointerListIBM=GLee_Lazy_glFogCoordPointerListIBM; +#endif +#ifndef GLEE_C_DEFINED_glIndexPointerListIBM +#define GLEE_C_DEFINED_glIndexPointerListIBM + void __stdcall GLee_Lazy_glIndexPointerListIBM(GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride) {if (GLeeInit()) glIndexPointerListIBM(type, stride, pointer, ptrstride);} + GLEEPFNGLINDEXPOINTERLISTIBMPROC GLeeFuncPtr_glIndexPointerListIBM=GLee_Lazy_glIndexPointerListIBM; +#endif +#ifndef GLEE_C_DEFINED_glNormalPointerListIBM +#define GLEE_C_DEFINED_glNormalPointerListIBM + void __stdcall GLee_Lazy_glNormalPointerListIBM(GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride) {if (GLeeInit()) glNormalPointerListIBM(type, stride, pointer, ptrstride);} + GLEEPFNGLNORMALPOINTERLISTIBMPROC GLeeFuncPtr_glNormalPointerListIBM=GLee_Lazy_glNormalPointerListIBM; +#endif +#ifndef GLEE_C_DEFINED_glTexCoordPointerListIBM +#define GLEE_C_DEFINED_glTexCoordPointerListIBM + void __stdcall GLee_Lazy_glTexCoordPointerListIBM(GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride) {if (GLeeInit()) glTexCoordPointerListIBM(size, type, stride, pointer, ptrstride);} + GLEEPFNGLTEXCOORDPOINTERLISTIBMPROC GLeeFuncPtr_glTexCoordPointerListIBM=GLee_Lazy_glTexCoordPointerListIBM; +#endif +#ifndef GLEE_C_DEFINED_glVertexPointerListIBM +#define GLEE_C_DEFINED_glVertexPointerListIBM + void __stdcall GLee_Lazy_glVertexPointerListIBM(GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride) {if (GLeeInit()) glVertexPointerListIBM(size, type, stride, pointer, ptrstride);} + GLEEPFNGLVERTEXPOINTERLISTIBMPROC GLeeFuncPtr_glVertexPointerListIBM=GLee_Lazy_glVertexPointerListIBM; +#endif +#endif + +/* GL_SGIX_subsample */ + +#ifdef __GLEE_GL_SGIX_subsample +#endif + +/* GL_SGIX_ycrcb_subsample */ + +#ifdef __GLEE_GL_SGIX_ycrcb_subsample +#endif + +/* GL_SGIX_ycrcba */ + +#ifdef __GLEE_GL_SGIX_ycrcba +#endif + +/* GL_SGI_depth_pass_instrument */ + +#ifdef __GLEE_GL_SGI_depth_pass_instrument +#endif + +/* GL_3DFX_texture_compression_FXT1 */ + +#ifdef __GLEE_GL_3DFX_texture_compression_FXT1 +#endif + +/* GL_3DFX_multisample */ + +#ifdef __GLEE_GL_3DFX_multisample +#endif + +/* GL_3DFX_tbuffer */ + +#ifdef __GLEE_GL_3DFX_tbuffer +#ifndef GLEE_C_DEFINED_glTbufferMask3DFX +#define GLEE_C_DEFINED_glTbufferMask3DFX + void __stdcall GLee_Lazy_glTbufferMask3DFX(GLuint mask) {if (GLeeInit()) glTbufferMask3DFX(mask);} + GLEEPFNGLTBUFFERMASK3DFXPROC GLeeFuncPtr_glTbufferMask3DFX=GLee_Lazy_glTbufferMask3DFX; +#endif +#endif + +/* GL_EXT_multisample */ + +#ifdef __GLEE_GL_EXT_multisample +#ifndef GLEE_C_DEFINED_glSampleMaskEXT +#define GLEE_C_DEFINED_glSampleMaskEXT + void __stdcall GLee_Lazy_glSampleMaskEXT(GLclampf value, GLboolean invert) {if (GLeeInit()) glSampleMaskEXT(value, invert);} + GLEEPFNGLSAMPLEMASKEXTPROC GLeeFuncPtr_glSampleMaskEXT=GLee_Lazy_glSampleMaskEXT; +#endif +#ifndef GLEE_C_DEFINED_glSamplePatternEXT +#define GLEE_C_DEFINED_glSamplePatternEXT + void __stdcall GLee_Lazy_glSamplePatternEXT(GLenum pattern) {if (GLeeInit()) glSamplePatternEXT(pattern);} + GLEEPFNGLSAMPLEPATTERNEXTPROC GLeeFuncPtr_glSamplePatternEXT=GLee_Lazy_glSamplePatternEXT; +#endif +#endif + +/* GL_SGIX_vertex_preclip */ + +#ifdef __GLEE_GL_SGIX_vertex_preclip +#endif + +/* GL_SGIX_convolution_accuracy */ + +#ifdef __GLEE_GL_SGIX_convolution_accuracy +#endif + +/* GL_SGIX_resample */ + +#ifdef __GLEE_GL_SGIX_resample +#endif + +/* GL_SGIS_point_line_texgen */ + +#ifdef __GLEE_GL_SGIS_point_line_texgen +#endif + +/* GL_SGIS_texture_color_mask */ + +#ifdef __GLEE_GL_SGIS_texture_color_mask +#ifndef GLEE_C_DEFINED_glTextureColorMaskSGIS +#define GLEE_C_DEFINED_glTextureColorMaskSGIS + void __stdcall GLee_Lazy_glTextureColorMaskSGIS(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {if (GLeeInit()) glTextureColorMaskSGIS(red, green, blue, alpha);} + GLEEPFNGLTEXTURECOLORMASKSGISPROC GLeeFuncPtr_glTextureColorMaskSGIS=GLee_Lazy_glTextureColorMaskSGIS; +#endif +#endif + +/* GL_EXT_texture_env_dot3 */ + +#ifdef __GLEE_GL_EXT_texture_env_dot3 +#endif + +/* GL_ATI_texture_mirror_once */ + +#ifdef __GLEE_GL_ATI_texture_mirror_once +#endif + +/* GL_NV_fence */ + +#ifdef __GLEE_GL_NV_fence +#ifndef GLEE_C_DEFINED_glDeleteFencesNV +#define GLEE_C_DEFINED_glDeleteFencesNV + void __stdcall GLee_Lazy_glDeleteFencesNV(GLsizei n, const GLuint * fences) {if (GLeeInit()) glDeleteFencesNV(n, fences);} + GLEEPFNGLDELETEFENCESNVPROC GLeeFuncPtr_glDeleteFencesNV=GLee_Lazy_glDeleteFencesNV; +#endif +#ifndef GLEE_C_DEFINED_glGenFencesNV +#define GLEE_C_DEFINED_glGenFencesNV + void __stdcall GLee_Lazy_glGenFencesNV(GLsizei n, GLuint * fences) {if (GLeeInit()) glGenFencesNV(n, fences);} + GLEEPFNGLGENFENCESNVPROC GLeeFuncPtr_glGenFencesNV=GLee_Lazy_glGenFencesNV; +#endif +#ifndef GLEE_C_DEFINED_glIsFenceNV +#define GLEE_C_DEFINED_glIsFenceNV + GLboolean __stdcall GLee_Lazy_glIsFenceNV(GLuint fence) {if (GLeeInit()) return glIsFenceNV(fence); return (GLboolean)0;} + GLEEPFNGLISFENCENVPROC GLeeFuncPtr_glIsFenceNV=GLee_Lazy_glIsFenceNV; +#endif +#ifndef GLEE_C_DEFINED_glTestFenceNV +#define GLEE_C_DEFINED_glTestFenceNV + GLboolean __stdcall GLee_Lazy_glTestFenceNV(GLuint fence) {if (GLeeInit()) return glTestFenceNV(fence); return (GLboolean)0;} + GLEEPFNGLTESTFENCENVPROC GLeeFuncPtr_glTestFenceNV=GLee_Lazy_glTestFenceNV; +#endif +#ifndef GLEE_C_DEFINED_glGetFenceivNV +#define GLEE_C_DEFINED_glGetFenceivNV + void __stdcall GLee_Lazy_glGetFenceivNV(GLuint fence, GLenum pname, GLint * params) {if (GLeeInit()) glGetFenceivNV(fence, pname, params);} + GLEEPFNGLGETFENCEIVNVPROC GLeeFuncPtr_glGetFenceivNV=GLee_Lazy_glGetFenceivNV; +#endif +#ifndef GLEE_C_DEFINED_glFinishFenceNV +#define GLEE_C_DEFINED_glFinishFenceNV + void __stdcall GLee_Lazy_glFinishFenceNV(GLuint fence) {if (GLeeInit()) glFinishFenceNV(fence);} + GLEEPFNGLFINISHFENCENVPROC GLeeFuncPtr_glFinishFenceNV=GLee_Lazy_glFinishFenceNV; +#endif +#ifndef GLEE_C_DEFINED_glSetFenceNV +#define GLEE_C_DEFINED_glSetFenceNV + void __stdcall GLee_Lazy_glSetFenceNV(GLuint fence, GLenum condition) {if (GLeeInit()) glSetFenceNV(fence, condition);} + GLEEPFNGLSETFENCENVPROC GLeeFuncPtr_glSetFenceNV=GLee_Lazy_glSetFenceNV; +#endif +#endif + +/* GL_IBM_texture_mirrored_repeat */ + +#ifdef __GLEE_GL_IBM_texture_mirrored_repeat +#endif + +/* GL_NV_evaluators */ + +#ifdef __GLEE_GL_NV_evaluators +#ifndef GLEE_C_DEFINED_glMapControlPointsNV +#define GLEE_C_DEFINED_glMapControlPointsNV + void __stdcall GLee_Lazy_glMapControlPointsNV(GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid * points) {if (GLeeInit()) glMapControlPointsNV(target, index, type, ustride, vstride, uorder, vorder, packed, points);} + GLEEPFNGLMAPCONTROLPOINTSNVPROC GLeeFuncPtr_glMapControlPointsNV=GLee_Lazy_glMapControlPointsNV; +#endif +#ifndef GLEE_C_DEFINED_glMapParameterivNV +#define GLEE_C_DEFINED_glMapParameterivNV + void __stdcall GLee_Lazy_glMapParameterivNV(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glMapParameterivNV(target, pname, params);} + GLEEPFNGLMAPPARAMETERIVNVPROC GLeeFuncPtr_glMapParameterivNV=GLee_Lazy_glMapParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glMapParameterfvNV +#define GLEE_C_DEFINED_glMapParameterfvNV + void __stdcall GLee_Lazy_glMapParameterfvNV(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glMapParameterfvNV(target, pname, params);} + GLEEPFNGLMAPPARAMETERFVNVPROC GLeeFuncPtr_glMapParameterfvNV=GLee_Lazy_glMapParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetMapControlPointsNV +#define GLEE_C_DEFINED_glGetMapControlPointsNV + void __stdcall GLee_Lazy_glGetMapControlPointsNV(GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid * points) {if (GLeeInit()) glGetMapControlPointsNV(target, index, type, ustride, vstride, packed, points);} + GLEEPFNGLGETMAPCONTROLPOINTSNVPROC GLeeFuncPtr_glGetMapControlPointsNV=GLee_Lazy_glGetMapControlPointsNV; +#endif +#ifndef GLEE_C_DEFINED_glGetMapParameterivNV +#define GLEE_C_DEFINED_glGetMapParameterivNV + void __stdcall GLee_Lazy_glGetMapParameterivNV(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetMapParameterivNV(target, pname, params);} + GLEEPFNGLGETMAPPARAMETERIVNVPROC GLeeFuncPtr_glGetMapParameterivNV=GLee_Lazy_glGetMapParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetMapParameterfvNV +#define GLEE_C_DEFINED_glGetMapParameterfvNV + void __stdcall GLee_Lazy_glGetMapParameterfvNV(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMapParameterfvNV(target, pname, params);} + GLEEPFNGLGETMAPPARAMETERFVNVPROC GLeeFuncPtr_glGetMapParameterfvNV=GLee_Lazy_glGetMapParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetMapAttribParameterivNV +#define GLEE_C_DEFINED_glGetMapAttribParameterivNV + void __stdcall GLee_Lazy_glGetMapAttribParameterivNV(GLenum target, GLuint index, GLenum pname, GLint * params) {if (GLeeInit()) glGetMapAttribParameterivNV(target, index, pname, params);} + GLEEPFNGLGETMAPATTRIBPARAMETERIVNVPROC GLeeFuncPtr_glGetMapAttribParameterivNV=GLee_Lazy_glGetMapAttribParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetMapAttribParameterfvNV +#define GLEE_C_DEFINED_glGetMapAttribParameterfvNV + void __stdcall GLee_Lazy_glGetMapAttribParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMapAttribParameterfvNV(target, index, pname, params);} + GLEEPFNGLGETMAPATTRIBPARAMETERFVNVPROC GLeeFuncPtr_glGetMapAttribParameterfvNV=GLee_Lazy_glGetMapAttribParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glEvalMapsNV +#define GLEE_C_DEFINED_glEvalMapsNV + void __stdcall GLee_Lazy_glEvalMapsNV(GLenum target, GLenum mode) {if (GLeeInit()) glEvalMapsNV(target, mode);} + GLEEPFNGLEVALMAPSNVPROC GLeeFuncPtr_glEvalMapsNV=GLee_Lazy_glEvalMapsNV; +#endif +#endif + +/* GL_NV_packed_depth_stencil */ + +#ifdef __GLEE_GL_NV_packed_depth_stencil +#endif + +/* GL_NV_register_combiners2 */ + +#ifdef __GLEE_GL_NV_register_combiners2 +#ifndef GLEE_C_DEFINED_glCombinerStageParameterfvNV +#define GLEE_C_DEFINED_glCombinerStageParameterfvNV + void __stdcall GLee_Lazy_glCombinerStageParameterfvNV(GLenum stage, GLenum pname, const GLfloat * params) {if (GLeeInit()) glCombinerStageParameterfvNV(stage, pname, params);} + GLEEPFNGLCOMBINERSTAGEPARAMETERFVNVPROC GLeeFuncPtr_glCombinerStageParameterfvNV=GLee_Lazy_glCombinerStageParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetCombinerStageParameterfvNV +#define GLEE_C_DEFINED_glGetCombinerStageParameterfvNV + void __stdcall GLee_Lazy_glGetCombinerStageParameterfvNV(GLenum stage, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetCombinerStageParameterfvNV(stage, pname, params);} + GLEEPFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC GLeeFuncPtr_glGetCombinerStageParameterfvNV=GLee_Lazy_glGetCombinerStageParameterfvNV; +#endif +#endif + +/* GL_NV_texture_compression_vtc */ + +#ifdef __GLEE_GL_NV_texture_compression_vtc +#endif + +/* GL_NV_texture_rectangle */ + +#ifdef __GLEE_GL_NV_texture_rectangle +#endif + +/* GL_NV_texture_shader */ + +#ifdef __GLEE_GL_NV_texture_shader +#endif + +/* GL_NV_texture_shader2 */ + +#ifdef __GLEE_GL_NV_texture_shader2 +#endif + +/* GL_NV_vertex_array_range2 */ + +#ifdef __GLEE_GL_NV_vertex_array_range2 +#endif + +/* GL_NV_vertex_program */ + +#ifdef __GLEE_GL_NV_vertex_program +#ifndef GLEE_C_DEFINED_glAreProgramsResidentNV +#define GLEE_C_DEFINED_glAreProgramsResidentNV + GLboolean __stdcall GLee_Lazy_glAreProgramsResidentNV(GLsizei n, const GLuint * programs, GLboolean * residences) {if (GLeeInit()) return glAreProgramsResidentNV(n, programs, residences); return (GLboolean)0;} + GLEEPFNGLAREPROGRAMSRESIDENTNVPROC GLeeFuncPtr_glAreProgramsResidentNV=GLee_Lazy_glAreProgramsResidentNV; +#endif +#ifndef GLEE_C_DEFINED_glBindProgramNV +#define GLEE_C_DEFINED_glBindProgramNV + void __stdcall GLee_Lazy_glBindProgramNV(GLenum target, GLuint id) {if (GLeeInit()) glBindProgramNV(target, id);} + GLEEPFNGLBINDPROGRAMNVPROC GLeeFuncPtr_glBindProgramNV=GLee_Lazy_glBindProgramNV; +#endif +#ifndef GLEE_C_DEFINED_glDeleteProgramsNV +#define GLEE_C_DEFINED_glDeleteProgramsNV + void __stdcall GLee_Lazy_glDeleteProgramsNV(GLsizei n, const GLuint * programs) {if (GLeeInit()) glDeleteProgramsNV(n, programs);} + GLEEPFNGLDELETEPROGRAMSNVPROC GLeeFuncPtr_glDeleteProgramsNV=GLee_Lazy_glDeleteProgramsNV; +#endif +#ifndef GLEE_C_DEFINED_glExecuteProgramNV +#define GLEE_C_DEFINED_glExecuteProgramNV + void __stdcall GLee_Lazy_glExecuteProgramNV(GLenum target, GLuint id, const GLfloat * params) {if (GLeeInit()) glExecuteProgramNV(target, id, params);} + GLEEPFNGLEXECUTEPROGRAMNVPROC GLeeFuncPtr_glExecuteProgramNV=GLee_Lazy_glExecuteProgramNV; +#endif +#ifndef GLEE_C_DEFINED_glGenProgramsNV +#define GLEE_C_DEFINED_glGenProgramsNV + void __stdcall GLee_Lazy_glGenProgramsNV(GLsizei n, GLuint * programs) {if (GLeeInit()) glGenProgramsNV(n, programs);} + GLEEPFNGLGENPROGRAMSNVPROC GLeeFuncPtr_glGenProgramsNV=GLee_Lazy_glGenProgramsNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramParameterdvNV +#define GLEE_C_DEFINED_glGetProgramParameterdvNV + void __stdcall GLee_Lazy_glGetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble * params) {if (GLeeInit()) glGetProgramParameterdvNV(target, index, pname, params);} + GLEEPFNGLGETPROGRAMPARAMETERDVNVPROC GLeeFuncPtr_glGetProgramParameterdvNV=GLee_Lazy_glGetProgramParameterdvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramParameterfvNV +#define GLEE_C_DEFINED_glGetProgramParameterfvNV + void __stdcall GLee_Lazy_glGetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetProgramParameterfvNV(target, index, pname, params);} + GLEEPFNGLGETPROGRAMPARAMETERFVNVPROC GLeeFuncPtr_glGetProgramParameterfvNV=GLee_Lazy_glGetProgramParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramivNV +#define GLEE_C_DEFINED_glGetProgramivNV + void __stdcall GLee_Lazy_glGetProgramivNV(GLuint id, GLenum pname, GLint * params) {if (GLeeInit()) glGetProgramivNV(id, pname, params);} + GLEEPFNGLGETPROGRAMIVNVPROC GLeeFuncPtr_glGetProgramivNV=GLee_Lazy_glGetProgramivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramStringNV +#define GLEE_C_DEFINED_glGetProgramStringNV + void __stdcall GLee_Lazy_glGetProgramStringNV(GLuint id, GLenum pname, GLubyte * program) {if (GLeeInit()) glGetProgramStringNV(id, pname, program);} + GLEEPFNGLGETPROGRAMSTRINGNVPROC GLeeFuncPtr_glGetProgramStringNV=GLee_Lazy_glGetProgramStringNV; +#endif +#ifndef GLEE_C_DEFINED_glGetTrackMatrixivNV +#define GLEE_C_DEFINED_glGetTrackMatrixivNV + void __stdcall GLee_Lazy_glGetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint * params) {if (GLeeInit()) glGetTrackMatrixivNV(target, address, pname, params);} + GLEEPFNGLGETTRACKMATRIXIVNVPROC GLeeFuncPtr_glGetTrackMatrixivNV=GLee_Lazy_glGetTrackMatrixivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribdvNV +#define GLEE_C_DEFINED_glGetVertexAttribdvNV + void __stdcall GLee_Lazy_glGetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble * params) {if (GLeeInit()) glGetVertexAttribdvNV(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBDVNVPROC GLeeFuncPtr_glGetVertexAttribdvNV=GLee_Lazy_glGetVertexAttribdvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribfvNV +#define GLEE_C_DEFINED_glGetVertexAttribfvNV + void __stdcall GLee_Lazy_glGetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetVertexAttribfvNV(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBFVNVPROC GLeeFuncPtr_glGetVertexAttribfvNV=GLee_Lazy_glGetVertexAttribfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribivNV +#define GLEE_C_DEFINED_glGetVertexAttribivNV + void __stdcall GLee_Lazy_glGetVertexAttribivNV(GLuint index, GLenum pname, GLint * params) {if (GLeeInit()) glGetVertexAttribivNV(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBIVNVPROC GLeeFuncPtr_glGetVertexAttribivNV=GLee_Lazy_glGetVertexAttribivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribPointervNV +#define GLEE_C_DEFINED_glGetVertexAttribPointervNV + void __stdcall GLee_Lazy_glGetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid* * pointer) {if (GLeeInit()) glGetVertexAttribPointervNV(index, pname, pointer);} + GLEEPFNGLGETVERTEXATTRIBPOINTERVNVPROC GLeeFuncPtr_glGetVertexAttribPointervNV=GLee_Lazy_glGetVertexAttribPointervNV; +#endif +#ifndef GLEE_C_DEFINED_glIsProgramNV +#define GLEE_C_DEFINED_glIsProgramNV + GLboolean __stdcall GLee_Lazy_glIsProgramNV(GLuint id) {if (GLeeInit()) return glIsProgramNV(id); return (GLboolean)0;} + GLEEPFNGLISPROGRAMNVPROC GLeeFuncPtr_glIsProgramNV=GLee_Lazy_glIsProgramNV; +#endif +#ifndef GLEE_C_DEFINED_glLoadProgramNV +#define GLEE_C_DEFINED_glLoadProgramNV + void __stdcall GLee_Lazy_glLoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte * program) {if (GLeeInit()) glLoadProgramNV(target, id, len, program);} + GLEEPFNGLLOADPROGRAMNVPROC GLeeFuncPtr_glLoadProgramNV=GLee_Lazy_glLoadProgramNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramParameter4dNV +#define GLEE_C_DEFINED_glProgramParameter4dNV + void __stdcall GLee_Lazy_glProgramParameter4dNV(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glProgramParameter4dNV(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMPARAMETER4DNVPROC GLeeFuncPtr_glProgramParameter4dNV=GLee_Lazy_glProgramParameter4dNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramParameter4dvNV +#define GLEE_C_DEFINED_glProgramParameter4dvNV + void __stdcall GLee_Lazy_glProgramParameter4dvNV(GLenum target, GLuint index, const GLdouble * v) {if (GLeeInit()) glProgramParameter4dvNV(target, index, v);} + GLEEPFNGLPROGRAMPARAMETER4DVNVPROC GLeeFuncPtr_glProgramParameter4dvNV=GLee_Lazy_glProgramParameter4dvNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramParameter4fNV +#define GLEE_C_DEFINED_glProgramParameter4fNV + void __stdcall GLee_Lazy_glProgramParameter4fNV(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glProgramParameter4fNV(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMPARAMETER4FNVPROC GLeeFuncPtr_glProgramParameter4fNV=GLee_Lazy_glProgramParameter4fNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramParameter4fvNV +#define GLEE_C_DEFINED_glProgramParameter4fvNV + void __stdcall GLee_Lazy_glProgramParameter4fvNV(GLenum target, GLuint index, const GLfloat * v) {if (GLeeInit()) glProgramParameter4fvNV(target, index, v);} + GLEEPFNGLPROGRAMPARAMETER4FVNVPROC GLeeFuncPtr_glProgramParameter4fvNV=GLee_Lazy_glProgramParameter4fvNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramParameters4dvNV +#define GLEE_C_DEFINED_glProgramParameters4dvNV + void __stdcall GLee_Lazy_glProgramParameters4dvNV(GLenum target, GLuint index, GLuint count, const GLdouble * v) {if (GLeeInit()) glProgramParameters4dvNV(target, index, count, v);} + GLEEPFNGLPROGRAMPARAMETERS4DVNVPROC GLeeFuncPtr_glProgramParameters4dvNV=GLee_Lazy_glProgramParameters4dvNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramParameters4fvNV +#define GLEE_C_DEFINED_glProgramParameters4fvNV + void __stdcall GLee_Lazy_glProgramParameters4fvNV(GLenum target, GLuint index, GLuint count, const GLfloat * v) {if (GLeeInit()) glProgramParameters4fvNV(target, index, count, v);} + GLEEPFNGLPROGRAMPARAMETERS4FVNVPROC GLeeFuncPtr_glProgramParameters4fvNV=GLee_Lazy_glProgramParameters4fvNV; +#endif +#ifndef GLEE_C_DEFINED_glRequestResidentProgramsNV +#define GLEE_C_DEFINED_glRequestResidentProgramsNV + void __stdcall GLee_Lazy_glRequestResidentProgramsNV(GLsizei n, const GLuint * programs) {if (GLeeInit()) glRequestResidentProgramsNV(n, programs);} + GLEEPFNGLREQUESTRESIDENTPROGRAMSNVPROC GLeeFuncPtr_glRequestResidentProgramsNV=GLee_Lazy_glRequestResidentProgramsNV; +#endif +#ifndef GLEE_C_DEFINED_glTrackMatrixNV +#define GLEE_C_DEFINED_glTrackMatrixNV + void __stdcall GLee_Lazy_glTrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform) {if (GLeeInit()) glTrackMatrixNV(target, address, matrix, transform);} + GLEEPFNGLTRACKMATRIXNVPROC GLeeFuncPtr_glTrackMatrixNV=GLee_Lazy_glTrackMatrixNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribPointerNV +#define GLEE_C_DEFINED_glVertexAttribPointerNV + void __stdcall GLee_Lazy_glVertexAttribPointerNV(GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexAttribPointerNV(index, fsize, type, stride, pointer);} + GLEEPFNGLVERTEXATTRIBPOINTERNVPROC GLeeFuncPtr_glVertexAttribPointerNV=GLee_Lazy_glVertexAttribPointerNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1dNV +#define GLEE_C_DEFINED_glVertexAttrib1dNV + void __stdcall GLee_Lazy_glVertexAttrib1dNV(GLuint index, GLdouble x) {if (GLeeInit()) glVertexAttrib1dNV(index, x);} + GLEEPFNGLVERTEXATTRIB1DNVPROC GLeeFuncPtr_glVertexAttrib1dNV=GLee_Lazy_glVertexAttrib1dNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1dvNV +#define GLEE_C_DEFINED_glVertexAttrib1dvNV + void __stdcall GLee_Lazy_glVertexAttrib1dvNV(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib1dvNV(index, v);} + GLEEPFNGLVERTEXATTRIB1DVNVPROC GLeeFuncPtr_glVertexAttrib1dvNV=GLee_Lazy_glVertexAttrib1dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1fNV +#define GLEE_C_DEFINED_glVertexAttrib1fNV + void __stdcall GLee_Lazy_glVertexAttrib1fNV(GLuint index, GLfloat x) {if (GLeeInit()) glVertexAttrib1fNV(index, x);} + GLEEPFNGLVERTEXATTRIB1FNVPROC GLeeFuncPtr_glVertexAttrib1fNV=GLee_Lazy_glVertexAttrib1fNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1fvNV +#define GLEE_C_DEFINED_glVertexAttrib1fvNV + void __stdcall GLee_Lazy_glVertexAttrib1fvNV(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib1fvNV(index, v);} + GLEEPFNGLVERTEXATTRIB1FVNVPROC GLeeFuncPtr_glVertexAttrib1fvNV=GLee_Lazy_glVertexAttrib1fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1sNV +#define GLEE_C_DEFINED_glVertexAttrib1sNV + void __stdcall GLee_Lazy_glVertexAttrib1sNV(GLuint index, GLshort x) {if (GLeeInit()) glVertexAttrib1sNV(index, x);} + GLEEPFNGLVERTEXATTRIB1SNVPROC GLeeFuncPtr_glVertexAttrib1sNV=GLee_Lazy_glVertexAttrib1sNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1svNV +#define GLEE_C_DEFINED_glVertexAttrib1svNV + void __stdcall GLee_Lazy_glVertexAttrib1svNV(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib1svNV(index, v);} + GLEEPFNGLVERTEXATTRIB1SVNVPROC GLeeFuncPtr_glVertexAttrib1svNV=GLee_Lazy_glVertexAttrib1svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2dNV +#define GLEE_C_DEFINED_glVertexAttrib2dNV + void __stdcall GLee_Lazy_glVertexAttrib2dNV(GLuint index, GLdouble x, GLdouble y) {if (GLeeInit()) glVertexAttrib2dNV(index, x, y);} + GLEEPFNGLVERTEXATTRIB2DNVPROC GLeeFuncPtr_glVertexAttrib2dNV=GLee_Lazy_glVertexAttrib2dNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2dvNV +#define GLEE_C_DEFINED_glVertexAttrib2dvNV + void __stdcall GLee_Lazy_glVertexAttrib2dvNV(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib2dvNV(index, v);} + GLEEPFNGLVERTEXATTRIB2DVNVPROC GLeeFuncPtr_glVertexAttrib2dvNV=GLee_Lazy_glVertexAttrib2dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2fNV +#define GLEE_C_DEFINED_glVertexAttrib2fNV + void __stdcall GLee_Lazy_glVertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) {if (GLeeInit()) glVertexAttrib2fNV(index, x, y);} + GLEEPFNGLVERTEXATTRIB2FNVPROC GLeeFuncPtr_glVertexAttrib2fNV=GLee_Lazy_glVertexAttrib2fNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2fvNV +#define GLEE_C_DEFINED_glVertexAttrib2fvNV + void __stdcall GLee_Lazy_glVertexAttrib2fvNV(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib2fvNV(index, v);} + GLEEPFNGLVERTEXATTRIB2FVNVPROC GLeeFuncPtr_glVertexAttrib2fvNV=GLee_Lazy_glVertexAttrib2fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2sNV +#define GLEE_C_DEFINED_glVertexAttrib2sNV + void __stdcall GLee_Lazy_glVertexAttrib2sNV(GLuint index, GLshort x, GLshort y) {if (GLeeInit()) glVertexAttrib2sNV(index, x, y);} + GLEEPFNGLVERTEXATTRIB2SNVPROC GLeeFuncPtr_glVertexAttrib2sNV=GLee_Lazy_glVertexAttrib2sNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2svNV +#define GLEE_C_DEFINED_glVertexAttrib2svNV + void __stdcall GLee_Lazy_glVertexAttrib2svNV(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib2svNV(index, v);} + GLEEPFNGLVERTEXATTRIB2SVNVPROC GLeeFuncPtr_glVertexAttrib2svNV=GLee_Lazy_glVertexAttrib2svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3dNV +#define GLEE_C_DEFINED_glVertexAttrib3dNV + void __stdcall GLee_Lazy_glVertexAttrib3dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glVertexAttrib3dNV(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3DNVPROC GLeeFuncPtr_glVertexAttrib3dNV=GLee_Lazy_glVertexAttrib3dNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3dvNV +#define GLEE_C_DEFINED_glVertexAttrib3dvNV + void __stdcall GLee_Lazy_glVertexAttrib3dvNV(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib3dvNV(index, v);} + GLEEPFNGLVERTEXATTRIB3DVNVPROC GLeeFuncPtr_glVertexAttrib3dvNV=GLee_Lazy_glVertexAttrib3dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3fNV +#define GLEE_C_DEFINED_glVertexAttrib3fNV + void __stdcall GLee_Lazy_glVertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glVertexAttrib3fNV(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3FNVPROC GLeeFuncPtr_glVertexAttrib3fNV=GLee_Lazy_glVertexAttrib3fNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3fvNV +#define GLEE_C_DEFINED_glVertexAttrib3fvNV + void __stdcall GLee_Lazy_glVertexAttrib3fvNV(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib3fvNV(index, v);} + GLEEPFNGLVERTEXATTRIB3FVNVPROC GLeeFuncPtr_glVertexAttrib3fvNV=GLee_Lazy_glVertexAttrib3fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3sNV +#define GLEE_C_DEFINED_glVertexAttrib3sNV + void __stdcall GLee_Lazy_glVertexAttrib3sNV(GLuint index, GLshort x, GLshort y, GLshort z) {if (GLeeInit()) glVertexAttrib3sNV(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3SNVPROC GLeeFuncPtr_glVertexAttrib3sNV=GLee_Lazy_glVertexAttrib3sNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3svNV +#define GLEE_C_DEFINED_glVertexAttrib3svNV + void __stdcall GLee_Lazy_glVertexAttrib3svNV(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib3svNV(index, v);} + GLEEPFNGLVERTEXATTRIB3SVNVPROC GLeeFuncPtr_glVertexAttrib3svNV=GLee_Lazy_glVertexAttrib3svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4dNV +#define GLEE_C_DEFINED_glVertexAttrib4dNV + void __stdcall GLee_Lazy_glVertexAttrib4dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glVertexAttrib4dNV(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4DNVPROC GLeeFuncPtr_glVertexAttrib4dNV=GLee_Lazy_glVertexAttrib4dNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4dvNV +#define GLEE_C_DEFINED_glVertexAttrib4dvNV + void __stdcall GLee_Lazy_glVertexAttrib4dvNV(GLuint index, const GLdouble * v) {if (GLeeInit()) glVertexAttrib4dvNV(index, v);} + GLEEPFNGLVERTEXATTRIB4DVNVPROC GLeeFuncPtr_glVertexAttrib4dvNV=GLee_Lazy_glVertexAttrib4dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4fNV +#define GLEE_C_DEFINED_glVertexAttrib4fNV + void __stdcall GLee_Lazy_glVertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glVertexAttrib4fNV(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4FNVPROC GLeeFuncPtr_glVertexAttrib4fNV=GLee_Lazy_glVertexAttrib4fNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4fvNV +#define GLEE_C_DEFINED_glVertexAttrib4fvNV + void __stdcall GLee_Lazy_glVertexAttrib4fvNV(GLuint index, const GLfloat * v) {if (GLeeInit()) glVertexAttrib4fvNV(index, v);} + GLEEPFNGLVERTEXATTRIB4FVNVPROC GLeeFuncPtr_glVertexAttrib4fvNV=GLee_Lazy_glVertexAttrib4fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4sNV +#define GLEE_C_DEFINED_glVertexAttrib4sNV + void __stdcall GLee_Lazy_glVertexAttrib4sNV(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {if (GLeeInit()) glVertexAttrib4sNV(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4SNVPROC GLeeFuncPtr_glVertexAttrib4sNV=GLee_Lazy_glVertexAttrib4sNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4svNV +#define GLEE_C_DEFINED_glVertexAttrib4svNV + void __stdcall GLee_Lazy_glVertexAttrib4svNV(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttrib4svNV(index, v);} + GLEEPFNGLVERTEXATTRIB4SVNVPROC GLeeFuncPtr_glVertexAttrib4svNV=GLee_Lazy_glVertexAttrib4svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4ubNV +#define GLEE_C_DEFINED_glVertexAttrib4ubNV + void __stdcall GLee_Lazy_glVertexAttrib4ubNV(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {if (GLeeInit()) glVertexAttrib4ubNV(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4UBNVPROC GLeeFuncPtr_glVertexAttrib4ubNV=GLee_Lazy_glVertexAttrib4ubNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4ubvNV +#define GLEE_C_DEFINED_glVertexAttrib4ubvNV + void __stdcall GLee_Lazy_glVertexAttrib4ubvNV(GLuint index, const GLubyte * v) {if (GLeeInit()) glVertexAttrib4ubvNV(index, v);} + GLEEPFNGLVERTEXATTRIB4UBVNVPROC GLeeFuncPtr_glVertexAttrib4ubvNV=GLee_Lazy_glVertexAttrib4ubvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs1dvNV +#define GLEE_C_DEFINED_glVertexAttribs1dvNV + void __stdcall GLee_Lazy_glVertexAttribs1dvNV(GLuint index, GLsizei count, const GLdouble * v) {if (GLeeInit()) glVertexAttribs1dvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS1DVNVPROC GLeeFuncPtr_glVertexAttribs1dvNV=GLee_Lazy_glVertexAttribs1dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs1fvNV +#define GLEE_C_DEFINED_glVertexAttribs1fvNV + void __stdcall GLee_Lazy_glVertexAttribs1fvNV(GLuint index, GLsizei count, const GLfloat * v) {if (GLeeInit()) glVertexAttribs1fvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS1FVNVPROC GLeeFuncPtr_glVertexAttribs1fvNV=GLee_Lazy_glVertexAttribs1fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs1svNV +#define GLEE_C_DEFINED_glVertexAttribs1svNV + void __stdcall GLee_Lazy_glVertexAttribs1svNV(GLuint index, GLsizei count, const GLshort * v) {if (GLeeInit()) glVertexAttribs1svNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS1SVNVPROC GLeeFuncPtr_glVertexAttribs1svNV=GLee_Lazy_glVertexAttribs1svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs2dvNV +#define GLEE_C_DEFINED_glVertexAttribs2dvNV + void __stdcall GLee_Lazy_glVertexAttribs2dvNV(GLuint index, GLsizei count, const GLdouble * v) {if (GLeeInit()) glVertexAttribs2dvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS2DVNVPROC GLeeFuncPtr_glVertexAttribs2dvNV=GLee_Lazy_glVertexAttribs2dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs2fvNV +#define GLEE_C_DEFINED_glVertexAttribs2fvNV + void __stdcall GLee_Lazy_glVertexAttribs2fvNV(GLuint index, GLsizei count, const GLfloat * v) {if (GLeeInit()) glVertexAttribs2fvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS2FVNVPROC GLeeFuncPtr_glVertexAttribs2fvNV=GLee_Lazy_glVertexAttribs2fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs2svNV +#define GLEE_C_DEFINED_glVertexAttribs2svNV + void __stdcall GLee_Lazy_glVertexAttribs2svNV(GLuint index, GLsizei count, const GLshort * v) {if (GLeeInit()) glVertexAttribs2svNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS2SVNVPROC GLeeFuncPtr_glVertexAttribs2svNV=GLee_Lazy_glVertexAttribs2svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs3dvNV +#define GLEE_C_DEFINED_glVertexAttribs3dvNV + void __stdcall GLee_Lazy_glVertexAttribs3dvNV(GLuint index, GLsizei count, const GLdouble * v) {if (GLeeInit()) glVertexAttribs3dvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS3DVNVPROC GLeeFuncPtr_glVertexAttribs3dvNV=GLee_Lazy_glVertexAttribs3dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs3fvNV +#define GLEE_C_DEFINED_glVertexAttribs3fvNV + void __stdcall GLee_Lazy_glVertexAttribs3fvNV(GLuint index, GLsizei count, const GLfloat * v) {if (GLeeInit()) glVertexAttribs3fvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS3FVNVPROC GLeeFuncPtr_glVertexAttribs3fvNV=GLee_Lazy_glVertexAttribs3fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs3svNV +#define GLEE_C_DEFINED_glVertexAttribs3svNV + void __stdcall GLee_Lazy_glVertexAttribs3svNV(GLuint index, GLsizei count, const GLshort * v) {if (GLeeInit()) glVertexAttribs3svNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS3SVNVPROC GLeeFuncPtr_glVertexAttribs3svNV=GLee_Lazy_glVertexAttribs3svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs4dvNV +#define GLEE_C_DEFINED_glVertexAttribs4dvNV + void __stdcall GLee_Lazy_glVertexAttribs4dvNV(GLuint index, GLsizei count, const GLdouble * v) {if (GLeeInit()) glVertexAttribs4dvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS4DVNVPROC GLeeFuncPtr_glVertexAttribs4dvNV=GLee_Lazy_glVertexAttribs4dvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs4fvNV +#define GLEE_C_DEFINED_glVertexAttribs4fvNV + void __stdcall GLee_Lazy_glVertexAttribs4fvNV(GLuint index, GLsizei count, const GLfloat * v) {if (GLeeInit()) glVertexAttribs4fvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS4FVNVPROC GLeeFuncPtr_glVertexAttribs4fvNV=GLee_Lazy_glVertexAttribs4fvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs4svNV +#define GLEE_C_DEFINED_glVertexAttribs4svNV + void __stdcall GLee_Lazy_glVertexAttribs4svNV(GLuint index, GLsizei count, const GLshort * v) {if (GLeeInit()) glVertexAttribs4svNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS4SVNVPROC GLeeFuncPtr_glVertexAttribs4svNV=GLee_Lazy_glVertexAttribs4svNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs4ubvNV +#define GLEE_C_DEFINED_glVertexAttribs4ubvNV + void __stdcall GLee_Lazy_glVertexAttribs4ubvNV(GLuint index, GLsizei count, const GLubyte * v) {if (GLeeInit()) glVertexAttribs4ubvNV(index, count, v);} + GLEEPFNGLVERTEXATTRIBS4UBVNVPROC GLeeFuncPtr_glVertexAttribs4ubvNV=GLee_Lazy_glVertexAttribs4ubvNV; +#endif +#endif + +/* GL_SGIX_texture_coordinate_clamp */ + +#ifdef __GLEE_GL_SGIX_texture_coordinate_clamp +#endif + +/* GL_SGIX_scalebias_hint */ + +#ifdef __GLEE_GL_SGIX_scalebias_hint +#endif + +/* GL_OML_interlace */ + +#ifdef __GLEE_GL_OML_interlace +#endif + +/* GL_OML_subsample */ + +#ifdef __GLEE_GL_OML_subsample +#endif + +/* GL_OML_resample */ + +#ifdef __GLEE_GL_OML_resample +#endif + +/* GL_NV_copy_depth_to_color */ + +#ifdef __GLEE_GL_NV_copy_depth_to_color +#endif + +/* GL_ATI_envmap_bumpmap */ + +#ifdef __GLEE_GL_ATI_envmap_bumpmap +#ifndef GLEE_C_DEFINED_glTexBumpParameterivATI +#define GLEE_C_DEFINED_glTexBumpParameterivATI + void __stdcall GLee_Lazy_glTexBumpParameterivATI(GLenum pname, const GLint * param) {if (GLeeInit()) glTexBumpParameterivATI(pname, param);} + GLEEPFNGLTEXBUMPPARAMETERIVATIPROC GLeeFuncPtr_glTexBumpParameterivATI=GLee_Lazy_glTexBumpParameterivATI; +#endif +#ifndef GLEE_C_DEFINED_glTexBumpParameterfvATI +#define GLEE_C_DEFINED_glTexBumpParameterfvATI + void __stdcall GLee_Lazy_glTexBumpParameterfvATI(GLenum pname, const GLfloat * param) {if (GLeeInit()) glTexBumpParameterfvATI(pname, param);} + GLEEPFNGLTEXBUMPPARAMETERFVATIPROC GLeeFuncPtr_glTexBumpParameterfvATI=GLee_Lazy_glTexBumpParameterfvATI; +#endif +#ifndef GLEE_C_DEFINED_glGetTexBumpParameterivATI +#define GLEE_C_DEFINED_glGetTexBumpParameterivATI + void __stdcall GLee_Lazy_glGetTexBumpParameterivATI(GLenum pname, GLint * param) {if (GLeeInit()) glGetTexBumpParameterivATI(pname, param);} + GLEEPFNGLGETTEXBUMPPARAMETERIVATIPROC GLeeFuncPtr_glGetTexBumpParameterivATI=GLee_Lazy_glGetTexBumpParameterivATI; +#endif +#ifndef GLEE_C_DEFINED_glGetTexBumpParameterfvATI +#define GLEE_C_DEFINED_glGetTexBumpParameterfvATI + void __stdcall GLee_Lazy_glGetTexBumpParameterfvATI(GLenum pname, GLfloat * param) {if (GLeeInit()) glGetTexBumpParameterfvATI(pname, param);} + GLEEPFNGLGETTEXBUMPPARAMETERFVATIPROC GLeeFuncPtr_glGetTexBumpParameterfvATI=GLee_Lazy_glGetTexBumpParameterfvATI; +#endif +#endif + +/* GL_ATI_fragment_shader */ + +#ifdef __GLEE_GL_ATI_fragment_shader +#ifndef GLEE_C_DEFINED_glGenFragmentShadersATI +#define GLEE_C_DEFINED_glGenFragmentShadersATI + GLuint __stdcall GLee_Lazy_glGenFragmentShadersATI(GLuint range) {if (GLeeInit()) return glGenFragmentShadersATI(range); return (GLuint)0;} + GLEEPFNGLGENFRAGMENTSHADERSATIPROC GLeeFuncPtr_glGenFragmentShadersATI=GLee_Lazy_glGenFragmentShadersATI; +#endif +#ifndef GLEE_C_DEFINED_glBindFragmentShaderATI +#define GLEE_C_DEFINED_glBindFragmentShaderATI + void __stdcall GLee_Lazy_glBindFragmentShaderATI(GLuint id) {if (GLeeInit()) glBindFragmentShaderATI(id);} + GLEEPFNGLBINDFRAGMENTSHADERATIPROC GLeeFuncPtr_glBindFragmentShaderATI=GLee_Lazy_glBindFragmentShaderATI; +#endif +#ifndef GLEE_C_DEFINED_glDeleteFragmentShaderATI +#define GLEE_C_DEFINED_glDeleteFragmentShaderATI + void __stdcall GLee_Lazy_glDeleteFragmentShaderATI(GLuint id) {if (GLeeInit()) glDeleteFragmentShaderATI(id);} + GLEEPFNGLDELETEFRAGMENTSHADERATIPROC GLeeFuncPtr_glDeleteFragmentShaderATI=GLee_Lazy_glDeleteFragmentShaderATI; +#endif +#ifndef GLEE_C_DEFINED_glBeginFragmentShaderATI +#define GLEE_C_DEFINED_glBeginFragmentShaderATI + void __stdcall GLee_Lazy_glBeginFragmentShaderATI(void) {if (GLeeInit()) glBeginFragmentShaderATI();} + GLEEPFNGLBEGINFRAGMENTSHADERATIPROC GLeeFuncPtr_glBeginFragmentShaderATI=GLee_Lazy_glBeginFragmentShaderATI; +#endif +#ifndef GLEE_C_DEFINED_glEndFragmentShaderATI +#define GLEE_C_DEFINED_glEndFragmentShaderATI + void __stdcall GLee_Lazy_glEndFragmentShaderATI(void) {if (GLeeInit()) glEndFragmentShaderATI();} + GLEEPFNGLENDFRAGMENTSHADERATIPROC GLeeFuncPtr_glEndFragmentShaderATI=GLee_Lazy_glEndFragmentShaderATI; +#endif +#ifndef GLEE_C_DEFINED_glPassTexCoordATI +#define GLEE_C_DEFINED_glPassTexCoordATI + void __stdcall GLee_Lazy_glPassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle) {if (GLeeInit()) glPassTexCoordATI(dst, coord, swizzle);} + GLEEPFNGLPASSTEXCOORDATIPROC GLeeFuncPtr_glPassTexCoordATI=GLee_Lazy_glPassTexCoordATI; +#endif +#ifndef GLEE_C_DEFINED_glSampleMapATI +#define GLEE_C_DEFINED_glSampleMapATI + void __stdcall GLee_Lazy_glSampleMapATI(GLuint dst, GLuint interp, GLenum swizzle) {if (GLeeInit()) glSampleMapATI(dst, interp, swizzle);} + GLEEPFNGLSAMPLEMAPATIPROC GLeeFuncPtr_glSampleMapATI=GLee_Lazy_glSampleMapATI; +#endif +#ifndef GLEE_C_DEFINED_glColorFragmentOp1ATI +#define GLEE_C_DEFINED_glColorFragmentOp1ATI + void __stdcall GLee_Lazy_glColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) {if (GLeeInit()) glColorFragmentOp1ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod);} + GLEEPFNGLCOLORFRAGMENTOP1ATIPROC GLeeFuncPtr_glColorFragmentOp1ATI=GLee_Lazy_glColorFragmentOp1ATI; +#endif +#ifndef GLEE_C_DEFINED_glColorFragmentOp2ATI +#define GLEE_C_DEFINED_glColorFragmentOp2ATI + void __stdcall GLee_Lazy_glColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) {if (GLeeInit()) glColorFragmentOp2ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod);} + GLEEPFNGLCOLORFRAGMENTOP2ATIPROC GLeeFuncPtr_glColorFragmentOp2ATI=GLee_Lazy_glColorFragmentOp2ATI; +#endif +#ifndef GLEE_C_DEFINED_glColorFragmentOp3ATI +#define GLEE_C_DEFINED_glColorFragmentOp3ATI + void __stdcall GLee_Lazy_glColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) {if (GLeeInit()) glColorFragmentOp3ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod);} + GLEEPFNGLCOLORFRAGMENTOP3ATIPROC GLeeFuncPtr_glColorFragmentOp3ATI=GLee_Lazy_glColorFragmentOp3ATI; +#endif +#ifndef GLEE_C_DEFINED_glAlphaFragmentOp1ATI +#define GLEE_C_DEFINED_glAlphaFragmentOp1ATI + void __stdcall GLee_Lazy_glAlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) {if (GLeeInit()) glAlphaFragmentOp1ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod);} + GLEEPFNGLALPHAFRAGMENTOP1ATIPROC GLeeFuncPtr_glAlphaFragmentOp1ATI=GLee_Lazy_glAlphaFragmentOp1ATI; +#endif +#ifndef GLEE_C_DEFINED_glAlphaFragmentOp2ATI +#define GLEE_C_DEFINED_glAlphaFragmentOp2ATI + void __stdcall GLee_Lazy_glAlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) {if (GLeeInit()) glAlphaFragmentOp2ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod);} + GLEEPFNGLALPHAFRAGMENTOP2ATIPROC GLeeFuncPtr_glAlphaFragmentOp2ATI=GLee_Lazy_glAlphaFragmentOp2ATI; +#endif +#ifndef GLEE_C_DEFINED_glAlphaFragmentOp3ATI +#define GLEE_C_DEFINED_glAlphaFragmentOp3ATI + void __stdcall GLee_Lazy_glAlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) {if (GLeeInit()) glAlphaFragmentOp3ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod);} + GLEEPFNGLALPHAFRAGMENTOP3ATIPROC GLeeFuncPtr_glAlphaFragmentOp3ATI=GLee_Lazy_glAlphaFragmentOp3ATI; +#endif +#ifndef GLEE_C_DEFINED_glSetFragmentShaderConstantATI +#define GLEE_C_DEFINED_glSetFragmentShaderConstantATI + void __stdcall GLee_Lazy_glSetFragmentShaderConstantATI(GLuint dst, const GLfloat * value) {if (GLeeInit()) glSetFragmentShaderConstantATI(dst, value);} + GLEEPFNGLSETFRAGMENTSHADERCONSTANTATIPROC GLeeFuncPtr_glSetFragmentShaderConstantATI=GLee_Lazy_glSetFragmentShaderConstantATI; +#endif +#endif + +/* GL_ATI_pn_triangles */ + +#ifdef __GLEE_GL_ATI_pn_triangles +#ifndef GLEE_C_DEFINED_glPNTrianglesiATI +#define GLEE_C_DEFINED_glPNTrianglesiATI + void __stdcall GLee_Lazy_glPNTrianglesiATI(GLenum pname, GLint param) {if (GLeeInit()) glPNTrianglesiATI(pname, param);} + GLEEPFNGLPNTRIANGLESIATIPROC GLeeFuncPtr_glPNTrianglesiATI=GLee_Lazy_glPNTrianglesiATI; +#endif +#ifndef GLEE_C_DEFINED_glPNTrianglesfATI +#define GLEE_C_DEFINED_glPNTrianglesfATI + void __stdcall GLee_Lazy_glPNTrianglesfATI(GLenum pname, GLfloat param) {if (GLeeInit()) glPNTrianglesfATI(pname, param);} + GLEEPFNGLPNTRIANGLESFATIPROC GLeeFuncPtr_glPNTrianglesfATI=GLee_Lazy_glPNTrianglesfATI; +#endif +#endif + +/* GL_ATI_vertex_array_object */ + +#ifdef __GLEE_GL_ATI_vertex_array_object +#ifndef GLEE_C_DEFINED_glNewObjectBufferATI +#define GLEE_C_DEFINED_glNewObjectBufferATI + GLuint __stdcall GLee_Lazy_glNewObjectBufferATI(GLsizei size, const GLvoid * pointer, GLenum usage) {if (GLeeInit()) return glNewObjectBufferATI(size, pointer, usage); return (GLuint)0;} + GLEEPFNGLNEWOBJECTBUFFERATIPROC GLeeFuncPtr_glNewObjectBufferATI=GLee_Lazy_glNewObjectBufferATI; +#endif +#ifndef GLEE_C_DEFINED_glIsObjectBufferATI +#define GLEE_C_DEFINED_glIsObjectBufferATI + GLboolean __stdcall GLee_Lazy_glIsObjectBufferATI(GLuint buffer) {if (GLeeInit()) return glIsObjectBufferATI(buffer); return (GLboolean)0;} + GLEEPFNGLISOBJECTBUFFERATIPROC GLeeFuncPtr_glIsObjectBufferATI=GLee_Lazy_glIsObjectBufferATI; +#endif +#ifndef GLEE_C_DEFINED_glUpdateObjectBufferATI +#define GLEE_C_DEFINED_glUpdateObjectBufferATI + void __stdcall GLee_Lazy_glUpdateObjectBufferATI(GLuint buffer, GLuint offset, GLsizei size, const GLvoid * pointer, GLenum preserve) {if (GLeeInit()) glUpdateObjectBufferATI(buffer, offset, size, pointer, preserve);} + GLEEPFNGLUPDATEOBJECTBUFFERATIPROC GLeeFuncPtr_glUpdateObjectBufferATI=GLee_Lazy_glUpdateObjectBufferATI; +#endif +#ifndef GLEE_C_DEFINED_glGetObjectBufferfvATI +#define GLEE_C_DEFINED_glGetObjectBufferfvATI + void __stdcall GLee_Lazy_glGetObjectBufferfvATI(GLuint buffer, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetObjectBufferfvATI(buffer, pname, params);} + GLEEPFNGLGETOBJECTBUFFERFVATIPROC GLeeFuncPtr_glGetObjectBufferfvATI=GLee_Lazy_glGetObjectBufferfvATI; +#endif +#ifndef GLEE_C_DEFINED_glGetObjectBufferivATI +#define GLEE_C_DEFINED_glGetObjectBufferivATI + void __stdcall GLee_Lazy_glGetObjectBufferivATI(GLuint buffer, GLenum pname, GLint * params) {if (GLeeInit()) glGetObjectBufferivATI(buffer, pname, params);} + GLEEPFNGLGETOBJECTBUFFERIVATIPROC GLeeFuncPtr_glGetObjectBufferivATI=GLee_Lazy_glGetObjectBufferivATI; +#endif +#ifndef GLEE_C_DEFINED_glFreeObjectBufferATI +#define GLEE_C_DEFINED_glFreeObjectBufferATI + void __stdcall GLee_Lazy_glFreeObjectBufferATI(GLuint buffer) {if (GLeeInit()) glFreeObjectBufferATI(buffer);} + GLEEPFNGLFREEOBJECTBUFFERATIPROC GLeeFuncPtr_glFreeObjectBufferATI=GLee_Lazy_glFreeObjectBufferATI; +#endif +#ifndef GLEE_C_DEFINED_glArrayObjectATI +#define GLEE_C_DEFINED_glArrayObjectATI + void __stdcall GLee_Lazy_glArrayObjectATI(GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset) {if (GLeeInit()) glArrayObjectATI(array, size, type, stride, buffer, offset);} + GLEEPFNGLARRAYOBJECTATIPROC GLeeFuncPtr_glArrayObjectATI=GLee_Lazy_glArrayObjectATI; +#endif +#ifndef GLEE_C_DEFINED_glGetArrayObjectfvATI +#define GLEE_C_DEFINED_glGetArrayObjectfvATI + void __stdcall GLee_Lazy_glGetArrayObjectfvATI(GLenum array, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetArrayObjectfvATI(array, pname, params);} + GLEEPFNGLGETARRAYOBJECTFVATIPROC GLeeFuncPtr_glGetArrayObjectfvATI=GLee_Lazy_glGetArrayObjectfvATI; +#endif +#ifndef GLEE_C_DEFINED_glGetArrayObjectivATI +#define GLEE_C_DEFINED_glGetArrayObjectivATI + void __stdcall GLee_Lazy_glGetArrayObjectivATI(GLenum array, GLenum pname, GLint * params) {if (GLeeInit()) glGetArrayObjectivATI(array, pname, params);} + GLEEPFNGLGETARRAYOBJECTIVATIPROC GLeeFuncPtr_glGetArrayObjectivATI=GLee_Lazy_glGetArrayObjectivATI; +#endif +#ifndef GLEE_C_DEFINED_glVariantArrayObjectATI +#define GLEE_C_DEFINED_glVariantArrayObjectATI + void __stdcall GLee_Lazy_glVariantArrayObjectATI(GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset) {if (GLeeInit()) glVariantArrayObjectATI(id, type, stride, buffer, offset);} + GLEEPFNGLVARIANTARRAYOBJECTATIPROC GLeeFuncPtr_glVariantArrayObjectATI=GLee_Lazy_glVariantArrayObjectATI; +#endif +#ifndef GLEE_C_DEFINED_glGetVariantArrayObjectfvATI +#define GLEE_C_DEFINED_glGetVariantArrayObjectfvATI + void __stdcall GLee_Lazy_glGetVariantArrayObjectfvATI(GLuint id, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetVariantArrayObjectfvATI(id, pname, params);} + GLEEPFNGLGETVARIANTARRAYOBJECTFVATIPROC GLeeFuncPtr_glGetVariantArrayObjectfvATI=GLee_Lazy_glGetVariantArrayObjectfvATI; +#endif +#ifndef GLEE_C_DEFINED_glGetVariantArrayObjectivATI +#define GLEE_C_DEFINED_glGetVariantArrayObjectivATI + void __stdcall GLee_Lazy_glGetVariantArrayObjectivATI(GLuint id, GLenum pname, GLint * params) {if (GLeeInit()) glGetVariantArrayObjectivATI(id, pname, params);} + GLEEPFNGLGETVARIANTARRAYOBJECTIVATIPROC GLeeFuncPtr_glGetVariantArrayObjectivATI=GLee_Lazy_glGetVariantArrayObjectivATI; +#endif +#endif + +/* GL_EXT_vertex_shader */ + +#ifdef __GLEE_GL_EXT_vertex_shader +#ifndef GLEE_C_DEFINED_glBeginVertexShaderEXT +#define GLEE_C_DEFINED_glBeginVertexShaderEXT + void __stdcall GLee_Lazy_glBeginVertexShaderEXT(void) {if (GLeeInit()) glBeginVertexShaderEXT();} + GLEEPFNGLBEGINVERTEXSHADEREXTPROC GLeeFuncPtr_glBeginVertexShaderEXT=GLee_Lazy_glBeginVertexShaderEXT; +#endif +#ifndef GLEE_C_DEFINED_glEndVertexShaderEXT +#define GLEE_C_DEFINED_glEndVertexShaderEXT + void __stdcall GLee_Lazy_glEndVertexShaderEXT(void) {if (GLeeInit()) glEndVertexShaderEXT();} + GLEEPFNGLENDVERTEXSHADEREXTPROC GLeeFuncPtr_glEndVertexShaderEXT=GLee_Lazy_glEndVertexShaderEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindVertexShaderEXT +#define GLEE_C_DEFINED_glBindVertexShaderEXT + void __stdcall GLee_Lazy_glBindVertexShaderEXT(GLuint id) {if (GLeeInit()) glBindVertexShaderEXT(id);} + GLEEPFNGLBINDVERTEXSHADEREXTPROC GLeeFuncPtr_glBindVertexShaderEXT=GLee_Lazy_glBindVertexShaderEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenVertexShadersEXT +#define GLEE_C_DEFINED_glGenVertexShadersEXT + GLuint __stdcall GLee_Lazy_glGenVertexShadersEXT(GLuint range) {if (GLeeInit()) return glGenVertexShadersEXT(range); return (GLuint)0;} + GLEEPFNGLGENVERTEXSHADERSEXTPROC GLeeFuncPtr_glGenVertexShadersEXT=GLee_Lazy_glGenVertexShadersEXT; +#endif +#ifndef GLEE_C_DEFINED_glDeleteVertexShaderEXT +#define GLEE_C_DEFINED_glDeleteVertexShaderEXT + void __stdcall GLee_Lazy_glDeleteVertexShaderEXT(GLuint id) {if (GLeeInit()) glDeleteVertexShaderEXT(id);} + GLEEPFNGLDELETEVERTEXSHADEREXTPROC GLeeFuncPtr_glDeleteVertexShaderEXT=GLee_Lazy_glDeleteVertexShaderEXT; +#endif +#ifndef GLEE_C_DEFINED_glShaderOp1EXT +#define GLEE_C_DEFINED_glShaderOp1EXT + void __stdcall GLee_Lazy_glShaderOp1EXT(GLenum op, GLuint res, GLuint arg1) {if (GLeeInit()) glShaderOp1EXT(op, res, arg1);} + GLEEPFNGLSHADEROP1EXTPROC GLeeFuncPtr_glShaderOp1EXT=GLee_Lazy_glShaderOp1EXT; +#endif +#ifndef GLEE_C_DEFINED_glShaderOp2EXT +#define GLEE_C_DEFINED_glShaderOp2EXT + void __stdcall GLee_Lazy_glShaderOp2EXT(GLenum op, GLuint res, GLuint arg1, GLuint arg2) {if (GLeeInit()) glShaderOp2EXT(op, res, arg1, arg2);} + GLEEPFNGLSHADEROP2EXTPROC GLeeFuncPtr_glShaderOp2EXT=GLee_Lazy_glShaderOp2EXT; +#endif +#ifndef GLEE_C_DEFINED_glShaderOp3EXT +#define GLEE_C_DEFINED_glShaderOp3EXT + void __stdcall GLee_Lazy_glShaderOp3EXT(GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3) {if (GLeeInit()) glShaderOp3EXT(op, res, arg1, arg2, arg3);} + GLEEPFNGLSHADEROP3EXTPROC GLeeFuncPtr_glShaderOp3EXT=GLee_Lazy_glShaderOp3EXT; +#endif +#ifndef GLEE_C_DEFINED_glSwizzleEXT +#define GLEE_C_DEFINED_glSwizzleEXT + void __stdcall GLee_Lazy_glSwizzleEXT(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW) {if (GLeeInit()) glSwizzleEXT(res, in, outX, outY, outZ, outW);} + GLEEPFNGLSWIZZLEEXTPROC GLeeFuncPtr_glSwizzleEXT=GLee_Lazy_glSwizzleEXT; +#endif +#ifndef GLEE_C_DEFINED_glWriteMaskEXT +#define GLEE_C_DEFINED_glWriteMaskEXT + void __stdcall GLee_Lazy_glWriteMaskEXT(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW) {if (GLeeInit()) glWriteMaskEXT(res, in, outX, outY, outZ, outW);} + GLEEPFNGLWRITEMASKEXTPROC GLeeFuncPtr_glWriteMaskEXT=GLee_Lazy_glWriteMaskEXT; +#endif +#ifndef GLEE_C_DEFINED_glInsertComponentEXT +#define GLEE_C_DEFINED_glInsertComponentEXT + void __stdcall GLee_Lazy_glInsertComponentEXT(GLuint res, GLuint src, GLuint num) {if (GLeeInit()) glInsertComponentEXT(res, src, num);} + GLEEPFNGLINSERTCOMPONENTEXTPROC GLeeFuncPtr_glInsertComponentEXT=GLee_Lazy_glInsertComponentEXT; +#endif +#ifndef GLEE_C_DEFINED_glExtractComponentEXT +#define GLEE_C_DEFINED_glExtractComponentEXT + void __stdcall GLee_Lazy_glExtractComponentEXT(GLuint res, GLuint src, GLuint num) {if (GLeeInit()) glExtractComponentEXT(res, src, num);} + GLEEPFNGLEXTRACTCOMPONENTEXTPROC GLeeFuncPtr_glExtractComponentEXT=GLee_Lazy_glExtractComponentEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenSymbolsEXT +#define GLEE_C_DEFINED_glGenSymbolsEXT + GLuint __stdcall GLee_Lazy_glGenSymbolsEXT(GLenum datatype, GLenum storagetype, GLenum range, GLuint components) {if (GLeeInit()) return glGenSymbolsEXT(datatype, storagetype, range, components); return (GLuint)0;} + GLEEPFNGLGENSYMBOLSEXTPROC GLeeFuncPtr_glGenSymbolsEXT=GLee_Lazy_glGenSymbolsEXT; +#endif +#ifndef GLEE_C_DEFINED_glSetInvariantEXT +#define GLEE_C_DEFINED_glSetInvariantEXT + void __stdcall GLee_Lazy_glSetInvariantEXT(GLuint id, GLenum type, const GLvoid * addr) {if (GLeeInit()) glSetInvariantEXT(id, type, addr);} + GLEEPFNGLSETINVARIANTEXTPROC GLeeFuncPtr_glSetInvariantEXT=GLee_Lazy_glSetInvariantEXT; +#endif +#ifndef GLEE_C_DEFINED_glSetLocalConstantEXT +#define GLEE_C_DEFINED_glSetLocalConstantEXT + void __stdcall GLee_Lazy_glSetLocalConstantEXT(GLuint id, GLenum type, const GLvoid * addr) {if (GLeeInit()) glSetLocalConstantEXT(id, type, addr);} + GLEEPFNGLSETLOCALCONSTANTEXTPROC GLeeFuncPtr_glSetLocalConstantEXT=GLee_Lazy_glSetLocalConstantEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantbvEXT +#define GLEE_C_DEFINED_glVariantbvEXT + void __stdcall GLee_Lazy_glVariantbvEXT(GLuint id, const GLbyte * addr) {if (GLeeInit()) glVariantbvEXT(id, addr);} + GLEEPFNGLVARIANTBVEXTPROC GLeeFuncPtr_glVariantbvEXT=GLee_Lazy_glVariantbvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantsvEXT +#define GLEE_C_DEFINED_glVariantsvEXT + void __stdcall GLee_Lazy_glVariantsvEXT(GLuint id, const GLshort * addr) {if (GLeeInit()) glVariantsvEXT(id, addr);} + GLEEPFNGLVARIANTSVEXTPROC GLeeFuncPtr_glVariantsvEXT=GLee_Lazy_glVariantsvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantivEXT +#define GLEE_C_DEFINED_glVariantivEXT + void __stdcall GLee_Lazy_glVariantivEXT(GLuint id, const GLint * addr) {if (GLeeInit()) glVariantivEXT(id, addr);} + GLEEPFNGLVARIANTIVEXTPROC GLeeFuncPtr_glVariantivEXT=GLee_Lazy_glVariantivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantfvEXT +#define GLEE_C_DEFINED_glVariantfvEXT + void __stdcall GLee_Lazy_glVariantfvEXT(GLuint id, const GLfloat * addr) {if (GLeeInit()) glVariantfvEXT(id, addr);} + GLEEPFNGLVARIANTFVEXTPROC GLeeFuncPtr_glVariantfvEXT=GLee_Lazy_glVariantfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantdvEXT +#define GLEE_C_DEFINED_glVariantdvEXT + void __stdcall GLee_Lazy_glVariantdvEXT(GLuint id, const GLdouble * addr) {if (GLeeInit()) glVariantdvEXT(id, addr);} + GLEEPFNGLVARIANTDVEXTPROC GLeeFuncPtr_glVariantdvEXT=GLee_Lazy_glVariantdvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantubvEXT +#define GLEE_C_DEFINED_glVariantubvEXT + void __stdcall GLee_Lazy_glVariantubvEXT(GLuint id, const GLubyte * addr) {if (GLeeInit()) glVariantubvEXT(id, addr);} + GLEEPFNGLVARIANTUBVEXTPROC GLeeFuncPtr_glVariantubvEXT=GLee_Lazy_glVariantubvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantusvEXT +#define GLEE_C_DEFINED_glVariantusvEXT + void __stdcall GLee_Lazy_glVariantusvEXT(GLuint id, const GLushort * addr) {if (GLeeInit()) glVariantusvEXT(id, addr);} + GLEEPFNGLVARIANTUSVEXTPROC GLeeFuncPtr_glVariantusvEXT=GLee_Lazy_glVariantusvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantuivEXT +#define GLEE_C_DEFINED_glVariantuivEXT + void __stdcall GLee_Lazy_glVariantuivEXT(GLuint id, const GLuint * addr) {if (GLeeInit()) glVariantuivEXT(id, addr);} + GLEEPFNGLVARIANTUIVEXTPROC GLeeFuncPtr_glVariantuivEXT=GLee_Lazy_glVariantuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVariantPointerEXT +#define GLEE_C_DEFINED_glVariantPointerEXT + void __stdcall GLee_Lazy_glVariantPointerEXT(GLuint id, GLenum type, GLuint stride, const GLvoid * addr) {if (GLeeInit()) glVariantPointerEXT(id, type, stride, addr);} + GLEEPFNGLVARIANTPOINTEREXTPROC GLeeFuncPtr_glVariantPointerEXT=GLee_Lazy_glVariantPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glEnableVariantClientStateEXT +#define GLEE_C_DEFINED_glEnableVariantClientStateEXT + void __stdcall GLee_Lazy_glEnableVariantClientStateEXT(GLuint id) {if (GLeeInit()) glEnableVariantClientStateEXT(id);} + GLEEPFNGLENABLEVARIANTCLIENTSTATEEXTPROC GLeeFuncPtr_glEnableVariantClientStateEXT=GLee_Lazy_glEnableVariantClientStateEXT; +#endif +#ifndef GLEE_C_DEFINED_glDisableVariantClientStateEXT +#define GLEE_C_DEFINED_glDisableVariantClientStateEXT + void __stdcall GLee_Lazy_glDisableVariantClientStateEXT(GLuint id) {if (GLeeInit()) glDisableVariantClientStateEXT(id);} + GLEEPFNGLDISABLEVARIANTCLIENTSTATEEXTPROC GLeeFuncPtr_glDisableVariantClientStateEXT=GLee_Lazy_glDisableVariantClientStateEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindLightParameterEXT +#define GLEE_C_DEFINED_glBindLightParameterEXT + GLuint __stdcall GLee_Lazy_glBindLightParameterEXT(GLenum light, GLenum value) {if (GLeeInit()) return glBindLightParameterEXT(light, value); return (GLuint)0;} + GLEEPFNGLBINDLIGHTPARAMETEREXTPROC GLeeFuncPtr_glBindLightParameterEXT=GLee_Lazy_glBindLightParameterEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindMaterialParameterEXT +#define GLEE_C_DEFINED_glBindMaterialParameterEXT + GLuint __stdcall GLee_Lazy_glBindMaterialParameterEXT(GLenum face, GLenum value) {if (GLeeInit()) return glBindMaterialParameterEXT(face, value); return (GLuint)0;} + GLEEPFNGLBINDMATERIALPARAMETEREXTPROC GLeeFuncPtr_glBindMaterialParameterEXT=GLee_Lazy_glBindMaterialParameterEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindTexGenParameterEXT +#define GLEE_C_DEFINED_glBindTexGenParameterEXT + GLuint __stdcall GLee_Lazy_glBindTexGenParameterEXT(GLenum unit, GLenum coord, GLenum value) {if (GLeeInit()) return glBindTexGenParameterEXT(unit, coord, value); return (GLuint)0;} + GLEEPFNGLBINDTEXGENPARAMETEREXTPROC GLeeFuncPtr_glBindTexGenParameterEXT=GLee_Lazy_glBindTexGenParameterEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindTextureUnitParameterEXT +#define GLEE_C_DEFINED_glBindTextureUnitParameterEXT + GLuint __stdcall GLee_Lazy_glBindTextureUnitParameterEXT(GLenum unit, GLenum value) {if (GLeeInit()) return glBindTextureUnitParameterEXT(unit, value); return (GLuint)0;} + GLEEPFNGLBINDTEXTUREUNITPARAMETEREXTPROC GLeeFuncPtr_glBindTextureUnitParameterEXT=GLee_Lazy_glBindTextureUnitParameterEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindParameterEXT +#define GLEE_C_DEFINED_glBindParameterEXT + GLuint __stdcall GLee_Lazy_glBindParameterEXT(GLenum value) {if (GLeeInit()) return glBindParameterEXT(value); return (GLuint)0;} + GLEEPFNGLBINDPARAMETEREXTPROC GLeeFuncPtr_glBindParameterEXT=GLee_Lazy_glBindParameterEXT; +#endif +#ifndef GLEE_C_DEFINED_glIsVariantEnabledEXT +#define GLEE_C_DEFINED_glIsVariantEnabledEXT + GLboolean __stdcall GLee_Lazy_glIsVariantEnabledEXT(GLuint id, GLenum cap) {if (GLeeInit()) return glIsVariantEnabledEXT(id, cap); return (GLboolean)0;} + GLEEPFNGLISVARIANTENABLEDEXTPROC GLeeFuncPtr_glIsVariantEnabledEXT=GLee_Lazy_glIsVariantEnabledEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetVariantBooleanvEXT +#define GLEE_C_DEFINED_glGetVariantBooleanvEXT + void __stdcall GLee_Lazy_glGetVariantBooleanvEXT(GLuint id, GLenum value, GLboolean * data) {if (GLeeInit()) glGetVariantBooleanvEXT(id, value, data);} + GLEEPFNGLGETVARIANTBOOLEANVEXTPROC GLeeFuncPtr_glGetVariantBooleanvEXT=GLee_Lazy_glGetVariantBooleanvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetVariantIntegervEXT +#define GLEE_C_DEFINED_glGetVariantIntegervEXT + void __stdcall GLee_Lazy_glGetVariantIntegervEXT(GLuint id, GLenum value, GLint * data) {if (GLeeInit()) glGetVariantIntegervEXT(id, value, data);} + GLEEPFNGLGETVARIANTINTEGERVEXTPROC GLeeFuncPtr_glGetVariantIntegervEXT=GLee_Lazy_glGetVariantIntegervEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetVariantFloatvEXT +#define GLEE_C_DEFINED_glGetVariantFloatvEXT + void __stdcall GLee_Lazy_glGetVariantFloatvEXT(GLuint id, GLenum value, GLfloat * data) {if (GLeeInit()) glGetVariantFloatvEXT(id, value, data);} + GLEEPFNGLGETVARIANTFLOATVEXTPROC GLeeFuncPtr_glGetVariantFloatvEXT=GLee_Lazy_glGetVariantFloatvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetVariantPointervEXT +#define GLEE_C_DEFINED_glGetVariantPointervEXT + void __stdcall GLee_Lazy_glGetVariantPointervEXT(GLuint id, GLenum value, GLvoid* * data) {if (GLeeInit()) glGetVariantPointervEXT(id, value, data);} + GLEEPFNGLGETVARIANTPOINTERVEXTPROC GLeeFuncPtr_glGetVariantPointervEXT=GLee_Lazy_glGetVariantPointervEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetInvariantBooleanvEXT +#define GLEE_C_DEFINED_glGetInvariantBooleanvEXT + void __stdcall GLee_Lazy_glGetInvariantBooleanvEXT(GLuint id, GLenum value, GLboolean * data) {if (GLeeInit()) glGetInvariantBooleanvEXT(id, value, data);} + GLEEPFNGLGETINVARIANTBOOLEANVEXTPROC GLeeFuncPtr_glGetInvariantBooleanvEXT=GLee_Lazy_glGetInvariantBooleanvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetInvariantIntegervEXT +#define GLEE_C_DEFINED_glGetInvariantIntegervEXT + void __stdcall GLee_Lazy_glGetInvariantIntegervEXT(GLuint id, GLenum value, GLint * data) {if (GLeeInit()) glGetInvariantIntegervEXT(id, value, data);} + GLEEPFNGLGETINVARIANTINTEGERVEXTPROC GLeeFuncPtr_glGetInvariantIntegervEXT=GLee_Lazy_glGetInvariantIntegervEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetInvariantFloatvEXT +#define GLEE_C_DEFINED_glGetInvariantFloatvEXT + void __stdcall GLee_Lazy_glGetInvariantFloatvEXT(GLuint id, GLenum value, GLfloat * data) {if (GLeeInit()) glGetInvariantFloatvEXT(id, value, data);} + GLEEPFNGLGETINVARIANTFLOATVEXTPROC GLeeFuncPtr_glGetInvariantFloatvEXT=GLee_Lazy_glGetInvariantFloatvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetLocalConstantBooleanvEXT +#define GLEE_C_DEFINED_glGetLocalConstantBooleanvEXT + void __stdcall GLee_Lazy_glGetLocalConstantBooleanvEXT(GLuint id, GLenum value, GLboolean * data) {if (GLeeInit()) glGetLocalConstantBooleanvEXT(id, value, data);} + GLEEPFNGLGETLOCALCONSTANTBOOLEANVEXTPROC GLeeFuncPtr_glGetLocalConstantBooleanvEXT=GLee_Lazy_glGetLocalConstantBooleanvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetLocalConstantIntegervEXT +#define GLEE_C_DEFINED_glGetLocalConstantIntegervEXT + void __stdcall GLee_Lazy_glGetLocalConstantIntegervEXT(GLuint id, GLenum value, GLint * data) {if (GLeeInit()) glGetLocalConstantIntegervEXT(id, value, data);} + GLEEPFNGLGETLOCALCONSTANTINTEGERVEXTPROC GLeeFuncPtr_glGetLocalConstantIntegervEXT=GLee_Lazy_glGetLocalConstantIntegervEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetLocalConstantFloatvEXT +#define GLEE_C_DEFINED_glGetLocalConstantFloatvEXT + void __stdcall GLee_Lazy_glGetLocalConstantFloatvEXT(GLuint id, GLenum value, GLfloat * data) {if (GLeeInit()) glGetLocalConstantFloatvEXT(id, value, data);} + GLEEPFNGLGETLOCALCONSTANTFLOATVEXTPROC GLeeFuncPtr_glGetLocalConstantFloatvEXT=GLee_Lazy_glGetLocalConstantFloatvEXT; +#endif +#endif + +/* GL_ATI_vertex_streams */ + +#ifdef __GLEE_GL_ATI_vertex_streams +#ifndef GLEE_C_DEFINED_glVertexStream1sATI +#define GLEE_C_DEFINED_glVertexStream1sATI + void __stdcall GLee_Lazy_glVertexStream1sATI(GLenum stream, GLshort x) {if (GLeeInit()) glVertexStream1sATI(stream, x);} + GLEEPFNGLVERTEXSTREAM1SATIPROC GLeeFuncPtr_glVertexStream1sATI=GLee_Lazy_glVertexStream1sATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream1svATI +#define GLEE_C_DEFINED_glVertexStream1svATI + void __stdcall GLee_Lazy_glVertexStream1svATI(GLenum stream, const GLshort * coords) {if (GLeeInit()) glVertexStream1svATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM1SVATIPROC GLeeFuncPtr_glVertexStream1svATI=GLee_Lazy_glVertexStream1svATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream1iATI +#define GLEE_C_DEFINED_glVertexStream1iATI + void __stdcall GLee_Lazy_glVertexStream1iATI(GLenum stream, GLint x) {if (GLeeInit()) glVertexStream1iATI(stream, x);} + GLEEPFNGLVERTEXSTREAM1IATIPROC GLeeFuncPtr_glVertexStream1iATI=GLee_Lazy_glVertexStream1iATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream1ivATI +#define GLEE_C_DEFINED_glVertexStream1ivATI + void __stdcall GLee_Lazy_glVertexStream1ivATI(GLenum stream, const GLint * coords) {if (GLeeInit()) glVertexStream1ivATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM1IVATIPROC GLeeFuncPtr_glVertexStream1ivATI=GLee_Lazy_glVertexStream1ivATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream1fATI +#define GLEE_C_DEFINED_glVertexStream1fATI + void __stdcall GLee_Lazy_glVertexStream1fATI(GLenum stream, GLfloat x) {if (GLeeInit()) glVertexStream1fATI(stream, x);} + GLEEPFNGLVERTEXSTREAM1FATIPROC GLeeFuncPtr_glVertexStream1fATI=GLee_Lazy_glVertexStream1fATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream1fvATI +#define GLEE_C_DEFINED_glVertexStream1fvATI + void __stdcall GLee_Lazy_glVertexStream1fvATI(GLenum stream, const GLfloat * coords) {if (GLeeInit()) glVertexStream1fvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM1FVATIPROC GLeeFuncPtr_glVertexStream1fvATI=GLee_Lazy_glVertexStream1fvATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream1dATI +#define GLEE_C_DEFINED_glVertexStream1dATI + void __stdcall GLee_Lazy_glVertexStream1dATI(GLenum stream, GLdouble x) {if (GLeeInit()) glVertexStream1dATI(stream, x);} + GLEEPFNGLVERTEXSTREAM1DATIPROC GLeeFuncPtr_glVertexStream1dATI=GLee_Lazy_glVertexStream1dATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream1dvATI +#define GLEE_C_DEFINED_glVertexStream1dvATI + void __stdcall GLee_Lazy_glVertexStream1dvATI(GLenum stream, const GLdouble * coords) {if (GLeeInit()) glVertexStream1dvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM1DVATIPROC GLeeFuncPtr_glVertexStream1dvATI=GLee_Lazy_glVertexStream1dvATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2sATI +#define GLEE_C_DEFINED_glVertexStream2sATI + void __stdcall GLee_Lazy_glVertexStream2sATI(GLenum stream, GLshort x, GLshort y) {if (GLeeInit()) glVertexStream2sATI(stream, x, y);} + GLEEPFNGLVERTEXSTREAM2SATIPROC GLeeFuncPtr_glVertexStream2sATI=GLee_Lazy_glVertexStream2sATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2svATI +#define GLEE_C_DEFINED_glVertexStream2svATI + void __stdcall GLee_Lazy_glVertexStream2svATI(GLenum stream, const GLshort * coords) {if (GLeeInit()) glVertexStream2svATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM2SVATIPROC GLeeFuncPtr_glVertexStream2svATI=GLee_Lazy_glVertexStream2svATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2iATI +#define GLEE_C_DEFINED_glVertexStream2iATI + void __stdcall GLee_Lazy_glVertexStream2iATI(GLenum stream, GLint x, GLint y) {if (GLeeInit()) glVertexStream2iATI(stream, x, y);} + GLEEPFNGLVERTEXSTREAM2IATIPROC GLeeFuncPtr_glVertexStream2iATI=GLee_Lazy_glVertexStream2iATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2ivATI +#define GLEE_C_DEFINED_glVertexStream2ivATI + void __stdcall GLee_Lazy_glVertexStream2ivATI(GLenum stream, const GLint * coords) {if (GLeeInit()) glVertexStream2ivATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM2IVATIPROC GLeeFuncPtr_glVertexStream2ivATI=GLee_Lazy_glVertexStream2ivATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2fATI +#define GLEE_C_DEFINED_glVertexStream2fATI + void __stdcall GLee_Lazy_glVertexStream2fATI(GLenum stream, GLfloat x, GLfloat y) {if (GLeeInit()) glVertexStream2fATI(stream, x, y);} + GLEEPFNGLVERTEXSTREAM2FATIPROC GLeeFuncPtr_glVertexStream2fATI=GLee_Lazy_glVertexStream2fATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2fvATI +#define GLEE_C_DEFINED_glVertexStream2fvATI + void __stdcall GLee_Lazy_glVertexStream2fvATI(GLenum stream, const GLfloat * coords) {if (GLeeInit()) glVertexStream2fvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM2FVATIPROC GLeeFuncPtr_glVertexStream2fvATI=GLee_Lazy_glVertexStream2fvATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2dATI +#define GLEE_C_DEFINED_glVertexStream2dATI + void __stdcall GLee_Lazy_glVertexStream2dATI(GLenum stream, GLdouble x, GLdouble y) {if (GLeeInit()) glVertexStream2dATI(stream, x, y);} + GLEEPFNGLVERTEXSTREAM2DATIPROC GLeeFuncPtr_glVertexStream2dATI=GLee_Lazy_glVertexStream2dATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream2dvATI +#define GLEE_C_DEFINED_glVertexStream2dvATI + void __stdcall GLee_Lazy_glVertexStream2dvATI(GLenum stream, const GLdouble * coords) {if (GLeeInit()) glVertexStream2dvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM2DVATIPROC GLeeFuncPtr_glVertexStream2dvATI=GLee_Lazy_glVertexStream2dvATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3sATI +#define GLEE_C_DEFINED_glVertexStream3sATI + void __stdcall GLee_Lazy_glVertexStream3sATI(GLenum stream, GLshort x, GLshort y, GLshort z) {if (GLeeInit()) glVertexStream3sATI(stream, x, y, z);} + GLEEPFNGLVERTEXSTREAM3SATIPROC GLeeFuncPtr_glVertexStream3sATI=GLee_Lazy_glVertexStream3sATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3svATI +#define GLEE_C_DEFINED_glVertexStream3svATI + void __stdcall GLee_Lazy_glVertexStream3svATI(GLenum stream, const GLshort * coords) {if (GLeeInit()) glVertexStream3svATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM3SVATIPROC GLeeFuncPtr_glVertexStream3svATI=GLee_Lazy_glVertexStream3svATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3iATI +#define GLEE_C_DEFINED_glVertexStream3iATI + void __stdcall GLee_Lazy_glVertexStream3iATI(GLenum stream, GLint x, GLint y, GLint z) {if (GLeeInit()) glVertexStream3iATI(stream, x, y, z);} + GLEEPFNGLVERTEXSTREAM3IATIPROC GLeeFuncPtr_glVertexStream3iATI=GLee_Lazy_glVertexStream3iATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3ivATI +#define GLEE_C_DEFINED_glVertexStream3ivATI + void __stdcall GLee_Lazy_glVertexStream3ivATI(GLenum stream, const GLint * coords) {if (GLeeInit()) glVertexStream3ivATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM3IVATIPROC GLeeFuncPtr_glVertexStream3ivATI=GLee_Lazy_glVertexStream3ivATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3fATI +#define GLEE_C_DEFINED_glVertexStream3fATI + void __stdcall GLee_Lazy_glVertexStream3fATI(GLenum stream, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glVertexStream3fATI(stream, x, y, z);} + GLEEPFNGLVERTEXSTREAM3FATIPROC GLeeFuncPtr_glVertexStream3fATI=GLee_Lazy_glVertexStream3fATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3fvATI +#define GLEE_C_DEFINED_glVertexStream3fvATI + void __stdcall GLee_Lazy_glVertexStream3fvATI(GLenum stream, const GLfloat * coords) {if (GLeeInit()) glVertexStream3fvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM3FVATIPROC GLeeFuncPtr_glVertexStream3fvATI=GLee_Lazy_glVertexStream3fvATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3dATI +#define GLEE_C_DEFINED_glVertexStream3dATI + void __stdcall GLee_Lazy_glVertexStream3dATI(GLenum stream, GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glVertexStream3dATI(stream, x, y, z);} + GLEEPFNGLVERTEXSTREAM3DATIPROC GLeeFuncPtr_glVertexStream3dATI=GLee_Lazy_glVertexStream3dATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream3dvATI +#define GLEE_C_DEFINED_glVertexStream3dvATI + void __stdcall GLee_Lazy_glVertexStream3dvATI(GLenum stream, const GLdouble * coords) {if (GLeeInit()) glVertexStream3dvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM3DVATIPROC GLeeFuncPtr_glVertexStream3dvATI=GLee_Lazy_glVertexStream3dvATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4sATI +#define GLEE_C_DEFINED_glVertexStream4sATI + void __stdcall GLee_Lazy_glVertexStream4sATI(GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w) {if (GLeeInit()) glVertexStream4sATI(stream, x, y, z, w);} + GLEEPFNGLVERTEXSTREAM4SATIPROC GLeeFuncPtr_glVertexStream4sATI=GLee_Lazy_glVertexStream4sATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4svATI +#define GLEE_C_DEFINED_glVertexStream4svATI + void __stdcall GLee_Lazy_glVertexStream4svATI(GLenum stream, const GLshort * coords) {if (GLeeInit()) glVertexStream4svATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM4SVATIPROC GLeeFuncPtr_glVertexStream4svATI=GLee_Lazy_glVertexStream4svATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4iATI +#define GLEE_C_DEFINED_glVertexStream4iATI + void __stdcall GLee_Lazy_glVertexStream4iATI(GLenum stream, GLint x, GLint y, GLint z, GLint w) {if (GLeeInit()) glVertexStream4iATI(stream, x, y, z, w);} + GLEEPFNGLVERTEXSTREAM4IATIPROC GLeeFuncPtr_glVertexStream4iATI=GLee_Lazy_glVertexStream4iATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4ivATI +#define GLEE_C_DEFINED_glVertexStream4ivATI + void __stdcall GLee_Lazy_glVertexStream4ivATI(GLenum stream, const GLint * coords) {if (GLeeInit()) glVertexStream4ivATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM4IVATIPROC GLeeFuncPtr_glVertexStream4ivATI=GLee_Lazy_glVertexStream4ivATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4fATI +#define GLEE_C_DEFINED_glVertexStream4fATI + void __stdcall GLee_Lazy_glVertexStream4fATI(GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glVertexStream4fATI(stream, x, y, z, w);} + GLEEPFNGLVERTEXSTREAM4FATIPROC GLeeFuncPtr_glVertexStream4fATI=GLee_Lazy_glVertexStream4fATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4fvATI +#define GLEE_C_DEFINED_glVertexStream4fvATI + void __stdcall GLee_Lazy_glVertexStream4fvATI(GLenum stream, const GLfloat * coords) {if (GLeeInit()) glVertexStream4fvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM4FVATIPROC GLeeFuncPtr_glVertexStream4fvATI=GLee_Lazy_glVertexStream4fvATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4dATI +#define GLEE_C_DEFINED_glVertexStream4dATI + void __stdcall GLee_Lazy_glVertexStream4dATI(GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glVertexStream4dATI(stream, x, y, z, w);} + GLEEPFNGLVERTEXSTREAM4DATIPROC GLeeFuncPtr_glVertexStream4dATI=GLee_Lazy_glVertexStream4dATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexStream4dvATI +#define GLEE_C_DEFINED_glVertexStream4dvATI + void __stdcall GLee_Lazy_glVertexStream4dvATI(GLenum stream, const GLdouble * coords) {if (GLeeInit()) glVertexStream4dvATI(stream, coords);} + GLEEPFNGLVERTEXSTREAM4DVATIPROC GLeeFuncPtr_glVertexStream4dvATI=GLee_Lazy_glVertexStream4dvATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3bATI +#define GLEE_C_DEFINED_glNormalStream3bATI + void __stdcall GLee_Lazy_glNormalStream3bATI(GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz) {if (GLeeInit()) glNormalStream3bATI(stream, nx, ny, nz);} + GLEEPFNGLNORMALSTREAM3BATIPROC GLeeFuncPtr_glNormalStream3bATI=GLee_Lazy_glNormalStream3bATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3bvATI +#define GLEE_C_DEFINED_glNormalStream3bvATI + void __stdcall GLee_Lazy_glNormalStream3bvATI(GLenum stream, const GLbyte * coords) {if (GLeeInit()) glNormalStream3bvATI(stream, coords);} + GLEEPFNGLNORMALSTREAM3BVATIPROC GLeeFuncPtr_glNormalStream3bvATI=GLee_Lazy_glNormalStream3bvATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3sATI +#define GLEE_C_DEFINED_glNormalStream3sATI + void __stdcall GLee_Lazy_glNormalStream3sATI(GLenum stream, GLshort nx, GLshort ny, GLshort nz) {if (GLeeInit()) glNormalStream3sATI(stream, nx, ny, nz);} + GLEEPFNGLNORMALSTREAM3SATIPROC GLeeFuncPtr_glNormalStream3sATI=GLee_Lazy_glNormalStream3sATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3svATI +#define GLEE_C_DEFINED_glNormalStream3svATI + void __stdcall GLee_Lazy_glNormalStream3svATI(GLenum stream, const GLshort * coords) {if (GLeeInit()) glNormalStream3svATI(stream, coords);} + GLEEPFNGLNORMALSTREAM3SVATIPROC GLeeFuncPtr_glNormalStream3svATI=GLee_Lazy_glNormalStream3svATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3iATI +#define GLEE_C_DEFINED_glNormalStream3iATI + void __stdcall GLee_Lazy_glNormalStream3iATI(GLenum stream, GLint nx, GLint ny, GLint nz) {if (GLeeInit()) glNormalStream3iATI(stream, nx, ny, nz);} + GLEEPFNGLNORMALSTREAM3IATIPROC GLeeFuncPtr_glNormalStream3iATI=GLee_Lazy_glNormalStream3iATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3ivATI +#define GLEE_C_DEFINED_glNormalStream3ivATI + void __stdcall GLee_Lazy_glNormalStream3ivATI(GLenum stream, const GLint * coords) {if (GLeeInit()) glNormalStream3ivATI(stream, coords);} + GLEEPFNGLNORMALSTREAM3IVATIPROC GLeeFuncPtr_glNormalStream3ivATI=GLee_Lazy_glNormalStream3ivATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3fATI +#define GLEE_C_DEFINED_glNormalStream3fATI + void __stdcall GLee_Lazy_glNormalStream3fATI(GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz) {if (GLeeInit()) glNormalStream3fATI(stream, nx, ny, nz);} + GLEEPFNGLNORMALSTREAM3FATIPROC GLeeFuncPtr_glNormalStream3fATI=GLee_Lazy_glNormalStream3fATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3fvATI +#define GLEE_C_DEFINED_glNormalStream3fvATI + void __stdcall GLee_Lazy_glNormalStream3fvATI(GLenum stream, const GLfloat * coords) {if (GLeeInit()) glNormalStream3fvATI(stream, coords);} + GLEEPFNGLNORMALSTREAM3FVATIPROC GLeeFuncPtr_glNormalStream3fvATI=GLee_Lazy_glNormalStream3fvATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3dATI +#define GLEE_C_DEFINED_glNormalStream3dATI + void __stdcall GLee_Lazy_glNormalStream3dATI(GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz) {if (GLeeInit()) glNormalStream3dATI(stream, nx, ny, nz);} + GLEEPFNGLNORMALSTREAM3DATIPROC GLeeFuncPtr_glNormalStream3dATI=GLee_Lazy_glNormalStream3dATI; +#endif +#ifndef GLEE_C_DEFINED_glNormalStream3dvATI +#define GLEE_C_DEFINED_glNormalStream3dvATI + void __stdcall GLee_Lazy_glNormalStream3dvATI(GLenum stream, const GLdouble * coords) {if (GLeeInit()) glNormalStream3dvATI(stream, coords);} + GLEEPFNGLNORMALSTREAM3DVATIPROC GLeeFuncPtr_glNormalStream3dvATI=GLee_Lazy_glNormalStream3dvATI; +#endif +#ifndef GLEE_C_DEFINED_glClientActiveVertexStreamATI +#define GLEE_C_DEFINED_glClientActiveVertexStreamATI + void __stdcall GLee_Lazy_glClientActiveVertexStreamATI(GLenum stream) {if (GLeeInit()) glClientActiveVertexStreamATI(stream);} + GLEEPFNGLCLIENTACTIVEVERTEXSTREAMATIPROC GLeeFuncPtr_glClientActiveVertexStreamATI=GLee_Lazy_glClientActiveVertexStreamATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexBlendEnviATI +#define GLEE_C_DEFINED_glVertexBlendEnviATI + void __stdcall GLee_Lazy_glVertexBlendEnviATI(GLenum pname, GLint param) {if (GLeeInit()) glVertexBlendEnviATI(pname, param);} + GLEEPFNGLVERTEXBLENDENVIATIPROC GLeeFuncPtr_glVertexBlendEnviATI=GLee_Lazy_glVertexBlendEnviATI; +#endif +#ifndef GLEE_C_DEFINED_glVertexBlendEnvfATI +#define GLEE_C_DEFINED_glVertexBlendEnvfATI + void __stdcall GLee_Lazy_glVertexBlendEnvfATI(GLenum pname, GLfloat param) {if (GLeeInit()) glVertexBlendEnvfATI(pname, param);} + GLEEPFNGLVERTEXBLENDENVFATIPROC GLeeFuncPtr_glVertexBlendEnvfATI=GLee_Lazy_glVertexBlendEnvfATI; +#endif +#endif + +/* GL_ATI_element_array */ + +#ifdef __GLEE_GL_ATI_element_array +#ifndef GLEE_C_DEFINED_glElementPointerATI +#define GLEE_C_DEFINED_glElementPointerATI + void __stdcall GLee_Lazy_glElementPointerATI(GLenum type, const GLvoid * pointer) {if (GLeeInit()) glElementPointerATI(type, pointer);} + GLEEPFNGLELEMENTPOINTERATIPROC GLeeFuncPtr_glElementPointerATI=GLee_Lazy_glElementPointerATI; +#endif +#ifndef GLEE_C_DEFINED_glDrawElementArrayATI +#define GLEE_C_DEFINED_glDrawElementArrayATI + void __stdcall GLee_Lazy_glDrawElementArrayATI(GLenum mode, GLsizei count) {if (GLeeInit()) glDrawElementArrayATI(mode, count);} + GLEEPFNGLDRAWELEMENTARRAYATIPROC GLeeFuncPtr_glDrawElementArrayATI=GLee_Lazy_glDrawElementArrayATI; +#endif +#ifndef GLEE_C_DEFINED_glDrawRangeElementArrayATI +#define GLEE_C_DEFINED_glDrawRangeElementArrayATI + void __stdcall GLee_Lazy_glDrawRangeElementArrayATI(GLenum mode, GLuint start, GLuint end, GLsizei count) {if (GLeeInit()) glDrawRangeElementArrayATI(mode, start, end, count);} + GLEEPFNGLDRAWRANGEELEMENTARRAYATIPROC GLeeFuncPtr_glDrawRangeElementArrayATI=GLee_Lazy_glDrawRangeElementArrayATI; +#endif +#endif + +/* GL_SUN_mesh_array */ + +#ifdef __GLEE_GL_SUN_mesh_array +#ifndef GLEE_C_DEFINED_glDrawMeshArraysSUN +#define GLEE_C_DEFINED_glDrawMeshArraysSUN + void __stdcall GLee_Lazy_glDrawMeshArraysSUN(GLenum mode, GLint first, GLsizei count, GLsizei width) {if (GLeeInit()) glDrawMeshArraysSUN(mode, first, count, width);} + GLEEPFNGLDRAWMESHARRAYSSUNPROC GLeeFuncPtr_glDrawMeshArraysSUN=GLee_Lazy_glDrawMeshArraysSUN; +#endif +#endif + +/* GL_SUN_slice_accum */ + +#ifdef __GLEE_GL_SUN_slice_accum +#endif + +/* GL_NV_multisample_filter_hint */ + +#ifdef __GLEE_GL_NV_multisample_filter_hint +#endif + +/* GL_NV_depth_clamp */ + +#ifdef __GLEE_GL_NV_depth_clamp +#endif + +/* GL_NV_occlusion_query */ + +#ifdef __GLEE_GL_NV_occlusion_query +#ifndef GLEE_C_DEFINED_glGenOcclusionQueriesNV +#define GLEE_C_DEFINED_glGenOcclusionQueriesNV + void __stdcall GLee_Lazy_glGenOcclusionQueriesNV(GLsizei n, GLuint * ids) {if (GLeeInit()) glGenOcclusionQueriesNV(n, ids);} + GLEEPFNGLGENOCCLUSIONQUERIESNVPROC GLeeFuncPtr_glGenOcclusionQueriesNV=GLee_Lazy_glGenOcclusionQueriesNV; +#endif +#ifndef GLEE_C_DEFINED_glDeleteOcclusionQueriesNV +#define GLEE_C_DEFINED_glDeleteOcclusionQueriesNV + void __stdcall GLee_Lazy_glDeleteOcclusionQueriesNV(GLsizei n, const GLuint * ids) {if (GLeeInit()) glDeleteOcclusionQueriesNV(n, ids);} + GLEEPFNGLDELETEOCCLUSIONQUERIESNVPROC GLeeFuncPtr_glDeleteOcclusionQueriesNV=GLee_Lazy_glDeleteOcclusionQueriesNV; +#endif +#ifndef GLEE_C_DEFINED_glIsOcclusionQueryNV +#define GLEE_C_DEFINED_glIsOcclusionQueryNV + GLboolean __stdcall GLee_Lazy_glIsOcclusionQueryNV(GLuint id) {if (GLeeInit()) return glIsOcclusionQueryNV(id); return (GLboolean)0;} + GLEEPFNGLISOCCLUSIONQUERYNVPROC GLeeFuncPtr_glIsOcclusionQueryNV=GLee_Lazy_glIsOcclusionQueryNV; +#endif +#ifndef GLEE_C_DEFINED_glBeginOcclusionQueryNV +#define GLEE_C_DEFINED_glBeginOcclusionQueryNV + void __stdcall GLee_Lazy_glBeginOcclusionQueryNV(GLuint id) {if (GLeeInit()) glBeginOcclusionQueryNV(id);} + GLEEPFNGLBEGINOCCLUSIONQUERYNVPROC GLeeFuncPtr_glBeginOcclusionQueryNV=GLee_Lazy_glBeginOcclusionQueryNV; +#endif +#ifndef GLEE_C_DEFINED_glEndOcclusionQueryNV +#define GLEE_C_DEFINED_glEndOcclusionQueryNV + void __stdcall GLee_Lazy_glEndOcclusionQueryNV(void) {if (GLeeInit()) glEndOcclusionQueryNV();} + GLEEPFNGLENDOCCLUSIONQUERYNVPROC GLeeFuncPtr_glEndOcclusionQueryNV=GLee_Lazy_glEndOcclusionQueryNV; +#endif +#ifndef GLEE_C_DEFINED_glGetOcclusionQueryivNV +#define GLEE_C_DEFINED_glGetOcclusionQueryivNV + void __stdcall GLee_Lazy_glGetOcclusionQueryivNV(GLuint id, GLenum pname, GLint * params) {if (GLeeInit()) glGetOcclusionQueryivNV(id, pname, params);} + GLEEPFNGLGETOCCLUSIONQUERYIVNVPROC GLeeFuncPtr_glGetOcclusionQueryivNV=GLee_Lazy_glGetOcclusionQueryivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetOcclusionQueryuivNV +#define GLEE_C_DEFINED_glGetOcclusionQueryuivNV + void __stdcall GLee_Lazy_glGetOcclusionQueryuivNV(GLuint id, GLenum pname, GLuint * params) {if (GLeeInit()) glGetOcclusionQueryuivNV(id, pname, params);} + GLEEPFNGLGETOCCLUSIONQUERYUIVNVPROC GLeeFuncPtr_glGetOcclusionQueryuivNV=GLee_Lazy_glGetOcclusionQueryuivNV; +#endif +#endif + +/* GL_NV_point_sprite */ + +#ifdef __GLEE_GL_NV_point_sprite +#ifndef GLEE_C_DEFINED_glPointParameteriNV +#define GLEE_C_DEFINED_glPointParameteriNV + void __stdcall GLee_Lazy_glPointParameteriNV(GLenum pname, GLint param) {if (GLeeInit()) glPointParameteriNV(pname, param);} + GLEEPFNGLPOINTPARAMETERINVPROC GLeeFuncPtr_glPointParameteriNV=GLee_Lazy_glPointParameteriNV; +#endif +#ifndef GLEE_C_DEFINED_glPointParameterivNV +#define GLEE_C_DEFINED_glPointParameterivNV + void __stdcall GLee_Lazy_glPointParameterivNV(GLenum pname, const GLint * params) {if (GLeeInit()) glPointParameterivNV(pname, params);} + GLEEPFNGLPOINTPARAMETERIVNVPROC GLeeFuncPtr_glPointParameterivNV=GLee_Lazy_glPointParameterivNV; +#endif +#endif + +/* GL_NV_texture_shader3 */ + +#ifdef __GLEE_GL_NV_texture_shader3 +#endif + +/* GL_NV_vertex_program1_1 */ + +#ifdef __GLEE_GL_NV_vertex_program1_1 +#endif + +/* GL_EXT_shadow_funcs */ + +#ifdef __GLEE_GL_EXT_shadow_funcs +#endif + +/* GL_EXT_stencil_two_side */ + +#ifdef __GLEE_GL_EXT_stencil_two_side +#ifndef GLEE_C_DEFINED_glActiveStencilFaceEXT +#define GLEE_C_DEFINED_glActiveStencilFaceEXT + void __stdcall GLee_Lazy_glActiveStencilFaceEXT(GLenum face) {if (GLeeInit()) glActiveStencilFaceEXT(face);} + GLEEPFNGLACTIVESTENCILFACEEXTPROC GLeeFuncPtr_glActiveStencilFaceEXT=GLee_Lazy_glActiveStencilFaceEXT; +#endif +#endif + +/* GL_ATI_text_fragment_shader */ + +#ifdef __GLEE_GL_ATI_text_fragment_shader +#endif + +/* GL_APPLE_client_storage */ + +#ifdef __GLEE_GL_APPLE_client_storage +#endif + +/* GL_APPLE_element_array */ + +#ifdef __GLEE_GL_APPLE_element_array +#ifndef GLEE_C_DEFINED_glElementPointerAPPLE +#define GLEE_C_DEFINED_glElementPointerAPPLE + void __stdcall GLee_Lazy_glElementPointerAPPLE(GLenum type, const GLvoid * pointer) {if (GLeeInit()) glElementPointerAPPLE(type, pointer);} + GLEEPFNGLELEMENTPOINTERAPPLEPROC GLeeFuncPtr_glElementPointerAPPLE=GLee_Lazy_glElementPointerAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glDrawElementArrayAPPLE +#define GLEE_C_DEFINED_glDrawElementArrayAPPLE + void __stdcall GLee_Lazy_glDrawElementArrayAPPLE(GLenum mode, GLint first, GLsizei count) {if (GLeeInit()) glDrawElementArrayAPPLE(mode, first, count);} + GLEEPFNGLDRAWELEMENTARRAYAPPLEPROC GLeeFuncPtr_glDrawElementArrayAPPLE=GLee_Lazy_glDrawElementArrayAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glDrawRangeElementArrayAPPLE +#define GLEE_C_DEFINED_glDrawRangeElementArrayAPPLE + void __stdcall GLee_Lazy_glDrawRangeElementArrayAPPLE(GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count) {if (GLeeInit()) glDrawRangeElementArrayAPPLE(mode, start, end, first, count);} + GLEEPFNGLDRAWRANGEELEMENTARRAYAPPLEPROC GLeeFuncPtr_glDrawRangeElementArrayAPPLE=GLee_Lazy_glDrawRangeElementArrayAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glMultiDrawElementArrayAPPLE +#define GLEE_C_DEFINED_glMultiDrawElementArrayAPPLE + void __stdcall GLee_Lazy_glMultiDrawElementArrayAPPLE(GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount) {if (GLeeInit()) glMultiDrawElementArrayAPPLE(mode, first, count, primcount);} + GLEEPFNGLMULTIDRAWELEMENTARRAYAPPLEPROC GLeeFuncPtr_glMultiDrawElementArrayAPPLE=GLee_Lazy_glMultiDrawElementArrayAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glMultiDrawRangeElementArrayAPPLE +#define GLEE_C_DEFINED_glMultiDrawRangeElementArrayAPPLE + void __stdcall GLee_Lazy_glMultiDrawRangeElementArrayAPPLE(GLenum mode, GLuint start, GLuint end, const GLint * first, const GLsizei * count, GLsizei primcount) {if (GLeeInit()) glMultiDrawRangeElementArrayAPPLE(mode, start, end, first, count, primcount);} + GLEEPFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC GLeeFuncPtr_glMultiDrawRangeElementArrayAPPLE=GLee_Lazy_glMultiDrawRangeElementArrayAPPLE; +#endif +#endif + +/* GL_APPLE_fence */ + +#ifdef __GLEE_GL_APPLE_fence +#ifndef GLEE_C_DEFINED_glGenFencesAPPLE +#define GLEE_C_DEFINED_glGenFencesAPPLE + void __stdcall GLee_Lazy_glGenFencesAPPLE(GLsizei n, GLuint * fences) {if (GLeeInit()) glGenFencesAPPLE(n, fences);} + GLEEPFNGLGENFENCESAPPLEPROC GLeeFuncPtr_glGenFencesAPPLE=GLee_Lazy_glGenFencesAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glDeleteFencesAPPLE +#define GLEE_C_DEFINED_glDeleteFencesAPPLE + void __stdcall GLee_Lazy_glDeleteFencesAPPLE(GLsizei n, const GLuint * fences) {if (GLeeInit()) glDeleteFencesAPPLE(n, fences);} + GLEEPFNGLDELETEFENCESAPPLEPROC GLeeFuncPtr_glDeleteFencesAPPLE=GLee_Lazy_glDeleteFencesAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glSetFenceAPPLE +#define GLEE_C_DEFINED_glSetFenceAPPLE + void __stdcall GLee_Lazy_glSetFenceAPPLE(GLuint fence) {if (GLeeInit()) glSetFenceAPPLE(fence);} + GLEEPFNGLSETFENCEAPPLEPROC GLeeFuncPtr_glSetFenceAPPLE=GLee_Lazy_glSetFenceAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glIsFenceAPPLE +#define GLEE_C_DEFINED_glIsFenceAPPLE + GLboolean __stdcall GLee_Lazy_glIsFenceAPPLE(GLuint fence) {if (GLeeInit()) return glIsFenceAPPLE(fence); return (GLboolean)0;} + GLEEPFNGLISFENCEAPPLEPROC GLeeFuncPtr_glIsFenceAPPLE=GLee_Lazy_glIsFenceAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glTestFenceAPPLE +#define GLEE_C_DEFINED_glTestFenceAPPLE + GLboolean __stdcall GLee_Lazy_glTestFenceAPPLE(GLuint fence) {if (GLeeInit()) return glTestFenceAPPLE(fence); return (GLboolean)0;} + GLEEPFNGLTESTFENCEAPPLEPROC GLeeFuncPtr_glTestFenceAPPLE=GLee_Lazy_glTestFenceAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glFinishFenceAPPLE +#define GLEE_C_DEFINED_glFinishFenceAPPLE + void __stdcall GLee_Lazy_glFinishFenceAPPLE(GLuint fence) {if (GLeeInit()) glFinishFenceAPPLE(fence);} + GLEEPFNGLFINISHFENCEAPPLEPROC GLeeFuncPtr_glFinishFenceAPPLE=GLee_Lazy_glFinishFenceAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glTestObjectAPPLE +#define GLEE_C_DEFINED_glTestObjectAPPLE + GLboolean __stdcall GLee_Lazy_glTestObjectAPPLE(GLenum object, GLuint name) {if (GLeeInit()) return glTestObjectAPPLE(object, name); return (GLboolean)0;} + GLEEPFNGLTESTOBJECTAPPLEPROC GLeeFuncPtr_glTestObjectAPPLE=GLee_Lazy_glTestObjectAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glFinishObjectAPPLE +#define GLEE_C_DEFINED_glFinishObjectAPPLE + void __stdcall GLee_Lazy_glFinishObjectAPPLE(GLenum object, GLint name) {if (GLeeInit()) glFinishObjectAPPLE(object, name);} + GLEEPFNGLFINISHOBJECTAPPLEPROC GLeeFuncPtr_glFinishObjectAPPLE=GLee_Lazy_glFinishObjectAPPLE; +#endif +#endif + +/* GL_APPLE_vertex_array_object */ + +#ifdef __GLEE_GL_APPLE_vertex_array_object +#ifndef GLEE_C_DEFINED_glBindVertexArrayAPPLE +#define GLEE_C_DEFINED_glBindVertexArrayAPPLE + void __stdcall GLee_Lazy_glBindVertexArrayAPPLE(GLuint array) {if (GLeeInit()) glBindVertexArrayAPPLE(array);} + GLEEPFNGLBINDVERTEXARRAYAPPLEPROC GLeeFuncPtr_glBindVertexArrayAPPLE=GLee_Lazy_glBindVertexArrayAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glDeleteVertexArraysAPPLE +#define GLEE_C_DEFINED_glDeleteVertexArraysAPPLE + void __stdcall GLee_Lazy_glDeleteVertexArraysAPPLE(GLsizei n, const GLuint * arrays) {if (GLeeInit()) glDeleteVertexArraysAPPLE(n, arrays);} + GLEEPFNGLDELETEVERTEXARRAYSAPPLEPROC GLeeFuncPtr_glDeleteVertexArraysAPPLE=GLee_Lazy_glDeleteVertexArraysAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glGenVertexArraysAPPLE +#define GLEE_C_DEFINED_glGenVertexArraysAPPLE + void __stdcall GLee_Lazy_glGenVertexArraysAPPLE(GLsizei n, GLuint * arrays) {if (GLeeInit()) glGenVertexArraysAPPLE(n, arrays);} + GLEEPFNGLGENVERTEXARRAYSAPPLEPROC GLeeFuncPtr_glGenVertexArraysAPPLE=GLee_Lazy_glGenVertexArraysAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glIsVertexArrayAPPLE +#define GLEE_C_DEFINED_glIsVertexArrayAPPLE + GLboolean __stdcall GLee_Lazy_glIsVertexArrayAPPLE(GLuint array) {if (GLeeInit()) return glIsVertexArrayAPPLE(array); return (GLboolean)0;} + GLEEPFNGLISVERTEXARRAYAPPLEPROC GLeeFuncPtr_glIsVertexArrayAPPLE=GLee_Lazy_glIsVertexArrayAPPLE; +#endif +#endif + +/* GL_APPLE_vertex_array_range */ + +#ifdef __GLEE_GL_APPLE_vertex_array_range +#ifndef GLEE_C_DEFINED_glVertexArrayRangeAPPLE +#define GLEE_C_DEFINED_glVertexArrayRangeAPPLE + void __stdcall GLee_Lazy_glVertexArrayRangeAPPLE(GLsizei length, GLvoid * pointer) {if (GLeeInit()) glVertexArrayRangeAPPLE(length, pointer);} + GLEEPFNGLVERTEXARRAYRANGEAPPLEPROC GLeeFuncPtr_glVertexArrayRangeAPPLE=GLee_Lazy_glVertexArrayRangeAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glFlushVertexArrayRangeAPPLE +#define GLEE_C_DEFINED_glFlushVertexArrayRangeAPPLE + void __stdcall GLee_Lazy_glFlushVertexArrayRangeAPPLE(GLsizei length, GLvoid * pointer) {if (GLeeInit()) glFlushVertexArrayRangeAPPLE(length, pointer);} + GLEEPFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC GLeeFuncPtr_glFlushVertexArrayRangeAPPLE=GLee_Lazy_glFlushVertexArrayRangeAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayParameteriAPPLE +#define GLEE_C_DEFINED_glVertexArrayParameteriAPPLE + void __stdcall GLee_Lazy_glVertexArrayParameteriAPPLE(GLenum pname, GLint param) {if (GLeeInit()) glVertexArrayParameteriAPPLE(pname, param);} + GLEEPFNGLVERTEXARRAYPARAMETERIAPPLEPROC GLeeFuncPtr_glVertexArrayParameteriAPPLE=GLee_Lazy_glVertexArrayParameteriAPPLE; +#endif +#endif + +/* GL_APPLE_ycbcr_422 */ + +#ifdef __GLEE_GL_APPLE_ycbcr_422 +#endif + +/* GL_S3_s3tc */ + +#ifdef __GLEE_GL_S3_s3tc +#endif + +/* GL_ATI_draw_buffers */ + +#ifdef __GLEE_GL_ATI_draw_buffers +#ifndef GLEE_C_DEFINED_glDrawBuffersATI +#define GLEE_C_DEFINED_glDrawBuffersATI + void __stdcall GLee_Lazy_glDrawBuffersATI(GLsizei n, const GLenum * bufs) {if (GLeeInit()) glDrawBuffersATI(n, bufs);} + GLEEPFNGLDRAWBUFFERSATIPROC GLeeFuncPtr_glDrawBuffersATI=GLee_Lazy_glDrawBuffersATI; +#endif +#endif + +/* GL_ATI_pixel_format_float */ + +#ifdef __GLEE_GL_ATI_pixel_format_float +#endif + +/* GL_ATI_texture_env_combine3 */ + +#ifdef __GLEE_GL_ATI_texture_env_combine3 +#endif + +/* GL_ATI_texture_float */ + +#ifdef __GLEE_GL_ATI_texture_float +#endif + +/* GL_NV_float_buffer */ + +#ifdef __GLEE_GL_NV_float_buffer +#endif + +/* GL_NV_fragment_program */ + +#ifdef __GLEE_GL_NV_fragment_program +#ifndef GLEE_C_DEFINED_glProgramNamedParameter4fNV +#define GLEE_C_DEFINED_glProgramNamedParameter4fNV + void __stdcall GLee_Lazy_glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glProgramNamedParameter4fNV(id, len, name, x, y, z, w);} + GLEEPFNGLPROGRAMNAMEDPARAMETER4FNVPROC GLeeFuncPtr_glProgramNamedParameter4fNV=GLee_Lazy_glProgramNamedParameter4fNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramNamedParameter4dNV +#define GLEE_C_DEFINED_glProgramNamedParameter4dNV + void __stdcall GLee_Lazy_glProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glProgramNamedParameter4dNV(id, len, name, x, y, z, w);} + GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC GLeeFuncPtr_glProgramNamedParameter4dNV=GLee_Lazy_glProgramNamedParameter4dNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramNamedParameter4fvNV +#define GLEE_C_DEFINED_glProgramNamedParameter4fvNV + void __stdcall GLee_Lazy_glProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v) {if (GLeeInit()) glProgramNamedParameter4fvNV(id, len, name, v);} + GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC GLeeFuncPtr_glProgramNamedParameter4fvNV=GLee_Lazy_glProgramNamedParameter4fvNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramNamedParameter4dvNV +#define GLEE_C_DEFINED_glProgramNamedParameter4dvNV + void __stdcall GLee_Lazy_glProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v) {if (GLeeInit()) glProgramNamedParameter4dvNV(id, len, name, v);} + GLEEPFNGLPROGRAMNAMEDPARAMETER4DVNVPROC GLeeFuncPtr_glProgramNamedParameter4dvNV=GLee_Lazy_glProgramNamedParameter4dvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramNamedParameterfvNV +#define GLEE_C_DEFINED_glGetProgramNamedParameterfvNV + void __stdcall GLee_Lazy_glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte * name, GLfloat * params) {if (GLeeInit()) glGetProgramNamedParameterfvNV(id, len, name, params);} + GLEEPFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC GLeeFuncPtr_glGetProgramNamedParameterfvNV=GLee_Lazy_glGetProgramNamedParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramNamedParameterdvNV +#define GLEE_C_DEFINED_glGetProgramNamedParameterdvNV + void __stdcall GLee_Lazy_glGetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte * name, GLdouble * params) {if (GLeeInit()) glGetProgramNamedParameterdvNV(id, len, name, params);} + GLEEPFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC GLeeFuncPtr_glGetProgramNamedParameterdvNV=GLee_Lazy_glGetProgramNamedParameterdvNV; +#endif +#endif + +/* GL_NV_half_float */ + +#ifdef __GLEE_GL_NV_half_float +#ifndef GLEE_C_DEFINED_glVertex2hNV +#define GLEE_C_DEFINED_glVertex2hNV + void __stdcall GLee_Lazy_glVertex2hNV(GLhalfNV x, GLhalfNV y) {if (GLeeInit()) glVertex2hNV(x, y);} + GLEEPFNGLVERTEX2HNVPROC GLeeFuncPtr_glVertex2hNV=GLee_Lazy_glVertex2hNV; +#endif +#ifndef GLEE_C_DEFINED_glVertex2hvNV +#define GLEE_C_DEFINED_glVertex2hvNV + void __stdcall GLee_Lazy_glVertex2hvNV(const GLhalfNV * v) {if (GLeeInit()) glVertex2hvNV(v);} + GLEEPFNGLVERTEX2HVNVPROC GLeeFuncPtr_glVertex2hvNV=GLee_Lazy_glVertex2hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertex3hNV +#define GLEE_C_DEFINED_glVertex3hNV + void __stdcall GLee_Lazy_glVertex3hNV(GLhalfNV x, GLhalfNV y, GLhalfNV z) {if (GLeeInit()) glVertex3hNV(x, y, z);} + GLEEPFNGLVERTEX3HNVPROC GLeeFuncPtr_glVertex3hNV=GLee_Lazy_glVertex3hNV; +#endif +#ifndef GLEE_C_DEFINED_glVertex3hvNV +#define GLEE_C_DEFINED_glVertex3hvNV + void __stdcall GLee_Lazy_glVertex3hvNV(const GLhalfNV * v) {if (GLeeInit()) glVertex3hvNV(v);} + GLEEPFNGLVERTEX3HVNVPROC GLeeFuncPtr_glVertex3hvNV=GLee_Lazy_glVertex3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertex4hNV +#define GLEE_C_DEFINED_glVertex4hNV + void __stdcall GLee_Lazy_glVertex4hNV(GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w) {if (GLeeInit()) glVertex4hNV(x, y, z, w);} + GLEEPFNGLVERTEX4HNVPROC GLeeFuncPtr_glVertex4hNV=GLee_Lazy_glVertex4hNV; +#endif +#ifndef GLEE_C_DEFINED_glVertex4hvNV +#define GLEE_C_DEFINED_glVertex4hvNV + void __stdcall GLee_Lazy_glVertex4hvNV(const GLhalfNV * v) {if (GLeeInit()) glVertex4hvNV(v);} + GLEEPFNGLVERTEX4HVNVPROC GLeeFuncPtr_glVertex4hvNV=GLee_Lazy_glVertex4hvNV; +#endif +#ifndef GLEE_C_DEFINED_glNormal3hNV +#define GLEE_C_DEFINED_glNormal3hNV + void __stdcall GLee_Lazy_glNormal3hNV(GLhalfNV nx, GLhalfNV ny, GLhalfNV nz) {if (GLeeInit()) glNormal3hNV(nx, ny, nz);} + GLEEPFNGLNORMAL3HNVPROC GLeeFuncPtr_glNormal3hNV=GLee_Lazy_glNormal3hNV; +#endif +#ifndef GLEE_C_DEFINED_glNormal3hvNV +#define GLEE_C_DEFINED_glNormal3hvNV + void __stdcall GLee_Lazy_glNormal3hvNV(const GLhalfNV * v) {if (GLeeInit()) glNormal3hvNV(v);} + GLEEPFNGLNORMAL3HVNVPROC GLeeFuncPtr_glNormal3hvNV=GLee_Lazy_glNormal3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glColor3hNV +#define GLEE_C_DEFINED_glColor3hNV + void __stdcall GLee_Lazy_glColor3hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue) {if (GLeeInit()) glColor3hNV(red, green, blue);} + GLEEPFNGLCOLOR3HNVPROC GLeeFuncPtr_glColor3hNV=GLee_Lazy_glColor3hNV; +#endif +#ifndef GLEE_C_DEFINED_glColor3hvNV +#define GLEE_C_DEFINED_glColor3hvNV + void __stdcall GLee_Lazy_glColor3hvNV(const GLhalfNV * v) {if (GLeeInit()) glColor3hvNV(v);} + GLEEPFNGLCOLOR3HVNVPROC GLeeFuncPtr_glColor3hvNV=GLee_Lazy_glColor3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glColor4hNV +#define GLEE_C_DEFINED_glColor4hNV + void __stdcall GLee_Lazy_glColor4hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha) {if (GLeeInit()) glColor4hNV(red, green, blue, alpha);} + GLEEPFNGLCOLOR4HNVPROC GLeeFuncPtr_glColor4hNV=GLee_Lazy_glColor4hNV; +#endif +#ifndef GLEE_C_DEFINED_glColor4hvNV +#define GLEE_C_DEFINED_glColor4hvNV + void __stdcall GLee_Lazy_glColor4hvNV(const GLhalfNV * v) {if (GLeeInit()) glColor4hvNV(v);} + GLEEPFNGLCOLOR4HVNVPROC GLeeFuncPtr_glColor4hvNV=GLee_Lazy_glColor4hvNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord1hNV +#define GLEE_C_DEFINED_glTexCoord1hNV + void __stdcall GLee_Lazy_glTexCoord1hNV(GLhalfNV s) {if (GLeeInit()) glTexCoord1hNV(s);} + GLEEPFNGLTEXCOORD1HNVPROC GLeeFuncPtr_glTexCoord1hNV=GLee_Lazy_glTexCoord1hNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord1hvNV +#define GLEE_C_DEFINED_glTexCoord1hvNV + void __stdcall GLee_Lazy_glTexCoord1hvNV(const GLhalfNV * v) {if (GLeeInit()) glTexCoord1hvNV(v);} + GLEEPFNGLTEXCOORD1HVNVPROC GLeeFuncPtr_glTexCoord1hvNV=GLee_Lazy_glTexCoord1hvNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2hNV +#define GLEE_C_DEFINED_glTexCoord2hNV + void __stdcall GLee_Lazy_glTexCoord2hNV(GLhalfNV s, GLhalfNV t) {if (GLeeInit()) glTexCoord2hNV(s, t);} + GLEEPFNGLTEXCOORD2HNVPROC GLeeFuncPtr_glTexCoord2hNV=GLee_Lazy_glTexCoord2hNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2hvNV +#define GLEE_C_DEFINED_glTexCoord2hvNV + void __stdcall GLee_Lazy_glTexCoord2hvNV(const GLhalfNV * v) {if (GLeeInit()) glTexCoord2hvNV(v);} + GLEEPFNGLTEXCOORD2HVNVPROC GLeeFuncPtr_glTexCoord2hvNV=GLee_Lazy_glTexCoord2hvNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord3hNV +#define GLEE_C_DEFINED_glTexCoord3hNV + void __stdcall GLee_Lazy_glTexCoord3hNV(GLhalfNV s, GLhalfNV t, GLhalfNV r) {if (GLeeInit()) glTexCoord3hNV(s, t, r);} + GLEEPFNGLTEXCOORD3HNVPROC GLeeFuncPtr_glTexCoord3hNV=GLee_Lazy_glTexCoord3hNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord3hvNV +#define GLEE_C_DEFINED_glTexCoord3hvNV + void __stdcall GLee_Lazy_glTexCoord3hvNV(const GLhalfNV * v) {if (GLeeInit()) glTexCoord3hvNV(v);} + GLEEPFNGLTEXCOORD3HVNVPROC GLeeFuncPtr_glTexCoord3hvNV=GLee_Lazy_glTexCoord3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4hNV +#define GLEE_C_DEFINED_glTexCoord4hNV + void __stdcall GLee_Lazy_glTexCoord4hNV(GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q) {if (GLeeInit()) glTexCoord4hNV(s, t, r, q);} + GLEEPFNGLTEXCOORD4HNVPROC GLeeFuncPtr_glTexCoord4hNV=GLee_Lazy_glTexCoord4hNV; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4hvNV +#define GLEE_C_DEFINED_glTexCoord4hvNV + void __stdcall GLee_Lazy_glTexCoord4hvNV(const GLhalfNV * v) {if (GLeeInit()) glTexCoord4hvNV(v);} + GLEEPFNGLTEXCOORD4HVNVPROC GLeeFuncPtr_glTexCoord4hvNV=GLee_Lazy_glTexCoord4hvNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1hNV +#define GLEE_C_DEFINED_glMultiTexCoord1hNV + void __stdcall GLee_Lazy_glMultiTexCoord1hNV(GLenum target, GLhalfNV s) {if (GLeeInit()) glMultiTexCoord1hNV(target, s);} + GLEEPFNGLMULTITEXCOORD1HNVPROC GLeeFuncPtr_glMultiTexCoord1hNV=GLee_Lazy_glMultiTexCoord1hNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1hvNV +#define GLEE_C_DEFINED_glMultiTexCoord1hvNV + void __stdcall GLee_Lazy_glMultiTexCoord1hvNV(GLenum target, const GLhalfNV * v) {if (GLeeInit()) glMultiTexCoord1hvNV(target, v);} + GLEEPFNGLMULTITEXCOORD1HVNVPROC GLeeFuncPtr_glMultiTexCoord1hvNV=GLee_Lazy_glMultiTexCoord1hvNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2hNV +#define GLEE_C_DEFINED_glMultiTexCoord2hNV + void __stdcall GLee_Lazy_glMultiTexCoord2hNV(GLenum target, GLhalfNV s, GLhalfNV t) {if (GLeeInit()) glMultiTexCoord2hNV(target, s, t);} + GLEEPFNGLMULTITEXCOORD2HNVPROC GLeeFuncPtr_glMultiTexCoord2hNV=GLee_Lazy_glMultiTexCoord2hNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2hvNV +#define GLEE_C_DEFINED_glMultiTexCoord2hvNV + void __stdcall GLee_Lazy_glMultiTexCoord2hvNV(GLenum target, const GLhalfNV * v) {if (GLeeInit()) glMultiTexCoord2hvNV(target, v);} + GLEEPFNGLMULTITEXCOORD2HVNVPROC GLeeFuncPtr_glMultiTexCoord2hvNV=GLee_Lazy_glMultiTexCoord2hvNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3hNV +#define GLEE_C_DEFINED_glMultiTexCoord3hNV + void __stdcall GLee_Lazy_glMultiTexCoord3hNV(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r) {if (GLeeInit()) glMultiTexCoord3hNV(target, s, t, r);} + GLEEPFNGLMULTITEXCOORD3HNVPROC GLeeFuncPtr_glMultiTexCoord3hNV=GLee_Lazy_glMultiTexCoord3hNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3hvNV +#define GLEE_C_DEFINED_glMultiTexCoord3hvNV + void __stdcall GLee_Lazy_glMultiTexCoord3hvNV(GLenum target, const GLhalfNV * v) {if (GLeeInit()) glMultiTexCoord3hvNV(target, v);} + GLEEPFNGLMULTITEXCOORD3HVNVPROC GLeeFuncPtr_glMultiTexCoord3hvNV=GLee_Lazy_glMultiTexCoord3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4hNV +#define GLEE_C_DEFINED_glMultiTexCoord4hNV + void __stdcall GLee_Lazy_glMultiTexCoord4hNV(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q) {if (GLeeInit()) glMultiTexCoord4hNV(target, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4HNVPROC GLeeFuncPtr_glMultiTexCoord4hNV=GLee_Lazy_glMultiTexCoord4hNV; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4hvNV +#define GLEE_C_DEFINED_glMultiTexCoord4hvNV + void __stdcall GLee_Lazy_glMultiTexCoord4hvNV(GLenum target, const GLhalfNV * v) {if (GLeeInit()) glMultiTexCoord4hvNV(target, v);} + GLEEPFNGLMULTITEXCOORD4HVNVPROC GLeeFuncPtr_glMultiTexCoord4hvNV=GLee_Lazy_glMultiTexCoord4hvNV; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordhNV +#define GLEE_C_DEFINED_glFogCoordhNV + void __stdcall GLee_Lazy_glFogCoordhNV(GLhalfNV fog) {if (GLeeInit()) glFogCoordhNV(fog);} + GLEEPFNGLFOGCOORDHNVPROC GLeeFuncPtr_glFogCoordhNV=GLee_Lazy_glFogCoordhNV; +#endif +#ifndef GLEE_C_DEFINED_glFogCoordhvNV +#define GLEE_C_DEFINED_glFogCoordhvNV + void __stdcall GLee_Lazy_glFogCoordhvNV(const GLhalfNV * fog) {if (GLeeInit()) glFogCoordhvNV(fog);} + GLEEPFNGLFOGCOORDHVNVPROC GLeeFuncPtr_glFogCoordhvNV=GLee_Lazy_glFogCoordhvNV; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3hNV +#define GLEE_C_DEFINED_glSecondaryColor3hNV + void __stdcall GLee_Lazy_glSecondaryColor3hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue) {if (GLeeInit()) glSecondaryColor3hNV(red, green, blue);} + GLEEPFNGLSECONDARYCOLOR3HNVPROC GLeeFuncPtr_glSecondaryColor3hNV=GLee_Lazy_glSecondaryColor3hNV; +#endif +#ifndef GLEE_C_DEFINED_glSecondaryColor3hvNV +#define GLEE_C_DEFINED_glSecondaryColor3hvNV + void __stdcall GLee_Lazy_glSecondaryColor3hvNV(const GLhalfNV * v) {if (GLeeInit()) glSecondaryColor3hvNV(v);} + GLEEPFNGLSECONDARYCOLOR3HVNVPROC GLeeFuncPtr_glSecondaryColor3hvNV=GLee_Lazy_glSecondaryColor3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexWeighthNV +#define GLEE_C_DEFINED_glVertexWeighthNV + void __stdcall GLee_Lazy_glVertexWeighthNV(GLhalfNV weight) {if (GLeeInit()) glVertexWeighthNV(weight);} + GLEEPFNGLVERTEXWEIGHTHNVPROC GLeeFuncPtr_glVertexWeighthNV=GLee_Lazy_glVertexWeighthNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexWeighthvNV +#define GLEE_C_DEFINED_glVertexWeighthvNV + void __stdcall GLee_Lazy_glVertexWeighthvNV(const GLhalfNV * weight) {if (GLeeInit()) glVertexWeighthvNV(weight);} + GLEEPFNGLVERTEXWEIGHTHVNVPROC GLeeFuncPtr_glVertexWeighthvNV=GLee_Lazy_glVertexWeighthvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1hNV +#define GLEE_C_DEFINED_glVertexAttrib1hNV + void __stdcall GLee_Lazy_glVertexAttrib1hNV(GLuint index, GLhalfNV x) {if (GLeeInit()) glVertexAttrib1hNV(index, x);} + GLEEPFNGLVERTEXATTRIB1HNVPROC GLeeFuncPtr_glVertexAttrib1hNV=GLee_Lazy_glVertexAttrib1hNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib1hvNV +#define GLEE_C_DEFINED_glVertexAttrib1hvNV + void __stdcall GLee_Lazy_glVertexAttrib1hvNV(GLuint index, const GLhalfNV * v) {if (GLeeInit()) glVertexAttrib1hvNV(index, v);} + GLEEPFNGLVERTEXATTRIB1HVNVPROC GLeeFuncPtr_glVertexAttrib1hvNV=GLee_Lazy_glVertexAttrib1hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2hNV +#define GLEE_C_DEFINED_glVertexAttrib2hNV + void __stdcall GLee_Lazy_glVertexAttrib2hNV(GLuint index, GLhalfNV x, GLhalfNV y) {if (GLeeInit()) glVertexAttrib2hNV(index, x, y);} + GLEEPFNGLVERTEXATTRIB2HNVPROC GLeeFuncPtr_glVertexAttrib2hNV=GLee_Lazy_glVertexAttrib2hNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib2hvNV +#define GLEE_C_DEFINED_glVertexAttrib2hvNV + void __stdcall GLee_Lazy_glVertexAttrib2hvNV(GLuint index, const GLhalfNV * v) {if (GLeeInit()) glVertexAttrib2hvNV(index, v);} + GLEEPFNGLVERTEXATTRIB2HVNVPROC GLeeFuncPtr_glVertexAttrib2hvNV=GLee_Lazy_glVertexAttrib2hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3hNV +#define GLEE_C_DEFINED_glVertexAttrib3hNV + void __stdcall GLee_Lazy_glVertexAttrib3hNV(GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z) {if (GLeeInit()) glVertexAttrib3hNV(index, x, y, z);} + GLEEPFNGLVERTEXATTRIB3HNVPROC GLeeFuncPtr_glVertexAttrib3hNV=GLee_Lazy_glVertexAttrib3hNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib3hvNV +#define GLEE_C_DEFINED_glVertexAttrib3hvNV + void __stdcall GLee_Lazy_glVertexAttrib3hvNV(GLuint index, const GLhalfNV * v) {if (GLeeInit()) glVertexAttrib3hvNV(index, v);} + GLEEPFNGLVERTEXATTRIB3HVNVPROC GLeeFuncPtr_glVertexAttrib3hvNV=GLee_Lazy_glVertexAttrib3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4hNV +#define GLEE_C_DEFINED_glVertexAttrib4hNV + void __stdcall GLee_Lazy_glVertexAttrib4hNV(GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w) {if (GLeeInit()) glVertexAttrib4hNV(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIB4HNVPROC GLeeFuncPtr_glVertexAttrib4hNV=GLee_Lazy_glVertexAttrib4hNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttrib4hvNV +#define GLEE_C_DEFINED_glVertexAttrib4hvNV + void __stdcall GLee_Lazy_glVertexAttrib4hvNV(GLuint index, const GLhalfNV * v) {if (GLeeInit()) glVertexAttrib4hvNV(index, v);} + GLEEPFNGLVERTEXATTRIB4HVNVPROC GLeeFuncPtr_glVertexAttrib4hvNV=GLee_Lazy_glVertexAttrib4hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs1hvNV +#define GLEE_C_DEFINED_glVertexAttribs1hvNV + void __stdcall GLee_Lazy_glVertexAttribs1hvNV(GLuint index, GLsizei n, const GLhalfNV * v) {if (GLeeInit()) glVertexAttribs1hvNV(index, n, v);} + GLEEPFNGLVERTEXATTRIBS1HVNVPROC GLeeFuncPtr_glVertexAttribs1hvNV=GLee_Lazy_glVertexAttribs1hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs2hvNV +#define GLEE_C_DEFINED_glVertexAttribs2hvNV + void __stdcall GLee_Lazy_glVertexAttribs2hvNV(GLuint index, GLsizei n, const GLhalfNV * v) {if (GLeeInit()) glVertexAttribs2hvNV(index, n, v);} + GLEEPFNGLVERTEXATTRIBS2HVNVPROC GLeeFuncPtr_glVertexAttribs2hvNV=GLee_Lazy_glVertexAttribs2hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs3hvNV +#define GLEE_C_DEFINED_glVertexAttribs3hvNV + void __stdcall GLee_Lazy_glVertexAttribs3hvNV(GLuint index, GLsizei n, const GLhalfNV * v) {if (GLeeInit()) glVertexAttribs3hvNV(index, n, v);} + GLEEPFNGLVERTEXATTRIBS3HVNVPROC GLeeFuncPtr_glVertexAttribs3hvNV=GLee_Lazy_glVertexAttribs3hvNV; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribs4hvNV +#define GLEE_C_DEFINED_glVertexAttribs4hvNV + void __stdcall GLee_Lazy_glVertexAttribs4hvNV(GLuint index, GLsizei n, const GLhalfNV * v) {if (GLeeInit()) glVertexAttribs4hvNV(index, n, v);} + GLEEPFNGLVERTEXATTRIBS4HVNVPROC GLeeFuncPtr_glVertexAttribs4hvNV=GLee_Lazy_glVertexAttribs4hvNV; +#endif +#endif + +/* GL_NV_pixel_data_range */ + +#ifdef __GLEE_GL_NV_pixel_data_range +#ifndef GLEE_C_DEFINED_glPixelDataRangeNV +#define GLEE_C_DEFINED_glPixelDataRangeNV + void __stdcall GLee_Lazy_glPixelDataRangeNV(GLenum target, GLsizei length, GLvoid * pointer) {if (GLeeInit()) glPixelDataRangeNV(target, length, pointer);} + GLEEPFNGLPIXELDATARANGENVPROC GLeeFuncPtr_glPixelDataRangeNV=GLee_Lazy_glPixelDataRangeNV; +#endif +#ifndef GLEE_C_DEFINED_glFlushPixelDataRangeNV +#define GLEE_C_DEFINED_glFlushPixelDataRangeNV + void __stdcall GLee_Lazy_glFlushPixelDataRangeNV(GLenum target) {if (GLeeInit()) glFlushPixelDataRangeNV(target);} + GLEEPFNGLFLUSHPIXELDATARANGENVPROC GLeeFuncPtr_glFlushPixelDataRangeNV=GLee_Lazy_glFlushPixelDataRangeNV; +#endif +#endif + +/* GL_NV_primitive_restart */ + +#ifdef __GLEE_GL_NV_primitive_restart +#ifndef GLEE_C_DEFINED_glPrimitiveRestartNV +#define GLEE_C_DEFINED_glPrimitiveRestartNV + void __stdcall GLee_Lazy_glPrimitiveRestartNV(void) {if (GLeeInit()) glPrimitiveRestartNV();} + GLEEPFNGLPRIMITIVERESTARTNVPROC GLeeFuncPtr_glPrimitiveRestartNV=GLee_Lazy_glPrimitiveRestartNV; +#endif +#ifndef GLEE_C_DEFINED_glPrimitiveRestartIndexNV +#define GLEE_C_DEFINED_glPrimitiveRestartIndexNV + void __stdcall GLee_Lazy_glPrimitiveRestartIndexNV(GLuint index) {if (GLeeInit()) glPrimitiveRestartIndexNV(index);} + GLEEPFNGLPRIMITIVERESTARTINDEXNVPROC GLeeFuncPtr_glPrimitiveRestartIndexNV=GLee_Lazy_glPrimitiveRestartIndexNV; +#endif +#endif + +/* GL_NV_texture_expand_normal */ + +#ifdef __GLEE_GL_NV_texture_expand_normal +#endif + +/* GL_NV_vertex_program2 */ + +#ifdef __GLEE_GL_NV_vertex_program2 +#endif + +/* GL_ATI_map_object_buffer */ + +#ifdef __GLEE_GL_ATI_map_object_buffer +#ifndef GLEE_C_DEFINED_glMapObjectBufferATI +#define GLEE_C_DEFINED_glMapObjectBufferATI + GLvoid* __stdcall GLee_Lazy_glMapObjectBufferATI(GLuint buffer) {if (GLeeInit()) return glMapObjectBufferATI(buffer); return (GLvoid*)0;} + GLEEPFNGLMAPOBJECTBUFFERATIPROC GLeeFuncPtr_glMapObjectBufferATI=GLee_Lazy_glMapObjectBufferATI; +#endif +#ifndef GLEE_C_DEFINED_glUnmapObjectBufferATI +#define GLEE_C_DEFINED_glUnmapObjectBufferATI + void __stdcall GLee_Lazy_glUnmapObjectBufferATI(GLuint buffer) {if (GLeeInit()) glUnmapObjectBufferATI(buffer);} + GLEEPFNGLUNMAPOBJECTBUFFERATIPROC GLeeFuncPtr_glUnmapObjectBufferATI=GLee_Lazy_glUnmapObjectBufferATI; +#endif +#endif + +/* GL_ATI_separate_stencil */ + +#ifdef __GLEE_GL_ATI_separate_stencil +#ifndef GLEE_C_DEFINED_glStencilOpSeparateATI +#define GLEE_C_DEFINED_glStencilOpSeparateATI + void __stdcall GLee_Lazy_glStencilOpSeparateATI(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {if (GLeeInit()) glStencilOpSeparateATI(face, sfail, dpfail, dppass);} + GLEEPFNGLSTENCILOPSEPARATEATIPROC GLeeFuncPtr_glStencilOpSeparateATI=GLee_Lazy_glStencilOpSeparateATI; +#endif +#ifndef GLEE_C_DEFINED_glStencilFuncSeparateATI +#define GLEE_C_DEFINED_glStencilFuncSeparateATI + void __stdcall GLee_Lazy_glStencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) {if (GLeeInit()) glStencilFuncSeparateATI(frontfunc, backfunc, ref, mask);} + GLEEPFNGLSTENCILFUNCSEPARATEATIPROC GLeeFuncPtr_glStencilFuncSeparateATI=GLee_Lazy_glStencilFuncSeparateATI; +#endif +#endif + +/* GL_ATI_vertex_attrib_array_object */ + +#ifdef __GLEE_GL_ATI_vertex_attrib_array_object +#ifndef GLEE_C_DEFINED_glVertexAttribArrayObjectATI +#define GLEE_C_DEFINED_glVertexAttribArrayObjectATI + void __stdcall GLee_Lazy_glVertexAttribArrayObjectATI(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset) {if (GLeeInit()) glVertexAttribArrayObjectATI(index, size, type, normalized, stride, buffer, offset);} + GLEEPFNGLVERTEXATTRIBARRAYOBJECTATIPROC GLeeFuncPtr_glVertexAttribArrayObjectATI=GLee_Lazy_glVertexAttribArrayObjectATI; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribArrayObjectfvATI +#define GLEE_C_DEFINED_glGetVertexAttribArrayObjectfvATI + void __stdcall GLee_Lazy_glGetVertexAttribArrayObjectfvATI(GLuint index, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetVertexAttribArrayObjectfvATI(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC GLeeFuncPtr_glGetVertexAttribArrayObjectfvATI=GLee_Lazy_glGetVertexAttribArrayObjectfvATI; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribArrayObjectivATI +#define GLEE_C_DEFINED_glGetVertexAttribArrayObjectivATI + void __stdcall GLee_Lazy_glGetVertexAttribArrayObjectivATI(GLuint index, GLenum pname, GLint * params) {if (GLeeInit()) glGetVertexAttribArrayObjectivATI(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC GLeeFuncPtr_glGetVertexAttribArrayObjectivATI=GLee_Lazy_glGetVertexAttribArrayObjectivATI; +#endif +#endif + +/* GL_OES_read_format */ + +#ifdef __GLEE_GL_OES_read_format +#endif + +/* GL_EXT_depth_bounds_test */ + +#ifdef __GLEE_GL_EXT_depth_bounds_test +#ifndef GLEE_C_DEFINED_glDepthBoundsEXT +#define GLEE_C_DEFINED_glDepthBoundsEXT + void __stdcall GLee_Lazy_glDepthBoundsEXT(GLclampd zmin, GLclampd zmax) {if (GLeeInit()) glDepthBoundsEXT(zmin, zmax);} + GLEEPFNGLDEPTHBOUNDSEXTPROC GLeeFuncPtr_glDepthBoundsEXT=GLee_Lazy_glDepthBoundsEXT; +#endif +#endif + +/* GL_EXT_texture_mirror_clamp */ + +#ifdef __GLEE_GL_EXT_texture_mirror_clamp +#endif + +/* GL_EXT_blend_equation_separate */ + +#ifdef __GLEE_GL_EXT_blend_equation_separate +#ifndef GLEE_C_DEFINED_glBlendEquationSeparateEXT +#define GLEE_C_DEFINED_glBlendEquationSeparateEXT + void __stdcall GLee_Lazy_glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeAlpha) {if (GLeeInit()) glBlendEquationSeparateEXT(modeRGB, modeAlpha);} + GLEEPFNGLBLENDEQUATIONSEPARATEEXTPROC GLeeFuncPtr_glBlendEquationSeparateEXT=GLee_Lazy_glBlendEquationSeparateEXT; +#endif +#endif + +/* GL_MESA_pack_invert */ + +#ifdef __GLEE_GL_MESA_pack_invert +#endif + +/* GL_MESA_ycbcr_texture */ + +#ifdef __GLEE_GL_MESA_ycbcr_texture +#endif + +/* GL_EXT_pixel_buffer_object */ + +#ifdef __GLEE_GL_EXT_pixel_buffer_object +#endif + +/* GL_NV_fragment_program_option */ + +#ifdef __GLEE_GL_NV_fragment_program_option +#endif + +/* GL_NV_fragment_program2 */ + +#ifdef __GLEE_GL_NV_fragment_program2 +#endif + +/* GL_NV_vertex_program2_option */ + +#ifdef __GLEE_GL_NV_vertex_program2_option +#endif + +/* GL_NV_vertex_program3 */ + +#ifdef __GLEE_GL_NV_vertex_program3 +#endif + +/* GL_EXT_framebuffer_object */ + +#ifdef __GLEE_GL_EXT_framebuffer_object +#ifndef GLEE_C_DEFINED_glIsRenderbufferEXT +#define GLEE_C_DEFINED_glIsRenderbufferEXT + GLboolean __stdcall GLee_Lazy_glIsRenderbufferEXT(GLuint renderbuffer) {if (GLeeInit()) return glIsRenderbufferEXT(renderbuffer); return (GLboolean)0;} + GLEEPFNGLISRENDERBUFFEREXTPROC GLeeFuncPtr_glIsRenderbufferEXT=GLee_Lazy_glIsRenderbufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindRenderbufferEXT +#define GLEE_C_DEFINED_glBindRenderbufferEXT + void __stdcall GLee_Lazy_glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) {if (GLeeInit()) glBindRenderbufferEXT(target, renderbuffer);} + GLEEPFNGLBINDRENDERBUFFEREXTPROC GLeeFuncPtr_glBindRenderbufferEXT=GLee_Lazy_glBindRenderbufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glDeleteRenderbuffersEXT +#define GLEE_C_DEFINED_glDeleteRenderbuffersEXT + void __stdcall GLee_Lazy_glDeleteRenderbuffersEXT(GLsizei n, const GLuint * renderbuffers) {if (GLeeInit()) glDeleteRenderbuffersEXT(n, renderbuffers);} + GLEEPFNGLDELETERENDERBUFFERSEXTPROC GLeeFuncPtr_glDeleteRenderbuffersEXT=GLee_Lazy_glDeleteRenderbuffersEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenRenderbuffersEXT +#define GLEE_C_DEFINED_glGenRenderbuffersEXT + void __stdcall GLee_Lazy_glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers) {if (GLeeInit()) glGenRenderbuffersEXT(n, renderbuffers);} + GLEEPFNGLGENRENDERBUFFERSEXTPROC GLeeFuncPtr_glGenRenderbuffersEXT=GLee_Lazy_glGenRenderbuffersEXT; +#endif +#ifndef GLEE_C_DEFINED_glRenderbufferStorageEXT +#define GLEE_C_DEFINED_glRenderbufferStorageEXT + void __stdcall GLee_Lazy_glRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glRenderbufferStorageEXT(target, internalformat, width, height);} + GLEEPFNGLRENDERBUFFERSTORAGEEXTPROC GLeeFuncPtr_glRenderbufferStorageEXT=GLee_Lazy_glRenderbufferStorageEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetRenderbufferParameterivEXT +#define GLEE_C_DEFINED_glGetRenderbufferParameterivEXT + void __stdcall GLee_Lazy_glGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetRenderbufferParameterivEXT(target, pname, params);} + GLEEPFNGLGETRENDERBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetRenderbufferParameterivEXT=GLee_Lazy_glGetRenderbufferParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glIsFramebufferEXT +#define GLEE_C_DEFINED_glIsFramebufferEXT + GLboolean __stdcall GLee_Lazy_glIsFramebufferEXT(GLuint framebuffer) {if (GLeeInit()) return glIsFramebufferEXT(framebuffer); return (GLboolean)0;} + GLEEPFNGLISFRAMEBUFFEREXTPROC GLeeFuncPtr_glIsFramebufferEXT=GLee_Lazy_glIsFramebufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindFramebufferEXT +#define GLEE_C_DEFINED_glBindFramebufferEXT + void __stdcall GLee_Lazy_glBindFramebufferEXT(GLenum target, GLuint framebuffer) {if (GLeeInit()) glBindFramebufferEXT(target, framebuffer);} + GLEEPFNGLBINDFRAMEBUFFEREXTPROC GLeeFuncPtr_glBindFramebufferEXT=GLee_Lazy_glBindFramebufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glDeleteFramebuffersEXT +#define GLEE_C_DEFINED_glDeleteFramebuffersEXT + void __stdcall GLee_Lazy_glDeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers) {if (GLeeInit()) glDeleteFramebuffersEXT(n, framebuffers);} + GLEEPFNGLDELETEFRAMEBUFFERSEXTPROC GLeeFuncPtr_glDeleteFramebuffersEXT=GLee_Lazy_glDeleteFramebuffersEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenFramebuffersEXT +#define GLEE_C_DEFINED_glGenFramebuffersEXT + void __stdcall GLee_Lazy_glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers) {if (GLeeInit()) glGenFramebuffersEXT(n, framebuffers);} + GLEEPFNGLGENFRAMEBUFFERSEXTPROC GLeeFuncPtr_glGenFramebuffersEXT=GLee_Lazy_glGenFramebuffersEXT; +#endif +#ifndef GLEE_C_DEFINED_glCheckFramebufferStatusEXT +#define GLEE_C_DEFINED_glCheckFramebufferStatusEXT + GLenum __stdcall GLee_Lazy_glCheckFramebufferStatusEXT(GLenum target) {if (GLeeInit()) return glCheckFramebufferStatusEXT(target); return (GLenum)0;} + GLEEPFNGLCHECKFRAMEBUFFERSTATUSEXTPROC GLeeFuncPtr_glCheckFramebufferStatusEXT=GLee_Lazy_glCheckFramebufferStatusEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTexture1DEXT +#define GLEE_C_DEFINED_glFramebufferTexture1DEXT + void __stdcall GLee_Lazy_glFramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {if (GLeeInit()) glFramebufferTexture1DEXT(target, attachment, textarget, texture, level);} + GLEEPFNGLFRAMEBUFFERTEXTURE1DEXTPROC GLeeFuncPtr_glFramebufferTexture1DEXT=GLee_Lazy_glFramebufferTexture1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTexture2DEXT +#define GLEE_C_DEFINED_glFramebufferTexture2DEXT + void __stdcall GLee_Lazy_glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {if (GLeeInit()) glFramebufferTexture2DEXT(target, attachment, textarget, texture, level);} + GLEEPFNGLFRAMEBUFFERTEXTURE2DEXTPROC GLeeFuncPtr_glFramebufferTexture2DEXT=GLee_Lazy_glFramebufferTexture2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTexture3DEXT +#define GLEE_C_DEFINED_glFramebufferTexture3DEXT + void __stdcall GLee_Lazy_glFramebufferTexture3DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {if (GLeeInit()) glFramebufferTexture3DEXT(target, attachment, textarget, texture, level, zoffset);} + GLEEPFNGLFRAMEBUFFERTEXTURE3DEXTPROC GLeeFuncPtr_glFramebufferTexture3DEXT=GLee_Lazy_glFramebufferTexture3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferRenderbufferEXT +#define GLEE_C_DEFINED_glFramebufferRenderbufferEXT + void __stdcall GLee_Lazy_glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {if (GLeeInit()) glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);} + GLEEPFNGLFRAMEBUFFERRENDERBUFFEREXTPROC GLeeFuncPtr_glFramebufferRenderbufferEXT=GLee_Lazy_glFramebufferRenderbufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFramebufferAttachmentParameterivEXT +#define GLEE_C_DEFINED_glGetFramebufferAttachmentParameterivEXT + void __stdcall GLee_Lazy_glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint * params) {if (GLeeInit()) glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);} + GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC GLeeFuncPtr_glGetFramebufferAttachmentParameterivEXT=GLee_Lazy_glGetFramebufferAttachmentParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenerateMipmapEXT +#define GLEE_C_DEFINED_glGenerateMipmapEXT + void __stdcall GLee_Lazy_glGenerateMipmapEXT(GLenum target) {if (GLeeInit()) glGenerateMipmapEXT(target);} + GLEEPFNGLGENERATEMIPMAPEXTPROC GLeeFuncPtr_glGenerateMipmapEXT=GLee_Lazy_glGenerateMipmapEXT; +#endif +#endif + +/* GL_GREMEDY_string_marker */ + +#ifdef __GLEE_GL_GREMEDY_string_marker +#ifndef GLEE_C_DEFINED_glStringMarkerGREMEDY +#define GLEE_C_DEFINED_glStringMarkerGREMEDY + void __stdcall GLee_Lazy_glStringMarkerGREMEDY(GLsizei len, const GLvoid * string) {if (GLeeInit()) glStringMarkerGREMEDY(len, string);} + GLEEPFNGLSTRINGMARKERGREMEDYPROC GLeeFuncPtr_glStringMarkerGREMEDY=GLee_Lazy_glStringMarkerGREMEDY; +#endif +#endif + +/* GL_EXT_packed_depth_stencil */ + +#ifdef __GLEE_GL_EXT_packed_depth_stencil +#endif + +/* GL_EXT_stencil_clear_tag */ + +#ifdef __GLEE_GL_EXT_stencil_clear_tag +#ifndef GLEE_C_DEFINED_glStencilClearTagEXT +#define GLEE_C_DEFINED_glStencilClearTagEXT + void __stdcall GLee_Lazy_glStencilClearTagEXT(GLsizei stencilTagBits, GLuint stencilClearTag) {if (GLeeInit()) glStencilClearTagEXT(stencilTagBits, stencilClearTag);} + GLEEPFNGLSTENCILCLEARTAGEXTPROC GLeeFuncPtr_glStencilClearTagEXT=GLee_Lazy_glStencilClearTagEXT; +#endif +#endif + +/* GL_EXT_texture_sRGB */ + +#ifdef __GLEE_GL_EXT_texture_sRGB +#endif + +/* GL_EXT_framebuffer_blit */ + +#ifdef __GLEE_GL_EXT_framebuffer_blit +#ifndef GLEE_C_DEFINED_glBlitFramebufferEXT +#define GLEE_C_DEFINED_glBlitFramebufferEXT + void __stdcall GLee_Lazy_glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {if (GLeeInit()) glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);} + GLEEPFNGLBLITFRAMEBUFFEREXTPROC GLeeFuncPtr_glBlitFramebufferEXT=GLee_Lazy_glBlitFramebufferEXT; +#endif +#endif + +/* GL_EXT_framebuffer_multisample */ + +#ifdef __GLEE_GL_EXT_framebuffer_multisample +#ifndef GLEE_C_DEFINED_glRenderbufferStorageMultisampleEXT +#define GLEE_C_DEFINED_glRenderbufferStorageMultisampleEXT + void __stdcall GLee_Lazy_glRenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);} + GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC GLeeFuncPtr_glRenderbufferStorageMultisampleEXT=GLee_Lazy_glRenderbufferStorageMultisampleEXT; +#endif +#endif + +/* GL_MESAX_texture_stack */ + +#ifdef __GLEE_GL_MESAX_texture_stack +#endif + +/* GL_EXT_timer_query */ + +#ifdef __GLEE_GL_EXT_timer_query +#ifndef GLEE_C_DEFINED_glGetQueryObjecti64vEXT +#define GLEE_C_DEFINED_glGetQueryObjecti64vEXT + void __stdcall GLee_Lazy_glGetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT * params) {if (GLeeInit()) glGetQueryObjecti64vEXT(id, pname, params);} + GLEEPFNGLGETQUERYOBJECTI64VEXTPROC GLeeFuncPtr_glGetQueryObjecti64vEXT=GLee_Lazy_glGetQueryObjecti64vEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetQueryObjectui64vEXT +#define GLEE_C_DEFINED_glGetQueryObjectui64vEXT + void __stdcall GLee_Lazy_glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT * params) {if (GLeeInit()) glGetQueryObjectui64vEXT(id, pname, params);} + GLEEPFNGLGETQUERYOBJECTUI64VEXTPROC GLeeFuncPtr_glGetQueryObjectui64vEXT=GLee_Lazy_glGetQueryObjectui64vEXT; +#endif +#endif + +/* GL_EXT_gpu_program_parameters */ + +#ifdef __GLEE_GL_EXT_gpu_program_parameters +#ifndef GLEE_C_DEFINED_glProgramEnvParameters4fvEXT +#define GLEE_C_DEFINED_glProgramEnvParameters4fvEXT + void __stdcall GLee_Lazy_glProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat * params) {if (GLeeInit()) glProgramEnvParameters4fvEXT(target, index, count, params);} + GLEEPFNGLPROGRAMENVPARAMETERS4FVEXTPROC GLeeFuncPtr_glProgramEnvParameters4fvEXT=GLee_Lazy_glProgramEnvParameters4fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameters4fvEXT +#define GLEE_C_DEFINED_glProgramLocalParameters4fvEXT + void __stdcall GLee_Lazy_glProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat * params) {if (GLeeInit()) glProgramLocalParameters4fvEXT(target, index, count, params);} + GLEEPFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC GLeeFuncPtr_glProgramLocalParameters4fvEXT=GLee_Lazy_glProgramLocalParameters4fvEXT; +#endif +#endif + +/* GL_APPLE_flush_buffer_range */ + +#ifdef __GLEE_GL_APPLE_flush_buffer_range +#ifndef GLEE_C_DEFINED_glBufferParameteriAPPLE +#define GLEE_C_DEFINED_glBufferParameteriAPPLE + void __stdcall GLee_Lazy_glBufferParameteriAPPLE(GLenum target, GLenum pname, GLint param) {if (GLeeInit()) glBufferParameteriAPPLE(target, pname, param);} + GLEEPFNGLBUFFERPARAMETERIAPPLEPROC GLeeFuncPtr_glBufferParameteriAPPLE=GLee_Lazy_glBufferParameteriAPPLE; +#endif +#ifndef GLEE_C_DEFINED_glFlushMappedBufferRangeAPPLE +#define GLEE_C_DEFINED_glFlushMappedBufferRangeAPPLE + void __stdcall GLee_Lazy_glFlushMappedBufferRangeAPPLE(GLenum target, GLintptr offset, GLsizeiptr size) {if (GLeeInit()) glFlushMappedBufferRangeAPPLE(target, offset, size);} + GLEEPFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC GLeeFuncPtr_glFlushMappedBufferRangeAPPLE=GLee_Lazy_glFlushMappedBufferRangeAPPLE; +#endif +#endif + +/* GL_EXT_gpu_shader4 */ + +#ifdef __GLEE_GL_EXT_gpu_shader4 +#ifndef GLEE_C_DEFINED_glGetUniformuivEXT +#define GLEE_C_DEFINED_glGetUniformuivEXT + void __stdcall GLee_Lazy_glGetUniformuivEXT(GLuint program, GLint location, GLuint * params) {if (GLeeInit()) glGetUniformuivEXT(program, location, params);} + GLEEPFNGLGETUNIFORMUIVEXTPROC GLeeFuncPtr_glGetUniformuivEXT=GLee_Lazy_glGetUniformuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindFragDataLocationEXT +#define GLEE_C_DEFINED_glBindFragDataLocationEXT + void __stdcall GLee_Lazy_glBindFragDataLocationEXT(GLuint program, GLuint color, const GLchar * name) {if (GLeeInit()) glBindFragDataLocationEXT(program, color, name);} + GLEEPFNGLBINDFRAGDATALOCATIONEXTPROC GLeeFuncPtr_glBindFragDataLocationEXT=GLee_Lazy_glBindFragDataLocationEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFragDataLocationEXT +#define GLEE_C_DEFINED_glGetFragDataLocationEXT + GLint __stdcall GLee_Lazy_glGetFragDataLocationEXT(GLuint program, const GLchar * name) {if (GLeeInit()) return glGetFragDataLocationEXT(program, name); return (GLint)0;} + GLEEPFNGLGETFRAGDATALOCATIONEXTPROC GLeeFuncPtr_glGetFragDataLocationEXT=GLee_Lazy_glGetFragDataLocationEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform1uiEXT +#define GLEE_C_DEFINED_glUniform1uiEXT + void __stdcall GLee_Lazy_glUniform1uiEXT(GLint location, GLuint v0) {if (GLeeInit()) glUniform1uiEXT(location, v0);} + GLEEPFNGLUNIFORM1UIEXTPROC GLeeFuncPtr_glUniform1uiEXT=GLee_Lazy_glUniform1uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform2uiEXT +#define GLEE_C_DEFINED_glUniform2uiEXT + void __stdcall GLee_Lazy_glUniform2uiEXT(GLint location, GLuint v0, GLuint v1) {if (GLeeInit()) glUniform2uiEXT(location, v0, v1);} + GLEEPFNGLUNIFORM2UIEXTPROC GLeeFuncPtr_glUniform2uiEXT=GLee_Lazy_glUniform2uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform3uiEXT +#define GLEE_C_DEFINED_glUniform3uiEXT + void __stdcall GLee_Lazy_glUniform3uiEXT(GLint location, GLuint v0, GLuint v1, GLuint v2) {if (GLeeInit()) glUniform3uiEXT(location, v0, v1, v2);} + GLEEPFNGLUNIFORM3UIEXTPROC GLeeFuncPtr_glUniform3uiEXT=GLee_Lazy_glUniform3uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform4uiEXT +#define GLEE_C_DEFINED_glUniform4uiEXT + void __stdcall GLee_Lazy_glUniform4uiEXT(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {if (GLeeInit()) glUniform4uiEXT(location, v0, v1, v2, v3);} + GLEEPFNGLUNIFORM4UIEXTPROC GLeeFuncPtr_glUniform4uiEXT=GLee_Lazy_glUniform4uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform1uivEXT +#define GLEE_C_DEFINED_glUniform1uivEXT + void __stdcall GLee_Lazy_glUniform1uivEXT(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform1uivEXT(location, count, value);} + GLEEPFNGLUNIFORM1UIVEXTPROC GLeeFuncPtr_glUniform1uivEXT=GLee_Lazy_glUniform1uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform2uivEXT +#define GLEE_C_DEFINED_glUniform2uivEXT + void __stdcall GLee_Lazy_glUniform2uivEXT(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform2uivEXT(location, count, value);} + GLEEPFNGLUNIFORM2UIVEXTPROC GLeeFuncPtr_glUniform2uivEXT=GLee_Lazy_glUniform2uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform3uivEXT +#define GLEE_C_DEFINED_glUniform3uivEXT + void __stdcall GLee_Lazy_glUniform3uivEXT(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform3uivEXT(location, count, value);} + GLEEPFNGLUNIFORM3UIVEXTPROC GLeeFuncPtr_glUniform3uivEXT=GLee_Lazy_glUniform3uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glUniform4uivEXT +#define GLEE_C_DEFINED_glUniform4uivEXT + void __stdcall GLee_Lazy_glUniform4uivEXT(GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glUniform4uivEXT(location, count, value);} + GLEEPFNGLUNIFORM4UIVEXTPROC GLeeFuncPtr_glUniform4uivEXT=GLee_Lazy_glUniform4uivEXT; +#endif +#endif + +/* GL_EXT_draw_instanced */ + +#ifdef __GLEE_GL_EXT_draw_instanced +#ifndef GLEE_C_DEFINED_glDrawArraysInstancedEXT +#define GLEE_C_DEFINED_glDrawArraysInstancedEXT + void __stdcall GLee_Lazy_glDrawArraysInstancedEXT(GLenum mode, GLint start, GLsizei count, GLsizei primcount) {if (GLeeInit()) glDrawArraysInstancedEXT(mode, start, count, primcount);} + GLEEPFNGLDRAWARRAYSINSTANCEDEXTPROC GLeeFuncPtr_glDrawArraysInstancedEXT=GLee_Lazy_glDrawArraysInstancedEXT; +#endif +#ifndef GLEE_C_DEFINED_glDrawElementsInstancedEXT +#define GLEE_C_DEFINED_glDrawElementsInstancedEXT + void __stdcall GLee_Lazy_glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount) {if (GLeeInit()) glDrawElementsInstancedEXT(mode, count, type, indices, primcount);} + GLEEPFNGLDRAWELEMENTSINSTANCEDEXTPROC GLeeFuncPtr_glDrawElementsInstancedEXT=GLee_Lazy_glDrawElementsInstancedEXT; +#endif +#endif + +/* GL_EXT_packed_float */ + +#ifdef __GLEE_GL_EXT_packed_float +#endif + +/* GL_EXT_texture_array */ + +#ifdef __GLEE_GL_EXT_texture_array +#endif + +/* GL_EXT_texture_buffer_object */ + +#ifdef __GLEE_GL_EXT_texture_buffer_object +#ifndef GLEE_C_DEFINED_glTexBufferEXT +#define GLEE_C_DEFINED_glTexBufferEXT + void __stdcall GLee_Lazy_glTexBufferEXT(GLenum target, GLenum internalformat, GLuint buffer) {if (GLeeInit()) glTexBufferEXT(target, internalformat, buffer);} + GLEEPFNGLTEXBUFFEREXTPROC GLeeFuncPtr_glTexBufferEXT=GLee_Lazy_glTexBufferEXT; +#endif +#endif + +/* GL_EXT_texture_compression_latc */ + +#ifdef __GLEE_GL_EXT_texture_compression_latc +#endif + +/* GL_EXT_texture_compression_rgtc */ + +#ifdef __GLEE_GL_EXT_texture_compression_rgtc +#endif + +/* GL_EXT_texture_shared_exponent */ + +#ifdef __GLEE_GL_EXT_texture_shared_exponent +#endif + +/* GL_NV_depth_buffer_float */ + +#ifdef __GLEE_GL_NV_depth_buffer_float +#ifndef GLEE_C_DEFINED_glDepthRangedNV +#define GLEE_C_DEFINED_glDepthRangedNV + void __stdcall GLee_Lazy_glDepthRangedNV(GLdouble zNear, GLdouble zFar) {if (GLeeInit()) glDepthRangedNV(zNear, zFar);} + GLEEPFNGLDEPTHRANGEDNVPROC GLeeFuncPtr_glDepthRangedNV=GLee_Lazy_glDepthRangedNV; +#endif +#ifndef GLEE_C_DEFINED_glClearDepthdNV +#define GLEE_C_DEFINED_glClearDepthdNV + void __stdcall GLee_Lazy_glClearDepthdNV(GLdouble depth) {if (GLeeInit()) glClearDepthdNV(depth);} + GLEEPFNGLCLEARDEPTHDNVPROC GLeeFuncPtr_glClearDepthdNV=GLee_Lazy_glClearDepthdNV; +#endif +#ifndef GLEE_C_DEFINED_glDepthBoundsdNV +#define GLEE_C_DEFINED_glDepthBoundsdNV + void __stdcall GLee_Lazy_glDepthBoundsdNV(GLdouble zmin, GLdouble zmax) {if (GLeeInit()) glDepthBoundsdNV(zmin, zmax);} + GLEEPFNGLDEPTHBOUNDSDNVPROC GLeeFuncPtr_glDepthBoundsdNV=GLee_Lazy_glDepthBoundsdNV; +#endif +#endif + +/* GL_NV_framebuffer_multisample_coverage */ + +#ifdef __GLEE_GL_NV_framebuffer_multisample_coverage +#ifndef GLEE_C_DEFINED_glRenderbufferStorageMultisampleCoverageNV +#define GLEE_C_DEFINED_glRenderbufferStorageMultisampleCoverageNV + void __stdcall GLee_Lazy_glRenderbufferStorageMultisampleCoverageNV(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glRenderbufferStorageMultisampleCoverageNV(target, coverageSamples, colorSamples, internalformat, width, height);} + GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC GLeeFuncPtr_glRenderbufferStorageMultisampleCoverageNV=GLee_Lazy_glRenderbufferStorageMultisampleCoverageNV; +#endif +#endif + +/* GL_EXT_framebuffer_sRGB */ + +#ifdef __GLEE_GL_EXT_framebuffer_sRGB +#endif + +/* GL_NV_geometry_shader4 */ + +#ifdef __GLEE_GL_NV_geometry_shader4 +#endif + +/* GL_NV_parameter_buffer_object */ + +#ifdef __GLEE_GL_NV_parameter_buffer_object +#ifndef GLEE_C_DEFINED_glProgramBufferParametersfvNV +#define GLEE_C_DEFINED_glProgramBufferParametersfvNV + void __stdcall GLee_Lazy_glProgramBufferParametersfvNV(GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat * params) {if (GLeeInit()) glProgramBufferParametersfvNV(target, buffer, index, count, params);} + GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC GLeeFuncPtr_glProgramBufferParametersfvNV=GLee_Lazy_glProgramBufferParametersfvNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramBufferParametersIivNV +#define GLEE_C_DEFINED_glProgramBufferParametersIivNV + void __stdcall GLee_Lazy_glProgramBufferParametersIivNV(GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint * params) {if (GLeeInit()) glProgramBufferParametersIivNV(target, buffer, index, count, params);} + GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC GLeeFuncPtr_glProgramBufferParametersIivNV=GLee_Lazy_glProgramBufferParametersIivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramBufferParametersIuivNV +#define GLEE_C_DEFINED_glProgramBufferParametersIuivNV + void __stdcall GLee_Lazy_glProgramBufferParametersIuivNV(GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint * params) {if (GLeeInit()) glProgramBufferParametersIuivNV(target, buffer, index, count, params);} + GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC GLeeFuncPtr_glProgramBufferParametersIuivNV=GLee_Lazy_glProgramBufferParametersIuivNV; +#endif +#endif + +/* GL_EXT_draw_buffers2 */ + +#ifdef __GLEE_GL_EXT_draw_buffers2 +#ifndef GLEE_C_DEFINED_glColorMaskIndexedEXT +#define GLEE_C_DEFINED_glColorMaskIndexedEXT + void __stdcall GLee_Lazy_glColorMaskIndexedEXT(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) {if (GLeeInit()) glColorMaskIndexedEXT(index, r, g, b, a);} + GLEEPFNGLCOLORMASKINDEXEDEXTPROC GLeeFuncPtr_glColorMaskIndexedEXT=GLee_Lazy_glColorMaskIndexedEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetBooleanIndexedvEXT +#define GLEE_C_DEFINED_glGetBooleanIndexedvEXT + void __stdcall GLee_Lazy_glGetBooleanIndexedvEXT(GLenum target, GLuint index, GLboolean * data) {if (GLeeInit()) glGetBooleanIndexedvEXT(target, index, data);} + GLEEPFNGLGETBOOLEANINDEXEDVEXTPROC GLeeFuncPtr_glGetBooleanIndexedvEXT=GLee_Lazy_glGetBooleanIndexedvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetIntegerIndexedvEXT +#define GLEE_C_DEFINED_glGetIntegerIndexedvEXT + void __stdcall GLee_Lazy_glGetIntegerIndexedvEXT(GLenum target, GLuint index, GLint * data) {if (GLeeInit()) glGetIntegerIndexedvEXT(target, index, data);} + GLEEPFNGLGETINTEGERINDEXEDVEXTPROC GLeeFuncPtr_glGetIntegerIndexedvEXT=GLee_Lazy_glGetIntegerIndexedvEXT; +#endif +#ifndef GLEE_C_DEFINED_glEnableIndexedEXT +#define GLEE_C_DEFINED_glEnableIndexedEXT + void __stdcall GLee_Lazy_glEnableIndexedEXT(GLenum target, GLuint index) {if (GLeeInit()) glEnableIndexedEXT(target, index);} + GLEEPFNGLENABLEINDEXEDEXTPROC GLeeFuncPtr_glEnableIndexedEXT=GLee_Lazy_glEnableIndexedEXT; +#endif +#ifndef GLEE_C_DEFINED_glDisableIndexedEXT +#define GLEE_C_DEFINED_glDisableIndexedEXT + void __stdcall GLee_Lazy_glDisableIndexedEXT(GLenum target, GLuint index) {if (GLeeInit()) glDisableIndexedEXT(target, index);} + GLEEPFNGLDISABLEINDEXEDEXTPROC GLeeFuncPtr_glDisableIndexedEXT=GLee_Lazy_glDisableIndexedEXT; +#endif +#ifndef GLEE_C_DEFINED_glIsEnabledIndexedEXT +#define GLEE_C_DEFINED_glIsEnabledIndexedEXT + GLboolean __stdcall GLee_Lazy_glIsEnabledIndexedEXT(GLenum target, GLuint index) {if (GLeeInit()) return glIsEnabledIndexedEXT(target, index); return (GLboolean)0;} + GLEEPFNGLISENABLEDINDEXEDEXTPROC GLeeFuncPtr_glIsEnabledIndexedEXT=GLee_Lazy_glIsEnabledIndexedEXT; +#endif +#endif + +/* GL_NV_transform_feedback */ + +#ifdef __GLEE_GL_NV_transform_feedback +#ifndef GLEE_C_DEFINED_glBeginTransformFeedbackNV +#define GLEE_C_DEFINED_glBeginTransformFeedbackNV + void __stdcall GLee_Lazy_glBeginTransformFeedbackNV(GLenum primitiveMode) {if (GLeeInit()) glBeginTransformFeedbackNV(primitiveMode);} + GLEEPFNGLBEGINTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glBeginTransformFeedbackNV=GLee_Lazy_glBeginTransformFeedbackNV; +#endif +#ifndef GLEE_C_DEFINED_glEndTransformFeedbackNV +#define GLEE_C_DEFINED_glEndTransformFeedbackNV + void __stdcall GLee_Lazy_glEndTransformFeedbackNV(void) {if (GLeeInit()) glEndTransformFeedbackNV();} + GLEEPFNGLENDTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glEndTransformFeedbackNV=GLee_Lazy_glEndTransformFeedbackNV; +#endif +#ifndef GLEE_C_DEFINED_glTransformFeedbackAttribsNV +#define GLEE_C_DEFINED_glTransformFeedbackAttribsNV + void __stdcall GLee_Lazy_glTransformFeedbackAttribsNV(GLuint count, const GLint * attribs, GLenum bufferMode) {if (GLeeInit()) glTransformFeedbackAttribsNV(count, attribs, bufferMode);} + GLEEPFNGLTRANSFORMFEEDBACKATTRIBSNVPROC GLeeFuncPtr_glTransformFeedbackAttribsNV=GLee_Lazy_glTransformFeedbackAttribsNV; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferRangeNV +#define GLEE_C_DEFINED_glBindBufferRangeNV + void __stdcall GLee_Lazy_glBindBufferRangeNV(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {if (GLeeInit()) glBindBufferRangeNV(target, index, buffer, offset, size);} + GLEEPFNGLBINDBUFFERRANGENVPROC GLeeFuncPtr_glBindBufferRangeNV=GLee_Lazy_glBindBufferRangeNV; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferOffsetNV +#define GLEE_C_DEFINED_glBindBufferOffsetNV + void __stdcall GLee_Lazy_glBindBufferOffsetNV(GLenum target, GLuint index, GLuint buffer, GLintptr offset) {if (GLeeInit()) glBindBufferOffsetNV(target, index, buffer, offset);} + GLEEPFNGLBINDBUFFEROFFSETNVPROC GLeeFuncPtr_glBindBufferOffsetNV=GLee_Lazy_glBindBufferOffsetNV; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferBaseNV +#define GLEE_C_DEFINED_glBindBufferBaseNV + void __stdcall GLee_Lazy_glBindBufferBaseNV(GLenum target, GLuint index, GLuint buffer) {if (GLeeInit()) glBindBufferBaseNV(target, index, buffer);} + GLEEPFNGLBINDBUFFERBASENVPROC GLeeFuncPtr_glBindBufferBaseNV=GLee_Lazy_glBindBufferBaseNV; +#endif +#ifndef GLEE_C_DEFINED_glTransformFeedbackVaryingsNV +#define GLEE_C_DEFINED_glTransformFeedbackVaryingsNV + void __stdcall GLee_Lazy_glTransformFeedbackVaryingsNV(GLuint program, GLsizei count, const GLint * locations, GLenum bufferMode) {if (GLeeInit()) glTransformFeedbackVaryingsNV(program, count, locations, bufferMode);} + GLEEPFNGLTRANSFORMFEEDBACKVARYINGSNVPROC GLeeFuncPtr_glTransformFeedbackVaryingsNV=GLee_Lazy_glTransformFeedbackVaryingsNV; +#endif +#ifndef GLEE_C_DEFINED_glActiveVaryingNV +#define GLEE_C_DEFINED_glActiveVaryingNV + void __stdcall GLee_Lazy_glActiveVaryingNV(GLuint program, const GLchar * name) {if (GLeeInit()) glActiveVaryingNV(program, name);} + GLEEPFNGLACTIVEVARYINGNVPROC GLeeFuncPtr_glActiveVaryingNV=GLee_Lazy_glActiveVaryingNV; +#endif +#ifndef GLEE_C_DEFINED_glGetVaryingLocationNV +#define GLEE_C_DEFINED_glGetVaryingLocationNV + GLint __stdcall GLee_Lazy_glGetVaryingLocationNV(GLuint program, const GLchar * name) {if (GLeeInit()) return glGetVaryingLocationNV(program, name); return (GLint)0;} + GLEEPFNGLGETVARYINGLOCATIONNVPROC GLeeFuncPtr_glGetVaryingLocationNV=GLee_Lazy_glGetVaryingLocationNV; +#endif +#ifndef GLEE_C_DEFINED_glGetActiveVaryingNV +#define GLEE_C_DEFINED_glGetActiveVaryingNV + void __stdcall GLee_Lazy_glGetActiveVaryingNV(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name) {if (GLeeInit()) glGetActiveVaryingNV(program, index, bufSize, length, size, type, name);} + GLEEPFNGLGETACTIVEVARYINGNVPROC GLeeFuncPtr_glGetActiveVaryingNV=GLee_Lazy_glGetActiveVaryingNV; +#endif +#ifndef GLEE_C_DEFINED_glGetTransformFeedbackVaryingNV +#define GLEE_C_DEFINED_glGetTransformFeedbackVaryingNV + void __stdcall GLee_Lazy_glGetTransformFeedbackVaryingNV(GLuint program, GLuint index, GLint * location) {if (GLeeInit()) glGetTransformFeedbackVaryingNV(program, index, location);} + GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC GLeeFuncPtr_glGetTransformFeedbackVaryingNV=GLee_Lazy_glGetTransformFeedbackVaryingNV; +#endif +#endif + +/* GL_EXT_bindable_uniform */ + +#ifdef __GLEE_GL_EXT_bindable_uniform +#ifndef GLEE_C_DEFINED_glUniformBufferEXT +#define GLEE_C_DEFINED_glUniformBufferEXT + void __stdcall GLee_Lazy_glUniformBufferEXT(GLuint program, GLint location, GLuint buffer) {if (GLeeInit()) glUniformBufferEXT(program, location, buffer);} + GLEEPFNGLUNIFORMBUFFEREXTPROC GLeeFuncPtr_glUniformBufferEXT=GLee_Lazy_glUniformBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformBufferSizeEXT +#define GLEE_C_DEFINED_glGetUniformBufferSizeEXT + GLint __stdcall GLee_Lazy_glGetUniformBufferSizeEXT(GLuint program, GLint location) {if (GLeeInit()) return glGetUniformBufferSizeEXT(program, location); return (GLint)0;} + GLEEPFNGLGETUNIFORMBUFFERSIZEEXTPROC GLeeFuncPtr_glGetUniformBufferSizeEXT=GLee_Lazy_glGetUniformBufferSizeEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetUniformOffsetEXT +#define GLEE_C_DEFINED_glGetUniformOffsetEXT + GLintptr __stdcall GLee_Lazy_glGetUniformOffsetEXT(GLuint program, GLint location) {if (GLeeInit()) return glGetUniformOffsetEXT(program, location); return (GLintptr)0;} + GLEEPFNGLGETUNIFORMOFFSETEXTPROC GLeeFuncPtr_glGetUniformOffsetEXT=GLee_Lazy_glGetUniformOffsetEXT; +#endif +#endif + +/* GL_EXT_texture_integer */ + +#ifdef __GLEE_GL_EXT_texture_integer +#ifndef GLEE_C_DEFINED_glTexParameterIivEXT +#define GLEE_C_DEFINED_glTexParameterIivEXT + void __stdcall GLee_Lazy_glTexParameterIivEXT(GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glTexParameterIivEXT(target, pname, params);} + GLEEPFNGLTEXPARAMETERIIVEXTPROC GLeeFuncPtr_glTexParameterIivEXT=GLee_Lazy_glTexParameterIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glTexParameterIuivEXT +#define GLEE_C_DEFINED_glTexParameterIuivEXT + void __stdcall GLee_Lazy_glTexParameterIuivEXT(GLenum target, GLenum pname, const GLuint * params) {if (GLeeInit()) glTexParameterIuivEXT(target, pname, params);} + GLEEPFNGLTEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glTexParameterIuivEXT=GLee_Lazy_glTexParameterIuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTexParameterIivEXT +#define GLEE_C_DEFINED_glGetTexParameterIivEXT + void __stdcall GLee_Lazy_glGetTexParameterIivEXT(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetTexParameterIivEXT(target, pname, params);} + GLEEPFNGLGETTEXPARAMETERIIVEXTPROC GLeeFuncPtr_glGetTexParameterIivEXT=GLee_Lazy_glGetTexParameterIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTexParameterIuivEXT +#define GLEE_C_DEFINED_glGetTexParameterIuivEXT + void __stdcall GLee_Lazy_glGetTexParameterIuivEXT(GLenum target, GLenum pname, GLuint * params) {if (GLeeInit()) glGetTexParameterIuivEXT(target, pname, params);} + GLEEPFNGLGETTEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetTexParameterIuivEXT=GLee_Lazy_glGetTexParameterIuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glClearColorIiEXT +#define GLEE_C_DEFINED_glClearColorIiEXT + void __stdcall GLee_Lazy_glClearColorIiEXT(GLint red, GLint green, GLint blue, GLint alpha) {if (GLeeInit()) glClearColorIiEXT(red, green, blue, alpha);} + GLEEPFNGLCLEARCOLORIIEXTPROC GLeeFuncPtr_glClearColorIiEXT=GLee_Lazy_glClearColorIiEXT; +#endif +#ifndef GLEE_C_DEFINED_glClearColorIuiEXT +#define GLEE_C_DEFINED_glClearColorIuiEXT + void __stdcall GLee_Lazy_glClearColorIuiEXT(GLuint red, GLuint green, GLuint blue, GLuint alpha) {if (GLeeInit()) glClearColorIuiEXT(red, green, blue, alpha);} + GLEEPFNGLCLEARCOLORIUIEXTPROC GLeeFuncPtr_glClearColorIuiEXT=GLee_Lazy_glClearColorIuiEXT; +#endif +#endif + +/* GL_GREMEDY_frame_terminator */ + +#ifdef __GLEE_GL_GREMEDY_frame_terminator +#ifndef GLEE_C_DEFINED_glFrameTerminatorGREMEDY +#define GLEE_C_DEFINED_glFrameTerminatorGREMEDY + void __stdcall GLee_Lazy_glFrameTerminatorGREMEDY(void) {if (GLeeInit()) glFrameTerminatorGREMEDY();} + GLEEPFNGLFRAMETERMINATORGREMEDYPROC GLeeFuncPtr_glFrameTerminatorGREMEDY=GLee_Lazy_glFrameTerminatorGREMEDY; +#endif +#endif + +/* GL_NV_conditional_render */ + +#ifdef __GLEE_GL_NV_conditional_render +#ifndef GLEE_C_DEFINED_glBeginConditionalRenderNV +#define GLEE_C_DEFINED_glBeginConditionalRenderNV + void __stdcall GLee_Lazy_glBeginConditionalRenderNV(GLuint id, GLenum mode) {if (GLeeInit()) glBeginConditionalRenderNV(id, mode);} + GLEEPFNGLBEGINCONDITIONALRENDERNVPROC GLeeFuncPtr_glBeginConditionalRenderNV=GLee_Lazy_glBeginConditionalRenderNV; +#endif +#ifndef GLEE_C_DEFINED_glEndConditionalRenderNV +#define GLEE_C_DEFINED_glEndConditionalRenderNV + void __stdcall GLee_Lazy_glEndConditionalRenderNV(void) {if (GLeeInit()) glEndConditionalRenderNV();} + GLEEPFNGLENDCONDITIONALRENDERNVPROC GLeeFuncPtr_glEndConditionalRenderNV=GLee_Lazy_glEndConditionalRenderNV; +#endif +#endif + +/* GL_NV_present_video */ + +#ifdef __GLEE_GL_NV_present_video +#endif + +/* GL_EXT_transform_feedback */ + +#ifdef __GLEE_GL_EXT_transform_feedback +#ifndef GLEE_C_DEFINED_glBeginTransformFeedbackEXT +#define GLEE_C_DEFINED_glBeginTransformFeedbackEXT + void __stdcall GLee_Lazy_glBeginTransformFeedbackEXT(GLenum primitiveMode) {if (GLeeInit()) glBeginTransformFeedbackEXT(primitiveMode);} + GLEEPFNGLBEGINTRANSFORMFEEDBACKEXTPROC GLeeFuncPtr_glBeginTransformFeedbackEXT=GLee_Lazy_glBeginTransformFeedbackEXT; +#endif +#ifndef GLEE_C_DEFINED_glEndTransformFeedbackEXT +#define GLEE_C_DEFINED_glEndTransformFeedbackEXT + void __stdcall GLee_Lazy_glEndTransformFeedbackEXT(void) {if (GLeeInit()) glEndTransformFeedbackEXT();} + GLEEPFNGLENDTRANSFORMFEEDBACKEXTPROC GLeeFuncPtr_glEndTransformFeedbackEXT=GLee_Lazy_glEndTransformFeedbackEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferRangeEXT +#define GLEE_C_DEFINED_glBindBufferRangeEXT + void __stdcall GLee_Lazy_glBindBufferRangeEXT(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {if (GLeeInit()) glBindBufferRangeEXT(target, index, buffer, offset, size);} + GLEEPFNGLBINDBUFFERRANGEEXTPROC GLeeFuncPtr_glBindBufferRangeEXT=GLee_Lazy_glBindBufferRangeEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferOffsetEXT +#define GLEE_C_DEFINED_glBindBufferOffsetEXT + void __stdcall GLee_Lazy_glBindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, GLintptr offset) {if (GLeeInit()) glBindBufferOffsetEXT(target, index, buffer, offset);} + GLEEPFNGLBINDBUFFEROFFSETEXTPROC GLeeFuncPtr_glBindBufferOffsetEXT=GLee_Lazy_glBindBufferOffsetEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindBufferBaseEXT +#define GLEE_C_DEFINED_glBindBufferBaseEXT + void __stdcall GLee_Lazy_glBindBufferBaseEXT(GLenum target, GLuint index, GLuint buffer) {if (GLeeInit()) glBindBufferBaseEXT(target, index, buffer);} + GLEEPFNGLBINDBUFFERBASEEXTPROC GLeeFuncPtr_glBindBufferBaseEXT=GLee_Lazy_glBindBufferBaseEXT; +#endif +#ifndef GLEE_C_DEFINED_glTransformFeedbackVaryingsEXT +#define GLEE_C_DEFINED_glTransformFeedbackVaryingsEXT + void __stdcall GLee_Lazy_glTransformFeedbackVaryingsEXT(GLuint program, GLsizei count, const GLint * locations, GLenum bufferMode) {if (GLeeInit()) glTransformFeedbackVaryingsEXT(program, count, locations, bufferMode);} + GLEEPFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC GLeeFuncPtr_glTransformFeedbackVaryingsEXT=GLee_Lazy_glTransformFeedbackVaryingsEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTransformFeedbackVaryingEXT +#define GLEE_C_DEFINED_glGetTransformFeedbackVaryingEXT + void __stdcall GLee_Lazy_glGetTransformFeedbackVaryingEXT(GLuint program, GLuint index, GLint * location) {if (GLeeInit()) glGetTransformFeedbackVaryingEXT(program, index, location);} + GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC GLeeFuncPtr_glGetTransformFeedbackVaryingEXT=GLee_Lazy_glGetTransformFeedbackVaryingEXT; +#endif +#endif + +/* GL_EXT_direct_state_access */ + +#ifdef __GLEE_GL_EXT_direct_state_access +#ifndef GLEE_C_DEFINED_glClientAttribDefaultEXT +#define GLEE_C_DEFINED_glClientAttribDefaultEXT + void __stdcall GLee_Lazy_glClientAttribDefaultEXT(GLbitfield mask) {if (GLeeInit()) glClientAttribDefaultEXT(mask);} + GLEEPFNGLCLIENTATTRIBDEFAULTEXTPROC GLeeFuncPtr_glClientAttribDefaultEXT=GLee_Lazy_glClientAttribDefaultEXT; +#endif +#ifndef GLEE_C_DEFINED_glPushClientAttribDefaultEXT +#define GLEE_C_DEFINED_glPushClientAttribDefaultEXT + void __stdcall GLee_Lazy_glPushClientAttribDefaultEXT(GLbitfield mask) {if (GLeeInit()) glPushClientAttribDefaultEXT(mask);} + GLEEPFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC GLeeFuncPtr_glPushClientAttribDefaultEXT=GLee_Lazy_glPushClientAttribDefaultEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixLoadfEXT +#define GLEE_C_DEFINED_glMatrixLoadfEXT + void __stdcall GLee_Lazy_glMatrixLoadfEXT(GLenum mode, const GLfloat * m) {if (GLeeInit()) glMatrixLoadfEXT(mode, m);} + GLEEPFNGLMATRIXLOADFEXTPROC GLeeFuncPtr_glMatrixLoadfEXT=GLee_Lazy_glMatrixLoadfEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixLoaddEXT +#define GLEE_C_DEFINED_glMatrixLoaddEXT + void __stdcall GLee_Lazy_glMatrixLoaddEXT(GLenum mode, const GLdouble * m) {if (GLeeInit()) glMatrixLoaddEXT(mode, m);} + GLEEPFNGLMATRIXLOADDEXTPROC GLeeFuncPtr_glMatrixLoaddEXT=GLee_Lazy_glMatrixLoaddEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixMultfEXT +#define GLEE_C_DEFINED_glMatrixMultfEXT + void __stdcall GLee_Lazy_glMatrixMultfEXT(GLenum mode, const GLfloat * m) {if (GLeeInit()) glMatrixMultfEXT(mode, m);} + GLEEPFNGLMATRIXMULTFEXTPROC GLeeFuncPtr_glMatrixMultfEXT=GLee_Lazy_glMatrixMultfEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixMultdEXT +#define GLEE_C_DEFINED_glMatrixMultdEXT + void __stdcall GLee_Lazy_glMatrixMultdEXT(GLenum mode, const GLdouble * m) {if (GLeeInit()) glMatrixMultdEXT(mode, m);} + GLEEPFNGLMATRIXMULTDEXTPROC GLeeFuncPtr_glMatrixMultdEXT=GLee_Lazy_glMatrixMultdEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixLoadIdentityEXT +#define GLEE_C_DEFINED_glMatrixLoadIdentityEXT + void __stdcall GLee_Lazy_glMatrixLoadIdentityEXT(GLenum mode) {if (GLeeInit()) glMatrixLoadIdentityEXT(mode);} + GLEEPFNGLMATRIXLOADIDENTITYEXTPROC GLeeFuncPtr_glMatrixLoadIdentityEXT=GLee_Lazy_glMatrixLoadIdentityEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixRotatefEXT +#define GLEE_C_DEFINED_glMatrixRotatefEXT + void __stdcall GLee_Lazy_glMatrixRotatefEXT(GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glMatrixRotatefEXT(mode, angle, x, y, z);} + GLEEPFNGLMATRIXROTATEFEXTPROC GLeeFuncPtr_glMatrixRotatefEXT=GLee_Lazy_glMatrixRotatefEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixRotatedEXT +#define GLEE_C_DEFINED_glMatrixRotatedEXT + void __stdcall GLee_Lazy_glMatrixRotatedEXT(GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glMatrixRotatedEXT(mode, angle, x, y, z);} + GLEEPFNGLMATRIXROTATEDEXTPROC GLeeFuncPtr_glMatrixRotatedEXT=GLee_Lazy_glMatrixRotatedEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixScalefEXT +#define GLEE_C_DEFINED_glMatrixScalefEXT + void __stdcall GLee_Lazy_glMatrixScalefEXT(GLenum mode, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glMatrixScalefEXT(mode, x, y, z);} + GLEEPFNGLMATRIXSCALEFEXTPROC GLeeFuncPtr_glMatrixScalefEXT=GLee_Lazy_glMatrixScalefEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixScaledEXT +#define GLEE_C_DEFINED_glMatrixScaledEXT + void __stdcall GLee_Lazy_glMatrixScaledEXT(GLenum mode, GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glMatrixScaledEXT(mode, x, y, z);} + GLEEPFNGLMATRIXSCALEDEXTPROC GLeeFuncPtr_glMatrixScaledEXT=GLee_Lazy_glMatrixScaledEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixTranslatefEXT +#define GLEE_C_DEFINED_glMatrixTranslatefEXT + void __stdcall GLee_Lazy_glMatrixTranslatefEXT(GLenum mode, GLfloat x, GLfloat y, GLfloat z) {if (GLeeInit()) glMatrixTranslatefEXT(mode, x, y, z);} + GLEEPFNGLMATRIXTRANSLATEFEXTPROC GLeeFuncPtr_glMatrixTranslatefEXT=GLee_Lazy_glMatrixTranslatefEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixTranslatedEXT +#define GLEE_C_DEFINED_glMatrixTranslatedEXT + void __stdcall GLee_Lazy_glMatrixTranslatedEXT(GLenum mode, GLdouble x, GLdouble y, GLdouble z) {if (GLeeInit()) glMatrixTranslatedEXT(mode, x, y, z);} + GLEEPFNGLMATRIXTRANSLATEDEXTPROC GLeeFuncPtr_glMatrixTranslatedEXT=GLee_Lazy_glMatrixTranslatedEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixFrustumEXT +#define GLEE_C_DEFINED_glMatrixFrustumEXT + void __stdcall GLee_Lazy_glMatrixFrustumEXT(GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) {if (GLeeInit()) glMatrixFrustumEXT(mode, left, right, bottom, top, zNear, zFar);} + GLEEPFNGLMATRIXFRUSTUMEXTPROC GLeeFuncPtr_glMatrixFrustumEXT=GLee_Lazy_glMatrixFrustumEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixOrthoEXT +#define GLEE_C_DEFINED_glMatrixOrthoEXT + void __stdcall GLee_Lazy_glMatrixOrthoEXT(GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) {if (GLeeInit()) glMatrixOrthoEXT(mode, left, right, bottom, top, zNear, zFar);} + GLEEPFNGLMATRIXORTHOEXTPROC GLeeFuncPtr_glMatrixOrthoEXT=GLee_Lazy_glMatrixOrthoEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixPopEXT +#define GLEE_C_DEFINED_glMatrixPopEXT + void __stdcall GLee_Lazy_glMatrixPopEXT(GLenum mode) {if (GLeeInit()) glMatrixPopEXT(mode);} + GLEEPFNGLMATRIXPOPEXTPROC GLeeFuncPtr_glMatrixPopEXT=GLee_Lazy_glMatrixPopEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixPushEXT +#define GLEE_C_DEFINED_glMatrixPushEXT + void __stdcall GLee_Lazy_glMatrixPushEXT(GLenum mode) {if (GLeeInit()) glMatrixPushEXT(mode);} + GLEEPFNGLMATRIXPUSHEXTPROC GLeeFuncPtr_glMatrixPushEXT=GLee_Lazy_glMatrixPushEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixLoadTransposefEXT +#define GLEE_C_DEFINED_glMatrixLoadTransposefEXT + void __stdcall GLee_Lazy_glMatrixLoadTransposefEXT(GLenum mode, const GLfloat * m) {if (GLeeInit()) glMatrixLoadTransposefEXT(mode, m);} + GLEEPFNGLMATRIXLOADTRANSPOSEFEXTPROC GLeeFuncPtr_glMatrixLoadTransposefEXT=GLee_Lazy_glMatrixLoadTransposefEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixLoadTransposedEXT +#define GLEE_C_DEFINED_glMatrixLoadTransposedEXT + void __stdcall GLee_Lazy_glMatrixLoadTransposedEXT(GLenum mode, const GLdouble * m) {if (GLeeInit()) glMatrixLoadTransposedEXT(mode, m);} + GLEEPFNGLMATRIXLOADTRANSPOSEDEXTPROC GLeeFuncPtr_glMatrixLoadTransposedEXT=GLee_Lazy_glMatrixLoadTransposedEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixMultTransposefEXT +#define GLEE_C_DEFINED_glMatrixMultTransposefEXT + void __stdcall GLee_Lazy_glMatrixMultTransposefEXT(GLenum mode, const GLfloat * m) {if (GLeeInit()) glMatrixMultTransposefEXT(mode, m);} + GLEEPFNGLMATRIXMULTTRANSPOSEFEXTPROC GLeeFuncPtr_glMatrixMultTransposefEXT=GLee_Lazy_glMatrixMultTransposefEXT; +#endif +#ifndef GLEE_C_DEFINED_glMatrixMultTransposedEXT +#define GLEE_C_DEFINED_glMatrixMultTransposedEXT + void __stdcall GLee_Lazy_glMatrixMultTransposedEXT(GLenum mode, const GLdouble * m) {if (GLeeInit()) glMatrixMultTransposedEXT(mode, m);} + GLEEPFNGLMATRIXMULTTRANSPOSEDEXTPROC GLeeFuncPtr_glMatrixMultTransposedEXT=GLee_Lazy_glMatrixMultTransposedEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureParameterfEXT +#define GLEE_C_DEFINED_glTextureParameterfEXT + void __stdcall GLee_Lazy_glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param) {if (GLeeInit()) glTextureParameterfEXT(texture, target, pname, param);} + GLEEPFNGLTEXTUREPARAMETERFEXTPROC GLeeFuncPtr_glTextureParameterfEXT=GLee_Lazy_glTextureParameterfEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureParameterfvEXT +#define GLEE_C_DEFINED_glTextureParameterfvEXT + void __stdcall GLee_Lazy_glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glTextureParameterfvEXT(texture, target, pname, params);} + GLEEPFNGLTEXTUREPARAMETERFVEXTPROC GLeeFuncPtr_glTextureParameterfvEXT=GLee_Lazy_glTextureParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureParameteriEXT +#define GLEE_C_DEFINED_glTextureParameteriEXT + void __stdcall GLee_Lazy_glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param) {if (GLeeInit()) glTextureParameteriEXT(texture, target, pname, param);} + GLEEPFNGLTEXTUREPARAMETERIEXTPROC GLeeFuncPtr_glTextureParameteriEXT=GLee_Lazy_glTextureParameteriEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureParameterivEXT +#define GLEE_C_DEFINED_glTextureParameterivEXT + void __stdcall GLee_Lazy_glTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glTextureParameterivEXT(texture, target, pname, params);} + GLEEPFNGLTEXTUREPARAMETERIVEXTPROC GLeeFuncPtr_glTextureParameterivEXT=GLee_Lazy_glTextureParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureImage1DEXT +#define GLEE_C_DEFINED_glTextureImage1DEXT + void __stdcall GLee_Lazy_glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTextureImage1DEXT(texture, target, level, internalformat, width, border, format, type, pixels);} + GLEEPFNGLTEXTUREIMAGE1DEXTPROC GLeeFuncPtr_glTextureImage1DEXT=GLee_Lazy_glTextureImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureImage2DEXT +#define GLEE_C_DEFINED_glTextureImage2DEXT + void __stdcall GLee_Lazy_glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTextureImage2DEXT(texture, target, level, internalformat, width, height, border, format, type, pixels);} + GLEEPFNGLTEXTUREIMAGE2DEXTPROC GLeeFuncPtr_glTextureImage2DEXT=GLee_Lazy_glTextureImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureSubImage1DEXT +#define GLEE_C_DEFINED_glTextureSubImage1DEXT + void __stdcall GLee_Lazy_glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels);} + GLEEPFNGLTEXTURESUBIMAGE1DEXTPROC GLeeFuncPtr_glTextureSubImage1DEXT=GLee_Lazy_glTextureSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureSubImage2DEXT +#define GLEE_C_DEFINED_glTextureSubImage2DEXT + void __stdcall GLee_Lazy_glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);} + GLEEPFNGLTEXTURESUBIMAGE2DEXTPROC GLeeFuncPtr_glTextureSubImage2DEXT=GLee_Lazy_glTextureSubImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTextureImage1DEXT +#define GLEE_C_DEFINED_glCopyTextureImage1DEXT + void __stdcall GLee_Lazy_glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {if (GLeeInit()) glCopyTextureImage1DEXT(texture, target, level, internalformat, x, y, width, border);} + GLEEPFNGLCOPYTEXTUREIMAGE1DEXTPROC GLeeFuncPtr_glCopyTextureImage1DEXT=GLee_Lazy_glCopyTextureImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTextureImage2DEXT +#define GLEE_C_DEFINED_glCopyTextureImage2DEXT + void __stdcall GLee_Lazy_glCopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {if (GLeeInit()) glCopyTextureImage2DEXT(texture, target, level, internalformat, x, y, width, height, border);} + GLEEPFNGLCOPYTEXTUREIMAGE2DEXTPROC GLeeFuncPtr_glCopyTextureImage2DEXT=GLee_Lazy_glCopyTextureImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTextureSubImage1DEXT +#define GLEE_C_DEFINED_glCopyTextureSubImage1DEXT + void __stdcall GLee_Lazy_glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyTextureSubImage1DEXT(texture, target, level, xoffset, x, y, width);} + GLEEPFNGLCOPYTEXTURESUBIMAGE1DEXTPROC GLeeFuncPtr_glCopyTextureSubImage1DEXT=GLee_Lazy_glCopyTextureSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTextureSubImage2DEXT +#define GLEE_C_DEFINED_glCopyTextureSubImage2DEXT + void __stdcall GLee_Lazy_glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, x, y, width, height);} + GLEEPFNGLCOPYTEXTURESUBIMAGE2DEXTPROC GLeeFuncPtr_glCopyTextureSubImage2DEXT=GLee_Lazy_glCopyTextureSubImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureImageEXT +#define GLEE_C_DEFINED_glGetTextureImageEXT + void __stdcall GLee_Lazy_glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels) {if (GLeeInit()) glGetTextureImageEXT(texture, target, level, format, type, pixels);} + GLEEPFNGLGETTEXTUREIMAGEEXTPROC GLeeFuncPtr_glGetTextureImageEXT=GLee_Lazy_glGetTextureImageEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureParameterfvEXT +#define GLEE_C_DEFINED_glGetTextureParameterfvEXT + void __stdcall GLee_Lazy_glGetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetTextureParameterfvEXT(texture, target, pname, params);} + GLEEPFNGLGETTEXTUREPARAMETERFVEXTPROC GLeeFuncPtr_glGetTextureParameterfvEXT=GLee_Lazy_glGetTextureParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureParameterivEXT +#define GLEE_C_DEFINED_glGetTextureParameterivEXT + void __stdcall GLee_Lazy_glGetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetTextureParameterivEXT(texture, target, pname, params);} + GLEEPFNGLGETTEXTUREPARAMETERIVEXTPROC GLeeFuncPtr_glGetTextureParameterivEXT=GLee_Lazy_glGetTextureParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureLevelParameterfvEXT +#define GLEE_C_DEFINED_glGetTextureLevelParameterfvEXT + void __stdcall GLee_Lazy_glGetTextureLevelParameterfvEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetTextureLevelParameterfvEXT(texture, target, level, pname, params);} + GLEEPFNGLGETTEXTURELEVELPARAMETERFVEXTPROC GLeeFuncPtr_glGetTextureLevelParameterfvEXT=GLee_Lazy_glGetTextureLevelParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureLevelParameterivEXT +#define GLEE_C_DEFINED_glGetTextureLevelParameterivEXT + void __stdcall GLee_Lazy_glGetTextureLevelParameterivEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLint * params) {if (GLeeInit()) glGetTextureLevelParameterivEXT(texture, target, level, pname, params);} + GLEEPFNGLGETTEXTURELEVELPARAMETERIVEXTPROC GLeeFuncPtr_glGetTextureLevelParameterivEXT=GLee_Lazy_glGetTextureLevelParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureImage3DEXT +#define GLEE_C_DEFINED_glTextureImage3DEXT + void __stdcall GLee_Lazy_glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTextureImage3DEXT(texture, target, level, internalformat, width, height, depth, border, format, type, pixels);} + GLEEPFNGLTEXTUREIMAGE3DEXTPROC GLeeFuncPtr_glTextureImage3DEXT=GLee_Lazy_glTextureImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureSubImage3DEXT +#define GLEE_C_DEFINED_glTextureSubImage3DEXT + void __stdcall GLee_Lazy_glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);} + GLEEPFNGLTEXTURESUBIMAGE3DEXTPROC GLeeFuncPtr_glTextureSubImage3DEXT=GLee_Lazy_glTextureSubImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyTextureSubImage3DEXT +#define GLEE_C_DEFINED_glCopyTextureSubImage3DEXT + void __stdcall GLee_Lazy_glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, x, y, width, height);} + GLEEPFNGLCOPYTEXTURESUBIMAGE3DEXTPROC GLeeFuncPtr_glCopyTextureSubImage3DEXT=GLee_Lazy_glCopyTextureSubImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexParameterfEXT +#define GLEE_C_DEFINED_glMultiTexParameterfEXT + void __stdcall GLee_Lazy_glMultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param) {if (GLeeInit()) glMultiTexParameterfEXT(texunit, target, pname, param);} + GLEEPFNGLMULTITEXPARAMETERFEXTPROC GLeeFuncPtr_glMultiTexParameterfEXT=GLee_Lazy_glMultiTexParameterfEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexParameterfvEXT +#define GLEE_C_DEFINED_glMultiTexParameterfvEXT + void __stdcall GLee_Lazy_glMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glMultiTexParameterfvEXT(texunit, target, pname, params);} + GLEEPFNGLMULTITEXPARAMETERFVEXTPROC GLeeFuncPtr_glMultiTexParameterfvEXT=GLee_Lazy_glMultiTexParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexParameteriEXT +#define GLEE_C_DEFINED_glMultiTexParameteriEXT + void __stdcall GLee_Lazy_glMultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint param) {if (GLeeInit()) glMultiTexParameteriEXT(texunit, target, pname, param);} + GLEEPFNGLMULTITEXPARAMETERIEXTPROC GLeeFuncPtr_glMultiTexParameteriEXT=GLee_Lazy_glMultiTexParameteriEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexParameterivEXT +#define GLEE_C_DEFINED_glMultiTexParameterivEXT + void __stdcall GLee_Lazy_glMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glMultiTexParameterivEXT(texunit, target, pname, params);} + GLEEPFNGLMULTITEXPARAMETERIVEXTPROC GLeeFuncPtr_glMultiTexParameterivEXT=GLee_Lazy_glMultiTexParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexImage1DEXT +#define GLEE_C_DEFINED_glMultiTexImage1DEXT + void __stdcall GLee_Lazy_glMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glMultiTexImage1DEXT(texunit, target, level, internalformat, width, border, format, type, pixels);} + GLEEPFNGLMULTITEXIMAGE1DEXTPROC GLeeFuncPtr_glMultiTexImage1DEXT=GLee_Lazy_glMultiTexImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexImage2DEXT +#define GLEE_C_DEFINED_glMultiTexImage2DEXT + void __stdcall GLee_Lazy_glMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glMultiTexImage2DEXT(texunit, target, level, internalformat, width, height, border, format, type, pixels);} + GLEEPFNGLMULTITEXIMAGE2DEXTPROC GLeeFuncPtr_glMultiTexImage2DEXT=GLee_Lazy_glMultiTexImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexSubImage1DEXT +#define GLEE_C_DEFINED_glMultiTexSubImage1DEXT + void __stdcall GLee_Lazy_glMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glMultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, type, pixels);} + GLEEPFNGLMULTITEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glMultiTexSubImage1DEXT=GLee_Lazy_glMultiTexSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexSubImage2DEXT +#define GLEE_C_DEFINED_glMultiTexSubImage2DEXT + void __stdcall GLee_Lazy_glMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, format, type, pixels);} + GLEEPFNGLMULTITEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glMultiTexSubImage2DEXT=GLee_Lazy_glMultiTexSubImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyMultiTexImage1DEXT +#define GLEE_C_DEFINED_glCopyMultiTexImage1DEXT + void __stdcall GLee_Lazy_glCopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {if (GLeeInit()) glCopyMultiTexImage1DEXT(texunit, target, level, internalformat, x, y, width, border);} + GLEEPFNGLCOPYMULTITEXIMAGE1DEXTPROC GLeeFuncPtr_glCopyMultiTexImage1DEXT=GLee_Lazy_glCopyMultiTexImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyMultiTexImage2DEXT +#define GLEE_C_DEFINED_glCopyMultiTexImage2DEXT + void __stdcall GLee_Lazy_glCopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {if (GLeeInit()) glCopyMultiTexImage2DEXT(texunit, target, level, internalformat, x, y, width, height, border);} + GLEEPFNGLCOPYMULTITEXIMAGE2DEXTPROC GLeeFuncPtr_glCopyMultiTexImage2DEXT=GLee_Lazy_glCopyMultiTexImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyMultiTexSubImage1DEXT +#define GLEE_C_DEFINED_glCopyMultiTexSubImage1DEXT + void __stdcall GLee_Lazy_glCopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {if (GLeeInit()) glCopyMultiTexSubImage1DEXT(texunit, target, level, xoffset, x, y, width);} + GLEEPFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glCopyMultiTexSubImage1DEXT=GLee_Lazy_glCopyMultiTexSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyMultiTexSubImage2DEXT +#define GLEE_C_DEFINED_glCopyMultiTexSubImage2DEXT + void __stdcall GLee_Lazy_glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, x, y, width, height);} + GLEEPFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glCopyMultiTexSubImage2DEXT=GLee_Lazy_glCopyMultiTexSubImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexImageEXT +#define GLEE_C_DEFINED_glGetMultiTexImageEXT + void __stdcall GLee_Lazy_glGetMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels) {if (GLeeInit()) glGetMultiTexImageEXT(texunit, target, level, format, type, pixels);} + GLEEPFNGLGETMULTITEXIMAGEEXTPROC GLeeFuncPtr_glGetMultiTexImageEXT=GLee_Lazy_glGetMultiTexImageEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexParameterfvEXT +#define GLEE_C_DEFINED_glGetMultiTexParameterfvEXT + void __stdcall GLee_Lazy_glGetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMultiTexParameterfvEXT(texunit, target, pname, params);} + GLEEPFNGLGETMULTITEXPARAMETERFVEXTPROC GLeeFuncPtr_glGetMultiTexParameterfvEXT=GLee_Lazy_glGetMultiTexParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexParameterivEXT +#define GLEE_C_DEFINED_glGetMultiTexParameterivEXT + void __stdcall GLee_Lazy_glGetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetMultiTexParameterivEXT(texunit, target, pname, params);} + GLEEPFNGLGETMULTITEXPARAMETERIVEXTPROC GLeeFuncPtr_glGetMultiTexParameterivEXT=GLee_Lazy_glGetMultiTexParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexLevelParameterfvEXT +#define GLEE_C_DEFINED_glGetMultiTexLevelParameterfvEXT + void __stdcall GLee_Lazy_glGetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMultiTexLevelParameterfvEXT(texunit, target, level, pname, params);} + GLEEPFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC GLeeFuncPtr_glGetMultiTexLevelParameterfvEXT=GLee_Lazy_glGetMultiTexLevelParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexLevelParameterivEXT +#define GLEE_C_DEFINED_glGetMultiTexLevelParameterivEXT + void __stdcall GLee_Lazy_glGetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint * params) {if (GLeeInit()) glGetMultiTexLevelParameterivEXT(texunit, target, level, pname, params);} + GLEEPFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC GLeeFuncPtr_glGetMultiTexLevelParameterivEXT=GLee_Lazy_glGetMultiTexLevelParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexImage3DEXT +#define GLEE_C_DEFINED_glMultiTexImage3DEXT + void __stdcall GLee_Lazy_glMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glMultiTexImage3DEXT(texunit, target, level, internalformat, width, height, depth, border, format, type, pixels);} + GLEEPFNGLMULTITEXIMAGE3DEXTPROC GLeeFuncPtr_glMultiTexImage3DEXT=GLee_Lazy_glMultiTexImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexSubImage3DEXT +#define GLEE_C_DEFINED_glMultiTexSubImage3DEXT + void __stdcall GLee_Lazy_glMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels) {if (GLeeInit()) glMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);} + GLEEPFNGLMULTITEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glMultiTexSubImage3DEXT=GLee_Lazy_glMultiTexSubImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCopyMultiTexSubImage3DEXT +#define GLEE_C_DEFINED_glCopyMultiTexSubImage3DEXT + void __stdcall GLee_Lazy_glCopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glCopyMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, x, y, width, height);} + GLEEPFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glCopyMultiTexSubImage3DEXT=GLee_Lazy_glCopyMultiTexSubImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glBindMultiTextureEXT +#define GLEE_C_DEFINED_glBindMultiTextureEXT + void __stdcall GLee_Lazy_glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) {if (GLeeInit()) glBindMultiTextureEXT(texunit, target, texture);} + GLEEPFNGLBINDMULTITEXTUREEXTPROC GLeeFuncPtr_glBindMultiTextureEXT=GLee_Lazy_glBindMultiTextureEXT; +#endif +#ifndef GLEE_C_DEFINED_glEnableClientStateIndexedEXT +#define GLEE_C_DEFINED_glEnableClientStateIndexedEXT + void __stdcall GLee_Lazy_glEnableClientStateIndexedEXT(GLenum array, GLuint index) {if (GLeeInit()) glEnableClientStateIndexedEXT(array, index);} + GLEEPFNGLENABLECLIENTSTATEINDEXEDEXTPROC GLeeFuncPtr_glEnableClientStateIndexedEXT=GLee_Lazy_glEnableClientStateIndexedEXT; +#endif +#ifndef GLEE_C_DEFINED_glDisableClientStateIndexedEXT +#define GLEE_C_DEFINED_glDisableClientStateIndexedEXT + void __stdcall GLee_Lazy_glDisableClientStateIndexedEXT(GLenum array, GLuint index) {if (GLeeInit()) glDisableClientStateIndexedEXT(array, index);} + GLEEPFNGLDISABLECLIENTSTATEINDEXEDEXTPROC GLeeFuncPtr_glDisableClientStateIndexedEXT=GLee_Lazy_glDisableClientStateIndexedEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoordPointerEXT +#define GLEE_C_DEFINED_glMultiTexCoordPointerEXT + void __stdcall GLee_Lazy_glMultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glMultiTexCoordPointerEXT(texunit, size, type, stride, pointer);} + GLEEPFNGLMULTITEXCOORDPOINTEREXTPROC GLeeFuncPtr_glMultiTexCoordPointerEXT=GLee_Lazy_glMultiTexCoordPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexEnvfEXT +#define GLEE_C_DEFINED_glMultiTexEnvfEXT + void __stdcall GLee_Lazy_glMultiTexEnvfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param) {if (GLeeInit()) glMultiTexEnvfEXT(texunit, target, pname, param);} + GLEEPFNGLMULTITEXENVFEXTPROC GLeeFuncPtr_glMultiTexEnvfEXT=GLee_Lazy_glMultiTexEnvfEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexEnvfvEXT +#define GLEE_C_DEFINED_glMultiTexEnvfvEXT + void __stdcall GLee_Lazy_glMultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glMultiTexEnvfvEXT(texunit, target, pname, params);} + GLEEPFNGLMULTITEXENVFVEXTPROC GLeeFuncPtr_glMultiTexEnvfvEXT=GLee_Lazy_glMultiTexEnvfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexEnviEXT +#define GLEE_C_DEFINED_glMultiTexEnviEXT + void __stdcall GLee_Lazy_glMultiTexEnviEXT(GLenum texunit, GLenum target, GLenum pname, GLint param) {if (GLeeInit()) glMultiTexEnviEXT(texunit, target, pname, param);} + GLEEPFNGLMULTITEXENVIEXTPROC GLeeFuncPtr_glMultiTexEnviEXT=GLee_Lazy_glMultiTexEnviEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexEnvivEXT +#define GLEE_C_DEFINED_glMultiTexEnvivEXT + void __stdcall GLee_Lazy_glMultiTexEnvivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glMultiTexEnvivEXT(texunit, target, pname, params);} + GLEEPFNGLMULTITEXENVIVEXTPROC GLeeFuncPtr_glMultiTexEnvivEXT=GLee_Lazy_glMultiTexEnvivEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexGendEXT +#define GLEE_C_DEFINED_glMultiTexGendEXT + void __stdcall GLee_Lazy_glMultiTexGendEXT(GLenum texunit, GLenum coord, GLenum pname, GLdouble param) {if (GLeeInit()) glMultiTexGendEXT(texunit, coord, pname, param);} + GLEEPFNGLMULTITEXGENDEXTPROC GLeeFuncPtr_glMultiTexGendEXT=GLee_Lazy_glMultiTexGendEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexGendvEXT +#define GLEE_C_DEFINED_glMultiTexGendvEXT + void __stdcall GLee_Lazy_glMultiTexGendvEXT(GLenum texunit, GLenum coord, GLenum pname, const GLdouble * params) {if (GLeeInit()) glMultiTexGendvEXT(texunit, coord, pname, params);} + GLEEPFNGLMULTITEXGENDVEXTPROC GLeeFuncPtr_glMultiTexGendvEXT=GLee_Lazy_glMultiTexGendvEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexGenfEXT +#define GLEE_C_DEFINED_glMultiTexGenfEXT + void __stdcall GLee_Lazy_glMultiTexGenfEXT(GLenum texunit, GLenum coord, GLenum pname, GLfloat param) {if (GLeeInit()) glMultiTexGenfEXT(texunit, coord, pname, param);} + GLEEPFNGLMULTITEXGENFEXTPROC GLeeFuncPtr_glMultiTexGenfEXT=GLee_Lazy_glMultiTexGenfEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexGenfvEXT +#define GLEE_C_DEFINED_glMultiTexGenfvEXT + void __stdcall GLee_Lazy_glMultiTexGenfvEXT(GLenum texunit, GLenum coord, GLenum pname, const GLfloat * params) {if (GLeeInit()) glMultiTexGenfvEXT(texunit, coord, pname, params);} + GLEEPFNGLMULTITEXGENFVEXTPROC GLeeFuncPtr_glMultiTexGenfvEXT=GLee_Lazy_glMultiTexGenfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexGeniEXT +#define GLEE_C_DEFINED_glMultiTexGeniEXT + void __stdcall GLee_Lazy_glMultiTexGeniEXT(GLenum texunit, GLenum coord, GLenum pname, GLint param) {if (GLeeInit()) glMultiTexGeniEXT(texunit, coord, pname, param);} + GLEEPFNGLMULTITEXGENIEXTPROC GLeeFuncPtr_glMultiTexGeniEXT=GLee_Lazy_glMultiTexGeniEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexGenivEXT +#define GLEE_C_DEFINED_glMultiTexGenivEXT + void __stdcall GLee_Lazy_glMultiTexGenivEXT(GLenum texunit, GLenum coord, GLenum pname, const GLint * params) {if (GLeeInit()) glMultiTexGenivEXT(texunit, coord, pname, params);} + GLEEPFNGLMULTITEXGENIVEXTPROC GLeeFuncPtr_glMultiTexGenivEXT=GLee_Lazy_glMultiTexGenivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexEnvfvEXT +#define GLEE_C_DEFINED_glGetMultiTexEnvfvEXT + void __stdcall GLee_Lazy_glGetMultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMultiTexEnvfvEXT(texunit, target, pname, params);} + GLEEPFNGLGETMULTITEXENVFVEXTPROC GLeeFuncPtr_glGetMultiTexEnvfvEXT=GLee_Lazy_glGetMultiTexEnvfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexEnvivEXT +#define GLEE_C_DEFINED_glGetMultiTexEnvivEXT + void __stdcall GLee_Lazy_glGetMultiTexEnvivEXT(GLenum texunit, GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetMultiTexEnvivEXT(texunit, target, pname, params);} + GLEEPFNGLGETMULTITEXENVIVEXTPROC GLeeFuncPtr_glGetMultiTexEnvivEXT=GLee_Lazy_glGetMultiTexEnvivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexGendvEXT +#define GLEE_C_DEFINED_glGetMultiTexGendvEXT + void __stdcall GLee_Lazy_glGetMultiTexGendvEXT(GLenum texunit, GLenum coord, GLenum pname, GLdouble * params) {if (GLeeInit()) glGetMultiTexGendvEXT(texunit, coord, pname, params);} + GLEEPFNGLGETMULTITEXGENDVEXTPROC GLeeFuncPtr_glGetMultiTexGendvEXT=GLee_Lazy_glGetMultiTexGendvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexGenfvEXT +#define GLEE_C_DEFINED_glGetMultiTexGenfvEXT + void __stdcall GLee_Lazy_glGetMultiTexGenfvEXT(GLenum texunit, GLenum coord, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetMultiTexGenfvEXT(texunit, coord, pname, params);} + GLEEPFNGLGETMULTITEXGENFVEXTPROC GLeeFuncPtr_glGetMultiTexGenfvEXT=GLee_Lazy_glGetMultiTexGenfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexGenivEXT +#define GLEE_C_DEFINED_glGetMultiTexGenivEXT + void __stdcall GLee_Lazy_glGetMultiTexGenivEXT(GLenum texunit, GLenum coord, GLenum pname, GLint * params) {if (GLeeInit()) glGetMultiTexGenivEXT(texunit, coord, pname, params);} + GLEEPFNGLGETMULTITEXGENIVEXTPROC GLeeFuncPtr_glGetMultiTexGenivEXT=GLee_Lazy_glGetMultiTexGenivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFloatIndexedvEXT +#define GLEE_C_DEFINED_glGetFloatIndexedvEXT + void __stdcall GLee_Lazy_glGetFloatIndexedvEXT(GLenum target, GLuint index, GLfloat * data) {if (GLeeInit()) glGetFloatIndexedvEXT(target, index, data);} + GLEEPFNGLGETFLOATINDEXEDVEXTPROC GLeeFuncPtr_glGetFloatIndexedvEXT=GLee_Lazy_glGetFloatIndexedvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetDoubleIndexedvEXT +#define GLEE_C_DEFINED_glGetDoubleIndexedvEXT + void __stdcall GLee_Lazy_glGetDoubleIndexedvEXT(GLenum target, GLuint index, GLdouble * data) {if (GLeeInit()) glGetDoubleIndexedvEXT(target, index, data);} + GLEEPFNGLGETDOUBLEINDEXEDVEXTPROC GLeeFuncPtr_glGetDoubleIndexedvEXT=GLee_Lazy_glGetDoubleIndexedvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetPointerIndexedvEXT +#define GLEE_C_DEFINED_glGetPointerIndexedvEXT + void __stdcall GLee_Lazy_glGetPointerIndexedvEXT(GLenum target, GLuint index, GLvoid* * data) {if (GLeeInit()) glGetPointerIndexedvEXT(target, index, data);} + GLEEPFNGLGETPOINTERINDEXEDVEXTPROC GLeeFuncPtr_glGetPointerIndexedvEXT=GLee_Lazy_glGetPointerIndexedvEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTextureImage3DEXT +#define GLEE_C_DEFINED_glCompressedTextureImage3DEXT + void __stdcall GLee_Lazy_glCompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedTextureImage3DEXT(texture, target, level, internalformat, width, height, depth, border, imageSize, bits);} + GLEEPFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC GLeeFuncPtr_glCompressedTextureImage3DEXT=GLee_Lazy_glCompressedTextureImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTextureImage2DEXT +#define GLEE_C_DEFINED_glCompressedTextureImage2DEXT + void __stdcall GLee_Lazy_glCompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedTextureImage2DEXT(texture, target, level, internalformat, width, height, border, imageSize, bits);} + GLEEPFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC GLeeFuncPtr_glCompressedTextureImage2DEXT=GLee_Lazy_glCompressedTextureImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTextureImage1DEXT +#define GLEE_C_DEFINED_glCompressedTextureImage1DEXT + void __stdcall GLee_Lazy_glCompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedTextureImage1DEXT(texture, target, level, internalformat, width, border, imageSize, bits);} + GLEEPFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC GLeeFuncPtr_glCompressedTextureImage1DEXT=GLee_Lazy_glCompressedTextureImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTextureSubImage3DEXT +#define GLEE_C_DEFINED_glCompressedTextureSubImage3DEXT + void __stdcall GLee_Lazy_glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);} + GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC GLeeFuncPtr_glCompressedTextureSubImage3DEXT=GLee_Lazy_glCompressedTextureSubImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTextureSubImage2DEXT +#define GLEE_C_DEFINED_glCompressedTextureSubImage2DEXT + void __stdcall GLee_Lazy_glCompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);} + GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC GLeeFuncPtr_glCompressedTextureSubImage2DEXT=GLee_Lazy_glCompressedTextureSubImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedTextureSubImage1DEXT +#define GLEE_C_DEFINED_glCompressedTextureSubImage1DEXT + void __stdcall GLee_Lazy_glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits);} + GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC GLeeFuncPtr_glCompressedTextureSubImage1DEXT=GLee_Lazy_glCompressedTextureSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetCompressedTextureImageEXT +#define GLEE_C_DEFINED_glGetCompressedTextureImageEXT + void __stdcall GLee_Lazy_glGetCompressedTextureImageEXT(GLuint texture, GLenum target, GLint lod, GLvoid * img) {if (GLeeInit()) glGetCompressedTextureImageEXT(texture, target, lod, img);} + GLEEPFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC GLeeFuncPtr_glGetCompressedTextureImageEXT=GLee_Lazy_glGetCompressedTextureImageEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedMultiTexImage3DEXT +#define GLEE_C_DEFINED_glCompressedMultiTexImage3DEXT + void __stdcall GLee_Lazy_glCompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedMultiTexImage3DEXT(texunit, target, level, internalformat, width, height, depth, border, imageSize, bits);} + GLEEPFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC GLeeFuncPtr_glCompressedMultiTexImage3DEXT=GLee_Lazy_glCompressedMultiTexImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedMultiTexImage2DEXT +#define GLEE_C_DEFINED_glCompressedMultiTexImage2DEXT + void __stdcall GLee_Lazy_glCompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedMultiTexImage2DEXT(texunit, target, level, internalformat, width, height, border, imageSize, bits);} + GLEEPFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC GLeeFuncPtr_glCompressedMultiTexImage2DEXT=GLee_Lazy_glCompressedMultiTexImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedMultiTexImage1DEXT +#define GLEE_C_DEFINED_glCompressedMultiTexImage1DEXT + void __stdcall GLee_Lazy_glCompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedMultiTexImage1DEXT(texunit, target, level, internalformat, width, border, imageSize, bits);} + GLEEPFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC GLeeFuncPtr_glCompressedMultiTexImage1DEXT=GLee_Lazy_glCompressedMultiTexImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedMultiTexSubImage3DEXT +#define GLEE_C_DEFINED_glCompressedMultiTexSubImage3DEXT + void __stdcall GLee_Lazy_glCompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);} + GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glCompressedMultiTexSubImage3DEXT=GLee_Lazy_glCompressedMultiTexSubImage3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedMultiTexSubImage2DEXT +#define GLEE_C_DEFINED_glCompressedMultiTexSubImage2DEXT + void __stdcall GLee_Lazy_glCompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, format, imageSize, bits);} + GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glCompressedMultiTexSubImage2DEXT=GLee_Lazy_glCompressedMultiTexSubImage2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glCompressedMultiTexSubImage1DEXT +#define GLEE_C_DEFINED_glCompressedMultiTexSubImage1DEXT + void __stdcall GLee_Lazy_glCompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * bits) {if (GLeeInit()) glCompressedMultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, imageSize, bits);} + GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glCompressedMultiTexSubImage1DEXT=GLee_Lazy_glCompressedMultiTexSubImage1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetCompressedMultiTexImageEXT +#define GLEE_C_DEFINED_glGetCompressedMultiTexImageEXT + void __stdcall GLee_Lazy_glGetCompressedMultiTexImageEXT(GLenum texunit, GLenum target, GLint lod, GLvoid * img) {if (GLeeInit()) glGetCompressedMultiTexImageEXT(texunit, target, lod, img);} + GLEEPFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC GLeeFuncPtr_glGetCompressedMultiTexImageEXT=GLee_Lazy_glGetCompressedMultiTexImageEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramStringEXT +#define GLEE_C_DEFINED_glNamedProgramStringEXT + void __stdcall GLee_Lazy_glNamedProgramStringEXT(GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid * string) {if (GLeeInit()) glNamedProgramStringEXT(program, target, format, len, string);} + GLEEPFNGLNAMEDPROGRAMSTRINGEXTPROC GLeeFuncPtr_glNamedProgramStringEXT=GLee_Lazy_glNamedProgramStringEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameter4dEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameter4dEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameter4dEXT(GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glNamedProgramLocalParameter4dEXT(program, target, index, x, y, z, w);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4dEXT=GLee_Lazy_glNamedProgramLocalParameter4dEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameter4dvEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameter4dvEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameter4dvEXT(GLuint program, GLenum target, GLuint index, const GLdouble * params) {if (GLeeInit()) glNamedProgramLocalParameter4dvEXT(program, target, index, params);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4dvEXT=GLee_Lazy_glNamedProgramLocalParameter4dvEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameter4fEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameter4fEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameter4fEXT(GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glNamedProgramLocalParameter4fEXT(program, target, index, x, y, z, w);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4fEXT=GLee_Lazy_glNamedProgramLocalParameter4fEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameter4fvEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameter4fvEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint index, const GLfloat * params) {if (GLeeInit()) glNamedProgramLocalParameter4fvEXT(program, target, index, params);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4fvEXT=GLee_Lazy_glNamedProgramLocalParameter4fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedProgramLocalParameterdvEXT +#define GLEE_C_DEFINED_glGetNamedProgramLocalParameterdvEXT + void __stdcall GLee_Lazy_glGetNamedProgramLocalParameterdvEXT(GLuint program, GLenum target, GLuint index, GLdouble * params) {if (GLeeInit()) glGetNamedProgramLocalParameterdvEXT(program, target, index, params);} + GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterdvEXT=GLee_Lazy_glGetNamedProgramLocalParameterdvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedProgramLocalParameterfvEXT +#define GLEE_C_DEFINED_glGetNamedProgramLocalParameterfvEXT + void __stdcall GLee_Lazy_glGetNamedProgramLocalParameterfvEXT(GLuint program, GLenum target, GLuint index, GLfloat * params) {if (GLeeInit()) glGetNamedProgramLocalParameterfvEXT(program, target, index, params);} + GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterfvEXT=GLee_Lazy_glGetNamedProgramLocalParameterfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedProgramivEXT +#define GLEE_C_DEFINED_glGetNamedProgramivEXT + void __stdcall GLee_Lazy_glGetNamedProgramivEXT(GLuint program, GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetNamedProgramivEXT(program, target, pname, params);} + GLEEPFNGLGETNAMEDPROGRAMIVEXTPROC GLeeFuncPtr_glGetNamedProgramivEXT=GLee_Lazy_glGetNamedProgramivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedProgramStringEXT +#define GLEE_C_DEFINED_glGetNamedProgramStringEXT + void __stdcall GLee_Lazy_glGetNamedProgramStringEXT(GLuint program, GLenum target, GLenum pname, GLvoid * string) {if (GLeeInit()) glGetNamedProgramStringEXT(program, target, pname, string);} + GLEEPFNGLGETNAMEDPROGRAMSTRINGEXTPROC GLeeFuncPtr_glGetNamedProgramStringEXT=GLee_Lazy_glGetNamedProgramStringEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameters4fvEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameters4fvEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameters4fvEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat * params) {if (GLeeInit()) glNamedProgramLocalParameters4fvEXT(program, target, index, count, params);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameters4fvEXT=GLee_Lazy_glNamedProgramLocalParameters4fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameterI4iEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameterI4iEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameterI4iEXT(GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w) {if (GLeeInit()) glNamedProgramLocalParameterI4iEXT(program, target, index, x, y, z, w);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4iEXT=GLee_Lazy_glNamedProgramLocalParameterI4iEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameterI4ivEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameterI4ivEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameterI4ivEXT(GLuint program, GLenum target, GLuint index, const GLint * params) {if (GLeeInit()) glNamedProgramLocalParameterI4ivEXT(program, target, index, params);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4ivEXT=GLee_Lazy_glNamedProgramLocalParameterI4ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParametersI4ivEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParametersI4ivEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParametersI4ivEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLint * params) {if (GLeeInit()) glNamedProgramLocalParametersI4ivEXT(program, target, index, count, params);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC GLeeFuncPtr_glNamedProgramLocalParametersI4ivEXT=GLee_Lazy_glNamedProgramLocalParametersI4ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameterI4uiEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameterI4uiEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameterI4uiEXT(GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {if (GLeeInit()) glNamedProgramLocalParameterI4uiEXT(program, target, index, x, y, z, w);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4uiEXT=GLee_Lazy_glNamedProgramLocalParameterI4uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParameterI4uivEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParameterI4uivEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParameterI4uivEXT(GLuint program, GLenum target, GLuint index, const GLuint * params) {if (GLeeInit()) glNamedProgramLocalParameterI4uivEXT(program, target, index, params);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4uivEXT=GLee_Lazy_glNamedProgramLocalParameterI4uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedProgramLocalParametersI4uivEXT +#define GLEE_C_DEFINED_glNamedProgramLocalParametersI4uivEXT + void __stdcall GLee_Lazy_glNamedProgramLocalParametersI4uivEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint * params) {if (GLeeInit()) glNamedProgramLocalParametersI4uivEXT(program, target, index, count, params);} + GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC GLeeFuncPtr_glNamedProgramLocalParametersI4uivEXT=GLee_Lazy_glNamedProgramLocalParametersI4uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedProgramLocalParameterIivEXT +#define GLEE_C_DEFINED_glGetNamedProgramLocalParameterIivEXT + void __stdcall GLee_Lazy_glGetNamedProgramLocalParameterIivEXT(GLuint program, GLenum target, GLuint index, GLint * params) {if (GLeeInit()) glGetNamedProgramLocalParameterIivEXT(program, target, index, params);} + GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterIivEXT=GLee_Lazy_glGetNamedProgramLocalParameterIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedProgramLocalParameterIuivEXT +#define GLEE_C_DEFINED_glGetNamedProgramLocalParameterIuivEXT + void __stdcall GLee_Lazy_glGetNamedProgramLocalParameterIuivEXT(GLuint program, GLenum target, GLuint index, GLuint * params) {if (GLeeInit()) glGetNamedProgramLocalParameterIuivEXT(program, target, index, params);} + GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterIuivEXT=GLee_Lazy_glGetNamedProgramLocalParameterIuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureParameterIivEXT +#define GLEE_C_DEFINED_glTextureParameterIivEXT + void __stdcall GLee_Lazy_glTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glTextureParameterIivEXT(texture, target, pname, params);} + GLEEPFNGLTEXTUREPARAMETERIIVEXTPROC GLeeFuncPtr_glTextureParameterIivEXT=GLee_Lazy_glTextureParameterIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureParameterIuivEXT +#define GLEE_C_DEFINED_glTextureParameterIuivEXT + void __stdcall GLee_Lazy_glTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint * params) {if (GLeeInit()) glTextureParameterIuivEXT(texture, target, pname, params);} + GLEEPFNGLTEXTUREPARAMETERIUIVEXTPROC GLeeFuncPtr_glTextureParameterIuivEXT=GLee_Lazy_glTextureParameterIuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureParameterIivEXT +#define GLEE_C_DEFINED_glGetTextureParameterIivEXT + void __stdcall GLee_Lazy_glGetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetTextureParameterIivEXT(texture, target, pname, params);} + GLEEPFNGLGETTEXTUREPARAMETERIIVEXTPROC GLeeFuncPtr_glGetTextureParameterIivEXT=GLee_Lazy_glGetTextureParameterIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureParameterIuivEXT +#define GLEE_C_DEFINED_glGetTextureParameterIuivEXT + void __stdcall GLee_Lazy_glGetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, GLuint * params) {if (GLeeInit()) glGetTextureParameterIuivEXT(texture, target, pname, params);} + GLEEPFNGLGETTEXTUREPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetTextureParameterIuivEXT=GLee_Lazy_glGetTextureParameterIuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexParameterIivEXT +#define GLEE_C_DEFINED_glMultiTexParameterIivEXT + void __stdcall GLee_Lazy_glMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint * params) {if (GLeeInit()) glMultiTexParameterIivEXT(texunit, target, pname, params);} + GLEEPFNGLMULTITEXPARAMETERIIVEXTPROC GLeeFuncPtr_glMultiTexParameterIivEXT=GLee_Lazy_glMultiTexParameterIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexParameterIuivEXT +#define GLEE_C_DEFINED_glMultiTexParameterIuivEXT + void __stdcall GLee_Lazy_glMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const GLuint * params) {if (GLeeInit()) glMultiTexParameterIuivEXT(texunit, target, pname, params);} + GLEEPFNGLMULTITEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glMultiTexParameterIuivEXT=GLee_Lazy_glMultiTexParameterIuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexParameterIivEXT +#define GLEE_C_DEFINED_glGetMultiTexParameterIivEXT + void __stdcall GLee_Lazy_glGetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetMultiTexParameterIivEXT(texunit, target, pname, params);} + GLEEPFNGLGETMULTITEXPARAMETERIIVEXTPROC GLeeFuncPtr_glGetMultiTexParameterIivEXT=GLee_Lazy_glGetMultiTexParameterIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetMultiTexParameterIuivEXT +#define GLEE_C_DEFINED_glGetMultiTexParameterIuivEXT + void __stdcall GLee_Lazy_glGetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, GLuint * params) {if (GLeeInit()) glGetMultiTexParameterIuivEXT(texunit, target, pname, params);} + GLEEPFNGLGETMULTITEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetMultiTexParameterIuivEXT=GLee_Lazy_glGetMultiTexParameterIuivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform1fEXT +#define GLEE_C_DEFINED_glProgramUniform1fEXT + void __stdcall GLee_Lazy_glProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0) {if (GLeeInit()) glProgramUniform1fEXT(program, location, v0);} + GLEEPFNGLPROGRAMUNIFORM1FEXTPROC GLeeFuncPtr_glProgramUniform1fEXT=GLee_Lazy_glProgramUniform1fEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform2fEXT +#define GLEE_C_DEFINED_glProgramUniform2fEXT + void __stdcall GLee_Lazy_glProgramUniform2fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1) {if (GLeeInit()) glProgramUniform2fEXT(program, location, v0, v1);} + GLEEPFNGLPROGRAMUNIFORM2FEXTPROC GLeeFuncPtr_glProgramUniform2fEXT=GLee_Lazy_glProgramUniform2fEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform3fEXT +#define GLEE_C_DEFINED_glProgramUniform3fEXT + void __stdcall GLee_Lazy_glProgramUniform3fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {if (GLeeInit()) glProgramUniform3fEXT(program, location, v0, v1, v2);} + GLEEPFNGLPROGRAMUNIFORM3FEXTPROC GLeeFuncPtr_glProgramUniform3fEXT=GLee_Lazy_glProgramUniform3fEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform4fEXT +#define GLEE_C_DEFINED_glProgramUniform4fEXT + void __stdcall GLee_Lazy_glProgramUniform4fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {if (GLeeInit()) glProgramUniform4fEXT(program, location, v0, v1, v2, v3);} + GLEEPFNGLPROGRAMUNIFORM4FEXTPROC GLeeFuncPtr_glProgramUniform4fEXT=GLee_Lazy_glProgramUniform4fEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform1iEXT +#define GLEE_C_DEFINED_glProgramUniform1iEXT + void __stdcall GLee_Lazy_glProgramUniform1iEXT(GLuint program, GLint location, GLint v0) {if (GLeeInit()) glProgramUniform1iEXT(program, location, v0);} + GLEEPFNGLPROGRAMUNIFORM1IEXTPROC GLeeFuncPtr_glProgramUniform1iEXT=GLee_Lazy_glProgramUniform1iEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform2iEXT +#define GLEE_C_DEFINED_glProgramUniform2iEXT + void __stdcall GLee_Lazy_glProgramUniform2iEXT(GLuint program, GLint location, GLint v0, GLint v1) {if (GLeeInit()) glProgramUniform2iEXT(program, location, v0, v1);} + GLEEPFNGLPROGRAMUNIFORM2IEXTPROC GLeeFuncPtr_glProgramUniform2iEXT=GLee_Lazy_glProgramUniform2iEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform3iEXT +#define GLEE_C_DEFINED_glProgramUniform3iEXT + void __stdcall GLee_Lazy_glProgramUniform3iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) {if (GLeeInit()) glProgramUniform3iEXT(program, location, v0, v1, v2);} + GLEEPFNGLPROGRAMUNIFORM3IEXTPROC GLeeFuncPtr_glProgramUniform3iEXT=GLee_Lazy_glProgramUniform3iEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform4iEXT +#define GLEE_C_DEFINED_glProgramUniform4iEXT + void __stdcall GLee_Lazy_glProgramUniform4iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {if (GLeeInit()) glProgramUniform4iEXT(program, location, v0, v1, v2, v3);} + GLEEPFNGLPROGRAMUNIFORM4IEXTPROC GLeeFuncPtr_glProgramUniform4iEXT=GLee_Lazy_glProgramUniform4iEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform1fvEXT +#define GLEE_C_DEFINED_glProgramUniform1fvEXT + void __stdcall GLee_Lazy_glProgramUniform1fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glProgramUniform1fvEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM1FVEXTPROC GLeeFuncPtr_glProgramUniform1fvEXT=GLee_Lazy_glProgramUniform1fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform2fvEXT +#define GLEE_C_DEFINED_glProgramUniform2fvEXT + void __stdcall GLee_Lazy_glProgramUniform2fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glProgramUniform2fvEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM2FVEXTPROC GLeeFuncPtr_glProgramUniform2fvEXT=GLee_Lazy_glProgramUniform2fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform3fvEXT +#define GLEE_C_DEFINED_glProgramUniform3fvEXT + void __stdcall GLee_Lazy_glProgramUniform3fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glProgramUniform3fvEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM3FVEXTPROC GLeeFuncPtr_glProgramUniform3fvEXT=GLee_Lazy_glProgramUniform3fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform4fvEXT +#define GLEE_C_DEFINED_glProgramUniform4fvEXT + void __stdcall GLee_Lazy_glProgramUniform4fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat * value) {if (GLeeInit()) glProgramUniform4fvEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM4FVEXTPROC GLeeFuncPtr_glProgramUniform4fvEXT=GLee_Lazy_glProgramUniform4fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform1ivEXT +#define GLEE_C_DEFINED_glProgramUniform1ivEXT + void __stdcall GLee_Lazy_glProgramUniform1ivEXT(GLuint program, GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glProgramUniform1ivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM1IVEXTPROC GLeeFuncPtr_glProgramUniform1ivEXT=GLee_Lazy_glProgramUniform1ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform2ivEXT +#define GLEE_C_DEFINED_glProgramUniform2ivEXT + void __stdcall GLee_Lazy_glProgramUniform2ivEXT(GLuint program, GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glProgramUniform2ivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM2IVEXTPROC GLeeFuncPtr_glProgramUniform2ivEXT=GLee_Lazy_glProgramUniform2ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform3ivEXT +#define GLEE_C_DEFINED_glProgramUniform3ivEXT + void __stdcall GLee_Lazy_glProgramUniform3ivEXT(GLuint program, GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glProgramUniform3ivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM3IVEXTPROC GLeeFuncPtr_glProgramUniform3ivEXT=GLee_Lazy_glProgramUniform3ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform4ivEXT +#define GLEE_C_DEFINED_glProgramUniform4ivEXT + void __stdcall GLee_Lazy_glProgramUniform4ivEXT(GLuint program, GLint location, GLsizei count, const GLint * value) {if (GLeeInit()) glProgramUniform4ivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM4IVEXTPROC GLeeFuncPtr_glProgramUniform4ivEXT=GLee_Lazy_glProgramUniform4ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix2fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix2fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix2fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix2fvEXT=GLee_Lazy_glProgramUniformMatrix2fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix3fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix3fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix3fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix3fvEXT=GLee_Lazy_glProgramUniformMatrix3fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix4fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix4fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix4fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix4fvEXT=GLee_Lazy_glProgramUniformMatrix4fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix2x3fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix2x3fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix2x3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix2x3fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix2x3fvEXT=GLee_Lazy_glProgramUniformMatrix2x3fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix3x2fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix3x2fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix3x2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix3x2fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix3x2fvEXT=GLee_Lazy_glProgramUniformMatrix3x2fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix2x4fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix2x4fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix2x4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix2x4fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix2x4fvEXT=GLee_Lazy_glProgramUniformMatrix2x4fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix4x2fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix4x2fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix4x2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix4x2fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix4x2fvEXT=GLee_Lazy_glProgramUniformMatrix4x2fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix3x4fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix3x4fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix3x4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix3x4fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix3x4fvEXT=GLee_Lazy_glProgramUniformMatrix3x4fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformMatrix4x3fvEXT +#define GLEE_C_DEFINED_glProgramUniformMatrix4x3fvEXT + void __stdcall GLee_Lazy_glProgramUniformMatrix4x3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {if (GLeeInit()) glProgramUniformMatrix4x3fvEXT(program, location, count, transpose, value);} + GLEEPFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix4x3fvEXT=GLee_Lazy_glProgramUniformMatrix4x3fvEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform1uiEXT +#define GLEE_C_DEFINED_glProgramUniform1uiEXT + void __stdcall GLee_Lazy_glProgramUniform1uiEXT(GLuint program, GLint location, GLuint v0) {if (GLeeInit()) glProgramUniform1uiEXT(program, location, v0);} + GLEEPFNGLPROGRAMUNIFORM1UIEXTPROC GLeeFuncPtr_glProgramUniform1uiEXT=GLee_Lazy_glProgramUniform1uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform2uiEXT +#define GLEE_C_DEFINED_glProgramUniform2uiEXT + void __stdcall GLee_Lazy_glProgramUniform2uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1) {if (GLeeInit()) glProgramUniform2uiEXT(program, location, v0, v1);} + GLEEPFNGLPROGRAMUNIFORM2UIEXTPROC GLeeFuncPtr_glProgramUniform2uiEXT=GLee_Lazy_glProgramUniform2uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform3uiEXT +#define GLEE_C_DEFINED_glProgramUniform3uiEXT + void __stdcall GLee_Lazy_glProgramUniform3uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) {if (GLeeInit()) glProgramUniform3uiEXT(program, location, v0, v1, v2);} + GLEEPFNGLPROGRAMUNIFORM3UIEXTPROC GLeeFuncPtr_glProgramUniform3uiEXT=GLee_Lazy_glProgramUniform3uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform4uiEXT +#define GLEE_C_DEFINED_glProgramUniform4uiEXT + void __stdcall GLee_Lazy_glProgramUniform4uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {if (GLeeInit()) glProgramUniform4uiEXT(program, location, v0, v1, v2, v3);} + GLEEPFNGLPROGRAMUNIFORM4UIEXTPROC GLeeFuncPtr_glProgramUniform4uiEXT=GLee_Lazy_glProgramUniform4uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform1uivEXT +#define GLEE_C_DEFINED_glProgramUniform1uivEXT + void __stdcall GLee_Lazy_glProgramUniform1uivEXT(GLuint program, GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glProgramUniform1uivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM1UIVEXTPROC GLeeFuncPtr_glProgramUniform1uivEXT=GLee_Lazy_glProgramUniform1uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform2uivEXT +#define GLEE_C_DEFINED_glProgramUniform2uivEXT + void __stdcall GLee_Lazy_glProgramUniform2uivEXT(GLuint program, GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glProgramUniform2uivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM2UIVEXTPROC GLeeFuncPtr_glProgramUniform2uivEXT=GLee_Lazy_glProgramUniform2uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform3uivEXT +#define GLEE_C_DEFINED_glProgramUniform3uivEXT + void __stdcall GLee_Lazy_glProgramUniform3uivEXT(GLuint program, GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glProgramUniform3uivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM3UIVEXTPROC GLeeFuncPtr_glProgramUniform3uivEXT=GLee_Lazy_glProgramUniform3uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniform4uivEXT +#define GLEE_C_DEFINED_glProgramUniform4uivEXT + void __stdcall GLee_Lazy_glProgramUniform4uivEXT(GLuint program, GLint location, GLsizei count, const GLuint * value) {if (GLeeInit()) glProgramUniform4uivEXT(program, location, count, value);} + GLEEPFNGLPROGRAMUNIFORM4UIVEXTPROC GLeeFuncPtr_glProgramUniform4uivEXT=GLee_Lazy_glProgramUniform4uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedBufferDataEXT +#define GLEE_C_DEFINED_glNamedBufferDataEXT + void __stdcall GLee_Lazy_glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const GLvoid * data, GLenum usage) {if (GLeeInit()) glNamedBufferDataEXT(buffer, size, data, usage);} + GLEEPFNGLNAMEDBUFFERDATAEXTPROC GLeeFuncPtr_glNamedBufferDataEXT=GLee_Lazy_glNamedBufferDataEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedBufferSubDataEXT +#define GLEE_C_DEFINED_glNamedBufferSubDataEXT + void __stdcall GLee_Lazy_glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid * data) {if (GLeeInit()) glNamedBufferSubDataEXT(buffer, offset, size, data);} + GLEEPFNGLNAMEDBUFFERSUBDATAEXTPROC GLeeFuncPtr_glNamedBufferSubDataEXT=GLee_Lazy_glNamedBufferSubDataEXT; +#endif +#ifndef GLEE_C_DEFINED_glMapNamedBufferEXT +#define GLEE_C_DEFINED_glMapNamedBufferEXT + GLvoid* __stdcall GLee_Lazy_glMapNamedBufferEXT(GLuint buffer, GLenum access) {if (GLeeInit()) return glMapNamedBufferEXT(buffer, access); return (GLvoid*)0;} + GLEEPFNGLMAPNAMEDBUFFEREXTPROC GLeeFuncPtr_glMapNamedBufferEXT=GLee_Lazy_glMapNamedBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glUnmapNamedBufferEXT +#define GLEE_C_DEFINED_glUnmapNamedBufferEXT + GLboolean __stdcall GLee_Lazy_glUnmapNamedBufferEXT(GLuint buffer) {if (GLeeInit()) return glUnmapNamedBufferEXT(buffer); return (GLboolean)0;} + GLEEPFNGLUNMAPNAMEDBUFFEREXTPROC GLeeFuncPtr_glUnmapNamedBufferEXT=GLee_Lazy_glUnmapNamedBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedBufferParameterivEXT +#define GLEE_C_DEFINED_glGetNamedBufferParameterivEXT + void __stdcall GLee_Lazy_glGetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint * params) {if (GLeeInit()) glGetNamedBufferParameterivEXT(buffer, pname, params);} + GLEEPFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedBufferParameterivEXT=GLee_Lazy_glGetNamedBufferParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedBufferPointervEXT +#define GLEE_C_DEFINED_glGetNamedBufferPointervEXT + void __stdcall GLee_Lazy_glGetNamedBufferPointervEXT(GLuint buffer, GLenum pname, GLvoid* * params) {if (GLeeInit()) glGetNamedBufferPointervEXT(buffer, pname, params);} + GLEEPFNGLGETNAMEDBUFFERPOINTERVEXTPROC GLeeFuncPtr_glGetNamedBufferPointervEXT=GLee_Lazy_glGetNamedBufferPointervEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedBufferSubDataEXT +#define GLEE_C_DEFINED_glGetNamedBufferSubDataEXT + void __stdcall GLee_Lazy_glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid * data) {if (GLeeInit()) glGetNamedBufferSubDataEXT(buffer, offset, size, data);} + GLEEPFNGLGETNAMEDBUFFERSUBDATAEXTPROC GLeeFuncPtr_glGetNamedBufferSubDataEXT=GLee_Lazy_glGetNamedBufferSubDataEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureBufferEXT +#define GLEE_C_DEFINED_glTextureBufferEXT + void __stdcall GLee_Lazy_glTextureBufferEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer) {if (GLeeInit()) glTextureBufferEXT(texture, target, internalformat, buffer);} + GLEEPFNGLTEXTUREBUFFEREXTPROC GLeeFuncPtr_glTextureBufferEXT=GLee_Lazy_glTextureBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexBufferEXT +#define GLEE_C_DEFINED_glMultiTexBufferEXT + void __stdcall GLee_Lazy_glMultiTexBufferEXT(GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer) {if (GLeeInit()) glMultiTexBufferEXT(texunit, target, internalformat, buffer);} + GLEEPFNGLMULTITEXBUFFEREXTPROC GLeeFuncPtr_glMultiTexBufferEXT=GLee_Lazy_glMultiTexBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedRenderbufferStorageEXT +#define GLEE_C_DEFINED_glNamedRenderbufferStorageEXT + void __stdcall GLee_Lazy_glNamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glNamedRenderbufferStorageEXT(renderbuffer, internalformat, width, height);} + GLEEPFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC GLeeFuncPtr_glNamedRenderbufferStorageEXT=GLee_Lazy_glNamedRenderbufferStorageEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedRenderbufferParameterivEXT +#define GLEE_C_DEFINED_glGetNamedRenderbufferParameterivEXT + void __stdcall GLee_Lazy_glGetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, GLint * params) {if (GLeeInit()) glGetNamedRenderbufferParameterivEXT(renderbuffer, pname, params);} + GLEEPFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedRenderbufferParameterivEXT=GLee_Lazy_glGetNamedRenderbufferParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glCheckNamedFramebufferStatusEXT +#define GLEE_C_DEFINED_glCheckNamedFramebufferStatusEXT + GLenum __stdcall GLee_Lazy_glCheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target) {if (GLeeInit()) return glCheckNamedFramebufferStatusEXT(framebuffer, target); return (GLenum)0;} + GLEEPFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC GLeeFuncPtr_glCheckNamedFramebufferStatusEXT=GLee_Lazy_glCheckNamedFramebufferStatusEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferTexture1DEXT +#define GLEE_C_DEFINED_glNamedFramebufferTexture1DEXT + void __stdcall GLee_Lazy_glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {if (GLeeInit()) glNamedFramebufferTexture1DEXT(framebuffer, attachment, textarget, texture, level);} + GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC GLeeFuncPtr_glNamedFramebufferTexture1DEXT=GLee_Lazy_glNamedFramebufferTexture1DEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferTexture2DEXT +#define GLEE_C_DEFINED_glNamedFramebufferTexture2DEXT + void __stdcall GLee_Lazy_glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {if (GLeeInit()) glNamedFramebufferTexture2DEXT(framebuffer, attachment, textarget, texture, level);} + GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC GLeeFuncPtr_glNamedFramebufferTexture2DEXT=GLee_Lazy_glNamedFramebufferTexture2DEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferTexture3DEXT +#define GLEE_C_DEFINED_glNamedFramebufferTexture3DEXT + void __stdcall GLee_Lazy_glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {if (GLeeInit()) glNamedFramebufferTexture3DEXT(framebuffer, attachment, textarget, texture, level, zoffset);} + GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC GLeeFuncPtr_glNamedFramebufferTexture3DEXT=GLee_Lazy_glNamedFramebufferTexture3DEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferRenderbufferEXT +#define GLEE_C_DEFINED_glNamedFramebufferRenderbufferEXT + void __stdcall GLee_Lazy_glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {if (GLeeInit()) glNamedFramebufferRenderbufferEXT(framebuffer, attachment, renderbuffertarget, renderbuffer);} + GLEEPFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC GLeeFuncPtr_glNamedFramebufferRenderbufferEXT=GLee_Lazy_glNamedFramebufferRenderbufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedFramebufferAttachmentParameterivEXT +#define GLEE_C_DEFINED_glGetNamedFramebufferAttachmentParameterivEXT + void __stdcall GLee_Lazy_glGetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params) {if (GLeeInit()) glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachment, pname, params);} + GLEEPFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedFramebufferAttachmentParameterivEXT=GLee_Lazy_glGetNamedFramebufferAttachmentParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenerateTextureMipmapEXT +#define GLEE_C_DEFINED_glGenerateTextureMipmapEXT + void __stdcall GLee_Lazy_glGenerateTextureMipmapEXT(GLuint texture, GLenum target) {if (GLeeInit()) glGenerateTextureMipmapEXT(texture, target);} + GLEEPFNGLGENERATETEXTUREMIPMAPEXTPROC GLeeFuncPtr_glGenerateTextureMipmapEXT=GLee_Lazy_glGenerateTextureMipmapEXT; +#endif +#ifndef GLEE_C_DEFINED_glGenerateMultiTexMipmapEXT +#define GLEE_C_DEFINED_glGenerateMultiTexMipmapEXT + void __stdcall GLee_Lazy_glGenerateMultiTexMipmapEXT(GLenum texunit, GLenum target) {if (GLeeInit()) glGenerateMultiTexMipmapEXT(texunit, target);} + GLEEPFNGLGENERATEMULTITEXMIPMAPEXTPROC GLeeFuncPtr_glGenerateMultiTexMipmapEXT=GLee_Lazy_glGenerateMultiTexMipmapEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferDrawBufferEXT +#define GLEE_C_DEFINED_glFramebufferDrawBufferEXT + void __stdcall GLee_Lazy_glFramebufferDrawBufferEXT(GLuint framebuffer, GLenum mode) {if (GLeeInit()) glFramebufferDrawBufferEXT(framebuffer, mode);} + GLEEPFNGLFRAMEBUFFERDRAWBUFFEREXTPROC GLeeFuncPtr_glFramebufferDrawBufferEXT=GLee_Lazy_glFramebufferDrawBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferDrawBuffersEXT +#define GLEE_C_DEFINED_glFramebufferDrawBuffersEXT + void __stdcall GLee_Lazy_glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, const GLenum * bufs) {if (GLeeInit()) glFramebufferDrawBuffersEXT(framebuffer, n, bufs);} + GLEEPFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC GLeeFuncPtr_glFramebufferDrawBuffersEXT=GLee_Lazy_glFramebufferDrawBuffersEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferReadBufferEXT +#define GLEE_C_DEFINED_glFramebufferReadBufferEXT + void __stdcall GLee_Lazy_glFramebufferReadBufferEXT(GLuint framebuffer, GLenum mode) {if (GLeeInit()) glFramebufferReadBufferEXT(framebuffer, mode);} + GLEEPFNGLFRAMEBUFFERREADBUFFEREXTPROC GLeeFuncPtr_glFramebufferReadBufferEXT=GLee_Lazy_glFramebufferReadBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFramebufferParameterivEXT +#define GLEE_C_DEFINED_glGetFramebufferParameterivEXT + void __stdcall GLee_Lazy_glGetFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, GLint * params) {if (GLeeInit()) glGetFramebufferParameterivEXT(framebuffer, pname, params);} + GLEEPFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetFramebufferParameterivEXT=GLee_Lazy_glGetFramebufferParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedRenderbufferStorageMultisampleEXT +#define GLEE_C_DEFINED_glNamedRenderbufferStorageMultisampleEXT + void __stdcall GLee_Lazy_glNamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glNamedRenderbufferStorageMultisampleEXT(renderbuffer, samples, internalformat, width, height);} + GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC GLeeFuncPtr_glNamedRenderbufferStorageMultisampleEXT=GLee_Lazy_glNamedRenderbufferStorageMultisampleEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedRenderbufferStorageMultisampleCoverageEXT +#define GLEE_C_DEFINED_glNamedRenderbufferStorageMultisampleCoverageEXT + void __stdcall GLee_Lazy_glNamedRenderbufferStorageMultisampleCoverageEXT(GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height) {if (GLeeInit()) glNamedRenderbufferStorageMultisampleCoverageEXT(renderbuffer, coverageSamples, colorSamples, internalformat, width, height);} + GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC GLeeFuncPtr_glNamedRenderbufferStorageMultisampleCoverageEXT=GLee_Lazy_glNamedRenderbufferStorageMultisampleCoverageEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferTextureEXT +#define GLEE_C_DEFINED_glNamedFramebufferTextureEXT + void __stdcall GLee_Lazy_glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level) {if (GLeeInit()) glNamedFramebufferTextureEXT(framebuffer, attachment, texture, level);} + GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC GLeeFuncPtr_glNamedFramebufferTextureEXT=GLee_Lazy_glNamedFramebufferTextureEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferTextureLayerEXT +#define GLEE_C_DEFINED_glNamedFramebufferTextureLayerEXT + void __stdcall GLee_Lazy_glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer) {if (GLeeInit()) glNamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer);} + GLEEPFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC GLeeFuncPtr_glNamedFramebufferTextureLayerEXT=GLee_Lazy_glNamedFramebufferTextureLayerEXT; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferTextureFaceEXT +#define GLEE_C_DEFINED_glNamedFramebufferTextureFaceEXT + void __stdcall GLee_Lazy_glNamedFramebufferTextureFaceEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face) {if (GLeeInit()) glNamedFramebufferTextureFaceEXT(framebuffer, attachment, texture, level, face);} + GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC GLeeFuncPtr_glNamedFramebufferTextureFaceEXT=GLee_Lazy_glNamedFramebufferTextureFaceEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureRenderbufferEXT +#define GLEE_C_DEFINED_glTextureRenderbufferEXT + void __stdcall GLee_Lazy_glTextureRenderbufferEXT(GLuint texture, GLenum target, GLuint renderbuffer) {if (GLeeInit()) glTextureRenderbufferEXT(texture, target, renderbuffer);} + GLEEPFNGLTEXTURERENDERBUFFEREXTPROC GLeeFuncPtr_glTextureRenderbufferEXT=GLee_Lazy_glTextureRenderbufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexRenderbufferEXT +#define GLEE_C_DEFINED_glMultiTexRenderbufferEXT + void __stdcall GLee_Lazy_glMultiTexRenderbufferEXT(GLenum texunit, GLenum target, GLuint renderbuffer) {if (GLeeInit()) glMultiTexRenderbufferEXT(texunit, target, renderbuffer);} + GLEEPFNGLMULTITEXRENDERBUFFEREXTPROC GLeeFuncPtr_glMultiTexRenderbufferEXT=GLee_Lazy_glMultiTexRenderbufferEXT; +#endif +#endif + +/* GL_EXT_vertex_array_bgra */ + +#ifdef __GLEE_GL_EXT_vertex_array_bgra +#endif + +/* GL_EXT_texture_swizzle */ + +#ifdef __GLEE_GL_EXT_texture_swizzle +#endif + +/* GL_NV_explicit_multisample */ + +#ifdef __GLEE_GL_NV_explicit_multisample +#ifndef GLEE_C_DEFINED_glGetMultisamplefvNV +#define GLEE_C_DEFINED_glGetMultisamplefvNV + void __stdcall GLee_Lazy_glGetMultisamplefvNV(GLenum pname, GLuint index, GLfloat * val) {if (GLeeInit()) glGetMultisamplefvNV(pname, index, val);} + GLEEPFNGLGETMULTISAMPLEFVNVPROC GLeeFuncPtr_glGetMultisamplefvNV=GLee_Lazy_glGetMultisamplefvNV; +#endif +#ifndef GLEE_C_DEFINED_glSampleMaskIndexedNV +#define GLEE_C_DEFINED_glSampleMaskIndexedNV + void __stdcall GLee_Lazy_glSampleMaskIndexedNV(GLuint index, GLbitfield mask) {if (GLeeInit()) glSampleMaskIndexedNV(index, mask);} + GLEEPFNGLSAMPLEMASKINDEXEDNVPROC GLeeFuncPtr_glSampleMaskIndexedNV=GLee_Lazy_glSampleMaskIndexedNV; +#endif +#ifndef GLEE_C_DEFINED_glTexRenderbufferNV +#define GLEE_C_DEFINED_glTexRenderbufferNV + void __stdcall GLee_Lazy_glTexRenderbufferNV(GLenum target, GLuint renderbuffer) {if (GLeeInit()) glTexRenderbufferNV(target, renderbuffer);} + GLEEPFNGLTEXRENDERBUFFERNVPROC GLeeFuncPtr_glTexRenderbufferNV=GLee_Lazy_glTexRenderbufferNV; +#endif +#endif + +/* GL_NV_transform_feedback2 */ + +#ifdef __GLEE_GL_NV_transform_feedback2 +#ifndef GLEE_C_DEFINED_glBindTransformFeedbackNV +#define GLEE_C_DEFINED_glBindTransformFeedbackNV + void __stdcall GLee_Lazy_glBindTransformFeedbackNV(GLenum target, GLuint id) {if (GLeeInit()) glBindTransformFeedbackNV(target, id);} + GLEEPFNGLBINDTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glBindTransformFeedbackNV=GLee_Lazy_glBindTransformFeedbackNV; +#endif +#ifndef GLEE_C_DEFINED_glDeleteTransformFeedbacksNV +#define GLEE_C_DEFINED_glDeleteTransformFeedbacksNV + void __stdcall GLee_Lazy_glDeleteTransformFeedbacksNV(GLsizei n, const GLuint * ids) {if (GLeeInit()) glDeleteTransformFeedbacksNV(n, ids);} + GLEEPFNGLDELETETRANSFORMFEEDBACKSNVPROC GLeeFuncPtr_glDeleteTransformFeedbacksNV=GLee_Lazy_glDeleteTransformFeedbacksNV; +#endif +#ifndef GLEE_C_DEFINED_glGenTransformFeedbacksNV +#define GLEE_C_DEFINED_glGenTransformFeedbacksNV + void __stdcall GLee_Lazy_glGenTransformFeedbacksNV(GLsizei n, GLuint * ids) {if (GLeeInit()) glGenTransformFeedbacksNV(n, ids);} + GLEEPFNGLGENTRANSFORMFEEDBACKSNVPROC GLeeFuncPtr_glGenTransformFeedbacksNV=GLee_Lazy_glGenTransformFeedbacksNV; +#endif +#ifndef GLEE_C_DEFINED_glIsTransformFeedbackNV +#define GLEE_C_DEFINED_glIsTransformFeedbackNV + GLboolean __stdcall GLee_Lazy_glIsTransformFeedbackNV(GLuint id) {if (GLeeInit()) return glIsTransformFeedbackNV(id); return (GLboolean)0;} + GLEEPFNGLISTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glIsTransformFeedbackNV=GLee_Lazy_glIsTransformFeedbackNV; +#endif +#ifndef GLEE_C_DEFINED_glPauseTransformFeedbackNV +#define GLEE_C_DEFINED_glPauseTransformFeedbackNV + void __stdcall GLee_Lazy_glPauseTransformFeedbackNV(void) {if (GLeeInit()) glPauseTransformFeedbackNV();} + GLEEPFNGLPAUSETRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glPauseTransformFeedbackNV=GLee_Lazy_glPauseTransformFeedbackNV; +#endif +#ifndef GLEE_C_DEFINED_glResumeTransformFeedbackNV +#define GLEE_C_DEFINED_glResumeTransformFeedbackNV + void __stdcall GLee_Lazy_glResumeTransformFeedbackNV(void) {if (GLeeInit()) glResumeTransformFeedbackNV();} + GLEEPFNGLRESUMETRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glResumeTransformFeedbackNV=GLee_Lazy_glResumeTransformFeedbackNV; +#endif +#ifndef GLEE_C_DEFINED_glDrawTransformFeedbackNV +#define GLEE_C_DEFINED_glDrawTransformFeedbackNV + void __stdcall GLee_Lazy_glDrawTransformFeedbackNV(GLenum mode, GLuint id) {if (GLeeInit()) glDrawTransformFeedbackNV(mode, id);} + GLEEPFNGLDRAWTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glDrawTransformFeedbackNV=GLee_Lazy_glDrawTransformFeedbackNV; +#endif +#endif + +/* GL_SGIX_texture_select */ + +#ifdef __GLEE_GL_SGIX_texture_select +#endif + +/* GL_INGR_blend_func_separate */ + +#ifdef __GLEE_GL_INGR_blend_func_separate +#ifndef GLEE_C_DEFINED_glBlendFuncSeparateINGR +#define GLEE_C_DEFINED_glBlendFuncSeparateINGR + void __stdcall GLee_Lazy_glBlendFuncSeparateINGR(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {if (GLeeInit()) glBlendFuncSeparateINGR(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);} + GLEEPFNGLBLENDFUNCSEPARATEINGRPROC GLeeFuncPtr_glBlendFuncSeparateINGR=GLee_Lazy_glBlendFuncSeparateINGR; +#endif +#endif + +/* GL_SGIX_depth_pass_instrument */ + +#ifdef __GLEE_GL_SGIX_depth_pass_instrument +#endif + +/* GL_SGIX_igloo_interface */ + +#ifdef __GLEE_GL_SGIX_igloo_interface +#ifndef GLEE_C_DEFINED_glIglooInterfaceSGIX +#define GLEE_C_DEFINED_glIglooInterfaceSGIX + void __stdcall GLee_Lazy_glIglooInterfaceSGIX(GLenum pname, const GLvoid * params) {if (GLeeInit()) glIglooInterfaceSGIX(pname, params);} + GLEEPFNGLIGLOOINTERFACESGIXPROC GLeeFuncPtr_glIglooInterfaceSGIX=GLee_Lazy_glIglooInterfaceSGIX; +#endif +#endif + +/* GL_EXT_fragment_lighting */ + +#ifdef __GLEE_GL_EXT_fragment_lighting +#ifndef GLEE_C_DEFINED_glFragmentLightModeliEXT +#define GLEE_C_DEFINED_glFragmentLightModeliEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightModeliEXT(GLenum pname, GLint param) {if (GLeeInit()) glFragmentLightModeliEXT(pname, param);} + GLEEPFNGLFRAGMENTLIGHTMODELIEXTPROC GLeeFuncPtr_glFragmentLightModeliEXT=GLee_Lazy_glFragmentLightModeliEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightModelfEXT +#define GLEE_C_DEFINED_glFragmentLightModelfEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightModelfEXT(GLenum pname, GLfloat param) {if (GLeeInit()) glFragmentLightModelfEXT(pname, param);} + GLEEPFNGLFRAGMENTLIGHTMODELFEXTPROC GLeeFuncPtr_glFragmentLightModelfEXT=GLee_Lazy_glFragmentLightModelfEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightModelivEXT +#define GLEE_C_DEFINED_glFragmentLightModelivEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightModelivEXT(GLenum pname, GLint * params) {if (GLeeInit()) glFragmentLightModelivEXT(pname, params);} + GLEEPFNGLFRAGMENTLIGHTMODELIVEXTPROC GLeeFuncPtr_glFragmentLightModelivEXT=GLee_Lazy_glFragmentLightModelivEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightModelfvEXT +#define GLEE_C_DEFINED_glFragmentLightModelfvEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightModelfvEXT(GLenum pname, GLfloat * params) {if (GLeeInit()) glFragmentLightModelfvEXT(pname, params);} + GLEEPFNGLFRAGMENTLIGHTMODELFVEXTPROC GLeeFuncPtr_glFragmentLightModelfvEXT=GLee_Lazy_glFragmentLightModelfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightiEXT +#define GLEE_C_DEFINED_glFragmentLightiEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightiEXT(GLenum light, GLenum pname, GLint param) {if (GLeeInit()) glFragmentLightiEXT(light, pname, param);} + GLEEPFNGLFRAGMENTLIGHTIEXTPROC GLeeFuncPtr_glFragmentLightiEXT=GLee_Lazy_glFragmentLightiEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightfEXT +#define GLEE_C_DEFINED_glFragmentLightfEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightfEXT(GLenum light, GLenum pname, GLfloat param) {if (GLeeInit()) glFragmentLightfEXT(light, pname, param);} + GLEEPFNGLFRAGMENTLIGHTFEXTPROC GLeeFuncPtr_glFragmentLightfEXT=GLee_Lazy_glFragmentLightfEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightivEXT +#define GLEE_C_DEFINED_glFragmentLightivEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightivEXT(GLenum light, GLenum pname, GLint * params) {if (GLeeInit()) glFragmentLightivEXT(light, pname, params);} + GLEEPFNGLFRAGMENTLIGHTIVEXTPROC GLeeFuncPtr_glFragmentLightivEXT=GLee_Lazy_glFragmentLightivEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentLightfvEXT +#define GLEE_C_DEFINED_glFragmentLightfvEXT + GLvoid __stdcall GLee_Lazy_glFragmentLightfvEXT(GLenum light, GLenum pname, GLfloat * params) {if (GLeeInit()) glFragmentLightfvEXT(light, pname, params);} + GLEEPFNGLFRAGMENTLIGHTFVEXTPROC GLeeFuncPtr_glFragmentLightfvEXT=GLee_Lazy_glFragmentLightfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentLightivEXT +#define GLEE_C_DEFINED_glGetFragmentLightivEXT + GLvoid __stdcall GLee_Lazy_glGetFragmentLightivEXT(GLenum light, GLenum pname, GLint * params) {if (GLeeInit()) glGetFragmentLightivEXT(light, pname, params);} + GLEEPFNGLGETFRAGMENTLIGHTIVEXTPROC GLeeFuncPtr_glGetFragmentLightivEXT=GLee_Lazy_glGetFragmentLightivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentLightfvEXT +#define GLEE_C_DEFINED_glGetFragmentLightfvEXT + GLvoid __stdcall GLee_Lazy_glGetFragmentLightfvEXT(GLenum light, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetFragmentLightfvEXT(light, pname, params);} + GLEEPFNGLGETFRAGMENTLIGHTFVEXTPROC GLeeFuncPtr_glGetFragmentLightfvEXT=GLee_Lazy_glGetFragmentLightfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialfEXT +#define GLEE_C_DEFINED_glFragmentMaterialfEXT + GLvoid __stdcall GLee_Lazy_glFragmentMaterialfEXT(GLenum face, GLenum pname, const GLfloat param) {if (GLeeInit()) glFragmentMaterialfEXT(face, pname, param);} + GLEEPFNGLFRAGMENTMATERIALFEXTPROC GLeeFuncPtr_glFragmentMaterialfEXT=GLee_Lazy_glFragmentMaterialfEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialiEXT +#define GLEE_C_DEFINED_glFragmentMaterialiEXT + GLvoid __stdcall GLee_Lazy_glFragmentMaterialiEXT(GLenum face, GLenum pname, const GLint param) {if (GLeeInit()) glFragmentMaterialiEXT(face, pname, param);} + GLEEPFNGLFRAGMENTMATERIALIEXTPROC GLeeFuncPtr_glFragmentMaterialiEXT=GLee_Lazy_glFragmentMaterialiEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialfvEXT +#define GLEE_C_DEFINED_glFragmentMaterialfvEXT + GLvoid __stdcall GLee_Lazy_glFragmentMaterialfvEXT(GLenum face, GLenum pname, const GLfloat * params) {if (GLeeInit()) glFragmentMaterialfvEXT(face, pname, params);} + GLEEPFNGLFRAGMENTMATERIALFVEXTPROC GLeeFuncPtr_glFragmentMaterialfvEXT=GLee_Lazy_glFragmentMaterialfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentMaterialivEXT +#define GLEE_C_DEFINED_glFragmentMaterialivEXT + GLvoid __stdcall GLee_Lazy_glFragmentMaterialivEXT(GLenum face, GLenum pname, const GLint * params) {if (GLeeInit()) glFragmentMaterialivEXT(face, pname, params);} + GLEEPFNGLFRAGMENTMATERIALIVEXTPROC GLeeFuncPtr_glFragmentMaterialivEXT=GLee_Lazy_glFragmentMaterialivEXT; +#endif +#ifndef GLEE_C_DEFINED_glFragmentColorMaterialEXT +#define GLEE_C_DEFINED_glFragmentColorMaterialEXT + GLvoid __stdcall GLee_Lazy_glFragmentColorMaterialEXT(GLenum face, GLenum mode) {if (GLeeInit()) glFragmentColorMaterialEXT(face, mode);} + GLEEPFNGLFRAGMENTCOLORMATERIALEXTPROC GLeeFuncPtr_glFragmentColorMaterialEXT=GLee_Lazy_glFragmentColorMaterialEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentMaterialfvEXT +#define GLEE_C_DEFINED_glGetFragmentMaterialfvEXT + GLvoid __stdcall GLee_Lazy_glGetFragmentMaterialfvEXT(GLenum face, GLenum pname, const GLfloat * params) {if (GLeeInit()) glGetFragmentMaterialfvEXT(face, pname, params);} + GLEEPFNGLGETFRAGMENTMATERIALFVEXTPROC GLeeFuncPtr_glGetFragmentMaterialfvEXT=GLee_Lazy_glGetFragmentMaterialfvEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetFragmentMaterialivEXT +#define GLEE_C_DEFINED_glGetFragmentMaterialivEXT + GLvoid __stdcall GLee_Lazy_glGetFragmentMaterialivEXT(GLenum face, GLenum pname, const GLint * params) {if (GLeeInit()) glGetFragmentMaterialivEXT(face, pname, params);} + GLEEPFNGLGETFRAGMENTMATERIALIVEXTPROC GLeeFuncPtr_glGetFragmentMaterialivEXT=GLee_Lazy_glGetFragmentMaterialivEXT; +#endif +#ifndef GLEE_C_DEFINED_glLightEnviEXT +#define GLEE_C_DEFINED_glLightEnviEXT + GLvoid __stdcall GLee_Lazy_glLightEnviEXT(GLenum pname, GLint param) {if (GLeeInit()) glLightEnviEXT(pname, param);} + GLEEPFNGLLIGHTENVIEXTPROC GLeeFuncPtr_glLightEnviEXT=GLee_Lazy_glLightEnviEXT; +#endif +#endif + +/* GL_EXT_geometry_shader4 */ + +#ifdef __GLEE_GL_EXT_geometry_shader4 +#ifndef GLEE_C_DEFINED_glProgramParameteriEXT +#define GLEE_C_DEFINED_glProgramParameteriEXT + GLvoid __stdcall GLee_Lazy_glProgramParameteriEXT(GLuint program, GLenum pname, GLint value) {if (GLeeInit()) glProgramParameteriEXT(program, pname, value);} + GLEEPFNGLPROGRAMPARAMETERIEXTPROC GLeeFuncPtr_glProgramParameteriEXT=GLee_Lazy_glProgramParameteriEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureEXT +#define GLEE_C_DEFINED_glFramebufferTextureEXT + GLvoid __stdcall GLee_Lazy_glFramebufferTextureEXT(GLenum target, GLenum attachment, GLuint texture, GLint level) {if (GLeeInit()) glFramebufferTextureEXT(target, attachment, texture, level);} + GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC GLeeFuncPtr_glFramebufferTextureEXT=GLee_Lazy_glFramebufferTextureEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureLayerEXT +#define GLEE_C_DEFINED_glFramebufferTextureLayerEXT + GLvoid __stdcall GLee_Lazy_glFramebufferTextureLayerEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {if (GLeeInit()) glFramebufferTextureLayerEXT(target, attachment, texture, level, layer);} + GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC GLeeFuncPtr_glFramebufferTextureLayerEXT=GLee_Lazy_glFramebufferTextureLayerEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureFaceEXT +#define GLEE_C_DEFINED_glFramebufferTextureFaceEXT + GLvoid __stdcall GLee_Lazy_glFramebufferTextureFaceEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face) {if (GLeeInit()) glFramebufferTextureFaceEXT(target, attachment, texture, level, face);} + GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC GLeeFuncPtr_glFramebufferTextureFaceEXT=GLee_Lazy_glFramebufferTextureFaceEXT; +#endif +#endif + +/* GL_EXT_scene_marker */ + +#ifdef __GLEE_GL_EXT_scene_marker +#ifndef GLEE_C_DEFINED_glBeginSceneEXT +#define GLEE_C_DEFINED_glBeginSceneEXT + GLvoid __stdcall GLee_Lazy_glBeginSceneEXT(void) {if (GLeeInit()) glBeginSceneEXT();} + GLEEPFNGLBEGINSCENEEXTPROC GLeeFuncPtr_glBeginSceneEXT=GLee_Lazy_glBeginSceneEXT; +#endif +#ifndef GLEE_C_DEFINED_glEndSceneEXT +#define GLEE_C_DEFINED_glEndSceneEXT + GLvoid __stdcall GLee_Lazy_glEndSceneEXT(void) {if (GLeeInit()) glEndSceneEXT();} + GLEEPFNGLENDSCENEEXTPROC GLeeFuncPtr_glEndSceneEXT=GLee_Lazy_glEndSceneEXT; +#endif +#endif + +/* GL_EXT_texture_compression_dxt1 */ + +#ifdef __GLEE_GL_EXT_texture_compression_dxt1 +#endif + +/* GL_EXT_texture_env */ + +#ifdef __GLEE_GL_EXT_texture_env +#endif + +/* GL_IBM_static_data */ + +#ifdef __GLEE_GL_IBM_static_data +#endif + +/* GL_NV_gpu_program4 */ + +#ifdef __GLEE_GL_NV_gpu_program4 +#ifndef GLEE_C_DEFINED_glProgramLocalParameterI4iNV +#define GLEE_C_DEFINED_glProgramLocalParameterI4iNV + GLvoid __stdcall GLee_Lazy_glProgramLocalParameterI4iNV(GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w) {if (GLeeInit()) glProgramLocalParameterI4iNV(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMLOCALPARAMETERI4INVPROC GLeeFuncPtr_glProgramLocalParameterI4iNV=GLee_Lazy_glProgramLocalParameterI4iNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameterI4ivNV +#define GLEE_C_DEFINED_glProgramLocalParameterI4ivNV + GLvoid __stdcall GLee_Lazy_glProgramLocalParameterI4ivNV(GLenum target, GLuint index, const GLint * params) {if (GLeeInit()) glProgramLocalParameterI4ivNV(target, index, params);} + GLEEPFNGLPROGRAMLOCALPARAMETERI4IVNVPROC GLeeFuncPtr_glProgramLocalParameterI4ivNV=GLee_Lazy_glProgramLocalParameterI4ivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParametersI4ivNV +#define GLEE_C_DEFINED_glProgramLocalParametersI4ivNV + GLvoid __stdcall GLee_Lazy_glProgramLocalParametersI4ivNV(GLenum target, GLuint index, GLsizei count, const GLint * params) {if (GLeeInit()) glProgramLocalParametersI4ivNV(target, index, count, params);} + GLEEPFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC GLeeFuncPtr_glProgramLocalParametersI4ivNV=GLee_Lazy_glProgramLocalParametersI4ivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameterI4uiNV +#define GLEE_C_DEFINED_glProgramLocalParameterI4uiNV + GLvoid __stdcall GLee_Lazy_glProgramLocalParameterI4uiNV(GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {if (GLeeInit()) glProgramLocalParameterI4uiNV(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMLOCALPARAMETERI4UINVPROC GLeeFuncPtr_glProgramLocalParameterI4uiNV=GLee_Lazy_glProgramLocalParameterI4uiNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParameterI4uivNV +#define GLEE_C_DEFINED_glProgramLocalParameterI4uivNV + GLvoid __stdcall GLee_Lazy_glProgramLocalParameterI4uivNV(GLenum target, GLuint index, const GLuint * params) {if (GLeeInit()) glProgramLocalParameterI4uivNV(target, index, params);} + GLEEPFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC GLeeFuncPtr_glProgramLocalParameterI4uivNV=GLee_Lazy_glProgramLocalParameterI4uivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramLocalParametersI4uivNV +#define GLEE_C_DEFINED_glProgramLocalParametersI4uivNV + GLvoid __stdcall GLee_Lazy_glProgramLocalParametersI4uivNV(GLenum target, GLuint index, GLsizei count, const GLuint * params) {if (GLeeInit()) glProgramLocalParametersI4uivNV(target, index, count, params);} + GLEEPFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC GLeeFuncPtr_glProgramLocalParametersI4uivNV=GLee_Lazy_glProgramLocalParametersI4uivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameterI4iNV +#define GLEE_C_DEFINED_glProgramEnvParameterI4iNV + GLvoid __stdcall GLee_Lazy_glProgramEnvParameterI4iNV(GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w) {if (GLeeInit()) glProgramEnvParameterI4iNV(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMENVPARAMETERI4INVPROC GLeeFuncPtr_glProgramEnvParameterI4iNV=GLee_Lazy_glProgramEnvParameterI4iNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameterI4ivNV +#define GLEE_C_DEFINED_glProgramEnvParameterI4ivNV + GLvoid __stdcall GLee_Lazy_glProgramEnvParameterI4ivNV(GLenum target, GLuint index, const GLint * params) {if (GLeeInit()) glProgramEnvParameterI4ivNV(target, index, params);} + GLEEPFNGLPROGRAMENVPARAMETERI4IVNVPROC GLeeFuncPtr_glProgramEnvParameterI4ivNV=GLee_Lazy_glProgramEnvParameterI4ivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParametersI4ivNV +#define GLEE_C_DEFINED_glProgramEnvParametersI4ivNV + GLvoid __stdcall GLee_Lazy_glProgramEnvParametersI4ivNV(GLenum target, GLuint index, GLsizei count, const GLint * params) {if (GLeeInit()) glProgramEnvParametersI4ivNV(target, index, count, params);} + GLEEPFNGLPROGRAMENVPARAMETERSI4IVNVPROC GLeeFuncPtr_glProgramEnvParametersI4ivNV=GLee_Lazy_glProgramEnvParametersI4ivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameterI4uiNV +#define GLEE_C_DEFINED_glProgramEnvParameterI4uiNV + GLvoid __stdcall GLee_Lazy_glProgramEnvParameterI4uiNV(GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {if (GLeeInit()) glProgramEnvParameterI4uiNV(target, index, x, y, z, w);} + GLEEPFNGLPROGRAMENVPARAMETERI4UINVPROC GLeeFuncPtr_glProgramEnvParameterI4uiNV=GLee_Lazy_glProgramEnvParameterI4uiNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParameterI4uivNV +#define GLEE_C_DEFINED_glProgramEnvParameterI4uivNV + GLvoid __stdcall GLee_Lazy_glProgramEnvParameterI4uivNV(GLenum target, GLuint index, const GLuint * params) {if (GLeeInit()) glProgramEnvParameterI4uivNV(target, index, params);} + GLEEPFNGLPROGRAMENVPARAMETERI4UIVNVPROC GLeeFuncPtr_glProgramEnvParameterI4uivNV=GLee_Lazy_glProgramEnvParameterI4uivNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramEnvParametersI4uivNV +#define GLEE_C_DEFINED_glProgramEnvParametersI4uivNV + GLvoid __stdcall GLee_Lazy_glProgramEnvParametersI4uivNV(GLenum target, GLuint index, GLsizei count, const GLuint * params) {if (GLeeInit()) glProgramEnvParametersI4uivNV(target, index, count, params);} + GLEEPFNGLPROGRAMENVPARAMETERSI4UIVNVPROC GLeeFuncPtr_glProgramEnvParametersI4uivNV=GLee_Lazy_glProgramEnvParametersI4uivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramLocalParameterIivNV +#define GLEE_C_DEFINED_glGetProgramLocalParameterIivNV + GLvoid __stdcall GLee_Lazy_glGetProgramLocalParameterIivNV(GLenum target, GLuint index, GLint * params) {if (GLeeInit()) glGetProgramLocalParameterIivNV(target, index, params);} + GLEEPFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC GLeeFuncPtr_glGetProgramLocalParameterIivNV=GLee_Lazy_glGetProgramLocalParameterIivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramLocalParameterIuivNV +#define GLEE_C_DEFINED_glGetProgramLocalParameterIuivNV + GLvoid __stdcall GLee_Lazy_glGetProgramLocalParameterIuivNV(GLenum target, GLuint index, GLuint * params) {if (GLeeInit()) glGetProgramLocalParameterIuivNV(target, index, params);} + GLEEPFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC GLeeFuncPtr_glGetProgramLocalParameterIuivNV=GLee_Lazy_glGetProgramLocalParameterIuivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramEnvParameterIivNV +#define GLEE_C_DEFINED_glGetProgramEnvParameterIivNV + GLvoid __stdcall GLee_Lazy_glGetProgramEnvParameterIivNV(GLenum target, GLuint index, GLint * params) {if (GLeeInit()) glGetProgramEnvParameterIivNV(target, index, params);} + GLEEPFNGLGETPROGRAMENVPARAMETERIIVNVPROC GLeeFuncPtr_glGetProgramEnvParameterIivNV=GLee_Lazy_glGetProgramEnvParameterIivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramEnvParameterIuivNV +#define GLEE_C_DEFINED_glGetProgramEnvParameterIuivNV + GLvoid __stdcall GLee_Lazy_glGetProgramEnvParameterIuivNV(GLenum target, GLuint index, GLuint * params) {if (GLeeInit()) glGetProgramEnvParameterIuivNV(target, index, params);} + GLEEPFNGLGETPROGRAMENVPARAMETERIUIVNVPROC GLeeFuncPtr_glGetProgramEnvParameterIuivNV=GLee_Lazy_glGetProgramEnvParameterIuivNV; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureEXT +#define GLEE_C_DEFINED_glFramebufferTextureEXT + GLvoid __stdcall GLee_Lazy_glFramebufferTextureEXT(GLenum target, GLenum attachment, GLuint texture, GLint level) {if (GLeeInit()) glFramebufferTextureEXT(target, attachment, texture, level);} + GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC GLeeFuncPtr_glFramebufferTextureEXT=GLee_Lazy_glFramebufferTextureEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureLayerEXT +#define GLEE_C_DEFINED_glFramebufferTextureLayerEXT + GLvoid __stdcall GLee_Lazy_glFramebufferTextureLayerEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {if (GLeeInit()) glFramebufferTextureLayerEXT(target, attachment, texture, level, layer);} + GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC GLeeFuncPtr_glFramebufferTextureLayerEXT=GLee_Lazy_glFramebufferTextureLayerEXT; +#endif +#ifndef GLEE_C_DEFINED_glFramebufferTextureFaceEXT +#define GLEE_C_DEFINED_glFramebufferTextureFaceEXT + GLvoid __stdcall GLee_Lazy_glFramebufferTextureFaceEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face) {if (GLeeInit()) glFramebufferTextureFaceEXT(target, attachment, texture, level, face);} + GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC GLeeFuncPtr_glFramebufferTextureFaceEXT=GLee_Lazy_glFramebufferTextureFaceEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2iEXT +#define GLEE_C_DEFINED_glVertexAttribI2iEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI2iEXT(GLuint index, GLint x, GLint y) {if (GLeeInit()) glVertexAttribI2iEXT(index, x, y);} + GLEEPFNGLVERTEXATTRIBI2IEXTPROC GLeeFuncPtr_glVertexAttribI2iEXT=GLee_Lazy_glVertexAttribI2iEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3iEXT +#define GLEE_C_DEFINED_glVertexAttribI3iEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI3iEXT(GLuint index, GLint x, GLint y, GLint z) {if (GLeeInit()) glVertexAttribI3iEXT(index, x, y, z);} + GLEEPFNGLVERTEXATTRIBI3IEXTPROC GLeeFuncPtr_glVertexAttribI3iEXT=GLee_Lazy_glVertexAttribI3iEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4iEXT +#define GLEE_C_DEFINED_glVertexAttribI4iEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4iEXT(GLuint index, GLint x, GLint y, GLint z, GLint w) {if (GLeeInit()) glVertexAttribI4iEXT(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIBI4IEXTPROC GLeeFuncPtr_glVertexAttribI4iEXT=GLee_Lazy_glVertexAttribI4iEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI1uiEXT +#define GLEE_C_DEFINED_glVertexAttribI1uiEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI1uiEXT(GLuint index, GLuint x) {if (GLeeInit()) glVertexAttribI1uiEXT(index, x);} + GLEEPFNGLVERTEXATTRIBI1UIEXTPROC GLeeFuncPtr_glVertexAttribI1uiEXT=GLee_Lazy_glVertexAttribI1uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2uiEXT +#define GLEE_C_DEFINED_glVertexAttribI2uiEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI2uiEXT(GLuint index, GLuint x, GLuint y) {if (GLeeInit()) glVertexAttribI2uiEXT(index, x, y);} + GLEEPFNGLVERTEXATTRIBI2UIEXTPROC GLeeFuncPtr_glVertexAttribI2uiEXT=GLee_Lazy_glVertexAttribI2uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3uiEXT +#define GLEE_C_DEFINED_glVertexAttribI3uiEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI3uiEXT(GLuint index, GLuint x, GLuint y, GLuint z) {if (GLeeInit()) glVertexAttribI3uiEXT(index, x, y, z);} + GLEEPFNGLVERTEXATTRIBI3UIEXTPROC GLeeFuncPtr_glVertexAttribI3uiEXT=GLee_Lazy_glVertexAttribI3uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4uiEXT +#define GLEE_C_DEFINED_glVertexAttribI4uiEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4uiEXT(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {if (GLeeInit()) glVertexAttribI4uiEXT(index, x, y, z, w);} + GLEEPFNGLVERTEXATTRIBI4UIEXTPROC GLeeFuncPtr_glVertexAttribI4uiEXT=GLee_Lazy_glVertexAttribI4uiEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI1ivEXT +#define GLEE_C_DEFINED_glVertexAttribI1ivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI1ivEXT(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI1ivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI1IVEXTPROC GLeeFuncPtr_glVertexAttribI1ivEXT=GLee_Lazy_glVertexAttribI1ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2ivEXT +#define GLEE_C_DEFINED_glVertexAttribI2ivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI2ivEXT(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI2ivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI2IVEXTPROC GLeeFuncPtr_glVertexAttribI2ivEXT=GLee_Lazy_glVertexAttribI2ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3ivEXT +#define GLEE_C_DEFINED_glVertexAttribI3ivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI3ivEXT(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI3ivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI3IVEXTPROC GLeeFuncPtr_glVertexAttribI3ivEXT=GLee_Lazy_glVertexAttribI3ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4ivEXT +#define GLEE_C_DEFINED_glVertexAttribI4ivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4ivEXT(GLuint index, const GLint * v) {if (GLeeInit()) glVertexAttribI4ivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI4IVEXTPROC GLeeFuncPtr_glVertexAttribI4ivEXT=GLee_Lazy_glVertexAttribI4ivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI1uivEXT +#define GLEE_C_DEFINED_glVertexAttribI1uivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI1uivEXT(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI1uivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI1UIVEXTPROC GLeeFuncPtr_glVertexAttribI1uivEXT=GLee_Lazy_glVertexAttribI1uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI2uivEXT +#define GLEE_C_DEFINED_glVertexAttribI2uivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI2uivEXT(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI2uivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI2UIVEXTPROC GLeeFuncPtr_glVertexAttribI2uivEXT=GLee_Lazy_glVertexAttribI2uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI3uivEXT +#define GLEE_C_DEFINED_glVertexAttribI3uivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI3uivEXT(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI3uivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI3UIVEXTPROC GLeeFuncPtr_glVertexAttribI3uivEXT=GLee_Lazy_glVertexAttribI3uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4uivEXT +#define GLEE_C_DEFINED_glVertexAttribI4uivEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4uivEXT(GLuint index, const GLuint * v) {if (GLeeInit()) glVertexAttribI4uivEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI4UIVEXTPROC GLeeFuncPtr_glVertexAttribI4uivEXT=GLee_Lazy_glVertexAttribI4uivEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4bvEXT +#define GLEE_C_DEFINED_glVertexAttribI4bvEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4bvEXT(GLuint index, const GLbyte * v) {if (GLeeInit()) glVertexAttribI4bvEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI4BVEXTPROC GLeeFuncPtr_glVertexAttribI4bvEXT=GLee_Lazy_glVertexAttribI4bvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4svEXT +#define GLEE_C_DEFINED_glVertexAttribI4svEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4svEXT(GLuint index, const GLshort * v) {if (GLeeInit()) glVertexAttribI4svEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI4SVEXTPROC GLeeFuncPtr_glVertexAttribI4svEXT=GLee_Lazy_glVertexAttribI4svEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4ubvEXT +#define GLEE_C_DEFINED_glVertexAttribI4ubvEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4ubvEXT(GLuint index, const GLubyte * v) {if (GLeeInit()) glVertexAttribI4ubvEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI4UBVEXTPROC GLeeFuncPtr_glVertexAttribI4ubvEXT=GLee_Lazy_glVertexAttribI4ubvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribI4usvEXT +#define GLEE_C_DEFINED_glVertexAttribI4usvEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribI4usvEXT(GLuint index, const GLushort * v) {if (GLeeInit()) glVertexAttribI4usvEXT(index, v);} + GLEEPFNGLVERTEXATTRIBI4USVEXTPROC GLeeFuncPtr_glVertexAttribI4usvEXT=GLee_Lazy_glVertexAttribI4usvEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribIPointerEXT +#define GLEE_C_DEFINED_glVertexAttribIPointerEXT + GLvoid __stdcall GLee_Lazy_glVertexAttribIPointerEXT(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexAttribIPointerEXT(index, size, type, stride, pointer);} + GLEEPFNGLVERTEXATTRIBIPOINTEREXTPROC GLeeFuncPtr_glVertexAttribIPointerEXT=GLee_Lazy_glVertexAttribIPointerEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribIivEXT +#define GLEE_C_DEFINED_glGetVertexAttribIivEXT + GLvoid __stdcall GLee_Lazy_glGetVertexAttribIivEXT(GLuint index, GLenum pname, GLint * params) {if (GLeeInit()) glGetVertexAttribIivEXT(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBIIVEXTPROC GLeeFuncPtr_glGetVertexAttribIivEXT=GLee_Lazy_glGetVertexAttribIivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetVertexAttribIuivEXT +#define GLEE_C_DEFINED_glGetVertexAttribIuivEXT + GLvoid __stdcall GLee_Lazy_glGetVertexAttribIuivEXT(GLuint index, GLenum pname, GLuint * params) {if (GLeeInit()) glGetVertexAttribIuivEXT(index, pname, params);} + GLEEPFNGLGETVERTEXATTRIBIUIVEXTPROC GLeeFuncPtr_glGetVertexAttribIuivEXT=GLee_Lazy_glGetVertexAttribIuivEXT; +#endif +#endif + +/* GL_OES_byte_coordinates */ + +#ifdef __GLEE_GL_OES_byte_coordinates +#endif + +/* GL_OES_compressed_paletted_texture */ + +#ifdef __GLEE_GL_OES_compressed_paletted_texture +#endif + +/* GL_OES_single_precision */ + +#ifdef __GLEE_GL_OES_single_precision +#ifndef GLEE_C_DEFINED_glDepthRangefOES +#define GLEE_C_DEFINED_glDepthRangefOES + GLvoid __stdcall GLee_Lazy_glDepthRangefOES(GLclampf n, GLclampf f) {if (GLeeInit()) glDepthRangefOES(n, f);} + GLEEPFNGLDEPTHRANGEFOESPROC GLeeFuncPtr_glDepthRangefOES=GLee_Lazy_glDepthRangefOES; +#endif +#ifndef GLEE_C_DEFINED_glFrustumfOES +#define GLEE_C_DEFINED_glFrustumfOES + GLvoid __stdcall GLee_Lazy_glFrustumfOES(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f) {if (GLeeInit()) glFrustumfOES(l, r, b, t, n, f);} + GLEEPFNGLFRUSTUMFOESPROC GLeeFuncPtr_glFrustumfOES=GLee_Lazy_glFrustumfOES; +#endif +#ifndef GLEE_C_DEFINED_glOrthofOES +#define GLEE_C_DEFINED_glOrthofOES + GLvoid __stdcall GLee_Lazy_glOrthofOES(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f) {if (GLeeInit()) glOrthofOES(l, r, b, t, n, f);} + GLEEPFNGLORTHOFOESPROC GLeeFuncPtr_glOrthofOES=GLee_Lazy_glOrthofOES; +#endif +#ifndef GLEE_C_DEFINED_glClipPlanefOES +#define GLEE_C_DEFINED_glClipPlanefOES + GLvoid __stdcall GLee_Lazy_glClipPlanefOES(GLenum plane, const GLfloat* equation) {if (GLeeInit()) glClipPlanefOES(plane, equation);} + GLEEPFNGLCLIPPLANEFOESPROC GLeeFuncPtr_glClipPlanefOES=GLee_Lazy_glClipPlanefOES; +#endif +#ifndef GLEE_C_DEFINED_glGetClipPlanefOES +#define GLEE_C_DEFINED_glGetClipPlanefOES + GLvoid __stdcall GLee_Lazy_glGetClipPlanefOES(GLenum plane, GLfloat* equation) {if (GLeeInit()) glGetClipPlanefOES(plane, equation);} + GLEEPFNGLGETCLIPPLANEFOESPROC GLeeFuncPtr_glGetClipPlanefOES=GLee_Lazy_glGetClipPlanefOES; +#endif +#ifndef GLEE_C_DEFINED_glClearDepthfOES +#define GLEE_C_DEFINED_glClearDepthfOES + GLvoid __stdcall GLee_Lazy_glClearDepthfOES(GLclampd depth) {if (GLeeInit()) glClearDepthfOES(depth);} + GLEEPFNGLCLEARDEPTHFOESPROC GLeeFuncPtr_glClearDepthfOES=GLee_Lazy_glClearDepthfOES; +#endif +#endif + +/* GL_SGIX_pixel_texture_bits */ + +#ifdef __GLEE_GL_SGIX_pixel_texture_bits +#endif + +/* GL_SGIX_texture_range */ + +#ifdef __GLEE_GL_SGIX_texture_range +#endif + +/* WGL */ + +#ifdef WIN32 + +/* Extension querying variables */ + +GLboolean _GLEE_WGL_ARB_buffer_region = GL_FALSE; +GLboolean _GLEE_WGL_ARB_multisample = GL_FALSE; +GLboolean _GLEE_WGL_ARB_extensions_string = GL_FALSE; +GLboolean _GLEE_WGL_ARB_pixel_format = GL_FALSE; +GLboolean _GLEE_WGL_ARB_make_current_read = GL_FALSE; +GLboolean _GLEE_WGL_ARB_pbuffer = GL_FALSE; +GLboolean _GLEE_WGL_ARB_render_texture = GL_FALSE; +GLboolean _GLEE_WGL_ARB_pixel_format_float = GL_FALSE; +GLboolean _GLEE_WGL_ARB_create_context = GL_FALSE; +GLboolean _GLEE_WGL_EXT_make_current_read = GL_FALSE; +GLboolean _GLEE_WGL_EXT_pixel_format = GL_FALSE; +GLboolean _GLEE_WGL_EXT_pbuffer = GL_FALSE; +GLboolean _GLEE_WGL_EXT_depth_float = GL_FALSE; +GLboolean _GLEE_WGL_3DFX_multisample = GL_FALSE; +GLboolean _GLEE_WGL_EXT_multisample = GL_FALSE; +GLboolean _GLEE_WGL_I3D_digital_video_control = GL_FALSE; +GLboolean _GLEE_WGL_I3D_gamma = GL_FALSE; +GLboolean _GLEE_WGL_I3D_genlock = GL_FALSE; +GLboolean _GLEE_WGL_I3D_image_buffer = GL_FALSE; +GLboolean _GLEE_WGL_I3D_swap_frame_lock = GL_FALSE; +GLboolean _GLEE_WGL_NV_render_depth_texture = GL_FALSE; +GLboolean _GLEE_WGL_NV_render_texture_rectangle = GL_FALSE; +GLboolean _GLEE_WGL_ATI_pixel_format_float = GL_FALSE; +GLboolean _GLEE_WGL_NV_float_buffer = GL_FALSE; +GLboolean _GLEE_WGL_3DL_stereo_control = GL_FALSE; +GLboolean _GLEE_WGL_EXT_pixel_format_packed_float = GL_FALSE; +GLboolean _GLEE_WGL_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean _GLEE_WGL_NV_present_video = GL_FALSE; +GLboolean _GLEE_WGL_NV_swap_group = GL_FALSE; +GLboolean _GLEE_WGL_NV_gpu_affinity = GL_FALSE; +GLboolean _GLEE_WGL_EXT_display_color_table = GL_FALSE; +GLboolean _GLEE_WGL_EXT_extensions_string = GL_FALSE; +GLboolean _GLEE_WGL_EXT_swap_control = GL_FALSE; +GLboolean _GLEE_WGL_NV_vertex_array_range = GL_FALSE; +GLboolean _GLEE_WGL_OML_sync_control = GL_FALSE; +GLboolean _GLEE_WGL_I3D_swap_frame_usage = GL_FALSE; +GLboolean _GLEE_WGL_NV_video_output = GL_FALSE; + +/* WGL Extension names */ + +char __GLeeWGLExtensionNames[37][34]={ + "WGL_ARB_buffer_region", + "WGL_ARB_multisample", + "WGL_ARB_extensions_string", + "WGL_ARB_pixel_format", + "WGL_ARB_make_current_read", + "WGL_ARB_pbuffer", + "WGL_ARB_render_texture", + "WGL_ARB_pixel_format_float", + "WGL_ARB_create_context", + "WGL_EXT_make_current_read", + "WGL_EXT_pixel_format", + "WGL_EXT_pbuffer", + "WGL_EXT_depth_float", + "WGL_3DFX_multisample", + "WGL_EXT_multisample", + "WGL_I3D_digital_video_control", + "WGL_I3D_gamma", + "WGL_I3D_genlock", + "WGL_I3D_image_buffer", + "WGL_I3D_swap_frame_lock", + "WGL_NV_render_depth_texture", + "WGL_NV_render_texture_rectangle", + "WGL_ATI_pixel_format_float", + "WGL_NV_float_buffer", + "WGL_3DL_stereo_control", + "WGL_EXT_pixel_format_packed_float", + "WGL_EXT_framebuffer_sRGB", + "WGL_NV_present_video", + "WGL_NV_swap_group", + "WGL_NV_gpu_affinity", + "WGL_EXT_display_color_table", + "WGL_EXT_extensions_string", + "WGL_EXT_swap_control", + "WGL_NV_vertex_array_range", + "WGL_OML_sync_control", + "WGL_I3D_swap_frame_usage", + "WGL_NV_video_output" +}; +int __GLeeWGLNumExtensions=37; + +/* WGL_ARB_buffer_region */ + +#ifdef __GLEE_WGL_ARB_buffer_region +#ifndef GLEE_C_DEFINED_wglCreateBufferRegionARB +#define GLEE_C_DEFINED_wglCreateBufferRegionARB + HANDLE __stdcall GLee_Lazy_wglCreateBufferRegionARB(HDC hDC, int iLayerPlane, UINT uType) {if (GLeeInit()) return wglCreateBufferRegionARB(hDC, iLayerPlane, uType); return (HANDLE)0;} + GLEEPFNWGLCREATEBUFFERREGIONARBPROC GLeeFuncPtr_wglCreateBufferRegionARB=GLee_Lazy_wglCreateBufferRegionARB; +#endif +#ifndef GLEE_C_DEFINED_wglDeleteBufferRegionARB +#define GLEE_C_DEFINED_wglDeleteBufferRegionARB + VOID __stdcall GLee_Lazy_wglDeleteBufferRegionARB(HANDLE hRegion) {if (GLeeInit()) wglDeleteBufferRegionARB(hRegion);} + GLEEPFNWGLDELETEBUFFERREGIONARBPROC GLeeFuncPtr_wglDeleteBufferRegionARB=GLee_Lazy_wglDeleteBufferRegionARB; +#endif +#ifndef GLEE_C_DEFINED_wglSaveBufferRegionARB +#define GLEE_C_DEFINED_wglSaveBufferRegionARB + BOOL __stdcall GLee_Lazy_wglSaveBufferRegionARB(HANDLE hRegion, int x, int y, int width, int height) {if (GLeeInit()) return wglSaveBufferRegionARB(hRegion, x, y, width, height); return (BOOL)0;} + GLEEPFNWGLSAVEBUFFERREGIONARBPROC GLeeFuncPtr_wglSaveBufferRegionARB=GLee_Lazy_wglSaveBufferRegionARB; +#endif +#ifndef GLEE_C_DEFINED_wglRestoreBufferRegionARB +#define GLEE_C_DEFINED_wglRestoreBufferRegionARB + BOOL __stdcall GLee_Lazy_wglRestoreBufferRegionARB(HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc) {if (GLeeInit()) return wglRestoreBufferRegionARB(hRegion, x, y, width, height, xSrc, ySrc); return (BOOL)0;} + GLEEPFNWGLRESTOREBUFFERREGIONARBPROC GLeeFuncPtr_wglRestoreBufferRegionARB=GLee_Lazy_wglRestoreBufferRegionARB; +#endif +#endif + +/* WGL_ARB_multisample */ + +#ifdef __GLEE_WGL_ARB_multisample +#endif + +/* WGL_ARB_extensions_string */ + +#ifdef __GLEE_WGL_ARB_extensions_string +#ifndef GLEE_C_DEFINED_wglGetExtensionsStringARB +#define GLEE_C_DEFINED_wglGetExtensionsStringARB + const char * __stdcall GLee_Lazy_wglGetExtensionsStringARB(HDC hdc) {if (GLeeInit()) return wglGetExtensionsStringARB(hdc); return (const char *)0;} + GLEEPFNWGLGETEXTENSIONSSTRINGARBPROC GLeeFuncPtr_wglGetExtensionsStringARB=GLee_Lazy_wglGetExtensionsStringARB; +#endif +#endif + +/* WGL_ARB_pixel_format */ + +#ifdef __GLEE_WGL_ARB_pixel_format +#ifndef GLEE_C_DEFINED_wglGetPixelFormatAttribivARB +#define GLEE_C_DEFINED_wglGetPixelFormatAttribivARB + BOOL __stdcall GLee_Lazy_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, int * piValues) {if (GLeeInit()) return wglGetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); return (BOOL)0;} + GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribivARB=GLee_Lazy_wglGetPixelFormatAttribivARB; +#endif +#ifndef GLEE_C_DEFINED_wglGetPixelFormatAttribfvARB +#define GLEE_C_DEFINED_wglGetPixelFormatAttribfvARB + BOOL __stdcall GLee_Lazy_wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, FLOAT * pfValues) {if (GLeeInit()) return wglGetPixelFormatAttribfvARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); return (BOOL)0;} + GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribfvARB=GLee_Lazy_wglGetPixelFormatAttribfvARB; +#endif +#ifndef GLEE_C_DEFINED_wglChoosePixelFormatARB +#define GLEE_C_DEFINED_wglChoosePixelFormatARB + BOOL __stdcall GLee_Lazy_wglChoosePixelFormatARB(HDC hdc, const int * piAttribIList, const FLOAT * pfAttribFList, UINT nMaxFormats, int * piFormats, UINT * nNumFormats) {if (GLeeInit()) return wglChoosePixelFormatARB(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); return (BOOL)0;} + GLEEPFNWGLCHOOSEPIXELFORMATARBPROC GLeeFuncPtr_wglChoosePixelFormatARB=GLee_Lazy_wglChoosePixelFormatARB; +#endif +#endif + +/* WGL_ARB_make_current_read */ + +#ifdef __GLEE_WGL_ARB_make_current_read +#ifndef GLEE_C_DEFINED_wglMakeContextCurrentARB +#define GLEE_C_DEFINED_wglMakeContextCurrentARB + BOOL __stdcall GLee_Lazy_wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc) {if (GLeeInit()) return wglMakeContextCurrentARB(hDrawDC, hReadDC, hglrc); return (BOOL)0;} + GLEEPFNWGLMAKECONTEXTCURRENTARBPROC GLeeFuncPtr_wglMakeContextCurrentARB=GLee_Lazy_wglMakeContextCurrentARB; +#endif +#ifndef GLEE_C_DEFINED_wglGetCurrentReadDCARB +#define GLEE_C_DEFINED_wglGetCurrentReadDCARB + HDC __stdcall GLee_Lazy_wglGetCurrentReadDCARB(void) {if (GLeeInit()) return wglGetCurrentReadDCARB(); return (HDC)0;} + GLEEPFNWGLGETCURRENTREADDCARBPROC GLeeFuncPtr_wglGetCurrentReadDCARB=GLee_Lazy_wglGetCurrentReadDCARB; +#endif +#endif + +/* WGL_ARB_pbuffer */ + +#ifdef __GLEE_WGL_ARB_pbuffer +#ifndef GLEE_C_DEFINED_wglCreatePbufferARB +#define GLEE_C_DEFINED_wglCreatePbufferARB + HPBUFFERARB __stdcall GLee_Lazy_wglCreatePbufferARB(HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int * piAttribList) {if (GLeeInit()) return wglCreatePbufferARB(hDC, iPixelFormat, iWidth, iHeight, piAttribList); return (HPBUFFERARB)0;} + GLEEPFNWGLCREATEPBUFFERARBPROC GLeeFuncPtr_wglCreatePbufferARB=GLee_Lazy_wglCreatePbufferARB; +#endif +#ifndef GLEE_C_DEFINED_wglGetPbufferDCARB +#define GLEE_C_DEFINED_wglGetPbufferDCARB + HDC __stdcall GLee_Lazy_wglGetPbufferDCARB(HPBUFFERARB hPbuffer) {if (GLeeInit()) return wglGetPbufferDCARB(hPbuffer); return (HDC)0;} + GLEEPFNWGLGETPBUFFERDCARBPROC GLeeFuncPtr_wglGetPbufferDCARB=GLee_Lazy_wglGetPbufferDCARB; +#endif +#ifndef GLEE_C_DEFINED_wglReleasePbufferDCARB +#define GLEE_C_DEFINED_wglReleasePbufferDCARB + int __stdcall GLee_Lazy_wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hDC) {if (GLeeInit()) return wglReleasePbufferDCARB(hPbuffer, hDC); return (int)0;} + GLEEPFNWGLRELEASEPBUFFERDCARBPROC GLeeFuncPtr_wglReleasePbufferDCARB=GLee_Lazy_wglReleasePbufferDCARB; +#endif +#ifndef GLEE_C_DEFINED_wglDestroyPbufferARB +#define GLEE_C_DEFINED_wglDestroyPbufferARB + BOOL __stdcall GLee_Lazy_wglDestroyPbufferARB(HPBUFFERARB hPbuffer) {if (GLeeInit()) return wglDestroyPbufferARB(hPbuffer); return (BOOL)0;} + GLEEPFNWGLDESTROYPBUFFERARBPROC GLeeFuncPtr_wglDestroyPbufferARB=GLee_Lazy_wglDestroyPbufferARB; +#endif +#ifndef GLEE_C_DEFINED_wglQueryPbufferARB +#define GLEE_C_DEFINED_wglQueryPbufferARB + BOOL __stdcall GLee_Lazy_wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int * piValue) {if (GLeeInit()) return wglQueryPbufferARB(hPbuffer, iAttribute, piValue); return (BOOL)0;} + GLEEPFNWGLQUERYPBUFFERARBPROC GLeeFuncPtr_wglQueryPbufferARB=GLee_Lazy_wglQueryPbufferARB; +#endif +#endif + +/* WGL_ARB_render_texture */ + +#ifdef __GLEE_WGL_ARB_render_texture +#ifndef GLEE_C_DEFINED_wglBindTexImageARB +#define GLEE_C_DEFINED_wglBindTexImageARB + BOOL __stdcall GLee_Lazy_wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) {if (GLeeInit()) return wglBindTexImageARB(hPbuffer, iBuffer); return (BOOL)0;} + GLEEPFNWGLBINDTEXIMAGEARBPROC GLeeFuncPtr_wglBindTexImageARB=GLee_Lazy_wglBindTexImageARB; +#endif +#ifndef GLEE_C_DEFINED_wglReleaseTexImageARB +#define GLEE_C_DEFINED_wglReleaseTexImageARB + BOOL __stdcall GLee_Lazy_wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) {if (GLeeInit()) return wglReleaseTexImageARB(hPbuffer, iBuffer); return (BOOL)0;} + GLEEPFNWGLRELEASETEXIMAGEARBPROC GLeeFuncPtr_wglReleaseTexImageARB=GLee_Lazy_wglReleaseTexImageARB; +#endif +#ifndef GLEE_C_DEFINED_wglSetPbufferAttribARB +#define GLEE_C_DEFINED_wglSetPbufferAttribARB + BOOL __stdcall GLee_Lazy_wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int * piAttribList) {if (GLeeInit()) return wglSetPbufferAttribARB(hPbuffer, piAttribList); return (BOOL)0;} + GLEEPFNWGLSETPBUFFERATTRIBARBPROC GLeeFuncPtr_wglSetPbufferAttribARB=GLee_Lazy_wglSetPbufferAttribARB; +#endif +#endif + +/* WGL_ARB_pixel_format_float */ + +#ifdef __GLEE_WGL_ARB_pixel_format_float +#endif + +/* WGL_ARB_create_context */ + +#ifdef __GLEE_WGL_ARB_create_context +#ifndef GLEE_C_DEFINED_wglCreateContextAttribsARB +#define GLEE_C_DEFINED_wglCreateContextAttribsARB + HGLRC __stdcall GLee_Lazy_wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int * attribList) {if (GLeeInit()) return wglCreateContextAttribsARB(hDC, hShareContext, attribList); return (HGLRC)0;} + GLEEPFNWGLCREATECONTEXTATTRIBSARBPROC GLeeFuncPtr_wglCreateContextAttribsARB=GLee_Lazy_wglCreateContextAttribsARB; +#endif +#endif + +/* WGL_EXT_make_current_read */ + +#ifdef __GLEE_WGL_EXT_make_current_read +#ifndef GLEE_C_DEFINED_wglMakeContextCurrentEXT +#define GLEE_C_DEFINED_wglMakeContextCurrentEXT + BOOL __stdcall GLee_Lazy_wglMakeContextCurrentEXT(HDC hDrawDC, HDC hReadDC, HGLRC hglrc) {if (GLeeInit()) return wglMakeContextCurrentEXT(hDrawDC, hReadDC, hglrc); return (BOOL)0;} + GLEEPFNWGLMAKECONTEXTCURRENTEXTPROC GLeeFuncPtr_wglMakeContextCurrentEXT=GLee_Lazy_wglMakeContextCurrentEXT; +#endif +#ifndef GLEE_C_DEFINED_wglGetCurrentReadDCEXT +#define GLEE_C_DEFINED_wglGetCurrentReadDCEXT + HDC __stdcall GLee_Lazy_wglGetCurrentReadDCEXT(void) {if (GLeeInit()) return wglGetCurrentReadDCEXT(); return (HDC)0;} + GLEEPFNWGLGETCURRENTREADDCEXTPROC GLeeFuncPtr_wglGetCurrentReadDCEXT=GLee_Lazy_wglGetCurrentReadDCEXT; +#endif +#endif + +/* WGL_EXT_pixel_format */ + +#ifdef __GLEE_WGL_EXT_pixel_format +#ifndef GLEE_C_DEFINED_wglGetPixelFormatAttribivEXT +#define GLEE_C_DEFINED_wglGetPixelFormatAttribivEXT + BOOL __stdcall GLee_Lazy_wglGetPixelFormatAttribivEXT(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int * piAttributes, int * piValues) {if (GLeeInit()) return wglGetPixelFormatAttribivEXT(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); return (BOOL)0;} + GLEEPFNWGLGETPIXELFORMATATTRIBIVEXTPROC GLeeFuncPtr_wglGetPixelFormatAttribivEXT=GLee_Lazy_wglGetPixelFormatAttribivEXT; +#endif +#ifndef GLEE_C_DEFINED_wglGetPixelFormatAttribfvEXT +#define GLEE_C_DEFINED_wglGetPixelFormatAttribfvEXT + BOOL __stdcall GLee_Lazy_wglGetPixelFormatAttribfvEXT(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int * piAttributes, FLOAT * pfValues) {if (GLeeInit()) return wglGetPixelFormatAttribfvEXT(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); return (BOOL)0;} + GLEEPFNWGLGETPIXELFORMATATTRIBFVEXTPROC GLeeFuncPtr_wglGetPixelFormatAttribfvEXT=GLee_Lazy_wglGetPixelFormatAttribfvEXT; +#endif +#ifndef GLEE_C_DEFINED_wglChoosePixelFormatEXT +#define GLEE_C_DEFINED_wglChoosePixelFormatEXT + BOOL __stdcall GLee_Lazy_wglChoosePixelFormatEXT(HDC hdc, const int * piAttribIList, const FLOAT * pfAttribFList, UINT nMaxFormats, int * piFormats, UINT * nNumFormats) {if (GLeeInit()) return wglChoosePixelFormatEXT(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); return (BOOL)0;} + GLEEPFNWGLCHOOSEPIXELFORMATEXTPROC GLeeFuncPtr_wglChoosePixelFormatEXT=GLee_Lazy_wglChoosePixelFormatEXT; +#endif +#endif + +/* WGL_EXT_pbuffer */ + +#ifdef __GLEE_WGL_EXT_pbuffer +#ifndef GLEE_C_DEFINED_wglCreatePbufferEXT +#define GLEE_C_DEFINED_wglCreatePbufferEXT + HPBUFFEREXT __stdcall GLee_Lazy_wglCreatePbufferEXT(HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int * piAttribList) {if (GLeeInit()) return wglCreatePbufferEXT(hDC, iPixelFormat, iWidth, iHeight, piAttribList); return (HPBUFFEREXT)0;} + GLEEPFNWGLCREATEPBUFFEREXTPROC GLeeFuncPtr_wglCreatePbufferEXT=GLee_Lazy_wglCreatePbufferEXT; +#endif +#ifndef GLEE_C_DEFINED_wglGetPbufferDCEXT +#define GLEE_C_DEFINED_wglGetPbufferDCEXT + HDC __stdcall GLee_Lazy_wglGetPbufferDCEXT(HPBUFFEREXT hPbuffer) {if (GLeeInit()) return wglGetPbufferDCEXT(hPbuffer); return (HDC)0;} + GLEEPFNWGLGETPBUFFERDCEXTPROC GLeeFuncPtr_wglGetPbufferDCEXT=GLee_Lazy_wglGetPbufferDCEXT; +#endif +#ifndef GLEE_C_DEFINED_wglReleasePbufferDCEXT +#define GLEE_C_DEFINED_wglReleasePbufferDCEXT + int __stdcall GLee_Lazy_wglReleasePbufferDCEXT(HPBUFFEREXT hPbuffer, HDC hDC) {if (GLeeInit()) return wglReleasePbufferDCEXT(hPbuffer, hDC); return (int)0;} + GLEEPFNWGLRELEASEPBUFFERDCEXTPROC GLeeFuncPtr_wglReleasePbufferDCEXT=GLee_Lazy_wglReleasePbufferDCEXT; +#endif +#ifndef GLEE_C_DEFINED_wglDestroyPbufferEXT +#define GLEE_C_DEFINED_wglDestroyPbufferEXT + BOOL __stdcall GLee_Lazy_wglDestroyPbufferEXT(HPBUFFEREXT hPbuffer) {if (GLeeInit()) return wglDestroyPbufferEXT(hPbuffer); return (BOOL)0;} + GLEEPFNWGLDESTROYPBUFFEREXTPROC GLeeFuncPtr_wglDestroyPbufferEXT=GLee_Lazy_wglDestroyPbufferEXT; +#endif +#ifndef GLEE_C_DEFINED_wglQueryPbufferEXT +#define GLEE_C_DEFINED_wglQueryPbufferEXT + BOOL __stdcall GLee_Lazy_wglQueryPbufferEXT(HPBUFFEREXT hPbuffer, int iAttribute, int * piValue) {if (GLeeInit()) return wglQueryPbufferEXT(hPbuffer, iAttribute, piValue); return (BOOL)0;} + GLEEPFNWGLQUERYPBUFFEREXTPROC GLeeFuncPtr_wglQueryPbufferEXT=GLee_Lazy_wglQueryPbufferEXT; +#endif +#endif + +/* WGL_EXT_depth_float */ + +#ifdef __GLEE_WGL_EXT_depth_float +#endif + +/* WGL_3DFX_multisample */ + +#ifdef __GLEE_WGL_3DFX_multisample +#endif + +/* WGL_EXT_multisample */ + +#ifdef __GLEE_WGL_EXT_multisample +#endif + +/* WGL_I3D_digital_video_control */ + +#ifdef __GLEE_WGL_I3D_digital_video_control +#ifndef GLEE_C_DEFINED_wglGetDigitalVideoParametersI3D +#define GLEE_C_DEFINED_wglGetDigitalVideoParametersI3D + BOOL __stdcall GLee_Lazy_wglGetDigitalVideoParametersI3D(HDC hDC, int iAttribute, int * piValue) {if (GLeeInit()) return wglGetDigitalVideoParametersI3D(hDC, iAttribute, piValue); return (BOOL)0;} + GLEEPFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC GLeeFuncPtr_wglGetDigitalVideoParametersI3D=GLee_Lazy_wglGetDigitalVideoParametersI3D; +#endif +#ifndef GLEE_C_DEFINED_wglSetDigitalVideoParametersI3D +#define GLEE_C_DEFINED_wglSetDigitalVideoParametersI3D + BOOL __stdcall GLee_Lazy_wglSetDigitalVideoParametersI3D(HDC hDC, int iAttribute, const int * piValue) {if (GLeeInit()) return wglSetDigitalVideoParametersI3D(hDC, iAttribute, piValue); return (BOOL)0;} + GLEEPFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC GLeeFuncPtr_wglSetDigitalVideoParametersI3D=GLee_Lazy_wglSetDigitalVideoParametersI3D; +#endif +#endif + +/* WGL_I3D_gamma */ + +#ifdef __GLEE_WGL_I3D_gamma +#ifndef GLEE_C_DEFINED_wglGetGammaTableParametersI3D +#define GLEE_C_DEFINED_wglGetGammaTableParametersI3D + BOOL __stdcall GLee_Lazy_wglGetGammaTableParametersI3D(HDC hDC, int iAttribute, int * piValue) {if (GLeeInit()) return wglGetGammaTableParametersI3D(hDC, iAttribute, piValue); return (BOOL)0;} + GLEEPFNWGLGETGAMMATABLEPARAMETERSI3DPROC GLeeFuncPtr_wglGetGammaTableParametersI3D=GLee_Lazy_wglGetGammaTableParametersI3D; +#endif +#ifndef GLEE_C_DEFINED_wglSetGammaTableParametersI3D +#define GLEE_C_DEFINED_wglSetGammaTableParametersI3D + BOOL __stdcall GLee_Lazy_wglSetGammaTableParametersI3D(HDC hDC, int iAttribute, const int * piValue) {if (GLeeInit()) return wglSetGammaTableParametersI3D(hDC, iAttribute, piValue); return (BOOL)0;} + GLEEPFNWGLSETGAMMATABLEPARAMETERSI3DPROC GLeeFuncPtr_wglSetGammaTableParametersI3D=GLee_Lazy_wglSetGammaTableParametersI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGetGammaTableI3D +#define GLEE_C_DEFINED_wglGetGammaTableI3D + BOOL __stdcall GLee_Lazy_wglGetGammaTableI3D(HDC hDC, int iEntries, USHORT * puRed, USHORT * puGreen, USHORT * puBlue) {if (GLeeInit()) return wglGetGammaTableI3D(hDC, iEntries, puRed, puGreen, puBlue); return (BOOL)0;} + GLEEPFNWGLGETGAMMATABLEI3DPROC GLeeFuncPtr_wglGetGammaTableI3D=GLee_Lazy_wglGetGammaTableI3D; +#endif +#ifndef GLEE_C_DEFINED_wglSetGammaTableI3D +#define GLEE_C_DEFINED_wglSetGammaTableI3D + BOOL __stdcall GLee_Lazy_wglSetGammaTableI3D(HDC hDC, int iEntries, const USHORT * puRed, const USHORT * puGreen, const USHORT * puBlue) {if (GLeeInit()) return wglSetGammaTableI3D(hDC, iEntries, puRed, puGreen, puBlue); return (BOOL)0;} + GLEEPFNWGLSETGAMMATABLEI3DPROC GLeeFuncPtr_wglSetGammaTableI3D=GLee_Lazy_wglSetGammaTableI3D; +#endif +#endif + +/* WGL_I3D_genlock */ + +#ifdef __GLEE_WGL_I3D_genlock +#ifndef GLEE_C_DEFINED_wglEnableGenlockI3D +#define GLEE_C_DEFINED_wglEnableGenlockI3D + BOOL __stdcall GLee_Lazy_wglEnableGenlockI3D(HDC hDC) {if (GLeeInit()) return wglEnableGenlockI3D(hDC); return (BOOL)0;} + GLEEPFNWGLENABLEGENLOCKI3DPROC GLeeFuncPtr_wglEnableGenlockI3D=GLee_Lazy_wglEnableGenlockI3D; +#endif +#ifndef GLEE_C_DEFINED_wglDisableGenlockI3D +#define GLEE_C_DEFINED_wglDisableGenlockI3D + BOOL __stdcall GLee_Lazy_wglDisableGenlockI3D(HDC hDC) {if (GLeeInit()) return wglDisableGenlockI3D(hDC); return (BOOL)0;} + GLEEPFNWGLDISABLEGENLOCKI3DPROC GLeeFuncPtr_wglDisableGenlockI3D=GLee_Lazy_wglDisableGenlockI3D; +#endif +#ifndef GLEE_C_DEFINED_wglIsEnabledGenlockI3D +#define GLEE_C_DEFINED_wglIsEnabledGenlockI3D + BOOL __stdcall GLee_Lazy_wglIsEnabledGenlockI3D(HDC hDC, BOOL * pFlag) {if (GLeeInit()) return wglIsEnabledGenlockI3D(hDC, pFlag); return (BOOL)0;} + GLEEPFNWGLISENABLEDGENLOCKI3DPROC GLeeFuncPtr_wglIsEnabledGenlockI3D=GLee_Lazy_wglIsEnabledGenlockI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGenlockSourceI3D +#define GLEE_C_DEFINED_wglGenlockSourceI3D + BOOL __stdcall GLee_Lazy_wglGenlockSourceI3D(HDC hDC, UINT uSource) {if (GLeeInit()) return wglGenlockSourceI3D(hDC, uSource); return (BOOL)0;} + GLEEPFNWGLGENLOCKSOURCEI3DPROC GLeeFuncPtr_wglGenlockSourceI3D=GLee_Lazy_wglGenlockSourceI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGetGenlockSourceI3D +#define GLEE_C_DEFINED_wglGetGenlockSourceI3D + BOOL __stdcall GLee_Lazy_wglGetGenlockSourceI3D(HDC hDC, UINT * uSource) {if (GLeeInit()) return wglGetGenlockSourceI3D(hDC, uSource); return (BOOL)0;} + GLEEPFNWGLGETGENLOCKSOURCEI3DPROC GLeeFuncPtr_wglGetGenlockSourceI3D=GLee_Lazy_wglGetGenlockSourceI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGenlockSourceEdgeI3D +#define GLEE_C_DEFINED_wglGenlockSourceEdgeI3D + BOOL __stdcall GLee_Lazy_wglGenlockSourceEdgeI3D(HDC hDC, UINT uEdge) {if (GLeeInit()) return wglGenlockSourceEdgeI3D(hDC, uEdge); return (BOOL)0;} + GLEEPFNWGLGENLOCKSOURCEEDGEI3DPROC GLeeFuncPtr_wglGenlockSourceEdgeI3D=GLee_Lazy_wglGenlockSourceEdgeI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGetGenlockSourceEdgeI3D +#define GLEE_C_DEFINED_wglGetGenlockSourceEdgeI3D + BOOL __stdcall GLee_Lazy_wglGetGenlockSourceEdgeI3D(HDC hDC, UINT * uEdge) {if (GLeeInit()) return wglGetGenlockSourceEdgeI3D(hDC, uEdge); return (BOOL)0;} + GLEEPFNWGLGETGENLOCKSOURCEEDGEI3DPROC GLeeFuncPtr_wglGetGenlockSourceEdgeI3D=GLee_Lazy_wglGetGenlockSourceEdgeI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGenlockSampleRateI3D +#define GLEE_C_DEFINED_wglGenlockSampleRateI3D + BOOL __stdcall GLee_Lazy_wglGenlockSampleRateI3D(HDC hDC, UINT uRate) {if (GLeeInit()) return wglGenlockSampleRateI3D(hDC, uRate); return (BOOL)0;} + GLEEPFNWGLGENLOCKSAMPLERATEI3DPROC GLeeFuncPtr_wglGenlockSampleRateI3D=GLee_Lazy_wglGenlockSampleRateI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGetGenlockSampleRateI3D +#define GLEE_C_DEFINED_wglGetGenlockSampleRateI3D + BOOL __stdcall GLee_Lazy_wglGetGenlockSampleRateI3D(HDC hDC, UINT * uRate) {if (GLeeInit()) return wglGetGenlockSampleRateI3D(hDC, uRate); return (BOOL)0;} + GLEEPFNWGLGETGENLOCKSAMPLERATEI3DPROC GLeeFuncPtr_wglGetGenlockSampleRateI3D=GLee_Lazy_wglGetGenlockSampleRateI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGenlockSourceDelayI3D +#define GLEE_C_DEFINED_wglGenlockSourceDelayI3D + BOOL __stdcall GLee_Lazy_wglGenlockSourceDelayI3D(HDC hDC, UINT uDelay) {if (GLeeInit()) return wglGenlockSourceDelayI3D(hDC, uDelay); return (BOOL)0;} + GLEEPFNWGLGENLOCKSOURCEDELAYI3DPROC GLeeFuncPtr_wglGenlockSourceDelayI3D=GLee_Lazy_wglGenlockSourceDelayI3D; +#endif +#ifndef GLEE_C_DEFINED_wglGetGenlockSourceDelayI3D +#define GLEE_C_DEFINED_wglGetGenlockSourceDelayI3D + BOOL __stdcall GLee_Lazy_wglGetGenlockSourceDelayI3D(HDC hDC, UINT * uDelay) {if (GLeeInit()) return wglGetGenlockSourceDelayI3D(hDC, uDelay); return (BOOL)0;} + GLEEPFNWGLGETGENLOCKSOURCEDELAYI3DPROC GLeeFuncPtr_wglGetGenlockSourceDelayI3D=GLee_Lazy_wglGetGenlockSourceDelayI3D; +#endif +#ifndef GLEE_C_DEFINED_wglQueryGenlockMaxSourceDelayI3D +#define GLEE_C_DEFINED_wglQueryGenlockMaxSourceDelayI3D + BOOL __stdcall GLee_Lazy_wglQueryGenlockMaxSourceDelayI3D(HDC hDC, UINT * uMaxLineDelay, UINT * uMaxPixelDelay) {if (GLeeInit()) return wglQueryGenlockMaxSourceDelayI3D(hDC, uMaxLineDelay, uMaxPixelDelay); return (BOOL)0;} + GLEEPFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC GLeeFuncPtr_wglQueryGenlockMaxSourceDelayI3D=GLee_Lazy_wglQueryGenlockMaxSourceDelayI3D; +#endif +#endif + +/* WGL_I3D_image_buffer */ + +#ifdef __GLEE_WGL_I3D_image_buffer +#ifndef GLEE_C_DEFINED_wglCreateImageBufferI3D +#define GLEE_C_DEFINED_wglCreateImageBufferI3D + LPVOID __stdcall GLee_Lazy_wglCreateImageBufferI3D(HDC hDC, DWORD dwSize, UINT uFlags) {if (GLeeInit()) return wglCreateImageBufferI3D(hDC, dwSize, uFlags); return (LPVOID)0;} + GLEEPFNWGLCREATEIMAGEBUFFERI3DPROC GLeeFuncPtr_wglCreateImageBufferI3D=GLee_Lazy_wglCreateImageBufferI3D; +#endif +#ifndef GLEE_C_DEFINED_wglDestroyImageBufferI3D +#define GLEE_C_DEFINED_wglDestroyImageBufferI3D + BOOL __stdcall GLee_Lazy_wglDestroyImageBufferI3D(HDC hDC, LPVOID pAddress) {if (GLeeInit()) return wglDestroyImageBufferI3D(hDC, pAddress); return (BOOL)0;} + GLEEPFNWGLDESTROYIMAGEBUFFERI3DPROC GLeeFuncPtr_wglDestroyImageBufferI3D=GLee_Lazy_wglDestroyImageBufferI3D; +#endif +#ifndef GLEE_C_DEFINED_wglAssociateImageBufferEventsI3D +#define GLEE_C_DEFINED_wglAssociateImageBufferEventsI3D + BOOL __stdcall GLee_Lazy_wglAssociateImageBufferEventsI3D(HDC hDC, const HANDLE * pEvent, const LPVOID * pAddress, const DWORD * pSize, UINT count) {if (GLeeInit()) return wglAssociateImageBufferEventsI3D(hDC, pEvent, pAddress, pSize, count); return (BOOL)0;} + GLEEPFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC GLeeFuncPtr_wglAssociateImageBufferEventsI3D=GLee_Lazy_wglAssociateImageBufferEventsI3D; +#endif +#ifndef GLEE_C_DEFINED_wglReleaseImageBufferEventsI3D +#define GLEE_C_DEFINED_wglReleaseImageBufferEventsI3D + BOOL __stdcall GLee_Lazy_wglReleaseImageBufferEventsI3D(HDC hDC, const LPVOID * pAddress, UINT count) {if (GLeeInit()) return wglReleaseImageBufferEventsI3D(hDC, pAddress, count); return (BOOL)0;} + GLEEPFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC GLeeFuncPtr_wglReleaseImageBufferEventsI3D=GLee_Lazy_wglReleaseImageBufferEventsI3D; +#endif +#endif + +/* WGL_I3D_swap_frame_lock */ + +#ifdef __GLEE_WGL_I3D_swap_frame_lock +#ifndef GLEE_C_DEFINED_wglEnableFrameLockI3D +#define GLEE_C_DEFINED_wglEnableFrameLockI3D + BOOL __stdcall GLee_Lazy_wglEnableFrameLockI3D(void) {if (GLeeInit()) return wglEnableFrameLockI3D(); return (BOOL)0;} + GLEEPFNWGLENABLEFRAMELOCKI3DPROC GLeeFuncPtr_wglEnableFrameLockI3D=GLee_Lazy_wglEnableFrameLockI3D; +#endif +#ifndef GLEE_C_DEFINED_wglDisableFrameLockI3D +#define GLEE_C_DEFINED_wglDisableFrameLockI3D + BOOL __stdcall GLee_Lazy_wglDisableFrameLockI3D(void) {if (GLeeInit()) return wglDisableFrameLockI3D(); return (BOOL)0;} + GLEEPFNWGLDISABLEFRAMELOCKI3DPROC GLeeFuncPtr_wglDisableFrameLockI3D=GLee_Lazy_wglDisableFrameLockI3D; +#endif +#ifndef GLEE_C_DEFINED_wglIsEnabledFrameLockI3D +#define GLEE_C_DEFINED_wglIsEnabledFrameLockI3D + BOOL __stdcall GLee_Lazy_wglIsEnabledFrameLockI3D(BOOL * pFlag) {if (GLeeInit()) return wglIsEnabledFrameLockI3D(pFlag); return (BOOL)0;} + GLEEPFNWGLISENABLEDFRAMELOCKI3DPROC GLeeFuncPtr_wglIsEnabledFrameLockI3D=GLee_Lazy_wglIsEnabledFrameLockI3D; +#endif +#ifndef GLEE_C_DEFINED_wglQueryFrameLockMasterI3D +#define GLEE_C_DEFINED_wglQueryFrameLockMasterI3D + BOOL __stdcall GLee_Lazy_wglQueryFrameLockMasterI3D(BOOL * pFlag) {if (GLeeInit()) return wglQueryFrameLockMasterI3D(pFlag); return (BOOL)0;} + GLEEPFNWGLQUERYFRAMELOCKMASTERI3DPROC GLeeFuncPtr_wglQueryFrameLockMasterI3D=GLee_Lazy_wglQueryFrameLockMasterI3D; +#endif +#endif + +/* WGL_NV_render_depth_texture */ + +#ifdef __GLEE_WGL_NV_render_depth_texture +#endif + +/* WGL_NV_render_texture_rectangle */ + +#ifdef __GLEE_WGL_NV_render_texture_rectangle +#endif + +/* WGL_ATI_pixel_format_float */ + +#ifdef __GLEE_WGL_ATI_pixel_format_float +#endif + +/* WGL_NV_float_buffer */ + +#ifdef __GLEE_WGL_NV_float_buffer +#endif + +/* WGL_3DL_stereo_control */ + +#ifdef __GLEE_WGL_3DL_stereo_control +#endif + +/* WGL_EXT_pixel_format_packed_float */ + +#ifdef __GLEE_WGL_EXT_pixel_format_packed_float +#endif + +/* WGL_EXT_framebuffer_sRGB */ + +#ifdef __GLEE_WGL_EXT_framebuffer_sRGB +#endif + +/* WGL_NV_present_video */ + +#ifdef __GLEE_WGL_NV_present_video +#ifndef GLEE_C_DEFINED_wglEnumerateVideoDevicesNV +#define GLEE_C_DEFINED_wglEnumerateVideoDevicesNV + int __stdcall GLee_Lazy_wglEnumerateVideoDevicesNV(HDC hDC, HVIDEOOUTPUTDEVICENV * phDeviceList) {if (GLeeInit()) return wglEnumerateVideoDevicesNV(hDC, phDeviceList); return (int)0;} + GLEEPFNWGLENUMERATEVIDEODEVICESNVPROC GLeeFuncPtr_wglEnumerateVideoDevicesNV=GLee_Lazy_wglEnumerateVideoDevicesNV; +#endif +#ifndef GLEE_C_DEFINED_wglBindVideoDeviceNV +#define GLEE_C_DEFINED_wglBindVideoDeviceNV + BOOL __stdcall GLee_Lazy_wglBindVideoDeviceNV(HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int * piAttribList) {if (GLeeInit()) return wglBindVideoDeviceNV(hDC, uVideoSlot, hVideoDevice, piAttribList); return (BOOL)0;} + GLEEPFNWGLBINDVIDEODEVICENVPROC GLeeFuncPtr_wglBindVideoDeviceNV=GLee_Lazy_wglBindVideoDeviceNV; +#endif +#ifndef GLEE_C_DEFINED_wglQueryCurrentContextNV +#define GLEE_C_DEFINED_wglQueryCurrentContextNV + BOOL __stdcall GLee_Lazy_wglQueryCurrentContextNV(int iAttribute, int * piValue) {if (GLeeInit()) return wglQueryCurrentContextNV(iAttribute, piValue); return (BOOL)0;} + GLEEPFNWGLQUERYCURRENTCONTEXTNVPROC GLeeFuncPtr_wglQueryCurrentContextNV=GLee_Lazy_wglQueryCurrentContextNV; +#endif +#endif + +/* WGL_NV_swap_group */ + +#ifdef __GLEE_WGL_NV_swap_group +#ifndef GLEE_C_DEFINED_wglJoinSwapGroupNV +#define GLEE_C_DEFINED_wglJoinSwapGroupNV + BOOL __stdcall GLee_Lazy_wglJoinSwapGroupNV(HDC hDC, GLuint group) {if (GLeeInit()) return wglJoinSwapGroupNV(hDC, group); return (BOOL)0;} + GLEEPFNWGLJOINSWAPGROUPNVPROC GLeeFuncPtr_wglJoinSwapGroupNV=GLee_Lazy_wglJoinSwapGroupNV; +#endif +#ifndef GLEE_C_DEFINED_wglBindSwapBarrierNV +#define GLEE_C_DEFINED_wglBindSwapBarrierNV + BOOL __stdcall GLee_Lazy_wglBindSwapBarrierNV(GLuint group, GLuint barrier) {if (GLeeInit()) return wglBindSwapBarrierNV(group, barrier); return (BOOL)0;} + GLEEPFNWGLBINDSWAPBARRIERNVPROC GLeeFuncPtr_wglBindSwapBarrierNV=GLee_Lazy_wglBindSwapBarrierNV; +#endif +#ifndef GLEE_C_DEFINED_wglQuerySwapGroupNV +#define GLEE_C_DEFINED_wglQuerySwapGroupNV + BOOL __stdcall GLee_Lazy_wglQuerySwapGroupNV(HDC hDC, GLuint * group, GLuint * barrier) {if (GLeeInit()) return wglQuerySwapGroupNV(hDC, group, barrier); return (BOOL)0;} + GLEEPFNWGLQUERYSWAPGROUPNVPROC GLeeFuncPtr_wglQuerySwapGroupNV=GLee_Lazy_wglQuerySwapGroupNV; +#endif +#ifndef GLEE_C_DEFINED_wglQueryMaxSwapGroupsNV +#define GLEE_C_DEFINED_wglQueryMaxSwapGroupsNV + BOOL __stdcall GLee_Lazy_wglQueryMaxSwapGroupsNV(HDC hDC, GLuint * maxGroups, GLuint * maxBarriers) {if (GLeeInit()) return wglQueryMaxSwapGroupsNV(hDC, maxGroups, maxBarriers); return (BOOL)0;} + GLEEPFNWGLQUERYMAXSWAPGROUPSNVPROC GLeeFuncPtr_wglQueryMaxSwapGroupsNV=GLee_Lazy_wglQueryMaxSwapGroupsNV; +#endif +#ifndef GLEE_C_DEFINED_wglQueryFrameCountNV +#define GLEE_C_DEFINED_wglQueryFrameCountNV + BOOL __stdcall GLee_Lazy_wglQueryFrameCountNV(HDC hDC, GLuint * count) {if (GLeeInit()) return wglQueryFrameCountNV(hDC, count); return (BOOL)0;} + GLEEPFNWGLQUERYFRAMECOUNTNVPROC GLeeFuncPtr_wglQueryFrameCountNV=GLee_Lazy_wglQueryFrameCountNV; +#endif +#ifndef GLEE_C_DEFINED_wglResetFrameCountNV +#define GLEE_C_DEFINED_wglResetFrameCountNV + BOOL __stdcall GLee_Lazy_wglResetFrameCountNV(HDC hDC) {if (GLeeInit()) return wglResetFrameCountNV(hDC); return (BOOL)0;} + GLEEPFNWGLRESETFRAMECOUNTNVPROC GLeeFuncPtr_wglResetFrameCountNV=GLee_Lazy_wglResetFrameCountNV; +#endif +#endif + +/* WGL_NV_gpu_affinity */ + +#ifdef __GLEE_WGL_NV_gpu_affinity +#ifndef GLEE_C_DEFINED_wglEnumGpusNV +#define GLEE_C_DEFINED_wglEnumGpusNV + BOOL __stdcall GLee_Lazy_wglEnumGpusNV(UINT iGpuIndex, HGPUNV * phGpu) {if (GLeeInit()) return wglEnumGpusNV(iGpuIndex, phGpu); return (BOOL)0;} + GLEEPFNWGLENUMGPUSNVPROC GLeeFuncPtr_wglEnumGpusNV=GLee_Lazy_wglEnumGpusNV; +#endif +#ifndef GLEE_C_DEFINED_wglEnumGpuDevicesNV +#define GLEE_C_DEFINED_wglEnumGpuDevicesNV + BOOL __stdcall GLee_Lazy_wglEnumGpuDevicesNV(HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice) {if (GLeeInit()) return wglEnumGpuDevicesNV(hGpu, iDeviceIndex, lpGpuDevice); return (BOOL)0;} + GLEEPFNWGLENUMGPUDEVICESNVPROC GLeeFuncPtr_wglEnumGpuDevicesNV=GLee_Lazy_wglEnumGpuDevicesNV; +#endif +#ifndef GLEE_C_DEFINED_wglCreateAffinityDCNV +#define GLEE_C_DEFINED_wglCreateAffinityDCNV + HDC __stdcall GLee_Lazy_wglCreateAffinityDCNV(const HGPUNV * phGpuList) {if (GLeeInit()) return wglCreateAffinityDCNV(phGpuList); return (HDC)0;} + GLEEPFNWGLCREATEAFFINITYDCNVPROC GLeeFuncPtr_wglCreateAffinityDCNV=GLee_Lazy_wglCreateAffinityDCNV; +#endif +#ifndef GLEE_C_DEFINED_wglEnumGpusFromAffinityDCNV +#define GLEE_C_DEFINED_wglEnumGpusFromAffinityDCNV + BOOL __stdcall GLee_Lazy_wglEnumGpusFromAffinityDCNV(HDC hAffinityDC, UINT iGpuIndex, HGPUNV * hGpu) {if (GLeeInit()) return wglEnumGpusFromAffinityDCNV(hAffinityDC, iGpuIndex, hGpu); return (BOOL)0;} + GLEEPFNWGLENUMGPUSFROMAFFINITYDCNVPROC GLeeFuncPtr_wglEnumGpusFromAffinityDCNV=GLee_Lazy_wglEnumGpusFromAffinityDCNV; +#endif +#ifndef GLEE_C_DEFINED_wglDeleteDCNV +#define GLEE_C_DEFINED_wglDeleteDCNV + BOOL __stdcall GLee_Lazy_wglDeleteDCNV(HDC hdc) {if (GLeeInit()) return wglDeleteDCNV(hdc); return (BOOL)0;} + GLEEPFNWGLDELETEDCNVPROC GLeeFuncPtr_wglDeleteDCNV=GLee_Lazy_wglDeleteDCNV; +#endif +#endif + +/* WGL_EXT_display_color_table */ + +#ifdef __GLEE_WGL_EXT_display_color_table +#ifndef GLEE_C_DEFINED_wglCreateDisplayColorTableEXT +#define GLEE_C_DEFINED_wglCreateDisplayColorTableEXT + GLboolean __stdcall GLee_Lazy_wglCreateDisplayColorTableEXT(GLushort id) {if (GLeeInit()) return wglCreateDisplayColorTableEXT(id); return (GLboolean)0;} + GLEEPFNWGLCREATEDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglCreateDisplayColorTableEXT=GLee_Lazy_wglCreateDisplayColorTableEXT; +#endif +#ifndef GLEE_C_DEFINED_wglLoadDisplayColorTableEXT +#define GLEE_C_DEFINED_wglLoadDisplayColorTableEXT + GLboolean __stdcall GLee_Lazy_wglLoadDisplayColorTableEXT(const GLushort * table, GLuint length) {if (GLeeInit()) return wglLoadDisplayColorTableEXT(table, length); return (GLboolean)0;} + GLEEPFNWGLLOADDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglLoadDisplayColorTableEXT=GLee_Lazy_wglLoadDisplayColorTableEXT; +#endif +#ifndef GLEE_C_DEFINED_wglBindDisplayColorTableEXT +#define GLEE_C_DEFINED_wglBindDisplayColorTableEXT + GLboolean __stdcall GLee_Lazy_wglBindDisplayColorTableEXT(GLushort id) {if (GLeeInit()) return wglBindDisplayColorTableEXT(id); return (GLboolean)0;} + GLEEPFNWGLBINDDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglBindDisplayColorTableEXT=GLee_Lazy_wglBindDisplayColorTableEXT; +#endif +#ifndef GLEE_C_DEFINED_wglDestroyDisplayColorTableEXT +#define GLEE_C_DEFINED_wglDestroyDisplayColorTableEXT + VOID __stdcall GLee_Lazy_wglDestroyDisplayColorTableEXT(GLushort id) {if (GLeeInit()) wglDestroyDisplayColorTableEXT(id);} + GLEEPFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglDestroyDisplayColorTableEXT=GLee_Lazy_wglDestroyDisplayColorTableEXT; +#endif +#endif + +/* WGL_EXT_extensions_string */ + +#ifdef __GLEE_WGL_EXT_extensions_string +#ifndef GLEE_C_DEFINED_wglGetExtensionsStringEXT +#define GLEE_C_DEFINED_wglGetExtensionsStringEXT + const char * __stdcall GLee_Lazy_wglGetExtensionsStringEXT(void) {if (GLeeInit()) return wglGetExtensionsStringEXT(); return (const char *)0;} + GLEEPFNWGLGETEXTENSIONSSTRINGEXTPROC GLeeFuncPtr_wglGetExtensionsStringEXT=GLee_Lazy_wglGetExtensionsStringEXT; +#endif +#endif + +/* WGL_EXT_swap_control */ + +#ifdef __GLEE_WGL_EXT_swap_control +#ifndef GLEE_C_DEFINED_wglSwapIntervalEXT +#define GLEE_C_DEFINED_wglSwapIntervalEXT + BOOL __stdcall GLee_Lazy_wglSwapIntervalEXT(int interval) {if (GLeeInit()) return wglSwapIntervalEXT(interval); return (BOOL)0;} + GLEEPFNWGLSWAPINTERVALEXTPROC GLeeFuncPtr_wglSwapIntervalEXT=GLee_Lazy_wglSwapIntervalEXT; +#endif +#ifndef GLEE_C_DEFINED_wglGetSwapIntervalEXT +#define GLEE_C_DEFINED_wglGetSwapIntervalEXT + int __stdcall GLee_Lazy_wglGetSwapIntervalEXT(void) {if (GLeeInit()) return wglGetSwapIntervalEXT(); return (int)0;} + GLEEPFNWGLGETSWAPINTERVALEXTPROC GLeeFuncPtr_wglGetSwapIntervalEXT=GLee_Lazy_wglGetSwapIntervalEXT; +#endif +#endif + +/* WGL_NV_vertex_array_range */ + +#ifdef __GLEE_WGL_NV_vertex_array_range +#ifndef GLEE_C_DEFINED_wglAllocateMemoryNV +#define GLEE_C_DEFINED_wglAllocateMemoryNV + void* __stdcall GLee_Lazy_wglAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority) {if (GLeeInit()) return wglAllocateMemoryNV(size, readfreq, writefreq, priority); return (void*)0;} + GLEEPFNWGLALLOCATEMEMORYNVPROC GLeeFuncPtr_wglAllocateMemoryNV=GLee_Lazy_wglAllocateMemoryNV; +#endif +#ifndef GLEE_C_DEFINED_wglFreeMemoryNV +#define GLEE_C_DEFINED_wglFreeMemoryNV + void __stdcall GLee_Lazy_wglFreeMemoryNV(void * pointer) {if (GLeeInit()) wglFreeMemoryNV(pointer);} + GLEEPFNWGLFREEMEMORYNVPROC GLeeFuncPtr_wglFreeMemoryNV=GLee_Lazy_wglFreeMemoryNV; +#endif +#endif + +/* WGL_OML_sync_control */ + +#ifdef __GLEE_WGL_OML_sync_control +#ifndef GLEE_C_DEFINED_wglGetSyncValuesOML +#define GLEE_C_DEFINED_wglGetSyncValuesOML + BOOL __stdcall GLee_Lazy_wglGetSyncValuesOML(HDC hdc, INT64 * ust, INT64 * msc, INT64 * sbc) {if (GLeeInit()) return wglGetSyncValuesOML(hdc, ust, msc, sbc); return (BOOL)0;} + GLEEPFNWGLGETSYNCVALUESOMLPROC GLeeFuncPtr_wglGetSyncValuesOML=GLee_Lazy_wglGetSyncValuesOML; +#endif +#ifndef GLEE_C_DEFINED_wglGetMscRateOML +#define GLEE_C_DEFINED_wglGetMscRateOML + BOOL __stdcall GLee_Lazy_wglGetMscRateOML(HDC hdc, INT32 * numerator, INT32 * denominator) {if (GLeeInit()) return wglGetMscRateOML(hdc, numerator, denominator); return (BOOL)0;} + GLEEPFNWGLGETMSCRATEOMLPROC GLeeFuncPtr_wglGetMscRateOML=GLee_Lazy_wglGetMscRateOML; +#endif +#ifndef GLEE_C_DEFINED_wglSwapBuffersMscOML +#define GLEE_C_DEFINED_wglSwapBuffersMscOML + INT64 __stdcall GLee_Lazy_wglSwapBuffersMscOML(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder) {if (GLeeInit()) return wglSwapBuffersMscOML(hdc, target_msc, divisor, remainder); return (INT64)0;} + GLEEPFNWGLSWAPBUFFERSMSCOMLPROC GLeeFuncPtr_wglSwapBuffersMscOML=GLee_Lazy_wglSwapBuffersMscOML; +#endif +#ifndef GLEE_C_DEFINED_wglSwapLayerBuffersMscOML +#define GLEE_C_DEFINED_wglSwapLayerBuffersMscOML + INT64 __stdcall GLee_Lazy_wglSwapLayerBuffersMscOML(HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder) {if (GLeeInit()) return wglSwapLayerBuffersMscOML(hdc, fuPlanes, target_msc, divisor, remainder); return (INT64)0;} + GLEEPFNWGLSWAPLAYERBUFFERSMSCOMLPROC GLeeFuncPtr_wglSwapLayerBuffersMscOML=GLee_Lazy_wglSwapLayerBuffersMscOML; +#endif +#ifndef GLEE_C_DEFINED_wglWaitForMscOML +#define GLEE_C_DEFINED_wglWaitForMscOML + BOOL __stdcall GLee_Lazy_wglWaitForMscOML(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 * ust, INT64 * msc, INT64 * sbc) {if (GLeeInit()) return wglWaitForMscOML(hdc, target_msc, divisor, remainder, ust, msc, sbc); return (BOOL)0;} + GLEEPFNWGLWAITFORMSCOMLPROC GLeeFuncPtr_wglWaitForMscOML=GLee_Lazy_wglWaitForMscOML; +#endif +#ifndef GLEE_C_DEFINED_wglWaitForSbcOML +#define GLEE_C_DEFINED_wglWaitForSbcOML + BOOL __stdcall GLee_Lazy_wglWaitForSbcOML(HDC hdc, INT64 target_sbc, INT64 * ust, INT64 * msc, INT64 * sbc) {if (GLeeInit()) return wglWaitForSbcOML(hdc, target_sbc, ust, msc, sbc); return (BOOL)0;} + GLEEPFNWGLWAITFORSBCOMLPROC GLeeFuncPtr_wglWaitForSbcOML=GLee_Lazy_wglWaitForSbcOML; +#endif +#endif + +/* WGL_I3D_swap_frame_usage */ + +#ifdef __GLEE_WGL_I3D_swap_frame_usage +#ifndef GLEE_C_DEFINED_wglGetFrameUsageI3D +#define GLEE_C_DEFINED_wglGetFrameUsageI3D + BOOL __stdcall GLee_Lazy_wglGetFrameUsageI3D(float * pUsage) {if (GLeeInit()) return wglGetFrameUsageI3D(pUsage); return (BOOL)0;} + GLEEPFNWGLGETFRAMEUSAGEI3DPROC GLeeFuncPtr_wglGetFrameUsageI3D=GLee_Lazy_wglGetFrameUsageI3D; +#endif +#ifndef GLEE_C_DEFINED_wglBeginFrameTrackingI3D +#define GLEE_C_DEFINED_wglBeginFrameTrackingI3D + BOOL __stdcall GLee_Lazy_wglBeginFrameTrackingI3D(void) {if (GLeeInit()) return wglBeginFrameTrackingI3D(); return (BOOL)0;} + GLEEPFNWGLBEGINFRAMETRACKINGI3DPROC GLeeFuncPtr_wglBeginFrameTrackingI3D=GLee_Lazy_wglBeginFrameTrackingI3D; +#endif +#ifndef GLEE_C_DEFINED_wglEndFrameTrackingI3D +#define GLEE_C_DEFINED_wglEndFrameTrackingI3D + BOOL __stdcall GLee_Lazy_wglEndFrameTrackingI3D(void) {if (GLeeInit()) return wglEndFrameTrackingI3D(); return (BOOL)0;} + GLEEPFNWGLENDFRAMETRACKINGI3DPROC GLeeFuncPtr_wglEndFrameTrackingI3D=GLee_Lazy_wglEndFrameTrackingI3D; +#endif +#ifndef GLEE_C_DEFINED_wglQueryFrameTrackingI3D +#define GLEE_C_DEFINED_wglQueryFrameTrackingI3D + BOOL __stdcall GLee_Lazy_wglQueryFrameTrackingI3D(DWORD * pFrameCount, DWORD * pMissedFrames, float * pLastMissedUsage) {if (GLeeInit()) return wglQueryFrameTrackingI3D(pFrameCount, pMissedFrames, pLastMissedUsage); return (BOOL)0;} + GLEEPFNWGLQUERYFRAMETRACKINGI3DPROC GLeeFuncPtr_wglQueryFrameTrackingI3D=GLee_Lazy_wglQueryFrameTrackingI3D; +#endif +#endif + +/* WGL_NV_video_output */ + +#ifdef __GLEE_WGL_NV_video_output +#ifndef GLEE_C_DEFINED_wglGetVideoDeviceNV +#define GLEE_C_DEFINED_wglGetVideoDeviceNV + BOOL __stdcall GLee_Lazy_wglGetVideoDeviceNV(HDC hDC, int numDevices, HPVIDEODEV * hVideoDevice) {if (GLeeInit()) return wglGetVideoDeviceNV(hDC, numDevices, hVideoDevice); return (BOOL)0;} + GLEEPFNWGLGETVIDEODEVICENVPROC GLeeFuncPtr_wglGetVideoDeviceNV=GLee_Lazy_wglGetVideoDeviceNV; +#endif +#ifndef GLEE_C_DEFINED_wglReleaseVideoDeviceNV +#define GLEE_C_DEFINED_wglReleaseVideoDeviceNV + BOOL __stdcall GLee_Lazy_wglReleaseVideoDeviceNV(HPVIDEODEV hVideoDevice) {if (GLeeInit()) return wglReleaseVideoDeviceNV(hVideoDevice); return (BOOL)0;} + GLEEPFNWGLRELEASEVIDEODEVICENVPROC GLeeFuncPtr_wglReleaseVideoDeviceNV=GLee_Lazy_wglReleaseVideoDeviceNV; +#endif +#ifndef GLEE_C_DEFINED_wglBindVideoImageNV +#define GLEE_C_DEFINED_wglBindVideoImageNV + BOOL __stdcall GLee_Lazy_wglBindVideoImageNV(HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer) {if (GLeeInit()) return wglBindVideoImageNV(hVideoDevice, hPbuffer, iVideoBuffer); return (BOOL)0;} + GLEEPFNWGLBINDVIDEOIMAGENVPROC GLeeFuncPtr_wglBindVideoImageNV=GLee_Lazy_wglBindVideoImageNV; +#endif +#ifndef GLEE_C_DEFINED_wglReleaseVideoImageNV +#define GLEE_C_DEFINED_wglReleaseVideoImageNV + BOOL __stdcall GLee_Lazy_wglReleaseVideoImageNV(HPBUFFERARB hPbuffer, int iVideoBuffer) {if (GLeeInit()) return wglReleaseVideoImageNV(hPbuffer, iVideoBuffer); return (BOOL)0;} + GLEEPFNWGLRELEASEVIDEOIMAGENVPROC GLeeFuncPtr_wglReleaseVideoImageNV=GLee_Lazy_wglReleaseVideoImageNV; +#endif +#ifndef GLEE_C_DEFINED_wglSendPbufferToVideoNV +#define GLEE_C_DEFINED_wglSendPbufferToVideoNV + BOOL __stdcall GLee_Lazy_wglSendPbufferToVideoNV(HPBUFFERARB hPbuffer, int iBufferType, unsigned long * pulCounterPbuffer, BOOL bBlock) {if (GLeeInit()) return wglSendPbufferToVideoNV(hPbuffer, iBufferType, pulCounterPbuffer, bBlock); return (BOOL)0;} + GLEEPFNWGLSENDPBUFFERTOVIDEONVPROC GLeeFuncPtr_wglSendPbufferToVideoNV=GLee_Lazy_wglSendPbufferToVideoNV; +#endif +#ifndef GLEE_C_DEFINED_wglGetVideoInfoNV +#define GLEE_C_DEFINED_wglGetVideoInfoNV + BOOL __stdcall GLee_Lazy_wglGetVideoInfoNV(HPVIDEODEV hpVideoDevice, unsigned long * pulCounterOutputPbuffer, unsigned long * pulCounterOutputVideo) {if (GLeeInit()) return wglGetVideoInfoNV(hpVideoDevice, pulCounterOutputPbuffer, pulCounterOutputVideo); return (BOOL)0;} + GLEEPFNWGLGETVIDEOINFONVPROC GLeeFuncPtr_wglGetVideoInfoNV=GLee_Lazy_wglGetVideoInfoNV; +#endif +#endif +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else /* GLX */ + +/* Extension querying variables */ + +GLboolean _GLEE_GLX_VERSION_1_3 = GL_FALSE; +GLboolean _GLEE_GLX_VERSION_1_4 = GL_FALSE; +GLboolean _GLEE_GLX_ARB_multisample = GL_FALSE; +GLboolean _GLEE_GLX_ARB_fbconfig_float = GL_FALSE; +GLboolean _GLEE_GLX_ARB_create_context = GL_FALSE; +GLboolean _GLEE_GLX_SGIS_multisample = GL_FALSE; +GLboolean _GLEE_GLX_EXT_visual_info = GL_FALSE; +GLboolean _GLEE_GLX_SGI_swap_control = GL_FALSE; +GLboolean _GLEE_GLX_SGI_video_sync = GL_FALSE; +GLboolean _GLEE_GLX_SGI_make_current_read = GL_FALSE; +GLboolean _GLEE_GLX_EXT_visual_rating = GL_FALSE; +GLboolean _GLEE_GLX_EXT_import_context = GL_FALSE; +GLboolean _GLEE_GLX_SGIX_fbconfig = GL_FALSE; +GLboolean _GLEE_GLX_SGIX_pbuffer = GL_FALSE; +GLboolean _GLEE_GLX_SGI_cushion = GL_FALSE; +GLboolean _GLEE_GLX_SGIX_video_resize = GL_FALSE; +GLboolean _GLEE_GLX_SGIX_swap_group = GL_FALSE; +GLboolean _GLEE_GLX_SGIX_swap_barrier = GL_FALSE; +GLboolean _GLEE_GLX_SGIS_blended_overlay = GL_FALSE; +GLboolean _GLEE_GLX_SGIS_shared_multisample = GL_FALSE; +GLboolean _GLEE_GLX_SUN_get_transparent_index = GL_FALSE; +GLboolean _GLEE_GLX_3DFX_multisample = GL_FALSE; +GLboolean _GLEE_GLX_MESA_copy_sub_buffer = GL_FALSE; +GLboolean _GLEE_GLX_MESA_pixmap_colormap = GL_FALSE; +GLboolean _GLEE_GLX_MESA_release_buffers = GL_FALSE; +GLboolean _GLEE_GLX_MESA_set_3dfx_mode = GL_FALSE; +GLboolean _GLEE_GLX_SGIX_visual_select_group = GL_FALSE; +GLboolean _GLEE_GLX_OML_swap_method = GL_FALSE; +GLboolean _GLEE_GLX_OML_sync_control = GL_FALSE; +GLboolean _GLEE_GLX_NV_float_buffer = GL_FALSE; +GLboolean _GLEE_GLX_SGIX_hyperpipe = GL_FALSE; +GLboolean _GLEE_GLX_MESA_agp_offset = GL_FALSE; +GLboolean _GLEE_GLX_EXT_fbconfig_packed_float = GL_FALSE; +GLboolean _GLEE_GLX_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean _GLEE_GLX_EXT_texture_from_pixmap = GL_FALSE; +GLboolean _GLEE_GLX_NV_present_video = GL_FALSE; +GLboolean _GLEE_GLX_NV_video_out = GL_FALSE; +GLboolean _GLEE_GLX_NV_swap_group = GL_FALSE; +GLboolean _GLEE_GLX_EXT_scene_marker = GL_FALSE; +GLboolean _GLEE_GLX_NV_video_output = GL_FALSE; + +/* GLX Extension names */ + +char __GLeeGLXExtensionNames[40][30]={ + "GLX_VERSION_1_3", + "GLX_VERSION_1_4", + "GLX_ARB_multisample", + "GLX_ARB_fbconfig_float", + "GLX_ARB_create_context", + "GLX_SGIS_multisample", + "GLX_EXT_visual_info", + "GLX_SGI_swap_control", + "GLX_SGI_video_sync", + "GLX_SGI_make_current_read", + "GLX_EXT_visual_rating", + "GLX_EXT_import_context", + "GLX_SGIX_fbconfig", + "GLX_SGIX_pbuffer", + "GLX_SGI_cushion", + "GLX_SGIX_video_resize", + "GLX_SGIX_swap_group", + "GLX_SGIX_swap_barrier", + "GLX_SGIS_blended_overlay", + "GLX_SGIS_shared_multisample", + "GLX_SUN_get_transparent_index", + "GLX_3DFX_multisample", + "GLX_MESA_copy_sub_buffer", + "GLX_MESA_pixmap_colormap", + "GLX_MESA_release_buffers", + "GLX_MESA_set_3dfx_mode", + "GLX_SGIX_visual_select_group", + "GLX_OML_swap_method", + "GLX_OML_sync_control", + "GLX_NV_float_buffer", + "GLX_SGIX_hyperpipe", + "GLX_MESA_agp_offset", + "GLX_EXT_fbconfig_packed_float", + "GLX_EXT_framebuffer_sRGB", + "GLX_EXT_texture_from_pixmap", + "GLX_NV_present_video", + "GLX_NV_video_out", + "GLX_NV_swap_group", + "GLX_EXT_scene_marker", + "GLX_NV_video_output" +}; +int __GLeeGLXNumExtensions=40; + +/* GLX_VERSION_1_3 */ + +#ifdef __GLEE_GLX_VERSION_1_3 +#ifndef GLEE_C_DEFINED_glXGetFBConfigs +#define GLEE_C_DEFINED_glXGetFBConfigs + GLXFBConfig * __stdcall GLee_Lazy_glXGetFBConfigs(Display * dpy, int screen, int * nelements) {if (GLeeInit()) return glXGetFBConfigs(dpy, screen, nelements); return (GLXFBConfig *)0;} + GLEEPFNGLXGETFBCONFIGSPROC GLeeFuncPtr_glXGetFBConfigs=GLee_Lazy_glXGetFBConfigs; +#endif +#ifndef GLEE_C_DEFINED_glXChooseFBConfig +#define GLEE_C_DEFINED_glXChooseFBConfig + GLXFBConfig * __stdcall GLee_Lazy_glXChooseFBConfig(Display * dpy, int screen, const int * attrib_list, int * nelements) {if (GLeeInit()) return glXChooseFBConfig(dpy, screen, attrib_list, nelements); return (GLXFBConfig *)0;} + GLEEPFNGLXCHOOSEFBCONFIGPROC GLeeFuncPtr_glXChooseFBConfig=GLee_Lazy_glXChooseFBConfig; +#endif +#ifndef GLEE_C_DEFINED_glXGetFBConfigAttrib +#define GLEE_C_DEFINED_glXGetFBConfigAttrib + int __stdcall GLee_Lazy_glXGetFBConfigAttrib(Display * dpy, GLXFBConfig config, int attribute, int * value) {if (GLeeInit()) return glXGetFBConfigAttrib(dpy, config, attribute, value); return (int)0;} + GLEEPFNGLXGETFBCONFIGATTRIBPROC GLeeFuncPtr_glXGetFBConfigAttrib=GLee_Lazy_glXGetFBConfigAttrib; +#endif +#ifndef GLEE_C_DEFINED_glXGetVisualFromFBConfig +#define GLEE_C_DEFINED_glXGetVisualFromFBConfig + XVisualInfo * __stdcall GLee_Lazy_glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config) {if (GLeeInit()) return glXGetVisualFromFBConfig(dpy, config); return (XVisualInfo *)0;} + GLEEPFNGLXGETVISUALFROMFBCONFIGPROC GLeeFuncPtr_glXGetVisualFromFBConfig=GLee_Lazy_glXGetVisualFromFBConfig; +#endif +#ifndef GLEE_C_DEFINED_glXCreateWindow +#define GLEE_C_DEFINED_glXCreateWindow + GLXWindow __stdcall GLee_Lazy_glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, const int * attrib_list) {if (GLeeInit()) return glXCreateWindow(dpy, config, win, attrib_list); return (GLXWindow)0;} + GLEEPFNGLXCREATEWINDOWPROC GLeeFuncPtr_glXCreateWindow=GLee_Lazy_glXCreateWindow; +#endif +#ifndef GLEE_C_DEFINED_glXDestroyWindow +#define GLEE_C_DEFINED_glXDestroyWindow + void __stdcall GLee_Lazy_glXDestroyWindow(Display * dpy, GLXWindow win) {if (GLeeInit()) glXDestroyWindow(dpy, win);} + GLEEPFNGLXDESTROYWINDOWPROC GLeeFuncPtr_glXDestroyWindow=GLee_Lazy_glXDestroyWindow; +#endif +#ifndef GLEE_C_DEFINED_glXCreatePixmap +#define GLEE_C_DEFINED_glXCreatePixmap + GLXPixmap __stdcall GLee_Lazy_glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list) {if (GLeeInit()) return glXCreatePixmap(dpy, config, pixmap, attrib_list); return (GLXPixmap)0;} + GLEEPFNGLXCREATEPIXMAPPROC GLeeFuncPtr_glXCreatePixmap=GLee_Lazy_glXCreatePixmap; +#endif +#ifndef GLEE_C_DEFINED_glXDestroyPixmap +#define GLEE_C_DEFINED_glXDestroyPixmap + void __stdcall GLee_Lazy_glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) {if (GLeeInit()) glXDestroyPixmap(dpy, pixmap);} + GLEEPFNGLXDESTROYPIXMAPPROC GLeeFuncPtr_glXDestroyPixmap=GLee_Lazy_glXDestroyPixmap; +#endif +#ifndef GLEE_C_DEFINED_glXCreatePbuffer +#define GLEE_C_DEFINED_glXCreatePbuffer + GLXPbuffer __stdcall GLee_Lazy_glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int * attrib_list) {if (GLeeInit()) return glXCreatePbuffer(dpy, config, attrib_list); return (GLXPbuffer)0;} + GLEEPFNGLXCREATEPBUFFERPROC GLeeFuncPtr_glXCreatePbuffer=GLee_Lazy_glXCreatePbuffer; +#endif +#ifndef GLEE_C_DEFINED_glXDestroyPbuffer +#define GLEE_C_DEFINED_glXDestroyPbuffer + void __stdcall GLee_Lazy_glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) {if (GLeeInit()) glXDestroyPbuffer(dpy, pbuf);} + GLEEPFNGLXDESTROYPBUFFERPROC GLeeFuncPtr_glXDestroyPbuffer=GLee_Lazy_glXDestroyPbuffer; +#endif +#ifndef GLEE_C_DEFINED_glXQueryDrawable +#define GLEE_C_DEFINED_glXQueryDrawable + void __stdcall GLee_Lazy_glXQueryDrawable(Display * dpy, GLXDrawable draw, int attribute, unsigned int * value) {if (GLeeInit()) glXQueryDrawable(dpy, draw, attribute, value);} + GLEEPFNGLXQUERYDRAWABLEPROC GLeeFuncPtr_glXQueryDrawable=GLee_Lazy_glXQueryDrawable; +#endif +#ifndef GLEE_C_DEFINED_glXCreateNewContext +#define GLEE_C_DEFINED_glXCreateNewContext + GLXContext __stdcall GLee_Lazy_glXCreateNewContext(Display * dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct) {if (GLeeInit()) return glXCreateNewContext(dpy, config, render_type, share_list, direct); return (GLXContext)0;} + GLEEPFNGLXCREATENEWCONTEXTPROC GLeeFuncPtr_glXCreateNewContext=GLee_Lazy_glXCreateNewContext; +#endif +#ifndef GLEE_C_DEFINED_glXMakeContextCurrent +#define GLEE_C_DEFINED_glXMakeContextCurrent + Bool __stdcall GLee_Lazy_glXMakeContextCurrent(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) {if (GLeeInit()) return glXMakeContextCurrent(dpy, draw, read, ctx); return (Bool)0;} + GLEEPFNGLXMAKECONTEXTCURRENTPROC GLeeFuncPtr_glXMakeContextCurrent=GLee_Lazy_glXMakeContextCurrent; +#endif +#ifndef GLEE_C_DEFINED_glXGetCurrentReadDrawable +#define GLEE_C_DEFINED_glXGetCurrentReadDrawable + GLXDrawable __stdcall GLee_Lazy_glXGetCurrentReadDrawable(void) {if (GLeeInit()) return glXGetCurrentReadDrawable(); return (GLXDrawable)0;} + GLEEPFNGLXGETCURRENTREADDRAWABLEPROC GLeeFuncPtr_glXGetCurrentReadDrawable=GLee_Lazy_glXGetCurrentReadDrawable; +#endif +#ifndef GLEE_C_DEFINED_glXGetCurrentDisplay +#define GLEE_C_DEFINED_glXGetCurrentDisplay + Display * __stdcall GLee_Lazy_glXGetCurrentDisplay(void) {if (GLeeInit()) return glXGetCurrentDisplay(); return (Display *)0;} + GLEEPFNGLXGETCURRENTDISPLAYPROC GLeeFuncPtr_glXGetCurrentDisplay=GLee_Lazy_glXGetCurrentDisplay; +#endif +#ifndef GLEE_C_DEFINED_glXQueryContext +#define GLEE_C_DEFINED_glXQueryContext + int __stdcall GLee_Lazy_glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int * value) {if (GLeeInit()) return glXQueryContext(dpy, ctx, attribute, value); return (int)0;} + GLEEPFNGLXQUERYCONTEXTPROC GLeeFuncPtr_glXQueryContext=GLee_Lazy_glXQueryContext; +#endif +#ifndef GLEE_C_DEFINED_glXSelectEvent +#define GLEE_C_DEFINED_glXSelectEvent + void __stdcall GLee_Lazy_glXSelectEvent(Display * dpy, GLXDrawable draw, unsigned long event_mask) {if (GLeeInit()) glXSelectEvent(dpy, draw, event_mask);} + GLEEPFNGLXSELECTEVENTPROC GLeeFuncPtr_glXSelectEvent=GLee_Lazy_glXSelectEvent; +#endif +#ifndef GLEE_C_DEFINED_glXGetSelectedEvent +#define GLEE_C_DEFINED_glXGetSelectedEvent + void __stdcall GLee_Lazy_glXGetSelectedEvent(Display * dpy, GLXDrawable draw, unsigned long * event_mask) {if (GLeeInit()) glXGetSelectedEvent(dpy, draw, event_mask);} + GLEEPFNGLXGETSELECTEDEVENTPROC GLeeFuncPtr_glXGetSelectedEvent=GLee_Lazy_glXGetSelectedEvent; +#endif +#endif + +/* GLX_VERSION_1_4 */ + +#ifdef __GLEE_GLX_VERSION_1_4 +#ifndef GLEE_C_DEFINED_glXGetProcAddress +#define GLEE_C_DEFINED_glXGetProcAddress + __GLXextFuncPtr __stdcall GLee_Lazy_glXGetProcAddress(const GLubyte * procName) {if (GLeeInit()) return glXGetProcAddress(procName); return (__GLXextFuncPtr)0;} + GLEEPFNGLXGETPROCADDRESSPROC GLeeFuncPtr_glXGetProcAddress=GLee_Lazy_glXGetProcAddress; +#endif +#endif + +/* GLX_ARB_multisample */ + +#ifdef __GLEE_GLX_ARB_multisample +#endif + +/* GLX_ARB_fbconfig_float */ + +#ifdef __GLEE_GLX_ARB_fbconfig_float +#endif + +/* GLX_ARB_create_context */ + +#ifdef __GLEE_GLX_ARB_create_context +#ifndef GLEE_C_DEFINED_glXCreateContextAttribsARB +#define GLEE_C_DEFINED_glXCreateContextAttribsARB + GLXContext __stdcall GLee_Lazy_glXCreateContextAttribsARB(Display * dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int * attrib_list) {if (GLeeInit()) return glXCreateContextAttribsARB(dpy, config, share_context, direct, attrib_list); return (GLXContext)0;} + GLEEPFNGLXCREATECONTEXTATTRIBSARBPROC GLeeFuncPtr_glXCreateContextAttribsARB=GLee_Lazy_glXCreateContextAttribsARB; +#endif +#endif + +/* GLX_SGIS_multisample */ + +#ifdef __GLEE_GLX_SGIS_multisample +#endif + +/* GLX_EXT_visual_info */ + +#ifdef __GLEE_GLX_EXT_visual_info +#endif + +/* GLX_SGI_swap_control */ + +#ifdef __GLEE_GLX_SGI_swap_control +#ifndef GLEE_C_DEFINED_glXSwapIntervalSGI +#define GLEE_C_DEFINED_glXSwapIntervalSGI + int __stdcall GLee_Lazy_glXSwapIntervalSGI(int interval) {if (GLeeInit()) return glXSwapIntervalSGI(interval); return (int)0;} + GLEEPFNGLXSWAPINTERVALSGIPROC GLeeFuncPtr_glXSwapIntervalSGI=GLee_Lazy_glXSwapIntervalSGI; +#endif +#endif + +/* GLX_SGI_video_sync */ + +#ifdef __GLEE_GLX_SGI_video_sync +#ifndef GLEE_C_DEFINED_glXGetVideoSyncSGI +#define GLEE_C_DEFINED_glXGetVideoSyncSGI + int __stdcall GLee_Lazy_glXGetVideoSyncSGI(unsigned int * count) {if (GLeeInit()) return glXGetVideoSyncSGI(count); return (int)0;} + GLEEPFNGLXGETVIDEOSYNCSGIPROC GLeeFuncPtr_glXGetVideoSyncSGI=GLee_Lazy_glXGetVideoSyncSGI; +#endif +#ifndef GLEE_C_DEFINED_glXWaitVideoSyncSGI +#define GLEE_C_DEFINED_glXWaitVideoSyncSGI + int __stdcall GLee_Lazy_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int * count) {if (GLeeInit()) return glXWaitVideoSyncSGI(divisor, remainder, count); return (int)0;} + GLEEPFNGLXWAITVIDEOSYNCSGIPROC GLeeFuncPtr_glXWaitVideoSyncSGI=GLee_Lazy_glXWaitVideoSyncSGI; +#endif +#endif + +/* GLX_SGI_make_current_read */ + +#ifdef __GLEE_GLX_SGI_make_current_read +#ifndef GLEE_C_DEFINED_glXMakeCurrentReadSGI +#define GLEE_C_DEFINED_glXMakeCurrentReadSGI + Bool __stdcall GLee_Lazy_glXMakeCurrentReadSGI(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) {if (GLeeInit()) return glXMakeCurrentReadSGI(dpy, draw, read, ctx); return (Bool)0;} + GLEEPFNGLXMAKECURRENTREADSGIPROC GLeeFuncPtr_glXMakeCurrentReadSGI=GLee_Lazy_glXMakeCurrentReadSGI; +#endif +#ifndef GLEE_C_DEFINED_glXGetCurrentReadDrawableSGI +#define GLEE_C_DEFINED_glXGetCurrentReadDrawableSGI + GLXDrawable __stdcall GLee_Lazy_glXGetCurrentReadDrawableSGI(void) {if (GLeeInit()) return glXGetCurrentReadDrawableSGI(); return (GLXDrawable)0;} + GLEEPFNGLXGETCURRENTREADDRAWABLESGIPROC GLeeFuncPtr_glXGetCurrentReadDrawableSGI=GLee_Lazy_glXGetCurrentReadDrawableSGI; +#endif +#endif + +/* GLX_EXT_visual_rating */ + +#ifdef __GLEE_GLX_EXT_visual_rating +#endif + +/* GLX_EXT_import_context */ + +#ifdef __GLEE_GLX_EXT_import_context +#ifndef GLEE_C_DEFINED_glXGetCurrentDisplayEXT +#define GLEE_C_DEFINED_glXGetCurrentDisplayEXT + Display * __stdcall GLee_Lazy_glXGetCurrentDisplayEXT(void) {if (GLeeInit()) return glXGetCurrentDisplayEXT(); return (Display *)0;} + GLEEPFNGLXGETCURRENTDISPLAYEXTPROC GLeeFuncPtr_glXGetCurrentDisplayEXT=GLee_Lazy_glXGetCurrentDisplayEXT; +#endif +#ifndef GLEE_C_DEFINED_glXQueryContextInfoEXT +#define GLEE_C_DEFINED_glXQueryContextInfoEXT + int __stdcall GLee_Lazy_glXQueryContextInfoEXT(Display * dpy, GLXContext context, int attribute, int * value) {if (GLeeInit()) return glXQueryContextInfoEXT(dpy, context, attribute, value); return (int)0;} + GLEEPFNGLXQUERYCONTEXTINFOEXTPROC GLeeFuncPtr_glXQueryContextInfoEXT=GLee_Lazy_glXQueryContextInfoEXT; +#endif +#ifndef GLEE_C_DEFINED_glXGetContextIDEXT +#define GLEE_C_DEFINED_glXGetContextIDEXT + GLXContextID __stdcall GLee_Lazy_glXGetContextIDEXT(const GLXContext context) {if (GLeeInit()) return glXGetContextIDEXT(context); return (GLXContextID)0;} + GLEEPFNGLXGETCONTEXTIDEXTPROC GLeeFuncPtr_glXGetContextIDEXT=GLee_Lazy_glXGetContextIDEXT; +#endif +#ifndef GLEE_C_DEFINED_glXImportContextEXT +#define GLEE_C_DEFINED_glXImportContextEXT + GLXContext __stdcall GLee_Lazy_glXImportContextEXT(Display * dpy, GLXContextID contextID) {if (GLeeInit()) return glXImportContextEXT(dpy, contextID); return (GLXContext)0;} + GLEEPFNGLXIMPORTCONTEXTEXTPROC GLeeFuncPtr_glXImportContextEXT=GLee_Lazy_glXImportContextEXT; +#endif +#ifndef GLEE_C_DEFINED_glXFreeContextEXT +#define GLEE_C_DEFINED_glXFreeContextEXT + void __stdcall GLee_Lazy_glXFreeContextEXT(Display * dpy, GLXContext context) {if (GLeeInit()) glXFreeContextEXT(dpy, context);} + GLEEPFNGLXFREECONTEXTEXTPROC GLeeFuncPtr_glXFreeContextEXT=GLee_Lazy_glXFreeContextEXT; +#endif +#endif + +/* GLX_SGIX_fbconfig */ + +#ifdef __GLEE_GLX_SGIX_fbconfig +#ifndef GLEE_C_DEFINED_glXGetFBConfigAttribSGIX +#define GLEE_C_DEFINED_glXGetFBConfigAttribSGIX + int __stdcall GLee_Lazy_glXGetFBConfigAttribSGIX(Display * dpy, GLXFBConfigSGIX config, int attribute, int * value) {if (GLeeInit()) return glXGetFBConfigAttribSGIX(dpy, config, attribute, value); return (int)0;} + GLEEPFNGLXGETFBCONFIGATTRIBSGIXPROC GLeeFuncPtr_glXGetFBConfigAttribSGIX=GLee_Lazy_glXGetFBConfigAttribSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXChooseFBConfigSGIX +#define GLEE_C_DEFINED_glXChooseFBConfigSGIX + GLXFBConfigSGIX * __stdcall GLee_Lazy_glXChooseFBConfigSGIX(Display * dpy, int screen, int * attrib_list, int * nelements) {if (GLeeInit()) return glXChooseFBConfigSGIX(dpy, screen, attrib_list, nelements); return (GLXFBConfigSGIX *)0;} + GLEEPFNGLXCHOOSEFBCONFIGSGIXPROC GLeeFuncPtr_glXChooseFBConfigSGIX=GLee_Lazy_glXChooseFBConfigSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXCreateGLXPixmapWithConfigSGIX +#define GLEE_C_DEFINED_glXCreateGLXPixmapWithConfigSGIX + GLXPixmap __stdcall GLee_Lazy_glXCreateGLXPixmapWithConfigSGIX(Display * dpy, GLXFBConfigSGIX config, Pixmap pixmap) {if (GLeeInit()) return glXCreateGLXPixmapWithConfigSGIX(dpy, config, pixmap); return (GLXPixmap)0;} + GLEEPFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC GLeeFuncPtr_glXCreateGLXPixmapWithConfigSGIX=GLee_Lazy_glXCreateGLXPixmapWithConfigSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXCreateContextWithConfigSGIX +#define GLEE_C_DEFINED_glXCreateContextWithConfigSGIX + GLXContext __stdcall GLee_Lazy_glXCreateContextWithConfigSGIX(Display * dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) {if (GLeeInit()) return glXCreateContextWithConfigSGIX(dpy, config, render_type, share_list, direct); return (GLXContext)0;} + GLEEPFNGLXCREATECONTEXTWITHCONFIGSGIXPROC GLeeFuncPtr_glXCreateContextWithConfigSGIX=GLee_Lazy_glXCreateContextWithConfigSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXGetVisualFromFBConfigSGIX +#define GLEE_C_DEFINED_glXGetVisualFromFBConfigSGIX + XVisualInfo * __stdcall GLee_Lazy_glXGetVisualFromFBConfigSGIX(Display * dpy, GLXFBConfigSGIX config) {if (GLeeInit()) return glXGetVisualFromFBConfigSGIX(dpy, config); return (XVisualInfo *)0;} + GLEEPFNGLXGETVISUALFROMFBCONFIGSGIXPROC GLeeFuncPtr_glXGetVisualFromFBConfigSGIX=GLee_Lazy_glXGetVisualFromFBConfigSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXGetFBConfigFromVisualSGIX +#define GLEE_C_DEFINED_glXGetFBConfigFromVisualSGIX + GLXFBConfigSGIX __stdcall GLee_Lazy_glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis) {if (GLeeInit()) return glXGetFBConfigFromVisualSGIX(dpy, vis); return (GLXFBConfigSGIX)0;} + GLEEPFNGLXGETFBCONFIGFROMVISUALSGIXPROC GLeeFuncPtr_glXGetFBConfigFromVisualSGIX=GLee_Lazy_glXGetFBConfigFromVisualSGIX; +#endif +#endif + +/* GLX_SGIX_pbuffer */ + +#ifdef __GLEE_GLX_SGIX_pbuffer +#ifndef GLEE_C_DEFINED_glXCreateGLXPbufferSGIX +#define GLEE_C_DEFINED_glXCreateGLXPbufferSGIX + GLXPbufferSGIX __stdcall GLee_Lazy_glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int * attrib_list) {if (GLeeInit()) return glXCreateGLXPbufferSGIX(dpy, config, width, height, attrib_list); return (GLXPbufferSGIX)0;} + GLEEPFNGLXCREATEGLXPBUFFERSGIXPROC GLeeFuncPtr_glXCreateGLXPbufferSGIX=GLee_Lazy_glXCreateGLXPbufferSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXDestroyGLXPbufferSGIX +#define GLEE_C_DEFINED_glXDestroyGLXPbufferSGIX + void __stdcall GLee_Lazy_glXDestroyGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX pbuf) {if (GLeeInit()) glXDestroyGLXPbufferSGIX(dpy, pbuf);} + GLEEPFNGLXDESTROYGLXPBUFFERSGIXPROC GLeeFuncPtr_glXDestroyGLXPbufferSGIX=GLee_Lazy_glXDestroyGLXPbufferSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXQueryGLXPbufferSGIX +#define GLEE_C_DEFINED_glXQueryGLXPbufferSGIX + int __stdcall GLee_Lazy_glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int * value) {if (GLeeInit()) return glXQueryGLXPbufferSGIX(dpy, pbuf, attribute, value); return (int)0;} + GLEEPFNGLXQUERYGLXPBUFFERSGIXPROC GLeeFuncPtr_glXQueryGLXPbufferSGIX=GLee_Lazy_glXQueryGLXPbufferSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXSelectEventSGIX +#define GLEE_C_DEFINED_glXSelectEventSGIX + void __stdcall GLee_Lazy_glXSelectEventSGIX(Display * dpy, GLXDrawable drawable, unsigned long mask) {if (GLeeInit()) glXSelectEventSGIX(dpy, drawable, mask);} + GLEEPFNGLXSELECTEVENTSGIXPROC GLeeFuncPtr_glXSelectEventSGIX=GLee_Lazy_glXSelectEventSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXGetSelectedEventSGIX +#define GLEE_C_DEFINED_glXGetSelectedEventSGIX + void __stdcall GLee_Lazy_glXGetSelectedEventSGIX(Display * dpy, GLXDrawable drawable, unsigned long * mask) {if (GLeeInit()) glXGetSelectedEventSGIX(dpy, drawable, mask);} + GLEEPFNGLXGETSELECTEDEVENTSGIXPROC GLeeFuncPtr_glXGetSelectedEventSGIX=GLee_Lazy_glXGetSelectedEventSGIX; +#endif +#endif + +/* GLX_SGI_cushion */ + +#ifdef __GLEE_GLX_SGI_cushion +#ifndef GLEE_C_DEFINED_glXCushionSGI +#define GLEE_C_DEFINED_glXCushionSGI + void __stdcall GLee_Lazy_glXCushionSGI(Display * dpy, Window window, float cushion) {if (GLeeInit()) glXCushionSGI(dpy, window, cushion);} + GLEEPFNGLXCUSHIONSGIPROC GLeeFuncPtr_glXCushionSGI=GLee_Lazy_glXCushionSGI; +#endif +#endif + +/* GLX_SGIX_video_resize */ + +#ifdef __GLEE_GLX_SGIX_video_resize +#ifndef GLEE_C_DEFINED_glXBindChannelToWindowSGIX +#define GLEE_C_DEFINED_glXBindChannelToWindowSGIX + int __stdcall GLee_Lazy_glXBindChannelToWindowSGIX(Display * display, int screen, int channel, Window window) {if (GLeeInit()) return glXBindChannelToWindowSGIX(display, screen, channel, window); return (int)0;} + GLEEPFNGLXBINDCHANNELTOWINDOWSGIXPROC GLeeFuncPtr_glXBindChannelToWindowSGIX=GLee_Lazy_glXBindChannelToWindowSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXChannelRectSGIX +#define GLEE_C_DEFINED_glXChannelRectSGIX + int __stdcall GLee_Lazy_glXChannelRectSGIX(Display * display, int screen, int channel, int x, int y, int w, int h) {if (GLeeInit()) return glXChannelRectSGIX(display, screen, channel, x, y, w, h); return (int)0;} + GLEEPFNGLXCHANNELRECTSGIXPROC GLeeFuncPtr_glXChannelRectSGIX=GLee_Lazy_glXChannelRectSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXQueryChannelRectSGIX +#define GLEE_C_DEFINED_glXQueryChannelRectSGIX + int __stdcall GLee_Lazy_glXQueryChannelRectSGIX(Display * display, int screen, int channel, int * dx, int * dy, int * dw, int * dh) {if (GLeeInit()) return glXQueryChannelRectSGIX(display, screen, channel, dx, dy, dw, dh); return (int)0;} + GLEEPFNGLXQUERYCHANNELRECTSGIXPROC GLeeFuncPtr_glXQueryChannelRectSGIX=GLee_Lazy_glXQueryChannelRectSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXQueryChannelDeltasSGIX +#define GLEE_C_DEFINED_glXQueryChannelDeltasSGIX + int __stdcall GLee_Lazy_glXQueryChannelDeltasSGIX(Display * display, int screen, int channel, int * x, int * y, int * w, int * h) {if (GLeeInit()) return glXQueryChannelDeltasSGIX(display, screen, channel, x, y, w, h); return (int)0;} + GLEEPFNGLXQUERYCHANNELDELTASSGIXPROC GLeeFuncPtr_glXQueryChannelDeltasSGIX=GLee_Lazy_glXQueryChannelDeltasSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXChannelRectSyncSGIX +#define GLEE_C_DEFINED_glXChannelRectSyncSGIX + int __stdcall GLee_Lazy_glXChannelRectSyncSGIX(Display * display, int screen, int channel, GLenum synctype) {if (GLeeInit()) return glXChannelRectSyncSGIX(display, screen, channel, synctype); return (int)0;} + GLEEPFNGLXCHANNELRECTSYNCSGIXPROC GLeeFuncPtr_glXChannelRectSyncSGIX=GLee_Lazy_glXChannelRectSyncSGIX; +#endif +#endif + +/* GLX_SGIX_swap_group */ + +#ifdef __GLEE_GLX_SGIX_swap_group +#ifndef GLEE_C_DEFINED_glXJoinSwapGroupSGIX +#define GLEE_C_DEFINED_glXJoinSwapGroupSGIX + void __stdcall GLee_Lazy_glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable, GLXDrawable member) {if (GLeeInit()) glXJoinSwapGroupSGIX(dpy, drawable, member);} + GLEEPFNGLXJOINSWAPGROUPSGIXPROC GLeeFuncPtr_glXJoinSwapGroupSGIX=GLee_Lazy_glXJoinSwapGroupSGIX; +#endif +#endif + +/* GLX_SGIX_swap_barrier */ + +#ifdef __GLEE_GLX_SGIX_swap_barrier +#ifndef GLEE_C_DEFINED_glXBindSwapBarrierSGIX +#define GLEE_C_DEFINED_glXBindSwapBarrierSGIX + void __stdcall GLee_Lazy_glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier) {if (GLeeInit()) glXBindSwapBarrierSGIX(dpy, drawable, barrier);} + GLEEPFNGLXBINDSWAPBARRIERSGIXPROC GLeeFuncPtr_glXBindSwapBarrierSGIX=GLee_Lazy_glXBindSwapBarrierSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXQueryMaxSwapBarriersSGIX +#define GLEE_C_DEFINED_glXQueryMaxSwapBarriersSGIX + Bool __stdcall GLee_Lazy_glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int * max) {if (GLeeInit()) return glXQueryMaxSwapBarriersSGIX(dpy, screen, max); return (Bool)0;} + GLEEPFNGLXQUERYMAXSWAPBARRIERSSGIXPROC GLeeFuncPtr_glXQueryMaxSwapBarriersSGIX=GLee_Lazy_glXQueryMaxSwapBarriersSGIX; +#endif +#endif + +/* GLX_SGIS_blended_overlay */ + +#ifdef __GLEE_GLX_SGIS_blended_overlay +#endif + +/* GLX_SGIS_shared_multisample */ + +#ifdef __GLEE_GLX_SGIS_shared_multisample +#endif + +/* GLX_SUN_get_transparent_index */ + +#ifdef __GLEE_GLX_SUN_get_transparent_index +#ifndef GLEE_C_DEFINED_glXGetTransparentIndexSUN +#define GLEE_C_DEFINED_glXGetTransparentIndexSUN + Status __stdcall GLee_Lazy_glXGetTransparentIndexSUN(Display * dpy, Window overlay, Window underlay, long * pTransparentIndex) {if (GLeeInit()) return glXGetTransparentIndexSUN(dpy, overlay, underlay, pTransparentIndex); return (Status)0;} + GLEEPFNGLXGETTRANSPARENTINDEXSUNPROC GLeeFuncPtr_glXGetTransparentIndexSUN=GLee_Lazy_glXGetTransparentIndexSUN; +#endif +#endif + +/* GLX_3DFX_multisample */ + +#ifdef __GLEE_GLX_3DFX_multisample +#endif + +/* GLX_MESA_copy_sub_buffer */ + +#ifdef __GLEE_GLX_MESA_copy_sub_buffer +#ifndef GLEE_C_DEFINED_glXCopySubBufferMESA +#define GLEE_C_DEFINED_glXCopySubBufferMESA + void __stdcall GLee_Lazy_glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, int x, int y, int width, int height) {if (GLeeInit()) glXCopySubBufferMESA(dpy, drawable, x, y, width, height);} + GLEEPFNGLXCOPYSUBBUFFERMESAPROC GLeeFuncPtr_glXCopySubBufferMESA=GLee_Lazy_glXCopySubBufferMESA; +#endif +#endif + +/* GLX_MESA_pixmap_colormap */ + +#ifdef __GLEE_GLX_MESA_pixmap_colormap +#ifndef GLEE_C_DEFINED_glXCreateGLXPixmapMESA +#define GLEE_C_DEFINED_glXCreateGLXPixmapMESA + GLXPixmap __stdcall GLee_Lazy_glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual, Pixmap pixmap, Colormap cmap) {if (GLeeInit()) return glXCreateGLXPixmapMESA(dpy, visual, pixmap, cmap); return (GLXPixmap)0;} + GLEEPFNGLXCREATEGLXPIXMAPMESAPROC GLeeFuncPtr_glXCreateGLXPixmapMESA=GLee_Lazy_glXCreateGLXPixmapMESA; +#endif +#endif + +/* GLX_MESA_release_buffers */ + +#ifdef __GLEE_GLX_MESA_release_buffers +#ifndef GLEE_C_DEFINED_glXReleaseBuffersMESA +#define GLEE_C_DEFINED_glXReleaseBuffersMESA + Bool __stdcall GLee_Lazy_glXReleaseBuffersMESA(Display * dpy, GLXDrawable drawable) {if (GLeeInit()) return glXReleaseBuffersMESA(dpy, drawable); return (Bool)0;} + GLEEPFNGLXRELEASEBUFFERSMESAPROC GLeeFuncPtr_glXReleaseBuffersMESA=GLee_Lazy_glXReleaseBuffersMESA; +#endif +#endif + +/* GLX_MESA_set_3dfx_mode */ + +#ifdef __GLEE_GLX_MESA_set_3dfx_mode +#ifndef GLEE_C_DEFINED_glXSet3DfxModeMESA +#define GLEE_C_DEFINED_glXSet3DfxModeMESA + Bool __stdcall GLee_Lazy_glXSet3DfxModeMESA(int mode) {if (GLeeInit()) return glXSet3DfxModeMESA(mode); return (Bool)0;} + GLEEPFNGLXSET3DFXMODEMESAPROC GLeeFuncPtr_glXSet3DfxModeMESA=GLee_Lazy_glXSet3DfxModeMESA; +#endif +#endif + +/* GLX_SGIX_visual_select_group */ + +#ifdef __GLEE_GLX_SGIX_visual_select_group +#endif + +/* GLX_OML_swap_method */ + +#ifdef __GLEE_GLX_OML_swap_method +#endif + +/* GLX_OML_sync_control */ + +#ifdef __GLEE_GLX_OML_sync_control +#ifndef GLEE_C_DEFINED_glXGetSyncValuesOML +#define GLEE_C_DEFINED_glXGetSyncValuesOML + Bool __stdcall GLee_Lazy_glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable, int64_t * ust, int64_t * msc, int64_t * sbc) {if (GLeeInit()) return glXGetSyncValuesOML(dpy, drawable, ust, msc, sbc); return (Bool)0;} + GLEEPFNGLXGETSYNCVALUESOMLPROC GLeeFuncPtr_glXGetSyncValuesOML=GLee_Lazy_glXGetSyncValuesOML; +#endif +#ifndef GLEE_C_DEFINED_glXGetMscRateOML +#define GLEE_C_DEFINED_glXGetMscRateOML + Bool __stdcall GLee_Lazy_glXGetMscRateOML(Display * dpy, GLXDrawable drawable, int32_t * numerator, int32_t * denominator) {if (GLeeInit()) return glXGetMscRateOML(dpy, drawable, numerator, denominator); return (Bool)0;} + GLEEPFNGLXGETMSCRATEOMLPROC GLeeFuncPtr_glXGetMscRateOML=GLee_Lazy_glXGetMscRateOML; +#endif +#ifndef GLEE_C_DEFINED_glXSwapBuffersMscOML +#define GLEE_C_DEFINED_glXSwapBuffersMscOML + int64_t __stdcall GLee_Lazy_glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) {if (GLeeInit()) return glXSwapBuffersMscOML(dpy, drawable, target_msc, divisor, remainder); return (int64_t)0;} + GLEEPFNGLXSWAPBUFFERSMSCOMLPROC GLeeFuncPtr_glXSwapBuffersMscOML=GLee_Lazy_glXSwapBuffersMscOML; +#endif +#ifndef GLEE_C_DEFINED_glXWaitForMscOML +#define GLEE_C_DEFINED_glXWaitForMscOML + Bool __stdcall GLee_Lazy_glXWaitForMscOML(Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * ust, int64_t * msc, int64_t * sbc) {if (GLeeInit()) return glXWaitForMscOML(dpy, drawable, target_msc, divisor, remainder, ust, msc, sbc); return (Bool)0;} + GLEEPFNGLXWAITFORMSCOMLPROC GLeeFuncPtr_glXWaitForMscOML=GLee_Lazy_glXWaitForMscOML; +#endif +#ifndef GLEE_C_DEFINED_glXWaitForSbcOML +#define GLEE_C_DEFINED_glXWaitForSbcOML + Bool __stdcall GLee_Lazy_glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t * ust, int64_t * msc, int64_t * sbc) {if (GLeeInit()) return glXWaitForSbcOML(dpy, drawable, target_sbc, ust, msc, sbc); return (Bool)0;} + GLEEPFNGLXWAITFORSBCOMLPROC GLeeFuncPtr_glXWaitForSbcOML=GLee_Lazy_glXWaitForSbcOML; +#endif +#endif + +/* GLX_NV_float_buffer */ + +#ifdef __GLEE_GLX_NV_float_buffer +#endif + +/* GLX_SGIX_hyperpipe */ + +#ifdef __GLEE_GLX_SGIX_hyperpipe +#ifndef GLEE_C_DEFINED_glXQueryHyperpipeNetworkSGIX +#define GLEE_C_DEFINED_glXQueryHyperpipeNetworkSGIX + GLXHyperpipeNetworkSGIX * __stdcall GLee_Lazy_glXQueryHyperpipeNetworkSGIX(Display * dpy, int * npipes) {if (GLeeInit()) return glXQueryHyperpipeNetworkSGIX(dpy, npipes); return (GLXHyperpipeNetworkSGIX *)0;} + GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX=GLee_Lazy_glXQueryHyperpipeNetworkSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXHyperpipeConfigSGIX +#define GLEE_C_DEFINED_glXHyperpipeConfigSGIX + int __stdcall GLee_Lazy_glXHyperpipeConfigSGIX(Display * dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX * cfg, int * hpId) {if (GLeeInit()) return glXHyperpipeConfigSGIX(dpy, networkId, npipes, cfg, hpId); return (int)0;} + GLEEPFNGLXHYPERPIPECONFIGSGIXPROC GLeeFuncPtr_glXHyperpipeConfigSGIX=GLee_Lazy_glXHyperpipeConfigSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXQueryHyperpipeConfigSGIX +#define GLEE_C_DEFINED_glXQueryHyperpipeConfigSGIX + GLXHyperpipeConfigSGIX * __stdcall GLee_Lazy_glXQueryHyperpipeConfigSGIX(Display * dpy, int hpId, int * npipes) {if (GLeeInit()) return glXQueryHyperpipeConfigSGIX(dpy, hpId, npipes); return (GLXHyperpipeConfigSGIX *)0;} + GLEEPFNGLXQUERYHYPERPIPECONFIGSGIXPROC GLeeFuncPtr_glXQueryHyperpipeConfigSGIX=GLee_Lazy_glXQueryHyperpipeConfigSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXDestroyHyperpipeConfigSGIX +#define GLEE_C_DEFINED_glXDestroyHyperpipeConfigSGIX + int __stdcall GLee_Lazy_glXDestroyHyperpipeConfigSGIX(Display * dpy, int hpId) {if (GLeeInit()) return glXDestroyHyperpipeConfigSGIX(dpy, hpId); return (int)0;} + GLEEPFNGLXDESTROYHYPERPIPECONFIGSGIXPROC GLeeFuncPtr_glXDestroyHyperpipeConfigSGIX=GLee_Lazy_glXDestroyHyperpipeConfigSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXBindHyperpipeSGIX +#define GLEE_C_DEFINED_glXBindHyperpipeSGIX + int __stdcall GLee_Lazy_glXBindHyperpipeSGIX(Display * dpy, int hpId) {if (GLeeInit()) return glXBindHyperpipeSGIX(dpy, hpId); return (int)0;} + GLEEPFNGLXBINDHYPERPIPESGIXPROC GLeeFuncPtr_glXBindHyperpipeSGIX=GLee_Lazy_glXBindHyperpipeSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXQueryHyperpipeBestAttribSGIX +#define GLEE_C_DEFINED_glXQueryHyperpipeBestAttribSGIX + int __stdcall GLee_Lazy_glXQueryHyperpipeBestAttribSGIX(Display * dpy, int timeSlice, int attrib, int size, void * attribList, void * returnAttribList) {if (GLeeInit()) return glXQueryHyperpipeBestAttribSGIX(dpy, timeSlice, attrib, size, attribList, returnAttribList); return (int)0;} + GLEEPFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC GLeeFuncPtr_glXQueryHyperpipeBestAttribSGIX=GLee_Lazy_glXQueryHyperpipeBestAttribSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXHyperpipeAttribSGIX +#define GLEE_C_DEFINED_glXHyperpipeAttribSGIX + int __stdcall GLee_Lazy_glXHyperpipeAttribSGIX(Display * dpy, int timeSlice, int attrib, int size, void * attribList) {if (GLeeInit()) return glXHyperpipeAttribSGIX(dpy, timeSlice, attrib, size, attribList); return (int)0;} + GLEEPFNGLXHYPERPIPEATTRIBSGIXPROC GLeeFuncPtr_glXHyperpipeAttribSGIX=GLee_Lazy_glXHyperpipeAttribSGIX; +#endif +#ifndef GLEE_C_DEFINED_glXQueryHyperpipeAttribSGIX +#define GLEE_C_DEFINED_glXQueryHyperpipeAttribSGIX + int __stdcall GLee_Lazy_glXQueryHyperpipeAttribSGIX(Display * dpy, int timeSlice, int attrib, int size, void * returnAttribList) {if (GLeeInit()) return glXQueryHyperpipeAttribSGIX(dpy, timeSlice, attrib, size, returnAttribList); return (int)0;} + GLEEPFNGLXQUERYHYPERPIPEATTRIBSGIXPROC GLeeFuncPtr_glXQueryHyperpipeAttribSGIX=GLee_Lazy_glXQueryHyperpipeAttribSGIX; +#endif +#endif + +/* GLX_MESA_agp_offset */ + +#ifdef __GLEE_GLX_MESA_agp_offset +#ifndef GLEE_C_DEFINED_glXGetAGPOffsetMESA +#define GLEE_C_DEFINED_glXGetAGPOffsetMESA + unsigned int __stdcall GLee_Lazy_glXGetAGPOffsetMESA(const void * pointer) {if (GLeeInit()) return glXGetAGPOffsetMESA(pointer); return (unsigned int)0;} + GLEEPFNGLXGETAGPOFFSETMESAPROC GLeeFuncPtr_glXGetAGPOffsetMESA=GLee_Lazy_glXGetAGPOffsetMESA; +#endif +#endif + +/* GLX_EXT_fbconfig_packed_float */ + +#ifdef __GLEE_GLX_EXT_fbconfig_packed_float +#endif + +/* GLX_EXT_framebuffer_sRGB */ + +#ifdef __GLEE_GLX_EXT_framebuffer_sRGB +#endif + +/* GLX_EXT_texture_from_pixmap */ + +#ifdef __GLEE_GLX_EXT_texture_from_pixmap +#ifndef GLEE_C_DEFINED_glXBindTexImageEXT +#define GLEE_C_DEFINED_glXBindTexImageEXT + void __stdcall GLee_Lazy_glXBindTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer, const int * attrib_list) {if (GLeeInit()) glXBindTexImageEXT(dpy, drawable, buffer, attrib_list);} + GLEEPFNGLXBINDTEXIMAGEEXTPROC GLeeFuncPtr_glXBindTexImageEXT=GLee_Lazy_glXBindTexImageEXT; +#endif +#ifndef GLEE_C_DEFINED_glXReleaseTexImageEXT +#define GLEE_C_DEFINED_glXReleaseTexImageEXT + void __stdcall GLee_Lazy_glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer) {if (GLeeInit()) glXReleaseTexImageEXT(dpy, drawable, buffer);} + GLEEPFNGLXRELEASETEXIMAGEEXTPROC GLeeFuncPtr_glXReleaseTexImageEXT=GLee_Lazy_glXReleaseTexImageEXT; +#endif +#endif + +/* GLX_NV_present_video */ + +#ifdef __GLEE_GLX_NV_present_video +#endif + +/* GLX_NV_video_out */ + +#ifdef __GLEE_GLX_NV_video_out +#endif + +/* GLX_NV_swap_group */ + +#ifdef __GLEE_GLX_NV_swap_group +#endif + +/* GLX_EXT_scene_marker */ + +#ifdef __GLEE_GLX_EXT_scene_marker +#endif + +/* GLX_NV_video_output */ + +#ifdef __GLEE_GLX_NV_video_output +#ifndef GLEE_C_DEFINED_glXGetVideoDeviceNV +#define GLEE_C_DEFINED_glXGetVideoDeviceNV + int __stdcall GLee_Lazy_glXGetVideoDeviceNV(Display * dpy, int screen, int numVideoDevices, GLXVideoDeviceNV * pVideoDevice) {if (GLeeInit()) return glXGetVideoDeviceNV(dpy, screen, numVideoDevices, pVideoDevice); return (int)0;} + GLEEPFNGLXGETVIDEODEVICENVPROC GLeeFuncPtr_glXGetVideoDeviceNV=GLee_Lazy_glXGetVideoDeviceNV; +#endif +#ifndef GLEE_C_DEFINED_glXReleaseVideoDeviceNV +#define GLEE_C_DEFINED_glXReleaseVideoDeviceNV + int __stdcall GLee_Lazy_glXReleaseVideoDeviceNV(Display * dpy, int screen, GLXVideoDeviceNV VideoDevice) {if (GLeeInit()) return glXReleaseVideoDeviceNV(dpy, screen, VideoDevice); return (int)0;} + GLEEPFNGLXRELEASEVIDEODEVICENVPROC GLeeFuncPtr_glXReleaseVideoDeviceNV=GLee_Lazy_glXReleaseVideoDeviceNV; +#endif +#ifndef GLEE_C_DEFINED_glXBindVideoImageNV +#define GLEE_C_DEFINED_glXBindVideoImageNV + int __stdcall GLee_Lazy_glXBindVideoImageNV(Display * dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer) {if (GLeeInit()) return glXBindVideoImageNV(dpy, VideoDevice, pbuf, iVideoBuffer); return (int)0;} + GLEEPFNGLXBINDVIDEOIMAGENVPROC GLeeFuncPtr_glXBindVideoImageNV=GLee_Lazy_glXBindVideoImageNV; +#endif +#ifndef GLEE_C_DEFINED_glXReleaseVideoImageNV +#define GLEE_C_DEFINED_glXReleaseVideoImageNV + int __stdcall GLee_Lazy_glXReleaseVideoImageNV(Display * dpy, GLXPbuffer pbuf) {if (GLeeInit()) return glXReleaseVideoImageNV(dpy, pbuf); return (int)0;} + GLEEPFNGLXRELEASEVIDEOIMAGENVPROC GLeeFuncPtr_glXReleaseVideoImageNV=GLee_Lazy_glXReleaseVideoImageNV; +#endif +#ifndef GLEE_C_DEFINED_glXSendPbufferToVideoNV +#define GLEE_C_DEFINED_glXSendPbufferToVideoNV + int __stdcall GLee_Lazy_glXSendPbufferToVideoNV(Display * dpy, GLXPbuffer pbuf, int iBufferType, unsigned long * pulCounterPbuffer, GLboolean bBlock) {if (GLeeInit()) return glXSendPbufferToVideoNV(dpy, pbuf, iBufferType, pulCounterPbuffer, bBlock); return (int)0;} + GLEEPFNGLXSENDPBUFFERTOVIDEONVPROC GLeeFuncPtr_glXSendPbufferToVideoNV=GLee_Lazy_glXSendPbufferToVideoNV; +#endif +#ifndef GLEE_C_DEFINED_glXGetVideoInfoNV +#define GLEE_C_DEFINED_glXGetVideoInfoNV + int __stdcall GLee_Lazy_glXGetVideoInfoNV(Display * dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long * pulCounterOutputPbuffer, unsigned long * pulCounterOutputVideo) {if (GLeeInit()) return glXGetVideoInfoNV(dpy, screen, VideoDevice, pulCounterOutputPbuffer, pulCounterOutputVideo); return (int)0;} + GLEEPFNGLXGETVIDEOINFONVPROC GLeeFuncPtr_glXGetVideoInfoNV=GLee_Lazy_glXGetVideoInfoNV; +#endif +#endif +#endif /* end GLX */ +/***************************************************************** +* Extension link functions +*****************************************************************/ + +GLuint __GLeeLink_GL_VERSION_1_2(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_VERSION_1_2 + if ((GLeeFuncPtr_glBlendColor = (GLEEPFNGLBLENDCOLORPROC) __GLeeGetProcAddress("glBlendColor"))!=0) nLinked++; + if ((GLeeFuncPtr_glBlendEquation = (GLEEPFNGLBLENDEQUATIONPROC) __GLeeGetProcAddress("glBlendEquation"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawRangeElements = (GLEEPFNGLDRAWRANGEELEMENTSPROC) __GLeeGetProcAddress("glDrawRangeElements"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorTable = (GLEEPFNGLCOLORTABLEPROC) __GLeeGetProcAddress("glColorTable"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorTableParameterfv = (GLEEPFNGLCOLORTABLEPARAMETERFVPROC) __GLeeGetProcAddress("glColorTableParameterfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorTableParameteriv = (GLEEPFNGLCOLORTABLEPARAMETERIVPROC) __GLeeGetProcAddress("glColorTableParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyColorTable = (GLEEPFNGLCOPYCOLORTABLEPROC) __GLeeGetProcAddress("glCopyColorTable"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTable = (GLEEPFNGLGETCOLORTABLEPROC) __GLeeGetProcAddress("glGetColorTable"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableParameterfv = (GLEEPFNGLGETCOLORTABLEPARAMETERFVPROC) __GLeeGetProcAddress("glGetColorTableParameterfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableParameteriv = (GLEEPFNGLGETCOLORTABLEPARAMETERIVPROC) __GLeeGetProcAddress("glGetColorTableParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorSubTable = (GLEEPFNGLCOLORSUBTABLEPROC) __GLeeGetProcAddress("glColorSubTable"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyColorSubTable = (GLEEPFNGLCOPYCOLORSUBTABLEPROC) __GLeeGetProcAddress("glCopyColorSubTable"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionFilter1D = (GLEEPFNGLCONVOLUTIONFILTER1DPROC) __GLeeGetProcAddress("glConvolutionFilter1D"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionFilter2D = (GLEEPFNGLCONVOLUTIONFILTER2DPROC) __GLeeGetProcAddress("glConvolutionFilter2D"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameterf = (GLEEPFNGLCONVOLUTIONPARAMETERFPROC) __GLeeGetProcAddress("glConvolutionParameterf"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameterfv = (GLEEPFNGLCONVOLUTIONPARAMETERFVPROC) __GLeeGetProcAddress("glConvolutionParameterfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameteri = (GLEEPFNGLCONVOLUTIONPARAMETERIPROC) __GLeeGetProcAddress("glConvolutionParameteri"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameteriv = (GLEEPFNGLCONVOLUTIONPARAMETERIVPROC) __GLeeGetProcAddress("glConvolutionParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyConvolutionFilter1D = (GLEEPFNGLCOPYCONVOLUTIONFILTER1DPROC) __GLeeGetProcAddress("glCopyConvolutionFilter1D"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyConvolutionFilter2D = (GLEEPFNGLCOPYCONVOLUTIONFILTER2DPROC) __GLeeGetProcAddress("glCopyConvolutionFilter2D"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetConvolutionFilter = (GLEEPFNGLGETCONVOLUTIONFILTERPROC) __GLeeGetProcAddress("glGetConvolutionFilter"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetConvolutionParameterfv = (GLEEPFNGLGETCONVOLUTIONPARAMETERFVPROC) __GLeeGetProcAddress("glGetConvolutionParameterfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetConvolutionParameteriv = (GLEEPFNGLGETCONVOLUTIONPARAMETERIVPROC) __GLeeGetProcAddress("glGetConvolutionParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetSeparableFilter = (GLEEPFNGLGETSEPARABLEFILTERPROC) __GLeeGetProcAddress("glGetSeparableFilter"))!=0) nLinked++; + if ((GLeeFuncPtr_glSeparableFilter2D = (GLEEPFNGLSEPARABLEFILTER2DPROC) __GLeeGetProcAddress("glSeparableFilter2D"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetHistogram = (GLEEPFNGLGETHISTOGRAMPROC) __GLeeGetProcAddress("glGetHistogram"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetHistogramParameterfv = (GLEEPFNGLGETHISTOGRAMPARAMETERFVPROC) __GLeeGetProcAddress("glGetHistogramParameterfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetHistogramParameteriv = (GLEEPFNGLGETHISTOGRAMPARAMETERIVPROC) __GLeeGetProcAddress("glGetHistogramParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMinmax = (GLEEPFNGLGETMINMAXPROC) __GLeeGetProcAddress("glGetMinmax"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMinmaxParameterfv = (GLEEPFNGLGETMINMAXPARAMETERFVPROC) __GLeeGetProcAddress("glGetMinmaxParameterfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMinmaxParameteriv = (GLEEPFNGLGETMINMAXPARAMETERIVPROC) __GLeeGetProcAddress("glGetMinmaxParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glHistogram = (GLEEPFNGLHISTOGRAMPROC) __GLeeGetProcAddress("glHistogram"))!=0) nLinked++; + if ((GLeeFuncPtr_glMinmax = (GLEEPFNGLMINMAXPROC) __GLeeGetProcAddress("glMinmax"))!=0) nLinked++; + if ((GLeeFuncPtr_glResetHistogram = (GLEEPFNGLRESETHISTOGRAMPROC) __GLeeGetProcAddress("glResetHistogram"))!=0) nLinked++; + if ((GLeeFuncPtr_glResetMinmax = (GLEEPFNGLRESETMINMAXPROC) __GLeeGetProcAddress("glResetMinmax"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexImage3D = (GLEEPFNGLTEXIMAGE3DPROC) __GLeeGetProcAddress("glTexImage3D"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexSubImage3D = (GLEEPFNGLTEXSUBIMAGE3DPROC) __GLeeGetProcAddress("glTexSubImage3D"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTexSubImage3D = (GLEEPFNGLCOPYTEXSUBIMAGE3DPROC) __GLeeGetProcAddress("glCopyTexSubImage3D"))!=0) nLinked++; +#endif + if (nLinked==38) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_imaging(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_VERSION_1_3(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_VERSION_1_3 + if ((GLeeFuncPtr_glActiveTexture = (GLEEPFNGLACTIVETEXTUREPROC) __GLeeGetProcAddress("glActiveTexture"))!=0) nLinked++; + if ((GLeeFuncPtr_glClientActiveTexture = (GLEEPFNGLCLIENTACTIVETEXTUREPROC) __GLeeGetProcAddress("glClientActiveTexture"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1d = (GLEEPFNGLMULTITEXCOORD1DPROC) __GLeeGetProcAddress("glMultiTexCoord1d"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1dv = (GLEEPFNGLMULTITEXCOORD1DVPROC) __GLeeGetProcAddress("glMultiTexCoord1dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1f = (GLEEPFNGLMULTITEXCOORD1FPROC) __GLeeGetProcAddress("glMultiTexCoord1f"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1fv = (GLEEPFNGLMULTITEXCOORD1FVPROC) __GLeeGetProcAddress("glMultiTexCoord1fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1i = (GLEEPFNGLMULTITEXCOORD1IPROC) __GLeeGetProcAddress("glMultiTexCoord1i"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1iv = (GLEEPFNGLMULTITEXCOORD1IVPROC) __GLeeGetProcAddress("glMultiTexCoord1iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1s = (GLEEPFNGLMULTITEXCOORD1SPROC) __GLeeGetProcAddress("glMultiTexCoord1s"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1sv = (GLEEPFNGLMULTITEXCOORD1SVPROC) __GLeeGetProcAddress("glMultiTexCoord1sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2d = (GLEEPFNGLMULTITEXCOORD2DPROC) __GLeeGetProcAddress("glMultiTexCoord2d"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2dv = (GLEEPFNGLMULTITEXCOORD2DVPROC) __GLeeGetProcAddress("glMultiTexCoord2dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2f = (GLEEPFNGLMULTITEXCOORD2FPROC) __GLeeGetProcAddress("glMultiTexCoord2f"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2fv = (GLEEPFNGLMULTITEXCOORD2FVPROC) __GLeeGetProcAddress("glMultiTexCoord2fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2i = (GLEEPFNGLMULTITEXCOORD2IPROC) __GLeeGetProcAddress("glMultiTexCoord2i"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2iv = (GLEEPFNGLMULTITEXCOORD2IVPROC) __GLeeGetProcAddress("glMultiTexCoord2iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2s = (GLEEPFNGLMULTITEXCOORD2SPROC) __GLeeGetProcAddress("glMultiTexCoord2s"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2sv = (GLEEPFNGLMULTITEXCOORD2SVPROC) __GLeeGetProcAddress("glMultiTexCoord2sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3d = (GLEEPFNGLMULTITEXCOORD3DPROC) __GLeeGetProcAddress("glMultiTexCoord3d"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3dv = (GLEEPFNGLMULTITEXCOORD3DVPROC) __GLeeGetProcAddress("glMultiTexCoord3dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3f = (GLEEPFNGLMULTITEXCOORD3FPROC) __GLeeGetProcAddress("glMultiTexCoord3f"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3fv = (GLEEPFNGLMULTITEXCOORD3FVPROC) __GLeeGetProcAddress("glMultiTexCoord3fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3i = (GLEEPFNGLMULTITEXCOORD3IPROC) __GLeeGetProcAddress("glMultiTexCoord3i"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3iv = (GLEEPFNGLMULTITEXCOORD3IVPROC) __GLeeGetProcAddress("glMultiTexCoord3iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3s = (GLEEPFNGLMULTITEXCOORD3SPROC) __GLeeGetProcAddress("glMultiTexCoord3s"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3sv = (GLEEPFNGLMULTITEXCOORD3SVPROC) __GLeeGetProcAddress("glMultiTexCoord3sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4d = (GLEEPFNGLMULTITEXCOORD4DPROC) __GLeeGetProcAddress("glMultiTexCoord4d"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4dv = (GLEEPFNGLMULTITEXCOORD4DVPROC) __GLeeGetProcAddress("glMultiTexCoord4dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4f = (GLEEPFNGLMULTITEXCOORD4FPROC) __GLeeGetProcAddress("glMultiTexCoord4f"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4fv = (GLEEPFNGLMULTITEXCOORD4FVPROC) __GLeeGetProcAddress("glMultiTexCoord4fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4i = (GLEEPFNGLMULTITEXCOORD4IPROC) __GLeeGetProcAddress("glMultiTexCoord4i"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4iv = (GLEEPFNGLMULTITEXCOORD4IVPROC) __GLeeGetProcAddress("glMultiTexCoord4iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4s = (GLEEPFNGLMULTITEXCOORD4SPROC) __GLeeGetProcAddress("glMultiTexCoord4s"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4sv = (GLEEPFNGLMULTITEXCOORD4SVPROC) __GLeeGetProcAddress("glMultiTexCoord4sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glLoadTransposeMatrixf = (GLEEPFNGLLOADTRANSPOSEMATRIXFPROC) __GLeeGetProcAddress("glLoadTransposeMatrixf"))!=0) nLinked++; + if ((GLeeFuncPtr_glLoadTransposeMatrixd = (GLEEPFNGLLOADTRANSPOSEMATRIXDPROC) __GLeeGetProcAddress("glLoadTransposeMatrixd"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultTransposeMatrixf = (GLEEPFNGLMULTTRANSPOSEMATRIXFPROC) __GLeeGetProcAddress("glMultTransposeMatrixf"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultTransposeMatrixd = (GLEEPFNGLMULTTRANSPOSEMATRIXDPROC) __GLeeGetProcAddress("glMultTransposeMatrixd"))!=0) nLinked++; + if ((GLeeFuncPtr_glSampleCoverage = (GLEEPFNGLSAMPLECOVERAGEPROC) __GLeeGetProcAddress("glSampleCoverage"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexImage3D = (GLEEPFNGLCOMPRESSEDTEXIMAGE3DPROC) __GLeeGetProcAddress("glCompressedTexImage3D"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexImage2D = (GLEEPFNGLCOMPRESSEDTEXIMAGE2DPROC) __GLeeGetProcAddress("glCompressedTexImage2D"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexImage1D = (GLEEPFNGLCOMPRESSEDTEXIMAGE1DPROC) __GLeeGetProcAddress("glCompressedTexImage1D"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexSubImage3D = (GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) __GLeeGetProcAddress("glCompressedTexSubImage3D"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexSubImage2D = (GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) __GLeeGetProcAddress("glCompressedTexSubImage2D"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexSubImage1D = (GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) __GLeeGetProcAddress("glCompressedTexSubImage1D"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCompressedTexImage = (GLEEPFNGLGETCOMPRESSEDTEXIMAGEPROC) __GLeeGetProcAddress("glGetCompressedTexImage"))!=0) nLinked++; +#endif + if (nLinked==46) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_VERSION_1_4(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_VERSION_1_4 + if ((GLeeFuncPtr_glBlendFuncSeparate = (GLEEPFNGLBLENDFUNCSEPARATEPROC) __GLeeGetProcAddress("glBlendFuncSeparate"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordf = (GLEEPFNGLFOGCOORDFPROC) __GLeeGetProcAddress("glFogCoordf"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordfv = (GLEEPFNGLFOGCOORDFVPROC) __GLeeGetProcAddress("glFogCoordfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordd = (GLEEPFNGLFOGCOORDDPROC) __GLeeGetProcAddress("glFogCoordd"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoorddv = (GLEEPFNGLFOGCOORDDVPROC) __GLeeGetProcAddress("glFogCoorddv"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordPointer = (GLEEPFNGLFOGCOORDPOINTERPROC) __GLeeGetProcAddress("glFogCoordPointer"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiDrawArrays = (GLEEPFNGLMULTIDRAWARRAYSPROC) __GLeeGetProcAddress("glMultiDrawArrays"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiDrawElements = (GLEEPFNGLMULTIDRAWELEMENTSPROC) __GLeeGetProcAddress("glMultiDrawElements"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameterf = (GLEEPFNGLPOINTPARAMETERFPROC) __GLeeGetProcAddress("glPointParameterf"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameterfv = (GLEEPFNGLPOINTPARAMETERFVPROC) __GLeeGetProcAddress("glPointParameterfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameteri = (GLEEPFNGLPOINTPARAMETERIPROC) __GLeeGetProcAddress("glPointParameteri"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameteriv = (GLEEPFNGLPOINTPARAMETERIVPROC) __GLeeGetProcAddress("glPointParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3b = (GLEEPFNGLSECONDARYCOLOR3BPROC) __GLeeGetProcAddress("glSecondaryColor3b"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3bv = (GLEEPFNGLSECONDARYCOLOR3BVPROC) __GLeeGetProcAddress("glSecondaryColor3bv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3d = (GLEEPFNGLSECONDARYCOLOR3DPROC) __GLeeGetProcAddress("glSecondaryColor3d"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3dv = (GLEEPFNGLSECONDARYCOLOR3DVPROC) __GLeeGetProcAddress("glSecondaryColor3dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3f = (GLEEPFNGLSECONDARYCOLOR3FPROC) __GLeeGetProcAddress("glSecondaryColor3f"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3fv = (GLEEPFNGLSECONDARYCOLOR3FVPROC) __GLeeGetProcAddress("glSecondaryColor3fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3i = (GLEEPFNGLSECONDARYCOLOR3IPROC) __GLeeGetProcAddress("glSecondaryColor3i"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3iv = (GLEEPFNGLSECONDARYCOLOR3IVPROC) __GLeeGetProcAddress("glSecondaryColor3iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3s = (GLEEPFNGLSECONDARYCOLOR3SPROC) __GLeeGetProcAddress("glSecondaryColor3s"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3sv = (GLEEPFNGLSECONDARYCOLOR3SVPROC) __GLeeGetProcAddress("glSecondaryColor3sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3ub = (GLEEPFNGLSECONDARYCOLOR3UBPROC) __GLeeGetProcAddress("glSecondaryColor3ub"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3ubv = (GLEEPFNGLSECONDARYCOLOR3UBVPROC) __GLeeGetProcAddress("glSecondaryColor3ubv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3ui = (GLEEPFNGLSECONDARYCOLOR3UIPROC) __GLeeGetProcAddress("glSecondaryColor3ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3uiv = (GLEEPFNGLSECONDARYCOLOR3UIVPROC) __GLeeGetProcAddress("glSecondaryColor3uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3us = (GLEEPFNGLSECONDARYCOLOR3USPROC) __GLeeGetProcAddress("glSecondaryColor3us"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3usv = (GLEEPFNGLSECONDARYCOLOR3USVPROC) __GLeeGetProcAddress("glSecondaryColor3usv"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColorPointer = (GLEEPFNGLSECONDARYCOLORPOINTERPROC) __GLeeGetProcAddress("glSecondaryColorPointer"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2d = (GLEEPFNGLWINDOWPOS2DPROC) __GLeeGetProcAddress("glWindowPos2d"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2dv = (GLEEPFNGLWINDOWPOS2DVPROC) __GLeeGetProcAddress("glWindowPos2dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2f = (GLEEPFNGLWINDOWPOS2FPROC) __GLeeGetProcAddress("glWindowPos2f"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2fv = (GLEEPFNGLWINDOWPOS2FVPROC) __GLeeGetProcAddress("glWindowPos2fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2i = (GLEEPFNGLWINDOWPOS2IPROC) __GLeeGetProcAddress("glWindowPos2i"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2iv = (GLEEPFNGLWINDOWPOS2IVPROC) __GLeeGetProcAddress("glWindowPos2iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2s = (GLEEPFNGLWINDOWPOS2SPROC) __GLeeGetProcAddress("glWindowPos2s"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2sv = (GLEEPFNGLWINDOWPOS2SVPROC) __GLeeGetProcAddress("glWindowPos2sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3d = (GLEEPFNGLWINDOWPOS3DPROC) __GLeeGetProcAddress("glWindowPos3d"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3dv = (GLEEPFNGLWINDOWPOS3DVPROC) __GLeeGetProcAddress("glWindowPos3dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3f = (GLEEPFNGLWINDOWPOS3FPROC) __GLeeGetProcAddress("glWindowPos3f"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3fv = (GLEEPFNGLWINDOWPOS3FVPROC) __GLeeGetProcAddress("glWindowPos3fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3i = (GLEEPFNGLWINDOWPOS3IPROC) __GLeeGetProcAddress("glWindowPos3i"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3iv = (GLEEPFNGLWINDOWPOS3IVPROC) __GLeeGetProcAddress("glWindowPos3iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3s = (GLEEPFNGLWINDOWPOS3SPROC) __GLeeGetProcAddress("glWindowPos3s"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3sv = (GLEEPFNGLWINDOWPOS3SVPROC) __GLeeGetProcAddress("glWindowPos3sv"))!=0) nLinked++; +#endif + if (nLinked==45) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_VERSION_1_5(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_VERSION_1_5 + if ((GLeeFuncPtr_glGenQueries = (GLEEPFNGLGENQUERIESPROC) __GLeeGetProcAddress("glGenQueries"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteQueries = (GLEEPFNGLDELETEQUERIESPROC) __GLeeGetProcAddress("glDeleteQueries"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsQuery = (GLEEPFNGLISQUERYPROC) __GLeeGetProcAddress("glIsQuery"))!=0) nLinked++; + if ((GLeeFuncPtr_glBeginQuery = (GLEEPFNGLBEGINQUERYPROC) __GLeeGetProcAddress("glBeginQuery"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndQuery = (GLEEPFNGLENDQUERYPROC) __GLeeGetProcAddress("glEndQuery"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetQueryiv = (GLEEPFNGLGETQUERYIVPROC) __GLeeGetProcAddress("glGetQueryiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetQueryObjectiv = (GLEEPFNGLGETQUERYOBJECTIVPROC) __GLeeGetProcAddress("glGetQueryObjectiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetQueryObjectuiv = (GLEEPFNGLGETQUERYOBJECTUIVPROC) __GLeeGetProcAddress("glGetQueryObjectuiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBuffer = (GLEEPFNGLBINDBUFFERPROC) __GLeeGetProcAddress("glBindBuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteBuffers = (GLEEPFNGLDELETEBUFFERSPROC) __GLeeGetProcAddress("glDeleteBuffers"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenBuffers = (GLEEPFNGLGENBUFFERSPROC) __GLeeGetProcAddress("glGenBuffers"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsBuffer = (GLEEPFNGLISBUFFERPROC) __GLeeGetProcAddress("glIsBuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glBufferData = (GLEEPFNGLBUFFERDATAPROC) __GLeeGetProcAddress("glBufferData"))!=0) nLinked++; + if ((GLeeFuncPtr_glBufferSubData = (GLEEPFNGLBUFFERSUBDATAPROC) __GLeeGetProcAddress("glBufferSubData"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBufferSubData = (GLEEPFNGLGETBUFFERSUBDATAPROC) __GLeeGetProcAddress("glGetBufferSubData"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapBuffer = (GLEEPFNGLMAPBUFFERPROC) __GLeeGetProcAddress("glMapBuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glUnmapBuffer = (GLEEPFNGLUNMAPBUFFERPROC) __GLeeGetProcAddress("glUnmapBuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBufferParameteriv = (GLEEPFNGLGETBUFFERPARAMETERIVPROC) __GLeeGetProcAddress("glGetBufferParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBufferPointerv = (GLEEPFNGLGETBUFFERPOINTERVPROC) __GLeeGetProcAddress("glGetBufferPointerv"))!=0) nLinked++; +#endif + if (nLinked==19) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_VERSION_2_0(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_VERSION_2_0 + if ((GLeeFuncPtr_glBlendEquationSeparate = (GLEEPFNGLBLENDEQUATIONSEPARATEPROC) __GLeeGetProcAddress("glBlendEquationSeparate"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawBuffers = (GLEEPFNGLDRAWBUFFERSPROC) __GLeeGetProcAddress("glDrawBuffers"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilOpSeparate = (GLEEPFNGLSTENCILOPSEPARATEPROC) __GLeeGetProcAddress("glStencilOpSeparate"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilFuncSeparate = (GLEEPFNGLSTENCILFUNCSEPARATEPROC) __GLeeGetProcAddress("glStencilFuncSeparate"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilMaskSeparate = (GLEEPFNGLSTENCILMASKSEPARATEPROC) __GLeeGetProcAddress("glStencilMaskSeparate"))!=0) nLinked++; + if ((GLeeFuncPtr_glAttachShader = (GLEEPFNGLATTACHSHADERPROC) __GLeeGetProcAddress("glAttachShader"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindAttribLocation = (GLEEPFNGLBINDATTRIBLOCATIONPROC) __GLeeGetProcAddress("glBindAttribLocation"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompileShader = (GLEEPFNGLCOMPILESHADERPROC) __GLeeGetProcAddress("glCompileShader"))!=0) nLinked++; + if ((GLeeFuncPtr_glCreateProgram = (GLEEPFNGLCREATEPROGRAMPROC) __GLeeGetProcAddress("glCreateProgram"))!=0) nLinked++; + if ((GLeeFuncPtr_glCreateShader = (GLEEPFNGLCREATESHADERPROC) __GLeeGetProcAddress("glCreateShader"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteProgram = (GLEEPFNGLDELETEPROGRAMPROC) __GLeeGetProcAddress("glDeleteProgram"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteShader = (GLEEPFNGLDELETESHADERPROC) __GLeeGetProcAddress("glDeleteShader"))!=0) nLinked++; + if ((GLeeFuncPtr_glDetachShader = (GLEEPFNGLDETACHSHADERPROC) __GLeeGetProcAddress("glDetachShader"))!=0) nLinked++; + if ((GLeeFuncPtr_glDisableVertexAttribArray = (GLEEPFNGLDISABLEVERTEXATTRIBARRAYPROC) __GLeeGetProcAddress("glDisableVertexAttribArray"))!=0) nLinked++; + if ((GLeeFuncPtr_glEnableVertexAttribArray = (GLEEPFNGLENABLEVERTEXATTRIBARRAYPROC) __GLeeGetProcAddress("glEnableVertexAttribArray"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetActiveAttrib = (GLEEPFNGLGETACTIVEATTRIBPROC) __GLeeGetProcAddress("glGetActiveAttrib"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetActiveUniform = (GLEEPFNGLGETACTIVEUNIFORMPROC) __GLeeGetProcAddress("glGetActiveUniform"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetAttachedShaders = (GLEEPFNGLGETATTACHEDSHADERSPROC) __GLeeGetProcAddress("glGetAttachedShaders"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetAttribLocation = (GLEEPFNGLGETATTRIBLOCATIONPROC) __GLeeGetProcAddress("glGetAttribLocation"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramiv = (GLEEPFNGLGETPROGRAMIVPROC) __GLeeGetProcAddress("glGetProgramiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramInfoLog = (GLEEPFNGLGETPROGRAMINFOLOGPROC) __GLeeGetProcAddress("glGetProgramInfoLog"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetShaderiv = (GLEEPFNGLGETSHADERIVPROC) __GLeeGetProcAddress("glGetShaderiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetShaderInfoLog = (GLEEPFNGLGETSHADERINFOLOGPROC) __GLeeGetProcAddress("glGetShaderInfoLog"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetShaderSource = (GLEEPFNGLGETSHADERSOURCEPROC) __GLeeGetProcAddress("glGetShaderSource"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformLocation = (GLEEPFNGLGETUNIFORMLOCATIONPROC) __GLeeGetProcAddress("glGetUniformLocation"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformfv = (GLEEPFNGLGETUNIFORMFVPROC) __GLeeGetProcAddress("glGetUniformfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformiv = (GLEEPFNGLGETUNIFORMIVPROC) __GLeeGetProcAddress("glGetUniformiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribdv = (GLEEPFNGLGETVERTEXATTRIBDVPROC) __GLeeGetProcAddress("glGetVertexAttribdv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribfv = (GLEEPFNGLGETVERTEXATTRIBFVPROC) __GLeeGetProcAddress("glGetVertexAttribfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribiv = (GLEEPFNGLGETVERTEXATTRIBIVPROC) __GLeeGetProcAddress("glGetVertexAttribiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribPointerv = (GLEEPFNGLGETVERTEXATTRIBPOINTERVPROC) __GLeeGetProcAddress("glGetVertexAttribPointerv"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsProgram = (GLEEPFNGLISPROGRAMPROC) __GLeeGetProcAddress("glIsProgram"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsShader = (GLEEPFNGLISSHADERPROC) __GLeeGetProcAddress("glIsShader"))!=0) nLinked++; + if ((GLeeFuncPtr_glLinkProgram = (GLEEPFNGLLINKPROGRAMPROC) __GLeeGetProcAddress("glLinkProgram"))!=0) nLinked++; + if ((GLeeFuncPtr_glShaderSource = (GLEEPFNGLSHADERSOURCEPROC) __GLeeGetProcAddress("glShaderSource"))!=0) nLinked++; + if ((GLeeFuncPtr_glUseProgram = (GLEEPFNGLUSEPROGRAMPROC) __GLeeGetProcAddress("glUseProgram"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1f = (GLEEPFNGLUNIFORM1FPROC) __GLeeGetProcAddress("glUniform1f"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2f = (GLEEPFNGLUNIFORM2FPROC) __GLeeGetProcAddress("glUniform2f"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3f = (GLEEPFNGLUNIFORM3FPROC) __GLeeGetProcAddress("glUniform3f"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4f = (GLEEPFNGLUNIFORM4FPROC) __GLeeGetProcAddress("glUniform4f"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1i = (GLEEPFNGLUNIFORM1IPROC) __GLeeGetProcAddress("glUniform1i"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2i = (GLEEPFNGLUNIFORM2IPROC) __GLeeGetProcAddress("glUniform2i"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3i = (GLEEPFNGLUNIFORM3IPROC) __GLeeGetProcAddress("glUniform3i"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4i = (GLEEPFNGLUNIFORM4IPROC) __GLeeGetProcAddress("glUniform4i"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1fv = (GLEEPFNGLUNIFORM1FVPROC) __GLeeGetProcAddress("glUniform1fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2fv = (GLEEPFNGLUNIFORM2FVPROC) __GLeeGetProcAddress("glUniform2fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3fv = (GLEEPFNGLUNIFORM3FVPROC) __GLeeGetProcAddress("glUniform3fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4fv = (GLEEPFNGLUNIFORM4FVPROC) __GLeeGetProcAddress("glUniform4fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1iv = (GLEEPFNGLUNIFORM1IVPROC) __GLeeGetProcAddress("glUniform1iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2iv = (GLEEPFNGLUNIFORM2IVPROC) __GLeeGetProcAddress("glUniform2iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3iv = (GLEEPFNGLUNIFORM3IVPROC) __GLeeGetProcAddress("glUniform3iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4iv = (GLEEPFNGLUNIFORM4IVPROC) __GLeeGetProcAddress("glUniform4iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix2fv = (GLEEPFNGLUNIFORMMATRIX2FVPROC) __GLeeGetProcAddress("glUniformMatrix2fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix3fv = (GLEEPFNGLUNIFORMMATRIX3FVPROC) __GLeeGetProcAddress("glUniformMatrix3fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix4fv = (GLEEPFNGLUNIFORMMATRIX4FVPROC) __GLeeGetProcAddress("glUniformMatrix4fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glValidateProgram = (GLEEPFNGLVALIDATEPROGRAMPROC) __GLeeGetProcAddress("glValidateProgram"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1d = (GLEEPFNGLVERTEXATTRIB1DPROC) __GLeeGetProcAddress("glVertexAttrib1d"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1dv = (GLEEPFNGLVERTEXATTRIB1DVPROC) __GLeeGetProcAddress("glVertexAttrib1dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1f = (GLEEPFNGLVERTEXATTRIB1FPROC) __GLeeGetProcAddress("glVertexAttrib1f"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1fv = (GLEEPFNGLVERTEXATTRIB1FVPROC) __GLeeGetProcAddress("glVertexAttrib1fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1s = (GLEEPFNGLVERTEXATTRIB1SPROC) __GLeeGetProcAddress("glVertexAttrib1s"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1sv = (GLEEPFNGLVERTEXATTRIB1SVPROC) __GLeeGetProcAddress("glVertexAttrib1sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2d = (GLEEPFNGLVERTEXATTRIB2DPROC) __GLeeGetProcAddress("glVertexAttrib2d"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2dv = (GLEEPFNGLVERTEXATTRIB2DVPROC) __GLeeGetProcAddress("glVertexAttrib2dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2f = (GLEEPFNGLVERTEXATTRIB2FPROC) __GLeeGetProcAddress("glVertexAttrib2f"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2fv = (GLEEPFNGLVERTEXATTRIB2FVPROC) __GLeeGetProcAddress("glVertexAttrib2fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2s = (GLEEPFNGLVERTEXATTRIB2SPROC) __GLeeGetProcAddress("glVertexAttrib2s"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2sv = (GLEEPFNGLVERTEXATTRIB2SVPROC) __GLeeGetProcAddress("glVertexAttrib2sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3d = (GLEEPFNGLVERTEXATTRIB3DPROC) __GLeeGetProcAddress("glVertexAttrib3d"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3dv = (GLEEPFNGLVERTEXATTRIB3DVPROC) __GLeeGetProcAddress("glVertexAttrib3dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3f = (GLEEPFNGLVERTEXATTRIB3FPROC) __GLeeGetProcAddress("glVertexAttrib3f"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3fv = (GLEEPFNGLVERTEXATTRIB3FVPROC) __GLeeGetProcAddress("glVertexAttrib3fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3s = (GLEEPFNGLVERTEXATTRIB3SPROC) __GLeeGetProcAddress("glVertexAttrib3s"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3sv = (GLEEPFNGLVERTEXATTRIB3SVPROC) __GLeeGetProcAddress("glVertexAttrib3sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4Nbv = (GLEEPFNGLVERTEXATTRIB4NBVPROC) __GLeeGetProcAddress("glVertexAttrib4Nbv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4Niv = (GLEEPFNGLVERTEXATTRIB4NIVPROC) __GLeeGetProcAddress("glVertexAttrib4Niv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4Nsv = (GLEEPFNGLVERTEXATTRIB4NSVPROC) __GLeeGetProcAddress("glVertexAttrib4Nsv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4Nub = (GLEEPFNGLVERTEXATTRIB4NUBPROC) __GLeeGetProcAddress("glVertexAttrib4Nub"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4Nubv = (GLEEPFNGLVERTEXATTRIB4NUBVPROC) __GLeeGetProcAddress("glVertexAttrib4Nubv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4Nuiv = (GLEEPFNGLVERTEXATTRIB4NUIVPROC) __GLeeGetProcAddress("glVertexAttrib4Nuiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4Nusv = (GLEEPFNGLVERTEXATTRIB4NUSVPROC) __GLeeGetProcAddress("glVertexAttrib4Nusv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4bv = (GLEEPFNGLVERTEXATTRIB4BVPROC) __GLeeGetProcAddress("glVertexAttrib4bv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4d = (GLEEPFNGLVERTEXATTRIB4DPROC) __GLeeGetProcAddress("glVertexAttrib4d"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4dv = (GLEEPFNGLVERTEXATTRIB4DVPROC) __GLeeGetProcAddress("glVertexAttrib4dv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4f = (GLEEPFNGLVERTEXATTRIB4FPROC) __GLeeGetProcAddress("glVertexAttrib4f"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4fv = (GLEEPFNGLVERTEXATTRIB4FVPROC) __GLeeGetProcAddress("glVertexAttrib4fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4iv = (GLEEPFNGLVERTEXATTRIB4IVPROC) __GLeeGetProcAddress("glVertexAttrib4iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4s = (GLEEPFNGLVERTEXATTRIB4SPROC) __GLeeGetProcAddress("glVertexAttrib4s"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4sv = (GLEEPFNGLVERTEXATTRIB4SVPROC) __GLeeGetProcAddress("glVertexAttrib4sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4ubv = (GLEEPFNGLVERTEXATTRIB4UBVPROC) __GLeeGetProcAddress("glVertexAttrib4ubv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4uiv = (GLEEPFNGLVERTEXATTRIB4UIVPROC) __GLeeGetProcAddress("glVertexAttrib4uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4usv = (GLEEPFNGLVERTEXATTRIB4USVPROC) __GLeeGetProcAddress("glVertexAttrib4usv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribPointer = (GLEEPFNGLVERTEXATTRIBPOINTERPROC) __GLeeGetProcAddress("glVertexAttribPointer"))!=0) nLinked++; +#endif + if (nLinked==93) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_VERSION_2_1(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_VERSION_2_1 + if ((GLeeFuncPtr_glUniformMatrix2x3fv = (GLEEPFNGLUNIFORMMATRIX2X3FVPROC) __GLeeGetProcAddress("glUniformMatrix2x3fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix3x2fv = (GLEEPFNGLUNIFORMMATRIX3X2FVPROC) __GLeeGetProcAddress("glUniformMatrix3x2fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix2x4fv = (GLEEPFNGLUNIFORMMATRIX2X4FVPROC) __GLeeGetProcAddress("glUniformMatrix2x4fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix4x2fv = (GLEEPFNGLUNIFORMMATRIX4X2FVPROC) __GLeeGetProcAddress("glUniformMatrix4x2fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix3x4fv = (GLEEPFNGLUNIFORMMATRIX3X4FVPROC) __GLeeGetProcAddress("glUniformMatrix3x4fv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix4x3fv = (GLEEPFNGLUNIFORMMATRIX4X3FVPROC) __GLeeGetProcAddress("glUniformMatrix4x3fv"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_VERSION_3_0(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_VERSION_3_0 + if ((GLeeFuncPtr_glColorMaski = (GLEEPFNGLCOLORMASKIPROC) __GLeeGetProcAddress("glColorMaski"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBooleani_v = (GLEEPFNGLGETBOOLEANI_VPROC) __GLeeGetProcAddress("glGetBooleani_v"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetIntegeri_v = (GLEEPFNGLGETINTEGERI_VPROC) __GLeeGetProcAddress("glGetIntegeri_v"))!=0) nLinked++; + if ((GLeeFuncPtr_glEnablei = (GLEEPFNGLENABLEIPROC) __GLeeGetProcAddress("glEnablei"))!=0) nLinked++; + if ((GLeeFuncPtr_glDisablei = (GLEEPFNGLDISABLEIPROC) __GLeeGetProcAddress("glDisablei"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsEnabledi = (GLEEPFNGLISENABLEDIPROC) __GLeeGetProcAddress("glIsEnabledi"))!=0) nLinked++; + if ((GLeeFuncPtr_glBeginTransformFeedback = (GLEEPFNGLBEGINTRANSFORMFEEDBACKPROC) __GLeeGetProcAddress("glBeginTransformFeedback"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndTransformFeedback = (GLEEPFNGLENDTRANSFORMFEEDBACKPROC) __GLeeGetProcAddress("glEndTransformFeedback"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferRange = (GLEEPFNGLBINDBUFFERRANGEPROC) __GLeeGetProcAddress("glBindBufferRange"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferBase = (GLEEPFNGLBINDBUFFERBASEPROC) __GLeeGetProcAddress("glBindBufferBase"))!=0) nLinked++; + if ((GLeeFuncPtr_glTransformFeedbackVaryings = (GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC) __GLeeGetProcAddress("glTransformFeedbackVaryings"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTransformFeedbackVarying = (GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGPROC) __GLeeGetProcAddress("glGetTransformFeedbackVarying"))!=0) nLinked++; + if ((GLeeFuncPtr_glClampColor = (GLEEPFNGLCLAMPCOLORPROC) __GLeeGetProcAddress("glClampColor"))!=0) nLinked++; + if ((GLeeFuncPtr_glBeginConditionalRender = (GLEEPFNGLBEGINCONDITIONALRENDERPROC) __GLeeGetProcAddress("glBeginConditionalRender"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndConditionalRender = (GLEEPFNGLENDCONDITIONALRENDERPROC) __GLeeGetProcAddress("glEndConditionalRender"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI1i = (GLEEPFNGLVERTEXATTRIBI1IPROC) __GLeeGetProcAddress("glVertexAttribI1i"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2i = (GLEEPFNGLVERTEXATTRIBI2IPROC) __GLeeGetProcAddress("glVertexAttribI2i"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3i = (GLEEPFNGLVERTEXATTRIBI3IPROC) __GLeeGetProcAddress("glVertexAttribI3i"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4i = (GLEEPFNGLVERTEXATTRIBI4IPROC) __GLeeGetProcAddress("glVertexAttribI4i"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI1ui = (GLEEPFNGLVERTEXATTRIBI1UIPROC) __GLeeGetProcAddress("glVertexAttribI1ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2ui = (GLEEPFNGLVERTEXATTRIBI2UIPROC) __GLeeGetProcAddress("glVertexAttribI2ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3ui = (GLEEPFNGLVERTEXATTRIBI3UIPROC) __GLeeGetProcAddress("glVertexAttribI3ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4ui = (GLEEPFNGLVERTEXATTRIBI4UIPROC) __GLeeGetProcAddress("glVertexAttribI4ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI1iv = (GLEEPFNGLVERTEXATTRIBI1IVPROC) __GLeeGetProcAddress("glVertexAttribI1iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2iv = (GLEEPFNGLVERTEXATTRIBI2IVPROC) __GLeeGetProcAddress("glVertexAttribI2iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3iv = (GLEEPFNGLVERTEXATTRIBI3IVPROC) __GLeeGetProcAddress("glVertexAttribI3iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4iv = (GLEEPFNGLVERTEXATTRIBI4IVPROC) __GLeeGetProcAddress("glVertexAttribI4iv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI1uiv = (GLEEPFNGLVERTEXATTRIBI1UIVPROC) __GLeeGetProcAddress("glVertexAttribI1uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2uiv = (GLEEPFNGLVERTEXATTRIBI2UIVPROC) __GLeeGetProcAddress("glVertexAttribI2uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3uiv = (GLEEPFNGLVERTEXATTRIBI3UIVPROC) __GLeeGetProcAddress("glVertexAttribI3uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4uiv = (GLEEPFNGLVERTEXATTRIBI4UIVPROC) __GLeeGetProcAddress("glVertexAttribI4uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4bv = (GLEEPFNGLVERTEXATTRIBI4BVPROC) __GLeeGetProcAddress("glVertexAttribI4bv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4sv = (GLEEPFNGLVERTEXATTRIBI4SVPROC) __GLeeGetProcAddress("glVertexAttribI4sv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4ubv = (GLEEPFNGLVERTEXATTRIBI4UBVPROC) __GLeeGetProcAddress("glVertexAttribI4ubv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4usv = (GLEEPFNGLVERTEXATTRIBI4USVPROC) __GLeeGetProcAddress("glVertexAttribI4usv"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribIPointer = (GLEEPFNGLVERTEXATTRIBIPOINTERPROC) __GLeeGetProcAddress("glVertexAttribIPointer"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribIiv = (GLEEPFNGLGETVERTEXATTRIBIIVPROC) __GLeeGetProcAddress("glGetVertexAttribIiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribIuiv = (GLEEPFNGLGETVERTEXATTRIBIUIVPROC) __GLeeGetProcAddress("glGetVertexAttribIuiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformuiv = (GLEEPFNGLGETUNIFORMUIVPROC) __GLeeGetProcAddress("glGetUniformuiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindFragDataLocation = (GLEEPFNGLBINDFRAGDATALOCATIONPROC) __GLeeGetProcAddress("glBindFragDataLocation"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragDataLocation = (GLEEPFNGLGETFRAGDATALOCATIONPROC) __GLeeGetProcAddress("glGetFragDataLocation"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1ui = (GLEEPFNGLUNIFORM1UIPROC) __GLeeGetProcAddress("glUniform1ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2ui = (GLEEPFNGLUNIFORM2UIPROC) __GLeeGetProcAddress("glUniform2ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3ui = (GLEEPFNGLUNIFORM3UIPROC) __GLeeGetProcAddress("glUniform3ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4ui = (GLEEPFNGLUNIFORM4UIPROC) __GLeeGetProcAddress("glUniform4ui"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1uiv = (GLEEPFNGLUNIFORM1UIVPROC) __GLeeGetProcAddress("glUniform1uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2uiv = (GLEEPFNGLUNIFORM2UIVPROC) __GLeeGetProcAddress("glUniform2uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3uiv = (GLEEPFNGLUNIFORM3UIVPROC) __GLeeGetProcAddress("glUniform3uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4uiv = (GLEEPFNGLUNIFORM4UIVPROC) __GLeeGetProcAddress("glUniform4uiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexParameterIiv = (GLEEPFNGLTEXPARAMETERIIVPROC) __GLeeGetProcAddress("glTexParameterIiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexParameterIuiv = (GLEEPFNGLTEXPARAMETERIUIVPROC) __GLeeGetProcAddress("glTexParameterIuiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexParameterIiv = (GLEEPFNGLGETTEXPARAMETERIIVPROC) __GLeeGetProcAddress("glGetTexParameterIiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexParameterIuiv = (GLEEPFNGLGETTEXPARAMETERIUIVPROC) __GLeeGetProcAddress("glGetTexParameterIuiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearBufferiv = (GLEEPFNGLCLEARBUFFERIVPROC) __GLeeGetProcAddress("glClearBufferiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearBufferuiv = (GLEEPFNGLCLEARBUFFERUIVPROC) __GLeeGetProcAddress("glClearBufferuiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearBufferfv = (GLEEPFNGLCLEARBUFFERFVPROC) __GLeeGetProcAddress("glClearBufferfv"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearBufferfi = (GLEEPFNGLCLEARBUFFERFIPROC) __GLeeGetProcAddress("glClearBufferfi"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetStringi = (GLEEPFNGLGETSTRINGIPROC) __GLeeGetProcAddress("glGetStringi"))!=0) nLinked++; +#endif + if (nLinked==58) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_multitexture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_multitexture + if ((GLeeFuncPtr_glActiveTextureARB = (GLEEPFNGLACTIVETEXTUREARBPROC) __GLeeGetProcAddress("glActiveTextureARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glClientActiveTextureARB = (GLEEPFNGLCLIENTACTIVETEXTUREARBPROC) __GLeeGetProcAddress("glClientActiveTextureARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1dARB = (GLEEPFNGLMULTITEXCOORD1DARBPROC) __GLeeGetProcAddress("glMultiTexCoord1dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1dvARB = (GLEEPFNGLMULTITEXCOORD1DVARBPROC) __GLeeGetProcAddress("glMultiTexCoord1dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1fARB = (GLEEPFNGLMULTITEXCOORD1FARBPROC) __GLeeGetProcAddress("glMultiTexCoord1fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1fvARB = (GLEEPFNGLMULTITEXCOORD1FVARBPROC) __GLeeGetProcAddress("glMultiTexCoord1fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1iARB = (GLEEPFNGLMULTITEXCOORD1IARBPROC) __GLeeGetProcAddress("glMultiTexCoord1iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1ivARB = (GLEEPFNGLMULTITEXCOORD1IVARBPROC) __GLeeGetProcAddress("glMultiTexCoord1ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1sARB = (GLEEPFNGLMULTITEXCOORD1SARBPROC) __GLeeGetProcAddress("glMultiTexCoord1sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1svARB = (GLEEPFNGLMULTITEXCOORD1SVARBPROC) __GLeeGetProcAddress("glMultiTexCoord1svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2dARB = (GLEEPFNGLMULTITEXCOORD2DARBPROC) __GLeeGetProcAddress("glMultiTexCoord2dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2dvARB = (GLEEPFNGLMULTITEXCOORD2DVARBPROC) __GLeeGetProcAddress("glMultiTexCoord2dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2fARB = (GLEEPFNGLMULTITEXCOORD2FARBPROC) __GLeeGetProcAddress("glMultiTexCoord2fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2fvARB = (GLEEPFNGLMULTITEXCOORD2FVARBPROC) __GLeeGetProcAddress("glMultiTexCoord2fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2iARB = (GLEEPFNGLMULTITEXCOORD2IARBPROC) __GLeeGetProcAddress("glMultiTexCoord2iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2ivARB = (GLEEPFNGLMULTITEXCOORD2IVARBPROC) __GLeeGetProcAddress("glMultiTexCoord2ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2sARB = (GLEEPFNGLMULTITEXCOORD2SARBPROC) __GLeeGetProcAddress("glMultiTexCoord2sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2svARB = (GLEEPFNGLMULTITEXCOORD2SVARBPROC) __GLeeGetProcAddress("glMultiTexCoord2svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3dARB = (GLEEPFNGLMULTITEXCOORD3DARBPROC) __GLeeGetProcAddress("glMultiTexCoord3dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3dvARB = (GLEEPFNGLMULTITEXCOORD3DVARBPROC) __GLeeGetProcAddress("glMultiTexCoord3dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3fARB = (GLEEPFNGLMULTITEXCOORD3FARBPROC) __GLeeGetProcAddress("glMultiTexCoord3fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3fvARB = (GLEEPFNGLMULTITEXCOORD3FVARBPROC) __GLeeGetProcAddress("glMultiTexCoord3fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3iARB = (GLEEPFNGLMULTITEXCOORD3IARBPROC) __GLeeGetProcAddress("glMultiTexCoord3iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3ivARB = (GLEEPFNGLMULTITEXCOORD3IVARBPROC) __GLeeGetProcAddress("glMultiTexCoord3ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3sARB = (GLEEPFNGLMULTITEXCOORD3SARBPROC) __GLeeGetProcAddress("glMultiTexCoord3sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3svARB = (GLEEPFNGLMULTITEXCOORD3SVARBPROC) __GLeeGetProcAddress("glMultiTexCoord3svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4dARB = (GLEEPFNGLMULTITEXCOORD4DARBPROC) __GLeeGetProcAddress("glMultiTexCoord4dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4dvARB = (GLEEPFNGLMULTITEXCOORD4DVARBPROC) __GLeeGetProcAddress("glMultiTexCoord4dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4fARB = (GLEEPFNGLMULTITEXCOORD4FARBPROC) __GLeeGetProcAddress("glMultiTexCoord4fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4fvARB = (GLEEPFNGLMULTITEXCOORD4FVARBPROC) __GLeeGetProcAddress("glMultiTexCoord4fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4iARB = (GLEEPFNGLMULTITEXCOORD4IARBPROC) __GLeeGetProcAddress("glMultiTexCoord4iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4ivARB = (GLEEPFNGLMULTITEXCOORD4IVARBPROC) __GLeeGetProcAddress("glMultiTexCoord4ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4sARB = (GLEEPFNGLMULTITEXCOORD4SARBPROC) __GLeeGetProcAddress("glMultiTexCoord4sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4svARB = (GLEEPFNGLMULTITEXCOORD4SVARBPROC) __GLeeGetProcAddress("glMultiTexCoord4svARB"))!=0) nLinked++; +#endif + if (nLinked==34) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_transpose_matrix(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_transpose_matrix + if ((GLeeFuncPtr_glLoadTransposeMatrixfARB = (GLEEPFNGLLOADTRANSPOSEMATRIXFARBPROC) __GLeeGetProcAddress("glLoadTransposeMatrixfARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glLoadTransposeMatrixdARB = (GLEEPFNGLLOADTRANSPOSEMATRIXDARBPROC) __GLeeGetProcAddress("glLoadTransposeMatrixdARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultTransposeMatrixfARB = (GLEEPFNGLMULTTRANSPOSEMATRIXFARBPROC) __GLeeGetProcAddress("glMultTransposeMatrixfARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultTransposeMatrixdARB = (GLEEPFNGLMULTTRANSPOSEMATRIXDARBPROC) __GLeeGetProcAddress("glMultTransposeMatrixdARB"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_multisample(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_multisample + if ((GLeeFuncPtr_glSampleCoverageARB = (GLEEPFNGLSAMPLECOVERAGEARBPROC) __GLeeGetProcAddress("glSampleCoverageARB"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_env_add(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_cube_map(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_compression(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_texture_compression + if ((GLeeFuncPtr_glCompressedTexImage3DARB = (GLEEPFNGLCOMPRESSEDTEXIMAGE3DARBPROC) __GLeeGetProcAddress("glCompressedTexImage3DARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexImage2DARB = (GLEEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC) __GLeeGetProcAddress("glCompressedTexImage2DARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexImage1DARB = (GLEEPFNGLCOMPRESSEDTEXIMAGE1DARBPROC) __GLeeGetProcAddress("glCompressedTexImage1DARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexSubImage3DARB = (GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) __GLeeGetProcAddress("glCompressedTexSubImage3DARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexSubImage2DARB = (GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) __GLeeGetProcAddress("glCompressedTexSubImage2DARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTexSubImage1DARB = (GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) __GLeeGetProcAddress("glCompressedTexSubImage1DARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCompressedTexImageARB = (GLEEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC) __GLeeGetProcAddress("glGetCompressedTexImageARB"))!=0) nLinked++; +#endif + if (nLinked==7) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_border_clamp(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_point_parameters(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_point_parameters + if ((GLeeFuncPtr_glPointParameterfARB = (GLEEPFNGLPOINTPARAMETERFARBPROC) __GLeeGetProcAddress("glPointParameterfARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameterfvARB = (GLEEPFNGLPOINTPARAMETERFVARBPROC) __GLeeGetProcAddress("glPointParameterfvARB"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_vertex_blend(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_vertex_blend + if ((GLeeFuncPtr_glWeightbvARB = (GLEEPFNGLWEIGHTBVARBPROC) __GLeeGetProcAddress("glWeightbvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightsvARB = (GLEEPFNGLWEIGHTSVARBPROC) __GLeeGetProcAddress("glWeightsvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightivARB = (GLEEPFNGLWEIGHTIVARBPROC) __GLeeGetProcAddress("glWeightivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightfvARB = (GLEEPFNGLWEIGHTFVARBPROC) __GLeeGetProcAddress("glWeightfvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightdvARB = (GLEEPFNGLWEIGHTDVARBPROC) __GLeeGetProcAddress("glWeightdvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightubvARB = (GLEEPFNGLWEIGHTUBVARBPROC) __GLeeGetProcAddress("glWeightubvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightusvARB = (GLEEPFNGLWEIGHTUSVARBPROC) __GLeeGetProcAddress("glWeightusvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightuivARB = (GLEEPFNGLWEIGHTUIVARBPROC) __GLeeGetProcAddress("glWeightuivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightPointerARB = (GLEEPFNGLWEIGHTPOINTERARBPROC) __GLeeGetProcAddress("glWeightPointerARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexBlendARB = (GLEEPFNGLVERTEXBLENDARBPROC) __GLeeGetProcAddress("glVertexBlendARB"))!=0) nLinked++; +#endif + if (nLinked==10) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_matrix_palette(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_matrix_palette + if ((GLeeFuncPtr_glCurrentPaletteMatrixARB = (GLEEPFNGLCURRENTPALETTEMATRIXARBPROC) __GLeeGetProcAddress("glCurrentPaletteMatrixARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixIndexubvARB = (GLEEPFNGLMATRIXINDEXUBVARBPROC) __GLeeGetProcAddress("glMatrixIndexubvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixIndexusvARB = (GLEEPFNGLMATRIXINDEXUSVARBPROC) __GLeeGetProcAddress("glMatrixIndexusvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixIndexuivARB = (GLEEPFNGLMATRIXINDEXUIVARBPROC) __GLeeGetProcAddress("glMatrixIndexuivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixIndexPointerARB = (GLEEPFNGLMATRIXINDEXPOINTERARBPROC) __GLeeGetProcAddress("glMatrixIndexPointerARB"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_env_combine(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_env_crossbar(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_env_dot3(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_mirrored_repeat(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_depth_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_shadow(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_shadow_ambient(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_window_pos(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_window_pos + if ((GLeeFuncPtr_glWindowPos2dARB = (GLEEPFNGLWINDOWPOS2DARBPROC) __GLeeGetProcAddress("glWindowPos2dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2dvARB = (GLEEPFNGLWINDOWPOS2DVARBPROC) __GLeeGetProcAddress("glWindowPos2dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2fARB = (GLEEPFNGLWINDOWPOS2FARBPROC) __GLeeGetProcAddress("glWindowPos2fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2fvARB = (GLEEPFNGLWINDOWPOS2FVARBPROC) __GLeeGetProcAddress("glWindowPos2fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2iARB = (GLEEPFNGLWINDOWPOS2IARBPROC) __GLeeGetProcAddress("glWindowPos2iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2ivARB = (GLEEPFNGLWINDOWPOS2IVARBPROC) __GLeeGetProcAddress("glWindowPos2ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2sARB = (GLEEPFNGLWINDOWPOS2SARBPROC) __GLeeGetProcAddress("glWindowPos2sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2svARB = (GLEEPFNGLWINDOWPOS2SVARBPROC) __GLeeGetProcAddress("glWindowPos2svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3dARB = (GLEEPFNGLWINDOWPOS3DARBPROC) __GLeeGetProcAddress("glWindowPos3dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3dvARB = (GLEEPFNGLWINDOWPOS3DVARBPROC) __GLeeGetProcAddress("glWindowPos3dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3fARB = (GLEEPFNGLWINDOWPOS3FARBPROC) __GLeeGetProcAddress("glWindowPos3fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3fvARB = (GLEEPFNGLWINDOWPOS3FVARBPROC) __GLeeGetProcAddress("glWindowPos3fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3iARB = (GLEEPFNGLWINDOWPOS3IARBPROC) __GLeeGetProcAddress("glWindowPos3iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3ivARB = (GLEEPFNGLWINDOWPOS3IVARBPROC) __GLeeGetProcAddress("glWindowPos3ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3sARB = (GLEEPFNGLWINDOWPOS3SARBPROC) __GLeeGetProcAddress("glWindowPos3sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3svARB = (GLEEPFNGLWINDOWPOS3SVARBPROC) __GLeeGetProcAddress("glWindowPos3svARB"))!=0) nLinked++; +#endif + if (nLinked==16) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_vertex_program(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_vertex_program + if ((GLeeFuncPtr_glVertexAttrib1dARB = (GLEEPFNGLVERTEXATTRIB1DARBPROC) __GLeeGetProcAddress("glVertexAttrib1dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1dvARB = (GLEEPFNGLVERTEXATTRIB1DVARBPROC) __GLeeGetProcAddress("glVertexAttrib1dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1fARB = (GLEEPFNGLVERTEXATTRIB1FARBPROC) __GLeeGetProcAddress("glVertexAttrib1fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1fvARB = (GLEEPFNGLVERTEXATTRIB1FVARBPROC) __GLeeGetProcAddress("glVertexAttrib1fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1sARB = (GLEEPFNGLVERTEXATTRIB1SARBPROC) __GLeeGetProcAddress("glVertexAttrib1sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1svARB = (GLEEPFNGLVERTEXATTRIB1SVARBPROC) __GLeeGetProcAddress("glVertexAttrib1svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2dARB = (GLEEPFNGLVERTEXATTRIB2DARBPROC) __GLeeGetProcAddress("glVertexAttrib2dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2dvARB = (GLEEPFNGLVERTEXATTRIB2DVARBPROC) __GLeeGetProcAddress("glVertexAttrib2dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2fARB = (GLEEPFNGLVERTEXATTRIB2FARBPROC) __GLeeGetProcAddress("glVertexAttrib2fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2fvARB = (GLEEPFNGLVERTEXATTRIB2FVARBPROC) __GLeeGetProcAddress("glVertexAttrib2fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2sARB = (GLEEPFNGLVERTEXATTRIB2SARBPROC) __GLeeGetProcAddress("glVertexAttrib2sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2svARB = (GLEEPFNGLVERTEXATTRIB2SVARBPROC) __GLeeGetProcAddress("glVertexAttrib2svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3dARB = (GLEEPFNGLVERTEXATTRIB3DARBPROC) __GLeeGetProcAddress("glVertexAttrib3dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3dvARB = (GLEEPFNGLVERTEXATTRIB3DVARBPROC) __GLeeGetProcAddress("glVertexAttrib3dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3fARB = (GLEEPFNGLVERTEXATTRIB3FARBPROC) __GLeeGetProcAddress("glVertexAttrib3fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3fvARB = (GLEEPFNGLVERTEXATTRIB3FVARBPROC) __GLeeGetProcAddress("glVertexAttrib3fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3sARB = (GLEEPFNGLVERTEXATTRIB3SARBPROC) __GLeeGetProcAddress("glVertexAttrib3sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3svARB = (GLEEPFNGLVERTEXATTRIB3SVARBPROC) __GLeeGetProcAddress("glVertexAttrib3svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4NbvARB = (GLEEPFNGLVERTEXATTRIB4NBVARBPROC) __GLeeGetProcAddress("glVertexAttrib4NbvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4NivARB = (GLEEPFNGLVERTEXATTRIB4NIVARBPROC) __GLeeGetProcAddress("glVertexAttrib4NivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4NsvARB = (GLEEPFNGLVERTEXATTRIB4NSVARBPROC) __GLeeGetProcAddress("glVertexAttrib4NsvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4NubARB = (GLEEPFNGLVERTEXATTRIB4NUBARBPROC) __GLeeGetProcAddress("glVertexAttrib4NubARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4NubvARB = (GLEEPFNGLVERTEXATTRIB4NUBVARBPROC) __GLeeGetProcAddress("glVertexAttrib4NubvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4NuivARB = (GLEEPFNGLVERTEXATTRIB4NUIVARBPROC) __GLeeGetProcAddress("glVertexAttrib4NuivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4NusvARB = (GLEEPFNGLVERTEXATTRIB4NUSVARBPROC) __GLeeGetProcAddress("glVertexAttrib4NusvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4bvARB = (GLEEPFNGLVERTEXATTRIB4BVARBPROC) __GLeeGetProcAddress("glVertexAttrib4bvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4dARB = (GLEEPFNGLVERTEXATTRIB4DARBPROC) __GLeeGetProcAddress("glVertexAttrib4dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4dvARB = (GLEEPFNGLVERTEXATTRIB4DVARBPROC) __GLeeGetProcAddress("glVertexAttrib4dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4fARB = (GLEEPFNGLVERTEXATTRIB4FARBPROC) __GLeeGetProcAddress("glVertexAttrib4fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4fvARB = (GLEEPFNGLVERTEXATTRIB4FVARBPROC) __GLeeGetProcAddress("glVertexAttrib4fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4ivARB = (GLEEPFNGLVERTEXATTRIB4IVARBPROC) __GLeeGetProcAddress("glVertexAttrib4ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4sARB = (GLEEPFNGLVERTEXATTRIB4SARBPROC) __GLeeGetProcAddress("glVertexAttrib4sARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4svARB = (GLEEPFNGLVERTEXATTRIB4SVARBPROC) __GLeeGetProcAddress("glVertexAttrib4svARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4ubvARB = (GLEEPFNGLVERTEXATTRIB4UBVARBPROC) __GLeeGetProcAddress("glVertexAttrib4ubvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4uivARB = (GLEEPFNGLVERTEXATTRIB4UIVARBPROC) __GLeeGetProcAddress("glVertexAttrib4uivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4usvARB = (GLEEPFNGLVERTEXATTRIB4USVARBPROC) __GLeeGetProcAddress("glVertexAttrib4usvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribPointerARB = (GLEEPFNGLVERTEXATTRIBPOINTERARBPROC) __GLeeGetProcAddress("glVertexAttribPointerARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glEnableVertexAttribArrayARB = (GLEEPFNGLENABLEVERTEXATTRIBARRAYARBPROC) __GLeeGetProcAddress("glEnableVertexAttribArrayARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDisableVertexAttribArrayARB = (GLEEPFNGLDISABLEVERTEXATTRIBARRAYARBPROC) __GLeeGetProcAddress("glDisableVertexAttribArrayARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramStringARB = (GLEEPFNGLPROGRAMSTRINGARBPROC) __GLeeGetProcAddress("glProgramStringARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindProgramARB = (GLEEPFNGLBINDPROGRAMARBPROC) __GLeeGetProcAddress("glBindProgramARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteProgramsARB = (GLEEPFNGLDELETEPROGRAMSARBPROC) __GLeeGetProcAddress("glDeleteProgramsARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenProgramsARB = (GLEEPFNGLGENPROGRAMSARBPROC) __GLeeGetProcAddress("glGenProgramsARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameter4dARB = (GLEEPFNGLPROGRAMENVPARAMETER4DARBPROC) __GLeeGetProcAddress("glProgramEnvParameter4dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameter4dvARB = (GLEEPFNGLPROGRAMENVPARAMETER4DVARBPROC) __GLeeGetProcAddress("glProgramEnvParameter4dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameter4fARB = (GLEEPFNGLPROGRAMENVPARAMETER4FARBPROC) __GLeeGetProcAddress("glProgramEnvParameter4fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameter4fvARB = (GLEEPFNGLPROGRAMENVPARAMETER4FVARBPROC) __GLeeGetProcAddress("glProgramEnvParameter4fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameter4dARB = (GLEEPFNGLPROGRAMLOCALPARAMETER4DARBPROC) __GLeeGetProcAddress("glProgramLocalParameter4dARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameter4dvARB = (GLEEPFNGLPROGRAMLOCALPARAMETER4DVARBPROC) __GLeeGetProcAddress("glProgramLocalParameter4dvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameter4fARB = (GLEEPFNGLPROGRAMLOCALPARAMETER4FARBPROC) __GLeeGetProcAddress("glProgramLocalParameter4fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameter4fvARB = (GLEEPFNGLPROGRAMLOCALPARAMETER4FVARBPROC) __GLeeGetProcAddress("glProgramLocalParameter4fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramEnvParameterdvARB = (GLEEPFNGLGETPROGRAMENVPARAMETERDVARBPROC) __GLeeGetProcAddress("glGetProgramEnvParameterdvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramEnvParameterfvARB = (GLEEPFNGLGETPROGRAMENVPARAMETERFVARBPROC) __GLeeGetProcAddress("glGetProgramEnvParameterfvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramLocalParameterdvARB = (GLEEPFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) __GLeeGetProcAddress("glGetProgramLocalParameterdvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramLocalParameterfvARB = (GLEEPFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) __GLeeGetProcAddress("glGetProgramLocalParameterfvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramivARB = (GLEEPFNGLGETPROGRAMIVARBPROC) __GLeeGetProcAddress("glGetProgramivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramStringARB = (GLEEPFNGLGETPROGRAMSTRINGARBPROC) __GLeeGetProcAddress("glGetProgramStringARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribdvARB = (GLEEPFNGLGETVERTEXATTRIBDVARBPROC) __GLeeGetProcAddress("glGetVertexAttribdvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribfvARB = (GLEEPFNGLGETVERTEXATTRIBFVARBPROC) __GLeeGetProcAddress("glGetVertexAttribfvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribivARB = (GLEEPFNGLGETVERTEXATTRIBIVARBPROC) __GLeeGetProcAddress("glGetVertexAttribivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribPointervARB = (GLEEPFNGLGETVERTEXATTRIBPOINTERVARBPROC) __GLeeGetProcAddress("glGetVertexAttribPointervARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsProgramARB = (GLEEPFNGLISPROGRAMARBPROC) __GLeeGetProcAddress("glIsProgramARB"))!=0) nLinked++; +#endif + if (nLinked==62) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_fragment_program(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_vertex_buffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_vertex_buffer_object + if ((GLeeFuncPtr_glBindBufferARB = (GLEEPFNGLBINDBUFFERARBPROC) __GLeeGetProcAddress("glBindBufferARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteBuffersARB = (GLEEPFNGLDELETEBUFFERSARBPROC) __GLeeGetProcAddress("glDeleteBuffersARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenBuffersARB = (GLEEPFNGLGENBUFFERSARBPROC) __GLeeGetProcAddress("glGenBuffersARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsBufferARB = (GLEEPFNGLISBUFFERARBPROC) __GLeeGetProcAddress("glIsBufferARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glBufferDataARB = (GLEEPFNGLBUFFERDATAARBPROC) __GLeeGetProcAddress("glBufferDataARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glBufferSubDataARB = (GLEEPFNGLBUFFERSUBDATAARBPROC) __GLeeGetProcAddress("glBufferSubDataARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBufferSubDataARB = (GLEEPFNGLGETBUFFERSUBDATAARBPROC) __GLeeGetProcAddress("glGetBufferSubDataARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapBufferARB = (GLEEPFNGLMAPBUFFERARBPROC) __GLeeGetProcAddress("glMapBufferARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUnmapBufferARB = (GLEEPFNGLUNMAPBUFFERARBPROC) __GLeeGetProcAddress("glUnmapBufferARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBufferParameterivARB = (GLEEPFNGLGETBUFFERPARAMETERIVARBPROC) __GLeeGetProcAddress("glGetBufferParameterivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBufferPointervARB = (GLEEPFNGLGETBUFFERPOINTERVARBPROC) __GLeeGetProcAddress("glGetBufferPointervARB"))!=0) nLinked++; +#endif + if (nLinked==11) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_occlusion_query(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_occlusion_query + if ((GLeeFuncPtr_glGenQueriesARB = (GLEEPFNGLGENQUERIESARBPROC) __GLeeGetProcAddress("glGenQueriesARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteQueriesARB = (GLEEPFNGLDELETEQUERIESARBPROC) __GLeeGetProcAddress("glDeleteQueriesARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsQueryARB = (GLEEPFNGLISQUERYARBPROC) __GLeeGetProcAddress("glIsQueryARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glBeginQueryARB = (GLEEPFNGLBEGINQUERYARBPROC) __GLeeGetProcAddress("glBeginQueryARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndQueryARB = (GLEEPFNGLENDQUERYARBPROC) __GLeeGetProcAddress("glEndQueryARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetQueryivARB = (GLEEPFNGLGETQUERYIVARBPROC) __GLeeGetProcAddress("glGetQueryivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetQueryObjectivARB = (GLEEPFNGLGETQUERYOBJECTIVARBPROC) __GLeeGetProcAddress("glGetQueryObjectivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetQueryObjectuivARB = (GLEEPFNGLGETQUERYOBJECTUIVARBPROC) __GLeeGetProcAddress("glGetQueryObjectuivARB"))!=0) nLinked++; +#endif + if (nLinked==8) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_shader_objects(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_shader_objects + if ((GLeeFuncPtr_glDeleteObjectARB = (GLEEPFNGLDELETEOBJECTARBPROC) __GLeeGetProcAddress("glDeleteObjectARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetHandleARB = (GLEEPFNGLGETHANDLEARBPROC) __GLeeGetProcAddress("glGetHandleARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDetachObjectARB = (GLEEPFNGLDETACHOBJECTARBPROC) __GLeeGetProcAddress("glDetachObjectARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCreateShaderObjectARB = (GLEEPFNGLCREATESHADEROBJECTARBPROC) __GLeeGetProcAddress("glCreateShaderObjectARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glShaderSourceARB = (GLEEPFNGLSHADERSOURCEARBPROC) __GLeeGetProcAddress("glShaderSourceARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompileShaderARB = (GLEEPFNGLCOMPILESHADERARBPROC) __GLeeGetProcAddress("glCompileShaderARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glCreateProgramObjectARB = (GLEEPFNGLCREATEPROGRAMOBJECTARBPROC) __GLeeGetProcAddress("glCreateProgramObjectARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glAttachObjectARB = (GLEEPFNGLATTACHOBJECTARBPROC) __GLeeGetProcAddress("glAttachObjectARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glLinkProgramARB = (GLEEPFNGLLINKPROGRAMARBPROC) __GLeeGetProcAddress("glLinkProgramARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUseProgramObjectARB = (GLEEPFNGLUSEPROGRAMOBJECTARBPROC) __GLeeGetProcAddress("glUseProgramObjectARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glValidateProgramARB = (GLEEPFNGLVALIDATEPROGRAMARBPROC) __GLeeGetProcAddress("glValidateProgramARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1fARB = (GLEEPFNGLUNIFORM1FARBPROC) __GLeeGetProcAddress("glUniform1fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2fARB = (GLEEPFNGLUNIFORM2FARBPROC) __GLeeGetProcAddress("glUniform2fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3fARB = (GLEEPFNGLUNIFORM3FARBPROC) __GLeeGetProcAddress("glUniform3fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4fARB = (GLEEPFNGLUNIFORM4FARBPROC) __GLeeGetProcAddress("glUniform4fARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1iARB = (GLEEPFNGLUNIFORM1IARBPROC) __GLeeGetProcAddress("glUniform1iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2iARB = (GLEEPFNGLUNIFORM2IARBPROC) __GLeeGetProcAddress("glUniform2iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3iARB = (GLEEPFNGLUNIFORM3IARBPROC) __GLeeGetProcAddress("glUniform3iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4iARB = (GLEEPFNGLUNIFORM4IARBPROC) __GLeeGetProcAddress("glUniform4iARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1fvARB = (GLEEPFNGLUNIFORM1FVARBPROC) __GLeeGetProcAddress("glUniform1fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2fvARB = (GLEEPFNGLUNIFORM2FVARBPROC) __GLeeGetProcAddress("glUniform2fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3fvARB = (GLEEPFNGLUNIFORM3FVARBPROC) __GLeeGetProcAddress("glUniform3fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4fvARB = (GLEEPFNGLUNIFORM4FVARBPROC) __GLeeGetProcAddress("glUniform4fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1ivARB = (GLEEPFNGLUNIFORM1IVARBPROC) __GLeeGetProcAddress("glUniform1ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2ivARB = (GLEEPFNGLUNIFORM2IVARBPROC) __GLeeGetProcAddress("glUniform2ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3ivARB = (GLEEPFNGLUNIFORM3IVARBPROC) __GLeeGetProcAddress("glUniform3ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4ivARB = (GLEEPFNGLUNIFORM4IVARBPROC) __GLeeGetProcAddress("glUniform4ivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix2fvARB = (GLEEPFNGLUNIFORMMATRIX2FVARBPROC) __GLeeGetProcAddress("glUniformMatrix2fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix3fvARB = (GLEEPFNGLUNIFORMMATRIX3FVARBPROC) __GLeeGetProcAddress("glUniformMatrix3fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformMatrix4fvARB = (GLEEPFNGLUNIFORMMATRIX4FVARBPROC) __GLeeGetProcAddress("glUniformMatrix4fvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetObjectParameterfvARB = (GLEEPFNGLGETOBJECTPARAMETERFVARBPROC) __GLeeGetProcAddress("glGetObjectParameterfvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetObjectParameterivARB = (GLEEPFNGLGETOBJECTPARAMETERIVARBPROC) __GLeeGetProcAddress("glGetObjectParameterivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetInfoLogARB = (GLEEPFNGLGETINFOLOGARBPROC) __GLeeGetProcAddress("glGetInfoLogARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetAttachedObjectsARB = (GLEEPFNGLGETATTACHEDOBJECTSARBPROC) __GLeeGetProcAddress("glGetAttachedObjectsARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformLocationARB = (GLEEPFNGLGETUNIFORMLOCATIONARBPROC) __GLeeGetProcAddress("glGetUniformLocationARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetActiveUniformARB = (GLEEPFNGLGETACTIVEUNIFORMARBPROC) __GLeeGetProcAddress("glGetActiveUniformARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformfvARB = (GLEEPFNGLGETUNIFORMFVARBPROC) __GLeeGetProcAddress("glGetUniformfvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformivARB = (GLEEPFNGLGETUNIFORMIVARBPROC) __GLeeGetProcAddress("glGetUniformivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetShaderSourceARB = (GLEEPFNGLGETSHADERSOURCEARBPROC) __GLeeGetProcAddress("glGetShaderSourceARB"))!=0) nLinked++; +#endif + if (nLinked==39) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_vertex_shader(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_vertex_shader + if ((GLeeFuncPtr_glBindAttribLocationARB = (GLEEPFNGLBINDATTRIBLOCATIONARBPROC) __GLeeGetProcAddress("glBindAttribLocationARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetActiveAttribARB = (GLEEPFNGLGETACTIVEATTRIBARBPROC) __GLeeGetProcAddress("glGetActiveAttribARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetAttribLocationARB = (GLEEPFNGLGETATTRIBLOCATIONARBPROC) __GLeeGetProcAddress("glGetAttribLocationARB"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_fragment_shader(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_shading_language_100(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_non_power_of_two(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_point_sprite(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_fragment_program_shadow(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_draw_buffers(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_draw_buffers + if ((GLeeFuncPtr_glDrawBuffersARB = (GLEEPFNGLDRAWBUFFERSARBPROC) __GLeeGetProcAddress("glDrawBuffersARB"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_rectangle(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_color_buffer_float(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_color_buffer_float + if ((GLeeFuncPtr_glClampColorARB = (GLEEPFNGLCLAMPCOLORARBPROC) __GLeeGetProcAddress("glClampColorARB"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_half_float_pixel(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_pixel_buffer_object(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_depth_buffer_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_draw_instanced(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_draw_instanced + if ((GLeeFuncPtr_glDrawArraysInstancedARB = (GLEEPFNGLDRAWARRAYSINSTANCEDARBPROC) __GLeeGetProcAddress("glDrawArraysInstancedARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawElementsInstancedARB = (GLEEPFNGLDRAWELEMENTSINSTANCEDARBPROC) __GLeeGetProcAddress("glDrawElementsInstancedARB"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_framebuffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_framebuffer_object + if ((GLeeFuncPtr_glIsRenderbuffer = (GLEEPFNGLISRENDERBUFFERPROC) __GLeeGetProcAddress("glIsRenderbuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindRenderbuffer = (GLEEPFNGLBINDRENDERBUFFERPROC) __GLeeGetProcAddress("glBindRenderbuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteRenderbuffers = (GLEEPFNGLDELETERENDERBUFFERSPROC) __GLeeGetProcAddress("glDeleteRenderbuffers"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenRenderbuffers = (GLEEPFNGLGENRENDERBUFFERSPROC) __GLeeGetProcAddress("glGenRenderbuffers"))!=0) nLinked++; + if ((GLeeFuncPtr_glRenderbufferStorage = (GLEEPFNGLRENDERBUFFERSTORAGEPROC) __GLeeGetProcAddress("glRenderbufferStorage"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetRenderbufferParameteriv = (GLEEPFNGLGETRENDERBUFFERPARAMETERIVPROC) __GLeeGetProcAddress("glGetRenderbufferParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsFramebuffer = (GLEEPFNGLISFRAMEBUFFERPROC) __GLeeGetProcAddress("glIsFramebuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindFramebuffer = (GLEEPFNGLBINDFRAMEBUFFERPROC) __GLeeGetProcAddress("glBindFramebuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteFramebuffers = (GLEEPFNGLDELETEFRAMEBUFFERSPROC) __GLeeGetProcAddress("glDeleteFramebuffers"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenFramebuffers = (GLEEPFNGLGENFRAMEBUFFERSPROC) __GLeeGetProcAddress("glGenFramebuffers"))!=0) nLinked++; + if ((GLeeFuncPtr_glCheckFramebufferStatus = (GLEEPFNGLCHECKFRAMEBUFFERSTATUSPROC) __GLeeGetProcAddress("glCheckFramebufferStatus"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTexture1D = (GLEEPFNGLFRAMEBUFFERTEXTURE1DPROC) __GLeeGetProcAddress("glFramebufferTexture1D"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTexture2D = (GLEEPFNGLFRAMEBUFFERTEXTURE2DPROC) __GLeeGetProcAddress("glFramebufferTexture2D"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTexture3D = (GLEEPFNGLFRAMEBUFFERTEXTURE3DPROC) __GLeeGetProcAddress("glFramebufferTexture3D"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferRenderbuffer = (GLEEPFNGLFRAMEBUFFERRENDERBUFFERPROC) __GLeeGetProcAddress("glFramebufferRenderbuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFramebufferAttachmentParameteriv = (GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) __GLeeGetProcAddress("glGetFramebufferAttachmentParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenerateMipmap = (GLEEPFNGLGENERATEMIPMAPPROC) __GLeeGetProcAddress("glGenerateMipmap"))!=0) nLinked++; + if ((GLeeFuncPtr_glBlitFramebuffer = (GLEEPFNGLBLITFRAMEBUFFERPROC) __GLeeGetProcAddress("glBlitFramebuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glRenderbufferStorageMultisample = (GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) __GLeeGetProcAddress("glRenderbufferStorageMultisample"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureLayer = (GLEEPFNGLFRAMEBUFFERTEXTURELAYERPROC) __GLeeGetProcAddress("glFramebufferTextureLayer"))!=0) nLinked++; +#endif + if (nLinked==20) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_framebuffer_sRGB(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_geometry_shader4(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_geometry_shader4 + if ((GLeeFuncPtr_glProgramParameteriARB = (GLEEPFNGLPROGRAMPARAMETERIARBPROC) __GLeeGetProcAddress("glProgramParameteriARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureARB = (GLEEPFNGLFRAMEBUFFERTEXTUREARBPROC) __GLeeGetProcAddress("glFramebufferTextureARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureLayerARB = (GLEEPFNGLFRAMEBUFFERTEXTURELAYERARBPROC) __GLeeGetProcAddress("glFramebufferTextureLayerARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureFaceARB = (GLEEPFNGLFRAMEBUFFERTEXTUREFACEARBPROC) __GLeeGetProcAddress("glFramebufferTextureFaceARB"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_half_float_vertex(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_instanced_arrays(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_instanced_arrays + if ((GLeeFuncPtr_glVertexAttribDivisor = (GLEEPFNGLVERTEXATTRIBDIVISORPROC) __GLeeGetProcAddress("glVertexAttribDivisor"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_map_buffer_range(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_map_buffer_range + if ((GLeeFuncPtr_glMapBufferRange = (GLEEPFNGLMAPBUFFERRANGEPROC) __GLeeGetProcAddress("glMapBufferRange"))!=0) nLinked++; + if ((GLeeFuncPtr_glFlushMappedBufferRange = (GLEEPFNGLFLUSHMAPPEDBUFFERRANGEPROC) __GLeeGetProcAddress("glFlushMappedBufferRange"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_buffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_texture_buffer_object + if ((GLeeFuncPtr_glTexBufferARB = (GLEEPFNGLTEXBUFFERARBPROC) __GLeeGetProcAddress("glTexBufferARB"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_compression_rgtc(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_rg(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_vertex_array_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_vertex_array_object + if ((GLeeFuncPtr_glBindVertexArray = (GLEEPFNGLBINDVERTEXARRAYPROC) __GLeeGetProcAddress("glBindVertexArray"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteVertexArrays = (GLEEPFNGLDELETEVERTEXARRAYSPROC) __GLeeGetProcAddress("glDeleteVertexArrays"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenVertexArrays = (GLEEPFNGLGENVERTEXARRAYSPROC) __GLeeGetProcAddress("glGenVertexArrays"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsVertexArray = (GLEEPFNGLISVERTEXARRAYPROC) __GLeeGetProcAddress("glIsVertexArray"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_abgr(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_blend_color(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_blend_color + if ((GLeeFuncPtr_glBlendColorEXT = (GLEEPFNGLBLENDCOLOREXTPROC) __GLeeGetProcAddress("glBlendColorEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_polygon_offset(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_polygon_offset + if ((GLeeFuncPtr_glPolygonOffsetEXT = (GLEEPFNGLPOLYGONOFFSETEXTPROC) __GLeeGetProcAddress("glPolygonOffsetEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture3D(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_texture3D + if ((GLeeFuncPtr_glTexImage3DEXT = (GLEEPFNGLTEXIMAGE3DEXTPROC) __GLeeGetProcAddress("glTexImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexSubImage3DEXT = (GLEEPFNGLTEXSUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glTexSubImage3DEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIS_texture_filter4(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_texture_filter4 + if ((GLeeFuncPtr_glGetTexFilterFuncSGIS = (GLEEPFNGLGETTEXFILTERFUNCSGISPROC) __GLeeGetProcAddress("glGetTexFilterFuncSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexFilterFuncSGIS = (GLEEPFNGLTEXFILTERFUNCSGISPROC) __GLeeGetProcAddress("glTexFilterFuncSGIS"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_subtexture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_subtexture + if ((GLeeFuncPtr_glTexSubImage1DEXT = (GLEEPFNGLTEXSUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glTexSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexSubImage2DEXT = (GLEEPFNGLTEXSUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glTexSubImage2DEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_copy_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_copy_texture + if ((GLeeFuncPtr_glCopyTexImage1DEXT = (GLEEPFNGLCOPYTEXIMAGE1DEXTPROC) __GLeeGetProcAddress("glCopyTexImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTexImage2DEXT = (GLEEPFNGLCOPYTEXIMAGE2DEXTPROC) __GLeeGetProcAddress("glCopyTexImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTexSubImage1DEXT = (GLEEPFNGLCOPYTEXSUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glCopyTexSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTexSubImage2DEXT = (GLEEPFNGLCOPYTEXSUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glCopyTexSubImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTexSubImage3DEXT = (GLEEPFNGLCOPYTEXSUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glCopyTexSubImage3DEXT"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_histogram(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_histogram + if ((GLeeFuncPtr_glGetHistogramEXT = (GLEEPFNGLGETHISTOGRAMEXTPROC) __GLeeGetProcAddress("glGetHistogramEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetHistogramParameterfvEXT = (GLEEPFNGLGETHISTOGRAMPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetHistogramParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetHistogramParameterivEXT = (GLEEPFNGLGETHISTOGRAMPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetHistogramParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMinmaxEXT = (GLEEPFNGLGETMINMAXEXTPROC) __GLeeGetProcAddress("glGetMinmaxEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMinmaxParameterfvEXT = (GLEEPFNGLGETMINMAXPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetMinmaxParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMinmaxParameterivEXT = (GLEEPFNGLGETMINMAXPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetMinmaxParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glHistogramEXT = (GLEEPFNGLHISTOGRAMEXTPROC) __GLeeGetProcAddress("glHistogramEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMinmaxEXT = (GLEEPFNGLMINMAXEXTPROC) __GLeeGetProcAddress("glMinmaxEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glResetHistogramEXT = (GLEEPFNGLRESETHISTOGRAMEXTPROC) __GLeeGetProcAddress("glResetHistogramEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glResetMinmaxEXT = (GLEEPFNGLRESETMINMAXEXTPROC) __GLeeGetProcAddress("glResetMinmaxEXT"))!=0) nLinked++; +#endif + if (nLinked==10) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_convolution(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_convolution + if ((GLeeFuncPtr_glConvolutionFilter1DEXT = (GLEEPFNGLCONVOLUTIONFILTER1DEXTPROC) __GLeeGetProcAddress("glConvolutionFilter1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionFilter2DEXT = (GLEEPFNGLCONVOLUTIONFILTER2DEXTPROC) __GLeeGetProcAddress("glConvolutionFilter2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameterfEXT = (GLEEPFNGLCONVOLUTIONPARAMETERFEXTPROC) __GLeeGetProcAddress("glConvolutionParameterfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameterfvEXT = (GLEEPFNGLCONVOLUTIONPARAMETERFVEXTPROC) __GLeeGetProcAddress("glConvolutionParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameteriEXT = (GLEEPFNGLCONVOLUTIONPARAMETERIEXTPROC) __GLeeGetProcAddress("glConvolutionParameteriEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameterivEXT = (GLEEPFNGLCONVOLUTIONPARAMETERIVEXTPROC) __GLeeGetProcAddress("glConvolutionParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyConvolutionFilter1DEXT = (GLEEPFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) __GLeeGetProcAddress("glCopyConvolutionFilter1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyConvolutionFilter2DEXT = (GLEEPFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) __GLeeGetProcAddress("glCopyConvolutionFilter2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetConvolutionFilterEXT = (GLEEPFNGLGETCONVOLUTIONFILTEREXTPROC) __GLeeGetProcAddress("glGetConvolutionFilterEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetConvolutionParameterfvEXT = (GLEEPFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetConvolutionParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetConvolutionParameterivEXT = (GLEEPFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetConvolutionParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetSeparableFilterEXT = (GLEEPFNGLGETSEPARABLEFILTEREXTPROC) __GLeeGetProcAddress("glGetSeparableFilterEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSeparableFilter2DEXT = (GLEEPFNGLSEPARABLEFILTER2DEXTPROC) __GLeeGetProcAddress("glSeparableFilter2DEXT"))!=0) nLinked++; +#endif + if (nLinked==13) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGI_color_matrix(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGI_color_table(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGI_color_table + if ((GLeeFuncPtr_glColorTableSGI = (GLEEPFNGLCOLORTABLESGIPROC) __GLeeGetProcAddress("glColorTableSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorTableParameterfvSGI = (GLEEPFNGLCOLORTABLEPARAMETERFVSGIPROC) __GLeeGetProcAddress("glColorTableParameterfvSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorTableParameterivSGI = (GLEEPFNGLCOLORTABLEPARAMETERIVSGIPROC) __GLeeGetProcAddress("glColorTableParameterivSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyColorTableSGI = (GLEEPFNGLCOPYCOLORTABLESGIPROC) __GLeeGetProcAddress("glCopyColorTableSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableSGI = (GLEEPFNGLGETCOLORTABLESGIPROC) __GLeeGetProcAddress("glGetColorTableSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableParameterfvSGI = (GLEEPFNGLGETCOLORTABLEPARAMETERFVSGIPROC) __GLeeGetProcAddress("glGetColorTableParameterfvSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableParameterivSGI = (GLEEPFNGLGETCOLORTABLEPARAMETERIVSGIPROC) __GLeeGetProcAddress("glGetColorTableParameterivSGI"))!=0) nLinked++; +#endif + if (nLinked==7) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIS_pixel_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_pixel_texture + if ((GLeeFuncPtr_glPixelTexGenParameteriSGIS = (GLEEPFNGLPIXELTEXGENPARAMETERISGISPROC) __GLeeGetProcAddress("glPixelTexGenParameteriSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelTexGenParameterivSGIS = (GLEEPFNGLPIXELTEXGENPARAMETERIVSGISPROC) __GLeeGetProcAddress("glPixelTexGenParameterivSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelTexGenParameterfSGIS = (GLEEPFNGLPIXELTEXGENPARAMETERFSGISPROC) __GLeeGetProcAddress("glPixelTexGenParameterfSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelTexGenParameterfvSGIS = (GLEEPFNGLPIXELTEXGENPARAMETERFVSGISPROC) __GLeeGetProcAddress("glPixelTexGenParameterfvSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPixelTexGenParameterivSGIS = (GLEEPFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) __GLeeGetProcAddress("glGetPixelTexGenParameterivSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPixelTexGenParameterfvSGIS = (GLEEPFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) __GLeeGetProcAddress("glGetPixelTexGenParameterfvSGIS"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_pixel_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_pixel_texture + if ((GLeeFuncPtr_glPixelTexGenSGIX = (GLEEPFNGLPIXELTEXGENSGIXPROC) __GLeeGetProcAddress("glPixelTexGenSGIX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIS_texture4D(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_texture4D + if ((GLeeFuncPtr_glTexImage4DSGIS = (GLEEPFNGLTEXIMAGE4DSGISPROC) __GLeeGetProcAddress("glTexImage4DSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexSubImage4DSGIS = (GLEEPFNGLTEXSUBIMAGE4DSGISPROC) __GLeeGetProcAddress("glTexSubImage4DSGIS"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGI_texture_color_table(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_cmyka(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_texture_object + if ((GLeeFuncPtr_glAreTexturesResidentEXT = (GLEEPFNGLARETEXTURESRESIDENTEXTPROC) __GLeeGetProcAddress("glAreTexturesResidentEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindTextureEXT = (GLEEPFNGLBINDTEXTUREEXTPROC) __GLeeGetProcAddress("glBindTextureEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteTexturesEXT = (GLEEPFNGLDELETETEXTURESEXTPROC) __GLeeGetProcAddress("glDeleteTexturesEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenTexturesEXT = (GLEEPFNGLGENTEXTURESEXTPROC) __GLeeGetProcAddress("glGenTexturesEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsTextureEXT = (GLEEPFNGLISTEXTUREEXTPROC) __GLeeGetProcAddress("glIsTextureEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glPrioritizeTexturesEXT = (GLEEPFNGLPRIORITIZETEXTURESEXTPROC) __GLeeGetProcAddress("glPrioritizeTexturesEXT"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIS_detail_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_detail_texture + if ((GLeeFuncPtr_glDetailTexFuncSGIS = (GLEEPFNGLDETAILTEXFUNCSGISPROC) __GLeeGetProcAddress("glDetailTexFuncSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetDetailTexFuncSGIS = (GLEEPFNGLGETDETAILTEXFUNCSGISPROC) __GLeeGetProcAddress("glGetDetailTexFuncSGIS"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIS_sharpen_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_sharpen_texture + if ((GLeeFuncPtr_glSharpenTexFuncSGIS = (GLEEPFNGLSHARPENTEXFUNCSGISPROC) __GLeeGetProcAddress("glSharpenTexFuncSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetSharpenTexFuncSGIS = (GLEEPFNGLGETSHARPENTEXFUNCSGISPROC) __GLeeGetProcAddress("glGetSharpenTexFuncSGIS"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_packed_pixels(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_texture_lod(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_multisample(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_multisample + if ((GLeeFuncPtr_glSampleMaskSGIS = (GLEEPFNGLSAMPLEMASKSGISPROC) __GLeeGetProcAddress("glSampleMaskSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glSamplePatternSGIS = (GLEEPFNGLSAMPLEPATTERNSGISPROC) __GLeeGetProcAddress("glSamplePatternSGIS"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_rescale_normal(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_vertex_array(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_vertex_array + if ((GLeeFuncPtr_glArrayElementEXT = (GLEEPFNGLARRAYELEMENTEXTPROC) __GLeeGetProcAddress("glArrayElementEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorPointerEXT = (GLEEPFNGLCOLORPOINTEREXTPROC) __GLeeGetProcAddress("glColorPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawArraysEXT = (GLEEPFNGLDRAWARRAYSEXTPROC) __GLeeGetProcAddress("glDrawArraysEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glEdgeFlagPointerEXT = (GLEEPFNGLEDGEFLAGPOINTEREXTPROC) __GLeeGetProcAddress("glEdgeFlagPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPointervEXT = (GLEEPFNGLGETPOINTERVEXTPROC) __GLeeGetProcAddress("glGetPointervEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glIndexPointerEXT = (GLEEPFNGLINDEXPOINTEREXTPROC) __GLeeGetProcAddress("glIndexPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalPointerEXT = (GLEEPFNGLNORMALPOINTEREXTPROC) __GLeeGetProcAddress("glNormalPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoordPointerEXT = (GLEEPFNGLTEXCOORDPOINTEREXTPROC) __GLeeGetProcAddress("glTexCoordPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexPointerEXT = (GLEEPFNGLVERTEXPOINTEREXTPROC) __GLeeGetProcAddress("glVertexPointerEXT"))!=0) nLinked++; +#endif + if (nLinked==9) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_misc_attribute(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_generate_mipmap(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_clipmap(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_shadow(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_texture_edge_clamp(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_texture_border_clamp(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_blend_minmax(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_blend_minmax + if ((GLeeFuncPtr_glBlendEquationEXT = (GLEEPFNGLBLENDEQUATIONEXTPROC) __GLeeGetProcAddress("glBlendEquationEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_blend_subtract(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_blend_logic_op(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_interlace(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_pixel_tiles(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_texture_select(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_sprite(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_sprite + if ((GLeeFuncPtr_glSpriteParameterfSGIX = (GLEEPFNGLSPRITEPARAMETERFSGIXPROC) __GLeeGetProcAddress("glSpriteParameterfSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glSpriteParameterfvSGIX = (GLEEPFNGLSPRITEPARAMETERFVSGIXPROC) __GLeeGetProcAddress("glSpriteParameterfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glSpriteParameteriSGIX = (GLEEPFNGLSPRITEPARAMETERISGIXPROC) __GLeeGetProcAddress("glSpriteParameteriSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glSpriteParameterivSGIX = (GLEEPFNGLSPRITEPARAMETERIVSGIXPROC) __GLeeGetProcAddress("glSpriteParameterivSGIX"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_texture_multi_buffer(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_point_parameters(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_point_parameters + if ((GLeeFuncPtr_glPointParameterfEXT = (GLEEPFNGLPOINTPARAMETERFEXTPROC) __GLeeGetProcAddress("glPointParameterfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameterfvEXT = (GLEEPFNGLPOINTPARAMETERFVEXTPROC) __GLeeGetProcAddress("glPointParameterfvEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIS_point_parameters(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_point_parameters + if ((GLeeFuncPtr_glPointParameterfSGIS = (GLEEPFNGLPOINTPARAMETERFSGISPROC) __GLeeGetProcAddress("glPointParameterfSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameterfvSGIS = (GLEEPFNGLPOINTPARAMETERFVSGISPROC) __GLeeGetProcAddress("glPointParameterfvSGIS"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_instruments(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_instruments + if ((GLeeFuncPtr_glGetInstrumentsSGIX = (GLEEPFNGLGETINSTRUMENTSSGIXPROC) __GLeeGetProcAddress("glGetInstrumentsSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glInstrumentsBufferSGIX = (GLEEPFNGLINSTRUMENTSBUFFERSGIXPROC) __GLeeGetProcAddress("glInstrumentsBufferSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glPollInstrumentsSGIX = (GLEEPFNGLPOLLINSTRUMENTSSGIXPROC) __GLeeGetProcAddress("glPollInstrumentsSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glReadInstrumentsSGIX = (GLEEPFNGLREADINSTRUMENTSSGIXPROC) __GLeeGetProcAddress("glReadInstrumentsSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glStartInstrumentsSGIX = (GLEEPFNGLSTARTINSTRUMENTSSGIXPROC) __GLeeGetProcAddress("glStartInstrumentsSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glStopInstrumentsSGIX = (GLEEPFNGLSTOPINSTRUMENTSSGIXPROC) __GLeeGetProcAddress("glStopInstrumentsSGIX"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_texture_scale_bias(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_framezoom(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_framezoom + if ((GLeeFuncPtr_glFrameZoomSGIX = (GLEEPFNGLFRAMEZOOMSGIXPROC) __GLeeGetProcAddress("glFrameZoomSGIX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_tag_sample_buffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_tag_sample_buffer + if ((GLeeFuncPtr_glTagSampleBufferSGIX = (GLEEPFNGLTAGSAMPLEBUFFERSGIXPROC) __GLeeGetProcAddress("glTagSampleBufferSGIX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_FfdMaskSGIX(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_polynomial_ffd(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_polynomial_ffd + if ((GLeeFuncPtr_glDeformationMap3dSGIX = (GLEEPFNGLDEFORMATIONMAP3DSGIXPROC) __GLeeGetProcAddress("glDeformationMap3dSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeformationMap3fSGIX = (GLEEPFNGLDEFORMATIONMAP3FSGIXPROC) __GLeeGetProcAddress("glDeformationMap3fSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeformSGIX = (GLEEPFNGLDEFORMSGIXPROC) __GLeeGetProcAddress("glDeformSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glLoadIdentityDeformationMapSGIX = (GLEEPFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) __GLeeGetProcAddress("glLoadIdentityDeformationMapSGIX"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_reference_plane(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_reference_plane + if ((GLeeFuncPtr_glReferencePlaneSGIX = (GLEEPFNGLREFERENCEPLANESGIXPROC) __GLeeGetProcAddress("glReferencePlaneSGIX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_flush_raster(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_flush_raster + if ((GLeeFuncPtr_glFlushRasterSGIX = (GLEEPFNGLFLUSHRASTERSGIXPROC) __GLeeGetProcAddress("glFlushRasterSGIX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_depth_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_fog_function(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_fog_function + if ((GLeeFuncPtr_glFogFuncSGIS = (GLEEPFNGLFOGFUNCSGISPROC) __GLeeGetProcAddress("glFogFuncSGIS"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFogFuncSGIS = (GLEEPFNGLGETFOGFUNCSGISPROC) __GLeeGetProcAddress("glGetFogFuncSGIS"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_fog_offset(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_HP_image_transform(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_HP_image_transform + if ((GLeeFuncPtr_glImageTransformParameteriHP = (GLEEPFNGLIMAGETRANSFORMPARAMETERIHPPROC) __GLeeGetProcAddress("glImageTransformParameteriHP"))!=0) nLinked++; + if ((GLeeFuncPtr_glImageTransformParameterfHP = (GLEEPFNGLIMAGETRANSFORMPARAMETERFHPPROC) __GLeeGetProcAddress("glImageTransformParameterfHP"))!=0) nLinked++; + if ((GLeeFuncPtr_glImageTransformParameterivHP = (GLEEPFNGLIMAGETRANSFORMPARAMETERIVHPPROC) __GLeeGetProcAddress("glImageTransformParameterivHP"))!=0) nLinked++; + if ((GLeeFuncPtr_glImageTransformParameterfvHP = (GLEEPFNGLIMAGETRANSFORMPARAMETERFVHPPROC) __GLeeGetProcAddress("glImageTransformParameterfvHP"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetImageTransformParameterivHP = (GLEEPFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) __GLeeGetProcAddress("glGetImageTransformParameterivHP"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetImageTransformParameterfvHP = (GLEEPFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) __GLeeGetProcAddress("glGetImageTransformParameterfvHP"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_HP_convolution_border_modes(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_INGR_palette_buffer(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_texture_add_env(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_color_subtable(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_color_subtable + if ((GLeeFuncPtr_glColorSubTableEXT = (GLEEPFNGLCOLORSUBTABLEEXTPROC) __GLeeGetProcAddress("glColorSubTableEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyColorSubTableEXT = (GLEEPFNGLCOPYCOLORSUBTABLEEXTPROC) __GLeeGetProcAddress("glCopyColorSubTableEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_PGI_vertex_hints(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_PGI_misc_hints(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_PGI_misc_hints + if ((GLeeFuncPtr_glHintPGI = (GLEEPFNGLHINTPGIPROC) __GLeeGetProcAddress("glHintPGI"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_paletted_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_paletted_texture + if ((GLeeFuncPtr_glColorTableEXT = (GLEEPFNGLCOLORTABLEEXTPROC) __GLeeGetProcAddress("glColorTableEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableEXT = (GLEEPFNGLGETCOLORTABLEEXTPROC) __GLeeGetProcAddress("glGetColorTableEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableParameterivEXT = (GLEEPFNGLGETCOLORTABLEPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetColorTableParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetColorTableParameterfvEXT = (GLEEPFNGLGETCOLORTABLEPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetColorTableParameterfvEXT"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_clip_volume_hint(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_list_priority(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_list_priority + if ((GLeeFuncPtr_glGetListParameterfvSGIX = (GLEEPFNGLGETLISTPARAMETERFVSGIXPROC) __GLeeGetProcAddress("glGetListParameterfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetListParameterivSGIX = (GLEEPFNGLGETLISTPARAMETERIVSGIXPROC) __GLeeGetProcAddress("glGetListParameterivSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glListParameterfSGIX = (GLEEPFNGLLISTPARAMETERFSGIXPROC) __GLeeGetProcAddress("glListParameterfSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glListParameterfvSGIX = (GLEEPFNGLLISTPARAMETERFVSGIXPROC) __GLeeGetProcAddress("glListParameterfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glListParameteriSGIX = (GLEEPFNGLLISTPARAMETERISGIXPROC) __GLeeGetProcAddress("glListParameteriSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glListParameterivSGIX = (GLEEPFNGLLISTPARAMETERIVSGIXPROC) __GLeeGetProcAddress("glListParameterivSGIX"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_ir_instrument1(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_calligraphic_fragment(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_texture_lod_bias(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_shadow_ambient(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_index_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_index_material(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_index_material + if ((GLeeFuncPtr_glIndexMaterialEXT = (GLEEPFNGLINDEXMATERIALEXTPROC) __GLeeGetProcAddress("glIndexMaterialEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_index_func(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_index_func + if ((GLeeFuncPtr_glIndexFuncEXT = (GLEEPFNGLINDEXFUNCEXTPROC) __GLeeGetProcAddress("glIndexFuncEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_index_array_formats(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_compiled_vertex_array(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_compiled_vertex_array + if ((GLeeFuncPtr_glLockArraysEXT = (GLEEPFNGLLOCKARRAYSEXTPROC) __GLeeGetProcAddress("glLockArraysEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUnlockArraysEXT = (GLEEPFNGLUNLOCKARRAYSEXTPROC) __GLeeGetProcAddress("glUnlockArraysEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_cull_vertex(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_cull_vertex + if ((GLeeFuncPtr_glCullParameterdvEXT = (GLEEPFNGLCULLPARAMETERDVEXTPROC) __GLeeGetProcAddress("glCullParameterdvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCullParameterfvEXT = (GLEEPFNGLCULLPARAMETERFVEXTPROC) __GLeeGetProcAddress("glCullParameterfvEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_ycrcb(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_fragment_lighting(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_fragment_lighting + if ((GLeeFuncPtr_glFragmentColorMaterialSGIX = (GLEEPFNGLFRAGMENTCOLORMATERIALSGIXPROC) __GLeeGetProcAddress("glFragmentColorMaterialSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightfSGIX = (GLEEPFNGLFRAGMENTLIGHTFSGIXPROC) __GLeeGetProcAddress("glFragmentLightfSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightfvSGIX = (GLEEPFNGLFRAGMENTLIGHTFVSGIXPROC) __GLeeGetProcAddress("glFragmentLightfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightiSGIX = (GLEEPFNGLFRAGMENTLIGHTISGIXPROC) __GLeeGetProcAddress("glFragmentLightiSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightivSGIX = (GLEEPFNGLFRAGMENTLIGHTIVSGIXPROC) __GLeeGetProcAddress("glFragmentLightivSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightModelfSGIX = (GLEEPFNGLFRAGMENTLIGHTMODELFSGIXPROC) __GLeeGetProcAddress("glFragmentLightModelfSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightModelfvSGIX = (GLEEPFNGLFRAGMENTLIGHTMODELFVSGIXPROC) __GLeeGetProcAddress("glFragmentLightModelfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightModeliSGIX = (GLEEPFNGLFRAGMENTLIGHTMODELISGIXPROC) __GLeeGetProcAddress("glFragmentLightModeliSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightModelivSGIX = (GLEEPFNGLFRAGMENTLIGHTMODELIVSGIXPROC) __GLeeGetProcAddress("glFragmentLightModelivSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialfSGIX = (GLEEPFNGLFRAGMENTMATERIALFSGIXPROC) __GLeeGetProcAddress("glFragmentMaterialfSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialfvSGIX = (GLEEPFNGLFRAGMENTMATERIALFVSGIXPROC) __GLeeGetProcAddress("glFragmentMaterialfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialiSGIX = (GLEEPFNGLFRAGMENTMATERIALISGIXPROC) __GLeeGetProcAddress("glFragmentMaterialiSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialivSGIX = (GLEEPFNGLFRAGMENTMATERIALIVSGIXPROC) __GLeeGetProcAddress("glFragmentMaterialivSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentLightfvSGIX = (GLEEPFNGLGETFRAGMENTLIGHTFVSGIXPROC) __GLeeGetProcAddress("glGetFragmentLightfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentLightivSGIX = (GLEEPFNGLGETFRAGMENTLIGHTIVSGIXPROC) __GLeeGetProcAddress("glGetFragmentLightivSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentMaterialfvSGIX = (GLEEPFNGLGETFRAGMENTMATERIALFVSGIXPROC) __GLeeGetProcAddress("glGetFragmentMaterialfvSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentMaterialivSGIX = (GLEEPFNGLGETFRAGMENTMATERIALIVSGIXPROC) __GLeeGetProcAddress("glGetFragmentMaterialivSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glLightEnviSGIX = (GLEEPFNGLLIGHTENVISGIXPROC) __GLeeGetProcAddress("glLightEnviSGIX"))!=0) nLinked++; +#endif + if (nLinked==18) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_IBM_rasterpos_clip(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_HP_texture_lighting(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_draw_range_elements(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_draw_range_elements + if ((GLeeFuncPtr_glDrawRangeElementsEXT = (GLEEPFNGLDRAWRANGEELEMENTSEXTPROC) __GLeeGetProcAddress("glDrawRangeElementsEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_WIN_phong_shading(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_WIN_specular_fog(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_light_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_light_texture + if ((GLeeFuncPtr_glApplyTextureEXT = (GLEEPFNGLAPPLYTEXTUREEXTPROC) __GLeeGetProcAddress("glApplyTextureEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureLightEXT = (GLEEPFNGLTEXTURELIGHTEXTPROC) __GLeeGetProcAddress("glTextureLightEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureMaterialEXT = (GLEEPFNGLTEXTUREMATERIALEXTPROC) __GLeeGetProcAddress("glTextureMaterialEXT"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_blend_alpha_minmax(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_impact_pixel_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_bgra(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_async(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_async + if ((GLeeFuncPtr_glAsyncMarkerSGIX = (GLEEPFNGLASYNCMARKERSGIXPROC) __GLeeGetProcAddress("glAsyncMarkerSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glFinishAsyncSGIX = (GLEEPFNGLFINISHASYNCSGIXPROC) __GLeeGetProcAddress("glFinishAsyncSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glPollAsyncSGIX = (GLEEPFNGLPOLLASYNCSGIXPROC) __GLeeGetProcAddress("glPollAsyncSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenAsyncMarkersSGIX = (GLEEPFNGLGENASYNCMARKERSSGIXPROC) __GLeeGetProcAddress("glGenAsyncMarkersSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteAsyncMarkersSGIX = (GLEEPFNGLDELETEASYNCMARKERSSGIXPROC) __GLeeGetProcAddress("glDeleteAsyncMarkersSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsAsyncMarkerSGIX = (GLEEPFNGLISASYNCMARKERSGIXPROC) __GLeeGetProcAddress("glIsAsyncMarkerSGIX"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_async_pixel(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_async_histogram(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_INTEL_texture_scissor(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_INTEL_parallel_arrays(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_INTEL_parallel_arrays + if ((GLeeFuncPtr_glVertexPointervINTEL = (GLEEPFNGLVERTEXPOINTERVINTELPROC) __GLeeGetProcAddress("glVertexPointervINTEL"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalPointervINTEL = (GLEEPFNGLNORMALPOINTERVINTELPROC) __GLeeGetProcAddress("glNormalPointervINTEL"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorPointervINTEL = (GLEEPFNGLCOLORPOINTERVINTELPROC) __GLeeGetProcAddress("glColorPointervINTEL"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoordPointervINTEL = (GLEEPFNGLTEXCOORDPOINTERVINTELPROC) __GLeeGetProcAddress("glTexCoordPointervINTEL"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_HP_occlusion_test(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_pixel_transform(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_pixel_transform + if ((GLeeFuncPtr_glPixelTransformParameteriEXT = (GLEEPFNGLPIXELTRANSFORMPARAMETERIEXTPROC) __GLeeGetProcAddress("glPixelTransformParameteriEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelTransformParameterfEXT = (GLEEPFNGLPIXELTRANSFORMPARAMETERFEXTPROC) __GLeeGetProcAddress("glPixelTransformParameterfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelTransformParameterivEXT = (GLEEPFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) __GLeeGetProcAddress("glPixelTransformParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelTransformParameterfvEXT = (GLEEPFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) __GLeeGetProcAddress("glPixelTransformParameterfvEXT"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_pixel_transform_color_table(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_shared_texture_palette(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_separate_specular_color(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_secondary_color(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_secondary_color + if ((GLeeFuncPtr_glSecondaryColor3bEXT = (GLEEPFNGLSECONDARYCOLOR3BEXTPROC) __GLeeGetProcAddress("glSecondaryColor3bEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3bvEXT = (GLEEPFNGLSECONDARYCOLOR3BVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3bvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3dEXT = (GLEEPFNGLSECONDARYCOLOR3DEXTPROC) __GLeeGetProcAddress("glSecondaryColor3dEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3dvEXT = (GLEEPFNGLSECONDARYCOLOR3DVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3dvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3fEXT = (GLEEPFNGLSECONDARYCOLOR3FEXTPROC) __GLeeGetProcAddress("glSecondaryColor3fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3fvEXT = (GLEEPFNGLSECONDARYCOLOR3FVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3iEXT = (GLEEPFNGLSECONDARYCOLOR3IEXTPROC) __GLeeGetProcAddress("glSecondaryColor3iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3ivEXT = (GLEEPFNGLSECONDARYCOLOR3IVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3sEXT = (GLEEPFNGLSECONDARYCOLOR3SEXTPROC) __GLeeGetProcAddress("glSecondaryColor3sEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3svEXT = (GLEEPFNGLSECONDARYCOLOR3SVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3svEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3ubEXT = (GLEEPFNGLSECONDARYCOLOR3UBEXTPROC) __GLeeGetProcAddress("glSecondaryColor3ubEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3ubvEXT = (GLEEPFNGLSECONDARYCOLOR3UBVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3ubvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3uiEXT = (GLEEPFNGLSECONDARYCOLOR3UIEXTPROC) __GLeeGetProcAddress("glSecondaryColor3uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3uivEXT = (GLEEPFNGLSECONDARYCOLOR3UIVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3usEXT = (GLEEPFNGLSECONDARYCOLOR3USEXTPROC) __GLeeGetProcAddress("glSecondaryColor3usEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3usvEXT = (GLEEPFNGLSECONDARYCOLOR3USVEXTPROC) __GLeeGetProcAddress("glSecondaryColor3usvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColorPointerEXT = (GLEEPFNGLSECONDARYCOLORPOINTEREXTPROC) __GLeeGetProcAddress("glSecondaryColorPointerEXT"))!=0) nLinked++; +#endif + if (nLinked==17) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_perturb_normal(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_texture_perturb_normal + if ((GLeeFuncPtr_glTextureNormalEXT = (GLEEPFNGLTEXTURENORMALEXTPROC) __GLeeGetProcAddress("glTextureNormalEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_multi_draw_arrays(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_multi_draw_arrays + if ((GLeeFuncPtr_glMultiDrawArraysEXT = (GLEEPFNGLMULTIDRAWARRAYSEXTPROC) __GLeeGetProcAddress("glMultiDrawArraysEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiDrawElementsEXT = (GLEEPFNGLMULTIDRAWELEMENTSEXTPROC) __GLeeGetProcAddress("glMultiDrawElementsEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_fog_coord(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_fog_coord + if ((GLeeFuncPtr_glFogCoordfEXT = (GLEEPFNGLFOGCOORDFEXTPROC) __GLeeGetProcAddress("glFogCoordfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordfvEXT = (GLEEPFNGLFOGCOORDFVEXTPROC) __GLeeGetProcAddress("glFogCoordfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoorddEXT = (GLEEPFNGLFOGCOORDDEXTPROC) __GLeeGetProcAddress("glFogCoorddEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoorddvEXT = (GLEEPFNGLFOGCOORDDVEXTPROC) __GLeeGetProcAddress("glFogCoorddvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordPointerEXT = (GLEEPFNGLFOGCOORDPOINTEREXTPROC) __GLeeGetProcAddress("glFogCoordPointerEXT"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_REND_screen_coordinates(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_coordinate_frame(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_coordinate_frame + if ((GLeeFuncPtr_glTangent3bEXT = (GLEEPFNGLTANGENT3BEXTPROC) __GLeeGetProcAddress("glTangent3bEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3bvEXT = (GLEEPFNGLTANGENT3BVEXTPROC) __GLeeGetProcAddress("glTangent3bvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3dEXT = (GLEEPFNGLTANGENT3DEXTPROC) __GLeeGetProcAddress("glTangent3dEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3dvEXT = (GLEEPFNGLTANGENT3DVEXTPROC) __GLeeGetProcAddress("glTangent3dvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3fEXT = (GLEEPFNGLTANGENT3FEXTPROC) __GLeeGetProcAddress("glTangent3fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3fvEXT = (GLEEPFNGLTANGENT3FVEXTPROC) __GLeeGetProcAddress("glTangent3fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3iEXT = (GLEEPFNGLTANGENT3IEXTPROC) __GLeeGetProcAddress("glTangent3iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3ivEXT = (GLEEPFNGLTANGENT3IVEXTPROC) __GLeeGetProcAddress("glTangent3ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3sEXT = (GLEEPFNGLTANGENT3SEXTPROC) __GLeeGetProcAddress("glTangent3sEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangent3svEXT = (GLEEPFNGLTANGENT3SVEXTPROC) __GLeeGetProcAddress("glTangent3svEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3bEXT = (GLEEPFNGLBINORMAL3BEXTPROC) __GLeeGetProcAddress("glBinormal3bEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3bvEXT = (GLEEPFNGLBINORMAL3BVEXTPROC) __GLeeGetProcAddress("glBinormal3bvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3dEXT = (GLEEPFNGLBINORMAL3DEXTPROC) __GLeeGetProcAddress("glBinormal3dEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3dvEXT = (GLEEPFNGLBINORMAL3DVEXTPROC) __GLeeGetProcAddress("glBinormal3dvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3fEXT = (GLEEPFNGLBINORMAL3FEXTPROC) __GLeeGetProcAddress("glBinormal3fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3fvEXT = (GLEEPFNGLBINORMAL3FVEXTPROC) __GLeeGetProcAddress("glBinormal3fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3iEXT = (GLEEPFNGLBINORMAL3IEXTPROC) __GLeeGetProcAddress("glBinormal3iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3ivEXT = (GLEEPFNGLBINORMAL3IVEXTPROC) __GLeeGetProcAddress("glBinormal3ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3sEXT = (GLEEPFNGLBINORMAL3SEXTPROC) __GLeeGetProcAddress("glBinormal3sEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormal3svEXT = (GLEEPFNGLBINORMAL3SVEXTPROC) __GLeeGetProcAddress("glBinormal3svEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTangentPointerEXT = (GLEEPFNGLTANGENTPOINTEREXTPROC) __GLeeGetProcAddress("glTangentPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBinormalPointerEXT = (GLEEPFNGLBINORMALPOINTEREXTPROC) __GLeeGetProcAddress("glBinormalPointerEXT"))!=0) nLinked++; +#endif + if (nLinked==22) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_env_combine(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_APPLE_specular_vector(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_APPLE_transform_hint(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_fog_scale(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SUNX_constant_data(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SUNX_constant_data + if ((GLeeFuncPtr_glFinishTextureSUNX = (GLEEPFNGLFINISHTEXTURESUNXPROC) __GLeeGetProcAddress("glFinishTextureSUNX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SUN_global_alpha(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SUN_global_alpha + if ((GLeeFuncPtr_glGlobalAlphaFactorbSUN = (GLEEPFNGLGLOBALALPHAFACTORBSUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactorbSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glGlobalAlphaFactorsSUN = (GLEEPFNGLGLOBALALPHAFACTORSSUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactorsSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glGlobalAlphaFactoriSUN = (GLEEPFNGLGLOBALALPHAFACTORISUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactoriSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glGlobalAlphaFactorfSUN = (GLEEPFNGLGLOBALALPHAFACTORFSUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactorfSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glGlobalAlphaFactordSUN = (GLEEPFNGLGLOBALALPHAFACTORDSUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactordSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glGlobalAlphaFactorubSUN = (GLEEPFNGLGLOBALALPHAFACTORUBSUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactorubSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glGlobalAlphaFactorusSUN = (GLEEPFNGLGLOBALALPHAFACTORUSSUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactorusSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glGlobalAlphaFactoruiSUN = (GLEEPFNGLGLOBALALPHAFACTORUISUNPROC) __GLeeGetProcAddress("glGlobalAlphaFactoruiSUN"))!=0) nLinked++; +#endif + if (nLinked==8) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SUN_triangle_list(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SUN_triangle_list + if ((GLeeFuncPtr_glReplacementCodeuiSUN = (GLEEPFNGLREPLACEMENTCODEUISUNPROC) __GLeeGetProcAddress("glReplacementCodeuiSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeusSUN = (GLEEPFNGLREPLACEMENTCODEUSSUNPROC) __GLeeGetProcAddress("glReplacementCodeusSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeubSUN = (GLEEPFNGLREPLACEMENTCODEUBSUNPROC) __GLeeGetProcAddress("glReplacementCodeubSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuivSUN = (GLEEPFNGLREPLACEMENTCODEUIVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuivSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeusvSUN = (GLEEPFNGLREPLACEMENTCODEUSVSUNPROC) __GLeeGetProcAddress("glReplacementCodeusvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeubvSUN = (GLEEPFNGLREPLACEMENTCODEUBVSUNPROC) __GLeeGetProcAddress("glReplacementCodeubvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodePointerSUN = (GLEEPFNGLREPLACEMENTCODEPOINTERSUNPROC) __GLeeGetProcAddress("glReplacementCodePointerSUN"))!=0) nLinked++; +#endif + if (nLinked==7) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SUN_vertex(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SUN_vertex + if ((GLeeFuncPtr_glColor4ubVertex2fSUN = (GLEEPFNGLCOLOR4UBVERTEX2FSUNPROC) __GLeeGetProcAddress("glColor4ubVertex2fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4ubVertex2fvSUN = (GLEEPFNGLCOLOR4UBVERTEX2FVSUNPROC) __GLeeGetProcAddress("glColor4ubVertex2fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4ubVertex3fSUN = (GLEEPFNGLCOLOR4UBVERTEX3FSUNPROC) __GLeeGetProcAddress("glColor4ubVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4ubVertex3fvSUN = (GLEEPFNGLCOLOR4UBVERTEX3FVSUNPROC) __GLeeGetProcAddress("glColor4ubVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor3fVertex3fSUN = (GLEEPFNGLCOLOR3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glColor3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor3fVertex3fvSUN = (GLEEPFNGLCOLOR3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glColor3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormal3fVertex3fSUN = (GLEEPFNGLNORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormal3fVertex3fvSUN = (GLEEPFNGLNORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glNormal3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4fNormal3fVertex3fSUN = (GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glColor4fNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4fNormal3fVertex3fvSUN = (GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glColor4fNormal3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fVertex3fSUN = (GLEEPFNGLTEXCOORD2FVERTEX3FSUNPROC) __GLeeGetProcAddress("glTexCoord2fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fVertex3fvSUN = (GLEEPFNGLTEXCOORD2FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glTexCoord2fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4fVertex4fSUN = (GLEEPFNGLTEXCOORD4FVERTEX4FSUNPROC) __GLeeGetProcAddress("glTexCoord4fVertex4fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4fVertex4fvSUN = (GLEEPFNGLTEXCOORD4FVERTEX4FVSUNPROC) __GLeeGetProcAddress("glTexCoord4fVertex4fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fColor4ubVertex3fSUN = (GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) __GLeeGetProcAddress("glTexCoord2fColor4ubVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fColor4ubVertex3fvSUN = (GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) __GLeeGetProcAddress("glTexCoord2fColor4ubVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fColor3fVertex3fSUN = (GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glTexCoord2fColor3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fColor3fVertex3fvSUN = (GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glTexCoord2fColor3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fNormal3fVertex3fSUN = (GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glTexCoord2fNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fNormal3fVertex3fvSUN = (GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glTexCoord2fNormal3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fSUN = (GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glTexCoord2fColor4fNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fvSUN = (GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glTexCoord2fColor4fNormal3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fSUN = (GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) __GLeeGetProcAddress("glTexCoord4fColor4fNormal3fVertex4fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fvSUN = (GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) __GLeeGetProcAddress("glTexCoord4fColor4fNormal3fVertex4fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiColor4ubVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiColor4ubVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiColor3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiColor3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiNormal3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiColor4fNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiColor4fNormal3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiTexCoord2fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiTexCoord2fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN"))!=0) nLinked++; + if ((GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) __GLeeGetProcAddress("glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN"))!=0) nLinked++; +#endif + if (nLinked==40) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_blend_func_separate(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_blend_func_separate + if ((GLeeFuncPtr_glBlendFuncSeparateEXT = (GLEEPFNGLBLENDFUNCSEPARATEEXTPROC) __GLeeGetProcAddress("glBlendFuncSeparateEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_INGR_color_clamp(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_INGR_interlace_read(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_stencil_wrap(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_422_pixels(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_texgen_reflection(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_cube_map(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SUN_convolution_border_modes(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_env_add(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_lod_bias(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_filter_anisotropic(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_vertex_weighting(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_vertex_weighting + if ((GLeeFuncPtr_glVertexWeightfEXT = (GLEEPFNGLVERTEXWEIGHTFEXTPROC) __GLeeGetProcAddress("glVertexWeightfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexWeightfvEXT = (GLEEPFNGLVERTEXWEIGHTFVEXTPROC) __GLeeGetProcAddress("glVertexWeightfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexWeightPointerEXT = (GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC) __GLeeGetProcAddress("glVertexWeightPointerEXT"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_light_max_exponent(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_vertex_array_range(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_vertex_array_range + if ((GLeeFuncPtr_glFlushVertexArrayRangeNV = (GLEEPFNGLFLUSHVERTEXARRAYRANGENVPROC) __GLeeGetProcAddress("glFlushVertexArrayRangeNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayRangeNV = (GLEEPFNGLVERTEXARRAYRANGENVPROC) __GLeeGetProcAddress("glVertexArrayRangeNV"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_register_combiners(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_register_combiners + if ((GLeeFuncPtr_glCombinerParameterfvNV = (GLEEPFNGLCOMBINERPARAMETERFVNVPROC) __GLeeGetProcAddress("glCombinerParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCombinerParameterfNV = (GLEEPFNGLCOMBINERPARAMETERFNVPROC) __GLeeGetProcAddress("glCombinerParameterfNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCombinerParameterivNV = (GLEEPFNGLCOMBINERPARAMETERIVNVPROC) __GLeeGetProcAddress("glCombinerParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCombinerParameteriNV = (GLEEPFNGLCOMBINERPARAMETERINVPROC) __GLeeGetProcAddress("glCombinerParameteriNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCombinerInputNV = (GLEEPFNGLCOMBINERINPUTNVPROC) __GLeeGetProcAddress("glCombinerInputNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCombinerOutputNV = (GLEEPFNGLCOMBINEROUTPUTNVPROC) __GLeeGetProcAddress("glCombinerOutputNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glFinalCombinerInputNV = (GLEEPFNGLFINALCOMBINERINPUTNVPROC) __GLeeGetProcAddress("glFinalCombinerInputNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCombinerInputParameterfvNV = (GLEEPFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetCombinerInputParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCombinerInputParameterivNV = (GLEEPFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) __GLeeGetProcAddress("glGetCombinerInputParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCombinerOutputParameterfvNV = (GLEEPFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetCombinerOutputParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCombinerOutputParameterivNV = (GLEEPFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) __GLeeGetProcAddress("glGetCombinerOutputParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFinalCombinerInputParameterfvNV = (GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetFinalCombinerInputParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFinalCombinerInputParameterivNV = (GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) __GLeeGetProcAddress("glGetFinalCombinerInputParameterivNV"))!=0) nLinked++; +#endif + if (nLinked==13) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_fog_distance(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_texgen_emboss(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_blend_square(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_texture_env_combine4(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_MESA_resize_buffers(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_MESA_resize_buffers + if ((GLeeFuncPtr_glResizeBuffersMESA = (GLEEPFNGLRESIZEBUFFERSMESAPROC) __GLeeGetProcAddress("glResizeBuffersMESA"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_MESA_window_pos(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_MESA_window_pos + if ((GLeeFuncPtr_glWindowPos2dMESA = (GLEEPFNGLWINDOWPOS2DMESAPROC) __GLeeGetProcAddress("glWindowPos2dMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2dvMESA = (GLEEPFNGLWINDOWPOS2DVMESAPROC) __GLeeGetProcAddress("glWindowPos2dvMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2fMESA = (GLEEPFNGLWINDOWPOS2FMESAPROC) __GLeeGetProcAddress("glWindowPos2fMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2fvMESA = (GLEEPFNGLWINDOWPOS2FVMESAPROC) __GLeeGetProcAddress("glWindowPos2fvMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2iMESA = (GLEEPFNGLWINDOWPOS2IMESAPROC) __GLeeGetProcAddress("glWindowPos2iMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2ivMESA = (GLEEPFNGLWINDOWPOS2IVMESAPROC) __GLeeGetProcAddress("glWindowPos2ivMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2sMESA = (GLEEPFNGLWINDOWPOS2SMESAPROC) __GLeeGetProcAddress("glWindowPos2sMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos2svMESA = (GLEEPFNGLWINDOWPOS2SVMESAPROC) __GLeeGetProcAddress("glWindowPos2svMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3dMESA = (GLEEPFNGLWINDOWPOS3DMESAPROC) __GLeeGetProcAddress("glWindowPos3dMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3dvMESA = (GLEEPFNGLWINDOWPOS3DVMESAPROC) __GLeeGetProcAddress("glWindowPos3dvMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3fMESA = (GLEEPFNGLWINDOWPOS3FMESAPROC) __GLeeGetProcAddress("glWindowPos3fMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3fvMESA = (GLEEPFNGLWINDOWPOS3FVMESAPROC) __GLeeGetProcAddress("glWindowPos3fvMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3iMESA = (GLEEPFNGLWINDOWPOS3IMESAPROC) __GLeeGetProcAddress("glWindowPos3iMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3ivMESA = (GLEEPFNGLWINDOWPOS3IVMESAPROC) __GLeeGetProcAddress("glWindowPos3ivMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3sMESA = (GLEEPFNGLWINDOWPOS3SMESAPROC) __GLeeGetProcAddress("glWindowPos3sMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos3svMESA = (GLEEPFNGLWINDOWPOS3SVMESAPROC) __GLeeGetProcAddress("glWindowPos3svMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4dMESA = (GLEEPFNGLWINDOWPOS4DMESAPROC) __GLeeGetProcAddress("glWindowPos4dMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4dvMESA = (GLEEPFNGLWINDOWPOS4DVMESAPROC) __GLeeGetProcAddress("glWindowPos4dvMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4fMESA = (GLEEPFNGLWINDOWPOS4FMESAPROC) __GLeeGetProcAddress("glWindowPos4fMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4fvMESA = (GLEEPFNGLWINDOWPOS4FVMESAPROC) __GLeeGetProcAddress("glWindowPos4fvMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4iMESA = (GLEEPFNGLWINDOWPOS4IMESAPROC) __GLeeGetProcAddress("glWindowPos4iMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4ivMESA = (GLEEPFNGLWINDOWPOS4IVMESAPROC) __GLeeGetProcAddress("glWindowPos4ivMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4sMESA = (GLEEPFNGLWINDOWPOS4SMESAPROC) __GLeeGetProcAddress("glWindowPos4sMESA"))!=0) nLinked++; + if ((GLeeFuncPtr_glWindowPos4svMESA = (GLEEPFNGLWINDOWPOS4SVMESAPROC) __GLeeGetProcAddress("glWindowPos4svMESA"))!=0) nLinked++; +#endif + if (nLinked==24) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_compression_s3tc(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_IBM_cull_vertex(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_IBM_multimode_draw_arrays(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_IBM_multimode_draw_arrays + if ((GLeeFuncPtr_glMultiModeDrawArraysIBM = (GLEEPFNGLMULTIMODEDRAWARRAYSIBMPROC) __GLeeGetProcAddress("glMultiModeDrawArraysIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiModeDrawElementsIBM = (GLEEPFNGLMULTIMODEDRAWELEMENTSIBMPROC) __GLeeGetProcAddress("glMultiModeDrawElementsIBM"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_IBM_vertex_array_lists(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_IBM_vertex_array_lists + if ((GLeeFuncPtr_glColorPointerListIBM = (GLEEPFNGLCOLORPOINTERLISTIBMPROC) __GLeeGetProcAddress("glColorPointerListIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColorPointerListIBM = (GLEEPFNGLSECONDARYCOLORPOINTERLISTIBMPROC) __GLeeGetProcAddress("glSecondaryColorPointerListIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glEdgeFlagPointerListIBM = (GLEEPFNGLEDGEFLAGPOINTERLISTIBMPROC) __GLeeGetProcAddress("glEdgeFlagPointerListIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordPointerListIBM = (GLEEPFNGLFOGCOORDPOINTERLISTIBMPROC) __GLeeGetProcAddress("glFogCoordPointerListIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glIndexPointerListIBM = (GLEEPFNGLINDEXPOINTERLISTIBMPROC) __GLeeGetProcAddress("glIndexPointerListIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalPointerListIBM = (GLEEPFNGLNORMALPOINTERLISTIBMPROC) __GLeeGetProcAddress("glNormalPointerListIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoordPointerListIBM = (GLEEPFNGLTEXCOORDPOINTERLISTIBMPROC) __GLeeGetProcAddress("glTexCoordPointerListIBM"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexPointerListIBM = (GLEEPFNGLVERTEXPOINTERLISTIBMPROC) __GLeeGetProcAddress("glVertexPointerListIBM"))!=0) nLinked++; +#endif + if (nLinked==8) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_subsample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_ycrcb_subsample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_ycrcba(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGI_depth_pass_instrument(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_3DFX_texture_compression_FXT1(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_3DFX_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_3DFX_tbuffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_3DFX_tbuffer + if ((GLeeFuncPtr_glTbufferMask3DFX = (GLEEPFNGLTBUFFERMASK3DFXPROC) __GLeeGetProcAddress("glTbufferMask3DFX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_multisample(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_multisample + if ((GLeeFuncPtr_glSampleMaskEXT = (GLEEPFNGLSAMPLEMASKEXTPROC) __GLeeGetProcAddress("glSampleMaskEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSamplePatternEXT = (GLEEPFNGLSAMPLEPATTERNEXTPROC) __GLeeGetProcAddress("glSamplePatternEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_vertex_preclip(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_convolution_accuracy(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_resample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_point_line_texgen(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIS_texture_color_mask(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIS_texture_color_mask + if ((GLeeFuncPtr_glTextureColorMaskSGIS = (GLEEPFNGLTEXTURECOLORMASKSGISPROC) __GLeeGetProcAddress("glTextureColorMaskSGIS"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_env_dot3(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ATI_texture_mirror_once(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_fence(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_fence + if ((GLeeFuncPtr_glDeleteFencesNV = (GLEEPFNGLDELETEFENCESNVPROC) __GLeeGetProcAddress("glDeleteFencesNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenFencesNV = (GLEEPFNGLGENFENCESNVPROC) __GLeeGetProcAddress("glGenFencesNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsFenceNV = (GLEEPFNGLISFENCENVPROC) __GLeeGetProcAddress("glIsFenceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTestFenceNV = (GLEEPFNGLTESTFENCENVPROC) __GLeeGetProcAddress("glTestFenceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFenceivNV = (GLEEPFNGLGETFENCEIVNVPROC) __GLeeGetProcAddress("glGetFenceivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glFinishFenceNV = (GLEEPFNGLFINISHFENCENVPROC) __GLeeGetProcAddress("glFinishFenceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glSetFenceNV = (GLEEPFNGLSETFENCENVPROC) __GLeeGetProcAddress("glSetFenceNV"))!=0) nLinked++; +#endif + if (nLinked==7) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_IBM_texture_mirrored_repeat(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_evaluators(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_evaluators + if ((GLeeFuncPtr_glMapControlPointsNV = (GLEEPFNGLMAPCONTROLPOINTSNVPROC) __GLeeGetProcAddress("glMapControlPointsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapParameterivNV = (GLEEPFNGLMAPPARAMETERIVNVPROC) __GLeeGetProcAddress("glMapParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapParameterfvNV = (GLEEPFNGLMAPPARAMETERFVNVPROC) __GLeeGetProcAddress("glMapParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMapControlPointsNV = (GLEEPFNGLGETMAPCONTROLPOINTSNVPROC) __GLeeGetProcAddress("glGetMapControlPointsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMapParameterivNV = (GLEEPFNGLGETMAPPARAMETERIVNVPROC) __GLeeGetProcAddress("glGetMapParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMapParameterfvNV = (GLEEPFNGLGETMAPPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetMapParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMapAttribParameterivNV = (GLEEPFNGLGETMAPATTRIBPARAMETERIVNVPROC) __GLeeGetProcAddress("glGetMapAttribParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMapAttribParameterfvNV = (GLEEPFNGLGETMAPATTRIBPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetMapAttribParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glEvalMapsNV = (GLEEPFNGLEVALMAPSNVPROC) __GLeeGetProcAddress("glEvalMapsNV"))!=0) nLinked++; +#endif + if (nLinked==9) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_packed_depth_stencil(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_register_combiners2(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_register_combiners2 + if ((GLeeFuncPtr_glCombinerStageParameterfvNV = (GLEEPFNGLCOMBINERSTAGEPARAMETERFVNVPROC) __GLeeGetProcAddress("glCombinerStageParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCombinerStageParameterfvNV = (GLEEPFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetCombinerStageParameterfvNV"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_texture_compression_vtc(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_texture_rectangle(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_texture_shader(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_texture_shader2(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_vertex_array_range2(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_vertex_program(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_vertex_program + if ((GLeeFuncPtr_glAreProgramsResidentNV = (GLEEPFNGLAREPROGRAMSRESIDENTNVPROC) __GLeeGetProcAddress("glAreProgramsResidentNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindProgramNV = (GLEEPFNGLBINDPROGRAMNVPROC) __GLeeGetProcAddress("glBindProgramNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteProgramsNV = (GLEEPFNGLDELETEPROGRAMSNVPROC) __GLeeGetProcAddress("glDeleteProgramsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glExecuteProgramNV = (GLEEPFNGLEXECUTEPROGRAMNVPROC) __GLeeGetProcAddress("glExecuteProgramNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenProgramsNV = (GLEEPFNGLGENPROGRAMSNVPROC) __GLeeGetProcAddress("glGenProgramsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramParameterdvNV = (GLEEPFNGLGETPROGRAMPARAMETERDVNVPROC) __GLeeGetProcAddress("glGetProgramParameterdvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramParameterfvNV = (GLEEPFNGLGETPROGRAMPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetProgramParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramivNV = (GLEEPFNGLGETPROGRAMIVNVPROC) __GLeeGetProcAddress("glGetProgramivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramStringNV = (GLEEPFNGLGETPROGRAMSTRINGNVPROC) __GLeeGetProcAddress("glGetProgramStringNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTrackMatrixivNV = (GLEEPFNGLGETTRACKMATRIXIVNVPROC) __GLeeGetProcAddress("glGetTrackMatrixivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribdvNV = (GLEEPFNGLGETVERTEXATTRIBDVNVPROC) __GLeeGetProcAddress("glGetVertexAttribdvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribfvNV = (GLEEPFNGLGETVERTEXATTRIBFVNVPROC) __GLeeGetProcAddress("glGetVertexAttribfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribivNV = (GLEEPFNGLGETVERTEXATTRIBIVNVPROC) __GLeeGetProcAddress("glGetVertexAttribivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribPointervNV = (GLEEPFNGLGETVERTEXATTRIBPOINTERVNVPROC) __GLeeGetProcAddress("glGetVertexAttribPointervNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsProgramNV = (GLEEPFNGLISPROGRAMNVPROC) __GLeeGetProcAddress("glIsProgramNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glLoadProgramNV = (GLEEPFNGLLOADPROGRAMNVPROC) __GLeeGetProcAddress("glLoadProgramNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramParameter4dNV = (GLEEPFNGLPROGRAMPARAMETER4DNVPROC) __GLeeGetProcAddress("glProgramParameter4dNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramParameter4dvNV = (GLEEPFNGLPROGRAMPARAMETER4DVNVPROC) __GLeeGetProcAddress("glProgramParameter4dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramParameter4fNV = (GLEEPFNGLPROGRAMPARAMETER4FNVPROC) __GLeeGetProcAddress("glProgramParameter4fNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramParameter4fvNV = (GLEEPFNGLPROGRAMPARAMETER4FVNVPROC) __GLeeGetProcAddress("glProgramParameter4fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramParameters4dvNV = (GLEEPFNGLPROGRAMPARAMETERS4DVNVPROC) __GLeeGetProcAddress("glProgramParameters4dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramParameters4fvNV = (GLEEPFNGLPROGRAMPARAMETERS4FVNVPROC) __GLeeGetProcAddress("glProgramParameters4fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glRequestResidentProgramsNV = (GLEEPFNGLREQUESTRESIDENTPROGRAMSNVPROC) __GLeeGetProcAddress("glRequestResidentProgramsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTrackMatrixNV = (GLEEPFNGLTRACKMATRIXNVPROC) __GLeeGetProcAddress("glTrackMatrixNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribPointerNV = (GLEEPFNGLVERTEXATTRIBPOINTERNVPROC) __GLeeGetProcAddress("glVertexAttribPointerNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1dNV = (GLEEPFNGLVERTEXATTRIB1DNVPROC) __GLeeGetProcAddress("glVertexAttrib1dNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1dvNV = (GLEEPFNGLVERTEXATTRIB1DVNVPROC) __GLeeGetProcAddress("glVertexAttrib1dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1fNV = (GLEEPFNGLVERTEXATTRIB1FNVPROC) __GLeeGetProcAddress("glVertexAttrib1fNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1fvNV = (GLEEPFNGLVERTEXATTRIB1FVNVPROC) __GLeeGetProcAddress("glVertexAttrib1fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1sNV = (GLEEPFNGLVERTEXATTRIB1SNVPROC) __GLeeGetProcAddress("glVertexAttrib1sNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1svNV = (GLEEPFNGLVERTEXATTRIB1SVNVPROC) __GLeeGetProcAddress("glVertexAttrib1svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2dNV = (GLEEPFNGLVERTEXATTRIB2DNVPROC) __GLeeGetProcAddress("glVertexAttrib2dNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2dvNV = (GLEEPFNGLVERTEXATTRIB2DVNVPROC) __GLeeGetProcAddress("glVertexAttrib2dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2fNV = (GLEEPFNGLVERTEXATTRIB2FNVPROC) __GLeeGetProcAddress("glVertexAttrib2fNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2fvNV = (GLEEPFNGLVERTEXATTRIB2FVNVPROC) __GLeeGetProcAddress("glVertexAttrib2fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2sNV = (GLEEPFNGLVERTEXATTRIB2SNVPROC) __GLeeGetProcAddress("glVertexAttrib2sNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2svNV = (GLEEPFNGLVERTEXATTRIB2SVNVPROC) __GLeeGetProcAddress("glVertexAttrib2svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3dNV = (GLEEPFNGLVERTEXATTRIB3DNVPROC) __GLeeGetProcAddress("glVertexAttrib3dNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3dvNV = (GLEEPFNGLVERTEXATTRIB3DVNVPROC) __GLeeGetProcAddress("glVertexAttrib3dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3fNV = (GLEEPFNGLVERTEXATTRIB3FNVPROC) __GLeeGetProcAddress("glVertexAttrib3fNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3fvNV = (GLEEPFNGLVERTEXATTRIB3FVNVPROC) __GLeeGetProcAddress("glVertexAttrib3fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3sNV = (GLEEPFNGLVERTEXATTRIB3SNVPROC) __GLeeGetProcAddress("glVertexAttrib3sNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3svNV = (GLEEPFNGLVERTEXATTRIB3SVNVPROC) __GLeeGetProcAddress("glVertexAttrib3svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4dNV = (GLEEPFNGLVERTEXATTRIB4DNVPROC) __GLeeGetProcAddress("glVertexAttrib4dNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4dvNV = (GLEEPFNGLVERTEXATTRIB4DVNVPROC) __GLeeGetProcAddress("glVertexAttrib4dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4fNV = (GLEEPFNGLVERTEXATTRIB4FNVPROC) __GLeeGetProcAddress("glVertexAttrib4fNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4fvNV = (GLEEPFNGLVERTEXATTRIB4FVNVPROC) __GLeeGetProcAddress("glVertexAttrib4fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4sNV = (GLEEPFNGLVERTEXATTRIB4SNVPROC) __GLeeGetProcAddress("glVertexAttrib4sNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4svNV = (GLEEPFNGLVERTEXATTRIB4SVNVPROC) __GLeeGetProcAddress("glVertexAttrib4svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4ubNV = (GLEEPFNGLVERTEXATTRIB4UBNVPROC) __GLeeGetProcAddress("glVertexAttrib4ubNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4ubvNV = (GLEEPFNGLVERTEXATTRIB4UBVNVPROC) __GLeeGetProcAddress("glVertexAttrib4ubvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs1dvNV = (GLEEPFNGLVERTEXATTRIBS1DVNVPROC) __GLeeGetProcAddress("glVertexAttribs1dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs1fvNV = (GLEEPFNGLVERTEXATTRIBS1FVNVPROC) __GLeeGetProcAddress("glVertexAttribs1fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs1svNV = (GLEEPFNGLVERTEXATTRIBS1SVNVPROC) __GLeeGetProcAddress("glVertexAttribs1svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs2dvNV = (GLEEPFNGLVERTEXATTRIBS2DVNVPROC) __GLeeGetProcAddress("glVertexAttribs2dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs2fvNV = (GLEEPFNGLVERTEXATTRIBS2FVNVPROC) __GLeeGetProcAddress("glVertexAttribs2fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs2svNV = (GLEEPFNGLVERTEXATTRIBS2SVNVPROC) __GLeeGetProcAddress("glVertexAttribs2svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs3dvNV = (GLEEPFNGLVERTEXATTRIBS3DVNVPROC) __GLeeGetProcAddress("glVertexAttribs3dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs3fvNV = (GLEEPFNGLVERTEXATTRIBS3FVNVPROC) __GLeeGetProcAddress("glVertexAttribs3fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs3svNV = (GLEEPFNGLVERTEXATTRIBS3SVNVPROC) __GLeeGetProcAddress("glVertexAttribs3svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs4dvNV = (GLEEPFNGLVERTEXATTRIBS4DVNVPROC) __GLeeGetProcAddress("glVertexAttribs4dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs4fvNV = (GLEEPFNGLVERTEXATTRIBS4FVNVPROC) __GLeeGetProcAddress("glVertexAttribs4fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs4svNV = (GLEEPFNGLVERTEXATTRIBS4SVNVPROC) __GLeeGetProcAddress("glVertexAttribs4svNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs4ubvNV = (GLEEPFNGLVERTEXATTRIBS4UBVNVPROC) __GLeeGetProcAddress("glVertexAttribs4ubvNV"))!=0) nLinked++; +#endif + if (nLinked==64) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_texture_coordinate_clamp(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_scalebias_hint(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_OML_interlace(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_OML_subsample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_OML_resample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_copy_depth_to_color(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ATI_envmap_bumpmap(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_envmap_bumpmap + if ((GLeeFuncPtr_glTexBumpParameterivATI = (GLEEPFNGLTEXBUMPPARAMETERIVATIPROC) __GLeeGetProcAddress("glTexBumpParameterivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexBumpParameterfvATI = (GLEEPFNGLTEXBUMPPARAMETERFVATIPROC) __GLeeGetProcAddress("glTexBumpParameterfvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexBumpParameterivATI = (GLEEPFNGLGETTEXBUMPPARAMETERIVATIPROC) __GLeeGetProcAddress("glGetTexBumpParameterivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexBumpParameterfvATI = (GLEEPFNGLGETTEXBUMPPARAMETERFVATIPROC) __GLeeGetProcAddress("glGetTexBumpParameterfvATI"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_fragment_shader(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_fragment_shader + if ((GLeeFuncPtr_glGenFragmentShadersATI = (GLEEPFNGLGENFRAGMENTSHADERSATIPROC) __GLeeGetProcAddress("glGenFragmentShadersATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindFragmentShaderATI = (GLEEPFNGLBINDFRAGMENTSHADERATIPROC) __GLeeGetProcAddress("glBindFragmentShaderATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteFragmentShaderATI = (GLEEPFNGLDELETEFRAGMENTSHADERATIPROC) __GLeeGetProcAddress("glDeleteFragmentShaderATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glBeginFragmentShaderATI = (GLEEPFNGLBEGINFRAGMENTSHADERATIPROC) __GLeeGetProcAddress("glBeginFragmentShaderATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndFragmentShaderATI = (GLEEPFNGLENDFRAGMENTSHADERATIPROC) __GLeeGetProcAddress("glEndFragmentShaderATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glPassTexCoordATI = (GLEEPFNGLPASSTEXCOORDATIPROC) __GLeeGetProcAddress("glPassTexCoordATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glSampleMapATI = (GLEEPFNGLSAMPLEMAPATIPROC) __GLeeGetProcAddress("glSampleMapATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorFragmentOp1ATI = (GLEEPFNGLCOLORFRAGMENTOP1ATIPROC) __GLeeGetProcAddress("glColorFragmentOp1ATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorFragmentOp2ATI = (GLEEPFNGLCOLORFRAGMENTOP2ATIPROC) __GLeeGetProcAddress("glColorFragmentOp2ATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glColorFragmentOp3ATI = (GLEEPFNGLCOLORFRAGMENTOP3ATIPROC) __GLeeGetProcAddress("glColorFragmentOp3ATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glAlphaFragmentOp1ATI = (GLEEPFNGLALPHAFRAGMENTOP1ATIPROC) __GLeeGetProcAddress("glAlphaFragmentOp1ATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glAlphaFragmentOp2ATI = (GLEEPFNGLALPHAFRAGMENTOP2ATIPROC) __GLeeGetProcAddress("glAlphaFragmentOp2ATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glAlphaFragmentOp3ATI = (GLEEPFNGLALPHAFRAGMENTOP3ATIPROC) __GLeeGetProcAddress("glAlphaFragmentOp3ATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glSetFragmentShaderConstantATI = (GLEEPFNGLSETFRAGMENTSHADERCONSTANTATIPROC) __GLeeGetProcAddress("glSetFragmentShaderConstantATI"))!=0) nLinked++; +#endif + if (nLinked==14) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_pn_triangles(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_pn_triangles + if ((GLeeFuncPtr_glPNTrianglesiATI = (GLEEPFNGLPNTRIANGLESIATIPROC) __GLeeGetProcAddress("glPNTrianglesiATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glPNTrianglesfATI = (GLEEPFNGLPNTRIANGLESFATIPROC) __GLeeGetProcAddress("glPNTrianglesfATI"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_vertex_array_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_vertex_array_object + if ((GLeeFuncPtr_glNewObjectBufferATI = (GLEEPFNGLNEWOBJECTBUFFERATIPROC) __GLeeGetProcAddress("glNewObjectBufferATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsObjectBufferATI = (GLEEPFNGLISOBJECTBUFFERATIPROC) __GLeeGetProcAddress("glIsObjectBufferATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glUpdateObjectBufferATI = (GLEEPFNGLUPDATEOBJECTBUFFERATIPROC) __GLeeGetProcAddress("glUpdateObjectBufferATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetObjectBufferfvATI = (GLEEPFNGLGETOBJECTBUFFERFVATIPROC) __GLeeGetProcAddress("glGetObjectBufferfvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetObjectBufferivATI = (GLEEPFNGLGETOBJECTBUFFERIVATIPROC) __GLeeGetProcAddress("glGetObjectBufferivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glFreeObjectBufferATI = (GLEEPFNGLFREEOBJECTBUFFERATIPROC) __GLeeGetProcAddress("glFreeObjectBufferATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glArrayObjectATI = (GLEEPFNGLARRAYOBJECTATIPROC) __GLeeGetProcAddress("glArrayObjectATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetArrayObjectfvATI = (GLEEPFNGLGETARRAYOBJECTFVATIPROC) __GLeeGetProcAddress("glGetArrayObjectfvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetArrayObjectivATI = (GLEEPFNGLGETARRAYOBJECTIVATIPROC) __GLeeGetProcAddress("glGetArrayObjectivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantArrayObjectATI = (GLEEPFNGLVARIANTARRAYOBJECTATIPROC) __GLeeGetProcAddress("glVariantArrayObjectATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVariantArrayObjectfvATI = (GLEEPFNGLGETVARIANTARRAYOBJECTFVATIPROC) __GLeeGetProcAddress("glGetVariantArrayObjectfvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVariantArrayObjectivATI = (GLEEPFNGLGETVARIANTARRAYOBJECTIVATIPROC) __GLeeGetProcAddress("glGetVariantArrayObjectivATI"))!=0) nLinked++; +#endif + if (nLinked==12) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_vertex_shader(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_vertex_shader + if ((GLeeFuncPtr_glBeginVertexShaderEXT = (GLEEPFNGLBEGINVERTEXSHADEREXTPROC) __GLeeGetProcAddress("glBeginVertexShaderEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndVertexShaderEXT = (GLEEPFNGLENDVERTEXSHADEREXTPROC) __GLeeGetProcAddress("glEndVertexShaderEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindVertexShaderEXT = (GLEEPFNGLBINDVERTEXSHADEREXTPROC) __GLeeGetProcAddress("glBindVertexShaderEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenVertexShadersEXT = (GLEEPFNGLGENVERTEXSHADERSEXTPROC) __GLeeGetProcAddress("glGenVertexShadersEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteVertexShaderEXT = (GLEEPFNGLDELETEVERTEXSHADEREXTPROC) __GLeeGetProcAddress("glDeleteVertexShaderEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glShaderOp1EXT = (GLEEPFNGLSHADEROP1EXTPROC) __GLeeGetProcAddress("glShaderOp1EXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glShaderOp2EXT = (GLEEPFNGLSHADEROP2EXTPROC) __GLeeGetProcAddress("glShaderOp2EXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glShaderOp3EXT = (GLEEPFNGLSHADEROP3EXTPROC) __GLeeGetProcAddress("glShaderOp3EXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSwizzleEXT = (GLEEPFNGLSWIZZLEEXTPROC) __GLeeGetProcAddress("glSwizzleEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glWriteMaskEXT = (GLEEPFNGLWRITEMASKEXTPROC) __GLeeGetProcAddress("glWriteMaskEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glInsertComponentEXT = (GLEEPFNGLINSERTCOMPONENTEXTPROC) __GLeeGetProcAddress("glInsertComponentEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glExtractComponentEXT = (GLEEPFNGLEXTRACTCOMPONENTEXTPROC) __GLeeGetProcAddress("glExtractComponentEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenSymbolsEXT = (GLEEPFNGLGENSYMBOLSEXTPROC) __GLeeGetProcAddress("glGenSymbolsEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSetInvariantEXT = (GLEEPFNGLSETINVARIANTEXTPROC) __GLeeGetProcAddress("glSetInvariantEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glSetLocalConstantEXT = (GLEEPFNGLSETLOCALCONSTANTEXTPROC) __GLeeGetProcAddress("glSetLocalConstantEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantbvEXT = (GLEEPFNGLVARIANTBVEXTPROC) __GLeeGetProcAddress("glVariantbvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantsvEXT = (GLEEPFNGLVARIANTSVEXTPROC) __GLeeGetProcAddress("glVariantsvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantivEXT = (GLEEPFNGLVARIANTIVEXTPROC) __GLeeGetProcAddress("glVariantivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantfvEXT = (GLEEPFNGLVARIANTFVEXTPROC) __GLeeGetProcAddress("glVariantfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantdvEXT = (GLEEPFNGLVARIANTDVEXTPROC) __GLeeGetProcAddress("glVariantdvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantubvEXT = (GLEEPFNGLVARIANTUBVEXTPROC) __GLeeGetProcAddress("glVariantubvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantusvEXT = (GLEEPFNGLVARIANTUSVEXTPROC) __GLeeGetProcAddress("glVariantusvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantuivEXT = (GLEEPFNGLVARIANTUIVEXTPROC) __GLeeGetProcAddress("glVariantuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVariantPointerEXT = (GLEEPFNGLVARIANTPOINTEREXTPROC) __GLeeGetProcAddress("glVariantPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glEnableVariantClientStateEXT = (GLEEPFNGLENABLEVARIANTCLIENTSTATEEXTPROC) __GLeeGetProcAddress("glEnableVariantClientStateEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDisableVariantClientStateEXT = (GLEEPFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) __GLeeGetProcAddress("glDisableVariantClientStateEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindLightParameterEXT = (GLEEPFNGLBINDLIGHTPARAMETEREXTPROC) __GLeeGetProcAddress("glBindLightParameterEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindMaterialParameterEXT = (GLEEPFNGLBINDMATERIALPARAMETEREXTPROC) __GLeeGetProcAddress("glBindMaterialParameterEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindTexGenParameterEXT = (GLEEPFNGLBINDTEXGENPARAMETEREXTPROC) __GLeeGetProcAddress("glBindTexGenParameterEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindTextureUnitParameterEXT = (GLEEPFNGLBINDTEXTUREUNITPARAMETEREXTPROC) __GLeeGetProcAddress("glBindTextureUnitParameterEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindParameterEXT = (GLEEPFNGLBINDPARAMETEREXTPROC) __GLeeGetProcAddress("glBindParameterEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsVariantEnabledEXT = (GLEEPFNGLISVARIANTENABLEDEXTPROC) __GLeeGetProcAddress("glIsVariantEnabledEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVariantBooleanvEXT = (GLEEPFNGLGETVARIANTBOOLEANVEXTPROC) __GLeeGetProcAddress("glGetVariantBooleanvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVariantIntegervEXT = (GLEEPFNGLGETVARIANTINTEGERVEXTPROC) __GLeeGetProcAddress("glGetVariantIntegervEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVariantFloatvEXT = (GLEEPFNGLGETVARIANTFLOATVEXTPROC) __GLeeGetProcAddress("glGetVariantFloatvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVariantPointervEXT = (GLEEPFNGLGETVARIANTPOINTERVEXTPROC) __GLeeGetProcAddress("glGetVariantPointervEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetInvariantBooleanvEXT = (GLEEPFNGLGETINVARIANTBOOLEANVEXTPROC) __GLeeGetProcAddress("glGetInvariantBooleanvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetInvariantIntegervEXT = (GLEEPFNGLGETINVARIANTINTEGERVEXTPROC) __GLeeGetProcAddress("glGetInvariantIntegervEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetInvariantFloatvEXT = (GLEEPFNGLGETINVARIANTFLOATVEXTPROC) __GLeeGetProcAddress("glGetInvariantFloatvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetLocalConstantBooleanvEXT = (GLEEPFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) __GLeeGetProcAddress("glGetLocalConstantBooleanvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetLocalConstantIntegervEXT = (GLEEPFNGLGETLOCALCONSTANTINTEGERVEXTPROC) __GLeeGetProcAddress("glGetLocalConstantIntegervEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetLocalConstantFloatvEXT = (GLEEPFNGLGETLOCALCONSTANTFLOATVEXTPROC) __GLeeGetProcAddress("glGetLocalConstantFloatvEXT"))!=0) nLinked++; +#endif + if (nLinked==42) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_vertex_streams(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_vertex_streams + if ((GLeeFuncPtr_glVertexStream1sATI = (GLEEPFNGLVERTEXSTREAM1SATIPROC) __GLeeGetProcAddress("glVertexStream1sATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream1svATI = (GLEEPFNGLVERTEXSTREAM1SVATIPROC) __GLeeGetProcAddress("glVertexStream1svATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream1iATI = (GLEEPFNGLVERTEXSTREAM1IATIPROC) __GLeeGetProcAddress("glVertexStream1iATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream1ivATI = (GLEEPFNGLVERTEXSTREAM1IVATIPROC) __GLeeGetProcAddress("glVertexStream1ivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream1fATI = (GLEEPFNGLVERTEXSTREAM1FATIPROC) __GLeeGetProcAddress("glVertexStream1fATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream1fvATI = (GLEEPFNGLVERTEXSTREAM1FVATIPROC) __GLeeGetProcAddress("glVertexStream1fvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream1dATI = (GLEEPFNGLVERTEXSTREAM1DATIPROC) __GLeeGetProcAddress("glVertexStream1dATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream1dvATI = (GLEEPFNGLVERTEXSTREAM1DVATIPROC) __GLeeGetProcAddress("glVertexStream1dvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2sATI = (GLEEPFNGLVERTEXSTREAM2SATIPROC) __GLeeGetProcAddress("glVertexStream2sATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2svATI = (GLEEPFNGLVERTEXSTREAM2SVATIPROC) __GLeeGetProcAddress("glVertexStream2svATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2iATI = (GLEEPFNGLVERTEXSTREAM2IATIPROC) __GLeeGetProcAddress("glVertexStream2iATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2ivATI = (GLEEPFNGLVERTEXSTREAM2IVATIPROC) __GLeeGetProcAddress("glVertexStream2ivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2fATI = (GLEEPFNGLVERTEXSTREAM2FATIPROC) __GLeeGetProcAddress("glVertexStream2fATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2fvATI = (GLEEPFNGLVERTEXSTREAM2FVATIPROC) __GLeeGetProcAddress("glVertexStream2fvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2dATI = (GLEEPFNGLVERTEXSTREAM2DATIPROC) __GLeeGetProcAddress("glVertexStream2dATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream2dvATI = (GLEEPFNGLVERTEXSTREAM2DVATIPROC) __GLeeGetProcAddress("glVertexStream2dvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3sATI = (GLEEPFNGLVERTEXSTREAM3SATIPROC) __GLeeGetProcAddress("glVertexStream3sATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3svATI = (GLEEPFNGLVERTEXSTREAM3SVATIPROC) __GLeeGetProcAddress("glVertexStream3svATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3iATI = (GLEEPFNGLVERTEXSTREAM3IATIPROC) __GLeeGetProcAddress("glVertexStream3iATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3ivATI = (GLEEPFNGLVERTEXSTREAM3IVATIPROC) __GLeeGetProcAddress("glVertexStream3ivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3fATI = (GLEEPFNGLVERTEXSTREAM3FATIPROC) __GLeeGetProcAddress("glVertexStream3fATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3fvATI = (GLEEPFNGLVERTEXSTREAM3FVATIPROC) __GLeeGetProcAddress("glVertexStream3fvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3dATI = (GLEEPFNGLVERTEXSTREAM3DATIPROC) __GLeeGetProcAddress("glVertexStream3dATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream3dvATI = (GLEEPFNGLVERTEXSTREAM3DVATIPROC) __GLeeGetProcAddress("glVertexStream3dvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4sATI = (GLEEPFNGLVERTEXSTREAM4SATIPROC) __GLeeGetProcAddress("glVertexStream4sATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4svATI = (GLEEPFNGLVERTEXSTREAM4SVATIPROC) __GLeeGetProcAddress("glVertexStream4svATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4iATI = (GLEEPFNGLVERTEXSTREAM4IATIPROC) __GLeeGetProcAddress("glVertexStream4iATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4ivATI = (GLEEPFNGLVERTEXSTREAM4IVATIPROC) __GLeeGetProcAddress("glVertexStream4ivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4fATI = (GLEEPFNGLVERTEXSTREAM4FATIPROC) __GLeeGetProcAddress("glVertexStream4fATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4fvATI = (GLEEPFNGLVERTEXSTREAM4FVATIPROC) __GLeeGetProcAddress("glVertexStream4fvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4dATI = (GLEEPFNGLVERTEXSTREAM4DATIPROC) __GLeeGetProcAddress("glVertexStream4dATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexStream4dvATI = (GLEEPFNGLVERTEXSTREAM4DVATIPROC) __GLeeGetProcAddress("glVertexStream4dvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3bATI = (GLEEPFNGLNORMALSTREAM3BATIPROC) __GLeeGetProcAddress("glNormalStream3bATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3bvATI = (GLEEPFNGLNORMALSTREAM3BVATIPROC) __GLeeGetProcAddress("glNormalStream3bvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3sATI = (GLEEPFNGLNORMALSTREAM3SATIPROC) __GLeeGetProcAddress("glNormalStream3sATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3svATI = (GLEEPFNGLNORMALSTREAM3SVATIPROC) __GLeeGetProcAddress("glNormalStream3svATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3iATI = (GLEEPFNGLNORMALSTREAM3IATIPROC) __GLeeGetProcAddress("glNormalStream3iATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3ivATI = (GLEEPFNGLNORMALSTREAM3IVATIPROC) __GLeeGetProcAddress("glNormalStream3ivATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3fATI = (GLEEPFNGLNORMALSTREAM3FATIPROC) __GLeeGetProcAddress("glNormalStream3fATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3fvATI = (GLEEPFNGLNORMALSTREAM3FVATIPROC) __GLeeGetProcAddress("glNormalStream3fvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3dATI = (GLEEPFNGLNORMALSTREAM3DATIPROC) __GLeeGetProcAddress("glNormalStream3dATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormalStream3dvATI = (GLEEPFNGLNORMALSTREAM3DVATIPROC) __GLeeGetProcAddress("glNormalStream3dvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glClientActiveVertexStreamATI = (GLEEPFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) __GLeeGetProcAddress("glClientActiveVertexStreamATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexBlendEnviATI = (GLEEPFNGLVERTEXBLENDENVIATIPROC) __GLeeGetProcAddress("glVertexBlendEnviATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexBlendEnvfATI = (GLEEPFNGLVERTEXBLENDENVFATIPROC) __GLeeGetProcAddress("glVertexBlendEnvfATI"))!=0) nLinked++; +#endif + if (nLinked==45) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_element_array(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_element_array + if ((GLeeFuncPtr_glElementPointerATI = (GLEEPFNGLELEMENTPOINTERATIPROC) __GLeeGetProcAddress("glElementPointerATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawElementArrayATI = (GLEEPFNGLDRAWELEMENTARRAYATIPROC) __GLeeGetProcAddress("glDrawElementArrayATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawRangeElementArrayATI = (GLEEPFNGLDRAWRANGEELEMENTARRAYATIPROC) __GLeeGetProcAddress("glDrawRangeElementArrayATI"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SUN_mesh_array(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SUN_mesh_array + if ((GLeeFuncPtr_glDrawMeshArraysSUN = (GLEEPFNGLDRAWMESHARRAYSSUNPROC) __GLeeGetProcAddress("glDrawMeshArraysSUN"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SUN_slice_accum(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_multisample_filter_hint(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_depth_clamp(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_occlusion_query(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_occlusion_query + if ((GLeeFuncPtr_glGenOcclusionQueriesNV = (GLEEPFNGLGENOCCLUSIONQUERIESNVPROC) __GLeeGetProcAddress("glGenOcclusionQueriesNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteOcclusionQueriesNV = (GLEEPFNGLDELETEOCCLUSIONQUERIESNVPROC) __GLeeGetProcAddress("glDeleteOcclusionQueriesNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsOcclusionQueryNV = (GLEEPFNGLISOCCLUSIONQUERYNVPROC) __GLeeGetProcAddress("glIsOcclusionQueryNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glBeginOcclusionQueryNV = (GLEEPFNGLBEGINOCCLUSIONQUERYNVPROC) __GLeeGetProcAddress("glBeginOcclusionQueryNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndOcclusionQueryNV = (GLEEPFNGLENDOCCLUSIONQUERYNVPROC) __GLeeGetProcAddress("glEndOcclusionQueryNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetOcclusionQueryivNV = (GLEEPFNGLGETOCCLUSIONQUERYIVNVPROC) __GLeeGetProcAddress("glGetOcclusionQueryivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetOcclusionQueryuivNV = (GLEEPFNGLGETOCCLUSIONQUERYUIVNVPROC) __GLeeGetProcAddress("glGetOcclusionQueryuivNV"))!=0) nLinked++; +#endif + if (nLinked==7) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_point_sprite(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_point_sprite + if ((GLeeFuncPtr_glPointParameteriNV = (GLEEPFNGLPOINTPARAMETERINVPROC) __GLeeGetProcAddress("glPointParameteriNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameterivNV = (GLEEPFNGLPOINTPARAMETERIVNVPROC) __GLeeGetProcAddress("glPointParameterivNV"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_texture_shader3(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_vertex_program1_1(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_shadow_funcs(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_stencil_two_side(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_stencil_two_side + if ((GLeeFuncPtr_glActiveStencilFaceEXT = (GLEEPFNGLACTIVESTENCILFACEEXTPROC) __GLeeGetProcAddress("glActiveStencilFaceEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_text_fragment_shader(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_APPLE_client_storage(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_APPLE_element_array(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_APPLE_element_array + if ((GLeeFuncPtr_glElementPointerAPPLE = (GLEEPFNGLELEMENTPOINTERAPPLEPROC) __GLeeGetProcAddress("glElementPointerAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawElementArrayAPPLE = (GLEEPFNGLDRAWELEMENTARRAYAPPLEPROC) __GLeeGetProcAddress("glDrawElementArrayAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawRangeElementArrayAPPLE = (GLEEPFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) __GLeeGetProcAddress("glDrawRangeElementArrayAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiDrawElementArrayAPPLE = (GLEEPFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) __GLeeGetProcAddress("glMultiDrawElementArrayAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiDrawRangeElementArrayAPPLE = (GLEEPFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) __GLeeGetProcAddress("glMultiDrawRangeElementArrayAPPLE"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_APPLE_fence(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_APPLE_fence + if ((GLeeFuncPtr_glGenFencesAPPLE = (GLEEPFNGLGENFENCESAPPLEPROC) __GLeeGetProcAddress("glGenFencesAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteFencesAPPLE = (GLEEPFNGLDELETEFENCESAPPLEPROC) __GLeeGetProcAddress("glDeleteFencesAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glSetFenceAPPLE = (GLEEPFNGLSETFENCEAPPLEPROC) __GLeeGetProcAddress("glSetFenceAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsFenceAPPLE = (GLEEPFNGLISFENCEAPPLEPROC) __GLeeGetProcAddress("glIsFenceAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glTestFenceAPPLE = (GLEEPFNGLTESTFENCEAPPLEPROC) __GLeeGetProcAddress("glTestFenceAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glFinishFenceAPPLE = (GLEEPFNGLFINISHFENCEAPPLEPROC) __GLeeGetProcAddress("glFinishFenceAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glTestObjectAPPLE = (GLEEPFNGLTESTOBJECTAPPLEPROC) __GLeeGetProcAddress("glTestObjectAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glFinishObjectAPPLE = (GLEEPFNGLFINISHOBJECTAPPLEPROC) __GLeeGetProcAddress("glFinishObjectAPPLE"))!=0) nLinked++; +#endif + if (nLinked==8) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_APPLE_vertex_array_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_APPLE_vertex_array_object + if ((GLeeFuncPtr_glBindVertexArrayAPPLE = (GLEEPFNGLBINDVERTEXARRAYAPPLEPROC) __GLeeGetProcAddress("glBindVertexArrayAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteVertexArraysAPPLE = (GLEEPFNGLDELETEVERTEXARRAYSAPPLEPROC) __GLeeGetProcAddress("glDeleteVertexArraysAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenVertexArraysAPPLE = (GLEEPFNGLGENVERTEXARRAYSAPPLEPROC) __GLeeGetProcAddress("glGenVertexArraysAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsVertexArrayAPPLE = (GLEEPFNGLISVERTEXARRAYAPPLEPROC) __GLeeGetProcAddress("glIsVertexArrayAPPLE"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_APPLE_vertex_array_range(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_APPLE_vertex_array_range + if ((GLeeFuncPtr_glVertexArrayRangeAPPLE = (GLEEPFNGLVERTEXARRAYRANGEAPPLEPROC) __GLeeGetProcAddress("glVertexArrayRangeAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glFlushVertexArrayRangeAPPLE = (GLEEPFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) __GLeeGetProcAddress("glFlushVertexArrayRangeAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayParameteriAPPLE = (GLEEPFNGLVERTEXARRAYPARAMETERIAPPLEPROC) __GLeeGetProcAddress("glVertexArrayParameteriAPPLE"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_APPLE_ycbcr_422(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_S3_s3tc(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ATI_draw_buffers(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_draw_buffers + if ((GLeeFuncPtr_glDrawBuffersATI = (GLEEPFNGLDRAWBUFFERSATIPROC) __GLeeGetProcAddress("glDrawBuffersATI"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_pixel_format_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ATI_texture_env_combine3(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ATI_texture_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_float_buffer(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_fragment_program(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_fragment_program + if ((GLeeFuncPtr_glProgramNamedParameter4fNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4FNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4fNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramNamedParameter4dNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4dNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramNamedParameter4fvNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramNamedParameter4dvNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4dvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramNamedParameterfvNV = (GLEEPFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetProgramNamedParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramNamedParameterdvNV = (GLEEPFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) __GLeeGetProcAddress("glGetProgramNamedParameterdvNV"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_half_float(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_half_float + if ((GLeeFuncPtr_glVertex2hNV = (GLEEPFNGLVERTEX2HNVPROC) __GLeeGetProcAddress("glVertex2hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex2hvNV = (GLEEPFNGLVERTEX2HVNVPROC) __GLeeGetProcAddress("glVertex2hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex3hNV = (GLEEPFNGLVERTEX3HNVPROC) __GLeeGetProcAddress("glVertex3hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex3hvNV = (GLEEPFNGLVERTEX3HVNVPROC) __GLeeGetProcAddress("glVertex3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex4hNV = (GLEEPFNGLVERTEX4HNVPROC) __GLeeGetProcAddress("glVertex4hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex4hvNV = (GLEEPFNGLVERTEX4HVNVPROC) __GLeeGetProcAddress("glVertex4hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormal3hNV = (GLEEPFNGLNORMAL3HNVPROC) __GLeeGetProcAddress("glNormal3hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormal3hvNV = (GLEEPFNGLNORMAL3HVNVPROC) __GLeeGetProcAddress("glNormal3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor3hNV = (GLEEPFNGLCOLOR3HNVPROC) __GLeeGetProcAddress("glColor3hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor3hvNV = (GLEEPFNGLCOLOR3HVNVPROC) __GLeeGetProcAddress("glColor3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4hNV = (GLEEPFNGLCOLOR4HNVPROC) __GLeeGetProcAddress("glColor4hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4hvNV = (GLEEPFNGLCOLOR4HVNVPROC) __GLeeGetProcAddress("glColor4hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord1hNV = (GLEEPFNGLTEXCOORD1HNVPROC) __GLeeGetProcAddress("glTexCoord1hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord1hvNV = (GLEEPFNGLTEXCOORD1HVNVPROC) __GLeeGetProcAddress("glTexCoord1hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2hNV = (GLEEPFNGLTEXCOORD2HNVPROC) __GLeeGetProcAddress("glTexCoord2hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2hvNV = (GLEEPFNGLTEXCOORD2HVNVPROC) __GLeeGetProcAddress("glTexCoord2hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord3hNV = (GLEEPFNGLTEXCOORD3HNVPROC) __GLeeGetProcAddress("glTexCoord3hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord3hvNV = (GLEEPFNGLTEXCOORD3HVNVPROC) __GLeeGetProcAddress("glTexCoord3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4hNV = (GLEEPFNGLTEXCOORD4HNVPROC) __GLeeGetProcAddress("glTexCoord4hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4hvNV = (GLEEPFNGLTEXCOORD4HVNVPROC) __GLeeGetProcAddress("glTexCoord4hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1hNV = (GLEEPFNGLMULTITEXCOORD1HNVPROC) __GLeeGetProcAddress("glMultiTexCoord1hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1hvNV = (GLEEPFNGLMULTITEXCOORD1HVNVPROC) __GLeeGetProcAddress("glMultiTexCoord1hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2hNV = (GLEEPFNGLMULTITEXCOORD2HNVPROC) __GLeeGetProcAddress("glMultiTexCoord2hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2hvNV = (GLEEPFNGLMULTITEXCOORD2HVNVPROC) __GLeeGetProcAddress("glMultiTexCoord2hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3hNV = (GLEEPFNGLMULTITEXCOORD3HNVPROC) __GLeeGetProcAddress("glMultiTexCoord3hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3hvNV = (GLEEPFNGLMULTITEXCOORD3HVNVPROC) __GLeeGetProcAddress("glMultiTexCoord3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4hNV = (GLEEPFNGLMULTITEXCOORD4HNVPROC) __GLeeGetProcAddress("glMultiTexCoord4hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4hvNV = (GLEEPFNGLMULTITEXCOORD4HVNVPROC) __GLeeGetProcAddress("glMultiTexCoord4hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordhNV = (GLEEPFNGLFOGCOORDHNVPROC) __GLeeGetProcAddress("glFogCoordhNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogCoordhvNV = (GLEEPFNGLFOGCOORDHVNVPROC) __GLeeGetProcAddress("glFogCoordhvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3hNV = (GLEEPFNGLSECONDARYCOLOR3HNVPROC) __GLeeGetProcAddress("glSecondaryColor3hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glSecondaryColor3hvNV = (GLEEPFNGLSECONDARYCOLOR3HVNVPROC) __GLeeGetProcAddress("glSecondaryColor3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexWeighthNV = (GLEEPFNGLVERTEXWEIGHTHNVPROC) __GLeeGetProcAddress("glVertexWeighthNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexWeighthvNV = (GLEEPFNGLVERTEXWEIGHTHVNVPROC) __GLeeGetProcAddress("glVertexWeighthvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1hNV = (GLEEPFNGLVERTEXATTRIB1HNVPROC) __GLeeGetProcAddress("glVertexAttrib1hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib1hvNV = (GLEEPFNGLVERTEXATTRIB1HVNVPROC) __GLeeGetProcAddress("glVertexAttrib1hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2hNV = (GLEEPFNGLVERTEXATTRIB2HNVPROC) __GLeeGetProcAddress("glVertexAttrib2hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib2hvNV = (GLEEPFNGLVERTEXATTRIB2HVNVPROC) __GLeeGetProcAddress("glVertexAttrib2hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3hNV = (GLEEPFNGLVERTEXATTRIB3HNVPROC) __GLeeGetProcAddress("glVertexAttrib3hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib3hvNV = (GLEEPFNGLVERTEXATTRIB3HVNVPROC) __GLeeGetProcAddress("glVertexAttrib3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4hNV = (GLEEPFNGLVERTEXATTRIB4HNVPROC) __GLeeGetProcAddress("glVertexAttrib4hNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttrib4hvNV = (GLEEPFNGLVERTEXATTRIB4HVNVPROC) __GLeeGetProcAddress("glVertexAttrib4hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs1hvNV = (GLEEPFNGLVERTEXATTRIBS1HVNVPROC) __GLeeGetProcAddress("glVertexAttribs1hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs2hvNV = (GLEEPFNGLVERTEXATTRIBS2HVNVPROC) __GLeeGetProcAddress("glVertexAttribs2hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs3hvNV = (GLEEPFNGLVERTEXATTRIBS3HVNVPROC) __GLeeGetProcAddress("glVertexAttribs3hvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribs4hvNV = (GLEEPFNGLVERTEXATTRIBS4HVNVPROC) __GLeeGetProcAddress("glVertexAttribs4hvNV"))!=0) nLinked++; +#endif + if (nLinked==46) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_pixel_data_range(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_pixel_data_range + if ((GLeeFuncPtr_glPixelDataRangeNV = (GLEEPFNGLPIXELDATARANGENVPROC) __GLeeGetProcAddress("glPixelDataRangeNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glFlushPixelDataRangeNV = (GLEEPFNGLFLUSHPIXELDATARANGENVPROC) __GLeeGetProcAddress("glFlushPixelDataRangeNV"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_primitive_restart(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_primitive_restart + if ((GLeeFuncPtr_glPrimitiveRestartNV = (GLEEPFNGLPRIMITIVERESTARTNVPROC) __GLeeGetProcAddress("glPrimitiveRestartNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPrimitiveRestartIndexNV = (GLEEPFNGLPRIMITIVERESTARTINDEXNVPROC) __GLeeGetProcAddress("glPrimitiveRestartIndexNV"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_texture_expand_normal(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_vertex_program2(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ATI_map_object_buffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_map_object_buffer + if ((GLeeFuncPtr_glMapObjectBufferATI = (GLEEPFNGLMAPOBJECTBUFFERATIPROC) __GLeeGetProcAddress("glMapObjectBufferATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glUnmapObjectBufferATI = (GLEEPFNGLUNMAPOBJECTBUFFERATIPROC) __GLeeGetProcAddress("glUnmapObjectBufferATI"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_separate_stencil(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_separate_stencil + if ((GLeeFuncPtr_glStencilOpSeparateATI = (GLEEPFNGLSTENCILOPSEPARATEATIPROC) __GLeeGetProcAddress("glStencilOpSeparateATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilFuncSeparateATI = (GLEEPFNGLSTENCILFUNCSEPARATEATIPROC) __GLeeGetProcAddress("glStencilFuncSeparateATI"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ATI_vertex_attrib_array_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ATI_vertex_attrib_array_object + if ((GLeeFuncPtr_glVertexAttribArrayObjectATI = (GLEEPFNGLVERTEXATTRIBARRAYOBJECTATIPROC) __GLeeGetProcAddress("glVertexAttribArrayObjectATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribArrayObjectfvATI = (GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) __GLeeGetProcAddress("glGetVertexAttribArrayObjectfvATI"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribArrayObjectivATI = (GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) __GLeeGetProcAddress("glGetVertexAttribArrayObjectivATI"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_OES_read_format(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_depth_bounds_test(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_depth_bounds_test + if ((GLeeFuncPtr_glDepthBoundsEXT = (GLEEPFNGLDEPTHBOUNDSEXTPROC) __GLeeGetProcAddress("glDepthBoundsEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_mirror_clamp(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_blend_equation_separate(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_blend_equation_separate + if ((GLeeFuncPtr_glBlendEquationSeparateEXT = (GLEEPFNGLBLENDEQUATIONSEPARATEEXTPROC) __GLeeGetProcAddress("glBlendEquationSeparateEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_MESA_pack_invert(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_MESA_ycbcr_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_pixel_buffer_object(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_fragment_program_option(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_fragment_program2(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_vertex_program2_option(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_vertex_program3(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_framebuffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_framebuffer_object + if ((GLeeFuncPtr_glIsRenderbufferEXT = (GLEEPFNGLISRENDERBUFFEREXTPROC) __GLeeGetProcAddress("glIsRenderbufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindRenderbufferEXT = (GLEEPFNGLBINDRENDERBUFFEREXTPROC) __GLeeGetProcAddress("glBindRenderbufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteRenderbuffersEXT = (GLEEPFNGLDELETERENDERBUFFERSEXTPROC) __GLeeGetProcAddress("glDeleteRenderbuffersEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenRenderbuffersEXT = (GLEEPFNGLGENRENDERBUFFERSEXTPROC) __GLeeGetProcAddress("glGenRenderbuffersEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glRenderbufferStorageEXT = (GLEEPFNGLRENDERBUFFERSTORAGEEXTPROC) __GLeeGetProcAddress("glRenderbufferStorageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetRenderbufferParameterivEXT = (GLEEPFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetRenderbufferParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsFramebufferEXT = (GLEEPFNGLISFRAMEBUFFEREXTPROC) __GLeeGetProcAddress("glIsFramebufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindFramebufferEXT = (GLEEPFNGLBINDFRAMEBUFFEREXTPROC) __GLeeGetProcAddress("glBindFramebufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteFramebuffersEXT = (GLEEPFNGLDELETEFRAMEBUFFERSEXTPROC) __GLeeGetProcAddress("glDeleteFramebuffersEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenFramebuffersEXT = (GLEEPFNGLGENFRAMEBUFFERSEXTPROC) __GLeeGetProcAddress("glGenFramebuffersEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCheckFramebufferStatusEXT = (GLEEPFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) __GLeeGetProcAddress("glCheckFramebufferStatusEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTexture1DEXT = (GLEEPFNGLFRAMEBUFFERTEXTURE1DEXTPROC) __GLeeGetProcAddress("glFramebufferTexture1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTexture2DEXT = (GLEEPFNGLFRAMEBUFFERTEXTURE2DEXTPROC) __GLeeGetProcAddress("glFramebufferTexture2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTexture3DEXT = (GLEEPFNGLFRAMEBUFFERTEXTURE3DEXTPROC) __GLeeGetProcAddress("glFramebufferTexture3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferRenderbufferEXT = (GLEEPFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) __GLeeGetProcAddress("glFramebufferRenderbufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFramebufferAttachmentParameterivEXT = (GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetFramebufferAttachmentParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenerateMipmapEXT = (GLEEPFNGLGENERATEMIPMAPEXTPROC) __GLeeGetProcAddress("glGenerateMipmapEXT"))!=0) nLinked++; +#endif + if (nLinked==17) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_GREMEDY_string_marker(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_GREMEDY_string_marker + if ((GLeeFuncPtr_glStringMarkerGREMEDY = (GLEEPFNGLSTRINGMARKERGREMEDYPROC) __GLeeGetProcAddress("glStringMarkerGREMEDY"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_packed_depth_stencil(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_stencil_clear_tag(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_stencil_clear_tag + if ((GLeeFuncPtr_glStencilClearTagEXT = (GLEEPFNGLSTENCILCLEARTAGEXTPROC) __GLeeGetProcAddress("glStencilClearTagEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_sRGB(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_framebuffer_blit(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_framebuffer_blit + if ((GLeeFuncPtr_glBlitFramebufferEXT = (GLEEPFNGLBLITFRAMEBUFFEREXTPROC) __GLeeGetProcAddress("glBlitFramebufferEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_framebuffer_multisample(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_framebuffer_multisample + if ((GLeeFuncPtr_glRenderbufferStorageMultisampleEXT = (GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) __GLeeGetProcAddress("glRenderbufferStorageMultisampleEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_MESAX_texture_stack(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_timer_query(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_timer_query + if ((GLeeFuncPtr_glGetQueryObjecti64vEXT = (GLEEPFNGLGETQUERYOBJECTI64VEXTPROC) __GLeeGetProcAddress("glGetQueryObjecti64vEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetQueryObjectui64vEXT = (GLEEPFNGLGETQUERYOBJECTUI64VEXTPROC) __GLeeGetProcAddress("glGetQueryObjectui64vEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_gpu_program_parameters(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_gpu_program_parameters + if ((GLeeFuncPtr_glProgramEnvParameters4fvEXT = (GLEEPFNGLPROGRAMENVPARAMETERS4FVEXTPROC) __GLeeGetProcAddress("glProgramEnvParameters4fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameters4fvEXT = (GLEEPFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) __GLeeGetProcAddress("glProgramLocalParameters4fvEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_APPLE_flush_buffer_range(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_APPLE_flush_buffer_range + if ((GLeeFuncPtr_glBufferParameteriAPPLE = (GLEEPFNGLBUFFERPARAMETERIAPPLEPROC) __GLeeGetProcAddress("glBufferParameteriAPPLE"))!=0) nLinked++; + if ((GLeeFuncPtr_glFlushMappedBufferRangeAPPLE = (GLEEPFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) __GLeeGetProcAddress("glFlushMappedBufferRangeAPPLE"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_gpu_shader4(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_gpu_shader4 + if ((GLeeFuncPtr_glGetUniformuivEXT = (GLEEPFNGLGETUNIFORMUIVEXTPROC) __GLeeGetProcAddress("glGetUniformuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindFragDataLocationEXT = (GLEEPFNGLBINDFRAGDATALOCATIONEXTPROC) __GLeeGetProcAddress("glBindFragDataLocationEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragDataLocationEXT = (GLEEPFNGLGETFRAGDATALOCATIONEXTPROC) __GLeeGetProcAddress("glGetFragDataLocationEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1uiEXT = (GLEEPFNGLUNIFORM1UIEXTPROC) __GLeeGetProcAddress("glUniform1uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2uiEXT = (GLEEPFNGLUNIFORM2UIEXTPROC) __GLeeGetProcAddress("glUniform2uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3uiEXT = (GLEEPFNGLUNIFORM3UIEXTPROC) __GLeeGetProcAddress("glUniform3uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4uiEXT = (GLEEPFNGLUNIFORM4UIEXTPROC) __GLeeGetProcAddress("glUniform4uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform1uivEXT = (GLEEPFNGLUNIFORM1UIVEXTPROC) __GLeeGetProcAddress("glUniform1uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform2uivEXT = (GLEEPFNGLUNIFORM2UIVEXTPROC) __GLeeGetProcAddress("glUniform2uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform3uivEXT = (GLEEPFNGLUNIFORM3UIVEXTPROC) __GLeeGetProcAddress("glUniform3uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniform4uivEXT = (GLEEPFNGLUNIFORM4UIVEXTPROC) __GLeeGetProcAddress("glUniform4uivEXT"))!=0) nLinked++; +#endif + if (nLinked==11) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_draw_instanced(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_draw_instanced + if ((GLeeFuncPtr_glDrawArraysInstancedEXT = (GLEEPFNGLDRAWARRAYSINSTANCEDEXTPROC) __GLeeGetProcAddress("glDrawArraysInstancedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawElementsInstancedEXT = (GLEEPFNGLDRAWELEMENTSINSTANCEDEXTPROC) __GLeeGetProcAddress("glDrawElementsInstancedEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_packed_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_array(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_buffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_texture_buffer_object + if ((GLeeFuncPtr_glTexBufferEXT = (GLEEPFNGLTEXBUFFEREXTPROC) __GLeeGetProcAddress("glTexBufferEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_compression_latc(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_compression_rgtc(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_shared_exponent(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_depth_buffer_float(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_depth_buffer_float + if ((GLeeFuncPtr_glDepthRangedNV = (GLEEPFNGLDEPTHRANGEDNVPROC) __GLeeGetProcAddress("glDepthRangedNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearDepthdNV = (GLEEPFNGLCLEARDEPTHDNVPROC) __GLeeGetProcAddress("glClearDepthdNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glDepthBoundsdNV = (GLEEPFNGLDEPTHBOUNDSDNVPROC) __GLeeGetProcAddress("glDepthBoundsdNV"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_framebuffer_multisample_coverage(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_framebuffer_multisample_coverage + if ((GLeeFuncPtr_glRenderbufferStorageMultisampleCoverageNV = (GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) __GLeeGetProcAddress("glRenderbufferStorageMultisampleCoverageNV"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_framebuffer_sRGB(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_geometry_shader4(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_parameter_buffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_parameter_buffer_object + if ((GLeeFuncPtr_glProgramBufferParametersfvNV = (GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) __GLeeGetProcAddress("glProgramBufferParametersfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramBufferParametersIivNV = (GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) __GLeeGetProcAddress("glProgramBufferParametersIivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramBufferParametersIuivNV = (GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) __GLeeGetProcAddress("glProgramBufferParametersIuivNV"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_draw_buffers2(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_draw_buffers2 + if ((GLeeFuncPtr_glColorMaskIndexedEXT = (GLEEPFNGLCOLORMASKINDEXEDEXTPROC) __GLeeGetProcAddress("glColorMaskIndexedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetBooleanIndexedvEXT = (GLEEPFNGLGETBOOLEANINDEXEDVEXTPROC) __GLeeGetProcAddress("glGetBooleanIndexedvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetIntegerIndexedvEXT = (GLEEPFNGLGETINTEGERINDEXEDVEXTPROC) __GLeeGetProcAddress("glGetIntegerIndexedvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glEnableIndexedEXT = (GLEEPFNGLENABLEINDEXEDEXTPROC) __GLeeGetProcAddress("glEnableIndexedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDisableIndexedEXT = (GLEEPFNGLDISABLEINDEXEDEXTPROC) __GLeeGetProcAddress("glDisableIndexedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsEnabledIndexedEXT = (GLEEPFNGLISENABLEDINDEXEDEXTPROC) __GLeeGetProcAddress("glIsEnabledIndexedEXT"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_transform_feedback(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_transform_feedback + if ((GLeeFuncPtr_glBeginTransformFeedbackNV = (GLEEPFNGLBEGINTRANSFORMFEEDBACKNVPROC) __GLeeGetProcAddress("glBeginTransformFeedbackNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndTransformFeedbackNV = (GLEEPFNGLENDTRANSFORMFEEDBACKNVPROC) __GLeeGetProcAddress("glEndTransformFeedbackNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTransformFeedbackAttribsNV = (GLEEPFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) __GLeeGetProcAddress("glTransformFeedbackAttribsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferRangeNV = (GLEEPFNGLBINDBUFFERRANGENVPROC) __GLeeGetProcAddress("glBindBufferRangeNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferOffsetNV = (GLEEPFNGLBINDBUFFEROFFSETNVPROC) __GLeeGetProcAddress("glBindBufferOffsetNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferBaseNV = (GLEEPFNGLBINDBUFFERBASENVPROC) __GLeeGetProcAddress("glBindBufferBaseNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTransformFeedbackVaryingsNV = (GLEEPFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) __GLeeGetProcAddress("glTransformFeedbackVaryingsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glActiveVaryingNV = (GLEEPFNGLACTIVEVARYINGNVPROC) __GLeeGetProcAddress("glActiveVaryingNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVaryingLocationNV = (GLEEPFNGLGETVARYINGLOCATIONNVPROC) __GLeeGetProcAddress("glGetVaryingLocationNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetActiveVaryingNV = (GLEEPFNGLGETACTIVEVARYINGNVPROC) __GLeeGetProcAddress("glGetActiveVaryingNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTransformFeedbackVaryingNV = (GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) __GLeeGetProcAddress("glGetTransformFeedbackVaryingNV"))!=0) nLinked++; +#endif + if (nLinked==11) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_bindable_uniform(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_bindable_uniform + if ((GLeeFuncPtr_glUniformBufferEXT = (GLEEPFNGLUNIFORMBUFFEREXTPROC) __GLeeGetProcAddress("glUniformBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformBufferSizeEXT = (GLEEPFNGLGETUNIFORMBUFFERSIZEEXTPROC) __GLeeGetProcAddress("glGetUniformBufferSizeEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetUniformOffsetEXT = (GLEEPFNGLGETUNIFORMOFFSETEXTPROC) __GLeeGetProcAddress("glGetUniformOffsetEXT"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_integer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_texture_integer + if ((GLeeFuncPtr_glTexParameterIivEXT = (GLEEPFNGLTEXPARAMETERIIVEXTPROC) __GLeeGetProcAddress("glTexParameterIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexParameterIuivEXT = (GLEEPFNGLTEXPARAMETERIUIVEXTPROC) __GLeeGetProcAddress("glTexParameterIuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexParameterIivEXT = (GLEEPFNGLGETTEXPARAMETERIIVEXTPROC) __GLeeGetProcAddress("glGetTexParameterIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexParameterIuivEXT = (GLEEPFNGLGETTEXPARAMETERIUIVEXTPROC) __GLeeGetProcAddress("glGetTexParameterIuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearColorIiEXT = (GLEEPFNGLCLEARCOLORIIEXTPROC) __GLeeGetProcAddress("glClearColorIiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearColorIuiEXT = (GLEEPFNGLCLEARCOLORIUIEXTPROC) __GLeeGetProcAddress("glClearColorIuiEXT"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_GREMEDY_frame_terminator(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_GREMEDY_frame_terminator + if ((GLeeFuncPtr_glFrameTerminatorGREMEDY = (GLEEPFNGLFRAMETERMINATORGREMEDYPROC) __GLeeGetProcAddress("glFrameTerminatorGREMEDY"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_conditional_render(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_conditional_render + if ((GLeeFuncPtr_glBeginConditionalRenderNV = (GLEEPFNGLBEGINCONDITIONALRENDERNVPROC) __GLeeGetProcAddress("glBeginConditionalRenderNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndConditionalRenderNV = (GLEEPFNGLENDCONDITIONALRENDERNVPROC) __GLeeGetProcAddress("glEndConditionalRenderNV"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_present_video(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_transform_feedback(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_transform_feedback + if ((GLeeFuncPtr_glBeginTransformFeedbackEXT = (GLEEPFNGLBEGINTRANSFORMFEEDBACKEXTPROC) __GLeeGetProcAddress("glBeginTransformFeedbackEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndTransformFeedbackEXT = (GLEEPFNGLENDTRANSFORMFEEDBACKEXTPROC) __GLeeGetProcAddress("glEndTransformFeedbackEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferRangeEXT = (GLEEPFNGLBINDBUFFERRANGEEXTPROC) __GLeeGetProcAddress("glBindBufferRangeEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferOffsetEXT = (GLEEPFNGLBINDBUFFEROFFSETEXTPROC) __GLeeGetProcAddress("glBindBufferOffsetEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindBufferBaseEXT = (GLEEPFNGLBINDBUFFERBASEEXTPROC) __GLeeGetProcAddress("glBindBufferBaseEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTransformFeedbackVaryingsEXT = (GLEEPFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) __GLeeGetProcAddress("glTransformFeedbackVaryingsEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTransformFeedbackVaryingEXT = (GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) __GLeeGetProcAddress("glGetTransformFeedbackVaryingEXT"))!=0) nLinked++; +#endif + if (nLinked==7) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_direct_state_access(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_direct_state_access + if ((GLeeFuncPtr_glClientAttribDefaultEXT = (GLEEPFNGLCLIENTATTRIBDEFAULTEXTPROC) __GLeeGetProcAddress("glClientAttribDefaultEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glPushClientAttribDefaultEXT = (GLEEPFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) __GLeeGetProcAddress("glPushClientAttribDefaultEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixLoadfEXT = (GLEEPFNGLMATRIXLOADFEXTPROC) __GLeeGetProcAddress("glMatrixLoadfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixLoaddEXT = (GLEEPFNGLMATRIXLOADDEXTPROC) __GLeeGetProcAddress("glMatrixLoaddEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixMultfEXT = (GLEEPFNGLMATRIXMULTFEXTPROC) __GLeeGetProcAddress("glMatrixMultfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixMultdEXT = (GLEEPFNGLMATRIXMULTDEXTPROC) __GLeeGetProcAddress("glMatrixMultdEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixLoadIdentityEXT = (GLEEPFNGLMATRIXLOADIDENTITYEXTPROC) __GLeeGetProcAddress("glMatrixLoadIdentityEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixRotatefEXT = (GLEEPFNGLMATRIXROTATEFEXTPROC) __GLeeGetProcAddress("glMatrixRotatefEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixRotatedEXT = (GLEEPFNGLMATRIXROTATEDEXTPROC) __GLeeGetProcAddress("glMatrixRotatedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixScalefEXT = (GLEEPFNGLMATRIXSCALEFEXTPROC) __GLeeGetProcAddress("glMatrixScalefEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixScaledEXT = (GLEEPFNGLMATRIXSCALEDEXTPROC) __GLeeGetProcAddress("glMatrixScaledEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixTranslatefEXT = (GLEEPFNGLMATRIXTRANSLATEFEXTPROC) __GLeeGetProcAddress("glMatrixTranslatefEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixTranslatedEXT = (GLEEPFNGLMATRIXTRANSLATEDEXTPROC) __GLeeGetProcAddress("glMatrixTranslatedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixFrustumEXT = (GLEEPFNGLMATRIXFRUSTUMEXTPROC) __GLeeGetProcAddress("glMatrixFrustumEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixOrthoEXT = (GLEEPFNGLMATRIXORTHOEXTPROC) __GLeeGetProcAddress("glMatrixOrthoEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixPopEXT = (GLEEPFNGLMATRIXPOPEXTPROC) __GLeeGetProcAddress("glMatrixPopEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixPushEXT = (GLEEPFNGLMATRIXPUSHEXTPROC) __GLeeGetProcAddress("glMatrixPushEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixLoadTransposefEXT = (GLEEPFNGLMATRIXLOADTRANSPOSEFEXTPROC) __GLeeGetProcAddress("glMatrixLoadTransposefEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixLoadTransposedEXT = (GLEEPFNGLMATRIXLOADTRANSPOSEDEXTPROC) __GLeeGetProcAddress("glMatrixLoadTransposedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixMultTransposefEXT = (GLEEPFNGLMATRIXMULTTRANSPOSEFEXTPROC) __GLeeGetProcAddress("glMatrixMultTransposefEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMatrixMultTransposedEXT = (GLEEPFNGLMATRIXMULTTRANSPOSEDEXTPROC) __GLeeGetProcAddress("glMatrixMultTransposedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureParameterfEXT = (GLEEPFNGLTEXTUREPARAMETERFEXTPROC) __GLeeGetProcAddress("glTextureParameterfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureParameterfvEXT = (GLEEPFNGLTEXTUREPARAMETERFVEXTPROC) __GLeeGetProcAddress("glTextureParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureParameteriEXT = (GLEEPFNGLTEXTUREPARAMETERIEXTPROC) __GLeeGetProcAddress("glTextureParameteriEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureParameterivEXT = (GLEEPFNGLTEXTUREPARAMETERIVEXTPROC) __GLeeGetProcAddress("glTextureParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureImage1DEXT = (GLEEPFNGLTEXTUREIMAGE1DEXTPROC) __GLeeGetProcAddress("glTextureImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureImage2DEXT = (GLEEPFNGLTEXTUREIMAGE2DEXTPROC) __GLeeGetProcAddress("glTextureImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureSubImage1DEXT = (GLEEPFNGLTEXTURESUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glTextureSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureSubImage2DEXT = (GLEEPFNGLTEXTURESUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glTextureSubImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTextureImage1DEXT = (GLEEPFNGLCOPYTEXTUREIMAGE1DEXTPROC) __GLeeGetProcAddress("glCopyTextureImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTextureImage2DEXT = (GLEEPFNGLCOPYTEXTUREIMAGE2DEXTPROC) __GLeeGetProcAddress("glCopyTextureImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTextureSubImage1DEXT = (GLEEPFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glCopyTextureSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTextureSubImage2DEXT = (GLEEPFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glCopyTextureSubImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureImageEXT = (GLEEPFNGLGETTEXTUREIMAGEEXTPROC) __GLeeGetProcAddress("glGetTextureImageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureParameterfvEXT = (GLEEPFNGLGETTEXTUREPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetTextureParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureParameterivEXT = (GLEEPFNGLGETTEXTUREPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetTextureParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureLevelParameterfvEXT = (GLEEPFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetTextureLevelParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureLevelParameterivEXT = (GLEEPFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetTextureLevelParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureImage3DEXT = (GLEEPFNGLTEXTUREIMAGE3DEXTPROC) __GLeeGetProcAddress("glTextureImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureSubImage3DEXT = (GLEEPFNGLTEXTURESUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glTextureSubImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyTextureSubImage3DEXT = (GLEEPFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glCopyTextureSubImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexParameterfEXT = (GLEEPFNGLMULTITEXPARAMETERFEXTPROC) __GLeeGetProcAddress("glMultiTexParameterfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexParameterfvEXT = (GLEEPFNGLMULTITEXPARAMETERFVEXTPROC) __GLeeGetProcAddress("glMultiTexParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexParameteriEXT = (GLEEPFNGLMULTITEXPARAMETERIEXTPROC) __GLeeGetProcAddress("glMultiTexParameteriEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexParameterivEXT = (GLEEPFNGLMULTITEXPARAMETERIVEXTPROC) __GLeeGetProcAddress("glMultiTexParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexImage1DEXT = (GLEEPFNGLMULTITEXIMAGE1DEXTPROC) __GLeeGetProcAddress("glMultiTexImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexImage2DEXT = (GLEEPFNGLMULTITEXIMAGE2DEXTPROC) __GLeeGetProcAddress("glMultiTexImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexSubImage1DEXT = (GLEEPFNGLMULTITEXSUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glMultiTexSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexSubImage2DEXT = (GLEEPFNGLMULTITEXSUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glMultiTexSubImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyMultiTexImage1DEXT = (GLEEPFNGLCOPYMULTITEXIMAGE1DEXTPROC) __GLeeGetProcAddress("glCopyMultiTexImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyMultiTexImage2DEXT = (GLEEPFNGLCOPYMULTITEXIMAGE2DEXTPROC) __GLeeGetProcAddress("glCopyMultiTexImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyMultiTexSubImage1DEXT = (GLEEPFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glCopyMultiTexSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyMultiTexSubImage2DEXT = (GLEEPFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glCopyMultiTexSubImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexImageEXT = (GLEEPFNGLGETMULTITEXIMAGEEXTPROC) __GLeeGetProcAddress("glGetMultiTexImageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexParameterfvEXT = (GLEEPFNGLGETMULTITEXPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetMultiTexParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexParameterivEXT = (GLEEPFNGLGETMULTITEXPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetMultiTexParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexLevelParameterfvEXT = (GLEEPFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetMultiTexLevelParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexLevelParameterivEXT = (GLEEPFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetMultiTexLevelParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexImage3DEXT = (GLEEPFNGLMULTITEXIMAGE3DEXTPROC) __GLeeGetProcAddress("glMultiTexImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexSubImage3DEXT = (GLEEPFNGLMULTITEXSUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glMultiTexSubImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyMultiTexSubImage3DEXT = (GLEEPFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glCopyMultiTexSubImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glBindMultiTextureEXT = (GLEEPFNGLBINDMULTITEXTUREEXTPROC) __GLeeGetProcAddress("glBindMultiTextureEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glEnableClientStateIndexedEXT = (GLEEPFNGLENABLECLIENTSTATEINDEXEDEXTPROC) __GLeeGetProcAddress("glEnableClientStateIndexedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glDisableClientStateIndexedEXT = (GLEEPFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) __GLeeGetProcAddress("glDisableClientStateIndexedEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoordPointerEXT = (GLEEPFNGLMULTITEXCOORDPOINTEREXTPROC) __GLeeGetProcAddress("glMultiTexCoordPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexEnvfEXT = (GLEEPFNGLMULTITEXENVFEXTPROC) __GLeeGetProcAddress("glMultiTexEnvfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexEnvfvEXT = (GLEEPFNGLMULTITEXENVFVEXTPROC) __GLeeGetProcAddress("glMultiTexEnvfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexEnviEXT = (GLEEPFNGLMULTITEXENVIEXTPROC) __GLeeGetProcAddress("glMultiTexEnviEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexEnvivEXT = (GLEEPFNGLMULTITEXENVIVEXTPROC) __GLeeGetProcAddress("glMultiTexEnvivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexGendEXT = (GLEEPFNGLMULTITEXGENDEXTPROC) __GLeeGetProcAddress("glMultiTexGendEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexGendvEXT = (GLEEPFNGLMULTITEXGENDVEXTPROC) __GLeeGetProcAddress("glMultiTexGendvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexGenfEXT = (GLEEPFNGLMULTITEXGENFEXTPROC) __GLeeGetProcAddress("glMultiTexGenfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexGenfvEXT = (GLEEPFNGLMULTITEXGENFVEXTPROC) __GLeeGetProcAddress("glMultiTexGenfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexGeniEXT = (GLEEPFNGLMULTITEXGENIEXTPROC) __GLeeGetProcAddress("glMultiTexGeniEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexGenivEXT = (GLEEPFNGLMULTITEXGENIVEXTPROC) __GLeeGetProcAddress("glMultiTexGenivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexEnvfvEXT = (GLEEPFNGLGETMULTITEXENVFVEXTPROC) __GLeeGetProcAddress("glGetMultiTexEnvfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexEnvivEXT = (GLEEPFNGLGETMULTITEXENVIVEXTPROC) __GLeeGetProcAddress("glGetMultiTexEnvivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexGendvEXT = (GLEEPFNGLGETMULTITEXGENDVEXTPROC) __GLeeGetProcAddress("glGetMultiTexGendvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexGenfvEXT = (GLEEPFNGLGETMULTITEXGENFVEXTPROC) __GLeeGetProcAddress("glGetMultiTexGenfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexGenivEXT = (GLEEPFNGLGETMULTITEXGENIVEXTPROC) __GLeeGetProcAddress("glGetMultiTexGenivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFloatIndexedvEXT = (GLEEPFNGLGETFLOATINDEXEDVEXTPROC) __GLeeGetProcAddress("glGetFloatIndexedvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetDoubleIndexedvEXT = (GLEEPFNGLGETDOUBLEINDEXEDVEXTPROC) __GLeeGetProcAddress("glGetDoubleIndexedvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPointerIndexedvEXT = (GLEEPFNGLGETPOINTERINDEXEDVEXTPROC) __GLeeGetProcAddress("glGetPointerIndexedvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTextureImage3DEXT = (GLEEPFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) __GLeeGetProcAddress("glCompressedTextureImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTextureImage2DEXT = (GLEEPFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) __GLeeGetProcAddress("glCompressedTextureImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTextureImage1DEXT = (GLEEPFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) __GLeeGetProcAddress("glCompressedTextureImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTextureSubImage3DEXT = (GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glCompressedTextureSubImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTextureSubImage2DEXT = (GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glCompressedTextureSubImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedTextureSubImage1DEXT = (GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glCompressedTextureSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCompressedTextureImageEXT = (GLEEPFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) __GLeeGetProcAddress("glGetCompressedTextureImageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedMultiTexImage3DEXT = (GLEEPFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) __GLeeGetProcAddress("glCompressedMultiTexImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedMultiTexImage2DEXT = (GLEEPFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) __GLeeGetProcAddress("glCompressedMultiTexImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedMultiTexImage1DEXT = (GLEEPFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) __GLeeGetProcAddress("glCompressedMultiTexImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedMultiTexSubImage3DEXT = (GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) __GLeeGetProcAddress("glCompressedMultiTexSubImage3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedMultiTexSubImage2DEXT = (GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) __GLeeGetProcAddress("glCompressedMultiTexSubImage2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCompressedMultiTexSubImage1DEXT = (GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) __GLeeGetProcAddress("glCompressedMultiTexSubImage1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetCompressedMultiTexImageEXT = (GLEEPFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) __GLeeGetProcAddress("glGetCompressedMultiTexImageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramStringEXT = (GLEEPFNGLNAMEDPROGRAMSTRINGEXTPROC) __GLeeGetProcAddress("glNamedProgramStringEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameter4dEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameter4dEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameter4dvEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameter4dvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameter4fEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameter4fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameter4fvEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameter4fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedProgramLocalParameterdvEXT = (GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) __GLeeGetProcAddress("glGetNamedProgramLocalParameterdvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedProgramLocalParameterfvEXT = (GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetNamedProgramLocalParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedProgramivEXT = (GLEEPFNGLGETNAMEDPROGRAMIVEXTPROC) __GLeeGetProcAddress("glGetNamedProgramivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedProgramStringEXT = (GLEEPFNGLGETNAMEDPROGRAMSTRINGEXTPROC) __GLeeGetProcAddress("glGetNamedProgramStringEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameters4fvEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameters4fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameterI4iEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameterI4iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameterI4ivEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameterI4ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParametersI4ivEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParametersI4ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameterI4uiEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameterI4uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParameterI4uivEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParameterI4uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedProgramLocalParametersI4uivEXT = (GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) __GLeeGetProcAddress("glNamedProgramLocalParametersI4uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedProgramLocalParameterIivEXT = (GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) __GLeeGetProcAddress("glGetNamedProgramLocalParameterIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedProgramLocalParameterIuivEXT = (GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) __GLeeGetProcAddress("glGetNamedProgramLocalParameterIuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureParameterIivEXT = (GLEEPFNGLTEXTUREPARAMETERIIVEXTPROC) __GLeeGetProcAddress("glTextureParameterIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureParameterIuivEXT = (GLEEPFNGLTEXTUREPARAMETERIUIVEXTPROC) __GLeeGetProcAddress("glTextureParameterIuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureParameterIivEXT = (GLEEPFNGLGETTEXTUREPARAMETERIIVEXTPROC) __GLeeGetProcAddress("glGetTextureParameterIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureParameterIuivEXT = (GLEEPFNGLGETTEXTUREPARAMETERIUIVEXTPROC) __GLeeGetProcAddress("glGetTextureParameterIuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexParameterIivEXT = (GLEEPFNGLMULTITEXPARAMETERIIVEXTPROC) __GLeeGetProcAddress("glMultiTexParameterIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexParameterIuivEXT = (GLEEPFNGLMULTITEXPARAMETERIUIVEXTPROC) __GLeeGetProcAddress("glMultiTexParameterIuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexParameterIivEXT = (GLEEPFNGLGETMULTITEXPARAMETERIIVEXTPROC) __GLeeGetProcAddress("glGetMultiTexParameterIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMultiTexParameterIuivEXT = (GLEEPFNGLGETMULTITEXPARAMETERIUIVEXTPROC) __GLeeGetProcAddress("glGetMultiTexParameterIuivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform1fEXT = (GLEEPFNGLPROGRAMUNIFORM1FEXTPROC) __GLeeGetProcAddress("glProgramUniform1fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform2fEXT = (GLEEPFNGLPROGRAMUNIFORM2FEXTPROC) __GLeeGetProcAddress("glProgramUniform2fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform3fEXT = (GLEEPFNGLPROGRAMUNIFORM3FEXTPROC) __GLeeGetProcAddress("glProgramUniform3fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform4fEXT = (GLEEPFNGLPROGRAMUNIFORM4FEXTPROC) __GLeeGetProcAddress("glProgramUniform4fEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform1iEXT = (GLEEPFNGLPROGRAMUNIFORM1IEXTPROC) __GLeeGetProcAddress("glProgramUniform1iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform2iEXT = (GLEEPFNGLPROGRAMUNIFORM2IEXTPROC) __GLeeGetProcAddress("glProgramUniform2iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform3iEXT = (GLEEPFNGLPROGRAMUNIFORM3IEXTPROC) __GLeeGetProcAddress("glProgramUniform3iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform4iEXT = (GLEEPFNGLPROGRAMUNIFORM4IEXTPROC) __GLeeGetProcAddress("glProgramUniform4iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform1fvEXT = (GLEEPFNGLPROGRAMUNIFORM1FVEXTPROC) __GLeeGetProcAddress("glProgramUniform1fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform2fvEXT = (GLEEPFNGLPROGRAMUNIFORM2FVEXTPROC) __GLeeGetProcAddress("glProgramUniform2fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform3fvEXT = (GLEEPFNGLPROGRAMUNIFORM3FVEXTPROC) __GLeeGetProcAddress("glProgramUniform3fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform4fvEXT = (GLEEPFNGLPROGRAMUNIFORM4FVEXTPROC) __GLeeGetProcAddress("glProgramUniform4fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform1ivEXT = (GLEEPFNGLPROGRAMUNIFORM1IVEXTPROC) __GLeeGetProcAddress("glProgramUniform1ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform2ivEXT = (GLEEPFNGLPROGRAMUNIFORM2IVEXTPROC) __GLeeGetProcAddress("glProgramUniform2ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform3ivEXT = (GLEEPFNGLPROGRAMUNIFORM3IVEXTPROC) __GLeeGetProcAddress("glProgramUniform3ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform4ivEXT = (GLEEPFNGLPROGRAMUNIFORM4IVEXTPROC) __GLeeGetProcAddress("glProgramUniform4ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix2fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix2fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix3fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix3fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix4fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix4fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix2x3fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix2x3fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix3x2fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix3x2fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix2x4fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix2x4fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix4x2fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix4x2fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix3x4fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix3x4fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformMatrix4x3fvEXT = (GLEEPFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) __GLeeGetProcAddress("glProgramUniformMatrix4x3fvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform1uiEXT = (GLEEPFNGLPROGRAMUNIFORM1UIEXTPROC) __GLeeGetProcAddress("glProgramUniform1uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform2uiEXT = (GLEEPFNGLPROGRAMUNIFORM2UIEXTPROC) __GLeeGetProcAddress("glProgramUniform2uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform3uiEXT = (GLEEPFNGLPROGRAMUNIFORM3UIEXTPROC) __GLeeGetProcAddress("glProgramUniform3uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform4uiEXT = (GLEEPFNGLPROGRAMUNIFORM4UIEXTPROC) __GLeeGetProcAddress("glProgramUniform4uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform1uivEXT = (GLEEPFNGLPROGRAMUNIFORM1UIVEXTPROC) __GLeeGetProcAddress("glProgramUniform1uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform2uivEXT = (GLEEPFNGLPROGRAMUNIFORM2UIVEXTPROC) __GLeeGetProcAddress("glProgramUniform2uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform3uivEXT = (GLEEPFNGLPROGRAMUNIFORM3UIVEXTPROC) __GLeeGetProcAddress("glProgramUniform3uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniform4uivEXT = (GLEEPFNGLPROGRAMUNIFORM4UIVEXTPROC) __GLeeGetProcAddress("glProgramUniform4uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedBufferDataEXT = (GLEEPFNGLNAMEDBUFFERDATAEXTPROC) __GLeeGetProcAddress("glNamedBufferDataEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedBufferSubDataEXT = (GLEEPFNGLNAMEDBUFFERSUBDATAEXTPROC) __GLeeGetProcAddress("glNamedBufferSubDataEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapNamedBufferEXT = (GLEEPFNGLMAPNAMEDBUFFEREXTPROC) __GLeeGetProcAddress("glMapNamedBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glUnmapNamedBufferEXT = (GLEEPFNGLUNMAPNAMEDBUFFEREXTPROC) __GLeeGetProcAddress("glUnmapNamedBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedBufferParameterivEXT = (GLEEPFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetNamedBufferParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedBufferPointervEXT = (GLEEPFNGLGETNAMEDBUFFERPOINTERVEXTPROC) __GLeeGetProcAddress("glGetNamedBufferPointervEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedBufferSubDataEXT = (GLEEPFNGLGETNAMEDBUFFERSUBDATAEXTPROC) __GLeeGetProcAddress("glGetNamedBufferSubDataEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureBufferEXT = (GLEEPFNGLTEXTUREBUFFEREXTPROC) __GLeeGetProcAddress("glTextureBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexBufferEXT = (GLEEPFNGLMULTITEXBUFFEREXTPROC) __GLeeGetProcAddress("glMultiTexBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedRenderbufferStorageEXT = (GLEEPFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) __GLeeGetProcAddress("glNamedRenderbufferStorageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedRenderbufferParameterivEXT = (GLEEPFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetNamedRenderbufferParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glCheckNamedFramebufferStatusEXT = (GLEEPFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) __GLeeGetProcAddress("glCheckNamedFramebufferStatusEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferTexture1DEXT = (GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) __GLeeGetProcAddress("glNamedFramebufferTexture1DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferTexture2DEXT = (GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) __GLeeGetProcAddress("glNamedFramebufferTexture2DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferTexture3DEXT = (GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) __GLeeGetProcAddress("glNamedFramebufferTexture3DEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferRenderbufferEXT = (GLEEPFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) __GLeeGetProcAddress("glNamedFramebufferRenderbufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedFramebufferAttachmentParameterivEXT = (GLEEPFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetNamedFramebufferAttachmentParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenerateTextureMipmapEXT = (GLEEPFNGLGENERATETEXTUREMIPMAPEXTPROC) __GLeeGetProcAddress("glGenerateTextureMipmapEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenerateMultiTexMipmapEXT = (GLEEPFNGLGENERATEMULTITEXMIPMAPEXTPROC) __GLeeGetProcAddress("glGenerateMultiTexMipmapEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferDrawBufferEXT = (GLEEPFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) __GLeeGetProcAddress("glFramebufferDrawBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferDrawBuffersEXT = (GLEEPFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) __GLeeGetProcAddress("glFramebufferDrawBuffersEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferReadBufferEXT = (GLEEPFNGLFRAMEBUFFERREADBUFFEREXTPROC) __GLeeGetProcAddress("glFramebufferReadBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFramebufferParameterivEXT = (GLEEPFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetFramebufferParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedRenderbufferStorageMultisampleEXT = (GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) __GLeeGetProcAddress("glNamedRenderbufferStorageMultisampleEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedRenderbufferStorageMultisampleCoverageEXT = (GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) __GLeeGetProcAddress("glNamedRenderbufferStorageMultisampleCoverageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferTextureEXT = (GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) __GLeeGetProcAddress("glNamedFramebufferTextureEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferTextureLayerEXT = (GLEEPFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) __GLeeGetProcAddress("glNamedFramebufferTextureLayerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferTextureFaceEXT = (GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) __GLeeGetProcAddress("glNamedFramebufferTextureFaceEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureRenderbufferEXT = (GLEEPFNGLTEXTURERENDERBUFFEREXTPROC) __GLeeGetProcAddress("glTextureRenderbufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexRenderbufferEXT = (GLEEPFNGLMULTITEXRENDERBUFFEREXTPROC) __GLeeGetProcAddress("glMultiTexRenderbufferEXT"))!=0) nLinked++; +#endif + if (nLinked==186) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_vertex_array_bgra(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_swizzle(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_explicit_multisample(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_explicit_multisample + if ((GLeeFuncPtr_glGetMultisamplefvNV = (GLEEPFNGLGETMULTISAMPLEFVNVPROC) __GLeeGetProcAddress("glGetMultisamplefvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glSampleMaskIndexedNV = (GLEEPFNGLSAMPLEMASKINDEXEDNVPROC) __GLeeGetProcAddress("glSampleMaskIndexedNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexRenderbufferNV = (GLEEPFNGLTEXRENDERBUFFERNVPROC) __GLeeGetProcAddress("glTexRenderbufferNV"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_transform_feedback2(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_transform_feedback2 + if ((GLeeFuncPtr_glBindTransformFeedbackNV = (GLEEPFNGLBINDTRANSFORMFEEDBACKNVPROC) __GLeeGetProcAddress("glBindTransformFeedbackNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeleteTransformFeedbacksNV = (GLEEPFNGLDELETETRANSFORMFEEDBACKSNVPROC) __GLeeGetProcAddress("glDeleteTransformFeedbacksNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGenTransformFeedbacksNV = (GLEEPFNGLGENTRANSFORMFEEDBACKSNVPROC) __GLeeGetProcAddress("glGenTransformFeedbacksNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsTransformFeedbackNV = (GLEEPFNGLISTRANSFORMFEEDBACKNVPROC) __GLeeGetProcAddress("glIsTransformFeedbackNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPauseTransformFeedbackNV = (GLEEPFNGLPAUSETRANSFORMFEEDBACKNVPROC) __GLeeGetProcAddress("glPauseTransformFeedbackNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glResumeTransformFeedbackNV = (GLEEPFNGLRESUMETRANSFORMFEEDBACKNVPROC) __GLeeGetProcAddress("glResumeTransformFeedbackNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glDrawTransformFeedbackNV = (GLEEPFNGLDRAWTRANSFORMFEEDBACKNVPROC) __GLeeGetProcAddress("glDrawTransformFeedbackNV"))!=0) nLinked++; +#endif + if (nLinked==7) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_texture_select(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_INGR_blend_func_separate(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_INGR_blend_func_separate + if ((GLeeFuncPtr_glBlendFuncSeparateINGR = (GLEEPFNGLBLENDFUNCSEPARATEINGRPROC) __GLeeGetProcAddress("glBlendFuncSeparateINGR"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_depth_pass_instrument(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_igloo_interface(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_SGIX_igloo_interface + if ((GLeeFuncPtr_glIglooInterfaceSGIX = (GLEEPFNGLIGLOOINTERFACESGIXPROC) __GLeeGetProcAddress("glIglooInterfaceSGIX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_fragment_lighting(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_fragment_lighting + if ((GLeeFuncPtr_glFragmentLightModeliEXT = (GLEEPFNGLFRAGMENTLIGHTMODELIEXTPROC) __GLeeGetProcAddress("glFragmentLightModeliEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightModelfEXT = (GLEEPFNGLFRAGMENTLIGHTMODELFEXTPROC) __GLeeGetProcAddress("glFragmentLightModelfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightModelivEXT = (GLEEPFNGLFRAGMENTLIGHTMODELIVEXTPROC) __GLeeGetProcAddress("glFragmentLightModelivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightModelfvEXT = (GLEEPFNGLFRAGMENTLIGHTMODELFVEXTPROC) __GLeeGetProcAddress("glFragmentLightModelfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightiEXT = (GLEEPFNGLFRAGMENTLIGHTIEXTPROC) __GLeeGetProcAddress("glFragmentLightiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightfEXT = (GLEEPFNGLFRAGMENTLIGHTFEXTPROC) __GLeeGetProcAddress("glFragmentLightfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightivEXT = (GLEEPFNGLFRAGMENTLIGHTIVEXTPROC) __GLeeGetProcAddress("glFragmentLightivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentLightfvEXT = (GLEEPFNGLFRAGMENTLIGHTFVEXTPROC) __GLeeGetProcAddress("glFragmentLightfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentLightivEXT = (GLEEPFNGLGETFRAGMENTLIGHTIVEXTPROC) __GLeeGetProcAddress("glGetFragmentLightivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentLightfvEXT = (GLEEPFNGLGETFRAGMENTLIGHTFVEXTPROC) __GLeeGetProcAddress("glGetFragmentLightfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialfEXT = (GLEEPFNGLFRAGMENTMATERIALFEXTPROC) __GLeeGetProcAddress("glFragmentMaterialfEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialiEXT = (GLEEPFNGLFRAGMENTMATERIALIEXTPROC) __GLeeGetProcAddress("glFragmentMaterialiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialfvEXT = (GLEEPFNGLFRAGMENTMATERIALFVEXTPROC) __GLeeGetProcAddress("glFragmentMaterialfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentMaterialivEXT = (GLEEPFNGLFRAGMENTMATERIALIVEXTPROC) __GLeeGetProcAddress("glFragmentMaterialivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFragmentColorMaterialEXT = (GLEEPFNGLFRAGMENTCOLORMATERIALEXTPROC) __GLeeGetProcAddress("glFragmentColorMaterialEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentMaterialfvEXT = (GLEEPFNGLGETFRAGMENTMATERIALFVEXTPROC) __GLeeGetProcAddress("glGetFragmentMaterialfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFragmentMaterialivEXT = (GLEEPFNGLGETFRAGMENTMATERIALIVEXTPROC) __GLeeGetProcAddress("glGetFragmentMaterialivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glLightEnviEXT = (GLEEPFNGLLIGHTENVIEXTPROC) __GLeeGetProcAddress("glLightEnviEXT"))!=0) nLinked++; +#endif + if (nLinked==18) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_geometry_shader4(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_geometry_shader4 + if ((GLeeFuncPtr_glProgramParameteriEXT = (GLEEPFNGLPROGRAMPARAMETERIEXTPROC) __GLeeGetProcAddress("glProgramParameteriEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureEXT = (GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC) __GLeeGetProcAddress("glFramebufferTextureEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureLayerEXT = (GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) __GLeeGetProcAddress("glFramebufferTextureLayerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureFaceEXT = (GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) __GLeeGetProcAddress("glFramebufferTextureFaceEXT"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_scene_marker(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_EXT_scene_marker + if ((GLeeFuncPtr_glBeginSceneEXT = (GLEEPFNGLBEGINSCENEEXTPROC) __GLeeGetProcAddress("glBeginSceneEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndSceneEXT = (GLEEPFNGLENDSCENEEXTPROC) __GLeeGetProcAddress("glEndSceneEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_EXT_texture_compression_dxt1(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_EXT_texture_env(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_IBM_static_data(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_gpu_program4(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_gpu_program4 + if ((GLeeFuncPtr_glProgramLocalParameterI4iNV = (GLEEPFNGLPROGRAMLOCALPARAMETERI4INVPROC) __GLeeGetProcAddress("glProgramLocalParameterI4iNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameterI4ivNV = (GLEEPFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) __GLeeGetProcAddress("glProgramLocalParameterI4ivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParametersI4ivNV = (GLEEPFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) __GLeeGetProcAddress("glProgramLocalParametersI4ivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameterI4uiNV = (GLEEPFNGLPROGRAMLOCALPARAMETERI4UINVPROC) __GLeeGetProcAddress("glProgramLocalParameterI4uiNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParameterI4uivNV = (GLEEPFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) __GLeeGetProcAddress("glProgramLocalParameterI4uivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramLocalParametersI4uivNV = (GLEEPFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) __GLeeGetProcAddress("glProgramLocalParametersI4uivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameterI4iNV = (GLEEPFNGLPROGRAMENVPARAMETERI4INVPROC) __GLeeGetProcAddress("glProgramEnvParameterI4iNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameterI4ivNV = (GLEEPFNGLPROGRAMENVPARAMETERI4IVNVPROC) __GLeeGetProcAddress("glProgramEnvParameterI4ivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParametersI4ivNV = (GLEEPFNGLPROGRAMENVPARAMETERSI4IVNVPROC) __GLeeGetProcAddress("glProgramEnvParametersI4ivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameterI4uiNV = (GLEEPFNGLPROGRAMENVPARAMETERI4UINVPROC) __GLeeGetProcAddress("glProgramEnvParameterI4uiNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParameterI4uivNV = (GLEEPFNGLPROGRAMENVPARAMETERI4UIVNVPROC) __GLeeGetProcAddress("glProgramEnvParameterI4uivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramEnvParametersI4uivNV = (GLEEPFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) __GLeeGetProcAddress("glProgramEnvParametersI4uivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramLocalParameterIivNV = (GLEEPFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) __GLeeGetProcAddress("glGetProgramLocalParameterIivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramLocalParameterIuivNV = (GLEEPFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) __GLeeGetProcAddress("glGetProgramLocalParameterIuivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramEnvParameterIivNV = (GLEEPFNGLGETPROGRAMENVPARAMETERIIVNVPROC) __GLeeGetProcAddress("glGetProgramEnvParameterIivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramEnvParameterIuivNV = (GLEEPFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) __GLeeGetProcAddress("glGetProgramEnvParameterIuivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureEXT = (GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC) __GLeeGetProcAddress("glFramebufferTextureEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureLayerEXT = (GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) __GLeeGetProcAddress("glFramebufferTextureLayerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glFramebufferTextureFaceEXT = (GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) __GLeeGetProcAddress("glFramebufferTextureFaceEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2iEXT = (GLEEPFNGLVERTEXATTRIBI2IEXTPROC) __GLeeGetProcAddress("glVertexAttribI2iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3iEXT = (GLEEPFNGLVERTEXATTRIBI3IEXTPROC) __GLeeGetProcAddress("glVertexAttribI3iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4iEXT = (GLEEPFNGLVERTEXATTRIBI4IEXTPROC) __GLeeGetProcAddress("glVertexAttribI4iEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI1uiEXT = (GLEEPFNGLVERTEXATTRIBI1UIEXTPROC) __GLeeGetProcAddress("glVertexAttribI1uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2uiEXT = (GLEEPFNGLVERTEXATTRIBI2UIEXTPROC) __GLeeGetProcAddress("glVertexAttribI2uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3uiEXT = (GLEEPFNGLVERTEXATTRIBI3UIEXTPROC) __GLeeGetProcAddress("glVertexAttribI3uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4uiEXT = (GLEEPFNGLVERTEXATTRIBI4UIEXTPROC) __GLeeGetProcAddress("glVertexAttribI4uiEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI1ivEXT = (GLEEPFNGLVERTEXATTRIBI1IVEXTPROC) __GLeeGetProcAddress("glVertexAttribI1ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2ivEXT = (GLEEPFNGLVERTEXATTRIBI2IVEXTPROC) __GLeeGetProcAddress("glVertexAttribI2ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3ivEXT = (GLEEPFNGLVERTEXATTRIBI3IVEXTPROC) __GLeeGetProcAddress("glVertexAttribI3ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4ivEXT = (GLEEPFNGLVERTEXATTRIBI4IVEXTPROC) __GLeeGetProcAddress("glVertexAttribI4ivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI1uivEXT = (GLEEPFNGLVERTEXATTRIBI1UIVEXTPROC) __GLeeGetProcAddress("glVertexAttribI1uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI2uivEXT = (GLEEPFNGLVERTEXATTRIBI2UIVEXTPROC) __GLeeGetProcAddress("glVertexAttribI2uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI3uivEXT = (GLEEPFNGLVERTEXATTRIBI3UIVEXTPROC) __GLeeGetProcAddress("glVertexAttribI3uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4uivEXT = (GLEEPFNGLVERTEXATTRIBI4UIVEXTPROC) __GLeeGetProcAddress("glVertexAttribI4uivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4bvEXT = (GLEEPFNGLVERTEXATTRIBI4BVEXTPROC) __GLeeGetProcAddress("glVertexAttribI4bvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4svEXT = (GLEEPFNGLVERTEXATTRIBI4SVEXTPROC) __GLeeGetProcAddress("glVertexAttribI4svEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4ubvEXT = (GLEEPFNGLVERTEXATTRIBI4UBVEXTPROC) __GLeeGetProcAddress("glVertexAttribI4ubvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribI4usvEXT = (GLEEPFNGLVERTEXATTRIBI4USVEXTPROC) __GLeeGetProcAddress("glVertexAttribI4usvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribIPointerEXT = (GLEEPFNGLVERTEXATTRIBIPOINTEREXTPROC) __GLeeGetProcAddress("glVertexAttribIPointerEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribIivEXT = (GLEEPFNGLGETVERTEXATTRIBIIVEXTPROC) __GLeeGetProcAddress("glGetVertexAttribIivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetVertexAttribIuivEXT = (GLEEPFNGLGETVERTEXATTRIBIUIVEXTPROC) __GLeeGetProcAddress("glGetVertexAttribIuivEXT"))!=0) nLinked++; +#endif + if (nLinked==41) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_OES_byte_coordinates(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_OES_compressed_paletted_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_OES_single_precision(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_OES_single_precision + if ((GLeeFuncPtr_glDepthRangefOES = (GLEEPFNGLDEPTHRANGEFOESPROC) __GLeeGetProcAddress("glDepthRangefOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glFrustumfOES = (GLEEPFNGLFRUSTUMFOESPROC) __GLeeGetProcAddress("glFrustumfOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glOrthofOES = (GLEEPFNGLORTHOFOESPROC) __GLeeGetProcAddress("glOrthofOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClipPlanefOES = (GLEEPFNGLCLIPPLANEFOESPROC) __GLeeGetProcAddress("glClipPlanefOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetClipPlanefOES = (GLEEPFNGLGETCLIPPLANEFOESPROC) __GLeeGetProcAddress("glGetClipPlanefOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearDepthfOES = (GLEEPFNGLCLEARDEPTHFOESPROC) __GLeeGetProcAddress("glClearDepthfOES"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_SGIX_pixel_texture_bits(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_SGIX_texture_range(void) {return GLEE_LINK_COMPLETE;} + +GLEE_LINK_FUNCTION __GLeeGLLoadFunction[322]; + +void initGLLoadFunctions(void) +{ + __GLeeGLLoadFunction[0]=__GLeeLink_GL_VERSION_1_2; + __GLeeGLLoadFunction[1]=__GLeeLink_GL_ARB_imaging; + __GLeeGLLoadFunction[2]=__GLeeLink_GL_VERSION_1_3; + __GLeeGLLoadFunction[3]=__GLeeLink_GL_VERSION_1_4; + __GLeeGLLoadFunction[4]=__GLeeLink_GL_VERSION_1_5; + __GLeeGLLoadFunction[5]=__GLeeLink_GL_VERSION_2_0; + __GLeeGLLoadFunction[6]=__GLeeLink_GL_VERSION_2_1; + __GLeeGLLoadFunction[7]=__GLeeLink_GL_VERSION_3_0; + __GLeeGLLoadFunction[8]=__GLeeLink_GL_ARB_multitexture; + __GLeeGLLoadFunction[9]=__GLeeLink_GL_ARB_transpose_matrix; + __GLeeGLLoadFunction[10]=__GLeeLink_GL_ARB_multisample; + __GLeeGLLoadFunction[11]=__GLeeLink_GL_ARB_texture_env_add; + __GLeeGLLoadFunction[12]=__GLeeLink_GL_ARB_texture_cube_map; + __GLeeGLLoadFunction[13]=__GLeeLink_GL_ARB_texture_compression; + __GLeeGLLoadFunction[14]=__GLeeLink_GL_ARB_texture_border_clamp; + __GLeeGLLoadFunction[15]=__GLeeLink_GL_ARB_point_parameters; + __GLeeGLLoadFunction[16]=__GLeeLink_GL_ARB_vertex_blend; + __GLeeGLLoadFunction[17]=__GLeeLink_GL_ARB_matrix_palette; + __GLeeGLLoadFunction[18]=__GLeeLink_GL_ARB_texture_env_combine; + __GLeeGLLoadFunction[19]=__GLeeLink_GL_ARB_texture_env_crossbar; + __GLeeGLLoadFunction[20]=__GLeeLink_GL_ARB_texture_env_dot3; + __GLeeGLLoadFunction[21]=__GLeeLink_GL_ARB_texture_mirrored_repeat; + __GLeeGLLoadFunction[22]=__GLeeLink_GL_ARB_depth_texture; + __GLeeGLLoadFunction[23]=__GLeeLink_GL_ARB_shadow; + __GLeeGLLoadFunction[24]=__GLeeLink_GL_ARB_shadow_ambient; + __GLeeGLLoadFunction[25]=__GLeeLink_GL_ARB_window_pos; + __GLeeGLLoadFunction[26]=__GLeeLink_GL_ARB_vertex_program; + __GLeeGLLoadFunction[27]=__GLeeLink_GL_ARB_fragment_program; + __GLeeGLLoadFunction[28]=__GLeeLink_GL_ARB_vertex_buffer_object; + __GLeeGLLoadFunction[29]=__GLeeLink_GL_ARB_occlusion_query; + __GLeeGLLoadFunction[30]=__GLeeLink_GL_ARB_shader_objects; + __GLeeGLLoadFunction[31]=__GLeeLink_GL_ARB_vertex_shader; + __GLeeGLLoadFunction[32]=__GLeeLink_GL_ARB_fragment_shader; + __GLeeGLLoadFunction[33]=__GLeeLink_GL_ARB_shading_language_100; + __GLeeGLLoadFunction[34]=__GLeeLink_GL_ARB_texture_non_power_of_two; + __GLeeGLLoadFunction[35]=__GLeeLink_GL_ARB_point_sprite; + __GLeeGLLoadFunction[36]=__GLeeLink_GL_ARB_fragment_program_shadow; + __GLeeGLLoadFunction[37]=__GLeeLink_GL_ARB_draw_buffers; + __GLeeGLLoadFunction[38]=__GLeeLink_GL_ARB_texture_rectangle; + __GLeeGLLoadFunction[39]=__GLeeLink_GL_ARB_color_buffer_float; + __GLeeGLLoadFunction[40]=__GLeeLink_GL_ARB_half_float_pixel; + __GLeeGLLoadFunction[41]=__GLeeLink_GL_ARB_texture_float; + __GLeeGLLoadFunction[42]=__GLeeLink_GL_ARB_pixel_buffer_object; + __GLeeGLLoadFunction[43]=__GLeeLink_GL_ARB_depth_buffer_float; + __GLeeGLLoadFunction[44]=__GLeeLink_GL_ARB_draw_instanced; + __GLeeGLLoadFunction[45]=__GLeeLink_GL_ARB_framebuffer_object; + __GLeeGLLoadFunction[46]=__GLeeLink_GL_ARB_framebuffer_sRGB; + __GLeeGLLoadFunction[47]=__GLeeLink_GL_ARB_geometry_shader4; + __GLeeGLLoadFunction[48]=__GLeeLink_GL_ARB_half_float_vertex; + __GLeeGLLoadFunction[49]=__GLeeLink_GL_ARB_instanced_arrays; + __GLeeGLLoadFunction[50]=__GLeeLink_GL_ARB_map_buffer_range; + __GLeeGLLoadFunction[51]=__GLeeLink_GL_ARB_texture_buffer_object; + __GLeeGLLoadFunction[52]=__GLeeLink_GL_ARB_texture_compression_rgtc; + __GLeeGLLoadFunction[53]=__GLeeLink_GL_ARB_texture_rg; + __GLeeGLLoadFunction[54]=__GLeeLink_GL_ARB_vertex_array_object; + __GLeeGLLoadFunction[55]=__GLeeLink_GL_EXT_abgr; + __GLeeGLLoadFunction[56]=__GLeeLink_GL_EXT_blend_color; + __GLeeGLLoadFunction[57]=__GLeeLink_GL_EXT_polygon_offset; + __GLeeGLLoadFunction[58]=__GLeeLink_GL_EXT_texture; + __GLeeGLLoadFunction[59]=__GLeeLink_GL_EXT_texture3D; + __GLeeGLLoadFunction[60]=__GLeeLink_GL_SGIS_texture_filter4; + __GLeeGLLoadFunction[61]=__GLeeLink_GL_EXT_subtexture; + __GLeeGLLoadFunction[62]=__GLeeLink_GL_EXT_copy_texture; + __GLeeGLLoadFunction[63]=__GLeeLink_GL_EXT_histogram; + __GLeeGLLoadFunction[64]=__GLeeLink_GL_EXT_convolution; + __GLeeGLLoadFunction[65]=__GLeeLink_GL_SGI_color_matrix; + __GLeeGLLoadFunction[66]=__GLeeLink_GL_SGI_color_table; + __GLeeGLLoadFunction[67]=__GLeeLink_GL_SGIS_pixel_texture; + __GLeeGLLoadFunction[68]=__GLeeLink_GL_SGIX_pixel_texture; + __GLeeGLLoadFunction[69]=__GLeeLink_GL_SGIS_texture4D; + __GLeeGLLoadFunction[70]=__GLeeLink_GL_SGI_texture_color_table; + __GLeeGLLoadFunction[71]=__GLeeLink_GL_EXT_cmyka; + __GLeeGLLoadFunction[72]=__GLeeLink_GL_EXT_texture_object; + __GLeeGLLoadFunction[73]=__GLeeLink_GL_SGIS_detail_texture; + __GLeeGLLoadFunction[74]=__GLeeLink_GL_SGIS_sharpen_texture; + __GLeeGLLoadFunction[75]=__GLeeLink_GL_EXT_packed_pixels; + __GLeeGLLoadFunction[76]=__GLeeLink_GL_SGIS_texture_lod; + __GLeeGLLoadFunction[77]=__GLeeLink_GL_SGIS_multisample; + __GLeeGLLoadFunction[78]=__GLeeLink_GL_EXT_rescale_normal; + __GLeeGLLoadFunction[79]=__GLeeLink_GL_EXT_vertex_array; + __GLeeGLLoadFunction[80]=__GLeeLink_GL_EXT_misc_attribute; + __GLeeGLLoadFunction[81]=__GLeeLink_GL_SGIS_generate_mipmap; + __GLeeGLLoadFunction[82]=__GLeeLink_GL_SGIX_clipmap; + __GLeeGLLoadFunction[83]=__GLeeLink_GL_SGIX_shadow; + __GLeeGLLoadFunction[84]=__GLeeLink_GL_SGIS_texture_edge_clamp; + __GLeeGLLoadFunction[85]=__GLeeLink_GL_SGIS_texture_border_clamp; + __GLeeGLLoadFunction[86]=__GLeeLink_GL_EXT_blend_minmax; + __GLeeGLLoadFunction[87]=__GLeeLink_GL_EXT_blend_subtract; + __GLeeGLLoadFunction[88]=__GLeeLink_GL_EXT_blend_logic_op; + __GLeeGLLoadFunction[89]=__GLeeLink_GL_SGIX_interlace; + __GLeeGLLoadFunction[90]=__GLeeLink_GL_SGIX_pixel_tiles; + __GLeeGLLoadFunction[91]=__GLeeLink_GL_SGIS_texture_select; + __GLeeGLLoadFunction[92]=__GLeeLink_GL_SGIX_sprite; + __GLeeGLLoadFunction[93]=__GLeeLink_GL_SGIX_texture_multi_buffer; + __GLeeGLLoadFunction[94]=__GLeeLink_GL_EXT_point_parameters; + __GLeeGLLoadFunction[95]=__GLeeLink_GL_SGIS_point_parameters; + __GLeeGLLoadFunction[96]=__GLeeLink_GL_SGIX_instruments; + __GLeeGLLoadFunction[97]=__GLeeLink_GL_SGIX_texture_scale_bias; + __GLeeGLLoadFunction[98]=__GLeeLink_GL_SGIX_framezoom; + __GLeeGLLoadFunction[99]=__GLeeLink_GL_SGIX_tag_sample_buffer; + __GLeeGLLoadFunction[100]=__GLeeLink_GL_FfdMaskSGIX; + __GLeeGLLoadFunction[101]=__GLeeLink_GL_SGIX_polynomial_ffd; + __GLeeGLLoadFunction[102]=__GLeeLink_GL_SGIX_reference_plane; + __GLeeGLLoadFunction[103]=__GLeeLink_GL_SGIX_flush_raster; + __GLeeGLLoadFunction[104]=__GLeeLink_GL_SGIX_depth_texture; + __GLeeGLLoadFunction[105]=__GLeeLink_GL_SGIS_fog_function; + __GLeeGLLoadFunction[106]=__GLeeLink_GL_SGIX_fog_offset; + __GLeeGLLoadFunction[107]=__GLeeLink_GL_HP_image_transform; + __GLeeGLLoadFunction[108]=__GLeeLink_GL_HP_convolution_border_modes; + __GLeeGLLoadFunction[109]=__GLeeLink_GL_INGR_palette_buffer; + __GLeeGLLoadFunction[110]=__GLeeLink_GL_SGIX_texture_add_env; + __GLeeGLLoadFunction[111]=__GLeeLink_GL_EXT_color_subtable; + __GLeeGLLoadFunction[112]=__GLeeLink_GL_PGI_vertex_hints; + __GLeeGLLoadFunction[113]=__GLeeLink_GL_PGI_misc_hints; + __GLeeGLLoadFunction[114]=__GLeeLink_GL_EXT_paletted_texture; + __GLeeGLLoadFunction[115]=__GLeeLink_GL_EXT_clip_volume_hint; + __GLeeGLLoadFunction[116]=__GLeeLink_GL_SGIX_list_priority; + __GLeeGLLoadFunction[117]=__GLeeLink_GL_SGIX_ir_instrument1; + __GLeeGLLoadFunction[118]=__GLeeLink_GL_SGIX_calligraphic_fragment; + __GLeeGLLoadFunction[119]=__GLeeLink_GL_SGIX_texture_lod_bias; + __GLeeGLLoadFunction[120]=__GLeeLink_GL_SGIX_shadow_ambient; + __GLeeGLLoadFunction[121]=__GLeeLink_GL_EXT_index_texture; + __GLeeGLLoadFunction[122]=__GLeeLink_GL_EXT_index_material; + __GLeeGLLoadFunction[123]=__GLeeLink_GL_EXT_index_func; + __GLeeGLLoadFunction[124]=__GLeeLink_GL_EXT_index_array_formats; + __GLeeGLLoadFunction[125]=__GLeeLink_GL_EXT_compiled_vertex_array; + __GLeeGLLoadFunction[126]=__GLeeLink_GL_EXT_cull_vertex; + __GLeeGLLoadFunction[127]=__GLeeLink_GL_SGIX_ycrcb; + __GLeeGLLoadFunction[128]=__GLeeLink_GL_SGIX_fragment_lighting; + __GLeeGLLoadFunction[129]=__GLeeLink_GL_IBM_rasterpos_clip; + __GLeeGLLoadFunction[130]=__GLeeLink_GL_HP_texture_lighting; + __GLeeGLLoadFunction[131]=__GLeeLink_GL_EXT_draw_range_elements; + __GLeeGLLoadFunction[132]=__GLeeLink_GL_WIN_phong_shading; + __GLeeGLLoadFunction[133]=__GLeeLink_GL_WIN_specular_fog; + __GLeeGLLoadFunction[134]=__GLeeLink_GL_EXT_light_texture; + __GLeeGLLoadFunction[135]=__GLeeLink_GL_SGIX_blend_alpha_minmax; + __GLeeGLLoadFunction[136]=__GLeeLink_GL_SGIX_impact_pixel_texture; + __GLeeGLLoadFunction[137]=__GLeeLink_GL_EXT_bgra; + __GLeeGLLoadFunction[138]=__GLeeLink_GL_SGIX_async; + __GLeeGLLoadFunction[139]=__GLeeLink_GL_SGIX_async_pixel; + __GLeeGLLoadFunction[140]=__GLeeLink_GL_SGIX_async_histogram; + __GLeeGLLoadFunction[141]=__GLeeLink_GL_INTEL_texture_scissor; + __GLeeGLLoadFunction[142]=__GLeeLink_GL_INTEL_parallel_arrays; + __GLeeGLLoadFunction[143]=__GLeeLink_GL_HP_occlusion_test; + __GLeeGLLoadFunction[144]=__GLeeLink_GL_EXT_pixel_transform; + __GLeeGLLoadFunction[145]=__GLeeLink_GL_EXT_pixel_transform_color_table; + __GLeeGLLoadFunction[146]=__GLeeLink_GL_EXT_shared_texture_palette; + __GLeeGLLoadFunction[147]=__GLeeLink_GL_EXT_separate_specular_color; + __GLeeGLLoadFunction[148]=__GLeeLink_GL_EXT_secondary_color; + __GLeeGLLoadFunction[149]=__GLeeLink_GL_EXT_texture_perturb_normal; + __GLeeGLLoadFunction[150]=__GLeeLink_GL_EXT_multi_draw_arrays; + __GLeeGLLoadFunction[151]=__GLeeLink_GL_EXT_fog_coord; + __GLeeGLLoadFunction[152]=__GLeeLink_GL_REND_screen_coordinates; + __GLeeGLLoadFunction[153]=__GLeeLink_GL_EXT_coordinate_frame; + __GLeeGLLoadFunction[154]=__GLeeLink_GL_EXT_texture_env_combine; + __GLeeGLLoadFunction[155]=__GLeeLink_GL_APPLE_specular_vector; + __GLeeGLLoadFunction[156]=__GLeeLink_GL_APPLE_transform_hint; + __GLeeGLLoadFunction[157]=__GLeeLink_GL_SGIX_fog_scale; + __GLeeGLLoadFunction[158]=__GLeeLink_GL_SUNX_constant_data; + __GLeeGLLoadFunction[159]=__GLeeLink_GL_SUN_global_alpha; + __GLeeGLLoadFunction[160]=__GLeeLink_GL_SUN_triangle_list; + __GLeeGLLoadFunction[161]=__GLeeLink_GL_SUN_vertex; + __GLeeGLLoadFunction[162]=__GLeeLink_GL_EXT_blend_func_separate; + __GLeeGLLoadFunction[163]=__GLeeLink_GL_INGR_color_clamp; + __GLeeGLLoadFunction[164]=__GLeeLink_GL_INGR_interlace_read; + __GLeeGLLoadFunction[165]=__GLeeLink_GL_EXT_stencil_wrap; + __GLeeGLLoadFunction[166]=__GLeeLink_GL_EXT_422_pixels; + __GLeeGLLoadFunction[167]=__GLeeLink_GL_NV_texgen_reflection; + __GLeeGLLoadFunction[168]=__GLeeLink_GL_EXT_texture_cube_map; + __GLeeGLLoadFunction[169]=__GLeeLink_GL_SUN_convolution_border_modes; + __GLeeGLLoadFunction[170]=__GLeeLink_GL_EXT_texture_env_add; + __GLeeGLLoadFunction[171]=__GLeeLink_GL_EXT_texture_lod_bias; + __GLeeGLLoadFunction[172]=__GLeeLink_GL_EXT_texture_filter_anisotropic; + __GLeeGLLoadFunction[173]=__GLeeLink_GL_EXT_vertex_weighting; + __GLeeGLLoadFunction[174]=__GLeeLink_GL_NV_light_max_exponent; + __GLeeGLLoadFunction[175]=__GLeeLink_GL_NV_vertex_array_range; + __GLeeGLLoadFunction[176]=__GLeeLink_GL_NV_register_combiners; + __GLeeGLLoadFunction[177]=__GLeeLink_GL_NV_fog_distance; + __GLeeGLLoadFunction[178]=__GLeeLink_GL_NV_texgen_emboss; + __GLeeGLLoadFunction[179]=__GLeeLink_GL_NV_blend_square; + __GLeeGLLoadFunction[180]=__GLeeLink_GL_NV_texture_env_combine4; + __GLeeGLLoadFunction[181]=__GLeeLink_GL_MESA_resize_buffers; + __GLeeGLLoadFunction[182]=__GLeeLink_GL_MESA_window_pos; + __GLeeGLLoadFunction[183]=__GLeeLink_GL_EXT_texture_compression_s3tc; + __GLeeGLLoadFunction[184]=__GLeeLink_GL_IBM_cull_vertex; + __GLeeGLLoadFunction[185]=__GLeeLink_GL_IBM_multimode_draw_arrays; + __GLeeGLLoadFunction[186]=__GLeeLink_GL_IBM_vertex_array_lists; + __GLeeGLLoadFunction[187]=__GLeeLink_GL_SGIX_subsample; + __GLeeGLLoadFunction[188]=__GLeeLink_GL_SGIX_ycrcb_subsample; + __GLeeGLLoadFunction[189]=__GLeeLink_GL_SGIX_ycrcba; + __GLeeGLLoadFunction[190]=__GLeeLink_GL_SGI_depth_pass_instrument; + __GLeeGLLoadFunction[191]=__GLeeLink_GL_3DFX_texture_compression_FXT1; + __GLeeGLLoadFunction[192]=__GLeeLink_GL_3DFX_multisample; + __GLeeGLLoadFunction[193]=__GLeeLink_GL_3DFX_tbuffer; + __GLeeGLLoadFunction[194]=__GLeeLink_GL_EXT_multisample; + __GLeeGLLoadFunction[195]=__GLeeLink_GL_SGIX_vertex_preclip; + __GLeeGLLoadFunction[196]=__GLeeLink_GL_SGIX_convolution_accuracy; + __GLeeGLLoadFunction[197]=__GLeeLink_GL_SGIX_resample; + __GLeeGLLoadFunction[198]=__GLeeLink_GL_SGIS_point_line_texgen; + __GLeeGLLoadFunction[199]=__GLeeLink_GL_SGIS_texture_color_mask; + __GLeeGLLoadFunction[200]=__GLeeLink_GL_EXT_texture_env_dot3; + __GLeeGLLoadFunction[201]=__GLeeLink_GL_ATI_texture_mirror_once; + __GLeeGLLoadFunction[202]=__GLeeLink_GL_NV_fence; + __GLeeGLLoadFunction[203]=__GLeeLink_GL_IBM_texture_mirrored_repeat; + __GLeeGLLoadFunction[204]=__GLeeLink_GL_NV_evaluators; + __GLeeGLLoadFunction[205]=__GLeeLink_GL_NV_packed_depth_stencil; + __GLeeGLLoadFunction[206]=__GLeeLink_GL_NV_register_combiners2; + __GLeeGLLoadFunction[207]=__GLeeLink_GL_NV_texture_compression_vtc; + __GLeeGLLoadFunction[208]=__GLeeLink_GL_NV_texture_rectangle; + __GLeeGLLoadFunction[209]=__GLeeLink_GL_NV_texture_shader; + __GLeeGLLoadFunction[210]=__GLeeLink_GL_NV_texture_shader2; + __GLeeGLLoadFunction[211]=__GLeeLink_GL_NV_vertex_array_range2; + __GLeeGLLoadFunction[212]=__GLeeLink_GL_NV_vertex_program; + __GLeeGLLoadFunction[213]=__GLeeLink_GL_SGIX_texture_coordinate_clamp; + __GLeeGLLoadFunction[214]=__GLeeLink_GL_SGIX_scalebias_hint; + __GLeeGLLoadFunction[215]=__GLeeLink_GL_OML_interlace; + __GLeeGLLoadFunction[216]=__GLeeLink_GL_OML_subsample; + __GLeeGLLoadFunction[217]=__GLeeLink_GL_OML_resample; + __GLeeGLLoadFunction[218]=__GLeeLink_GL_NV_copy_depth_to_color; + __GLeeGLLoadFunction[219]=__GLeeLink_GL_ATI_envmap_bumpmap; + __GLeeGLLoadFunction[220]=__GLeeLink_GL_ATI_fragment_shader; + __GLeeGLLoadFunction[221]=__GLeeLink_GL_ATI_pn_triangles; + __GLeeGLLoadFunction[222]=__GLeeLink_GL_ATI_vertex_array_object; + __GLeeGLLoadFunction[223]=__GLeeLink_GL_EXT_vertex_shader; + __GLeeGLLoadFunction[224]=__GLeeLink_GL_ATI_vertex_streams; + __GLeeGLLoadFunction[225]=__GLeeLink_GL_ATI_element_array; + __GLeeGLLoadFunction[226]=__GLeeLink_GL_SUN_mesh_array; + __GLeeGLLoadFunction[227]=__GLeeLink_GL_SUN_slice_accum; + __GLeeGLLoadFunction[228]=__GLeeLink_GL_NV_multisample_filter_hint; + __GLeeGLLoadFunction[229]=__GLeeLink_GL_NV_depth_clamp; + __GLeeGLLoadFunction[230]=__GLeeLink_GL_NV_occlusion_query; + __GLeeGLLoadFunction[231]=__GLeeLink_GL_NV_point_sprite; + __GLeeGLLoadFunction[232]=__GLeeLink_GL_NV_texture_shader3; + __GLeeGLLoadFunction[233]=__GLeeLink_GL_NV_vertex_program1_1; + __GLeeGLLoadFunction[234]=__GLeeLink_GL_EXT_shadow_funcs; + __GLeeGLLoadFunction[235]=__GLeeLink_GL_EXT_stencil_two_side; + __GLeeGLLoadFunction[236]=__GLeeLink_GL_ATI_text_fragment_shader; + __GLeeGLLoadFunction[237]=__GLeeLink_GL_APPLE_client_storage; + __GLeeGLLoadFunction[238]=__GLeeLink_GL_APPLE_element_array; + __GLeeGLLoadFunction[239]=__GLeeLink_GL_APPLE_fence; + __GLeeGLLoadFunction[240]=__GLeeLink_GL_APPLE_vertex_array_object; + __GLeeGLLoadFunction[241]=__GLeeLink_GL_APPLE_vertex_array_range; + __GLeeGLLoadFunction[242]=__GLeeLink_GL_APPLE_ycbcr_422; + __GLeeGLLoadFunction[243]=__GLeeLink_GL_S3_s3tc; + __GLeeGLLoadFunction[244]=__GLeeLink_GL_ATI_draw_buffers; + __GLeeGLLoadFunction[245]=__GLeeLink_GL_ATI_pixel_format_float; + __GLeeGLLoadFunction[246]=__GLeeLink_GL_ATI_texture_env_combine3; + __GLeeGLLoadFunction[247]=__GLeeLink_GL_ATI_texture_float; + __GLeeGLLoadFunction[248]=__GLeeLink_GL_NV_float_buffer; + __GLeeGLLoadFunction[249]=__GLeeLink_GL_NV_fragment_program; + __GLeeGLLoadFunction[250]=__GLeeLink_GL_NV_half_float; + __GLeeGLLoadFunction[251]=__GLeeLink_GL_NV_pixel_data_range; + __GLeeGLLoadFunction[252]=__GLeeLink_GL_NV_primitive_restart; + __GLeeGLLoadFunction[253]=__GLeeLink_GL_NV_texture_expand_normal; + __GLeeGLLoadFunction[254]=__GLeeLink_GL_NV_vertex_program2; + __GLeeGLLoadFunction[255]=__GLeeLink_GL_ATI_map_object_buffer; + __GLeeGLLoadFunction[256]=__GLeeLink_GL_ATI_separate_stencil; + __GLeeGLLoadFunction[257]=__GLeeLink_GL_ATI_vertex_attrib_array_object; + __GLeeGLLoadFunction[258]=__GLeeLink_GL_OES_read_format; + __GLeeGLLoadFunction[259]=__GLeeLink_GL_EXT_depth_bounds_test; + __GLeeGLLoadFunction[260]=__GLeeLink_GL_EXT_texture_mirror_clamp; + __GLeeGLLoadFunction[261]=__GLeeLink_GL_EXT_blend_equation_separate; + __GLeeGLLoadFunction[262]=__GLeeLink_GL_MESA_pack_invert; + __GLeeGLLoadFunction[263]=__GLeeLink_GL_MESA_ycbcr_texture; + __GLeeGLLoadFunction[264]=__GLeeLink_GL_EXT_pixel_buffer_object; + __GLeeGLLoadFunction[265]=__GLeeLink_GL_NV_fragment_program_option; + __GLeeGLLoadFunction[266]=__GLeeLink_GL_NV_fragment_program2; + __GLeeGLLoadFunction[267]=__GLeeLink_GL_NV_vertex_program2_option; + __GLeeGLLoadFunction[268]=__GLeeLink_GL_NV_vertex_program3; + __GLeeGLLoadFunction[269]=__GLeeLink_GL_EXT_framebuffer_object; + __GLeeGLLoadFunction[270]=__GLeeLink_GL_GREMEDY_string_marker; + __GLeeGLLoadFunction[271]=__GLeeLink_GL_EXT_packed_depth_stencil; + __GLeeGLLoadFunction[272]=__GLeeLink_GL_EXT_stencil_clear_tag; + __GLeeGLLoadFunction[273]=__GLeeLink_GL_EXT_texture_sRGB; + __GLeeGLLoadFunction[274]=__GLeeLink_GL_EXT_framebuffer_blit; + __GLeeGLLoadFunction[275]=__GLeeLink_GL_EXT_framebuffer_multisample; + __GLeeGLLoadFunction[276]=__GLeeLink_GL_MESAX_texture_stack; + __GLeeGLLoadFunction[277]=__GLeeLink_GL_EXT_timer_query; + __GLeeGLLoadFunction[278]=__GLeeLink_GL_EXT_gpu_program_parameters; + __GLeeGLLoadFunction[279]=__GLeeLink_GL_APPLE_flush_buffer_range; + __GLeeGLLoadFunction[280]=__GLeeLink_GL_EXT_gpu_shader4; + __GLeeGLLoadFunction[281]=__GLeeLink_GL_EXT_draw_instanced; + __GLeeGLLoadFunction[282]=__GLeeLink_GL_EXT_packed_float; + __GLeeGLLoadFunction[283]=__GLeeLink_GL_EXT_texture_array; + __GLeeGLLoadFunction[284]=__GLeeLink_GL_EXT_texture_buffer_object; + __GLeeGLLoadFunction[285]=__GLeeLink_GL_EXT_texture_compression_latc; + __GLeeGLLoadFunction[286]=__GLeeLink_GL_EXT_texture_compression_rgtc; + __GLeeGLLoadFunction[287]=__GLeeLink_GL_EXT_texture_shared_exponent; + __GLeeGLLoadFunction[288]=__GLeeLink_GL_NV_depth_buffer_float; + __GLeeGLLoadFunction[289]=__GLeeLink_GL_NV_framebuffer_multisample_coverage; + __GLeeGLLoadFunction[290]=__GLeeLink_GL_EXT_framebuffer_sRGB; + __GLeeGLLoadFunction[291]=__GLeeLink_GL_NV_geometry_shader4; + __GLeeGLLoadFunction[292]=__GLeeLink_GL_NV_parameter_buffer_object; + __GLeeGLLoadFunction[293]=__GLeeLink_GL_EXT_draw_buffers2; + __GLeeGLLoadFunction[294]=__GLeeLink_GL_NV_transform_feedback; + __GLeeGLLoadFunction[295]=__GLeeLink_GL_EXT_bindable_uniform; + __GLeeGLLoadFunction[296]=__GLeeLink_GL_EXT_texture_integer; + __GLeeGLLoadFunction[297]=__GLeeLink_GL_GREMEDY_frame_terminator; + __GLeeGLLoadFunction[298]=__GLeeLink_GL_NV_conditional_render; + __GLeeGLLoadFunction[299]=__GLeeLink_GL_NV_present_video; + __GLeeGLLoadFunction[300]=__GLeeLink_GL_EXT_transform_feedback; + __GLeeGLLoadFunction[301]=__GLeeLink_GL_EXT_direct_state_access; + __GLeeGLLoadFunction[302]=__GLeeLink_GL_EXT_vertex_array_bgra; + __GLeeGLLoadFunction[303]=__GLeeLink_GL_EXT_texture_swizzle; + __GLeeGLLoadFunction[304]=__GLeeLink_GL_NV_explicit_multisample; + __GLeeGLLoadFunction[305]=__GLeeLink_GL_NV_transform_feedback2; + __GLeeGLLoadFunction[306]=__GLeeLink_GL_SGIX_texture_select; + __GLeeGLLoadFunction[307]=__GLeeLink_GL_INGR_blend_func_separate; + __GLeeGLLoadFunction[308]=__GLeeLink_GL_SGIX_depth_pass_instrument; + __GLeeGLLoadFunction[309]=__GLeeLink_GL_SGIX_igloo_interface; + __GLeeGLLoadFunction[310]=__GLeeLink_GL_EXT_fragment_lighting; + __GLeeGLLoadFunction[311]=__GLeeLink_GL_EXT_geometry_shader4; + __GLeeGLLoadFunction[312]=__GLeeLink_GL_EXT_scene_marker; + __GLeeGLLoadFunction[313]=__GLeeLink_GL_EXT_texture_compression_dxt1; + __GLeeGLLoadFunction[314]=__GLeeLink_GL_EXT_texture_env; + __GLeeGLLoadFunction[315]=__GLeeLink_GL_IBM_static_data; + __GLeeGLLoadFunction[316]=__GLeeLink_GL_NV_gpu_program4; + __GLeeGLLoadFunction[317]=__GLeeLink_GL_OES_byte_coordinates; + __GLeeGLLoadFunction[318]=__GLeeLink_GL_OES_compressed_paletted_texture; + __GLeeGLLoadFunction[319]=__GLeeLink_GL_OES_single_precision; + __GLeeGLLoadFunction[320]=__GLeeLink_GL_SGIX_pixel_texture_bits; + __GLeeGLLoadFunction[321]=__GLeeLink_GL_SGIX_texture_range; +} + +#ifdef WIN32 +GLuint __GLeeLink_WGL_ARB_buffer_region(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_ARB_buffer_region + if ((GLeeFuncPtr_wglCreateBufferRegionARB = (GLEEPFNWGLCREATEBUFFERREGIONARBPROC) __GLeeGetProcAddress("wglCreateBufferRegionARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDeleteBufferRegionARB = (GLEEPFNWGLDELETEBUFFERREGIONARBPROC) __GLeeGetProcAddress("wglDeleteBufferRegionARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSaveBufferRegionARB = (GLEEPFNWGLSAVEBUFFERREGIONARBPROC) __GLeeGetProcAddress("wglSaveBufferRegionARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglRestoreBufferRegionARB = (GLEEPFNWGLRESTOREBUFFERREGIONARBPROC) __GLeeGetProcAddress("wglRestoreBufferRegionARB"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_ARB_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_ARB_extensions_string(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_ARB_extensions_string + if ((GLeeFuncPtr_wglGetExtensionsStringARB = (GLEEPFNWGLGETEXTENSIONSSTRINGARBPROC) __GLeeGetProcAddress("wglGetExtensionsStringARB"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_ARB_pixel_format(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_ARB_pixel_format + if ((GLeeFuncPtr_wglGetPixelFormatAttribivARB = (GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC) __GLeeGetProcAddress("wglGetPixelFormatAttribivARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetPixelFormatAttribfvARB = (GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC) __GLeeGetProcAddress("wglGetPixelFormatAttribfvARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglChoosePixelFormatARB = (GLEEPFNWGLCHOOSEPIXELFORMATARBPROC) __GLeeGetProcAddress("wglChoosePixelFormatARB"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_ARB_make_current_read(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_ARB_make_current_read + if ((GLeeFuncPtr_wglMakeContextCurrentARB = (GLEEPFNWGLMAKECONTEXTCURRENTARBPROC) __GLeeGetProcAddress("wglMakeContextCurrentARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetCurrentReadDCARB = (GLEEPFNWGLGETCURRENTREADDCARBPROC) __GLeeGetProcAddress("wglGetCurrentReadDCARB"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_ARB_pbuffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_ARB_pbuffer + if ((GLeeFuncPtr_wglCreatePbufferARB = (GLEEPFNWGLCREATEPBUFFERARBPROC) __GLeeGetProcAddress("wglCreatePbufferARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetPbufferDCARB = (GLEEPFNWGLGETPBUFFERDCARBPROC) __GLeeGetProcAddress("wglGetPbufferDCARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglReleasePbufferDCARB = (GLEEPFNWGLRELEASEPBUFFERDCARBPROC) __GLeeGetProcAddress("wglReleasePbufferDCARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDestroyPbufferARB = (GLEEPFNWGLDESTROYPBUFFERARBPROC) __GLeeGetProcAddress("wglDestroyPbufferARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryPbufferARB = (GLEEPFNWGLQUERYPBUFFERARBPROC) __GLeeGetProcAddress("wglQueryPbufferARB"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_ARB_render_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_ARB_render_texture + if ((GLeeFuncPtr_wglBindTexImageARB = (GLEEPFNWGLBINDTEXIMAGEARBPROC) __GLeeGetProcAddress("wglBindTexImageARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglReleaseTexImageARB = (GLEEPFNWGLRELEASETEXIMAGEARBPROC) __GLeeGetProcAddress("wglReleaseTexImageARB"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSetPbufferAttribARB = (GLEEPFNWGLSETPBUFFERATTRIBARBPROC) __GLeeGetProcAddress("wglSetPbufferAttribARB"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_ARB_pixel_format_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_ARB_create_context(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_ARB_create_context + if ((GLeeFuncPtr_wglCreateContextAttribsARB = (GLEEPFNWGLCREATECONTEXTATTRIBSARBPROC) __GLeeGetProcAddress("wglCreateContextAttribsARB"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_EXT_make_current_read(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_EXT_make_current_read + if ((GLeeFuncPtr_wglMakeContextCurrentEXT = (GLEEPFNWGLMAKECONTEXTCURRENTEXTPROC) __GLeeGetProcAddress("wglMakeContextCurrentEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetCurrentReadDCEXT = (GLEEPFNWGLGETCURRENTREADDCEXTPROC) __GLeeGetProcAddress("wglGetCurrentReadDCEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_EXT_pixel_format(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_EXT_pixel_format + if ((GLeeFuncPtr_wglGetPixelFormatAttribivEXT = (GLEEPFNWGLGETPIXELFORMATATTRIBIVEXTPROC) __GLeeGetProcAddress("wglGetPixelFormatAttribivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetPixelFormatAttribfvEXT = (GLEEPFNWGLGETPIXELFORMATATTRIBFVEXTPROC) __GLeeGetProcAddress("wglGetPixelFormatAttribfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglChoosePixelFormatEXT = (GLEEPFNWGLCHOOSEPIXELFORMATEXTPROC) __GLeeGetProcAddress("wglChoosePixelFormatEXT"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_EXT_pbuffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_EXT_pbuffer + if ((GLeeFuncPtr_wglCreatePbufferEXT = (GLEEPFNWGLCREATEPBUFFEREXTPROC) __GLeeGetProcAddress("wglCreatePbufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetPbufferDCEXT = (GLEEPFNWGLGETPBUFFERDCEXTPROC) __GLeeGetProcAddress("wglGetPbufferDCEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglReleasePbufferDCEXT = (GLEEPFNWGLRELEASEPBUFFERDCEXTPROC) __GLeeGetProcAddress("wglReleasePbufferDCEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDestroyPbufferEXT = (GLEEPFNWGLDESTROYPBUFFEREXTPROC) __GLeeGetProcAddress("wglDestroyPbufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryPbufferEXT = (GLEEPFNWGLQUERYPBUFFEREXTPROC) __GLeeGetProcAddress("wglQueryPbufferEXT"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_EXT_depth_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_3DFX_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_EXT_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_I3D_digital_video_control(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_I3D_digital_video_control + if ((GLeeFuncPtr_wglGetDigitalVideoParametersI3D = (GLEEPFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) __GLeeGetProcAddress("wglGetDigitalVideoParametersI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSetDigitalVideoParametersI3D = (GLEEPFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) __GLeeGetProcAddress("wglSetDigitalVideoParametersI3D"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_I3D_gamma(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_I3D_gamma + if ((GLeeFuncPtr_wglGetGammaTableParametersI3D = (GLEEPFNWGLGETGAMMATABLEPARAMETERSI3DPROC) __GLeeGetProcAddress("wglGetGammaTableParametersI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSetGammaTableParametersI3D = (GLEEPFNWGLSETGAMMATABLEPARAMETERSI3DPROC) __GLeeGetProcAddress("wglSetGammaTableParametersI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetGammaTableI3D = (GLEEPFNWGLGETGAMMATABLEI3DPROC) __GLeeGetProcAddress("wglGetGammaTableI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSetGammaTableI3D = (GLEEPFNWGLSETGAMMATABLEI3DPROC) __GLeeGetProcAddress("wglSetGammaTableI3D"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_I3D_genlock(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_I3D_genlock + if ((GLeeFuncPtr_wglEnableGenlockI3D = (GLEEPFNWGLENABLEGENLOCKI3DPROC) __GLeeGetProcAddress("wglEnableGenlockI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDisableGenlockI3D = (GLEEPFNWGLDISABLEGENLOCKI3DPROC) __GLeeGetProcAddress("wglDisableGenlockI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglIsEnabledGenlockI3D = (GLEEPFNWGLISENABLEDGENLOCKI3DPROC) __GLeeGetProcAddress("wglIsEnabledGenlockI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGenlockSourceI3D = (GLEEPFNWGLGENLOCKSOURCEI3DPROC) __GLeeGetProcAddress("wglGenlockSourceI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetGenlockSourceI3D = (GLEEPFNWGLGETGENLOCKSOURCEI3DPROC) __GLeeGetProcAddress("wglGetGenlockSourceI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGenlockSourceEdgeI3D = (GLEEPFNWGLGENLOCKSOURCEEDGEI3DPROC) __GLeeGetProcAddress("wglGenlockSourceEdgeI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetGenlockSourceEdgeI3D = (GLEEPFNWGLGETGENLOCKSOURCEEDGEI3DPROC) __GLeeGetProcAddress("wglGetGenlockSourceEdgeI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGenlockSampleRateI3D = (GLEEPFNWGLGENLOCKSAMPLERATEI3DPROC) __GLeeGetProcAddress("wglGenlockSampleRateI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetGenlockSampleRateI3D = (GLEEPFNWGLGETGENLOCKSAMPLERATEI3DPROC) __GLeeGetProcAddress("wglGetGenlockSampleRateI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGenlockSourceDelayI3D = (GLEEPFNWGLGENLOCKSOURCEDELAYI3DPROC) __GLeeGetProcAddress("wglGenlockSourceDelayI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetGenlockSourceDelayI3D = (GLEEPFNWGLGETGENLOCKSOURCEDELAYI3DPROC) __GLeeGetProcAddress("wglGetGenlockSourceDelayI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryGenlockMaxSourceDelayI3D = (GLEEPFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) __GLeeGetProcAddress("wglQueryGenlockMaxSourceDelayI3D"))!=0) nLinked++; +#endif + if (nLinked==12) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_I3D_image_buffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_I3D_image_buffer + if ((GLeeFuncPtr_wglCreateImageBufferI3D = (GLEEPFNWGLCREATEIMAGEBUFFERI3DPROC) __GLeeGetProcAddress("wglCreateImageBufferI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDestroyImageBufferI3D = (GLEEPFNWGLDESTROYIMAGEBUFFERI3DPROC) __GLeeGetProcAddress("wglDestroyImageBufferI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglAssociateImageBufferEventsI3D = (GLEEPFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) __GLeeGetProcAddress("wglAssociateImageBufferEventsI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglReleaseImageBufferEventsI3D = (GLEEPFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) __GLeeGetProcAddress("wglReleaseImageBufferEventsI3D"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_I3D_swap_frame_lock(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_I3D_swap_frame_lock + if ((GLeeFuncPtr_wglEnableFrameLockI3D = (GLEEPFNWGLENABLEFRAMELOCKI3DPROC) __GLeeGetProcAddress("wglEnableFrameLockI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDisableFrameLockI3D = (GLEEPFNWGLDISABLEFRAMELOCKI3DPROC) __GLeeGetProcAddress("wglDisableFrameLockI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglIsEnabledFrameLockI3D = (GLEEPFNWGLISENABLEDFRAMELOCKI3DPROC) __GLeeGetProcAddress("wglIsEnabledFrameLockI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryFrameLockMasterI3D = (GLEEPFNWGLQUERYFRAMELOCKMASTERI3DPROC) __GLeeGetProcAddress("wglQueryFrameLockMasterI3D"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_NV_render_depth_texture(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_NV_render_texture_rectangle(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_ATI_pixel_format_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_NV_float_buffer(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_3DL_stereo_control(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_EXT_pixel_format_packed_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_EXT_framebuffer_sRGB(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_NV_present_video(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_NV_present_video + if ((GLeeFuncPtr_wglEnumerateVideoDevicesNV = (GLEEPFNWGLENUMERATEVIDEODEVICESNVPROC) __GLeeGetProcAddress("wglEnumerateVideoDevicesNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglBindVideoDeviceNV = (GLEEPFNWGLBINDVIDEODEVICENVPROC) __GLeeGetProcAddress("wglBindVideoDeviceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryCurrentContextNV = (GLEEPFNWGLQUERYCURRENTCONTEXTNVPROC) __GLeeGetProcAddress("wglQueryCurrentContextNV"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_NV_swap_group(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_NV_swap_group + if ((GLeeFuncPtr_wglJoinSwapGroupNV = (GLEEPFNWGLJOINSWAPGROUPNVPROC) __GLeeGetProcAddress("wglJoinSwapGroupNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglBindSwapBarrierNV = (GLEEPFNWGLBINDSWAPBARRIERNVPROC) __GLeeGetProcAddress("wglBindSwapBarrierNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQuerySwapGroupNV = (GLEEPFNWGLQUERYSWAPGROUPNVPROC) __GLeeGetProcAddress("wglQuerySwapGroupNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryMaxSwapGroupsNV = (GLEEPFNWGLQUERYMAXSWAPGROUPSNVPROC) __GLeeGetProcAddress("wglQueryMaxSwapGroupsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryFrameCountNV = (GLEEPFNWGLQUERYFRAMECOUNTNVPROC) __GLeeGetProcAddress("wglQueryFrameCountNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglResetFrameCountNV = (GLEEPFNWGLRESETFRAMECOUNTNVPROC) __GLeeGetProcAddress("wglResetFrameCountNV"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_NV_gpu_affinity(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_NV_gpu_affinity + if ((GLeeFuncPtr_wglEnumGpusNV = (GLEEPFNWGLENUMGPUSNVPROC) __GLeeGetProcAddress("wglEnumGpusNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglEnumGpuDevicesNV = (GLEEPFNWGLENUMGPUDEVICESNVPROC) __GLeeGetProcAddress("wglEnumGpuDevicesNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglCreateAffinityDCNV = (GLEEPFNWGLCREATEAFFINITYDCNVPROC) __GLeeGetProcAddress("wglCreateAffinityDCNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglEnumGpusFromAffinityDCNV = (GLEEPFNWGLENUMGPUSFROMAFFINITYDCNVPROC) __GLeeGetProcAddress("wglEnumGpusFromAffinityDCNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDeleteDCNV = (GLEEPFNWGLDELETEDCNVPROC) __GLeeGetProcAddress("wglDeleteDCNV"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_EXT_display_color_table(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_EXT_display_color_table + if ((GLeeFuncPtr_wglCreateDisplayColorTableEXT = (GLEEPFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) __GLeeGetProcAddress("wglCreateDisplayColorTableEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglLoadDisplayColorTableEXT = (GLEEPFNWGLLOADDISPLAYCOLORTABLEEXTPROC) __GLeeGetProcAddress("wglLoadDisplayColorTableEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglBindDisplayColorTableEXT = (GLEEPFNWGLBINDDISPLAYCOLORTABLEEXTPROC) __GLeeGetProcAddress("wglBindDisplayColorTableEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglDestroyDisplayColorTableEXT = (GLEEPFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) __GLeeGetProcAddress("wglDestroyDisplayColorTableEXT"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_EXT_extensions_string(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_EXT_extensions_string + if ((GLeeFuncPtr_wglGetExtensionsStringEXT = (GLEEPFNWGLGETEXTENSIONSSTRINGEXTPROC) __GLeeGetProcAddress("wglGetExtensionsStringEXT"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_EXT_swap_control(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_EXT_swap_control + if ((GLeeFuncPtr_wglSwapIntervalEXT = (GLEEPFNWGLSWAPINTERVALEXTPROC) __GLeeGetProcAddress("wglSwapIntervalEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetSwapIntervalEXT = (GLEEPFNWGLGETSWAPINTERVALEXTPROC) __GLeeGetProcAddress("wglGetSwapIntervalEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_NV_vertex_array_range(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_NV_vertex_array_range + if ((GLeeFuncPtr_wglAllocateMemoryNV = (GLEEPFNWGLALLOCATEMEMORYNVPROC) __GLeeGetProcAddress("wglAllocateMemoryNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglFreeMemoryNV = (GLEEPFNWGLFREEMEMORYNVPROC) __GLeeGetProcAddress("wglFreeMemoryNV"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_OML_sync_control(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_OML_sync_control + if ((GLeeFuncPtr_wglGetSyncValuesOML = (GLEEPFNWGLGETSYNCVALUESOMLPROC) __GLeeGetProcAddress("wglGetSyncValuesOML"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetMscRateOML = (GLEEPFNWGLGETMSCRATEOMLPROC) __GLeeGetProcAddress("wglGetMscRateOML"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSwapBuffersMscOML = (GLEEPFNWGLSWAPBUFFERSMSCOMLPROC) __GLeeGetProcAddress("wglSwapBuffersMscOML"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSwapLayerBuffersMscOML = (GLEEPFNWGLSWAPLAYERBUFFERSMSCOMLPROC) __GLeeGetProcAddress("wglSwapLayerBuffersMscOML"))!=0) nLinked++; + if ((GLeeFuncPtr_wglWaitForMscOML = (GLEEPFNWGLWAITFORMSCOMLPROC) __GLeeGetProcAddress("wglWaitForMscOML"))!=0) nLinked++; + if ((GLeeFuncPtr_wglWaitForSbcOML = (GLEEPFNWGLWAITFORSBCOMLPROC) __GLeeGetProcAddress("wglWaitForSbcOML"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_I3D_swap_frame_usage(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_I3D_swap_frame_usage + if ((GLeeFuncPtr_wglGetFrameUsageI3D = (GLEEPFNWGLGETFRAMEUSAGEI3DPROC) __GLeeGetProcAddress("wglGetFrameUsageI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglBeginFrameTrackingI3D = (GLEEPFNWGLBEGINFRAMETRACKINGI3DPROC) __GLeeGetProcAddress("wglBeginFrameTrackingI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglEndFrameTrackingI3D = (GLEEPFNWGLENDFRAMETRACKINGI3DPROC) __GLeeGetProcAddress("wglEndFrameTrackingI3D"))!=0) nLinked++; + if ((GLeeFuncPtr_wglQueryFrameTrackingI3D = (GLEEPFNWGLQUERYFRAMETRACKINGI3DPROC) __GLeeGetProcAddress("wglQueryFrameTrackingI3D"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_WGL_NV_video_output(void) +{ + GLint nLinked=0; +#ifdef __GLEE_WGL_NV_video_output + if ((GLeeFuncPtr_wglGetVideoDeviceNV = (GLEEPFNWGLGETVIDEODEVICENVPROC) __GLeeGetProcAddress("wglGetVideoDeviceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglReleaseVideoDeviceNV = (GLEEPFNWGLRELEASEVIDEODEVICENVPROC) __GLeeGetProcAddress("wglReleaseVideoDeviceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglBindVideoImageNV = (GLEEPFNWGLBINDVIDEOIMAGENVPROC) __GLeeGetProcAddress("wglBindVideoImageNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglReleaseVideoImageNV = (GLEEPFNWGLRELEASEVIDEOIMAGENVPROC) __GLeeGetProcAddress("wglReleaseVideoImageNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglSendPbufferToVideoNV = (GLEEPFNWGLSENDPBUFFERTOVIDEONVPROC) __GLeeGetProcAddress("wglSendPbufferToVideoNV"))!=0) nLinked++; + if ((GLeeFuncPtr_wglGetVideoInfoNV = (GLEEPFNWGLGETVIDEOINFONVPROC) __GLeeGetProcAddress("wglGetVideoInfoNV"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLEE_LINK_FUNCTION __GLeeWGLLoadFunction[37]; + +void initWGLLoadFunctions(void) +{ + __GLeeWGLLoadFunction[0]=__GLeeLink_WGL_ARB_buffer_region; + __GLeeWGLLoadFunction[1]=__GLeeLink_WGL_ARB_multisample; + __GLeeWGLLoadFunction[2]=__GLeeLink_WGL_ARB_extensions_string; + __GLeeWGLLoadFunction[3]=__GLeeLink_WGL_ARB_pixel_format; + __GLeeWGLLoadFunction[4]=__GLeeLink_WGL_ARB_make_current_read; + __GLeeWGLLoadFunction[5]=__GLeeLink_WGL_ARB_pbuffer; + __GLeeWGLLoadFunction[6]=__GLeeLink_WGL_ARB_render_texture; + __GLeeWGLLoadFunction[7]=__GLeeLink_WGL_ARB_pixel_format_float; + __GLeeWGLLoadFunction[8]=__GLeeLink_WGL_ARB_create_context; + __GLeeWGLLoadFunction[9]=__GLeeLink_WGL_EXT_make_current_read; + __GLeeWGLLoadFunction[10]=__GLeeLink_WGL_EXT_pixel_format; + __GLeeWGLLoadFunction[11]=__GLeeLink_WGL_EXT_pbuffer; + __GLeeWGLLoadFunction[12]=__GLeeLink_WGL_EXT_depth_float; + __GLeeWGLLoadFunction[13]=__GLeeLink_WGL_3DFX_multisample; + __GLeeWGLLoadFunction[14]=__GLeeLink_WGL_EXT_multisample; + __GLeeWGLLoadFunction[15]=__GLeeLink_WGL_I3D_digital_video_control; + __GLeeWGLLoadFunction[16]=__GLeeLink_WGL_I3D_gamma; + __GLeeWGLLoadFunction[17]=__GLeeLink_WGL_I3D_genlock; + __GLeeWGLLoadFunction[18]=__GLeeLink_WGL_I3D_image_buffer; + __GLeeWGLLoadFunction[19]=__GLeeLink_WGL_I3D_swap_frame_lock; + __GLeeWGLLoadFunction[20]=__GLeeLink_WGL_NV_render_depth_texture; + __GLeeWGLLoadFunction[21]=__GLeeLink_WGL_NV_render_texture_rectangle; + __GLeeWGLLoadFunction[22]=__GLeeLink_WGL_ATI_pixel_format_float; + __GLeeWGLLoadFunction[23]=__GLeeLink_WGL_NV_float_buffer; + __GLeeWGLLoadFunction[24]=__GLeeLink_WGL_3DL_stereo_control; + __GLeeWGLLoadFunction[25]=__GLeeLink_WGL_EXT_pixel_format_packed_float; + __GLeeWGLLoadFunction[26]=__GLeeLink_WGL_EXT_framebuffer_sRGB; + __GLeeWGLLoadFunction[27]=__GLeeLink_WGL_NV_present_video; + __GLeeWGLLoadFunction[28]=__GLeeLink_WGL_NV_swap_group; + __GLeeWGLLoadFunction[29]=__GLeeLink_WGL_NV_gpu_affinity; + __GLeeWGLLoadFunction[30]=__GLeeLink_WGL_EXT_display_color_table; + __GLeeWGLLoadFunction[31]=__GLeeLink_WGL_EXT_extensions_string; + __GLeeWGLLoadFunction[32]=__GLeeLink_WGL_EXT_swap_control; + __GLeeWGLLoadFunction[33]=__GLeeLink_WGL_NV_vertex_array_range; + __GLeeWGLLoadFunction[34]=__GLeeLink_WGL_OML_sync_control; + __GLeeWGLLoadFunction[35]=__GLeeLink_WGL_I3D_swap_frame_usage; + __GLeeWGLLoadFunction[36]=__GLeeLink_WGL_NV_video_output; +} + +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else /* Linux */ +GLuint __GLeeLink_GLX_VERSION_1_3(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_VERSION_1_3 + if ((GLeeFuncPtr_glXGetFBConfigs = (GLEEPFNGLXGETFBCONFIGSPROC) __GLeeGetProcAddress("glXGetFBConfigs"))!=0) nLinked++; + if ((GLeeFuncPtr_glXChooseFBConfig = (GLEEPFNGLXCHOOSEFBCONFIGPROC) __GLeeGetProcAddress("glXChooseFBConfig"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetFBConfigAttrib = (GLEEPFNGLXGETFBCONFIGATTRIBPROC) __GLeeGetProcAddress("glXGetFBConfigAttrib"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetVisualFromFBConfig = (GLEEPFNGLXGETVISUALFROMFBCONFIGPROC) __GLeeGetProcAddress("glXGetVisualFromFBConfig"))!=0) nLinked++; + if ((GLeeFuncPtr_glXCreateWindow = (GLEEPFNGLXCREATEWINDOWPROC) __GLeeGetProcAddress("glXCreateWindow"))!=0) nLinked++; + if ((GLeeFuncPtr_glXDestroyWindow = (GLEEPFNGLXDESTROYWINDOWPROC) __GLeeGetProcAddress("glXDestroyWindow"))!=0) nLinked++; + if ((GLeeFuncPtr_glXCreatePixmap = (GLEEPFNGLXCREATEPIXMAPPROC) __GLeeGetProcAddress("glXCreatePixmap"))!=0) nLinked++; + if ((GLeeFuncPtr_glXDestroyPixmap = (GLEEPFNGLXDESTROYPIXMAPPROC) __GLeeGetProcAddress("glXDestroyPixmap"))!=0) nLinked++; + if ((GLeeFuncPtr_glXCreatePbuffer = (GLEEPFNGLXCREATEPBUFFERPROC) __GLeeGetProcAddress("glXCreatePbuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glXDestroyPbuffer = (GLEEPFNGLXDESTROYPBUFFERPROC) __GLeeGetProcAddress("glXDestroyPbuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryDrawable = (GLEEPFNGLXQUERYDRAWABLEPROC) __GLeeGetProcAddress("glXQueryDrawable"))!=0) nLinked++; + if ((GLeeFuncPtr_glXCreateNewContext = (GLEEPFNGLXCREATENEWCONTEXTPROC) __GLeeGetProcAddress("glXCreateNewContext"))!=0) nLinked++; + if ((GLeeFuncPtr_glXMakeContextCurrent = (GLEEPFNGLXMAKECONTEXTCURRENTPROC) __GLeeGetProcAddress("glXMakeContextCurrent"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetCurrentReadDrawable = (GLEEPFNGLXGETCURRENTREADDRAWABLEPROC) __GLeeGetProcAddress("glXGetCurrentReadDrawable"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetCurrentDisplay = (GLEEPFNGLXGETCURRENTDISPLAYPROC) __GLeeGetProcAddress("glXGetCurrentDisplay"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryContext = (GLEEPFNGLXQUERYCONTEXTPROC) __GLeeGetProcAddress("glXQueryContext"))!=0) nLinked++; + if ((GLeeFuncPtr_glXSelectEvent = (GLEEPFNGLXSELECTEVENTPROC) __GLeeGetProcAddress("glXSelectEvent"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetSelectedEvent = (GLEEPFNGLXGETSELECTEDEVENTPROC) __GLeeGetProcAddress("glXGetSelectedEvent"))!=0) nLinked++; +#endif + if (nLinked==18) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_VERSION_1_4(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_VERSION_1_4 + if ((GLeeFuncPtr_glXGetProcAddress = (GLEEPFNGLXGETPROCADDRESSPROC) __GLeeGetProcAddress("glXGetProcAddress"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_ARB_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_ARB_fbconfig_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_ARB_create_context(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_ARB_create_context + if ((GLeeFuncPtr_glXCreateContextAttribsARB = (GLEEPFNGLXCREATECONTEXTATTRIBSARBPROC) __GLeeGetProcAddress("glXCreateContextAttribsARB"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIS_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_EXT_visual_info(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_SGI_swap_control(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGI_swap_control + if ((GLeeFuncPtr_glXSwapIntervalSGI = (GLEEPFNGLXSWAPINTERVALSGIPROC) __GLeeGetProcAddress("glXSwapIntervalSGI"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGI_video_sync(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGI_video_sync + if ((GLeeFuncPtr_glXGetVideoSyncSGI = (GLEEPFNGLXGETVIDEOSYNCSGIPROC) __GLeeGetProcAddress("glXGetVideoSyncSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glXWaitVideoSyncSGI = (GLEEPFNGLXWAITVIDEOSYNCSGIPROC) __GLeeGetProcAddress("glXWaitVideoSyncSGI"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGI_make_current_read(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGI_make_current_read + if ((GLeeFuncPtr_glXMakeCurrentReadSGI = (GLEEPFNGLXMAKECURRENTREADSGIPROC) __GLeeGetProcAddress("glXMakeCurrentReadSGI"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetCurrentReadDrawableSGI = (GLEEPFNGLXGETCURRENTREADDRAWABLESGIPROC) __GLeeGetProcAddress("glXGetCurrentReadDrawableSGI"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_EXT_visual_rating(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_EXT_import_context(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_EXT_import_context + if ((GLeeFuncPtr_glXGetCurrentDisplayEXT = (GLEEPFNGLXGETCURRENTDISPLAYEXTPROC) __GLeeGetProcAddress("glXGetCurrentDisplayEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryContextInfoEXT = (GLEEPFNGLXQUERYCONTEXTINFOEXTPROC) __GLeeGetProcAddress("glXQueryContextInfoEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetContextIDEXT = (GLEEPFNGLXGETCONTEXTIDEXTPROC) __GLeeGetProcAddress("glXGetContextIDEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glXImportContextEXT = (GLEEPFNGLXIMPORTCONTEXTEXTPROC) __GLeeGetProcAddress("glXImportContextEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glXFreeContextEXT = (GLEEPFNGLXFREECONTEXTEXTPROC) __GLeeGetProcAddress("glXFreeContextEXT"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIX_fbconfig(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGIX_fbconfig + if ((GLeeFuncPtr_glXGetFBConfigAttribSGIX = (GLEEPFNGLXGETFBCONFIGATTRIBSGIXPROC) __GLeeGetProcAddress("glXGetFBConfigAttribSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXChooseFBConfigSGIX = (GLEEPFNGLXCHOOSEFBCONFIGSGIXPROC) __GLeeGetProcAddress("glXChooseFBConfigSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXCreateGLXPixmapWithConfigSGIX = (GLEEPFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) __GLeeGetProcAddress("glXCreateGLXPixmapWithConfigSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXCreateContextWithConfigSGIX = (GLEEPFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) __GLeeGetProcAddress("glXCreateContextWithConfigSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetVisualFromFBConfigSGIX = (GLEEPFNGLXGETVISUALFROMFBCONFIGSGIXPROC) __GLeeGetProcAddress("glXGetVisualFromFBConfigSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetFBConfigFromVisualSGIX = (GLEEPFNGLXGETFBCONFIGFROMVISUALSGIXPROC) __GLeeGetProcAddress("glXGetFBConfigFromVisualSGIX"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIX_pbuffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGIX_pbuffer + if ((GLeeFuncPtr_glXCreateGLXPbufferSGIX = (GLEEPFNGLXCREATEGLXPBUFFERSGIXPROC) __GLeeGetProcAddress("glXCreateGLXPbufferSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXDestroyGLXPbufferSGIX = (GLEEPFNGLXDESTROYGLXPBUFFERSGIXPROC) __GLeeGetProcAddress("glXDestroyGLXPbufferSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryGLXPbufferSGIX = (GLEEPFNGLXQUERYGLXPBUFFERSGIXPROC) __GLeeGetProcAddress("glXQueryGLXPbufferSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXSelectEventSGIX = (GLEEPFNGLXSELECTEVENTSGIXPROC) __GLeeGetProcAddress("glXSelectEventSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetSelectedEventSGIX = (GLEEPFNGLXGETSELECTEDEVENTSGIXPROC) __GLeeGetProcAddress("glXGetSelectedEventSGIX"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGI_cushion(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGI_cushion + if ((GLeeFuncPtr_glXCushionSGI = (GLEEPFNGLXCUSHIONSGIPROC) __GLeeGetProcAddress("glXCushionSGI"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIX_video_resize(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGIX_video_resize + if ((GLeeFuncPtr_glXBindChannelToWindowSGIX = (GLEEPFNGLXBINDCHANNELTOWINDOWSGIXPROC) __GLeeGetProcAddress("glXBindChannelToWindowSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXChannelRectSGIX = (GLEEPFNGLXCHANNELRECTSGIXPROC) __GLeeGetProcAddress("glXChannelRectSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryChannelRectSGIX = (GLEEPFNGLXQUERYCHANNELRECTSGIXPROC) __GLeeGetProcAddress("glXQueryChannelRectSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryChannelDeltasSGIX = (GLEEPFNGLXQUERYCHANNELDELTASSGIXPROC) __GLeeGetProcAddress("glXQueryChannelDeltasSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXChannelRectSyncSGIX = (GLEEPFNGLXCHANNELRECTSYNCSGIXPROC) __GLeeGetProcAddress("glXChannelRectSyncSGIX"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIX_swap_group(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGIX_swap_group + if ((GLeeFuncPtr_glXJoinSwapGroupSGIX = (GLEEPFNGLXJOINSWAPGROUPSGIXPROC) __GLeeGetProcAddress("glXJoinSwapGroupSGIX"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIX_swap_barrier(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGIX_swap_barrier + if ((GLeeFuncPtr_glXBindSwapBarrierSGIX = (GLEEPFNGLXBINDSWAPBARRIERSGIXPROC) __GLeeGetProcAddress("glXBindSwapBarrierSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryMaxSwapBarriersSGIX = (GLEEPFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) __GLeeGetProcAddress("glXQueryMaxSwapBarriersSGIX"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIS_blended_overlay(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_SGIS_shared_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_SUN_get_transparent_index(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SUN_get_transparent_index + if ((GLeeFuncPtr_glXGetTransparentIndexSUN = (GLEEPFNGLXGETTRANSPARENTINDEXSUNPROC) __GLeeGetProcAddress("glXGetTransparentIndexSUN"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_3DFX_multisample(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_MESA_copy_sub_buffer(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_MESA_copy_sub_buffer + if ((GLeeFuncPtr_glXCopySubBufferMESA = (GLEEPFNGLXCOPYSUBBUFFERMESAPROC) __GLeeGetProcAddress("glXCopySubBufferMESA"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_MESA_pixmap_colormap(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_MESA_pixmap_colormap + if ((GLeeFuncPtr_glXCreateGLXPixmapMESA = (GLEEPFNGLXCREATEGLXPIXMAPMESAPROC) __GLeeGetProcAddress("glXCreateGLXPixmapMESA"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_MESA_release_buffers(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_MESA_release_buffers + if ((GLeeFuncPtr_glXReleaseBuffersMESA = (GLEEPFNGLXRELEASEBUFFERSMESAPROC) __GLeeGetProcAddress("glXReleaseBuffersMESA"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_MESA_set_3dfx_mode(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_MESA_set_3dfx_mode + if ((GLeeFuncPtr_glXSet3DfxModeMESA = (GLEEPFNGLXSET3DFXMODEMESAPROC) __GLeeGetProcAddress("glXSet3DfxModeMESA"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_SGIX_visual_select_group(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_OML_swap_method(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_OML_sync_control(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_OML_sync_control + if ((GLeeFuncPtr_glXGetSyncValuesOML = (GLEEPFNGLXGETSYNCVALUESOMLPROC) __GLeeGetProcAddress("glXGetSyncValuesOML"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetMscRateOML = (GLEEPFNGLXGETMSCRATEOMLPROC) __GLeeGetProcAddress("glXGetMscRateOML"))!=0) nLinked++; + if ((GLeeFuncPtr_glXSwapBuffersMscOML = (GLEEPFNGLXSWAPBUFFERSMSCOMLPROC) __GLeeGetProcAddress("glXSwapBuffersMscOML"))!=0) nLinked++; + if ((GLeeFuncPtr_glXWaitForMscOML = (GLEEPFNGLXWAITFORMSCOMLPROC) __GLeeGetProcAddress("glXWaitForMscOML"))!=0) nLinked++; + if ((GLeeFuncPtr_glXWaitForSbcOML = (GLEEPFNGLXWAITFORSBCOMLPROC) __GLeeGetProcAddress("glXWaitForSbcOML"))!=0) nLinked++; +#endif + if (nLinked==5) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_NV_float_buffer(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_SGIX_hyperpipe(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_SGIX_hyperpipe + if ((GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX = (GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC) __GLeeGetProcAddress("glXQueryHyperpipeNetworkSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXHyperpipeConfigSGIX = (GLEEPFNGLXHYPERPIPECONFIGSGIXPROC) __GLeeGetProcAddress("glXHyperpipeConfigSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryHyperpipeConfigSGIX = (GLEEPFNGLXQUERYHYPERPIPECONFIGSGIXPROC) __GLeeGetProcAddress("glXQueryHyperpipeConfigSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXDestroyHyperpipeConfigSGIX = (GLEEPFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) __GLeeGetProcAddress("glXDestroyHyperpipeConfigSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXBindHyperpipeSGIX = (GLEEPFNGLXBINDHYPERPIPESGIXPROC) __GLeeGetProcAddress("glXBindHyperpipeSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryHyperpipeBestAttribSGIX = (GLEEPFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) __GLeeGetProcAddress("glXQueryHyperpipeBestAttribSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXHyperpipeAttribSGIX = (GLEEPFNGLXHYPERPIPEATTRIBSGIXPROC) __GLeeGetProcAddress("glXHyperpipeAttribSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryHyperpipeAttribSGIX = (GLEEPFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) __GLeeGetProcAddress("glXQueryHyperpipeAttribSGIX"))!=0) nLinked++; +#endif + if (nLinked==8) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_MESA_agp_offset(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_MESA_agp_offset + if ((GLeeFuncPtr_glXGetAGPOffsetMESA = (GLEEPFNGLXGETAGPOFFSETMESAPROC) __GLeeGetProcAddress("glXGetAGPOffsetMESA"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_EXT_fbconfig_packed_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_EXT_framebuffer_sRGB(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_EXT_texture_from_pixmap(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_EXT_texture_from_pixmap + if ((GLeeFuncPtr_glXBindTexImageEXT = (GLEEPFNGLXBINDTEXIMAGEEXTPROC) __GLeeGetProcAddress("glXBindTexImageEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glXReleaseTexImageEXT = (GLEEPFNGLXRELEASETEXIMAGEEXTPROC) __GLeeGetProcAddress("glXReleaseTexImageEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GLX_NV_present_video(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_NV_video_out(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_NV_swap_group(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_EXT_scene_marker(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_NV_video_output(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GLX_NV_video_output + if ((GLeeFuncPtr_glXGetVideoDeviceNV = (GLEEPFNGLXGETVIDEODEVICENVPROC) __GLeeGetProcAddress("glXGetVideoDeviceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glXReleaseVideoDeviceNV = (GLEEPFNGLXRELEASEVIDEODEVICENVPROC) __GLeeGetProcAddress("glXReleaseVideoDeviceNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glXBindVideoImageNV = (GLEEPFNGLXBINDVIDEOIMAGENVPROC) __GLeeGetProcAddress("glXBindVideoImageNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glXReleaseVideoImageNV = (GLEEPFNGLXRELEASEVIDEOIMAGENVPROC) __GLeeGetProcAddress("glXReleaseVideoImageNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glXSendPbufferToVideoNV = (GLEEPFNGLXSENDPBUFFERTOVIDEONVPROC) __GLeeGetProcAddress("glXSendPbufferToVideoNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glXGetVideoInfoNV = (GLEEPFNGLXGETVIDEOINFONVPROC) __GLeeGetProcAddress("glXGetVideoInfoNV"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLEE_LINK_FUNCTION __GLeeGLXLoadFunction[40]; + +void initGLXLoadFunctions(void) +{ + __GLeeGLXLoadFunction[0]=__GLeeLink_GLX_VERSION_1_3; + __GLeeGLXLoadFunction[1]=__GLeeLink_GLX_VERSION_1_4; + __GLeeGLXLoadFunction[2]=__GLeeLink_GLX_ARB_multisample; + __GLeeGLXLoadFunction[3]=__GLeeLink_GLX_ARB_fbconfig_float; + __GLeeGLXLoadFunction[4]=__GLeeLink_GLX_ARB_create_context; + __GLeeGLXLoadFunction[5]=__GLeeLink_GLX_SGIS_multisample; + __GLeeGLXLoadFunction[6]=__GLeeLink_GLX_EXT_visual_info; + __GLeeGLXLoadFunction[7]=__GLeeLink_GLX_SGI_swap_control; + __GLeeGLXLoadFunction[8]=__GLeeLink_GLX_SGI_video_sync; + __GLeeGLXLoadFunction[9]=__GLeeLink_GLX_SGI_make_current_read; + __GLeeGLXLoadFunction[10]=__GLeeLink_GLX_EXT_visual_rating; + __GLeeGLXLoadFunction[11]=__GLeeLink_GLX_EXT_import_context; + __GLeeGLXLoadFunction[12]=__GLeeLink_GLX_SGIX_fbconfig; + __GLeeGLXLoadFunction[13]=__GLeeLink_GLX_SGIX_pbuffer; + __GLeeGLXLoadFunction[14]=__GLeeLink_GLX_SGI_cushion; + __GLeeGLXLoadFunction[15]=__GLeeLink_GLX_SGIX_video_resize; + __GLeeGLXLoadFunction[16]=__GLeeLink_GLX_SGIX_swap_group; + __GLeeGLXLoadFunction[17]=__GLeeLink_GLX_SGIX_swap_barrier; + __GLeeGLXLoadFunction[18]=__GLeeLink_GLX_SGIS_blended_overlay; + __GLeeGLXLoadFunction[19]=__GLeeLink_GLX_SGIS_shared_multisample; + __GLeeGLXLoadFunction[20]=__GLeeLink_GLX_SUN_get_transparent_index; + __GLeeGLXLoadFunction[21]=__GLeeLink_GLX_3DFX_multisample; + __GLeeGLXLoadFunction[22]=__GLeeLink_GLX_MESA_copy_sub_buffer; + __GLeeGLXLoadFunction[23]=__GLeeLink_GLX_MESA_pixmap_colormap; + __GLeeGLXLoadFunction[24]=__GLeeLink_GLX_MESA_release_buffers; + __GLeeGLXLoadFunction[25]=__GLeeLink_GLX_MESA_set_3dfx_mode; + __GLeeGLXLoadFunction[26]=__GLeeLink_GLX_SGIX_visual_select_group; + __GLeeGLXLoadFunction[27]=__GLeeLink_GLX_OML_swap_method; + __GLeeGLXLoadFunction[28]=__GLeeLink_GLX_OML_sync_control; + __GLeeGLXLoadFunction[29]=__GLeeLink_GLX_NV_float_buffer; + __GLeeGLXLoadFunction[30]=__GLeeLink_GLX_SGIX_hyperpipe; + __GLeeGLXLoadFunction[31]=__GLeeLink_GLX_MESA_agp_offset; + __GLeeGLXLoadFunction[32]=__GLeeLink_GLX_EXT_fbconfig_packed_float; + __GLeeGLXLoadFunction[33]=__GLeeLink_GLX_EXT_framebuffer_sRGB; + __GLeeGLXLoadFunction[34]=__GLeeLink_GLX_EXT_texture_from_pixmap; + __GLeeGLXLoadFunction[35]=__GLeeLink_GLX_NV_present_video; + __GLeeGLXLoadFunction[36]=__GLeeLink_GLX_NV_video_out; + __GLeeGLXLoadFunction[37]=__GLeeLink_GLX_NV_swap_group; + __GLeeGLXLoadFunction[38]=__GLeeLink_GLX_EXT_scene_marker; + __GLeeGLXLoadFunction[39]=__GLeeLink_GLX_NV_video_output; +} + +#endif /* end Linux */ + + +/***************************************************************** + * GLee internal types + *****************************************************************/ +typedef struct +{ + char ** names; + int * lengths; + int numNames; +}ExtensionList; + + +/***************************************************************** + * GLee internal variables + *****************************************************************/ +char GLeeErrorString[256]=""; + + +/***************************************************************** + * GLee internal functions + *****************************************************************/ + +void __GLeeExtList_init(ExtensionList *extList) +{ + extList->names=0; + extList->lengths=0; + extList->numNames=0; +} + +void __GLeeExtList_clean(ExtensionList *extList) +{ + int a; + for (a=0;anumNames;a++) + { + if (extList->names[a]!=0) free((void *)extList->names[a]); + } + if (extList->names!=0) free((void *)extList->names); + if (extList->lengths!=0) free((void *)extList->lengths); + extList->names=0; + extList->lengths=0; + extList->numNames=0; +} + +void __GLeeExtList_add(ExtensionList *extList, const char * extName) +{ + int length=strlen(extName)+1; + int i=extList->numNames; + int n=i+1; + if (i==0) + { + extList->lengths=(int *)malloc(sizeof(int)); + extList->names=(char **)malloc(sizeof(char *)); + }else + { + extList->lengths=(int *)realloc((void *)extList->lengths, n*sizeof(int)); + extList->names=(char **)realloc((void *)extList->names, n*sizeof(char *)); + } + extList->names[i]=(char *)malloc(length*sizeof(char)); + strcpy(extList->names[i],extName); + extList->lengths[i]=length; + extList->numNames++; +} + +const char *__GLeeGetExtStrPlat( void ) +{ +#ifdef WIN32 + if (!_GLEE_WGL_ARB_extensions_string) + wglGetExtensionsStringARB = (GLEEPFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB"); + + if (wglGetExtensionsStringARB) + return (const char *)wglGetExtensionsStringARB(wglGetCurrentDC()); +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else + Display *dpy=glXGetCurrentDisplay(); + if(dpy) + { + int dpynr=DefaultScreen(dpy); + return (const char*)glXQueryExtensionsString(dpy,dpynr); + } +#endif + return 0; +} + +void __GLeeWriteError(const char * errorStr) +{ + int a=0; + for (a=0;a<256;a++) + { + GLeeErrorString[a]=errorStr[a]; + } + GLeeErrorString[255]='\0'; +} + +int __GLeeGetVersionNumber(char *versionStr) +{ + int major=(int)versionStr[0]-(int)'0'; + int minor=(int)versionStr[2]-(int)'0'; + return major<<8 | minor; +} + +GLboolean __GLeeGetExtensions(ExtensionList* extList) +{ + const char * platExtStr; + const char * glExtStr; + char * extStr; + char emptyString[1] = ""; + char extensionName[1024]; + int a,b; + int totalExtStrLen; + int platExtStrLen; + int addASpace; + + /* read the platform specific extension string */ + platExtStr=__GLeeGetExtStrPlat(); + if (!platExtStr) platExtStr=emptyString; + + glExtStr=(const char *)glGetString(GL_EXTENSIONS); + if (glExtStr==0) + { + __GLeeWriteError("glGetString(GL_EXTENSIONS) failed."); + return GL_FALSE; + } + + /* allocate the extension string */ + platExtStrLen = strlen(platExtStr); + totalExtStrLen = platExtStrLen + strlen(glExtStr); + extStr=(char *)malloc( (totalExtStrLen+2) * sizeof(char) ); /* we add 2 to allow for an extra space and a null terminator */ + + /* If the last character of platExtStr is not a space, we need to add one when we concatenate the extension strings*/ + addASpace = 0; + if ( platExtStrLen > 2 ) + { + if ( platExtStr[ platExtStrLen-1 ] != ' ') + { + addASpace = 1; + } + } + + /* concatenate the two extension strings */ + if ( addASpace ) + { + sprintf(extStr,"%s %s",platExtStr,glExtStr); + } + else + { + sprintf(extStr,"%s%s",platExtStr,glExtStr); + } + + /* extract the extensions */ + for ( a=0;anumNames; + int a; + for (a=0;anames[a],name)==0) + return GL_TRUE; + } + return GL_FALSE; +} + +GLEE_EXTERN GLint __GLeeGetExtensionNumber(const char *extensionName, int type) +{ + int a; + switch (type) + { + case 0: + for (a=0;a<__GLeeGLNumExtensions;a++) + if (strcmp(extensionName,__GLeeGLExtensionNames[a])==0) return a; + return -1; +#ifdef WIN32 + case 1: + for (a=0;a<__GLeeWGLNumExtensions;a++) + if (strcmp(extensionName,__GLeeWGLExtensionNames[a])==0) return a; + return -1; +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else + case 2: + for (a=0;a<__GLeeGLXNumExtensions;a++) + if (strcmp(extensionName,__GLeeGLXExtensionNames[a])==0) return a; + return -1; +#endif + } + return -1; +} + +/***************************************************************** + * GLee external functions + *****************************************************************/ + +#ifdef WIN32 +GLEE_EXTERN const char * GLeeGetExtStrWGL( void ) +{ + return __GLeeGetExtStrPlat(); +} +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else +GLEE_EXTERN const char * GLeeGetExtStrGLX( void ) +{ + return __GLeeGetExtStrPlat(); +} +#endif + +GLEE_EXTERN const char * GLeeGetExtStrGL( void ) +{ + return (const char *)glGetString(GL_EXTENSIONS); +} + +GLEE_EXTERN const char * GLeeGetErrorString( void ) +{ + return GLeeErrorString; +} + +GLboolean __GLeeInitedLoadFunctions=GL_FALSE; + +GLEE_EXTERN GLint GLeeForceLink(const char * extensionName) +{ + int type=0; + int extNum; + int len=strlen(extensionName); + if (len<5) return GLEE_LINK_FAIL; + if (!__GLeeInitedLoadFunctions) + { + if (!__GLeeInited) GLeeInit(); + initGLLoadFunctions(); +#ifdef WIN32 + initWGLLoadFunctions(); +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else + initGLXLoadFunctions(); +#endif + __GLeeInitedLoadFunctions=GL_TRUE; + } + if (extensionName[0]=='W') type=1; + else if (extensionName[2]=='X') type=2; + extNum=__GLeeGetExtensionNumber(extensionName,type); + if (extNum==-1) return GLEE_LINK_FAIL; + if (type==0) return __GLeeGLLoadFunction[extNum](); +#ifdef WIN32 + if (type==1) return __GLeeWGLLoadFunction[extNum](); +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else + if (type==2) return __GLeeGLXLoadFunction[extNum](); +#endif + return GLEE_LINK_FAIL; +} + +GLEE_EXTERN GLboolean GLeeEnabled(GLboolean * extensionQueryingVariable) +{ + if (!__GLeeInited) GLeeInit(); + return *extensionQueryingVariable; +} + +GLEE_EXTERN GLboolean GLeeInit( void ) +{ + int version; + ExtensionList extensionNames; + + if (__GLeeInited) + { + return GL_FALSE; + } + + __GLeeExtList_init(&extensionNames); + if (!__GLeeGetExtensions(&extensionNames)) + { + __GLeeWriteError("GL extension querying failed."); + __GLeeExtList_clean(&extensionNames); + return GL_FALSE; + } + + version=__GLeeGetVersionNumber((char *)glGetString(GL_VERSION)); + + __GLeeInited = GL_TRUE; + + +/***************************************************************** + * Autogenerated linking functions + *****************************************************************/ + if (version>=258) + { + _GLEE_VERSION_1_2 = GL_TRUE; + __GLeeLink_GL_VERSION_1_2(); + } + if (__GLeeCheckExtension("GL_ARB_imaging", &extensionNames) ) + { + _GLEE_ARB_imaging = GL_TRUE; + __GLeeLink_GL_ARB_imaging(); + } + if (version>=259) + { + _GLEE_VERSION_1_3 = GL_TRUE; + __GLeeLink_GL_VERSION_1_3(); + } + if (version>=260) + { + _GLEE_VERSION_1_4 = GL_TRUE; + __GLeeLink_GL_VERSION_1_4(); + } + if (version>=261) + { + _GLEE_VERSION_1_5 = GL_TRUE; + __GLeeLink_GL_VERSION_1_5(); + } + if (version>=512) + { + _GLEE_VERSION_2_0 = GL_TRUE; + __GLeeLink_GL_VERSION_2_0(); + } + if (version>=513) + { + _GLEE_VERSION_2_1 = GL_TRUE; + __GLeeLink_GL_VERSION_2_1(); + } + if (version>=768) + { + _GLEE_VERSION_3_0 = GL_TRUE; + __GLeeLink_GL_VERSION_3_0(); + } + if (__GLeeCheckExtension("GL_ARB_multitexture", &extensionNames) ) + { + _GLEE_ARB_multitexture = GL_TRUE; + __GLeeLink_GL_ARB_multitexture(); + } + if (__GLeeCheckExtension("GL_ARB_transpose_matrix", &extensionNames) ) + { + _GLEE_ARB_transpose_matrix = GL_TRUE; + __GLeeLink_GL_ARB_transpose_matrix(); + } + if (__GLeeCheckExtension("GL_ARB_multisample", &extensionNames) ) + { + _GLEE_ARB_multisample = GL_TRUE; + __GLeeLink_GL_ARB_multisample(); + } + if (__GLeeCheckExtension("GL_ARB_texture_env_add", &extensionNames) ) + { + _GLEE_ARB_texture_env_add = GL_TRUE; + __GLeeLink_GL_ARB_texture_env_add(); + } + if (__GLeeCheckExtension("GL_ARB_texture_cube_map", &extensionNames) ) + { + _GLEE_ARB_texture_cube_map = GL_TRUE; + __GLeeLink_GL_ARB_texture_cube_map(); + } + if (__GLeeCheckExtension("GL_ARB_texture_compression", &extensionNames) ) + { + _GLEE_ARB_texture_compression = GL_TRUE; + __GLeeLink_GL_ARB_texture_compression(); + } + if (__GLeeCheckExtension("GL_ARB_texture_border_clamp", &extensionNames) ) + { + _GLEE_ARB_texture_border_clamp = GL_TRUE; + __GLeeLink_GL_ARB_texture_border_clamp(); + } + if (__GLeeCheckExtension("GL_ARB_point_parameters", &extensionNames) ) + { + _GLEE_ARB_point_parameters = GL_TRUE; + __GLeeLink_GL_ARB_point_parameters(); + } + if (__GLeeCheckExtension("GL_ARB_vertex_blend", &extensionNames) ) + { + _GLEE_ARB_vertex_blend = GL_TRUE; + __GLeeLink_GL_ARB_vertex_blend(); + } + if (__GLeeCheckExtension("GL_ARB_matrix_palette", &extensionNames) ) + { + _GLEE_ARB_matrix_palette = GL_TRUE; + __GLeeLink_GL_ARB_matrix_palette(); + } + if (__GLeeCheckExtension("GL_ARB_texture_env_combine", &extensionNames) ) + { + _GLEE_ARB_texture_env_combine = GL_TRUE; + __GLeeLink_GL_ARB_texture_env_combine(); + } + if (__GLeeCheckExtension("GL_ARB_texture_env_crossbar", &extensionNames) ) + { + _GLEE_ARB_texture_env_crossbar = GL_TRUE; + __GLeeLink_GL_ARB_texture_env_crossbar(); + } + if (__GLeeCheckExtension("GL_ARB_texture_env_dot3", &extensionNames) ) + { + _GLEE_ARB_texture_env_dot3 = GL_TRUE; + __GLeeLink_GL_ARB_texture_env_dot3(); + } + if (__GLeeCheckExtension("GL_ARB_texture_mirrored_repeat", &extensionNames) ) + { + _GLEE_ARB_texture_mirrored_repeat = GL_TRUE; + __GLeeLink_GL_ARB_texture_mirrored_repeat(); + } + if (__GLeeCheckExtension("GL_ARB_depth_texture", &extensionNames) ) + { + _GLEE_ARB_depth_texture = GL_TRUE; + __GLeeLink_GL_ARB_depth_texture(); + } + if (__GLeeCheckExtension("GL_ARB_shadow", &extensionNames) ) + { + _GLEE_ARB_shadow = GL_TRUE; + __GLeeLink_GL_ARB_shadow(); + } + if (__GLeeCheckExtension("GL_ARB_shadow_ambient", &extensionNames) ) + { + _GLEE_ARB_shadow_ambient = GL_TRUE; + __GLeeLink_GL_ARB_shadow_ambient(); + } + if (__GLeeCheckExtension("GL_ARB_window_pos", &extensionNames) ) + { + _GLEE_ARB_window_pos = GL_TRUE; + __GLeeLink_GL_ARB_window_pos(); + } + if (__GLeeCheckExtension("GL_ARB_vertex_program", &extensionNames) ) + { + _GLEE_ARB_vertex_program = GL_TRUE; + __GLeeLink_GL_ARB_vertex_program(); + } + if (__GLeeCheckExtension("GL_ARB_fragment_program", &extensionNames) ) + { + _GLEE_ARB_fragment_program = GL_TRUE; + __GLeeLink_GL_ARB_fragment_program(); + } + if (__GLeeCheckExtension("GL_ARB_vertex_buffer_object", &extensionNames) ) + { + _GLEE_ARB_vertex_buffer_object = GL_TRUE; + __GLeeLink_GL_ARB_vertex_buffer_object(); + } + if (__GLeeCheckExtension("GL_ARB_occlusion_query", &extensionNames) ) + { + _GLEE_ARB_occlusion_query = GL_TRUE; + __GLeeLink_GL_ARB_occlusion_query(); + } + if (__GLeeCheckExtension("GL_ARB_shader_objects", &extensionNames) ) + { + _GLEE_ARB_shader_objects = GL_TRUE; + __GLeeLink_GL_ARB_shader_objects(); + } + if (__GLeeCheckExtension("GL_ARB_vertex_shader", &extensionNames) ) + { + _GLEE_ARB_vertex_shader = GL_TRUE; + __GLeeLink_GL_ARB_vertex_shader(); + } + if (__GLeeCheckExtension("GL_ARB_fragment_shader", &extensionNames) ) + { + _GLEE_ARB_fragment_shader = GL_TRUE; + __GLeeLink_GL_ARB_fragment_shader(); + } + if (__GLeeCheckExtension("GL_ARB_shading_language_100", &extensionNames) ) + { + _GLEE_ARB_shading_language_100 = GL_TRUE; + __GLeeLink_GL_ARB_shading_language_100(); + } + if (__GLeeCheckExtension("GL_ARB_texture_non_power_of_two", &extensionNames) ) + { + _GLEE_ARB_texture_non_power_of_two = GL_TRUE; + __GLeeLink_GL_ARB_texture_non_power_of_two(); + } + if (__GLeeCheckExtension("GL_ARB_point_sprite", &extensionNames) ) + { + _GLEE_ARB_point_sprite = GL_TRUE; + __GLeeLink_GL_ARB_point_sprite(); + } + if (__GLeeCheckExtension("GL_ARB_fragment_program_shadow", &extensionNames) ) + { + _GLEE_ARB_fragment_program_shadow = GL_TRUE; + __GLeeLink_GL_ARB_fragment_program_shadow(); + } + if (__GLeeCheckExtension("GL_ARB_draw_buffers", &extensionNames) ) + { + _GLEE_ARB_draw_buffers = GL_TRUE; + __GLeeLink_GL_ARB_draw_buffers(); + } + if (__GLeeCheckExtension("GL_ARB_texture_rectangle", &extensionNames) ) + { + _GLEE_ARB_texture_rectangle = GL_TRUE; + __GLeeLink_GL_ARB_texture_rectangle(); + } + if (__GLeeCheckExtension("GL_ARB_color_buffer_float", &extensionNames) ) + { + _GLEE_ARB_color_buffer_float = GL_TRUE; + __GLeeLink_GL_ARB_color_buffer_float(); + } + if (__GLeeCheckExtension("GL_ARB_half_float_pixel", &extensionNames) ) + { + _GLEE_ARB_half_float_pixel = GL_TRUE; + __GLeeLink_GL_ARB_half_float_pixel(); + } + if (__GLeeCheckExtension("GL_ARB_texture_float", &extensionNames) ) + { + _GLEE_ARB_texture_float = GL_TRUE; + __GLeeLink_GL_ARB_texture_float(); + } + if (__GLeeCheckExtension("GL_ARB_pixel_buffer_object", &extensionNames) ) + { + _GLEE_ARB_pixel_buffer_object = GL_TRUE; + __GLeeLink_GL_ARB_pixel_buffer_object(); + } + if (__GLeeCheckExtension("GL_ARB_depth_buffer_float", &extensionNames) ) + { + _GLEE_ARB_depth_buffer_float = GL_TRUE; + __GLeeLink_GL_ARB_depth_buffer_float(); + } + if (__GLeeCheckExtension("GL_ARB_draw_instanced", &extensionNames) ) + { + _GLEE_ARB_draw_instanced = GL_TRUE; + __GLeeLink_GL_ARB_draw_instanced(); + } + if (__GLeeCheckExtension("GL_ARB_framebuffer_object", &extensionNames) ) + { + _GLEE_ARB_framebuffer_object = GL_TRUE; + __GLeeLink_GL_ARB_framebuffer_object(); + } + if (__GLeeCheckExtension("GL_ARB_framebuffer_sRGB", &extensionNames) ) + { + _GLEE_ARB_framebuffer_sRGB = GL_TRUE; + __GLeeLink_GL_ARB_framebuffer_sRGB(); + } + if (__GLeeCheckExtension("GL_ARB_geometry_shader4", &extensionNames) ) + { + _GLEE_ARB_geometry_shader4 = GL_TRUE; + __GLeeLink_GL_ARB_geometry_shader4(); + } + if (__GLeeCheckExtension("GL_ARB_half_float_vertex", &extensionNames) ) + { + _GLEE_ARB_half_float_vertex = GL_TRUE; + __GLeeLink_GL_ARB_half_float_vertex(); + } + if (__GLeeCheckExtension("GL_ARB_instanced_arrays", &extensionNames) ) + { + _GLEE_ARB_instanced_arrays = GL_TRUE; + __GLeeLink_GL_ARB_instanced_arrays(); + } + if (__GLeeCheckExtension("GL_ARB_map_buffer_range", &extensionNames) ) + { + _GLEE_ARB_map_buffer_range = GL_TRUE; + __GLeeLink_GL_ARB_map_buffer_range(); + } + if (__GLeeCheckExtension("GL_ARB_texture_buffer_object", &extensionNames) ) + { + _GLEE_ARB_texture_buffer_object = GL_TRUE; + __GLeeLink_GL_ARB_texture_buffer_object(); + } + if (__GLeeCheckExtension("GL_ARB_texture_compression_rgtc", &extensionNames) ) + { + _GLEE_ARB_texture_compression_rgtc = GL_TRUE; + __GLeeLink_GL_ARB_texture_compression_rgtc(); + } + if (__GLeeCheckExtension("GL_ARB_texture_rg", &extensionNames) ) + { + _GLEE_ARB_texture_rg = GL_TRUE; + __GLeeLink_GL_ARB_texture_rg(); + } + if (__GLeeCheckExtension("GL_ARB_vertex_array_object", &extensionNames) ) + { + _GLEE_ARB_vertex_array_object = GL_TRUE; + __GLeeLink_GL_ARB_vertex_array_object(); + } + if (__GLeeCheckExtension("GL_EXT_abgr", &extensionNames) ) + { + _GLEE_EXT_abgr = GL_TRUE; + __GLeeLink_GL_EXT_abgr(); + } + if (__GLeeCheckExtension("GL_EXT_blend_color", &extensionNames) ) + { + _GLEE_EXT_blend_color = GL_TRUE; + __GLeeLink_GL_EXT_blend_color(); + } + if (__GLeeCheckExtension("GL_EXT_polygon_offset", &extensionNames) ) + { + _GLEE_EXT_polygon_offset = GL_TRUE; + __GLeeLink_GL_EXT_polygon_offset(); + } + if (__GLeeCheckExtension("GL_EXT_texture", &extensionNames) ) + { + _GLEE_EXT_texture = GL_TRUE; + __GLeeLink_GL_EXT_texture(); + } + if (__GLeeCheckExtension("GL_EXT_texture3D", &extensionNames) ) + { + _GLEE_EXT_texture3D = GL_TRUE; + __GLeeLink_GL_EXT_texture3D(); + } + if (__GLeeCheckExtension("GL_SGIS_texture_filter4", &extensionNames) ) + { + _GLEE_SGIS_texture_filter4 = GL_TRUE; + __GLeeLink_GL_SGIS_texture_filter4(); + } + if (__GLeeCheckExtension("GL_EXT_subtexture", &extensionNames) ) + { + _GLEE_EXT_subtexture = GL_TRUE; + __GLeeLink_GL_EXT_subtexture(); + } + if (__GLeeCheckExtension("GL_EXT_copy_texture", &extensionNames) ) + { + _GLEE_EXT_copy_texture = GL_TRUE; + __GLeeLink_GL_EXT_copy_texture(); + } + if (__GLeeCheckExtension("GL_EXT_histogram", &extensionNames) ) + { + _GLEE_EXT_histogram = GL_TRUE; + __GLeeLink_GL_EXT_histogram(); + } + if (__GLeeCheckExtension("GL_EXT_convolution", &extensionNames) ) + { + _GLEE_EXT_convolution = GL_TRUE; + __GLeeLink_GL_EXT_convolution(); + } + if (__GLeeCheckExtension("GL_SGI_color_matrix", &extensionNames) ) + { + _GLEE_SGI_color_matrix = GL_TRUE; + __GLeeLink_GL_SGI_color_matrix(); + } + if (__GLeeCheckExtension("GL_SGI_color_table", &extensionNames) ) + { + _GLEE_SGI_color_table = GL_TRUE; + __GLeeLink_GL_SGI_color_table(); + } + if (__GLeeCheckExtension("GL_SGIS_pixel_texture", &extensionNames) ) + { + _GLEE_SGIS_pixel_texture = GL_TRUE; + __GLeeLink_GL_SGIS_pixel_texture(); + } + if (__GLeeCheckExtension("GL_SGIX_pixel_texture", &extensionNames) ) + { + _GLEE_SGIX_pixel_texture = GL_TRUE; + __GLeeLink_GL_SGIX_pixel_texture(); + } + if (__GLeeCheckExtension("GL_SGIS_texture4D", &extensionNames) ) + { + _GLEE_SGIS_texture4D = GL_TRUE; + __GLeeLink_GL_SGIS_texture4D(); + } + if (__GLeeCheckExtension("GL_SGI_texture_color_table", &extensionNames) ) + { + _GLEE_SGI_texture_color_table = GL_TRUE; + __GLeeLink_GL_SGI_texture_color_table(); + } + if (__GLeeCheckExtension("GL_EXT_cmyka", &extensionNames) ) + { + _GLEE_EXT_cmyka = GL_TRUE; + __GLeeLink_GL_EXT_cmyka(); + } + if (__GLeeCheckExtension("GL_EXT_texture_object", &extensionNames) ) + { + _GLEE_EXT_texture_object = GL_TRUE; + __GLeeLink_GL_EXT_texture_object(); + } + if (__GLeeCheckExtension("GL_SGIS_detail_texture", &extensionNames) ) + { + _GLEE_SGIS_detail_texture = GL_TRUE; + __GLeeLink_GL_SGIS_detail_texture(); + } + if (__GLeeCheckExtension("GL_SGIS_sharpen_texture", &extensionNames) ) + { + _GLEE_SGIS_sharpen_texture = GL_TRUE; + __GLeeLink_GL_SGIS_sharpen_texture(); + } + if (__GLeeCheckExtension("GL_EXT_packed_pixels", &extensionNames) ) + { + _GLEE_EXT_packed_pixels = GL_TRUE; + __GLeeLink_GL_EXT_packed_pixels(); + } + if (__GLeeCheckExtension("GL_SGIS_texture_lod", &extensionNames) ) + { + _GLEE_SGIS_texture_lod = GL_TRUE; + __GLeeLink_GL_SGIS_texture_lod(); + } + if (__GLeeCheckExtension("GL_SGIS_multisample", &extensionNames) ) + { + _GLEE_SGIS_multisample = GL_TRUE; + __GLeeLink_GL_SGIS_multisample(); + } + if (__GLeeCheckExtension("GL_EXT_rescale_normal", &extensionNames) ) + { + _GLEE_EXT_rescale_normal = GL_TRUE; + __GLeeLink_GL_EXT_rescale_normal(); + } + if (__GLeeCheckExtension("GL_EXT_vertex_array", &extensionNames) ) + { + _GLEE_EXT_vertex_array = GL_TRUE; + __GLeeLink_GL_EXT_vertex_array(); + } + if (__GLeeCheckExtension("GL_EXT_misc_attribute", &extensionNames) ) + { + _GLEE_EXT_misc_attribute = GL_TRUE; + __GLeeLink_GL_EXT_misc_attribute(); + } + if (__GLeeCheckExtension("GL_SGIS_generate_mipmap", &extensionNames) ) + { + _GLEE_SGIS_generate_mipmap = GL_TRUE; + __GLeeLink_GL_SGIS_generate_mipmap(); + } + if (__GLeeCheckExtension("GL_SGIX_clipmap", &extensionNames) ) + { + _GLEE_SGIX_clipmap = GL_TRUE; + __GLeeLink_GL_SGIX_clipmap(); + } + if (__GLeeCheckExtension("GL_SGIX_shadow", &extensionNames) ) + { + _GLEE_SGIX_shadow = GL_TRUE; + __GLeeLink_GL_SGIX_shadow(); + } + if (__GLeeCheckExtension("GL_SGIS_texture_edge_clamp", &extensionNames) ) + { + _GLEE_SGIS_texture_edge_clamp = GL_TRUE; + __GLeeLink_GL_SGIS_texture_edge_clamp(); + } + if (__GLeeCheckExtension("GL_SGIS_texture_border_clamp", &extensionNames) ) + { + _GLEE_SGIS_texture_border_clamp = GL_TRUE; + __GLeeLink_GL_SGIS_texture_border_clamp(); + } + if (__GLeeCheckExtension("GL_EXT_blend_minmax", &extensionNames) ) + { + _GLEE_EXT_blend_minmax = GL_TRUE; + __GLeeLink_GL_EXT_blend_minmax(); + } + if (__GLeeCheckExtension("GL_EXT_blend_subtract", &extensionNames) ) + { + _GLEE_EXT_blend_subtract = GL_TRUE; + __GLeeLink_GL_EXT_blend_subtract(); + } + if (__GLeeCheckExtension("GL_EXT_blend_logic_op", &extensionNames) ) + { + _GLEE_EXT_blend_logic_op = GL_TRUE; + __GLeeLink_GL_EXT_blend_logic_op(); + } + if (__GLeeCheckExtension("GL_SGIX_interlace", &extensionNames) ) + { + _GLEE_SGIX_interlace = GL_TRUE; + __GLeeLink_GL_SGIX_interlace(); + } + if (__GLeeCheckExtension("GL_SGIX_pixel_tiles", &extensionNames) ) + { + _GLEE_SGIX_pixel_tiles = GL_TRUE; + __GLeeLink_GL_SGIX_pixel_tiles(); + } + if (__GLeeCheckExtension("GL_SGIS_texture_select", &extensionNames) ) + { + _GLEE_SGIS_texture_select = GL_TRUE; + __GLeeLink_GL_SGIS_texture_select(); + } + if (__GLeeCheckExtension("GL_SGIX_sprite", &extensionNames) ) + { + _GLEE_SGIX_sprite = GL_TRUE; + __GLeeLink_GL_SGIX_sprite(); + } + if (__GLeeCheckExtension("GL_SGIX_texture_multi_buffer", &extensionNames) ) + { + _GLEE_SGIX_texture_multi_buffer = GL_TRUE; + __GLeeLink_GL_SGIX_texture_multi_buffer(); + } + if (__GLeeCheckExtension("GL_EXT_point_parameters", &extensionNames) ) + { + _GLEE_EXT_point_parameters = GL_TRUE; + __GLeeLink_GL_EXT_point_parameters(); + } + if (__GLeeCheckExtension("GL_SGIS_point_parameters", &extensionNames) ) + { + _GLEE_SGIS_point_parameters = GL_TRUE; + __GLeeLink_GL_SGIS_point_parameters(); + } + if (__GLeeCheckExtension("GL_SGIX_instruments", &extensionNames) ) + { + _GLEE_SGIX_instruments = GL_TRUE; + __GLeeLink_GL_SGIX_instruments(); + } + if (__GLeeCheckExtension("GL_SGIX_texture_scale_bias", &extensionNames) ) + { + _GLEE_SGIX_texture_scale_bias = GL_TRUE; + __GLeeLink_GL_SGIX_texture_scale_bias(); + } + if (__GLeeCheckExtension("GL_SGIX_framezoom", &extensionNames) ) + { + _GLEE_SGIX_framezoom = GL_TRUE; + __GLeeLink_GL_SGIX_framezoom(); + } + if (__GLeeCheckExtension("GL_SGIX_tag_sample_buffer", &extensionNames) ) + { + _GLEE_SGIX_tag_sample_buffer = GL_TRUE; + __GLeeLink_GL_SGIX_tag_sample_buffer(); + } + if (__GLeeCheckExtension("GL_FfdMaskSGIX", &extensionNames) ) + { + _GLEE_FfdMaskSGIX = GL_TRUE; + __GLeeLink_GL_FfdMaskSGIX(); + } + if (__GLeeCheckExtension("GL_SGIX_polynomial_ffd", &extensionNames) ) + { + _GLEE_SGIX_polynomial_ffd = GL_TRUE; + __GLeeLink_GL_SGIX_polynomial_ffd(); + } + if (__GLeeCheckExtension("GL_SGIX_reference_plane", &extensionNames) ) + { + _GLEE_SGIX_reference_plane = GL_TRUE; + __GLeeLink_GL_SGIX_reference_plane(); + } + if (__GLeeCheckExtension("GL_SGIX_flush_raster", &extensionNames) ) + { + _GLEE_SGIX_flush_raster = GL_TRUE; + __GLeeLink_GL_SGIX_flush_raster(); + } + if (__GLeeCheckExtension("GL_SGIX_depth_texture", &extensionNames) ) + { + _GLEE_SGIX_depth_texture = GL_TRUE; + __GLeeLink_GL_SGIX_depth_texture(); + } + if (__GLeeCheckExtension("GL_SGIS_fog_function", &extensionNames) ) + { + _GLEE_SGIS_fog_function = GL_TRUE; + __GLeeLink_GL_SGIS_fog_function(); + } + if (__GLeeCheckExtension("GL_SGIX_fog_offset", &extensionNames) ) + { + _GLEE_SGIX_fog_offset = GL_TRUE; + __GLeeLink_GL_SGIX_fog_offset(); + } + if (__GLeeCheckExtension("GL_HP_image_transform", &extensionNames) ) + { + _GLEE_HP_image_transform = GL_TRUE; + __GLeeLink_GL_HP_image_transform(); + } + if (__GLeeCheckExtension("GL_HP_convolution_border_modes", &extensionNames) ) + { + _GLEE_HP_convolution_border_modes = GL_TRUE; + __GLeeLink_GL_HP_convolution_border_modes(); + } + if (__GLeeCheckExtension("GL_INGR_palette_buffer", &extensionNames) ) + { + _GLEE_INGR_palette_buffer = GL_TRUE; + __GLeeLink_GL_INGR_palette_buffer(); + } + if (__GLeeCheckExtension("GL_SGIX_texture_add_env", &extensionNames) ) + { + _GLEE_SGIX_texture_add_env = GL_TRUE; + __GLeeLink_GL_SGIX_texture_add_env(); + } + if (__GLeeCheckExtension("GL_EXT_color_subtable", &extensionNames) ) + { + _GLEE_EXT_color_subtable = GL_TRUE; + __GLeeLink_GL_EXT_color_subtable(); + } + if (__GLeeCheckExtension("GL_PGI_vertex_hints", &extensionNames) ) + { + _GLEE_PGI_vertex_hints = GL_TRUE; + __GLeeLink_GL_PGI_vertex_hints(); + } + if (__GLeeCheckExtension("GL_PGI_misc_hints", &extensionNames) ) + { + _GLEE_PGI_misc_hints = GL_TRUE; + __GLeeLink_GL_PGI_misc_hints(); + } + if (__GLeeCheckExtension("GL_EXT_paletted_texture", &extensionNames) ) + { + _GLEE_EXT_paletted_texture = GL_TRUE; + __GLeeLink_GL_EXT_paletted_texture(); + } + if (__GLeeCheckExtension("GL_EXT_clip_volume_hint", &extensionNames) ) + { + _GLEE_EXT_clip_volume_hint = GL_TRUE; + __GLeeLink_GL_EXT_clip_volume_hint(); + } + if (__GLeeCheckExtension("GL_SGIX_list_priority", &extensionNames) ) + { + _GLEE_SGIX_list_priority = GL_TRUE; + __GLeeLink_GL_SGIX_list_priority(); + } + if (__GLeeCheckExtension("GL_SGIX_ir_instrument1", &extensionNames) ) + { + _GLEE_SGIX_ir_instrument1 = GL_TRUE; + __GLeeLink_GL_SGIX_ir_instrument1(); + } + if (__GLeeCheckExtension("GL_SGIX_calligraphic_fragment", &extensionNames) ) + { + _GLEE_SGIX_calligraphic_fragment = GL_TRUE; + __GLeeLink_GL_SGIX_calligraphic_fragment(); + } + if (__GLeeCheckExtension("GL_SGIX_texture_lod_bias", &extensionNames) ) + { + _GLEE_SGIX_texture_lod_bias = GL_TRUE; + __GLeeLink_GL_SGIX_texture_lod_bias(); + } + if (__GLeeCheckExtension("GL_SGIX_shadow_ambient", &extensionNames) ) + { + _GLEE_SGIX_shadow_ambient = GL_TRUE; + __GLeeLink_GL_SGIX_shadow_ambient(); + } + if (__GLeeCheckExtension("GL_EXT_index_texture", &extensionNames) ) + { + _GLEE_EXT_index_texture = GL_TRUE; + __GLeeLink_GL_EXT_index_texture(); + } + if (__GLeeCheckExtension("GL_EXT_index_material", &extensionNames) ) + { + _GLEE_EXT_index_material = GL_TRUE; + __GLeeLink_GL_EXT_index_material(); + } + if (__GLeeCheckExtension("GL_EXT_index_func", &extensionNames) ) + { + _GLEE_EXT_index_func = GL_TRUE; + __GLeeLink_GL_EXT_index_func(); + } + if (__GLeeCheckExtension("GL_EXT_index_array_formats", &extensionNames) ) + { + _GLEE_EXT_index_array_formats = GL_TRUE; + __GLeeLink_GL_EXT_index_array_formats(); + } + if (__GLeeCheckExtension("GL_EXT_compiled_vertex_array", &extensionNames) ) + { + _GLEE_EXT_compiled_vertex_array = GL_TRUE; + __GLeeLink_GL_EXT_compiled_vertex_array(); + } + if (__GLeeCheckExtension("GL_EXT_cull_vertex", &extensionNames) ) + { + _GLEE_EXT_cull_vertex = GL_TRUE; + __GLeeLink_GL_EXT_cull_vertex(); + } + if (__GLeeCheckExtension("GL_SGIX_ycrcb", &extensionNames) ) + { + _GLEE_SGIX_ycrcb = GL_TRUE; + __GLeeLink_GL_SGIX_ycrcb(); + } + if (__GLeeCheckExtension("GL_SGIX_fragment_lighting", &extensionNames) ) + { + _GLEE_SGIX_fragment_lighting = GL_TRUE; + __GLeeLink_GL_SGIX_fragment_lighting(); + } + if (__GLeeCheckExtension("GL_IBM_rasterpos_clip", &extensionNames) ) + { + _GLEE_IBM_rasterpos_clip = GL_TRUE; + __GLeeLink_GL_IBM_rasterpos_clip(); + } + if (__GLeeCheckExtension("GL_HP_texture_lighting", &extensionNames) ) + { + _GLEE_HP_texture_lighting = GL_TRUE; + __GLeeLink_GL_HP_texture_lighting(); + } + if (__GLeeCheckExtension("GL_EXT_draw_range_elements", &extensionNames) ) + { + _GLEE_EXT_draw_range_elements = GL_TRUE; + __GLeeLink_GL_EXT_draw_range_elements(); + } + if (__GLeeCheckExtension("GL_WIN_phong_shading", &extensionNames) ) + { + _GLEE_WIN_phong_shading = GL_TRUE; + __GLeeLink_GL_WIN_phong_shading(); + } + if (__GLeeCheckExtension("GL_WIN_specular_fog", &extensionNames) ) + { + _GLEE_WIN_specular_fog = GL_TRUE; + __GLeeLink_GL_WIN_specular_fog(); + } + if (__GLeeCheckExtension("GL_EXT_light_texture", &extensionNames) ) + { + _GLEE_EXT_light_texture = GL_TRUE; + __GLeeLink_GL_EXT_light_texture(); + } + if (__GLeeCheckExtension("GL_SGIX_blend_alpha_minmax", &extensionNames) ) + { + _GLEE_SGIX_blend_alpha_minmax = GL_TRUE; + __GLeeLink_GL_SGIX_blend_alpha_minmax(); + } + if (__GLeeCheckExtension("GL_SGIX_impact_pixel_texture", &extensionNames) ) + { + _GLEE_SGIX_impact_pixel_texture = GL_TRUE; + __GLeeLink_GL_SGIX_impact_pixel_texture(); + } + if (__GLeeCheckExtension("GL_EXT_bgra", &extensionNames) ) + { + _GLEE_EXT_bgra = GL_TRUE; + __GLeeLink_GL_EXT_bgra(); + } + if (__GLeeCheckExtension("GL_SGIX_async", &extensionNames) ) + { + _GLEE_SGIX_async = GL_TRUE; + __GLeeLink_GL_SGIX_async(); + } + if (__GLeeCheckExtension("GL_SGIX_async_pixel", &extensionNames) ) + { + _GLEE_SGIX_async_pixel = GL_TRUE; + __GLeeLink_GL_SGIX_async_pixel(); + } + if (__GLeeCheckExtension("GL_SGIX_async_histogram", &extensionNames) ) + { + _GLEE_SGIX_async_histogram = GL_TRUE; + __GLeeLink_GL_SGIX_async_histogram(); + } + if (__GLeeCheckExtension("GL_INTEL_texture_scissor", &extensionNames) ) + { + _GLEE_INTEL_texture_scissor = GL_TRUE; + __GLeeLink_GL_INTEL_texture_scissor(); + } + if (__GLeeCheckExtension("GL_INTEL_parallel_arrays", &extensionNames) ) + { + _GLEE_INTEL_parallel_arrays = GL_TRUE; + __GLeeLink_GL_INTEL_parallel_arrays(); + } + if (__GLeeCheckExtension("GL_HP_occlusion_test", &extensionNames) ) + { + _GLEE_HP_occlusion_test = GL_TRUE; + __GLeeLink_GL_HP_occlusion_test(); + } + if (__GLeeCheckExtension("GL_EXT_pixel_transform", &extensionNames) ) + { + _GLEE_EXT_pixel_transform = GL_TRUE; + __GLeeLink_GL_EXT_pixel_transform(); + } + if (__GLeeCheckExtension("GL_EXT_pixel_transform_color_table", &extensionNames) ) + { + _GLEE_EXT_pixel_transform_color_table = GL_TRUE; + __GLeeLink_GL_EXT_pixel_transform_color_table(); + } + if (__GLeeCheckExtension("GL_EXT_shared_texture_palette", &extensionNames) ) + { + _GLEE_EXT_shared_texture_palette = GL_TRUE; + __GLeeLink_GL_EXT_shared_texture_palette(); + } + if (__GLeeCheckExtension("GL_EXT_separate_specular_color", &extensionNames) ) + { + _GLEE_EXT_separate_specular_color = GL_TRUE; + __GLeeLink_GL_EXT_separate_specular_color(); + } + if (__GLeeCheckExtension("GL_EXT_secondary_color", &extensionNames) ) + { + _GLEE_EXT_secondary_color = GL_TRUE; + __GLeeLink_GL_EXT_secondary_color(); + } + if (__GLeeCheckExtension("GL_EXT_texture_perturb_normal", &extensionNames) ) + { + _GLEE_EXT_texture_perturb_normal = GL_TRUE; + __GLeeLink_GL_EXT_texture_perturb_normal(); + } + if (__GLeeCheckExtension("GL_EXT_multi_draw_arrays", &extensionNames) ) + { + _GLEE_EXT_multi_draw_arrays = GL_TRUE; + __GLeeLink_GL_EXT_multi_draw_arrays(); + } + if (__GLeeCheckExtension("GL_EXT_fog_coord", &extensionNames) ) + { + _GLEE_EXT_fog_coord = GL_TRUE; + __GLeeLink_GL_EXT_fog_coord(); + } + if (__GLeeCheckExtension("GL_REND_screen_coordinates", &extensionNames) ) + { + _GLEE_REND_screen_coordinates = GL_TRUE; + __GLeeLink_GL_REND_screen_coordinates(); + } + if (__GLeeCheckExtension("GL_EXT_coordinate_frame", &extensionNames) ) + { + _GLEE_EXT_coordinate_frame = GL_TRUE; + __GLeeLink_GL_EXT_coordinate_frame(); + } + if (__GLeeCheckExtension("GL_EXT_texture_env_combine", &extensionNames) ) + { + _GLEE_EXT_texture_env_combine = GL_TRUE; + __GLeeLink_GL_EXT_texture_env_combine(); + } + if (__GLeeCheckExtension("GL_APPLE_specular_vector", &extensionNames) ) + { + _GLEE_APPLE_specular_vector = GL_TRUE; + __GLeeLink_GL_APPLE_specular_vector(); + } + if (__GLeeCheckExtension("GL_APPLE_transform_hint", &extensionNames) ) + { + _GLEE_APPLE_transform_hint = GL_TRUE; + __GLeeLink_GL_APPLE_transform_hint(); + } + if (__GLeeCheckExtension("GL_SGIX_fog_scale", &extensionNames) ) + { + _GLEE_SGIX_fog_scale = GL_TRUE; + __GLeeLink_GL_SGIX_fog_scale(); + } + if (__GLeeCheckExtension("GL_SUNX_constant_data", &extensionNames) ) + { + _GLEE_SUNX_constant_data = GL_TRUE; + __GLeeLink_GL_SUNX_constant_data(); + } + if (__GLeeCheckExtension("GL_SUN_global_alpha", &extensionNames) ) + { + _GLEE_SUN_global_alpha = GL_TRUE; + __GLeeLink_GL_SUN_global_alpha(); + } + if (__GLeeCheckExtension("GL_SUN_triangle_list", &extensionNames) ) + { + _GLEE_SUN_triangle_list = GL_TRUE; + __GLeeLink_GL_SUN_triangle_list(); + } + if (__GLeeCheckExtension("GL_SUN_vertex", &extensionNames) ) + { + _GLEE_SUN_vertex = GL_TRUE; + __GLeeLink_GL_SUN_vertex(); + } + if (__GLeeCheckExtension("GL_EXT_blend_func_separate", &extensionNames) ) + { + _GLEE_EXT_blend_func_separate = GL_TRUE; + __GLeeLink_GL_EXT_blend_func_separate(); + } + if (__GLeeCheckExtension("GL_INGR_color_clamp", &extensionNames) ) + { + _GLEE_INGR_color_clamp = GL_TRUE; + __GLeeLink_GL_INGR_color_clamp(); + } + if (__GLeeCheckExtension("GL_INGR_interlace_read", &extensionNames) ) + { + _GLEE_INGR_interlace_read = GL_TRUE; + __GLeeLink_GL_INGR_interlace_read(); + } + if (__GLeeCheckExtension("GL_EXT_stencil_wrap", &extensionNames) ) + { + _GLEE_EXT_stencil_wrap = GL_TRUE; + __GLeeLink_GL_EXT_stencil_wrap(); + } + if (__GLeeCheckExtension("GL_EXT_422_pixels", &extensionNames) ) + { + _GLEE_EXT_422_pixels = GL_TRUE; + __GLeeLink_GL_EXT_422_pixels(); + } + if (__GLeeCheckExtension("GL_NV_texgen_reflection", &extensionNames) ) + { + _GLEE_NV_texgen_reflection = GL_TRUE; + __GLeeLink_GL_NV_texgen_reflection(); + } + if (__GLeeCheckExtension("GL_EXT_texture_cube_map", &extensionNames) ) + { + _GLEE_EXT_texture_cube_map = GL_TRUE; + __GLeeLink_GL_EXT_texture_cube_map(); + } + if (__GLeeCheckExtension("GL_SUN_convolution_border_modes", &extensionNames) ) + { + _GLEE_SUN_convolution_border_modes = GL_TRUE; + __GLeeLink_GL_SUN_convolution_border_modes(); + } + if (__GLeeCheckExtension("GL_EXT_texture_env_add", &extensionNames) ) + { + _GLEE_EXT_texture_env_add = GL_TRUE; + __GLeeLink_GL_EXT_texture_env_add(); + } + if (__GLeeCheckExtension("GL_EXT_texture_lod_bias", &extensionNames) ) + { + _GLEE_EXT_texture_lod_bias = GL_TRUE; + __GLeeLink_GL_EXT_texture_lod_bias(); + } + if (__GLeeCheckExtension("GL_EXT_texture_filter_anisotropic", &extensionNames) ) + { + _GLEE_EXT_texture_filter_anisotropic = GL_TRUE; + __GLeeLink_GL_EXT_texture_filter_anisotropic(); + } + if (__GLeeCheckExtension("GL_EXT_vertex_weighting", &extensionNames) ) + { + _GLEE_EXT_vertex_weighting = GL_TRUE; + __GLeeLink_GL_EXT_vertex_weighting(); + } + if (__GLeeCheckExtension("GL_NV_light_max_exponent", &extensionNames) ) + { + _GLEE_NV_light_max_exponent = GL_TRUE; + __GLeeLink_GL_NV_light_max_exponent(); + } + if (__GLeeCheckExtension("GL_NV_vertex_array_range", &extensionNames) ) + { + _GLEE_NV_vertex_array_range = GL_TRUE; + __GLeeLink_GL_NV_vertex_array_range(); + } + if (__GLeeCheckExtension("GL_NV_register_combiners", &extensionNames) ) + { + _GLEE_NV_register_combiners = GL_TRUE; + __GLeeLink_GL_NV_register_combiners(); + } + if (__GLeeCheckExtension("GL_NV_fog_distance", &extensionNames) ) + { + _GLEE_NV_fog_distance = GL_TRUE; + __GLeeLink_GL_NV_fog_distance(); + } + if (__GLeeCheckExtension("GL_NV_texgen_emboss", &extensionNames) ) + { + _GLEE_NV_texgen_emboss = GL_TRUE; + __GLeeLink_GL_NV_texgen_emboss(); + } + if (__GLeeCheckExtension("GL_NV_blend_square", &extensionNames) ) + { + _GLEE_NV_blend_square = GL_TRUE; + __GLeeLink_GL_NV_blend_square(); + } + if (__GLeeCheckExtension("GL_NV_texture_env_combine4", &extensionNames) ) + { + _GLEE_NV_texture_env_combine4 = GL_TRUE; + __GLeeLink_GL_NV_texture_env_combine4(); + } + if (__GLeeCheckExtension("GL_MESA_resize_buffers", &extensionNames) ) + { + _GLEE_MESA_resize_buffers = GL_TRUE; + __GLeeLink_GL_MESA_resize_buffers(); + } + if (__GLeeCheckExtension("GL_MESA_window_pos", &extensionNames) ) + { + _GLEE_MESA_window_pos = GL_TRUE; + __GLeeLink_GL_MESA_window_pos(); + } + if (__GLeeCheckExtension("GL_EXT_texture_compression_s3tc", &extensionNames) ) + { + _GLEE_EXT_texture_compression_s3tc = GL_TRUE; + __GLeeLink_GL_EXT_texture_compression_s3tc(); + } + if (__GLeeCheckExtension("GL_IBM_cull_vertex", &extensionNames) ) + { + _GLEE_IBM_cull_vertex = GL_TRUE; + __GLeeLink_GL_IBM_cull_vertex(); + } + if (__GLeeCheckExtension("GL_IBM_multimode_draw_arrays", &extensionNames) ) + { + _GLEE_IBM_multimode_draw_arrays = GL_TRUE; + __GLeeLink_GL_IBM_multimode_draw_arrays(); + } + if (__GLeeCheckExtension("GL_IBM_vertex_array_lists", &extensionNames) ) + { + _GLEE_IBM_vertex_array_lists = GL_TRUE; + __GLeeLink_GL_IBM_vertex_array_lists(); + } + if (__GLeeCheckExtension("GL_SGIX_subsample", &extensionNames) ) + { + _GLEE_SGIX_subsample = GL_TRUE; + __GLeeLink_GL_SGIX_subsample(); + } + if (__GLeeCheckExtension("GL_SGIX_ycrcb_subsample", &extensionNames) ) + { + _GLEE_SGIX_ycrcb_subsample = GL_TRUE; + __GLeeLink_GL_SGIX_ycrcb_subsample(); + } + if (__GLeeCheckExtension("GL_SGIX_ycrcba", &extensionNames) ) + { + _GLEE_SGIX_ycrcba = GL_TRUE; + __GLeeLink_GL_SGIX_ycrcba(); + } + if (__GLeeCheckExtension("GL_SGI_depth_pass_instrument", &extensionNames) ) + { + _GLEE_SGI_depth_pass_instrument = GL_TRUE; + __GLeeLink_GL_SGI_depth_pass_instrument(); + } + if (__GLeeCheckExtension("GL_3DFX_texture_compression_FXT1", &extensionNames) ) + { + _GLEE_3DFX_texture_compression_FXT1 = GL_TRUE; + __GLeeLink_GL_3DFX_texture_compression_FXT1(); + } + if (__GLeeCheckExtension("GL_3DFX_multisample", &extensionNames) ) + { + _GLEE_3DFX_multisample = GL_TRUE; + __GLeeLink_GL_3DFX_multisample(); + } + if (__GLeeCheckExtension("GL_3DFX_tbuffer", &extensionNames) ) + { + _GLEE_3DFX_tbuffer = GL_TRUE; + __GLeeLink_GL_3DFX_tbuffer(); + } + if (__GLeeCheckExtension("GL_EXT_multisample", &extensionNames) ) + { + _GLEE_EXT_multisample = GL_TRUE; + __GLeeLink_GL_EXT_multisample(); + } + if (__GLeeCheckExtension("GL_SGIX_vertex_preclip", &extensionNames) ) + { + _GLEE_SGIX_vertex_preclip = GL_TRUE; + __GLeeLink_GL_SGIX_vertex_preclip(); + } + if (__GLeeCheckExtension("GL_SGIX_convolution_accuracy", &extensionNames) ) + { + _GLEE_SGIX_convolution_accuracy = GL_TRUE; + __GLeeLink_GL_SGIX_convolution_accuracy(); + } + if (__GLeeCheckExtension("GL_SGIX_resample", &extensionNames) ) + { + _GLEE_SGIX_resample = GL_TRUE; + __GLeeLink_GL_SGIX_resample(); + } + if (__GLeeCheckExtension("GL_SGIS_point_line_texgen", &extensionNames) ) + { + _GLEE_SGIS_point_line_texgen = GL_TRUE; + __GLeeLink_GL_SGIS_point_line_texgen(); + } + if (__GLeeCheckExtension("GL_SGIS_texture_color_mask", &extensionNames) ) + { + _GLEE_SGIS_texture_color_mask = GL_TRUE; + __GLeeLink_GL_SGIS_texture_color_mask(); + } + if (__GLeeCheckExtension("GL_EXT_texture_env_dot3", &extensionNames) ) + { + _GLEE_EXT_texture_env_dot3 = GL_TRUE; + __GLeeLink_GL_EXT_texture_env_dot3(); + } + if (__GLeeCheckExtension("GL_ATI_texture_mirror_once", &extensionNames) ) + { + _GLEE_ATI_texture_mirror_once = GL_TRUE; + __GLeeLink_GL_ATI_texture_mirror_once(); + } + if (__GLeeCheckExtension("GL_NV_fence", &extensionNames) ) + { + _GLEE_NV_fence = GL_TRUE; + __GLeeLink_GL_NV_fence(); + } + if (__GLeeCheckExtension("GL_IBM_texture_mirrored_repeat", &extensionNames) ) + { + _GLEE_IBM_texture_mirrored_repeat = GL_TRUE; + __GLeeLink_GL_IBM_texture_mirrored_repeat(); + } + if (__GLeeCheckExtension("GL_NV_evaluators", &extensionNames) ) + { + _GLEE_NV_evaluators = GL_TRUE; + __GLeeLink_GL_NV_evaluators(); + } + if (__GLeeCheckExtension("GL_NV_packed_depth_stencil", &extensionNames) ) + { + _GLEE_NV_packed_depth_stencil = GL_TRUE; + __GLeeLink_GL_NV_packed_depth_stencil(); + } + if (__GLeeCheckExtension("GL_NV_register_combiners2", &extensionNames) ) + { + _GLEE_NV_register_combiners2 = GL_TRUE; + __GLeeLink_GL_NV_register_combiners2(); + } + if (__GLeeCheckExtension("GL_NV_texture_compression_vtc", &extensionNames) ) + { + _GLEE_NV_texture_compression_vtc = GL_TRUE; + __GLeeLink_GL_NV_texture_compression_vtc(); + } + if (__GLeeCheckExtension("GL_NV_texture_rectangle", &extensionNames) ) + { + _GLEE_NV_texture_rectangle = GL_TRUE; + __GLeeLink_GL_NV_texture_rectangle(); + } + if (__GLeeCheckExtension("GL_NV_texture_shader", &extensionNames) ) + { + _GLEE_NV_texture_shader = GL_TRUE; + __GLeeLink_GL_NV_texture_shader(); + } + if (__GLeeCheckExtension("GL_NV_texture_shader2", &extensionNames) ) + { + _GLEE_NV_texture_shader2 = GL_TRUE; + __GLeeLink_GL_NV_texture_shader2(); + } + if (__GLeeCheckExtension("GL_NV_vertex_array_range2", &extensionNames) ) + { + _GLEE_NV_vertex_array_range2 = GL_TRUE; + __GLeeLink_GL_NV_vertex_array_range2(); + } + if (__GLeeCheckExtension("GL_NV_vertex_program", &extensionNames) ) + { + _GLEE_NV_vertex_program = GL_TRUE; + __GLeeLink_GL_NV_vertex_program(); + } + if (__GLeeCheckExtension("GL_SGIX_texture_coordinate_clamp", &extensionNames) ) + { + _GLEE_SGIX_texture_coordinate_clamp = GL_TRUE; + __GLeeLink_GL_SGIX_texture_coordinate_clamp(); + } + if (__GLeeCheckExtension("GL_SGIX_scalebias_hint", &extensionNames) ) + { + _GLEE_SGIX_scalebias_hint = GL_TRUE; + __GLeeLink_GL_SGIX_scalebias_hint(); + } + if (__GLeeCheckExtension("GL_OML_interlace", &extensionNames) ) + { + _GLEE_OML_interlace = GL_TRUE; + __GLeeLink_GL_OML_interlace(); + } + if (__GLeeCheckExtension("GL_OML_subsample", &extensionNames) ) + { + _GLEE_OML_subsample = GL_TRUE; + __GLeeLink_GL_OML_subsample(); + } + if (__GLeeCheckExtension("GL_OML_resample", &extensionNames) ) + { + _GLEE_OML_resample = GL_TRUE; + __GLeeLink_GL_OML_resample(); + } + if (__GLeeCheckExtension("GL_NV_copy_depth_to_color", &extensionNames) ) + { + _GLEE_NV_copy_depth_to_color = GL_TRUE; + __GLeeLink_GL_NV_copy_depth_to_color(); + } + if (__GLeeCheckExtension("GL_ATI_envmap_bumpmap", &extensionNames) ) + { + _GLEE_ATI_envmap_bumpmap = GL_TRUE; + __GLeeLink_GL_ATI_envmap_bumpmap(); + } + if (__GLeeCheckExtension("GL_ATI_fragment_shader", &extensionNames) ) + { + _GLEE_ATI_fragment_shader = GL_TRUE; + __GLeeLink_GL_ATI_fragment_shader(); + } + if (__GLeeCheckExtension("GL_ATI_pn_triangles", &extensionNames) ) + { + _GLEE_ATI_pn_triangles = GL_TRUE; + __GLeeLink_GL_ATI_pn_triangles(); + } + if (__GLeeCheckExtension("GL_ATI_vertex_array_object", &extensionNames) ) + { + _GLEE_ATI_vertex_array_object = GL_TRUE; + __GLeeLink_GL_ATI_vertex_array_object(); + } + if (__GLeeCheckExtension("GL_EXT_vertex_shader", &extensionNames) ) + { + _GLEE_EXT_vertex_shader = GL_TRUE; + __GLeeLink_GL_EXT_vertex_shader(); + } + if (__GLeeCheckExtension("GL_ATI_vertex_streams", &extensionNames) ) + { + _GLEE_ATI_vertex_streams = GL_TRUE; + __GLeeLink_GL_ATI_vertex_streams(); + } + if (__GLeeCheckExtension("GL_ATI_element_array", &extensionNames) ) + { + _GLEE_ATI_element_array = GL_TRUE; + __GLeeLink_GL_ATI_element_array(); + } + if (__GLeeCheckExtension("GL_SUN_mesh_array", &extensionNames) ) + { + _GLEE_SUN_mesh_array = GL_TRUE; + __GLeeLink_GL_SUN_mesh_array(); + } + if (__GLeeCheckExtension("GL_SUN_slice_accum", &extensionNames) ) + { + _GLEE_SUN_slice_accum = GL_TRUE; + __GLeeLink_GL_SUN_slice_accum(); + } + if (__GLeeCheckExtension("GL_NV_multisample_filter_hint", &extensionNames) ) + { + _GLEE_NV_multisample_filter_hint = GL_TRUE; + __GLeeLink_GL_NV_multisample_filter_hint(); + } + if (__GLeeCheckExtension("GL_NV_depth_clamp", &extensionNames) ) + { + _GLEE_NV_depth_clamp = GL_TRUE; + __GLeeLink_GL_NV_depth_clamp(); + } + if (__GLeeCheckExtension("GL_NV_occlusion_query", &extensionNames) ) + { + _GLEE_NV_occlusion_query = GL_TRUE; + __GLeeLink_GL_NV_occlusion_query(); + } + if (__GLeeCheckExtension("GL_NV_point_sprite", &extensionNames) ) + { + _GLEE_NV_point_sprite = GL_TRUE; + __GLeeLink_GL_NV_point_sprite(); + } + if (__GLeeCheckExtension("GL_NV_texture_shader3", &extensionNames) ) + { + _GLEE_NV_texture_shader3 = GL_TRUE; + __GLeeLink_GL_NV_texture_shader3(); + } + if (__GLeeCheckExtension("GL_NV_vertex_program1_1", &extensionNames) ) + { + _GLEE_NV_vertex_program1_1 = GL_TRUE; + __GLeeLink_GL_NV_vertex_program1_1(); + } + if (__GLeeCheckExtension("GL_EXT_shadow_funcs", &extensionNames) ) + { + _GLEE_EXT_shadow_funcs = GL_TRUE; + __GLeeLink_GL_EXT_shadow_funcs(); + } + if (__GLeeCheckExtension("GL_EXT_stencil_two_side", &extensionNames) ) + { + _GLEE_EXT_stencil_two_side = GL_TRUE; + __GLeeLink_GL_EXT_stencil_two_side(); + } + if (__GLeeCheckExtension("GL_ATI_text_fragment_shader", &extensionNames) ) + { + _GLEE_ATI_text_fragment_shader = GL_TRUE; + __GLeeLink_GL_ATI_text_fragment_shader(); + } + if (__GLeeCheckExtension("GL_APPLE_client_storage", &extensionNames) ) + { + _GLEE_APPLE_client_storage = GL_TRUE; + __GLeeLink_GL_APPLE_client_storage(); + } + if (__GLeeCheckExtension("GL_APPLE_element_array", &extensionNames) ) + { + _GLEE_APPLE_element_array = GL_TRUE; + __GLeeLink_GL_APPLE_element_array(); + } + if (__GLeeCheckExtension("GL_APPLE_fence", &extensionNames) ) + { + _GLEE_APPLE_fence = GL_TRUE; + __GLeeLink_GL_APPLE_fence(); + } + if (__GLeeCheckExtension("GL_APPLE_vertex_array_object", &extensionNames) ) + { + _GLEE_APPLE_vertex_array_object = GL_TRUE; + __GLeeLink_GL_APPLE_vertex_array_object(); + } + if (__GLeeCheckExtension("GL_APPLE_vertex_array_range", &extensionNames) ) + { + _GLEE_APPLE_vertex_array_range = GL_TRUE; + __GLeeLink_GL_APPLE_vertex_array_range(); + } + if (__GLeeCheckExtension("GL_APPLE_ycbcr_422", &extensionNames) ) + { + _GLEE_APPLE_ycbcr_422 = GL_TRUE; + __GLeeLink_GL_APPLE_ycbcr_422(); + } + if (__GLeeCheckExtension("GL_S3_s3tc", &extensionNames) ) + { + _GLEE_S3_s3tc = GL_TRUE; + __GLeeLink_GL_S3_s3tc(); + } + if (__GLeeCheckExtension("GL_ATI_draw_buffers", &extensionNames) ) + { + _GLEE_ATI_draw_buffers = GL_TRUE; + __GLeeLink_GL_ATI_draw_buffers(); + } + if (__GLeeCheckExtension("GL_ATI_pixel_format_float", &extensionNames) ) + { + _GLEE_ATI_pixel_format_float = GL_TRUE; + __GLeeLink_GL_ATI_pixel_format_float(); + } + if (__GLeeCheckExtension("GL_ATI_texture_env_combine3", &extensionNames) ) + { + _GLEE_ATI_texture_env_combine3 = GL_TRUE; + __GLeeLink_GL_ATI_texture_env_combine3(); + } + if (__GLeeCheckExtension("GL_ATI_texture_float", &extensionNames) ) + { + _GLEE_ATI_texture_float = GL_TRUE; + __GLeeLink_GL_ATI_texture_float(); + } + if (__GLeeCheckExtension("GL_NV_float_buffer", &extensionNames) ) + { + _GLEE_NV_float_buffer = GL_TRUE; + __GLeeLink_GL_NV_float_buffer(); + } + if (__GLeeCheckExtension("GL_NV_fragment_program", &extensionNames) ) + { + _GLEE_NV_fragment_program = GL_TRUE; + __GLeeLink_GL_NV_fragment_program(); + } + if (__GLeeCheckExtension("GL_NV_half_float", &extensionNames) ) + { + _GLEE_NV_half_float = GL_TRUE; + __GLeeLink_GL_NV_half_float(); + } + if (__GLeeCheckExtension("GL_NV_pixel_data_range", &extensionNames) ) + { + _GLEE_NV_pixel_data_range = GL_TRUE; + __GLeeLink_GL_NV_pixel_data_range(); + } + if (__GLeeCheckExtension("GL_NV_primitive_restart", &extensionNames) ) + { + _GLEE_NV_primitive_restart = GL_TRUE; + __GLeeLink_GL_NV_primitive_restart(); + } + if (__GLeeCheckExtension("GL_NV_texture_expand_normal", &extensionNames) ) + { + _GLEE_NV_texture_expand_normal = GL_TRUE; + __GLeeLink_GL_NV_texture_expand_normal(); + } + if (__GLeeCheckExtension("GL_NV_vertex_program2", &extensionNames) ) + { + _GLEE_NV_vertex_program2 = GL_TRUE; + __GLeeLink_GL_NV_vertex_program2(); + } + if (__GLeeCheckExtension("GL_ATI_map_object_buffer", &extensionNames) ) + { + _GLEE_ATI_map_object_buffer = GL_TRUE; + __GLeeLink_GL_ATI_map_object_buffer(); + } + if (__GLeeCheckExtension("GL_ATI_separate_stencil", &extensionNames) ) + { + _GLEE_ATI_separate_stencil = GL_TRUE; + __GLeeLink_GL_ATI_separate_stencil(); + } + if (__GLeeCheckExtension("GL_ATI_vertex_attrib_array_object", &extensionNames) ) + { + _GLEE_ATI_vertex_attrib_array_object = GL_TRUE; + __GLeeLink_GL_ATI_vertex_attrib_array_object(); + } + if (__GLeeCheckExtension("GL_OES_read_format", &extensionNames) ) + { + _GLEE_OES_read_format = GL_TRUE; + __GLeeLink_GL_OES_read_format(); + } + if (__GLeeCheckExtension("GL_EXT_depth_bounds_test", &extensionNames) ) + { + _GLEE_EXT_depth_bounds_test = GL_TRUE; + __GLeeLink_GL_EXT_depth_bounds_test(); + } + if (__GLeeCheckExtension("GL_EXT_texture_mirror_clamp", &extensionNames) ) + { + _GLEE_EXT_texture_mirror_clamp = GL_TRUE; + __GLeeLink_GL_EXT_texture_mirror_clamp(); + } + if (__GLeeCheckExtension("GL_EXT_blend_equation_separate", &extensionNames) ) + { + _GLEE_EXT_blend_equation_separate = GL_TRUE; + __GLeeLink_GL_EXT_blend_equation_separate(); + } + if (__GLeeCheckExtension("GL_MESA_pack_invert", &extensionNames) ) + { + _GLEE_MESA_pack_invert = GL_TRUE; + __GLeeLink_GL_MESA_pack_invert(); + } + if (__GLeeCheckExtension("GL_MESA_ycbcr_texture", &extensionNames) ) + { + _GLEE_MESA_ycbcr_texture = GL_TRUE; + __GLeeLink_GL_MESA_ycbcr_texture(); + } + if (__GLeeCheckExtension("GL_EXT_pixel_buffer_object", &extensionNames) ) + { + _GLEE_EXT_pixel_buffer_object = GL_TRUE; + __GLeeLink_GL_EXT_pixel_buffer_object(); + } + if (__GLeeCheckExtension("GL_NV_fragment_program_option", &extensionNames) ) + { + _GLEE_NV_fragment_program_option = GL_TRUE; + __GLeeLink_GL_NV_fragment_program_option(); + } + if (__GLeeCheckExtension("GL_NV_fragment_program2", &extensionNames) ) + { + _GLEE_NV_fragment_program2 = GL_TRUE; + __GLeeLink_GL_NV_fragment_program2(); + } + if (__GLeeCheckExtension("GL_NV_vertex_program2_option", &extensionNames) ) + { + _GLEE_NV_vertex_program2_option = GL_TRUE; + __GLeeLink_GL_NV_vertex_program2_option(); + } + if (__GLeeCheckExtension("GL_NV_vertex_program3", &extensionNames) ) + { + _GLEE_NV_vertex_program3 = GL_TRUE; + __GLeeLink_GL_NV_vertex_program3(); + } + if (__GLeeCheckExtension("GL_EXT_framebuffer_object", &extensionNames) ) + { + _GLEE_EXT_framebuffer_object = GL_TRUE; + __GLeeLink_GL_EXT_framebuffer_object(); + } + if (__GLeeCheckExtension("GL_GREMEDY_string_marker", &extensionNames) ) + { + _GLEE_GREMEDY_string_marker = GL_TRUE; + __GLeeLink_GL_GREMEDY_string_marker(); + } + if (__GLeeCheckExtension("GL_EXT_packed_depth_stencil", &extensionNames) ) + { + _GLEE_EXT_packed_depth_stencil = GL_TRUE; + __GLeeLink_GL_EXT_packed_depth_stencil(); + } + if (__GLeeCheckExtension("GL_EXT_stencil_clear_tag", &extensionNames) ) + { + _GLEE_EXT_stencil_clear_tag = GL_TRUE; + __GLeeLink_GL_EXT_stencil_clear_tag(); + } + if (__GLeeCheckExtension("GL_EXT_texture_sRGB", &extensionNames) ) + { + _GLEE_EXT_texture_sRGB = GL_TRUE; + __GLeeLink_GL_EXT_texture_sRGB(); + } + if (__GLeeCheckExtension("GL_EXT_framebuffer_blit", &extensionNames) ) + { + _GLEE_EXT_framebuffer_blit = GL_TRUE; + __GLeeLink_GL_EXT_framebuffer_blit(); + } + if (__GLeeCheckExtension("GL_EXT_framebuffer_multisample", &extensionNames) ) + { + _GLEE_EXT_framebuffer_multisample = GL_TRUE; + __GLeeLink_GL_EXT_framebuffer_multisample(); + } + if (__GLeeCheckExtension("GL_MESAX_texture_stack", &extensionNames) ) + { + _GLEE_MESAX_texture_stack = GL_TRUE; + __GLeeLink_GL_MESAX_texture_stack(); + } + if (__GLeeCheckExtension("GL_EXT_timer_query", &extensionNames) ) + { + _GLEE_EXT_timer_query = GL_TRUE; + __GLeeLink_GL_EXT_timer_query(); + } + if (__GLeeCheckExtension("GL_EXT_gpu_program_parameters", &extensionNames) ) + { + _GLEE_EXT_gpu_program_parameters = GL_TRUE; + __GLeeLink_GL_EXT_gpu_program_parameters(); + } + if (__GLeeCheckExtension("GL_APPLE_flush_buffer_range", &extensionNames) ) + { + _GLEE_APPLE_flush_buffer_range = GL_TRUE; + __GLeeLink_GL_APPLE_flush_buffer_range(); + } + if (__GLeeCheckExtension("GL_EXT_gpu_shader4", &extensionNames) ) + { + _GLEE_EXT_gpu_shader4 = GL_TRUE; + __GLeeLink_GL_EXT_gpu_shader4(); + } + if (__GLeeCheckExtension("GL_EXT_draw_instanced", &extensionNames) ) + { + _GLEE_EXT_draw_instanced = GL_TRUE; + __GLeeLink_GL_EXT_draw_instanced(); + } + if (__GLeeCheckExtension("GL_EXT_packed_float", &extensionNames) ) + { + _GLEE_EXT_packed_float = GL_TRUE; + __GLeeLink_GL_EXT_packed_float(); + } + if (__GLeeCheckExtension("GL_EXT_texture_array", &extensionNames) ) + { + _GLEE_EXT_texture_array = GL_TRUE; + __GLeeLink_GL_EXT_texture_array(); + } + if (__GLeeCheckExtension("GL_EXT_texture_buffer_object", &extensionNames) ) + { + _GLEE_EXT_texture_buffer_object = GL_TRUE; + __GLeeLink_GL_EXT_texture_buffer_object(); + } + if (__GLeeCheckExtension("GL_EXT_texture_compression_latc", &extensionNames) ) + { + _GLEE_EXT_texture_compression_latc = GL_TRUE; + __GLeeLink_GL_EXT_texture_compression_latc(); + } + if (__GLeeCheckExtension("GL_EXT_texture_compression_rgtc", &extensionNames) ) + { + _GLEE_EXT_texture_compression_rgtc = GL_TRUE; + __GLeeLink_GL_EXT_texture_compression_rgtc(); + } + if (__GLeeCheckExtension("GL_EXT_texture_shared_exponent", &extensionNames) ) + { + _GLEE_EXT_texture_shared_exponent = GL_TRUE; + __GLeeLink_GL_EXT_texture_shared_exponent(); + } + if (__GLeeCheckExtension("GL_NV_depth_buffer_float", &extensionNames) ) + { + _GLEE_NV_depth_buffer_float = GL_TRUE; + __GLeeLink_GL_NV_depth_buffer_float(); + } + if (__GLeeCheckExtension("GL_NV_framebuffer_multisample_coverage", &extensionNames) ) + { + _GLEE_NV_framebuffer_multisample_coverage = GL_TRUE; + __GLeeLink_GL_NV_framebuffer_multisample_coverage(); + } + if (__GLeeCheckExtension("GL_EXT_framebuffer_sRGB", &extensionNames) ) + { + _GLEE_EXT_framebuffer_sRGB = GL_TRUE; + __GLeeLink_GL_EXT_framebuffer_sRGB(); + } + if (__GLeeCheckExtension("GL_NV_geometry_shader4", &extensionNames) ) + { + _GLEE_NV_geometry_shader4 = GL_TRUE; + __GLeeLink_GL_NV_geometry_shader4(); + } + if (__GLeeCheckExtension("GL_NV_parameter_buffer_object", &extensionNames) ) + { + _GLEE_NV_parameter_buffer_object = GL_TRUE; + __GLeeLink_GL_NV_parameter_buffer_object(); + } + if (__GLeeCheckExtension("GL_EXT_draw_buffers2", &extensionNames) ) + { + _GLEE_EXT_draw_buffers2 = GL_TRUE; + __GLeeLink_GL_EXT_draw_buffers2(); + } + if (__GLeeCheckExtension("GL_NV_transform_feedback", &extensionNames) ) + { + _GLEE_NV_transform_feedback = GL_TRUE; + __GLeeLink_GL_NV_transform_feedback(); + } + if (__GLeeCheckExtension("GL_EXT_bindable_uniform", &extensionNames) ) + { + _GLEE_EXT_bindable_uniform = GL_TRUE; + __GLeeLink_GL_EXT_bindable_uniform(); + } + if (__GLeeCheckExtension("GL_EXT_texture_integer", &extensionNames) ) + { + _GLEE_EXT_texture_integer = GL_TRUE; + __GLeeLink_GL_EXT_texture_integer(); + } + if (__GLeeCheckExtension("GL_GREMEDY_frame_terminator", &extensionNames) ) + { + _GLEE_GREMEDY_frame_terminator = GL_TRUE; + __GLeeLink_GL_GREMEDY_frame_terminator(); + } + if (__GLeeCheckExtension("GL_NV_conditional_render", &extensionNames) ) + { + _GLEE_NV_conditional_render = GL_TRUE; + __GLeeLink_GL_NV_conditional_render(); + } + if (__GLeeCheckExtension("GL_NV_present_video", &extensionNames) ) + { + _GLEE_NV_present_video = GL_TRUE; + __GLeeLink_GL_NV_present_video(); + } + if (__GLeeCheckExtension("GL_EXT_transform_feedback", &extensionNames) ) + { + _GLEE_EXT_transform_feedback = GL_TRUE; + __GLeeLink_GL_EXT_transform_feedback(); + } + if (__GLeeCheckExtension("GL_EXT_direct_state_access", &extensionNames) ) + { + _GLEE_EXT_direct_state_access = GL_TRUE; + __GLeeLink_GL_EXT_direct_state_access(); + } + if (__GLeeCheckExtension("GL_EXT_vertex_array_bgra", &extensionNames) ) + { + _GLEE_EXT_vertex_array_bgra = GL_TRUE; + __GLeeLink_GL_EXT_vertex_array_bgra(); + } + if (__GLeeCheckExtension("GL_EXT_texture_swizzle", &extensionNames) ) + { + _GLEE_EXT_texture_swizzle = GL_TRUE; + __GLeeLink_GL_EXT_texture_swizzle(); + } + if (__GLeeCheckExtension("GL_NV_explicit_multisample", &extensionNames) ) + { + _GLEE_NV_explicit_multisample = GL_TRUE; + __GLeeLink_GL_NV_explicit_multisample(); + } + if (__GLeeCheckExtension("GL_NV_transform_feedback2", &extensionNames) ) + { + _GLEE_NV_transform_feedback2 = GL_TRUE; + __GLeeLink_GL_NV_transform_feedback2(); + } + if (__GLeeCheckExtension("GL_SGIX_texture_select", &extensionNames) ) + { + _GLEE_SGIX_texture_select = GL_TRUE; + __GLeeLink_GL_SGIX_texture_select(); + } + if (__GLeeCheckExtension("GL_INGR_blend_func_separate", &extensionNames) ) + { + _GLEE_INGR_blend_func_separate = GL_TRUE; + __GLeeLink_GL_INGR_blend_func_separate(); + } + if (__GLeeCheckExtension("GL_SGIX_depth_pass_instrument", &extensionNames) ) + { + _GLEE_SGIX_depth_pass_instrument = GL_TRUE; + __GLeeLink_GL_SGIX_depth_pass_instrument(); + } + if (__GLeeCheckExtension("GL_SGIX_igloo_interface", &extensionNames) ) + { + _GLEE_SGIX_igloo_interface = GL_TRUE; + __GLeeLink_GL_SGIX_igloo_interface(); + } + if (__GLeeCheckExtension("GL_EXT_fragment_lighting", &extensionNames) ) + { + _GLEE_EXT_fragment_lighting = GL_TRUE; + __GLeeLink_GL_EXT_fragment_lighting(); + } + if (__GLeeCheckExtension("GL_EXT_geometry_shader4", &extensionNames) ) + { + _GLEE_EXT_geometry_shader4 = GL_TRUE; + __GLeeLink_GL_EXT_geometry_shader4(); + } + if (__GLeeCheckExtension("GL_EXT_scene_marker", &extensionNames) ) + { + _GLEE_EXT_scene_marker = GL_TRUE; + __GLeeLink_GL_EXT_scene_marker(); + } + if (__GLeeCheckExtension("GL_EXT_texture_compression_dxt1", &extensionNames) ) + { + _GLEE_EXT_texture_compression_dxt1 = GL_TRUE; + __GLeeLink_GL_EXT_texture_compression_dxt1(); + } + if (__GLeeCheckExtension("GL_EXT_texture_env", &extensionNames) ) + { + _GLEE_EXT_texture_env = GL_TRUE; + __GLeeLink_GL_EXT_texture_env(); + } + if (__GLeeCheckExtension("GL_IBM_static_data", &extensionNames) ) + { + _GLEE_IBM_static_data = GL_TRUE; + __GLeeLink_GL_IBM_static_data(); + } + if (__GLeeCheckExtension("GL_NV_gpu_program4", &extensionNames) ) + { + _GLEE_NV_gpu_program4 = GL_TRUE; + __GLeeLink_GL_NV_gpu_program4(); + } + if (__GLeeCheckExtension("GL_OES_byte_coordinates", &extensionNames) ) + { + _GLEE_OES_byte_coordinates = GL_TRUE; + __GLeeLink_GL_OES_byte_coordinates(); + } + if (__GLeeCheckExtension("GL_OES_compressed_paletted_texture", &extensionNames) ) + { + _GLEE_OES_compressed_paletted_texture = GL_TRUE; + __GLeeLink_GL_OES_compressed_paletted_texture(); + } + if (__GLeeCheckExtension("GL_OES_single_precision", &extensionNames) ) + { + _GLEE_OES_single_precision = GL_TRUE; + __GLeeLink_GL_OES_single_precision(); + } + if (__GLeeCheckExtension("GL_SGIX_pixel_texture_bits", &extensionNames) ) + { + _GLEE_SGIX_pixel_texture_bits = GL_TRUE; + __GLeeLink_GL_SGIX_pixel_texture_bits(); + } + if (__GLeeCheckExtension("GL_SGIX_texture_range", &extensionNames) ) + { + _GLEE_SGIX_texture_range = GL_TRUE; + __GLeeLink_GL_SGIX_texture_range(); + } +#ifdef WIN32 + if (__GLeeCheckExtension("WGL_ARB_buffer_region", &extensionNames) ) + { + _GLEE_WGL_ARB_buffer_region = GL_TRUE; + __GLeeLink_WGL_ARB_buffer_region(); + } + if (__GLeeCheckExtension("WGL_ARB_multisample", &extensionNames) ) + { + _GLEE_WGL_ARB_multisample = GL_TRUE; + __GLeeLink_WGL_ARB_multisample(); + } + if (__GLeeCheckExtension("WGL_ARB_extensions_string", &extensionNames) ) + { + _GLEE_WGL_ARB_extensions_string = GL_TRUE; + __GLeeLink_WGL_ARB_extensions_string(); + } + if (__GLeeCheckExtension("WGL_ARB_pixel_format", &extensionNames) ) + { + _GLEE_WGL_ARB_pixel_format = GL_TRUE; + __GLeeLink_WGL_ARB_pixel_format(); + } + if (__GLeeCheckExtension("WGL_ARB_make_current_read", &extensionNames) ) + { + _GLEE_WGL_ARB_make_current_read = GL_TRUE; + __GLeeLink_WGL_ARB_make_current_read(); + } + if (__GLeeCheckExtension("WGL_ARB_pbuffer", &extensionNames) ) + { + _GLEE_WGL_ARB_pbuffer = GL_TRUE; + __GLeeLink_WGL_ARB_pbuffer(); + } + if (__GLeeCheckExtension("WGL_ARB_render_texture", &extensionNames) ) + { + _GLEE_WGL_ARB_render_texture = GL_TRUE; + __GLeeLink_WGL_ARB_render_texture(); + } + if (__GLeeCheckExtension("WGL_ARB_pixel_format_float", &extensionNames) ) + { + _GLEE_WGL_ARB_pixel_format_float = GL_TRUE; + __GLeeLink_WGL_ARB_pixel_format_float(); + } + if (__GLeeCheckExtension("WGL_ARB_create_context", &extensionNames) ) + { + _GLEE_WGL_ARB_create_context = GL_TRUE; + __GLeeLink_WGL_ARB_create_context(); + } + if (__GLeeCheckExtension("WGL_EXT_make_current_read", &extensionNames) ) + { + _GLEE_WGL_EXT_make_current_read = GL_TRUE; + __GLeeLink_WGL_EXT_make_current_read(); + } + if (__GLeeCheckExtension("WGL_EXT_pixel_format", &extensionNames) ) + { + _GLEE_WGL_EXT_pixel_format = GL_TRUE; + __GLeeLink_WGL_EXT_pixel_format(); + } + if (__GLeeCheckExtension("WGL_EXT_pbuffer", &extensionNames) ) + { + _GLEE_WGL_EXT_pbuffer = GL_TRUE; + __GLeeLink_WGL_EXT_pbuffer(); + } + if (__GLeeCheckExtension("WGL_EXT_depth_float", &extensionNames) ) + { + _GLEE_WGL_EXT_depth_float = GL_TRUE; + __GLeeLink_WGL_EXT_depth_float(); + } + if (__GLeeCheckExtension("WGL_3DFX_multisample", &extensionNames) ) + { + _GLEE_WGL_3DFX_multisample = GL_TRUE; + __GLeeLink_WGL_3DFX_multisample(); + } + if (__GLeeCheckExtension("WGL_EXT_multisample", &extensionNames) ) + { + _GLEE_WGL_EXT_multisample = GL_TRUE; + __GLeeLink_WGL_EXT_multisample(); + } + if (__GLeeCheckExtension("WGL_I3D_digital_video_control", &extensionNames) ) + { + _GLEE_WGL_I3D_digital_video_control = GL_TRUE; + __GLeeLink_WGL_I3D_digital_video_control(); + } + if (__GLeeCheckExtension("WGL_I3D_gamma", &extensionNames) ) + { + _GLEE_WGL_I3D_gamma = GL_TRUE; + __GLeeLink_WGL_I3D_gamma(); + } + if (__GLeeCheckExtension("WGL_I3D_genlock", &extensionNames) ) + { + _GLEE_WGL_I3D_genlock = GL_TRUE; + __GLeeLink_WGL_I3D_genlock(); + } + if (__GLeeCheckExtension("WGL_I3D_image_buffer", &extensionNames) ) + { + _GLEE_WGL_I3D_image_buffer = GL_TRUE; + __GLeeLink_WGL_I3D_image_buffer(); + } + if (__GLeeCheckExtension("WGL_I3D_swap_frame_lock", &extensionNames) ) + { + _GLEE_WGL_I3D_swap_frame_lock = GL_TRUE; + __GLeeLink_WGL_I3D_swap_frame_lock(); + } + if (__GLeeCheckExtension("WGL_NV_render_depth_texture", &extensionNames) ) + { + _GLEE_WGL_NV_render_depth_texture = GL_TRUE; + __GLeeLink_WGL_NV_render_depth_texture(); + } + if (__GLeeCheckExtension("WGL_NV_render_texture_rectangle", &extensionNames) ) + { + _GLEE_WGL_NV_render_texture_rectangle = GL_TRUE; + __GLeeLink_WGL_NV_render_texture_rectangle(); + } + if (__GLeeCheckExtension("WGL_ATI_pixel_format_float", &extensionNames) ) + { + _GLEE_WGL_ATI_pixel_format_float = GL_TRUE; + __GLeeLink_WGL_ATI_pixel_format_float(); + } + if (__GLeeCheckExtension("WGL_NV_float_buffer", &extensionNames) ) + { + _GLEE_WGL_NV_float_buffer = GL_TRUE; + __GLeeLink_WGL_NV_float_buffer(); + } + if (__GLeeCheckExtension("WGL_3DL_stereo_control", &extensionNames) ) + { + _GLEE_WGL_3DL_stereo_control = GL_TRUE; + __GLeeLink_WGL_3DL_stereo_control(); + } + if (__GLeeCheckExtension("WGL_EXT_pixel_format_packed_float", &extensionNames) ) + { + _GLEE_WGL_EXT_pixel_format_packed_float = GL_TRUE; + __GLeeLink_WGL_EXT_pixel_format_packed_float(); + } + if (__GLeeCheckExtension("WGL_EXT_framebuffer_sRGB", &extensionNames) ) + { + _GLEE_WGL_EXT_framebuffer_sRGB = GL_TRUE; + __GLeeLink_WGL_EXT_framebuffer_sRGB(); + } + if (__GLeeCheckExtension("WGL_NV_present_video", &extensionNames) ) + { + _GLEE_WGL_NV_present_video = GL_TRUE; + __GLeeLink_WGL_NV_present_video(); + } + if (__GLeeCheckExtension("WGL_NV_swap_group", &extensionNames) ) + { + _GLEE_WGL_NV_swap_group = GL_TRUE; + __GLeeLink_WGL_NV_swap_group(); + } + if (__GLeeCheckExtension("WGL_NV_gpu_affinity", &extensionNames) ) + { + _GLEE_WGL_NV_gpu_affinity = GL_TRUE; + __GLeeLink_WGL_NV_gpu_affinity(); + } + if (__GLeeCheckExtension("WGL_EXT_display_color_table", &extensionNames) ) + { + _GLEE_WGL_EXT_display_color_table = GL_TRUE; + __GLeeLink_WGL_EXT_display_color_table(); + } + if (__GLeeCheckExtension("WGL_EXT_extensions_string", &extensionNames) ) + { + _GLEE_WGL_EXT_extensions_string = GL_TRUE; + __GLeeLink_WGL_EXT_extensions_string(); + } + if (__GLeeCheckExtension("WGL_EXT_swap_control", &extensionNames) ) + { + _GLEE_WGL_EXT_swap_control = GL_TRUE; + __GLeeLink_WGL_EXT_swap_control(); + } + if (__GLeeCheckExtension("WGL_NV_vertex_array_range", &extensionNames) ) + { + _GLEE_WGL_NV_vertex_array_range = GL_TRUE; + __GLeeLink_WGL_NV_vertex_array_range(); + } + if (__GLeeCheckExtension("WGL_OML_sync_control", &extensionNames) ) + { + _GLEE_WGL_OML_sync_control = GL_TRUE; + __GLeeLink_WGL_OML_sync_control(); + } + if (__GLeeCheckExtension("WGL_I3D_swap_frame_usage", &extensionNames) ) + { + _GLEE_WGL_I3D_swap_frame_usage = GL_TRUE; + __GLeeLink_WGL_I3D_swap_frame_usage(); + } + if (__GLeeCheckExtension("WGL_NV_video_output", &extensionNames) ) + { + _GLEE_WGL_NV_video_output = GL_TRUE; + __GLeeLink_WGL_NV_video_output(); + } +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else /* GLX */ + if (__GLeeCheckExtension("GLX_VERSION_1_3", &extensionNames) ) + { + _GLEE_GLX_VERSION_1_3 = GL_TRUE; + __GLeeLink_GLX_VERSION_1_3(); + } + if (__GLeeCheckExtension("GLX_VERSION_1_4", &extensionNames) ) + { + _GLEE_GLX_VERSION_1_4 = GL_TRUE; + __GLeeLink_GLX_VERSION_1_4(); + } + if (__GLeeCheckExtension("GLX_ARB_multisample", &extensionNames) ) + { + _GLEE_GLX_ARB_multisample = GL_TRUE; + __GLeeLink_GLX_ARB_multisample(); + } + if (__GLeeCheckExtension("GLX_ARB_fbconfig_float", &extensionNames) ) + { + _GLEE_GLX_ARB_fbconfig_float = GL_TRUE; + __GLeeLink_GLX_ARB_fbconfig_float(); + } + if (__GLeeCheckExtension("GLX_ARB_create_context", &extensionNames) ) + { + _GLEE_GLX_ARB_create_context = GL_TRUE; + __GLeeLink_GLX_ARB_create_context(); + } + if (__GLeeCheckExtension("GLX_SGIS_multisample", &extensionNames) ) + { + _GLEE_GLX_SGIS_multisample = GL_TRUE; + __GLeeLink_GLX_SGIS_multisample(); + } + if (__GLeeCheckExtension("GLX_EXT_visual_info", &extensionNames) ) + { + _GLEE_GLX_EXT_visual_info = GL_TRUE; + __GLeeLink_GLX_EXT_visual_info(); + } + if (__GLeeCheckExtension("GLX_SGI_swap_control", &extensionNames) ) + { + _GLEE_GLX_SGI_swap_control = GL_TRUE; + __GLeeLink_GLX_SGI_swap_control(); + } + if (__GLeeCheckExtension("GLX_SGI_video_sync", &extensionNames) ) + { + _GLEE_GLX_SGI_video_sync = GL_TRUE; + __GLeeLink_GLX_SGI_video_sync(); + } + if (__GLeeCheckExtension("GLX_SGI_make_current_read", &extensionNames) ) + { + _GLEE_GLX_SGI_make_current_read = GL_TRUE; + __GLeeLink_GLX_SGI_make_current_read(); + } + if (__GLeeCheckExtension("GLX_EXT_visual_rating", &extensionNames) ) + { + _GLEE_GLX_EXT_visual_rating = GL_TRUE; + __GLeeLink_GLX_EXT_visual_rating(); + } + if (__GLeeCheckExtension("GLX_EXT_import_context", &extensionNames) ) + { + _GLEE_GLX_EXT_import_context = GL_TRUE; + __GLeeLink_GLX_EXT_import_context(); + } + if (__GLeeCheckExtension("GLX_SGIX_fbconfig", &extensionNames) ) + { + _GLEE_GLX_SGIX_fbconfig = GL_TRUE; + __GLeeLink_GLX_SGIX_fbconfig(); + } + if (__GLeeCheckExtension("GLX_SGIX_pbuffer", &extensionNames) ) + { + _GLEE_GLX_SGIX_pbuffer = GL_TRUE; + __GLeeLink_GLX_SGIX_pbuffer(); + } + if (__GLeeCheckExtension("GLX_SGI_cushion", &extensionNames) ) + { + _GLEE_GLX_SGI_cushion = GL_TRUE; + __GLeeLink_GLX_SGI_cushion(); + } + if (__GLeeCheckExtension("GLX_SGIX_video_resize", &extensionNames) ) + { + _GLEE_GLX_SGIX_video_resize = GL_TRUE; + __GLeeLink_GLX_SGIX_video_resize(); + } + if (__GLeeCheckExtension("GLX_SGIX_swap_group", &extensionNames) ) + { + _GLEE_GLX_SGIX_swap_group = GL_TRUE; + __GLeeLink_GLX_SGIX_swap_group(); + } + if (__GLeeCheckExtension("GLX_SGIX_swap_barrier", &extensionNames) ) + { + _GLEE_GLX_SGIX_swap_barrier = GL_TRUE; + __GLeeLink_GLX_SGIX_swap_barrier(); + } + if (__GLeeCheckExtension("GLX_SGIS_blended_overlay", &extensionNames) ) + { + _GLEE_GLX_SGIS_blended_overlay = GL_TRUE; + __GLeeLink_GLX_SGIS_blended_overlay(); + } + if (__GLeeCheckExtension("GLX_SGIS_shared_multisample", &extensionNames) ) + { + _GLEE_GLX_SGIS_shared_multisample = GL_TRUE; + __GLeeLink_GLX_SGIS_shared_multisample(); + } + if (__GLeeCheckExtension("GLX_SUN_get_transparent_index", &extensionNames) ) + { + _GLEE_GLX_SUN_get_transparent_index = GL_TRUE; + __GLeeLink_GLX_SUN_get_transparent_index(); + } + if (__GLeeCheckExtension("GLX_3DFX_multisample", &extensionNames) ) + { + _GLEE_GLX_3DFX_multisample = GL_TRUE; + __GLeeLink_GLX_3DFX_multisample(); + } + if (__GLeeCheckExtension("GLX_MESA_copy_sub_buffer", &extensionNames) ) + { + _GLEE_GLX_MESA_copy_sub_buffer = GL_TRUE; + __GLeeLink_GLX_MESA_copy_sub_buffer(); + } + if (__GLeeCheckExtension("GLX_MESA_pixmap_colormap", &extensionNames) ) + { + _GLEE_GLX_MESA_pixmap_colormap = GL_TRUE; + __GLeeLink_GLX_MESA_pixmap_colormap(); + } + if (__GLeeCheckExtension("GLX_MESA_release_buffers", &extensionNames) ) + { + _GLEE_GLX_MESA_release_buffers = GL_TRUE; + __GLeeLink_GLX_MESA_release_buffers(); + } + if (__GLeeCheckExtension("GLX_MESA_set_3dfx_mode", &extensionNames) ) + { + _GLEE_GLX_MESA_set_3dfx_mode = GL_TRUE; + __GLeeLink_GLX_MESA_set_3dfx_mode(); + } + if (__GLeeCheckExtension("GLX_SGIX_visual_select_group", &extensionNames) ) + { + _GLEE_GLX_SGIX_visual_select_group = GL_TRUE; + __GLeeLink_GLX_SGIX_visual_select_group(); + } + if (__GLeeCheckExtension("GLX_OML_swap_method", &extensionNames) ) + { + _GLEE_GLX_OML_swap_method = GL_TRUE; + __GLeeLink_GLX_OML_swap_method(); + } + if (__GLeeCheckExtension("GLX_OML_sync_control", &extensionNames) ) + { + _GLEE_GLX_OML_sync_control = GL_TRUE; + __GLeeLink_GLX_OML_sync_control(); + } + if (__GLeeCheckExtension("GLX_NV_float_buffer", &extensionNames) ) + { + _GLEE_GLX_NV_float_buffer = GL_TRUE; + __GLeeLink_GLX_NV_float_buffer(); + } + if (__GLeeCheckExtension("GLX_SGIX_hyperpipe", &extensionNames) ) + { + _GLEE_GLX_SGIX_hyperpipe = GL_TRUE; + __GLeeLink_GLX_SGIX_hyperpipe(); + } + if (__GLeeCheckExtension("GLX_MESA_agp_offset", &extensionNames) ) + { + _GLEE_GLX_MESA_agp_offset = GL_TRUE; + __GLeeLink_GLX_MESA_agp_offset(); + } + if (__GLeeCheckExtension("GLX_EXT_fbconfig_packed_float", &extensionNames) ) + { + _GLEE_GLX_EXT_fbconfig_packed_float = GL_TRUE; + __GLeeLink_GLX_EXT_fbconfig_packed_float(); + } + if (__GLeeCheckExtension("GLX_EXT_framebuffer_sRGB", &extensionNames) ) + { + _GLEE_GLX_EXT_framebuffer_sRGB = GL_TRUE; + __GLeeLink_GLX_EXT_framebuffer_sRGB(); + } + if (__GLeeCheckExtension("GLX_EXT_texture_from_pixmap", &extensionNames) ) + { + _GLEE_GLX_EXT_texture_from_pixmap = GL_TRUE; + __GLeeLink_GLX_EXT_texture_from_pixmap(); + } + if (__GLeeCheckExtension("GLX_NV_present_video", &extensionNames) ) + { + _GLEE_GLX_NV_present_video = GL_TRUE; + __GLeeLink_GLX_NV_present_video(); + } + if (__GLeeCheckExtension("GLX_NV_video_out", &extensionNames) ) + { + _GLEE_GLX_NV_video_out = GL_TRUE; + __GLeeLink_GLX_NV_video_out(); + } + if (__GLeeCheckExtension("GLX_NV_swap_group", &extensionNames) ) + { + _GLEE_GLX_NV_swap_group = GL_TRUE; + __GLeeLink_GLX_NV_swap_group(); + } + if (__GLeeCheckExtension("GLX_EXT_scene_marker", &extensionNames) ) + { + _GLEE_GLX_EXT_scene_marker = GL_TRUE; + __GLeeLink_GLX_EXT_scene_marker(); + } + if (__GLeeCheckExtension("GLX_NV_video_output", &extensionNames) ) + { + _GLEE_GLX_NV_video_output = GL_TRUE; + __GLeeLink_GLX_NV_video_output(); + } +#endif /* end GLX */ + + __GLeeExtList_clean(&extensionNames); + return GL_TRUE; +} diff --git a/Extras/sph/common/GLee.h b/Extras/sph/common/GLee.h new file mode 100644 index 0000000..8987d24 --- /dev/null +++ b/Extras/sph/common/GLee.h @@ -0,0 +1,17647 @@ +/*************************************************************************** +* +* GLee.h +* GLee (OpenGL Easy Extension library) +* Version : 5.4 +* +* Copyright (c)2009 Ben Woodhouse All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer as +* the first lines of this file unmodified. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BEN WOODHOUSE ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL BEN WOODHOUSE BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +* Web: http://elf-stone.com/glee.php +* +* [This file was automatically generated by GLeeGen 7.0 +* +***************************************************************************/ + +#ifndef __glee_h_ +#define __glee_h_ + +#ifdef __gl_h_ + #error gl.h included before glee.h +#endif + +#ifdef __glext_h_ + #error glext.h included before glee.h +#endif + +#ifdef __wglext_h_ + #error wglext.h included before glee.h +#endif + +#ifdef __glxext_h_ + #error glxext.h included before glee.h +#endif + +#ifdef WIN32 + #define WIN32_LEAN_AND_MEAN + #include + #include +#elif defined(__APPLE__) || defined(__APPLE_CC__) + #define GL_GLEXT_LEGACY + #include +#else // GLX + #define __glext_h_ /* prevent glext.h from being included */ + #define __glxext_h_ /* prevent glxext.h from being included */ + #define GLX_GLXEXT_PROTOTYPES + #include + #include +#endif + +#ifndef APIENTRY + #define APIENTRY +#endif + +#ifndef APIENTRYP + #define APIENTRYP APIENTRY * +#endif + +#define GLEE_EXTERN extern + +#ifdef __cplusplus + extern "C" { /* begin C linkage */ +#endif + +#define GLEE_LINK_FAIL 0 +#define GLEE_LINK_PARTIAL 1 +#define GLEE_LINK_COMPLETE 2 + +/* Extension querying variables */ + +GLEE_EXTERN GLboolean _GLEE_VERSION_1_2; +GLEE_EXTERN GLboolean _GLEE_ARB_imaging; +GLEE_EXTERN GLboolean _GLEE_VERSION_1_3; +GLEE_EXTERN GLboolean _GLEE_VERSION_1_4; +GLEE_EXTERN GLboolean _GLEE_VERSION_1_5; +GLEE_EXTERN GLboolean _GLEE_VERSION_2_0; +GLEE_EXTERN GLboolean _GLEE_VERSION_2_1; +GLEE_EXTERN GLboolean _GLEE_VERSION_3_0; +GLEE_EXTERN GLboolean _GLEE_ARB_multitexture; +GLEE_EXTERN GLboolean _GLEE_ARB_transpose_matrix; +GLEE_EXTERN GLboolean _GLEE_ARB_multisample; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_env_add; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_cube_map; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_compression; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_border_clamp; +GLEE_EXTERN GLboolean _GLEE_ARB_point_parameters; +GLEE_EXTERN GLboolean _GLEE_ARB_vertex_blend; +GLEE_EXTERN GLboolean _GLEE_ARB_matrix_palette; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_env_combine; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_env_crossbar; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_env_dot3; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_mirrored_repeat; +GLEE_EXTERN GLboolean _GLEE_ARB_depth_texture; +GLEE_EXTERN GLboolean _GLEE_ARB_shadow; +GLEE_EXTERN GLboolean _GLEE_ARB_shadow_ambient; +GLEE_EXTERN GLboolean _GLEE_ARB_window_pos; +GLEE_EXTERN GLboolean _GLEE_ARB_vertex_program; +GLEE_EXTERN GLboolean _GLEE_ARB_fragment_program; +GLEE_EXTERN GLboolean _GLEE_ARB_vertex_buffer_object; +GLEE_EXTERN GLboolean _GLEE_ARB_occlusion_query; +GLEE_EXTERN GLboolean _GLEE_ARB_shader_objects; +GLEE_EXTERN GLboolean _GLEE_ARB_vertex_shader; +GLEE_EXTERN GLboolean _GLEE_ARB_fragment_shader; +GLEE_EXTERN GLboolean _GLEE_ARB_shading_language_100; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_non_power_of_two; +GLEE_EXTERN GLboolean _GLEE_ARB_point_sprite; +GLEE_EXTERN GLboolean _GLEE_ARB_fragment_program_shadow; +GLEE_EXTERN GLboolean _GLEE_ARB_draw_buffers; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_rectangle; +GLEE_EXTERN GLboolean _GLEE_ARB_color_buffer_float; +GLEE_EXTERN GLboolean _GLEE_ARB_half_float_pixel; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_float; +GLEE_EXTERN GLboolean _GLEE_ARB_pixel_buffer_object; +GLEE_EXTERN GLboolean _GLEE_ARB_depth_buffer_float; +GLEE_EXTERN GLboolean _GLEE_ARB_draw_instanced; +GLEE_EXTERN GLboolean _GLEE_ARB_framebuffer_object; +GLEE_EXTERN GLboolean _GLEE_ARB_framebuffer_sRGB; +GLEE_EXTERN GLboolean _GLEE_ARB_geometry_shader4; +GLEE_EXTERN GLboolean _GLEE_ARB_half_float_vertex; +GLEE_EXTERN GLboolean _GLEE_ARB_instanced_arrays; +GLEE_EXTERN GLboolean _GLEE_ARB_map_buffer_range; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_buffer_object; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_compression_rgtc; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_rg; +GLEE_EXTERN GLboolean _GLEE_ARB_vertex_array_object; +GLEE_EXTERN GLboolean _GLEE_EXT_abgr; +GLEE_EXTERN GLboolean _GLEE_EXT_blend_color; +GLEE_EXTERN GLboolean _GLEE_EXT_polygon_offset; +GLEE_EXTERN GLboolean _GLEE_EXT_texture; +GLEE_EXTERN GLboolean _GLEE_EXT_texture3D; +GLEE_EXTERN GLboolean _GLEE_SGIS_texture_filter4; +GLEE_EXTERN GLboolean _GLEE_EXT_subtexture; +GLEE_EXTERN GLboolean _GLEE_EXT_copy_texture; +GLEE_EXTERN GLboolean _GLEE_EXT_histogram; +GLEE_EXTERN GLboolean _GLEE_EXT_convolution; +GLEE_EXTERN GLboolean _GLEE_SGI_color_matrix; +GLEE_EXTERN GLboolean _GLEE_SGI_color_table; +GLEE_EXTERN GLboolean _GLEE_SGIS_pixel_texture; +GLEE_EXTERN GLboolean _GLEE_SGIX_pixel_texture; +GLEE_EXTERN GLboolean _GLEE_SGIS_texture4D; +GLEE_EXTERN GLboolean _GLEE_SGI_texture_color_table; +GLEE_EXTERN GLboolean _GLEE_EXT_cmyka; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_object; +GLEE_EXTERN GLboolean _GLEE_SGIS_detail_texture; +GLEE_EXTERN GLboolean _GLEE_SGIS_sharpen_texture; +GLEE_EXTERN GLboolean _GLEE_EXT_packed_pixels; +GLEE_EXTERN GLboolean _GLEE_SGIS_texture_lod; +GLEE_EXTERN GLboolean _GLEE_SGIS_multisample; +GLEE_EXTERN GLboolean _GLEE_EXT_rescale_normal; +GLEE_EXTERN GLboolean _GLEE_EXT_vertex_array; +GLEE_EXTERN GLboolean _GLEE_EXT_misc_attribute; +GLEE_EXTERN GLboolean _GLEE_SGIS_generate_mipmap; +GLEE_EXTERN GLboolean _GLEE_SGIX_clipmap; +GLEE_EXTERN GLboolean _GLEE_SGIX_shadow; +GLEE_EXTERN GLboolean _GLEE_SGIS_texture_edge_clamp; +GLEE_EXTERN GLboolean _GLEE_SGIS_texture_border_clamp; +GLEE_EXTERN GLboolean _GLEE_EXT_blend_minmax; +GLEE_EXTERN GLboolean _GLEE_EXT_blend_subtract; +GLEE_EXTERN GLboolean _GLEE_EXT_blend_logic_op; +GLEE_EXTERN GLboolean _GLEE_SGIX_interlace; +GLEE_EXTERN GLboolean _GLEE_SGIX_pixel_tiles; +GLEE_EXTERN GLboolean _GLEE_SGIS_texture_select; +GLEE_EXTERN GLboolean _GLEE_SGIX_sprite; +GLEE_EXTERN GLboolean _GLEE_SGIX_texture_multi_buffer; +GLEE_EXTERN GLboolean _GLEE_EXT_point_parameters; +GLEE_EXTERN GLboolean _GLEE_SGIS_point_parameters; +GLEE_EXTERN GLboolean _GLEE_SGIX_instruments; +GLEE_EXTERN GLboolean _GLEE_SGIX_texture_scale_bias; +GLEE_EXTERN GLboolean _GLEE_SGIX_framezoom; +GLEE_EXTERN GLboolean _GLEE_SGIX_tag_sample_buffer; +GLEE_EXTERN GLboolean _GLEE_FfdMaskSGIX; +GLEE_EXTERN GLboolean _GLEE_SGIX_polynomial_ffd; +GLEE_EXTERN GLboolean _GLEE_SGIX_reference_plane; +GLEE_EXTERN GLboolean _GLEE_SGIX_flush_raster; +GLEE_EXTERN GLboolean _GLEE_SGIX_depth_texture; +GLEE_EXTERN GLboolean _GLEE_SGIS_fog_function; +GLEE_EXTERN GLboolean _GLEE_SGIX_fog_offset; +GLEE_EXTERN GLboolean _GLEE_HP_image_transform; +GLEE_EXTERN GLboolean _GLEE_HP_convolution_border_modes; +GLEE_EXTERN GLboolean _GLEE_INGR_palette_buffer; +GLEE_EXTERN GLboolean _GLEE_SGIX_texture_add_env; +GLEE_EXTERN GLboolean _GLEE_EXT_color_subtable; +GLEE_EXTERN GLboolean _GLEE_PGI_vertex_hints; +GLEE_EXTERN GLboolean _GLEE_PGI_misc_hints; +GLEE_EXTERN GLboolean _GLEE_EXT_paletted_texture; +GLEE_EXTERN GLboolean _GLEE_EXT_clip_volume_hint; +GLEE_EXTERN GLboolean _GLEE_SGIX_list_priority; +GLEE_EXTERN GLboolean _GLEE_SGIX_ir_instrument1; +GLEE_EXTERN GLboolean _GLEE_SGIX_calligraphic_fragment; +GLEE_EXTERN GLboolean _GLEE_SGIX_texture_lod_bias; +GLEE_EXTERN GLboolean _GLEE_SGIX_shadow_ambient; +GLEE_EXTERN GLboolean _GLEE_EXT_index_texture; +GLEE_EXTERN GLboolean _GLEE_EXT_index_material; +GLEE_EXTERN GLboolean _GLEE_EXT_index_func; +GLEE_EXTERN GLboolean _GLEE_EXT_index_array_formats; +GLEE_EXTERN GLboolean _GLEE_EXT_compiled_vertex_array; +GLEE_EXTERN GLboolean _GLEE_EXT_cull_vertex; +GLEE_EXTERN GLboolean _GLEE_SGIX_ycrcb; +GLEE_EXTERN GLboolean _GLEE_SGIX_fragment_lighting; +GLEE_EXTERN GLboolean _GLEE_IBM_rasterpos_clip; +GLEE_EXTERN GLboolean _GLEE_HP_texture_lighting; +GLEE_EXTERN GLboolean _GLEE_EXT_draw_range_elements; +GLEE_EXTERN GLboolean _GLEE_WIN_phong_shading; +GLEE_EXTERN GLboolean _GLEE_WIN_specular_fog; +GLEE_EXTERN GLboolean _GLEE_EXT_light_texture; +GLEE_EXTERN GLboolean _GLEE_SGIX_blend_alpha_minmax; +GLEE_EXTERN GLboolean _GLEE_SGIX_impact_pixel_texture; +GLEE_EXTERN GLboolean _GLEE_EXT_bgra; +GLEE_EXTERN GLboolean _GLEE_SGIX_async; +GLEE_EXTERN GLboolean _GLEE_SGIX_async_pixel; +GLEE_EXTERN GLboolean _GLEE_SGIX_async_histogram; +GLEE_EXTERN GLboolean _GLEE_INTEL_texture_scissor; +GLEE_EXTERN GLboolean _GLEE_INTEL_parallel_arrays; +GLEE_EXTERN GLboolean _GLEE_HP_occlusion_test; +GLEE_EXTERN GLboolean _GLEE_EXT_pixel_transform; +GLEE_EXTERN GLboolean _GLEE_EXT_pixel_transform_color_table; +GLEE_EXTERN GLboolean _GLEE_EXT_shared_texture_palette; +GLEE_EXTERN GLboolean _GLEE_EXT_separate_specular_color; +GLEE_EXTERN GLboolean _GLEE_EXT_secondary_color; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_perturb_normal; +GLEE_EXTERN GLboolean _GLEE_EXT_multi_draw_arrays; +GLEE_EXTERN GLboolean _GLEE_EXT_fog_coord; +GLEE_EXTERN GLboolean _GLEE_REND_screen_coordinates; +GLEE_EXTERN GLboolean _GLEE_EXT_coordinate_frame; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_env_combine; +GLEE_EXTERN GLboolean _GLEE_APPLE_specular_vector; +GLEE_EXTERN GLboolean _GLEE_APPLE_transform_hint; +GLEE_EXTERN GLboolean _GLEE_SGIX_fog_scale; +GLEE_EXTERN GLboolean _GLEE_SUNX_constant_data; +GLEE_EXTERN GLboolean _GLEE_SUN_global_alpha; +GLEE_EXTERN GLboolean _GLEE_SUN_triangle_list; +GLEE_EXTERN GLboolean _GLEE_SUN_vertex; +GLEE_EXTERN GLboolean _GLEE_EXT_blend_func_separate; +GLEE_EXTERN GLboolean _GLEE_INGR_color_clamp; +GLEE_EXTERN GLboolean _GLEE_INGR_interlace_read; +GLEE_EXTERN GLboolean _GLEE_EXT_stencil_wrap; +GLEE_EXTERN GLboolean _GLEE_EXT_422_pixels; +GLEE_EXTERN GLboolean _GLEE_NV_texgen_reflection; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_cube_map; +GLEE_EXTERN GLboolean _GLEE_SUN_convolution_border_modes; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_env_add; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_lod_bias; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_filter_anisotropic; +GLEE_EXTERN GLboolean _GLEE_EXT_vertex_weighting; +GLEE_EXTERN GLboolean _GLEE_NV_light_max_exponent; +GLEE_EXTERN GLboolean _GLEE_NV_vertex_array_range; +GLEE_EXTERN GLboolean _GLEE_NV_register_combiners; +GLEE_EXTERN GLboolean _GLEE_NV_fog_distance; +GLEE_EXTERN GLboolean _GLEE_NV_texgen_emboss; +GLEE_EXTERN GLboolean _GLEE_NV_blend_square; +GLEE_EXTERN GLboolean _GLEE_NV_texture_env_combine4; +GLEE_EXTERN GLboolean _GLEE_MESA_resize_buffers; +GLEE_EXTERN GLboolean _GLEE_MESA_window_pos; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_compression_s3tc; +GLEE_EXTERN GLboolean _GLEE_IBM_cull_vertex; +GLEE_EXTERN GLboolean _GLEE_IBM_multimode_draw_arrays; +GLEE_EXTERN GLboolean _GLEE_IBM_vertex_array_lists; +GLEE_EXTERN GLboolean _GLEE_SGIX_subsample; +GLEE_EXTERN GLboolean _GLEE_SGIX_ycrcb_subsample; +GLEE_EXTERN GLboolean _GLEE_SGIX_ycrcba; +GLEE_EXTERN GLboolean _GLEE_SGI_depth_pass_instrument; +GLEE_EXTERN GLboolean _GLEE_3DFX_texture_compression_FXT1; +GLEE_EXTERN GLboolean _GLEE_3DFX_multisample; +GLEE_EXTERN GLboolean _GLEE_3DFX_tbuffer; +GLEE_EXTERN GLboolean _GLEE_EXT_multisample; +GLEE_EXTERN GLboolean _GLEE_SGIX_vertex_preclip; +GLEE_EXTERN GLboolean _GLEE_SGIX_convolution_accuracy; +GLEE_EXTERN GLboolean _GLEE_SGIX_resample; +GLEE_EXTERN GLboolean _GLEE_SGIS_point_line_texgen; +GLEE_EXTERN GLboolean _GLEE_SGIS_texture_color_mask; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_env_dot3; +GLEE_EXTERN GLboolean _GLEE_ATI_texture_mirror_once; +GLEE_EXTERN GLboolean _GLEE_NV_fence; +GLEE_EXTERN GLboolean _GLEE_IBM_texture_mirrored_repeat; +GLEE_EXTERN GLboolean _GLEE_NV_evaluators; +GLEE_EXTERN GLboolean _GLEE_NV_packed_depth_stencil; +GLEE_EXTERN GLboolean _GLEE_NV_register_combiners2; +GLEE_EXTERN GLboolean _GLEE_NV_texture_compression_vtc; +GLEE_EXTERN GLboolean _GLEE_NV_texture_rectangle; +GLEE_EXTERN GLboolean _GLEE_NV_texture_shader; +GLEE_EXTERN GLboolean _GLEE_NV_texture_shader2; +GLEE_EXTERN GLboolean _GLEE_NV_vertex_array_range2; +GLEE_EXTERN GLboolean _GLEE_NV_vertex_program; +GLEE_EXTERN GLboolean _GLEE_SGIX_texture_coordinate_clamp; +GLEE_EXTERN GLboolean _GLEE_SGIX_scalebias_hint; +GLEE_EXTERN GLboolean _GLEE_OML_interlace; +GLEE_EXTERN GLboolean _GLEE_OML_subsample; +GLEE_EXTERN GLboolean _GLEE_OML_resample; +GLEE_EXTERN GLboolean _GLEE_NV_copy_depth_to_color; +GLEE_EXTERN GLboolean _GLEE_ATI_envmap_bumpmap; +GLEE_EXTERN GLboolean _GLEE_ATI_fragment_shader; +GLEE_EXTERN GLboolean _GLEE_ATI_pn_triangles; +GLEE_EXTERN GLboolean _GLEE_ATI_vertex_array_object; +GLEE_EXTERN GLboolean _GLEE_EXT_vertex_shader; +GLEE_EXTERN GLboolean _GLEE_ATI_vertex_streams; +GLEE_EXTERN GLboolean _GLEE_ATI_element_array; +GLEE_EXTERN GLboolean _GLEE_SUN_mesh_array; +GLEE_EXTERN GLboolean _GLEE_SUN_slice_accum; +GLEE_EXTERN GLboolean _GLEE_NV_multisample_filter_hint; +GLEE_EXTERN GLboolean _GLEE_NV_depth_clamp; +GLEE_EXTERN GLboolean _GLEE_NV_occlusion_query; +GLEE_EXTERN GLboolean _GLEE_NV_point_sprite; +GLEE_EXTERN GLboolean _GLEE_NV_texture_shader3; +GLEE_EXTERN GLboolean _GLEE_NV_vertex_program1_1; +GLEE_EXTERN GLboolean _GLEE_EXT_shadow_funcs; +GLEE_EXTERN GLboolean _GLEE_EXT_stencil_two_side; +GLEE_EXTERN GLboolean _GLEE_ATI_text_fragment_shader; +GLEE_EXTERN GLboolean _GLEE_APPLE_client_storage; +GLEE_EXTERN GLboolean _GLEE_APPLE_element_array; +GLEE_EXTERN GLboolean _GLEE_APPLE_fence; +GLEE_EXTERN GLboolean _GLEE_APPLE_vertex_array_object; +GLEE_EXTERN GLboolean _GLEE_APPLE_vertex_array_range; +GLEE_EXTERN GLboolean _GLEE_APPLE_ycbcr_422; +GLEE_EXTERN GLboolean _GLEE_S3_s3tc; +GLEE_EXTERN GLboolean _GLEE_ATI_draw_buffers; +GLEE_EXTERN GLboolean _GLEE_ATI_pixel_format_float; +GLEE_EXTERN GLboolean _GLEE_ATI_texture_env_combine3; +GLEE_EXTERN GLboolean _GLEE_ATI_texture_float; +GLEE_EXTERN GLboolean _GLEE_NV_float_buffer; +GLEE_EXTERN GLboolean _GLEE_NV_fragment_program; +GLEE_EXTERN GLboolean _GLEE_NV_half_float; +GLEE_EXTERN GLboolean _GLEE_NV_pixel_data_range; +GLEE_EXTERN GLboolean _GLEE_NV_primitive_restart; +GLEE_EXTERN GLboolean _GLEE_NV_texture_expand_normal; +GLEE_EXTERN GLboolean _GLEE_NV_vertex_program2; +GLEE_EXTERN GLboolean _GLEE_ATI_map_object_buffer; +GLEE_EXTERN GLboolean _GLEE_ATI_separate_stencil; +GLEE_EXTERN GLboolean _GLEE_ATI_vertex_attrib_array_object; +GLEE_EXTERN GLboolean _GLEE_OES_read_format; +GLEE_EXTERN GLboolean _GLEE_EXT_depth_bounds_test; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_mirror_clamp; +GLEE_EXTERN GLboolean _GLEE_EXT_blend_equation_separate; +GLEE_EXTERN GLboolean _GLEE_MESA_pack_invert; +GLEE_EXTERN GLboolean _GLEE_MESA_ycbcr_texture; +GLEE_EXTERN GLboolean _GLEE_EXT_pixel_buffer_object; +GLEE_EXTERN GLboolean _GLEE_NV_fragment_program_option; +GLEE_EXTERN GLboolean _GLEE_NV_fragment_program2; +GLEE_EXTERN GLboolean _GLEE_NV_vertex_program2_option; +GLEE_EXTERN GLboolean _GLEE_NV_vertex_program3; +GLEE_EXTERN GLboolean _GLEE_EXT_framebuffer_object; +GLEE_EXTERN GLboolean _GLEE_GREMEDY_string_marker; +GLEE_EXTERN GLboolean _GLEE_EXT_packed_depth_stencil; +GLEE_EXTERN GLboolean _GLEE_EXT_stencil_clear_tag; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_sRGB; +GLEE_EXTERN GLboolean _GLEE_EXT_framebuffer_blit; +GLEE_EXTERN GLboolean _GLEE_EXT_framebuffer_multisample; +GLEE_EXTERN GLboolean _GLEE_MESAX_texture_stack; +GLEE_EXTERN GLboolean _GLEE_EXT_timer_query; +GLEE_EXTERN GLboolean _GLEE_EXT_gpu_program_parameters; +GLEE_EXTERN GLboolean _GLEE_APPLE_flush_buffer_range; +GLEE_EXTERN GLboolean _GLEE_EXT_gpu_shader4; +GLEE_EXTERN GLboolean _GLEE_EXT_draw_instanced; +GLEE_EXTERN GLboolean _GLEE_EXT_packed_float; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_array; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_buffer_object; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_compression_latc; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_compression_rgtc; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_shared_exponent; +GLEE_EXTERN GLboolean _GLEE_NV_depth_buffer_float; +GLEE_EXTERN GLboolean _GLEE_NV_framebuffer_multisample_coverage; +GLEE_EXTERN GLboolean _GLEE_EXT_framebuffer_sRGB; +GLEE_EXTERN GLboolean _GLEE_NV_geometry_shader4; +GLEE_EXTERN GLboolean _GLEE_NV_parameter_buffer_object; +GLEE_EXTERN GLboolean _GLEE_EXT_draw_buffers2; +GLEE_EXTERN GLboolean _GLEE_NV_transform_feedback; +GLEE_EXTERN GLboolean _GLEE_EXT_bindable_uniform; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_integer; +GLEE_EXTERN GLboolean _GLEE_GREMEDY_frame_terminator; +GLEE_EXTERN GLboolean _GLEE_NV_conditional_render; +GLEE_EXTERN GLboolean _GLEE_NV_present_video; +GLEE_EXTERN GLboolean _GLEE_EXT_transform_feedback; +GLEE_EXTERN GLboolean _GLEE_EXT_direct_state_access; +GLEE_EXTERN GLboolean _GLEE_EXT_vertex_array_bgra; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_swizzle; +GLEE_EXTERN GLboolean _GLEE_NV_explicit_multisample; +GLEE_EXTERN GLboolean _GLEE_NV_transform_feedback2; +GLEE_EXTERN GLboolean _GLEE_SGIX_texture_select; +GLEE_EXTERN GLboolean _GLEE_INGR_blend_func_separate; +GLEE_EXTERN GLboolean _GLEE_SGIX_depth_pass_instrument; +GLEE_EXTERN GLboolean _GLEE_SGIX_igloo_interface; +GLEE_EXTERN GLboolean _GLEE_EXT_fragment_lighting; +GLEE_EXTERN GLboolean _GLEE_EXT_geometry_shader4; +GLEE_EXTERN GLboolean _GLEE_EXT_scene_marker; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_compression_dxt1; +GLEE_EXTERN GLboolean _GLEE_EXT_texture_env; +GLEE_EXTERN GLboolean _GLEE_IBM_static_data; +GLEE_EXTERN GLboolean _GLEE_NV_gpu_program4; +GLEE_EXTERN GLboolean _GLEE_OES_byte_coordinates; +GLEE_EXTERN GLboolean _GLEE_OES_compressed_paletted_texture; +GLEE_EXTERN GLboolean _GLEE_OES_single_precision; +GLEE_EXTERN GLboolean _GLEE_SGIX_pixel_texture_bits; +GLEE_EXTERN GLboolean _GLEE_SGIX_texture_range; + +/* Aliases for extension querying variables */ + +#define GLEE_VERSION_1_2 GLeeEnabled(&_GLEE_VERSION_1_2) +#define GLEE_ARB_imaging GLeeEnabled(&_GLEE_ARB_imaging) +#define GLEE_VERSION_1_3 GLeeEnabled(&_GLEE_VERSION_1_3) +#define GLEE_VERSION_1_4 GLeeEnabled(&_GLEE_VERSION_1_4) +#define GLEE_VERSION_1_5 GLeeEnabled(&_GLEE_VERSION_1_5) +#define GLEE_VERSION_2_0 GLeeEnabled(&_GLEE_VERSION_2_0) +#define GLEE_VERSION_2_1 GLeeEnabled(&_GLEE_VERSION_2_1) +#define GLEE_VERSION_3_0 GLeeEnabled(&_GLEE_VERSION_3_0) +#define GLEE_ARB_multitexture GLeeEnabled(&_GLEE_ARB_multitexture) +#define GLEE_ARB_transpose_matrix GLeeEnabled(&_GLEE_ARB_transpose_matrix) +#define GLEE_ARB_multisample GLeeEnabled(&_GLEE_ARB_multisample) +#define GLEE_ARB_texture_env_add GLeeEnabled(&_GLEE_ARB_texture_env_add) +#define GLEE_ARB_texture_cube_map GLeeEnabled(&_GLEE_ARB_texture_cube_map) +#define GLEE_ARB_texture_compression GLeeEnabled(&_GLEE_ARB_texture_compression) +#define GLEE_ARB_texture_border_clamp GLeeEnabled(&_GLEE_ARB_texture_border_clamp) +#define GLEE_ARB_point_parameters GLeeEnabled(&_GLEE_ARB_point_parameters) +#define GLEE_ARB_vertex_blend GLeeEnabled(&_GLEE_ARB_vertex_blend) +#define GLEE_ARB_matrix_palette GLeeEnabled(&_GLEE_ARB_matrix_palette) +#define GLEE_ARB_texture_env_combine GLeeEnabled(&_GLEE_ARB_texture_env_combine) +#define GLEE_ARB_texture_env_crossbar GLeeEnabled(&_GLEE_ARB_texture_env_crossbar) +#define GLEE_ARB_texture_env_dot3 GLeeEnabled(&_GLEE_ARB_texture_env_dot3) +#define GLEE_ARB_texture_mirrored_repeat GLeeEnabled(&_GLEE_ARB_texture_mirrored_repeat) +#define GLEE_ARB_depth_texture GLeeEnabled(&_GLEE_ARB_depth_texture) +#define GLEE_ARB_shadow GLeeEnabled(&_GLEE_ARB_shadow) +#define GLEE_ARB_shadow_ambient GLeeEnabled(&_GLEE_ARB_shadow_ambient) +#define GLEE_ARB_window_pos GLeeEnabled(&_GLEE_ARB_window_pos) +#define GLEE_ARB_vertex_program GLeeEnabled(&_GLEE_ARB_vertex_program) +#define GLEE_ARB_fragment_program GLeeEnabled(&_GLEE_ARB_fragment_program) +#define GLEE_ARB_vertex_buffer_object GLeeEnabled(&_GLEE_ARB_vertex_buffer_object) +#define GLEE_ARB_occlusion_query GLeeEnabled(&_GLEE_ARB_occlusion_query) +#define GLEE_ARB_shader_objects GLeeEnabled(&_GLEE_ARB_shader_objects) +#define GLEE_ARB_vertex_shader GLeeEnabled(&_GLEE_ARB_vertex_shader) +#define GLEE_ARB_fragment_shader GLeeEnabled(&_GLEE_ARB_fragment_shader) +#define GLEE_ARB_shading_language_100 GLeeEnabled(&_GLEE_ARB_shading_language_100) +#define GLEE_ARB_texture_non_power_of_two GLeeEnabled(&_GLEE_ARB_texture_non_power_of_two) +#define GLEE_ARB_point_sprite GLeeEnabled(&_GLEE_ARB_point_sprite) +#define GLEE_ARB_fragment_program_shadow GLeeEnabled(&_GLEE_ARB_fragment_program_shadow) +#define GLEE_ARB_draw_buffers GLeeEnabled(&_GLEE_ARB_draw_buffers) +#define GLEE_ARB_texture_rectangle GLeeEnabled(&_GLEE_ARB_texture_rectangle) +#define GLEE_ARB_color_buffer_float GLeeEnabled(&_GLEE_ARB_color_buffer_float) +#define GLEE_ARB_half_float_pixel GLeeEnabled(&_GLEE_ARB_half_float_pixel) +#define GLEE_ARB_texture_float GLeeEnabled(&_GLEE_ARB_texture_float) +#define GLEE_ARB_pixel_buffer_object GLeeEnabled(&_GLEE_ARB_pixel_buffer_object) +#define GLEE_ARB_depth_buffer_float GLeeEnabled(&_GLEE_ARB_depth_buffer_float) +#define GLEE_ARB_draw_instanced GLeeEnabled(&_GLEE_ARB_draw_instanced) +#define GLEE_ARB_framebuffer_object GLeeEnabled(&_GLEE_ARB_framebuffer_object) +#define GLEE_ARB_framebuffer_sRGB GLeeEnabled(&_GLEE_ARB_framebuffer_sRGB) +#define GLEE_ARB_geometry_shader4 GLeeEnabled(&_GLEE_ARB_geometry_shader4) +#define GLEE_ARB_half_float_vertex GLeeEnabled(&_GLEE_ARB_half_float_vertex) +#define GLEE_ARB_instanced_arrays GLeeEnabled(&_GLEE_ARB_instanced_arrays) +#define GLEE_ARB_map_buffer_range GLeeEnabled(&_GLEE_ARB_map_buffer_range) +#define GLEE_ARB_texture_buffer_object GLeeEnabled(&_GLEE_ARB_texture_buffer_object) +#define GLEE_ARB_texture_compression_rgtc GLeeEnabled(&_GLEE_ARB_texture_compression_rgtc) +#define GLEE_ARB_texture_rg GLeeEnabled(&_GLEE_ARB_texture_rg) +#define GLEE_ARB_vertex_array_object GLeeEnabled(&_GLEE_ARB_vertex_array_object) +#define GLEE_EXT_abgr GLeeEnabled(&_GLEE_EXT_abgr) +#define GLEE_EXT_blend_color GLeeEnabled(&_GLEE_EXT_blend_color) +#define GLEE_EXT_polygon_offset GLeeEnabled(&_GLEE_EXT_polygon_offset) +#define GLEE_EXT_texture GLeeEnabled(&_GLEE_EXT_texture) +#define GLEE_EXT_texture3D GLeeEnabled(&_GLEE_EXT_texture3D) +#define GLEE_SGIS_texture_filter4 GLeeEnabled(&_GLEE_SGIS_texture_filter4) +#define GLEE_EXT_subtexture GLeeEnabled(&_GLEE_EXT_subtexture) +#define GLEE_EXT_copy_texture GLeeEnabled(&_GLEE_EXT_copy_texture) +#define GLEE_EXT_histogram GLeeEnabled(&_GLEE_EXT_histogram) +#define GLEE_EXT_convolution GLeeEnabled(&_GLEE_EXT_convolution) +#define GLEE_SGI_color_matrix GLeeEnabled(&_GLEE_SGI_color_matrix) +#define GLEE_SGI_color_table GLeeEnabled(&_GLEE_SGI_color_table) +#define GLEE_SGIS_pixel_texture GLeeEnabled(&_GLEE_SGIS_pixel_texture) +#define GLEE_SGIX_pixel_texture GLeeEnabled(&_GLEE_SGIX_pixel_texture) +#define GLEE_SGIS_texture4D GLeeEnabled(&_GLEE_SGIS_texture4D) +#define GLEE_SGI_texture_color_table GLeeEnabled(&_GLEE_SGI_texture_color_table) +#define GLEE_EXT_cmyka GLeeEnabled(&_GLEE_EXT_cmyka) +#define GLEE_EXT_texture_object GLeeEnabled(&_GLEE_EXT_texture_object) +#define GLEE_SGIS_detail_texture GLeeEnabled(&_GLEE_SGIS_detail_texture) +#define GLEE_SGIS_sharpen_texture GLeeEnabled(&_GLEE_SGIS_sharpen_texture) +#define GLEE_EXT_packed_pixels GLeeEnabled(&_GLEE_EXT_packed_pixels) +#define GLEE_SGIS_texture_lod GLeeEnabled(&_GLEE_SGIS_texture_lod) +#define GLEE_SGIS_multisample GLeeEnabled(&_GLEE_SGIS_multisample) +#define GLEE_EXT_rescale_normal GLeeEnabled(&_GLEE_EXT_rescale_normal) +#define GLEE_EXT_vertex_array GLeeEnabled(&_GLEE_EXT_vertex_array) +#define GLEE_EXT_misc_attribute GLeeEnabled(&_GLEE_EXT_misc_attribute) +#define GLEE_SGIS_generate_mipmap GLeeEnabled(&_GLEE_SGIS_generate_mipmap) +#define GLEE_SGIX_clipmap GLeeEnabled(&_GLEE_SGIX_clipmap) +#define GLEE_SGIX_shadow GLeeEnabled(&_GLEE_SGIX_shadow) +#define GLEE_SGIS_texture_edge_clamp GLeeEnabled(&_GLEE_SGIS_texture_edge_clamp) +#define GLEE_SGIS_texture_border_clamp GLeeEnabled(&_GLEE_SGIS_texture_border_clamp) +#define GLEE_EXT_blend_minmax GLeeEnabled(&_GLEE_EXT_blend_minmax) +#define GLEE_EXT_blend_subtract GLeeEnabled(&_GLEE_EXT_blend_subtract) +#define GLEE_EXT_blend_logic_op GLeeEnabled(&_GLEE_EXT_blend_logic_op) +#define GLEE_SGIX_interlace GLeeEnabled(&_GLEE_SGIX_interlace) +#define GLEE_SGIX_pixel_tiles GLeeEnabled(&_GLEE_SGIX_pixel_tiles) +#define GLEE_SGIS_texture_select GLeeEnabled(&_GLEE_SGIS_texture_select) +#define GLEE_SGIX_sprite GLeeEnabled(&_GLEE_SGIX_sprite) +#define GLEE_SGIX_texture_multi_buffer GLeeEnabled(&_GLEE_SGIX_texture_multi_buffer) +#define GLEE_EXT_point_parameters GLeeEnabled(&_GLEE_EXT_point_parameters) +#define GLEE_SGIS_point_parameters GLeeEnabled(&_GLEE_SGIS_point_parameters) +#define GLEE_SGIX_instruments GLeeEnabled(&_GLEE_SGIX_instruments) +#define GLEE_SGIX_texture_scale_bias GLeeEnabled(&_GLEE_SGIX_texture_scale_bias) +#define GLEE_SGIX_framezoom GLeeEnabled(&_GLEE_SGIX_framezoom) +#define GLEE_SGIX_tag_sample_buffer GLeeEnabled(&_GLEE_SGIX_tag_sample_buffer) +#define GLEE_FfdMaskSGIX GLeeEnabled(&_GLEE_FfdMaskSGIX) +#define GLEE_SGIX_polynomial_ffd GLeeEnabled(&_GLEE_SGIX_polynomial_ffd) +#define GLEE_SGIX_reference_plane GLeeEnabled(&_GLEE_SGIX_reference_plane) +#define GLEE_SGIX_flush_raster GLeeEnabled(&_GLEE_SGIX_flush_raster) +#define GLEE_SGIX_depth_texture GLeeEnabled(&_GLEE_SGIX_depth_texture) +#define GLEE_SGIS_fog_function GLeeEnabled(&_GLEE_SGIS_fog_function) +#define GLEE_SGIX_fog_offset GLeeEnabled(&_GLEE_SGIX_fog_offset) +#define GLEE_HP_image_transform GLeeEnabled(&_GLEE_HP_image_transform) +#define GLEE_HP_convolution_border_modes GLeeEnabled(&_GLEE_HP_convolution_border_modes) +#define GLEE_INGR_palette_buffer GLeeEnabled(&_GLEE_INGR_palette_buffer) +#define GLEE_SGIX_texture_add_env GLeeEnabled(&_GLEE_SGIX_texture_add_env) +#define GLEE_EXT_color_subtable GLeeEnabled(&_GLEE_EXT_color_subtable) +#define GLEE_PGI_vertex_hints GLeeEnabled(&_GLEE_PGI_vertex_hints) +#define GLEE_PGI_misc_hints GLeeEnabled(&_GLEE_PGI_misc_hints) +#define GLEE_EXT_paletted_texture GLeeEnabled(&_GLEE_EXT_paletted_texture) +#define GLEE_EXT_clip_volume_hint GLeeEnabled(&_GLEE_EXT_clip_volume_hint) +#define GLEE_SGIX_list_priority GLeeEnabled(&_GLEE_SGIX_list_priority) +#define GLEE_SGIX_ir_instrument1 GLeeEnabled(&_GLEE_SGIX_ir_instrument1) +#define GLEE_SGIX_calligraphic_fragment GLeeEnabled(&_GLEE_SGIX_calligraphic_fragment) +#define GLEE_SGIX_texture_lod_bias GLeeEnabled(&_GLEE_SGIX_texture_lod_bias) +#define GLEE_SGIX_shadow_ambient GLeeEnabled(&_GLEE_SGIX_shadow_ambient) +#define GLEE_EXT_index_texture GLeeEnabled(&_GLEE_EXT_index_texture) +#define GLEE_EXT_index_material GLeeEnabled(&_GLEE_EXT_index_material) +#define GLEE_EXT_index_func GLeeEnabled(&_GLEE_EXT_index_func) +#define GLEE_EXT_index_array_formats GLeeEnabled(&_GLEE_EXT_index_array_formats) +#define GLEE_EXT_compiled_vertex_array GLeeEnabled(&_GLEE_EXT_compiled_vertex_array) +#define GLEE_EXT_cull_vertex GLeeEnabled(&_GLEE_EXT_cull_vertex) +#define GLEE_SGIX_ycrcb GLeeEnabled(&_GLEE_SGIX_ycrcb) +#define GLEE_SGIX_fragment_lighting GLeeEnabled(&_GLEE_SGIX_fragment_lighting) +#define GLEE_IBM_rasterpos_clip GLeeEnabled(&_GLEE_IBM_rasterpos_clip) +#define GLEE_HP_texture_lighting GLeeEnabled(&_GLEE_HP_texture_lighting) +#define GLEE_EXT_draw_range_elements GLeeEnabled(&_GLEE_EXT_draw_range_elements) +#define GLEE_WIN_phong_shading GLeeEnabled(&_GLEE_WIN_phong_shading) +#define GLEE_WIN_specular_fog GLeeEnabled(&_GLEE_WIN_specular_fog) +#define GLEE_EXT_light_texture GLeeEnabled(&_GLEE_EXT_light_texture) +#define GLEE_SGIX_blend_alpha_minmax GLeeEnabled(&_GLEE_SGIX_blend_alpha_minmax) +#define GLEE_SGIX_impact_pixel_texture GLeeEnabled(&_GLEE_SGIX_impact_pixel_texture) +#define GLEE_EXT_bgra GLeeEnabled(&_GLEE_EXT_bgra) +#define GLEE_SGIX_async GLeeEnabled(&_GLEE_SGIX_async) +#define GLEE_SGIX_async_pixel GLeeEnabled(&_GLEE_SGIX_async_pixel) +#define GLEE_SGIX_async_histogram GLeeEnabled(&_GLEE_SGIX_async_histogram) +#define GLEE_INTEL_texture_scissor GLeeEnabled(&_GLEE_INTEL_texture_scissor) +#define GLEE_INTEL_parallel_arrays GLeeEnabled(&_GLEE_INTEL_parallel_arrays) +#define GLEE_HP_occlusion_test GLeeEnabled(&_GLEE_HP_occlusion_test) +#define GLEE_EXT_pixel_transform GLeeEnabled(&_GLEE_EXT_pixel_transform) +#define GLEE_EXT_pixel_transform_color_table GLeeEnabled(&_GLEE_EXT_pixel_transform_color_table) +#define GLEE_EXT_shared_texture_palette GLeeEnabled(&_GLEE_EXT_shared_texture_palette) +#define GLEE_EXT_separate_specular_color GLeeEnabled(&_GLEE_EXT_separate_specular_color) +#define GLEE_EXT_secondary_color GLeeEnabled(&_GLEE_EXT_secondary_color) +#define GLEE_EXT_texture_perturb_normal GLeeEnabled(&_GLEE_EXT_texture_perturb_normal) +#define GLEE_EXT_multi_draw_arrays GLeeEnabled(&_GLEE_EXT_multi_draw_arrays) +#define GLEE_EXT_fog_coord GLeeEnabled(&_GLEE_EXT_fog_coord) +#define GLEE_REND_screen_coordinates GLeeEnabled(&_GLEE_REND_screen_coordinates) +#define GLEE_EXT_coordinate_frame GLeeEnabled(&_GLEE_EXT_coordinate_frame) +#define GLEE_EXT_texture_env_combine GLeeEnabled(&_GLEE_EXT_texture_env_combine) +#define GLEE_APPLE_specular_vector GLeeEnabled(&_GLEE_APPLE_specular_vector) +#define GLEE_APPLE_transform_hint GLeeEnabled(&_GLEE_APPLE_transform_hint) +#define GLEE_SGIX_fog_scale GLeeEnabled(&_GLEE_SGIX_fog_scale) +#define GLEE_SUNX_constant_data GLeeEnabled(&_GLEE_SUNX_constant_data) +#define GLEE_SUN_global_alpha GLeeEnabled(&_GLEE_SUN_global_alpha) +#define GLEE_SUN_triangle_list GLeeEnabled(&_GLEE_SUN_triangle_list) +#define GLEE_SUN_vertex GLeeEnabled(&_GLEE_SUN_vertex) +#define GLEE_EXT_blend_func_separate GLeeEnabled(&_GLEE_EXT_blend_func_separate) +#define GLEE_INGR_color_clamp GLeeEnabled(&_GLEE_INGR_color_clamp) +#define GLEE_INGR_interlace_read GLeeEnabled(&_GLEE_INGR_interlace_read) +#define GLEE_EXT_stencil_wrap GLeeEnabled(&_GLEE_EXT_stencil_wrap) +#define GLEE_EXT_422_pixels GLeeEnabled(&_GLEE_EXT_422_pixels) +#define GLEE_NV_texgen_reflection GLeeEnabled(&_GLEE_NV_texgen_reflection) +#define GLEE_EXT_texture_cube_map GLeeEnabled(&_GLEE_EXT_texture_cube_map) +#define GLEE_SUN_convolution_border_modes GLeeEnabled(&_GLEE_SUN_convolution_border_modes) +#define GLEE_EXT_texture_env_add GLeeEnabled(&_GLEE_EXT_texture_env_add) +#define GLEE_EXT_texture_lod_bias GLeeEnabled(&_GLEE_EXT_texture_lod_bias) +#define GLEE_EXT_texture_filter_anisotropic GLeeEnabled(&_GLEE_EXT_texture_filter_anisotropic) +#define GLEE_EXT_vertex_weighting GLeeEnabled(&_GLEE_EXT_vertex_weighting) +#define GLEE_NV_light_max_exponent GLeeEnabled(&_GLEE_NV_light_max_exponent) +#define GLEE_NV_vertex_array_range GLeeEnabled(&_GLEE_NV_vertex_array_range) +#define GLEE_NV_register_combiners GLeeEnabled(&_GLEE_NV_register_combiners) +#define GLEE_NV_fog_distance GLeeEnabled(&_GLEE_NV_fog_distance) +#define GLEE_NV_texgen_emboss GLeeEnabled(&_GLEE_NV_texgen_emboss) +#define GLEE_NV_blend_square GLeeEnabled(&_GLEE_NV_blend_square) +#define GLEE_NV_texture_env_combine4 GLeeEnabled(&_GLEE_NV_texture_env_combine4) +#define GLEE_MESA_resize_buffers GLeeEnabled(&_GLEE_MESA_resize_buffers) +#define GLEE_MESA_window_pos GLeeEnabled(&_GLEE_MESA_window_pos) +#define GLEE_EXT_texture_compression_s3tc GLeeEnabled(&_GLEE_EXT_texture_compression_s3tc) +#define GLEE_IBM_cull_vertex GLeeEnabled(&_GLEE_IBM_cull_vertex) +#define GLEE_IBM_multimode_draw_arrays GLeeEnabled(&_GLEE_IBM_multimode_draw_arrays) +#define GLEE_IBM_vertex_array_lists GLeeEnabled(&_GLEE_IBM_vertex_array_lists) +#define GLEE_SGIX_subsample GLeeEnabled(&_GLEE_SGIX_subsample) +#define GLEE_SGIX_ycrcb_subsample GLeeEnabled(&_GLEE_SGIX_ycrcb_subsample) +#define GLEE_SGIX_ycrcba GLeeEnabled(&_GLEE_SGIX_ycrcba) +#define GLEE_SGI_depth_pass_instrument GLeeEnabled(&_GLEE_SGI_depth_pass_instrument) +#define GLEE_3DFX_texture_compression_FXT1 GLeeEnabled(&_GLEE_3DFX_texture_compression_FXT1) +#define GLEE_3DFX_multisample GLeeEnabled(&_GLEE_3DFX_multisample) +#define GLEE_3DFX_tbuffer GLeeEnabled(&_GLEE_3DFX_tbuffer) +#define GLEE_EXT_multisample GLeeEnabled(&_GLEE_EXT_multisample) +#define GLEE_SGIX_vertex_preclip GLeeEnabled(&_GLEE_SGIX_vertex_preclip) +#define GLEE_SGIX_convolution_accuracy GLeeEnabled(&_GLEE_SGIX_convolution_accuracy) +#define GLEE_SGIX_resample GLeeEnabled(&_GLEE_SGIX_resample) +#define GLEE_SGIS_point_line_texgen GLeeEnabled(&_GLEE_SGIS_point_line_texgen) +#define GLEE_SGIS_texture_color_mask GLeeEnabled(&_GLEE_SGIS_texture_color_mask) +#define GLEE_EXT_texture_env_dot3 GLeeEnabled(&_GLEE_EXT_texture_env_dot3) +#define GLEE_ATI_texture_mirror_once GLeeEnabled(&_GLEE_ATI_texture_mirror_once) +#define GLEE_NV_fence GLeeEnabled(&_GLEE_NV_fence) +#define GLEE_IBM_texture_mirrored_repeat GLeeEnabled(&_GLEE_IBM_texture_mirrored_repeat) +#define GLEE_NV_evaluators GLeeEnabled(&_GLEE_NV_evaluators) +#define GLEE_NV_packed_depth_stencil GLeeEnabled(&_GLEE_NV_packed_depth_stencil) +#define GLEE_NV_register_combiners2 GLeeEnabled(&_GLEE_NV_register_combiners2) +#define GLEE_NV_texture_compression_vtc GLeeEnabled(&_GLEE_NV_texture_compression_vtc) +#define GLEE_NV_texture_rectangle GLeeEnabled(&_GLEE_NV_texture_rectangle) +#define GLEE_NV_texture_shader GLeeEnabled(&_GLEE_NV_texture_shader) +#define GLEE_NV_texture_shader2 GLeeEnabled(&_GLEE_NV_texture_shader2) +#define GLEE_NV_vertex_array_range2 GLeeEnabled(&_GLEE_NV_vertex_array_range2) +#define GLEE_NV_vertex_program GLeeEnabled(&_GLEE_NV_vertex_program) +#define GLEE_SGIX_texture_coordinate_clamp GLeeEnabled(&_GLEE_SGIX_texture_coordinate_clamp) +#define GLEE_SGIX_scalebias_hint GLeeEnabled(&_GLEE_SGIX_scalebias_hint) +#define GLEE_OML_interlace GLeeEnabled(&_GLEE_OML_interlace) +#define GLEE_OML_subsample GLeeEnabled(&_GLEE_OML_subsample) +#define GLEE_OML_resample GLeeEnabled(&_GLEE_OML_resample) +#define GLEE_NV_copy_depth_to_color GLeeEnabled(&_GLEE_NV_copy_depth_to_color) +#define GLEE_ATI_envmap_bumpmap GLeeEnabled(&_GLEE_ATI_envmap_bumpmap) +#define GLEE_ATI_fragment_shader GLeeEnabled(&_GLEE_ATI_fragment_shader) +#define GLEE_ATI_pn_triangles GLeeEnabled(&_GLEE_ATI_pn_triangles) +#define GLEE_ATI_vertex_array_object GLeeEnabled(&_GLEE_ATI_vertex_array_object) +#define GLEE_EXT_vertex_shader GLeeEnabled(&_GLEE_EXT_vertex_shader) +#define GLEE_ATI_vertex_streams GLeeEnabled(&_GLEE_ATI_vertex_streams) +#define GLEE_ATI_element_array GLeeEnabled(&_GLEE_ATI_element_array) +#define GLEE_SUN_mesh_array GLeeEnabled(&_GLEE_SUN_mesh_array) +#define GLEE_SUN_slice_accum GLeeEnabled(&_GLEE_SUN_slice_accum) +#define GLEE_NV_multisample_filter_hint GLeeEnabled(&_GLEE_NV_multisample_filter_hint) +#define GLEE_NV_depth_clamp GLeeEnabled(&_GLEE_NV_depth_clamp) +#define GLEE_NV_occlusion_query GLeeEnabled(&_GLEE_NV_occlusion_query) +#define GLEE_NV_point_sprite GLeeEnabled(&_GLEE_NV_point_sprite) +#define GLEE_NV_texture_shader3 GLeeEnabled(&_GLEE_NV_texture_shader3) +#define GLEE_NV_vertex_program1_1 GLeeEnabled(&_GLEE_NV_vertex_program1_1) +#define GLEE_EXT_shadow_funcs GLeeEnabled(&_GLEE_EXT_shadow_funcs) +#define GLEE_EXT_stencil_two_side GLeeEnabled(&_GLEE_EXT_stencil_two_side) +#define GLEE_ATI_text_fragment_shader GLeeEnabled(&_GLEE_ATI_text_fragment_shader) +#define GLEE_APPLE_client_storage GLeeEnabled(&_GLEE_APPLE_client_storage) +#define GLEE_APPLE_element_array GLeeEnabled(&_GLEE_APPLE_element_array) +#define GLEE_APPLE_fence GLeeEnabled(&_GLEE_APPLE_fence) +#define GLEE_APPLE_vertex_array_object GLeeEnabled(&_GLEE_APPLE_vertex_array_object) +#define GLEE_APPLE_vertex_array_range GLeeEnabled(&_GLEE_APPLE_vertex_array_range) +#define GLEE_APPLE_ycbcr_422 GLeeEnabled(&_GLEE_APPLE_ycbcr_422) +#define GLEE_S3_s3tc GLeeEnabled(&_GLEE_S3_s3tc) +#define GLEE_ATI_draw_buffers GLeeEnabled(&_GLEE_ATI_draw_buffers) +#define GLEE_ATI_pixel_format_float GLeeEnabled(&_GLEE_ATI_pixel_format_float) +#define GLEE_ATI_texture_env_combine3 GLeeEnabled(&_GLEE_ATI_texture_env_combine3) +#define GLEE_ATI_texture_float GLeeEnabled(&_GLEE_ATI_texture_float) +#define GLEE_NV_float_buffer GLeeEnabled(&_GLEE_NV_float_buffer) +#define GLEE_NV_fragment_program GLeeEnabled(&_GLEE_NV_fragment_program) +#define GLEE_NV_half_float GLeeEnabled(&_GLEE_NV_half_float) +#define GLEE_NV_pixel_data_range GLeeEnabled(&_GLEE_NV_pixel_data_range) +#define GLEE_NV_primitive_restart GLeeEnabled(&_GLEE_NV_primitive_restart) +#define GLEE_NV_texture_expand_normal GLeeEnabled(&_GLEE_NV_texture_expand_normal) +#define GLEE_NV_vertex_program2 GLeeEnabled(&_GLEE_NV_vertex_program2) +#define GLEE_ATI_map_object_buffer GLeeEnabled(&_GLEE_ATI_map_object_buffer) +#define GLEE_ATI_separate_stencil GLeeEnabled(&_GLEE_ATI_separate_stencil) +#define GLEE_ATI_vertex_attrib_array_object GLeeEnabled(&_GLEE_ATI_vertex_attrib_array_object) +#define GLEE_OES_read_format GLeeEnabled(&_GLEE_OES_read_format) +#define GLEE_EXT_depth_bounds_test GLeeEnabled(&_GLEE_EXT_depth_bounds_test) +#define GLEE_EXT_texture_mirror_clamp GLeeEnabled(&_GLEE_EXT_texture_mirror_clamp) +#define GLEE_EXT_blend_equation_separate GLeeEnabled(&_GLEE_EXT_blend_equation_separate) +#define GLEE_MESA_pack_invert GLeeEnabled(&_GLEE_MESA_pack_invert) +#define GLEE_MESA_ycbcr_texture GLeeEnabled(&_GLEE_MESA_ycbcr_texture) +#define GLEE_EXT_pixel_buffer_object GLeeEnabled(&_GLEE_EXT_pixel_buffer_object) +#define GLEE_NV_fragment_program_option GLeeEnabled(&_GLEE_NV_fragment_program_option) +#define GLEE_NV_fragment_program2 GLeeEnabled(&_GLEE_NV_fragment_program2) +#define GLEE_NV_vertex_program2_option GLeeEnabled(&_GLEE_NV_vertex_program2_option) +#define GLEE_NV_vertex_program3 GLeeEnabled(&_GLEE_NV_vertex_program3) +#define GLEE_EXT_framebuffer_object GLeeEnabled(&_GLEE_EXT_framebuffer_object) +#define GLEE_GREMEDY_string_marker GLeeEnabled(&_GLEE_GREMEDY_string_marker) +#define GLEE_EXT_packed_depth_stencil GLeeEnabled(&_GLEE_EXT_packed_depth_stencil) +#define GLEE_EXT_stencil_clear_tag GLeeEnabled(&_GLEE_EXT_stencil_clear_tag) +#define GLEE_EXT_texture_sRGB GLeeEnabled(&_GLEE_EXT_texture_sRGB) +#define GLEE_EXT_framebuffer_blit GLeeEnabled(&_GLEE_EXT_framebuffer_blit) +#define GLEE_EXT_framebuffer_multisample GLeeEnabled(&_GLEE_EXT_framebuffer_multisample) +#define GLEE_MESAX_texture_stack GLeeEnabled(&_GLEE_MESAX_texture_stack) +#define GLEE_EXT_timer_query GLeeEnabled(&_GLEE_EXT_timer_query) +#define GLEE_EXT_gpu_program_parameters GLeeEnabled(&_GLEE_EXT_gpu_program_parameters) +#define GLEE_APPLE_flush_buffer_range GLeeEnabled(&_GLEE_APPLE_flush_buffer_range) +#define GLEE_EXT_gpu_shader4 GLeeEnabled(&_GLEE_EXT_gpu_shader4) +#define GLEE_EXT_draw_instanced GLeeEnabled(&_GLEE_EXT_draw_instanced) +#define GLEE_EXT_packed_float GLeeEnabled(&_GLEE_EXT_packed_float) +#define GLEE_EXT_texture_array GLeeEnabled(&_GLEE_EXT_texture_array) +#define GLEE_EXT_texture_buffer_object GLeeEnabled(&_GLEE_EXT_texture_buffer_object) +#define GLEE_EXT_texture_compression_latc GLeeEnabled(&_GLEE_EXT_texture_compression_latc) +#define GLEE_EXT_texture_compression_rgtc GLeeEnabled(&_GLEE_EXT_texture_compression_rgtc) +#define GLEE_EXT_texture_shared_exponent GLeeEnabled(&_GLEE_EXT_texture_shared_exponent) +#define GLEE_NV_depth_buffer_float GLeeEnabled(&_GLEE_NV_depth_buffer_float) +#define GLEE_NV_framebuffer_multisample_coverage GLeeEnabled(&_GLEE_NV_framebuffer_multisample_coverage) +#define GLEE_EXT_framebuffer_sRGB GLeeEnabled(&_GLEE_EXT_framebuffer_sRGB) +#define GLEE_NV_geometry_shader4 GLeeEnabled(&_GLEE_NV_geometry_shader4) +#define GLEE_NV_parameter_buffer_object GLeeEnabled(&_GLEE_NV_parameter_buffer_object) +#define GLEE_EXT_draw_buffers2 GLeeEnabled(&_GLEE_EXT_draw_buffers2) +#define GLEE_NV_transform_feedback GLeeEnabled(&_GLEE_NV_transform_feedback) +#define GLEE_EXT_bindable_uniform GLeeEnabled(&_GLEE_EXT_bindable_uniform) +#define GLEE_EXT_texture_integer GLeeEnabled(&_GLEE_EXT_texture_integer) +#define GLEE_GREMEDY_frame_terminator GLeeEnabled(&_GLEE_GREMEDY_frame_terminator) +#define GLEE_NV_conditional_render GLeeEnabled(&_GLEE_NV_conditional_render) +#define GLEE_NV_present_video GLeeEnabled(&_GLEE_NV_present_video) +#define GLEE_EXT_transform_feedback GLeeEnabled(&_GLEE_EXT_transform_feedback) +#define GLEE_EXT_direct_state_access GLeeEnabled(&_GLEE_EXT_direct_state_access) +#define GLEE_EXT_vertex_array_bgra GLeeEnabled(&_GLEE_EXT_vertex_array_bgra) +#define GLEE_EXT_texture_swizzle GLeeEnabled(&_GLEE_EXT_texture_swizzle) +#define GLEE_NV_explicit_multisample GLeeEnabled(&_GLEE_NV_explicit_multisample) +#define GLEE_NV_transform_feedback2 GLeeEnabled(&_GLEE_NV_transform_feedback2) +#define GLEE_SGIX_texture_select GLeeEnabled(&_GLEE_SGIX_texture_select) +#define GLEE_INGR_blend_func_separate GLeeEnabled(&_GLEE_INGR_blend_func_separate) +#define GLEE_SGIX_depth_pass_instrument GLeeEnabled(&_GLEE_SGIX_depth_pass_instrument) +#define GLEE_SGIX_igloo_interface GLeeEnabled(&_GLEE_SGIX_igloo_interface) +#define GLEE_EXT_fragment_lighting GLeeEnabled(&_GLEE_EXT_fragment_lighting) +#define GLEE_EXT_geometry_shader4 GLeeEnabled(&_GLEE_EXT_geometry_shader4) +#define GLEE_EXT_scene_marker GLeeEnabled(&_GLEE_EXT_scene_marker) +#define GLEE_EXT_texture_compression_dxt1 GLeeEnabled(&_GLEE_EXT_texture_compression_dxt1) +#define GLEE_EXT_texture_env GLeeEnabled(&_GLEE_EXT_texture_env) +#define GLEE_IBM_static_data GLeeEnabled(&_GLEE_IBM_static_data) +#define GLEE_NV_gpu_program4 GLeeEnabled(&_GLEE_NV_gpu_program4) +#define GLEE_OES_byte_coordinates GLeeEnabled(&_GLEE_OES_byte_coordinates) +#define GLEE_OES_compressed_paletted_texture GLeeEnabled(&_GLEE_OES_compressed_paletted_texture) +#define GLEE_OES_single_precision GLeeEnabled(&_GLEE_OES_single_precision) +#define GLEE_SGIX_pixel_texture_bits GLeeEnabled(&_GLEE_SGIX_pixel_texture_bits) +#define GLEE_SGIX_texture_range GLeeEnabled(&_GLEE_SGIX_texture_range) + + +/***************************************************************** + * Additional types needed for extensions + *****************************************************************/ + +/* Used for GLSL shader text */ +#ifndef GL_VERSION_2_0 + typedef char GLchar; +#endif + +#include + +#ifndef GL_VERSION_1_5 + typedef ptrdiff_t GLintptr; + typedef ptrdiff_t GLsizeiptr; +#endif + +#ifndef GL_NV_half_float + typedef unsigned short GLhalfNV; +#endif + +#ifndef GL_ARB_vertex_buffer_object + typedef ptrdiff_t GLintptrARB; + typedef ptrdiff_t GLsizeiptrARB; +#endif + +#ifndef GL_ARB_shader_objects + typedef int GLhandleARB; + typedef char GLcharARB; +#endif + +#ifndef GL_EXT_timer_query + typedef signed long long GLint64EXT; + typedef unsigned long long GLuint64EXT; +#endif + +/* Platform-specific */ + +#ifdef WIN32 + + /* WGL */ + + #ifndef WGL_ARB_pbuffer + DECLARE_HANDLE(HPBUFFERARB); + #endif + + #ifndef WGL_EXT_pbuffer + DECLARE_HANDLE(HPBUFFEREXT); + #endif + + #ifndef WGL_NV_video_output + DECLARE_HANDLE(HPVIDEODEV); + #endif + + #ifndef WGL_NV_present_video + DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); + #endif + + #ifndef WGL_NV_gpu_affinity + DECLARE_HANDLE(HPGPUNV); + DECLARE_HANDLE(HGPUNV); + + typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; + } GPU_DEVICE, *PGPU_DEVICE; + #endif + +#elif defined(__APPLE__) || defined(__APPLE_CC__) + + /* Mac OS X */ + +#else + + /* GLX */ + + typedef void (*__GLXextFuncPtr)(void); + + #ifndef GLX_ARB_get_proc_address + #define GLX_ARB_get_proc_address 1 + extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *); + extern void ( * glXGetProcAddressARB (const GLubyte *procName))(void); + typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName); + #endif + + #ifndef GLX_SGIX_fbconfig + typedef XID GLXFBConfigIDSGIX; + typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + #endif + + #ifndef GLX_SGIX_pbuffer + typedef XID GLXPbufferSGIX; + typedef struct { + int type; + unsigned long serial; + Bool send_event; + Display *display; + GLXDrawable drawable; + int event_type; + int draw_type; + unsigned int mask; + int x, y; + int width, height; + int count; + } GLXBufferClobberEventSGIX; + #endif + + #ifndef GLX_SGIX_hyperpipe + #define _GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 + typedef struct + { + char pipeName[_GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; + } GLXHyperpipeNetworkSGIX; + + typedef struct + { + char pipeName[_GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int participationType; + int timeSlice; + } GLXHyperpipeConfigSGIX; + + typedef struct + { + char pipeName[_GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin; + int srcYOrigin; + int srcWidth; + int srcHeight; + int destXOrigin; + int destYOrigin; + int destWidth; + int destHeight; + } GLXPipeRect; + + typedef struct + { + char pipeName[_GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin; + int YOrigin; + int maxHeight; + int maxWidth; + } GLXPipeRectLimits; + #endif + + #ifndef GLX_NV_video_output + typedef unsigned int GLXVideoDeviceNV; + #endif // GLX_NV_video_output + +#endif /* end platform specific */ + + + +/* GL_VERSION_1_2 */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#define __GLEE_GL_VERSION_1_2 1 +/* Constants */ +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#ifndef GLEE_H_DEFINED_glBlendColor +#define GLEE_H_DEFINED_glBlendColor + typedef void (APIENTRYP GLEEPFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + GLEE_EXTERN GLEEPFNGLBLENDCOLORPROC GLeeFuncPtr_glBlendColor; + #define glBlendColor GLeeFuncPtr_glBlendColor +#endif +#ifndef GLEE_H_DEFINED_glBlendEquation +#define GLEE_H_DEFINED_glBlendEquation + typedef void (APIENTRYP GLEEPFNGLBLENDEQUATIONPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLBLENDEQUATIONPROC GLeeFuncPtr_glBlendEquation; + #define glBlendEquation GLeeFuncPtr_glBlendEquation +#endif +#ifndef GLEE_H_DEFINED_glDrawRangeElements +#define GLEE_H_DEFINED_glDrawRangeElements + typedef void (APIENTRYP GLEEPFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices); + GLEE_EXTERN GLEEPFNGLDRAWRANGEELEMENTSPROC GLeeFuncPtr_glDrawRangeElements; + #define glDrawRangeElements GLeeFuncPtr_glDrawRangeElements +#endif +#ifndef GLEE_H_DEFINED_glColorTable +#define GLEE_H_DEFINED_glColorTable + typedef void (APIENTRYP GLEEPFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table); + GLEE_EXTERN GLEEPFNGLCOLORTABLEPROC GLeeFuncPtr_glColorTable; + #define glColorTable GLeeFuncPtr_glColorTable +#endif +#ifndef GLEE_H_DEFINED_glColorTableParameterfv +#define GLEE_H_DEFINED_glColorTableParameterfv + typedef void (APIENTRYP GLEEPFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLCOLORTABLEPARAMETERFVPROC GLeeFuncPtr_glColorTableParameterfv; + #define glColorTableParameterfv GLeeFuncPtr_glColorTableParameterfv +#endif +#ifndef GLEE_H_DEFINED_glColorTableParameteriv +#define GLEE_H_DEFINED_glColorTableParameteriv + typedef void (APIENTRYP GLEEPFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLCOLORTABLEPARAMETERIVPROC GLeeFuncPtr_glColorTableParameteriv; + #define glColorTableParameteriv GLeeFuncPtr_glColorTableParameteriv +#endif +#ifndef GLEE_H_DEFINED_glCopyColorTable +#define GLEE_H_DEFINED_glCopyColorTable + typedef void (APIENTRYP GLEEPFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYCOLORTABLEPROC GLeeFuncPtr_glCopyColorTable; + #define glCopyColorTable GLeeFuncPtr_glCopyColorTable +#endif +#ifndef GLEE_H_DEFINED_glGetColorTable +#define GLEE_H_DEFINED_glGetColorTable + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid * table); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEPROC GLeeFuncPtr_glGetColorTable; + #define glGetColorTable GLeeFuncPtr_glGetColorTable +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableParameterfv +#define GLEE_H_DEFINED_glGetColorTableParameterfv + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEPARAMETERFVPROC GLeeFuncPtr_glGetColorTableParameterfv; + #define glGetColorTableParameterfv GLeeFuncPtr_glGetColorTableParameterfv +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableParameteriv +#define GLEE_H_DEFINED_glGetColorTableParameteriv + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEPARAMETERIVPROC GLeeFuncPtr_glGetColorTableParameteriv; + #define glGetColorTableParameteriv GLeeFuncPtr_glGetColorTableParameteriv +#endif +#ifndef GLEE_H_DEFINED_glColorSubTable +#define GLEE_H_DEFINED_glColorSubTable + typedef void (APIENTRYP GLEEPFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOLORSUBTABLEPROC GLeeFuncPtr_glColorSubTable; + #define glColorSubTable GLeeFuncPtr_glColorSubTable +#endif +#ifndef GLEE_H_DEFINED_glCopyColorSubTable +#define GLEE_H_DEFINED_glCopyColorSubTable + typedef void (APIENTRYP GLEEPFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYCOLORSUBTABLEPROC GLeeFuncPtr_glCopyColorSubTable; + #define glCopyColorSubTable GLeeFuncPtr_glCopyColorSubTable +#endif +#ifndef GLEE_H_DEFINED_glConvolutionFilter1D +#define GLEE_H_DEFINED_glConvolutionFilter1D + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * image); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONFILTER1DPROC GLeeFuncPtr_glConvolutionFilter1D; + #define glConvolutionFilter1D GLeeFuncPtr_glConvolutionFilter1D +#endif +#ifndef GLEE_H_DEFINED_glConvolutionFilter2D +#define GLEE_H_DEFINED_glConvolutionFilter2D + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * image); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONFILTER2DPROC GLeeFuncPtr_glConvolutionFilter2D; + #define glConvolutionFilter2D GLeeFuncPtr_glConvolutionFilter2D +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameterf +#define GLEE_H_DEFINED_glConvolutionParameterf + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERFPROC GLeeFuncPtr_glConvolutionParameterf; + #define glConvolutionParameterf GLeeFuncPtr_glConvolutionParameterf +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameterfv +#define GLEE_H_DEFINED_glConvolutionParameterfv + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERFVPROC GLeeFuncPtr_glConvolutionParameterfv; + #define glConvolutionParameterfv GLeeFuncPtr_glConvolutionParameterfv +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameteri +#define GLEE_H_DEFINED_glConvolutionParameteri + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERIPROC GLeeFuncPtr_glConvolutionParameteri; + #define glConvolutionParameteri GLeeFuncPtr_glConvolutionParameteri +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameteriv +#define GLEE_H_DEFINED_glConvolutionParameteriv + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERIVPROC GLeeFuncPtr_glConvolutionParameteriv; + #define glConvolutionParameteriv GLeeFuncPtr_glConvolutionParameteriv +#endif +#ifndef GLEE_H_DEFINED_glCopyConvolutionFilter1D +#define GLEE_H_DEFINED_glCopyConvolutionFilter1D + typedef void (APIENTRYP GLEEPFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYCONVOLUTIONFILTER1DPROC GLeeFuncPtr_glCopyConvolutionFilter1D; + #define glCopyConvolutionFilter1D GLeeFuncPtr_glCopyConvolutionFilter1D +#endif +#ifndef GLEE_H_DEFINED_glCopyConvolutionFilter2D +#define GLEE_H_DEFINED_glCopyConvolutionFilter2D + typedef void (APIENTRYP GLEEPFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYCONVOLUTIONFILTER2DPROC GLeeFuncPtr_glCopyConvolutionFilter2D; + #define glCopyConvolutionFilter2D GLeeFuncPtr_glCopyConvolutionFilter2D +#endif +#ifndef GLEE_H_DEFINED_glGetConvolutionFilter +#define GLEE_H_DEFINED_glGetConvolutionFilter + typedef void (APIENTRYP GLEEPFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid * image); + GLEE_EXTERN GLEEPFNGLGETCONVOLUTIONFILTERPROC GLeeFuncPtr_glGetConvolutionFilter; + #define glGetConvolutionFilter GLeeFuncPtr_glGetConvolutionFilter +#endif +#ifndef GLEE_H_DEFINED_glGetConvolutionParameterfv +#define GLEE_H_DEFINED_glGetConvolutionParameterfv + typedef void (APIENTRYP GLEEPFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCONVOLUTIONPARAMETERFVPROC GLeeFuncPtr_glGetConvolutionParameterfv; + #define glGetConvolutionParameterfv GLeeFuncPtr_glGetConvolutionParameterfv +#endif +#ifndef GLEE_H_DEFINED_glGetConvolutionParameteriv +#define GLEE_H_DEFINED_glGetConvolutionParameteriv + typedef void (APIENTRYP GLEEPFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETCONVOLUTIONPARAMETERIVPROC GLeeFuncPtr_glGetConvolutionParameteriv; + #define glGetConvolutionParameteriv GLeeFuncPtr_glGetConvolutionParameteriv +#endif +#ifndef GLEE_H_DEFINED_glGetSeparableFilter +#define GLEE_H_DEFINED_glGetSeparableFilter + typedef void (APIENTRYP GLEEPFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span); + GLEE_EXTERN GLEEPFNGLGETSEPARABLEFILTERPROC GLeeFuncPtr_glGetSeparableFilter; + #define glGetSeparableFilter GLeeFuncPtr_glGetSeparableFilter +#endif +#ifndef GLEE_H_DEFINED_glSeparableFilter2D +#define GLEE_H_DEFINED_glSeparableFilter2D + typedef void (APIENTRYP GLEEPFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * row, const GLvoid * column); + GLEE_EXTERN GLEEPFNGLSEPARABLEFILTER2DPROC GLeeFuncPtr_glSeparableFilter2D; + #define glSeparableFilter2D GLeeFuncPtr_glSeparableFilter2D +#endif +#ifndef GLEE_H_DEFINED_glGetHistogram +#define GLEE_H_DEFINED_glGetHistogram + typedef void (APIENTRYP GLEEPFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); + GLEE_EXTERN GLEEPFNGLGETHISTOGRAMPROC GLeeFuncPtr_glGetHistogram; + #define glGetHistogram GLeeFuncPtr_glGetHistogram +#endif +#ifndef GLEE_H_DEFINED_glGetHistogramParameterfv +#define GLEE_H_DEFINED_glGetHistogramParameterfv + typedef void (APIENTRYP GLEEPFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETHISTOGRAMPARAMETERFVPROC GLeeFuncPtr_glGetHistogramParameterfv; + #define glGetHistogramParameterfv GLeeFuncPtr_glGetHistogramParameterfv +#endif +#ifndef GLEE_H_DEFINED_glGetHistogramParameteriv +#define GLEE_H_DEFINED_glGetHistogramParameteriv + typedef void (APIENTRYP GLEEPFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETHISTOGRAMPARAMETERIVPROC GLeeFuncPtr_glGetHistogramParameteriv; + #define glGetHistogramParameteriv GLeeFuncPtr_glGetHistogramParameteriv +#endif +#ifndef GLEE_H_DEFINED_glGetMinmax +#define GLEE_H_DEFINED_glGetMinmax + typedef void (APIENTRYP GLEEPFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); + GLEE_EXTERN GLEEPFNGLGETMINMAXPROC GLeeFuncPtr_glGetMinmax; + #define glGetMinmax GLeeFuncPtr_glGetMinmax +#endif +#ifndef GLEE_H_DEFINED_glGetMinmaxParameterfv +#define GLEE_H_DEFINED_glGetMinmaxParameterfv + typedef void (APIENTRYP GLEEPFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMINMAXPARAMETERFVPROC GLeeFuncPtr_glGetMinmaxParameterfv; + #define glGetMinmaxParameterfv GLeeFuncPtr_glGetMinmaxParameterfv +#endif +#ifndef GLEE_H_DEFINED_glGetMinmaxParameteriv +#define GLEE_H_DEFINED_glGetMinmaxParameteriv + typedef void (APIENTRYP GLEEPFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMINMAXPARAMETERIVPROC GLeeFuncPtr_glGetMinmaxParameteriv; + #define glGetMinmaxParameteriv GLeeFuncPtr_glGetMinmaxParameteriv +#endif +#ifndef GLEE_H_DEFINED_glHistogram +#define GLEE_H_DEFINED_glHistogram + typedef void (APIENTRYP GLEEPFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); + GLEE_EXTERN GLEEPFNGLHISTOGRAMPROC GLeeFuncPtr_glHistogram; + #define glHistogram GLeeFuncPtr_glHistogram +#endif +#ifndef GLEE_H_DEFINED_glMinmax +#define GLEE_H_DEFINED_glMinmax + typedef void (APIENTRYP GLEEPFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); + GLEE_EXTERN GLEEPFNGLMINMAXPROC GLeeFuncPtr_glMinmax; + #define glMinmax GLeeFuncPtr_glMinmax +#endif +#ifndef GLEE_H_DEFINED_glResetHistogram +#define GLEE_H_DEFINED_glResetHistogram + typedef void (APIENTRYP GLEEPFNGLRESETHISTOGRAMPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLRESETHISTOGRAMPROC GLeeFuncPtr_glResetHistogram; + #define glResetHistogram GLeeFuncPtr_glResetHistogram +#endif +#ifndef GLEE_H_DEFINED_glResetMinmax +#define GLEE_H_DEFINED_glResetMinmax + typedef void (APIENTRYP GLEEPFNGLRESETMINMAXPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLRESETMINMAXPROC GLeeFuncPtr_glResetMinmax; + #define glResetMinmax GLeeFuncPtr_glResetMinmax +#endif +#ifndef GLEE_H_DEFINED_glTexImage3D +#define GLEE_H_DEFINED_glTexImage3D + typedef void (APIENTRYP GLEEPFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXIMAGE3DPROC GLeeFuncPtr_glTexImage3D; + #define glTexImage3D GLeeFuncPtr_glTexImage3D +#endif +#ifndef GLEE_H_DEFINED_glTexSubImage3D +#define GLEE_H_DEFINED_glTexSubImage3D + typedef void (APIENTRYP GLEEPFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXSUBIMAGE3DPROC GLeeFuncPtr_glTexSubImage3D; + #define glTexSubImage3D GLeeFuncPtr_glTexSubImage3D +#endif +#ifndef GLEE_H_DEFINED_glCopyTexSubImage3D +#define GLEE_H_DEFINED_glCopyTexSubImage3D + typedef void (APIENTRYP GLEEPFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYTEXSUBIMAGE3DPROC GLeeFuncPtr_glCopyTexSubImage3D; + #define glCopyTexSubImage3D GLeeFuncPtr_glCopyTexSubImage3D +#endif +#endif + +/* GL_ARB_imaging */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 +#define __GLEE_GL_ARB_imaging 1 +/* Constants */ +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +/* GL_VERSION_1_3 */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#define __GLEE_GL_VERSION_1_3 1 +/* Constants */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#ifndef GLEE_H_DEFINED_glActiveTexture +#define GLEE_H_DEFINED_glActiveTexture + typedef void (APIENTRYP GLEEPFNGLACTIVETEXTUREPROC) (GLenum texture); + GLEE_EXTERN GLEEPFNGLACTIVETEXTUREPROC GLeeFuncPtr_glActiveTexture; + #define glActiveTexture GLeeFuncPtr_glActiveTexture +#endif +#ifndef GLEE_H_DEFINED_glClientActiveTexture +#define GLEE_H_DEFINED_glClientActiveTexture + typedef void (APIENTRYP GLEEPFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); + GLEE_EXTERN GLEEPFNGLCLIENTACTIVETEXTUREPROC GLeeFuncPtr_glClientActiveTexture; + #define glClientActiveTexture GLeeFuncPtr_glClientActiveTexture +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1d +#define GLEE_H_DEFINED_glMultiTexCoord1d + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1DPROC GLeeFuncPtr_glMultiTexCoord1d; + #define glMultiTexCoord1d GLeeFuncPtr_glMultiTexCoord1d +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1dv +#define GLEE_H_DEFINED_glMultiTexCoord1dv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1DVPROC GLeeFuncPtr_glMultiTexCoord1dv; + #define glMultiTexCoord1dv GLeeFuncPtr_glMultiTexCoord1dv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1f +#define GLEE_H_DEFINED_glMultiTexCoord1f + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1FPROC GLeeFuncPtr_glMultiTexCoord1f; + #define glMultiTexCoord1f GLeeFuncPtr_glMultiTexCoord1f +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1fv +#define GLEE_H_DEFINED_glMultiTexCoord1fv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1FVPROC GLeeFuncPtr_glMultiTexCoord1fv; + #define glMultiTexCoord1fv GLeeFuncPtr_glMultiTexCoord1fv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1i +#define GLEE_H_DEFINED_glMultiTexCoord1i + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1IPROC GLeeFuncPtr_glMultiTexCoord1i; + #define glMultiTexCoord1i GLeeFuncPtr_glMultiTexCoord1i +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1iv +#define GLEE_H_DEFINED_glMultiTexCoord1iv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1IVPROC GLeeFuncPtr_glMultiTexCoord1iv; + #define glMultiTexCoord1iv GLeeFuncPtr_glMultiTexCoord1iv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1s +#define GLEE_H_DEFINED_glMultiTexCoord1s + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1SPROC GLeeFuncPtr_glMultiTexCoord1s; + #define glMultiTexCoord1s GLeeFuncPtr_glMultiTexCoord1s +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1sv +#define GLEE_H_DEFINED_glMultiTexCoord1sv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1SVPROC GLeeFuncPtr_glMultiTexCoord1sv; + #define glMultiTexCoord1sv GLeeFuncPtr_glMultiTexCoord1sv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2d +#define GLEE_H_DEFINED_glMultiTexCoord2d + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2DPROC GLeeFuncPtr_glMultiTexCoord2d; + #define glMultiTexCoord2d GLeeFuncPtr_glMultiTexCoord2d +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2dv +#define GLEE_H_DEFINED_glMultiTexCoord2dv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2DVPROC GLeeFuncPtr_glMultiTexCoord2dv; + #define glMultiTexCoord2dv GLeeFuncPtr_glMultiTexCoord2dv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2f +#define GLEE_H_DEFINED_glMultiTexCoord2f + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2FPROC GLeeFuncPtr_glMultiTexCoord2f; + #define glMultiTexCoord2f GLeeFuncPtr_glMultiTexCoord2f +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2fv +#define GLEE_H_DEFINED_glMultiTexCoord2fv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2FVPROC GLeeFuncPtr_glMultiTexCoord2fv; + #define glMultiTexCoord2fv GLeeFuncPtr_glMultiTexCoord2fv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2i +#define GLEE_H_DEFINED_glMultiTexCoord2i + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2IPROC GLeeFuncPtr_glMultiTexCoord2i; + #define glMultiTexCoord2i GLeeFuncPtr_glMultiTexCoord2i +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2iv +#define GLEE_H_DEFINED_glMultiTexCoord2iv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2IVPROC GLeeFuncPtr_glMultiTexCoord2iv; + #define glMultiTexCoord2iv GLeeFuncPtr_glMultiTexCoord2iv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2s +#define GLEE_H_DEFINED_glMultiTexCoord2s + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2SPROC GLeeFuncPtr_glMultiTexCoord2s; + #define glMultiTexCoord2s GLeeFuncPtr_glMultiTexCoord2s +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2sv +#define GLEE_H_DEFINED_glMultiTexCoord2sv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2SVPROC GLeeFuncPtr_glMultiTexCoord2sv; + #define glMultiTexCoord2sv GLeeFuncPtr_glMultiTexCoord2sv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3d +#define GLEE_H_DEFINED_glMultiTexCoord3d + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3DPROC GLeeFuncPtr_glMultiTexCoord3d; + #define glMultiTexCoord3d GLeeFuncPtr_glMultiTexCoord3d +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3dv +#define GLEE_H_DEFINED_glMultiTexCoord3dv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3DVPROC GLeeFuncPtr_glMultiTexCoord3dv; + #define glMultiTexCoord3dv GLeeFuncPtr_glMultiTexCoord3dv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3f +#define GLEE_H_DEFINED_glMultiTexCoord3f + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3FPROC GLeeFuncPtr_glMultiTexCoord3f; + #define glMultiTexCoord3f GLeeFuncPtr_glMultiTexCoord3f +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3fv +#define GLEE_H_DEFINED_glMultiTexCoord3fv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3FVPROC GLeeFuncPtr_glMultiTexCoord3fv; + #define glMultiTexCoord3fv GLeeFuncPtr_glMultiTexCoord3fv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3i +#define GLEE_H_DEFINED_glMultiTexCoord3i + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3IPROC GLeeFuncPtr_glMultiTexCoord3i; + #define glMultiTexCoord3i GLeeFuncPtr_glMultiTexCoord3i +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3iv +#define GLEE_H_DEFINED_glMultiTexCoord3iv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3IVPROC GLeeFuncPtr_glMultiTexCoord3iv; + #define glMultiTexCoord3iv GLeeFuncPtr_glMultiTexCoord3iv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3s +#define GLEE_H_DEFINED_glMultiTexCoord3s + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3SPROC GLeeFuncPtr_glMultiTexCoord3s; + #define glMultiTexCoord3s GLeeFuncPtr_glMultiTexCoord3s +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3sv +#define GLEE_H_DEFINED_glMultiTexCoord3sv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3SVPROC GLeeFuncPtr_glMultiTexCoord3sv; + #define glMultiTexCoord3sv GLeeFuncPtr_glMultiTexCoord3sv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4d +#define GLEE_H_DEFINED_glMultiTexCoord4d + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4DPROC GLeeFuncPtr_glMultiTexCoord4d; + #define glMultiTexCoord4d GLeeFuncPtr_glMultiTexCoord4d +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4dv +#define GLEE_H_DEFINED_glMultiTexCoord4dv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4DVPROC GLeeFuncPtr_glMultiTexCoord4dv; + #define glMultiTexCoord4dv GLeeFuncPtr_glMultiTexCoord4dv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4f +#define GLEE_H_DEFINED_glMultiTexCoord4f + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4FPROC GLeeFuncPtr_glMultiTexCoord4f; + #define glMultiTexCoord4f GLeeFuncPtr_glMultiTexCoord4f +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4fv +#define GLEE_H_DEFINED_glMultiTexCoord4fv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4FVPROC GLeeFuncPtr_glMultiTexCoord4fv; + #define glMultiTexCoord4fv GLeeFuncPtr_glMultiTexCoord4fv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4i +#define GLEE_H_DEFINED_glMultiTexCoord4i + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4IPROC GLeeFuncPtr_glMultiTexCoord4i; + #define glMultiTexCoord4i GLeeFuncPtr_glMultiTexCoord4i +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4iv +#define GLEE_H_DEFINED_glMultiTexCoord4iv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4IVPROC GLeeFuncPtr_glMultiTexCoord4iv; + #define glMultiTexCoord4iv GLeeFuncPtr_glMultiTexCoord4iv +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4s +#define GLEE_H_DEFINED_glMultiTexCoord4s + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4SPROC GLeeFuncPtr_glMultiTexCoord4s; + #define glMultiTexCoord4s GLeeFuncPtr_glMultiTexCoord4s +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4sv +#define GLEE_H_DEFINED_glMultiTexCoord4sv + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4SVPROC GLeeFuncPtr_glMultiTexCoord4sv; + #define glMultiTexCoord4sv GLeeFuncPtr_glMultiTexCoord4sv +#endif +#ifndef GLEE_H_DEFINED_glLoadTransposeMatrixf +#define GLEE_H_DEFINED_glLoadTransposeMatrixf + typedef void (APIENTRYP GLEEPFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat * m); + GLEE_EXTERN GLEEPFNGLLOADTRANSPOSEMATRIXFPROC GLeeFuncPtr_glLoadTransposeMatrixf; + #define glLoadTransposeMatrixf GLeeFuncPtr_glLoadTransposeMatrixf +#endif +#ifndef GLEE_H_DEFINED_glLoadTransposeMatrixd +#define GLEE_H_DEFINED_glLoadTransposeMatrixd + typedef void (APIENTRYP GLEEPFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble * m); + GLEE_EXTERN GLEEPFNGLLOADTRANSPOSEMATRIXDPROC GLeeFuncPtr_glLoadTransposeMatrixd; + #define glLoadTransposeMatrixd GLeeFuncPtr_glLoadTransposeMatrixd +#endif +#ifndef GLEE_H_DEFINED_glMultTransposeMatrixf +#define GLEE_H_DEFINED_glMultTransposeMatrixf + typedef void (APIENTRYP GLEEPFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat * m); + GLEE_EXTERN GLEEPFNGLMULTTRANSPOSEMATRIXFPROC GLeeFuncPtr_glMultTransposeMatrixf; + #define glMultTransposeMatrixf GLeeFuncPtr_glMultTransposeMatrixf +#endif +#ifndef GLEE_H_DEFINED_glMultTransposeMatrixd +#define GLEE_H_DEFINED_glMultTransposeMatrixd + typedef void (APIENTRYP GLEEPFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble * m); + GLEE_EXTERN GLEEPFNGLMULTTRANSPOSEMATRIXDPROC GLeeFuncPtr_glMultTransposeMatrixd; + #define glMultTransposeMatrixd GLeeFuncPtr_glMultTransposeMatrixd +#endif +#ifndef GLEE_H_DEFINED_glSampleCoverage +#define GLEE_H_DEFINED_glSampleCoverage + typedef void (APIENTRYP GLEEPFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + GLEE_EXTERN GLEEPFNGLSAMPLECOVERAGEPROC GLeeFuncPtr_glSampleCoverage; + #define glSampleCoverage GLeeFuncPtr_glSampleCoverage +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexImage3D +#define GLEE_H_DEFINED_glCompressedTexImage3D + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXIMAGE3DPROC GLeeFuncPtr_glCompressedTexImage3D; + #define glCompressedTexImage3D GLeeFuncPtr_glCompressedTexImage3D +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexImage2D +#define GLEE_H_DEFINED_glCompressedTexImage2D + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXIMAGE2DPROC GLeeFuncPtr_glCompressedTexImage2D; + #define glCompressedTexImage2D GLeeFuncPtr_glCompressedTexImage2D +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexImage1D +#define GLEE_H_DEFINED_glCompressedTexImage1D + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXIMAGE1DPROC GLeeFuncPtr_glCompressedTexImage1D; + #define glCompressedTexImage1D GLeeFuncPtr_glCompressedTexImage1D +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexSubImage3D +#define GLEE_H_DEFINED_glCompressedTexSubImage3D + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DPROC GLeeFuncPtr_glCompressedTexSubImage3D; + #define glCompressedTexSubImage3D GLeeFuncPtr_glCompressedTexSubImage3D +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexSubImage2D +#define GLEE_H_DEFINED_glCompressedTexSubImage2D + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DPROC GLeeFuncPtr_glCompressedTexSubImage2D; + #define glCompressedTexSubImage2D GLeeFuncPtr_glCompressedTexSubImage2D +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexSubImage1D +#define GLEE_H_DEFINED_glCompressedTexSubImage1D + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DPROC GLeeFuncPtr_glCompressedTexSubImage1D; + #define glCompressedTexSubImage1D GLeeFuncPtr_glCompressedTexSubImage1D +#endif +#ifndef GLEE_H_DEFINED_glGetCompressedTexImage +#define GLEE_H_DEFINED_glGetCompressedTexImage + typedef void (APIENTRYP GLEEPFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid * img); + GLEE_EXTERN GLEEPFNGLGETCOMPRESSEDTEXIMAGEPROC GLeeFuncPtr_glGetCompressedTexImage; + #define glGetCompressedTexImage GLeeFuncPtr_glGetCompressedTexImage +#endif +#endif + +/* GL_VERSION_1_4 */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#define __GLEE_GL_VERSION_1_4 1 +/* Constants */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#ifndef GLEE_H_DEFINED_glBlendFuncSeparate +#define GLEE_H_DEFINED_glBlendFuncSeparate + typedef void (APIENTRYP GLEEPFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + GLEE_EXTERN GLEEPFNGLBLENDFUNCSEPARATEPROC GLeeFuncPtr_glBlendFuncSeparate; + #define glBlendFuncSeparate GLeeFuncPtr_glBlendFuncSeparate +#endif +#ifndef GLEE_H_DEFINED_glFogCoordf +#define GLEE_H_DEFINED_glFogCoordf + typedef void (APIENTRYP GLEEPFNGLFOGCOORDFPROC) (GLfloat coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDFPROC GLeeFuncPtr_glFogCoordf; + #define glFogCoordf GLeeFuncPtr_glFogCoordf +#endif +#ifndef GLEE_H_DEFINED_glFogCoordfv +#define GLEE_H_DEFINED_glFogCoordfv + typedef void (APIENTRYP GLEEPFNGLFOGCOORDFVPROC) (const GLfloat * coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDFVPROC GLeeFuncPtr_glFogCoordfv; + #define glFogCoordfv GLeeFuncPtr_glFogCoordfv +#endif +#ifndef GLEE_H_DEFINED_glFogCoordd +#define GLEE_H_DEFINED_glFogCoordd + typedef void (APIENTRYP GLEEPFNGLFOGCOORDDPROC) (GLdouble coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDDPROC GLeeFuncPtr_glFogCoordd; + #define glFogCoordd GLeeFuncPtr_glFogCoordd +#endif +#ifndef GLEE_H_DEFINED_glFogCoorddv +#define GLEE_H_DEFINED_glFogCoorddv + typedef void (APIENTRYP GLEEPFNGLFOGCOORDDVPROC) (const GLdouble * coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDDVPROC GLeeFuncPtr_glFogCoorddv; + #define glFogCoorddv GLeeFuncPtr_glFogCoorddv +#endif +#ifndef GLEE_H_DEFINED_glFogCoordPointer +#define GLEE_H_DEFINED_glFogCoordPointer + typedef void (APIENTRYP GLEEPFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLFOGCOORDPOINTERPROC GLeeFuncPtr_glFogCoordPointer; + #define glFogCoordPointer GLeeFuncPtr_glFogCoordPointer +#endif +#ifndef GLEE_H_DEFINED_glMultiDrawArrays +#define GLEE_H_DEFINED_glMultiDrawArrays + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLMULTIDRAWARRAYSPROC GLeeFuncPtr_glMultiDrawArrays; + #define glMultiDrawArrays GLeeFuncPtr_glMultiDrawArrays +#endif +#ifndef GLEE_H_DEFINED_glMultiDrawElements +#define GLEE_H_DEFINED_glMultiDrawElements + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLMULTIDRAWELEMENTSPROC GLeeFuncPtr_glMultiDrawElements; + #define glMultiDrawElements GLeeFuncPtr_glMultiDrawElements +#endif +#ifndef GLEE_H_DEFINED_glPointParameterf +#define GLEE_H_DEFINED_glPointParameterf + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFPROC GLeeFuncPtr_glPointParameterf; + #define glPointParameterf GLeeFuncPtr_glPointParameterf +#endif +#ifndef GLEE_H_DEFINED_glPointParameterfv +#define GLEE_H_DEFINED_glPointParameterfv + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFVPROC GLeeFuncPtr_glPointParameterfv; + #define glPointParameterfv GLeeFuncPtr_glPointParameterfv +#endif +#ifndef GLEE_H_DEFINED_glPointParameteri +#define GLEE_H_DEFINED_glPointParameteri + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERIPROC GLeeFuncPtr_glPointParameteri; + #define glPointParameteri GLeeFuncPtr_glPointParameteri +#endif +#ifndef GLEE_H_DEFINED_glPointParameteriv +#define GLEE_H_DEFINED_glPointParameteriv + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERIVPROC GLeeFuncPtr_glPointParameteriv; + #define glPointParameteriv GLeeFuncPtr_glPointParameteriv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3b +#define GLEE_H_DEFINED_glSecondaryColor3b + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3BPROC GLeeFuncPtr_glSecondaryColor3b; + #define glSecondaryColor3b GLeeFuncPtr_glSecondaryColor3b +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3bv +#define GLEE_H_DEFINED_glSecondaryColor3bv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3BVPROC) (const GLbyte * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3BVPROC GLeeFuncPtr_glSecondaryColor3bv; + #define glSecondaryColor3bv GLeeFuncPtr_glSecondaryColor3bv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3d +#define GLEE_H_DEFINED_glSecondaryColor3d + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3DPROC GLeeFuncPtr_glSecondaryColor3d; + #define glSecondaryColor3d GLeeFuncPtr_glSecondaryColor3d +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3dv +#define GLEE_H_DEFINED_glSecondaryColor3dv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3DVPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3DVPROC GLeeFuncPtr_glSecondaryColor3dv; + #define glSecondaryColor3dv GLeeFuncPtr_glSecondaryColor3dv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3f +#define GLEE_H_DEFINED_glSecondaryColor3f + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3FPROC GLeeFuncPtr_glSecondaryColor3f; + #define glSecondaryColor3f GLeeFuncPtr_glSecondaryColor3f +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3fv +#define GLEE_H_DEFINED_glSecondaryColor3fv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3FVPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3FVPROC GLeeFuncPtr_glSecondaryColor3fv; + #define glSecondaryColor3fv GLeeFuncPtr_glSecondaryColor3fv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3i +#define GLEE_H_DEFINED_glSecondaryColor3i + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3IPROC GLeeFuncPtr_glSecondaryColor3i; + #define glSecondaryColor3i GLeeFuncPtr_glSecondaryColor3i +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3iv +#define GLEE_H_DEFINED_glSecondaryColor3iv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3IVPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3IVPROC GLeeFuncPtr_glSecondaryColor3iv; + #define glSecondaryColor3iv GLeeFuncPtr_glSecondaryColor3iv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3s +#define GLEE_H_DEFINED_glSecondaryColor3s + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3SPROC GLeeFuncPtr_glSecondaryColor3s; + #define glSecondaryColor3s GLeeFuncPtr_glSecondaryColor3s +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3sv +#define GLEE_H_DEFINED_glSecondaryColor3sv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3SVPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3SVPROC GLeeFuncPtr_glSecondaryColor3sv; + #define glSecondaryColor3sv GLeeFuncPtr_glSecondaryColor3sv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3ub +#define GLEE_H_DEFINED_glSecondaryColor3ub + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UBPROC GLeeFuncPtr_glSecondaryColor3ub; + #define glSecondaryColor3ub GLeeFuncPtr_glSecondaryColor3ub +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3ubv +#define GLEE_H_DEFINED_glSecondaryColor3ubv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UBVPROC GLeeFuncPtr_glSecondaryColor3ubv; + #define glSecondaryColor3ubv GLeeFuncPtr_glSecondaryColor3ubv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3ui +#define GLEE_H_DEFINED_glSecondaryColor3ui + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UIPROC GLeeFuncPtr_glSecondaryColor3ui; + #define glSecondaryColor3ui GLeeFuncPtr_glSecondaryColor3ui +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3uiv +#define GLEE_H_DEFINED_glSecondaryColor3uiv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UIVPROC) (const GLuint * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UIVPROC GLeeFuncPtr_glSecondaryColor3uiv; + #define glSecondaryColor3uiv GLeeFuncPtr_glSecondaryColor3uiv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3us +#define GLEE_H_DEFINED_glSecondaryColor3us + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3USPROC GLeeFuncPtr_glSecondaryColor3us; + #define glSecondaryColor3us GLeeFuncPtr_glSecondaryColor3us +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3usv +#define GLEE_H_DEFINED_glSecondaryColor3usv + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3USVPROC) (const GLushort * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3USVPROC GLeeFuncPtr_glSecondaryColor3usv; + #define glSecondaryColor3usv GLeeFuncPtr_glSecondaryColor3usv +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColorPointer +#define GLEE_H_DEFINED_glSecondaryColorPointer + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLORPOINTERPROC GLeeFuncPtr_glSecondaryColorPointer; + #define glSecondaryColorPointer GLeeFuncPtr_glSecondaryColorPointer +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2d +#define GLEE_H_DEFINED_glWindowPos2d + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2DPROC GLeeFuncPtr_glWindowPos2d; + #define glWindowPos2d GLeeFuncPtr_glWindowPos2d +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2dv +#define GLEE_H_DEFINED_glWindowPos2dv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2DVPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2DVPROC GLeeFuncPtr_glWindowPos2dv; + #define glWindowPos2dv GLeeFuncPtr_glWindowPos2dv +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2f +#define GLEE_H_DEFINED_glWindowPos2f + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2FPROC GLeeFuncPtr_glWindowPos2f; + #define glWindowPos2f GLeeFuncPtr_glWindowPos2f +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2fv +#define GLEE_H_DEFINED_glWindowPos2fv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2FVPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2FVPROC GLeeFuncPtr_glWindowPos2fv; + #define glWindowPos2fv GLeeFuncPtr_glWindowPos2fv +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2i +#define GLEE_H_DEFINED_glWindowPos2i + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2IPROC) (GLint x, GLint y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2IPROC GLeeFuncPtr_glWindowPos2i; + #define glWindowPos2i GLeeFuncPtr_glWindowPos2i +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2iv +#define GLEE_H_DEFINED_glWindowPos2iv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2IVPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2IVPROC GLeeFuncPtr_glWindowPos2iv; + #define glWindowPos2iv GLeeFuncPtr_glWindowPos2iv +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2s +#define GLEE_H_DEFINED_glWindowPos2s + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2SPROC GLeeFuncPtr_glWindowPos2s; + #define glWindowPos2s GLeeFuncPtr_glWindowPos2s +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2sv +#define GLEE_H_DEFINED_glWindowPos2sv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2SVPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2SVPROC GLeeFuncPtr_glWindowPos2sv; + #define glWindowPos2sv GLeeFuncPtr_glWindowPos2sv +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3d +#define GLEE_H_DEFINED_glWindowPos3d + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3DPROC GLeeFuncPtr_glWindowPos3d; + #define glWindowPos3d GLeeFuncPtr_glWindowPos3d +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3dv +#define GLEE_H_DEFINED_glWindowPos3dv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3DVPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3DVPROC GLeeFuncPtr_glWindowPos3dv; + #define glWindowPos3dv GLeeFuncPtr_glWindowPos3dv +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3f +#define GLEE_H_DEFINED_glWindowPos3f + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3FPROC GLeeFuncPtr_glWindowPos3f; + #define glWindowPos3f GLeeFuncPtr_glWindowPos3f +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3fv +#define GLEE_H_DEFINED_glWindowPos3fv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3FVPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3FVPROC GLeeFuncPtr_glWindowPos3fv; + #define glWindowPos3fv GLeeFuncPtr_glWindowPos3fv +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3i +#define GLEE_H_DEFINED_glWindowPos3i + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3IPROC GLeeFuncPtr_glWindowPos3i; + #define glWindowPos3i GLeeFuncPtr_glWindowPos3i +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3iv +#define GLEE_H_DEFINED_glWindowPos3iv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3IVPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3IVPROC GLeeFuncPtr_glWindowPos3iv; + #define glWindowPos3iv GLeeFuncPtr_glWindowPos3iv +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3s +#define GLEE_H_DEFINED_glWindowPos3s + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3SPROC GLeeFuncPtr_glWindowPos3s; + #define glWindowPos3s GLeeFuncPtr_glWindowPos3s +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3sv +#define GLEE_H_DEFINED_glWindowPos3sv + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3SVPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3SVPROC GLeeFuncPtr_glWindowPos3sv; + #define glWindowPos3sv GLeeFuncPtr_glWindowPos3sv +#endif +#endif + +/* GL_VERSION_1_5 */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#define __GLEE_GL_VERSION_1_5 1 +/* Constants */ +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#ifndef GLEE_H_DEFINED_glGenQueries +#define GLEE_H_DEFINED_glGenQueries + typedef void (APIENTRYP GLEEPFNGLGENQUERIESPROC) (GLsizei n, GLuint * ids); + GLEE_EXTERN GLEEPFNGLGENQUERIESPROC GLeeFuncPtr_glGenQueries; + #define glGenQueries GLeeFuncPtr_glGenQueries +#endif +#ifndef GLEE_H_DEFINED_glDeleteQueries +#define GLEE_H_DEFINED_glDeleteQueries + typedef void (APIENTRYP GLEEPFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint * ids); + GLEE_EXTERN GLEEPFNGLDELETEQUERIESPROC GLeeFuncPtr_glDeleteQueries; + #define glDeleteQueries GLeeFuncPtr_glDeleteQueries +#endif +#ifndef GLEE_H_DEFINED_glIsQuery +#define GLEE_H_DEFINED_glIsQuery + typedef GLboolean (APIENTRYP GLEEPFNGLISQUERYPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLISQUERYPROC GLeeFuncPtr_glIsQuery; + #define glIsQuery GLeeFuncPtr_glIsQuery +#endif +#ifndef GLEE_H_DEFINED_glBeginQuery +#define GLEE_H_DEFINED_glBeginQuery + typedef void (APIENTRYP GLEEPFNGLBEGINQUERYPROC) (GLenum target, GLuint id); + GLEE_EXTERN GLEEPFNGLBEGINQUERYPROC GLeeFuncPtr_glBeginQuery; + #define glBeginQuery GLeeFuncPtr_glBeginQuery +#endif +#ifndef GLEE_H_DEFINED_glEndQuery +#define GLEE_H_DEFINED_glEndQuery + typedef void (APIENTRYP GLEEPFNGLENDQUERYPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLENDQUERYPROC GLeeFuncPtr_glEndQuery; + #define glEndQuery GLeeFuncPtr_glEndQuery +#endif +#ifndef GLEE_H_DEFINED_glGetQueryiv +#define GLEE_H_DEFINED_glGetQueryiv + typedef void (APIENTRYP GLEEPFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETQUERYIVPROC GLeeFuncPtr_glGetQueryiv; + #define glGetQueryiv GLeeFuncPtr_glGetQueryiv +#endif +#ifndef GLEE_H_DEFINED_glGetQueryObjectiv +#define GLEE_H_DEFINED_glGetQueryObjectiv + typedef void (APIENTRYP GLEEPFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETQUERYOBJECTIVPROC GLeeFuncPtr_glGetQueryObjectiv; + #define glGetQueryObjectiv GLeeFuncPtr_glGetQueryObjectiv +#endif +#ifndef GLEE_H_DEFINED_glGetQueryObjectuiv +#define GLEE_H_DEFINED_glGetQueryObjectuiv + typedef void (APIENTRYP GLEEPFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETQUERYOBJECTUIVPROC GLeeFuncPtr_glGetQueryObjectuiv; + #define glGetQueryObjectuiv GLeeFuncPtr_glGetQueryObjectuiv +#endif +#ifndef GLEE_H_DEFINED_glBindBuffer +#define GLEE_H_DEFINED_glBindBuffer + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); + GLEE_EXTERN GLEEPFNGLBINDBUFFERPROC GLeeFuncPtr_glBindBuffer; + #define glBindBuffer GLeeFuncPtr_glBindBuffer +#endif +#ifndef GLEE_H_DEFINED_glDeleteBuffers +#define GLEE_H_DEFINED_glDeleteBuffers + typedef void (APIENTRYP GLEEPFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint * buffers); + GLEE_EXTERN GLEEPFNGLDELETEBUFFERSPROC GLeeFuncPtr_glDeleteBuffers; + #define glDeleteBuffers GLeeFuncPtr_glDeleteBuffers +#endif +#ifndef GLEE_H_DEFINED_glGenBuffers +#define GLEE_H_DEFINED_glGenBuffers + typedef void (APIENTRYP GLEEPFNGLGENBUFFERSPROC) (GLsizei n, GLuint * buffers); + GLEE_EXTERN GLEEPFNGLGENBUFFERSPROC GLeeFuncPtr_glGenBuffers; + #define glGenBuffers GLeeFuncPtr_glGenBuffers +#endif +#ifndef GLEE_H_DEFINED_glIsBuffer +#define GLEE_H_DEFINED_glIsBuffer + typedef GLboolean (APIENTRYP GLEEPFNGLISBUFFERPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLISBUFFERPROC GLeeFuncPtr_glIsBuffer; + #define glIsBuffer GLeeFuncPtr_glIsBuffer +#endif +#ifndef GLEE_H_DEFINED_glBufferData +#define GLEE_H_DEFINED_glBufferData + typedef void (APIENTRYP GLEEPFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); + GLEE_EXTERN GLEEPFNGLBUFFERDATAPROC GLeeFuncPtr_glBufferData; + #define glBufferData GLeeFuncPtr_glBufferData +#endif +#ifndef GLEE_H_DEFINED_glBufferSubData +#define GLEE_H_DEFINED_glBufferSubData + typedef void (APIENTRYP GLEEPFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLBUFFERSUBDATAPROC GLeeFuncPtr_glBufferSubData; + #define glBufferSubData GLeeFuncPtr_glBufferSubData +#endif +#ifndef GLEE_H_DEFINED_glGetBufferSubData +#define GLEE_H_DEFINED_glGetBufferSubData + typedef void (APIENTRYP GLEEPFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data); + GLEE_EXTERN GLEEPFNGLGETBUFFERSUBDATAPROC GLeeFuncPtr_glGetBufferSubData; + #define glGetBufferSubData GLeeFuncPtr_glGetBufferSubData +#endif +#ifndef GLEE_H_DEFINED_glMapBuffer +#define GLEE_H_DEFINED_glMapBuffer + typedef GLvoid* (APIENTRYP GLEEPFNGLMAPBUFFERPROC) (GLenum target, GLenum access); + GLEE_EXTERN GLEEPFNGLMAPBUFFERPROC GLeeFuncPtr_glMapBuffer; + #define glMapBuffer GLeeFuncPtr_glMapBuffer +#endif +#ifndef GLEE_H_DEFINED_glUnmapBuffer +#define GLEE_H_DEFINED_glUnmapBuffer + typedef GLboolean (APIENTRYP GLEEPFNGLUNMAPBUFFERPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLUNMAPBUFFERPROC GLeeFuncPtr_glUnmapBuffer; + #define glUnmapBuffer GLeeFuncPtr_glUnmapBuffer +#endif +#ifndef GLEE_H_DEFINED_glGetBufferParameteriv +#define GLEE_H_DEFINED_glGetBufferParameteriv + typedef void (APIENTRYP GLEEPFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETBUFFERPARAMETERIVPROC GLeeFuncPtr_glGetBufferParameteriv; + #define glGetBufferParameteriv GLeeFuncPtr_glGetBufferParameteriv +#endif +#ifndef GLEE_H_DEFINED_glGetBufferPointerv +#define GLEE_H_DEFINED_glGetBufferPointerv + typedef void (APIENTRYP GLEEPFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* * params); + GLEE_EXTERN GLEEPFNGLGETBUFFERPOINTERVPROC GLeeFuncPtr_glGetBufferPointerv; + #define glGetBufferPointerv GLeeFuncPtr_glGetBufferPointerv +#endif +#endif + +/* GL_VERSION_2_0 */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#define __GLEE_GL_VERSION_2_0 1 +/* Constants */ +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#ifndef GLEE_H_DEFINED_glBlendEquationSeparate +#define GLEE_H_DEFINED_glBlendEquationSeparate + typedef void (APIENTRYP GLEEPFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); + GLEE_EXTERN GLEEPFNGLBLENDEQUATIONSEPARATEPROC GLeeFuncPtr_glBlendEquationSeparate; + #define glBlendEquationSeparate GLeeFuncPtr_glBlendEquationSeparate +#endif +#ifndef GLEE_H_DEFINED_glDrawBuffers +#define GLEE_H_DEFINED_glDrawBuffers + typedef void (APIENTRYP GLEEPFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum * bufs); + GLEE_EXTERN GLEEPFNGLDRAWBUFFERSPROC GLeeFuncPtr_glDrawBuffers; + #define glDrawBuffers GLeeFuncPtr_glDrawBuffers +#endif +#ifndef GLEE_H_DEFINED_glStencilOpSeparate +#define GLEE_H_DEFINED_glStencilOpSeparate + typedef void (APIENTRYP GLEEPFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + GLEE_EXTERN GLEEPFNGLSTENCILOPSEPARATEPROC GLeeFuncPtr_glStencilOpSeparate; + #define glStencilOpSeparate GLeeFuncPtr_glStencilOpSeparate +#endif +#ifndef GLEE_H_DEFINED_glStencilFuncSeparate +#define GLEE_H_DEFINED_glStencilFuncSeparate + typedef void (APIENTRYP GLEEPFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); + GLEE_EXTERN GLEEPFNGLSTENCILFUNCSEPARATEPROC GLeeFuncPtr_glStencilFuncSeparate; + #define glStencilFuncSeparate GLeeFuncPtr_glStencilFuncSeparate +#endif +#ifndef GLEE_H_DEFINED_glStencilMaskSeparate +#define GLEE_H_DEFINED_glStencilMaskSeparate + typedef void (APIENTRYP GLEEPFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); + GLEE_EXTERN GLEEPFNGLSTENCILMASKSEPARATEPROC GLeeFuncPtr_glStencilMaskSeparate; + #define glStencilMaskSeparate GLeeFuncPtr_glStencilMaskSeparate +#endif +#ifndef GLEE_H_DEFINED_glAttachShader +#define GLEE_H_DEFINED_glAttachShader + typedef void (APIENTRYP GLEEPFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); + GLEE_EXTERN GLEEPFNGLATTACHSHADERPROC GLeeFuncPtr_glAttachShader; + #define glAttachShader GLeeFuncPtr_glAttachShader +#endif +#ifndef GLEE_H_DEFINED_glBindAttribLocation +#define GLEE_H_DEFINED_glBindAttribLocation + typedef void (APIENTRYP GLEEPFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar * name); + GLEE_EXTERN GLEEPFNGLBINDATTRIBLOCATIONPROC GLeeFuncPtr_glBindAttribLocation; + #define glBindAttribLocation GLeeFuncPtr_glBindAttribLocation +#endif +#ifndef GLEE_H_DEFINED_glCompileShader +#define GLEE_H_DEFINED_glCompileShader + typedef void (APIENTRYP GLEEPFNGLCOMPILESHADERPROC) (GLuint shader); + GLEE_EXTERN GLEEPFNGLCOMPILESHADERPROC GLeeFuncPtr_glCompileShader; + #define glCompileShader GLeeFuncPtr_glCompileShader +#endif +#ifndef GLEE_H_DEFINED_glCreateProgram +#define GLEE_H_DEFINED_glCreateProgram + typedef GLuint (APIENTRYP GLEEPFNGLCREATEPROGRAMPROC) (); + GLEE_EXTERN GLEEPFNGLCREATEPROGRAMPROC GLeeFuncPtr_glCreateProgram; + #define glCreateProgram GLeeFuncPtr_glCreateProgram +#endif +#ifndef GLEE_H_DEFINED_glCreateShader +#define GLEE_H_DEFINED_glCreateShader + typedef GLuint (APIENTRYP GLEEPFNGLCREATESHADERPROC) (GLenum type); + GLEE_EXTERN GLEEPFNGLCREATESHADERPROC GLeeFuncPtr_glCreateShader; + #define glCreateShader GLeeFuncPtr_glCreateShader +#endif +#ifndef GLEE_H_DEFINED_glDeleteProgram +#define GLEE_H_DEFINED_glDeleteProgram + typedef void (APIENTRYP GLEEPFNGLDELETEPROGRAMPROC) (GLuint program); + GLEE_EXTERN GLEEPFNGLDELETEPROGRAMPROC GLeeFuncPtr_glDeleteProgram; + #define glDeleteProgram GLeeFuncPtr_glDeleteProgram +#endif +#ifndef GLEE_H_DEFINED_glDeleteShader +#define GLEE_H_DEFINED_glDeleteShader + typedef void (APIENTRYP GLEEPFNGLDELETESHADERPROC) (GLuint shader); + GLEE_EXTERN GLEEPFNGLDELETESHADERPROC GLeeFuncPtr_glDeleteShader; + #define glDeleteShader GLeeFuncPtr_glDeleteShader +#endif +#ifndef GLEE_H_DEFINED_glDetachShader +#define GLEE_H_DEFINED_glDetachShader + typedef void (APIENTRYP GLEEPFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); + GLEE_EXTERN GLEEPFNGLDETACHSHADERPROC GLeeFuncPtr_glDetachShader; + #define glDetachShader GLeeFuncPtr_glDetachShader +#endif +#ifndef GLEE_H_DEFINED_glDisableVertexAttribArray +#define GLEE_H_DEFINED_glDisableVertexAttribArray + typedef void (APIENTRYP GLEEPFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); + GLEE_EXTERN GLEEPFNGLDISABLEVERTEXATTRIBARRAYPROC GLeeFuncPtr_glDisableVertexAttribArray; + #define glDisableVertexAttribArray GLeeFuncPtr_glDisableVertexAttribArray +#endif +#ifndef GLEE_H_DEFINED_glEnableVertexAttribArray +#define GLEE_H_DEFINED_glEnableVertexAttribArray + typedef void (APIENTRYP GLEEPFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); + GLEE_EXTERN GLEEPFNGLENABLEVERTEXATTRIBARRAYPROC GLeeFuncPtr_glEnableVertexAttribArray; + #define glEnableVertexAttribArray GLeeFuncPtr_glEnableVertexAttribArray +#endif +#ifndef GLEE_H_DEFINED_glGetActiveAttrib +#define GLEE_H_DEFINED_glGetActiveAttrib + typedef void (APIENTRYP GLEEPFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); + GLEE_EXTERN GLEEPFNGLGETACTIVEATTRIBPROC GLeeFuncPtr_glGetActiveAttrib; + #define glGetActiveAttrib GLeeFuncPtr_glGetActiveAttrib +#endif +#ifndef GLEE_H_DEFINED_glGetActiveUniform +#define GLEE_H_DEFINED_glGetActiveUniform + typedef void (APIENTRYP GLEEPFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); + GLEE_EXTERN GLEEPFNGLGETACTIVEUNIFORMPROC GLeeFuncPtr_glGetActiveUniform; + #define glGetActiveUniform GLeeFuncPtr_glGetActiveUniform +#endif +#ifndef GLEE_H_DEFINED_glGetAttachedShaders +#define GLEE_H_DEFINED_glGetAttachedShaders + typedef void (APIENTRYP GLEEPFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei * count, GLuint * obj); + GLEE_EXTERN GLEEPFNGLGETATTACHEDSHADERSPROC GLeeFuncPtr_glGetAttachedShaders; + #define glGetAttachedShaders GLeeFuncPtr_glGetAttachedShaders +#endif +#ifndef GLEE_H_DEFINED_glGetAttribLocation +#define GLEE_H_DEFINED_glGetAttribLocation + typedef GLint (APIENTRYP GLEEPFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETATTRIBLOCATIONPROC GLeeFuncPtr_glGetAttribLocation; + #define glGetAttribLocation GLeeFuncPtr_glGetAttribLocation +#endif +#ifndef GLEE_H_DEFINED_glGetProgramiv +#define GLEE_H_DEFINED_glGetProgramiv + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMIVPROC GLeeFuncPtr_glGetProgramiv; + #define glGetProgramiv GLeeFuncPtr_glGetProgramiv +#endif +#ifndef GLEE_H_DEFINED_glGetProgramInfoLog +#define GLEE_H_DEFINED_glGetProgramInfoLog + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); + GLEE_EXTERN GLEEPFNGLGETPROGRAMINFOLOGPROC GLeeFuncPtr_glGetProgramInfoLog; + #define glGetProgramInfoLog GLeeFuncPtr_glGetProgramInfoLog +#endif +#ifndef GLEE_H_DEFINED_glGetShaderiv +#define GLEE_H_DEFINED_glGetShaderiv + typedef void (APIENTRYP GLEEPFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETSHADERIVPROC GLeeFuncPtr_glGetShaderiv; + #define glGetShaderiv GLeeFuncPtr_glGetShaderiv +#endif +#ifndef GLEE_H_DEFINED_glGetShaderInfoLog +#define GLEE_H_DEFINED_glGetShaderInfoLog + typedef void (APIENTRYP GLEEPFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); + GLEE_EXTERN GLEEPFNGLGETSHADERINFOLOGPROC GLeeFuncPtr_glGetShaderInfoLog; + #define glGetShaderInfoLog GLeeFuncPtr_glGetShaderInfoLog +#endif +#ifndef GLEE_H_DEFINED_glGetShaderSource +#define GLEE_H_DEFINED_glGetShaderSource + typedef void (APIENTRYP GLEEPFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); + GLEE_EXTERN GLEEPFNGLGETSHADERSOURCEPROC GLeeFuncPtr_glGetShaderSource; + #define glGetShaderSource GLeeFuncPtr_glGetShaderSource +#endif +#ifndef GLEE_H_DEFINED_glGetUniformLocation +#define GLEE_H_DEFINED_glGetUniformLocation + typedef GLint (APIENTRYP GLEEPFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETUNIFORMLOCATIONPROC GLeeFuncPtr_glGetUniformLocation; + #define glGetUniformLocation GLeeFuncPtr_glGetUniformLocation +#endif +#ifndef GLEE_H_DEFINED_glGetUniformfv +#define GLEE_H_DEFINED_glGetUniformfv + typedef void (APIENTRYP GLEEPFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETUNIFORMFVPROC GLeeFuncPtr_glGetUniformfv; + #define glGetUniformfv GLeeFuncPtr_glGetUniformfv +#endif +#ifndef GLEE_H_DEFINED_glGetUniformiv +#define GLEE_H_DEFINED_glGetUniformiv + typedef void (APIENTRYP GLEEPFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint * params); + GLEE_EXTERN GLEEPFNGLGETUNIFORMIVPROC GLeeFuncPtr_glGetUniformiv; + #define glGetUniformiv GLeeFuncPtr_glGetUniformiv +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribdv +#define GLEE_H_DEFINED_glGetVertexAttribdv + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBDVPROC GLeeFuncPtr_glGetVertexAttribdv; + #define glGetVertexAttribdv GLeeFuncPtr_glGetVertexAttribdv +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribfv +#define GLEE_H_DEFINED_glGetVertexAttribfv + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBFVPROC GLeeFuncPtr_glGetVertexAttribfv; + #define glGetVertexAttribfv GLeeFuncPtr_glGetVertexAttribfv +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribiv +#define GLEE_H_DEFINED_glGetVertexAttribiv + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBIVPROC GLeeFuncPtr_glGetVertexAttribiv; + #define glGetVertexAttribiv GLeeFuncPtr_glGetVertexAttribiv +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribPointerv +#define GLEE_H_DEFINED_glGetVertexAttribPointerv + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBPOINTERVPROC GLeeFuncPtr_glGetVertexAttribPointerv; + #define glGetVertexAttribPointerv GLeeFuncPtr_glGetVertexAttribPointerv +#endif +#ifndef GLEE_H_DEFINED_glIsProgram +#define GLEE_H_DEFINED_glIsProgram + typedef GLboolean (APIENTRYP GLEEPFNGLISPROGRAMPROC) (GLuint program); + GLEE_EXTERN GLEEPFNGLISPROGRAMPROC GLeeFuncPtr_glIsProgram; + #define glIsProgram GLeeFuncPtr_glIsProgram +#endif +#ifndef GLEE_H_DEFINED_glIsShader +#define GLEE_H_DEFINED_glIsShader + typedef GLboolean (APIENTRYP GLEEPFNGLISSHADERPROC) (GLuint shader); + GLEE_EXTERN GLEEPFNGLISSHADERPROC GLeeFuncPtr_glIsShader; + #define glIsShader GLeeFuncPtr_glIsShader +#endif +#ifndef GLEE_H_DEFINED_glLinkProgram +#define GLEE_H_DEFINED_glLinkProgram + typedef void (APIENTRYP GLEEPFNGLLINKPROGRAMPROC) (GLuint program); + GLEE_EXTERN GLEEPFNGLLINKPROGRAMPROC GLeeFuncPtr_glLinkProgram; + #define glLinkProgram GLeeFuncPtr_glLinkProgram +#endif +#ifndef GLEE_H_DEFINED_glShaderSource +#define GLEE_H_DEFINED_glShaderSource + typedef void (APIENTRYP GLEEPFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* * string, const GLint * length); + GLEE_EXTERN GLEEPFNGLSHADERSOURCEPROC GLeeFuncPtr_glShaderSource; + #define glShaderSource GLeeFuncPtr_glShaderSource +#endif +#ifndef GLEE_H_DEFINED_glUseProgram +#define GLEE_H_DEFINED_glUseProgram + typedef void (APIENTRYP GLEEPFNGLUSEPROGRAMPROC) (GLuint program); + GLEE_EXTERN GLEEPFNGLUSEPROGRAMPROC GLeeFuncPtr_glUseProgram; + #define glUseProgram GLeeFuncPtr_glUseProgram +#endif +#ifndef GLEE_H_DEFINED_glUniform1f +#define GLEE_H_DEFINED_glUniform1f + typedef void (APIENTRYP GLEEPFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); + GLEE_EXTERN GLEEPFNGLUNIFORM1FPROC GLeeFuncPtr_glUniform1f; + #define glUniform1f GLeeFuncPtr_glUniform1f +#endif +#ifndef GLEE_H_DEFINED_glUniform2f +#define GLEE_H_DEFINED_glUniform2f + typedef void (APIENTRYP GLEEPFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); + GLEE_EXTERN GLEEPFNGLUNIFORM2FPROC GLeeFuncPtr_glUniform2f; + #define glUniform2f GLeeFuncPtr_glUniform2f +#endif +#ifndef GLEE_H_DEFINED_glUniform3f +#define GLEE_H_DEFINED_glUniform3f + typedef void (APIENTRYP GLEEPFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + GLEE_EXTERN GLEEPFNGLUNIFORM3FPROC GLeeFuncPtr_glUniform3f; + #define glUniform3f GLeeFuncPtr_glUniform3f +#endif +#ifndef GLEE_H_DEFINED_glUniform4f +#define GLEE_H_DEFINED_glUniform4f + typedef void (APIENTRYP GLEEPFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + GLEE_EXTERN GLEEPFNGLUNIFORM4FPROC GLeeFuncPtr_glUniform4f; + #define glUniform4f GLeeFuncPtr_glUniform4f +#endif +#ifndef GLEE_H_DEFINED_glUniform1i +#define GLEE_H_DEFINED_glUniform1i + typedef void (APIENTRYP GLEEPFNGLUNIFORM1IPROC) (GLint location, GLint v0); + GLEE_EXTERN GLEEPFNGLUNIFORM1IPROC GLeeFuncPtr_glUniform1i; + #define glUniform1i GLeeFuncPtr_glUniform1i +#endif +#ifndef GLEE_H_DEFINED_glUniform2i +#define GLEE_H_DEFINED_glUniform2i + typedef void (APIENTRYP GLEEPFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); + GLEE_EXTERN GLEEPFNGLUNIFORM2IPROC GLeeFuncPtr_glUniform2i; + #define glUniform2i GLeeFuncPtr_glUniform2i +#endif +#ifndef GLEE_H_DEFINED_glUniform3i +#define GLEE_H_DEFINED_glUniform3i + typedef void (APIENTRYP GLEEPFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); + GLEE_EXTERN GLEEPFNGLUNIFORM3IPROC GLeeFuncPtr_glUniform3i; + #define glUniform3i GLeeFuncPtr_glUniform3i +#endif +#ifndef GLEE_H_DEFINED_glUniform4i +#define GLEE_H_DEFINED_glUniform4i + typedef void (APIENTRYP GLEEPFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + GLEE_EXTERN GLEEPFNGLUNIFORM4IPROC GLeeFuncPtr_glUniform4i; + #define glUniform4i GLeeFuncPtr_glUniform4i +#endif +#ifndef GLEE_H_DEFINED_glUniform1fv +#define GLEE_H_DEFINED_glUniform1fv + typedef void (APIENTRYP GLEEPFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM1FVPROC GLeeFuncPtr_glUniform1fv; + #define glUniform1fv GLeeFuncPtr_glUniform1fv +#endif +#ifndef GLEE_H_DEFINED_glUniform2fv +#define GLEE_H_DEFINED_glUniform2fv + typedef void (APIENTRYP GLEEPFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM2FVPROC GLeeFuncPtr_glUniform2fv; + #define glUniform2fv GLeeFuncPtr_glUniform2fv +#endif +#ifndef GLEE_H_DEFINED_glUniform3fv +#define GLEE_H_DEFINED_glUniform3fv + typedef void (APIENTRYP GLEEPFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM3FVPROC GLeeFuncPtr_glUniform3fv; + #define glUniform3fv GLeeFuncPtr_glUniform3fv +#endif +#ifndef GLEE_H_DEFINED_glUniform4fv +#define GLEE_H_DEFINED_glUniform4fv + typedef void (APIENTRYP GLEEPFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM4FVPROC GLeeFuncPtr_glUniform4fv; + #define glUniform4fv GLeeFuncPtr_glUniform4fv +#endif +#ifndef GLEE_H_DEFINED_glUniform1iv +#define GLEE_H_DEFINED_glUniform1iv + typedef void (APIENTRYP GLEEPFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM1IVPROC GLeeFuncPtr_glUniform1iv; + #define glUniform1iv GLeeFuncPtr_glUniform1iv +#endif +#ifndef GLEE_H_DEFINED_glUniform2iv +#define GLEE_H_DEFINED_glUniform2iv + typedef void (APIENTRYP GLEEPFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM2IVPROC GLeeFuncPtr_glUniform2iv; + #define glUniform2iv GLeeFuncPtr_glUniform2iv +#endif +#ifndef GLEE_H_DEFINED_glUniform3iv +#define GLEE_H_DEFINED_glUniform3iv + typedef void (APIENTRYP GLEEPFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM3IVPROC GLeeFuncPtr_glUniform3iv; + #define glUniform3iv GLeeFuncPtr_glUniform3iv +#endif +#ifndef GLEE_H_DEFINED_glUniform4iv +#define GLEE_H_DEFINED_glUniform4iv + typedef void (APIENTRYP GLEEPFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM4IVPROC GLeeFuncPtr_glUniform4iv; + #define glUniform4iv GLeeFuncPtr_glUniform4iv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix2fv +#define GLEE_H_DEFINED_glUniformMatrix2fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX2FVPROC GLeeFuncPtr_glUniformMatrix2fv; + #define glUniformMatrix2fv GLeeFuncPtr_glUniformMatrix2fv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix3fv +#define GLEE_H_DEFINED_glUniformMatrix3fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX3FVPROC GLeeFuncPtr_glUniformMatrix3fv; + #define glUniformMatrix3fv GLeeFuncPtr_glUniformMatrix3fv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix4fv +#define GLEE_H_DEFINED_glUniformMatrix4fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX4FVPROC GLeeFuncPtr_glUniformMatrix4fv; + #define glUniformMatrix4fv GLeeFuncPtr_glUniformMatrix4fv +#endif +#ifndef GLEE_H_DEFINED_glValidateProgram +#define GLEE_H_DEFINED_glValidateProgram + typedef void (APIENTRYP GLEEPFNGLVALIDATEPROGRAMPROC) (GLuint program); + GLEE_EXTERN GLEEPFNGLVALIDATEPROGRAMPROC GLeeFuncPtr_glValidateProgram; + #define glValidateProgram GLeeFuncPtr_glValidateProgram +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1d +#define GLEE_H_DEFINED_glVertexAttrib1d + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1DPROC GLeeFuncPtr_glVertexAttrib1d; + #define glVertexAttrib1d GLeeFuncPtr_glVertexAttrib1d +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1dv +#define GLEE_H_DEFINED_glVertexAttrib1dv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1DVPROC GLeeFuncPtr_glVertexAttrib1dv; + #define glVertexAttrib1dv GLeeFuncPtr_glVertexAttrib1dv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1f +#define GLEE_H_DEFINED_glVertexAttrib1f + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1FPROC GLeeFuncPtr_glVertexAttrib1f; + #define glVertexAttrib1f GLeeFuncPtr_glVertexAttrib1f +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1fv +#define GLEE_H_DEFINED_glVertexAttrib1fv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1FVPROC GLeeFuncPtr_glVertexAttrib1fv; + #define glVertexAttrib1fv GLeeFuncPtr_glVertexAttrib1fv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1s +#define GLEE_H_DEFINED_glVertexAttrib1s + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1SPROC GLeeFuncPtr_glVertexAttrib1s; + #define glVertexAttrib1s GLeeFuncPtr_glVertexAttrib1s +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1sv +#define GLEE_H_DEFINED_glVertexAttrib1sv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1SVPROC GLeeFuncPtr_glVertexAttrib1sv; + #define glVertexAttrib1sv GLeeFuncPtr_glVertexAttrib1sv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2d +#define GLEE_H_DEFINED_glVertexAttrib2d + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2DPROC GLeeFuncPtr_glVertexAttrib2d; + #define glVertexAttrib2d GLeeFuncPtr_glVertexAttrib2d +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2dv +#define GLEE_H_DEFINED_glVertexAttrib2dv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2DVPROC GLeeFuncPtr_glVertexAttrib2dv; + #define glVertexAttrib2dv GLeeFuncPtr_glVertexAttrib2dv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2f +#define GLEE_H_DEFINED_glVertexAttrib2f + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2FPROC GLeeFuncPtr_glVertexAttrib2f; + #define glVertexAttrib2f GLeeFuncPtr_glVertexAttrib2f +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2fv +#define GLEE_H_DEFINED_glVertexAttrib2fv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2FVPROC GLeeFuncPtr_glVertexAttrib2fv; + #define glVertexAttrib2fv GLeeFuncPtr_glVertexAttrib2fv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2s +#define GLEE_H_DEFINED_glVertexAttrib2s + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2SPROC GLeeFuncPtr_glVertexAttrib2s; + #define glVertexAttrib2s GLeeFuncPtr_glVertexAttrib2s +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2sv +#define GLEE_H_DEFINED_glVertexAttrib2sv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2SVPROC GLeeFuncPtr_glVertexAttrib2sv; + #define glVertexAttrib2sv GLeeFuncPtr_glVertexAttrib2sv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3d +#define GLEE_H_DEFINED_glVertexAttrib3d + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3DPROC GLeeFuncPtr_glVertexAttrib3d; + #define glVertexAttrib3d GLeeFuncPtr_glVertexAttrib3d +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3dv +#define GLEE_H_DEFINED_glVertexAttrib3dv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3DVPROC GLeeFuncPtr_glVertexAttrib3dv; + #define glVertexAttrib3dv GLeeFuncPtr_glVertexAttrib3dv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3f +#define GLEE_H_DEFINED_glVertexAttrib3f + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3FPROC GLeeFuncPtr_glVertexAttrib3f; + #define glVertexAttrib3f GLeeFuncPtr_glVertexAttrib3f +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3fv +#define GLEE_H_DEFINED_glVertexAttrib3fv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3FVPROC GLeeFuncPtr_glVertexAttrib3fv; + #define glVertexAttrib3fv GLeeFuncPtr_glVertexAttrib3fv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3s +#define GLEE_H_DEFINED_glVertexAttrib3s + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3SPROC GLeeFuncPtr_glVertexAttrib3s; + #define glVertexAttrib3s GLeeFuncPtr_glVertexAttrib3s +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3sv +#define GLEE_H_DEFINED_glVertexAttrib3sv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3SVPROC GLeeFuncPtr_glVertexAttrib3sv; + #define glVertexAttrib3sv GLeeFuncPtr_glVertexAttrib3sv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4Nbv +#define GLEE_H_DEFINED_glVertexAttrib4Nbv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NBVPROC GLeeFuncPtr_glVertexAttrib4Nbv; + #define glVertexAttrib4Nbv GLeeFuncPtr_glVertexAttrib4Nbv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4Niv +#define GLEE_H_DEFINED_glVertexAttrib4Niv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NIVPROC GLeeFuncPtr_glVertexAttrib4Niv; + #define glVertexAttrib4Niv GLeeFuncPtr_glVertexAttrib4Niv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4Nsv +#define GLEE_H_DEFINED_glVertexAttrib4Nsv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NSVPROC GLeeFuncPtr_glVertexAttrib4Nsv; + #define glVertexAttrib4Nsv GLeeFuncPtr_glVertexAttrib4Nsv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4Nub +#define GLEE_H_DEFINED_glVertexAttrib4Nub + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUBPROC GLeeFuncPtr_glVertexAttrib4Nub; + #define glVertexAttrib4Nub GLeeFuncPtr_glVertexAttrib4Nub +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4Nubv +#define GLEE_H_DEFINED_glVertexAttrib4Nubv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUBVPROC GLeeFuncPtr_glVertexAttrib4Nubv; + #define glVertexAttrib4Nubv GLeeFuncPtr_glVertexAttrib4Nubv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4Nuiv +#define GLEE_H_DEFINED_glVertexAttrib4Nuiv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUIVPROC GLeeFuncPtr_glVertexAttrib4Nuiv; + #define glVertexAttrib4Nuiv GLeeFuncPtr_glVertexAttrib4Nuiv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4Nusv +#define GLEE_H_DEFINED_glVertexAttrib4Nusv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUSVPROC GLeeFuncPtr_glVertexAttrib4Nusv; + #define glVertexAttrib4Nusv GLeeFuncPtr_glVertexAttrib4Nusv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4bv +#define GLEE_H_DEFINED_glVertexAttrib4bv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4BVPROC GLeeFuncPtr_glVertexAttrib4bv; + #define glVertexAttrib4bv GLeeFuncPtr_glVertexAttrib4bv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4d +#define GLEE_H_DEFINED_glVertexAttrib4d + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4DPROC GLeeFuncPtr_glVertexAttrib4d; + #define glVertexAttrib4d GLeeFuncPtr_glVertexAttrib4d +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4dv +#define GLEE_H_DEFINED_glVertexAttrib4dv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4DVPROC GLeeFuncPtr_glVertexAttrib4dv; + #define glVertexAttrib4dv GLeeFuncPtr_glVertexAttrib4dv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4f +#define GLEE_H_DEFINED_glVertexAttrib4f + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4FPROC GLeeFuncPtr_glVertexAttrib4f; + #define glVertexAttrib4f GLeeFuncPtr_glVertexAttrib4f +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4fv +#define GLEE_H_DEFINED_glVertexAttrib4fv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4FVPROC GLeeFuncPtr_glVertexAttrib4fv; + #define glVertexAttrib4fv GLeeFuncPtr_glVertexAttrib4fv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4iv +#define GLEE_H_DEFINED_glVertexAttrib4iv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4IVPROC GLeeFuncPtr_glVertexAttrib4iv; + #define glVertexAttrib4iv GLeeFuncPtr_glVertexAttrib4iv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4s +#define GLEE_H_DEFINED_glVertexAttrib4s + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4SPROC GLeeFuncPtr_glVertexAttrib4s; + #define glVertexAttrib4s GLeeFuncPtr_glVertexAttrib4s +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4sv +#define GLEE_H_DEFINED_glVertexAttrib4sv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4SVPROC GLeeFuncPtr_glVertexAttrib4sv; + #define glVertexAttrib4sv GLeeFuncPtr_glVertexAttrib4sv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4ubv +#define GLEE_H_DEFINED_glVertexAttrib4ubv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4UBVPROC GLeeFuncPtr_glVertexAttrib4ubv; + #define glVertexAttrib4ubv GLeeFuncPtr_glVertexAttrib4ubv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4uiv +#define GLEE_H_DEFINED_glVertexAttrib4uiv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4UIVPROC GLeeFuncPtr_glVertexAttrib4uiv; + #define glVertexAttrib4uiv GLeeFuncPtr_glVertexAttrib4uiv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4usv +#define GLEE_H_DEFINED_glVertexAttrib4usv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4USVPROC GLeeFuncPtr_glVertexAttrib4usv; + #define glVertexAttrib4usv GLeeFuncPtr_glVertexAttrib4usv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribPointer +#define GLEE_H_DEFINED_glVertexAttribPointer + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBPOINTERPROC GLeeFuncPtr_glVertexAttribPointer; + #define glVertexAttribPointer GLeeFuncPtr_glVertexAttribPointer +#endif +#endif + +/* GL_VERSION_2_1 */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#define __GLEE_GL_VERSION_2_1 1 +/* Constants */ +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#ifndef GLEE_H_DEFINED_glUniformMatrix2x3fv +#define GLEE_H_DEFINED_glUniformMatrix2x3fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX2X3FVPROC GLeeFuncPtr_glUniformMatrix2x3fv; + #define glUniformMatrix2x3fv GLeeFuncPtr_glUniformMatrix2x3fv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix3x2fv +#define GLEE_H_DEFINED_glUniformMatrix3x2fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX3X2FVPROC GLeeFuncPtr_glUniformMatrix3x2fv; + #define glUniformMatrix3x2fv GLeeFuncPtr_glUniformMatrix3x2fv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix2x4fv +#define GLEE_H_DEFINED_glUniformMatrix2x4fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX2X4FVPROC GLeeFuncPtr_glUniformMatrix2x4fv; + #define glUniformMatrix2x4fv GLeeFuncPtr_glUniformMatrix2x4fv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix4x2fv +#define GLEE_H_DEFINED_glUniformMatrix4x2fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX4X2FVPROC GLeeFuncPtr_glUniformMatrix4x2fv; + #define glUniformMatrix4x2fv GLeeFuncPtr_glUniformMatrix4x2fv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix3x4fv +#define GLEE_H_DEFINED_glUniformMatrix3x4fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX3X4FVPROC GLeeFuncPtr_glUniformMatrix3x4fv; + #define glUniformMatrix3x4fv GLeeFuncPtr_glUniformMatrix3x4fv +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix4x3fv +#define GLEE_H_DEFINED_glUniformMatrix4x3fv + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX4X3FVPROC GLeeFuncPtr_glUniformMatrix4x3fv; + #define glUniformMatrix4x3fv GLeeFuncPtr_glUniformMatrix4x3fv +#endif +#endif + +/* GL_VERSION_3_0 */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +#define __GLEE_GL_VERSION_3_0 1 +/* Constants */ +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#ifndef GLEE_H_DEFINED_glColorMaski +#define GLEE_H_DEFINED_glColorMaski + typedef void (APIENTRYP GLEEPFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + GLEE_EXTERN GLEEPFNGLCOLORMASKIPROC GLeeFuncPtr_glColorMaski; + #define glColorMaski GLeeFuncPtr_glColorMaski +#endif +#ifndef GLEE_H_DEFINED_glGetBooleani_v +#define GLEE_H_DEFINED_glGetBooleani_v + typedef void (APIENTRYP GLEEPFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean * data); + GLEE_EXTERN GLEEPFNGLGETBOOLEANI_VPROC GLeeFuncPtr_glGetBooleani_v; + #define glGetBooleani_v GLeeFuncPtr_glGetBooleani_v +#endif +#ifndef GLEE_H_DEFINED_glGetIntegeri_v +#define GLEE_H_DEFINED_glGetIntegeri_v + typedef void (APIENTRYP GLEEPFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint * data); + GLEE_EXTERN GLEEPFNGLGETINTEGERI_VPROC GLeeFuncPtr_glGetIntegeri_v; + #define glGetIntegeri_v GLeeFuncPtr_glGetIntegeri_v +#endif +#ifndef GLEE_H_DEFINED_glEnablei +#define GLEE_H_DEFINED_glEnablei + typedef void (APIENTRYP GLEEPFNGLENABLEIPROC) (GLenum target, GLuint index); + GLEE_EXTERN GLEEPFNGLENABLEIPROC GLeeFuncPtr_glEnablei; + #define glEnablei GLeeFuncPtr_glEnablei +#endif +#ifndef GLEE_H_DEFINED_glDisablei +#define GLEE_H_DEFINED_glDisablei + typedef void (APIENTRYP GLEEPFNGLDISABLEIPROC) (GLenum target, GLuint index); + GLEE_EXTERN GLEEPFNGLDISABLEIPROC GLeeFuncPtr_glDisablei; + #define glDisablei GLeeFuncPtr_glDisablei +#endif +#ifndef GLEE_H_DEFINED_glIsEnabledi +#define GLEE_H_DEFINED_glIsEnabledi + typedef GLboolean (APIENTRYP GLEEPFNGLISENABLEDIPROC) (GLenum target, GLuint index); + GLEE_EXTERN GLEEPFNGLISENABLEDIPROC GLeeFuncPtr_glIsEnabledi; + #define glIsEnabledi GLeeFuncPtr_glIsEnabledi +#endif +#ifndef GLEE_H_DEFINED_glBeginTransformFeedback +#define GLEE_H_DEFINED_glBeginTransformFeedback + typedef void (APIENTRYP GLEEPFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); + GLEE_EXTERN GLEEPFNGLBEGINTRANSFORMFEEDBACKPROC GLeeFuncPtr_glBeginTransformFeedback; + #define glBeginTransformFeedback GLeeFuncPtr_glBeginTransformFeedback +#endif +#ifndef GLEE_H_DEFINED_glEndTransformFeedback +#define GLEE_H_DEFINED_glEndTransformFeedback + typedef void (APIENTRYP GLEEPFNGLENDTRANSFORMFEEDBACKPROC) (); + GLEE_EXTERN GLEEPFNGLENDTRANSFORMFEEDBACKPROC GLeeFuncPtr_glEndTransformFeedback; + #define glEndTransformFeedback GLeeFuncPtr_glEndTransformFeedback +#endif +#ifndef GLEE_H_DEFINED_glBindBufferRange +#define GLEE_H_DEFINED_glBindBufferRange + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + GLEE_EXTERN GLEEPFNGLBINDBUFFERRANGEPROC GLeeFuncPtr_glBindBufferRange; + #define glBindBufferRange GLeeFuncPtr_glBindBufferRange +#endif +#ifndef GLEE_H_DEFINED_glBindBufferBase +#define GLEE_H_DEFINED_glBindBufferBase + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); + GLEE_EXTERN GLEEPFNGLBINDBUFFERBASEPROC GLeeFuncPtr_glBindBufferBase; + #define glBindBufferBase GLeeFuncPtr_glBindBufferBase +#endif +#ifndef GLEE_H_DEFINED_glTransformFeedbackVaryings +#define GLEE_H_DEFINED_glTransformFeedbackVaryings + typedef void (APIENTRYP GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLint * locations, GLenum bufferMode); + GLEE_EXTERN GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC GLeeFuncPtr_glTransformFeedbackVaryings; + #define glTransformFeedbackVaryings GLeeFuncPtr_glTransformFeedbackVaryings +#endif +#ifndef GLEE_H_DEFINED_glGetTransformFeedbackVarying +#define GLEE_H_DEFINED_glGetTransformFeedbackVarying + typedef void (APIENTRYP GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLint * location); + GLEE_EXTERN GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGPROC GLeeFuncPtr_glGetTransformFeedbackVarying; + #define glGetTransformFeedbackVarying GLeeFuncPtr_glGetTransformFeedbackVarying +#endif +#ifndef GLEE_H_DEFINED_glClampColor +#define GLEE_H_DEFINED_glClampColor + typedef void (APIENTRYP GLEEPFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); + GLEE_EXTERN GLEEPFNGLCLAMPCOLORPROC GLeeFuncPtr_glClampColor; + #define glClampColor GLeeFuncPtr_glClampColor +#endif +#ifndef GLEE_H_DEFINED_glBeginConditionalRender +#define GLEE_H_DEFINED_glBeginConditionalRender + typedef void (APIENTRYP GLEEPFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); + GLEE_EXTERN GLEEPFNGLBEGINCONDITIONALRENDERPROC GLeeFuncPtr_glBeginConditionalRender; + #define glBeginConditionalRender GLeeFuncPtr_glBeginConditionalRender +#endif +#ifndef GLEE_H_DEFINED_glEndConditionalRender +#define GLEE_H_DEFINED_glEndConditionalRender + typedef void (APIENTRYP GLEEPFNGLENDCONDITIONALRENDERPROC) (); + GLEE_EXTERN GLEEPFNGLENDCONDITIONALRENDERPROC GLeeFuncPtr_glEndConditionalRender; + #define glEndConditionalRender GLeeFuncPtr_glEndConditionalRender +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI1i +#define GLEE_H_DEFINED_glVertexAttribI1i + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI1IPROC GLeeFuncPtr_glVertexAttribI1i; + #define glVertexAttribI1i GLeeFuncPtr_glVertexAttribI1i +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2i +#define GLEE_H_DEFINED_glVertexAttribI2i + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2IPROC GLeeFuncPtr_glVertexAttribI2i; + #define glVertexAttribI2i GLeeFuncPtr_glVertexAttribI2i +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3i +#define GLEE_H_DEFINED_glVertexAttribI3i + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3IPROC GLeeFuncPtr_glVertexAttribI3i; + #define glVertexAttribI3i GLeeFuncPtr_glVertexAttribI3i +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4i +#define GLEE_H_DEFINED_glVertexAttribI4i + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4IPROC GLeeFuncPtr_glVertexAttribI4i; + #define glVertexAttribI4i GLeeFuncPtr_glVertexAttribI4i +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI1ui +#define GLEE_H_DEFINED_glVertexAttribI1ui + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI1UIPROC GLeeFuncPtr_glVertexAttribI1ui; + #define glVertexAttribI1ui GLeeFuncPtr_glVertexAttribI1ui +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2ui +#define GLEE_H_DEFINED_glVertexAttribI2ui + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2UIPROC GLeeFuncPtr_glVertexAttribI2ui; + #define glVertexAttribI2ui GLeeFuncPtr_glVertexAttribI2ui +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3ui +#define GLEE_H_DEFINED_glVertexAttribI3ui + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3UIPROC GLeeFuncPtr_glVertexAttribI3ui; + #define glVertexAttribI3ui GLeeFuncPtr_glVertexAttribI3ui +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4ui +#define GLEE_H_DEFINED_glVertexAttribI4ui + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4UIPROC GLeeFuncPtr_glVertexAttribI4ui; + #define glVertexAttribI4ui GLeeFuncPtr_glVertexAttribI4ui +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI1iv +#define GLEE_H_DEFINED_glVertexAttribI1iv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI1IVPROC GLeeFuncPtr_glVertexAttribI1iv; + #define glVertexAttribI1iv GLeeFuncPtr_glVertexAttribI1iv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2iv +#define GLEE_H_DEFINED_glVertexAttribI2iv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2IVPROC GLeeFuncPtr_glVertexAttribI2iv; + #define glVertexAttribI2iv GLeeFuncPtr_glVertexAttribI2iv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3iv +#define GLEE_H_DEFINED_glVertexAttribI3iv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3IVPROC GLeeFuncPtr_glVertexAttribI3iv; + #define glVertexAttribI3iv GLeeFuncPtr_glVertexAttribI3iv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4iv +#define GLEE_H_DEFINED_glVertexAttribI4iv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4IVPROC GLeeFuncPtr_glVertexAttribI4iv; + #define glVertexAttribI4iv GLeeFuncPtr_glVertexAttribI4iv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI1uiv +#define GLEE_H_DEFINED_glVertexAttribI1uiv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI1UIVPROC GLeeFuncPtr_glVertexAttribI1uiv; + #define glVertexAttribI1uiv GLeeFuncPtr_glVertexAttribI1uiv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2uiv +#define GLEE_H_DEFINED_glVertexAttribI2uiv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2UIVPROC GLeeFuncPtr_glVertexAttribI2uiv; + #define glVertexAttribI2uiv GLeeFuncPtr_glVertexAttribI2uiv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3uiv +#define GLEE_H_DEFINED_glVertexAttribI3uiv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3UIVPROC GLeeFuncPtr_glVertexAttribI3uiv; + #define glVertexAttribI3uiv GLeeFuncPtr_glVertexAttribI3uiv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4uiv +#define GLEE_H_DEFINED_glVertexAttribI4uiv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4UIVPROC GLeeFuncPtr_glVertexAttribI4uiv; + #define glVertexAttribI4uiv GLeeFuncPtr_glVertexAttribI4uiv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4bv +#define GLEE_H_DEFINED_glVertexAttribI4bv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4BVPROC GLeeFuncPtr_glVertexAttribI4bv; + #define glVertexAttribI4bv GLeeFuncPtr_glVertexAttribI4bv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4sv +#define GLEE_H_DEFINED_glVertexAttribI4sv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4SVPROC GLeeFuncPtr_glVertexAttribI4sv; + #define glVertexAttribI4sv GLeeFuncPtr_glVertexAttribI4sv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4ubv +#define GLEE_H_DEFINED_glVertexAttribI4ubv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4UBVPROC GLeeFuncPtr_glVertexAttribI4ubv; + #define glVertexAttribI4ubv GLeeFuncPtr_glVertexAttribI4ubv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4usv +#define GLEE_H_DEFINED_glVertexAttribI4usv + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4USVPROC GLeeFuncPtr_glVertexAttribI4usv; + #define glVertexAttribI4usv GLeeFuncPtr_glVertexAttribI4usv +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribIPointer +#define GLEE_H_DEFINED_glVertexAttribIPointer + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBIPOINTERPROC GLeeFuncPtr_glVertexAttribIPointer; + #define glVertexAttribIPointer GLeeFuncPtr_glVertexAttribIPointer +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribIiv +#define GLEE_H_DEFINED_glGetVertexAttribIiv + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBIIVPROC GLeeFuncPtr_glGetVertexAttribIiv; + #define glGetVertexAttribIiv GLeeFuncPtr_glGetVertexAttribIiv +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribIuiv +#define GLEE_H_DEFINED_glGetVertexAttribIuiv + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBIUIVPROC GLeeFuncPtr_glGetVertexAttribIuiv; + #define glGetVertexAttribIuiv GLeeFuncPtr_glGetVertexAttribIuiv +#endif +#ifndef GLEE_H_DEFINED_glGetUniformuiv +#define GLEE_H_DEFINED_glGetUniformuiv + typedef void (APIENTRYP GLEEPFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETUNIFORMUIVPROC GLeeFuncPtr_glGetUniformuiv; + #define glGetUniformuiv GLeeFuncPtr_glGetUniformuiv +#endif +#ifndef GLEE_H_DEFINED_glBindFragDataLocation +#define GLEE_H_DEFINED_glBindFragDataLocation + typedef void (APIENTRYP GLEEPFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar * name); + GLEE_EXTERN GLEEPFNGLBINDFRAGDATALOCATIONPROC GLeeFuncPtr_glBindFragDataLocation; + #define glBindFragDataLocation GLeeFuncPtr_glBindFragDataLocation +#endif +#ifndef GLEE_H_DEFINED_glGetFragDataLocation +#define GLEE_H_DEFINED_glGetFragDataLocation + typedef GLint (APIENTRYP GLEEPFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETFRAGDATALOCATIONPROC GLeeFuncPtr_glGetFragDataLocation; + #define glGetFragDataLocation GLeeFuncPtr_glGetFragDataLocation +#endif +#ifndef GLEE_H_DEFINED_glUniform1ui +#define GLEE_H_DEFINED_glUniform1ui + typedef void (APIENTRYP GLEEPFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); + GLEE_EXTERN GLEEPFNGLUNIFORM1UIPROC GLeeFuncPtr_glUniform1ui; + #define glUniform1ui GLeeFuncPtr_glUniform1ui +#endif +#ifndef GLEE_H_DEFINED_glUniform2ui +#define GLEE_H_DEFINED_glUniform2ui + typedef void (APIENTRYP GLEEPFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); + GLEE_EXTERN GLEEPFNGLUNIFORM2UIPROC GLeeFuncPtr_glUniform2ui; + #define glUniform2ui GLeeFuncPtr_glUniform2ui +#endif +#ifndef GLEE_H_DEFINED_glUniform3ui +#define GLEE_H_DEFINED_glUniform3ui + typedef void (APIENTRYP GLEEPFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); + GLEE_EXTERN GLEEPFNGLUNIFORM3UIPROC GLeeFuncPtr_glUniform3ui; + #define glUniform3ui GLeeFuncPtr_glUniform3ui +#endif +#ifndef GLEE_H_DEFINED_glUniform4ui +#define GLEE_H_DEFINED_glUniform4ui + typedef void (APIENTRYP GLEEPFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + GLEE_EXTERN GLEEPFNGLUNIFORM4UIPROC GLeeFuncPtr_glUniform4ui; + #define glUniform4ui GLeeFuncPtr_glUniform4ui +#endif +#ifndef GLEE_H_DEFINED_glUniform1uiv +#define GLEE_H_DEFINED_glUniform1uiv + typedef void (APIENTRYP GLEEPFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM1UIVPROC GLeeFuncPtr_glUniform1uiv; + #define glUniform1uiv GLeeFuncPtr_glUniform1uiv +#endif +#ifndef GLEE_H_DEFINED_glUniform2uiv +#define GLEE_H_DEFINED_glUniform2uiv + typedef void (APIENTRYP GLEEPFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM2UIVPROC GLeeFuncPtr_glUniform2uiv; + #define glUniform2uiv GLeeFuncPtr_glUniform2uiv +#endif +#ifndef GLEE_H_DEFINED_glUniform3uiv +#define GLEE_H_DEFINED_glUniform3uiv + typedef void (APIENTRYP GLEEPFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM3UIVPROC GLeeFuncPtr_glUniform3uiv; + #define glUniform3uiv GLeeFuncPtr_glUniform3uiv +#endif +#ifndef GLEE_H_DEFINED_glUniform4uiv +#define GLEE_H_DEFINED_glUniform4uiv + typedef void (APIENTRYP GLEEPFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM4UIVPROC GLeeFuncPtr_glUniform4uiv; + #define glUniform4uiv GLeeFuncPtr_glUniform4uiv +#endif +#ifndef GLEE_H_DEFINED_glTexParameterIiv +#define GLEE_H_DEFINED_glTexParameterIiv + typedef void (APIENTRYP GLEEPFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLTEXPARAMETERIIVPROC GLeeFuncPtr_glTexParameterIiv; + #define glTexParameterIiv GLeeFuncPtr_glTexParameterIiv +#endif +#ifndef GLEE_H_DEFINED_glTexParameterIuiv +#define GLEE_H_DEFINED_glTexParameterIuiv + typedef void (APIENTRYP GLEEPFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint * params); + GLEE_EXTERN GLEEPFNGLTEXPARAMETERIUIVPROC GLeeFuncPtr_glTexParameterIuiv; + #define glTexParameterIuiv GLeeFuncPtr_glTexParameterIuiv +#endif +#ifndef GLEE_H_DEFINED_glGetTexParameterIiv +#define GLEE_H_DEFINED_glGetTexParameterIiv + typedef void (APIENTRYP GLEEPFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETTEXPARAMETERIIVPROC GLeeFuncPtr_glGetTexParameterIiv; + #define glGetTexParameterIiv GLeeFuncPtr_glGetTexParameterIiv +#endif +#ifndef GLEE_H_DEFINED_glGetTexParameterIuiv +#define GLEE_H_DEFINED_glGetTexParameterIuiv + typedef void (APIENTRYP GLEEPFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETTEXPARAMETERIUIVPROC GLeeFuncPtr_glGetTexParameterIuiv; + #define glGetTexParameterIuiv GLeeFuncPtr_glGetTexParameterIuiv +#endif +#ifndef GLEE_H_DEFINED_glClearBufferiv +#define GLEE_H_DEFINED_glClearBufferiv + typedef void (APIENTRYP GLEEPFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint * value); + GLEE_EXTERN GLEEPFNGLCLEARBUFFERIVPROC GLeeFuncPtr_glClearBufferiv; + #define glClearBufferiv GLeeFuncPtr_glClearBufferiv +#endif +#ifndef GLEE_H_DEFINED_glClearBufferuiv +#define GLEE_H_DEFINED_glClearBufferuiv + typedef void (APIENTRYP GLEEPFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint * value); + GLEE_EXTERN GLEEPFNGLCLEARBUFFERUIVPROC GLeeFuncPtr_glClearBufferuiv; + #define glClearBufferuiv GLeeFuncPtr_glClearBufferuiv +#endif +#ifndef GLEE_H_DEFINED_glClearBufferfv +#define GLEE_H_DEFINED_glClearBufferfv + typedef void (APIENTRYP GLEEPFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLCLEARBUFFERFVPROC GLeeFuncPtr_glClearBufferfv; + #define glClearBufferfv GLeeFuncPtr_glClearBufferfv +#endif +#ifndef GLEE_H_DEFINED_glClearBufferfi +#define GLEE_H_DEFINED_glClearBufferfi + typedef void (APIENTRYP GLEEPFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + GLEE_EXTERN GLEEPFNGLCLEARBUFFERFIPROC GLeeFuncPtr_glClearBufferfi; + #define glClearBufferfi GLeeFuncPtr_glClearBufferfi +#endif +#ifndef GLEE_H_DEFINED_glGetStringi +#define GLEE_H_DEFINED_glGetStringi + typedef const GLubyte * (APIENTRYP GLEEPFNGLGETSTRINGIPROC) (GLenum name, GLuint index); + GLEE_EXTERN GLEEPFNGLGETSTRINGIPROC GLeeFuncPtr_glGetStringi; + #define glGetStringi GLeeFuncPtr_glGetStringi +#endif +#endif + +/* GL_ARB_multitexture */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#define __GLEE_GL_ARB_multitexture 1 +/* Constants */ +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#ifndef GLEE_H_DEFINED_glActiveTextureARB +#define GLEE_H_DEFINED_glActiveTextureARB + typedef void (APIENTRYP GLEEPFNGLACTIVETEXTUREARBPROC) (GLenum texture); + GLEE_EXTERN GLEEPFNGLACTIVETEXTUREARBPROC GLeeFuncPtr_glActiveTextureARB; + #define glActiveTextureARB GLeeFuncPtr_glActiveTextureARB +#endif +#ifndef GLEE_H_DEFINED_glClientActiveTextureARB +#define GLEE_H_DEFINED_glClientActiveTextureARB + typedef void (APIENTRYP GLEEPFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); + GLEE_EXTERN GLEEPFNGLCLIENTACTIVETEXTUREARBPROC GLeeFuncPtr_glClientActiveTextureARB; + #define glClientActiveTextureARB GLeeFuncPtr_glClientActiveTextureARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1dARB +#define GLEE_H_DEFINED_glMultiTexCoord1dARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1DARBPROC GLeeFuncPtr_glMultiTexCoord1dARB; + #define glMultiTexCoord1dARB GLeeFuncPtr_glMultiTexCoord1dARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1dvARB +#define GLEE_H_DEFINED_glMultiTexCoord1dvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1DVARBPROC GLeeFuncPtr_glMultiTexCoord1dvARB; + #define glMultiTexCoord1dvARB GLeeFuncPtr_glMultiTexCoord1dvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1fARB +#define GLEE_H_DEFINED_glMultiTexCoord1fARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1FARBPROC GLeeFuncPtr_glMultiTexCoord1fARB; + #define glMultiTexCoord1fARB GLeeFuncPtr_glMultiTexCoord1fARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1fvARB +#define GLEE_H_DEFINED_glMultiTexCoord1fvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1FVARBPROC GLeeFuncPtr_glMultiTexCoord1fvARB; + #define glMultiTexCoord1fvARB GLeeFuncPtr_glMultiTexCoord1fvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1iARB +#define GLEE_H_DEFINED_glMultiTexCoord1iARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1IARBPROC GLeeFuncPtr_glMultiTexCoord1iARB; + #define glMultiTexCoord1iARB GLeeFuncPtr_glMultiTexCoord1iARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1ivARB +#define GLEE_H_DEFINED_glMultiTexCoord1ivARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1IVARBPROC GLeeFuncPtr_glMultiTexCoord1ivARB; + #define glMultiTexCoord1ivARB GLeeFuncPtr_glMultiTexCoord1ivARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1sARB +#define GLEE_H_DEFINED_glMultiTexCoord1sARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1SARBPROC GLeeFuncPtr_glMultiTexCoord1sARB; + #define glMultiTexCoord1sARB GLeeFuncPtr_glMultiTexCoord1sARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1svARB +#define GLEE_H_DEFINED_glMultiTexCoord1svARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1SVARBPROC GLeeFuncPtr_glMultiTexCoord1svARB; + #define glMultiTexCoord1svARB GLeeFuncPtr_glMultiTexCoord1svARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2dARB +#define GLEE_H_DEFINED_glMultiTexCoord2dARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2DARBPROC GLeeFuncPtr_glMultiTexCoord2dARB; + #define glMultiTexCoord2dARB GLeeFuncPtr_glMultiTexCoord2dARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2dvARB +#define GLEE_H_DEFINED_glMultiTexCoord2dvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2DVARBPROC GLeeFuncPtr_glMultiTexCoord2dvARB; + #define glMultiTexCoord2dvARB GLeeFuncPtr_glMultiTexCoord2dvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2fARB +#define GLEE_H_DEFINED_glMultiTexCoord2fARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2FARBPROC GLeeFuncPtr_glMultiTexCoord2fARB; + #define glMultiTexCoord2fARB GLeeFuncPtr_glMultiTexCoord2fARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2fvARB +#define GLEE_H_DEFINED_glMultiTexCoord2fvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2FVARBPROC GLeeFuncPtr_glMultiTexCoord2fvARB; + #define glMultiTexCoord2fvARB GLeeFuncPtr_glMultiTexCoord2fvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2iARB +#define GLEE_H_DEFINED_glMultiTexCoord2iARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2IARBPROC GLeeFuncPtr_glMultiTexCoord2iARB; + #define glMultiTexCoord2iARB GLeeFuncPtr_glMultiTexCoord2iARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2ivARB +#define GLEE_H_DEFINED_glMultiTexCoord2ivARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2IVARBPROC GLeeFuncPtr_glMultiTexCoord2ivARB; + #define glMultiTexCoord2ivARB GLeeFuncPtr_glMultiTexCoord2ivARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2sARB +#define GLEE_H_DEFINED_glMultiTexCoord2sARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2SARBPROC GLeeFuncPtr_glMultiTexCoord2sARB; + #define glMultiTexCoord2sARB GLeeFuncPtr_glMultiTexCoord2sARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2svARB +#define GLEE_H_DEFINED_glMultiTexCoord2svARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2SVARBPROC GLeeFuncPtr_glMultiTexCoord2svARB; + #define glMultiTexCoord2svARB GLeeFuncPtr_glMultiTexCoord2svARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3dARB +#define GLEE_H_DEFINED_glMultiTexCoord3dARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3DARBPROC GLeeFuncPtr_glMultiTexCoord3dARB; + #define glMultiTexCoord3dARB GLeeFuncPtr_glMultiTexCoord3dARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3dvARB +#define GLEE_H_DEFINED_glMultiTexCoord3dvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3DVARBPROC GLeeFuncPtr_glMultiTexCoord3dvARB; + #define glMultiTexCoord3dvARB GLeeFuncPtr_glMultiTexCoord3dvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3fARB +#define GLEE_H_DEFINED_glMultiTexCoord3fARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3FARBPROC GLeeFuncPtr_glMultiTexCoord3fARB; + #define glMultiTexCoord3fARB GLeeFuncPtr_glMultiTexCoord3fARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3fvARB +#define GLEE_H_DEFINED_glMultiTexCoord3fvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3FVARBPROC GLeeFuncPtr_glMultiTexCoord3fvARB; + #define glMultiTexCoord3fvARB GLeeFuncPtr_glMultiTexCoord3fvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3iARB +#define GLEE_H_DEFINED_glMultiTexCoord3iARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3IARBPROC GLeeFuncPtr_glMultiTexCoord3iARB; + #define glMultiTexCoord3iARB GLeeFuncPtr_glMultiTexCoord3iARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3ivARB +#define GLEE_H_DEFINED_glMultiTexCoord3ivARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3IVARBPROC GLeeFuncPtr_glMultiTexCoord3ivARB; + #define glMultiTexCoord3ivARB GLeeFuncPtr_glMultiTexCoord3ivARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3sARB +#define GLEE_H_DEFINED_glMultiTexCoord3sARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3SARBPROC GLeeFuncPtr_glMultiTexCoord3sARB; + #define glMultiTexCoord3sARB GLeeFuncPtr_glMultiTexCoord3sARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3svARB +#define GLEE_H_DEFINED_glMultiTexCoord3svARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3SVARBPROC GLeeFuncPtr_glMultiTexCoord3svARB; + #define glMultiTexCoord3svARB GLeeFuncPtr_glMultiTexCoord3svARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4dARB +#define GLEE_H_DEFINED_glMultiTexCoord4dARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4DARBPROC GLeeFuncPtr_glMultiTexCoord4dARB; + #define glMultiTexCoord4dARB GLeeFuncPtr_glMultiTexCoord4dARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4dvARB +#define GLEE_H_DEFINED_glMultiTexCoord4dvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4DVARBPROC GLeeFuncPtr_glMultiTexCoord4dvARB; + #define glMultiTexCoord4dvARB GLeeFuncPtr_glMultiTexCoord4dvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4fARB +#define GLEE_H_DEFINED_glMultiTexCoord4fARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4FARBPROC GLeeFuncPtr_glMultiTexCoord4fARB; + #define glMultiTexCoord4fARB GLeeFuncPtr_glMultiTexCoord4fARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4fvARB +#define GLEE_H_DEFINED_glMultiTexCoord4fvARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4FVARBPROC GLeeFuncPtr_glMultiTexCoord4fvARB; + #define glMultiTexCoord4fvARB GLeeFuncPtr_glMultiTexCoord4fvARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4iARB +#define GLEE_H_DEFINED_glMultiTexCoord4iARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4IARBPROC GLeeFuncPtr_glMultiTexCoord4iARB; + #define glMultiTexCoord4iARB GLeeFuncPtr_glMultiTexCoord4iARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4ivARB +#define GLEE_H_DEFINED_glMultiTexCoord4ivARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4IVARBPROC GLeeFuncPtr_glMultiTexCoord4ivARB; + #define glMultiTexCoord4ivARB GLeeFuncPtr_glMultiTexCoord4ivARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4sARB +#define GLEE_H_DEFINED_glMultiTexCoord4sARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4SARBPROC GLeeFuncPtr_glMultiTexCoord4sARB; + #define glMultiTexCoord4sARB GLeeFuncPtr_glMultiTexCoord4sARB +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4svARB +#define GLEE_H_DEFINED_glMultiTexCoord4svARB + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4SVARBPROC GLeeFuncPtr_glMultiTexCoord4svARB; + #define glMultiTexCoord4svARB GLeeFuncPtr_glMultiTexCoord4svARB +#endif +#endif + +/* GL_ARB_transpose_matrix */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#define __GLEE_GL_ARB_transpose_matrix 1 +/* Constants */ +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#ifndef GLEE_H_DEFINED_glLoadTransposeMatrixfARB +#define GLEE_H_DEFINED_glLoadTransposeMatrixfARB + typedef void (APIENTRYP GLEEPFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat * m); + GLEE_EXTERN GLEEPFNGLLOADTRANSPOSEMATRIXFARBPROC GLeeFuncPtr_glLoadTransposeMatrixfARB; + #define glLoadTransposeMatrixfARB GLeeFuncPtr_glLoadTransposeMatrixfARB +#endif +#ifndef GLEE_H_DEFINED_glLoadTransposeMatrixdARB +#define GLEE_H_DEFINED_glLoadTransposeMatrixdARB + typedef void (APIENTRYP GLEEPFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble * m); + GLEE_EXTERN GLEEPFNGLLOADTRANSPOSEMATRIXDARBPROC GLeeFuncPtr_glLoadTransposeMatrixdARB; + #define glLoadTransposeMatrixdARB GLeeFuncPtr_glLoadTransposeMatrixdARB +#endif +#ifndef GLEE_H_DEFINED_glMultTransposeMatrixfARB +#define GLEE_H_DEFINED_glMultTransposeMatrixfARB + typedef void (APIENTRYP GLEEPFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat * m); + GLEE_EXTERN GLEEPFNGLMULTTRANSPOSEMATRIXFARBPROC GLeeFuncPtr_glMultTransposeMatrixfARB; + #define glMultTransposeMatrixfARB GLeeFuncPtr_glMultTransposeMatrixfARB +#endif +#ifndef GLEE_H_DEFINED_glMultTransposeMatrixdARB +#define GLEE_H_DEFINED_glMultTransposeMatrixdARB + typedef void (APIENTRYP GLEEPFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble * m); + GLEE_EXTERN GLEEPFNGLMULTTRANSPOSEMATRIXDARBPROC GLeeFuncPtr_glMultTransposeMatrixdARB; + #define glMultTransposeMatrixdARB GLeeFuncPtr_glMultTransposeMatrixdARB +#endif +#endif + +/* GL_ARB_multisample */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#define __GLEE_GL_ARB_multisample 1 +/* Constants */ +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#ifndef GLEE_H_DEFINED_glSampleCoverageARB +#define GLEE_H_DEFINED_glSampleCoverageARB + typedef void (APIENTRYP GLEEPFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + GLEE_EXTERN GLEEPFNGLSAMPLECOVERAGEARBPROC GLeeFuncPtr_glSampleCoverageARB; + #define glSampleCoverageARB GLeeFuncPtr_glSampleCoverageARB +#endif +#endif + +/* GL_ARB_texture_env_add */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#define __GLEE_GL_ARB_texture_env_add 1 +/* Constants */ +#endif + +/* GL_ARB_texture_cube_map */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#define __GLEE_GL_ARB_texture_cube_map 1 +/* Constants */ +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +/* GL_ARB_texture_compression */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#define __GLEE_GL_ARB_texture_compression 1 +/* Constants */ +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#ifndef GLEE_H_DEFINED_glCompressedTexImage3DARB +#define GLEE_H_DEFINED_glCompressedTexImage3DARB + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXIMAGE3DARBPROC GLeeFuncPtr_glCompressedTexImage3DARB; + #define glCompressedTexImage3DARB GLeeFuncPtr_glCompressedTexImage3DARB +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexImage2DARB +#define GLEE_H_DEFINED_glCompressedTexImage2DARB + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC GLeeFuncPtr_glCompressedTexImage2DARB; + #define glCompressedTexImage2DARB GLeeFuncPtr_glCompressedTexImage2DARB +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexImage1DARB +#define GLEE_H_DEFINED_glCompressedTexImage1DARB + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXIMAGE1DARBPROC GLeeFuncPtr_glCompressedTexImage1DARB; + #define glCompressedTexImage1DARB GLeeFuncPtr_glCompressedTexImage1DARB +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexSubImage3DARB +#define GLEE_H_DEFINED_glCompressedTexSubImage3DARB + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC GLeeFuncPtr_glCompressedTexSubImage3DARB; + #define glCompressedTexSubImage3DARB GLeeFuncPtr_glCompressedTexSubImage3DARB +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexSubImage2DARB +#define GLEE_H_DEFINED_glCompressedTexSubImage2DARB + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC GLeeFuncPtr_glCompressedTexSubImage2DARB; + #define glCompressedTexSubImage2DARB GLeeFuncPtr_glCompressedTexSubImage2DARB +#endif +#ifndef GLEE_H_DEFINED_glCompressedTexSubImage1DARB +#define GLEE_H_DEFINED_glCompressedTexSubImage1DARB + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC GLeeFuncPtr_glCompressedTexSubImage1DARB; + #define glCompressedTexSubImage1DARB GLeeFuncPtr_glCompressedTexSubImage1DARB +#endif +#ifndef GLEE_H_DEFINED_glGetCompressedTexImageARB +#define GLEE_H_DEFINED_glGetCompressedTexImageARB + typedef void (APIENTRYP GLEEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid * img); + GLEE_EXTERN GLEEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC GLeeFuncPtr_glGetCompressedTexImageARB; + #define glGetCompressedTexImageARB GLeeFuncPtr_glGetCompressedTexImageARB +#endif +#endif + +/* GL_ARB_texture_border_clamp */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#define __GLEE_GL_ARB_texture_border_clamp 1 +/* Constants */ +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +/* GL_ARB_point_parameters */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#define __GLEE_GL_ARB_point_parameters 1 +/* Constants */ +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#ifndef GLEE_H_DEFINED_glPointParameterfARB +#define GLEE_H_DEFINED_glPointParameterfARB + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFARBPROC GLeeFuncPtr_glPointParameterfARB; + #define glPointParameterfARB GLeeFuncPtr_glPointParameterfARB +#endif +#ifndef GLEE_H_DEFINED_glPointParameterfvARB +#define GLEE_H_DEFINED_glPointParameterfvARB + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFVARBPROC GLeeFuncPtr_glPointParameterfvARB; + #define glPointParameterfvARB GLeeFuncPtr_glPointParameterfvARB +#endif +#endif + +/* GL_ARB_vertex_blend */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#define __GLEE_GL_ARB_vertex_blend 1 +/* Constants */ +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#ifndef GLEE_H_DEFINED_glWeightbvARB +#define GLEE_H_DEFINED_glWeightbvARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTBVARBPROC GLeeFuncPtr_glWeightbvARB; + #define glWeightbvARB GLeeFuncPtr_glWeightbvARB +#endif +#ifndef GLEE_H_DEFINED_glWeightsvARB +#define GLEE_H_DEFINED_glWeightsvARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTSVARBPROC) (GLint size, const GLshort * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTSVARBPROC GLeeFuncPtr_glWeightsvARB; + #define glWeightsvARB GLeeFuncPtr_glWeightsvARB +#endif +#ifndef GLEE_H_DEFINED_glWeightivARB +#define GLEE_H_DEFINED_glWeightivARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTIVARBPROC) (GLint size, const GLint * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTIVARBPROC GLeeFuncPtr_glWeightivARB; + #define glWeightivARB GLeeFuncPtr_glWeightivARB +#endif +#ifndef GLEE_H_DEFINED_glWeightfvARB +#define GLEE_H_DEFINED_glWeightfvARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTFVARBPROC GLeeFuncPtr_glWeightfvARB; + #define glWeightfvARB GLeeFuncPtr_glWeightfvARB +#endif +#ifndef GLEE_H_DEFINED_glWeightdvARB +#define GLEE_H_DEFINED_glWeightdvARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTDVARBPROC GLeeFuncPtr_glWeightdvARB; + #define glWeightdvARB GLeeFuncPtr_glWeightdvARB +#endif +#ifndef GLEE_H_DEFINED_glWeightubvARB +#define GLEE_H_DEFINED_glWeightubvARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTUBVARBPROC GLeeFuncPtr_glWeightubvARB; + #define glWeightubvARB GLeeFuncPtr_glWeightubvARB +#endif +#ifndef GLEE_H_DEFINED_glWeightusvARB +#define GLEE_H_DEFINED_glWeightusvARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTUSVARBPROC GLeeFuncPtr_glWeightusvARB; + #define glWeightusvARB GLeeFuncPtr_glWeightusvARB +#endif +#ifndef GLEE_H_DEFINED_glWeightuivARB +#define GLEE_H_DEFINED_glWeightuivARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTUIVARBPROC GLeeFuncPtr_glWeightuivARB; + #define glWeightuivARB GLeeFuncPtr_glWeightuivARB +#endif +#ifndef GLEE_H_DEFINED_glWeightPointerARB +#define GLEE_H_DEFINED_glWeightPointerARB + typedef void (APIENTRYP GLEEPFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLWEIGHTPOINTERARBPROC GLeeFuncPtr_glWeightPointerARB; + #define glWeightPointerARB GLeeFuncPtr_glWeightPointerARB +#endif +#ifndef GLEE_H_DEFINED_glVertexBlendARB +#define GLEE_H_DEFINED_glVertexBlendARB + typedef void (APIENTRYP GLEEPFNGLVERTEXBLENDARBPROC) (GLint count); + GLEE_EXTERN GLEEPFNGLVERTEXBLENDARBPROC GLeeFuncPtr_glVertexBlendARB; + #define glVertexBlendARB GLeeFuncPtr_glVertexBlendARB +#endif +#endif + +/* GL_ARB_matrix_palette */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#define __GLEE_GL_ARB_matrix_palette 1 +/* Constants */ +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#ifndef GLEE_H_DEFINED_glCurrentPaletteMatrixARB +#define GLEE_H_DEFINED_glCurrentPaletteMatrixARB + typedef void (APIENTRYP GLEEPFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); + GLEE_EXTERN GLEEPFNGLCURRENTPALETTEMATRIXARBPROC GLeeFuncPtr_glCurrentPaletteMatrixARB; + #define glCurrentPaletteMatrixARB GLeeFuncPtr_glCurrentPaletteMatrixARB +#endif +#ifndef GLEE_H_DEFINED_glMatrixIndexubvARB +#define GLEE_H_DEFINED_glMatrixIndexubvARB + typedef void (APIENTRYP GLEEPFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte * indices); + GLEE_EXTERN GLEEPFNGLMATRIXINDEXUBVARBPROC GLeeFuncPtr_glMatrixIndexubvARB; + #define glMatrixIndexubvARB GLeeFuncPtr_glMatrixIndexubvARB +#endif +#ifndef GLEE_H_DEFINED_glMatrixIndexusvARB +#define GLEE_H_DEFINED_glMatrixIndexusvARB + typedef void (APIENTRYP GLEEPFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort * indices); + GLEE_EXTERN GLEEPFNGLMATRIXINDEXUSVARBPROC GLeeFuncPtr_glMatrixIndexusvARB; + #define glMatrixIndexusvARB GLeeFuncPtr_glMatrixIndexusvARB +#endif +#ifndef GLEE_H_DEFINED_glMatrixIndexuivARB +#define GLEE_H_DEFINED_glMatrixIndexuivARB + typedef void (APIENTRYP GLEEPFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint * indices); + GLEE_EXTERN GLEEPFNGLMATRIXINDEXUIVARBPROC GLeeFuncPtr_glMatrixIndexuivARB; + #define glMatrixIndexuivARB GLeeFuncPtr_glMatrixIndexuivARB +#endif +#ifndef GLEE_H_DEFINED_glMatrixIndexPointerARB +#define GLEE_H_DEFINED_glMatrixIndexPointerARB + typedef void (APIENTRYP GLEEPFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLMATRIXINDEXPOINTERARBPROC GLeeFuncPtr_glMatrixIndexPointerARB; + #define glMatrixIndexPointerARB GLeeFuncPtr_glMatrixIndexPointerARB +#endif +#endif + +/* GL_ARB_texture_env_combine */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#define __GLEE_GL_ARB_texture_env_combine 1 +/* Constants */ +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +/* GL_ARB_texture_env_crossbar */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#define __GLEE_GL_ARB_texture_env_crossbar 1 +/* Constants */ +#endif + +/* GL_ARB_texture_env_dot3 */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#define __GLEE_GL_ARB_texture_env_dot3 1 +/* Constants */ +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +/* GL_ARB_texture_mirrored_repeat */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#define __GLEE_GL_ARB_texture_mirrored_repeat 1 +/* Constants */ +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +/* GL_ARB_depth_texture */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#define __GLEE_GL_ARB_depth_texture 1 +/* Constants */ +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +/* GL_ARB_shadow */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#define __GLEE_GL_ARB_shadow 1 +/* Constants */ +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +/* GL_ARB_shadow_ambient */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#define __GLEE_GL_ARB_shadow_ambient 1 +/* Constants */ +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +/* GL_ARB_window_pos */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +#define __GLEE_GL_ARB_window_pos 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glWindowPos2dARB +#define GLEE_H_DEFINED_glWindowPos2dARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2DARBPROC GLeeFuncPtr_glWindowPos2dARB; + #define glWindowPos2dARB GLeeFuncPtr_glWindowPos2dARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2dvARB +#define GLEE_H_DEFINED_glWindowPos2dvARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2DVARBPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2DVARBPROC GLeeFuncPtr_glWindowPos2dvARB; + #define glWindowPos2dvARB GLeeFuncPtr_glWindowPos2dvARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2fARB +#define GLEE_H_DEFINED_glWindowPos2fARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2FARBPROC GLeeFuncPtr_glWindowPos2fARB; + #define glWindowPos2fARB GLeeFuncPtr_glWindowPos2fARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2fvARB +#define GLEE_H_DEFINED_glWindowPos2fvARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2FVARBPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2FVARBPROC GLeeFuncPtr_glWindowPos2fvARB; + #define glWindowPos2fvARB GLeeFuncPtr_glWindowPos2fvARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2iARB +#define GLEE_H_DEFINED_glWindowPos2iARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2IARBPROC GLeeFuncPtr_glWindowPos2iARB; + #define glWindowPos2iARB GLeeFuncPtr_glWindowPos2iARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2ivARB +#define GLEE_H_DEFINED_glWindowPos2ivARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2IVARBPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2IVARBPROC GLeeFuncPtr_glWindowPos2ivARB; + #define glWindowPos2ivARB GLeeFuncPtr_glWindowPos2ivARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2sARB +#define GLEE_H_DEFINED_glWindowPos2sARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2SARBPROC GLeeFuncPtr_glWindowPos2sARB; + #define glWindowPos2sARB GLeeFuncPtr_glWindowPos2sARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2svARB +#define GLEE_H_DEFINED_glWindowPos2svARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2SVARBPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2SVARBPROC GLeeFuncPtr_glWindowPos2svARB; + #define glWindowPos2svARB GLeeFuncPtr_glWindowPos2svARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3dARB +#define GLEE_H_DEFINED_glWindowPos3dARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3DARBPROC GLeeFuncPtr_glWindowPos3dARB; + #define glWindowPos3dARB GLeeFuncPtr_glWindowPos3dARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3dvARB +#define GLEE_H_DEFINED_glWindowPos3dvARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3DVARBPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3DVARBPROC GLeeFuncPtr_glWindowPos3dvARB; + #define glWindowPos3dvARB GLeeFuncPtr_glWindowPos3dvARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3fARB +#define GLEE_H_DEFINED_glWindowPos3fARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3FARBPROC GLeeFuncPtr_glWindowPos3fARB; + #define glWindowPos3fARB GLeeFuncPtr_glWindowPos3fARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3fvARB +#define GLEE_H_DEFINED_glWindowPos3fvARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3FVARBPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3FVARBPROC GLeeFuncPtr_glWindowPos3fvARB; + #define glWindowPos3fvARB GLeeFuncPtr_glWindowPos3fvARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3iARB +#define GLEE_H_DEFINED_glWindowPos3iARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3IARBPROC GLeeFuncPtr_glWindowPos3iARB; + #define glWindowPos3iARB GLeeFuncPtr_glWindowPos3iARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3ivARB +#define GLEE_H_DEFINED_glWindowPos3ivARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3IVARBPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3IVARBPROC GLeeFuncPtr_glWindowPos3ivARB; + #define glWindowPos3ivARB GLeeFuncPtr_glWindowPos3ivARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3sARB +#define GLEE_H_DEFINED_glWindowPos3sARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3SARBPROC GLeeFuncPtr_glWindowPos3sARB; + #define glWindowPos3sARB GLeeFuncPtr_glWindowPos3sARB +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3svARB +#define GLEE_H_DEFINED_glWindowPos3svARB + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3SVARBPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3SVARBPROC GLeeFuncPtr_glWindowPos3svARB; + #define glWindowPos3svARB GLeeFuncPtr_glWindowPos3svARB +#endif +#endif + +/* GL_ARB_vertex_program */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#define __GLEE_GL_ARB_vertex_program 1 +/* Constants */ +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#ifndef GLEE_H_DEFINED_glVertexAttrib1dARB +#define GLEE_H_DEFINED_glVertexAttrib1dARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1DARBPROC GLeeFuncPtr_glVertexAttrib1dARB; + #define glVertexAttrib1dARB GLeeFuncPtr_glVertexAttrib1dARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1dvARB +#define GLEE_H_DEFINED_glVertexAttrib1dvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1DVARBPROC GLeeFuncPtr_glVertexAttrib1dvARB; + #define glVertexAttrib1dvARB GLeeFuncPtr_glVertexAttrib1dvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1fARB +#define GLEE_H_DEFINED_glVertexAttrib1fARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1FARBPROC GLeeFuncPtr_glVertexAttrib1fARB; + #define glVertexAttrib1fARB GLeeFuncPtr_glVertexAttrib1fARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1fvARB +#define GLEE_H_DEFINED_glVertexAttrib1fvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1FVARBPROC GLeeFuncPtr_glVertexAttrib1fvARB; + #define glVertexAttrib1fvARB GLeeFuncPtr_glVertexAttrib1fvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1sARB +#define GLEE_H_DEFINED_glVertexAttrib1sARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1SARBPROC GLeeFuncPtr_glVertexAttrib1sARB; + #define glVertexAttrib1sARB GLeeFuncPtr_glVertexAttrib1sARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1svARB +#define GLEE_H_DEFINED_glVertexAttrib1svARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1SVARBPROC GLeeFuncPtr_glVertexAttrib1svARB; + #define glVertexAttrib1svARB GLeeFuncPtr_glVertexAttrib1svARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2dARB +#define GLEE_H_DEFINED_glVertexAttrib2dARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2DARBPROC GLeeFuncPtr_glVertexAttrib2dARB; + #define glVertexAttrib2dARB GLeeFuncPtr_glVertexAttrib2dARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2dvARB +#define GLEE_H_DEFINED_glVertexAttrib2dvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2DVARBPROC GLeeFuncPtr_glVertexAttrib2dvARB; + #define glVertexAttrib2dvARB GLeeFuncPtr_glVertexAttrib2dvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2fARB +#define GLEE_H_DEFINED_glVertexAttrib2fARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2FARBPROC GLeeFuncPtr_glVertexAttrib2fARB; + #define glVertexAttrib2fARB GLeeFuncPtr_glVertexAttrib2fARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2fvARB +#define GLEE_H_DEFINED_glVertexAttrib2fvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2FVARBPROC GLeeFuncPtr_glVertexAttrib2fvARB; + #define glVertexAttrib2fvARB GLeeFuncPtr_glVertexAttrib2fvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2sARB +#define GLEE_H_DEFINED_glVertexAttrib2sARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2SARBPROC GLeeFuncPtr_glVertexAttrib2sARB; + #define glVertexAttrib2sARB GLeeFuncPtr_glVertexAttrib2sARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2svARB +#define GLEE_H_DEFINED_glVertexAttrib2svARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2SVARBPROC GLeeFuncPtr_glVertexAttrib2svARB; + #define glVertexAttrib2svARB GLeeFuncPtr_glVertexAttrib2svARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3dARB +#define GLEE_H_DEFINED_glVertexAttrib3dARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3DARBPROC GLeeFuncPtr_glVertexAttrib3dARB; + #define glVertexAttrib3dARB GLeeFuncPtr_glVertexAttrib3dARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3dvARB +#define GLEE_H_DEFINED_glVertexAttrib3dvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3DVARBPROC GLeeFuncPtr_glVertexAttrib3dvARB; + #define glVertexAttrib3dvARB GLeeFuncPtr_glVertexAttrib3dvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3fARB +#define GLEE_H_DEFINED_glVertexAttrib3fARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3FARBPROC GLeeFuncPtr_glVertexAttrib3fARB; + #define glVertexAttrib3fARB GLeeFuncPtr_glVertexAttrib3fARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3fvARB +#define GLEE_H_DEFINED_glVertexAttrib3fvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3FVARBPROC GLeeFuncPtr_glVertexAttrib3fvARB; + #define glVertexAttrib3fvARB GLeeFuncPtr_glVertexAttrib3fvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3sARB +#define GLEE_H_DEFINED_glVertexAttrib3sARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3SARBPROC GLeeFuncPtr_glVertexAttrib3sARB; + #define glVertexAttrib3sARB GLeeFuncPtr_glVertexAttrib3sARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3svARB +#define GLEE_H_DEFINED_glVertexAttrib3svARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3SVARBPROC GLeeFuncPtr_glVertexAttrib3svARB; + #define glVertexAttrib3svARB GLeeFuncPtr_glVertexAttrib3svARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4NbvARB +#define GLEE_H_DEFINED_glVertexAttrib4NbvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NBVARBPROC GLeeFuncPtr_glVertexAttrib4NbvARB; + #define glVertexAttrib4NbvARB GLeeFuncPtr_glVertexAttrib4NbvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4NivARB +#define GLEE_H_DEFINED_glVertexAttrib4NivARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NIVARBPROC GLeeFuncPtr_glVertexAttrib4NivARB; + #define glVertexAttrib4NivARB GLeeFuncPtr_glVertexAttrib4NivARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4NsvARB +#define GLEE_H_DEFINED_glVertexAttrib4NsvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NSVARBPROC GLeeFuncPtr_glVertexAttrib4NsvARB; + #define glVertexAttrib4NsvARB GLeeFuncPtr_glVertexAttrib4NsvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4NubARB +#define GLEE_H_DEFINED_glVertexAttrib4NubARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUBARBPROC GLeeFuncPtr_glVertexAttrib4NubARB; + #define glVertexAttrib4NubARB GLeeFuncPtr_glVertexAttrib4NubARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4NubvARB +#define GLEE_H_DEFINED_glVertexAttrib4NubvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUBVARBPROC GLeeFuncPtr_glVertexAttrib4NubvARB; + #define glVertexAttrib4NubvARB GLeeFuncPtr_glVertexAttrib4NubvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4NuivARB +#define GLEE_H_DEFINED_glVertexAttrib4NuivARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUIVARBPROC GLeeFuncPtr_glVertexAttrib4NuivARB; + #define glVertexAttrib4NuivARB GLeeFuncPtr_glVertexAttrib4NuivARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4NusvARB +#define GLEE_H_DEFINED_glVertexAttrib4NusvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4NUSVARBPROC GLeeFuncPtr_glVertexAttrib4NusvARB; + #define glVertexAttrib4NusvARB GLeeFuncPtr_glVertexAttrib4NusvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4bvARB +#define GLEE_H_DEFINED_glVertexAttrib4bvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4BVARBPROC GLeeFuncPtr_glVertexAttrib4bvARB; + #define glVertexAttrib4bvARB GLeeFuncPtr_glVertexAttrib4bvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4dARB +#define GLEE_H_DEFINED_glVertexAttrib4dARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4DARBPROC GLeeFuncPtr_glVertexAttrib4dARB; + #define glVertexAttrib4dARB GLeeFuncPtr_glVertexAttrib4dARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4dvARB +#define GLEE_H_DEFINED_glVertexAttrib4dvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4DVARBPROC GLeeFuncPtr_glVertexAttrib4dvARB; + #define glVertexAttrib4dvARB GLeeFuncPtr_glVertexAttrib4dvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4fARB +#define GLEE_H_DEFINED_glVertexAttrib4fARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4FARBPROC GLeeFuncPtr_glVertexAttrib4fARB; + #define glVertexAttrib4fARB GLeeFuncPtr_glVertexAttrib4fARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4fvARB +#define GLEE_H_DEFINED_glVertexAttrib4fvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4FVARBPROC GLeeFuncPtr_glVertexAttrib4fvARB; + #define glVertexAttrib4fvARB GLeeFuncPtr_glVertexAttrib4fvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4ivARB +#define GLEE_H_DEFINED_glVertexAttrib4ivARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4IVARBPROC GLeeFuncPtr_glVertexAttrib4ivARB; + #define glVertexAttrib4ivARB GLeeFuncPtr_glVertexAttrib4ivARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4sARB +#define GLEE_H_DEFINED_glVertexAttrib4sARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4SARBPROC GLeeFuncPtr_glVertexAttrib4sARB; + #define glVertexAttrib4sARB GLeeFuncPtr_glVertexAttrib4sARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4svARB +#define GLEE_H_DEFINED_glVertexAttrib4svARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4SVARBPROC GLeeFuncPtr_glVertexAttrib4svARB; + #define glVertexAttrib4svARB GLeeFuncPtr_glVertexAttrib4svARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4ubvARB +#define GLEE_H_DEFINED_glVertexAttrib4ubvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4UBVARBPROC GLeeFuncPtr_glVertexAttrib4ubvARB; + #define glVertexAttrib4ubvARB GLeeFuncPtr_glVertexAttrib4ubvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4uivARB +#define GLEE_H_DEFINED_glVertexAttrib4uivARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4UIVARBPROC GLeeFuncPtr_glVertexAttrib4uivARB; + #define glVertexAttrib4uivARB GLeeFuncPtr_glVertexAttrib4uivARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4usvARB +#define GLEE_H_DEFINED_glVertexAttrib4usvARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4USVARBPROC GLeeFuncPtr_glVertexAttrib4usvARB; + #define glVertexAttrib4usvARB GLeeFuncPtr_glVertexAttrib4usvARB +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribPointerARB +#define GLEE_H_DEFINED_glVertexAttribPointerARB + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBPOINTERARBPROC GLeeFuncPtr_glVertexAttribPointerARB; + #define glVertexAttribPointerARB GLeeFuncPtr_glVertexAttribPointerARB +#endif +#ifndef GLEE_H_DEFINED_glEnableVertexAttribArrayARB +#define GLEE_H_DEFINED_glEnableVertexAttribArrayARB + typedef void (APIENTRYP GLEEPFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); + GLEE_EXTERN GLEEPFNGLENABLEVERTEXATTRIBARRAYARBPROC GLeeFuncPtr_glEnableVertexAttribArrayARB; + #define glEnableVertexAttribArrayARB GLeeFuncPtr_glEnableVertexAttribArrayARB +#endif +#ifndef GLEE_H_DEFINED_glDisableVertexAttribArrayARB +#define GLEE_H_DEFINED_glDisableVertexAttribArrayARB + typedef void (APIENTRYP GLEEPFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); + GLEE_EXTERN GLEEPFNGLDISABLEVERTEXATTRIBARRAYARBPROC GLeeFuncPtr_glDisableVertexAttribArrayARB; + #define glDisableVertexAttribArrayARB GLeeFuncPtr_glDisableVertexAttribArrayARB +#endif +#ifndef GLEE_H_DEFINED_glProgramStringARB +#define GLEE_H_DEFINED_glProgramStringARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid * string); + GLEE_EXTERN GLEEPFNGLPROGRAMSTRINGARBPROC GLeeFuncPtr_glProgramStringARB; + #define glProgramStringARB GLeeFuncPtr_glProgramStringARB +#endif +#ifndef GLEE_H_DEFINED_glBindProgramARB +#define GLEE_H_DEFINED_glBindProgramARB + typedef void (APIENTRYP GLEEPFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); + GLEE_EXTERN GLEEPFNGLBINDPROGRAMARBPROC GLeeFuncPtr_glBindProgramARB; + #define glBindProgramARB GLeeFuncPtr_glBindProgramARB +#endif +#ifndef GLEE_H_DEFINED_glDeleteProgramsARB +#define GLEE_H_DEFINED_glDeleteProgramsARB + typedef void (APIENTRYP GLEEPFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint * programs); + GLEE_EXTERN GLEEPFNGLDELETEPROGRAMSARBPROC GLeeFuncPtr_glDeleteProgramsARB; + #define glDeleteProgramsARB GLeeFuncPtr_glDeleteProgramsARB +#endif +#ifndef GLEE_H_DEFINED_glGenProgramsARB +#define GLEE_H_DEFINED_glGenProgramsARB + typedef void (APIENTRYP GLEEPFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint * programs); + GLEE_EXTERN GLEEPFNGLGENPROGRAMSARBPROC GLeeFuncPtr_glGenProgramsARB; + #define glGenProgramsARB GLeeFuncPtr_glGenProgramsARB +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameter4dARB +#define GLEE_H_DEFINED_glProgramEnvParameter4dARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETER4DARBPROC GLeeFuncPtr_glProgramEnvParameter4dARB; + #define glProgramEnvParameter4dARB GLeeFuncPtr_glProgramEnvParameter4dARB +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameter4dvARB +#define GLEE_H_DEFINED_glProgramEnvParameter4dvARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble * params); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETER4DVARBPROC GLeeFuncPtr_glProgramEnvParameter4dvARB; + #define glProgramEnvParameter4dvARB GLeeFuncPtr_glProgramEnvParameter4dvARB +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameter4fARB +#define GLEE_H_DEFINED_glProgramEnvParameter4fARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETER4FARBPROC GLeeFuncPtr_glProgramEnvParameter4fARB; + #define glProgramEnvParameter4fARB GLeeFuncPtr_glProgramEnvParameter4fARB +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameter4fvARB +#define GLEE_H_DEFINED_glProgramEnvParameter4fvARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETER4FVARBPROC GLeeFuncPtr_glProgramEnvParameter4fvARB; + #define glProgramEnvParameter4fvARB GLeeFuncPtr_glProgramEnvParameter4fvARB +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameter4dARB +#define GLEE_H_DEFINED_glProgramLocalParameter4dARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETER4DARBPROC GLeeFuncPtr_glProgramLocalParameter4dARB; + #define glProgramLocalParameter4dARB GLeeFuncPtr_glProgramLocalParameter4dARB +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameter4dvARB +#define GLEE_H_DEFINED_glProgramLocalParameter4dvARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble * params); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETER4DVARBPROC GLeeFuncPtr_glProgramLocalParameter4dvARB; + #define glProgramLocalParameter4dvARB GLeeFuncPtr_glProgramLocalParameter4dvARB +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameter4fARB +#define GLEE_H_DEFINED_glProgramLocalParameter4fARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETER4FARBPROC GLeeFuncPtr_glProgramLocalParameter4fARB; + #define glProgramLocalParameter4fARB GLeeFuncPtr_glProgramLocalParameter4fARB +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameter4fvARB +#define GLEE_H_DEFINED_glProgramLocalParameter4fvARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETER4FVARBPROC GLeeFuncPtr_glProgramLocalParameter4fvARB; + #define glProgramLocalParameter4fvARB GLeeFuncPtr_glProgramLocalParameter4fvARB +#endif +#ifndef GLEE_H_DEFINED_glGetProgramEnvParameterdvARB +#define GLEE_H_DEFINED_glGetProgramEnvParameterdvARB + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMENVPARAMETERDVARBPROC GLeeFuncPtr_glGetProgramEnvParameterdvARB; + #define glGetProgramEnvParameterdvARB GLeeFuncPtr_glGetProgramEnvParameterdvARB +#endif +#ifndef GLEE_H_DEFINED_glGetProgramEnvParameterfvARB +#define GLEE_H_DEFINED_glGetProgramEnvParameterfvARB + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMENVPARAMETERFVARBPROC GLeeFuncPtr_glGetProgramEnvParameterfvARB; + #define glGetProgramEnvParameterfvARB GLeeFuncPtr_glGetProgramEnvParameterfvARB +#endif +#ifndef GLEE_H_DEFINED_glGetProgramLocalParameterdvARB +#define GLEE_H_DEFINED_glGetProgramLocalParameterdvARB + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMLOCALPARAMETERDVARBPROC GLeeFuncPtr_glGetProgramLocalParameterdvARB; + #define glGetProgramLocalParameterdvARB GLeeFuncPtr_glGetProgramLocalParameterdvARB +#endif +#ifndef GLEE_H_DEFINED_glGetProgramLocalParameterfvARB +#define GLEE_H_DEFINED_glGetProgramLocalParameterfvARB + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMLOCALPARAMETERFVARBPROC GLeeFuncPtr_glGetProgramLocalParameterfvARB; + #define glGetProgramLocalParameterfvARB GLeeFuncPtr_glGetProgramLocalParameterfvARB +#endif +#ifndef GLEE_H_DEFINED_glGetProgramivARB +#define GLEE_H_DEFINED_glGetProgramivARB + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMIVARBPROC GLeeFuncPtr_glGetProgramivARB; + #define glGetProgramivARB GLeeFuncPtr_glGetProgramivARB +#endif +#ifndef GLEE_H_DEFINED_glGetProgramStringARB +#define GLEE_H_DEFINED_glGetProgramStringARB + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid * string); + GLEE_EXTERN GLEEPFNGLGETPROGRAMSTRINGARBPROC GLeeFuncPtr_glGetProgramStringARB; + #define glGetProgramStringARB GLeeFuncPtr_glGetProgramStringARB +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribdvARB +#define GLEE_H_DEFINED_glGetVertexAttribdvARB + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBDVARBPROC GLeeFuncPtr_glGetVertexAttribdvARB; + #define glGetVertexAttribdvARB GLeeFuncPtr_glGetVertexAttribdvARB +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribfvARB +#define GLEE_H_DEFINED_glGetVertexAttribfvARB + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBFVARBPROC GLeeFuncPtr_glGetVertexAttribfvARB; + #define glGetVertexAttribfvARB GLeeFuncPtr_glGetVertexAttribfvARB +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribivARB +#define GLEE_H_DEFINED_glGetVertexAttribivARB + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBIVARBPROC GLeeFuncPtr_glGetVertexAttribivARB; + #define glGetVertexAttribivARB GLeeFuncPtr_glGetVertexAttribivARB +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribPointervARB +#define GLEE_H_DEFINED_glGetVertexAttribPointervARB + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBPOINTERVARBPROC GLeeFuncPtr_glGetVertexAttribPointervARB; + #define glGetVertexAttribPointervARB GLeeFuncPtr_glGetVertexAttribPointervARB +#endif +#ifndef GLEE_H_DEFINED_glIsProgramARB +#define GLEE_H_DEFINED_glIsProgramARB + typedef GLboolean (APIENTRYP GLEEPFNGLISPROGRAMARBPROC) (GLuint program); + GLEE_EXTERN GLEEPFNGLISPROGRAMARBPROC GLeeFuncPtr_glIsProgramARB; + #define glIsProgramARB GLeeFuncPtr_glIsProgramARB +#endif +#endif + +/* GL_ARB_fragment_program */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +#define __GLEE_GL_ARB_fragment_program 1 +/* Constants */ +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +/* GL_ARB_vertex_buffer_object */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +#define __GLEE_GL_ARB_vertex_buffer_object 1 +/* Constants */ +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#ifndef GLEE_H_DEFINED_glBindBufferARB +#define GLEE_H_DEFINED_glBindBufferARB + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); + GLEE_EXTERN GLEEPFNGLBINDBUFFERARBPROC GLeeFuncPtr_glBindBufferARB; + #define glBindBufferARB GLeeFuncPtr_glBindBufferARB +#endif +#ifndef GLEE_H_DEFINED_glDeleteBuffersARB +#define GLEE_H_DEFINED_glDeleteBuffersARB + typedef void (APIENTRYP GLEEPFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint * buffers); + GLEE_EXTERN GLEEPFNGLDELETEBUFFERSARBPROC GLeeFuncPtr_glDeleteBuffersARB; + #define glDeleteBuffersARB GLeeFuncPtr_glDeleteBuffersARB +#endif +#ifndef GLEE_H_DEFINED_glGenBuffersARB +#define GLEE_H_DEFINED_glGenBuffersARB + typedef void (APIENTRYP GLEEPFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint * buffers); + GLEE_EXTERN GLEEPFNGLGENBUFFERSARBPROC GLeeFuncPtr_glGenBuffersARB; + #define glGenBuffersARB GLeeFuncPtr_glGenBuffersARB +#endif +#ifndef GLEE_H_DEFINED_glIsBufferARB +#define GLEE_H_DEFINED_glIsBufferARB + typedef GLboolean (APIENTRYP GLEEPFNGLISBUFFERARBPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLISBUFFERARBPROC GLeeFuncPtr_glIsBufferARB; + #define glIsBufferARB GLeeFuncPtr_glIsBufferARB +#endif +#ifndef GLEE_H_DEFINED_glBufferDataARB +#define GLEE_H_DEFINED_glBufferDataARB + typedef void (APIENTRYP GLEEPFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage); + GLEE_EXTERN GLEEPFNGLBUFFERDATAARBPROC GLeeFuncPtr_glBufferDataARB; + #define glBufferDataARB GLeeFuncPtr_glBufferDataARB +#endif +#ifndef GLEE_H_DEFINED_glBufferSubDataARB +#define GLEE_H_DEFINED_glBufferSubDataARB + typedef void (APIENTRYP GLEEPFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLBUFFERSUBDATAARBPROC GLeeFuncPtr_glBufferSubDataARB; + #define glBufferSubDataARB GLeeFuncPtr_glBufferSubDataARB +#endif +#ifndef GLEE_H_DEFINED_glGetBufferSubDataARB +#define GLEE_H_DEFINED_glGetBufferSubDataARB + typedef void (APIENTRYP GLEEPFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data); + GLEE_EXTERN GLEEPFNGLGETBUFFERSUBDATAARBPROC GLeeFuncPtr_glGetBufferSubDataARB; + #define glGetBufferSubDataARB GLeeFuncPtr_glGetBufferSubDataARB +#endif +#ifndef GLEE_H_DEFINED_glMapBufferARB +#define GLEE_H_DEFINED_glMapBufferARB + typedef GLvoid* (APIENTRYP GLEEPFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); + GLEE_EXTERN GLEEPFNGLMAPBUFFERARBPROC GLeeFuncPtr_glMapBufferARB; + #define glMapBufferARB GLeeFuncPtr_glMapBufferARB +#endif +#ifndef GLEE_H_DEFINED_glUnmapBufferARB +#define GLEE_H_DEFINED_glUnmapBufferARB + typedef GLboolean (APIENTRYP GLEEPFNGLUNMAPBUFFERARBPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLUNMAPBUFFERARBPROC GLeeFuncPtr_glUnmapBufferARB; + #define glUnmapBufferARB GLeeFuncPtr_glUnmapBufferARB +#endif +#ifndef GLEE_H_DEFINED_glGetBufferParameterivARB +#define GLEE_H_DEFINED_glGetBufferParameterivARB + typedef void (APIENTRYP GLEEPFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETBUFFERPARAMETERIVARBPROC GLeeFuncPtr_glGetBufferParameterivARB; + #define glGetBufferParameterivARB GLeeFuncPtr_glGetBufferParameterivARB +#endif +#ifndef GLEE_H_DEFINED_glGetBufferPointervARB +#define GLEE_H_DEFINED_glGetBufferPointervARB + typedef void (APIENTRYP GLEEPFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* * params); + GLEE_EXTERN GLEEPFNGLGETBUFFERPOINTERVARBPROC GLeeFuncPtr_glGetBufferPointervARB; + #define glGetBufferPointervARB GLeeFuncPtr_glGetBufferPointervARB +#endif +#endif + +/* GL_ARB_occlusion_query */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#define __GLEE_GL_ARB_occlusion_query 1 +/* Constants */ +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +#ifndef GLEE_H_DEFINED_glGenQueriesARB +#define GLEE_H_DEFINED_glGenQueriesARB + typedef void (APIENTRYP GLEEPFNGLGENQUERIESARBPROC) (GLsizei n, GLuint * ids); + GLEE_EXTERN GLEEPFNGLGENQUERIESARBPROC GLeeFuncPtr_glGenQueriesARB; + #define glGenQueriesARB GLeeFuncPtr_glGenQueriesARB +#endif +#ifndef GLEE_H_DEFINED_glDeleteQueriesARB +#define GLEE_H_DEFINED_glDeleteQueriesARB + typedef void (APIENTRYP GLEEPFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint * ids); + GLEE_EXTERN GLEEPFNGLDELETEQUERIESARBPROC GLeeFuncPtr_glDeleteQueriesARB; + #define glDeleteQueriesARB GLeeFuncPtr_glDeleteQueriesARB +#endif +#ifndef GLEE_H_DEFINED_glIsQueryARB +#define GLEE_H_DEFINED_glIsQueryARB + typedef GLboolean (APIENTRYP GLEEPFNGLISQUERYARBPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLISQUERYARBPROC GLeeFuncPtr_glIsQueryARB; + #define glIsQueryARB GLeeFuncPtr_glIsQueryARB +#endif +#ifndef GLEE_H_DEFINED_glBeginQueryARB +#define GLEE_H_DEFINED_glBeginQueryARB + typedef void (APIENTRYP GLEEPFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); + GLEE_EXTERN GLEEPFNGLBEGINQUERYARBPROC GLeeFuncPtr_glBeginQueryARB; + #define glBeginQueryARB GLeeFuncPtr_glBeginQueryARB +#endif +#ifndef GLEE_H_DEFINED_glEndQueryARB +#define GLEE_H_DEFINED_glEndQueryARB + typedef void (APIENTRYP GLEEPFNGLENDQUERYARBPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLENDQUERYARBPROC GLeeFuncPtr_glEndQueryARB; + #define glEndQueryARB GLeeFuncPtr_glEndQueryARB +#endif +#ifndef GLEE_H_DEFINED_glGetQueryivARB +#define GLEE_H_DEFINED_glGetQueryivARB + typedef void (APIENTRYP GLEEPFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETQUERYIVARBPROC GLeeFuncPtr_glGetQueryivARB; + #define glGetQueryivARB GLeeFuncPtr_glGetQueryivARB +#endif +#ifndef GLEE_H_DEFINED_glGetQueryObjectivARB +#define GLEE_H_DEFINED_glGetQueryObjectivARB + typedef void (APIENTRYP GLEEPFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETQUERYOBJECTIVARBPROC GLeeFuncPtr_glGetQueryObjectivARB; + #define glGetQueryObjectivARB GLeeFuncPtr_glGetQueryObjectivARB +#endif +#ifndef GLEE_H_DEFINED_glGetQueryObjectuivARB +#define GLEE_H_DEFINED_glGetQueryObjectuivARB + typedef void (APIENTRYP GLEEPFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETQUERYOBJECTUIVARBPROC GLeeFuncPtr_glGetQueryObjectuivARB; + #define glGetQueryObjectuivARB GLeeFuncPtr_glGetQueryObjectuivARB +#endif +#endif + +/* GL_ARB_shader_objects */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#define __GLEE_GL_ARB_shader_objects 1 +/* Constants */ +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#ifndef GLEE_H_DEFINED_glDeleteObjectARB +#define GLEE_H_DEFINED_glDeleteObjectARB + typedef void (APIENTRYP GLEEPFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); + GLEE_EXTERN GLEEPFNGLDELETEOBJECTARBPROC GLeeFuncPtr_glDeleteObjectARB; + #define glDeleteObjectARB GLeeFuncPtr_glDeleteObjectARB +#endif +#ifndef GLEE_H_DEFINED_glGetHandleARB +#define GLEE_H_DEFINED_glGetHandleARB + typedef GLhandleARB (APIENTRYP GLEEPFNGLGETHANDLEARBPROC) (GLenum pname); + GLEE_EXTERN GLEEPFNGLGETHANDLEARBPROC GLeeFuncPtr_glGetHandleARB; + #define glGetHandleARB GLeeFuncPtr_glGetHandleARB +#endif +#ifndef GLEE_H_DEFINED_glDetachObjectARB +#define GLEE_H_DEFINED_glDetachObjectARB + typedef void (APIENTRYP GLEEPFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); + GLEE_EXTERN GLEEPFNGLDETACHOBJECTARBPROC GLeeFuncPtr_glDetachObjectARB; + #define glDetachObjectARB GLeeFuncPtr_glDetachObjectARB +#endif +#ifndef GLEE_H_DEFINED_glCreateShaderObjectARB +#define GLEE_H_DEFINED_glCreateShaderObjectARB + typedef GLhandleARB (APIENTRYP GLEEPFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); + GLEE_EXTERN GLEEPFNGLCREATESHADEROBJECTARBPROC GLeeFuncPtr_glCreateShaderObjectARB; + #define glCreateShaderObjectARB GLeeFuncPtr_glCreateShaderObjectARB +#endif +#ifndef GLEE_H_DEFINED_glShaderSourceARB +#define GLEE_H_DEFINED_glShaderSourceARB + typedef void (APIENTRYP GLEEPFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* * string, const GLint * length); + GLEE_EXTERN GLEEPFNGLSHADERSOURCEARBPROC GLeeFuncPtr_glShaderSourceARB; + #define glShaderSourceARB GLeeFuncPtr_glShaderSourceARB +#endif +#ifndef GLEE_H_DEFINED_glCompileShaderARB +#define GLEE_H_DEFINED_glCompileShaderARB + typedef void (APIENTRYP GLEEPFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); + GLEE_EXTERN GLEEPFNGLCOMPILESHADERARBPROC GLeeFuncPtr_glCompileShaderARB; + #define glCompileShaderARB GLeeFuncPtr_glCompileShaderARB +#endif +#ifndef GLEE_H_DEFINED_glCreateProgramObjectARB +#define GLEE_H_DEFINED_glCreateProgramObjectARB + typedef GLhandleARB (APIENTRYP GLEEPFNGLCREATEPROGRAMOBJECTARBPROC) (); + GLEE_EXTERN GLEEPFNGLCREATEPROGRAMOBJECTARBPROC GLeeFuncPtr_glCreateProgramObjectARB; + #define glCreateProgramObjectARB GLeeFuncPtr_glCreateProgramObjectARB +#endif +#ifndef GLEE_H_DEFINED_glAttachObjectARB +#define GLEE_H_DEFINED_glAttachObjectARB + typedef void (APIENTRYP GLEEPFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); + GLEE_EXTERN GLEEPFNGLATTACHOBJECTARBPROC GLeeFuncPtr_glAttachObjectARB; + #define glAttachObjectARB GLeeFuncPtr_glAttachObjectARB +#endif +#ifndef GLEE_H_DEFINED_glLinkProgramARB +#define GLEE_H_DEFINED_glLinkProgramARB + typedef void (APIENTRYP GLEEPFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); + GLEE_EXTERN GLEEPFNGLLINKPROGRAMARBPROC GLeeFuncPtr_glLinkProgramARB; + #define glLinkProgramARB GLeeFuncPtr_glLinkProgramARB +#endif +#ifndef GLEE_H_DEFINED_glUseProgramObjectARB +#define GLEE_H_DEFINED_glUseProgramObjectARB + typedef void (APIENTRYP GLEEPFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); + GLEE_EXTERN GLEEPFNGLUSEPROGRAMOBJECTARBPROC GLeeFuncPtr_glUseProgramObjectARB; + #define glUseProgramObjectARB GLeeFuncPtr_glUseProgramObjectARB +#endif +#ifndef GLEE_H_DEFINED_glValidateProgramARB +#define GLEE_H_DEFINED_glValidateProgramARB + typedef void (APIENTRYP GLEEPFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); + GLEE_EXTERN GLEEPFNGLVALIDATEPROGRAMARBPROC GLeeFuncPtr_glValidateProgramARB; + #define glValidateProgramARB GLeeFuncPtr_glValidateProgramARB +#endif +#ifndef GLEE_H_DEFINED_glUniform1fARB +#define GLEE_H_DEFINED_glUniform1fARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); + GLEE_EXTERN GLEEPFNGLUNIFORM1FARBPROC GLeeFuncPtr_glUniform1fARB; + #define glUniform1fARB GLeeFuncPtr_glUniform1fARB +#endif +#ifndef GLEE_H_DEFINED_glUniform2fARB +#define GLEE_H_DEFINED_glUniform2fARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); + GLEE_EXTERN GLEEPFNGLUNIFORM2FARBPROC GLeeFuncPtr_glUniform2fARB; + #define glUniform2fARB GLeeFuncPtr_glUniform2fARB +#endif +#ifndef GLEE_H_DEFINED_glUniform3fARB +#define GLEE_H_DEFINED_glUniform3fARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + GLEE_EXTERN GLEEPFNGLUNIFORM3FARBPROC GLeeFuncPtr_glUniform3fARB; + #define glUniform3fARB GLeeFuncPtr_glUniform3fARB +#endif +#ifndef GLEE_H_DEFINED_glUniform4fARB +#define GLEE_H_DEFINED_glUniform4fARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + GLEE_EXTERN GLEEPFNGLUNIFORM4FARBPROC GLeeFuncPtr_glUniform4fARB; + #define glUniform4fARB GLeeFuncPtr_glUniform4fARB +#endif +#ifndef GLEE_H_DEFINED_glUniform1iARB +#define GLEE_H_DEFINED_glUniform1iARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); + GLEE_EXTERN GLEEPFNGLUNIFORM1IARBPROC GLeeFuncPtr_glUniform1iARB; + #define glUniform1iARB GLeeFuncPtr_glUniform1iARB +#endif +#ifndef GLEE_H_DEFINED_glUniform2iARB +#define GLEE_H_DEFINED_glUniform2iARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); + GLEE_EXTERN GLEEPFNGLUNIFORM2IARBPROC GLeeFuncPtr_glUniform2iARB; + #define glUniform2iARB GLeeFuncPtr_glUniform2iARB +#endif +#ifndef GLEE_H_DEFINED_glUniform3iARB +#define GLEE_H_DEFINED_glUniform3iARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); + GLEE_EXTERN GLEEPFNGLUNIFORM3IARBPROC GLeeFuncPtr_glUniform3iARB; + #define glUniform3iARB GLeeFuncPtr_glUniform3iARB +#endif +#ifndef GLEE_H_DEFINED_glUniform4iARB +#define GLEE_H_DEFINED_glUniform4iARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + GLEE_EXTERN GLEEPFNGLUNIFORM4IARBPROC GLeeFuncPtr_glUniform4iARB; + #define glUniform4iARB GLeeFuncPtr_glUniform4iARB +#endif +#ifndef GLEE_H_DEFINED_glUniform1fvARB +#define GLEE_H_DEFINED_glUniform1fvARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM1FVARBPROC GLeeFuncPtr_glUniform1fvARB; + #define glUniform1fvARB GLeeFuncPtr_glUniform1fvARB +#endif +#ifndef GLEE_H_DEFINED_glUniform2fvARB +#define GLEE_H_DEFINED_glUniform2fvARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM2FVARBPROC GLeeFuncPtr_glUniform2fvARB; + #define glUniform2fvARB GLeeFuncPtr_glUniform2fvARB +#endif +#ifndef GLEE_H_DEFINED_glUniform3fvARB +#define GLEE_H_DEFINED_glUniform3fvARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM3FVARBPROC GLeeFuncPtr_glUniform3fvARB; + #define glUniform3fvARB GLeeFuncPtr_glUniform3fvARB +#endif +#ifndef GLEE_H_DEFINED_glUniform4fvARB +#define GLEE_H_DEFINED_glUniform4fvARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORM4FVARBPROC GLeeFuncPtr_glUniform4fvARB; + #define glUniform4fvARB GLeeFuncPtr_glUniform4fvARB +#endif +#ifndef GLEE_H_DEFINED_glUniform1ivARB +#define GLEE_H_DEFINED_glUniform1ivARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM1IVARBPROC GLeeFuncPtr_glUniform1ivARB; + #define glUniform1ivARB GLeeFuncPtr_glUniform1ivARB +#endif +#ifndef GLEE_H_DEFINED_glUniform2ivARB +#define GLEE_H_DEFINED_glUniform2ivARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM2IVARBPROC GLeeFuncPtr_glUniform2ivARB; + #define glUniform2ivARB GLeeFuncPtr_glUniform2ivARB +#endif +#ifndef GLEE_H_DEFINED_glUniform3ivARB +#define GLEE_H_DEFINED_glUniform3ivARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM3IVARBPROC GLeeFuncPtr_glUniform3ivARB; + #define glUniform3ivARB GLeeFuncPtr_glUniform3ivARB +#endif +#ifndef GLEE_H_DEFINED_glUniform4ivARB +#define GLEE_H_DEFINED_glUniform4ivARB + typedef void (APIENTRYP GLEEPFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM4IVARBPROC GLeeFuncPtr_glUniform4ivARB; + #define glUniform4ivARB GLeeFuncPtr_glUniform4ivARB +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix2fvARB +#define GLEE_H_DEFINED_glUniformMatrix2fvARB + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX2FVARBPROC GLeeFuncPtr_glUniformMatrix2fvARB; + #define glUniformMatrix2fvARB GLeeFuncPtr_glUniformMatrix2fvARB +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix3fvARB +#define GLEE_H_DEFINED_glUniformMatrix3fvARB + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX3FVARBPROC GLeeFuncPtr_glUniformMatrix3fvARB; + #define glUniformMatrix3fvARB GLeeFuncPtr_glUniformMatrix3fvARB +#endif +#ifndef GLEE_H_DEFINED_glUniformMatrix4fvARB +#define GLEE_H_DEFINED_glUniformMatrix4fvARB + typedef void (APIENTRYP GLEEPFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLUNIFORMMATRIX4FVARBPROC GLeeFuncPtr_glUniformMatrix4fvARB; + #define glUniformMatrix4fvARB GLeeFuncPtr_glUniformMatrix4fvARB +#endif +#ifndef GLEE_H_DEFINED_glGetObjectParameterfvARB +#define GLEE_H_DEFINED_glGetObjectParameterfvARB + typedef void (APIENTRYP GLEEPFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETOBJECTPARAMETERFVARBPROC GLeeFuncPtr_glGetObjectParameterfvARB; + #define glGetObjectParameterfvARB GLeeFuncPtr_glGetObjectParameterfvARB +#endif +#ifndef GLEE_H_DEFINED_glGetObjectParameterivARB +#define GLEE_H_DEFINED_glGetObjectParameterivARB + typedef void (APIENTRYP GLEEPFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETOBJECTPARAMETERIVARBPROC GLeeFuncPtr_glGetObjectParameterivARB; + #define glGetObjectParameterivARB GLeeFuncPtr_glGetObjectParameterivARB +#endif +#ifndef GLEE_H_DEFINED_glGetInfoLogARB +#define GLEE_H_DEFINED_glGetInfoLogARB + typedef void (APIENTRYP GLEEPFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog); + GLEE_EXTERN GLEEPFNGLGETINFOLOGARBPROC GLeeFuncPtr_glGetInfoLogARB; + #define glGetInfoLogARB GLeeFuncPtr_glGetInfoLogARB +#endif +#ifndef GLEE_H_DEFINED_glGetAttachedObjectsARB +#define GLEE_H_DEFINED_glGetAttachedObjectsARB + typedef void (APIENTRYP GLEEPFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count, GLhandleARB * obj); + GLEE_EXTERN GLEEPFNGLGETATTACHEDOBJECTSARBPROC GLeeFuncPtr_glGetAttachedObjectsARB; + #define glGetAttachedObjectsARB GLeeFuncPtr_glGetAttachedObjectsARB +#endif +#ifndef GLEE_H_DEFINED_glGetUniformLocationARB +#define GLEE_H_DEFINED_glGetUniformLocationARB + typedef GLint (APIENTRYP GLEEPFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB * name); + GLEE_EXTERN GLEEPFNGLGETUNIFORMLOCATIONARBPROC GLeeFuncPtr_glGetUniformLocationARB; + #define glGetUniformLocationARB GLeeFuncPtr_glGetUniformLocationARB +#endif +#ifndef GLEE_H_DEFINED_glGetActiveUniformARB +#define GLEE_H_DEFINED_glGetActiveUniformARB + typedef void (APIENTRYP GLEEPFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name); + GLEE_EXTERN GLEEPFNGLGETACTIVEUNIFORMARBPROC GLeeFuncPtr_glGetActiveUniformARB; + #define glGetActiveUniformARB GLeeFuncPtr_glGetActiveUniformARB +#endif +#ifndef GLEE_H_DEFINED_glGetUniformfvARB +#define GLEE_H_DEFINED_glGetUniformfvARB + typedef void (APIENTRYP GLEEPFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETUNIFORMFVARBPROC GLeeFuncPtr_glGetUniformfvARB; + #define glGetUniformfvARB GLeeFuncPtr_glGetUniformfvARB +#endif +#ifndef GLEE_H_DEFINED_glGetUniformivARB +#define GLEE_H_DEFINED_glGetUniformivARB + typedef void (APIENTRYP GLEEPFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint * params); + GLEE_EXTERN GLEEPFNGLGETUNIFORMIVARBPROC GLeeFuncPtr_glGetUniformivARB; + #define glGetUniformivARB GLeeFuncPtr_glGetUniformivARB +#endif +#ifndef GLEE_H_DEFINED_glGetShaderSourceARB +#define GLEE_H_DEFINED_glGetShaderSourceARB + typedef void (APIENTRYP GLEEPFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source); + GLEE_EXTERN GLEEPFNGLGETSHADERSOURCEARBPROC GLeeFuncPtr_glGetShaderSourceARB; + #define glGetShaderSourceARB GLeeFuncPtr_glGetShaderSourceARB +#endif +#endif + +/* GL_ARB_vertex_shader */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#define __GLEE_GL_ARB_vertex_shader 1 +/* Constants */ +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#ifndef GLEE_H_DEFINED_glBindAttribLocationARB +#define GLEE_H_DEFINED_glBindAttribLocationARB + typedef void (APIENTRYP GLEEPFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB * name); + GLEE_EXTERN GLEEPFNGLBINDATTRIBLOCATIONARBPROC GLeeFuncPtr_glBindAttribLocationARB; + #define glBindAttribLocationARB GLeeFuncPtr_glBindAttribLocationARB +#endif +#ifndef GLEE_H_DEFINED_glGetActiveAttribARB +#define GLEE_H_DEFINED_glGetActiveAttribARB + typedef void (APIENTRYP GLEEPFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name); + GLEE_EXTERN GLEEPFNGLGETACTIVEATTRIBARBPROC GLeeFuncPtr_glGetActiveAttribARB; + #define glGetActiveAttribARB GLeeFuncPtr_glGetActiveAttribARB +#endif +#ifndef GLEE_H_DEFINED_glGetAttribLocationARB +#define GLEE_H_DEFINED_glGetAttribLocationARB + typedef GLint (APIENTRYP GLEEPFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB * name); + GLEE_EXTERN GLEEPFNGLGETATTRIBLOCATIONARBPROC GLeeFuncPtr_glGetAttribLocationARB; + #define glGetAttribLocationARB GLeeFuncPtr_glGetAttribLocationARB +#endif +#endif + +/* GL_ARB_fragment_shader */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#define __GLEE_GL_ARB_fragment_shader 1 +/* Constants */ +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif + +/* GL_ARB_shading_language_100 */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#define __GLEE_GL_ARB_shading_language_100 1 +/* Constants */ +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif + +/* GL_ARB_texture_non_power_of_two */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#define __GLEE_GL_ARB_texture_non_power_of_two 1 +/* Constants */ +#endif + +/* GL_ARB_point_sprite */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#define __GLEE_GL_ARB_point_sprite 1 +/* Constants */ +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif + +/* GL_ARB_fragment_program_shadow */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#define __GLEE_GL_ARB_fragment_program_shadow 1 +/* Constants */ +#endif + +/* GL_ARB_draw_buffers */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#define __GLEE_GL_ARB_draw_buffers 1 +/* Constants */ +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#ifndef GLEE_H_DEFINED_glDrawBuffersARB +#define GLEE_H_DEFINED_glDrawBuffersARB + typedef void (APIENTRYP GLEEPFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum * bufs); + GLEE_EXTERN GLEEPFNGLDRAWBUFFERSARBPROC GLeeFuncPtr_glDrawBuffersARB; + #define glDrawBuffersARB GLeeFuncPtr_glDrawBuffersARB +#endif +#endif + +/* GL_ARB_texture_rectangle */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#define __GLEE_GL_ARB_texture_rectangle 1 +/* Constants */ +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif + +/* GL_ARB_color_buffer_float */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#define __GLEE_GL_ARB_color_buffer_float 1 +/* Constants */ +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +#ifndef GLEE_H_DEFINED_glClampColorARB +#define GLEE_H_DEFINED_glClampColorARB + typedef void (APIENTRYP GLEEPFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); + GLEE_EXTERN GLEEPFNGLCLAMPCOLORARBPROC GLeeFuncPtr_glClampColorARB; + #define glClampColorARB GLeeFuncPtr_glClampColorARB +#endif +#endif + +/* GL_ARB_half_float_pixel */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +#define __GLEE_GL_ARB_half_float_pixel 1 +/* Constants */ +#define GL_HALF_FLOAT_ARB 0x140B +#endif + +/* GL_ARB_texture_float */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#define __GLEE_GL_ARB_texture_float 1 +/* Constants */ +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif + +/* GL_ARB_pixel_buffer_object */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#define __GLEE_GL_ARB_pixel_buffer_object 1 +/* Constants */ +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif + +/* GL_ARB_depth_buffer_float */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 +#define __GLEE_GL_ARB_depth_buffer_float 1 +/* Constants */ +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#endif + +/* GL_ARB_draw_instanced */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 +#define __GLEE_GL_ARB_draw_instanced 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glDrawArraysInstancedARB +#define GLEE_H_DEFINED_glDrawArraysInstancedARB + typedef void (APIENTRYP GLEEPFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLDRAWARRAYSINSTANCEDARBPROC GLeeFuncPtr_glDrawArraysInstancedARB; + #define glDrawArraysInstancedARB GLeeFuncPtr_glDrawArraysInstancedARB +#endif +#ifndef GLEE_H_DEFINED_glDrawElementsInstancedARB +#define GLEE_H_DEFINED_glDrawElementsInstancedARB + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLDRAWELEMENTSINSTANCEDARBPROC GLeeFuncPtr_glDrawElementsInstancedARB; + #define glDrawElementsInstancedARB GLeeFuncPtr_glDrawElementsInstancedARB +#endif +#endif + +/* GL_ARB_framebuffer_object */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 +#define __GLEE_GL_ARB_framebuffer_object 1 +/* Constants */ +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#ifndef GLEE_H_DEFINED_glIsRenderbuffer +#define GLEE_H_DEFINED_glIsRenderbuffer + typedef GLboolean (APIENTRYP GLEEPFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLISRENDERBUFFERPROC GLeeFuncPtr_glIsRenderbuffer; + #define glIsRenderbuffer GLeeFuncPtr_glIsRenderbuffer +#endif +#ifndef GLEE_H_DEFINED_glBindRenderbuffer +#define GLEE_H_DEFINED_glBindRenderbuffer + typedef void (APIENTRYP GLEEPFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLBINDRENDERBUFFERPROC GLeeFuncPtr_glBindRenderbuffer; + #define glBindRenderbuffer GLeeFuncPtr_glBindRenderbuffer +#endif +#ifndef GLEE_H_DEFINED_glDeleteRenderbuffers +#define GLEE_H_DEFINED_glDeleteRenderbuffers + typedef void (APIENTRYP GLEEPFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint * renderbuffers); + GLEE_EXTERN GLEEPFNGLDELETERENDERBUFFERSPROC GLeeFuncPtr_glDeleteRenderbuffers; + #define glDeleteRenderbuffers GLeeFuncPtr_glDeleteRenderbuffers +#endif +#ifndef GLEE_H_DEFINED_glGenRenderbuffers +#define GLEE_H_DEFINED_glGenRenderbuffers + typedef void (APIENTRYP GLEEPFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint * renderbuffers); + GLEE_EXTERN GLEEPFNGLGENRENDERBUFFERSPROC GLeeFuncPtr_glGenRenderbuffers; + #define glGenRenderbuffers GLeeFuncPtr_glGenRenderbuffers +#endif +#ifndef GLEE_H_DEFINED_glRenderbufferStorage +#define GLEE_H_DEFINED_glRenderbufferStorage + typedef void (APIENTRYP GLEEPFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLRENDERBUFFERSTORAGEPROC GLeeFuncPtr_glRenderbufferStorage; + #define glRenderbufferStorage GLeeFuncPtr_glRenderbufferStorage +#endif +#ifndef GLEE_H_DEFINED_glGetRenderbufferParameteriv +#define GLEE_H_DEFINED_glGetRenderbufferParameteriv + typedef void (APIENTRYP GLEEPFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETRENDERBUFFERPARAMETERIVPROC GLeeFuncPtr_glGetRenderbufferParameteriv; + #define glGetRenderbufferParameteriv GLeeFuncPtr_glGetRenderbufferParameteriv +#endif +#ifndef GLEE_H_DEFINED_glIsFramebuffer +#define GLEE_H_DEFINED_glIsFramebuffer + typedef GLboolean (APIENTRYP GLEEPFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); + GLEE_EXTERN GLEEPFNGLISFRAMEBUFFERPROC GLeeFuncPtr_glIsFramebuffer; + #define glIsFramebuffer GLeeFuncPtr_glIsFramebuffer +#endif +#ifndef GLEE_H_DEFINED_glBindFramebuffer +#define GLEE_H_DEFINED_glBindFramebuffer + typedef void (APIENTRYP GLEEPFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); + GLEE_EXTERN GLEEPFNGLBINDFRAMEBUFFERPROC GLeeFuncPtr_glBindFramebuffer; + #define glBindFramebuffer GLeeFuncPtr_glBindFramebuffer +#endif +#ifndef GLEE_H_DEFINED_glDeleteFramebuffers +#define GLEE_H_DEFINED_glDeleteFramebuffers + typedef void (APIENTRYP GLEEPFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint * framebuffers); + GLEE_EXTERN GLEEPFNGLDELETEFRAMEBUFFERSPROC GLeeFuncPtr_glDeleteFramebuffers; + #define glDeleteFramebuffers GLeeFuncPtr_glDeleteFramebuffers +#endif +#ifndef GLEE_H_DEFINED_glGenFramebuffers +#define GLEE_H_DEFINED_glGenFramebuffers + typedef void (APIENTRYP GLEEPFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint * framebuffers); + GLEE_EXTERN GLEEPFNGLGENFRAMEBUFFERSPROC GLeeFuncPtr_glGenFramebuffers; + #define glGenFramebuffers GLeeFuncPtr_glGenFramebuffers +#endif +#ifndef GLEE_H_DEFINED_glCheckFramebufferStatus +#define GLEE_H_DEFINED_glCheckFramebufferStatus + typedef GLenum (APIENTRYP GLEEPFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLCHECKFRAMEBUFFERSTATUSPROC GLeeFuncPtr_glCheckFramebufferStatus; + #define glCheckFramebufferStatus GLeeFuncPtr_glCheckFramebufferStatus +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTexture1D +#define GLEE_H_DEFINED_glFramebufferTexture1D + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURE1DPROC GLeeFuncPtr_glFramebufferTexture1D; + #define glFramebufferTexture1D GLeeFuncPtr_glFramebufferTexture1D +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTexture2D +#define GLEE_H_DEFINED_glFramebufferTexture2D + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURE2DPROC GLeeFuncPtr_glFramebufferTexture2D; + #define glFramebufferTexture2D GLeeFuncPtr_glFramebufferTexture2D +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTexture3D +#define GLEE_H_DEFINED_glFramebufferTexture3D + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURE3DPROC GLeeFuncPtr_glFramebufferTexture3D; + #define glFramebufferTexture3D GLeeFuncPtr_glFramebufferTexture3D +#endif +#ifndef GLEE_H_DEFINED_glFramebufferRenderbuffer +#define GLEE_H_DEFINED_glFramebufferRenderbuffer + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERRENDERBUFFERPROC GLeeFuncPtr_glFramebufferRenderbuffer; + #define glFramebufferRenderbuffer GLeeFuncPtr_glFramebufferRenderbuffer +#endif +#ifndef GLEE_H_DEFINED_glGetFramebufferAttachmentParameteriv +#define GLEE_H_DEFINED_glGetFramebufferAttachmentParameteriv + typedef void (APIENTRYP GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GLeeFuncPtr_glGetFramebufferAttachmentParameteriv; + #define glGetFramebufferAttachmentParameteriv GLeeFuncPtr_glGetFramebufferAttachmentParameteriv +#endif +#ifndef GLEE_H_DEFINED_glGenerateMipmap +#define GLEE_H_DEFINED_glGenerateMipmap + typedef void (APIENTRYP GLEEPFNGLGENERATEMIPMAPPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLGENERATEMIPMAPPROC GLeeFuncPtr_glGenerateMipmap; + #define glGenerateMipmap GLeeFuncPtr_glGenerateMipmap +#endif +#ifndef GLEE_H_DEFINED_glBlitFramebuffer +#define GLEE_H_DEFINED_glBlitFramebuffer + typedef void (APIENTRYP GLEEPFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + GLEE_EXTERN GLEEPFNGLBLITFRAMEBUFFERPROC GLeeFuncPtr_glBlitFramebuffer; + #define glBlitFramebuffer GLeeFuncPtr_glBlitFramebuffer +#endif +#ifndef GLEE_H_DEFINED_glRenderbufferStorageMultisample +#define GLEE_H_DEFINED_glRenderbufferStorageMultisample + typedef void (APIENTRYP GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC GLeeFuncPtr_glRenderbufferStorageMultisample; + #define glRenderbufferStorageMultisample GLeeFuncPtr_glRenderbufferStorageMultisample +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureLayer +#define GLEE_H_DEFINED_glFramebufferTextureLayer + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURELAYERPROC GLeeFuncPtr_glFramebufferTextureLayer; + #define glFramebufferTextureLayer GLeeFuncPtr_glFramebufferTextureLayer +#endif +#endif + +/* GL_ARB_framebuffer_sRGB */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 +#define __GLEE_GL_ARB_framebuffer_sRGB 1 +/* Constants */ +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#endif + +/* GL_ARB_geometry_shader4 */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 +#define __GLEE_GL_ARB_geometry_shader4 1 +/* Constants */ +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +#ifndef GLEE_H_DEFINED_glProgramParameteriARB +#define GLEE_H_DEFINED_glProgramParameteriARB + typedef void (APIENTRYP GLEEPFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETERIARBPROC GLeeFuncPtr_glProgramParameteriARB; + #define glProgramParameteriARB GLeeFuncPtr_glProgramParameteriARB +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureARB +#define GLEE_H_DEFINED_glFramebufferTextureARB + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTUREARBPROC GLeeFuncPtr_glFramebufferTextureARB; + #define glFramebufferTextureARB GLeeFuncPtr_glFramebufferTextureARB +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureLayerARB +#define GLEE_H_DEFINED_glFramebufferTextureLayerARB + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURELAYERARBPROC GLeeFuncPtr_glFramebufferTextureLayerARB; + #define glFramebufferTextureLayerARB GLeeFuncPtr_glFramebufferTextureLayerARB +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureFaceARB +#define GLEE_H_DEFINED_glFramebufferTextureFaceARB + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTUREFACEARBPROC GLeeFuncPtr_glFramebufferTextureFaceARB; + #define glFramebufferTextureFaceARB GLeeFuncPtr_glFramebufferTextureFaceARB +#endif +#endif + +/* GL_ARB_half_float_vertex */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 +#define __GLEE_GL_ARB_half_float_vertex 1 +/* Constants */ +#define GL_HALF_FLOAT 0x140B +#endif + +/* GL_ARB_instanced_arrays */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 +#define __GLEE_GL_ARB_instanced_arrays 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glVertexAttribDivisor +#define GLEE_H_DEFINED_glVertexAttribDivisor + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBDIVISORPROC GLeeFuncPtr_glVertexAttribDivisor; + #define glVertexAttribDivisor GLeeFuncPtr_glVertexAttribDivisor +#endif +#endif + +/* GL_ARB_map_buffer_range */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 +#define __GLEE_GL_ARB_map_buffer_range 1 +/* Constants */ +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#ifndef GLEE_H_DEFINED_glMapBufferRange +#define GLEE_H_DEFINED_glMapBufferRange + typedef void (APIENTRYP GLEEPFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + GLEE_EXTERN GLEEPFNGLMAPBUFFERRANGEPROC GLeeFuncPtr_glMapBufferRange; + #define glMapBufferRange GLeeFuncPtr_glMapBufferRange +#endif +#ifndef GLEE_H_DEFINED_glFlushMappedBufferRange +#define GLEE_H_DEFINED_glFlushMappedBufferRange + typedef void (APIENTRYP GLEEPFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); + GLEE_EXTERN GLEEPFNGLFLUSHMAPPEDBUFFERRANGEPROC GLeeFuncPtr_glFlushMappedBufferRange; + #define glFlushMappedBufferRange GLeeFuncPtr_glFlushMappedBufferRange +#endif +#endif + +/* GL_ARB_texture_buffer_object */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 +#define __GLEE_GL_ARB_texture_buffer_object 1 +/* Constants */ +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +#ifndef GLEE_H_DEFINED_glTexBufferARB +#define GLEE_H_DEFINED_glTexBufferARB + typedef void (APIENTRYP GLEEPFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); + GLEE_EXTERN GLEEPFNGLTEXBUFFERARBPROC GLeeFuncPtr_glTexBufferARB; + #define glTexBufferARB GLeeFuncPtr_glTexBufferARB +#endif +#endif + +/* GL_ARB_texture_compression_rgtc */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 +#define __GLEE_GL_ARB_texture_compression_rgtc 1 +/* Constants */ +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +/* GL_ARB_texture_rg */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 +#define __GLEE_GL_ARB_texture_rg 1 +/* Constants */ +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#endif + +/* GL_ARB_vertex_array_object */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 +#define __GLEE_GL_ARB_vertex_array_object 1 +/* Constants */ +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#ifndef GLEE_H_DEFINED_glBindVertexArray +#define GLEE_H_DEFINED_glBindVertexArray + typedef void (APIENTRYP GLEEPFNGLBINDVERTEXARRAYPROC) (GLuint array); + GLEE_EXTERN GLEEPFNGLBINDVERTEXARRAYPROC GLeeFuncPtr_glBindVertexArray; + #define glBindVertexArray GLeeFuncPtr_glBindVertexArray +#endif +#ifndef GLEE_H_DEFINED_glDeleteVertexArrays +#define GLEE_H_DEFINED_glDeleteVertexArrays + typedef void (APIENTRYP GLEEPFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint * arrays); + GLEE_EXTERN GLEEPFNGLDELETEVERTEXARRAYSPROC GLeeFuncPtr_glDeleteVertexArrays; + #define glDeleteVertexArrays GLeeFuncPtr_glDeleteVertexArrays +#endif +#ifndef GLEE_H_DEFINED_glGenVertexArrays +#define GLEE_H_DEFINED_glGenVertexArrays + typedef void (APIENTRYP GLEEPFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint * arrays); + GLEE_EXTERN GLEEPFNGLGENVERTEXARRAYSPROC GLeeFuncPtr_glGenVertexArrays; + #define glGenVertexArrays GLeeFuncPtr_glGenVertexArrays +#endif +#ifndef GLEE_H_DEFINED_glIsVertexArray +#define GLEE_H_DEFINED_glIsVertexArray + typedef GLboolean (APIENTRYP GLEEPFNGLISVERTEXARRAYPROC) (GLuint array); + GLEE_EXTERN GLEEPFNGLISVERTEXARRAYPROC GLeeFuncPtr_glIsVertexArray; + #define glIsVertexArray GLeeFuncPtr_glIsVertexArray +#endif +#endif + +/* GL_EXT_abgr */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#define __GLEE_GL_EXT_abgr 1 +/* Constants */ +#define GL_ABGR_EXT 0x8000 +#endif + +/* GL_EXT_blend_color */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#define __GLEE_GL_EXT_blend_color 1 +/* Constants */ +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#ifndef GLEE_H_DEFINED_glBlendColorEXT +#define GLEE_H_DEFINED_glBlendColorEXT + typedef void (APIENTRYP GLEEPFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + GLEE_EXTERN GLEEPFNGLBLENDCOLOREXTPROC GLeeFuncPtr_glBlendColorEXT; + #define glBlendColorEXT GLeeFuncPtr_glBlendColorEXT +#endif +#endif + +/* GL_EXT_polygon_offset */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#define __GLEE_GL_EXT_polygon_offset 1 +/* Constants */ +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#ifndef GLEE_H_DEFINED_glPolygonOffsetEXT +#define GLEE_H_DEFINED_glPolygonOffsetEXT + typedef void (APIENTRYP GLEEPFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); + GLEE_EXTERN GLEEPFNGLPOLYGONOFFSETEXTPROC GLeeFuncPtr_glPolygonOffsetEXT; + #define glPolygonOffsetEXT GLeeFuncPtr_glPolygonOffsetEXT +#endif +#endif + +/* GL_EXT_texture */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#define __GLEE_GL_EXT_texture 1 +/* Constants */ +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +/* GL_EXT_texture3D */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#define __GLEE_GL_EXT_texture3D 1 +/* Constants */ +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#ifndef GLEE_H_DEFINED_glTexImage3DEXT +#define GLEE_H_DEFINED_glTexImage3DEXT + typedef void (APIENTRYP GLEEPFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXIMAGE3DEXTPROC GLeeFuncPtr_glTexImage3DEXT; + #define glTexImage3DEXT GLeeFuncPtr_glTexImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glTexSubImage3DEXT +#define GLEE_H_DEFINED_glTexSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glTexSubImage3DEXT; + #define glTexSubImage3DEXT GLeeFuncPtr_glTexSubImage3DEXT +#endif +#endif + +/* GL_SGIS_texture_filter4 */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#define __GLEE_GL_SGIS_texture_filter4 1 +/* Constants */ +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#ifndef GLEE_H_DEFINED_glGetTexFilterFuncSGIS +#define GLEE_H_DEFINED_glGetTexFilterFuncSGIS + typedef void (APIENTRYP GLEEPFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat * weights); + GLEE_EXTERN GLEEPFNGLGETTEXFILTERFUNCSGISPROC GLeeFuncPtr_glGetTexFilterFuncSGIS; + #define glGetTexFilterFuncSGIS GLeeFuncPtr_glGetTexFilterFuncSGIS +#endif +#ifndef GLEE_H_DEFINED_glTexFilterFuncSGIS +#define GLEE_H_DEFINED_glTexFilterFuncSGIS + typedef void (APIENTRYP GLEEPFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat * weights); + GLEE_EXTERN GLEEPFNGLTEXFILTERFUNCSGISPROC GLeeFuncPtr_glTexFilterFuncSGIS; + #define glTexFilterFuncSGIS GLeeFuncPtr_glTexFilterFuncSGIS +#endif +#endif + +/* GL_EXT_subtexture */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#define __GLEE_GL_EXT_subtexture 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glTexSubImage1DEXT +#define GLEE_H_DEFINED_glTexSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glTexSubImage1DEXT; + #define glTexSubImage1DEXT GLeeFuncPtr_glTexSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glTexSubImage2DEXT +#define GLEE_H_DEFINED_glTexSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glTexSubImage2DEXT; + #define glTexSubImage2DEXT GLeeFuncPtr_glTexSubImage2DEXT +#endif +#endif + +/* GL_EXT_copy_texture */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#define __GLEE_GL_EXT_copy_texture 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glCopyTexImage1DEXT +#define GLEE_H_DEFINED_glCopyTexImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); + GLEE_EXTERN GLEEPFNGLCOPYTEXIMAGE1DEXTPROC GLeeFuncPtr_glCopyTexImage1DEXT; + #define glCopyTexImage1DEXT GLeeFuncPtr_glCopyTexImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTexImage2DEXT +#define GLEE_H_DEFINED_glCopyTexImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + GLEE_EXTERN GLEEPFNGLCOPYTEXIMAGE2DEXTPROC GLeeFuncPtr_glCopyTexImage2DEXT; + #define glCopyTexImage2DEXT GLeeFuncPtr_glCopyTexImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTexSubImage1DEXT +#define GLEE_H_DEFINED_glCopyTexSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYTEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glCopyTexSubImage1DEXT; + #define glCopyTexSubImage1DEXT GLeeFuncPtr_glCopyTexSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTexSubImage2DEXT +#define GLEE_H_DEFINED_glCopyTexSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYTEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glCopyTexSubImage2DEXT; + #define glCopyTexSubImage2DEXT GLeeFuncPtr_glCopyTexSubImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTexSubImage3DEXT +#define GLEE_H_DEFINED_glCopyTexSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYTEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glCopyTexSubImage3DEXT; + #define glCopyTexSubImage3DEXT GLeeFuncPtr_glCopyTexSubImage3DEXT +#endif +#endif + +/* GL_EXT_histogram */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#define __GLEE_GL_EXT_histogram 1 +/* Constants */ +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#ifndef GLEE_H_DEFINED_glGetHistogramEXT +#define GLEE_H_DEFINED_glGetHistogramEXT + typedef void (APIENTRYP GLEEPFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); + GLEE_EXTERN GLEEPFNGLGETHISTOGRAMEXTPROC GLeeFuncPtr_glGetHistogramEXT; + #define glGetHistogramEXT GLeeFuncPtr_glGetHistogramEXT +#endif +#ifndef GLEE_H_DEFINED_glGetHistogramParameterfvEXT +#define GLEE_H_DEFINED_glGetHistogramParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETHISTOGRAMPARAMETERFVEXTPROC GLeeFuncPtr_glGetHistogramParameterfvEXT; + #define glGetHistogramParameterfvEXT GLeeFuncPtr_glGetHistogramParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetHistogramParameterivEXT +#define GLEE_H_DEFINED_glGetHistogramParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETHISTOGRAMPARAMETERIVEXTPROC GLeeFuncPtr_glGetHistogramParameterivEXT; + #define glGetHistogramParameterivEXT GLeeFuncPtr_glGetHistogramParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMinmaxEXT +#define GLEE_H_DEFINED_glGetMinmaxEXT + typedef void (APIENTRYP GLEEPFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); + GLEE_EXTERN GLEEPFNGLGETMINMAXEXTPROC GLeeFuncPtr_glGetMinmaxEXT; + #define glGetMinmaxEXT GLeeFuncPtr_glGetMinmaxEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMinmaxParameterfvEXT +#define GLEE_H_DEFINED_glGetMinmaxParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMINMAXPARAMETERFVEXTPROC GLeeFuncPtr_glGetMinmaxParameterfvEXT; + #define glGetMinmaxParameterfvEXT GLeeFuncPtr_glGetMinmaxParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMinmaxParameterivEXT +#define GLEE_H_DEFINED_glGetMinmaxParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMINMAXPARAMETERIVEXTPROC GLeeFuncPtr_glGetMinmaxParameterivEXT; + #define glGetMinmaxParameterivEXT GLeeFuncPtr_glGetMinmaxParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glHistogramEXT +#define GLEE_H_DEFINED_glHistogramEXT + typedef void (APIENTRYP GLEEPFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); + GLEE_EXTERN GLEEPFNGLHISTOGRAMEXTPROC GLeeFuncPtr_glHistogramEXT; + #define glHistogramEXT GLeeFuncPtr_glHistogramEXT +#endif +#ifndef GLEE_H_DEFINED_glMinmaxEXT +#define GLEE_H_DEFINED_glMinmaxEXT + typedef void (APIENTRYP GLEEPFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); + GLEE_EXTERN GLEEPFNGLMINMAXEXTPROC GLeeFuncPtr_glMinmaxEXT; + #define glMinmaxEXT GLeeFuncPtr_glMinmaxEXT +#endif +#ifndef GLEE_H_DEFINED_glResetHistogramEXT +#define GLEE_H_DEFINED_glResetHistogramEXT + typedef void (APIENTRYP GLEEPFNGLRESETHISTOGRAMEXTPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLRESETHISTOGRAMEXTPROC GLeeFuncPtr_glResetHistogramEXT; + #define glResetHistogramEXT GLeeFuncPtr_glResetHistogramEXT +#endif +#ifndef GLEE_H_DEFINED_glResetMinmaxEXT +#define GLEE_H_DEFINED_glResetMinmaxEXT + typedef void (APIENTRYP GLEEPFNGLRESETMINMAXEXTPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLRESETMINMAXEXTPROC GLeeFuncPtr_glResetMinmaxEXT; + #define glResetMinmaxEXT GLeeFuncPtr_glResetMinmaxEXT +#endif +#endif + +/* GL_EXT_convolution */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#define __GLEE_GL_EXT_convolution 1 +/* Constants */ +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#ifndef GLEE_H_DEFINED_glConvolutionFilter1DEXT +#define GLEE_H_DEFINED_glConvolutionFilter1DEXT + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * image); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONFILTER1DEXTPROC GLeeFuncPtr_glConvolutionFilter1DEXT; + #define glConvolutionFilter1DEXT GLeeFuncPtr_glConvolutionFilter1DEXT +#endif +#ifndef GLEE_H_DEFINED_glConvolutionFilter2DEXT +#define GLEE_H_DEFINED_glConvolutionFilter2DEXT + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * image); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONFILTER2DEXTPROC GLeeFuncPtr_glConvolutionFilter2DEXT; + #define glConvolutionFilter2DEXT GLeeFuncPtr_glConvolutionFilter2DEXT +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameterfEXT +#define GLEE_H_DEFINED_glConvolutionParameterfEXT + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERFEXTPROC GLeeFuncPtr_glConvolutionParameterfEXT; + #define glConvolutionParameterfEXT GLeeFuncPtr_glConvolutionParameterfEXT +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameterfvEXT +#define GLEE_H_DEFINED_glConvolutionParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERFVEXTPROC GLeeFuncPtr_glConvolutionParameterfvEXT; + #define glConvolutionParameterfvEXT GLeeFuncPtr_glConvolutionParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameteriEXT +#define GLEE_H_DEFINED_glConvolutionParameteriEXT + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERIEXTPROC GLeeFuncPtr_glConvolutionParameteriEXT; + #define glConvolutionParameteriEXT GLeeFuncPtr_glConvolutionParameteriEXT +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameterivEXT +#define GLEE_H_DEFINED_glConvolutionParameterivEXT + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERIVEXTPROC GLeeFuncPtr_glConvolutionParameterivEXT; + #define glConvolutionParameterivEXT GLeeFuncPtr_glConvolutionParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyConvolutionFilter1DEXT +#define GLEE_H_DEFINED_glCopyConvolutionFilter1DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYCONVOLUTIONFILTER1DEXTPROC GLeeFuncPtr_glCopyConvolutionFilter1DEXT; + #define glCopyConvolutionFilter1DEXT GLeeFuncPtr_glCopyConvolutionFilter1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyConvolutionFilter2DEXT +#define GLEE_H_DEFINED_glCopyConvolutionFilter2DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYCONVOLUTIONFILTER2DEXTPROC GLeeFuncPtr_glCopyConvolutionFilter2DEXT; + #define glCopyConvolutionFilter2DEXT GLeeFuncPtr_glCopyConvolutionFilter2DEXT +#endif +#ifndef GLEE_H_DEFINED_glGetConvolutionFilterEXT +#define GLEE_H_DEFINED_glGetConvolutionFilterEXT + typedef void (APIENTRYP GLEEPFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid * image); + GLEE_EXTERN GLEEPFNGLGETCONVOLUTIONFILTEREXTPROC GLeeFuncPtr_glGetConvolutionFilterEXT; + #define glGetConvolutionFilterEXT GLeeFuncPtr_glGetConvolutionFilterEXT +#endif +#ifndef GLEE_H_DEFINED_glGetConvolutionParameterfvEXT +#define GLEE_H_DEFINED_glGetConvolutionParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCONVOLUTIONPARAMETERFVEXTPROC GLeeFuncPtr_glGetConvolutionParameterfvEXT; + #define glGetConvolutionParameterfvEXT GLeeFuncPtr_glGetConvolutionParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetConvolutionParameterivEXT +#define GLEE_H_DEFINED_glGetConvolutionParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETCONVOLUTIONPARAMETERIVEXTPROC GLeeFuncPtr_glGetConvolutionParameterivEXT; + #define glGetConvolutionParameterivEXT GLeeFuncPtr_glGetConvolutionParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetSeparableFilterEXT +#define GLEE_H_DEFINED_glGetSeparableFilterEXT + typedef void (APIENTRYP GLEEPFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span); + GLEE_EXTERN GLEEPFNGLGETSEPARABLEFILTEREXTPROC GLeeFuncPtr_glGetSeparableFilterEXT; + #define glGetSeparableFilterEXT GLeeFuncPtr_glGetSeparableFilterEXT +#endif +#ifndef GLEE_H_DEFINED_glSeparableFilter2DEXT +#define GLEE_H_DEFINED_glSeparableFilter2DEXT + typedef void (APIENTRYP GLEEPFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * row, const GLvoid * column); + GLEE_EXTERN GLEEPFNGLSEPARABLEFILTER2DEXTPROC GLeeFuncPtr_glSeparableFilter2DEXT; + #define glSeparableFilter2DEXT GLeeFuncPtr_glSeparableFilter2DEXT +#endif +#endif + +/* GL_SGI_color_matrix */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 +#define __GLEE_GL_SGI_color_matrix 1 +/* Constants */ +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +/* GL_SGI_color_table */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#define __GLEE_GL_SGI_color_table 1 +/* Constants */ +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#ifndef GLEE_H_DEFINED_glColorTableSGI +#define GLEE_H_DEFINED_glColorTableSGI + typedef void (APIENTRYP GLEEPFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table); + GLEE_EXTERN GLEEPFNGLCOLORTABLESGIPROC GLeeFuncPtr_glColorTableSGI; + #define glColorTableSGI GLeeFuncPtr_glColorTableSGI +#endif +#ifndef GLEE_H_DEFINED_glColorTableParameterfvSGI +#define GLEE_H_DEFINED_glColorTableParameterfvSGI + typedef void (APIENTRYP GLEEPFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLCOLORTABLEPARAMETERFVSGIPROC GLeeFuncPtr_glColorTableParameterfvSGI; + #define glColorTableParameterfvSGI GLeeFuncPtr_glColorTableParameterfvSGI +#endif +#ifndef GLEE_H_DEFINED_glColorTableParameterivSGI +#define GLEE_H_DEFINED_glColorTableParameterivSGI + typedef void (APIENTRYP GLEEPFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLCOLORTABLEPARAMETERIVSGIPROC GLeeFuncPtr_glColorTableParameterivSGI; + #define glColorTableParameterivSGI GLeeFuncPtr_glColorTableParameterivSGI +#endif +#ifndef GLEE_H_DEFINED_glCopyColorTableSGI +#define GLEE_H_DEFINED_glCopyColorTableSGI + typedef void (APIENTRYP GLEEPFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYCOLORTABLESGIPROC GLeeFuncPtr_glCopyColorTableSGI; + #define glCopyColorTableSGI GLeeFuncPtr_glCopyColorTableSGI +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableSGI +#define GLEE_H_DEFINED_glGetColorTableSGI + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid * table); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLESGIPROC GLeeFuncPtr_glGetColorTableSGI; + #define glGetColorTableSGI GLeeFuncPtr_glGetColorTableSGI +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableParameterfvSGI +#define GLEE_H_DEFINED_glGetColorTableParameterfvSGI + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEPARAMETERFVSGIPROC GLeeFuncPtr_glGetColorTableParameterfvSGI; + #define glGetColorTableParameterfvSGI GLeeFuncPtr_glGetColorTableParameterfvSGI +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableParameterivSGI +#define GLEE_H_DEFINED_glGetColorTableParameterivSGI + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEPARAMETERIVSGIPROC GLeeFuncPtr_glGetColorTableParameterivSGI; + #define glGetColorTableParameterivSGI GLeeFuncPtr_glGetColorTableParameterivSGI +#endif +#endif + +/* GL_SGIS_pixel_texture */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#define __GLEE_GL_SGIS_pixel_texture 1 +/* Constants */ +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#ifndef GLEE_H_DEFINED_glPixelTexGenParameteriSGIS +#define GLEE_H_DEFINED_glPixelTexGenParameteriSGIS + typedef void (APIENTRYP GLEEPFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLPIXELTEXGENPARAMETERISGISPROC GLeeFuncPtr_glPixelTexGenParameteriSGIS; + #define glPixelTexGenParameteriSGIS GLeeFuncPtr_glPixelTexGenParameteriSGIS +#endif +#ifndef GLEE_H_DEFINED_glPixelTexGenParameterivSGIS +#define GLEE_H_DEFINED_glPixelTexGenParameterivSGIS + typedef void (APIENTRYP GLEEPFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLPIXELTEXGENPARAMETERIVSGISPROC GLeeFuncPtr_glPixelTexGenParameterivSGIS; + #define glPixelTexGenParameterivSGIS GLeeFuncPtr_glPixelTexGenParameterivSGIS +#endif +#ifndef GLEE_H_DEFINED_glPixelTexGenParameterfSGIS +#define GLEE_H_DEFINED_glPixelTexGenParameterfSGIS + typedef void (APIENTRYP GLEEPFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLPIXELTEXGENPARAMETERFSGISPROC GLeeFuncPtr_glPixelTexGenParameterfSGIS; + #define glPixelTexGenParameterfSGIS GLeeFuncPtr_glPixelTexGenParameterfSGIS +#endif +#ifndef GLEE_H_DEFINED_glPixelTexGenParameterfvSGIS +#define GLEE_H_DEFINED_glPixelTexGenParameterfvSGIS + typedef void (APIENTRYP GLEEPFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPIXELTEXGENPARAMETERFVSGISPROC GLeeFuncPtr_glPixelTexGenParameterfvSGIS; + #define glPixelTexGenParameterfvSGIS GLeeFuncPtr_glPixelTexGenParameterfvSGIS +#endif +#ifndef GLEE_H_DEFINED_glGetPixelTexGenParameterivSGIS +#define GLEE_H_DEFINED_glGetPixelTexGenParameterivSGIS + typedef void (APIENTRYP GLEEPFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPIXELTEXGENPARAMETERIVSGISPROC GLeeFuncPtr_glGetPixelTexGenParameterivSGIS; + #define glGetPixelTexGenParameterivSGIS GLeeFuncPtr_glGetPixelTexGenParameterivSGIS +#endif +#ifndef GLEE_H_DEFINED_glGetPixelTexGenParameterfvSGIS +#define GLEE_H_DEFINED_glGetPixelTexGenParameterfvSGIS + typedef void (APIENTRYP GLEEPFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETPIXELTEXGENPARAMETERFVSGISPROC GLeeFuncPtr_glGetPixelTexGenParameterfvSGIS; + #define glGetPixelTexGenParameterfvSGIS GLeeFuncPtr_glGetPixelTexGenParameterfvSGIS +#endif +#endif + +/* GL_SGIX_pixel_texture */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#define __GLEE_GL_SGIX_pixel_texture 1 +/* Constants */ +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#ifndef GLEE_H_DEFINED_glPixelTexGenSGIX +#define GLEE_H_DEFINED_glPixelTexGenSGIX + typedef void (APIENTRYP GLEEPFNGLPIXELTEXGENSGIXPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLPIXELTEXGENSGIXPROC GLeeFuncPtr_glPixelTexGenSGIX; + #define glPixelTexGenSGIX GLeeFuncPtr_glPixelTexGenSGIX +#endif +#endif + +/* GL_SGIS_texture4D */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#define __GLEE_GL_SGIS_texture4D 1 +/* Constants */ +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#ifndef GLEE_H_DEFINED_glTexImage4DSGIS +#define GLEE_H_DEFINED_glTexImage4DSGIS + typedef void (APIENTRYP GLEEPFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXIMAGE4DSGISPROC GLeeFuncPtr_glTexImage4DSGIS; + #define glTexImage4DSGIS GLeeFuncPtr_glTexImage4DSGIS +#endif +#ifndef GLEE_H_DEFINED_glTexSubImage4DSGIS +#define GLEE_H_DEFINED_glTexSubImage4DSGIS + typedef void (APIENTRYP GLEEPFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXSUBIMAGE4DSGISPROC GLeeFuncPtr_glTexSubImage4DSGIS; + #define glTexSubImage4DSGIS GLeeFuncPtr_glTexSubImage4DSGIS +#endif +#endif + +/* GL_SGI_texture_color_table */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#define __GLEE_GL_SGI_texture_color_table 1 +/* Constants */ +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +/* GL_EXT_cmyka */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#define __GLEE_GL_EXT_cmyka 1 +/* Constants */ +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +/* GL_EXT_texture_object */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#define __GLEE_GL_EXT_texture_object 1 +/* Constants */ +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#ifndef GLEE_H_DEFINED_glAreTexturesResidentEXT +#define GLEE_H_DEFINED_glAreTexturesResidentEXT + typedef GLboolean (APIENTRYP GLEEPFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint * textures, GLboolean * residences); + GLEE_EXTERN GLEEPFNGLARETEXTURESRESIDENTEXTPROC GLeeFuncPtr_glAreTexturesResidentEXT; + #define glAreTexturesResidentEXT GLeeFuncPtr_glAreTexturesResidentEXT +#endif +#ifndef GLEE_H_DEFINED_glBindTextureEXT +#define GLEE_H_DEFINED_glBindTextureEXT + typedef void (APIENTRYP GLEEPFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); + GLEE_EXTERN GLEEPFNGLBINDTEXTUREEXTPROC GLeeFuncPtr_glBindTextureEXT; + #define glBindTextureEXT GLeeFuncPtr_glBindTextureEXT +#endif +#ifndef GLEE_H_DEFINED_glDeleteTexturesEXT +#define GLEE_H_DEFINED_glDeleteTexturesEXT + typedef void (APIENTRYP GLEEPFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint * textures); + GLEE_EXTERN GLEEPFNGLDELETETEXTURESEXTPROC GLeeFuncPtr_glDeleteTexturesEXT; + #define glDeleteTexturesEXT GLeeFuncPtr_glDeleteTexturesEXT +#endif +#ifndef GLEE_H_DEFINED_glGenTexturesEXT +#define GLEE_H_DEFINED_glGenTexturesEXT + typedef void (APIENTRYP GLEEPFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint * textures); + GLEE_EXTERN GLEEPFNGLGENTEXTURESEXTPROC GLeeFuncPtr_glGenTexturesEXT; + #define glGenTexturesEXT GLeeFuncPtr_glGenTexturesEXT +#endif +#ifndef GLEE_H_DEFINED_glIsTextureEXT +#define GLEE_H_DEFINED_glIsTextureEXT + typedef GLboolean (APIENTRYP GLEEPFNGLISTEXTUREEXTPROC) (GLuint texture); + GLEE_EXTERN GLEEPFNGLISTEXTUREEXTPROC GLeeFuncPtr_glIsTextureEXT; + #define glIsTextureEXT GLeeFuncPtr_glIsTextureEXT +#endif +#ifndef GLEE_H_DEFINED_glPrioritizeTexturesEXT +#define GLEE_H_DEFINED_glPrioritizeTexturesEXT + typedef void (APIENTRYP GLEEPFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint * textures, const GLclampf * priorities); + GLEE_EXTERN GLEEPFNGLPRIORITIZETEXTURESEXTPROC GLeeFuncPtr_glPrioritizeTexturesEXT; + #define glPrioritizeTexturesEXT GLeeFuncPtr_glPrioritizeTexturesEXT +#endif +#endif + +/* GL_SGIS_detail_texture */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#define __GLEE_GL_SGIS_detail_texture 1 +/* Constants */ +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#ifndef GLEE_H_DEFINED_glDetailTexFuncSGIS +#define GLEE_H_DEFINED_glDetailTexFuncSGIS + typedef void (APIENTRYP GLEEPFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat * points); + GLEE_EXTERN GLEEPFNGLDETAILTEXFUNCSGISPROC GLeeFuncPtr_glDetailTexFuncSGIS; + #define glDetailTexFuncSGIS GLeeFuncPtr_glDetailTexFuncSGIS +#endif +#ifndef GLEE_H_DEFINED_glGetDetailTexFuncSGIS +#define GLEE_H_DEFINED_glGetDetailTexFuncSGIS + typedef void (APIENTRYP GLEEPFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat * points); + GLEE_EXTERN GLEEPFNGLGETDETAILTEXFUNCSGISPROC GLeeFuncPtr_glGetDetailTexFuncSGIS; + #define glGetDetailTexFuncSGIS GLeeFuncPtr_glGetDetailTexFuncSGIS +#endif +#endif + +/* GL_SGIS_sharpen_texture */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#define __GLEE_GL_SGIS_sharpen_texture 1 +/* Constants */ +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#ifndef GLEE_H_DEFINED_glSharpenTexFuncSGIS +#define GLEE_H_DEFINED_glSharpenTexFuncSGIS + typedef void (APIENTRYP GLEEPFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat * points); + GLEE_EXTERN GLEEPFNGLSHARPENTEXFUNCSGISPROC GLeeFuncPtr_glSharpenTexFuncSGIS; + #define glSharpenTexFuncSGIS GLeeFuncPtr_glSharpenTexFuncSGIS +#endif +#ifndef GLEE_H_DEFINED_glGetSharpenTexFuncSGIS +#define GLEE_H_DEFINED_glGetSharpenTexFuncSGIS + typedef void (APIENTRYP GLEEPFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat * points); + GLEE_EXTERN GLEEPFNGLGETSHARPENTEXFUNCSGISPROC GLeeFuncPtr_glGetSharpenTexFuncSGIS; + #define glGetSharpenTexFuncSGIS GLeeFuncPtr_glGetSharpenTexFuncSGIS +#endif +#endif + +/* GL_EXT_packed_pixels */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#define __GLEE_GL_EXT_packed_pixels 1 +/* Constants */ +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +/* GL_SGIS_texture_lod */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#define __GLEE_GL_SGIS_texture_lod 1 +/* Constants */ +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +/* GL_SGIS_multisample */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#define __GLEE_GL_SGIS_multisample 1 +/* Constants */ +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#ifndef GLEE_H_DEFINED_glSampleMaskSGIS +#define GLEE_H_DEFINED_glSampleMaskSGIS + typedef void (APIENTRYP GLEEPFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); + GLEE_EXTERN GLEEPFNGLSAMPLEMASKSGISPROC GLeeFuncPtr_glSampleMaskSGIS; + #define glSampleMaskSGIS GLeeFuncPtr_glSampleMaskSGIS +#endif +#ifndef GLEE_H_DEFINED_glSamplePatternSGIS +#define GLEE_H_DEFINED_glSamplePatternSGIS + typedef void (APIENTRYP GLEEPFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); + GLEE_EXTERN GLEEPFNGLSAMPLEPATTERNSGISPROC GLeeFuncPtr_glSamplePatternSGIS; + #define glSamplePatternSGIS GLeeFuncPtr_glSamplePatternSGIS +#endif +#endif + +/* GL_EXT_rescale_normal */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#define __GLEE_GL_EXT_rescale_normal 1 +/* Constants */ +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +/* GL_EXT_vertex_array */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#define __GLEE_GL_EXT_vertex_array 1 +/* Constants */ +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#ifndef GLEE_H_DEFINED_glArrayElementEXT +#define GLEE_H_DEFINED_glArrayElementEXT + typedef void (APIENTRYP GLEEPFNGLARRAYELEMENTEXTPROC) (GLint i); + GLEE_EXTERN GLEEPFNGLARRAYELEMENTEXTPROC GLeeFuncPtr_glArrayElementEXT; + #define glArrayElementEXT GLeeFuncPtr_glArrayElementEXT +#endif +#ifndef GLEE_H_DEFINED_glColorPointerEXT +#define GLEE_H_DEFINED_glColorPointerEXT + typedef void (APIENTRYP GLEEPFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLCOLORPOINTEREXTPROC GLeeFuncPtr_glColorPointerEXT; + #define glColorPointerEXT GLeeFuncPtr_glColorPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glDrawArraysEXT +#define GLEE_H_DEFINED_glDrawArraysEXT + typedef void (APIENTRYP GLEEPFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); + GLEE_EXTERN GLEEPFNGLDRAWARRAYSEXTPROC GLeeFuncPtr_glDrawArraysEXT; + #define glDrawArraysEXT GLeeFuncPtr_glDrawArraysEXT +#endif +#ifndef GLEE_H_DEFINED_glEdgeFlagPointerEXT +#define GLEE_H_DEFINED_glEdgeFlagPointerEXT + typedef void (APIENTRYP GLEEPFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean * pointer); + GLEE_EXTERN GLEEPFNGLEDGEFLAGPOINTEREXTPROC GLeeFuncPtr_glEdgeFlagPointerEXT; + #define glEdgeFlagPointerEXT GLeeFuncPtr_glEdgeFlagPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glGetPointervEXT +#define GLEE_H_DEFINED_glGetPointervEXT + typedef void (APIENTRYP GLEEPFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* * params); + GLEE_EXTERN GLEEPFNGLGETPOINTERVEXTPROC GLeeFuncPtr_glGetPointervEXT; + #define glGetPointervEXT GLeeFuncPtr_glGetPointervEXT +#endif +#ifndef GLEE_H_DEFINED_glIndexPointerEXT +#define GLEE_H_DEFINED_glIndexPointerEXT + typedef void (APIENTRYP GLEEPFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLINDEXPOINTEREXTPROC GLeeFuncPtr_glIndexPointerEXT; + #define glIndexPointerEXT GLeeFuncPtr_glIndexPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glNormalPointerEXT +#define GLEE_H_DEFINED_glNormalPointerEXT + typedef void (APIENTRYP GLEEPFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLNORMALPOINTEREXTPROC GLeeFuncPtr_glNormalPointerEXT; + #define glNormalPointerEXT GLeeFuncPtr_glNormalPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glTexCoordPointerEXT +#define GLEE_H_DEFINED_glTexCoordPointerEXT + typedef void (APIENTRYP GLEEPFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLTEXCOORDPOINTEREXTPROC GLeeFuncPtr_glTexCoordPointerEXT; + #define glTexCoordPointerEXT GLeeFuncPtr_glTexCoordPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexPointerEXT +#define GLEE_H_DEFINED_glVertexPointerEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXPOINTEREXTPROC GLeeFuncPtr_glVertexPointerEXT; + #define glVertexPointerEXT GLeeFuncPtr_glVertexPointerEXT +#endif +#endif + +/* GL_EXT_misc_attribute */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#define __GLEE_GL_EXT_misc_attribute 1 +/* Constants */ +#endif + +/* GL_SGIS_generate_mipmap */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#define __GLEE_GL_SGIS_generate_mipmap 1 +/* Constants */ +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +/* GL_SGIX_clipmap */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#define __GLEE_GL_SGIX_clipmap 1 +/* Constants */ +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +/* GL_SGIX_shadow */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#define __GLEE_GL_SGIX_shadow 1 +/* Constants */ +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +/* GL_SGIS_texture_edge_clamp */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#define __GLEE_GL_SGIS_texture_edge_clamp 1 +/* Constants */ +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +/* GL_SGIS_texture_border_clamp */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#define __GLEE_GL_SGIS_texture_border_clamp 1 +/* Constants */ +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +/* GL_EXT_blend_minmax */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#define __GLEE_GL_EXT_blend_minmax 1 +/* Constants */ +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#ifndef GLEE_H_DEFINED_glBlendEquationEXT +#define GLEE_H_DEFINED_glBlendEquationEXT + typedef void (APIENTRYP GLEEPFNGLBLENDEQUATIONEXTPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLBLENDEQUATIONEXTPROC GLeeFuncPtr_glBlendEquationEXT; + #define glBlendEquationEXT GLeeFuncPtr_glBlendEquationEXT +#endif +#endif + +/* GL_EXT_blend_subtract */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#define __GLEE_GL_EXT_blend_subtract 1 +/* Constants */ +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +/* GL_EXT_blend_logic_op */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#define __GLEE_GL_EXT_blend_logic_op 1 +/* Constants */ +#endif + +/* GL_SGIX_interlace */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#define __GLEE_GL_SGIX_interlace 1 +/* Constants */ +#define GL_INTERLACE_SGIX 0x8094 +#endif + +/* GL_SGIX_pixel_tiles */ + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#define __GLEE_GL_SGIX_pixel_tiles 1 +/* Constants */ +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +/* GL_SGIS_texture_select */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 +#define __GLEE_GL_SGIS_texture_select 1 +/* Constants */ +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +/* GL_SGIX_sprite */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#define __GLEE_GL_SGIX_sprite 1 +/* Constants */ +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#ifndef GLEE_H_DEFINED_glSpriteParameterfSGIX +#define GLEE_H_DEFINED_glSpriteParameterfSGIX + typedef void (APIENTRYP GLEEPFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLSPRITEPARAMETERFSGIXPROC GLeeFuncPtr_glSpriteParameterfSGIX; + #define glSpriteParameterfSGIX GLeeFuncPtr_glSpriteParameterfSGIX +#endif +#ifndef GLEE_H_DEFINED_glSpriteParameterfvSGIX +#define GLEE_H_DEFINED_glSpriteParameterfvSGIX + typedef void (APIENTRYP GLEEPFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLSPRITEPARAMETERFVSGIXPROC GLeeFuncPtr_glSpriteParameterfvSGIX; + #define glSpriteParameterfvSGIX GLeeFuncPtr_glSpriteParameterfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glSpriteParameteriSGIX +#define GLEE_H_DEFINED_glSpriteParameteriSGIX + typedef void (APIENTRYP GLEEPFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLSPRITEPARAMETERISGIXPROC GLeeFuncPtr_glSpriteParameteriSGIX; + #define glSpriteParameteriSGIX GLeeFuncPtr_glSpriteParameteriSGIX +#endif +#ifndef GLEE_H_DEFINED_glSpriteParameterivSGIX +#define GLEE_H_DEFINED_glSpriteParameterivSGIX + typedef void (APIENTRYP GLEEPFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLSPRITEPARAMETERIVSGIXPROC GLeeFuncPtr_glSpriteParameterivSGIX; + #define glSpriteParameterivSGIX GLeeFuncPtr_glSpriteParameterivSGIX +#endif +#endif + +/* GL_SGIX_texture_multi_buffer */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#define __GLEE_GL_SGIX_texture_multi_buffer 1 +/* Constants */ +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +/* GL_EXT_point_parameters */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#define __GLEE_GL_EXT_point_parameters 1 +/* Constants */ +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#ifndef GLEE_H_DEFINED_glPointParameterfEXT +#define GLEE_H_DEFINED_glPointParameterfEXT + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFEXTPROC GLeeFuncPtr_glPointParameterfEXT; + #define glPointParameterfEXT GLeeFuncPtr_glPointParameterfEXT +#endif +#ifndef GLEE_H_DEFINED_glPointParameterfvEXT +#define GLEE_H_DEFINED_glPointParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFVEXTPROC GLeeFuncPtr_glPointParameterfvEXT; + #define glPointParameterfvEXT GLeeFuncPtr_glPointParameterfvEXT +#endif +#endif + +/* GL_SGIS_point_parameters */ + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#define __GLEE_GL_SGIS_point_parameters 1 +/* Constants */ +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#ifndef GLEE_H_DEFINED_glPointParameterfSGIS +#define GLEE_H_DEFINED_glPointParameterfSGIS + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFSGISPROC GLeeFuncPtr_glPointParameterfSGIS; + #define glPointParameterfSGIS GLeeFuncPtr_glPointParameterfSGIS +#endif +#ifndef GLEE_H_DEFINED_glPointParameterfvSGIS +#define GLEE_H_DEFINED_glPointParameterfvSGIS + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERFVSGISPROC GLeeFuncPtr_glPointParameterfvSGIS; + #define glPointParameterfvSGIS GLeeFuncPtr_glPointParameterfvSGIS +#endif +#endif + +/* GL_SGIX_instruments */ + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#define __GLEE_GL_SGIX_instruments 1 +/* Constants */ +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#ifndef GLEE_H_DEFINED_glGetInstrumentsSGIX +#define GLEE_H_DEFINED_glGetInstrumentsSGIX + typedef GLint (APIENTRYP GLEEPFNGLGETINSTRUMENTSSGIXPROC) (); + GLEE_EXTERN GLEEPFNGLGETINSTRUMENTSSGIXPROC GLeeFuncPtr_glGetInstrumentsSGIX; + #define glGetInstrumentsSGIX GLeeFuncPtr_glGetInstrumentsSGIX +#endif +#ifndef GLEE_H_DEFINED_glInstrumentsBufferSGIX +#define GLEE_H_DEFINED_glInstrumentsBufferSGIX + typedef void (APIENTRYP GLEEPFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint * buffer); + GLEE_EXTERN GLEEPFNGLINSTRUMENTSBUFFERSGIXPROC GLeeFuncPtr_glInstrumentsBufferSGIX; + #define glInstrumentsBufferSGIX GLeeFuncPtr_glInstrumentsBufferSGIX +#endif +#ifndef GLEE_H_DEFINED_glPollInstrumentsSGIX +#define GLEE_H_DEFINED_glPollInstrumentsSGIX + typedef GLint (APIENTRYP GLEEPFNGLPOLLINSTRUMENTSSGIXPROC) (GLint * marker_p); + GLEE_EXTERN GLEEPFNGLPOLLINSTRUMENTSSGIXPROC GLeeFuncPtr_glPollInstrumentsSGIX; + #define glPollInstrumentsSGIX GLeeFuncPtr_glPollInstrumentsSGIX +#endif +#ifndef GLEE_H_DEFINED_glReadInstrumentsSGIX +#define GLEE_H_DEFINED_glReadInstrumentsSGIX + typedef void (APIENTRYP GLEEPFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); + GLEE_EXTERN GLEEPFNGLREADINSTRUMENTSSGIXPROC GLeeFuncPtr_glReadInstrumentsSGIX; + #define glReadInstrumentsSGIX GLeeFuncPtr_glReadInstrumentsSGIX +#endif +#ifndef GLEE_H_DEFINED_glStartInstrumentsSGIX +#define GLEE_H_DEFINED_glStartInstrumentsSGIX + typedef void (APIENTRYP GLEEPFNGLSTARTINSTRUMENTSSGIXPROC) (); + GLEE_EXTERN GLEEPFNGLSTARTINSTRUMENTSSGIXPROC GLeeFuncPtr_glStartInstrumentsSGIX; + #define glStartInstrumentsSGIX GLeeFuncPtr_glStartInstrumentsSGIX +#endif +#ifndef GLEE_H_DEFINED_glStopInstrumentsSGIX +#define GLEE_H_DEFINED_glStopInstrumentsSGIX + typedef void (APIENTRYP GLEEPFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); + GLEE_EXTERN GLEEPFNGLSTOPINSTRUMENTSSGIXPROC GLeeFuncPtr_glStopInstrumentsSGIX; + #define glStopInstrumentsSGIX GLeeFuncPtr_glStopInstrumentsSGIX +#endif +#endif + +/* GL_SGIX_texture_scale_bias */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#define __GLEE_GL_SGIX_texture_scale_bias 1 +/* Constants */ +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +/* GL_SGIX_framezoom */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#define __GLEE_GL_SGIX_framezoom 1 +/* Constants */ +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#ifndef GLEE_H_DEFINED_glFrameZoomSGIX +#define GLEE_H_DEFINED_glFrameZoomSGIX + typedef void (APIENTRYP GLEEPFNGLFRAMEZOOMSGIXPROC) (GLint factor); + GLEE_EXTERN GLEEPFNGLFRAMEZOOMSGIXPROC GLeeFuncPtr_glFrameZoomSGIX; + #define glFrameZoomSGIX GLeeFuncPtr_glFrameZoomSGIX +#endif +#endif + +/* GL_SGIX_tag_sample_buffer */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#define __GLEE_GL_SGIX_tag_sample_buffer 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glTagSampleBufferSGIX +#define GLEE_H_DEFINED_glTagSampleBufferSGIX + typedef void (APIENTRYP GLEEPFNGLTAGSAMPLEBUFFERSGIXPROC) (); + GLEE_EXTERN GLEEPFNGLTAGSAMPLEBUFFERSGIXPROC GLeeFuncPtr_glTagSampleBufferSGIX; + #define glTagSampleBufferSGIX GLeeFuncPtr_glTagSampleBufferSGIX +#endif +#endif + +/* GL_FfdMaskSGIX */ + +#ifndef GL_FfdMaskSGIX +#define GL_FfdMaskSGIX 1 +#define __GLEE_GL_FfdMaskSGIX 1 +/* Constants */ +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +/* GL_SGIX_polynomial_ffd */ + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#define __GLEE_GL_SGIX_polynomial_ffd 1 +/* Constants */ +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#ifndef GLEE_H_DEFINED_glDeformationMap3dSGIX +#define GLEE_H_DEFINED_glDeformationMap3dSGIX + typedef void (APIENTRYP GLEEPFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble * points); + GLEE_EXTERN GLEEPFNGLDEFORMATIONMAP3DSGIXPROC GLeeFuncPtr_glDeformationMap3dSGIX; + #define glDeformationMap3dSGIX GLeeFuncPtr_glDeformationMap3dSGIX +#endif +#ifndef GLEE_H_DEFINED_glDeformationMap3fSGIX +#define GLEE_H_DEFINED_glDeformationMap3fSGIX + typedef void (APIENTRYP GLEEPFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat * points); + GLEE_EXTERN GLEEPFNGLDEFORMATIONMAP3FSGIXPROC GLeeFuncPtr_glDeformationMap3fSGIX; + #define glDeformationMap3fSGIX GLeeFuncPtr_glDeformationMap3fSGIX +#endif +#ifndef GLEE_H_DEFINED_glDeformSGIX +#define GLEE_H_DEFINED_glDeformSGIX + typedef void (APIENTRYP GLEEPFNGLDEFORMSGIXPROC) (GLbitfield mask); + GLEE_EXTERN GLEEPFNGLDEFORMSGIXPROC GLeeFuncPtr_glDeformSGIX; + #define glDeformSGIX GLeeFuncPtr_glDeformSGIX +#endif +#ifndef GLEE_H_DEFINED_glLoadIdentityDeformationMapSGIX +#define GLEE_H_DEFINED_glLoadIdentityDeformationMapSGIX + typedef void (APIENTRYP GLEEPFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); + GLEE_EXTERN GLEEPFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC GLeeFuncPtr_glLoadIdentityDeformationMapSGIX; + #define glLoadIdentityDeformationMapSGIX GLeeFuncPtr_glLoadIdentityDeformationMapSGIX +#endif +#endif + +/* GL_SGIX_reference_plane */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#define __GLEE_GL_SGIX_reference_plane 1 +/* Constants */ +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#ifndef GLEE_H_DEFINED_glReferencePlaneSGIX +#define GLEE_H_DEFINED_glReferencePlaneSGIX + typedef void (APIENTRYP GLEEPFNGLREFERENCEPLANESGIXPROC) (const GLdouble * equation); + GLEE_EXTERN GLEEPFNGLREFERENCEPLANESGIXPROC GLeeFuncPtr_glReferencePlaneSGIX; + #define glReferencePlaneSGIX GLeeFuncPtr_glReferencePlaneSGIX +#endif +#endif + +/* GL_SGIX_flush_raster */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#define __GLEE_GL_SGIX_flush_raster 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glFlushRasterSGIX +#define GLEE_H_DEFINED_glFlushRasterSGIX + typedef void (APIENTRYP GLEEPFNGLFLUSHRASTERSGIXPROC) (); + GLEE_EXTERN GLEEPFNGLFLUSHRASTERSGIXPROC GLeeFuncPtr_glFlushRasterSGIX; + #define glFlushRasterSGIX GLeeFuncPtr_glFlushRasterSGIX +#endif +#endif + +/* GL_SGIX_depth_texture */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#define __GLEE_GL_SGIX_depth_texture 1 +/* Constants */ +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +/* GL_SGIS_fog_function */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#define __GLEE_GL_SGIS_fog_function 1 +/* Constants */ +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#ifndef GLEE_H_DEFINED_glFogFuncSGIS +#define GLEE_H_DEFINED_glFogFuncSGIS + typedef void (APIENTRYP GLEEPFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat * points); + GLEE_EXTERN GLEEPFNGLFOGFUNCSGISPROC GLeeFuncPtr_glFogFuncSGIS; + #define glFogFuncSGIS GLeeFuncPtr_glFogFuncSGIS +#endif +#ifndef GLEE_H_DEFINED_glGetFogFuncSGIS +#define GLEE_H_DEFINED_glGetFogFuncSGIS + typedef void (APIENTRYP GLEEPFNGLGETFOGFUNCSGISPROC) (GLfloat * points); + GLEE_EXTERN GLEEPFNGLGETFOGFUNCSGISPROC GLeeFuncPtr_glGetFogFuncSGIS; + #define glGetFogFuncSGIS GLeeFuncPtr_glGetFogFuncSGIS +#endif +#endif + +/* GL_SGIX_fog_offset */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#define __GLEE_GL_SGIX_fog_offset 1 +/* Constants */ +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +/* GL_HP_image_transform */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#define __GLEE_GL_HP_image_transform 1 +/* Constants */ +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#ifndef GLEE_H_DEFINED_glImageTransformParameteriHP +#define GLEE_H_DEFINED_glImageTransformParameteriHP + typedef void (APIENTRYP GLEEPFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLIMAGETRANSFORMPARAMETERIHPPROC GLeeFuncPtr_glImageTransformParameteriHP; + #define glImageTransformParameteriHP GLeeFuncPtr_glImageTransformParameteriHP +#endif +#ifndef GLEE_H_DEFINED_glImageTransformParameterfHP +#define GLEE_H_DEFINED_glImageTransformParameterfHP + typedef void (APIENTRYP GLEEPFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLIMAGETRANSFORMPARAMETERFHPPROC GLeeFuncPtr_glImageTransformParameterfHP; + #define glImageTransformParameterfHP GLeeFuncPtr_glImageTransformParameterfHP +#endif +#ifndef GLEE_H_DEFINED_glImageTransformParameterivHP +#define GLEE_H_DEFINED_glImageTransformParameterivHP + typedef void (APIENTRYP GLEEPFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLIMAGETRANSFORMPARAMETERIVHPPROC GLeeFuncPtr_glImageTransformParameterivHP; + #define glImageTransformParameterivHP GLeeFuncPtr_glImageTransformParameterivHP +#endif +#ifndef GLEE_H_DEFINED_glImageTransformParameterfvHP +#define GLEE_H_DEFINED_glImageTransformParameterfvHP + typedef void (APIENTRYP GLEEPFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLIMAGETRANSFORMPARAMETERFVHPPROC GLeeFuncPtr_glImageTransformParameterfvHP; + #define glImageTransformParameterfvHP GLeeFuncPtr_glImageTransformParameterfvHP +#endif +#ifndef GLEE_H_DEFINED_glGetImageTransformParameterivHP +#define GLEE_H_DEFINED_glGetImageTransformParameterivHP + typedef void (APIENTRYP GLEEPFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC GLeeFuncPtr_glGetImageTransformParameterivHP; + #define glGetImageTransformParameterivHP GLeeFuncPtr_glGetImageTransformParameterivHP +#endif +#ifndef GLEE_H_DEFINED_glGetImageTransformParameterfvHP +#define GLEE_H_DEFINED_glGetImageTransformParameterfvHP + typedef void (APIENTRYP GLEEPFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC GLeeFuncPtr_glGetImageTransformParameterfvHP; + #define glGetImageTransformParameterfvHP GLeeFuncPtr_glGetImageTransformParameterfvHP +#endif +#endif + +/* GL_HP_convolution_border_modes */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#define __GLEE_GL_HP_convolution_border_modes 1 +/* Constants */ +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +/* GL_INGR_palette_buffer */ + +#ifndef GL_INGR_palette_buffer +#define GL_INGR_palette_buffer 1 +#define __GLEE_GL_INGR_palette_buffer 1 +/* Constants */ +#endif + +/* GL_SGIX_texture_add_env */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#define __GLEE_GL_SGIX_texture_add_env 1 +/* Constants */ +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +/* GL_EXT_color_subtable */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#define __GLEE_GL_EXT_color_subtable 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glColorSubTableEXT +#define GLEE_H_DEFINED_glColorSubTableEXT + typedef void (APIENTRYP GLEEPFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLCOLORSUBTABLEEXTPROC GLeeFuncPtr_glColorSubTableEXT; + #define glColorSubTableEXT GLeeFuncPtr_glColorSubTableEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyColorSubTableEXT +#define GLEE_H_DEFINED_glCopyColorSubTableEXT + typedef void (APIENTRYP GLEEPFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYCOLORSUBTABLEEXTPROC GLeeFuncPtr_glCopyColorSubTableEXT; + #define glCopyColorSubTableEXT GLeeFuncPtr_glCopyColorSubTableEXT +#endif +#endif + +/* GL_PGI_vertex_hints */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#define __GLEE_GL_PGI_vertex_hints 1 +/* Constants */ +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +/* GL_PGI_misc_hints */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#define __GLEE_GL_PGI_misc_hints 1 +/* Constants */ +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#ifndef GLEE_H_DEFINED_glHintPGI +#define GLEE_H_DEFINED_glHintPGI + typedef void (APIENTRYP GLEEPFNGLHINTPGIPROC) (GLenum target, GLint mode); + GLEE_EXTERN GLEEPFNGLHINTPGIPROC GLeeFuncPtr_glHintPGI; + #define glHintPGI GLeeFuncPtr_glHintPGI +#endif +#endif + +/* GL_EXT_paletted_texture */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#define __GLEE_GL_EXT_paletted_texture 1 +/* Constants */ +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#ifndef GLEE_H_DEFINED_glColorTableEXT +#define GLEE_H_DEFINED_glColorTableEXT + typedef void (APIENTRYP GLEEPFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid * table); + GLEE_EXTERN GLEEPFNGLCOLORTABLEEXTPROC GLeeFuncPtr_glColorTableEXT; + #define glColorTableEXT GLeeFuncPtr_glColorTableEXT +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableEXT +#define GLEE_H_DEFINED_glGetColorTableEXT + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid * data); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEEXTPROC GLeeFuncPtr_glGetColorTableEXT; + #define glGetColorTableEXT GLeeFuncPtr_glGetColorTableEXT +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableParameterivEXT +#define GLEE_H_DEFINED_glGetColorTableParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEPARAMETERIVEXTPROC GLeeFuncPtr_glGetColorTableParameterivEXT; + #define glGetColorTableParameterivEXT GLeeFuncPtr_glGetColorTableParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetColorTableParameterfvEXT +#define GLEE_H_DEFINED_glGetColorTableParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCOLORTABLEPARAMETERFVEXTPROC GLeeFuncPtr_glGetColorTableParameterfvEXT; + #define glGetColorTableParameterfvEXT GLeeFuncPtr_glGetColorTableParameterfvEXT +#endif +#endif + +/* GL_EXT_clip_volume_hint */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#define __GLEE_GL_EXT_clip_volume_hint 1 +/* Constants */ +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +/* GL_SGIX_list_priority */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#define __GLEE_GL_SGIX_list_priority 1 +/* Constants */ +#define GL_LIST_PRIORITY_SGIX 0x8182 +#ifndef GLEE_H_DEFINED_glGetListParameterfvSGIX +#define GLEE_H_DEFINED_glGetListParameterfvSGIX + typedef void (APIENTRYP GLEEPFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETLISTPARAMETERFVSGIXPROC GLeeFuncPtr_glGetListParameterfvSGIX; + #define glGetListParameterfvSGIX GLeeFuncPtr_glGetListParameterfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glGetListParameterivSGIX +#define GLEE_H_DEFINED_glGetListParameterivSGIX + typedef void (APIENTRYP GLEEPFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETLISTPARAMETERIVSGIXPROC GLeeFuncPtr_glGetListParameterivSGIX; + #define glGetListParameterivSGIX GLeeFuncPtr_glGetListParameterivSGIX +#endif +#ifndef GLEE_H_DEFINED_glListParameterfSGIX +#define GLEE_H_DEFINED_glListParameterfSGIX + typedef void (APIENTRYP GLEEPFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLLISTPARAMETERFSGIXPROC GLeeFuncPtr_glListParameterfSGIX; + #define glListParameterfSGIX GLeeFuncPtr_glListParameterfSGIX +#endif +#ifndef GLEE_H_DEFINED_glListParameterfvSGIX +#define GLEE_H_DEFINED_glListParameterfvSGIX + typedef void (APIENTRYP GLEEPFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLLISTPARAMETERFVSGIXPROC GLeeFuncPtr_glListParameterfvSGIX; + #define glListParameterfvSGIX GLeeFuncPtr_glListParameterfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glListParameteriSGIX +#define GLEE_H_DEFINED_glListParameteriSGIX + typedef void (APIENTRYP GLEEPFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLLISTPARAMETERISGIXPROC GLeeFuncPtr_glListParameteriSGIX; + #define glListParameteriSGIX GLeeFuncPtr_glListParameteriSGIX +#endif +#ifndef GLEE_H_DEFINED_glListParameterivSGIX +#define GLEE_H_DEFINED_glListParameterivSGIX + typedef void (APIENTRYP GLEEPFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLLISTPARAMETERIVSGIXPROC GLeeFuncPtr_glListParameterivSGIX; + #define glListParameterivSGIX GLeeFuncPtr_glListParameterivSGIX +#endif +#endif + +/* GL_SGIX_ir_instrument1 */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#define __GLEE_GL_SGIX_ir_instrument1 1 +/* Constants */ +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +/* GL_SGIX_calligraphic_fragment */ + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#define __GLEE_GL_SGIX_calligraphic_fragment 1 +/* Constants */ +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +/* GL_SGIX_texture_lod_bias */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#define __GLEE_GL_SGIX_texture_lod_bias 1 +/* Constants */ +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +/* GL_SGIX_shadow_ambient */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#define __GLEE_GL_SGIX_shadow_ambient 1 +/* Constants */ +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +/* GL_EXT_index_texture */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#define __GLEE_GL_EXT_index_texture 1 +/* Constants */ +#endif + +/* GL_EXT_index_material */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#define __GLEE_GL_EXT_index_material 1 +/* Constants */ +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#ifndef GLEE_H_DEFINED_glIndexMaterialEXT +#define GLEE_H_DEFINED_glIndexMaterialEXT + typedef void (APIENTRYP GLEEPFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); + GLEE_EXTERN GLEEPFNGLINDEXMATERIALEXTPROC GLeeFuncPtr_glIndexMaterialEXT; + #define glIndexMaterialEXT GLeeFuncPtr_glIndexMaterialEXT +#endif +#endif + +/* GL_EXT_index_func */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#define __GLEE_GL_EXT_index_func 1 +/* Constants */ +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#ifndef GLEE_H_DEFINED_glIndexFuncEXT +#define GLEE_H_DEFINED_glIndexFuncEXT + typedef void (APIENTRYP GLEEPFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); + GLEE_EXTERN GLEEPFNGLINDEXFUNCEXTPROC GLeeFuncPtr_glIndexFuncEXT; + #define glIndexFuncEXT GLeeFuncPtr_glIndexFuncEXT +#endif +#endif + +/* GL_EXT_index_array_formats */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#define __GLEE_GL_EXT_index_array_formats 1 +/* Constants */ +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +/* GL_EXT_compiled_vertex_array */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#define __GLEE_GL_EXT_compiled_vertex_array 1 +/* Constants */ +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#ifndef GLEE_H_DEFINED_glLockArraysEXT +#define GLEE_H_DEFINED_glLockArraysEXT + typedef void (APIENTRYP GLEEPFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); + GLEE_EXTERN GLEEPFNGLLOCKARRAYSEXTPROC GLeeFuncPtr_glLockArraysEXT; + #define glLockArraysEXT GLeeFuncPtr_glLockArraysEXT +#endif +#ifndef GLEE_H_DEFINED_glUnlockArraysEXT +#define GLEE_H_DEFINED_glUnlockArraysEXT + typedef void (APIENTRYP GLEEPFNGLUNLOCKARRAYSEXTPROC) (); + GLEE_EXTERN GLEEPFNGLUNLOCKARRAYSEXTPROC GLeeFuncPtr_glUnlockArraysEXT; + #define glUnlockArraysEXT GLeeFuncPtr_glUnlockArraysEXT +#endif +#endif + +/* GL_EXT_cull_vertex */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#define __GLEE_GL_EXT_cull_vertex 1 +/* Constants */ +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#ifndef GLEE_H_DEFINED_glCullParameterdvEXT +#define GLEE_H_DEFINED_glCullParameterdvEXT + typedef void (APIENTRYP GLEEPFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble * params); + GLEE_EXTERN GLEEPFNGLCULLPARAMETERDVEXTPROC GLeeFuncPtr_glCullParameterdvEXT; + #define glCullParameterdvEXT GLeeFuncPtr_glCullParameterdvEXT +#endif +#ifndef GLEE_H_DEFINED_glCullParameterfvEXT +#define GLEE_H_DEFINED_glCullParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLCULLPARAMETERFVEXTPROC GLeeFuncPtr_glCullParameterfvEXT; + #define glCullParameterfvEXT GLeeFuncPtr_glCullParameterfvEXT +#endif +#endif + +/* GL_SGIX_ycrcb */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#define __GLEE_GL_SGIX_ycrcb 1 +/* Constants */ +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +/* GL_SGIX_fragment_lighting */ + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#define __GLEE_GL_SGIX_fragment_lighting 1 +/* Constants */ +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#ifndef GLEE_H_DEFINED_glFragmentColorMaterialSGIX +#define GLEE_H_DEFINED_glFragmentColorMaterialSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); + GLEE_EXTERN GLEEPFNGLFRAGMENTCOLORMATERIALSGIXPROC GLeeFuncPtr_glFragmentColorMaterialSGIX; + #define glFragmentColorMaterialSGIX GLeeFuncPtr_glFragmentColorMaterialSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightfSGIX +#define GLEE_H_DEFINED_glFragmentLightfSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTFSGIXPROC GLeeFuncPtr_glFragmentLightfSGIX; + #define glFragmentLightfSGIX GLeeFuncPtr_glFragmentLightfSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightfvSGIX +#define GLEE_H_DEFINED_glFragmentLightfvSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTFVSGIXPROC GLeeFuncPtr_glFragmentLightfvSGIX; + #define glFragmentLightfvSGIX GLeeFuncPtr_glFragmentLightfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightiSGIX +#define GLEE_H_DEFINED_glFragmentLightiSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTISGIXPROC GLeeFuncPtr_glFragmentLightiSGIX; + #define glFragmentLightiSGIX GLeeFuncPtr_glFragmentLightiSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightivSGIX +#define GLEE_H_DEFINED_glFragmentLightivSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTIVSGIXPROC GLeeFuncPtr_glFragmentLightivSGIX; + #define glFragmentLightivSGIX GLeeFuncPtr_glFragmentLightivSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightModelfSGIX +#define GLEE_H_DEFINED_glFragmentLightModelfSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELFSGIXPROC GLeeFuncPtr_glFragmentLightModelfSGIX; + #define glFragmentLightModelfSGIX GLeeFuncPtr_glFragmentLightModelfSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightModelfvSGIX +#define GLEE_H_DEFINED_glFragmentLightModelfvSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELFVSGIXPROC GLeeFuncPtr_glFragmentLightModelfvSGIX; + #define glFragmentLightModelfvSGIX GLeeFuncPtr_glFragmentLightModelfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightModeliSGIX +#define GLEE_H_DEFINED_glFragmentLightModeliSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELISGIXPROC GLeeFuncPtr_glFragmentLightModeliSGIX; + #define glFragmentLightModeliSGIX GLeeFuncPtr_glFragmentLightModeliSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightModelivSGIX +#define GLEE_H_DEFINED_glFragmentLightModelivSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELIVSGIXPROC GLeeFuncPtr_glFragmentLightModelivSGIX; + #define glFragmentLightModelivSGIX GLeeFuncPtr_glFragmentLightModelivSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialfSGIX +#define GLEE_H_DEFINED_glFragmentMaterialfSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALFSGIXPROC GLeeFuncPtr_glFragmentMaterialfSGIX; + #define glFragmentMaterialfSGIX GLeeFuncPtr_glFragmentMaterialfSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialfvSGIX +#define GLEE_H_DEFINED_glFragmentMaterialfvSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALFVSGIXPROC GLeeFuncPtr_glFragmentMaterialfvSGIX; + #define glFragmentMaterialfvSGIX GLeeFuncPtr_glFragmentMaterialfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialiSGIX +#define GLEE_H_DEFINED_glFragmentMaterialiSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALISGIXPROC GLeeFuncPtr_glFragmentMaterialiSGIX; + #define glFragmentMaterialiSGIX GLeeFuncPtr_glFragmentMaterialiSGIX +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialivSGIX +#define GLEE_H_DEFINED_glFragmentMaterialivSGIX + typedef void (APIENTRYP GLEEPFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALIVSGIXPROC GLeeFuncPtr_glFragmentMaterialivSGIX; + #define glFragmentMaterialivSGIX GLeeFuncPtr_glFragmentMaterialivSGIX +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentLightfvSGIX +#define GLEE_H_DEFINED_glGetFragmentLightfvSGIX + typedef void (APIENTRYP GLEEPFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTLIGHTFVSGIXPROC GLeeFuncPtr_glGetFragmentLightfvSGIX; + #define glGetFragmentLightfvSGIX GLeeFuncPtr_glGetFragmentLightfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentLightivSGIX +#define GLEE_H_DEFINED_glGetFragmentLightivSGIX + typedef void (APIENTRYP GLEEPFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTLIGHTIVSGIXPROC GLeeFuncPtr_glGetFragmentLightivSGIX; + #define glGetFragmentLightivSGIX GLeeFuncPtr_glGetFragmentLightivSGIX +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentMaterialfvSGIX +#define GLEE_H_DEFINED_glGetFragmentMaterialfvSGIX + typedef void (APIENTRYP GLEEPFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTMATERIALFVSGIXPROC GLeeFuncPtr_glGetFragmentMaterialfvSGIX; + #define glGetFragmentMaterialfvSGIX GLeeFuncPtr_glGetFragmentMaterialfvSGIX +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentMaterialivSGIX +#define GLEE_H_DEFINED_glGetFragmentMaterialivSGIX + typedef void (APIENTRYP GLEEPFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTMATERIALIVSGIXPROC GLeeFuncPtr_glGetFragmentMaterialivSGIX; + #define glGetFragmentMaterialivSGIX GLeeFuncPtr_glGetFragmentMaterialivSGIX +#endif +#ifndef GLEE_H_DEFINED_glLightEnviSGIX +#define GLEE_H_DEFINED_glLightEnviSGIX + typedef void (APIENTRYP GLEEPFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLLIGHTENVISGIXPROC GLeeFuncPtr_glLightEnviSGIX; + #define glLightEnviSGIX GLeeFuncPtr_glLightEnviSGIX +#endif +#endif + +/* GL_IBM_rasterpos_clip */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#define __GLEE_GL_IBM_rasterpos_clip 1 +/* Constants */ +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +/* GL_HP_texture_lighting */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#define __GLEE_GL_HP_texture_lighting 1 +/* Constants */ +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +/* GL_EXT_draw_range_elements */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#define __GLEE_GL_EXT_draw_range_elements 1 +/* Constants */ +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#ifndef GLEE_H_DEFINED_glDrawRangeElementsEXT +#define GLEE_H_DEFINED_glDrawRangeElementsEXT + typedef void (APIENTRYP GLEEPFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices); + GLEE_EXTERN GLEEPFNGLDRAWRANGEELEMENTSEXTPROC GLeeFuncPtr_glDrawRangeElementsEXT; + #define glDrawRangeElementsEXT GLeeFuncPtr_glDrawRangeElementsEXT +#endif +#endif + +/* GL_WIN_phong_shading */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#define __GLEE_GL_WIN_phong_shading 1 +/* Constants */ +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +/* GL_WIN_specular_fog */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#define __GLEE_GL_WIN_specular_fog 1 +/* Constants */ +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +/* GL_EXT_light_texture */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#define __GLEE_GL_EXT_light_texture 1 +/* Constants */ +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#ifndef GLEE_H_DEFINED_glApplyTextureEXT +#define GLEE_H_DEFINED_glApplyTextureEXT + typedef void (APIENTRYP GLEEPFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLAPPLYTEXTUREEXTPROC GLeeFuncPtr_glApplyTextureEXT; + #define glApplyTextureEXT GLeeFuncPtr_glApplyTextureEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureLightEXT +#define GLEE_H_DEFINED_glTextureLightEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURELIGHTEXTPROC) (GLenum pname); + GLEE_EXTERN GLEEPFNGLTEXTURELIGHTEXTPROC GLeeFuncPtr_glTextureLightEXT; + #define glTextureLightEXT GLeeFuncPtr_glTextureLightEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureMaterialEXT +#define GLEE_H_DEFINED_glTextureMaterialEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); + GLEE_EXTERN GLEEPFNGLTEXTUREMATERIALEXTPROC GLeeFuncPtr_glTextureMaterialEXT; + #define glTextureMaterialEXT GLeeFuncPtr_glTextureMaterialEXT +#endif +#endif + +/* GL_SGIX_blend_alpha_minmax */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#define __GLEE_GL_SGIX_blend_alpha_minmax 1 +/* Constants */ +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +/* GL_SGIX_impact_pixel_texture */ + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_SGIX_impact_pixel_texture 1 +#define __GLEE_GL_SGIX_impact_pixel_texture 1 +/* Constants */ +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +/* GL_EXT_bgra */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#define __GLEE_GL_EXT_bgra 1 +/* Constants */ +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_SGIX_async */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#define __GLEE_GL_SGIX_async 1 +/* Constants */ +#define GL_ASYNC_MARKER_SGIX 0x8329 +#ifndef GLEE_H_DEFINED_glAsyncMarkerSGIX +#define GLEE_H_DEFINED_glAsyncMarkerSGIX + typedef void (APIENTRYP GLEEPFNGLASYNCMARKERSGIXPROC) (GLuint marker); + GLEE_EXTERN GLEEPFNGLASYNCMARKERSGIXPROC GLeeFuncPtr_glAsyncMarkerSGIX; + #define glAsyncMarkerSGIX GLeeFuncPtr_glAsyncMarkerSGIX +#endif +#ifndef GLEE_H_DEFINED_glFinishAsyncSGIX +#define GLEE_H_DEFINED_glFinishAsyncSGIX + typedef GLint (APIENTRYP GLEEPFNGLFINISHASYNCSGIXPROC) (GLuint * markerp); + GLEE_EXTERN GLEEPFNGLFINISHASYNCSGIXPROC GLeeFuncPtr_glFinishAsyncSGIX; + #define glFinishAsyncSGIX GLeeFuncPtr_glFinishAsyncSGIX +#endif +#ifndef GLEE_H_DEFINED_glPollAsyncSGIX +#define GLEE_H_DEFINED_glPollAsyncSGIX + typedef GLint (APIENTRYP GLEEPFNGLPOLLASYNCSGIXPROC) (GLuint * markerp); + GLEE_EXTERN GLEEPFNGLPOLLASYNCSGIXPROC GLeeFuncPtr_glPollAsyncSGIX; + #define glPollAsyncSGIX GLeeFuncPtr_glPollAsyncSGIX +#endif +#ifndef GLEE_H_DEFINED_glGenAsyncMarkersSGIX +#define GLEE_H_DEFINED_glGenAsyncMarkersSGIX + typedef GLuint (APIENTRYP GLEEPFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); + GLEE_EXTERN GLEEPFNGLGENASYNCMARKERSSGIXPROC GLeeFuncPtr_glGenAsyncMarkersSGIX; + #define glGenAsyncMarkersSGIX GLeeFuncPtr_glGenAsyncMarkersSGIX +#endif +#ifndef GLEE_H_DEFINED_glDeleteAsyncMarkersSGIX +#define GLEE_H_DEFINED_glDeleteAsyncMarkersSGIX + typedef void (APIENTRYP GLEEPFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); + GLEE_EXTERN GLEEPFNGLDELETEASYNCMARKERSSGIXPROC GLeeFuncPtr_glDeleteAsyncMarkersSGIX; + #define glDeleteAsyncMarkersSGIX GLeeFuncPtr_glDeleteAsyncMarkersSGIX +#endif +#ifndef GLEE_H_DEFINED_glIsAsyncMarkerSGIX +#define GLEE_H_DEFINED_glIsAsyncMarkerSGIX + typedef GLboolean (APIENTRYP GLEEPFNGLISASYNCMARKERSGIXPROC) (GLuint marker); + GLEE_EXTERN GLEEPFNGLISASYNCMARKERSGIXPROC GLeeFuncPtr_glIsAsyncMarkerSGIX; + #define glIsAsyncMarkerSGIX GLeeFuncPtr_glIsAsyncMarkerSGIX +#endif +#endif + +/* GL_SGIX_async_pixel */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#define __GLEE_GL_SGIX_async_pixel 1 +/* Constants */ +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +/* GL_SGIX_async_histogram */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#define __GLEE_GL_SGIX_async_histogram 1 +/* Constants */ +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +/* GL_INTEL_texture_scissor */ + +#ifndef GL_INTEL_texture_scissor +#define GL_INTEL_texture_scissor 1 +#define __GLEE_GL_INTEL_texture_scissor 1 +/* Constants */ +#endif + +/* GL_INTEL_parallel_arrays */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#define __GLEE_GL_INTEL_parallel_arrays 1 +/* Constants */ +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#ifndef GLEE_H_DEFINED_glVertexPointervINTEL +#define GLEE_H_DEFINED_glVertexPointervINTEL + typedef void (APIENTRYP GLEEPFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXPOINTERVINTELPROC GLeeFuncPtr_glVertexPointervINTEL; + #define glVertexPointervINTEL GLeeFuncPtr_glVertexPointervINTEL +#endif +#ifndef GLEE_H_DEFINED_glNormalPointervINTEL +#define GLEE_H_DEFINED_glNormalPointervINTEL + typedef void (APIENTRYP GLEEPFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLNORMALPOINTERVINTELPROC GLeeFuncPtr_glNormalPointervINTEL; + #define glNormalPointervINTEL GLeeFuncPtr_glNormalPointervINTEL +#endif +#ifndef GLEE_H_DEFINED_glColorPointervINTEL +#define GLEE_H_DEFINED_glColorPointervINTEL + typedef void (APIENTRYP GLEEPFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLCOLORPOINTERVINTELPROC GLeeFuncPtr_glColorPointervINTEL; + #define glColorPointervINTEL GLeeFuncPtr_glColorPointervINTEL +#endif +#ifndef GLEE_H_DEFINED_glTexCoordPointervINTEL +#define GLEE_H_DEFINED_glTexCoordPointervINTEL + typedef void (APIENTRYP GLEEPFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLTEXCOORDPOINTERVINTELPROC GLeeFuncPtr_glTexCoordPointervINTEL; + #define glTexCoordPointervINTEL GLeeFuncPtr_glTexCoordPointervINTEL +#endif +#endif + +/* GL_HP_occlusion_test */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#define __GLEE_GL_HP_occlusion_test 1 +/* Constants */ +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +/* GL_EXT_pixel_transform */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#define __GLEE_GL_EXT_pixel_transform 1 +/* Constants */ +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#ifndef GLEE_H_DEFINED_glPixelTransformParameteriEXT +#define GLEE_H_DEFINED_glPixelTransformParameteriEXT + typedef void (APIENTRYP GLEEPFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLPIXELTRANSFORMPARAMETERIEXTPROC GLeeFuncPtr_glPixelTransformParameteriEXT; + #define glPixelTransformParameteriEXT GLeeFuncPtr_glPixelTransformParameteriEXT +#endif +#ifndef GLEE_H_DEFINED_glPixelTransformParameterfEXT +#define GLEE_H_DEFINED_glPixelTransformParameterfEXT + typedef void (APIENTRYP GLEEPFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLPIXELTRANSFORMPARAMETERFEXTPROC GLeeFuncPtr_glPixelTransformParameterfEXT; + #define glPixelTransformParameterfEXT GLeeFuncPtr_glPixelTransformParameterfEXT +#endif +#ifndef GLEE_H_DEFINED_glPixelTransformParameterivEXT +#define GLEE_H_DEFINED_glPixelTransformParameterivEXT + typedef void (APIENTRYP GLEEPFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLPIXELTRANSFORMPARAMETERIVEXTPROC GLeeFuncPtr_glPixelTransformParameterivEXT; + #define glPixelTransformParameterivEXT GLeeFuncPtr_glPixelTransformParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glPixelTransformParameterfvEXT +#define GLEE_H_DEFINED_glPixelTransformParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPIXELTRANSFORMPARAMETERFVEXTPROC GLeeFuncPtr_glPixelTransformParameterfvEXT; + #define glPixelTransformParameterfvEXT GLeeFuncPtr_glPixelTransformParameterfvEXT +#endif +#endif + +/* GL_EXT_pixel_transform_color_table */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#define __GLEE_GL_EXT_pixel_transform_color_table 1 +/* Constants */ +#endif + +/* GL_EXT_shared_texture_palette */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#define __GLEE_GL_EXT_shared_texture_palette 1 +/* Constants */ +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +/* GL_EXT_separate_specular_color */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#define __GLEE_GL_EXT_separate_specular_color 1 +/* Constants */ +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +/* GL_EXT_secondary_color */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#define __GLEE_GL_EXT_secondary_color 1 +/* Constants */ +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#ifndef GLEE_H_DEFINED_glSecondaryColor3bEXT +#define GLEE_H_DEFINED_glSecondaryColor3bEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3BEXTPROC GLeeFuncPtr_glSecondaryColor3bEXT; + #define glSecondaryColor3bEXT GLeeFuncPtr_glSecondaryColor3bEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3bvEXT +#define GLEE_H_DEFINED_glSecondaryColor3bvEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3BVEXTPROC GLeeFuncPtr_glSecondaryColor3bvEXT; + #define glSecondaryColor3bvEXT GLeeFuncPtr_glSecondaryColor3bvEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3dEXT +#define GLEE_H_DEFINED_glSecondaryColor3dEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3DEXTPROC GLeeFuncPtr_glSecondaryColor3dEXT; + #define glSecondaryColor3dEXT GLeeFuncPtr_glSecondaryColor3dEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3dvEXT +#define GLEE_H_DEFINED_glSecondaryColor3dvEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3DVEXTPROC GLeeFuncPtr_glSecondaryColor3dvEXT; + #define glSecondaryColor3dvEXT GLeeFuncPtr_glSecondaryColor3dvEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3fEXT +#define GLEE_H_DEFINED_glSecondaryColor3fEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3FEXTPROC GLeeFuncPtr_glSecondaryColor3fEXT; + #define glSecondaryColor3fEXT GLeeFuncPtr_glSecondaryColor3fEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3fvEXT +#define GLEE_H_DEFINED_glSecondaryColor3fvEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3FVEXTPROC GLeeFuncPtr_glSecondaryColor3fvEXT; + #define glSecondaryColor3fvEXT GLeeFuncPtr_glSecondaryColor3fvEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3iEXT +#define GLEE_H_DEFINED_glSecondaryColor3iEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3IEXTPROC GLeeFuncPtr_glSecondaryColor3iEXT; + #define glSecondaryColor3iEXT GLeeFuncPtr_glSecondaryColor3iEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3ivEXT +#define GLEE_H_DEFINED_glSecondaryColor3ivEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3IVEXTPROC GLeeFuncPtr_glSecondaryColor3ivEXT; + #define glSecondaryColor3ivEXT GLeeFuncPtr_glSecondaryColor3ivEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3sEXT +#define GLEE_H_DEFINED_glSecondaryColor3sEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3SEXTPROC GLeeFuncPtr_glSecondaryColor3sEXT; + #define glSecondaryColor3sEXT GLeeFuncPtr_glSecondaryColor3sEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3svEXT +#define GLEE_H_DEFINED_glSecondaryColor3svEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3SVEXTPROC GLeeFuncPtr_glSecondaryColor3svEXT; + #define glSecondaryColor3svEXT GLeeFuncPtr_glSecondaryColor3svEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3ubEXT +#define GLEE_H_DEFINED_glSecondaryColor3ubEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UBEXTPROC GLeeFuncPtr_glSecondaryColor3ubEXT; + #define glSecondaryColor3ubEXT GLeeFuncPtr_glSecondaryColor3ubEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3ubvEXT +#define GLEE_H_DEFINED_glSecondaryColor3ubvEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UBVEXTPROC GLeeFuncPtr_glSecondaryColor3ubvEXT; + #define glSecondaryColor3ubvEXT GLeeFuncPtr_glSecondaryColor3ubvEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3uiEXT +#define GLEE_H_DEFINED_glSecondaryColor3uiEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UIEXTPROC GLeeFuncPtr_glSecondaryColor3uiEXT; + #define glSecondaryColor3uiEXT GLeeFuncPtr_glSecondaryColor3uiEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3uivEXT +#define GLEE_H_DEFINED_glSecondaryColor3uivEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3UIVEXTPROC GLeeFuncPtr_glSecondaryColor3uivEXT; + #define glSecondaryColor3uivEXT GLeeFuncPtr_glSecondaryColor3uivEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3usEXT +#define GLEE_H_DEFINED_glSecondaryColor3usEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3USEXTPROC GLeeFuncPtr_glSecondaryColor3usEXT; + #define glSecondaryColor3usEXT GLeeFuncPtr_glSecondaryColor3usEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3usvEXT +#define GLEE_H_DEFINED_glSecondaryColor3usvEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3USVEXTPROC GLeeFuncPtr_glSecondaryColor3usvEXT; + #define glSecondaryColor3usvEXT GLeeFuncPtr_glSecondaryColor3usvEXT +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColorPointerEXT +#define GLEE_H_DEFINED_glSecondaryColorPointerEXT + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLORPOINTEREXTPROC GLeeFuncPtr_glSecondaryColorPointerEXT; + #define glSecondaryColorPointerEXT GLeeFuncPtr_glSecondaryColorPointerEXT +#endif +#endif + +/* GL_EXT_texture_perturb_normal */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#define __GLEE_GL_EXT_texture_perturb_normal 1 +/* Constants */ +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#ifndef GLEE_H_DEFINED_glTextureNormalEXT +#define GLEE_H_DEFINED_glTextureNormalEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURENORMALEXTPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLTEXTURENORMALEXTPROC GLeeFuncPtr_glTextureNormalEXT; + #define glTextureNormalEXT GLeeFuncPtr_glTextureNormalEXT +#endif +#endif + +/* GL_EXT_multi_draw_arrays */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#define __GLEE_GL_EXT_multi_draw_arrays 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glMultiDrawArraysEXT +#define GLEE_H_DEFINED_glMultiDrawArraysEXT + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLMULTIDRAWARRAYSEXTPROC GLeeFuncPtr_glMultiDrawArraysEXT; + #define glMultiDrawArraysEXT GLeeFuncPtr_glMultiDrawArraysEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiDrawElementsEXT +#define GLEE_H_DEFINED_glMultiDrawElementsEXT + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLMULTIDRAWELEMENTSEXTPROC GLeeFuncPtr_glMultiDrawElementsEXT; + #define glMultiDrawElementsEXT GLeeFuncPtr_glMultiDrawElementsEXT +#endif +#endif + +/* GL_EXT_fog_coord */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#define __GLEE_GL_EXT_fog_coord 1 +/* Constants */ +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#ifndef GLEE_H_DEFINED_glFogCoordfEXT +#define GLEE_H_DEFINED_glFogCoordfEXT + typedef void (APIENTRYP GLEEPFNGLFOGCOORDFEXTPROC) (GLfloat coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDFEXTPROC GLeeFuncPtr_glFogCoordfEXT; + #define glFogCoordfEXT GLeeFuncPtr_glFogCoordfEXT +#endif +#ifndef GLEE_H_DEFINED_glFogCoordfvEXT +#define GLEE_H_DEFINED_glFogCoordfvEXT + typedef void (APIENTRYP GLEEPFNGLFOGCOORDFVEXTPROC) (const GLfloat * coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDFVEXTPROC GLeeFuncPtr_glFogCoordfvEXT; + #define glFogCoordfvEXT GLeeFuncPtr_glFogCoordfvEXT +#endif +#ifndef GLEE_H_DEFINED_glFogCoorddEXT +#define GLEE_H_DEFINED_glFogCoorddEXT + typedef void (APIENTRYP GLEEPFNGLFOGCOORDDEXTPROC) (GLdouble coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDDEXTPROC GLeeFuncPtr_glFogCoorddEXT; + #define glFogCoorddEXT GLeeFuncPtr_glFogCoorddEXT +#endif +#ifndef GLEE_H_DEFINED_glFogCoorddvEXT +#define GLEE_H_DEFINED_glFogCoorddvEXT + typedef void (APIENTRYP GLEEPFNGLFOGCOORDDVEXTPROC) (const GLdouble * coord); + GLEE_EXTERN GLEEPFNGLFOGCOORDDVEXTPROC GLeeFuncPtr_glFogCoorddvEXT; + #define glFogCoorddvEXT GLeeFuncPtr_glFogCoorddvEXT +#endif +#ifndef GLEE_H_DEFINED_glFogCoordPointerEXT +#define GLEE_H_DEFINED_glFogCoordPointerEXT + typedef void (APIENTRYP GLEEPFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLFOGCOORDPOINTEREXTPROC GLeeFuncPtr_glFogCoordPointerEXT; + #define glFogCoordPointerEXT GLeeFuncPtr_glFogCoordPointerEXT +#endif +#endif + +/* GL_REND_screen_coordinates */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#define __GLEE_GL_REND_screen_coordinates 1 +/* Constants */ +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +/* GL_EXT_coordinate_frame */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#define __GLEE_GL_EXT_coordinate_frame 1 +/* Constants */ +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#ifndef GLEE_H_DEFINED_glTangent3bEXT +#define GLEE_H_DEFINED_glTangent3bEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); + GLEE_EXTERN GLEEPFNGLTANGENT3BEXTPROC GLeeFuncPtr_glTangent3bEXT; + #define glTangent3bEXT GLeeFuncPtr_glTangent3bEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3bvEXT +#define GLEE_H_DEFINED_glTangent3bvEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3BVEXTPROC) (const GLbyte * v); + GLEE_EXTERN GLEEPFNGLTANGENT3BVEXTPROC GLeeFuncPtr_glTangent3bvEXT; + #define glTangent3bvEXT GLeeFuncPtr_glTangent3bvEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3dEXT +#define GLEE_H_DEFINED_glTangent3dEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); + GLEE_EXTERN GLEEPFNGLTANGENT3DEXTPROC GLeeFuncPtr_glTangent3dEXT; + #define glTangent3dEXT GLeeFuncPtr_glTangent3dEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3dvEXT +#define GLEE_H_DEFINED_glTangent3dvEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3DVEXTPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLTANGENT3DVEXTPROC GLeeFuncPtr_glTangent3dvEXT; + #define glTangent3dvEXT GLeeFuncPtr_glTangent3dvEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3fEXT +#define GLEE_H_DEFINED_glTangent3fEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); + GLEE_EXTERN GLEEPFNGLTANGENT3FEXTPROC GLeeFuncPtr_glTangent3fEXT; + #define glTangent3fEXT GLeeFuncPtr_glTangent3fEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3fvEXT +#define GLEE_H_DEFINED_glTangent3fvEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3FVEXTPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTANGENT3FVEXTPROC GLeeFuncPtr_glTangent3fvEXT; + #define glTangent3fvEXT GLeeFuncPtr_glTangent3fvEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3iEXT +#define GLEE_H_DEFINED_glTangent3iEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); + GLEE_EXTERN GLEEPFNGLTANGENT3IEXTPROC GLeeFuncPtr_glTangent3iEXT; + #define glTangent3iEXT GLeeFuncPtr_glTangent3iEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3ivEXT +#define GLEE_H_DEFINED_glTangent3ivEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3IVEXTPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLTANGENT3IVEXTPROC GLeeFuncPtr_glTangent3ivEXT; + #define glTangent3ivEXT GLeeFuncPtr_glTangent3ivEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3sEXT +#define GLEE_H_DEFINED_glTangent3sEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); + GLEE_EXTERN GLEEPFNGLTANGENT3SEXTPROC GLeeFuncPtr_glTangent3sEXT; + #define glTangent3sEXT GLeeFuncPtr_glTangent3sEXT +#endif +#ifndef GLEE_H_DEFINED_glTangent3svEXT +#define GLEE_H_DEFINED_glTangent3svEXT + typedef void (APIENTRYP GLEEPFNGLTANGENT3SVEXTPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLTANGENT3SVEXTPROC GLeeFuncPtr_glTangent3svEXT; + #define glTangent3svEXT GLeeFuncPtr_glTangent3svEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3bEXT +#define GLEE_H_DEFINED_glBinormal3bEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); + GLEE_EXTERN GLEEPFNGLBINORMAL3BEXTPROC GLeeFuncPtr_glBinormal3bEXT; + #define glBinormal3bEXT GLeeFuncPtr_glBinormal3bEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3bvEXT +#define GLEE_H_DEFINED_glBinormal3bvEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3BVEXTPROC) (const GLbyte * v); + GLEE_EXTERN GLEEPFNGLBINORMAL3BVEXTPROC GLeeFuncPtr_glBinormal3bvEXT; + #define glBinormal3bvEXT GLeeFuncPtr_glBinormal3bvEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3dEXT +#define GLEE_H_DEFINED_glBinormal3dEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); + GLEE_EXTERN GLEEPFNGLBINORMAL3DEXTPROC GLeeFuncPtr_glBinormal3dEXT; + #define glBinormal3dEXT GLeeFuncPtr_glBinormal3dEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3dvEXT +#define GLEE_H_DEFINED_glBinormal3dvEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3DVEXTPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLBINORMAL3DVEXTPROC GLeeFuncPtr_glBinormal3dvEXT; + #define glBinormal3dvEXT GLeeFuncPtr_glBinormal3dvEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3fEXT +#define GLEE_H_DEFINED_glBinormal3fEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); + GLEE_EXTERN GLEEPFNGLBINORMAL3FEXTPROC GLeeFuncPtr_glBinormal3fEXT; + #define glBinormal3fEXT GLeeFuncPtr_glBinormal3fEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3fvEXT +#define GLEE_H_DEFINED_glBinormal3fvEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3FVEXTPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLBINORMAL3FVEXTPROC GLeeFuncPtr_glBinormal3fvEXT; + #define glBinormal3fvEXT GLeeFuncPtr_glBinormal3fvEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3iEXT +#define GLEE_H_DEFINED_glBinormal3iEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); + GLEE_EXTERN GLEEPFNGLBINORMAL3IEXTPROC GLeeFuncPtr_glBinormal3iEXT; + #define glBinormal3iEXT GLeeFuncPtr_glBinormal3iEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3ivEXT +#define GLEE_H_DEFINED_glBinormal3ivEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3IVEXTPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLBINORMAL3IVEXTPROC GLeeFuncPtr_glBinormal3ivEXT; + #define glBinormal3ivEXT GLeeFuncPtr_glBinormal3ivEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3sEXT +#define GLEE_H_DEFINED_glBinormal3sEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); + GLEE_EXTERN GLEEPFNGLBINORMAL3SEXTPROC GLeeFuncPtr_glBinormal3sEXT; + #define glBinormal3sEXT GLeeFuncPtr_glBinormal3sEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormal3svEXT +#define GLEE_H_DEFINED_glBinormal3svEXT + typedef void (APIENTRYP GLEEPFNGLBINORMAL3SVEXTPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLBINORMAL3SVEXTPROC GLeeFuncPtr_glBinormal3svEXT; + #define glBinormal3svEXT GLeeFuncPtr_glBinormal3svEXT +#endif +#ifndef GLEE_H_DEFINED_glTangentPointerEXT +#define GLEE_H_DEFINED_glTangentPointerEXT + typedef void (APIENTRYP GLEEPFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLTANGENTPOINTEREXTPROC GLeeFuncPtr_glTangentPointerEXT; + #define glTangentPointerEXT GLeeFuncPtr_glTangentPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glBinormalPointerEXT +#define GLEE_H_DEFINED_glBinormalPointerEXT + typedef void (APIENTRYP GLEEPFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLBINORMALPOINTEREXTPROC GLeeFuncPtr_glBinormalPointerEXT; + #define glBinormalPointerEXT GLeeFuncPtr_glBinormalPointerEXT +#endif +#endif + +/* GL_EXT_texture_env_combine */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#define __GLEE_GL_EXT_texture_env_combine 1 +/* Constants */ +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +/* GL_APPLE_specular_vector */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#define __GLEE_GL_APPLE_specular_vector 1 +/* Constants */ +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +/* GL_APPLE_transform_hint */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#define __GLEE_GL_APPLE_transform_hint 1 +/* Constants */ +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +/* GL_SGIX_fog_scale */ + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#define __GLEE_GL_SGIX_fog_scale 1 +/* Constants */ +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +/* GL_SUNX_constant_data */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#define __GLEE_GL_SUNX_constant_data 1 +/* Constants */ +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#ifndef GLEE_H_DEFINED_glFinishTextureSUNX +#define GLEE_H_DEFINED_glFinishTextureSUNX + typedef void (APIENTRYP GLEEPFNGLFINISHTEXTURESUNXPROC) (); + GLEE_EXTERN GLEEPFNGLFINISHTEXTURESUNXPROC GLeeFuncPtr_glFinishTextureSUNX; + #define glFinishTextureSUNX GLeeFuncPtr_glFinishTextureSUNX +#endif +#endif + +/* GL_SUN_global_alpha */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#define __GLEE_GL_SUN_global_alpha 1 +/* Constants */ +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactorbSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactorbSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORBSUNPROC GLeeFuncPtr_glGlobalAlphaFactorbSUN; + #define glGlobalAlphaFactorbSUN GLeeFuncPtr_glGlobalAlphaFactorbSUN +#endif +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactorsSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactorsSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORSSUNPROC GLeeFuncPtr_glGlobalAlphaFactorsSUN; + #define glGlobalAlphaFactorsSUN GLeeFuncPtr_glGlobalAlphaFactorsSUN +#endif +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactoriSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactoriSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORISUNPROC GLeeFuncPtr_glGlobalAlphaFactoriSUN; + #define glGlobalAlphaFactoriSUN GLeeFuncPtr_glGlobalAlphaFactoriSUN +#endif +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactorfSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactorfSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORFSUNPROC GLeeFuncPtr_glGlobalAlphaFactorfSUN; + #define glGlobalAlphaFactorfSUN GLeeFuncPtr_glGlobalAlphaFactorfSUN +#endif +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactordSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactordSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORDSUNPROC GLeeFuncPtr_glGlobalAlphaFactordSUN; + #define glGlobalAlphaFactordSUN GLeeFuncPtr_glGlobalAlphaFactordSUN +#endif +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactorubSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactorubSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORUBSUNPROC GLeeFuncPtr_glGlobalAlphaFactorubSUN; + #define glGlobalAlphaFactorubSUN GLeeFuncPtr_glGlobalAlphaFactorubSUN +#endif +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactorusSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactorusSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORUSSUNPROC GLeeFuncPtr_glGlobalAlphaFactorusSUN; + #define glGlobalAlphaFactorusSUN GLeeFuncPtr_glGlobalAlphaFactorusSUN +#endif +#ifndef GLEE_H_DEFINED_glGlobalAlphaFactoruiSUN +#define GLEE_H_DEFINED_glGlobalAlphaFactoruiSUN + typedef void (APIENTRYP GLEEPFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); + GLEE_EXTERN GLEEPFNGLGLOBALALPHAFACTORUISUNPROC GLeeFuncPtr_glGlobalAlphaFactoruiSUN; + #define glGlobalAlphaFactoruiSUN GLeeFuncPtr_glGlobalAlphaFactoruiSUN +#endif +#endif + +/* GL_SUN_triangle_list */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#define __GLEE_GL_SUN_triangle_list 1 +/* Constants */ +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#ifndef GLEE_H_DEFINED_glReplacementCodeuiSUN +#define GLEE_H_DEFINED_glReplacementCodeuiSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUISUNPROC GLeeFuncPtr_glReplacementCodeuiSUN; + #define glReplacementCodeuiSUN GLeeFuncPtr_glReplacementCodeuiSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeusSUN +#define GLEE_H_DEFINED_glReplacementCodeusSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUSSUNPROC GLeeFuncPtr_glReplacementCodeusSUN; + #define glReplacementCodeusSUN GLeeFuncPtr_glReplacementCodeusSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeubSUN +#define GLEE_H_DEFINED_glReplacementCodeubSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUBSUNPROC GLeeFuncPtr_glReplacementCodeubSUN; + #define glReplacementCodeubSUN GLeeFuncPtr_glReplacementCodeubSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuivSUN +#define GLEE_H_DEFINED_glReplacementCodeuivSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint * code); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUIVSUNPROC GLeeFuncPtr_glReplacementCodeuivSUN; + #define glReplacementCodeuivSUN GLeeFuncPtr_glReplacementCodeuivSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeusvSUN +#define GLEE_H_DEFINED_glReplacementCodeusvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort * code); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUSVSUNPROC GLeeFuncPtr_glReplacementCodeusvSUN; + #define glReplacementCodeusvSUN GLeeFuncPtr_glReplacementCodeusvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeubvSUN +#define GLEE_H_DEFINED_glReplacementCodeubvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte * code); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUBVSUNPROC GLeeFuncPtr_glReplacementCodeubvSUN; + #define glReplacementCodeubvSUN GLeeFuncPtr_glReplacementCodeubvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodePointerSUN +#define GLEE_H_DEFINED_glReplacementCodePointerSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEPOINTERSUNPROC GLeeFuncPtr_glReplacementCodePointerSUN; + #define glReplacementCodePointerSUN GLeeFuncPtr_glReplacementCodePointerSUN +#endif +#endif + +/* GL_SUN_vertex */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#define __GLEE_GL_SUN_vertex 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glColor4ubVertex2fSUN +#define GLEE_H_DEFINED_glColor4ubVertex2fSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLCOLOR4UBVERTEX2FSUNPROC GLeeFuncPtr_glColor4ubVertex2fSUN; + #define glColor4ubVertex2fSUN GLeeFuncPtr_glColor4ubVertex2fSUN +#endif +#ifndef GLEE_H_DEFINED_glColor4ubVertex2fvSUN +#define GLEE_H_DEFINED_glColor4ubVertex2fvSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte * c, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLCOLOR4UBVERTEX2FVSUNPROC GLeeFuncPtr_glColor4ubVertex2fvSUN; + #define glColor4ubVertex2fvSUN GLeeFuncPtr_glColor4ubVertex2fvSUN +#endif +#ifndef GLEE_H_DEFINED_glColor4ubVertex3fSUN +#define GLEE_H_DEFINED_glColor4ubVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLCOLOR4UBVERTEX3FSUNPROC GLeeFuncPtr_glColor4ubVertex3fSUN; + #define glColor4ubVertex3fSUN GLeeFuncPtr_glColor4ubVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glColor4ubVertex3fvSUN +#define GLEE_H_DEFINED_glColor4ubVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte * c, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLCOLOR4UBVERTEX3FVSUNPROC GLeeFuncPtr_glColor4ubVertex3fvSUN; + #define glColor4ubVertex3fvSUN GLeeFuncPtr_glColor4ubVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glColor3fVertex3fSUN +#define GLEE_H_DEFINED_glColor3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLCOLOR3FVERTEX3FSUNPROC GLeeFuncPtr_glColor3fVertex3fSUN; + #define glColor3fVertex3fSUN GLeeFuncPtr_glColor3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glColor3fVertex3fvSUN +#define GLEE_H_DEFINED_glColor3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat * c, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLCOLOR3FVERTEX3FVSUNPROC GLeeFuncPtr_glColor3fVertex3fvSUN; + #define glColor3fVertex3fvSUN GLeeFuncPtr_glColor3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glNormal3fVertex3fSUN; + #define glNormal3fVertex3fSUN GLeeFuncPtr_glNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glNormal3fVertex3fvSUN; + #define glNormal3fVertex3fvSUN GLeeFuncPtr_glNormal3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glColor4fNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glColor4fNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glColor4fNormal3fVertex3fSUN; + #define glColor4fNormal3fVertex3fSUN GLeeFuncPtr_glColor4fNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glColor4fNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glColor4fNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat * c, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glColor4fNormal3fVertex3fvSUN; + #define glColor4fNormal3fVertex3fvSUN GLeeFuncPtr_glColor4fNormal3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fVertex3fSUN +#define GLEE_H_DEFINED_glTexCoord2fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fVertex3fSUN; + #define glTexCoord2fVertex3fSUN GLeeFuncPtr_glTexCoord2fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fVertex3fvSUN +#define GLEE_H_DEFINED_glTexCoord2fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat * tc, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fVertex3fvSUN; + #define glTexCoord2fVertex3fvSUN GLeeFuncPtr_glTexCoord2fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4fVertex4fSUN +#define GLEE_H_DEFINED_glTexCoord4fVertex4fSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLTEXCOORD4FVERTEX4FSUNPROC GLeeFuncPtr_glTexCoord4fVertex4fSUN; + #define glTexCoord4fVertex4fSUN GLeeFuncPtr_glTexCoord4fVertex4fSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4fVertex4fvSUN +#define GLEE_H_DEFINED_glTexCoord4fVertex4fvSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat * tc, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD4FVERTEX4FVSUNPROC GLeeFuncPtr_glTexCoord4fVertex4fvSUN; + #define glTexCoord4fVertex4fvSUN GLeeFuncPtr_glTexCoord4fVertex4fvSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fColor4ubVertex3fSUN +#define GLEE_H_DEFINED_glTexCoord2fColor4ubVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fColor4ubVertex3fSUN; + #define glTexCoord2fColor4ubVertex3fSUN GLeeFuncPtr_glTexCoord2fColor4ubVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fColor4ubVertex3fvSUN +#define GLEE_H_DEFINED_glTexCoord2fColor4ubVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat * tc, const GLubyte * c, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fColor4ubVertex3fvSUN; + #define glTexCoord2fColor4ubVertex3fvSUN GLeeFuncPtr_glTexCoord2fColor4ubVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fColor3fVertex3fSUN +#define GLEE_H_DEFINED_glTexCoord2fColor3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fColor3fVertex3fSUN; + #define glTexCoord2fColor3fVertex3fSUN GLeeFuncPtr_glTexCoord2fColor3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fColor3fVertex3fvSUN +#define GLEE_H_DEFINED_glTexCoord2fColor3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat * tc, const GLfloat * c, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fColor3fVertex3fvSUN; + #define glTexCoord2fColor3fVertex3fvSUN GLeeFuncPtr_glTexCoord2fColor3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glTexCoord2fNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fNormal3fVertex3fSUN; + #define glTexCoord2fNormal3fVertex3fSUN GLeeFuncPtr_glTexCoord2fNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glTexCoord2fNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat * tc, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fNormal3fVertex3fvSUN; + #define glTexCoord2fNormal3fVertex3fvSUN GLeeFuncPtr_glTexCoord2fNormal3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fColor4fNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glTexCoord2fColor4fNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fSUN; + #define glTexCoord2fColor4fNormal3fVertex3fSUN GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2fColor4fNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glTexCoord2fColor4fNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fvSUN; + #define glTexCoord2fColor4fNormal3fVertex3fvSUN GLeeFuncPtr_glTexCoord2fColor4fNormal3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4fColor4fNormal3fVertex4fSUN +#define GLEE_H_DEFINED_glTexCoord4fColor4fNormal3fVertex4fSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fSUN; + #define glTexCoord4fColor4fNormal3fVertex4fSUN GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fSUN +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4fColor4fNormal3fVertex4fvSUN +#define GLEE_H_DEFINED_glTexCoord4fColor4fNormal3fVertex4fvSUN + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fvSUN; + #define glTexCoord4fColor4fNormal3fVertex4fvSUN GLeeFuncPtr_glTexCoord4fColor4fNormal3fVertex4fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiVertex3fSUN; + #define glReplacementCodeuiVertex3fSUN GLeeFuncPtr_glReplacementCodeuiVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint * rc, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiVertex3fvSUN; + #define glReplacementCodeuiVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiColor4ubVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiColor4ubVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fSUN; + #define glReplacementCodeuiColor4ubVertex3fSUN GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiColor4ubVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiColor4ubVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint * rc, const GLubyte * c, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fvSUN; + #define glReplacementCodeuiColor4ubVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiColor4ubVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiColor3fVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiColor3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fSUN; + #define glReplacementCodeuiColor3fVertex3fSUN GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiColor3fVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiColor3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint * rc, const GLfloat * c, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fvSUN; + #define glReplacementCodeuiColor3fVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiColor3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fSUN; + #define glReplacementCodeuiNormal3fVertex3fSUN GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint * rc, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fvSUN; + #define glReplacementCodeuiNormal3fVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiNormal3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fSUN; + #define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiColor4fNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint * rc, const GLfloat * c, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fvSUN; + #define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiColor4fNormal3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fSUN; + #define glReplacementCodeuiTexCoord2fVertex3fSUN GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint * rc, const GLfloat * tc, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fvSUN; + #define glReplacementCodeuiTexCoord2fVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiTexCoord2fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; + #define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint * rc, const GLfloat * tc, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; + #define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN +#define GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; + #define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN +#endif +#ifndef GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN +#define GLEE_H_DEFINED_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN + typedef void (APIENTRYP GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint * rc, const GLfloat * tc, const GLfloat * c, const GLfloat * n, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; + #define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLeeFuncPtr_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN +#endif +#endif + +/* GL_EXT_blend_func_separate */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#define __GLEE_GL_EXT_blend_func_separate 1 +/* Constants */ +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#ifndef GLEE_H_DEFINED_glBlendFuncSeparateEXT +#define GLEE_H_DEFINED_glBlendFuncSeparateEXT + typedef void (APIENTRYP GLEEPFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + GLEE_EXTERN GLEEPFNGLBLENDFUNCSEPARATEEXTPROC GLeeFuncPtr_glBlendFuncSeparateEXT; + #define glBlendFuncSeparateEXT GLeeFuncPtr_glBlendFuncSeparateEXT +#endif +#endif + +/* GL_INGR_color_clamp */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#define __GLEE_GL_INGR_color_clamp 1 +/* Constants */ +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +/* GL_INGR_interlace_read */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#define __GLEE_GL_INGR_interlace_read 1 +/* Constants */ +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +/* GL_EXT_stencil_wrap */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#define __GLEE_GL_EXT_stencil_wrap 1 +/* Constants */ +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +/* GL_EXT_422_pixels */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#define __GLEE_GL_EXT_422_pixels 1 +/* Constants */ +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +/* GL_NV_texgen_reflection */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#define __GLEE_GL_NV_texgen_reflection 1 +/* Constants */ +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +/* GL_EXT_texture_cube_map */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 +#define __GLEE_GL_EXT_texture_cube_map 1 +/* Constants */ +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +/* GL_SUN_convolution_border_modes */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#define __GLEE_GL_SUN_convolution_border_modes 1 +/* Constants */ +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +/* GL_EXT_texture_env_add */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#define __GLEE_GL_EXT_texture_env_add 1 +/* Constants */ +#endif + +/* GL_EXT_texture_lod_bias */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#define __GLEE_GL_EXT_texture_lod_bias 1 +/* Constants */ +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +/* GL_EXT_texture_filter_anisotropic */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#define __GLEE_GL_EXT_texture_filter_anisotropic 1 +/* Constants */ +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +/* GL_EXT_vertex_weighting */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#define __GLEE_GL_EXT_vertex_weighting 1 +/* Constants */ +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#ifndef GLEE_H_DEFINED_glVertexWeightfEXT +#define GLEE_H_DEFINED_glVertexWeightfEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); + GLEE_EXTERN GLEEPFNGLVERTEXWEIGHTFEXTPROC GLeeFuncPtr_glVertexWeightfEXT; + #define glVertexWeightfEXT GLeeFuncPtr_glVertexWeightfEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexWeightfvEXT +#define GLEE_H_DEFINED_glVertexWeightfvEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat * weight); + GLEE_EXTERN GLEEPFNGLVERTEXWEIGHTFVEXTPROC GLeeFuncPtr_glVertexWeightfvEXT; + #define glVertexWeightfvEXT GLeeFuncPtr_glVertexWeightfvEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexWeightPointerEXT +#define GLEE_H_DEFINED_glVertexWeightPointerEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC GLeeFuncPtr_glVertexWeightPointerEXT; + #define glVertexWeightPointerEXT GLeeFuncPtr_glVertexWeightPointerEXT +#endif +#endif + +/* GL_NV_light_max_exponent */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#define __GLEE_GL_NV_light_max_exponent 1 +/* Constants */ +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +/* GL_NV_vertex_array_range */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#define __GLEE_GL_NV_vertex_array_range 1 +/* Constants */ +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#ifndef GLEE_H_DEFINED_glFlushVertexArrayRangeNV +#define GLEE_H_DEFINED_glFlushVertexArrayRangeNV + typedef void (APIENTRYP GLEEPFNGLFLUSHVERTEXARRAYRANGENVPROC) (); + GLEE_EXTERN GLEEPFNGLFLUSHVERTEXARRAYRANGENVPROC GLeeFuncPtr_glFlushVertexArrayRangeNV; + #define glFlushVertexArrayRangeNV GLeeFuncPtr_glFlushVertexArrayRangeNV +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayRangeNV +#define GLEE_H_DEFINED_glVertexArrayRangeNV + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYRANGENVPROC GLeeFuncPtr_glVertexArrayRangeNV; + #define glVertexArrayRangeNV GLeeFuncPtr_glVertexArrayRangeNV +#endif +#endif + +/* GL_NV_register_combiners */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#define __GLEE_GL_NV_register_combiners 1 +/* Constants */ +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +#ifndef GLEE_H_DEFINED_glCombinerParameterfvNV +#define GLEE_H_DEFINED_glCombinerParameterfvNV + typedef void (APIENTRYP GLEEPFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLCOMBINERPARAMETERFVNVPROC GLeeFuncPtr_glCombinerParameterfvNV; + #define glCombinerParameterfvNV GLeeFuncPtr_glCombinerParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glCombinerParameterfNV +#define GLEE_H_DEFINED_glCombinerParameterfNV + typedef void (APIENTRYP GLEEPFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLCOMBINERPARAMETERFNVPROC GLeeFuncPtr_glCombinerParameterfNV; + #define glCombinerParameterfNV GLeeFuncPtr_glCombinerParameterfNV +#endif +#ifndef GLEE_H_DEFINED_glCombinerParameterivNV +#define GLEE_H_DEFINED_glCombinerParameterivNV + typedef void (APIENTRYP GLEEPFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLCOMBINERPARAMETERIVNVPROC GLeeFuncPtr_glCombinerParameterivNV; + #define glCombinerParameterivNV GLeeFuncPtr_glCombinerParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glCombinerParameteriNV +#define GLEE_H_DEFINED_glCombinerParameteriNV + typedef void (APIENTRYP GLEEPFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLCOMBINERPARAMETERINVPROC GLeeFuncPtr_glCombinerParameteriNV; + #define glCombinerParameteriNV GLeeFuncPtr_glCombinerParameteriNV +#endif +#ifndef GLEE_H_DEFINED_glCombinerInputNV +#define GLEE_H_DEFINED_glCombinerInputNV + typedef void (APIENTRYP GLEEPFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); + GLEE_EXTERN GLEEPFNGLCOMBINERINPUTNVPROC GLeeFuncPtr_glCombinerInputNV; + #define glCombinerInputNV GLeeFuncPtr_glCombinerInputNV +#endif +#ifndef GLEE_H_DEFINED_glCombinerOutputNV +#define GLEE_H_DEFINED_glCombinerOutputNV + typedef void (APIENTRYP GLEEPFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); + GLEE_EXTERN GLEEPFNGLCOMBINEROUTPUTNVPROC GLeeFuncPtr_glCombinerOutputNV; + #define glCombinerOutputNV GLeeFuncPtr_glCombinerOutputNV +#endif +#ifndef GLEE_H_DEFINED_glFinalCombinerInputNV +#define GLEE_H_DEFINED_glFinalCombinerInputNV + typedef void (APIENTRYP GLEEPFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); + GLEE_EXTERN GLEEPFNGLFINALCOMBINERINPUTNVPROC GLeeFuncPtr_glFinalCombinerInputNV; + #define glFinalCombinerInputNV GLeeFuncPtr_glFinalCombinerInputNV +#endif +#ifndef GLEE_H_DEFINED_glGetCombinerInputParameterfvNV +#define GLEE_H_DEFINED_glGetCombinerInputParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCOMBINERINPUTPARAMETERFVNVPROC GLeeFuncPtr_glGetCombinerInputParameterfvNV; + #define glGetCombinerInputParameterfvNV GLeeFuncPtr_glGetCombinerInputParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetCombinerInputParameterivNV +#define GLEE_H_DEFINED_glGetCombinerInputParameterivNV + typedef void (APIENTRYP GLEEPFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETCOMBINERINPUTPARAMETERIVNVPROC GLeeFuncPtr_glGetCombinerInputParameterivNV; + #define glGetCombinerInputParameterivNV GLeeFuncPtr_glGetCombinerInputParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glGetCombinerOutputParameterfvNV +#define GLEE_H_DEFINED_glGetCombinerOutputParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC GLeeFuncPtr_glGetCombinerOutputParameterfvNV; + #define glGetCombinerOutputParameterfvNV GLeeFuncPtr_glGetCombinerOutputParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetCombinerOutputParameterivNV +#define GLEE_H_DEFINED_glGetCombinerOutputParameterivNV + typedef void (APIENTRYP GLEEPFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC GLeeFuncPtr_glGetCombinerOutputParameterivNV; + #define glGetCombinerOutputParameterivNV GLeeFuncPtr_glGetCombinerOutputParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glGetFinalCombinerInputParameterfvNV +#define GLEE_H_DEFINED_glGetFinalCombinerInputParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC GLeeFuncPtr_glGetFinalCombinerInputParameterfvNV; + #define glGetFinalCombinerInputParameterfvNV GLeeFuncPtr_glGetFinalCombinerInputParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetFinalCombinerInputParameterivNV +#define GLEE_H_DEFINED_glGetFinalCombinerInputParameterivNV + typedef void (APIENTRYP GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC GLeeFuncPtr_glGetFinalCombinerInputParameterivNV; + #define glGetFinalCombinerInputParameterivNV GLeeFuncPtr_glGetFinalCombinerInputParameterivNV +#endif +#endif + +/* GL_NV_fog_distance */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#define __GLEE_GL_NV_fog_distance 1 +/* Constants */ +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +#endif + +/* GL_NV_texgen_emboss */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#define __GLEE_GL_NV_texgen_emboss 1 +/* Constants */ +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +/* GL_NV_blend_square */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#define __GLEE_GL_NV_blend_square 1 +/* Constants */ +#endif + +/* GL_NV_texture_env_combine4 */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#define __GLEE_GL_NV_texture_env_combine4 1 +/* Constants */ +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +/* GL_MESA_resize_buffers */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#define __GLEE_GL_MESA_resize_buffers 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glResizeBuffersMESA +#define GLEE_H_DEFINED_glResizeBuffersMESA + typedef void (APIENTRYP GLEEPFNGLRESIZEBUFFERSMESAPROC) (); + GLEE_EXTERN GLEEPFNGLRESIZEBUFFERSMESAPROC GLeeFuncPtr_glResizeBuffersMESA; + #define glResizeBuffersMESA GLeeFuncPtr_glResizeBuffersMESA +#endif +#endif + +/* GL_MESA_window_pos */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#define __GLEE_GL_MESA_window_pos 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glWindowPos2dMESA +#define GLEE_H_DEFINED_glWindowPos2dMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2DMESAPROC GLeeFuncPtr_glWindowPos2dMESA; + #define glWindowPos2dMESA GLeeFuncPtr_glWindowPos2dMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2dvMESA +#define GLEE_H_DEFINED_glWindowPos2dvMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2DVMESAPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2DVMESAPROC GLeeFuncPtr_glWindowPos2dvMESA; + #define glWindowPos2dvMESA GLeeFuncPtr_glWindowPos2dvMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2fMESA +#define GLEE_H_DEFINED_glWindowPos2fMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2FMESAPROC GLeeFuncPtr_glWindowPos2fMESA; + #define glWindowPos2fMESA GLeeFuncPtr_glWindowPos2fMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2fvMESA +#define GLEE_H_DEFINED_glWindowPos2fvMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2FVMESAPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2FVMESAPROC GLeeFuncPtr_glWindowPos2fvMESA; + #define glWindowPos2fvMESA GLeeFuncPtr_glWindowPos2fvMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2iMESA +#define GLEE_H_DEFINED_glWindowPos2iMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2IMESAPROC GLeeFuncPtr_glWindowPos2iMESA; + #define glWindowPos2iMESA GLeeFuncPtr_glWindowPos2iMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2ivMESA +#define GLEE_H_DEFINED_glWindowPos2ivMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2IVMESAPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2IVMESAPROC GLeeFuncPtr_glWindowPos2ivMESA; + #define glWindowPos2ivMESA GLeeFuncPtr_glWindowPos2ivMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2sMESA +#define GLEE_H_DEFINED_glWindowPos2sMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2SMESAPROC GLeeFuncPtr_glWindowPos2sMESA; + #define glWindowPos2sMESA GLeeFuncPtr_glWindowPos2sMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos2svMESA +#define GLEE_H_DEFINED_glWindowPos2svMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS2SVMESAPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS2SVMESAPROC GLeeFuncPtr_glWindowPos2svMESA; + #define glWindowPos2svMESA GLeeFuncPtr_glWindowPos2svMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3dMESA +#define GLEE_H_DEFINED_glWindowPos3dMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3DMESAPROC GLeeFuncPtr_glWindowPos3dMESA; + #define glWindowPos3dMESA GLeeFuncPtr_glWindowPos3dMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3dvMESA +#define GLEE_H_DEFINED_glWindowPos3dvMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3DVMESAPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3DVMESAPROC GLeeFuncPtr_glWindowPos3dvMESA; + #define glWindowPos3dvMESA GLeeFuncPtr_glWindowPos3dvMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3fMESA +#define GLEE_H_DEFINED_glWindowPos3fMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3FMESAPROC GLeeFuncPtr_glWindowPos3fMESA; + #define glWindowPos3fMESA GLeeFuncPtr_glWindowPos3fMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3fvMESA +#define GLEE_H_DEFINED_glWindowPos3fvMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3FVMESAPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3FVMESAPROC GLeeFuncPtr_glWindowPos3fvMESA; + #define glWindowPos3fvMESA GLeeFuncPtr_glWindowPos3fvMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3iMESA +#define GLEE_H_DEFINED_glWindowPos3iMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3IMESAPROC GLeeFuncPtr_glWindowPos3iMESA; + #define glWindowPos3iMESA GLeeFuncPtr_glWindowPos3iMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3ivMESA +#define GLEE_H_DEFINED_glWindowPos3ivMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3IVMESAPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3IVMESAPROC GLeeFuncPtr_glWindowPos3ivMESA; + #define glWindowPos3ivMESA GLeeFuncPtr_glWindowPos3ivMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3sMESA +#define GLEE_H_DEFINED_glWindowPos3sMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3SMESAPROC GLeeFuncPtr_glWindowPos3sMESA; + #define glWindowPos3sMESA GLeeFuncPtr_glWindowPos3sMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos3svMESA +#define GLEE_H_DEFINED_glWindowPos3svMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS3SVMESAPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS3SVMESAPROC GLeeFuncPtr_glWindowPos3svMESA; + #define glWindowPos3svMESA GLeeFuncPtr_glWindowPos3svMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4dMESA +#define GLEE_H_DEFINED_glWindowPos4dMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4DMESAPROC GLeeFuncPtr_glWindowPos4dMESA; + #define glWindowPos4dMESA GLeeFuncPtr_glWindowPos4dMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4dvMESA +#define GLEE_H_DEFINED_glWindowPos4dvMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4DVMESAPROC) (const GLdouble * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4DVMESAPROC GLeeFuncPtr_glWindowPos4dvMESA; + #define glWindowPos4dvMESA GLeeFuncPtr_glWindowPos4dvMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4fMESA +#define GLEE_H_DEFINED_glWindowPos4fMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4FMESAPROC GLeeFuncPtr_glWindowPos4fMESA; + #define glWindowPos4fMESA GLeeFuncPtr_glWindowPos4fMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4fvMESA +#define GLEE_H_DEFINED_glWindowPos4fvMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4FVMESAPROC) (const GLfloat * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4FVMESAPROC GLeeFuncPtr_glWindowPos4fvMESA; + #define glWindowPos4fvMESA GLeeFuncPtr_glWindowPos4fvMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4iMESA +#define GLEE_H_DEFINED_glWindowPos4iMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4IMESAPROC GLeeFuncPtr_glWindowPos4iMESA; + #define glWindowPos4iMESA GLeeFuncPtr_glWindowPos4iMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4ivMESA +#define GLEE_H_DEFINED_glWindowPos4ivMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4IVMESAPROC) (const GLint * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4IVMESAPROC GLeeFuncPtr_glWindowPos4ivMESA; + #define glWindowPos4ivMESA GLeeFuncPtr_glWindowPos4ivMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4sMESA +#define GLEE_H_DEFINED_glWindowPos4sMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4SMESAPROC GLeeFuncPtr_glWindowPos4sMESA; + #define glWindowPos4sMESA GLeeFuncPtr_glWindowPos4sMESA +#endif +#ifndef GLEE_H_DEFINED_glWindowPos4svMESA +#define GLEE_H_DEFINED_glWindowPos4svMESA + typedef void (APIENTRYP GLEEPFNGLWINDOWPOS4SVMESAPROC) (const GLshort * v); + GLEE_EXTERN GLEEPFNGLWINDOWPOS4SVMESAPROC GLeeFuncPtr_glWindowPos4svMESA; + #define glWindowPos4svMESA GLeeFuncPtr_glWindowPos4svMESA +#endif +#endif + +/* GL_EXT_texture_compression_s3tc */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#define __GLEE_GL_EXT_texture_compression_s3tc 1 +/* Constants */ +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +/* GL_IBM_cull_vertex */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#define __GLEE_GL_IBM_cull_vertex 1 +/* Constants */ +#define GL_CULL_VERTEX_IBM 103050 +#endif + +/* GL_IBM_multimode_draw_arrays */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#define __GLEE_GL_IBM_multimode_draw_arrays 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glMultiModeDrawArraysIBM +#define GLEE_H_DEFINED_glMultiModeDrawArraysIBM + typedef void (APIENTRYP GLEEPFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride); + GLEE_EXTERN GLEEPFNGLMULTIMODEDRAWARRAYSIBMPROC GLeeFuncPtr_glMultiModeDrawArraysIBM; + #define glMultiModeDrawArraysIBM GLeeFuncPtr_glMultiModeDrawArraysIBM +#endif +#ifndef GLEE_H_DEFINED_glMultiModeDrawElementsIBM +#define GLEE_H_DEFINED_glMultiModeDrawElementsIBM + typedef void (APIENTRYP GLEEPFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid* const * indices, GLsizei primcount, GLint modestride); + GLEE_EXTERN GLEEPFNGLMULTIMODEDRAWELEMENTSIBMPROC GLeeFuncPtr_glMultiModeDrawElementsIBM; + #define glMultiModeDrawElementsIBM GLeeFuncPtr_glMultiModeDrawElementsIBM +#endif +#endif + +/* GL_IBM_vertex_array_lists */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#define __GLEE_GL_IBM_vertex_array_lists 1 +/* Constants */ +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#ifndef GLEE_H_DEFINED_glColorPointerListIBM +#define GLEE_H_DEFINED_glColorPointerListIBM + typedef void (APIENTRYP GLEEPFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLCOLORPOINTERLISTIBMPROC GLeeFuncPtr_glColorPointerListIBM; + #define glColorPointerListIBM GLeeFuncPtr_glColorPointerListIBM +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColorPointerListIBM +#define GLEE_H_DEFINED_glSecondaryColorPointerListIBM + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLORPOINTERLISTIBMPROC GLeeFuncPtr_glSecondaryColorPointerListIBM; + #define glSecondaryColorPointerListIBM GLeeFuncPtr_glSecondaryColorPointerListIBM +#endif +#ifndef GLEE_H_DEFINED_glEdgeFlagPointerListIBM +#define GLEE_H_DEFINED_glEdgeFlagPointerListIBM + typedef void (APIENTRYP GLEEPFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLEDGEFLAGPOINTERLISTIBMPROC GLeeFuncPtr_glEdgeFlagPointerListIBM; + #define glEdgeFlagPointerListIBM GLeeFuncPtr_glEdgeFlagPointerListIBM +#endif +#ifndef GLEE_H_DEFINED_glFogCoordPointerListIBM +#define GLEE_H_DEFINED_glFogCoordPointerListIBM + typedef void (APIENTRYP GLEEPFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLFOGCOORDPOINTERLISTIBMPROC GLeeFuncPtr_glFogCoordPointerListIBM; + #define glFogCoordPointerListIBM GLeeFuncPtr_glFogCoordPointerListIBM +#endif +#ifndef GLEE_H_DEFINED_glIndexPointerListIBM +#define GLEE_H_DEFINED_glIndexPointerListIBM + typedef void (APIENTRYP GLEEPFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLINDEXPOINTERLISTIBMPROC GLeeFuncPtr_glIndexPointerListIBM; + #define glIndexPointerListIBM GLeeFuncPtr_glIndexPointerListIBM +#endif +#ifndef GLEE_H_DEFINED_glNormalPointerListIBM +#define GLEE_H_DEFINED_glNormalPointerListIBM + typedef void (APIENTRYP GLEEPFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLNORMALPOINTERLISTIBMPROC GLeeFuncPtr_glNormalPointerListIBM; + #define glNormalPointerListIBM GLeeFuncPtr_glNormalPointerListIBM +#endif +#ifndef GLEE_H_DEFINED_glTexCoordPointerListIBM +#define GLEE_H_DEFINED_glTexCoordPointerListIBM + typedef void (APIENTRYP GLEEPFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLTEXCOORDPOINTERLISTIBMPROC GLeeFuncPtr_glTexCoordPointerListIBM; + #define glTexCoordPointerListIBM GLeeFuncPtr_glTexCoordPointerListIBM +#endif +#ifndef GLEE_H_DEFINED_glVertexPointerListIBM +#define GLEE_H_DEFINED_glVertexPointerListIBM + typedef void (APIENTRYP GLEEPFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* * pointer, GLint ptrstride); + GLEE_EXTERN GLEEPFNGLVERTEXPOINTERLISTIBMPROC GLeeFuncPtr_glVertexPointerListIBM; + #define glVertexPointerListIBM GLeeFuncPtr_glVertexPointerListIBM +#endif +#endif + +/* GL_SGIX_subsample */ + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#define __GLEE_GL_SGIX_subsample 1 +/* Constants */ +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +/* GL_SGIX_ycrcb_subsample */ + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#define __GLEE_GL_SGIX_ycrcb_subsample 1 +/* Constants */ +#endif + +/* GL_SGIX_ycrcba */ + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#define __GLEE_GL_SGIX_ycrcba 1 +/* Constants */ +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +/* GL_SGI_depth_pass_instrument */ + +#ifndef GL_SGI_depth_pass_instrument +#define GL_SGI_depth_pass_instrument 1 +#define __GLEE_GL_SGI_depth_pass_instrument 1 +/* Constants */ +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +/* GL_3DFX_texture_compression_FXT1 */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#define __GLEE_GL_3DFX_texture_compression_FXT1 1 +/* Constants */ +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +/* GL_3DFX_multisample */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#define __GLEE_GL_3DFX_multisample 1 +/* Constants */ +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +/* GL_3DFX_tbuffer */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#define __GLEE_GL_3DFX_tbuffer 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glTbufferMask3DFX +#define GLEE_H_DEFINED_glTbufferMask3DFX + typedef void (APIENTRYP GLEEPFNGLTBUFFERMASK3DFXPROC) (GLuint mask); + GLEE_EXTERN GLEEPFNGLTBUFFERMASK3DFXPROC GLeeFuncPtr_glTbufferMask3DFX; + #define glTbufferMask3DFX GLeeFuncPtr_glTbufferMask3DFX +#endif +#endif + +/* GL_EXT_multisample */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#define __GLEE_GL_EXT_multisample 1 +/* Constants */ +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#ifndef GLEE_H_DEFINED_glSampleMaskEXT +#define GLEE_H_DEFINED_glSampleMaskEXT + typedef void (APIENTRYP GLEEPFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); + GLEE_EXTERN GLEEPFNGLSAMPLEMASKEXTPROC GLeeFuncPtr_glSampleMaskEXT; + #define glSampleMaskEXT GLeeFuncPtr_glSampleMaskEXT +#endif +#ifndef GLEE_H_DEFINED_glSamplePatternEXT +#define GLEE_H_DEFINED_glSamplePatternEXT + typedef void (APIENTRYP GLEEPFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); + GLEE_EXTERN GLEEPFNGLSAMPLEPATTERNEXTPROC GLeeFuncPtr_glSamplePatternEXT; + #define glSamplePatternEXT GLeeFuncPtr_glSamplePatternEXT +#endif +#endif + +/* GL_SGIX_vertex_preclip */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#define __GLEE_GL_SGIX_vertex_preclip 1 +/* Constants */ +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +/* GL_SGIX_convolution_accuracy */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#define __GLEE_GL_SGIX_convolution_accuracy 1 +/* Constants */ +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +/* GL_SGIX_resample */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#define __GLEE_GL_SGIX_resample 1 +/* Constants */ +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +/* GL_SGIS_point_line_texgen */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#define __GLEE_GL_SGIS_point_line_texgen 1 +/* Constants */ +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +/* GL_SGIS_texture_color_mask */ + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#define __GLEE_GL_SGIS_texture_color_mask 1 +/* Constants */ +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#ifndef GLEE_H_DEFINED_glTextureColorMaskSGIS +#define GLEE_H_DEFINED_glTextureColorMaskSGIS + typedef void (APIENTRYP GLEEPFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + GLEE_EXTERN GLEEPFNGLTEXTURECOLORMASKSGISPROC GLeeFuncPtr_glTextureColorMaskSGIS; + #define glTextureColorMaskSGIS GLeeFuncPtr_glTextureColorMaskSGIS +#endif +#endif + +/* GL_EXT_texture_env_dot3 */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#define __GLEE_GL_EXT_texture_env_dot3 1 +/* Constants */ +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif + +/* GL_ATI_texture_mirror_once */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#define __GLEE_GL_ATI_texture_mirror_once 1 +/* Constants */ +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +/* GL_NV_fence */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#define __GLEE_GL_NV_fence 1 +/* Constants */ +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#ifndef GLEE_H_DEFINED_glDeleteFencesNV +#define GLEE_H_DEFINED_glDeleteFencesNV + typedef void (APIENTRYP GLEEPFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint * fences); + GLEE_EXTERN GLEEPFNGLDELETEFENCESNVPROC GLeeFuncPtr_glDeleteFencesNV; + #define glDeleteFencesNV GLeeFuncPtr_glDeleteFencesNV +#endif +#ifndef GLEE_H_DEFINED_glGenFencesNV +#define GLEE_H_DEFINED_glGenFencesNV + typedef void (APIENTRYP GLEEPFNGLGENFENCESNVPROC) (GLsizei n, GLuint * fences); + GLEE_EXTERN GLEEPFNGLGENFENCESNVPROC GLeeFuncPtr_glGenFencesNV; + #define glGenFencesNV GLeeFuncPtr_glGenFencesNV +#endif +#ifndef GLEE_H_DEFINED_glIsFenceNV +#define GLEE_H_DEFINED_glIsFenceNV + typedef GLboolean (APIENTRYP GLEEPFNGLISFENCENVPROC) (GLuint fence); + GLEE_EXTERN GLEEPFNGLISFENCENVPROC GLeeFuncPtr_glIsFenceNV; + #define glIsFenceNV GLeeFuncPtr_glIsFenceNV +#endif +#ifndef GLEE_H_DEFINED_glTestFenceNV +#define GLEE_H_DEFINED_glTestFenceNV + typedef GLboolean (APIENTRYP GLEEPFNGLTESTFENCENVPROC) (GLuint fence); + GLEE_EXTERN GLEEPFNGLTESTFENCENVPROC GLeeFuncPtr_glTestFenceNV; + #define glTestFenceNV GLeeFuncPtr_glTestFenceNV +#endif +#ifndef GLEE_H_DEFINED_glGetFenceivNV +#define GLEE_H_DEFINED_glGetFenceivNV + typedef void (APIENTRYP GLEEPFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFENCEIVNVPROC GLeeFuncPtr_glGetFenceivNV; + #define glGetFenceivNV GLeeFuncPtr_glGetFenceivNV +#endif +#ifndef GLEE_H_DEFINED_glFinishFenceNV +#define GLEE_H_DEFINED_glFinishFenceNV + typedef void (APIENTRYP GLEEPFNGLFINISHFENCENVPROC) (GLuint fence); + GLEE_EXTERN GLEEPFNGLFINISHFENCENVPROC GLeeFuncPtr_glFinishFenceNV; + #define glFinishFenceNV GLeeFuncPtr_glFinishFenceNV +#endif +#ifndef GLEE_H_DEFINED_glSetFenceNV +#define GLEE_H_DEFINED_glSetFenceNV + typedef void (APIENTRYP GLEEPFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); + GLEE_EXTERN GLEEPFNGLSETFENCENVPROC GLeeFuncPtr_glSetFenceNV; + #define glSetFenceNV GLeeFuncPtr_glSetFenceNV +#endif +#endif + +/* GL_IBM_texture_mirrored_repeat */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 +#define __GLEE_GL_IBM_texture_mirrored_repeat 1 +/* Constants */ +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +/* GL_NV_evaluators */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#define __GLEE_GL_NV_evaluators 1 +/* Constants */ +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#ifndef GLEE_H_DEFINED_glMapControlPointsNV +#define GLEE_H_DEFINED_glMapControlPointsNV + typedef void (APIENTRYP GLEEPFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid * points); + GLEE_EXTERN GLEEPFNGLMAPCONTROLPOINTSNVPROC GLeeFuncPtr_glMapControlPointsNV; + #define glMapControlPointsNV GLeeFuncPtr_glMapControlPointsNV +#endif +#ifndef GLEE_H_DEFINED_glMapParameterivNV +#define GLEE_H_DEFINED_glMapParameterivNV + typedef void (APIENTRYP GLEEPFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLMAPPARAMETERIVNVPROC GLeeFuncPtr_glMapParameterivNV; + #define glMapParameterivNV GLeeFuncPtr_glMapParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glMapParameterfvNV +#define GLEE_H_DEFINED_glMapParameterfvNV + typedef void (APIENTRYP GLEEPFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLMAPPARAMETERFVNVPROC GLeeFuncPtr_glMapParameterfvNV; + #define glMapParameterfvNV GLeeFuncPtr_glMapParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetMapControlPointsNV +#define GLEE_H_DEFINED_glGetMapControlPointsNV + typedef void (APIENTRYP GLEEPFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid * points); + GLEE_EXTERN GLEEPFNGLGETMAPCONTROLPOINTSNVPROC GLeeFuncPtr_glGetMapControlPointsNV; + #define glGetMapControlPointsNV GLeeFuncPtr_glGetMapControlPointsNV +#endif +#ifndef GLEE_H_DEFINED_glGetMapParameterivNV +#define GLEE_H_DEFINED_glGetMapParameterivNV + typedef void (APIENTRYP GLEEPFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMAPPARAMETERIVNVPROC GLeeFuncPtr_glGetMapParameterivNV; + #define glGetMapParameterivNV GLeeFuncPtr_glGetMapParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glGetMapParameterfvNV +#define GLEE_H_DEFINED_glGetMapParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMAPPARAMETERFVNVPROC GLeeFuncPtr_glGetMapParameterfvNV; + #define glGetMapParameterfvNV GLeeFuncPtr_glGetMapParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetMapAttribParameterivNV +#define GLEE_H_DEFINED_glGetMapAttribParameterivNV + typedef void (APIENTRYP GLEEPFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMAPATTRIBPARAMETERIVNVPROC GLeeFuncPtr_glGetMapAttribParameterivNV; + #define glGetMapAttribParameterivNV GLeeFuncPtr_glGetMapAttribParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glGetMapAttribParameterfvNV +#define GLEE_H_DEFINED_glGetMapAttribParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMAPATTRIBPARAMETERFVNVPROC GLeeFuncPtr_glGetMapAttribParameterfvNV; + #define glGetMapAttribParameterfvNV GLeeFuncPtr_glGetMapAttribParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glEvalMapsNV +#define GLEE_H_DEFINED_glEvalMapsNV + typedef void (APIENTRYP GLEEPFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); + GLEE_EXTERN GLEEPFNGLEVALMAPSNVPROC GLeeFuncPtr_glEvalMapsNV; + #define glEvalMapsNV GLeeFuncPtr_glEvalMapsNV +#endif +#endif + +/* GL_NV_packed_depth_stencil */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#define __GLEE_GL_NV_packed_depth_stencil 1 +/* Constants */ +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +/* GL_NV_register_combiners2 */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#define __GLEE_GL_NV_register_combiners2 1 +/* Constants */ +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#ifndef GLEE_H_DEFINED_glCombinerStageParameterfvNV +#define GLEE_H_DEFINED_glCombinerStageParameterfvNV + typedef void (APIENTRYP GLEEPFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLCOMBINERSTAGEPARAMETERFVNVPROC GLeeFuncPtr_glCombinerStageParameterfvNV; + #define glCombinerStageParameterfvNV GLeeFuncPtr_glCombinerStageParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetCombinerStageParameterfvNV +#define GLEE_H_DEFINED_glGetCombinerStageParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC GLeeFuncPtr_glGetCombinerStageParameterfvNV; + #define glGetCombinerStageParameterfvNV GLeeFuncPtr_glGetCombinerStageParameterfvNV +#endif +#endif + +/* GL_NV_texture_compression_vtc */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#define __GLEE_GL_NV_texture_compression_vtc 1 +/* Constants */ +#endif + +/* GL_NV_texture_rectangle */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#define __GLEE_GL_NV_texture_rectangle 1 +/* Constants */ +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +/* GL_NV_texture_shader */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#define __GLEE_GL_NV_texture_shader 1 +/* Constants */ +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +/* GL_NV_texture_shader2 */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#define __GLEE_GL_NV_texture_shader2 1 +/* Constants */ +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +/* GL_NV_vertex_array_range2 */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#define __GLEE_GL_NV_vertex_array_range2 1 +/* Constants */ +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +/* GL_NV_vertex_program */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#define __GLEE_GL_NV_vertex_program 1 +/* Constants */ +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#ifndef GLEE_H_DEFINED_glAreProgramsResidentNV +#define GLEE_H_DEFINED_glAreProgramsResidentNV + typedef GLboolean (APIENTRYP GLEEPFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint * programs, GLboolean * residences); + GLEE_EXTERN GLEEPFNGLAREPROGRAMSRESIDENTNVPROC GLeeFuncPtr_glAreProgramsResidentNV; + #define glAreProgramsResidentNV GLeeFuncPtr_glAreProgramsResidentNV +#endif +#ifndef GLEE_H_DEFINED_glBindProgramNV +#define GLEE_H_DEFINED_glBindProgramNV + typedef void (APIENTRYP GLEEPFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); + GLEE_EXTERN GLEEPFNGLBINDPROGRAMNVPROC GLeeFuncPtr_glBindProgramNV; + #define glBindProgramNV GLeeFuncPtr_glBindProgramNV +#endif +#ifndef GLEE_H_DEFINED_glDeleteProgramsNV +#define GLEE_H_DEFINED_glDeleteProgramsNV + typedef void (APIENTRYP GLEEPFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint * programs); + GLEE_EXTERN GLEEPFNGLDELETEPROGRAMSNVPROC GLeeFuncPtr_glDeleteProgramsNV; + #define glDeleteProgramsNV GLeeFuncPtr_glDeleteProgramsNV +#endif +#ifndef GLEE_H_DEFINED_glExecuteProgramNV +#define GLEE_H_DEFINED_glExecuteProgramNV + typedef void (APIENTRYP GLEEPFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLEXECUTEPROGRAMNVPROC GLeeFuncPtr_glExecuteProgramNV; + #define glExecuteProgramNV GLeeFuncPtr_glExecuteProgramNV +#endif +#ifndef GLEE_H_DEFINED_glGenProgramsNV +#define GLEE_H_DEFINED_glGenProgramsNV + typedef void (APIENTRYP GLEEPFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint * programs); + GLEE_EXTERN GLEEPFNGLGENPROGRAMSNVPROC GLeeFuncPtr_glGenProgramsNV; + #define glGenProgramsNV GLeeFuncPtr_glGenProgramsNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramParameterdvNV +#define GLEE_H_DEFINED_glGetProgramParameterdvNV + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMPARAMETERDVNVPROC GLeeFuncPtr_glGetProgramParameterdvNV; + #define glGetProgramParameterdvNV GLeeFuncPtr_glGetProgramParameterdvNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramParameterfvNV +#define GLEE_H_DEFINED_glGetProgramParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMPARAMETERFVNVPROC GLeeFuncPtr_glGetProgramParameterfvNV; + #define glGetProgramParameterfvNV GLeeFuncPtr_glGetProgramParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramivNV +#define GLEE_H_DEFINED_glGetProgramivNV + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMIVNVPROC GLeeFuncPtr_glGetProgramivNV; + #define glGetProgramivNV GLeeFuncPtr_glGetProgramivNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramStringNV +#define GLEE_H_DEFINED_glGetProgramStringNV + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte * program); + GLEE_EXTERN GLEEPFNGLGETPROGRAMSTRINGNVPROC GLeeFuncPtr_glGetProgramStringNV; + #define glGetProgramStringNV GLeeFuncPtr_glGetProgramStringNV +#endif +#ifndef GLEE_H_DEFINED_glGetTrackMatrixivNV +#define GLEE_H_DEFINED_glGetTrackMatrixivNV + typedef void (APIENTRYP GLEEPFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETTRACKMATRIXIVNVPROC GLeeFuncPtr_glGetTrackMatrixivNV; + #define glGetTrackMatrixivNV GLeeFuncPtr_glGetTrackMatrixivNV +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribdvNV +#define GLEE_H_DEFINED_glGetVertexAttribdvNV + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBDVNVPROC GLeeFuncPtr_glGetVertexAttribdvNV; + #define glGetVertexAttribdvNV GLeeFuncPtr_glGetVertexAttribdvNV +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribfvNV +#define GLEE_H_DEFINED_glGetVertexAttribfvNV + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBFVNVPROC GLeeFuncPtr_glGetVertexAttribfvNV; + #define glGetVertexAttribfvNV GLeeFuncPtr_glGetVertexAttribfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribivNV +#define GLEE_H_DEFINED_glGetVertexAttribivNV + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBIVNVPROC GLeeFuncPtr_glGetVertexAttribivNV; + #define glGetVertexAttribivNV GLeeFuncPtr_glGetVertexAttribivNV +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribPointervNV +#define GLEE_H_DEFINED_glGetVertexAttribPointervNV + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* * pointer); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBPOINTERVNVPROC GLeeFuncPtr_glGetVertexAttribPointervNV; + #define glGetVertexAttribPointervNV GLeeFuncPtr_glGetVertexAttribPointervNV +#endif +#ifndef GLEE_H_DEFINED_glIsProgramNV +#define GLEE_H_DEFINED_glIsProgramNV + typedef GLboolean (APIENTRYP GLEEPFNGLISPROGRAMNVPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLISPROGRAMNVPROC GLeeFuncPtr_glIsProgramNV; + #define glIsProgramNV GLeeFuncPtr_glIsProgramNV +#endif +#ifndef GLEE_H_DEFINED_glLoadProgramNV +#define GLEE_H_DEFINED_glLoadProgramNV + typedef void (APIENTRYP GLEEPFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte * program); + GLEE_EXTERN GLEEPFNGLLOADPROGRAMNVPROC GLeeFuncPtr_glLoadProgramNV; + #define glLoadProgramNV GLeeFuncPtr_glLoadProgramNV +#endif +#ifndef GLEE_H_DEFINED_glProgramParameter4dNV +#define GLEE_H_DEFINED_glProgramParameter4dNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETER4DNVPROC GLeeFuncPtr_glProgramParameter4dNV; + #define glProgramParameter4dNV GLeeFuncPtr_glProgramParameter4dNV +#endif +#ifndef GLEE_H_DEFINED_glProgramParameter4dvNV +#define GLEE_H_DEFINED_glProgramParameter4dvNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETER4DVNVPROC GLeeFuncPtr_glProgramParameter4dvNV; + #define glProgramParameter4dvNV GLeeFuncPtr_glProgramParameter4dvNV +#endif +#ifndef GLEE_H_DEFINED_glProgramParameter4fNV +#define GLEE_H_DEFINED_glProgramParameter4fNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETER4FNVPROC GLeeFuncPtr_glProgramParameter4fNV; + #define glProgramParameter4fNV GLeeFuncPtr_glProgramParameter4fNV +#endif +#ifndef GLEE_H_DEFINED_glProgramParameter4fvNV +#define GLEE_H_DEFINED_glProgramParameter4fvNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETER4FVNVPROC GLeeFuncPtr_glProgramParameter4fvNV; + #define glProgramParameter4fvNV GLeeFuncPtr_glProgramParameter4fvNV +#endif +#ifndef GLEE_H_DEFINED_glProgramParameters4dvNV +#define GLEE_H_DEFINED_glProgramParameters4dvNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETERS4DVNVPROC GLeeFuncPtr_glProgramParameters4dvNV; + #define glProgramParameters4dvNV GLeeFuncPtr_glProgramParameters4dvNV +#endif +#ifndef GLEE_H_DEFINED_glProgramParameters4fvNV +#define GLEE_H_DEFINED_glProgramParameters4fvNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETERS4FVNVPROC GLeeFuncPtr_glProgramParameters4fvNV; + #define glProgramParameters4fvNV GLeeFuncPtr_glProgramParameters4fvNV +#endif +#ifndef GLEE_H_DEFINED_glRequestResidentProgramsNV +#define GLEE_H_DEFINED_glRequestResidentProgramsNV + typedef void (APIENTRYP GLEEPFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint * programs); + GLEE_EXTERN GLEEPFNGLREQUESTRESIDENTPROGRAMSNVPROC GLeeFuncPtr_glRequestResidentProgramsNV; + #define glRequestResidentProgramsNV GLeeFuncPtr_glRequestResidentProgramsNV +#endif +#ifndef GLEE_H_DEFINED_glTrackMatrixNV +#define GLEE_H_DEFINED_glTrackMatrixNV + typedef void (APIENTRYP GLEEPFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); + GLEE_EXTERN GLEEPFNGLTRACKMATRIXNVPROC GLeeFuncPtr_glTrackMatrixNV; + #define glTrackMatrixNV GLeeFuncPtr_glTrackMatrixNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribPointerNV +#define GLEE_H_DEFINED_glVertexAttribPointerNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBPOINTERNVPROC GLeeFuncPtr_glVertexAttribPointerNV; + #define glVertexAttribPointerNV GLeeFuncPtr_glVertexAttribPointerNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1dNV +#define GLEE_H_DEFINED_glVertexAttrib1dNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1DNVPROC GLeeFuncPtr_glVertexAttrib1dNV; + #define glVertexAttrib1dNV GLeeFuncPtr_glVertexAttrib1dNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1dvNV +#define GLEE_H_DEFINED_glVertexAttrib1dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1DVNVPROC GLeeFuncPtr_glVertexAttrib1dvNV; + #define glVertexAttrib1dvNV GLeeFuncPtr_glVertexAttrib1dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1fNV +#define GLEE_H_DEFINED_glVertexAttrib1fNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1FNVPROC GLeeFuncPtr_glVertexAttrib1fNV; + #define glVertexAttrib1fNV GLeeFuncPtr_glVertexAttrib1fNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1fvNV +#define GLEE_H_DEFINED_glVertexAttrib1fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1FVNVPROC GLeeFuncPtr_glVertexAttrib1fvNV; + #define glVertexAttrib1fvNV GLeeFuncPtr_glVertexAttrib1fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1sNV +#define GLEE_H_DEFINED_glVertexAttrib1sNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1SNVPROC GLeeFuncPtr_glVertexAttrib1sNV; + #define glVertexAttrib1sNV GLeeFuncPtr_glVertexAttrib1sNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1svNV +#define GLEE_H_DEFINED_glVertexAttrib1svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1SVNVPROC GLeeFuncPtr_glVertexAttrib1svNV; + #define glVertexAttrib1svNV GLeeFuncPtr_glVertexAttrib1svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2dNV +#define GLEE_H_DEFINED_glVertexAttrib2dNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2DNVPROC GLeeFuncPtr_glVertexAttrib2dNV; + #define glVertexAttrib2dNV GLeeFuncPtr_glVertexAttrib2dNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2dvNV +#define GLEE_H_DEFINED_glVertexAttrib2dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2DVNVPROC GLeeFuncPtr_glVertexAttrib2dvNV; + #define glVertexAttrib2dvNV GLeeFuncPtr_glVertexAttrib2dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2fNV +#define GLEE_H_DEFINED_glVertexAttrib2fNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2FNVPROC GLeeFuncPtr_glVertexAttrib2fNV; + #define glVertexAttrib2fNV GLeeFuncPtr_glVertexAttrib2fNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2fvNV +#define GLEE_H_DEFINED_glVertexAttrib2fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2FVNVPROC GLeeFuncPtr_glVertexAttrib2fvNV; + #define glVertexAttrib2fvNV GLeeFuncPtr_glVertexAttrib2fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2sNV +#define GLEE_H_DEFINED_glVertexAttrib2sNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2SNVPROC GLeeFuncPtr_glVertexAttrib2sNV; + #define glVertexAttrib2sNV GLeeFuncPtr_glVertexAttrib2sNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2svNV +#define GLEE_H_DEFINED_glVertexAttrib2svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2SVNVPROC GLeeFuncPtr_glVertexAttrib2svNV; + #define glVertexAttrib2svNV GLeeFuncPtr_glVertexAttrib2svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3dNV +#define GLEE_H_DEFINED_glVertexAttrib3dNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3DNVPROC GLeeFuncPtr_glVertexAttrib3dNV; + #define glVertexAttrib3dNV GLeeFuncPtr_glVertexAttrib3dNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3dvNV +#define GLEE_H_DEFINED_glVertexAttrib3dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3DVNVPROC GLeeFuncPtr_glVertexAttrib3dvNV; + #define glVertexAttrib3dvNV GLeeFuncPtr_glVertexAttrib3dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3fNV +#define GLEE_H_DEFINED_glVertexAttrib3fNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3FNVPROC GLeeFuncPtr_glVertexAttrib3fNV; + #define glVertexAttrib3fNV GLeeFuncPtr_glVertexAttrib3fNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3fvNV +#define GLEE_H_DEFINED_glVertexAttrib3fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3FVNVPROC GLeeFuncPtr_glVertexAttrib3fvNV; + #define glVertexAttrib3fvNV GLeeFuncPtr_glVertexAttrib3fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3sNV +#define GLEE_H_DEFINED_glVertexAttrib3sNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3SNVPROC GLeeFuncPtr_glVertexAttrib3sNV; + #define glVertexAttrib3sNV GLeeFuncPtr_glVertexAttrib3sNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3svNV +#define GLEE_H_DEFINED_glVertexAttrib3svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3SVNVPROC GLeeFuncPtr_glVertexAttrib3svNV; + #define glVertexAttrib3svNV GLeeFuncPtr_glVertexAttrib3svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4dNV +#define GLEE_H_DEFINED_glVertexAttrib4dNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4DNVPROC GLeeFuncPtr_glVertexAttrib4dNV; + #define glVertexAttrib4dNV GLeeFuncPtr_glVertexAttrib4dNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4dvNV +#define GLEE_H_DEFINED_glVertexAttrib4dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4DVNVPROC GLeeFuncPtr_glVertexAttrib4dvNV; + #define glVertexAttrib4dvNV GLeeFuncPtr_glVertexAttrib4dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4fNV +#define GLEE_H_DEFINED_glVertexAttrib4fNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4FNVPROC GLeeFuncPtr_glVertexAttrib4fNV; + #define glVertexAttrib4fNV GLeeFuncPtr_glVertexAttrib4fNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4fvNV +#define GLEE_H_DEFINED_glVertexAttrib4fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4FVNVPROC GLeeFuncPtr_glVertexAttrib4fvNV; + #define glVertexAttrib4fvNV GLeeFuncPtr_glVertexAttrib4fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4sNV +#define GLEE_H_DEFINED_glVertexAttrib4sNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4SNVPROC GLeeFuncPtr_glVertexAttrib4sNV; + #define glVertexAttrib4sNV GLeeFuncPtr_glVertexAttrib4sNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4svNV +#define GLEE_H_DEFINED_glVertexAttrib4svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4SVNVPROC GLeeFuncPtr_glVertexAttrib4svNV; + #define glVertexAttrib4svNV GLeeFuncPtr_glVertexAttrib4svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4ubNV +#define GLEE_H_DEFINED_glVertexAttrib4ubNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4UBNVPROC GLeeFuncPtr_glVertexAttrib4ubNV; + #define glVertexAttrib4ubNV GLeeFuncPtr_glVertexAttrib4ubNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4ubvNV +#define GLEE_H_DEFINED_glVertexAttrib4ubvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4UBVNVPROC GLeeFuncPtr_glVertexAttrib4ubvNV; + #define glVertexAttrib4ubvNV GLeeFuncPtr_glVertexAttrib4ubvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs1dvNV +#define GLEE_H_DEFINED_glVertexAttribs1dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS1DVNVPROC GLeeFuncPtr_glVertexAttribs1dvNV; + #define glVertexAttribs1dvNV GLeeFuncPtr_glVertexAttribs1dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs1fvNV +#define GLEE_H_DEFINED_glVertexAttribs1fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS1FVNVPROC GLeeFuncPtr_glVertexAttribs1fvNV; + #define glVertexAttribs1fvNV GLeeFuncPtr_glVertexAttribs1fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs1svNV +#define GLEE_H_DEFINED_glVertexAttribs1svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS1SVNVPROC GLeeFuncPtr_glVertexAttribs1svNV; + #define glVertexAttribs1svNV GLeeFuncPtr_glVertexAttribs1svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs2dvNV +#define GLEE_H_DEFINED_glVertexAttribs2dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS2DVNVPROC GLeeFuncPtr_glVertexAttribs2dvNV; + #define glVertexAttribs2dvNV GLeeFuncPtr_glVertexAttribs2dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs2fvNV +#define GLEE_H_DEFINED_glVertexAttribs2fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS2FVNVPROC GLeeFuncPtr_glVertexAttribs2fvNV; + #define glVertexAttribs2fvNV GLeeFuncPtr_glVertexAttribs2fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs2svNV +#define GLEE_H_DEFINED_glVertexAttribs2svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS2SVNVPROC GLeeFuncPtr_glVertexAttribs2svNV; + #define glVertexAttribs2svNV GLeeFuncPtr_glVertexAttribs2svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs3dvNV +#define GLEE_H_DEFINED_glVertexAttribs3dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS3DVNVPROC GLeeFuncPtr_glVertexAttribs3dvNV; + #define glVertexAttribs3dvNV GLeeFuncPtr_glVertexAttribs3dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs3fvNV +#define GLEE_H_DEFINED_glVertexAttribs3fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS3FVNVPROC GLeeFuncPtr_glVertexAttribs3fvNV; + #define glVertexAttribs3fvNV GLeeFuncPtr_glVertexAttribs3fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs3svNV +#define GLEE_H_DEFINED_glVertexAttribs3svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS3SVNVPROC GLeeFuncPtr_glVertexAttribs3svNV; + #define glVertexAttribs3svNV GLeeFuncPtr_glVertexAttribs3svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs4dvNV +#define GLEE_H_DEFINED_glVertexAttribs4dvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS4DVNVPROC GLeeFuncPtr_glVertexAttribs4dvNV; + #define glVertexAttribs4dvNV GLeeFuncPtr_glVertexAttribs4dvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs4fvNV +#define GLEE_H_DEFINED_glVertexAttribs4fvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS4FVNVPROC GLeeFuncPtr_glVertexAttribs4fvNV; + #define glVertexAttribs4fvNV GLeeFuncPtr_glVertexAttribs4fvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs4svNV +#define GLEE_H_DEFINED_glVertexAttribs4svNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS4SVNVPROC GLeeFuncPtr_glVertexAttribs4svNV; + #define glVertexAttribs4svNV GLeeFuncPtr_glVertexAttribs4svNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs4ubvNV +#define GLEE_H_DEFINED_glVertexAttribs4ubvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS4UBVNVPROC GLeeFuncPtr_glVertexAttribs4ubvNV; + #define glVertexAttribs4ubvNV GLeeFuncPtr_glVertexAttribs4ubvNV +#endif +#endif + +/* GL_SGIX_texture_coordinate_clamp */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#define __GLEE_GL_SGIX_texture_coordinate_clamp 1 +/* Constants */ +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +/* GL_SGIX_scalebias_hint */ + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#define __GLEE_GL_SGIX_scalebias_hint 1 +/* Constants */ +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +/* GL_OML_interlace */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#define __GLEE_GL_OML_interlace 1 +/* Constants */ +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +/* GL_OML_subsample */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#define __GLEE_GL_OML_subsample 1 +/* Constants */ +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +/* GL_OML_resample */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#define __GLEE_GL_OML_resample 1 +/* Constants */ +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +/* GL_NV_copy_depth_to_color */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#define __GLEE_GL_NV_copy_depth_to_color 1 +/* Constants */ +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +/* GL_ATI_envmap_bumpmap */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#define __GLEE_GL_ATI_envmap_bumpmap 1 +/* Constants */ +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#ifndef GLEE_H_DEFINED_glTexBumpParameterivATI +#define GLEE_H_DEFINED_glTexBumpParameterivATI + typedef void (APIENTRYP GLEEPFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint * param); + GLEE_EXTERN GLEEPFNGLTEXBUMPPARAMETERIVATIPROC GLeeFuncPtr_glTexBumpParameterivATI; + #define glTexBumpParameterivATI GLeeFuncPtr_glTexBumpParameterivATI +#endif +#ifndef GLEE_H_DEFINED_glTexBumpParameterfvATI +#define GLEE_H_DEFINED_glTexBumpParameterfvATI + typedef void (APIENTRYP GLEEPFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat * param); + GLEE_EXTERN GLEEPFNGLTEXBUMPPARAMETERFVATIPROC GLeeFuncPtr_glTexBumpParameterfvATI; + #define glTexBumpParameterfvATI GLeeFuncPtr_glTexBumpParameterfvATI +#endif +#ifndef GLEE_H_DEFINED_glGetTexBumpParameterivATI +#define GLEE_H_DEFINED_glGetTexBumpParameterivATI + typedef void (APIENTRYP GLEEPFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint * param); + GLEE_EXTERN GLEEPFNGLGETTEXBUMPPARAMETERIVATIPROC GLeeFuncPtr_glGetTexBumpParameterivATI; + #define glGetTexBumpParameterivATI GLeeFuncPtr_glGetTexBumpParameterivATI +#endif +#ifndef GLEE_H_DEFINED_glGetTexBumpParameterfvATI +#define GLEE_H_DEFINED_glGetTexBumpParameterfvATI + typedef void (APIENTRYP GLEEPFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat * param); + GLEE_EXTERN GLEEPFNGLGETTEXBUMPPARAMETERFVATIPROC GLeeFuncPtr_glGetTexBumpParameterfvATI; + #define glGetTexBumpParameterfvATI GLeeFuncPtr_glGetTexBumpParameterfvATI +#endif +#endif + +/* GL_ATI_fragment_shader */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#define __GLEE_GL_ATI_fragment_shader 1 +/* Constants */ +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#ifndef GLEE_H_DEFINED_glGenFragmentShadersATI +#define GLEE_H_DEFINED_glGenFragmentShadersATI + typedef GLuint (APIENTRYP GLEEPFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); + GLEE_EXTERN GLEEPFNGLGENFRAGMENTSHADERSATIPROC GLeeFuncPtr_glGenFragmentShadersATI; + #define glGenFragmentShadersATI GLeeFuncPtr_glGenFragmentShadersATI +#endif +#ifndef GLEE_H_DEFINED_glBindFragmentShaderATI +#define GLEE_H_DEFINED_glBindFragmentShaderATI + typedef void (APIENTRYP GLEEPFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLBINDFRAGMENTSHADERATIPROC GLeeFuncPtr_glBindFragmentShaderATI; + #define glBindFragmentShaderATI GLeeFuncPtr_glBindFragmentShaderATI +#endif +#ifndef GLEE_H_DEFINED_glDeleteFragmentShaderATI +#define GLEE_H_DEFINED_glDeleteFragmentShaderATI + typedef void (APIENTRYP GLEEPFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLDELETEFRAGMENTSHADERATIPROC GLeeFuncPtr_glDeleteFragmentShaderATI; + #define glDeleteFragmentShaderATI GLeeFuncPtr_glDeleteFragmentShaderATI +#endif +#ifndef GLEE_H_DEFINED_glBeginFragmentShaderATI +#define GLEE_H_DEFINED_glBeginFragmentShaderATI + typedef void (APIENTRYP GLEEPFNGLBEGINFRAGMENTSHADERATIPROC) (); + GLEE_EXTERN GLEEPFNGLBEGINFRAGMENTSHADERATIPROC GLeeFuncPtr_glBeginFragmentShaderATI; + #define glBeginFragmentShaderATI GLeeFuncPtr_glBeginFragmentShaderATI +#endif +#ifndef GLEE_H_DEFINED_glEndFragmentShaderATI +#define GLEE_H_DEFINED_glEndFragmentShaderATI + typedef void (APIENTRYP GLEEPFNGLENDFRAGMENTSHADERATIPROC) (); + GLEE_EXTERN GLEEPFNGLENDFRAGMENTSHADERATIPROC GLeeFuncPtr_glEndFragmentShaderATI; + #define glEndFragmentShaderATI GLeeFuncPtr_glEndFragmentShaderATI +#endif +#ifndef GLEE_H_DEFINED_glPassTexCoordATI +#define GLEE_H_DEFINED_glPassTexCoordATI + typedef void (APIENTRYP GLEEPFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); + GLEE_EXTERN GLEEPFNGLPASSTEXCOORDATIPROC GLeeFuncPtr_glPassTexCoordATI; + #define glPassTexCoordATI GLeeFuncPtr_glPassTexCoordATI +#endif +#ifndef GLEE_H_DEFINED_glSampleMapATI +#define GLEE_H_DEFINED_glSampleMapATI + typedef void (APIENTRYP GLEEPFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); + GLEE_EXTERN GLEEPFNGLSAMPLEMAPATIPROC GLeeFuncPtr_glSampleMapATI; + #define glSampleMapATI GLeeFuncPtr_glSampleMapATI +#endif +#ifndef GLEE_H_DEFINED_glColorFragmentOp1ATI +#define GLEE_H_DEFINED_glColorFragmentOp1ATI + typedef void (APIENTRYP GLEEPFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); + GLEE_EXTERN GLEEPFNGLCOLORFRAGMENTOP1ATIPROC GLeeFuncPtr_glColorFragmentOp1ATI; + #define glColorFragmentOp1ATI GLeeFuncPtr_glColorFragmentOp1ATI +#endif +#ifndef GLEE_H_DEFINED_glColorFragmentOp2ATI +#define GLEE_H_DEFINED_glColorFragmentOp2ATI + typedef void (APIENTRYP GLEEPFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); + GLEE_EXTERN GLEEPFNGLCOLORFRAGMENTOP2ATIPROC GLeeFuncPtr_glColorFragmentOp2ATI; + #define glColorFragmentOp2ATI GLeeFuncPtr_glColorFragmentOp2ATI +#endif +#ifndef GLEE_H_DEFINED_glColorFragmentOp3ATI +#define GLEE_H_DEFINED_glColorFragmentOp3ATI + typedef void (APIENTRYP GLEEPFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); + GLEE_EXTERN GLEEPFNGLCOLORFRAGMENTOP3ATIPROC GLeeFuncPtr_glColorFragmentOp3ATI; + #define glColorFragmentOp3ATI GLeeFuncPtr_glColorFragmentOp3ATI +#endif +#ifndef GLEE_H_DEFINED_glAlphaFragmentOp1ATI +#define GLEE_H_DEFINED_glAlphaFragmentOp1ATI + typedef void (APIENTRYP GLEEPFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); + GLEE_EXTERN GLEEPFNGLALPHAFRAGMENTOP1ATIPROC GLeeFuncPtr_glAlphaFragmentOp1ATI; + #define glAlphaFragmentOp1ATI GLeeFuncPtr_glAlphaFragmentOp1ATI +#endif +#ifndef GLEE_H_DEFINED_glAlphaFragmentOp2ATI +#define GLEE_H_DEFINED_glAlphaFragmentOp2ATI + typedef void (APIENTRYP GLEEPFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); + GLEE_EXTERN GLEEPFNGLALPHAFRAGMENTOP2ATIPROC GLeeFuncPtr_glAlphaFragmentOp2ATI; + #define glAlphaFragmentOp2ATI GLeeFuncPtr_glAlphaFragmentOp2ATI +#endif +#ifndef GLEE_H_DEFINED_glAlphaFragmentOp3ATI +#define GLEE_H_DEFINED_glAlphaFragmentOp3ATI + typedef void (APIENTRYP GLEEPFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); + GLEE_EXTERN GLEEPFNGLALPHAFRAGMENTOP3ATIPROC GLeeFuncPtr_glAlphaFragmentOp3ATI; + #define glAlphaFragmentOp3ATI GLeeFuncPtr_glAlphaFragmentOp3ATI +#endif +#ifndef GLEE_H_DEFINED_glSetFragmentShaderConstantATI +#define GLEE_H_DEFINED_glSetFragmentShaderConstantATI + typedef void (APIENTRYP GLEEPFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLSETFRAGMENTSHADERCONSTANTATIPROC GLeeFuncPtr_glSetFragmentShaderConstantATI; + #define glSetFragmentShaderConstantATI GLeeFuncPtr_glSetFragmentShaderConstantATI +#endif +#endif + +/* GL_ATI_pn_triangles */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#define __GLEE_GL_ATI_pn_triangles 1 +/* Constants */ +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#ifndef GLEE_H_DEFINED_glPNTrianglesiATI +#define GLEE_H_DEFINED_glPNTrianglesiATI + typedef void (APIENTRYP GLEEPFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLPNTRIANGLESIATIPROC GLeeFuncPtr_glPNTrianglesiATI; + #define glPNTrianglesiATI GLeeFuncPtr_glPNTrianglesiATI +#endif +#ifndef GLEE_H_DEFINED_glPNTrianglesfATI +#define GLEE_H_DEFINED_glPNTrianglesfATI + typedef void (APIENTRYP GLEEPFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLPNTRIANGLESFATIPROC GLeeFuncPtr_glPNTrianglesfATI; + #define glPNTrianglesfATI GLeeFuncPtr_glPNTrianglesfATI +#endif +#endif + +/* GL_ATI_vertex_array_object */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#define __GLEE_GL_ATI_vertex_array_object 1 +/* Constants */ +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#ifndef GLEE_H_DEFINED_glNewObjectBufferATI +#define GLEE_H_DEFINED_glNewObjectBufferATI + typedef GLuint (APIENTRYP GLEEPFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid * pointer, GLenum usage); + GLEE_EXTERN GLEEPFNGLNEWOBJECTBUFFERATIPROC GLeeFuncPtr_glNewObjectBufferATI; + #define glNewObjectBufferATI GLeeFuncPtr_glNewObjectBufferATI +#endif +#ifndef GLEE_H_DEFINED_glIsObjectBufferATI +#define GLEE_H_DEFINED_glIsObjectBufferATI + typedef GLboolean (APIENTRYP GLEEPFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLISOBJECTBUFFERATIPROC GLeeFuncPtr_glIsObjectBufferATI; + #define glIsObjectBufferATI GLeeFuncPtr_glIsObjectBufferATI +#endif +#ifndef GLEE_H_DEFINED_glUpdateObjectBufferATI +#define GLEE_H_DEFINED_glUpdateObjectBufferATI + typedef void (APIENTRYP GLEEPFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid * pointer, GLenum preserve); + GLEE_EXTERN GLEEPFNGLUPDATEOBJECTBUFFERATIPROC GLeeFuncPtr_glUpdateObjectBufferATI; + #define glUpdateObjectBufferATI GLeeFuncPtr_glUpdateObjectBufferATI +#endif +#ifndef GLEE_H_DEFINED_glGetObjectBufferfvATI +#define GLEE_H_DEFINED_glGetObjectBufferfvATI + typedef void (APIENTRYP GLEEPFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETOBJECTBUFFERFVATIPROC GLeeFuncPtr_glGetObjectBufferfvATI; + #define glGetObjectBufferfvATI GLeeFuncPtr_glGetObjectBufferfvATI +#endif +#ifndef GLEE_H_DEFINED_glGetObjectBufferivATI +#define GLEE_H_DEFINED_glGetObjectBufferivATI + typedef void (APIENTRYP GLEEPFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETOBJECTBUFFERIVATIPROC GLeeFuncPtr_glGetObjectBufferivATI; + #define glGetObjectBufferivATI GLeeFuncPtr_glGetObjectBufferivATI +#endif +#ifndef GLEE_H_DEFINED_glFreeObjectBufferATI +#define GLEE_H_DEFINED_glFreeObjectBufferATI + typedef void (APIENTRYP GLEEPFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLFREEOBJECTBUFFERATIPROC GLeeFuncPtr_glFreeObjectBufferATI; + #define glFreeObjectBufferATI GLeeFuncPtr_glFreeObjectBufferATI +#endif +#ifndef GLEE_H_DEFINED_glArrayObjectATI +#define GLEE_H_DEFINED_glArrayObjectATI + typedef void (APIENTRYP GLEEPFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + GLEE_EXTERN GLEEPFNGLARRAYOBJECTATIPROC GLeeFuncPtr_glArrayObjectATI; + #define glArrayObjectATI GLeeFuncPtr_glArrayObjectATI +#endif +#ifndef GLEE_H_DEFINED_glGetArrayObjectfvATI +#define GLEE_H_DEFINED_glGetArrayObjectfvATI + typedef void (APIENTRYP GLEEPFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETARRAYOBJECTFVATIPROC GLeeFuncPtr_glGetArrayObjectfvATI; + #define glGetArrayObjectfvATI GLeeFuncPtr_glGetArrayObjectfvATI +#endif +#ifndef GLEE_H_DEFINED_glGetArrayObjectivATI +#define GLEE_H_DEFINED_glGetArrayObjectivATI + typedef void (APIENTRYP GLEEPFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETARRAYOBJECTIVATIPROC GLeeFuncPtr_glGetArrayObjectivATI; + #define glGetArrayObjectivATI GLeeFuncPtr_glGetArrayObjectivATI +#endif +#ifndef GLEE_H_DEFINED_glVariantArrayObjectATI +#define GLEE_H_DEFINED_glVariantArrayObjectATI + typedef void (APIENTRYP GLEEPFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + GLEE_EXTERN GLEEPFNGLVARIANTARRAYOBJECTATIPROC GLeeFuncPtr_glVariantArrayObjectATI; + #define glVariantArrayObjectATI GLeeFuncPtr_glVariantArrayObjectATI +#endif +#ifndef GLEE_H_DEFINED_glGetVariantArrayObjectfvATI +#define GLEE_H_DEFINED_glGetVariantArrayObjectfvATI + typedef void (APIENTRYP GLEEPFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETVARIANTARRAYOBJECTFVATIPROC GLeeFuncPtr_glGetVariantArrayObjectfvATI; + #define glGetVariantArrayObjectfvATI GLeeFuncPtr_glGetVariantArrayObjectfvATI +#endif +#ifndef GLEE_H_DEFINED_glGetVariantArrayObjectivATI +#define GLEE_H_DEFINED_glGetVariantArrayObjectivATI + typedef void (APIENTRYP GLEEPFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETVARIANTARRAYOBJECTIVATIPROC GLeeFuncPtr_glGetVariantArrayObjectivATI; + #define glGetVariantArrayObjectivATI GLeeFuncPtr_glGetVariantArrayObjectivATI +#endif +#endif + +/* GL_EXT_vertex_shader */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#define __GLEE_GL_EXT_vertex_shader 1 +/* Constants */ +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#ifndef GLEE_H_DEFINED_glBeginVertexShaderEXT +#define GLEE_H_DEFINED_glBeginVertexShaderEXT + typedef void (APIENTRYP GLEEPFNGLBEGINVERTEXSHADEREXTPROC) (); + GLEE_EXTERN GLEEPFNGLBEGINVERTEXSHADEREXTPROC GLeeFuncPtr_glBeginVertexShaderEXT; + #define glBeginVertexShaderEXT GLeeFuncPtr_glBeginVertexShaderEXT +#endif +#ifndef GLEE_H_DEFINED_glEndVertexShaderEXT +#define GLEE_H_DEFINED_glEndVertexShaderEXT + typedef void (APIENTRYP GLEEPFNGLENDVERTEXSHADEREXTPROC) (); + GLEE_EXTERN GLEEPFNGLENDVERTEXSHADEREXTPROC GLeeFuncPtr_glEndVertexShaderEXT; + #define glEndVertexShaderEXT GLeeFuncPtr_glEndVertexShaderEXT +#endif +#ifndef GLEE_H_DEFINED_glBindVertexShaderEXT +#define GLEE_H_DEFINED_glBindVertexShaderEXT + typedef void (APIENTRYP GLEEPFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLBINDVERTEXSHADEREXTPROC GLeeFuncPtr_glBindVertexShaderEXT; + #define glBindVertexShaderEXT GLeeFuncPtr_glBindVertexShaderEXT +#endif +#ifndef GLEE_H_DEFINED_glGenVertexShadersEXT +#define GLEE_H_DEFINED_glGenVertexShadersEXT + typedef GLuint (APIENTRYP GLEEPFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); + GLEE_EXTERN GLEEPFNGLGENVERTEXSHADERSEXTPROC GLeeFuncPtr_glGenVertexShadersEXT; + #define glGenVertexShadersEXT GLeeFuncPtr_glGenVertexShadersEXT +#endif +#ifndef GLEE_H_DEFINED_glDeleteVertexShaderEXT +#define GLEE_H_DEFINED_glDeleteVertexShaderEXT + typedef void (APIENTRYP GLEEPFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLDELETEVERTEXSHADEREXTPROC GLeeFuncPtr_glDeleteVertexShaderEXT; + #define glDeleteVertexShaderEXT GLeeFuncPtr_glDeleteVertexShaderEXT +#endif +#ifndef GLEE_H_DEFINED_glShaderOp1EXT +#define GLEE_H_DEFINED_glShaderOp1EXT + typedef void (APIENTRYP GLEEPFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); + GLEE_EXTERN GLEEPFNGLSHADEROP1EXTPROC GLeeFuncPtr_glShaderOp1EXT; + #define glShaderOp1EXT GLeeFuncPtr_glShaderOp1EXT +#endif +#ifndef GLEE_H_DEFINED_glShaderOp2EXT +#define GLEE_H_DEFINED_glShaderOp2EXT + typedef void (APIENTRYP GLEEPFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); + GLEE_EXTERN GLEEPFNGLSHADEROP2EXTPROC GLeeFuncPtr_glShaderOp2EXT; + #define glShaderOp2EXT GLeeFuncPtr_glShaderOp2EXT +#endif +#ifndef GLEE_H_DEFINED_glShaderOp3EXT +#define GLEE_H_DEFINED_glShaderOp3EXT + typedef void (APIENTRYP GLEEPFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); + GLEE_EXTERN GLEEPFNGLSHADEROP3EXTPROC GLeeFuncPtr_glShaderOp3EXT; + #define glShaderOp3EXT GLeeFuncPtr_glShaderOp3EXT +#endif +#ifndef GLEE_H_DEFINED_glSwizzleEXT +#define GLEE_H_DEFINED_glSwizzleEXT + typedef void (APIENTRYP GLEEPFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + GLEE_EXTERN GLEEPFNGLSWIZZLEEXTPROC GLeeFuncPtr_glSwizzleEXT; + #define glSwizzleEXT GLeeFuncPtr_glSwizzleEXT +#endif +#ifndef GLEE_H_DEFINED_glWriteMaskEXT +#define GLEE_H_DEFINED_glWriteMaskEXT + typedef void (APIENTRYP GLEEPFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + GLEE_EXTERN GLEEPFNGLWRITEMASKEXTPROC GLeeFuncPtr_glWriteMaskEXT; + #define glWriteMaskEXT GLeeFuncPtr_glWriteMaskEXT +#endif +#ifndef GLEE_H_DEFINED_glInsertComponentEXT +#define GLEE_H_DEFINED_glInsertComponentEXT + typedef void (APIENTRYP GLEEPFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); + GLEE_EXTERN GLEEPFNGLINSERTCOMPONENTEXTPROC GLeeFuncPtr_glInsertComponentEXT; + #define glInsertComponentEXT GLeeFuncPtr_glInsertComponentEXT +#endif +#ifndef GLEE_H_DEFINED_glExtractComponentEXT +#define GLEE_H_DEFINED_glExtractComponentEXT + typedef void (APIENTRYP GLEEPFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); + GLEE_EXTERN GLEEPFNGLEXTRACTCOMPONENTEXTPROC GLeeFuncPtr_glExtractComponentEXT; + #define glExtractComponentEXT GLeeFuncPtr_glExtractComponentEXT +#endif +#ifndef GLEE_H_DEFINED_glGenSymbolsEXT +#define GLEE_H_DEFINED_glGenSymbolsEXT + typedef GLuint (APIENTRYP GLEEPFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); + GLEE_EXTERN GLEEPFNGLGENSYMBOLSEXTPROC GLeeFuncPtr_glGenSymbolsEXT; + #define glGenSymbolsEXT GLeeFuncPtr_glGenSymbolsEXT +#endif +#ifndef GLEE_H_DEFINED_glSetInvariantEXT +#define GLEE_H_DEFINED_glSetInvariantEXT + typedef void (APIENTRYP GLEEPFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid * addr); + GLEE_EXTERN GLEEPFNGLSETINVARIANTEXTPROC GLeeFuncPtr_glSetInvariantEXT; + #define glSetInvariantEXT GLeeFuncPtr_glSetInvariantEXT +#endif +#ifndef GLEE_H_DEFINED_glSetLocalConstantEXT +#define GLEE_H_DEFINED_glSetLocalConstantEXT + typedef void (APIENTRYP GLEEPFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid * addr); + GLEE_EXTERN GLEEPFNGLSETLOCALCONSTANTEXTPROC GLeeFuncPtr_glSetLocalConstantEXT; + #define glSetLocalConstantEXT GLeeFuncPtr_glSetLocalConstantEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantbvEXT +#define GLEE_H_DEFINED_glVariantbvEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte * addr); + GLEE_EXTERN GLEEPFNGLVARIANTBVEXTPROC GLeeFuncPtr_glVariantbvEXT; + #define glVariantbvEXT GLeeFuncPtr_glVariantbvEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantsvEXT +#define GLEE_H_DEFINED_glVariantsvEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort * addr); + GLEE_EXTERN GLEEPFNGLVARIANTSVEXTPROC GLeeFuncPtr_glVariantsvEXT; + #define glVariantsvEXT GLeeFuncPtr_glVariantsvEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantivEXT +#define GLEE_H_DEFINED_glVariantivEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTIVEXTPROC) (GLuint id, const GLint * addr); + GLEE_EXTERN GLEEPFNGLVARIANTIVEXTPROC GLeeFuncPtr_glVariantivEXT; + #define glVariantivEXT GLeeFuncPtr_glVariantivEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantfvEXT +#define GLEE_H_DEFINED_glVariantfvEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat * addr); + GLEE_EXTERN GLEEPFNGLVARIANTFVEXTPROC GLeeFuncPtr_glVariantfvEXT; + #define glVariantfvEXT GLeeFuncPtr_glVariantfvEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantdvEXT +#define GLEE_H_DEFINED_glVariantdvEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble * addr); + GLEE_EXTERN GLEEPFNGLVARIANTDVEXTPROC GLeeFuncPtr_glVariantdvEXT; + #define glVariantdvEXT GLeeFuncPtr_glVariantdvEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantubvEXT +#define GLEE_H_DEFINED_glVariantubvEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte * addr); + GLEE_EXTERN GLEEPFNGLVARIANTUBVEXTPROC GLeeFuncPtr_glVariantubvEXT; + #define glVariantubvEXT GLeeFuncPtr_glVariantubvEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantusvEXT +#define GLEE_H_DEFINED_glVariantusvEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort * addr); + GLEE_EXTERN GLEEPFNGLVARIANTUSVEXTPROC GLeeFuncPtr_glVariantusvEXT; + #define glVariantusvEXT GLeeFuncPtr_glVariantusvEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantuivEXT +#define GLEE_H_DEFINED_glVariantuivEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint * addr); + GLEE_EXTERN GLEEPFNGLVARIANTUIVEXTPROC GLeeFuncPtr_glVariantuivEXT; + #define glVariantuivEXT GLeeFuncPtr_glVariantuivEXT +#endif +#ifndef GLEE_H_DEFINED_glVariantPointerEXT +#define GLEE_H_DEFINED_glVariantPointerEXT + typedef void (APIENTRYP GLEEPFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid * addr); + GLEE_EXTERN GLEEPFNGLVARIANTPOINTEREXTPROC GLeeFuncPtr_glVariantPointerEXT; + #define glVariantPointerEXT GLeeFuncPtr_glVariantPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glEnableVariantClientStateEXT +#define GLEE_H_DEFINED_glEnableVariantClientStateEXT + typedef void (APIENTRYP GLEEPFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLENABLEVARIANTCLIENTSTATEEXTPROC GLeeFuncPtr_glEnableVariantClientStateEXT; + #define glEnableVariantClientStateEXT GLeeFuncPtr_glEnableVariantClientStateEXT +#endif +#ifndef GLEE_H_DEFINED_glDisableVariantClientStateEXT +#define GLEE_H_DEFINED_glDisableVariantClientStateEXT + typedef void (APIENTRYP GLEEPFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLDISABLEVARIANTCLIENTSTATEEXTPROC GLeeFuncPtr_glDisableVariantClientStateEXT; + #define glDisableVariantClientStateEXT GLeeFuncPtr_glDisableVariantClientStateEXT +#endif +#ifndef GLEE_H_DEFINED_glBindLightParameterEXT +#define GLEE_H_DEFINED_glBindLightParameterEXT + typedef GLuint (APIENTRYP GLEEPFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); + GLEE_EXTERN GLEEPFNGLBINDLIGHTPARAMETEREXTPROC GLeeFuncPtr_glBindLightParameterEXT; + #define glBindLightParameterEXT GLeeFuncPtr_glBindLightParameterEXT +#endif +#ifndef GLEE_H_DEFINED_glBindMaterialParameterEXT +#define GLEE_H_DEFINED_glBindMaterialParameterEXT + typedef GLuint (APIENTRYP GLEEPFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); + GLEE_EXTERN GLEEPFNGLBINDMATERIALPARAMETEREXTPROC GLeeFuncPtr_glBindMaterialParameterEXT; + #define glBindMaterialParameterEXT GLeeFuncPtr_glBindMaterialParameterEXT +#endif +#ifndef GLEE_H_DEFINED_glBindTexGenParameterEXT +#define GLEE_H_DEFINED_glBindTexGenParameterEXT + typedef GLuint (APIENTRYP GLEEPFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); + GLEE_EXTERN GLEEPFNGLBINDTEXGENPARAMETEREXTPROC GLeeFuncPtr_glBindTexGenParameterEXT; + #define glBindTexGenParameterEXT GLeeFuncPtr_glBindTexGenParameterEXT +#endif +#ifndef GLEE_H_DEFINED_glBindTextureUnitParameterEXT +#define GLEE_H_DEFINED_glBindTextureUnitParameterEXT + typedef GLuint (APIENTRYP GLEEPFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); + GLEE_EXTERN GLEEPFNGLBINDTEXTUREUNITPARAMETEREXTPROC GLeeFuncPtr_glBindTextureUnitParameterEXT; + #define glBindTextureUnitParameterEXT GLeeFuncPtr_glBindTextureUnitParameterEXT +#endif +#ifndef GLEE_H_DEFINED_glBindParameterEXT +#define GLEE_H_DEFINED_glBindParameterEXT + typedef GLuint (APIENTRYP GLEEPFNGLBINDPARAMETEREXTPROC) (GLenum value); + GLEE_EXTERN GLEEPFNGLBINDPARAMETEREXTPROC GLeeFuncPtr_glBindParameterEXT; + #define glBindParameterEXT GLeeFuncPtr_glBindParameterEXT +#endif +#ifndef GLEE_H_DEFINED_glIsVariantEnabledEXT +#define GLEE_H_DEFINED_glIsVariantEnabledEXT + typedef GLboolean (APIENTRYP GLEEPFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); + GLEE_EXTERN GLEEPFNGLISVARIANTENABLEDEXTPROC GLeeFuncPtr_glIsVariantEnabledEXT; + #define glIsVariantEnabledEXT GLeeFuncPtr_glIsVariantEnabledEXT +#endif +#ifndef GLEE_H_DEFINED_glGetVariantBooleanvEXT +#define GLEE_H_DEFINED_glGetVariantBooleanvEXT + typedef void (APIENTRYP GLEEPFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean * data); + GLEE_EXTERN GLEEPFNGLGETVARIANTBOOLEANVEXTPROC GLeeFuncPtr_glGetVariantBooleanvEXT; + #define glGetVariantBooleanvEXT GLeeFuncPtr_glGetVariantBooleanvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetVariantIntegervEXT +#define GLEE_H_DEFINED_glGetVariantIntegervEXT + typedef void (APIENTRYP GLEEPFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint * data); + GLEE_EXTERN GLEEPFNGLGETVARIANTINTEGERVEXTPROC GLeeFuncPtr_glGetVariantIntegervEXT; + #define glGetVariantIntegervEXT GLeeFuncPtr_glGetVariantIntegervEXT +#endif +#ifndef GLEE_H_DEFINED_glGetVariantFloatvEXT +#define GLEE_H_DEFINED_glGetVariantFloatvEXT + typedef void (APIENTRYP GLEEPFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat * data); + GLEE_EXTERN GLEEPFNGLGETVARIANTFLOATVEXTPROC GLeeFuncPtr_glGetVariantFloatvEXT; + #define glGetVariantFloatvEXT GLeeFuncPtr_glGetVariantFloatvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetVariantPointervEXT +#define GLEE_H_DEFINED_glGetVariantPointervEXT + typedef void (APIENTRYP GLEEPFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* * data); + GLEE_EXTERN GLEEPFNGLGETVARIANTPOINTERVEXTPROC GLeeFuncPtr_glGetVariantPointervEXT; + #define glGetVariantPointervEXT GLeeFuncPtr_glGetVariantPointervEXT +#endif +#ifndef GLEE_H_DEFINED_glGetInvariantBooleanvEXT +#define GLEE_H_DEFINED_glGetInvariantBooleanvEXT + typedef void (APIENTRYP GLEEPFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean * data); + GLEE_EXTERN GLEEPFNGLGETINVARIANTBOOLEANVEXTPROC GLeeFuncPtr_glGetInvariantBooleanvEXT; + #define glGetInvariantBooleanvEXT GLeeFuncPtr_glGetInvariantBooleanvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetInvariantIntegervEXT +#define GLEE_H_DEFINED_glGetInvariantIntegervEXT + typedef void (APIENTRYP GLEEPFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint * data); + GLEE_EXTERN GLEEPFNGLGETINVARIANTINTEGERVEXTPROC GLeeFuncPtr_glGetInvariantIntegervEXT; + #define glGetInvariantIntegervEXT GLeeFuncPtr_glGetInvariantIntegervEXT +#endif +#ifndef GLEE_H_DEFINED_glGetInvariantFloatvEXT +#define GLEE_H_DEFINED_glGetInvariantFloatvEXT + typedef void (APIENTRYP GLEEPFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat * data); + GLEE_EXTERN GLEEPFNGLGETINVARIANTFLOATVEXTPROC GLeeFuncPtr_glGetInvariantFloatvEXT; + #define glGetInvariantFloatvEXT GLeeFuncPtr_glGetInvariantFloatvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetLocalConstantBooleanvEXT +#define GLEE_H_DEFINED_glGetLocalConstantBooleanvEXT + typedef void (APIENTRYP GLEEPFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean * data); + GLEE_EXTERN GLEEPFNGLGETLOCALCONSTANTBOOLEANVEXTPROC GLeeFuncPtr_glGetLocalConstantBooleanvEXT; + #define glGetLocalConstantBooleanvEXT GLeeFuncPtr_glGetLocalConstantBooleanvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetLocalConstantIntegervEXT +#define GLEE_H_DEFINED_glGetLocalConstantIntegervEXT + typedef void (APIENTRYP GLEEPFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint * data); + GLEE_EXTERN GLEEPFNGLGETLOCALCONSTANTINTEGERVEXTPROC GLeeFuncPtr_glGetLocalConstantIntegervEXT; + #define glGetLocalConstantIntegervEXT GLeeFuncPtr_glGetLocalConstantIntegervEXT +#endif +#ifndef GLEE_H_DEFINED_glGetLocalConstantFloatvEXT +#define GLEE_H_DEFINED_glGetLocalConstantFloatvEXT + typedef void (APIENTRYP GLEEPFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat * data); + GLEE_EXTERN GLEEPFNGLGETLOCALCONSTANTFLOATVEXTPROC GLeeFuncPtr_glGetLocalConstantFloatvEXT; + #define glGetLocalConstantFloatvEXT GLeeFuncPtr_glGetLocalConstantFloatvEXT +#endif +#endif + +/* GL_ATI_vertex_streams */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#define __GLEE_GL_ATI_vertex_streams 1 +/* Constants */ +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#ifndef GLEE_H_DEFINED_glVertexStream1sATI +#define GLEE_H_DEFINED_glVertexStream1sATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1SATIPROC GLeeFuncPtr_glVertexStream1sATI; + #define glVertexStream1sATI GLeeFuncPtr_glVertexStream1sATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream1svATI +#define GLEE_H_DEFINED_glVertexStream1svATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1SVATIPROC GLeeFuncPtr_glVertexStream1svATI; + #define glVertexStream1svATI GLeeFuncPtr_glVertexStream1svATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream1iATI +#define GLEE_H_DEFINED_glVertexStream1iATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1IATIPROC GLeeFuncPtr_glVertexStream1iATI; + #define glVertexStream1iATI GLeeFuncPtr_glVertexStream1iATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream1ivATI +#define GLEE_H_DEFINED_glVertexStream1ivATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1IVATIPROC GLeeFuncPtr_glVertexStream1ivATI; + #define glVertexStream1ivATI GLeeFuncPtr_glVertexStream1ivATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream1fATI +#define GLEE_H_DEFINED_glVertexStream1fATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1FATIPROC GLeeFuncPtr_glVertexStream1fATI; + #define glVertexStream1fATI GLeeFuncPtr_glVertexStream1fATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream1fvATI +#define GLEE_H_DEFINED_glVertexStream1fvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1FVATIPROC GLeeFuncPtr_glVertexStream1fvATI; + #define glVertexStream1fvATI GLeeFuncPtr_glVertexStream1fvATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream1dATI +#define GLEE_H_DEFINED_glVertexStream1dATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1DATIPROC GLeeFuncPtr_glVertexStream1dATI; + #define glVertexStream1dATI GLeeFuncPtr_glVertexStream1dATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream1dvATI +#define GLEE_H_DEFINED_glVertexStream1dvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM1DVATIPROC GLeeFuncPtr_glVertexStream1dvATI; + #define glVertexStream1dvATI GLeeFuncPtr_glVertexStream1dvATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2sATI +#define GLEE_H_DEFINED_glVertexStream2sATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2SATIPROC GLeeFuncPtr_glVertexStream2sATI; + #define glVertexStream2sATI GLeeFuncPtr_glVertexStream2sATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2svATI +#define GLEE_H_DEFINED_glVertexStream2svATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2SVATIPROC GLeeFuncPtr_glVertexStream2svATI; + #define glVertexStream2svATI GLeeFuncPtr_glVertexStream2svATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2iATI +#define GLEE_H_DEFINED_glVertexStream2iATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2IATIPROC GLeeFuncPtr_glVertexStream2iATI; + #define glVertexStream2iATI GLeeFuncPtr_glVertexStream2iATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2ivATI +#define GLEE_H_DEFINED_glVertexStream2ivATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2IVATIPROC GLeeFuncPtr_glVertexStream2ivATI; + #define glVertexStream2ivATI GLeeFuncPtr_glVertexStream2ivATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2fATI +#define GLEE_H_DEFINED_glVertexStream2fATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2FATIPROC GLeeFuncPtr_glVertexStream2fATI; + #define glVertexStream2fATI GLeeFuncPtr_glVertexStream2fATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2fvATI +#define GLEE_H_DEFINED_glVertexStream2fvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2FVATIPROC GLeeFuncPtr_glVertexStream2fvATI; + #define glVertexStream2fvATI GLeeFuncPtr_glVertexStream2fvATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2dATI +#define GLEE_H_DEFINED_glVertexStream2dATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2DATIPROC GLeeFuncPtr_glVertexStream2dATI; + #define glVertexStream2dATI GLeeFuncPtr_glVertexStream2dATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream2dvATI +#define GLEE_H_DEFINED_glVertexStream2dvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM2DVATIPROC GLeeFuncPtr_glVertexStream2dvATI; + #define glVertexStream2dvATI GLeeFuncPtr_glVertexStream2dvATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3sATI +#define GLEE_H_DEFINED_glVertexStream3sATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3SATIPROC GLeeFuncPtr_glVertexStream3sATI; + #define glVertexStream3sATI GLeeFuncPtr_glVertexStream3sATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3svATI +#define GLEE_H_DEFINED_glVertexStream3svATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3SVATIPROC GLeeFuncPtr_glVertexStream3svATI; + #define glVertexStream3svATI GLeeFuncPtr_glVertexStream3svATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3iATI +#define GLEE_H_DEFINED_glVertexStream3iATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3IATIPROC GLeeFuncPtr_glVertexStream3iATI; + #define glVertexStream3iATI GLeeFuncPtr_glVertexStream3iATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3ivATI +#define GLEE_H_DEFINED_glVertexStream3ivATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3IVATIPROC GLeeFuncPtr_glVertexStream3ivATI; + #define glVertexStream3ivATI GLeeFuncPtr_glVertexStream3ivATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3fATI +#define GLEE_H_DEFINED_glVertexStream3fATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3FATIPROC GLeeFuncPtr_glVertexStream3fATI; + #define glVertexStream3fATI GLeeFuncPtr_glVertexStream3fATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3fvATI +#define GLEE_H_DEFINED_glVertexStream3fvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3FVATIPROC GLeeFuncPtr_glVertexStream3fvATI; + #define glVertexStream3fvATI GLeeFuncPtr_glVertexStream3fvATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3dATI +#define GLEE_H_DEFINED_glVertexStream3dATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3DATIPROC GLeeFuncPtr_glVertexStream3dATI; + #define glVertexStream3dATI GLeeFuncPtr_glVertexStream3dATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream3dvATI +#define GLEE_H_DEFINED_glVertexStream3dvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM3DVATIPROC GLeeFuncPtr_glVertexStream3dvATI; + #define glVertexStream3dvATI GLeeFuncPtr_glVertexStream3dvATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4sATI +#define GLEE_H_DEFINED_glVertexStream4sATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4SATIPROC GLeeFuncPtr_glVertexStream4sATI; + #define glVertexStream4sATI GLeeFuncPtr_glVertexStream4sATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4svATI +#define GLEE_H_DEFINED_glVertexStream4svATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4SVATIPROC GLeeFuncPtr_glVertexStream4svATI; + #define glVertexStream4svATI GLeeFuncPtr_glVertexStream4svATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4iATI +#define GLEE_H_DEFINED_glVertexStream4iATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4IATIPROC GLeeFuncPtr_glVertexStream4iATI; + #define glVertexStream4iATI GLeeFuncPtr_glVertexStream4iATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4ivATI +#define GLEE_H_DEFINED_glVertexStream4ivATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4IVATIPROC GLeeFuncPtr_glVertexStream4ivATI; + #define glVertexStream4ivATI GLeeFuncPtr_glVertexStream4ivATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4fATI +#define GLEE_H_DEFINED_glVertexStream4fATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4FATIPROC GLeeFuncPtr_glVertexStream4fATI; + #define glVertexStream4fATI GLeeFuncPtr_glVertexStream4fATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4fvATI +#define GLEE_H_DEFINED_glVertexStream4fvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4FVATIPROC GLeeFuncPtr_glVertexStream4fvATI; + #define glVertexStream4fvATI GLeeFuncPtr_glVertexStream4fvATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4dATI +#define GLEE_H_DEFINED_glVertexStream4dATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4DATIPROC GLeeFuncPtr_glVertexStream4dATI; + #define glVertexStream4dATI GLeeFuncPtr_glVertexStream4dATI +#endif +#ifndef GLEE_H_DEFINED_glVertexStream4dvATI +#define GLEE_H_DEFINED_glVertexStream4dvATI + typedef void (APIENTRYP GLEEPFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble * coords); + GLEE_EXTERN GLEEPFNGLVERTEXSTREAM4DVATIPROC GLeeFuncPtr_glVertexStream4dvATI; + #define glVertexStream4dvATI GLeeFuncPtr_glVertexStream4dvATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3bATI +#define GLEE_H_DEFINED_glNormalStream3bATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3BATIPROC GLeeFuncPtr_glNormalStream3bATI; + #define glNormalStream3bATI GLeeFuncPtr_glNormalStream3bATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3bvATI +#define GLEE_H_DEFINED_glNormalStream3bvATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3BVATIPROC GLeeFuncPtr_glNormalStream3bvATI; + #define glNormalStream3bvATI GLeeFuncPtr_glNormalStream3bvATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3sATI +#define GLEE_H_DEFINED_glNormalStream3sATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3SATIPROC GLeeFuncPtr_glNormalStream3sATI; + #define glNormalStream3sATI GLeeFuncPtr_glNormalStream3sATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3svATI +#define GLEE_H_DEFINED_glNormalStream3svATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort * coords); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3SVATIPROC GLeeFuncPtr_glNormalStream3svATI; + #define glNormalStream3svATI GLeeFuncPtr_glNormalStream3svATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3iATI +#define GLEE_H_DEFINED_glNormalStream3iATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3IATIPROC GLeeFuncPtr_glNormalStream3iATI; + #define glNormalStream3iATI GLeeFuncPtr_glNormalStream3iATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3ivATI +#define GLEE_H_DEFINED_glNormalStream3ivATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint * coords); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3IVATIPROC GLeeFuncPtr_glNormalStream3ivATI; + #define glNormalStream3ivATI GLeeFuncPtr_glNormalStream3ivATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3fATI +#define GLEE_H_DEFINED_glNormalStream3fATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3FATIPROC GLeeFuncPtr_glNormalStream3fATI; + #define glNormalStream3fATI GLeeFuncPtr_glNormalStream3fATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3fvATI +#define GLEE_H_DEFINED_glNormalStream3fvATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat * coords); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3FVATIPROC GLeeFuncPtr_glNormalStream3fvATI; + #define glNormalStream3fvATI GLeeFuncPtr_glNormalStream3fvATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3dATI +#define GLEE_H_DEFINED_glNormalStream3dATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3DATIPROC GLeeFuncPtr_glNormalStream3dATI; + #define glNormalStream3dATI GLeeFuncPtr_glNormalStream3dATI +#endif +#ifndef GLEE_H_DEFINED_glNormalStream3dvATI +#define GLEE_H_DEFINED_glNormalStream3dvATI + typedef void (APIENTRYP GLEEPFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble * coords); + GLEE_EXTERN GLEEPFNGLNORMALSTREAM3DVATIPROC GLeeFuncPtr_glNormalStream3dvATI; + #define glNormalStream3dvATI GLeeFuncPtr_glNormalStream3dvATI +#endif +#ifndef GLEE_H_DEFINED_glClientActiveVertexStreamATI +#define GLEE_H_DEFINED_glClientActiveVertexStreamATI + typedef void (APIENTRYP GLEEPFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); + GLEE_EXTERN GLEEPFNGLCLIENTACTIVEVERTEXSTREAMATIPROC GLeeFuncPtr_glClientActiveVertexStreamATI; + #define glClientActiveVertexStreamATI GLeeFuncPtr_glClientActiveVertexStreamATI +#endif +#ifndef GLEE_H_DEFINED_glVertexBlendEnviATI +#define GLEE_H_DEFINED_glVertexBlendEnviATI + typedef void (APIENTRYP GLEEPFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLVERTEXBLENDENVIATIPROC GLeeFuncPtr_glVertexBlendEnviATI; + #define glVertexBlendEnviATI GLeeFuncPtr_glVertexBlendEnviATI +#endif +#ifndef GLEE_H_DEFINED_glVertexBlendEnvfATI +#define GLEE_H_DEFINED_glVertexBlendEnvfATI + typedef void (APIENTRYP GLEEPFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLVERTEXBLENDENVFATIPROC GLeeFuncPtr_glVertexBlendEnvfATI; + #define glVertexBlendEnvfATI GLeeFuncPtr_glVertexBlendEnvfATI +#endif +#endif + +/* GL_ATI_element_array */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#define __GLEE_GL_ATI_element_array 1 +/* Constants */ +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#ifndef GLEE_H_DEFINED_glElementPointerATI +#define GLEE_H_DEFINED_glElementPointerATI + typedef void (APIENTRYP GLEEPFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLELEMENTPOINTERATIPROC GLeeFuncPtr_glElementPointerATI; + #define glElementPointerATI GLeeFuncPtr_glElementPointerATI +#endif +#ifndef GLEE_H_DEFINED_glDrawElementArrayATI +#define GLEE_H_DEFINED_glDrawElementArrayATI + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); + GLEE_EXTERN GLEEPFNGLDRAWELEMENTARRAYATIPROC GLeeFuncPtr_glDrawElementArrayATI; + #define glDrawElementArrayATI GLeeFuncPtr_glDrawElementArrayATI +#endif +#ifndef GLEE_H_DEFINED_glDrawRangeElementArrayATI +#define GLEE_H_DEFINED_glDrawRangeElementArrayATI + typedef void (APIENTRYP GLEEPFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); + GLEE_EXTERN GLEEPFNGLDRAWRANGEELEMENTARRAYATIPROC GLeeFuncPtr_glDrawRangeElementArrayATI; + #define glDrawRangeElementArrayATI GLeeFuncPtr_glDrawRangeElementArrayATI +#endif +#endif + +/* GL_SUN_mesh_array */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#define __GLEE_GL_SUN_mesh_array 1 +/* Constants */ +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#ifndef GLEE_H_DEFINED_glDrawMeshArraysSUN +#define GLEE_H_DEFINED_glDrawMeshArraysSUN + typedef void (APIENTRYP GLEEPFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); + GLEE_EXTERN GLEEPFNGLDRAWMESHARRAYSSUNPROC GLeeFuncPtr_glDrawMeshArraysSUN; + #define glDrawMeshArraysSUN GLeeFuncPtr_glDrawMeshArraysSUN +#endif +#endif + +/* GL_SUN_slice_accum */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#define __GLEE_GL_SUN_slice_accum 1 +/* Constants */ +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +/* GL_NV_multisample_filter_hint */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#define __GLEE_GL_NV_multisample_filter_hint 1 +/* Constants */ +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +/* GL_NV_depth_clamp */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#define __GLEE_GL_NV_depth_clamp 1 +/* Constants */ +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +/* GL_NV_occlusion_query */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#define __GLEE_GL_NV_occlusion_query 1 +/* Constants */ +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#ifndef GLEE_H_DEFINED_glGenOcclusionQueriesNV +#define GLEE_H_DEFINED_glGenOcclusionQueriesNV + typedef void (APIENTRYP GLEEPFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint * ids); + GLEE_EXTERN GLEEPFNGLGENOCCLUSIONQUERIESNVPROC GLeeFuncPtr_glGenOcclusionQueriesNV; + #define glGenOcclusionQueriesNV GLeeFuncPtr_glGenOcclusionQueriesNV +#endif +#ifndef GLEE_H_DEFINED_glDeleteOcclusionQueriesNV +#define GLEE_H_DEFINED_glDeleteOcclusionQueriesNV + typedef void (APIENTRYP GLEEPFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint * ids); + GLEE_EXTERN GLEEPFNGLDELETEOCCLUSIONQUERIESNVPROC GLeeFuncPtr_glDeleteOcclusionQueriesNV; + #define glDeleteOcclusionQueriesNV GLeeFuncPtr_glDeleteOcclusionQueriesNV +#endif +#ifndef GLEE_H_DEFINED_glIsOcclusionQueryNV +#define GLEE_H_DEFINED_glIsOcclusionQueryNV + typedef GLboolean (APIENTRYP GLEEPFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLISOCCLUSIONQUERYNVPROC GLeeFuncPtr_glIsOcclusionQueryNV; + #define glIsOcclusionQueryNV GLeeFuncPtr_glIsOcclusionQueryNV +#endif +#ifndef GLEE_H_DEFINED_glBeginOcclusionQueryNV +#define GLEE_H_DEFINED_glBeginOcclusionQueryNV + typedef void (APIENTRYP GLEEPFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLBEGINOCCLUSIONQUERYNVPROC GLeeFuncPtr_glBeginOcclusionQueryNV; + #define glBeginOcclusionQueryNV GLeeFuncPtr_glBeginOcclusionQueryNV +#endif +#ifndef GLEE_H_DEFINED_glEndOcclusionQueryNV +#define GLEE_H_DEFINED_glEndOcclusionQueryNV + typedef void (APIENTRYP GLEEPFNGLENDOCCLUSIONQUERYNVPROC) (); + GLEE_EXTERN GLEEPFNGLENDOCCLUSIONQUERYNVPROC GLeeFuncPtr_glEndOcclusionQueryNV; + #define glEndOcclusionQueryNV GLeeFuncPtr_glEndOcclusionQueryNV +#endif +#ifndef GLEE_H_DEFINED_glGetOcclusionQueryivNV +#define GLEE_H_DEFINED_glGetOcclusionQueryivNV + typedef void (APIENTRYP GLEEPFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETOCCLUSIONQUERYIVNVPROC GLeeFuncPtr_glGetOcclusionQueryivNV; + #define glGetOcclusionQueryivNV GLeeFuncPtr_glGetOcclusionQueryivNV +#endif +#ifndef GLEE_H_DEFINED_glGetOcclusionQueryuivNV +#define GLEE_H_DEFINED_glGetOcclusionQueryuivNV + typedef void (APIENTRYP GLEEPFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETOCCLUSIONQUERYUIVNVPROC GLeeFuncPtr_glGetOcclusionQueryuivNV; + #define glGetOcclusionQueryuivNV GLeeFuncPtr_glGetOcclusionQueryuivNV +#endif +#endif + +/* GL_NV_point_sprite */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#define __GLEE_GL_NV_point_sprite 1 +/* Constants */ +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#ifndef GLEE_H_DEFINED_glPointParameteriNV +#define GLEE_H_DEFINED_glPointParameteriNV + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERINVPROC GLeeFuncPtr_glPointParameteriNV; + #define glPointParameteriNV GLeeFuncPtr_glPointParameteriNV +#endif +#ifndef GLEE_H_DEFINED_glPointParameterivNV +#define GLEE_H_DEFINED_glPointParameterivNV + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERIVNVPROC GLeeFuncPtr_glPointParameterivNV; + #define glPointParameterivNV GLeeFuncPtr_glPointParameterivNV +#endif +#endif + +/* GL_NV_texture_shader3 */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#define __GLEE_GL_NV_texture_shader3 1 +/* Constants */ +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +/* GL_NV_vertex_program1_1 */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#define __GLEE_GL_NV_vertex_program1_1 1 +/* Constants */ +#endif + +/* GL_EXT_shadow_funcs */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#define __GLEE_GL_EXT_shadow_funcs 1 +/* Constants */ +#endif + +/* GL_EXT_stencil_two_side */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#define __GLEE_GL_EXT_stencil_two_side 1 +/* Constants */ +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#ifndef GLEE_H_DEFINED_glActiveStencilFaceEXT +#define GLEE_H_DEFINED_glActiveStencilFaceEXT + typedef void (APIENTRYP GLEEPFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); + GLEE_EXTERN GLEEPFNGLACTIVESTENCILFACEEXTPROC GLeeFuncPtr_glActiveStencilFaceEXT; + #define glActiveStencilFaceEXT GLeeFuncPtr_glActiveStencilFaceEXT +#endif +#endif + +/* GL_ATI_text_fragment_shader */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#define __GLEE_GL_ATI_text_fragment_shader 1 +/* Constants */ +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +/* GL_APPLE_client_storage */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#define __GLEE_GL_APPLE_client_storage 1 +/* Constants */ +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +/* GL_APPLE_element_array */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#define __GLEE_GL_APPLE_element_array 1 +/* Constants */ +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#ifndef GLEE_H_DEFINED_glElementPointerAPPLE +#define GLEE_H_DEFINED_glElementPointerAPPLE + typedef void (APIENTRYP GLEEPFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLELEMENTPOINTERAPPLEPROC GLeeFuncPtr_glElementPointerAPPLE; + #define glElementPointerAPPLE GLeeFuncPtr_glElementPointerAPPLE +#endif +#ifndef GLEE_H_DEFINED_glDrawElementArrayAPPLE +#define GLEE_H_DEFINED_glDrawElementArrayAPPLE + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); + GLEE_EXTERN GLEEPFNGLDRAWELEMENTARRAYAPPLEPROC GLeeFuncPtr_glDrawElementArrayAPPLE; + #define glDrawElementArrayAPPLE GLeeFuncPtr_glDrawElementArrayAPPLE +#endif +#ifndef GLEE_H_DEFINED_glDrawRangeElementArrayAPPLE +#define GLEE_H_DEFINED_glDrawRangeElementArrayAPPLE + typedef void (APIENTRYP GLEEPFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); + GLEE_EXTERN GLEEPFNGLDRAWRANGEELEMENTARRAYAPPLEPROC GLeeFuncPtr_glDrawRangeElementArrayAPPLE; + #define glDrawRangeElementArrayAPPLE GLeeFuncPtr_glDrawRangeElementArrayAPPLE +#endif +#ifndef GLEE_H_DEFINED_glMultiDrawElementArrayAPPLE +#define GLEE_H_DEFINED_glMultiDrawElementArrayAPPLE + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLMULTIDRAWELEMENTARRAYAPPLEPROC GLeeFuncPtr_glMultiDrawElementArrayAPPLE; + #define glMultiDrawElementArrayAPPLE GLeeFuncPtr_glMultiDrawElementArrayAPPLE +#endif +#ifndef GLEE_H_DEFINED_glMultiDrawRangeElementArrayAPPLE +#define GLEE_H_DEFINED_glMultiDrawRangeElementArrayAPPLE + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint * first, const GLsizei * count, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC GLeeFuncPtr_glMultiDrawRangeElementArrayAPPLE; + #define glMultiDrawRangeElementArrayAPPLE GLeeFuncPtr_glMultiDrawRangeElementArrayAPPLE +#endif +#endif + +/* GL_APPLE_fence */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#define __GLEE_GL_APPLE_fence 1 +/* Constants */ +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#ifndef GLEE_H_DEFINED_glGenFencesAPPLE +#define GLEE_H_DEFINED_glGenFencesAPPLE + typedef void (APIENTRYP GLEEPFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint * fences); + GLEE_EXTERN GLEEPFNGLGENFENCESAPPLEPROC GLeeFuncPtr_glGenFencesAPPLE; + #define glGenFencesAPPLE GLeeFuncPtr_glGenFencesAPPLE +#endif +#ifndef GLEE_H_DEFINED_glDeleteFencesAPPLE +#define GLEE_H_DEFINED_glDeleteFencesAPPLE + typedef void (APIENTRYP GLEEPFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint * fences); + GLEE_EXTERN GLEEPFNGLDELETEFENCESAPPLEPROC GLeeFuncPtr_glDeleteFencesAPPLE; + #define glDeleteFencesAPPLE GLeeFuncPtr_glDeleteFencesAPPLE +#endif +#ifndef GLEE_H_DEFINED_glSetFenceAPPLE +#define GLEE_H_DEFINED_glSetFenceAPPLE + typedef void (APIENTRYP GLEEPFNGLSETFENCEAPPLEPROC) (GLuint fence); + GLEE_EXTERN GLEEPFNGLSETFENCEAPPLEPROC GLeeFuncPtr_glSetFenceAPPLE; + #define glSetFenceAPPLE GLeeFuncPtr_glSetFenceAPPLE +#endif +#ifndef GLEE_H_DEFINED_glIsFenceAPPLE +#define GLEE_H_DEFINED_glIsFenceAPPLE + typedef GLboolean (APIENTRYP GLEEPFNGLISFENCEAPPLEPROC) (GLuint fence); + GLEE_EXTERN GLEEPFNGLISFENCEAPPLEPROC GLeeFuncPtr_glIsFenceAPPLE; + #define glIsFenceAPPLE GLeeFuncPtr_glIsFenceAPPLE +#endif +#ifndef GLEE_H_DEFINED_glTestFenceAPPLE +#define GLEE_H_DEFINED_glTestFenceAPPLE + typedef GLboolean (APIENTRYP GLEEPFNGLTESTFENCEAPPLEPROC) (GLuint fence); + GLEE_EXTERN GLEEPFNGLTESTFENCEAPPLEPROC GLeeFuncPtr_glTestFenceAPPLE; + #define glTestFenceAPPLE GLeeFuncPtr_glTestFenceAPPLE +#endif +#ifndef GLEE_H_DEFINED_glFinishFenceAPPLE +#define GLEE_H_DEFINED_glFinishFenceAPPLE + typedef void (APIENTRYP GLEEPFNGLFINISHFENCEAPPLEPROC) (GLuint fence); + GLEE_EXTERN GLEEPFNGLFINISHFENCEAPPLEPROC GLeeFuncPtr_glFinishFenceAPPLE; + #define glFinishFenceAPPLE GLeeFuncPtr_glFinishFenceAPPLE +#endif +#ifndef GLEE_H_DEFINED_glTestObjectAPPLE +#define GLEE_H_DEFINED_glTestObjectAPPLE + typedef GLboolean (APIENTRYP GLEEPFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + GLEE_EXTERN GLEEPFNGLTESTOBJECTAPPLEPROC GLeeFuncPtr_glTestObjectAPPLE; + #define glTestObjectAPPLE GLeeFuncPtr_glTestObjectAPPLE +#endif +#ifndef GLEE_H_DEFINED_glFinishObjectAPPLE +#define GLEE_H_DEFINED_glFinishObjectAPPLE + typedef void (APIENTRYP GLEEPFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); + GLEE_EXTERN GLEEPFNGLFINISHOBJECTAPPLEPROC GLeeFuncPtr_glFinishObjectAPPLE; + #define glFinishObjectAPPLE GLeeFuncPtr_glFinishObjectAPPLE +#endif +#endif + +/* GL_APPLE_vertex_array_object */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#define __GLEE_GL_APPLE_vertex_array_object 1 +/* Constants */ +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#ifndef GLEE_H_DEFINED_glBindVertexArrayAPPLE +#define GLEE_H_DEFINED_glBindVertexArrayAPPLE + typedef void (APIENTRYP GLEEPFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); + GLEE_EXTERN GLEEPFNGLBINDVERTEXARRAYAPPLEPROC GLeeFuncPtr_glBindVertexArrayAPPLE; + #define glBindVertexArrayAPPLE GLeeFuncPtr_glBindVertexArrayAPPLE +#endif +#ifndef GLEE_H_DEFINED_glDeleteVertexArraysAPPLE +#define GLEE_H_DEFINED_glDeleteVertexArraysAPPLE + typedef void (APIENTRYP GLEEPFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint * arrays); + GLEE_EXTERN GLEEPFNGLDELETEVERTEXARRAYSAPPLEPROC GLeeFuncPtr_glDeleteVertexArraysAPPLE; + #define glDeleteVertexArraysAPPLE GLeeFuncPtr_glDeleteVertexArraysAPPLE +#endif +#ifndef GLEE_H_DEFINED_glGenVertexArraysAPPLE +#define GLEE_H_DEFINED_glGenVertexArraysAPPLE + typedef void (APIENTRYP GLEEPFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint * arrays); + GLEE_EXTERN GLEEPFNGLGENVERTEXARRAYSAPPLEPROC GLeeFuncPtr_glGenVertexArraysAPPLE; + #define glGenVertexArraysAPPLE GLeeFuncPtr_glGenVertexArraysAPPLE +#endif +#ifndef GLEE_H_DEFINED_glIsVertexArrayAPPLE +#define GLEE_H_DEFINED_glIsVertexArrayAPPLE + typedef GLboolean (APIENTRYP GLEEPFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + GLEE_EXTERN GLEEPFNGLISVERTEXARRAYAPPLEPROC GLeeFuncPtr_glIsVertexArrayAPPLE; + #define glIsVertexArrayAPPLE GLeeFuncPtr_glIsVertexArrayAPPLE +#endif +#endif + +/* GL_APPLE_vertex_array_range */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#define __GLEE_GL_APPLE_vertex_array_range 1 +/* Constants */ +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#ifndef GLEE_H_DEFINED_glVertexArrayRangeAPPLE +#define GLEE_H_DEFINED_glVertexArrayRangeAPPLE + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYRANGEAPPLEPROC GLeeFuncPtr_glVertexArrayRangeAPPLE; + #define glVertexArrayRangeAPPLE GLeeFuncPtr_glVertexArrayRangeAPPLE +#endif +#ifndef GLEE_H_DEFINED_glFlushVertexArrayRangeAPPLE +#define GLEE_H_DEFINED_glFlushVertexArrayRangeAPPLE + typedef void (APIENTRYP GLEEPFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC GLeeFuncPtr_glFlushVertexArrayRangeAPPLE; + #define glFlushVertexArrayRangeAPPLE GLeeFuncPtr_glFlushVertexArrayRangeAPPLE +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayParameteriAPPLE +#define GLEE_H_DEFINED_glVertexArrayParameteriAPPLE + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYPARAMETERIAPPLEPROC GLeeFuncPtr_glVertexArrayParameteriAPPLE; + #define glVertexArrayParameteriAPPLE GLeeFuncPtr_glVertexArrayParameteriAPPLE +#endif +#endif + +/* GL_APPLE_ycbcr_422 */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#define __GLEE_GL_APPLE_ycbcr_422 1 +/* Constants */ +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +/* GL_S3_s3tc */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#define __GLEE_GL_S3_s3tc 1 +/* Constants */ +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +/* GL_ATI_draw_buffers */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#define __GLEE_GL_ATI_draw_buffers 1 +/* Constants */ +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#ifndef GLEE_H_DEFINED_glDrawBuffersATI +#define GLEE_H_DEFINED_glDrawBuffersATI + typedef void (APIENTRYP GLEEPFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum * bufs); + GLEE_EXTERN GLEEPFNGLDRAWBUFFERSATIPROC GLeeFuncPtr_glDrawBuffersATI; + #define glDrawBuffersATI GLeeFuncPtr_glDrawBuffersATI +#endif +#endif + +/* GL_ATI_pixel_format_float */ + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +#define __GLEE_GL_ATI_pixel_format_float 1 +/* Constants */ +#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif + +/* GL_ATI_texture_env_combine3 */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#define __GLEE_GL_ATI_texture_env_combine3 1 +/* Constants */ +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +/* GL_ATI_texture_float */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#define __GLEE_GL_ATI_texture_float 1 +/* Constants */ +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +/* GL_NV_float_buffer */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#define __GLEE_GL_NV_float_buffer 1 +/* Constants */ +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +/* GL_NV_fragment_program */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +#define __GLEE_GL_NV_fragment_program 1 +/* Constants */ +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#ifndef GLEE_H_DEFINED_glProgramNamedParameter4fNV +#define GLEE_H_DEFINED_glProgramNamedParameter4fNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4FNVPROC GLeeFuncPtr_glProgramNamedParameter4fNV; + #define glProgramNamedParameter4fNV GLeeFuncPtr_glProgramNamedParameter4fNV +#endif +#ifndef GLEE_H_DEFINED_glProgramNamedParameter4dNV +#define GLEE_H_DEFINED_glProgramNamedParameter4dNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC GLeeFuncPtr_glProgramNamedParameter4dNV; + #define glProgramNamedParameter4dNV GLeeFuncPtr_glProgramNamedParameter4dNV +#endif +#ifndef GLEE_H_DEFINED_glProgramNamedParameter4fvNV +#define GLEE_H_DEFINED_glProgramNamedParameter4fvNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v); + GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC GLeeFuncPtr_glProgramNamedParameter4fvNV; + #define glProgramNamedParameter4fvNV GLeeFuncPtr_glProgramNamedParameter4fvNV +#endif +#ifndef GLEE_H_DEFINED_glProgramNamedParameter4dvNV +#define GLEE_H_DEFINED_glProgramNamedParameter4dvNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v); + GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4DVNVPROC GLeeFuncPtr_glProgramNamedParameter4dvNV; + #define glProgramNamedParameter4dvNV GLeeFuncPtr_glProgramNamedParameter4dvNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramNamedParameterfvNV +#define GLEE_H_DEFINED_glGetProgramNamedParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte * name, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC GLeeFuncPtr_glGetProgramNamedParameterfvNV; + #define glGetProgramNamedParameterfvNV GLeeFuncPtr_glGetProgramNamedParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramNamedParameterdvNV +#define GLEE_H_DEFINED_glGetProgramNamedParameterdvNV + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte * name, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC GLeeFuncPtr_glGetProgramNamedParameterdvNV; + #define glGetProgramNamedParameterdvNV GLeeFuncPtr_glGetProgramNamedParameterdvNV +#endif +#endif + +/* GL_NV_half_float */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +#define __GLEE_GL_NV_half_float 1 +/* Constants */ +#define GL_HALF_FLOAT_NV 0x140B +#ifndef GLEE_H_DEFINED_glVertex2hNV +#define GLEE_H_DEFINED_glVertex2hNV + typedef void (APIENTRYP GLEEPFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); + GLEE_EXTERN GLEEPFNGLVERTEX2HNVPROC GLeeFuncPtr_glVertex2hNV; + #define glVertex2hNV GLeeFuncPtr_glVertex2hNV +#endif +#ifndef GLEE_H_DEFINED_glVertex2hvNV +#define GLEE_H_DEFINED_glVertex2hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEX2HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEX2HVNVPROC GLeeFuncPtr_glVertex2hvNV; + #define glVertex2hvNV GLeeFuncPtr_glVertex2hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertex3hNV +#define GLEE_H_DEFINED_glVertex3hNV + typedef void (APIENTRYP GLEEPFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); + GLEE_EXTERN GLEEPFNGLVERTEX3HNVPROC GLeeFuncPtr_glVertex3hNV; + #define glVertex3hNV GLeeFuncPtr_glVertex3hNV +#endif +#ifndef GLEE_H_DEFINED_glVertex3hvNV +#define GLEE_H_DEFINED_glVertex3hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEX3HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEX3HVNVPROC GLeeFuncPtr_glVertex3hvNV; + #define glVertex3hvNV GLeeFuncPtr_glVertex3hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertex4hNV +#define GLEE_H_DEFINED_glVertex4hNV + typedef void (APIENTRYP GLEEPFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); + GLEE_EXTERN GLEEPFNGLVERTEX4HNVPROC GLeeFuncPtr_glVertex4hNV; + #define glVertex4hNV GLeeFuncPtr_glVertex4hNV +#endif +#ifndef GLEE_H_DEFINED_glVertex4hvNV +#define GLEE_H_DEFINED_glVertex4hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEX4HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEX4HVNVPROC GLeeFuncPtr_glVertex4hvNV; + #define glVertex4hvNV GLeeFuncPtr_glVertex4hvNV +#endif +#ifndef GLEE_H_DEFINED_glNormal3hNV +#define GLEE_H_DEFINED_glNormal3hNV + typedef void (APIENTRYP GLEEPFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); + GLEE_EXTERN GLEEPFNGLNORMAL3HNVPROC GLeeFuncPtr_glNormal3hNV; + #define glNormal3hNV GLeeFuncPtr_glNormal3hNV +#endif +#ifndef GLEE_H_DEFINED_glNormal3hvNV +#define GLEE_H_DEFINED_glNormal3hvNV + typedef void (APIENTRYP GLEEPFNGLNORMAL3HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLNORMAL3HVNVPROC GLeeFuncPtr_glNormal3hvNV; + #define glNormal3hvNV GLeeFuncPtr_glNormal3hvNV +#endif +#ifndef GLEE_H_DEFINED_glColor3hNV +#define GLEE_H_DEFINED_glColor3hNV + typedef void (APIENTRYP GLEEPFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); + GLEE_EXTERN GLEEPFNGLCOLOR3HNVPROC GLeeFuncPtr_glColor3hNV; + #define glColor3hNV GLeeFuncPtr_glColor3hNV +#endif +#ifndef GLEE_H_DEFINED_glColor3hvNV +#define GLEE_H_DEFINED_glColor3hvNV + typedef void (APIENTRYP GLEEPFNGLCOLOR3HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLCOLOR3HVNVPROC GLeeFuncPtr_glColor3hvNV; + #define glColor3hvNV GLeeFuncPtr_glColor3hvNV +#endif +#ifndef GLEE_H_DEFINED_glColor4hNV +#define GLEE_H_DEFINED_glColor4hNV + typedef void (APIENTRYP GLEEPFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); + GLEE_EXTERN GLEEPFNGLCOLOR4HNVPROC GLeeFuncPtr_glColor4hNV; + #define glColor4hNV GLeeFuncPtr_glColor4hNV +#endif +#ifndef GLEE_H_DEFINED_glColor4hvNV +#define GLEE_H_DEFINED_glColor4hvNV + typedef void (APIENTRYP GLEEPFNGLCOLOR4HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLCOLOR4HVNVPROC GLeeFuncPtr_glColor4hvNV; + #define glColor4hvNV GLeeFuncPtr_glColor4hvNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord1hNV +#define GLEE_H_DEFINED_glTexCoord1hNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD1HNVPROC) (GLhalfNV s); + GLEE_EXTERN GLEEPFNGLTEXCOORD1HNVPROC GLeeFuncPtr_glTexCoord1hNV; + #define glTexCoord1hNV GLeeFuncPtr_glTexCoord1hNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord1hvNV +#define GLEE_H_DEFINED_glTexCoord1hvNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD1HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD1HVNVPROC GLeeFuncPtr_glTexCoord1hvNV; + #define glTexCoord1hvNV GLeeFuncPtr_glTexCoord1hvNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2hNV +#define GLEE_H_DEFINED_glTexCoord2hNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); + GLEE_EXTERN GLEEPFNGLTEXCOORD2HNVPROC GLeeFuncPtr_glTexCoord2hNV; + #define glTexCoord2hNV GLeeFuncPtr_glTexCoord2hNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2hvNV +#define GLEE_H_DEFINED_glTexCoord2hvNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD2HVNVPROC GLeeFuncPtr_glTexCoord2hvNV; + #define glTexCoord2hvNV GLeeFuncPtr_glTexCoord2hvNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord3hNV +#define GLEE_H_DEFINED_glTexCoord3hNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); + GLEE_EXTERN GLEEPFNGLTEXCOORD3HNVPROC GLeeFuncPtr_glTexCoord3hNV; + #define glTexCoord3hNV GLeeFuncPtr_glTexCoord3hNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord3hvNV +#define GLEE_H_DEFINED_glTexCoord3hvNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD3HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD3HVNVPROC GLeeFuncPtr_glTexCoord3hvNV; + #define glTexCoord3hvNV GLeeFuncPtr_glTexCoord3hvNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4hNV +#define GLEE_H_DEFINED_glTexCoord4hNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); + GLEE_EXTERN GLEEPFNGLTEXCOORD4HNVPROC GLeeFuncPtr_glTexCoord4hNV; + #define glTexCoord4hNV GLeeFuncPtr_glTexCoord4hNV +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4hvNV +#define GLEE_H_DEFINED_glTexCoord4hvNV + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLTEXCOORD4HVNVPROC GLeeFuncPtr_glTexCoord4hvNV; + #define glTexCoord4hvNV GLeeFuncPtr_glTexCoord4hvNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1hNV +#define GLEE_H_DEFINED_glMultiTexCoord1hNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1HNVPROC GLeeFuncPtr_glMultiTexCoord1hNV; + #define glMultiTexCoord1hNV GLeeFuncPtr_glMultiTexCoord1hNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1hvNV +#define GLEE_H_DEFINED_glMultiTexCoord1hvNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1HVNVPROC GLeeFuncPtr_glMultiTexCoord1hvNV; + #define glMultiTexCoord1hvNV GLeeFuncPtr_glMultiTexCoord1hvNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2hNV +#define GLEE_H_DEFINED_glMultiTexCoord2hNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2HNVPROC GLeeFuncPtr_glMultiTexCoord2hNV; + #define glMultiTexCoord2hNV GLeeFuncPtr_glMultiTexCoord2hNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2hvNV +#define GLEE_H_DEFINED_glMultiTexCoord2hvNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2HVNVPROC GLeeFuncPtr_glMultiTexCoord2hvNV; + #define glMultiTexCoord2hvNV GLeeFuncPtr_glMultiTexCoord2hvNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3hNV +#define GLEE_H_DEFINED_glMultiTexCoord3hNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3HNVPROC GLeeFuncPtr_glMultiTexCoord3hNV; + #define glMultiTexCoord3hNV GLeeFuncPtr_glMultiTexCoord3hNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3hvNV +#define GLEE_H_DEFINED_glMultiTexCoord3hvNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3HVNVPROC GLeeFuncPtr_glMultiTexCoord3hvNV; + #define glMultiTexCoord3hvNV GLeeFuncPtr_glMultiTexCoord3hvNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4hNV +#define GLEE_H_DEFINED_glMultiTexCoord4hNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4HNVPROC GLeeFuncPtr_glMultiTexCoord4hNV; + #define glMultiTexCoord4hNV GLeeFuncPtr_glMultiTexCoord4hNV +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4hvNV +#define GLEE_H_DEFINED_glMultiTexCoord4hvNV + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4HVNVPROC GLeeFuncPtr_glMultiTexCoord4hvNV; + #define glMultiTexCoord4hvNV GLeeFuncPtr_glMultiTexCoord4hvNV +#endif +#ifndef GLEE_H_DEFINED_glFogCoordhNV +#define GLEE_H_DEFINED_glFogCoordhNV + typedef void (APIENTRYP GLEEPFNGLFOGCOORDHNVPROC) (GLhalfNV fog); + GLEE_EXTERN GLEEPFNGLFOGCOORDHNVPROC GLeeFuncPtr_glFogCoordhNV; + #define glFogCoordhNV GLeeFuncPtr_glFogCoordhNV +#endif +#ifndef GLEE_H_DEFINED_glFogCoordhvNV +#define GLEE_H_DEFINED_glFogCoordhvNV + typedef void (APIENTRYP GLEEPFNGLFOGCOORDHVNVPROC) (const GLhalfNV * fog); + GLEE_EXTERN GLEEPFNGLFOGCOORDHVNVPROC GLeeFuncPtr_glFogCoordhvNV; + #define glFogCoordhvNV GLeeFuncPtr_glFogCoordhvNV +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3hNV +#define GLEE_H_DEFINED_glSecondaryColor3hNV + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3HNVPROC GLeeFuncPtr_glSecondaryColor3hNV; + #define glSecondaryColor3hNV GLeeFuncPtr_glSecondaryColor3hNV +#endif +#ifndef GLEE_H_DEFINED_glSecondaryColor3hvNV +#define GLEE_H_DEFINED_glSecondaryColor3hvNV + typedef void (APIENTRYP GLEEPFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLSECONDARYCOLOR3HVNVPROC GLeeFuncPtr_glSecondaryColor3hvNV; + #define glSecondaryColor3hvNV GLeeFuncPtr_glSecondaryColor3hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexWeighthNV +#define GLEE_H_DEFINED_glVertexWeighthNV + typedef void (APIENTRYP GLEEPFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); + GLEE_EXTERN GLEEPFNGLVERTEXWEIGHTHNVPROC GLeeFuncPtr_glVertexWeighthNV; + #define glVertexWeighthNV GLeeFuncPtr_glVertexWeighthNV +#endif +#ifndef GLEE_H_DEFINED_glVertexWeighthvNV +#define GLEE_H_DEFINED_glVertexWeighthvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV * weight); + GLEE_EXTERN GLEEPFNGLVERTEXWEIGHTHVNVPROC GLeeFuncPtr_glVertexWeighthvNV; + #define glVertexWeighthvNV GLeeFuncPtr_glVertexWeighthvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1hNV +#define GLEE_H_DEFINED_glVertexAttrib1hNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1HNVPROC GLeeFuncPtr_glVertexAttrib1hNV; + #define glVertexAttrib1hNV GLeeFuncPtr_glVertexAttrib1hNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib1hvNV +#define GLEE_H_DEFINED_glVertexAttrib1hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB1HVNVPROC GLeeFuncPtr_glVertexAttrib1hvNV; + #define glVertexAttrib1hvNV GLeeFuncPtr_glVertexAttrib1hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2hNV +#define GLEE_H_DEFINED_glVertexAttrib2hNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2HNVPROC GLeeFuncPtr_glVertexAttrib2hNV; + #define glVertexAttrib2hNV GLeeFuncPtr_glVertexAttrib2hNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib2hvNV +#define GLEE_H_DEFINED_glVertexAttrib2hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB2HVNVPROC GLeeFuncPtr_glVertexAttrib2hvNV; + #define glVertexAttrib2hvNV GLeeFuncPtr_glVertexAttrib2hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3hNV +#define GLEE_H_DEFINED_glVertexAttrib3hNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3HNVPROC GLeeFuncPtr_glVertexAttrib3hNV; + #define glVertexAttrib3hNV GLeeFuncPtr_glVertexAttrib3hNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib3hvNV +#define GLEE_H_DEFINED_glVertexAttrib3hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB3HVNVPROC GLeeFuncPtr_glVertexAttrib3hvNV; + #define glVertexAttrib3hvNV GLeeFuncPtr_glVertexAttrib3hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4hNV +#define GLEE_H_DEFINED_glVertexAttrib4hNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4HNVPROC GLeeFuncPtr_glVertexAttrib4hNV; + #define glVertexAttrib4hNV GLeeFuncPtr_glVertexAttrib4hNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttrib4hvNV +#define GLEE_H_DEFINED_glVertexAttrib4hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIB4HVNVPROC GLeeFuncPtr_glVertexAttrib4hvNV; + #define glVertexAttrib4hvNV GLeeFuncPtr_glVertexAttrib4hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs1hvNV +#define GLEE_H_DEFINED_glVertexAttribs1hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS1HVNVPROC GLeeFuncPtr_glVertexAttribs1hvNV; + #define glVertexAttribs1hvNV GLeeFuncPtr_glVertexAttribs1hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs2hvNV +#define GLEE_H_DEFINED_glVertexAttribs2hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS2HVNVPROC GLeeFuncPtr_glVertexAttribs2hvNV; + #define glVertexAttribs2hvNV GLeeFuncPtr_glVertexAttribs2hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs3hvNV +#define GLEE_H_DEFINED_glVertexAttribs3hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS3HVNVPROC GLeeFuncPtr_glVertexAttribs3hvNV; + #define glVertexAttribs3hvNV GLeeFuncPtr_glVertexAttribs3hvNV +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribs4hvNV +#define GLEE_H_DEFINED_glVertexAttribs4hvNV + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBS4HVNVPROC GLeeFuncPtr_glVertexAttribs4hvNV; + #define glVertexAttribs4hvNV GLeeFuncPtr_glVertexAttribs4hvNV +#endif +#endif + +/* GL_NV_pixel_data_range */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#define __GLEE_GL_NV_pixel_data_range 1 +/* Constants */ +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#ifndef GLEE_H_DEFINED_glPixelDataRangeNV +#define GLEE_H_DEFINED_glPixelDataRangeNV + typedef void (APIENTRYP GLEEPFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLPIXELDATARANGENVPROC GLeeFuncPtr_glPixelDataRangeNV; + #define glPixelDataRangeNV GLeeFuncPtr_glPixelDataRangeNV +#endif +#ifndef GLEE_H_DEFINED_glFlushPixelDataRangeNV +#define GLEE_H_DEFINED_glFlushPixelDataRangeNV + typedef void (APIENTRYP GLEEPFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLFLUSHPIXELDATARANGENVPROC GLeeFuncPtr_glFlushPixelDataRangeNV; + #define glFlushPixelDataRangeNV GLeeFuncPtr_glFlushPixelDataRangeNV +#endif +#endif + +/* GL_NV_primitive_restart */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#define __GLEE_GL_NV_primitive_restart 1 +/* Constants */ +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#ifndef GLEE_H_DEFINED_glPrimitiveRestartNV +#define GLEE_H_DEFINED_glPrimitiveRestartNV + typedef void (APIENTRYP GLEEPFNGLPRIMITIVERESTARTNVPROC) (); + GLEE_EXTERN GLEEPFNGLPRIMITIVERESTARTNVPROC GLeeFuncPtr_glPrimitiveRestartNV; + #define glPrimitiveRestartNV GLeeFuncPtr_glPrimitiveRestartNV +#endif +#ifndef GLEE_H_DEFINED_glPrimitiveRestartIndexNV +#define GLEE_H_DEFINED_glPrimitiveRestartIndexNV + typedef void (APIENTRYP GLEEPFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); + GLEE_EXTERN GLEEPFNGLPRIMITIVERESTARTINDEXNVPROC GLeeFuncPtr_glPrimitiveRestartIndexNV; + #define glPrimitiveRestartIndexNV GLeeFuncPtr_glPrimitiveRestartIndexNV +#endif +#endif + +/* GL_NV_texture_expand_normal */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#define __GLEE_GL_NV_texture_expand_normal 1 +/* Constants */ +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +/* GL_NV_vertex_program2 */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#define __GLEE_GL_NV_vertex_program2 1 +/* Constants */ +#endif + +/* GL_ATI_map_object_buffer */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +#define __GLEE_GL_ATI_map_object_buffer 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glMapObjectBufferATI +#define GLEE_H_DEFINED_glMapObjectBufferATI + typedef GLvoid* (APIENTRYP GLEEPFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLMAPOBJECTBUFFERATIPROC GLeeFuncPtr_glMapObjectBufferATI; + #define glMapObjectBufferATI GLeeFuncPtr_glMapObjectBufferATI +#endif +#ifndef GLEE_H_DEFINED_glUnmapObjectBufferATI +#define GLEE_H_DEFINED_glUnmapObjectBufferATI + typedef void (APIENTRYP GLEEPFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLUNMAPOBJECTBUFFERATIPROC GLeeFuncPtr_glUnmapObjectBufferATI; + #define glUnmapObjectBufferATI GLeeFuncPtr_glUnmapObjectBufferATI +#endif +#endif + +/* GL_ATI_separate_stencil */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#define __GLEE_GL_ATI_separate_stencil 1 +/* Constants */ +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#ifndef GLEE_H_DEFINED_glStencilOpSeparateATI +#define GLEE_H_DEFINED_glStencilOpSeparateATI + typedef void (APIENTRYP GLEEPFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + GLEE_EXTERN GLEEPFNGLSTENCILOPSEPARATEATIPROC GLeeFuncPtr_glStencilOpSeparateATI; + #define glStencilOpSeparateATI GLeeFuncPtr_glStencilOpSeparateATI +#endif +#ifndef GLEE_H_DEFINED_glStencilFuncSeparateATI +#define GLEE_H_DEFINED_glStencilFuncSeparateATI + typedef void (APIENTRYP GLEEPFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); + GLEE_EXTERN GLEEPFNGLSTENCILFUNCSEPARATEATIPROC GLeeFuncPtr_glStencilFuncSeparateATI; + #define glStencilFuncSeparateATI GLeeFuncPtr_glStencilFuncSeparateATI +#endif +#endif + +/* GL_ATI_vertex_attrib_array_object */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +#define __GLEE_GL_ATI_vertex_attrib_array_object 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glVertexAttribArrayObjectATI +#define GLEE_H_DEFINED_glVertexAttribArrayObjectATI + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBARRAYOBJECTATIPROC GLeeFuncPtr_glVertexAttribArrayObjectATI; + #define glVertexAttribArrayObjectATI GLeeFuncPtr_glVertexAttribArrayObjectATI +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribArrayObjectfvATI +#define GLEE_H_DEFINED_glGetVertexAttribArrayObjectfvATI + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC GLeeFuncPtr_glGetVertexAttribArrayObjectfvATI; + #define glGetVertexAttribArrayObjectfvATI GLeeFuncPtr_glGetVertexAttribArrayObjectfvATI +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribArrayObjectivATI +#define GLEE_H_DEFINED_glGetVertexAttribArrayObjectivATI + typedef void (APIENTRYP GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC GLeeFuncPtr_glGetVertexAttribArrayObjectivATI; + #define glGetVertexAttribArrayObjectivATI GLeeFuncPtr_glGetVertexAttribArrayObjectivATI +#endif +#endif + +/* GL_OES_read_format */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#define __GLEE_GL_OES_read_format 1 +/* Constants */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif + +/* GL_EXT_depth_bounds_test */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#define __GLEE_GL_EXT_depth_bounds_test 1 +/* Constants */ +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#ifndef GLEE_H_DEFINED_glDepthBoundsEXT +#define GLEE_H_DEFINED_glDepthBoundsEXT + typedef void (APIENTRYP GLEEPFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); + GLEE_EXTERN GLEEPFNGLDEPTHBOUNDSEXTPROC GLeeFuncPtr_glDepthBoundsEXT; + #define glDepthBoundsEXT GLeeFuncPtr_glDepthBoundsEXT +#endif +#endif + +/* GL_EXT_texture_mirror_clamp */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#define __GLEE_GL_EXT_texture_mirror_clamp 1 +/* Constants */ +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif + +/* GL_EXT_blend_equation_separate */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#define __GLEE_GL_EXT_blend_equation_separate 1 +/* Constants */ +#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#ifndef GLEE_H_DEFINED_glBlendEquationSeparateEXT +#define GLEE_H_DEFINED_glBlendEquationSeparateEXT + typedef void (APIENTRYP GLEEPFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); + GLEE_EXTERN GLEEPFNGLBLENDEQUATIONSEPARATEEXTPROC GLeeFuncPtr_glBlendEquationSeparateEXT; + #define glBlendEquationSeparateEXT GLeeFuncPtr_glBlendEquationSeparateEXT +#endif +#endif + +/* GL_MESA_pack_invert */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#define __GLEE_GL_MESA_pack_invert 1 +/* Constants */ +#define GL_PACK_INVERT_MESA 0x8758 +#endif + +/* GL_MESA_ycbcr_texture */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#define __GLEE_GL_MESA_ycbcr_texture 1 +/* Constants */ +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif + +/* GL_EXT_pixel_buffer_object */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#define __GLEE_GL_EXT_pixel_buffer_object 1 +/* Constants */ +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif + +/* GL_NV_fragment_program_option */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#define __GLEE_GL_NV_fragment_program_option 1 +/* Constants */ +#endif + +/* GL_NV_fragment_program2 */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#define __GLEE_GL_NV_fragment_program2 1 +/* Constants */ +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif + +/* GL_NV_vertex_program2_option */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#define __GLEE_GL_NV_vertex_program2_option 1 +/* Constants */ +#endif + +/* GL_NV_vertex_program3 */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#define __GLEE_GL_NV_vertex_program3 1 +/* Constants */ +#endif + +/* GL_EXT_framebuffer_object */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#define __GLEE_GL_EXT_framebuffer_object 1 +/* Constants */ +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#ifndef GLEE_H_DEFINED_glIsRenderbufferEXT +#define GLEE_H_DEFINED_glIsRenderbufferEXT + typedef GLboolean (APIENTRYP GLEEPFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLISRENDERBUFFEREXTPROC GLeeFuncPtr_glIsRenderbufferEXT; + #define glIsRenderbufferEXT GLeeFuncPtr_glIsRenderbufferEXT +#endif +#ifndef GLEE_H_DEFINED_glBindRenderbufferEXT +#define GLEE_H_DEFINED_glBindRenderbufferEXT + typedef void (APIENTRYP GLEEPFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLBINDRENDERBUFFEREXTPROC GLeeFuncPtr_glBindRenderbufferEXT; + #define glBindRenderbufferEXT GLeeFuncPtr_glBindRenderbufferEXT +#endif +#ifndef GLEE_H_DEFINED_glDeleteRenderbuffersEXT +#define GLEE_H_DEFINED_glDeleteRenderbuffersEXT + typedef void (APIENTRYP GLEEPFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint * renderbuffers); + GLEE_EXTERN GLEEPFNGLDELETERENDERBUFFERSEXTPROC GLeeFuncPtr_glDeleteRenderbuffersEXT; + #define glDeleteRenderbuffersEXT GLeeFuncPtr_glDeleteRenderbuffersEXT +#endif +#ifndef GLEE_H_DEFINED_glGenRenderbuffersEXT +#define GLEE_H_DEFINED_glGenRenderbuffersEXT + typedef void (APIENTRYP GLEEPFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint * renderbuffers); + GLEE_EXTERN GLEEPFNGLGENRENDERBUFFERSEXTPROC GLeeFuncPtr_glGenRenderbuffersEXT; + #define glGenRenderbuffersEXT GLeeFuncPtr_glGenRenderbuffersEXT +#endif +#ifndef GLEE_H_DEFINED_glRenderbufferStorageEXT +#define GLEE_H_DEFINED_glRenderbufferStorageEXT + typedef void (APIENTRYP GLEEPFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLRENDERBUFFERSTORAGEEXTPROC GLeeFuncPtr_glRenderbufferStorageEXT; + #define glRenderbufferStorageEXT GLeeFuncPtr_glRenderbufferStorageEXT +#endif +#ifndef GLEE_H_DEFINED_glGetRenderbufferParameterivEXT +#define GLEE_H_DEFINED_glGetRenderbufferParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETRENDERBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetRenderbufferParameterivEXT; + #define glGetRenderbufferParameterivEXT GLeeFuncPtr_glGetRenderbufferParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glIsFramebufferEXT +#define GLEE_H_DEFINED_glIsFramebufferEXT + typedef GLboolean (APIENTRYP GLEEPFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); + GLEE_EXTERN GLEEPFNGLISFRAMEBUFFEREXTPROC GLeeFuncPtr_glIsFramebufferEXT; + #define glIsFramebufferEXT GLeeFuncPtr_glIsFramebufferEXT +#endif +#ifndef GLEE_H_DEFINED_glBindFramebufferEXT +#define GLEE_H_DEFINED_glBindFramebufferEXT + typedef void (APIENTRYP GLEEPFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); + GLEE_EXTERN GLEEPFNGLBINDFRAMEBUFFEREXTPROC GLeeFuncPtr_glBindFramebufferEXT; + #define glBindFramebufferEXT GLeeFuncPtr_glBindFramebufferEXT +#endif +#ifndef GLEE_H_DEFINED_glDeleteFramebuffersEXT +#define GLEE_H_DEFINED_glDeleteFramebuffersEXT + typedef void (APIENTRYP GLEEPFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint * framebuffers); + GLEE_EXTERN GLEEPFNGLDELETEFRAMEBUFFERSEXTPROC GLeeFuncPtr_glDeleteFramebuffersEXT; + #define glDeleteFramebuffersEXT GLeeFuncPtr_glDeleteFramebuffersEXT +#endif +#ifndef GLEE_H_DEFINED_glGenFramebuffersEXT +#define GLEE_H_DEFINED_glGenFramebuffersEXT + typedef void (APIENTRYP GLEEPFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint * framebuffers); + GLEE_EXTERN GLEEPFNGLGENFRAMEBUFFERSEXTPROC GLeeFuncPtr_glGenFramebuffersEXT; + #define glGenFramebuffersEXT GLeeFuncPtr_glGenFramebuffersEXT +#endif +#ifndef GLEE_H_DEFINED_glCheckFramebufferStatusEXT +#define GLEE_H_DEFINED_glCheckFramebufferStatusEXT + typedef GLenum (APIENTRYP GLEEPFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLCHECKFRAMEBUFFERSTATUSEXTPROC GLeeFuncPtr_glCheckFramebufferStatusEXT; + #define glCheckFramebufferStatusEXT GLeeFuncPtr_glCheckFramebufferStatusEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTexture1DEXT +#define GLEE_H_DEFINED_glFramebufferTexture1DEXT + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURE1DEXTPROC GLeeFuncPtr_glFramebufferTexture1DEXT; + #define glFramebufferTexture1DEXT GLeeFuncPtr_glFramebufferTexture1DEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTexture2DEXT +#define GLEE_H_DEFINED_glFramebufferTexture2DEXT + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURE2DEXTPROC GLeeFuncPtr_glFramebufferTexture2DEXT; + #define glFramebufferTexture2DEXT GLeeFuncPtr_glFramebufferTexture2DEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTexture3DEXT +#define GLEE_H_DEFINED_glFramebufferTexture3DEXT + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURE3DEXTPROC GLeeFuncPtr_glFramebufferTexture3DEXT; + #define glFramebufferTexture3DEXT GLeeFuncPtr_glFramebufferTexture3DEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferRenderbufferEXT +#define GLEE_H_DEFINED_glFramebufferRenderbufferEXT + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERRENDERBUFFEREXTPROC GLeeFuncPtr_glFramebufferRenderbufferEXT; + #define glFramebufferRenderbufferEXT GLeeFuncPtr_glFramebufferRenderbufferEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFramebufferAttachmentParameterivEXT +#define GLEE_H_DEFINED_glGetFramebufferAttachmentParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC GLeeFuncPtr_glGetFramebufferAttachmentParameterivEXT; + #define glGetFramebufferAttachmentParameterivEXT GLeeFuncPtr_glGetFramebufferAttachmentParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGenerateMipmapEXT +#define GLEE_H_DEFINED_glGenerateMipmapEXT + typedef void (APIENTRYP GLEEPFNGLGENERATEMIPMAPEXTPROC) (GLenum target); + GLEE_EXTERN GLEEPFNGLGENERATEMIPMAPEXTPROC GLeeFuncPtr_glGenerateMipmapEXT; + #define glGenerateMipmapEXT GLeeFuncPtr_glGenerateMipmapEXT +#endif +#endif + +/* GL_GREMEDY_string_marker */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +#define __GLEE_GL_GREMEDY_string_marker 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glStringMarkerGREMEDY +#define GLEE_H_DEFINED_glStringMarkerGREMEDY + typedef void (APIENTRYP GLEEPFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid * string); + GLEE_EXTERN GLEEPFNGLSTRINGMARKERGREMEDYPROC GLeeFuncPtr_glStringMarkerGREMEDY; + #define glStringMarkerGREMEDY GLeeFuncPtr_glStringMarkerGREMEDY +#endif +#endif + +/* GL_EXT_packed_depth_stencil */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 +#define __GLEE_GL_EXT_packed_depth_stencil 1 +/* Constants */ +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif + +/* GL_EXT_stencil_clear_tag */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 +#define __GLEE_GL_EXT_stencil_clear_tag 1 +/* Constants */ +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +#ifndef GLEE_H_DEFINED_glStencilClearTagEXT +#define GLEE_H_DEFINED_glStencilClearTagEXT + typedef void (APIENTRYP GLEEPFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); + GLEE_EXTERN GLEEPFNGLSTENCILCLEARTAGEXTPROC GLeeFuncPtr_glStencilClearTagEXT; + #define glStencilClearTagEXT GLeeFuncPtr_glStencilClearTagEXT +#endif +#endif + +/* GL_EXT_texture_sRGB */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 +#define __GLEE_GL_EXT_texture_sRGB 1 +/* Constants */ +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif + +/* GL_EXT_framebuffer_blit */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#define __GLEE_GL_EXT_framebuffer_blit 1 +/* Constants */ +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#ifndef GLEE_H_DEFINED_glBlitFramebufferEXT +#define GLEE_H_DEFINED_glBlitFramebufferEXT + typedef void (APIENTRYP GLEEPFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + GLEE_EXTERN GLEEPFNGLBLITFRAMEBUFFEREXTPROC GLeeFuncPtr_glBlitFramebufferEXT; + #define glBlitFramebufferEXT GLeeFuncPtr_glBlitFramebufferEXT +#endif +#endif + +/* GL_EXT_framebuffer_multisample */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#define __GLEE_GL_EXT_framebuffer_multisample 1 +/* Constants */ +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#ifndef GLEE_H_DEFINED_glRenderbufferStorageMultisampleEXT +#define GLEE_H_DEFINED_glRenderbufferStorageMultisampleEXT + typedef void (APIENTRYP GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC GLeeFuncPtr_glRenderbufferStorageMultisampleEXT; + #define glRenderbufferStorageMultisampleEXT GLeeFuncPtr_glRenderbufferStorageMultisampleEXT +#endif +#endif + +/* GL_MESAX_texture_stack */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 +#define __GLEE_GL_MESAX_texture_stack 1 +/* Constants */ +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif + +/* GL_EXT_timer_query */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 +#define __GLEE_GL_EXT_timer_query 1 +/* Constants */ +#define GL_TIME_ELAPSED_EXT 0x88BF +#ifndef GLEE_H_DEFINED_glGetQueryObjecti64vEXT +#define GLEE_H_DEFINED_glGetQueryObjecti64vEXT + typedef void (APIENTRYP GLEEPFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT * params); + GLEE_EXTERN GLEEPFNGLGETQUERYOBJECTI64VEXTPROC GLeeFuncPtr_glGetQueryObjecti64vEXT; + #define glGetQueryObjecti64vEXT GLeeFuncPtr_glGetQueryObjecti64vEXT +#endif +#ifndef GLEE_H_DEFINED_glGetQueryObjectui64vEXT +#define GLEE_H_DEFINED_glGetQueryObjectui64vEXT + typedef void (APIENTRYP GLEEPFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT * params); + GLEE_EXTERN GLEEPFNGLGETQUERYOBJECTUI64VEXTPROC GLeeFuncPtr_glGetQueryObjectui64vEXT; + #define glGetQueryObjectui64vEXT GLeeFuncPtr_glGetQueryObjectui64vEXT +#endif +#endif + +/* GL_EXT_gpu_program_parameters */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 +#define __GLEE_GL_EXT_gpu_program_parameters 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glProgramEnvParameters4fvEXT +#define GLEE_H_DEFINED_glProgramEnvParameters4fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETERS4FVEXTPROC GLeeFuncPtr_glProgramEnvParameters4fvEXT; + #define glProgramEnvParameters4fvEXT GLeeFuncPtr_glProgramEnvParameters4fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameters4fvEXT +#define GLEE_H_DEFINED_glProgramLocalParameters4fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC GLeeFuncPtr_glProgramLocalParameters4fvEXT; + #define glProgramLocalParameters4fvEXT GLeeFuncPtr_glProgramLocalParameters4fvEXT +#endif +#endif + +/* GL_APPLE_flush_buffer_range */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 +#define __GLEE_GL_APPLE_flush_buffer_range 1 +/* Constants */ +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +#ifndef GLEE_H_DEFINED_glBufferParameteriAPPLE +#define GLEE_H_DEFINED_glBufferParameteriAPPLE + typedef void (APIENTRYP GLEEPFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLBUFFERPARAMETERIAPPLEPROC GLeeFuncPtr_glBufferParameteriAPPLE; + #define glBufferParameteriAPPLE GLeeFuncPtr_glBufferParameteriAPPLE +#endif +#ifndef GLEE_H_DEFINED_glFlushMappedBufferRangeAPPLE +#define GLEE_H_DEFINED_glFlushMappedBufferRangeAPPLE + typedef void (APIENTRYP GLEEPFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); + GLEE_EXTERN GLEEPFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC GLeeFuncPtr_glFlushMappedBufferRangeAPPLE; + #define glFlushMappedBufferRangeAPPLE GLeeFuncPtr_glFlushMappedBufferRangeAPPLE +#endif +#endif + +/* GL_EXT_gpu_shader4 */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#define __GLEE_GL_EXT_gpu_shader4 1 +/* Constants */ +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#ifndef GLEE_H_DEFINED_glGetUniformuivEXT +#define GLEE_H_DEFINED_glGetUniformuivEXT + typedef void (APIENTRYP GLEEPFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETUNIFORMUIVEXTPROC GLeeFuncPtr_glGetUniformuivEXT; + #define glGetUniformuivEXT GLeeFuncPtr_glGetUniformuivEXT +#endif +#ifndef GLEE_H_DEFINED_glBindFragDataLocationEXT +#define GLEE_H_DEFINED_glBindFragDataLocationEXT + typedef void (APIENTRYP GLEEPFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar * name); + GLEE_EXTERN GLEEPFNGLBINDFRAGDATALOCATIONEXTPROC GLeeFuncPtr_glBindFragDataLocationEXT; + #define glBindFragDataLocationEXT GLeeFuncPtr_glBindFragDataLocationEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFragDataLocationEXT +#define GLEE_H_DEFINED_glGetFragDataLocationEXT + typedef GLint (APIENTRYP GLEEPFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETFRAGDATALOCATIONEXTPROC GLeeFuncPtr_glGetFragDataLocationEXT; + #define glGetFragDataLocationEXT GLeeFuncPtr_glGetFragDataLocationEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform1uiEXT +#define GLEE_H_DEFINED_glUniform1uiEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); + GLEE_EXTERN GLEEPFNGLUNIFORM1UIEXTPROC GLeeFuncPtr_glUniform1uiEXT; + #define glUniform1uiEXT GLeeFuncPtr_glUniform1uiEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform2uiEXT +#define GLEE_H_DEFINED_glUniform2uiEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); + GLEE_EXTERN GLEEPFNGLUNIFORM2UIEXTPROC GLeeFuncPtr_glUniform2uiEXT; + #define glUniform2uiEXT GLeeFuncPtr_glUniform2uiEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform3uiEXT +#define GLEE_H_DEFINED_glUniform3uiEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); + GLEE_EXTERN GLEEPFNGLUNIFORM3UIEXTPROC GLeeFuncPtr_glUniform3uiEXT; + #define glUniform3uiEXT GLeeFuncPtr_glUniform3uiEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform4uiEXT +#define GLEE_H_DEFINED_glUniform4uiEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + GLEE_EXTERN GLEEPFNGLUNIFORM4UIEXTPROC GLeeFuncPtr_glUniform4uiEXT; + #define glUniform4uiEXT GLeeFuncPtr_glUniform4uiEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform1uivEXT +#define GLEE_H_DEFINED_glUniform1uivEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM1UIVEXTPROC GLeeFuncPtr_glUniform1uivEXT; + #define glUniform1uivEXT GLeeFuncPtr_glUniform1uivEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform2uivEXT +#define GLEE_H_DEFINED_glUniform2uivEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM2UIVEXTPROC GLeeFuncPtr_glUniform2uivEXT; + #define glUniform2uivEXT GLeeFuncPtr_glUniform2uivEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform3uivEXT +#define GLEE_H_DEFINED_glUniform3uivEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM3UIVEXTPROC GLeeFuncPtr_glUniform3uivEXT; + #define glUniform3uivEXT GLeeFuncPtr_glUniform3uivEXT +#endif +#ifndef GLEE_H_DEFINED_glUniform4uivEXT +#define GLEE_H_DEFINED_glUniform4uivEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLUNIFORM4UIVEXTPROC GLeeFuncPtr_glUniform4uivEXT; + #define glUniform4uivEXT GLeeFuncPtr_glUniform4uivEXT +#endif +#endif + +/* GL_EXT_draw_instanced */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +#define __GLEE_GL_EXT_draw_instanced 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glDrawArraysInstancedEXT +#define GLEE_H_DEFINED_glDrawArraysInstancedEXT + typedef void (APIENTRYP GLEEPFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLDRAWARRAYSINSTANCEDEXTPROC GLeeFuncPtr_glDrawArraysInstancedEXT; + #define glDrawArraysInstancedEXT GLeeFuncPtr_glDrawArraysInstancedEXT +#endif +#ifndef GLEE_H_DEFINED_glDrawElementsInstancedEXT +#define GLEE_H_DEFINED_glDrawElementsInstancedEXT + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount); + GLEE_EXTERN GLEEPFNGLDRAWELEMENTSINSTANCEDEXTPROC GLeeFuncPtr_glDrawElementsInstancedEXT; + #define glDrawElementsInstancedEXT GLeeFuncPtr_glDrawElementsInstancedEXT +#endif +#endif + +/* GL_EXT_packed_float */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#define __GLEE_GL_EXT_packed_float 1 +/* Constants */ +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif + +/* GL_EXT_texture_array */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#define __GLEE_GL_EXT_texture_array 1 +/* Constants */ +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#endif + +/* GL_EXT_texture_buffer_object */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#define __GLEE_GL_EXT_texture_buffer_object 1 +/* Constants */ +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#ifndef GLEE_H_DEFINED_glTexBufferEXT +#define GLEE_H_DEFINED_glTexBufferEXT + typedef void (APIENTRYP GLEEPFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); + GLEE_EXTERN GLEEPFNGLTEXBUFFEREXTPROC GLeeFuncPtr_glTexBufferEXT; + #define glTexBufferEXT GLeeFuncPtr_glTexBufferEXT +#endif +#endif + +/* GL_EXT_texture_compression_latc */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#define __GLEE_GL_EXT_texture_compression_latc 1 +/* Constants */ +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif + +/* GL_EXT_texture_compression_rgtc */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#define __GLEE_GL_EXT_texture_compression_rgtc 1 +/* Constants */ +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + +/* GL_EXT_texture_shared_exponent */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#define __GLEE_GL_EXT_texture_shared_exponent 1 +/* Constants */ +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif + +/* GL_NV_depth_buffer_float */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#define __GLEE_GL_NV_depth_buffer_float 1 +/* Constants */ +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#ifndef GLEE_H_DEFINED_glDepthRangedNV +#define GLEE_H_DEFINED_glDepthRangedNV + typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); + GLEE_EXTERN GLEEPFNGLDEPTHRANGEDNVPROC GLeeFuncPtr_glDepthRangedNV; + #define glDepthRangedNV GLeeFuncPtr_glDepthRangedNV +#endif +#ifndef GLEE_H_DEFINED_glClearDepthdNV +#define GLEE_H_DEFINED_glClearDepthdNV + typedef void (APIENTRYP GLEEPFNGLCLEARDEPTHDNVPROC) (GLdouble depth); + GLEE_EXTERN GLEEPFNGLCLEARDEPTHDNVPROC GLeeFuncPtr_glClearDepthdNV; + #define glClearDepthdNV GLeeFuncPtr_glClearDepthdNV +#endif +#ifndef GLEE_H_DEFINED_glDepthBoundsdNV +#define GLEE_H_DEFINED_glDepthBoundsdNV + typedef void (APIENTRYP GLEEPFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); + GLEE_EXTERN GLEEPFNGLDEPTHBOUNDSDNVPROC GLeeFuncPtr_glDepthBoundsdNV; + #define glDepthBoundsdNV GLeeFuncPtr_glDepthBoundsdNV +#endif +#endif + +/* GL_NV_framebuffer_multisample_coverage */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#define __GLEE_GL_NV_framebuffer_multisample_coverage 1 +/* Constants */ +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#ifndef GLEE_H_DEFINED_glRenderbufferStorageMultisampleCoverageNV +#define GLEE_H_DEFINED_glRenderbufferStorageMultisampleCoverageNV + typedef void (APIENTRYP GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC GLeeFuncPtr_glRenderbufferStorageMultisampleCoverageNV; + #define glRenderbufferStorageMultisampleCoverageNV GLeeFuncPtr_glRenderbufferStorageMultisampleCoverageNV +#endif +#endif + +/* GL_EXT_framebuffer_sRGB */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#define __GLEE_GL_EXT_framebuffer_sRGB 1 +/* Constants */ +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +/* GL_NV_geometry_shader4 */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 +#define __GLEE_GL_NV_geometry_shader4 1 +/* Constants */ +#endif + +/* GL_NV_parameter_buffer_object */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#define __GLEE_GL_NV_parameter_buffer_object 1 +/* Constants */ +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +#ifndef GLEE_H_DEFINED_glProgramBufferParametersfvNV +#define GLEE_H_DEFINED_glProgramBufferParametersfvNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC GLeeFuncPtr_glProgramBufferParametersfvNV; + #define glProgramBufferParametersfvNV GLeeFuncPtr_glProgramBufferParametersfvNV +#endif +#ifndef GLEE_H_DEFINED_glProgramBufferParametersIivNV +#define GLEE_H_DEFINED_glProgramBufferParametersIivNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC GLeeFuncPtr_glProgramBufferParametersIivNV; + #define glProgramBufferParametersIivNV GLeeFuncPtr_glProgramBufferParametersIivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramBufferParametersIuivNV +#define GLEE_H_DEFINED_glProgramBufferParametersIuivNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC GLeeFuncPtr_glProgramBufferParametersIuivNV; + #define glProgramBufferParametersIuivNV GLeeFuncPtr_glProgramBufferParametersIuivNV +#endif +#endif + +/* GL_EXT_draw_buffers2 */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +#define __GLEE_GL_EXT_draw_buffers2 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glColorMaskIndexedEXT +#define GLEE_H_DEFINED_glColorMaskIndexedEXT + typedef void (APIENTRYP GLEEPFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + GLEE_EXTERN GLEEPFNGLCOLORMASKINDEXEDEXTPROC GLeeFuncPtr_glColorMaskIndexedEXT; + #define glColorMaskIndexedEXT GLeeFuncPtr_glColorMaskIndexedEXT +#endif +#ifndef GLEE_H_DEFINED_glGetBooleanIndexedvEXT +#define GLEE_H_DEFINED_glGetBooleanIndexedvEXT + typedef void (APIENTRYP GLEEPFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean * data); + GLEE_EXTERN GLEEPFNGLGETBOOLEANINDEXEDVEXTPROC GLeeFuncPtr_glGetBooleanIndexedvEXT; + #define glGetBooleanIndexedvEXT GLeeFuncPtr_glGetBooleanIndexedvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetIntegerIndexedvEXT +#define GLEE_H_DEFINED_glGetIntegerIndexedvEXT + typedef void (APIENTRYP GLEEPFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint * data); + GLEE_EXTERN GLEEPFNGLGETINTEGERINDEXEDVEXTPROC GLeeFuncPtr_glGetIntegerIndexedvEXT; + #define glGetIntegerIndexedvEXT GLeeFuncPtr_glGetIntegerIndexedvEXT +#endif +#ifndef GLEE_H_DEFINED_glEnableIndexedEXT +#define GLEE_H_DEFINED_glEnableIndexedEXT + typedef void (APIENTRYP GLEEPFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); + GLEE_EXTERN GLEEPFNGLENABLEINDEXEDEXTPROC GLeeFuncPtr_glEnableIndexedEXT; + #define glEnableIndexedEXT GLeeFuncPtr_glEnableIndexedEXT +#endif +#ifndef GLEE_H_DEFINED_glDisableIndexedEXT +#define GLEE_H_DEFINED_glDisableIndexedEXT + typedef void (APIENTRYP GLEEPFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); + GLEE_EXTERN GLEEPFNGLDISABLEINDEXEDEXTPROC GLeeFuncPtr_glDisableIndexedEXT; + #define glDisableIndexedEXT GLeeFuncPtr_glDisableIndexedEXT +#endif +#ifndef GLEE_H_DEFINED_glIsEnabledIndexedEXT +#define GLEE_H_DEFINED_glIsEnabledIndexedEXT + typedef GLboolean (APIENTRYP GLEEPFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); + GLEE_EXTERN GLEEPFNGLISENABLEDINDEXEDEXTPROC GLeeFuncPtr_glIsEnabledIndexedEXT; + #define glIsEnabledIndexedEXT GLeeFuncPtr_glIsEnabledIndexedEXT +#endif +#endif + +/* GL_NV_transform_feedback */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#define __GLEE_GL_NV_transform_feedback 1 +/* Constants */ +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#ifndef GLEE_H_DEFINED_glBeginTransformFeedbackNV +#define GLEE_H_DEFINED_glBeginTransformFeedbackNV + typedef void (APIENTRYP GLEEPFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); + GLEE_EXTERN GLEEPFNGLBEGINTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glBeginTransformFeedbackNV; + #define glBeginTransformFeedbackNV GLeeFuncPtr_glBeginTransformFeedbackNV +#endif +#ifndef GLEE_H_DEFINED_glEndTransformFeedbackNV +#define GLEE_H_DEFINED_glEndTransformFeedbackNV + typedef void (APIENTRYP GLEEPFNGLENDTRANSFORMFEEDBACKNVPROC) (); + GLEE_EXTERN GLEEPFNGLENDTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glEndTransformFeedbackNV; + #define glEndTransformFeedbackNV GLeeFuncPtr_glEndTransformFeedbackNV +#endif +#ifndef GLEE_H_DEFINED_glTransformFeedbackAttribsNV +#define GLEE_H_DEFINED_glTransformFeedbackAttribsNV + typedef void (APIENTRYP GLEEPFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint * attribs, GLenum bufferMode); + GLEE_EXTERN GLEEPFNGLTRANSFORMFEEDBACKATTRIBSNVPROC GLeeFuncPtr_glTransformFeedbackAttribsNV; + #define glTransformFeedbackAttribsNV GLeeFuncPtr_glTransformFeedbackAttribsNV +#endif +#ifndef GLEE_H_DEFINED_glBindBufferRangeNV +#define GLEE_H_DEFINED_glBindBufferRangeNV + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + GLEE_EXTERN GLEEPFNGLBINDBUFFERRANGENVPROC GLeeFuncPtr_glBindBufferRangeNV; + #define glBindBufferRangeNV GLeeFuncPtr_glBindBufferRangeNV +#endif +#ifndef GLEE_H_DEFINED_glBindBufferOffsetNV +#define GLEE_H_DEFINED_glBindBufferOffsetNV + typedef void (APIENTRYP GLEEPFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); + GLEE_EXTERN GLEEPFNGLBINDBUFFEROFFSETNVPROC GLeeFuncPtr_glBindBufferOffsetNV; + #define glBindBufferOffsetNV GLeeFuncPtr_glBindBufferOffsetNV +#endif +#ifndef GLEE_H_DEFINED_glBindBufferBaseNV +#define GLEE_H_DEFINED_glBindBufferBaseNV + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); + GLEE_EXTERN GLEEPFNGLBINDBUFFERBASENVPROC GLeeFuncPtr_glBindBufferBaseNV; + #define glBindBufferBaseNV GLeeFuncPtr_glBindBufferBaseNV +#endif +#ifndef GLEE_H_DEFINED_glTransformFeedbackVaryingsNV +#define GLEE_H_DEFINED_glTransformFeedbackVaryingsNV + typedef void (APIENTRYP GLEEPFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint * locations, GLenum bufferMode); + GLEE_EXTERN GLEEPFNGLTRANSFORMFEEDBACKVARYINGSNVPROC GLeeFuncPtr_glTransformFeedbackVaryingsNV; + #define glTransformFeedbackVaryingsNV GLeeFuncPtr_glTransformFeedbackVaryingsNV +#endif +#ifndef GLEE_H_DEFINED_glActiveVaryingNV +#define GLEE_H_DEFINED_glActiveVaryingNV + typedef void (APIENTRYP GLEEPFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar * name); + GLEE_EXTERN GLEEPFNGLACTIVEVARYINGNVPROC GLeeFuncPtr_glActiveVaryingNV; + #define glActiveVaryingNV GLeeFuncPtr_glActiveVaryingNV +#endif +#ifndef GLEE_H_DEFINED_glGetVaryingLocationNV +#define GLEE_H_DEFINED_glGetVaryingLocationNV + typedef GLint (APIENTRYP GLEEPFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETVARYINGLOCATIONNVPROC GLeeFuncPtr_glGetVaryingLocationNV; + #define glGetVaryingLocationNV GLeeFuncPtr_glGetVaryingLocationNV +#endif +#ifndef GLEE_H_DEFINED_glGetActiveVaryingNV +#define GLEE_H_DEFINED_glGetActiveVaryingNV + typedef void (APIENTRYP GLEEPFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); + GLEE_EXTERN GLEEPFNGLGETACTIVEVARYINGNVPROC GLeeFuncPtr_glGetActiveVaryingNV; + #define glGetActiveVaryingNV GLeeFuncPtr_glGetActiveVaryingNV +#endif +#ifndef GLEE_H_DEFINED_glGetTransformFeedbackVaryingNV +#define GLEE_H_DEFINED_glGetTransformFeedbackVaryingNV + typedef void (APIENTRYP GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint * location); + GLEE_EXTERN GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC GLeeFuncPtr_glGetTransformFeedbackVaryingNV; + #define glGetTransformFeedbackVaryingNV GLeeFuncPtr_glGetTransformFeedbackVaryingNV +#endif +#endif + +/* GL_EXT_bindable_uniform */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#define __GLEE_GL_EXT_bindable_uniform 1 +/* Constants */ +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#ifndef GLEE_H_DEFINED_glUniformBufferEXT +#define GLEE_H_DEFINED_glUniformBufferEXT + typedef void (APIENTRYP GLEEPFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); + GLEE_EXTERN GLEEPFNGLUNIFORMBUFFEREXTPROC GLeeFuncPtr_glUniformBufferEXT; + #define glUniformBufferEXT GLeeFuncPtr_glUniformBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glGetUniformBufferSizeEXT +#define GLEE_H_DEFINED_glGetUniformBufferSizeEXT + typedef GLint (APIENTRYP GLEEPFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); + GLEE_EXTERN GLEEPFNGLGETUNIFORMBUFFERSIZEEXTPROC GLeeFuncPtr_glGetUniformBufferSizeEXT; + #define glGetUniformBufferSizeEXT GLeeFuncPtr_glGetUniformBufferSizeEXT +#endif +#ifndef GLEE_H_DEFINED_glGetUniformOffsetEXT +#define GLEE_H_DEFINED_glGetUniformOffsetEXT + typedef GLintptr (APIENTRYP GLEEPFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); + GLEE_EXTERN GLEEPFNGLGETUNIFORMOFFSETEXTPROC GLeeFuncPtr_glGetUniformOffsetEXT; + #define glGetUniformOffsetEXT GLeeFuncPtr_glGetUniformOffsetEXT +#endif +#endif + +/* GL_EXT_texture_integer */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#define __GLEE_GL_EXT_texture_integer 1 +/* Constants */ +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#ifndef GLEE_H_DEFINED_glTexParameterIivEXT +#define GLEE_H_DEFINED_glTexParameterIivEXT + typedef void (APIENTRYP GLEEPFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLTEXPARAMETERIIVEXTPROC GLeeFuncPtr_glTexParameterIivEXT; + #define glTexParameterIivEXT GLeeFuncPtr_glTexParameterIivEXT +#endif +#ifndef GLEE_H_DEFINED_glTexParameterIuivEXT +#define GLEE_H_DEFINED_glTexParameterIuivEXT + typedef void (APIENTRYP GLEEPFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint * params); + GLEE_EXTERN GLEEPFNGLTEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glTexParameterIuivEXT; + #define glTexParameterIuivEXT GLeeFuncPtr_glTexParameterIuivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTexParameterIivEXT +#define GLEE_H_DEFINED_glGetTexParameterIivEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETTEXPARAMETERIIVEXTPROC GLeeFuncPtr_glGetTexParameterIivEXT; + #define glGetTexParameterIivEXT GLeeFuncPtr_glGetTexParameterIivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTexParameterIuivEXT +#define GLEE_H_DEFINED_glGetTexParameterIuivEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETTEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetTexParameterIuivEXT; + #define glGetTexParameterIuivEXT GLeeFuncPtr_glGetTexParameterIuivEXT +#endif +#ifndef GLEE_H_DEFINED_glClearColorIiEXT +#define GLEE_H_DEFINED_glClearColorIiEXT + typedef void (APIENTRYP GLEEPFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); + GLEE_EXTERN GLEEPFNGLCLEARCOLORIIEXTPROC GLeeFuncPtr_glClearColorIiEXT; + #define glClearColorIiEXT GLeeFuncPtr_glClearColorIiEXT +#endif +#ifndef GLEE_H_DEFINED_glClearColorIuiEXT +#define GLEE_H_DEFINED_glClearColorIuiEXT + typedef void (APIENTRYP GLEEPFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); + GLEE_EXTERN GLEEPFNGLCLEARCOLORIUIEXTPROC GLeeFuncPtr_glClearColorIuiEXT; + #define glClearColorIuiEXT GLeeFuncPtr_glClearColorIuiEXT +#endif +#endif + +/* GL_GREMEDY_frame_terminator */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 +#define __GLEE_GL_GREMEDY_frame_terminator 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glFrameTerminatorGREMEDY +#define GLEE_H_DEFINED_glFrameTerminatorGREMEDY + typedef void (APIENTRYP GLEEPFNGLFRAMETERMINATORGREMEDYPROC) (); + GLEE_EXTERN GLEEPFNGLFRAMETERMINATORGREMEDYPROC GLeeFuncPtr_glFrameTerminatorGREMEDY; + #define glFrameTerminatorGREMEDY GLeeFuncPtr_glFrameTerminatorGREMEDY +#endif +#endif + +/* GL_NV_conditional_render */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 +#define __GLEE_GL_NV_conditional_render 1 +/* Constants */ +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +#ifndef GLEE_H_DEFINED_glBeginConditionalRenderNV +#define GLEE_H_DEFINED_glBeginConditionalRenderNV + typedef void (APIENTRYP GLEEPFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); + GLEE_EXTERN GLEEPFNGLBEGINCONDITIONALRENDERNVPROC GLeeFuncPtr_glBeginConditionalRenderNV; + #define glBeginConditionalRenderNV GLeeFuncPtr_glBeginConditionalRenderNV +#endif +#ifndef GLEE_H_DEFINED_glEndConditionalRenderNV +#define GLEE_H_DEFINED_glEndConditionalRenderNV + typedef void (APIENTRYP GLEEPFNGLENDCONDITIONALRENDERNVPROC) (); + GLEE_EXTERN GLEEPFNGLENDCONDITIONALRENDERNVPROC GLeeFuncPtr_glEndConditionalRenderNV; + #define glEndConditionalRenderNV GLeeFuncPtr_glEndConditionalRenderNV +#endif +#endif + +/* GL_NV_present_video */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 +#define __GLEE_GL_NV_present_video 1 +/* Constants */ +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B +#endif + +/* GL_EXT_transform_feedback */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 +#define __GLEE_GL_EXT_transform_feedback 1 +/* Constants */ +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#ifndef GLEE_H_DEFINED_glBeginTransformFeedbackEXT +#define GLEE_H_DEFINED_glBeginTransformFeedbackEXT + typedef void (APIENTRYP GLEEPFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); + GLEE_EXTERN GLEEPFNGLBEGINTRANSFORMFEEDBACKEXTPROC GLeeFuncPtr_glBeginTransformFeedbackEXT; + #define glBeginTransformFeedbackEXT GLeeFuncPtr_glBeginTransformFeedbackEXT +#endif +#ifndef GLEE_H_DEFINED_glEndTransformFeedbackEXT +#define GLEE_H_DEFINED_glEndTransformFeedbackEXT + typedef void (APIENTRYP GLEEPFNGLENDTRANSFORMFEEDBACKEXTPROC) (); + GLEE_EXTERN GLEEPFNGLENDTRANSFORMFEEDBACKEXTPROC GLeeFuncPtr_glEndTransformFeedbackEXT; + #define glEndTransformFeedbackEXT GLeeFuncPtr_glEndTransformFeedbackEXT +#endif +#ifndef GLEE_H_DEFINED_glBindBufferRangeEXT +#define GLEE_H_DEFINED_glBindBufferRangeEXT + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + GLEE_EXTERN GLEEPFNGLBINDBUFFERRANGEEXTPROC GLeeFuncPtr_glBindBufferRangeEXT; + #define glBindBufferRangeEXT GLeeFuncPtr_glBindBufferRangeEXT +#endif +#ifndef GLEE_H_DEFINED_glBindBufferOffsetEXT +#define GLEE_H_DEFINED_glBindBufferOffsetEXT + typedef void (APIENTRYP GLEEPFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); + GLEE_EXTERN GLEEPFNGLBINDBUFFEROFFSETEXTPROC GLeeFuncPtr_glBindBufferOffsetEXT; + #define glBindBufferOffsetEXT GLeeFuncPtr_glBindBufferOffsetEXT +#endif +#ifndef GLEE_H_DEFINED_glBindBufferBaseEXT +#define GLEE_H_DEFINED_glBindBufferBaseEXT + typedef void (APIENTRYP GLEEPFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); + GLEE_EXTERN GLEEPFNGLBINDBUFFERBASEEXTPROC GLeeFuncPtr_glBindBufferBaseEXT; + #define glBindBufferBaseEXT GLeeFuncPtr_glBindBufferBaseEXT +#endif +#ifndef GLEE_H_DEFINED_glTransformFeedbackVaryingsEXT +#define GLEE_H_DEFINED_glTransformFeedbackVaryingsEXT + typedef void (APIENTRYP GLEEPFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLint * locations, GLenum bufferMode); + GLEE_EXTERN GLEEPFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC GLeeFuncPtr_glTransformFeedbackVaryingsEXT; + #define glTransformFeedbackVaryingsEXT GLeeFuncPtr_glTransformFeedbackVaryingsEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTransformFeedbackVaryingEXT +#define GLEE_H_DEFINED_glGetTransformFeedbackVaryingEXT + typedef void (APIENTRYP GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLint * location); + GLEE_EXTERN GLEEPFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC GLeeFuncPtr_glGetTransformFeedbackVaryingEXT; + #define glGetTransformFeedbackVaryingEXT GLeeFuncPtr_glGetTransformFeedbackVaryingEXT +#endif +#endif + +/* GL_EXT_direct_state_access */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 +#define __GLEE_GL_EXT_direct_state_access 1 +/* Constants */ +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +#ifndef GLEE_H_DEFINED_glClientAttribDefaultEXT +#define GLEE_H_DEFINED_glClientAttribDefaultEXT + typedef void (APIENTRYP GLEEPFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); + GLEE_EXTERN GLEEPFNGLCLIENTATTRIBDEFAULTEXTPROC GLeeFuncPtr_glClientAttribDefaultEXT; + #define glClientAttribDefaultEXT GLeeFuncPtr_glClientAttribDefaultEXT +#endif +#ifndef GLEE_H_DEFINED_glPushClientAttribDefaultEXT +#define GLEE_H_DEFINED_glPushClientAttribDefaultEXT + typedef void (APIENTRYP GLEEPFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); + GLEE_EXTERN GLEEPFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC GLeeFuncPtr_glPushClientAttribDefaultEXT; + #define glPushClientAttribDefaultEXT GLeeFuncPtr_glPushClientAttribDefaultEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixLoadfEXT +#define GLEE_H_DEFINED_glMatrixLoadfEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat * m); + GLEE_EXTERN GLEEPFNGLMATRIXLOADFEXTPROC GLeeFuncPtr_glMatrixLoadfEXT; + #define glMatrixLoadfEXT GLeeFuncPtr_glMatrixLoadfEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixLoaddEXT +#define GLEE_H_DEFINED_glMatrixLoaddEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble * m); + GLEE_EXTERN GLEEPFNGLMATRIXLOADDEXTPROC GLeeFuncPtr_glMatrixLoaddEXT; + #define glMatrixLoaddEXT GLeeFuncPtr_glMatrixLoaddEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixMultfEXT +#define GLEE_H_DEFINED_glMatrixMultfEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat * m); + GLEE_EXTERN GLEEPFNGLMATRIXMULTFEXTPROC GLeeFuncPtr_glMatrixMultfEXT; + #define glMatrixMultfEXT GLeeFuncPtr_glMatrixMultfEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixMultdEXT +#define GLEE_H_DEFINED_glMatrixMultdEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble * m); + GLEE_EXTERN GLEEPFNGLMATRIXMULTDEXTPROC GLeeFuncPtr_glMatrixMultdEXT; + #define glMatrixMultdEXT GLeeFuncPtr_glMatrixMultdEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixLoadIdentityEXT +#define GLEE_H_DEFINED_glMatrixLoadIdentityEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLMATRIXLOADIDENTITYEXTPROC GLeeFuncPtr_glMatrixLoadIdentityEXT; + #define glMatrixLoadIdentityEXT GLeeFuncPtr_glMatrixLoadIdentityEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixRotatefEXT +#define GLEE_H_DEFINED_glMatrixRotatefEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLMATRIXROTATEFEXTPROC GLeeFuncPtr_glMatrixRotatefEXT; + #define glMatrixRotatefEXT GLeeFuncPtr_glMatrixRotatefEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixRotatedEXT +#define GLEE_H_DEFINED_glMatrixRotatedEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLMATRIXROTATEDEXTPROC GLeeFuncPtr_glMatrixRotatedEXT; + #define glMatrixRotatedEXT GLeeFuncPtr_glMatrixRotatedEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixScalefEXT +#define GLEE_H_DEFINED_glMatrixScalefEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLMATRIXSCALEFEXTPROC GLeeFuncPtr_glMatrixScalefEXT; + #define glMatrixScalefEXT GLeeFuncPtr_glMatrixScalefEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixScaledEXT +#define GLEE_H_DEFINED_glMatrixScaledEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLMATRIXSCALEDEXTPROC GLeeFuncPtr_glMatrixScaledEXT; + #define glMatrixScaledEXT GLeeFuncPtr_glMatrixScaledEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixTranslatefEXT +#define GLEE_H_DEFINED_glMatrixTranslatefEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); + GLEE_EXTERN GLEEPFNGLMATRIXTRANSLATEFEXTPROC GLeeFuncPtr_glMatrixTranslatefEXT; + #define glMatrixTranslatefEXT GLeeFuncPtr_glMatrixTranslatefEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixTranslatedEXT +#define GLEE_H_DEFINED_glMatrixTranslatedEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); + GLEE_EXTERN GLEEPFNGLMATRIXTRANSLATEDEXTPROC GLeeFuncPtr_glMatrixTranslatedEXT; + #define glMatrixTranslatedEXT GLeeFuncPtr_glMatrixTranslatedEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixFrustumEXT +#define GLEE_H_DEFINED_glMatrixFrustumEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + GLEE_EXTERN GLEEPFNGLMATRIXFRUSTUMEXTPROC GLeeFuncPtr_glMatrixFrustumEXT; + #define glMatrixFrustumEXT GLeeFuncPtr_glMatrixFrustumEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixOrthoEXT +#define GLEE_H_DEFINED_glMatrixOrthoEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + GLEE_EXTERN GLEEPFNGLMATRIXORTHOEXTPROC GLeeFuncPtr_glMatrixOrthoEXT; + #define glMatrixOrthoEXT GLeeFuncPtr_glMatrixOrthoEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixPopEXT +#define GLEE_H_DEFINED_glMatrixPopEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXPOPEXTPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLMATRIXPOPEXTPROC GLeeFuncPtr_glMatrixPopEXT; + #define glMatrixPopEXT GLeeFuncPtr_glMatrixPopEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixPushEXT +#define GLEE_H_DEFINED_glMatrixPushEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXPUSHEXTPROC) (GLenum mode); + GLEE_EXTERN GLEEPFNGLMATRIXPUSHEXTPROC GLeeFuncPtr_glMatrixPushEXT; + #define glMatrixPushEXT GLeeFuncPtr_glMatrixPushEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixLoadTransposefEXT +#define GLEE_H_DEFINED_glMatrixLoadTransposefEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat * m); + GLEE_EXTERN GLEEPFNGLMATRIXLOADTRANSPOSEFEXTPROC GLeeFuncPtr_glMatrixLoadTransposefEXT; + #define glMatrixLoadTransposefEXT GLeeFuncPtr_glMatrixLoadTransposefEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixLoadTransposedEXT +#define GLEE_H_DEFINED_glMatrixLoadTransposedEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble * m); + GLEE_EXTERN GLEEPFNGLMATRIXLOADTRANSPOSEDEXTPROC GLeeFuncPtr_glMatrixLoadTransposedEXT; + #define glMatrixLoadTransposedEXT GLeeFuncPtr_glMatrixLoadTransposedEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixMultTransposefEXT +#define GLEE_H_DEFINED_glMatrixMultTransposefEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat * m); + GLEE_EXTERN GLEEPFNGLMATRIXMULTTRANSPOSEFEXTPROC GLeeFuncPtr_glMatrixMultTransposefEXT; + #define glMatrixMultTransposefEXT GLeeFuncPtr_glMatrixMultTransposefEXT +#endif +#ifndef GLEE_H_DEFINED_glMatrixMultTransposedEXT +#define GLEE_H_DEFINED_glMatrixMultTransposedEXT + typedef void (APIENTRYP GLEEPFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble * m); + GLEE_EXTERN GLEEPFNGLMATRIXMULTTRANSPOSEDEXTPROC GLeeFuncPtr_glMatrixMultTransposedEXT; + #define glMatrixMultTransposedEXT GLeeFuncPtr_glMatrixMultTransposedEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureParameterfEXT +#define GLEE_H_DEFINED_glTextureParameterfEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLTEXTUREPARAMETERFEXTPROC GLeeFuncPtr_glTextureParameterfEXT; + #define glTextureParameterfEXT GLeeFuncPtr_glTextureParameterfEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureParameterfvEXT +#define GLEE_H_DEFINED_glTextureParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLTEXTUREPARAMETERFVEXTPROC GLeeFuncPtr_glTextureParameterfvEXT; + #define glTextureParameterfvEXT GLeeFuncPtr_glTextureParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureParameteriEXT +#define GLEE_H_DEFINED_glTextureParameteriEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLTEXTUREPARAMETERIEXTPROC GLeeFuncPtr_glTextureParameteriEXT; + #define glTextureParameteriEXT GLeeFuncPtr_glTextureParameteriEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureParameterivEXT +#define GLEE_H_DEFINED_glTextureParameterivEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLTEXTUREPARAMETERIVEXTPROC GLeeFuncPtr_glTextureParameterivEXT; + #define glTextureParameterivEXT GLeeFuncPtr_glTextureParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureImage1DEXT +#define GLEE_H_DEFINED_glTextureImage1DEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXTUREIMAGE1DEXTPROC GLeeFuncPtr_glTextureImage1DEXT; + #define glTextureImage1DEXT GLeeFuncPtr_glTextureImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureImage2DEXT +#define GLEE_H_DEFINED_glTextureImage2DEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXTUREIMAGE2DEXTPROC GLeeFuncPtr_glTextureImage2DEXT; + #define glTextureImage2DEXT GLeeFuncPtr_glTextureImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureSubImage1DEXT +#define GLEE_H_DEFINED_glTextureSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXTURESUBIMAGE1DEXTPROC GLeeFuncPtr_glTextureSubImage1DEXT; + #define glTextureSubImage1DEXT GLeeFuncPtr_glTextureSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureSubImage2DEXT +#define GLEE_H_DEFINED_glTextureSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXTURESUBIMAGE2DEXTPROC GLeeFuncPtr_glTextureSubImage2DEXT; + #define glTextureSubImage2DEXT GLeeFuncPtr_glTextureSubImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTextureImage1DEXT +#define GLEE_H_DEFINED_glCopyTextureImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); + GLEE_EXTERN GLEEPFNGLCOPYTEXTUREIMAGE1DEXTPROC GLeeFuncPtr_glCopyTextureImage1DEXT; + #define glCopyTextureImage1DEXT GLeeFuncPtr_glCopyTextureImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTextureImage2DEXT +#define GLEE_H_DEFINED_glCopyTextureImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + GLEE_EXTERN GLEEPFNGLCOPYTEXTUREIMAGE2DEXTPROC GLeeFuncPtr_glCopyTextureImage2DEXT; + #define glCopyTextureImage2DEXT GLeeFuncPtr_glCopyTextureImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTextureSubImage1DEXT +#define GLEE_H_DEFINED_glCopyTextureSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYTEXTURESUBIMAGE1DEXTPROC GLeeFuncPtr_glCopyTextureSubImage1DEXT; + #define glCopyTextureSubImage1DEXT GLeeFuncPtr_glCopyTextureSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTextureSubImage2DEXT +#define GLEE_H_DEFINED_glCopyTextureSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYTEXTURESUBIMAGE2DEXTPROC GLeeFuncPtr_glCopyTextureSubImage2DEXT; + #define glCopyTextureSubImage2DEXT GLeeFuncPtr_glCopyTextureSubImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTextureImageEXT +#define GLEE_H_DEFINED_glGetTextureImageEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLGETTEXTUREIMAGEEXTPROC GLeeFuncPtr_glGetTextureImageEXT; + #define glGetTextureImageEXT GLeeFuncPtr_glGetTextureImageEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTextureParameterfvEXT +#define GLEE_H_DEFINED_glGetTextureParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETTEXTUREPARAMETERFVEXTPROC GLeeFuncPtr_glGetTextureParameterfvEXT; + #define glGetTextureParameterfvEXT GLeeFuncPtr_glGetTextureParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTextureParameterivEXT +#define GLEE_H_DEFINED_glGetTextureParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETTEXTUREPARAMETERIVEXTPROC GLeeFuncPtr_glGetTextureParameterivEXT; + #define glGetTextureParameterivEXT GLeeFuncPtr_glGetTextureParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTextureLevelParameterfvEXT +#define GLEE_H_DEFINED_glGetTextureLevelParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETTEXTURELEVELPARAMETERFVEXTPROC GLeeFuncPtr_glGetTextureLevelParameterfvEXT; + #define glGetTextureLevelParameterfvEXT GLeeFuncPtr_glGetTextureLevelParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTextureLevelParameterivEXT +#define GLEE_H_DEFINED_glGetTextureLevelParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETTEXTURELEVELPARAMETERIVEXTPROC GLeeFuncPtr_glGetTextureLevelParameterivEXT; + #define glGetTextureLevelParameterivEXT GLeeFuncPtr_glGetTextureLevelParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureImage3DEXT +#define GLEE_H_DEFINED_glTextureImage3DEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXTUREIMAGE3DEXTPROC GLeeFuncPtr_glTextureImage3DEXT; + #define glTextureImage3DEXT GLeeFuncPtr_glTextureImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureSubImage3DEXT +#define GLEE_H_DEFINED_glTextureSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLTEXTURESUBIMAGE3DEXTPROC GLeeFuncPtr_glTextureSubImage3DEXT; + #define glTextureSubImage3DEXT GLeeFuncPtr_glTextureSubImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyTextureSubImage3DEXT +#define GLEE_H_DEFINED_glCopyTextureSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYTEXTURESUBIMAGE3DEXTPROC GLeeFuncPtr_glCopyTextureSubImage3DEXT; + #define glCopyTextureSubImage3DEXT GLeeFuncPtr_glCopyTextureSubImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexParameterfEXT +#define GLEE_H_DEFINED_glMultiTexParameterfEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLMULTITEXPARAMETERFEXTPROC GLeeFuncPtr_glMultiTexParameterfEXT; + #define glMultiTexParameterfEXT GLeeFuncPtr_glMultiTexParameterfEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexParameterfvEXT +#define GLEE_H_DEFINED_glMultiTexParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLMULTITEXPARAMETERFVEXTPROC GLeeFuncPtr_glMultiTexParameterfvEXT; + #define glMultiTexParameterfvEXT GLeeFuncPtr_glMultiTexParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexParameteriEXT +#define GLEE_H_DEFINED_glMultiTexParameteriEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLMULTITEXPARAMETERIEXTPROC GLeeFuncPtr_glMultiTexParameteriEXT; + #define glMultiTexParameteriEXT GLeeFuncPtr_glMultiTexParameteriEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexParameterivEXT +#define GLEE_H_DEFINED_glMultiTexParameterivEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLMULTITEXPARAMETERIVEXTPROC GLeeFuncPtr_glMultiTexParameterivEXT; + #define glMultiTexParameterivEXT GLeeFuncPtr_glMultiTexParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexImage1DEXT +#define GLEE_H_DEFINED_glMultiTexImage1DEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLMULTITEXIMAGE1DEXTPROC GLeeFuncPtr_glMultiTexImage1DEXT; + #define glMultiTexImage1DEXT GLeeFuncPtr_glMultiTexImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexImage2DEXT +#define GLEE_H_DEFINED_glMultiTexImage2DEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLMULTITEXIMAGE2DEXTPROC GLeeFuncPtr_glMultiTexImage2DEXT; + #define glMultiTexImage2DEXT GLeeFuncPtr_glMultiTexImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexSubImage1DEXT +#define GLEE_H_DEFINED_glMultiTexSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLMULTITEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glMultiTexSubImage1DEXT; + #define glMultiTexSubImage1DEXT GLeeFuncPtr_glMultiTexSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexSubImage2DEXT +#define GLEE_H_DEFINED_glMultiTexSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLMULTITEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glMultiTexSubImage2DEXT; + #define glMultiTexSubImage2DEXT GLeeFuncPtr_glMultiTexSubImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyMultiTexImage1DEXT +#define GLEE_H_DEFINED_glCopyMultiTexImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); + GLEE_EXTERN GLEEPFNGLCOPYMULTITEXIMAGE1DEXTPROC GLeeFuncPtr_glCopyMultiTexImage1DEXT; + #define glCopyMultiTexImage1DEXT GLeeFuncPtr_glCopyMultiTexImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyMultiTexImage2DEXT +#define GLEE_H_DEFINED_glCopyMultiTexImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + GLEE_EXTERN GLEEPFNGLCOPYMULTITEXIMAGE2DEXTPROC GLeeFuncPtr_glCopyMultiTexImage2DEXT; + #define glCopyMultiTexImage2DEXT GLeeFuncPtr_glCopyMultiTexImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyMultiTexSubImage1DEXT +#define GLEE_H_DEFINED_glCopyMultiTexSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + GLEE_EXTERN GLEEPFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glCopyMultiTexSubImage1DEXT; + #define glCopyMultiTexSubImage1DEXT GLeeFuncPtr_glCopyMultiTexSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyMultiTexSubImage2DEXT +#define GLEE_H_DEFINED_glCopyMultiTexSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glCopyMultiTexSubImage2DEXT; + #define glCopyMultiTexSubImage2DEXT GLeeFuncPtr_glCopyMultiTexSubImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexImageEXT +#define GLEE_H_DEFINED_glGetMultiTexImageEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLGETMULTITEXIMAGEEXTPROC GLeeFuncPtr_glGetMultiTexImageEXT; + #define glGetMultiTexImageEXT GLeeFuncPtr_glGetMultiTexImageEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexParameterfvEXT +#define GLEE_H_DEFINED_glGetMultiTexParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXPARAMETERFVEXTPROC GLeeFuncPtr_glGetMultiTexParameterfvEXT; + #define glGetMultiTexParameterfvEXT GLeeFuncPtr_glGetMultiTexParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexParameterivEXT +#define GLEE_H_DEFINED_glGetMultiTexParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXPARAMETERIVEXTPROC GLeeFuncPtr_glGetMultiTexParameterivEXT; + #define glGetMultiTexParameterivEXT GLeeFuncPtr_glGetMultiTexParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexLevelParameterfvEXT +#define GLEE_H_DEFINED_glGetMultiTexLevelParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC GLeeFuncPtr_glGetMultiTexLevelParameterfvEXT; + #define glGetMultiTexLevelParameterfvEXT GLeeFuncPtr_glGetMultiTexLevelParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexLevelParameterivEXT +#define GLEE_H_DEFINED_glGetMultiTexLevelParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC GLeeFuncPtr_glGetMultiTexLevelParameterivEXT; + #define glGetMultiTexLevelParameterivEXT GLeeFuncPtr_glGetMultiTexLevelParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexImage3DEXT +#define GLEE_H_DEFINED_glMultiTexImage3DEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLMULTITEXIMAGE3DEXTPROC GLeeFuncPtr_glMultiTexImage3DEXT; + #define glMultiTexImage3DEXT GLeeFuncPtr_glMultiTexImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexSubImage3DEXT +#define GLEE_H_DEFINED_glMultiTexSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels); + GLEE_EXTERN GLEEPFNGLMULTITEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glMultiTexSubImage3DEXT; + #define glMultiTexSubImage3DEXT GLeeFuncPtr_glMultiTexSubImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glCopyMultiTexSubImage3DEXT +#define GLEE_H_DEFINED_glCopyMultiTexSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glCopyMultiTexSubImage3DEXT; + #define glCopyMultiTexSubImage3DEXT GLeeFuncPtr_glCopyMultiTexSubImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glBindMultiTextureEXT +#define GLEE_H_DEFINED_glBindMultiTextureEXT + typedef void (APIENTRYP GLEEPFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); + GLEE_EXTERN GLEEPFNGLBINDMULTITEXTUREEXTPROC GLeeFuncPtr_glBindMultiTextureEXT; + #define glBindMultiTextureEXT GLeeFuncPtr_glBindMultiTextureEXT +#endif +#ifndef GLEE_H_DEFINED_glEnableClientStateIndexedEXT +#define GLEE_H_DEFINED_glEnableClientStateIndexedEXT + typedef void (APIENTRYP GLEEPFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); + GLEE_EXTERN GLEEPFNGLENABLECLIENTSTATEINDEXEDEXTPROC GLeeFuncPtr_glEnableClientStateIndexedEXT; + #define glEnableClientStateIndexedEXT GLeeFuncPtr_glEnableClientStateIndexedEXT +#endif +#ifndef GLEE_H_DEFINED_glDisableClientStateIndexedEXT +#define GLEE_H_DEFINED_glDisableClientStateIndexedEXT + typedef void (APIENTRYP GLEEPFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); + GLEE_EXTERN GLEEPFNGLDISABLECLIENTSTATEINDEXEDEXTPROC GLeeFuncPtr_glDisableClientStateIndexedEXT; + #define glDisableClientStateIndexedEXT GLeeFuncPtr_glDisableClientStateIndexedEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoordPointerEXT +#define GLEE_H_DEFINED_glMultiTexCoordPointerEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORDPOINTEREXTPROC GLeeFuncPtr_glMultiTexCoordPointerEXT; + #define glMultiTexCoordPointerEXT GLeeFuncPtr_glMultiTexCoordPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexEnvfEXT +#define GLEE_H_DEFINED_glMultiTexEnvfEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLMULTITEXENVFEXTPROC GLeeFuncPtr_glMultiTexEnvfEXT; + #define glMultiTexEnvfEXT GLeeFuncPtr_glMultiTexEnvfEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexEnvfvEXT +#define GLEE_H_DEFINED_glMultiTexEnvfvEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLMULTITEXENVFVEXTPROC GLeeFuncPtr_glMultiTexEnvfvEXT; + #define glMultiTexEnvfvEXT GLeeFuncPtr_glMultiTexEnvfvEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexEnviEXT +#define GLEE_H_DEFINED_glMultiTexEnviEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLMULTITEXENVIEXTPROC GLeeFuncPtr_glMultiTexEnviEXT; + #define glMultiTexEnviEXT GLeeFuncPtr_glMultiTexEnviEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexEnvivEXT +#define GLEE_H_DEFINED_glMultiTexEnvivEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLMULTITEXENVIVEXTPROC GLeeFuncPtr_glMultiTexEnvivEXT; + #define glMultiTexEnvivEXT GLeeFuncPtr_glMultiTexEnvivEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexGendEXT +#define GLEE_H_DEFINED_glMultiTexGendEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); + GLEE_EXTERN GLEEPFNGLMULTITEXGENDEXTPROC GLeeFuncPtr_glMultiTexGendEXT; + #define glMultiTexGendEXT GLeeFuncPtr_glMultiTexGendEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexGendvEXT +#define GLEE_H_DEFINED_glMultiTexGendvEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble * params); + GLEE_EXTERN GLEEPFNGLMULTITEXGENDVEXTPROC GLeeFuncPtr_glMultiTexGendvEXT; + #define glMultiTexGendvEXT GLeeFuncPtr_glMultiTexGendvEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexGenfEXT +#define GLEE_H_DEFINED_glMultiTexGenfEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLMULTITEXGENFEXTPROC GLeeFuncPtr_glMultiTexGenfEXT; + #define glMultiTexGenfEXT GLeeFuncPtr_glMultiTexGenfEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexGenfvEXT +#define GLEE_H_DEFINED_glMultiTexGenfvEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLMULTITEXGENFVEXTPROC GLeeFuncPtr_glMultiTexGenfvEXT; + #define glMultiTexGenfvEXT GLeeFuncPtr_glMultiTexGenfvEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexGeniEXT +#define GLEE_H_DEFINED_glMultiTexGeniEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLMULTITEXGENIEXTPROC GLeeFuncPtr_glMultiTexGeniEXT; + #define glMultiTexGeniEXT GLeeFuncPtr_glMultiTexGeniEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexGenivEXT +#define GLEE_H_DEFINED_glMultiTexGenivEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLMULTITEXGENIVEXTPROC GLeeFuncPtr_glMultiTexGenivEXT; + #define glMultiTexGenivEXT GLeeFuncPtr_glMultiTexGenivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexEnvfvEXT +#define GLEE_H_DEFINED_glGetMultiTexEnvfvEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXENVFVEXTPROC GLeeFuncPtr_glGetMultiTexEnvfvEXT; + #define glGetMultiTexEnvfvEXT GLeeFuncPtr_glGetMultiTexEnvfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexEnvivEXT +#define GLEE_H_DEFINED_glGetMultiTexEnvivEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXENVIVEXTPROC GLeeFuncPtr_glGetMultiTexEnvivEXT; + #define glGetMultiTexEnvivEXT GLeeFuncPtr_glGetMultiTexEnvivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexGendvEXT +#define GLEE_H_DEFINED_glGetMultiTexGendvEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXGENDVEXTPROC GLeeFuncPtr_glGetMultiTexGendvEXT; + #define glGetMultiTexGendvEXT GLeeFuncPtr_glGetMultiTexGendvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexGenfvEXT +#define GLEE_H_DEFINED_glGetMultiTexGenfvEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXGENFVEXTPROC GLeeFuncPtr_glGetMultiTexGenfvEXT; + #define glGetMultiTexGenfvEXT GLeeFuncPtr_glGetMultiTexGenfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexGenivEXT +#define GLEE_H_DEFINED_glGetMultiTexGenivEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXGENIVEXTPROC GLeeFuncPtr_glGetMultiTexGenivEXT; + #define glGetMultiTexGenivEXT GLeeFuncPtr_glGetMultiTexGenivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFloatIndexedvEXT +#define GLEE_H_DEFINED_glGetFloatIndexedvEXT + typedef void (APIENTRYP GLEEPFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat * data); + GLEE_EXTERN GLEEPFNGLGETFLOATINDEXEDVEXTPROC GLeeFuncPtr_glGetFloatIndexedvEXT; + #define glGetFloatIndexedvEXT GLeeFuncPtr_glGetFloatIndexedvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetDoubleIndexedvEXT +#define GLEE_H_DEFINED_glGetDoubleIndexedvEXT + typedef void (APIENTRYP GLEEPFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble * data); + GLEE_EXTERN GLEEPFNGLGETDOUBLEINDEXEDVEXTPROC GLeeFuncPtr_glGetDoubleIndexedvEXT; + #define glGetDoubleIndexedvEXT GLeeFuncPtr_glGetDoubleIndexedvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetPointerIndexedvEXT +#define GLEE_H_DEFINED_glGetPointerIndexedvEXT + typedef void (APIENTRYP GLEEPFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* * data); + GLEE_EXTERN GLEEPFNGLGETPOINTERINDEXEDVEXTPROC GLeeFuncPtr_glGetPointerIndexedvEXT; + #define glGetPointerIndexedvEXT GLeeFuncPtr_glGetPointerIndexedvEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedTextureImage3DEXT +#define GLEE_H_DEFINED_glCompressedTextureImage3DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC GLeeFuncPtr_glCompressedTextureImage3DEXT; + #define glCompressedTextureImage3DEXT GLeeFuncPtr_glCompressedTextureImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedTextureImage2DEXT +#define GLEE_H_DEFINED_glCompressedTextureImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC GLeeFuncPtr_glCompressedTextureImage2DEXT; + #define glCompressedTextureImage2DEXT GLeeFuncPtr_glCompressedTextureImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedTextureImage1DEXT +#define GLEE_H_DEFINED_glCompressedTextureImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC GLeeFuncPtr_glCompressedTextureImage1DEXT; + #define glCompressedTextureImage1DEXT GLeeFuncPtr_glCompressedTextureImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedTextureSubImage3DEXT +#define GLEE_H_DEFINED_glCompressedTextureSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC GLeeFuncPtr_glCompressedTextureSubImage3DEXT; + #define glCompressedTextureSubImage3DEXT GLeeFuncPtr_glCompressedTextureSubImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedTextureSubImage2DEXT +#define GLEE_H_DEFINED_glCompressedTextureSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC GLeeFuncPtr_glCompressedTextureSubImage2DEXT; + #define glCompressedTextureSubImage2DEXT GLeeFuncPtr_glCompressedTextureSubImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedTextureSubImage1DEXT +#define GLEE_H_DEFINED_glCompressedTextureSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC GLeeFuncPtr_glCompressedTextureSubImage1DEXT; + #define glCompressedTextureSubImage1DEXT GLeeFuncPtr_glCompressedTextureSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glGetCompressedTextureImageEXT +#define GLEE_H_DEFINED_glGetCompressedTextureImageEXT + typedef void (APIENTRYP GLEEPFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid * img); + GLEE_EXTERN GLEEPFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC GLeeFuncPtr_glGetCompressedTextureImageEXT; + #define glGetCompressedTextureImageEXT GLeeFuncPtr_glGetCompressedTextureImageEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedMultiTexImage3DEXT +#define GLEE_H_DEFINED_glCompressedMultiTexImage3DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC GLeeFuncPtr_glCompressedMultiTexImage3DEXT; + #define glCompressedMultiTexImage3DEXT GLeeFuncPtr_glCompressedMultiTexImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedMultiTexImage2DEXT +#define GLEE_H_DEFINED_glCompressedMultiTexImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC GLeeFuncPtr_glCompressedMultiTexImage2DEXT; + #define glCompressedMultiTexImage2DEXT GLeeFuncPtr_glCompressedMultiTexImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedMultiTexImage1DEXT +#define GLEE_H_DEFINED_glCompressedMultiTexImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC GLeeFuncPtr_glCompressedMultiTexImage1DEXT; + #define glCompressedMultiTexImage1DEXT GLeeFuncPtr_glCompressedMultiTexImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedMultiTexSubImage3DEXT +#define GLEE_H_DEFINED_glCompressedMultiTexSubImage3DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC GLeeFuncPtr_glCompressedMultiTexSubImage3DEXT; + #define glCompressedMultiTexSubImage3DEXT GLeeFuncPtr_glCompressedMultiTexSubImage3DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedMultiTexSubImage2DEXT +#define GLEE_H_DEFINED_glCompressedMultiTexSubImage2DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC GLeeFuncPtr_glCompressedMultiTexSubImage2DEXT; + #define glCompressedMultiTexSubImage2DEXT GLeeFuncPtr_glCompressedMultiTexSubImage2DEXT +#endif +#ifndef GLEE_H_DEFINED_glCompressedMultiTexSubImage1DEXT +#define GLEE_H_DEFINED_glCompressedMultiTexSubImage1DEXT + typedef void (APIENTRYP GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * bits); + GLEE_EXTERN GLEEPFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC GLeeFuncPtr_glCompressedMultiTexSubImage1DEXT; + #define glCompressedMultiTexSubImage1DEXT GLeeFuncPtr_glCompressedMultiTexSubImage1DEXT +#endif +#ifndef GLEE_H_DEFINED_glGetCompressedMultiTexImageEXT +#define GLEE_H_DEFINED_glGetCompressedMultiTexImageEXT + typedef void (APIENTRYP GLEEPFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid * img); + GLEE_EXTERN GLEEPFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC GLeeFuncPtr_glGetCompressedMultiTexImageEXT; + #define glGetCompressedMultiTexImageEXT GLeeFuncPtr_glGetCompressedMultiTexImageEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramStringEXT +#define GLEE_H_DEFINED_glNamedProgramStringEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid * string); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMSTRINGEXTPROC GLeeFuncPtr_glNamedProgramStringEXT; + #define glNamedProgramStringEXT GLeeFuncPtr_glNamedProgramStringEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameter4dEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameter4dEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4dEXT; + #define glNamedProgramLocalParameter4dEXT GLeeFuncPtr_glNamedProgramLocalParameter4dEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameter4dvEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameter4dvEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble * params); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4dvEXT; + #define glNamedProgramLocalParameter4dvEXT GLeeFuncPtr_glNamedProgramLocalParameter4dvEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameter4fEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameter4fEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4fEXT; + #define glNamedProgramLocalParameter4fEXT GLeeFuncPtr_glNamedProgramLocalParameter4fEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameter4fvEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameter4fvEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameter4fvEXT; + #define glNamedProgramLocalParameter4fvEXT GLeeFuncPtr_glNamedProgramLocalParameter4fvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedProgramLocalParameterdvEXT +#define GLEE_H_DEFINED_glGetNamedProgramLocalParameterdvEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterdvEXT; + #define glGetNamedProgramLocalParameterdvEXT GLeeFuncPtr_glGetNamedProgramLocalParameterdvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedProgramLocalParameterfvEXT +#define GLEE_H_DEFINED_glGetNamedProgramLocalParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterfvEXT; + #define glGetNamedProgramLocalParameterfvEXT GLeeFuncPtr_glGetNamedProgramLocalParameterfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedProgramivEXT +#define GLEE_H_DEFINED_glGetNamedProgramivEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDPROGRAMIVEXTPROC GLeeFuncPtr_glGetNamedProgramivEXT; + #define glGetNamedProgramivEXT GLeeFuncPtr_glGetNamedProgramivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedProgramStringEXT +#define GLEE_H_DEFINED_glGetNamedProgramStringEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid * string); + GLEE_EXTERN GLEEPFNGLGETNAMEDPROGRAMSTRINGEXTPROC GLeeFuncPtr_glGetNamedProgramStringEXT; + #define glGetNamedProgramStringEXT GLeeFuncPtr_glGetNamedProgramStringEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameters4fvEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameters4fvEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameters4fvEXT; + #define glNamedProgramLocalParameters4fvEXT GLeeFuncPtr_glNamedProgramLocalParameters4fvEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameterI4iEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameterI4iEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4iEXT; + #define glNamedProgramLocalParameterI4iEXT GLeeFuncPtr_glNamedProgramLocalParameterI4iEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameterI4ivEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameterI4ivEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint * params); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4ivEXT; + #define glNamedProgramLocalParameterI4ivEXT GLeeFuncPtr_glNamedProgramLocalParameterI4ivEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParametersI4ivEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParametersI4ivEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint * params); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC GLeeFuncPtr_glNamedProgramLocalParametersI4ivEXT; + #define glNamedProgramLocalParametersI4ivEXT GLeeFuncPtr_glNamedProgramLocalParametersI4ivEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameterI4uiEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameterI4uiEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4uiEXT; + #define glNamedProgramLocalParameterI4uiEXT GLeeFuncPtr_glNamedProgramLocalParameterI4uiEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParameterI4uivEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParameterI4uivEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint * params); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC GLeeFuncPtr_glNamedProgramLocalParameterI4uivEXT; + #define glNamedProgramLocalParameterI4uivEXT GLeeFuncPtr_glNamedProgramLocalParameterI4uivEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedProgramLocalParametersI4uivEXT +#define GLEE_H_DEFINED_glNamedProgramLocalParametersI4uivEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint * params); + GLEE_EXTERN GLEEPFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC GLeeFuncPtr_glNamedProgramLocalParametersI4uivEXT; + #define glNamedProgramLocalParametersI4uivEXT GLeeFuncPtr_glNamedProgramLocalParametersI4uivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedProgramLocalParameterIivEXT +#define GLEE_H_DEFINED_glGetNamedProgramLocalParameterIivEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterIivEXT; + #define glGetNamedProgramLocalParameterIivEXT GLeeFuncPtr_glGetNamedProgramLocalParameterIivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedProgramLocalParameterIuivEXT +#define GLEE_H_DEFINED_glGetNamedProgramLocalParameterIuivEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetNamedProgramLocalParameterIuivEXT; + #define glGetNamedProgramLocalParameterIuivEXT GLeeFuncPtr_glGetNamedProgramLocalParameterIuivEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureParameterIivEXT +#define GLEE_H_DEFINED_glTextureParameterIivEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLTEXTUREPARAMETERIIVEXTPROC GLeeFuncPtr_glTextureParameterIivEXT; + #define glTextureParameterIivEXT GLeeFuncPtr_glTextureParameterIivEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureParameterIuivEXT +#define GLEE_H_DEFINED_glTextureParameterIuivEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint * params); + GLEE_EXTERN GLEEPFNGLTEXTUREPARAMETERIUIVEXTPROC GLeeFuncPtr_glTextureParameterIuivEXT; + #define glTextureParameterIuivEXT GLeeFuncPtr_glTextureParameterIuivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTextureParameterIivEXT +#define GLEE_H_DEFINED_glGetTextureParameterIivEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETTEXTUREPARAMETERIIVEXTPROC GLeeFuncPtr_glGetTextureParameterIivEXT; + #define glGetTextureParameterIivEXT GLeeFuncPtr_glGetTextureParameterIivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetTextureParameterIuivEXT +#define GLEE_H_DEFINED_glGetTextureParameterIuivEXT + typedef void (APIENTRYP GLEEPFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETTEXTUREPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetTextureParameterIuivEXT; + #define glGetTextureParameterIuivEXT GLeeFuncPtr_glGetTextureParameterIuivEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexParameterIivEXT +#define GLEE_H_DEFINED_glMultiTexParameterIivEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLMULTITEXPARAMETERIIVEXTPROC GLeeFuncPtr_glMultiTexParameterIivEXT; + #define glMultiTexParameterIivEXT GLeeFuncPtr_glMultiTexParameterIivEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexParameterIuivEXT +#define GLEE_H_DEFINED_glMultiTexParameterIuivEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint * params); + GLEE_EXTERN GLEEPFNGLMULTITEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glMultiTexParameterIuivEXT; + #define glMultiTexParameterIuivEXT GLeeFuncPtr_glMultiTexParameterIuivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexParameterIivEXT +#define GLEE_H_DEFINED_glGetMultiTexParameterIivEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXPARAMETERIIVEXTPROC GLeeFuncPtr_glGetMultiTexParameterIivEXT; + #define glGetMultiTexParameterIivEXT GLeeFuncPtr_glGetMultiTexParameterIivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetMultiTexParameterIuivEXT +#define GLEE_H_DEFINED_glGetMultiTexParameterIuivEXT + typedef void (APIENTRYP GLEEPFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETMULTITEXPARAMETERIUIVEXTPROC GLeeFuncPtr_glGetMultiTexParameterIuivEXT; + #define glGetMultiTexParameterIuivEXT GLeeFuncPtr_glGetMultiTexParameterIuivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform1fEXT +#define GLEE_H_DEFINED_glProgramUniform1fEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM1FEXTPROC GLeeFuncPtr_glProgramUniform1fEXT; + #define glProgramUniform1fEXT GLeeFuncPtr_glProgramUniform1fEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform2fEXT +#define GLEE_H_DEFINED_glProgramUniform2fEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM2FEXTPROC GLeeFuncPtr_glProgramUniform2fEXT; + #define glProgramUniform2fEXT GLeeFuncPtr_glProgramUniform2fEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform3fEXT +#define GLEE_H_DEFINED_glProgramUniform3fEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM3FEXTPROC GLeeFuncPtr_glProgramUniform3fEXT; + #define glProgramUniform3fEXT GLeeFuncPtr_glProgramUniform3fEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform4fEXT +#define GLEE_H_DEFINED_glProgramUniform4fEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM4FEXTPROC GLeeFuncPtr_glProgramUniform4fEXT; + #define glProgramUniform4fEXT GLeeFuncPtr_glProgramUniform4fEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform1iEXT +#define GLEE_H_DEFINED_glProgramUniform1iEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM1IEXTPROC GLeeFuncPtr_glProgramUniform1iEXT; + #define glProgramUniform1iEXT GLeeFuncPtr_glProgramUniform1iEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform2iEXT +#define GLEE_H_DEFINED_glProgramUniform2iEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM2IEXTPROC GLeeFuncPtr_glProgramUniform2iEXT; + #define glProgramUniform2iEXT GLeeFuncPtr_glProgramUniform2iEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform3iEXT +#define GLEE_H_DEFINED_glProgramUniform3iEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM3IEXTPROC GLeeFuncPtr_glProgramUniform3iEXT; + #define glProgramUniform3iEXT GLeeFuncPtr_glProgramUniform3iEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform4iEXT +#define GLEE_H_DEFINED_glProgramUniform4iEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM4IEXTPROC GLeeFuncPtr_glProgramUniform4iEXT; + #define glProgramUniform4iEXT GLeeFuncPtr_glProgramUniform4iEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform1fvEXT +#define GLEE_H_DEFINED_glProgramUniform1fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM1FVEXTPROC GLeeFuncPtr_glProgramUniform1fvEXT; + #define glProgramUniform1fvEXT GLeeFuncPtr_glProgramUniform1fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform2fvEXT +#define GLEE_H_DEFINED_glProgramUniform2fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM2FVEXTPROC GLeeFuncPtr_glProgramUniform2fvEXT; + #define glProgramUniform2fvEXT GLeeFuncPtr_glProgramUniform2fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform3fvEXT +#define GLEE_H_DEFINED_glProgramUniform3fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM3FVEXTPROC GLeeFuncPtr_glProgramUniform3fvEXT; + #define glProgramUniform3fvEXT GLeeFuncPtr_glProgramUniform3fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform4fvEXT +#define GLEE_H_DEFINED_glProgramUniform4fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM4FVEXTPROC GLeeFuncPtr_glProgramUniform4fvEXT; + #define glProgramUniform4fvEXT GLeeFuncPtr_glProgramUniform4fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform1ivEXT +#define GLEE_H_DEFINED_glProgramUniform1ivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM1IVEXTPROC GLeeFuncPtr_glProgramUniform1ivEXT; + #define glProgramUniform1ivEXT GLeeFuncPtr_glProgramUniform1ivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform2ivEXT +#define GLEE_H_DEFINED_glProgramUniform2ivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM2IVEXTPROC GLeeFuncPtr_glProgramUniform2ivEXT; + #define glProgramUniform2ivEXT GLeeFuncPtr_glProgramUniform2ivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform3ivEXT +#define GLEE_H_DEFINED_glProgramUniform3ivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM3IVEXTPROC GLeeFuncPtr_glProgramUniform3ivEXT; + #define glProgramUniform3ivEXT GLeeFuncPtr_glProgramUniform3ivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform4ivEXT +#define GLEE_H_DEFINED_glProgramUniform4ivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM4IVEXTPROC GLeeFuncPtr_glProgramUniform4ivEXT; + #define glProgramUniform4ivEXT GLeeFuncPtr_glProgramUniform4ivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix2fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix2fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix2fvEXT; + #define glProgramUniformMatrix2fvEXT GLeeFuncPtr_glProgramUniformMatrix2fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix3fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix3fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix3fvEXT; + #define glProgramUniformMatrix3fvEXT GLeeFuncPtr_glProgramUniformMatrix3fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix4fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix4fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix4fvEXT; + #define glProgramUniformMatrix4fvEXT GLeeFuncPtr_glProgramUniformMatrix4fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix2x3fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix2x3fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix2x3fvEXT; + #define glProgramUniformMatrix2x3fvEXT GLeeFuncPtr_glProgramUniformMatrix2x3fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix3x2fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix3x2fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix3x2fvEXT; + #define glProgramUniformMatrix3x2fvEXT GLeeFuncPtr_glProgramUniformMatrix3x2fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix2x4fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix2x4fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix2x4fvEXT; + #define glProgramUniformMatrix2x4fvEXT GLeeFuncPtr_glProgramUniformMatrix2x4fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix4x2fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix4x2fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix4x2fvEXT; + #define glProgramUniformMatrix4x2fvEXT GLeeFuncPtr_glProgramUniformMatrix4x2fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix3x4fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix3x4fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix3x4fvEXT; + #define glProgramUniformMatrix3x4fvEXT GLeeFuncPtr_glProgramUniformMatrix3x4fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformMatrix4x3fvEXT +#define GLEE_H_DEFINED_glProgramUniformMatrix4x3fvEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC GLeeFuncPtr_glProgramUniformMatrix4x3fvEXT; + #define glProgramUniformMatrix4x3fvEXT GLeeFuncPtr_glProgramUniformMatrix4x3fvEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform1uiEXT +#define GLEE_H_DEFINED_glProgramUniform1uiEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM1UIEXTPROC GLeeFuncPtr_glProgramUniform1uiEXT; + #define glProgramUniform1uiEXT GLeeFuncPtr_glProgramUniform1uiEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform2uiEXT +#define GLEE_H_DEFINED_glProgramUniform2uiEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM2UIEXTPROC GLeeFuncPtr_glProgramUniform2uiEXT; + #define glProgramUniform2uiEXT GLeeFuncPtr_glProgramUniform2uiEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform3uiEXT +#define GLEE_H_DEFINED_glProgramUniform3uiEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM3UIEXTPROC GLeeFuncPtr_glProgramUniform3uiEXT; + #define glProgramUniform3uiEXT GLeeFuncPtr_glProgramUniform3uiEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform4uiEXT +#define GLEE_H_DEFINED_glProgramUniform4uiEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM4UIEXTPROC GLeeFuncPtr_glProgramUniform4uiEXT; + #define glProgramUniform4uiEXT GLeeFuncPtr_glProgramUniform4uiEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform1uivEXT +#define GLEE_H_DEFINED_glProgramUniform1uivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM1UIVEXTPROC GLeeFuncPtr_glProgramUniform1uivEXT; + #define glProgramUniform1uivEXT GLeeFuncPtr_glProgramUniform1uivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform2uivEXT +#define GLEE_H_DEFINED_glProgramUniform2uivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM2UIVEXTPROC GLeeFuncPtr_glProgramUniform2uivEXT; + #define glProgramUniform2uivEXT GLeeFuncPtr_glProgramUniform2uivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform3uivEXT +#define GLEE_H_DEFINED_glProgramUniform3uivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM3UIVEXTPROC GLeeFuncPtr_glProgramUniform3uivEXT; + #define glProgramUniform3uivEXT GLeeFuncPtr_glProgramUniform3uivEXT +#endif +#ifndef GLEE_H_DEFINED_glProgramUniform4uivEXT +#define GLEE_H_DEFINED_glProgramUniform4uivEXT + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint * value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORM4UIVEXTPROC GLeeFuncPtr_glProgramUniform4uivEXT; + #define glProgramUniform4uivEXT GLeeFuncPtr_glProgramUniform4uivEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedBufferDataEXT +#define GLEE_H_DEFINED_glNamedBufferDataEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid * data, GLenum usage); + GLEE_EXTERN GLEEPFNGLNAMEDBUFFERDATAEXTPROC GLeeFuncPtr_glNamedBufferDataEXT; + #define glNamedBufferDataEXT GLeeFuncPtr_glNamedBufferDataEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedBufferSubDataEXT +#define GLEE_H_DEFINED_glNamedBufferSubDataEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid * data); + GLEE_EXTERN GLEEPFNGLNAMEDBUFFERSUBDATAEXTPROC GLeeFuncPtr_glNamedBufferSubDataEXT; + #define glNamedBufferSubDataEXT GLeeFuncPtr_glNamedBufferSubDataEXT +#endif +#ifndef GLEE_H_DEFINED_glMapNamedBufferEXT +#define GLEE_H_DEFINED_glMapNamedBufferEXT + typedef GLvoid* (APIENTRYP GLEEPFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); + GLEE_EXTERN GLEEPFNGLMAPNAMEDBUFFEREXTPROC GLeeFuncPtr_glMapNamedBufferEXT; + #define glMapNamedBufferEXT GLeeFuncPtr_glMapNamedBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glUnmapNamedBufferEXT +#define GLEE_H_DEFINED_glUnmapNamedBufferEXT + typedef GLboolean (APIENTRYP GLEEPFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLUNMAPNAMEDBUFFEREXTPROC GLeeFuncPtr_glUnmapNamedBufferEXT; + #define glUnmapNamedBufferEXT GLeeFuncPtr_glUnmapNamedBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedBufferParameterivEXT +#define GLEE_H_DEFINED_glGetNamedBufferParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedBufferParameterivEXT; + #define glGetNamedBufferParameterivEXT GLeeFuncPtr_glGetNamedBufferParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedBufferPointervEXT +#define GLEE_H_DEFINED_glGetNamedBufferPointervEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDBUFFERPOINTERVEXTPROC GLeeFuncPtr_glGetNamedBufferPointervEXT; + #define glGetNamedBufferPointervEXT GLeeFuncPtr_glGetNamedBufferPointervEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedBufferSubDataEXT +#define GLEE_H_DEFINED_glGetNamedBufferSubDataEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid * data); + GLEE_EXTERN GLEEPFNGLGETNAMEDBUFFERSUBDATAEXTPROC GLeeFuncPtr_glGetNamedBufferSubDataEXT; + #define glGetNamedBufferSubDataEXT GLeeFuncPtr_glGetNamedBufferSubDataEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureBufferEXT +#define GLEE_H_DEFINED_glTextureBufferEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); + GLEE_EXTERN GLEEPFNGLTEXTUREBUFFEREXTPROC GLeeFuncPtr_glTextureBufferEXT; + #define glTextureBufferEXT GLeeFuncPtr_glTextureBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexBufferEXT +#define GLEE_H_DEFINED_glMultiTexBufferEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); + GLEE_EXTERN GLEEPFNGLMULTITEXBUFFEREXTPROC GLeeFuncPtr_glMultiTexBufferEXT; + #define glMultiTexBufferEXT GLeeFuncPtr_glMultiTexBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedRenderbufferStorageEXT +#define GLEE_H_DEFINED_glNamedRenderbufferStorageEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC GLeeFuncPtr_glNamedRenderbufferStorageEXT; + #define glNamedRenderbufferStorageEXT GLeeFuncPtr_glNamedRenderbufferStorageEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedRenderbufferParameterivEXT +#define GLEE_H_DEFINED_glGetNamedRenderbufferParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedRenderbufferParameterivEXT; + #define glGetNamedRenderbufferParameterivEXT GLeeFuncPtr_glGetNamedRenderbufferParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glCheckNamedFramebufferStatusEXT +#define GLEE_H_DEFINED_glCheckNamedFramebufferStatusEXT + typedef GLenum (APIENTRYP GLEEPFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); + GLEE_EXTERN GLEEPFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC GLeeFuncPtr_glCheckNamedFramebufferStatusEXT; + #define glCheckNamedFramebufferStatusEXT GLeeFuncPtr_glCheckNamedFramebufferStatusEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferTexture1DEXT +#define GLEE_H_DEFINED_glNamedFramebufferTexture1DEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC GLeeFuncPtr_glNamedFramebufferTexture1DEXT; + #define glNamedFramebufferTexture1DEXT GLeeFuncPtr_glNamedFramebufferTexture1DEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferTexture2DEXT +#define GLEE_H_DEFINED_glNamedFramebufferTexture2DEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC GLeeFuncPtr_glNamedFramebufferTexture2DEXT; + #define glNamedFramebufferTexture2DEXT GLeeFuncPtr_glNamedFramebufferTexture2DEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferTexture3DEXT +#define GLEE_H_DEFINED_glNamedFramebufferTexture3DEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC GLeeFuncPtr_glNamedFramebufferTexture3DEXT; + #define glNamedFramebufferTexture3DEXT GLeeFuncPtr_glNamedFramebufferTexture3DEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferRenderbufferEXT +#define GLEE_H_DEFINED_glNamedFramebufferRenderbufferEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC GLeeFuncPtr_glNamedFramebufferRenderbufferEXT; + #define glNamedFramebufferRenderbufferEXT GLeeFuncPtr_glNamedFramebufferRenderbufferEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedFramebufferAttachmentParameterivEXT +#define GLEE_H_DEFINED_glGetNamedFramebufferAttachmentParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedFramebufferAttachmentParameterivEXT; + #define glGetNamedFramebufferAttachmentParameterivEXT GLeeFuncPtr_glGetNamedFramebufferAttachmentParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGenerateTextureMipmapEXT +#define GLEE_H_DEFINED_glGenerateTextureMipmapEXT + typedef void (APIENTRYP GLEEPFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); + GLEE_EXTERN GLEEPFNGLGENERATETEXTUREMIPMAPEXTPROC GLeeFuncPtr_glGenerateTextureMipmapEXT; + #define glGenerateTextureMipmapEXT GLeeFuncPtr_glGenerateTextureMipmapEXT +#endif +#ifndef GLEE_H_DEFINED_glGenerateMultiTexMipmapEXT +#define GLEE_H_DEFINED_glGenerateMultiTexMipmapEXT + typedef void (APIENTRYP GLEEPFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); + GLEE_EXTERN GLEEPFNGLGENERATEMULTITEXMIPMAPEXTPROC GLeeFuncPtr_glGenerateMultiTexMipmapEXT; + #define glGenerateMultiTexMipmapEXT GLeeFuncPtr_glGenerateMultiTexMipmapEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferDrawBufferEXT +#define GLEE_H_DEFINED_glFramebufferDrawBufferEXT + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERDRAWBUFFEREXTPROC GLeeFuncPtr_glFramebufferDrawBufferEXT; + #define glFramebufferDrawBufferEXT GLeeFuncPtr_glFramebufferDrawBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferDrawBuffersEXT +#define GLEE_H_DEFINED_glFramebufferDrawBuffersEXT + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum * bufs); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC GLeeFuncPtr_glFramebufferDrawBuffersEXT; + #define glFramebufferDrawBuffersEXT GLeeFuncPtr_glFramebufferDrawBuffersEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferReadBufferEXT +#define GLEE_H_DEFINED_glFramebufferReadBufferEXT + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERREADBUFFEREXTPROC GLeeFuncPtr_glFramebufferReadBufferEXT; + #define glFramebufferReadBufferEXT GLeeFuncPtr_glFramebufferReadBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFramebufferParameterivEXT +#define GLEE_H_DEFINED_glGetFramebufferParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetFramebufferParameterivEXT; + #define glGetFramebufferParameterivEXT GLeeFuncPtr_glGetFramebufferParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedRenderbufferStorageMultisampleEXT +#define GLEE_H_DEFINED_glNamedRenderbufferStorageMultisampleEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC GLeeFuncPtr_glNamedRenderbufferStorageMultisampleEXT; + #define glNamedRenderbufferStorageMultisampleEXT GLeeFuncPtr_glNamedRenderbufferStorageMultisampleEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedRenderbufferStorageMultisampleCoverageEXT +#define GLEE_H_DEFINED_glNamedRenderbufferStorageMultisampleCoverageEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC GLeeFuncPtr_glNamedRenderbufferStorageMultisampleCoverageEXT; + #define glNamedRenderbufferStorageMultisampleCoverageEXT GLeeFuncPtr_glNamedRenderbufferStorageMultisampleCoverageEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferTextureEXT +#define GLEE_H_DEFINED_glNamedFramebufferTextureEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC GLeeFuncPtr_glNamedFramebufferTextureEXT; + #define glNamedFramebufferTextureEXT GLeeFuncPtr_glNamedFramebufferTextureEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferTextureLayerEXT +#define GLEE_H_DEFINED_glNamedFramebufferTextureLayerEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC GLeeFuncPtr_glNamedFramebufferTextureLayerEXT; + #define glNamedFramebufferTextureLayerEXT GLeeFuncPtr_glNamedFramebufferTextureLayerEXT +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferTextureFaceEXT +#define GLEE_H_DEFINED_glNamedFramebufferTextureFaceEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC GLeeFuncPtr_glNamedFramebufferTextureFaceEXT; + #define glNamedFramebufferTextureFaceEXT GLeeFuncPtr_glNamedFramebufferTextureFaceEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureRenderbufferEXT +#define GLEE_H_DEFINED_glTextureRenderbufferEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLTEXTURERENDERBUFFEREXTPROC GLeeFuncPtr_glTextureRenderbufferEXT; + #define glTextureRenderbufferEXT GLeeFuncPtr_glTextureRenderbufferEXT +#endif +#ifndef GLEE_H_DEFINED_glMultiTexRenderbufferEXT +#define GLEE_H_DEFINED_glMultiTexRenderbufferEXT + typedef void (APIENTRYP GLEEPFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLMULTITEXRENDERBUFFEREXTPROC GLeeFuncPtr_glMultiTexRenderbufferEXT; + #define glMultiTexRenderbufferEXT GLeeFuncPtr_glMultiTexRenderbufferEXT +#endif +#endif + +/* GL_EXT_vertex_array_bgra */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 +#define __GLEE_GL_EXT_vertex_array_bgra 1 +/* Constants */ +#endif + +/* GL_EXT_texture_swizzle */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 +#define __GLEE_GL_EXT_texture_swizzle 1 +/* Constants */ +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#endif + +/* GL_NV_explicit_multisample */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 +#define __GLEE_GL_NV_explicit_multisample 1 +/* Constants */ +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#ifndef GLEE_H_DEFINED_glGetMultisamplefvNV +#define GLEE_H_DEFINED_glGetMultisamplefvNV + typedef void (APIENTRYP GLEEPFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat * val); + GLEE_EXTERN GLEEPFNGLGETMULTISAMPLEFVNVPROC GLeeFuncPtr_glGetMultisamplefvNV; + #define glGetMultisamplefvNV GLeeFuncPtr_glGetMultisamplefvNV +#endif +#ifndef GLEE_H_DEFINED_glSampleMaskIndexedNV +#define GLEE_H_DEFINED_glSampleMaskIndexedNV + typedef void (APIENTRYP GLEEPFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); + GLEE_EXTERN GLEEPFNGLSAMPLEMASKINDEXEDNVPROC GLeeFuncPtr_glSampleMaskIndexedNV; + #define glSampleMaskIndexedNV GLeeFuncPtr_glSampleMaskIndexedNV +#endif +#ifndef GLEE_H_DEFINED_glTexRenderbufferNV +#define GLEE_H_DEFINED_glTexRenderbufferNV + typedef void (APIENTRYP GLEEPFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); + GLEE_EXTERN GLEEPFNGLTEXRENDERBUFFERNVPROC GLeeFuncPtr_glTexRenderbufferNV; + #define glTexRenderbufferNV GLeeFuncPtr_glTexRenderbufferNV +#endif +#endif + +/* GL_NV_transform_feedback2 */ + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 1 +#define __GLEE_GL_NV_transform_feedback2 1 +/* Constants */ +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +#ifndef GLEE_H_DEFINED_glBindTransformFeedbackNV +#define GLEE_H_DEFINED_glBindTransformFeedbackNV + typedef void (APIENTRYP GLEEPFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); + GLEE_EXTERN GLEEPFNGLBINDTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glBindTransformFeedbackNV; + #define glBindTransformFeedbackNV GLeeFuncPtr_glBindTransformFeedbackNV +#endif +#ifndef GLEE_H_DEFINED_glDeleteTransformFeedbacksNV +#define GLEE_H_DEFINED_glDeleteTransformFeedbacksNV + typedef void (APIENTRYP GLEEPFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint * ids); + GLEE_EXTERN GLEEPFNGLDELETETRANSFORMFEEDBACKSNVPROC GLeeFuncPtr_glDeleteTransformFeedbacksNV; + #define glDeleteTransformFeedbacksNV GLeeFuncPtr_glDeleteTransformFeedbacksNV +#endif +#ifndef GLEE_H_DEFINED_glGenTransformFeedbacksNV +#define GLEE_H_DEFINED_glGenTransformFeedbacksNV + typedef void (APIENTRYP GLEEPFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint * ids); + GLEE_EXTERN GLEEPFNGLGENTRANSFORMFEEDBACKSNVPROC GLeeFuncPtr_glGenTransformFeedbacksNV; + #define glGenTransformFeedbacksNV GLeeFuncPtr_glGenTransformFeedbacksNV +#endif +#ifndef GLEE_H_DEFINED_glIsTransformFeedbackNV +#define GLEE_H_DEFINED_glIsTransformFeedbackNV + typedef GLboolean (APIENTRYP GLEEPFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLISTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glIsTransformFeedbackNV; + #define glIsTransformFeedbackNV GLeeFuncPtr_glIsTransformFeedbackNV +#endif +#ifndef GLEE_H_DEFINED_glPauseTransformFeedbackNV +#define GLEE_H_DEFINED_glPauseTransformFeedbackNV + typedef void (APIENTRYP GLEEPFNGLPAUSETRANSFORMFEEDBACKNVPROC) (); + GLEE_EXTERN GLEEPFNGLPAUSETRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glPauseTransformFeedbackNV; + #define glPauseTransformFeedbackNV GLeeFuncPtr_glPauseTransformFeedbackNV +#endif +#ifndef GLEE_H_DEFINED_glResumeTransformFeedbackNV +#define GLEE_H_DEFINED_glResumeTransformFeedbackNV + typedef void (APIENTRYP GLEEPFNGLRESUMETRANSFORMFEEDBACKNVPROC) (); + GLEE_EXTERN GLEEPFNGLRESUMETRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glResumeTransformFeedbackNV; + #define glResumeTransformFeedbackNV GLeeFuncPtr_glResumeTransformFeedbackNV +#endif +#ifndef GLEE_H_DEFINED_glDrawTransformFeedbackNV +#define GLEE_H_DEFINED_glDrawTransformFeedbackNV + typedef void (APIENTRYP GLEEPFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); + GLEE_EXTERN GLEEPFNGLDRAWTRANSFORMFEEDBACKNVPROC GLeeFuncPtr_glDrawTransformFeedbackNV; + #define glDrawTransformFeedbackNV GLeeFuncPtr_glDrawTransformFeedbackNV +#endif +#endif + +/* GL_SGIX_texture_select */ + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#define __GLEE_GL_SGIX_texture_select 1 +/* Constants */ +#endif + +/* GL_INGR_blend_func_separate */ + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +#define __GLEE_GL_INGR_blend_func_separate 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glBlendFuncSeparateINGR +#define GLEE_H_DEFINED_glBlendFuncSeparateINGR + typedef void (APIENTRYP GLEEPFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + GLEE_EXTERN GLEEPFNGLBLENDFUNCSEPARATEINGRPROC GLeeFuncPtr_glBlendFuncSeparateINGR; + #define glBlendFuncSeparateINGR GLeeFuncPtr_glBlendFuncSeparateINGR +#endif +#endif + +/* GL_SGIX_depth_pass_instrument */ + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#define __GLEE_GL_SGIX_depth_pass_instrument 1 +/* Constants */ +#endif + +/* GL_SGIX_igloo_interface */ + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +#define __GLEE_GL_SGIX_igloo_interface 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glIglooInterfaceSGIX +#define GLEE_H_DEFINED_glIglooInterfaceSGIX + typedef void (APIENTRYP GLEEPFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid * params); + GLEE_EXTERN GLEEPFNGLIGLOOINTERFACESGIXPROC GLeeFuncPtr_glIglooInterfaceSGIX; + #define glIglooInterfaceSGIX GLeeFuncPtr_glIglooInterfaceSGIX +#endif +#endif + +/* GL_EXT_fragment_lighting */ + +#ifndef GL_EXT_fragment_lighting +#define GL_EXT_fragment_lighting 1 +#define __GLEE_GL_EXT_fragment_lighting 1 +/* Constants */ +#define GL_FRAGMENT_LIGHTING_EXT 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 +#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 +#define GL_LIGHT_ENV_MODE_EXT 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B +#define GL_FRAGMENT_LIGHT0_EXT 0x840C +#define GL_FRAGMENT_LIGHT7_EXT 0x8413 +#ifndef GLEE_H_DEFINED_glFragmentLightModeliEXT +#define GLEE_H_DEFINED_glFragmentLightModeliEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELIEXTPROC GLeeFuncPtr_glFragmentLightModeliEXT; + #define glFragmentLightModeliEXT GLeeFuncPtr_glFragmentLightModeliEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightModelfEXT +#define GLEE_H_DEFINED_glFragmentLightModelfEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELFEXTPROC GLeeFuncPtr_glFragmentLightModelfEXT; + #define glFragmentLightModelfEXT GLeeFuncPtr_glFragmentLightModelfEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightModelivEXT +#define GLEE_H_DEFINED_glFragmentLightModelivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELIVEXTPROC GLeeFuncPtr_glFragmentLightModelivEXT; + #define glFragmentLightModelivEXT GLeeFuncPtr_glFragmentLightModelivEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightModelfvEXT +#define GLEE_H_DEFINED_glFragmentLightModelfvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTMODELFVEXTPROC GLeeFuncPtr_glFragmentLightModelfvEXT; + #define glFragmentLightModelfvEXT GLeeFuncPtr_glFragmentLightModelfvEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightiEXT +#define GLEE_H_DEFINED_glFragmentLightiEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTIEXTPROC GLeeFuncPtr_glFragmentLightiEXT; + #define glFragmentLightiEXT GLeeFuncPtr_glFragmentLightiEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightfEXT +#define GLEE_H_DEFINED_glFragmentLightfEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTFEXTPROC GLeeFuncPtr_glFragmentLightfEXT; + #define glFragmentLightfEXT GLeeFuncPtr_glFragmentLightfEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightivEXT +#define GLEE_H_DEFINED_glFragmentLightivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTIVEXTPROC GLeeFuncPtr_glFragmentLightivEXT; + #define glFragmentLightivEXT GLeeFuncPtr_glFragmentLightivEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentLightfvEXT +#define GLEE_H_DEFINED_glFragmentLightfvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTLIGHTFVEXTPROC GLeeFuncPtr_glFragmentLightfvEXT; + #define glFragmentLightfvEXT GLeeFuncPtr_glFragmentLightfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentLightivEXT +#define GLEE_H_DEFINED_glGetFragmentLightivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTLIGHTIVEXTPROC GLeeFuncPtr_glGetFragmentLightivEXT; + #define glGetFragmentLightivEXT GLeeFuncPtr_glGetFragmentLightivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentLightfvEXT +#define GLEE_H_DEFINED_glGetFragmentLightfvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTLIGHTFVEXTPROC GLeeFuncPtr_glGetFragmentLightfvEXT; + #define glGetFragmentLightfvEXT GLeeFuncPtr_glGetFragmentLightfvEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialfEXT +#define GLEE_H_DEFINED_glFragmentMaterialfEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALFEXTPROC GLeeFuncPtr_glFragmentMaterialfEXT; + #define glFragmentMaterialfEXT GLeeFuncPtr_glFragmentMaterialfEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialiEXT +#define GLEE_H_DEFINED_glFragmentMaterialiEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALIEXTPROC GLeeFuncPtr_glFragmentMaterialiEXT; + #define glFragmentMaterialiEXT GLeeFuncPtr_glFragmentMaterialiEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialfvEXT +#define GLEE_H_DEFINED_glFragmentMaterialfvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALFVEXTPROC GLeeFuncPtr_glFragmentMaterialfvEXT; + #define glFragmentMaterialfvEXT GLeeFuncPtr_glFragmentMaterialfvEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentMaterialivEXT +#define GLEE_H_DEFINED_glFragmentMaterialivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLFRAGMENTMATERIALIVEXTPROC GLeeFuncPtr_glFragmentMaterialivEXT; + #define glFragmentMaterialivEXT GLeeFuncPtr_glFragmentMaterialivEXT +#endif +#ifndef GLEE_H_DEFINED_glFragmentColorMaterialEXT +#define GLEE_H_DEFINED_glFragmentColorMaterialEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); + GLEE_EXTERN GLEEPFNGLFRAGMENTCOLORMATERIALEXTPROC GLeeFuncPtr_glFragmentColorMaterialEXT; + #define glFragmentColorMaterialEXT GLeeFuncPtr_glFragmentColorMaterialEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentMaterialfvEXT +#define GLEE_H_DEFINED_glGetFragmentMaterialfvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTMATERIALFVEXTPROC GLeeFuncPtr_glGetFragmentMaterialfvEXT; + #define glGetFragmentMaterialfvEXT GLeeFuncPtr_glGetFragmentMaterialfvEXT +#endif +#ifndef GLEE_H_DEFINED_glGetFragmentMaterialivEXT +#define GLEE_H_DEFINED_glGetFragmentMaterialivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAGMENTMATERIALIVEXTPROC GLeeFuncPtr_glGetFragmentMaterialivEXT; + #define glGetFragmentMaterialivEXT GLeeFuncPtr_glGetFragmentMaterialivEXT +#endif +#ifndef GLEE_H_DEFINED_glLightEnviEXT +#define GLEE_H_DEFINED_glLightEnviEXT + typedef GLvoid (APIENTRYP GLEEPFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLLIGHTENVIEXTPROC GLeeFuncPtr_glLightEnviEXT; + #define glLightEnviEXT GLeeFuncPtr_glLightEnviEXT +#endif +#endif + +/* GL_EXT_geometry_shader4 */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#define __GLEE_GL_EXT_geometry_shader4 1 +/* Constants */ +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#ifndef GLEE_H_DEFINED_glProgramParameteriEXT +#define GLEE_H_DEFINED_glProgramParameteriEXT + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); + GLEE_EXTERN GLEEPFNGLPROGRAMPARAMETERIEXTPROC GLeeFuncPtr_glProgramParameteriEXT; + #define glProgramParameteriEXT GLeeFuncPtr_glProgramParameteriEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureEXT +#define GLEE_H_DEFINED_glFramebufferTextureEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC GLeeFuncPtr_glFramebufferTextureEXT; + #define glFramebufferTextureEXT GLeeFuncPtr_glFramebufferTextureEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureLayerEXT +#define GLEE_H_DEFINED_glFramebufferTextureLayerEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC GLeeFuncPtr_glFramebufferTextureLayerEXT; + #define glFramebufferTextureLayerEXT GLeeFuncPtr_glFramebufferTextureLayerEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureFaceEXT +#define GLEE_H_DEFINED_glFramebufferTextureFaceEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC GLeeFuncPtr_glFramebufferTextureFaceEXT; + #define glFramebufferTextureFaceEXT GLeeFuncPtr_glFramebufferTextureFaceEXT +#endif +#endif + +/* GL_EXT_scene_marker */ + +#ifndef GL_EXT_scene_marker +#define GL_EXT_scene_marker 1 +#define __GLEE_GL_EXT_scene_marker 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glBeginSceneEXT +#define GLEE_H_DEFINED_glBeginSceneEXT + typedef GLvoid (APIENTRYP GLEEPFNGLBEGINSCENEEXTPROC) (); + GLEE_EXTERN GLEEPFNGLBEGINSCENEEXTPROC GLeeFuncPtr_glBeginSceneEXT; + #define glBeginSceneEXT GLeeFuncPtr_glBeginSceneEXT +#endif +#ifndef GLEE_H_DEFINED_glEndSceneEXT +#define GLEE_H_DEFINED_glEndSceneEXT + typedef GLvoid (APIENTRYP GLEEPFNGLENDSCENEEXTPROC) (); + GLEE_EXTERN GLEEPFNGLENDSCENEEXTPROC GLeeFuncPtr_glEndSceneEXT; + #define glEndSceneEXT GLeeFuncPtr_glEndSceneEXT +#endif +#endif + +/* GL_EXT_texture_compression_dxt1 */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#define __GLEE_GL_EXT_texture_compression_dxt1 1 +/* Constants */ +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + +/* GL_EXT_texture_env */ + +#ifndef GL_EXT_texture_env +#define GL_EXT_texture_env 1 +#define __GLEE_GL_EXT_texture_env 1 +/* Constants */ +#define GL_TEXTURE_ENV0_EXT 0 +#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0 +#define GL_ENV_COPY_EXT 0 +#define GL_ENV_REPLACE_EXT 0 +#define GL_ENV_MODULATE_EXT 0 +#define GL_ENV_ADD_EXT 0 +#define GL_ENV_SUBTRACT_EXT 0 +#define GL_ENV_REVERSE_SUBTRACT_EXT 0 +#define GL_ENV_BLEND_EXT 0 +#define GL_ENV_REVERSE_BLEND_EXT 0 +#define GL_TEXTURE_ENV_SHIFT_EXT 0 +#endif + +/* GL_IBM_static_data */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 +#define __GLEE_GL_IBM_static_data 1 +/* Constants */ +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 +#endif + +/* GL_NV_gpu_program4 */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#define __GLEE_GL_NV_gpu_program4 1 +/* Constants */ +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#ifndef GLEE_H_DEFINED_glProgramLocalParameterI4iNV +#define GLEE_H_DEFINED_glProgramLocalParameterI4iNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETERI4INVPROC GLeeFuncPtr_glProgramLocalParameterI4iNV; + #define glProgramLocalParameterI4iNV GLeeFuncPtr_glProgramLocalParameterI4iNV +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameterI4ivNV +#define GLEE_H_DEFINED_glProgramLocalParameterI4ivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETERI4IVNVPROC GLeeFuncPtr_glProgramLocalParameterI4ivNV; + #define glProgramLocalParameterI4ivNV GLeeFuncPtr_glProgramLocalParameterI4ivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParametersI4ivNV +#define GLEE_H_DEFINED_glProgramLocalParametersI4ivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC GLeeFuncPtr_glProgramLocalParametersI4ivNV; + #define glProgramLocalParametersI4ivNV GLeeFuncPtr_glProgramLocalParametersI4ivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameterI4uiNV +#define GLEE_H_DEFINED_glProgramLocalParameterI4uiNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETERI4UINVPROC GLeeFuncPtr_glProgramLocalParameterI4uiNV; + #define glProgramLocalParameterI4uiNV GLeeFuncPtr_glProgramLocalParameterI4uiNV +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParameterI4uivNV +#define GLEE_H_DEFINED_glProgramLocalParameterI4uivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC GLeeFuncPtr_glProgramLocalParameterI4uivNV; + #define glProgramLocalParameterI4uivNV GLeeFuncPtr_glProgramLocalParameterI4uivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramLocalParametersI4uivNV +#define GLEE_H_DEFINED_glProgramLocalParametersI4uivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC GLeeFuncPtr_glProgramLocalParametersI4uivNV; + #define glProgramLocalParametersI4uivNV GLeeFuncPtr_glProgramLocalParametersI4uivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameterI4iNV +#define GLEE_H_DEFINED_glProgramEnvParameterI4iNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETERI4INVPROC GLeeFuncPtr_glProgramEnvParameterI4iNV; + #define glProgramEnvParameterI4iNV GLeeFuncPtr_glProgramEnvParameterI4iNV +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameterI4ivNV +#define GLEE_H_DEFINED_glProgramEnvParameterI4ivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETERI4IVNVPROC GLeeFuncPtr_glProgramEnvParameterI4ivNV; + #define glProgramEnvParameterI4ivNV GLeeFuncPtr_glProgramEnvParameterI4ivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParametersI4ivNV +#define GLEE_H_DEFINED_glProgramEnvParametersI4ivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETERSI4IVNVPROC GLeeFuncPtr_glProgramEnvParametersI4ivNV; + #define glProgramEnvParametersI4ivNV GLeeFuncPtr_glProgramEnvParametersI4ivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameterI4uiNV +#define GLEE_H_DEFINED_glProgramEnvParameterI4uiNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETERI4UINVPROC GLeeFuncPtr_glProgramEnvParameterI4uiNV; + #define glProgramEnvParameterI4uiNV GLeeFuncPtr_glProgramEnvParameterI4uiNV +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParameterI4uivNV +#define GLEE_H_DEFINED_glProgramEnvParameterI4uivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETERI4UIVNVPROC GLeeFuncPtr_glProgramEnvParameterI4uivNV; + #define glProgramEnvParameterI4uivNV GLeeFuncPtr_glProgramEnvParameterI4uivNV +#endif +#ifndef GLEE_H_DEFINED_glProgramEnvParametersI4uivNV +#define GLEE_H_DEFINED_glProgramEnvParametersI4uivNV + typedef GLvoid (APIENTRYP GLEEPFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint * params); + GLEE_EXTERN GLEEPFNGLPROGRAMENVPARAMETERSI4UIVNVPROC GLeeFuncPtr_glProgramEnvParametersI4uivNV; + #define glProgramEnvParametersI4uivNV GLeeFuncPtr_glProgramEnvParametersI4uivNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramLocalParameterIivNV +#define GLEE_H_DEFINED_glGetProgramLocalParameterIivNV + typedef GLvoid (APIENTRYP GLEEPFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC GLeeFuncPtr_glGetProgramLocalParameterIivNV; + #define glGetProgramLocalParameterIivNV GLeeFuncPtr_glGetProgramLocalParameterIivNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramLocalParameterIuivNV +#define GLEE_H_DEFINED_glGetProgramLocalParameterIuivNV + typedef GLvoid (APIENTRYP GLEEPFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC GLeeFuncPtr_glGetProgramLocalParameterIuivNV; + #define glGetProgramLocalParameterIuivNV GLeeFuncPtr_glGetProgramLocalParameterIuivNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramEnvParameterIivNV +#define GLEE_H_DEFINED_glGetProgramEnvParameterIivNV + typedef GLvoid (APIENTRYP GLEEPFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMENVPARAMETERIIVNVPROC GLeeFuncPtr_glGetProgramEnvParameterIivNV; + #define glGetProgramEnvParameterIivNV GLeeFuncPtr_glGetProgramEnvParameterIivNV +#endif +#ifndef GLEE_H_DEFINED_glGetProgramEnvParameterIuivNV +#define GLEE_H_DEFINED_glGetProgramEnvParameterIuivNV + typedef GLvoid (APIENTRYP GLEEPFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMENVPARAMETERIUIVNVPROC GLeeFuncPtr_glGetProgramEnvParameterIuivNV; + #define glGetProgramEnvParameterIuivNV GLeeFuncPtr_glGetProgramEnvParameterIuivNV +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureEXT +#define GLEE_H_DEFINED_glFramebufferTextureEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTUREEXTPROC GLeeFuncPtr_glFramebufferTextureEXT; + #define glFramebufferTextureEXT GLeeFuncPtr_glFramebufferTextureEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureLayerEXT +#define GLEE_H_DEFINED_glFramebufferTextureLayerEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTURELAYEREXTPROC GLeeFuncPtr_glFramebufferTextureLayerEXT; + #define glFramebufferTextureLayerEXT GLeeFuncPtr_glFramebufferTextureLayerEXT +#endif +#ifndef GLEE_H_DEFINED_glFramebufferTextureFaceEXT +#define GLEE_H_DEFINED_glFramebufferTextureFaceEXT + typedef GLvoid (APIENTRYP GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERTEXTUREFACEEXTPROC GLeeFuncPtr_glFramebufferTextureFaceEXT; + #define glFramebufferTextureFaceEXT GLeeFuncPtr_glFramebufferTextureFaceEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2iEXT +#define GLEE_H_DEFINED_glVertexAttribI2iEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2IEXTPROC GLeeFuncPtr_glVertexAttribI2iEXT; + #define glVertexAttribI2iEXT GLeeFuncPtr_glVertexAttribI2iEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3iEXT +#define GLEE_H_DEFINED_glVertexAttribI3iEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3IEXTPROC GLeeFuncPtr_glVertexAttribI3iEXT; + #define glVertexAttribI3iEXT GLeeFuncPtr_glVertexAttribI3iEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4iEXT +#define GLEE_H_DEFINED_glVertexAttribI4iEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4IEXTPROC GLeeFuncPtr_glVertexAttribI4iEXT; + #define glVertexAttribI4iEXT GLeeFuncPtr_glVertexAttribI4iEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI1uiEXT +#define GLEE_H_DEFINED_glVertexAttribI1uiEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI1UIEXTPROC GLeeFuncPtr_glVertexAttribI1uiEXT; + #define glVertexAttribI1uiEXT GLeeFuncPtr_glVertexAttribI1uiEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2uiEXT +#define GLEE_H_DEFINED_glVertexAttribI2uiEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2UIEXTPROC GLeeFuncPtr_glVertexAttribI2uiEXT; + #define glVertexAttribI2uiEXT GLeeFuncPtr_glVertexAttribI2uiEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3uiEXT +#define GLEE_H_DEFINED_glVertexAttribI3uiEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3UIEXTPROC GLeeFuncPtr_glVertexAttribI3uiEXT; + #define glVertexAttribI3uiEXT GLeeFuncPtr_glVertexAttribI3uiEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4uiEXT +#define GLEE_H_DEFINED_glVertexAttribI4uiEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4UIEXTPROC GLeeFuncPtr_glVertexAttribI4uiEXT; + #define glVertexAttribI4uiEXT GLeeFuncPtr_glVertexAttribI4uiEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI1ivEXT +#define GLEE_H_DEFINED_glVertexAttribI1ivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI1IVEXTPROC GLeeFuncPtr_glVertexAttribI1ivEXT; + #define glVertexAttribI1ivEXT GLeeFuncPtr_glVertexAttribI1ivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2ivEXT +#define GLEE_H_DEFINED_glVertexAttribI2ivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2IVEXTPROC GLeeFuncPtr_glVertexAttribI2ivEXT; + #define glVertexAttribI2ivEXT GLeeFuncPtr_glVertexAttribI2ivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3ivEXT +#define GLEE_H_DEFINED_glVertexAttribI3ivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3IVEXTPROC GLeeFuncPtr_glVertexAttribI3ivEXT; + #define glVertexAttribI3ivEXT GLeeFuncPtr_glVertexAttribI3ivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4ivEXT +#define GLEE_H_DEFINED_glVertexAttribI4ivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4IVEXTPROC GLeeFuncPtr_glVertexAttribI4ivEXT; + #define glVertexAttribI4ivEXT GLeeFuncPtr_glVertexAttribI4ivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI1uivEXT +#define GLEE_H_DEFINED_glVertexAttribI1uivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI1UIVEXTPROC GLeeFuncPtr_glVertexAttribI1uivEXT; + #define glVertexAttribI1uivEXT GLeeFuncPtr_glVertexAttribI1uivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI2uivEXT +#define GLEE_H_DEFINED_glVertexAttribI2uivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI2UIVEXTPROC GLeeFuncPtr_glVertexAttribI2uivEXT; + #define glVertexAttribI2uivEXT GLeeFuncPtr_glVertexAttribI2uivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI3uivEXT +#define GLEE_H_DEFINED_glVertexAttribI3uivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI3UIVEXTPROC GLeeFuncPtr_glVertexAttribI3uivEXT; + #define glVertexAttribI3uivEXT GLeeFuncPtr_glVertexAttribI3uivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4uivEXT +#define GLEE_H_DEFINED_glVertexAttribI4uivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4UIVEXTPROC GLeeFuncPtr_glVertexAttribI4uivEXT; + #define glVertexAttribI4uivEXT GLeeFuncPtr_glVertexAttribI4uivEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4bvEXT +#define GLEE_H_DEFINED_glVertexAttribI4bvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4BVEXTPROC GLeeFuncPtr_glVertexAttribI4bvEXT; + #define glVertexAttribI4bvEXT GLeeFuncPtr_glVertexAttribI4bvEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4svEXT +#define GLEE_H_DEFINED_glVertexAttribI4svEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4SVEXTPROC GLeeFuncPtr_glVertexAttribI4svEXT; + #define glVertexAttribI4svEXT GLeeFuncPtr_glVertexAttribI4svEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4ubvEXT +#define GLEE_H_DEFINED_glVertexAttribI4ubvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4UBVEXTPROC GLeeFuncPtr_glVertexAttribI4ubvEXT; + #define glVertexAttribI4ubvEXT GLeeFuncPtr_glVertexAttribI4ubvEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribI4usvEXT +#define GLEE_H_DEFINED_glVertexAttribI4usvEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort * v); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBI4USVEXTPROC GLeeFuncPtr_glVertexAttribI4usvEXT; + #define glVertexAttribI4usvEXT GLeeFuncPtr_glVertexAttribI4usvEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribIPointerEXT +#define GLEE_H_DEFINED_glVertexAttribIPointerEXT + typedef GLvoid (APIENTRYP GLEEPFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBIPOINTEREXTPROC GLeeFuncPtr_glVertexAttribIPointerEXT; + #define glVertexAttribIPointerEXT GLeeFuncPtr_glVertexAttribIPointerEXT +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribIivEXT +#define GLEE_H_DEFINED_glGetVertexAttribIivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBIIVEXTPROC GLeeFuncPtr_glGetVertexAttribIivEXT; + #define glGetVertexAttribIivEXT GLeeFuncPtr_glGetVertexAttribIivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetVertexAttribIuivEXT +#define GLEE_H_DEFINED_glGetVertexAttribIuivEXT + typedef GLvoid (APIENTRYP GLEEPFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint * params); + GLEE_EXTERN GLEEPFNGLGETVERTEXATTRIBIUIVEXTPROC GLeeFuncPtr_glGetVertexAttribIuivEXT; + #define glGetVertexAttribIuivEXT GLeeFuncPtr_glGetVertexAttribIuivEXT +#endif +#endif + +/* GL_OES_byte_coordinates */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 +#define __GLEE_GL_OES_byte_coordinates 1 +/* Constants */ +#define GL_BYTE 0x1400 +#endif + +/* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#define __GLEE_GL_OES_compressed_paletted_texture 1 +/* Constants */ +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +/* GL_OES_single_precision */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 +#define __GLEE_GL_OES_single_precision 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glDepthRangefOES +#define GLEE_H_DEFINED_glDepthRangefOES + typedef GLvoid (APIENTRYP GLEEPFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); + GLEE_EXTERN GLEEPFNGLDEPTHRANGEFOESPROC GLeeFuncPtr_glDepthRangefOES; + #define glDepthRangefOES GLeeFuncPtr_glDepthRangefOES +#endif +#ifndef GLEE_H_DEFINED_glFrustumfOES +#define GLEE_H_DEFINED_glFrustumfOES + typedef GLvoid (APIENTRYP GLEEPFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + GLEE_EXTERN GLEEPFNGLFRUSTUMFOESPROC GLeeFuncPtr_glFrustumfOES; + #define glFrustumfOES GLeeFuncPtr_glFrustumfOES +#endif +#ifndef GLEE_H_DEFINED_glOrthofOES +#define GLEE_H_DEFINED_glOrthofOES + typedef GLvoid (APIENTRYP GLEEPFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + GLEE_EXTERN GLEEPFNGLORTHOFOESPROC GLeeFuncPtr_glOrthofOES; + #define glOrthofOES GLeeFuncPtr_glOrthofOES +#endif +#ifndef GLEE_H_DEFINED_glClipPlanefOES +#define GLEE_H_DEFINED_glClipPlanefOES + typedef GLvoid (APIENTRYP GLEEPFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation); + GLEE_EXTERN GLEEPFNGLCLIPPLANEFOESPROC GLeeFuncPtr_glClipPlanefOES; + #define glClipPlanefOES GLeeFuncPtr_glClipPlanefOES +#endif +#ifndef GLEE_H_DEFINED_glGetClipPlanefOES +#define GLEE_H_DEFINED_glGetClipPlanefOES + typedef GLvoid (APIENTRYP GLEEPFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation); + GLEE_EXTERN GLEEPFNGLGETCLIPPLANEFOESPROC GLeeFuncPtr_glGetClipPlanefOES; + #define glGetClipPlanefOES GLeeFuncPtr_glGetClipPlanefOES +#endif +#ifndef GLEE_H_DEFINED_glClearDepthfOES +#define GLEE_H_DEFINED_glClearDepthfOES + typedef GLvoid (APIENTRYP GLEEPFNGLCLEARDEPTHFOESPROC) (GLclampd depth); + GLEE_EXTERN GLEEPFNGLCLEARDEPTHFOESPROC GLeeFuncPtr_glClearDepthfOES; + #define glClearDepthfOES GLeeFuncPtr_glClearDepthfOES +#endif +#endif + +/* GL_SGIX_pixel_texture_bits */ + +#ifndef GL_SGIX_pixel_texture_bits +#define GL_SGIX_pixel_texture_bits 1 +#define __GLEE_GL_SGIX_pixel_texture_bits 1 +/* Constants */ +#endif + +/* GL_SGIX_texture_range */ + +#ifndef GL_SGIX_texture_range +#define GL_SGIX_texture_range 1 +#define __GLEE_GL_SGIX_texture_range 1 +/* Constants */ +#define GL_RGB_SIGNED_SGIX 0x85E0 +#define GL_RGBA_SIGNED_SGIX 0x85E1 +#define GL_ALPHA_SIGNED_SGIX 0x85E2 +#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 +#define GL_INTENSITY_SIGNED_SGIX 0x85E4 +#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 +#define GL_RGB16_SIGNED_SGIX 0x85E6 +#define GL_RGBA16_SIGNED_SGIX 0x85E7 +#define GL_ALPHA16_SIGNED_SGIX 0x85E8 +#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 +#define GL_INTENSITY16_SIGNED_SGIX 0x85EA +#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB +#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC +#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED +#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE +#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF +#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 +#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 +#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 +#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 +#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 +#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 +#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 +#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 +#define GL_MIN_LUMINANCE_SGIS 0x85F8 +#define GL_MAX_LUMINANCE_SGIS 0x85F9 +#define GL_MIN_INTENSITY_SGIS 0x85FA +#define GL_MAX_INTENSITY_SGIS 0x85FB +#endif + +/* WGL */ + +#ifdef WIN32 + +/* Extension querying variables */ + +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_buffer_region; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_multisample; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_extensions_string; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_pixel_format; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_make_current_read; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_pbuffer; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_render_texture; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_pixel_format_float; +GLEE_EXTERN GLboolean _GLEE_WGL_ARB_create_context; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_make_current_read; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_pixel_format; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_pbuffer; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_depth_float; +GLEE_EXTERN GLboolean _GLEE_WGL_3DFX_multisample; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_multisample; +GLEE_EXTERN GLboolean _GLEE_WGL_I3D_digital_video_control; +GLEE_EXTERN GLboolean _GLEE_WGL_I3D_gamma; +GLEE_EXTERN GLboolean _GLEE_WGL_I3D_genlock; +GLEE_EXTERN GLboolean _GLEE_WGL_I3D_image_buffer; +GLEE_EXTERN GLboolean _GLEE_WGL_I3D_swap_frame_lock; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_render_depth_texture; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_render_texture_rectangle; +GLEE_EXTERN GLboolean _GLEE_WGL_ATI_pixel_format_float; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_float_buffer; +GLEE_EXTERN GLboolean _GLEE_WGL_3DL_stereo_control; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_pixel_format_packed_float; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_framebuffer_sRGB; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_present_video; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_swap_group; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_gpu_affinity; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_display_color_table; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_extensions_string; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_swap_control; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_vertex_array_range; +GLEE_EXTERN GLboolean _GLEE_WGL_OML_sync_control; +GLEE_EXTERN GLboolean _GLEE_WGL_I3D_swap_frame_usage; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_video_output; + +/* Aliases for extension querying variables */ + +#define GLEE_WGL_ARB_buffer_region GLeeEnabled(&_GLEE_WGL_ARB_buffer_region) +#define GLEE_WGL_ARB_multisample GLeeEnabled(&_GLEE_WGL_ARB_multisample) +#define GLEE_WGL_ARB_extensions_string GLeeEnabled(&_GLEE_WGL_ARB_extensions_string) +#define GLEE_WGL_ARB_pixel_format GLeeEnabled(&_GLEE_WGL_ARB_pixel_format) +#define GLEE_WGL_ARB_make_current_read GLeeEnabled(&_GLEE_WGL_ARB_make_current_read) +#define GLEE_WGL_ARB_pbuffer GLeeEnabled(&_GLEE_WGL_ARB_pbuffer) +#define GLEE_WGL_ARB_render_texture GLeeEnabled(&_GLEE_WGL_ARB_render_texture) +#define GLEE_WGL_ARB_pixel_format_float GLeeEnabled(&_GLEE_WGL_ARB_pixel_format_float) +#define GLEE_WGL_ARB_create_context GLeeEnabled(&_GLEE_WGL_ARB_create_context) +#define GLEE_WGL_EXT_make_current_read GLeeEnabled(&_GLEE_WGL_EXT_make_current_read) +#define GLEE_WGL_EXT_pixel_format GLeeEnabled(&_GLEE_WGL_EXT_pixel_format) +#define GLEE_WGL_EXT_pbuffer GLeeEnabled(&_GLEE_WGL_EXT_pbuffer) +#define GLEE_WGL_EXT_depth_float GLeeEnabled(&_GLEE_WGL_EXT_depth_float) +#define GLEE_WGL_3DFX_multisample GLeeEnabled(&_GLEE_WGL_3DFX_multisample) +#define GLEE_WGL_EXT_multisample GLeeEnabled(&_GLEE_WGL_EXT_multisample) +#define GLEE_WGL_I3D_digital_video_control GLeeEnabled(&_GLEE_WGL_I3D_digital_video_control) +#define GLEE_WGL_I3D_gamma GLeeEnabled(&_GLEE_WGL_I3D_gamma) +#define GLEE_WGL_I3D_genlock GLeeEnabled(&_GLEE_WGL_I3D_genlock) +#define GLEE_WGL_I3D_image_buffer GLeeEnabled(&_GLEE_WGL_I3D_image_buffer) +#define GLEE_WGL_I3D_swap_frame_lock GLeeEnabled(&_GLEE_WGL_I3D_swap_frame_lock) +#define GLEE_WGL_NV_render_depth_texture GLeeEnabled(&_GLEE_WGL_NV_render_depth_texture) +#define GLEE_WGL_NV_render_texture_rectangle GLeeEnabled(&_GLEE_WGL_NV_render_texture_rectangle) +#define GLEE_WGL_ATI_pixel_format_float GLeeEnabled(&_GLEE_WGL_ATI_pixel_format_float) +#define GLEE_WGL_NV_float_buffer GLeeEnabled(&_GLEE_WGL_NV_float_buffer) +#define GLEE_WGL_3DL_stereo_control GLeeEnabled(&_GLEE_WGL_3DL_stereo_control) +#define GLEE_WGL_EXT_pixel_format_packed_float GLeeEnabled(&_GLEE_WGL_EXT_pixel_format_packed_float) +#define GLEE_WGL_EXT_framebuffer_sRGB GLeeEnabled(&_GLEE_WGL_EXT_framebuffer_sRGB) +#define GLEE_WGL_NV_present_video GLeeEnabled(&_GLEE_WGL_NV_present_video) +#define GLEE_WGL_NV_swap_group GLeeEnabled(&_GLEE_WGL_NV_swap_group) +#define GLEE_WGL_NV_gpu_affinity GLeeEnabled(&_GLEE_WGL_NV_gpu_affinity) +#define GLEE_WGL_EXT_display_color_table GLeeEnabled(&_GLEE_WGL_EXT_display_color_table) +#define GLEE_WGL_EXT_extensions_string GLeeEnabled(&_GLEE_WGL_EXT_extensions_string) +#define GLEE_WGL_EXT_swap_control GLeeEnabled(&_GLEE_WGL_EXT_swap_control) +#define GLEE_WGL_NV_vertex_array_range GLeeEnabled(&_GLEE_WGL_NV_vertex_array_range) +#define GLEE_WGL_OML_sync_control GLeeEnabled(&_GLEE_WGL_OML_sync_control) +#define GLEE_WGL_I3D_swap_frame_usage GLeeEnabled(&_GLEE_WGL_I3D_swap_frame_usage) +#define GLEE_WGL_NV_video_output GLeeEnabled(&_GLEE_WGL_NV_video_output) + +/* WGL_ARB_buffer_region */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#define __GLEE_WGL_ARB_buffer_region 1 +/* Constants */ +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#ifndef GLEE_H_DEFINED_wglCreateBufferRegionARB +#define GLEE_H_DEFINED_wglCreateBufferRegionARB + typedef HANDLE (APIENTRYP GLEEPFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); + GLEE_EXTERN GLEEPFNWGLCREATEBUFFERREGIONARBPROC GLeeFuncPtr_wglCreateBufferRegionARB; + #define wglCreateBufferRegionARB GLeeFuncPtr_wglCreateBufferRegionARB +#endif +#ifndef GLEE_H_DEFINED_wglDeleteBufferRegionARB +#define GLEE_H_DEFINED_wglDeleteBufferRegionARB + typedef VOID (APIENTRYP GLEEPFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); + GLEE_EXTERN GLEEPFNWGLDELETEBUFFERREGIONARBPROC GLeeFuncPtr_wglDeleteBufferRegionARB; + #define wglDeleteBufferRegionARB GLeeFuncPtr_wglDeleteBufferRegionARB +#endif +#ifndef GLEE_H_DEFINED_wglSaveBufferRegionARB +#define GLEE_H_DEFINED_wglSaveBufferRegionARB + typedef BOOL (APIENTRYP GLEEPFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + GLEE_EXTERN GLEEPFNWGLSAVEBUFFERREGIONARBPROC GLeeFuncPtr_wglSaveBufferRegionARB; + #define wglSaveBufferRegionARB GLeeFuncPtr_wglSaveBufferRegionARB +#endif +#ifndef GLEE_H_DEFINED_wglRestoreBufferRegionARB +#define GLEE_H_DEFINED_wglRestoreBufferRegionARB + typedef BOOL (APIENTRYP GLEEPFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); + GLEE_EXTERN GLEEPFNWGLRESTOREBUFFERREGIONARBPROC GLeeFuncPtr_wglRestoreBufferRegionARB; + #define wglRestoreBufferRegionARB GLeeFuncPtr_wglRestoreBufferRegionARB +#endif +#endif + +/* WGL_ARB_multisample */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#define __GLEE_WGL_ARB_multisample 1 +/* Constants */ +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +/* WGL_ARB_extensions_string */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +#define __GLEE_WGL_ARB_extensions_string 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglGetExtensionsStringARB +#define GLEE_H_DEFINED_wglGetExtensionsStringARB + typedef const char * (APIENTRYP GLEEPFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + GLEE_EXTERN GLEEPFNWGLGETEXTENSIONSSTRINGARBPROC GLeeFuncPtr_wglGetExtensionsStringARB; + #define wglGetExtensionsStringARB GLeeFuncPtr_wglGetExtensionsStringARB +#endif +#endif + +/* WGL_ARB_pixel_format */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#define __GLEE_WGL_ARB_pixel_format 1 +/* Constants */ +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#ifndef GLEE_H_DEFINED_wglGetPixelFormatAttribivARB +#define GLEE_H_DEFINED_wglGetPixelFormatAttribivARB + typedef BOOL (APIENTRYP GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, int * piValues); + GLEE_EXTERN GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribivARB; + #define wglGetPixelFormatAttribivARB GLeeFuncPtr_wglGetPixelFormatAttribivARB +#endif +#ifndef GLEE_H_DEFINED_wglGetPixelFormatAttribfvARB +#define GLEE_H_DEFINED_wglGetPixelFormatAttribfvARB + typedef BOOL (APIENTRYP GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, FLOAT * pfValues); + GLEE_EXTERN GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribfvARB; + #define wglGetPixelFormatAttribfvARB GLeeFuncPtr_wglGetPixelFormatAttribfvARB +#endif +#ifndef GLEE_H_DEFINED_wglChoosePixelFormatARB +#define GLEE_H_DEFINED_wglChoosePixelFormatARB + typedef BOOL (APIENTRYP GLEEPFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int * piAttribIList, const FLOAT * pfAttribFList, UINT nMaxFormats, int * piFormats, UINT * nNumFormats); + GLEE_EXTERN GLEEPFNWGLCHOOSEPIXELFORMATARBPROC GLeeFuncPtr_wglChoosePixelFormatARB; + #define wglChoosePixelFormatARB GLeeFuncPtr_wglChoosePixelFormatARB +#endif +#endif + +/* WGL_ARB_make_current_read */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#define __GLEE_WGL_ARB_make_current_read 1 +/* Constants */ +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#ifndef GLEE_H_DEFINED_wglMakeContextCurrentARB +#define GLEE_H_DEFINED_wglMakeContextCurrentARB + typedef BOOL (APIENTRYP GLEEPFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + GLEE_EXTERN GLEEPFNWGLMAKECONTEXTCURRENTARBPROC GLeeFuncPtr_wglMakeContextCurrentARB; + #define wglMakeContextCurrentARB GLeeFuncPtr_wglMakeContextCurrentARB +#endif +#ifndef GLEE_H_DEFINED_wglGetCurrentReadDCARB +#define GLEE_H_DEFINED_wglGetCurrentReadDCARB + typedef HDC (APIENTRYP GLEEPFNWGLGETCURRENTREADDCARBPROC) (); + GLEE_EXTERN GLEEPFNWGLGETCURRENTREADDCARBPROC GLeeFuncPtr_wglGetCurrentReadDCARB; + #define wglGetCurrentReadDCARB GLeeFuncPtr_wglGetCurrentReadDCARB +#endif +#endif + +/* WGL_ARB_pbuffer */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +#define __GLEE_WGL_ARB_pbuffer 1 +/* Constants */ +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#ifndef GLEE_H_DEFINED_wglCreatePbufferARB +#define GLEE_H_DEFINED_wglCreatePbufferARB + typedef HPBUFFERARB (APIENTRYP GLEEPFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int * piAttribList); + GLEE_EXTERN GLEEPFNWGLCREATEPBUFFERARBPROC GLeeFuncPtr_wglCreatePbufferARB; + #define wglCreatePbufferARB GLeeFuncPtr_wglCreatePbufferARB +#endif +#ifndef GLEE_H_DEFINED_wglGetPbufferDCARB +#define GLEE_H_DEFINED_wglGetPbufferDCARB + typedef HDC (APIENTRYP GLEEPFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); + GLEE_EXTERN GLEEPFNWGLGETPBUFFERDCARBPROC GLeeFuncPtr_wglGetPbufferDCARB; + #define wglGetPbufferDCARB GLeeFuncPtr_wglGetPbufferDCARB +#endif +#ifndef GLEE_H_DEFINED_wglReleasePbufferDCARB +#define GLEE_H_DEFINED_wglReleasePbufferDCARB + typedef int (APIENTRYP GLEEPFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + GLEE_EXTERN GLEEPFNWGLRELEASEPBUFFERDCARBPROC GLeeFuncPtr_wglReleasePbufferDCARB; + #define wglReleasePbufferDCARB GLeeFuncPtr_wglReleasePbufferDCARB +#endif +#ifndef GLEE_H_DEFINED_wglDestroyPbufferARB +#define GLEE_H_DEFINED_wglDestroyPbufferARB + typedef BOOL (APIENTRYP GLEEPFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); + GLEE_EXTERN GLEEPFNWGLDESTROYPBUFFERARBPROC GLeeFuncPtr_wglDestroyPbufferARB; + #define wglDestroyPbufferARB GLeeFuncPtr_wglDestroyPbufferARB +#endif +#ifndef GLEE_H_DEFINED_wglQueryPbufferARB +#define GLEE_H_DEFINED_wglQueryPbufferARB + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int * piValue); + GLEE_EXTERN GLEEPFNWGLQUERYPBUFFERARBPROC GLeeFuncPtr_wglQueryPbufferARB; + #define wglQueryPbufferARB GLeeFuncPtr_wglQueryPbufferARB +#endif +#endif + +/* WGL_ARB_render_texture */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#define __GLEE_WGL_ARB_render_texture 1 +/* Constants */ +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#ifndef GLEE_H_DEFINED_wglBindTexImageARB +#define GLEE_H_DEFINED_wglBindTexImageARB + typedef BOOL (APIENTRYP GLEEPFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); + GLEE_EXTERN GLEEPFNWGLBINDTEXIMAGEARBPROC GLeeFuncPtr_wglBindTexImageARB; + #define wglBindTexImageARB GLeeFuncPtr_wglBindTexImageARB +#endif +#ifndef GLEE_H_DEFINED_wglReleaseTexImageARB +#define GLEE_H_DEFINED_wglReleaseTexImageARB + typedef BOOL (APIENTRYP GLEEPFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); + GLEE_EXTERN GLEEPFNWGLRELEASETEXIMAGEARBPROC GLeeFuncPtr_wglReleaseTexImageARB; + #define wglReleaseTexImageARB GLeeFuncPtr_wglReleaseTexImageARB +#endif +#ifndef GLEE_H_DEFINED_wglSetPbufferAttribARB +#define GLEE_H_DEFINED_wglSetPbufferAttribARB + typedef BOOL (APIENTRYP GLEEPFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int * piAttribList); + GLEE_EXTERN GLEEPFNWGLSETPBUFFERATTRIBARBPROC GLeeFuncPtr_wglSetPbufferAttribARB; + #define wglSetPbufferAttribARB GLeeFuncPtr_wglSetPbufferAttribARB +#endif +#endif + +/* WGL_ARB_pixel_format_float */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 +#define __GLEE_WGL_ARB_pixel_format_float 1 +/* Constants */ +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif + +/* WGL_ARB_create_context */ + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 +#define __GLEE_WGL_ARB_create_context 1 +/* Constants */ +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#ifndef GLEE_H_DEFINED_wglCreateContextAttribsARB +#define GLEE_H_DEFINED_wglCreateContextAttribsARB + typedef HGLRC (APIENTRYP GLEEPFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int * attribList); + GLEE_EXTERN GLEEPFNWGLCREATECONTEXTATTRIBSARBPROC GLeeFuncPtr_wglCreateContextAttribsARB; + #define wglCreateContextAttribsARB GLeeFuncPtr_wglCreateContextAttribsARB +#endif +#endif + +/* WGL_EXT_make_current_read */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#define __GLEE_WGL_EXT_make_current_read 1 +/* Constants */ +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#ifndef GLEE_H_DEFINED_wglMakeContextCurrentEXT +#define GLEE_H_DEFINED_wglMakeContextCurrentEXT + typedef BOOL (APIENTRYP GLEEPFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + GLEE_EXTERN GLEEPFNWGLMAKECONTEXTCURRENTEXTPROC GLeeFuncPtr_wglMakeContextCurrentEXT; + #define wglMakeContextCurrentEXT GLeeFuncPtr_wglMakeContextCurrentEXT +#endif +#ifndef GLEE_H_DEFINED_wglGetCurrentReadDCEXT +#define GLEE_H_DEFINED_wglGetCurrentReadDCEXT + typedef HDC (APIENTRYP GLEEPFNWGLGETCURRENTREADDCEXTPROC) (); + GLEE_EXTERN GLEEPFNWGLGETCURRENTREADDCEXTPROC GLeeFuncPtr_wglGetCurrentReadDCEXT; + #define wglGetCurrentReadDCEXT GLeeFuncPtr_wglGetCurrentReadDCEXT +#endif +#endif + +/* WGL_EXT_pixel_format */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#define __GLEE_WGL_EXT_pixel_format 1 +/* Constants */ +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#ifndef GLEE_H_DEFINED_wglGetPixelFormatAttribivEXT +#define GLEE_H_DEFINED_wglGetPixelFormatAttribivEXT + typedef BOOL (APIENTRYP GLEEPFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int * piAttributes, int * piValues); + GLEE_EXTERN GLEEPFNWGLGETPIXELFORMATATTRIBIVEXTPROC GLeeFuncPtr_wglGetPixelFormatAttribivEXT; + #define wglGetPixelFormatAttribivEXT GLeeFuncPtr_wglGetPixelFormatAttribivEXT +#endif +#ifndef GLEE_H_DEFINED_wglGetPixelFormatAttribfvEXT +#define GLEE_H_DEFINED_wglGetPixelFormatAttribfvEXT + typedef BOOL (APIENTRYP GLEEPFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int * piAttributes, FLOAT * pfValues); + GLEE_EXTERN GLEEPFNWGLGETPIXELFORMATATTRIBFVEXTPROC GLeeFuncPtr_wglGetPixelFormatAttribfvEXT; + #define wglGetPixelFormatAttribfvEXT GLeeFuncPtr_wglGetPixelFormatAttribfvEXT +#endif +#ifndef GLEE_H_DEFINED_wglChoosePixelFormatEXT +#define GLEE_H_DEFINED_wglChoosePixelFormatEXT + typedef BOOL (APIENTRYP GLEEPFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int * piAttribIList, const FLOAT * pfAttribFList, UINT nMaxFormats, int * piFormats, UINT * nNumFormats); + GLEE_EXTERN GLEEPFNWGLCHOOSEPIXELFORMATEXTPROC GLeeFuncPtr_wglChoosePixelFormatEXT; + #define wglChoosePixelFormatEXT GLeeFuncPtr_wglChoosePixelFormatEXT +#endif +#endif + +/* WGL_EXT_pbuffer */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +#define __GLEE_WGL_EXT_pbuffer 1 +/* Constants */ +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#ifndef GLEE_H_DEFINED_wglCreatePbufferEXT +#define GLEE_H_DEFINED_wglCreatePbufferEXT + typedef HPBUFFEREXT (APIENTRYP GLEEPFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int * piAttribList); + GLEE_EXTERN GLEEPFNWGLCREATEPBUFFEREXTPROC GLeeFuncPtr_wglCreatePbufferEXT; + #define wglCreatePbufferEXT GLeeFuncPtr_wglCreatePbufferEXT +#endif +#ifndef GLEE_H_DEFINED_wglGetPbufferDCEXT +#define GLEE_H_DEFINED_wglGetPbufferDCEXT + typedef HDC (APIENTRYP GLEEPFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); + GLEE_EXTERN GLEEPFNWGLGETPBUFFERDCEXTPROC GLeeFuncPtr_wglGetPbufferDCEXT; + #define wglGetPbufferDCEXT GLeeFuncPtr_wglGetPbufferDCEXT +#endif +#ifndef GLEE_H_DEFINED_wglReleasePbufferDCEXT +#define GLEE_H_DEFINED_wglReleasePbufferDCEXT + typedef int (APIENTRYP GLEEPFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); + GLEE_EXTERN GLEEPFNWGLRELEASEPBUFFERDCEXTPROC GLeeFuncPtr_wglReleasePbufferDCEXT; + #define wglReleasePbufferDCEXT GLeeFuncPtr_wglReleasePbufferDCEXT +#endif +#ifndef GLEE_H_DEFINED_wglDestroyPbufferEXT +#define GLEE_H_DEFINED_wglDestroyPbufferEXT + typedef BOOL (APIENTRYP GLEEPFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); + GLEE_EXTERN GLEEPFNWGLDESTROYPBUFFEREXTPROC GLeeFuncPtr_wglDestroyPbufferEXT; + #define wglDestroyPbufferEXT GLeeFuncPtr_wglDestroyPbufferEXT +#endif +#ifndef GLEE_H_DEFINED_wglQueryPbufferEXT +#define GLEE_H_DEFINED_wglQueryPbufferEXT + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int * piValue); + GLEE_EXTERN GLEEPFNWGLQUERYPBUFFEREXTPROC GLeeFuncPtr_wglQueryPbufferEXT; + #define wglQueryPbufferEXT GLeeFuncPtr_wglQueryPbufferEXT +#endif +#endif + +/* WGL_EXT_depth_float */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#define __GLEE_WGL_EXT_depth_float 1 +/* Constants */ +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +/* WGL_3DFX_multisample */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#define __GLEE_WGL_3DFX_multisample 1 +/* Constants */ +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +/* WGL_EXT_multisample */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#define __GLEE_WGL_EXT_multisample 1 +/* Constants */ +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +/* WGL_I3D_digital_video_control */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#define __GLEE_WGL_I3D_digital_video_control 1 +/* Constants */ +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#ifndef GLEE_H_DEFINED_wglGetDigitalVideoParametersI3D +#define GLEE_H_DEFINED_wglGetDigitalVideoParametersI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int * piValue); + GLEE_EXTERN GLEEPFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC GLeeFuncPtr_wglGetDigitalVideoParametersI3D; + #define wglGetDigitalVideoParametersI3D GLeeFuncPtr_wglGetDigitalVideoParametersI3D +#endif +#ifndef GLEE_H_DEFINED_wglSetDigitalVideoParametersI3D +#define GLEE_H_DEFINED_wglSetDigitalVideoParametersI3D + typedef BOOL (APIENTRYP GLEEPFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int * piValue); + GLEE_EXTERN GLEEPFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC GLeeFuncPtr_wglSetDigitalVideoParametersI3D; + #define wglSetDigitalVideoParametersI3D GLeeFuncPtr_wglSetDigitalVideoParametersI3D +#endif +#endif + +/* WGL_I3D_gamma */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#define __GLEE_WGL_I3D_gamma 1 +/* Constants */ +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#ifndef GLEE_H_DEFINED_wglGetGammaTableParametersI3D +#define GLEE_H_DEFINED_wglGetGammaTableParametersI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int * piValue); + GLEE_EXTERN GLEEPFNWGLGETGAMMATABLEPARAMETERSI3DPROC GLeeFuncPtr_wglGetGammaTableParametersI3D; + #define wglGetGammaTableParametersI3D GLeeFuncPtr_wglGetGammaTableParametersI3D +#endif +#ifndef GLEE_H_DEFINED_wglSetGammaTableParametersI3D +#define GLEE_H_DEFINED_wglSetGammaTableParametersI3D + typedef BOOL (APIENTRYP GLEEPFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int * piValue); + GLEE_EXTERN GLEEPFNWGLSETGAMMATABLEPARAMETERSI3DPROC GLeeFuncPtr_wglSetGammaTableParametersI3D; + #define wglSetGammaTableParametersI3D GLeeFuncPtr_wglSetGammaTableParametersI3D +#endif +#ifndef GLEE_H_DEFINED_wglGetGammaTableI3D +#define GLEE_H_DEFINED_wglGetGammaTableI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT * puRed, USHORT * puGreen, USHORT * puBlue); + GLEE_EXTERN GLEEPFNWGLGETGAMMATABLEI3DPROC GLeeFuncPtr_wglGetGammaTableI3D; + #define wglGetGammaTableI3D GLeeFuncPtr_wglGetGammaTableI3D +#endif +#ifndef GLEE_H_DEFINED_wglSetGammaTableI3D +#define GLEE_H_DEFINED_wglSetGammaTableI3D + typedef BOOL (APIENTRYP GLEEPFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT * puRed, const USHORT * puGreen, const USHORT * puBlue); + GLEE_EXTERN GLEEPFNWGLSETGAMMATABLEI3DPROC GLeeFuncPtr_wglSetGammaTableI3D; + #define wglSetGammaTableI3D GLeeFuncPtr_wglSetGammaTableI3D +#endif +#endif + +/* WGL_I3D_genlock */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#define __GLEE_WGL_I3D_genlock 1 +/* Constants */ +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#ifndef GLEE_H_DEFINED_wglEnableGenlockI3D +#define GLEE_H_DEFINED_wglEnableGenlockI3D + typedef BOOL (APIENTRYP GLEEPFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); + GLEE_EXTERN GLEEPFNWGLENABLEGENLOCKI3DPROC GLeeFuncPtr_wglEnableGenlockI3D; + #define wglEnableGenlockI3D GLeeFuncPtr_wglEnableGenlockI3D +#endif +#ifndef GLEE_H_DEFINED_wglDisableGenlockI3D +#define GLEE_H_DEFINED_wglDisableGenlockI3D + typedef BOOL (APIENTRYP GLEEPFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); + GLEE_EXTERN GLEEPFNWGLDISABLEGENLOCKI3DPROC GLeeFuncPtr_wglDisableGenlockI3D; + #define wglDisableGenlockI3D GLeeFuncPtr_wglDisableGenlockI3D +#endif +#ifndef GLEE_H_DEFINED_wglIsEnabledGenlockI3D +#define GLEE_H_DEFINED_wglIsEnabledGenlockI3D + typedef BOOL (APIENTRYP GLEEPFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL * pFlag); + GLEE_EXTERN GLEEPFNWGLISENABLEDGENLOCKI3DPROC GLeeFuncPtr_wglIsEnabledGenlockI3D; + #define wglIsEnabledGenlockI3D GLeeFuncPtr_wglIsEnabledGenlockI3D +#endif +#ifndef GLEE_H_DEFINED_wglGenlockSourceI3D +#define GLEE_H_DEFINED_wglGenlockSourceI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); + GLEE_EXTERN GLEEPFNWGLGENLOCKSOURCEI3DPROC GLeeFuncPtr_wglGenlockSourceI3D; + #define wglGenlockSourceI3D GLeeFuncPtr_wglGenlockSourceI3D +#endif +#ifndef GLEE_H_DEFINED_wglGetGenlockSourceI3D +#define GLEE_H_DEFINED_wglGetGenlockSourceI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT * uSource); + GLEE_EXTERN GLEEPFNWGLGETGENLOCKSOURCEI3DPROC GLeeFuncPtr_wglGetGenlockSourceI3D; + #define wglGetGenlockSourceI3D GLeeFuncPtr_wglGetGenlockSourceI3D +#endif +#ifndef GLEE_H_DEFINED_wglGenlockSourceEdgeI3D +#define GLEE_H_DEFINED_wglGenlockSourceEdgeI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); + GLEE_EXTERN GLEEPFNWGLGENLOCKSOURCEEDGEI3DPROC GLeeFuncPtr_wglGenlockSourceEdgeI3D; + #define wglGenlockSourceEdgeI3D GLeeFuncPtr_wglGenlockSourceEdgeI3D +#endif +#ifndef GLEE_H_DEFINED_wglGetGenlockSourceEdgeI3D +#define GLEE_H_DEFINED_wglGetGenlockSourceEdgeI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT * uEdge); + GLEE_EXTERN GLEEPFNWGLGETGENLOCKSOURCEEDGEI3DPROC GLeeFuncPtr_wglGetGenlockSourceEdgeI3D; + #define wglGetGenlockSourceEdgeI3D GLeeFuncPtr_wglGetGenlockSourceEdgeI3D +#endif +#ifndef GLEE_H_DEFINED_wglGenlockSampleRateI3D +#define GLEE_H_DEFINED_wglGenlockSampleRateI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); + GLEE_EXTERN GLEEPFNWGLGENLOCKSAMPLERATEI3DPROC GLeeFuncPtr_wglGenlockSampleRateI3D; + #define wglGenlockSampleRateI3D GLeeFuncPtr_wglGenlockSampleRateI3D +#endif +#ifndef GLEE_H_DEFINED_wglGetGenlockSampleRateI3D +#define GLEE_H_DEFINED_wglGetGenlockSampleRateI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT * uRate); + GLEE_EXTERN GLEEPFNWGLGETGENLOCKSAMPLERATEI3DPROC GLeeFuncPtr_wglGetGenlockSampleRateI3D; + #define wglGetGenlockSampleRateI3D GLeeFuncPtr_wglGetGenlockSampleRateI3D +#endif +#ifndef GLEE_H_DEFINED_wglGenlockSourceDelayI3D +#define GLEE_H_DEFINED_wglGenlockSourceDelayI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); + GLEE_EXTERN GLEEPFNWGLGENLOCKSOURCEDELAYI3DPROC GLeeFuncPtr_wglGenlockSourceDelayI3D; + #define wglGenlockSourceDelayI3D GLeeFuncPtr_wglGenlockSourceDelayI3D +#endif +#ifndef GLEE_H_DEFINED_wglGetGenlockSourceDelayI3D +#define GLEE_H_DEFINED_wglGetGenlockSourceDelayI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT * uDelay); + GLEE_EXTERN GLEEPFNWGLGETGENLOCKSOURCEDELAYI3DPROC GLeeFuncPtr_wglGetGenlockSourceDelayI3D; + #define wglGetGenlockSourceDelayI3D GLeeFuncPtr_wglGetGenlockSourceDelayI3D +#endif +#ifndef GLEE_H_DEFINED_wglQueryGenlockMaxSourceDelayI3D +#define GLEE_H_DEFINED_wglQueryGenlockMaxSourceDelayI3D + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT * uMaxLineDelay, UINT * uMaxPixelDelay); + GLEE_EXTERN GLEEPFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC GLeeFuncPtr_wglQueryGenlockMaxSourceDelayI3D; + #define wglQueryGenlockMaxSourceDelayI3D GLeeFuncPtr_wglQueryGenlockMaxSourceDelayI3D +#endif +#endif + +/* WGL_I3D_image_buffer */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#define __GLEE_WGL_I3D_image_buffer 1 +/* Constants */ +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#ifndef GLEE_H_DEFINED_wglCreateImageBufferI3D +#define GLEE_H_DEFINED_wglCreateImageBufferI3D + typedef LPVOID (APIENTRYP GLEEPFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); + GLEE_EXTERN GLEEPFNWGLCREATEIMAGEBUFFERI3DPROC GLeeFuncPtr_wglCreateImageBufferI3D; + #define wglCreateImageBufferI3D GLeeFuncPtr_wglCreateImageBufferI3D +#endif +#ifndef GLEE_H_DEFINED_wglDestroyImageBufferI3D +#define GLEE_H_DEFINED_wglDestroyImageBufferI3D + typedef BOOL (APIENTRYP GLEEPFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); + GLEE_EXTERN GLEEPFNWGLDESTROYIMAGEBUFFERI3DPROC GLeeFuncPtr_wglDestroyImageBufferI3D; + #define wglDestroyImageBufferI3D GLeeFuncPtr_wglDestroyImageBufferI3D +#endif +#ifndef GLEE_H_DEFINED_wglAssociateImageBufferEventsI3D +#define GLEE_H_DEFINED_wglAssociateImageBufferEventsI3D + typedef BOOL (APIENTRYP GLEEPFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE * pEvent, const LPVOID * pAddress, const DWORD * pSize, UINT count); + GLEE_EXTERN GLEEPFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC GLeeFuncPtr_wglAssociateImageBufferEventsI3D; + #define wglAssociateImageBufferEventsI3D GLeeFuncPtr_wglAssociateImageBufferEventsI3D +#endif +#ifndef GLEE_H_DEFINED_wglReleaseImageBufferEventsI3D +#define GLEE_H_DEFINED_wglReleaseImageBufferEventsI3D + typedef BOOL (APIENTRYP GLEEPFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID * pAddress, UINT count); + GLEE_EXTERN GLEEPFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC GLeeFuncPtr_wglReleaseImageBufferEventsI3D; + #define wglReleaseImageBufferEventsI3D GLeeFuncPtr_wglReleaseImageBufferEventsI3D +#endif +#endif + +/* WGL_I3D_swap_frame_lock */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +#define __GLEE_WGL_I3D_swap_frame_lock 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglEnableFrameLockI3D +#define GLEE_H_DEFINED_wglEnableFrameLockI3D + typedef BOOL (APIENTRYP GLEEPFNWGLENABLEFRAMELOCKI3DPROC) (); + GLEE_EXTERN GLEEPFNWGLENABLEFRAMELOCKI3DPROC GLeeFuncPtr_wglEnableFrameLockI3D; + #define wglEnableFrameLockI3D GLeeFuncPtr_wglEnableFrameLockI3D +#endif +#ifndef GLEE_H_DEFINED_wglDisableFrameLockI3D +#define GLEE_H_DEFINED_wglDisableFrameLockI3D + typedef BOOL (APIENTRYP GLEEPFNWGLDISABLEFRAMELOCKI3DPROC) (); + GLEE_EXTERN GLEEPFNWGLDISABLEFRAMELOCKI3DPROC GLeeFuncPtr_wglDisableFrameLockI3D; + #define wglDisableFrameLockI3D GLeeFuncPtr_wglDisableFrameLockI3D +#endif +#ifndef GLEE_H_DEFINED_wglIsEnabledFrameLockI3D +#define GLEE_H_DEFINED_wglIsEnabledFrameLockI3D + typedef BOOL (APIENTRYP GLEEPFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL * pFlag); + GLEE_EXTERN GLEEPFNWGLISENABLEDFRAMELOCKI3DPROC GLeeFuncPtr_wglIsEnabledFrameLockI3D; + #define wglIsEnabledFrameLockI3D GLeeFuncPtr_wglIsEnabledFrameLockI3D +#endif +#ifndef GLEE_H_DEFINED_wglQueryFrameLockMasterI3D +#define GLEE_H_DEFINED_wglQueryFrameLockMasterI3D + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL * pFlag); + GLEE_EXTERN GLEEPFNWGLQUERYFRAMELOCKMASTERI3DPROC GLeeFuncPtr_wglQueryFrameLockMasterI3D; + #define wglQueryFrameLockMasterI3D GLeeFuncPtr_wglQueryFrameLockMasterI3D +#endif +#endif + +/* WGL_NV_render_depth_texture */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 +#define __GLEE_WGL_NV_render_depth_texture 1 +/* Constants */ +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +/* WGL_NV_render_texture_rectangle */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 +#define __GLEE_WGL_NV_render_texture_rectangle 1 +/* Constants */ +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +/* WGL_ATI_pixel_format_float */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 +#define __GLEE_WGL_ATI_pixel_format_float 1 +/* Constants */ +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#endif + +/* WGL_NV_float_buffer */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 +#define __GLEE_WGL_NV_float_buffer 1 +/* Constants */ +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + +/* WGL_3DL_stereo_control */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 +#define __GLEE_WGL_3DL_stereo_control 1 +/* Constants */ +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 +#endif + +/* WGL_EXT_pixel_format_packed_float */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 +#define __GLEE_WGL_EXT_pixel_format_packed_float 1 +/* Constants */ +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 +#endif + +/* WGL_EXT_framebuffer_sRGB */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 +#define __GLEE_WGL_EXT_framebuffer_sRGB 1 +/* Constants */ +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 +#endif + +/* WGL_NV_present_video */ + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 +#define __GLEE_WGL_NV_present_video 1 +/* Constants */ +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 +#ifndef GLEE_H_DEFINED_wglEnumerateVideoDevicesNV +#define GLEE_H_DEFINED_wglEnumerateVideoDevicesNV + typedef int (APIENTRYP GLEEPFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV * phDeviceList); + GLEE_EXTERN GLEEPFNWGLENUMERATEVIDEODEVICESNVPROC GLeeFuncPtr_wglEnumerateVideoDevicesNV; + #define wglEnumerateVideoDevicesNV GLeeFuncPtr_wglEnumerateVideoDevicesNV +#endif +#ifndef GLEE_H_DEFINED_wglBindVideoDeviceNV +#define GLEE_H_DEFINED_wglBindVideoDeviceNV + typedef BOOL (APIENTRYP GLEEPFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int * piAttribList); + GLEE_EXTERN GLEEPFNWGLBINDVIDEODEVICENVPROC GLeeFuncPtr_wglBindVideoDeviceNV; + #define wglBindVideoDeviceNV GLeeFuncPtr_wglBindVideoDeviceNV +#endif +#ifndef GLEE_H_DEFINED_wglQueryCurrentContextNV +#define GLEE_H_DEFINED_wglQueryCurrentContextNV + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int * piValue); + GLEE_EXTERN GLEEPFNWGLQUERYCURRENTCONTEXTNVPROC GLeeFuncPtr_wglQueryCurrentContextNV; + #define wglQueryCurrentContextNV GLeeFuncPtr_wglQueryCurrentContextNV +#endif +#endif + +/* WGL_NV_swap_group */ + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 +#define __GLEE_WGL_NV_swap_group 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglJoinSwapGroupNV +#define GLEE_H_DEFINED_wglJoinSwapGroupNV + typedef BOOL (APIENTRYP GLEEPFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); + GLEE_EXTERN GLEEPFNWGLJOINSWAPGROUPNVPROC GLeeFuncPtr_wglJoinSwapGroupNV; + #define wglJoinSwapGroupNV GLeeFuncPtr_wglJoinSwapGroupNV +#endif +#ifndef GLEE_H_DEFINED_wglBindSwapBarrierNV +#define GLEE_H_DEFINED_wglBindSwapBarrierNV + typedef BOOL (APIENTRYP GLEEPFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); + GLEE_EXTERN GLEEPFNWGLBINDSWAPBARRIERNVPROC GLeeFuncPtr_wglBindSwapBarrierNV; + #define wglBindSwapBarrierNV GLeeFuncPtr_wglBindSwapBarrierNV +#endif +#ifndef GLEE_H_DEFINED_wglQuerySwapGroupNV +#define GLEE_H_DEFINED_wglQuerySwapGroupNV + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint * group, GLuint * barrier); + GLEE_EXTERN GLEEPFNWGLQUERYSWAPGROUPNVPROC GLeeFuncPtr_wglQuerySwapGroupNV; + #define wglQuerySwapGroupNV GLeeFuncPtr_wglQuerySwapGroupNV +#endif +#ifndef GLEE_H_DEFINED_wglQueryMaxSwapGroupsNV +#define GLEE_H_DEFINED_wglQueryMaxSwapGroupsNV + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint * maxGroups, GLuint * maxBarriers); + GLEE_EXTERN GLEEPFNWGLQUERYMAXSWAPGROUPSNVPROC GLeeFuncPtr_wglQueryMaxSwapGroupsNV; + #define wglQueryMaxSwapGroupsNV GLeeFuncPtr_wglQueryMaxSwapGroupsNV +#endif +#ifndef GLEE_H_DEFINED_wglQueryFrameCountNV +#define GLEE_H_DEFINED_wglQueryFrameCountNV + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint * count); + GLEE_EXTERN GLEEPFNWGLQUERYFRAMECOUNTNVPROC GLeeFuncPtr_wglQueryFrameCountNV; + #define wglQueryFrameCountNV GLeeFuncPtr_wglQueryFrameCountNV +#endif +#ifndef GLEE_H_DEFINED_wglResetFrameCountNV +#define GLEE_H_DEFINED_wglResetFrameCountNV + typedef BOOL (APIENTRYP GLEEPFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); + GLEE_EXTERN GLEEPFNWGLRESETFRAMECOUNTNVPROC GLeeFuncPtr_wglResetFrameCountNV; + #define wglResetFrameCountNV GLeeFuncPtr_wglResetFrameCountNV +#endif +#endif + +/* WGL_NV_gpu_affinity */ + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 +#define __GLEE_WGL_NV_gpu_affinity 1 +/* Constants */ +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 +#ifndef GLEE_H_DEFINED_wglEnumGpusNV +#define GLEE_H_DEFINED_wglEnumGpusNV + typedef BOOL (APIENTRYP GLEEPFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV * phGpu); + GLEE_EXTERN GLEEPFNWGLENUMGPUSNVPROC GLeeFuncPtr_wglEnumGpusNV; + #define wglEnumGpusNV GLeeFuncPtr_wglEnumGpusNV +#endif +#ifndef GLEE_H_DEFINED_wglEnumGpuDevicesNV +#define GLEE_H_DEFINED_wglEnumGpuDevicesNV + typedef BOOL (APIENTRYP GLEEPFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); + GLEE_EXTERN GLEEPFNWGLENUMGPUDEVICESNVPROC GLeeFuncPtr_wglEnumGpuDevicesNV; + #define wglEnumGpuDevicesNV GLeeFuncPtr_wglEnumGpuDevicesNV +#endif +#ifndef GLEE_H_DEFINED_wglCreateAffinityDCNV +#define GLEE_H_DEFINED_wglCreateAffinityDCNV + typedef HDC (APIENTRYP GLEEPFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV * phGpuList); + GLEE_EXTERN GLEEPFNWGLCREATEAFFINITYDCNVPROC GLeeFuncPtr_wglCreateAffinityDCNV; + #define wglCreateAffinityDCNV GLeeFuncPtr_wglCreateAffinityDCNV +#endif +#ifndef GLEE_H_DEFINED_wglEnumGpusFromAffinityDCNV +#define GLEE_H_DEFINED_wglEnumGpusFromAffinityDCNV + typedef BOOL (APIENTRYP GLEEPFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV * hGpu); + GLEE_EXTERN GLEEPFNWGLENUMGPUSFROMAFFINITYDCNVPROC GLeeFuncPtr_wglEnumGpusFromAffinityDCNV; + #define wglEnumGpusFromAffinityDCNV GLeeFuncPtr_wglEnumGpusFromAffinityDCNV +#endif +#ifndef GLEE_H_DEFINED_wglDeleteDCNV +#define GLEE_H_DEFINED_wglDeleteDCNV + typedef BOOL (APIENTRYP GLEEPFNWGLDELETEDCNVPROC) (HDC hdc); + GLEE_EXTERN GLEEPFNWGLDELETEDCNVPROC GLeeFuncPtr_wglDeleteDCNV; + #define wglDeleteDCNV GLeeFuncPtr_wglDeleteDCNV +#endif +#endif + +/* WGL_EXT_display_color_table */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +#define __GLEE_WGL_EXT_display_color_table 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglCreateDisplayColorTableEXT +#define GLEE_H_DEFINED_wglCreateDisplayColorTableEXT + typedef GLboolean (APIENTRYP GLEEPFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); + GLEE_EXTERN GLEEPFNWGLCREATEDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglCreateDisplayColorTableEXT; + #define wglCreateDisplayColorTableEXT GLeeFuncPtr_wglCreateDisplayColorTableEXT +#endif +#ifndef GLEE_H_DEFINED_wglLoadDisplayColorTableEXT +#define GLEE_H_DEFINED_wglLoadDisplayColorTableEXT + typedef GLboolean (APIENTRYP GLEEPFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort * table, GLuint length); + GLEE_EXTERN GLEEPFNWGLLOADDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglLoadDisplayColorTableEXT; + #define wglLoadDisplayColorTableEXT GLeeFuncPtr_wglLoadDisplayColorTableEXT +#endif +#ifndef GLEE_H_DEFINED_wglBindDisplayColorTableEXT +#define GLEE_H_DEFINED_wglBindDisplayColorTableEXT + typedef GLboolean (APIENTRYP GLEEPFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); + GLEE_EXTERN GLEEPFNWGLBINDDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglBindDisplayColorTableEXT; + #define wglBindDisplayColorTableEXT GLeeFuncPtr_wglBindDisplayColorTableEXT +#endif +#ifndef GLEE_H_DEFINED_wglDestroyDisplayColorTableEXT +#define GLEE_H_DEFINED_wglDestroyDisplayColorTableEXT + typedef VOID (APIENTRYP GLEEPFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); + GLEE_EXTERN GLEEPFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC GLeeFuncPtr_wglDestroyDisplayColorTableEXT; + #define wglDestroyDisplayColorTableEXT GLeeFuncPtr_wglDestroyDisplayColorTableEXT +#endif +#endif + +/* WGL_EXT_extensions_string */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +#define __GLEE_WGL_EXT_extensions_string 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglGetExtensionsStringEXT +#define GLEE_H_DEFINED_wglGetExtensionsStringEXT + typedef const char * (APIENTRYP GLEEPFNWGLGETEXTENSIONSSTRINGEXTPROC) (); + GLEE_EXTERN GLEEPFNWGLGETEXTENSIONSSTRINGEXTPROC GLeeFuncPtr_wglGetExtensionsStringEXT; + #define wglGetExtensionsStringEXT GLeeFuncPtr_wglGetExtensionsStringEXT +#endif +#endif + +/* WGL_EXT_swap_control */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +#define __GLEE_WGL_EXT_swap_control 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglSwapIntervalEXT +#define GLEE_H_DEFINED_wglSwapIntervalEXT + typedef BOOL (APIENTRYP GLEEPFNWGLSWAPINTERVALEXTPROC) (int interval); + GLEE_EXTERN GLEEPFNWGLSWAPINTERVALEXTPROC GLeeFuncPtr_wglSwapIntervalEXT; + #define wglSwapIntervalEXT GLeeFuncPtr_wglSwapIntervalEXT +#endif +#ifndef GLEE_H_DEFINED_wglGetSwapIntervalEXT +#define GLEE_H_DEFINED_wglGetSwapIntervalEXT + typedef int (APIENTRYP GLEEPFNWGLGETSWAPINTERVALEXTPROC) (); + GLEE_EXTERN GLEEPFNWGLGETSWAPINTERVALEXTPROC GLeeFuncPtr_wglGetSwapIntervalEXT; + #define wglGetSwapIntervalEXT GLeeFuncPtr_wglGetSwapIntervalEXT +#endif +#endif + +/* WGL_NV_vertex_array_range */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +#define __GLEE_WGL_NV_vertex_array_range 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglAllocateMemoryNV +#define GLEE_H_DEFINED_wglAllocateMemoryNV + typedef void* (APIENTRYP GLEEPFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); + GLEE_EXTERN GLEEPFNWGLALLOCATEMEMORYNVPROC GLeeFuncPtr_wglAllocateMemoryNV; + #define wglAllocateMemoryNV GLeeFuncPtr_wglAllocateMemoryNV +#endif +#ifndef GLEE_H_DEFINED_wglFreeMemoryNV +#define GLEE_H_DEFINED_wglFreeMemoryNV + typedef void (APIENTRYP GLEEPFNWGLFREEMEMORYNVPROC) (void * pointer); + GLEE_EXTERN GLEEPFNWGLFREEMEMORYNVPROC GLeeFuncPtr_wglFreeMemoryNV; + #define wglFreeMemoryNV GLeeFuncPtr_wglFreeMemoryNV +#endif +#endif + +/* WGL_OML_sync_control */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +#define __GLEE_WGL_OML_sync_control 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglGetSyncValuesOML +#define GLEE_H_DEFINED_wglGetSyncValuesOML + typedef BOOL (APIENTRYP GLEEPFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 * ust, INT64 * msc, INT64 * sbc); + GLEE_EXTERN GLEEPFNWGLGETSYNCVALUESOMLPROC GLeeFuncPtr_wglGetSyncValuesOML; + #define wglGetSyncValuesOML GLeeFuncPtr_wglGetSyncValuesOML +#endif +#ifndef GLEE_H_DEFINED_wglGetMscRateOML +#define GLEE_H_DEFINED_wglGetMscRateOML + typedef BOOL (APIENTRYP GLEEPFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 * numerator, INT32 * denominator); + GLEE_EXTERN GLEEPFNWGLGETMSCRATEOMLPROC GLeeFuncPtr_wglGetMscRateOML; + #define wglGetMscRateOML GLeeFuncPtr_wglGetMscRateOML +#endif +#ifndef GLEE_H_DEFINED_wglSwapBuffersMscOML +#define GLEE_H_DEFINED_wglSwapBuffersMscOML + typedef INT64 (APIENTRYP GLEEPFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); + GLEE_EXTERN GLEEPFNWGLSWAPBUFFERSMSCOMLPROC GLeeFuncPtr_wglSwapBuffersMscOML; + #define wglSwapBuffersMscOML GLeeFuncPtr_wglSwapBuffersMscOML +#endif +#ifndef GLEE_H_DEFINED_wglSwapLayerBuffersMscOML +#define GLEE_H_DEFINED_wglSwapLayerBuffersMscOML + typedef INT64 (APIENTRYP GLEEPFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); + GLEE_EXTERN GLEEPFNWGLSWAPLAYERBUFFERSMSCOMLPROC GLeeFuncPtr_wglSwapLayerBuffersMscOML; + #define wglSwapLayerBuffersMscOML GLeeFuncPtr_wglSwapLayerBuffersMscOML +#endif +#ifndef GLEE_H_DEFINED_wglWaitForMscOML +#define GLEE_H_DEFINED_wglWaitForMscOML + typedef BOOL (APIENTRYP GLEEPFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 * ust, INT64 * msc, INT64 * sbc); + GLEE_EXTERN GLEEPFNWGLWAITFORMSCOMLPROC GLeeFuncPtr_wglWaitForMscOML; + #define wglWaitForMscOML GLeeFuncPtr_wglWaitForMscOML +#endif +#ifndef GLEE_H_DEFINED_wglWaitForSbcOML +#define GLEE_H_DEFINED_wglWaitForSbcOML + typedef BOOL (APIENTRYP GLEEPFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 * ust, INT64 * msc, INT64 * sbc); + GLEE_EXTERN GLEEPFNWGLWAITFORSBCOMLPROC GLeeFuncPtr_wglWaitForSbcOML; + #define wglWaitForSbcOML GLeeFuncPtr_wglWaitForSbcOML +#endif +#endif + +/* WGL_I3D_swap_frame_usage */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +#define __GLEE_WGL_I3D_swap_frame_usage 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_wglGetFrameUsageI3D +#define GLEE_H_DEFINED_wglGetFrameUsageI3D + typedef BOOL (APIENTRYP GLEEPFNWGLGETFRAMEUSAGEI3DPROC) (float * pUsage); + GLEE_EXTERN GLEEPFNWGLGETFRAMEUSAGEI3DPROC GLeeFuncPtr_wglGetFrameUsageI3D; + #define wglGetFrameUsageI3D GLeeFuncPtr_wglGetFrameUsageI3D +#endif +#ifndef GLEE_H_DEFINED_wglBeginFrameTrackingI3D +#define GLEE_H_DEFINED_wglBeginFrameTrackingI3D + typedef BOOL (APIENTRYP GLEEPFNWGLBEGINFRAMETRACKINGI3DPROC) (); + GLEE_EXTERN GLEEPFNWGLBEGINFRAMETRACKINGI3DPROC GLeeFuncPtr_wglBeginFrameTrackingI3D; + #define wglBeginFrameTrackingI3D GLeeFuncPtr_wglBeginFrameTrackingI3D +#endif +#ifndef GLEE_H_DEFINED_wglEndFrameTrackingI3D +#define GLEE_H_DEFINED_wglEndFrameTrackingI3D + typedef BOOL (APIENTRYP GLEEPFNWGLENDFRAMETRACKINGI3DPROC) (); + GLEE_EXTERN GLEEPFNWGLENDFRAMETRACKINGI3DPROC GLeeFuncPtr_wglEndFrameTrackingI3D; + #define wglEndFrameTrackingI3D GLeeFuncPtr_wglEndFrameTrackingI3D +#endif +#ifndef GLEE_H_DEFINED_wglQueryFrameTrackingI3D +#define GLEE_H_DEFINED_wglQueryFrameTrackingI3D + typedef BOOL (APIENTRYP GLEEPFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD * pFrameCount, DWORD * pMissedFrames, float * pLastMissedUsage); + GLEE_EXTERN GLEEPFNWGLQUERYFRAMETRACKINGI3DPROC GLeeFuncPtr_wglQueryFrameTrackingI3D; + #define wglQueryFrameTrackingI3D GLeeFuncPtr_wglQueryFrameTrackingI3D +#endif +#endif + +/* WGL_NV_video_output */ + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 +#define __GLEE_WGL_NV_video_output 1 +/* Constants */ +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC +#ifndef GLEE_H_DEFINED_wglGetVideoDeviceNV +#define GLEE_H_DEFINED_wglGetVideoDeviceNV + typedef BOOL (APIENTRYP GLEEPFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV * hVideoDevice); + GLEE_EXTERN GLEEPFNWGLGETVIDEODEVICENVPROC GLeeFuncPtr_wglGetVideoDeviceNV; + #define wglGetVideoDeviceNV GLeeFuncPtr_wglGetVideoDeviceNV +#endif +#ifndef GLEE_H_DEFINED_wglReleaseVideoDeviceNV +#define GLEE_H_DEFINED_wglReleaseVideoDeviceNV + typedef BOOL (APIENTRYP GLEEPFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); + GLEE_EXTERN GLEEPFNWGLRELEASEVIDEODEVICENVPROC GLeeFuncPtr_wglReleaseVideoDeviceNV; + #define wglReleaseVideoDeviceNV GLeeFuncPtr_wglReleaseVideoDeviceNV +#endif +#ifndef GLEE_H_DEFINED_wglBindVideoImageNV +#define GLEE_H_DEFINED_wglBindVideoImageNV + typedef BOOL (APIENTRYP GLEEPFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); + GLEE_EXTERN GLEEPFNWGLBINDVIDEOIMAGENVPROC GLeeFuncPtr_wglBindVideoImageNV; + #define wglBindVideoImageNV GLeeFuncPtr_wglBindVideoImageNV +#endif +#ifndef GLEE_H_DEFINED_wglReleaseVideoImageNV +#define GLEE_H_DEFINED_wglReleaseVideoImageNV + typedef BOOL (APIENTRYP GLEEPFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); + GLEE_EXTERN GLEEPFNWGLRELEASEVIDEOIMAGENVPROC GLeeFuncPtr_wglReleaseVideoImageNV; + #define wglReleaseVideoImageNV GLeeFuncPtr_wglReleaseVideoImageNV +#endif +#ifndef GLEE_H_DEFINED_wglSendPbufferToVideoNV +#define GLEE_H_DEFINED_wglSendPbufferToVideoNV + typedef BOOL (APIENTRYP GLEEPFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long * pulCounterPbuffer, BOOL bBlock); + GLEE_EXTERN GLEEPFNWGLSENDPBUFFERTOVIDEONVPROC GLeeFuncPtr_wglSendPbufferToVideoNV; + #define wglSendPbufferToVideoNV GLeeFuncPtr_wglSendPbufferToVideoNV +#endif +#ifndef GLEE_H_DEFINED_wglGetVideoInfoNV +#define GLEE_H_DEFINED_wglGetVideoInfoNV + typedef BOOL (APIENTRYP GLEEPFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long * pulCounterOutputPbuffer, unsigned long * pulCounterOutputVideo); + GLEE_EXTERN GLEEPFNWGLGETVIDEOINFONVPROC GLeeFuncPtr_wglGetVideoInfoNV; + #define wglGetVideoInfoNV GLeeFuncPtr_wglGetVideoInfoNV +#endif +#endif +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else /* GLX */ + +/* Extension querying variables */ + +GLEE_EXTERN GLboolean _GLEE_GLX_VERSION_1_3; +GLEE_EXTERN GLboolean _GLEE_GLX_VERSION_1_4; +GLEE_EXTERN GLboolean _GLEE_GLX_ARB_multisample; +GLEE_EXTERN GLboolean _GLEE_GLX_ARB_fbconfig_float; +GLEE_EXTERN GLboolean _GLEE_GLX_ARB_create_context; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIS_multisample; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_visual_info; +GLEE_EXTERN GLboolean _GLEE_GLX_SGI_swap_control; +GLEE_EXTERN GLboolean _GLEE_GLX_SGI_video_sync; +GLEE_EXTERN GLboolean _GLEE_GLX_SGI_make_current_read; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_visual_rating; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_import_context; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIX_fbconfig; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIX_pbuffer; +GLEE_EXTERN GLboolean _GLEE_GLX_SGI_cushion; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIX_video_resize; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIX_swap_group; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIX_swap_barrier; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIS_blended_overlay; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIS_shared_multisample; +GLEE_EXTERN GLboolean _GLEE_GLX_SUN_get_transparent_index; +GLEE_EXTERN GLboolean _GLEE_GLX_3DFX_multisample; +GLEE_EXTERN GLboolean _GLEE_GLX_MESA_copy_sub_buffer; +GLEE_EXTERN GLboolean _GLEE_GLX_MESA_pixmap_colormap; +GLEE_EXTERN GLboolean _GLEE_GLX_MESA_release_buffers; +GLEE_EXTERN GLboolean _GLEE_GLX_MESA_set_3dfx_mode; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIX_visual_select_group; +GLEE_EXTERN GLboolean _GLEE_GLX_OML_swap_method; +GLEE_EXTERN GLboolean _GLEE_GLX_OML_sync_control; +GLEE_EXTERN GLboolean _GLEE_GLX_NV_float_buffer; +GLEE_EXTERN GLboolean _GLEE_GLX_SGIX_hyperpipe; +GLEE_EXTERN GLboolean _GLEE_GLX_MESA_agp_offset; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_fbconfig_packed_float; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_framebuffer_sRGB; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_texture_from_pixmap; +GLEE_EXTERN GLboolean _GLEE_GLX_NV_present_video; +GLEE_EXTERN GLboolean _GLEE_GLX_NV_video_out; +GLEE_EXTERN GLboolean _GLEE_GLX_NV_swap_group; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; +GLEE_EXTERN GLboolean _GLEE_GLX_NV_video_output; + +/* Aliases for extension querying variables */ + +#define GLEE_GLX_VERSION_1_3 GLeeEnabled(&_GLEE_GLX_VERSION_1_3) +#define GLEE_GLX_VERSION_1_4 GLeeEnabled(&_GLEE_GLX_VERSION_1_4) +#define GLEE_GLX_ARB_multisample GLeeEnabled(&_GLEE_GLX_ARB_multisample) +#define GLEE_GLX_ARB_fbconfig_float GLeeEnabled(&_GLEE_GLX_ARB_fbconfig_float) +#define GLEE_GLX_ARB_create_context GLeeEnabled(&_GLEE_GLX_ARB_create_context) +#define GLEE_GLX_SGIS_multisample GLeeEnabled(&_GLEE_GLX_SGIS_multisample) +#define GLEE_GLX_EXT_visual_info GLeeEnabled(&_GLEE_GLX_EXT_visual_info) +#define GLEE_GLX_SGI_swap_control GLeeEnabled(&_GLEE_GLX_SGI_swap_control) +#define GLEE_GLX_SGI_video_sync GLeeEnabled(&_GLEE_GLX_SGI_video_sync) +#define GLEE_GLX_SGI_make_current_read GLeeEnabled(&_GLEE_GLX_SGI_make_current_read) +#define GLEE_GLX_EXT_visual_rating GLeeEnabled(&_GLEE_GLX_EXT_visual_rating) +#define GLEE_GLX_EXT_import_context GLeeEnabled(&_GLEE_GLX_EXT_import_context) +#define GLEE_GLX_SGIX_fbconfig GLeeEnabled(&_GLEE_GLX_SGIX_fbconfig) +#define GLEE_GLX_SGIX_pbuffer GLeeEnabled(&_GLEE_GLX_SGIX_pbuffer) +#define GLEE_GLX_SGI_cushion GLeeEnabled(&_GLEE_GLX_SGI_cushion) +#define GLEE_GLX_SGIX_video_resize GLeeEnabled(&_GLEE_GLX_SGIX_video_resize) +#define GLEE_GLX_SGIX_swap_group GLeeEnabled(&_GLEE_GLX_SGIX_swap_group) +#define GLEE_GLX_SGIX_swap_barrier GLeeEnabled(&_GLEE_GLX_SGIX_swap_barrier) +#define GLEE_GLX_SGIS_blended_overlay GLeeEnabled(&_GLEE_GLX_SGIS_blended_overlay) +#define GLEE_GLX_SGIS_shared_multisample GLeeEnabled(&_GLEE_GLX_SGIS_shared_multisample) +#define GLEE_GLX_SUN_get_transparent_index GLeeEnabled(&_GLEE_GLX_SUN_get_transparent_index) +#define GLEE_GLX_3DFX_multisample GLeeEnabled(&_GLEE_GLX_3DFX_multisample) +#define GLEE_GLX_MESA_copy_sub_buffer GLeeEnabled(&_GLEE_GLX_MESA_copy_sub_buffer) +#define GLEE_GLX_MESA_pixmap_colormap GLeeEnabled(&_GLEE_GLX_MESA_pixmap_colormap) +#define GLEE_GLX_MESA_release_buffers GLeeEnabled(&_GLEE_GLX_MESA_release_buffers) +#define GLEE_GLX_MESA_set_3dfx_mode GLeeEnabled(&_GLEE_GLX_MESA_set_3dfx_mode) +#define GLEE_GLX_SGIX_visual_select_group GLeeEnabled(&_GLEE_GLX_SGIX_visual_select_group) +#define GLEE_GLX_OML_swap_method GLeeEnabled(&_GLEE_GLX_OML_swap_method) +#define GLEE_GLX_OML_sync_control GLeeEnabled(&_GLEE_GLX_OML_sync_control) +#define GLEE_GLX_NV_float_buffer GLeeEnabled(&_GLEE_GLX_NV_float_buffer) +#define GLEE_GLX_SGIX_hyperpipe GLeeEnabled(&_GLEE_GLX_SGIX_hyperpipe) +#define GLEE_GLX_MESA_agp_offset GLeeEnabled(&_GLEE_GLX_MESA_agp_offset) +#define GLEE_GLX_EXT_fbconfig_packed_float GLeeEnabled(&_GLEE_GLX_EXT_fbconfig_packed_float) +#define GLEE_GLX_EXT_framebuffer_sRGB GLeeEnabled(&_GLEE_GLX_EXT_framebuffer_sRGB) +#define GLEE_GLX_EXT_texture_from_pixmap GLeeEnabled(&_GLEE_GLX_EXT_texture_from_pixmap) +#define GLEE_GLX_NV_present_video GLeeEnabled(&_GLEE_GLX_NV_present_video) +#define GLEE_GLX_NV_video_out GLeeEnabled(&_GLEE_GLX_NV_video_out) +#define GLEE_GLX_NV_swap_group GLeeEnabled(&_GLEE_GLX_NV_swap_group) +#define GLEE_GLX_EXT_scene_marker GLeeEnabled(&_GLEE_GLX_EXT_scene_marker) +#define GLEE_GLX_NV_video_output GLeeEnabled(&_GLEE_GLX_NV_video_output) + +/* GLX_VERSION_1_3 */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 +#define __GLEE_GLX_VERSION_1_3 1 +/* Constants */ +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#ifndef GLEE_H_DEFINED_glXGetFBConfigs +#define GLEE_H_DEFINED_glXGetFBConfigs + typedef GLXFBConfig * (APIENTRYP GLEEPFNGLXGETFBCONFIGSPROC) (Display * dpy, int screen, int * nelements); + GLEE_EXTERN GLEEPFNGLXGETFBCONFIGSPROC GLeeFuncPtr_glXGetFBConfigs; + #define glXGetFBConfigs GLeeFuncPtr_glXGetFBConfigs +#endif +#ifndef GLEE_H_DEFINED_glXChooseFBConfig +#define GLEE_H_DEFINED_glXChooseFBConfig + typedef GLXFBConfig * (APIENTRYP GLEEPFNGLXCHOOSEFBCONFIGPROC) (Display * dpy, int screen, const int * attrib_list, int * nelements); + GLEE_EXTERN GLEEPFNGLXCHOOSEFBCONFIGPROC GLeeFuncPtr_glXChooseFBConfig; + #define glXChooseFBConfig GLeeFuncPtr_glXChooseFBConfig +#endif +#ifndef GLEE_H_DEFINED_glXGetFBConfigAttrib +#define GLEE_H_DEFINED_glXGetFBConfigAttrib + typedef int (APIENTRYP GLEEPFNGLXGETFBCONFIGATTRIBPROC) (Display * dpy, GLXFBConfig config, int attribute, int * value); + GLEE_EXTERN GLEEPFNGLXGETFBCONFIGATTRIBPROC GLeeFuncPtr_glXGetFBConfigAttrib; + #define glXGetFBConfigAttrib GLeeFuncPtr_glXGetFBConfigAttrib +#endif +#ifndef GLEE_H_DEFINED_glXGetVisualFromFBConfig +#define GLEE_H_DEFINED_glXGetVisualFromFBConfig + typedef XVisualInfo * (APIENTRYP GLEEPFNGLXGETVISUALFROMFBCONFIGPROC) (Display * dpy, GLXFBConfig config); + GLEE_EXTERN GLEEPFNGLXGETVISUALFROMFBCONFIGPROC GLeeFuncPtr_glXGetVisualFromFBConfig; + #define glXGetVisualFromFBConfig GLeeFuncPtr_glXGetVisualFromFBConfig +#endif +#ifndef GLEE_H_DEFINED_glXCreateWindow +#define GLEE_H_DEFINED_glXCreateWindow + typedef GLXWindow (APIENTRYP GLEEPFNGLXCREATEWINDOWPROC) (Display * dpy, GLXFBConfig config, Window win, const int * attrib_list); + GLEE_EXTERN GLEEPFNGLXCREATEWINDOWPROC GLeeFuncPtr_glXCreateWindow; + #define glXCreateWindow GLeeFuncPtr_glXCreateWindow +#endif +#ifndef GLEE_H_DEFINED_glXDestroyWindow +#define GLEE_H_DEFINED_glXDestroyWindow + typedef void (APIENTRYP GLEEPFNGLXDESTROYWINDOWPROC) (Display * dpy, GLXWindow win); + GLEE_EXTERN GLEEPFNGLXDESTROYWINDOWPROC GLeeFuncPtr_glXDestroyWindow; + #define glXDestroyWindow GLeeFuncPtr_glXDestroyWindow +#endif +#ifndef GLEE_H_DEFINED_glXCreatePixmap +#define GLEE_H_DEFINED_glXCreatePixmap + typedef GLXPixmap (APIENTRYP GLEEPFNGLXCREATEPIXMAPPROC) (Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list); + GLEE_EXTERN GLEEPFNGLXCREATEPIXMAPPROC GLeeFuncPtr_glXCreatePixmap; + #define glXCreatePixmap GLeeFuncPtr_glXCreatePixmap +#endif +#ifndef GLEE_H_DEFINED_glXDestroyPixmap +#define GLEE_H_DEFINED_glXDestroyPixmap + typedef void (APIENTRYP GLEEPFNGLXDESTROYPIXMAPPROC) (Display * dpy, GLXPixmap pixmap); + GLEE_EXTERN GLEEPFNGLXDESTROYPIXMAPPROC GLeeFuncPtr_glXDestroyPixmap; + #define glXDestroyPixmap GLeeFuncPtr_glXDestroyPixmap +#endif +#ifndef GLEE_H_DEFINED_glXCreatePbuffer +#define GLEE_H_DEFINED_glXCreatePbuffer + typedef GLXPbuffer (APIENTRYP GLEEPFNGLXCREATEPBUFFERPROC) (Display * dpy, GLXFBConfig config, const int * attrib_list); + GLEE_EXTERN GLEEPFNGLXCREATEPBUFFERPROC GLeeFuncPtr_glXCreatePbuffer; + #define glXCreatePbuffer GLeeFuncPtr_glXCreatePbuffer +#endif +#ifndef GLEE_H_DEFINED_glXDestroyPbuffer +#define GLEE_H_DEFINED_glXDestroyPbuffer + typedef void (APIENTRYP GLEEPFNGLXDESTROYPBUFFERPROC) (Display * dpy, GLXPbuffer pbuf); + GLEE_EXTERN GLEEPFNGLXDESTROYPBUFFERPROC GLeeFuncPtr_glXDestroyPbuffer; + #define glXDestroyPbuffer GLeeFuncPtr_glXDestroyPbuffer +#endif +#ifndef GLEE_H_DEFINED_glXQueryDrawable +#define GLEE_H_DEFINED_glXQueryDrawable + typedef void (APIENTRYP GLEEPFNGLXQUERYDRAWABLEPROC) (Display * dpy, GLXDrawable draw, int attribute, unsigned int * value); + GLEE_EXTERN GLEEPFNGLXQUERYDRAWABLEPROC GLeeFuncPtr_glXQueryDrawable; + #define glXQueryDrawable GLeeFuncPtr_glXQueryDrawable +#endif +#ifndef GLEE_H_DEFINED_glXCreateNewContext +#define GLEE_H_DEFINED_glXCreateNewContext + typedef GLXContext (APIENTRYP GLEEPFNGLXCREATENEWCONTEXTPROC) (Display * dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); + GLEE_EXTERN GLEEPFNGLXCREATENEWCONTEXTPROC GLeeFuncPtr_glXCreateNewContext; + #define glXCreateNewContext GLeeFuncPtr_glXCreateNewContext +#endif +#ifndef GLEE_H_DEFINED_glXMakeContextCurrent +#define GLEE_H_DEFINED_glXMakeContextCurrent + typedef Bool (APIENTRYP GLEEPFNGLXMAKECONTEXTCURRENTPROC) (Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + GLEE_EXTERN GLEEPFNGLXMAKECONTEXTCURRENTPROC GLeeFuncPtr_glXMakeContextCurrent; + #define glXMakeContextCurrent GLeeFuncPtr_glXMakeContextCurrent +#endif +#ifndef GLEE_H_DEFINED_glXGetCurrentReadDrawable +#define GLEE_H_DEFINED_glXGetCurrentReadDrawable + typedef GLXDrawable (APIENTRYP GLEEPFNGLXGETCURRENTREADDRAWABLEPROC) (); + GLEE_EXTERN GLEEPFNGLXGETCURRENTREADDRAWABLEPROC GLeeFuncPtr_glXGetCurrentReadDrawable; + #define glXGetCurrentReadDrawable GLeeFuncPtr_glXGetCurrentReadDrawable +#endif +#ifndef GLEE_H_DEFINED_glXGetCurrentDisplay +#define GLEE_H_DEFINED_glXGetCurrentDisplay + typedef Display * (APIENTRYP GLEEPFNGLXGETCURRENTDISPLAYPROC) (); + GLEE_EXTERN GLEEPFNGLXGETCURRENTDISPLAYPROC GLeeFuncPtr_glXGetCurrentDisplay; + #define glXGetCurrentDisplay GLeeFuncPtr_glXGetCurrentDisplay +#endif +#ifndef GLEE_H_DEFINED_glXQueryContext +#define GLEE_H_DEFINED_glXQueryContext + typedef int (APIENTRYP GLEEPFNGLXQUERYCONTEXTPROC) (Display * dpy, GLXContext ctx, int attribute, int * value); + GLEE_EXTERN GLEEPFNGLXQUERYCONTEXTPROC GLeeFuncPtr_glXQueryContext; + #define glXQueryContext GLeeFuncPtr_glXQueryContext +#endif +#ifndef GLEE_H_DEFINED_glXSelectEvent +#define GLEE_H_DEFINED_glXSelectEvent + typedef void (APIENTRYP GLEEPFNGLXSELECTEVENTPROC) (Display * dpy, GLXDrawable draw, unsigned long event_mask); + GLEE_EXTERN GLEEPFNGLXSELECTEVENTPROC GLeeFuncPtr_glXSelectEvent; + #define glXSelectEvent GLeeFuncPtr_glXSelectEvent +#endif +#ifndef GLEE_H_DEFINED_glXGetSelectedEvent +#define GLEE_H_DEFINED_glXGetSelectedEvent + typedef void (APIENTRYP GLEEPFNGLXGETSELECTEDEVENTPROC) (Display * dpy, GLXDrawable draw, unsigned long * event_mask); + GLEE_EXTERN GLEEPFNGLXGETSELECTEDEVENTPROC GLeeFuncPtr_glXGetSelectedEvent; + #define glXGetSelectedEvent GLeeFuncPtr_glXGetSelectedEvent +#endif +#endif + +/* GLX_VERSION_1_4 */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 +#define __GLEE_GLX_VERSION_1_4 1 +/* Constants */ +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 +#ifndef GLEE_H_DEFINED_glXGetProcAddress +#define GLEE_H_DEFINED_glXGetProcAddress + typedef __GLXextFuncPtr (APIENTRYP GLEEPFNGLXGETPROCADDRESSPROC) (const GLubyte * procName); + GLEE_EXTERN GLEEPFNGLXGETPROCADDRESSPROC GLeeFuncPtr_glXGetProcAddress; + #define glXGetProcAddress GLeeFuncPtr_glXGetProcAddress +#endif +#endif + +/* GLX_ARB_multisample */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 +#define __GLEE_GLX_ARB_multisample 1 +/* Constants */ +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 +#endif + +/* GLX_ARB_fbconfig_float */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 +#define __GLEE_GLX_ARB_fbconfig_float 1 +/* Constants */ +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 +#endif + +/* GLX_ARB_create_context */ + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context 1 +#define __GLEE_GLX_ARB_create_context 1 +/* Constants */ +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#ifndef GLEE_H_DEFINED_glXCreateContextAttribsARB +#define GLEE_H_DEFINED_glXCreateContextAttribsARB + typedef GLXContext (APIENTRYP GLEEPFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int * attrib_list); + GLEE_EXTERN GLEEPFNGLXCREATECONTEXTATTRIBSARBPROC GLeeFuncPtr_glXCreateContextAttribsARB; + #define glXCreateContextAttribsARB GLeeFuncPtr_glXCreateContextAttribsARB +#endif +#endif + +/* GLX_SGIS_multisample */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 +#define __GLEE_GLX_SGIS_multisample 1 +/* Constants */ +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 +#endif + +/* GLX_EXT_visual_info */ + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 +#define __GLEE_GLX_EXT_visual_info 1 +/* Constants */ +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#endif + +/* GLX_SGI_swap_control */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 +#define __GLEE_GLX_SGI_swap_control 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXSwapIntervalSGI +#define GLEE_H_DEFINED_glXSwapIntervalSGI + typedef int (APIENTRYP GLEEPFNGLXSWAPINTERVALSGIPROC) (int interval); + GLEE_EXTERN GLEEPFNGLXSWAPINTERVALSGIPROC GLeeFuncPtr_glXSwapIntervalSGI; + #define glXSwapIntervalSGI GLeeFuncPtr_glXSwapIntervalSGI +#endif +#endif + +/* GLX_SGI_video_sync */ + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 +#define __GLEE_GLX_SGI_video_sync 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXGetVideoSyncSGI +#define GLEE_H_DEFINED_glXGetVideoSyncSGI + typedef int (APIENTRYP GLEEPFNGLXGETVIDEOSYNCSGIPROC) (unsigned int * count); + GLEE_EXTERN GLEEPFNGLXGETVIDEOSYNCSGIPROC GLeeFuncPtr_glXGetVideoSyncSGI; + #define glXGetVideoSyncSGI GLeeFuncPtr_glXGetVideoSyncSGI +#endif +#ifndef GLEE_H_DEFINED_glXWaitVideoSyncSGI +#define GLEE_H_DEFINED_glXWaitVideoSyncSGI + typedef int (APIENTRYP GLEEPFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int * count); + GLEE_EXTERN GLEEPFNGLXWAITVIDEOSYNCSGIPROC GLeeFuncPtr_glXWaitVideoSyncSGI; + #define glXWaitVideoSyncSGI GLeeFuncPtr_glXWaitVideoSyncSGI +#endif +#endif + +/* GLX_SGI_make_current_read */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 +#define __GLEE_GLX_SGI_make_current_read 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXMakeCurrentReadSGI +#define GLEE_H_DEFINED_glXMakeCurrentReadSGI + typedef Bool (APIENTRYP GLEEPFNGLXMAKECURRENTREADSGIPROC) (Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + GLEE_EXTERN GLEEPFNGLXMAKECURRENTREADSGIPROC GLeeFuncPtr_glXMakeCurrentReadSGI; + #define glXMakeCurrentReadSGI GLeeFuncPtr_glXMakeCurrentReadSGI +#endif +#ifndef GLEE_H_DEFINED_glXGetCurrentReadDrawableSGI +#define GLEE_H_DEFINED_glXGetCurrentReadDrawableSGI + typedef GLXDrawable (APIENTRYP GLEEPFNGLXGETCURRENTREADDRAWABLESGIPROC) (); + GLEE_EXTERN GLEEPFNGLXGETCURRENTREADDRAWABLESGIPROC GLeeFuncPtr_glXGetCurrentReadDrawableSGI; + #define glXGetCurrentReadDrawableSGI GLeeFuncPtr_glXGetCurrentReadDrawableSGI +#endif +#endif + +/* GLX_EXT_visual_rating */ + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 +#define __GLEE_GLX_EXT_visual_rating 1 +/* Constants */ +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#endif + +/* GLX_EXT_import_context */ + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 +#define __GLEE_GLX_EXT_import_context 1 +/* Constants */ +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C +#ifndef GLEE_H_DEFINED_glXGetCurrentDisplayEXT +#define GLEE_H_DEFINED_glXGetCurrentDisplayEXT + typedef Display * (APIENTRYP GLEEPFNGLXGETCURRENTDISPLAYEXTPROC) (); + GLEE_EXTERN GLEEPFNGLXGETCURRENTDISPLAYEXTPROC GLeeFuncPtr_glXGetCurrentDisplayEXT; + #define glXGetCurrentDisplayEXT GLeeFuncPtr_glXGetCurrentDisplayEXT +#endif +#ifndef GLEE_H_DEFINED_glXQueryContextInfoEXT +#define GLEE_H_DEFINED_glXQueryContextInfoEXT + typedef int (APIENTRYP GLEEPFNGLXQUERYCONTEXTINFOEXTPROC) (Display * dpy, GLXContext context, int attribute, int * value); + GLEE_EXTERN GLEEPFNGLXQUERYCONTEXTINFOEXTPROC GLeeFuncPtr_glXQueryContextInfoEXT; + #define glXQueryContextInfoEXT GLeeFuncPtr_glXQueryContextInfoEXT +#endif +#ifndef GLEE_H_DEFINED_glXGetContextIDEXT +#define GLEE_H_DEFINED_glXGetContextIDEXT + typedef GLXContextID (APIENTRYP GLEEPFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); + GLEE_EXTERN GLEEPFNGLXGETCONTEXTIDEXTPROC GLeeFuncPtr_glXGetContextIDEXT; + #define glXGetContextIDEXT GLeeFuncPtr_glXGetContextIDEXT +#endif +#ifndef GLEE_H_DEFINED_glXImportContextEXT +#define GLEE_H_DEFINED_glXImportContextEXT + typedef GLXContext (APIENTRYP GLEEPFNGLXIMPORTCONTEXTEXTPROC) (Display * dpy, GLXContextID contextID); + GLEE_EXTERN GLEEPFNGLXIMPORTCONTEXTEXTPROC GLeeFuncPtr_glXImportContextEXT; + #define glXImportContextEXT GLeeFuncPtr_glXImportContextEXT +#endif +#ifndef GLEE_H_DEFINED_glXFreeContextEXT +#define GLEE_H_DEFINED_glXFreeContextEXT + typedef void (APIENTRYP GLEEPFNGLXFREECONTEXTEXTPROC) (Display * dpy, GLXContext context); + GLEE_EXTERN GLEEPFNGLXFREECONTEXTEXTPROC GLeeFuncPtr_glXFreeContextEXT; + #define glXFreeContextEXT GLeeFuncPtr_glXFreeContextEXT +#endif +#endif + +/* GLX_SGIX_fbconfig */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 +#define __GLEE_GLX_SGIX_fbconfig 1 +/* Constants */ +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 +#ifndef GLEE_H_DEFINED_glXGetFBConfigAttribSGIX +#define GLEE_H_DEFINED_glXGetFBConfigAttribSGIX + typedef int (APIENTRYP GLEEPFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display * dpy, GLXFBConfigSGIX config, int attribute, int * value); + GLEE_EXTERN GLEEPFNGLXGETFBCONFIGATTRIBSGIXPROC GLeeFuncPtr_glXGetFBConfigAttribSGIX; + #define glXGetFBConfigAttribSGIX GLeeFuncPtr_glXGetFBConfigAttribSGIX +#endif +#ifndef GLEE_H_DEFINED_glXChooseFBConfigSGIX +#define GLEE_H_DEFINED_glXChooseFBConfigSGIX + typedef GLXFBConfigSGIX * (APIENTRYP GLEEPFNGLXCHOOSEFBCONFIGSGIXPROC) (Display * dpy, int screen, int * attrib_list, int * nelements); + GLEE_EXTERN GLEEPFNGLXCHOOSEFBCONFIGSGIXPROC GLeeFuncPtr_glXChooseFBConfigSGIX; + #define glXChooseFBConfigSGIX GLeeFuncPtr_glXChooseFBConfigSGIX +#endif +#ifndef GLEE_H_DEFINED_glXCreateGLXPixmapWithConfigSGIX +#define GLEE_H_DEFINED_glXCreateGLXPixmapWithConfigSGIX + typedef GLXPixmap (APIENTRYP GLEEPFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display * dpy, GLXFBConfigSGIX config, Pixmap pixmap); + GLEE_EXTERN GLEEPFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC GLeeFuncPtr_glXCreateGLXPixmapWithConfigSGIX; + #define glXCreateGLXPixmapWithConfigSGIX GLeeFuncPtr_glXCreateGLXPixmapWithConfigSGIX +#endif +#ifndef GLEE_H_DEFINED_glXCreateContextWithConfigSGIX +#define GLEE_H_DEFINED_glXCreateContextWithConfigSGIX + typedef GLXContext (APIENTRYP GLEEPFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display * dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); + GLEE_EXTERN GLEEPFNGLXCREATECONTEXTWITHCONFIGSGIXPROC GLeeFuncPtr_glXCreateContextWithConfigSGIX; + #define glXCreateContextWithConfigSGIX GLeeFuncPtr_glXCreateContextWithConfigSGIX +#endif +#ifndef GLEE_H_DEFINED_glXGetVisualFromFBConfigSGIX +#define GLEE_H_DEFINED_glXGetVisualFromFBConfigSGIX + typedef XVisualInfo * (APIENTRYP GLEEPFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display * dpy, GLXFBConfigSGIX config); + GLEE_EXTERN GLEEPFNGLXGETVISUALFROMFBCONFIGSGIXPROC GLeeFuncPtr_glXGetVisualFromFBConfigSGIX; + #define glXGetVisualFromFBConfigSGIX GLeeFuncPtr_glXGetVisualFromFBConfigSGIX +#endif +#ifndef GLEE_H_DEFINED_glXGetFBConfigFromVisualSGIX +#define GLEE_H_DEFINED_glXGetFBConfigFromVisualSGIX + typedef GLXFBConfigSGIX (APIENTRYP GLEEPFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display * dpy, XVisualInfo * vis); + GLEE_EXTERN GLEEPFNGLXGETFBCONFIGFROMVISUALSGIXPROC GLeeFuncPtr_glXGetFBConfigFromVisualSGIX; + #define glXGetFBConfigFromVisualSGIX GLeeFuncPtr_glXGetFBConfigFromVisualSGIX +#endif +#endif + +/* GLX_SGIX_pbuffer */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 +#define __GLEE_GLX_SGIX_pbuffer 1 +/* Constants */ +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#ifndef GLEE_H_DEFINED_glXCreateGLXPbufferSGIX +#define GLEE_H_DEFINED_glXCreateGLXPbufferSGIX + typedef GLXPbufferSGIX (APIENTRYP GLEEPFNGLXCREATEGLXPBUFFERSGIXPROC) (Display * dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int * attrib_list); + GLEE_EXTERN GLEEPFNGLXCREATEGLXPBUFFERSGIXPROC GLeeFuncPtr_glXCreateGLXPbufferSGIX; + #define glXCreateGLXPbufferSGIX GLeeFuncPtr_glXCreateGLXPbufferSGIX +#endif +#ifndef GLEE_H_DEFINED_glXDestroyGLXPbufferSGIX +#define GLEE_H_DEFINED_glXDestroyGLXPbufferSGIX + typedef void (APIENTRYP GLEEPFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display * dpy, GLXPbufferSGIX pbuf); + GLEE_EXTERN GLEEPFNGLXDESTROYGLXPBUFFERSGIXPROC GLeeFuncPtr_glXDestroyGLXPbufferSGIX; + #define glXDestroyGLXPbufferSGIX GLeeFuncPtr_glXDestroyGLXPbufferSGIX +#endif +#ifndef GLEE_H_DEFINED_glXQueryGLXPbufferSGIX +#define GLEE_H_DEFINED_glXQueryGLXPbufferSGIX + typedef int (APIENTRYP GLEEPFNGLXQUERYGLXPBUFFERSGIXPROC) (Display * dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int * value); + GLEE_EXTERN GLEEPFNGLXQUERYGLXPBUFFERSGIXPROC GLeeFuncPtr_glXQueryGLXPbufferSGIX; + #define glXQueryGLXPbufferSGIX GLeeFuncPtr_glXQueryGLXPbufferSGIX +#endif +#ifndef GLEE_H_DEFINED_glXSelectEventSGIX +#define GLEE_H_DEFINED_glXSelectEventSGIX + typedef void (APIENTRYP GLEEPFNGLXSELECTEVENTSGIXPROC) (Display * dpy, GLXDrawable drawable, unsigned long mask); + GLEE_EXTERN GLEEPFNGLXSELECTEVENTSGIXPROC GLeeFuncPtr_glXSelectEventSGIX; + #define glXSelectEventSGIX GLeeFuncPtr_glXSelectEventSGIX +#endif +#ifndef GLEE_H_DEFINED_glXGetSelectedEventSGIX +#define GLEE_H_DEFINED_glXGetSelectedEventSGIX + typedef void (APIENTRYP GLEEPFNGLXGETSELECTEDEVENTSGIXPROC) (Display * dpy, GLXDrawable drawable, unsigned long * mask); + GLEE_EXTERN GLEEPFNGLXGETSELECTEDEVENTSGIXPROC GLeeFuncPtr_glXGetSelectedEventSGIX; + #define glXGetSelectedEventSGIX GLeeFuncPtr_glXGetSelectedEventSGIX +#endif +#endif + +/* GLX_SGI_cushion */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 +#define __GLEE_GLX_SGI_cushion 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXCushionSGI +#define GLEE_H_DEFINED_glXCushionSGI + typedef void (APIENTRYP GLEEPFNGLXCUSHIONSGIPROC) (Display * dpy, Window window, float cushion); + GLEE_EXTERN GLEEPFNGLXCUSHIONSGIPROC GLeeFuncPtr_glXCushionSGI; + #define glXCushionSGI GLeeFuncPtr_glXCushionSGI +#endif +#endif + +/* GLX_SGIX_video_resize */ + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 +#define __GLEE_GLX_SGIX_video_resize 1 +/* Constants */ +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 +#ifndef GLEE_H_DEFINED_glXBindChannelToWindowSGIX +#define GLEE_H_DEFINED_glXBindChannelToWindowSGIX + typedef int (APIENTRYP GLEEPFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display * display, int screen, int channel, Window window); + GLEE_EXTERN GLEEPFNGLXBINDCHANNELTOWINDOWSGIXPROC GLeeFuncPtr_glXBindChannelToWindowSGIX; + #define glXBindChannelToWindowSGIX GLeeFuncPtr_glXBindChannelToWindowSGIX +#endif +#ifndef GLEE_H_DEFINED_glXChannelRectSGIX +#define GLEE_H_DEFINED_glXChannelRectSGIX + typedef int (APIENTRYP GLEEPFNGLXCHANNELRECTSGIXPROC) (Display * display, int screen, int channel, int x, int y, int w, int h); + GLEE_EXTERN GLEEPFNGLXCHANNELRECTSGIXPROC GLeeFuncPtr_glXChannelRectSGIX; + #define glXChannelRectSGIX GLeeFuncPtr_glXChannelRectSGIX +#endif +#ifndef GLEE_H_DEFINED_glXQueryChannelRectSGIX +#define GLEE_H_DEFINED_glXQueryChannelRectSGIX + typedef int (APIENTRYP GLEEPFNGLXQUERYCHANNELRECTSGIXPROC) (Display * display, int screen, int channel, int * dx, int * dy, int * dw, int * dh); + GLEE_EXTERN GLEEPFNGLXQUERYCHANNELRECTSGIXPROC GLeeFuncPtr_glXQueryChannelRectSGIX; + #define glXQueryChannelRectSGIX GLeeFuncPtr_glXQueryChannelRectSGIX +#endif +#ifndef GLEE_H_DEFINED_glXQueryChannelDeltasSGIX +#define GLEE_H_DEFINED_glXQueryChannelDeltasSGIX + typedef int (APIENTRYP GLEEPFNGLXQUERYCHANNELDELTASSGIXPROC) (Display * display, int screen, int channel, int * x, int * y, int * w, int * h); + GLEE_EXTERN GLEEPFNGLXQUERYCHANNELDELTASSGIXPROC GLeeFuncPtr_glXQueryChannelDeltasSGIX; + #define glXQueryChannelDeltasSGIX GLeeFuncPtr_glXQueryChannelDeltasSGIX +#endif +#ifndef GLEE_H_DEFINED_glXChannelRectSyncSGIX +#define GLEE_H_DEFINED_glXChannelRectSyncSGIX + typedef int (APIENTRYP GLEEPFNGLXCHANNELRECTSYNCSGIXPROC) (Display * display, int screen, int channel, GLenum synctype); + GLEE_EXTERN GLEEPFNGLXCHANNELRECTSYNCSGIXPROC GLeeFuncPtr_glXChannelRectSyncSGIX; + #define glXChannelRectSyncSGIX GLeeFuncPtr_glXChannelRectSyncSGIX +#endif +#endif + +/* GLX_SGIX_swap_group */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 +#define __GLEE_GLX_SGIX_swap_group 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXJoinSwapGroupSGIX +#define GLEE_H_DEFINED_glXJoinSwapGroupSGIX + typedef void (APIENTRYP GLEEPFNGLXJOINSWAPGROUPSGIXPROC) (Display * dpy, GLXDrawable drawable, GLXDrawable member); + GLEE_EXTERN GLEEPFNGLXJOINSWAPGROUPSGIXPROC GLeeFuncPtr_glXJoinSwapGroupSGIX; + #define glXJoinSwapGroupSGIX GLeeFuncPtr_glXJoinSwapGroupSGIX +#endif +#endif + +/* GLX_SGIX_swap_barrier */ + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 +#define __GLEE_GLX_SGIX_swap_barrier 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXBindSwapBarrierSGIX +#define GLEE_H_DEFINED_glXBindSwapBarrierSGIX + typedef void (APIENTRYP GLEEPFNGLXBINDSWAPBARRIERSGIXPROC) (Display * dpy, GLXDrawable drawable, int barrier); + GLEE_EXTERN GLEEPFNGLXBINDSWAPBARRIERSGIXPROC GLeeFuncPtr_glXBindSwapBarrierSGIX; + #define glXBindSwapBarrierSGIX GLeeFuncPtr_glXBindSwapBarrierSGIX +#endif +#ifndef GLEE_H_DEFINED_glXQueryMaxSwapBarriersSGIX +#define GLEE_H_DEFINED_glXQueryMaxSwapBarriersSGIX + typedef Bool (APIENTRYP GLEEPFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display * dpy, int screen, int * max); + GLEE_EXTERN GLEEPFNGLXQUERYMAXSWAPBARRIERSSGIXPROC GLeeFuncPtr_glXQueryMaxSwapBarriersSGIX; + #define glXQueryMaxSwapBarriersSGIX GLeeFuncPtr_glXQueryMaxSwapBarriersSGIX +#endif +#endif + +/* GLX_SGIS_blended_overlay */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 +#define __GLEE_GLX_SGIS_blended_overlay 1 +/* Constants */ +#define GLX_BLENDED_RGBA_SGIS 0x8025 +#endif + +/* GLX_SGIS_shared_multisample */ + +#ifndef GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample 1 +#define __GLEE_GLX_SGIS_shared_multisample 1 +/* Constants */ +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 +#endif + +/* GLX_SUN_get_transparent_index */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 +#define __GLEE_GLX_SUN_get_transparent_index 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXGetTransparentIndexSUN +#define GLEE_H_DEFINED_glXGetTransparentIndexSUN + typedef Status (APIENTRYP GLEEPFNGLXGETTRANSPARENTINDEXSUNPROC) (Display * dpy, Window overlay, Window underlay, long * pTransparentIndex); + GLEE_EXTERN GLEEPFNGLXGETTRANSPARENTINDEXSUNPROC GLeeFuncPtr_glXGetTransparentIndexSUN; + #define glXGetTransparentIndexSUN GLeeFuncPtr_glXGetTransparentIndexSUN +#endif +#endif + +/* GLX_3DFX_multisample */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 +#define __GLEE_GLX_3DFX_multisample 1 +/* Constants */ +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 +#endif + +/* GLX_MESA_copy_sub_buffer */ + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 +#define __GLEE_GLX_MESA_copy_sub_buffer 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXCopySubBufferMESA +#define GLEE_H_DEFINED_glXCopySubBufferMESA + typedef void (APIENTRYP GLEEPFNGLXCOPYSUBBUFFERMESAPROC) (Display * dpy, GLXDrawable drawable, int x, int y, int width, int height); + GLEE_EXTERN GLEEPFNGLXCOPYSUBBUFFERMESAPROC GLeeFuncPtr_glXCopySubBufferMESA; + #define glXCopySubBufferMESA GLeeFuncPtr_glXCopySubBufferMESA +#endif +#endif + +/* GLX_MESA_pixmap_colormap */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 +#define __GLEE_GLX_MESA_pixmap_colormap 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXCreateGLXPixmapMESA +#define GLEE_H_DEFINED_glXCreateGLXPixmapMESA + typedef GLXPixmap (APIENTRYP GLEEPFNGLXCREATEGLXPIXMAPMESAPROC) (Display * dpy, XVisualInfo * visual, Pixmap pixmap, Colormap cmap); + GLEE_EXTERN GLEEPFNGLXCREATEGLXPIXMAPMESAPROC GLeeFuncPtr_glXCreateGLXPixmapMESA; + #define glXCreateGLXPixmapMESA GLeeFuncPtr_glXCreateGLXPixmapMESA +#endif +#endif + +/* GLX_MESA_release_buffers */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 +#define __GLEE_GLX_MESA_release_buffers 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXReleaseBuffersMESA +#define GLEE_H_DEFINED_glXReleaseBuffersMESA + typedef Bool (APIENTRYP GLEEPFNGLXRELEASEBUFFERSMESAPROC) (Display * dpy, GLXDrawable drawable); + GLEE_EXTERN GLEEPFNGLXRELEASEBUFFERSMESAPROC GLeeFuncPtr_glXReleaseBuffersMESA; + #define glXReleaseBuffersMESA GLeeFuncPtr_glXReleaseBuffersMESA +#endif +#endif + +/* GLX_MESA_set_3dfx_mode */ + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 +#define __GLEE_GLX_MESA_set_3dfx_mode 1 +/* Constants */ +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 +#ifndef GLEE_H_DEFINED_glXSet3DfxModeMESA +#define GLEE_H_DEFINED_glXSet3DfxModeMESA + typedef Bool (APIENTRYP GLEEPFNGLXSET3DFXMODEMESAPROC) (int mode); + GLEE_EXTERN GLEEPFNGLXSET3DFXMODEMESAPROC GLeeFuncPtr_glXSet3DfxModeMESA; + #define glXSet3DfxModeMESA GLeeFuncPtr_glXSet3DfxModeMESA +#endif +#endif + +/* GLX_SGIX_visual_select_group */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 +#define __GLEE_GLX_SGIX_visual_select_group 1 +/* Constants */ +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 +#endif + +/* GLX_OML_swap_method */ + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 +#define __GLEE_GLX_OML_swap_method 1 +/* Constants */ +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 +#endif + +/* GLX_OML_sync_control */ + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control 1 +#define __GLEE_GLX_OML_sync_control 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXGetSyncValuesOML +#define GLEE_H_DEFINED_glXGetSyncValuesOML + typedef Bool (APIENTRYP GLEEPFNGLXGETSYNCVALUESOMLPROC) (Display * dpy, GLXDrawable drawable, int64_t * ust, int64_t * msc, int64_t * sbc); + GLEE_EXTERN GLEEPFNGLXGETSYNCVALUESOMLPROC GLeeFuncPtr_glXGetSyncValuesOML; + #define glXGetSyncValuesOML GLeeFuncPtr_glXGetSyncValuesOML +#endif +#ifndef GLEE_H_DEFINED_glXGetMscRateOML +#define GLEE_H_DEFINED_glXGetMscRateOML + typedef Bool (APIENTRYP GLEEPFNGLXGETMSCRATEOMLPROC) (Display * dpy, GLXDrawable drawable, int32_t * numerator, int32_t * denominator); + GLEE_EXTERN GLEEPFNGLXGETMSCRATEOMLPROC GLeeFuncPtr_glXGetMscRateOML; + #define glXGetMscRateOML GLeeFuncPtr_glXGetMscRateOML +#endif +#ifndef GLEE_H_DEFINED_glXSwapBuffersMscOML +#define GLEE_H_DEFINED_glXSwapBuffersMscOML + typedef int64_t (APIENTRYP GLEEPFNGLXSWAPBUFFERSMSCOMLPROC) (Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); + GLEE_EXTERN GLEEPFNGLXSWAPBUFFERSMSCOMLPROC GLeeFuncPtr_glXSwapBuffersMscOML; + #define glXSwapBuffersMscOML GLeeFuncPtr_glXSwapBuffersMscOML +#endif +#ifndef GLEE_H_DEFINED_glXWaitForMscOML +#define GLEE_H_DEFINED_glXWaitForMscOML + typedef Bool (APIENTRYP GLEEPFNGLXWAITFORMSCOMLPROC) (Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * ust, int64_t * msc, int64_t * sbc); + GLEE_EXTERN GLEEPFNGLXWAITFORMSCOMLPROC GLeeFuncPtr_glXWaitForMscOML; + #define glXWaitForMscOML GLeeFuncPtr_glXWaitForMscOML +#endif +#ifndef GLEE_H_DEFINED_glXWaitForSbcOML +#define GLEE_H_DEFINED_glXWaitForSbcOML + typedef Bool (APIENTRYP GLEEPFNGLXWAITFORSBCOMLPROC) (Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t * ust, int64_t * msc, int64_t * sbc); + GLEE_EXTERN GLEEPFNGLXWAITFORSBCOMLPROC GLeeFuncPtr_glXWaitForSbcOML; + #define glXWaitForSbcOML GLeeFuncPtr_glXWaitForSbcOML +#endif +#endif + +/* GLX_NV_float_buffer */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 +#define __GLEE_GLX_NV_float_buffer 1 +/* Constants */ +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 +#endif + +/* GLX_SGIX_hyperpipe */ + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 +#define __GLEE_GLX_SGIX_hyperpipe 1 +/* Constants */ +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 +#ifndef GLEE_H_DEFINED_glXQueryHyperpipeNetworkSGIX +#define GLEE_H_DEFINED_glXQueryHyperpipeNetworkSGIX + typedef GLXHyperpipeNetworkSGIX * (APIENTRYP GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display * dpy, int * npipes); + GLEE_EXTERN GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX; + #define glXQueryHyperpipeNetworkSGIX GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX +#endif +#ifndef GLEE_H_DEFINED_glXHyperpipeConfigSGIX +#define GLEE_H_DEFINED_glXHyperpipeConfigSGIX + typedef int (APIENTRYP GLEEPFNGLXHYPERPIPECONFIGSGIXPROC) (Display * dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX * cfg, int * hpId); + GLEE_EXTERN GLEEPFNGLXHYPERPIPECONFIGSGIXPROC GLeeFuncPtr_glXHyperpipeConfigSGIX; + #define glXHyperpipeConfigSGIX GLeeFuncPtr_glXHyperpipeConfigSGIX +#endif +#ifndef GLEE_H_DEFINED_glXQueryHyperpipeConfigSGIX +#define GLEE_H_DEFINED_glXQueryHyperpipeConfigSGIX + typedef GLXHyperpipeConfigSGIX * (APIENTRYP GLEEPFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display * dpy, int hpId, int * npipes); + GLEE_EXTERN GLEEPFNGLXQUERYHYPERPIPECONFIGSGIXPROC GLeeFuncPtr_glXQueryHyperpipeConfigSGIX; + #define glXQueryHyperpipeConfigSGIX GLeeFuncPtr_glXQueryHyperpipeConfigSGIX +#endif +#ifndef GLEE_H_DEFINED_glXDestroyHyperpipeConfigSGIX +#define GLEE_H_DEFINED_glXDestroyHyperpipeConfigSGIX + typedef int (APIENTRYP GLEEPFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display * dpy, int hpId); + GLEE_EXTERN GLEEPFNGLXDESTROYHYPERPIPECONFIGSGIXPROC GLeeFuncPtr_glXDestroyHyperpipeConfigSGIX; + #define glXDestroyHyperpipeConfigSGIX GLeeFuncPtr_glXDestroyHyperpipeConfigSGIX +#endif +#ifndef GLEE_H_DEFINED_glXBindHyperpipeSGIX +#define GLEE_H_DEFINED_glXBindHyperpipeSGIX + typedef int (APIENTRYP GLEEPFNGLXBINDHYPERPIPESGIXPROC) (Display * dpy, int hpId); + GLEE_EXTERN GLEEPFNGLXBINDHYPERPIPESGIXPROC GLeeFuncPtr_glXBindHyperpipeSGIX; + #define glXBindHyperpipeSGIX GLeeFuncPtr_glXBindHyperpipeSGIX +#endif +#ifndef GLEE_H_DEFINED_glXQueryHyperpipeBestAttribSGIX +#define GLEE_H_DEFINED_glXQueryHyperpipeBestAttribSGIX + typedef int (APIENTRYP GLEEPFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display * dpy, int timeSlice, int attrib, int size, void * attribList, void * returnAttribList); + GLEE_EXTERN GLEEPFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC GLeeFuncPtr_glXQueryHyperpipeBestAttribSGIX; + #define glXQueryHyperpipeBestAttribSGIX GLeeFuncPtr_glXQueryHyperpipeBestAttribSGIX +#endif +#ifndef GLEE_H_DEFINED_glXHyperpipeAttribSGIX +#define GLEE_H_DEFINED_glXHyperpipeAttribSGIX + typedef int (APIENTRYP GLEEPFNGLXHYPERPIPEATTRIBSGIXPROC) (Display * dpy, int timeSlice, int attrib, int size, void * attribList); + GLEE_EXTERN GLEEPFNGLXHYPERPIPEATTRIBSGIXPROC GLeeFuncPtr_glXHyperpipeAttribSGIX; + #define glXHyperpipeAttribSGIX GLeeFuncPtr_glXHyperpipeAttribSGIX +#endif +#ifndef GLEE_H_DEFINED_glXQueryHyperpipeAttribSGIX +#define GLEE_H_DEFINED_glXQueryHyperpipeAttribSGIX + typedef int (APIENTRYP GLEEPFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display * dpy, int timeSlice, int attrib, int size, void * returnAttribList); + GLEE_EXTERN GLEEPFNGLXQUERYHYPERPIPEATTRIBSGIXPROC GLeeFuncPtr_glXQueryHyperpipeAttribSGIX; + #define glXQueryHyperpipeAttribSGIX GLeeFuncPtr_glXQueryHyperpipeAttribSGIX +#endif +#endif + +/* GLX_MESA_agp_offset */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 +#define __GLEE_GLX_MESA_agp_offset 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glXGetAGPOffsetMESA +#define GLEE_H_DEFINED_glXGetAGPOffsetMESA + typedef unsigned int (APIENTRYP GLEEPFNGLXGETAGPOFFSETMESAPROC) (const void * pointer); + GLEE_EXTERN GLEEPFNGLXGETAGPOFFSETMESAPROC GLeeFuncPtr_glXGetAGPOffsetMESA; + #define glXGetAGPOffsetMESA GLeeFuncPtr_glXGetAGPOffsetMESA +#endif +#endif + +/* GLX_EXT_fbconfig_packed_float */ + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 +#define __GLEE_GLX_EXT_fbconfig_packed_float 1 +/* Constants */ +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#endif + +/* GLX_EXT_framebuffer_sRGB */ + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 +#define __GLEE_GLX_EXT_framebuffer_sRGB 1 +/* Constants */ +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 +#endif + +/* GLX_EXT_texture_from_pixmap */ + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap 1 +#define __GLEE_GLX_EXT_texture_from_pixmap 1 +/* Constants */ +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT +#define GLX_BACK_EXT GLX_BACK_LEFT_EXT +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB +#ifndef GLEE_H_DEFINED_glXBindTexImageEXT +#define GLEE_H_DEFINED_glXBindTexImageEXT + typedef void (APIENTRYP GLEEPFNGLXBINDTEXIMAGEEXTPROC) (Display * dpy, GLXDrawable drawable, int buffer, const int * attrib_list); + GLEE_EXTERN GLEEPFNGLXBINDTEXIMAGEEXTPROC GLeeFuncPtr_glXBindTexImageEXT; + #define glXBindTexImageEXT GLeeFuncPtr_glXBindTexImageEXT +#endif +#ifndef GLEE_H_DEFINED_glXReleaseTexImageEXT +#define GLEE_H_DEFINED_glXReleaseTexImageEXT + typedef void (APIENTRYP GLEEPFNGLXRELEASETEXIMAGEEXTPROC) (Display * dpy, GLXDrawable drawable, int buffer); + GLEE_EXTERN GLEEPFNGLXRELEASETEXIMAGEEXTPROC GLeeFuncPtr_glXReleaseTexImageEXT; + #define glXReleaseTexImageEXT GLeeFuncPtr_glXReleaseTexImageEXT +#endif +#endif + +/* GLX_NV_present_video */ + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video 1 +#define __GLEE_GLX_NV_present_video 1 +/* Constants */ +#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 +#endif + +/* GLX_NV_video_out */ + +#ifndef GLX_NV_video_out +#define GLX_NV_video_out 1 +#define __GLEE_GLX_NV_video_out 1 +/* Constants */ +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB +#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC +#endif + +/* GLX_NV_swap_group */ + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group 1 +#define __GLEE_GLX_NV_swap_group 1 +/* Constants */ +#endif + +/* GLX_EXT_scene_marker */ + +#ifndef GLX_EXT_scene_marker +#define GLX_EXT_scene_marker 1 +#define __GLEE_GLX_EXT_scene_marker 1 +/* Constants */ +#endif + +/* GLX_NV_video_output */ + +#ifndef GLX_NV_video_output +#define GLX_NV_video_output 1 +#define __GLEE_GLX_NV_video_output 1 +/* Constants */ +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB +#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC +#ifndef GLEE_H_DEFINED_glXGetVideoDeviceNV +#define GLEE_H_DEFINED_glXGetVideoDeviceNV + typedef int (APIENTRYP GLEEPFNGLXGETVIDEODEVICENVPROC) (Display * dpy, int screen, int numVideoDevices, GLXVideoDeviceNV * pVideoDevice); + GLEE_EXTERN GLEEPFNGLXGETVIDEODEVICENVPROC GLeeFuncPtr_glXGetVideoDeviceNV; + #define glXGetVideoDeviceNV GLeeFuncPtr_glXGetVideoDeviceNV +#endif +#ifndef GLEE_H_DEFINED_glXReleaseVideoDeviceNV +#define GLEE_H_DEFINED_glXReleaseVideoDeviceNV + typedef int (APIENTRYP GLEEPFNGLXRELEASEVIDEODEVICENVPROC) (Display * dpy, int screen, GLXVideoDeviceNV VideoDevice); + GLEE_EXTERN GLEEPFNGLXRELEASEVIDEODEVICENVPROC GLeeFuncPtr_glXReleaseVideoDeviceNV; + #define glXReleaseVideoDeviceNV GLeeFuncPtr_glXReleaseVideoDeviceNV +#endif +#ifndef GLEE_H_DEFINED_glXBindVideoImageNV +#define GLEE_H_DEFINED_glXBindVideoImageNV + typedef int (APIENTRYP GLEEPFNGLXBINDVIDEOIMAGENVPROC) (Display * dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); + GLEE_EXTERN GLEEPFNGLXBINDVIDEOIMAGENVPROC GLeeFuncPtr_glXBindVideoImageNV; + #define glXBindVideoImageNV GLeeFuncPtr_glXBindVideoImageNV +#endif +#ifndef GLEE_H_DEFINED_glXReleaseVideoImageNV +#define GLEE_H_DEFINED_glXReleaseVideoImageNV + typedef int (APIENTRYP GLEEPFNGLXRELEASEVIDEOIMAGENVPROC) (Display * dpy, GLXPbuffer pbuf); + GLEE_EXTERN GLEEPFNGLXRELEASEVIDEOIMAGENVPROC GLeeFuncPtr_glXReleaseVideoImageNV; + #define glXReleaseVideoImageNV GLeeFuncPtr_glXReleaseVideoImageNV +#endif +#ifndef GLEE_H_DEFINED_glXSendPbufferToVideoNV +#define GLEE_H_DEFINED_glXSendPbufferToVideoNV + typedef int (APIENTRYP GLEEPFNGLXSENDPBUFFERTOVIDEONVPROC) (Display * dpy, GLXPbuffer pbuf, int iBufferType, unsigned long * pulCounterPbuffer, GLboolean bBlock); + GLEE_EXTERN GLEEPFNGLXSENDPBUFFERTOVIDEONVPROC GLeeFuncPtr_glXSendPbufferToVideoNV; + #define glXSendPbufferToVideoNV GLeeFuncPtr_glXSendPbufferToVideoNV +#endif +#ifndef GLEE_H_DEFINED_glXGetVideoInfoNV +#define GLEE_H_DEFINED_glXGetVideoInfoNV + typedef int (APIENTRYP GLEEPFNGLXGETVIDEOINFONVPROC) (Display * dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long * pulCounterOutputPbuffer, unsigned long * pulCounterOutputVideo); + GLEE_EXTERN GLEEPFNGLXGETVIDEOINFONVPROC GLeeFuncPtr_glXGetVideoInfoNV; + #define glXGetVideoInfoNV GLeeFuncPtr_glXGetVideoInfoNV +#endif +#endif +#endif /*end GLX */ + +/***************************************************************** + * GLee functions + *****************************************************************/ + +GLEE_EXTERN GLboolean GLeeInit( void ); +GLEE_EXTERN GLint GLeeForceLink(const char * extensionName); +GLEE_EXTERN const char * GLeeGetErrorString( void ); +GLEE_EXTERN const char * GLeeGetExtStrGL( void ); +GLEE_EXTERN GLboolean GLeeEnabled(GLboolean * extensionQueryingVariable); + +#ifdef WIN32 +GLEE_EXTERN const char * GLeeGetExtStrWGL( void ); +#elif defined(__APPLE__) || defined(__APPLE_CC__) +#else +GLEE_EXTERN const char * GLeeGetExtStrGLX( void ); +#endif + +#ifdef __cplusplus +} /* end C linkage */ +#endif + +#endif /* __glee_h_ defined */ diff --git a/Extras/sph/common/common_defs.h b/Extras/sph/common/common_defs.h new file mode 100644 index 0000000..0f1628c --- /dev/null +++ b/Extras/sph/common/common_defs.h @@ -0,0 +1,52 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef COMMON_DEF + #define COMMON_DEF + + // Global defs + + //#define USE_SHADOWS // Disable if you don't have FBOs, or to greatly speed up demo. + +// #define USE_JPEG + + #define BUILD_CUDA // CUDA - Visual Studio 2005 only (as of April 2009) + + #define TEX_SIZE 2048 + #define LIGHT_NEAR 0.5 + #define LIGHT_FAR 300.0 + #define DEGtoRAD (3.141592/180.0) + + #ifdef _MSC_VER + #include + #else + typedef unsigned int DWORD; + #endif + typedef unsigned int uint; + + #define COLOR(r,g,b) ( (DWORD(r*255.0f)<<24) | (DWORD(g*255.0f)<<16) | (DWORD(b*255.0f)<<8) ) + #define COLORA(r,g,b,a) ( (DWORD(r*255.0f)<<24) | (DWORD(g*255.0f)<<16) | (DWORD(b*255.0f)<<8) | DWORD(a*255.0f) ) + #define RED(c) (float((c>>24) & 0xFF)/255.0) + #define GRN(c) (float((c>>16) & 0xFF)/255.0) + #define BLUE(c) (float((c>>8) & 0xFF)/255.0) + #define ALPH(c) (float(c & 0xFF)/255.0) +#endif \ No newline at end of file diff --git a/Extras/sph/common/geomx.cpp b/Extras/sph/common/geomx.cpp new file mode 100644 index 0000000..4503fee --- /dev/null +++ b/Extras/sph/common/geomx.cpp @@ -0,0 +1,443 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +#include +#include "geomx.h" +#include "mdebug.h" + +#include + +GeomX::GeomX () +{ + mHeap = 0x0; +} + +void GeomX::FreeBuffers () +{ + for (int n=0; n < (int) mBuf.size(); n++) { + free ( mBuf[n].data ); + mBuf[n].data = 0x0; + } + mBuf.clear (); + + if ( mHeap != 0x0 ) free ( mHeap ); + mHeap = 0x0; + mHeapNum = 0; + mHeapMax = 0; +} + +void GeomX::ResetHeap () +{ + mHeapNum = 0; + mHeapFree = -1; +} + +int GeomX::GetSize () +{ + int sum = mHeapNum * sizeof(hval) ; + for (int n=0; n < (int) mBuf.size(); n++) + sum += mBuf[n].size; + sum += (int) mAttribute.size() * sizeof(GeomAttr); + return sum; +} + +void GeomX::ClearAttributes () +{ + mAttribute.clear (); +} + +int GeomX::CopyBuffer ( uchar bdest, uchar bsrc, GeomX& src ) +{ + if ( bsrc >= src.GetNumBuf() ) return -1; + + if ( bdest >= GetNumBuf() ) { + for (int n=0; n <= bdest - GetNumBuf(); n++ ) + AddBuffer ( 0, 0, 0 ); + } + if ( mBuf[bdest].data != 0x0 ) { + free ( mBuf[bdest].data ); + mBuf[bdest].data = 0x0; + } + + GeomBuf* buf = src.GetBuffer( bsrc ); + mBuf[bdest].dtype = buf->dtype; + mBuf[bdest].max = buf->max; + mBuf[bdest].num = buf->num; + mBuf[bdest].stride = buf->stride; + mBuf[bdest].size = buf->size; + mBuf[bdest].data = (char*) malloc ( mBuf[bdest].max * mBuf[bdest].stride ); + memcpy ( mBuf[bdest].data, buf->data, mBuf[bdest].num * mBuf[bdest].stride ); + + return bdest; +} + + +void GeomX::CopyBuffers ( GeomX& src ) +{ + FreeBuffers (); + for (int n = 0; n < src.GetNumBuf(); n++) + CopyBuffer ( n, n, src ); + CopyHeap ( src ); +} + +void GeomX::CopyHeap ( GeomX& src ) +{ + hpos num, max, freepos; + hval* src_data = src.GetHeap ( num, max, freepos ); + + if ( mHeap != 0x0 ) { + free ( mHeap ); + mHeap = 0x0; + } + + mHeap = (hval*) malloc ( max * sizeof(hval) ); + mHeapMax = max; + mHeapNum = num; + mHeapFree = freepos; + + memcpy ( mHeap, src_data, mHeapNum * sizeof(hval) ); +} + +hval* GeomX::GetHeap ( hpos& num, hpos& max, hpos& free ) +{ + num = mHeapNum; + max = mHeapMax; + free = mHeapFree; + return mHeap; +} + +void GeomX::CopyAttributes ( GeomX& src ) +{ + GeomAttr* attr; + ClearAttributes (); + int a; + for (int n = 0; n < src.GetNumAttr(); n++) { + attr = src.GetAttribute ( n ); + a = AddAttribute ( (uchar) attr->buf, attr->name, attr->stride, false ); + mAttribute[a].offset = attr->offset; + } +} + + +void GeomX::AddHeap ( int max ) +{ + mHeap = (hval*) malloc ( max * sizeof(hval ) ); + mHeapMax = max; + mHeapNum = 0; + mHeapFree = -1; +} + +int GeomX::AddAttribute ( uchar b, std::string name, ushort stride ) +{ + return AddAttribute ( b, name, stride, true ); +} + +int GeomX::AddAttribute ( uchar b, std::string name, ushort stride, bool bExtend ) +{ + GeomBuf* buf = &mBuf[b]; + GeomAttr attr; + + attr.buf = b; + attr.name = name; + attr.offset = buf->stride; + attr.stride = stride; + + if ( bExtend ) { + int new_stride = buf->stride + attr.stride; + char* new_data = (char*) malloc ( buf->max * new_stride ); + char* old_data = buf->data; + for (int n=0; n < buf->num; n++) { + memcpy ( new_data, old_data, buf->stride ); + old_data += buf->stride; + new_data += new_stride; + } + free ( buf->data ); + buf->data = new_data; + buf->stride = new_stride; + } + mAttribute.push_back ( attr ); + return (int) mAttribute.size()-1; +} + +int GeomX::GetAttribute ( std::string name ) +{ + for (int n=0; n < (int) mAttribute.size(); n++) { + if ( mAttribute[n].name.compare ( name ) == 0 ) + return n; + } + return -1; +} + +int GeomX::GetAttrOffset ( std::string name ) +{ + for (int n=0; n < (int) mAttribute.size(); n++) { + if ( mAttribute[n].name.compare ( name ) == 0 ) + return mAttribute[n].offset; + } + return -1; +} + +int GeomX::AddBuffer ( uchar typ, ushort stride, int max ) +{ + GeomBuf buf; + buf.dtype = typ; + buf.stride = stride; + buf.max = max; + buf.num = 0; + buf.size = 0; + buf.data = (char*) malloc ( buf.max * buf.stride ); + mBuf.push_back ( buf ); + return (int) mBuf.size()-1; +} +void GeomX::ResetBuffer ( uchar b, int n ) +{ + mBuf[b].max = n; + + if ( mBuf[b].data != 0x0 ) free ( mBuf[b].data ); + + char* new_data = (char*) malloc ( mBuf[b].max * mBuf[b].stride ); + + mBuf[b].data = new_data; + + mBuf[b].num = 0; + mBuf[b].size = mBuf[b].num*mBuf[b].stride; +} + +char* GeomX::AddElem ( uchar b, href& ndx ) +{ + if ( mBuf[b].num >= mBuf[b].max ) { + if ( long(mBuf[b].max) * 2 > ELEM_MAX ) { + error.PrintF ( "geom", "Maximum number of elements reached.\n" ); + error.Exit (); + } + mBuf[b].max *= 2; + char* new_data = (char*) malloc ( mBuf[b].max * mBuf[b].stride ); + memcpy ( new_data, mBuf[b].data, mBuf[b].num*mBuf[b].stride ); + free ( mBuf[b].data ); + mBuf[b].data = new_data; + } + mBuf[b].num++; + mBuf[b].size += mBuf[b].stride; + ndx = mBuf[b].num-1; + return mBuf[b].data + ndx*mBuf[b].stride; +} + +char* GeomX::RandomElem ( uchar b, href& ndx ) +{ + ndx = mBuf[b].num * rand() / RAND_MAX; + return mBuf[b].data + ndx*mBuf[b].stride; +} + +int GeomX::AddElem ( uchar b, char* data ) +{ + if ( mBuf[b].num >= mBuf[b].max ) { + mBuf[b].max *= 2; + char* new_data = (char*) malloc ( mBuf[b].max * mBuf[b].stride ); + memcpy ( new_data, mBuf[b].data, mBuf[b].num*mBuf[b].stride ); + free ( mBuf[b].data ); + mBuf[b].data = new_data; + } + memcpy ( mBuf[b].data + mBuf[b].num*mBuf[b].stride, data, mBuf[b].stride ); + mBuf[b].num++; + mBuf[b].size += mBuf[b].stride; + return mBuf[b].num-1; +} + +bool GeomX::DelElem ( uchar b, int n ) +{ + if ( n >= 0 && n < mBuf[b].num ) { + memcpy ( mBuf[b].data + n*mBuf[b].stride, mBuf[b].data + (mBuf[b].num-1)*mBuf[b].stride, mBuf[b].stride ); + mBuf[b].num--; + mBuf[b].size -= mBuf[b].stride; + return true; + } + return false; +} + +hpos GeomX::HeapExpand ( ushort size, ushort& ret ) +{ + mHeapMax *= 2; + if ( mHeapMax > HEAP_MAX ) { + error.PrintF ( "geom", "Geom heap size exceeds range of index.\n" ); + error.Exit (); + } + hval* pNewHeap = (hval*) malloc ( mHeapMax * sizeof(hval) ); + if ( pNewHeap == 0x0 ) { + error.PrintF ( "geom", "Geom heap out of memory.\n" ); + error.Exit (); + } + memcpy ( pNewHeap, mHeap, mHeapNum*sizeof(hval) ); + free ( mHeap ); + mHeap = pNewHeap; + ret = size; + assert ( mHeapNum >= 0 && mHeapNum < mHeapMax ); + return mHeapNum; +} + +#define LIST_INIT 4 + +hpos GeomX::HeapAlloc ( ushort size, ushort& ret ) +{ + hval* pPrev = 0x0; + hval* pCurr = mHeap + mHeapFree; + hpos pos = -1; + + if ( mHeapNum + size < mHeapMax ) { + // Heap not yet full. + pos = mHeapNum; + ret = size; + mHeapNum += size; + } else { + // Heap full, search free space + if ( mHeapFree == -1 ) { + pos = HeapExpand ( size, ret ); + mHeapNum += ret; + } else { + while ( *pCurr < size && pCurr != mHeap-1 ) { + pPrev = pCurr; + pCurr = mHeap + * (hpos*) (pCurr + FPOS); + } + if ( pCurr != mHeap-1 ) { + // Found free space. + if ( pPrev == 0x0 ) { + mHeapFree = * (hpos*) (pCurr + FPOS); + assert ( mHeapFree >= -1 ); + } else { + * (hpos*) (pPrev+FPOS) = * (hpos*) (pCurr+FPOS); + } + pos = pCurr-mHeap; + ret = *pCurr; + } else { + // Heap full, no free space. Expand heap. + pos = HeapExpand ( size, ret ); + mHeapNum += ret; + } + } + } + + assert ( pos >= 0 && pos <= mHeapNum ); + memset ( mHeap+pos, 0, size*sizeof(hval) ); + return pos; +} + +void GeomX::HeapAddFree ( hpos pos, int size ) +{ + // memset ( mHeap+pos, 0xFF, size*sizeof(hval) ); + + if ( pos < mHeapFree || mHeapFree == -1 ) { + // Lowest position. Insert at head of heap. + * (hpos*) (mHeap+pos) = size; + * (hpos*) (mHeap+pos + FPOS) = mHeapFree; + mHeapFree = pos; + if ( mHeapFree != -1 && *(hpos*) (mHeap+mHeapFree+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pHeapFree, %d\n", pos ); error.Exit (); } + + assert ( mHeapFree >= -1 ); + } else { + hval* pCurr = mHeap + pos; + hval* pPrev = 0x0; + hval* pNext = mHeap + mHeapFree; + + if ( pCurr == pNext ) { // Freeing the first block + mHeapFree = * (hpos*) (pCurr + FPOS); + * (hpos*) (mHeap+mHeapFree + FPOS) = 0xFFFFFFFF; + * (hpos*) (pCurr + FPOS) = 0xFFFFFFFF; + * (hpos*) pCurr = 0xFFFFFFFF; + return; + + } + + // Find first block greater than new free pos. + while ( pNext < pCurr && pNext != mHeap-1 ) { + pPrev = pNext; + pNext = mHeap + * (hpos*) (pNext + FPOS); + } + + int x = 0; + if ( pPrev + *(pPrev) == pCurr ) { // Prev block touches current one (expand previous) + * (hpos*) pPrev += size; // - prev.size = prev.size + curr.size + x=1; + + } else if ( pCurr + size == pNext && pNext != mHeap-1 ) { // Curr block touches next one (expand current block) + * (hpos*) (pPrev + FPOS) = pos; // - prev.next = curr + * (hpos*) (pCurr + FPOS) = * (hpos*) (pNext + FPOS); // - curr.next = next.next + * (hpos*) pCurr = size + * (hpos*) pNext; // - curr.size = size + next.size + * (hpos*) (pNext) = 0xFFFFFFFF; // - curr = null + * (hpos*) (pNext + FPOS) = 0xFFFFFFFF; // - curr.next = null + x=2; + + } else { // Otherwise (linked list insert) + * (hpos*) (pPrev + FPOS) = pos; // - prev.next = curr + if ( pNext != mHeap-1 ) + * (hpos*) (pCurr + FPOS) = pNext - mHeap; // - curr.next = next + else + * (hpos*) (pCurr + FPOS) = 0xFFFFFFFF; // - curr.next = null (no next node) + * (hpos*) pCurr = size; // - curr.size = size + x=3; + } + if ( pCurr !=mHeap-1 && *(hpos*) (pCurr+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pCurr, %d, %d\n", x, pos ); error.Exit (); } + if ( pPrev !=mHeap-1 && *(hpos*) (pPrev+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pPrev, %d, %d\n", x, pos ); error.Exit (); } + if ( pNext !=mHeap-1 && *(hpos*) (pNext+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pNext, %d, %d\n", x, pos ); error.Exit (); } + if ( *(hpos*) (mHeap+mHeapFree+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pHeapFree, %d, %d\n", x, pos ); error.Exit (); } + + // -- check for bugs (remove eventually) + pNext = mHeap + mHeapFree; + while ( pNext != mHeap-1 ) { + pPrev = pNext; + pNext = mHeap + * (hpos*) (pNext + FPOS); + if ( pNext < pPrev && pNext != mHeap-1 ) { + error.PrintF ( "geomx", "ERROR: Heap free space out of order. %d, %d\n", x, pos ); + error.Exit (); + } + } + //--- + } + } + +void GeomX::ClearRefs ( hList& list ) +{ + list.cnt = 0; + list.max = 0; + list.pos = 0; +} + +hval GeomX::AddRef ( hval r, hList& list, hval delta ) +{ + if ( list.max == 0 ) { + list.cnt = 1; + list.pos = HeapAlloc ( LIST_INIT, list.max ); + *(mHeap + list.pos) = r+delta; + } else { + if ( list.cnt >= list.max ) { + int siz = list.max; + hpos new_pos = HeapAlloc ( siz+LIST_INIT, list.max ); // Alloc new location + //printf ( "MOVE %d -> %d\n", list.pos, new_pos ); + memcpy ( mHeap+new_pos, mHeap+list.pos, list.cnt*sizeof(hval) ); // Copy data to new location + HeapAddFree ( list.pos, siz ); // Free old location + list.pos = new_pos; + + } + *(mHeap + list.pos + list.cnt) = r+delta; + list.cnt++; + } + return list.pos; +} \ No newline at end of file diff --git a/Extras/sph/common/geomx.h b/Extras/sph/common/geomx.h new file mode 100644 index 0000000..e1f20f6 --- /dev/null +++ b/Extras/sph/common/geomx.h @@ -0,0 +1,125 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEF_GEOM + #define DEF_GEOM + + #include + + #define HEAP_MAX 2147483640 // largest heap size (range of hpos) + + #define ELEM_MAX 2147483640 // largest number of elements in a buffer (range of hval) + //#define ELEM_MAX 32768 // largest number of elements in a buffer (range of hval) + + #define BUF_UNDEF 255 + + #define FPOS 2 // free position offsets + typedef unsigned char uchar; + typedef unsigned short ushort; + typedef signed int hpos; // pointers into heap + typedef signed int hval; // values in heap + typedef hval href; // values are typically references + struct hList { + ushort cnt; + ushort max; + hpos pos; + }; + + class GeomAttr { + public: + GeomAttr() { name = ""; buf = 0; stride = 0; offset = 0; } + std::string name; + ushort buf; + ushort stride; + ushort offset; + }; + + class GeomBuf { + public: + GeomBuf() { dtype = 0; num = 0; max = 0; stride = 0; data = 0x0; } + uchar dtype; + hval num; + hval max; + long size; + ushort stride; + char* data; + }; + + class GeomX { + public: + GeomX (); + + // virtual objType GetType () { return 'geom'; } + + // Basic geometry setup + void FreeBuffers (); + void ClearAttributes (); + void AddHeap ( int max ); + int CopyBuffer ( uchar bdest, uchar bsrc, GeomX& src ); + void CopyBuffers ( GeomX& src ); + void CopyAttributes ( GeomX& src ); + void CopyHeap ( GeomX& src ); + void ResetBuffer ( uchar b, int n ); + void ResetHeap (); + int AddBuffer ( uchar typ, ushort stride, int max ); + int AddAttribute ( uchar b, std::string name, ushort stride ); + int AddAttribute ( uchar b, std::string name, ushort stride, bool bExtend ); + int GetAttribute ( std::string name ); + int GetAttrOffset ( std::string name ); + int NumElem ( uchar b ) { if ( b==BUF_UNDEF) return 0; else return mBuf[b].num; } + int MaxElem ( uchar b ) { if ( b==BUF_UNDEF) return 0; else return mBuf[b].max; } + int GetStride ( uchar b ) { return mBuf[b].stride; } + char* GetElem ( uchar b, int n ) { return mBuf[b].data + n*mBuf[b].stride; } + char* RandomElem ( uchar b, href& ndx ); + char* AddElem ( uchar b, href& pos ); + int AddElem ( uchar b, char* data ); + bool DelElem ( uchar b, int n ); + char* GetStart ( uchar b ) { return mBuf[b].data; } + char* GetEnd ( uchar b ) { return mBuf[b].data + mBuf[b].num*mBuf[b].stride; } + GeomBuf* GetBuffer ( uchar b ) { return &mBuf[b]; } + GeomAttr* GetAttribute ( int n ) { return &mAttribute[n]; } + int GetNumBuf () { return (int) mBuf.size(); } + int GetNumAttr () { return (int) mAttribute.size(); } + hval* GetHeap ( hpos& num, hpos& max, hpos& free ); + + int GetSize (); + + /*int AddRef ( int b, int n, int ref, ushort listpos ); + int AddRef ( int b, int n, int ref, bool bUseHeap, ushort listpos, ushort width );*/ + void ClearRefs ( hList& list ); + hval AddRef ( hval r, hList& list, hval delta ); + hpos HeapAlloc ( ushort size, ushort& ret ); + hpos HeapExpand ( ushort size, ushort& ret ); + void HeapAddFree ( hpos pos, int size ); + + + protected: + std::vector< GeomBuf > mBuf; + std::vector< GeomAttr > mAttribute; + + hpos mHeapNum; + hpos mHeapMax; + hpos mHeapFree; + hval* mHeap; + }; + +#endif diff --git a/Extras/sph/common/gl_helper.cpp b/Extras/sph/common/gl_helper.cpp new file mode 100644 index 0000000..dce10d1 --- /dev/null +++ b/Extras/sph/common/gl_helper.cpp @@ -0,0 +1,402 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "common_defs.h" +#include "gl_helper.h" + +#include + + +// Shadow Light +float light_proj[16]; +float light_x, light_y, light_z; +float light_tox, light_toy, light_toz; +float light_mfov; + +// Fonts +void *font = GLUT_BITMAP_8_BY_13; +void *fonts[] = {GLUT_BITMAP_9_BY_15, + GLUT_BITMAP_TIMES_ROMAN_10, + GLUT_BITMAP_TIMES_ROMAN_24}; +// Timing +mint::Time tm_last; +int tm_cnt; +float tm_fps; + +GLuint glSphere = 65535; +float glRadius = 0.0; + +void setSphereRadius ( float r ) +{ + if ( glRadius == r ) return; + glRadius = r; + + // GL sphere + if ( glSphere != 65535 ) glDeleteLists ( glSphere, 1 ); + glSphere = glGenLists ( 1 ); + float x, y, z, x1, y1, z1; + glNewList ( glSphere, GL_COMPILE ); + glBegin ( GL_TRIANGLE_STRIP ); + for ( float tilt=-90; tilt <= 90; tilt += 10.0) { + for ( float ang=0; ang <= 360; ang += 30.0) { + x = sin ( ang*DEGtoRAD) * cos ( tilt*DEGtoRAD ); + y = cos ( ang*DEGtoRAD) * cos ( tilt*DEGtoRAD ); + z = sin ( tilt*DEGtoRAD ) ; + x1 = sin ( ang*DEGtoRAD) * cos ( (tilt+10.0)*DEGtoRAD ) ; + y1 = cos ( ang*DEGtoRAD) * cos ( (tilt+10.0)*DEGtoRAD ) ; + z1 = sin ( (tilt+10.0)*DEGtoRAD ); + glNormal3f ( x, y, z ); glVertex3f ( x*r, y*r, z*r ); + glNormal3f ( x1, y1, z1 ); glVertex3f ( x1*r, y1*r, z1*r ); + } + } + glEnd (); + glEndList (); +} + +void drawSphere () +{ + if ( glRadius == 0.0 ) setSphereRadius ( 1.0 ); + glCallList ( glSphere ); +} + +// Check if there have been any openGL problems +void checkOpenGL () +{ + GLenum errCode = glGetError(); + if (errCode != GL_NO_ERROR) { + const GLubyte* errString = gluErrorString(errCode); + fprintf( stderr, "OpenGL error: %s\n", errString ); + } +} + +void drawText ( int x, int y, char* msg) +{ + int len, i; + glRasterPos2f(x, y); + len = (int) strlen(msg); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, msg[i]); +} + +void drawGrid () +{ + glColor3f ( 0.3, 0.3, 0.3 ); + glBegin ( GL_LINES ); + for (float x=-40; x<=40.0; x+=10.0 ) { + glVertex3f ( x, -40.0, 0 ); + glVertex3f ( x, 40.0, 0 ); + } + for (float y=-40; y<=40.0; y+=10.0 ) { + glVertex3f ( -40.0, y, 0 ); + glVertex3f ( 40.0, y, 0 ); + } + glEnd (); +} + +void measureFPS () +{ + // Measure FPS + mint::Time tm_elaps; + if ( ++tm_cnt > 5 ) { + tm_elaps.SetSystemTime ( ACC_NSEC ); // get current sytem time - accurate to 1 ns + tm_elaps = tm_elaps - tm_last; // get elapsed time from 5 frames ago + tm_fps = 5.0 * 1000.0 / tm_elaps.GetMSec (); // compute fps + tm_cnt = 0; // reset frame counter + tm_last.SetSystemTime ( ACC_NSEC ); + } +} + +void checkFrameBuffers () +{ + GLenum status; + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + switch(status) { + case GL_FRAMEBUFFER_COMPLETE_EXT: printf ( "FBO complete\n" ); break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: printf ( "FBO format unsupported\n"); break; + default: printf ( "Unknown FBO error\n"); + } +} + +void disableShadows () + { + glDisable ( GL_TEXTURE_2D ); + + glActiveTextureARB( GL_TEXTURE1_ARB ); + glBindTexture ( GL_TEXTURE_2D, 0 ); + glDisable ( GL_TEXTURE_GEN_S ); + glDisable ( GL_TEXTURE_GEN_T ); + glDisable ( GL_TEXTURE_GEN_R ); + glDisable ( GL_TEXTURE_GEN_Q ); + + glActiveTextureARB( GL_TEXTURE2_ARB ); + glBindTexture ( GL_TEXTURE_2D, 0 ); + glDisable ( GL_TEXTURE_GEN_S ); + glDisable ( GL_TEXTURE_GEN_T ); + glDisable ( GL_TEXTURE_GEN_R ); + glDisable ( GL_TEXTURE_GEN_Q ); + } + +#ifdef USE_SHADOWS + // Materials & Textures + GLuint shadow1_id = 0; // display buffer shadows + GLuint shadow2_id = 0; // display buffer shadows + + // Frame buffer + GLuint frameBufferObject = 0; // frame buffer shadows + + void createFrameBuffer () + { + //Generate the frame buffer object + glGenFramebuffersEXT (1, &frameBufferObject); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferObject); // Turn on frame buffer object + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow1_id, 0); + glDrawBuffer (GL_NONE); // Set Draw & ReadBuffer to none since we're rendering depth only + glReadBuffer (GL_NONE); + checkFrameBuffers (); // Check completeness of frame buffer object (no need for stencil and depth attachement) + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); // Turn off frame buffer object + } + + void createShadowTextures () + { + // Create depth texture maps + glActiveTextureARB( GL_TEXTURE1_ARB ); + glGenTextures( 1, &shadow1_id ); + glBindTexture ( GL_TEXTURE_2D, shadow1_id ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + //-- sets region outside shadow to 0 + //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_ARB ); + //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_ARB ); + + //-- sets region outside shadow to 1 (border edge color) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + + glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D ( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0); + + glActiveTextureARB( GL_TEXTURE2_ARB ); + glGenTextures( 1, &shadow2_id ); + glBindTexture ( GL_TEXTURE_2D, shadow2_id ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_ARB ); + //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_ARB ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D ( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0); + } + + void computeLightMatrix ( int n, int tx, int ty ) + { + int lnum = n; + // Construct projective texturing matrix + + // S - light bias matrix + glMatrixMode ( GL_MODELVIEW ); + glLoadIdentity (); + glTranslatef ( 0.5, 0.5, 0.5 ); + glScalef ( 0.5, 0.5, 0.5 ); + // Plight - light projection matrix + gluPerspective ( light_mfov*2.0, float(tx) / ty, LIGHT_NEAR, LIGHT_FAR ); + // L^-1 - light view inverse matrix + gluLookAt ( light_x, light_y, light_z, light_tox, light_toy, light_toz, 0, 0, 1); + glPushMatrix (); + glGetFloatv ( GL_MODELVIEW_MATRIX, light_proj ); + glPopMatrix (); + + } + + void renderDepthMap_Clear ( float wx, float wy ) + { + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferObject); + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow1_id, 0); + glActiveTextureARB( GL_TEXTURE1_ARB ); // TEXTURE1 = shadow map stage + glViewport (1, 1, TEX_SIZE-2, TEX_SIZE-2); // Note: Avoid artifact cause by drawing into border pixels + glClear ( GL_DEPTH_BUFFER_BIT ); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); + glViewport ( 0, 0, (GLsizei) wx, (GLsizei) wy ); + } + + void renderDepthMap_FrameBuffer ( int n, float wx, float wy ) + { + float vmat[16]; + + computeLightMatrix ( n, TEX_SIZE, TEX_SIZE ); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferObject); + + if ( n == 0 ) { + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow1_id, 0); + } else { + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow2_id, 0); + } + + if ( n == 0 ) glActiveTextureARB( GL_TEXTURE1_ARB ); // TEXTURE1 = shadow map stage + else glActiveTextureARB( GL_TEXTURE2_ARB ); // TEXTURE2 = shadow map stage + + glViewport (1, 1, TEX_SIZE-2, TEX_SIZE-2); // Note: Avoid artifact cause by drawing into border pixels + glClear ( GL_DEPTH_BUFFER_BIT ); + glLoadIdentity(); + + // Plight - projection matrix of light + glMatrixMode ( GL_PROJECTION ); // Setup projection for depth-map rendering + glLoadIdentity (); + gluPerspective ( light_mfov*2.0, float(TEX_SIZE) / TEX_SIZE, LIGHT_NEAR, LIGHT_FAR ); + + // L^-1 - light view matrix (gluLookAt computes inverse) + glMatrixMode ( GL_MODELVIEW); // Setup view for depth-map rendering + glLoadIdentity (); + gluLookAt ( light_x, light_y, light_z, light_tox, light_toy, light_toz, 0, 0, 1); + glPushMatrix (); // Save view matrix for later + glGetFloatv ( GL_MODELVIEW_MATRIX, vmat ); + glPopMatrix (); + + glDisable ( GL_LIGHTING ); + glColor4f ( 1, 1, 1, 1 ); + glShadeModel (GL_FLAT); // No shading (faster) + + glEnable ( GL_CULL_FACE ); + glCullFace ( GL_FRONT ); + + glEnable ( GL_POLYGON_OFFSET_FILL ); + glPolygonOffset ( 50.0, 0.1 ); // Depth bias + + drawScene ( &vmat[0], false ); // Draw scene. + + glDisable ( GL_POLYGON_OFFSET_FILL ); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); + glViewport ( 0, 0, (GLsizei) wx, (GLsizei) wy ); + + //glCullFace (GL_BACK); // Restore render states + //glBindTexture ( GL_TEXTURE_2D, 0); + } + + void renderShadowStage ( int n, float* vmat ) + { + GLfloat pos[4]; + GLfloat row[4]; + + computeLightMatrix ( n, TEX_SIZE, TEX_SIZE ); + if ( n == 0 ) { + glActiveTextureARB( GL_TEXTURE1_ARB ); // TEXTURE1 = shadow map stage #1 + } else { + glActiveTextureARB( GL_TEXTURE2_ARB ); // TEXTURE2 = shadow map stage #2 + } + glEnable ( GL_TEXTURE_2D ); + if ( n == 0 ) glBindTexture ( GL_TEXTURE_2D, shadow1_id ); + else glBindTexture ( GL_TEXTURE_2D, shadow2_id ); + + glMatrixMode( GL_MODELVIEW ); + glLoadMatrixf ( vmat ); + + row[0] = light_proj[0]; row[1] = light_proj[4]; row[2] = light_proj[8]; row[3] = light_proj[12]; + glTexGenfv(GL_S, GL_EYE_PLANE, &row[0] ); + row[0] = light_proj[1]; row[1] = light_proj[5]; row[2] = light_proj[9]; row[3] = light_proj[13]; + glTexGenfv(GL_T, GL_EYE_PLANE, &row[0] ); + row[0] = light_proj[2]; row[1] = light_proj[6]; row[2] = light_proj[10]; row[3] = light_proj[14]; + glTexGenfv(GL_R, GL_EYE_PLANE, &row[0] ); + row[0] = light_proj[3]; row[1] = light_proj[7]; row[2] = light_proj[11]; row[3] = light_proj[15]; + glTexGenfv(GL_Q, GL_EYE_PLANE, &row[0] ); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_TEXTURE_GEN_Q); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE ) ; + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE ) ; + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS ) ; + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT ) ; + + pos[0] = 0.20; + pos[1] = 0.20; + pos[2] = 0.20; + pos[3] = 0.20; + glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &pos[0] ); + } + + void renderShadows ( float* vmat ) + { + GLfloat pos[4]; + + renderShadowStage ( 0, vmat ); + // renderShadowStage ( 1, vmat ); + + glActiveTextureARB( GL_TEXTURE0_ARB ); // Render Tex 0 - Base render + glDisable ( GL_TEXTURE_GEN_S ); + glDisable ( GL_TEXTURE_GEN_T ); + glDisable ( GL_TEXTURE_GEN_R ); + glDisable ( GL_TEXTURE_GEN_Q ); + glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + glEnable ( GL_LIGHTING ); + glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT); + + glEnable ( GL_LIGHT0 ); + pos[0] = light_x; pos[1] = light_y; pos[2] = light_z; pos[3] = 1.0; + glLightfv ( GL_LIGHT0, GL_POSITION, &pos[0] ); + + /* glEnable ( GL_LIGHT1 ); + pos[0] = light[1].x; pos[1] = light[1].y; pos[2] = light[1].z; pos[3] = 1.0; + glLightfv ( GL_LIGHT1, GL_POSITION, &pos[0] );*/ + } + + + + void setShadowLight ( float fx, float fy, float fz, float tx, float ty, float tz, float fov ) + { + light_x = fx; + light_y = fy; + light_z = fz; + light_tox = tx; + light_toy = ty; + light_toz = tz; + light_mfov = fov; + } + + void setShadowLightColor ( float dr, float dg, float db, float sr, float sg, float sb ) + { + GLfloat amb[4] = {0.0,0.0,0.0,1}; + GLfloat dif[4]; + GLfloat spec[4]; + GLfloat pos[4] = {0.0,0.0,0.0, 100.0}; + + glEnable(GL_LIGHT0); + dif[0] = dr; dif[1] = dg; dif[2] = db; dif[3] = 1; + spec[0] = sr; spec[1] = sg; spec[2] = sb; spec[3] = 1; + glLightfv(GL_LIGHT0, GL_AMBIENT, &amb[0] ); + glLightfv(GL_LIGHT0, GL_DIFFUSE, &dif[0] ); + glLightfv(GL_LIGHT0, GL_SPECULAR, &spec[0] ); + } + +#endif diff --git a/Extras/sph/common/gl_helper.h b/Extras/sph/common/gl_helper.h new file mode 100644 index 0000000..ccf402e --- /dev/null +++ b/Extras/sph/common/gl_helper.h @@ -0,0 +1,89 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef GL_HELPER + #define GL_HELPER + + #include "common_defs.h" + + #include + #include + + #ifdef _MSC_VER // Windows + #ifdef USE_SHADOWS + #include + #include + #endif + #include + #else // Linux + #ifdef USE_SHADOWS + #include "GLee.h" + #endif + #include + #include + #endif + + #include "image.h" + #include "mtime.h" + + extern void checkOpenGL (); + extern void drawText ( int x, int y, char* msg); + extern void drawGrid (); + extern void measureFPS (); + + extern mint::Time tm_last; + extern int tm_cnt; + extern float tm_fps; + + + extern void disableShadows (); + extern void checkFrameBuffers (); + + extern GLuint glSphere; + extern float glRadius; + extern void setSphereRadius ( float f ); + extern void drawSphere (); + + #ifdef USE_SHADOWS + extern void setShadowLight ( float fx, float fy, float fz, float tx, float ty, float tz, float fov ); + extern void setShadowLightColor ( float dr, float dg, float db, float sr, float sg, float sb ); + + extern void createFrameBuffer (); + extern void createShadowTextures (); + extern void computeLightMatrix ( int n, int tx, int ty ); + extern void renderDepthMap_Clear ( float wx, float wy ); + extern void renderDepthMap_FrameBuffer ( int n, float wx, float wy ); + extern void renderShadowStage ( int n, float* vmat ); + extern void renderShadows ( float* vmat ); + extern void drawScene ( float* view_mat, bool bShaders ); // provided by user + + extern float light_proj[16]; + extern float light_x, light_y, light_z; + extern float light_tox, light_toy, light_toz; + extern float light_mfov; + + extern GLuint shadow1_id; + extern GLuint shadow2_id; + #endif + + +#endif \ No newline at end of file diff --git a/Extras/sph/common/glext.h b/Extras/sph/common/glext.h new file mode 100644 index 0000000..7a92b57 --- /dev/null +++ b/Extras/sph/common/glext.h @@ -0,0 +1,7139 @@ +#ifndef __glext_h_ +#define __glext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + + Copyright NVIDIA Corporation 2006 + + TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED + *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR + CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR + LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, + OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE + THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. + +******************************************************************************/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#ifndef GLAPIENTRY +# ifdef _WIN32 +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) /* Mimic */ +# define GLAPIENTRY __stdcall +# else +# define GLAPIENTRY +# endif +# else +# define GLAPIENTRY +# endif +#endif + +#ifndef GLAPI +# define GLAPI extern +#endif + +#ifndef GLAPIENTRYP +# define GLAPIENTRYP GLAPIENTRY * +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +/* glext.h last updated 2005/06/06 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define GL_GLEXT_VERSION 28 + +#ifndef GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +#ifndef GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#endif + +#ifndef GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#endif + +#ifndef GL_VERSION_1_5 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#endif + +#ifndef GL_VERSION_2_0 +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#endif + +#ifndef GL_VERSION_2_1 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#endif + +#ifndef GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_env_add +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_point_parameters +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +#ifndef GL_ARB_shadow +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +#ifndef GL_ARB_window_pos +#endif + +#ifndef GL_ARB_vertex_program +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +#ifndef GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +#endif + +#ifndef GL_ARB_shader_objects +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#endif + +#ifndef GL_ARB_point_sprite +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_HALF_FLOAT_ARB 0x140B +#endif + +#ifndef GL_ARB_texture_float +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif + +#ifndef GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#endif + +#ifndef GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_EXT_misc_attribute +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_EXT_blend_logic_op +#endif + +#ifndef GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_EXT_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_INGR_palette_buffer +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_texture +#endif + +#ifndef GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +/* reuse GL_FRAGMENT_DEPTH_EXT */ +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +#ifndef GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_texture_scissor +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_env_add +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* reuse GL_TEXTURE0_ARB */ +/* reuse GL_TEXTURE1_ARB */ +/* reuse GL_ZERO */ +/* reuse GL_NONE */ +/* reuse GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* reuse GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_blend_square +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#endif + +#ifndef GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_NV_evaluators +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#endif + +#ifndef GL_NV_texture_compression_vtc +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +#ifndef GL_NV_texture_shader +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_vertex_program +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +#ifndef GL_OML_interlace +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +#ifndef GL_OML_subsample +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +#ifndef GL_OML_resample +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#endif + +#ifndef GL_ATI_element_array +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#endif + +#ifndef GL_SUN_mesh_array +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +#ifndef GL_NV_occlusion_query +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#endif + +#ifndef GL_NV_point_sprite +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +#ifndef GL_NV_vertex_program1_1 +#endif + +#ifndef GL_EXT_shadow_funcs +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +#ifndef GL_APPLE_element_array +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#endif + +#ifndef GL_APPLE_fence +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +#ifndef GL_S3_s3tc +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +#ifndef GL_ATI_texture_float +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +#ifndef GL_NV_float_buffer +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +#ifndef GL_NV_fragment_program +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif + +#ifndef GL_NV_half_float +#define GL_HALF_FLOAT_NV 0x140B +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#endif + +#ifndef GL_NV_primitive_restart +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +#ifndef GL_NV_vertex_program2 +#endif + +#ifndef GL_ATI_map_object_buffer +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#endif + +#ifndef GL_OES_read_format +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#endif + +#ifndef GL_MESA_pack_invert +#define GL_PACK_INVERT_MESA 0x8758 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif + +#ifndef GL_NV_fragment_program_option +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif + +#ifndef GL_NV_vertex_program2_option +/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ +/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ +#endif + +#ifndef GL_NV_vertex_program3 +/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX_EXT 0x8D45 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#endif + +#ifndef GL_GREMEDY_string_marker +#endif + +#ifndef GL_EXT_Cg_shader +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F +#endif + +#ifndef GL_EXT_timer_query +#define GL_TIME_ELAPSED_EXT 0x88BF +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif + +#ifndef GL_EXT_packed_float +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif + +#ifndef GL_EXT_texture_array +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +/* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ +#endif + +#ifndef GL_EXT_texture_integer +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif + +#ifndef GL_NV_transform_feedback +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8D57 +#define GL_MAX_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E11 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E13 +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + +/*************************************************************/ + +#include +#ifndef GL_VERSION_2_0 +/* GL type for program/shader text */ +typedef char GLchar; /* native character */ +#endif + +#ifndef GL_VERSION_1_5 +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +#endif + +#ifndef GL_ARB_vertex_buffer_object +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#endif + +#ifndef GL_ARB_shader_objects +/* GL types for handling shader object handles and program/shader text */ +typedef char GLcharARB; /* native character */ +typedef unsigned int GLhandleARB; /* shader object handle */ +#endif + +/* GL types for "half" precision (s10e5) float data in host memory */ +#ifndef GL_ARB_half_float_pixel +typedef unsigned short GLhalfARB; +#endif + +#ifndef GL_NV_half_float +typedef unsigned short GLhalfNV; +#endif + +#ifndef GL_EXT_timer_query +#ifndef GL_COMPILER_LACKS_64BIT_INT +#if defined(__GNUC__) || defined(__arm) || defined(__IAR_SYSTEMS_ICC__) || defined(__ghs__) || defined(_WIN64) +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +#else +typedef signed __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +#endif +#endif +#endif + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +GLAPI void GLAPIENTRY glBlendEquation (GLenum); +GLAPI void GLAPIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void GLAPIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); +GLAPI void GLAPIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); +GLAPI void GLAPIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); +GLAPI void GLAPIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void GLAPIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void GLAPIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void GLAPIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +GLAPI void GLAPIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void GLAPIENTRY glMinmax (GLenum, GLenum, GLboolean); +GLAPI void GLAPIENTRY glResetHistogram (GLenum); +GLAPI void GLAPIENTRY glResetMinmax (GLenum); +GLAPI void GLAPIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (GLAPIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (GLAPIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (GLAPIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (GLAPIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glActiveTexture (GLenum); +GLAPI void GLAPIENTRY glClientActiveTexture (GLenum); +GLAPI void GLAPIENTRY glMultiTexCoord1d (GLenum, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord1f (GLenum, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord1i (GLenum, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord1iv (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord1s (GLenum, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord2iv (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord3iv (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord4iv (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glLoadTransposeMatrixf (const GLfloat *); +GLAPI void GLAPIENTRY glLoadTransposeMatrixd (const GLdouble *); +GLAPI void GLAPIENTRY glMultTransposeMatrixf (const GLfloat *); +GLAPI void GLAPIENTRY glMultTransposeMatrixd (const GLdouble *); +GLAPI void GLAPIENTRY glSampleCoverage (GLclampf, GLboolean); +GLAPI void GLAPIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (GLAPIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (GLAPIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (GLAPIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (GLAPIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); +GLAPI void GLAPIENTRY glFogCoordf (GLfloat); +GLAPI void GLAPIENTRY glFogCoordfv (const GLfloat *); +GLAPI void GLAPIENTRY glFogCoordd (GLdouble); +GLAPI void GLAPIENTRY glFogCoorddv (const GLdouble *); +GLAPI void GLAPIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void GLAPIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +GLAPI void GLAPIENTRY glPointParameterf (GLenum, GLfloat); +GLAPI void GLAPIENTRY glPointParameterfv (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glPointParameteri (GLenum, GLint); +GLAPI void GLAPIENTRY glPointParameteriv (GLenum, const GLint *); +GLAPI void GLAPIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); +GLAPI void GLAPIENTRY glSecondaryColor3bv (const GLbyte *); +GLAPI void GLAPIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glSecondaryColor3dv (const GLdouble *); +GLAPI void GLAPIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glSecondaryColor3fv (const GLfloat *); +GLAPI void GLAPIENTRY glSecondaryColor3i (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glSecondaryColor3iv (const GLint *); +GLAPI void GLAPIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glSecondaryColor3sv (const GLshort *); +GLAPI void GLAPIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); +GLAPI void GLAPIENTRY glSecondaryColor3ubv (const GLubyte *); +GLAPI void GLAPIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glSecondaryColor3uiv (const GLuint *); +GLAPI void GLAPIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); +GLAPI void GLAPIENTRY glSecondaryColor3usv (const GLushort *); +GLAPI void GLAPIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glWindowPos2d (GLdouble, GLdouble); +GLAPI void GLAPIENTRY glWindowPos2dv (const GLdouble *); +GLAPI void GLAPIENTRY glWindowPos2f (GLfloat, GLfloat); +GLAPI void GLAPIENTRY glWindowPos2fv (const GLfloat *); +GLAPI void GLAPIENTRY glWindowPos2i (GLint, GLint); +GLAPI void GLAPIENTRY glWindowPos2iv (const GLint *); +GLAPI void GLAPIENTRY glWindowPos2s (GLshort, GLshort); +GLAPI void GLAPIENTRY glWindowPos2sv (const GLshort *); +GLAPI void GLAPIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glWindowPos3dv (const GLdouble *); +GLAPI void GLAPIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glWindowPos3fv (const GLfloat *); +GLAPI void GLAPIENTRY glWindowPos3i (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glWindowPos3iv (const GLint *); +GLAPI void GLAPIENTRY glWindowPos3s (GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glWindowPos3sv (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +#endif + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGenQueries (GLsizei, GLuint *); +GLAPI void GLAPIENTRY glDeleteQueries (GLsizei, const GLuint *); +GLAPI GLboolean GLAPIENTRY glIsQuery (GLuint); +GLAPI void GLAPIENTRY glBeginQuery (GLenum, GLuint); +GLAPI void GLAPIENTRY glEndQuery (GLenum); +GLAPI void GLAPIENTRY glGetQueryiv (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); +GLAPI void GLAPIENTRY glBindBuffer (GLenum, GLuint); +GLAPI void GLAPIENTRY glDeleteBuffers (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenBuffers (GLsizei, GLuint *); +GLAPI GLboolean GLAPIENTRY glIsBuffer (GLuint); +GLAPI void GLAPIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); +GLAPI void GLAPIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); +GLAPI void GLAPIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); +GLAPI GLvoid* GLAPIENTRY glMapBuffer (GLenum, GLenum); +GLAPI GLboolean GLAPIENTRY glUnmapBuffer (GLenum); +GLAPI void GLAPIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (GLAPIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GLAPIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GLAPIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (GLAPIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (GLAPIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (GLAPIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +typedef void (GLAPIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +typedef GLvoid* (GLAPIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendEquationSeparate (GLenum, GLenum); +GLAPI void GLAPIENTRY glDrawBuffers (GLsizei, const GLenum *); +GLAPI void GLAPIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); +GLAPI void GLAPIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); +GLAPI void GLAPIENTRY glStencilMaskSeparate (GLenum, GLuint); +GLAPI void GLAPIENTRY glAttachShader (GLuint, GLuint); +GLAPI void GLAPIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *); +GLAPI void GLAPIENTRY glCompileShader (GLuint); +GLAPI GLuint GLAPIENTRY glCreateProgram (void); +GLAPI GLuint GLAPIENTRY glCreateShader (GLenum); +GLAPI void GLAPIENTRY glDeleteProgram (GLuint); +GLAPI void GLAPIENTRY glDeleteShader (GLuint); +GLAPI void GLAPIENTRY glDetachShader (GLuint, GLuint); +GLAPI void GLAPIENTRY glDisableVertexAttribArray (GLuint); +GLAPI void GLAPIENTRY glEnableVertexAttribArray (GLuint); +GLAPI void GLAPIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +GLAPI void GLAPIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +GLAPI void GLAPIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); +GLAPI GLint GLAPIENTRY glGetAttribLocation (GLuint, const GLchar *); +GLAPI void GLAPIENTRY glGetProgramiv (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI void GLAPIENTRY glGetShaderiv (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI void GLAPIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI GLint GLAPIENTRY glGetUniformLocation (GLuint, const GLchar *); +GLAPI void GLAPIENTRY glGetUniformfv (GLuint, GLint, GLfloat *); +GLAPI void GLAPIENTRY glGetUniformiv (GLuint, GLint, GLint *); +GLAPI void GLAPIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *); +GLAPI void GLAPIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean GLAPIENTRY glIsProgram (GLuint); +GLAPI GLboolean GLAPIENTRY glIsShader (GLuint); +GLAPI void GLAPIENTRY glLinkProgram (GLuint); +GLAPI void GLAPIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); +GLAPI void GLAPIENTRY glUseProgram (GLuint); +GLAPI void GLAPIENTRY glUniform1f (GLint, GLfloat); +GLAPI void GLAPIENTRY glUniform2f (GLint, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glUniform1i (GLint, GLint); +GLAPI void GLAPIENTRY glUniform2i (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glUniform3i (GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform1iv (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniform2iv (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniform3iv (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniform4iv (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void GLAPIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void GLAPIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void GLAPIENTRY glValidateProgram (GLuint); +GLAPI void GLAPIENTRY glVertexAttrib1d (GLuint, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib1dv (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib1f (GLuint, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib1fv (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib1s (GLuint, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib1sv (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib2dv (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib2fv (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib2sv (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib3dv (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib3fv (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib3sv (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *); +GLAPI void GLAPIENTRY glVertexAttrib4Niv (GLuint, const GLint *); +GLAPI void GLAPIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void GLAPIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *); +GLAPI void GLAPIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *); +GLAPI void GLAPIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *); +GLAPI void GLAPIENTRY glVertexAttrib4bv (GLuint, const GLbyte *); +GLAPI void GLAPIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib4dv (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib4fv (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib4iv (GLuint, const GLint *); +GLAPI void GLAPIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib4sv (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *); +GLAPI void GLAPIENTRY glVertexAttrib4uiv (GLuint, const GLuint *); +GLAPI void GLAPIENTRY glVertexAttrib4usv (GLuint, const GLushort *); +GLAPI void GLAPIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (GLAPIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GLAPIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (GLAPIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (GLAPIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GLAPIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GLAPIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GLAPIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GLAPIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); +typedef GLint (GLAPIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GLAPIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GLAPIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (GLAPIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (GLAPIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (GLAPIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); +typedef void (GLAPIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void GLAPIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void GLAPIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void GLAPIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void GLAPIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void GLAPIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glActiveTextureARB (GLenum); +GLAPI void GLAPIENTRY glClientActiveTextureARB (GLenum); +GLAPI void GLAPIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord1iARB (GLenum, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord1sARB (GLenum, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); +GLAPI void GLAPIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glLoadTransposeMatrixfARB (const GLfloat *); +GLAPI void GLAPIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +GLAPI void GLAPIENTRY glMultTransposeMatrixfARB (const GLfloat *); +GLAPI void GLAPIENTRY glMultTransposeMatrixdARB (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (GLAPIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (GLAPIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (GLAPIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glSampleCoverageARB (GLclampf, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); +#endif + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#endif + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPointParameterfARB (GLenum, GLfloat); +GLAPI void GLAPIENTRY glPointParameterfvARB (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glWeightbvARB (GLint, const GLbyte *); +GLAPI void GLAPIENTRY glWeightsvARB (GLint, const GLshort *); +GLAPI void GLAPIENTRY glWeightivARB (GLint, const GLint *); +GLAPI void GLAPIENTRY glWeightfvARB (GLint, const GLfloat *); +GLAPI void GLAPIENTRY glWeightdvARB (GLint, const GLdouble *); +GLAPI void GLAPIENTRY glWeightubvARB (GLint, const GLubyte *); +GLAPI void GLAPIENTRY glWeightusvARB (GLint, const GLushort *); +GLAPI void GLAPIENTRY glWeightuivARB (GLint, const GLuint *); +GLAPI void GLAPIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glVertexBlendARB (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (GLAPIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glCurrentPaletteMatrixARB (GLint); +GLAPI void GLAPIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); +GLAPI void GLAPIENTRY glMatrixIndexusvARB (GLint, const GLushort *); +GLAPI void GLAPIENTRY glMatrixIndexuivARB (GLint, const GLuint *); +GLAPI void GLAPIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (GLAPIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (GLAPIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (GLAPIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (GLAPIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#endif + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#endif + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glWindowPos2dARB (GLdouble, GLdouble); +GLAPI void GLAPIENTRY glWindowPos2dvARB (const GLdouble *); +GLAPI void GLAPIENTRY glWindowPos2fARB (GLfloat, GLfloat); +GLAPI void GLAPIENTRY glWindowPos2fvARB (const GLfloat *); +GLAPI void GLAPIENTRY glWindowPos2iARB (GLint, GLint); +GLAPI void GLAPIENTRY glWindowPos2ivARB (const GLint *); +GLAPI void GLAPIENTRY glWindowPos2sARB (GLshort, GLshort); +GLAPI void GLAPIENTRY glWindowPos2svARB (const GLshort *); +GLAPI void GLAPIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glWindowPos3dvARB (const GLdouble *); +GLAPI void GLAPIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glWindowPos3fvARB (const GLfloat *); +GLAPI void GLAPIENTRY glWindowPos3iARB (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glWindowPos3ivARB (const GLint *); +GLAPI void GLAPIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glWindowPos3svARB (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#endif + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glVertexAttrib1dARB (GLuint, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib1fARB (GLuint, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib1sARB (GLuint, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); +GLAPI void GLAPIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); +GLAPI void GLAPIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void GLAPIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); +GLAPI void GLAPIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); +GLAPI void GLAPIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); +GLAPI void GLAPIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); +GLAPI void GLAPIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); +GLAPI void GLAPIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); +GLAPI void GLAPIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); +GLAPI void GLAPIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); +GLAPI void GLAPIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glEnableVertexAttribArrayARB (GLuint); +GLAPI void GLAPIENTRY glDisableVertexAttribArrayARB (GLuint); +GLAPI void GLAPIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glBindProgramARB (GLenum, GLuint); +GLAPI void GLAPIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenProgramsARB (GLsizei, GLuint *); +GLAPI void GLAPIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void GLAPIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void GLAPIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void GLAPIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void GLAPIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); +GLAPI void GLAPIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean GLAPIENTRY glIsProgramARB (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); +typedef void (GLAPIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (GLAPIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (GLAPIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); +#endif + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBindBufferARB (GLenum, GLuint); +GLAPI void GLAPIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenBuffersARB (GLsizei, GLuint *); +GLAPI GLboolean GLAPIENTRY glIsBufferARB (GLuint); +GLAPI void GLAPIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); +GLAPI void GLAPIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); +GLAPI void GLAPIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); +GLAPI GLvoid* GLAPIENTRY glMapBufferARB (GLenum, GLenum); +GLAPI GLboolean GLAPIENTRY glUnmapBufferARB (GLenum); +GLAPI void GLAPIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (GLAPIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (GLAPIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (GLAPIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); +typedef void (GLAPIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); +typedef GLvoid* (GLAPIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGenQueriesARB (GLsizei, GLuint *); +GLAPI void GLAPIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); +GLAPI GLboolean GLAPIENTRY glIsQueryARB (GLuint); +GLAPI void GLAPIENTRY glBeginQueryARB (GLenum, GLuint); +GLAPI void GLAPIENTRY glEndQueryARB (GLenum); +GLAPI void GLAPIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); +typedef void (GLAPIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GLAPIENTRYP PFNGLISQUERYARBPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDeleteObjectARB (GLhandleARB); +GLAPI GLhandleARB GLAPIENTRY glGetHandleARB (GLenum); +GLAPI void GLAPIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); +GLAPI GLhandleARB GLAPIENTRY glCreateShaderObjectARB (GLenum); +GLAPI void GLAPIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); +GLAPI void GLAPIENTRY glCompileShaderARB (GLhandleARB); +GLAPI GLhandleARB GLAPIENTRY glCreateProgramObjectARB (void); +GLAPI void GLAPIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); +GLAPI void GLAPIENTRY glLinkProgramARB (GLhandleARB); +GLAPI void GLAPIENTRY glUseProgramObjectARB (GLhandleARB); +GLAPI void GLAPIENTRY glValidateProgramARB (GLhandleARB); +GLAPI void GLAPIENTRY glUniform1fARB (GLint, GLfloat); +GLAPI void GLAPIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glUniform1iARB (GLint, GLint); +GLAPI void GLAPIENTRY glUniform2iARB (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); +GLAPI void GLAPIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void GLAPIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void GLAPIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void GLAPIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +GLAPI void GLAPIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); +GLAPI GLint GLAPIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); +GLAPI void GLAPIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +GLAPI void GLAPIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); +GLAPI void GLAPIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); +GLAPI void GLAPIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef GLhandleARB (GLAPIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (GLAPIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); +typedef void (GLAPIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (GLAPIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef void (GLAPIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (GLAPIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (GLAPIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (GLAPIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (GLAPIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); +GLAPI void GLAPIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +GLAPI GLint GLAPIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (GLAPIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (GLAPIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#endif + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDrawBuffersARB (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glClampColorARB (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +#endif + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#endif + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (GLAPIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +GLAPI void GLAPIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +GLAPI void GLAPIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); +GLAPI void GLAPIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +GLAPI void GLAPIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void GLAPIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); +GLAPI void GLAPIENTRY glResetHistogramEXT (GLenum); +GLAPI void GLAPIENTRY glResetMinmaxEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void GLAPIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); +GLAPI void GLAPIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void GLAPIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void GLAPIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void GLAPIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (GLAPIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +#endif + +#ifndef GL_EXT_color_matrix +#define GL_EXT_color_matrix 1 +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void GLAPIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPixelTexGenSGIX (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); +GLAPI void GLAPIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); +GLAPI void GLAPIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); +GLAPI void GLAPIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); +GLAPI void GLAPIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean GLAPIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); +GLAPI void GLAPIENTRY glBindTextureEXT (GLenum, GLuint); +GLAPI void GLAPIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenTexturesEXT (GLsizei, GLuint *); +GLAPI GLboolean GLAPIENTRY glIsTextureEXT (GLuint); +GLAPI void GLAPIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (GLAPIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (GLAPIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (GLAPIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (GLAPIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (GLAPIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (GLAPIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (GLAPIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glSampleMaskSGIS (GLclampf, GLboolean); +GLAPI void GLAPIENTRY glSamplePatternSGIS (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glArrayElementEXT (GLint); +GLAPI void GLAPIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); +GLAPI void GLAPIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); +GLAPI void GLAPIENTRY glGetPointervEXT (GLenum, GLvoid* *); +GLAPI void GLAPIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (GLAPIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); +typedef void (GLAPIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendEquationEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#endif + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#endif + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); +GLAPI void GLAPIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glSpriteParameteriSGIX (GLenum, GLint); +GLAPI void GLAPIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPointParameterfEXT (GLenum, GLfloat); +GLAPI void GLAPIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPointParameterfSGIS (GLenum, GLfloat); +GLAPI void GLAPIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint GLAPIENTRY glGetInstrumentsSGIX (void); +GLAPI void GLAPIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); +GLAPI GLint GLAPIENTRY glPollInstrumentsSGIX (GLint *); +GLAPI void GLAPIENTRY glReadInstrumentsSGIX (GLint); +GLAPI void GLAPIENTRY glStartInstrumentsSGIX (void); +GLAPI void GLAPIENTRY glStopInstrumentsSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLint (GLAPIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (GLAPIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (GLAPIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (GLAPIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (GLAPIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (GLAPIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glFrameZoomSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTagSampleBufferSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); +GLAPI void GLAPIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); +GLAPI void GLAPIENTRY glDeformSGIX (GLbitfield); +GLAPI void GLAPIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (GLAPIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (GLAPIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (GLAPIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glReferencePlaneSGIX (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glFlushRasterSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glGetFogFuncSGIS (GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (GLAPIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); +GLAPI void GLAPIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); +GLAPI void GLAPIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glHintPGI (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void GLAPIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); +GLAPI void GLAPIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); +GLAPI void GLAPIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#endif + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glIndexMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glIndexFuncEXT (GLenum, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glLockArraysEXT (GLint, GLsizei); +GLAPI void GLAPIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (GLAPIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glCullParameterdvEXT (GLenum, GLdouble *); +GLAPI void GLAPIENTRY glCullParameterfvEXT (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (GLAPIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); +GLAPI void GLAPIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); +GLAPI void GLAPIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); +GLAPI void GLAPIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); +GLAPI void GLAPIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glFragmentLightModeliSGIX (GLenum, GLint); +GLAPI void GLAPIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); +GLAPI void GLAPIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); +GLAPI void GLAPIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); +GLAPI void GLAPIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glLightEnviSGIX (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glApplyTextureEXT (GLenum); +GLAPI void GLAPIENTRY glTextureLightEXT (GLenum); +GLAPI void GLAPIENTRY glTextureMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (GLAPIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (GLAPIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glAsyncMarkerSGIX (GLuint); +GLAPI GLint GLAPIENTRY glFinishAsyncSGIX (GLuint *); +GLAPI GLint GLAPIENTRY glPollAsyncSGIX (GLuint *); +GLAPI GLuint GLAPIENTRY glGenAsyncMarkersSGIX (GLsizei); +GLAPI void GLAPIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); +GLAPI GLboolean GLAPIENTRY glIsAsyncMarkerSGIX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (GLAPIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (GLAPIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (GLAPIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (GLAPIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (GLAPIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void GLAPIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); +GLAPI void GLAPIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void GLAPIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (GLAPIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); +typedef void (GLAPIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (GLAPIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); +GLAPI void GLAPIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void GLAPIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void GLAPIENTRY glSecondaryColor3bvEXT (const GLbyte *); +GLAPI void GLAPIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glSecondaryColor3dvEXT (const GLdouble *); +GLAPI void GLAPIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glSecondaryColor3fvEXT (const GLfloat *); +GLAPI void GLAPIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glSecondaryColor3ivEXT (const GLint *); +GLAPI void GLAPIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glSecondaryColor3svEXT (const GLshort *); +GLAPI void GLAPIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); +GLAPI void GLAPIENTRY glSecondaryColor3ubvEXT (const GLubyte *); +GLAPI void GLAPIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glSecondaryColor3uivEXT (const GLuint *); +GLAPI void GLAPIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); +GLAPI void GLAPIENTRY glSecondaryColor3usvEXT (const GLushort *); +GLAPI void GLAPIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTextureNormalEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void GLAPIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glFogCoordfEXT (GLfloat); +GLAPI void GLAPIENTRY glFogCoordfvEXT (const GLfloat *); +GLAPI void GLAPIENTRY glFogCoorddEXT (GLdouble); +GLAPI void GLAPIENTRY glFogCoorddvEXT (const GLdouble *); +GLAPI void GLAPIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (GLAPIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void GLAPIENTRY glTangent3bvEXT (const GLbyte *); +GLAPI void GLAPIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glTangent3dvEXT (const GLdouble *); +GLAPI void GLAPIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTangent3fvEXT (const GLfloat *); +GLAPI void GLAPIENTRY glTangent3iEXT (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glTangent3ivEXT (const GLint *); +GLAPI void GLAPIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glTangent3svEXT (const GLshort *); +GLAPI void GLAPIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void GLAPIENTRY glBinormal3bvEXT (const GLbyte *); +GLAPI void GLAPIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glBinormal3dvEXT (const GLdouble *); +GLAPI void GLAPIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glBinormal3fvEXT (const GLfloat *); +GLAPI void GLAPIENTRY glBinormal3iEXT (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glBinormal3ivEXT (const GLint *); +GLAPI void GLAPIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glBinormal3svEXT (const GLshort *); +GLAPI void GLAPIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (GLAPIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (GLAPIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (GLAPIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (GLAPIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (GLAPIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (GLAPIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (GLAPIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (GLAPIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (GLAPIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (GLAPIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glFinishTextureSUNX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGlobalAlphaFactorbSUN (GLbyte); +GLAPI void GLAPIENTRY glGlobalAlphaFactorsSUN (GLshort); +GLAPI void GLAPIENTRY glGlobalAlphaFactoriSUN (GLint); +GLAPI void GLAPIENTRY glGlobalAlphaFactorfSUN (GLfloat); +GLAPI void GLAPIENTRY glGlobalAlphaFactordSUN (GLdouble); +GLAPI void GLAPIENTRY glGlobalAlphaFactorubSUN (GLubyte); +GLAPI void GLAPIENTRY glGlobalAlphaFactorusSUN (GLushort); +GLAPI void GLAPIENTRY glGlobalAlphaFactoruiSUN (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (GLAPIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glReplacementCodeuiSUN (GLuint); +GLAPI void GLAPIENTRY glReplacementCodeusSUN (GLushort); +GLAPI void GLAPIENTRY glReplacementCodeubSUN (GLubyte); +GLAPI void GLAPIENTRY glReplacementCodeuivSUN (const GLuint *); +GLAPI void GLAPIENTRY glReplacementCodeusvSUN (const GLushort *); +GLAPI void GLAPIENTRY glReplacementCodeubvSUN (const GLubyte *); +GLAPI void GLAPIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); +GLAPI void GLAPIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); +GLAPI void GLAPIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); +GLAPI void GLAPIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void GLAPIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#endif + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glVertexWeightfEXT (GLfloat); +GLAPI void GLAPIENTRY glVertexWeightfvEXT (const GLfloat *); +GLAPI void GLAPIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (GLAPIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (GLAPIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glFlushVertexArrayRangeNV (void); +GLAPI void GLAPIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (GLAPIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glCombinerParameterfNV (GLenum, GLfloat); +GLAPI void GLAPIENTRY glCombinerParameterivNV (GLenum, const GLint *); +GLAPI void GLAPIENTRY glCombinerParameteriNV (GLenum, GLint); +GLAPI void GLAPIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +GLAPI void GLAPIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +GLAPI void GLAPIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +GLAPI void GLAPIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#endif + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glResizeBuffersMESA (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glWindowPos2dMESA (GLdouble, GLdouble); +GLAPI void GLAPIENTRY glWindowPos2dvMESA (const GLdouble *); +GLAPI void GLAPIENTRY glWindowPos2fMESA (GLfloat, GLfloat); +GLAPI void GLAPIENTRY glWindowPos2fvMESA (const GLfloat *); +GLAPI void GLAPIENTRY glWindowPos2iMESA (GLint, GLint); +GLAPI void GLAPIENTRY glWindowPos2ivMESA (const GLint *); +GLAPI void GLAPIENTRY glWindowPos2sMESA (GLshort, GLshort); +GLAPI void GLAPIENTRY glWindowPos2svMESA (const GLshort *); +GLAPI void GLAPIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glWindowPos3dvMESA (const GLdouble *); +GLAPI void GLAPIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glWindowPos3fvMESA (const GLfloat *); +GLAPI void GLAPIENTRY glWindowPos3iMESA (GLint, GLint, GLint); +GLAPI void GLAPIENTRY glWindowPos3ivMESA (const GLint *); +GLAPI void GLAPIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glWindowPos3svMESA (const GLshort *); +GLAPI void GLAPIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glWindowPos4dvMESA (const GLdouble *); +GLAPI void GLAPIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glWindowPos4fvMESA (const GLfloat *); +GLAPI void GLAPIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glWindowPos4ivMESA (const GLint *); +GLAPI void GLAPIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glWindowPos4svMESA (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); +GLAPI void GLAPIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (GLAPIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void GLAPIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void GLAPIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); +GLAPI void GLAPIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void GLAPIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void GLAPIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void GLAPIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void GLAPIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (GLAPIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); +typedef void (GLAPIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (GLAPIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (GLAPIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (GLAPIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (GLAPIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTbufferMask3DFX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glSampleMaskEXT (GLclampf, GLboolean); +GLAPI void GLAPIENTRY glSamplePatternEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#endif + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDeleteFencesNV (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenFencesNV (GLsizei, GLuint *); +GLAPI GLboolean GLAPIENTRY glIsFenceNV (GLuint); +GLAPI GLboolean GLAPIENTRY glTestFenceNV (GLuint); +GLAPI void GLAPIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glFinishFenceNV (GLuint); +GLAPI void GLAPIENTRY glSetFenceNV (GLuint, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GLAPIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GLAPIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); +GLAPI void GLAPIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); +GLAPI void GLAPIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); +GLAPI void GLAPIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glEvalMapsNV (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); +typedef void (GLAPIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); +typedef void (GLAPIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#endif + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#endif + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean GLAPIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); +GLAPI void GLAPIENTRY glBindProgramNV (GLenum, GLuint); +GLAPI void GLAPIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glGenProgramsNV (GLsizei, GLuint *); +GLAPI void GLAPIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); +GLAPI void GLAPIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); +GLAPI void GLAPIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); +GLAPI void GLAPIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean GLAPIENTRY glIsProgramNV (GLuint); +GLAPI void GLAPIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); +GLAPI void GLAPIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); +GLAPI void GLAPIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void GLAPIENTRY glVertexAttrib1dNV (GLuint, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib1fNV (GLuint, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib1sNV (GLuint, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void GLAPIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); +GLAPI void GLAPIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void GLAPIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void GLAPIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); +GLAPI void GLAPIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (GLAPIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (GLAPIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (GLAPIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (GLAPIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (GLAPIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (GLAPIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (GLAPIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#endif + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#endif + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#endif + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTexBumpParameterivATI (GLenum, const GLint *); +GLAPI void GLAPIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); +GLAPI void GLAPIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (GLAPIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (GLAPIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (GLAPIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint GLAPIENTRY glGenFragmentShadersATI (GLuint); +GLAPI void GLAPIENTRY glBindFragmentShaderATI (GLuint); +GLAPI void GLAPIENTRY glDeleteFragmentShaderATI (GLuint); +GLAPI void GLAPIENTRY glBeginFragmentShaderATI (void); +GLAPI void GLAPIENTRY glEndFragmentShaderATI (void); +GLAPI void GLAPIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); +GLAPI void GLAPIENTRY glSampleMapATI (GLuint, GLuint, GLenum); +GLAPI void GLAPIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (GLAPIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (GLAPIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAPIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAPIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPNTrianglesiATI (GLenum, GLint); +GLAPI void GLAPIENTRY glPNTrianglesfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint GLAPIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); +GLAPI GLboolean GLAPIENTRY glIsObjectBufferATI (GLuint); +GLAPI void GLAPIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); +GLAPI void GLAPIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glFreeObjectBufferATI (GLuint); +GLAPI void GLAPIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void GLAPIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void GLAPIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (GLAPIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); +typedef GLboolean (GLAPIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); +typedef void (GLAPIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBeginVertexShaderEXT (void); +GLAPI void GLAPIENTRY glEndVertexShaderEXT (void); +GLAPI void GLAPIENTRY glBindVertexShaderEXT (GLuint); +GLAPI GLuint GLAPIENTRY glGenVertexShadersEXT (GLuint); +GLAPI void GLAPIENTRY glDeleteVertexShaderEXT (GLuint); +GLAPI void GLAPIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); +GLAPI void GLAPIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void GLAPIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void GLAPIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); +GLAPI void GLAPIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); +GLAPI GLuint GLAPIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); +GLAPI void GLAPIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glVariantbvEXT (GLuint, const GLbyte *); +GLAPI void GLAPIENTRY glVariantsvEXT (GLuint, const GLshort *); +GLAPI void GLAPIENTRY glVariantivEXT (GLuint, const GLint *); +GLAPI void GLAPIENTRY glVariantfvEXT (GLuint, const GLfloat *); +GLAPI void GLAPIENTRY glVariantdvEXT (GLuint, const GLdouble *); +GLAPI void GLAPIENTRY glVariantubvEXT (GLuint, const GLubyte *); +GLAPI void GLAPIENTRY glVariantusvEXT (GLuint, const GLushort *); +GLAPI void GLAPIENTRY glVariantuivEXT (GLuint, const GLuint *); +GLAPI void GLAPIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); +GLAPI void GLAPIENTRY glEnableVariantClientStateEXT (GLuint); +GLAPI void GLAPIENTRY glDisableVariantClientStateEXT (GLuint); +GLAPI GLuint GLAPIENTRY glBindLightParameterEXT (GLenum, GLenum); +GLAPI GLuint GLAPIENTRY glBindMaterialParameterEXT (GLenum, GLenum); +GLAPI GLuint GLAPIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); +GLAPI GLuint GLAPIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); +GLAPI GLuint GLAPIENTRY glBindParameterEXT (GLenum); +GLAPI GLboolean GLAPIENTRY glIsVariantEnabledEXT (GLuint, GLenum); +GLAPI void GLAPIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void GLAPIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); +GLAPI void GLAPIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void GLAPIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void GLAPIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (GLAPIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (GLAPIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (GLAPIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAPIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAPIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (GLAPIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (GLAPIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (GLAPIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (GLAPIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (GLAPIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); +typedef void (GLAPIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (GLAPIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (GLAPIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (GLAPIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (GLAPIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (GLAPIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (GLAPIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (GLAPIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); +typedef void (GLAPIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glVertexStream1sATI (GLenum, GLshort); +GLAPI void GLAPIENTRY glVertexStream1svATI (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glVertexStream1iATI (GLenum, GLint); +GLAPI void GLAPIENTRY glVertexStream1ivATI (GLenum, const GLint *); +GLAPI void GLAPIENTRY glVertexStream1fATI (GLenum, GLfloat); +GLAPI void GLAPIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glVertexStream1dATI (GLenum, GLdouble); +GLAPI void GLAPIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexStream2svATI (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glVertexStream2iATI (GLenum, GLint, GLint); +GLAPI void GLAPIENTRY glVertexStream2ivATI (GLenum, const GLint *); +GLAPI void GLAPIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexStream3svATI (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glVertexStream3ivATI (GLenum, const GLint *); +GLAPI void GLAPIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glVertexStream4svATI (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glVertexStream4ivATI (GLenum, const GLint *); +GLAPI void GLAPIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); +GLAPI void GLAPIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); +GLAPI void GLAPIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void GLAPIENTRY glNormalStream3svATI (GLenum, const GLshort *); +GLAPI void GLAPIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void GLAPIENTRY glNormalStream3ivATI (GLenum, const GLint *); +GLAPI void GLAPIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); +GLAPI void GLAPIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); +GLAPI void GLAPIENTRY glClientActiveVertexStreamATI (GLenum); +GLAPI void GLAPIENTRY glVertexBlendEnviATI (GLenum, GLint); +GLAPI void GLAPIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (GLAPIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (GLAPIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glElementPointerATI (GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glDrawElementArrayATI (GLenum, GLsizei); +GLAPI void GLAPIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (GLAPIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#endif + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); +GLAPI void GLAPIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); +GLAPI GLboolean GLAPIENTRY glIsOcclusionQueryNV (GLuint); +GLAPI void GLAPIENTRY glBeginOcclusionQueryNV (GLuint); +GLAPI void GLAPIENTRY glEndOcclusionQueryNV (void); +GLAPI void GLAPIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); +GLAPI void GLAPIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (GLAPIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GLAPIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (GLAPIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPointParameteriNV (GLenum, GLint); +GLAPI void GLAPIENTRY glPointParameterivNV (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#endif + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glActiveStencilFaceEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); +GLAPI void GLAPIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); +GLAPI void GLAPIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); +GLAPI void GLAPIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); +GLAPI void GLAPIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAPIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGenFencesAPPLE (GLsizei, GLuint *); +GLAPI void GLAPIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glSetFenceAPPLE (GLuint); +GLAPI GLboolean GLAPIENTRY glIsFenceAPPLE (GLuint); +GLAPI GLboolean GLAPIENTRY glTestFenceAPPLE (GLuint); +GLAPI void GLAPIENTRY glFinishFenceAPPLE (GLuint); +GLAPI GLboolean GLAPIENTRY glTestObjectAPPLE (GLenum, GLuint); +GLAPI void GLAPIENTRY glFinishObjectAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (GLAPIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (GLAPIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (GLAPIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBindVertexArrayAPPLE (GLuint); +GLAPI void GLAPIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenVertexArraysAPPLE (GLsizei, const GLuint *); +GLAPI GLboolean GLAPIENTRY glIsVertexArrayAPPLE (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (GLAPIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (GLAPIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef GLboolean (GLAPIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void GLAPIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void GLAPIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#endif + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDrawBuffersATI (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +/* This is really a WGL extension, but defines some associated GL enums. + * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. + */ +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#endif + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#endif + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#endif + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void GLAPIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void GLAPIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); +GLAPI void GLAPIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); +GLAPI void GLAPIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); +GLAPI void GLAPIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (GLAPIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glVertex2hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glVertex3hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glVertex4hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glNormal3hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glColor3hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glColor4hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glTexCoord1hNV (GLhalfNV); +GLAPI void GLAPIENTRY glTexCoord1hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glTexCoord2hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glTexCoord3hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glTexCoord4hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); +GLAPI void GLAPIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); +GLAPI void GLAPIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); +GLAPI void GLAPIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); +GLAPI void GLAPIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); +GLAPI void GLAPIENTRY glFogCoordhNV (GLhalfNV); +GLAPI void GLAPIENTRY glFogCoordhvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glSecondaryColor3hvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexWeighthNV (GLhalfNV); +GLAPI void GLAPIENTRY glVertexWeighthvNV (const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); +GLAPI void GLAPIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void GLAPIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void GLAPIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (GLAPIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (GLAPIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (GLAPIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (GLAPIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (GLAPIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (GLAPIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (GLAPIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (GLAPIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (GLAPIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (GLAPIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (GLAPIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (GLAPIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (GLAPIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (GLAPIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); +GLAPI void GLAPIENTRY glFlushPixelDataRangeNV (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#endif + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glPrimitiveRestartNV (void); +GLAPI void GLAPIENTRY glPrimitiveRestartIndexNV (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (GLAPIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#endif + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLvoid* GLAPIENTRY glMapObjectBufferATI (GLuint); +GLAPI void GLAPIENTRY glUnmapObjectBufferATI (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLvoid* (GLAPIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); +GLAPI void GLAPIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); +GLAPI void GLAPIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void GLAPIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#endif + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDepthBoundsEXT (GLclampd, GLclampd); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +#endif + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#endif + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#endif + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#endif + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean GLAPIENTRY glIsRenderbufferEXT (GLuint); +GLAPI void GLAPIENTRY glBindRenderbufferEXT (GLenum, GLuint); +GLAPI void GLAPIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *); +GLAPI void GLAPIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); +GLAPI void GLAPIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); +GLAPI GLboolean GLAPIENTRY glIsFramebufferEXT (GLuint); +GLAPI void GLAPIENTRY glBindFramebufferEXT (GLenum, GLuint); +GLAPI void GLAPIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *); +GLAPI void GLAPIENTRY glGenFramebuffersEXT (GLsizei, GLuint *); +GLAPI GLenum GLAPIENTRY glCheckFramebufferStatusEXT (GLenum); +GLAPI void GLAPIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI void GLAPIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI void GLAPIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); +GLAPI void GLAPIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); +GLAPI void GLAPIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); +GLAPI void GLAPIENTRY glGenerateMipmapEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (GLAPIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (GLAPIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (GLAPIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (GLAPIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef void (GLAPIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (GLAPIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (GLAPIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (GLAPIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +#endif + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); +#endif + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 +#endif + +#ifndef GL_EXT_timer_query +#ifndef GL_COMPILER_LACKS_64BIT_INT +#define GL_EXT_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params); +GLAPI void GLAPIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (GLAPIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); +#endif +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#endif + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); +GLAPI void GLAPIENTRY glEndTransformFeedbackNV (void); +GLAPI void GLAPIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); +GLAPI void GLAPIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void GLAPIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +GLAPI void GLAPIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); +GLAPI void GLAPIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +GLAPI void GLAPIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); +GLAPI GLint GLAPIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); +GLAPI void GLAPIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void GLAPIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (GLAPIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +typedef void (GLAPIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef GLint (GLAPIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +#endif + + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); +GLAPI void GLAPIENTRY glClearDepthdNV (GLdouble depth); +GLAPI void GLAPIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (GLAPIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (GLAPIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#endif + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#endif + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#endif + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GLAPI void GLAPIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); +GLAPI void GLAPIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); +GLAPI void GLAPIENTRY glEnableIndexedEXT (GLenum target, GLuint index); +GLAPI void GLAPIENTRY glDisableIndexedEXT (GLenum target, GLuint index); +GLAPI GLboolean GLAPIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (GLAPIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); +typedef void (GLAPIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (GLAPIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +#endif + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); +GLAPI void GLAPIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); +GLAPI void GLAPIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (GLAPIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GLAPIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAPIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); +GLAPI GLint GLAPIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); +GLAPI GLintptr GLAPIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef GLint (GLAPIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (GLAPIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); +GLAPI void GLAPIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint GLAPIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); +GLAPI void GLAPIENTRY glUniform1uiEXT (GLint location, GLuint v0); +GLAPI void GLAPIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); +GLAPI void GLAPIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void GLAPIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void GLAPIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void GLAPIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void GLAPIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void GLAPIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void GLAPIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); +GLAPI void GLAPIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); +GLAPI void GLAPIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); +GLAPI void GLAPIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); +GLAPI void GLAPIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void GLAPIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void GLAPIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); +GLAPI void GLAPIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); +GLAPI void GLAPIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); +GLAPI void GLAPIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); +GLAPI void GLAPIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); +GLAPI void GLAPIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); +GLAPI void GLAPIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); +GLAPI void GLAPIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); +GLAPI void GLAPIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); +GLAPI void GLAPIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); +GLAPI void GLAPIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); +GLAPI void GLAPIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); +GLAPI void GLAPIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (GLAPIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GLAPIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +#endif + + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GLAPI void GLAPIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void GLAPIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void GLAPIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GLAPIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void GLAPIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void GLAPIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void GLAPIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void GLAPIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void GLAPIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void GLAPIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void GLAPIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void GLAPIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void GLAPIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void GLAPIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void GLAPIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); +GLAPI void GLAPIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void GLAPIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (GLAPIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); +GLAPI void GLAPIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +GLAPI void GLAPIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void GLAPIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +GLAPI void GLAPIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GLAPIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Extras/sph/common/glut.h b/Extras/sph/common/glut.h new file mode 100644 index 0000000..11735a1 --- /dev/null +++ b/Extras/sph/common/glut.h @@ -0,0 +1,791 @@ +#ifndef __glut_h__ +#define __glut_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998, 2000, 2006. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#if defined(_WIN32) || defined(__CYGWIN__) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 + /* This would put tons of macros and crap in our clean name space. */ +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED + /* Cygwin and MingW32 are two free GNU-based Open Source compilation + environments for Win32. Note that __CYGWIN32__ is deprecated + in favor of simply __CYGWIN__. */ +# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__) +# if defined(__CYGWIN__) +# define APIENTRY __stdcall +# else +# ifdef i386 +# define APIENTRY __attribute__((stdcall)) +# else +# define APIENTRY +# endif +# endif +# else +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__) +# ifndef __stdcall +# define __stdcall __attribute__((stdcall)) +# endif +# define CALLBACK __stdcall +# else +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif +# endif + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__) +# define WINGDIAPI +# else +# define WINGDIAPI __declspec(dllimport) +# endif +# endif +# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__) + /* Rely on Cygwin32/MingW32 to set wchar_t. */ + /* XXX Warning. The Cygwin32/MingW32 definition for wchar_t + is an "int" instead of the "short" used by Windows. */ +# include +# else + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif +# endif + +/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA + in your compile preprocessor options (Microsoft Visual C only). */ +# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) && defined(_MSC_VER) +# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +# pragma comment (lib, "user32.lib") /* link with Windows User lib */ +# pragma comment (lib, "gdi32.lib") /* link with Windows GDI lib */ +/* To enable automatic SGI OpenGL for Windows library usage for GLUT, + define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */ +# ifdef GLUT_USE_SGI_OPENGL +# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */ +# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */ +# if defined(GLUT_STATIC_LIB) +# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */ +# else +# pragma comment (lib, "glut.lib") /* link with Win32 GLUT lib */ +# endif +# else +# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */ +# if defined(GLUT_STATIC_LIB) +# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */ +# else +# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ +# endif +# endif +# endif + +/* To disable supression of annoying warnings about floats being promoted + to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor + options. */ +# if defined(_MSC_VER) && !defined(GLUT_NO_WARNING_DISABLE) +# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */ +# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +# endif + +/* Win32 has an annoying issue where there are multiple C run-time + libraries (CRTs). If the executable is linked with a different CRT + from the GLUT DLL, the GLUT DLL will not share the same CRT static + data seen by the executable. In particular, atexit callbacks registered + in the executable will not be called if GLUT calls its (different) + exit routine). GLUT is typically built with the + "/MD" option (the CRT with multithreading DLL support), but the Visual + C++ linker default is "/ML" (the single threaded CRT). + + One workaround to this issue is requiring users to always link with + the same CRT as GLUT is compiled with. That requires users supply a + non-standard option. GLUT 3.7 has its own built-in workaround where + the executable's "exit" function pointer is covertly passed to GLUT. + GLUT then calls the executable's exit function pointer to ensure that + any "atexit" calls registered by the application are called if GLUT + needs to exit. + + Note that the __glut*WithExit routines should NEVER be called directly. + To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ + +/* XXX This is from Win32's */ +# if !defined(_MSC_VER) && !defined(__cdecl) + /* Define __cdecl for non-Microsoft compilers. */ +# define __cdecl +# define GLUT_DEFINED___CDECL +# endif +# ifndef _CRTIMP +# ifdef _NTSDK + /* Definition compatible with NT SDK */ +# define _CRTIMP +# else + /* Current definition */ +# ifdef _DLL +# define _CRTIMP __declspec(dllimport) +# else +# define _CRTIMP +# endif +# endif +# define GLUT_DEFINED__CRTIMP +# endif + +/* GLUT API entry point declarations for Win32. */ +# ifdef GLUT_BUILDING_LIB +/* MSDN article 835326 says "When you build a DLL by using the 64-bit + version of the Microsoft Visual C++ Compiler and Linker, you may + receive Linker error number LNK4197 if a function has been declared + for export more than one time." GLUT builds with glut.def that + declares GLUT's EXPORTS list so do not use __declspec(dllexport) + to keep 64-bit compiler happy. */ +# define GLUTAPI /*__declspec(dllexport)*/ +# else +# ifdef _DLL +# define GLUTAPI __declspec(dllimport) +# else +# define GLUTAPI extern +# endif +# endif + +/* GLUT callback calling convention for Win32. */ +# define GLUTCALLBACK __cdecl + +# if (_MSC_VER >= 800) || defined(__MINGW32__) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__) +# define GLUTAPIENTRY __stdcall +# else +# define GLUTAPIENTRY +# endif + +#endif /* _WIN32 */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# ifndef GLUT_BUILDING_LIB +# if __BORLANDC__ +# if defined(_BUILDRTLDLL) +void __cdecl __export exit(int __status); +# else +void __cdecl exit(int __status); +# endif +# else +# if _MSC_VER >= 1200 + extern _CRTIMP __declspec(noreturn) void __cdecl exit(int); +# else + extern _CRTIMP void __cdecl exit(int); +# endif +# endif +# endif +#else +/* non-Win32 case. */ +/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */ +# define APIENTRY +# define GLUT_APIENTRY_DEFINED +# define CALLBACK +/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */ +# define GLUTAPI extern +# define GLUTAPIENTRY +# define GLUTCALLBACK +/* Prototype exit for the non-Win32 case (see above). */ +# ifdef __GNUC__ +extern void exit(int __status) __attribute__((__noreturn__)); +# else +extern void exit(int); +# endif +#endif + +/** + GLUT API revision history: + + GLUT_API_VERSION is updated to reflect incompatible GLUT + API changes (interface changes, semantic changes, deletions, + or additions). + + GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 + + GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, + extension. Supports new input devices like tablet, dial and button + box, and Spaceball. Easy to query OpenGL extensions. + + GLUT_API_VERSION=3 glutMenuStatus added. + + GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, + glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic + video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, + glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, + glutJoystickFunc, glutForceJoystickFunc, glutStrokeWidthf, + glutStrokeLengthf (NOT FINALIZED!). +**/ +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +#define GLUT_API_VERSION 3 +#endif + +/** + GLUT implementation revision history: + + GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT + API revisions and implementation revisions (ie, bug fixes). + + GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of + GLUT Xlib-based implementation. 11/29/94 + + GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of + GLUT Xlib-based implementation providing GLUT version 2 + interfaces. + + GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 + + GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 + + GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 + + GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 + + GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner + and video resize. 1/3/97 + + GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. + + GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. + + GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. + + GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support. + + GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface. + + GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa + + GLUT_XLIB_IMPLEMENTATION=16 mjk's early GLUT 3.8 + + GLUT_XLIB_IMPLEMENTATION=17 mjk's GLUT 3.8 with glutStrokeWidthf and glutStrokeLengthf +**/ +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 17 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +#ifdef _WIN32 +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutStrokeRoman; +GLUTAPI void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutBitmap9By15; +GLUTAPI void *glutBitmap8By13; +GLUTAPI void *glutBitmapTimesRoman10; +GLUTAPI void *glutBitmapTimesRoman24; +GLUTAPI void *glutBitmapHelvetica10; +GLUTAPI void *glutBitmapHelvetica12; +GLUTAPI void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X ((GLenum) 100) +#define GLUT_WINDOW_Y ((GLenum) 101) +#define GLUT_WINDOW_WIDTH ((GLenum) 102) +#define GLUT_WINDOW_HEIGHT ((GLenum) 103) +#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) +#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) +#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) +#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) +#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) +#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) +#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) +#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) +#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) +#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) +#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) +#define GLUT_WINDOW_RGBA ((GLenum) 116) +#define GLUT_WINDOW_PARENT ((GLenum) 117) +#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) +#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) +#define GLUT_WINDOW_STEREO ((GLenum) 121) +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR ((GLenum) 122) +#endif +#define GLUT_SCREEN_WIDTH ((GLenum) 200) +#define GLUT_SCREEN_HEIGHT ((GLenum) 201) +#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) +#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) +#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) +#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) +#define GLUT_INIT_WINDOW_X ((GLenum) 500) +#define GLUT_INIT_WINDOW_Y ((GLenum) 501) +#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) +#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) +#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME ((GLenum) 700) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD ((GLenum) 600) +#define GLUT_HAS_MOUSE ((GLenum) 601) +#define GLUT_HAS_SPACEBALL ((GLenum) 602) +#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) +#define GLUT_HAS_TABLET ((GLenum) 604) +#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) +#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) +#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) +#define GLUT_NUM_DIALS ((GLenum) 608) +#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) +#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) +#define GLUT_HAS_JOYSTICK ((GLenum) 612) +#define GLUT_OWNS_JOYSTICK ((GLenum) 613) +#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) +#define GLUT_JOYSTICK_AXES ((GLenum) 615) +#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) +#define GLUT_LAYER_IN_USE ((GLenum) 801) +#define GLUT_HAS_OVERLAY ((GLenum) 802) +#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) +#define GLUT_NORMAL_DAMAGED ((GLenum) 804) +#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) +#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) +#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) +#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) +#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) +#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) +#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) +#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL ((GLenum) 0) +#define GLUT_OVERLAY ((GLenum) 1) + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +/* GLUT initialization sub-API. */ +GLUTAPI void GLUTAPIENTRY glutInit(int *argcp, char **argv); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI void GLUTAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static void GLUTAPIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } +#define glutInit glutInit_ATEXIT_HACK +#endif +#endif +GLUTAPI void GLUTAPIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void GLUTAPIENTRY glutInitDisplayString(const char *string); +#endif +GLUTAPI void GLUTAPIENTRY glutInitWindowPosition(int x, int y); +GLUTAPI void GLUTAPIENTRY glutInitWindowSize(int width, int height); +GLUTAPI void GLUTAPIENTRY glutMainLoop(void); + +/* GLUT window sub-API. */ +GLUTAPI int GLUTAPIENTRY glutCreateWindow(const char *title); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int GLUTAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int GLUTAPIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } +#define glutCreateWindow glutCreateWindow_ATEXIT_HACK +#endif +#endif +GLUTAPI int GLUTAPIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); +GLUTAPI void GLUTAPIENTRY glutDestroyWindow(int win); +GLUTAPI void GLUTAPIENTRY glutPostRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void GLUTAPIENTRY glutPostWindowRedisplay(int win); +#endif +GLUTAPI void GLUTAPIENTRY glutSwapBuffers(void); +GLUTAPI int GLUTAPIENTRY glutGetWindow(void); +GLUTAPI void GLUTAPIENTRY glutSetWindow(int win); +GLUTAPI void GLUTAPIENTRY glutSetWindowTitle(const char *title); +GLUTAPI void GLUTAPIENTRY glutSetIconTitle(const char *title); +GLUTAPI void GLUTAPIENTRY glutPositionWindow(int x, int y); +GLUTAPI void GLUTAPIENTRY glutReshapeWindow(int width, int height); +GLUTAPI void GLUTAPIENTRY glutPopWindow(void); +GLUTAPI void GLUTAPIENTRY glutPushWindow(void); +GLUTAPI void GLUTAPIENTRY glutIconifyWindow(void); +GLUTAPI void GLUTAPIENTRY glutShowWindow(void); +GLUTAPI void GLUTAPIENTRY glutHideWindow(void); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void GLUTAPIENTRY glutFullScreen(void); +GLUTAPI void GLUTAPIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void GLUTAPIENTRY glutWarpPointer(int x, int y); +#endif + +/* GLUT overlay sub-API. */ +GLUTAPI void GLUTAPIENTRY glutEstablishOverlay(void); +GLUTAPI void GLUTAPIENTRY glutRemoveOverlay(void); +GLUTAPI void GLUTAPIENTRY glutUseLayer(GLenum layer); +GLUTAPI void GLUTAPIENTRY glutPostOverlayRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void GLUTAPIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +GLUTAPI void GLUTAPIENTRY glutShowOverlay(void); +GLUTAPI void GLUTAPIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +GLUTAPI int GLUTAPIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int GLUTAPIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int GLUTAPIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); } +#define glutCreateMenu glutCreateMenu_ATEXIT_HACK +#endif +#endif +GLUTAPI void GLUTAPIENTRY glutDestroyMenu(int menu); +GLUTAPI int GLUTAPIENTRY glutGetMenu(void); +GLUTAPI void GLUTAPIENTRY glutSetMenu(int menu); +GLUTAPI void GLUTAPIENTRY glutAddMenuEntry(const char *label, int value); +GLUTAPI void GLUTAPIENTRY glutAddSubMenu(const char *label, int submenu); +GLUTAPI void GLUTAPIENTRY glutChangeToMenuEntry(int item, const char *label, int value); +GLUTAPI void GLUTAPIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); +GLUTAPI void GLUTAPIENTRY glutRemoveMenuItem(int item); +GLUTAPI void GLUTAPIENTRY glutAttachMenu(int button); +GLUTAPI void GLUTAPIENTRY glutDetachMenu(int button); + +/* GLUT window callback sub-API. */ +GLUTAPI void GLUTAPIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void GLUTAPIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height)); +GLUTAPI void GLUTAPIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void GLUTAPIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +GLUTAPI void GLUTAPIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void GLUTAPIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void GLUTAPIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void GLUTAPIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void GLUTAPIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void GLUTAPIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value); +GLUTAPI void GLUTAPIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state)); +#if (GLUT_API_VERSION >= 2) +GLUTAPI void GLUTAPIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void GLUTAPIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void GLUTAPIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void GLUTAPIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void GLUTAPIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void GLUTAPIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value)); +GLUTAPI void GLUTAPIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void GLUTAPIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void GLUTAPIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)); +GLUTAPI void GLUTAPIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void GLUTAPIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +GLUTAPI void GLUTAPIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void GLUTAPIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void GLUTAPIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +GLUTAPI void GLUTAPIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); +GLUTAPI GLfloat GLUTAPIENTRY glutGetColor(int ndx, int component); +GLUTAPI void GLUTAPIENTRY glutCopyColormap(int win); + +/* GLUT state retrieval sub-API. */ +GLUTAPI int GLUTAPIENTRY glutGet(GLenum type); +GLUTAPI int GLUTAPIENTRY glutDeviceGet(GLenum type); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +GLUTAPI int GLUTAPIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +GLUTAPI int GLUTAPIENTRY glutGetModifiers(void); +GLUTAPI int GLUTAPIENTRY glutLayerGet(GLenum type); +#endif + +/* GLUT font sub-API */ +GLUTAPI void GLUTAPIENTRY glutBitmapCharacter(void *font, int character); +GLUTAPI int GLUTAPIENTRY glutBitmapWidth(void *font, int character); +GLUTAPI void GLUTAPIENTRY glutStrokeCharacter(void *font, int character); +GLUTAPI int GLUTAPIENTRY glutStrokeWidth(void *font, int character); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI int GLUTAPIENTRY glutBitmapLength(void *font, const unsigned char *string); +GLUTAPI int GLUTAPIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 17) +GLUTAPI float GLUTAPIENTRY glutStrokeWidthf(void *font, int character); +GLUTAPI float GLUTAPIENTRY glutStrokeLengthf(void *font, const unsigned char *string); +#endif + +/* GLUT pre-built models sub-API */ +GLUTAPI void GLUTAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void GLUTAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void GLUTAPIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void GLUTAPIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void GLUTAPIENTRY glutWireCube(GLdouble size); +GLUTAPI void GLUTAPIENTRY glutSolidCube(GLdouble size); +GLUTAPI void GLUTAPIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void GLUTAPIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void GLUTAPIENTRY glutWireDodecahedron(void); +GLUTAPI void GLUTAPIENTRY glutSolidDodecahedron(void); +GLUTAPI void GLUTAPIENTRY glutWireTeapot(GLdouble size); +GLUTAPI void GLUTAPIENTRY glutSolidTeapot(GLdouble size); +GLUTAPI void GLUTAPIENTRY glutWireOctahedron(void); +GLUTAPI void GLUTAPIENTRY glutSolidOctahedron(void); +GLUTAPI void GLUTAPIENTRY glutWireTetrahedron(void); +GLUTAPI void GLUTAPIENTRY glutSolidTetrahedron(void); +GLUTAPI void GLUTAPIENTRY glutWireIcosahedron(void); +GLUTAPI void GLUTAPIENTRY glutSolidIcosahedron(void); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +GLUTAPI int GLUTAPIENTRY glutVideoResizeGet(GLenum param); +GLUTAPI void GLUTAPIENTRY glutSetupVideoResizing(void); +GLUTAPI void GLUTAPIENTRY glutStopVideoResizing(void); +GLUTAPI void GLUTAPIENTRY glutVideoResize(int x, int y, int width, int height); +GLUTAPI void GLUTAPIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +GLUTAPI void GLUTAPIENTRY glutReportErrors(void); +#endif + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +/* GLUT device control sub-API. */ +/* glutSetKeyRepeat modes. */ +#define GLUT_KEY_REPEAT_OFF 0 +#define GLUT_KEY_REPEAT_ON 1 +#define GLUT_KEY_REPEAT_DEFAULT 2 + +/* Joystick button masks. */ +#define GLUT_JOYSTICK_BUTTON_A 1 +#define GLUT_JOYSTICK_BUTTON_B 2 +#define GLUT_JOYSTICK_BUTTON_C 4 +#define GLUT_JOYSTICK_BUTTON_D 8 + +GLUTAPI void GLUTAPIENTRY glutIgnoreKeyRepeat(int ignore); +GLUTAPI void GLUTAPIENTRY glutSetKeyRepeat(int repeatMode); +GLUTAPI void GLUTAPIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0) +#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1) +#define GLUT_GAME_MODE_WIDTH ((GLenum) 2) +#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3) +#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4) +#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5) +#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6) + +GLUTAPI void GLUTAPIENTRY glutGameModeString(const char *string); +GLUTAPI int GLUTAPIENTRY glutEnterGameMode(void); +GLUTAPI void GLUTAPIENTRY glutLeaveGameMode(void); +GLUTAPI int GLUTAPIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#ifdef GLUT_APIENTRY_DEFINED +# undef GLUT_APIENTRY_DEFINED +# undef APIENTRY +#endif + +#ifdef GLUT_WINGDIAPI_DEFINED +# undef GLUT_WINGDIAPI_DEFINED +# undef WINGDIAPI +#endif + +#ifdef GLUT_DEFINED___CDECL +# undef GLUT_DEFINED___CDECL +# undef __cdecl +#endif + +#ifdef GLUT_DEFINED__CRTIMP +# undef GLUT_DEFINED__CRTIMP +# undef _CRTIMP +#endif + +#endif /* __glut_h__ */ diff --git a/Extras/sph/common/image.cpp b/Extras/sph/common/image.cpp new file mode 100644 index 0000000..6a2fb48 --- /dev/null +++ b/Extras/sph/common/image.cpp @@ -0,0 +1,1948 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "image.h" + +#include +#include +#include +#include +#include + +#include "gl_helper.h" + +// Link with JPEG library on platforms that support it. +#ifdef USE_JPEG + #include + #include + #include "jerror.h" +#endif + +#ifndef WIN32 + #include +#endif + + +// Disable warnings on depricated functions +#pragma warning( disable : 4995) // removes warning 4995 - depricated function +#pragma warning( disable : 4996) // removes warning 4996 - depricated function + +#ifdef WIN32 + #define GL_TEXTURE_CUBE_MAP 0x8513 + #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#endif + +static const int maxvals[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 }; + +static inline unsigned char val2bits (double v, int b) +{ + return (unsigned char) (floor(v * maxvals[b] + 0.5) / maxvals[b] * 255); +} + + +Image::Image () +{ + width = 0; + height = 0; + channels = 0; + bits = 0; + maxValue = 0; + pixels = NULL; + owns = true; +} + + +Image::Image (int width_, int height_) +{ + create ( width_, height_, 3 ); +} + + +Image::Image (int width_, int height_, int channels_) +{ + create (width_, height_, channels_ ); +} + +void Image::create ( int width_, int height_, int channels_ ) +{ + width = width_; + height = height_; + channels = channels_; + bits = 8; + maxValue = 255; + + assert(width > 0 && height > 0 && + (channels == 1 || channels == 3 || channels == 4) && + bits > 0 && bits < 9 + ); + + pixels = new unsigned char[width*height*channels]; + owns = true; + memset(pixels, 0, width*height*channels); + + clear ( Pixel(0,0,0 ) ); + + glGenTextures( 1, (GLuint*) &imgID ); + glBindTexture ( GL_TEXTURE_2D, imgID ); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1); + refresh (); +} + +void Image::draw () +{ + draw ( 0, 0 ); +} + +void Image::draw ( float x, float y ) +{ + glEnable ( GL_TEXTURE_2D ); + glColor4f ( 1,1,1,1); + glBindTexture ( GL_TEXTURE_2D, (GLuint) imgID ); + glBegin ( GL_QUADS ); + glTexCoord2f ( 0, 1); glVertex2f ( x, y ); + glTexCoord2f ( 1, 1 ); glVertex2f ( x+width, y ); + glTexCoord2f ( 1, 0 ); glVertex2f ( x+width, y+height ); + glTexCoord2f ( 0, 0 ); glVertex2f ( x, y+height ); + glEnd (); +} + + +Image::Image (int width_, int height_, int channels_, int bits_) +{ + width = width_; + height = height_; + channels = channels_; + bits = bits_; + maxValue = val2bits(1.0,bits); + + assert(width > 0 && height > 0 && + (channels == 1 || channels == 3 || channels == 4) && + bits > 0 && bits < 9 + ); + + pixels = new unsigned char[width*height*channels]; + owns = true; + memset(pixels, 0, width*height*channels); +} + + +Image::Image (const char* filename) +{ + width = 0; + height = 0; + channels = 0; + bits = 0; + maxValue = 0; + pixels = NULL; + owns = true; + + read(filename); +} + + +Image::~Image () +{ + if (pixels && owns) delete[] pixels; +} + + +Image::Image (const Image& image) +{ + width = image.width; + height = image.height; + channels = image.channels; + bits = image.bits; + maxValue = image.maxValue; + pixels = new unsigned char[width*height*channels]; + owns = true; + + for (int i = 0; i < width*height*channels; ++i) + pixels[i] = image.pixels[i]; +} + + +Image& Image::operator= (const Image& image) +{ + if (&image == this) return *this; + + if (pixels) delete[] pixels; + + width = image.width; + height = image.height; + channels = image.channels; + bits = image.bits; + maxValue = image.maxValue; + pixels = new unsigned char[width*height*channels]; + owns = true; + + for (int i = 0; i < width*height*channels; ++i) + pixels[i] = image.pixels[i]; + + return *this; +} + + +void Image::setPixels ( unsigned char *newPixels ) +{ + if( bad() || ! newPixels ) + return; + + //if( owns && pixels ) + // delete [] pixels; + + memcpy ( pixels, newPixels, width*height*channels ); +} + + +bool Image::good () +{ + return (width > 0 && height > 0 && + (channels == 1 || channels == 3 || channels == 4) && + bits > 0 && bits < 9 && pixels); +} + + +bool Image::bad () +{ + return !good(); +} + +void Image::clear () +{ + clear ( Pixel(0,0,0) ); +} + + +void Image::clear ( Pixel pixel ) +{ + unsigned char* buf = pixels; + + if ( channels == 3) { + for (int n=0; n < width*height; n++) { + *buf++ = (unsigned char) (pixel.r*255.0f); + *buf++ = (unsigned char) (pixel.g*255.0f); + *buf++ = (unsigned char) (pixel.b*255.0f); + } + } else { + for (int n=0; n < width*height; n++) { + *buf++ = (unsigned char) ( pixel.r*255.0f); + *buf++ = (unsigned char) (pixel.g*255.0f); + *buf++ = (unsigned char) (pixel.b*255.0f); + *buf++ = (unsigned char) (pixel.a*255.0f); + } + } +} + + +int Image::index (int x, int y, int c) +{ + return (((height - y - 1) * width + x) * channels + c); +} + + +double Image::getPixel (int x, int y, int channel) +{ + assert(good()); + assert((x >= 0) && + (x < width) && + (y >= 0) && + (y < height) && + (channel >= 0) && + (channel < channels)); + + return pixels[index(x,y,channel)] / 255.0; +} + + +double Image::getPixel_ (int x, int y, int channel) +{ + if (!good() || + (x < 0) || + (x >= width) || + (y < 0) || + (y >= height) || + (channel < 0) || + (channel >= channels)) + return 0.0; + + return getPixel(x,y,channel); +} + + +Pixel Image::getPixel (int x, int y) +{ + assert(good()); + assert((x >= 0) && + (x < width) && + (y >= 0) && + (y < height)); + + Pixel pixel; + memset(&pixel, 0, sizeof(Pixel)); + + switch (channels) + { + case 4: + pixel.a = pixels[index(x,y,IALPHA)] / 255.0; + + case 3: + pixel.b = pixels[index(x,y,IBLUE)] / 255.0; + pixel.g = pixels[index(x,y,IGREEN)] / 255.0; + + case 1: + pixel.r = pixels[index(x,y,IRED)] / 255.0; + + default: + break; + } + return pixel; +} + + +Pixel Image::getPixel_ (int x, int y) +{ + if (!good() || + (x < 0) || + (x >= width) || + (y < 0) || + (y >= height)) + { + Pixel pixel; + memset(&pixel, 0, sizeof(Pixel)); + return pixel; + } + + return getPixel(x,y); +} + + +Pixel& Image::getPixel (int x, int y, Pixel& pixel) +{ + assert(good()); + assert((x >= 0) && + (x < width) && + (y >= 0) && + (y < height)); + + memset(&pixel, 0, sizeof(Pixel)); + + switch (channels) + { + case 4: + pixel.a = pixels[index(x,y,IALPHA)] / 255.0; + + case 3: + pixel.b = pixels[index(x,y,IBLUE)] / 255.0; + pixel.g = pixels[index(x,y,IGREEN)] / 255.0; + + case 1: + pixel.r = pixels[index(x,y,IRED)] / 255.0; + + default: + break; + } + return pixel; +} + + +Pixel& Image::getPixel_ (int x, int y, Pixel& pixel) +{ + if (!good() || + (x < 0) || + (x >= width) || + (y < 0) || + (y >= height)) + { + memset(&pixel, 0, sizeof(Pixel)); + return pixel; + } + + return getPixel(x,y,pixel); +} + + +void Image::setPixel (int x, int y, int channel, double value) +{ + assert(good()); + assert ( (channel >= 0) && (channel < channels)); + assert( (value >= 0.0) && (value <= 1.0)); + + if ( (x >= 0) && (x < width) && (y >= 0) && (y < height) ) + pixels[index(x,y,channel)] = val2bits(value, bits); +} + +void Image::setPixel_ (int x, int y, int channel, double value) +{ + if (!good() || + (x < 0) || + (x >= width) || + (y < 0) || + (y >= height) || + (channel < 0) || + (channel >= channels) || + (value < 0.0) || + (value > 1.0)) + return; + + setPixel(x,y,channel,value); +} + +void Image::setPixel4 ( int x, int y, Pixel pixel ) +{ + setPixel ( x, y, pixel ); + setPixel ( x+1, y, pixel ); + setPixel ( x, y+1, pixel ); + setPixel ( x+1, y+1, pixel ); +} + +void Image::setPixel (int x, int y, Pixel pixel) +{ + assert(good()); + if ( x < 0 || x >= width || y < 0 || y >= height ) return; + + switch (channels) + { + case 4: + pixels[index(x,y,IALPHA)] = val2bits(pixel.a, bits); + + case 3: + pixels[index(x,y,IBLUE)] = val2bits(pixel.b, bits); + pixels[index(x,y,IGREEN)] = val2bits(pixel.g, bits); + + case 1: + pixels[index(x,y,IRED)] = val2bits(pixel.r, bits); + + default: + break; + } +} + +void Image::setAlpha (int x, int y, double value) +{ + assert(good()); + pixels[index(x,y,IALPHA)] = val2bits(value, bits); +} + + +void Image::setPixel_ (int x, int y, Pixel pixel) +{ + if (!good() || + (x < 0) || + (x >= width) || + (y < 0) || + (y >= height)) + return; + + setPixel(x,y,pixel); +} + + +#ifndef DISABLE_OPENGL + +void Image::glReadPixelsWrapper () +{ + assert(good()); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + switch (channels) + { + case 1: + glReadPixels(0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + break; + case 3: + glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + break; + case 4: + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + break; + default: + break; + } +} + +void Image::glDrawPixelsWrapper () +{ + assert(good()); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + switch (channels) + { + case 1: + glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + break; + case 3: + glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + break; + + case 4: + glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + break; + + default: + break; + } +} + +void Image::refresh () +{ + glTexImage2DWrapper (); +} + + +void Image::glTexImage2DWrapper () +{ + assert(good()); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + switch (channels) + { + case 1: + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + break; + + case 3: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, pixels); + break; + + case 4: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + break; + + default: + break; + } +} + +void Image::glTexImageCubeWrapper ( int i ) +{ + assert(good()); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + switch (channels) + { + case 1: + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_LUMINANCE, width, height, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + break; + case 3: + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGB, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, pixels); + break; + case 4: + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + break; + default: + break; + } +} + +void Image::glTexSubImage2DWrapper ( int x, int y) +{ + assert(good()); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + switch (channels) + { + case 1: + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, + GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + break; + + case 3: + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, + GL_RGB, GL_UNSIGNED_BYTE, pixels); + break; + + case 4: + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + break; + + default: + break; + } +} + + +#endif // DISABLE_OPENGL + +int Image::read (const char* filename ) +{ + return read ( filename, 0x0 ); +} + +int Image::read (const char* filename, const char* alphaname ) +{ + FILE *file, *file_a; + + // Open image file + file = fopen( filename, "rb" ); + if (!file) { + printf ( "Cannot find file: %s\n", filename ); + perror("Image::read"); + return -1; + } + // Open alpha file + if ( alphaname != 0x0 ) { + file_a = fopen( alphaname, "rb" ); + if (!file_a) { + printf ( "Cannot find file: %s\n", alphaname ); + perror("Image::read"); + return -1; + } + } else { + file_a = 0x0; + } + // Get image file format + unsigned char type[4]; + fread((void*) type, sizeof(char), 4, file); + if (ferror(file)) { + fclose(file); + printf ( "Error reading file: %s\n", filename ); + perror("Image::read"); + return -1; + } + + int result = 0; + + fseek(file, 0, SEEK_SET); + + if (type[0] == 'P' && (type[1] == '1' || type[1] == '2' || type[1] == '3' || type[1] == '5' || type[1] == '6')) { + result = readPNM(file); + } else if ((type[0] == 0x4D && type[1] == 0x42) || (type[1] == 0x4D && type[0] == 0x42)) { + result = readBMP(file, file_a, true ); + } else if (type[0] == 0x49 && type[1] == 0x49 && type[2] == 0x42 ) { + //result = readTIF(file); + } +#ifdef USE_JPEG + else if ((type[0] == 0xD8 && type[1] == 0xFF) || (type[1] == 0xD8 && type[0] == 0xFF)) { + result = readJPG(file); + } +#endif + else { + fprintf( stderr, "Image::read: Unrecognized file type.\nMaybe it is a JPEG file. Either supply the file or set USE_JPEG.\n" ); + result = -1; + } + fclose(file); + return result; +} + + +int Image::write (const char* filename) +{ + size_t len = strlen(filename); + const char* ext = &(filename[len-4]); + int result = 0; + + if (strncmp(ext, ".pnm", 4) == 0) + { + result = writePNM(filename); + } + else if (strncmp(ext, ".bmp", 4) == 0) + { + result = writeBMP(filename); + } +#ifdef USE_JPEG + else if (strncmp(ext, ".jpg", 4) == 0) + { + result = writeJPG(filename); + } +#endif + else + { + char filenamewithext[1024]; +#ifdef WIN32 + _snprintf( filenamewithext, 1024, "%.1019s.pnm", filename ); +#else + snprintf( filenamewithext, 1024, "%.1019s.pnm", filename ); +#endif + result = writePNM(filenamewithext); + } + + return result; +} + +// +// .JPG file manipulation +// +// This code enabled only if JPEG is supported. +// +#ifdef USE_JPEG + + int Image::readJPG (const char* filename) + { + FILE* file = fopen(filename, "rb" ); + + if (!file) + { + printf ( "Cannot find file: %s\n", filename ); + perror("Image::readJPG"); + //_getch(); + return -1; + } + + int result = readJPG(file); + fclose(file); + + return result; + } + + + int Image::writeJPG (const char* filename) + { + FILE* file = fopen(filename, "wb"); + + if (!file) + { + perror("Image::writeJPG"); + return -1; + } + + int result = writeJPG(file); + fclose(file); + + if (result == -1) + unlink(filename); + + return result; + } + + + struct my_error_mgr + { + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; + }; + + + typedef struct my_error_mgr * my_error_ptr; + + + void my_error_exit (j_common_ptr cinfo) + { + my_error_ptr myerr = (my_error_ptr) cinfo->err; + (*cinfo->err->output_message) (cinfo); + longjmp(myerr->setjmp_buffer, 1); + } + + + int Image::readJPG (FILE* file) + { + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr; + JSAMPROW row_pointer[1]; + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + + // failure jump point + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_decompress(&cinfo); + fprintf(stderr, "Image::readJPG: jpeg decompression error"); + return -1; + } + + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, file); + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + if (cinfo.out_color_space != JCS_RGB && + cinfo.out_color_space != JCS_GRAYSCALE) + { + fprintf(stderr, "Image::readJPG: unrecognized colorspace"); + return -1; + } + + width = cinfo.output_width; + height = cinfo.output_height; + bits = 8; + channels = cinfo.out_color_components; + pixels = new unsigned char[width*height*channels]; + memset(pixels, 0, width*height*channels); + + int row_stride = width * channels; + + while (cinfo.output_scanline < cinfo.output_height) + { + row_pointer[0] = &pixels[(height - cinfo.output_scanline - 1) * row_stride]; + jpeg_read_scanlines(&cinfo, row_pointer, 1); + } + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + return 0; + } + + + int Image::writeJPG (FILE* file) + { + if (!good()) + { + fprintf(stderr, "Image::writeJPG: bad image\n"); + return -1; + } + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPROW row_pointer[1]; + int row_stride = width * channels; + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, file); + + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.input_components = channels; + cinfo.in_color_space = (channels == 3) ? JCS_RGB : JCS_GRAYSCALE; + + jpeg_set_defaults(&cinfo); + + jpeg_set_quality (&cinfo, 100, TRUE); + + jpeg_start_compress(&cinfo, TRUE); + + while (cinfo.next_scanline < cinfo.image_height) + { + row_pointer[0] = & pixels[(height - cinfo.next_scanline - 1) * row_stride]; + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + return 0; + } + +#endif // USE_JPEG + + + +// +// .BMP file manipulation +// + +int Image::readBMP (const char* filename ) +{ + FILE* file = fopen(filename, "rb"); + if (!file) + { + perror("Image::readBMP"); + return -1; + } + + int result = readBMP (file, 0x0, true); + fclose(file); + + return result; +} + + +int Image::writeBMP (const char* filename) +{ + FILE* file = fopen(filename, "wb"); + + if (!file) + { + perror("Image::writeBMP"); + return -1; + } + + int result = writeBMP(file); + fclose(file); + + if (result == -1) + unlink(filename); + + return result; +} + + +#if !defined(WIN32) + + typedef unsigned char BYTE; + typedef unsigned short int WORD; + typedef unsigned int DWORD; + typedef int LONG; + + + typedef struct tagBITMAPFILEHEADER { + WORD bfType; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; + } BITMAPFILEHEADER; + + + + typedef struct tagBITMAPINFOHEADER { + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; + } BITMAPINFOHEADER; + + /* constants for the biCompression field */ + #define BI_RGB 0L + #define BI_RLE8 1L + #define BI_RLE4 2L + #define BI_BITFIELDS 3L + + + typedef struct tagRGBTRIPLE { + BYTE rgbtBlue; + BYTE rgbtGreen; + BYTE rgbtRed; + } RGBTRIPLE; + + + typedef struct { //tagRGBQUAD + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; + BYTE rgbReserved; + } RGBQUAD; + +#endif // !defined(WIN32) + + +/* Some magic numbers */ + +#define BMP_BF_TYPE 0x4D42 +/* word BM */ + +#define BMP_BF_OFF_BITS 54 +/* 14 for file header + 40 for info header (not sizeof(), but packed size) */ + +#define BMP_BI_SIZE 40 +/* packed size of info header */ + + +/* Reads a WORD from a file in little endian format */ +static WORD WordReadLE (FILE* fp) +{ + WORD lsb, msb; + + lsb = fgetc(fp); + msb = fgetc(fp); + return (msb << 8) | lsb; +} + + + +/* Writes a WORD to a file in little endian format */ +static void WordWriteLE(WORD x, FILE* fp) +{ + BYTE lsb, msb; + + lsb = (BYTE) (x & 0x00FF); + msb = (BYTE) (x >> 8); + fputc(lsb, fp); + fputc(msb, fp); +} + + + +/* Reads a DWORD word from a file in little endian format */ +static DWORD DWordReadLE(FILE* fp) +{ + DWORD b1, b2, b3, b4; + + b1 = fgetc(fp); + b2 = fgetc(fp); + b3 = fgetc(fp); + b4 = fgetc(fp); + return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; +} + + + +/* Writes a DWORD to a file in little endian format */ +static void DWordWriteLE(DWORD x, FILE* fp) +{ + unsigned char b1, b2, b3, b4; + + b1 = (x & 0x000000FF); + b2 = ((x >> 8) & 0x000000FF); + b3 = ((x >> 16) & 0x000000FF); + b4 = ((x >> 24) & 0x000000FF); + fputc(b1, fp); + fputc(b2, fp); + fputc(b3, fp); + fputc(b4, fp); +} + + + +/* Reads a LONG word from a file in little endian format */ +static LONG LongReadLE(FILE* fp) +{ + LONG b1, b2, b3, b4; + + b1 = fgetc(fp); + b2 = fgetc(fp); + b3 = fgetc(fp); + b4 = fgetc(fp); + return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; +} + + + +/* Writes a LONG to a file in little endian format */ +static void LongWriteLE(LONG x, FILE* fp) +{ + char b1, b2, b3, b4; + + b1 = (x & 0x000000FF); + b2 = ((x >> 8) & 0x000000FF); + b3 = ((x >> 16) & 0x000000FF); + b4 = ((x >> 24) & 0x000000FF); + fputc(b1, fp); + fputc(b2, fp); + fputc(b3, fp); + fputc(b4, fp); +} + + +int bitcount (DWORD w) +{ + w = (0x55555555 & w) + (0x55555555 & (w>> 1)); + w = (0x33333333 & w) + (0x33333333 & (w>> 2)); + w = (0x0f0f0f0f & w) + (0x0f0f0f0f & (w>> 4)); + w = (0x00ff00ff & w) + (0x00ff00ff & (w>> 8)); + w = (0x0000ffff & w) + (0x0000ffff & (w>>16)); + return w; +} + + +// read BMP palette +int Image::readPaletteBMP ( FILE* fp, RGBQUAD*& palette, int bit_count ) +{ + bool bColor; + int palSize = 0; + switch ( bit_count ) { + case 1: palSize = 2; break; + case 4: palSize = 16; break; + case 8: palSize = 256; break; + } + if ( palSize != 0 ) { + palette = new RGBQUAD[ palSize ]; + memset(palette, 0, palSize * sizeof(RGBQUAD)); + fread((void*) palette, sizeof(RGBQUAD), palSize, fp ); + bColor = false; + for (int i = 0; !bColor && i < 2; ++i) { + bColor = bColor || (palette[i].rgbRed != palette[i].rgbGreen) || (palette[i].rgbBlue != palette[i].rgbGreen); + } + } else { + palette = 0x0; + } + return palSize; +} + + + +int Image::readBMP (FILE* fp, FILE* fp_a, bool bBaseImg ) +{ + RGBQUAD* palette; + int palSize; + int index; + Pixel pixel; + WORD red, green, blue; + DWORD bluemask, greenmask, redmask; + int bluewidth, greenwidth; + bool done; + + if ( bBaseImg ) { + if (pixels && owns) delete[] pixels; + } + + BITMAPFILEHEADER bmfh; + BITMAPINFOHEADER bmih; + + /* Read file header */ + bmfh.bfType = WordReadLE(fp); + bmfh.bfSize = DWordReadLE(fp); + bmfh.bfReserved1 = WordReadLE(fp); + bmfh.bfReserved2 = WordReadLE(fp); + bmfh.bfOffBits = DWordReadLE(fp); + + /* Check file header */ + if (bmfh.bfType != BMP_BF_TYPE) { + fprintf( stderr, "Image::readBMP: unrecognized type\n" ); + return -1; + } + + /* Read info header */ + bmih.biSize = DWordReadLE(fp); + bmih.biWidth = LongReadLE(fp); + bmih.biHeight = LongReadLE(fp); + bmih.biPlanes = WordReadLE(fp); + bmih.biBitCount = WordReadLE(fp); + bmih.biCompression = DWordReadLE(fp); + bmih.biSizeImage = DWordReadLE(fp); + bmih.biXPelsPerMeter = LongReadLE(fp); + bmih.biYPelsPerMeter = LongReadLE(fp); + bmih.biClrUsed = DWordReadLE(fp); + bmih.biClrImportant = DWordReadLE(fp); + + if ((bmih.biWidth <= 0) || (bmih.biHeight <= 0) || (bmih.biPlanes != 1)) { + fprintf(stderr, "Image::readBMP: malformed file\n"); + return -1; + } + + /* Creates the image */ + if ( bBaseImg ) { + // Create storage and load base image + width = bmih.biWidth; + height = bmih.biHeight; + + // Read palette (if there is one) + palSize = readPaletteBMP ( fp, palette, bmih.biBitCount ); + + switch ( bmih.biBitCount ) { + case 1: channels = 1; // 1 byte per bit - *bad storage, 2 color (B & W) + case 4: channels = 1; // 1 byte per 4-bits - not great, 16 color, index mode + case 8: channels = 1; // 1 byte per pixel, 256 color, index mode + case 16: channels = 3; // 2 byte per pixel, 16-bit color + case 24: channels = 3; // 3 byte per pixel (RGB), 24-bit color + case 32: channels = 3; // 4 byte per pixel, 32-bit color, compressed down to 24-bit + } + if ( palSize != 0 ) channels += 2; // use 3 channels for images with color palettes + if ( fp_a != 0x0 && channels == 3 ) channels = 4; // extra channel for alpha + + // Create storage for new image (including alpha) + bits = 8; + maxValue = 255; + pixels = new unsigned char[width*height*channels]; + owns = true; + memset(pixels, 0, width*height*channels); + } else { + // Load alpha image + bits = 8; + maxValue = 255; + + // Read palette (if there is one) + palSize = readPaletteBMP ( fp, palette, bmih.biBitCount ); + } + + // Determine line length + int scanlinelength; + if ((width * bmih.biBitCount) % 32 == 0) scanlinelength = width * bmih.biBitCount / 8; + else scanlinelength = (width * bmih.biBitCount / 32 + 1) * 4; + + + // Read all the color info / data + switch (bmih.biBitCount) { + case 1: // 1 bit - monochrome, index mode + BYTE* scanlineByte; + scanlineByte = new BYTE[scanlinelength]; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + for (int y = 0; y < height; ++y) { + fread((void*) scanlineByte, scanlinelength, 1, fp); + for (int x = 0; x < width; ++x) { + index = (scanlineByte[x/8] >> (7 - (x % 8))) & 0x01; + if ( bBaseImg ) { + pixel.r = palette[index].rgbRed / 255.0; + pixel.g = palette[index].rgbGreen / 255.0; + pixel.b = palette[index].rgbBlue / 255.0; + setPixel (x, height - 1 - y, pixel); + } else { + setAlpha (x, height - 1 - y, index / 255.0f ); + } + } + } + delete [] scanlineByte; + break; + case 4: // 4 bit - 16 color, index mode + if (bmih.biCompression == BI_RGB) { // 4-bit, uncompressed data + BYTE* scanlineByte; + scanlineByte = new BYTE[scanlinelength]; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + for (int y = 0; y < height; ++y) { + fread((void*) scanlineByte, scanlinelength, 1, fp); + for (int x = 0; x < width; ++x) { + if (x % 2 == 0) index = (scanlineByte[x/2] >> 4) & 0x0F; + else index = scanlineByte[x/2] & 0x0F; + if ( bBaseImg ) { + pixel.r = palette[index].rgbRed / 255.0; + pixel.g = palette[index].rgbGreen / 255.0; + pixel.b = palette[index].rgbBlue / 255.0; + setPixel (x, height - 1 - y, pixel); + } else { + setAlpha (x, height - 1 - y, index/255.0f); + } + } + } + delete [] scanlineByte; + } else if (bmih.biCompression == BI_RLE4) { // 4-bit RLE compression + unsigned char rleCode[2]; + int curx = 0; + int cury = 0; + done = false; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + while (!done && fp) { + fread((void*) rleCode, sizeof(char), 2, fp); + if (ferror(fp)) done = true; + if (rleCode[0] == 0 && rleCode[1] < 3) { // escape code (next byte is how) + if (rleCode[1] == 0) { // code 0 - goto next line + curx = 0; + ++cury; + if (cury >= height) done = true; + } else if (rleCode[1] == 1) { // code 1 - finished image + done = true; + } else { // otherwise - two bytes reposition read + curx += fgetc(fp); + cury += fgetc(fp); + } + } else if (rleCode[0] == 0) { // absolute code (next byte is length) + BYTE byte; + for (int i = 0; i < (rleCode[1] + 1) / 2; ++i) { + byte = fgetc(fp); + index = (byte >> 4) & 0x0F; + if ( bBaseImg ) { + pixel.r = palette[index].rgbRed / 255.0; + pixel.g = palette[index].rgbGreen / 255.0; + pixel.b = palette[index].rgbBlue / 255.0; + setPixel(curx, height - 1 - cury, pixel); + } else { + setAlpha(curx, height - 1 - cury, index/255.0f ); + } + ++curx; + index = byte & 0x0F; + if ( bBaseImg ) { + pixel.r = palette[index].rgbRed / 255.0; + pixel.g = palette[index].rgbGreen / 255.0; + pixel.b = palette[index].rgbBlue / 255.0; + setPixel(curx, height - 1 - cury, pixel); + } else { + setAlpha(curx, height - 1 - cury, index/255.0f ); + } + ++curx; + } + if (((rleCode[1] + 1) / 2) % 2 != 0) // byte align + fgetc(fp); + } else { + for (int i = 0; i < rleCode[0]; ++i) { + if (i % 2 == 0) index = (rleCode[1] >> 4) & 0x0F; + else index = rleCode[1] & 0x0F; + + if ( bBaseImg ) { + pixel.r = palette[index].rgbRed / 255.0; + pixel.g = palette[index].rgbGreen / 255.0; + pixel.b = palette[index].rgbBlue / 255.0; + setPixel(curx, height - 1 - cury, pixel); + } else { + setAlpha(curx, height - 1 - cury, index/255.0f ); + } + ++curx; + } + } + } + } // 8-bit compression cases + break; + case 8: // 8 bit - 256 color, index mode + // read the palette + if (bmih.biCompression == BI_RGB) { // uncompressed data + BYTE* scanlineByte; + scanlineByte = new BYTE[scanlinelength]; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + + for (int y = 0; y < height; ++y) { + fread((void*) scanlineByte, scanlinelength, 1, fp); + for (int x = 0; x < width; ++x) { + index = scanlineByte[x]; + if ( bBaseImg ) { + pixel.r = palette[index].rgbRed / 255.0; + pixel.g = palette[index].rgbGreen / 255.0; + pixel.b = palette[index].rgbBlue / 255.0; + setPixel(x, height - 1 - y, pixel); + } else { + setAlpha(x, height - 1 - y, index/255.0f ); + } + } + } + delete [] scanlineByte; + } else if (bmih.biCompression == BI_RLE8) { // 8-bit RLE compression + unsigned char rleCode[2]; + int curx = 0; + int cury = 0; + done = false; + + fseek(fp, bmfh.bfOffBits, SEEK_SET); + while (!done && fp) { + fread((void*) rleCode, sizeof(char), 2, fp); + if (ferror(fp)) done = true; + if (rleCode[0] == 0 && rleCode[1] < 3) { // escape + if (rleCode[1] == 0) { + curx = 0; + ++cury; + if (cury >= height) done = true; + } else if (rleCode[1] == 1) { + done = true; + } else { + curx += fgetc(fp); + cury += fgetc(fp); + } + } else if (rleCode[0] == 0) { // absolute mode + for (int i = 0; i < rleCode[1]; ++i) { + index = fgetc(fp); + if ( bBaseImg ) { + pixel.r = palette[index].rgbRed / 255.0; + pixel.g = palette[index].rgbGreen / 255.0; + pixel.b = palette[index].rgbBlue / 255.0; + setPixel (curx, height - 1 - cury, pixel); + } else { + setAlpha (curx, height - 1 - cury, index/255.0f); + } + ++curx; + } + if (rleCode[1] % 2 != 0) fgetc(fp); + } else { // encoded mode + pixel.r = palette[rleCode[1]].rgbRed / 255.0; + pixel.g = palette[rleCode[1]].rgbGreen / 255.0; + pixel.b = palette[rleCode[1]].rgbBlue / 255.0; + if ( bBaseImg ) { + for (int i = 0; i < rleCode[0]; ++i) { + setPixel(curx, height - 1 - cury, pixel); + ++curx; + } + } else { + for (int i = 0; i < rleCode[0]; ++i) { + setAlpha(curx, height - 1 - cury, rleCode[1]/255.0f ); + ++curx; + } + } + } + } // while not done + } // 8-bit compression cases + break; + case 16: // 16 bit - 2^16 color, rgb mode + if (bmih.biCompression == BI_BITFIELDS) { // user specified + redmask = DWordReadLE(fp); + greenmask = DWordReadLE(fp); + bluemask = DWordReadLE(fp); + bluewidth = bitcount(bluemask); + greenwidth = bitcount(greenmask); + } else { // bmih.biCompression == BI_RGB // using default values + bluemask = 0x001F; + bluewidth = 5; + greenmask = 0x03E0; + greenwidth = 5; + redmask = 0x7C00; + } + WORD* scanlineWord; + scanlineWord = new WORD[(scanlinelength+1)/2]; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + + for (int y = 0; y < height; ++y) { + fread( (void*) scanlineWord, scanlinelength, 1, fp); + for (int x = 0; x < width; ++x) { + if ( bBaseImg ) { + red = (scanlineWord[x] & redmask) + >> (bluewidth + greenwidth); + green = (scanlineWord[x] & greenmask) >> bluewidth; + blue = (scanlineWord[x] & bluemask); + pixel.r = red / 255.0; + pixel.g = green / 255.0; + pixel.b = blue / 255.0; + setPixel(x, height - 1 - y, pixel); + } else { + setAlpha(x, height - 1 - y, (scanlineWord[x]/65535.0f) ); + } + } + } + delete [] scanlineWord; + break; + case 24: // 24 bit - 2^24 color, rgb mode + RGBTRIPLE *scanline24; + scanline24 = new RGBTRIPLE[(scanlinelength+2)/3]; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + + for (int y = 0; y < height; ++y) { + fread((void*) scanline24, scanlinelength, 1, fp); + for (int x = 0; x < width; ++x) { + if ( bBaseImg ) { + pixel.r = scanline24[x].rgbtRed / 255.0; + pixel.g = scanline24[x].rgbtGreen / 255.0; + pixel.b = scanline24[x].rgbtBlue / 255.0; + setPixel(x, height - 1 - y, pixel); + } else { + setAlpha(x, height - 1 - y, scanline24[x].rgbtRed / 255.0f ); + } + } + } + delete [] scanline24; + break; + case 32: // 32 bit - 2^32 color, rgb mode + if (bmih.biCompression == BI_RGB) { // default encoding + RGBQUAD* scanline32; + scanline32 = new RGBQUAD[(scanlinelength+3)/4]; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + for (int y = 0; y < height; ++y) { + fread((void*) scanline32, scanlinelength, 1, fp); + for (int x = 0; x < width; ++x) { + if ( bBaseImg ) { + pixel.r = scanline32[x].rgbRed / 255.0; + pixel.g = scanline32[x].rgbGreen / 255.0; + pixel.b = scanline32[x].rgbBlue / 255.0; + setPixel(x, height - 1 - y, pixel); + } else { + setAlpha(x, height - 1 - y, scanline32[x].rgbRed / 255.0f ); + } + } + } + delete [] scanline32; + } else if (bmih.biCompression == BI_BITFIELDS) { // user specified + // get masks and shifts + redmask = DWordReadLE(fp); + greenmask = DWordReadLE(fp); + bluemask = DWordReadLE(fp); + bluewidth = bitcount(bluemask); + greenwidth = bitcount(greenmask); + DWORD* scanlineDword; + scanlineDword = new DWORD[(scanlinelength+3)/4]; + fseek(fp, bmfh.bfOffBits, SEEK_SET); + + for (int y = 0; y < height; ++y) { + fread((void*) scanlineDword, scanlinelength, 1, fp); + for (int x = 0; x < width; ++x) { + if ( bBaseImg ) { + red = (scanlineDword[x] & redmask) + >> (bluewidth + greenwidth); + green = (scanlineDword[x] & greenmask) >> bluewidth; + blue = (scanlineDword[x] & bluemask); + + pixel.r = red / 255.0; + pixel.g = green / 255.0; + pixel.b = blue / 255.0; + setPixel(x, height - 1 - y, pixel); + } else { + setAlpha(x, height - 1 - y, (scanlineDword[x] / 65535.0f) ); + } + } + } + delete [] scanlineDword; + } + break; + }; // close select + + // Read alpha image (recursive call) + if ( bBaseImg && fp_a != 0x0 ) { + readBMP ( fp_a, 0x0, false ); + } + return 0; +} + + + +int Image::writeBMP (FILE* fp) +{ + if (!good()) + { + fprintf(stderr, "Image::writeBMP: bad image\n"); + return -1; + } + + BITMAPFILEHEADER bmfh; + BITMAPINFOHEADER bmih; + int lineLength; + + if (channels == 1) + lineLength = width; + else + lineLength = width * 3; + + if ((lineLength % 4) != 0) + lineLength = (lineLength / 4 + 1) * 4; + + /* Write file header */ + + bmfh.bfType = BMP_BF_TYPE; + bmfh.bfSize = BMP_BF_OFF_BITS + lineLength * height; + bmfh.bfReserved1 = 0; + bmfh.bfReserved2 = 0; + bmfh.bfOffBits = BMP_BF_OFF_BITS; + + if (channels == 1) + bmfh.bfOffBits += 256 * 4; + + WordWriteLE(bmfh.bfType, fp); + DWordWriteLE(bmfh.bfSize, fp); + WordWriteLE(bmfh.bfReserved1, fp); + WordWriteLE(bmfh.bfReserved2, fp); + DWordWriteLE(bmfh.bfOffBits, fp); + + /* Write info header */ + + bmih.biSize = BMP_BI_SIZE; + bmih.biWidth = width; + bmih.biHeight = height; + bmih.biPlanes = 1; + bmih.biBitCount = (channels == 1) ? 8 : 24; + bmih.biCompression = BI_RGB; + bmih.biSizeImage = lineLength * (DWORD) bmih.biHeight; + bmih.biXPelsPerMeter = 2925; + bmih.biYPelsPerMeter = 2925; + bmih.biClrUsed = (channels == 1) ? 256 : 0; + bmih.biClrImportant = 0; + + DWordWriteLE(bmih.biSize, fp); + LongWriteLE(bmih.biWidth, fp); + LongWriteLE(bmih.biHeight, fp); + WordWriteLE(bmih.biPlanes, fp); + WordWriteLE(bmih.biBitCount, fp); + DWordWriteLE(bmih.biCompression, fp); + DWordWriteLE(bmih.biSizeImage, fp); + LongWriteLE(bmih.biXPelsPerMeter, fp); + LongWriteLE(bmih.biYPelsPerMeter, fp); + DWordWriteLE(bmih.biClrUsed, fp); + DWordWriteLE(bmih.biClrImportant, fp); + + /* Write pixels */ + + Pixel pixel; + + if (channels == 1) + { + // write 8-bit grayscale palette + + unsigned char palettecolor[4]; + for (int i = 0; i < 256; ++i) + { + memset(palettecolor, (unsigned char) i, 4); + fwrite((void*) palettecolor, sizeof(char), 4, fp); + } + + // write image data + + for (int y = 0; y < height; ++y) + { + int nbytes = 0; + for (int x = 0; x < width; ++x) + { + getPixel(x, height - y - 1, pixel); + fputc((int) (pixel.r * 255), fp); + nbytes++; + } + + while ((nbytes % 4) != 0) + { + fputc(0, fp); nbytes++; + } + } + } + else + { + for (int y = 0; y < height; ++y) + { + int nbytes = 0; + for (int x = 0; x < width; ++x) + { + getPixel(x, height - y - 1, pixel); + fputc((int) (pixel.b * 255), fp); nbytes++; + fputc((int) (pixel.g * 255), fp); nbytes++; + fputc((int) (pixel.r * 255), fp); nbytes++; + } + + while ((nbytes % 4) != 0) + { + fputc(0, fp); + nbytes++; + } + } + } + + if (ferror(fp)) + { + perror("Image::writeBMP"); + return -1; + } + + return 0; +} + + + +/****************************************************************** +* .PNM file manipulation +*/ + + +#define PNM_ASCII 0 +#define PNM_BINARY 1 +#define PNM_PBM 10 +#define PNM_PGM 11 +#define PNM_PPM 12 + + +int Image::readPNM (const char* filename) +{ + FILE* file = fopen(filename, "rb"); + + if (!file) + { + perror("Image::readPNM"); + return -1; + } + + int result = readPNM(file); + fclose(file); + + return result; +} + + +int Image::writePNM (const char* filename) +{ + FILE* file = fopen(filename, "wb"); + + if (!file) + { + perror("Image::writePNM"); + return -1; + } + + int result = writePNM(file); + fclose(file); + + if (result == -1) + unlink(filename); + + return result; +} + + +static inline void getWord (FILE* fp, char* s) +{ + fscanf(fp, "%1023s", s); +} + + +static inline void getLine (FILE* fp, char* s) +{ + fgets(s, 1024, fp); +} + + +static inline void getWordSkipComments (FILE* fp, char* s) +{ + getWord(fp, s); + while (s[0] == '#' && !ferror(fp)) + { + getLine(fp, s); + getWord(fp, s); + } +} + + +int Image::readPNM (FILE* fp) +{ + if (pixels && owns) + delete[] pixels; + pixels = NULL; + + char nextLine[1024]; + + getWord(fp, nextLine); + + int mode, type; + + if (nextLine[0] == 'P') + { + switch (nextLine[1]) + { + case '1': + mode = PNM_ASCII; + type = PNM_PBM; + channels = 1; + break; + + case '2': + mode = PNM_ASCII; + type = PNM_PGM; + channels = 1; + break; + + case '3': + mode = PNM_ASCII; + type = PNM_PPM; + channels = 3; + break; + + case '5': + mode = PNM_BINARY; + type = PNM_PGM; + channels = 1; + break; + + case '6': + mode = PNM_BINARY; + type = PNM_PPM; + channels = 3; + break; + + default: + fprintf( stderr, "Image::readPNM: malformed file\n" ); + return -1; + } + } + else + { + fprintf( stderr, "Image::readPNM: malformed file\n" ); + return -1; + } + + getWordSkipComments(fp, nextLine); + width = atoi(nextLine); + + getWordSkipComments(fp, nextLine); + height = atoi(nextLine); + + if (type != PNM_PBM) + { + getWordSkipComments(fp, nextLine); + maxValue = atoi(nextLine); + } + else + { + maxValue = 1; + } + + if (ferror(fp)) + { + perror("Image::readPNM"); + return -1; + } + + if (width <= 0 || height <= 0 || maxValue <= 0) + { + fprintf( stderr, "Image::readPNM: malformed file\n" ); + return -1; + } + + bits = (int) ceil(log10(maxValue + 1.0) / log10(2.0)); + pixels = new unsigned char[width*height*channels]; + owns = true; + memset(pixels, 0, width*height*channels); + + int red, blue, green, intensity; + Pixel pixel; + BYTE *scanlineByte; + RGBTRIPLE *scanline24; + + if (mode == PNM_ASCII) + { + if (type == PNM_PBM || type == PNM_PGM) + { + for (int y = 0; y < height; ++y) + { + for (int x = 0; x < width; ++x) + { + fscanf(fp, "%d", &intensity); + if (ferror(fp)) + { + perror("Image::readPNM"); + delete[] pixels; + pixels = NULL; + return -1; + } + + pixel.r = intensity / (float) maxValue; + setPixel(x,y,pixel); + } + } + } + else if (type == PNM_PPM) + { + for (int y = 0; y < height; ++y) + { + for (int x = 0; x < width; ++x) + { + fscanf(fp, "%d %d %d", &red, &green, &blue); + if (ferror(fp)) + { + perror("Image::readPNM"); + delete[] pixels; + pixels = NULL; + return -1; + } + + pixel.r = red / (float) maxValue; + pixel.g = green / (float) maxValue; + pixel.b = blue / (float) maxValue; + setPixel(x,y,pixel); + } + } + } + } + else if (mode == PNM_BINARY) + { + // move buffer up to the data's start + fgetc(fp); + + if (type == PNM_PGM) + { + scanlineByte = new BYTE[width]; + + for (int y = 0; y < height; ++y) + { + fread((void*) scanlineByte, sizeof(BYTE), width, fp); + if (ferror(fp)) + { + perror("Image::readPNM"); + delete[] scanlineByte; + delete[] pixels; + pixels = NULL; + return -1; + } + + for (int x = 0; x < width; ++x) + { + pixel.r = scanlineByte[x] / (float) maxValue; + setPixel(x,y,pixel); + } + } + + delete[] scanlineByte; + } + else if (type == PNM_PPM) + { + scanline24 = new RGBTRIPLE[width]; + + for (int y = 0; y < height; ++y) + { + fread((void*) scanline24, sizeof(RGBTRIPLE), width, fp); + if (ferror(fp)) + { + perror("Image::readPNM"); + delete[] scanline24; + delete[] pixels; + pixels = NULL; + return -1; + } + + for (int x = 0; x < width; ++x) + { + pixel.b = scanline24[x].rgbtRed / (float) maxValue; + pixel.g = scanline24[x].rgbtGreen / (float) maxValue; + pixel.r = scanline24[x].rgbtBlue / (float) maxValue; + + setPixel(x,y,pixel); + } + } + + delete[] scanline24; + } + } + + return 0; +} + + +int Image::writePNM (FILE* fp) +{ + if (!good()) + { + fprintf(stderr, "Image::writePNM: bad image\n"); + return -1; + } + + if (channels == 1) + { + if (bits == 1) + { + fprintf(fp, "P1\n"); + fprintf(fp, "%d %d\n", width, height); + + for (int j = 0; j < height; ++j) + { + for (int i = 0; i < width; ++i) + { + fprintf(fp, "%d ", pixels[index(i,j,0)] * maxValue / 255); + } + fprintf(fp, "\n"); + } + } + else + { + fprintf(fp, "P2\n"); + fprintf(fp, "%d %d %d\n", width, height, maxValue); + + for (int j = 0; j < height; ++j) + { + for (int i = 0; i < width; ++i) + { + fprintf(fp, "%d ", pixels[index(i,j,0)] * maxValue / 255); + } + fprintf(fp, "\n"); + } + } + } + else + { + fprintf(fp, "P3\n"); + fprintf(fp, "%d %d %d\n", width, height, maxValue); + + for (int j = 0; j < height; ++j) + { + for (int i = 0; i < width; ++i) + { + fprintf(fp, "%d %d %d ", + pixels[index(i,j,0)] * maxValue / 255, + pixels[index(i,j,1)] * maxValue / 255, + pixels[index(i,j,2)] * maxValue / 255); + } + fprintf(fp, "\n"); + } + } + + return 0; +} diff --git a/Extras/sph/common/image.h b/Extras/sph/common/image.h new file mode 100644 index 0000000..6da5e1f --- /dev/null +++ b/Extras/sph/common/image.h @@ -0,0 +1,188 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +class Image; + +#ifndef IMAGE_H + #define IMAGE_H + + #include "common_defs.h" + #include + + #ifdef _MSC_VER + #include + #endif + + // Image class code below... + #define IRED 0 + #define IGREEN 1 + #define IBLUE 2 + #define IALPHA 3 + + class Pixel { + public: + Pixel () { r=0;g=0;b=0;a=1;} + Pixel ( double r_, double g_, double b_ ) {r = r_; g = g_; b = b_; a = 1.0; } + Pixel ( double r_, double g_, double b_, double a_ ) {r = r_; g = g_; b = b_; a = a_; } + double r; + double g; + double b; + double a; + }; + + #if defined(_MSC_VER) && defined(USE_JPEG) + #pragma comment(lib, "jpegd.lib" ) + #endif + + /* + * generic multi channel 8-bit max image class. can read and write + * BMP, ascii PNM, and JPG file formats, and supports some useful OpenGL + * calls. + * + * get and set pixel methods use doubles from 0.0 to 1.0. these + * values are mapped to integer values from 0 to the maximum value + * allowed by the number of bits per channel in the image. + */ + class Image { + public: + Image (); + ~Image (); + + // create empty image with specified characteristics + Image (int width_, int height_); + Image (int width_, int height_, int channels_); + Image (int width_, int height_, int channels_, + int bits_); + + // create image and read data from filename + // use good() or bad() to check success + Image (const char* filename); + + // copy constructor and assignment operator + // _deep_ copy! + Image (const Image& image); + Image& operator= (const Image& image); + + // accessors + int getWidth () { return width; } + int getHeight () { return height; } + int getChannels () { return channels; } + int getBits () { return bits; } + unsigned char* getPixels () { return pixels; } + + void create ( int width_, int height_, int channels_ ); + + void refresh (); + + void draw (); + void draw ( float x, float y ); + + + // unsafe! use at your own risk! + void setPixels ( unsigned char *newPixels ); + + // check if the image is valid + bool good (); + bool bad (); + + // set all the pixel data + void clear (); + void clear ( Pixel pixel ); + + // retrieve pixel data. methods with _ at the + // end of their name return 0.0 if the x and y + // are out of range. otherwise, an assertion + // failure occurs + double getPixel (int x, int y, int channel); + double getPixel_ (int x, int y, int channel); + Pixel getPixel (int x, int y); + Pixel getPixel_ (int x, int y); + Pixel& getPixel (int x, int y, Pixel& pixel); + Pixel& getPixel_ (int x, int y, Pixel& pixel); + + // set pixel data. if x and y are out of range, + // an assertion failure occurs + void setPixel (int x, int y, int channel, double value); + void setPixel_ (int x, int y, int channel, double value); + void setPixel (int x, int y, Pixel pixel); + void setPixel_ (int x, int y, Pixel pixel); + void setPixel4 ( int x, int y, Pixel pixel ); + + void setAlpha (int x, int y, double value); + + #ifndef DISABLE_OPENGL + // OpenGL call wrappers + void glReadPixelsWrapper (); + void glDrawPixelsWrapper (); + void glTexImage2DWrapper (); + void glTexImageCubeWrapper ( int i ); + void glTexSubImage2DWrapper ( int x, int y); + #endif + + // top-level file read and write calls, + // determines file type + int read (const char* filename); + int read (const char* filename, const char* alphaname ); + int write (const char* filename); + + int readPaletteBMP ( FILE* fp, RGBQUAD*& palette, int bit_count ); + + // BMP specific read and write calls + int readBMP (const char* filename); + int readBMP (FILE* file, FILE* file_a, bool bBaseImg ); + int writeBMP (const char* filename); + int writeBMP (FILE* file); + + // PNM specific read and write calls + int readPNM (const char* filename); + int readPNM (FILE* file); + int writePNM (const char* filename); + int writePNM (FILE* file); + + #ifdef USE_JPEG + // JPG specific read and write calls + int readJPG (const char* filename); + int readJPG (FILE* file); + int writeJPG (const char* filename); + int writeJPG (FILE* file); + #endif + + private: + + int index(int x, int y, int c); + + int width; + int height; + int channels; // number of channels per pixel + int bits; // number of bits per channel + int maxValue; // max that can be stored in bits + + unsigned char* pixels; // image data + + bool owns; // if image owns pixels + + unsigned int imgID; + + }; + + +#endif // IMAGE_H diff --git a/Extras/sph/common/matrix-inline.h b/Extras/sph/common/matrix-inline.h new file mode 100644 index 0000000..1de585c --- /dev/null +++ b/Extras/sph/common/matrix-inline.h @@ -0,0 +1,1879 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "matrix.h" + +// MatrixC Code Definition +#define VNAME C +#define VTYPE unsigned char + +// Constructors/Destructors + +inline MatrixC::MatrixC (void) {data = NULL; Resize (0,0);} +inline MatrixC::~MatrixC (void) {if (data!=NULL) delete[] data;} +inline MatrixC::MatrixC (int r, int c) {data = NULL; Resize (c,r);} + +// Member Functions + + +inline VTYPE &MatrixC::operator () (int c, int r) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) Error.Print ( ErrorLev::Matrix, ErrorDef::MatrixIsNull, true ); + if (r<0 || r>=rows) Error.Print ( ErrorLev::Matrix, ErrorDef::RowOutOfBounds, true ); + if (c<0 || c>=cols) Error.Print ( ErrorLev::Matrix, ErrorDef::ColOutOfBounds, true ); + #endif + return *(data + (r*cols+c)); +} +inline MatrixC &MatrixC::operator= (unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n255) { + *n = (VTYPE) 255; + } else if (*b<=0) { + *n = (VTYPE) 0; + } else { + *n = (VTYPE) *b; + } + } + return *this; +} + +inline MatrixC &MatrixC::operator+= (unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n= bce) { // If last col in B.. + bs = op.data; // Go back to first column in B + as += cols; // Goto next row in A + } + n++; // Goto next element in C + } + delete[] data; // Destroy old A matrix + data = newdata; rows = newr; cols = newc; len = newlen; // Replace with new A matrix + } + return *this; +} + +inline MatrixC &MatrixC::Resize (int x, int y) +{ + if (data!=NULL) { + if (rows!=y || cols!=x) { + delete[] data; + len = (rows = y) * (cols = x); + data = new VTYPE[len]; + } + } else { + len = (rows = y) * (cols = x); data = new VTYPE[len]; + } + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixC::Resize: Out of memory for construction.\n"); + #endif + #ifdef MATRIX_INITIALIZE + memset (data, 0, sizeof(VTYPE)*len); + #endif + return *this; +} +inline MatrixC &MatrixC::ResizeSafe (int x, int y) +{ + VTYPE *newdata; + int newlen; + VTYPE *n, *ne; + VTYPE *b, *be; + int bskip; + + + if (data!=NULL) { + newlen = x*y; + newdata = new VTYPE[newlen]; + #ifdef DEBUG_MATRIX + if (newdata==NULL) + Debug.Print (DEBUG_MATRIX, "MatrixC::SizeSafe: Out of memory for construction.\n"); + #endif + if (y>=rows && x>=cols) { // New size is larger (in both r and c) + memset (newdata, 0, newlen*sizeof(VTYPE)); // Clear new matrix + ne = data + len; // Calculate end of current matrix + b = newdata; // Start of new matrix + be = newdata + cols; // Last filled column+1 in new matrix + bskip = x-cols; + for (n = data; n0) { + n = data; // Copy columns to left of c + ne = data + len; + nskip = (cols-c); + b = newdata; + be = newdata + c; + bskip = (cols-c)+1; + for (; n Ainv + // b -> solution x + // + + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixC::GaussJordan: Not implemented for char matrix\n"); + #endif + return *this; +} +inline int MatrixC::GetX() {return cols;} +inline int MatrixC::GetY() {return rows;} +inline int MatrixC::GetRows(void) {return rows;} +inline int MatrixC::GetCols(void) {return cols;} +inline int MatrixC::GetLength(void) {return len;} +inline VTYPE *MatrixC::GetData(void) {return data;} + +inline double MatrixC::GetF (int r, int c) {return (double) (*(data + r*cols + c));} + +#undef VTYPE +#undef VNAME + +// MatrixI Code Definition +#define VNAME I +#define VTYPE int + +// Constructors/Destructors + +inline MatrixI::MatrixI (void) {data = NULL; Resize (0,0);} +inline MatrixI::~MatrixI (void) {if (data!=NULL) delete[] data;} +inline MatrixI::MatrixI (int r, int c) {data = NULL; Resize (c,r);} + +// Member Functions + +inline VTYPE &MatrixI::operator () (int c, int r) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixI::op(): Matrix data is null\n"); + if (r<0 || r>=rows) Debug.Print (DEBUG_MATRIX, "MatrixI:op(): Row is out of bounds\n"); + if (c<0 || c>=cols) Debug.Print (DEBUG_MATRIX, "MatrixI:op(): Col is out of bounds\n"); + #endif + return *(data + (r*cols+c)); +} +inline MatrixI &MatrixI::operator= (unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n= bce) { // If last col in B.. + bs = op.data; // Go back to first column in B + as += cols; // Goto next row in A + } + n++; // Goto next element in C + } + delete[] data; // Destroy old A matrix + data = newdata; rows = newr; cols = newc; len = newlen; // Replace with new A matrix + } + return *this; +} + +inline MatrixI &MatrixI::Resize (int x, int y) +{ + if (data!=NULL) { + if (rows!=y || cols!=x) {delete[] data; len = (rows = y) * (cols = x); data = new VTYPE[len];} + } else { + len = (rows = y) * (cols = x); data = new VTYPE[len]; + } + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixC::Size: Out of memory for construction.\n"); + #endif + #ifdef MATRIX_INITIALIZE + memset (data, 0, sizeof(VTYPE)*len); + #endif + return *this; +} +inline MatrixI &MatrixI::ResizeSafe (int x, int y) +{ + VTYPE *newdata; + int newlen; + VTYPE *n, *ne; + VTYPE *b, *be; + int bskip; + + + if (data!=NULL) { + newlen = x*y; + newdata = new VTYPE[newlen]; + #ifdef DEBUG_MATRIX + if (newdata==NULL) + Debug.Print (DEBUG_MATRIX, "MatrixC::SizeSafe: Out of memory for construction.\n"); + #endif + if (y>=rows && x>=cols) { // New size is larger (in both r and c) + memset (newdata, 0, newlen*sizeof(VTYPE)); // Clear new matrix + ne = data + len; // Calculate end of current matrix + b = newdata; // Start of new matrix + be = newdata + cols; // Last filled column+1 in new matrix + bskip = x-cols; + for (n = data; n0) { + n = data; // Copy columns to left of c + ne = data + len; + nskip = (cols-c); + b = newdata; + be = newdata + c; + bskip = (cols-c)+1; + for (; n Ainv + // b -> solution x + // + + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixI::GaussJordan: Not implemented for int matrix\n"); + #endif + return *this; +} +inline int MatrixI::GetX() {return cols;} +inline int MatrixI::GetY() {return rows;} +inline int MatrixI::GetRows(void) {return rows;} +inline int MatrixI::GetCols(void) {return cols;} +inline int MatrixI::GetLength(void) {return len;} +inline VTYPE *MatrixI::GetData(void) {return data;} + +inline double MatrixI::GetF (int r, int c) {return (double) (*(data + r*cols + c));} + +#undef VTYPE +#undef VNAME + + +// MatrixF Code Definition +#define VNAME F +#define VTYPE double + +// Constructors/Destructors + +inline MatrixF::MatrixF (void) {data = NULL; Resize (0,0);} + +inline MatrixF::~MatrixF (void) { + if (data!=NULL) + delete [] data; +} +inline MatrixF::MatrixF (const int r, const int c) {data = NULL; Resize (r,c);} + +// Member Functions + +inline VTYPE MatrixF::GetVal ( int c, int r ) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) Error.Print ( ErrorLev::Matrix, ErrorDef::MatrixIsNull, true ); + if (r<0 || r>=rows) Error.Print ( ErrorLev::Matrix, ErrorDef::RowOutOfBounds, true ); + if (c<0 || c>=cols) Error.Print ( ErrorLev::Matrix, ErrorDef::ColOutOfBounds, true ); + #endif + return *(data + (r*cols+c)); +} + +inline VTYPE &MatrixF::operator () (const int c, const int r) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) + Error.Print ( ErrorLev::Matrix, ErrorDef::MatrixIsNull, true ); + if (r<0 || r>=rows) + Error.Print ( ErrorLev::Matrix, ErrorDef::RowOutOfBounds, true ); + if (c<0 || c>=cols) + Error.Print ( ErrorLev::Matrix, ErrorDef::ColOutOfBounds, true ); + #endif + return *(data + (r*cols+c)); +} +inline MatrixF &MatrixF::operator= (const unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n= bce) { // If last col in B.. + bs = op.data; // Go back to first column in B + as += cols; // Goto next row in A + } + n++; // Goto next element in C + } + delete[] data; // Destroy old A matrix + data = newdata; rows = newr; cols = newc; len = newlen; // Replace with new A matrix + } + return *this; +} + +inline MatrixF &MatrixF::Multiply4x4 (const MatrixF &op) { + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Matrix data is null\n"); + if (op.data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Operand matrix (op) data is null\n"); + if (rows!=4 || cols!=4) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Matrix m is not 4x4"); + if (op.rows!=4 || op.cols!=4) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Matrix op is not 4x4"); + #endif + register double c1, c2, c3, c4; // Temporary storage + VTYPE *n, *a, *b1, *b2, *b3, *b4; + a = data; n = data; + b1 = op.data; b2 = op.data + 4; b3 = op.data + 8; b4 = op.data + 12; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a++; // Calculate First Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + b1 -= 3 ; b2 -= 3; b3 -= 3; b4 -= 3; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a++; // Calculate Second Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + b1 -= 3 ; b2 -= 3; b3 -= 3; b4 -= 3; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a++; // Calculate Third Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + b1 -= 3 ; b2 -= 3; b3 -= 3; b4 -= 3; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a; // Calculate Four Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + + return *this; +} + + +inline MatrixF &MatrixF::Resize (const int x, const int y) +{ + if (data!=NULL) { + if (rows==y && cols==x) return *this; + delete[] data; + } + rows = y; cols = x; + if (y>0 && x>0) { + len = rows * cols; + if (len!=0) { + data = new VTYPE[len]; + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixF::Size: Out of memory for construction.\n"); + #endif + } + } + + #ifdef MATRIX_INITIALIZE + if (data!=NULL) memset (data, 0, sizeof(VTYPE)*len); + #endif + return *this; +} +inline MatrixF &MatrixF::ResizeSafe (const int x, const int y) +{ + VTYPE *newdata; + int newlen; + VTYPE *n, *ne; + VTYPE *b, *be; + int bskip; + + if (data!=NULL) { + newlen = x*y; + newdata = new VTYPE[newlen]; + #ifdef DEBUG_MATRIX + if (newdata==NULL) + Debug.Print (DEBUG_MATRIX, "MatrixF::SizeSafe: Out of memory for construction.\n"); + #endif + if (y>=rows && x>=cols) { // New size is larger (in both r and c) + memset (newdata, 0, newlen*sizeof(VTYPE)); // Clear new matrix + ne = data + len; // Calculate end of current matrix + b = newdata; // Start of new matrix + be = newdata + cols; // Last filled column+1 in new matrix + bskip = x-cols; + for (n = data; n0) { + n = data; // Copy columns to left of c + ne = data + len; + nskip = (cols-c); + b = newdata; + be = newdata + c; + bskip = (cols-c)+1; + for (; n>counter-clockwise<< when looking down the X+ axis toward the origin +inline MatrixF &MatrixF::RotateX (const double ang) +{ + Resize (4,4); + VTYPE *n = data; + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + *n = 1; n += 5; + *n++ = (VTYPE) c; *n = (VTYPE) s; n+=3; + *n++ = (VTYPE) -s; *n = (VTYPE) c; n+=5; + *n = 1; + return *this; +} + +// rotates points >>counter-clockwise<< when looking down the Y+ axis toward the origin +inline MatrixF &MatrixF::RotateY (const double ang) +{ + Resize (4,4); + VTYPE *n = data; + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + *n = (VTYPE) c; n+=2; + *n = (VTYPE) -s; n+=3; + *n = 1; n+=3; + *n = (VTYPE) s; n+=2; + *n = (VTYPE) c; n+=5; + *n = 1; + return *this; +} + +// rotates points >>counter-clockwise<< when looking down the Z+ axis toward the origin +inline MatrixF &MatrixF::RotateZ (const double ang) +{ + Resize (4,4); + VTYPE *n = data; + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + *n++ = (VTYPE) c; *n = (VTYPE) s; n+=3; + *n++ = (VTYPE) -s; *n = (VTYPE) c; n+=5; + *n = 1; n+=5; *n = 1; + return *this; +} +inline MatrixF &MatrixF::Ortho (double sx, double sy, double vn, double vf) +{ + // simplified version of OpenGL's glOrtho function + VTYPE *n = data; + *n++ = (VTYPE) (1.0/sx); *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) (1.0/sy); *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) (-2.0/(vf-vn)); *n++ = (VTYPE) (-(vf+vn)/(vf-vn)); + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0; *n++ = (VTYPE) 1.0; +} + +inline MatrixF &MatrixF::Translate (double tx, double ty, double tz) +{ + Resize (4,4); + VTYPE *n = data; + *n++ = (VTYPE) 1.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 1.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 1.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) tx; *n++ = (VTYPE) ty; *n++ = (VTYPE) tz; *n++ = (VTYPE) 1.0; + return *this; +} + +inline MatrixF &MatrixF::Basis (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3) +{ + Resize (4,4); + VTYPE *n = data; + *n++ = (VTYPE) c1.X(); *n++ = (VTYPE) c2.X(); *n++ = (VTYPE) c3.X(); *n++ = (VTYPE) 0; + *n++ = (VTYPE) c1.Y(); *n++ = (VTYPE) c2.Y(); *n++ = (VTYPE) c3.Y(); *n++ = (VTYPE) 0; + *n++ = (VTYPE) c1.Z(); *n++ = (VTYPE) c2.Z(); *n++ = (VTYPE) c3.Z(); *n++ = (VTYPE) 0; + *n++ = (VTYPE) 0; *n++ = (VTYPE) 0; *n++ = (VTYPE) 0; *n++ = (VTYPE) 0; + return *this; +} + +#define SWAP(a, b) {temp=(a); (a)=(b); (b)=temp;} + +inline MatrixF &MatrixF::GaussJordan (MatrixF &b) +{ + // Gauss-Jordan solves the matrix equation Ax = b + // Given the problem: + // A*x = b (where A is 'this' matrix and b is provided) + // The solution is: + // Ainv*b = x + // This function returns Ainv in A and x in b... that is: + // A (this) -> Ainv + // b -> solution x + // + + MatrixI index_col, index_row; + MatrixI piv_flag; + int r, c, c2, rs, cs; + double piv_val; + int piv_row, piv_col; + double pivinv, dummy, temp; + + #ifdef DEBUG_MATRIX + if (rows!=cols) Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Number of rows and cols of A must be equal.\n"); + if (rows!=b.rows) Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Number of rows of A and rows of b must be equal.\n"); + if (b.cols!=1) Debug.Print ( DEBUG_MATRIX, "MatrixF::GaussJordan: Number of cols of b must be 1.\n"); + #endif + + index_col.Resize (cols, 1); + index_row.Resize (cols, 1); + piv_flag.Resize (cols, 1); + piv_flag = 0; + for (c = 0; c < cols; c++) { + piv_val = 0.0; + for (rs = 0; rs < rows; rs++) { + if (piv_flag(rs, 0) != 1 ) + for (cs = 0; cs < cols; cs++) { + if (piv_flag(cs, 0) == 0) { + if (fabs((*this) (cs, rs)) >= piv_val) { + piv_val = fabs((*this) (cs, rs)); + piv_row = rs; + piv_col = cs; + } + } else if (piv_flag(cs, 0)>1) { + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Singular matrix (dbl pivs).\n"); + //Print (); + #endif + } + } + } + piv_flag(piv_col, 0)++; + if (piv_row != piv_col) { + for (c2 = 0; c2 < cols; c2++) SWAP ((*this) (c2, piv_row), (*this) (c2, piv_col)); + for (c2 = 0; c2 < b.cols; c2++) SWAP (b(c2, piv_row), b(c2, piv_col)); + } + index_row (c, 0) = piv_row; + index_col (c, 0) = piv_col; + if ((*this) (piv_col, piv_col) == 0.0) { + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Singular matrix (0 piv).\n"); + //Print (); + #endif + } + pivinv = 1.0 / ((*this) (piv_col, piv_col)); + (*this) (piv_col, piv_col) = 1.0; + for (c2 = 0; c2 < cols; c2++) (*this) (c2, piv_col) *= pivinv; + for (c2 = 0; c2 < b.cols; c2++) b(c2, piv_col) *= pivinv; + for (r = 0; r < rows; r++) { + if (r != piv_col) { + dummy = (*this) (piv_col, r); + (*this) (piv_col, r) = 0.0; + for (c2 = 0; c2 < cols; c2++) (*this) (c2, r) -= (*this) (c2, piv_col)*dummy; + for (c2 = 0; c2 < b.cols; c2++) b(c2, r) -= b(c2, piv_col)*dummy; + } + } + } + for (c = cols-1; c >= 0; c--) { + if (index_row(c, 0) != index_col(c, 0)) + for (r = 0; r < rows; r++) + SWAP ((*this) (index_row(c,0), r), (*this) (index_col(c,0), r) ); + } + return *this; +} +inline MatrixF &MatrixF::Submatrix ( MatrixF& b, int mx, int my) +{ + VTYPE* pEnd = data + rows*cols; // end of matrix + VTYPE* pVal = data; + VTYPE* pNewVal = b.data; + VTYPE* pNewEnd = pNewVal + mx; + int pNewSkip = cols - mx; + + for (pVal = data; pVal < pEnd;) { + for (; pNewVal < pNewEnd;) *pVal++ = *pNewVal++; + pNewVal += pNewSkip; + pNewEnd += mx; + } + return *this; +} + +// N-Vector Dot Product +// Elements may be in rows or columns, but: +// - If in rows, number of columns must be one and number of rows must match. +// - If in cols, number of rows must be one and number of cols must match. +inline double MatrixF::Dot ( MatrixF& b ) +{ + double d = 0.0; + VTYPE* pA = data; + VTYPE* pB = b.data; + + if ( rows==1 && b.rows==1 && cols == b.cols ) { + VTYPE* pAEnd = data + cols; + d = 0.0; + for (; pA < pAEnd;) + d += (*pA++) * (*pB++); + } else if ( cols==1 && b.cols==1 && rows == b.rows) { + VTYPE* pAEnd = data + rows; + d = 0.0; + for (; pA < pAEnd;) + d += (*pA++) * (*pB++); + } + return d; +} + +#define I(x, y) ( (y*xres) + x ) +#define Ix(r) ( r % xres ) // X coordinate from row +#define Iy(r) ( r / xres ) // Y coordinate from row + +inline MatrixF &MatrixF::MatrixVector5 (MatrixF& x, int mrows, MatrixF& b) +{ + double v; + + // A( 2, r ) * B ( r ) + A(1,r)*B(r-1) + A(3,r)*B(r+1) + A(0, r)*B( R-( r ) ) + A(4, r)*B( R+( r ) ) + for (int r = 0; r < mrows; r++) { + v = GetVal(2, r) * x(0,r); + if ( r > 0 ) v += GetVal(1,r) * x(0,r-1); + if ( r < mrows-1) v += GetVal(3,r) * x(0,r+1); + if ( (int) GetVal(5, r) >= 0) v += GetVal(0,r) * x(0, (int) GetVal(5,r)); + if ( (int) GetVal(6, r) >= 0) v += GetVal(4,r) * x(0, (int) GetVal(6,r)); + b(0,r) = v; + } + return *this; +} + +inline MatrixF &MatrixF::ConjugateGradient (MatrixF &b) +{ + return *this; +} + +// Sparse Conjugate Gradient 2D (special case) +// This compute conjugate gradients on a +// sparse "5-7" x N positive definite matrix. +// Only 'mrows' subset of the row-size of A and b will be used. +inline MatrixF &MatrixF::ConjugateGradient5 (MatrixF &b, int mrows ) +{ + double a, g, rdot; + int i, imax; + MatrixF x, xnew; // solution vector + MatrixF r, rnew; // residual + MatrixF p, ptemp; // search direction + MatrixF v; + + x.Resize ( 1, mrows ); + xnew.Resize ( 1, mrows ); + r.Resize ( 1, mrows ); + rnew.Resize ( 1, mrows ); + p.Resize ( 1, mrows ); + ptemp.Resize ( 1, mrows ); + v.Resize ( 1, mrows ); + + r.Submatrix ( b, 1, mrows); + MatrixVector5 ( x, mrows, v ); // (Ax -> v) + r -= v; // r = b - Ax + p = r; + + imax = 20; + for (i=0; i < imax; i++) { + MatrixVector5 ( p, mrows, v ); // v = Ap + rdot = r.Dot ( r ); + a = rdot / p.Dot ( v ); // a = (r . r) / (p . v) + xnew = p; + xnew *= a; + xnew += x; // x = x + p*a + v *= a; + rnew = r; // rnew = r - v*a + rnew -= v; + g = rnew.Dot ( rnew ) / rdot; // g = (rnew . rnew) / (r . r) + p *= g; + p += rnew; // p = rnew + p*g + r = rnew; + x = xnew; + } + for (int rx=0; rx < mrows; rx++) + b(0, rx) = x(0, rx); + return *this; +} + +inline int MatrixF::GetX() {return cols;} +inline int MatrixF::GetY() {return rows;} +inline int MatrixF::GetRows(void) {return rows;} +inline int MatrixF::GetCols(void) {return cols;} +inline int MatrixF::GetLength(void) {return len;} +inline VTYPE *MatrixF::GetData(void) {return data;} + +inline double MatrixF::GetF (const int r, const int c) {return (double) (*(data + r*cols + c));} + +inline void MatrixF::GetRowVec (int r, Vector3DF &v) +{ + VTYPE *n = data + r*cols; + v.x = *n++; v.y = *n++; v.z= *n++; +} + +inline void MatrixF::Print ( char* fname ) +{ + char buf[2000]; + + FILE* fp = fopen ( fname, "w+" ); + + for (int r=0; r < rows; r++) { + buf[0] = '\0'; + for (int c =0; c < cols; c++) { + sprintf ( buf, "%s %04.3f", buf, GetVal(c, r) ); + } + fprintf ( fp, "%s\n", buf); + } + fprintf ( fp, "---------------------------------------\n", buf); + fflush ( fp ); + fclose ( fp ); +} + +#undef VTYPE +#undef VNAME \ No newline at end of file diff --git a/Extras/sph/common/matrix.cci b/Extras/sph/common/matrix.cci new file mode 100644 index 0000000..37b7e0b --- /dev/null +++ b/Extras/sph/common/matrix.cci @@ -0,0 +1,2046 @@ + +// MatrixC Code Definition +#define VNAME C +#define VTYPE unsigned char + +// Constructors/Destructors + +inline MatrixC::MatrixC (void) {data = NULL; Resize (0,0);} +inline MatrixC::~MatrixC (void) {if (data!=NULL) delete[] data;} +inline MatrixC::MatrixC (int r, int c) {data = NULL; Resize (c,r);} + +// Member Functions + + +inline VTYPE &MatrixC::operator () (int c, int r) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) Error.Print ( ErrorLev::Matrix, ErrorDef::MatrixIsNull, true ); + if (r<0 || r>=rows) Error.Print ( ErrorLev::Matrix, ErrorDef::RowOutOfBounds, true ); + if (c<0 || c>=cols) Error.Print ( ErrorLev::Matrix, ErrorDef::ColOutOfBounds, true ); + #endif + return *(data + (r*cols+c)); +} +inline MatrixC &MatrixC::operator= (unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n255) { + *n = (VTYPE) 255; + } else if (*b<=0) { + *n = (VTYPE) 0; + } else { + *n = (VTYPE) *b; + } + } + return *this; +} + +inline MatrixC &MatrixC::operator+= (unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n= bce) { // If last col in B.. + bs = op.data; // Go back to first column in B + as += cols; // Goto next row in A + } + n++; // Goto next element in C + } + delete[] data; // Destroy old A matrix + data = newdata; rows = newr; cols = newc; len = newlen; // Replace with new A matrix + } + return *this; +} + +inline MatrixC &MatrixC::Resize (int x, int y) +{ + if (data!=NULL) { + if (rows!=y || cols!=x) { + delete[] data; + len = (rows = y) * (cols = x); + data = new VTYPE[len]; + } + } else { + len = (rows = y) * (cols = x); data = new VTYPE[len]; + } + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixC::Resize: Out of memory for construction.\n"); + #endif + #ifdef MATRIX_INITIALIZE + memset (data, 0, sizeof(VTYPE)*len); + #endif + return *this; +} +inline MatrixC &MatrixC::ResizeSafe (int x, int y) +{ + VTYPE *newdata; + int newlen; + VTYPE *n, *ne; + VTYPE *b, *be; + int bskip; + + + if (data!=NULL) { + newlen = x*y; + newdata = new VTYPE[newlen]; + #ifdef DEBUG_MATRIX + if (newdata==NULL) + Debug.Print (DEBUG_MATRIX, "MatrixC::SizeSafe: Out of memory for construction.\n"); + #endif + if (y>=rows && x>=cols) { // New size is larger (in both r and c) + memset (newdata, 0, newlen*sizeof(VTYPE)); // Clear new matrix + ne = data + len; // Calculate end of current matrix + b = newdata; // Start of new matrix + be = newdata + cols; // Last filled column+1 in new matrix + bskip = x-cols; + for (n = data; n0) { + n = data; // Copy columns to left of c + ne = data + len; + nskip = (cols-c); + b = newdata; + be = newdata + c; + bskip = (cols-c)+1; + for (; n Ainv + // b -> solution x + // + + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixC::GaussJordan: Not implemented for char matrix\n"); + #endif + return *this; +} +inline int MatrixC::GetX() {return cols;} +inline int MatrixC::GetY() {return rows;} +inline int MatrixC::GetRows(void) {return rows;} +inline int MatrixC::GetCols(void) {return cols;} +inline int MatrixC::GetLength(void) {return len;} +inline VTYPE *MatrixC::GetData(void) {return data;} + +inline double MatrixC::GetF (int r, int c) {return (double) (*(data + r*cols + c));} + +#undef VTYPE +#undef VNAME + +// MatrixI Code Definition +#define VNAME I +#define VTYPE int + +// Constructors/Destructors + +inline MatrixI::MatrixI (void) {data = NULL; Resize (0,0);} +inline MatrixI::~MatrixI (void) {if (data!=NULL) delete[] data;} +inline MatrixI::MatrixI (int r, int c) {data = NULL; Resize (c,r);} + +// Member Functions + +inline VTYPE &MatrixI::operator () (int c, int r) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixI::op(): Matrix data is null\n"); + if (r<0 || r>=rows) Debug.Print (DEBUG_MATRIX, "MatrixI:op(): Row is out of bounds\n"); + if (c<0 || c>=cols) Debug.Print (DEBUG_MATRIX, "MatrixI:op(): Col is out of bounds\n"); + #endif + return *(data + (r*cols+c)); +} +inline MatrixI &MatrixI::operator= (unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n= bce) { // If last col in B.. + bs = op.data; // Go back to first column in B + as += cols; // Goto next row in A + } + n++; // Goto next element in C + } + delete[] data; // Destroy old A matrix + data = newdata; rows = newr; cols = newc; len = newlen; // Replace with new A matrix + } + return *this; +} + +inline MatrixI &MatrixI::Resize (int x, int y) +{ + if (data!=NULL) { + if (rows!=y || cols!=x) {delete[] data; len = (rows = y) * (cols = x); data = new VTYPE[len];} + } else { + len = (rows = y) * (cols = x); data = new VTYPE[len]; + } + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixC::Size: Out of memory for construction.\n"); + #endif + #ifdef MATRIX_INITIALIZE + memset (data, 0, sizeof(VTYPE)*len); + #endif + return *this; +} +inline MatrixI &MatrixI::ResizeSafe (int x, int y) +{ + VTYPE *newdata; + int newlen; + VTYPE *n, *ne; + VTYPE *b, *be; + int bskip; + + + if (data!=NULL) { + newlen = x*y; + newdata = new VTYPE[newlen]; + #ifdef DEBUG_MATRIX + if (newdata==NULL) + Debug.Print (DEBUG_MATRIX, "MatrixC::SizeSafe: Out of memory for construction.\n"); + #endif + if (y>=rows && x>=cols) { // New size is larger (in both r and c) + memset (newdata, 0, newlen*sizeof(VTYPE)); // Clear new matrix + ne = data + len; // Calculate end of current matrix + b = newdata; // Start of new matrix + be = newdata + cols; // Last filled column+1 in new matrix + bskip = x-cols; + for (n = data; n0) { + n = data; // Copy columns to left of c + ne = data + len; + nskip = (cols-c); + b = newdata; + be = newdata + c; + bskip = (cols-c)+1; + for (; n Ainv + // b -> solution x + // + + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixI::GaussJordan: Not implemented for int matrix\n"); + #endif + return *this; +} +inline int MatrixI::GetX() {return cols;} +inline int MatrixI::GetY() {return rows;} +inline int MatrixI::GetRows(void) {return rows;} +inline int MatrixI::GetCols(void) {return cols;} +inline int MatrixI::GetLength(void) {return len;} +inline VTYPE *MatrixI::GetData(void) {return data;} + +inline double MatrixI::GetF (int r, int c) {return (double) (*(data + r*cols + c));} + +#undef VTYPE +#undef VNAME + + +// MatrixF Code Definition +#define VNAME F +#define VTYPE double + +// Constructors/Destructors + +inline MatrixF::MatrixF (void) {data = NULL; Resize (0,0);} + +inline MatrixF::~MatrixF (void) { + if (data!=NULL) + delete [] data; +} +inline MatrixF::MatrixF (const int r, const int c) {data = NULL; Resize (r,c);} + +// Member Functions + +inline VTYPE MatrixF::GetVal ( int c, int r ) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) Error.Print ( ErrorLev::Matrix, ErrorDef::MatrixIsNull, true ); + if (r<0 || r>=rows) Error.Print ( ErrorLev::Matrix, ErrorDef::RowOutOfBounds, true ); + if (c<0 || c>=cols) Error.Print ( ErrorLev::Matrix, ErrorDef::ColOutOfBounds, true ); + #endif + return *(data + (r*cols+c)); +} + +inline VTYPE &MatrixF::operator () (const int c, const int r) +{ + #ifdef DEBUG_MATRIX + if (data==NULL) + Error.Print ( ErrorLev::Matrix, ErrorDef::MatrixIsNull, true ); + if (r<0 || r>=rows) + Error.Print ( ErrorLev::Matrix, ErrorDef::RowOutOfBounds, true ); + if (c<0 || c>=cols) + Error.Print ( ErrorLev::Matrix, ErrorDef::ColOutOfBounds, true ); + #endif + return *(data + (r*cols+c)); +} +inline MatrixF &MatrixF::operator= (const unsigned char op) {VTYPE *n = data, *nlen = data + len; for (;n= bce) { // If last col in B.. + bs = op.data; // Go back to first column in B + as += cols; // Goto next row in A + } + n++; // Goto next element in C + } + delete[] data; // Destroy old A matrix + data = newdata; rows = newr; cols = newc; len = newlen; // Replace with new A matrix + } + return *this; +} + +inline MatrixF &MatrixF::Multiply4x4 (const MatrixF &op) { + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Matrix data is null\n"); + if (op.data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Operand matrix (op) data is null\n"); + if (rows!=4 || cols!=4) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Matrix m is not 4x4"); + if (op.rows!=4 || op.cols!=4) Debug.Print (DEBUG_MATRIX, "MatrixF::Multiply4x4 m*=op: Matrix op is not 4x4"); + #endif + register double c1, c2, c3, c4; // Temporary storage + VTYPE *n, *a, *b1, *b2, *b3, *b4; + a = data; n = data; + b1 = op.data; b2 = op.data + 4; b3 = op.data + 8; b4 = op.data + 12; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a++; // Calculate First Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + b1 -= 3 ; b2 -= 3; b3 -= 3; b4 -= 3; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a++; // Calculate Second Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + b1 -= 3 ; b2 -= 3; b3 -= 3; b4 -= 3; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a++; // Calculate Third Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + b1 -= 3 ; b2 -= 3; b3 -= 3; b4 -= 3; + + c1 = *a++; c2 = *a++; c3 = *a++; c4 = *a; // Calculate Four Row + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n++ = c1*(*b1++) + c2*(*b2++) + c3*(*b3++) + c4*(*b4++); + *n = c1*(*b1) + c2*(*b2) + c3*(*b3) + c4*(*b4); + + return *this; +} + + +inline MatrixF &MatrixF::Resize (const int x, const int y) +{ + if (data!=NULL) { + if (rows==y && cols==x) return *this; + delete[] data; + } + rows = y; cols = x; + if (y>0 && x>0) { + len = rows * cols; + if (len!=0) { + data = new VTYPE[len]; + #ifdef DEBUG_MATRIX + if (data==NULL) Debug.Print (DEBUG_MATRIX, "MatrixF::Size: Out of memory for construction.\n"); + #endif + } + } + + #ifdef MATRIX_INITIALIZE + if (data!=NULL) memset (data, 0, sizeof(VTYPE)*len); + #endif + return *this; +} +inline MatrixF &MatrixF::ResizeSafe (const int x, const int y) +{ + VTYPE *newdata; + int newlen; + VTYPE *n, *ne; + VTYPE *b, *be; + int bskip; + + if (data!=NULL) { + newlen = x*y; + newdata = new VTYPE[newlen]; + #ifdef DEBUG_MATRIX + if (newdata==NULL) + Debug.Print (DEBUG_MATRIX, "MatrixF::SizeSafe: Out of memory for construction.\n"); + #endif + if (y>=rows && x>=cols) { // New size is larger (in both r and c) + memset (newdata, 0, newlen*sizeof(VTYPE)); // Clear new matrix + ne = data + len; // Calculate end of current matrix + b = newdata; // Start of new matrix + be = newdata + cols; // Last filled column+1 in new matrix + bskip = x-cols; + for (n = data; n0) { + n = data; // Copy columns to left of c + ne = data + len; + nskip = (cols-c); + b = newdata; + be = newdata + c; + bskip = (cols-c)+1; + for (; n>counter-clockwise<< when looking down the X+ axis toward the origin +inline MatrixF &MatrixF::RotateX (const double ang) +{ + Resize (4,4); + VTYPE *n = data; + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + *n = 1; n += 5; + *n++ = (VTYPE) c; *n = (VTYPE) s; n+=3; + *n++ = (VTYPE) -s; *n = (VTYPE) c; n+=5; + *n = 1; + return *this; +} + +// rotates points >>counter-clockwise<< when looking down the Y+ axis toward the origin +inline MatrixF &MatrixF::RotateY (const double ang) +{ + Resize (4,4); + VTYPE *n = data; + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + *n = (VTYPE) c; n+=2; + *n = (VTYPE) -s; n+=3; + *n = 1; n+=3; + *n = (VTYPE) s; n+=2; + *n = (VTYPE) c; n+=5; + *n = 1; + return *this; +} + +// rotates points >>counter-clockwise<< when looking down the Z+ axis toward the origin +inline MatrixF &MatrixF::RotateZ (const double ang) +{ + Resize (4,4); + VTYPE *n = data; + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + *n++ = (VTYPE) c; *n = (VTYPE) s; n+=3; + *n++ = (VTYPE) -s; *n = (VTYPE) c; n+=5; + *n = 1; n+=5; *n = 1; + return *this; +} +inline MatrixF &MatrixF::Ortho (double sx, double sy, double vn, double vf) +{ + // simplified version of OpenGL's glOrtho function + VTYPE *n = data; + *n++ = (VTYPE) (1.0/sx); *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) (1.0/sy); *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) (-2.0/(vf-vn)); *n++ = (VTYPE) (-(vf+vn)/(vf-vn)); + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0; *n++ = (VTYPE) 1.0; +} + +inline MatrixF &MatrixF::Translate (double tx, double ty, double tz) +{ + Resize (4,4); + VTYPE *n = data; + *n++ = (VTYPE) 1.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 1.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 0.0; *n++ = (VTYPE) 1.0; *n++ = (VTYPE) 0.0; + *n++ = (VTYPE) tx; *n++ = (VTYPE) ty; *n++ = (VTYPE) tz; *n++ = (VTYPE) 1.0; + return *this; +} + +inline MatrixF &MatrixF::Basis (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3) +{ + Resize (4,4); + VTYPE *n = data; + *n++ = (VTYPE) c1.X(); *n++ = (VTYPE) c2.X(); *n++ = (VTYPE) c3.X(); *n++ = (VTYPE) 0; + *n++ = (VTYPE) c1.Y(); *n++ = (VTYPE) c2.Y(); *n++ = (VTYPE) c3.Y(); *n++ = (VTYPE) 0; + *n++ = (VTYPE) c1.Z(); *n++ = (VTYPE) c2.Z(); *n++ = (VTYPE) c3.Z(); *n++ = (VTYPE) 0; + *n++ = (VTYPE) 0; *n++ = (VTYPE) 0; *n++ = (VTYPE) 0; *n++ = (VTYPE) 0; + return *this; +} + +#define SWAP(a, b) {temp=(a); (a)=(b); (b)=temp;} + +inline MatrixF &MatrixF::GaussJordan (MatrixF &b) +{ + // Gauss-Jordan solves the matrix equation Ax = b + // Given the problem: + // A*x = b (where A is 'this' matrix and b is provided) + // The solution is: + // Ainv*b = x + // This function returns Ainv in A and x in b... that is: + // A (this) -> Ainv + // b -> solution x + // + + MatrixI index_col, index_row; + MatrixI piv_flag; + int r, c, c2, rs, cs; + double piv_val; + int piv_row, piv_col; + double pivinv, dummy, temp; + + #ifdef DEBUG_MATRIX + if (rows!=cols) Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Number of rows and cols of A must be equal.\n"); + if (rows!=b.rows) Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Number of rows of A and rows of b must be equal.\n"); + if (b.cols!=1) Debug.Print ( DEBUG_MATRIX, "MatrixF::GaussJordan: Number of cols of b must be 1.\n"); + #endif + + index_col.Resize (cols, 1); + index_row.Resize (cols, 1); + piv_flag.Resize (cols, 1); + piv_flag = 0; + for (c = 0; c < cols; c++) { + piv_val = 0.0; + for (rs = 0; rs < rows; rs++) { + if (piv_flag(rs, 0) != 1 ) + for (cs = 0; cs < cols; cs++) { + if (piv_flag(cs, 0) == 0) { + if (fabs((*this) (cs, rs)) >= piv_val) { + piv_val = fabs((*this) (cs, rs)); + piv_row = rs; + piv_col = cs; + } + } else if (piv_flag(cs, 0)>1) { + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Singular matrix (dbl pivs).\n"); + //Print (); + #endif + } + } + } + piv_flag(piv_col, 0)++; + if (piv_row != piv_col) { + for (c2 = 0; c2 < cols; c2++) SWAP ((*this) (c2, piv_row), (*this) (c2, piv_col)); + for (c2 = 0; c2 < b.cols; c2++) SWAP (b(c2, piv_row), b(c2, piv_col)); + } + index_row (c, 0) = piv_row; + index_col (c, 0) = piv_col; + if ((*this) (piv_col, piv_col) == 0.0) { + #ifdef DEBUG_MATRIX + Debug.Print (DEBUG_MATRIX, "MatrixF::GaussJordan: Singular matrix (0 piv).\n"); + //Print (); + #endif + } + pivinv = 1.0 / ((*this) (piv_col, piv_col)); + (*this) (piv_col, piv_col) = 1.0; + for (c2 = 0; c2 < cols; c2++) (*this) (c2, piv_col) *= pivinv; + for (c2 = 0; c2 < b.cols; c2++) b(c2, piv_col) *= pivinv; + for (r = 0; r < rows; r++) { + if (r != piv_col) { + dummy = (*this) (piv_col, r); + (*this) (piv_col, r) = 0.0; + for (c2 = 0; c2 < cols; c2++) (*this) (c2, r) -= (*this) (c2, piv_col)*dummy; + for (c2 = 0; c2 < b.cols; c2++) b(c2, r) -= b(c2, piv_col)*dummy; + } + } + } + for (c = cols-1; c >= 0; c--) { + if (index_row(c, 0) != index_col(c, 0)) + for (r = 0; r < rows; r++) + SWAP ((*this) (index_row(c,0), r), (*this) (index_col(c,0), r) ); + } + return *this; +} +inline MatrixF &MatrixF::Submatrix ( MatrixF& b, int mx, int my) +{ + VTYPE* pEnd = data + rows*cols; // end of matrix + VTYPE* pVal = data; + VTYPE* pNewVal = b.data; + VTYPE* pNewEnd = pNewVal + mx; + int pNewSkip = cols - mx; + + for (pVal = data; pVal < pEnd;) { + for (; pNewVal < pNewEnd;) *pVal++ = *pNewVal++; + pNewVal += pNewSkip; + pNewEnd += mx; + } + return *this; +} + +// N-Vector Dot Product +// Elements may be in rows or columns, but: +// - If in rows, number of columns must be one and number of rows must match. +// - If in cols, number of rows must be one and number of cols must match. +inline double MatrixF::Dot ( MatrixF& b ) +{ + double d = 0.0; + VTYPE* pA = data; + VTYPE* pB = b.data; + + if ( rows==1 && b.rows==1 && cols == b.cols ) { + VTYPE* pAEnd = data + cols; + d = 0.0; + for (; pA < pAEnd;) + d += (*pA++) * (*pB++); + } else if ( cols==1 && b.cols==1 && rows == b.rows) { + VTYPE* pAEnd = data + rows; + d = 0.0; + for (; pA < pAEnd;) + d += (*pA++) * (*pB++); + } + return d; +} + +#define I(x, y) ( (y*xres) + x ) +#define Ix(r) ( r % xres ) // X coordinate from row +#define Iy(r) ( r / xres ) // Y coordinate from row + +inline MatrixF &MatrixF::MatrixVector5 (MatrixF& x, int mrows, MatrixF& b) +{ + double v; + + // A( 2, r ) * B ( r ) + A(1,r)*B(r-1) + A(3,r)*B(r+1) + A(0, r)*B( R-( r ) ) + A(4, r)*B( R+( r ) ) + for (int r = 0; r < mrows; r++) { + v = GetVal(2, r) * x(0,r); + if ( r > 0 ) v += GetVal(1,r) * x(0,r-1); + if ( r < mrows-1) v += GetVal(3,r) * x(0,r+1); + if ( (int) GetVal(5, r) >= 0) v += GetVal(0,r) * x(0, (int) GetVal(5,r)); + if ( (int) GetVal(6, r) >= 0) v += GetVal(4,r) * x(0, (int) GetVal(6,r)); + b(0,r) = v; + } + return *this; +} + +inline MatrixF &MatrixF::ConjugateGradient (MatrixF &b) +{ + return *this; +} + +// Sparse Conjugate Gradient 2D (special case) +// This compute conjugate gradients on a +// sparse "5-7" x N positive definite matrix. +// Only 'mrows' subset of the row-size of A and b will be used. +inline MatrixF &MatrixF::ConjugateGradient5 (MatrixF &b, int mrows ) +{ + double a, g, rdot; + int i, imax; + MatrixF x, xnew; // solution vector + MatrixF r, rnew; // residual + MatrixF p, ptemp; // search direction + MatrixF v; + + x.Resize ( 1, mrows ); + xnew.Resize ( 1, mrows ); + r.Resize ( 1, mrows ); + rnew.Resize ( 1, mrows ); + p.Resize ( 1, mrows ); + ptemp.Resize ( 1, mrows ); + v.Resize ( 1, mrows ); + + r.Submatrix ( b, 1, mrows); + MatrixVector5 ( x, mrows, v ); // (Ax -> v) + r -= v; // r = b - Ax + p = r; + + imax = 20; + for (i=0; i < imax; i++) { + MatrixVector5 ( p, mrows, v ); // v = Ap + rdot = r.Dot ( r ); + a = rdot / p.Dot ( v ); // a = (r . r) / (p . v) + xnew = p; + xnew *= a; + xnew += x; // x = x + p*a + v *= a; + rnew = r; // rnew = r - v*a + rnew -= v; + g = rnew.Dot ( rnew ) / rdot; // g = (rnew . rnew) / (r . r) + p *= g; + p += rnew; // p = rnew + p*g + r = rnew; + x = xnew; + } + for (int rx=0; rx < mrows; rx++) + b(0, rx) = x(0, rx); + return *this; +} + +inline int MatrixF::GetX() {return cols;} +inline int MatrixF::GetY() {return rows;} +inline int MatrixF::GetRows(void) {return rows;} +inline int MatrixF::GetCols(void) {return cols;} +inline int MatrixF::GetLength(void) {return len;} +inline VTYPE *MatrixF::GetData(void) {return data;} + +inline double MatrixF::GetF (const int r, const int c) {return (double) (*(data + r*cols + c));} + +inline void MatrixF::GetRowVec (int r, Vector3DF &v) +{ + VTYPE *n = data + r*cols; + v.x = (float) *n++; v.y = (float) *n++; v.z= (float) *n++; +} + +inline void MatrixF::Print ( char* fname ) +{ + char buf[2000]; + + FILE* fp = fopen ( fname, "w+" ); + + for (int r=0; r < rows; r++) { + buf[0] = '\0'; + for (int c =0; c < cols; c++) { + sprintf ( buf, "%s %04.3f", buf, GetVal(c, r) ); + } + fprintf ( fp, "%s\n", buf); + } + fprintf ( fp, "---------------------------------------\n", buf); + fflush ( fp ); + fclose ( fp ); +} + + +// MatrixF Code Definition +#undef VTYPE +#define VNAME F +#define VTYPE float + +// Constructors/Destructors + +inline Matrix4F::Matrix4F (void) { for (int n=0; n < 16; n++) data[n] = 0.0; } + +inline Matrix4F &Matrix4F::operator= (const unsigned char op) {for ( int n=0; n<16; n++) data[n] = (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator= (const int op) {for ( int n=0; n<16; n++) data[n] = (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator= (const double op) {for ( int n=0; n<16; n++) data[n] = (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator+= (const unsigned char op) {for ( int n=0; n<16; n++) data[n] += (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator+= (const int op) {for ( int n=0; n<16; n++) data[n] += (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator+= (const double op) {for ( int n=0; n<16; n++) data[n] += (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator-= (const unsigned char op) {for ( int n=0; n<16; n++) data[n] -= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator-= (const int op) {for ( int n=0; n<16; n++) data[n] -= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator-= (const double op) {for ( int n=0; n<16; n++) data[n] -= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator*= (const unsigned char op) {for ( int n=0; n<16; n++) data[n] *= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator*= (const int op) {for ( int n=0; n<16; n++) data[n] *= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator*= (const double op) {for ( int n=0; n<16; n++) data[n] *= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator/= (const unsigned char op) {for ( int n=0; n<16; n++) data[n] /= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator/= (const int op) {for ( int n=0; n<16; n++) data[n] /= (VTYPE) op; return *this;} +inline Matrix4F &Matrix4F::operator/= (const double op) {for ( int n=0; n<16; n++) data[n] /= (VTYPE) op; return *this;} + +inline Matrix4F &Matrix4F::Multiply (const Matrix4F &op) { + register float orig[16]; // Temporary storage + memcpy ( orig, data, 16*sizeof(float) ); + + // Calculate First Row + data[0] = orig[0]*op.data[0] + orig[1]*op.data[4] + orig[2]*op.data[8] + orig[3]*op.data[12]; + data[1] = orig[0]*op.data[1] + orig[1]*op.data[5] + orig[2]*op.data[9] + orig[3]*op.data[13]; + data[2] = orig[0]*op.data[2] + orig[1]*op.data[6] + orig[2]*op.data[10] + orig[3]*op.data[14]; + data[3] = orig[0]*op.data[3] + orig[1]*op.data[7] + orig[2]*op.data[11] + orig[3]*op.data[15]; + + // Calculate Second Row + data[4] = orig[4]*op.data[0] + orig[5]*op.data[4] + orig[6]*op.data[8] + orig[7]*op.data[12]; + data[5] = orig[4]*op.data[1] + orig[5]*op.data[5] + orig[6]*op.data[9] + orig[7]*op.data[13]; + data[6] = orig[4]*op.data[2] + orig[5]*op.data[6] + orig[6]*op.data[10] + orig[7]*op.data[14]; + data[7] = orig[4]*op.data[3] + orig[5]*op.data[7] + orig[6]*op.data[11] + orig[7]*op.data[15]; + + // Calculate Third Row + data[8] = orig[8]*op.data[0] + orig[9]*op.data[4] + orig[10]*op.data[8] + orig[11]*op.data[12]; + data[9] = orig[8]*op.data[1] + orig[9]*op.data[5] + orig[10]*op.data[9] + orig[11]*op.data[13]; + data[10] = orig[8]*op.data[2] + orig[9]*op.data[6] + orig[10]*op.data[10] + orig[11]*op.data[14]; + data[11] = orig[8]*op.data[3] + orig[9]*op.data[7] + orig[10]*op.data[11] + orig[11]*op.data[15]; + + // Calculate Four Row + data[12] = orig[12]*op.data[0] + orig[13]*op.data[4] + orig[14]*op.data[8] + orig[15]*op.data[12]; + data[13] = orig[12]*op.data[1] + orig[13]*op.data[5] + orig[14]*op.data[9] + orig[15]*op.data[13]; + data[14] = orig[12]*op.data[2] + orig[13]*op.data[6] + orig[14]*op.data[10] + orig[15]*op.data[14]; + data[15] = orig[12]*op.data[3] + orig[13]*op.data[7] + orig[14]*op.data[11] + orig[15]*op.data[15]; + + return *this; +} + +inline Matrix4F &Matrix4F::Transpose (void) +{ + register float orig[16]; // Temporary storage + memcpy ( orig, data, 16*sizeof(VTYPE) ); + + data[0] = orig[0]; data[1] = orig[4]; data[2] = orig[8]; data[3] = orig[12]; + data[4] = orig[1]; data[5] = orig[5]; data[6] = orig[9]; data[7] = orig[13]; + data[8] = orig[2]; data[9] = orig[6]; data[10] = orig[10];data[11] = orig[14]; + data[12] = orig[3]; data[13] = orig[7]; data[14] = orig[11];data[15] = orig[15]; + return *this; +} + +inline Matrix4F &Matrix4F::Identity (const int order) +{ + memset (data, 0, 16*sizeof(VTYPE)); + data[0] = 1.0; + data[5] = 1.0; + data[10] = 1.0; + data[15] = 1.0; + return *this; +} + +inline Matrix4F &Matrix4F::RotateX (const double ang) +{ + memset (data, 0, 16*sizeof(VTYPE)); + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + data[0] = 1; + data[5] = (VTYPE) c; data[6] = (VTYPE) s; + data[9] = (VTYPE) -s; data[10] = (VTYPE) c; + data[15] = 1; + return *this; +} + +// rotates points >>counter-clockwise<< when looking down the Y+ axis toward the origin +inline Matrix4F &Matrix4F::RotateY (const double ang) +{ + memset (data, 0, 16*sizeof(VTYPE)); + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + data[0] = (VTYPE) c; + data[2] = (VTYPE) -s; + data[5] = 1; + data[8] = (VTYPE) s; + data[10] = (VTYPE) c; + data[15] = 1; + return *this; +} + +// rotates points >>counter-clockwise<< when looking down the Z+ axis toward the origin +inline Matrix4F &Matrix4F::RotateZ (const double ang) +{ + memset (data, 0, 16*sizeof(VTYPE)); + double c,s; + c = cos(ang * 3.141592/180); + s = sin(ang * 3.141592/180); + data[0] = (VTYPE) c; data[1] = (VTYPE) s; + data[4] = (VTYPE) -s; data[5] = (VTYPE) c; + data[10] = 1; + data[15] = 1; + return *this; +} +inline Matrix4F &Matrix4F::Ortho (double sx, double sy, double vn, double vf) +{ + // simplified version of OpenGL's glOrtho function + data[ 0] = (VTYPE) (1.0/sx);data[ 1] = (VTYPE) 0.0; data[ 2] = (VTYPE) 0.0; data[ 3]= (VTYPE) 0.0; + data[ 4] = (VTYPE) 0.0; data[ 5] = (VTYPE) (1.0/sy);data[ 6] = (VTYPE) 0.0; data[ 7] = (VTYPE) 0.0; + data[ 8] = (VTYPE) 0.0; data[ 9] = (VTYPE) 0.0; data[10]= (VTYPE) (-2.0/(vf-vn)); data[11] = (VTYPE) (-(vf+vn)/(vf-vn)); + data[12] = (VTYPE) 0.0; data[13] = (VTYPE) 0.0; data[14] = (VTYPE) 0; data[15] = (VTYPE) 1.0; +} + +inline Matrix4F &Matrix4F::Translate (double tx, double ty, double tz) +{ + data[ 0] = (VTYPE) 1.0; data[ 1] = (VTYPE) 0.0; data[ 2] = (VTYPE) 0.0; data[ 3] = (VTYPE) 0.0; + data[ 4] = (VTYPE) 0.0; data[ 5] = (VTYPE) 1.0; data[ 6] = (VTYPE) 0.0; data[ 7] = (VTYPE) 0.0; + data[ 8] = (VTYPE) 0.0; data[ 9] = (VTYPE) 0.0; data[10] = (VTYPE) 1.0; data[11] = (VTYPE) 0.0; + data[12] = (VTYPE) tx; data[13] = (VTYPE) ty; data[14] = (VTYPE) tz; data[15] = (VTYPE) 1.0; + return *this; +} + +inline Matrix4F &Matrix4F::Basis (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3) +{ + data[ 0] = (VTYPE) c1.x; data[ 1] = (VTYPE) c2.x; data[ 2] = (VTYPE) c3.x; data[ 3] = (VTYPE) 0.0; + data[ 4] = (VTYPE) c1.y; data[ 5] = (VTYPE) c2.y; data[ 6] = (VTYPE) c3.y; data[ 7] = (VTYPE) 0.0; + data[ 8] = (VTYPE) c1.z; data[ 9] = (VTYPE) c2.z; data[10] = (VTYPE) c3.z; data[11] = (VTYPE) 0.0; + data[12] = (VTYPE) 0.0; data[13] = (VTYPE) 0.0; data[14] = (VTYPE) 0.0; data[15] = (VTYPE) 1.0; + return *this; +} + +inline Matrix4F &Matrix4F::SRT (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const Vector3DF& s) +{ + data[ 0] = (VTYPE) c1.x*s.x; data[ 1] = (VTYPE) c2.x*s.x; data[ 2] = (VTYPE) c3.x*s.x; data[ 3] = (VTYPE) 0.0; + data[ 4] = (VTYPE) c1.y*s.y; data[ 5] = (VTYPE) c2.y*s.y; data[ 6] = (VTYPE) c3.y*s.y; data[ 7] = (VTYPE) 0.0; + data[ 8] = (VTYPE) c1.z*s.z; data[ 9] = (VTYPE) c2.z*s.z; data[10] = (VTYPE) c3.z*s.z; data[11] = (VTYPE) 0.0; + data[12] = (VTYPE) t.x; data[13] = (VTYPE) t.y; data[14] = (VTYPE) t.z; data[15] = (VTYPE) 1.0; +} +inline Matrix4F &Matrix4F::SRT (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const float s) +{ + data[ 0] = (VTYPE) c1.x*s; data[ 1] = (VTYPE) c1.y*s; data[ 2] = (VTYPE) c1.z*s; data[ 3] = (VTYPE) 0.0; + data[ 4] = (VTYPE) c2.x*s; data[ 5] = (VTYPE) c2.y*s; data[ 6] = (VTYPE) c2.z*s; data[ 7] = (VTYPE) 0.0; + data[ 8] = (VTYPE) c3.x*s; data[ 9] = (VTYPE) c3.y*s; data[10] = (VTYPE) c3.z*s; data[11] = (VTYPE) 0.0; + data[12] = (VTYPE) t.x; data[13] = (VTYPE) t.y; data[14] = (VTYPE) t.z; data[15] = (VTYPE) 1.0; + return *this; +} + +inline Matrix4F &Matrix4F::InvTRS (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const Vector3DF& s) +{ + data[ 0] = (VTYPE) c1.x/s.x; data[ 1] = (VTYPE) c1.y/s.y; data[ 2] = (VTYPE) c1.z/s.z; data[ 3] = (VTYPE) 0.0; + data[ 4] = (VTYPE) c2.x/s.x; data[ 5] = (VTYPE) c2.y/s.y; data[ 6] = (VTYPE) c2.z/s.z; data[ 7] = (VTYPE) 0.0; + data[ 8] = (VTYPE) c3.x/s.x; data[ 9] = (VTYPE) c3.y/s.y; data[10] = (VTYPE) c3.z/s.z; data[11] = (VTYPE) 0.0; + data[12] = (VTYPE) -t.x/s.x; data[13] = (VTYPE) -t.y/s.y; data[14] = (VTYPE) -t.z/s.z; data[15] = (VTYPE) 1.0; +} +inline Matrix4F &Matrix4F::InvTRS (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const float s) +{ + data[ 0] = (VTYPE) c1.x/s; data[ 1] = (VTYPE) c1.y/s; data[ 2] = (VTYPE) c1.z/s; data[ 3] = (VTYPE) 0.0; + data[ 4] = (VTYPE) c2.x/s; data[ 5] = (VTYPE) c2.y/s; data[ 6] = (VTYPE) c2.z/s; data[ 7] = (VTYPE) 0.0; + data[ 8] = (VTYPE) c3.x/s; data[ 9] = (VTYPE) c3.y/s; data[10] = (VTYPE) c3.z/s; data[11] = (VTYPE) 0.0; + data[12] = (VTYPE) -t.x/s; data[13] = (VTYPE) -t.y/s; data[14] = (VTYPE) -t.z/s; data[15] = (VTYPE) 1.0; +} + +inline float Matrix4F::GetF (const int r, const int c) {return (float) data[ (r<<2) + c];} + +inline void Matrix4F::GetRowVec (int r, Vector3DF &v) +{ + v.x = data[ (r<<2) ]; + v.y = data[ (r<<2)+1 ]; + v.z = data[ (r<<2)+2 ]; +} + +#undef VTYPE +#undef VNAME + diff --git a/Extras/sph/common/matrix.cpp b/Extras/sph/common/matrix.cpp new file mode 100644 index 0000000..35d56aa --- /dev/null +++ b/Extras/sph/common/matrix.cpp @@ -0,0 +1,23 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "matrix.h" + diff --git a/Extras/sph/common/matrix.h b/Extras/sph/common/matrix.h new file mode 100644 index 0000000..956bfe4 --- /dev/null +++ b/Extras/sph/common/matrix.h @@ -0,0 +1,429 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include +#include +#include +#include +#include + +//*********** NOTE +// +// LOOK AT MovieTrackPoint. IN ORDER FOR VECTORS AND MATRICIES TO BE USED IN OBJECTS +// THAT WILL BE USED IN stl::vectors, THEIR CONSTRUCTORS AND OPERATORS MUST TAKE ONLY +// const PARAMETERS. LOOK AT MatrixF and Vector2DF.. THIS WAS NOT YET DONE WITH +// THE OTHER MATRIX AND VECTOR CLASSES (Vector2DC, Vector2DI, MatrixC, MatrixI, ...) +// + + +#ifndef MATRIX_DEF + #define MATRIX_DEF + + #include "vector.h" + #include "mdebug.h" + + //#define MATRIX_INITIALIZE // Initializes vectors + + class MatrixC; // Forward Referencing + class MatrixI; + class MatrixF; + + class Matrix { + public: + // Member Virtual Functions + virtual Matrix &operator= (unsigned char c)=0; + virtual Matrix &operator= (int c)=0; + virtual Matrix &operator= (double c)=0; + virtual Matrix &operator= (MatrixC &op)=0; + virtual Matrix &operator= (MatrixI &op)=0; + virtual Matrix &operator= (MatrixF &op)=0; + + virtual Matrix &operator+= (unsigned char c)=0; + virtual Matrix &operator+= (int c)=0; + virtual Matrix &operator+= (double c)=0; + virtual Matrix &operator+= (MatrixC &op)=0; + virtual Matrix &operator+= (MatrixI &op)=0; + virtual Matrix &operator+= (MatrixF &op)=0; + + virtual Matrix &operator-= (unsigned char c)=0; + virtual Matrix &operator-= (int c)=0; + virtual Matrix &operator-= (double c)=0; + virtual Matrix &operator-= (MatrixC &op)=0; + virtual Matrix &operator-= (MatrixI &op)=0; + virtual Matrix &operator-= (MatrixF &op)=0; + + virtual Matrix &operator*= (unsigned char c)=0; + virtual Matrix &operator*= (int c)=0; + virtual Matrix &operator*= (double c)=0; + virtual Matrix &operator*= (MatrixC &op)=0; + virtual Matrix &operator*= (MatrixI &op)=0; + virtual Matrix &operator*= (MatrixF &op)=0; + + virtual Matrix &operator/= (unsigned char c)=0; + virtual Matrix &operator/= (int c)=0; + virtual Matrix &operator/= (double c)=0; + virtual Matrix &operator/= (MatrixC &op)=0; + virtual Matrix &operator/= (MatrixI &op)=0; + virtual Matrix &operator/= (MatrixF &op)=0; + + virtual Matrix &Multiply (MatrixF &op)=0; + virtual Matrix &Resize (int x, int y)=0; + virtual Matrix &ResizeSafe (int x, int y)=0; + virtual Matrix &InsertRow (int r)=0; + virtual Matrix &InsertCol (int c)=0; + virtual Matrix &Transpose (void)=0; + virtual Matrix &Identity (int order)=0; + /*inline Matrix &RotateX (double ang); + inline Matrix &RotateY (double ang); + inline Matrix &RotateZ (double ang); */ + virtual Matrix &Basis (Vector3DF &c1, Vector3DF &c2, Vector3DF &c3)=0; + virtual Matrix &GaussJordan (MatrixF &b) { return *this; } + virtual Matrix &ConjugateGradient (MatrixF &b) { return *this; } + + virtual int GetRows(void)=0; + virtual int GetCols(void)=0; + virtual int GetLength(void)=0; + + virtual unsigned char *GetDataC (void)=0; + virtual int *GetDataI (void)=0; + virtual double *GetDataF (void)=0; + + virtual double GetF (int r, int c); + }; + + // MatrixC Declaration + #define VNAME C + #define VTYPE unsigned char + + class MatrixC { + public: + VTYPE *data; + int rows, cols, len; + + // Constructors/Destructors + inline MatrixC (); + inline ~MatrixC (); + inline MatrixC (int r, int c); + + // Member Functions + inline VTYPE &operator () (int c, int r); + inline MatrixC &operator= (unsigned char c); + inline MatrixC &operator= (int c); + inline MatrixC &operator= (double c); + inline MatrixC &operator= (MatrixC &op); + inline MatrixC &operator= (MatrixI &op); + inline MatrixC &operator= (MatrixF &op); + + inline MatrixC &operator+= (unsigned char c); + inline MatrixC &operator+= (int c); + inline MatrixC &operator+= (double c); + inline MatrixC &operator+= (MatrixC &op); + inline MatrixC &operator+= (MatrixI &op); + inline MatrixC &operator+= (MatrixF &op); + + inline MatrixC &operator-= (unsigned char c); + inline MatrixC &operator-= (int c); + inline MatrixC &operator-= (double c); + inline MatrixC &operator-= (MatrixC &op); + inline MatrixC &operator-= (MatrixI &op); + inline MatrixC &operator-= (MatrixF &op); + + inline MatrixC &operator*= (unsigned char c); + inline MatrixC &operator*= (int c); + inline MatrixC &operator*= (double c); + inline MatrixC &operator*= (MatrixC &op); + inline MatrixC &operator*= (MatrixI &op); + inline MatrixC &operator*= (MatrixF &op); + + inline MatrixC &operator/= (unsigned char c); + inline MatrixC &operator/= (int c); + inline MatrixC &operator/= (double c); + inline MatrixC &operator/= (MatrixC &op); + inline MatrixC &operator/= (MatrixI &op); + inline MatrixC &operator/= (MatrixF &op); + + inline MatrixC &Multiply (MatrixF &op); + inline MatrixC &Resize (int x, int y); + inline MatrixC &ResizeSafe (int x, int y); + inline MatrixC &InsertRow (int r); + inline MatrixC &InsertCol (int c); + inline MatrixC &Transpose (void); + inline MatrixC &Identity (int order); + inline MatrixC &Basis (Vector3DF &c1, Vector3DF &c2, Vector3DF &c3); + inline MatrixC &GaussJordan (MatrixF &b); + + inline int GetX(); + inline int GetY(); + inline int GetRows(void); + inline int GetCols(void); + inline int GetLength(void); + inline VTYPE *GetData(void); + + inline unsigned char *GetDataC (void) {return data;} + inline int *GetDataI (void) {return NULL;} + inline double *GetDataF (void) {return NULL;} + + inline double GetF (int r, int c); + }; + #undef VNAME + #undef VTYPE + + // MatrixI Declaration + #define VNAME I + #define VTYPE int + + class MatrixI { + public: + VTYPE *data; + int rows, cols, len; + + // Constructors/Destructors + inline MatrixI (); + inline ~MatrixI (); + inline MatrixI (int r, int c); + + // Member Functions + inline VTYPE &operator () (int c, int r); + inline MatrixI &operator= (unsigned char c); + inline MatrixI &operator= (int c); + inline MatrixI &operator= (double c); + inline MatrixI &operator= (MatrixC &op); + inline MatrixI &operator= (MatrixI &op); + inline MatrixI &operator= (MatrixF &op); + + inline MatrixI &operator+= (unsigned char c); + inline MatrixI &operator+= (int c); + inline MatrixI &operator+= (double c); + inline MatrixI &operator+= (MatrixC &op); + inline MatrixI &operator+= (MatrixI &op); + inline MatrixI &operator+= (MatrixF &op); + + inline MatrixI &operator-= (unsigned char c); + inline MatrixI &operator-= (int c); + inline MatrixI &operator-= (double c); + inline MatrixI &operator-= (MatrixC &op); + inline MatrixI &operator-= (MatrixI &op); + inline MatrixI &operator-= (MatrixF &op); + + inline MatrixI &operator*= (unsigned char c); + inline MatrixI &operator*= (int c); + inline MatrixI &operator*= (double c); + inline MatrixI &operator*= (MatrixC &op); + inline MatrixI &operator*= (MatrixI &op); + inline MatrixI &operator*= (MatrixF &op); + + inline MatrixI &operator/= (unsigned char c); + inline MatrixI &operator/= (int c); + inline MatrixI &operator/= (double c); + inline MatrixI &operator/= (MatrixC &op); + inline MatrixI &operator/= (MatrixI &op); + inline MatrixI &operator/= (MatrixF &op); + + inline MatrixI &Multiply (MatrixF &op); + inline MatrixI &Resize (int x, int y); + inline MatrixI &ResizeSafe (int x, int y); + inline MatrixI &InsertRow (int r); + inline MatrixI &InsertCol (int c); + inline MatrixI &Transpose (void); + inline MatrixI &Identity (int order); + inline MatrixI &Basis (Vector3DF &c1, Vector3DF &c2, Vector3DF &c3); + inline MatrixI &GaussJordan (MatrixF &b); + + inline int GetX(); + inline int GetY(); + inline int GetRows(void); + inline int GetCols(void); + inline int GetLength(void); + inline VTYPE *GetData(void); + + inline unsigned char *GetDataC (void) {return NULL;} + inline int *GetDataI (void) {return data;} + inline double *GetDataF (void) {return NULL;} + + inline double GetF (int r, int c); + }; + #undef VNAME + #undef VTYPE + + // MatrixF Declaration + #define VNAME F + #define VTYPE double + + class MatrixF { + public: + VTYPE *data; + int rows, cols, len; + + // Constructors/Destructors + inline MatrixF (); + inline ~MatrixF (); + inline MatrixF (const int r, const int c); + + // Member Functions + inline VTYPE GetVal ( int c, int r ); + inline VTYPE &operator () (const int c, const int r); + inline MatrixF &operator= (const unsigned char c); + inline MatrixF &operator= (const int c); + inline MatrixF &operator= (const double c); + inline MatrixF &operator= (const MatrixC &op); + inline MatrixF &operator= (const MatrixI &op); + inline MatrixF &operator= (const MatrixF &op); + + inline MatrixF &operator+= (const unsigned char c); + inline MatrixF &operator+= (const int c); + inline MatrixF &operator+= (const double c); + inline MatrixF &operator+= (const MatrixC &op); + inline MatrixF &operator+= (const MatrixI &op); + inline MatrixF &operator+= (const MatrixF &op); + + inline MatrixF &operator-= (const unsigned char c); + inline MatrixF &operator-= (const int c); + inline MatrixF &operator-= (const double c); + inline MatrixF &operator-= (const MatrixC &op); + inline MatrixF &operator-= (const MatrixI &op); + inline MatrixF &operator-= (const MatrixF &op); + + inline MatrixF &operator*= (const unsigned char c); + inline MatrixF &operator*= (const int c); + inline MatrixF &operator*= (const double c); + inline MatrixF &operator*= (const MatrixC &op); + inline MatrixF &operator*= (const MatrixI &op); + inline MatrixF &operator*= (const MatrixF &op); + + inline MatrixF &operator/= (const unsigned char c); + inline MatrixF &operator/= (const int c); + inline MatrixF &operator/= (const double c); + inline MatrixF &operator/= (const MatrixC &op); + inline MatrixF &operator/= (const MatrixI &op); + inline MatrixF &operator/= (const MatrixF &op); + + inline MatrixF &Multiply4x4 (const MatrixF &op); + inline MatrixF &Multiply (const MatrixF &op); + inline MatrixF &Resize (const int x, const int y); + inline MatrixF &ResizeSafe (const int x, const int y); + inline MatrixF &InsertRow (const int r); + inline MatrixF &InsertCol (const int c); + inline MatrixF &Transpose (void); + inline MatrixF &Identity (const int order); + inline MatrixF &RotateX (const double ang); + inline MatrixF &RotateY (const double ang); + inline MatrixF &RotateZ (const double ang); + inline MatrixF &Ortho (double sx, double sy, double n, double f); + inline MatrixF &Translate (double tx, double ty, double tz); + inline MatrixF &Basis (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3); + inline MatrixF &GaussJordan (MatrixF &b); + inline MatrixF &ConjugateGradient (MatrixF &b); + inline MatrixF &Submatrix ( MatrixF& b, int mx, int my); + inline MatrixF &MatrixVector5 (MatrixF& x, int mrows, MatrixF& b ); + inline MatrixF &ConjugateGradient5 (MatrixF &b, int mrows ); + inline double Dot ( MatrixF& b ); + + inline void Print ( char* fname ); + + inline int GetX(); + inline int GetY(); + inline int GetRows(void); + inline int GetCols(void); + inline int GetLength(void); + inline VTYPE *GetData(void); + inline void GetRowVec (int r, Vector3DF &v); + + inline unsigned char *GetDataC (void) const {return NULL;} + inline int *GetDataI (void) const {return NULL;} + inline double *GetDataF (void) const {return data;} + + inline double GetF (const int r, const int c); + }; + #undef VNAME + #undef VTYPE + + // MatrixF Declaration + #define VNAME F + #define VTYPE float + + class Matrix4F { + public: + VTYPE data[16]; + + // Constructors/Destructors + inline Matrix4F (); + + // Member Functions + inline VTYPE &operator () (const int n) { return data[n]; } + inline VTYPE &operator () (const int c, const int r) { return data[ (r<<2)+c ]; } + inline Matrix4F &operator= (const unsigned char c); + inline Matrix4F &operator= (const int c); + inline Matrix4F &operator= (const double c); + inline Matrix4F &operator+= (const unsigned char c); + inline Matrix4F &operator+= (const int c); + inline Matrix4F &operator+= (const double c); + inline Matrix4F &operator-= (const unsigned char c); + inline Matrix4F &operator-= (const int c); + inline Matrix4F &operator-= (const double c); + inline Matrix4F &operator*= (const unsigned char c); + inline Matrix4F &operator*= (const int c); + inline Matrix4F &operator*= (const double c); + inline Matrix4F &operator/= (const unsigned char c); + inline Matrix4F &operator/= (const int c); + inline Matrix4F &operator/= (const double c); + + inline Matrix4F &Multiply (const Matrix4F &op); + inline Matrix4F &Transpose (void); + inline Matrix4F &Identity (const int order); + inline Matrix4F &RotateX (const double ang); + inline Matrix4F &RotateY (const double ang); + inline Matrix4F &RotateZ (const double ang); + inline Matrix4F &Ortho (double sx, double sy, double n, double f); + inline Matrix4F &Translate (double tx, double ty, double tz); + inline Matrix4F &Basis (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3); + + // Scale-Rotate-Translate (compound matrix) + inline Matrix4F &SRT (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const Vector3DF& s); + inline Matrix4F &SRT (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const float s); + + // invTranslate-invRotate-invScale (compound matrix) + inline Matrix4F &InvTRS (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const Vector3DF& s); + inline Matrix4F &InvTRS (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const float s); + + inline int GetX() { return 4; } + inline int GetY() { return 4; } + inline int GetRows(void) { return 4; } + inline int GetCols(void) { return 4; } + inline int GetLength(void) { return 16; } + inline VTYPE *GetData(void) { return data; } + inline void GetRowVec (int r, Vector3DF &v); + + inline unsigned char *GetDataC (void) const {return NULL;} + inline int *GetDataI (void) const {return NULL;} + inline float *GetDataF (void) const {return (float*) data;} + + inline float GetF (const int r, const int c); + }; + #undef VNAME + #undef VTYPE + + + // Matrix Code Definitions (Inlined) + + #include "matrix.cci" + +#endif + diff --git a/Extras/sph/common/mdebug.cpp b/Extras/sph/common/mdebug.cpp new file mode 100644 index 0000000..b0b868b --- /dev/null +++ b/Extras/sph/common/mdebug.cpp @@ -0,0 +1,583 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + + +//#define MEMORY_DEBUG // Overloads the new and delete operators + +#include +#include +#include + +#include "mdebug.h" + +#ifdef _MSC_VER + #include + #include + #include + #include +#endif + +CDebug debug; +CError error; + +//------------------------------------------------- DEBUG CLASS +CDebug::CDebug () +{ + m_OutName = "debug.txt"; + m_bStarted = false; + m_bToFile = true; + m_bToSysbox = true; + m_bToCons = false; + m_OutFile = NULL; + m_OutCons = NULL; + Start (); +} + +CDebug::~CDebug (void) +{ + Stop (); +} + +void CDebug::Start () +{ + if ( m_bStarted ) Stop (); + + if ( m_bToFile ) { + char fn[200]; + +#ifdef _MSC_VER + strcpy_s ( fn, 200, m_OutName.c_str () ); + fopen_s ( &m_OutFile, fn, "w+t" ); +#else + strncpy ( fn, m_OutName.c_str(), 200 ); + m_OutFile = fopen( fn, "w+" ); +#endif + + if ( m_OutFile == 0x0 ) { + exit ( EXIT_FAILURE ); // error: Cannot create debug file + } + m_bStarted = true; + Print ( "debug", "CDebug started to file.\n"); + } + m_bStarted = true; +} + +void CDebug::Exit ( int code ) +{ + if ( !m_bToSysbox ) { + #ifdef _MSC_VER + _getch(); + #endif + } + exit ( code ); +} + +void CDebug::Stop () +{ + if ( m_bStarted ) { + if ( m_bToFile ) { + Print ( "debug", "CDebug stopped."); + fclose ( m_OutFile ); + } + } + m_bStarted = false; +} + +void CDebug::SendToFile ( char* fname ) +{ + if (m_bStarted) Stop (); + m_bToFile = true; + m_OutName = fname; +} + +void CDebug::SendToConsole ( bool tf ) +{ + m_bToCons = tf; + if ( tf ) { + #ifdef _MSC_VER + AllocConsole (); + long lStdHandle = (long) GetStdHandle( STD_OUTPUT_HANDLE ); + int hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + m_OutCons = _fdopen( hConHandle, "w" ); + #endif + } +} + +void CDebug::SendToSysbox ( bool tf ) +{ + m_bToSysbox = tf; +} + +void CDebug::Print ( std::string subsys, std::string msg ) +{ + if ( m_bStarted ) { + if ( m_bToFile ) { + fprintf ( m_OutFile, "%s: %s\n", subsys.c_str(), msg.c_str() ); + fflush ( m_OutFile); + } + if ( m_bToCons ) { + #ifdef _MSC_VER + fprintf ( m_OutCons, "%s: %s\n", subsys.c_str(), msg.c_str() ); + fflush ( m_OutCons ); + #else + printf ( "%s: %s\n", subsys.c_str(), msg.c_str() ); + #endif + } + } +} + +void CDebug::Print (char* msg) +{ + if ( m_bStarted ) { + if ( m_bToFile ) { + fprintf ( m_OutFile, "%s", msg ); + fflush ( m_OutFile ); + } + if ( m_bToCons ) { + #ifdef _MSC_VER + fprintf ( m_OutCons, "%s", msg ); + fflush ( m_OutCons ); + #else + printf ( "%s", msg ); + #endif + } + } +} + +void CDebug::Print ( std::string msg ) +{ + if ( m_bStarted ) { + if ( m_bToFile ) { + fprintf ( m_OutFile, "%s", msg.c_str() ); + fflush ( m_OutFile ); + } + if ( m_bToCons ) { + #ifdef _MSC_VER + fprintf ( m_OutCons, "%s", msg.c_str() ); + fflush ( m_OutCons ); + #else + printf ( "%s", msg.c_str() ); + #endif + } + } +} + +void CDebug::PrintF ( std::string substr, char* format, ... ) +{ + // Note: This is the >only< way to do this. There is no general way to + // pass on all the arguments from one ellipsis function to another. + // The function vfprintf was specially designed to allow this. + + if ( m_bStarted ) { + if ( m_bToFile ) { + va_list argptr; + va_start (argptr, format); + fprintf ( m_OutFile, "%s: ", substr.c_str() ); + vfprintf ( m_OutFile, format, argptr); + va_end (argptr); + fflush ( m_OutFile ); + } + if ( m_bToCons ) { + #ifdef _MSC_VER + va_list argptr; + va_start (argptr, format); + fprintf ( m_OutCons, "%s: ", substr.c_str() ); + vfprintf ( m_OutCons, format, argptr); + va_end (argptr); + fflush ( m_OutCons ); + #else + va_list argptr; + va_start (argptr, format); + printf ( "%s: ", substr.c_str() ); + vprintf ( format, argptr); + va_end (argptr); + #endif + } + } +} + + +void CDebug::Printf ( char* format, ... ) +{ + // Note: This is the >only< way to do this. There is no general way to + // pass on all the arguments from one ellipsis function to another. + // The function vfprintf was specially designed to allow this. + + if ( m_bStarted ) { + if ( m_bToFile ) { + va_list argptr; + va_start (argptr, format); + vfprintf ( m_OutFile, format, argptr); + va_end (argptr); + fflush ( m_OutFile ); + } + if ( m_bToCons ) { + #ifdef _MSC_VER + va_list argptr; + va_start (argptr, format); + vfprintf ( m_OutCons, format, argptr); + va_end (argptr); + fflush ( m_OutCons ); + #else + va_list argptr; + va_start (argptr, format); + vprintf ( format, argptr); + va_end (argptr); + #endif + } + } +} + +void CDebug::PrintErr ( std::string errid, std::string subsys, std::string msg, std::string sysbox ) +{ + if ( m_bStarted ) { + if ( m_bToFile ) { + fprintf ( m_OutFile, "%s: ERROR: %s\n", subsys.c_str(), msg.c_str() ); + fflush ( m_OutFile ); + } + if ( m_bToCons ) { + #ifdef _MSC_VER + fprintf ( m_OutCons, "%s: ERROR: %s\n", subsys.c_str(), msg.c_str() ); + fflush ( m_OutCons ); + #else + printf ( "%s: ERROR[%s] %s\n", subsys.c_str(), errid.c_str(), msg.c_str() ); + #endif + } + if ( m_bToSysbox ) { + char disp[4000]; + char caption[200]; + + #ifdef _MSC_VER + // Message boxes for Windows + strcpy_s ( caption, 200, "Mint - Error" ); + strcpy_s ( disp, 4000, sysbox.c_str()); + #include + int hr = MessageBoxA ( 0x0, disp, caption, MB_OK); + #else + strncpy ( caption, m_ErrorSubsys.c_str(), 200 ); + strncpy ( disp, msg.c_str(), 4000 ); + #endif + } + } +} + + +//-------------------------------------------------------------------- Error Class Code +// +// This software is released under the LGPL Open Source Liscense. +// See the documentation included with this source code for terms of modification, +// distribution and re-release. +// +// Original Copyright (C) 2002 Rama C. Hoetzlein, GameX R4 +// + +CError::CError () +{ + m_Errors.clear (); + m_ErrorID = ""; + m_ErrorSubsys = ""; + m_ErrorMsg = ""; + m_ErrorFunc = ""; + m_ErrorFix = ""; + m_ErrorExtra = ""; +} + +void CError::Start () +{ + Start ( "" ); +} + +void CError::Start ( char* fname ) +{ + if ( fname != 0x0 && strlen(fname) > 0 ) { + // Read error message file. NOT YET IMPLEMENTED + } else { + debug.Print ( "error", "No error file loaded." ); + } + debug.Print ( "error", "Error handler started." ); + m_bStarted = true; +} + +void CError::OutputMessage () +{ + // Create sysbox message + std::string box_msg; + box_msg = "Subsystem: " + m_ErrorSubsys + "\n\n"; + box_msg += "Error: " + m_ErrorMsg + "\n"; + if ( m_ErrorExtra.length() > 0) box_msg += "Info: " + m_ErrorExtra + "\n"; + if ( m_ErrorFix.length() > 0) box_msg += "\nFix: " + m_ErrorFix + "\n"; + if ( m_ErrorID.length() > 0 ) box_msg += "Error ID: " + m_ErrorID + "\n"; + if ( m_ErrorFunc.length() > 0 ) box_msg += "Function: " + m_ErrorFunc + "\n"; + + // Error output to debug file + debug.PrintErr ( m_ErrorID, m_ErrorSubsys, m_ErrorMsg, box_msg ); +} + +void CError::Exit ( int code ) +{ + debug.Exit ( code ); +} + +void CError::Print ( char* msg) +{ + // User-level error (no additional info) + m_ErrorID = ""; + m_ErrorSubsys = "undef"; + m_ErrorMsg = msg; + m_ErrorFunc = ""; + m_ErrorFix = ""; + m_ErrorExtra = ""; + OutputMessage (); +} + +void CError::Print ( std::string msg ) +{ + // User-level error (no additional info) + m_ErrorID = ""; + m_ErrorSubsys = "undef"; + m_ErrorMsg = msg; + m_ErrorFunc = ""; + m_ErrorFix = ""; + m_ErrorExtra = ""; + OutputMessage (); +} + +void CError::Print ( std::string subsys, std::string msg ){ + // Unregistered error + m_ErrorID = ""; + m_ErrorSubsys = subsys; + m_ErrorMsg = msg; + m_ErrorFunc = ""; + m_ErrorFix = ""; + m_ErrorExtra = ""; + OutputMessage (); +} + +void CError::PrintF ( std::string subsys, char* msg, ... ) +{ + char buf[2000]; + va_list argptr; + m_ErrorID = ""; + m_ErrorSubsys = subsys; + va_start(argptr, msg); + #ifdef _MSC_VER + vsprintf_s (buf, 2000, msg, argptr); + #else + vsnprintf(buf, 2000, msg, argptr); + #endif + va_end (argptr); + m_ErrorMsg = buf; + m_ErrorFunc = ""; + m_ErrorFix = ""; + m_ErrorExtra = ""; + OutputMessage (); +} + + +void CError::PrintErr ( std::string err ) +{ + // Registered error - NOT YET IMPLEMENTED + // CErrorMsg* msg = m_ +} + +void CError::PrintErrDX ( std::string err, int result ) +{ +// +// #ifdef BUILD_DX +// m_ErrorExtra = DXGetErrorString9 ( result ); +// #endif + OutputMessage (); + m_ErrorExtra = ""; +} + +void CError::PrintErrGL ( std::string err, int result ) +{ + OutputMessage (); + m_ErrorExtra = ""; +} + +void CError::PrintErrW ( std::string err, int result ) +{ + + OutputMessage (); + m_ErrorExtra = ""; +} + + +/* +void CError::GetErrorMessage ( ErrorDef::Errors err ) +{ + switch (err) { + //----------------------------------------------------- MATRIX Errors + case ErrorDef::MatrixIsNull: + m_strDescription = "Matrix data is null\n"; + m_strFunction = "Matrix::op()"; + m_strFix = ""; + break; + case ErrorDef::ColOutOfBounds: + m_strDescription = "Column index out of bounds\n"; + m_strFunction = "Matrix::op()"; + m_strFix = ""; + break; + case ErrorDef::RowOutOfBounds: + m_strDescription = "Row index out of bounds\n"; + m_strFunction = "Matrix::op()"; + m_strFix = ""; + break; + //----------------------------------------------------- WinDX Errors + case ErrorDef::DXInitFail: + m_strDescription = "Initialization of DirectX failed."; + m_strFunction = "GameX::InitDirect3D"; + m_strFix = "Reinstall DirectX 9.0. Confirm DirectX hardware support."; + break; + case ErrorDef::DXCannotGetMode: + m_strDescription = "Cannot get current display mode."; + m_strFunction = "GameX::SysGetCurrentMode"; + m_strFix = ""; + break; + case ErrorDef::DXCannotSetMode: + m_strDescription = "Cannot select display mode."; + m_strFunction = "GameX::SysSelectMode"; + m_strFix = "Try requesting a different display mode and options."; + break; + case ErrorDef::WinCannotCreateClass: + m_strDescription = "Cannot create Windows class."; + m_strFunction = "GameX::SysCreateWindowsClass"; + m_strFix = "Close other applications. Restart system."; + break; + case ErrorDef::WinCannotCreateWindow: + m_strDescription = "Cannot create Window."; + m_strFunction = "GameX::SysCreateWindow"; + m_strFix = "Try requesting a different display mode and options.\nClose other applications. Restart system. Possibly unsupported display hardware."; + break; + case ErrorDef::DXCannotCreateDevice: + m_strDescription = "Cannot create DirectX Device."; + m_strFunction = "GameX::SysCreateDevice3D"; + m_strFix = "Try requesting a different display mode and options."; + break; + case ErrorDef::DXCannotCreateDepthStencils: + m_strDescription = "Cannot create DirectX Depth Stencils."; + m_strFunction = "GameX::SysCreateDepthStencils"; + m_strFix = "Try requesting a different display mode and options."; + break; + //---------------------------------------------------------------- File Errors + case ErrorDef::CannotAppendAndRead: + m_strDescription = "Cannot open a file in both APPEND and READ mode."; + m_strFunction = "File::Open"; + m_strFix = "Use either APPEND, READ or WRITE when opening file."; + break; + case ErrorDef::CannotAppendAndWrite: + m_strDescription = "Cannot open a file in both APPEND and WRITE mode."; + m_strFunction = "File::Open"; + m_strFix = "Use either APPEND, READ or WRITE when opening file."; + break; + case ErrorDef::FileNotFound: + m_strDescription = "File not found."; + m_strFunction = "File::Open"; + m_strFix = "Use AUTOCREATE if you would like to create a new file."; + break; + case ErrorDef::LeaveEofOnlyOnAppend: + m_strDescription = "Warning:LEAVEEOF flag can only be used in APPEND mode."; + m_strFunction = "File::Open"; + m_strFix = "Remove the LEAVEEOF flag or open file in APPEND mode."; + break; + case ErrorDef::NoModeSpecified: + m_strDescription = "No open mode specified."; + m_strFunction = "File::Open"; + m_strFix = "You must specify READ, WRITE or APPEND to open a file."; + break; + case ErrorDef::NoNotOpenCmd: + m_strDescription = "NOTOPEN cannot be used as an open file flag."; + m_strFunction = "File::Open"; + m_strFix = "Remove the NOTOPEN flag."; + break; + case ErrorDef::NoSeqAndRandom: + m_strDescription = "Cannot open file in both SEQUENTIAL and RANDOM access modes."; + m_strFunction = "File::Open"; + m_strFix = "Choose either SEQUENTIAL or RANDOM mode to open file in."; + break; + case ErrorDef::CannotCreateFont: + m_strDescription = "Cannot create default font."; + m_strFunction = "RenderDX::Initialize"; + m_strFix = "DirectX fonts are not supported for some reason."; + break; + case ErrorDef::CannotCreateSprite: + m_strDescription = "Cannot create default sprite."; + m_strFunction = "RenderDX::Initialize"; + m_strFix = "DirectX sprites are not supported for some reason."; + break; + case ErrorDef::CannotAddImage: + m_strDescription = "Cannot create image on video memory."; + m_strFunction = "RenderDX::AddImage"; + m_strFix = "DirectX was unable to create hardware texture for the image."; + break; + case ErrorDef::CannotUpdateImage: + m_strDescription = "Cannot update image data on video memory."; + m_strFunction = "RenderDX::UpdateImage"; + m_strFix = "DirectX was unable to modify hardware texture for the image."; + break; + case ErrorDef::CannotOpenFile: + #if defined(BUILD_VSNET) + m_strDescription = strerror( errno ); + #else + m_strDescription = ""; // should replace with Mac general error code + #endif + m_strFunction = "File::Open"; + m_strFix = ""; + break; + case ErrorDef::ImageLoadError: + m_strDescription = "Unable to load image."; + m_strFunction = "ImageX::Load"; + m_strFix = ""; + break; + default: + char msg[500]; + sprintf (msg, "%d", (int) err ); + m_strDescription = "Undefined error: "; + m_strDescription += msg; + m_strSubsystem = "Undefined error."; + m_strFix = "Error must be given a description and fix message."; + break; + }; +} +*/ + + + +#ifdef MEMORY_DEBUG + + // User-defined operator new. + void *operator new( size_t stSize ) + { + void* pvMem = malloc( stSize ); + debug.Printf ( "NEW %p (%d bytes)\n", pvMem, stSize ); + return pvMem; + } + + // User-defined operator delete. + void operator delete( void *pvMem ) + { + debug.Printf ( "DELETE %p\n", pvMem ); + free ( pvMem ); + } +#endif \ No newline at end of file diff --git a/Extras/sph/common/mdebug.h b/Extras/sph/common/mdebug.h new file mode 100644 index 0000000..9c07993 --- /dev/null +++ b/Extras/sph/common/mdebug.h @@ -0,0 +1,138 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef INC_MINT_DEBUG_H + #define INC_MINT_DEBUG_H + + #include + #include + #include + #include + + + + #ifdef BUILD_VS2005 + // #pragma warning( disable : 4101) // removes warning 4101 - unreferenced local + // #pragma warning( disable : 4244) // removes warning 4244 - conversion loss of data + #pragma warning( disable : 4995) // removes warning 4995 - depricated function + #pragma warning( disable : 4996) // removes warning 4996 - depricated function + // #pragma warning( disable : 4018) // removes warning 4018 - unsigned/signed + #endif + + class CDebug { + public: + CDebug (); + ~CDebug (); + + // Control functions + void Start (); + void Stop (); + void SendToConsole ( bool tf ); + void SendToSysbox ( bool tf ); + void SendToFile ( bool tf ); + void SendToFile ( char *filename ); + + // Output functions + void Exit ( int code ); + void Print ( std::string subsys, std::string msg ); + void Print ( std::string msg ); + void Print ( char* msg); + void PrintF ( std::string subsys, char *msg, ... ); + void Printf ( char *msg, ... ); + void PrintErr ( std::string errid, std::string subsys, std::string msg, std::string sysbox ); // Used by Error class + + // Filtering functions + void AddFilter ( std::string subsys ); + void ClearFilters (); + + private: + bool m_bStarted; + bool m_bToFile; + bool m_bToCons; + bool m_bToSysbox; + std::string m_OutName; + FILE* m_OutFile; + FILE* m_OutCons; + + std::map< std::string, bool > m_Filters; + }; + + class CErrorMsg { + std::string m_strSubsys; + std::string m_strFunction; + std::string m_strMessage; + std::string m_strFix; + std::string m_strExtraInfo; + bool m_bFatal; + bool m_bFilter; + }; + + class CError { + public: + CError (); + + void Start (); + void Start ( char* fname ); + void LoadErrors (); + void OutputMessage (); + void Exit () { Exit (EXIT_SUCCESS); } + void Exit ( int code ); + + // Unregistered errors + void Print ( std::string subsys, std::string msg ); + void Print ( std::string msg ); + void Print ( char* msg); + void PrintF ( std::string subsys, char *msg, ... ); + + // Registered errors + void PrintErr ( std::string err ); + void PrintErrDX ( std::string err, int result ); // for DirectX errors + void PrintErrGL ( std::string err, int result ); // for OpenGL errors + void PrintErrW ( std::string err, int result ); // for Windows errors + + std::string GetErrorSubsys () { return m_ErrorID; } + std::string GetErrorMessage () { return m_ErrorMsg; } + std::string GetErrorFunction () { return m_ErrorFunc; } + std::string GetErrorFix () { return m_ErrorFix; } + std::string GetErrorExtra () { return m_ErrorExtra; } + + private: + + bool m_bStarted; + + std::string m_ErrorID; // Current error + std::string m_ErrorSubsys; + std::string m_ErrorMsg; + std::string m_ErrorFunc; + std::string m_ErrorFix; + std::string m_ErrorExtra; + bool m_bFatal; + + std::map < std::string, CErrorMsg* > m_Errors; // List of registered errors + }; + + + + extern CError error; + extern CDebug debug; +#endif + diff --git a/Extras/sph/common/mesh.cpp b/Extras/sph/common/mesh.cpp new file mode 100644 index 0000000..af3849c --- /dev/null +++ b/Extras/sph/common/mesh.cpp @@ -0,0 +1,955 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include "mesh.h" +#include "mdebug.h" +//#include "mfile.h" + +//#include "event.h" + +#include + +#define DEGtoRAD (3.141592/180.0) + +bool Mesh::mbInitStatic = false; +int Mesh::miBufSize[MAX_MFORMAT][MAX_BFORMAT]; + +Mesh::Mesh () +{ + debug.SendToConsole ( true ); + + m_Mform = MFormat::UDef; + m_CurrF = 0; + m_Vbuf = BUF_UNDEF; + m_Ebuf = BUF_UNDEF; + m_Fbuf = BUF_UNDEF; +} + +Mesh& Mesh::operator= ( Mesh& src ) +{ + CopyBuffers ( src ); + CopyAttributes ( src ); + m_Mform = src.GetMeshBufs ( m_Vbuf, m_Ebuf, m_Fbuf ); + return *this; +} + +void Mesh::InitStatic () +{ + mbInitStatic = true; + miBufSize[ (int) FVF ][ (int) BVert ] = sizeof ( VertFVF ); + miBufSize[ (int) FVF ][ (int) BFace ] = sizeof ( FaceFVF ); + miBufSize[ (int) FVF ][ (int) BEdge ] = 0; + miBufSize[ (int) CM ][ (int) BVert ] = sizeof ( VertCM ); + miBufSize[ (int) CM ][ (int) BEdge ] = sizeof ( EdgeCM ); + miBufSize[ (int) CM ][ (int) BFace ] = sizeof ( FaceCM ); + +} + +/*void Mesh::onUpdate ( objData dat, mint::Event* e ) +{ + uchar dtype; + hval num; + hval max; + long size; + ushort stride; + int num_buf; + + switch ( dat ) { + case 'full': + ClearBuffers (); + ClearAttributes (); + + m_Mform = (MFormat) e->getUChar (); + m_Vbuf = e->getUChar (); + m_Ebuf = e->getUChar (); + m_Fbuf = e->getUChar (); + num_buf = e->getInt (); + for (int b=0; b < num_buf; b++) { + dtype = e->getUChar (); + stride = e->getUShort (); + num = e->getInt (); + max = e->getInt (); + AddBuffer ( dtype, stride, max ); + e->getMem ( mBuf[b].data, num * mBuf[b].stride ); + mBuf[b].num = num; + } + + mHeapNum = e->getInt (); + mHeapMax = e->getInt (); + mHeapFree = e->getInt (); + mHeap = new hval[mHeapMax]; + e->getMem ( (char*) mHeap, mHeapNum * sizeof(hval) ); + break; + }; +} + +void Mesh::UpdateMesh () +{ + int s = GetSize () + (mBuf.size()+1)*4*sizeof(int); + mint::Event* e = updateStart ( 'full', s ); + + e->attachUChar ( (char) m_Mform ) ; + e->attachUChar ( (char) m_Vbuf ); + e->attachUChar ( (char) m_Ebuf ); + e->attachUChar ( (char) m_Fbuf ); + e->attachInt ( mBuf.size() ); + for (int b=0; b < mBuf.size(); b++) { + e->attachUChar ( mBuf[b].dtype ); + e->attachUShort ( mBuf[b].stride ); + e->attachInt ( mBuf[b].num ); + e->attachInt ( mBuf[b].max ); + e->attachMem ( mBuf[b].data, mBuf[b].num * mBuf[b].stride ); + } + e->attachInt ( mHeapNum ); + e->attachInt ( mHeapMax ); + e->attachInt ( mHeapFree ); + e->attachMem ( (char*) mHeap, mHeapNum * sizeof(hval) ); + + updateEnd ( e ); +} +*/ + +//------------------------------------------------------------------ FVF - Face-vertex-face Mesh +void Mesh::CreateFVF () +{ + if ( !mbInitStatic ) InitStatic (); + SetFuncFVF (); + + m_Mform = FVF; + m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( FVF, BVert ), 64 ); + m_Fbuf = AddBuffer ( (uchar) BFace, BufSize( FVF, BFace ), 64 ); + AddAttribute ( m_Vbuf, "pos", sizeof ( AttrPos ), false ); + AddAttribute ( m_Vbuf, "norm", sizeof ( AttrNorm ) ); + + AddHeap ( 128 ); +} + +void Mesh::ClearFVF () +{ + ResetBuffer ( 0, mBuf[0].max ); + ResetBuffer ( 1, mBuf[0].max ); + + ResetHeap (); +} + +void Mesh::SmoothFVF ( int iter ) +{ + Vector3DF norm, side; + int cnt; + FaceFVF* f; + VertFVF *v1, *v2, *v3; + AttrPos* face_pos; + face_pos = new AttrPos[ NumFace() ]; + + for (int j=0; j < iter; j++) { + // Compute centroid of all faces + for (int n=0; n < NumFace(); n++) { + f = GetFaceFVF ( n ); + v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3); + face_pos[n].x = ( v1->x + v2->x + v3->x ) / 3.0; + face_pos[n].y = ( v1->y + v2->y + v3->y ) / 3.0; + face_pos[n].z = ( v1->z + v2->z + v3->z ) / 3.0; + } + // Compute new vertex positions + int cnt; + Vector3DF vec; + for (int n=0; n < NumVert(); n++) { + v1 = GetVertFVF ( n ); + vec.Set (0,0,0); + hval* fptr = mHeap + v1->flist.pos; + for (int j=0; j < v1->flist.cnt; j++) { + vec.x += face_pos[ (*fptr) ].x; + vec.y += face_pos[ (*fptr) ].y; + vec.z += face_pos[ (*fptr) ].z; + fptr++; + } + v1->x = vec.x / (float) v1->flist.cnt; + v1->y = vec.y / (float) v1->flist.cnt; + v1->z = vec.z / (float) v1->flist.cnt; + } + } + delete face_pos; +} + +void Mesh::SetNormalFVF ( int n, Vector3DF norm ) +{ + VertFVF* v1; + AttrNorm* vn; + int noff = GetAttrOffset ( "norm" ); + v1 = GetVertFVF ( n ); + vn = (AttrNorm* ) ((char*) v1 + noff ); + vn->nx = norm.x; + vn->ny = norm.y; + vn->nz = norm.z; +} + + +void Mesh::SetColorFVF ( int n, DWORD clr ) +{ + VertFVF* v1; + AttrClr* vc; + int coff = GetAttrOffset ( "color" ); + if ( coff == -1 ) return; + v1 = GetVertFVF ( n ); + vc = (AttrClr* ) ((char*) v1 + coff ); + vc->clr = clr; +} +void Mesh::ComputeNormalsFVF () +{ + Vector3DF norm, side; + FaceFVF* f; + VertFVF *v1, *v2, *v3, *v4; + AttrNorm* vn; + AttrNorm* face_norms; + face_norms = new AttrNorm[ NumFace() ]; + + // Clear vertex normals + int noff = GetAttrOffset ( "norm" ); + for (int n=0; n < NumVert(); n++) { + v1 = GetVertFVF ( n ); + vn = (AttrNorm*) ((char*) v1 + noff); + vn->nx = 0; + vn->ny = 0; + vn->nz = 0; + } + + // Compute normals of all faces + for (int n=0; n < NumFace(); n++) { + f = GetFaceFVF ( n ); + v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3); + side = Vector3DF ( v2->x, v2->y, v2->z ); + side -= Vector3DF ( v1->x, v1->y, v1->z ); + side.Normalize (); + norm = Vector3DF ( v3->x, v3->y, v3->z ); + norm -= Vector3DF ( v1->x, v1->y, v1->z ); + norm.Normalize (); + norm.Cross ( side ); + face_norms[n].nx = norm.x; + face_norms[n].ny = norm.y; + face_norms[n].nz = norm.z; + vn = (AttrNorm*) ((char*) v1 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z; + vn = (AttrNorm*) ((char*) v2 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z; + vn = (AttrNorm*) ((char*) v3 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z; + if ( f->v4 != -1 ) { + v4 = GetVertFVF(f->v4); + vn = (AttrNorm*) ((char*) v4 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z; + } + } + + // Normalize vertex normals + Vector3DF vec; + for (int n=0; n < NumVert(); n++) { + v1 = GetVertFVF ( n ); + vn = (AttrNorm*) ((char*) v1 + noff); + vec.Set ( vn->nx, vn->ny, vn->nz ); + vec.Normalize (); + vn->nx = vec.x; + vn->ny = vec.y; + vn->nz = vec.z; + } + + // Compute normal of a vertex from surrounding faces (slow method) + /*int cnt; + for (int n=0; n < NumVert(); n++) { + v1 = GetVertFVF ( n ); + vn = (VertNorm*) GetExtraFVF ( v1 ); + cnt = 0; + vn->nx = 0; vn->ny = 0; vn->nz = 0; + hval* fptr = mHeap + v1->flist.pos; + for (int j=0; j < v1->flist.cnt; j++) { + vn->nx += face_norms[ (*fptr) ].nx; + vn->ny += face_norms[ (*fptr) ].ny; + vn->nz += face_norms[ (*fptr) ].nz; + cnt++; + fptr++; + } + vn->nx /= (float) cnt; + vn->ny /= (float) cnt; + vn->nz /= (float) cnt; + }*/ + + delete face_norms; +} + +void Mesh::SetFuncFVF () +{ + m_AddVertFunc = &Mesh::AddVertFVF; + m_AddFaceFast3Func = &Mesh::AddFaceFast3FVF; + m_AddFaceFast4Func = &Mesh::AddFaceFast4FVF; +} + +xref Mesh::AddFaceFast3FVF ( xref v1, xref v2, xref v3 ) +{ + xref fNdx; + FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx ); + f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1; + AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA ); + return fNdx; +} +xref Mesh::AddFaceFast4FVF ( xref v1, xref v2, xref v3, xref v4 ) +{ + xref fNdx; + FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx ); + f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4; + AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertFVF(v4)->flist, FACE_DELTA ); + return fNdx; +} +xref Mesh::AddVertFVF ( float x, float y, float z ) +{ + xref ndx; + VertFVF* v = (VertFVF*) AddElem ( m_Vbuf, ndx ); + v->x = x; v->y = y; v->z = z; + ClearRefs ( v->flist ); + return ndx; +} + +void Mesh::DebugFVF () +{ + int n; + int j; + VertFVF* v; + FaceFVF* f; + debug.Printf ( "-- MESH --\n"); + + debug.Printf ( "-- verts\n" ); + for (n=0; n < NumVert(); n++) { + v = GetVertFVF(n); + debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) f:%d %d{", n, v->x, v->y, v->z, v->flist.cnt, v->flist.pos); + if ( v->flist.cnt > 0 ) { + for (j=0; j < v->flist.cnt; j++) + debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA ); + } + debug.Printf ( "}\n" ); + } + debug.Printf ( "-- faces\n" ); + for (n=0; n < NumFace(); n++) { + f = GetFaceFVF(n); + debug.Printf ( "%d: v:%d %d %d\n", n, f->v1, f->v2, f->v3); + } + + DebugHeap (); + + debug.Printf ("\n\n"); + //_getch(); +} + + +//------------------------------------------------------------------ CM - Connected Mesh +// Create Connected Mesh (CM) +void Mesh::CreateCM () +{ + if ( !mbInitStatic ) InitStatic (); + SetFuncCM (); + + m_Mform = CM; + m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( CM, BVert ), 64 ); + m_Ebuf = AddBuffer ( (uchar) BEdge, BufSize ( CM, BEdge), 64 ); + m_Fbuf = AddBuffer ( (uchar) BFace, BufSize ( CM, BFace), 64 ); + AddAttribute ( m_Vbuf, "pos", sizeof(AttrPos), false ); + AddAttribute ( m_Vbuf, "norm", sizeof(AttrNorm) ); + + AddHeap ( 128 ); +} + +void Mesh::SetFuncCM () +{ + m_AddVertFunc = &Mesh::AddVertCM; + m_AddFaceFast3Func = &Mesh::AddFaceFast3CM; + m_AddFaceFast4Func = &Mesh::AddFaceFast4CM; +} + + +xref Mesh::AddVertCM ( float x, float y, float z ) +{ + xref ndx; + VertCM* v = (VertCM*) AddElem ( m_Vbuf, ndx ); + v->x = x; v->y = y; v->z = z; + ClearRefs ( v->elist ); + ClearRefs ( v->flist ); + return ndx; +} + +xref Mesh::AddFaceFast3CM ( xref v1, xref v2, xref v3 ) +{ + xref fNdx; + FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx ); + f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1; + xref eNdx; + eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx; + eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx; + eNdx = AddEdgeCM ( f->v3, f->v1 ); f->e3 = eNdx; + AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA ); + return fNdx; +} +xref Mesh::AddFaceFast4CM ( xref v1, xref v2, xref v3, xref v4 ) +{ + xref fNdx; + FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx ); + f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4; + xref eNdx; + eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx; + eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx; + eNdx = AddEdgeCM ( f->v3, f->v4 ); f->e3 = eNdx; + eNdx = AddEdgeCM ( f->v4, f->v1 ); f->e4 = eNdx; + AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA ); + AddRef ( fNdx, GetVertCM(v4)->flist, FACE_DELTA ); + return fNdx; +} + +xref Mesh::FindEdgeCM ( xref v1, xref v2 ) +{ + EdgeCM *pE; + VertCM *pV1; + pV1 = GetVertCM(v1); + if ( pV1->elist.cnt == 0 ) return -1; + hval* e = mHeap + pV1->elist.pos; + #ifdef MESH_DEBUG + for (int n=0; n < pV1->elist.cnt; n++) { + pE = GetEdgeCM( (*e)-EDGE_DELTA ); + if ( pE->v1 == v2 || pE->v2 == v2 ) return (*e)-EDGE_DELTA; + e++; + } + #else + for (int n=0; n < pV1->elist.cnt; n++) { + pE = GetEdgeCM( *e ); + if ( pE->v1 == v2 || pE->v2 == v2 ) return *e; + e++; + } + #endif + return -1; +} + +xref Mesh::AddEdgeCM ( xref v1, xref v2 ) +{ + xref eNdx = FindEdgeCM ( v1, v2 ); + EdgeCM* e = GetEdgeCM(eNdx); + if ( eNdx == -1 ) { + e = (EdgeCM*) AddElem ( m_Ebuf, eNdx ); + e->f1 = 0; + e->f2 = 0; + e->v1 = v1; + e->v2 = v2; + AddRef ( eNdx, GetVertCM(v1)->elist, EDGE_DELTA ); + AddRef ( eNdx, GetVertCM(v2)->elist, EDGE_DELTA ); + } + return eNdx; +} + +void Mesh::DebugCM () +{ + int n; + int j; + VertCM* v; + EdgeCM* e; + FaceCM* f; + debug.Printf ( "-- MESH --\n"); + + debug.Printf ( "-- verts\n" ); + for (n=0; n < NumVert(); n++) { + v = GetVertCM(n); + debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) e:%d %d{", n, v->x, v->y, v->z, v->elist.cnt, v->elist.pos); + if ( v->elist.cnt > 0 ) { + for (j=0; j < v->elist.cnt; j++) + debug.Printf ( "%d ", *(mHeap+v->elist.pos+j) - EDGE_DELTA ); + } + debug.Printf ( "}, f:%d %d{", v->flist.cnt, v->flist.pos); + if ( v->flist.cnt > 0 ) { + for (j=0; j < v->flist.cnt; j++) + debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA ); + } + debug.Printf ( "}\n" ); + } + + debug.Printf ( "-- edges\n" ); + for (n=0; n < NumEdge(); n++) { + e = GetEdgeCM (n); + debug.Printf ( "%d: v:%d %d, f:%d %d\n", n, e->v1, e->v2, e->f1, e->f2 ); + } + + debug.Printf ( "-- faces\n" ); + for (n=0; n < NumFace(); n++) { + f = GetFaceCM(n); + debug.Printf ( "%d: v:%d %d %d, e:%d %d %d\n", n, f->v1, f->v2, f->v3, f->e1, f->e2, f->e3 ); + } + + + hval* pVal = mHeap; + debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree ); + for (n=0; n < mHeapNum; n++) { + if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n ); + #ifdef MESH_DEBUG + if ( *pVal == 0 ) { + debug.Printf ( "00000 "); + } else if ( *pVal == (hval) 0xFFFF ) { + debug.Printf ( "----- "); + } else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) { + debug.Printf ( "v%04d ", *pVal - VERT_DELTA ); + } else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) { + debug.Printf ( "e%04d ", *pVal - EDGE_DELTA ); + } else if ( *pVal >= FACE_DELTA ) { + debug.Printf ( "f%04d ", *pVal - FACE_DELTA ); + } else { + debug.Printf ( "H%04d ", (int) *pVal ); + } + #else + debug.Printf ( "%05d ", (int) *pVal ); + #endif + pVal++; + } + + debug.Printf ("\n\n"); + //_getch(); +} + +void Mesh::DebugHeap () +{ + hval* pVal = mHeap; + debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree ); + for (int n=0; n < mHeapNum; n++) { + if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n ); + #ifdef MESH_DEBUG + if ( *pVal == 0 ) { + debug.Printf ( "00000 "); + } else if ( *pVal == (hval) 0xFFFF ) { + debug.Printf ( "----- "); + } else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) { + debug.Printf ( "v%04d ", *pVal - VERT_DELTA ); + } else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) { + debug.Printf ( "e%04d ", *pVal - EDGE_DELTA ); + } else if ( *pVal >= FACE_DELTA ) { + debug.Printf ( "f%04d ", *pVal - FACE_DELTA ); + } else { + debug.Printf ( "H%04d ", (int) *pVal ); + } + #else + debug.Printf ( "%05d ", (int) *pVal ); + #endif + pVal++; + } +} + +void Mesh::DrawVertsCM ( float* viewmat, int a, int b ) +{ + VertCM* v; + + glColor3f (1,0,0); + glLoadMatrixf ( viewmat ); + glTranslatef ( mT.x, mT.y, mT.z ); + glBegin ( GL_POINTS ); + for (int n = a; n <= b; n++) { + v = GetVertCM (n); + glVertex3f ( v->x, v->y, v->z ); + //glCallList ( m_GLObj ); + } + glEnd (); +} + +void Mesh::DrawVertsFVF ( float* viewmat, int a, int b ) +{ + VertFVF* v; + glColor3f (1,0,0); + glLoadMatrixf ( viewmat ); + glTranslatef ( mT.x, mT.y, mT.z ); + glBegin ( GL_POINTS ); + for (int n = a; n <= b; n++) { + v = GetVertFVF (n); + glVertex3f ( v->x, v->y, v->z ); + //glCallList ( m_GLObj ); + } + glEnd (); +} + +void Mesh::DrawFacesCM ( float* viewmat, int a, int b ) +{ + FaceCM* f; + VertCM* v; + AttrNorm* vn; + int noff = GetAttrOffset ( "norm" ); + glLoadMatrixf ( viewmat ); + glTranslatef ( mT.x, mT.y, mT.z ); + GLenum dm = GL_TRIANGLES; + glBegin ( dm ); + f = GetFaceCM ( a ); + for (int n = a; n <= b; n++) { + if ( f->v4 == -1 ) { + if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; } + v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + } else { + if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; } + v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + v = GetVertCM(f->v4); vn = (AttrNorm*) ((char*) v + noff); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + } + f++; + } + glEnd (); +} + +void Mesh::DrawFacesFVF ( float* viewmat, int a, int b ) +{ + FaceFVF* f; + VertFVF* v; + AttrNorm* vn; + AttrClr* vc; + int noff = GetAttrOffset ( "norm" ); + int coff = GetAttrOffset ( "color" ); + coff = -1; + + //glLoadMatrixf ( viewmat ); + //glTranslatef ( mT.x, mT.y, mT.z ); + GLenum dm = GL_TRIANGLES; + glBegin ( dm ); + f = GetFaceFVF ( a ); + for (int n = a; n <= b; n++) { + if ( f->v4 == -1 ) { + if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; } + v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff); + if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) ); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + + v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff); + if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) ); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + + v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff); + if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) ); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + } else { + if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; } + v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff); + if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) ); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + + v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff); + if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) ); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + + v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff); + if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) ); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + + v = GetVertFVF(f->v4); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff); + if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) ); + glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z ); + } + f++; + } + glEnd (); +} + +void Mesh::DrawEdgesCM ( float* viewmat, int a, int b ) +{ + EdgeCM* e; + + glLoadMatrixf ( viewmat ); + glTranslatef ( mT.x, mT.y, mT.z ); + glBegin ( GL_LINES ); + e = GetEdgeCM ( a ); + for (int n = a; n <= b; n++) { + glVertex3f ( GetVertCM(e->v1)->x, GetVertCM(e->v1)->y, GetVertCM(e->v1)->z ); + glVertex3f ( GetVertCM(e->v2)->x, GetVertCM(e->v2)->y, GetVertCM(e->v2)->z ); + e++; + } + glEnd (); +} + +void Mesh::DrawGL ( float* viewmat ) +{ + mT.Set(0,0,0); + + switch ( m_Mform ) { + case CM: { + glDepthRange (0.001, 1.001); + //glColor3f ( 1, 0, 0 ); DrawVertsCM ( viewmat, 0, NumVert()-1 ); + glColor3f ( .6, .6, .6 ); DrawFacesCM ( viewmat, 0, NumFace()-1 ); + //glDepthRange (0.0005, 1.0005); + //glColor3f ( 1, 1, 1); DrawEdgesCM ( viewmat, 0, NumEdge()-1 ); + } break; + case FVF: { + //glColor3f (1,0,0); DrawVertsFVF ( viewmat, 0, NumVert()-1 ); + //glEnable (GL_LIGHTING); + + glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL ); + glColor4f ( .9, .9, .9, 0.75 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 ); + + /*glDisable (GL_LIGHTING ); + glDepthRange (0.000, 1.00); + glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ); + glLineWidth ( 3 ); + glColor4f ( 0, 0, 0, 1.0 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 ); + glEnable ( GL_LIGHTING ); + + glLineWidth ( 1); + + glDepthRange (0.0, 1.0); + glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );*/ + + } break; + } +} + +void Mesh::DrawFaceGL ( float* viewmat ) +{ + mT.Set (0,0,0); + if ( m_CurrF < 0 ) m_CurrF = NumFace()-1; + if ( m_CurrF >= NumFace() ) m_CurrF = 0; + + switch ( m_Mform ) { + case FVF: + glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 ); + DrawFacesFVF ( viewmat, m_CurrF, m_CurrF ); + break; + case CM: + glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 ); + DrawFacesCM ( viewmat, m_CurrF, m_CurrF ); + break; + }; +} + +void Mesh::Measure () +{ + hval* pCurr = mHeap + mHeapFree; + int vs, es, fs, hs, hm, as, frees = 0; + vs = NumVert(); if ( vs !=0 ) vs *= GetStride(m_Vbuf); + es = NumEdge(); if ( es !=0 ) es *= GetStride(m_Ebuf); + fs = NumFace(); if ( fs !=0 ) fs *= GetStride(m_Fbuf); + hs = mHeapNum*sizeof(hval); + hm = mHeapMax*sizeof(hval); + + while ( pCurr != mHeap-1 ) { + frees += *(pCurr); + pCurr = mHeap + * (hpos*) (pCurr + FPOS); + } + frees *= sizeof(hval); + as = 0; + if ( m_Vbuf!=-1 ) as += mBuf[m_Vbuf].max * GetStride(m_Vbuf); + if ( m_Fbuf!=-1 ) as += mBuf[m_Fbuf].max * GetStride(m_Fbuf); + if ( m_Ebuf!=-1 ) as += mBuf[m_Ebuf].max * GetStride(m_Ebuf); + as += hm; + + debug.Printf ( "NumVert: %07.1fk (%d)\n", vs/1000.0, NumVert() ); + debug.Printf ( "NumFace: %07.1fk (%d)\n", fs/1000.0, NumFace() ); + debug.Printf ( "NumEdge: %07.1fk (%d)\n", es/1000.0, NumEdge() ); + debug.Printf ( "Heap Size: %07.1fk (%d)\n", hs/1000.0, mHeapNum ); + debug.Printf ( "Free Size: %07.1fk\n", frees/1000.0 ); + debug.Printf ( "Heap Used: %07.1fk (%5.1f%%)\n", (hs-frees)/1000.0, (hs-frees)*100.0/(vs+es+fs+hs-frees) ); + debug.Printf ( "Heap Max: %07.1fk\n", hm/1000.0 ); + debug.Printf ( "Total Used: %07.1fk\n", (vs+es+fs+hs-frees)/1000.0 ); + debug.Printf ( "Total Alloc: %07.1fk\n", as/1000.0 ); + debug.Printf ( "Fragmentation: %f%%\n", (hm-(hs-frees))*100.0 / hm ); +} + + +/*int Mesh::GetIndex ( int b, void* v ) +{ + if ( v == 0x0 ) return -1; + return ((char*) v - (char*) mBuf[b].data) / mBuf[b].stride; +}*/ + +int Mesh::FindPlyElem ( char typ ) +{ + for (int n=0; n < m_Ply.size(); n++) { + if ( m_Ply[n]->type == typ ) return n; + } + return -1; +} + +int Mesh::FindPlyProp ( int elem, std::string name ) +{ + for (int n=0; n < m_Ply[elem]->prop_list.size(); n++) { + if ( m_Ply[elem]->prop_list[n].name.compare ( name)==0 ) + return n; + } + return -1; +} + +void Mesh::LoadPly ( char* fname, float s ) +{ +/* int m_PlyCnt; + float m_PlyData[40]; + char buf[1000]; + char bword[1000]; + std::string word; + Buffer b(1000); + int vnum, fnum, elem, cnt; + char typ; + + if ( m_Mform == MFormat::UDef ) + CreateFVF (); + + m_File.Open ( fname, FILE_READ | FILE_SEQUENTIAL ); + if ( !m_File.Valid() ) { + error.PrintF ( "mesh", "Could not find file: %s\n", fname ); + error.Exit (); + } + + // Read header + m_File.ReadLine ( buf, 1000 ); + b.ReadWord ( buf, bword ); word = bword; + if ( word.compare("ply" )!=0 ) { + error.PrintF ( "Not a ply file. %s\n", fname ); + error.Exit (); + } + + debug.Printf ( "Reading PLY.\n" ); + while ( m_File.ReadLine ( buf, 1000 ) == FILE_STATUS_OK ) { + b.ReadWord ( buf, bword ); + word = bword; + if ( word.compare("comment" )!=0 ) { + if ( word.compare("end_header")==0 ) break; + if ( word.compare("property")==0 ) { + b.ReadWord ( buf, bword ); + word = bword; + if ( word.compare("float")==0 ) typ = PLY_FLOAT; + if ( word.compare("float16")==0 ) typ = PLY_FLOAT; + if ( word.compare("float32")==0 ) typ = PLY_FLOAT; + if ( word.compare("int8")==0 ) typ = PLY_INT; + if ( word.compare("uint8")==0 ) typ = PLY_UINT; + if ( word.compare("list")==0) { + typ = PLY_LIST; + b.ReadWord ( buf, bword ); + b.ReadWord ( buf, bword ); + } + b.ReadWord ( buf, bword ); + word = bword; + AddPlyProperty ( typ, word ); + } + if ( word.compare("element" )==0 ) { + b.ReadWord ( buf, bword); word = bword; + if ( word.compare("vertex")==0 ) { + b.ReadWord ( buf, bword); + vnum = atoi ( bword ); + debug.Printf ( " Verts: %d\n", vnum ); + AddPlyElement ( PLY_VERTS, vnum ); + } + if ( word.compare("face")==0 ) { + b.ReadWord ( buf, bword); + fnum = atoi ( bword ); + debug.Printf ( " Faces: %d\n", fnum ); + AddPlyElement ( PLY_FACES, fnum ); + } + } + } + } + + // Read data + int xi, yi, zi; + debug.Printf ( " Reading verts..\n" ); + elem = FindPlyElem ( PLY_VERTS ); + xi = FindPlyProp ( elem, "x" ); + yi = FindPlyProp ( elem, "y" ); + zi = FindPlyProp ( elem, "z" ); + if ( elem == -1 || xi == -1 || yi == -1 || zi == -1 ) { + debug.Printf ( "ERROR: Vertex data not found.\n" ); + exit(-1); + } + for (int n=0; n < m_Ply[elem]->num; n++) { + m_File.ReadLine ( buf, 1000 ); + for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) { + b.ReadWord ( buf, bword ); + m_PlyData[ j ] = atof ( bword ); + } + AddVert ( m_PlyData[xi]*s, m_PlyData[zi]*s, m_PlyData[yi]*s ); + } + + debug.Printf ( " Reading faces..\n" ); + elem = FindPlyElem ( PLY_FACES ); + xi = FindPlyProp ( elem, "vertex_indices" ); + if ( elem == -1 || xi == -1 ) { + debug.Printf ( "ERROR: Face data not found.\n" ); + exit(-1); + } + for (int n=0; n < m_Ply[elem]->num; n++) { + m_File.ReadLine ( buf, 1000 ); + m_PlyCnt = 0; + for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) { + if ( m_Ply[elem]->prop_list[j].type == PLY_LIST ) { + b.ReadWord ( buf, bword ); + cnt = atoi ( bword ); + m_PlyData[ m_PlyCnt++ ] = cnt; + for (int c =0; c < cnt; c++) { + b.ReadWord ( buf, bword ); + m_PlyData[ m_PlyCnt++ ] = atof ( bword ); + } + } else { + b.ReadWord ( buf, bword ); + m_PlyData[ m_PlyCnt++ ] = atof ( bword ); + } + } + if ( m_PlyData[xi] == 3 ) { + //debug.Printf ( " Face: %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] ); + AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] ); + } + + if ( m_PlyData[xi] == 4 ) { + //debug.Printf ( " Face: %d, %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4]); + AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4] ); + } + } + + Measure (); + ComputeNormalsFVF (); // !-- should be abstracted +*/ + + // UpdateMesh (); +} + +void Mesh::AddPlyElement ( char typ, int n ) +{ + debug.Printf ( " Element: %d, %d\n", typ, n ); + PlyElement* p = new PlyElement; + p->num = n; + p->type = typ; + p->prop_list.clear (); + m_PlyCurrElem = m_Ply.size(); + m_Ply.push_back ( p ); +} + +void Mesh::AddPlyProperty ( char typ, std::string name ) +{ + debug.Printf ( " Property: %d, %s\n", typ, name.c_str() ); + PlyProperty p; + p.name = name; + p.type = typ; + m_Ply [ m_PlyCurrElem ]->prop_list.push_back ( p ); +} \ No newline at end of file diff --git a/Extras/sph/common/mesh.h b/Extras/sph/common/mesh.h new file mode 100644 index 0000000..71032f9 --- /dev/null +++ b/Extras/sph/common/mesh.h @@ -0,0 +1,160 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEF_MESH + #define DEF_MESH + + #include + #include + + #include "geomx.h" + #include "mesh_info.h" + #include "vector.h" + + //#include "mfile.h" + + //#define MESH_DEBUG + + #ifdef MESH_DEBUG + #define VERT_DELTA 10000 + #define EDGE_DELTA 20000 + #define FACE_DELTA 30000 + #else + #define VERT_DELTA 0 + #define EDGE_DELTA 0 + #define FACE_DELTA 0 + #endif + + #define PLY_UINT 0 + #define PLY_INT 1 + #define PLY_FLOAT 2 + #define PLY_LIST 3 + #define PLY_VERTS 4 + #define PLY_FACES 5 + + struct PlyProperty { + char type; + std::string name; + }; + struct PlyElement { + int num; + char type; // 0 = vert, 1 = face + std::vector prop_list; + }; + + class Mesh : public GeomX, public MeshInfo { + public: + Mesh (); + + //virtual objType GetType () { return 'mesh'; } + + // Distributed functions + //virtual void onUpdate ( objData dat, mint::Event* e ); + //void UpdateMesh (); + + // Generic functions + void InitStatic (); + void DrawGL ( float* viewmat ); + void DrawFaceGL ( float* viewmat ); + void Measure (); + Mesh& operator= ( Mesh& op2 ); + + // Load PLY mesh + void LoadPly ( char* fname, float s ); + void AddPlyElement ( char typ, int n ); + void AddPlyProperty ( char typ, std::string name ); + void LoadPlyVerts (); + void LoadPlyFaces (); + int FindPlyElem ( char typ ); + int FindPlyProp ( int elem, std::string name ); + + // Vertex, Face, Edge functions + xref AddVert (float x, float y, float z ) { return (this->*m_AddVertFunc) (x, y, z); } + xref AddFaceFast (xref v1, xref v2, xref v3 ) { return (this->*m_AddFaceFast3Func) (v1, v2, v3); } + xref AddFaceFast (xref v1, xref v2, xref v3, xref v4 ) { return (this->*m_AddFaceFast4Func) (v1, v2, v3, v4); } + xref (Mesh::*m_AddVertFunc) (float x, float y, float z); + xref (Mesh::*m_AddFaceFast3Func) (xref v1, xref v2, xref v3); + xref (Mesh::*m_AddFaceFast4Func) (xref v1, xref v2, xref v3, xref v4); + + int NumVert () { return NumElem ( m_Vbuf ); } + int NumEdge () { return NumElem ( m_Ebuf ); } + int NumFace () { return NumElem ( m_Fbuf ); } + + void IncFace ( int n ) { m_CurrF += n; } + void DebugHeap (); + + // FVF - Face-Vertex-Face Mesh + void CreateFVF (); + void ClearFVF (); + void SetFuncFVF (); + xref AddVertFVF ( float x, float y, float z ); + xref AddFaceFast3FVF ( xref v1, xref v2, xref v3 ); + xref AddFaceFast4FVF ( xref v1, xref v2, xref v3, xref v4 ); + VertFVF* GetVertFVF ( int n ) { return (VertFVF*) (mBuf[m_Vbuf].data + n*mBuf[m_Vbuf].stride); } + FaceFVF* GetFaceFVF ( int n ) { return (FaceFVF*) (mBuf[m_Fbuf].data + n*mBuf[m_Fbuf].stride); } + void* GetExtraFVF ( VertFVF* v ) { return ((char*) v + miBufSize[(int) FVF][BVert]); } + void ComputeNormalsFVF (); + void SetNormalFVF ( int n, Vector3DF norm ); + void SetColorFVF ( int n, DWORD clr ); + void SmoothFVF ( int iter ); + void DebugFVF (); + void DrawVertsFVF ( float* viewmat, int a, int b ); + void DrawFacesFVF ( float* viewmat, int a, int b ); + + // CM - Connected Mesh + void CreateCM (); + void SetFuncCM (); + xref AddVertCM ( float x, float y, float z ); + xref AddFaceFast3CM ( xref v1, xref v2, xref v3 ); + xref AddFaceFast4CM ( xref v1, xref v2, xref v3, xref v4 ); + xref AddEdgeCM ( xref v1, xref v2 ); + xref FindEdgeCM ( xref v1, xref v2 ); + VertCM* GetVertCM ( int n ) { return (VertCM*) (mBuf[m_Vbuf].data + n*mBuf[m_Vbuf].stride); } + EdgeCM* GetEdgeCM ( int n ) { return (EdgeCM*) (mBuf[m_Ebuf].data + n*mBuf[m_Ebuf].stride); } + FaceCM* GetFaceCM ( int n ) { return (FaceCM*) (mBuf[m_Fbuf].data + n*mBuf[m_Fbuf].stride); } + void* GetExtraCM ( VertCM* v ) { return ((char*) v + miBufSize[(int) CM][BVert] ); } + void DebugCM (); + void DrawVertsCM ( float* viewmat, int a, int b ); + void DrawFacesCM ( float* viewmat, int a, int b ); + void DrawEdgesCM ( float* viewmat, int a, int b ); + + MFormat GetMeshBufs ( char& v, char& e, char& f ) { v = m_Vbuf; e = m_Ebuf; f = m_Fbuf; return m_Mform; } + + protected: + MFormat m_Mform; // Mesh format + char m_Vbuf; + char m_Ebuf; + char m_Fbuf; + + int m_CurrF; + + std::vector< PlyElement* > m_Ply; + //File m_File; + int m_PlyCurrElem; + + static bool mbInitStatic; + + Vector3DF mT; + }; + +#endif + diff --git a/Extras/sph/common/mesh_info.h b/Extras/sph/common/mesh_info.h new file mode 100644 index 0000000..745709a --- /dev/null +++ b/Extras/sph/common/mesh_info.h @@ -0,0 +1,97 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEF_MESH_INFO + #define DEF_MESH_INFO + + #include "common_defs.h" + //#include "mint_config.h" + typedef signed int xref; + + #define MAX_MFORMAT 10 + #define MAX_BFORMAT 5 + + // CM - Connected mesh + struct FaceCM { + xref e1, e2, e3, e4; + xref v1, v2, v3, v4; + }; + struct EdgeCM { + xref v1, v2; + xref f1, f2; + }; + struct VertCM { + hList elist; + hList flist; + float x, y, z; + }; + // FVF - Face-vertex-face mesh + struct FaceFVF { + xref v1, v2, v3, v4; + }; + struct VertFVF { + hList flist; + float x, y, z; + }; + + // Extra attributes + struct AttrPos { + float x, y, z; + }; + struct AttrClr { + DWORD clr; + }; + struct AttrNorm { + float nx, ny, nz; + }; + struct AttrTex { + float tu, tv; + }; + + class MeshInfo { + public: + enum MFormat { // Mesh format + UDef = 0, + VV = 1, // Vertex-Vertex + FV = 2, // Face-Vertex + FVF = 3, + WE = 4, // Winged-Edge + CM = 5 // Connected-Mesh + }; + enum BFormat { // Buffer format + BVert = 0, + BEdge = 1, + BFace = 2, + }; + enum AFormat { // Extra Attribute formats + APos = 0, + AClr = 1, + ANorm = 2, + ATex = 3 + }; + static int BufSize ( MFormat m, BFormat b ) { return miBufSize[(int) m][(int) b]; } + static int miBufSize [MAX_MFORMAT][MAX_BFORMAT]; + }; + +#endif + + diff --git a/Extras/sph/common/mtime.cpp b/Extras/sph/common/mtime.cpp new file mode 100644 index 0000000..90a562c --- /dev/null +++ b/Extras/sph/common/mtime.cpp @@ -0,0 +1,612 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifdef _MSC_VER + #include +#else + #include +#endif + +#include +#include +#include + +#include "mtime.h" +#include "mdebug.h" + +#ifdef _MSC_VER + #define VS2005 + #pragma comment ( lib, "winmm.lib" ) + LARGE_INTEGER m_BaseCount; + LARGE_INTEGER m_BaseFreq; +#endif + +using namespace mint; + +const int Time::m_DaysInMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +bool Time::m_Started = false; +sjtime m_BaseTime; +sjtime m_BaseTicks; + +void mint::start_timing ( sjtime base ) +{ + m_BaseTime = base; + + #ifdef _MSC_VER + m_BaseTicks = timeGetTime(); + QueryPerformanceCounter ( &m_BaseCount ); + QueryPerformanceFrequency ( &m_BaseFreq ); + #else + struct timeval tv; + gettimeofday(&tv, NULL); + m_BaseTicks = ((sjtime) tv.tv_sec * 1000000LL) + (sjtime) tv.tv_usec; + #endif +} + +void Time::SetSystemTime ( int accuracy ) +{ + switch ( accuracy ) { + case ACC_SEC: // 1 second accuracy + SetSystemTime (); + break; + case ACC_MSEC: { // 1 millisecond accuracy + #ifdef _MSC_VER + m_CurrTime = m_BaseTime + sjtime(timeGetTime() - m_BaseTicks)*MSEC_SCALAR; + #else + struct timeval tv; + gettimeofday(&tv, NULL); + sjtime t = ((sjtime) tv.tv_sec * 1000000LL) + (sjtime) tv.tv_usec; + m_CurrTime = m_BaseTime + ( t - m_BaseTicks) * 1000LL; // 1000LL - converts microseconds to milliseconds + #endif + } break; + case ACC_NSEC: { // 1 nanosecond accuracy + #ifdef _MSC_VER + LARGE_INTEGER currCount; + QueryPerformanceCounter ( &currCount ); + m_CurrTime = m_BaseTime + sjtime( (double(currCount.QuadPart-m_BaseCount.QuadPart) / m_BaseFreq.QuadPart) * SEC_SCALAR); + #else + debug.Printf ( "mtime", "ERROR: ACC_NSEC NOT IMPLEMENTED for Time::SetSystemTime\n" ); + #endif + } break; + } +} + + +Time::Time () +{ + if ( !m_Started ) { + m_Started = true; + SetSystemTime (); // Get base time from wall clock + start_timing ( m_CurrTime ); // Start timing from base time + } + m_CurrTime = 0; +} + +// Note regarding hours: +// 0 <= hr <= 23 +// hr = 0 is midnight (12 am) +// hr = 1 is 1 am +// hr = 12 is noon +// hr = 13 is 1 pm (subtract 12) +// hr = 23 is 11 pm (subtact 12) + +// GetScaledJulianTime +// Returns -1.0 if the time specified is invalid. +sjtime Time::GetScaledJulianTime ( int hr, int min, int m, int d, int y, int s, int ms, int ns ) +{ + double MJD; // Modified Julian Date (JD - 2400000.5) + sjtime SJT; // Scaled Julian Time SJT = MJD * 86400000 + UT + + // Check if date/time is valid + if (m <=0 || m > 12) return (sjtime) -1; + if ( y % 4 == 0 && m == 2) { // leap year in february + if (d <=0 || d > m_DaysInMonth[m]+1) return (sjtime) -1; + } else { + if (d <=0 || d > m_DaysInMonth[m]) return (sjtime) -1; + } + if (hr < 0 || hr > 23) return (sjtime) -1; + if (min < 0 || min > 59) return (sjtime) -1; + + // Compute Modified Julian Date + MJD = 367 * y - int ( 7 * (y + int (( m + 9)/12)) / 4 ); + MJD -= int ( 3 * (int((y + (m - 9)/7)/100) + 1) / 4); + MJD += int ( 275 * m / 9 ) + d + 1721028.5 - 1.0; + MJD -= 2400000.5; + // Compute Scaled Julian Time + SJT = sjtime(MJD) * sjtime( DAY_SCALAR ); + SJT += hr * HR_SCALAR + min * MIN_SCALAR + s * SEC_SCALAR + ms * MSEC_SCALAR + ns * NSEC_SCALAR; + return SJT; +} + +sjtime Time::GetScaledJulianTime ( int hr, int min, int m, int d, int y ) +{ + return GetScaledJulianTime ( hr, min, m, d, y, 0, 0, 0 ); +} + +void Time::GetTime ( sjtime SJT, int& hr, int& min, int& m, int& d, int& y) +{ + int s = 0, ms = 0, ns = 0; + GetTime ( SJT, hr, min, m, d, y, s, ms, ns ); +} + +void Time::GetTime ( sjtime SJT, int& hr, int& min, int& m, int& d, int& y, int& s, int &ms, int& ns) +{ + // Compute Universal Time from SJT + sjtime UT = sjtime( SJT % sjtime( DAY_SCALAR ) ); + + // Compute Modified Julian Date from SJT + double MJD = double(SJT / DAY_SCALAR); + + // Use MJD to get Month, Day, Year + double z = floor ( MJD + 1 + 2400000.5 - 1721118.5); + double g = z - 0.25; + double a = floor ( g / 36524.25 ); + double b = a - floor ( a / 4.0 ); + y = int( floor (( b + g ) / 365.25 ) ); + double c = b + z - floor ( 365.25 * y ); + m = int (( 5 * c + 456) / 153 ); + d = int( c - int (( 153 * m - 457) / 5) ); + if (m > 12) { + y++; + m -= 12; + } + // Use UT to get Hrs, Mins, Secs, Msecs + hr = int( UT / HR_SCALAR ); + UT -= hr * HR_SCALAR; + min = int( UT / MIN_SCALAR ); + UT -= min * MIN_SCALAR; + s = int ( UT / SEC_SCALAR ); + UT -= s * SEC_SCALAR; + ms = int ( UT / MSEC_SCALAR ); + UT -= ms * MSEC_SCALAR; + ns = int ( UT / NSEC_SCALAR ); + + // UT Example: + // MSEC_SCALAR = 1 + // SEC_SCALAR = 1,000 + // MIN_SCALAR = 60,000 + // HR_SCALAR = 3,600,000 + // DAY_SCALAR = 86,400,000 + // + // 7:14:03, 32 msec + // UT = 7*3,600,000 + 14*60,000 + 3*1,000 + 32 = 26,043,032 + // + // 26,043,032 / 3,600,000 = 7 26,043,032 - (7 * 3,600,000) = 843,032 + // 843,032 / 60,000 = 14 843,032 - (14 * 60,000) = 3,032 + // 3,032 / 1,000 = 3 3,032 - (3 * 1,000) = 32 + // 32 / 1 = 32 +} + +void Time::GetTime (int& s, int& ms, int& ns ) +{ + int hr, min, m, d, y; + GetTime ( m_CurrTime, hr, min, m, d, y, s, ms, ns ); +} + + +void Time::GetTime (int& hr, int& min, int& m, int& d, int& y) +{ + GetTime ( m_CurrTime, hr, min, m, d, y); +} + +void Time::GetTime (int& hr, int& min, int& m, int& d, int& y, int& s, int& ms, int& ns) +{ + GetTime ( m_CurrTime, hr, min, m, d, y, s, ms, ns); +} + +bool Time::SetTime ( int sec ) +{ + int hr, min, m, d, y; + GetTime ( m_CurrTime, hr, min, m, d, y ); + m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, sec, 0, 0 ); + return true; +} + +bool Time::SetTime ( int sec, int msec ) +{ + int hr, min, m, d, y; + GetTime ( m_CurrTime, hr, min, m, d, y ); + m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, sec, msec, 0 ); + return true; +} + +bool Time::SetTime (int hr, int min, int m, int d, int y) +{ + int s, ms, ns; + GetTime ( s, ms, ns ); + m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, s, ms, ns ); + if (m_CurrTime == -1.0) return false; + return true; +} + +bool Time::SetTime (int hr, int min, int m, int d, int y, int s, int ms, int ns) +{ + m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, s, ms, ns ); + if (m_CurrTime == -1.0) return false; + return true; +} + +bool Time::SetTime ( std::string line ) +{ + int hr, min, m, d, y; + std::string dat; + if ( line.substr ( 0, 1 ) == " " ) + dat = line.substr ( 1, line.length()-1 ).c_str(); + else + dat = line; + + hr = atoi ( dat.substr ( 0, 2).c_str() ); + min = atoi ( dat.substr ( 3, 2).c_str() ); + m = atoi ( dat.substr ( 6, 2).c_str () ); + d = atoi ( dat.substr ( 9, 2).c_str () ); + y = atoi ( dat.substr ( 12, 4).c_str () ); + return SetTime ( hr, min, m, d, y); +} + +bool Time::SetDate ( std::string line ) +{ + int hr, min, m, d, y; + std::string dat; + if ( line.substr ( 0, 1 ) == " " ) + dat = line.substr ( 1, line.length()-1 ).c_str(); + else + dat = line; + + hr = 0; + min = 0; + m = atoi ( dat.substr ( 0, 2).c_str () ); + d = atoi ( dat.substr ( 3, 2).c_str () ); + y = atoi ( dat.substr ( 6, 4).c_str () ); + return SetTime ( hr, min, m, d, y); +} + +std::string Time::GetDayOfWeekName () +{ + switch (GetDayOfWeek()) { + case 1: return "Sunday"; break; + case 2: return "Monday"; break; + case 3: return "Tuesday"; break; + case 4: return "Wednesday"; break; + case 5: return "Thursday"; break; + case 6: return "Friday"; break; + case 7: return "Saturday"; break; + } + return "day error"; +} + +int Time::GetDayOfWeek () +{ + // Compute Modified Julian Date + double MJD = (double) m_CurrTime / sjtime( DAY_SCALAR ); + + // Compute Julian Date + double JD = floor ( MJD + 1 + 2400000.5 ); + int dow = (int(JD - 0.5) % 7) + 4; + if (dow > 7) dow -= 7; + + // day of week (1 = sunday, 7 = saturday) + return dow ; +} + +int Time::GetWeekOfYear () +{ + int hr, min, m, d, y; + GetTime ( hr, min, m, d, y ); + double mjd_start = (double) GetScaledJulianTime ( 0, 0, 1, 1, y ) / DAY_SCALAR; // mjt for jan 1st of year + double mjd_curr = (double) GetScaledJulianTime ( 0, 0, m, d, y ) / DAY_SCALAR; // mjt for specified day in year + double JD = floor ( mjd_start + 1 + 2400000.5 ); + int dow = (int ( JD - 0.5 ) % 7) + 4; // day of week for jan 1st of year. + if (dow > 7) dow -= 7; + + // week of year (first week in january = week 0) + return int((mjd_curr - mjd_start + dow -1 ) / 7 ); +} + +int Time::GetElapsedDays ( Time& base ) +{ + return int( sjtime(m_CurrTime - base.GetSJT() ) / sjtime( DAY_SCALAR ) ); +} + +int Time::GetElapsedWeeks ( Time& base ) +{ + return GetElapsedDays(base) / 7; +} + +int Time::GetElapsedMonths ( Time& base) +{ + return int ( double(GetElapsedDays(base)) / 30.416 ); +} + +int Time::GetElapsedYears ( Time& base ) +{ + // It is much easier to compute this in m/d/y format rather + // than using julian dates. + int bhr, bmin, bm, bd, by; + int ehr, emin, em, ed, ey; + GetTime ( base.GetSJT(), bhr, bmin, bm, bd, by ); + GetTime ( m_CurrTime, ehr, emin, em, ed, ey ); + if ( em < bm) { + // earlier month + return ey - by - 1; + } else if ( em > bm) { + // later month + return ey - by; + } else { + // same month + if ( ed < bd ) { + // earlier day + return ey - by - 1; + } else if ( ed >= bd ) { + // later or same day + return ey - by; + } + } + return -1; +} + +int Time::GetFracDay ( Time& base ) +{ + // Resolution = 5-mins + return int( sjtime(m_CurrTime - base.GetSJT() ) % sjtime(DAY_SCALAR) ) / (MIN_SCALAR*5); +} + +int Time::GetFracWeek ( Time& base ) +{ + // Resolution = 1 hr + int day = GetElapsedDays(base) % 7; // day in week + int hrs = int( sjtime(m_CurrTime - base.GetSJT() ) % sjtime(DAY_SCALAR) ) / (HR_SCALAR); + return day * 24 + hrs; +} + +int Time::GetFracMonth ( Time& base ) +{ + // Resolution = 4 hrs + int day = (int) fmod ( double(GetElapsedDays(base)), 30.416 ); // day in month + int hrs = int( sjtime(m_CurrTime - base.GetSJT() ) % sjtime(DAY_SCALAR) ) / (HR_SCALAR*4); + return day * (24 / 4) + hrs; +} + +int Time::GetFracYear ( Time& base ) +{ + // It is much easier to compute this in m/d/y format rather + // than using julian dates. + int bhr, bmin, bm, bd, by; + int ehr, emin, em, ed, ey; + sjtime LastFullYear; + GetTime ( base.GetSJT() , bhr, bmin, bm, bd, by ); + GetTime ( m_CurrTime, ehr, emin, em, ed, ey ); + if ( em < bm) { + // earlier month + LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey - 1); + return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) ); + } else if ( em > bm) { + // later month + LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey); + return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) ); + } else { + // same month + if ( ed < bd ) { + // earlier day + LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey - 1); + return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) ); + } else if ( ed > bd ) { + // later day + LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey); + return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) ); + } else { + return 0; // same day + } + } +} + +std::string Time::GetReadableDate () +{ + char buf[200]; + std::string line; + int hr, min, m, d, y; + + GetTime ( hr, min, m, d, y ); + sprintf ( buf, "%02d:%02d %02d-%02d-%04d", hr, min, m, d, y); + return std::string ( buf ); +} + +std::string Time::GetReadableTime () +{ + char buf[200]; + std::string line; + int hr, min, m, d, y, s, ms, ns; + + GetTime ( hr, min, m, d, y, s, ms, ns ); + sprintf ( buf, "%02d:%02d:%02d %03d.%06d %02d-%02d-%04d", hr, min, s, ms, ns, m, d, y); + return std::string ( buf ); +} + +std::string Time::GetReadableSJT () +{ + char buf[200]; + sprintf ( buf, "%I64d", m_CurrTime ); + return std::string ( buf ); +} + +std::string Time::GetReadableTime ( int fmt ) +{ + char buf[200]; + int hr, min, m, d, y, s, ms, ns; + GetTime ( hr, min, m, d, y, s, ms, ns ); + + switch (fmt) { + case 0: sprintf ( buf, "%02d %03d.%06d", s, ms, ns); + } + return std::string ( buf ); +} + +void Time::SetSystemTime () +{ + int hr, mn, sec, m, d, y; + char timebuf[100]; + char datebuf[100]; + std::string line; + + #ifdef _MSC_VER + #ifdef VS2005 + _strtime_s ( timebuf, 100 ); + _strdate_s ( datebuf, 100 ); + #else + _strtime ( timebuf ); + _strdate ( datebuf ); + #endif + #endif + #if (defined(__linux__) || defined(__CYGWIN__)) + time_t tt; + struct tm tim; + tt = time(NULL); + localtime_r(&tt, &tim); + sprintf( timebuf, "%02i:%02i:%02i", tim.tm_hour, tim.tm_min, tim.tm_sec); + sprintf( datebuf, "%02i:%02i:%02i", tim.tm_mon, tim.tm_mday, tim.tm_year % 100); + #endif + + line = timebuf; + hr = atoi ( line.substr ( 0, 2).c_str() ); + mn = atoi ( line.substr ( 3, 2).c_str() ); + sec = atoi ( line.substr ( 6, 2).c_str() ); + line = datebuf; + m = atoi ( line.substr ( 0, 2).c_str() ); + d = atoi ( line.substr ( 3, 2).c_str() ); + y = atoi ( line.substr ( 6, 2).c_str() ); + + // NOTE: This only works from 1930 to 2030 + if ( y > 30) y += 1900; + else y += 2000; + + SetTime ( hr, mn, m, d, y, sec, 0, 0); +} + + +double Time::GetSec () +{ + return ((double) m_CurrTime / (double) SEC_SCALAR ); +} + +int Time::GetMSec () +{ + return ((double) m_CurrTime / (double) MSEC_SCALAR ); + + /*int s, ms, ns; + GetTime ( s, ms, ns ); + return ms;*/ +} + +void Time::Advance ( Time& t ) +{ + m_CurrTime += t.GetSJT (); +} + +void Time::AdvanceMinutes ( int n) +{ + m_CurrTime += (sjtime) MIN_SCALAR * n; +} + +void Time::AdvanceHours ( int n ) +{ + m_CurrTime += (sjtime) HR_SCALAR * n; +} + +void Time::AdvanceDays ( int n ) +{ + m_CurrTime += (sjtime) DAY_SCALAR * n; +} + +void Time::AdvanceSec ( int n ) +{ + m_CurrTime += (sjtime) SEC_SCALAR * n; +} + +void Time::AdvanceMins ( int n) +{ + m_CurrTime += (sjtime) MIN_SCALAR * n; +} + +void Time::AdvanceMSec ( int n ) +{ + m_CurrTime += (sjtime) MSEC_SCALAR * n; +} + +Time& Time::operator= ( const Time& op ) { m_CurrTime = op.m_CurrTime; return *this; } +Time& Time::operator= ( Time& op ) { m_CurrTime = op.m_CurrTime; return *this; } +bool Time::operator< ( const Time& op ) { return (m_CurrTime < op.m_CurrTime); } +bool Time::operator> ( const Time& op ) { return (m_CurrTime > op.m_CurrTime); } +bool Time::operator< ( Time& op ) { return (m_CurrTime < op.m_CurrTime); } +bool Time::operator> ( Time& op ) { return (m_CurrTime > op.m_CurrTime); } + +bool Time::operator<= ( const Time& op ) { return (m_CurrTime <= op.m_CurrTime); } +bool Time::operator>= ( const Time& op ) { return (m_CurrTime >= op.m_CurrTime); } +bool Time::operator<= ( Time& op ) { return (m_CurrTime <= op.m_CurrTime); } +bool Time::operator>= ( Time& op ) { return (m_CurrTime >= op.m_CurrTime); } + +Time Time::operator- ( Time& op ) +{ + return Time( m_CurrTime - op.GetSJT() ); +} +Time Time::operator+ ( Time& op ) +{ + return Time( m_CurrTime + op.GetSJT() ); +} + +bool Time::operator== ( const Time& op ) +{ + return (m_CurrTime == op.m_CurrTime); +} +bool Time::operator!= ( Time& op ) +{ + return (m_CurrTime != op.m_CurrTime); +} + +void Time::RegressionTest () +{ + // This code verifies the Julian Date calculations are correct for all + // minutes over a range of years. Useful to debug type issues when + // compiling on different platforms. + // + int m, d, y, hr, min; + int cm, cd, cy, chr, cmin; + + for (y=2000; y < 2080; y++) { + for (m=1; m <= 12; m++) { + for (d=1; d <= 31; d++) { + for (hr=0; hr<=23; hr++) { + for (min=0; min<=59; min++) { + if ( SetTime ( hr, min, m, d, y, 0, 0, 0 ) ) { + GetTime ( chr, cmin, cm, cd, cy ); + if ( hr!=chr || min!=cmin || m!=cm || d!=cd || y!=cy) { +// debug.Printf (" time", "Error: %d, %d, %d, %d, %d = %I64d\n", hr, min, m, d, y, GetSJT()); +// debug.Printf (" time", "-----: %d, %d, %d, %d, %d\n", chr, cmin, cm, cd, cy); + } + } + } + } + } + } +// debug.Printf (" time", "Verified: %d\n", y); + } +} + + diff --git a/Extras/sph/common/mtime.h b/Extras/sph/common/mtime.h new file mode 100644 index 0000000..2f8c1b6 --- /dev/null +++ b/Extras/sph/common/mtime.h @@ -0,0 +1,234 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef TIME_HPP + #define TIME_HPP + + #include + + #ifdef _MSC_VER + #include + typedef __int64 mstime; // microsecond time = 8 byte integer + typedef __int64 sjtime; // scaled julian times = 8 byte integer + + #define MSEC_SCALAR 1000000i64 + #define SEC_SCALAR 1000000000i64 + #define MIN_SCALAR 60000000000i64 + #define HR_SCALAR 3600000000000i64 + #define DAY_SCALAR 86400000000000i64 + + #pragma warning ( disable : 4522 ) + #pragma warning ( disable : 4996 ) // sprintf warning + #endif + + #ifdef __linux__ + #include + typedef __s64 mstime; + typedef __s64 sjtime; + + #define MSEC_SCALAR 1000000LL + #define SEC_SCALAR 1000000000LL + #define MIN_SCALAR 60000000000LL + #define HR_SCALAR 3600000000000LL + #define DAY_SCALAR 86400000000000LL + #endif + + #ifdef __CYGWIN__ + #include // found in \cygwin\usr\include\w32api + typedef __int64 mstime; + typedef __int64 sjtime; + + #define MSEC_SCALAR 1000000LL + #define SEC_SCALAR 1000000000LL + #define MIN_SCALAR 60000000000LL + #define HR_SCALAR 3600000000000LL + #define DAY_SCALAR 86400000000000LL + #endif + + #define ACC_SEC 0 + #define ACC_MSEC 1 + #define ACC_NSEC 2 + + #define NSEC_SCALAR 1 + + // Time Class + // R. Hoetzlein + // + // Overview: + // There is a need in many systems to represent both very small (nanoseconds) and + // very large (millenia) timescales accurately. Modified Julian Date accurate represents + // individual days over +/- about 30,000 yrs. However, MJD represents fractions of a day + // as a floating point fraction. This is inaccurate for any timing-critical applications. + // The Time class here uses an 8-byte (64 bit) integer called SJT, Scaled Julian Time. + // SJT = MJD * DAY_SCALAR + UT (nanoseconds). + // SJT is the Modified Julian Date scaled by a integer factor, and added to Universal Time + // represented in nanoseconds. + // + // Features: + // - Accurately represents individual nanoseconds over +/- 30,000 yrs. + // - Correct rollover of tiny time scales on month, day, year boundaries. + // e.g. Set date/time to 11:59:59.9999, on Feb 28th, + // - Accurately gives day of the week for any date + // - Accurately compares two dates (days elapsed) even across leap-years. + // - Adjust sec/nsec independently from month/day/year (work at scale you desire) + // + // Implementation Notes: + // JD = Julian Day is the number of days elapsed since Jan 1, 4713 BC in the proleptic Julian calendar. + // http://en.wikipedia.org/wiki/Julian_day + // MJD = Modified Julian Date. Most modern dates, after 19th c., have Julian Date which are greater + // than 2400000.5. MJD is an offset. MJD = JD - 2400000.5 + // It shifts the epoch date (start date) to Nov 17, 1858. + // UT = Universal Time. This is the time of day in hours as measured from Greenwich England. + // For non-astronomic uses, this is: UT = Local Time + Time Zone. + // SJT = Scaled Julian Time = MJD * DAY_SCALAR + UT (in nanoseconds). + // + // Julian Dates (and their MJD and SJT equivalents) + // ------------ + // Jan 1, 4713 BC = JD 0 = MJD -2400000 = SJT + // Jan 1, 1500 AD = JD 2268933.5 = MJD -131067 = SJT + // Nov 16, 1858 AD = JD 2400000.5 = MJD 0 = SJT 0 + // Jan 1, 1960 AD = JD 2436935.5 = MJD 36935 = SJT 3,191,184,000,000 + // Jan 1, 2005 AD = JD 2453372.5 = MJD 53372 = SJT 4,611,340,800,000 + // Jan 1, 2100 AD = JD 2488070.5 = MJD 88070 = SJT 7,609,248,000,000 + // + // + // + // 32/64-Bit Integer Ranges + // 32-bit Integer Min: –2,147,483,648 ( 4 bytes ) + // 32-bit Integer Max: 2,147,483,647 + // SJT 2005: 4,611,340,800,000 + // 64-bit Integer Min: –9,223,372,036,854,775,808 + // 64-bit Integer Max: 9,223,372,036,854,775,807 ( 8 bytes ) + // + // SJT Range + // --------- + // * USING DAY_SCALAR = 86,400,000 (millisec accuracy) + // SJT Range = (+/-9,223,372,036,854,775,807 SJT / 86,400,000 DAY_SCALAR) + // SJT Range (in Julian Days) = +2400000.5 + (+/-106,751,991,167 MJD) + // SJT Range (in Julian Days) = +/- 292278883 years, with 1 millisecond accuracy. + // + // * USING DAY_SCALAR = 86,400,000,000,000 (nanosec accuracy) + // SJT Range = (+/-9,223,372,036,854,775,807 SJT / 86,400,000,000,000 DAY_SCALAR) + // SJT Range (in Julian Days) = +2400000.5 + (+/-106,751 MJD) + // SJT Range (in Julian Days) = 1566 AD to 2151 AD, with 1 nanosecond accuracy. + + namespace mint { + + class Time { + public: + Time (); + Time ( sjtime t ) { m_CurrTime = t; } + Time ( int sec, int msec ) { m_CurrTime = 0; SetTime ( sec, msec ); } + + // Set time + bool SetTime ( int sec ); // Set seconds + bool SetTime ( int sec, int msec ); // Set seconds, msecs + bool SetTime ( int hr, int min, int m, int d, int y); // Set hr/min, month, day, year + bool SetTime ( int hr, int min, int m, int d, int y, int s, int ms, int ns); // Set hr/min, month, day, year, sec, ms, ns + bool SetTime ( Time& t ) { m_CurrTime = t.GetSJT(); return true;} // Set to another Time object + bool SetTime ( std::string line ); // Set time from string (hr,min,sec) + bool SetDate ( std::string line ); // Set date from string (mo,day,yr) + void SetSystemTime (); // Set date/time to system clock + void SetSystemTime ( int accuracy ); // Set date/time to system clock + void SetSJT ( sjtime t ) { m_CurrTime = t ;} // Set Scaled Julian Time directly + + // Get time + void GetTime (int& sec, int& msec, int& nsec ); + void GetTime (int& hr, int& min, int& m, int& d, int& y); + void GetTime (int& hr, int& min, int& m, int& d, int& y, int& s, int& ms, int& ns); + double GetSec (); + int GetMSec (); + std::string GetReadableDate (); + std::string GetReadableTime (); + std::string GetReadableTime ( int fmt ); + std::string GetReadableSJT (); + std::string GetDayOfWeekName (); + sjtime GetSJT () { return m_CurrTime; } + + // Advance Time + void Advance ( Time& t ); + void AdvanceMinutes ( int n); + void AdvanceHours ( int n ); + void AdvanceDays ( int n ); + void AdvanceSec ( int n ); + void AdvanceMins ( int n); + void AdvanceMSec ( int n ); + + // Utility functions + // (these do the actual work, but should not be private as they may be useful to user) + sjtime GetScaledJulianTime ( int hr, int min, int m, int d, int y ); + sjtime GetScaledJulianTime ( int hr, int min, int m, int d, int y, int s, int ms, int ns ); + void GetTime ( sjtime t, int& hr, int& min, int& m, int& d, int& y); + void GetTime ( sjtime t, int& hr, int& min, int& m, int& d, int& y, int& s, int& ms, int& ns); + + // Get/Set Julian Date and Modified Julain Date + void SetJD ( double jd ); + void SetMJD ( int jd ); + double GetJD (); + int GetMJD (); + + // Time operators + Time& operator= ( const Time& op ); + Time& operator= ( Time& op ); + bool operator< ( const Time& op ); + bool operator< ( Time& op ); + bool operator> ( const Time& op ); + bool operator> ( Time& op ); + bool operator<= ( const Time& op ); + bool operator<= ( Time& op ); + bool operator>= ( const Time& op ); + bool operator>= ( Time& op ); + bool operator== ( const Time& op ); + bool operator!= ( Time& op ); + Time operator- ( Time& op ); + Time operator+ ( Time& op ); + + // Elapsed Times + int GetElapsedDays ( Time& base ); + int GetElapsedWeeks ( Time& base ); + int GetElapsedMonths ( Time& base ); + int GetElapsedYears ( Time& base ); + int GetFracDay ( Time& base ); // Return Unit = 5 mins + int GetFracWeek ( Time& base ); // Return Unit = 1 hr + int GetFracMonth ( Time& base ); // Return Unit = 4 hrs + int GetFracYear ( Time& base ); // Return Unit = 1 day + int GetDayOfWeek (); + int GetWeekOfYear (); + + void RegressionTest (); + + private: + static const int m_DaysInMonth[13]; + static bool m_Started; + + sjtime m_CurrTime; + }; + + // Used for precise system time (Win32) + void start_timing ( sjtime base ); + + } +#endif + + + diff --git a/Extras/sph/common/particle.cpp b/Extras/sph/common/particle.cpp new file mode 100644 index 0000000..0eca87b --- /dev/null +++ b/Extras/sph/common/particle.cpp @@ -0,0 +1,23 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "particle.h" \ No newline at end of file diff --git a/Extras/sph/common/particle.h b/Extras/sph/common/particle.h new file mode 100644 index 0000000..06fdf5e --- /dev/null +++ b/Extras/sph/common/particle.h @@ -0,0 +1,29 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef DEF_PARTICLE + #define DEF_PARTICLE + + #include "vector.h" + + + +#endif diff --git a/Extras/sph/common/point_set.cpp b/Extras/sph/common/point_set.cpp new file mode 100644 index 0000000..d343cda --- /dev/null +++ b/Extras/sph/common/point_set.cpp @@ -0,0 +1,539 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "gl_helper.h" + +#include "point_set.h" + +int PointSet::m_pcurr = -1; + +PointSet::PointSet () +{ + m_GridRes.Set ( 0, 0, 0 ); + m_pcurr = -1; + Reset (); +} + +int PointSet::GetGridCell ( int x, int y, int z ) +{ + return (int) ( (z*m_GridRes.y + y)*m_GridRes.x + x); +} + +Point* PointSet::firstGridParticle ( int gc, int& p ) +{ + m_pcurr = m_Grid [ gc ]; + if ( m_pcurr == -1 ) return 0x0; + p = m_pcurr; + return (Point*) (mBuf[0].data + m_pcurr * mBuf[0].stride); +} + +Point* PointSet::nextGridParticle ( int& p ) +{ + Point* pnt = 0x0; + if ( m_pcurr != -1 ) { + pnt = (Point*) (mBuf[0].data + m_pcurr * mBuf[0].stride); + p = m_pcurr; + m_pcurr = pnt->next; + } + return pnt; +} + +unsigned short* PointSet::getNeighborTable ( int n, int& cnt ) +{ + cnt = m_NC[n]; + if ( cnt == 0 ) return 0x0; + return &m_Neighbor[n][0]; +} + +float PointSet::GetValue ( float x, float y, float z ) +{ + float dx, dy, dz, dsq; + float sum; + int pndx; + Point* pcurr; + float R2 = 1.8*1.8; + + Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 ); + + int cnt = 0; + sum = 0.0; + for (int cell=0; cell < 8; cell++ ) { + if ( m_GridCell[cell] != -1 ) { + pndx = m_Grid [ m_GridCell[cell] ]; + while ( pndx != -1 ) { + pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride); + dx = x - pcurr->pos.x; + dy = y - pcurr->pos.y; + dz = z - pcurr->pos.z; + dsq = dx*dx+dy*dy+dz*dz; + if ( dsq < R2 ) sum += R2 / dsq; + pndx = pcurr->next; + } + } + } + return sum; +} +Vector3DF PointSet::GetGradient ( float x, float y, float z ) +{ + Vector3DF norm; + float dx, dy, dz, dsq; + float sum; + int pndx; + Point* pcurr; + float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0); + + Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 ); + + int cnt = 0; + sum = 0.0; + norm.Set (0,0,0); + for (int cell=0; cell < 8; cell++ ) { + if ( m_GridCell[cell] != -1 ) { + pndx = m_Grid [ m_GridCell[cell] ]; + while ( pndx != -1 ) { + pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride); + dx = x - pcurr->pos.x; + dy = y - pcurr->pos.y; + dz = z - pcurr->pos.z; + dsq = dx*dx+dy*dy+dz*dz; + if ( dsq > 0 && dsq < R2 ) { + dsq = 2.0*R2 / (dsq*dsq); + norm.x += dx * dsq; + norm.y += dy * dsq; + norm.z += dz * dsq; + } + pndx = pcurr->next; + } + } + } + norm.Normalize (); + return norm; +} + +DWORD PointSet::GetColor ( float x, float y, float z ) +{ + Vector3DF clr; + float dx, dy, dz, dsq; + float sum; + int pndx; + Point* pcurr; + float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0); + + Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 ); + + int cnt = 0; + sum = 0.0; + clr.Set (0,0,0); + for (int cell=0; cell < 8; cell++ ) { + if ( m_GridCell[cell] != -1 ) { + pndx = m_Grid [ m_GridCell[cell] ]; + while ( pndx != -1 ) { + pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride); + dx = x - pcurr->pos.x; + dy = y - pcurr->pos.y; + dz = z - pcurr->pos.z; + dsq = dx*dx+dy*dy+dz*dz; + if ( dsq < R2 ) { + dsq = 2.0*R2 / (dsq*dsq); + clr.x += RED(pcurr->clr) * dsq; + clr.y += GRN(pcurr->clr) * dsq; + clr.z += BLUE(pcurr->clr) * dsq; + } + pndx = pcurr->next; + } + } + } + clr.Normalize (); + return COLORA(clr.x, clr.y, clr.z, 1.0); +} + +void PointSet::Reset () +{ + // Reset number of particles +// ResetBuffer ( 0 ); + + m_Time = 0; + m_DT = 0.1; + m_Param[POINT_GRAV] = 100.0; + m_Param[PLANE_GRAV] = 0.0; + + m_Vec[ POINT_GRAV_POS].Set(0,0,50.0); + m_Vec[ PLANE_GRAV_DIR].Set(0,0,-9.8); + m_Vec[ EMIT_RATE ].Set ( 1, 10, 0 ); + m_Vec[ EMIT_POS ].Set ( 50, 0, 35 ); + m_Vec[ EMIT_ANG ].Set ( 90, 45, 50.0 ); + m_Vec[ EMIT_DANG ].Set ( 0, 0, 0 ); + m_Vec[ EMIT_SPREAD ].Set ( 4, 4, 1 ); +} + +void PointSet::Initialize ( int mode, int total ) +{ + switch (mode) { + case BPOINT: { + FreeBuffers (); + AddBuffer ( BPOINT, sizeof ( Point ), total ); + AddAttribute ( 0, "pos", sizeof ( Vector3DF ), false ); + AddAttribute ( 0, "color", sizeof ( DWORD ), false ); + Reset (); + } break; + + case BPARTICLE: { + FreeBuffers (); + AddBuffer ( BPARTICLE, sizeof ( Particle ), total ); + AddAttribute ( 0, "pos", sizeof ( Vector3DF ), false ); + AddAttribute ( 0, "color", sizeof ( DWORD ), false ); + AddAttribute ( 0, "vel", sizeof ( Vector3DF ), false ); + AddAttribute ( 0, "ndx", sizeof ( unsigned short ), false ); + AddAttribute ( 0, "age", sizeof ( unsigned short ), false ); + Reset (); + } break; + } + + +} + +int PointSet::AddPoint () +{ + xref ndx; + AddElem ( 0, ndx ); + return ndx; +} + +int PointSet::AddPointReuse () +{ + xref ndx; + if ( NumPoints() < mBuf[0].max-1 ) + AddElem ( 0, ndx ); + else + RandomElem ( 0, ndx ); + return ndx; +} + +void PointSet::AddVolume ( Vector3DF min, Vector3DF max, float spacing ) +{ + Vector3DF pos; + Point* p; + float dx, dy, dz; + dx = max.x-min.x; + dy = max.y-min.y; + dz = max.z-min.z; + for (float z = max.z; z >= min.z; z -= spacing ) { + for (float y = min.y; y <= max.y; y += spacing ) { + for (float x = min.x; x <= max.x; x += spacing ) { + p = GetPoint ( AddPointReuse () ); + pos.Set ( x, y, z); + //pos.x += -0.05 + float( rand() * 0.1 ) / RAND_MAX; + //pos.y += -0.05 + float( rand() * 0.1 ) / RAND_MAX; + //pos.z += -0.05 + float( rand() * 0.1 ) / RAND_MAX; + p->pos = pos; + p->clr = COLORA( (x-min.x)/dx, (y-min.y)/dy, (z-min.z)/dz, 1); + } + } + } +} + +void PointSet::Draw ( float* view_mat, float rad ) +{ + char* dat; + Point* p; + glEnable ( GL_NORMALIZE ); + + if ( m_Param[PNT_DRAWMODE] == 0 ) { + glLoadMatrixf ( view_mat ); + dat = mBuf[0].data; + for (int n = 0; n < NumPoints(); n++) { + p = (Point*) dat; + glPushMatrix (); + glTranslatef ( p->pos.x, p->pos.y, p->pos.z ); + glScalef ( 0.2, 0.2, 0.2 ); + glColor4f ( RED(p->clr), GRN(p->clr), BLUE(p->clr), ALPH(p->clr) ); + drawSphere (); + glPopMatrix (); + dat += mBuf[0].stride; + } + } else if ( m_Param[PNT_DRAWMODE] == 1 ) { + glLoadMatrixf ( view_mat ); + dat = mBuf[0].data; + glBegin ( GL_POINTS ); + for (int n=0; n < NumPoints(); n++) { + p = (Point*) dat; + glColor3f ( RED(p->clr), GRN(p->clr), BLUE(p->clr) ); + glVertex3f ( p->pos.x, p->pos.y, p->pos.z ); + dat += mBuf[0].stride; + } + glEnd (); + } +} + +void PointSet::Emit ( float spacing ) +{ + Particle* p; + Vector3DF dir; + Vector3DF pos; + float ang_rand, tilt_rand; + float rnd = m_Vec[EMIT_RATE].y * 0.15; + int x = (int) sqrt(m_Vec[EMIT_RATE].y); + + for ( int n = 0; n < m_Vec[EMIT_RATE].y; n++ ) { + ang_rand = (float(rand()*2.0/RAND_MAX) - 1.0) * m_Vec[EMIT_SPREAD].x; + tilt_rand = (float(rand()*2.0/RAND_MAX) - 1.0) * m_Vec[EMIT_SPREAD].y; + dir.x = cos ( ( m_Vec[EMIT_ANG].x + ang_rand) * DEGtoRAD ) * sin( ( m_Vec[EMIT_ANG].y + tilt_rand) * DEGtoRAD ) * m_Vec[EMIT_ANG].z; + dir.y = sin ( ( m_Vec[EMIT_ANG].x + ang_rand) * DEGtoRAD ) * sin( ( m_Vec[EMIT_ANG].y + tilt_rand) * DEGtoRAD ) * m_Vec[EMIT_ANG].z; + dir.z = cos ( ( m_Vec[EMIT_ANG].y + tilt_rand) * DEGtoRAD ) * m_Vec[EMIT_ANG].z; + pos = m_Vec[EMIT_POS]; + pos.x += spacing * (n/x); + pos.y += spacing * (n%x); + + p = (Particle*) GetElem( 0, AddPointReuse () ); + p->pos = pos; + p->vel = dir; + p->vel_eval = dir; + p->age = 0; + p->clr = COLORA ( m_Time/10.0, m_Time/5.0, m_Time /4.0, 1 ); + } +} + + +void PointSet::Run () +{ + if ( m_Vec[EMIT_RATE].x > 0 && ++m_Frame >= (int) m_Vec[EMIT_RATE].x ) { + m_Frame = 0; + Emit ( 1.0 ); + } + Advance(); +} + +void PointSet::Advance () +{ + char* dat; + Particle* p; + Vector3DF vnext, accel, norm; + + vnext = m_Vec[EMIT_DANG]; + vnext *= m_DT; + m_Vec[EMIT_ANG] += vnext; + + dat = mBuf[0].data; + for ( int c = 0; c < NumPoints(); c++ ) { + p = (Particle*) dat; + + accel.Set (0, 0, 0); + + // Plane gravity + if ( m_Param[PLANE_GRAV] > 0) + accel += m_Vec[PLANE_GRAV_DIR]; + + // Point gravity + if ( m_Param[POINT_GRAV] > 0 ) { + norm.x = ( p->pos.x - m_Vec[POINT_GRAV_POS].x ); + norm.y = ( p->pos.y - m_Vec[POINT_GRAV_POS].y ); + norm.z = ( p->pos.z - m_Vec[POINT_GRAV_POS].z ); + norm.Normalize (); + norm *= m_Param[POINT_GRAV]; + accel -= norm; + } + + // Leapfrog Integration ---------------------------- + vnext = accel; + vnext *= m_DT; + vnext += p->vel; // v(t+1/2) = v(t-1/2) + a(t) dt + p->vel_eval = p->vel; + p->vel_eval += vnext; + p->vel_eval *= 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later + p->vel = vnext; + vnext *= m_DT; + p->pos += vnext; // p(t+1) = p(t) + v(t+1/2) dt + + // Euler integration ------------------------------- + // accel += m_Gravity; + // accel *= m_DT; + // mParticles[c].vel += accel; // v(t+1) = v(t) + a(t) dt + // mParticles[c].vel_eval += accel; + // mParticles[c].vel_eval *= m_DT/d; + // mParticles[c].pos += mParticles[c].vel_eval; + // mParticles[c].vel_eval = mParticles[c].vel; + + dat += mBuf[0].stride; + } + + m_Time += m_DT; +} + +// Ideal grid cell size (gs) = 2 * smoothing radius = 0.02*2 = 0.04 +// Ideal domain size = k*gs/d = k*0.02*2/0.005 = k*8 = {8, 16, 24, 32, 40, 48, ..} +// (k = number of cells, gs = cell size, d = simulation scale) +void PointSet::Grid_Setup ( Vector3DF min, Vector3DF max, float sim_scale, float cell_size, float border ) +{ + float world_cellsize = cell_size / sim_scale; + m_Grid.clear (); + m_GridMin = min; m_GridMin -= border; + m_GridMax = max; m_GridMax += border; + m_GridSize = m_GridMax; + m_GridSize -= m_GridMin; + m_GridCellsize = world_cellsize; + m_GridRes.x = ceil ( m_GridSize.x / world_cellsize ); // Determine grid resolution + m_GridRes.y = ceil ( m_GridSize.y / world_cellsize ); + m_GridRes.z = ceil ( m_GridSize.z / world_cellsize ); + m_GridSize.x = m_GridRes.x * cell_size / sim_scale; // Adjust grid size to multiple of cell size + m_GridSize.y = m_GridRes.y * cell_size / sim_scale; + m_GridSize.z = m_GridRes.z * cell_size / sim_scale; + m_GridDelta = m_GridRes; // delta = translate from world space to cell # + m_GridDelta /= m_GridSize; + m_GridTotal = (int)(m_GridSize.x * m_GridSize.y * m_GridSize.z); + + m_Grid.clear (); + m_GridCnt.clear (); + + m_Grid.reserve ( m_GridTotal ); + m_GridCnt.reserve ( m_GridTotal ); + for (int n=0; n < m_GridTotal; n++) { + m_Grid.push_back ( -1 ); + m_GridCnt.push_back ( 0 ); + } + +} + +void PointSet::Grid_Draw ( float* view_mat ) +{ + float clr; + int cx, cy, cz; + float x1, y1, z1; + float x2, y2, z2; + int g = 0; + + glLoadMatrixf ( view_mat ); + glColor3f ( 0.7, 0.7, 0.7 ); + + glBegin ( GL_LINES ); + + cz = 0; + //for ( cz = 0; cz < m_GridRes.z; cz++ ) { + for ( cy = 0; cy < m_GridRes.y; cy++ ) { + for ( cx = 0; cx < m_GridRes.x; cx++ ) { + // Cell is not empty. Process it. + //if ( m_Grid[g] != 0x0 ) { + // clr = m_GridCnt[g]/30.0; + clr = 0.25; + if ( clr <0.25) clr =0.25; + if ( clr >1) clr =1 ; + glColor3f ( clr, clr, clr ); + x1 = (cx * m_GridDelta.x) + m_GridMin.x; x2 = ((cx+1) * m_GridDelta.x) + m_GridMin.x; + y1 = (cy * m_GridDelta.y) + m_GridMin.y; y2 = ((cy+1) * m_GridDelta.y) + m_GridMin.y; + z1 = (cz * m_GridDelta.z) + m_GridMin.z; z2 = ((cz+1) * m_GridDelta.z) + m_GridMin.z; + glVertex3f ( x1, y1, z1 ); glVertex3f ( x2, y1, z1 ); + glVertex3f ( x2, y1, z1 ); glVertex3f ( x2, y2, z1 ); + glVertex3f ( x2, y2, z1 ); glVertex3f ( x1, y2, z1 ); + glVertex3f ( x1, y2, z1 ); glVertex3f ( x1, y1, z1 ); + glVertex3f ( x1, y1, z2 ); glVertex3f ( x2, y1, z2 ); + glVertex3f ( x2, y1, z2 ); glVertex3f ( x2, y2, z2 ); + glVertex3f ( x2, y2, z2 ); glVertex3f ( x1, y2, z2 ); + glVertex3f ( x1, y2, z2 ); glVertex3f ( x1, y1, z2 ); + glVertex3f ( x1, y1, z1 ); glVertex3f ( x1, y1, z2 ); + glVertex3f ( x1, y2, z1 ); glVertex3f ( x1, y2, z2 ); + glVertex3f ( x2, y2, z1 ); glVertex3f ( x2, y2, z2 ); + glVertex3f ( x2, y1, z1 ); glVertex3f ( x2, y1, z2 ); + //} + g++; + } + } + //} + + glEnd (); +} + +void PointSet::Grid_InsertParticles () +{ + char *dat1, *dat1_end; + Point *p; + int gs; + int gx, gy, gz; + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) + ((Point*) dat1)->next = -1; + + for (int n=0; n < m_GridTotal; n++) { + m_Grid[n] = -1; + m_GridCnt[n] = 0; + } + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + int n = 0; + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) { + p = (Point*) dat1; + gx = (int)( (p->pos.x - m_GridMin.x) * m_GridDelta.x); // Determine grid cell + gy = (int)( (p->pos.y - m_GridMin.y) * m_GridDelta.y); + gz = (int)( (p->pos.z - m_GridMin.z) * m_GridDelta.z); + gs = (int)( (gz*m_GridRes.y + gy)*m_GridRes.x + gx); + if ( gs >= 0 && gs < m_GridTotal ) { + p->next = m_Grid[gs]; + m_Grid[gs] = n; + m_GridCnt[gs]++; + } + n++; + } +} + +int PointSet::Grid_FindCell ( Vector3DF p ) +{ + int gc; + Vector3DI cell; + cell.x = (int) (p.x - m_GridMin.x) * m_GridDelta.x; + cell.y = (int) (p.y - m_GridMin.y) * m_GridDelta.y; + cell.z = (int) (p.z - m_GridMin.z) * m_GridDelta.z; + gc = (int)( (cell.z*m_GridRes.y + cell.y)*m_GridRes.x + cell.x); + if ( gc < 0 || gc > m_GridTotal ) return -1; + return gc; +} + +void PointSet::Grid_FindCells ( Vector3DF p, float radius ) +{ + Vector3DI sph_min; + + // Compute sphere range + sph_min.x = (int)((-radius + p.x - m_GridMin.x) * m_GridDelta.x); + sph_min.y = (int)((-radius + p.y - m_GridMin.y) * m_GridDelta.y); + sph_min.z = (int)((-radius + p.z - m_GridMin.z) * m_GridDelta.z); + if ( sph_min.x < 0 ) sph_min.x = 0; + if ( sph_min.y < 0 ) sph_min.y = 0; + if ( sph_min.z < 0 ) sph_min.z = 0; + + m_GridCell[0] = (int)((sph_min.z * m_GridRes.y + sph_min.y) * m_GridRes.x + sph_min.x); + m_GridCell[1] = m_GridCell[0] + 1; + m_GridCell[2] = (int)(m_GridCell[0] + m_GridRes.x); + m_GridCell[3] = m_GridCell[2] + 1; + + if ( sph_min.z+1 < m_GridRes.z ) { + m_GridCell[4] = (int)(m_GridCell[0] + m_GridRes.y*m_GridRes.x); + m_GridCell[5] = m_GridCell[4] + 1; + m_GridCell[6] = (int)(m_GridCell[4] + m_GridRes.x); + m_GridCell[7] = m_GridCell[6] + 1; + } + if ( sph_min.x+1 >= m_GridRes.x ) { + m_GridCell[1] = -1; m_GridCell[3] = -1; + m_GridCell[5] = -1; m_GridCell[7] = -1; + } + if ( sph_min.y+1 >= m_GridRes.y ) { + m_GridCell[2] = -1; m_GridCell[3] = -1; + m_GridCell[6] = -1; m_GridCell[7] = -1; + } +} diff --git a/Extras/sph/common/point_set.h b/Extras/sph/common/point_set.h new file mode 100644 index 0000000..c9fe293 --- /dev/null +++ b/Extras/sph/common/point_set.h @@ -0,0 +1,165 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEF_POINT_SET + #define DEF_POINT_SET + + #include + #include + #include + #include + #include + + #include "common_defs.h" + #include "geomx.h" + #include "vector.h" + + typedef signed int xref; + + #define MAX_NEIGHBOR 80 + + #define MAX_PARAM 21 + + // Scalar params + #define PNT_DRAWMODE 0 + #define PNT_SPHERE 0 + #define PNT_POINT 1 + #define PNT_DRAWSIZE 1 + #define POINT_GRAV 2 + #define PLANE_GRAV 3 + + // Vector params + #define EMIT_POS 0 + #define EMIT_ANG 1 + #define EMIT_DANG 2 + #define EMIT_SPREAD 3 + #define EMIT_RATE 4 + #define POINT_GRAV_POS 5 + #define PLANE_GRAV_DIR 6 + + + #define BPOINT 0 + #define BPARTICLE 1 + + struct Point { + Vector3DF pos; + DWORD clr; + int next; + }; + + struct Particle { + Vector3DF pos; + DWORD clr; + int next; + Vector3DF vel; + Vector3DF vel_eval; + unsigned short age; + }; + + class PointSet : public GeomX { + public: + PointSet (); + + // Point Sets + + virtual void Initialize ( int mode, int max ); + virtual void Draw ( float* view_mat, float rad ); + virtual void Reset (); + virtual int AddPoint (); + virtual int AddPointReuse (); + Point* GetPoint ( int n ) { return (Point*) GetElem(0, n); } + int NumPoints () { return NumElem(0); } + + // Metablobs + virtual float GetValue ( float x, float y, float z ); + virtual Vector3DF GetGradient ( float x, float y, float z ); + // virtual float GetValue ( float x, float y, float z, Vector3DF& dir ); + virtual DWORD GetColor ( float x, float y, float z ); + + // Particle system + virtual void Run (); + virtual void Advance (); + virtual void Emit ( float spacing ); + + // Misc + virtual void AddVolume ( Vector3DF min, Vector3DF max, float spacing ); + + // Parameters + void SetParam (int p, float v ) { m_Param[p] = v; } + void SetParam (int p, int v ) { m_Param[p] = (float) v; } + float GetParam ( int p ) { return (float) m_Param[p]; } + Vector3DF GetVec ( int p ) { return m_Vec[p]; } + void SetVec ( int p, Vector3DF v ) { m_Vec[p] = v; } + void Toggle ( int p ) { m_Toggle[p] = !m_Toggle[p]; } + bool GetToggle ( int p ) { return m_Toggle[p]; } + + float GetDT() { return (float) m_DT; } + + // Spatial Subdivision + void Grid_Setup ( Vector3DF min, Vector3DF max, float sim_scale, float cell_size, float border ); + void Grid_Create (); + void Grid_InsertParticles (); + void Grid_Draw ( float* view_mat ); + void Grid_FindCells ( Vector3DF p, float radius ); + int Grid_FindCell ( Vector3DF p ); + Vector3DF GetGridRes () { return m_GridRes; } + Vector3DF GetGridMin () { return m_GridMin; } + Vector3DF GetGridMax () { return m_GridMax; } + Vector3DF GetGridDelta () { return m_GridDelta; } + int GetGridCell ( int x, int y, int z ); + Point* firstGridParticle ( int gc, int& p ); + Point* nextGridParticle ( int& p ); + unsigned short* getNeighborTable ( int n, int& cnt ); + + protected: + int m_Frame; + + // Parameters + double m_Param [ MAX_PARAM ]; // see defines above + Vector3DF m_Vec [ MAX_PARAM ]; + bool m_Toggle [ MAX_PARAM ]; + + // Particle System + double m_DT; + double m_Time; + + // Spatial Grid + std::vector< int > m_Grid; + std::vector< int > m_GridCnt; + int m_GridTotal; // total # cells + Vector3DF m_GridMin; // volume of grid (may not match domain volume exactly) + Vector3DF m_GridMax; + Vector3DF m_GridRes; // resolution in each axis + Vector3DF m_GridSize; // physical size in each axis + Vector3DF m_GridDelta; + float m_GridCellsize; + int m_GridCell[27]; + + // Neighbor Table + unsigned short m_NC[65536]; // neighbor table (600k) + unsigned short m_Neighbor[65536][MAX_NEIGHBOR]; + float m_NDist[65536][MAX_NEIGHBOR]; + + static int m_pcurr; + }; + +#endif diff --git a/Extras/sph/common/vector-inline.h b/Extras/sph/common/vector-inline.h new file mode 100644 index 0000000..9d5865d --- /dev/null +++ b/Extras/sph/common/vector-inline.h @@ -0,0 +1,782 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +// Vector Operations Implemented: +// =, +, -, *, / (on vectors and scalars) +// Cross Cross product vector with op +// Dot Dot product vector with op +// Dist (op) Distance from vector to op +// DistSq Distance^2 from vector to op +// Length () Length of vector +// Normalize () Normalizes vector +// + +#include "vector.h" + +// Vector2DC Code Definition + +#define VTYPE unsigned char +#define VNAME 2DC + +// Constructors/Destructors +inline Vector2DC::Vector2DC() {x=0; y=0;} +inline Vector2DC::~Vector2DC() {} +inline Vector2DC::Vector2DC (VTYPE xa, VTYPE ya) {x=xa; y=ya;} +inline Vector2DC::Vector2DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} + +// Member Functions +inline Vector2DC &Vector2DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} + +// Note: Cross product does not exist for 2D vectors (only 3D) + +inline double Vector2DC::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DC::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DC::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} + +inline double Vector2DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} + +inline Vector2DC &Vector2DC::Normalize (void) { + double n = (double) x*x + (double) y*y; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + } + return *this; +} +inline double Vector2DC::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector2DC::X(void) {return x;} +inline VTYPE &Vector2DC::Y(void) {return y;} +inline VTYPE Vector2DC::Z(void) {return 0;} +inline VTYPE Vector2DC::W(void) {return 0;} +inline const VTYPE &Vector2DC::X(void) const {return x;} +inline const VTYPE &Vector2DC::Y(void) const {return y;} +inline const VTYPE Vector2DC::Z(void) const {return 0;} +inline const VTYPE Vector2DC::W(void) const {return 0;} +inline VTYPE *Vector2DC::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector2DI Code Definition + +#define VNAME 2DI +#define VTYPE int + +// Constructors/Destructors +inline Vector2DI::Vector2DI() {x=0; y=0;} +inline Vector2DI::~Vector2DI() {} +inline Vector2DI::Vector2DI (VTYPE xa, VTYPE ya) {x=xa; y=ya;} +inline Vector2DI::Vector2DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} + +// Member Functions +inline Vector2DI &Vector2DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} + +// Note: Cross product does not exist for 2D vectors (only 3D) + +inline double Vector2DI::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DI::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DI::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} + +inline double Vector2DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} + +inline Vector2DI &Vector2DI::Normalize (void) { + double n = (double) x*x + (double) y*y; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + } + return *this; +} +inline double Vector2DI::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector2DI::X(void) {return x;} +inline VTYPE &Vector2DI::Y(void) {return y;} +inline VTYPE Vector2DI::Z(void) {return 0;} +inline VTYPE Vector2DI::W(void) {return 0;} +inline const VTYPE &Vector2DI::X(void) const {return x;} +inline const VTYPE &Vector2DI::Y(void) const {return y;} +inline const VTYPE Vector2DI::Z(void) const {return 0;} +inline const VTYPE Vector2DI::W(void) const {return 0;} +inline VTYPE *Vector2DI::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector2DF Code Definition + +#define VNAME 2DF +#define VTYPE double + +// Constructors/Destructors +inline Vector2DF::Vector2DF() {x=0; y=0;} +inline Vector2DF::~Vector2DF() {} +inline Vector2DF::Vector2DF (const VTYPE xa, const VTYPE ya) {x=xa; y=ya;} +inline Vector2DF::Vector2DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} + +// Member Functions +inline Vector2DF &Vector2DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} + +// Note: Cross product does not exist for 2D vectors (only 3D) + +inline double Vector2DF::Dot(const Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DF::Dot(const Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DF::Dot(const Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} + +inline double Vector2DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::DistSq (const Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} + +inline Vector2DF &Vector2DF::Normalize (void) { + double n = (double) x*x + (double) y*y; + if (n!=0.0) { + n = sqrt(n); + x /= n; + y /= n; + } + return *this; +} +inline double Vector2DF::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector2DF::X(void) {return x;} +inline VTYPE &Vector2DF::Y(void) {return y;} +inline VTYPE Vector2DF::Z(void) {return 0;} +inline VTYPE Vector2DF::W(void) {return 0;} +inline const VTYPE &Vector2DF::X(void) const {return x;} +inline const VTYPE &Vector2DF::Y(void) const {return y;} +inline const VTYPE Vector2DF::Z(void) const {return 0;} +inline const VTYPE Vector2DF::W(void) const {return 0;} +inline VTYPE *Vector2DF::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector3DC Code Definition + +#define VNAME 3DC +#define VTYPE unsigned char + +// Constructors/Destructors +inline Vector3DC::Vector3DC() {x=0; y=0; z=0;} +inline Vector3DC::~Vector3DC() {} +inline Vector3DC::Vector3DC (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;} +inline Vector3DC::Vector3DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DC::Vector3DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DC::Vector3DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DC::Vector3DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DC::Vector3DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DC::Vector3DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DC::Vector3DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} + +// Member Functions +inline Vector3DC &Vector3DC::Set (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za; return *this;} + +inline Vector3DC &Vector3DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DC &Vector3DC::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DC &Vector3DC::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} + +inline double Vector3DC::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DC::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DC::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} + +inline double Vector3DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} + +inline Vector3DC &Vector3DC::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + z = (VTYPE) (((double) z*255)/n); + } + return *this; +} +inline double Vector3DC::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector3DC::X(void) {return x;} +inline VTYPE &Vector3DC::Y(void) {return y;} +inline VTYPE &Vector3DC::Z(void) {return z;} +inline VTYPE Vector3DC::W(void) {return 0;} +inline const VTYPE &Vector3DC::X(void) const {return x;} +inline const VTYPE &Vector3DC::Y(void) const {return y;} +inline const VTYPE &Vector3DC::Z(void) const {return z;} +inline const VTYPE Vector3DC::W(void) const {return 0;} +inline VTYPE *Vector3DC::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector3DI Code Definition + +#define VNAME 3DI +#define VTYPE int + +// Constructors/Destructors +inline Vector3DI::Vector3DI() {x=0; y=0; z=0;} +inline Vector3DI::~Vector3DI() {} +inline Vector3DI::Vector3DI (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;} +inline Vector3DI::Vector3DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DI::Vector3DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DI::Vector3DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DI::Vector3DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DI::Vector3DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DI::Vector3DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DI::Vector3DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} + +// Set Functions +inline Vector3DI &Vector3DI::Set (const int xa, const int ya, const int za) +{ + x = xa; y = ya; z = za; + return *this; +} + +// Member Functions +inline Vector3DI &Vector3DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DI &Vector3DI::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DI &Vector3DI::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} + +inline double Vector3DI::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DI::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DI::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} + +inline double Vector3DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} + +inline Vector3DI &Vector3DI::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + z = (VTYPE) (((double) z*255)/n); + } + return *this; +} +inline double Vector3DI::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector3DI::X(void) {return x;} +inline VTYPE &Vector3DI::Y(void) {return y;} +inline VTYPE &Vector3DI::Z(void) {return z;} +inline VTYPE Vector3DI::W(void) {return 0;} +inline const VTYPE &Vector3DI::X(void) const {return x;} +inline const VTYPE &Vector3DI::Y(void) const {return y;} +inline const VTYPE &Vector3DI::Z(void) const {return z;} +inline const VTYPE Vector3DI::W(void) const {return 0;} +inline VTYPE *Vector3DI::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector3DF Code Definition + +#define VNAME 3DF +#define VTYPE double + +// Constructors/Destructors +inline Vector3DF::Vector3DF() {x=0; y=0; z=0;} +inline Vector3DF::~Vector3DF() {} +inline Vector3DF::Vector3DF (const VTYPE xa, const VTYPE ya, const VTYPE za) {x=xa; y=ya; z=za;} +inline Vector3DF::Vector3DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DF::Vector3DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DF::Vector3DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DF::Vector3DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DF::Vector3DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DF::Vector3DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DF::Vector3DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} + +// Set Functions +inline Vector3DF &Vector3DF::Set (const double xa, const double ya, const double za) +{ + x = xa; y = ya; z = za; + return *this; +} + +// Member Functions +inline Vector3DF &Vector3DF::operator= (const int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator= (const double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator+= (const int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator+= (const double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator-= (const int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator-= (const double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator*= (const int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator*= (const double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator/= (const int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator/= (const double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::Cross (const Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DF &Vector3DF::Cross (const Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DF &Vector3DF::Cross (const Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} + +inline double Vector3DF::Dot(const Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DF::Dot(const Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DF::Dot(const Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} + +inline double Vector3DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::DistSq (const Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} + +inline Vector3DF &Vector3DF::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z; + if (n!=0.0) { + n = sqrt(n); + x /= n; y /= n; z /= n; + } + return *this; +} +inline double Vector3DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector3DF::X() {return x;} +inline VTYPE &Vector3DF::Y() {return y;} +inline VTYPE &Vector3DF::Z() {return z;} +inline VTYPE Vector3DF::W() {return 0;} +inline const VTYPE &Vector3DF::X() const {return x;} +inline const VTYPE &Vector3DF::Y() const {return y;} +inline const VTYPE &Vector3DF::Z() const {return z;} +inline const VTYPE Vector3DF::W() const {return 0;} +inline VTYPE *Vector3DF::Data () {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector4DF Code Definition + +#define VNAME 4DF +#define VTYPE double + +// Constructors/Destructors +inline Vector4DF::Vector4DF() {x=0; y=0; z=0; w=0;} +inline Vector4DF::~Vector4DF() {} +inline Vector4DF::Vector4DF (VTYPE xa, VTYPE ya, VTYPE za, VTYPE wa) {x=xa; y=ya; z=za; w=wa;} +inline Vector4DF::Vector4DF (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w;} + +// Member Functions +inline Vector4DF &Vector4DF::operator= (int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator= (double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator+= (int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator+= (double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; w+=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator-= (int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator-= (double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; w-=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator*= (int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator*= (double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; w*=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator/= (int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator/= (double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; w/=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::Cross (Vector4DF &v) {double ax = x, ay = y, az = z, aw = w; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); w = (VTYPE) 0; return *this;} + +inline double Vector4DF::Dot(Vector4DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z + (double) w*v.w; return dot;} + +inline double Vector4DF::Dist (Vector4DF &v) {double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} + +inline double Vector4DF::DistSq (Vector4DF &v) {double a,b,c,d; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; d = (double) w - (double) v.w; return (a*a + b*b + c*c + d*d);} + +inline Vector4DF &Vector4DF::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z + (double) w*w; + if (n!=0.0) { + n = sqrt(n); + x /= n; y /= n; z /= n; w /= n; + } + return *this; +} +inline double Vector4DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z + (double) w*w; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector4DF::X(void) {return x;} +inline VTYPE &Vector4DF::Y(void) {return y;} +inline VTYPE &Vector4DF::Z(void) {return z;} +inline VTYPE &Vector4DF::W(void) {return w;} +inline const VTYPE &Vector4DF::X(void) const {return x;} +inline const VTYPE &Vector4DF::Y(void) const {return y;} +inline const VTYPE &Vector4DF::Z(void) const {return z;} +inline const VTYPE &Vector4DF::W(void) const {return w;} +inline VTYPE *Vector4DF::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME diff --git a/Extras/sph/common/vector.cci b/Extras/sph/common/vector.cci new file mode 100644 index 0000000..2a548f3 --- /dev/null +++ b/Extras/sph/common/vector.cci @@ -0,0 +1,761 @@ +// Vector Operations Implemented: +// =, +, -, *, / (on vectors and scalars) +// Cross Cross product vector with op +// Dot Dot product vector with op +// Dist (op) Distance from vector to op +// DistSq Distance^2 from vector to op +// Length () Length of vector +// Normalize () Normalizes vector +// + +#include + +// Vector2DC Code Definition + +#define VTYPE unsigned char +#define VNAME 2DC + +// Constructors/Destructors +inline Vector2DC::Vector2DC() {x=0; y=0;} +inline Vector2DC::~Vector2DC() {} +inline Vector2DC::Vector2DC (VTYPE xa, VTYPE ya) {x=xa; y=ya;} +inline Vector2DC::Vector2DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DC::Vector2DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} + +// Member Functions +inline Vector2DC &Vector2DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} + +inline Vector2DC &Vector2DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DC &Vector2DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} + +// Note: Cross product does not exist for 2D vectors (only 3D) + +inline double Vector2DC::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DC::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DC::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} + +inline double Vector2DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DC::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DC::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} + +inline Vector2DC &Vector2DC::Normalize (void) { + double n = (double) x*x + (double) y*y; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + } + return *this; +} +inline double Vector2DC::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector2DC::X(void) {return x;} +inline VTYPE &Vector2DC::Y(void) {return y;} +inline VTYPE Vector2DC::Z(void) {return 0;} +inline VTYPE Vector2DC::W(void) {return 0;} +inline const VTYPE &Vector2DC::X(void) const {return x;} +inline const VTYPE &Vector2DC::Y(void) const {return y;} +inline const VTYPE Vector2DC::Z(void) const {return 0;} +inline const VTYPE Vector2DC::W(void) const {return 0;} +inline VTYPE *Vector2DC::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector2DI Code Definition + +#define VNAME 2DI +#define VTYPE int + +// Constructors/Destructors +inline Vector2DI::Vector2DI() {x=0; y=0;} +inline Vector2DI::~Vector2DI() {} +inline Vector2DI::Vector2DI (VTYPE xa, VTYPE ya) {x=xa; y=ya;} +inline Vector2DI::Vector2DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DI::Vector2DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} + +// Member Functions +inline Vector2DI &Vector2DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} + +inline Vector2DI &Vector2DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DI &Vector2DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} + +// Note: Cross product does not exist for 2D vectors (only 3D) + +inline double Vector2DI::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DI::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DI::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} + +inline double Vector2DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DI::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DI::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} + +inline Vector2DI &Vector2DI::Normalize (void) { + double n = (double) x*x + (double) y*y; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + } + return *this; +} +inline double Vector2DI::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector2DI::X(void) {return x;} +inline VTYPE &Vector2DI::Y(void) {return y;} +inline VTYPE Vector2DI::Z(void) {return 0;} +inline VTYPE Vector2DI::W(void) {return 0;} +inline const VTYPE &Vector2DI::X(void) const {return x;} +inline const VTYPE &Vector2DI::Y(void) const {return y;} +inline const VTYPE Vector2DI::Z(void) const {return 0;} +inline const VTYPE Vector2DI::W(void) const {return 0;} +inline VTYPE *Vector2DI::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector2DF Code Definition + +#define VNAME 2DF +#define VTYPE double + +// Constructors/Destructors +inline Vector2DF::Vector2DF() {x=0; y=0;} +inline Vector2DF::~Vector2DF() {} +inline Vector2DF::Vector2DF (const VTYPE xa, const VTYPE ya) {x=xa; y=ya;} +inline Vector2DF::Vector2DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} +inline Vector2DF::Vector2DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;} + +// Member Functions +inline Vector2DF &Vector2DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} + +inline Vector2DF &Vector2DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector2DF &Vector2DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} + +// Note: Cross product does not exist for 2D vectors (only 3D) + +inline double Vector2DF::Dot(const Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DF::Dot(const Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} +inline double Vector2DF::Dot(const Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;} + +inline double Vector2DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector2DF::DistSq (const Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} +inline double Vector2DF::DistSq (const Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);} + +inline Vector2DF &Vector2DF::Normalize (void) { + double n = (double) x*x + (double) y*y; + if (n!=0.0) { + n = sqrt(n); + x /= n; + y /= n; + } + return *this; +} +inline double Vector2DF::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector2DF::X(void) {return x;} +inline VTYPE &Vector2DF::Y(void) {return y;} +inline VTYPE Vector2DF::Z(void) {return 0;} +inline VTYPE Vector2DF::W(void) {return 0;} +inline const VTYPE &Vector2DF::X(void) const {return x;} +inline const VTYPE &Vector2DF::Y(void) const {return y;} +inline const VTYPE Vector2DF::Z(void) const {return 0;} +inline const VTYPE Vector2DF::W(void) const {return 0;} +inline VTYPE *Vector2DF::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector3DC Code Definition + +#define VNAME 3DC +#define VTYPE unsigned char + +// Constructors/Destructors +inline Vector3DC::Vector3DC() {x=0; y=0; z=0;} +inline Vector3DC::~Vector3DC() {} +inline Vector3DC::Vector3DC (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;} +inline Vector3DC::Vector3DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DC::Vector3DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DC::Vector3DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DC::Vector3DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DC::Vector3DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DC::Vector3DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DC::Vector3DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} + +// Member Functions +inline Vector3DC &Vector3DC::Set (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za; return *this;} + +inline Vector3DC &Vector3DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DC &Vector3DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} + +inline Vector3DC &Vector3DC::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DC &Vector3DC::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DC &Vector3DC::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} + +inline double Vector3DC::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DC::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DC::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} + +inline double Vector3DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DC::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DC::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} + +inline Vector3DC &Vector3DC::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + z = (VTYPE) (((double) z*255)/n); + } + return *this; +} +inline double Vector3DC::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector3DC::X(void) {return x;} +inline VTYPE &Vector3DC::Y(void) {return y;} +inline VTYPE &Vector3DC::Z(void) {return z;} +inline VTYPE Vector3DC::W(void) {return 0;} +inline const VTYPE &Vector3DC::X(void) const {return x;} +inline const VTYPE &Vector3DC::Y(void) const {return y;} +inline const VTYPE &Vector3DC::Z(void) const {return z;} +inline const VTYPE Vector3DC::W(void) const {return 0;} +inline VTYPE *Vector3DC::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector3DI Code Definition + +#define VNAME 3DI +#define VTYPE int + +// Constructors/Destructors +inline Vector3DI::Vector3DI() {x=0; y=0; z=0;} +inline Vector3DI::~Vector3DI() {} +inline Vector3DI::Vector3DI (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;} +inline Vector3DI::Vector3DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DI::Vector3DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DI::Vector3DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DI::Vector3DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DI::Vector3DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DI::Vector3DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DI::Vector3DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} + +// Set Functions +inline Vector3DI &Vector3DI::Set (const int xa, const int ya, const int za) +{ + x = xa; y = ya; z = za; + return *this; +} + +// Member Functions +inline Vector3DI &Vector3DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DI &Vector3DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} + +inline Vector3DI &Vector3DI::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DI &Vector3DI::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DI &Vector3DI::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} + +inline double Vector3DI::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DI::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DI::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} + +inline double Vector3DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DI::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DI::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} + +inline Vector3DI &Vector3DI::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z; + if (n!=0.0) { + n = sqrt(n); + x = (VTYPE) (((double) x*255)/n); + y = (VTYPE) (((double) y*255)/n); + z = (VTYPE) (((double) z*255)/n); + } + return *this; +} +inline double Vector3DI::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector3DI::X(void) {return x;} +inline VTYPE &Vector3DI::Y(void) {return y;} +inline VTYPE &Vector3DI::Z(void) {return z;} +inline VTYPE Vector3DI::W(void) {return 0;} +inline const VTYPE &Vector3DI::X(void) const {return x;} +inline const VTYPE &Vector3DI::Y(void) const {return y;} +inline const VTYPE &Vector3DI::Z(void) const {return z;} +inline const VTYPE Vector3DI::W(void) const {return 0;} +inline VTYPE *Vector3DI::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector3DF Code Definition + +#define VNAME 3DF +#define VTYPE float + +// Constructors/Destructors +inline Vector3DF::Vector3DF() {x=0; y=0; z=0;} +inline Vector3DF::~Vector3DF() {} +inline Vector3DF::Vector3DF (const VTYPE xa, const VTYPE ya, const VTYPE za) {x=xa; y=ya; z=za;} +inline Vector3DF::Vector3DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DF::Vector3DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DF::Vector3DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;} +inline Vector3DF::Vector3DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DF::Vector3DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DF::Vector3DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} +inline Vector3DF::Vector3DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;} + +// Set Functions +inline Vector3DF &Vector3DF::Set (const double xa, const double ya, const double za) +{ + x = (float) xa; y = (float) ya; z = (float) za; + return *this; +} + +// Member Functions +inline Vector3DF &Vector3DF::operator= (const int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator= (const double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator+= (const int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator+= (const double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator-= (const int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator-= (const double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator*= (const int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator*= (const double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::operator/= (const int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator/= (const double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector3DF &Vector3DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} + +inline Vector3DF &Vector3DF::Cross (const Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DF &Vector3DF::Cross (const Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} +inline Vector3DF &Vector3DF::Cross (const Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;} + +inline double Vector3DF::Dot(const Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DF::Dot(const Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} +inline double Vector3DF::Dot(const Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;} + +inline double Vector3DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} +inline double Vector3DF::DistSq (const Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} +inline double Vector3DF::DistSq (const Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);} + +inline Vector3DF &Vector3DF::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z; + if (n!=0.0) { + n = sqrt(n); + x /= (float) n; y /= (float) n; z /= (float) n; + } + return *this; +} +inline double Vector3DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector3DF::X() {return x;} +inline VTYPE &Vector3DF::Y() {return y;} +inline VTYPE &Vector3DF::Z() {return z;} +inline VTYPE Vector3DF::W() {return 0;} +inline const VTYPE &Vector3DF::X() const {return x;} +inline const VTYPE &Vector3DF::Y() const {return y;} +inline const VTYPE &Vector3DF::Z() const {return z;} +inline const VTYPE Vector3DF::W() const {return 0;} +inline VTYPE *Vector3DF::Data () {return &x;} + +#undef VTYPE +#undef VNAME + +// Vector4DF Code Definition + +#define VNAME 4DF +#define VTYPE double + +// Constructors/Destructors +inline Vector4DF::Vector4DF() {x=0; y=0; z=0; w=0;} +inline Vector4DF::~Vector4DF() {} +inline Vector4DF::Vector4DF (VTYPE xa, VTYPE ya, VTYPE za, VTYPE wa) {x=xa; y=ya; z=za; w=wa;} +inline Vector4DF::Vector4DF (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;} +inline Vector4DF::Vector4DF (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w;} + +// Member Functions +inline Vector4DF &Vector4DF::operator= (int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator= (double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;} +inline Vector4DF &Vector4DF::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator+= (int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator+= (double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; w+=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator-= (int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator-= (double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; w-=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator*= (int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator*= (double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; w*=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::operator/= (int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator/= (double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;} +inline Vector4DF &Vector4DF::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; w/=(VTYPE) op.w; return *this;} + +inline Vector4DF &Vector4DF::Cross (Vector4DF &v) {double ax = x, ay = y, az = z, aw = w; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); w = (VTYPE) 0; return *this;} + +inline double Vector4DF::Dot(Vector4DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z + (double) w*v.w; return dot;} + +inline double Vector4DF::Dist (Vector4DF &v) {double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;} + +inline double Vector4DF::DistSq (Vector4DF &v) {double a,b,c,d; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; d = (double) w - (double) v.w; return (a*a + b*b + c*c + d*d);} + +inline Vector4DF &Vector4DF::Normalize (void) { + double n = (double) x*x + (double) y*y + (double) z*z + (double) w*w; + if (n!=0.0) { + n = sqrt(n); + x /= n; y /= n; z /= n; w /= n; + } + return *this; +} +inline double Vector4DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z + (double) w*w; if (n != 0.0) return sqrt(n); return 0.0; } + +inline VTYPE &Vector4DF::X(void) {return x;} +inline VTYPE &Vector4DF::Y(void) {return y;} +inline VTYPE &Vector4DF::Z(void) {return z;} +inline VTYPE &Vector4DF::W(void) {return w;} +inline const VTYPE &Vector4DF::X(void) const {return x;} +inline const VTYPE &Vector4DF::Y(void) const {return y;} +inline const VTYPE &Vector4DF::Z(void) const {return z;} +inline const VTYPE &Vector4DF::W(void) const {return w;} +inline VTYPE *Vector4DF::Data (void) {return &x;} + +#undef VTYPE +#undef VNAME diff --git a/Extras/sph/common/vector.cpp b/Extras/sph/common/vector.cpp new file mode 100644 index 0000000..4cfc7b9 --- /dev/null +++ b/Extras/sph/common/vector.cpp @@ -0,0 +1,70 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "vector.h" +#include "matrix.h" + +Vector3DF &Vector3DF::operator*= (const MatrixF &op) +{ + double *m = op.GetDataF (); + double xa, ya, za; + xa = x * (*m++); ya = x * (*m++); za = x * (*m++); m++; + xa += y * (*m++); ya += y * (*m++); za += y * (*m++); m++; + xa += z * (*m++); ya += z * (*m++); za += z * (*m++); m++; + xa += (*m++); ya += (*m++); za += (*m++); + x = (float) xa; y = (float) ya; z = (float) za; + return *this; +} + +Vector3DF &Vector3DF::operator*= (const Matrix4F &op) +{ + float xa, ya, za; + xa = x * op.data[0] + y * op.data[4] + z * op.data[8] + op.data[12]; + ya = x * op.data[1] + y * op.data[5] + z * op.data[9] + op.data[13]; + za = x * op.data[2] + y * op.data[6] + z * op.data[10] + op.data[14]; + x = xa; y = ya; z = za; + return *this; +} + +Vector4DF &Vector4DF::operator*= (const MatrixF &op) +{ + double *m = op.GetDataF (); + double xa, ya, za, wa; + xa = x * (*m++); ya = x * (*m++); za = x * (*m++); wa = x * (*m++); + xa += y * (*m++); ya += y * (*m++); za += y * (*m++); wa += y * (*m++); + xa += z * (*m++); ya += z * (*m++); za += z * (*m++); wa += z * (*m++); + xa += w * (*m++); ya += w * (*m++); za += w * (*m++); wa += w * (*m++); + x = xa; y = ya; z = za; w = wa; + return *this; +} + +Vector4DF &Vector4DF::operator*= (const Matrix4F &op) +{ + double xa, ya, za, wa; + xa = x * op.data[0] + y * op.data[4] + z * op.data[8] + w * op.data[12]; + ya = x * op.data[1] + y * op.data[5] + z * op.data[9] + w * op.data[13]; + za = x * op.data[2] + y * op.data[6] + z * op.data[10] + w * op.data[14]; + wa = x * op.data[3] + y * op.data[7] + z * op.data[11] + w * op.data[15]; + x = xa; y = ya; z = za; w = wa; + return *this; +} + diff --git a/Extras/sph/common/vector.h b/Extras/sph/common/vector.h new file mode 100644 index 0000000..2c8c0bf --- /dev/null +++ b/Extras/sph/common/vector.h @@ -0,0 +1,785 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +// ** NOTES ** +// Vector code CANNOT be inlined in header file because of dependencies +// across vector classes (error generated: "Use of undeclared class..") +// +#include +#include +#include +#include +#include + +#ifndef VECTOR_DEF + #define VECTOR_DEF + + //#define VECTOR_INITIALIZE // Initializes vectors + + class Vector2DC; // Forward Referencing + class Vector2DI; + class Vector2DF; + class Vector3DC; + class Vector3DI; + class Vector3DF; + class Vector4DF; + class MatrixF; + class Matrix4F; + + // Vector2DC Declaration + + #define VNAME 2DC + #define VTYPE unsigned char + + class Vector2DC { + public: + VTYPE x, y; + + // Constructors/Destructors + inline Vector2DC(); + inline ~Vector2DC(); + inline Vector2DC (VTYPE xa, VTYPE ya); + inline Vector2DC (Vector2DC &op); + inline Vector2DC (Vector2DI &op); + inline Vector2DC (Vector2DF &op); + inline Vector2DC (Vector3DC &op); + inline Vector2DC (Vector3DI &op); + inline Vector2DC (Vector3DF &op); + inline Vector2DC (Vector4DF &op); + + // Member Functions + inline Vector2DC &operator= (Vector2DC &op); + inline Vector2DC &operator= (Vector2DI &op); + inline Vector2DC &operator= (Vector2DF &op); + inline Vector2DC &operator= (Vector3DC &op); + inline Vector2DC &operator= (Vector3DI &op); + inline Vector2DC &operator= (Vector3DF &op); + inline Vector2DC &operator= (Vector4DF &op); + + inline Vector2DC &operator+= (Vector2DC &op); + inline Vector2DC &operator+= (Vector2DI &op); + inline Vector2DC &operator+= (Vector2DF &op); + inline Vector2DC &operator+= (Vector3DC &op); + inline Vector2DC &operator+= (Vector3DI &op); + inline Vector2DC &operator+= (Vector3DF &op); + inline Vector2DC &operator+= (Vector4DF &op); + + inline Vector2DC &operator-= (Vector2DC &op); + inline Vector2DC &operator-= (Vector2DI &op); + inline Vector2DC &operator-= (Vector2DF &op); + inline Vector2DC &operator-= (Vector3DC &op); + inline Vector2DC &operator-= (Vector3DI &op); + inline Vector2DC &operator-= (Vector3DF &op); + inline Vector2DC &operator-= (Vector4DF &op); + + inline Vector2DC &operator*= (Vector2DC &op); + inline Vector2DC &operator*= (Vector2DI &op); + inline Vector2DC &operator*= (Vector2DF &op); + inline Vector2DC &operator*= (Vector3DC &op); + inline Vector2DC &operator*= (Vector3DI &op); + inline Vector2DC &operator*= (Vector3DF &op); + inline Vector2DC &operator*= (Vector4DF &op); + + inline Vector2DC &operator/= (Vector2DC &op); + inline Vector2DC &operator/= (Vector2DI &op); + inline Vector2DC &operator/= (Vector2DF &op); + inline Vector2DC &operator/= (Vector3DC &op); + inline Vector2DC &operator/= (Vector3DI &op); + inline Vector2DC &operator/= (Vector3DF &op); + inline Vector2DC &operator/= (Vector4DF &op); + + // Note: Cross product does not exist for 2D vectors (only 3D) + + inline double Dot(Vector2DC &v); + inline double Dot(Vector2DI &v); + inline double Dot(Vector2DF &v); + + inline double Dist (Vector2DC &v); + inline double Dist (Vector2DI &v); + inline double Dist (Vector2DF &v); + inline double Dist (Vector3DC &v); + inline double Dist (Vector3DI &v); + inline double Dist (Vector3DF &v); + inline double Dist (Vector4DF &v); + + inline double DistSq (Vector2DC &v); + inline double DistSq (Vector2DI &v); + inline double DistSq (Vector2DF &v); + inline double DistSq (Vector3DC &v); + inline double DistSq (Vector3DI &v); + inline double DistSq (Vector3DF &v); + inline double DistSq (Vector4DF &v); + + inline Vector2DC &Normalize (void); + inline double Length (void); + + inline VTYPE &X(void); + inline VTYPE &Y(void); + inline VTYPE Z(void); + inline VTYPE W(void); + inline const VTYPE &X(void) const; + inline const VTYPE &Y(void) const; + inline const VTYPE Z(void) const; + inline const VTYPE W(void) const; + inline VTYPE *Data (void); + }; + + #undef VNAME + #undef VTYPE + + // Vector2DI Declaration + + #define VNAME 2DI + #define VTYPE int + + class Vector2DI { + public: + VTYPE x, y; + + // Constructors/Destructors + inline Vector2DI(); + inline ~Vector2DI(); + inline Vector2DI (VTYPE xa, VTYPE ya); + inline Vector2DI (Vector2DC &op); + inline Vector2DI (Vector2DI &op); + inline Vector2DI (Vector2DF &op); + inline Vector2DI (Vector3DC &op); + inline Vector2DI (Vector3DI &op); + inline Vector2DI (Vector3DF &op); + inline Vector2DI (Vector4DF &op); + + // Member Functions + inline Vector2DI &operator= (Vector2DC &op); + inline Vector2DI &operator= (Vector2DI &op); + inline Vector2DI &operator= (Vector2DF &op); + inline Vector2DI &operator= (Vector3DC &op); + inline Vector2DI &operator= (Vector3DI &op); + inline Vector2DI &operator= (Vector3DF &op); + inline Vector2DI &operator= (Vector4DF &op); + + inline Vector2DI &operator+= (Vector2DC &op); + inline Vector2DI &operator+= (Vector2DI &op); + inline Vector2DI &operator+= (Vector2DF &op); + inline Vector2DI &operator+= (Vector3DC &op); + inline Vector2DI &operator+= (Vector3DI &op); + inline Vector2DI &operator+= (Vector3DF &op); + inline Vector2DI &operator+= (Vector4DF &op); + + inline Vector2DI &operator-= (Vector2DC &op); + inline Vector2DI &operator-= (Vector2DI &op); + inline Vector2DI &operator-= (Vector2DF &op); + inline Vector2DI &operator-= (Vector3DC &op); + inline Vector2DI &operator-= (Vector3DI &op); + inline Vector2DI &operator-= (Vector3DF &op); + inline Vector2DI &operator-= (Vector4DF &op); + + inline Vector2DI &operator*= (Vector2DC &op); + inline Vector2DI &operator*= (Vector2DI &op); + inline Vector2DI &operator*= (Vector2DF &op); + inline Vector2DI &operator*= (Vector3DC &op); + inline Vector2DI &operator*= (Vector3DI &op); + inline Vector2DI &operator*= (Vector3DF &op); + inline Vector2DI &operator*= (Vector4DF &op); + + inline Vector2DI &operator/= (Vector2DC &op); + inline Vector2DI &operator/= (Vector2DI &op); + inline Vector2DI &operator/= (Vector2DF &op); + inline Vector2DI &operator/= (Vector3DC &op); + inline Vector2DI &operator/= (Vector3DI &op); + inline Vector2DI &operator/= (Vector3DF &op); + inline Vector2DI &operator/= (Vector4DF &op); + + + // Note: Cross product does not exist for 2D vectors (only 3D) + + inline double Dot(Vector2DC &v); + inline double Dot(Vector2DI &v); + inline double Dot(Vector2DF &v); + + inline double Dist (Vector2DC &v); + inline double Dist (Vector2DI &v); + inline double Dist (Vector2DF &v); + inline double Dist (Vector3DC &v); + inline double Dist (Vector3DI &v); + inline double Dist (Vector3DF &v); + inline double Dist (Vector4DF &v); + + inline double DistSq (Vector2DC &v); + inline double DistSq (Vector2DI &v); + inline double DistSq (Vector2DF &v); + inline double DistSq (Vector3DC &v); + inline double DistSq (Vector3DI &v); + inline double DistSq (Vector3DF &v); + inline double DistSq (Vector4DF &v); + + inline Vector2DI &Normalize (void); + inline double Length (void); + + inline VTYPE &X(void); + inline VTYPE &Y(void); + inline VTYPE Z(void); + inline VTYPE W(void); + inline const VTYPE &X(void) const; + inline const VTYPE &Y(void) const; + inline const VTYPE Z(void) const; + inline const VTYPE W(void) const; + inline VTYPE *Data (void); + }; + + #undef VNAME + #undef VTYPE + + // Vector2DF Declarations + + #define VNAME 2DF + #define VTYPE double + + class Vector2DF { + public: + VTYPE x, y; + + // Constructors/Destructors + Vector2DF (); + ~Vector2DF (); + Vector2DF (const VTYPE xa, const VTYPE ya); + Vector2DF (const Vector2DC &op); + Vector2DF (const Vector2DI &op); + Vector2DF (const Vector2DF &op); + Vector2DF (const Vector3DC &op); + Vector2DF (const Vector3DI &op); + Vector2DF (const Vector3DF &op); + Vector2DF (const Vector4DF &op); + + // Member Functions + Vector2DF &operator= (const Vector2DC &op); + Vector2DF &operator= (const Vector2DI &op); + Vector2DF &operator= (const Vector2DF &op); + Vector2DF &operator= (const Vector3DC &op); + Vector2DF &operator= (const Vector3DI &op); + Vector2DF &operator= (const Vector3DF &op); + Vector2DF &operator= (const Vector4DF &op); + + Vector2DF &operator+= (const Vector2DC &op); + Vector2DF &operator+= (const Vector2DI &op); + Vector2DF &operator+= (const Vector2DF &op); + Vector2DF &operator+= (const Vector3DC &op); + Vector2DF &operator+= (const Vector3DI &op); + Vector2DF &operator+= (const Vector3DF &op); + Vector2DF &operator+= (const Vector4DF &op); + + Vector2DF &operator-= (const Vector2DC &op); + Vector2DF &operator-= (const Vector2DI &op); + Vector2DF &operator-= (const Vector2DF &op); + Vector2DF &operator-= (const Vector3DC &op); + Vector2DF &operator-= (const Vector3DI &op); + Vector2DF &operator-= (const Vector3DF &op); + Vector2DF &operator-= (const Vector4DF &op); + + Vector2DF &operator*= (const Vector2DC &op); + Vector2DF &operator*= (const Vector2DI &op); + Vector2DF &operator*= (const Vector2DF &op); + Vector2DF &operator*= (const Vector3DC &op); + Vector2DF &operator*= (const Vector3DI &op); + Vector2DF &operator*= (const Vector3DF &op); + Vector2DF &operator*= (const Vector4DF &op); + + Vector2DF &operator/= (const Vector2DC &op); + Vector2DF &operator/= (const Vector2DI &op); + Vector2DF &operator/= (const Vector2DF &op); + Vector2DF &operator/= (const Vector3DC &op); + Vector2DF &operator/= (const Vector3DI &op); + Vector2DF &operator/= (const Vector3DF &op); + Vector2DF &operator/= (const Vector4DF &op); + + Vector2DF &operator/= (const double v) {x /= v; y /= v; return *this;} + + // Note: Cross product does not exist for 2D vectors (only 3D) + + double Dot(const Vector2DC &v); + double Dot(const Vector2DI &v); + double Dot(const Vector2DF &v); + + double Dist (const Vector2DC &v); + double Dist (const Vector2DI &v); + double Dist (const Vector2DF &v); + double Dist (const Vector3DC &v); + double Dist (const Vector3DI &v); + double Dist (const Vector3DF &v); + double Dist (const Vector4DF &v); + + double DistSq (const Vector2DC &v); + double DistSq (const Vector2DI &v); + double DistSq (const Vector2DF &v); + double DistSq (const Vector3DC &v); + double DistSq (const Vector3DI &v); + double DistSq (const Vector3DF &v); + double DistSq (const Vector4DF &v); + + Vector2DF &Normalize (void); + double Length (void); + + VTYPE &X(void); + VTYPE &Y(void); + VTYPE Z(void); + VTYPE W(void); + const VTYPE &X(void) const; + const VTYPE &Y(void) const; + const VTYPE Z(void) const; + const VTYPE W(void) const; + VTYPE *Data (void); + }; + + #undef VNAME + #undef VTYPE + + // Vector3DC Declaration + + #define VNAME 3DC + #define VTYPE unsigned char + + class Vector3DC { + public: + VTYPE x, y, z; + + // Constructors/Destructors + inline Vector3DC(); + inline ~Vector3DC(); + inline Vector3DC (VTYPE xa, VTYPE ya, VTYPE za); + inline Vector3DC (Vector2DC &op); + inline Vector3DC (Vector2DI &op); + inline Vector3DC (Vector2DF &op); + inline Vector3DC (Vector3DC &op); + inline Vector3DC (Vector3DI &op); + inline Vector3DC (Vector3DF &op); + inline Vector3DC (Vector4DF &op); + + // Member Functions + inline Vector3DC &Set (VTYPE xa, VTYPE ya, VTYPE za); + + inline Vector3DC &operator= (Vector2DC &op); + inline Vector3DC &operator= (Vector2DI &op); + inline Vector3DC &operator= (Vector2DF &op); + inline Vector3DC &operator= (Vector3DC &op); + inline Vector3DC &operator= (Vector3DI &op); + inline Vector3DC &operator= (Vector3DF &op); + inline Vector3DC &operator= (Vector4DF &op); + + inline Vector3DC &operator+= (Vector2DC &op); + inline Vector3DC &operator+= (Vector2DI &op); + inline Vector3DC &operator+= (Vector2DF &op); + inline Vector3DC &operator+= (Vector3DC &op); + inline Vector3DC &operator+= (Vector3DI &op); + inline Vector3DC &operator+= (Vector3DF &op); + inline Vector3DC &operator+= (Vector4DF &op); + + inline Vector3DC &operator-= (Vector2DC &op); + inline Vector3DC &operator-= (Vector2DI &op); + inline Vector3DC &operator-= (Vector2DF &op); + inline Vector3DC &operator-= (Vector3DC &op); + inline Vector3DC &operator-= (Vector3DI &op); + inline Vector3DC &operator-= (Vector3DF &op); + inline Vector3DC &operator-= (Vector4DF &op); + + inline Vector3DC &operator*= (Vector2DC &op); + inline Vector3DC &operator*= (Vector2DI &op); + inline Vector3DC &operator*= (Vector2DF &op); + inline Vector3DC &operator*= (Vector3DC &op); + inline Vector3DC &operator*= (Vector3DI &op); + inline Vector3DC &operator*= (Vector3DF &op); + inline Vector3DC &operator*= (Vector4DF &op); + + inline Vector3DC &operator/= (Vector2DC &op); + inline Vector3DC &operator/= (Vector2DI &op); + inline Vector3DC &operator/= (Vector2DF &op); + inline Vector3DC &operator/= (Vector3DC &op); + inline Vector3DC &operator/= (Vector3DI &op); + inline Vector3DC &operator/= (Vector3DF &op); + inline Vector3DC &operator/= (Vector4DF &op); + + inline Vector3DC &Cross (Vector3DC &v); + inline Vector3DC &Cross (Vector3DI &v); + inline Vector3DC &Cross (Vector3DF &v); + + inline double Dot(Vector3DC &v); + inline double Dot(Vector3DI &v); + inline double Dot(Vector3DF &v); + + inline double Dist (Vector2DC &v); + inline double Dist (Vector2DI &v); + inline double Dist (Vector2DF &v); + inline double Dist (Vector3DC &v); + inline double Dist (Vector3DI &v); + inline double Dist (Vector3DF &v); + inline double Dist (Vector4DF &v); + + inline double DistSq (Vector2DC &v); + inline double DistSq (Vector2DI &v); + inline double DistSq (Vector2DF &v); + inline double DistSq (Vector3DC &v); + inline double DistSq (Vector3DI &v); + inline double DistSq (Vector3DF &v); + inline double DistSq (Vector4DF &v); + + inline Vector3DC &Normalize (void); + inline double Length (void); + + inline VTYPE &X(void); + inline VTYPE &Y(void); + inline VTYPE &Z(void); + inline VTYPE W(void); + inline const VTYPE &X(void) const; + inline const VTYPE &Y(void) const; + inline const VTYPE &Z(void) const; + inline const VTYPE W(void) const; + inline VTYPE *Data (void); + }; + + #undef VNAME + #undef VTYPE + + // Vector3DI Declaration + + #define VNAME 3DI + #define VTYPE int + + class Vector3DI { + public: + VTYPE x, y, z; + + // Constructors/Destructors + inline Vector3DI(); + inline ~Vector3DI(); + inline Vector3DI (VTYPE xa, VTYPE ya, VTYPE za); + inline Vector3DI (Vector2DC &op); + inline Vector3DI (Vector2DI &op); + inline Vector3DI (Vector2DF &op); + inline Vector3DI (Vector3DC &op); + inline Vector3DI (Vector3DI &op); + inline Vector3DI (Vector3DF &op); + inline Vector3DI (Vector4DF &op); + + // Set Functions + inline Vector3DI &Set (const int xa, const int ya, const int za); + + // Member Functions + inline Vector3DI &operator= (Vector2DC &op); + inline Vector3DI &operator= (Vector2DI &op); + inline Vector3DI &operator= (Vector2DF &op); + inline Vector3DI &operator= (Vector3DC &op); + inline Vector3DI &operator= (Vector3DI &op); + inline Vector3DI &operator= (Vector3DF &op); + inline Vector3DI &operator= (Vector4DF &op); + + inline Vector3DI &operator+= (Vector2DC &op); + inline Vector3DI &operator+= (Vector2DI &op); + inline Vector3DI &operator+= (Vector2DF &op); + inline Vector3DI &operator+= (Vector3DC &op); + inline Vector3DI &operator+= (Vector3DI &op); + inline Vector3DI &operator+= (Vector3DF &op); + inline Vector3DI &operator+= (Vector4DF &op); + + inline Vector3DI &operator-= (Vector2DC &op); + inline Vector3DI &operator-= (Vector2DI &op); + inline Vector3DI &operator-= (Vector2DF &op); + inline Vector3DI &operator-= (Vector3DC &op); + inline Vector3DI &operator-= (Vector3DI &op); + inline Vector3DI &operator-= (Vector3DF &op); + inline Vector3DI &operator-= (Vector4DF &op); + + inline Vector3DI &operator*= (Vector2DC &op); + inline Vector3DI &operator*= (Vector2DI &op); + inline Vector3DI &operator*= (Vector2DF &op); + inline Vector3DI &operator*= (Vector3DC &op); + inline Vector3DI &operator*= (Vector3DI &op); + inline Vector3DI &operator*= (Vector3DF &op); + inline Vector3DI &operator*= (Vector4DF &op); + + inline Vector3DI &operator/= (Vector2DC &op); + inline Vector3DI &operator/= (Vector2DI &op); + inline Vector3DI &operator/= (Vector2DF &op); + inline Vector3DI &operator/= (Vector3DC &op); + inline Vector3DI &operator/= (Vector3DI &op); + inline Vector3DI &operator/= (Vector3DF &op); + inline Vector3DI &operator/= (Vector4DF &op); + + inline Vector3DI &Cross (Vector3DC &v); + inline Vector3DI &Cross (Vector3DI &v); + inline Vector3DI &Cross (Vector3DF &v); + + inline double Dot(Vector3DC &v); + inline double Dot(Vector3DI &v); + inline double Dot(Vector3DF &v); + + inline double Dist (Vector2DC &v); + inline double Dist (Vector2DI &v); + inline double Dist (Vector2DF &v); + inline double Dist (Vector3DC &v); + inline double Dist (Vector3DI &v); + inline double Dist (Vector3DF &v); + inline double Dist (Vector4DF &v); + + inline double DistSq (Vector2DC &v); + inline double DistSq (Vector2DI &v); + inline double DistSq (Vector2DF &v); + inline double DistSq (Vector3DC &v); + inline double DistSq (Vector3DI &v); + inline double DistSq (Vector3DF &v); + inline double DistSq (Vector4DF &v); + + inline Vector3DI &Normalize (void); + inline double Length (void); + + inline VTYPE &X(void); + inline VTYPE &Y(void); + inline VTYPE &Z(void); + inline VTYPE W(void); + inline const VTYPE &X(void) const; + inline const VTYPE &Y(void) const; + inline const VTYPE &Z(void) const; + inline const VTYPE W(void) const; + inline VTYPE *Data (void); + }; + + #undef VNAME + #undef VTYPE + + // Vector3DF Declarations + + #define VNAME 3DF + #define VTYPE float + + class Vector3DF { + public: + VTYPE x, y, z; + + // Constructors/Destructors + inline Vector3DF(); + inline ~Vector3DF(); + inline Vector3DF (const VTYPE xa, const VTYPE ya, const VTYPE za); + inline Vector3DF (const Vector2DC &op); + inline Vector3DF (const Vector2DI &op); + inline Vector3DF (const Vector2DF &op); + inline Vector3DF (const Vector3DC &op); + inline Vector3DF (const Vector3DI &op); + inline Vector3DF (const Vector3DF &op); + inline Vector3DF (const Vector4DF &op); + + // Set Functions + inline Vector3DF &Set (const double xa, const double ya, const double za); + + // Member Functions + inline Vector3DF &operator= (const int op); + inline Vector3DF &operator= (const double op); + inline Vector3DF &operator= (const Vector2DC &op); + inline Vector3DF &operator= (const Vector2DI &op); + inline Vector3DF &operator= (const Vector2DF &op); + inline Vector3DF &operator= (const Vector3DC &op); + inline Vector3DF &operator= (const Vector3DI &op); + inline Vector3DF &operator= (const Vector3DF &op); + inline Vector3DF &operator= (const Vector4DF &op); + + inline Vector3DF &operator+= (const int op); + inline Vector3DF &operator+= (const double op); + inline Vector3DF &operator+= (const Vector2DC &op); + inline Vector3DF &operator+= (const Vector2DI &op); + inline Vector3DF &operator+= (const Vector2DF &op); + inline Vector3DF &operator+= (const Vector3DC &op); + inline Vector3DF &operator+= (const Vector3DI &op); + inline Vector3DF &operator+= (const Vector3DF &op); + inline Vector3DF &operator+= (const Vector4DF &op); + + inline Vector3DF &operator-= (const int op); + inline Vector3DF &operator-= (const double op); + inline Vector3DF &operator-= (const Vector2DC &op); + inline Vector3DF &operator-= (const Vector2DI &op); + inline Vector3DF &operator-= (const Vector2DF &op); + inline Vector3DF &operator-= (const Vector3DC &op); + inline Vector3DF &operator-= (const Vector3DI &op); + inline Vector3DF &operator-= (const Vector3DF &op); + inline Vector3DF &operator-= (const Vector4DF &op); + + inline Vector3DF &operator*= (const int op); + inline Vector3DF &operator*= (const double op); + inline Vector3DF &operator*= (const Vector2DC &op); + inline Vector3DF &operator*= (const Vector2DI &op); + inline Vector3DF &operator*= (const Vector2DF &op); + inline Vector3DF &operator*= (const Vector3DC &op); + inline Vector3DF &operator*= (const Vector3DI &op); + inline Vector3DF &operator*= (const Vector3DF &op); + inline Vector3DF &operator*= (const Vector4DF &op); + Vector3DF &operator*= (const Matrix4F &op); + Vector3DF &operator*= (const MatrixF &op); // see vector.cpp + + inline Vector3DF &operator/= (const int op); + inline Vector3DF &operator/= (const double op); + inline Vector3DF &operator/= (const Vector2DC &op); + inline Vector3DF &operator/= (const Vector2DI &op); + inline Vector3DF &operator/= (const Vector2DF &op); + inline Vector3DF &operator/= (const Vector3DC &op); + inline Vector3DF &operator/= (const Vector3DI &op); + inline Vector3DF &operator/= (const Vector3DF &op); + inline Vector3DF &operator/= (const Vector4DF &op); + + inline Vector3DF &Cross (const Vector3DC &v); + inline Vector3DF &Cross (const Vector3DI &v); + inline Vector3DF &Cross (const Vector3DF &v); + + inline double Dot(const Vector3DC &v); + inline double Dot(const Vector3DI &v); + inline double Dot(const Vector3DF &v); + + inline double Dist (const Vector2DC &v); + inline double Dist (const Vector2DI &v); + inline double Dist (const Vector2DF &v); + inline double Dist (const Vector3DC &v); + inline double Dist (const Vector3DI &v); + inline double Dist (const Vector3DF &v); + inline double Dist (const Vector4DF &v); + + inline double DistSq (const Vector2DC &v); + inline double DistSq (const Vector2DI &v); + inline double DistSq (const Vector2DF &v); + inline double DistSq (const Vector3DC &v); + inline double DistSq (const Vector3DI &v); + inline double DistSq (const Vector3DF &v); + inline double DistSq (const Vector4DF &v); + + inline Vector3DF &Normalize (void); + inline double Length (void); + + inline VTYPE &X(); + inline VTYPE &Y(); + inline VTYPE &Z(); + inline VTYPE W(); + inline const VTYPE &X() const; + inline const VTYPE &Y() const; + inline const VTYPE &Z() const; + inline const VTYPE W() const; + inline VTYPE *Data (); + }; + + #undef VNAME + #undef VTYPE + + // Vector4DF Declarations + + #define VNAME 4DF + #define VTYPE double + + class Vector4DF { + public: + VTYPE x, y, z, w; + + // Constructors/Destructors + inline Vector4DF(); + inline ~Vector4DF(); + inline Vector4DF (VTYPE xa, VTYPE ya, VTYPE za, VTYPE wa); + inline Vector4DF (Vector2DC &op); + inline Vector4DF (Vector2DI &op); + inline Vector4DF (Vector2DF &op); + inline Vector4DF (Vector3DC &op); + inline Vector4DF (Vector3DI &op); + inline Vector4DF (Vector3DF &op); + inline Vector4DF (Vector4DF &op); + + // Member Functions + inline Vector4DF &operator= (int op); + inline Vector4DF &operator= (double op); + inline Vector4DF &operator= (Vector2DC &op); + inline Vector4DF &operator= (Vector2DI &op); + inline Vector4DF &operator= (Vector2DF &op); + inline Vector4DF &operator= (Vector3DC &op); + inline Vector4DF &operator= (Vector3DI &op); + inline Vector4DF &operator= (Vector3DF &op); + inline Vector4DF &operator= (Vector4DF &op); + + inline Vector4DF &operator+= (int op); + inline Vector4DF &operator+= (double op); + inline Vector4DF &operator+= (Vector2DC &op); + inline Vector4DF &operator+= (Vector2DI &op); + inline Vector4DF &operator+= (Vector2DF &op); + inline Vector4DF &operator+= (Vector3DC &op); + inline Vector4DF &operator+= (Vector3DI &op); + inline Vector4DF &operator+= (Vector3DF &op); + inline Vector4DF &operator+= (Vector4DF &op); + + inline Vector4DF &operator-= (int op); + inline Vector4DF &operator-= (double op); + inline Vector4DF &operator-= (Vector2DC &op); + inline Vector4DF &operator-= (Vector2DI &op); + inline Vector4DF &operator-= (Vector2DF &op); + inline Vector4DF &operator-= (Vector3DC &op); + inline Vector4DF &operator-= (Vector3DI &op); + inline Vector4DF &operator-= (Vector3DF &op); + inline Vector4DF &operator-= (Vector4DF &op); + + inline Vector4DF &operator*= (int op); + inline Vector4DF &operator*= (double op); + inline Vector4DF &operator*= (Vector2DC &op); + inline Vector4DF &operator*= (Vector2DI &op); + inline Vector4DF &operator*= (Vector2DF &op); + inline Vector4DF &operator*= (Vector3DC &op); + inline Vector4DF &operator*= (Vector3DI &op); + inline Vector4DF &operator*= (Vector3DF &op); + inline Vector4DF &operator*= (Vector4DF &op); + Vector4DF &operator*= (const Matrix4F &op); + Vector4DF &operator*= (const MatrixF &op); // see vector.cpp + + inline Vector4DF &operator/= (int op); + inline Vector4DF &operator/= (double op); + inline Vector4DF &operator/= (Vector2DC &op); + inline Vector4DF &operator/= (Vector2DI &op); + inline Vector4DF &operator/= (Vector2DF &op); + inline Vector4DF &operator/= (Vector3DC &op); + inline Vector4DF &operator/= (Vector3DI &op); + inline Vector4DF &operator/= (Vector3DF &op); + inline Vector4DF &operator/= (Vector4DF &op); + + inline Vector4DF &Cross (Vector4DF &v); + + inline double Dot(Vector4DF &v); + + inline double Dist (Vector4DF &v); + + inline double DistSq (Vector4DF &v); + + inline Vector4DF &Normalize (void); + inline double Length (void); + + inline VTYPE &X(void); + inline VTYPE &Y(void); + inline VTYPE &Z(void); + inline VTYPE &W(void); + inline const VTYPE &X(void) const; + inline const VTYPE &Y(void) const; + inline const VTYPE &Z(void) const; + inline const VTYPE &W(void) const; + inline VTYPE *Data (void); + }; + + #undef VNAME + #undef VTYPE + + // Vector Code Definitions (Inlined) + #include "vector.cci" + +#endif + diff --git a/Extras/sph/fluid_system_host.linkinfo b/Extras/sph/fluid_system_host.linkinfo new file mode 100644 index 0000000..b094dc5 --- /dev/null +++ b/Extras/sph/fluid_system_host.linkinfo @@ -0,0 +1 @@ + --import sRadixSum,%laneid,%ctaid,%nctaid,%smid,A7,%pm3,%pm2,%pm1,__CC-temp__0__,%pm0,%tid,%clock,%warpid,%ntid,%gridid --export _Z8RadixSumP12KeyValuePairjjj,_Z13hashParticlesPcP5uint2i,_Z15insertParticlesPcP5uint2Piii,_Z15computePressurePcPiP5uint2i,_Z25RadixAddOffsetsAndShuffleP12KeyValuePairS0_jji,_Z20insertParticlesRadixPcP5uint2PiS_ii,_Z12computeForcePcPiP5uint2i,_Z15computeForceNbrPci,_Z16advanceParticlesPciff,_Z14RadixPrefixSumv \ No newline at end of file diff --git a/Extras/sph/fluids.vcproj b/Extras/sph/fluids.vcproj new file mode 100644 index 0000000..e9060ec --- /dev/null +++ b/Extras/sph/fluids.vcproj @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/sph/fluids/fluid.cpp b/Extras/sph/fluids/fluid.cpp new file mode 100644 index 0000000..e9bddc8 --- /dev/null +++ b/Extras/sph/fluids/fluid.cpp @@ -0,0 +1,22 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "fluid.h" diff --git a/Extras/sph/fluids/fluid.h b/Extras/sph/fluids/fluid.h new file mode 100644 index 0000000..2ed6202 --- /dev/null +++ b/Extras/sph/fluids/fluid.h @@ -0,0 +1,44 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEF_FLUID + #define DEF_FLUID + + #include "vector.h" + + #include "common_defs.h" + + struct Fluid { + public: + Vector3DF pos; // Basic particle (must match Particle class) + DWORD clr; + int next; + Vector3DF vel; + Vector3DF vel_eval; + unsigned short age; + + float pressure; // Smoothed Particle Hydrodynamics + float density; + Vector3DF sph_force; + }; + +#endif /*PARTICLE_H_*/ diff --git a/Extras/sph/fluids/fluid_system.cpp b/Extras/sph/fluids/fluid_system.cpp new file mode 100644 index 0000000..966a2ce --- /dev/null +++ b/Extras/sph/fluids/fluid_system.cpp @@ -0,0 +1,869 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include + +#ifdef _MSC_VER + #include +#else + #include +#endif + +#include "common_defs.h" +#include "mtime.h" +#include "fluid_system.h" + +#ifdef BUILD_CUDA + #include "fluid_system_host.cuh" +#endif + +#define EPSILON 0.00001f //for collision detection + +FluidSystem::FluidSystem () +{ +} + +void FluidSystem::Initialize ( int mode, int total ) +{ + if ( mode != BFLUID ) { + printf ( "ERROR: FluidSystem not initialized as BFLUID.\n"); + } + PointSet::Initialize ( mode, total ); + + FreeBuffers (); + AddBuffer ( BFLUID, sizeof ( Fluid ), total ); + AddAttribute ( 0, "pos", sizeof ( Vector3DF ), false ); + AddAttribute ( 0, "color", sizeof ( DWORD ), false ); + AddAttribute ( 0, "vel", sizeof ( Vector3DF ), false ); + AddAttribute ( 0, "ndx", sizeof ( unsigned short ), false ); + AddAttribute ( 0, "age", sizeof ( unsigned short ), false ); + + AddAttribute ( 0, "pressure", sizeof ( double ), false ); + AddAttribute ( 0, "density", sizeof ( double ), false ); + AddAttribute ( 0, "sph_force", sizeof ( Vector3DF ), false ); + AddAttribute ( 0, "next", sizeof ( Fluid* ), false ); + AddAttribute ( 0, "tag", sizeof ( bool ), false ); + + SPH_Setup (); + Reset ( total ); +} + +void FluidSystem::Reset ( int nmax ) +{ + ResetBuffer ( 0, nmax ); + + m_DT = 0.003; // 0.001; // .001 = for point grav + + // Reset parameters + m_Param [ MAX_FRAC ] = 1.0; + m_Param [ POINT_GRAV ] = 0.0; + m_Param [ PLANE_GRAV ] = 1.0; + + m_Param [ BOUND_ZMIN_SLOPE ] = 0.0; + m_Param [ FORCE_XMAX_SIN ] = 0.0; + m_Param [ FORCE_XMIN_SIN ] = 0.0; + m_Toggle [ WRAP_X ] = false; + m_Toggle [ WALL_BARRIER ] = false; + m_Toggle [ LEVY_BARRIER ] = false; + m_Toggle [ DRAIN_BARRIER ] = false; + m_Param [ SPH_INTSTIFF ] = 1.00; + m_Param [ SPH_VISC ] = 0.2; + m_Param [ SPH_INTSTIFF ] = 0.50; + m_Param [ SPH_EXTSTIFF ] = 20000; + m_Param [ SPH_SMOOTHRADIUS ] = 0.01; + + m_Vec [ POINT_GRAV_POS ].Set ( 0, 0, 50 ); + m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, -9.8 ); + m_Vec [ EMIT_POS ].Set ( 0, 0, 0 ); + m_Vec [ EMIT_RATE ].Set ( 0, 0, 0 ); + m_Vec [ EMIT_ANG ].Set ( 0, 90, 1.0 ); + m_Vec [ EMIT_DANG ].Set ( 0, 0, 0 ); +} + +int FluidSystem::AddPoint () +{ + xref ndx; + Fluid* f = (Fluid*) AddElem ( 0, ndx ); + f->sph_force.Set(0,0,0); + f->vel.Set(0,0,0); + f->vel_eval.Set(0,0,0); + f->next = 0x0; + f->pressure = 0; + f->density = 0; + return ndx; +} + +int FluidSystem::AddPointReuse () +{ + xref ndx; + Fluid* f; + if ( NumPoints() <= mBuf[0].max-2 ) + f = (Fluid*) AddElem ( 0, ndx ); + else + f = (Fluid*) RandomElem ( 0, ndx ); + + f->sph_force.Set(0,0,0); + f->vel.Set(0,0,0); + f->vel_eval.Set(0,0,0); + f->next = 0x0; + f->pressure = 0; + f->density = 0; + return ndx; +} + +void FluidSystem::Run () +{ + bool bTiming = false;//true; + + mint::Time start, stop; + + float ss = m_Param [ SPH_PDIST ] / m_Param[ SPH_SIMSCALE ]; // simulation scale (not Schutzstaffel) + + if ( m_Vec[EMIT_RATE].x > 0 && (++m_Frame) % (int) m_Vec[EMIT_RATE].x == 0 ) { + //m_Frame = 0; + Emit ( ss ); + } + + #ifdef NOGRID + // Slow method - O(n^2) + SPH_ComputePressureSlow (); + SPH_ComputeForceSlow (); + #else + + if ( m_Toggle[USE_CUDA] ) { + + #ifdef BUILD_CUDA + // -- GPU -- + start.SetSystemTime ( ACC_NSEC ); + TransferToCUDA ( mBuf[0].data, (int*) &m_Grid[0], NumPoints() ); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "TO: %s\n", stop.GetReadableTime().c_str() ); } + + start.SetSystemTime ( ACC_NSEC ); + Grid_InsertParticlesCUDA (); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "INSERT (CUDA): %s\n", stop.GetReadableTime().c_str() ); } + + start.SetSystemTime ( ACC_NSEC ); + SPH_ComputePressureCUDA (); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "PRESS (CUDA): %s\n", stop.GetReadableTime().c_str() ); } + + start.SetSystemTime ( ACC_NSEC ); + SPH_ComputeForceCUDA (); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FORCE (CUDA): %s\n", stop.GetReadableTime().c_str() ); } + + //** CUDA integrator is incomplete.. + // Once integrator is done, we can remove TransferTo/From steps + /*start.SetSystemTime ( ACC_NSEC ); + SPH_AdvanceCUDA( m_DT, m_DT/m_Param[SPH_SIMSCALE] ); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "ADV (CUDA): %s\n", stop.GetReadableTime().c_str() ); }*/ + + start.SetSystemTime ( ACC_NSEC ); + TransferFromCUDA ( mBuf[0].data, (int*) &m_Grid[0], NumPoints() ); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FROM: %s\n", stop.GetReadableTime().c_str() ); } + + // .. Do advance on CPU + Advance(); + + #endif + + } else { + // -- CPU only -- + + start.SetSystemTime ( ACC_NSEC ); + Grid_InsertParticles (); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "INSERT: %s\n", stop.GetReadableTime().c_str() ); } + + start.SetSystemTime ( ACC_NSEC ); + SPH_ComputePressureGrid (); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "PRESS: %s\n", stop.GetReadableTime().c_str() ); } + + start.SetSystemTime ( ACC_NSEC ); + SPH_ComputeForceGridNC (); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FORCE: %s\n", stop.GetReadableTime().c_str() ); } + + start.SetSystemTime ( ACC_NSEC ); + Advance(); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "ADV: %s\n", stop.GetReadableTime().c_str() ); } + } + + #endif +} + + + +void FluidSystem::SPH_DrawDomain () +{ + Vector3DF min, max; + min = m_Vec[SPH_VOLMIN]; + max = m_Vec[SPH_VOLMAX]; + min.z += 0.5; + + glColor3f ( 0.0, 0.0, 1.0 ); + glBegin ( GL_LINES ); + glVertex3f ( min.x, min.y, min.z ); glVertex3f ( max.x, min.y, min.z ); + glVertex3f ( min.x, max.y, min.z ); glVertex3f ( max.x, max.y, min.z ); + glVertex3f ( min.x, min.y, min.z ); glVertex3f ( min.x, max.y, min.z ); + glVertex3f ( max.x, min.y, min.z ); glVertex3f ( max.x, max.y, min.z ); + glEnd (); +} + +void FluidSystem::Advance () +{ + char *dat1, *dat1_end; + Fluid* p; + Vector3DF norm, z; + Vector3DF dir, accel; + Vector3DF vnext; + Vector3DF min, max; + double adj; + float SL, SL2, ss, radius; + float stiff, damp, speed, diff; + SL = m_Param[SPH_LIMIT]; + SL2 = SL*SL; + + stiff = m_Param[SPH_EXTSTIFF]; + damp = m_Param[SPH_EXTDAMP]; + radius = m_Param[SPH_PRADIUS]; + min = m_Vec[SPH_VOLMIN]; + max = m_Vec[SPH_VOLMAX]; + ss = m_Param[SPH_SIMSCALE]; + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) { + p = (Fluid*) dat1; + + // Compute Acceleration + accel = p->sph_force; + accel *= m_Param[SPH_PMASS]; + + // Velocity limiting + speed = accel.x*accel.x + accel.y*accel.y + accel.z*accel.z; + if ( speed > SL2 ) { + accel *= SL / sqrt(speed); + } + + // Boundary Conditions + + // Z-axis walls + diff = 2 * radius - ( p->pos.z - min.z - (p->pos.x - m_Vec[SPH_VOLMIN].x) * m_Param[BOUND_ZMIN_SLOPE] )*ss; + if (diff > EPSILON ) { + norm.Set ( -m_Param[BOUND_ZMIN_SLOPE], 0, 1.0 - m_Param[BOUND_ZMIN_SLOPE] ); + adj = stiff * diff - damp * norm.Dot ( p->vel_eval ); + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + + diff = 2 * radius - ( max.z - p->pos.z )*ss; + if (diff > EPSILON) { + norm.Set ( 0, 0, -1 ); + adj = stiff * diff - damp * norm.Dot ( p->vel_eval ); + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + + // X-axis walls + if ( !m_Toggle[WRAP_X] ) { + diff = 2 * radius - ( p->pos.x - min.x + (sin(m_Time*10.0)-1+(p->pos.y*0.025)*0.25) * m_Param[FORCE_XMIN_SIN] )*ss; + //diff = 2 * radius - ( p->pos.x - min.x + (sin(m_Time*10.0)-1) * m_Param[FORCE_XMIN_SIN] )*ss; + if (diff > EPSILON ) { + norm.Set ( 1.0, 0, 0 ); + adj = (m_Param[ FORCE_XMIN_SIN ] + 1) * stiff * diff - damp * norm.Dot ( p->vel_eval ) ; + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + + diff = 2 * radius - ( max.x - p->pos.x + (sin(m_Time*10.0)-1) * m_Param[FORCE_XMAX_SIN] )*ss; + if (diff > EPSILON) { + norm.Set ( -1, 0, 0 ); + adj = (m_Param[ FORCE_XMAX_SIN ]+1) * stiff * diff - damp * norm.Dot ( p->vel_eval ); + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + } + + // Y-axis walls + diff = 2 * radius - ( p->pos.y - min.y )*ss; + if (diff > EPSILON) { + norm.Set ( 0, 1, 0 ); + adj = stiff * diff - damp * norm.Dot ( p->vel_eval ); + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + diff = 2 * radius - ( max.y - p->pos.y )*ss; + if (diff > EPSILON) { + norm.Set ( 0, -1, 0 ); + adj = stiff * diff - damp * norm.Dot ( p->vel_eval ); + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + + // Wall barrier + if ( m_Toggle[WALL_BARRIER] ) { + diff = 2 * radius - ( p->pos.x - 0 )*ss; + if (diff < 2*radius && diff > EPSILON && fabs(p->pos.y) < 3 && p->pos.z < 10) { + norm.Set ( 1.0, 0, 0 ); + adj = 2*stiff * diff - damp * norm.Dot ( p->vel_eval ) ; + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + } + + // Levy barrier + if ( m_Toggle[LEVY_BARRIER] ) { + diff = 2 * radius - ( p->pos.x - 0 )*ss; + if (diff < 2*radius && diff > EPSILON && fabs(p->pos.y) > 5 && p->pos.z < 10) { + norm.Set ( 1.0, 0, 0 ); + adj = 2*stiff * diff - damp * norm.Dot ( p->vel_eval ) ; + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + } + // Drain barrier + if ( m_Toggle[DRAIN_BARRIER] ) { + diff = 2 * radius - ( p->pos.z - min.z-15 )*ss; + if (diff < 2*radius && diff > EPSILON && (fabs(p->pos.x)>3 || fabs(p->pos.y)>3) ) { + norm.Set ( 0, 0, 1); + adj = stiff * diff - damp * norm.Dot ( p->vel_eval ); + accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z; + } + } + + // Plane gravity + if ( m_Param[PLANE_GRAV] > 0) + accel += m_Vec[PLANE_GRAV_DIR]; + + // Point gravity + if ( m_Param[POINT_GRAV] > 0 ) { + norm.x = ( p->pos.x - m_Vec[POINT_GRAV_POS].x ); + norm.y = ( p->pos.y - m_Vec[POINT_GRAV_POS].y ); + norm.z = ( p->pos.z - m_Vec[POINT_GRAV_POS].z ); + norm.Normalize (); + norm *= m_Param[POINT_GRAV]; + accel -= norm; + } + + // Leapfrog Integration ---------------------------- + vnext = accel; + vnext *= m_DT; + vnext += p->vel; // v(t+1/2) = v(t-1/2) + a(t) dt + p->vel_eval = p->vel; + p->vel_eval += vnext; + p->vel_eval *= 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later + p->vel = vnext; + vnext *= m_DT/ss; + p->pos += vnext; // p(t+1) = p(t) + v(t+1/2) dt + + if ( m_Param[CLR_MODE]==1.0 ) { + adj = fabs(vnext.x)+fabs(vnext.y)+fabs(vnext.z) / 7000.0; + adj = (adj > 1.0) ? 1.0 : adj; + p->clr = COLORA( 0, adj, adj, 1 ); + } + if ( m_Param[CLR_MODE]==2.0 ) { + float v = 0.5 + ( p->pressure / 1500.0); + if ( v < 0.1 ) v = 0.1; + if ( v > 1.0 ) v = 1.0; + p->clr = COLORA ( v, 1-v, 0, 1 ); + } + + + // Euler integration ------------------------------- + /* accel += m_Gravity; + accel *= m_DT; + p->vel += accel; // v(t+1) = v(t) + a(t) dt + p->vel_eval += accel; + p->vel_eval *= m_DT/d; + p->pos += p->vel_eval; + p->vel_eval = p->vel; */ + + + if ( m_Toggle[WRAP_X] ) { + diff = p->pos.x - (m_Vec[SPH_VOLMIN].x + 2); // -- Simulates object in center of flow + if ( diff <= 0 ) { + p->pos.x = (m_Vec[SPH_VOLMAX].x - 2) + diff*2; + p->pos.z = 10; + } + } + } + + m_Time += m_DT; +} + +//------------------------------------------------------ SPH Setup +// +// Range = +/- 10.0 * 0.006 (r) = 0.12 m (= 120 mm = 4.7 inch) +// Container Volume (Vc) = 0.001728 m^3 +// Rest Density (D) = 1000.0 kg / m^3 +// Particle Mass (Pm) = 0.00020543 kg (mass = vol * density) +// Number of Particles (N) = 4000.0 +// Water Mass (M) = 0.821 kg (= 821 grams) +// Water Volume (V) = 0.000821 m^3 (= 3.4 cups, .21 gals) +// Smoothing Radius (R) = 0.02 m (= 20 mm = ~3/4 inch) +// Particle Radius (Pr) = 0.00366 m (= 4 mm = ~1/8 inch) +// Particle Volume (Pv) = 2.054e-7 m^3 (= .268 milliliters) +// Rest Distance (Pd) = 0.0059 m +// +// Given: D, Pm, N +// Pv = Pm / D 0.00020543 kg / 1000 kg/m^3 = 2.054e-7 m^3 +// Pv = 4/3*pi*Pr^3 cuberoot( 2.054e-7 m^3 * 3/(4pi) ) = 0.00366 m +// M = Pm * N 0.00020543 kg * 4000.0 = 0.821 kg +// V = M / D 0.821 kg / 1000 kg/m^3 = 0.000821 m^3 +// V = Pv * N 2.054e-7 m^3 * 4000 = 0.000821 m^3 +// Pd = cuberoot(Pm/D) cuberoot(0.00020543/1000) = 0.0059 m +// +// Ideal grid cell size (gs) = 2 * smoothing radius = 0.02*2 = 0.04 +// Ideal domain size = k*gs/d = k*0.02*2/0.005 = k*8 = {8, 16, 24, 32, 40, 48, ..} +// (k = number of cells, gs = cell size, d = simulation scale) + +void FluidSystem::SPH_Setup () +{ + m_Param [ SPH_SIMSCALE ] = 0.004; // unit size + m_Param [ SPH_VISC ] = 0.2; // pascal-second (Pa.s) = 1 kg m^-1 s^-1 (see wikipedia page on viscosity) + m_Param [ SPH_RESTDENSITY ] = 600.0; // kg / m^3 + m_Param [ SPH_PMASS ] = 0.00020543; // kg + m_Param [ SPH_PRADIUS ] = 0.004; // m + m_Param [ SPH_PDIST ] = 0.0059; // m + m_Param [ SPH_SMOOTHRADIUS ] = 0.01; // m + m_Param [ SPH_INTSTIFF ] = 1.00; + m_Param [ SPH_EXTSTIFF ] = 10000.0; + m_Param [ SPH_EXTDAMP ] = 256.0; + m_Param [ SPH_LIMIT ] = 200.0; // m / s + + m_Toggle [ SPH_GRID ] = false; + m_Toggle [ SPH_DEBUG ] = false; + + SPH_ComputeKernels (); +} + +void FluidSystem::SPH_ComputeKernels () +{ + m_Param [ SPH_PDIST ] = pow ( m_Param[SPH_PMASS] / m_Param[SPH_RESTDENSITY], 1/3.0 ); + m_R2 = m_Param [SPH_SMOOTHRADIUS] * m_Param[SPH_SMOOTHRADIUS]; + m_Poly6Kern = 315.0f / (64.0f * 3.141592 * pow( m_Param[SPH_SMOOTHRADIUS], 9) ); // Wpoly6 kernel (denominator part) - 2003 Muller, p.4 + m_SpikyKern = -45.0f / (3.141592 * pow( m_Param[SPH_SMOOTHRADIUS], 6) ); // Laplacian of viscocity (denominator): PI h^6 + m_LapKern = 45.0f / (3.141592 * pow( m_Param[SPH_SMOOTHRADIUS], 6) ); +} + +void FluidSystem::SPH_CreateExample ( int n, int nmax ) +{ + Vector3DF pos; + Vector3DF min, max; + + Reset ( nmax ); + + switch ( n ) { + case 0: // Wave pool + + //-- TEST CASE: 2x2x2 grid, 32 particles. NOTE: Set PRADIUS to 0.0004 to reduce wall influence + // grid 0: 3*3*2 = 18 particles + // grid 1,2: 3*1*2 = 6 particles + // grid 3: 1*1*2 = 2 particles + // grid 4,5,6: 0 = 0 particles + /*m_Vec [ SPH_VOLMIN ].Set ( -2.5, -2.5, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 2.5, 2.5, 5.0 ); + m_Vec [ SPH_INITMIN ].Set ( -2.5, -2.5, 0 ); + m_Vec [ SPH_INITMAX ].Set ( 2.5, 2.5, 1.6 );*/ + + m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 40 ); + + //m_Vec [ SPH_INITMIN ].Set ( -5, -5, 10 ); + //m_Vec [ SPH_INITMAX ].Set ( 5, 5, 20 ); + + m_Vec [ SPH_INITMIN ].Set ( -20, -26, 10 ); + m_Vec [ SPH_INITMAX ].Set ( 20, 26, 40 ); + + m_Param [ FORCE_XMIN_SIN ] = 12.0; + m_Param [ BOUND_ZMIN_SLOPE ] = 0.05; + break; + case 1: // Dam break + m_Vec [ SPH_VOLMIN ].Set ( -30, -14, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 30, 14, 60 ); + m_Vec [ SPH_INITMIN ].Set ( 0, -13, 0 ); + m_Vec [ SPH_INITMAX ].Set ( 29, 13, 30 ); + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + break; + case 2: // Dual-Wave pool + m_Vec [ SPH_VOLMIN ].Set ( -60, -5, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 60, 5, 50 ); + m_Vec [ SPH_INITMIN ].Set ( -46, -5, 0 ); + m_Vec [ SPH_INITMAX ].Set ( 46, 5, 15 ); + m_Param [ FORCE_XMIN_SIN ] = 8.0; + m_Param [ FORCE_XMAX_SIN ] = 8.0; + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + break; + case 3: // Swirl Stream + m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 ); + m_Vec [ SPH_INITMIN ].Set ( -30, -30, 0 ); + m_Vec [ SPH_INITMAX ].Set ( 30, 30, 40 ); + m_Vec [ EMIT_POS ].Set ( -20, -20, 22 ); + m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 ); + m_Vec [ EMIT_ANG ].Set ( 0, 120, 1.5 ); + m_Vec [ EMIT_DANG ].Set ( 0, 0, 0 ); + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + break; + case 4: // Shockwave + m_Vec [ SPH_VOLMIN ].Set ( -60, -15, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 60, 15, 50 ); + m_Vec [ SPH_INITMIN ].Set ( -59, -14, 0 ); + m_Vec [ SPH_INITMAX ].Set ( 59, 14, 30 ); + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + m_Toggle [ WALL_BARRIER ] = true; + m_Toggle [ WRAP_X ] = true; + break; + case 5: // Zero gravity + m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 ); + m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 ); + m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 ); + m_Vec [ EMIT_POS ].Set ( -20, 0, 40 ); + m_Vec [ EMIT_RATE ].Set ( 2, 1, 0 ); + m_Vec [ EMIT_ANG ].Set ( 0, 120, 0.25 ); + m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 ); + m_Param [ SPH_INTSTIFF ] = 0.20; + break; + case 6: // Point gravity + m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 ); + m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 ); + m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 ); + m_Param [ SPH_INTSTIFF ] = 0.50; + m_Vec [ EMIT_POS ].Set ( -20, 20, 25 ); + m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 ); + m_Vec [ EMIT_ANG ].Set ( -20, 100, 2.0 ); + m_Vec [ POINT_GRAV_POS ].Set ( 0, 0, 25 ); + m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 ); + m_Param [ POINT_GRAV ] = 3.5; + break; + case 7: // Levy break + m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 ); + m_Vec [ SPH_INITMIN ].Set ( 10, -40, 0 ); + m_Vec [ SPH_INITMAX ].Set ( 40, 40, 50 ); + m_Vec [ EMIT_POS ].Set ( 34, 27, 16.6 ); + m_Vec [ EMIT_RATE ].Set ( 2, 9, 0 ); + m_Vec [ EMIT_ANG ].Set ( 118, 200, 1.0 ); + m_Toggle [ LEVY_BARRIER ] = true; + m_Param [ BOUND_ZMIN_SLOPE ] = 0.1; + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + break; + case 8: // Drain + m_Vec [ SPH_VOLMIN ].Set ( -20, -20, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 20, 20, 50 ); + m_Vec [ SPH_INITMIN ].Set ( -15, -20, 20 ); + m_Vec [ SPH_INITMAX ].Set ( 20, 20, 50 ); + m_Vec [ EMIT_POS ].Set ( -16, -16, 30 ); + m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 ); + m_Vec [ EMIT_ANG ].Set ( -20, 140, 1.8 ); + m_Toggle [ DRAIN_BARRIER ] = true; + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + break; + case 9: // Tumbler + m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 ); + m_Vec [ SPH_INITMIN ].Set ( 24, -29, 20 ); + m_Vec [ SPH_INITMAX ].Set ( 29, 29, 40 ); + m_Param [ SPH_VISC ] = 0.1; + m_Param [ SPH_INTSTIFF ] = 0.50; + m_Param [ SPH_EXTSTIFF ] = 8000; + //m_Param [ SPH_SMOOTHRADIUS ] = 0.01; + m_Param [ BOUND_ZMIN_SLOPE ] = 0.4; + m_Param [ FORCE_XMIN_SIN ] = 12.00; + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + break; + case 10: // Large sim + m_Vec [ SPH_VOLMIN ].Set ( -35, -35, 0 ); + m_Vec [ SPH_VOLMAX ].Set ( 35, 35, 60 ); + m_Vec [ SPH_INITMIN ].Set ( -5, -35, 0 ); + m_Vec [ SPH_INITMAX ].Set ( 30, 0, 60 ); + m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 ); + break; + } + + SPH_ComputeKernels (); + + m_Param [ SPH_SIMSIZE ] = m_Param [ SPH_SIMSCALE ] * (m_Vec[SPH_VOLMAX].z - m_Vec[SPH_VOLMIN].z); + m_Param [ SPH_PDIST ] = pow ( m_Param[SPH_PMASS] / m_Param[SPH_RESTDENSITY], 1/3.0 ); + + float ss = m_Param [ SPH_PDIST ]*0.87 / m_Param[ SPH_SIMSCALE ]; + printf ( "Spacing: %f\n", ss); + AddVolume ( m_Vec[SPH_INITMIN], m_Vec[SPH_INITMAX], ss ); // Create the particles + + float cell_size = m_Param[SPH_SMOOTHRADIUS]*2.0; // Grid cell size (2r) + Grid_Setup ( m_Vec[SPH_VOLMIN], m_Vec[SPH_VOLMAX], m_Param[SPH_SIMSCALE], cell_size, 1.0 ); // Setup grid + Grid_InsertParticles (); // Insert particles + + Vector3DF vmin, vmax; + vmin = m_Vec[SPH_VOLMIN]; + vmin -= Vector3DF(2,2,2); + vmax = m_Vec[SPH_VOLMAX]; + vmax += Vector3DF(2,2,-2); + + #ifdef BUILD_CUDA + FluidClearCUDA (); + Sleep ( 500 ); + + FluidSetupCUDA ( NumPoints(), sizeof(Fluid), *(float3*)& m_GridMin, *(float3*)& m_GridMax, *(float3*)& m_GridRes, *(float3*)& m_GridSize, (int) m_Vec[EMIT_RATE].x ); + + Sleep ( 500 ); + + FluidParamCUDA ( m_Param[SPH_SIMSCALE], m_Param[SPH_SMOOTHRADIUS], m_Param[SPH_PMASS], m_Param[SPH_RESTDENSITY], m_Param[SPH_INTSTIFF], m_Param[SPH_VISC] ); + #endif + +} + +// Compute Pressures - Very slow yet simple. O(n^2) +void FluidSystem::SPH_ComputePressureSlow () +{ + char *dat1, *dat1_end; + char *dat2, *dat2_end; + Fluid *p, *q; + int cnt = 0; + double dx, dy, dz, sum, dsq, c; + double d, d2, mR, mR2; + d = m_Param[SPH_SIMSCALE]; + d2 = d*d; + mR = m_Param[SPH_SMOOTHRADIUS]; + mR2 = mR*mR; + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) { + p = (Fluid*) dat1; + + sum = 0.0; + cnt = 0; + + dat2_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + for ( dat2 = mBuf[0].data; dat2 < dat2_end; dat2 += mBuf[0].stride ) { + q = (Fluid*) dat2; + + if ( p==q ) continue; + dx = ( p->pos.x - q->pos.x)*d; // dist in cm + dy = ( p->pos.y - q->pos.y)*d; + dz = ( p->pos.z - q->pos.z)*d; + dsq = (dx*dx + dy*dy + dz*dz); + if ( mR2 > dsq ) { + c = m_R2 - dsq; + sum += c * c * c; + cnt++; + //if ( p == m_CurrP ) q->tag = true; + } + } + p->density = sum * m_Param[SPH_PMASS] * m_Poly6Kern ; + p->pressure = ( p->density - m_Param[SPH_RESTDENSITY] ) * m_Param[SPH_INTSTIFF]; + p->density = 1.0f / p->density; + } +} + +// Compute Pressures - Using spatial grid, and also create neighbor table +void FluidSystem::SPH_ComputePressureGrid () +{ + char *dat1, *dat1_end; + Fluid* p; + Fluid* pcurr; + int pndx; + int i, cnt = 0; + float dx, dy, dz, sum, dsq, c; + float d, d2, mR, mR2; + float radius = m_Param[SPH_SMOOTHRADIUS] / m_Param[SPH_SIMSCALE]; + d = m_Param[SPH_SIMSCALE]; + d2 = d*d; + mR = m_Param[SPH_SMOOTHRADIUS]; + mR2 = mR*mR; + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + i = 0; + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride, i++ ) { + p = (Fluid*) dat1; + + sum = 0.0; + m_NC[i] = 0; + + Grid_FindCells ( p->pos, radius ); + for (int cell=0; cell < 8; cell++) { + if ( m_GridCell[cell] != -1 ) { + pndx = m_Grid [ m_GridCell[cell] ]; + while ( pndx != -1 ) { + pcurr = (Fluid*) (mBuf[0].data + pndx*mBuf[0].stride); + if ( pcurr == p ) {pndx = pcurr->next; continue; } + dx = ( p->pos.x - pcurr->pos.x)*d; // dist in cm + dy = ( p->pos.y - pcurr->pos.y)*d; + dz = ( p->pos.z - pcurr->pos.z)*d; + dsq = (dx*dx + dy*dy + dz*dz); + if ( mR2 > dsq ) { + c = m_R2 - dsq; + sum += c * c * c; + if ( m_NC[i] < MAX_NEIGHBOR ) { + m_Neighbor[i][ m_NC[i] ] = pndx; + m_NDist[i][ m_NC[i] ] = sqrt(dsq); + m_NC[i]++; + } + } + pndx = pcurr->next; + } + } + m_GridCell[cell] = -1; + } + p->density = sum * m_Param[SPH_PMASS] * m_Poly6Kern ; + p->pressure = ( p->density - m_Param[SPH_RESTDENSITY] ) * m_Param[SPH_INTSTIFF]; + p->density = 1.0f / p->density; + } +} + +// Compute Forces - Very slow, but simple. O(n^2) +void FluidSystem::SPH_ComputeForceSlow () +{ + char *dat1, *dat1_end; + char *dat2, *dat2_end; + Fluid *p, *q; + Vector3DF force, fcurr; + register double pterm, vterm, dterm; + double c, r, d, sum, dsq; + double dx, dy, dz; + double mR, mR2, visc; + + d = m_Param[SPH_SIMSCALE]; + mR = m_Param[SPH_SMOOTHRADIUS]; + mR2 = (mR*mR); + visc = m_Param[SPH_VISC]; + vterm = m_LapKern * visc; + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) { + p = (Fluid*) dat1; + + sum = 0.0; + force.Set ( 0, 0, 0 ); + + dat2_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + for ( dat2 = mBuf[0].data; dat2 < dat2_end; dat2 += mBuf[0].stride ) { + q = (Fluid*) dat2; + + if ( p == q ) continue; + dx = ( p->pos.x - q->pos.x )*d; // dist in cm + dy = ( p->pos.y - q->pos.y )*d; + dz = ( p->pos.z - q->pos.z )*d; + dsq = (dx*dx + dy*dy + dz*dz); + if ( mR2 > dsq ) { + r = sqrt ( dsq ); + c = (mR - r); + pterm = -0.5f * c * m_SpikyKern * ( p->pressure + q->pressure) / r; + dterm = c * p->density * q->density; + force.x += ( pterm * dx + vterm * (q->vel_eval.x - p->vel_eval.x) ) * dterm; + force.y += ( pterm * dy + vterm * (q->vel_eval.y - p->vel_eval.y) ) * dterm; + force.z += ( pterm * dz + vterm * (q->vel_eval.z - p->vel_eval.z) ) * dterm; + } + } + p->sph_force = force; + } +} + +// Compute Forces - Using spatial grid. Faster. +void FluidSystem::SPH_ComputeForceGrid () +{ + char *dat1, *dat1_end; + Fluid *p; + Fluid *pcurr; + int pndx; + Vector3DF force, fcurr; + register double pterm, vterm, dterm; + double c, d, dsq, r; + double dx, dy, dz; + double mR, mR2, visc; + float radius = m_Param[SPH_SMOOTHRADIUS] / m_Param[SPH_SIMSCALE]; + + d = m_Param[SPH_SIMSCALE]; + mR = m_Param[SPH_SMOOTHRADIUS]; + mR2 = (mR*mR); + visc = m_Param[SPH_VISC]; + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) { + p = (Fluid*) dat1; + + force.Set ( 0, 0, 0 ); + + Grid_FindCells ( p->pos, radius ); + for (int cell=0; cell < 8; cell++) { + if ( m_GridCell[cell] != -1 ) { + pndx = m_Grid [ m_GridCell[cell] ]; + while ( pndx != -1 ) { + pcurr = (Fluid*) (mBuf[0].data + pndx*mBuf[0].stride); + if ( pcurr == p ) {pndx = pcurr->next; continue; } + + dx = ( p->pos.x - pcurr->pos.x)*d; // dist in cm + dy = ( p->pos.y - pcurr->pos.y)*d; + dz = ( p->pos.z - pcurr->pos.z)*d; + dsq = (dx*dx + dy*dy + dz*dz); + if ( mR2 > dsq ) { + r = sqrt ( dsq ); + c = (mR - r); + pterm = -0.5f * c * m_SpikyKern * ( p->pressure + pcurr->pressure) / r; + dterm = c * p->density * pcurr->density; + vterm = m_LapKern * visc; + force.x += ( pterm * dx + vterm * (pcurr->vel_eval.x - p->vel_eval.x) ) * dterm; + force.y += ( pterm * dy + vterm * (pcurr->vel_eval.y - p->vel_eval.y) ) * dterm; + force.z += ( pterm * dz + vterm * (pcurr->vel_eval.z - p->vel_eval.z) ) * dterm; + } + pndx = pcurr->next; + } + } + } + p->sph_force = force; + } +} + +// Compute Forces - Using spatial grid with saved neighbor table. Fastest. +void FluidSystem::SPH_ComputeForceGridNC () +{ + char *dat1, *dat1_end; + Fluid *p; + Fluid *pcurr; + Vector3DF force, fcurr; + register float pterm, vterm, dterm; + int i; + float c, d; + float dx, dy, dz; + float mR, mR2, visc; + + d = m_Param[SPH_SIMSCALE]; + mR = m_Param[SPH_SMOOTHRADIUS]; + mR2 = (mR*mR); + visc = m_Param[SPH_VISC]; + + dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride; + i = 0; + + for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride, i++ ) { + p = (Fluid*) dat1; + + force.Set ( 0, 0, 0 ); + for (int j=0; j < m_NC[i]; j++ ) { + pcurr = (Fluid*) (mBuf[0].data + m_Neighbor[i][j]*mBuf[0].stride); + dx = ( p->pos.x - pcurr->pos.x)*d; // dist in cm + dy = ( p->pos.y - pcurr->pos.y)*d; + dz = ( p->pos.z - pcurr->pos.z)*d; + c = ( mR - m_NDist[i][j] ); + pterm = -0.5f * c * m_SpikyKern * ( p->pressure + pcurr->pressure) / m_NDist[i][j]; + dterm = c * p->density * pcurr->density; + vterm = m_LapKern * visc; + force.x += ( pterm * dx + vterm * (pcurr->vel_eval.x - p->vel_eval.x) ) * dterm; + force.y += ( pterm * dy + vterm * (pcurr->vel_eval.y - p->vel_eval.y) ) * dterm; + force.z += ( pterm * dz + vterm * (pcurr->vel_eval.z - p->vel_eval.z) ) * dterm; + } + p->sph_force = force; + } +} + diff --git a/Extras/sph/fluids/fluid_system.cu b/Extras/sph/fluids/fluid_system.cu new file mode 100644 index 0000000..f67eda7 --- /dev/null +++ b/Extras/sph/fluids/fluid_system.cu @@ -0,0 +1,71 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include +#include + +#if defined(__APPLE__) || defined(MACOSX) + #include +#else + #include +#endif +#include + +#include "fluid_system_kern.cu" + +extern "C" +{ + +// Compute number of blocks to create +int iDivUp (int a, int b) { + return (a % b != 0) ? (a / b + 1) : (a / b); +} +void computeNumBlocks (int numPnts, int minThreads, int &numBlocks, int &numThreads) +{ + numThreads = min( minThreads, numPnts ); + numBlocks = iDivUp ( numPnts, numThreads ); +} + + +void Grid_InsertParticlesCUDA ( uchar* data, uint stride, uint numPoints ) +{ + int numThreads, numBlocks; + computeNumBlocks (numPoints, 256, numBlocks, numThreads); + + // transfer point data to device + char* pntData; + size = numPoints * stride; + cudaMalloc( (void**) &pntData, size); + cudaMemcpy( pntData, data, size, cudaMemcpyHostToDevice); + + // execute the kernel + insertParticles<<< numBlocks, numThreads >>> ( pntData, stride ); + + // transfer data back to host + cudaMemcpy( data, pntData, cudaMemcpyDeviceToHost); + + // check if kernel invocation generated an error + CUT_CHECK_ERROR("Kernel execution failed"); + CUDA_SAFE_CALL(cudaGLUnmapBufferObject(vboPos)); +} \ No newline at end of file diff --git a/Extras/sph/fluids/fluid_system.h b/Extras/sph/fluids/fluid_system.h new file mode 100644 index 0000000..ddc1de3 --- /dev/null +++ b/Extras/sph/fluids/fluid_system.h @@ -0,0 +1,106 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef DEF_FLUID_SYS + #define DEF_FLUID_SYS + + #include + #include + #include + #include + #include + + #include "point_set.h" + #include "fluid.h" + + // Scalar params + #define SPH_SIMSIZE 4 + #define SPH_SIMSCALE 5 + #define SPH_VISC 6 + #define SPH_RESTDENSITY 7 + #define SPH_PMASS 8 + #define SPH_PRADIUS 9 + #define SPH_PDIST 10 + #define SPH_SMOOTHRADIUS 11 + #define SPH_INTSTIFF 12 + #define SPH_EXTSTIFF 13 + #define SPH_EXTDAMP 14 + #define SPH_LIMIT 15 + #define BOUND_ZMIN_SLOPE 16 + #define FORCE_XMAX_SIN 17 + #define FORCE_XMIN_SIN 18 + #define MAX_FRAC 19 + #define CLR_MODE 20 + + // Vector params + #define SPH_VOLMIN 7 + #define SPH_VOLMAX 8 + #define SPH_INITMIN 9 + #define SPH_INITMAX 10 + + // Toggles + #define SPH_GRID 0 + #define SPH_DEBUG 1 + #define WRAP_X 2 + #define WALL_BARRIER 3 + #define LEVY_BARRIER 4 + #define DRAIN_BARRIER 5 + #define USE_CUDA 6 + + #define MAX_PARAM 21 + #define BFLUID 2 + + class FluidSystem : public PointSet { + public: + FluidSystem (); + + // Basic Particle System + virtual void Initialize ( int mode, int nmax ); + virtual void Reset ( int nmax ); + virtual void Run (); + virtual void Advance (); + virtual int AddPoint (); + virtual int AddPointReuse (); + Fluid* AddFluid () { return (Fluid*) GetElem(0, AddPointReuse()); } + Fluid* GetFluid (int n) { return (Fluid*) GetElem(0, n); } + + // Smoothed Particle Hydrodynamics + void SPH_Setup (); + void SPH_CreateExample ( int n, int nmax ); + void SPH_DrawDomain (); + void SPH_ComputeKernels (); + + void SPH_ComputePressureSlow (); // O(n^2) + void SPH_ComputePressureGrid (); // O(kn) - spatial grid + + void SPH_ComputeForceSlow (); // O(n^2) + void SPH_ComputeForceGrid (); // O(kn) - spatial grid + void SPH_ComputeForceGridNC (); // O(cn) - neighbor table + + private: + + // Smoothed Particle Hydrodynamics + double m_R2, m_Poly6Kern, m_LapKern, m_SpikyKern; // Kernel functions + }; + +#endif diff --git a/Extras/sph/fluids/fluid_system_host.cu b/Extras/sph/fluids/fluid_system_host.cu new file mode 100644 index 0000000..07c5747 --- /dev/null +++ b/Extras/sph/fluids/fluid_system_host.cu @@ -0,0 +1,250 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +//#include "C:\CUDA\common\inc\cutil.h" // cutil32.lib +#include +#include "../CUDA/btCudaDefines.h" + + + +#if defined(__APPLE__) || defined(MACOSX) + #include +#else + #include +#endif +#include + +#include "radixsort.cu" +#include "fluid_system_kern.cu" // build kernel + +FluidParams fcuda; + +__device__ char* bufPnts; // point data (array of Fluid structs) +__device__ char* bufPntSort; // point data (array of Fluid structs) +__device__ uint* bufHash[2]; // point grid hash +__device__ int* bufGrid; + + + +extern "C" +{ +// Initialize CUDA +void cudaInit(int argc, char **argv) +{ + //CUT_DEVICE_INIT(argc, argv); + + cudaDeviceProp p; + cudaGetDeviceProperties ( &p, 0); + + printf ( "-- CUDA --\n" ); + printf ( "Name: %s\n", p.name ); + printf ( "Revision: %d.%d\n", p.major, p.minor ); + printf ( "Global Mem: %d\n", p.totalGlobalMem ); + printf ( "Shared/Blk: %d\n", p.sharedMemPerBlock ); + printf ( "Regs/Blk: %d\n", p.regsPerBlock ); + printf ( "Warp Size: %d\n", p.warpSize ); + printf ( "Mem Pitch: %d\n", p.memPitch ); + printf ( "Thrds/Blk: %d\n", p.maxThreadsPerBlock ); + printf ( "Const Mem: %d\n", p.totalConstMem ); + printf ( "Clock Rate: %d\n", p.clockRate ); + + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufPnts, 10 ) ); + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufPntSort, 10 ) ); + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufHash, 10 ) ); + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufGrid, 10 ) ); +}; + +// Compute number of blocks to create +int iDivUp (int a, int b) { + return (a % b != 0) ? (a / b + 1) : (a / b); +} +void computeNumBlocks (int numPnts, int maxThreads, int &numBlocks, int &numThreads) +{ + numThreads = min( maxThreads, numPnts ); + numBlocks = iDivUp ( numPnts, numThreads ); +} + +void FluidClearCUDA () +{ + BT_GPU_SAFE_CALL ( cudaFree ( bufPnts ) ); + BT_GPU_SAFE_CALL ( cudaFree ( bufPntSort ) ); + BT_GPU_SAFE_CALL ( cudaFree ( bufHash[0] ) ); + BT_GPU_SAFE_CALL ( cudaFree ( bufHash[1] ) ); + BT_GPU_SAFE_CALL ( cudaFree ( bufGrid ) ); +} + + +void FluidSetupCUDA ( int num, int stride, float3 min, float3 max, float3 res, float3 size, int chk ) +{ + fcuda.min = make_float3(min.x, min.y, min.z); + fcuda.max = make_float3(max.x, max.y, max.z); + fcuda.res = make_float3(res.x, res.y, res.z); + fcuda.size = make_float3(size.x, size.y, size.z); + fcuda.pnts = num; + fcuda.delta.x = res.x / size.x; + fcuda.delta.y = res.y / size.y; + fcuda.delta.z = res.z / size.z; + fcuda.cells = res.x*res.y*res.z; + fcuda.chk = chk; + + computeNumBlocks ( fcuda.pnts, 256, fcuda.numBlocks, fcuda.numThreads); // particles + computeNumBlocks ( fcuda.cells, 256, fcuda.gridBlocks, fcuda.gridThreads); // grid cell + + fcuda.szPnts = (fcuda.numBlocks * fcuda.numThreads) * stride; + fcuda.szHash = (fcuda.numBlocks * fcuda.numThreads) * sizeof(uint2); // pairs + fcuda.szGrid = (fcuda.gridBlocks * fcuda.gridThreads) * sizeof(uint); + fcuda.stride = stride; + printf ( "pnts: %d, t:%dx%d=%d, bufPnts:%d, bufHash:%d\n", fcuda.pnts, fcuda.numBlocks, fcuda.numThreads, fcuda.numBlocks*fcuda.numThreads, fcuda.szPnts, fcuda.szHash ); + printf ( "grds: %d, t:%dx%d=%d, bufGrid:%d, Res: %dx%dx%d\n", fcuda.cells, fcuda.gridBlocks, fcuda.gridThreads, fcuda.gridBlocks*fcuda.gridThreads, fcuda.szGrid, (int) fcuda.res.x, (int) fcuda.res.y, (int) fcuda.res.z ); + + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufPnts, fcuda.szPnts ) ); + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufPntSort, fcuda.szPnts ) ); + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufHash[0], fcuda.szHash ) ); + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufHash[1], fcuda.szHash ) ); + BT_GPU_SAFE_CALL ( cudaMalloc ( (void**) &bufGrid, fcuda.szGrid ) ); + + printf ( "POINTERS\n"); + printf ( "bufPnts: %p\n", bufPnts ); + printf ( "bufPntSort: %p\n", bufPntSort ); + printf ( "bufHash0: %p\n", bufHash[0] ); + printf ( "bufHash1: %p\n", bufHash[1] ); + printf ( "bufGrid: %p\n", bufGrid ); + + BT_GPU_SAFE_CALL ( cudaMemcpyToSymbol ( simData, &fcuda, sizeof(FluidParams) ) ); + cudaThreadSynchronize (); +} + +void FluidParamCUDA ( float sim_scale, float smooth_rad, float mass, float rest, float stiff, float visc ) +{ + fcuda.sim_scale = sim_scale; + fcuda.smooth_rad = smooth_rad; + fcuda.r2 = smooth_rad * smooth_rad; + fcuda.pmass = mass; + fcuda.rest_dens = rest; + fcuda.stiffness = stiff; + fcuda.visc = visc; + + fcuda.pdist = pow ( fcuda.pmass / fcuda.rest_dens, 1/3.0f ); + fcuda.poly6kern = 315.0f / (64.0f * 3.141592 * pow( smooth_rad, 9.0f) ); + fcuda.spikykern = -45.0f / (3.141592 * pow( smooth_rad, 6.0f) ); + fcuda.lapkern = 45.0f / (3.141592 * pow( smooth_rad, 6.0f) ); + + BT_GPU_SAFE_CALL( cudaMemcpyToSymbol ( simData, &fcuda, sizeof(FluidParams) ) ); + cudaThreadSynchronize (); +} + +void TransferToCUDA ( char* data, int* grid, int numPoints ) +{ + BT_GPU_SAFE_CALL( cudaMemcpy ( bufPnts, data, numPoints * fcuda.stride, cudaMemcpyHostToDevice ) ); + cudaThreadSynchronize (); +} + +void TransferFromCUDA ( char* data, int* grid, int numPoints ) +{ + BT_GPU_SAFE_CALL( cudaMemcpy ( data, bufPntSort, numPoints * fcuda.stride, cudaMemcpyDeviceToHost ) ); + cudaThreadSynchronize (); + + BT_GPU_SAFE_CALL( cudaMemcpy ( grid, bufGrid, fcuda.cells * sizeof(uint), cudaMemcpyDeviceToHost ) ); +} + +void Grid_InsertParticlesCUDA () +{ + BT_GPU_SAFE_CALL( cudaMemset ( bufHash[0], 0, fcuda.szHash ) ); + + hashParticles<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPnts, (uint2*) bufHash[0], fcuda.pnts ); + BT_GPU_CHECK_ERROR( "Kernel execution failed"); + cudaThreadSynchronize (); + + //int buf[20000]; + /*printf ( "HASH: %d (%d)\n", fcuda.pnts, fcuda.numBlocks*fcuda.numThreads ); + BT_GPU_SAFE_CALL( cudaMemcpy ( buf, bufHash[0], fcuda.pnts * 2*sizeof(uint), cudaMemcpyDeviceToHost ) ); + //for (int n=0; n < fcuda.numBlocks*fcuda.numThreads; n++) { + for (int n=0; n < 100; n++) { + printf ( "%d: <%d,%d>\n", n, buf[n*2], buf[n*2+1] ); + }*/ + + RadixSort( (KeyValuePair *) bufHash[0], (KeyValuePair *) bufHash[1], fcuda.pnts, 32); + BT_GPU_CHECK_ERROR( "Kernel execution failed"); + cudaThreadSynchronize (); + + /*printf ( "HASH: %d (%d)\n", fcuda.pnts, fcuda.numBlocks*fcuda.numThreads ); + BT_GPU_SAFE_CALL( cudaMemcpy ( buf, bufHash[0], fcuda.pnts * 2*sizeof(uint), cudaMemcpyDeviceToHost ) ); + //for (int n=0; n < fcuda.numBlocks*fcuda.numThreads; n++) { + for (int n=0; n < 100; n++) { + printf ( "%d: <%d,%d>\n", n, buf[n*2], buf[n*2+1] ); + }*/ + + // insertParticles<<< fcuda.gridBlocks, fcuda.gridThreads>>> ( bufPnts, (uint2*) bufHash[0], bufGrid, fcuda.pnts, fcuda.cells ); + + BT_GPU_SAFE_CALL( cudaMemset ( bufGrid, NULL_HASH, fcuda.cells * sizeof(uint) ) ); + + insertParticlesRadix<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPnts, (uint2*) bufHash[0], bufGrid, bufPntSort, fcuda.pnts, fcuda.cells ); + BT_GPU_CHECK_ERROR( "Kernel execution failed"); + cudaThreadSynchronize (); + + /*printf ( "GRID: %d\n", fcuda.cells ); + BT_GPU_SAFE_CALL( cudaMemcpy ( buf, bufGrid, fcuda.cells * sizeof(uint), cudaMemcpyDeviceToHost ) ); + *for (int n=0; n < 100; n++) { + printf ( "%d: %d\n", n, buf[n]); + }*/ +} + +void SPH_ComputePressureCUDA () +{ + computePressure<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, bufGrid, (uint2*) bufHash[0], fcuda.pnts ); + BT_GPU_CHECK_ERROR( "Kernel execution failed"); + cudaThreadSynchronize (); +} + +void SPH_ComputeForceCUDA () +{ + //-- standard force + //computeForce<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, bufGrid, (uint2*) bufHash[0], fcuda.pnts ); + + // Force using neighbor table + computeForceNbr<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, fcuda.pnts ); + BT_GPU_CHECK_ERROR( "Kernel execution failed"); + cudaThreadSynchronize (); +} + +void SPH_AdvanceCUDA ( float dt, float ss ) +{ + advanceParticles<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, fcuda.pnts, dt, ss ); + BT_GPU_CHECK_ERROR( "Kernel execution failed"); + cudaThreadSynchronize (); +} + +} // extern C + + + + + //----------- Per frame: Malloc/Free, Host<->Device + // transfer point data to device + /*char* pntData; + int size = (fcuda.numBlocks*fcuda.numThreads) * stride; + cudaMalloc( (void**) &pntData, size); + cudaMemcpy( pntData, data, numPoints*stride, cudaMemcpyHostToDevice); + insertParticles<<< fcuda.numBlocks, fcuda.numThreads >>> ( pntData, stride, numPoints ); + cudaMemcpy( data, pntData, numPoints*stride, cudaMemcpyDeviceToHost); + cudaFree( pntData );*/ diff --git a/Extras/sph/fluids/fluid_system_host.cuh b/Extras/sph/fluids/fluid_system_host.cuh new file mode 100644 index 0000000..355b57d --- /dev/null +++ b/Extras/sph/fluids/fluid_system_host.cuh @@ -0,0 +1,63 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +#include +#include // for cudaStream_t + +typedef unsigned int uint; // should be 4-bytes on CUDA +typedef unsigned char uchar; // should be 1-bytes on CUDA + +struct FluidParams { + int numThreads, numBlocks; + int gridThreads, gridBlocks; + int szPnts, szHash, szGrid; + int stride, pnts, cells; + int chk; + float smooth_rad, r2, sim_scale, visc; + float3 min, max, res, size, delta; + + float pdist, pmass, rest_dens, stiffness; + float poly6kern, spikykern, lapkern; + +}; + +extern "C" +{ + +void cudaInit(int argc, char **argv); + +void FluidClearCUDA (); +void FluidSetupCUDA ( int num, int stride, float3 min, float3 max, float3 res, float3 size, int chk ); +void FluidParamCUDA ( float sim_scale, float smooth_rad, float mass, float rest, float stiff, float visc ); + +void TransferToCUDA ( char* data, int* grid, int numPoints ); +void TransferFromCUDA ( char* data, int* grid, int numPoints ); + +void Grid_InsertParticlesCUDA (); +void SPH_ComputePressureCUDA (); +void SPH_ComputeForceCUDA (); +void SPH_AdvanceCUDA ( float dt, float ss ); + +} + + diff --git a/Extras/sph/fluids/fluid_system_kern.cu b/Extras/sph/fluids/fluid_system_kern.cu new file mode 100644 index 0000000..235b463 --- /dev/null +++ b/Extras/sph/fluids/fluid_system_kern.cu @@ -0,0 +1,402 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef _PARTICLES_KERNEL_H_ + #define _PARTICLES_KERNEL_H_ + + #include + #include + + #include "fluid_system_host.cuh" + + #define TOTAL_THREADS 65536 + #define BLOCK_THREADS 256 + #define MAX_NBR 80 + + __constant__ FluidParams simData; // simulation data (on device) + + __device__ int bufNeighbor[ TOTAL_THREADS*MAX_NBR ]; + __device__ float bufNdist[ TOTAL_THREADS*MAX_NBR ]; + + #define COLOR(r,g,b) ( (uint((r)*255.0f)<<24) | (uint((g)*255.0f)<<16) | (uint((b)*255.0f)<<8) ) + #define COLORA(r,g,b,a) ( (uint((r)*255.0f)<<24) | (uint((g)*255.0f)<<16) | (uint((b)*255.0f)<<8) | uint((a)*255.0f) ) + + #define NULL_HASH 333333 + + #define OFFSET_CLR 12 + #define OFFSET_NEXT 16 + #define OFFSET_VEL 20 + #define OFFSET_VEVAL 32 + #define OFFSET_PRESS 48 + #define OFFSET_DENS 52 + #define OFFSET_FORCE 56 + + + __global__ void hashParticles ( char* bufPnts, uint2* bufHash, int numPnt ) + { + uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index + float3* pos = (float3*) (bufPnts + __mul24(ndx, simData.stride) ); + int gz = (pos->z - simData.min.z) * simData.delta.z ; + int gy = (pos->y - simData.min.y) * simData.delta.y ; + int gx = (pos->x - simData.min.x) * simData.delta.x ; + if ( ndx >= numPnt || gx < 0 || gz > simData.res.x-1 || gy < 0 || gy > simData.res.y-1 || gz < 0 || gz > simData.res.z-1 ) + bufHash[ndx] = make_uint2( NULL_HASH, ndx ); + else + bufHash[ndx] = make_uint2( __mul24(__mul24(gz, (int) simData.res.y)+gy, (int) simData.res.x) + gx, ndx ); + + __syncthreads (); + } + + __global__ void insertParticles ( char* bufPnts, uint2* bufHash, int* bufGrid, int numPnt, int numGrid ) + { + uint grid_ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // grid cell index + + bufPnts += OFFSET_NEXT; + bufGrid[grid_ndx] = -1; + for (int n=0; n < numPnt; n++) { + if ( bufHash[n].x == grid_ndx ) { + *(int*) (bufPnts + __mul24(bufHash[n].y, simData.stride)) = bufGrid[grid_ndx]; + bufGrid[grid_ndx] = bufHash[n].y; + } + } + __syncthreads (); + } + + __global__ void insertParticlesRadix ( char* bufPnts, uint2* bufHash, int* bufGrid, char* bufPntSort, int numPnt, int numGrid ) + { + uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index + + uint2 bufHashSort = bufHash[ndx]; + + __shared__ uint sharedHash[257]; + sharedHash[threadIdx.x+1] = bufHashSort.x; + if ( ndx > 0 && threadIdx.x == 0 ) { + volatile uint2 prevData = bufHash[ndx-1]; + sharedHash[0] = prevData.x; + } + __syncthreads (); + + if ( (ndx == 0 || bufHashSort.x != sharedHash[threadIdx.x]) && bufHashSort.x != NULL_HASH ) { + bufGrid [ bufHashSort.x ] = ndx; + } + if ( ndx < numPnt ) { + char* src = bufPnts + __mul24( bufHashSort.y, simData.stride ); + char* dest = bufPntSort + __mul24( ndx, simData.stride ); + + *(float3*)(dest) = *(float3*)(src); + *(uint*) (dest + OFFSET_CLR) = *(uint*) (src + OFFSET_CLR); + *(float3*)(dest + OFFSET_VEL) = *(float3*)(src + OFFSET_VEL); + *(float3*)(dest + OFFSET_VEVAL) = *(float3*)(src + OFFSET_VEVAL); + + *(float*) (dest + OFFSET_DENS) = 0.0; + *(float*) (dest + OFFSET_PRESS) = 0.0; + *(float3*) (dest + OFFSET_FORCE)= make_float3(0,0,0); + *(int*) (dest + OFFSET_NEXT) = bufHashSort.x; + } + + __syncthreads (); + + } + + //__shared__ int ncount [ BLOCK_THREADS ]; + + __device__ float contributePressure ( int pndx, float3* p, int qndx, int grid_ndx, char* bufPnts, uint2* bufHash ) + { + float3* qpos; + float3 dist; + float dsq, c, sum; + float d = simData.sim_scale; + int nbr = __mul24(pndx, MAX_NBR); + + sum = 0.0; + for ( ; qndx < simData.pnts; qndx++ ) { + + if ( bufHash[qndx].x != grid_ndx || qndx == NULL_HASH) break; + + if ( qndx != pndx ) { + qpos = (float3*) ( bufPnts + __mul24(qndx, simData.stride )); + + dist.x = ( p->x - qpos->x )*d; // dist in cm + dist.y = ( p->y - qpos->y )*d; + dist.z = ( p->z - qpos->z )*d; + dsq = (dist.x*dist.x + dist.y*dist.y + dist.z*dist.z); + if ( dsq < simData.r2 ) { + c = simData.r2 - dsq; + sum += c * c * c; + if ( bufNeighbor[nbr] < MAX_NBR ) { + bufNeighbor[ nbr+bufNeighbor[nbr] ] = qndx; + bufNdist[ nbr+bufNeighbor[nbr] ] = sqrt(dsq); + bufNeighbor[nbr]++; + } + } + } + //curr = *(int*) (bufPnts + __mul24(curr, simData.stride) + OFFSET_NEXT); + } + return sum; + } + + /*if ( ncount[threadIdx.x] < MAX_NBR ) { + bufNeighbor [ nbr + ncount[threadIdx.x] ] = curr; + bufNdist [ nbr + ncount[threadIdx.x] ] = sqrt(dsq); + ncount[threadIdx.x]++; + }*/ + + __global__ void computePressure ( char* bufPntSort, int* bufGrid, uint2* bufHash, int numPnt ) + { + uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index + + //if ( ndx < 1024 ) { + + float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride)); + + // Find 2x2x2 grid cells + // - Use registers only, no arrays (local-memory too slow) + int3 cell; + int gc0, gc1, gc2, gc3, gc4, gc5, gc6, gc7; + float gs = simData.smooth_rad / simData.sim_scale; + + cell.x = max(0, (int)((-gs + pos->x - simData.min.x) * simData.delta.x)); + cell.y = max(0, (int)((-gs + pos->y - simData.min.y) * simData.delta.y)); + cell.z = max(0, (int)((-gs + pos->z - simData.min.z) * simData.delta.z)); + gc0 = __mul24(__mul24(cell.z, simData.res.y) + cell.y, simData.res.x) + cell.x; + gc1 = gc0 + 1; + gc2 = gc0 + simData.res.x; + gc3 = gc2 + 1; + if ( cell.z+1 < simData.res.z ) { + gc4 = gc0 + __mul24(simData.res.x, simData.res.y); + gc5 = gc4 + 1; + gc6 = gc4 + simData.res.x; + gc7 = gc6 + 1; + } + if ( cell.x+1 >= simData.res.x ) { + gc1 = -1; gc3 = -1; + gc5 = -1; gc7 = -1; + } + if ( cell.y+1 >= simData.res.y ) { + gc2 = -1; gc3 = -1; + gc6 = -1; gc7 = -1; + } + // Sum Pressure + float sum = 0.0; + bufNeighbor[ __mul24(ndx, MAX_NBR) ] = 1; + if (gc0 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc0], gc0, bufPntSort, bufHash ); + if (gc1 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc1], gc1, bufPntSort, bufHash ); + if (gc2 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc2], gc2, bufPntSort, bufHash ); + if (gc3 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc3], gc3, bufPntSort, bufHash ); + if (gc4 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc4], gc4, bufPntSort, bufHash ); + if (gc5 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc5], gc5, bufPntSort, bufHash ); + if (gc6 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc6], gc6, bufPntSort, bufHash ); + if (gc7 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc7], gc7, bufPntSort, bufHash ); + + // Compute Density & Pressure + sum = sum * simData.pmass * simData.poly6kern; + if ( sum == 0.0 ) sum = 1.0; + *(float*) ((char*)pos + OFFSET_PRESS) = ( sum - simData.rest_dens ) * simData.stiffness; + *(float*) ((char*)pos + OFFSET_DENS) = 1.0f / sum; + + //} + //__syncthreads (); + } + + __device__ void contributeForce ( float3& force, int pndx, float3* p, int qndx, int grid_ndx, char* bufPnts, uint2* bufHash ) + { + float press = *(float*) ((char*)p + OFFSET_PRESS); + float dens = *(float*) ((char*)p + OFFSET_DENS); + float3 veval = *(float3*) ((char*)p + OFFSET_VEVAL ); + float3 qeval, dist; + float c, ndistj, dsq; + float pterm, dterm, vterm; + float3* qpos; + float d = simData.sim_scale; + + vterm = simData.lapkern * simData.visc; + + for ( ; qndx < simData.pnts; qndx++ ) { + + if ( bufHash[qndx].x != grid_ndx || qndx == NULL_HASH) break; + + if ( qndx != pndx ) { + qpos = (float3*) ( bufPnts + __mul24(qndx, simData.stride )); + + dist.x = ( p->x - qpos->x )*d; // dist in cm + dist.y = ( p->y - qpos->y )*d; + dist.z = ( p->z - qpos->z )*d; + dsq = (dist.x*dist.x + dist.y*dist.y + dist.z*dist.z); + if ( dsq < simData.r2 ) { + ndistj = sqrt(dsq); + c = ( simData.smooth_rad - ndistj ); + dist.x = ( p->x - qpos->x )*d; // dist in cm + dist.y = ( p->y - qpos->y )*d; + dist.z = ( p->z - qpos->z )*d; + pterm = -0.5f * c * simData.spikykern * ( press + *(float*)((char*)qpos+OFFSET_PRESS) ) / ndistj; + dterm = c * dens * *(float*)((char*)qpos+OFFSET_DENS); + qeval = *(float3*)((char*)qpos+OFFSET_VEVAL); + force.x += ( pterm * dist.x + vterm * ( qeval.x - veval.x )) * dterm; + force.y += ( pterm * dist.y + vterm * ( qeval.y - veval.y )) * dterm; + force.z += ( pterm * dist.z + vterm * ( qeval.z - veval.z )) * dterm; + } + } + } + } + + + + __global__ void computeForce ( char* bufPntSort, int* bufGrid, uint2* bufHash, int numPnt ) + { + uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index + + //if ( ndx < numPnt ) { + + float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride)); + + // Find 2x2x2 grid cells + // - Use registers only, no arrays (local-memory too slow) + int3 cell; + int gc0, gc1, gc2, gc3, gc4, gc5, gc6, gc7; + float gs = simData.smooth_rad / simData.sim_scale; + + cell.x = max(0, (int)((-gs + pos->x - simData.min.x) * simData.delta.x)); + cell.y = max(0, (int)((-gs + pos->y - simData.min.y) * simData.delta.y)); + cell.z = max(0, (int)((-gs + pos->z - simData.min.z) * simData.delta.z)); + gc0 = __mul24(__mul24(cell.z, simData.res.y) + cell.y, simData.res.x) + cell.x; + gc1 = gc0 + 1; + gc2 = gc0 + simData.res.x; + gc3 = gc2 + 1; + if ( cell.z+1 < simData.res.z ) { + gc4 = gc0 + __mul24(simData.res.x, simData.res.y); + gc5 = gc4 + 1; + gc6 = gc4 + simData.res.x; + gc7 = gc6 + 1; + } + if ( cell.x+1 >= simData.res.x ) { + gc1 = -1; gc3 = -1; + gc5 = -1; gc7 = -1; + } + if ( cell.y+1 >= simData.res.y ) { + gc2 = -1; gc3 = -1; + gc6 = -1; gc7 = -1; + } + // Sum Pressure + float3 force = make_float3(0,0,0); + if (gc0 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc0], gc0, bufPntSort, bufHash ); + if (gc1 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc1], gc1, bufPntSort, bufHash ); + if (gc2 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc2], gc2, bufPntSort, bufHash ); + if (gc3 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc3], gc3, bufPntSort, bufHash ); + if (gc4 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc4], gc4, bufPntSort, bufHash ); + if (gc5 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc5], gc5, bufPntSort, bufHash ); + if (gc6 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc6], gc6, bufPntSort, bufHash ); + if (gc7 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc7], gc7, bufPntSort, bufHash ); + + // Update Force + *(float3*) ((char*)pos + OFFSET_FORCE ) = force; + + //} + //__syncthreads (); + } + + + __global__ void computeForceNbr ( char* bufPntSort, int numPnt ) + { + uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index + + if ( ndx < numPnt ) { + + float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride)); + + float3* qpos; + float press = *(float*) ((char*)pos + OFFSET_PRESS); + float dens = *(float*) ((char*)pos + OFFSET_DENS); + float3 veval = *(float3*) ((char*)pos + OFFSET_VEVAL ); + float3 qeval, dist, force; + float d = simData.sim_scale; + float c, ndistj; + float pterm, dterm, vterm; + vterm = simData.lapkern * simData.visc; + int nbr = __mul24(ndx, MAX_NBR); + + int ncnt = bufNeighbor[ nbr ]; + + force = make_float3(0,0,0); + for (int j=1; j < ncnt; j++) { // base 1, n[0] = count + ndistj = bufNdist[ nbr+j ]; + qpos = (float3*) (bufPntSort + __mul24( bufNeighbor[ nbr+j ], simData.stride) ); + c = ( simData.smooth_rad - ndistj ); + dist.x = ( pos->x - qpos->x )*d; // dist in cm + dist.y = ( pos->y - qpos->y )*d; + dist.z = ( pos->z - qpos->z )*d; + pterm = -0.5f * c * simData.spikykern * ( press + *(float*)((char*)qpos+OFFSET_PRESS) ) / ndistj; + dterm = c * dens * *(float*)((char*)qpos+OFFSET_DENS); + qeval = *(float3*)((char*)qpos+OFFSET_VEVAL); + force.x += ( pterm * dist.x + vterm * ( qeval.x - veval.x )) * dterm; + force.y += ( pterm * dist.y + vterm * ( qeval.y - veval.y )) * dterm; + force.z += ( pterm * dist.z + vterm * ( qeval.z - veval.z )) * dterm; + } + *(float3*) ((char*)pos + OFFSET_FORCE ) = force; + + } + + } + + __global__ void advanceParticles ( char* bufPntSort, int numPnt, float dt, float ss ) + { + uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index + + if ( ndx < numPnt ) { + + // Get particle vars + float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride)); + float3* vel = (float3*) ((char*)pos + OFFSET_VEL ); + float3* vel_eval = (float3*) ((char*)pos + OFFSET_VEVAL ); + float3 accel = *(float3*) ((char*)pos + OFFSET_FORCE ); + float3 vcurr, vnext; + + // Leapfrog integration + accel.x *= 0.00020543; // NOTE - To do: SPH_PMASS should be passed in + accel.y *= 0.00020543; + accel.z *= 0.00020543; + accel.z -= 9.8; + + vcurr = *vel; + vnext.x = accel.x*dt + vcurr.x; + vnext.y = accel.y*dt + vcurr.y; + vnext.z = accel.z*dt + vcurr.z; // v(t+1/2) = v(t-1/2) + a(t) dt + + accel.x = (vcurr.x + vnext.x) * 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later + accel.y = (vcurr.y + vnext.y) * 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later + accel.z = (vcurr.z + vnext.z) * 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later + + *vel_eval = accel; + *vel = vnext; + + dt /= simData.sim_scale; + vnext.x = pos->x + vnext.x*dt; + vnext.y = pos->y + vnext.y*dt; + vnext.z = pos->z + vnext.z*dt; + *pos = vnext; // p(t+1) = p(t) + v(t+1/2) dt + } + + __syncthreads (); + } + +#endif diff --git a/Extras/sph/fluids/fluid_system_kern.cuh b/Extras/sph/fluids/fluid_system_kern.cuh new file mode 100644 index 0000000..c1f0d81 --- /dev/null +++ b/Extras/sph/fluids/fluid_system_kern.cuh @@ -0,0 +1,45 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _PARTICLES_KERNEL_H_ + #define _PARTICLES_KERNEL_H_ + + #include + #include + #include "cutil_math.h" + #include "math_constants.h" + + // Insert particles in grid + + __global__ void insertParticles ( char* pntData, uint pntStride ) + { + int index = __mul24(blockIdx.x,blockDim.x) + threadIdx.x; + float4 p = *(float4*) (pntData + index*pntStride); + + // get address in grid + int3 gridPos = calcGridPos(p); + + addParticleToCell(gridPos, index, gridCounters, gridCells); + } + + +#endif diff --git a/Extras/sph/fluids/radixsort.cu b/Extras/sph/fluids/radixsort.cu new file mode 100644 index 0000000..24c85c6 --- /dev/null +++ b/Extras/sph/fluids/radixsort.cu @@ -0,0 +1,79 @@ +/* + * Copyright 1993-2006 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + */ + +/* Radixsort project with key/value and arbitrary datset size support + * which demonstrates the use of CUDA in a multi phase sorting + * computation. + * Host code. + */ + +#include "radixsort.cuh" +#include "radixsort_kernel.cu" + +extern "C" +{ + +//////////////////////////////////////////////////////////////////////////////// +//! Perform a radix sort +//! Sorting performed in place on passed arrays. +//! +//! @param pData0 input and output array - data will be sorted +//! @param pData1 additional array to allow ping pong computation +//! @param elements number of elements to sort +//////////////////////////////////////////////////////////////////////////////// +void RadixSort(KeyValuePair *pData0, KeyValuePair *pData1, uint elements, uint bits) +{ + // Round element count to total number of threads for efficiency + uint elements_rounded_to_3072; + int modval = elements % 3072; + if( modval == 0 ) + elements_rounded_to_3072 = elements; + else + elements_rounded_to_3072 = elements + (3072 - (modval)); + + // Iterate over n bytes of y bit word, using each byte to sort the list in turn + for (uint shift = 0; shift < bits; shift += RADIX) + { + // Perform one round of radix sorting + + // Generate per radix group sums radix counts across a radix group + RadixSum<<>>(pData0, elements, elements_rounded_to_3072, shift); + // Prefix sum in radix groups, and then between groups throughout a block + RadixPrefixSum<<>>(); + // Sum the block offsets and then shuffle data into bins + RadixAddOffsetsAndShuffle<<>>(pData0, pData1, elements, elements_rounded_to_3072, shift); + + // Exchange data pointers + KeyValuePair* pTemp = pData0; + pData0 = pData1; + pData1 = pTemp; + } +} + +} diff --git a/Extras/sph/fluids/radixsort.cuh b/Extras/sph/fluids/radixsort.cuh new file mode 100644 index 0000000..538bb11 --- /dev/null +++ b/Extras/sph/fluids/radixsort.cuh @@ -0,0 +1,63 @@ +/* + * Copyright 1993-2006 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + */ + +/* Radixsort project which demonstrates the use of CUDA in a multi phase + * sorting computation. + * Type definitions. + */ + +#ifndef _RADIXSORT_H_ +#define _RADIXSORT_H_ + +#include + +#define SYNCIT __syncthreads() + +// Use 16 bit keys/values +#define SIXTEEN 0 + +typedef unsigned int uint; +typedef unsigned short ushort; + +#if SIXTEEN +typedef struct __align__(4) { + ushort key; + ushort value; +#else +typedef struct __align__(8) { + uint key; + uint value; +#endif +} KeyValuePair; + +extern "C" { + void RadixSort(KeyValuePair *pData0, KeyValuePair *pData1, uint elements, uint bits); +} + +#endif // #ifndef _RADIXSORT_H_ diff --git a/Extras/sph/fluids/radixsort_kernel.cu b/Extras/sph/fluids/radixsort_kernel.cu new file mode 100644 index 0000000..dad689b --- /dev/null +++ b/Extras/sph/fluids/radixsort_kernel.cu @@ -0,0 +1,577 @@ +/* + * Copyright 1993-2006 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + */ + +/* Radixsort project with key/value and arbitrary datset size support + * which demonstrates the use of CUDA in a multi phase sorting + * computation. + * Device code. + */ + +#ifndef _RADIXSORT_KERNEL_H_ +#define _RADIXSORT_KERNEL_H_ + +#include +#include "radixsort.cuh" + +#define SYNCIT __syncthreads() + +static const int NUM_SMS = 16; +static const int NUM_THREADS_PER_SM = 192; +static const int NUM_THREADS_PER_BLOCK = 64; +//static const int NUM_THREADS = NUM_THREADS_PER_SM * NUM_SMS; +static const int NUM_BLOCKS = (NUM_THREADS_PER_SM / NUM_THREADS_PER_BLOCK) * NUM_SMS; +static const int RADIX = 8; // Number of bits per radix sort pass +static const int RADICES = 1 << RADIX; // Number of radices +static const int RADIXMASK = RADICES - 1; // Mask for each radix sort pass +#if SIXTEEN +static const int RADIXBITS = 16; // Number of bits to sort over +#else +static const int RADIXBITS = 32; // Number of bits to sort over +#endif +static const int RADIXTHREADS = 16; // Number of threads sharing each radix counter +static const int RADIXGROUPS = NUM_THREADS_PER_BLOCK / RADIXTHREADS; // Number of radix groups per CTA +static const int TOTALRADIXGROUPS = NUM_BLOCKS * RADIXGROUPS; // Number of radix groups for each radix +static const int SORTRADIXGROUPS = TOTALRADIXGROUPS * RADICES; // Total radix count +static const int GRFELEMENTS = (NUM_THREADS_PER_BLOCK / RADIXTHREADS) * RADICES; +static const int GRFSIZE = GRFELEMENTS * sizeof(uint); + +// Prefix sum variables +static const int PREFIX_NUM_THREADS_PER_SM = NUM_THREADS_PER_SM; +static const int PREFIX_NUM_THREADS_PER_BLOCK = PREFIX_NUM_THREADS_PER_SM; +static const int PREFIX_NUM_BLOCKS = (PREFIX_NUM_THREADS_PER_SM / PREFIX_NUM_THREADS_PER_BLOCK) * NUM_SMS; +static const int PREFIX_BLOCKSIZE = SORTRADIXGROUPS / PREFIX_NUM_BLOCKS; +static const int PREFIX_GRFELEMENTS = PREFIX_BLOCKSIZE + 2 * PREFIX_NUM_THREADS_PER_BLOCK; +static const int PREFIX_GRFSIZE = PREFIX_GRFELEMENTS * sizeof(uint); + +// Shuffle variables +static const int SHUFFLE_GRFOFFSET = RADIXGROUPS * RADICES; +static const int SHUFFLE_GRFELEMENTS = SHUFFLE_GRFOFFSET + PREFIX_NUM_BLOCKS; +static const int SHUFFLE_GRFSIZE = SHUFFLE_GRFELEMENTS * sizeof(uint); + + +#define SDATA( index) CUT_BANK_CHECKER(sdata, index) + +// Prefix sum data +uint gRadixSum[TOTALRADIXGROUPS * RADICES]; +__device__ uint dRadixSum[TOTALRADIXGROUPS * RADICES]; +uint gRadixBlockSum[PREFIX_NUM_BLOCKS]; +__device__ uint dRadixBlockSum[PREFIX_NUM_BLOCKS]; + +extern __shared__ uint sRadixSum[]; + + + +//////////////////////////////////////////////////////////////////////////////// +//! Perform a radix sum on the list to be sorted. Each SM holds a set of +//! radix counters for each group of RADIXGROUPS thread in the GRF. +//! +//! @param pData input data +//! @param elements total number of elements +//! @param elements_rounded_to_3072 total number of elements rounded up to the +//! nearest multiple of 3072 +//! @param shift the shift (0 to 24) that we are using to obtain the correct +//! byte +//////////////////////////////////////////////////////////////////////////////// +__global__ void RadixSum(KeyValuePair *pData, uint elements, uint elements_rounded_to_3072, uint shift) +{ + uint pos = threadIdx.x; + + // Zero radix counts + while (pos < GRFELEMENTS) + { + sRadixSum[pos] = 0; + pos += NUM_THREADS_PER_BLOCK; + } + + // Sum up data + // Source addresses computed so that each thread is reading from a block of + // consecutive addresses so there are no conflicts between threads + // They then loop over their combined region and the next batch works elsewhere. + // So threads 0 to 16 work on memory 0 to 320. + // First reading 0,1,2,3...15 then 16,17,18,19...31 and so on + // optimising parallel access to shared memory by a thread accessing 16*threadID + // The next radix group runs from 320 to 640 and the same applies in that region + uint tmod = threadIdx.x % RADIXTHREADS; + uint tpos = threadIdx.x / RADIXTHREADS; + + // Take the rounded element list size so that all threads have a certain size dataset to work with + // and no zero size datasets confusing the issue + // By using a multiple of 3072 we ensure that all threads have elements + // to work with until the last phase, at which point we individually test + uint element_fraction = elements_rounded_to_3072 / TOTALRADIXGROUPS; + + // Generate range + // Note that it is possible for both pos and end to be past the end of the element set + // which will be caught later. + pos = (blockIdx.x * RADIXGROUPS + tpos) * element_fraction; + uint end = pos + element_fraction; + pos += tmod; + //printf("pos: %d\n", pos); + __syncthreads(); + + while (pos < end ) + { + uint key = 0; + + // Read first data element if we are in the set of elements + //if( pos < elements ) + //key = pData[pos].key; + KeyValuePair kvp; + // Read first data element, both items at once as the memory will want to coalesce like that anyway + if (pos < elements) + kvp = pData[pos]; + else + kvp.key = 0; + key = kvp.key; + + + // Calculate position of radix counter to increment + // There are RADICES radices in each pass (256) + // and hence this many counters for bin grouping + // Multiply by RADIXGROUPS (4) to spread through memory + // and into 4 radix groups + uint p = ((key >> shift) & RADIXMASK) * RADIXGROUPS; + + // Increment radix counters + // Each radix group has its own set of counters + // so we add the thread position [0-3], ie the group index. + // We slow down here and take at least 16 cycles to write to the summation boxes + // but other groups will only conflict with themselves and so can also be writing + // 16 cycles here at least avoids retries. + uint ppos = p + tpos; + + // If we are past the last element we don't want to do anything + // We do have to check each time, however, to ensure that all + // threads sync on each sync here. + if (tmod == 0 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 1 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 2 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 3 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 4 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 5 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 6 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 7 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 8 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 9 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 10 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 11 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 12 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 13 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 14 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + if (tmod == 15 && pos < elements) + sRadixSum[ppos]++; + SYNCIT; + + pos += RADIXTHREADS; + + } + + __syncthreads(); + + __syncthreads(); + + // Output radix sums into separate memory regions for each radix group + // So this memory then is layed out: + // 0...... 192..... 384 ................ 192*256 + // ie all 256 bins for each radix group + // in there: + // 0.............192 + // 0 4 8 12... - block idx * 4 + // And in the block boxes we see the 4 radix groups for that block + // So 0-192 should contain bin 0 for each radix group, and so on + uint offset = blockIdx.x * RADIXGROUPS; + uint row = threadIdx.x / RADIXGROUPS; + uint column = threadIdx.x % RADIXGROUPS; + while (row < RADICES) + { + dRadixSum[offset + row * TOTALRADIXGROUPS + column] = sRadixSum[row * RADIXGROUPS + column]; + row += NUM_THREADS_PER_BLOCK / RADIXGROUPS; + } +} + +//////////////////////////////////////////////////////////////////////////////// +//! Performs first part of parallel prefix sum - individual sums of each radix +//! count. By the end of this we have prefix sums on a block level in dRadixSum +//! and totals for blocks in dRadixBlockSum. +//////////////////////////////////////////////////////////////////////////////// +__global__ void RadixPrefixSum() +{ + // Read radix groups in offset by one in the GRF so a zero can be inserted at the beginning + // and the final sum of all radix counts summed here is tacked onto the end for reading by + // the next stage + // Each block in this case is the full number of threads per SM (and hence the total number + // of radix groups), 192. We should then have the total set of offsets for an entire radix + // group by the end of this stage + // Device mem addressing + + uint brow = blockIdx.x * (RADICES / PREFIX_NUM_BLOCKS); + uint drow = threadIdx.x / TOTALRADIXGROUPS; // In default parameterisation this is always 0 + uint dcolumn = threadIdx.x % TOTALRADIXGROUPS; // And similarly this is always the same as threadIdx.x + uint dpos = (brow + drow) * TOTALRADIXGROUPS + dcolumn; + uint end = ((blockIdx.x + 1) * (RADICES / PREFIX_NUM_BLOCKS)) * TOTALRADIXGROUPS; + // Shared mem addressing + uint srow = threadIdx.x / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + uint scolumn = threadIdx.x % (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + uint spos = srow * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + scolumn; + + // Read (RADICES / PREFIX_NUM_BLOCKS) radix counts into the GRF alongside each other + while (dpos < end) + { + sRadixSum[spos] = dRadixSum[dpos]; + spos += (PREFIX_NUM_THREADS_PER_BLOCK / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK)) * + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + dpos += (TOTALRADIXGROUPS / PREFIX_NUM_THREADS_PER_BLOCK) * TOTALRADIXGROUPS; + } + __syncthreads(); + + // Perform preliminary sum on each thread's stretch of data + // Each thread having a block of 16, with spacers between 0...16 18...33 and so on + int pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + end = pos + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + uint sum = 0; + while (pos < end) + { + sum += sRadixSum[pos]; + sRadixSum[pos] = sum; + pos++; + } + __syncthreads(); + + + // Calculate internal offsets by performing a more traditional parallel + // prefix sum of the topmost member of each thread's work data. Right now, + // these are stored between the work data for each thread, allowing us to + // eliminate GRF conflicts as well as hold the offsets needed to complete the sum + // In other words we have: + // 0....15 16 17....32 33 34.... + // Where this first stage updates the intermediate values (so 16=15, 33=32 etc) + int m = (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + sRadixSum[pos] = sRadixSum[pos - 1]; + __syncthreads(); + // This stage then performs a parallel prefix sum (ie use powers of 2 to propagate in log n stages) + // to update 17, 34 etc with the totals to that point (so 34 becomes [34] + [17]) and so on. + while (m < PREFIX_NUM_THREADS_PER_BLOCK * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1)) + { + int p = pos - m; + uint t = ((p > 0) ? sRadixSum[p] : 0); + __syncthreads(); + sRadixSum[pos] += t; + __syncthreads(); + m *= 2; + } + __syncthreads(); + + + + // Add internal offsets to each thread's work data. + // So now we take 17 and add it to all values 18 to 33 so all offsets for that block + // are updated. + pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + end = pos + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + int p = pos - 1; + sum = ((p > 0) ? sRadixSum[p] : 0); + while (pos < end) + { + sRadixSum[pos] += sum; + pos++; + } + __syncthreads(); + + // Write summed data back out to global memory in the same way as we read it in + // We now have prefix sum values internal to groups + brow = blockIdx.x * (RADICES / PREFIX_NUM_BLOCKS); + drow = threadIdx.x / TOTALRADIXGROUPS; + dcolumn = threadIdx.x % TOTALRADIXGROUPS; + srow = threadIdx.x / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + scolumn = threadIdx.x % (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK); + dpos = (brow + drow) * TOTALRADIXGROUPS + dcolumn + 1; + spos = srow * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + scolumn; + end = ((blockIdx.x + 1) * RADICES / PREFIX_NUM_BLOCKS) * TOTALRADIXGROUPS; + while (dpos < end) + { + dRadixSum[dpos] = sRadixSum[spos]; + dpos += (TOTALRADIXGROUPS / PREFIX_NUM_THREADS_PER_BLOCK) * TOTALRADIXGROUPS; + spos += (PREFIX_NUM_THREADS_PER_BLOCK / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK)) * + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1); + } + + // Write last element to summation + // Storing block sums in a separate array + if (threadIdx.x == 0) { + dRadixBlockSum[blockIdx.x] = sRadixSum[PREFIX_NUM_THREADS_PER_BLOCK * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) - 1]; + dRadixSum[blockIdx.x * PREFIX_BLOCKSIZE] = 0; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +//! Initially perform prefix sum of block totals to obtain final set of offsets. +//! Then make use of radix sums to perform a shuffling of the data into the +//! correct bins. +//! +//! @param pSrc input data +//! @param pDst output data +//! @param elements total number of elements +//! @param shift the shift (0 to 24) that we are using to obtain the correct +//! byte +//////////////////////////////////////////////////////////////////////////////// +__global__ void RadixAddOffsetsAndShuffle(KeyValuePair* pSrc, KeyValuePair* pDst, uint elements, uint elements_rounded_to_3072, int shift) +{ + // Read offsets from previous blocks + if (threadIdx.x == 0) + sRadixSum[SHUFFLE_GRFOFFSET] = 0; + + if (threadIdx.x < PREFIX_NUM_BLOCKS - 1) + sRadixSum[SHUFFLE_GRFOFFSET + threadIdx.x + 1] = dRadixBlockSum[threadIdx.x]; + __syncthreads(); + + // Parallel prefix sum over block sums + int pos = threadIdx.x; + int n = 1; + while (n < PREFIX_NUM_BLOCKS) + { + int ppos = pos - n; + uint t0 = ((pos < PREFIX_NUM_BLOCKS) && (ppos >= 0)) ? sRadixSum[SHUFFLE_GRFOFFSET + ppos] : 0; + __syncthreads(); + if (pos < PREFIX_NUM_BLOCKS) + sRadixSum[SHUFFLE_GRFOFFSET + pos] += t0; + __syncthreads(); + n *= 2; + } + + // Read radix count data and add appropriate block offset + // for each radix at the memory location for this thread + // (where the other threads in the block will be reading + // as well, hence the large stride). + // There is one counter box per radix group per radix + // per block (4*256*3) + // We use 64 threads to read the 4 radix groups set of radices + // for the block. + int row = threadIdx.x / RADIXGROUPS; + int column = threadIdx.x % RADIXGROUPS; + int spos = row * RADIXGROUPS + column; + int dpos = row * TOTALRADIXGROUPS + column + blockIdx.x * RADIXGROUPS; + while (spos < SHUFFLE_GRFOFFSET) + { + sRadixSum[spos] = dRadixSum[dpos] + sRadixSum[SHUFFLE_GRFOFFSET + dpos / (TOTALRADIXGROUPS * RADICES / PREFIX_NUM_BLOCKS)]; + spos += NUM_THREADS_PER_BLOCK; + dpos += (NUM_THREADS_PER_BLOCK / RADIXGROUPS) * TOTALRADIXGROUPS; + } + __syncthreads(); + + //int pos; + // Shuffle data + // Each of the subbins for a block should be filled via the counters, properly interleaved + // Then, as we now iterate over each data value, we increment the subbins (each thread in the + // radix group in turn to avoid miss writes due to conflicts) and set locations correctly. + uint element_fraction = elements_rounded_to_3072 / TOTALRADIXGROUPS; + int tmod = threadIdx.x % RADIXTHREADS; + int tpos = threadIdx.x / RADIXTHREADS; + + pos = (blockIdx.x * RADIXGROUPS + tpos) * element_fraction; + uint end = pos + element_fraction; //(blockIdx.x * RADIXGROUPS + tpos + 1) * element_fraction; + pos += tmod; + + __syncthreads(); + + while (pos < end ) + { + KeyValuePair kvp; +#if 1 // old load + // Read first data element, both items at once as the memory will want to coalesce like that anyway + if (pos < elements) + { + kvp = pSrc[pos]; + } + else + kvp.key = 0; + +#else // casting to float2 to get it to combine loads + int2 kvpf2; + + // Read first data element, both items at once as the memory will want to coalesce like that anyway + if (pos < elements) + { + // kvp = pSrc[pos]; + kvpf2 = ((int2*)pSrc)[pos]; + // printf("kvp: %f %f kvpf2: %f %f\n", kvp.key, kvp.value, kvpf2.x, kvpf2.y); + } + else + //kvp.key = 0; + kvpf2.x = 0; + + kvp.key = kvpf2.x; + kvp.value = kvpf2.y; +#endif + + uint index; + + // Calculate position of radix counter to increment + uint p = ((kvp.key >> shift) & RADIXMASK) * RADIXGROUPS; + + // Move data, keeping counts updated. + // Increment radix counters, relying on hexadecathread + // warp to prevent this code from stepping all over itself. + uint ppos = p + tpos; + if (tmod == 0 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 1 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 2 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 3 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 4 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 5 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 6 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 7 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 8 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 9 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 10 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 11 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 12 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 13 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 14 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + if (tmod == 15 && pos < elements) + { + index = sRadixSum[ppos]++; + pDst[index] = kvp; + } + SYNCIT; + + pos += RADIXTHREADS; + } + + __syncthreads(); +} + +#endif // #ifndef _RADIXSORT_KERNEL_H_ diff --git a/Extras/sph/fluids_2005.sln b/Extras/sph/fluids_2005.sln new file mode 100644 index 0000000..a49be24 --- /dev/null +++ b/Extras/sph/fluids_2005.sln @@ -0,0 +1,23 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fluids_2005", "fluids_2005.vcproj", "{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + EmuDebug|Win32 = EmuDebug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Debug|Win32.ActiveCfg = Debug|Win32 + {644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Debug|Win32.Build.0 = Debug|Win32 + {644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.EmuDebug|Win32.ActiveCfg = EmuDebug|Win32 + {644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.EmuDebug|Win32.Build.0 = EmuDebug|Win32 + {644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Release|Win32.ActiveCfg = Release|Win32 + {644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Extras/sph/fluids_2005.vcproj b/Extras/sph/fluids_2005.vcproj new file mode 100644 index 0000000..b0b7a4d --- /dev/null +++ b/Extras/sph/fluids_2005.vcproj @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/sph/main.cpp b/Extras/sph/main.cpp new file mode 100644 index 0000000..21336d2 --- /dev/null +++ b/Extras/sph/main.cpp @@ -0,0 +1,594 @@ +/* + FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU + Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com + + ZLib license + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include +#include +#include + +#include "common_defs.h" + +#ifdef BUILD_CUDA + #include "fluid_system_host.cuh" +#endif +#include "fluid_system.h" +#include "gl_helper.h" + +#ifdef _MSC_VER // Windows + #include +#else // Linux + #include +#endif + +bool bTiming = false; +bool bRec = false; +int mFrame = 0; + +// Globals +FluidSystem psys; + +float window_width = 1024; +float window_height = 768; + +Vector3DF cam_from, cam_angs, cam_to; // Camera stuff +Vector3DF obj_from, obj_angs, obj_dang; +Vector3DF light[2], light_to[2]; // Light stuff +float light_fov, cam_fov; + +int psys_rate = 0; // Particle stuff +int psys_freq = 1; +int psys_demo = 0; +int psys_nmax = 4096; + +bool bHelp = false; // Toggles +int iShade = 1; +int iClrMode = 0; +bool bPntDraw = false; +bool bPause = false; + +// View matricies +float view_matrix[16]; // View matrix (V) +float model_matrix[16]; // Model matrix (M) +float proj_matrix[16]; // Projective matrix + +// Mouse control +#define DRAG_OFF 0 // mouse states +#define DRAG_LEFT 1 +#define DRAG_RIGHT 2 +int last_x = -1, last_y = -1; // mouse vars +int mode = 0; +int dragging = 0; +int psel; + +GLuint screen_id; +GLuint depth_id; + + +// Different things we can move around +#define MODE_CAM 0 +#define MODE_CAM_TO 1 +#define MODE_OBJ 2 +#define MODE_OBJPOS 3 +#define MODE_OBJGRP 4 +#define MODE_LIGHTPOS 5 + +#define MODE_DOF 6 + +GLuint screenBufferObject; +GLuint depthBufferObject; +GLuint envid; + +void drawScene ( float* viewmat, bool bShade ) +{ + if ( iShade <= 1 && bShade ) { + glEnable ( GL_LIGHT0 ); + GLfloat diff[4]; + GLfloat spec[4]; + GLfloat shininess = 60.0; + + diff[0] = 0.8f; diff[1] = 0.8f; diff[2] = 0.8f; diff[3] = 1.0f; + spec[0] = 1.0f; spec[1] = 1.0f; spec[2] = 1.0f; spec[3] = 1.0f; + glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, &diff[0]); + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, &spec[0]); + glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &shininess); + glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); + + glColor3f ( 1, 1, 1 ); + glLoadMatrixf ( viewmat ); + glBegin ( GL_QUADS ); + glNormal3f ( 0, 0, 1 ); + glVertex3f ( -1000, -1000, 0.0 ); + glVertex3f ( 1000, -1000, 0.0 ); + glVertex3f ( 1000, 1000, 0.0 ); + glVertex3f ( -1000, 1000, 0.0 ); + glEnd (); + glBegin ( GL_LINES ); + for (float n=-100; n <= 100; n += 20.0 ) { + glVertex3f ( -100, n, 0.1 ); + glVertex3f ( 100, n, 0.1 ); + glVertex3f ( n, -100, 0.1 ); + glVertex3f ( n, 100, 0.1 ); + } + glEnd (); + + psys.Draw ( &viewmat[0], 0.8 ); // Draw particles + + } else { + glDisable ( GL_LIGHTING ); + psys.Draw ( &viewmat[0], 0.55 ); // Draw particles + } +} + +void draw2D () +{ + + mint::Time start, stop; + + #ifdef USE_SHADOWS + disableShadows (); + #endif + glDisable ( GL_LIGHTING ); + glDisable ( GL_DEPTH_TEST ); + + glMatrixMode ( GL_PROJECTION ); + glLoadIdentity (); + glScalef ( 2.0/window_width, -2.0/window_height, 1 ); // Setup view (0,0) to (800,600) + glTranslatef ( -window_width/2.0, -window_height/2, 0.0); + + glMatrixMode ( GL_MODELVIEW ); + glLoadIdentity (); + glPushMatrix (); + glGetFloatv ( GL_MODELVIEW_MATRIX, view_matrix ); + glPopMatrix (); + + char disp[200]; + glColor4f ( 1.0, 1.0, 1.0, 1.0 ); + + strcpy ( disp, "Press H for help." ); drawText ( 10, 20, disp ); + + if ( bHelp ) { + + if ( psys.GetToggle ( USE_CUDA ) ) { + sprintf ( disp, "Kernel: USING CUDA (GPU)" ); drawText ( 20, 40, disp ); + } else { + sprintf ( disp, "Kernel: USING CPU" ); drawText ( 20, 40, disp ); + } + + sprintf ( disp, "KEYBOARD" ); drawText ( 20, 60, disp ); + sprintf ( disp, "[ ] Next/Prev Demo" ); drawText ( 20, 70, disp ); + sprintf ( disp, "N M Adjust Max Particles" ); drawText ( 20, 80, disp ); + sprintf ( disp, "space Pause" ); drawText ( 20, 90, disp ); + sprintf ( disp, "S Shading mode" ); drawText ( 20, 100, disp ); + sprintf ( disp, "G Toggle CUDA vs CPU" ); drawText ( 20, 110, disp ); + sprintf ( disp, "< > Change emitter rate" ); drawText ( 20, 120, disp ); + sprintf ( disp, "C Move camera /w mouse" ); drawText ( 20, 130, disp ); + sprintf ( disp, "I Move emitter /w mouse" ); drawText ( 20, 140, disp ); + sprintf ( disp, "O Change emitter angle" ); drawText ( 20, 150, disp ); + sprintf ( disp, "L Move light /w mouse" ); drawText ( 20, 160, disp ); + sprintf ( disp, "X Draw velocity/pressure/color" ); drawText ( 20, 170, disp ); + + Vector3DF vol = psys.GetVec(SPH_VOLMAX); + vol -= psys.GetVec(SPH_VOLMIN); + sprintf ( disp, "Volume Size: %3.5f %3.2f %3.2f", vol.x, vol.y, vol.z ); drawText ( 20, 190, disp ); + sprintf ( disp, "Time Step (dt): %3.5f", psys.GetDT () ); drawText ( 20, 200, disp ); + sprintf ( disp, "Num Particles: %d", psys.NumPoints() ); drawText ( 20, 210, disp ); + sprintf ( disp, "Simulation Scale: %3.5f", psys.GetParam(SPH_SIMSIZE) ); drawText ( 20, 220, disp ); + sprintf ( disp, "Simulation Size (m): %3.5f", psys.GetParam(SPH_SIMSCALE) ); drawText ( 20, 230, disp ); + sprintf ( disp, "Smooth Radius (m): %3.3f", psys.GetParam(SPH_SMOOTHRADIUS) ); drawText ( 20, 240, disp ); + sprintf ( disp, "Particle Radius (m): %3.3f", psys.GetParam(SPH_PRADIUS) ); drawText ( 20, 250, disp ); + sprintf ( disp, "Particle Mass (kg): %0.8f", psys.GetParam(SPH_PMASS) ); drawText ( 20, 260, disp ); + sprintf ( disp, "Rest Density (kg/m^3): %3.3f", psys.GetParam(SPH_RESTDENSITY) ); drawText ( 20, 270, disp ); + sprintf ( disp, "Viscosity: %3.3f", psys.GetParam(SPH_VISC) ); drawText ( 20, 280, disp ); + sprintf ( disp, "Internal Stiffness: %3.3f", psys.GetParam(SPH_INTSTIFF) ); drawText ( 20, 290, disp ); + sprintf ( disp, "Boundary Stiffness: %6.0f", psys.GetParam(SPH_EXTSTIFF) ); drawText ( 20, 300, disp ); + sprintf ( disp, "Boundary Dampening: %4.3f", psys.GetParam(SPH_EXTDAMP) ); drawText ( 20, 310, disp ); + sprintf ( disp, "Speed Limiting: %4.3f", psys.GetParam(SPH_LIMIT) ); drawText ( 20, 320, disp ); + vol = psys.GetVec ( PLANE_GRAV_DIR ); + sprintf ( disp, "Gravity: %3.2f %3.2f %3.2f", vol.x, vol.y, vol.z ); drawText ( 20, 330, disp ); + } +} + +void computeFromPositions () +{ + cam_from.x = cam_to.x + sin( cam_angs.x * DEGtoRAD) * sin( cam_angs.y * DEGtoRAD) * cam_angs.z; + cam_from.y = cam_to.y + -cos( cam_angs.x * DEGtoRAD) * sin( cam_angs.y * DEGtoRAD) * cam_angs.z; + cam_from.z = cam_to.z + cos( cam_angs.y * DEGtoRAD) * cam_angs.z; +} + +void computeProjection () +{ + // ---- Create projection matrix for eye-coordinate transformations + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + gluPerspective ( cam_fov, window_width / ( float ) window_height, 10.0, 800.0 ); + glPushMatrix (); + glGetFloatv ( GL_MODELVIEW_MATRIX, proj_matrix ); + glPopMatrix (); +} + +void computeView () +{ + glMatrixMode ( GL_MODELVIEW ); + glLoadIdentity (); + gluLookAt ( cam_from.x, cam_from.y, cam_from.z, cam_to.x, cam_to.y, cam_to.z, 0, 0, 1 ); + glPushMatrix (); + glGetFloatv ( GL_MODELVIEW_MATRIX, view_matrix ); + glPopMatrix (); +} + +int frame; + +void display () +{ + mint::Time start, stop; + +// iso = sin(frame*0.01f ); + + // Do simulation! + if ( !bPause ) psys.Run (); + + frame++; + measureFPS (); + + glEnable ( GL_DEPTH_TEST ); + + // Render depth map shadows + start.SetSystemTime ( ACC_NSEC ); + disableShadows (); + #ifdef USE_SHADOWS + if ( iShade==1 ) { + renderDepthMap_FrameBuffer ( 0, window_width, window_height ); + } else { + renderDepthMap_Clear ( window_width, window_height ); + } + #endif + + // Clear frame buffer + if ( iShade<=1 ) glClearColor( 0.29, 0.29, 0.29, 1.0 ); + else glClearColor ( 0, 0, 0, 0 ); + glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glDisable ( GL_CULL_FACE ); + glShadeModel ( GL_SMOOTH ); + + // Compute camera view + computeFromPositions (); + computeProjection (); + computeView (); + + // Draw Shadows (if on) + #ifdef USE_SHADOWS + if ( iShade==1 ) renderShadows ( view_matrix ); + #endif + + // Draw 3D + start.SetSystemTime ( ACC_NSEC ); + glEnable ( GL_LIGHTING ); + glLoadMatrixf ( view_matrix ); + drawScene ( view_matrix, true ); + if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "SCENE: %s\n", stop.GetReadableTime().c_str() ); } + + // Draw 2D overlay + draw2D (); + + // Swap buffers + glutSwapBuffers(); + glutPostRedisplay(); +} + +void reshape ( int width, int height ) +{ + // set window height and width + window_width = (float) width; + window_height = (float) height; + glViewport( 0, 0, width, height ); +} + +void UpdateEmit () +{ + obj_from = psys.GetVec ( EMIT_POS ); + obj_angs = psys.GetVec ( EMIT_ANG ); + obj_dang = psys.GetVec ( EMIT_RATE ); +} + + +void keyboard_func ( unsigned char key, int x, int y ) +{ + switch( key ) { + case 'M': case 'm': { + psys_nmax *= 2; + if ( psys_nmax > 65535 ) psys_nmax = 65535; + psys.SPH_CreateExample ( psys_demo, psys_nmax ); + } break; + case 'N': case 'n': { + psys_nmax /= 2; + if ( psys_nmax < 64 ) psys_nmax = 64; + psys.SPH_CreateExample ( psys_demo, psys_nmax ); + } break; + case '0': + UpdateEmit (); + psys_freq++; + psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) ); + break; + case '9': + UpdateEmit (); + psys_freq--; if ( psys_freq < 0 ) psys_freq = 0; + psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) ); + break; + case '.': case '>': + UpdateEmit (); + if ( ++psys_rate > 100 ) psys_rate = 100; + psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) ); + break; + case ',': case '<': + UpdateEmit (); + if ( --psys_rate < 0 ) psys_rate = 0; + psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) ); + break; + case 'g': case 'G': psys.Toggle ( USE_CUDA ); break; + case 'f': case 'F': mode = MODE_DOF; break; + + case 'z': case 'Z': mode = MODE_CAM_TO; break; + case 'c': case 'C': mode = MODE_CAM; break; + case 'h': case 'H': bHelp = !bHelp; break; + case 'i': case 'I': + UpdateEmit (); + mode = MODE_OBJPOS; + break; + case 'o': case 'O': + UpdateEmit (); + mode = MODE_OBJ; + break; + case 'x': case 'X': + if ( ++iClrMode > 2) iClrMode = 0; + psys.SetParam ( CLR_MODE, iClrMode ); + break; + case 'l': case 'L': mode = MODE_LIGHTPOS; break; + case 'd': case 'D': { + int d = psys.GetParam ( PNT_DRAWMODE ) + 1; + if ( d > 2 ) d = 0; + psys.SetParam ( PNT_DRAWMODE, d ); + } break; + case 's': case 'S': if ( ++iShade > 2 ) iShade = 0; break; + case 27: exit( 0 ); break; + + case '`': + bRec = !bRec; break; + + case ' ': + //psys.Run (); ptris.Rebuild (); break; + bPause = !bPause; break; + + case '\'': case ';': psys.SPH_CreateExample ( psys_demo, psys_nmax ); break; + case 'r': case 'R': psys.SPH_CreateExample ( psys_demo, psys_nmax ); break; + case '[': + psys_demo--; + if (psys_demo < 0 ) psys_demo = 10; + psys.SPH_CreateExample ( psys_demo, psys_nmax ); + UpdateEmit (); + break; + case ']': + psys_demo++; + if (psys_demo > 10 ) psys_demo = 0; + psys.SPH_CreateExample ( psys_demo, psys_nmax ); + UpdateEmit (); + break; + default: + break; + } +} + + +void mouse_click_func ( int button, int state, int x, int y ) +{ + if( state == GLUT_DOWN ) { + if ( button == GLUT_LEFT_BUTTON ) dragging = DRAG_LEFT; + else if ( button == GLUT_RIGHT_BUTTON ) dragging = DRAG_RIGHT; + last_x = x; + last_y = y; + } else { + dragging = DRAG_OFF; + } +} + +void mouse_move_func ( int x, int y ) +{ + int dx = x - last_x; + int dy = y - last_y; + + switch ( mode ) { + case MODE_CAM: + if ( dragging == DRAG_LEFT ) { + cam_angs.x += dx; + cam_angs.y += dy; + if ( cam_angs.x >= 360.0 ) cam_angs.x -= 360.0; + if ( cam_angs.x < 0 ) cam_angs.x += 360.0; + if ( cam_angs.y >= 180.0 ) cam_angs.y = 180.0; + if ( cam_angs.y <= -180.0 ) cam_angs.y = -180.0; + printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z ); + printf ( "Cam To: %f %f %f\n", cam_to.x, cam_to.y, cam_to.z ); + printf ( "Cam FOV: %f\n", cam_fov); + } else if ( dragging == DRAG_RIGHT ) { + cam_angs.z += dy*.15; + if ( cam_angs.z < 0) cam_angs.z = 0; + printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z ); + printf ( "Cam To: %f %f %f\n", cam_to.x, cam_to.y, cam_to.z ); + printf ( "Cam FOV: %f\n", cam_fov ); + } + break; + case MODE_CAM_TO: + if ( dragging == DRAG_LEFT ) { + cam_to.x += dx; + cam_to.y += dy; + } else if ( dragging == DRAG_RIGHT ) { + cam_to.z += dy*.05; + if ( cam_to.z < 0) cam_to.z = 0; + } + break; + case MODE_OBJ: + if ( dragging == DRAG_LEFT ) { + obj_angs.x -= dx*0.1; + obj_angs.y += dy*0.1; + printf ( "Obj Angs: %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z ); + //force_x += dx*.1; + //force_y += dy*.1; + } else if (dragging == DRAG_RIGHT) { + obj_angs.z -= dy*.005; + printf ( "Obj Angs: %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z ); + } + psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) ); + break; + case MODE_OBJPOS: + if ( dragging == DRAG_LEFT ) { + obj_from.x -= dx*.1; + obj_from.y += dy*.1; + printf ( "Obj: %f %f %f\n", obj_from.x, obj_from.y, obj_from.z ); + } else if (dragging == DRAG_RIGHT) { + obj_from.z -= dy*.1; + printf ( "Obj: %f %f %f\n", obj_from.x, obj_from.y, obj_from.z ); + } + psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) ); + //psys.setPos ( obj_x, obj_y, obj_z, obj_ang, obj_tilt, obj_dist ); + break; + case MODE_LIGHTPOS: + if ( dragging == DRAG_LEFT ) { + light[0].x -= dx*.1; + light[0].y += dy*.1; + printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z ); + } else if (dragging == DRAG_RIGHT) { + light[0].z -= dy*.1; + printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z ); + } + #ifdef USE_SHADOWS + setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov ); + #endif + break; + } + + if ( x < 10 || y < 10 || x > 1000 || y > 700 ) { + glutWarpPointer ( 1024/2, 768/2 ); + last_x = 1024/2; + last_y = 768/2; + } else { + last_x = x; + last_y = y; + } +} + + +void idle_func () +{ +} + +void init () +{ + + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + + srand ( time ( 0x0 ) ); + + glClearColor( 0.49, 0.49, 0.49, 1.0 ); + glShadeModel( GL_SMOOTH ); + + glEnable ( GL_COLOR_MATERIAL ); + glEnable (GL_DEPTH_TEST); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask ( 1 ); + glEnable ( GL_TEXTURE_2D ); + + // callbacks + glutDisplayFunc( display ); + glutReshapeFunc( reshape ); + glutKeyboardFunc( keyboard_func ); + glutMouseFunc( mouse_click_func ); + glutMotionFunc( mouse_move_func ); + glutIdleFunc( idle_func ); + glutSetCursor ( GLUT_CURSOR_NONE ); + + cam_angs.x = 29; cam_angs.y = 75; cam_angs.z = 80.0; + cam_to.x = 0; cam_to.y = 0; cam_to.z = 5; + cam_fov = 35.0; + + light[0].x = 39; light[0].y = -60; light[0].z = 43; + light_to[0].x = 0; light_to[0].y = 0; light_to[0].z = 0; + + light[1].x = 15; light[1].y = -5; light[1].z = 145; + light_to[1].x = 0; light_to[1].y = 0; light_to[1].z = 0; + + light_fov = 45; + + #ifdef USE_SHADOWS + createShadowTextures(); + createFrameBuffer (); + setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov ); + setShadowLightColor ( .7, .7, .7, 0.2, 0.2, 0.2 ); + #endif + + obj_from.x = 0; obj_from.y = 0; obj_from.z = 20; // emitter + obj_angs.x = 118.7; obj_angs.y = 200; obj_angs.z = 1.0; + obj_dang.x = 1; obj_dang.y = 1; obj_dang.z = 0; + + psys.Initialize ( BFLUID, psys_nmax ); + psys.SPH_CreateExample ( 0, psys_nmax ); + psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) ); + psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) ); + + psys.SetParam ( PNT_DRAWMODE, int(bPntDraw ? 1:0) ); + psys.SetParam ( CLR_MODE, iClrMode ); +} + + +int main ( int argc, char **argv ) +{ + #ifdef BUILD_CUDA + // Initialize CUDA + cudaInit( argc, argv ); + #endif + + // set up the window + glutInit( &argc, &argv[0] ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); + glutInitWindowPosition( 100, 100 ); + glutInitWindowSize( (int) window_width, (int) window_height ); + glutCreateWindow ( "Fluids v.1 (c) 2008, R. Hoetzlein (ZLib)" ); + +// glutFullScreen (); + + // initialize parameters + init(); + + // wait for something to happen + glutMainLoop(); + + return 0; +} + +extern "C" { + void btCuda_exit(int val) + { + fprintf(stderr, "Press ENTER key to terminate the program\n"); + getchar(); + exit(val); + } +} \ No newline at end of file diff --git a/GLUT32.DLL b/GLUT32.DLL new file mode 100644 index 0000000000000000000000000000000000000000..3297bd0783b702755a952ad50e518d3e1a922595 GIT binary patch literal 160256 zcmeFa4}4VBnKynXxd{VIm_a5uO2Dy>HI`tb32o?vcAzl^P2(iMBvu4$sU4@(qC2Cw zKa7c!0GGok-BoM5v?UwcWn0^&yR?l}AtA`{PsRU9QA?}az3iZkiZLp6-tYIEJCjL3 z+xOky{yy*T^Vz_ed+#~VdCqg5^PJ~A=Q-z|`=u{$(egD-(-G2XP3ysxe*yXX@jp9| zJmtLKOwo2ueB%5bTm2K~FA3lHH{Lb3eCzACT>nk)SFgY6rf)^PU-_E%me@_+8*lQ~ zT)o))&2O#x+9gFrlYACx#}{w9pzagen%wXKo}c=B-kK%2Hr@EuFw-)W1TWXLdYi88 zNS*D^#2wS7oIlxCFiHCfV)of&blb0SaUt}|N0+?MQ}tvF>ns1ZA+k`@R;BYa+~E(I zm@j)(kKT$r?XyLiHgZv(wvEXj^|uCCKJ`(F9~0lJX_bnAGXh-_{o2|nQjTrM59woF zL3i$-SJPHra?7ggqt|O%a~t^3i`2Vt-H{6=+ct2C0@J+HkrqV3Zd@-LOF#e^F1h7v ztH1SCO{<=bbk?m5*V@zI79#e4{{Dvp|HFa*pK(Cc`1JS*cc?jNetVOqiJ)E7`%2?` zb^k%<<|)t}VvU~vmj6j-!iI<02Sv~!syB6}ogHtYref}~Ud@%L@p*&cAqPf~7ZUY8 zdt>-bb-%>tXbQij?rVImVEF9}jJq*>G6Umj3cn-o#oPg4i)a=q+$cP_QAlv3FyKaI zkJvJKuW*a2U830$6j#_ITBEpHZxUw*8=KO_?mo?hYGz491+yfI91;POB@r-L5&@GX zamDiZUiTimwk7jN{)K|(QX|7Vm*m~L^DVyJ;ZZzuZ0bA^bqp?WnZNn5rY#4GieCOQ z|6(xTO$5t)ZZU%V6}_7#8#O*h$AM^dNZe*`|2;-#&Hv=O3q`Y@|APPE9VMvg>?ei9 z>N*O-2Y`7cFe965(^a-Fb{vQuSia)gTv8>;T|2*)=Zc?jh`KT~<>I9w|G{QwCrtpc z)+_4VBI@&YrekM^_XqP_=Fg$|LC=ci*IgUm>)7Mc+CS7F2F}EcBJ2(FeuJJqV zHs{^T5#MNDhjCS0Z5JyX$hPPzVH#K4og0TheWLQ(zCY&qm-)QTjw2MEX7`{z{iT`5 zCfi)UJ2t%6=IneJ(Z({LOQ0>kgWkqI#K&L3&o4X7cS+AWs4Ma>l5 zsF|+gX%M#-(3dTs=_o;5?iTga?M8i}o#oX`w_8ASEg+BN$G#fhxf4X4qcL5q@6lYH zy-}AaCZohcd-njYsY%HKUO}KHmg-&JRe3H*x~s7%X#V5}2#V* zl!(Qj6`%bFV=g0X#Vys1U`eW2)cK4XORRFfq>F_US}{ zF&t&Siky6QsVP9;no2*D@Dk=& zp>l`@$D*|tp)G!+X>Ggvj^!;7t?sz#SY#}j;J_^|E_HFo{+%r)ir6`Wjpi$H$+P%K zIy%{3>$syZqD8b+ftV7pHHzX>Xa=b&pe0^=0J^PK7e(8?3jMp+Wi)tL;6uPcau=)UE`*>A?Ch(HSz>DT7fRYy;z{?HH& zHblQbVnXTSQy7t#_Y3`<)o2A2eKu~xxD7_Mbg>2vY^WqrDIu~scIDrxY1yZW;q0xL zD=`hnibW9-H6n$0x*08ovT$3rD5F~*^Fc0UpgcFduZG& zJj@r=BbY9Bu{s=sy2>DXoxRC|y?Ah)tGS|+kj!QRfoy(o{S!g6`&weryA^co+;IJ3 zNc=aK$yih(S-=z!ppB_f*MpSL6ZXzt*apo|0o(Cx7DDcbjEN|s416ku`1yj3u>DG! za9fJuumt9oIl~Sfz=-ikD`FW74J%SAdX=)Z_lwoOa-ac=iCq*E?b2W~a(}Y`xzVlN zox{;t0P!{}!5^(4x(kgFAgS@8D@U(E;jW4UozFbNzR`MN;tKmNPEY5p8Hu^(wVaAg zj#p{1Lc>G21@T^o|KPe;Rl!R!%Ccw{e3FKXRd68-HayK|D0E9#5L}C&s9C(U;`NaK z@#g5Fd2?1FD!O3aoG`ER=FM5c>!tJNwD5ZIyg6%loiT6DYF?*xt;8i+@DK_n#s0@Z z+#Eic<)B;4q;~T^-dzXIMb8F%T|pB*2Mt}vjV7S=le#r)fIx&x8=IB}P5oYgfbA~- zpJOgGPfJCwaj{}mO+Txi(C;@3fwc{BDti zDnQJ_cyC#}PxrsD?oZ;$zTfB1elp>{yYCNqP3dQ){`J2DYs3ds8;PpOLItvo)jp5^ zap&E0P)jtpJHAgBmunOgqxO_os>wPuMr=@y|M3kH0HJnv{uVTX{TP0n9Z%vuNzv1G z+krf>To=wv#>F(f{ss9e4zSXF(L7^HJgLX~_4YJbx9&MWiaetsXf!M_8d{8oWk$nF zqhS>Y@EWx>89a>zl);Fw946per;hlSV93FWON1M`=as3 zb$=f%9p~m(ptQkpAClcxj|S8-G#(pX>@%ij+A~N0RP^Qy9*B>h2(#lth%n$4Qo_I5BKRg^s!2x5Jfv6KgK%nL^1}GLs_W{fFWS4Caa2B4R)7IB~*ujv{sF+g;BTw zeJiIHE>(+W&P3{c>nK314W!4I3e_3Tm6-U6(#1;WEJY^`gqjnTKLZVH@p4{6tRRIR z-JMg@&NSNJ1wq-zZFdPCouH^Eg{R{vh*MA|Jn>c`V92?nmA!o$2TW zAc?l;RMfdr6bi?s{=Pf)*tb$=qvCF|I8{W_m*dgLN5FdlTNj8w?mz=eHQ{w`KAX)7 zu8QMe5OPK@!mlrOK3N7nE%BAN(rR>xL$mjb=S8K>D3AB*SH|8+lO=Yva-GZ$)&P3| zpk?trGvj^HI^->3Lx7cK&d%G}3DA~eE^UkE^b2Uu#pxFSU&)s3jZPApQb?u!xK{K+ zv`YI=c{Nwj`I@U5;VOhV2(u8rj6k*3NYbdGfZAgX?&iBqsO`)hCE&(W&9Xc#LSZ9K8?``xB~Bnuz{#R>E;>-|zEavPo5^WDfFng!0z5Sjt=cK)Ry$ zt)IX9^z8RoS@E=Zm-Xs9p7-{T#KHLQ^WT23^L3Q!Y5g=9;uHO|4?!!ICfqit&R&Q3 zobh?_x4O})izd4fvV+g1SAtcgv6q3)Bi{LEv{hbgR-)#cS|Vmk=<%d>4x*9)omw#& zpyH&UyTZpn6-Z@8#Yn~LsEYs3(aV9*i)u7cNhRDO*wk#^fPN6iX!Q6xJ%1=Qr8)c> z>*EERkSFX}0&^*YMk0wl(#7%UHxwKH<4`Xk3}oq=v-5X|OX#=OO1jQMx)Ickuzfda zBiQg>d#nKfi3XCMa4bq{)V0Q1LM3%U<(6p3GuFa^;bt=CFfuCNSX%<02BILGh^0a| z)|MLKvSFZg#inIT1WQj&Kvg^q}se&w%L=*sr9HiD(8sRF|jf7GedPtEyha#$S#RsP7v2#EYI3$vq zR6vqLK;SiK?Se&l$eV%S_^4{5()1j>ay*orQ)z8E`8dR>GS#HY|4#Ii3HPlur52}) zAEHb^eC__1;W;Ql3!8mGDZVNDVma}uI0~HT5-&oOyyz#Q-?)_h@0xxJpziFv7#$W= z%9d4?Id=@H2vBkSw%KjrKQ1885NmXhkd;&tb) z$%&hP82@m(b3=oo?e4>hwyn7Au0)l@+Yhspif7*bajY7cJe{v6ZIqIjE4e@?eaQvV zJCG_gZq$thb}+d_*xL`l-R&~$J**$O+`qe8VPjp04Fd<1fO~h1iY6vTN8xsXnm-V` zdUu^lVPP^u=TDF~LjvI?2~tO#iG=upG37HOG=;nKnWT*!G`YaRu9;jQr98R7$Nm?c z@EghUX}=+dlM6}}_A)$Zov+6x$p+~mMV-&IPKo!~jT=wV26A9{P!(@`!j4)KiK=yQ zY^`HX(vh?g@9`yQuH7vPfDx*edyzR)OLEWI`HzSh%j_Jsu2lJ1C6&J;CqD%^Hc3Jo z3v}4vW10ww`j{qKt#D-`5D`JAMv0v%6zFkYNGsBHxUuMk5EC660oFe6IZ|#CeU+ z88vEKzbZ198Xi zCWp3;1yY?eX(Jh^;9u&T)a$vObDP4J(>cZ4ySF3qVM)bNbWD5aGtLeZ0;x*NiKPFQXTWRH$RR*{i-2+l`##P|WK3?fyP+dHmuS+z^+LspL1pmy0bV|!uy z0U9l1upL&|GA$bmXGo%rMS+z{+_=$xIwoywmwrxRqAs9V#%3vz@ z2PzZapT4$Vq~o8|T;D+W0>Wa1MF{6&fYAy*^3Rr+|B-2bU4kysM^VmsrJAb^;V?qz zV$JpcARI+l{3*?~79loUbNy$TMGs1yJXxPyFnMy}I|1P1oCERTw#@F|Ud>GY6 zt;>A+8xTv*Ra@=(@6*6ZVijS2V4+i6cP^aL;>Gqoy^js0X@bKCAIRTtH0Y_>DBU4K zdj8WWIHbo%Z0kI5cX#&QF%=haa8Usf022Q1uDz(uZvJ3OF$|Hum_vIU%I! zXHl#YcXYY?_piHHgy1|6IWXNTA}hNIZcH&GkF%Mvgs~gz%687n**;=p8)fo9v+tC?4^V8?=cz2%;^%5-*!5WxLbw1IE<=p^~PK&>n zADzEqPMu10=6b z@8)$ZhAxr|_FqB|Ht$gdE$R)L7vKs;B59f^?m>bml9ik^wu12!9?Tw5!P4f6*Ts5r zAhCwG1c zW#bpI9&!H`lsmj9KYEV%Ib5`w*oB24Ed%&SG4K!XaYSc|ySFlR{WkpOKarorJeIWj!f(6D;`RASjpQ4|LNUv&G)1E5C?9zjUf=q@{G9Cop z*~!^YEPnU5LDXW#GmXvhKYX~f3692XtN|v*$@Qd_f0*!~e_+PS?x>=vvW>f01LJnGg1i7qY8{PZmM~=Ux)Y3*|8E?=G_#IdP8PWEs73RiCX#~K>Ym=vFN>a zyO1zOs65pD9QbV-mrF@CZd#qbe>+Mr<}i9V>2`Mf ziUrEvAu1pCzvJxq5hD~;-{b8P_#f)**jv*n@Fqfim@q1Nf9veZ>p9WKD?!FjC5xuRdzE>oQbJJ=|z^GWe+sQnL`2bhW_ zrh_$SB7d^%C&T@Ls54~#lLAQ>zXXO1_qRo-gv`HJapngLK#1&47k&ZLNJHL=eek%+ z&PWp=zSq;g^fJx$RfMew352x>)F54tLUlmF7KKl82)S;dB*y&r57Ox_4ogV#S~?#*;w0A{&>`0Jx%pvBwP!}}!r1T5^0wRi@ z9nL?G3OIlSi8cL#EJ4hb8D{nZ;Zi!Aj}YxM(HimRthaAb{z3l>(ZaUBO?zXLHrcAZ z(Q`X`qtll*iZ`XS9@YM~yQBbSVWsSi!b-Utg_S~= zg_ZI)3M*x86jlma7FNpGD6EvPQCKNlSy(Aoqp(t@Mq#BuWnrZ(jlxPf8ikcYl!cY@ zlZ9>ciG}6p<6TmA0%f=rMYPVv0ypj}dhv4@UHvG+afA_s37^wk#Rxux3WNm+L4*|u z-$Yo4AP~NbupQyo2#+H?hwv)Gn+O`(X)*%dUikl1Zlv%~pB2$&tmyUck9|dnMA)7O z+n`+(n;o8_JZBv=prEyYp*S0LgMjDOr15QKUD3p!n+_$-31~Zzj zlPC^49sXR7R;!`NlLd@JF6==eF}%wTDqW1hpgSe(TMGMN&OA9T^#_CIWw3yNa$FuY zA83{yGt-GaF=oSzn6F`kh&Y0B=L}ru16^FJk3{K4pT7pgM7Z4ONxz8AO*9IGi4Il< zyTHT!1^4Khwh1e+STe@E5O7$@jbZ&EAYKT_O(qG)JxLqb2XB~eTw@2Sl2n28tqsFh zpC6kJ*m!SVE#T;MX_IDl7A~=Dr$;P4)#U{% zM9~m96Hn<)&B4Y7b0?~b6{7AD#V%}vyYu`bge zW-&jC>ccj22Ny3kW)iGoIQ=4;>eBW{eQki>0;pT2iw+-+8-IVaAU;xkOJTZzpx~9e zwlRd23AEKyvJg3?@0B}4YIQPNP zIIM{qo6n``o-HtTmPC>4@Nhy=jgTr*B^w>*Fv>zFnPxn6?hZs<-rm2HDQH8oBhZNL zYm@+4%g*yK6J;~B@7)HVtbE5$_+S#rO+IoBv?d980|53%KgJ7<8569-isWja7iMx0 z+%|vp8QBdw)2)-mQ*xbM{Q2#l5_X8N!`2p@m4w}-U_n+jSJ^j$Kd{fLFk!2~B&ZtY zxl2(HDCHKeYAhn(MK(G+K10YQfI=PoNAN3`&YX9rkP2*p#9CcEK6@V$%Eh-%0TSD= z^+ZiEGgWbU{cO3qz6z`Bn-@Ss9_8wKzqPjBARq6`JbnR>SXu9%-G_Dc%jClk)x(AI z;Rou$BOku69wuiV_G3N$s9aB{rr>&d`RIE3H{^OcM=q|X|9M92%cwC2C)R=6ZfXMY zWOh9r+iuFyQ0S0eZoR4K6;ER|-4&gK-;&rx0IvosFn4U7A)Z9-pAgkHqbe@f)8$&a z%qDrkoebb#nw)laZh=*;7XFrIc2fep9L=XXtFM2{mjjyXMufjZ z_#r|k!dirf5VHCk^9gJD+?`oI@2NoLa+c5CSUz6^QOH?7kK!?R`5f8?>*n0(8ScfP zr6dm0ww4l9S1F~F`TtE-X)$@_uweyO!5<{#QMn4bWl7!>VU}8x^YYLeS z-~*IrXD`;VM^aNl;myR~0(zmz!@ZKIZ0^_|7B#x_32GMtXUrpivi&DBp9t?oW=ttQ zZoTpyv^q_sks4_t9m7R#agytmkI-X2ZoTpm=zFYJK2pF-&U)n|RLiO9j}-D^tyew( z^Pq>SQHYM#h=uT%jmSeCdX;L`-nop%1I~poJ@A)Lm&SGelywg&X9dT zWoJdLr5k3jC?FT$ILkp{KLd(mV=EE6C6k@ZjjlS4;@8F&8C$5}jj7S945hZyi|ITX zJBPwX;NarMrDi{{V?dO`f*XScHV??^JQFgu zp_orAUd*KFj_g-sw>&LhJ(zw0_&+CM)ROaDTIQl>8<-#-pvBas!Bq;N8R3=H*vkI- zHL^%!E~8WOZHM#=*znq{yiw*Xj2tvcJVN@CBX)-~lw5x=5b-a$o)ZiH8M|n57(dv? zUkPgF|A(A07}BRL3Rf%-$o*vKYgo~nd6tzy zC9e=|L{1A>naI((qK!4miMc?u(Fn|mnJU_7>@kL%z!i;;Uy!nwZ(^X{jAPc;WMKU+c7VKxIOA2;qL=y`g zNRhtGM)SuiJ9Ww?&dICH|(<9TOJC^&u` z4SNPu`tc(lk$^>zpxcr+?3@kyl=O&&e9`H0OobZ63S#`4&aLD2*E%vh8iXG zGLAOG(eu#CrO=;T7F~mSW7x6AM5T2&EULS%vgW)j8xk8QV?1tuF9{NE!#?Uw-ws?& zgXO+bT)N70AiI3I52d*e-kb;Xi!c|(P`bDUM9juZKdR7RI6zsMevxD)lyfHG4(Q?E zAiRgL^h)?>5e_1}if{^{_$v5x5w1X3iEul@-y!@IVK2hV2$$ExM~pCx`wm?H6~X=` z&2#-|7s{bGlt1mn?e<@H)C!^J46h1+4&~RMSC7i8FK$mG_%3Qe|xfDcumP#8d zS}NwRWXjBStc+ZId=W&$Zhv-Z4qWUtnx65!HQDJd*Prax9^Ja;sJqVDnFb-$LiYmI z@wf1RUAye+Vklg<#)elfihXD|c~2v_6c4zRv-pu_+?DZePAPuF-WJs6`EWHZ-F&aj z-1Sw-)o#Ag1|`rMZb6c{-HHvXSYLRJ%D092_?{DR?BG3LcuPOuy$qM|e&)Q%%E>q1 z!Y?uA#H(M2i|zGM~lPyHK2d%CnSfccI;SO;_4UbocptNgtpHxWfpiO!?J{>;AtZA>N zZL36&ME(w{iqbD5_I8DEUqKDXvK{|EGVNZ5gj_1h!eN5$A_9U*1ej<&z}Tt`0;1MZ zD|R1NxwFMj+*jZu?o`e0=Ts88CMiQwsZ6?f_c4`}@vX$F!X~j_i84`KvY?)D$VbUe zT&_oKu)B&7VKLeP9yvE(Pd6gp%7JCxWHw;GLd7t0bGlB$4mw9Vqv3$_`8eMDnu5)c z;Zg*jnZ6F#;UjPl_v_ePR^xN~_q7&ub4148CmG|CF&vgfk^C)YD(n;KikeH)hns#% zhx=X8=}<#2h~jF{O`2!#!InH+ffuiDt}E!KfiT>kM_@02Z3GS|V6O%2WmlHKv=OAC zAc~j|b-x+)F{^O`!?o9Cx|@1mfoB_Fw^hZk(0`b4{}B3Ps(32C2QR?a#`|=U2T6Yu zcwI@Ihk(IK753SOt~J#DI!w2~JH9mLXl&}P139K0Wn}jEA)Y(=&|4(=MiJ>+Hw%X~ zoZDRq;I4A~IBZ5y6|UWU;EFS^z7I2xnX#1D9DHP?A(`3=e68nplW_`Po>4@`WDqEP zf6hFP$Jb3m2{S;($4^wEl`+*6^UE*@VCpAl^63}n{|Hr&o`u22F7`DBYps~r8!K?| zOnh&prS--rKj1St(*OhXMEmwXLko|%oEtc8#`ODG3*1-~P)>-8?ghQ0({53;W!&@T zG0$D@YbD8DZHPwxt`6(E&bn^2u5wF7+h$eDXlXLKeMCifJzxQEwXWOLwK42LDdu}6 z>`-UG&Eri<;?nKyta1R3Eb|M@`cobnT!jBNh=geQ%gD49U zSJ<@{H~o>>$pXfZEy`f;W=*?Tdx+t=U1SSxrgo8ExUpl8jLa$PrfxI1d6lB=!0Uqb zSdV}~-dZCkBJs6#6JjNpn@8ZL<7TE}FIt=ULb&&F_?Po6;}_(SnvWU3If;85+mYFE zvXRdiac7E+gn|rClX#10PLu+NEGpT?ME;$I2J|UvPE-jCncBYtDbrzp>2UvOjS-rD zE}AJYHWZbssjk}h*zkfVRz)-%SfssFvd<^DlU6i3AcGsU$J?#1TuW0@(z?h|Ti>mezp&dzp3HiyF1kY;QVRhA0m{`yT? z^-a-hs~hm5)BFHNgRpiU8v4bs4HwMUUff-e91l-MZaMy4y1NC>7-|cwm}qgt9$tw! z$n66XEtZF3IA3Wy3T8K2j*A9*La{Q1xN+poma(%V}r0giM4*0-BSGbH+zkjwQmb9X7Mjd^HqlM zZiHVW96~sXkl|?84yD%%OuU?{$*1s7*W0w9c}X)nDU-w75YcF!%?M2T(4^cFYUi;j zaQza3n@!#dVPqXYec58Zj%XMogn~iqxDF(4mn14FA1xm;kyhnDB+LIfGL9+#JB;|~ z@^3-%>E(~&za@)b)vsYZ{?97>9%^&c58h}LM%@mtwtOsRCFJl0dvXSg^C*s?H44nL zviKGKZ!8^0|BH;kjPI|*{|KOg|7B?2NM7S$iO=ML5zy}#4l|91Yy8AYE~gLH_@WF0 zMRm{GT!RM&it2go8{9K^aBzuAlQ4${m-#Ar3?=W^QG z7)@Qc_hA~k7VeT3v0tVK#r!(x=3P6F*j$e+!4F{T0UH2J4LmzFNW`qU3Kvm(3fqqo zOE&YACsCNt1Bv<$Y>s{rue2oGfke%{@}1*a`zRDnheF19$`OCV)&7A8=R=?J2$sL zO^KN$q-2g4zvNUU+M{ZqFJcEs$;$(HDv=?L_Ww}IfEOvHik&EpE-V+(bMf;PT#2L{ zS*iz+03mSU9>O)4L9oOUodW|ncR)688O)6`Jk zfMh`35&`<1g#_+7E8Bs=W6dfXvOG_$04=qyUeJ=kYGEWMCi5zjb8@4K<#nu*v-2W! zRwV|A|T?&EibdRFF`B0(3J^MUB3y zCHq1AgzM#km6Z4QU%D`i>&pdeSv_Ll?ZNjU4{r}1co{>^OTB{!UYaAJU`%IV zUP-kD`bjf@*J|E`47`2+1*^Eea z#TN*DLGv+cCXBt%Uoee1?9wrZ?K&KKG4J3goqhp_>!_1;0<4Oolf~loBvh}4L$H1y zBe0U7H13M!*T(nyER&i?`C9hYpf+g3KW*^Pz#{wL!GSvaU_f5=!3DU!a$@lCz#<)& z1GqryC_D!S>h!^bz~C8d(Fa@XuN)urU{TOQ4t_UsLh0c9v9K;7i3@(4lz#Yalu!Tmqx@#b`O5>>WGI5Vd=Kv<0fUMeKRzh`iF~uaIc$I0 z<_h=1J_(s_*($Dv+mDYuz!Fubzt2Hi70ho+=o-8JHR1Q%l9`(x*W8WDC}`xPcZ&KEW(lf*hLj?umJD(SFH>=oYYY z8LXCNlo?zpqNO-?jcvKa*OLGEl>qW!99>q?OE3fvLJPtYfR=zaF#FI3B`{I<;7Ws& z&!q#7eC$t+k2nC}fh^P)o%6r5w8>r8h&xk!V(1#RKa!CI2p7~TP?gp3X zr7TXDcCQ|Id0^d!mj|RhMB|1w2rXAwv$&Jy4xV7W;;9OEHG_v<*(-&l8c%hDPawV$ z^<0TgQ$s&>Ig)879Ugq29_v6;5P466O2P+O15}yxA#Gq7@d4b`$h#Vdb-%>eg19{l*7_f@bpMM#g`lpag&IrHgBjL?6!k?214?)1o_S0v}VZwoG zW2NC%f1Q5E&3G9YJGAo;LQ&YGUlq1yaXa3QZ@n^v7hR9QakiMsC6aH=J|>9Um^xJq z@Ti38IDzu{_&)npu{X0;x;vi4DZt1RJBXI{TzlPevA|(DlRX%QR>+C5lemNCO1M&D)02VKG`cOoQVeV5pe7@;sy?-!%B|12tWR;KKGDg83moRo zD=k{^B1!oh$8xdsa!K=Y5wF3*>PPaG=O4k9)4(ThPz zRGy%@X$sEM|J)!L-YnMY8{v`wA6(Yi`cK_aWD)puG=E^BV^f2z7H8-Wt}rKo(&g8% zK;$$})ml&NocQB;cDd!%k1KEP|89BNqU4S8w@Ifi1a`*>3Y2t*HRc>Jy#FyNu<%kB zD`|%F%2>Eo0U8U|Nk^6<*Ye+4@;^j$r^~-WNAH)Mukrk8J)DR6dayAv!Q>7QXf})S z?I%jm7wJL?YhD{B^PJp^xjKHsZAF;fzYy-ixR1-P)zeOSNf*}xg3=eJ9e|$=U&JxY z5Tutoe3iiXQc=}Qn0P>Wfx(_&5Z>Y;qyn&aH?!fK10X;%yB>lRKrdo33deO4{=LLi zC(&t25=->5#Af{=NGp`D7g0WnKk~?9`v!RGB(^ z2k&)|gqSm%%{O?R%z_e;Y$0FbD2q+8Ksfb2he$z9jJ`DYV2z_(B_`?}<%8$otkQhv z=0(tyNaaZrK2(Q`sijx}-Q@sHbzM_x5W^iT#ykK|`y zWXr!OcKXWEuvTOS4jWQV0Jqrct45-jW8xtc(eQt9`uRkMj~owjiv5vzv(VWVxF)gL zN0vAKb@?!cmVxrWrU)?D74HqqFQa_m-nscM4BP4A=RmdcPjLuu-^)IsG$L}S{zHEk z`p+cupc<*H{v*3~v-mLk+B)#ZR|jx`;&3mYuxSX7G7jQ`DHRO~JCfmlP8V-xu|+b&UPrty0AjJR zhWXXeG*W|L&f-AFTM%Xcl$BC;YgE@xoId-%scXXI543qfnkH#U<~>GB_T7&Mw8KgR$cWVmZT zYKYl5_oSdbrux@9qKolrJ{DaH{I}b&4}b2XfWQIm!>#kg%pTl}XSqc~fu4&mQQ*G7 zzt$d|vH*KH@R6I}bB`&`-O@!jk@H@~unyAfKn_gG0*K}*@Or3wC*ZIP4uZ)oqjp~9 zC@C7t{cptz{0mC4MPyNF6FQgN{w5Q*l|qbgB*c_(8mAcGd zzCu zi^3tn{nq-#IQeZqLE^+_Uk5JoY`@>o`U-XIhyKx_%du?-Bbq$EuLoKOOJ6p5*tCub zwiX!1(bzm#TIY}uFqU-ai1Ml^48&Fx0q~%84S-@W_p?2`5kmsj!AaB_T7uJlyWAPa zwW?oXEd|;G9GC)gGrkX2D~^CUf)%y)y=_1=Ds>k9_e%Oh;;n~Cef*Dh&@2yb!_{s_ z6oxAY?p<{D;+~_lhn5D1F?G5)kJ|QfT^Uin9>NXp$x~J3+Hzoc-YXZ{{RsW1OpXuoO-*|efDkT-Ptdw8dX5cWe1yMf8FYWb zH-&o;5k&9V3u%bscpnTO@)S0zzwnydVTt9jR0~TnHz=W6Uyywv$D1VAYfx!B4aQ(a zIvhmz!RF4DP^QqvThVbr_{3&2_AL9NK5sr>Zo)pi7Iw28%JE~4fS+O@T#piAthlWK za|rPG#!XRp9br2ZEG(lMV^*?ujnda(4eo> zV9F%l%Yn4kG+R|f$#o!NNf5kU*39+MW%9PMsr?X;76uoGH-q@_y^1RxU`NoXb*TNl zIKU1Bxz%p|kS9^QiaoJRYI=u1i4WVL?ps;+jU$qIqSh@u{@)??2xD)tVjJ8z>yeO=#1jyAENXVV2ElD(ZDVpE-E|ED1|I4clPnE{KqW zM^@F^5nGN}5+b*<5?}gVMM#4STy7{gZfc267E6~Ip_N8#8BTL;T?uZqaJJIwGiuiw zwd;)9fKgj#v@Vl=wB-8jU`u%$&_0!1{}Aq1;@;S`19!%*o$|Lw{yr*yd*$z5`MY2K z9+tmHEWB!7>|-`C`?DSuDM-y!*XQvPx?l+jva?Aju4qRHCoRlHl@hTo_o zxqc(AIs#6dllSuUDojPzcOViC?K0->hY%YL_4pVC_Jl0K@pkA%M&(`R7c7C^@KQQG zuXR;)dYC#98|1-A>vjYU#7_iqTew_5E0)7)FYGX4!7;v0@nn1+UaSqEP5pb;y}b~} z0Z5=IJ}-42XprwhJ_J1Rz4p}Ph@RbejBN$Pfseeju(cY8v4MaQ=twxO5I4!1ji-n} zNPLNf>E-?5FhTEs2cR5u32I-^7~alU7Z9L~QRR;j5ASQw;kX=XPCuU=o7LuxD_#CK zF*Yx>Lns#78zDe)Y>r|IhuxiG<|&YjgQGavd)6Ax7tmOk&TkL~c>0^nkO4Uzf4Rb6 z8lBuIuB4-a_{qu~3aP-Prc+x%IVM_`xg4&y$n!|B-UuD^8tYhwnxoQPYKJVhbc*6C zs7M$_U6r_^Ph#{ahVhOpBVRtdJkZSw&HCdVWtHXN^U8VYo)f zAw!b|jFA<%+SO>LaB!r!f(O+B$2n-KCUYPgg(e%aq~>ZK^w);`qM5HRSM%-)FY@4h z*DLN*dSikzwwjZAJMo)W<3}2t!0u0S(-;jzS@abi^_>DDz_;X@t9^Fgqx6@*4{1L(!>;jk5E$@fVdp(J$mJzOaP`K<6OqF(kL2%Dj?W zJa29<;-EfeNoT5M=nr_mjB0mCX+f^8QjVFB-*qn93UZgyrsmIO=Rq#HqBC^ zvdN-kCb4k`YkMF%3)w#->Y|H`x~M7)Zj#0*_Fnz4H<&7d5#&K?#I^wG5r_FHNRp)s z?8Xk_$SoolKNYrx|I&}eKP?ykLB+v}XK*6@eS7fnxe1VjUm|j}P$ISpl~uvMWWe?Y zBLQfJstj{=v2uuOqI7VANo+gDi#X%+u0Ze?^G#9`$K>PR;wy^ z@o^=_U_@E+W1ZK853fYpX-Gks@KxPv|BkvB$r42s&Zl|{+A84qv6 zz2u?Tu?4sBCmn{oQKZ1$RmCh`3hv@BHOVrI8QPje_1JN7AbePSY$qYa~!vhy#tj3#Va0MKpclC-mUhcBRF2TiN zi(Mprh+cHw$%t@!oQbcac+gg=PEA*Dzk*t9lB(!cr(p2i6vV)${)4aWeV? zfz8v_TI9LqER`KpVzt8pwz8A0DrQry11~I1Q+PMk78$lIEVfdis62ZXHUo6tC=jw& zJk!z3lK5Q;_`N%%pJU1s}t$lkSdiL;MShrU5wVlp? z4RMMo^A~!dNhez$Phf*u!WO;J613>bjF2^FgsdSeWHq8_jS{!dWt;)ga#6HW#eGsP z-A-2$*c`^^{P2-DC4v}>&N3!g4FirRAv>T+zM|vm$N4o6ZN&R22F@Nq*oW{6!dnQ1 zoA6#TLK(sr5SkFahOibvAp8K~7YKV1q$09@;wSiRtt!sHN8jaj<2Bwr6-O&x-{nK; zcs~#(qyNwiaJb;8FkYtHG`v9O*@x{0HvG)=Zd~S@?d+hZLCj~b{DocQ&8NS^dCxJR zaCZCyepLrPf;)8Joe4}pp7b8?!{erfI$V7lf#~?Z=01M~m7LVi|8%>YMoWroN8fPo%DwN6X>XmkNQ@+1}LES@^P4EuubY zOI7CSo5jqh59$_oOg9tkjdJ*;^97cEs z;bnx^5QfHuj7((SH)>rHDa&!BNDH!;b~k>DoJOD12AwhRg25oKU6aLpECYQ{5Hft#2an&xu$); zd~OS-FWNM(rY(r~>hhZ)No_VBkN*+?Nu2VdQk3#PzD-6>wIbykvxevRCK-E{6)UCB zC{5j#)ZBA;d~6EJgElep5*CULvW%9h`Xoxu=9$Gjx619njppCL3Pxw4khkxp zjP(B{To-0>Arnq)wz7%zjC(ZKH3-)u*bvGQY7uTgxC!A_gjR(02zMjgkMIM8A0zx6 z;a3Qm{(*j|cb|aeV41RKeC8RlmQO)W2!rO2G}-mj#Ut}= zA{3Aad!xA$c(c#kKM_nf>9PRAvw(gzUlg?^KnINl+n0@ytSw<`vev6EvQw&VEbAgC zMbf8W%vEPn8S{xUS-{enCwfuH{5^yZ$ePU-(1rTRPZ%HqwZdwhRV(N^`9eoiFk~{P z)N?uh8D-^4=Lb&w0Tu^%LeHr?*!3C;!{=W|@^D6t^S-`CaeN36I@JM3OBMs$3p#EM zPbc(qk!oJ6BRU708Bt+;RRnYK!@$xk^i4tYh^#%96=8_o>V*n?mU_8gX)@kHD2R{i zLDT#NN09N($)bn|1lEJN9JNKZKTcZZL95XM^L13o4C5zKE=F?ntN(4x(4V7zJ^BZw zU(x=?=Z)nKW4RmO2{)G8jpZfAa*wgx3tquF0=KFvDr8hXY<8;NlDNVKheqx!3%+}D zh5kX(^-=yo0{u1qLE?aa@HJ9;DJbn?1lmv(5yPl|kWb1#c#@#E{$5rpT=^9|yr&*i zlR(CE{cTS`M#lKtj?xPJ(qK*$HFT!;-LI>s4D#Y5oXRpMQImHJtVfq<_nUA&!MCn*7Naqu`ec+

    iz;6jmR7=;8&+;4|(2%?SXsr*D2V5V_$OGia72ZM)eEpbY2l5BaLvq_4 z*9ya7rd^dylPX76m;S~A^B1Up#Fry9a!~GJrXQhjSBeE&f>Rzj=tc1_vuAgn84TUArWYK10T+iHw!wSG2{(CVIRWL7_O!WS9o@S z;pAmMzp$~?#lD;q33@X1XXn`gAwQh~10?B3icD28G-tD@bEBqi8386NRjaPxBffnD zs(4<4H1MM^bo@{5<^Z6VFR#+umw>; zEZlh#b!medTh7#=p^$Ne#=DqUG+OTBq&%sUZbPp3a)&VwEO?MIUL$uy zxi3uPcmT*Qtr25tLT^+5`;O(~GmjO$Fak0II7^I=*l(MUDdfrT;Q)#uyrkRTvjcB+ z_xBvZ=hpjsw*3*~eUIxs-tWiUy1!@R#k}9Kh`&{9@EhJtHmx}-MWlZR@catlQG`7R z`w^Z*cn;yW2*(gIEZ~@)`v?CORc0v<{wbv$6b?5g% zJ#)96=iR{>2O?Vg@3Bt&1sJvN_CBr^1KP{)-D!oKFa8mw!I0@c(c)=8u@OLvu|JPK*QN0%(xLbV z1vuD}eo-t0^y5UTH}aHgg_b*^_qa6C;UhrMdqb^uoeJ%66oPkv=hPfJ zOF{etr*p%_pv>9v185S_A2$o(SHx|dvtvDSgYdaX7Mmrdjpk*!lujq5>mLPJvbGMT zkbCZsdAE`vSmpOKjl5fbQl>gPUd65v*`Mg4d;t%cQ#PD;@5d7@d7iN`j!bc{EWXM7 zx8LS4>O0JyDIV(`R`E`&c-t9@UzJ;Y^O)in@#(aqL!!>{q^OSl?GcoR14z}eBI9AU zN^%#QI?3HBn-W~Op>tS_MAd%Ysrir>wMBp*6+DcsHGOZm-hE}paBZmBT!s-8EjS+S zqY`bi`Ln?sE_@qVp*&iG*gkO#3KO%*mPXvagnO9rv6+?t*uQ;7oV7l-L_LtqTWfcA zei1ie9M}hmd2!2`GQ>adIyY=a<)iiS4_vVsa+@LAeFAuK1eGL9_N$>8HK%xIWO=ji zK|BQ;7sCs(#Tr+$f_OvxQOPD->_E1$_YIH$3|7vL?-j9|{Bo^~kh>meGh}nOe}E+- z?Y6M9V=@M=_y@jN++usz2<%PkBNnq@gWm^Q)%+Tbv1Jw`3QLm-L?6VVg;LZjA; zlkaAU0mMqc{6h)%0zij+p!%#$47<_zE$44jQdguU}D+Rud}rloZbEr!qNfnU!72K5IP;J{Zl zHarJb!uFgZHtdym&JM!?Dwr4h0Isk;z?Xi$+0?*AG4}`%AZxOK2ZbPq7QyaRoD_J6 zql+;PTQ@J`B6Ssc))+{;jD$j9YbF-_Eb2B5xuTJZ^>9a8>ZTsBPfLAW?q5r-l;2%WT_d-yrJ8ysG3}}z?r2NZ^q`7b zYJSfuUOvJzwYL{2uDO)VV!3@-nR_!i%Hl8@v?stj0y`maIcF{1O_A zLk9*7Zb+bE;ZXcx1CH-|yCt8I?R?OJc9HuHFiF2t<{J;4ZIvJj!O05g;=^cw`E4M; z8Lvhhg}M^gVc8(I*d&bo8?A1G!4Gt~nlMfO4om%5x-t^>-RE;8j4vAr*-IfD=gA~3jU$Vkig#s+$>jf%SU^-gIl3LNsUDDtqMJ_>F{#ucn zI!3xaPUI}6LqAaTuL3rdIBP@Mx)Pc5#bms%e+%C%aTXk*_wS=I>g?w9o8P{bZNwC%aTX z*%fBmxw}+9*`@l)F4a$Vv7cD=9&J}y^=9)I&w@cS&!kSCJzbqlP3J~t+cr1SQYYCC z6-s}H{QKBO-OvjN3gCSh^)YZz94>KoZom^PN67K>;%XYyax*4dtl4}Y2fzF`h-6k0 zpa=e&J9Pg^O2t(8Irvr zu^*R;*E?UoV~SiKz)itpusyZR>}ok)5{-?w$5ewWKA^>|!Z~KL;YZn+qtVPej-QDm zR#xQPi<}~3fh)^fJOxX9`0+N(SxUqJXC=`|?Z>$@g)zf>v4?n$d_qddbihfPwdaRW zX;Jg@dYn%$TS7-}4^+$bbk=ceE_R1nx>J59H~#0mnBAB|zikSw*7-U%>2&i6Rq#Uh z@aRZ44-0bB!|M$;LNbJ`k!O5MtlwdEl+~aiWWMth$eMqqzRN>{$C(0C*x$QWf;LRiIy48P=SR+a<|sosh9e|MkO2B?8(Vf!0w?BQe^Zd1H%HXi`C@fKDw zd3`3=Vv`|tOv%4+#7*e9_?7B) zc6t zjixPweRK}|I}ipz_hG5eSBZN}BXL`f5dd>1o&|{xURhwB^vLrJJTDau!DVCqh^8k_ z4;Ve^u>`3lR_X?(;-G+F_6SKHnc%fjZ$xSkh=ceX^huP2F8VQ4Uv&sPk%w2JiLgKD z(;rLk>4-4Y$hF3eC<%^^s%@IDZ5$~^z13;Qn+b|ds4+>LM_!d8TC zgnbBk$XAK$=Mm}FgK!%{D?%s2W`w^-_#Q$R!ghpz zL6{Hz{CCoQ{3m!p^`A6X{Xb)G1g_1vuEwUfzH{z_Np(YJrndXco=#ruh7-T16T+7v0pVYAQ2 zlV!DuhP40Cy4TPr*`w(}Fg#+sM80I1kPQ*A4uTAJV~-vA0*J-o6@-9r44F8D%n7{7Bsquldd*sZLk7rY zPV5kIA7VlTCrl$^M1(rBenaRQrGjVr=EK1(pA+x8s1dd$9K$} zwC{#j&badH^Eyefuei)n*1H zJAvA=z`5!&)%>k*dH|Hi-1N7f|F>)J+Wx4&x#^BWgWTiqc=z}J{ieTdKl_Ks9{c%! zd(`JQl7Fb=qa;5bEvF+|-4OAv;j`M${V^6X0OPQW+qBhrZL)2V-(_OLOk}ffRdTr0Icb@;r^FQ~J8*2}^v3@e8?BrdkeEX7f z9?HF>_CUVthN_Wt+6(yta=k(ID1KpNdt5k+yK}J0ZW~rKzp72?W{S0_juij3YM}=Pc63*A`FBJU3O^5B*?K+wK z9b5BV{Yx07#|d^ElTm-3=bXdi-s2DZ3KdbcHyZrfZ|a2|EtKpZo?kbL`|I`QU%hq3 z8*As^^HN?BTD*cmapMj~!s5&LwELM?ZhO{^J9a<*z!P^r@xWtuw+@_Z_ZDEkkxobbY zE%?FX4?H0F!4t21Hb36l+Q#4O#UlP-+(B`8UW4)9Uwg)}1FyOE(?x!1^1er@>=(Xt z{dI{PXeEjB_$S}GJ(zv#-s-9)zxf*!$=mBUJoL>o-(QPHoV~W{p5MCnq^ZK`uP*Xb`A#}0 z#dEa!>%p5j`S56X61f+we@B7?{FT~}EHAF}Yg?b!*Ae8d``iIPdI0^M zkMKpmbNAZMy8ZO+XU%?I#Lv4^0k`IOIL%*ueaJxOfAXsHo^ykJyy+na;PNiUO%J`{ zVR?=fu6)saK%2Uo1+(Vw6i6hieev(k=yz2=pv3v@b$)pK_?^?aTz><7_XAQ-rTyR0 z2dlswddMzk!2@2( z-$eN=ia0m&RT@%jS! z7sm3--~Sc1_P`^aJmY-{^uY@F5O^0@1TAnG_*t+UJPzyxN6%xUO!(XrX1v@JXS^>E z7llL65W@8_l#Qk8V)UrAqsufm6aYB}S z?gaAI3FKYmt;OvJZeCnmb@ddZYz z+EYpKYE%5sNb#omp`GGQ^TRScRpU+$(WcqAwxKUqFIz9l_N(^^FFz_08tALL`pSQ) zex$@|DaGqFl;oM8CwcW0&o3G+lh;b|ivHHT9=z6KaP&m&)=%@Mw8t>To7NtMBT2c_ z+QWxel!d`!YrJ2&aXOED|H00}X*``%pA;t*s%_*9_J!>&uRN_EEhW5YR>*G8)f8`9 z{}`os)5cf|_=Sc{{;WUjsm&l0O4 zJaykX6IX0sR{v#R<;MTw;#B|T`zhX(epE^E;&N4w$??!g@uvBu4NvpiZMWT`Db6Y< zeVqRiY#y_DZW-QUtz52gcaU6&1KXJ@|zjyiQ# zuIndJ0)APCXY*WfGDL1w+i&ui@<~c^CCS!tlN&j^7T^-*0I-TKr+5f%9SgyZJwnq!z z;^NUo>&sK>(Mxz!{nAhIrpkINb9&y@(_8rU@xb;&R`Os^0WRqqm+3w~YKjcHTj(p&|GI%DNk_RSlB9HByK`yYA4fO+5 zJCgH3L9%W3NphEe8F`5?zrMb{U@}+6r2kgo1s}UxOC+4YZ1y^lerFUnSR%@(k~D~&+7rN+C?7EV>?K2 zey}z$`&N)w_TK(Sx8HtnZw0x6>X?i#*IsK|>T!1Rl6HRk_U%@b%5ip>pX@$TM6S+2 zm&oi7KJt;*YPWLDiF$e=>Z%RomAwaVzx4!m2JqI%prCnivc5~mX%BV0ARZ60HM*~a zd{n6R;W0A>p8ar%(&hZ(hc3md4&mkV3;Bi8-fOOj636{#iPgd?gR5aiJ$qSeP*|r9_h)ldkJ1=$t~oi zM`O&{6NY@Kt|A}g^Tk3jpC6E*Al~Ho7$)W6EElrMD}0vr^ZjC2^!>P>CHkz5mAUG} zJL(tnIeLw}xejG+K0s@liO%1f>hJW}5-Ceh z3weBM6HL+5b>(SanAz__X$A&TH@fr+mB3bj}RXH#f2&5uB%-9681Xn zY3;#cg!xO;S1z}EioOawx1VIK7x9w&qs?1wTx-{mk5wPJO?sNC zOqRZHdg3Tl8}Ncg)ALv;N=I^kcjK##+#mRCK?c6&;7C{KMf3C$@@CE!5L5l$ho|vp zK#xLJzZj}KHlgxV+}>Hd!ab%>4;MDpe_1@=c-yy&I8EO?yj<>RyIm_4Vt-}n>qPo0 zC$Mh?-qFA>pQybD@Z31FT3COkVBXLQowbua%G5 z(ZA|3Dfj+CKgJ|?I{0hmVZ({ zLe9~Y=}-LXg}4oP)xsC3hevf4NKjDQOxCwzJQJJTwVxkGX9?8?^82$t45Y_DmOr+A zW@4Xhx~ogb+cg56Mg9=de(NJY78G+cxniKY#$(H9)Ms6C387@kbN@*B=|D!+ZLcPH&x zQF+QmP+89Zx^m-Vu(e!cr0NZ}%J1wgZYl4D%I|L}ADFy>+(PUWGRe-#`Uddgs;ZvO zZ?eJJv4q?_!6HNQ9UzkVe5m&0a)!>IPA-mXw{_&P%jNIMcFBEF^Kve?$DW{AKI@0k zJg}js1aA+sMZ3GyZ#!BhuMY26UjMWAn=Rz*)ofx@ePomC&%KZj)h_a4ad&Z#oI--a z$zal+6?kW#z5DFltssckn_0X8ynKFF{(Zq?*AR3; z6VyNvj9A03f+Y}uIZy^UFknBk0y$eGG2SOy)?1a(jbc`)S6X%#Gk4rqcpC;<4AO{9K-wZ()G(im% z!HDO;t6&KPU=EZ)4h(oEz5+U+3F@E(Jg~-l1IwTd8lVF5V4e3YLeK?GPyq_639c6gT%>UyKHs^Qz4>v_?ZcE-za=f_-ePt%eEPVmIH!WIlg`!LP zQqL8+%2$`tyyzq^i?^EQsZc@|Z(qDQ)>{wWc;mv1vC{V=Td!Xz`)cs= z%=O3U8gWCa-0}5mzS@KrKc9~u&}Z4#P4l7$npwOs&70zv^)zpaU-I8b**C>66?k+3 zb%Ko-k+SS-B>Fa9M9Si|;kkXEv#Y2K9f=))`53JcdTIAx-O{G6QUxp6s! z_Zq#AbZ~!aU1Dnz*!gPVKE~tq*IYF-v)~n?7e2DutCHeP^G74io6?WlY2FmSEvI=? z{I-_nP4S!eO~$uov!m9sa+~=j8MoR`EI;?syeWR^r+HJ#9j19x{8IR5&3kt+@iFsV@1{Q4m(26dFFw5JczvQj zsZZsr^T?xmZoH6`RnK;sH>IB}r+HKSv6kjd@rU=VlzmhDQG%!Uk?e(}DfZRj*?H=B zk^@lHHyMX&>U^~YFFHTocp)ik-sz=zZrf!0z{z>BpXN=O?}lmKl=-gkFYM!d-*5T; zv1$F&PxGd<$9$SMr9C=n-jw!Offvtr@suY&yZyELo}2Fm@OU4oa}>lcBxSWnZfN&2 z=J&moe97G}vifN`#hd1rxioJ|e_>Oq`>2)cP4VASnm5INt7+a8|Bc`=E(5=)V{`S% z$@_&;^3~$Er@fDq+&60QwtgQe;WZ8yB-aALGWih#3DG_#QnwdWlvk>6&*pgs7(5Bi0qK$%gDEWFDYML zMZWcWN%`s!IcrlpnTeWv!Vc%x{C8E(%H6;;HSD^BY%AYfC*rsB(J9dD3o0shsVmOL;w$hsf18)JL-V#{fC+Cv}=s zMg2n@=TASBe(zsp=es}nfe*fWs+~o6y`J*Ael*!GHRL=mq$9SQLFWAI?vwNIn5S4e zxS!G|-$nbJkbZTc?CQWHjJ=>F+b8cIEAXya*t>UuP9?c~gbw`U>Ni0Cid!4@h#-DJ zDNB#{zuA|zZtHb!Y2~CN8E4YRx(B>VNGN7`Iy~?0?|heDE?|m_2Sh$(}(dc@z17 ziWLh5W}N&$JhjW@dZLq*x8W$27xBW_Pb=_vKZzHV^oEjqM3v~151c;-@QyLb<+dL) zyIeo8euUP1HTS*oeJ_dT%f#QlZ+?K6z0Oe%)_utJo|0ZvQW=xwG?DY(fW0-4CGQ}Q z_rY26W#qfg<^Z;Mv{+P;1o4t}s#2H-;4NG;v!G2tmYxxE{N>MH_TEf+;rn`@V}>oj zHP>AKCh2tLO!}h&j|S4p*|vaN@fz^l`Y+p_HgZ&$k}P|dB-i^(yug$t?<0@aQN`jw zR=9rU?DaxRz%T34bMtbze6w~)E>-%HdMPbmWzw+csLVavx9@WOPUB*7T~UFzv0rT{ zZ+5v2cv1bPmfMDhpB4f=z@6gvWq9fZlzsNJalIye(S9|{Z{81VpQlEqxt;x4{wTtW zHYRIEbFtvX3t~}dUX6fl5=RspAOSVUFb6H3l_dn#vB_wE$(wyLe8|SOYH9nOl z{nEi4!2IL#50MX;^ny>8pWE;(D>M^p7(*t)(xJc@L`sWQbc^Nz>+OvwvPS@r0^qrXI9>vC75 zPcJm_M&{y_atH7@*LC5{t@Y*pJ)X}rxj3Hgr<3z&8J@YA9m}+SFb7Zl!bYZxvqrK2!WcQX&+U;qP|VWVL6(+XjzYqli=V`S2KA z#}@fYl%3A0nfCDoO-|n~44k5`1Mir<*EGG|SH!b;3bty4ra^OoPI5lHePMgUc}u8{182MpC7?1+IvmR0dyQFc1|$KE6&I- z#j@mTUf0CZqbjiPL4MgS?OQHm(;WYPN|xW|;VnM*x##HprrTywM9AWG;N=$%o_5;l zm3rskg0-x8$$iY(zXDJ1IqCln~gEp80Wsm~{=7$x~1uakqYm{Fm&VhC2*FNZh z7N~irel>YxmAV4d^lK3D>6&;ULtf)Qu&YhVR* zK@-$K3FN>!&o2642?SscltB&*cy6--I$$37pa6zE=jwwVXn{H?0S~P4%x@XAK?77k z9`KEX`4DtL6VyQocwmj^#LJ)!8lVF5V4dgcA?Si8sDUEzz#8usEQ2;^fC|Wib>77Y zK^HVZ4HUtMcT!ft5(vN?D1#gr;OiC80rS8I7p2~pT4mgC^nv47KYQb|H)MSm{KagM zpT6Jd^;iVeom6YLXg{k2-}8FDw^R3x<$k-}U)Fj^A+>+frO#aJm&A+p6u6f)*KxAW#oFu!6S~kWaIS;{d!7XQZ|Bk4M9AWG6JF%)Y+jh+`KB$Kw+_#mW#ILq?vUxH{3%gATb)MC%d)Qm&$r<9w6-4i zhvzp^^4Ko%oIkXNx8Mix+`5JC8YRvUkNeH@mlAz`u!)!GTZPx?1Vi>Bnf-5+k{2UA zS^cGO>V}@F{m)N$Q~Te%cttGZxA;|F%3r?6xac6~dy=j??VE02G~PeG>N4{APN$h4 z6rZd(_l*l*w!RGeu`GtI3o;S5TKjBU3r#*i@#iPO&vdZniW6J7) zNk5UN=dU2=xBA-cVGt<4^JBbD8u)9-3HGFknbgYBx-2zMaW(Kq@bsub!K)d~_DQLA ztP-omho*SZdl71z=(#0xgN14>&5Jyd#cQT{%s2{Jye>TZKBVO9kS6T2K3@&t@q5hm zHhSa_!38&OttaKRrqwfd+D1KF@fWLQ*;P*Srubtn&5PP0OJ6X?E1Kz9yd`)y-+aq0 zx7~K$!BzOR4)JSH55Pu{6&&qIl!| z2u<+fZFD??Y5p4TAHF}I))&oS3D4B?!}mMzw37k67v<8`rsMr`;IBBIQR5LR-gvnK ze~{J}^~)???(|f-Mc)d};+5f*89A!+V)TnAYOj=i%3Pg;_x7Oesnh*bQ1S}iS%K#C z@%AWI19%+p?k$xxYTddbYrHO{cwPxb1o6h(ZQ!qt@!S_@W$7D@@wP6v_^`yjY4b^K zj8~L-X5V;!8Td_j+y(q%(JLnR0h_;ktuwmFf6{w+@MGKo``$U;UhhkGFC6z9=Ya4Y zbK1imT-$r+tYnk&K}t^zEq8jenR>h*XTGhM>OFL*y@e#O?n6HC2E74^>i>z{4?Q}3 z4LQf*J|a*3S#@$ja{4`TCrzK98N-*nExBDf`L^gYGLn6N3Aw)aDE-ApNq;l4FTeHS zabK_{PU6>C-t&i&!&H!+f(v1&a`F$yj-o$Mn(8@Ok23Os-)n3ouOr|5y+>jzuIY@y1Fu&ckV|D3@4nY4KQ7mOIrJOIWg(UZvd@(tk8=**k;f%Up0u}8 zeZPmidxc}jwxqwRJqLa${XU@x0>_hI$Nh!<8+Mp2M$Gb8?h*J4Rek`9Tk9*s8!~-y zkmGHKmiSG1dj1@8RM@^#@|53w$y>Gt%+c!eqpo%oCFMp-%<0|kAkJLEje zKi)4qU;UzG`Q3gyOWsA^bo)%}|Ks{Ye+9Y3{pBs{k34!^$mWRg{H%YheAOUG^-HSm zf?wFBeWJc5BnT$j4@S?gAa}Xx*ik0+r)0lo>r#JigO~3AQ3g7AfZWw1y^fFNq2EK^ zoZ`n2xtfu7EN`|m@CV4FePCuk^?ri=jkQuPH_;9l5&A{sZnu`*4}9eDsYzD;hVpaKR5HA0Q9SLHr;^ zLFG)&58jy?Pa+1v=JDYBCFEh$;6W%YX+6n&R)aTUUMS{sqr@L3CkN{uYQy2kl_tVH1+h z9@S&=dzWQtb$~qHFJ;x!E80B4+c-zAN&FQ1f#-h6hf%vH<13bj+#^)aPG`XP31!u@ zft-2NLXzKkQS(TEJnmNN+vDxP{SUc(r0)&NvOh$AfG?HPE+k7ni1bs3R68d2dq0`% zce3m+A|JM8L3@~`-$x$rg0kcd%fEF$2$0A7p2YvLe^_ZE-@`5Ax4hee+k#vDgZ{;S zF*wTz8pGq`xLgh4`yS20swVMwQr{tRhNmBpSL0lDrmv~L0nR_q*0ULI>ICIa<|8ju zdzF!s+b>44$^3QXf$t;re9bed@lB%dHzgT?K67O&X5WjP_sBIRr^c0J3atA~ zj&KY4DspOHe$=V+wu$PVs-M|ckMfsu z+4`HvnIFr!E#w{KzJ)O5zoh+^O}}QAZ2haqxt|b<#jJUJD0x&J`Cmx;KYxz)FD|Hl ziQEr0f0vP?-Uw>nRR18+_v^?ve;<$Nu75R=_xzp`EN_y(7sBy7PQNBzZbf1_p6lo4 z2VcBpl>>u7RmDp4?9vx+&FQm*#9rx9c~s=wZTTy@-P;=6a?}^c=O3?HME>Z<{&+q& zf6En;jkh)glsUp&QsRFGU$LNsDm=dgLTfI`k)5_FbB#Y2L_zI zt$+@g2RBz zsDl#lz<}o+?%y>};nffro*ekg$TvTqmE8j8zQ|b{5O_fAib>7KN&SXtUda)&>?u4x zrLVX(&rk8D`C&fI^S9R5foIiVgCG6cY^J|fVtp;XR$_i@eFJ#D3trFB?EahFrlv-yRuME#_Mge!Fh^Kqjc>nPIxs<;6exC5iV1XMsyks6QGDY)MxbPpEg<7EC+=6rPx zUcAqbAMi@w`13KZ>itxj=N>?bH?EKG{~P1Ea#--%il;iTJ}e$zQ(7YTp%j3$xYgx2x6J z1t}xQ$nklN--Cx2&3_Eko@h4zCH_?k^WS-6JYT7r|6F}_rQrKzc+vbvKMj1P&VX^h zF#nC|^Mi4ot`wO6;2lMwA$qWx)lZkkdFH>Y{A~}O*1p%fgGtSWEdDzDs`nW5 z{}`vJdr!zOT)_Hy)AQkE-l-uUY*~V?&(&uR`OtTNx=3}Il(&#?eoicZDRAFMp8cFS z2tE9{BK^j7zLHO(fPI{MAm2j|xFxtH=z{kKRc}v3NcuxuUb#BjQlIM6^Gi>)-|w$W*EpPRL@PG6K{Ai4okM>FPg5GAC~~?|^9nrQFa9_79eR+Q{JMj+sT+r}A9+d) zZ}Z>FL3?z6ZX#c<6^lck2g*t&$gW8}9e94T-_sw=vB_x@PwN5R|A8mN6}$ivLB1I8 z&paN3XTnIH@)s$ApR2G3zQQrozUuQXsQm|i2|44FV2?#ebA4dkpS%YG&spPsil?%Y z`=b2LIWWAkuMp^mxnlbUj}M-Bf!~EUgrWz{l56fIJsKyWAF4cmW8Z61`E$Jf1AhR| z{gJiw-@`IGKSDqEH1}L7d8*{v#FZEG_#O~=?zwZ@+HKsPfnP@+@2_RYq`Zl|L4|1% zRnUU^uWSD(!Q&iUJf1)6k3D78dj+|9IP6*fA1{aTkDT92F;lwpPH&c9Moy0&VcN4~ zF|&BZrziX1ta{auqr#MA$>)*V^XR|7&3rO$FW>uve52n)Zcx7&9~ayQR1VLj?ZI@! zQ+eaO&|j54yzGMKi#h|w`zwDBCn?tpL?UFBTYSbw{er+)+2ghbFM58#lYd9d@@EsC zvu)ryKUB5zWIyPdKDRH<@@t4ZYGi(ME-7!^AM}5x$2PB7dUCs&m-^OzQ|niP7wuc^ z{yN@{^nc`G;F}@xxB9jVVQAwX`R3n?HHNQwrh|O*-{Xnc3H zyTYC#1R@bO`#11M(zns^f>6AqpJ<-(eWCbF>}I0T?^UPmANMosUwFyBRNCAeFv)Ae zyGDy%ZD1YE#>FJB3om}&t+`3hyW4@wAnrJy=YLjy^x%7n-XXkXU+joGHtF-Kg*~o5 zs?+9rM+MMsK0NeoFEln@2etk&Zl713hqt)6*tQ*hls&854!md1UU!4r$2wxNuZ!n@ z*1ho5d?(U3fS2rxx7L@tFum_|JoWMMdgQBRcxnl)uWsevA^yb!C#zlN;Oiw_3r=n3 zeZQ^p`92FhPhX69o6G0?10MSbrg*{>eQWUIVuOg6HNSbj?Q`sl8>aQg61=BB%f8RT zZ35A`**<;`7M{vgoo&$wFRPtf@REJ6Gcb$SgEv~VU*BJhpHF6$+lM!{N!`M}q3Pq4 ziOv}7%PO}}HNR+o8oiaAU0)xbdrtqM;8x!~r*CX}POpBeb(>$EhhOwqO>x(3x@u?k zhc3LZyt5p_k$sxG(IGux;D^XZo~wamZoakg5lTKlPVTbqdr5vSqWs>h-6xgcYu=0d zlCJsh7bWMyRWrvrb@@pAS+-&ol^@29n1I?A8r$@;rIQAYe(f@kAS5BR6(tHY!3>xMCv*MdiF z6$ZsfU$P#wb|jVeKwP;vaJv8c@F-R;S0UZ5g}v%mF37Km+z+{| zR*+K+AKm>j)$d5;{YT`R-vdbcZ43G4_W&dhLy!Gt*XcLM6xk$DjP>pD^;_Vts2t=L zsP#Bc`ebC_4@_Suv8R5X*sJn5_xqV``PbdNcw@a>+t`<7%`YW*kK&Bwbl%L*dGp>a z{JTs_30d=g9X{^|jJ+Trei##m|`ay9Umkh2-&v$K8N{+{1Q z9(c|Tfw8jJvFq?6v9+md*El8c^UvZrCK$n61!u}fdI^bGRT1e>%bMz1uZZKDj*MrteyK{2?SscltB&* z*gvd*4rqcpD1#gru(t|9546A>sDL~evLEe(CGB6q94LdhCH^zxJa!B@FX)3FXn{FU z201X`%p?RI&;)f*26-^x94Q1n5P$~oK@p5Nds_v|paYtq4$8m-tDH&pKnv7C33y2B?5MSm!xW2)dvN zYM=;4JTF@XOCSJqpbT6+qW<39GW8@YM*Uh^*x>sh0mcLp8NL&@3{A6 zPb*XX`!ZKwh$Nxq(tLHAeTws!t3&cnlvmiP35lTc#`(o+`MKNjum9m)*rniX6EAu1 zKsk%m#sqJ7!Rbr>u7=~a$9Yz^^iA@X$9X#oJa-`&H>gsgn! zi?-!mA2|HwfBcMh(aWBk-5&Gsvix_ESHXXcE%kTE*VqUif7a8jZYx zjf44d-oCBIL1&z|yY~x6 z2>0Hrp9@>mw+_$E!pHfJr$h32cqlv`9QRx*RkFEfyk35_MZO*M*!bV6-WfqTEQjj) zMAn;6^0o!aueES8A1kF%T_*oo-qm3vdyC=-QGdwwPepdOD z`PWXE-+EcNRr!S%o~ZsO(a!3juKttd&yk=0IXJ|>!;K^SyPJP&{2Mj~{PTD&{o}#T zK>4%!NtgUr2lVp+1EbvFFT5V*C;u9a!PVi_mQSURw{yL^M!t>PgMIMswoU<8z1p=C zA1s7^{zaSlx~C|J@9Jfj{0My?emE99ySIp;`%A2=0r z{to%i^d89!a*DSx{x&=?@RIR2IX~+D)~K$M|IqP6$1e>o4XzF@49+`t-Z9OH8m%WE zKl!*kmj~nXa;KVqG40CyOaE$IJ-ARGL*+Y_Z|c)rt$A8k3hH-JJKHtq3)R{Q@~7uz zBG}*Y3I=$Ydc!6ul%6!?sl2B>NZB@W;AZqw&UwY=6~{)N99qW zv9r9hu&;aB=<=re$RHfh;;tUbO5!#x%y&bFlcC&PxdK2iHw&(xfmGf%Pu>gAn+Ixo!E=Ho}u%_Z`CPE)?69m5fX0_X>PXd-ojwdbAD5 zUSH0Or^Plw^P9Uv>8gB4<#v!aN8NI{J4)4Ca#ycqW}qsm#sxuhokF*$Y&{KC)4|1LMu+zgDaCQ+`zbko*IGgxuNxY@R@La{AY9KRZ9&{${oCGR`p8Fo=-YuPe15 z-+zXD_f>}vpM1)m*MIr&U9VXf+I~m`Ylq2x(}b^nBdcVa1$`vQH_83W_tigo@HM`V z7mn|?^AI>{-|=x-tgga4d>qE{!zR~S-uYSnD^^Fy|B*XpBPg?)EO=LWWv{`S?^2Fq z&or*{yVDybkgxD^&WrMUuKwjd;g_%8vz<BNx{G>|Cl0LgvGl{ZM)726kv zVmp72w@={bU%~Surxv}gAnl%U1om6P|N;N5lPGk33zhHG~palDD~ z3XfM|e}VJdp=&?)6E9isNw358tVaF|{1W`6e9zme{5g0@{kJN=SPkIqvUA1BcGNm` z>vmisUu?Dd-R@nk-$nC`oInWu0ld`tl%>iK6$CPorKPjbLEt4;O zwxrZ7{qyj$`kU*Cp|WM_?~pG!XEK_XHE#Ow!Z1)H+5IEAZ|1o_aqfrwcz8UN2GxB= zA1o+Kv6{b>=lw_a+utsh{v^NN`^{I&$cMw&<1QW!ordxKn)LPjI{ZQ*pD&k-#YTe{ zmO`g4vaW4;{E*Qn+%!>?LwhOgxW{gKQkr?3k>r?~sX;zqpcl@8W^PR2xON)GmcOKq(*Ufj{d^cfj|JwfH?&0piuEDNwXJ{)Al{H>oP+cb9afU+@ z-25}nD^}NKR};I!!@*tNXZRZMk#{fgUEbkwDc>(%@(YF*3T=A<}e>#xB} zY|y9leTfFJz`2ijEU4mt#|Ot5Mae(Wvc^-Fe6;@1&K=8#hKGh~(?NOi++)1noO`Ie z@%G=iigy}W^LlO{eq}Eb=iPkXls#Yj%E$T|pN2`T_!PQR@U80CBH#Tv*O{!}va^#G zw9*EQSw@u#pI+WN`9h`^&3{?vI1kKDL#;OYn3*bzwB(7|hlvu3T$x^XICSiz_Yc+tQyScp*E~Mx$6Pm-Fb( zUY`_SowWB1B?w9X>-jb0))=I!eu+E?)&J&^$NfsOWL@R^>Q8Ots*|1Cs8R&!8ShWU z>Jq$mv&o-*bUJp3=*9u-Gk*V7<%HHl=p+h_Mi>~$OV(%cIx6&s@Hw(+Xr^$1yc)2C zEPnBqx2lI*U)GWDZeBI`dU!ZE93Bb36)t$Yy?y+6y+r|eW3B3P@yaxg>2P(h=eeCXlIZy#PutpoMfDUMa zIw*r27|_30KnKi&GRT1e<9-Enz&!9l0SuWZSHThpfDdwDmHR{&G(ZUqxu33p0L+0h z7_qik1zpepB`{>&wE_ZA19`B0}2Swn4fzH7}4+NkF@?h;H_#HGs z84P)TvJ9G_3`RUhS^+Ik0VAHPt$;R|10^uxSz`zS-~&(BJa-L%5AtA*=gwU)2MS<~ z=kHz602Po2>%7Adf-Y!+8YqAv?{xG*Pw#esIw%1TtX+h?patrn00z&ay+IRHKmn{j z7u}!>nxF;>VC^~ZQ}3az>_<1F^c>G?+^-(tzyHE>uYbX;=k;e5U;N?+SiEp)q58ky zxMz0Z(ys61o_EQ?D>kkr*ZrZ@+?Lne(k6Ztd8J43%U*ol>}&6Nn_Vl`wfG@C#jC{S zoiCq#XW?73M}Fn^tCV}kM{oa-U3*?lcHE(KmHF}V@~q-lz4*H7(+_^7DxPBL8AkfN z*E+rVC@vCz_*Wip`V>=-L$7|{8|+%KuK)B`et%ZD;nMEx`Wrt!t902fzG9W3bhuUV z6pMS$8$VuEeI#ErT?Mo6V$$xxXW~f52fqFR@)WELai!zw2d^+4=<;28p6AN*JaLq+ za>P^p>QQ|f#HVxJB$iFGPi;Vwr#6f2Uj6RJ#>$rOrC0V!uZs(j4TTMxq*L{hp0qxt zW6P}cN|$2QL+P;{s;}~l`=lHDrt12E=gA+kS2|SBNVoY|WlOL0#QIeK((4#o#1&%g zvsQ>@qxyql`Cocew)85N9;K^1_1)M9N|Rq7Oq$A%{qE{5|6dXLzd$UwwovTa#?noP z@~W++Q~Fe{Y?AGYWrNaXn=8lp)zvxf3tzEzP@SbG*6IA1^b_f#>Ynl{R=s7Diwo7W zNh!U4TRuIGrDKM4|G>8VFBERHe*X)F*UUb5=RN4CnOz_F`cIm@uf6A#$WN!3|CR3g zR!#9C<-vY=@n0Ul}~!5C)T@+ z-nh*at4)5D{u}#N?GXD|>AF@ub62|YUx?xovHTym0~AkX%g1q>C|^C|H;7e+{ObJZ zdFlC2d1HALhmn1UBHkgbg9G$rmD49(e96*!Wml{>mTNv8m>!!44!QR4TYKhzZChUb zPHnG#qq?a7y1Aws+i3MvI`z@qYV~sYte=zL^E570-#D+zk$)7+CZ!AFsT|D%DmN}) zd*u@LsK1D(exfAL)G*5@l`_s6a6Vtdtg8nbad;&Bqs!*RK4Z}DP#Vw;q%aTCwG zs;lbd{N>Ju29&FEWRJ74Z{sq~r#S9UlB*4rpLViXd6lky82iilVe`E0{B84w`CVsw zb8q1LJ|chU{-wI=ex^81kNu?m{u=xl;vuo@lHIZW(yw;Wbv$20bA`=6vQO#%f7e6p zoNw`cG3WfY`DF2Z@3j7)c|rE6-4$ybtDl^E{b$W*@%=lxzgxQV<0;nfTt3g!d_WPN z<_Yyjl_Oq!pI0n@DP4U}Jo!QSRA1>)tn!tv^2LkGeK@*%*zfv<-8Zc~*I)WpC)qy( zukl9b|0Z$VALZ|OoJoh;L2aXS`ColS<*Q$)e6@r6k=h|1PqN?jt8O$_<9qPd>wwAr zBzvVt>C&suDo1ryxf%zuL$=8-m9Ni=Rkl8>9`X2!>-Q7XyF-2DXXTThrB{9yCz`L# z&#J5ZtaSNVJo#Dq6uY{A*6!tTe~9~sYv;b{l^t<^ipy0jy-HVI?)mwbu z_wC-S^3_k&zQLQ^{3<&%zse7?O@0yLYsr;=+rkA9V>ek{K1P0#l# zHfjV%1BZRWI@6H|29F$cA)Dg+kh_2Ot^HNMc;1n}#gqS)PxoKhuUPHx+UMig?&guGUHo{Sae6i1ywm!j z%2gZ44vh`HgHybEYrn?rql?|~^MUbFuULfOPc*r7KqZ zYph{Uyl3|{)=*{l5ykJqR`m;=vxujCkn$v%qszJ8={EsEEp zctku|ulPEyM_kYNTKY=Yx_VWjxJDe`$K(r*Pt{9#q)%-jyEQ%)tA8k696@QyN7}|Y zf}2Oj_f_Iar}C(N(xW&Y_bMkn$I6a)K922s81^@@H?F6P|6}vF)-5VW?X5D^2UU*d zX;-g3)^Cf8ZoVxO$L0Uu?jL+?b#QH0I3#~{uwU(7x$ghWZ};cEr+zJeru*9*ZwPBCNn4y}iEtytHwTFIorRA-(lTUn7c}Q5+D* z?Jhg0>ml)%N!Pkb`V_02Sbwbd{*>E~%2|uz^(Y<@%a1z8lz%lx#nKNU7{CFJ2_ZjI`pI5o!$(|59 zv`<d#J0GD__YD@>-leKM+rPRkqXb&Rtbbye?Hf)zjT4+;a%oIX%I`#kJ2CV!yqbGeo*`6u>k9II_L59$8=qv|g@*IUOP z^>O(}eNnO6Nc~*r7V?#1`7M5~r#>TSytHn1l|Xq>6vYMiOA zidA=||ESwT?_Gu1tNt+}*8b1cTe0WqS~hB)bUvwBy)>Vxes5qusPy-89w44#<(mPm zxAMLjahurrE%B#Y$GdCIL20@4%J0%6zpj#B`bNZYK9w2IKXH3WPg*WL;xRT4DP8_m zIr6vWFU8Vdc$+&%@rftvulhNAK1)CCvTnV==7F(#l27)vqqu8&Ht%mj(xG|Mr#KGs zo8}VPs_`JX`h#N0lrDehbL^M+S{%vMzw}x2zT&h`T)xj*nX+>YJJc@gQCxhxtGDvG z`v0G`dlP-q9}vr5(yRNNt4DH9syb@_OuKA(?%>YVr=N#QkItjy6Wv!;j`BHwxbii= z``8ovSFsy^I`jC^-UsG7(fmi8o+o6_k9z#8KdeXgjELiTO)(;y=j30F7x_u!NB-4# za_ySD&(L~D^!@{}#)tUv{4m)bI=4>u2VLvlsd+}_Me8NYul^x@8h?s4R-{+=*SLSg z=TwvD;cE8~d*b;;vGm9`<(Cbrr&yr9W-A z^66S~jgM}mca=Eqm+`td?ica(4E$ll_ulE&)6z$uF@54?UB~r`=Y{xM`ikgLT#jNt zitEI2J!5+n$Mq(Q&F?|P@1*!~{dFEDethlb&F&%11Dc1WU;SOJ1eTy3vd{aWejH`1pn$zH|->vP53 zLrRzbqIA=v@e$>V-zVVSZG1bwC10re>OQD+%G=PRa^-*RGi&%u*8;!AH2Z) zr#Nn>HtDK|{3?C&tL&0rWryxPise_O%OB#&ud+k!r&xZKT=%E69{E-2@~hJ2SMjAs z<;t&$Qp7mJ1$e;21 z8gAZ^UsX@})z#zU8+uf3?AIRtl3$0!@@wl|+Aq52Qi_4usCvj|`9*b5tU4)Obrnx_ zclG;##qzPzM7s4`XT_#t9I43bjRi5qj=Ajd0wb|sJvh2A+lX|sy?z?<=}fOH!gn$T|MlRzn6)n`@h0} zc|d(e^NRY%a?{Og@%12et@r24yjK|Wb)J!b-Ng0llk08BD+k7}>l4>Y6W89A319jv zscYHSOkGQVIB~r;ah>D6p4eXTixbz&6W41K*LB{nN#|cpUCSPi_eIk3?!@&R?@PpT z@q^U0>}f^sBgo(8uju`O*#Di0>m1LsV}0V6Q`gczm%5fbNL@=_@>f#V zWihwer{4XQburiR;0{b>7zh&K|W-BXuqR_a?4~scY4z%z85} zPuI=gOs-{5H+3y}|6Pe(`a9g`us)>0DbMfBCLszSc+K zpWkHHXPkYSt(TOpb=6w+H*J0Omv>*}YyBmjV(AGZeXCJCh~gpfe|z9pt6G06*825j z|L-2tuUOaT{orl3Zl3x3=$wpn*(<){3xZ#?=WDNh=6igtuN7;3{%g-a!}hn5Ykjpg zbnDR@4!QFu>C-ywjMuv}DwQL9UCcQ*a`{zuPzBGG=Xuhnbd{s^xawE@K(zlP*7G)> z_`#1}F+0z??$bU=-lJarZL@dyi8EP~e{5E<)_{lp^ue|UymR)`X77W~xyoYYQ#}-` zUKfA&Jges~KJJ62C#_Fw+pGWSrKb0m-)LKW&lw-IHE(RkhaYm#*0iIUtE`@%{NAfo zzp9H1RppbNhu`^I7Jv8sAF=u?zv`)2YhmeC|BLmh{v+zE1#0eAx2|pzzwcK+W&J_1 z{Qu5xgx0@){qjGt_=SSN!sCex)yKZ#FYI?K6s!HB^jY!LzUTeiPg^s7d*(Wzgqv6J-bw_c2K(NA)eOg5BS7yn4K4V_C02&>LdG9PsOUY`iYC(`}`yP z^6RI+%~!uw9FMpBZTwEq?>@@<{U80r53AaL{_8hCV(q=Z^)pufE8hMcd-qVW{I7J? zUp(SN%18Sgk{*py?axZ+J^a6ye2uT4zjwds{pa`HVS4}ORVSMt9&q3h=6}V~t90oV zPkNP4dZj1U8=!ainD5y;EsE7YUbylFn+LvHf0?zTV$BOmkLQ6k@~OY9NAZYQ?W1;3 zjL1_vs@>F26pLT{U^KpnpY}5cv8(HU?C0jJKYXvWbK_ce$MPr+#lyZs5zpS|ucPOC zrEgj}wep{Bl+z{svJbpK^{(F5e1PfIwd~4&<82$)lIy&E8UE=X`MTzTL(f=!C-%GN z=mXMky{gke8D4y!&^6@*F7eB%Lar69vaklk0#nStkGk(?Hae3AUf7|M@{cpcv^H2E5s^x#$1+TJlf60H7%{v!;=z6n9 zvG%q~*SHxz<`Nq>w>AI3$0YBHCv>cSdS0_kxeJ%ho8H;Ky3X`o{Ngh#-#u@9p~aUR zY*~FJ*FExOFMhlFsm1DFN>@KT_j>2Ag-f0P?s?|!hTn=feD_}ccqciDJ|(_QS|r(J?SL%xuBG}E$t4?bs~*?;kO&#-e3U8~-Y zdihsvJ}-XGJ(vCD_uPBSxBP~y$A=%{>Y-TmP`c_Np6pdVisJsE`yKB;pjYWCNA)=C zy5F*TsGSGc$6DlfA8B^n_32B@E|nuYE2HbpZpF&4bj^?AsedY;{2)DwrB~_uTj$#IxVT)s z@7-MDd-V>eU-X%;?zH+|ci(^abseYAz$^cr^S@8L^sM{L??3*-*IK>iK6S43Z^fFo zm9BaAIZyh8wa1t5dXm|7(>Gsb{piY>->~uY)^^A2S4_RDN|%5CeDo%(?`eOn{?3}# z%JV$wm48%@c;}!0QELaq@`KVfzW?cA@3(WSYyU9k`tRTp^MmxtE|nuY6>A<;y2i09 zuRj~tPw(?LsPC0CH(0(uA6;ek&kp9y{*V6oS+aNb+CSWB@jpH6cdh)nPd&xTKmYvC z+x$megQqRBC+GFL+hgo~*TK(Y>;k!1j;VS`gJWml1s1n@wN2E@+c0)(>x#X4yoKG<>|fdF7a&eKJ(Lq z{_dx3Ue~qsYMsB1eBZu5wsCgWU;nZ716^yp>pH$a=05EDb%FT0`_8j<-&cpfZT{AE ztgnLng)2L(e=F8Jo&UxQZJz%6&2P8%{NVq*$Hv7wPJOzy=kPHNYtN@$@Oqo4FDPDX z^R#012c^4tx?%P``TIX+<5;o!vts#W=04BbTi3GZ(vu#uaV@##^EvF3fBMAF|H5AD zr&{l-9kgy$to5$u3B~G9N>@4JDONu8SuB2ht#z*CTE{BZx>flVOP|tJ5Ajql>C^bq zI$N>U&q~*NT0E_8h7_@|*JMeknbQ<7>%PZ}C-c<(EGdtA0vXdy1!V;mVKganH@l z*sJ&XePXRQ+r&Tr#P^z?f97`&+IV>UQ?E9A|L7;2{r~z+H_tro_x>`v552|ap+|&I zwf?+v=HJ+}OvP${rEA}@zx5WIN0d+YI6a={^m?AkQM$@iJIM~^)BF5G?0W1gE;PTo zSnEu8{n95q#r*o!`fJS2KfK^Zv-_?;d#BaoAAR@xA&O;>(xq2Cm7{zr*XfD%I{&o) z(7n&!C63#1vR&n8&9`y;yyMhoZL}Ardrt23<(8xQA&N^;Tp|9C>Q}#;kMg&oxJ~@H ze{=13+JSePAHMvm!1cF3d70Vyw(H%x@#pVdwf1}e?=M>Wz2(u*wD!C1zAsw)DVD#K zE`Nz#u$+zq;7xBR|KTY1 zt)2^)uFDUk74025#TsWCFMafW@l6+4c`o+6KmLmL-~Cx#i}#_I@3e93(w#lUKXP`L zqu3{|eevn0$Hkoa*tO@q=z}+)&*hts_$}heddAnq&$)frJ!gEx?3lcE=}uoa(zg`F zD^c7he(f`#Z1%XA_Y$J(+;6+{1sC^cU(dqex_LSsM2-c5KrqM<FLkL_UZj}AA8^P?yA+>#hw>mpZ3=;w|e~i!i|>y z%9&ei{(fuww{8Ab?AC*~SbK}7eyV($r=>@+{4}H-^&jtJe80%T$)@+qcimzBdCrr5 z#r$*AzZcCv?|Jv{nST_^KT4N>#8bVMPyTUw{y+BK1w5+a{2!lO4ADkd6?M@F2Stq( z^z8lY{cH#jH0TOJVnx{{*^p?+uDL)^3P(g6TePV~zfozsD%!NAU$Iif`{AO-7Hw48 zrfTh?R8vJ8Z#At{exG;FIeQ5U^6l^WKfmYyJm0hVWX{aI^UlmW@4WNQoRcj6zWSH* zxqP~xTgm0~=|{9L!TC?;U0gnAeR&_34}~NjN+e-~P(4&erS>=`r!W=9@p{a=Ya_^kzZ@P164vzFJldD%svr+NPsAJ=EZ^<2&%=W?cy z`u~hr!~IUmr*^E04st)|jg?pN@gsh;&Q|{Jdt8205BV8d2z!To8V9XDdasx2V~qGw zI@LqtKyU*hejkm|kY>b0ET zvG=^p`JdD#pd4du-<`$7(;w2-)2H9j*3;iNZ{+Qzkm}*s%&+J3--us7{%t-#jdZG~4)ipBO$Z;na1FP!6e5XHNcLg6 z^>S`MUY=m%`D@<)l+WkwkN=d<=aLg$+>U&Ihvt`3Nb`u&X0a$5a#4#gPprF5!?==k{`>V0^!_MW;H zGDacE!F8nXe)d#~HT+d(0yKHF_Uti9;VgVnAU6mK`c3th;&)c>6 z8%f@-KmYn%-Y$a=h14!er}~JF>Zfwl9^ykG@uhUCkLc)JZyVb4@`Tfo-(UGwA<2{M zt9Bl{wmr`G{}fXB>&KrTBtPOO$CvVU(R`_XO0y3Mgd>I8xf6x74!`)1Mq1amuX%qy z>f5(ncy&6Te`j6sH*SAoQ-6f^?%PiEG#*4pdP#It57ALbbd)~#)5*NwlWzJ2mmh`H zZ%U{B5FPc8%29iX4~4{+(y1PzqxVXC&|cDyeuQ`5HG%hA3(2pV!2O~3PkxryTYJCu zzpCDOL3@9zGNqlfes90__mC7)J%vE^)7pF8bqM!gDsa9(U)#d%#@5R>rsMQnJ3F8H zNp!@A zFSv`#aml?Cc)P3j-p%DmA+?9nsUD)EdZ`?>gZNNLd?}skG1{|DZ%;qMZ21s9#c7=0 zTVK!Xvwrb3uYcqu%?{iwX?B46RlQw*{{i7A^XPvGU5ayctsfK4q-RJs;W@$6T>c-| zpUU|(Hr~mfw^E$^mB-#Dd71GXLHi#)RG#`p{LpS5QoAXg`ayiDoy3dPxo`zaC#$7@>O;E z0fglD62Htj$eEmebiDTVR$d>Sj}pBRCw{{^KekirpGgk|gs_jiJqOOKN5&p|Wi_Wa;+3i0B&Y2+KBRCvO!TDh)Ncx@Jqq~H`}{o! zw^rBl^4fEJT5q-I_@mP)PW4gw0lhsbJsd_jVckEupMS;tU()}0sQl9N9sYdYJ+qSQ z1BLXS2&L2cKGD%W^NDL-<9bRV?Q|r(^T5l+w_REw``*NZuK2$I5mnkHBMCmji zjOXDLN56SKof8lp=_{p^-Vi_P7xBk@*sg`W+bJFML64g`Uz#6!xe(=pKBUvj)Iac3 zDFlCBj{FdV57kTZr+ub*m-ZfX6GDm)Bcy#S?N2B)#;NW(ZM~rMCHLOJK`z^fsIk$te9=L_erT7oO=V7$y1a3#& z_A4>haX$Ot4YW>FuKLvm9{%E)pYrsbRS)xZIGZ2ImH27v$?thc{3xCH5g+15{Um-A z5FN_i4{tzj4lX z{(gEX-mjwf+a|30EsqO`(|UE&2bYHmz^)5%dVg&B!#Rg7V85$K#AX$@81={>boi=F0zCtkGBCeF=K+WZcFda{4ghPv3qz-X+oMtH%2X zk34xg)^m-%6wm4DJ%;I%H*oq0;`H7@-EUsu<1vUhy$5hX>#Mv!49~Ye{4vhur29F2 z1>#+v%CvmKh}#vs*Qe(XBTmoF=e(@7XAsYQ>G|>tPi)}wHsd)ZJx@C8%OsBvA|5TW zRsKc(Des?x=ZI7OISJ$6$LkwGoSr-W=Jua+{iw$CFzXkSDt~;{Mqa*Gk6-rfA94CR zJa2mX_Q{nu-|~o-k2vvfnD#5qUqzgr12s1OocGU+=P~qL>tA2RIei%MV>+yrGk^MH z&aWHsc){e#`48O2>mNj%o)^7v%??gqf#(!I+h@Tuo`*UAA;g0VEtRgHJx}O@OVGsbly95?oW9Ar8u9Y z{7Y88RvU+?peHiE2j@5 z{>-GgmCsBX;Q0#TyU(ABzxnAO+B{qiEn863gUDw^x=-`ZOrN}t_m}OW_X78#z7;$!KS$&7%h1Mk=kWG4Ax{41 zwf<*#|9jzwke~Hj>TJ$0f^}X!-Bo$*`bT-Zw4d}z+n>S<(7!(jg5wu`zad>lsKpLX z$7wkavgOnt8Uq5|(|(2aas;}k{UXf)0^L&?y6B$rsSKqNJzr}O5--%Rw~OB&rp-r} zM|_QXD9o;h?x}tXwR$yLqpcKD8M^46Xo#Ldiihtk;cb(5T^__eZ?k@Hq(7ULZloO* zE%6@3H=7snF!)hAzekgJUko|Zdot8F3aPzxPoR5xmx%5uBzg+TA2;r)j}$lhP5E?B z@}N8lY24_ZLZUV9X>2J@>Et6*oI<+jo-V3~?g?~H^wdteh?edtqNEXyTk~Q_2WJ3KkzCVc0rRm+_(Q$I@$;YSn zj_4f~dR|NK2Al%WJCOACN)v$7fYbBD={-;S4&+II089qX1kM7c0A~Z|0OtY~Kx7o6 zh%W)^fd(Kp3W$!DYfk)Xz0V{x&!1cgt z;M+hKKy9YBQy-`==K)iJZvxYR>A?BG1%L=x04rbv?0^Gs0xm$x6L%xc19$=Y&L=+* z07&6vpd1JRmB0+33YZDZ0%il%z#QO0;3A*~m|aD$(YxLbG<;OEKesAl%;#E?))ZMKtCx+5C8&(I6}UZWQ{ z4c$Xm()4tnp_jAh$t4=j-&wJ#RnKZ94yn`aSWV2%b@$ev*Dq^mOk|)6+e8bNZKdFXHzv?G{k)B2Gj1 z27j#$Hcq3pttRK5;i7a3>AL%_Ip9;nWoz7H%+Z%QGD7HX4aQ@ROtjhe6mM*FqTWaJ zvee&4g6^%=pr0TkgiIgd_e5*lL;o>nD1H{|-3_}Jdxq{2(mdh!lyBTOHa^Jt6Aj%v zuJSxf_Xsh55Au7WH|`C3YJ)*f_XfSuccM4$sXSezPfyILc~*-V_V6x0rE6)7As_WV zs?$&^pTo4=Q2BIOvLTp<{)|nyi_;LDb}4C|nmawOTajV1L`#~>uX zM89N)zh|m`6Z;J%)zj0HQWQO-7~yET1n3NY0y!+Wh~IJij{lO0UoYsIz^w3mtpm!C@K3wg`4w{YG?qs5Zp zy!}T$wLg(e6?x(INd)WF?(13;FVsnS3Q*zKZ;aq9#ec zl%FeKMNVb%^VZM)VwBHczmUn#TfdBaRgfc!qC|4rC(DeX|HvOqCMpKeHj*zPbE&d| z{8Ta`sB$uI`;tcfVfv?L^7H5q`k%?q%b%t6`q^RnpUKbPf65PsBjK>XNdI!>pOhn% zFDI%Ka*FpoHy`~+zGO00R8)P$_#ZOqJhJQni7S*Ox|S+jA94Sk5{XxqU7@5REsMuZu=E^D2q-O4o_!#CsVJi9G*@B-AJ{ZkgG@1<3;0|+dfr}WYY;6KcdTR zpDK4}(H&-8L@8C?l1(Qcp5GwoA||107Yx)c+8E=?9apkbDVgmnF#UZ_*ZCFhNnCGf ztTLA=RDt}Ds#aB0&}2QrysFO79dVu}vgzo60#`o$=*^}(LcMAhouR+^_zh*#3B208 z^_u>Q@lPrcj?6}_D>B)23HeolX?rTF_wn+%@?xPnOZRctMcY|Y2`mVTz)U| zli_fZT1a-4pj~u^l$5t2KgFFEkfY@j zjdsa0l{dc&d#0z5Ju_??ZdE{*kY9nTX=rFjS1YbpS$Z#%p4Jf`We6Tb4{u|ZoRFWC z70SmQU4=S$ge6sKXA=2nXNuDD^+QEItVHB+`6=YXI}_*&!%0S2^&_Ur>^<(^@bbBG zCOIjxfcz9F>7x2Ga!^&umys`3{rp!?R7qLmY@G9%LXpFkCpjvzg8b6b5pdSVP#Xs- zPe9L*A5JF2l%Lx^O%GJgKPjllr?R8hAmQK1}=A5cCY?=*skucvJt9vVi8gIIG)~pXhc?Ippy(MS&y1X?9z|{KsVeY3&Wr(2C~KNk12HMwwKM5cW9KKxVoBZu=(1>{$>)ZYFE zxRoBlpM_-P3z2Y7{_^nukgx6Ew6=|IpMrc5eN3S>)c(x4BLaCPk)IMGN(!-2`pxrI z%9pV(JxqQI`I0F?JDAaWBlG@$klwHI`ZIb%;|2XkzP5kMFJBq?+Wskj|02kL%ts`k=qYh-a>qI`=N3! zT3bi+835f#w=9^tNAl>6Dvu!F*mqGKx%IG+`6Kf8DonI5%a<=9|4eo!o--_9FDl*2 zpV1idWpnump*qmf_O9hHd=%sx`?`GfB$1yGaP{Tyhl>1Ek13*Je&-wa6!Q01hjD^4 zoMr!X!NG2`zvJ)Y%?W+SrKOi3$dzYG7C@Jhv5^HIvSGRXROM>q8~ZjYpPQeOn~-np zhw}Ba8~Gn7bGSU~@#O3sMQcMYA0gBSI_x)arSi680Qu-|BwW2eZ-0l8uO>;L`Q)X@ zreWSs&i_#TQ)ChOA5~SYqJ4P2euRYQBzEzfoS6&7VL|1X?#EdFPdce5{M~lQ+K(`A{N3=o!wN z-=&rB$-iEp|H#L@#+=Kir`Z1>-((u;35%vY^8o#)@+NG357WL8TArpKneiP&zP9Vp^e0!pVE>Vyl#{$XmCe#GmGsB_8QMqVCmh+Il|V-%)K`IX z(|G012Stv6&RF=cm$ttUcE7WPV2bFfMk-}PS`)>D-7Mm+@dkj+L;-*F!Ht1 z+PG-rW~4AVf&4C@4v+vdFoHG>09$|_AOTbZ0>FS2#!98}0u&$u$bbMaAO&4kfh3>+ z5kLk6fB`AYbrnd`oChL+1ek#l*uz0!8_)}M0d;@`n1K5=$exMKN2ATjF5C8_G=!^$Q0tyfTWIzB$a1J&A^Z^P` z2Z(?P7{ZyM3iJXApc)W>k+)F>=mWZe2p|C_Uy+ffskg^7x&M3jj7af+11 zhL3iA1HsAqJ=sde#E|e$veyy))5_YFC`x8NQKemJP3Nb0Y4Vp(;df*|h>sj<0-vL4 zPbs{sBBel~;?y3E55=_hYyqG0R6xBps|{Lf_Nqihy`gg2gfQ$^I5cv^a+C2+*+l-n z8S$Xj{MV7{&2Dx6@`)psFGSrE6M3Ea%Wpw>mAwV|U#kqLgKEFJTivBT zuhv8U6IG^CQIh*uy3zJ$IKPrZ!zfq6JyymJ4j&w*Tq9nFd+nT_%SmM{5~}#Jz%&uH zL=`pbqEVhmMY(*bOs;(8P~F#*JC~I!`O5Viv0U!BQ2E?(kwg7QET20r`O23bI8uLe z$0c9+YLx#tm6;FP-L-05d5^?}_wmY=eEQgZ*m@_i=ka#kM0TyBat_)UjqbOK@?B#3 zN-(y2cM0gVanTFXIq<(n(XFfQ67_7N*Z5}WD?mRSNna_ZL?pAGO}`)Ds4cc7@OzHDi)Zhsuo}r^wfoTZA`A^Ofs8V!2AZpX-C%v@2hG z2aZ_&>&Mr`3XdSKuOHtq%D=~2lopjNKva!lG?(H{-+C5>Ev1i5*YN!Fxd-JBU@hKP0rDCaAod0uxt7(Z?!ntTVp!p5PdfOAKJ4!yKrjkgJ zs;&2#_GI`ZkCIRRer5O!9VH(o7bs&eOX3eYc%Zfj22;hLW&8_* zNn5)|tN0vzrWH&0h{eNP?~g2>F!-!VnI&_%xdfjg z`W)oHaYrfTW@$|-BVTPEYjOOSyihO7A4o6j+70IY?%g0Et<0TgEHnuE)#lu5HM^nF z2V+U+4H-Y2*AXf`CLe!UEXM*u{72JEdFi!9J|BG(=nsy-a*_QYt0jvv>=%CXm`OB= zqUME8P$nq6O^obWZod+t-lODW63WyuN)cy7d~(~L2&ImaPcc@<0+r?+XX0ID)FPKS(K-%F2DPB;2Pzl^Uj>ks=Ij z1D}5$92O%Y&I0jcjS1XGBYd2kH}!{3-LqzNK*J=3jHn==!c@jGqZn01o|BQ z&-hYdC?u~nFW)|$@0kBtdo{krDMmIfUwc{UeP-;1T$5`;YlEf%q3Gmj%%aJQRv6Lap@(jF0) zs?Ak7)CKwjtZO%2T|7&(v*g2SG;BL=LVcjayF7H^X)fhy=i3@Tl4nW<eXd=Vp@>l;!=( z*h6hxCGe413XElZ7Nu6JhdYrOeV#$(!yyIbjjiP|s6!ue6?t49D)JNE>&vi=tgn$k zfU5-1<%_$NO7cj7?m(3wno7%#NLN}0`_0ck==4MTP~5mD-lWH*Gy1q7jD$p#ld9IP zU33sUm5+U@u#ad)CYcFeWk_5Ajs60RH;29$fspj`)EC;ei5zK zE?K31nU60tm8SLA(C1Qxs7N<+^*9`oLBEYr>4hLO4H*6=+ga-?qsvC zWxFOQ>zUGR{NNrbvn?!oH2v)bKkodXf_(BFLcY|nq-1Ql)baMt8^3e0PfA2)ol{N? zA~Qg19WE7+@e?W?OY?(Yl$^dpgv(O5H!8)EFH4{wrxr2oGbvTX2w1_fhMQ$`L=+O@ z$SRGR_TjnqDiUg<`XV2t)~FVRc82t^C~MS@Qfh>Jea&{#_|mw9Lw%rsPkBb|lGB5T zp)_`eBC}x3G#$;qj~qmK8C?zV^MwJ{&p*4^E;a)@(n;_*3iz0jZPWE!Cb^i$rR9;c0CS|@JqCA}!PF8Hn>G15za4PS{sM2YCu0Bwi zaA+Ioi%o2-L_eohu+tjYga&45VB!w?iQs1^`}jSDs7VG|dnra&cW8*pqn>=H|C#zU zYHDA_35AC}U(e7R_9z^xBYJCk!}3)E3lrG|Lq|2vDY+YTBhTMhG-l$eL}~~94QPJ( zZUJ5T{Be2fyF^F)a>oJt9?;Rbf%Z8A=hIP~BW6ByVts}}rAN;b8V5PVPDDK{qJQ!~ z*Z7E+&RN{Y*988V3? zbVOEFWY9(SXY}}nK|i8-4>`Yc`BVQi{tD<1j-<>9IJ6SZ2g+fQOTZa^g;Jm@_|sA~ zp`D9p{m&iWL}&}jk4YJtKq1Z#Mdb4935ll`nhI`Y{6{JJj#4xWKWfP= zxuga^k+Ny{5zP3(DK-R3Kjs6gS95-JmXXVETSy^(3e$dy&=i>!MOcZze?(S>6MQo> zm-3%7CKi*cjPnX`(skbWo-_f08XUog57d;`tobC4+{+|)vSbSsg&a#8L-=FdO zjPgn-g7QCRA1gT7#iMo@n^ciHPMHY1nu7JiN3B;U%Dnk3*WOSX{3Db`&sLs+B)WYU{lzX)=efOcq`iS+N$ z&nJv_(7e^g!H`2D)P(X!S9|_(=tKFVJD1I0eu&CX9>IL3p8@)r+)Y1cl}64gj+}#^ z!pJoKBNasOBeK-6{(d6ah}`~c300g%^Em5#GcA>jzpkqVw_~~GBcU#oKQKugtB-7o zk1Jn?EQ+XNr19M6fHqCC=CL8q?$9=r@4|`0^ROO=`{>hx+r-@Z#n1@Vk4myHqrD}E z^p}OC)2Y35E_moq@T)wDdFQ3ke*6z+@Z)Em<&m;TnM$9a3hP6kNY%X<&Vk^O3dDN=z_ zUc|$=gu3SU!_+|`!c;9s+J^%QlO^? zn>amTSji%=dALtNt2BR*Y^>%VkS>NpriqXvKM%^h7ehW-Nrp~kI46-om(49xLw>$Z zpjRV83WfQl;)eVk-B(16`j?V>i4HM-={JRlXzgUGo*}EC!|@T?g|$a1z@DaEjix=0 z?P^q6fmKDj^7(~BC{O#8y;zCp3ZaAxPaU=Aj$i*=x?&Q}Z!xxI{6qgMq6EGft%Ep8 zP;O9E^`N>&Z*9K%n^1ltyB9eC7L4el`ATV7mgD z@K1qSq>NKmVMOm8$43&fBkA3s%uv>( z%jc`VkILtGuwC$iwCm7$AcuxPZ;b6;L*VJ~>&M$Xne5F zr_ED(maXY=9jDjYL;6d=rSjkKbh?pm%rlx_T0YG|6*Q4hAC=eV3srKAUeMs*kNnI! zmwRGM{4)C};u#4IfxZ+HeNp*9DQ6!jFXFc$ugpGyw{JV@2$|2M=kfe>s7$}eU&Wsw zXtp5NA7Y_u&=;42AQCa8O0qJQV$)iJ_Kc?Q0{x-=lU3A>`f=`$e4lU4>b)4O?dtYq zz2GuUG>;98V`nI4I$@OQ`6eiFnSk8&tS8iu@*-Z1X=7zkrakp55|x4pO2PM8m&*3Z zY)6D`7uj|bi<+730Gn9Gc@Qsszl0Fqxq23z6BV-{`>VQ3T^Csw!D5^mgSsc;&6^IK z1>m80#Gaa@5S4b3t;%}dCzCwG;6v{gX&;(#C!oF)*qYRuRHp1$u!5AOj{~0B4X%AOc80DKLoh**+j=IQ}0+y3vj%K%({lD$dY*fG{8c!+6Fp z04P8mPysL?g=Z~2KmrH@W?&f4qxyk9pa~EF2Bh#@ZX3`8L;wLu;aOx45CIsF#Isu& z7{asd9zX(y@SHyh)Bz@-AMZ0LKo}5!;bOEGPyh)SE<)Wv1TX^wg(we105dR9fN=$6 zV1%JfKo=kZBY1~y8=wHyKq)YY_XvA|I=~DJ;yubFkN{-B1PmR(d+0y{5P@O5le-1z z0%X7h4B|cHUZ4&z1F3%^4upZODOd2humK)xS-CXc zIyc@BV}lg$Y;V%DS#?%fd_ya8jT-R(W|3Fh7Hw^BL2DY}5u|CYi2YuxXKobrbm9NN zqK(U=Epub-O;+|WVsoR3*=@}YApNBl!(Aab%&(8O5I2VVdGQX;`gP)kR_V-Gn7Fk@ zm$by_zxHww&unXpx54AorKk(6Y6klZ`SW7YhRV*y#uz9rM7*jky26Mrq*gb_RwUwW z7@14LGcTT9W3!&$(9%Nxt#@fl=ln!dtS!dQq5DfaqYZ7%^_mRY+1XiX#B+YfN;K(I zO1(I?LMMjbg!qh=EzPYBXuvp%@z&}}!e-Yj&?}tCu8yySYK7zNGrM4a5t|1siMGdP zL=zpIXvLY7Hb2%;+XMw^inlbd$$E-Gv2f1CbLaBrf5a9ycEnrQZG}*YmUun>D{o>jo_+HiGed&lC&hGy`bJO8p7^J=w`S-=)A#t_9@c>`}O zSghZD#UMUta%W4dI@;RM5)0vf9v2|3wz>YA8S&0m^yX4l)!a_XLqd!;)HE+?i?*$t z0fDr$i)PNdcxHP1uP&I=z7WF}UvXJ;do!t9TR}}c+5qipkGF-`{sIhz7GcpsjdE67 zd|5b-9VgZ~9xIKL^r!iY^Q1Ya$}OBS#Y7lf8H zFIJCUIN6MrW*C*)`22bdYAa*=czryPlk`wO6VZB4Ap$EEk|kH8&UR?_jHYPo(irh=iIN_6z|6Hn#?y$${FUt; zv1M~(nDO=K@3U-XYv-~zW38Qx)#~lYB;8`PloPy+RxOJ!k7?A!ER;yZS{o=9V)qn4 zA)6alYO!Sn7d5xE)HW}Jwx2>ZYqxB-Aq8V1vv;_5=@Xw-a0z!V(P~&<0Q-4ab6ZDe zwB@4MO0>Cv@^L$#OeW4#W;8XoG-#5@s3d!>K+~4mxTZafJ&I9k2uDd_abm((3_bQy zM!UHdK2#8n#jeT7ZNdDR^9)Nl3(}zFOw$y`))vfP5lv_|wjF=M%PnHV5YxXs?m*oq`3eWc@&+H`ZZ{tzP5+wNBGzz0k~7sC2BIHS$(!WJcQTsyVt4 zo+?-j)otiZVCKW}VuZPSk@M@J4^H(`LZMWM6D;lj#;-(J4c~8?1AdFEkR>)C;Rc+# zy5S3720z?|Hzn@??nK&M$ips8!Nyu9OhEpBA*mPNy@$3h_je<| z4zH?$b^vi@HqvflEVT&hr4uyxhwZ~?Rk9jZ-3K0Xz!$tk)R_d$mM-MuAGyojDDxfM zPe-{cz;izG7J>$RO$Z}E&*h*2zaHc#u0jZY2|Mch0r&xtb!b1Jg5Lnb2>2y$Mw<{f ziMU5d=gdi@o9;qgs9%KbH-ToDfIbhK!IR3M4jF9}Rw6`vUS9aJycAfxU`C(@{HwCi|`|2aSixEP26t-u=KHsD9V z!@v&URbU_RFJP>@kWB*42P%R2Kt0e2tOITblE4;V2QUEq6*vH#=qY5A0SizC)Bu+Q zFi}OK0o?r%<%tEXZ=j&B$CYyzm@oIeA!-e>!hZ=m#!^QZ9hcG;$ zd2Bw`wgv1mwh-Una5=ua;R<|j!0abINW`@&meWmbp@kSZzpCbFOMANQx;K`NLv*pW+0kV&zWXC)T$q{s z_6~T;*xFvQJk|!6kF%WF1t-6~Io>+IGeO&?SOZVST3#Q!Fb*dWzIK|!tj-qf>9~hV z?2WpN<{9z%SYfea<|KN{LBfS+B&H>R4DL}i$J*MB%q)RbH#fwxn@jPmY;qLgjb*1` zpO9|voTaVU<-?Jh7fWE9&H0lSrf+l+rUgcshLfA=gr>N(b%5{G+yP;w8E7@nhXcZs z4v`q@UJ{SCHKdzlBrHgzlWL+XF>bn`YGTplF+-4?=Un)6HSxHnbR;+K6{brYDV-U` zm>Z`yW+>vF?HQTq(j2WkVff$8@Og8K!bQ%Ktj?~ zXxXER!57S`Fyorf!Ty9-r6px+35FZ0%s1wmQq98#JDSJ{L62wgg(b=;C`I_Tkn=~3 z^sKhI1Di%tY9!?96cW-3jr&}-S}dn@C*1vpSRAcrzRs8_v}erjL)IRW*BNhVZomPP z-U1%$T#^;5!jVsXv?JXR;KwajJ75C$%MZ2X-Y21@o zxZ*T&`gDtJy2UC^cRA>1#&k)X-rOFSB!_#th5CBrvX1E%d#0>=R9QYrb<^w->Z7f# z@eZLq)*;lBD<;Gng}CO-2vE6JoRHDkyg;Y3UBcN7#~J3Dn|74f&hCX3{2WkdZWrdw zt_)EdbL%n63-QhlsspT-YO~1jV?07z?AlHoZ^3+jO%pipOt~YsAwzfgHe`FE9-}X3 zHwaD9cA+(Hv_|VwE^PyEaFo0QO@Q!ag=ILE6_&(wiSlamm2HoA!X?ZUgIIJiqUyXn zbm1+-VOrbD^YMLrnlRIGk~>?&f2YHn^?0`)es5IV$S>5>3-qu^4{y@Lb$VEQm~xa9;5OisrlN?GRSP+ZsH= z+3i9_Gx^Za^7E*>d3pH*zR9bR7i~#2MJcSWr+`8h?d)38+1SpOv~tI|k1oS`cROpx;|Qu7>T0tl8gY`7e_WQq(H2_ZX$!C+V9@{t?`Wba zr73#5fUOS>WE-H%G_GWdP+}=|T>2Qs4GV?mJj-L5oI~ZGZ#<4_oU&@;8grPDB3{P0 zEJ-9-Q>=Mu6J(9YUme$>|0Ks1d|#}6za^eq)skFz&&j4`>Y;AZ1Ev)u5FA9Kv)F{R zQ`fPtK$(TJYZiy*RW4pePZ%_zW9;yNu(?4Xy9%2|nhr5Rs!%E#fa%eO_>$Q4rdZ4J z7`B+vJd27r-69$bLt?tanX{-IMR{x1qLi5Kbp21uOVce_$+Sf+G2JcYl&3j9tw00m z0$qsG^FJ;}3K!3rammF2Ww$5$iOgtjnzkR(7PJC$NqbOh93Hg8afa4F3y^2%1D?NVM+@zA zmX7SKyaYXiU(8Jaw9??0^?X2kXx+SAW2x77NPc5h{vnSTsHoAFY~9SGu2`ezb89h! z+=(b2uc0jIE^Ym>IMR&3vurZkQMezlUa;SID8OYgdM=NSPdE0(=%;Zn#1niK=I)Gf z@**r*DJ&!-#fP5rZj95+6Gj)~hN&)Xv|BN^&S%q?#^RV`I6lMw5Yx*UNk)CVU^+29 zD|ub01Pek3wUI)j$Pt^Udt?|$_y$YjFqe8^Jg|j@&?9il@VFd8)ao(PNgl@iQPqa; z2i7La|FAxcS93k&)6x)I(n)H_rnj%e37{SxW!^bjw&TD6 z&R1IuQpMwVp1uUnHMvCbuGSTWCI#)Q?kzC=(EL#)zOQ}9yg1fZq}4XT(d8DQnHEG? zZ)_9E1%woJeQN=ycEfWN+BJnF*3>p*@9GgcTd!%2ufQTnCsxy7$$9NWqn})4ohqe0 z(_FVyfD5XfLShxy_-CE*9aSN!FYC1AsLEuIn{nQz4V$(g72`cQ1?@5SA1c4m^I6;W zz-#gd*Tvf6LJL1|7M5eq&}%Ek+D7)F{p;5?d(OI|uWN@XYqd|erZ-CotZzAmD>}&z zG@OSfa9i&Ya7xfhrVC5;+3g;IrwcK9yM}x_qC2$AtY}BHMc`*=S>+B#7Yff27SQ_$ zS+v?}nE9P8``puwQ4C6oKF742a&yGYKro8s9gB$nc!!rfXWD$_RPCmTh+Z!|#a@{gc@PsIyIxkDW;}bAjmc*CB>(N}nwBDyr z`@V)&U;YjIr7x|9UzzPio_~n1Zj?1bzIM{&#nX1Qhg{THJ-rpuwi0F`5nVz@MR>%` zCDe%bWH3z+SseAnUTEkfyPS42xPyz{pVM7uxXeJ$PSKK+m4Xpg=QYlE$?TxY|RfgRxO$l-Ss z^k2tM*Fkh04>vO#tMu-RD$S{rw*ra(Utchkb|{T3-X^{yer%awy}{aNeaZTXwZLYw zon|}JHr3{|eaqHrTWjmF-EDi=w!`+a?G4+fwnF=OyI`Mg57_71WAU`cg z;&izdxuULXUEg;7-SvgbEKQa=rPb0c((Te+Qd0V<^lM3#`lVN;*QLKmL(<1miTf0H zxjW>Z@BWtiD)+VS8{OY^-{!v0{WJG}yB~2s>3-JT@80Wv-~FZg1kYs8`JTm|HJ+P1 zKl6;>QTs%%#ardA@z#15c^kYf-gfUw?{~bnd++i-<~``W(09G>r@pPeJ-!1zw|}Pp zV*lm-yZvwZhy8m3uLo8J?+I=WG6C>gzefRo4@J;bo_^0_rzuhnSH~N$QP5wUrX8#ud zR{u8tQ-0OI%ir(++<#JFQsBIREAV09lR$Y;4qhFM2Ui5Y9egafBZ!v|*cOcS38GWH zOuS0GR{XYjr?^qPUwl(M#&WhLWO>H&s-?(!sr4GGV!gxqx%GJ4`L>z1THF1$$8B%g zKC~6vC)(@mi|i45gS`o3ew}^2{SNz&?a$j^vhT6KVL!%klEdPtajbN#acp-y?|8>i z;5^M);S4#$&IK6r?>KM8m_O+Jh4WX=ZO&($7MJAmyTYz|SEsAnb&u#wd6 z*EggyBvG0nEs&a|>!n+v1;3J>llDmaF#h|cVd*nzL^^<%CyL#r?lQN@J>G4GMhNaH z?h5xbx9GOJCAZHlySGCVUWPN(YOj>qnq;hE=&c;cSbp7ox4JU{nrgRKAH z+2{GxQ{X+`TkaLSQ@j=4Xq-K_qs3T8}fY&je5ZU3yjq7{CoXh`bz`0 zz^uS!fvW=d2ObN&5O^c-_rP(%GlEltB1Y`q;7jx}2y4K2T_(mY>n%N&4VGTZMoZGN z$?_Y^pyfSFfpwhqTx;CA%DTb&xK*|8vwmQ`#CC(N+jgsMz&6f4&%V~4vhTAG+4tLr zF(2zN8zYVeN0Xz^@sMMO<3-1tj@8h?3fDB3=(1xh*1I0chdcwd%*n{Nc;lNWuEVOe&zWs zr2B8rDc%bp$Ef!@?+?A3z0Y~y@_ykp`Ofgo_SO4t;kec-uE^vu%rQOKokoRkoWkhIiZk8}n|L?G?TBnu#qDv=aL;wmgLR9zo82AmHSYV} zk3&m->;9wrJ@>Jmv7U(@3#|0@o?g$Rp65L8d%oeF>b=Oj#Cx~*N$>04FTE#Vex2j< z`{wzU_?G*=?fb6p4&Qyg&Az?9G5%BiH~1g)Z}-3C|JeU;|A_%}z!LBW<^}2k-+_ia z5O^H=@n+!DKv~Y{hk};`Bf+)7zTiW_?ZMv#Q$ZG?zw*Fy0CBQ-0sbApGVuoS`(jdj zNjw2#|0l~^mUk@w!1y|?mDUdHI_qYvlfSo)SjXDN!%F(?58I!zKj(PK@tWgLj=wnm z=_qoZ?40a$JA=;I&bhFES2*jP&CY9`E1YYbH^CDA(0PyZUgyu84>=!mKJ9$Y`CI2} z&ObT#I^T2t-TArm-_9|vGS_(5X|6L}6_}q+j8K)U#x>9NEmy?V+y(zs7%lZkdY6)!VM9l2-VM7D%W$rGF*B$N$-4D6zJPn>}J&Nbgp0_d^ET-_)ZWnp5gCOXw5u9 z^oUjBQ{ugrt(GS(&stuw{Mqs`R-NOlW3loqw63(?YQ5X~3+ofs9oAE9=feA#Yg=Sn zW?KjUgW*0h&1tQoT@GB=t$Zl%9}YkOm;t53s(U<~<85u)`bl&hgIoUg=#1KP~Cq z} z|C$^hX}5pCzsEo5f774Bnlj|y58v)H|5&UnQv*`qqQJictcS4<=<4}mNc@)ADL#mG zV2?NmFDWJN6Nj)K42z$^?>m5(Ig2f&mNJXUG9D{~!!pxysU>2GLDtt>?y%f%`Gw_S ztPihXZTN@9f|X#7^%Cg!z1F9!uUQLiUfT@FyA{^{0a*H1;Z=WOE480&pJYGBF52CY z{iXJ+;A7oqf7bpt`&ag2$9TsX@UJd%%*Q&u%JBoo{f>v>W&P3duHzHOB#c6>^GatN z8vg_5CU{uS!p9tOmcoWicG+C>Vb^cQ`hLIbW!E2Fe|GJ2{SzZ_7JRHGX}NThv{iaq z+9kaKYyMB^1ov6)3*AfIE8L2^*Zr{jF}Lb|1uObN_c73LyC>|q+Oyg7u;($))1IB4 z7d^l8{ND41XRqfy&u8$l55UVV_Lh3fye98>Z@2eB-zENK{+A);<00kC1AT$5@J%m( zg?JK{cX#kF&~27vY!zf~7Z-|G!tU-6e=GhO(*8vJr#Qwk)^eUjw0vNh0Ux{3dZTrZ z^>yo4R);NM3)>djVzw6Bb?|%c!>;5w`{|Hc9X!z!9H%*^Ic(U2R68znT~JdBjoj`0CG5j#um+8=1ovU>dlLJRW~oD3%Pr)P z^mpmsQnC9)_&pAH)SbY-qtE@Kd%DLBpYlR@m5V&}o@+dvo>iV6$mS1N$98&ugI&dm zzH;9+zO|VB&-hOF%l;~VwZFz6_SgFB{EPe%csfn~7JtIu;qQXaqxjePyZ!57A2#@V zb9{YMU_4g0a#-Fefr`MifEchtXMF)VP!*_#?Fa{IVLukZKWYdx<@JlQy`fiwuLr*% zo3e$mJ_P5AjqrS~6W5B5iSLS^i%HAREdLFgvE9;dImh}p^HSi4QT4y)+H|};Oolj!Nw;Ow( zea`*P0#}La8!i*pxU;an$*u+13ADI=2&;RtWR)tVuym!g1YT#K^cZ%3OvU*(+F6U$ zcY}4S^-XKBZ5nnbt8ANWyKVbzWp+FEChP2*u@^aj-Di!X1GZ|HW4~j()8}l!yx4@A zKXaC29c{r(cnWi%4C~?|X&wC9J=jx}yQ|zS?hWpz-22>R(DOx}b&4j+8_^^UFZ=8K)vU;|ctO+ODvQ`|N1!Zx~hx%a!r zdwjf~n>@Qb`#s~a-)Zo!hlPF9TZ|n|t#6fYqwgv7^nkA%daLzxkKWTofmMM`fnD&q zi{V$-1Y3gZgIj}d2JtN^DaKm3Urqg7g?{eBY%aD;!CKUToy=Cto9O2>_{FQN8?h2? z!j5^fbqhvy8?2*>e)nT#8o*2+#5kuQg(2&Hc*>u_-#UO7=!ztHoHx-`LL2z*{UJ4Ftno%-b2LJU~7VvNI;5R&=&>XM7M1{Jczrv_|$Y=iK=Q;_=*G;G-RnQg>&0I%;C+e__bb`#D(%<#ws`xJWx z#zlk%N_L-JwpYPJud#>iwORY+7JCBY)@5I1SD>Zc*gN-N6npI(?Sf;9qXO1Sbl4pd z##44w!D`jOgRgberFU&Djs!Hi3zlDTtix%-dPfiZpI+#A5*~h^W3yumv|tY) zckFfyIQBROp%*E~K6ps`9mDXEMldg#v)EbcEW=sEc&8cr0>L>2yYy*J5oZ$;=8EjB za#lNQuxqb%*1WI2yNRR7>`-ipz9hY(=h!VCC>T9X<{wcwcS{s z%i;I5K+~RrrX8@9!*(s=KKpLyQ5p24R-aLCVm!++UJV$Jt$apJf%IF_GinOt(1N~F z4?lB`$3A(HYaM#HYn1gkz^zAvdp-KN8}sVu?ME$a{w8ic%3;S_U^|||j4Hz}wHB6R zqi#70SOW8j>_&sQUfc?Aq}VdeQmfCVJ(kbVN3t60xn(?HEyo;afR1m59)HGr*aA)4 zgw;3Zi;QBx9oh@+NNFT=S8G!(S0D%C30)YYnr&0Ws zby8qZAP^u>AP`_sAP`_sAP^u>AP^uBAW&dXAP^uBAP`^>AP`^>AP^u>U=UysVDSES z?Ye2&n|FG>xw+0=NoI;xyU+jmT3eoV?m87cK;8LF6Y#*9KH}T>ae?j@$zq#qvC}o_ z2CVK&oLmbo?RG`?HRt}O>%!h1X~XZHbVqoMfb=*fKZYd8hzuE%B9rb#H>KN|!0=i3 z5)X0(TCVXSH#qEDIQfoT^8XX&^VVnBdjrEA_q^U)PNOI-d0|dwK5)?!Sf?Z#cu_zSn;XH=dAs-t~k2DVTkawx6L2ALx$G`w4k9 z?SJe~`k&B=%YIImRP?XG^-aI*-=Z9Mw0QTlAD`jYhab43ouBTT!hviKB`|m`^tDzc^o8|6N2yl)UDB0&nWzjuwvalt-Q-*NPw_VUW~S;5dr#o$ z1?`1UXv<+ssZbs)H*rc@CsR#RqV#FGZ^0}pC7!PN!bOW?(pCw=bWr4ilvwGpoG8Kh zg`81Aho|*zPGrok=j`kPt#WAO#_U24cP!9l=b2s!+*OE!DscOfLF9DBhZ%i!+R+^QPQY&1(i8}kcA>CWCJKxn&E%#NxoMk+@d+pJ1j-dh{!D*L8c^zJaH1+q3o^&E7o|{h57! zfVm#qOTKWXb+%{~w#fuL9kcVIW6>?x>-JCJz=oYSbPUI^_*;1Hq%)#v2s)>oapyg} ze%AT@=RSGn?#e%KJrhxi#oF^cotOyxNM~o^cgC=Dx$y5z{iItJQG;9x5;AWrkXRotN3hxyJMo72S@t(btMpV!?O;td^s&i=NpZ z!del`R5B?h4R*ks6w1{}jScXx*|R5{<6Z^HA;!B_I6A365%(Q4>E~WI8y2%+wOlen zikq9SUF-J>JHw$_YsWgpH5s@fPdQepuNq#*#lx)TLH{M!@pq#?q92OsF_O;3rYHLS zRjjez-|St418F)lZ0;E zz~v`6c^!=iaN8vu>B5gCXdl9iQ&@3`qm+tZ!8!@}p5ZkN{KQCUK}j=d;2=Hat|Yz< z9Atp@N^~3RY$nmI3jwxQdS@vAxLUJ;dz4vaHMyQjWR=vplV;8m8Jb$pcz z-%nV(j;9K7RC5sRlNL(UO@QT0&8qZ?2|ioHGmqinnr!KsuB32QghTqYtHSLpRM9{7d{z2z?Qj{J3xf`8^D9$=+M(pY1l4YmgQV0&N; zb_V9)1-B+IH#dah7g~n=$&F(9!?x@ZHEkSfhg*mG;rE@y75?=apZ+WNGOv$@M{i)* zV>sw73Hk)T|Bifl3g^D(^v+>Kd(^qYh3dU+QSl{OAF9^CqktNi;k3NNVOk<%v?EpL2`+~XG(f0aq=2&eTd^qSmgxIH6^DR+@ne@@mO_^ zRt}l887|fXq4mKSbQU6@shW~lLxsBzwGY%y0JtFBuCDJ91} zxoX9=Qb1F!b*$Q(jD)h>bC|55Blj^P)0TLcsx8+l*XT3tA)Y(MXBSL;g=#PRI_}w~ zv2aO{!9j>8PRWr4op41@vt+MLIt;;F`LIHW=B21!!BkaD(h^5(asq+|$EVo{X>n50 zX2FwH^ukM?&xGp)=i~F7AWT^%_Yisc|=qF zvKhZ13#x=VO^GRu*4WrJX?y0JrQDIlE1ec0q`T7Tc}<0>giK%I0^|u=WX>77A9QWb z#_zd2{fMWQr=szc4&HacGgWwdlYY=f!)vl~v|7jI3R4>T?a|1L(C`T??bAD@FkMFT zWWv+FN{|Vi%W6$FNm-!b9?hDGa;NBaw(rpaM4XO>m-Jxlk?PY@Fg3%&8)U)}E`ALA zCFHjn_LdB2DNMz1w}~&w=+rWt`;a+^g`itX*nPQrflm+7ml(dbap{76P2^r)H+k2T z^dK2?DVWEIdvQ~(IcE;!isfpD%6o)#IFhY(IvP2j9$cN$jAd=PTDeM_=F3I*g5MEY zw@uy=!QFLhrFNC-=f2H5Cdl>K$rQv^PrAtTOX9g-WxTI>XS#89F^HJan^F|Jka zt_~J_nzM{nY`JGKtAT1E>+f8vL60Ocl9EX(a);Rwpd@6L3lO}d84@5Qf^(*zLweUC z89jz?D%v4aHIgB-UNGlN6jCtXA+ue8c1>8^r%CplppZ2UtOa&fJyE%7V4ptq5LSxN zhf;c!hi1dX$LdU@i%*HcQn}Imv1%q|mtwqfn1-?HnP)2BI;t^BXb5MpmEkz5YyRTe z?RBH_&uQfTj5q$)**?7iopx@1i$=%gB$Bz8yw`|-=;AvU=$bB&(M8`-aUbzE&9P6l)EtW zvg6TW88l53R^iZAOx7ON0l_Q$N>?q>yHE{h0Pod!YKP<{{i%VPgy={i(Mk`)J3RSg zs@#>MrP5VL>**AD(+sXQVZ4~N&G&3(GF8r6praWMV7_nCV21GCylpdsCDZ4l_Z5sh zVwE**?3hMn(Ra|39M|vAz~-#ZVV^2AP_VKD4ynn!Bj%`<>w3YvITaU=(2<%fC|5O6 z_ZJ49d93a(G}e`z19rBSk*_T+<`BAdP)( ze`{ag-$pxkP|v@ + +// include log tokens + +#include + +// include simple void functions we ignore + +#include + +// include functions that need a bit of work, but we don't log + +#include + +// include functions we log + +#ifdef EGL_LOG_PTR + +extern unsigned int *EGL_LOG_PTR; + +inline void xGLL(int a) { *EGL_LOG_PTR=(unsigned int)a; EGL_LOG_PTR++; }; +inline void xGLL(unsigned int a) { *EGL_LOG_PTR=a; EGL_LOG_PTR++; }; +inline void xGLL(float a) { *(float *)EGL_LOG_PTR=a; EGL_LOG_PTR++; }; +inline void xGLL(double a) { *(float *)EGL_LOG_PTR=(float)a; EGL_LOG_PTR++; }; +inline void xGLL(const float *a) { for(int t=0;t!=16;t++) xGLL(a[t]); }; +inline void xGLL(const double *a) { for(int t=0;t!=16;t++) xGLL(a[t]); }; +#else + +inline void xGLL(int a) {}; +inline void xGLL(unsigned int a) {}; +inline void xGLL(float a) {}; +inline void xGLL(double a) {}; +inline void xGLL(const float *a) {}; +inline void xGLL(const double *a) {}; + +#endif + +// functions we might log + +#include + +#endif diff --git a/Glut/EmptyGL/GL/glu.h b/Glut/EmptyGL/GL/glu.h new file mode 100644 index 0000000..95a40b2 --- /dev/null +++ b/Glut/EmptyGL/GL/glu.h @@ -0,0 +1,23 @@ +#ifndef EMPTY_GLU +#define EMPTY_GLU + +inline void gluOrtho2D( int a,int b, int c ,int d ) { } ; +inline void gluLookAt( + GLfloat a,GLfloat b, GLfloat c, + GLfloat d,GLfloat e, GLfloat f, + GLfloat g,GLfloat h, GLfloat i ) { }; + +#define GLU_FILL 1 +#define GLU_SMOOTH 2 + +typedef int GLUquadric; +typedef GLUquadric GLUquadricObj; + +inline GLUquadric *gluNewQuadric() { return (GLUquadric *)1; }; +inline void gluQuadricDrawStyle( GLUquadric *o, int mode) {}; +inline void gluQuadricNormals( GLUquadric *o, int mode) {}; +inline void gluDeleteQuadric( GLUquadric *q) {}; +inline void gluDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops) {}; +inline void gluCylinder (GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks) {}; +inline int gluBuild2DMipmaps (GLenum target, GLint components, GLint width, GLint height, GLenum format, GLenum type, const void *data) { return 0;} +#endif diff --git a/Glut/EmptyGL/GL/glut.h b/Glut/EmptyGL/GL/glut.h new file mode 100644 index 0000000..9007ecd --- /dev/null +++ b/Glut/EmptyGL/GL/glut.h @@ -0,0 +1,60 @@ +#ifndef EMPTY_GLUT_H +#define EMPTY_GLUT_H + +#include +#include + + +#define GLUT_KEY_F1 0 +#define GLUT_KEY_F2 1 +#define GLUT_KEY_END 2 +#define GLUT_KEY_LEFT 3 +#define GLUT_KEY_RIGHT 4 +#define GLUT_KEY_UP 5 +#define GLUT_KEY_DOWN 6 +#define GLUT_KEY_PAGE_UP 7 +#define GLUT_KEY_PAGE_DOWN 8 +#define GLUT_KEY_HOME 9 +#define GLUT_KEY_F3 10 +#define GLUT_KEY_F4 11 +#define GLUT_KEY_F5 12 +#define GLUT_ACTIVE_SHIFT 13 + + +#define GLUT_DOUBLE 1 +#define GLUT_RGBA 2 +#define GLUT_DEPTH 4 +#define GLUT_STENCIL 8 +#define GLUT_WINDOW_WIDTH 16 +#define GLUT_WINDOW_HEIGHT 32 +#define GLUT_RGB 64 + + + + +inline void glutSwapBuffers() {} +inline void glutShowWindow() {} +inline void glutPostRedisplay() {} +inline void glutInit(int *argc, char **argv) {} +inline void glutInitDisplayMode( unsigned int ) {} +inline void glutInitWindowPosition(int x, int y) {} +inline void glutInitWindowSize(int x, int y) {} +inline int glutCreateWindow( const char *str) {return 0;} +inline void glutKeyboardFunc( void (*func)(unsigned char, int ,int ) ) {} +inline void glutSpecialFunc( void (*func)(int key, int x,int y) ) {} +inline void glutSpecialUpFunc( void (*func)(int key, int x,int y) ) {} +inline void glutReshapeFunc( void (*func)(int w,int h) ) {} +inline void glutDisplayFunc( void (*func)() ) {} +inline void glutIdleFunc( void (*func)() ) {} +inline void glutMotionFunc( void (*func)(int x,int y) ) {} +inline void glutMouseFunc( void (*func)(int button,int state,int x,int y) ) {} +inline void glutMainLoop() {} +inline void glutSetWindow(int bla) {} + +inline void glutSolidCube(GLfloat ) {} +inline void glutSolidSphere(GLfloat , int a , int b) {} +inline void glutSolidCone(GLfloat ,GLfloat , int a , int b) {} +inline int glutGetModifiers() { return 0;} +inline void gluPerspective(float a,float b,float c,float d) {} +inline float glutGet(int code) { return 0.f;} +#endif diff --git a/Glut/GL/glew.h b/Glut/GL/glew.h new file mode 100644 index 0000000..f70103d --- /dev/null +++ b/Glut/GL/glew.h @@ -0,0 +1,15507 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __glew_h__ +#define __glew_h__ +#define __GLEW_H__ + +#if defined(__gl_h_) || defined(__GL_H__) || defined(__X_GL_H) +#error gl.h included before glew.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error glext.h included before glew.h +#endif +#if defined(__gl_ATI_h_) +#error glATI.h included before glew.h +#endif + +#define __gl_h_ +#define __GL_H__ +#define __X_GL_H +#define __glext_h_ +#define __GLEXT_H_ +#define __gl_ATI_h_ + +#if defined(_WIN32) + +/* + * GLEW does not include to avoid name space pollution. + * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t + * defined properly. + */ +/* */ +#ifndef APIENTRY +#define GLEW_APIENTRY_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define APIENTRY __stdcall +# elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +#endif +#ifndef GLAPI +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define GLAPI extern +# endif +#endif +/* */ +#ifndef CALLBACK +#define GLEW_CALLBACK_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define CALLBACK __attribute__ ((__stdcall__)) +# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +#endif +/* and */ +#ifndef WINGDIAPI +#define GLEW_WINGDIAPI_DEFINED +#define WINGDIAPI __declspec(dllimport) +#endif +/* */ +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +#endif +/* */ +#if !defined(_W64) +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif +#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) && !defined(__MINGW64__) +# ifdef _WIN64 +typedef __int64 ptrdiff_t; +# else +typedef _W64 int ptrdiff_t; +# endif +# define _PTRDIFF_T_DEFINED +# define _PTRDIFF_T_ +#endif + +#ifndef GLAPI +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define GLAPI extern +# else +# define GLAPI WINGDIAPI +# endif +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY APIENTRY +#endif + +/* + * GLEW_STATIC is defined for static library. + * GLEW_BUILD is defined for building the DLL library. + */ + +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#else /* _UNIX */ + +/* + * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO + * C. On my system, this amounts to _3 lines_ of included code, all of + * them pretty much harmless. If you know of a way of detecting 32 vs + * 64 _targets_ at compile time you are free to replace this with + * something that's portable. For now, _this_ is the portable solution. + * (mem, 2004-01-04) + */ + +#include + +/* SGI MIPSPro doesn't like stdint.h in C++ mode */ + +#if defined(__sgi) && !defined(__GNUC__) +#include +#else +#include +#endif + +#define GLEW_APIENTRY_DEFINED +#define APIENTRY + +/* + * GLEW_STATIC is defined for static library. + */ + +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# if defined(__GNUC__) && __GNUC__>=4 +# define GLEWAPI extern __attribute__ ((visibility("default"))) +# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# define GLEWAPI extern __global +# else +# define GLEWAPI extern +# endif +#endif + +/* */ +#ifndef GLAPI +#define GLAPI extern +#endif +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#endif /* _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 + +typedef unsigned int GLenum; +typedef unsigned int GLbitfield; +typedef unsigned int GLuint; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLboolean; +typedef signed char GLbyte; +typedef short GLshort; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned long GLulong; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; +#if defined(_MSC_VER) && _MSC_VER < 1400 +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +#elif defined(_MSC_VER) || defined(__BORLANDC__) +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +#else +# if defined(__MINGW32__) || defined(__CYGWIN__) +#include +# endif +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif +typedef GLint64EXT GLint64; +typedef GLuint64EXT GLuint64; +typedef struct __GLsync *GLsync; + +typedef char GLchar; + +#define GL_ZERO 0 +#define GL_FALSE 0 +#define GL_LOGIC_OP 0x0BF1 +#define GL_NONE 0 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_NO_ERROR 0 +#define GL_POINTS 0x0000 +#define GL_CURRENT_BIT 0x00000001 +#define GL_TRUE 1 +#define GL_ONE 1 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_POINT_BIT 0x00000002 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_BIT 0x00000004 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON 0x0009 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_EXP2 0x0801 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_COLOR_INDEX 0x1900 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_S 0x2000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_R3_G3_B2 0x2A10 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_LIGHT0 0x4000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_HINT_BIT 0x00008000 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff + +GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); +GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); +GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void GLAPIENTRY glArrayElement (GLint i); +GLAPI void GLAPIENTRY glBegin (GLenum mode); +GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GLAPI void GLAPIENTRY glCallList (GLuint list); +GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists); +GLAPI void GLAPIENTRY glClear (GLbitfield mask); +GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); +GLAPI void GLAPIENTRY glClearIndex (GLfloat c); +GLAPI void GLAPIENTRY glClearStencil (GLint s); +GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); +GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); +GLAPI void GLAPIENTRY glColor3iv (const GLint *v); +GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); +GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glColor4iv (const GLint *v); +GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); +GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glCullFace (GLenum mode); +GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); +GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void GLAPIENTRY glDepthFunc (GLenum func); +GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); +GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); +GLAPI void GLAPIENTRY glDisable (GLenum cap); +GLAPI void GLAPIENTRY glDisableClientState (GLenum array); +GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); +GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); +GLAPI void GLAPIENTRY glEnable (GLenum cap); +GLAPI void GLAPIENTRY glEnableClientState (GLenum array); +GLAPI void GLAPIENTRY glEnd (void); +GLAPI void GLAPIENTRY glEndList (void); +GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); +GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); +GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); +GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); +GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); +GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); +GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); +GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); +GLAPI void GLAPIENTRY glFinish (void); +GLAPI void GLAPIENTRY glFlush (void); +GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glFrontFace (GLenum mode); +GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); +GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); +GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); +GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); +GLAPI GLenum GLAPIENTRY glGetError (void); +GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); +GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); +GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); +GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); +GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); +GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); +GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, GLvoid* *params); +GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); +GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); +GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); +GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); +GLAPI void GLAPIENTRY glIndexMask (GLuint mask); +GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glIndexd (GLdouble c); +GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); +GLAPI void GLAPIENTRY glIndexf (GLfloat c); +GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); +GLAPI void GLAPIENTRY glIndexi (GLint c); +GLAPI void GLAPIENTRY glIndexiv (const GLint *c); +GLAPI void GLAPIENTRY glIndexs (GLshort c); +GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); +GLAPI void GLAPIENTRY glIndexub (GLubyte c); +GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); +GLAPI void GLAPIENTRY glInitNames (void); +GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); +GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); +GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); +GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); +GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); +GLAPI void GLAPIENTRY glLineWidth (GLfloat width); +GLAPI void GLAPIENTRY glListBase (GLuint base); +GLAPI void GLAPIENTRY glLoadIdentity (void); +GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glLoadName (GLuint name); +GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); +GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); +GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); +GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); +GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); +GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); +GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); +GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); +GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); +GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void GLAPIENTRY glPassThrough (GLfloat token); +GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); +GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); +GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); +GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); +GLAPI void GLAPIENTRY glPointSize (GLfloat size); +GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); +GLAPI void GLAPIENTRY glPopAttrib (void); +GLAPI void GLAPIENTRY glPopClientAttrib (void); +GLAPI void GLAPIENTRY glPopMatrix (void); +GLAPI void GLAPIENTRY glPopName (void); +GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); +GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushMatrix (void); +GLAPI void GLAPIENTRY glPushName (GLuint name); +GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); +GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); +GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); +GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); +GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); +GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); +GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); +GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); +GLAPI void GLAPIENTRY glShadeModel (GLenum mode); +GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GLAPI void GLAPIENTRY glStencilMask (GLuint mask); +GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); +GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); +GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord1i (GLint s); +GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); +GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); +GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); +GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); +GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) + +#endif /* GL_VERSION_1_1 */ + +/* ---------------------------------- GLU ---------------------------------- */ + +#ifndef GLEW_NO_GLU +/* this is where we can safely include GLU */ +# if defined(__APPLE__) && defined(__MACH__) +# include +# else +# include +# endif +#endif + +/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 + +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + +#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) +#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) +#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) +#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) + +#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) + +#endif /* GL_VERSION_1_2 */ + +/* ---------------------------- GL_VERSION_1_2_1 --------------------------- */ + +#ifndef GL_VERSION_1_2_1 +#define GL_VERSION_1_2_1 1 + +#define GLEW_VERSION_1_2_1 GLEW_GET_VAR(__GLEW_VERSION_1_2_1) + +#endif /* GL_VERSION_1_2_1 */ + +/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 + +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_SUBTRACT 0x84E7 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_MULTISAMPLE_BIT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLvoid *img); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + +#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) +#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) +#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) +#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) +#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) +#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) +#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) +#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) +#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) +#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) +#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) +#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) +#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) +#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) +#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) +#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) +#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) +#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) +#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) +#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) +#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) +#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) +#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) +#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) +#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) +#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) +#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) +#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) +#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) +#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) +#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) +#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) +#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) +#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) +#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) +#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) +#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) +#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) +#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) +#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) +#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) +#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) +#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) +#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) +#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) +#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) + +#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) + +#endif /* GL_VERSION_1_3 */ + +/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 + +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); + +#define glBlendColor GLEW_GET_FUN(__glewBlendColor) +#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) +#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) +#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) +#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) +#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) +#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) +#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) +#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) +#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) +#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) +#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) +#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri) +#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv) +#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) +#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) +#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) +#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) +#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) +#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) +#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) +#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) +#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) +#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) +#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) +#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) +#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) +#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) +#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) +#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) +#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) +#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) +#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) +#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) +#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) +#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) +#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) +#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) +#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) +#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) +#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) +#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) +#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) +#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) +#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) +#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) +#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) + +#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) + +#endif /* GL_VERSION_1_4 */ + +/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 + +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 + +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); +typedef GLvoid* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); + +#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) +#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) +#define glBufferData GLEW_GET_FUN(__glewBufferData) +#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) +#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) +#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) +#define glEndQuery GLEW_GET_FUN(__glewEndQuery) +#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) +#define glGenQueries GLEW_GET_FUN(__glewGenQueries) +#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) +#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) +#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) +#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) +#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) +#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) +#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) +#define glIsQuery GLEW_GET_FUN(__glewIsQuery) +#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) +#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) + +#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) + +#endif /* GL_VERSION_1_5 */ + +/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 + +typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source); +typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid**); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths); +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); + +#define glAttachShader GLEW_GET_FUN(__glewAttachShader) +#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) +#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) +#define glCompileShader GLEW_GET_FUN(__glewCompileShader) +#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) +#define glCreateShader GLEW_GET_FUN(__glewCreateShader) +#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) +#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) +#define glDetachShader GLEW_GET_FUN(__glewDetachShader) +#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) +#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) +#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) +#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) +#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) +#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) +#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) +#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) +#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) +#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) +#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) +#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) +#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) +#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) +#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) +#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) +#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) +#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) +#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) +#define glIsProgram GLEW_GET_FUN(__glewIsProgram) +#define glIsShader GLEW_GET_FUN(__glewIsShader) +#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) +#define glShaderSource GLEW_GET_FUN(__glewShaderSource) +#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) +#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) +#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) +#define glUniform1f GLEW_GET_FUN(__glewUniform1f) +#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) +#define glUniform1i GLEW_GET_FUN(__glewUniform1i) +#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) +#define glUniform2f GLEW_GET_FUN(__glewUniform2f) +#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) +#define glUniform2i GLEW_GET_FUN(__glewUniform2i) +#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) +#define glUniform3f GLEW_GET_FUN(__glewUniform3f) +#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) +#define glUniform3i GLEW_GET_FUN(__glewUniform3i) +#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) +#define glUniform4f GLEW_GET_FUN(__glewUniform4f) +#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) +#define glUniform4i GLEW_GET_FUN(__glewUniform4i) +#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) +#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) +#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) +#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) +#define glUseProgram GLEW_GET_FUN(__glewUseProgram) +#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) +#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) +#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) +#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) +#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) +#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) +#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) +#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) +#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) +#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) +#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) +#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) +#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) +#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) +#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) +#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) +#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) +#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) +#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) +#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) +#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) +#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) +#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) +#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) +#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) +#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) +#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) +#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) +#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) +#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) +#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) +#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) +#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) +#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) +#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) +#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) +#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) +#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) + +#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) + +#endif /* GL_VERSION_2_0 */ + +/* ----------------------------- GL_VERSION_2_1 ---------------------------- */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 + +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + +#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv) +#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv) +#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv) +#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv) +#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv) +#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv) + +#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1) + +#endif /* GL_VERSION_2_1 */ + +/* ----------------------------- GL_VERSION_3_0 ---------------------------- */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 + +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint, GLenum); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum); +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint, GLuint, const GLchar*); +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum, GLint, GLfloat, GLint); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum, GLint, const GLfloat*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum, GLint, const GLint*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum, GLint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum, GLuint, GLboolean*); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint, const GLchar*); +typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum, GLenum, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint, GLint, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint, GLenum, GLuint*); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum, GLenum, const GLint*); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum, GLenum, const GLuint*); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLchar **, GLenum); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint, const GLbyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint, GLint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint, const GLshort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint, const GLubyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint, const GLushort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint, GLint, GLenum, GLsizei, const GLvoid*); + +#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) +#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) +#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation) +#define glClampColor GLEW_GET_FUN(__glewClampColor) +#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi) +#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv) +#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv) +#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv) +#define glColorMaski GLEW_GET_FUN(__glewColorMaski) +#define glDisablei GLEW_GET_FUN(__glewDisablei) +#define glEnablei GLEW_GET_FUN(__glewEnablei) +#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender) +#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback) +#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v) +#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation) +#define glGetStringi GLEW_GET_FUN(__glewGetStringi) +#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv) +#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv) +#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying) +#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv) +#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv) +#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv) +#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi) +#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv) +#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv) +#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings) +#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui) +#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv) +#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui) +#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv) +#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui) +#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv) +#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui) +#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv) +#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i) +#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv) +#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui) +#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv) +#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i) +#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv) +#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui) +#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv) +#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i) +#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv) +#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui) +#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv) +#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv) +#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i) +#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv) +#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv) +#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv) +#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui) +#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv) +#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv) +#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer) + +#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0) + +#endif /* GL_VERSION_3_0 */ + +/* ----------------------------- GL_VERSION_3_1 ---------------------------- */ + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 + +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum, GLint, GLsizei, GLsizei); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum, GLsizei, GLenum, const GLvoid*, GLsizei); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum, GLenum, GLuint); + +#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced) +#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced) +#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex) +#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer) + +#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1) + +#endif /* GL_VERSION_3_1 */ + +/* ----------------------------- GL_VERSION_3_2 ---------------------------- */ + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 + +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum, GLenum, GLuint, GLint); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum, GLenum, GLint64 *); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum, GLuint, GLint64 *); + +#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture) +#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v) +#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v) + +#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2) + +#endif /* GL_VERSION_3_2 */ + +/* ----------------------------- GL_VERSION_3_3 ---------------------------- */ + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_RGB10_A2UI 0x906F + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisor GLEW_GET_FUN(__glewVertexAttribDivisor) + +#define GLEW_VERSION_3_3 GLEW_GET_VAR(__GLEW_VERSION_3_3) + +#endif /* GL_VERSION_3_3 */ + +/* ----------------------------- GL_VERSION_4_0 ---------------------------- */ + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 + +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value); + +#define glBlendEquationSeparatei GLEW_GET_FUN(__glewBlendEquationSeparatei) +#define glBlendEquationi GLEW_GET_FUN(__glewBlendEquationi) +#define glBlendFuncSeparatei GLEW_GET_FUN(__glewBlendFuncSeparatei) +#define glBlendFunci GLEW_GET_FUN(__glewBlendFunci) +#define glMinSampleShading GLEW_GET_FUN(__glewMinSampleShading) + +#define GLEW_VERSION_4_0 GLEW_GET_VAR(__GLEW_VERSION_4_0) + +#endif /* GL_VERSION_4_0 */ + +/* ----------------------------- GL_VERSION_4_1 ---------------------------- */ + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 + +#define GLEW_VERSION_4_1 GLEW_GET_VAR(__GLEW_VERSION_4_1) + +#endif /* GL_VERSION_4_1 */ + +/* -------------------------- GL_3DFX_multisample -------------------------- */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 + +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 + +#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) + +#endif /* GL_3DFX_multisample */ + +/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 + +typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); + +#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) + +#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) + +#endif /* GL_3DFX_tbuffer */ + +/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 + +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 + +#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +/* ----------------------- GL_AMD_blend_minmax_factor ---------------------- */ + +#ifndef GL_AMD_blend_minmax_factor +#define GL_AMD_blend_minmax_factor 1 + +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D + +#define GLEW_AMD_blend_minmax_factor GLEW_GET_VAR(__GLEW_AMD_blend_minmax_factor) + +#endif /* GL_AMD_blend_minmax_factor */ + +/* ----------------------- GL_AMD_conservative_depth ----------------------- */ + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth 1 + +#define GLEW_AMD_conservative_depth GLEW_GET_VAR(__GLEW_AMD_conservative_depth) + +#endif /* GL_AMD_conservative_depth */ + +/* -------------------------- GL_AMD_debug_output -------------------------- */ + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 + +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 + +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void* userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const char* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, char* message); + +#define glDebugMessageCallbackAMD GLEW_GET_FUN(__glewDebugMessageCallbackAMD) +#define glDebugMessageEnableAMD GLEW_GET_FUN(__glewDebugMessageEnableAMD) +#define glDebugMessageInsertAMD GLEW_GET_FUN(__glewDebugMessageInsertAMD) +#define glGetDebugMessageLogAMD GLEW_GET_FUN(__glewGetDebugMessageLogAMD) + +#define GLEW_AMD_debug_output GLEW_GET_VAR(__GLEW_AMD_debug_output) + +#endif /* GL_AMD_debug_output */ + +/* ---------------------- GL_AMD_depth_clamp_separate ---------------------- */ + +#ifndef GL_AMD_depth_clamp_separate +#define GL_AMD_depth_clamp_separate 1 + +#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E +#define GL_DEPTH_CLAMP_FAR_AMD 0x901F + +#define GLEW_AMD_depth_clamp_separate GLEW_GET_VAR(__GLEW_AMD_depth_clamp_separate) + +#endif /* GL_AMD_depth_clamp_separate */ + +/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */ + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + +#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD) +#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD) +#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD) +#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD) + +#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend) + +#endif /* GL_AMD_draw_buffers_blend */ + +/* ------------------------- GL_AMD_name_gen_delete ------------------------ */ + +#ifndef GL_AMD_name_gen_delete +#define GL_AMD_name_gen_delete 1 + +#define GL_DATA_BUFFER_AMD 0x9151 +#define GL_PERFORMANCE_MONITOR_AMD 0x9152 +#define GL_QUERY_OBJECT_AMD 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 +#define GL_SAMPLER_OBJECT_AMD 0x9155 + +typedef void (GLAPIENTRY * PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint* names); +typedef void (GLAPIENTRY * PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint* names); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); + +#define glDeleteNamesAMD GLEW_GET_FUN(__glewDeleteNamesAMD) +#define glGenNamesAMD GLEW_GET_FUN(__glewGenNamesAMD) +#define glIsNameAMD GLEW_GET_FUN(__glewIsNameAMD) + +#define GLEW_AMD_name_gen_delete GLEW_GET_VAR(__GLEW_AMD_name_gen_delete) + +#endif /* GL_AMD_name_gen_delete */ + +/* ----------------------- GL_AMD_performance_monitor ---------------------- */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 + +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 + +typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void* data); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char *counterString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, char *groupString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList); + +#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD) +#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD) +#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD) +#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD) +#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD) +#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD) +#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD) +#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD) +#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD) +#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD) +#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD) + +#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor) + +#endif /* GL_AMD_performance_monitor */ + +/* ------------------------ GL_AMD_sample_positions ------------------------ */ + +#ifndef GL_AMD_sample_positions +#define GL_AMD_sample_positions 1 + +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F + +typedef void (GLAPIENTRY * PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat* val); + +#define glSetMultisamplefvAMD GLEW_GET_FUN(__glewSetMultisamplefvAMD) + +#define GLEW_AMD_sample_positions GLEW_GET_VAR(__GLEW_AMD_sample_positions) + +#endif /* GL_AMD_sample_positions */ + +/* ------------------ GL_AMD_seamless_cubemap_per_texture ------------------ */ + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS_ARB 0x884F + +#define GLEW_AMD_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_AMD_seamless_cubemap_per_texture) + +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +/* ---------------------- GL_AMD_shader_stencil_export --------------------- */ + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export 1 + +#define GLEW_AMD_shader_stencil_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_export) + +#endif /* GL_AMD_shader_stencil_export */ + +/* ------------------------ GL_AMD_texture_texture4 ------------------------ */ + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 1 + +#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4) + +#endif /* GL_AMD_texture_texture4 */ + +/* --------------- GL_AMD_transform_feedback3_lines_triangles -------------- */ + +#ifndef GL_AMD_transform_feedback3_lines_triangles +#define GL_AMD_transform_feedback3_lines_triangles 1 + +#define GLEW_AMD_transform_feedback3_lines_triangles GLEW_GET_VAR(__GLEW_AMD_transform_feedback3_lines_triangles) + +#endif /* GL_AMD_transform_feedback3_lines_triangles */ + +/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */ + +#ifndef GL_AMD_vertex_shader_tessellator +#define GL_AMD_vertex_shader_tessellator 1 + +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 + +typedef void (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); + +#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD) +#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD) + +#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator) + +#endif /* GL_AMD_vertex_shader_tessellator */ + +/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */ + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 + +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 + +#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil) + +#endif /* GL_APPLE_aux_depth_stencil */ + +/* ------------------------ GL_APPLE_client_storage ------------------------ */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 + +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + +#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) + +#endif /* GL_APPLE_client_storage */ + +/* ------------------------- GL_APPLE_element_array ------------------------ */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 + +#define GL_ELEMENT_ARRAY_APPLE 0x8A0C +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); + +#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) +#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) +#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) +#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) +#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) + +#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) + +#endif /* GL_APPLE_element_array */ + +/* ----------------------------- GL_APPLE_fence ---------------------------- */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 + +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + +#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) +#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) +#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) +#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) +#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) +#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) +#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) +#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) + +#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) + +#endif /* GL_APPLE_fence */ + +/* ------------------------- GL_APPLE_float_pixels ------------------------- */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 + +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F + +#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) + +#endif /* GL_APPLE_float_pixels */ + +/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 + +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 + +typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); + +#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE) +#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE) + +#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range) + +#endif /* GL_APPLE_flush_buffer_range */ + +/* ----------------------- GL_APPLE_object_purgeable ----------------------- */ + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable 1 + +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D + +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); + +#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE) +#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE) +#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE) + +#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable) + +#endif /* GL_APPLE_object_purgeable */ + +/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ + +#ifndef GL_APPLE_pixel_buffer +#define GL_APPLE_pixel_buffer 1 + +#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + +#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) + +#endif /* GL_APPLE_pixel_buffer */ + +/* ---------------------------- GL_APPLE_rgb_422 --------------------------- */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 + +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_422_APPLE 0x8A1F + +#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422) + +#endif /* GL_APPLE_rgb_422 */ + +/* --------------------------- GL_APPLE_row_bytes -------------------------- */ + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes 1 + +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 + +#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes) + +#endif /* GL_APPLE_row_bytes */ + +/* ------------------------ GL_APPLE_specular_vector ----------------------- */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 + +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + +#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) + +#endif /* GL_APPLE_specular_vector */ + +/* ------------------------- GL_APPLE_texture_range ------------------------ */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 + +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid **params); +typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer); + +#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) +#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) + +#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) + +#endif /* GL_APPLE_texture_range */ + +/* ------------------------ GL_APPLE_transform_hint ------------------------ */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 + +#define GL_TRANSFORM_HINT_APPLE 0x85B1 + +#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) + +#endif /* GL_APPLE_transform_hint */ + +/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + +#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) +#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) +#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) +#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) + +#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) + +#endif /* GL_APPLE_vertex_array_object */ + +/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) +#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) + +#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) + +#endif /* GL_APPLE_vertex_array_range */ + +/* ------------------- GL_APPLE_vertex_program_evaluators ------------------ */ + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators 1 + +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 + +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); + +#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE) +#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE) +#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE) +#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE) +#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE) +#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE) +#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE) + +#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators) + +#endif /* GL_APPLE_vertex_program_evaluators */ + +/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 + +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB + +#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) + +#endif /* GL_APPLE_ycbcr_422 */ + +/* ------------------------ GL_ARB_ES2_compatibility ----------------------- */ + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 + +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); +typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision); +typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const GLvoid*binary, GLsizei length); + +#define glClearDepthf GLEW_GET_FUN(__glewClearDepthf) +#define glDepthRangef GLEW_GET_FUN(__glewDepthRangef) +#define glGetShaderPrecisionFormat GLEW_GET_FUN(__glewGetShaderPrecisionFormat) +#define glReleaseShaderCompiler GLEW_GET_FUN(__glewReleaseShaderCompiler) +#define glShaderBinary GLEW_GET_FUN(__glewShaderBinary) + +#define GLEW_ARB_ES2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES2_compatibility) + +#endif /* GL_ARB_ES2_compatibility */ + +/* ----------------------- GL_ARB_blend_func_extended ---------------------- */ + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 + +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const char * name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const char * name); + +#define glBindFragDataLocationIndexed GLEW_GET_FUN(__glewBindFragDataLocationIndexed) +#define glGetFragDataIndex GLEW_GET_FUN(__glewGetFragDataIndex) + +#define GLEW_ARB_blend_func_extended GLEW_GET_VAR(__GLEW_ARB_blend_func_extended) + +#endif /* GL_ARB_blend_func_extended */ + +/* ---------------------------- GL_ARB_cl_event ---------------------------- */ + +#ifndef GL_ARB_cl_event +#define GL_ARB_cl_event 1 + +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 + +typedef struct _cl_context *cl_context; +typedef struct _cl_event *cl_event; + +typedef GLsync (GLAPIENTRY * PFNGLCREATESYNCFROMCLEVENTARBPROC) (cl_context context, cl_event event, GLbitfield flags); + +#define glCreateSyncFromCLeventARB GLEW_GET_FUN(__glewCreateSyncFromCLeventARB) + +#define GLEW_ARB_cl_event GLEW_GET_VAR(__GLEW_ARB_cl_event) + +#endif /* GL_ARB_cl_event */ + +/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 + +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D + +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); + +#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) + +#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) + +#endif /* GL_ARB_color_buffer_float */ + +/* -------------------------- GL_ARB_compatibility ------------------------- */ + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility 1 + +#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility) + +#endif /* GL_ARB_compatibility */ + +/* --------------------------- GL_ARB_copy_buffer -------------------------- */ + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 + +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 + +typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); + +#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData) + +#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer) + +#endif /* GL_ARB_copy_buffer */ + +/* -------------------------- GL_ARB_debug_output -------------------------- */ + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 + +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 + +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, void* userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, char* messageLog); + +#define glDebugMessageCallbackARB GLEW_GET_FUN(__glewDebugMessageCallbackARB) +#define glDebugMessageControlARB GLEW_GET_FUN(__glewDebugMessageControlARB) +#define glDebugMessageInsertARB GLEW_GET_FUN(__glewDebugMessageInsertARB) +#define glGetDebugMessageLogARB GLEW_GET_FUN(__glewGetDebugMessageLogARB) + +#define GLEW_ARB_debug_output GLEW_GET_VAR(__GLEW_ARB_debug_output) + +#endif /* GL_ARB_debug_output */ + +/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD + +#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float) + +#endif /* GL_ARB_depth_buffer_float */ + +/* --------------------------- GL_ARB_depth_clamp -------------------------- */ + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 + +#define GL_DEPTH_CLAMP 0x864F + +#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp) + +#endif /* GL_ARB_depth_clamp */ + +/* -------------------------- GL_ARB_depth_texture ------------------------- */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B + +#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) + +#endif /* GL_ARB_depth_texture */ + +/* -------------------------- GL_ARB_draw_buffers -------------------------- */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) + +#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) + +#endif /* GL_ARB_draw_buffers */ + +/* ----------------------- GL_ARB_draw_buffers_blend ----------------------- */ + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); + +#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB) +#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB) +#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB) +#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB) + +#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend) + +#endif /* GL_ARB_draw_buffers_blend */ + +/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */ + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, void* indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, void* indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei* count, GLenum type, GLvoid**indices, GLsizei primcount, GLint *basevertex); + +#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex) +#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex) +#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex) +#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex) + +#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex) + +#endif /* GL_ARB_draw_elements_base_vertex */ + +/* -------------------------- GL_ARB_draw_indirect ------------------------- */ + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 + +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void* indirect); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void* indirect); + +#define glDrawArraysIndirect GLEW_GET_FUN(__glewDrawArraysIndirect) +#define glDrawElementsIndirect GLEW_GET_FUN(__glewDrawElementsIndirect) + +#define GLEW_ARB_draw_indirect GLEW_GET_VAR(__GLEW_ARB_draw_indirect) + +#endif /* GL_ARB_draw_indirect */ + +/* ------------------------- GL_ARB_draw_instanced ------------------------- */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 + +#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) + +#endif /* GL_ARB_draw_instanced */ + +/* -------------------- GL_ARB_explicit_attrib_location -------------------- */ + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 + +#define GLEW_ARB_explicit_attrib_location GLEW_GET_VAR(__GLEW_ARB_explicit_attrib_location) + +#endif /* GL_ARB_explicit_attrib_location */ + +/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */ + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 + +#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions) + +#endif /* GL_ARB_fragment_coord_conventions */ + +/* ------------------------ GL_ARB_fragment_program ------------------------ */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 + +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 + +#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) + +#endif /* GL_ARB_fragment_program */ + +/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 + +#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) + +#endif /* GL_ARB_fragment_program_shadow */ + +/* ------------------------- GL_ARB_fragment_shader ------------------------ */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 + +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B + +#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) + +#endif /* GL_ARB_fragment_shader */ + +/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_SRGB 0x8C40 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer) +#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer) +#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer) +#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus) +#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) +#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) +#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) +#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) +#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) +#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) +#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer) +#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers) +#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers) +#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap) +#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv) +#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv) +#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer) +#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer) +#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage) +#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample) + +#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object) + +#endif /* GL_ARB_framebuffer_object */ + +/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB 0x8DB9 + +#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB) + +#endif /* GL_ARB_framebuffer_sRGB */ + +/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_ARB 0xA +#define GL_LINE_STRIP_ADJACENCY_ARB 0xB +#define GL_TRIANGLES_ADJACENCY_ARB 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB) +#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB) +#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB) +#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB) + +#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4) + +#endif /* GL_ARB_geometry_shader4 */ + +/* ----------------------- GL_ARB_get_program_binary ----------------------- */ + +#ifndef GL_ARB_get_program_binary +#define GL_ARB_get_program_binary 1 + +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, GLvoid*binary); +typedef void (GLAPIENTRY * PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void* binary, GLsizei length); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); + +#define glGetProgramBinary GLEW_GET_FUN(__glewGetProgramBinary) +#define glProgramBinary GLEW_GET_FUN(__glewProgramBinary) +#define glProgramParameteri GLEW_GET_FUN(__glewProgramParameteri) + +#define GLEW_ARB_get_program_binary GLEW_GET_VAR(__GLEW_ARB_get_program_binary) + +#endif /* GL_ARB_get_program_binary */ + +/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */ + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 + +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 + +#define GLEW_ARB_gpu_shader5 GLEW_GET_VAR(__GLEW_ARB_gpu_shader5) + +#endif /* GL_ARB_gpu_shader5 */ + +/* ------------------------- GL_ARB_gpu_shader_fp64 ------------------------ */ + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 + +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); + +#define glGetUniformdv GLEW_GET_FUN(__glewGetUniformdv) +#define glProgramUniform1dEXT GLEW_GET_FUN(__glewProgramUniform1dEXT) +#define glProgramUniform1dvEXT GLEW_GET_FUN(__glewProgramUniform1dvEXT) +#define glProgramUniform2dEXT GLEW_GET_FUN(__glewProgramUniform2dEXT) +#define glProgramUniform2dvEXT GLEW_GET_FUN(__glewProgramUniform2dvEXT) +#define glProgramUniform3dEXT GLEW_GET_FUN(__glewProgramUniform3dEXT) +#define glProgramUniform3dvEXT GLEW_GET_FUN(__glewProgramUniform3dvEXT) +#define glProgramUniform4dEXT GLEW_GET_FUN(__glewProgramUniform4dEXT) +#define glProgramUniform4dvEXT GLEW_GET_FUN(__glewProgramUniform4dvEXT) +#define glProgramUniformMatrix2dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2dvEXT) +#define glProgramUniformMatrix2x3dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3dvEXT) +#define glProgramUniformMatrix2x4dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4dvEXT) +#define glProgramUniformMatrix3dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3dvEXT) +#define glProgramUniformMatrix3x2dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2dvEXT) +#define glProgramUniformMatrix3x4dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4dvEXT) +#define glProgramUniformMatrix4dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4dvEXT) +#define glProgramUniformMatrix4x2dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2dvEXT) +#define glProgramUniformMatrix4x3dvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3dvEXT) +#define glUniform1d GLEW_GET_FUN(__glewUniform1d) +#define glUniform1dv GLEW_GET_FUN(__glewUniform1dv) +#define glUniform2d GLEW_GET_FUN(__glewUniform2d) +#define glUniform2dv GLEW_GET_FUN(__glewUniform2dv) +#define glUniform3d GLEW_GET_FUN(__glewUniform3d) +#define glUniform3dv GLEW_GET_FUN(__glewUniform3dv) +#define glUniform4d GLEW_GET_FUN(__glewUniform4d) +#define glUniform4dv GLEW_GET_FUN(__glewUniform4dv) +#define glUniformMatrix2dv GLEW_GET_FUN(__glewUniformMatrix2dv) +#define glUniformMatrix2x3dv GLEW_GET_FUN(__glewUniformMatrix2x3dv) +#define glUniformMatrix2x4dv GLEW_GET_FUN(__glewUniformMatrix2x4dv) +#define glUniformMatrix3dv GLEW_GET_FUN(__glewUniformMatrix3dv) +#define glUniformMatrix3x2dv GLEW_GET_FUN(__glewUniformMatrix3x2dv) +#define glUniformMatrix3x4dv GLEW_GET_FUN(__glewUniformMatrix3x4dv) +#define glUniformMatrix4dv GLEW_GET_FUN(__glewUniformMatrix4dv) +#define glUniformMatrix4x2dv GLEW_GET_FUN(__glewUniformMatrix4x2dv) +#define glUniformMatrix4x3dv GLEW_GET_FUN(__glewUniformMatrix4x3dv) + +#define GLEW_ARB_gpu_shader_fp64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_fp64) + +#endif /* GL_ARB_gpu_shader_fp64 */ + +/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 + +#define GL_HALF_FLOAT_ARB 0x140B + +#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) + +#endif /* GL_ARB_half_float_pixel */ + +/* ------------------------ GL_ARB_half_float_vertex ----------------------- */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 + +#define GL_HALF_FLOAT 0x140B + +#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex) + +#endif /* GL_ARB_half_float_vertex */ + +/* ----------------------------- GL_ARB_imaging ---------------------------- */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_IGNORE_BORDER 0x8150 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_WRAP_BORDER 0x8152 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + +#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) +#define glColorTable GLEW_GET_FUN(__glewColorTable) +#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) +#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) +#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) +#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) +#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) +#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) +#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) +#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) +#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) +#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) +#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) +#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) +#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) +#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) +#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) +#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) +#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) +#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) +#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) +#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) +#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) +#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) +#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) +#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) +#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) +#define glHistogram GLEW_GET_FUN(__glewHistogram) +#define glMinmax GLEW_GET_FUN(__glewMinmax) +#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) +#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) +#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) + +#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) + +#endif /* GL_ARB_imaging */ + +/* ------------------------ GL_ARB_instanced_arrays ------------------------ */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + +#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) +#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) +#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB) + +#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays) + +#endif /* GL_ARB_instanced_arrays */ + +/* ------------------------ GL_ARB_map_buffer_range ------------------------ */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 + +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 + +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + +#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange) +#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange) + +#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range) + +#endif /* GL_ARB_map_buffer_range */ + +/* ------------------------- GL_ARB_matrix_palette ------------------------- */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 + +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 + +typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); + +#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) +#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) +#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) +#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) +#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) + +#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) + +#endif /* GL_ARB_matrix_palette */ + +/* --------------------------- GL_ARB_multisample -------------------------- */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 + +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + +#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) + +#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) + +#endif /* GL_ARB_multisample */ + +/* -------------------------- GL_ARB_multitexture -------------------------- */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) +#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) +#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) +#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) +#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) +#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) +#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) +#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) +#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) +#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) +#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) +#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) +#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) +#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) +#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) +#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) +#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) +#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) +#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) +#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) +#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) +#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) +#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) +#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) +#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) +#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) +#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) +#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) +#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) +#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) +#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) +#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) +#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) +#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) + +#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) + +#endif /* GL_ARB_multitexture */ + +/* ------------------------- GL_ARB_occlusion_query ------------------------ */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 + +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); + +#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) +#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) +#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) +#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) +#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) +#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) +#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) +#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) + +#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) + +#endif /* GL_ARB_occlusion_query */ + +/* ------------------------ GL_ARB_occlusion_query2 ------------------------ */ + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 + +#define GL_ANY_SAMPLES_PASSED 0x8C2F + +#define GLEW_ARB_occlusion_query2 GLEW_GET_VAR(__GLEW_ARB_occlusion_query2) + +#endif /* GL_ARB_occlusion_query2 */ + +/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF + +#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) + +#endif /* GL_ARB_pixel_buffer_object */ + +/* ------------------------ GL_ARB_point_parameters ------------------------ */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 + +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat* params); + +#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) +#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) + +#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) + +#endif /* GL_ARB_point_parameters */ + +/* -------------------------- GL_ARB_point_sprite -------------------------- */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 + +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 + +#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) + +#endif /* GL_ARB_point_sprite */ + +/* ------------------------ GL_ARB_provoking_vertex ------------------------ */ + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 + +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F + +typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode); + +#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex) + +#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex) + +#endif /* GL_ARB_provoking_vertex */ + +/* --------------------------- GL_ARB_robustness --------------------------- */ + +#ifndef GL_ARB_robustness +#define GL_ARB_robustness 1 + +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 + +typedef void (GLAPIENTRY * PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table); +typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void* img); +typedef void (GLAPIENTRY * PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image); +typedef void (GLAPIENTRY * PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +typedef void (GLAPIENTRY * PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble* v); +typedef void (GLAPIENTRY * PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat* v); +typedef void (GLAPIENTRY * PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint* v); +typedef void (GLAPIENTRY * PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort* values); +typedef void (GLAPIENTRY * PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte* pattern); +typedef void (GLAPIENTRY * PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, GLvoid*column, GLvoid*span); +typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* img); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); +typedef void (GLAPIENTRY * PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data); + +#define glGetnColorTableARB GLEW_GET_FUN(__glewGetnColorTableARB) +#define glGetnCompressedTexImageARB GLEW_GET_FUN(__glewGetnCompressedTexImageARB) +#define glGetnConvolutionFilterARB GLEW_GET_FUN(__glewGetnConvolutionFilterARB) +#define glGetnHistogramARB GLEW_GET_FUN(__glewGetnHistogramARB) +#define glGetnMapdvARB GLEW_GET_FUN(__glewGetnMapdvARB) +#define glGetnMapfvARB GLEW_GET_FUN(__glewGetnMapfvARB) +#define glGetnMapivARB GLEW_GET_FUN(__glewGetnMapivARB) +#define glGetnMinmaxARB GLEW_GET_FUN(__glewGetnMinmaxARB) +#define glGetnPixelMapfvARB GLEW_GET_FUN(__glewGetnPixelMapfvARB) +#define glGetnPixelMapuivARB GLEW_GET_FUN(__glewGetnPixelMapuivARB) +#define glGetnPixelMapusvARB GLEW_GET_FUN(__glewGetnPixelMapusvARB) +#define glGetnPolygonStippleARB GLEW_GET_FUN(__glewGetnPolygonStippleARB) +#define glGetnSeparableFilterARB GLEW_GET_FUN(__glewGetnSeparableFilterARB) +#define glGetnTexImageARB GLEW_GET_FUN(__glewGetnTexImageARB) +#define glGetnUniformdvARB GLEW_GET_FUN(__glewGetnUniformdvARB) +#define glGetnUniformfvARB GLEW_GET_FUN(__glewGetnUniformfvARB) +#define glGetnUniformivARB GLEW_GET_FUN(__glewGetnUniformivARB) +#define glGetnUniformuivARB GLEW_GET_FUN(__glewGetnUniformuivARB) +#define glReadnPixelsARB GLEW_GET_FUN(__glewReadnPixelsARB) + +#define GLEW_ARB_robustness GLEW_GET_VAR(__GLEW_ARB_robustness) + +#endif /* GL_ARB_robustness */ + +/* ------------------------- GL_ARB_sample_shading ------------------------- */ + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading 1 + +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 + +typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value); + +#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB) + +#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading) + +#endif /* GL_ARB_sample_shading */ + +/* ------------------------- GL_ARB_sampler_objects ------------------------ */ + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 + +#define GL_SAMPLER_BINDING 0x8919 + +typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers); +typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint* params); + +#define glBindSampler GLEW_GET_FUN(__glewBindSampler) +#define glDeleteSamplers GLEW_GET_FUN(__glewDeleteSamplers) +#define glGenSamplers GLEW_GET_FUN(__glewGenSamplers) +#define glGetSamplerParameterIiv GLEW_GET_FUN(__glewGetSamplerParameterIiv) +#define glGetSamplerParameterIuiv GLEW_GET_FUN(__glewGetSamplerParameterIuiv) +#define glGetSamplerParameterfv GLEW_GET_FUN(__glewGetSamplerParameterfv) +#define glGetSamplerParameteriv GLEW_GET_FUN(__glewGetSamplerParameteriv) +#define glIsSampler GLEW_GET_FUN(__glewIsSampler) +#define glSamplerParameterIiv GLEW_GET_FUN(__glewSamplerParameterIiv) +#define glSamplerParameterIuiv GLEW_GET_FUN(__glewSamplerParameterIuiv) +#define glSamplerParameterf GLEW_GET_FUN(__glewSamplerParameterf) +#define glSamplerParameterfv GLEW_GET_FUN(__glewSamplerParameterfv) +#define glSamplerParameteri GLEW_GET_FUN(__glewSamplerParameteri) +#define glSamplerParameteriv GLEW_GET_FUN(__glewSamplerParameteriv) + +#define GLEW_ARB_sampler_objects GLEW_GET_VAR(__GLEW_ARB_sampler_objects) + +#endif /* GL_ARB_sampler_objects */ + +/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */ + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F + +#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map) + +#endif /* GL_ARB_seamless_cube_map */ + +/* --------------------- GL_ARB_separate_shader_objects -------------------- */ + +#ifndef GL_ARB_separate_shader_objects +#define GL_ARB_separate_shader_objects 1 + +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_ALL_SHADER_BITS 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const char ** strings); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint* pipelines); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei* length, char *infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); + +#define glActiveShaderProgram GLEW_GET_FUN(__glewActiveShaderProgram) +#define glBindProgramPipeline GLEW_GET_FUN(__glewBindProgramPipeline) +#define glCreateShaderProgramv GLEW_GET_FUN(__glewCreateShaderProgramv) +#define glDeleteProgramPipelines GLEW_GET_FUN(__glewDeleteProgramPipelines) +#define glGenProgramPipelines GLEW_GET_FUN(__glewGenProgramPipelines) +#define glGetProgramPipelineInfoLog GLEW_GET_FUN(__glewGetProgramPipelineInfoLog) +#define glGetProgramPipelineiv GLEW_GET_FUN(__glewGetProgramPipelineiv) +#define glIsProgramPipeline GLEW_GET_FUN(__glewIsProgramPipeline) +#define glProgramUniform1d GLEW_GET_FUN(__glewProgramUniform1d) +#define glProgramUniform1dv GLEW_GET_FUN(__glewProgramUniform1dv) +#define glProgramUniform1f GLEW_GET_FUN(__glewProgramUniform1f) +#define glProgramUniform1fv GLEW_GET_FUN(__glewProgramUniform1fv) +#define glProgramUniform1i GLEW_GET_FUN(__glewProgramUniform1i) +#define glProgramUniform1iv GLEW_GET_FUN(__glewProgramUniform1iv) +#define glProgramUniform1ui GLEW_GET_FUN(__glewProgramUniform1ui) +#define glProgramUniform1uiv GLEW_GET_FUN(__glewProgramUniform1uiv) +#define glProgramUniform2d GLEW_GET_FUN(__glewProgramUniform2d) +#define glProgramUniform2dv GLEW_GET_FUN(__glewProgramUniform2dv) +#define glProgramUniform2f GLEW_GET_FUN(__glewProgramUniform2f) +#define glProgramUniform2fv GLEW_GET_FUN(__glewProgramUniform2fv) +#define glProgramUniform2i GLEW_GET_FUN(__glewProgramUniform2i) +#define glProgramUniform2iv GLEW_GET_FUN(__glewProgramUniform2iv) +#define glProgramUniform2ui GLEW_GET_FUN(__glewProgramUniform2ui) +#define glProgramUniform2uiv GLEW_GET_FUN(__glewProgramUniform2uiv) +#define glProgramUniform3d GLEW_GET_FUN(__glewProgramUniform3d) +#define glProgramUniform3dv GLEW_GET_FUN(__glewProgramUniform3dv) +#define glProgramUniform3f GLEW_GET_FUN(__glewProgramUniform3f) +#define glProgramUniform3fv GLEW_GET_FUN(__glewProgramUniform3fv) +#define glProgramUniform3i GLEW_GET_FUN(__glewProgramUniform3i) +#define glProgramUniform3iv GLEW_GET_FUN(__glewProgramUniform3iv) +#define glProgramUniform3ui GLEW_GET_FUN(__glewProgramUniform3ui) +#define glProgramUniform3uiv GLEW_GET_FUN(__glewProgramUniform3uiv) +#define glProgramUniform4d GLEW_GET_FUN(__glewProgramUniform4d) +#define glProgramUniform4dv GLEW_GET_FUN(__glewProgramUniform4dv) +#define glProgramUniform4f GLEW_GET_FUN(__glewProgramUniform4f) +#define glProgramUniform4fv GLEW_GET_FUN(__glewProgramUniform4fv) +#define glProgramUniform4i GLEW_GET_FUN(__glewProgramUniform4i) +#define glProgramUniform4iv GLEW_GET_FUN(__glewProgramUniform4iv) +#define glProgramUniform4ui GLEW_GET_FUN(__glewProgramUniform4ui) +#define glProgramUniform4uiv GLEW_GET_FUN(__glewProgramUniform4uiv) +#define glProgramUniformMatrix2dv GLEW_GET_FUN(__glewProgramUniformMatrix2dv) +#define glProgramUniformMatrix2fv GLEW_GET_FUN(__glewProgramUniformMatrix2fv) +#define glProgramUniformMatrix2x3dv GLEW_GET_FUN(__glewProgramUniformMatrix2x3dv) +#define glProgramUniformMatrix2x3fv GLEW_GET_FUN(__glewProgramUniformMatrix2x3fv) +#define glProgramUniformMatrix2x4dv GLEW_GET_FUN(__glewProgramUniformMatrix2x4dv) +#define glProgramUniformMatrix2x4fv GLEW_GET_FUN(__glewProgramUniformMatrix2x4fv) +#define glProgramUniformMatrix3dv GLEW_GET_FUN(__glewProgramUniformMatrix3dv) +#define glProgramUniformMatrix3fv GLEW_GET_FUN(__glewProgramUniformMatrix3fv) +#define glProgramUniformMatrix3x2dv GLEW_GET_FUN(__glewProgramUniformMatrix3x2dv) +#define glProgramUniformMatrix3x2fv GLEW_GET_FUN(__glewProgramUniformMatrix3x2fv) +#define glProgramUniformMatrix3x4dv GLEW_GET_FUN(__glewProgramUniformMatrix3x4dv) +#define glProgramUniformMatrix3x4fv GLEW_GET_FUN(__glewProgramUniformMatrix3x4fv) +#define glProgramUniformMatrix4dv GLEW_GET_FUN(__glewProgramUniformMatrix4dv) +#define glProgramUniformMatrix4fv GLEW_GET_FUN(__glewProgramUniformMatrix4fv) +#define glProgramUniformMatrix4x2dv GLEW_GET_FUN(__glewProgramUniformMatrix4x2dv) +#define glProgramUniformMatrix4x2fv GLEW_GET_FUN(__glewProgramUniformMatrix4x2fv) +#define glProgramUniformMatrix4x3dv GLEW_GET_FUN(__glewProgramUniformMatrix4x3dv) +#define glProgramUniformMatrix4x3fv GLEW_GET_FUN(__glewProgramUniformMatrix4x3fv) +#define glUseProgramStages GLEW_GET_FUN(__glewUseProgramStages) +#define glValidateProgramPipeline GLEW_GET_FUN(__glewValidateProgramPipeline) + +#define GLEW_ARB_separate_shader_objects GLEW_GET_VAR(__GLEW_ARB_separate_shader_objects) + +#endif /* GL_ARB_separate_shader_objects */ + +/* ----------------------- GL_ARB_shader_bit_encoding ---------------------- */ + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 + +#define GLEW_ARB_shader_bit_encoding GLEW_GET_VAR(__GLEW_ARB_shader_bit_encoding) + +#endif /* GL_ARB_shader_bit_encoding */ + +/* ------------------------- GL_ARB_shader_objects ------------------------- */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 + +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 + +typedef char GLcharARB; +typedef unsigned int GLhandleARB; + +typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); +typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); + +#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) +#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) +#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) +#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) +#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) +#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) +#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) +#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) +#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) +#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) +#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) +#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) +#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) +#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) +#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) +#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) +#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) +#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) +#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) +#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) +#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) +#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) +#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) +#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) +#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) +#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) +#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) +#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) +#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) +#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) +#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) +#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) +#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) +#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) +#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) +#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) +#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) +#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) +#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) + +#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) + +#endif /* GL_ARB_shader_objects */ + +/* ------------------------ GL_ARB_shader_precision ------------------------ */ + +#ifndef GL_ARB_shader_precision +#define GL_ARB_shader_precision 1 + +#define GLEW_ARB_shader_precision GLEW_GET_VAR(__GLEW_ARB_shader_precision) + +#endif /* GL_ARB_shader_precision */ + +/* ---------------------- GL_ARB_shader_stencil_export --------------------- */ + +#ifndef GL_ARB_shader_stencil_export +#define GL_ARB_shader_stencil_export 1 + +#define GLEW_ARB_shader_stencil_export GLEW_GET_VAR(__GLEW_ARB_shader_stencil_export) + +#endif /* GL_ARB_shader_stencil_export */ + +/* ------------------------ GL_ARB_shader_subroutine ----------------------- */ + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 + +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B + +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, char *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, char *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint* values); +typedef GLuint (GLAPIENTRY * PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const char* name); +typedef GLint (GLAPIENTRY * PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const char* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint* params); +typedef void (GLAPIENTRY * PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint* indices); + +#define glGetActiveSubroutineName GLEW_GET_FUN(__glewGetActiveSubroutineName) +#define glGetActiveSubroutineUniformName GLEW_GET_FUN(__glewGetActiveSubroutineUniformName) +#define glGetActiveSubroutineUniformiv GLEW_GET_FUN(__glewGetActiveSubroutineUniformiv) +#define glGetProgramStageiv GLEW_GET_FUN(__glewGetProgramStageiv) +#define glGetSubroutineIndex GLEW_GET_FUN(__glewGetSubroutineIndex) +#define glGetSubroutineUniformLocation GLEW_GET_FUN(__glewGetSubroutineUniformLocation) +#define glGetUniformSubroutineuiv GLEW_GET_FUN(__glewGetUniformSubroutineuiv) +#define glUniformSubroutinesuiv GLEW_GET_FUN(__glewUniformSubroutinesuiv) + +#define GLEW_ARB_shader_subroutine GLEW_GET_VAR(__GLEW_ARB_shader_subroutine) + +#endif /* GL_ARB_shader_subroutine */ + +/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */ + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod 1 + +#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod) + +#endif /* GL_ARB_shader_texture_lod */ + +/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 + +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C + +#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) + +#endif /* GL_ARB_shading_language_100 */ + +/* -------------------- GL_ARB_shading_language_include -------------------- */ + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include 1 + +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA + +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const char ** path, const GLint *length); +typedef void (GLAPIENTRY * PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const char* name); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const char* name, GLsizei bufSize, GLint *stringlen, char *string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const char* name, GLenum pname, GLint *params); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const char* name); +typedef void (GLAPIENTRY * PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const char* name, GLint stringlen, const char *string); + +#define glCompileShaderIncludeARB GLEW_GET_FUN(__glewCompileShaderIncludeARB) +#define glDeleteNamedStringARB GLEW_GET_FUN(__glewDeleteNamedStringARB) +#define glGetNamedStringARB GLEW_GET_FUN(__glewGetNamedStringARB) +#define glGetNamedStringivARB GLEW_GET_FUN(__glewGetNamedStringivARB) +#define glIsNamedStringARB GLEW_GET_FUN(__glewIsNamedStringARB) +#define glNamedStringARB GLEW_GET_FUN(__glewNamedStringARB) + +#define GLEW_ARB_shading_language_include GLEW_GET_VAR(__GLEW_ARB_shading_language_include) + +#endif /* GL_ARB_shading_language_include */ + +/* ----------------------------- GL_ARB_shadow ----------------------------- */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 + +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E + +#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) + +#endif /* GL_ARB_shadow */ + +/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 + +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF + +#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) + +#endif /* GL_ARB_shadow_ambient */ + +/* ------------------------------ GL_ARB_sync ------------------------------ */ + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 + +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF + +typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); +typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync); +typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values); +typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync); +typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); + +#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync) +#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync) +#define glFenceSync GLEW_GET_FUN(__glewFenceSync) +#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v) +#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv) +#define glIsSync GLEW_GET_FUN(__glewIsSync) +#define glWaitSync GLEW_GET_FUN(__glewWaitSync) + +#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync) + +#endif /* GL_ARB_sync */ + +/* ----------------------- GL_ARB_tessellation_shader ---------------------- */ + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 + +#define GL_PATCHES 0xE +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A + +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat* values); +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); + +#define glPatchParameterfv GLEW_GET_FUN(__glewPatchParameterfv) +#define glPatchParameteri GLEW_GET_FUN(__glewPatchParameteri) + +#define GLEW_ARB_tessellation_shader GLEW_GET_VAR(__GLEW_ARB_tessellation_shader) + +#endif /* GL_ARB_tessellation_shader */ + +/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_ARB 0x812D + +#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) + +#endif /* GL_ARB_texture_border_clamp */ + +/* ---------------------- GL_ARB_texture_buffer_object --------------------- */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB) + +#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object) + +#endif /* GL_ARB_texture_buffer_object */ + +/* ------------------- GL_ARB_texture_buffer_object_rgb32 ------------------ */ + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 + +#define GLEW_ARB_texture_buffer_object_rgb32 GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object_rgb32) + +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +/* ----------------------- GL_ARB_texture_compression ---------------------- */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 + +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void* img); + +#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) +#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) +#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) +#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) +#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) +#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) +#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) + +#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) + +#endif /* GL_ARB_texture_compression */ + +/* -------------------- GL_ARB_texture_compression_bptc -------------------- */ + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc 1 + +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F + +#define GLEW_ARB_texture_compression_bptc GLEW_GET_VAR(__GLEW_ARB_texture_compression_bptc) + +#endif /* GL_ARB_texture_compression_bptc */ + +/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE + +#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc) + +#endif /* GL_ARB_texture_compression_rgtc */ + +/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 + +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C + +#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) + +#endif /* GL_ARB_texture_cube_map */ + +/* --------------------- GL_ARB_texture_cube_map_array --------------------- */ + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array 1 + +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F + +#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array) + +#endif /* GL_ARB_texture_cube_map_array */ + +/* ------------------------- GL_ARB_texture_env_add ------------------------ */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 + +#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) + +#endif /* GL_ARB_texture_env_add */ + +/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 + +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A + +#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) + +#endif /* GL_ARB_texture_env_combine */ + +/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 + +#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) + +#endif /* GL_ARB_texture_env_crossbar */ + +/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 + +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF + +#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) + +#endif /* GL_ARB_texture_env_dot3 */ + +/* -------------------------- GL_ARB_texture_float ------------------------- */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 + +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 + +#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) + +#endif /* GL_ARB_texture_float */ + +/* ------------------------- GL_ARB_texture_gather ------------------------- */ + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather 1 + +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F + +#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather) + +#endif /* GL_ARB_texture_gather */ + +/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_ARB 0x8370 + +#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) + +#endif /* GL_ARB_texture_mirrored_repeat */ + +/* ----------------------- GL_ARB_texture_multisample ---------------------- */ + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 + +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 + +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + +#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv) +#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski) +#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample) +#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample) + +#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample) + +#endif /* GL_ARB_texture_multisample */ + +/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 + +#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) + +#endif /* GL_ARB_texture_non_power_of_two */ + +/* ------------------------ GL_ARB_texture_query_lod ----------------------- */ + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 + +#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod) + +#endif /* GL_ARB_texture_query_lod */ + +/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + +#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) + +#endif /* GL_ARB_texture_rectangle */ + +/* --------------------------- GL_ARB_texture_rg --------------------------- */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 + +#define GL_RED 0x1903 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C + +#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg) + +#endif /* GL_ARB_texture_rg */ + +/* ----------------------- GL_ARB_texture_rgb10_a2ui ----------------------- */ + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 + +#define GL_RGB10_A2UI 0x906F + +#define GLEW_ARB_texture_rgb10_a2ui GLEW_GET_VAR(__GLEW_ARB_texture_rgb10_a2ui) + +#endif /* GL_ARB_texture_rgb10_a2ui */ + +/* ------------------------- GL_ARB_texture_swizzle ------------------------ */ + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 + +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 + +#define GLEW_ARB_texture_swizzle GLEW_GET_VAR(__GLEW_ARB_texture_swizzle) + +#endif /* GL_ARB_texture_swizzle */ + +/* --------------------------- GL_ARB_timer_query -------------------------- */ + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 + +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); + +#define glGetQueryObjecti64v GLEW_GET_FUN(__glewGetQueryObjecti64v) +#define glGetQueryObjectui64v GLEW_GET_FUN(__glewGetQueryObjectui64v) +#define glQueryCounter GLEW_GET_FUN(__glewQueryCounter) + +#define GLEW_ARB_timer_query GLEW_GET_VAR(__GLEW_ARB_timer_query) + +#endif /* GL_ARB_timer_query */ + +/* ----------------------- GL_ARB_transform_feedback2 ---------------------- */ + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 + +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 + +typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); + +#define glBindTransformFeedback GLEW_GET_FUN(__glewBindTransformFeedback) +#define glDeleteTransformFeedbacks GLEW_GET_FUN(__glewDeleteTransformFeedbacks) +#define glDrawTransformFeedback GLEW_GET_FUN(__glewDrawTransformFeedback) +#define glGenTransformFeedbacks GLEW_GET_FUN(__glewGenTransformFeedbacks) +#define glIsTransformFeedback GLEW_GET_FUN(__glewIsTransformFeedback) +#define glPauseTransformFeedback GLEW_GET_FUN(__glewPauseTransformFeedback) +#define glResumeTransformFeedback GLEW_GET_FUN(__glewResumeTransformFeedback) + +#define GLEW_ARB_transform_feedback2 GLEW_GET_VAR(__GLEW_ARB_transform_feedback2) + +#endif /* GL_ARB_transform_feedback2 */ + +/* ----------------------- GL_ARB_transform_feedback3 ---------------------- */ + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 + +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_VERTEX_STREAMS 0x8E71 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (GLAPIENTRY * PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); + +#define glBeginQueryIndexed GLEW_GET_FUN(__glewBeginQueryIndexed) +#define glDrawTransformFeedbackStream GLEW_GET_FUN(__glewDrawTransformFeedbackStream) +#define glEndQueryIndexed GLEW_GET_FUN(__glewEndQueryIndexed) +#define glGetQueryIndexediv GLEW_GET_FUN(__glewGetQueryIndexediv) + +#define GLEW_ARB_transform_feedback3 GLEW_GET_VAR(__GLEW_ARB_transform_feedback3) + +#endif /* GL_ARB_transform_feedback3 */ + +/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 + +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 + +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); + +#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) +#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) +#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) +#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) + +#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) + +#endif /* GL_ARB_transpose_matrix */ + +/* ---------------------- GL_ARB_uniform_buffer_object --------------------- */ + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 + +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, char* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, char* uniformName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data); +typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const char* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const char** uniformNames, GLuint* uniformIndices); +typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + +#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) +#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) +#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName) +#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv) +#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName) +#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv) +#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) +#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex) +#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices) +#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding) + +#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object) + +#endif /* GL_ARB_uniform_buffer_object */ + +/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */ + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra) + +#endif /* GL_ARB_vertex_array_bgra */ + +/* ----------------------- GL_ARB_vertex_array_object ---------------------- */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); + +#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray) +#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays) +#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays) +#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray) + +#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object) + +#endif /* GL_ARB_vertex_array_object */ + +/* ----------------------- GL_ARB_vertex_attrib_64bit ---------------------- */ + +#ifndef GL_ARB_vertex_attrib_64bit +#define GL_ARB_vertex_attrib_64bit 1 + +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); + +#define glGetVertexAttribLdv GLEW_GET_FUN(__glewGetVertexAttribLdv) +#define glVertexAttribL1d GLEW_GET_FUN(__glewVertexAttribL1d) +#define glVertexAttribL1dv GLEW_GET_FUN(__glewVertexAttribL1dv) +#define glVertexAttribL2d GLEW_GET_FUN(__glewVertexAttribL2d) +#define glVertexAttribL2dv GLEW_GET_FUN(__glewVertexAttribL2dv) +#define glVertexAttribL3d GLEW_GET_FUN(__glewVertexAttribL3d) +#define glVertexAttribL3dv GLEW_GET_FUN(__glewVertexAttribL3dv) +#define glVertexAttribL4d GLEW_GET_FUN(__glewVertexAttribL4d) +#define glVertexAttribL4dv GLEW_GET_FUN(__glewVertexAttribL4dv) +#define glVertexAttribLPointer GLEW_GET_FUN(__glewVertexAttribLPointer) + +#define GLEW_ARB_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_64bit) + +#endif /* GL_ARB_vertex_attrib_64bit */ + +/* -------------------------- GL_ARB_vertex_blend -------------------------- */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 + +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F + +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); +typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); + +#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) +#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) +#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) +#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) +#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) +#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) +#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) +#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) +#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) +#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) + +#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) + +#endif /* GL_ARB_vertex_blend */ + +/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 + +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA + +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); + +#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) +#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) +#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) +#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) +#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) +#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) +#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) +#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) +#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) +#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) +#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) + +#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) + +#endif /* GL_ARB_vertex_buffer_object */ + +/* ------------------------- GL_ARB_vertex_program ------------------------- */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 + +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF + +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + +#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) +#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) +#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) +#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) +#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) +#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) +#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) +#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) +#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) +#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) +#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) +#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) +#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) +#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) +#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) +#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) +#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) +#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) +#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) +#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) +#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) +#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) +#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) +#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) +#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) +#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) +#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) +#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) +#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) +#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) +#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) +#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) +#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) +#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) +#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) +#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) +#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) +#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) +#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) +#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) +#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) +#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) +#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) +#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) +#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) +#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) +#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) +#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) +#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) +#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) +#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) +#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) +#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) +#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) +#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) +#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) +#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) +#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) +#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) +#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) +#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) +#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) + +#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) + +#endif /* GL_ARB_vertex_program */ + +/* -------------------------- GL_ARB_vertex_shader ------------------------- */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 + +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A + +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); + +#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) +#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) +#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) + +#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) + +#endif /* GL_ARB_vertex_shader */ + +/* ------------------- GL_ARB_vertex_type_2_10_10_10_rev ------------------- */ + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 + +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_INT_2_10_10_10_REV 0x8D9F + +typedef void (GLAPIENTRY * PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint* value); + +#define glColorP3ui GLEW_GET_FUN(__glewColorP3ui) +#define glColorP3uiv GLEW_GET_FUN(__glewColorP3uiv) +#define glColorP4ui GLEW_GET_FUN(__glewColorP4ui) +#define glColorP4uiv GLEW_GET_FUN(__glewColorP4uiv) +#define glMultiTexCoordP1ui GLEW_GET_FUN(__glewMultiTexCoordP1ui) +#define glMultiTexCoordP1uiv GLEW_GET_FUN(__glewMultiTexCoordP1uiv) +#define glMultiTexCoordP2ui GLEW_GET_FUN(__glewMultiTexCoordP2ui) +#define glMultiTexCoordP2uiv GLEW_GET_FUN(__glewMultiTexCoordP2uiv) +#define glMultiTexCoordP3ui GLEW_GET_FUN(__glewMultiTexCoordP3ui) +#define glMultiTexCoordP3uiv GLEW_GET_FUN(__glewMultiTexCoordP3uiv) +#define glMultiTexCoordP4ui GLEW_GET_FUN(__glewMultiTexCoordP4ui) +#define glMultiTexCoordP4uiv GLEW_GET_FUN(__glewMultiTexCoordP4uiv) +#define glNormalP3ui GLEW_GET_FUN(__glewNormalP3ui) +#define glNormalP3uiv GLEW_GET_FUN(__glewNormalP3uiv) +#define glSecondaryColorP3ui GLEW_GET_FUN(__glewSecondaryColorP3ui) +#define glSecondaryColorP3uiv GLEW_GET_FUN(__glewSecondaryColorP3uiv) +#define glTexCoordP1ui GLEW_GET_FUN(__glewTexCoordP1ui) +#define glTexCoordP1uiv GLEW_GET_FUN(__glewTexCoordP1uiv) +#define glTexCoordP2ui GLEW_GET_FUN(__glewTexCoordP2ui) +#define glTexCoordP2uiv GLEW_GET_FUN(__glewTexCoordP2uiv) +#define glTexCoordP3ui GLEW_GET_FUN(__glewTexCoordP3ui) +#define glTexCoordP3uiv GLEW_GET_FUN(__glewTexCoordP3uiv) +#define glTexCoordP4ui GLEW_GET_FUN(__glewTexCoordP4ui) +#define glTexCoordP4uiv GLEW_GET_FUN(__glewTexCoordP4uiv) +#define glVertexAttribP1ui GLEW_GET_FUN(__glewVertexAttribP1ui) +#define glVertexAttribP1uiv GLEW_GET_FUN(__glewVertexAttribP1uiv) +#define glVertexAttribP2ui GLEW_GET_FUN(__glewVertexAttribP2ui) +#define glVertexAttribP2uiv GLEW_GET_FUN(__glewVertexAttribP2uiv) +#define glVertexAttribP3ui GLEW_GET_FUN(__glewVertexAttribP3ui) +#define glVertexAttribP3uiv GLEW_GET_FUN(__glewVertexAttribP3uiv) +#define glVertexAttribP4ui GLEW_GET_FUN(__glewVertexAttribP4ui) +#define glVertexAttribP4uiv GLEW_GET_FUN(__glewVertexAttribP4uiv) +#define glVertexP2ui GLEW_GET_FUN(__glewVertexP2ui) +#define glVertexP2uiv GLEW_GET_FUN(__glewVertexP2uiv) +#define glVertexP3ui GLEW_GET_FUN(__glewVertexP3ui) +#define glVertexP3uiv GLEW_GET_FUN(__glewVertexP3uiv) +#define glVertexP4ui GLEW_GET_FUN(__glewVertexP4ui) +#define glVertexP4uiv GLEW_GET_FUN(__glewVertexP4uiv) + +#define GLEW_ARB_vertex_type_2_10_10_10_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_2_10_10_10_rev) + +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +/* ------------------------- GL_ARB_viewport_array ------------------------- */ + +#ifndef GL_ARB_viewport_array +#define GL_ARB_viewport_array 1 + +#define GL_DEPTH_RANGE 0x0B70 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_MAX_VIEWPORTS 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F + +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd * v); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble* data); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint * v); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat * v); + +#define glDepthRangeArrayv GLEW_GET_FUN(__glewDepthRangeArrayv) +#define glDepthRangeIndexed GLEW_GET_FUN(__glewDepthRangeIndexed) +#define glGetDoublei_v GLEW_GET_FUN(__glewGetDoublei_v) +#define glGetFloati_v GLEW_GET_FUN(__glewGetFloati_v) +#define glScissorArrayv GLEW_GET_FUN(__glewScissorArrayv) +#define glScissorIndexed GLEW_GET_FUN(__glewScissorIndexed) +#define glScissorIndexedv GLEW_GET_FUN(__glewScissorIndexedv) +#define glViewportArrayv GLEW_GET_FUN(__glewViewportArrayv) +#define glViewportIndexedf GLEW_GET_FUN(__glewViewportIndexedf) +#define glViewportIndexedfv GLEW_GET_FUN(__glewViewportIndexedfv) + +#define GLEW_ARB_viewport_array GLEW_GET_VAR(__GLEW_ARB_viewport_array) + +#endif /* GL_ARB_viewport_array */ + +/* --------------------------- GL_ARB_window_pos --------------------------- */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); + +#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) +#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) +#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) +#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) +#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) +#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) +#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) +#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) +#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) +#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) +#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) +#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) +#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) +#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) +#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) +#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) + +#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) + +#endif /* GL_ARB_window_pos */ + +/* ------------------------- GL_ATIX_point_sprites ------------------------- */ + +#ifndef GL_ATIX_point_sprites +#define GL_ATIX_point_sprites 1 + +#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0 +#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1 +#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2 +#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3 +#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4 +#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5 + +#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) + +#endif /* GL_ATIX_point_sprites */ + +/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ + +#ifndef GL_ATIX_texture_env_combine3 +#define GL_ATIX_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATIX 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 +#define GL_MODULATE_SUBTRACT_ATIX 0x8746 + +#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) + +#endif /* GL_ATIX_texture_env_combine3 */ + +/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ + +#ifndef GL_ATIX_texture_env_route +#define GL_ATIX_texture_env_route 1 + +#define GL_SECONDARY_COLOR_ATIX 0x8747 +#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 +#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 + +#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) + +#endif /* GL_ATIX_texture_env_route */ + +/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ + +#ifndef GL_ATIX_vertex_shader_output_point_size +#define GL_ATIX_vertex_shader_output_point_size 1 + +#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E + +#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +/* -------------------------- GL_ATI_draw_buffers -------------------------- */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) + +#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) + +#endif /* GL_ATI_draw_buffers */ + +/* -------------------------- GL_ATI_element_array ------------------------- */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 + +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void* pointer); + +#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) +#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) +#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) + +#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) + +#endif /* GL_ATI_element_array */ + +/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 + +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C + +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); + +#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) +#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) +#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) +#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) + +#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) + +#endif /* GL_ATI_envmap_bumpmap */ + +/* ------------------------- GL_ATI_fragment_shader ------------------------ */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 + +#define GL_RED_BIT_ATI 0x00000001 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B + +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); + +#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) +#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) +#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) +#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) +#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) +#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) +#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) +#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) +#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) +#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) +#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) +#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) +#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) +#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) + +#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) + +#endif /* GL_ATI_fragment_shader */ + +/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 + +typedef void* (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); + +#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) +#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) + +#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) + +#endif /* GL_ATI_map_object_buffer */ + +/* ----------------------------- GL_ATI_meminfo ---------------------------- */ + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo 1 + +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD + +#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo) + +#endif /* GL_ATI_meminfo */ + +/* -------------------------- GL_ATI_pn_triangles -------------------------- */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 + +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 + +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); + +#define glPNTrianglesfATI GLEW_GET_FUN(__glewPNTrianglesfATI) +#define glPNTrianglesiATI GLEW_GET_FUN(__glewPNTrianglesiATI) + +#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) + +#endif /* GL_ATI_pn_triangles */ + +/* ------------------------ GL_ATI_separate_stencil ------------------------ */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 + +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 + +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + +#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) +#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) + +#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) + +#endif /* GL_ATI_separate_stencil */ + +/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */ + +#ifndef GL_ATI_shader_texture_lod +#define GL_ATI_shader_texture_lod 1 + +#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod) + +#endif /* GL_ATI_shader_texture_lod */ + +/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 + +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 + +#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) + +#endif /* GL_ATI_text_fragment_shader */ + +/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ + +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc 1 + +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 + +#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) + +#endif /* GL_ATI_texture_compression_3dc */ + +/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 + +#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) + +#endif /* GL_ATI_texture_env_combine3 */ + +/* -------------------------- GL_ATI_texture_float ------------------------- */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 + +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F + +#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) + +#endif /* GL_ATI_texture_float */ + +/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 + +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 + +#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) + +#endif /* GL_ATI_texture_mirror_once */ + +/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 + +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 + +typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void* pointer, GLenum usage); +typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void* pointer, GLenum preserve); +typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + +#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) +#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) +#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) +#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) +#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) +#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) +#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) +#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) +#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) +#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) +#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) +#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) + +#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) + +#endif /* GL_ATI_vertex_array_object */ + +/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); + +#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) +#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) +#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) + +#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) + +#endif /* GL_ATI_vertex_attrib_array_object */ + +/* ------------------------- GL_ATI_vertex_streams ------------------------- */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 + +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_SOURCE_ATI 0x876C +#define GL_VERTEX_STREAM0_ATI 0x876D +#define GL_VERTEX_STREAM1_ATI 0x876E +#define GL_VERTEX_STREAM2_ATI 0x876F +#define GL_VERTEX_STREAM3_ATI 0x8770 +#define GL_VERTEX_STREAM4_ATI 0x8771 +#define GL_VERTEX_STREAM5_ATI 0x8772 +#define GL_VERTEX_STREAM6_ATI 0x8773 +#define GL_VERTEX_STREAM7_ATI 0x8774 + +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *v); + +#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) +#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) +#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) +#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) +#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) +#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) +#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) +#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) +#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) +#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) +#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) +#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) +#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) +#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) +#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) +#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) +#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) +#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) +#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) +#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) +#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) +#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) +#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) +#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) +#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) +#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) +#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) +#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) +#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) +#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) +#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) +#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) +#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) +#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) +#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) +#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) +#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) + +#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) + +#endif /* GL_ATI_vertex_streams */ + +/* --------------------------- GL_EXT_422_pixels --------------------------- */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 + +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF + +#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) + +#endif /* GL_EXT_422_pixels */ + +/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 + +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F + +#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) + +#endif /* GL_EXT_Cg_shader */ + +/* ------------------------------ GL_EXT_abgr ------------------------------ */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 + +#define GL_ABGR_EXT 0x8000 + +#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) + +#endif /* GL_EXT_abgr */ + +/* ------------------------------ GL_EXT_bgra ------------------------------ */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 + +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 + +#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) + +#endif /* GL_EXT_bgra */ + +/* ------------------------ GL_EXT_bindable_uniform ------------------------ */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 + +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF + +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); + +#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT) +#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT) +#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT) + +#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform) + +#endif /* GL_EXT_bindable_uniform */ + +/* --------------------------- GL_EXT_blend_color -------------------------- */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 + +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 + +typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + +#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) + +#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) + +#endif /* GL_EXT_blend_color */ + +/* --------------------- GL_EXT_blend_equation_separate -------------------- */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 + +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); + +#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) + +#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) + +#endif /* GL_EXT_blend_equation_separate */ + +/* ----------------------- GL_EXT_blend_func_separate ---------------------- */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 + +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB + +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + +#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) + +#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) + +#endif /* GL_EXT_blend_func_separate */ + +/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 + +#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) + +#endif /* GL_EXT_blend_logic_op */ + +/* -------------------------- GL_EXT_blend_minmax -------------------------- */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 + +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); + +#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) + +#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) + +#endif /* GL_EXT_blend_minmax */ + +/* ------------------------- GL_EXT_blend_subtract ------------------------- */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 + +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B + +#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) + +#endif /* GL_EXT_blend_subtract */ + +/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 + +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 + +#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) + +#endif /* GL_EXT_clip_volume_hint */ + +/* ------------------------------ GL_EXT_cmyka ----------------------------- */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 + +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F + +#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) + +#endif /* GL_EXT_cmyka */ + +/* ------------------------- GL_EXT_color_subtable ------------------------- */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + +#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) +#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) + +#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) + +#endif /* GL_EXT_color_subtable */ + +/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 + +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 + +typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); + +#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) +#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) + +#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) + +#endif /* GL_EXT_compiled_vertex_array */ + +/* --------------------------- GL_EXT_convolution -------------------------- */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 + +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 + +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* row, void* column, void* span); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* row, const void* column); + +#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) +#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) +#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) +#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) +#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) +#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) +#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) +#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) +#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) +#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) +#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) +#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) +#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) + +#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) + +#endif /* GL_EXT_convolution */ + +/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 + +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 + +typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); + +#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) +#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) + +#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) + +#endif /* GL_EXT_coordinate_frame */ + +/* -------------------------- GL_EXT_copy_texture -------------------------- */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 + +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) +#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) +#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) +#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) +#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) + +#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) + +#endif /* GL_EXT_copy_texture */ + +/* --------------------------- GL_EXT_cull_vertex -------------------------- */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 + +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC + +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) +#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) + +#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) + +#endif /* GL_EXT_cull_vertex */ + +/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 + +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 + +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); + +#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) + +#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) + +#endif /* GL_EXT_depth_bounds_test */ + +/* ----------------------- GL_EXT_direct_state_access ---------------------- */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 + +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F + +typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void* data); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLvoid** param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, GLvoid** param); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data); +typedef void (GLAPIENTRY * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); + +#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT) +#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT) +#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT) +#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT) +#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT) +#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT) +#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT) +#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT) +#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT) +#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT) +#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT) +#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT) +#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT) +#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT) +#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT) +#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT) +#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT) +#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT) +#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT) +#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT) +#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT) +#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT) +#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT) +#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT) +#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT) +#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT) +#define glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT) +#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT) +#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT) +#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) +#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT) +#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT) +#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT) +#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT) +#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT) +#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT) +#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT) +#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT) +#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT) +#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT) +#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT) +#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT) +#define glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT) +#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) +#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT) +#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT) +#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT) +#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT) +#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT) +#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT) +#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT) +#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT) +#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT) +#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT) +#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT) +#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT) +#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT) +#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT) +#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT) +#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT) +#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT) +#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT) +#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT) +#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT) +#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT) +#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT) +#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT) +#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT) +#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT) +#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT) +#define glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT) +#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT) +#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT) +#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT) +#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT) +#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT) +#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT) +#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT) +#define glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT) +#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT) +#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT) +#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT) +#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) +#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT) +#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT) +#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT) +#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT) +#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT) +#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT) +#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT) +#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT) +#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT) +#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT) +#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT) +#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT) +#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT) +#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT) +#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT) +#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT) +#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT) +#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT) +#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT) +#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT) +#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT) +#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT) +#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT) +#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT) +#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT) +#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT) +#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT) +#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT) +#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT) +#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT) +#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT) +#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT) +#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT) +#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT) +#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT) +#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT) +#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT) +#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT) +#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT) +#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT) +#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT) +#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT) +#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT) +#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT) +#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT) +#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT) +#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT) +#define glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT) +#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT) +#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT) +#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT) +#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT) +#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT) +#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT) +#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT) +#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT) +#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT) +#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT) +#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT) +#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT) +#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT) +#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT) +#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT) +#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT) +#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT) +#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT) +#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT) +#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT) +#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT) +#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT) +#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT) +#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT) +#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT) +#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT) +#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT) +#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT) +#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT) +#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT) +#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT) +#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT) +#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT) +#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT) +#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT) +#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT) +#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT) +#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT) +#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT) +#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT) +#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT) +#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT) +#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT) +#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT) +#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT) +#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT) +#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT) +#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT) +#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT) +#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT) +#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT) +#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT) +#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT) +#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT) +#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT) +#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT) +#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT) +#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT) +#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT) +#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT) +#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT) +#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT) +#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT) +#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT) +#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT) +#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT) +#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT) +#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT) +#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT) +#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT) +#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT) +#define glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT) +#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT) +#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT) +#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT) +#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT) +#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT) +#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT) +#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT) +#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT) +#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT) +#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT) + +#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access) + +#endif /* GL_EXT_direct_state_access */ + +/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 + +typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); +typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); + +#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT) +#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT) +#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT) +#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT) +#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT) +#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT) + +#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2) + +#endif /* GL_EXT_draw_buffers2 */ + +/* ------------------------- GL_EXT_draw_instanced ------------------------- */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); + +#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT) +#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT) + +#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced) + +#endif /* GL_EXT_draw_instanced */ + +/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 + +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 + +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + +#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) + +#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) + +#endif /* GL_EXT_draw_range_elements */ + +/* ---------------------------- GL_EXT_fog_coord --------------------------- */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 + +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 + +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); + +#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) +#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) +#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) +#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) +#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) + +#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) + +#endif /* GL_EXT_fog_coord */ + +/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ + +#ifndef GL_EXT_fragment_lighting +#define GL_EXT_fragment_lighting 1 + +#define GL_FRAGMENT_LIGHTING_EXT 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 +#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 +#define GL_LIGHT_ENV_MODE_EXT 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B +#define GL_FRAGMENT_LIGHT0_EXT 0x840C +#define GL_FRAGMENT_LIGHT7_EXT 0x8413 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); + +#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) +#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) +#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) +#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) +#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) +#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) +#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) +#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) +#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) +#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) +#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) +#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) +#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) +#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) +#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) +#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) +#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) +#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) + +#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) + +#endif /* GL_EXT_fragment_lighting */ + +/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) + +#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) + +#endif /* GL_EXT_framebuffer_blit */ + +/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) + +#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) + +#endif /* GL_EXT_framebuffer_multisample */ + +/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) +#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) +#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) +#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) +#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) +#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) +#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) +#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) +#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) +#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) +#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) +#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) +#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) +#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) +#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) +#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) +#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) + +#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) + +#endif /* GL_EXT_framebuffer_object */ + +/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA + +#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB) + +#endif /* GL_EXT_framebuffer_sRGB */ + +/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) +#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) +#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT) + +#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4) + +#endif /* GL_EXT_geometry_shader4 */ + +/* --------------------- GL_EXT_gpu_program_parameters --------------------- */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); + +#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT) +#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT) + +#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters) + +#endif /* GL_EXT_gpu_program_parameters */ + +/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 + +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + +#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT) +#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT) +#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT) +#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT) +#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT) +#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT) +#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT) +#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT) +#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT) +#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT) +#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT) +#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT) +#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT) +#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT) +#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT) +#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT) +#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT) +#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT) +#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT) +#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT) +#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT) +#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT) +#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT) +#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT) +#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT) +#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT) +#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT) +#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT) +#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT) +#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT) +#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT) +#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT) +#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT) +#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT) + +#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4) + +#endif /* GL_EXT_gpu_shader4 */ + +/* ---------------------------- GL_EXT_histogram --------------------------- */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 + +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 + +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); + +#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) +#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) +#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) +#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) +#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) +#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) +#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) +#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) +#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) +#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) + +#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) + +#endif /* GL_EXT_histogram */ + +/* ----------------------- GL_EXT_index_array_formats ---------------------- */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 + +#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) + +#endif /* GL_EXT_index_array_formats */ + +/* --------------------------- GL_EXT_index_func --------------------------- */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 + +typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); + +#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) + +#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) + +#endif /* GL_EXT_index_func */ + +/* ------------------------- GL_EXT_index_material ------------------------- */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 + +typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) + +#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) + +#endif /* GL_EXT_index_material */ + +/* -------------------------- GL_EXT_index_texture ------------------------- */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 + +#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) + +#endif /* GL_EXT_index_texture */ + +/* -------------------------- GL_EXT_light_texture ------------------------- */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 + +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 + +typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) +#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) +#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) + +#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) + +#endif /* GL_EXT_light_texture */ + +/* ------------------------- GL_EXT_misc_attribute ------------------------- */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 + +#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) + +#endif /* GL_EXT_misc_attribute */ + +/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const GLvoid **indices, GLsizei primcount); + +#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) +#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) + +#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) + +#endif /* GL_EXT_multi_draw_arrays */ + +/* --------------------------- GL_EXT_multisample -------------------------- */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 + +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); + +#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) +#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) + +#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) + +#endif /* GL_EXT_multisample */ + +/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 + +#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) + +#endif /* GL_EXT_packed_depth_stencil */ + +/* -------------------------- GL_EXT_packed_float -------------------------- */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 + +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C + +#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float) + +#endif /* GL_EXT_packed_float */ + +/* -------------------------- GL_EXT_packed_pixels ------------------------- */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 + +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 + +#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) + +#endif /* GL_EXT_packed_pixels */ + +/* ------------------------ GL_EXT_paletted_texture ------------------------ */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 + +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 +#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); + +#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) +#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) +#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) +#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) + +#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) + +#endif /* GL_EXT_paletted_texture */ + +/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF + +#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) + +#endif /* GL_EXT_pixel_buffer_object */ + +/* ------------------------- GL_EXT_pixel_transform ------------------------ */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 + +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 + +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) +#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) +#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) +#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) +#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) +#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) + +#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) + +#endif /* GL_EXT_pixel_transform */ + +/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 + +#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) + +#endif /* GL_EXT_pixel_transform_color_table */ + +/* ------------------------ GL_EXT_point_parameters ------------------------ */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 + +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat* params); + +#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) +#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) + +#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) + +#endif /* GL_EXT_point_parameters */ + +/* ------------------------- GL_EXT_polygon_offset ------------------------- */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 + +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 + +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); + +#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) + +#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) + +#endif /* GL_EXT_polygon_offset */ + +/* ------------------------ GL_EXT_provoking_vertex ------------------------ */ + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex 1 + +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F + +typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); + +#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT) + +#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex) + +#endif /* GL_EXT_provoking_vertex */ + +/* ------------------------- GL_EXT_rescale_normal ------------------------- */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 + +#define GL_RESCALE_NORMAL_EXT 0x803A + +#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) + +#endif /* GL_EXT_rescale_normal */ + +/* -------------------------- GL_EXT_scene_marker -------------------------- */ + +#ifndef GL_EXT_scene_marker +#define GL_EXT_scene_marker 1 + +typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); + +#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) +#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) + +#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) + +#endif /* GL_EXT_scene_marker */ + +/* ------------------------- GL_EXT_secondary_color ------------------------ */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 + +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E + +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + +#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) +#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) +#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) +#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) +#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) +#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) +#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) +#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) +#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) +#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) +#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) +#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) +#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) +#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) +#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) +#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) +#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) + +#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) + +#endif /* GL_EXT_secondary_color */ + +/* --------------------- GL_EXT_separate_shader_objects -------------------- */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 + +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D + +typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const char* string); +typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); + +#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT) +#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT) +#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT) + +#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects) + +#endif /* GL_EXT_separate_shader_objects */ + +/* --------------------- GL_EXT_separate_specular_color -------------------- */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 + +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA + +#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) + +#endif /* GL_EXT_separate_specular_color */ + +/* --------------------- GL_EXT_shader_image_load_store -------------------- */ + +#ifndef GL_EXT_shader_image_load_store +#define GL_EXT_shader_image_load_store 1 + +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (GLAPIENTRY * PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); + +#define glBindImageTextureEXT GLEW_GET_FUN(__glewBindImageTextureEXT) +#define glMemoryBarrierEXT GLEW_GET_FUN(__glewMemoryBarrierEXT) + +#define GLEW_EXT_shader_image_load_store GLEW_GET_VAR(__GLEW_EXT_shader_image_load_store) + +#endif /* GL_EXT_shader_image_load_store */ + +/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 + +#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) + +#endif /* GL_EXT_shadow_funcs */ + +/* --------------------- GL_EXT_shared_texture_palette --------------------- */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 + +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB + +#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) + +#endif /* GL_EXT_shared_texture_palette */ + +/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 + +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 + +#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) + +#endif /* GL_EXT_stencil_clear_tag */ + +/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 + +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 + +typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); + +#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) + +#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) + +#endif /* GL_EXT_stencil_two_side */ + +/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 + +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 + +#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) + +#endif /* GL_EXT_stencil_wrap */ + +/* --------------------------- GL_EXT_subtexture --------------------------- */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 + +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); + +#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) +#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) +#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) + +#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) + +#endif /* GL_EXT_subtexture */ + +/* ----------------------------- GL_EXT_texture ---------------------------- */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 + +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 + +#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) + +#endif /* GL_EXT_texture */ + +/* ---------------------------- GL_EXT_texture3D --------------------------- */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 + +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); + +#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) + +#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) + +#endif /* GL_EXT_texture3D */ + +/* -------------------------- GL_EXT_texture_array ------------------------- */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 + +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + +#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) + +#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array) + +#endif /* GL_EXT_texture_array */ + +/* ---------------------- GL_EXT_texture_buffer_object --------------------- */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT) + +#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object) + +#endif /* GL_EXT_texture_buffer_object */ + +/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 + +#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) + +#endif /* GL_EXT_texture_compression_dxt1 */ + +/* -------------------- GL_EXT_texture_compression_latc -------------------- */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 + +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 + +#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc) + +#endif /* GL_EXT_texture_compression_latc */ + +/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE + +#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc) + +#endif /* GL_EXT_texture_compression_rgtc */ + +/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) + +#endif /* GL_EXT_texture_compression_s3tc */ + +/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 + +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C + +#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) + +#endif /* GL_EXT_texture_cube_map */ + +/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ + +#ifndef GL_EXT_texture_edge_clamp +#define GL_EXT_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_EXT 0x812F + +#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) + +#endif /* GL_EXT_texture_edge_clamp */ + +/* --------------------------- GL_EXT_texture_env -------------------------- */ + +#ifndef GL_EXT_texture_env +#define GL_EXT_texture_env 1 + +#define GL_TEXTURE_ENV0_EXT 0 +#define GL_ENV_BLEND_EXT 0 +#define GL_TEXTURE_ENV_SHIFT_EXT 0 +#define GL_ENV_REPLACE_EXT 0 +#define GL_ENV_ADD_EXT 0 +#define GL_ENV_SUBTRACT_EXT 0 +#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0 +#define GL_ENV_REVERSE_SUBTRACT_EXT 0 +#define GL_ENV_REVERSE_BLEND_EXT 0 +#define GL_ENV_COPY_EXT 0 +#define GL_ENV_MODULATE_EXT 0 + +#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) + +#endif /* GL_EXT_texture_env */ + +/* ------------------------- GL_EXT_texture_env_add ------------------------ */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 + +#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) + +#endif /* GL_EXT_texture_env_add */ + +/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 + +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A + +#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) + +#endif /* GL_EXT_texture_env_combine */ + +/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 + +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 + +#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) + +#endif /* GL_EXT_texture_env_dot3 */ + +/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 + +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) + +#endif /* GL_EXT_texture_filter_anisotropic */ + +/* ------------------------- GL_EXT_texture_integer ------------------------ */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 + +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E + +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); + +#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT) +#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT) +#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT) +#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT) +#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT) +#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT) + +#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer) + +#endif /* GL_EXT_texture_integer */ + +/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 + +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 + +#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) + +#endif /* GL_EXT_texture_lod_bias */ + +/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 + +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 + +#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) + +#endif /* GL_EXT_texture_mirror_clamp */ + +/* ------------------------- GL_EXT_texture_object ------------------------- */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 + +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A + +typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); + +#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) +#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) +#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) +#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) +#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) +#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) + +#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) + +#endif /* GL_EXT_texture_object */ + +/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 + +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF + +typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); + +#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) + +#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) + +#endif /* GL_EXT_texture_perturb_normal */ + +/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ + +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 + +#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) + +#endif /* GL_EXT_texture_rectangle */ + +/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 + +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F + +#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) + +#endif /* GL_EXT_texture_sRGB */ + +/* ----------------------- GL_EXT_texture_sRGB_decode ---------------------- */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 + +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A + +#define GLEW_EXT_texture_sRGB_decode GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_decode) + +#endif /* GL_EXT_texture_sRGB_decode */ + +/* --------------------- GL_EXT_texture_shared_exponent -------------------- */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 + +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F + +#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent) + +#endif /* GL_EXT_texture_shared_exponent */ + +/* -------------------------- GL_EXT_texture_snorm ------------------------- */ + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm 1 + +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B + +#define GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm) + +#endif /* GL_EXT_texture_snorm */ + +/* ------------------------- GL_EXT_texture_swizzle ------------------------ */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 + +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 + +#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle) + +#endif /* GL_EXT_texture_swizzle */ + +/* --------------------------- GL_EXT_timer_query -------------------------- */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 + +#define GL_TIME_ELAPSED_EXT 0x88BF + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); + +#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT) +#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT) + +#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query) + +#endif /* GL_EXT_timer_query */ + +/* ----------------------- GL_EXT_transform_feedback ----------------------- */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 + +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F + +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, char *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const char ** varyings, GLenum bufferMode); + +#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT) +#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT) +#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT) +#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT) +#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT) +#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT) +#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT) + +#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback) + +#endif /* GL_EXT_transform_feedback */ + +/* -------------------------- GL_EXT_vertex_array -------------------------- */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 + +#define GL_DOUBLE_EXT 0x140A +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 + +typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); + +#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) +#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) +#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) +#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) +#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) +#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) +#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) +#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) + +#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) + +#endif /* GL_EXT_vertex_array */ + +/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra) + +#endif /* GL_EXT_vertex_array_bgra */ + +/* ----------------------- GL_EXT_vertex_attrib_64bit ---------------------- */ + +#ifndef GL_EXT_vertex_attrib_64bit +#define GL_EXT_vertex_attrib_64bit 1 + +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4_EXT 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); + +#define glGetVertexAttribLdvEXT GLEW_GET_FUN(__glewGetVertexAttribLdvEXT) +#define glVertexArrayVertexAttribLOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLOffsetEXT) +#define glVertexAttribL1dEXT GLEW_GET_FUN(__glewVertexAttribL1dEXT) +#define glVertexAttribL1dvEXT GLEW_GET_FUN(__glewVertexAttribL1dvEXT) +#define glVertexAttribL2dEXT GLEW_GET_FUN(__glewVertexAttribL2dEXT) +#define glVertexAttribL2dvEXT GLEW_GET_FUN(__glewVertexAttribL2dvEXT) +#define glVertexAttribL3dEXT GLEW_GET_FUN(__glewVertexAttribL3dEXT) +#define glVertexAttribL3dvEXT GLEW_GET_FUN(__glewVertexAttribL3dvEXT) +#define glVertexAttribL4dEXT GLEW_GET_FUN(__glewVertexAttribL4dEXT) +#define glVertexAttribL4dvEXT GLEW_GET_FUN(__glewVertexAttribL4dvEXT) +#define glVertexAttribLPointerEXT GLEW_GET_FUN(__glewVertexAttribLPointerEXT) + +#define GLEW_EXT_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_EXT_vertex_attrib_64bit) + +#endif /* GL_EXT_vertex_attrib_64bit */ + +/* -------------------------- GL_EXT_vertex_shader ------------------------- */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 + +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED + +typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); +typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid **data); +typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); +typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + +#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) +#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) +#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) +#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) +#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) +#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) +#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) +#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) +#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) +#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) +#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) +#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) +#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) +#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) +#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) +#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) +#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) +#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) +#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) +#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) +#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) +#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) +#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) +#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) +#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) +#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) +#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) +#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) +#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) +#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) +#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) +#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) +#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) +#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) +#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) +#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) +#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) +#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) +#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) +#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) +#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) +#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) + +#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) + +#endif /* GL_EXT_vertex_shader */ + +/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 + +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 + +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); + +#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) +#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) +#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) + +#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) + +#endif /* GL_EXT_vertex_weighting */ + +/* ------------------------- GL_EXT_x11_sync_object ------------------------ */ + +#ifndef GL_EXT_x11_sync_object +#define GL_EXT_x11_sync_object 1 + +#define GL_SYNC_X11_FENCE_EXT 0x90E1 + +typedef GLsync (GLAPIENTRY * PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); + +#define glImportSyncEXT GLEW_GET_FUN(__glewImportSyncEXT) + +#define GLEW_EXT_x11_sync_object GLEW_GET_VAR(__GLEW_EXT_x11_sync_object) + +#endif /* GL_EXT_x11_sync_object */ + +/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 + +typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void); + +#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY) + +#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator) + +#endif /* GL_GREMEDY_frame_terminator */ + +/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 + +typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void* string); + +#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) + +#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) + +#endif /* GL_GREMEDY_string_marker */ + +/* --------------------- GL_HP_convolution_border_modes -------------------- */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 + +#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) + +#endif /* GL_HP_convolution_border_modes */ + +/* ------------------------- GL_HP_image_transform ------------------------- */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 + +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) +#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) +#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) +#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) +#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) +#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) + +#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) + +#endif /* GL_HP_image_transform */ + +/* -------------------------- GL_HP_occlusion_test ------------------------- */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 + +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 + +#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) + +#endif /* GL_HP_occlusion_test */ + +/* ------------------------- GL_HP_texture_lighting ------------------------ */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 + +#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) + +#endif /* GL_HP_texture_lighting */ + +/* --------------------------- GL_IBM_cull_vertex -------------------------- */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 + +#define GL_CULL_VERTEX_IBM 103050 + +#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) + +#endif /* GL_IBM_cull_vertex */ + +/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLsizei primcount, GLint modestride); + +#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) +#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) + +#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) + +#endif /* GL_IBM_multimode_draw_arrays */ + +/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 + +#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 + +#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) + +#endif /* GL_IBM_rasterpos_clip */ + +/* --------------------------- GL_IBM_static_data -------------------------- */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 + +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 + +#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) + +#endif /* GL_IBM_static_data */ + +/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_IBM 0x8370 + +#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) + +#endif /* GL_IBM_texture_mirrored_repeat */ + +/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 + +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); + +#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) +#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) +#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) +#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) +#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) +#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) +#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) +#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) + +#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) + +#endif /* GL_IBM_vertex_array_lists */ + +/* -------------------------- GL_INGR_color_clamp -------------------------- */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 + +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 + +#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) + +#endif /* GL_INGR_color_clamp */ + +/* ------------------------- GL_INGR_interlace_read ------------------------ */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 + +#define GL_INTERLACE_READ_INGR 0x8568 + +#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) + +#endif /* GL_INGR_interlace_read */ + +/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 + +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); + +#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) +#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) +#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) +#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) + +#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) + +#endif /* GL_INTEL_parallel_arrays */ + +/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ + +#ifndef GL_INTEL_texture_scissor +#define GL_INTEL_texture_scissor 1 + +typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); +typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); + +#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) +#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) + +#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) + +#endif /* GL_INTEL_texture_scissor */ + +/* -------------------------- GL_KTX_buffer_region ------------------------- */ + +#ifndef GL_KTX_buffer_region +#define GL_KTX_buffer_region 1 + +#define GL_KTX_FRONT_REGION 0x0 +#define GL_KTX_BACK_REGION 0x1 +#define GL_KTX_Z_REGION 0x2 +#define GL_KTX_STENCIL_REGION 0x3 + +typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); +typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glBufferRegionEnabledEXT GLEW_GET_FUN(__glewBufferRegionEnabledEXT) +#define glDeleteBufferRegionEXT GLEW_GET_FUN(__glewDeleteBufferRegionEXT) +#define glDrawBufferRegionEXT GLEW_GET_FUN(__glewDrawBufferRegionEXT) +#define glNewBufferRegionEXT GLEW_GET_FUN(__glewNewBufferRegionEXT) +#define glReadBufferRegionEXT GLEW_GET_FUN(__glewReadBufferRegionEXT) + +#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) + +#endif /* GL_KTX_buffer_region */ + +/* ------------------------- GL_MESAX_texture_stack ------------------------ */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 + +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E + +#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) + +#endif /* GL_MESAX_texture_stack */ + +/* -------------------------- GL_MESA_pack_invert -------------------------- */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 + +#define GL_PACK_INVERT_MESA 0x8758 + +#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) + +#endif /* GL_MESA_pack_invert */ + +/* ------------------------- GL_MESA_resize_buffers ------------------------ */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 + +typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); + +#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) + +#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) + +#endif /* GL_MESA_resize_buffers */ + +/* --------------------------- GL_MESA_window_pos -------------------------- */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); + +#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) +#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) +#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) +#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) +#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) +#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) +#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) +#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) +#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) +#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) +#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) +#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) +#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) +#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) +#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) +#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) +#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) +#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) +#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) +#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) +#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) +#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) +#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) +#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) + +#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) + +#endif /* GL_MESA_window_pos */ + +/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 + +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 + +#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) + +#endif /* GL_MESA_ycbcr_texture */ + +/* ------------------------- GL_NVX_gpu_memory_info ------------------------ */ + +#ifndef GL_NVX_gpu_memory_info +#define GL_NVX_gpu_memory_info 1 + +#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B + +#define GLEW_NVX_gpu_memory_info GLEW_GET_VAR(__GLEW_NVX_gpu_memory_info) + +#endif /* GL_NVX_gpu_memory_info */ + +/* --------------------------- GL_NV_blend_square -------------------------- */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 + +#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) + +#endif /* GL_NV_blend_square */ + +/* ------------------------ GL_NV_conditional_render ----------------------- */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 + +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void); + +#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV) +#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV) + +#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render) + +#endif /* GL_NV_conditional_render */ + +/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 + +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F + +#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) + +#endif /* GL_NV_copy_depth_to_color */ + +/* ---------------------------- GL_NV_copy_image --------------------------- */ + +#ifndef GL_NV_copy_image +#define GL_NV_copy_image 1 + +typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + +#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV) + +#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image) + +#endif /* GL_NV_copy_image */ + +/* ------------------------ GL_NV_depth_buffer_float ----------------------- */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); + +#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV) +#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV) +#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV) + +#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float) + +#endif /* GL_NV_depth_buffer_float */ + +/* --------------------------- GL_NV_depth_clamp --------------------------- */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 + +#define GL_DEPTH_CLAMP_NV 0x864F + +#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) + +#endif /* GL_NV_depth_clamp */ + +/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */ + +#ifndef GL_NV_depth_range_unclamped +#define GL_NV_depth_range_unclamped 1 + +#define GL_SAMPLE_COUNT_BITS_NV 0x8864 +#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865 +#define GL_QUERY_RESULT_NV 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867 +#define GL_SAMPLE_COUNT_NV 0x8914 + +#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped) + +#endif /* GL_NV_depth_range_unclamped */ + +/* ---------------------------- GL_NV_evaluators --------------------------- */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 + +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 + +typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void* points); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void* points); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) +#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) +#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) +#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) +#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) +#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) +#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) +#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) +#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) + +#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) + +#endif /* GL_NV_evaluators */ + +/* ----------------------- GL_NV_explicit_multisample ---------------------- */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 + +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 + +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); + +#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV) +#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV) +#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV) + +#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample) + +#endif /* GL_NV_explicit_multisample */ + +/* ------------------------------ GL_NV_fence ------------------------------ */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 + +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); +typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); + +#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) +#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) +#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) +#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) +#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) +#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) +#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) + +#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) + +#endif /* GL_NV_fence */ + +/* --------------------------- GL_NV_float_buffer -------------------------- */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 + +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E + +#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) + +#endif /* GL_NV_float_buffer */ + +/* --------------------------- GL_NV_fog_distance -------------------------- */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 + +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C + +#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) + +#endif /* GL_NV_fog_distance */ + +/* ------------------------- GL_NV_fragment_program ------------------------ */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 + +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); + +#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) +#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) +#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) +#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) +#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) +#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) + +#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) + +#endif /* GL_NV_fragment_program */ + +/* ------------------------ GL_NV_fragment_program2 ------------------------ */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 + +#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) + +#endif /* GL_NV_fragment_program2 */ + +/* ------------------------ GL_NV_fragment_program4 ------------------------ */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 + +#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4) + +#endif /* GL_NV_fragment_program4 */ + +/* --------------------- GL_NV_fragment_program_option --------------------- */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 + +#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) + +#endif /* GL_NV_fragment_program_option */ + +/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 + +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV) + +#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage) + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +/* ------------------------ GL_NV_geometry_program4 ------------------------ */ + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 + +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 + +typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); + +#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV) + +#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4) + +#endif /* GL_NV_geometry_program4 */ + +/* ------------------------- GL_NV_geometry_shader4 ------------------------ */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 + +#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4) + +#endif /* GL_NV_geometry_shader4 */ + +/* --------------------------- GL_NV_gpu_program4 -------------------------- */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 + +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); + +#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV) +#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV) +#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV) +#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV) +#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV) +#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV) +#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV) +#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV) +#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV) +#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV) +#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV) +#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV) + +#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4) + +#endif /* GL_NV_gpu_program4 */ + +/* --------------------------- GL_NV_gpu_program5 -------------------------- */ + +#ifndef GL_NV_gpu_program5 +#define GL_NV_gpu_program5 1 + +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F + +#define GLEW_NV_gpu_program5 GLEW_GET_VAR(__GLEW_NV_gpu_program5) + +#endif /* GL_NV_gpu_program5 */ + +/* ------------------------- GL_NV_gpu_program_fp64 ------------------------ */ + +#ifndef GL_NV_gpu_program_fp64 +#define GL_NV_gpu_program_fp64 1 + +#define GLEW_NV_gpu_program_fp64 GLEW_GET_VAR(__GLEW_NV_gpu_program_fp64) + +#endif /* GL_NV_gpu_program_fp64 */ + +/* --------------------------- GL_NV_gpu_shader5 --------------------------- */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 + +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB + +typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetUniformi64vNV GLEW_GET_FUN(__glewGetUniformi64vNV) +#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV) +#define glProgramUniform1i64NV GLEW_GET_FUN(__glewProgramUniform1i64NV) +#define glProgramUniform1i64vNV GLEW_GET_FUN(__glewProgramUniform1i64vNV) +#define glProgramUniform1ui64NV GLEW_GET_FUN(__glewProgramUniform1ui64NV) +#define glProgramUniform1ui64vNV GLEW_GET_FUN(__glewProgramUniform1ui64vNV) +#define glProgramUniform2i64NV GLEW_GET_FUN(__glewProgramUniform2i64NV) +#define glProgramUniform2i64vNV GLEW_GET_FUN(__glewProgramUniform2i64vNV) +#define glProgramUniform2ui64NV GLEW_GET_FUN(__glewProgramUniform2ui64NV) +#define glProgramUniform2ui64vNV GLEW_GET_FUN(__glewProgramUniform2ui64vNV) +#define glProgramUniform3i64NV GLEW_GET_FUN(__glewProgramUniform3i64NV) +#define glProgramUniform3i64vNV GLEW_GET_FUN(__glewProgramUniform3i64vNV) +#define glProgramUniform3ui64NV GLEW_GET_FUN(__glewProgramUniform3ui64NV) +#define glProgramUniform3ui64vNV GLEW_GET_FUN(__glewProgramUniform3ui64vNV) +#define glProgramUniform4i64NV GLEW_GET_FUN(__glewProgramUniform4i64NV) +#define glProgramUniform4i64vNV GLEW_GET_FUN(__glewProgramUniform4i64vNV) +#define glProgramUniform4ui64NV GLEW_GET_FUN(__glewProgramUniform4ui64NV) +#define glProgramUniform4ui64vNV GLEW_GET_FUN(__glewProgramUniform4ui64vNV) +#define glUniform1i64NV GLEW_GET_FUN(__glewUniform1i64NV) +#define glUniform1i64vNV GLEW_GET_FUN(__glewUniform1i64vNV) +#define glUniform1ui64NV GLEW_GET_FUN(__glewUniform1ui64NV) +#define glUniform1ui64vNV GLEW_GET_FUN(__glewUniform1ui64vNV) +#define glUniform2i64NV GLEW_GET_FUN(__glewUniform2i64NV) +#define glUniform2i64vNV GLEW_GET_FUN(__glewUniform2i64vNV) +#define glUniform2ui64NV GLEW_GET_FUN(__glewUniform2ui64NV) +#define glUniform2ui64vNV GLEW_GET_FUN(__glewUniform2ui64vNV) +#define glUniform3i64NV GLEW_GET_FUN(__glewUniform3i64NV) +#define glUniform3i64vNV GLEW_GET_FUN(__glewUniform3i64vNV) +#define glUniform3ui64NV GLEW_GET_FUN(__glewUniform3ui64NV) +#define glUniform3ui64vNV GLEW_GET_FUN(__glewUniform3ui64vNV) +#define glUniform4i64NV GLEW_GET_FUN(__glewUniform4i64NV) +#define glUniform4i64vNV GLEW_GET_FUN(__glewUniform4i64vNV) +#define glUniform4ui64NV GLEW_GET_FUN(__glewUniform4ui64NV) +#define glUniform4ui64vNV GLEW_GET_FUN(__glewUniform4ui64vNV) + +#define GLEW_NV_gpu_shader5 GLEW_GET_VAR(__GLEW_NV_gpu_shader5) + +#endif /* GL_NV_gpu_shader5 */ + +/* ---------------------------- GL_NV_half_float --------------------------- */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 + +#define GL_HALF_FLOAT_NV 0x140B + +typedef unsigned short GLhalf; + +typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); +typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); +typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); + +#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) +#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) +#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) +#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) +#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) +#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) +#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) +#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) +#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) +#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) +#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) +#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) +#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) +#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) +#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) +#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) +#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) +#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) +#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) +#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) +#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) +#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) +#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) +#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) +#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) +#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) +#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) +#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) +#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) +#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) +#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) +#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) +#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) +#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) +#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) +#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) +#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) +#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) +#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) +#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) +#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) +#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) +#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) +#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) +#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) +#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) + +#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) + +#endif /* GL_NV_half_float */ + +/* ------------------------ GL_NV_light_max_exponent ----------------------- */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 + +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 + +#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) + +#endif /* GL_NV_light_max_exponent */ + +/* ----------------------- GL_NV_multisample_coverage ---------------------- */ + +#ifndef GL_NV_multisample_coverage +#define GL_NV_multisample_coverage 1 + +#define GL_COVERAGE_SAMPLES_NV 0x80A9 +#define GL_COLOR_SAMPLES_NV 0x8E20 + +#define GLEW_NV_multisample_coverage GLEW_GET_VAR(__GLEW_NV_multisample_coverage) + +#endif /* GL_NV_multisample_coverage */ + +/* --------------------- GL_NV_multisample_filter_hint --------------------- */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 + +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 + +#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) + +#endif /* GL_NV_multisample_filter_hint */ + +/* ------------------------- GL_NV_occlusion_query ------------------------- */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 + +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 + +typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); + +#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) +#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) +#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) +#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) +#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) +#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) +#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) + +#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) + +#endif /* GL_NV_occlusion_query */ + +/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA + +#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) + +#endif /* GL_NV_packed_depth_stencil */ + +/* --------------------- GL_NV_parameter_buffer_object --------------------- */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 + +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 + +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); + +#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV) +#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV) +#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV) + +#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object) + +#endif /* GL_NV_parameter_buffer_object */ + +/* --------------------- GL_NV_parameter_buffer_object2 -------------------- */ + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 1 + +#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2) + +#endif /* GL_NV_parameter_buffer_object2 */ + +/* ------------------------- GL_NV_pixel_data_range ------------------------ */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 + +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D + +typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void* pointer); + +#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) +#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) + +#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) + +#endif /* GL_NV_pixel_data_range */ + +/* --------------------------- GL_NV_point_sprite -------------------------- */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 + +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); + +#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) +#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) + +#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) + +#endif /* GL_NV_point_sprite */ + +/* -------------------------- GL_NV_present_video -------------------------- */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 + +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B + +typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); + +#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV) +#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV) +#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV) +#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV) +#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV) +#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV) + +#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video) + +#endif /* GL_NV_present_video */ + +/* ------------------------ GL_NV_primitive_restart ------------------------ */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 + +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 + +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); + +#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) +#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) + +#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) + +#endif /* GL_NV_primitive_restart */ + +/* ------------------------ GL_NV_register_combiners ----------------------- */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 + +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 + +typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); + +#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) +#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) +#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) +#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) +#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) +#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) +#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) +#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) +#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) +#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) +#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) +#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) +#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) + +#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) + +#endif /* GL_NV_register_combiners */ + +/* ----------------------- GL_NV_register_combiners2 ----------------------- */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 + +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 + +typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); + +#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) +#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) + +#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) + +#endif /* GL_NV_register_combiners2 */ + +/* ------------------------ GL_NV_shader_buffer_load ----------------------- */ + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load 1 + +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 + +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV) +#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV) +#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV) +#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV) +#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV) +#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV) +#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV) +#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV) +#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV) +#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV) +#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV) +#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV) +#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV) + +#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load) + +#endif /* GL_NV_shader_buffer_load */ + +/* ---------------------- GL_NV_tessellation_program5 ---------------------- */ + +#ifndef GL_NV_tessellation_program5 +#define GL_NV_tessellation_program5 1 + +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 + +#define GLEW_NV_tessellation_program5 GLEW_GET_VAR(__GLEW_NV_tessellation_program5) + +#endif /* GL_NV_tessellation_program5 */ + +/* -------------------------- GL_NV_texgen_emboss -------------------------- */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 + +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F + +#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) + +#endif /* GL_NV_texgen_emboss */ + +/* ------------------------ GL_NV_texgen_reflection ------------------------ */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 + +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 + +#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) + +#endif /* GL_NV_texgen_reflection */ + +/* ------------------------- GL_NV_texture_barrier ------------------------- */ + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 + +typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void); + +#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV) + +#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier) + +#endif /* GL_NV_texture_barrier */ + +/* --------------------- GL_NV_texture_compression_vtc --------------------- */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 + +#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) + +#endif /* GL_NV_texture_compression_vtc */ + +/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 + +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B + +#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) + +#endif /* GL_NV_texture_env_combine4 */ + +/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 + +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F + +#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) + +#endif /* GL_NV_texture_expand_normal */ + +/* ----------------------- GL_NV_texture_multisample ----------------------- */ + +#ifndef GL_NV_texture_multisample +#define GL_NV_texture_multisample 1 + +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); + +#define glTexImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage2DMultisampleCoverageNV) +#define glTexImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage3DMultisampleCoverageNV) +#define glTextureImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage2DMultisampleCoverageNV) +#define glTextureImage2DMultisampleNV GLEW_GET_FUN(__glewTextureImage2DMultisampleNV) +#define glTextureImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage3DMultisampleCoverageNV) +#define glTextureImage3DMultisampleNV GLEW_GET_FUN(__glewTextureImage3DMultisampleNV) + +#define GLEW_NV_texture_multisample GLEW_GET_VAR(__GLEW_NV_texture_multisample) + +#endif /* GL_NV_texture_multisample */ + +/* ------------------------ GL_NV_texture_rectangle ------------------------ */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 + +#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) + +#endif /* GL_NV_texture_rectangle */ + +/* -------------------------- GL_NV_texture_shader ------------------------- */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 + +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F + +#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) + +#endif /* GL_NV_texture_shader */ + +/* ------------------------- GL_NV_texture_shader2 ------------------------- */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 + +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D + +#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) + +#endif /* GL_NV_texture_shader2 */ + +/* ------------------------- GL_NV_texture_shader3 ------------------------- */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 + +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 + +#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) + +#endif /* GL_NV_texture_shader3 */ + +/* ------------------------ GL_NV_transform_feedback ----------------------- */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 + +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F + +typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); + +#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV) +#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV) +#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV) +#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV) +#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV) +#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV) +#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV) +#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV) +#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV) +#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV) +#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV) + +#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback) + +#endif /* GL_NV_transform_feedback */ + +/* ----------------------- GL_NV_transform_feedback2 ----------------------- */ + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 1 + +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 + +typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); + +#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV) +#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV) +#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV) +#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV) +#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV) +#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV) +#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV) + +#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2) + +#endif /* GL_NV_transform_feedback2 */ + +/* -------------------------- GL_NV_vdpau_interop -------------------------- */ + +#ifndef GL_NV_vdpau_interop +#define GL_NV_vdpau_interop 1 + +#define GL_SURFACE_STATE_NV 0x86EB +#define GL_SURFACE_REGISTERED_NV 0x86FD +#define GL_SURFACE_MAPPED_NV 0x8700 +#define GL_WRITE_DISCARD_NV 0x88BE + +typedef GLintptr GLvdpauSurfaceNV; + +typedef void (GLAPIENTRY * PFNGLVDPAUFININVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values); +typedef void (GLAPIENTRY * PFNGLVDPAUINITNVPROC) (const void* vdpDevice, const GLvoid*getProcAddress); +typedef void (GLAPIENTRY * PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (GLAPIENTRY * PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV* surfaces); +typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef void (GLAPIENTRY * PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); +typedef void (GLAPIENTRY * PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV* surfaces); +typedef void (GLAPIENTRY * PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); + +#define glVDPAUFiniNV GLEW_GET_FUN(__glewVDPAUFiniNV) +#define glVDPAUGetSurfaceivNV GLEW_GET_FUN(__glewVDPAUGetSurfaceivNV) +#define glVDPAUInitNV GLEW_GET_FUN(__glewVDPAUInitNV) +#define glVDPAUIsSurfaceNV GLEW_GET_FUN(__glewVDPAUIsSurfaceNV) +#define glVDPAUMapSurfacesNV GLEW_GET_FUN(__glewVDPAUMapSurfacesNV) +#define glVDPAURegisterOutputSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterOutputSurfaceNV) +#define glVDPAURegisterVideoSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterVideoSurfaceNV) +#define glVDPAUSurfaceAccessNV GLEW_GET_FUN(__glewVDPAUSurfaceAccessNV) +#define glVDPAUUnmapSurfacesNV GLEW_GET_FUN(__glewVDPAUUnmapSurfacesNV) +#define glVDPAUUnregisterSurfaceNV GLEW_GET_FUN(__glewVDPAUUnregisterSurfaceNV) + +#define GLEW_NV_vdpau_interop GLEW_GET_VAR(__GLEW_NV_vdpau_interop) + +#endif /* GL_NV_vdpau_interop */ + +/* ------------------------ GL_NV_vertex_array_range ----------------------- */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) +#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) + +#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) + +#endif /* GL_NV_vertex_array_range */ + +/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 + +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 + +#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) + +#endif /* GL_NV_vertex_array_range2 */ + +/* ------------------- GL_NV_vertex_attrib_integer_64bit ------------------- */ + +#ifndef GL_NV_vertex_attrib_integer_64bit +#define GL_NV_vertex_attrib_integer_64bit 1 + +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); + +#define glGetVertexAttribLi64vNV GLEW_GET_FUN(__glewGetVertexAttribLi64vNV) +#define glGetVertexAttribLui64vNV GLEW_GET_FUN(__glewGetVertexAttribLui64vNV) +#define glVertexAttribL1i64NV GLEW_GET_FUN(__glewVertexAttribL1i64NV) +#define glVertexAttribL1i64vNV GLEW_GET_FUN(__glewVertexAttribL1i64vNV) +#define glVertexAttribL1ui64NV GLEW_GET_FUN(__glewVertexAttribL1ui64NV) +#define glVertexAttribL1ui64vNV GLEW_GET_FUN(__glewVertexAttribL1ui64vNV) +#define glVertexAttribL2i64NV GLEW_GET_FUN(__glewVertexAttribL2i64NV) +#define glVertexAttribL2i64vNV GLEW_GET_FUN(__glewVertexAttribL2i64vNV) +#define glVertexAttribL2ui64NV GLEW_GET_FUN(__glewVertexAttribL2ui64NV) +#define glVertexAttribL2ui64vNV GLEW_GET_FUN(__glewVertexAttribL2ui64vNV) +#define glVertexAttribL3i64NV GLEW_GET_FUN(__glewVertexAttribL3i64NV) +#define glVertexAttribL3i64vNV GLEW_GET_FUN(__glewVertexAttribL3i64vNV) +#define glVertexAttribL3ui64NV GLEW_GET_FUN(__glewVertexAttribL3ui64NV) +#define glVertexAttribL3ui64vNV GLEW_GET_FUN(__glewVertexAttribL3ui64vNV) +#define glVertexAttribL4i64NV GLEW_GET_FUN(__glewVertexAttribL4i64NV) +#define glVertexAttribL4i64vNV GLEW_GET_FUN(__glewVertexAttribL4i64vNV) +#define glVertexAttribL4ui64NV GLEW_GET_FUN(__glewVertexAttribL4ui64NV) +#define glVertexAttribL4ui64vNV GLEW_GET_FUN(__glewVertexAttribL4ui64vNV) +#define glVertexAttribLFormatNV GLEW_GET_FUN(__glewVertexAttribLFormatNV) + +#define GLEW_NV_vertex_attrib_integer_64bit GLEW_GET_VAR(__GLEW_NV_vertex_attrib_integer_64bit) + +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */ + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory 1 + +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 +#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 +#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 + +typedef void (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]); +typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); + +#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV) +#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV) +#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV) +#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV) +#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV) +#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV) +#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV) +#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV) +#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV) +#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV) +#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV) +#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV) + +#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory) + +#endif /* GL_NV_vertex_buffer_unified_memory */ + +/* -------------------------- GL_NV_vertex_program ------------------------- */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 + +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F + +typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); + +#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) +#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) +#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) +#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) +#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) +#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) +#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) +#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) +#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) +#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) +#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) +#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) +#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) +#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) +#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) +#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) +#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) +#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) +#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) +#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) +#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) +#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) +#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) +#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) +#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) +#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) +#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) +#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) +#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) +#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) +#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) +#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) +#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) +#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) +#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) +#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) +#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) +#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) +#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) +#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) +#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) +#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) +#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) +#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) +#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) +#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) +#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) +#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) +#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) +#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) +#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) +#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) +#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) +#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) +#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) +#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) +#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) +#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) +#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) +#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) +#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) +#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) +#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) +#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) + +#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) + +#endif /* GL_NV_vertex_program */ + +/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 + +#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) + +#endif /* GL_NV_vertex_program1_1 */ + +/* ------------------------- GL_NV_vertex_program2 ------------------------- */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 + +#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) + +#endif /* GL_NV_vertex_program2 */ + +/* ---------------------- GL_NV_vertex_program2_option --------------------- */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 + +#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) + +#endif /* GL_NV_vertex_program2_option */ + +/* ------------------------- GL_NV_vertex_program3 ------------------------- */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 + +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C + +#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) + +#endif /* GL_NV_vertex_program3 */ + +/* ------------------------- GL_NV_vertex_program4 ------------------------- */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 + +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD + +#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) + +#endif /* GL_NV_vertex_program4 */ + +/* -------------------------- GL_NV_video_capture -------------------------- */ + +#ifndef GL_NV_video_capture +#define GL_NV_video_capture 1 + +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_SUCCESS_NV 0x902F +#define GL_FAILURE_NV 0x9030 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C + +typedef void (GLAPIENTRY * PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint* params); +typedef GLenum (GLAPIENTRY * PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint* sequence_num, GLuint64EXT *capture_time); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint* params); + +#define glBeginVideoCaptureNV GLEW_GET_FUN(__glewBeginVideoCaptureNV) +#define glBindVideoCaptureStreamBufferNV GLEW_GET_FUN(__glewBindVideoCaptureStreamBufferNV) +#define glBindVideoCaptureStreamTextureNV GLEW_GET_FUN(__glewBindVideoCaptureStreamTextureNV) +#define glEndVideoCaptureNV GLEW_GET_FUN(__glewEndVideoCaptureNV) +#define glGetVideoCaptureStreamdvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamdvNV) +#define glGetVideoCaptureStreamfvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamfvNV) +#define glGetVideoCaptureStreamivNV GLEW_GET_FUN(__glewGetVideoCaptureStreamivNV) +#define glGetVideoCaptureivNV GLEW_GET_FUN(__glewGetVideoCaptureivNV) +#define glVideoCaptureNV GLEW_GET_FUN(__glewVideoCaptureNV) +#define glVideoCaptureStreamParameterdvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterdvNV) +#define glVideoCaptureStreamParameterfvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterfvNV) +#define glVideoCaptureStreamParameterivNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterivNV) + +#define GLEW_NV_video_capture GLEW_GET_VAR(__GLEW_NV_video_capture) + +#endif /* GL_NV_video_capture */ + +/* ------------------------ GL_OES_byte_coordinates ------------------------ */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 + +#define GL_BYTE 0x1400 + +#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates) + +#endif /* GL_OES_byte_coordinates */ + +/* ------------------- GL_OES_compressed_paletted_texture ------------------ */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 + +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 + +#define GLEW_OES_compressed_paletted_texture GLEW_GET_VAR(__GLEW_OES_compressed_paletted_texture) + +#endif /* GL_OES_compressed_paletted_texture */ + +/* --------------------------- GL_OES_read_format -------------------------- */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 + +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B + +#define GLEW_OES_read_format GLEW_GET_VAR(__GLEW_OES_read_format) + +#endif /* GL_OES_read_format */ + +/* ------------------------ GL_OES_single_precision ------------------------ */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFOESPROC) (GLclampd depth); +typedef void (GLAPIENTRY * PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); +typedef void (GLAPIENTRY * PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + +#define glClearDepthfOES GLEW_GET_FUN(__glewClearDepthfOES) +#define glClipPlanefOES GLEW_GET_FUN(__glewClipPlanefOES) +#define glDepthRangefOES GLEW_GET_FUN(__glewDepthRangefOES) +#define glFrustumfOES GLEW_GET_FUN(__glewFrustumfOES) +#define glGetClipPlanefOES GLEW_GET_FUN(__glewGetClipPlanefOES) +#define glOrthofOES GLEW_GET_FUN(__glewOrthofOES) + +#define GLEW_OES_single_precision GLEW_GET_VAR(__GLEW_OES_single_precision) + +#endif /* GL_OES_single_precision */ + +/* ---------------------------- GL_OML_interlace --------------------------- */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 + +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 + +#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) + +#endif /* GL_OML_interlace */ + +/* ---------------------------- GL_OML_resample ---------------------------- */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 + +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 + +#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) + +#endif /* GL_OML_resample */ + +/* ---------------------------- GL_OML_subsample --------------------------- */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 + +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 + +#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) + +#endif /* GL_OML_subsample */ + +/* --------------------------- GL_PGI_misc_hints --------------------------- */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 + +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 +#define GL_CONSERVE_MEMORY_HINT_PGI 107005 +#define GL_RECLAIM_MEMORY_HINT_PGI 107006 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 +#define GL_ALWAYS_FAST_HINT_PGI 107020 +#define GL_ALWAYS_SOFT_HINT_PGI 107021 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 +#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 +#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 +#define GL_STRICT_LIGHTING_HINT_PGI 107031 +#define GL_STRICT_SCISSOR_HINT_PGI 107032 +#define GL_FULL_STIPPLE_HINT_PGI 107033 +#define GL_CLIP_NEAR_HINT_PGI 107040 +#define GL_CLIP_FAR_HINT_PGI 107041 +#define GL_WIDE_LINE_HINT_PGI 107042 +#define GL_BACK_NORMALS_HINT_PGI 107043 + +#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) + +#endif /* GL_PGI_misc_hints */ + +/* -------------------------- GL_PGI_vertex_hints -------------------------- */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 + +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_VERTEX_DATA_HINT_PGI 107050 +#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 +#define GL_MATERIAL_SIDE_HINT_PGI 107052 +#define GL_MAX_VERTEX_HINT_PGI 107053 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 + +#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) + +#endif /* GL_PGI_vertex_hints */ + +/* ----------------------- GL_REND_screen_coordinates ---------------------- */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 + +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 + +#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) + +#endif /* GL_REND_screen_coordinates */ + +/* ------------------------------- GL_S3_s3tc ------------------------------ */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 + +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 + +#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) + +#endif /* GL_S3_s3tc */ + +/* -------------------------- GL_SGIS_color_range -------------------------- */ + +#ifndef GL_SGIS_color_range +#define GL_SGIS_color_range 1 + +#define GL_EXTENDED_RANGE_SGIS 0x85A5 +#define GL_MIN_RED_SGIS 0x85A6 +#define GL_MAX_RED_SGIS 0x85A7 +#define GL_MIN_GREEN_SGIS 0x85A8 +#define GL_MAX_GREEN_SGIS 0x85A9 +#define GL_MIN_BLUE_SGIS 0x85AA +#define GL_MAX_BLUE_SGIS 0x85AB +#define GL_MIN_ALPHA_SGIS 0x85AC +#define GL_MAX_ALPHA_SGIS 0x85AD + +#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) + +#endif /* GL_SGIS_color_range */ + +/* ------------------------- GL_SGIS_detail_texture ------------------------ */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 + +typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); + +#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) +#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) + +#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) + +#endif /* GL_SGIS_detail_texture */ + +/* -------------------------- GL_SGIS_fog_function ------------------------- */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 + +typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); + +#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) +#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) + +#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) + +#endif /* GL_SGIS_fog_function */ + +/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 + +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 + +#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) + +#endif /* GL_SGIS_generate_mipmap */ + +/* -------------------------- GL_SGIS_multisample -------------------------- */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 + +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); + +#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) +#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) + +#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) + +#endif /* GL_SGIS_multisample */ + +/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 + +#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) + +#endif /* GL_SGIS_pixel_texture */ + +/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 + +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 + +#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen) + +#endif /* GL_SGIS_point_line_texgen */ + +/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 + +typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); +typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); + +#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) +#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) + +#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) + +#endif /* GL_SGIS_sharpen_texture */ + +/* --------------------------- GL_SGIS_texture4D --------------------------- */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void* pixels); + +#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) +#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) + +#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) + +#endif /* GL_SGIS_texture4D */ + +/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_SGIS 0x812D + +#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) + +#endif /* GL_SGIS_texture_border_clamp */ + +/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_SGIS 0x812F + +#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) + +#endif /* GL_SGIS_texture_edge_clamp */ + +/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 + +typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); +typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); + +#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) +#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) + +#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) + +#endif /* GL_SGIS_texture_filter4 */ + +/* -------------------------- GL_SGIS_texture_lod -------------------------- */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 + +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D + +#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) + +#endif /* GL_SGIS_texture_lod */ + +/* ------------------------- GL_SGIS_texture_select ------------------------ */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 + +#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) + +#endif /* GL_SGIS_texture_select */ + +/* ----------------------------- GL_SGIX_async ----------------------------- */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 + +#define GL_ASYNC_MARKER_SGIX 0x8329 + +typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); +typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); + +#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) +#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) +#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) +#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) +#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) +#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) + +#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) + +#endif /* GL_SGIX_async */ + +/* ------------------------ GL_SGIX_async_histogram ------------------------ */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 + +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D + +#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) + +#endif /* GL_SGIX_async_histogram */ + +/* -------------------------- GL_SGIX_async_pixel -------------------------- */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 + +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 + +#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) + +#endif /* GL_SGIX_async_pixel */ + +/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 + +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 + +#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) + +#endif /* GL_SGIX_blend_alpha_minmax */ + +/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 + +#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) + +#endif /* GL_SGIX_clipmap */ + +/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 + +#define GL_CONVOLUTION_HINT_SGIX 0x8316 + +#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy) + +#endif /* GL_SGIX_convolution_accuracy */ + +/* ------------------------- GL_SGIX_depth_texture ------------------------- */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 + +#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) + +#endif /* GL_SGIX_depth_texture */ + +/* -------------------------- GL_SGIX_flush_raster ------------------------- */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 + +typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); + +#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) + +#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) + +#endif /* GL_SGIX_flush_raster */ + +/* --------------------------- GL_SGIX_fog_offset -------------------------- */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 + +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 + +#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) + +#endif /* GL_SGIX_fog_offset */ + +/* -------------------------- GL_SGIX_fog_texture -------------------------- */ + +#ifndef GL_SGIX_fog_texture +#define GL_SGIX_fog_texture 1 + +#define GL_TEXTURE_FOG_SGIX 0 +#define GL_FOG_PATCHY_FACTOR_SGIX 0 +#define GL_FRAGMENT_FOG_SGIX 0 + +typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); + +#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) + +#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) + +#endif /* GL_SGIX_fog_texture */ + +/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ + +#ifndef GL_SGIX_fragment_specular_lighting +#define GL_SGIX_fragment_specular_lighting 1 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data); + +#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) +#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) +#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) +#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) +#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) +#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) +#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) +#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) +#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) +#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) +#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) +#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) +#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) +#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) +#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) +#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) +#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) + +#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) + +#endif /* GL_SGIX_fragment_specular_lighting */ + +/* --------------------------- GL_SGIX_framezoom --------------------------- */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 + +typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); + +#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) + +#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) + +#endif /* GL_SGIX_framezoom */ + +/* --------------------------- GL_SGIX_interlace --------------------------- */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 + +#define GL_INTERLACE_SGIX 0x8094 + +#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) + +#endif /* GL_SGIX_interlace */ + +/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 + +#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) + +#endif /* GL_SGIX_ir_instrument1 */ + +/* ------------------------- GL_SGIX_list_priority ------------------------- */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 + +#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) + +#endif /* GL_SGIX_list_priority */ + +/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 + +typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); + +#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) + +#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) + +#endif /* GL_SGIX_pixel_texture */ + +/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ + +#ifndef GL_SGIX_pixel_texture_bits +#define GL_SGIX_pixel_texture_bits 1 + +#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) + +#endif /* GL_SGIX_pixel_texture_bits */ + +/* ------------------------ GL_SGIX_reference_plane ------------------------ */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 + +typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); + +#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) + +#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) + +#endif /* GL_SGIX_reference_plane */ + +/* ---------------------------- GL_SGIX_resample --------------------------- */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 + +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 + +#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) + +#endif /* GL_SGIX_resample */ + +/* ----------------------------- GL_SGIX_shadow ---------------------------- */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 + +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D + +#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) + +#endif /* GL_SGIX_shadow */ + +/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 + +#define GL_SHADOW_AMBIENT_SGIX 0x80BF + +#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) + +#endif /* GL_SGIX_shadow_ambient */ + +/* ----------------------------- GL_SGIX_sprite ---------------------------- */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 + +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); + +#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) +#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) +#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) +#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) + +#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) + +#endif /* GL_SGIX_sprite */ + +/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 + +typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); + +#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) + +#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) + +#endif /* GL_SGIX_tag_sample_buffer */ + +/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 + +#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) + +#endif /* GL_SGIX_texture_add_env */ + +/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 + +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B + +#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 + +#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) + +#endif /* GL_SGIX_texture_lod_bias */ + +/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 + +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E + +#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) + +#endif /* GL_SGIX_texture_multi_buffer */ + +/* ------------------------- GL_SGIX_texture_range ------------------------- */ + +#ifndef GL_SGIX_texture_range +#define GL_SGIX_texture_range 1 + +#define GL_RGB_SIGNED_SGIX 0x85E0 +#define GL_RGBA_SIGNED_SGIX 0x85E1 +#define GL_ALPHA_SIGNED_SGIX 0x85E2 +#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 +#define GL_INTENSITY_SIGNED_SGIX 0x85E4 +#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 +#define GL_RGB16_SIGNED_SGIX 0x85E6 +#define GL_RGBA16_SIGNED_SGIX 0x85E7 +#define GL_ALPHA16_SIGNED_SGIX 0x85E8 +#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 +#define GL_INTENSITY16_SIGNED_SGIX 0x85EA +#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB +#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC +#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED +#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE +#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF +#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 +#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 +#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 +#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 +#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 +#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 +#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 +#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 +#define GL_MIN_LUMINANCE_SGIS 0x85F8 +#define GL_MAX_LUMINANCE_SGIS 0x85F9 +#define GL_MIN_INTENSITY_SGIS 0x85FA +#define GL_MAX_INTENSITY_SGIS 0x85FB + +#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) + +#endif /* GL_SGIX_texture_range */ + +/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 + +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C + +#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) + +#endif /* GL_SGIX_texture_scale_bias */ + +/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) + +#endif /* GL_SGIX_vertex_preclip */ + +/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ + +#ifndef GL_SGIX_vertex_preclip_hint +#define GL_SGIX_vertex_preclip_hint 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) + +#endif /* GL_SGIX_vertex_preclip_hint */ + +/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 + +#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) + +#endif /* GL_SGIX_ycrcb */ + +/* -------------------------- GL_SGI_color_matrix -------------------------- */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 + +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB + +#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) + +#endif /* GL_SGI_color_matrix */ + +/* --------------------------- GL_SGI_color_table -------------------------- */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 + +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* table); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void* table); + +#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) +#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) +#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) +#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) +#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) +#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) +#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) + +#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) + +#endif /* GL_SGI_color_table */ + +/* ----------------------- GL_SGI_texture_color_table ---------------------- */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 + +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD + +#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) + +#endif /* GL_SGI_texture_color_table */ + +/* ------------------------- GL_SUNX_constant_data ------------------------- */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 + +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 + +typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); + +#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) + +#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) + +#endif /* GL_SUNX_constant_data */ + +/* -------------------- GL_SUN_convolution_border_modes -------------------- */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 + +#define GL_WRAP_BORDER_SUN 0x81D4 + +#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) + +#endif /* GL_SUN_convolution_border_modes */ + +/* -------------------------- GL_SUN_global_alpha -------------------------- */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 + +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA + +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); + +#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) +#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) +#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) +#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) +#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) +#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) +#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) +#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) + +#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) + +#endif /* GL_SUN_global_alpha */ + +/* --------------------------- GL_SUN_mesh_array --------------------------- */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 + +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 + +#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) + +#endif /* GL_SUN_mesh_array */ + +/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ + +#ifndef GL_SUN_read_video_pixels +#define GL_SUN_read_video_pixels 1 + +typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); + +#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) + +#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) + +#endif /* GL_SUN_read_video_pixels */ + +/* --------------------------- GL_SUN_slice_accum -------------------------- */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 + +#define GL_SLICE_ACCUM_SUN 0x85CC + +#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) + +#endif /* GL_SUN_slice_accum */ + +/* -------------------------- GL_SUN_triangle_list ------------------------- */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 + +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB + +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); + +#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) +#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) +#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) +#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) +#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) +#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) +#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) + +#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) + +#endif /* GL_SUN_triangle_list */ + +/* ----------------------------- GL_SUN_vertex ----------------------------- */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); + +#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) +#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) +#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) +#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) +#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) +#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) +#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) +#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) +#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) +#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) +#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) +#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) +#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) +#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) +#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) +#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) +#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) +#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) +#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) +#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) +#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) +#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) +#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) +#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) +#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) +#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) +#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) +#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) +#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) + +#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) + +#endif /* GL_SUN_vertex */ + +/* -------------------------- GL_WIN_phong_shading ------------------------- */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 + +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB + +#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) + +#endif /* GL_WIN_phong_shading */ + +/* -------------------------- GL_WIN_specular_fog -------------------------- */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 + +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC + +#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) + +#endif /* GL_WIN_specular_fog */ + +/* ---------------------------- GL_WIN_swap_hint --------------------------- */ + +#ifndef GL_WIN_swap_hint +#define GL_WIN_swap_hint 1 + +typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); + +#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) + +#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +#if defined(GLEW_MX) && defined(_WIN32) +#define GLEW_FUN_EXPORT +#else +#define GLEW_FUN_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) +#define GLEW_VAR_EXPORT +#else +#define GLEW_VAR_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) && defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; + +GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; +GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; +GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; +GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; +GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; +GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; +GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; +GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; +GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; +GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; +GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; +GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; + +GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; +GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; +GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; +GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; +GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; +GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; +GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; +GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; +GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; +GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; +GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; +GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; +GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; +GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; +GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; + +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback; +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation; +GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv; +GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski; +GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei; +GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback; +GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation; +GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv; +GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex; +GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v; +GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIPROC __glewBlendEquationi; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIPROC __glewBlendFunci; +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading; + +GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD; + +GLEW_FUN_EXPORT PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD; +GLEW_FUN_EXPORT PFNGLGENNAMESAMDPROC __glewGenNamesAMD; +GLEW_FUN_EXPORT PFNGLISNAMEAMDPROC __glewIsNameAMD; + +GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD; +GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD; + +GLEW_FUN_EXPORT PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD; + +GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD; +GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; +GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; +GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; +GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; + +GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE; + +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; +GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHFPROC __glewClearDepthf; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEFPROC __glewDepthRangef; +GLEW_FUN_EXPORT PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat; +GLEW_FUN_EXPORT PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler; +GLEW_FUN_EXPORT PFNGLSHADERBINARYPROC __glewShaderBinary; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed; +GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex; + +GLEW_FUN_EXPORT PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB; + +GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; + +GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer; +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary; +GLEW_FUN_EXPORT PFNGLPROGRAMBINARYPROC __glewProgramBinary; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMDVPROC __glewGetUniformdv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DEXTPROC __glewProgramUniform1dEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DVEXTPROC __glewProgramUniform1dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DEXTPROC __glewProgramUniform2dEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DVEXTPROC __glewProgramUniform2dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DEXTPROC __glewProgramUniform3dEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DVEXTPROC __glewProgramUniform3dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DEXTPROC __glewProgramUniform4dEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DVEXTPROC __glewProgramUniform4dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC __glewProgramUniformMatrix2dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC __glewProgramUniformMatrix2x3dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC __glewProgramUniformMatrix2x4dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC __glewProgramUniformMatrix3dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC __glewProgramUniformMatrix3x2dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC __glewProgramUniformMatrix3x4dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC __glewProgramUniformMatrix4dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC __glewProgramUniformMatrix4x2dvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC __glewProgramUniformMatrix4x3dvEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1DPROC __glewUniform1d; +GLEW_FUN_EXPORT PFNGLUNIFORM1DVPROC __glewUniform1dv; +GLEW_FUN_EXPORT PFNGLUNIFORM2DPROC __glewUniform2d; +GLEW_FUN_EXPORT PFNGLUNIFORM2DVPROC __glewUniform2dv; +GLEW_FUN_EXPORT PFNGLUNIFORM3DPROC __glewUniform3d; +GLEW_FUN_EXPORT PFNGLUNIFORM3DVPROC __glewUniform3dv; +GLEW_FUN_EXPORT PFNGLUNIFORM4DPROC __glewUniform4d; +GLEW_FUN_EXPORT PFNGLUNIFORM4DVPROC __glewUniform4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; +GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; +GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; +GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; + +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange; +GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange; + +GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; + +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; +GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; +GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; +GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; + +GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex; + +GLEW_FUN_EXPORT PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB; +GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB; +GLEW_FUN_EXPORT PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB; +GLEW_FUN_EXPORT PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB; +GLEW_FUN_EXPORT PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB; +GLEW_FUN_EXPORT PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB; +GLEW_FUN_EXPORT PFNGLGETNMAPIVARBPROC __glewGetnMapivARB; +GLEW_FUN_EXPORT PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB; +GLEW_FUN_EXPORT PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB; +GLEW_FUN_EXPORT PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB; +GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB; +GLEW_FUN_EXPORT PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB; + +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB; + +GLEW_FUN_EXPORT PFNGLBINDSAMPLERPROC __glewBindSampler; +GLEW_FUN_EXPORT PFNGLDELETESAMPLERSPROC __glewDeleteSamplers; +GLEW_FUN_EXPORT PFNGLGENSAMPLERSPROC __glewGenSamplers; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv; +GLEW_FUN_EXPORT PFNGLISSAMPLERPROC __glewIsSampler; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv; + +GLEW_FUN_EXPORT PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines; +GLEW_FUN_EXPORT PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline; + +GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; +GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; +GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; +GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; +GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; +GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; +GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; + +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv; +GLEW_FUN_EXPORT PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv; + +GLEW_FUN_EXPORT PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB; +GLEW_FUN_EXPORT PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB; +GLEW_FUN_EXPORT PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB; +GLEW_FUN_EXPORT PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB; + +GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync; +GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync; +GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync; +GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v; +GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv; +GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync; +GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync; + +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv; +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIPROC __glewPatchParameteri; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; + +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski; +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v; +GLEW_FUN_EXPORT PFNGLQUERYCOUNTERPROC __glewQueryCounter; + +GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream; +GLEW_FUN_EXPORT PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed; +GLEW_FUN_EXPORT PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv; + +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv; +GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; +GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex; +GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices; +GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer; + +GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; +GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; +GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; +GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; +GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; +GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; + +GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; +GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; + +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; + +GLEW_FUN_EXPORT PFNGLCOLORP3UIPROC __glewColorP3ui; +GLEW_FUN_EXPORT PFNGLCOLORP3UIVPROC __glewColorP3uiv; +GLEW_FUN_EXPORT PFNGLCOLORP4UIPROC __glewColorP4ui; +GLEW_FUN_EXPORT PFNGLCOLORP4UIVPROC __glewColorP4uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLNORMALP3UIPROC __glewNormalP3ui; +GLEW_FUN_EXPORT PFNGLNORMALP3UIVPROC __glewNormalP3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIPROC __glewVertexP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIVPROC __glewVertexP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIPROC __glewVertexP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIVPROC __glewVertexP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIPROC __glewVertexP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIVPROC __glewVertexP4uiv; + +GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed; +GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VPROC __glewGetFloati_v; +GLEW_FUN_EXPORT PFNGLSCISSORARRAYVPROC __glewScissorArrayv; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDPROC __glewScissorIndexed; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv; +GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; + +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; + +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; +GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; +GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; +GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; + +GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; + +GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI; +GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI; + +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; + +GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; +GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; +GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; +GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT; +GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT; + +GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; + +GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; +GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; + +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; + +GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; + +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; +GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; + +GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT; +GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT; +GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT; +GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT; + +GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT; +GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; + +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; +GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; +GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; +GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; + +GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; + +GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; + +GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; +GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; + +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; + +GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT; + +GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; +GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; + +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; + +GLEW_FUN_EXPORT PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT; +GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT; + +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT; +GLEW_FUN_EXPORT PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT; + +GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; + +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; + +GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT; + +GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT; +GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT; + +GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; +GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; +GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; +GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; +GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; + +GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT; + +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT; + +GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; +GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; +GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; +GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; +GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT; + +GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; +GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; +GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; +GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; +GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; +GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; +GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; +GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; +GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; +GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; +GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; +GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; + +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; + +GLEW_FUN_EXPORT PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT; + +GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY; + +GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; + +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; + +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; + +GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; +GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; + +GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT; + +GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; + +GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; + +GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; +GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; +GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV; +GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; +GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; +GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; +GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; +GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; +GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; +GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV; + +GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; +GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; + +GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; +GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV; + +GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; +GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV; + +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; +GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; +GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; + +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV; +GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV; + +GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV; + +GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV; +GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV; + +GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV; + +GLEW_FUN_EXPORT PFNGLVDPAUFININVPROC __glewVDPAUFiniNV; +GLEW_FUN_EXPORT PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV; +GLEW_FUN_EXPORT PFNGLVDPAUINITNVPROC __glewVDPAUInitNV; +GLEW_FUN_EXPORT PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV; +GLEW_FUN_EXPORT PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV; +GLEW_FUN_EXPORT PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV; +GLEW_FUN_EXPORT PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV; + +GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV; +GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV; +GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV; +GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV; +GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV; +GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV; + +GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; +GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; +GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; +GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; +GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; +GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; +GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; + +GLEW_FUN_EXPORT PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV; +GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV; +GLEW_FUN_EXPORT PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES; +GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES; +GLEW_FUN_EXPORT PFNGLFRUSTUMFOESPROC __glewFrustumfOES; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES; +GLEW_FUN_EXPORT PFNGLORTHOFOESPROC __glewOrthofOES; + +GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; + +GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; + +GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; +GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; + +GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; +GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; + +GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; + +GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; + +GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; + +GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; + +GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; + +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; + +GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; + +GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; + +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; + +GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; + +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; + +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; + +GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; + +#if defined(GLEW_MX) && !defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_1; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_blend_minmax_factor; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_conservative_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_debug_output; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_depth_clamp_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_name_gen_delete; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sample_positions; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback3_lines_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_object_purgeable; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_program_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES2_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_blend_func_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cl_event; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_debug_output; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_attrib_location; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_program_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sampler_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_separate_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_bit_encoding; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_precision; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_stencil_export; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_subroutine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_include; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_tessellation_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object_rgb32; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_bptc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_gather; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rgb10_a2ui; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_viewport_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_meminfo; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_provoking_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_store; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_decode; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_attrib_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_x11_sync_object; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; +GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; +GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_memory_info; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program_fp64; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vdpau_interop; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_attrib_integer_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_video_capture; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_single_precision; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; + +#ifdef GLEW_MX +}; /* GLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +/* error codes */ +#define GLEW_OK 0 +#define GLEW_NO_ERROR 0 +#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ +#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* Need at least OpenGL 1.1 */ +#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* Need at least GLX 1.2 */ + +/* string codes */ +#define GLEW_VERSION 1 +#define GLEW_VERSION_MAJOR 2 +#define GLEW_VERSION_MINOR 3 +#define GLEW_VERSION_MICRO 4 + +/* API */ +#ifdef GLEW_MX + +typedef struct GLEWContextStruct GLEWContext; +GLEWAPI GLenum glewContextInit (GLEWContext* ctx); +GLEWAPI GLboolean glewContextIsSupported (const GLEWContext* ctx, const char* name); + +#define glewInit() glewContextInit(glewGetContext()) +#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x) +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&(glewGetContext()->x)) +#ifdef _WIN32 +# define GLEW_GET_FUN(x) glewGetContext()->x +#else +# define GLEW_GET_FUN(x) x +#endif + +#else /* GLEW_MX */ + +GLEWAPI GLenum glewInit (); +GLEWAPI GLboolean glewIsSupported (const char* name); +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define GLEW_GET_FUN(x) x + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean glewExperimental; +GLEWAPI GLboolean glewGetExtension (const char* name); +GLEWAPI const GLubyte* glewGetErrorString (GLenum error); +GLEWAPI const GLubyte* glewGetString (GLenum name); + +#ifdef __cplusplus +} +#endif + +#ifdef GLEW_APIENTRY_DEFINED +#undef GLEW_APIENTRY_DEFINED +#undef APIENTRY +#undef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifdef GLEW_CALLBACK_DEFINED +#undef GLEW_CALLBACK_DEFINED +#undef CALLBACK +#endif + +#ifdef GLEW_WINGDIAPI_DEFINED +#undef GLEW_WINGDIAPI_DEFINED +#undef WINGDIAPI +#endif + +#undef GLAPI +/* #undef GLEWAPI */ + +#endif /* __glew_h__ */ diff --git a/Glut/GL/glext.h b/Glut/GL/glext.h new file mode 100644 index 0000000..10c2bc0 --- /dev/null +++ b/Glut/GL/glext.h @@ -0,0 +1,3326 @@ +#ifndef __glext_h_ +#define __glext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright 1998, 1999, 2000, 2001, NVIDIA Corporation. +** All rights Reserved. +** +** THE INFORMATION CONTAINED HEREIN IS PROPRIETARY AND CONFIDENTIAL TO +** NVIDIA, CORPORATION. USE, REPRODUCTION OR DISCLOSURE TO ANY THIRD PARTY +** IS SUBJECT TO WRITTEN PRE-APPROVAL BY NVIDIA, CORPORATION. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +#define GL_GLEXT_VERSION 6 + +#ifndef GL_VERSION_1_2 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#endif + +#ifndef GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#endif + +#ifndef GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_BUM_SGIX 0x8139 +#define GL_PIXEL_TEX_BUM_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_EXT_misc_attribute +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_EXT_blend_logic_op +#endif + +#ifndef GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_INGR_palette_buffer +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_texture +#endif + +#ifndef GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +/* reuse GL_FRAGMENT_DEPTH_EXT */ +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_INTEL_texture_scissor +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE3_RGB_EXT 0x8583 +#define GL_SOURCE4_RGB_EXT 0x8584 +#define GL_SOURCE5_RGB_EXT 0x8585 +#define GL_SOURCE6_RGB_EXT 0x8586 +#define GL_SOURCE7_RGB_EXT 0x8587 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_SOURCE3_ALPHA_EXT 0x858B +#define GL_SOURCE4_ALPHA_EXT 0x858C +#define GL_SOURCE5_ALPHA_EXT 0x858D +#define GL_SOURCE6_ALPHA_EXT 0x858E +#define GL_SOURCE7_ALPHA_EXT 0x858F +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND3_RGB_EXT 0x8593 +#define GL_OPERAND4_RGB_EXT 0x8594 +#define GL_OPERAND5_RGB_EXT 0x8595 +#define GL_OPERAND6_RGB_EXT 0x8596 +#define GL_OPERAND7_RGB_EXT 0x8597 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#define GL_OPERAND3_ALPHA_EXT 0x859B +#define GL_OPERAND4_ALPHA_EXT 0x859C +#define GL_OPERAND5_ALPHA_EXT 0x859D +#define GL_OPERAND6_ALPHA_EXT 0x859E +#define GL_OPERAND7_ALPHA_EXT 0x859F +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_env_add +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW_MATRIX1_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* reuse GL_TEXTURE0_ARB */ +/* reuse GL_TEXTURE1_ARB */ +/* reuse GL_ZERO */ +/* reuse GL_NONE */ +/* reuse GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* reuse GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_blend_square +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + + +#ifndef GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#endif + +#ifndef GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif + + +/*************************************************************/ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +extern void APIENTRY glBlendEquation (GLenum); +extern void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +extern void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); +extern void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); +extern void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); +extern void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +extern void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +extern void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); +extern void APIENTRY glMinmax (GLenum, GLenum, GLboolean); +extern void APIENTRY glResetHistogram (GLenum); +extern void APIENTRY glResetMinmax (GLenum); +extern void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (APIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glActiveTextureARB (GLenum); +extern void APIENTRY glClientActiveTextureARB (GLenum); +extern void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); +extern void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); +extern void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); +extern void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); +extern void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); +extern void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); +extern void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +extern void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); +extern void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); +extern void APIENTRY glSamplePassARB (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPASSARBPROC) (GLenum pass); +#endif + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, void *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); +#endif + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); +extern void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +extern void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +extern void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); +extern void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); +extern void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); +extern void APIENTRY glResetHistogramEXT (GLenum); +extern void APIENTRY glResetMinmaxEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); +extern void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); +extern void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +extern void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +#endif + +#ifndef GL_EXT_color_matrix +#define GL_EXT_color_matrix 1 +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTexGenSGIX (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); +extern void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); +extern void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); +extern void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); +extern void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); +extern void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); +extern void APIENTRY glBindTextureEXT (GLenum, GLuint); +extern void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); +extern void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); +extern GLboolean APIENTRY glIsTextureEXT (GLuint); +extern void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); +extern void APIENTRY glSamplePatternSGIS (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glArrayElementEXT (GLint); +extern void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); +extern void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); +extern void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); +extern void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); +typedef void (APIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendEquationEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#endif + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#endif + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); +extern void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); +extern void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); +extern void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPointParameterfEXT (GLenum, GLfloat); +extern void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); +extern void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); +extern void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLint APIENTRY glGetInstrumentsSGIX (void); +extern void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); +extern GLint APIENTRY glPollInstrumentsSGIX (GLint *); +extern void APIENTRY glReadInstrumentsSGIX (GLint); +extern void APIENTRY glStartInstrumentsSGIX (void); +extern void APIENTRY glStopInstrumentsSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLint (APIENTRY * PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRY * PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRY * PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRY * PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRY * PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRY * PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFrameZoomSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTagSampleBufferSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glReferencePlaneSGIX (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFlushRasterSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); +extern void APIENTRY glGetFogFuncSGIS (const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETFOGFUNCSGISPROC) (const GLfloat *points); +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); +extern void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); +extern void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); +extern void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); +extern void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glHintPGI (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); +extern void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); +extern void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); +extern void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); +extern void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#endif + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIndexMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIndexFuncEXT (GLenum, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glLockArraysEXT (GLint, GLsizei); +extern void APIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); +extern void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); +extern void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); +extern void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); +extern void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); +extern void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); +extern void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); +extern void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); +extern void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); +extern void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); +extern void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); +extern void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); +extern void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); +extern void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); +extern void APIENTRY glLightEnviSGIX (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glApplyTextureEXT (GLenum); +extern void APIENTRY glTextureLightEXT (GLenum); +extern void APIENTRY glTextureMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); +extern void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); +extern void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); +extern void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); +extern void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); +extern void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); +extern void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); +extern void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); +extern void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); +extern void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); +extern void APIENTRY glSecondaryColor3ivEXT (const GLint *); +extern void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glSecondaryColor3svEXT (const GLshort *); +extern void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); +extern void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); +extern void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); +extern void APIENTRY glSecondaryColor3uivEXT (const GLuint *); +extern void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); +extern void APIENTRY glSecondaryColor3usvEXT (const GLushort *); +extern void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTextureNormalEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +extern void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFogCoordfEXT (GLfloat); +extern void APIENTRY glFogCoordfvEXT (const GLfloat *); +extern void APIENTRY glFogCoorddEXT (GLdouble); +extern void APIENTRY glFogCoorddvEXT (const GLdouble *); +extern void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glTangent3bvEXT (const GLbyte *); +extern void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glTangent3dvEXT (const GLdouble *); +extern void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTangent3fvEXT (const GLfloat *); +extern void APIENTRY glTangent3iEXT (GLint, GLint, GLint); +extern void APIENTRY glTangent3ivEXT (const GLint *); +extern void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glTangent3svEXT (const GLshort *); +extern void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glBinormal3bvEXT (const GLbyte *); +extern void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glBinormal3dvEXT (const GLdouble *); +extern void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glBinormal3fvEXT (const GLfloat *); +extern void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); +extern void APIENTRY glBinormal3ivEXT (const GLint *); +extern void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glBinormal3svEXT (const GLshort *); +extern void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRY * PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRY * PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRY * PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRY * PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRY * PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRY * PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRY * PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRY * PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRY * PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRY * PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFinishTextureSUNX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); +extern void APIENTRY glGlobalAlphaFactorsSUN (GLshort); +extern void APIENTRY glGlobalAlphaFactoriSUN (GLint); +extern void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); +extern void APIENTRY glGlobalAlphaFactordSUN (GLdouble); +extern void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); +extern void APIENTRY glGlobalAlphaFactorusSUN (GLushort); +extern void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glReplacementCodeuiSUN (GLuint); +extern void APIENTRY glReplacementCodeusSUN (GLushort); +extern void APIENTRY glReplacementCodeubSUN (GLubyte); +extern void APIENTRY glReplacementCodeuivSUN (const GLuint *); +extern void APIENTRY glReplacementCodeusvSUN (const GLushort *); +extern void APIENTRY glReplacementCodeubvSUN (const GLubyte *); +extern void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); +extern void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); +extern void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); +extern void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLenum *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLenum, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLenum *, const GLubyte *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLenum rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLenum rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLenum *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLenum rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#endif + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexWeightfEXT (GLfloat); +extern void APIENTRY glVertexWeightfvEXT (const GLfloat *); +extern void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFlushVertexArrayRangeNV (void); +extern void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei size, const GLvoid *pointer); +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +extern void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); +extern void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); +extern void APIENTRY glCombinerParameteriNV (GLenum, GLint); +extern void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +extern void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); +extern void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); +extern void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#endif + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glResizeBuffersMESA (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); +extern void APIENTRY glWindowPos2dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); +extern void APIENTRY glWindowPos2fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos2iMESA (GLint, GLint); +extern void APIENTRY glWindowPos2ivMESA (const GLint *); +extern void APIENTRY glWindowPos2sMESA (GLshort, GLshort); +extern void APIENTRY glWindowPos2svMESA (const GLshort *); +extern void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos3dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos3fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); +extern void APIENTRY glWindowPos3ivMESA (const GLint *); +extern void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos3svMESA (const GLshort *); +extern void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos4dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos4fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); +extern void APIENTRY glWindowPos4ivMESA (const GLint *); +extern void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos4svMESA (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glMultiModeDrawArraysIBM (GLenum, const GLint *, const GLsizei *, GLsizei, GLint); +extern void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* *, GLsizei, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, GLint modestride); +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); +extern void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTbufferMask3DFX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); +extern void APIENTRY glSamplePatternEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#endif + +#ifndef GL_SGI_vertex_preclip +#define GL_SGI_vertex_preclip 1 +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif + + + +/* added by Cass -- this part will be auto-generated in the future*/ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#endif + +/* Extensions */ +#define GL_ARB_texture_border_clamp 1 +#define GL_ARB_texture_env_combine 1 +#define GL_ARB_texture_env_dot3 1 +#define GL_EXT_texture_env_dot3 1 +#define GL_IBM_texture_mirrored_repeat 1 +#define GL_NV_evaluators 1 +#define GL_NV_fence 1 +#define GL_NV_multisample_filter_hint 1 +#define GL_NV_packed_depth_stencil 1 +#define GL_NV_register_combiners2 1 +#define GL_NV_texture_compression_vtc 1 +#define GL_NV_texture_rectangle 1 +#define GL_NV_texture_shader 1 +#define GL_NV_texture_shader2 1 +#define GL_NV_vertex_program 1 +#define GL_NV_point_sprite 1 +#define GL_NV_occlusion_query 1 + +/* ARB_texture_border_clamp */ +#define GL_CLAMP_TO_BORDER_ARB 0x812D + +/* ARB_texture_env_combine */ +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_SUBTRACT_ARB 0x84E7 + +/* ARB_texture_env_dot3 */ +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF + +/* EXT_texture_env_dot3 */ +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 + +/* IBM_texture_mirrored_repeat */ +#define GL_MIRRORED_REPEAT_IBM 0x8370 + +/* NV_vertex_program */ +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F + +/* NV_evaluators */ +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 + +/* NV_fence */ +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +/* NV_occlusion_query */ +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 + +/* NV_point_sprite */ +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 + +/* NV_texture_rectangle */ +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 + +/* NV_texture_shader */ +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_ISOTROPIC_BRDF_NV 0x86EB +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F + +/* NV_texture_shader2 */ +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF + +/* NV_register_combiners2 */ +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 + +/* NV_packed_depth_stencil */ +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA + +/* NV_multisample_filter_hint */ +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 + +/* NV_texture_compression_vtc */ + +/* NV_vertex_program */ +typedef GLboolean (APIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); + +/* NV_evaluators */ +typedef void (APIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); +typedef void (APIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); +typedef void (APIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); + +/* NV_fence */ +typedef void (APIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); + +/* NV_occlusion_query */ +typedef void (APIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (GLvoid); +typedef void (APIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); + +/* NV_point_sprite */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, int param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const int *params); + +/* NV_register_combiners2 */ +typedef void (APIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Glut/GL/glut.h b/Glut/GL/glut.h new file mode 100644 index 0000000..612f332 --- /dev/null +++ b/Glut/GL/glut.h @@ -0,0 +1,607 @@ +#ifndef __glut_h__ +#define __glut_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#if defined(_WIN32) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# define WINGDIAPI __declspec(dllimport) +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +/* MinGW32 chokes on the next line */ +#ifndef __MINGW32__ +typedef unsigned short int wchar_t; +#endif //__MINGW32__ +# define _WCHAR_T_DEFINED +# endif +# endif + +#pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +#pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +#pragma comment (lib, "glu32.lib") /* link with OpenGL Utility lib */ + +#ifdef _WIN64 +#pragma message("Note: including lib: glut64.lib\n") +#pragma comment (lib, "glut64.lib") /* link with Win32 GLUT lib */ +#else +#pragma message("Note: including lib: glut32.lib\n") +#pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ +#endif + +#pragma warning (disable:4244) /* Disable bogus conversion warnings. */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ + +#endif + +#include +#include + +/* define APIENTRY and CALLBACK to null string if we aren't on Win32 */ +#if !defined(_WIN32) +#define APIENTRY +#define GLUT_APIENTRY_DEFINED +#define CALLBACK +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + GLUT API revision history: + + GLUT_API_VERSION is updated to reflect incompatible GLUT + API changes (interface changes, semantic changes, deletions, + or additions). + + GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 + + GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, + extension. Supports new input devices like tablet, dial and button + box, and Spaceball. Easy to query OpenGL extensions. + + GLUT_API_VERSION=3 glutMenuStatus added. + + GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, + glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic + video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, + glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, + glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). +**/ +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +//#define GLUT_API_VERSION 3 +#define GLUT_API_VERSION 4 +#endif + +/** + GLUT implementation revision history: + + GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT + API revisions and implementation revisions (ie, bug fixes). + + GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of + GLUT Xlib-based implementation. 11/29/94 + + GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of + GLUT Xlib-based implementation providing GLUT version 2 + interfaces. + + GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 + + GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 + + GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 + + GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 + + GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner + and video resize. 1/3/97 + + GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. + + GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. + + GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. + + GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 release with GameGLUT support. +**/ +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 13 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +/* Layers for use. */ +#define GLUT_NORMAL 0 +#define GLUT_OVERLAY 1 + +#if defined(_WIN32) +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +extern void *glutStrokeRoman; +extern void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +extern void *glutBitmap9By15; +extern void *glutBitmap8By13; +extern void *glutBitmapTimesRoman10; +extern void *glutBitmapTimesRoman24; +extern void *glutBitmapHelvetica10; +extern void *glutBitmapHelvetica12; +extern void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X 100 +#define GLUT_WINDOW_Y 101 +#define GLUT_WINDOW_WIDTH 102 +#define GLUT_WINDOW_HEIGHT 103 +#define GLUT_WINDOW_BUFFER_SIZE 104 +#define GLUT_WINDOW_STENCIL_SIZE 105 +#define GLUT_WINDOW_DEPTH_SIZE 106 +#define GLUT_WINDOW_RED_SIZE 107 +#define GLUT_WINDOW_GREEN_SIZE 108 +#define GLUT_WINDOW_BLUE_SIZE 109 +#define GLUT_WINDOW_ALPHA_SIZE 110 +#define GLUT_WINDOW_ACCUM_RED_SIZE 111 +#define GLUT_WINDOW_ACCUM_GREEN_SIZE 112 +#define GLUT_WINDOW_ACCUM_BLUE_SIZE 113 +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 114 +#define GLUT_WINDOW_DOUBLEBUFFER 115 +#define GLUT_WINDOW_RGBA 116 +#define GLUT_WINDOW_PARENT 117 +#define GLUT_WINDOW_NUM_CHILDREN 118 +#define GLUT_WINDOW_COLORMAP_SIZE 119 +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES 120 +#define GLUT_WINDOW_STEREO 121 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR 122 +#endif +#define GLUT_SCREEN_WIDTH 200 +#define GLUT_SCREEN_HEIGHT 201 +#define GLUT_SCREEN_WIDTH_MM 202 +#define GLUT_SCREEN_HEIGHT_MM 203 +#define GLUT_MENU_NUM_ITEMS 300 +#define GLUT_DISPLAY_MODE_POSSIBLE 400 +#define GLUT_INIT_WINDOW_X 500 +#define GLUT_INIT_WINDOW_Y 501 +#define GLUT_INIT_WINDOW_WIDTH 502 +#define GLUT_INIT_WINDOW_HEIGHT 503 +#define GLUT_INIT_DISPLAY_MODE 504 +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME 700 +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID 123 +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD 600 +#define GLUT_HAS_MOUSE 601 +#define GLUT_HAS_SPACEBALL 602 +#define GLUT_HAS_DIAL_AND_BUTTON_BOX 603 +#define GLUT_HAS_TABLET 604 +#define GLUT_NUM_MOUSE_BUTTONS 605 +#define GLUT_NUM_SPACEBALL_BUTTONS 606 +#define GLUT_NUM_BUTTON_BOX_BUTTONS 607 +#define GLUT_NUM_DIALS 608 +#define GLUT_NUM_TABLET_BUTTONS 609 +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT 610 +#define GLUT_DEVICE_KEY_REPEAT 611 +#define GLUT_HAS_JOYSTICK 612 +#define GLUT_OWNS_JOYSTICK 613 +#define GLUT_JOYSTICK_BUTTONS 614 +#define GLUT_JOYSTICK_AXES 615 +#define GLUT_JOYSTICK_POLL_RATE 616 +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE 800 +#define GLUT_LAYER_IN_USE 801 +#define GLUT_HAS_OVERLAY 802 +#define GLUT_TRANSPARENT_INDEX 803 +#define GLUT_NORMAL_DAMAGED 804 +#define GLUT_OVERLAY_DAMAGED 805 + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE 900 +#define GLUT_VIDEO_RESIZE_IN_USE 901 +#define GLUT_VIDEO_RESIZE_X_DELTA 902 +#define GLUT_VIDEO_RESIZE_Y_DELTA 903 +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904 +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905 +#define GLUT_VIDEO_RESIZE_X 906 +#define GLUT_VIDEO_RESIZE_Y 907 +#define GLUT_VIDEO_RESIZE_WIDTH 908 +#define GLUT_VIDEO_RESIZE_HEIGHT 909 +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL 0 +#define GLUT_OVERLAY 1 + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +/* GLUT initialization sub-API. */ +extern void APIENTRY glutInit(int *argcp, char **argv); +extern void APIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutInitDisplayString(const char *string); +#endif +extern void APIENTRY glutInitWindowPosition(int x, int y); +extern void APIENTRY glutInitWindowSize(int width, int height); +extern void APIENTRY glutMainLoop(void); + +/* GLUT window sub-API. */ +extern int APIENTRY glutCreateWindow(const char *title); +extern int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); +extern void APIENTRY glutDestroyWindow(int win); +extern void APIENTRY glutPostRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +extern void APIENTRY glutPostWindowRedisplay(int win); +#endif +extern void APIENTRY glutSwapBuffers(void); +extern int APIENTRY glutGetWindow(void); +extern void APIENTRY glutSetWindow(int win); +extern void APIENTRY glutSetWindowTitle(const char *title); +extern void APIENTRY glutSetIconTitle(const char *title); +extern void APIENTRY glutPositionWindow(int x, int y); +extern void APIENTRY glutReshapeWindow(int width, int height); +extern void APIENTRY glutPopWindow(void); +extern void APIENTRY glutPushWindow(void); +extern void APIENTRY glutIconifyWindow(void); +extern void APIENTRY glutShowWindow(void); +extern void APIENTRY glutHideWindow(void); +#if (GLUT_API_VERSION >= 3) +extern void APIENTRY glutFullScreen(void); +extern void APIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutWarpPointer(int x, int y); +#endif + +/* GLUT overlay sub-API. */ +extern void APIENTRY glutEstablishOverlay(void); +extern void APIENTRY glutRemoveOverlay(void); +extern void APIENTRY glutUseLayer(GLenum layer); +extern void APIENTRY glutPostOverlayRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +extern void APIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +extern void APIENTRY glutShowOverlay(void); +extern void APIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +extern int APIENTRY glutCreateMenu(void (*)(int)); +extern void APIENTRY glutDestroyMenu(int menu); +extern int APIENTRY glutGetMenu(void); +extern void APIENTRY glutSetMenu(int menu); +extern void APIENTRY glutAddMenuEntry(const char *label, int value); +extern void APIENTRY glutAddSubMenu(const char *label, int submenu); +extern void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); +extern void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); +extern void APIENTRY glutRemoveMenuItem(int item); +extern void APIENTRY glutAttachMenu(int button); +extern void APIENTRY glutDetachMenu(int button); + +/* GLUT window callback sub-API. */ +extern void APIENTRY glutDisplayFunc(void (*func)(void)); +extern void APIENTRY glutReshapeFunc(void (*func)(int width, int height)); +extern void APIENTRY glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)); +extern void APIENTRY glutMouseFunc(void (*func)(int button, int state, int x, int y)); +extern void APIENTRY glutMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutPassiveMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutEntryFunc(void (*func)(int state)); +extern void APIENTRY glutVisibilityFunc(void (*func)(int state)); +extern void APIENTRY glutIdleFunc(void (*func)(void)); +extern void APIENTRY glutTimerFunc(unsigned int millis, void (*func)(int value), int value); +extern void APIENTRY glutMenuStateFunc(void (*func)(int state)); +#if (GLUT_API_VERSION >= 2) +extern void APIENTRY glutSpecialFunc(void (*func)(int key, int x, int y)); +extern void APIENTRY glutSpaceballMotionFunc(void (*func)(int x, int y, int z)); +extern void APIENTRY glutSpaceballRotateFunc(void (*func)(int x, int y, int z)); +extern void APIENTRY glutSpaceballButtonFunc(void (*func)(int button, int state)); +extern void APIENTRY glutButtonBoxFunc(void (*func)(int button, int state)); +extern void APIENTRY glutDialsFunc(void (*func)(int dial, int value)); +extern void APIENTRY glutTabletMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutTabletButtonFunc(void (*func)(int button, int state, int x, int y)); +#if (GLUT_API_VERSION >= 3) +extern void APIENTRY glutMenuStatusFunc(void (*func)(int status, int x, int y)); +extern void APIENTRY glutOverlayDisplayFunc(void (*func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutWindowStatusFunc(void (*func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +extern void APIENTRY glutKeyboardUpFunc(void (*func)(unsigned char key, int x, int y)); +extern void APIENTRY glutSpecialUpFunc(void (*func)(int key, int x, int y)); +extern void APIENTRY glutJoystickFunc(void (*func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +extern void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); +extern GLfloat APIENTRY glutGetColor(int ndx, int component); +extern void APIENTRY glutCopyColormap(int win); + +/* GLUT state retrieval sub-API. */ +extern int APIENTRY glutGet(GLenum type); +extern int APIENTRY glutDeviceGet(GLenum type); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +extern int APIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +extern int APIENTRY glutGetModifiers(void); +extern int APIENTRY glutLayerGet(GLenum type); +#endif + +/* GLUT font sub-API */ +extern void APIENTRY glutBitmapCharacter(void *font, int character); +extern int APIENTRY glutBitmapWidth(void *font, int character); +extern void APIENTRY glutStrokeCharacter(void *font, int character); +extern int APIENTRY glutStrokeWidth(void *font, int character); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern int APIENTRY glutBitmapLength(void *font, const unsigned char *string); +extern int APIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif + +/* GLUT pre-built models sub-API */ +extern void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +extern void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +extern void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +extern void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +extern void APIENTRY glutWireCube(GLdouble size); +extern void APIENTRY glutSolidCube(GLdouble size); +extern void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +extern void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +extern void APIENTRY glutWireDodecahedron(void); +extern void APIENTRY glutSolidDodecahedron(void); +extern void APIENTRY glutWireTeapot(GLdouble size); +extern void APIENTRY glutSolidTeapot(GLdouble size); +extern void APIENTRY glutWireOctahedron(void); +extern void APIENTRY glutSolidOctahedron(void); +extern void APIENTRY glutWireTetrahedron(void); +extern void APIENTRY glutSolidTetrahedron(void); +extern void APIENTRY glutWireIcosahedron(void); +extern void APIENTRY glutSolidIcosahedron(void); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +extern int APIENTRY glutVideoResizeGet(GLenum param); +extern void APIENTRY glutSetupVideoResizing(void); +extern void APIENTRY glutStopVideoResizing(void); +extern void APIENTRY glutVideoResize(int x, int y, int width, int height); +extern void APIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +extern void APIENTRY glutReportErrors(void); +#endif + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +/* GLUT device control sub-API. */ +/* glutSetKeyRepeat modes. */ +#define GLUT_KEY_REPEAT_OFF 0 +#define GLUT_KEY_REPEAT_ON 1 +#define GLUT_KEY_REPEAT_DEFAULT 2 + +/* Joystick button masks. */ +#define GLUT_JOYSTICK_BUTTON_A 1 +#define GLUT_JOYSTICK_BUTTON_B 2 +#define GLUT_JOYSTICK_BUTTON_C 4 +#define GLUT_JOYSTICK_BUTTON_D 8 + +extern void APIENTRY glutIgnoreKeyRepeat(int ignore); +extern void APIENTRY glutSetKeyRepeat(int repeatMode); +extern void APIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE 0 +#define GLUT_GAME_MODE_POSSIBLE 1 +#define GLUT_GAME_MODE_WIDTH 2 +#define GLUT_GAME_MODE_HEIGHT 3 +#define GLUT_GAME_MODE_PIXEL_DEPTH 4 +#define GLUT_GAME_MODE_REFRESH_RATE 5 +#define GLUT_GAME_MODE_DISPLAY_CHANGED 6 + +extern void APIENTRY glutGameModeString(const char *string); +extern int APIENTRY glutEnterGameMode(void); +extern void APIENTRY glutLeaveGameMode(void); +extern int APIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#ifdef GLUT_APIENTRY_DEFINED +# undef GLUT_APIENTRY_DEFINED +# undef APIENTRY +#endif + +#ifdef GLUT_WINGDIAPI_DEFINED +# undef GLUT_WINGDIAPI_DEFINED +# undef WINGDIAPI +#endif + +#endif /* __glut_h__ */ diff --git a/Glut/GL/glxew.h b/Glut/GL/glxew.h new file mode 100644 index 0000000..6d249f7 --- /dev/null +++ b/Glut/GL/glxew.h @@ -0,0 +1,1587 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __glxew_h__ +#define __glxew_h__ +#define __GLXEW_H__ + +#ifdef __glxext_h_ +#error glxext.h included before glxew.h +#endif + +#if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__) +#error glx.h included before glxew.h +#endif + +#define __glxext_h_ + +#define GLX_H +#define __GLX_glx_h__ +#define __glx_h__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ + +#ifndef GLX_VERSION_1_0 +#define GLX_VERSION_1_0 1 + +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +typedef XID GLXDrawable; +typedef XID GLXPixmap; +#ifdef __sun +typedef struct __glXContextRec *GLXContext; +#else +typedef struct __GLXcontextRec *GLXContext; +#endif + +typedef unsigned int GLXVideoDeviceNV; + +extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); +extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); +extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); +extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); +extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); +extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); +extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +extern void glXDestroyContext (Display *dpy, GLXContext ctx); +extern Bool glXIsDirect (Display *dpy, GLXContext ctx); +extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); +extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); +extern GLXContext glXGetCurrentContext (void); +extern GLXDrawable glXGetCurrentDrawable (void); +extern void glXWaitGL (void); +extern void glXWaitX (void); +extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); +extern void glXUseXFont (Font font, int first, int count, int listBase); + +#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) + +#endif /* GLX_VERSION_1_0 */ + +/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ + +#ifndef GLX_VERSION_1_1 +#define GLX_VERSION_1_1 + +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 + +extern const char* glXQueryExtensionsString (Display *dpy, int screen); +extern const char* glXGetClientString (Display *dpy, int name); +extern const char* glXQueryServerString (Display *dpy, int screen, int name); + +#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) + +#endif /* GLX_VERSION_1_1 */ + +/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ + +#ifndef GLX_VERSION_1_2 +#define GLX_VERSION_1_2 1 + +typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); + +#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) + +#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) + +#endif /* GLX_VERSION_1_2 */ + +/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 + +#define GLX_RGBA_BIT 0x00000001 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_DONT_CARE 0xFFFFFFFF + +typedef XID GLXFBConfigID; +typedef XID GLXPbuffer; +typedef XID GLXWindow; +typedef struct __GLXFBConfigRec *GLXFBConfig; + +typedef struct { + int event_type; + int draw_type; + unsigned long serial; + Bool send_event; + Display *display; + GLXDrawable drawable; + unsigned int buffer_mask; + unsigned int aux_buffer; + int x, y; + int width, height; + int count; +} GLXPbufferClobberEvent; +typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + long pad[24]; +} GLXEvent; + +typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); + +#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) +#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) +#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) +#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) +#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) +#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) +#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) +#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) +#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) +#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) +#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) +#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) +#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) +#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) +#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) +#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) +#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) + +#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) + +#endif /* GLX_VERSION_1_3 */ + +/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 + +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 + +extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); + +#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) + +#endif /* GLX_VERSION_1_4 */ + +/* -------------------------- GLX_3DFX_multisample ------------------------- */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 + +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 + +#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) + +#endif /* GLX_3DFX_multisample */ + +/* ------------------------ GLX_AMD_gpu_association ------------------------ */ + +#ifndef GLX_AMD_gpu_association +#define GLX_AMD_gpu_association 1 + +#define GLX_GPU_VENDOR_AMD 0x1F00 +#define GLX_GPU_RENDERER_STRING_AMD 0x1F01 +#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define GLX_GPU_RAM_AMD 0x21A3 +#define GLX_GPU_CLOCK_AMD 0x21A4 +#define GLX_GPU_NUM_PIPES_AMD 0x21A5 +#define GLX_GPU_NUM_SIMD_AMD 0x21A6 +#define GLX_GPU_NUM_RB_AMD 0x21A7 +#define GLX_GPU_NUM_SPI_AMD 0x21A8 + +#define GLXEW_AMD_gpu_association GLXEW_GET_VAR(__GLXEW_AMD_gpu_association) + +#endif /* GLX_AMD_gpu_association */ + +/* ------------------------- GLX_ARB_create_context ------------------------ */ + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context 1 + +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 + +typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + +#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB) + +#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context) + +#endif /* GLX_ARB_create_context */ + +/* --------------------- GLX_ARB_create_context_profile -------------------- */ + +#ifndef GLX_ARB_create_context_profile +#define GLX_ARB_create_context_profile 1 + +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 + +#define GLXEW_ARB_create_context_profile GLXEW_GET_VAR(__GLXEW_ARB_create_context_profile) + +#endif /* GLX_ARB_create_context_profile */ + +/* ------------------- GLX_ARB_create_context_robustness ------------------- */ + +#ifndef GLX_ARB_create_context_robustness +#define GLX_ARB_create_context_robustness 1 + +#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 + +#define GLXEW_ARB_create_context_robustness GLXEW_GET_VAR(__GLXEW_ARB_create_context_robustness) + +#endif /* GLX_ARB_create_context_robustness */ + +/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 + +#define GLX_RGBA_FLOAT_BIT 0x00000004 +#define GLX_RGBA_FLOAT_TYPE 0x20B9 + +#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) + +#endif /* GLX_ARB_fbconfig_float */ + +/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_ARB_framebuffer_sRGB +#define GLX_ARB_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 + +#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB) + +#endif /* GLX_ARB_framebuffer_sRGB */ + +/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 + +extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); + +#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) + +#endif /* GLX_ARB_get_proc_address */ + +/* -------------------------- GLX_ARB_multisample -------------------------- */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 + +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 + +#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) + +#endif /* GLX_ARB_multisample */ + +/* ---------------------- GLX_ARB_vertex_buffer_object --------------------- */ + +#ifndef GLX_ARB_vertex_buffer_object +#define GLX_ARB_vertex_buffer_object 1 + +#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 + +#define GLXEW_ARB_vertex_buffer_object GLXEW_GET_VAR(__GLXEW_ARB_vertex_buffer_object) + +#endif /* GLX_ARB_vertex_buffer_object */ + +/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ + +#ifndef GLX_ATI_pixel_format_float +#define GLX_ATI_pixel_format_float 1 + +#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 + +#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) + +#endif /* GLX_ATI_pixel_format_float */ + +/* ------------------------- GLX_ATI_render_texture ------------------------ */ + +#ifndef GLX_ATI_render_texture +#define GLX_ATI_render_texture 1 + +#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 +#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 +#define GLX_TEXTURE_FORMAT_ATI 0x9802 +#define GLX_TEXTURE_TARGET_ATI 0x9803 +#define GLX_MIPMAP_TEXTURE_ATI 0x9804 +#define GLX_TEXTURE_RGB_ATI 0x9805 +#define GLX_TEXTURE_RGBA_ATI 0x9806 +#define GLX_NO_TEXTURE_ATI 0x9807 +#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 +#define GLX_TEXTURE_1D_ATI 0x9809 +#define GLX_TEXTURE_2D_ATI 0x980A +#define GLX_MIPMAP_LEVEL_ATI 0x980B +#define GLX_CUBE_MAP_FACE_ATI 0x980C +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 +#define GLX_FRONT_LEFT_ATI 0x9813 +#define GLX_FRONT_RIGHT_ATI 0x9814 +#define GLX_BACK_LEFT_ATI 0x9815 +#define GLX_BACK_RIGHT_ATI 0x9816 +#define GLX_AUX0_ATI 0x9817 +#define GLX_AUX1_ATI 0x9818 +#define GLX_AUX2_ATI 0x9819 +#define GLX_AUX3_ATI 0x981A +#define GLX_AUX4_ATI 0x981B +#define GLX_AUX5_ATI 0x981C +#define GLX_AUX6_ATI 0x981D +#define GLX_AUX7_ATI 0x981E +#define GLX_AUX8_ATI 0x981F +#define GLX_AUX9_ATI 0x9820 +#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 +#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 + +typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); +typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); + +#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) +#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) +#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) + +#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) + +#endif /* GLX_ATI_render_texture */ + +/* ------------------- GLX_EXT_create_context_es2_profile ------------------ */ + +#ifndef GLX_EXT_create_context_es2_profile +#define GLX_EXT_create_context_es2_profile 1 + +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 + +#define GLXEW_EXT_create_context_es2_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es2_profile) + +#endif /* GLX_EXT_create_context_es2_profile */ + +/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */ + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 + +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 + +#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float) + +#endif /* GLX_EXT_fbconfig_packed_float */ + +/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 + +#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB) + +#endif /* GLX_EXT_framebuffer_sRGB */ + +/* ------------------------- GLX_EXT_import_context ------------------------ */ + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 + +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C + +typedef XID GLXContextID; + +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value); + +#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) +#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) +#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) +#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) + +#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) + +#endif /* GLX_EXT_import_context */ + +/* -------------------------- GLX_EXT_scene_marker ------------------------- */ + +#ifndef GLX_EXT_scene_marker +#define GLX_EXT_scene_marker 1 + +#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) + +#endif /* GLX_EXT_scene_marker */ + +/* -------------------------- GLX_EXT_swap_control ------------------------- */ + +#ifndef GLX_EXT_swap_control +#define GLX_EXT_swap_control 1 + +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 + +typedef void ( * PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval); + +#define glXSwapIntervalEXT GLXEW_GET_FUN(__glewXSwapIntervalEXT) + +#define GLXEW_EXT_swap_control GLXEW_GET_VAR(__GLXEW_EXT_swap_control) + +#endif /* GLX_EXT_swap_control */ + +/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */ + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap 1 + +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB + +typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer); + +#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT) +#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT) + +#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap) + +#endif /* GLX_EXT_texture_from_pixmap */ + +/* -------------------------- GLX_EXT_visual_info -------------------------- */ + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 + +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 + +#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) + +#endif /* GLX_EXT_visual_info */ + +/* ------------------------- GLX_EXT_visual_rating ------------------------- */ + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 + +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D + +#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) + +#endif /* GLX_EXT_visual_rating */ + +/* -------------------------- GLX_INTEL_swap_event ------------------------- */ + +#ifndef GLX_INTEL_swap_event +#define GLX_INTEL_swap_event 1 + +#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 +#define GLX_COPY_COMPLETE_INTEL 0x8181 +#define GLX_FLIP_COMPLETE_INTEL 0x8182 +#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 + +#define GLXEW_INTEL_swap_event GLXEW_GET_VAR(__GLXEW_INTEL_swap_event) + +#endif /* GLX_INTEL_swap_event */ + +/* -------------------------- GLX_MESA_agp_offset -------------------------- */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 + +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); + +#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) + +#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) + +#endif /* GLX_MESA_agp_offset */ + +/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 + +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height); + +#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) + +#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) + +#endif /* GLX_MESA_copy_sub_buffer */ + +/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 + +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); + +#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) + +#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) + +#endif /* GLX_MESA_pixmap_colormap */ + +/* ------------------------ GLX_MESA_release_buffers ----------------------- */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 + +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d); + +#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) + +#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) + +#endif /* GLX_MESA_release_buffers */ + +/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 + +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 + +typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); + +#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) + +#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) + +#endif /* GLX_MESA_set_3dfx_mode */ + +/* ------------------------- GLX_MESA_swap_control ------------------------- */ + +#ifndef GLX_MESA_swap_control +#define GLX_MESA_swap_control 1 + +typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC) (void); +typedef int ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval); + +#define glXGetSwapIntervalMESA GLXEW_GET_FUN(__glewXGetSwapIntervalMESA) +#define glXSwapIntervalMESA GLXEW_GET_FUN(__glewXSwapIntervalMESA) + +#define GLXEW_MESA_swap_control GLXEW_GET_VAR(__GLXEW_MESA_swap_control) + +#endif /* GLX_MESA_swap_control */ + +/* --------------------------- GLX_NV_copy_image --------------------------- */ + +#ifndef GLX_NV_copy_image +#define GLX_NV_copy_image 1 + +typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + +#define glXCopyImageSubDataNV GLXEW_GET_FUN(__glewXCopyImageSubDataNV) + +#define GLXEW_NV_copy_image GLXEW_GET_VAR(__GLXEW_NV_copy_image) + +#endif /* GLX_NV_copy_image */ + +/* -------------------------- GLX_NV_float_buffer -------------------------- */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 + +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 + +#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) + +#endif /* GLX_NV_float_buffer */ + +/* ---------------------- GLX_NV_multisample_coverage ---------------------- */ + +#ifndef GLX_NV_multisample_coverage +#define GLX_NV_multisample_coverage 1 + +#define GLX_COLOR_SAMPLES_NV 0x20B3 +#define GLX_COVERAGE_SAMPLES_NV 100001 + +#define GLXEW_NV_multisample_coverage GLXEW_GET_VAR(__GLXEW_NV_multisample_coverage) + +#endif /* GLX_NV_multisample_coverage */ + +/* -------------------------- GLX_NV_present_video ------------------------- */ + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video 1 + +#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 + +typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); +typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements); + +#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV) +#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV) + +#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video) + +#endif /* GLX_NV_present_video */ + +/* --------------------------- GLX_NV_swap_group --------------------------- */ + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group 1 + +typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier); +typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group); +typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint *count); +typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); +typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); +typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen); + +#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV) +#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV) +#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV) +#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV) +#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV) +#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV) + +#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group) + +#endif /* GLX_NV_swap_group */ + +/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ + +#ifndef GLX_NV_vertex_array_range +#define GLX_NV_vertex_array_range 1 + +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); + +#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) +#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) + +#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) + +#endif /* GLX_NV_vertex_array_range */ + +/* -------------------------- GLX_NV_video_capture ------------------------- */ + +#ifndef GLX_NV_video_capture +#define GLX_NV_video_capture 1 + +#define GLX_DEVICE_ID_NV 0x20CD +#define GLX_UNIQUE_ID_NV 0x20CE +#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + +typedef XID GLXVideoCaptureDeviceNV; + +typedef int ( * PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display* dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); +typedef GLXVideoCaptureDeviceNV * ( * PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display* dpy, int screen, int *nelements); +typedef void ( * PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device); +typedef int ( * PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value); +typedef void ( * PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device); + +#define glXBindVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXBindVideoCaptureDeviceNV) +#define glXEnumerateVideoCaptureDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoCaptureDevicesNV) +#define glXLockVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXLockVideoCaptureDeviceNV) +#define glXQueryVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXQueryVideoCaptureDeviceNV) +#define glXReleaseVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoCaptureDeviceNV) + +#define GLXEW_NV_video_capture GLXEW_GET_VAR(__GLXEW_NV_video_capture) + +#endif /* GLX_NV_video_capture */ + +/* -------------------------- GLX_NV_video_output -------------------------- */ + +#ifndef GLX_NV_video_output +#define GLX_NV_video_output 1 + +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB +#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC + +typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); +typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); +typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice); +typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf); +typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); + +#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV) +#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV) +#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV) +#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV) +#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV) +#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV) + +#define GLXEW_NV_video_output GLXEW_GET_VAR(__GLXEW_NV_video_output) + +#endif /* GLX_NV_video_output */ + +/* -------------------------- GLX_OML_swap_method -------------------------- */ + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 + +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 + +#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) + +#endif /* GLX_OML_swap_method */ + +/* -------------------------- GLX_OML_sync_control ------------------------- */ + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control 1 + +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); + +#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) +#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) +#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) +#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) +#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) + +#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) + +#endif /* GLX_OML_sync_control */ + +/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 + +#define GLX_BLENDED_RGBA_SGIS 0x8025 + +#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) + +#endif /* GLX_SGIS_blended_overlay */ + +/* -------------------------- GLX_SGIS_color_range ------------------------- */ + +#ifndef GLX_SGIS_color_range +#define GLX_SGIS_color_range 1 + +#define GLX_MIN_RED_SGIS 0 +#define GLX_MAX_GREEN_SGIS 0 +#define GLX_MIN_BLUE_SGIS 0 +#define GLX_MAX_ALPHA_SGIS 0 +#define GLX_MIN_GREEN_SGIS 0 +#define GLX_MIN_ALPHA_SGIS 0 +#define GLX_MAX_RED_SGIS 0 +#define GLX_EXTENDED_RANGE_SGIS 0 +#define GLX_MAX_BLUE_SGIS 0 + +#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) + +#endif /* GLX_SGIS_color_range */ + +/* -------------------------- GLX_SGIS_multisample ------------------------- */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 + +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 + +#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) + +#endif /* GLX_SGIS_multisample */ + +/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */ + +#ifndef GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample 1 + +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 + +#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) + +#endif /* GLX_SGIS_shared_multisample */ + +/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 + +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_SCREEN_EXT 0x800C +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 + +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + +typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap); +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config); + +#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) +#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) +#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) +#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) +#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) +#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) + +#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) + +#endif /* GLX_SGIX_fbconfig */ + +/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */ + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 + +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin; + int YOrigin; + int maxHeight; + int maxWidth; +} GLXPipeRectLimits; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin; + int srcYOrigin; + int srcWidth; + int srcHeight; + int destXOrigin; + int destYOrigin; + int destWidth; + int destHeight; +} GLXPipeRect; + +typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); +typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); + +#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX) +#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX) +#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX) +#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX) +#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX) +#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX) +#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX) +#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX) + +#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe) + +#endif /* GLX_SGIX_hyperpipe */ + +/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 + +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 + +typedef XID GLXPbufferSGIX; +typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; + +typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask); +typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); + +#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) +#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) +#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) +#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) +#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) + +#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) + +#endif /* GLX_SGIX_pbuffer */ + +/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 + +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); + +#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) +#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) + +#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) + +#endif /* GLX_SGIX_swap_barrier */ + +/* -------------------------- GLX_SGIX_swap_group -------------------------- */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 + +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); + +#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) + +#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) + +#endif /* GLX_SGIX_swap_group */ + +/* ------------------------- GLX_SGIX_video_resize ------------------------- */ + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 + +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 + +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) +#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) +#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) +#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) +#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) + +#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) + +#endif /* GLX_SGIX_video_resize */ + +/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 + +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 + +#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) + +#endif /* GLX_SGIX_visual_select_group */ + +/* ---------------------------- GLX_SGI_cushion ---------------------------- */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 + +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); + +#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) + +#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) + +#endif /* GLX_SGI_cushion */ + +/* ----------------------- GLX_SGI_make_current_read ----------------------- */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 + +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) +#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) + +#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) + +#endif /* GLX_SGI_make_current_read */ + +/* -------------------------- GLX_SGI_swap_control ------------------------- */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 + +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); + +#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) + +#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) + +#endif /* GLX_SGI_swap_control */ + +/* --------------------------- GLX_SGI_video_sync -------------------------- */ + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 + +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int* count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count); + +#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) +#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) + +#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) + +#endif /* GLX_SGI_video_sync */ + +/* --------------------- GLX_SUN_get_transparent_index --------------------- */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 + +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex); + +#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) + +#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) + +#endif /* GLX_SUN_get_transparent_index */ + +/* -------------------------- GLX_SUN_video_resize ------------------------- */ + +#ifndef GLX_SUN_video_resize +#define GLX_SUN_video_resize 1 + +#define GLX_VIDEO_RESIZE_SUN 0x8171 +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD + +typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); +typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); + +#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) +#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) + +#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define GLXEW_EXPORT +#else +#define GLXEW_EXPORT extern +#endif /* GLEW_MX */ + +extern PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; + +extern PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; +extern PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; +extern PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; +extern PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; +extern PFNGLXCREATEWINDOWPROC __glewXCreateWindow; +extern PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; +extern PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; +extern PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; +extern PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; +extern PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; +extern PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; +extern PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; +extern PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; +extern PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; +extern PFNGLXQUERYCONTEXTPROC __glewXQueryContext; +extern PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; +extern PFNGLXSELECTEVENTPROC __glewXSelectEvent; + +extern PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB; + +extern PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; +extern PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; +extern PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; + +extern PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; +extern PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; +extern PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; +extern PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; + +extern PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT; + +extern PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT; +extern PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT; + +extern PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; + +extern PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; + +extern PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; + +extern PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; + +extern PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; + +extern PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA; +extern PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA; + +extern PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV; + +extern PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV; +extern PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV; + +extern PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV; +extern PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV; +extern PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV; +extern PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV; +extern PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV; +extern PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV; + +extern PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; +extern PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; + +extern PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV; +extern PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV; +extern PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV; +extern PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV; +extern PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV; + +extern PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV; +extern PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV; +extern PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV; +extern PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV; +extern PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV; +extern PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV; + +extern PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; +extern PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; +extern PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; +extern PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; +extern PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; + +extern PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; +extern PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; +extern PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; +extern PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; +extern PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; +extern PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; + +extern PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX; +extern PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX; +extern PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX; +extern PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX; +extern PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX; +extern PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX; +extern PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX; +extern PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX; + +extern PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; +extern PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; +extern PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; +extern PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; +extern PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; + +extern PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; +extern PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; + +extern PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; + +extern PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; +extern PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; +extern PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; +extern PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; +extern PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; + +extern PFNGLXCUSHIONSGIPROC __glewXCushionSGI; + +extern PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; +extern PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; + +extern PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; + +extern PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; +extern PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; + +extern PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; + +extern PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; +extern PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; + +#if defined(GLEW_MX) +struct GLXEWContextStruct +{ +#endif /* GLEW_MX */ + +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_0; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_1; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_2; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_3; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_4; +GLXEW_EXPORT GLboolean __GLXEW_3DFX_multisample; +GLXEW_EXPORT GLboolean __GLXEW_AMD_gpu_association; +GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context; +GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context_profile; +GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context_robustness; +GLXEW_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; +GLXEW_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB; +GLXEW_EXPORT GLboolean __GLXEW_ARB_get_proc_address; +GLXEW_EXPORT GLboolean __GLXEW_ARB_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ARB_vertex_buffer_object; +GLXEW_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; +GLXEW_EXPORT GLboolean __GLXEW_ATI_render_texture; +GLXEW_EXPORT GLboolean __GLXEW_EXT_create_context_es2_profile; +GLXEW_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; +GLXEW_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; +GLXEW_EXPORT GLboolean __GLXEW_EXT_import_context; +GLXEW_EXPORT GLboolean __GLXEW_EXT_scene_marker; +GLXEW_EXPORT GLboolean __GLXEW_EXT_swap_control; +GLXEW_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_info; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_rating; +GLXEW_EXPORT GLboolean __GLXEW_INTEL_swap_event; +GLXEW_EXPORT GLboolean __GLXEW_MESA_agp_offset; +GLXEW_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; +GLXEW_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; +GLXEW_EXPORT GLboolean __GLXEW_MESA_release_buffers; +GLXEW_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; +GLXEW_EXPORT GLboolean __GLXEW_MESA_swap_control; +GLXEW_EXPORT GLboolean __GLXEW_NV_copy_image; +GLXEW_EXPORT GLboolean __GLXEW_NV_float_buffer; +GLXEW_EXPORT GLboolean __GLXEW_NV_multisample_coverage; +GLXEW_EXPORT GLboolean __GLXEW_NV_present_video; +GLXEW_EXPORT GLboolean __GLXEW_NV_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_NV_vertex_array_range; +GLXEW_EXPORT GLboolean __GLXEW_NV_video_capture; +GLXEW_EXPORT GLboolean __GLXEW_NV_video_output; +GLXEW_EXPORT GLboolean __GLXEW_OML_swap_method; +GLXEW_EXPORT GLboolean __GLXEW_OML_sync_control; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_color_range; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_fbconfig; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_hyperpipe; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_pbuffer; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_video_resize; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; +GLXEW_EXPORT GLboolean __GLXEW_SGI_cushion; +GLXEW_EXPORT GLboolean __GLXEW_SGI_make_current_read; +GLXEW_EXPORT GLboolean __GLXEW_SGI_swap_control; +GLXEW_EXPORT GLboolean __GLXEW_SGI_video_sync; +GLXEW_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; +GLXEW_EXPORT GLboolean __GLXEW_SUN_video_resize; + +#ifdef GLEW_MX +}; /* GLXEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------ */ + +#ifdef GLEW_MX + +typedef struct GLXEWContextStruct GLXEWContext; +extern GLenum glxewContextInit (GLXEWContext* ctx); +extern GLboolean glxewContextIsSupported (const GLXEWContext* ctx, const char* name); + +#define glxewInit() glxewContextInit(glxewGetContext()) +#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x) + +#define GLXEW_GET_VAR(x) (*(const GLboolean*)&(glxewGetContext()->x)) +#define GLXEW_GET_FUN(x) x + +#else /* GLEW_MX */ + +#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x) +#define GLXEW_GET_FUN(x) x + +extern GLboolean glxewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +extern GLboolean glxewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#endif /* __glxew_h__ */ diff --git a/Glut/GL/glxext.h b/Glut/GL/glxext.h new file mode 100644 index 0000000..b3de958 --- /dev/null +++ b/Glut/GL/glxext.h @@ -0,0 +1,546 @@ +#ifndef __glxext_h_ +#define __glxext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#else +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif + + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +#define GLX_GLXEXT_VERSION 2 + +#ifndef GLX_VERSION_1_3 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#endif + +#ifndef GLX_EXT_visual_info +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#endif + +#ifndef GLX_SGI_swap_control +#endif + +#ifndef GLX_SGI_video_sync +#endif + +#ifndef GLX_SGI_make_current_read +#endif + +#ifndef GLX_SGIX_video_source +#endif + +#ifndef GLX_EXT_visual_rating +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +/* reuse GLX_NONE_EXT */ +#endif + +#ifndef GLX_EXT_import_context +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C +#endif + +#ifndef GLX_SGIX_fbconfig +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 +/* reuse GLX_SCREEN_EXT */ +#endif + +#ifndef GLX_SGIX_pbuffer +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#endif + +#ifndef GLX_SGI_cushion +#endif + +#ifndef GLX_SGIX_video_resize +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 +#endif + +#ifndef GLX_SGIX_dmbuffer +#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 +#endif + +#ifndef GLX_SGIX_swap_group +#endif + +#ifndef GLX_SGIX_swap_barrier +#endif + +#ifndef GLX_SGIS_blended_overlay +#define GLX_BLENDED_RGBA_SGIS 0x8025 +#endif + +#ifndef GLX_SGIS_shared_multisample +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 +#endif + +#ifndef GLX_SUN_get_transparent_index +#endif + +#ifndef GLX_3DFX_multisample +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#endif + +#ifndef GLX_MESA_pixmap_colormap +#endif + +#ifndef GLX_MESA_release_buffers +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 +#endif + + +/*************************************************************/ + +#ifndef GLX_ARB_get_proc_address +typedef void (*__GLXextFuncPtr)(); +#endif + +#ifndef GLX_SGIX_video_source +typedef XID GLXVideoSourceSGIX; +#endif + +#ifndef GLX_SGIX_fbconfig +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +#endif + +#ifndef GLX_SGIX_pbuffer +typedef XID GLXPbufferSGIX; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXBufferClobberEventSGIX; +#endif + +#ifdef GL_NV_vertex_array_range +#ifndef PFNGLXALLOCATEMEMORYNVPROC +#ifdef GLX_GLXEXT_PROTOTYPES +extern void *glXAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); +#endif +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei, GLfloat, GLfloat, GLfloat); +#endif +#ifndef PFNGLXFREEMEMORYNVPROC +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXFreeMemoryNV (void *); +#endif +typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *); +#endif +#endif + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXFBConfig * glXGetFBConfigs (Display *, int, int *); +extern GLXFBConfig * glXChooseFBConfig (Display *, int, const int *, int *); +extern int glXGetFBConfigAttrib (Display *, GLXFBConfig, int, int *); +extern XVisualInfo * glXGetVisualFromFBConfig (Display *, GLXFBConfig); +extern GLXWindow glXCreateWindow (Display *, GLXFBConfig, Window, const int *); +extern void glXDestroyWindow (Display *, GLXWindow); +extern GLXPixmap glXCreatePixmap (Display *, GLXFBConfig, Pixmap, const int *); +extern void glXDestroyPixmap (Display *, GLXPixmap); +extern GLXPbuffer glXCreatePbuffer (Display *, GLXFBConfig, const int *); +extern void glXDestroyPbuffer (Display *, GLXPbuffer); +extern void glXQueryDrawable (Display *, GLXDrawable, int, unsigned int *); +extern GLXContext glXCreateNewContext (Display *, GLXFBConfig, int, GLXContext, Bool); +extern Bool glXMakeContextCurrent (Display *, GLXDrawable, GLXDrawable, GLXContext); +extern GLXDrawable glXGetCurrentReadDrawable (void); +extern Display * glXGetCurrentDisplay (void); +extern int glXQueryContext (Display *, GLXContext, int, int *); +extern void glXSelectEvent (Display *, GLXDrawable, unsigned long); +extern void glXGetSelectedEvent (Display *, GLXDrawable, unsigned long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXFBConfig * ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef Display * ( * PFNGLXGETCURRENTDISPLAYPROC) (void); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +#endif + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName); +#endif + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 +#endif + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 +#endif + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXSwapIntervalSGI (int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); +#endif + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXGetVideoSyncSGI (unsigned int *); +extern int glXWaitVideoSyncSGI (int, int, unsigned int *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count); +#endif + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXMakeCurrentReadSGI (Display *, GLXDrawable, GLXDrawable, GLXContext); +extern GLXDrawable glXGetCurrentReadDrawableSGI (void); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +#endif + +#ifdef _VL_H +#ifndef GLX_SGIX_video_source +#define GLX_SGIX_video_source 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *, int, VLServer, VLPath, int, VLNode); +extern void glXDestroyGLXVideoSourceSGIX (Display *, GLXVideoSourceSGIX); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXVideoSourceSGIX ( * PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); +typedef void ( * PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource); +#endif + +#endif /* _VL_H */ +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 +#endif + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Display * glXGetCurrentDisplayEXT (void); +extern int glXQueryContextInfoEXT (Display *, GLXContext, int, int *); +extern GLXContextID glXGetContextIDEXT (GLXContext); +extern GLXContext glXImportContextEXT (Display *, GLXContextID); +extern void glXFreeContextEXT (Display *, GLXContext); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Display * ( * PFNGLXGETCURRENTDISPLAYEXTPROC) (void); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID); +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context); +#endif + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXGetFBConfigAttribSGIX (Display *, GLXFBConfigSGIX, int, int *); +extern GLXFBConfigSGIX * glXChooseFBConfigSGIX (Display *, int, int *, int *); +extern GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *, GLXFBConfigSGIX, Pixmap); +extern GLXContext glXCreateContextWithConfigSGIX (Display *, GLXFBConfigSGIX, int, GLXContext, Bool); +extern XVisualInfo * glXGetVisualFromFBConfigSGIX (Display *, GLXFBConfigSGIX); +extern GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *, XVisualInfo *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX * ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); +typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis); +#endif + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); +extern void glXDestroyGLXPbufferSGIX (Display *, GLXPbufferSGIX); +extern int glXQueryGLXPbufferSGIX (Display *, GLXPbufferSGIX, int, unsigned int *); +extern void glXSelectEventSGIX (Display *, GLXDrawable, unsigned long); +extern void glXGetSelectedEventSGIX (Display *, GLXDrawable, unsigned long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXPbufferSGIX ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf); +typedef int ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask); +#endif + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXCushionSGI (Display *, Window, float); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion); +#endif + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXBindChannelToWindowSGIX (Display *, int, int, Window); +extern int glXChannelRectSGIX (Display *, int, int, int, int, int, int); +extern int glXQueryChannelRectSGIX (Display *, int, int, int *, int *, int *, int *); +extern int glXQueryChannelDeltasSGIX (Display *, int, int, int *, int *, int *, int *); +extern int glXChannelRectSyncSGIX (Display *, int, int, GLenum); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype); +#endif + +#ifdef _DM_BUFFER_H_ +#ifndef GLX_SGIX_dmbuffer +#define GLX_SGIX_dmbuffer 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXAssociateDMPbufferSGIX (Display *, GLXPbufferSGIX, DMparams *, DMbuffer); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#endif + +#endif /* _DM_BUFFER_H_ */ +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXJoinSwapGroupSGIX (Display *, GLXDrawable, GLXDrawable); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); +#endif + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXBindSwapBarrierSGIX (Display *, GLXDrawable, int); +extern Bool glXQueryMaxSwapBarriersSGIX (Display *, int, int *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); +#endif + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Status glXGetTransparentIndexSUN (Display *, Window, Window, long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXCopySubBufferMESA (Display *, GLXDrawable, int, int, int, int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); +#endif + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXPixmap glXCreateGLXPixmapMESA (Display *, XVisualInfo *, Pixmap, Colormap); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); +#endif + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXReleaseBuffersMESA (Display *, GLXDrawable); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable); +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXSet3DfxModeMESA (int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXSET3DFXMODEMESAPROC) (int mode); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Glut/GL/wglew.h b/Glut/GL/wglew.h new file mode 100644 index 0000000..05f054f --- /dev/null +++ b/Glut/GL/wglew.h @@ -0,0 +1,1363 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __wglew_h__ +#define __wglew_h__ +#define __WGLEW_H__ + +#ifdef __wglext_h_ +#error wglext.h included before wglew.h +#endif + +#define __wglext_h_ + +#if !defined(WINAPI) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +#include +# undef WIN32_LEAN_AND_MEAN +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -------------------------- WGL_3DFX_multisample ------------------------- */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 + +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 + +#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) + +#endif /* WGL_3DFX_multisample */ + +/* ------------------------- WGL_3DL_stereo_control ------------------------ */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 + +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 + +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); + +#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) + +#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) + +#endif /* WGL_3DL_stereo_control */ + +/* ------------------------ WGL_AMD_gpu_association ------------------------ */ + +#ifndef WGL_AMD_gpu_association +#define WGL_AMD_gpu_association 1 + +#define WGL_GPU_VENDOR_AMD 0x1F00 +#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 +#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define WGL_GPU_RAM_AMD 0x21A3 +#define WGL_GPU_CLOCK_AMD 0x21A4 +#define WGL_GPU_NUM_PIPES_AMD 0x21A5 +#define WGL_GPU_NUM_SIMD_AMD 0x21A6 +#define WGL_GPU_NUM_RB_AMD 0x21A7 +#define WGL_GPU_NUM_SPI_AMD 0x21A8 + +typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int* attribList); +typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); +typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT* ids); +typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, INT property, GLenum dataType, UINT size, void* data); +typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); + +#define wglBlitContextFramebufferAMD WGLEW_GET_FUN(__wglewBlitContextFramebufferAMD) +#define wglCreateAssociatedContextAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAMD) +#define wglCreateAssociatedContextAttribsAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAttribsAMD) +#define wglDeleteAssociatedContextAMD WGLEW_GET_FUN(__wglewDeleteAssociatedContextAMD) +#define wglGetContextGPUIDAMD WGLEW_GET_FUN(__wglewGetContextGPUIDAMD) +#define wglGetCurrentAssociatedContextAMD WGLEW_GET_FUN(__wglewGetCurrentAssociatedContextAMD) +#define wglGetGPUIDsAMD WGLEW_GET_FUN(__wglewGetGPUIDsAMD) +#define wglGetGPUInfoAMD WGLEW_GET_FUN(__wglewGetGPUInfoAMD) +#define wglMakeAssociatedContextCurrentAMD WGLEW_GET_FUN(__wglewMakeAssociatedContextCurrentAMD) + +#define WGLEW_AMD_gpu_association WGLEW_GET_VAR(__WGLEW_AMD_gpu_association) + +#endif /* WGL_AMD_gpu_association */ + +/* ------------------------- WGL_ARB_buffer_region ------------------------- */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 + +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 + +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + +#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) +#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) +#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) +#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) + +#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) + +#endif /* WGL_ARB_buffer_region */ + +/* ------------------------- WGL_ARB_create_context ------------------------ */ + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 + +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#define ERROR_INVALID_PROFILE_ARB 0x2096 + +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); + +#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB) + +#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context) + +#endif /* WGL_ARB_create_context */ + +/* --------------------- WGL_ARB_create_context_profile -------------------- */ + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile 1 + +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 + +#define WGLEW_ARB_create_context_profile WGLEW_GET_VAR(__WGLEW_ARB_create_context_profile) + +#endif /* WGL_ARB_create_context_profile */ + +/* ------------------- WGL_ARB_create_context_robustness ------------------- */ + +#ifndef WGL_ARB_create_context_robustness +#define WGL_ARB_create_context_robustness 1 + +#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 + +#define WGLEW_ARB_create_context_robustness WGLEW_GET_VAR(__WGLEW_ARB_create_context_robustness) + +#endif /* WGL_ARB_create_context_robustness */ + +/* ----------------------- WGL_ARB_extensions_string ----------------------- */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + +#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) + +#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) + +#endif /* WGL_ARB_extensions_string */ + +/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_ARB_framebuffer_sRGB +#define WGL_ARB_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 + +#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB) + +#endif /* WGL_ARB_framebuffer_sRGB */ + +/* ----------------------- WGL_ARB_make_current_read ----------------------- */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) +#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) + +#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) + +#endif /* WGL_ARB_make_current_read */ + +/* -------------------------- WGL_ARB_multisample -------------------------- */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + +#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) + +#endif /* WGL_ARB_multisample */ + +/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 + +DECLARE_HANDLE(HPBUFFERARB); + +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + +#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) +#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) +#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) +#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) +#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) + +#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) + +#endif /* WGL_ARB_pbuffer */ + +/* -------------------------- WGL_ARB_pixel_format ------------------------- */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); + +#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) +#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) +#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) + +#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) + +#endif /* WGL_ARB_pixel_format */ + +/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + +#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) + +#endif /* WGL_ARB_pixel_format_float */ + +/* ------------------------- WGL_ARB_render_texture ------------------------ */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 + +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 + +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList); + +#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) +#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) +#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) + +#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) + +#endif /* WGL_ARB_render_texture */ + +/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 + +#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) + +#endif /* WGL_ATI_pixel_format_float */ + +/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ + +#ifndef WGL_ATI_render_texture_rectangle +#define WGL_ATI_render_texture_rectangle 1 + +#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + +#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) + +#endif /* WGL_ATI_render_texture_rectangle */ + +/* ------------------- WGL_EXT_create_context_es2_profile ------------------ */ + +#ifndef WGL_EXT_create_context_es2_profile +#define WGL_EXT_create_context_es2_profile 1 + +#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 + +#define WGLEW_EXT_create_context_es2_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es2_profile) + +#endif /* WGL_EXT_create_context_es2_profile */ + +/* -------------------------- WGL_EXT_depth_float -------------------------- */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 + +#define WGL_DEPTH_FLOAT_EXT 0x2040 + +#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) + +#endif /* WGL_EXT_depth_float */ + +/* ---------------------- WGL_EXT_display_color_table ---------------------- */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 + +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length); + +#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) +#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) +#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) +#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) + +#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) + +#endif /* WGL_EXT_display_color_table */ + +/* ----------------------- WGL_EXT_extensions_string ----------------------- */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); + +#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) + +#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) + +#endif /* WGL_EXT_extensions_string */ + +/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 + +#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB) + +#endif /* WGL_EXT_framebuffer_sRGB */ + +/* ----------------------- WGL_EXT_make_current_read ----------------------- */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) +#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) + +#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) + +#endif /* WGL_EXT_make_current_read */ + +/* -------------------------- WGL_EXT_multisample -------------------------- */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 + +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 + +#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) + +#endif /* WGL_EXT_multisample */ + +/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 + +DECLARE_HANDLE(HPBUFFEREXT); + +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); + +#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) +#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) +#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) +#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) +#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) + +#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) + +#endif /* WGL_EXT_pbuffer */ + +/* -------------------------- WGL_EXT_pixel_format ------------------------- */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues); + +#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) +#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) +#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) + +#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) + +#endif /* WGL_EXT_pixel_format */ + +/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 + +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 + +#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float) + +#endif /* WGL_EXT_pixel_format_packed_float */ + +/* -------------------------- WGL_EXT_swap_control ------------------------- */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 + +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + +#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) +#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) + +#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) + +#endif /* WGL_EXT_swap_control */ + +/* --------------------- WGL_I3D_digital_video_control --------------------- */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 + +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 + +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) +#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) + +#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) + +#endif /* WGL_I3D_digital_video_control */ + +/* ----------------------------- WGL_I3D_gamma ----------------------------- */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 + +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F + +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) +#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) +#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) +#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) + +#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) + +#endif /* WGL_I3D_gamma */ + +/* ---------------------------- WGL_I3D_genlock ---------------------------- */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 + +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C + +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay); + +#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) +#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) +#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) +#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) +#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) +#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) +#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) +#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) +#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) +#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) +#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) +#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) + +#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) + +#endif /* WGL_I3D_genlock */ + +/* -------------------------- WGL_I3D_image_buffer ------------------------- */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 + +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 + +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count); +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count); + +#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) +#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) +#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) +#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) + +#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) + +#endif /* WGL_I3D_image_buffer */ + +/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 + +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); + +#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) +#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) +#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) +#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) + +#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) + +#endif /* WGL_I3D_swap_frame_lock */ + +/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 + +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); + +#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) +#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) +#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) +#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) + +#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) + +#endif /* WGL_I3D_swap_frame_usage */ + +/* --------------------------- WGL_NV_DX_interop --------------------------- */ + +#ifndef WGL_NV_DX_interop +#define WGL_NV_DX_interop 1 + +#define WGL_ACCESS_READ_ONLY_NV 0x0000 +#define WGL_ACCESS_READ_WRITE_NV 0x0001 +#define WGL_ACCESS_WRITE_DISCARD_NV 0x0002 + +typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); +typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); +typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice); +typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access); +typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle); +typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); + +#define wglDXCloseDeviceNV WGLEW_GET_FUN(__wglewDXCloseDeviceNV) +#define wglDXLockObjectsNV WGLEW_GET_FUN(__wglewDXLockObjectsNV) +#define wglDXObjectAccessNV WGLEW_GET_FUN(__wglewDXObjectAccessNV) +#define wglDXOpenDeviceNV WGLEW_GET_FUN(__wglewDXOpenDeviceNV) +#define wglDXRegisterObjectNV WGLEW_GET_FUN(__wglewDXRegisterObjectNV) +#define wglDXSetResourceShareHandleNV WGLEW_GET_FUN(__wglewDXSetResourceShareHandleNV) +#define wglDXUnlockObjectsNV WGLEW_GET_FUN(__wglewDXUnlockObjectsNV) +#define wglDXUnregisterObjectNV WGLEW_GET_FUN(__wglewDXUnregisterObjectNV) + +#define WGLEW_NV_DX_interop WGLEW_GET_VAR(__WGLEW_NV_DX_interop) + +#endif /* WGL_NV_DX_interop */ + +/* --------------------------- WGL_NV_copy_image --------------------------- */ + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image 1 + +typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + +#define wglCopyImageSubDataNV WGLEW_GET_FUN(__wglewCopyImageSubDataNV) + +#define WGLEW_NV_copy_image WGLEW_GET_VAR(__WGLEW_NV_copy_image) + +#endif /* WGL_NV_copy_image */ + +/* -------------------------- WGL_NV_float_buffer -------------------------- */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 + +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 + +#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) + +#endif /* WGL_NV_float_buffer */ + +/* -------------------------- WGL_NV_gpu_affinity -------------------------- */ + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 + +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 + +DECLARE_HANDLE(HGPUNV); +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; + +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); + +#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV) +#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV) +#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV) +#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV) +#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV) + +#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity) + +#endif /* WGL_NV_gpu_affinity */ + +/* ---------------------- WGL_NV_multisample_coverage ---------------------- */ + +#ifndef WGL_NV_multisample_coverage +#define WGL_NV_multisample_coverage 1 + +#define WGL_COVERAGE_SAMPLES_NV 0x2042 +#define WGL_COLOR_SAMPLES_NV 0x20B9 + +#define WGLEW_NV_multisample_coverage WGLEW_GET_VAR(__WGLEW_NV_multisample_coverage) + +#endif /* WGL_NV_multisample_coverage */ + +/* -------------------------- WGL_NV_present_video ------------------------- */ + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 + +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 + +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList); +typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList); +typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue); + +#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV) +#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV) +#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV) + +#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video) + +#endif /* WGL_NV_present_video */ + +/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 + +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 + +#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) + +#endif /* WGL_NV_render_depth_texture */ + +/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 + +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 + +#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) + +#endif /* WGL_NV_render_texture_rectangle */ + +/* --------------------------- WGL_NV_swap_group --------------------------- */ + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 + +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group, GLuint *barrier); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); + +#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV) +#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV) +#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV) +#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV) +#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV) +#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV) + +#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group) + +#endif /* WGL_NV_swap_group */ + +/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 + +typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); + +#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) +#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) + +#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) + +#endif /* WGL_NV_vertex_array_range */ + +/* -------------------------- WGL_NV_video_capture ------------------------- */ + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture 1 + +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV* phDeviceList); +typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); + +#define wglBindVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewBindVideoCaptureDeviceNV) +#define wglEnumerateVideoCaptureDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoCaptureDevicesNV) +#define wglLockVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewLockVideoCaptureDeviceNV) +#define wglQueryVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewQueryVideoCaptureDeviceNV) +#define wglReleaseVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoCaptureDeviceNV) + +#define WGLEW_NV_video_capture WGLEW_GET_VAR(__WGLEW_NV_video_capture) + +#endif /* WGL_NV_video_capture */ + +/* -------------------------- WGL_NV_video_output -------------------------- */ + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 + +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC + +DECLARE_HANDLE(HPVIDEODEV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); +typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock); + +#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV) +#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV) +#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV) +#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV) +#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV) +#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV) + +#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output) + +#endif /* WGL_NV_video_output */ + +/* -------------------------- WGL_OML_sync_control ------------------------- */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 + +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator); +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc); + +#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) +#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) +#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) +#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) +#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) +#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) + +#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define WGLEW_EXPORT +#else +#define WGLEW_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#ifdef GLEW_MX +struct WGLEWContextStruct +{ +#endif /* GLEW_MX */ + +WGLEW_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; + +WGLEW_EXPORT PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD; +WGLEW_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD; +WGLEW_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD; +WGLEW_EXPORT PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD; +WGLEW_EXPORT PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD; +WGLEW_EXPORT PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD; +WGLEW_EXPORT PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD; +WGLEW_EXPORT PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD; +WGLEW_EXPORT PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD; + +WGLEW_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; +WGLEW_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; +WGLEW_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; +WGLEW_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; + +WGLEW_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; + +WGLEW_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; +WGLEW_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; +WGLEW_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; +WGLEW_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; + +WGLEW_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; +WGLEW_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; +WGLEW_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; + +WGLEW_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; + +WGLEW_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; +WGLEW_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; +WGLEW_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; +WGLEW_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; + +WGLEW_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; +WGLEW_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; + +WGLEW_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; +WGLEW_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; + +WGLEW_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; +WGLEW_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; + +WGLEW_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; +WGLEW_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; +WGLEW_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; +WGLEW_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; +WGLEW_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; + +WGLEW_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; +WGLEW_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; +WGLEW_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; +WGLEW_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; + +WGLEW_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; +WGLEW_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; +WGLEW_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; + +WGLEW_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; +WGLEW_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; +WGLEW_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; + +WGLEW_EXPORT PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV; +WGLEW_EXPORT PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV; +WGLEW_EXPORT PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV; +WGLEW_EXPORT PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV; +WGLEW_EXPORT PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV; +WGLEW_EXPORT PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV; +WGLEW_EXPORT PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV; +WGLEW_EXPORT PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV; + +WGLEW_EXPORT PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV; + +WGLEW_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV; +WGLEW_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV; +WGLEW_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV; +WGLEW_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV; +WGLEW_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV; + +WGLEW_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV; +WGLEW_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV; +WGLEW_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV; + +WGLEW_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV; +WGLEW_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV; +WGLEW_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV; +WGLEW_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV; +WGLEW_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV; +WGLEW_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV; + +WGLEW_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; +WGLEW_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; + +WGLEW_EXPORT PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV; +WGLEW_EXPORT PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV; +WGLEW_EXPORT PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV; +WGLEW_EXPORT PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV; +WGLEW_EXPORT PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV; + +WGLEW_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV; +WGLEW_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV; +WGLEW_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV; +WGLEW_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV; +WGLEW_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV; +WGLEW_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV; + +WGLEW_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; +WGLEW_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; +WGLEW_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; +WGLEW_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; +WGLEW_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; +WGLEW_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; +WGLEW_EXPORT GLboolean __WGLEW_3DFX_multisample; +WGLEW_EXPORT GLboolean __WGLEW_3DL_stereo_control; +WGLEW_EXPORT GLboolean __WGLEW_AMD_gpu_association; +WGLEW_EXPORT GLboolean __WGLEW_ARB_buffer_region; +WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context; +WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context_profile; +WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context_robustness; +WGLEW_EXPORT GLboolean __WGLEW_ARB_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB; +WGLEW_EXPORT GLboolean __WGLEW_ARB_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_ARB_multisample; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ARB_render_texture; +WGLEW_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_EXT_create_context_es2_profile; +WGLEW_EXPORT GLboolean __WGLEW_EXT_depth_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_display_color_table; +WGLEW_EXPORT GLboolean __WGLEW_EXT_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; +WGLEW_EXPORT GLboolean __WGLEW_EXT_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_EXT_multisample; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_swap_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_digital_video_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_gamma; +WGLEW_EXPORT GLboolean __WGLEW_I3D_genlock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_image_buffer; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; +WGLEW_EXPORT GLboolean __WGLEW_NV_DX_interop; +WGLEW_EXPORT GLboolean __WGLEW_NV_copy_image; +WGLEW_EXPORT GLboolean __WGLEW_NV_float_buffer; +WGLEW_EXPORT GLboolean __WGLEW_NV_gpu_affinity; +WGLEW_EXPORT GLboolean __WGLEW_NV_multisample_coverage; +WGLEW_EXPORT GLboolean __WGLEW_NV_present_video; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_depth_texture; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_NV_swap_group; +WGLEW_EXPORT GLboolean __WGLEW_NV_vertex_array_range; +WGLEW_EXPORT GLboolean __WGLEW_NV_video_capture; +WGLEW_EXPORT GLboolean __WGLEW_NV_video_output; +WGLEW_EXPORT GLboolean __WGLEW_OML_sync_control; + +#ifdef GLEW_MX +}; /* WGLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX + +typedef struct WGLEWContextStruct WGLEWContext; +GLEWAPI GLenum wglewContextInit (WGLEWContext* ctx); +GLEWAPI GLboolean wglewContextIsSupported (const WGLEWContext* ctx, const char* name); + +#define wglewInit() wglewContextInit(wglewGetContext()) +#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x) + +#define WGLEW_GET_VAR(x) (*(const GLboolean*)&(wglewGetContext()->x)) +#define WGLEW_GET_FUN(x) wglewGetContext()->x + +#else /* GLEW_MX */ + +#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define WGLEW_GET_FUN(x) x + +GLEWAPI GLboolean wglewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean wglewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#undef GLEWAPI + +#endif /* __wglew_h__ */ diff --git a/Glut/GL/wglext.h b/Glut/GL/wglext.h new file mode 100644 index 0000000..8c6192c --- /dev/null +++ b/Glut/GL/wglext.h @@ -0,0 +1,466 @@ +#ifndef __wglext_h_ +#define __wglext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif + +/*************************************************************/ + +/* Header file version number */ +#define WGL_WGLEXT_VERSION 1 + +#ifndef WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_extensions_string +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + +#ifndef WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_unknown_genlock_extension_name +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_unknown_gamma_extension_name +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_unknown_digital_video_cursor_extension_name +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + + +/*************************************************************/ + +#ifndef WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#endif +#ifndef WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#endif + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); +extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); +extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); +extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringARB (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCARB (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); +extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); +extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); +extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); +extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); +extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); +extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#endif + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); +extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); +extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); +extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglSwapIntervalEXT (int); +extern int WINAPI wglGetSwapIntervalEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#endif + +#ifndef WGL_WGL_EXT_depth_float +#define WGL_WGL_EXT_depth_float 1 +#endif + +#ifndef WGL_WGL_3DFX_multisample +#define WGL_WGL_3DFX_multisample 1 +#endif + +#ifndef WGL_WGL_EXT_multisample +#define WGL_WGL_EXT_multisample 1 +#endif + +/* added by Cass -- but this should already be in here! */ +#ifndef WGL_NV_allocate_memory +#define WGL_NV_allocate_memory 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern void * wglAllocateMemoryNV(int size, float readfreq, float writefreq, float priority); +extern void wglFreeMemoryNV(void * pointer); +#endif +typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority); +typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#endif + +/* WGL_ARB_render_texture */ +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int * piAttribList); +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/Glut/btGlutInclude.h b/Glut/btGlutInclude.h new file mode 100644 index 0000000..d79cb56 --- /dev/null +++ b/Glut/btGlutInclude.h @@ -0,0 +1,43 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_GLUT_INCLUDE_H +#define BT_GLUT_INCLUDE_H + + +#ifdef _WIN32//for glut.h +#include +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#include +#else + + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif //_WINDOWS +#endif //APPLE + +#endif //BT_GLUT_INCLUDE_H diff --git a/Glut/glew32s.lib b/Glut/glew32s.lib new file mode 100644 index 0000000000000000000000000000000000000000..eb2d718e0f45203b49244f4df3f446334cf0f89c GIT binary patch literal 1288450 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 !?fvm4KiCjbNnN(`zHX;ES##71Y~~GnA){ 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 literal 0 HcmV?d00001 diff --git a/Glut/glew64s.lib b/Glut/glew64s.lib new file mode 100644 index 0000000000000000000000000000000000000000..e9b15a6823bcf68d247d1b0347ec8375a9511db9 GIT binary patch literal 1378464 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νQ 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 literal 0 HcmV?d00001 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..0f42fb5 --- /dev/null +++ b/INSTALL @@ -0,0 +1,111 @@ +Bullet Collision Detection and Physics Library + +See also http://bulletphysics.org/mediawiki-1.5.8/index.php/Creating_a_project_from_scratch + +** Windows Compilation ** + + Open the Microsoft Visual Studio solution in msvc/20xx/BULLET_PHYSICS.sln + +Alternatively, use CMake to autogenerate a build system for Windows: + + - Download/install CMake from www.cmake.org or package manager + - Use cmake-gui or + - List available build systems by running 'cmake' in the Bullet root folder + - Use cmake-gui + - Create a build system using the -G option for example: + + cmake . -G "Visual Studio 9 2008" or + cmake . -G "Visual Studio 9 2008 Win64" + + +** Linux Compilation ** + + - Download/install CMake from www.cmake.org or package manager + CMake is like autoconf in that it will create build scripts which are then + used for the actual compilation + + - List available build systems by running 'cmake' in the Bullet root folder + - Create a build system using the -G option for example: + + cmake . -G "Unix Makefiles" + + - There are some options for cmake builds: + BUILD_SHARED_LIBS: default 'OFF', set to 'ON' to build .so libraries + BUILD_EXTRAS: default 'ON', compiles additional libraries in 'Extras' + BUILD_DEMOS: default 'ON', compiles applications found in 'Demos' + CMAKE_INSTALL_PREFIX: default '/usr/local', the installation path. + CMAKE_INSTALL_RPATH: if you install outside a standard ld search path, + then you should set this to the installation lib path. + CMAKE_BUILD_TYPE: default 'Release', can include debug symbols with + either 'Debug' or 'RelWithDebInfo'. + Other options may be discovered by 'cmake --help-variable-list' and + 'cmake --help-variable OPTION' + + - Run 'cmake' with desired options of the form -DOPTION=VALUE + By default this will create the usual Makefile build system, but CMake can + also produce Eclipse or KDevelop project files. See 'cmake --help' to see + what "generators" are available in your environment, selected via '-G'. + For example: + cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=RelWithDebugInfo + + - Assuming using the default Makefile output from cmake, run 'make' to + build, and then 'make install' if you wish to install. + + +** Mac OS X Compilation ** + + - Download/install CMake from www.cmake.org or package manager + CMake is like autoconf in that it will create build scripts which are then + used for the actual compilation + + - List available build systems by running 'cmake' in the Bullet root folder + - Create a build system using the -G option for example: + + cmake . -G Xcode + cmake . -G "Unix Makefiles" + + - There are some options for cmake builds: + BUILD_SHARED_LIBS: default 'OFF', set to 'ON' to build .dylib libraries + BUILD_EXTRAS: default 'ON', compiles additional libraries in 'Extras' + BUILD_DEMOS: default 'ON', compiles applications found in 'Demos' + CMAKE_INSTALL_PREFIX: default '/usr/local', the installation path. + CMAKE_INSTALL_NAME_DIR: if you install outside a standard ld search + path, then you should set this to the installation lib/framework path. + CMAKE_OSX_ARCHITECTURES: defaults to the native architecture, but can be + set to a semicolon separated list for fat binaries, e.g. ppc;i386;x86_64 + CMAKE_BUILD_TYPE: default 'Release', can include debug symbols with + either 'Debug' or 'RelWithDebInfo'. + + To build framework bundles: + FRAMEWORK: default 'OFF', also requires 'BUILD_SHARED_LIBS' set ON + If both FRAMEWORK and BUILD_SHARED_LIBS are set, will create + OS X style Framework Bundles which can be placed in + linked via the -framework gcc argument or drag into Xcode projects. + (If not framework, then UNIX style 'include' and 'lib' will be produced) + + Other options may be discovered by 'cmake --help-variable-list' and + 'cmake --help-variable OPTION' + + - Run 'cmake' with desired options of the form -DOPTION=VALUE + By default this will create the usual Makefile build system, but CMake can + also produce Eclipse or KDevelop project files. See 'cmake --help' to see + what "generators" are available in your environment, selected via '-G'. + For example: + cmake -DBUILD_SHARED_LIBS=ON -DFRAMEWORK=ON \ + -DCMAKE_INSTALL_PREFIX=/Library/Frameworks \ + -DCMAKE_INSTALL_NAME_DIR=/Library/Frameworks \ + -DCMAKE_OSX_ARCHITECTURES='ppc;i386;x86_64' \ + -DCMAKE_BUILD_TYPE=RelWithDebugInfo + + - Assuming using the default Makefile output from cmake, run 'make' to build + and then 'make install'. + + +** Alternative Mac OS X and Linux via autoconf/make ** + - at the command line: + ./autogen.sh + ./configure + make + + +** For more help, visit http://www.bulletphysics.org ** diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..a9b97a8 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,7 @@ +if CONDITIONAL_BUILD_DEMOS +SUBDIRS=src Extras Demos +else +SUBDIRS=src +endif +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = bullet.pc diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..fa8442e --- /dev/null +++ b/Makefile.in @@ -0,0 +1,776 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/bullet.pc.in \ + $(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \ + ChangeLog INSTALL NEWS compile config.guess config.sub depcomp \ + install-sh ltmain.sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = bullet.pc +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = src Extras Demos +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@CONDITIONAL_BUILD_DEMOS_FALSE@SUBDIRS = src +@CONDITIONAL_BUILD_DEMOS_TRUE@SUBDIRS = src Extras Demos +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = bullet.pc +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +bullet.pc: $(top_builddir)/config.status $(srcdir)/bullet.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkgconfigDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-pkgconfigDATA + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..dec9f0f --- /dev/null +++ b/NEWS @@ -0,0 +1,5 @@ + +For news, visit the Bullet Physics forums at +http://www.bulletphysics.org and http://bullet.googlecode.com + + diff --git a/README b/README new file mode 100644 index 0000000..1eda762 --- /dev/null +++ b/README @@ -0,0 +1,6 @@ + +Bullet is a 3D Collision Detection and Rigid Body Dynamics Library for games and animation. +Free for commercial use, including Playstation 3, open source under the ZLib License. + +See the Bullet_User_Manual.pdf for more info and visit the Bullet Physics Forum at +http://bulletphysics.org diff --git a/RELEASING.TXT b/RELEASING.TXT new file mode 100644 index 0000000..8fba4a5 --- /dev/null +++ b/RELEASING.TXT @@ -0,0 +1,34 @@ +This document details the steps necessary to package a release of Bullet. + +1) Preparing for release: + +update VERSION in several places +update ChangeLog +regenerate MSVC project files + +2) Generating the release .zip: +Do an SVN export on a Windows machine into the directory: bullet-X.YY +prepare a zip file containing the directory + +3) Generating the release .tar.gz: +Do an SVN export on a Unix machine into the directory: bullet-X.YY +prepare a .tar.gz file containing the directory + +4) Uploading release to google code: + +Google Code Bullet downloads URL: http://code.google.com/p/bullet/downloads/list + +Title of release should follow this guide line: Bullet Physics SDK (revision) + +It is better to upload the .tar.gz before the .zip so that the .zip appears first in the list + +If the release is an Alpha/Beta or RC the tags should be: Type-Source, OpSys-ALL +If the release is a final release the tags should be: Type-Source, OpSys-ALL, Featured + +5) Obsoleting old releases + +Edit the tags on old releases and add the 'Deprecated' tag + +6) Announcing final releases: + +Final release announcements are done here: http://bulletphysics.com/Bullet/phpBB3/viewforum.php?f=18 diff --git a/Test/Info.plist b/Test/Info.plist new file mode 100644 index 0000000..4785b60 --- /dev/null +++ b/Test/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + CFBundleIdentifier + Apple.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Test/README.txt b/Test/README.txt new file mode 100644 index 0000000..c231a54 --- /dev/null +++ b/Test/README.txt @@ -0,0 +1,28 @@ +1) Add a .cpp and .h file for your test function. The function should conform to: + + #ifdef __cplusplus + extern "C" { + #endif + + #include "Utils.h" + #include "main.h" + #include "vector.h" + + // Your test function + int MyTestFunc(void); + + #ifdef __cplusplus + } + #endif + + The rest of the program doesn't care or know what you do in MyTestFunc, except that MyTestFunc should return non-zero in case of failure in MyTestFunc. There are some handy functions in Utils.h that you might want to use. Please use vlog instead of printf to print stuff, and random_number32/64() in place of rand(), so I can multithread later if it comes to that. There are some read-only globals that you may wish to respond to, declared in Utils.h: + + gReportAverageTimes if you do timing, report times as averages instead of best times if non-zero + gExitOnError if non-zero, return non-zero immediately if you encounter an error + gAppName (const char*) the name of the application + + As a convenience, vector.h has some cross platform vector types declared and will correctly include various vector headers according to compiler flag. + + +2) Add an entry to gTestList in TestList.cpp for your test function, so the rest of the app knows to call it + diff --git a/Test/Source/TestList.cpp b/Test/Source/TestList.cpp new file mode 100644 index 0000000..7e342b1 --- /dev/null +++ b/Test/Source/TestList.cpp @@ -0,0 +1,97 @@ +// +// TestList.c +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#include +#include "TestList.h" + +#include "Test_qtmul.h" +#include "Test_qtmulQV3.h" +#include "Test_qtmulV3Q.h" +#include "Test_qtdot.h" +#include "Test_qtnorm.h" + +#include "Test_v3dot.h" +#include "Test_v3sdiv.h" +#include "Test_v3norm.h" +#include "Test_v3cross.h" +#include "Test_v3triple.h" +#include "Test_v3interp.h" +#include "Test_v3lerp.h" +#include "Test_v3skew.h" +#include "Test_v3div.h" +#include "Test_v3rotate.h" + +#include "Test_maxdot.h" +#include "Test_mindot.h" +#include "Test_dot3.h" +#include "Test_3x3transpose.h" +#include "Test_3x3transposeTimes.h" +#include "Test_3x3timesTranspose.h" +#include "Test_3x3mulM.h" +#include "Test_3x3mulM1M2.h" +#include "Test_3x3mulMV.h" +#include "Test_3x3mulVM.h" +#include "Test_3x3setRot.h" +#include "Test_3x3getRot.h" + +#include "Test_btDbvt.h" +#include "Test_quat_aos_neon.h" + +#include "LinearMath/btScalar.h" +#define ENTRY( _name, _func ) { _name, _func } + +// +// Test functions have the form int (*TestFunc)( void ) +// They return a non-zero result in case of failure. +// +// Please see handy stuff in Utils.h, vector.h when writing your test code. +// +#if defined (BT_USE_NEON) || defined (BT_USE_SSE_IN_API) + +TestDesc gTestList[] = +{ + ENTRY( "maxdot", Test_maxdot ), + ENTRY( "mindot", Test_mindot ), + + ENTRY( "qtmul", Test_qtmul ), + ENTRY( "qtmulQV3", Test_qtmulQV3 ), + ENTRY( "qtmulV3Q", Test_qtmulV3Q ), + ENTRY( "qtdot", Test_qtdot ), + ENTRY( "qtnorm", Test_qtnorm ), + + ENTRY( "v3dot", Test_v3dot ), + ENTRY( "v3sdiv", Test_v3sdiv ), + ENTRY( "v3norm", Test_v3norm ), + ENTRY( "v3cross", Test_v3cross ), + ENTRY( "v3triple", Test_v3triple ), + ENTRY( "v3interp", Test_v3interp ), + ENTRY( "v3lerp", Test_v3lerp ), + ENTRY( "v3skew", Test_v3skew ), + ENTRY( "v3div", Test_v3div ), + ENTRY( "v3rotate", Test_v3rotate ), + + ENTRY( "dot3", Test_dot3 ), + ENTRY( "3x3transpose", Test_3x3transpose ), + ENTRY( "3x3transposeTimes", Test_3x3transposeTimes ), + ENTRY( "3x3timesTranspose", Test_3x3timesTranspose ), + ENTRY( "3x3mulM", Test_3x3mulM ), + ENTRY( "3x3mulM1M2", Test_3x3mulM1M2 ), + ENTRY( "3x3mulMV", Test_3x3mulMV ), + ENTRY( "3x3mulVM", Test_3x3mulMV ), + ENTRY( "3x3setRot", Test_3x3setRot ), + ENTRY( "3x3getRot", Test_3x3getRot ), + + ENTRY( "btDbvt", Test_btDbvt ), + ENTRY("quat_aos_neon", Test_quat_aos_neon), + + { NULL, NULL } +}; +#else +TestDesc gTestList[]={{NULL,NULL}}; + +#endif + diff --git a/Test/Source/TestList.h b/Test/Source/TestList.h new file mode 100644 index 0000000..f66d4c6 --- /dev/null +++ b/Test/Source/TestList.h @@ -0,0 +1,28 @@ +// +// TestList.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_TestList_h +#define BulletTest_TestList_h + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct TestDesc +{ + const char *name; + int (*test_func)(void); // return 0 for success, non-zero for failure +}TestDesc; + +extern TestDesc gTestList[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Test/Source/Tests/Test_3x3getRot.cpp b/Test/Source/Tests/Test_3x3getRot.cpp new file mode 100644 index 0000000..dbf2241 --- /dev/null +++ b/Test/Source/Tests/Test_3x3getRot.cpp @@ -0,0 +1,158 @@ +// +// Test_3x3getRot.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_3x3getRot.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN +} + +static inline btSimdFloat4 qtNAN_f4(void) +{ + return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN ); +} + +static void M3x3getRot_ref( const btMatrix3x3 &m, btQuaternion &q ) +{ + btVector3 m_el[3] = { m[0], m[1], m[2] }; + + btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); + + btScalar temp[4]; + + if (trace > btScalar(0.0)) + { + btScalar s = btSqrt(trace + btScalar(1.0)); + temp[3]=(s * btScalar(0.5)); + s = btScalar(0.5) / s; + + temp[0]=((m_el[2].y() - m_el[1].z()) * s); + temp[1]=((m_el[0].z() - m_el[2].x()) * s); + temp[2]=((m_el[1].x() - m_el[0].y()) * s); + } + else + { + int i = m_el[0].x() < m_el[1].y() ? + (m_el[1].y() < m_el[2].z() ? 2 : 1) : + (m_el[0].x() < m_el[2].z() ? 2 : 0); + int j = (i + 1) % 3; + int k = (i + 2) % 3; + + btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); + temp[i] = s * btScalar(0.5); + s = btScalar(0.5) / s; + + temp[3] = (m_el[k][j] - m_el[j][k]) * s; + temp[j] = (m_el[j][i] + m_el[i][j]) * s; + temp[k] = (m_el[k][i] + m_el[i][k]) * s; + } + q.setValue(temp[0],temp[1],temp[2],temp[3]); +} + +static int operator!= ( const btQuaternion &a, const btQuaternion &b ) +{ + if( fabs(a.x() - b.x()) + + fabs(a.y() - b.y()) + + fabs(a.z() - b.z()) + + fabs(a.w() - b.w()) > FLT_EPSILON * 4) + return 1; + + return 0; +} + +int Test_3x3getRot(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btQuaternion out[ARRAY_SIZE]; + btQuaternion out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + out[i] = btQuaternion(qtNAN_f4()); + out2[i] = btQuaternion(qtNAN_f4()); + + M3x3getRot_ref(in1[i], out[i]); + in1[i].getRotation(out2[i]); + + if( out[i] != out2[i] ) + { + vlog( "Error - M3x3getRot result error! "); + vlog( "failure @ %ld\n", i); + vlog( "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) \n", + out[i].x(), out[i].y(), out[i].z(), out[i].w(), + out2[i].x(), out2[i].y(), out2[i].z(), out2[i].w()); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = ~(bestTime&0);//-1ULL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + M3x3getRot_ref(in1[i], out[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = ~(bestTime&0);//-1ULL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i].getRotation(out2[i]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} + +#endif//BT_USE_SSE diff --git a/Test/Source/Tests/Test_3x3getRot.h b/Test/Source/Tests/Test_3x3getRot.h new file mode 100644 index 0000000..1998763 --- /dev/null +++ b/Test/Source/Tests/Test_3x3getRot.h @@ -0,0 +1,22 @@ +// +// Test_3x3getRot.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3getRot_h +#define BulletTest_Test_3x3getRot_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3getRot(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_3x3mulM.cpp b/Test/Source/Tests/Test_3x3mulM.cpp new file mode 100644 index 0000000..51a013e --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulM.cpp @@ -0,0 +1,169 @@ +// +// Test_3x3mulM.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_3x3mulM.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN +} + +static btMatrix3x3 M3x3mulM_ref( btMatrix3x3 &in, const btMatrix3x3 &m ) +{ + btVector3 m_el[3] = { in[0], in[1], in[2] }; + + in.setValue( + m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), + m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), + m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); + + return in; +} + +static SIMD_FORCE_INLINE bool fuzzyEqualSlow(const btVector3& ref, const btVector3& other) +{ + const btScalar epsilon = SIMD_EPSILON; + return ((btFabs(ref.m_floats[3]-other.m_floats[3])<=epsilon) && + (btFabs(ref.m_floats[2]-other.m_floats[2])<=epsilon) && + (btFabs(ref.m_floats[1]-other.m_floats[1])<=epsilon) && + (btFabs(ref.m_floats[0]-other.m_floats[0])<=epsilon)); +} + + +static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +{ + if( a.getRow(0) != b.getRow(0) ) + { + if (!fuzzyEqualSlow(a.getRow(0),b.getRow(0))) + { + return 1; + } + } + if( a.getRow(1) != b.getRow(1) ) + { + if( !fuzzyEqualSlow(a.getRow(1),b.getRow(1)) ) + return 1; + } + if( a.getRow(2) != b.getRow(2) ) + { + if( !fuzzyEqualSlow(a.getRow(2),b.getRow(2)) ) + { + return 1; + } + } + return 0; +} + +int Test_3x3mulM(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 in3[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + in3[i] = in1[i]; + + out[i] = M3x3mulM_ref(in1[i], in2[i]); + out2[i] = (in3[i] *= in2[i]); + + if( out[i] != out2[i] ) + { + vlog( "Error - M3x3mulM result error! "); + vlog( "failure @ %ld\n", i); + btVector3 m0, m1, m2; + m0 = out[i].getRow(0); + m1 = out[i].getRow(1); + m2 = out[i].getRow(2); + + vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + m0 = out2[i].getRow(0); + m1 = out2[i].getRow(1); + m2 = out2[i].getRow(2); + + vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = M3x3mulM_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out2[i] = (in3[i] *= in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_3x3mulM.h b/Test/Source/Tests/Test_3x3mulM.h new file mode 100644 index 0000000..fb5128e --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulM.h @@ -0,0 +1,22 @@ +// +// Test_3x3mulM.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3mulM_h +#define BulletTest_Test_3x3mulM_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3mulM(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_3x3mulM1M2.cpp b/Test/Source/Tests/Test_3x3mulM1M2.cpp new file mode 100644 index 0000000..c435c54 --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulM1M2.cpp @@ -0,0 +1,164 @@ +// +// Test_3x3mulM1M2.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_3x3mulM1M2.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN +} + +static btMatrix3x3 M3x3mulM1M2_ref( const btMatrix3x3 &m1, const btMatrix3x3 &m2 ) +{ + return btMatrix3x3( + m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]), + m2.tdotx(m1[1]), m2.tdoty(m1[1]), m2.tdotz(m1[1]), + m2.tdotx(m1[2]), m2.tdoty(m1[2]), m2.tdotz(m1[2])); +} + +static bool fuzzyEqualSlow(const btVector3& ref, const btVector3& other) +{ + const btScalar epsilon = SIMD_EPSILON; + return ((btFabs(ref.m_floats[3]-other.m_floats[3])<=epsilon) && + (btFabs(ref.m_floats[2]-other.m_floats[2])<=epsilon) && + (btFabs(ref.m_floats[1]-other.m_floats[1])<=epsilon) && + (btFabs(ref.m_floats[0]-other.m_floats[0])<=epsilon)); +} + + +static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +{ + if( a.getRow(0) != b.getRow(0) ) + { + if (!fuzzyEqualSlow(a.getRow(0),b.getRow(0))) + { + return 1; + } + } + if( a.getRow(1) != b.getRow(1) ) + { + if( !fuzzyEqualSlow(a.getRow(1),b.getRow(1)) ) + return 1; + } + if( a.getRow(2) != b.getRow(2) ) + { + if( !fuzzyEqualSlow(a.getRow(2),b.getRow(2)) ) + { + return 1; + } + } + return 0; +} + +int Test_3x3mulM1M2(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + + out[i] = M3x3mulM1M2_ref(in1[i], in2[i]); + out2[i] = (in1[i] * in2[i]); + + if( out[i] != out2[i] ) + { + vlog( "Error - M3x3mulM1M2 result error! "); + vlog( "failure @ %ld\n", i); + btVector3 m0, m1, m2; + m0 = out[i].getRow(0); + m1 = out[i].getRow(1); + m2 = out[i].getRow(2); + + vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + m0 = out2[i].getRow(0); + m1 = out2[i].getRow(1); + m2 = out2[i].getRow(2); + + vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = M3x3mulM1M2_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out2[i] = (in1[i] * in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_3x3mulM1M2.h b/Test/Source/Tests/Test_3x3mulM1M2.h new file mode 100644 index 0000000..a3075bd --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulM1M2.h @@ -0,0 +1,22 @@ +// +// Test_3x3mulM1M2.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3mulM1M2_h +#define BulletTest_Test_3x3mulM1M2_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3mulM1M2(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_3x3mulMV.cpp b/Test/Source/Tests/Test_3x3mulMV.cpp new file mode 100644 index 0000000..ba07831 --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulMV.cpp @@ -0,0 +1,112 @@ +// +// Test_3x3mulMV.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_3x3mulMV.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN +} + +static btVector3 M3x3mulMV_ref( const btMatrix3x3 &m, const btVector3 &v ) +{ + return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); +} + +int Test_3x3mulMV(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btVector3 in2[ARRAY_SIZE]; + btVector3 out[ARRAY_SIZE]; + btVector3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + in2[i] = btVector3(rand_f4()); + + out[i] = M3x3mulMV_ref(in1[i], in2[i]); + out2[i] = (in1[i] * in2[i]); + + if( fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) + + fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) + + fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) + + fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > FLT_EPSILON*4 ) + { + vlog( "Error - M3x3mulMV result error! "); + vlog( "failure @ %ld\n", i); + vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3], + out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]); + + return 1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = M3x3mulMV_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out2[i] = (in1[i] * in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_3x3mulMV.h b/Test/Source/Tests/Test_3x3mulMV.h new file mode 100644 index 0000000..877380d --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulMV.h @@ -0,0 +1,23 @@ +// +// Test_3x3mulMV.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3mulMV_h +#define BulletTest_Test_3x3mulMV_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3mulMV(void); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/Test/Source/Tests/Test_3x3mulVM.cpp b/Test/Source/Tests/Test_3x3mulVM.cpp new file mode 100644 index 0000000..86db895 --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulVM.cpp @@ -0,0 +1,112 @@ +// +// Test_3x3mulVM.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_3x3mulVM.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN +} + +static btVector3 M3x3mulVM_ref( const btVector3 &v, const btMatrix3x3 &m) +{ + return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); +} + +int Test_3x3mulVM(void) +{ + // Init an array flanked by guard pages + btVector3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btVector3 out[ARRAY_SIZE]; + btVector3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btVector3(rand_f4()); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + + out[i] = M3x3mulVM_ref(in1[i], in2[i]); + out2[i] = (in1[i] * in2[i]); + + if( fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) + + fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) + + fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) + + fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > FLT_EPSILON*4 ) + { + vlog( "Error - M3x3mulVM result error! "); + vlog( "failure @ %ld\n", i); + vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3], + out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]); + + return 1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = M3x3mulVM_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out2[i] = (in1[i] * in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_3x3mulVM.h b/Test/Source/Tests/Test_3x3mulVM.h new file mode 100644 index 0000000..81c34df --- /dev/null +++ b/Test/Source/Tests/Test_3x3mulVM.h @@ -0,0 +1,22 @@ +// +// Test_3x3mulVM.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3mulVM_h +#define BulletTest_Test_3x3mulVM_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3mulVM(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_3x3setRot.cpp b/Test/Source/Tests/Test_3x3setRot.cpp new file mode 100644 index 0000000..49f1775 --- /dev/null +++ b/Test/Source/Tests/Test_3x3setRot.cpp @@ -0,0 +1,171 @@ +// +// Test_3x3setRot.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_3x3setRot.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN +} + +static inline btSimdFloat4 qtrand_f4(void) +{ + return btAssign128( RANDF_01, RANDF_01, RANDF_01, RANDF_01 ); +} + +static btMatrix3x3 M3x3setRot_ref( btMatrix3x3 &m, const btQuaternion &q ) +{ + btScalar d = q.length2(); + btScalar s = btScalar(2.0) / d; + + btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; + + btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; + btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; + btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; + m.setValue( + btScalar(1.0) - (yy + zz), xy - wz, xz + wy, + xy + wz, btScalar(1.0) - (xx + zz), yz - wx, + xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); + + return m; +} + + +static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +{ + int i; + btVector3 av3, bv3; + + for(i=0; i<3; i++) + { + av3 = a.getRow(i); + bv3 = b.getRow(i); + + if( fabs(av3.m_floats[0] - bv3.m_floats[0]) + + fabs(av3.m_floats[1] - bv3.m_floats[1]) + + fabs(av3.m_floats[2] - bv3.m_floats[2]) > FLT_EPSILON * 4) + return 1; + } + + return 0; +} + +int Test_3x3setRot(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btQuaternion in2[ARRAY_SIZE]; + btMatrix3x3 in3[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + in2[i] = btQuaternion(qtrand_f4()); + in3[i] = in1[i]; + + out[i] = M3x3setRot_ref(in1[i], in2[i]); + in3[i].setRotation(in2[i]); + out2[i] = in3[i]; + + if( out[i] != out2[i] ) + { + vlog( "Error - M3x3setRot result error! "); + vlog( "failure @ %ld\n", i); + btVector3 m0, m1, m2; + m0 = out[i].getRow(0); + m1 = out[i].getRow(1); + m2 = out[i].getRow(2); + + vlog( "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + m0 = out2[i].getRow(0); + m1 = out2[i].getRow(1); + m2 = out2[i].getRow(2); + + vlog( "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = M3x3setRot_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in3[i].setRotation(in2[i]); + out2[i] = in3[i]; + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} +#endif //BT_USE_SSE + diff --git a/Test/Source/Tests/Test_3x3setRot.h b/Test/Source/Tests/Test_3x3setRot.h new file mode 100644 index 0000000..aac0ebf --- /dev/null +++ b/Test/Source/Tests/Test_3x3setRot.h @@ -0,0 +1,22 @@ +// +// Test_3x3setRot.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3setRot_h +#define BulletTest_Test_3x3setRot_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3setRot(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_3x3timesTranspose.cpp b/Test/Source/Tests/Test_3x3timesTranspose.cpp new file mode 100644 index 0000000..70e12e4 --- /dev/null +++ b/Test/Source/Tests/Test_3x3timesTranspose.cpp @@ -0,0 +1,117 @@ +// +// Test_3x3timesTranspose.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_3x3timesTranspose.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF, RANDF, RANDF, BT_NAN ); // w channel NaN +} + +static btMatrix3x3 timesTranspose( const btMatrix3x3 &in, const btMatrix3x3 &m ) +{ + btVector3 m_el[3] = { in[0], in[1], in[2] }; + return btMatrix3x3( + m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), + m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]), + m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2])); +} + +static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +{ + if( a.getRow(0) != b.getRow(0) ) + return 1; + if( a.getRow(1) != b.getRow(1) ) + return 1; + if( a.getRow(2) != b.getRow(2) ) + return 1; + return 0; +} + +int Test_3x3timesTranspose(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + + out[i] = timesTranspose(in1[i], in2[i]); + out2[i] = in1[i].timesTranspose(in2[i]); + + if( out[i] != out2[i] ) + { + printf( "failure @ %ld\n", i); + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = timesTranspose(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = in1[i].timesTranspose(in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_3x3timesTranspose.h b/Test/Source/Tests/Test_3x3timesTranspose.h new file mode 100644 index 0000000..a1c396b --- /dev/null +++ b/Test/Source/Tests/Test_3x3timesTranspose.h @@ -0,0 +1,22 @@ +// +// Test_3x3timesTranspose.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3timesTranspose_h +#define BulletTest_Test_3x3timesTranspose_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3timesTranspose(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_3x3transpose.cpp b/Test/Source/Tests/Test_3x3transpose.cpp new file mode 100644 index 0000000..c85333f --- /dev/null +++ b/Test/Source/Tests/Test_3x3transpose.cpp @@ -0,0 +1,116 @@ +// +// Test_3x3transpose.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_3x3transpose.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 1024 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF, RANDF, RANDF, BT_NAN ); // w channel NaN +} + +static btMatrix3x3 Transpose( btMatrix3x3 &in ) +{ + btVector3 row0 = in.getRow(0); + btVector3 row1 = in.getRow(1); + btVector3 row2 = in.getRow(2); + btVector3 col0 = btAssign128(row0.x(), row1.x(), row2.x(), 0 ); + btVector3 col1 = btAssign128(row0.y(), row1.y(), row2.y(), 0 ); + btVector3 col2 = btAssign128(row0.z(), row1.z(), row2.z(), 0); + return btMatrix3x3( col0, col1, col2); +} + +static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +{ + if( a.getRow(0) != b.getRow(0) ) + return 1; + if( a.getRow(1) != b.getRow(1) ) + return 1; + if( a.getRow(2) != b.getRow(2) ) + return 1; + return 0; +} + +int Test_3x3transpose(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + + out[i] = Transpose(in[i]); + out2[i] = in[i].transpose(); + + if( out[i] != out2[i] ) + { + printf( "failure @ %ld\n", i); + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = Transpose(in[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = in[i].transpose(); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} +#endif //BT_USE_SSE + diff --git a/Test/Source/Tests/Test_3x3transpose.h b/Test/Source/Tests/Test_3x3transpose.h new file mode 100644 index 0000000..3c4b834 --- /dev/null +++ b/Test/Source/Tests/Test_3x3transpose.h @@ -0,0 +1,22 @@ +// +// Test_3x3transpose.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3transpose_h +#define BulletTest_Test_3x3transpose_h + +#ifdef __cplusplus +extern "C" { +#endif + + int Test_3x3transpose(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_3x3transposeTimes.cpp b/Test/Source/Tests/Test_3x3transposeTimes.cpp new file mode 100644 index 0000000..5f14caf --- /dev/null +++ b/Test/Source/Tests/Test_3x3transposeTimes.cpp @@ -0,0 +1,168 @@ +// +// Test_3x3transposeTimes.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_3x3transposeTimes.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define LOOPCOUNT 1000 +#define ARRAY_SIZE 128 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN +} + +static btMatrix3x3 TransposeTimesReference( const btMatrix3x3 &in, const btMatrix3x3 &m ) +{ + btVector3 m_el[3] = { in[0], in[1], in[2] }; + btSimdFloat4 r0 = btAssign128(m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), + m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), + m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), + 0.0f ); + btSimdFloat4 r1 = btAssign128( m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(), + m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(), + m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), + 0.0f ); + btSimdFloat4 r2 = btAssign128( m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), + m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), + m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z(), + 0.0f ); + return btMatrix3x3( r0, r1, r2 ); +} + +static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +{ + if( a.getRow(0) != b.getRow(0) ) + return 1; + if( a.getRow(1) != b.getRow(1) ) + return 1; + if( a.getRow(2) != b.getRow(2) ) + return 1; + return 0; +} + +int Test_3x3transposeTimes(void) +{ + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + + float maxRelativeError = 0.f; + // Init the data + size_t i, j; + for( i = 0; i < ARRAY_SIZE; i++ ) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); + + out[i] = TransposeTimesReference(in1[i], in2[i]); + out2[i] = in1[i].transposeTimes(in2[i]); + + if( out[i] != out2[i] ) + { + + float relativeError = 0.f; + + for (int column=0;column<3;column++) + for (int row=0;row<3;row++) + relativeError = btMax(relativeError,btFabs(out2[i][row][column] - out[i][row][column]) / out[i][row][column]); + + if (relativeError>1e-6) + { + vlog( "failure @ %ld\n", i); + btVector3 m0, m1, m2; + m0 = out[i].getRow(0); + m1 = out[i].getRow(1); + m2 = out[i].getRow(2); + + vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + m0 = out2[i].getRow(0); + m1 = out2[i].getRow(1); + m2 = out2[i].getRow(2); + + vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + return -1; + } else + { + if (relativeError>maxRelativeError) + maxRelativeError = relativeError; + } + } + } + + if (maxRelativeError) + { + printf("Warning: maxRelativeError = %e\n",maxRelativeError); + } + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = TransposeTimesReference(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) { + startTime = ReadTicks(); + for( i = 0; i < ARRAY_SIZE; i++ ) + out[i] = in1[i].transposeTimes(in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog( "Timing:\n" ); + vlog( "\t scalar\t vector\n" ); + vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); + + return 0; +} + +#endif //BT_USE_SSE + diff --git a/Test/Source/Tests/Test_3x3transposeTimes.h b/Test/Source/Tests/Test_3x3transposeTimes.h new file mode 100644 index 0000000..08af2e1 --- /dev/null +++ b/Test/Source/Tests/Test_3x3transposeTimes.h @@ -0,0 +1,22 @@ +// +// Test_3x3transposeTimes.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_3x3transposeTimes_h +#define BulletTest_Test_3x3transposeTimes_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_3x3transposeTimes(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_btDbvt.cpp b/Test/Source/Tests/Test_btDbvt.cpp new file mode 100644 index 0000000..96ce525 --- /dev/null +++ b/Test/Source/Tests/Test_btDbvt.cpp @@ -0,0 +1,495 @@ +// +// Test_btDbvt.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc., Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_btDbvt.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +SIMD_FORCE_INLINE bool Intersect_ref( btDbvtAabbMm& a, btDbvtAabbMm& b) +{ + return( (a.tMins().x()<=b.tMaxs().x())&& + (a.tMaxs().x()>=b.tMins().x())&& + (a.tMins().y()<=b.tMaxs().y())&& + (a.tMaxs().y()>=b.tMins().y())&& + (a.tMins().z()<=b.tMaxs().z())&& + (a.tMaxs().z()>=b.tMins().z())); + + } + + +SIMD_FORCE_INLINE btScalar Proximity_ref( btDbvtAabbMm& a, + btDbvtAabbMm& b) +{ + const btVector3 d=(a.tMins()+a.tMaxs())-(b.tMins()+b.tMaxs()); + return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z())); +} + + + +SIMD_FORCE_INLINE int Select_ref( btDbvtAabbMm& o, + btDbvtAabbMm& a, + btDbvtAabbMm& b) +{ + return(Proximity_ref(o,a)b.tMaxs().m_floats[i]) + r.tMaxs().m_floats[i]=a.tMaxs().m_floats[i]; + else + r.tMaxs().m_floats[i]=b.tMaxs().m_floats[i]; + } +} +/* +[0] float32_t 0.0318338 +[1] float32_t 0.0309355 +[2] float32_t 0.93264 +[3] float32_t 0.88788 + +[0] float32_t 0.59133 +[1] float32_t 0.478779 +[2] float32_t 0.833354 +[3] float32_t 0.186335 + +[0] float32_t 0.242578 +[1] float32_t 0.0134696 +[2] float32_t 0.383139 +[3] float32_t 0.414653 + +[0] float32_t 0.067769 +[1] float32_t 0.993127 +[2] float32_t 0.484308 +[3] float32_t 0.765338 +*/ + +#define LOOPCOUNT 1000 +#define NUM_CYCLES 10000 +#define DATA_SIZE 1024 + +int Test_btDbvt(void) +{ + btDbvtAabbMm a[DATA_SIZE], b[DATA_SIZE], c[DATA_SIZE]; + btDbvtAabbMm a_ref[DATA_SIZE], b_ref[DATA_SIZE], c_ref[DATA_SIZE]; + + int i; + + bool Intersect_Test_Res[DATA_SIZE], Intersect_Ref_Res[DATA_SIZE]; + int Select_Test_Res[DATA_SIZE], Select_Ref_Res[DATA_SIZE]; + + + for (i = 0; i < DATA_SIZE; i++) + { + a[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; + a[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; + a[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; + a[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; + + a[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; + a[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; + a[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; + a[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; + + b[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; + b[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; + b[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; + b[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; + + b[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; + b[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; + b[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; + b[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; + + c[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; + c[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; + c[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; + c[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; + + c[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; + c[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; + c[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; + c[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; + + + a_ref[i].tMins().m_floats[0] = a[i].tMins().m_floats[0]; + a_ref[i].tMins().m_floats[1] = a[i].tMins().m_floats[1]; + a_ref[i].tMins().m_floats[2] = a[i].tMins().m_floats[2]; + a_ref[i].tMins().m_floats[3] = a[i].tMins().m_floats[3]; + + a_ref[i].tMaxs().m_floats[0] = a[i].tMaxs().m_floats[0]; + a_ref[i].tMaxs().m_floats[1] = a[i].tMaxs().m_floats[1]; + a_ref[i].tMaxs().m_floats[2] = a[i].tMaxs().m_floats[2]; + a_ref[i].tMaxs().m_floats[3] = a[i].tMaxs().m_floats[3]; + + b_ref[i].tMins().m_floats[0] = b[i].tMins().m_floats[0]; + b_ref[i].tMins().m_floats[1] = b[i].tMins().m_floats[1]; + b_ref[i].tMins().m_floats[2] = b[i].tMins().m_floats[2]; + b_ref[i].tMins().m_floats[3] = b[i].tMins().m_floats[3]; + + b_ref[i].tMaxs().m_floats[0] = b[i].tMaxs().m_floats[0]; + b_ref[i].tMaxs().m_floats[1] = b[i].tMaxs().m_floats[1]; + b_ref[i].tMaxs().m_floats[2] = b[i].tMaxs().m_floats[2]; + b_ref[i].tMaxs().m_floats[3] = b[i].tMaxs().m_floats[3]; + + c_ref[i].tMins().m_floats[0] = c[i].tMins().m_floats[0]; + c_ref[i].tMins().m_floats[1] = c[i].tMins().m_floats[1]; + c_ref[i].tMins().m_floats[2] = c[i].tMins().m_floats[2]; + c_ref[i].tMins().m_floats[3] = c[i].tMins().m_floats[3]; + + c_ref[i].tMaxs().m_floats[0] = c[i].tMaxs().m_floats[0]; + c_ref[i].tMaxs().m_floats[1] = c[i].tMaxs().m_floats[1]; + c_ref[i].tMaxs().m_floats[2] = c[i].tMaxs().m_floats[2]; + c_ref[i].tMaxs().m_floats[3] = c[i].tMaxs().m_floats[3]; + + } + + +#if 1 + for (i = 0; i < DATA_SIZE; i++) + { + + Intersect_Test_Res[i] = Intersect(a[i], b[i]); + Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]); + + if(Intersect_Test_Res[i] != Intersect_Ref_Res[i]) + { + printf("Diff on %d\n", i); + + printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); + printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); + printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); + printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); + + printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); + printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); + printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); + printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); + } + } +#endif + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j; + + + //////////////////////////////////// + // + // Time and Test Intersect + // + //////////////////////////////////// + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + + for (i = 0; i < DATA_SIZE; i++) + { + Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]); + } + + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Intersect_Test_Res[i] = Intersect(a[i], b[i]); + } + + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Intersect Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + + //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); + + for (i = 0; i < DATA_SIZE; i++) + { + if(Intersect_Test_Res[i] != Intersect_Ref_Res[i]) + { + printf("Intersect fail at %d\n", i); + return 1; + } + } + + //////////////////////////////////// + // + // Time and Test Merge + // + //////////////////////////////////// + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + + for (i = 0; i < DATA_SIZE; i++) + { + Merge_ref(a_ref[i], b_ref[i], c_ref[i]); + } + + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Merge(a[i], b[i], c[i]); + } + + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Merge Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + + //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); + /* + c [0] float32_t 0.00455523 + [1] float32_t 0.559712 + [2] float32_t 0.0795838 + [3] float32_t 0.10182 + +c_ref + [0] float32_t 0.00455523 + [1] float32_t 0.559712 + [2] float32_t 0.0795838 + [3] float32_t 0.552081 + + +c [0] float32_t 0.829904 + [1] float32_t 0.692891 + [2] float32_t 0.961654 + [3] float32_t 0.666956 + + c_ref + [0] float32_t 0.829904 + [1] float32_t 0.692891 + [2] float32_t 0.961654 + [3] float32_t 0.522878 + */ + for (i = 0; i < DATA_SIZE; i++) + { + //ignore 4th component because it is not computed in all code-paths + if( (fabs(c[i].tMaxs().m_floats[0] - c_ref[i].tMaxs().m_floats[0]) > 0.001) || + (fabs(c[i].tMaxs().m_floats[1] - c_ref[i].tMaxs().m_floats[1]) > 0.001) || + (fabs(c[i].tMaxs().m_floats[2] - c_ref[i].tMaxs().m_floats[2]) > 0.001) || + // (fabs(c[i].tMaxs().m_floats[3] - c_ref[i].tMaxs().m_floats[3]) > 0.001) || + (fabs(c[i].tMins().m_floats[0] - c_ref[i].tMins().m_floats[0]) > 0.001) || + (fabs(c[i].tMins().m_floats[1] - c_ref[i].tMins().m_floats[1]) > 0.001) || + (fabs(c[i].tMins().m_floats[2] - c_ref[i].tMins().m_floats[2]) > 0.001) + //|| (fabs(c[i].tMins().m_floats[3] - c_ref[i].tMins().m_floats[3]) > 0.001) + ) + + + //if((c[i].tMaxs().m_floats[0] != c_ref[i].tMaxs().m_floats[0]) || (c[i].tMaxs().m_floats[1] != c_ref[i].tMaxs().m_floats[1]) || (c[i].tMaxs().m_floats[2] != c_ref[i].tMaxs().m_floats[2]) || (c[i].tMaxs().m_floats[3] != c_ref[i].tMaxs().m_floats[3]) || (c[i].tMins().m_floats[0] != c_ref[i].tMins().m_floats[0]) || (c[i].tMins().m_floats[1] != c_ref[i].tMins().m_floats[1]) || (c[i].tMins().m_floats[2] != c_ref[i].tMins().m_floats[2]) || (c[i].tMins().m_floats[3] != c_ref[i].tMins().m_floats[3])) + { + printf("Merge fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]); + + printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); + printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); + printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); + printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); + printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]); + printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]); + + printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); + printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); + printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); + printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); + printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]); + printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]); + return 1; + + } + + } + + //////////////////////////////////// + // + // Time and Test Select + // + //////////////////////////////////// + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + + for (i = 0; i < DATA_SIZE; i++) + { + Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]); + } + + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Select_Test_Res[i] = Select(a[i], b[i], c[i]); + } + + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Select Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + + //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); + + for (i = 0; i < DATA_SIZE; i++) + { + Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]); + Select_Test_Res[i] = Select(a[i], b[i], c[i]); + + if(Select_Test_Res[i] != Select_Ref_Res[i]) + { + printf("Select fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]); + + printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); + printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); + printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); + printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); + printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]); + printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]); + + printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); + printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); + printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); + printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); + printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]); + printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]); + return 1; + } + + } + + return 0; +} +#endif + + + + diff --git a/Test/Source/Tests/Test_btDbvt.h b/Test/Source/Tests/Test_btDbvt.h new file mode 100644 index 0000000..92e309a --- /dev/null +++ b/Test/Source/Tests/Test_btDbvt.h @@ -0,0 +1,21 @@ +// +// Test_btDbvt.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc., Inc. +// + +#ifndef BulletTest_Test_btDbvt_h +#define BulletTest_Test_btDbvt_h + +#ifdef __cplusplus +extern "C" { +#endif + + int Test_btDbvt(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Test/Source/Tests/Test_dot3.cpp b/Test/Source/Tests/Test_dot3.cpp new file mode 100644 index 0000000..ef3ff4a --- /dev/null +++ b/Test/Source/Tests/Test_dot3.cpp @@ -0,0 +1,153 @@ +// +// Test_v3dot.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_dot3.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static btVector3 dot3_ref( const btVector3 &, const btVector3 &, const btVector3 &, const btVector3 &); +static btVector3 dot3_ref( const btVector3 &v, const btVector3 &v1, const btVector3 &v2, const btVector3 &v3) +{ + return btVector3( v.dot(v1), v.dot(v2), v.dot(v3)); +} + +/* +SIMD_FORCE_INLINE int operator!=(const btVector3 &s, const btVector3 &v) +{ +#ifdef __SSE__ + __m128 test = _mm_cmpneq_ps( s.mVec128, v.mVec128 ); + return (_mm_movemask_ps( test ) & 7) != 0; +#elif defined __ARM_NEON_H + uint32x4_t test = vandq_u32( vceqq_f32( s.mVec128, v.mVec128 ), (uint32x4_t){-1,-1,-1,0}); + uint32x2_t t = vpadd_u32( vget_low_u32(test), vget_high_u32(test)); + t = vpadd_u32(t, t); + return -3 != (int32_t) vget_lane_u32(t, 0); +#else + return s.m_floats[0] != v.m_floats[0] || + s.m_floats[1] != v.m_floats[1] || + s.m_floats[2] != v.m_floats[2]; +#endif +} +*/ + + + +#define LOOPCOUNT 1000 +#define NUM_CYCLES 10000 + +int Test_dot3(void) +{ + btVector3 v, v1, v2, v3; + +#define DATA_SIZE 1024 + + btVector3 vec3_arr[DATA_SIZE]; + btVector3 vec3_arr1[DATA_SIZE]; + btVector3 vec3_arr2[DATA_SIZE]; + btVector3 vec3_arr3[DATA_SIZE]; + btVector3 res_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + btVector3 correct, test; + + for( k = 0; k < DATA_SIZE; k++ ) + { + + vec3_arr[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN)); + vec3_arr1[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN)); + vec3_arr2[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN )); + vec3_arr3[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN)); + + correct = dot3_ref(vec3_arr[k], vec3_arr1[k], vec3_arr2[k], vec3_arr3[k]); + test = vec3_arr[k].dot3( vec3_arr1[k], vec3_arr2[k], vec3_arr3[k]); + + if( correct != test ) + { + vlog( "Error (%ld) - dot3 result error! *{%a, %a, %a, %a} != {%a, %a, %a, %a} \n", k, + correct.x(), correct.y(), correct.z(), correct.w(), + test.x(), test.y(), test.z(), test.w() ); + + return 1; + } + } + + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t k32 = (k & (DATA_SIZE-1)); + res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; + res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; + res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; + res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t k32 = (k & (DATA_SIZE-1)); + res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; + res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; + res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; + res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_dot3.h b/Test/Source/Tests/Test_dot3.h new file mode 100644 index 0000000..cb525f8 --- /dev/null +++ b/Test/Source/Tests/Test_dot3.h @@ -0,0 +1,22 @@ +// +// Test_mindot.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_dot3_h +#define BulletTest_Test_dot3_h + +#ifdef __cplusplus +extern "C" { +#endif + + int Test_dot3(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_maxdot.cpp b/Test/Source/Tests/Test_maxdot.cpp new file mode 100644 index 0000000..acc0cae --- /dev/null +++ b/Test/Source/Tests/Test_maxdot.cpp @@ -0,0 +1,281 @@ +// +// Test_maxdot.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_maxdot.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + + +// reference code for testing purposes +static long maxdot_ref( const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult ); + + + + + +#ifdef __arm__ + #define MAX_LOG2_SIZE 9 +#else + #define MAX_LOG2_SIZE 10 +#endif +#define MAX_SIZE (1U << MAX_LOG2_SIZE) +#define LOOPCOUNT 10 + +int Test_maxdot(void) +{ + // Init an array flanked by guard pages + btSimdFloat4 *data = (btSimdFloat4*) GuardCalloc( 1, MAX_SIZE * sizeof(btSimdFloat4), NULL ); + float *fp = (float*) data; + long correct, test; + btVector3 localScaling( 0.1f, 0.2f, 0.3f); + size_t size; + + // Init the data + size_t i; + for( i = 0; i < MAX_SIZE; i++ ) + { + fp[4*i] = (int32_t) RANDF_16; + fp[4*i+1] = (int32_t) RANDF_16; + fp[4*i+2] = (int32_t) RANDF_16; + fp[4*i+3] = BT_NAN; // w channel NaN + } + + float correctDot, testDot; + fp = (float*) localScaling; + float maxRelativeError = 0.f; + + for( size = 1; size <= MAX_SIZE; size++ ) + { + float *in = (float*)(data + MAX_SIZE - size); + size_t position; + + for( position = 0; position < size; position++ ) + { + float *biggest = in + position * 4; + float old[4] = { biggest[0], biggest[1], biggest[2], biggest[3] }; + biggest[0] += LARGE_FLOAT17; + biggest[1] += LARGE_FLOAT17; + biggest[2] += LARGE_FLOAT17; + biggest[3] += LARGE_FLOAT17; + + correctDot = BT_NAN; + testDot = BT_NAN; + correct = maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); + test = localScaling.maxDot( (btVector3*) in, size, testDot); + if( test < 0 || test >= size ) + { + vlog( "Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test); + continue; + } + if( correct != test ) + { + vlog( "Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test, + fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], + fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); + return 1; + } + if( test != position ) + { + vlog( "Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test, + fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2], + fp[0] * in[4*position] + fp[1] * in[4*position+1] + fp[2] * in[4*position+2] ); + return 1; + } + + if( correctDot != testDot ) + { + float relativeError = btFabs((testDot - correctDot) / correctDot); + if (relativeError>1e-6) + { + vlog( "Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, + fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], + fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); + return 1; + } else + { + if (maxRelativeError < relativeError) + { + maxRelativeError = relativeError; +#ifdef VERBOSE_WARNING + sprintf(errStr,"Warning @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, + fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], + fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2]); +#endif //VERBOSE_WARNING + } + } + } + + memcpy( biggest, old, 16 ); + } + } + + + if (maxRelativeError) + { + printf("Warning: relative error = %e\n", maxRelativeError); +#ifdef VERBOSE_WARNING + vlog(errStr); +#endif + } + + uint64_t scalarTimes[33 + (MAX_LOG2_SIZE-5)]; + uint64_t vectorTimes[33 + (MAX_LOG2_SIZE-5)]; + size_t j, k; + float *in = (float*) data; + for( size = 1; size <= 32; size++ ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTimes[size] = 0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + correct += maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + scalarTimes[size] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTimes[size] = bestTime; + else + scalarTimes[size] /= 100; + } + + uint64_t *timep = &scalarTimes[33]; + for( size = 64; size <= MAX_SIZE; size *= 2 ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] =0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + correct += maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + for( size = 1; size <= 32; size++ ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTimes[size] = 0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + test += localScaling.maxDot( (btVector3*) in, size, testDot); + currentTime = ReadTicks() - startTime; + vectorTimes[size] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTimes[size] = bestTime; + else + vectorTimes[size] /= 100; + } + + timep = &vectorTimes[33]; + for( size = 64; size <= MAX_SIZE; size *= 2 ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] =0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + test += localScaling.maxDot( (btVector3*) in, size, testDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + vlog( "Timing:\n" ); + vlog( " size\t scalar\t vector\n" ); + for( size = 1; size <= 32; size++ ) + vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[size] ) / LOOPCOUNT, TicksToCycles( vectorTimes[size] ) / LOOPCOUNT ); + size_t index = 33; + for( size = 64; size <= MAX_SIZE; size *= 2 ) + { + vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[index] ) / LOOPCOUNT, TicksToCycles( vectorTimes[index] ) / LOOPCOUNT ); + index++; + } + + // Useless check to make sure that the timing loops are not optimized away + if( test != correct ) + vlog( "Error: Test != correct: *%ld vs. %ld\n", correct, test); + + GuardFree(data); + + return 0; +} + + +static long maxdot_ref( const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult ) +{ + + const float *dp = (const float*) vertices; + float maxDot = -BT_INFINITY; + long i = 0; + long ptIndex = -1; + + for( i = 0; i < count; i++ ) + { + float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; dp += 4; + + if( dot > maxDot ) + { + maxDot = dot; + ptIndex = i; + } + } + + *dotResult = maxDot; + + return ptIndex; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_maxdot.h b/Test/Source/Tests/Test_maxdot.h new file mode 100644 index 0000000..2e6c517 --- /dev/null +++ b/Test/Source/Tests/Test_maxdot.h @@ -0,0 +1,22 @@ +// +// Test_maxdot.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_maxdot_h +#define BulletTest_Test_maxdot_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_maxdot(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_mindot.cpp b/Test/Source/Tests/Test_mindot.cpp new file mode 100644 index 0000000..2f44256 --- /dev/null +++ b/Test/Source/Tests/Test_mindot.cpp @@ -0,0 +1,269 @@ +// +// Test_mindot.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_mindot.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + + +// reference code for testing purposes +static long mindot_ref( const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult ); + +#ifdef __arm__ + #define MAX_LOG2_SIZE 9 +#else + #define MAX_LOG2_SIZE 9 +#endif +#define MAX_SIZE (1U << MAX_LOG2_SIZE) +#define LOOPCOUNT 100 + +int Test_mindot(void) +{ + // Init an array flanked by guard pages + btSimdFloat4 *data = (btSimdFloat4*) GuardCalloc( 1, MAX_SIZE * sizeof(btSimdFloat4), NULL ); + float *fp = (float*) data; + long correct, test; + btVector3 localScaling( 0.1f, 0.2f, 0.3f); + size_t size; + + // Init the data + size_t i; + for( i = 0; i < MAX_SIZE; i++ ) + { + fp[4*i] = (int32_t) RANDF_16; + fp[4*i+1] = (int32_t) RANDF_16; + fp[4*i+2] = (int32_t) RANDF_16; + fp[4*i+3] = BT_NAN; // w channel NaN + } + + float correctDot, testDot; + fp = (float*) localScaling; + float maxRelativeError = 0.f; + + for( size = 1; size <= MAX_SIZE; size++ ) + { + float *in = (float*)(data + MAX_SIZE - size); + size_t position; + + for( position = 0; position < size; position++ ) + { + float *biggest = in + position * 4; + float old[4] = { biggest[0], biggest[1], biggest[2], biggest[3] }; + biggest[0] -= LARGE_FLOAT17; + biggest[1] -= LARGE_FLOAT17; + biggest[2] -= LARGE_FLOAT17; + biggest[3] -= LARGE_FLOAT17; + + correctDot = BT_NAN; + testDot = BT_NAN; + correct = mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); + test = localScaling.minDot( (btVector3*) in, size, testDot); + if( test < 0 || test >= size ) + { + vlog( "Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test); + continue; + } + if( correct != test ) + { + vlog( "Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test, + fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], + fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); + return 1; + } + if( test != position ) + { + vlog( "Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test, + fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2], + fp[0] * in[4*position] + fp[1] * in[4*position+1] + fp[2] * in[4*position+2] ); + return 1; + } + + if( correctDot != testDot ) + { + float relativeError = btFabs((testDot - correctDot) / correctDot); + if (relativeError>1e6) + { + vlog( "Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, + fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], + fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); + return 1; + } else + { + if (maxRelativeError < relativeError) + { + maxRelativeError = relativeError; + } + } + } + + + memcpy( biggest, old, 16 ); + } + } + + if (maxRelativeError) + { + printf("Warning: relative error = %e\n", maxRelativeError); + } + uint64_t scalarTimes[33 + (MAX_LOG2_SIZE-5)]; + uint64_t vectorTimes[33 + (MAX_LOG2_SIZE-5)]; + size_t j, k; + float *in = (float*) data; + for( size = 1; size <= 32; size++ ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTimes[size] = 0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + correct += mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + scalarTimes[size] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTimes[size] = bestTime; + else + scalarTimes[size] /= 100; + } + + uint64_t *timep = &scalarTimes[33]; + for( size = 64; size <= MAX_SIZE; size *= 2 ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] =0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + correct += mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + for( size = 1; size <= 32; size++ ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTimes[size] = 0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + test += localScaling.minDot( (btVector3*) in, size, testDot); + currentTime = ReadTicks() - startTime; + vectorTimes[size] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTimes[size] = bestTime; + else + vectorTimes[size] /= 100; + } + + timep = &vectorTimes[33]; + for( size = 64; size <= MAX_SIZE; size *= 2 ) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] =0; + for (j = 0; j < 100; j++) { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + test += localScaling.minDot( (btVector3*) in, size, testDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + vlog( "Timing:\n" ); + vlog( " size\t scalar\t vector\n" ); + for( size = 1; size <= 32; size++ ) + vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[size] ) / LOOPCOUNT, TicksToCycles( vectorTimes[size] ) / LOOPCOUNT ); + size_t index = 33; + for( size = 64; size <= MAX_SIZE; size *= 2 ) + { + vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[index] ) / LOOPCOUNT, TicksToCycles( vectorTimes[index] ) / LOOPCOUNT ); + index++; + } + + // Useless check to make sure that the timing loops are not optimized away + if( test != correct ) + vlog( "Error: Test != correct: *%ld vs. %ld\n", correct, test); + + GuardFree(data); + + return 0; +} + + + +static long mindot_ref( const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult ) +{ + + const float *dp = (const float*) vertices; + float minDot = BT_INFINITY; + long i = 0; + long ptIndex = -1; + + for( i = 0; i < count; i++ ) + { + float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; dp += 4; + + if( dot < minDot ) + { + minDot = dot; + ptIndex = i; + } + } + + *dotResult = minDot; + + return ptIndex; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_mindot.h b/Test/Source/Tests/Test_mindot.h new file mode 100644 index 0000000..4810dcd --- /dev/null +++ b/Test/Source/Tests/Test_mindot.h @@ -0,0 +1,22 @@ +// +// Test_mindot.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_mindot_h +#define BulletTest_Test_mindot_h + +#ifdef __cplusplus +extern "C" { +#endif + + int Test_mindot(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_qtdot.cpp b/Test/Source/Tests/Test_qtdot.cpp new file mode 100644 index 0000000..3fad74d --- /dev/null +++ b/Test/Source/Tests/Test_qtdot.cpp @@ -0,0 +1,162 @@ +// +// Test_qtdot.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_qtdot.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define BT_OP(a, b) (a.dot(b)) +// reference code for testing purposes +static inline btScalar qtdot_ref(btQuaternion& q1, btQuaternion& q2); + +static inline btScalar qtdot_ref(btQuaternion& q1, btQuaternion& q2) +{ + return + q1.x() * q2.x() + + q1.y() * q2.y() + + q1.z() * q2.z() + + q1.w() * q2.w(); +} + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_qtdot(void) +{ + btQuaternion q1, q2; + float x, y, z, w, vNaN; + vNaN = BT_NAN; // w channel NaN + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + q1.setValue(x,y,z,w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + q2.setValue(x,y,z,w); + + btScalar correct_res, test_res; + + { + correct_res = vNaN; + test_res = vNaN; + correct_res = qtdot_ref(q1, q2); + test_res = BT_OP(q1,q2); + + if( fabsf(correct_res - test_res) > FLT_EPSILON*4 ) + { + vlog( "Error - qtdot result error! " + "\ncorrect = %10.4f " + "\ntested = %10.4f \n", + correct_res, test_res); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btQuaternion qt_arr1[DATA_SIZE]; + btQuaternion qt_arr2[DATA_SIZE]; + btScalar res_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x,y,z,w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr2[k].setValue(x,y,z,w); + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t km = (k & (DATA_SIZE-1)); + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++; + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++; + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++; + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t km = (k & (DATA_SIZE-1)); + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_qtdot.h b/Test/Source/Tests/Test_qtdot.h new file mode 100644 index 0000000..4917780 --- /dev/null +++ b/Test/Source/Tests/Test_qtdot.h @@ -0,0 +1,22 @@ +// +// Test_qtdot.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_qtdot_h +#define BulletTest_Test_qtdot_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_qtdot(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_qtmul.cpp b/Test/Source/Tests/Test_qtmul.cpp new file mode 100644 index 0000000..7b83a7b --- /dev/null +++ b/Test/Source/Tests/Test_qtmul.cpp @@ -0,0 +1,183 @@ +// +// Test_qtmul.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_qtmul.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define BT_OP(a, b) ((a) *= (b)) +// reference code for testing purposes +static inline btQuaternion& qtmul_ref(btQuaternion& q1, btQuaternion& q2); + +static inline btQuaternion& qtmul_ref(btQuaternion& q1, btQuaternion& q2) +{ + float x,y,z,w; + x = q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + y = q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), + z = q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), + w = q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z(); + + q1.setValue(x, y, z, w); + return q1; +} + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_qtmul(void) +{ + btQuaternion q1, q2, q3; + + float x, y, z, w, vNaN; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + vNaN = BT_NAN; // w channel NaN + q1.setValue(x,y,z,w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + q2.setValue(x,y,z,w); + + q3 = q1; + + btQuaternion correct_res, test_res; + + { + float vNaN = BT_NAN; + correct_res.setValue(vNaN, vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN, vNaN); + correct_res = qtmul_ref(q1, q2); + test_res = BT_OP(q3,q2); + + if( fabsf(correct_res.x() - test_res.x()) + + fabsf(correct_res.y() - test_res.y()) + + fabsf(correct_res.z() - test_res.z()) + + fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*10 ) + { + vlog( "Error - qtmul result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btQuaternion qt_arr1[DATA_SIZE]; + btQuaternion qt_arr2[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x,y,z,w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr2[k].setValue(x,y,z,w); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + qt_arr1[k] = qtmul_ref(qt_arr1[k], qt_arr2[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x,y,z,w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr2[k].setValue(x,y,z,w); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + qt_arr1[k] = BT_OP(qt_arr1[k], qt_arr2[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_qtmul.h b/Test/Source/Tests/Test_qtmul.h new file mode 100644 index 0000000..9109199 --- /dev/null +++ b/Test/Source/Tests/Test_qtmul.h @@ -0,0 +1,22 @@ +// +// Test_qtmul.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_qtmul_h +#define BulletTest_Test_qtmul_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_qtmul(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_qtmulQV3.cpp b/Test/Source/Tests/Test_qtmulQV3.cpp new file mode 100644 index 0000000..0a26b50 --- /dev/null +++ b/Test/Source/Tests/Test_qtmulQV3.cpp @@ -0,0 +1,162 @@ +// +// Test_qtmulQV3.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_qtmulQV3.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define BT_OP(a, b) ((a) * (b)) +// reference code for testing purposes +static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& w); + +static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& w) +{ + return btQuaternion( + q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); +} + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN +} + +static inline btSimdFloat4 qtrand_f4(void) +{ + return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1 ); +} + +static inline btSimdFloat4 qtNAN_f4(void) +{ + return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN ); +} + +int Test_qtmulQV3(void) +{ + btQuaternion q; + btVector3 v3; + + // Init the data + q = btQuaternion(qtrand_f4()); + v3 = btVector3(rand_f4()); + + btQuaternion correct_res, test_res; + correct_res = btQuaternion(qtNAN_f4()); + test_res = btQuaternion(qtNAN_f4()); + + { + correct_res = qtmulQV3_ref(q, v3); + test_res = BT_OP(q, v3); + + if( fabsf(correct_res.x() - test_res.x()) + + fabsf(correct_res.y() - test_res.y()) + + fabsf(correct_res.z() - test_res.z()) + + fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*8 ) + { + vlog( "Error - qtmulQV3 result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btQuaternion qt_arrR[DATA_SIZE]; + btQuaternion qt_arr[DATA_SIZE]; + btVector3 v3_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + qt_arrR[k] = qtmulQV3_ref(qt_arr[k], v3_arr[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + qt_arrR[k] = BT_OP(qt_arr[k], v3_arr[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_qtmulQV3.h b/Test/Source/Tests/Test_qtmulQV3.h new file mode 100644 index 0000000..f7bffce --- /dev/null +++ b/Test/Source/Tests/Test_qtmulQV3.h @@ -0,0 +1,22 @@ +// +// Test_qtmulQV3.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_qtmulQV3_h +#define BulletTest_Test_qtmulQV3_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_qtmulQV3(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_qtmulV3Q.cpp b/Test/Source/Tests/Test_qtmulV3Q.cpp new file mode 100644 index 0000000..48f5124 --- /dev/null +++ b/Test/Source/Tests/Test_qtmulV3Q.cpp @@ -0,0 +1,161 @@ +// +// Test_qtmulV3Q.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_qtmulV3Q.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define BT_OP(a, b) ((a) * (b)) +// reference code for testing purposes +static inline btQuaternion qtmulV3Q_ref(const btVector3& w, const btQuaternion& q); + +static inline btQuaternion qtmulV3Q_ref(const btVector3& w, const btQuaternion& q) +{ + return btQuaternion( + +w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + +w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), + +w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); +} + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +static inline btSimdFloat4 rand_f4(void) +{ + return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN +} + +static inline btSimdFloat4 qtrand_f4(void) +{ + return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1 ); +} + +static inline btSimdFloat4 qtNAN_f4(void) +{ + return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN ); +} + +int Test_qtmulV3Q(void) +{ + btQuaternion q; + btVector3 v3; + + // Init the data + q = btQuaternion(qtrand_f4()); + v3 = btVector3(rand_f4()); + + btQuaternion correct_res, test_res; + correct_res = btQuaternion(qtNAN_f4()); + test_res = btQuaternion(qtNAN_f4()); + + { + correct_res = qtmulV3Q_ref(v3, q); + test_res = BT_OP(v3, q); + + if( fabsf(correct_res.x() - test_res.x()) + + fabsf(correct_res.y() - test_res.y()) + + fabsf(correct_res.z() - test_res.z()) + + fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*8 ) + { + vlog( "Error - qtmulV3Q result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btQuaternion qt_arrR[DATA_SIZE]; + btQuaternion qt_arr[DATA_SIZE]; + btVector3 v3_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + qt_arrR[k] = qtmulV3Q_ref(v3_arr[k], qt_arr[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + qt_arrR[k] = BT_OP(v3_arr[k], qt_arr[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} +#endif//#ifdef BT_USE_SSE diff --git a/Test/Source/Tests/Test_qtmulV3Q.h b/Test/Source/Tests/Test_qtmulV3Q.h new file mode 100644 index 0000000..f9714c9 --- /dev/null +++ b/Test/Source/Tests/Test_qtmulV3Q.h @@ -0,0 +1,22 @@ +// +// Test_qtmulV3Q.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_qtmulV3Q_h +#define BulletTest_Test_qtmulV3Q_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_qtmulV3Q(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_qtnorm.cpp b/Test/Source/Tests/Test_qtnorm.cpp new file mode 100644 index 0000000..3d008bf --- /dev/null +++ b/Test/Source/Tests/Test_qtnorm.cpp @@ -0,0 +1,176 @@ +// +// Test_qtnorm.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_qtnorm.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define BT_OP(a) (a.normalize()) +// reference code for testing purposes +static inline btQuaternion& qtnorm_ref(btQuaternion& q1); + +static inline btQuaternion& qtnorm_ref(btQuaternion& q1) +{ + float dot = + q1.x() * q1.x() + + q1.y() * q1.y() + + q1.z() * q1.z() + + q1.w() * q1.w(); + + dot = 1.0f / sqrtf(dot); + + q1.setValue(q1.x()*dot, q1.y()*dot, q1.z()*dot, q1.w()*dot); + + return q1; +} + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_qtnorm(void) +{ + int i; + btQuaternion q1, q2; + float x, y, z, w, vNaN; + vNaN = BT_NAN; // w channel NaN + + btQuaternion correct_res, test_res; + + for (i=0; i FLT_EPSILON*10 ) + { + vlog( "Error - qtnorm result error! " + "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btQuaternion qt_arr0[DATA_SIZE]; + btQuaternion qt_arr1[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x,y,z,w); + } + + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t km = (k & (DATA_SIZE-1)); + qt_arr0[km] = qtnorm_ref(qt_arr1[km]);km++; + qt_arr0[km] = qtnorm_ref(qt_arr1[km]);km++; + qt_arr0[km] = qtnorm_ref(qt_arr1[km]);km++; + qt_arr0[km] = qtnorm_ref(qt_arr1[km]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x,y,z,w); + } + + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t km = (k & (DATA_SIZE-1)); + qt_arr0[km] = BT_OP(qt_arr1[km]);km++; + qt_arr0[km] = BT_OP(qt_arr1[km]);km++; + qt_arr0[km] = BT_OP(qt_arr1[km]);km++; + qt_arr0[km] = BT_OP(qt_arr1[km]);km++; + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_qtnorm.h b/Test/Source/Tests/Test_qtnorm.h new file mode 100644 index 0000000..5b00217 --- /dev/null +++ b/Test/Source/Tests/Test_qtnorm.h @@ -0,0 +1,22 @@ +// +// Test_qtnorm.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_qtnorm_h +#define BulletTest_Test_qtnorm_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_qtnorm(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_quat_aos_neon.cpp b/Test/Source/Tests/Test_quat_aos_neon.cpp new file mode 100644 index 0000000..c13e41a --- /dev/null +++ b/Test/Source/Tests/Test_quat_aos_neon.cpp @@ -0,0 +1,599 @@ +// +// Test_quat_aos_neon.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc., Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_quat_aos_neon.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" + +#include + + +//typedef Vectormath::Aos::Vector3 vmVector3; +//typedef Vectormath::Aos::Quat vmQuat; +//typedef Vectormath::Aos::Matrix3 vmMatrix3; +//typedef Vectormath::Aos::Transform3 vmTransform3; +//typedef Vectormath::Aos::Point3 vmPoint3; + + +typedef Vectormath::Aos::Vector4 vmVector4; + +// reference code for testing purposes +ATTRIBUTE_ALIGNED16(class) Quat_ref +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Quat_ref( ) { }; + + // Copy a quaternion + // + inline Quat_ref( const Quat_ref & quat ); + + // Construct a quaternion from x, y, z, and w elements + // + inline Quat_ref( float x, float y, float z, float w ); + + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat_ref( const vmVector3 & xyz, float w ); + + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat_ref( const vmVector4 & vec ); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat_ref( const vmMatrix3 & rotMat ); + + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat_ref( float scalar ); + + // Assign one quaternion to another + // + inline Quat_ref & operator =( const Quat_ref & quat ); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat_ref & setXYZ( const vmVector3 & vec ); + + // Get the x, y, and z elements of a quaternion + // + inline const vmVector3 getXYZ( ) const; + + // Set the x element of a quaternion + // + inline Quat_ref & setX( float x ); + + // Set the y element of a quaternion + // + inline Quat_ref & setY( float y ); + + // Set the z element of a quaternion + // + inline Quat_ref & setZ( float z ); + + // Set the w element of a quaternion + // + inline Quat_ref & setW( float w ); + + // Get the x element of a quaternion + // + inline float getX( ) const; + + // Get the y element of a quaternion + // + inline float getY( ) const; + + // Get the z element of a quaternion + // + inline float getZ( ) const; + + // Get the w element of a quaternion + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat_ref & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two quaternions + // + inline const Quat_ref operator +( const Quat_ref & quat ) const; + + // Subtract a quaternion from another quaternion + // + inline const Quat_ref operator -( const Quat_ref & quat ) const; + + // Multiply two quaternions + // + inline const Quat_ref operator *( const Quat_ref & quat ) const; + + // Multiply a quaternion by a scalar + // + inline const Quat_ref operator *( float scalar ) const; + + // Divide a quaternion by a scalar + // + inline const Quat_ref operator /( float scalar ) const; + + // Perform compound assignment and addition with a quaternion + // + inline Quat_ref & operator +=( const Quat_ref & quat ); + + // Perform compound assignment and subtraction by a quaternion + // + inline Quat_ref & operator -=( const Quat_ref & quat ); + + // Perform compound assignment and multiplication by a quaternion + // + inline Quat_ref & operator *=( const Quat_ref & quat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Quat_ref & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Quat_ref & operator /=( float scalar ); + + // Negate all elements of a quaternion + // + inline const Quat_ref operator -( ) const; + + // Construct an identity quaternion + // + static inline const Quat_ref identity( ); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat_ref rotation( const vmVector3 & unitVec0, const vmVector3 & unitVec1 ); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat_ref rotation( float radians, const vmVector3 & unitVec ); + + // Construct a quaternion to rotate around the x axis + // + static inline const Quat_ref rotationX( float radians ); + + // Construct a quaternion to rotate around the y axis + // + static inline const Quat_ref rotationY( float radians ); + + // Construct a quaternion to rotate around the z axis + // + static inline const Quat_ref rotationZ( float radians ); + +}; + +inline Quat_ref::Quat_ref( const Quat_ref & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; +} + +inline Quat_ref::Quat_ref( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Quat_ref::Quat_ref( const vmVector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Quat_ref::Quat_ref( const vmVector4 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = vec.getW(); +} + +inline Quat_ref::Quat_ref( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Quat_ref Quat_ref::identity( ) +{ + return Quat_ref( 0.0f, 0.0f, 0.0f, 1.0f ); +} + + +inline void loadXYZW_ref( Quat_ref & quat, const float * fptr ) +{ + quat = Quat_ref( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW_ref( const Quat_ref & quat, float * fptr ) +{ + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); +} + +inline Quat_ref & Quat_ref::operator =( const Quat_ref & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; + return *this; +} + +inline Quat_ref & Quat_ref::setXYZ( const vmVector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const vmVector3 Quat_ref::getXYZ( ) const +{ + return vmVector3( mX, mY, mZ ); +} + +inline Quat_ref & Quat_ref::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Quat_ref::getX( ) const +{ + return mX; +} + +inline Quat_ref & Quat_ref::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Quat_ref::getY( ) const +{ + return mY; +} + +inline Quat_ref & Quat_ref::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Quat_ref::getZ( ) const +{ + return mZ; +} + +inline Quat_ref & Quat_ref::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Quat_ref::getW( ) const +{ + return mW; +} + +inline Quat_ref & Quat_ref::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Quat_ref::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Quat_ref::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Quat_ref::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Quat_ref Quat_ref::operator +( const Quat_ref & quat ) const +{ + return Quat_ref( + ( mX + quat.mX ), + ( mY + quat.mY ), + ( mZ + quat.mZ ), + ( mW + quat.mW ) + ); +} + +inline const Quat_ref Quat_ref::operator -( const Quat_ref & quat ) const +{ + return Quat_ref( + ( mX - quat.mX ), + ( mY - quat.mY ), + ( mZ - quat.mZ ), + ( mW - quat.mW ) + ); +} + +inline const Quat_ref Quat_ref::operator *( float scalar ) const +{ + return Quat_ref( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Quat_ref & Quat_ref::operator +=( const Quat_ref & quat ) +{ + *this = *this + quat; + return *this; +} + +inline Quat_ref & Quat_ref::operator -=( const Quat_ref & quat ) +{ + *this = *this - quat; + return *this; +} + +inline Quat_ref & Quat_ref::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Quat_ref Quat_ref::operator /( float scalar ) const +{ + return Quat_ref( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Quat_ref & Quat_ref::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Quat_ref Quat_ref::operator -( ) const +{ + return Quat_ref( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Quat_ref operator *( float scalar, const Quat_ref & quat ) +{ + return quat * scalar; +} + +inline float dot( const Quat_ref & quat0, const Quat_ref & quat1 ) +{ + float result; + result = ( quat0.getX() * quat1.getX() ); + result = ( result + ( quat0.getY() * quat1.getY() ) ); + result = ( result + ( quat0.getZ() * quat1.getZ() ) ); + result = ( result + ( quat0.getW() * quat1.getW() ) ); + return result; +} + +inline const Quat_ref lerp( float t, const Quat_ref & quat0, const Quat_ref & quat1 ) +{ + return ( quat0 + ( ( quat1 - quat0 ) * t ) ); +} + +inline const Quat_ref slerp( float t, const Quat_ref & unitQuat0, const Quat_ref & unitQuat1 ) +{ + Quat_ref start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitQuat0, unitQuat1 ); + if ( cosAngle < 0.0f ) { + cosAngle = -cosAngle; + start = ( -unitQuat0 ); + } else { + start = unitQuat0; + } + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); +} + +inline const Quat_ref squad( float t, const Quat_ref & unitQuat0, const Quat_ref & unitQuat1, const Quat_ref & unitQuat2, const Quat_ref & unitQuat3 ) +{ + Quat_ref tmp0, tmp1; + tmp0 = slerp( t, unitQuat0, unitQuat3 ); + tmp1 = slerp( t, unitQuat1, unitQuat2 ); + return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); +} + +inline float norm( const Quat_ref & quat ) +{ + float result; + result = ( quat.getX() * quat.getX() ); + result = ( result + ( quat.getY() * quat.getY() ) ); + result = ( result + ( quat.getZ() * quat.getZ() ) ); + result = ( result + ( quat.getW() * quat.getW() ) ); + return result; +} + +inline float length( const Quat_ref & quat ) +{ + return ::sqrtf( norm( quat ) ); +} + +inline const Quat_ref normalize( const Quat_ref & quat ) +{ + float lenSqr, lenInv; + lenSqr = norm( quat ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Quat_ref( + ( quat.getX() * lenInv ), + ( quat.getY() * lenInv ), + ( quat.getZ() * lenInv ), + ( quat.getW() * lenInv ) + ); +} + +inline const Quat_ref Quat_ref::rotation( const vmVector3 & unitVec0, const vmVector3 & unitVec1 ) +{ + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); + recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); + return Quat_ref( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); +} + +inline const Quat_ref Quat_ref::rotation( float radians, const vmVector3 & unitVec ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat_ref( ( unitVec * s ), c ); +} + +inline const Quat_ref Quat_ref::rotationX( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat_ref( s, 0.0f, 0.0f, c ); +} + +inline const Quat_ref Quat_ref::rotationY( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat_ref( 0.0f, s, 0.0f, c ); +} + +inline const Quat_ref Quat_ref::rotationZ( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat_ref( 0.0f, 0.0f, s, c ); +} + +inline const Quat_ref Quat_ref::operator *( const Quat_ref & quat ) const +{ + return Quat_ref( + ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ), + ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ), + ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ), + ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) ) + ); +} + +inline Quat_ref & Quat_ref::operator *=( const Quat_ref & quat ) +{ + *this = *this * quat; + return *this; +} + +inline const vmVector3 rotate( const Quat_ref & quat, const vmVector3 & vec ) +{ + float tmpX, tmpY, tmpZ, tmpW; + tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); + tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); + tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); + tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); + return vmVector3( + ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), + ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), + ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) + ); +} + +inline const Quat_ref conj( const Quat_ref & quat ) +{ + return Quat_ref( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); +} + +inline const Quat_ref select( const Quat_ref & quat0, const Quat_ref & quat1, bool select1 ) +{ + return Quat_ref( + ( select1 )? quat1.getX() : quat0.getX(), + ( select1 )? quat1.getY() : quat0.getY(), + ( select1 )? quat1.getZ() : quat0.getZ(), + ( select1 )? quat1.getW() : quat0.getW() + ); +} + + + +#define LOOPCOUNT 1000 +#define NUM_CYCLES 10000 +#define DATA_SIZE 1024 + +int Test_quat_aos_neon(void) +{ + + return 0; +} + +#endif + diff --git a/Test/Source/Tests/Test_quat_aos_neon.h b/Test/Source/Tests/Test_quat_aos_neon.h new file mode 100644 index 0000000..e751a41 --- /dev/null +++ b/Test/Source/Tests/Test_quat_aos_neon.h @@ -0,0 +1,21 @@ +// +// Test_quat_aos_neon.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc., Inc. +// + +#ifndef BulletTest_Test_quat_aos_neon_h +#define BulletTest_Test_quat_aos_neon_h + +#ifdef __cplusplus +extern "C" { +#endif + + int Test_quat_aos_neon(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Test/Source/Tests/Test_v3cross.cpp b/Test/Source/Tests/Test_v3cross.cpp new file mode 100644 index 0000000..00ff4e4 --- /dev/null +++ b/Test/Source/Tests/Test_v3cross.cpp @@ -0,0 +1,181 @@ +// +// Test_v3cross.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_v3cross.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static btVector3& v3cross_ref(btVector3& v1, btVector3& v2); + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_v3cross(void) +{ + btVector3 v1, v2, v3; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x,y,z); + v1.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x,y,z); + v2.setW(w); + + v3 = v1; + + btVector3 correct_res, test_res; + + { + float vNaN = BT_NAN; + correct_res.setValue(vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN); + correct_res = v3cross_ref(v1, v2); + test_res = v3.cross(v2); + + if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) + { + vlog( "Error - v3cross result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btVector3 vec3_arr1[DATA_SIZE]; + btVector3 vec3_arr2[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr1[k] = v3cross_ref(vec3_arr1[k], vec3_arr2[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr1[k] = vec3_arr1[k].cross(vec3_arr2[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +static btVector3& v3cross_ref(btVector3& v1, btVector3& v2) +{ + btScalar x,y,z; + x = v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]; + y = v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]; + z = v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]; + + v1.m_floats[0] = x; + v1.m_floats[1] = y; + v1.m_floats[2] = z; + + return v1; +} + + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3cross.h b/Test/Source/Tests/Test_v3cross.h new file mode 100644 index 0000000..79854fe --- /dev/null +++ b/Test/Source/Tests/Test_v3cross.h @@ -0,0 +1,22 @@ +// +// Test_v3cross.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3cross_h +#define BulletTest_Test_v3cross_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3cross(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3div.cpp b/Test/Source/Tests/Test_v3div.cpp new file mode 100644 index 0000000..bd58002 --- /dev/null +++ b/Test/Source/Tests/Test_v3div.cpp @@ -0,0 +1,178 @@ +// +// Test_v3div.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_v3div.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +#define BT_OP(a, b) ((a) / (b)) +// reference code for testing purposes +static inline btVector3& v3div_ref(btVector3& v1, btVector3& v2); + +static btVector3& v3div_ref(btVector3& v0, btVector3& v1, btVector3& v2) +{ + v0.m_floats[0] = BT_OP(v1.m_floats[0] , v2.m_floats[0]), + v0.m_floats[1] = BT_OP(v1.m_floats[1] , v2.m_floats[1]), + v0.m_floats[2] = BT_OP(v1.m_floats[2] , v2.m_floats[2]); + + return v0; +} + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_v3div(void) +{ + btVector3 v1, v2, v3; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x,y,z); + v1.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x,y,z); + v2.setW(w); + + v3 = v1; + + btVector3 correct_res, test_res; + + { + float vNaN = BT_NAN; + correct_res.setValue(vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN); + correct_res = v3div_ref(correct_res, v1, v2); + test_res = BT_OP(v3,v2); + + if( fabsf(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabsf(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabsf(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON*10 ) + { + vlog( "Error - v3div result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btVector3 vec3_arr0[DATA_SIZE]; + btVector3 vec3_arr1[DATA_SIZE]; + btVector3 vec3_arr2[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + w = BT_NAN; // w channel NaN + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr0[k] = v3div_ref(vec3_arr0[k], vec3_arr1[k], vec3_arr2[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr0[k] = BT_OP(vec3_arr1[k] , vec3_arr2[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3div.h b/Test/Source/Tests/Test_v3div.h new file mode 100644 index 0000000..21bfb61 --- /dev/null +++ b/Test/Source/Tests/Test_v3div.h @@ -0,0 +1,22 @@ +// +// Test_v3div.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3div_h +#define BulletTest_Test_v3div_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3div(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3dot.cpp b/Test/Source/Tests/Test_v3dot.cpp new file mode 100644 index 0000000..caa2967 --- /dev/null +++ b/Test/Source/Tests/Test_v3dot.cpp @@ -0,0 +1,164 @@ +// +// Test_v3dot.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_v3dot.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static inline +btScalar v3dot_ref( + const btVector3& v1, + const btVector3& v2); + +#define LOOPCOUNT 1000 +#define NUM_CYCLES 10000 + +int Test_v3dot(void) +{ + btVector3 v1, v2; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x,y,z); + v1.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x,y,z); + v2.setW(w); + + float correctDot0, testDot0; + + { + correctDot0 = w; + testDot0 = w; ; + correctDot0 = v3dot_ref(v1, v2); + testDot0 = v1.dot(v2); + + if( fabsf(correctDot0 - testDot0) > FLT_EPSILON * 4 ) + { + vlog( "Error - v3dot result error! %f != %f \n", correctDot0, testDot0); + + return 1; + } + } + +#define DATA_SIZE 1024 + + btVector3 vec3_arr1[DATA_SIZE]; + btVector3 vec3_arr2[DATA_SIZE]; + btScalar res_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + + res_arr[k] = w; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t k32 = (k & (DATA_SIZE-1)); + res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); k32++; + res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); k32++; + res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); k32++; + res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t k32 = k & (DATA_SIZE -1); + res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); k32++; + res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); k32++; + res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); k32++; + res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + + +static btScalar v3dot_ref(const btVector3& v1, + const btVector3& v2) +{ + return (v1.m_floats[0] * v2.m_floats[0] + + v1.m_floats[1] * v2.m_floats[1] + + v1.m_floats[2] * v2.m_floats[2]); +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3dot.h b/Test/Source/Tests/Test_v3dot.h new file mode 100644 index 0000000..b80a3af --- /dev/null +++ b/Test/Source/Tests/Test_v3dot.h @@ -0,0 +1,22 @@ +// +// Test_v3dot.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3dot_h +#define BulletTest_Test_v3dot_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3dot(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3interp.cpp b/Test/Source/Tests/Test_v3interp.cpp new file mode 100644 index 0000000..b033775 --- /dev/null +++ b/Test/Source/Tests/Test_v3interp.cpp @@ -0,0 +1,195 @@ +// +// Test_v3interp.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_v3interp.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static inline +btVector3& v3interp_ref( + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt); + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_v3interp(void) +{ + btVector3 v1, v2; + btScalar rt; + + float x,y,z,w; + + float vNaN = BT_NAN; + w = BT_NAN; // w channel NaN + + btVector3 correct_res, test_res; + + for (rt = 0.0f; rt <= 1.0f; rt += 0.1f) + { + correct_res.setValue(vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN); + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v1.setValue(x,y,z); + v1.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x,y,z); + v2.setW(w); + + correct_res = v3interp_ref(correct_res, v1, v2, rt); + test_res.setInterpolate3(v1, v2, rt); + + if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) + { + vlog( "Error - v3interp result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n" + "\n rt=%10.4f", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2], rt); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btVector3 vec3_arr1[DATA_SIZE]; + btVector3 vec3_arr2[DATA_SIZE]; + btScalar rt_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + + rt_arr[k] = RANDF_01; + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + v3interp_ref(vec3_arr1[k], vec3_arr1[k], vec3_arr2[k], rt_arr[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + + rt_arr[k] = RANDF_01; + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr1[k].setInterpolate3(vec3_arr1[k], vec3_arr2[k], rt_arr[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +static btVector3& +v3interp_ref( + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt) +{ + btScalar s = btScalar(1.0) - rt; + vr.m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0]; + vr.m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1]; + vr.m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2]; + + return vr; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3interp.h b/Test/Source/Tests/Test_v3interp.h new file mode 100644 index 0000000..502b1ad --- /dev/null +++ b/Test/Source/Tests/Test_v3interp.h @@ -0,0 +1,22 @@ +// +// Test_v3interp.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3interp_h +#define BulletTest_Test_v3interp_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3interp(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3lerp.cpp b/Test/Source/Tests/Test_v3lerp.cpp new file mode 100644 index 0000000..311d0bd --- /dev/null +++ b/Test/Source/Tests/Test_v3lerp.cpp @@ -0,0 +1,198 @@ +// +// Test_v3lerp.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_v3lerp.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static inline +btVector3& +v3lerp_ref( + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt); + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_v3lerp(void) +{ + btVector3 v1, v2; + btScalar rt; + + float x,y,z,w; + + float vNaN =BT_NAN; + w =BT_NAN; // w channel NaN + + btVector3 correct_res, test_res; + + for (rt = 0.0f; rt <= 1.0f; rt += 0.1f) + { + correct_res.setValue(vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN); + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v1.setValue(x,y,z); + v1.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x,y,z); + v2.setW(w); + + correct_res = v3lerp_ref(correct_res, v1, v2, rt); + test_res = v1.lerp(v2, rt); + + if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) + { + vlog( "Error - v3lerp result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n" + "\n rt=%10.4f", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2], rt); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btVector3 vec3_arr1[DATA_SIZE]; + btVector3 vec3_arr2[DATA_SIZE]; + btScalar rt_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + w =BT_NAN; // w channel NaN + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + + rt_arr[k] = RANDF_01; + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + v3lerp_ref(vec3_arr1[k], vec3_arr1[k], vec3_arr2[k], rt_arr[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x,y,z); + vec3_arr2[k].setW(w); + + rt_arr[k] = RANDF_01; + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr1[k] = vec3_arr1[k].lerp(vec3_arr2[k], rt_arr[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +static +btVector3& +v3lerp_ref( + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt) +{ + vr.m_floats[0] = v0.m_floats[0] + rt * (v1.m_floats[0] - v0.m_floats[0]); + vr.m_floats[1] = v0.m_floats[1] + rt * (v1.m_floats[1] - v0.m_floats[1]); + vr.m_floats[2] = v0.m_floats[2] + rt * (v1.m_floats[2] - v0.m_floats[2]); + + return vr; +} + +#endif //BT_USE_SSE + diff --git a/Test/Source/Tests/Test_v3lerp.h b/Test/Source/Tests/Test_v3lerp.h new file mode 100644 index 0000000..a38a12c --- /dev/null +++ b/Test/Source/Tests/Test_v3lerp.h @@ -0,0 +1,22 @@ +// +// Test_v3lerp.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3lerp_h +#define BulletTest_Test_v3lerp_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3lerp(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3norm.cpp b/Test/Source/Tests/Test_v3norm.cpp new file mode 100644 index 0000000..51e0dd3 --- /dev/null +++ b/Test/Source/Tests/Test_v3norm.cpp @@ -0,0 +1,170 @@ +// +// Test_v3norm.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_v3norm.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static inline btVector3& v3norm_ref(btVector3& v); + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 1000 + +int Test_v3norm(void) +{ + btVector3 v1, v2; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x,y,z); + v1.setW(w); + + v2 = v1; + + btVector3 correct_res, test_res; + + { + float vNaN = BT_NAN; + correct_res.setValue(vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN); + correct_res = v3norm_ref(v1); + test_res = v2.normalize(); + + if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) + { + vlog( "Error - v3norm result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btVector3 vec3_arr0[DATA_SIZE]; + btVector3 vec3_arr1[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + } + + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + vec3_arr0[k] = v3norm_ref(vec3_arr1[k]); + vec3_arr0[k+1] = v3norm_ref(vec3_arr1[k+1]); + vec3_arr0[k+2] = v3norm_ref(vec3_arr1[k+2]); + vec3_arr0[k+3] = v3norm_ref(vec3_arr1[k+3]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + } + + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + vec3_arr0[k] = vec3_arr1[k].normalize(); + vec3_arr0[k+1] = vec3_arr1[k+1].normalize(); + vec3_arr0[k+2] = vec3_arr1[k+2].normalize(); + vec3_arr0[k+3] = vec3_arr1[k+3].normalize(); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +static btVector3& v3norm_ref(btVector3& v) +{ + float dot = v.m_floats[0] * v.m_floats[0] + + v.m_floats[1] * v.m_floats[1] + + v.m_floats[2] * v.m_floats[2]; + + dot = 1.0f / sqrtf(dot); + v.m_floats[0] *= dot; + v.m_floats[1] *= dot; + v.m_floats[2] *= dot; + + return v; +} + +#endif //BT_USE_SSE + diff --git a/Test/Source/Tests/Test_v3norm.h b/Test/Source/Tests/Test_v3norm.h new file mode 100644 index 0000000..5b86b4a --- /dev/null +++ b/Test/Source/Tests/Test_v3norm.h @@ -0,0 +1,22 @@ +// +// Test_v3norm.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3norm_h +#define BulletTest_Test_v3norm_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3norm(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3rotate.cpp b/Test/Source/Tests/Test_v3rotate.cpp new file mode 100644 index 0000000..8c3aea9 --- /dev/null +++ b/Test/Source/Tests/Test_v3rotate.cpp @@ -0,0 +1,194 @@ +// +// Test_v3rotate.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_v3rotate.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static inline +btVector3& v3rotate_ref( + btVector3& v0, + btVector3& v1, + const btScalar& s); + +#define LOOPCOUNT 2048 +#define NUM_CYCLES 1000 + +int Test_v3rotate(void) +{ + btVector3 v1, v2; + float s; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x,y,z); + v1.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x,y,z); + v2.setW(w); + + s = RANDF_01 * (float) SIMD_PI; + + btVector3 correct_res, test_res; + + { + float vNaN = BT_NAN; + correct_res.setValue(vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN); + test_res = v1.rotate(v2, s); + correct_res = v3rotate_ref(v1, v2, s); + + if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) + { + vlog( "Error - v3rotate result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btVector3 vec3_arr0[DATA_SIZE]; + btVector3 vec3_arr1[DATA_SIZE]; + btScalar s_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr0[k].setValue(x,y,z); + vec3_arr0[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + s_arr[k] = RANDF_01 * (float)SIMD_PI; + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr0[k] = v3rotate_ref(vec3_arr0[k], vec3_arr1[k], s_arr[k]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr0[k].setValue(x,y,z); + vec3_arr0[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setW(w); + + s_arr[k] = RANDF_01 * (float)SIMD_PI; + } + + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + vec3_arr0[k ] = vec3_arr0[k ].rotate(vec3_arr1[k ], s_arr[k]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +static inline +btVector3& +v3rotate_ref( + btVector3& v0, + btVector3& wAxis, + const btScalar& _angle) +{ + btVector3 o = wAxis * wAxis.dot( v0 ); + btVector3 _x = v0 - o; + btVector3 _y; + + _y = wAxis.cross( v0 ); + + v0 = o + _x * cosf( _angle ) + _y * sinf( _angle ); + + return v0; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3rotate.h b/Test/Source/Tests/Test_v3rotate.h new file mode 100644 index 0000000..0c40fc4 --- /dev/null +++ b/Test/Source/Tests/Test_v3rotate.h @@ -0,0 +1,22 @@ +// +// Test_v3rotate.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3rotate_h +#define BulletTest_Test_v3rotate_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3rotate(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3sdiv.cpp b/Test/Source/Tests/Test_v3sdiv.cpp new file mode 100644 index 0000000..43d5735 --- /dev/null +++ b/Test/Source/Tests/Test_v3sdiv.cpp @@ -0,0 +1,181 @@ +// +// Test_v3sdiv.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + +#include "Test_v3sdiv.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static inline +btVector3& v3sdiv_ref( + btVector3& v, + const btScalar& s); + +#define LOOPCOUNT 2048 +#define NUM_CYCLES 1000 + +int Test_v3sdiv(void) +{ + btVector3 v1, v2; + btScalar s; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x,y,z); + v1.setW(w); + + v2.setValue(x,y,z); + v2.setW(w); + + s = (float) RANDF_16; + + btVector3 correct_res, test_res; + + { + float vNaN = BT_NAN; + correct_res.setValue(vNaN, vNaN, vNaN); + test_res.setValue(vNaN, vNaN, vNaN); + correct_res = v3sdiv_ref(v1, s); + test_res = (v2 /= s); + + if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) + { + vlog( "Error - v3sdiv result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + + return 1; + } + } + +#define DATA_SIZE LOOPCOUNT + + btVector3 vec3_arr[DATA_SIZE]; + btScalar s_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = uint64_t(-1LL); + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr[k].setValue(x,y,z); + vec3_arr[k].setW(w); + + s_arr[k] = RANDF_01; + } + + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + v3sdiv_ref( vec3_arr[k], s_arr[k]); + v3sdiv_ref( vec3_arr[k+1], s_arr[k+1]); + v3sdiv_ref( vec3_arr[k+2], s_arr[k+2]); + v3sdiv_ref( vec3_arr[k+3], s_arr[k+3]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr[k].setValue(x,y,z); + vec3_arr[k].setW(w); + + s_arr[k] = RANDF_01; + } + + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + vec3_arr[k] /= s_arr[k]; + vec3_arr[k+1] /= s_arr[k+1]; + vec3_arr[k+2] /= s_arr[k+2]; + vec3_arr[k+3] /= s_arr[k+3]; + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, + TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + +static inline +btVector3& +v3sdiv_ref( + btVector3& v, + const btScalar& s) +{ + btScalar recip = btScalar(1.0) / s; + + v.m_floats[0] *= recip; + v.m_floats[1] *= recip; + v.m_floats[2] *= recip; + + return v; +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3sdiv.h b/Test/Source/Tests/Test_v3sdiv.h new file mode 100644 index 0000000..648715e --- /dev/null +++ b/Test/Source/Tests/Test_v3sdiv.h @@ -0,0 +1,22 @@ +// +// Test_v3sdiv.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3sdiv_h +#define BulletTest_Test_v3sdiv_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3sdiv(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3skew.cpp b/Test/Source/Tests/Test_v3skew.cpp new file mode 100644 index 0000000..a9c90fb --- /dev/null +++ b/Test/Source/Tests/Test_v3skew.cpp @@ -0,0 +1,197 @@ +// +// Test_v3skew.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_v3skew.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static void +v3skew_ref( + const btVector3* v, + btVector3* v1, + btVector3* v2, + btVector3* v3); + +#define LOOPCOUNT 2048 +#define NUM_CYCLES 10000 + +int Test_v3skew(void) +{ + btVector3 v, v1, v2, v3, vt1, vt2, vt3; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v.setValue(x,y,z); + v.setW(w); + + v1.setValue(w,w,w); + v1.setW(w); + + vt3 = vt2 = vt1 = v3 = v2 = v1; + + { + v3skew_ref(&v, &v1, &v2, &v3); + v.getSkewSymmetricMatrix(&vt1, &vt2, &vt3); + /* + if( v1.m_floats[0] != vt1.m_floats[0] || + v1.m_floats[1] != vt1.m_floats[1] || + v1.m_floats[2] != vt1.m_floats[2] ) + */ + if(!(v1 == vt1)) + { + vlog( "Error - v3skew result error! " + "\ncorrect v1 = (%10.4f, %10.4f, %10.4f) " + "\ntested v1 = (%10.4f, %10.4f, %10.4f) \n", + v1.m_floats[0], v1.m_floats[1], v1.m_floats[2], + vt1.m_floats[0], vt1.m_floats[1], vt1.m_floats[2]); + + return 1; + } + + /* + if( v2.m_floats[0] != vt2.m_floats[0] || + v2.m_floats[1] != vt2.m_floats[1] || + v2.m_floats[2] != vt2.m_floats[2] ) + */ + if(!(v2 == vt2)) + { + vlog( "Error - v3skew result error! " + "\ncorrect v2 = (%10.4f, %10.4f, %10.4f) " + "\ntested v2 = (%10.4f, %10.4f, %10.4f) \n", + v2.m_floats[0], v2.m_floats[1], v2.m_floats[2], + vt2.m_floats[0], vt2.m_floats[1], vt2.m_floats[2]); + + return 1; + } + + /* + if( v3.m_floats[0] != vt3.m_floats[0] || + v3.m_floats[1] != vt3.m_floats[1] || + v3.m_floats[2] != vt3.m_floats[2] ) + */ + if(!(v3 == vt3)) + { + vlog( "Error - v3skew result error! " + "\ncorrect v3 = (%10.4f, %10.4f, %10.4f) " + "\ntested v3 = (%10.4f, %10.4f, %10.4f) \n", + v3.m_floats[0], v3.m_floats[1], v3.m_floats[2], + vt3.m_floats[0], vt3.m_floats[1], vt3.m_floats[2]); + + return 1; + } + } + +#define DATA_SIZE 256 + + btVector3 v3_arr0[DATA_SIZE]; + btVector3 v3_arr1[DATA_SIZE]; + btVector3 v3_arr2[DATA_SIZE]; + btVector3 v3_arr3[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr0[k].setValue(x,y,z); + v3_arr0[k].setW(w); + + v3_arr1[k].setValue(w,w,w); + v3_arr1[k].setW(w); + + v3_arr3[k] = v3_arr2[k] = v3_arr1[k]; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + size_t k32 = (k & (DATA_SIZE-1)); + v3skew_ref( &v3_arr0[k32], &v3_arr1[k32], &v3_arr2[k32], &v3_arr3[k32]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k < LOOPCOUNT; k++ ) + { + size_t k32 = (k & (DATA_SIZE -1)); + v3_arr0[k32].getSkewSymmetricMatrix(&v3_arr1[k32], &v3_arr2[k32], &v3_arr3[k32]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + + +static void +v3skew_ref( + const btVector3* v, + btVector3* v1, + btVector3* v2, + btVector3* v3) +{ + v1->setValue(0. ,-v->z(),v->y()); + v2->setValue(v->z() ,0. ,-v->x()); + v3->setValue(-v->y(),v->x() ,0.); +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3skew.h b/Test/Source/Tests/Test_v3skew.h new file mode 100644 index 0000000..255f4a2 --- /dev/null +++ b/Test/Source/Tests/Test_v3skew.h @@ -0,0 +1,22 @@ +// +// Test_v3skew.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3skew_h +#define BulletTest_Test_v3skew_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3skew(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Tests/Test_v3triple.cpp b/Test/Source/Tests/Test_v3triple.cpp new file mode 100644 index 0000000..f0ecbd4 --- /dev/null +++ b/Test/Source/Tests/Test_v3triple.cpp @@ -0,0 +1,180 @@ +// +// Test_v3triple.cpp +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + + + +#include "LinearMath/btScalar.h" +#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +#include "Test_v3triple.h" +#include "vector.h" +#include "Utils.h" +#include "main.h" +#include +#include + +#include + +// reference code for testing purposes +static btScalar +v3triple_ref( + const btVector3& v, + const btVector3& v1, + const btVector3& v2); + +#define LOOPCOUNT 1024 +#define NUM_CYCLES 10000 + +int Test_v3triple(void) +{ + btVector3 v1, v2, v3; + + float x,y,z,w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x,y,z); + v1.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x,y,z); + v2.setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3.setValue(x,y,z); + v3.setW(w); + + float correctTriple0, testTriple0; + + { + correctTriple0 = w; + testTriple0 = w; + testTriple0 = v3triple_ref(v1,v2,v3); + correctTriple0 = v1.triple(v2, v3); + + if( fabsf(correctTriple0 - testTriple0) > FLT_EPSILON * 4 ) + { + vlog( "Error - v3triple result error! %f != %f \n", correctTriple0, testTriple0); + + return 1; + } + } + +#define DATA_SIZE 1024 + + btVector3 v3_arr1[DATA_SIZE]; + btVector3 v3_arr2[DATA_SIZE]; + btVector3 v3_arr3[DATA_SIZE]; + btScalar res_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + for( k = 0; k < DATA_SIZE; k++ ) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr1[k].setValue(x,y,z); + v3_arr1[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr2[k].setValue(x,y,z); + v3_arr2[k].setW(w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr3[k].setValue(x,y,z); + v3_arr3[k].setW(w); + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = uint64_t(-1LL); + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t k32 = (k & (DATA_SIZE-1)); + res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); k32++; + res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); k32++; + res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); k32++; + res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); + } + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = uint64_t(-1LL); + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + { + size_t k32 = k & (DATA_SIZE -1); + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); k32++; + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); k32++; + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); k32++; + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if( currentTime < bestTime ) + bestTime = currentTime; + } + if( 0 == gReportAverageTimes ) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog( "Timing:\n" ); + vlog( " \t scalar\t vector\n" ); + vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + + return 0; +} + + +static btScalar +v3triple_ref( + const btVector3& v, + const btVector3& v1, + const btVector3& v2) +{ + return + v.m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + + v.m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + + v.m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); +} + +#endif //BT_USE_SSE diff --git a/Test/Source/Tests/Test_v3triple.h b/Test/Source/Tests/Test_v3triple.h new file mode 100644 index 0000000..16fcf2b --- /dev/null +++ b/Test/Source/Tests/Test_v3triple.h @@ -0,0 +1,22 @@ +// +// Test_v3triple.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Test_v3triple_h +#define BulletTest_Test_v3triple_h + +#ifdef __cplusplus +extern "C" { +#endif + +int Test_v3triple(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Test/Source/Utils.cpp b/Test/Source/Utils.cpp new file mode 100644 index 0000000..830f53a --- /dev/null +++ b/Test/Source/Utils.cpp @@ -0,0 +1,272 @@ +// +// File.c +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#include +#ifdef __APPLE__ +#include +#include +#include +#include +#else +#include "LinearMath/btAlignedAllocator.h" + +#endif //__APPLE__ + +#include + +#include "Utils.h" + +#pragma mark Timing + +int gReportNanoseconds = 0; + +#ifdef _WIN32 +#include +uint64_t ReadTicks( void ) +{ + return __rdtsc(); +} +double TicksToCycles( uint64_t delta ) +{ + return double(delta); +} + +double TicksToSeconds( uint64_t delta ) +{ + return double(delta); +} + +void *GuardCalloc( size_t count, size_t size, size_t *objectStride ) +{ + if (objectStride) + *objectStride = size; + return (void*) btAlignedAlloc(count * size,16); +} +void GuardFree( void *buf ) +{ + btAlignedFree(buf); +} + +#endif + + +#ifdef __APPLE__ + +uint64_t ReadTicks( void ) +{ + return mach_absolute_time(); +} + +double TicksToCycles( uint64_t delta ) +{ + static long double conversion = 0.0L; + if( 0.0L == conversion ) + { + // attempt to get conversion to nanoseconds + mach_timebase_info_data_t info; + int err = mach_timebase_info( &info ); + if( err ) + return __builtin_nanf(""); + conversion = (long double) info.numer / info.denom; + + // attempt to get conversion to cycles + if( 0 == gReportNanoseconds ) + { + uint64_t frequency = 0; + size_t freq_size = sizeof( frequency ); + err = sysctlbyname( "hw.cpufrequency_max", &frequency, &freq_size, NULL, 0 ); + if( err || 0 == frequency ) + vlog( "Failed to get max cpu frequency. Reporting times as nanoseconds.\n" ); + else + { + conversion *= 1e-9L /* sec / ns */ * frequency /* cycles / sec */; + vlog( "Reporting times as cycles. (%2.2f MHz)\n", 1e-6 * frequency ); + } + } + else + vlog( "Reporting times as nanoseconds.\n" ); + } + + return (double) (delta * conversion); +} + +double TicksToSeconds( uint64_t delta ) +{ + static long double conversion = 0.0L; + if( 0.0L == conversion ) + { + // attempt to get conversion to nanoseconds + mach_timebase_info_data_t info; + int err = mach_timebase_info( &info ); + if( err ) + return __builtin_nanf(""); + conversion = info.numer / (1e9L * info.denom); + } + + return (double) (delta * conversion); +} + + + +#pragma mark - +#pragma mark GuardCalloc + +#define kPageSize 4096 + + +typedef struct BufInfo +{ + void *head; + size_t count; + size_t stride; + size_t totalSize; +}BufInfo; + +static int GuardMarkBuffer( void *buffer, int flag ); + +void *GuardCalloc( size_t count, size_t size, size_t *objectStride ) +{ + if( objectStride ) + *objectStride = 0; + + // Round size up to a multiple of a page size + size_t stride = (size + kPageSize - 1) & -kPageSize; + + //Calculate total size of the allocation + size_t totalSize = count * (stride + kPageSize) + kPageSize; + + // Allocate + char *buf = (char*)mmap( NULL, + totalSize, + PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, + 0, 0 ); + if( MAP_FAILED == buf ) + { + vlog( "mmap failed: %d\n", errno ); + return NULL; + } + + // Find the first byte of user data + char *result = buf + kPageSize; + + // Record what we did for posterity + BufInfo *bptr = (BufInfo*) result - 1; + bptr->head = buf; + bptr->count = count; + bptr->stride = stride; + bptr->totalSize = totalSize; + + // Place the first guard page. Masks our record above. + if( mprotect(buf, kPageSize, PROT_NONE) ) + { + munmap( buf, totalSize); + vlog( "mprotect -1 failed: %d\n", errno ); + return NULL; + } + + // Place the rest of the guard pages + size_t i; + char *p = result; + for( i = 0; i < count; i++ ) + { + p += stride; + if( mprotect(p, kPageSize, PROT_NONE) ) + { + munmap( buf, totalSize); + vlog( "mprotect %lu failed: %d\n", i, errno ); + return NULL; + } + p += kPageSize; + } + + // record the stride from object to object + if( objectStride ) + *objectStride = stride + kPageSize; + + // return pointer to first object + return result; +} + + +void GuardFree( void *buf ) +{ + if( mprotect((char*)buf - kPageSize, kPageSize, PROT_READ) ) + { + vlog( "Unable to read buf info. GuardFree failed! %p (%d)\n", buf, errno ); + return; + } + + BufInfo *bptr = (BufInfo*) buf - 1; + + if( munmap( bptr->head, bptr->totalSize ) ) + vlog( "Unable to unmap data. GuardFree failed! %p (%d)\n", buf, errno ); +} + +int GuardMarkReadOnly( void *buf ) +{ + return GuardMarkBuffer(buf, PROT_READ); +} + +int GuardMarkReadWrite( void *buf) +{ + return GuardMarkBuffer(buf, PROT_READ | PROT_WRITE); +} + +int GuardMarkWriteOnly( void *buf) +{ + return GuardMarkBuffer(buf, PROT_WRITE); +} + +static int GuardMarkBuffer( void *buf, int flag ) +{ + if( mprotect((char*)buf - kPageSize, kPageSize, PROT_READ) ) + { + vlog( "Unable to read buf info. GuardMarkBuffer %d failed! %p (%d)\n", flag, buf, errno ); + return errno; + } + + BufInfo *bptr = (BufInfo*) buf - 1; + + size_t count = bptr->count; + size_t stride = bptr->stride; + + size_t i; + for( i = 0; i < count; i++ ) + { + if( mprotect(buf, stride, flag) ) + { + vlog( "Unable to protect segment %ld. GuardMarkBuffer %d failed! %p (%d)\n", i, flag, buf, errno ); + return errno; + } + bptr += stride + kPageSize; + } + + if( mprotect((char*)buf - kPageSize, kPageSize, PROT_NONE) ) + { + vlog( "Unable to protect leading guard page. GuardMarkBuffer %d failed! %p (%d)\n", flag, buf, errno ); + return errno; + } + + return 0; +} +#endif + +uint32_t random_number32(void) +{ + return ((uint32_t) rand() << 16) ^ rand(); +} + + +uint64_t random_number64(void) +{ + return ((uint64_t) rand() << 48) ^ + ((uint64_t) rand() << 32) ^ + ((uint64_t) rand() << 16) ^ + rand(); +} + diff --git a/Test/Source/Utils.h b/Test/Source/Utils.h new file mode 100644 index 0000000..9d30cd4 --- /dev/null +++ b/Test/Source/Utils.h @@ -0,0 +1,72 @@ +// +// Utils.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_Utils_h +#define BulletTest_Utils_h + +#include "btIntDefines.h" + + + +#include +#include + +#ifdef _WIN32 +#define LARGE_FLOAT17 (1.f * powf(2,17)) +#define RANDF_16 (random_number32() * powf(2,-16)) +#define RANDF_01 ( random_number32() * powf(2,-32) ) +#define RANDF ( random_number32() * powf(2,-8) ) +#define RANDF_m1p1 (2.0f*( random_number32() * powf(2,-32)-1.0f)) +#else +#define LARGE_FLOAT17 (0x1.0p17f) +#define RANDF_16 (random_number32() * 0x1.0p-16f) +#define RANDF_01 ( random_number32() * 0x1.0p-32f ) +#define RANDF ( random_number32() * 0x1.0p-8f ) +#define RANDF_m1p1 (2.0f*( random_number32() * 0x1.0p-32f )-1.0f) +#endif//_WIN32 + + +#ifdef __cplusplus +extern "C" { +#endif + + /********************* + * Timing * + *********************/ + extern int gReportNanoseconds; + + uint64_t ReadTicks( void ); + double TicksToCycles( uint64_t delta ); // Performance data should be reported in cycles most of the time. + double TicksToSeconds( uint64_t delta ); + + + /********************* + * Guard Heap * + *********************/ + // return buffer containing count objects of size size, with guard pages in betweeen. + // The stride between one object and the next is given by objectStride. + // objectStride may be NULL. Objects so created are freed with GuardFree + void *GuardCalloc( size_t count, size_t size, size_t *objectStride ); + void GuardFree( void * ); + // mark the contents of a guard buffer read-only or write-only. Return 0 on success. + int GuardMarkReadOnly( void *); + int GuardMarkWriteOnly( void *); + int GuardMarkReadWrite( void *); + + /********************* + * Printing * + *********************/ + #define vlog( ... ) printf( __VA_ARGS__ ) + uint32_t random_number32(void); + uint64_t random_number64(void); + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/Test/Source/btIntDefines.h b/Test/Source/btIntDefines.h new file mode 100644 index 0000000..a5e9e62 --- /dev/null +++ b/Test/Source/btIntDefines.h @@ -0,0 +1,19 @@ + +#ifndef BT_INT_DEFINES_H +#define BT_INT_DEFINES_H + +#ifdef __GNUC__ + #include +#elif defined(_MSC_VER) + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; +#else + typedef int int32_t; + typedef long long int int64_t; + typedef unsigned int uint32_t; + typedef unsigned long long int uint64_t; +#endif + +#endif //BT_INT_DEFINES_H diff --git a/Test/Source/main.cpp b/Test/Source/main.cpp new file mode 100644 index 0000000..2ae832c --- /dev/null +++ b/Test/Source/main.cpp @@ -0,0 +1,326 @@ +// +// main.c +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// +#include +#ifdef __APPLE__ +#include +#endif //__APPLE__ + +#include +#include +#include +#include "main.h" +#include "Utils.h" +#include "TestList.h" +#include "LinearMath/btScalar.h" + +#if defined (BT_USE_NEON) || defined (BT_USE_SSE_IN_API) + +#ifdef _WIN32 +#define strcasecmp _stricmp +#define basename(A) A +#endif + +#define EXIT_NO_ERROR INT_MIN + +//int gReportNanoseconds = 0; // in Utils.c + +int gReportAverageTimes = 0; +int gExitOnError = 0; +char *gFullPath = NULL; +const char *gAppName = NULL; +int gArgc; +const char **gArgv; + +typedef struct TestNode +{ + struct TestNode *next; + const char *name; +}TestNode; + +TestNode *gNodeList = NULL; + +static int ParseArgs( int argc, const char *argv[] ); +static void PrintUsage( void ); +static int Init( void ); +static void ListTests(void ); + +const char *gArch = +#ifdef __i386__ + "i386"; +#elif defined __x86_64__ + "x86_64"; +#elif defined __arm__ + "arm"; +#elif defined _WIN64 + "win64"; +#elif defined _WIN32 + "win32"; +#else + #error unknown arch +#endif + + + + + +#include + +int main (int argc, const char * argv[]) +{ + + // Enable just one test programatically (instead of command-line param) + // TestNode *node = (TestNode*) malloc( sizeof( TestNode ) ); + // node->name = "btDbvt"; + // node->next = 0; + // gNodeList = node; + + srand(0.f); + + int numPassedTests=0; + int numFailedTests= 0; + + int err; + + // Parse arguments. Build gNodeList. + if( (err = ParseArgs( argc, argv ) ) ) + { + if( EXIT_NO_ERROR == err ) + return 0; + + PrintUsage(); + return err; + } + + printf("Arch: %s\n", gArch ); + + if( gReportAverageTimes ) + printf( "Reporting average times.\n" ); + else + printf( "Reporting best times.\n" ); + + // Set a few things up + if( (err = Init() )) + { + printf( "Init failed.\n" ); + return err; + } + + if( NULL == gNodeList ) + { // test everything + printf( "No function list found. Testing everything...\n" ); + size_t i; + for( i = 0; NULL != gTestList[i].test_func; i++ ) + { + printf( "\n----------------------------------------------\n" ); + printf( "Testing %s:\n", gTestList[i].name ); + printf( "----------------------------------------------\n" ); + uint64_t startTime = ReadTicks(); + int local_error = gTestList[i].test_func(); + uint64_t currentTime = ReadTicks() - startTime; + if( local_error ) + { + numFailedTests++; + printf( "*** %s test failed with error: %d\n", gTestList[i].name, local_error ); + if( gExitOnError ) + return local_error; + if( 0 == err ) + err = local_error; + } + else + { + numPassedTests++; + printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime)); + } + } + } + else + { // test just the list + while( NULL != gNodeList ) + { + TestNode *currentNode = gNodeList; + gNodeList = gNodeList->next; + + // Find the test with that name + size_t i; + for( i = 0; NULL != gTestList[i].test_func; i++ ) + if( 0 == strcasecmp( currentNode->name, gTestList[i].name ) ) + break; + + if( NULL != gTestList[i].test_func ) + { + printf( "\n----------------------------------------------\n" ); + printf( "Testing %s:\n", gTestList[i].name ); + printf( "----------------------------------------------\n" ); + uint64_t startTime = ReadTicks(); + int local_error = gTestList[i].test_func(); + uint64_t currentTime = ReadTicks() - startTime; + if( local_error ) + { + numFailedTests++; + printf( "*** %s test failed with error: %d\n", gTestList[i].name, local_error ); + if( gExitOnError ) + return local_error; + if( 0 == err ) + err = local_error; + } + else + { + numPassedTests++; + printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime)); + } + } + else + { + printf( "\n***Error: Test name \"%s\" not found! Skipping.\n", currentNode->name ); + err = -1; + if( gExitOnError ) + return -1; + } + + free( currentNode ); + } + } + printf( "\n----------------------------------------------\n" ); + printf("numPassedTests = %d, numFailedTests = %d\n",numPassedTests,numFailedTests); + + free(gFullPath); + return err; +} + +static int Init( void ) +{ + // init the timer + TicksToCycles(0); + + return 0; +} + +static int ParseArgs( int argc, const char *argv[] ) +{ + int listTests = 0; + TestNode *list = NULL; + + gArgc = argc; + gArgv = argv; + gFullPath = (char*)malloc( strlen(argv[0]) + 1); + strcpy(gFullPath, argv[0]); + gAppName = basename( gFullPath ); + if( NULL == gAppName ) + gAppName = ""; + + printf( "%s ", gAppName ); + int skipremaining=0; + + size_t i; + for( i = 1; i < argc; i++ ) + { + const char *arg = argv[i]; + printf( "\t%s", arg ); + if( arg[0] == '-' ) + { + arg++; + while( arg[0] != '\0' ) + { + int stop = 0; + switch( arg[0] ) + { + case 'a': + gReportAverageTimes ^= 1; + break; + case 'e': + gExitOnError ^= 1; + break; + case 'h': + PrintUsage(); + return EXIT_NO_ERROR; + case 'l': + listTests ^= 1; + return EXIT_NO_ERROR; + case 's': + gReportNanoseconds ^= 1; + break; + case ' ': + stop = 1; + break; + case 'N'://ignore the -NSDocumentRevisionsDebugMode argument from XCode 4.3.2 + skipremaining = 1; + stop = 1; + break; + default: + printf( "\nError: Unknown flag \'%c\'\n", arg[0] ); + return -1; + } + if( stop ) + break; + arg++; + } + } + else + { // add function name to the list + TestNode *node = (TestNode*) malloc( sizeof( TestNode ) ); + node->name = arg; + node->next = list; + list = node; + } + if (skipremaining) + break; + } + + // reverse the list of test names, and stick on gNodeList + while( list ) + { + TestNode *node = list; + TestNode *next = node->next; + node->next = gNodeList; + gNodeList = node; + list = next; + } + + printf( "\n" ); + if( listTests ) + ListTests(); + + return 0; +} + + +static void PrintUsage( void ) +{ + printf("\nUsage:\n" ); + printf("%s: <-aehls> ", gAppName); + printf("Options:\n"); + printf("\t-a\tToggle report average times vs. best times. (Default: best times)\n"); + printf("\t-e\tToggle exit immediately on error behavior. (Default: off)\n"); + printf("\t-h\tPrint this message.\n"); + printf("\t-l\tToggle list available test names. (Default: off)\n"); + printf("\t-s\tToggle report times in cycles or nanoseconds. (Default: cycles)\n\n"); + printf("\tOptions may be followed by one or more test names. If no test names \n" ); + printf("\tare provided, then all tests are run.\n\n"); +} + +static void ListTests(void ) +{ + size_t i; + + printf("\nTests:\n"); + for( i = 0; NULL != gTestList[i].test_func; i++ ) + { + printf( "%19s", gTestList[i].name ); + if( NULL != gTestList[i].test_func ) + printf( "," ); + if( 3 == (i&3) ) + printf( "\n" ); + } +} +#else +#include +int main(int argc, char* argv[]) +{ + printf("error: no SIMD enabled through BT_USE_NEON or BT_USE_SSE_IN_API \n(enable in LinearMath/btScalar.h or through build system)\n"); + return 0; +} +#endif diff --git a/Test/Source/main.h b/Test/Source/main.h new file mode 100644 index 0000000..e8e5dd2 --- /dev/null +++ b/Test/Source/main.h @@ -0,0 +1,25 @@ +// +// main.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_main_h +#define BulletTest_main_h + +#ifdef __cplusplus +extern "C" { +#endif + + extern int gReportAverageTimes; // if 0, report best times + extern int gExitOnError; // if non-zero, exit as soon an an error is encountered + extern const char *gAppName; // the name of this application + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/Test/Source/vector.h b/Test/Source/vector.h new file mode 100644 index 0000000..c476a9e --- /dev/null +++ b/Test/Source/vector.h @@ -0,0 +1,70 @@ +// +// vector.h +// BulletTest +// +// Copyright (c) 2011 Apple Inc. +// + +#ifndef BulletTest_vector_h +#define BulletTest_vector_h + +#ifdef __SSE__ + typedef float float4 __attribute__ ((__vector_size__(16))); + #include +#endif + +#ifdef __SSE2__ + typedef double double2 __attribute__ ((__vector_size__(16))); + typedef char char16 __attribute__ ((__vector_size__(16))); + typedef unsigned char uchar16 __attribute__ ((__vector_size__(16))); + typedef short short8 __attribute__ ((__vector_size__(16))); + typedef unsigned short ushort8 __attribute__ ((__vector_size__(16))); + typedef int int4 __attribute__ ((__vector_size__(16))); + // typedef unsigned int uint4 __attribute__ ((__vector_size__(16))); + #ifdef __LP64__ + typedef long long2 __attribute__ ((__vector_size__(16))); + typedef unsigned long ulong2 __attribute__ ((__vector_size__(16))); + #else + typedef long long long2 __attribute__ ((__vector_size__(16))); + typedef unsigned long long ulong2 __attribute__ ((__vector_size__(16))); + #endif + #include +#endif + +#ifdef __SSE3__ + #include +#endif + +#ifdef __SSSE3__ + #include +#endif + +#ifdef __SSE4_1__ + #include +#endif + +#ifdef __arm__ + #include + #ifdef _ARM_ARCH_7 + #define ARM_NEON_GCC_COMPATIBILITY 1 + #include + typedef float float4 __attribute__ ((__vector_size__(16))); + typedef double double2 __attribute__ ((__vector_size__(16))); + typedef char char16 __attribute__ ((__vector_size__(16))); + typedef unsigned char uchar16 __attribute__ ((__vector_size__(16))); + typedef short short8 __attribute__ ((__vector_size__(16))); + typedef unsigned short ushort8 __attribute__ ((__vector_size__(16))); + typedef int int4 __attribute__ ((__vector_size__(16))); + typedef unsigned int uint4 __attribute__ ((__vector_size__(16))); + #ifdef __LP64__ + typedef long long2 __attribute__ ((__vector_size__(16))); + typedef unsigned long ulong2 __attribute__ ((__vector_size__(16))); + #else + typedef long long long2 __attribute__ ((__vector_size__(16))); + typedef unsigned long long ulong2 __attribute__ ((__vector_size__(16))); + #endif + #endif +#endif + + +#endif diff --git a/Test/premake4.lua b/Test/premake4.lua new file mode 100644 index 0000000..ffd7298 --- /dev/null +++ b/Test/premake4.lua @@ -0,0 +1,23 @@ + +project "AppUnitTest" + +if _OPTIONS["ios"] then + kind "WindowedApp" +else + kind "ConsoleApp" +end +targetdir "bin" + +includedirs {"../src","Source", "Source/Tests"} + +links { + "BulletDynamics","BulletCollision", "LinearMath" +} + +language "C++" + +files { + "Source/**.cpp", + "Source/**.h", +} + diff --git a/UnitTests/BulletUnitTests/CMakeLists.txt b/UnitTests/BulletUnitTests/CMakeLists.txt new file mode 100644 index 0000000..8f38f05 --- /dev/null +++ b/UnitTests/BulletUnitTests/CMakeLists.txt @@ -0,0 +1,31 @@ + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${BULLET_PHYSICS_SOURCE_DIR}/UnitTests/cppunit/include + + + ${VECTOR_MATH_INCLUDE} +) + +LINK_LIBRARIES( + cppunit + BulletMultiThreaded + BulletSoftBody + BulletDynamics + BulletCollision + LinearMath +) + +ADD_EXECUTABLE(AppBulletUnitTests + Main.cpp + TestBulletOnly.h + TestLinearMath.h + TestCholeskyDecomposition.cpp + TestCholeskyDecomposition.h + TestPolarDecomposition.cpp + TestPolarDecomposition.h + btCholeskyDecomposition.cpp + btCholeskyDecomposition.h +) + + diff --git a/UnitTests/BulletUnitTests/Main.cpp b/UnitTests/BulletUnitTests/Main.cpp new file mode 100644 index 0000000..1bc8999 --- /dev/null +++ b/UnitTests/BulletUnitTests/Main.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include + +#include "TestBulletOnly.h" +#include "TestLinearMath.h" +#include "TestPolarDecomposition.h" +#include "TestCholeskyDecomposition.h" + + CPPUNIT_TEST_SUITE_REGISTRATION( TestLinearMath ); + CPPUNIT_TEST_SUITE_REGISTRATION( TestBulletOnly ); + CPPUNIT_TEST_SUITE_REGISTRATION( TestPolarDecomposition ); + CPPUNIT_TEST_SUITE_REGISTRATION( TestCholeskyDecomposition ); + + + + +int main(int argc, char* argv[]) +{ + // Create the event manager and test controller + CPPUNIT_NS::TestResult controller; + + // Add a listener that colllects test result + CPPUNIT_NS::TestResultCollector result; + controller.addListener( &result ); + + // Add a listener that print dots as test run. + CPPUNIT_NS::BriefTestProgressListener progress; + controller.addListener( &progress ); + + // Add the top suite to the test runner + CPPUNIT_NS::TestRunner runner; + runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() ); + runner.run( controller ); + + // Print test in a compiler compatible format. + CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() ); + outputter.write(); + + getchar(); + + return result.wasSuccessful() ? 0 : 1; +} + diff --git a/UnitTests/BulletUnitTests/TestBulletOnly.h b/UnitTests/BulletUnitTests/TestBulletOnly.h new file mode 100644 index 0000000..bdac6f8 --- /dev/null +++ b/UnitTests/BulletUnitTests/TestBulletOnly.h @@ -0,0 +1,119 @@ +#ifndef TESTBULLETONLY_HAS_BEEN_INCLUDED +#define TESTBULLETONLY_HAS_BEEN_INCLUDED + +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" + +// --------------------------------------------------------------------------- + +class TestBulletOnly : public CppUnit::TestFixture +{ + btCollisionConfiguration * mCollisionConfig; + btCollisionDispatcher * mCollisionDispatch; + btBroadphaseInterface * mBroadphase; + btConstraintSolver * mConstraintSolver; + btDiscreteDynamicsWorld * mWorld; + btCollisionShape* mBodyShape; + btRigidBody* mRigidBody; + btDefaultMotionState* mMotionState; + +public: + + void setUp() + { + // Setup the world -- + mCollisionConfig = new btDefaultCollisionConfiguration; + mCollisionDispatch = new btCollisionDispatcher( mCollisionConfig ); + mBroadphase = new btDbvtBroadphase(); + mConstraintSolver = new btSequentialImpulseConstraintSolver(); + mWorld = new btDiscreteDynamicsWorld( mCollisionDispatch, mBroadphase, mConstraintSolver, mCollisionConfig ); + mWorld->setGravity( btVector3( 0, -9.81, 0 )); + + // Set up the rigid body -- + mBodyShape = new btBoxShape( btVector3( 1, 1, 1 ) ); + btScalar mass = 1; + btVector3 localInertia(0,0,0); + mBodyShape->calculateLocalInertia(mass,localInertia); + btTransform bodyInitial; + + mMotionState = new btDefaultMotionState(); + + bodyInitial.setIdentity(); + bodyInitial.setOrigin( btVector3( 0, 0, 0 ) ); + mRigidBody = new btRigidBody( buildConstructionInfo(mass, 0.5, 0.5, 0, 0, *mMotionState, mBodyShape ) ); + + mWorld->addRigidBody( mRigidBody ); + } + + void tearDown() + { + mWorld->removeRigidBody(mRigidBody); + delete mRigidBody; + delete mMotionState; + delete mBodyShape; + delete mWorld; + delete mConstraintSolver; + delete mBroadphase; + delete mCollisionDispatch; + delete mCollisionConfig; + + } + + btRigidBody::btRigidBodyConstructionInfo buildConstructionInfo( btScalar mass, btScalar friction, btScalar restitution, btScalar linearDamping, + btScalar angularDamping, btDefaultMotionState & state, btCollisionShape * shape ) + { + btVector3 inertia(0,0,0); + if (mass>0) + shape->calculateLocalInertia( mass, inertia ); + + btRigidBody::btRigidBodyConstructionInfo info( mass, &state, shape, inertia ); + + info.m_friction = friction; + info.m_restitution = restitution; + info.m_linearDamping = linearDamping; + info.m_angularDamping = angularDamping; + + return info; + } + + void testKinematicVelocity0() + { + mRigidBody->setMassProps( 1, btVector3( 1, 1, 1 ) ); + mRigidBody->updateInertiaTensor(); + mRigidBody->setCollisionFlags( btCollisionObject::CF_KINEMATIC_OBJECT ); + // -- . + + // Interpolate the velocity -- + + //btVector3 velocity( 1., 2., 3. ), spin( 0.1, 0.2, 0.3 ); + btVector3 velocity( 1., 2., 3. ), spin( 0.1, 0.2, .3 ); + btTransform interpolated; + + // TODO: This is inaccurate for small spins. + btTransformUtil::integrateTransform( mRigidBody->getCenterOfMassTransform(), velocity, spin, 1.0f/60.f, interpolated ); + + mRigidBody->setInterpolationWorldTransform( interpolated ); + + mWorld->stepSimulation( 1.f/60.f, 60, 1.0f/60.f ); + + CPPUNIT_ASSERT_DOUBLES_EQUAL( mRigidBody->getLinearVelocity().length2(), velocity.length2(), 1e-8 ); +#ifdef BT_USE_DOUBLE_PRECISION + CPPUNIT_ASSERT_DOUBLES_EQUAL( mRigidBody->getAngularVelocity().length2(), spin.length2(), 1e-4 ); +#else + CPPUNIT_ASSERT_DOUBLES_EQUAL( mRigidBody->getAngularVelocity().length2(), spin.length2(), 5e-3 ); +#endif //CPPUNIT_ASSERT_DOUBLES_EQUAL + + } + + CPPUNIT_TEST_SUITE(TestBulletOnly); + CPPUNIT_TEST(testKinematicVelocity0); + CPPUNIT_TEST_SUITE_END(); + +private: + +}; + +#endif diff --git a/UnitTests/BulletUnitTests/TestCholeskyDecomposition.cpp b/UnitTests/BulletUnitTests/TestCholeskyDecomposition.cpp new file mode 100644 index 0000000..d927bef --- /dev/null +++ b/UnitTests/BulletUnitTests/TestCholeskyDecomposition.cpp @@ -0,0 +1,68 @@ +#include "TestCholeskyDecomposition.h" +#include "btCholeskyDecomposition.h" + +void TestCholeskyDecomposition::testZeroMatrix() +{ + const btMatrix3x3 A(0,0,0,0,0,0,0,0,0); + const int result = choleskyDecompose(A, L); + + // The zero matrix is not positive definite so the decomposition does not + // exist. + CPPUNIT_ASSERT(result != 0); +} + +void TestCholeskyDecomposition::testIdentityMatrix() +{ + const btMatrix3x3 A = I; + const int result = choleskyDecompose(A, L); + + // The identity is a special case where the result should also be the + // identity. + CPPUNIT_ASSERT(result == 0); + CPPUNIT_ASSERT(equal(L, I)); +} + +void TestCholeskyDecomposition::testPositiveDefiniteMatrix() +{ + const btMatrix3x3 M(3,0,0,1,2,0,3,2,1); + const btMatrix3x3 A = M * M.transpose(); + const int result = choleskyDecompose(A, L); + + // By construction, the resulting decomposition of A should be equal to M + CPPUNIT_ASSERT(result == 0); + CPPUNIT_ASSERT(equal(L, M)); + CPPUNIT_ASSERT(equal(A, L * L.transpose())); +} + +void TestCholeskyDecomposition::testPositiveSemiDefiniteMatrix() +{ + const btMatrix3x3 M(3,0,0,1,0,0,3,2,1); + const btMatrix3x3 A = M * M.transpose(); + const int result = choleskyDecompose(A, L); + + // The matrix is semi definite, i.e. one of the eigenvalues is zero, so the + // Cholesky decomposition does not exist. + CPPUNIT_ASSERT(result != 0); +} + +void TestCholeskyDecomposition::testNegativeDefiniteMatrix() +{ + const btMatrix3x3 M(3,0,0,1,2,0,3,2,1); + const btMatrix3x3 A = M * M.transpose() * (-1.0); + const int result = choleskyDecompose(A, L); + + // The matrix is negative definite, i.e. all of the eigenvalues are negative, + // so the Cholesky decomposition does not exist. + CPPUNIT_ASSERT(result != 0); +} + +bool TestCholeskyDecomposition::equal(const btMatrix3x3& A, const btMatrix3x3& B) const +{ + for (unsigned int i = 0; i < 3; ++i) + for (unsigned int j = 0; j < 3; ++j) + if (btFabs(A[i][j] - B[i][j]) > SIMD_EPSILON) + return false; + + return true; +} + diff --git a/UnitTests/BulletUnitTests/TestCholeskyDecomposition.h b/UnitTests/BulletUnitTests/TestCholeskyDecomposition.h new file mode 100644 index 0000000..6ada976 --- /dev/null +++ b/UnitTests/BulletUnitTests/TestCholeskyDecomposition.h @@ -0,0 +1,52 @@ +#ifndef TESTCHOLESKYDECOMPOSITION_H +#define TESTCHOLESKYDECOMPOSITION_H + +#include +#include +#include + +class TestCholeskyDecomposition : public CppUnit::TestFixture +{ + public: + + void setUp() + { + I.setIdentity(); + } + + void tearDown() + { + } + + void testZeroMatrix(); + void testIdentityMatrix(); + void testPositiveDefiniteMatrix(); + void testPositiveSemiDefiniteMatrix(); + void testNegativeDefiniteMatrix(); + + CPPUNIT_TEST_SUITE(TestCholeskyDecomposition); + CPPUNIT_TEST(testZeroMatrix); + CPPUNIT_TEST(testIdentityMatrix); + CPPUNIT_TEST(testPositiveDefiniteMatrix); + CPPUNIT_TEST(testPositiveSemiDefiniteMatrix); + CPPUNIT_TEST(testNegativeDefiniteMatrix); + CPPUNIT_TEST_SUITE_END(); + + private: + /** + * Returns TRUE if the specified matrices are equal and FALSE otherwise. + * + * @param A - the first matrix to be tested. + * @param B - the second matrix to be tested. + * + * @return a boolean indicating whether the specified matrix is symmetric. + */ + bool equal(const btMatrix3x3& A, const btMatrix3x3& B) const; + + private: + btMatrix3x3 L; + btMatrix3x3 I; +}; + +#endif // TESTCHOLESKYDECOMPOSITION_H + diff --git a/UnitTests/BulletUnitTests/TestLinearMath.h b/UnitTests/BulletUnitTests/TestLinearMath.h new file mode 100644 index 0000000..6221db4 --- /dev/null +++ b/UnitTests/BulletUnitTests/TestLinearMath.h @@ -0,0 +1,210 @@ +#ifndef TEST_LINEAR_MATH_HAS_BEEN_INCLUDED +#define TEST_LINEAR_MATH_HAS_BEEN_INCLUDED + +#include "cppunit/TestFixture.h" +#include "cppunit/extensions/HelperMacros.h" + +#include "LinearMath/btScalar.h" + +#define TEST_NUM_UNITSPHERE_POINTS 42 + +namespace +{ + struct compLess + { + bool operator()(const int& p1, const int& p2) const + { + return p1 < p2; + } + }; +} + +static btVector3 sPenetrationDirections[TEST_NUM_UNITSPHERE_POINTS] = + { + btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), + btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), + btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), + btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), + btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), + btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), + btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), + btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), + btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), + btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), + btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), + btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), + btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), + btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), + btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), + btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), + btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), + btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), + btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), + btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), + btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), + btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), + btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), + btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), + btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), + btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), + btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), + btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), + btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), + btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), + btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), + btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), + btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), + btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), + btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), + btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), + btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), + btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), + btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), + btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), + btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), + btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) + }; + + + +// --------------------------------------------------------------------------- + +class TestLinearMath : public CppUnit::TestFixture +{ + + + +public: + + void setUp() + { + } + + void tearDown() + { + } + + + void testNormalize() + { + + const btVector3 xaxis(1,0,0); + const btVector3 yaxis(0,1,0); + const btVector3 zaxis(0,0,1); + + const btVector3 negxaxis(-1,0,0); + const btVector3 negyaxis(0,-1,0); + const btVector3 negzaxis(0,0,-1); + + btVector3 vec; + + vec.setValue(1e-20,0,0); + vec.safeNormalize(); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, vec.length2(), 1e-6 ); + + vec.setValue(1e20,0,0); + vec.safeNormalize(); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, vec.length2(), 1e-6 ); + + //vec.setValue(1e-20,0,0); + //vec.normalize(); + //CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, vec.length2(), 1e-5 ); + + vec.setValue(1e19,0,0); + vec.normalize(); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, vec.length2(), 1e-5 ); + + } + + void testQuicksort() + { + int tests = 0; + int numElems = 100; + btAlignedObjectArray m_unsortedIntegers; + m_unsortedIntegers.resize(numElems); + for (int i=0;i=0) + CPPUNIT_ASSERT_DOUBLES_EQUAL( angle, compAngle, 1e-5 ); + else + { + CPPUNIT_ASSERT_DOUBLES_EQUAL( btFabs(angle), btFabs(compAngle), 1e-5 ); + } + btVector3 compAxis = quat.getAxis(); + + if (compAngle>SIMD_EPSILON) + { + if (i>=0) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL( axis.getX(), compAxis.getX(), 1e-4 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( axis.getY(), compAxis.getY(), 1e-4 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( axis.getZ(), compAxis.getZ(), 1e-4 ); + } else + { + btScalar sign = compAngle*angle<0? -1 : 1; + CPPUNIT_ASSERT_DOUBLES_EQUAL( sign*axis.getX(), compAxis.getX(), 1e-4 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( sign*axis.getY(), compAxis.getY(), 1e-4 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( sign*axis.getZ(), compAxis.getZ(), 1e-4 ); + } + } else + { + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.f, compAxis.getX(), 1e-4 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, compAxis.getY(), 1e-4 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, compAxis.getZ(), 1e-4 ); + + } + } + } + } + + + + + CPPUNIT_TEST_SUITE(TestLinearMath); + CPPUNIT_TEST(testQuicksort); + CPPUNIT_TEST(testNormalize); + CPPUNIT_TEST(testQuaternionGetAxisAngle); + + CPPUNIT_TEST_SUITE_END(); + +private: + +}; + +#endif //TEST_LINEAR_MATH_HAS_BEEN_INCLUDED diff --git a/UnitTests/BulletUnitTests/TestPolarDecomposition.cpp b/UnitTests/BulletUnitTests/TestPolarDecomposition.cpp new file mode 100644 index 0000000..c24ccc7 --- /dev/null +++ b/UnitTests/BulletUnitTests/TestPolarDecomposition.cpp @@ -0,0 +1,103 @@ +#include "TestPolarDecomposition.h" +#include "BulletSoftBody/btSoftBodyInternals.h" +#include "LinearMath/btPolarDecomposition.h" +#include "btCholeskyDecomposition.h" + +namespace +{ + const int MAX_ITERATIONS = btPolarDecomposition::DEFAULT_MAX_ITERATIONS; + const btScalar TOLERANCE = btPolarDecomposition::DEFAULT_TOLERANCE; +} + +void TestPolarDecomposition::testZeroMatrix() +{ + const btMatrix3x3 A(0,0,0,0,0,0,0,0,0); + const int iterations = PolarDecompose(A, U, H); + + // The decomposition should fail because the zero matrix is singular + CPPUNIT_ASSERT(iterations == MAX_ITERATIONS); +} + +void TestPolarDecomposition::testSingularMatrix() +{ + const btMatrix3x3 A(1,0,0,1,0,0,0,0,1); + + const int iterations = PolarDecompose(A, U, H); + + // The cdecomposition should fail because the matrix is singular. + CPPUNIT_ASSERT(iterations == MAX_ITERATIONS); +} + +void TestPolarDecomposition::testPoorlyConditionedMatrix() +{ + const btScalar e = btScalar(TOLERANCE); + const btMatrix3x3 A(1,0,0,1,e,0,0,0,1); + + const int iterations = PolarDecompose(A, U, H); + + // The decomposition should succeed, however, the matrix is poorly + // conditioned, i.e. as 'e' approaches zero, the matrix approaches a singular + // matrix (no inverse). + CPPUNIT_ASSERT(iterations < MAX_ITERATIONS); + CPPUNIT_ASSERT(equal(A, U * H)); + CPPUNIT_ASSERT(isOrthogonal(U)); + CPPUNIT_ASSERT(isSymmetric(H)); + CPPUNIT_ASSERT(isPositiveDefinite(H)); +} + +void TestPolarDecomposition::testIdentityMatrix() +{ + const btMatrix3x3 A = I; + const int iterations = PolarDecompose(A, U, H); + + // The identity is a special case. The decomposition should succeed and both + // the U and H matrices should be equal to the identity. + CPPUNIT_ASSERT(iterations < MAX_ITERATIONS); + CPPUNIT_ASSERT(equal(A, U * H)); + CPPUNIT_ASSERT(equal(U, I)); + CPPUNIT_ASSERT(equal(H, I)); +} + +void TestPolarDecomposition::testNonSingularMatrix() +{ + const btMatrix3x3 A(4, 6, 6, 9, 2, 0, 1, 6, 0); + const int iterations = PolarDecompose(A, U, H); + + // The decomposition should succeed so that A = U*H, where U is orthogonal and + // H is symmetric and positive definite. + CPPUNIT_ASSERT(iterations < MAX_ITERATIONS); + CPPUNIT_ASSERT(equal(A, U * H)); + CPPUNIT_ASSERT(isOrthogonal(U)); + CPPUNIT_ASSERT(isSymmetric(H)); + CPPUNIT_ASSERT(isPositiveDefinite(H)); +} + +bool TestPolarDecomposition::equal(const btMatrix3x3& A, const btMatrix3x3& B) const +{ + for (unsigned int i = 0; i < 3; ++i) + for (unsigned int j = 0; j < 3; ++j) + if (btFabs(A[i][j] - B[i][j]) > TOLERANCE) + return false; + + return true; +} + +bool TestPolarDecomposition::isOrthogonal(const btMatrix3x3& A) const +{ + return equal(A.transpose() * A, I); +} + +bool TestPolarDecomposition::isPositiveDefinite(const btMatrix3x3& A) const +{ + static btMatrix3x3 storage; + return (0 == choleskyDecompose(A, storage)); +} + +bool TestPolarDecomposition::isSymmetric(const btMatrix3x3& A) const +{ + return + (btFabs(A[0][1] - A[1][0]) < TOLERANCE) && + (btFabs(A[0][2] - A[2][0]) < TOLERANCE) && + (btFabs(A[1][2] - A[2][1]) < TOLERANCE); +} + diff --git a/UnitTests/BulletUnitTests/TestPolarDecomposition.h b/UnitTests/BulletUnitTests/TestPolarDecomposition.h new file mode 100644 index 0000000..ed0ba98 --- /dev/null +++ b/UnitTests/BulletUnitTests/TestPolarDecomposition.h @@ -0,0 +1,88 @@ +#ifndef TESTPOLARDECOMPOSITION_H +#define TESTPOLARDECOMPOSITION_H + +#include +#include +#include + +class TestPolarDecomposition : public CppUnit::TestFixture +{ + public: + + void setUp() + { + I.setIdentity(); + } + + void tearDown() + { + } + + void testPoorlyConditionedMatrix(); + void testSingularMatrix(); + void testNonSingularMatrix(); + void testIdentityMatrix(); + void testZeroMatrix(); + + CPPUNIT_TEST_SUITE(TestPolarDecomposition); + CPPUNIT_TEST(testZeroMatrix); + CPPUNIT_TEST(testSingularMatrix); + CPPUNIT_TEST(testPoorlyConditionedMatrix); + CPPUNIT_TEST(testIdentityMatrix); + CPPUNIT_TEST(testNonSingularMatrix); + CPPUNIT_TEST_SUITE_END(); + + private: + /** + * Returns TRUE if the specified matrix is orthogonal and FALSE otherwise. + * Orthogonality is checked by pre-multiplying the matrix by its transpose + * and comparing the result to the identity matrix. + * + * @param A - the matrix that is being tested + * + * @return a boolean indicating whether the specified matrix is orthogonal. + */ + bool isOrthogonal(const btMatrix3x3& A) const; + + /** + * Returns TRUE if the specified matrix is symmetric and FALSE otherwise. + * The symmetry of the matrix is determined by simplying testing the + * equality of the three off-diagonal elements. + * + * @param A - the matrix that is being tested. + * + * @return a boolean indicating whether the specified matrix is symmetric. + */ + bool isSymmetric(const btMatrix3x3& A) const; + + /** + * Returns TRUE if the specified matrix is positive definite and FALSE + * otherwise. The positive definiteness of the matrix is determined by + * calculating the Cholesky decomposition of the matrix; If the Cholesky + * decomposition exists, the original matrix is positive definite. + * + * @param A - the matrix that is being tested. + * + * @return a boolean indicating whether the specified matrix is positive + * definite. + */ + bool isPositiveDefinite(const btMatrix3x3& A) const; + + /** + * Returns TRUE if the specified matrices are equal and FALSE otherwise. + * + * @param A - the first matrix to be tested. + * @param B - the second matrix to be tested. + * + * @return a boolean indicating whether the specified matrix is symmetric. + */ + bool equal(const btMatrix3x3& A, const btMatrix3x3& B) const; + + private: + btMatrix3x3 U; + btMatrix3x3 H; + btMatrix3x3 I; +}; + +#endif // TESTPOLARDECOMPOSITION_H + diff --git a/UnitTests/BulletUnitTests/btCholeskyDecomposition.cpp b/UnitTests/BulletUnitTests/btCholeskyDecomposition.cpp new file mode 100644 index 0000000..4b3d655 --- /dev/null +++ b/UnitTests/BulletUnitTests/btCholeskyDecomposition.cpp @@ -0,0 +1,40 @@ +#include "btCholeskyDecomposition.h" + +int choleskyDecompose(const btMatrix3x3& A, btMatrix3x3& L) +{ + // TODO Check that the A matrix is symmetric + + // Iterate over the elements of the upper triangle of A + for (unsigned int i = 0; i < 3; ++i) + { + for (unsigned int j = i; j < 3; ++j) + { + btScalar sum = A[i][j]; + for (unsigned int k = 0; k < i; ++k) + { + sum -= L[i][k] * L[j][k]; + } + + if (i != j) + { + L[j][i] = sum / L[i][i]; + } + else + { + if (sum <= btScalar(0)) + { + return btCholeskyDecomposition::FAILURE_POSITIVE_DEFINITE; + } + + L[i][i] = sqrt(sum); + } + } + } + + L[0][1] = btScalar(0); + L[0][2] = btScalar(0); + L[1][2] = btScalar(0); + + return btCholeskyDecomposition::SUCCESS; +} + diff --git a/UnitTests/BulletUnitTests/btCholeskyDecomposition.h b/UnitTests/BulletUnitTests/btCholeskyDecomposition.h new file mode 100644 index 0000000..7740ab8 --- /dev/null +++ b/UnitTests/BulletUnitTests/btCholeskyDecomposition.h @@ -0,0 +1,19 @@ +#ifndef BTCHOLESKYDECOMPOSITION_H +#define BTCHOLESKYDECOMPOSITION_H + +#include "LinearMath/btMatrix3x3.h" + +struct btCholeskyDecomposition +{ + enum Result + { + SUCCESS, + FAILURE_SYMMETRY, + FAILURE_POSITIVE_DEFINITE + }; +}; + +int choleskyDecompose(const btMatrix3x3& A, btMatrix3x3& L); + +#endif // BTCHOLESKYDECOMPOSITION_H + diff --git a/UnitTests/CMakeLists.txt b/UnitTests/CMakeLists.txt new file mode 100644 index 0000000..275633b --- /dev/null +++ b/UnitTests/CMakeLists.txt @@ -0,0 +1,2 @@ + +SUBDIRS( cppunit BulletUnitTests) diff --git a/UnitTests/cppunit/AUTHORS b/UnitTests/cppunit/AUTHORS new file mode 100644 index 0000000..b600073 --- /dev/null +++ b/UnitTests/cppunit/AUTHORS @@ -0,0 +1,6 @@ +Michael Feathers +Jerome Lacoste +E. Sommerlade +Baptiste Lepilleur +Bastiaan Bakker +Steve Robbins diff --git a/UnitTests/cppunit/BUGS b/UnitTests/cppunit/BUGS new file mode 100644 index 0000000..64fb00f --- /dev/null +++ b/UnitTests/cppunit/BUGS @@ -0,0 +1,6 @@ + KNOWN BUGS + ---------- + +The handling of html and man pages in doc/Makefile.am is +flawed. It will not pass "make distcheck". + diff --git a/UnitTests/cppunit/CMakeLists.txt b/UnitTests/cppunit/CMakeLists.txt new file mode 100644 index 0000000..1468214 --- /dev/null +++ b/UnitTests/cppunit/CMakeLists.txt @@ -0,0 +1,74 @@ +INCLUDE_DIRECTORIES( + include +) + +ADD_LIBRARY(cppunit + +#core + src/cppunit/AdditionalMessage.cpp + src/cppunit/Asserter.cpp + src/cppunit/Exception.cpp + src/cppunit/Message.cpp + src/cppunit/SourceLine.cpp + src/cppunit/SynchronizedObject.cpp + src/cppunit/Test.cpp + src/cppunit/TestAssert.cpp + src/cppunit/TestCase.cpp + src/cppunit/TestComposite.cpp + src/cppunit/TestFailure.cpp + src/cppunit/TestLeaf.cpp + src/cppunit/TestPath.cpp + src/cppunit/TestResult.cpp + src/cppunit/TestRunner.cpp + src/cppunit/TestSuite.cpp + +#extension + src/cppunit/RepeatedTest.cpp + src/cppunit/TestCaseDecorator.cpp + src/cppunit/TestDecorator.cpp + src/cppunit/TestSetUp.cpp + +#helper + src/cppunit/TestFactoryRegistry.cpp + src/cppunit/TestNamer.cpp + src/cppunit/TestSuiteBuilderContext.cpp + src/cppunit/TypeInfoHelper.cpp + +#listener + src/cppunit/BriefTestProgressListener.cpp + src/cppunit/TestResultCollector.cpp + src/cppunit/TestSuccessListener.cpp + src/cppunit/TextTestProgressListener.cpp + src/cppunit/TextTestResult.cpp + +#output + src/cppunit/CompilerOutputter.cpp + src/cppunit/TextOutputter.cpp + src/cppunit/XmlOutputter.cpp + src/cppunit/XmlOutputterHook.cpp + +#plugin + src/cppunit/BeOsDynamicLibraryManager.cpp + src/cppunit/DynamicLibraryManager.cpp + src/cppunit/DynamicLibraryManagerException.cpp + src/cppunit/PlugInManager.cpp + src/cppunit/PlugInParameters.cpp + src/cppunit/ShlDynamicLibraryManager.cpp + src/cppunit/TestPlugInDefaultImpl.cpp + src/cppunit/UnixDynamicLibraryManager.cpp + src/cppunit/Win32DynamicLibraryManager.cpp + +#protector + src/cppunit/DefaultProtector.cpp + src/cppunit/Protector.cpp + src/cppunit/ProtectorChain.cpp + +#textui + src/cppunit/TextTestRunner.cpp + +#tools + src/cppunit/StringTools.cpp + src/cppunit/XmlDocument.cpp + src/cppunit/XmlElement.cpp + +) \ No newline at end of file diff --git a/UnitTests/cppunit/ChangeLog b/UnitTests/cppunit/ChangeLog new file mode 100644 index 0000000..210aae3 --- /dev/null +++ b/UnitTests/cppunit/ChangeLog @@ -0,0 +1,3749 @@ +2010-July-23 Erwin Coumans + * add cmake build support, removed other build systems + +2009-11-24 Baptiste Lepilleur + * src/cppunit/TestResult.cpp: flush stdout & stderr in destructor + to avoid message loss in case of crash (bug #2832029). + + * include/cppunit/plugin/TestPlugIn.h: + * include/cppunit/plugin/TestPlugInDefaultImpl.h: added missing dllexport + for CppUnitTestPlugIn. + + * include/cppunit/portability/config-msvc6.h: + * include/cppunit/portability/Portability.h: Added macro + CPPUNIT_UNIQUE_COUNTER on MSVS 7.0+ using __COUNTER__ to + fix bug #2031696. + + * examples/examples2008.sln: Fixed compilation issue in debug + configuration with VS2008 (due to incorrect configuration + being picked up). + + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.cpp: fixed + memory leak in getCommandLineArguments() (bug #1721408). + + * config/ax_cxx_gcc_abi_demangle.m4: + * src/cppunit/TypeInfoHelper.cpp: Fixed demangling of symbols on gcc 4.3 + (bug #2796543). + +2009-11-23 Baptiste Lepilleur + + * src/DllPlugInTester/Makefile.am: + * examples/cppunittest/Makefile.am: + * examples/money/Makefile.am: + * examples/simple/Makefile.am: + * examples/hierarchy/Makefile.am: Applied patch #2807259 + contributed by Jan Echternach. LIBADD_DL contains a list of libraries + like "-ldl". Thus, it should be in LDADD instead of LDFLAGS in case + one of the libraries depends on a path set in LDFLAGS. + +2008-12-16 Andy Dent + * src/msvc6/testrunner/MsDevCallerListCtrl.cpp: + * INSTALL-VS.Net2008.txt: Added updated project and instructions for + building under Visual Studio.Net 2008 and fixed compilation issue. + +2008-10-12 Baptiste Lepilleur + + * doc/cookbook.dox: fixed typos. + +2008-02-21 Steve M. Robbins + * examples/cppunittest/OrthodoxTest.h: + * examples/cppunittest/XMLOutputterTest.cpp: + * examples/hierarchy/main.cpp: + * include/cppunit/extensions/ExceptionTestCaseDecorator.h: + * src/cppunit/BriefTestProgressListener.cpp: + * src/cppunit/TestFactoryRegistry.cpp: + * src/cppunit/TestPlugInDefaultImpl.cpp: + * src/cppunit/TestSuccessListener.cpp: + * src/cppunit/TextProgressListener.cpp: + * src/cppunit/XmlOutputterHook.cpp: + * src/DllPlugInTester/CommandLineParserTest.cpp: + * src/DllPlugInTester/DllPlugInTesterTest.cpp: Changes to suppress + warnings of gcc -Wall -W -ansi, mainly from patch [1898225]. + +2008-02-20 Steve M. Robbins + + * examples/money/MoneyTest.h (TestFixture): Change deprecated + CPPUNIT_TEST_EXCEPTION to simple CPPUNIT_TEST. + * examples/money/MoneyTest.cpp (testAddThrow): Wrap throwing + expression "money += money123FF" inside CPPUNIT_ASSERT_THROW(). + + * Changes to build without warnings using gcc -Wall -W -ansi. + Applied patch [1898225] to remove name of unused argument and use + no-arg version of main(). Tested on both GCC 4.2.3 and a + prerelease of GCC 4.3.0. + * examples/cppunittest/assertion_traitsTest.cpp (test_toString): + Change template parameter of + CPPUNIT_NS::assertion_traits::toString() to const char*, + avoiding a deprecated conversion from string literal to char*. + * src/DllPlugInTester/CommandLineParserTest.cpp (parse): move + semicolon of empty loop body to its own line, avoiding a warning + in GCC 4.3. + +2008-02-20 Steve M. Robbins + + * configure.in: Update CPPUNIT_MICRO_VERSION for release 1.12.1. + +2008-02-07 Steve M. Robbins + + * src/qttestrunner/MostRecentTests.h: + * src/qttestrunner/TestRunnerModel.h: Change from to + replacment ; avoids use of compatibility headers. + +2007-03-04 Steve M. Robbins + + * include/cppunit/portability/FloatingPoint.h (floatingPointIsFinite): Change + return type to int, following the convention of isfinite(), finite(), etc. + +2007-02-25 Baptiste Lepilleur + + * doc/cookbook.dox: changed suite() to return a TestSuite instead + of a Test to avoid introducing unnecessary complexity. + +2007-02-24 Steve M. Robbins + + * include/cppunit/portability/FloatingPoint.h: Include Portability.h. + +2007-02-24 Baptiste Lepilleur + + * src/cppunit/TestAssert.cpp (assertDoubleEquals): Moved finite & NaN + tests to include/cppunit/portability/FloatingPoint.h. Changed + implementation assertDoubleEquals to explicitly test for NaN + in case of non-finite values to force equality failure in the + presence of NaN. Previous implementation failed on Microsoft + Visual Studio 6 (on this platform: NaN == NaN). + * examples/cppunittest/TestAssertTest.cpp: Add more unit tests to + test the portable floating-point primitive. Added missing + include . + + * include/cppunit/portability/Makefile.am: + * include/cppunit/portability/FloatingPoint.h: Added file. Extracted + isfinite() from TestAssert.cpp. + + * include/cppunit/config-evc4: + * include/cppunit/config-msvc6: Added support for _finite(). + +2007-01-30 Steve M. Robbins + + * examples/cppunittest/assertion_traitsTest.h: + * examples/cppunittest/assertion_traitsTest.cpp: New. Test + assertion_traits<>. + + * examples/cppunittest/Makefile.am: Add + assertion_traitsTest.{h,cpp}. + + * examples/cppunittest/TestAssertTest.h: + * examples/cppunittest/TestAssertTest.cpp: Add + testAssertDoubleEqualsPrecision() to test precision of failure + message. + +2007-01-27 Steve M. Robbins + + * examples/cppunittest/TestAssertTest.cpp: + * examples/cppunittest/TestAssertTest.h: Remove declaration of + unimplemented functions testAssertDoubleNotEquals1 and + testAssertDoubleNotEquals2. Factor new method + testAssertDoubleNonFinite out of existing testAssertDoubleEquals. + + * src/cppunit/Win32DynamicLibraryManager.cpp (doLoadLibrary): + Unconditionally use ANSI version of LoadLibrary() and other + functions with string arguments. + +2007-01-26 Steve M. Robbins + + * config/ax_cxx_have_isfinite.m4: New. Autoconf macro that tests + for finite() in C++ mode. + * configure.in: Check for isfinite() and finite(). + + * examples/cppunittest/TestAssertTest.cpp (testAssertDoubleEquals): + * src/cppunit/TestAssert.cpp (assertDoubleEquals): Account for + non-finite values. + +2007-01-11 Steve M. Robbins + + * examples/cppunittest/MockFunctor.h: + * examples/cppunittest/MockProtector.h: + * examples/cppunittest/XmlOutputterTest.cpp: + * examples/cppunittest/XmlUniformiser.cpp: + * src/DllPlugInTester/CommandLineParser.cpp: + * src/cppunit/DynamicLibraryManagerException.cpp: + * src/cppunit/TestCaseDecorator.cpp: + * src/cppunit/TextTestRunner.cpp: + * src/cppunit/XmlDocument.cpp: Arrange field initializers in + correct order. + + * include/cppunit/plugin/TestPlugIn.h (struct CppUnitTestPlugIn): + * include/cppunit/extensions/TestFixtureFactory.h (class TestFixtureFactory): + * include/cppunit/XmlOutputterHook.h (XmlOutputterHook): Add + virtual destructor to virtual class. + + * examples/cppunittest/TestAssertTest.cpp: Put a C++ statement in + the first argument of CPPUNIT_ASSERT_THROW() and + CPPUNIT_ASSERT_NO_THROW(). + + * examples/hierarchy/main.cpp (main): Return value now reflects + whether tests passed. + * examples/hierarchy/Makefile.am (XFAIL_TESTS): New. Mark hierachy + test program as an expected failure. + + * Makefile.am (dist-hook): Don't fail if $(distdir)/lib already + exists. + + * config/bb_enable_doxygen.m4 (BB_ENABLE_DOXYGEN): Add quotes + around function name, BB_ENABLE_DOXYGEN. + +2006-10-26 Baptiste Lepilleur + * include/cppunit/TestResult.h: + * include/cppunit/ui/Config.h: fixed compilation issues with QtTestRunner. + +2006-06-29 Baptiste Lepilleur + * Makefile.am: + * lib/.keepme: added dummy file to prevent lib/ removal by some + unzip clients. Fixed bug #1527877 . + + * src/msvc6/TesRunner/TestRunner.rc: + * src/msvc6/testpluginrunner/TestPlugInRunner.rc: Fixed bug #1528212 + (some resources wrongly tagged as French). + +2006-06-29 Baptiste Lepilleur + * include/cppunit/ui/text/TextTestRunner.h + * src/cppunit/TextTestRunner.cpp: applied patch #1210013 to remove + hidden virtual function warning. + + * autogen.sh: applied patch #1449380 contributed by Sander Temme + to allow running autogen on Mac OS X. + + * doc/header.html: updated to handle new tabs css required for + html doc generated with doxygen 1.4.7. + + * src/msvc6/testrunner/MsDevCallerListCtrl.cpp: applied correction + provided to fix bug #1498175 (double click on failure does not + goto failure). + +2006-03-04 Baptiste Lepilleur + * contrib/xml-xsl/report.xsl: reported correction posted on the wiki. + + * removed debian/ directory. An up to date patch can be found at: + packages.debian.org. + + * cppunit.spec.in: applied patch #1242905 partially (%post and %postun). + + * cppunit.pc.in: + * configure.in: + * Makefile.am: integrated patch from Robert Leight to generate pkg-config. + +2006-02-04 Baptiste Lepilleur + * include/cppunit/TestListener.h: + * src/qttestrunner/TestRunnerModel.cpp: removed compilation warning. + +2006-02-01 Baptiste Lepilleur + * examples/qt: integrated Ernst patch from qt examples. + +2005-12-12 Baptiste Lepilleur + * src/qttestrunner: integrated Ernst patch for QtTestRunner and Qt 3.x. + Enhanced qmake project files to handle multiple build configuration + +2005-11-27 Baptiste Lepilleur + * doc/cookbook.dox: fixed type (patch #1334567) + +2005-11-06 Baptiste Lepilleur + * include/cppunit/config/SourcePrefix.h: disable warning #4996 + (sprintf is deprecated) for visual studio 2005. + + * include/cppunit/TestAssert.h: use sprintf_s instead of sprintf for + visual studio 2005. + + * examples/ClockerPlugIn/ClockerPlugIn.cpp + * examples/DumperPlugIn/DumperPlugIn.cpp: use SourcePrefix.h. Fixed + wrong macro usage to implement DllMain. + + * examples/msvc6/HostApp/ExamplesTestCase.h + * examples/msvc6/HostApp/ExamplesTestCase.cpp + * examples/simple/ExamplesTestCase.h + * examples/simple/ExamplesTestCase.cpp: removed divideByZero test case + as it cause some crash on some platforms. + + +2005-10-27 Baptiste Lepilleur + * include/cppunit/TestAssert.h: added missing #include + +2005-07-30 Baptiste Lepilleur + * include/cppunit/config/SourcePrefix.h: added, prefix added at begining of sources + to remove warning. Removed most warning when compiling with VC++ 6sp6. + + * examples/money/Money.h: + * examples/money/MoneyTest.cpp: added assert equal usage. + +2005-07-30 Baptiste Lepilleur + + * include/cppunit/config/config-msvc6.h: auto-detect if RTTI are enabled + the _CPPRTTI macro (defined by the compiler when enabling RTTI). + + * include/cppunit/config/config-msvc6.h: added missing macro definition + CPPUNIT_HAVE_CPP_CAST. + + * src/cppunit/TestResultCollector.cpp: fixed memory leak in destructor. + +2005-07-15 Baptiste Lepilleur + + * config/bb_enable_doxygen.m4: Rolled back Brad Hards patch as it break + generation of doc/Makefile.am. + + * cppunit.spec.in: Applied patch #1232555 from Patrice Dumas. This file is + use for RPM packaging. + + * development snapshot release 1.11.0. + +2005-07-09 Baptiste Lepilleur + + * doc/Money.dox: + * include/cppunit/TestSuite.h: + * include/cppunit/XmlOutputterHook.h: applied Brad Hards patch + that correct miscellaneous doc generation issues (unescaped <>, \...). + + * include/cppunit/plugin/TestPlugIn.h: + * include/cppunit/CompilerOutputter.h: + * doc/CppUnit-win.dox: removed a few documentation generation warnings. + + * config/bb_enable_doxygen.m4: applied Brad Hards patch to remove warning + when running ./autogen.sh or aclocal. + + * doc/money.dox: fixed bad usage of CPPUNIT_ASSERT_EQUALS. + +2005-07-05 Baptiste Lepilleur + + * Examples/simple/Makefile.am: do not install 'simple' programm + (patch #1230784). + +2005-07-05 Baptiste Lepilleur + + * include/cppunit/TestResultCollector.h + * src/cppunit/TestResultCollector.cpp: fixed memory leak + occuring when calling reset(). + + * src/cppunit/DllMain.cpp: added work-around for mingw compilation + for BLENDFUNCTION macro issue when including windows.h. + + * src/qttestrunner/TestRunnerDlgImpl.cpp: fixed display of multiline + messages. + + * include/cppunit/Portability.h: better integration of compiler output + for gcc on Mac OS X with Xcode (contributed by Claus Broch). + +2005-06-14 Baptiste Lepilleur + * src/msvc6/testrunner/ProgressBar.cpp: applied patch from bug #1165875, + (use system color for border instead of hard-coded color). + + * src/cppunit/Makefile.am: + * configure.in: MinGW, cygwin: enable build of shared library when using + libtool. patch #1194394 contributed by Stéphane Fillod. + + * cppunit.m4: applied patch #1076398 contributed by Henner Sudek. Fix + version number comparison in AM_PATH_CPPUNIT. + + * contrib/xml-xsl/cppunit2junit.txt + * contrib/xml-xsl/cppunit2junit.xsl + * contrib/readme.txt: XSLT for compatibility with Ant junit xml formatter. + Patch #1112053 contributed by Norbert Barbosa. + +2005-02-23 Baptiste Lepilleur + + * examples/hierarchy/BoardGameTest.h: + * examples/hierarchy/ChessTest.h: fixed compilation issue, prefixed access + to class member with 'this' (inheriting from template parameter + dependent class). + +2004-11-19 Baptiste Lepilleur + + * include/cppunit/Message.h + * include/cppunit/SourceLine.h: + * src/cppunit/Message.cpp: + * src/cppunit/SourceLine.cpp: provided thread-safe copy constructor on + platform that do not provide thread-safe copy constructor for std::string. + +2004-11-08 Baptiste Lepilleur + + * include/cppunit/TestAssert.h: fixed portability bug pointed out by + Neil Ferguson. + +2004-11-06 Baptiste Lepilleur + + * include/cppunit/TestAssert.h: integrated Neil Ferguson patch for high + precision conversion to string for double number. Modified the patch + to works even if DBL_DIG C99 macro is not defined. + + * include/cppunit/Portability.h: fixed EVC++ 4 detection. + + * src/cppunit/Win32DynamicLibraryManager.cpp: integrated patch #1024428, + MinGW compilation under Windows XP. + +2004-11-05 Baptiste Lepilleur + + * include/cppunit/TestAssert.h: + * src/cppunit/TestAssert.cpp: integrated Neil Ferguson patch for missing + _MESSAGE assertion variants. Also enhanced the failure message of a + few assertions. + +2004-09-10 Baptiste Lepilleur + + * src/msvc6/DSPlugIn/StdAfx.h: add #error to prevent compilation on VC 7. + + * src/msvc6/testrunner/MsDevCallerListCtrl.cpp: + * src/msvc6/testrunner/MsDevCallerListCtrl.h: integrated go to source line + features on double click contributed by Max Quatember and + Andreas Pfaffenbichler. + +2004-08-01 Baptiste Lepilleur + + * include/cppunit/XmlOutputter.h: + * include/cppunit/tools/XmlDocument.h: + * src/cppunit/XmlDocument.cpp: + * src/cppunit/XmlOutputter.cpp: integrated patch #997006 from Akos Maroy. + This patch makes the 'standalone' attribute in XML header optional. + +2004-06-25 Baptiste Lepilleur + + * include/cppunit/Portability.h: moved OStringStream alias definition to + portability/Stream.h. User need to define EVC4 to indicate that + config-evc4.h should be used. (how to we detect this automatically ?). + Notes that this means it might be needed to add #include to some + headers since its no longer included by Portability.h. + + * include/cppunit/portability/Stream.h: define alias OStringStream, stdCOut(), + and OFileStream. If CPPUNIT_NO_STREAM is defined (evc4 config), then provides + our own implementation (based on sprintf and fwrite). + + * include/cppunit/config/config-evc4.h: config file for embedded visual c++ 4. + Still need to detect for this platform in Portability.h (currently relying on + EVC4 being defined...) + + * *.[cpp/h]: most source files have been impacted with the following change: + #include -> #include + std::ostream -> CPPUNIT_NS::OStream + std::ofstream -> CPPUNIT_NS::OFileStream + std::cout -> CPPUNIT_NS::stdCOut() + std::endl -> "\n" + Also, code using std::cin as been defined out if CPPUNIT_NO_STREAM was defined. + The exact list of impact files can be obtain in CVS using tags: + TG_CPPUNIT_NO_STREAM_BEFORE & TG_CPPUNIT_NO_STREAM_AFTER. + +2004-06-19 Baptiste Lepilleur + + * cppunit.m4: patch #946302, AM_PATH_CPPUNIT doesn't report result + if CppUnit is missing. + + +2004-06-18 Baptiste Lepilleur + + * Release 10.0.2 + + * include/cppunit/extension/TestSuiteBuilderContext.h: + * src/cppunit/TestSuiteBuilderContext.cpp: fixed bug #921843. This bug + was caused by a known STL bug in VC++ 6. + See http://www.dinkumware.com/vc_fixes.html issue with shared + std::map in dll. As a work-around the map has been replaced by a vector. + + * src/DllPlugInTester/*.cpp: bug #941625, string literal using char * + instead of const char *. Patch contributed by Curt Arnold has been + applied. + + * src/msvc6/testrunner/TestRunnerDlg.h: + * src/msvc6/testrunner/TestRunnerDlg.cpp: + * src/msvc6/testpluginrunner/TestPlugIn.cpp: + * src/msvc6/testpluginrunner/TestPlugInRunnerApp.cpp: + * src/msvc6/testpluginrunner/TestPlugInRunnerModel.cpp: + * src/msvc6/testpluginrunner/TestPlugInRunnerModel.h: bug #952912, + memory leaks when loading/reloading plug-ins. + +2004-06-17 Baptiste Lepilleur + + * include/cppunit/Portability.h: + * include/cppunit/plugin/TestPlugIn.h: fixed report compilation issue + with mingw & cygwin. WIN32 is now always defined if _WIN32 is defined. + Bug #945737 & #930338. + + * doc/Makefile.am: fixed bug #940650 => cp -dpR, removed option -p since + there is no link to preserve anyway (does not exist on SunOs). + + * src/cppunit/TestPath.cpp: bug #938753, array bound read in + splitPathString() with substr if an empty string is passed. + + * src/*/*.dsp: bug #933154, post build fail in directory with spaces. + + +2004-06-16 Baptiste Lepilleur + + * release 1.10.0 + + * install-UNIX.txt: added some notes concerning Sun CC 5.5 & AIX. + + * examples/*/*.dsp: fixed project settings (rtti not enabled). + +2004-03-13 Baptiste Lepilleur + + * release 1.9.14 + +2004-03-13 Baptiste Lepilleur + + * cppunit-config.in: bug #903363, missing -ldl from the output of + cppunit-config --libs. Fixed thanks Eric Blossom patch. + + * examples/qt/Main.cpp: + * examples/qt/ExampleTestCase.h: fixed bug #789672: QT example should + use CPPUNIT_NS macro. + + * src/cppunit/UnixDynamicLibraryManager.cpp: applied patch #816563 + from Gareth Sylvester. Adding RTLD_GLOBAL allows test plug-ins + to provide symbols to shared objects they load themselves. + + * examples/cppunittest/TestAssertTest.h: + * examples/cppunittest/TestAssertTest.cpp: + * examples/cppunittest/XmlUniformiserTest.h: + * examples/cppunittest/XmlUniformiserTest.cpp: + * include/cppunit/TestAssert.h: add the exception assertion macros + from cppunit 2: CPPUNIT_ASSERT_THROW, CPPUNIT_ASSERT_NO_THROW, + CPPUNIT_ASSERT_ASSERTION_FAIL, CPPUNIT_ASSERT_ASSERTION_PASS. + Updated unit test to use and test the new macros. + + * include/cppunit/extensions/HelperMacros.h: deprecated the + test case factory that check for exception (CPPUNIT_TEST_FAIL & + CPPUNIT_TEST_EXCEPTION). + + +2004-02-20 Baptiste Lepilleur + + * release 1.9.12 + +2004-02-18 Baptiste Lepilleur + + * configure.in: + * makefile.am: + * config/ax_cxx_gcc_abi_demangle.m4: + * src/cppunit/TypeInfoHelper.cpp: added patch from + Neil Ferguson to use gcc c++ abi to demangle typeinfo + name when available. + +2003-05-15 Baptiste Lepilleur + + * include/cppunit/plugin/testplugin.h: fixed bug #767358, wrong + preprocessor symbol for SHL_LOADER. + +2003-05-15 Baptiste Lepilleur + + * include/cppunit/config/config-msvc6.h: changed the compiler outputter + default format (CPPUNIT_COMPILER_LOCATION_FORMAT) for Visual Studio 7.0. + Assertion now appears in the task list. + +2003-05-07 Baptiste Lepilleur + + * include/cppunit/extensions/Makefile.am: removed TestSuiteBuilder.h + + * Makefile.am + * configure.in + * config/ac_dll.m4 + * examples/cppunittest/Makefile.am + * examples/hierarchy/Makefile.am + * examples/money/Makefile.am + * examples/simple/Makefile.am + * include/cppunit/config/SelectDllLoader.h + * include/cppunit/plugin/TestPlugIn.h + * include/cppunit/tools/Algorithm.h + * src/DllPlugInTester/Makefile.am + * src/cppunit/Makefile.am + * src/cppunit/TestDecorator.cpp + * src/cppunit/ShlDynamicLibraryManager.cpp + * src/cppunit/UnixDynamicLibraryManager.cpp + * src/cppunit/Win32DynamicLibraryManager.cpp: applied patch from + Abdessattar Sassi to add support + for plug-in to hp-ux (patch #721546). + + * INSTALL-unix: added build instruction for HP-UX. + +2003-04-06 Baptiste Lepilleur + + * include/cppunit/extensions/TestSuiteBuilder.h: removed (unused) + +2003-03-31 Baptiste Lepilleur + + * src/cppunit/DynamicLibraryManager.cpp: fixed compilation issue on Mingw + (bug #711583) + +2003-03-20 Baptiste Lepilleur + + * include/cppunit/extensions/TestNamer.h: + * src/cppunit/TestNamer.cpp: Fixed bug #704684, TestNamer has non-virtual + destructor. + +2003-03-15 Baptiste Lepilleur + + * src/msvc6/testrunner/DynamicWindow/cdxCDynamicWndEx.cpp: + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.cpp: + * examples/msvc6/HostApp/HostApp.cpp: + * src/msvc6/testpluginrunner/TestPlugInRunnerApp.cpp: fixed compatibility + issues with vc7 MFC. + + * include/cppunit/tools/Algorithm.h: + * examples/cppunittest/XmlOutputterTest.cpp: + * examples/cppunittest/XmlUniformiser.*: + * src/cppunit/CompilerOutputter.cpp: + * src/cppunit/ProtectorChain.cpp: + * src/cppunit/StringTools.cpp: + * src/cppunit/TestPath.cpp: + * src/cppunit/TypeInfoHelper.cpp: + * src/cppunit/XmlElement.cpp: + * src/cppunit/XmlOutputter.cpp: + * src/DllPlugInTester/CommandLineParser.h: + * src/msvc6/testrunner/TestRunnerDlg.cpp: switched to using unsigned index in loop to + avoid signed/unsigned warning in vc7. + + * include/cppunit/extension/ExceptionTestCaseDecorator.h: removed dll export + on template (caused link error on vc7). + +2003-03-11 Baptiste Lepilleur + * config/bb_enable_doxygen.m4: + * doc/Makefile.am: applied Luke Dunstan's fix for bug #700730 (spaces not + allowed in doxygen path) + + * src/cppunit/XmlElement.cpp: + * src/examples/cppunittest/XmlUniformser.cpp: fixed bug #676505 (no space + between attributes of XmlElement). + + * include/cppunit/tools/Algorithm.h: + * src/cppunit/TestResult.cpp: + * src/msvc6/testrunner/TestRunnerModel.cpp: added removeFromSequence + algorithm in Algorithm.h to fix STLPort compatibility issue + (std::remove use the one of cstdio instead of algorithm). Bug #694971. + + * src/examples/cppunittest/TrackedTestCase.cpp: + * src/examples/cppunittest/CppUnitTestMain.cpp: + * src/examples/money/Money.h: partially applied patch #699794. Fixed + compilation issues with Borland C++ 6. + +2003-01-23 Baptiste Lepilleur + + * include/cppunit/extensions/TestNamer.h: fixed bug #662666 (missing include + for typeinfo). + +2002-12-12 Baptiste Lepilleur + + * src/cppunit/TestResult.cpp: TestFailure are no longer passed as temporary, + but explicitely instantiated on the stack. Work around AIX compiler bug. + +2002-12-03 Baptiste Lepilleur + + * include/cppunit/TextTestResult.h: added missing dll export for + operator << (bug #610119). + +2002-12-02 Baptiste Lepilleur + + * include/cppunit/plugin/DynamicLibraryManagerException.h: added constructor + to fix compilation issues on recents version of gcc and sun CC (bug #619059) + + * include/cppunit/input/XmlInputHelper.h: added. + + * src/cppunit/XmlOuputter.cpp: use iterator instead of const_iterator. + + * src/src/msvc6/testrunner/DynamicWindow/cdxCDynamicWnd.cpp: added call to + IsUp() in cdxCDynamicWnd::DoOnGetMinMaxInfo() before calling + GetBorderSize() which caused an assertion. Bug #643612. + +2002-09-10 Baptiste Lepilleur + + * include/cppunit/extensions/TestSuiteBuilderContext.h: + * src/cppunit/TestSuiteBuilderContext.cpp: added addProperty() and + getStringProperty(). Added macros CPPUNIT_TEST_SUITE_PROPERTY. + + * src/msvc6/testrunner/TestRunnerDlg.cpp: integrated Tim Threlkeld's + bug fix #610162: browse button was disabled if history was empty. + + * src/msvc6/testrunner/DynamicWindow/cdxCSizeIconCtrl.cpp: integrated + Tim Threlkeld's bug fix #610191: common control were not initialized. + + * include/cppunit/extensions/ExceptionTestCaseDecorator.h: bug #603172, + missing Message construction. + + * src/cppunit/DefaultProtector.cpp: bug #603172. Fixed missing ';'. + + * src/cppunit/TestCase.cpp: bug #603671. Removed unguarded typeinfo + include. + + * examples/cppunittests/*Suite.h: bug #603666. Added missing Portability.h + include. + +2002-09-01 Baptiste Lepilleur + + * include/cppunit/ui/text/TextTestRunner.h: fixed header guards. + +2002-08-29 Baptiste Lepilleur + + * include/cppunit/TestResult.h: + * src/cppunit/TestResult.cpp: fixed shouldStop() bug. + +2002-08-29 Baptiste Lepilleur + + * include/cppunit/CompilerOutputter.h: + * include/cppunit/Exception.h: + * include/cppunit/Protector.h: + * include/cppunit/TestListener.h: + * include/cppunit/TestPath.h: + * include/cppunit/TestResult.h: + * include/cppunit/TestRunner.h: + * include/cppunit/XmlOutputter.h: + * include/cppunit/plugin/DynamicLibraryManager.h: + * include/cppunit/plugin/PlugInManager.h: + * include/cppunit/plugin/PlugInParameters.h: + * include/cppunit/TestPlugIn.h: + * src/cppunit/DefaultProtector.h: + * src/cppunit/ProtectorChain.h: + * src/cppunit/ProtectorContext.h: + * src/cppunit/TestCase.cpp: + * src/cppunit/TestResult.cpp: fixed a dew documentation bugs. + + * include/cppunit/TestResult.h: + * src/cppunit/TestResult.cpp: moved documentation to header. + +2002-08-29 Baptiste Lepilleur + + * include/cppunit/Asserter.h: + * include/cppunit/Message.h: + * include/cppunit/extensions/TestNamer.h: + * include/cppunit/extensions/TestSuiteBuilder.h: + * include/cppunit/tools/XmlDocument.h: + * include/cppunit/tools/XmlElement.h: Fixed a few documentation bugs. + +2002-08-28 Baptiste Lepilleur + + * include/cppunit/Portability.h: added CPPUNIT_STATIC_CAST. + + * include/cppunit/extensions/TestFixtureFactory.h: extracted from + HelperMacros.h. Added template class ConcretTestFixtureFactory. + + * include/cppunit/extensions/TestSuiteBuilderContext.h: + * src/cppunit/TestSuiteBuilderContext.cpp: added. Context used + to add test case to the fixture suite. Prevent future + compatibility break for custom test API. + + * include/cppunit/extensions/HelperMacros.h: mostly rewritten. No + longer use TestSuiteBuilder. Added support for abstract test fixture + through macro CPPUNIT_TEST_SUITE_END_ABSTRACT. Made custom test API + easier to use. + + * examples/cppunittest/HelperMacrosTest.h: + * examples/cppunittest/HelperMacrosTest.cpp: updated against + HelperMacros.h changes. + +2002-08-27 Baptiste Lepilleur + + * CodingGuideLines.txt: updated for OS/390 C++ limitation. + + * examples/cppunittests/MockFunctor.h: added. Mock Functor to help + testing. + + * examples/cppunittests/MockProtector.h: qdded. Mock Protector to help + testing. + + * examples/cppunittests/TestResultTest.h + * examples/cppunittests/TestResultTest.cpp: added tests for + pushProtector(), popProtector() and protect(). + + * include/cppunit/TestAssert.h: removed default message value from + assertEquals(). Caused compilation error on OS/390. + + * include/cppunit/plugin/PlugInParameters.h: + * src/cppunit/PlugInParameters.cpp: renamed commandLine() to + getCommandLine(). + + * src/msvc6/testrunner/TestRunnerDlg.h: + * src/msvc6/testrunner/TestRunnerDlg.cpp: bug fix, disabled Browse + button while running tests. + +2002-08-22 Steve M. Robbins + + * cppunit.m4: Doc fix: MINIMUM-VERSION is not optional when using + this macro. + +2002-08-04 Baptiste Lepilleur + + * src/cppunit/XmlDocument.cpp: fixed compatility bug with C++ builder. + + * include/cppunit/plugin/Parameters.h: renamed PlugInParameters.h. + + * src/cppunit/PlugInParameter.cpp: added. Implementation of class + PlugInParameters. + + * examples/DumperPlugIn/DumperPlugIn.cpp: + * examples/ClockerPlugIn/ClockerPlugIn.cpp: + * src/DllPlugInTester/CommandLineParser.h: + * src/DllPlugInTester/CommandLineParser.cpp: + * include/cppunit/plugin/TestPlugInDefaultImpl.h: + * src/cppunit/TestPlugInDefaultImpl.cpp: + * include/cppunit/plugin/PlugInManager.h: + * src/cppunit/PlugInManager.cpp: updated against PlugInParameter + change. + +2002-08-03 Baptiste Lepilleur + + * include/cppunit/XmlOutputterHook.h: integrated Stephan Stapel + documentation update. + +2002-08-03 Baptiste Lepilleur + + * include/cppunit/Exception.h: + * src/cppunit/Exception.h: added setMessage(). + + * include/cppunit/Protector.h: + * src/cppunit/Protector.cpp: added class ProtectorGuard. Change the + reportXXX() method to support Exception passing and SourceLine. + + * include/cppunit/TestCaller.h: removed 'expect exception' features. + It is now handled by ExceptionTestCaseDecorator and TestCaller no + longer need default template argument support. + + * include/cppunit/TestCase.h: + * include/cppunit/extensions/TestCaller.h: runTest() is now public + instead of protected, so that it can be decorated. + + * include/cppunit/TestResult.h: + * src/cppunit/TestResult.h: added pushProtector() and popProtector() + methods. This allow user to specify their own exception trap when + running test case. + + * include/cppunit/extensions/TestDecorator.h: + * src/cppunit/TestDecorator.cpp: added. Extracted from TestDecorator.h. + The test passed to the constructor is now owned by the decorator. + + * include/cppunit/extensions/TestCaseDecorator.h: + * src/cppunit/TestCaseDecorator.cpp: added. Decorator for TestCase + setUp(), tearDown() and runTest(). + + * include/cppunit/extensions/ExceptionTestCaseDecorator.h: added. + TestCaseDecorator to expect that a specific exception is thrown. + + * include/cppunit/extensions/HelperMacros.h: updated against TestCaller + change. + + * src/cppunit/DefaultFunctor.h: fixed bug (did not return underlying + test return code). + + * src/cppunit/ProtectorChain.cpp: fixed bug in chaing return code. + + * src/cppunit/DefaultFunctor.h: fixed bug. + + * src/msvc6/testrunner/ActiveTest.h: + * src/msvc6/testrunner/ActiveTest.cpp: updated against + TestCaseDecorator ownership policy change. Moved inline functions + to .cpp. + + * examples/cppunittest/TestSetUpTest.cpp: updated to use MockTestCase + and against the new ownership policy. + + * examples/cppunittest/TestDecoratorTest.cpp: + * examples/cppunittest/RepeatedTestTest.cpp: updated against + TestDecorator ownership policy change. + + * examples/cppunittest/ExceptionTestCaseDecoratorTest.h: + * examples/cppunittest/ExceptionTestCaseDecoratorTest.cpp: added. Unit + tests for ExceptionTestCaseDecoratorTest. + +2002-07-16 Baptiste Lepilleur + + * include/cppunit/Protector.h: + * src/cppunit/Protector.cpp: added. Base class for protectors. + + * src/cppunit/DefaultProtector.h: + * src/cppunit/DefaultProtector.cpp: added. Implementation of the default + protector used to catch std::exception and any other exception. + + * src/cppunit/ProtectorChain.h: + * src/cppunit/ProtectorChain.cpp: added. Implementation of a chain of + protector, allowing catching custom exception and implementation of + expected exception. + + * src/cppunit/TestCase.cpp: + * src/cppunit/TestResult.cpp: updated to use protector. + +2002-07-14 Baptiste Lepilleur + + * CodingGuideLines.txt: added. CppUnit's coding guidelines for portability. + + * include/cppunit/portability/CppUnitStack.h: added. wrapper for std::stack. + + * include/cppunit/portability/CppUnitSet.h: added. wrapper for std::set. + + * include/cppunit/ui/text/TestRunner.h: fixed namespace definition for + deprecated TestRunner. + + * include/cppunit/TestAssert.h: + * src/cppunit/TestAssert.cpp: removed old deprecated functions that did + not use SourceLine. Moved assertEquals() and assertDoubleEquals() into + CppUnit namespace. + + * src/cppunit/TestFactoryRegistry.cpp: use CppUnitMap instead of std::map. + + * src/DllPlugInTester/CommandLineParser.h: use CppUnitDeque instead + std::deque. + + * examples/cppunittest/*.h: + * examples/cppunittest/*.cpp: removed all usage of CppUnitTest namespace. + Everything is now in global space. + + * examples/*/*.h: + * examples/*/*.cpp: replaced usage of CppUnit:: with CPPUNIT_NS::. + + * examples/ClockerPlugIn/ClockerModel.h: use CppUnit STL wrapper instead + of STL container. + +2002-07-13 Baptiste Lepilleur + + * include/cppunit/ui/text/TestRunner.h: + * src/cppunit/TextTestRunner.cpp: Renamed TextUi::TestRunner + TextTestRunner and moved it to the CppUnit namespace. Added + a deprecated typedef for compatibility with previous version. + + * include/cppunit/ui/text/TextTestRunner.h: added. + + * include/cppunit/ui/mfc/TestRunner.h: + * src/cppunit/msvc6/testrunner/TestRunner.cpp: Renamed MfcUi::TestRunner + MfcTestRunner. Added deprecated typedef for compatibility. Renamed + TestRunner.cpp to MfcTestRunner.cpp. + + * include/cppunit/ui/mfc/MfcTestRunner.h: added. + + * include/cppunit/ui/qt/TestRunner.h: + * src/qttestrunner/TestRunner.cpp: renamed QtUi::TestRunner QtTestRunner + and moved it to CppUnit namespace. Added a deprecated typedef for + compatibility. Renamed TestRunner.cpp to QtTestRunner.cpp. + + * include/cppunit/ui/qt/TestRunner.h: + * src/qttestrunner/TestRunner.h: Moved TestRunner to CppUnit namespace + and renamed it QtTestRunner. Added deprecated typedef for compatibility. + + * include/cppunit/Asserter.h: + * src/cppunit/Asserter.cpp: changed namespace Asserter to a struct and + made all methods static. + + * include/cppunit/extensions/HelperMacros.h: + * include/cppunit/extensions/SourceLine.h: + * include/cppunit/extensions/TestAssert.h: + * include/cppunit/extensions/TestPlugIn.h: + * include/cppunit/Portability.h: changed CPPUNIT_NS(symbol) to a + symbol macro that expand either to CppUnit or nothing. The symbol is + no longer a parameter. + + * include/cppunit/portability/CppUnitVector.h: + * include/cppunit/portability/CppUnitDeque.h: + * include/cppunit/portability/CppUnitMap.h: added. STL Wrapper for + compilers that do not support template default argumenent and need + the allocator to be passed when instantiating STL container. + + * examples/cppunittest/*.h: + * examples/cppunittest/*.cpp: + * src/msvc6/testrunner/*.h: + * src/msvc6/testrunner/*.cpp: + * src/msvc6/testpluginrunner/*.h: + * src/msvc6/testpluginrunner/*.cpp: + * src/qttestrunner/*.h: + * src/qttestrunner/*.cpp: replaced occurence of CppUnit:: by CPPUNIT_NS. + + * src/cppunit/TestSuite.h: + replaced occurence of std::vector by CppUnitVector. + +2002-07-12 Baptiste Lepilleur + + * include/cppunit/config/Portability.h: If the compiler does not support + namespace (CPPUNIT_HAVE_NAMESPACES=0), define CPPUNIT_NO_STD_NAMESPACE + and CPPUNIT_NO_NAMESPACE. If CPPUNIT_NO_STD_NAMESPACE is defined, then + CppUnit assumes that STL are in the global namespace. If + CPPUNIT_NO_NAMESPACE is defined, then CppUnit classes are placed in the + global namespace instead of the CppUnit namespace. + + * include/cppunit/config/config-bcb5.h: + * include/cppunit/config/config-msvc6.h: added definition of macro + CPPUNIT_HAVE_NAMESPACES. + + * include/cppunit/tools/StringTools.h: use CPPUNIT_WRAP_COLUMN as default + parameter value for wrap(). + + * include/cppunit/*/*.h: + * src/cppunit/*.cpp: changed all CppUnit namespace declaration to use + macros CPPUNIT_NS_BEGIN and CPPUNIT_NS_END. Also, changed reference + to CppUnit namespace (essentially in macros) using CPPUNIT_NS macro. + + * doc/doxyfile.in: + * doc/CppUnit-Win.dox: updated doxygen configuration files so that + CPPUNIT_NS_BEGIN and CPPUNIT_NS_END macros are expanded. This help + generates the documentation using the CppUnit namespace. + +2002-07-11 Baptiste Lepilleur + + * include/cppunit/Portability.h: added macro CPPUNIT_CONST_CAST. + + * src/cppunit/Exception.cpp: + * src/cppunit/Test.cpp: + * examples/cppunittest/MockTestCase.cpp: replaced usage of const_cast with + CPPUNIT_CONST_CAST. + + * include/cppunit/Test.h: + * src/cppunit/Test.cpp: made findTestPath(), findTest() and resolvePath() + const methods. + +2002-07-10 Baptiste Lepilleur + + * include/cppunit/extensions/AutoRegisterSuite.h: + * include/cppunit/extensions/Orthodox.h: + * include/cppunit/extensions/TestSuiteBuilder.h: + * include/cppunit/extensions/TestSuiteFactory.h: + * include/cppunit/TestCaller.h: + * examples/hierarchy/BoardGameTest.h: + * examples/hierarchy/ChessTest.h: replaced usage of 'typename' in template + declaration with 'class'. + + * include/cppunit/ui/text/TestRunner.h: + * src/cppunit/TextTestRunner.cpp: updated to use the generic TestRunner. + Removed methods runTestByName() and runTest(). Inherits + CppUnit::TestRunner. + + * include/cppunit/extensions/TestSuiteBuilder.h: removed templatized method + addTestCallerForException(). It is no longer used since release 1.9.8. + + * examples/cppunittest/MockTestCase.h + * examples/cppunittest/MockTestCase.cpp: removed the usage of 'mutable' + keyword. + +2002-07-04 Baptiste Lepilleur + + * src/msvc6/DSPlugIn/DSPlugIn.dsp: updated so that only the release + configuration get copied to the lib/ directory. + +2002-07-03 Baptiste Lepilleur + + * include/cppunit/XmlOutputter.h: fixed XmlOutputter constructed default + value initializatino which caused compilation error with BC5. + + * src/cppunit/PlugInManager.cpp: added missing CPPUNIT_NO_TESTPLUGIN guard. + + * src/msvc6/testrunner/TestRunner.dsp: + * src/msvc6/testrunner/TestRunner.rc: + * src/msvc6/testrunner/TestRunnerDlg.cpp: + * src/msvc6/testrunner/TestRunnerDlg.h: + * src/msvc6/testrunner/TreeHierarchyDlg.cpp: + * src/msvc6/testrunner/TreeHierarchyDlg.h: + * src/msvc6/testpluginrunner/TestPlugInRunner.dsp: + * src/msvc6/testpluginrunner/TestPlugInRunner.rc: + * src/msvc6/testpluginrunner/TestPlugInRunnerApp.cpp: + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.cpp: + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.h: applied Steven Mitter + patch to fix bug #530426 (conflict between TestRunner and host + application's resources). Adapted patch to compile work with Unicode. + + * src/msvc6/testrunner/ResourceLoaders.h: + * src/msvc6/testrunner/ResourceLoaders.cpp: + * src/msvc6/testrunner/Change-Diary-ResourceBugFix.txt: added, from + Steven Mitter's patch. Simplified loadCString() to compile with Unicode. + + * src/cppunit/cppunit.dsp: + * src/cppunit/cppunit_dll.dsp: + * src/DllPlugInTester/DllPlugInTester.dsp: + * src/msvc6/testrunner/TestRunner.dsp: + * src/msvc6/testpluginrunner/TestPlugInRunner.dsp: all lib, dll and exe are + now created in the intermediate directory. A post-build rule is used to + copy them to the lib/ directory. + +2002-06-17 Baptiste Lepilleur + + * include/cppunit/AdditionalMessage.h: + * src/cppunit/AdditionalMessage.cpp: added. Class to help passing + additional message parameter. + + * include/cppunit/Asserter.h: added makeExpected(), makeActual() and + makeNotEqualMessage(). Removed methods made unnecessary by the + use of AdditionalMessage. + + * include/cppunit/Portability.h: added CPPUNIT_WRAP_COLUMN to define + CppUnit default wrap column. + + * src/cppunit/CompilerOutputter.cpp: use CPPUNIT_WRAP_COLUMN instead + of hard-coded value. + +2002-06-16 Baptiste Lepilleur + + * bumped version to 1.9.9 + + * release 1.9.8 + + * include/cppunit/plugin/TestPlugIn.h: updated documentation. + + * include/cppunit/tools/XmlDocument.h: updated documentation. + + * include/cppunit/tools/StringTools.h: + * src/cppunit/StringTools.cpp: added split() and wrap() functions. + + * include/cppunit/CompilerOutputter.h: + * src/cppunit/CompilerOutputter.cpp: extracted wrap() and + splitMessageIntoLines() to StringTools. + + * include/cppunit/XmlOutputterHook.h: + * src/cppunit/XmlOutputterHook.cpp: removed rooNode parameter from + beginDocument() and endDocument(). It can be retreive from document. + Renamed 'node' occurences to 'element'. + + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: updated against + XmlOutputterHook changes. Renamed 'node' occurences to 'element'. + + * src/cppunit/Message.cpp: + * src/cppunit/XmlElement.cpp: added missing include + + * examples/ClockerPlugIn/ClockerXmlHook.h: + * examples/ClockerPlugIn/ClockerXmlHook.cpp: updated against + XmlOutputterHook changes. + + * examples/cppunittest/MessageTest.cpp: removed std::string() from + assertion. Somehow gcc can't parse it. Added missing include . + + * examples/cppunittest/XmlElement.cpp: added missing include . + + * examples/cppunittest/XmlElementTest.h: + * examples/cppunittest/XmlElementTest.cpp: Renamed 'node' occurences + to 'element'. + + * examples/cppunittest/XmlOutputterTest.cpp: updated against + XmlOutputterHook changes. + + * examples/cppunittest/StringToolsTest.h: + * examples/cppunittest/StringToolsTest.cpp: added. Unit tests for + StringTools. Turn out that VC++ dismiss empty lines in tools output, + which is the reason why empty lines where not printed in + CompilerOutputter. + +2002-06-14 Baptiste Lepilleur + + * include/cppunit/plugin/PlugInManager.h: + * src/cppunit/PlugInManager.cpp: added two methods to use the plug-in + interface for Xml Outputter hooks. + + * include/cppunit/plugin/TestPlugIn.h: added two methods to the plug-in + interface for Xml Outputter hooks. + + * include/cppunit/plugin/TestPlugInAdapter.h: + * src/cppunit/plugin/TestPlugInAdapter.cpp: renamed TestPlugInDefaultImpl. + Added empty implementation for Xml outputter hook methods. + + * include/cppunit/tools/StringTools.h: + * src/cppunit/tools/StringTools.cpp: added. Functions to manipulate string + (conversion, wrapping...) + + * include/cppunit/tools/XmlElement.h: + * src/cppunit/XmlElement.cpp: renamed addNode() to addElement(). Added + methods to walk and modify XmlElement (for hook). Added documentation. + Use StringTools. + + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: added hook calls & management. + + * include/cppunit/XmlOutputterHook.h: + * src/cppunit/XmlOutputterHook.cpp: added. Hook to customize XML output. + + * src/DllPlugInTester/DllPlugInTester.cpp: call plug-in XmlOutputterHook + when writing XML output. Modified so that memory is freed before + unloading the test plug-in (caused crash when freeing the XmlDocument). + + * examples/ReadMe.txt: + * examples/ClockerPlugIn/ReadMe.txt: added details about the plug-in + (usage, xml content...) + + * examples/ClockerPlugIn/ClockerModel.h: + * examples/ClockerPlugIn/ClockerModel.cpp: extracted from ClockerListener. + Represents the test hierarchy and tracked time for each test. + + * examples/ClockerPlugIn/ClockerListener.h: + * examples/ClockerPlugIn/ClockerListener.cpp: extracted test hierarchy + tracking to ClockerModel. Replaced the 'flat' view option with a 'text' + option to print the timed test tree to stdout. + + * examples/ClockerPlugIn/ClockerPlugIn.cpp: updated to hook the XML + output and use the new classes. + + * examples/ClockerPlugIn/ClockerXmlHook.h: + * examples/ClockerPlugIn/ClockerXmlHook.cpp: added. XmlOutputterHook to + includes the timed test hierarchy and test timing in the XML output. + + * examples/cppunittest/XmlElementTest.h: + * examples/cppunittest/XmlElementTest.cpp: added new test cases. + + * examples/cppunittest/XmlOutputterTest.h: + * examples/cppunittest/XmlOutputterTest.cpp: added tests for + XmlOutputterHook. + +2002-06-14 Baptiste Lepilleur + + * src/cppunit/TypeInfoHelper.cpp: added work around for bug #565481. + gcc 3.0 RTTI name() returns the type prefixed with a number (the + length of the type). The work around strip the number. + + * src/msvc6/testpluginrunner/TestPlugInRunnerApp.cpp: registry key is now + set. Allow to save settings. + + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.h: + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.cpp: added layout + initialization for resizing. + + * src/msvc6/testpluginrunner/TestPlugRunner.rc: + * src/msvc6/testpluginrunner/TestPlugInRunner.dsp: added TestRunner + project files. Somehow I can't get cdxCDynamicDialog to compile + as a MFC extension. Included all sources files and resources + as a very dirt work around. + + * src/msvc6/testrunner/TestRunnerDlg.h: + * src/msvc6/testrunner/TestRunnerDlg.cpp: + * src/msvc6/testrunner/TestRunnerModel.h: those classes are no longer + exported in the MFC extension. See TestPlugInRunner issue with + cdxCDynamicDialog. + + * include/cppunit/Message.h: + * include/cppunit/TestPath.h: + * include/cppunit/TestResult.h: + * include/cppunit/TestResultCollector.h: + * include/cppunit/TestSuite.h: + * include/cppunit/TestFactoryRegistry.h: + * include/cppunit/XmlElement.h: + * include/cppunit/TypeInfoHelper.h: commented out STL template export + in DLL. This caused conflicts when instantiting the same template in + a user project. + +2002-06-14 Baptiste Lepilleur + + * src/cppunit/CompilerOutputter.cpp: fixed bug #549762 (line wrap). + + * src/msvc6/testrunner/DynamicWindow/*: added. Dynamic Window library + from Hans Bühler (hans.buehler@topmail.de) to resize window. + + * src/msvc6/testrunner/TestRunnerModel.h: + * src/msvc6/testrunner/TestRunnerModel.cpp: removed dialog bounds from + settings. Added public registry keys for cppunit, main dialog, and + browse dialog. + + * src/msvc6/testrunner/TreeHierarchyDlg.h: + * src/msvc6/testrunner/TreeHierarchyDlg.cpp: dialog is now resizable. + Window placement is stored and restored. + + * src/msvc6/testrunner/TestRunnerDlg.h: + * src/msvc6/testrunner/TestRunnerDlg.cpp: replaced dialog resizing code + by usage of Hans Bühler's Dynamic Window library. Dialog placement + is stored/restored by that library. ProgressBar is now a child window. + Added edit field to see the details of the failure. List on show + the short description of the failure. + + * src/msvc6/testrunner/ProgressBar.h: + * src/msvc6/testrunner/ProgressBar.cpp: is now a CWnd. + + * src/msvc6/testrunner/TestRunner.rc: named all static fill ID for resizing. + Added an invisble static field for progress bar placement. + +2002-06-13 Baptiste Lepilleur + + * doc/other_documentation.dox: fixed some typos. + + * include/cppunit/NotEqualException.h: + * src/cppunit/NotEqualException.cpp: removed. + + * include/cppunit/Exception.h: + * src/cppunit/Exception.cpp: removed 'type' related stuffs. + + * include/cppunit/TextTestResult.h: + * src/cppunit/TextTestResult.cpp: delegate printing to TextOutputter. + + * examples/simple/ExampleTestCase.h: + * examples/simple/ExampleTestCase.cpp: reindented. + + * src/qttestrunner/build: + * src/qttestrunner/qttestrunner.pro: + * src/qttestrunner/TestBrowserDlgImpl.h: + * src/qttestrunner/TestRunnerModel.h: applied Thomas Neidhart's patch, + 'Some minor fixes to compile QTTestrunner under Linux.'. + +2002-06-13 Baptiste Lepilleur + + * include/cppunit/Asserter.h: + * src/cppunit/Asserter.cpp: added functions that take a Message as a + parameter. Existing function have a short description indicating + an assertion failure. + + * include/cppunit/CompilerOuputter.h: + * src/cppunit/CompilerOuputter.cpp: removed printNotEqualMessage() and + printDefaultMessage(). Updated to use Message. + + * include/cppunit/Message.h: + * src/cppunit/Message.cpp: added. Represents a message associated to an + Exception. + + * include/cppunit/Exception.h: + * src/cppunit/Exception.cpp: the message associated to the exception is now + stored as a Message instead of a string. + + * include/cppunit/NotEqualException.cpp: constructs a Message instead of a + string. + + * include/cppunit/TestAssert.h: + * src/cppunit/TestAssert.cpp: updated to use Asserter functions that + take a message when pertinent (CPPUNIT_FAIL...). + + * include/cppunit/TestCaller.h: + * src/cppunit/TestCaller.cpp: exception not caught failure has a better + short description. + + * src/cppunit/TestCase.cpp: better short description when setUp() or + tearDown() fail. + + * src/msvc6/testrunner/TestRunnerDlg.cpp: replace '/n' in failure message + with space. + + * examples/cppunittest/ExceptionTest.cpp: + * examples/cppunittest/NotEqualExceptionTest.cpp: + * examples/cppunittest/TestCallerTest.cpp: + * examples/cppunittest/TestFailureTest.cpp: + * examples/cppunittest/TestResultCollectorTest.h: + * examples/cppunittest/TestResultCollectorTest.cpp: + * examples/cppunittest/TestResultTest.cpp: + * examples/cppunittest/XmlOutputterTest.h: + * examples/cppunittest/XmlOutputterTest.cpp: updated to use Exception/Message. + + * examples/cppunittest/MessageTest.h: + * examples/cppunittest/MessageTest.cpp: added. Unit test for Message. + +2002-06-11 Baptiste Lepilleur + + * install-unix: added some hints extracted from bug #544684 on how to compile + for Solaris/Forte C++ compiler. + + * TODO: cleaned-up and added new things. + + * include/cppunit/extensions/HelperMacros.h: CPPUNIT_TEST_SUITE now declares + a class named ThisTestFixtureFactory which is a wrapper for the fixture + factory. This removes the need to cast the fixture to the correct type when + using the factory. Updated other macros implementation to use this new + factory. Modified CPPUNIT_TEST_CUSTOM(S) macros to use this new factory + class. Added macro CPPUNIT_TEST_ADD to help create new macros like + CPPUNIT_TEST_xxx. + + * examples/cppunittest/HelperMacrosTest.h: + * examples/cppunittest/HelperMacrosTest.cpp: added unit tests for + CPPUNIT_TEST_CUSTOM, CPPUNIT_TEST_CUSTOMS and CPPUNIT_TEST_ADD. + +2002-06-01 Baptiste Lepilleur + + * doc/cookbook.dox: fixed bug. + + * install-unix: added compilation instruction for Solaris/Sun 6.0 + +2002-05-25 Baptiste Lepilleur + + * include/cppunit/extensions/TestSuiteBuilder.h: updated to use TestNamer. Removed + template method addTestCallerForException() which should solve the compilation + issue with Sun 5.0/6.0 compiler. + + * include/cppunit/extensions/HelperMacros.h: updated against TestSuiteBuilder + change. Added CPPUNIT_TEST_CUSTOM and CPPUNIT_TEST_CUSTOMS to add custom + tests to the fixture suite. + + * include/cppunit/extensions/TestNamer.h: + * src/cppunit/TestNamer.cpp: added, TestNamer to name test case and fixture. + +2002-05-23 Baptiste Lepilleur + + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: extracted class XmlOutputter::Node to + XmlElement. Extracted xml 'prolog' generation to XmlDocument. + + * include/cppunit/tools/XmlElement.h: + * src/cppunit/tools/XmlElement.cpp: added, extracted from XmlOutputter::Node. + + * include/cppunit/tools/XmlDocument.h: + * src/cppunit/tools/XmlDocument.cpp: added, extracted from XmlOutputter. Handle + XML document prolog (encoding & style-sheet) and manage the root element. + + * src/DllPlugInTester/DllPlugInTester.cpp: bug fix, flag --xsl was ignored. + + * examples/cppunittest/XmlOutputterTest.h: + * examples/cppunittest/XmlOutputterTest.cpp: updated for XmlOuputter changes. + extracted tests for XmlOutputter::Node to XmlElementTest + + * examples/cppunittest/XmlElementTest.h: + * examples/cppunittest/XmlElementTest.cpp: added, tests extracted from + XmlOutputterTest. + +2002-05-21 Baptiste Lepilleur + + * src/msvc6/testrunner/MsDevCallerListCtrl.h: + * src/msvc6/testrunner/MsDevCallerListCtrl.cpp: + * src/msvc6/testrunner/Resource.h: + * src/msvc6/testrunner/TestRunner.rc: + * src/msvc6/testrunner/TestRunnerDlg.cpp: + * src/msvc6/testrunner/TestRunnerModel.h: + * src/msvc6/testpluginrunner/TestPlugInRunner.rc: + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.cpp: + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.h: + * src/msvc6/testpluginrunner/TestPlugInRunnerModel.cpp: integrated patch from + Marco Welti (Welti@GretagMacbeth.ch) with a few clean up. + Display the name of the test being run during above the progress bar. Allow the + VC++ add-ins to works with TestPlugInRunner (COM init). DLL name can be specified + on the command line after flag '-testsuite'. Display wait cursor, clear and reload + history when reloading DLL. + + * THANKS: added Marco Welti to the list. + +2002-05-07 Baptiste Lepilleur + + * src/DllPlugInTester/CommandLineParser.cpp: fixed compilation issue. + + * src/msvc6/TestRunner/ActiveTest.h: + * src/msvc6/TestRunner/ActiveTest.cpp: reindented. bugfix: thread + handle resource leak (bug #553424). + +2002-04-25 Baptiste Lepilleur + + * src/cppunit/XmlOutputter.cpp: bugfix, use ISO-8859-1 encoding if an + empty string is given. + + * src/DllPlugInTester/CommandLineParser.h: + * src/DllPlugInTester/CommandLineParser.cpp: + * src/DllPlugInTester/DllPlugInTester.cpp: added option -w to wait for + the user to press a key before exiting (Philippe Lavoie patch, + with change). + +2002-04-22 Baptiste Lepilleur + + * include/cppunit/plugin/DynamicLibraryManagerException.h: removed + trailing ',' in enum. + + * examples/ClockerPlugIn/ClockerListener.cpp: bugfix, average test + case time computation. + +2002-04-21 Baptiste Lepilleur + + * bumped version to 1.9.7 + + * comitted stuffs I forgot to in 1.9.6. + +2002-04-21 Baptiste Lepilleur + + * contrib/bc5/bcc-makefile.zip: updated, generic makefile for + Borland 5.5, contributed by project cuppa. + + * examples/cppunittest/*Suite.h: integrated Jeffrey Morgan's patch, + to remove warning with gcc. + + * release 1.9.6 + +2002-04-21 Baptiste Lepilleur + + * src/DllPlugInTester/makefile.am: removed ld.so from LDADD flags. + + * src/DllPlugInTester/CommandLineParser.h: + * src/DllPlugInTester/CommandLineParser.cpp: rewrote, fixed problem + with double quotes in command line... + + * src/DllPlugInTester/CommandLineParserTest.h: + * src/DllPlugInTester/CommandLineParserTest.cpp: + * src/DllPlugInTester/DllPlugInTesterTest.cpp: added, unit tests for + CommandLineParser. + + * src/msvc6/TestPlugIn/*: removed. + + * examples/Money/*: added. New 'hello world' example. + + * doc/Money.dox: added. Article that go along with the Money example. + +2002-04-21 Baptiste Lepilleur + + * THANKS: updated + + * src/cppunit/DynamicLibraryManager.cpp: bugfix: did not pass + library name to exception. + + * include/cppunit/TestPath.h: + * src/cppunit/TestPath.cpp: changed into value object. + + * src/cppunit/BeosDynamicLibraryManager.cpp: integrated patch from + Shibu Yoshiki for BeOS ('cuppa' project team). + + * src/DllPlugInTester/CommandLineParser.h: + * src/DllPlugInTester/CommandLineParser.cpp: added. Command line + parsing. + + * src/DllPlugInTester/DllPlugInTester.cpp: full command line support + with parameters for plug-ins. + + * src/DllPlugInTester/makefile.am: + * examples/simple/makefile.am: + * examples/cppunittest/makefile.am: integrated Jeffrey Morgan's patch, + Unix side should be working again. + + * examples/ReadMe.txt: added. Brief description of each example. + + * examples/cppunittest/CppUnitTestPlugIn.cpp: + * examples/cppunittest/CppUnitTestPlugIn.dsp: added. New project to + build CppUnit's test suite as a test plug-in. + + * examples/cppunittest/CppUnitTestSuite.cpp: updated. Use new + helper macros to create the test suite hierarchy. + + * examples/simple/simple_plugin.opt: added. Contains debug tab + settings. + + * examples/ClockerPlugIn/ClockerListener.cpp: + * examples/ClockerPlugIn/ClockerListener.h: + * examples/ClockerPlugIn/Timer.cpp: + * examples/ClockerPlugIn/Timer.h: + * examples/ClockerPlugIn/WinNtTimer.cpp: + * examples/ClockerPlugIn/WinNtTimer.h: + * examples/ClockerPlugIn/ClockerPlugIn.cpp: + * examples/ClockerPlugIn/ClockerPlugIn.dsp: added. test listener + plug-in that times tests. + + * examples/DumperPlugIn/DumperListener.cpp: + * examples/DumperPlugIn/DumperListener.h: + * examples/DumperPlugIn/DumperPlugIn.cpp: + * examples/DumperPlugIn/DumperPlugIn.dsp: added. test listener + plug-in that dump the test tree. + + +2002-04-19 Baptiste Lepilleur + + * src/cppunit/PlugInManager.cpp: fixed bug in unload(). + + * include/cppunit/TypeInfoHelper.h: + * src/cppunit/TypeInfoHelper.cpp: Implementation is now always available + is CPPUNIT_HAVE_RTTI is not 0. This removes the need to use + different libraries. CPPUNIT_USE_TYPEINFO_NAME can be set on a + case by case basis for HelperMacros. + + * src/cppunit/TestFactoryRegistry.cpp: removed unused include of + TypeInfoHelper.h. + + * include/cppunit/TextTestProgressListener.h: + * src/cppunit/TextTestProgressListener.cpp: used endTest() instead + of done() to finalize. + + * src/msvc6/TestPlugInRunner/TestPlugIn.h: + * src/msvc6/TestPlugInRunner/TestPlugIn.cpp: updated to use the + new test plug-in system. + + * examples/simple/SimplePlugIn.cpp: + * examples/simple/simple_plugin.dsp: crossplatform test plug-in + example using 'simple'. + + * examples/msvc6/EasyTestPlugIn/*: projects replaced with the + crossplatform projecct examples/simple/simple_plugin.dsp. + +2002-04-19 Baptiste Lepilleur + + * configure.in: added some makefile.am + + * contrib/readme.txt: updated. + + * contrib/bc5/bc5-makefile.zip: added borland 5.5 makefile. Contributed by + project cuppa. + + * src/cppunit/TypeInfoHelper.cpp: fixed implementation to be more + portable. + + +2002-04-18 Baptiste Lepilleur + + * bumped version to 1.9.3 + + * FAQ: added question about 4786 warning on VC++. + + * NEWS: updated. + + * contrib/msvc/readme.txt: moved to contrib/readme.txt. + + * contrib/xml-xsl/report.xsl: added XML style sheet contributed by + 'cuppa' project team (http://sourceforge.jp/projects/cuppa/) + + * examples/cppunittest/TestResultTest.h: + * examples/cppunittest/TestResultTest.cpp: added tests for + startTestRun()/endTestRun(). + + * examples/simple/*: added. A simple example. + + * include/cppunit/BriefTestProgressListener.h: + * src/cppunit/BriefTestProgressListener.cpp: added. Verbose progess listener + that print the test name before running the test. + + * include/cppunit/TestListener.h: added startTestRun()/endTestRun(). + + * include/cppunit/TestResult.h: + * src/cppunit/TestResult.cpp: added runTest(), to be called to run + a test by test runner. + + * src/cppunit/TextTestRunner.cpp: + * src/cppunit/TestRunner.cpp: updated to use TestResult::runTest(). + + * include/cppunit/plugin/PlugInManager.h: + * src/cppunit/PlugInManager.cpp: added. Managers for all loaded plug-ins. + + * include/cppunit/plugin/TestPlugInDefaultImpl.h: + * src/cppunit/TestPlugInDefaultImpl.cpp: renamed TestPlugInAdapter. All + implementations are empty. + + * include/cppunit/plugin/TestPlugInSuite.h: removed. + * src/cppunit/TestPlugInSuite.cpp: removed. Replaced by PlugInManager. + + * include/cppunit/plugin/TestPlugIn.h: rewrote the plug-in interface to + provide more versatility. updated macros to match new interface. + + * include/cppunit/extensions/TestFactoryRegistry.h: + * include/cppunit/extensions/TestFactoryRegistry.cpp: Added unregisterFactory(). + Added convenience method addRegistry(). Rewrote registry life cycle + management. AutoRegisterSuite can now detect that the registry has been + destroy and not call to it to unregister its test factory. + + * include/cppunit/extensions/AutoRegisterTest.h: on destruction, the registered + factory is unregistered from the registry. + + * include/cppunit/extensions/HelperMacros.h: added macros + CPPUNIT_REGISTRY_ADD_TO_DEFAULT and CPPUNIT_REGISTRY_ADD to help + build test suite hierarchy. + + * src/cppunit/msvc/DllPlugInTester/*: moved to src/cppunit/DllPlugInTester/. + + * src/cppunit/DllPlugInTester/DllPlugInTester.cpp: removed UNICODE stuffs. Use + the PlugInManager instead of PlugInTestSuite. Simplified: only one test on + command line, but many DLL can be specified. Added configurations to link + against cppunit dll, those are now the default configuration (static linking + don't make much sense for plug-in). + +2002-04-15 Baptiste Lepilleur + + * release 1.9.2. + + * NEWS: updated. + + * configure.in: added include/cppunit/config/Makefile and + include/cppunit/plugin/Makefile to the list of target. + + * doc/CppUnit-win.dox: enabled generation of HTML Help documentation. + + * include/cppunit/config/Makefile.am: + * include/cppunit/plugin/Makefile.am: added. + + * include/cppunit/config-bcb5.h: + * include/cppunit/config-msvc6.h: + * include/cppunit/config-mac.h: moved to include/cppunit/config/. + + * include/cppunit/Portability.h: updated config files location. Added macros + CPPUNIT_STRINGIZE and CPPUNIT_JOIN (implementation adapted from boost.org). + Added macro CPPUNIT_MAKE_UNIQUE_NAME. + + * include/cppunit/Test.h: modified methods order. + + * include/cppunit/extensions/HelperMacros.h: renamed macro + __CPPUNIT_MAKE_UNIQUE_NAME to CPPUNIT_MAKE_UNIQUE_NAME and moved its + definition to include/cppunit/Portability.h. + + * include/cppunit/extensions/TestDecorator.h: Inherits Test instead of TestLeaf. + + * include/cppunit/plugin/DynamicLibraryManager.h: + * src/cppunit/DynamicLibraryManager.cpp: added. DLL manager (load & lookup + symbol). + + * src/cppunit/BeOsDynamicLibraryManager.cpp: + * src/cppunit/UnixDynamicLibraryManager.cpp: + * src/cppunit/Win32DynamicLibraryManager.cpp: added. Implementation of + platform dependent methods of DynamicLibraryManager. + + * include/cppunit/plugin/DynamicLibraryManagerException.h: + * src/cppunit/DynamicLibraryManagerException.cpp: added. Exception thrown + by DynamicLibraryManager. + + * include/cppunit/plugin/TestPlugIn.h: added. CppUnitTestPlugIn interface + definition. Helper macros to implements plug-in. + + * include/cppunit/plugin/TestPlugInSuite.h: + * src/cppunit/plugin/TestPlugInSuite.cpp: added. A suite to wrap a test + plug-in. + + * include/cppunit/plugin/TestPlugInDefaultImpl.h: + * src/cppunit/TestPlugInDefaultImpl.cpp: added. A default implementation + of the test plug-in interface. + + * src/msvc6/DllPlugInTester/DllPlugInTester.cpp: updated to use the + new TestPlugIn. + + * examples/cppunittest/TestResultCollectorTest.cpp: fixed typo. + +2002-04-14 Baptiste Lepilleur + + * NEWS: updated. + + * include/cppunit/TestSucessListener.h: + * src/cppunit/TestSucessListener.cpp: renamed TestSuccessListener + + * doc/cookbook.dox: + * src/msvc6/DllPlugInTester/DllPlugInTester.cpp: + * examples/cppunittest/TestResultCollectorTest.h: + * examples/cppunittest/TestResultCollectorTest.cpp: + * examples/cppunittest/XmlOutputterTest.h: + * examples/cppunittest/XmlOutputterTest.cpp: + * include/cppunit/CompilerOutputter.h: + * include/cppunit/TestListener.h: + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: + * src/cppunit/CompilerOutputter.cpp: fixed 'success' typo (was misspelled + 'sucess'). + + * include/cppunit/TestResultCollector.h: + * src/cppunit/TestResultCollector.cpp: updated (renaming of + TestSucessListener). + + * src/cppunit/XmlOutputter.cpp: + * examples/cppunittest/XmlOutputterTest.cpp: Changed SucessfulTests tag to + SucessfulTests. + +2002-04-13 Baptiste Lepilleur + + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: Made XML output more human readable. Idented element. + + * examples/cppunittest/XmlUniformiser.h: + * examples/cppunittest/XmlUniformiser.cpp: + * examples/cppunittest/XmlUniformiserTest.cpp: modified to ignore trailing space + at the end of element content. + +2002-04-13 Baptiste Lepilleur + + * Snapshot 1.9.0 + + * NEWS: updated + + * doc/other_documentation.dox: addded new module for test plug-in. + + * include/msvc6/DSPlugin/TestRunnerDSPlugin.h: + * include/msvc6/DSPlugin/TestRunnerDSPlugin_i.c: added. Those file are + generated by project src/msvc/DSPlugin. They are provided to allow + compilation of TestRunner without compiling DSPlugIn which does not + build on VC++ 7. + + * examples/examples.dsw: removed DSPlugIn for workspace (fail to build + with VC++ 7). Added DllPlugInTester.dsp to workspace. + + * examples/msvc6/TestPlugIn/TestPlugIn.dsp: added post-build unit testing + using the new DllPlugInTester. + + * examples/msvc6/EasyTestPlugIn/*: a new project that + demonstrates the use of CPPUNIT_TESTPLUGIN_IMPL to create a test plug-in. + + * src/cppunit/cppunit.dsw: + * src/TestPlugInRunner.dsw: + * src/TestRunner.dsw: removed. Should use src/CppUnitLibraries.dsw instead. + + * include/cppunit/ui/text/TestRunner.h: + * src/cppunit/TextTestRunner.cpp: removed findTestName() method. Replaced + by Test::findTest(). + + * src/msvc6/DSPlugIn/DSPlugIn.dsp: + * src/msvc6/DSPlugIn/DSAddIn.h: changed include for add-in. MIDL generates + files in sub-directory ToAddToDistribution. Generated file should be + copied to include/msvc6/DSPlugin when modified. This remove the dependecy + of MfcTestRunner on DSPlugIn. + + * src/msvc6/testrunner/ListCtrlFormatter.h: + * src/msvc6/testrunner/ListCtrlFormatter.cpp: added GetNextColumnIndex(). + + * src/msvc6/testrunner/src/TestRunnerDlg.h: + * src/msvc6/testrunner/src/TestRunnerDlg.cpp: set column number in + MsDevCallerListCtrl when initializing the list. + + * src/msvc6/testrunner/src/MsDevCallerListCtrl.h: + * src/msvc6/testrunner/src/MsDevCallerListCtrl.cpp: column indexes for + file and line number are no longer static. Added methods to set those + indexes. Changed DSPlugIn header name. + + * include/msvc6/testrunner/TestPlugInInterface.h: fixed inclusion of + windows header for WINAPI. Added macro CPPUNIT_TESTPLUGIN_IMPL to + automatically implements a test plug-in. + + * src/msvc6/DllPlugInTester/*: added new project. A application to test DLL + and report using CompilerOutputter. Target for post-build testing and + debugging of DLL. + + +2002-04-13 Baptiste Lepilleur + + * include/cppunit/CompilerOutputter.h: + * src/cppunit/CompilerOutputter.h: deprecated defaultOuputter(). Added + setLocationFormat() and format specifiation in constructor. A string + that represent the location format is used to output the location. + Default format is defined by CPPUNIT_COMPILER_LOCATION_FORMAT. + + * include/cppunit/config-msvc6.h: + * include/cppunit/Portability.h: added CPPUNIT_COMPILER_LOCATION_FORMAT. + Use gcc location format if VC++ is not detected. + + * include/cppunit/Test.h: fixed documentation. + + * include/cppunit/TestListener.h: added startSuite() and endSuite() + callbacks. Added new example to documentation. + + * include/cppunit/TestResult.h: + * src/cppunit/TestResult.cpp: + * include/cppunit/TestComposite.h: + * src/cppunit/TestComposite.cpp: Updated to inform the listeners. + + * src/qttestrunner/TestBrowserDlgImpl.cpp: used Test new composite + interface instead of RTTI to explore the test hierarchy. + + * examples/cppunittest/MockTestListener.h: + * examples/cppunittest/MockTestListener.cpp: updated,added support for + startSuite() and endSuite(). + + * examples/cppunittest/TestResultTest.h: + * examples/cppunittest/TestResultTest.cpp: added tests for startSuite() + and endSuite(). + +2002-04-12 Baptiste Lepilleur + + * Makefile.am: added examples/qt to tar ball release. + + * TODO: heavily updated. + + * contrib/msvc/CppUnit*.wwtpl: changed base class for unit test to TestFixture. + + * include/cppunit/Test.h: removed toString() method. Not used by the framework + and source of confusions with getName(). + Added getChildTestCount() and getChildTestAt(), introducing the composite pattern + at top level. Added utility methods findTest() and findTestPath(). + + * src/cppunit/Test.cpp: added. Implementation of new utility methods. + + * include/cppunit/TestCase.h: + * src/cppunit/TestCase.cpp: inherits TestLeaf. Removed toString(), run(void) and + defaultResult(). Removed default constructor. + + * src/cppunit/TestCase.cpp: + * src/cppunit/TestSuite.cpp: fixed some includes that used "" instead of <>. + + * include/cppunit/TestComposite.h: + * src/cppunit/TestComposite.cpp: added. Common implementation of Test for composite + tests (TestSuite). + + * include/cppunit/TestFailure.h: + * src/cppunit/TestFailure.cpp: removed toString(). + + * include/cppunit/TestLeaf.h: + * src/cppunit/TestLeaf.cpp: added. Common implementation of Test for single test + (TestCase). + + * include/cppunit/TestListener.h: added TimingListener example to documentation. + + * include/cppunit/TestPath.h: + * src/cppunit/TestPath.cpp: added. List of test traversed to access a test in the + test hierarchy. + + * include/cppunit/TestRunner.h: added. Generic TestRunner. + + * src/cppunit/TestRunner.cpp: moved to TextTestRunner.cpp. Added new implementation + of includecppunit/TestRunner.h. + + * include/cppunit/TestSuite.h: + * src/cppunit/TestSuite.cpp: inherits TestComposite and implements new Test + interface. Removed toString(). + + * src/cppunit/TextTestRunner.cpp: moved from TestRunner.cpp. Implementation of + include/cppunit/ui/text/TestRunner.h. + + * include/cppunit/extensions/RepeatedTest.h: + * src/cppunit/RepeatedTest.cpp: removed toString(). + + * include/cppunit/extensions/TestDecorator.h: inherits TestLeaf. + Removed toString() + + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: + * examples/cppunittest/XmlOutputterTest.cpp: + * examples/cppunittest/XmlOutputterTest.h: XML outputter now escape node content. + Add unit test for that bug (#540944). Added style sheet support. Modified + XML structure: failure message as its own element. + + * src/msvc/testrunner/TestRunnerModel.h: + * src/msvc/testrunner/TestRunnerModel.cpp: used Test::findTest() to find a test + by name instead of using RTTI. Added toAnsiString() for convertion when + compiling as UNICODE. + + * src/msvc/testrunner/TreeHierarchyDlg.h: + * src/msvc/testrunner/TreeHierarchyDlg.cpp: used new composite interface of Test + to explorer the test hierarchy instead of RTTI. + + * examples/cppunittest/TestPathTest.h: + * examples/cppunittest/TestPathTest.cpp: added, unit tests for TestPath. + + * examples/cppunittest/TestCaseTest.h: + * examples/cppunittest/TestCaseTest.cpp: added test for TestLeaf. + + * examples/cppunittest/TestSuiteTest.h: + * examples/cppunittest/TestSuiteTest.cpp: added test for TestComposite and + new Test interface. + +2002-04-11 Baptiste Lepilleur + + * configure.in: bumped version to 1.9.0 + + * NEWS: added version 1.9.0 + +2002-04-11 Baptiste Lepilleur + + * doc/FAQ: removed question about the Exception::operator =() problem. + + * release 1.8.0 + +2002-04-11 Steve M. Robbins + + * include/cppunit/ui/mfc/Makefile.am: + * include/cppunit/ui/qt/Makefile.am: + * include/cppunit/ui/text/Makefile.am: Set the libcppunitincludedir + variable. Correct case of header file ui/qt/Config.h. + + * configure.in: Output the new include/*/Makefiles. + +2002-04-10 Baptiste Lepilleur + + * Makefile.am: removed directory cppunitui from copy when making + the dist. + + * include/cppunit/ui: added Makefile.am for dist and install. + +2002-04-10 Baptiste Lepilleur + + * include/cppunitui/: moved to include/cppunit/ui (fix unix + install problem). + + * doc/cookbook.dox: + * examples/cppunittest/CppUnitTestMain.cpp: + * examples/msvc/CppUnitTestApp/HostApp.cpp: + * examples/msvc/HostApp/HostApp.cpp: + * examples/qt/Main.Cpp: + * examples/src/cppunit/TestRunner.cpp: + * examples/src/msvc6/TestRunner/TestRunner.cpp: + * examples/src/qttestrunner/TestRunner.cpp: updated to use + instead of in include directives. + + * doc/CppUnit-win.dox: generated documentation give the include + path at the bottom of the page for each class. + + * NEWS: added compatibility break for 1.7.10 users. + +2002-04-05 Baptiste Lepilleur + + * examples/cppunittest/CppUnitTestMain.cpp: never wait for a key press. + +2002-04-04 Baptiste Lepilleur + + * NEW: added CPPUNIT_ASSERT_EQUAL_MESSAGE compatiblity break. + + * include/cppunit/TestAssert.h: changed arguments order for + CPPUNIT_ASSERT_EQUAL_MESSAGE. 'message' is now the first argument + instead of the last (like CPPUNIT_ASSERT_MESSAGE). + + * examples/cppunittest/MockTestCase.cpp: + * examples/cppunittest/MockTestListener.cpp: updated to reflect + change on CPPUNIT_ASSERT_EQUAL_MESSAGE. + +2002-03-28 Baptiste Lepilleur + + * configure.in: bumped version to 1.7.11 + +2002-03-28 Baptiste Lepilleur + + * doc/cookbook.html: removed. Replaced by cookbook.doc. + + * doc/cookbook.dox: added, conversion of cookbook.html to Doxygen + format. + + * doc/other_documentation.dox: added groups definition. + + * doc/Makefile.am: replaced cookbook.html by cookbook.dox + + * doc/Doxyfile.in: added predefined CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION. + Replaced cookbook.html by cookbook.dox. + + * include/cppunitui/mfc/TestRunner.h: added, extracted from + include/msvc6/testrunner/TestRunner.h. Moved class TestRunner to + namespace CppUnit::MfcUi. + + * include/msvc6/testrunner/TestRunner.h: deprecated. A simple + typedef to CppUnit::MfcUi::TestRunner. + + * include/textui/TestRuner.h: added, extracted from + include/cppunit/TextTestRunner.h. + + * src/cppunit/TextTestRunner.cpp: renamed TestRunner.cpp. Moved + into namespace CppUnit::TextUi. + + * src/msvc6/testruner/TestRunner.cpp: moved into namespace + CppUnit::MfcUi. + + * src/cppunit/CompilerOutputter.cpp: removed printing "- " before + NotEqualException addional message, for consistency between + different TestRunner (Mfc,Text...) + + * include/cppunit/Asserter.h: + * include/cppunit/CompilerOutputter.h: + * include/cppunit/Exception.h: + * include/cppunit/NotEqualException.h: + * include/cppunit/Outputter.h: + * include/cppunit/SourceLine.h: + * include/cppunit/TestAssert.h: + * include/cppunit/TestCaller.h: + * include/cppunit/TestFailure.h: + * include/cppunit/TestFixture.h: + * include/cppunit/TestListener.h: + * include/cppunit/TestResult.h: + * include/cppunit/TestResultCollector.h: + * include/cppunit/TestSucessListener.h: + * include/cppunit/TestSuite.h: + * include/cppunit/TextTestProgressListener.h: + * include/cppunit/TextTestRunner.h: + * include/cppunit/XmlOutputter.h: + * include/cppunit/extensions/AutoRegisterSuite.h: + * include/cppunit/extensions/HelperMacros.h: + * include/cppunit/extensions/TestFactoryRegistry.h: + * include/cppunit/extensions/TestSuiteBuilder.h: + * include/cppunit/extensions/TestSuiteFactory.h: doc + update. organization in groups. + + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.cpp: + * examples/msvc6/HostApp/HostApp.cpp: updated to use + CppUnit::MfcUi::TestRunner. + + * examples/cppunittest/CppUnitTestMain.cpp: updated to use + CppUnit::TextUi::TestRunner. + +2002-03-27 Baptiste Lepilleur + + * include/msvc/testrunner/TestRunner.h: updated doc. reindented. + + * include/cppunit/Asserter.h: + * include/cppunit/Asserter.cpp: + * include/cppunit/TestResultCollector.h: + * include/cppunit/TestResult.h: + * include/cppunit/SynchronizedObject.h: + * include/cppunit/extensions/TestCaller.h: doc update. + + * include/cppunitui/qt/TestRunner.h: doc update. + +2002-03-27 Baptiste Lepilleur + + * makefile.am: added src/CppUnitLibraries.dsw, new contribution, and + src/qttestrunner. + + * TODO: updated (doc). + + * contrib/msvc/AddingUnitTestMethod.dsm: added, submitted by + bloodchen@hotmail.com. + + * constrib/msvc/readme.txt: updated. + + * include/cppunit/TestAsserter.h: + * include/cppunit/SourceLine.h: updated doc. + + * include/cppunit/TestCaller.h: reindented. updated doc. + + * include/cppunit/extensions/HelperMacros.h: relaxed constraint on fixture. + Fixture base class may be TestFixture instead of TestCase. + + * include/cppunit/TestCase.h: + * src/cppunit/TestCase.h: TestCase inherits TestFixture for setUp() and + tearDown() definition. Moved documentation to TestFixture. + + * include/cppunit/TestFixture.h: updated documentation. + + * include/cppunit/TestRegistry.h: + * src/cppunit/TestRegistry.cpp: Removed. Replaced by TestFactoryRegistry. + + * include/cppunit/TextTestRunner.h: + * src/cppunit/TextTestRunner.cpp: made printing progress using a + TextTestProgressListener optional. + + * examples/cppunittest/ExceptionTest.h: + * examples/cppunittest/HelperMacrosTest.h: + * examples/cppunittest/HelperMacrosTest.cpp: + * examples/cppunittest/NotEqualException.h: + * examples/cppunittest/OrthodoxTest.h: + * examples/cppunittest/RepeatedTest.h: + * examples/cppunittest/TestAssertTest.h: + * examples/cppunittest/TestCallerTest.h: + * examples/cppunittest/TestDecoratorTest.h: + * examples/cppunittest/TestFailureTest.h: + * examples/cppunittest/TestResultCollectorTest.h: + * examples/cppunittest/TestResultTest.h: + * examples/cppunittest/TestSetUpTest.h: + * examples/cppunittest/TestSuiteTest.h: + * examples/cppunittest/XmlOutputterTest.h: + * examples/cppunittest/XmlOutputterTest.cpp: + * examples/cppunittest/XmlUniformizerTest.h: + * examples/cppunittest/XmlUniformizerTest.cpp: changed base class for fixture + from TestCase to TestFixture. + + * examples/hierarchy/BoardGameTest.h: + * examples/hierarchy/ChessTest.h: + * examples/hierarchy/main.cpp: updated to use HelperMacros for correct + fixture instantiation (the ChessBoard::testReset test case was using + BoardGame fixture instance instead of ChessBoard). + +2002-03-26 Baptiste Lepilleur + + * configure.in: bumped version to 1.7.9 + +2002-03-26 Baptiste Lepilleur + + * src/msvc6/testpluginrunner/TestPlugInRunner.dsp: fixed release configuration. + +2002-03-25 Baptiste Lepilleur + + * include/cppunit/makefile.am: removed TestRegistry.h + + * include/cppunit/TestRegistry.h: removed. Obsolete, replaced by + TestFactoryRegistry. + + * src/cppunit/makefile.am: removed TestRegistry.cpp. Added cppunit_dll.dsp. + + * include/cppunit/CompilerOutputter.h: + * include/cppunit/NotEqualException.h: + * include/cppunit/SynchronizedObject.h: + * include/cppunit/TestFixture.h: + * include/cppunit/TestListener.h: + * include/cppunit/TestResult.h: + * include/cppunit/TestSucessListener.h: + * include/cppunit/TextOutputter.h: + * include/cppunit/TextTestProgressListener.h: + * include/cppunit/TextTestResult.h: + * include/cppunit/XmlOutputter.h: + * include/cppunit/extensions/TestFactory.h: + * include/cppunit/extensions/TestFactoryRegistry.h: + * include/cppunit/extensions/TestSuiteBuilder.h: + * include/cppunit/extensions/TestSuiteFactory.h: minor doc update. + + * include/cppunit/TestFixture.h: added DLL export. + + * include/cppunit/msvc6/TestPlugInInterface.h: updated doc. Added automatic + exportation of TestPlugIn publishing function. + + * src/cppunit/TestCase.cpp: + * include/cppunit/TestCase.h: inherits setUp() and tearDown() from + class TestFixture. + +2002-03-25 Baptiste Lepilleur + + * configure.in: bumped version to 1.7.7 + +2002-03-25 Baptiste Lepilleur + + * include/cppunit/config-msvc6.h: + * include/cppunit/Portability.h + * include/cppunit/extensions/TestFactoryRegistry.h + * include/cppunit/TestResult.h + * include/cppunit/TestResultCollector.h + * include/cppunit/TestSuite.h + * include/cppunit/TextTestRunner.h + * include/cppunit/XmlOutputter.h: removed warning when compiling CppUnit + as DLL. + + * src/cppunit/DllMain.cpp: added some defines to speed up compilation a bit. + +2002-03-25 Baptiste Lepilleur + + * INSTALL-WIN32.txt: updated for MFC Unicode TestRunner. + + * src/msvc6/testrunner/TestRunner.dsp: added Unicode configurations. + + * src/msvc6/testrunner/ListCtrlSetter.cpp: + * src/msvc6/testrunner/ListCtrlSetter.h: replaced usage of std::string by + CString for easier ansi/unicode switch. + + * src/msvc6/testrunner/MsDevCallerListCtrl.cpp: + * src/msvc6/testrunner/TestRunnerDlg.cpp: + * src/msvc6/testrunner/TestRunnerModel.cpp: + * src/msvc6/testrunner/TestRunnerModel.h: + * src/msvc6/testrunner/TreeHierarchyDlg.cpp: made changes to compile with + either ANSI and UNICODE support. + + * examples/msvc6/HostApp/HostApp.cpp: + * examples/msvc6/HostApp/HostApp.h: + * examples/msvc6/HostApp/HostAppDoc.cpp: + * examples/msvc6/HostApp/HostAppDoc.h: moved TestRunner execution to + HostApp::RunUnitTests() and removed the MainFrame application window. + + * examples/msvc6/HostApp/HostApp.dsp: added Unicode configurations. + +2002-03-24 Baptiste Lepilleur + + * INSTALL-WIN32.txt: added some info to build cppunit as a DLL. + + * include/cppunit/config-msvc6.h: added definition of macro CPPUNIT_API + when building or linking DLL. Defined CPPUNIT_BUILD_DLL when building, and + CPPUNIT_DLL when linking. + + * include/cppunit/Portability.h: added empty definition of macro + CPPUNIT_API when not building or using CppUnit as a DLL. When any of + those symbol is defined, the symbol CPPUNIT_NEED_DLL_DECL is set to 1. + + * include/cppunit/extensions/RepeatedTest.h: + * include/cppunit/extensions/TestDecorator.h: + * include/cppunit/extensions/TestSetUp.h: + * include/cppunit/TestCaller.h + * include/cppunit/extensions/TestFactory.h + * include/cppunit/extensions/TestFactoryRegistry.h + * include/cppunit/extensions/TypeInfoHelper.h + * include/cppunit/Asserter.h + * include/cppunit/Exception.h + * include/cppunit/NotEqualException.h + * include/cppunit/SourceLine.h + * include/cppunit/SynchronizedObject.h + * include/cppunit/Test.h + * include/cppunit/TestAssert.h + * include/cppunit/TestCase.h + * include/cppunit/TestFailure.h + * include/cppunit/TestListener.h + * include/cppunit/TestResult.h + * include/cppunit/TestSuite.h + * include/cppunit/CompilerOutputter.h + * include/cppunit/Outputter.h + * include/cppunit/TestResultCollector.h + * include/cppunit/TestSuccessListener.h + * include/cppunit/TextOutputter.h + * include/cppunit/TextTestProgressListener.h + * include/cppunit/TextTestResult.h + * include/cppunit/TextTestRunner.h + * include/cppunit/XmlOutputter.h: added CPPUNIT_API for DLL export. + + * include/cppunit/TestSuite.h: + * src/cppunit/TestSuite.cpp: reindented + + * include/cppunit/extensions/TestSetUp.h: + * src/cppunit/TestSetUp.cpp: added .cpp. extracted inline method and moved + them to cpp file. + + * src/cppunit/DllMain.cpp: added, contains Dll entry point. + +2002-03-06 Baptiste Lepilleur + + * src/cppunit/TextTestProgressListener.cpp: flush the stream after each + progess step. + +2002-03-03 Baptiste Lepilleur + + * configure.in: updated version number to 1.7.4 + +2002-03-03 Baptiste Lepilleur + + * include/cppunit/makefile.am: + * src/cppunit/makefile.am: added missing SynchronizedObject and + TextOutputter.h. + + * generated 1.7.3 tar ball. + +2002-02-29 Baptiste Lepilleur + + * inclued/cppunit/XmlOutputter.h: + * inclued/cppunit/XmlOutputter.cpp: added optional parameter to constructor + to specify the encoding. + + * configure.in: updated version number to 1.7.3 + +2002-02-28 Baptiste Lepilleur + + * NEW: updated and restructured. + + * include/cppunit/CompilerOutputter.h: + * src/cppunit/CompilerOutputter.cpp: + updated against TestResultChange. Changed TestResult to TestResultCollector. + + * include/cppunit/extensions/HelperMacros.h: minor documentation fix. + + * include/cppunit/Outputter.h: added. Abstract base class for all Outputter. + + * include/cppunit/Portability.h: made the fix on OStringStream suggested by + Bob Summerwill to remove level 4 warning with VC++. + + * include/cppunit/TestAssert.h: added macro CPPUNIT_ASSERT_EQUAL_MESSAGE. + + * src/cppunit/TestFailure.cpp: + * include/cppunit/TestFailure.h: added method clone() to duplicate a + failure. Made all method virtual. + + * include/cppunit/TestListener.h: changed signature of addFailure() to + addFailure( const TestFailure &failure ). Failure is now only a temporary + object. + + * include/cppunit/Outputter.h: added. Abstract base class for all + outputter. Used by TextTestRunner. + + * include/cppunit/SynchronizedObject.h: + * src/cppunit/SynchronizedObject.cpp: added. Class extracted from + TestResult. Base class for objects that can be accessed from different + threads. + + * include/cppunit/TestResult.h: TestFailure.h is no longer included. + + * include/cppunit/TestResult.h: + * src/cppunit/TestResult.cpp: extracted all methods related to keeping track + of the result to the new TestResultCollector class which is a TestListener. + + * include/cppunit/TestResultCollector.h: + * src/cppunit/TestResultCollector.cpp: added. TestListener which kept track + of the result of the test run. All failure/error, and tests are tracked. + + * include/cppunit/TestSucessListener.h: + * src/cppunit/TestSucessListener.cpp: added. TestListener extracted from + TestResult. Is responsible for wasSucessful(). + + * include/cppunit/TestCase.h: + * src/cppunit/TestCase.cpp: reindented. + + * include/cppunit/TextOutputter.h: + * src/cppunit/TextOutputter.cpp: added. Copied from the deprecated + TextTestResult and modified to act as an Ouputter. + + * include/cppunit/TextTestProgressListener.h: + * src/cppunit/TextTestProgressListener.cpp: Copied from the deprecated + TextTestResult and modified to print the dot while the test are running. + + * include/cppunit/TextTestResult.h: + * src/cppunit/TextTestResult.cpp: updated against TestResult change. + No compatiblity break. Deprecated. + + * include/cppunit/TextTestRunner.h: + * src/cppunit/TextTestRunner.cpp: updated to work with the new TestResult. + Use TextTestProgressListener and TextOutputter instead of TextTestResult. + Any outputter with interface Outputter can be used to print the test result + (CompilerOutputter, XmlOutputter, TextOutputter...) + + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: updated against TestResultChange. + Changed TestResult to TestResultCollector. + + * src/msvc6/TestRunnerDlg.h: + * src/msvc6/TestRunnerDlg.cpp: fixed the 'fullrowselect' feature of the + list view. The dialog is a TestListener itself, it no longer use the + GUITestResult class. + + * src/msvc6/TestRunner.rc: moved the "autorun test button" in such a way that + it did not overlap the progress bar anymore. + + * src/msvc6/MfcSynchronizationObject.h: added. Generic SynchronizedObject + lock for MFC. + + * src/msvc6/GUITestResult.h : + * src/msvc6/GUITestResult.cpp : removed. + + * src/qttestrunner/TestRunnerModel.h: + * src/qttestrunner/TestRunnerModel.cpp: changed addFailure() signature to + reflect change on TestListener. + + * examples/cppunittest/CppUnitTestMain.cpp: updated to use the new Outputter + abstraction and TextTestRunner facilities. + + * examples/cppunittest/FailingTestCase.h: + * examples/cppunittest/FailingTestCase.cpp: removed. Replaced by MockTestCase. + + * examples/cppunittest/FailingTestCase.h: + * examples/cppunittest/FailingTestCase.h: + + * examples/cppunittest/HelperMacrosTest.h: + * examples/cppunittest/HelperMacrosTest.cpp: Updated against TestResult change. + Use MockTestListener instead of TestResult to check for sucess or failure. + + * examples/cppunittest/MockTestListener.h: + * examples/cppunittest/MockTestListener.cpp: the class now behave like a mock + object. + + * examples/cppunittest/MockTestCase.h: + * examples/cppunittest/MockTestCase.cpp: added. Mock TestCase object. + + * examples/cppunittest/OrthodoxTest.h: + * examples/cppunittest/OrthodoxTest.cpp: Updated against TestResult change. + Use MockTestListener instead of TestResult to check for sucess or failure. + + * examples/cppunittest/SynchronizedTestResult.h: Updated against TestResult + change. + + * examples/cppunittest/TestCallerTest.h: + * examples/cppunittest/TestCallerTest.cpp: Updated against TestResult change. + Use MockTestListener instead of TestResult. + + * examples/cppunittest/TestCaseTest.h: + * examples/cppunittest/TestCaseTest.cpp: Updated against TestResult change. + Use MockTestListener and MockTestCase instead of FailingTestCase and TestResult. + + * examples/cppunittest/TestDecoratorTest.h: + * examples/cppunittest/TestDecoratorTest.cpp: Updated against TestResult change. + Use MockTestCase instead of FailingTestCase. + + * examples/cppunittest/TestListenerTest.h: + * examples/cppunittest/TestListenerTest.cpp: removed. Those unit tests have been + rewrote and moved to TestResultTest. + + * examples/cppunittest/TestResultTest.h: + * examples/cppunittest/TestResultTest.cpp: Updated to test the new interface. + Tests from TestListenerTest have been moved here. + + * examples/cppunittest/TestResultCollectorTest.h: + * examples/cppunittest/TestResultCollectorTest.cpp: added. Tests for the class + that been extracted from TestResult. + + * examples/cppunittest/TestSetUpTest.h: + * examples/cppunittest/TestSetUpTest.cpp: renamed SetUp inner class to MockSetUp. + Changed interface to be more akin to a Mock object. + + * examples/cppunittest/TestSuiteTest.h: + * examples/cppunittest/TestSuiteTest.cpp: Updated against TestResult change, + and rewrote to use MockTestCase instead of FailingTestCase. + + * examples/cppunittest/XmlOutputterTest.h: + * examples/cppunittest/XmlOutputterTest.cpp: Updated against TestResult change. + Added some utility methods to make the update easier. + +2001-10-28 Steve M. Robbins + + * INSTALL-unix: Add note about cygwin. + +2001-10-24 Baptiste Lepilleur + + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp: + * examples/msvc6/HostApp/HostApp.dsp: use custom file build instead + of post-build/pre-link step to copy the TestRunner DLL to the + Release/Debug directory. + + * src/msvc6/ProgressBar.cpp: + * src/msvc6/ProgressBar.h: + * src/msvc6/TestRunner.rc: + * src/msvc6/TestRunnerDlg.cpp: + * src/msvc6/TestRunnerDlg.h: + * src/msvc6/testRunner.dsp: + * src/msvc6/TestRunnerModel.cpp: + * src/msvc6/TestRunnerModel.h: included Gigi Sayfan (gigi@morphink.com) + patch. The dialog can now be resized, and list view columns and dialog + sizes are saved. + + * src/msvc6/ProgressBar.cpp: + * src/msvc6/ProgressBar.h: Minor refactoring. + + * THANKS: added Gigi Sayfan to the list. + +2001-10-21 Steve M. Robbins + + * configure.in: Bump version to 1.7.2. + + * Release 1.7.1 (alpha). + + * Merged changes from cvs BRANCH_1_6; details follow. + + * examples/cppunittest/TestSetUpTest.h (class SetUp): Add + namespace qualifier to CppUnit::TestSetup() constructor call. + + * include/cppunit/Makefile.am (dist-hook): Restore hook to + remove config-auto.h from distribution. + + * doc/Makefile.am: Move the definition of htmldir inside if DOC + conditional. Add "else" branch to conditional with dummy targets + for install-data-hook and uninstall-local. Move all-local outside + the conditional, and move "dox" target into both branches of the + conditional. + +2001-10-20 Steve M. Robbins + + * examples/cppunittest/Makefile.am (cppunittestmain_SOURCES): + Include XmlUnformiserTest files. + + * doc/Doxyfile.in (GENERATE_MAN): Do not generate man pages. + * doc/Makefile.am: Do not make man directories. + +2001-10-19 Baptiste Lepilleur + + * include/cppunit/Exception.h: + * src/cppunit/Exception.cpp: what(), added back the throw() qualifier. + +2001-10-14 Baptiste Lepilleur + + * include/cppunitui/* : added, Qt TestRunner. + + * examples/qt/* : added, example showing the use of Qt TestRunner. + + * src/qttestrunner : added, source of the Qt TestRunner DLL. + +2001-10-08 Steve M. Robbins + + * src/cppunit/Exception.cpp (what): Remove "throw()" qualifier, to + match earlier change to header. + +2001-10-07 Baptiste Lepilleur + + * include/cppunit/CompilerTestResultOutputter.h : + renamed CompilerOutputter.h + + * src/cppunit/CompilerTestResultOutputter.cpp : + renamed CompilerOutputter.cpp + + * include/cppunit/CompilerTestResultOutputter.h : + * src/cppunit/CompilerTestResultOutputter.cpp : ajust max line length + for wrapping. Added static factory method defaultOutputter(). Print + the number of test runs on success. + + * include/cppunit/CompilerTestResultOutputter.h : renamed + CompilerOutputter.h. + + * src/cppunit/CompilerTestResultOutputter.cpp : renamed + CompilerOutputter.cpp. + + * examples/cppunittest/CppUnitTestMain.cpp : use factory method + CompilerTestResultOutputter::defaultOutputter(). + + * src/msvc6/DSPlugIn/DSPlugIn.dsp : removed COM registration in + post-build step. IT is automatically done by VC++ when the add-in is + added. Caused build to failed if the add-in was used in VC++. + + * NEWS : updated. + + * src/cppunit/TestAssert.cpp : modified deprecated assert + implementations to use Asserter. + + * examples/cppunittest/XmlTestResultOutputterTest.h : + renamed XmlOutputterTest.h. + + * examples/cppunittest/XmlTestResultOutputterTest.cpp : + renamed XmlOutputterTest.cpp. + + * NEWS : + * examples/cppunittest/CppUnitTestMain.cpp : + * examples/cppunittest/CppUnitTestMain.dsp : + * examples/cppunittest/Makefile.am : + * examples/cppunittest/XmlTestResultOutputterTest.h : + * examples/cppunittest/XmlTestResultOutputterTest.cpp : + * examples/msvc6/CppUniTestApp/CppUnitTestApp.dsp + * include/cppunit/CompilerOutputter.h : + * include/cppunit/Makefile.am : + * include/cppunit/XmlTestResultOutputter.h : + * src/cppunit/CompilerOutputter.cpp : + * src/cppunit/cppunit.dsp : + * src/cppunit/Makefile.am : + * src/cppunit/XmlTestResultOutputter.cpp : change due to renaming + CompilerTestResultOutputter to CompilerOutputter, + XmlTestResultOutputter to XmlOuputter, XmlTestResultOutputterTest + to XmlOutputterTest. + +2001-10-06 Baptiste Lepilleur + + * include/cppunit/CompilerTestResultOutputter.h : + * src/cppunit/CompilerTestResultOutputter.cpp : added. Output result + in a compiler compatible format. + + * src/cppunit/CppUnit.dsp : + * include/cppunit/MakeFile.am : + * src/cppunit/MakeFile.am : added CompilerTestResultOutputter.cpp + and CompilerTestResultOutputter.h. + + * examples/cppunittest/CppUnitTestMain.cpp : if -selftest is specified + on the command line, no standard test result are printed, but compiler + compatible result at printed. + + * examples/cppunittest/CppUnitTestMain.dsp : added post-build step to + run the test suite with -selftest. + + * NEWS : updated. + + * src/cppunit/TextTestRunner.cpp : skip a line after printing + progress. + +2001-10-06 Baptiste Lepilleur + + * examples/cppunittest/CppUnitTestMain.cpp : application returns + 0 is test suite run sucessfuly, 1 otherwise. + + * src/cppunit/Exception.cpp : bug fix, operator =() with VC++. + Removed call to std::exception::operator =() which is bugged + on VC++. + + * doc/FAQ : added a note explaining why the test + ExceptionTest.testAssignment used to fail. + + * NEWS : updated and detailed. + + * include/cppunit/TestResult.h : + * src/cppunit/TestResult.cpp : added reset(). + + * include/cppunit/TextTestRunner.h : + * src/cppunit/TextTestRunner.cpp : Constructor take an optional + TextTestRestult. The TextTestResult remain alive as long as + the runner. Added result() to retreive the result. Printing the + result is now optinal (enabled by default). + +2001-10-05 Baptiste Lepilleur + + * include/cppunit/Asserter.h : + * src/cppunit/Asserter.cpp : added. Helper to create assertion macros. + + * src/cppunit/cppunit.dsp : + * src/cppunit/Makefile.am : + * include/cppunit/Makefile.am : added Asserter.h and Asserter.cpp. + + * include/cppunit/Exception.h : + * src/cppunit/Exception.cpp : added constructor that take a + SourceLine argument. Deprecated static constant and old constructor. + Fixed some constness issues. + + * examples/cppunittest/ExceptionTest.cpp : Refactored. + + * NEWS : partially updated (need to be more detailed) + + * include/cppunit/NotEqualException.h : + * src/cppunit/NotEqualException.cpp : added constructor that take a + SourceLine argument. Deprecated old constructor. Added a third element + to compose message. + + * examples/cppunittest/NotEqualExceptionTest.cpp : moved to "Core" + suite. Added test for SourceLine() and additionalMessage(). + Refactored. + + * include/cppunit/SourceLine.h : + * src/cppunit/SourceLine.cpp : added. Result of applying + IntroduceParameterObject refactoring on filename & line number... + + * include/cppunit/TestAssert.h : + * src/cppunit/TestAssert.cpp : deprecated old assert functions. + added functions assertEquals() and assertDoubleEquals() which use + SourceLine. + + * src/cppunit/TestCase.cpp : Modified for SourceLine. + + * include/cppunit/TestFailure.h : + * src/cppunit/TestFailure.cpp : added failedTestName(), and + sourceLine(). + + * src/msvc6/testrunner/TestRunnerDlg.cpp : modified to use SourceLine. + + * include/cppunit/TextTestResult.h : + * src/cppunit/TextTestResult.cpp : corrected include order and + switched to angled brackets. Refactored. Don't print failure location + if not available. Not equal failure dump additional message if + available. + + * src/cppunit/TextTestRunner.cpp : run() now returns a boolean to + indicate if the run was sucessful. + + * src/cppunit/XmlTestResultOutputter.cpp : replaced itoa() with + OStringStream. Refactored. + + * examples/cppunittest/XmlUniformiser.h : + * examples/cppunittest/XmlUniformiser.cpp : + CPPUNITTEST_ASSERT_XML_EQUAL capture failure location. Refactored + checkXmlEqual(). + + * examples/cppunittest/XmlUniformiserTest.h : + * examples/cppunittest/XmlUniformiserTest.cpp : added test for + CPPUNITTEST_ASSERT_XML_EQUAL. + + * include/cppunit/XmlTestResultOutputter.h : + * src/cppunit/XmlTestResultOutputter.cpp : updated to use SourceLine. + +2001-10-05 Baptiste Lepilleur + + * NEWS : updated. + + * include/cppunit/Exception.h : added include Portability.h. + + * include/cppunit/TestResult.* : changed TestFailures to a deque. + added tests(). + + * examples/cppunittest/CppUnitTest.dsp : + * examples/cppunittest/MakeFile.am : + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp : Added + XmlTestResultOutputterTest.*, XmlUniformiser.*, XmlUniformiserTest.*, + UnitTestToolSuite.h, OutputSuite.h. + + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp : revised project + folders structure. Added missing NoteEqualExceptionTest.*. + + * examples/cppunittest/CppUnitTestSuite.cpp : added 'Output' and + 'UnitTestTool' suites. + + * src/cppunit/cppunit.dsp: removed estring.h. Revised project folders + structure. Removed TestRegistry.*. Added TestSetUp.h, + XmlTestResultOutputter.*. + + * src/cppunit/MakeFile.am: added XmlTestResultOutputter.*. + + * src/testrunner/TestRunnerDlg.cpp: removed disabled code. + +2001-10-03 Baptiste Lepilleur + + * include/cppunit/TestFailure.cpp : + * include/cppunit/TestFailure.h : fixed some constness issues. Added + argument to indicate the type of failure to constructor. Added + isError(). + + * include/cppunit/TestListener.h : removed addError(). addFailure() + now take a TestFailure as argument. + + * include/cppunit/TestResult.h : + * include/cppunit/TestResult.cpp : removed errors(). Refactored. Fixed + some constness issues. Added typedef TestFailures for vector returned + by failures(). failures() returns a const reference on the list of + failure. added testFailuresTotal(). Constructor can take an optional + synchronization object. + + * include/cppunit/TextTestResult.h : + * include/cppunit/TextTestResult.cpp : removed printErrors(). + Refactored. Updated to suit new TestResult, errors and failures are + reported in the same list. + + * examples/cppunittest/TestFailureTest.cpp : + * examples/cppunittest/TestFailureTest.h : modified to use the new + TestFailure constructor. Added one test. + + * examples/cppunittest/TestListenerTest.cpp: removed addError(). + Refactored to suit new TestListener. + + * examples/cppunittest/TestResultTest.h : + * examples/cppunittest/TestResultTest.cpp : modified to suit the + new TestResult. + +2001-10-02 Baptiste Lepilleur + + * include/cppunit/extensions/TestFactoryRegistry.h + * src/cppunit/TestFactoryRegistry.cpp : fixed memory leaks that + occured when a TestFactoryRegistry was registered into another + TestFactoryRegistry. + + * include/cppunit/extensions/AutoRegisterSuite.h : updated doc. + + * include/cppunit/extensions/HelperMacros.h : added macro + CPPUNIT_TEST_SUITE_NAMED_REGISTRATION to register a suite into + a named suite. Updated doc. + + * examples/cppunittest/CoreSuite.h: + * examples/cppunittest/ExtensionSuite.h: + * examples/cppunittest/HelperSuite.h: added, declaration of suite for + use with CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + + * examples/cppunittest/makefile.am : added HelperSuite.h, CoreSuite.h, + ExtensionSuite.h, CppUnitTestSuite.h and CppUnitTestSuite.cpp. + + * examples/cppunittest/CppUnitTestSuite.*: added. + + * examples/cppunittest/ExceptionTest.cpp: + * examples/cppunittest/TestAssertTest.cpp: + * examples/cppunittest/TestCaseTest.cpp: + * examples/cppunittest/TestFailureTest.cpp: + * examples/cppunittest/TestListenerTest.cpp: + * examples/cppunittest/TestResultTest.cpp: + * examples/cppunittest/TestSuiteTest.cpp: moved into named suite + "Core" using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + + * examples/cppunittest/OrthodoxTest.cpp: + * examples/cppunittest/RepeatedTest.cpp: + * examples/cppunittest/TestDecoratorTest.cpp: + * examples/cppunittest/TestSetUpTest.cpp: moved into named suite + "Extension" using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + + * examples/cppunittest/HelperMacrosTest.cpp: + * examples/cppunittest/TestCallerTest.cpp: moved into named suite + "Helper" using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + + * examples/cppunittest/CppUnitTest.dsp : + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp : added + Makefile.am, HelperSuite.h, CoreSuite.h, ExtensionSuite.h, + CppUnitTestSuite.h and CppUnitTestSuite.cpp. + +2001-10-01 Baptiste Lepilleur + + * NEWS : updated. + + * doc/other_documentation.dox : added all the authors to the list of + authors. + + * examples/cppunittest/HelperMacrosTest.*: added unit tests for + CPPUNIT_TEST_FAIL & CPPUNIT_TEST_EXCEPTION. + + * examples/cppunittest/TestAssertTest.*: added unit tests for + CPPUNIT_FAIL. Corrected spelling error. Relaxed constraint on message + produced by CPPUNIT_ASSERT_MESSAGE. Refactored some tests. + + * include/cppunit/extensions/HelperMacros.h : added macro + CPPUNIT_TEST_EXCEPTION to create a test case for the specified method + that must throw an exception of the specified type. + + * include/cppunit/extensions/TestSuiteBuilder.h : made + makeTestName() public. Added addTestCallerForException() to add a + test case expecting an exception of the specified type to be + caught. + + * include/cppunit/TestAssert.h : added macro CPPUNIT_FAIL as a + shortcut for CPPUNIT_ASSERT_MESSAGE( message, false ). + +2001-09-30 Steve M. Robbins + + * configure.in: Set version to 1.7.0. + +2001-09-30 Steve M. Robbins + + * Release 1.6.1. + + * doc/footer.html: Do not meddle with font size. + + * doc/header.html: Add link to FAQ. Do not meddle with font size. + + * doc/Doxyfile.in (PROJECT_NAME): Set to "CppUnit", to be + consistent on capitalization. + (PROJECT_NUMBER): Include "Version" in the string. + + * doc/Makefile.am (EXTRA_DIST): Distribute FAQ. + + * Makefile.am (EXTRA_DIST): Distribute contrib/msvc/CppUnit.WWTpl + and contrib/msvc/readme.txt. + (dist-hook): Change line endings of these files. + + * include/cppunit/extensions/RepeatedTest.h + * src/cppunit/RepeatedTest.cpp (countTestCases, toString): + Add const qualifier to function. + +2001-09-30 Baptiste Lepilleur + + * contrib/msvc/CppUnit.WWTpl: added, template for WorkSpace Whiz! + to create new classes and unit tests. + + * doc/FAQ: + * INSTALL-WIN32.txt: moved FAQ from install-WIN32 to that file. Added + a generic question to hint at the helper macros. + + * include/cppunit/extensions/HelperMacros.h: bug #464844, moved + declaration of ThisTestCaseFactory from CPPUNIT_TEST_SUITE_END to + CPPUNIT_TEST_SUITE where the Fixture class name is available from + the macro parameter. + +2001-09-30 Steve M. Robbins + + * include/cppunit/config-mac.h: New. Macintosh configuration, + courtesy of Duane Murphy. + + * include/cppunit/Portability.h: Move include inside + #if-block that needs it. + + * doc/Makefile.am (doc-dist): Creates tar file of HTML doc files. + Remove all wildcarded filenames. Do not bother with manpages. + + * Makefile.am (EXTRA_DIST): Distribute INSTALL-unix and + cppunit-config.1. + (man_MANS): Install cppunit-config.1. + (doc-dist): Use "make doc-dist" in doc directory. + + * cppunit-config.1: Document --prefix and --exec-prefix. + + * cppunit-config.in (Usage): Remove "[LIBRARIES]" from help string. + +2001-09-29 Steve M. Robbins + + * configure.in: Set version to 1.6.1. + +2001-09-29 Baptiste Lepilleur + + * example/cppunittest/TestCaller.*: remove some memory leaks. + TestCaller exception catching features is now tested correctly. + Previous test tested nothing! + +2001-09-23 Steve M. Robbins + + * configure.in: Set version to 1.6.0. + + * Makefile.am (EXTRA_DIST): Add BUGS. + + * NEWS: Incorporate Baptiste's notes. + + * BUGS: New file for list of known bugs. + + * README: Note about file BUGS. + +2001-09-24 Baptiste Lepilleur + + * include/cppunit/TestAssert.h : changed header order to remove + warning on VC++ + + * include/cppunit/TestCaller.h : bugfix: threw 'new Exception' + instead of 'Exception'. + +2001-09-23 Steve M. Robbins + + * doc/footer.html: Put devel list in mailto tag. + + * doc/Makefile.am (man_MANS): Restore ability to install manpages. + (htmldir): HTML pages installed under $(pkgdatadir). + + * doc/other_documentation.dox: Reference cookbook.html + in same directory. Remove obsolete text. + + * configure.in: Do not set CFLAGS; remove --enable-debug-mode. + + * include/cppunit/Portability.h: + * include/cppunit/extensions/HelperMacros.h: Allow user + to request the old-style CU_TEST family of macros. + + * doc/Doxyfile.in (EXCLUDE_PATTERNS): Remove estring.h. + + * README: Add contact and bug-reporting info. + + * INSTALL-unix: New. Move the unix install notes here + from README. + + * AUTHORS: Put myself on the list. + +2001-09-21 Baptiste Lepilleur + + * include/cppunit/TestFailure.h : made destructor virtual. + + * INSTALL-WIN32.txt : added some more infos about DSPlugIn. + + * src/msvc6/DSPlugIn/DSPlugIn.rgs: added some registry data + that where missing to register the COM object. + + * src/msvc6/DSPlugIn/DSPlugIn.rc: updated some dll version info. + + * src/msvc6/DSPlugIn/DSPlugIn.dsp: fixed the custom build step to + register the DLL using regsvr32.exe. Added a post-build step to + copy the dll to the lib/ directory. This prevent a blocking + compilation error if the DLL is in use by VC++. + +2001-09-20 Steve M. Robbins + + * Makefile.am (snapshot): Replace "date -I" GNUism with portable + specification for ISO date format. + (dist-hook): Correct rule to change line endings for INSTALL-WIN32.txt. + + * include/cppunit/Portability.h: + * config/ac_cxx_have_strstream.m4 (AC_CXX_HAVE_STRSTREAM): Extend + to check for and use in preference to . + Patrick Hartling reports the former is required for the SGI + MIPSpro 7.3.1.2 compiler. + +2001-09-19 Baptiste Lepilleur + + * examples/cppunittest/makefile.am : added TestSetupTest.(cpp/h) + + * examples/examples.dsw: removed some unnecessary dependencies. + + * examples/msvc6/HostApp/HostApp.dsp: fixed release configuration + + * src/msvc6/DSPlugIn/DSPlugIn.dsp: fixed release configuration, and + disabled the custom build command that does not work. + + * include/cppunit/extensions/HelperMacros.h: reordered header to remove + some warning with VC++. + + * INSTALL-WIN32.txt : detailed what was in each project. Added a FAQ + about the failing test case in cppunittest. + +2001-09-19 Steve M. Robbins + + * README: Describe how to check if libtool is fixed. + + * Makefile.am (dist-hook): Include INSTALL-WIN32.txt in the list + of files to convert to MSDOS line endings. + (snapshot): Use ISO-8601 compliant date for filename. + (ACLOCAL_AMFLAGS): Specify local directory. + +2001-09-18 Steve M. Robbins + + * include/cppunit/TextTestResult.h: Change include from + to . Sugggested by Peer Sommerlund. + + * include/cppunit/Portability.h: Qualify ostrstream with std. + Suggested by Patrick Hartling. + +2001-09-18 Baptiste Lepilleur + + * examples/examples.dsw: + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsw: + * examples/msvc6/HostApp/HostApp.dsw: + * examples/msvc6/TestPlugIn/TestPlugIn.dsw: Added missing + project dependency. + + * src/msvc6/DSPlugIn/DSPlugIn.dsp: fixed *.tlb output directory. + + * include/msvc6/testrunner/TestPlugInInterface.h: does not define + NOMINMAX if already defined. + +2001-09-17 Baptiste Lepilleur + + * Makefile.am: Added INSTALL-WIN32.txt to EXTRA_DIST. + + * INSTALL-WIN32.txt: added, short documentation for CppUnit and VC++. + + * include/cppunit/extensions/HelperMacros.h: bug #448363, removed + an extraneous ';' at the end of CPPUNIT_TEST_SUITE_END macro. + + * examples/cppunittest/TestCallerTest.cpp: bug #448332, fixed + memory leaks. + + * src/msvc6/testrunner/TestRunnerDlg.h: + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.h: + * src/msvc6/testpluginrunner/TestPlugInRunnerDlg.cpp: change to define + IDD to a dummy value when subclassing the dialog. + + * src/cppunit/cppunit.dsp: + * src/msvc6/testrunner/TestRunner.dsp: + * src/msvc6/testpluginrunner/TestPlugInRunner.dsp: + * examples/cppunitttest/CppUnitTestMain.dsp: + * examples/hierarchy.dsp: + * examples/msvc6/TestPlugIn/TestPlugIn.dsp: + * examples/msvc6/HostApp/HostApp.dsp: all configurations can be compiled. + + * src/msvc6/testpluginrunner/TestPlugInRunner.dsw: added dependency to + cppunit.dsp and TestRunner.dsp. + +2001-09-16 Steve M. Robbins + + * Revert TestFixture-related changes from 2001-07-15: + + * src/cppunit/cppunit.dsp (SOURCE): Remove TestFixture.h. + + * src/cppunit/TestCase.cpp (setUp, tearDown): Restore function + bodies. + + * include/cppunit/TestCase.h (class TestCase): Do not derive + from class TestFixture. Restore member functions setUp() + and tearDown(). + + * include/cppunit/TestCaller.h: Do not include + . + + * include/cppunit/Makefile.am (libcppunitinclude_HEADERS): Remove + TestFixture.h. + +2001-09-14 Baptiste Lepilleur + * src/msvc6/testrunner/TestRunner.dsp: fixed release configuration. + + * src/msvc6/testrunner/TestRunner.dsw: added DSPlugIn.dsp. TestRunner + depends on DSPlugIn. + + * src/msvc6/testrunner/TestRunner.cpp: + * src/msvc6/testrunner/TestRunnerDlg.h: + * src/msvc6/testrunner/TestRunnerDlg.cpp: + * src/msvc6/testrunner/MsDevCallerListCtrl.cpp: + * src/msvc6/testrunner/MsDevCallerListCtrl.h: + * src/msvc6/DSPlugIn/*: integrated patch from + Patrick Berny (PPBerny@web.de). An add-ins for VC++. Double-cliking + a failed test in the TestRunner, VC++ will open the source file and + go to the failure location. + + * src/cppunit/Exception.cpp: + * include/cppunit/Exception.h: compile fix, call to overrided + operator = of parent class failed. Using typedef to the parent + class fix that. + + * src/cppunit/cppunit.dsp: added TestFixture.h + + * src/cppunit/TestFactoryRegistry.cpp: removed which isn't + needed any more. + + * include/cppunit/TestCase.h: + * include/cppunit/TestSuite.h: + * include/cppunit/extensions/TestFactoryRegistry.h: added + include before any other includes to remove warning + with VC++. + + * include/cppunit/Portability.h: moved platform specific includes at + the beginning of the header. fixed CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION + declaration. + + * include/cppunit/config-msvc6.h: removed pragma once (useless, should + be put in each header to have an effect). + +2001-08-07 Steve M. Robbins + + * doc/Makefile.am: Add workaround for broken Doxygen. + + * src/cppunit/TextTestResult.cpp (operator<<): Remove CppUnit:: + prefix. + + * configure.in: Add check for . + * src/cppunit/TestAssert.cpp: Use if not + available. + * src/cppunit/TestCase.cpp: Do not include . + + * include/cppunit/config-bcb5.h (HAVE_CMATH): + * include/cppunit/config-msvc6.h (HAVE_CMATH): Add. + + * src/cppunit/Exception.cpp: Qualify std::exception. + + * examples/cppunittest/OrthodoxTest.h (TestCase): Add assignment + operator. MIPSpro fails to compile without one. + + * Makefile.am: Removed automake conditional "DOC". + * doc/Makefile.am: Placed "DOC" conditional around + rules that invoke Doxygen. + + * config/Makefile.am: Removed. + * configure.in: Do not create config/Makefile. + * Makefile.am (EXTRA_DIST): Distribute config/*.m4. + (SUBDIRS): Do not descend into config. + +2001-07-15 Steve M. Robbins + + * include/cppunit/TestFixture.h: New. Declare class TextFixture. + + * include/cppunit/TestCaller.h: + * include/cppunit/TestCase.h: + * src/cppunit/TestCase.cpp: + * include/cppunit/Makefile.am: Subclass TestCase from TestFixture. + +2001-07-14 Steve M. Robbins + + * include/cppunit/Exception.h: + * include/cppunit/Test.h: + * include/cppunit/TestCaller.h: + * include/cppunit/TestCase.h: + * include/cppunit/TestFailure.h: + * include/cppunit/TestListener.h: + * include/cppunit/TestSuite.h: + * include/cppunit/extensions/RepeatedTest.h: + * include/cppunit/extensions/TestDecorator.h: + * src/cppunit/TestCase.cpp: Add documentation. + +2001-07-13 Steve M. Robbins + + * examples/cppunittest/TestAssertTest.h: + * examples/cppunittest/TestAssertTest.cpp: Add tests + for CPPUNIT_ASSERT_EQUAL. + +2001-07-12 Steve M. Robbins + + * configure.in: Set to version 1.5.6. On the assumption that + backwards compatibility has been broken (though I'm not certain), + set the binary age and interface age to zero. + + * examples/cppunittest/TestFailureTest.h: + * include/cppunit/Exception.h: + * include/cppunit/NotEqualException.h: + * src/cppunit/Exception.cpp: + * src/cppunit/NotEqualException.cpp: Add "throw()" to overridden + std::exception destructors; required for GCC 3.0. + +2001-07-07 Steve M. Robbins + + * include/cppunit/Makefile.am: Clean config-auto.h using + DISTCLEANFILES. + + * doc/Makefile.am: Temporarily disable manpage installation. + Fix html installation to ensure files removed by uninstall. + + * src/cppunit/estring.h: Removed. + + * src/cppunit/Makefile.am: + * src/cppunit/TestCase.cpp: + * src/cppunit/TextTestResult.cpp: Recode to avoid use of estring. + + * examples/cppunittest/OrthodoxTest.h: Add const qualifier + to operator== methods. + + * include/cppunit/config-bcb5.h: + * include/cppunit/config-msvc6.h: Define CPPUNIT_HAVE_SSTREAM to 1. + + * config/ac_cxx_have_sstream.m4: New. Defines macro + AC_CXX_HAVE_SSTREAM. Taken from the autoconf archive. + + * config/ac_cxx_have_strstream.m4: New. Copy of above, + modified to check for presence of strstream; defines + macro AC_CXX_HAVE_STRSTREAM. + + * configure.in: Invoke AC_CXX_HAVE_SSTREAM and + AC_CXX_HAVE_STRSTREAM. + + * include/cppunit/Portability.h: Define class + CppUnit::OStringStream. + + * include/cppunit/TestAssert.h: + * src/cppunit/TestFactoryRegistry.cpp: Replace std::ostringstream + by CppUnit::OStringStream. + + +2001-07-06 Steve M. Robbins + + * configure.in: Add --disable-typeinfo-name option. + + * README: Add note about new configure option. + + * configure.in: Remove AM_DISABLE_STATIC. + + * INSTALL: Update to version from autoconf 2.50. + +2001-07-05 Steve M. Robbins + + * include/cppunit/Portability.h: Remove definition of + CPPUNIT_USE_TYPEINFO. + + * configure.in: Define USE_TYPEINFO_NAME in config.h. + + * include/cppunit/config-msvc6.h (CPPUNIT_USE_TYPEINFO_NAME): + * include/cppunit/config-bcb5.h (CPPUNIT_USE_TYPEINFO_NAME): Add + definition. + + * include/cppunit/TestCaller.h: + * include/cppunit/extensions/TypeInfoHelper.h: + * include/cppunit/extensions/TestSuiteBuilder.h: + * include/cppunit/extensions/HelperMacros.h: + * src/cppunit/TypeInfoHelper.cpp: + * src/cppunit/TestFactoryRegistry.cpp: + * src/cppunit/TestCase.cpp (toString): + Switch from CPPUNIT_USE_TYPEINFO to CPPUNIT_USE_TYPEINFO_NAME. + + * src/cppunit/TestAssert.cpp: Remove include of estring.h. + + * configure.in: Invoke AC_PROG_CC to workaround a automake + bug. Move probes for CC/CXX ahead of the libtool macros. + + * examples/hierarchy/Makefile.am: + * examples/cppunittest/Makefile.am: + * src/cppunit/Makefile.am (INCLUDES): Search + $(top_builddir)/include for . + +2001-06-27 Baptiste Lepilleur + + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp: + moved dll copy from post-build to custom build setting, so that the + dll is copied even if the CppUnitTestApp was not modified. + + * examples/msvc6/TestPlugIn/: a new example of test plug in. + + * src/msvc6/TestRunner/ListCtrlFormatter.* + * src/msvc6/TestRunner/ListCtrlSetter.*: + added, helper to manipulate list control. + + * src/msvc6/TestRunner/TestRunnerDlg.*: change to make the error list + more compact. text moved to string resources. icons added for typ + test tfailure type. + + * src/msvc6/TestRunner/MostRecentTests.*: added, classes that will + replace the current implementation of MRU test which make it hard + to subclass the dialog. + + * src/msvc6/TestRunner/res/errortype.bmp: added, bitmap with error + types (failure and error). + + * src/msvc6/TestPlugInRunner/: A test runner to run test plug in. + Test plug in are DLL that publish a specified plug in interface. + Those DLL are loaded and reloaded by the TestPlugInRunner to run + tests. This remove the need to wrap DLL with a executable to test + them. + + * src/cppunit/cppunit.dsp: + removed config.h from project + added Portability.h and config-msvc6.h + + * include/cppunit/config-msvc6.h: + undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST + + +2001-06-20 Steve M. Robbins + + * autogen.sh: Stop when tool fails. Try /usr/local/share/aclocal + only if aclocal fails without it. + + * README.CVS: New. + +2001-06-18 Steve M. Robbins + + * include/cppunit/Portability.h (CPPUNIT_USE_TYPEINFO): + (CPPUNIT_ENABLE_NAKED_ASSERT): + (CPPUNIT_HAVE_CPP_SOURCEANNOTATION): Fix setting of + default values. + +2001-06-17 Steve M. Robbins + + * configure.in: Require autoconf 2.50 or better. + +2001-06-17 Bastiaan Bakker + + * configure.in: moved config.h from include/ to config/ + + * configure.in: added AC_CREATE_PREFIX_CONFIG_H call + + * config/ac_create_prefix_config_h.m4: added + + * configure.in: removed include/cppunit/config.h from AC_OUTPUT + * include/cppunit/config.h.in: obsoleted by + AC_CREATE_PREFIX_CONFIG_H macro. + + * configure.in: + * config/bb_enable_doxygen.m4: moved doxygen stuff into + BB_ENABLE_DOXYGEN macro + + * include/cppunit/Makefile.am: removed config.h, added config-auto.h, + config-msvc6.h, config-bcb5.h, Portability.h + + * include/cppunit/Makefile.am: added dist-hook to exclude + config-auto.h from dist tar + + * include/cppunit/TestAssert.h: + * include/cppunit/extensions/TypeInfoHelper.h: + * include/cppunit/extensions/TestSuiteBuilder.h: + * include/cppunit/extensions/HelperMacros.h: + * src/cppunit/TypeInfoHelper.cpp: + * src/cppunit/TestRegistry.cpp: + * src/cppunit/TestFactoryRegistry.cpp: + * src/cppunit/TestCase.cpp: replaced #include of with + + + * src/cppunit/TypeInfoHelper.cpp: use new macro name + CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST + + +2001-06-12 Baptiste Lepilleur + + * include/cppunit/NotEqualException.h + * src/cppunit/NotEqualException.h: + Fixed constructor and operator = (aren't unit test nice?). Added + methods expectedValue() and actualValue(). + + * include/cppunit/TestAssert.h: + * src/cppunit/TestAssert.cpp: + Use NotEqualException to report equality failure. + + * src/cppunit/TestFactoryRegistry.cpp: fixed makeTest(). It did not use m_name for + naming the suite. + + * src/cppunit/TestResult.cpp: + Report expect/was on different line for assertEquals failure. + + * examples/cppunittest/NotEqualExceptionTest.*: added unit tests for + NotEqualException. + + * examples/cppunittest/OrthodoxTest.*: operator ! use explicit construction. + + * examples/msvc6/CppUnitTestApp/CppUnitTestApp.cpp: modified so that the dialog + is not displayed after the tests are run. + +2001-06-11 Steve M. Robbins + + * examples/cppunittest/TestResultTest.cpp (testAddTwoErrors, + testAddTwoFailures): Replace vector::at() with more portable + vector::operator[]; GCC doesn't have the former. + + * include/cppunit/extensions/TestDecorator.h (countTestCases): + Declare return type. + + * src/cppunit/Makefile.am (libcppunit_la_SOURCES): Add + TestAssert.cpp, RepeatedTest.cpp. + + * include/cppunit/TestCaller.h (NoExceptionExpected): Fix + constructor name. + +2001-06-11 Baptiste Lepilleur + + * include/cppunit/Exception.h: now inherit from std::exception + instead of ::exception. Added clone(), type(), and isInstanceOf() + methods for subclassing support. Changed UNKNOWNLINENUMBER type to + long for consistence with lineNumber(). + + * include/cppunit/NotEqualException.h: addded, exception to be + used with assertEquals(). + + * include/cppunit/TestAssert.h: changed TestAssert into a + namespace instead of a class. This remove the need of template + member methods and does not cause compiler internal error on + VC++. Macro CPPUNIT_ASSERT_MESSAGE has been added to fail test + with a specified message. + + * include/cppunit/TestCaller.h: added "Expected exception" + support. Based on Tim Jansen patch (#403745), but use a traits + instead of RTTI to distingh between "No expected exception" and + "Excepted exception". Exception type name is reported using RTTI + if CPPUNIT_USE_TYPEINFO is defined. + + * include/cppunit/extensions/HelperMacros.h: static method suite() + implemented by CPPUNIT_TEST_SUITE_END macro now returns a + TestSuite instead of a Test. + + * include/cppunit/extensions/RepeatedTest.h: corrected + countTestCases, operator = declaration. + + * include/cppunit/extensions/TestDecorator.h: removed const from + run() method. Did not match run() declaration of Test class. + + * include/cppunit/extensions/TestFactory.h: fixed a comment. + + * include/cppunit/extensions/TestSetup.h: corrected run() method + declaration. Methods setUp() and tearDown() were not declared + virtual. + + * include/cppunit/extensions/TestSuiteBuilder.h: added a method + addTestCaller() which take a pointer on a fixture. + + * include/cppunit/NotEqualException.cpp: addded, exception to be + used with assertEquals(). + + * src/cppunit/RepeatedTest.cpp: added to reduce header dependency + (TestResult.h was missing). + + * src/cppunit/TestAssert.cpp: added to put non template functions + there. + + * src/cppunit/TestCase.cpp: added std:: prefix to catch + (exception& e). Integrated a modified version of Tim Jansen patch + (#403745) for TestCase to make the unit test (TestCaseTest) + pass. If the setUp() fail then neither the runTest() nor the + tearDown() method is called. + + * examples/examples.dsw: added cppunittest projects to workspace. + + * examples/cppunittest/TestResultTest.*: renamed + TestListenerTest.* + + * examples/cppunittest/*: added unit tests for: HelperMacros, + TestAssert, TestCaller, TestCase, TestFailure, TestResult, + TestSuite, TestDecoratorTest, TestSetUp, RepeatedTestTest, + Orthodox, Exception. + +2001-06-05 Baptiste Lepilleur + + * src/cppunit/TypeInfoHelper.cpp: removed #include , + cppunit/config.h was already included. + + * src/cppunit/cppunit.dsp: removed TestAssert.cpp from project. + + * added/updated .cvsignore files for beter handling of windows + projects. + + * added include/cppunit/config.h with a default configuration for + VC++ 6.0. + + * include/cppunit/.cvsignore: removed config.h from the list of + ignored file. + + * renamed VC++ configurations without RTTI from "Debug No + CU_USE_TYPEINFO" to "Debug Crossplatform". + + * include/cppunit/TestAssert.h: added include for fabs(). + +2001-06-02 Steve M. Robbins + + * src/cppunit/Exception.cpp: Remove unnecessary namespace + declaration; it confuses Doxygen. + +2001-06-02 Steve M. Robbins + + * configure.in: Add AC_CXX_STRING_COMPARE_STRING_FIRST. + + * autogen.sh: Add "-I config" to aclocal flags, to pick up + the new .m4 files. + + * config/ac_cxx_namespaces.m4: New. Taken from + http://cryp.to/autoconf-archive. + + * config/ac_cxx_string_compare_string_first.m4: New. Detect + if std::string::compare() takes string argument first. + +2001-06-02 Steve M. Robbins + + * include/cppunit/TestAssert.h: Declare generic assertion_traits + class. Replace notEqualsMessage functions for long and double by + a generic, template function. Replace assertEquals for longs by a + generic template function. Inline all class methods. Define new + assertion macros CPPUNIT_ASSERT, CPPUNIT_ASSERT_EQUAL, and + CPPUNIT_ASSERT_DOUBLES_EQUAL; the old names are available by + editing . + + * src/cppunit/TestAssert.cpp: Removed. Move code to inline + functions. + + * config/ac_cxx_rtti.m4: New. Taken from + http://cryp.to/autoconf-archive. + + * include/cppunit/config.h.in: New. Input file for installable, + generated config.h file. + + * configure.in: Use AC_CXX_RTTI; generate include/cppunit/config.h. + + * include/cppunit/extensions/HelperMacros.h: + * include/cppunit/extensions/TestSuiteBuilder.h: + * include/cppunit/extensions/TypeInfoHelper.h: + * src/cppunit/TestCase.cpp: + * src/cppunit/TestFactoryRegistry.cpp: + * src/cppunit/TypeInfoHelper.cpp: + Use "#if CPPUNIT_USE_TYPEINFO" rather than "#ifdef". + + * src/cppunit/TypeInfoHelper.cpp: Allow for std::string::compare() + that takes the string in the first argument. + + * doc/cookbook.html: + * examples/cppunittest/TestCallerTest.cpp: + * examples/cppunittest/TestResultTest.cpp: + * examples/hierarchy/BoardGameTest.h: + * examples/hierarchy/ChessTest.h: + * examples/msvc6/HostApp/ExampleTestCase.cpp: + * include/cppunit/TestCase.h: + * include/cppunit/extensions/Orthodox.h: + Replace assert by CPPUNIT_ASSERT. + Replace assertLongsEqual by CPPUNIT_ASSERT_EQUAL. + Replace assertDoublesEqual by CPPUNIT_ASSERT_DOUBLES_EQUAL. + + * * (CU_TEST_SUITE, CU_TEST, CU_TEST_SUITE_END, + CU_TEST_SUITE_REGISTRATION): Replace prefix CU_ with CPPUNIT_. + + * examples/cppunittest/.cvsignore: Add UNIX generated files. + +2001-06-01 Bastiaan Bakker + + * examples/cppunittest/Makefile.am: added + + * configure.in: added examples/cppunittest/Makefile to AC_OUTPUT. + + * examples/cppunittest/TestCallerTest (suite), + examples/cppunittest/TestResultTest (suite): fixed 'ISO C++ + forbids taking the address of a bound member function to form + a pointer to member function' bug reported by g++. + + * examples/cppunittest/TestCallerTest (suite), + examples/cppunittest/TestResultTest (suite): removed dependency on + RTTI. + +2001-06-01 Baptiste Lepilleur + + * added project cppunittest to examples/: unit tests to test cppunit. + The main file is CppUnitTestMain.cpp. Unit tests have been implemented + for TestCaller and TestListener. + + * added project CppUnitTestApp to examples/msvc6: graphical runner + for cppunittest. + + * added TestListener to TestResult. It is a port of junit + TestListener. + + * updated some .cvsignore to ignore files generated with VC++. + +2001-05-30 Bastiaan Bakker + + * src/cppunit/TestCase.cpp (toString): put type_info in std + namespace and inside CU_USE_TYPEINFO ifdef. + +2001-05-29 Steve M. Robbins + + * examples/hierarchy/main.cpp: Remove extraneous includes. + + * src/cppunit/TextTestResult.cpp (addError, addFailure): Do not + emit a newline. + + * include/cppunit/extensions/HelperMacros.h: Rework documentation. + (CU_TEST_SUITE): Move definition of member function suite() ... + (CU_TEST_SUITE_END): ... to here. + (CU_TEST): Use '&' to take address of member function + "testMethod". + + * include/cppunit/extensions/AutoRegisterSuite.h: Declare "factory" + as a TestFactory*. + +2001-05-28 Steve M. Robbins + + * doc/other_documentation.dox: Don't include "CppUnit" in + anchor text, since Doxygen puts its own anchor around it. + + * doc/Makefile.am (html/index.html): Depend on + other_documentation.dox. + + * doc/Doxyfile.in (EXCLUDE): Move config.h and estring.h to + EXCLUDE_PATTERNS; they were not being excluded. + + * ChangeLog: Reformat all entries to start with . See + for change log + format. + + * doc/cookbook.html: Update all code examples, except for TestRunner + section. + +2001-05-23 Baptiste Lepilleur + + * Updated CU_TEST_SUITE macro documentation. It is now stated + explicitly that you do not need to specify template parameter as + macro argument. The documentation example has been updated to + reflect that. + +2001-05-23 Bastiaan Bakker + + * autogen.sh: added '--add-missing' option to automake. + * autogen.sh: added '--force' option to libtoolize and removed + '--copy'. + * config: removed generated files from CVS. + +2001-05-20 Baptiste Lepilleur + + * Fixed bug #424320 (VC++ TestRunner): access violation caused by + NULL pointer in history list. NULL pointer are not added to the + history anymore. + +2001-05-19 Baptiste Lepilleur + + * Added some items to the TODO list for VC++ TestRunner. + + * "Debug" configuration is now the default configuration in VC++ + project. + + * Modified sort order in the test browser of VC++ TestRunner so + that tests are in the same order as in the suite. Suites are still + sorted alphabetically. + + * Merged Steve M. Robbins patch to replace assertImplementation + with assert in hierarchy example. + + * Added a TextTestRunner to runner tests. It is based on Michael + Feather's version, but have been rewriten. + + * Removed traces that printed the test name in TextTestResult + while running. + + * Added the test name to error and failure report in + TextTestResult. + + * Updated hierarchy example to use TextTestRunner. + +2001-05-18 Baptiste Lepilleur + + * Symbol CU_USE_TYPEINFO must be defined instead of USE_TYPEINFO + to compile RTTI. + + * Added back default constructor to TestSuiteBuilder which use + RTTI. It is available only if CU_USE_TYPEINFO is defined. + + * Moved TypeInfoHelper.h from src/cppunit to + include/cppunit/extensions. + + * Macro CU_TEST_SUITE in HelperMacros.h now use TestSuiteBuilder + default constructor if CU_USE_TYPEINFO is defined, otherwise it + use the type name given to the CU_TEST_SUITE macro. + + * TestFactoryRegistry::registerFactory(factory) now generate a + dummy name based on a serial number instead of using RTTI. The + macro CU_TEST_SUITE_REGISTRATION and class AutoRegisterSuite can + now when CU_USE_TYPEINFO is not defined. + + * Added a new Configuration named "Debug Without CU_USE_TYPEINFO" + to msvc6 projects. The flag CU_USE_TYPEINFO is not defined in that + configuration. + +2001-05-17 Steve M. Robbins + + * Makefile.am (dist-hook): Copy files relative to $(top_srcdir). + + * doc/Makefile.am: Generated doc files depend on Doxyfile. + + * doc/Doxyfile.in: Use autoconf substitutions in file names. + + * examples/hierarchy/Makefile.am (check_PROGRAMS): Build hierarchy + with "make check", not "make all". + + * examples/hierarchy/Makefile.am (INCLUDES): + + * src/cppunit/Makefile.am (INCLUDES): Search in + $(top_srcdir)/include. + + * Added .cvsignore files. + +2001-05-16 Bastiaan Bakker + + * Merged Debian packaging support files by Christian Leutloff from + debian package version 1.5.4-2. Added make target 'debian' for + debian package creation. + +2001-05-09 Bastiaan Bakker + + * Release as 1.5.5. + + * Finished CppUnitW 1.2 merge. Removed RTTI depency from + TestSuite. Added TestCaller constructor for calling methods in + existing TestCases. + +2001-04-29 Bastiaan Bakker + + * Merged Baptiste Lepilleurs CppUnitW 1.2. Some differences: + TypeInfo stuff (in TestSuite) compiled in only if USE_TYPEINFO is + set. TestSuite.getTests now returns a const ref instead of taking + a ref as parameter. Removed auto_ptr stuff from + TestFactoryRegistry: auto_ptr cannot be used in containers. + +2001-04-28 Bastiaan Bakker + + * Merged MSVC++ specific TestRunner and example adapted from + Micheal Feathers version by Baptiste Lepilleur. + + * Moved cppunit subdir into src. + +2001-04-24 Bastiaan Bakker + + * Merged Baptiste Lepilleurs patch for TestRegistry: now TestCases + do not automatically register with the Registry anymore. + + * Added extension headers from Micheal Feathers port to + include/cppunit/extensions. + +2001-04-19 Bastiaan Bakker + + * Added MSVC++ workspace and project files, submitted by Baptiste + Lepilleur. + +2001-04-15 Bastiaan Bakker + + * Moved public headers from cppunit into new subdir + include/cppunit. This should make more clear which headers are + used internally only (like estring.h). + + * Moved autoconf auxiliary stuff into new subdir config, to make + the top dir less crowded. + + * Prefixed std:: to cerr, cout and endl. + +2001-04-14 Bastiaan Bakker + + * Release as 1.5.4 + + * Added support for RPM generation. + + * Added autoconf support for Doxygen document generation: Doxygen + and GraphViz dot are automatically detected and LaTeX and HTML can + be switch on or off. + + * cppunit/TextTestResult.cpp: changed cout to stream. Fixes bug + #232636 + + * cppunit/TextTestReulst.cpp: add '#include '. Fixes + bug #223290 + + * cppunit/*.cpp: removed bogus 'inline' specifiers. Fixes bug + #224542 and #223291. + + * doc/header.html: corrected link to CppUnit project page Fixes + bug #414073 + + * cppunit/*.cpp, examples/hierarchy/main.cpp: removed all 'using + namespace ...' occurences. + +2001-01-31 Tim Jansen + + * cppunit/TestCase.cpp, cppunit/TestCase.h, cppunit/TestSuite.h, + cppunit/TestSuite.cpp: applied patch #402271 by bwithrow. Fixes + bug #220207 + + * cppunit/TestSuite.cpp (deleteContents): clear vector after + contents have been deleted (so there are no invalid pointers in + the vector) Patch #403540 / #403542 + + * cppunit/TestCaller.h: create Fixture with empty constructor so + that only the TestCaller but not the Fixture instance is + registered in the TestRegistry Patch #403541 / #403542 + + * examples/hierarchy/BoardGameTest.h, + examples/hierarchy/ChessTest.h, examples/hierarchy/main.cpp: + initialize example TestCases with TestSuite so that the + TestCallers are registered in the TestRegistry Patch + #403542. Fixes bug #415249 + + * cppunit/TestCaller.h, cppunit/TestCase.cpp, cppunit/TestCase.h: + changed documentation; made hopefully clearer which constructor + registers the instance in the TestRegistry; corrected syntax in + code example Patch #403542. diff --git a/UnitTests/cppunit/CodingGuideLines.txt b/UnitTests/cppunit/CodingGuideLines.txt new file mode 100644 index 0000000..5651ee8 --- /dev/null +++ b/UnitTests/cppunit/CodingGuideLines.txt @@ -0,0 +1,61 @@ +CppUnit's coding guidelines for portability: +-------------------------------------------- + +- don't explicitly declare CppUnit namespace, instead use macro + CPPUNIT_NS_BEGIN and CPPUNIT_NS_END. + +- don't explicitly use 'CppUnit' to refer to class in CppUnit namespace, + instead use macro CPPUNIT_NS which expands to either 'CppUnit' or + nothing depending on the configuration. + +- don't use the 'using directive', always use full qualification. For STL, + always use std::. + +- don't use C++ style cast directly, instead use CppUnit's cast macro + (CPPUNIT_CONST_CAST). + +- don't use the mutable keyword, instead do a const cast. + +- don't use the typename keyword in template declaration, instead use 'class'. + +- don't make use of RTTI (typeid) or dynamic_cast mandatory. + +- don't use STL container directly, instead use CppUnit's wrapper located + in include/cppunit/portability. This help support compilers that don't + support default template parameter and require an allocator to be + specified. + +- don't use default template parameters. If needed, use STLPort wrapper + technic (see include/cppunit/portability/). + +- don't use templatized member functions (template method declared inside a + class), instead declares them as simple template functions (even + mainstream compiler such as VC++ 6 as trouble with them). + +- don't use default parameter value in template function. Not supported + by all compiler (on OS/390 for instance). + +- don't use STL container at() method, instead use the array accessor []. + at() is not supported on some gcc versions. + +- dereferencing containers must be done by (*ref_ptr).data instead of + ref_ptr->data. + +In brief, it should be possible to compile CppUnit on a C++ compiler that do +not have the following features: +- C++ style cast +- mutable and typename keyword +- RTTI +- template default parameters +- templatized member functions (that is a template function declared within a + class). +- namespace + +As such, usage of those features should always be optional. + +Following those guidelines should allow to compile on most compilers, as long +as STL are available (in std namespace or not), with some form of strstream and +iostream, as well as exception support. + +-- +Baptiste Lepilleur diff --git a/UnitTests/cppunit/THANKS b/UnitTests/cppunit/THANKS new file mode 100644 index 0000000..89cfa9c --- /dev/null +++ b/UnitTests/cppunit/THANKS @@ -0,0 +1,23 @@ +Tim Jansen +Christian Leutloff +Steve M. Robbins +Patrick Berny +Patrick Hartling +Peer Sommerlund +Duane Murphy +Gigi Sayfan +Armin "bored" Michel +Jeffrey Morgan +'cuppa' project team (http://sourceforge.jp/projects/cuppa/) +Phil Verghese +Lavoie Philippe +Pavel Zabelin +Marco Welti +Thomas Neidhart +Hans Bühler (Dynamic Window library used by MFC UI) +John Sisson +Steven Mitter +Stephan Stapel +Abdessattar Sassi (hp-ux plug-in support) +Max Quatember and Andreas Pfaffenbichler (VC++ 7 MFC TestRunner go to source line) +Vincent Rivière diff --git a/UnitTests/cppunit/TODO b/UnitTests/cppunit/TODO new file mode 100644 index 0000000..19fa324 --- /dev/null +++ b/UnitTests/cppunit/TODO @@ -0,0 +1,35 @@ +* Bugs: +Asserter::makeNotEqualMessage() strip the shortDescription of the additional message. + +* CppUnit: + - STL concept checker. + - Memory leak tracking: setUp/tearDown should be leak safe if no failure occured. + +* UnitTest + - add tests for XmlOutputter::setStyleSheet (current assertion macro strip when + testing ) + +* VC++ TestRunner: + - Modify MfcUi::TestRunner to expose TestResult (which allow specific TestListener + for global initialization). + - Update MfcTestRunner to use TestPath to store test in the registry + +* Documentation: + CookBook: + - how to create simple test cases (with CppUnit namespace) + - test case using only CPPUINT_ASSERT + - test case using CPPUNIT_ASSERT_EQUAL + - advanced assertions with the CPPUNIT_ASSERT_MESSAGE + - Helper Macros for convenience + - Creating a suite + - Composing a suite from more suites (i.e. compose tests for n modules to + form a big test for the whole program) + - customizing output using an user defined TestListener + - how to write the TestListener (subclass of TestListener) + - how to hook it in + - how to use the GUI + - MSVC++ special stuff + - other custmization stuff I haven't understood yet + + CppUnit: architecture overview. + diff --git a/UnitTests/cppunit/include/cppunit/AdditionalMessage.h b/UnitTests/cppunit/include/cppunit/AdditionalMessage.h new file mode 100644 index 0000000..917d754 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/AdditionalMessage.h @@ -0,0 +1,76 @@ +#ifndef CPPUNIT_ADDITIONALMESSAGE_H +#define CPPUNIT_ADDITIONALMESSAGE_H + +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief An additional Message for assertions. + * \ingroup CreatingNewAssertions + * + * Provides a implicit constructor that takes a single string. This allow this + * class to be used as the message arguments in macros. + * + * The constructed object is either a Message with a single detail string if + * a string was passed to the macro, or a copy of the Message passed to the macro. + * + * Here is an example of usage: + * \code + * + * void checkStringEquals( const std::string &expected, + * const std::string &actual, + * const CppUnit::SourceLine &sourceLine, + * const CppUnit::AdditionalMessage &message ); + * + * #define XTLUT_ASSERT_STRING_EQUAL_MESSAGE( expected, actual, message ) \ + * ::XtlUt::Impl::checkStringEquals( ::Xtl::toString(expected), \ + * ::Xtl::toString(actual), \ + * CPPUNIT_SOURCELINE(), \ + * message ) + * \endcode + * + * In the previous example, the user can specify a simple string for \a message, + * or a complex Message object. + * + * \see Message + */ +class CPPUNIT_API AdditionalMessage : public Message +{ +public: + typedef Message SuperClass; + + /// Constructs an empty Message. + AdditionalMessage(); + + /*! \brief Constructs a Message with the specified detail string. + * \param detail1 Detail string of the message. If empty, then it is not added. + */ + AdditionalMessage( const std::string &detail1 ); + + /*! \brief Constructs a Message with the specified detail string. + * \param detail1 Detail string of the message. If empty, then it is not added. + */ + AdditionalMessage( const char *detail1 ); + + /*! \brief Constructs a copy of the specified message. + * \param other Message to copy. + */ + AdditionalMessage( const Message &other ); + + /*! \brief Assignment operator. + * \param other Message to copy. + * \return Reference on this object. + */ + AdditionalMessage &operator =( const Message &other ); + +private: +}; + + +CPPUNIT_NS_END + + + +#endif // CPPUNIT_ADDITIONALMESSAGE_H diff --git a/UnitTests/cppunit/include/cppunit/Asserter.h b/UnitTests/cppunit/include/cppunit/Asserter.h new file mode 100644 index 0000000..94dadaa --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/Asserter.h @@ -0,0 +1,143 @@ +#ifndef CPPUNIT_ASSERTER_H +#define CPPUNIT_ASSERTER_H + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +class Message; + + +/*! \brief A set of functions to help writing assertion macros. + * \ingroup CreatingNewAssertions + * + * Here is an example of assertion, a simplified version of the + * actual assertion implemented in examples/cppunittest/XmlUniformiser.h: + * \code + * #include + * #include + * + * void + * checkXmlEqual( std::string expectedXml, + * std::string actualXml, + * CppUnit::SourceLine sourceLine ) + * { + * std::string expected = XmlUniformiser( expectedXml ).stripped(); + * std::string actual = XmlUniformiser( actualXml ).stripped(); + * + * if ( expected == actual ) + * return; + * + * ::CppUnit::Asserter::failNotEqual( expected, + * actual, + * sourceLine ); + * } + * + * /// Asserts that two XML strings are equivalent. + * #define CPPUNITTEST_ASSERT_XML_EQUAL( expected, actual ) \ + * checkXmlEqual( expected, actual, \ + * CPPUNIT_SOURCELINE() ) + * \endcode + */ +struct Asserter +{ + /*! \brief Throws a Exception with the specified message and location. + */ + static void CPPUNIT_API fail( const Message &message, + const SourceLine &sourceLine = SourceLine() ); + + /*! \brief Throws a Exception with the specified message and location. + * \deprecated Use fail( Message, SourceLine ) instead. + */ + static void CPPUNIT_API fail( std::string message, + const SourceLine &sourceLine = SourceLine() ); + + /*! \brief Throws a Exception with the specified message and location. + * \param shouldFail if \c true then the exception is thrown. Otherwise + * nothing happen. + * \param message Message explaining the assertion failiure. + * \param sourceLine Location of the assertion. + */ + static void CPPUNIT_API failIf( bool shouldFail, + const Message &message, + const SourceLine &sourceLine = SourceLine() ); + + /*! \brief Throws a Exception with the specified message and location. + * \deprecated Use failIf( bool, Message, SourceLine ) instead. + * \param shouldFail if \c true then the exception is thrown. Otherwise + * nothing happen. + * \param message Message explaining the assertion failiure. + * \param sourceLine Location of the assertion. + */ + static void CPPUNIT_API failIf( bool shouldFail, + std::string message, + const SourceLine &sourceLine = SourceLine() ); + + /*! \brief Returns a expected value string for a message. + * Typically used to create 'not equal' message, or to check that a message + * contains the expected content when writing unit tests for your custom + * assertions. + * + * \param expectedValue String that represents the expected value. + * \return \a expectedValue prefixed with "Expected: ". + * \see makeActual(). + */ + static std::string CPPUNIT_API makeExpected( const std::string &expectedValue ); + + /*! \brief Returns an actual value string for a message. + * Typically used to create 'not equal' message, or to check that a message + * contains the expected content when writing unit tests for your custom + * assertions. + * + * \param actualValue String that represents the actual value. + * \return \a actualValue prefixed with "Actual : ". + * \see makeExpected(). + */ + static std::string CPPUNIT_API makeActual( const std::string &actualValue ); + + static Message CPPUNIT_API makeNotEqualMessage( const std::string &expectedValue, + const std::string &actualValue, + const AdditionalMessage &additionalMessage = AdditionalMessage(), + const std::string &shortDescription = "equality assertion failed"); + + /*! \brief Throws an Exception with the specified message and location. + * \param expected Text describing the expected value. + * \param actual Text describing the actual value. + * \param sourceLine Location of the assertion. + * \param additionalMessage Additional message. Usually used to report + * what are the differences between the expected and actual value. + * \param shortDescription Short description for the failure message. + */ + static void CPPUNIT_API failNotEqual( std::string expected, + std::string actual, + const SourceLine &sourceLine, + const AdditionalMessage &additionalMessage = AdditionalMessage(), + std::string shortDescription = "equality assertion failed" ); + + /*! \brief Throws an Exception with the specified message and location. + * \param shouldFail if \c true then the exception is thrown. Otherwise + * nothing happen. + * \param expected Text describing the expected value. + * \param actual Text describing the actual value. + * \param sourceLine Location of the assertion. + * \param additionalMessage Additional message. Usually used to report + * where the "difference" is located. + * \param shortDescription Short description for the failure message. + */ + static void CPPUNIT_API failNotEqualIf( bool shouldFail, + std::string expected, + std::string actual, + const SourceLine &sourceLine, + const AdditionalMessage &additionalMessage = AdditionalMessage(), + std::string shortDescription = "equality assertion failed" ); + +}; + + +CPPUNIT_NS_END + + +#endif // CPPUNIT_ASSERTER_H diff --git a/UnitTests/cppunit/include/cppunit/BriefTestProgressListener.h b/UnitTests/cppunit/include/cppunit/BriefTestProgressListener.h new file mode 100644 index 0000000..137ca44 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/BriefTestProgressListener.h @@ -0,0 +1,43 @@ +#ifndef CPPUNIT_BRIEFTESTPROGRESSLISTENER_H +#define CPPUNIT_BRIEFTESTPROGRESSLISTENER_H + +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief TestListener that prints the name of each test before running it. + * \ingroup TrackingTestExecution + */ +class CPPUNIT_API BriefTestProgressListener : public TestListener +{ +public: + /*! Constructs a BriefTestProgressListener object. + */ + BriefTestProgressListener(); + + /// Destructor. + virtual ~BriefTestProgressListener(); + + void startTest( Test *test ); + + void addFailure( const TestFailure &failure ); + + void endTest( Test *test ); + +private: + /// Prevents the use of the copy constructor. + BriefTestProgressListener( const BriefTestProgressListener © ); + + /// Prevents the use of the copy operator. + void operator =( const BriefTestProgressListener © ); + +private: + bool m_lastTestFailed; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_BRIEFTESTPROGRESSLISTENER_H diff --git a/UnitTests/cppunit/include/cppunit/CompilerOutputter.h b/UnitTests/cppunit/include/cppunit/CompilerOutputter.h new file mode 100644 index 0000000..885fe65 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/CompilerOutputter.h @@ -0,0 +1,146 @@ +#ifndef CPPUNIT_COMPILERTESTRESULTOUTPUTTER_H +#define CPPUNIT_COMPILERTESTRESULTOUTPUTTER_H + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +class Exception; +class SourceLine; +class Test; +class TestFailure; +class TestResultCollector; + +/*! + * \brief Outputs a TestResultCollector in a compiler compatible format. + * \ingroup WritingTestResult + * + * Printing the test results in a compiler compatible format (assertion + * location has the same format as compiler error), allow you to use your + * IDE to jump to the assertion failure. Location format can be customized (see + * setLocationFormat() ). + * + * For example, when running the test in a post-build with VC++, if an assertion + * fails, you can jump to the assertion by pressing F4 (jump to next error). + * + * Heres is an example of usage (from examples/cppunittest/CppUnitTestMain.cpp): + * \code + * int main( int argc, char* argv[] ) { + * // if command line contains "-selftest" then this is the post build check + * // => the output must be in the compiler error format. + * bool selfTest = (argc > 1) && + * (std::string("-selftest") == argv[1]); + * + * CppUnit::TextUi::TestRunner runner; + * runner.addTest( CppUnitTest::suite() ); // Add the top suite to the test runner + * + * if ( selfTest ) + * { // Change the default outputter to a compiler error format outputter + * // The test runner owns the new outputter. + * runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), + * std::cerr ) ); + * } + * + * // Run the test and don't wait a key if post build check. + * bool wasSuccessful = runner.run( "", !selfTest ); + * + * // Return error code 1 if the one of test failed. + * return wasSuccessful ? 0 : 1; + * } + * \endcode + */ +class CPPUNIT_API CompilerOutputter : public Outputter +{ +public: + /*! \brief Constructs a CompilerOutputter object. + * \param result Result of the test run. + * \param stream Stream used to output test result. + * \param locationFormat Error location format used by your compiler. Default + * to \c CPPUNIT_COMPILER_LOCATION_FORMAT which is defined + * in the configuration file. See setLocationFormat() for detail. + * \see setLocationFormat(). + */ + CompilerOutputter( TestResultCollector *result, + OStream &stream, + const std::string &locationFormat = CPPUNIT_COMPILER_LOCATION_FORMAT ); + + /// Destructor. + virtual ~CompilerOutputter(); + + /*! \brief Sets the error location format. + * + * Indicates the format used to report location of failed assertion. This format should + * match the one used by your compiler. + * + * The location format is a string in which the occurence of the following character + * sequence are replaced: + * + * - "%l" => replaced by the line number + * - "%p" => replaced by the full path name of the file ("G:\prg\vc\cppunit\MyTest.cpp") + * - "%f" => replaced by the base name of the file ("MyTest.cpp") + * + * Some examples: + * + * - VC++ error location format: "%p(%l):" => produce "G:\prg\MyTest.cpp(43):" + * - GCC error location format: "%f:%l:" => produce "MyTest.cpp:43:" + * + * Thoses are the two compilers currently supported (gcc format is used if + * VC++ is not detected). If you want your compiler to be automatically supported by + * CppUnit, send a mail to the mailing list (preferred), or submit a feature request + * that indicates how to detect your compiler with the preprocessor (\#ifdef...) and + * your compiler location format. + */ + void setLocationFormat( const std::string &locationFormat ); + + /*! \brief Creates an instance of an outputter that matches your current compiler. + * \deprecated This class is specialized through parameterization instead of subclassing... + * Use CompilerOutputter::CompilerOutputter instead. + */ + static CompilerOutputter *defaultOutputter( TestResultCollector *result, + OStream &stream ); + + void write(); + + void setNoWrap(); + + void setWrapColumn( int wrapColumn ); + + int wrapColumn() const; + + virtual void printSuccess(); + virtual void printFailureReport(); + virtual void printFailuresList(); + virtual void printStatistics(); + virtual void printFailureDetail( TestFailure *failure ); + virtual void printFailureLocation( SourceLine sourceLine ); + virtual void printFailureType( TestFailure *failure ); + virtual void printFailedTestName( TestFailure *failure ); + virtual void printFailureMessage( TestFailure *failure ); + +private: + /// Prevents the use of the copy constructor. + CompilerOutputter( const CompilerOutputter © ); + + /// Prevents the use of the copy operator. + void operator =( const CompilerOutputter © ); + + virtual bool processLocationFormatCommand( char command, + const SourceLine &sourceLine ); + + virtual std::string extractBaseName( const std::string &fileName ) const; + +private: + TestResultCollector *m_result; + OStream &m_stream; + std::string m_locationFormat; + int m_wrapColumn; +}; + + +CPPUNIT_NS_END + + +#endif // CPPUNIT_COMPILERTESTRESULTOUTPUTTER_H diff --git a/UnitTests/cppunit/include/cppunit/Exception.h b/UnitTests/cppunit/include/cppunit/Exception.h new file mode 100644 index 0000000..bf5fcac --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/Exception.h @@ -0,0 +1,90 @@ +#ifndef CPPUNIT_EXCEPTION_H +#define CPPUNIT_EXCEPTION_H + +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief Exceptions thrown by failed assertions. + * \ingroup BrowsingCollectedTestResult + * + * Exception is an exception that serves + * descriptive strings through its what() method + */ +class CPPUNIT_API Exception : public std::exception +{ +public: + /*! \brief Constructs the exception with the specified message and source location. + * \param message Message associated to the exception. + * \param sourceLine Source location related to the exception. + */ + Exception( const Message &message = Message(), + const SourceLine &sourceLine = SourceLine() ); + +#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED + /*! + * \deprecated Use other constructor instead. + */ + Exception( std::string message, + long lineNumber, + std::string fileName ); +#endif + + /*! \brief Constructs a copy of an exception. + * \param other Exception to copy. + */ + Exception( const Exception &other ); + + /// Destructs the exception + virtual ~Exception() throw(); + + /// Performs an assignment + Exception &operator =( const Exception &other ); + + /// Returns descriptive message + const char *what() const throw(); + + /// Location where the error occured + SourceLine sourceLine() const; + + /// Message related to the exception. + Message message() const; + + /// Set the message. + void setMessage( const Message &message ); + +#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED + /// The line on which the error occurred + long lineNumber() const; + + /// The file in which the error occurred + std::string fileName() const; + + static const std::string UNKNOWNFILENAME; + static const long UNKNOWNLINENUMBER; +#endif + + /// Clones the exception. + virtual Exception *clone() const; + +protected: + // VC++ does not recognize call to parent class when prefixed + // with a namespace. This is a workaround. + typedef std::exception SuperClass; + + Message m_message; + SourceLine m_sourceLine; + std::string m_whatMessage; +}; + + +CPPUNIT_NS_END + + +#endif // CPPUNIT_EXCEPTION_H + diff --git a/UnitTests/cppunit/include/cppunit/Message.h b/UnitTests/cppunit/include/cppunit/Message.h new file mode 100644 index 0000000..1ae51cc --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/Message.h @@ -0,0 +1,156 @@ +#ifndef CPPUNIT_MESSAGE_H +#define CPPUNIT_MESSAGE_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include + + +CPPUNIT_NS_BEGIN + + +#if CPPUNIT_NEED_DLL_DECL +// template class CPPUNIT_API std::deque; +#endif + +/*! \brief Message associated to an Exception. + * \ingroup CreatingNewAssertions + * A message is composed of two items: + * - a short description (~20/30 characters) + * - a list of detail strings + * + * The short description is used to indicate how the detail strings should be + * interpreted. It usually indicates the failure types, such as + * "assertion failed", "forced failure", "unexpected exception caught", + * "equality assertion failed"... It should not contains new line character (\n). + * + * Detail strings are used to provide more information about the failure. It + * can contains the asserted expression, the expected and actual values in an + * equality assertion, some addional messages... Detail strings can contains + * new line characters (\n). + */ +class CPPUNIT_API Message +{ +public: + Message(); + + // Ensure thread-safe copy by detaching the string. + Message( const Message &other ); + + explicit Message( const std::string &shortDescription ); + + Message( const std::string &shortDescription, + const std::string &detail1 ); + + Message( const std::string &shortDescription, + const std::string &detail1, + const std::string &detail2 ); + + Message( const std::string &shortDescription, + const std::string &detail1, + const std::string &detail2, + const std::string &detail3 ); + + Message &operator =( const Message &other ); + + /*! \brief Returns the short description. + * \return Short description. + */ + const std::string &shortDescription() const; + + /*! \brief Returns the number of detail string. + * \return Number of detail string. + */ + int detailCount() const; + + /*! \brief Returns the detail at the specified index. + * \param index Zero based index of the detail string to return. + * \returns Detail string at the specified index. + * \exception std::invalid_argument if \a index < 0 or index >= detailCount(). + */ + std::string detailAt( int index ) const; + + /*! \brief Returns a string that represents a list of the detail strings. + * + * Example: + * \code + * Message message( "not equal", "Expected: 3", "Actual: 7" ); + * std::string details = message.details(); + * // details contains: + * // "- Expected: 3\n- Actual: 7\n" \endcode + * + * \return A string that is a concatenation of all the detail strings. Each detail + * string is prefixed with '- ' and suffixed with '\n' before being + * concatenated to the other. + */ + std::string details() const; + + /*! \brief Removes all detail strings. + */ + void clearDetails(); + + /*! \brief Adds a single detail string. + * \param detail Detail string to add. + */ + void addDetail( const std::string &detail ); + + /*! \brief Adds two detail strings. + * \param detail1 Detail string to add. + * \param detail2 Detail string to add. + */ + void addDetail( const std::string &detail1, + const std::string &detail2 ); + + /*! \brief Adds three detail strings. + * \param detail1 Detail string to add. + * \param detail2 Detail string to add. + * \param detail3 Detail string to add. + */ + void addDetail( const std::string &detail1, + const std::string &detail2, + const std::string &detail3 ); + + /*! \brief Adds the detail strings of the specified message. + * \param message All the detail strings of this message are added to this one. + */ + void addDetail( const Message &message ); + + /*! \brief Sets the short description. + * \param shortDescription New short description. + */ + void setShortDescription( const std::string &shortDescription ); + + /*! \brief Tests if a message is identical to another one. + * \param other Message this message is compared to. + * \return \c true if the two message are identical, \c false otherwise. + */ + bool operator ==( const Message &other ) const; + + /*! \brief Tests if a message is different from another one. + * \param other Message this message is compared to. + * \return \c true if the two message are not identical, \c false otherwise. + */ + bool operator !=( const Message &other ) const; + +private: + std::string m_shortDescription; + + typedef CppUnitDeque Details; + Details m_details; +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + + +#endif // CPPUNIT_MESSAGE_H diff --git a/UnitTests/cppunit/include/cppunit/Outputter.h b/UnitTests/cppunit/include/cppunit/Outputter.h new file mode 100644 index 0000000..f31d681 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/Outputter.h @@ -0,0 +1,26 @@ +#ifndef CPPUNIT_OUTPUTTER_H +#define CPPUNIT_OUTPUTTER_H + +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief Abstract outputter to print test result summary. + * \ingroup WritingTestResult + */ +class CPPUNIT_API Outputter +{ +public: + /// Destructor. + virtual ~Outputter() {} + + virtual void write() =0; +}; + + +CPPUNIT_NS_END + + +#endif // CPPUNIT_OUTPUTTER_H diff --git a/UnitTests/cppunit/include/cppunit/Portability.h b/UnitTests/cppunit/include/cppunit/Portability.h new file mode 100644 index 0000000..591eb86 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/Portability.h @@ -0,0 +1,183 @@ +#ifndef CPPUNIT_PORTABILITY_H +#define CPPUNIT_PORTABILITY_H + +#if defined(_WIN32) && !defined(WIN32) +# define WIN32 1 +#endif + +/* include platform specific config */ +#if defined(__BORLANDC__) +# include +#elif defined (_MSC_VER) +# if _MSC_VER == 1200 && defined(_WIN32_WCE) //evc4 +# include +# else +# include +# endif +#else +# include +#endif + +// Version number of package +#ifndef CPPUNIT_VERSION +#define CPPUNIT_VERSION "1.12.0" +#endif + +#include // define CPPUNIT_API & CPPUNIT_NEED_DLL_DECL +#include + + +/* Options that the library user may switch on or off. + * If the user has not done so, we chose default values. + */ + + +/* Define to 1 if you wish to have the old-style macros + assert(), assertEqual(), assertDoublesEqual(), and assertLongsEqual() */ +#if !defined(CPPUNIT_ENABLE_NAKED_ASSERT) +# define CPPUNIT_ENABLE_NAKED_ASSERT 0 +#endif + +/* Define to 1 if you wish to have the old-style CU_TEST family + of macros. */ +#if !defined(CPPUNIT_ENABLE_CU_TEST_MACROS) +# define CPPUNIT_ENABLE_CU_TEST_MACROS 0 +#endif + +/* Define to 1 if the preprocessor expands (#foo) to "foo" (quotes incl.) + I don't think there is any C preprocess that does NOT support this! */ +#if !defined(CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION) +# define CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION 1 +#endif + +/* Assumes that STL and CppUnit are in global space if the compiler does not + support namespace. */ +#if !defined(CPPUNIT_HAVE_NAMESPACES) +# if !defined(CPPUNIT_NO_NAMESPACE) +# define CPPUNIT_NO_NAMESPACE 1 +# endif // !defined(CPPUNIT_NO_NAMESPACE) +# if !defined(CPPUNIT_NO_STD_NAMESPACE) +# define CPPUNIT_NO_STD_NAMESPACE 1 +# endif // !defined(CPPUNIT_NO_STD_NAMESPACE) +#endif // !defined(CPPUNIT_HAVE_NAMESPACES) + +/* Define CPPUNIT_STD_NEED_ALLOCATOR to 1 if you need to specify + * the allocator you used when instantiating STL container. Typically + * used for compilers that do not support template default parameter. + * CPPUNIT_STD_ALLOCATOR will be used as the allocator. Default is + * std::allocator. On some compilers, you may need to change this to + * std::allocator. + */ +#if CPPUNIT_STD_NEED_ALLOCATOR +# if !defined(CPPUNIT_STD_ALLOCATOR) +# define CPPUNIT_STD_ALLOCATOR std::allocator +# endif // !defined(CPPUNIT_STD_ALLOCATOR) +#endif // defined(CPPUNIT_STD_NEED_ALLOCATOR) + + +// Compiler error location format for CompilerOutputter +// If not define, assumes that it's gcc +// See class CompilerOutputter for format. +#if !defined(CPPUNIT_COMPILER_LOCATION_FORMAT) +#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) ) +// gcc/Xcode integration on Mac OS X +# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p:%l: " +#else +# define CPPUNIT_COMPILER_LOCATION_FORMAT "%f:%l:" +#endif +#endif + +// If CPPUNIT_HAVE_CPP_CAST is defined, then c++ style cast will be used, +// otherwise, C style cast are used. +#if defined( CPPUNIT_HAVE_CPP_CAST ) +# define CPPUNIT_CONST_CAST( TargetType, pointer ) \ + const_cast( pointer ) + +# define CPPUNIT_STATIC_CAST( TargetType, pointer ) \ + static_cast( pointer ) +#else // defined( CPPUNIT_HAVE_CPP_CAST ) +# define CPPUNIT_CONST_CAST( TargetType, pointer ) \ + ((TargetType)( pointer )) +# define CPPUNIT_STATIC_CAST( TargetType, pointer ) \ + ((TargetType)( pointer )) +#endif // defined( CPPUNIT_HAVE_CPP_CAST ) + +// If CPPUNIT_NO_STD_NAMESPACE is defined then STL are in the global space. +// => Define macro 'std' to nothing +#if defined(CPPUNIT_NO_STD_NAMESPACE) +# undef std +# define std +#endif // defined(CPPUNIT_NO_STD_NAMESPACE) + +// If CPPUNIT_NO_NAMESPACE is defined, then put CppUnit classes in the +// global namespace: the compiler does not support namespace. +#if defined(CPPUNIT_NO_NAMESPACE) +# define CPPUNIT_NS_BEGIN +# define CPPUNIT_NS_END +# define CPPUNIT_NS +#else // defined(CPPUNIT_NO_NAMESPACE) +# define CPPUNIT_NS_BEGIN namespace CppUnit { +# define CPPUNIT_NS_END } +# define CPPUNIT_NS CppUnit +#endif // defined(CPPUNIT_NO_NAMESPACE) + +/*! Stringize a symbol. + * + * Use this macro to convert a preprocessor symbol to a string. + * + * Example of usage: + * \code + * #define CPPUNIT_PLUGIN_EXPORTED_NAME cppunitTestPlugIn + * const char *name = CPPUNIT_STRINGIZE( CPPUNIT_PLUGIN_EXPORTED_NAME ); + * \endcode + */ +#define CPPUNIT_STRINGIZE( symbol ) _CPPUNIT_DO_STRINGIZE( symbol ) + +/// \internal +#define _CPPUNIT_DO_STRINGIZE( symbol ) #symbol + +/*! Joins to symbol after expanding them into string. + * + * Use this macro to join two symbols. Example of usage: + * + * \code + * #define MAKE_UNIQUE_NAME(prefix) CPPUNIT_JOIN( prefix, __LINE__ ) + * \endcode + * + * The macro defined in the example concatenate a given prefix with the line number + * to obtain a 'unique' identifier. + * + * \internal From boost documentation: + * The following piece of macro magic joins the two + * arguments together, even when one of the arguments is + * itself a macro (see 16.3.1 in C++ standard). The key + * is that macro expansion of macro arguments does not + * occur in CPPUNIT_JOIN2 but does in CPPUNIT_JOIN. + */ +#define CPPUNIT_JOIN( symbol1, symbol2 ) _CPPUNIT_DO_JOIN( symbol1, symbol2 ) + +/// \internal +#define _CPPUNIT_DO_JOIN( symbol1, symbol2 ) _CPPUNIT_DO_JOIN2( symbol1, symbol2 ) + +/// \internal +#define _CPPUNIT_DO_JOIN2( symbol1, symbol2 ) symbol1##symbol2 + +/// \internal Unique suffix for variable name. Can be overridden in platform specific +/// config-*.h. Default to line number. +#ifndef CPPUNIT_UNIQUE_COUNTER +# define CPPUNIT_UNIQUE_COUNTER __LINE__ +#endif + +/*! Adds the line number to the specified string to create a unique identifier. + * \param prefix Prefix added to the line number to create a unique identifier. + * \see CPPUNIT_TEST_SUITE_REGISTRATION for an example of usage. + */ +#define CPPUNIT_MAKE_UNIQUE_NAME( prefix ) CPPUNIT_JOIN( prefix, CPPUNIT_UNIQUE_COUNTER ) + +/*! Defines wrap colunm for %CppUnit. Used by CompilerOuputter. + */ +#if !defined(CPPUNIT_WRAP_COLUMN) +# define CPPUNIT_WRAP_COLUMN 79 +#endif + +#endif // CPPUNIT_PORTABILITY_H diff --git a/UnitTests/cppunit/include/cppunit/Protector.h b/UnitTests/cppunit/include/cppunit/Protector.h new file mode 100644 index 0000000..d14e75f --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/Protector.h @@ -0,0 +1,94 @@ +#ifndef CPPUNIT_PROTECTOR_H +#define CPPUNIT_PROTECTOR_H + +#include + +CPPUNIT_NS_BEGIN + +class Exception; +class Message; +class ProtectorContext; +class TestResult; + + +class CPPUNIT_API Functor +{ +public: + virtual ~Functor(); + + virtual bool operator()() const =0; +}; + + +/*! \brief Protects one or more test case run. + * + * Protector are used to globably 'decorate' a test case. The most common + * usage of Protector is to catch exception that do not subclass std::exception, + * such as MFC CException class or Rogue Wave RWXMsg class, and capture the + * message associated to the exception. In fact, CppUnit capture message from + * Exception and std::exception using a Protector. + * + * Protector are chained. When you add a Protector using + * TestResult::pushProtector(), your protector is in fact passed as a Functor + * to the first protector of the chain. + * + * TestCase protects call to setUp(), runTest() and tearDown() by calling + * TestResult::protect(). + * + * Because the protector chain is handled by TestResult, a protector can be + * active for a single test, or a complete test run. + * + * Here are some possible usages: + * - run all test case in a separate thread and assumes the test failed if it + * did not finish in a given time (infinite loop work around) + * - performance tracing : time only the runTest() time. + * \sa TestResult, TestCase, TestListener. + */ +class CPPUNIT_API Protector +{ +public: + virtual ~Protector(); + + virtual bool protect( const Functor &functor, + const ProtectorContext &context ) =0; + +protected: + void reportError( const ProtectorContext &context, + const Exception &error ) const; + + void reportError( const ProtectorContext &context, + const Message &message, + const SourceLine &sourceLine = SourceLine() ) const; + + void reportFailure( const ProtectorContext &context, + const Exception &failure ) const; + + Message actualMessage( const Message &message, + const ProtectorContext &context ) const; +}; + + +/*! \brief Scoped protector push to TestResult. + * + * Adds the specified Protector to the specified TestResult for the object + * life-time. + */ +class CPPUNIT_API ProtectorGuard +{ +public: + /// Pushes the specified protector. + ProtectorGuard( TestResult *result, + Protector *protector ); + + /// Pops the protector. + ~ProtectorGuard(); + +private: + TestResult *m_result; +}; + +CPPUNIT_NS_END + + +#endif // CPPUNIT_PROTECTOR_H + diff --git a/UnitTests/cppunit/include/cppunit/SourceLine.h b/UnitTests/cppunit/include/cppunit/SourceLine.h new file mode 100644 index 0000000..f7a85df --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/SourceLine.h @@ -0,0 +1,63 @@ +#ifndef CPPUNIT_SOURCELINE_H +#define CPPUNIT_SOURCELINE_H + +#include +#include + +/*! \brief Constructs a SourceLine object initialized with the location where the macro is expanded. + * \ingroup CreatingNewAssertions + * \relates CppUnit::SourceLine + * Used to write your own assertion macros. + * \see Asserter for example of usage. + */ +#define CPPUNIT_SOURCELINE() CPPUNIT_NS::SourceLine( __FILE__, __LINE__ ) + + +CPPUNIT_NS_BEGIN + + +/*! \brief Represents a source line location. + * \ingroup CreatingNewAssertions + * \ingroup BrowsingCollectedTestResult + * + * Used to capture the failure location in assertion. + * + * Use the CPPUNIT_SOURCELINE() macro to construct that object. Typically used when + * writing an assertion macro in association with Asserter. + * + * \see Asserter. + */ +class CPPUNIT_API SourceLine +{ +public: + SourceLine(); + + // Ensure thread-safe copy by detaching the string buffer. + SourceLine( const SourceLine &other ); + + SourceLine( const std::string &fileName, + int lineNumber ); + + SourceLine &operator =( const SourceLine &other ); + + /// Destructor. + virtual ~SourceLine(); + + bool isValid() const; + + int lineNumber() const; + + std::string fileName() const; + + bool operator ==( const SourceLine &other ) const; + bool operator !=( const SourceLine &other ) const; + +private: + std::string m_fileName; + int m_lineNumber; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_SOURCELINE_H diff --git a/UnitTests/cppunit/include/cppunit/SynchronizedObject.h b/UnitTests/cppunit/include/cppunit/SynchronizedObject.h new file mode 100644 index 0000000..0f7d094 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/SynchronizedObject.h @@ -0,0 +1,80 @@ +#ifndef CPPUNIT_SYNCHRONIZEDOBJECT_H +#define CPPUNIT_SYNCHRONIZEDOBJECT_H + +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief Base class for synchronized object. + * + * Synchronized object are object which members are used concurrently by mutiple + * threads. + * + * This class define the class SynchronizationObject which must be subclassed + * to implement an actual lock. + * + * Each instance of this class holds a pointer on a lock object. + * + * See src/msvc6/MfcSynchronizedObject.h for an example. + */ +class CPPUNIT_API SynchronizedObject +{ +public: + /*! \brief Abstract synchronization object (mutex) + */ + class SynchronizationObject + { + public: + SynchronizationObject() {} + virtual ~SynchronizationObject() {} + + virtual void lock() {} + virtual void unlock() {} + }; + + /*! Constructs a SynchronizedObject object. + */ + SynchronizedObject( SynchronizationObject *syncObject =0 ); + + /// Destructor. + virtual ~SynchronizedObject(); + +protected: + /*! \brief Locks a synchronization object in the current scope. + */ + class ExclusiveZone + { + SynchronizationObject *m_syncObject; + + public: + ExclusiveZone( SynchronizationObject *syncObject ) + : m_syncObject( syncObject ) + { + m_syncObject->lock(); + } + + ~ExclusiveZone() + { + m_syncObject->unlock (); + } + }; + + virtual void setSynchronizationObject( SynchronizationObject *syncObject ); + +protected: + SynchronizationObject *m_syncObject; + +private: + /// Prevents the use of the copy constructor. + SynchronizedObject( const SynchronizedObject © ); + + /// Prevents the use of the copy operator. + void operator =( const SynchronizedObject © ); +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_SYNCHRONIZEDOBJECT_H diff --git a/UnitTests/cppunit/include/cppunit/Test.h b/UnitTests/cppunit/include/cppunit/Test.h new file mode 100644 index 0000000..a56be0f --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/Test.h @@ -0,0 +1,117 @@ +#ifndef CPPUNIT_TEST_H +#define CPPUNIT_TEST_H + +#include +#include + +CPPUNIT_NS_BEGIN + + +class TestResult; +class TestPath; + +/*! \brief Base class for all test objects. + * \ingroup BrowsingCollectedTestResult + * + * All test objects should be a subclass of Test. Some test objects, + * TestCase for example, represent one individual test. Other test + * objects, such as TestSuite, are comprised of several tests. + * + * When a Test is run, the result is collected by a TestResult object. + * + * \see TestCase + * \see TestSuite + */ +class CPPUNIT_API Test +{ +public: + virtual ~Test() {}; + + /*! \brief Run the test, collecting results. + */ + virtual void run( TestResult *result ) =0; + + /*! \brief Return the number of test cases invoked by run(). + * + * The base unit of testing is the class TestCase. This + * method returns the number of TestCase objects invoked by + * the run() method. + */ + virtual int countTestCases () const =0; + + /*! \brief Returns the number of direct child of the test. + */ + virtual int getChildTestCount() const =0; + + /*! \brief Returns the child test of the specified index. + * + * This method test if the index is valid, then call doGetChildTestAt() if + * the index is valid. Otherwise std::out_of_range exception is thrown. + * + * You should override doGetChildTestAt() method. + * + * \param index Zero based index of the child test to return. + * \return Pointer on the test. Never \c NULL. + * \exception std::out_of_range is \a index is < 0 or >= getChildTestCount(). + */ + virtual Test *getChildTestAt( int index ) const; + + /*! \brief Returns the test name. + * + * Each test has a name. This name may be used to find the + * test in a suite or registry of tests. + */ + virtual std::string getName () const =0; + + /*! \brief Finds the test with the specified name and its parents test. + * \param testName Name of the test to find. + * \param testPath If the test is found, then all the tests traversed to access + * \a test are added to \a testPath, including \c this and \a test. + * \return \c true if a test with the specified name is found, \c false otherwise. + */ + virtual bool findTestPath( const std::string &testName, + TestPath &testPath ) const; + + /*! \brief Finds the specified test and its parents test. + * \param test Test to find. + * \param testPath If the test is found, then all the tests traversed to access + * \a test are added to \a testPath, including \c this and \a test. + * \return \c true if the specified test is found, \c false otherwise. + */ + virtual bool findTestPath( const Test *test, + TestPath &testPath ) const; + + /*! \brief Finds the test with the specified name in the hierarchy. + * \param testName Name of the test to find. + * \return Pointer on the first test found that is named \a testName. Never \c NULL. + * \exception std::invalid_argument if no test named \a testName is found. + */ + virtual Test *findTest( const std::string &testName ) const; + + /*! \brief Resolved the specified test path with this test acting as 'root'. + * \param testPath Test path string to resolve. + * \return Resolved TestPath. + * \exception std::invalid_argument if \a testPath could not be resolved. + * \see TestPath. + */ + virtual TestPath resolveTestPath( const std::string &testPath ) const; + +protected: + /*! Throws an exception if the specified index is invalid. + * \param index Zero base index of a child test. + * \exception std::out_of_range is \a index is < 0 or >= getChildTestCount(). + */ + virtual void checkIsValidIndex( int index ) const; + + /*! \brief Returns the child test of the specified valid index. + * \param index Zero based valid index of the child test to return. + * \return Pointer on the test. Never \c NULL. + */ + virtual Test *doGetChildTestAt( int index ) const =0; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TEST_H + diff --git a/UnitTests/cppunit/include/cppunit/TestAssert.h b/UnitTests/cppunit/include/cppunit/TestAssert.h new file mode 100644 index 0000000..f74797b --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestAssert.h @@ -0,0 +1,428 @@ +#ifndef CPPUNIT_TESTASSERT_H +#define CPPUNIT_TESTASSERT_H + +#include +#include +#include +#include +#include +#include // For struct assertion_traits + + +CPPUNIT_NS_BEGIN + + +/*! \brief Traits used by CPPUNIT_ASSERT_EQUAL(). + * + * Here is an example of specialising these traits: + * + * \code + * template<> + * struct assertion_traits // specialization for the std::string type + * { + * static bool equal( const std::string& x, const std::string& y ) + * { + * return x == y; + * } + * + * static std::string toString( const std::string& x ) + * { + * std::string text = '"' + x + '"'; // adds quote around the string to see whitespace + * OStringStream ost; + * ost << text; + * return ost.str(); + * } + * }; + * \endcode + */ +template +struct assertion_traits +{ + static bool equal( const T& x, const T& y ) + { + return x == y; + } + + static std::string toString( const T& x ) + { + OStringStream ost; + ost << x; + return ost.str(); + } +}; + + +/*! \brief Traits used by CPPUNIT_ASSERT_DOUBLES_EQUAL(). + * + * This specialisation from @c struct @c assertion_traits<> ensures that + * doubles are converted in full, instead of being rounded to the default + * 6 digits of precision. Use the system defined ISO C99 macro DBL_DIG + * within float.h is available to define the maximum precision, otherwise + * use the hard-coded maximum precision of 15. + */ +template <> +struct assertion_traits +{ + static bool equal( double x, double y ) + { + return x == y; + } + + static std::string toString( double x ) + { +#ifdef DBL_DIG + const int precision = DBL_DIG; +#else + const int precision = 15; +#endif // #ifdef DBL_DIG + char buffer[128]; +#ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning. + sprintf_s(buffer, sizeof(buffer), "%.*g", precision, x); +#else + sprintf(buffer, "%.*g", precision, x); +#endif + return buffer; + } +}; + + +/*! \brief (Implementation) Asserts that two objects of the same type are equals. + * Use CPPUNIT_ASSERT_EQUAL instead of this function. + * \sa assertion_traits, Asserter::failNotEqual(). + */ +template +void assertEquals( const T& expected, + const T& actual, + SourceLine sourceLine, + const std::string &message ) +{ + if ( !assertion_traits::equal(expected,actual) ) // lazy toString conversion... + { + Asserter::failNotEqual( assertion_traits::toString(expected), + assertion_traits::toString(actual), + sourceLine, + message ); + } +} + + +/*! \brief (Implementation) Asserts that two double are equals given a tolerance. + * Use CPPUNIT_ASSERT_DOUBLES_EQUAL instead of this function. + * \sa Asserter::failNotEqual(). + * \sa CPPUNIT_ASSERT_DOUBLES_EQUAL for detailed semantic of the assertion. + */ +void CPPUNIT_API assertDoubleEquals( double expected, + double actual, + double delta, + SourceLine sourceLine, + const std::string &message ); + + +/* A set of macros which allow us to get the line number + * and file name at the point of an error. + * Just goes to show that preprocessors do have some + * redeeming qualities. + */ +#if CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION +/** Assertions that a condition is \c true. + * \ingroup Assertions + */ +#define CPPUNIT_ASSERT(condition) \ + ( CPPUNIT_NS::Asserter::failIf( !(condition), \ + CPPUNIT_NS::Message( "assertion failed", \ + "Expression: " #condition), \ + CPPUNIT_SOURCELINE() ) ) +#else +#define CPPUNIT_ASSERT(condition) \ + ( CPPUNIT_NS::Asserter::failIf( !(condition), \ + CPPUNIT_NS::Message( "assertion failed" ), \ + CPPUNIT_SOURCELINE() ) ) +#endif + +/** Assertion with a user specified message. + * \ingroup Assertions + * \param message Message reported in diagnostic if \a condition evaluates + * to \c false. + * \param condition If this condition evaluates to \c false then the + * test failed. + */ +#define CPPUNIT_ASSERT_MESSAGE(message,condition) \ + ( CPPUNIT_NS::Asserter::failIf( !(condition), \ + CPPUNIT_NS::Message( "assertion failed", \ + "Expression: " \ + #condition, \ + message ), \ + CPPUNIT_SOURCELINE() ) ) + +/** Fails with the specified message. + * \ingroup Assertions + * \param message Message reported in diagnostic. + */ +#define CPPUNIT_FAIL( message ) \ + ( CPPUNIT_NS::Asserter::fail( CPPUNIT_NS::Message( "forced failure", \ + message ), \ + CPPUNIT_SOURCELINE() ) ) + +#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED +/// Generalized macro for primitive value comparisons +#define CPPUNIT_ASSERT_EQUAL(expected,actual) \ + ( CPPUNIT_NS::assertEquals( (expected), \ + (actual), \ + __LINE__, __FILE__ ) ) +#else +/** Asserts that two values are equals. + * \ingroup Assertions + * + * Equality and string representation can be defined with + * an appropriate CppUnit::assertion_traits class. + * + * A diagnostic is printed if actual and expected values disagree. + * + * Requirement for \a expected and \a actual parameters: + * - They are exactly of the same type + * - They are serializable into a std::strstream using operator <<. + * - They can be compared using operator ==. + * + * The last two requirements (serialization and comparison) can be + * removed by specializing the CppUnit::assertion_traits. + */ +#define CPPUNIT_ASSERT_EQUAL(expected,actual) \ + ( CPPUNIT_NS::assertEquals( (expected), \ + (actual), \ + CPPUNIT_SOURCELINE(), \ + "" ) ) + +/** Asserts that two values are equals, provides additional message on failure. + * \ingroup Assertions + * + * Equality and string representation can be defined with + * an appropriate assertion_traits class. + * + * A diagnostic is printed if actual and expected values disagree. + * The message is printed in addition to the expected and actual value + * to provide additional information. + * + * Requirement for \a expected and \a actual parameters: + * - They are exactly of the same type + * - They are serializable into a std::strstream using operator <<. + * - They can be compared using operator ==. + * + * The last two requirements (serialization and comparison) can be + * removed by specializing the CppUnit::assertion_traits. + */ +#define CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual) \ + ( CPPUNIT_NS::assertEquals( (expected), \ + (actual), \ + CPPUNIT_SOURCELINE(), \ + (message) ) ) +#endif + +/*! \brief Macro for primitive double value comparisons. + * \ingroup Assertions + * + * The assertion pass if both expected and actual are finite and + * \c fabs( \c expected - \c actual ) <= \c delta. + * If either \c expected or actual are infinite (+/- inf), the + * assertion pass if \c expected == \c actual. + * If either \c expected or \c actual is a NaN (not a number), then + * the assertion fails. + */ +#define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta) \ + ( CPPUNIT_NS::assertDoubleEquals( (expected), \ + (actual), \ + (delta), \ + CPPUNIT_SOURCELINE(), \ + "" ) ) + + +/*! \brief Macro for primitive double value comparisons, setting a + * user-supplied message in case of failure. + * \ingroup Assertions + * \sa CPPUNIT_ASSERT_DOUBLES_EQUAL for detailed semantic of the assertion. + */ +#define CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(message,expected,actual,delta) \ + ( CPPUNIT_NS::assertDoubleEquals( (expected), \ + (actual), \ + (delta), \ + CPPUNIT_SOURCELINE(), \ + (message) ) ) + + +/** Asserts that the given expression throws an exception of the specified type. + * \ingroup Assertions + * Example of usage: + * \code + * std::vector v; + * CPPUNIT_ASSERT_THROW( v.at( 50 ), std::out_of_range ); + * \endcode + */ +# define CPPUNIT_ASSERT_THROW( expression, ExceptionType ) \ + CPPUNIT_ASSERT_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(), \ + expression, \ + ExceptionType ) + + +// implementation detail +#if CPPUNIT_USE_TYPEINFO_NAME +#define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \ + CPPUNIT_NS::TypeInfoHelper::getClassName( typeid(exception) ) +#else +#define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \ + std::string( no_rtti_message ) +#endif // CPPUNIT_USE_TYPEINFO_NAME + +// implementation detail +#define CPPUNIT_GET_PARAMETER_STRING( parameter ) #parameter + +/** Asserts that the given expression throws an exception of the specified type, + * setting a user supplied message in case of failure. + * \ingroup Assertions + * Example of usage: + * \code + * std::vector v; + * CPPUNIT_ASSERT_THROW_MESSAGE( "- std::vector v;", v.at( 50 ), std::out_of_range ); + * \endcode + */ +# define CPPUNIT_ASSERT_THROW_MESSAGE( message, expression, ExceptionType ) \ + do { \ + bool cpputCorrectExceptionThrown_ = false; \ + CPPUNIT_NS::Message cpputMsg_( "expected exception not thrown" ); \ + cpputMsg_.addDetail( message ); \ + cpputMsg_.addDetail( "Expected: " \ + CPPUNIT_GET_PARAMETER_STRING( ExceptionType ) ); \ + \ + try { \ + expression; \ + } catch ( const ExceptionType & ) { \ + cpputCorrectExceptionThrown_ = true; \ + } catch ( const std::exception &e) { \ + cpputMsg_.addDetail( "Actual : " + \ + CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e, \ + "std::exception or derived") ); \ + cpputMsg_.addDetail( std::string("What() : ") + e.what() ); \ + } catch ( ... ) { \ + cpputMsg_.addDetail( "Actual : unknown."); \ + } \ + \ + if ( cpputCorrectExceptionThrown_ ) \ + break; \ + \ + CPPUNIT_NS::Asserter::fail( cpputMsg_, \ + CPPUNIT_SOURCELINE() ); \ + } while ( false ) + + +/** Asserts that the given expression does not throw any exceptions. + * \ingroup Assertions + * Example of usage: + * \code + * std::vector v; + * v.push_back( 10 ); + * CPPUNIT_ASSERT_NO_THROW( v.at( 0 ) ); + * \endcode + */ +# define CPPUNIT_ASSERT_NO_THROW( expression ) \ + CPPUNIT_ASSERT_NO_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(), \ + expression ) + + +/** Asserts that the given expression does not throw any exceptions, + * setting a user supplied message in case of failure. + * \ingroup Assertions + * Example of usage: + * \code + * std::vector v; + * v.push_back( 10 ); + * CPPUNIT_ASSERT_NO_THROW( "std::vector v;", v.at( 0 ) ); + * \endcode + */ +# define CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, expression ) \ + do { \ + CPPUNIT_NS::Message cpputMsg_( "unexpected exception caught" ); \ + cpputMsg_.addDetail( message ); \ + \ + try { \ + expression; \ + } catch ( const std::exception &e ) { \ + cpputMsg_.addDetail( "Caught: " + \ + CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e, \ + "std::exception or derived" ) ); \ + cpputMsg_.addDetail( std::string("What(): ") + e.what() ); \ + CPPUNIT_NS::Asserter::fail( cpputMsg_, \ + CPPUNIT_SOURCELINE() ); \ + } catch ( ... ) { \ + cpputMsg_.addDetail( "Caught: unknown." ); \ + CPPUNIT_NS::Asserter::fail( cpputMsg_, \ + CPPUNIT_SOURCELINE() ); \ + } \ + } while ( false ) + + +/** Asserts that an assertion fail. + * \ingroup Assertions + * Use to test assertions. + * Example of usage: + * \code + * CPPUNIT_ASSERT_ASSERTION_FAIL( CPPUNIT_ASSERT( 1 == 2 ) ); + * \endcode + */ +# define CPPUNIT_ASSERT_ASSERTION_FAIL( assertion ) \ + CPPUNIT_ASSERT_THROW( assertion, CPPUNIT_NS::Exception ) + + +/** Asserts that an assertion fail, with a user-supplied message in + * case of error. + * \ingroup Assertions + * Use to test assertions. + * Example of usage: + * \code + * CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( "1 == 2", CPPUNIT_ASSERT( 1 == 2 ) ); + * \endcode + */ +# define CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( message, assertion ) \ + CPPUNIT_ASSERT_THROW_MESSAGE( message, assertion, CPPUNIT_NS::Exception ) + + +/** Asserts that an assertion pass. + * \ingroup Assertions + * Use to test assertions. + * Example of usage: + * \code + * CPPUNIT_ASSERT_ASSERTION_PASS( CPPUNIT_ASSERT( 1 == 1 ) ); + * \endcode + */ +# define CPPUNIT_ASSERT_ASSERTION_PASS( assertion ) \ + CPPUNIT_ASSERT_NO_THROW( assertion ) + + +/** Asserts that an assertion pass, with a user-supplied message in + * case of failure. + * \ingroup Assertions + * Use to test assertions. + * Example of usage: + * \code + * CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( "1 != 1", CPPUNIT_ASSERT( 1 == 1 ) ); + * \endcode + */ +# define CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( message, assertion ) \ + CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, assertion ) + + + + +// Backwards compatibility + +#if CPPUNIT_ENABLE_NAKED_ASSERT + +#undef assert +#define assert(c) CPPUNIT_ASSERT(c) +#define assertEqual(e,a) CPPUNIT_ASSERT_EQUAL(e,a) +#define assertDoublesEqual(e,a,d) CPPUNIT_ASSERT_DOUBLES_EQUAL(e,a,d) +#define assertLongsEqual(e,a) CPPUNIT_ASSERT_EQUAL(e,a) + +#endif + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTASSERT_H diff --git a/UnitTests/cppunit/include/cppunit/TestCaller.h b/UnitTests/cppunit/include/cppunit/TestCaller.h new file mode 100644 index 0000000..dc4d82e --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestCaller.h @@ -0,0 +1,204 @@ +#ifndef CPPUNIT_TESTCALLER_H // -*- C++ -*- +#define CPPUNIT_TESTCALLER_H + +#include +#include + + +#if CPPUNIT_USE_TYPEINFO_NAME +# include +#endif + + +CPPUNIT_NS_BEGIN + +#if 0 +/*! \brief Marker class indicating that no exception is expected by TestCaller. + * This class is an implementation detail. You should never use this class directly. + */ +class CPPUNIT_API NoExceptionExpected +{ +private: + //! Prevent class instantiation. + NoExceptionExpected(); +}; + + +/*! \brief (Implementation) Traits used by TestCaller to expect an exception. + * + * This class is an implementation detail. You should never use this class directly. + */ +template +struct ExpectedExceptionTraits +{ + static void expectedException() + { +#if CPPUNIT_USE_TYPEINFO_NAME + throw Exception( Message( + "expected exception not thrown", + "Expected exception type: " + + TypeInfoHelper::getClassName( typeid( ExceptionType ) ) ) ); +#else + throw Exception( "expected exception not thrown" ); +#endif + } +}; + + +/*! \brief (Implementation) Traits specialization used by TestCaller to + * expect no exception. + * + * This class is an implementation detail. You should never use this class directly. + */ +template<> +struct ExpectedExceptionTraits +{ + static void expectedException() + { + } +}; + + +#endif + +//*** FIXME: rework this when class Fixture is implemented. ***// + + +/*! \brief Generate a test case from a fixture method. + * \ingroup WritingTestFixture + * + * A test caller provides access to a test case method + * on a test fixture class. Test callers are useful when + * you want to run an individual test or add it to a + * suite. + * Test Callers invoke only one Test (i.e. test method) on one + * Fixture of a TestFixture. + * + * Here is an example: + * \code + * class MathTest : public CppUnit::TestFixture { + * ... + * public: + * void setUp(); + * void tearDown(); + * + * void testAdd(); + * void testSubtract(); + * }; + * + * CppUnit::Test *MathTest::suite() { + * CppUnit::TestSuite *suite = new CppUnit::TestSuite; + * + * suite->addTest( new CppUnit::TestCaller( "testAdd", testAdd ) ); + * return suite; + * } + * \endcode + * + * You can use a TestCaller to bind any test method on a TestFixture + * class, as long as it accepts void and returns void. + * + * \see TestCase + */ + +template +class TestCaller : public TestCase +{ + typedef void (Fixture::*TestMethod)(); + +public: + /*! + * Constructor for TestCaller. This constructor builds a new Fixture + * instance owned by the TestCaller. + * \param name name of this TestCaller + * \param test the method this TestCaller calls in runTest() + */ + TestCaller( std::string name, TestMethod test ) : + TestCase( name ), + m_ownFixture( true ), + m_fixture( new Fixture() ), + m_test( test ) + { + } + + /*! + * Constructor for TestCaller. + * This constructor does not create a new Fixture instance but accepts + * an existing one as parameter. The TestCaller will not own the + * Fixture object. + * \param name name of this TestCaller + * \param test the method this TestCaller calls in runTest() + * \param fixture the Fixture to invoke the test method on. + */ + TestCaller(std::string name, TestMethod test, Fixture& fixture) : + TestCase( name ), + m_ownFixture( false ), + m_fixture( &fixture ), + m_test( test ) + { + } + + /*! + * Constructor for TestCaller. + * This constructor does not create a new Fixture instance but accepts + * an existing one as parameter. The TestCaller will own the + * Fixture object and delete it in its destructor. + * \param name name of this TestCaller + * \param test the method this TestCaller calls in runTest() + * \param fixture the Fixture to invoke the test method on. + */ + TestCaller(std::string name, TestMethod test, Fixture* fixture) : + TestCase( name ), + m_ownFixture( true ), + m_fixture( fixture ), + m_test( test ) + { + } + + ~TestCaller() + { + if (m_ownFixture) + delete m_fixture; + } + + void runTest() + { +// try { + (m_fixture->*m_test)(); +// } +// catch ( ExpectedException & ) { +// return; +// } + +// ExpectedExceptionTraits::expectedException(); + } + + void setUp() + { + m_fixture->setUp (); + } + + void tearDown() + { + m_fixture->tearDown (); + } + + std::string toString() const + { + return "TestCaller " + getName(); + } + +private: + TestCaller( const TestCaller &other ); + TestCaller &operator =( const TestCaller &other ); + +private: + bool m_ownFixture; + Fixture *m_fixture; + TestMethod m_test; +}; + + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTCALLER_H diff --git a/UnitTests/cppunit/include/cppunit/TestCase.h b/UnitTests/cppunit/include/cppunit/TestCase.h new file mode 100644 index 0000000..d4b7a46 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestCase.h @@ -0,0 +1,55 @@ +#ifndef CPPUNIT_TESTCASE_H +#define CPPUNIT_TESTCASE_H + +#include +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +class TestResult; + + +/*! \brief A single test object. + * + * This class is used to implement a simple test case: define a subclass + * that overrides the runTest method. + * + * You don't usually need to use that class, but TestFixture and TestCaller instead. + * + * You are expected to subclass TestCase is you need to write a class similiar + * to TestCaller. + */ +class CPPUNIT_API TestCase : public TestLeaf, + public TestFixture +{ +public: + + TestCase( const std::string &name ); + + TestCase(); + + ~TestCase(); + + virtual void run(TestResult *result); + + std::string getName() const; + + //! FIXME: this should probably be pure virtual. + virtual void runTest(); + +private: + TestCase( const TestCase &other ); + TestCase &operator=( const TestCase &other ); + +private: + const std::string m_name; +}; + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTCASE_H diff --git a/UnitTests/cppunit/include/cppunit/TestComposite.h b/UnitTests/cppunit/include/cppunit/TestComposite.h new file mode 100644 index 0000000..0ded95f --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestComposite.h @@ -0,0 +1,45 @@ +#ifndef CPPUNIT_TESTCOMPSITE_H // -*- C++ -*- +#define CPPUNIT_TESTCOMPSITE_H + +#include +#include + +CPPUNIT_NS_BEGIN + + +/*! \brief A Composite of Tests. + * + * Base class for all test composites. Subclass this class if you need to implement + * a custom TestSuite. + * + * \see Test, TestSuite. + */ +class CPPUNIT_API TestComposite : public Test +{ +public: + TestComposite( const std::string &name = "" ); + + ~TestComposite(); + + void run( TestResult *result ); + + int countTestCases() const; + + std::string getName() const; + +private: + TestComposite( const TestComposite &other ); + TestComposite &operator =( const TestComposite &other ); + + virtual void doStartSuite( TestResult *controller ); + virtual void doRunChildTests( TestResult *controller ); + virtual void doEndSuite( TestResult *controller ); + +private: + const std::string m_name; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTCOMPSITE_H diff --git a/UnitTests/cppunit/include/cppunit/TestFailure.h b/UnitTests/cppunit/include/cppunit/TestFailure.h new file mode 100644 index 0000000..6419979 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestFailure.h @@ -0,0 +1,58 @@ +#ifndef CPPUNIT_TESTFAILURE_H // -*- C++ -*- +#define CPPUNIT_TESTFAILURE_H + +#include +#include + +CPPUNIT_NS_BEGIN + + +class Exception; +class SourceLine; +class Test; + + +/*! \brief Record of a failed Test execution. + * \ingroup BrowsingCollectedTestResult + * + * A TestFailure collects a failed test together with + * the caught exception. + * + * TestFailure assumes lifetime control for any exception + * passed to it. + */ +class CPPUNIT_API TestFailure +{ +public: + TestFailure( Test *failedTest, + Exception *thrownException, + bool isError ); + + virtual ~TestFailure (); + + virtual Test *failedTest() const; + + virtual Exception *thrownException() const; + + virtual SourceLine sourceLine() const; + + virtual bool isError() const; + + virtual std::string failedTestName() const; + + virtual TestFailure *clone() const; + +protected: + Test *m_failedTest; + Exception *m_thrownException; + bool m_isError; + +private: + TestFailure( const TestFailure &other ); + TestFailure &operator =( const TestFailure& other ); +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTFAILURE_H diff --git a/UnitTests/cppunit/include/cppunit/TestFixture.h b/UnitTests/cppunit/include/cppunit/TestFixture.h new file mode 100644 index 0000000..1223adb --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestFixture.h @@ -0,0 +1,99 @@ +#ifndef CPPUNIT_TESTFIXTURE_H // -*- C++ -*- +#define CPPUNIT_TESTFIXTURE_H + +#include + +CPPUNIT_NS_BEGIN + + +/*! \brief Wraps a test case with setUp and tearDown methods. + * \ingroup WritingTestFixture + * + * A TestFixture is used to provide a common environment for a set + * of test cases. + * + * To define a test fixture, do the following: + * - implement a subclass of TestCase + * - the fixture is defined by instance variables + * - initialize the fixture state by overriding setUp + * (i.e. construct the instance variables of the fixture) + * - clean-up after a test by overriding tearDown. + * + * Each test runs in its own fixture so there + * can be no side effects among test runs. + * Here is an example: + * + * \code + * class MathTest : public CppUnit::TestFixture { + * protected: + * int m_value1, m_value2; + * + * public: + * MathTest() {} + * + * void setUp () { + * m_value1 = 2; + * m_value2 = 3; + * } + * } + * \endcode + * + * For each test implement a method which interacts + * with the fixture. Verify the expected results with assertions specified + * by calling CPPUNIT_ASSERT on the expression you want to test: + * + * \code + * public: + * void testAdd () { + * int result = m_value1 + m_value2; + * CPPUNIT_ASSERT( result == 5 ); + * } + * \endcode + * + * Once the methods are defined you can run them. To do this, use + * a TestCaller. + * + * \code + * CppUnit::Test *test = new CppUnit::TestCaller( "testAdd", + * &MathTest::testAdd ); + * test->run(); + * \endcode + * + * + * The tests to be run can be collected into a TestSuite. + * + * \code + * public: + * static CppUnit::TestSuite *MathTest::suite () { + * CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite; + * suiteOfTests->addTest(new CppUnit::TestCaller( + * "testAdd", &MathTest::testAdd)); + * suiteOfTests->addTest(new CppUnit::TestCaller( + * "testDivideByZero", &MathTest::testDivideByZero)); + * return suiteOfTests; + * } + * \endcode + * + * A set of macros have been created for convenience. They are located in HelperMacros.h. + * + * \see TestResult, TestSuite, TestCaller, + * \see CPPUNIT_TEST_SUB_SUITE, CPPUNIT_TEST, CPPUNIT_TEST_SUITE_END, + * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_EXCEPTION, CPPUNIT_TEST_FAIL. + */ +class CPPUNIT_API TestFixture +{ +public: + virtual ~TestFixture() {}; + + //! \brief Set up context before running a test. + virtual void setUp() {}; + + //! Clean up after the test run. + virtual void tearDown() {}; +}; + + +CPPUNIT_NS_END + + +#endif diff --git a/UnitTests/cppunit/include/cppunit/TestLeaf.h b/UnitTests/cppunit/include/cppunit/TestLeaf.h new file mode 100644 index 0000000..c83b075 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestLeaf.h @@ -0,0 +1,44 @@ +#ifndef CPPUNIT_TESTLEAF_H +#define CPPUNIT_TESTLEAF_H + +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief A single test object. + * + * Base class for single test case: a test that doesn't have any children. + * + */ +class CPPUNIT_API TestLeaf: public Test +{ +public: + /*! Returns 1 as the default number of test cases invoked by run(). + * + * You may override this method when many test cases are invoked (RepeatedTest + * for example). + * + * \return 1. + * \see Test::countTestCases(). + */ + int countTestCases() const; + + /*! Returns the number of child of this test case: 0. + * + * You should never override this method: a TestLeaf as no children by definition. + * + * \return 0. + */ + int getChildTestCount() const; + + /*! Always throws std::out_of_range. + * \see Test::doGetChildTestAt(). + */ + Test *doGetChildTestAt( int index ) const; +}; + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTLEAF_H diff --git a/UnitTests/cppunit/include/cppunit/TestListener.h b/UnitTests/cppunit/include/cppunit/TestListener.h new file mode 100644 index 0000000..330262d --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestListener.h @@ -0,0 +1,148 @@ +#ifndef CPPUNIT_TESTLISTENER_H // -*- C++ -*- +#define CPPUNIT_TESTLISTENER_H + +#include + + +CPPUNIT_NS_BEGIN + + +class Exception; +class Test; +class TestFailure; +class TestResult; + + +/*! \brief Listener for test progress and result. + * \ingroup TrackingTestExecution + * + * Implementing the Observer pattern a TestListener may be registered + * to a TestResult to obtain information on the testing progress. Use + * specialized sub classes of TestListener for text output + * (TextTestProgressListener). Do not use the Listener for the test + * result output, use a subclass of Outputter instead. + * + * The test framework distinguishes between failures and errors. + * A failure is anticipated and checked for with assertions. Errors are + * unanticipated problems signified by exceptions that are not generated + * by the framework. + * + * Here is an example to track test time: + * + * + * \code + * #include + * #include + * #include // for clock() + * + * class TimingListener : public CppUnit::TestListener + * { + * public: + * void startTest( CppUnit::Test *test ) + * { + * _chronometer.start(); + * } + * + * void endTest( CppUnit::Test *test ) + * { + * _chronometer.end(); + * addTest( test, _chronometer.elapsedTime() ); + * } + * + * // ... (interface to add/read test timing result) + * + * private: + * Clock _chronometer; + * }; + * \endcode + * + * And another example that track failure/success at test suite level and captures + * the TestPath of each suite: + * \code + * class SuiteTracker : public CppUnit::TestListener + * { + * public: + * void startSuite( CppUnit::Test *suite ) + * { + * m_currentPath.add( suite ); + * } + * + * void addFailure( const TestFailure &failure ) + * { + * m_suiteFailure.top() = false; + * } + * + * void endSuite( CppUnit::Test *suite ) + * { + * m_suiteStatus.insert( std::make_pair( suite, m_suiteFailure.top() ) ); + * m_suitePaths.insert( std::make_pair( suite, m_currentPath ) ); + * + * m_currentPath.up(); + * m_suiteFailure.pop(); + * } + * + * private: + * std::stack m_suiteFailure; + * CppUnit::TestPath m_currentPath; + * std::map m_suiteStatus; + * std::map m_suitePaths; + * }; + * \endcode + * + * \see TestResult + */ +class CPPUNIT_API TestListener +{ +public: + virtual ~TestListener() {} + + /// Called when just before a TestCase is run. + virtual void startTest( Test * /*test*/ ) {} + + /*! \brief Called when a failure occurs while running a test. + * \see TestFailure. + * \warning \a failure is a temporary object that is destroyed after the + * method call. Use TestFailure::clone() to create a duplicate. + */ + virtual void addFailure( const TestFailure & /*failure*/ ) {} + + /// Called just after a TestCase was run (even if a failure occured). + virtual void endTest( Test * /*test*/ ) {} + + /*! \brief Called by a TestComposite just before running its child tests. + */ + virtual void startSuite( Test * /*suite*/ ) {} + + /*! \brief Called by a TestComposite after running its child tests. + */ + virtual void endSuite( Test * /*suite*/ ) {} + + /*! \brief Called by a TestRunner before running the test. + * + * You can use this to do some global initialisation. A listener + * could also use to output a 'prolog' to the test run. + * + * \param test Test that is going to be run. + * \param eventManager Event manager used for the test run. + */ + virtual void startTestRun( Test * /*test*/, + TestResult * /*eventManager*/ ) {} + + /*! \brief Called by a TestRunner after running the test. + * + * TextTestProgressListener use this to emit a line break. You can also use this + * to do some global uninitialisation. + * + * \param test Test that was run. + * \param eventManager Event manager used for the test run. + */ + virtual void endTestRun( Test * /*test*/, + TestResult * /*eventManager*/ ) {} +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTLISTENER_H + + diff --git a/UnitTests/cppunit/include/cppunit/TestPath.h b/UnitTests/cppunit/include/cppunit/TestPath.h new file mode 100644 index 0000000..c3c851c --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestPath.h @@ -0,0 +1,211 @@ +#ifndef CPPUNIT_TESTPATH_H +#define CPPUNIT_TESTPATH_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include + +CPPUNIT_NS_BEGIN + + +class Test; + +#if CPPUNIT_NEED_DLL_DECL +// template class CPPUNIT_API std::deque; +#endif + + +/*! \brief A List of Test representing a path to access a Test. + * \ingroup ExecutingTest + * + * The path can be converted to a string and resolved from a string with toString() + * and TestPath( Test *root, const std::string &pathAsString ). + * + * Pointed tests are not owned by the class. + * + * \see Test::resolvedTestPath() + */ +class CPPUNIT_API TestPath +{ +public: + /*! \brief Constructs an invalid path. + * + * The path is invalid until a test is added with add(). + */ + TestPath(); + + /*! \brief Constructs a valid path. + * + * \param root Test to add. + */ + TestPath( Test *root ); + + /*! \brief Constructs a path using a slice of another path. + * \param otherPath Path the test are copied from. + * \param indexFirst Zero based index of the first test to copy. Adjusted to be in valid + * range. \a count is adjusted with \a indexFirst. + * \param count Number of tests to copy. If < 0 then all test starting from index + * \a indexFirst are copied. + */ + TestPath( const TestPath &otherPath, + int indexFirst, + int count = -1 ); + + /*! \brief Resolves a path from a string returned by toString(). + * + * If \a pathAsString is an absolute path (begins with '/'), then the first test name + * of the path must be the name of \a searchRoot. Otherwise, \a pathAsString is a + * relative path, and the first test found using Test::findTest() matching the first + * test name is used as root. An empty string resolve to a path containing + * \a searchRoot. + * + * The resolved path is always valid. + * + * \param searchRoot Test used to resolve the path. + * \param pathAsString String that contains the path as a string created by toString(). + * \exception std::invalid_argument if one of the test names can not be resolved. + * \see toString(). + */ + TestPath( Test *searchRoot, + const std::string &pathAsString ); + + /*! \brief Copy constructor. + * \param other Object to copy. + */ + TestPath( const TestPath &other ); + + virtual ~TestPath(); + + /*! \brief Tests if the path contains at least one test. + * \return \c true if the path contains at least one test, otherwise returns \c false. + */ + virtual bool isValid() const; + + /*! \brief Adds a test to the path. + * \param test Pointer on the test to add. Must not be \c NULL. + */ + virtual void add( Test *test ); + + /*! \brief Adds all the tests of the specified path. + * \param path Path that contains the test to add. + */ + virtual void add( const TestPath &path ); + + /*! \brief Inserts a test at the specified index. + * \param test Pointer on the test to insert. Must not be \c NULL. + * \param index Zero based index indicating where the test is inserted. + * \exception std::out_of_range is \a index < 0 or \a index > getTestCount(). + */ + virtual void insert( Test *test, int index ); + + /*! \brief Inserts all the tests at the specified path at a given index. + * \param path Path that contains the test to insert. + * \param index Zero based index indicating where the tests are inserted. + * \exception std::out_of_range is \a index < 0 or \a index > getTestCount(), and + * \a path is valid. + */ + virtual void insert( const TestPath &path, int index ); + + /*! \brief Removes all the test from the path. + * + * The path becomes invalid after this call. + */ + virtual void removeTests(); + + /*! \brief Removes the test at the specified index of the path. + * \param index Zero based index of the test to remove. + * \exception std::out_of_range is \a index < 0 or \a index >= getTestCount(). + */ + virtual void removeTest( int index ); + + /*! \brief Removes the last test. + * \exception std::out_of_range is the path is invalid. + * \see isValid(). + */ + virtual void up(); + + /*! \brief Returns the number of tests in the path. + * \return Number of tests in the path. + */ + virtual int getTestCount() const; + + /*! \brief Returns the test of the specified index. + * \param index Zero based index of the test to return. + * \return Pointer on the test at index \a index. Never \c NULL. + * \exception std::out_of_range is \a index < 0 or \a index >= getTestCount(). + */ + virtual Test *getTestAt( int index ) const; + + /*! \brief Get the last test of the path. + * \return Pointer on the last test (test at the bottom of the hierarchy). Never \c NULL. + * \exception std::out_of_range if the path is not valid ( isValid() returns \c false ). + */ + virtual Test *getChildTest() const; + + /*! \brief Returns the path as a string. + * + * For example, if a path is composed of three tests named "All Tests", "Math" and + * "Math::testAdd", toString() will return: + * + * "All Tests/Math/Math::testAdd". + * + * \return A string composed of the test names separated with a '/'. It is a relative + * path. + */ + virtual std::string toString() const; + + /*! \brief Assignment operator. + * \param other Object to copy. + * \return This object. + */ + TestPath &operator =( const TestPath &other ); + +protected: + /*! \brief Checks that the specified test index is within valid range. + * \param index Zero based index to check. + * \exception std::out_of_range is \a index < 0 or \a index >= getTestCount(). + */ + void checkIndexValid( int index ) const; + + /// A list of test names. + typedef CppUnitDeque PathTestNames; + + /*! \brief Splits a path string into its test name components. + * \param pathAsString Path string created with toString(). + * \param testNames Test name components are added to that container. + * \return \c true if the path is relative (does not begin with '/'), \c false + * if it is absolute (begin with '/'). + */ + bool splitPathString( const std::string &pathAsString, + PathTestNames &testNames ); + + /*! \brief Finds the actual root of a path string and get the path string name components. + * \param searchRoot Test used as root if the path string is absolute, or to search + * the root test if the path string is relative. + * \param pathAsString Path string. May be absolute or relative. + * \param testNames Test name components are added to that container. + * \return Pointer on the resolved root test. Never \c NULL. + * \exception std::invalid_argument if either the root name can not be resolved or if + * pathAsString contains no name components. + */ + Test *findActualRoot( Test *searchRoot, + const std::string &pathAsString, + PathTestNames &testNames ); + +protected: + typedef CppUnitDeque Tests; + Tests m_tests; + +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTPATH_H + diff --git a/UnitTests/cppunit/include/cppunit/TestResult.h b/UnitTests/cppunit/include/cppunit/TestResult.h new file mode 100644 index 0000000..e7e1050 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestResult.h @@ -0,0 +1,156 @@ +#ifndef CPPUNIT_TESTRESULT_H +#define CPPUNIT_TESTRESULT_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +class Exception; +class Functor; +class Protector; +class ProtectorChain; +class Test; +class TestFailure; +class TestListener; + + +#if CPPUNIT_NEED_DLL_DECL +// template class CPPUNIT_API std::deque; +#endif + +/*! \brief Manages TestListener. + * \ingroup TrackingTestExecution + * + * A single instance of this class is used when running the test. It is usually + * created by the test runner (TestRunner). + * + * This class shouldn't have to be inherited from. Use a TestListener + * or one of its subclasses to be informed of the ongoing tests. + * Use a Outputter to receive a test summary once it has finished + * + * TestResult supplies a template method 'setSynchronizationObject()' + * so that subclasses can provide mutual exclusion in the face of multiple + * threads. This can be useful when tests execute in one thread and + * they fill a subclass of TestResult which effects change in another + * thread. To have mutual exclusion, override setSynchronizationObject() + * and make sure that you create an instance of ExclusiveZone at the + * beginning of each method. + * + * \see Test, TestListener, TestResultCollector, Outputter. + */ +class CPPUNIT_API TestResult : protected SynchronizedObject +{ +public: + /// Construct a TestResult + TestResult( SynchronizationObject *syncObject = 0 ); + + /// Destroys a test result + virtual ~TestResult(); + + virtual void addListener( TestListener *listener ); + + virtual void removeListener( TestListener *listener ); + + /// Resets the stop flag. + virtual void reset(); + + /// Stop testing + virtual void stop(); + + /// Returns whether testing should be stopped + virtual bool shouldStop() const; + + /// Informs TestListener that a test will be started. + virtual void startTest( Test *test ); + + /*! \brief Adds an error to the list of errors. + * The passed in exception + * caused the error + */ + virtual void addError( Test *test, Exception *e ); + + /*! \brief Adds a failure to the list of failures. The passed in exception + * caused the failure. + */ + virtual void addFailure( Test *test, Exception *e ); + + /// Informs TestListener that a test was completed. + virtual void endTest( Test *test ); + + /// Informs TestListener that a test suite will be started. + virtual void startSuite( Test *test ); + + /// Informs TestListener that a test suite was completed. + virtual void endSuite( Test *test ); + + /*! \brief Run the specified test. + * + * Calls startTestRun(), test->run(this), and finally endTestRun(). + */ + virtual void runTest( Test *test ); + + /*! \brief Protects a call to the specified functor. + * + * See Protector to understand how protector works. A default protector is + * always present. It captures CppUnit::Exception, std::exception and + * any other exceptions, retrieving as much as possible information about + * the exception as possible. + * + * Additional Protector can be added to the chain to support other exception + * types using pushProtector() and popProtector(). + * + * \param functor Functor to call (typically a call to setUp(), runTest() or + * tearDown(). + * \param test Test the functor is associated to (used for failure reporting). + * \param shortDescription Short description override for the failure message. + */ + virtual bool protect( const Functor &functor, + Test *test, + const std::string &shortDescription = std::string("") ); + + /// Adds the specified protector to the protector chain. + virtual void pushProtector( Protector *protector ); + + /// Removes the last protector from the protector chain. + virtual void popProtector(); + +protected: + /*! \brief Called to add a failure to the list of failures. + */ + void addFailure( const TestFailure &failure ); + + virtual void startTestRun( Test *test ); + virtual void endTestRun( Test *test ); + +protected: + typedef CppUnitDeque TestListeners; + TestListeners m_listeners; + ProtectorChain *m_protectorChain; + bool m_stop; + +private: + TestResult( const TestResult &other ); + TestResult &operator =( const TestResult &other ); +}; + + +CPPUNIT_NS_END + + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + +#endif // CPPUNIT_TESTRESULT_H + + diff --git a/UnitTests/cppunit/include/cppunit/TestResultCollector.h b/UnitTests/cppunit/include/cppunit/TestResultCollector.h new file mode 100644 index 0000000..01b0a54 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestResultCollector.h @@ -0,0 +1,87 @@ +#ifndef CPPUNIT_TESTRESULTCOLLECTOR_H +#define CPPUNIT_TESTRESULTCOLLECTOR_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 4660 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include + + +CPPUNIT_NS_BEGIN + +#if CPPUNIT_NEED_DLL_DECL +// template class CPPUNIT_API std::deque; +// template class CPPUNIT_API std::deque; +#endif + + +/*! \brief Collects test result. + * \ingroup WritingTestResult + * \ingroup BrowsingCollectedTestResult + * + * A TestResultCollector is a TestListener which collects the results of executing + * a test case. It is an instance of the Collecting Parameter pattern. + * + * The test framework distinguishes between failures and errors. + * A failure is anticipated and checked for with assertions. Errors are + * unanticipated problems signified by exceptions that are not generated + * by the framework. + * \see TestListener, TestFailure. + */ +class CPPUNIT_API TestResultCollector : public TestSuccessListener +{ +public: + typedef CppUnitDeque TestFailures; + typedef CppUnitDeque Tests; + + + /*! Constructs a TestResultCollector object. + */ + TestResultCollector( SynchronizationObject *syncObject = 0 ); + + /// Destructor. + virtual ~TestResultCollector(); + + void startTest( Test *test ); + void addFailure( const TestFailure &failure ); + + virtual void reset(); + + virtual int runTests() const; + virtual int testErrors() const; + virtual int testFailures() const; + virtual int testFailuresTotal() const; + + virtual const TestFailures& failures() const; + virtual const Tests &tests() const; + +protected: + void freeFailures(); + + Tests m_tests; + TestFailures m_failures; + int m_testErrors; + +private: + /// Prevents the use of the copy constructor. + TestResultCollector( const TestResultCollector © ); + + /// Prevents the use of the copy operator. + void operator =( const TestResultCollector © ); +}; + + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + + +#endif // CPPUNIT_TESTRESULTCOLLECTOR_H diff --git a/UnitTests/cppunit/include/cppunit/TestRunner.h b/UnitTests/cppunit/include/cppunit/TestRunner.h new file mode 100644 index 0000000..930370a --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestRunner.h @@ -0,0 +1,135 @@ +#ifndef CPPUNIT_TESTRUNNER_H +#define CPPUNIT_TESTRUNNER_H + +#include +#include + +CPPUNIT_NS_BEGIN + + +class Test; +class TestResult; + + +/*! \brief Generic test runner. + * \ingroup ExecutingTest + * + * The TestRunner assumes ownership of all added tests: you can not add test + * or suite that are local variable since they can't be deleted. + * + * Example of usage: + * \code + * #include + * #include + * #include + * #include + * #include + * #include + * + * + * int + * main( int argc, char* argv[] ) + * { + * std::string testPath = (argc > 1) ? std::string(argv[1]) : ""; + * + * // Create the event manager and test controller + * CppUnit::TestResult controller; + * + * // Add a listener that colllects test result + * CppUnit::TestResultCollector result; + * controller.addListener( &result ); + * + * // Add a listener that print dots as test run. + * CppUnit::TextTestProgressListener progress; + * controller.addListener( &progress ); + * + * // Add the top suite to the test runner + * CppUnit::TestRunner runner; + * runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() ); + * try + * { + * std::cout << "Running " << testPath; + * runner.run( controller, testPath ); + * + * std::cerr << std::endl; + * + * // Print test in a compiler compatible format. + * CppUnit::CompilerOutputter outputter( &result, std::cerr ); + * outputter.write(); + * } + * catch ( std::invalid_argument &e ) // Test path not resolved + * { + * std::cerr << std::endl + * << "ERROR: " << e.what() + * << std::endl; + * return 0; + * } + * + * return result.wasSuccessful() ? 0 : 1; + * } + * \endcode + */ +class CPPUNIT_API TestRunner +{ +public: + /*! \brief Constructs a TestRunner object. + */ + TestRunner( ); + + /// Destructor. + virtual ~TestRunner(); + + /*! \brief Adds the specified test. + * \param test Test to add. The TestRunner takes ownership of the test. + */ + virtual void addTest( Test *test ); + + /*! \brief Runs a test using the specified controller. + * \param controller Event manager and controller used for testing + * \param testPath Test path string. See Test::resolveTestPath() for detail. + * \exception std::invalid_argument if no test matching \a testPath is found. + * see TestPath::TestPath( Test*, const std::string &) + * for detail. + */ + virtual void run( TestResult &controller, + const std::string &testPath = "" ); + +protected: + /*! \brief (INTERNAL) Mutating test suite. + */ + class CPPUNIT_API WrappingSuite : public TestSuite + { + public: + WrappingSuite( const std::string &name = "All Tests" ); + + int getChildTestCount() const; + + std::string getName() const; + + void run( TestResult *result ); + + protected: + Test *doGetChildTestAt( int index ) const; + + bool hasOnlyOneTest() const; + + Test *getUniqueChildTest() const; + }; + +protected: + WrappingSuite *m_suite; + +private: + /// Prevents the use of the copy constructor. + TestRunner( const TestRunner © ); + + /// Prevents the use of the copy operator. + void operator =( const TestRunner © ); + +private: +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTRUNNER_H diff --git a/UnitTests/cppunit/include/cppunit/TestSuccessListener.h b/UnitTests/cppunit/include/cppunit/TestSuccessListener.h new file mode 100644 index 0000000..60c5ff5 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestSuccessListener.h @@ -0,0 +1,39 @@ +#ifndef CPPUNIT_TESTSUCCESSLISTENER_H +#define CPPUNIT_TESTSUCCESSLISTENER_H + +#include +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief TestListener that checks if any test case failed. + * \ingroup TrackingTestExecution + */ +class CPPUNIT_API TestSuccessListener : public TestListener, + public SynchronizedObject +{ +public: + /*! Constructs a TestSuccessListener object. + */ + TestSuccessListener( SynchronizationObject *syncObject = 0 ); + + /// Destructor. + virtual ~TestSuccessListener(); + + virtual void reset(); + + void addFailure( const TestFailure &failure ); + + /// Returns whether the entire test was successful or not. + virtual bool wasSuccessful() const; + +private: + bool m_success; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TESTSUCCESSLISTENER_H diff --git a/UnitTests/cppunit/include/cppunit/TestSuite.h b/UnitTests/cppunit/include/cppunit/TestSuite.h new file mode 100644 index 0000000..2b9cd8d --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TestSuite.h @@ -0,0 +1,80 @@ +#ifndef CPPUNIT_TESTSUITE_H // -*- C++ -*- +#define CPPUNIT_TESTSUITE_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include + +CPPUNIT_NS_BEGIN + + +#if CPPUNIT_NEED_DLL_DECL +// template class CPPUNIT_API std::vector; +#endif + + +/*! \brief A Composite of Tests. + * \ingroup CreatingTestSuite + * + * It runs a collection of test cases. Here is an example. + * \code + * CppUnit::TestSuite *suite= new CppUnit::TestSuite(); + * suite->addTest(new CppUnit::TestCaller ( + * "testAdd", testAdd)); + * suite->addTest(new CppUnit::TestCaller ( + * "testDivideByZero", testDivideByZero)); + * \endcode + * Note that \link TestSuite TestSuites \endlink assume lifetime + * control for any tests added to them. + * + * TestSuites do not register themselves in the TestRegistry. + * \see Test + * \see TestCaller + */ +class CPPUNIT_API TestSuite : public TestComposite +{ +public: + /*! Constructs a test suite with the specified name. + */ + TestSuite( std::string name = "" ); + + ~TestSuite(); + + /*! Adds the specified test to the suite. + * \param test Test to add. Must not be \c NULL. + */ + void addTest( Test *test ); + + /*! Returns the list of the tests (DEPRECATED). + * \deprecated Use getChildTestCount() & getChildTestAt() of the + * TestComposite interface instead. + * \return Reference on a vector that contains the tests of the suite. + */ + const CppUnitVector &getTests() const; + + /*! Destroys all the tests of the suite. + */ + virtual void deleteContents(); + + int getChildTestCount() const; + + Test *doGetChildTestAt( int index ) const; + +private: + CppUnitVector m_tests; +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + +#endif // CPPUNIT_TESTSUITE_H diff --git a/UnitTests/cppunit/include/cppunit/TextOutputter.h b/UnitTests/cppunit/include/cppunit/TextOutputter.h new file mode 100644 index 0000000..6bd9cea --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TextOutputter.h @@ -0,0 +1,59 @@ +#ifndef CPPUNIT_TEXTOUTPUTTER_H +#define CPPUNIT_TEXTOUTPUTTER_H + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +class Exception; +class SourceLine; +class TestResultCollector; +class TestFailure; + + +/*! \brief Prints a TestResultCollector to a text stream. + * \ingroup WritingTestResult + */ +class CPPUNIT_API TextOutputter : public Outputter +{ +public: + TextOutputter( TestResultCollector *result, + OStream &stream ); + + /// Destructor. + virtual ~TextOutputter(); + + void write(); + virtual void printFailures(); + virtual void printHeader(); + + virtual void printFailure( TestFailure *failure, + int failureNumber ); + virtual void printFailureListMark( int failureNumber ); + virtual void printFailureTestName( TestFailure *failure ); + virtual void printFailureType( TestFailure *failure ); + virtual void printFailureLocation( SourceLine sourceLine ); + virtual void printFailureDetail( Exception *thrownException ); + virtual void printFailureWarning(); + virtual void printStatistics(); + +protected: + TestResultCollector *m_result; + OStream &m_stream; + +private: + /// Prevents the use of the copy constructor. + TextOutputter( const TextOutputter © ); + + /// Prevents the use of the copy operator. + void operator =( const TextOutputter © ); +}; + + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TEXTOUTPUTTER_H diff --git a/UnitTests/cppunit/include/cppunit/TextTestProgressListener.h b/UnitTests/cppunit/include/cppunit/TextTestProgressListener.h new file mode 100644 index 0000000..7521c40 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TextTestProgressListener.h @@ -0,0 +1,44 @@ +#ifndef CPPUNIT_TEXTTESTPROGRESSLISTENER_H +#define CPPUNIT_TEXTTESTPROGRESSLISTENER_H + +#include + + +CPPUNIT_NS_BEGIN + + +/*! + * \brief TestListener that show the status of each TestCase test result. + * \ingroup TrackingTestExecution + */ +class CPPUNIT_API TextTestProgressListener : public TestListener +{ +public: + /*! Constructs a TextTestProgressListener object. + */ + TextTestProgressListener(); + + /// Destructor. + virtual ~TextTestProgressListener(); + + void startTest( Test *test ); + + void addFailure( const TestFailure &failure ); + + void endTestRun( Test *test, + TestResult *eventManager ); + +private: + /// Prevents the use of the copy constructor. + TextTestProgressListener( const TextTestProgressListener © ); + + /// Prevents the use of the copy operator. + void operator =( const TextTestProgressListener © ); + +private: +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TEXTTESTPROGRESSLISTENER_H diff --git a/UnitTests/cppunit/include/cppunit/TextTestResult.h b/UnitTests/cppunit/include/cppunit/TextTestResult.h new file mode 100644 index 0000000..e7b1fa3 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TextTestResult.h @@ -0,0 +1,39 @@ +#ifndef CPPUNIT_TEXTTESTRESULT_H +#define CPPUNIT_TEXTTESTRESULT_H + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +class SourceLine; +class Exception; +class Test; + +/*! \brief Holds printable test result (DEPRECATED). + * \ingroup TrackingTestExecution + * + * deprecated Use class TextTestProgressListener and TextOutputter instead. + */ +class CPPUNIT_API TextTestResult : public TestResult, + public TestResultCollector +{ +public: + TextTestResult(); + + virtual void addFailure( const TestFailure &failure ); + virtual void startTest( Test *test ); + virtual void print( OStream &stream ); +}; + +/** insertion operator for easy output */ +CPPUNIT_API OStream &operator <<( OStream &stream, + TextTestResult &result ); + +CPPUNIT_NS_END + +#endif // CPPUNIT_TEXTTESTRESULT_H + + diff --git a/UnitTests/cppunit/include/cppunit/TextTestRunner.h b/UnitTests/cppunit/include/cppunit/TextTestRunner.h new file mode 100644 index 0000000..23890e0 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/TextTestRunner.h @@ -0,0 +1,6 @@ +#ifndef CPPUNIT_TEXTTESTRUNNER_H +#define CPPUNIT_TEXTTESTRUNNER_H + +#include + +#endif // CPPUNIT_TEXTTESTRUNNER_H diff --git a/UnitTests/cppunit/include/cppunit/XmlOutputter.h b/UnitTests/cppunit/include/cppunit/XmlOutputter.h new file mode 100644 index 0000000..0de9676 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/XmlOutputter.h @@ -0,0 +1,167 @@ +#ifndef CPPUNIT_XMLTESTRESULTOUTPUTTER_H +#define CPPUNIT_XMLTESTRESULTOUTPUTTER_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +class Test; +class TestFailure; +class TestResultCollector; +class XmlDocument; +class XmlElement; +class XmlOutputterHook; + + +/*! \brief Outputs a TestResultCollector in XML format. + * \ingroup WritingTestResult + * + * Save the test result as a XML stream. + * + * Additional datas can be added to the XML document using XmlOutputterHook. + * Hook are not owned by the XmlOutputter. They should be valid until + * destruction of the XmlOutputter. They can be removed with removeHook(). + * + * \see XmlDocument, XmlElement, XmlOutputterHook. + */ +class CPPUNIT_API XmlOutputter : public Outputter +{ +public: + /*! \brief Constructs a XmlOutputter object. + * \param result Result of the test run. + * \param stream Stream used to output the XML output. + * \param encoding Encoding used in the XML file (default is Latin-1). + */ + XmlOutputter( TestResultCollector *result, + OStream &stream, + std::string encoding = std::string("ISO-8859-1") ); + + /// Destructor. + virtual ~XmlOutputter(); + + /*! \brief Adds the specified hook to the outputter. + * \param hook Hook to add. Must not be \c NULL. + */ + virtual void addHook( XmlOutputterHook *hook ); + + /*! \brief Removes the specified hook from the outputter. + * \param hook Hook to remove. + */ + virtual void removeHook( XmlOutputterHook *hook ); + + /*! \brief Writes the specified result as an XML document to the stream. + * + * Refer to examples/cppunittest/XmlOutputterTest.cpp for example + * of use and XML document structure. + */ + virtual void write(); + + /*! \brief Sets the XSL style sheet used. + * + * \param styleSheet Name of the style sheet used. If empty, then no style sheet + * is used (default). + */ + virtual void setStyleSheet( const std::string &styleSheet ); + + /*! \brief set the output document as standalone or not. + * + * For the output document, specify wether it's a standalone XML + * document, or not. + * + * \param standalone if true, the output will be specified as standalone. + * if false, it will be not. + */ + virtual void setStandalone( bool standalone ); + + typedef CppUnitMap > FailedTests; + + /*! \brief Sets the root element and adds its children. + * + * Set the root element of the XML Document and add its child elements. + * + * For all hooks, call beginDocument() just after creating the root element (it + * is empty at this time), and endDocument() once all the datas have been added + * to the root element. + */ + virtual void setRootNode(); + + virtual void addFailedTests( FailedTests &failedTests, + XmlElement *rootNode ); + + virtual void addSuccessfulTests( FailedTests &failedTests, + XmlElement *rootNode ); + + /*! \brief Adds the statics element to the root node. + * + * Creates a new element containing statistics data and adds it to the root element. + * Then, for all hooks, call statisticsAdded(). + * \param rootNode Root element. + */ + virtual void addStatistics( XmlElement *rootNode ); + + /*! \brief Adds a failed test to the failed tests node. + * Creates a new element containing datas about the failed test, and adds it to + * the failed tests element. + * Then, for all hooks, call failTestAdded(). + */ + virtual void addFailedTest( Test *test, + TestFailure *failure, + int testNumber, + XmlElement *testsNode ); + + virtual void addFailureLocation( TestFailure *failure, + XmlElement *testElement ); + + + /*! \brief Adds a successful test to the successful tests node. + * Creates a new element containing datas about the successful test, and adds it to + * the successful tests element. + * Then, for all hooks, call successfulTestAdded(). + */ + virtual void addSuccessfulTest( Test *test, + int testNumber, + XmlElement *testsNode ); +protected: + virtual void fillFailedTestsMap( FailedTests &failedTests ); + +protected: + typedef CppUnitDeque Hooks; + + TestResultCollector *m_result; + OStream &m_stream; + std::string m_encoding; + std::string m_styleSheet; + XmlDocument *m_xml; + Hooks m_hooks; + +private: + /// Prevents the use of the copy constructor. + XmlOutputter( const XmlOutputter © ); + + /// Prevents the use of the copy operator. + void operator =( const XmlOutputter © ); + +private: +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + + +#endif // CPPUNIT_XMLTESTRESULTOUTPUTTER_H diff --git a/UnitTests/cppunit/include/cppunit/XmlOutputterHook.h b/UnitTests/cppunit/include/cppunit/XmlOutputterHook.h new file mode 100644 index 0000000..5ded3b1 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/XmlOutputterHook.h @@ -0,0 +1,163 @@ +#ifndef CPPUNIT_XMLOUTPUTTERHOOK_H +#define CPPUNIT_XMLOUTPUTTERHOOK_H + +#include + + +CPPUNIT_NS_BEGIN + + +class Test; +class TestFailure; +class XmlDocument; +class XmlElement; + + + +/*! \brief Hook to customize Xml output. + * + * XmlOutputterHook can be passed to XmlOutputter to customize the XmlDocument. + * + * Common customizations are: + * - adding some datas to successfull or failed test with + * failTestAdded() and successfulTestAdded(), + * - adding some statistics with statisticsAdded(), + * - adding other datas with beginDocument() or endDocument(). + * + * See examples/ClockerPlugIn which makes use of most the hook. + * + * Another simple example of an outputter hook is shown below. It may be + * used to add some meta information to your result files. In the example, + * the author name as well as the project name and test creation date is + * added to the head of the xml file. + * + * In order to make this information stored within the xml file, the virtual + * member function beginDocument() is overriden where a new + * XmlElement object is created. + * + * This element is simply added to the root node of the document which + * makes the information automatically being stored when the xml file + * is written. + * + * \code + * #include + * #include + * #include + * + * ... + * + * class MyXmlOutputterHook : public CppUnit::XmlOutputterHook + * { + * public: + * MyXmlOutputterHook(const std::string projectName, + * const std::string author) + * { + * m_projectName = projectName; + * m_author = author; + * }; + * + * virtual ~MyXmlOutputterHook() + * { + * }; + * + * void beginDocument(CppUnit::XmlDocument* document) + * { + * if (!document) + * return; + * + * // dump current time + * std::string szDate = CppUnit::StringTools::toString( (int)time(0) ); + * CppUnit::XmlElement* metaEl = new CppUnit::XmlElement("SuiteInfo", + * ""); + * + * metaEl->addElement( new CppUnit::XmlElement("Author", m_author) ); + * metaEl->addElement( new CppUnit::XmlElement("Project", m_projectName) ); + * metaEl->addElement( new CppUnit::XmlElement("Date", szDate ) ); + * + * document->rootElement().addElement(metaEl); + * }; + * private: + * std::string m_projectName; + * std::string m_author; + * }; + * \endcode + * + * Within your application's main code, you need to snap the hook + * object into your xml outputter object like shown below: + * + * \code + * CppUnit::TextUi::TestRunner runner; + * std::ofstream outputFile("testResults.xml"); + * + * CppUnit::XmlOutputter* outputter = new CppUnit::XmlOutputter( &runner.result(), + * outputFile ); + * MyXmlOutputterHook hook("myProject", "meAuthor"); + * outputter->addHook(&hook); + * runner.setOutputter(outputter); + * runner.addTest( VectorFixture::suite() ); + * runner.run(); + * outputFile.close(); + * \endcode + * + * This results into the following output: + * + * \code + * + * + * meAuthor + * myProject + * 1028143912 + * + * + * ... + * \endcode + * + * \see XmlOutputter, CppUnitTestPlugIn. + */ +class CPPUNIT_API XmlOutputterHook +{ +public: + /*! Called before any elements is added to the root element. + * \param document XML Document being created. + */ + virtual void beginDocument( XmlDocument *document ); + + /*! Called after adding all elements to the root element. + * \param document XML Document being created. + */ + virtual void endDocument( XmlDocument *document ); + + /*! Called after adding a fail test element. + * \param document XML Document being created. + * \param testElement \ element. + * \param test Test that failed. + * \param failure Test failure data. + */ + virtual void failTestAdded( XmlDocument *document, + XmlElement *testElement, + Test *test, + TestFailure *failure ); + + /*! Called after adding a successful test element. + * \param document XML Document being created. + * \param testElement \ element. + * \param test Test that was successful. + */ + virtual void successfulTestAdded( XmlDocument *document, + XmlElement *testElement, + Test *test ); + + /*! Called after adding the statistic element. + * \param document XML Document being created. + * \param statisticsElement \ element. + */ + virtual void statisticsAdded( XmlDocument *document, + XmlElement *statisticsElement ); + + virtual ~XmlOutputterHook() {} +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_XMLOUTPUTTERHOOK_H diff --git a/UnitTests/cppunit/include/cppunit/config-auto.h b/UnitTests/cppunit/include/cppunit/config-auto.h new file mode 100644 index 0000000..337baf7 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config-auto.h @@ -0,0 +1,179 @@ +#ifndef _INCLUDE_CPPUNIT_CONFIG_AUTO_H +#define _INCLUDE_CPPUNIT_CONFIG_AUTO_H 1 + +/* include/cppunit/config-auto.h. Generated automatically at end of configure. */ +/* config/config.h. Generated from config.h.in by configure. */ +/* config/config.h.in. Generated from configure.in by autoheader. */ + +/* define if library uses std::string::compare(string,pos,n) */ +/* #undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST */ + +/* define if the library defines strstream */ +#ifndef CPPUNIT_HAVE_CLASS_STRSTREAM +#define CPPUNIT_HAVE_CLASS_STRSTREAM 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_CMATH +#define CPPUNIT_HAVE_CMATH 1 +#endif + +/* Define if you have the GNU dld library. */ +/* #undef CPPUNIT_HAVE_DLD */ + +/* Define to 1 if you have the `dlerror' function. */ +#ifndef CPPUNIT_HAVE_DLERROR +#define CPPUNIT_HAVE_DLERROR 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_DLFCN_H +#define CPPUNIT_HAVE_DLFCN_H 1 +#endif + +/* Define to 1 if you have the `finite' function. */ +#ifndef CPPUNIT_HAVE_FINITE +#define CPPUNIT_HAVE_FINITE 1 +#endif + +/* define if the compiler supports GCC C++ ABI name demangling */ +#ifndef CPPUNIT_HAVE_GCC_ABI_DEMANGLE +#define CPPUNIT_HAVE_GCC_ABI_DEMANGLE 0 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_INTTYPES_H +#define CPPUNIT_HAVE_INTTYPES_H 1 +#endif + +/* define if compiler has isfinite */ +#ifndef CPPUNIT_HAVE_ISFINITE +#define CPPUNIT_HAVE_ISFINITE 1 +#endif + +/* Define if you have the libdl library or equivalent. */ +#ifndef CPPUNIT_HAVE_LIBDL +#define CPPUNIT_HAVE_LIBDL 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_MEMORY_H +#define CPPUNIT_HAVE_MEMORY_H 1 +#endif + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if the compiler supports Run-Time Type Identification */ +#ifndef CPPUNIT_HAVE_RTTI +#define CPPUNIT_HAVE_RTTI 0 +#endif + +/* Define if you have the shl_load function. */ +/* #undef CPPUNIT_HAVE_SHL_LOAD */ + +/* define if the compiler has stringstream */ +#ifndef CPPUNIT_HAVE_SSTREAM +#define CPPUNIT_HAVE_SSTREAM 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_STDINT_H +#define CPPUNIT_HAVE_STDINT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_STDLIB_H +#define CPPUNIT_HAVE_STDLIB_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_STRINGS_H +#define CPPUNIT_HAVE_STRINGS_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_STRING_H +#define CPPUNIT_HAVE_STRING_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_STRSTREAM +#define CPPUNIT_HAVE_STRSTREAM 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_SYS_STAT_H +#define CPPUNIT_HAVE_SYS_STAT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_SYS_TYPES_H +#define CPPUNIT_HAVE_SYS_TYPES_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef CPPUNIT_HAVE_UNISTD_H +#define CPPUNIT_HAVE_UNISTD_H 1 +#endif + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#ifndef CPPUNIT_LT_OBJDIR +#define CPPUNIT_LT_OBJDIR ".libs/" +#endif + +/* Name of package */ +#ifndef CPPUNIT_PACKAGE +#define CPPUNIT_PACKAGE "cppunit" +#endif + +/* Define to the address where bug reports for this package should be sent. */ +#ifndef CPPUNIT_PACKAGE_BUGREPORT +#define CPPUNIT_PACKAGE_BUGREPORT "" +#endif + +/* Define to the full name of this package. */ +#ifndef CPPUNIT_PACKAGE_NAME +#define CPPUNIT_PACKAGE_NAME "" +#endif + +/* Define to the full name and version of this package. */ +#ifndef CPPUNIT_PACKAGE_STRING +#define CPPUNIT_PACKAGE_STRING "" +#endif + +/* Define to the one symbol short name of this package. */ +#ifndef CPPUNIT_PACKAGE_TARNAME +#define CPPUNIT_PACKAGE_TARNAME "" +#endif + +/* Define to the home page for this package. */ +#ifndef CPPUNIT_PACKAGE_URL +#define CPPUNIT_PACKAGE_URL "" +#endif + +/* Define to the version of this package. */ +#ifndef CPPUNIT_PACKAGE_VERSION +#define CPPUNIT_PACKAGE_VERSION "" +#endif + +/* Define to 1 if you have the ANSI C header files. */ +#ifndef CPPUNIT_STDC_HEADERS +#define CPPUNIT_STDC_HEADERS 1 +#endif + +/* Define to 1 to use type_info::name() for class names */ +#ifndef CPPUNIT_USE_TYPEINFO_NAME +#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI +#endif + +/* Version number of package */ +#ifndef CPPUNIT_VERSION +#define CPPUNIT_VERSION "1.12.1" +#endif + +/* _INCLUDE_CPPUNIT_CONFIG_AUTO_H */ +#endif diff --git a/UnitTests/cppunit/include/cppunit/config/CppUnitApi.h b/UnitTests/cppunit/include/cppunit/config/CppUnitApi.h new file mode 100644 index 0000000..a068bbd --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config/CppUnitApi.h @@ -0,0 +1,33 @@ +#ifndef CPPUNIT_CONFIG_CPPUNITAPI +#define CPPUNIT_CONFIG_CPPUNITAPI + +#undef CPPUNIT_API + +#ifdef WIN32 + +// define CPPUNIT_DLL_BUILD when building CppUnit dll. +#ifdef CPPUNIT_BUILD_DLL +#define CPPUNIT_API __declspec(dllexport) +#endif + +// define CPPUNIT_DLL when linking to CppUnit dll. +#ifdef CPPUNIT_DLL +#define CPPUNIT_API __declspec(dllimport) +#endif + +#ifdef CPPUNIT_API +#undef CPPUNIT_NEED_DLL_DECL +#define CPPUNIT_NEED_DLL_DECL 1 +#endif + +#endif + + +#ifndef CPPUNIT_API +#define CPPUNIT_API +#undef CPPUNIT_NEED_DLL_DECL +#define CPPUNIT_NEED_DLL_DECL 0 +#endif + + +#endif // CPPUNIT_CONFIG_CPPUNITAPI diff --git a/UnitTests/cppunit/include/cppunit/config/SelectDllLoader.h b/UnitTests/cppunit/include/cppunit/config/SelectDllLoader.h new file mode 100644 index 0000000..dc1c011 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config/SelectDllLoader.h @@ -0,0 +1,76 @@ +#ifndef CPPUNIT_CONFIG_SELECTDLLLOADER_H +#define CPPUNIT_CONFIG_SELECTDLLLOADER_H + +/*! \file + * Selects DynamicLibraryManager implementation. + * + * Don't include this file directly. Include Portability.h instead. + */ + +/*! + * \def CPPUNIT_NO_TESTPLUGIN + * \brief If defined, then plug-in related classes and functions will not be compiled. + * + * \internal + * CPPUNIT_HAVE_WIN32_DLL_LOADER + * If defined, Win32 implementation of DynamicLibraryManager will be used. + * + * CPPUNIT_HAVE_BEOS_DLL_LOADER + * If defined, BeOs implementation of DynamicLibraryManager will be used. + * + * CPPUNIT_HAVE_UNIX_DLL_LOADER + * If defined, Unix implementation (dlfcn.h) of DynamicLibraryManager will be used. + */ + +/*! + * \def CPPUNIT_PLUGIN_EXPORT + * \ingroup WritingTestPlugIn + * \brief A macro to export a function from a dynamic library + * + * This macro export the C function following it from a dynamic library. + * Exporting the function makes it accessible to the DynamicLibraryManager. + * + * Example of usage: + * \code + * #include + * + * CPPUNIT_PLUGIN_EXPORT CppUnitTestPlugIn *CPPUNIT_PLUGIN_EXPORTED_NAME(void) + * { + * ... + * return &myPlugInInterface; + * } + * \endcode + */ + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +// Is WIN32 platform ? +#if defined(WIN32) +#define CPPUNIT_HAVE_WIN32_DLL_LOADER 1 +#undef CPPUNIT_PLUGIN_EXPORT +#define CPPUNIT_PLUGIN_EXPORT extern "C" __declspec(dllexport) + +// Is BeOS platform ? +#elif defined(__BEOS__) +#define CPPUNIT_HAVE_BEOS_DLL_LOADER 1 + +// Is Unix platform and have shl_load() (hp-ux) +#elif defined(CPPUNIT_HAVE_SHL_LOAD) +#define CPPUNIT_HAVE_UNIX_SHL_LOADER 1 + +// Is Unix platform and have include +#elif defined(CPPUNIT_HAVE_LIBDL) +#define CPPUNIT_HAVE_UNIX_DLL_LOADER 1 + +// Otherwise, disable support for DllLoader +#else +#define CPPUNIT_NO_TESTPLUGIN 1 +#endif + +#if !defined(CPPUNIT_PLUGIN_EXPORT) +#define CPPUNIT_PLUGIN_EXPORT extern "C" +#endif // !defined(CPPUNIT_PLUGIN_EXPORT) + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) + +#endif // CPPUNIT_CONFIG_SELECTDLLLOADER_H diff --git a/UnitTests/cppunit/include/cppunit/config/SourcePrefix.h b/UnitTests/cppunit/include/cppunit/config/SourcePrefix.h new file mode 100644 index 0000000..2334601 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config/SourcePrefix.h @@ -0,0 +1,14 @@ +#ifndef CPPUNIT_CONFIG_H_INCLUDED +#define CPPUNIT_CONFIG_H_INCLUDED + +#include + +#ifdef _MSC_VER +#pragma warning(disable: 4018 4284 4146) +#if _MSC_VER >= 1400 +#pragma warning(disable: 4996) // sprintf is deprecated +#endif +#endif + + +#endif // CPPUNIT_CONFIG_H_INCLUDED diff --git a/UnitTests/cppunit/include/cppunit/config/config-bcb5.h b/UnitTests/cppunit/include/cppunit/config/config-bcb5.h new file mode 100644 index 0000000..d491452 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config/config-bcb5.h @@ -0,0 +1,47 @@ +#ifndef _INCLUDE_CPPUNIT_CONFIG_BCB5_H +#define _INCLUDE_CPPUNIT_CONFIG_BCB5_H 1 + +#define HAVE_CMATH 1 + +/* include/cppunit/config-bcb5.h. Manually adapted from + include/cppunit/config-auto.h */ + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if library uses std::string::compare(string,pos,n) */ +#ifndef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST +#define CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST 0 +#endif + +/* Define if you have the header file. */ +#ifdef CPPUNIT_HAVE_DLFCN_H +#undef CPPUNIT_HAVE_DLFCN_H +#endif + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if the compiler supports Run-Time Type Identification */ +#ifndef CPPUNIT_HAVE_RTTI +#define CPPUNIT_HAVE_RTTI 1 +#endif + +/* Define to 1 to use type_info::name() for class names */ +#ifndef CPPUNIT_USE_TYPEINFO_NAME +#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI +#endif + +#define CPPUNIT_HAVE_SSTREAM 1 + +/* Name of package */ +#ifndef CPPUNIT_PACKAGE +#define CPPUNIT_PACKAGE "cppunit" +#endif + +/* _INCLUDE_CPPUNIT_CONFIG_BCB5_H */ +#endif diff --git a/UnitTests/cppunit/include/cppunit/config/config-evc4.h b/UnitTests/cppunit/include/cppunit/config/config-evc4.h new file mode 100644 index 0000000..a791698 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config/config-evc4.h @@ -0,0 +1,78 @@ +#ifndef _INCLUDE_CPPUNIT_CONFIG_EVC4_H +#define _INCLUDE_CPPUNIT_CONFIG_EVC4_H 1 + +#if _MSC_VER > 1000 // VC++ +#pragma warning( disable : 4786 ) // disable warning debug symbol > 255... +#endif // _MSC_VER > 1000 + +#define HAVE_CMATH 1 + +/* include/cppunit/config-msvc6.h. Manually adapted from + include/cppunit/config-auto.h */ + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if library uses std::string::compare(string,pos,n) */ +#ifdef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST +#undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST +#endif + +/* Define if you have the header file. */ +#ifdef CPPUNIT_HAVE_DLFCN_H +#undef CPPUNIT_HAVE_DLFCN_H +#endif + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if the compiler supports Run-Time Type Identification */ +#ifndef CPPUNIT_HAVE_RTTI +#define CPPUNIT_HAVE_RTTI 0 +#endif + +/* Define to 1 to use type_info::name() for class names */ +#ifndef CPPUNIT_USE_TYPEINFO_NAME +#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI +#endif + +#define CPPUNIT_NO_STREAM 1 +#define CPPUNIT_NO_ASSERT 1 + +#define CPPUNIT_HAVE_SSTREAM 0 + +/* Name of package */ +#ifndef CPPUNIT_PACKAGE +#define CPPUNIT_PACKAGE "cppunit" +#endif + + +// Compiler error location format for CompilerOutputter +// See class CompilerOutputter for format. +#undef CPPUNIT_COMPILER_LOCATION_FORMAT +#if _MSC_VER >= 1300 // VS 7.0 +# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l) : error : " +#else +# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l):" +#endif + +/* define to 1 if the compiler has _finite() */ +#ifndef CPPUNIT_HAVE__FINITE +#define CPPUNIT_HAVE__FINITE 1 +#endif + +// Uncomment to turn on STL wrapping => use this to test compilation. +// This will make CppUnit subclass std::vector & co to provide default +// parameter. +/*#define CPPUNIT_STD_NEED_ALLOCATOR 1 +#define CPPUNIT_STD_ALLOCATOR std::allocator +//#define CPPUNIT_NO_NAMESPACE 1 +*/ + + +/* _INCLUDE_CPPUNIT_CONFIG_EVC4_H */ +#endif diff --git a/UnitTests/cppunit/include/cppunit/config/config-mac.h b/UnitTests/cppunit/include/cppunit/config/config-mac.h new file mode 100644 index 0000000..4ace906 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config/config-mac.h @@ -0,0 +1,58 @@ +#ifndef _INCLUDE_CPPUNIT_CONFIG_MAC_H +#define _INCLUDE_CPPUNIT_CONFIG_MAC_H 1 + +/* MacOS X should be installed using the configure script. + This file is for other macs. + + It is not integrated into because we don't + know a suitable preprocessor symbol that will distinguish MacOS X + from other MacOS versions. Email us if you know the answer. +*/ + +/* define if library uses std::string::compare(string,pos,n) */ +#ifdef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST +#undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST +#endif + +/* define if the library defines strstream */ +#ifndef CPPUNIT_HAVE_CLASS_STRSTREAM +#define CPPUNIT_HAVE_CLASS_STRSTREAM 1 +#endif + +/* Define if you have the header file. */ +#ifdef CPPUNIT_HAVE_CMATH +#undef CPPUNIT_HAVE_CMATH +#endif + +/* Define if you have the header file. */ +#ifdef CPPUNIT_HAVE_DLFCN_H +#undef CPPUNIT_HAVE_DLFCN_H +#endif + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if the compiler supports Run-Time Type Identification */ +#ifndef CPPUNIT_HAVE_RTTI +#define CPPUNIT_HAVE_RTTI 1 +#endif + +/* define if the compiler has stringstream */ +#ifndef CPPUNIT_HAVE_SSTREAM +#define CPPUNIT_HAVE_SSTREAM 1 +#endif + +/* Define if you have the header file. */ +#ifndef CPPUNIT_HAVE_STRSTREAM +#define CPPUNIT_HAVE_STRSTREAM 1 +#endif + +/* Define to 1 to use type_info::name() for class names */ +#ifndef CPPUNIT_USE_TYPEINFO_NAME +#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI +#endif + +/* _INCLUDE_CPPUNIT_CONFIG_MAC_H */ +#endif diff --git a/UnitTests/cppunit/include/cppunit/config/config-msvc6.h b/UnitTests/cppunit/include/cppunit/config/config-msvc6.h new file mode 100644 index 0000000..54bce82 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/config/config-msvc6.h @@ -0,0 +1,86 @@ +#ifndef _INCLUDE_CPPUNIT_CONFIG_MSVC6_H +#define _INCLUDE_CPPUNIT_CONFIG_MSVC6_H 1 + +#if _MSC_VER > 1000 // VC++ +#pragma warning( disable : 4786 ) // disable warning debug symbol > 255... +#endif // _MSC_VER > 1000 + +#define HAVE_CMATH 1 + +/* include/cppunit/config-msvc6.h. Manually adapted from + include/cppunit/config-auto.h */ + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if library uses std::string::compare(string,pos,n) */ +#ifdef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST +#undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST +#endif + +/* Define if you have the header file. */ +#ifdef CPPUNIT_HAVE_DLFCN_H +#undef CPPUNIT_HAVE_DLFCN_H +#endif + +/* define to 1 if the compiler implements namespaces */ +#ifndef CPPUNIT_HAVE_NAMESPACES +#define CPPUNIT_HAVE_NAMESPACES 1 +#endif + +/* define if the compiler supports Run-Time Type Identification */ +#ifndef CPPUNIT_HAVE_RTTI +# ifdef _CPPRTTI // Defined by the compiler option /GR +# define CPPUNIT_HAVE_RTTI 1 +# else +# define CPPUNIT_HAVE_RTTI 0 +# endif +#endif + +/* Define to 1 to use type_info::name() for class names */ +#ifndef CPPUNIT_USE_TYPEINFO_NAME +#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI +#endif + +#define CPPUNIT_HAVE_SSTREAM 1 + +/* Name of package */ +#ifndef CPPUNIT_PACKAGE +#define CPPUNIT_PACKAGE "cppunit" +#endif + + +// Compiler error location format for CompilerOutputter +// See class CompilerOutputter for format. +#undef CPPUNIT_COMPILER_LOCATION_FORMAT +#if _MSC_VER >= 1300 // VS 7.0 +# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l) : error : " +#else +# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l):" +#endif + +// Define to 1 if the compiler support C++ style cast. +#define CPPUNIT_HAVE_CPP_CAST 1 + +/* define to 1 if the compiler has _finite() */ +#ifndef CPPUNIT_HAVE__FINITE +#define CPPUNIT_HAVE__FINITE 1 +#endif + + +// Uncomment to turn on STL wrapping => use this to test compilation. +// This will make CppUnit subclass std::vector & co to provide default +// parameter. +/*#define CPPUNIT_STD_NEED_ALLOCATOR 1 +#define CPPUNIT_STD_ALLOCATOR std::allocator +//#define CPPUNIT_NO_NAMESPACE 1 +*/ + +#if _MSC_VER >= 1300 // VS 7.0 +#define CPPUNIT_UNIQUE_COUNTER __COUNTER__ +#endif // if _MSC_VER >= 1300 // VS 7.0 + +/* _INCLUDE_CPPUNIT_CONFIG_MSVC6_H */ +#endif diff --git a/UnitTests/cppunit/include/cppunit/extensions/AutoRegisterSuite.h b/UnitTests/cppunit/include/cppunit/extensions/AutoRegisterSuite.h new file mode 100644 index 0000000..e04adb5 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/AutoRegisterSuite.h @@ -0,0 +1,83 @@ +#ifndef CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H +#define CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +/*! \brief (Implementation) Automatically register the test suite of the specified type. + * + * You should not use this class directly. Instead, use the following macros: + * - CPPUNIT_TEST_SUITE_REGISTRATION() + * - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() + * + * This object will register the test returned by TestCaseType::suite() + * when constructed to the test registry. + * + * This object is intented to be used as a static variable. + * + * + * \param TestCaseType Type of the test case which suite is registered. + * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION + * \see CppUnit::TestFactoryRegistry. + */ +template +class AutoRegisterSuite +{ +public: + /** Auto-register the suite factory in the global registry. + */ + AutoRegisterSuite() + : m_registry( &TestFactoryRegistry::getRegistry() ) + { + m_registry->registerFactory( &m_factory ); + } + + /** Auto-register the suite factory in the specified registry. + * \param name Name of the registry. + */ + AutoRegisterSuite( const std::string &name ) + : m_registry( &TestFactoryRegistry::getRegistry( name ) ) + { + m_registry->registerFactory( &m_factory ); + } + + ~AutoRegisterSuite() + { + if ( TestFactoryRegistry::isValid() ) + m_registry->unregisterFactory( &m_factory ); + } + +private: + TestFactoryRegistry *m_registry; + TestSuiteFactory m_factory; +}; + + +/*! \brief (Implementation) Automatically adds a registry into another registry. + * + * Don't use this class. Use the macros CPPUNIT_REGISTRY_ADD() and + * CPPUNIT_REGISTRY_ADD_TO_DEFAULT() instead. + */ +class AutoRegisterRegistry +{ +public: + AutoRegisterRegistry( const std::string &which, + const std::string &to ) + { + TestFactoryRegistry::getRegistry( to ).addRegistry( which ); + } + + AutoRegisterRegistry( const std::string &which ) + { + TestFactoryRegistry::getRegistry().addRegistry( which ); + } +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H diff --git a/UnitTests/cppunit/include/cppunit/extensions/ExceptionTestCaseDecorator.h b/UnitTests/cppunit/include/cppunit/extensions/ExceptionTestCaseDecorator.h new file mode 100644 index 0000000..2929a00 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/ExceptionTestCaseDecorator.h @@ -0,0 +1,104 @@ +#ifndef CPPUNIT_EXTENSIONS_EXCEPTIONTESTCASEDECORATOR_H +#define CPPUNIT_EXTENSIONS_EXCEPTIONTESTCASEDECORATOR_H + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +/*! \brief Expected exception test case decorator. + * + * A decorator used to assert that a specific test case should throw an + * exception of a given type. + * + * You should use this class only if you need to check the exception object + * state (that a specific cause is set for example). If you don't need to + * do that, you might consider using CPPUNIT_TEST_EXCEPTION() instead. + * + * Intended use is to subclass and override checkException(). Example: + * + * \code + * + * class NetworkErrorTestCaseDecorator : + * public ExceptionTestCaseDecorator + * { + * public: + * NetworkErrorTestCaseDecorator( NetworkError::Cause expectedCause ) + * : m_expectedCause( expectedCause ) + * { + * } + * private: + * void checkException( ExpectedExceptionType &e ) + * { + * CPPUNIT_ASSERT_EQUAL( m_expectedCause, e.getCause() ); + * } + * + * NetworkError::Cause m_expectedCause; + * }; + * \endcode + * + */ +template +class ExceptionTestCaseDecorator : public TestCaseDecorator +{ +public: + typedef ExpectedException ExpectedExceptionType; + + /*! \brief Decorates the specified test. + * \param test TestCase to decorate. Assumes ownership of the test. + */ + ExceptionTestCaseDecorator( TestCase *test ) + : TestCaseDecorator( test ) + { + } + + /*! \brief Checks that the expected exception is thrown by the decorated test. + * is thrown. + * + * Calls the decorated test runTest() and checks that an exception of + * type ExpectedException is thrown. Call checkException() passing the + * exception that was caught so that some assertions can be made if + * needed. + */ + void runTest() + { + try + { + TestCaseDecorator::runTest(); + } + catch ( ExpectedExceptionType &e ) + { + checkException( e ); + return; + } + + // Moved outside the try{} statement to handle the case where the + // expected exception type is Exception (expecting assertion failure). +#if CPPUNIT_USE_TYPEINFO_NAME + throw Exception( Message( + "expected exception not thrown", + "Expected exception type: " + + TypeInfoHelper::getClassName( + typeid( ExpectedExceptionType ) ) ) ); +#else + throw Exception( Message("expected exception not thrown") ); +#endif + } + +private: + /*! \brief Called when the exception is caught. + * + * Should be overriden to check the exception. + */ + virtual void checkException( ExpectedExceptionType & ) + { + } +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_EXTENSIONS_EXCEPTIONTESTCASEDECORATOR_H + diff --git a/UnitTests/cppunit/include/cppunit/extensions/HelperMacros.h b/UnitTests/cppunit/include/cppunit/extensions/HelperMacros.h new file mode 100644 index 0000000..12431e4 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/HelperMacros.h @@ -0,0 +1,541 @@ +// ////////////////////////////////////////////////////////////////////////// +// Header file HelperMacros.h +// (c)Copyright 2000, Baptiste Lepilleur. +// Created: 2001/04/15 +// ////////////////////////////////////////////////////////////////////////// +#ifndef CPPUNIT_EXTENSIONS_HELPERMACROS_H +#define CPPUNIT_EXTENSIONS_HELPERMACROS_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +/*! \addtogroup WritingTestFixture Writing test fixture + */ +/** @{ + */ + + +/** \file + * Macros intended to ease the definition of test suites. + * + * The macros + * CPPUNIT_TEST_SUITE(), CPPUNIT_TEST(), and CPPUNIT_TEST_SUITE_END() + * are designed to facilitate easy creation of a test suite. + * For example, + * + * \code + * #include + * class MyTest : public CppUnit::TestFixture { + * CPPUNIT_TEST_SUITE( MyTest ); + * CPPUNIT_TEST( testEquality ); + * CPPUNIT_TEST( testSetName ); + * CPPUNIT_TEST_SUITE_END(); + * public: + * void testEquality(); + * void testSetName(); + * }; + * \endcode + * + * The effect of these macros is to define two methods in the + * class MyTest. The first method is an auxiliary function + * named registerTests that you will not need to call directly. + * The second function + * \code static CppUnit::TestSuite *suite()\endcode + * returns a pointer to the suite of tests defined by the CPPUNIT_TEST() + * macros. + * + * Rather than invoking suite() directly, + * the macro CPPUNIT_TEST_SUITE_REGISTRATION() is + * used to create a static variable that automatically + * registers its test suite in a global registry. + * The registry yields a Test instance containing all the + * registered suites. + * \code + * CPPUNIT_TEST_SUITE_REGISTRATION( MyTest ); + * CppUnit::Test* tp = + * CppUnit::TestFactoryRegistry::getRegistry().makeTest(); + * \endcode + * + * The test suite macros can even be used with templated test classes. + * For example: + * + * \code + * template + * class StringTest : public CppUnit::TestFixture { + * CPPUNIT_TEST_SUITE( StringTest ); + * CPPUNIT_TEST( testAppend ); + * CPPUNIT_TEST_SUITE_END(); + * public: + * ... + * }; + * \endcode + * + * You need to add in an implementation file: + * + * \code + * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest ); + * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest ); + * \endcode + */ + + +/*! \brief Begin test suite + * + * This macro starts the declaration of a new test suite. + * Use CPPUNIT_TEST_SUB_SUITE() instead, if you wish to include the + * test suite of the parent class. + * + * \param ATestFixtureType Type of the test case class. This type \b MUST + * be derived from TestFixture. + * \see CPPUNIT_TEST_SUB_SUITE, CPPUNIT_TEST, CPPUNIT_TEST_SUITE_END, + * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_EXCEPTION, CPPUNIT_TEST_FAIL. + */ +#define CPPUNIT_TEST_SUITE( ATestFixtureType ) \ + public: \ + typedef ATestFixtureType TestFixtureType; \ + \ + private: \ + static const CPPUNIT_NS::TestNamer &getTestNamer__() \ + { \ + static CPPUNIT_TESTNAMER_DECL( testNamer, ATestFixtureType ); \ + return testNamer; \ + } \ + \ + public: \ + typedef CPPUNIT_NS::TestSuiteBuilderContext \ + TestSuiteBuilderContextType; \ + \ + static void \ + addTestsToSuite( CPPUNIT_NS::TestSuiteBuilderContextBase &baseContext ) \ + { \ + TestSuiteBuilderContextType context( baseContext ) + + +/*! \brief Begin test suite (includes parent suite) + * + * This macro may only be used in a class whose parent class + * defines a test suite using CPPUNIT_TEST_SUITE() or CPPUNIT_TEST_SUB_SUITE(). + * + * This macro begins the declaration of a test suite, in the same + * manner as CPPUNIT_TEST_SUITE(). In addition, the test suite of the + * parent is automatically inserted in the test suite being + * defined. + * + * Here is an example: + * + * \code + * #include + * class MySubTest : public MyTest { + * CPPUNIT_TEST_SUB_SUITE( MySubTest, MyTest ); + * CPPUNIT_TEST( testAdd ); + * CPPUNIT_TEST( testSub ); + * CPPUNIT_TEST_SUITE_END(); + * public: + * void testAdd(); + * void testSub(); + * }; + * \endcode + * + * \param ATestFixtureType Type of the test case class. This type \b MUST + * be derived from TestFixture. + * \param ASuperClass Type of the parent class. + * \see CPPUNIT_TEST_SUITE. + */ +#define CPPUNIT_TEST_SUB_SUITE( ATestFixtureType, ASuperClass ) \ + public: \ + typedef ASuperClass ParentTestFixtureType; \ + private: \ + CPPUNIT_TEST_SUITE( ATestFixtureType ); \ + ParentTestFixtureType::addTestsToSuite( baseContext ) + + +/*! \brief End declaration of the test suite. + * + * After this macro, member access is set to "private". + * + * \see CPPUNIT_TEST_SUITE. + * \see CPPUNIT_TEST_SUITE_REGISTRATION. + */ +#define CPPUNIT_TEST_SUITE_END() \ + } \ + \ + static CPPUNIT_NS::TestSuite *suite() \ + { \ + const CPPUNIT_NS::TestNamer &namer = getTestNamer__(); \ + std::auto_ptr suite( \ + new CPPUNIT_NS::TestSuite( namer.getFixtureName() )); \ + CPPUNIT_NS::ConcretTestFixtureFactory factory; \ + CPPUNIT_NS::TestSuiteBuilderContextBase context( *suite.get(), \ + namer, \ + factory ); \ + TestFixtureType::addTestsToSuite( context ); \ + return suite.release(); \ + } \ + private: /* dummy typedef so that the macro can still end with ';'*/ \ + typedef int CppUnitDummyTypedefForSemiColonEnding__ + +/*! \brief End declaration of an abstract test suite. + * + * Use this macro to indicate that the %TestFixture is abstract. No + * static suite() method will be declared. + * + * After this macro, member access is set to "private". + * + * Here is an example of usage: + * + * The abstract test fixture: + * \code + * #include + * class AbstractDocument; + * class AbstractDocumentTest : public CppUnit::TestFixture { + * CPPUNIT_TEST_SUITE( AbstractDocumentTest ); + * CPPUNIT_TEST( testInsertText ); + * CPPUNIT_TEST_SUITE_END_ABSTRACT(); + * public: + * void testInsertText(); + * + * void setUp() + * { + * m_document = makeDocument(); + * } + * + * void tearDown() + * { + * delete m_document; + * } + * protected: + * virtual AbstractDocument *makeDocument() =0; + * + * AbstractDocument *m_document; + * };\endcode + * + * The concret test fixture: + * \code + * class RichTextDocumentTest : public AbstractDocumentTest { + * CPPUNIT_TEST_SUB_SUITE( RichTextDocumentTest, AbstractDocumentTest ); + * CPPUNIT_TEST( testInsertFormatedText ); + * CPPUNIT_TEST_SUITE_END(); + * public: + * void testInsertFormatedText(); + * protected: + * AbstractDocument *makeDocument() + * { + * return new RichTextDocument(); + * } + * };\endcode + * + * \see CPPUNIT_TEST_SUB_SUITE. + * \see CPPUNIT_TEST_SUITE_REGISTRATION. + */ +#define CPPUNIT_TEST_SUITE_END_ABSTRACT() \ + } \ + private: /* dummy typedef so that the macro can still end with ';'*/ \ + typedef int CppUnitDummyTypedefForSemiColonEnding__ + + +/*! \brief Add a test to the suite (for custom test macro). + * + * The specified test will be added to the test suite being declared. This macro + * is intended for \e advanced usage, to extend %CppUnit by creating new macro such + * as CPPUNIT_TEST_EXCEPTION()... + * + * Between macro CPPUNIT_TEST_SUITE() and CPPUNIT_TEST_SUITE_END(), you can assume + * that the following variables can be used: + * \code + * typedef TestSuiteBuilder TestSuiteBuilderType; + * TestSuiteBuilderType &context; + * \endcode + * + * \c context can be used to name test case, create new test fixture instance, + * or add test case to the test fixture suite. + * + * Below is an example that show how to use this macro to create new macro to add + * test to the fixture suite. The macro below show how you would add a new type + * of test case which fails if the execution last more than a given time limit. + * It relies on an imaginary TimeOutTestCaller class which has an interface similar + * to TestCaller. + * + * \code + * #define CPPUNITEX_TEST_TIMELIMIT( testMethod, timeLimit ) \ + * CPPUNIT_TEST_SUITE_ADD_TEST( (new TimeOutTestCaller( \ + * namer.getTestNameFor( #testMethod ), \ + * &TestFixtureType::testMethod, \ + * factory.makeFixture(), \ + * timeLimit ) ) ) + * + * class PerformanceTest : CppUnit::TestFixture + * { + * public: + * CPPUNIT_TEST_SUITE( PerformanceTest ); + * CPPUNITEX_TEST_TIMELIMIT( testSortReverseOrder, 5.0 ); + * CPPUNIT_TEST_SUITE_END(); + * + * void testSortReverseOrder(); + * }; + * \endcode + * + * \param test Test to add to the suite. Must be a subclass of Test. The test name + * should have been obtained using TestNamer::getTestNameFor(). + */ +#define CPPUNIT_TEST_SUITE_ADD_TEST( test ) \ + context.addTest( test ) + +/*! \brief Add a method to the suite. + * \param testMethod Name of the method of the test case to add to the + * suite. The signature of the method must be of + * type: void testMethod(); + * \see CPPUNIT_TEST_SUITE. + */ +#define CPPUNIT_TEST( testMethod ) \ + CPPUNIT_TEST_SUITE_ADD_TEST( \ + ( new CPPUNIT_NS::TestCaller( \ + context.getTestNameFor( #testMethod), \ + &TestFixtureType::testMethod, \ + context.makeFixture() ) ) ) + +/*! \brief Add a test which fail if the specified exception is not caught. + * + * Example: + * \code + * #include + * #include + * class MyTest : public CppUnit::TestFixture { + * CPPUNIT_TEST_SUITE( MyTest ); + * CPPUNIT_TEST_EXCEPTION( testVectorAtThrow, std::invalid_argument ); + * CPPUNIT_TEST_SUITE_END(); + * public: + * void testVectorAtThrow() + * { + * std::vector v; + * v.at( 1 ); // must throw exception std::invalid_argument + * } + * }; + * \endcode + * + * \param testMethod Name of the method of the test case to add to the suite. + * \param ExceptionType Type of the exception that must be thrown by the test + * method. + * \deprecated Use the assertion macro CPPUNIT_ASSERT_THROW instead. + */ +#define CPPUNIT_TEST_EXCEPTION( testMethod, ExceptionType ) \ + CPPUNIT_TEST_SUITE_ADD_TEST( \ + (new CPPUNIT_NS::ExceptionTestCaseDecorator< ExceptionType >( \ + new CPPUNIT_NS::TestCaller< TestFixtureType >( \ + context.getTestNameFor( #testMethod ), \ + &TestFixtureType::testMethod, \ + context.makeFixture() ) ) ) ) + +/*! \brief Adds a test case which is excepted to fail. + * + * The added test case expect an assertion to fail. You usually used that type + * of test case when testing custom assertion macros. + * + * \code + * CPPUNIT_TEST_FAIL( testAssertFalseFail ); + * + * void testAssertFalseFail() + * { + * CPPUNIT_ASSERT( false ); + * } + * \endcode + * \see CreatingNewAssertions. + * \deprecated Use the assertion macro CPPUNIT_ASSERT_ASSERTION_FAIL instead. + */ +#define CPPUNIT_TEST_FAIL( testMethod ) \ + CPPUNIT_TEST_EXCEPTION( testMethod, CPPUNIT_NS::Exception ) + +/*! \brief Adds some custom test cases. + * + * Use this to add one or more test cases to the fixture suite. The specified + * method is called with a context parameter that can be used to name, + * instantiate fixture, and add instantiated test case to the fixture suite. + * The specified method must have the following signature: + * \code + * static void aMethodName( TestSuiteBuilderContextType &context ); + * \endcode + * + * \c TestSuiteBuilderContextType is typedef to + * TestSuiteBuilderContext declared by CPPUNIT_TEST_SUITE(). + * + * Here is an example that add two custom tests: + * + * \code + * #include + * + * class MyTest : public CppUnit::TestFixture { + * CPPUNIT_TEST_SUITE( MyTest ); + * CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( addTimeOutTests ); + * CPPUNIT_TEST_SUITE_END(); + * public: + * static void addTimeOutTests( TestSuiteBuilderContextType &context ) + * { + * context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test1" ) ), + * &MyTest::test1, + * context.makeFixture(), + * 5.0 ); + * context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test2" ) ), + * &MyTest::test2, + * context.makeFixture(), + * 5.0 ); + * } + * + * void test1() + * { + * // Do some test that may never end... + * } + * + * void test2() + * { + * // Do some test that may never end... + * } + * }; + * \endcode + * @param testAdderMethod Name of the method called to add the test cases. + */ +#define CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( testAdderMethod ) \ + testAdderMethod( context ) + +/*! \brief Adds a property to the test suite builder context. + * \param APropertyKey Key of the property to add. + * \param APropertyValue Value for the added property. + * Example: + * \code + * CPPUNIT_TEST_SUITE_PROPERTY("XmlFileName", "paraTest.xml"); \endcode + */ +#define CPPUNIT_TEST_SUITE_PROPERTY( APropertyKey, APropertyValue ) \ + context.addProperty( std::string(APropertyKey), \ + std::string(APropertyValue) ) + +/** @} + */ + + +/*! Adds the specified fixture suite to the unnamed registry. + * \ingroup CreatingTestSuite + * + * This macro declares a static variable whose construction + * causes a test suite factory to be inserted in a global registry + * of such factories. The registry is available by calling + * the static function CppUnit::TestFactoryRegistry::getRegistry(). + * + * \param ATestFixtureType Type of the test case class. + * \warning This macro should be used only once per line of code (the line + * number is used to name a hidden static variable). + * \see CPPUNIT_TEST_SUITE_NAMED_REGISTRATION + * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT + * \see CPPUNIT_REGISTRY_ADD + * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite, + * CppUnit::TestFactoryRegistry. + */ +#define CPPUNIT_TEST_SUITE_REGISTRATION( ATestFixtureType ) \ + static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType > \ + CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ ) + + +/** Adds the specified fixture suite to the specified registry suite. + * \ingroup CreatingTestSuite + * + * This macro declares a static variable whose construction + * causes a test suite factory to be inserted in the global registry + * suite of the specified name. The registry is available by calling + * the static function CppUnit::TestFactoryRegistry::getRegistry(). + * + * For the suite name, use a string returned by a static function rather + * than a hardcoded string. That way, you can know what are the name of + * named registry and you don't risk mistyping the registry name. + * + * \code + * // MySuites.h + * namespace MySuites { + * std::string math() { + * return "Math"; + * } + * } + * + * // ComplexNumberTest.cpp + * #include "MySuites.h" + * + * CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ComplexNumberTest, MySuites::math() ); + * \endcode + * + * \param ATestFixtureType Type of the test case class. + * \param suiteName Name of the global registry suite the test suite is + * registered into. + * \warning This macro should be used only once per line of code (the line + * number is used to name a hidden static variable). + * \see CPPUNIT_TEST_SUITE_REGISTRATION + * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT + * \see CPPUNIT_REGISTRY_ADD + * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite, + * CppUnit::TestFactoryRegistry.. + */ +#define CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ATestFixtureType, suiteName ) \ + static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType > \ + CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ )(suiteName) + +/*! Adds that the specified registry suite to another registry suite. + * \ingroup CreatingTestSuite + * + * Use this macros to automatically create test registry suite hierarchy. For example, + * if you want to create the following hierarchy: + * - Math + * - IntegerMath + * - FloatMath + * - FastFloat + * - StandardFloat + * + * You can do this automatically with: + * \code + * CPPUNIT_REGISTRY_ADD( "FastFloat", "FloatMath" ); + * CPPUNIT_REGISTRY_ADD( "IntegerMath", "Math" ); + * CPPUNIT_REGISTRY_ADD( "FloatMath", "Math" ); + * CPPUNIT_REGISTRY_ADD( "StandardFloat", "FloatMath" ); + * \endcode + * + * There is no specific order of declaration. Think of it as declaring links. + * + * You register the test in each suite using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + * + * \param which Name of the registry suite to add to the registry suite named \a to. + * \param to Name of the registry suite \a which is added to. + * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + */ +#define CPPUNIT_REGISTRY_ADD( which, to ) \ + static CPPUNIT_NS::AutoRegisterRegistry \ + CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which, to ) + +/*! Adds that the specified registry suite to the default registry suite. + * \ingroup CreatingTestSuite + * + * This macro is just like CPPUNIT_REGISTRY_ADD except the specified registry + * suite is added to the default suite (root suite). + * + * \param which Name of the registry suite to add to the default registry suite. + * \see CPPUNIT_REGISTRY_ADD. + */ +#define CPPUNIT_REGISTRY_ADD_TO_DEFAULT( which ) \ + static CPPUNIT_NS::AutoRegisterRegistry \ + CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which ) + +// Backwards compatibility +// (Not tested!) + +#if CPPUNIT_ENABLE_CU_TEST_MACROS + +#define CU_TEST_SUITE(tc) CPPUNIT_TEST_SUITE(tc) +#define CU_TEST_SUB_SUITE(tc,sc) CPPUNIT_TEST_SUB_SUITE(tc,sc) +#define CU_TEST(tm) CPPUNIT_TEST(tm) +#define CU_TEST_SUITE_END() CPPUNIT_TEST_SUITE_END() +#define CU_TEST_SUITE_REGISTRATION(tc) CPPUNIT_TEST_SUITE_REGISTRATION(tc) + +#endif + + +#endif // CPPUNIT_EXTENSIONS_HELPERMACROS_H diff --git a/UnitTests/cppunit/include/cppunit/extensions/Orthodox.h b/UnitTests/cppunit/include/cppunit/extensions/Orthodox.h new file mode 100644 index 0000000..7221259 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/Orthodox.h @@ -0,0 +1,95 @@ +#ifndef CPPUNIT_EXTENSIONS_ORTHODOX_H +#define CPPUNIT_EXTENSIONS_ORTHODOX_H + +#include + +CPPUNIT_NS_BEGIN + + +/* + * Orthodox performs a simple set of tests on an arbitary + * class to make sure that it supports at least the + * following operations: + * + * default construction - constructor + * equality/inequality - operator== && operator!= + * assignment - operator= + * negation - operator! + * safe passage - copy construction + * + * If operations for each of these are not declared + * the template will not instantiate. If it does + * instantiate, tests are performed to make sure + * that the operations have correct semantics. + * + * Adding an orthodox test to a suite is very + * easy: + * + * public: Test *suite () { + * TestSuite *suiteOfTests = new TestSuite; + * suiteOfTests->addTest (new ComplexNumberTest ("testAdd"); + * suiteOfTests->addTest (new TestCaller > ()); + * return suiteOfTests; + * } + * + * Templated test cases be very useful when you are want to + * make sure that a group of classes have the same form. + * + * see TestSuite + */ + + +template class Orthodox : public TestCase +{ +public: + Orthodox () : TestCase ("Orthodox") {} + +protected: + ClassUnderTest call (ClassUnderTest object); + void runTest (); + + +}; + + +// Run an orthodoxy test +template void Orthodox::runTest () +{ + // make sure we have a default constructor + ClassUnderTest a, b, c; + + // make sure we have an equality operator + CPPUNIT_ASSERT (a == b); + + // check the inverse + b.operator= (a.operator! ()); + CPPUNIT_ASSERT (a != b); + + // double inversion + b = !!a; + CPPUNIT_ASSERT (a == b); + + // invert again + b = !a; + + // check calls + c = a; + CPPUNIT_ASSERT (c == call (a)); + + c = b; + CPPUNIT_ASSERT (c == call (b)); + +} + + +// Exercise a call +template +ClassUnderTest Orthodox::call (ClassUnderTest object) +{ + return object; +} + + +CPPUNIT_NS_END + +#endif diff --git a/UnitTests/cppunit/include/cppunit/extensions/RepeatedTest.h b/UnitTests/cppunit/include/cppunit/extensions/RepeatedTest.h new file mode 100644 index 0000000..390ce48 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/RepeatedTest.h @@ -0,0 +1,43 @@ +#ifndef CPPUNIT_EXTENSIONS_REPEATEDTEST_H +#define CPPUNIT_EXTENSIONS_REPEATEDTEST_H + +#include +#include + +CPPUNIT_NS_BEGIN + + +class Test; +class TestResult; + + +/*! \brief Decorator that runs a test repeatedly. + * + * Does not assume ownership of the test it decorates + */ +class CPPUNIT_API RepeatedTest : public TestDecorator +{ +public: + RepeatedTest( Test *test, + int timesRepeat ) : + TestDecorator( test ), + m_timesRepeat(timesRepeat) + { + } + + void run( TestResult *result ); + + int countTestCases() const; + +private: + RepeatedTest( const RepeatedTest & ); + void operator=( const RepeatedTest & ); + + const int m_timesRepeat; +}; + + +CPPUNIT_NS_END + + +#endif // CPPUNIT_EXTENSIONS_REPEATEDTEST_H diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestCaseDecorator.h b/UnitTests/cppunit/include/cppunit/extensions/TestCaseDecorator.h new file mode 100644 index 0000000..3a15ba9 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestCaseDecorator.h @@ -0,0 +1,40 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTCASEDECORATOR_H +#define CPPUNIT_EXTENSIONS_TESTCASEDECORATOR_H + +#include +#include + +CPPUNIT_NS_BEGIN + + +/*! \brief Decorator for Test cases. + * + * TestCaseDecorator provides an alternate means to extend functionality + * of a test class without subclassing the test. Instead, one can + * subclass the decorater and use it to wrap the test class. + * + * Does not assume ownership of the test it decorates + */ +class CPPUNIT_API TestCaseDecorator : public TestCase +{ +public: + TestCaseDecorator( TestCase *test ); + ~TestCaseDecorator(); + + std::string getName() const; + + void setUp(); + + void tearDown(); + + void runTest(); + +protected: + TestCase *m_test; +}; + + +CPPUNIT_NS_END + +#endif + diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestDecorator.h b/UnitTests/cppunit/include/cppunit/extensions/TestDecorator.h new file mode 100644 index 0000000..59d9a30 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestDecorator.h @@ -0,0 +1,49 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTDECORATOR_H +#define CPPUNIT_EXTENSIONS_TESTDECORATOR_H + +#include +#include + +CPPUNIT_NS_BEGIN + + +class TestResult; + + +/*! \brief Decorator for Tests. + * + * TestDecorator provides an alternate means to extend functionality + * of a test class without subclassing the test. Instead, one can + * subclass the decorater and use it to wrap the test class. + * + * Does not assume ownership of the test it decorates + */ +class CPPUNIT_API TestDecorator : public Test +{ +public: + TestDecorator( Test *test ); + ~TestDecorator(); + + int countTestCases() const; + + std::string getName() const; + + void run( TestResult *result ); + + int getChildTestCount() const; + +protected: + Test *doGetChildTestAt( int index ) const; + + Test *m_test; + +private: + TestDecorator( const TestDecorator &); + void operator =( const TestDecorator & ); +}; + + +CPPUNIT_NS_END + +#endif + diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestFactory.h b/UnitTests/cppunit/include/cppunit/extensions/TestFactory.h new file mode 100644 index 0000000..214d353 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestFactory.h @@ -0,0 +1,27 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTFACTORY_H +#define CPPUNIT_EXTENSIONS_TESTFACTORY_H + +#include + +CPPUNIT_NS_BEGIN + + +class Test; + +/*! \brief Abstract Test factory. + */ +class CPPUNIT_API TestFactory +{ +public: + virtual ~TestFactory() {} + + /*! Makes a new test. + * \return A new Test. + */ + virtual Test* makeTest() = 0; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_EXTENSIONS_TESTFACTORY_H diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestFactoryRegistry.h b/UnitTests/cppunit/include/cppunit/extensions/TestFactoryRegistry.h new file mode 100644 index 0000000..fc8723e --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestFactoryRegistry.h @@ -0,0 +1,182 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H +#define CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +class TestSuite; + +#if CPPUNIT_NEED_DLL_DECL +// template class CPPUNIT_API std::set; +#endif + + +/*! \brief Registry for TestFactory. + * \ingroup CreatingTestSuite + * + * Notes that the registry \b DON'T assumes lifetime control for any registered tests + * anymore. + * + * The default registry is the registry returned by getRegistry() with the + * default name parameter value. + * + * To register tests, use the macros: + * - CPPUNIT_TEST_SUITE_REGISTRATION(): to add tests in the default registry. + * - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(): to add tests in a named registry. + * + * Example 1: retreiving a suite that contains all the test registered with + * CPPUNIT_TEST_SUITE_REGISTRATION(). + * \code + * CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + * CppUnit::TestSuite *suite = registry.makeTest(); + * \endcode + * + * Example 2: retreiving a suite that contains all the test registered with + * \link CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Math" )\endlink. + * \code + * CppUnit::TestFactoryRegistry &mathRegistry = CppUnit::TestFactoryRegistry::getRegistry( "Math" ); + * CppUnit::TestSuite *mathSuite = mathRegistry.makeTest(); + * \endcode + * + * Example 3: creating a test suite hierarchy composed of unnamed registration and + * named registration: + * - All Tests + * - tests registered with CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Graph" ) + * - tests registered with CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Math" ) + * - tests registered with CPPUNIT_TEST_SUITE_REGISTRATION + * + * \code + * CppUnit::TestSuite *rootSuite = new CppUnit::TestSuite( "All tests" ); + * rootSuite->addTest( CppUnit::TestFactoryRegistry::getRegistry( "Graph" ).makeTest() ); + * rootSuite->addTest( CppUnit::TestFactoryRegistry::getRegistry( "Math" ).makeTest() ); + * CppUnit::TestFactoryRegistry::getRegistry().addTestToSuite( rootSuite ); + * \endcode + * + * The same result can be obtained with: + * \code + * CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + * registry.addRegistry( "Graph" ); + * registry.addRegistry( "Math" ); + * CppUnit::TestSuite *suite = registry.makeTest(); + * \endcode + * + * Since a TestFactoryRegistry is a TestFactory, the named registries can be + * registered in the unnamed registry, creating the hierarchy links. + * + * \see TestSuiteFactory, AutoRegisterSuite + * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION + */ +class CPPUNIT_API TestFactoryRegistry : public TestFactory +{ +public: + /** Constructs the registry with the specified name. + * \param name Name of the registry. It is the name of TestSuite returned by + * makeTest(). + */ + TestFactoryRegistry( std::string name ); + + /// Destructor. + virtual ~TestFactoryRegistry(); + + /** Returns a new TestSuite that contains the registered test. + * \return A new TestSuite which contains all the test added using + * registerFactory(TestFactory *). + */ + virtual Test *makeTest(); + + /** Returns a named registry. + * + * If the \a name is left to its default value, then the registry that is returned is + * the one used by CPPUNIT_TEST_SUITE_REGISTRATION(): the 'top' level registry. + * + * \param name Name of the registry to return. + * \return Registry. If the registry does not exist, it is created with the + * specified name. + */ + static TestFactoryRegistry &getRegistry( const std::string &name = "All Tests" ); + + /** Adds the registered tests to the specified suite. + * \param suite Suite the tests are added to. + */ + void addTestToSuite( TestSuite *suite ); + + /** Adds the specified TestFactory to the registry. + * + * \param factory Factory to register. + */ + void registerFactory( TestFactory *factory ); + + /*! Removes the specified TestFactory from the registry. + * + * The specified factory is not destroyed. + * \param factory Factory to remove from the registry. + * \todo Address case when trying to remove a TestRegistryFactory. + */ + void unregisterFactory( TestFactory *factory ); + + /*! Adds a registry to the registry. + * + * Convenience method to help create test hierarchy. See TestFactoryRegistry detail + * for examples of use. Calling this method is equivalent to: + * \code + * this->registerFactory( TestFactoryRegistry::getRegistry( name ) ); + * \endcode + * + * \param name Name of the registry to add. + */ + void addRegistry( const std::string &name ); + + /*! Tests if the registry is valid. + * + * This method should be used when unregistering test factory on static variable + * destruction to ensure that the registry has not been already destroyed (in + * that case there is no need to unregister the test factory). + * + * You should not concern yourself with this method unless you are writing a class + * like AutoRegisterSuite. + * + * \return \c true if the specified registry has not been destroyed, + * otherwise returns \c false. + * \see AutoRegisterSuite. + */ + static bool isValid(); + + /** Adds the specified TestFactory with a specific name (DEPRECATED). + * \param name Name associated to the factory. + * \param factory Factory to register. + * \deprecated Use registerFactory( TestFactory *) instead. + */ + void registerFactory( const std::string &name, + TestFactory *factory ); + +private: + TestFactoryRegistry( const TestFactoryRegistry © ); + void operator =( const TestFactoryRegistry © ); + +private: + typedef CppUnitSet > Factories; + Factories m_factories; + + std::string m_name; +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + + +#endif // CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestFixtureFactory.h b/UnitTests/cppunit/include/cppunit/extensions/TestFixtureFactory.h new file mode 100644 index 0000000..45354c6 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestFixtureFactory.h @@ -0,0 +1,50 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTFIXTUREFACTORY_H +#define CPPUNIT_EXTENSIONS_TESTFIXTUREFACTORY_H + +#include + + +CPPUNIT_NS_BEGIN + + +class TestFixture; + +/*! \brief Abstract TestFixture factory (Implementation). + * + * Implementation detail. Use by HelperMacros to handle TestFixture hierarchy. + */ +class TestFixtureFactory +{ +public: + //! Creates a new TestFixture instance. + virtual TestFixture *makeFixture() =0; + + virtual ~TestFixtureFactory() {} +}; + + +/*! \brief Concret TestFixture factory (Implementation). + * + * Implementation detail. Use by HelperMacros to handle TestFixture hierarchy. + */ +template +class ConcretTestFixtureFactory : public CPPUNIT_NS::TestFixtureFactory +{ + /*! \brief Returns a new TestFixture instance. + * \return A new fixture instance. The fixture instance is returned by + * the TestFixtureFactory passed on construction. The actual type + * is that of the fixture on which the static method suite() + * was called. + */ + TestFixture *makeFixture() + { + return new TestFixtureType(); + } +}; + + +CPPUNIT_NS_END + + +#endif // CPPUNIT_EXTENSIONS_TESTFIXTUREFACTORY_H + diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestNamer.h b/UnitTests/cppunit/include/cppunit/extensions/TestNamer.h new file mode 100644 index 0000000..5a6471c --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestNamer.h @@ -0,0 +1,89 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTNAMER_H +#define CPPUNIT_EXTENSIONS_TESTNAMER_H + +#include +#include + +#if CPPUNIT_HAVE_RTTI +# include +#endif + + + +/*! \def CPPUNIT_TESTNAMER_DECL( variableName, FixtureType ) + * \brief Declares a TestNamer. + * + * Declares a TestNamer for the specified type, using RTTI if enabled, otherwise + * using macro string expansion. + * + * RTTI is used if CPPUNIT_USE_TYPEINFO_NAME is defined and not null. + * + * \code + * void someMethod() + * { + * CPPUNIT_TESTNAMER_DECL( namer, AFixtureType ); + * std::string fixtureName = namer.getFixtureName(); + * ... + * \endcode + * + * \relates TestNamer + * \see TestNamer + */ +#if CPPUNIT_USE_TYPEINFO_NAME +# define CPPUNIT_TESTNAMER_DECL( variableName, FixtureType ) \ + CPPUNIT_NS::TestNamer variableName( typeid(FixtureType) ) +#else +# define CPPUNIT_TESTNAMER_DECL( variableName, FixtureType ) \ + CPPUNIT_NS::TestNamer variableName( std::string(#FixtureType) ) +#endif + + + +CPPUNIT_NS_BEGIN + + +/*! \brief Names a test or a fixture suite. + * + * TestNamer is usually instantiated using CPPUNIT_TESTNAMER_DECL. + * + */ +class CPPUNIT_API TestNamer +{ +public: +#if CPPUNIT_HAVE_RTTI + /*! \brief Constructs a namer using the fixture's type-info. + * \param typeInfo Type-info of the fixture type. Use to name the fixture suite. + */ + TestNamer( const std::type_info &typeInfo ); +#endif + + /*! \brief Constructs a namer using the specified fixture name. + * \param fixtureName Name of the fixture suite. Usually extracted using a macro. + */ + TestNamer( const std::string &fixtureName ); + + virtual ~TestNamer(); + + /*! \brief Returns the name of the fixture. + * \return Name of the fixture. + */ + virtual std::string getFixtureName() const; + + /*! \brief Returns the name of the test for the specified method. + * \param testMethodName Name of the method that implements a test. + * \return A string that is the concatenation of the test fixture name + * (returned by getFixtureName()) and\a testMethodName, + * separated using '::'. This provides a fairly unique name for a given + * test. + */ + virtual std::string getTestNameFor( const std::string &testMethodName ) const; + +protected: + std::string m_fixtureName; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_EXTENSIONS_TESTNAMER_H + diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestSetUp.h b/UnitTests/cppunit/include/cppunit/extensions/TestSetUp.h new file mode 100644 index 0000000..f2128ec --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestSetUp.h @@ -0,0 +1,34 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTSETUP_H +#define CPPUNIT_EXTENSIONS_TESTSETUP_H + +#include + +CPPUNIT_NS_BEGIN + + +class Test; +class TestResult; + +/*! \brief Decorates a test by providing a specific setUp() and tearDown(). + */ +class CPPUNIT_API TestSetUp : public TestDecorator +{ +public: + TestSetUp( Test *test ); + + void run( TestResult *result ); + +protected: + virtual void setUp(); + virtual void tearDown(); + +private: + TestSetUp( const TestSetUp & ); + void operator =( const TestSetUp & ); +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_EXTENSIONS_TESTSETUP_H + diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestSuiteBuilderContext.h b/UnitTests/cppunit/include/cppunit/extensions/TestSuiteBuilderContext.h new file mode 100644 index 0000000..db26926 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestSuiteBuilderContext.h @@ -0,0 +1,131 @@ +#ifndef CPPUNIT_HELPER_TESTSUITEBUILDERCONTEXT_H +#define CPPUNIT_HELPER_TESTSUITEBUILDERCONTEXT_H + +#include +#include +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + + +CPPUNIT_NS_BEGIN + +class TestSuite; +class TestFixture; +class TestFixtureFactory; +class TestNamer; + +/*! \brief Context used when creating test suite in HelperMacros. + * + * Base class for all context used when creating test suite. The + * actual context type during test suite creation is TestSuiteBuilderContext. + * + * \sa CPPUNIT_TEST_SUITE, CPPUNIT_TEST_SUITE_ADD_TEST, + * CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS. + */ +class CPPUNIT_API TestSuiteBuilderContextBase +{ +public: + /*! \brief Constructs a new context. + * + * You should not use this. The context is created in + * CPPUNIT_TEST_SUITE(). + */ + TestSuiteBuilderContextBase( TestSuite &suite, + const TestNamer &namer, + TestFixtureFactory &factory ); + + virtual ~TestSuiteBuilderContextBase(); + + /*! \brief Adds a test to the fixture suite. + * + * \param test Test to add to the fixture suite. Must not be \c NULL. + */ + void addTest( Test *test ); + + /*! \brief Returns the fixture name. + * \return Fixture name. It is the name used to name the fixture + * suite. + */ + std::string getFixtureName() const; + + /*! \brief Returns the name of the test for the specified method. + * + * \param testMethodName Name of the method that implements a test. + * \return A string that is the concatenation of the test fixture name + * (returned by getFixtureName()) and\a testMethodName, + * separated using '::'. This provides a fairly unique name for a given + * test. + */ + std::string getTestNameFor( const std::string &testMethodName ) const; + + /*! \brief Adds property pair. + * \param key PropertyKey string to add. + * \param value PropertyValue string to add. + */ + void addProperty( const std::string &key, + const std::string &value ); + + /*! \brief Returns property value assigned to param key. + * \param key PropertyKey string. + */ + const std::string getStringProperty( const std::string &key ) const; + +protected: + TestFixture *makeTestFixture() const; + + // Notes: we use a vector here instead of a map to work-around the + // shared std::map in dll bug in VC6. + // See http://www.dinkumware.com/vc_fixes.html for detail. + typedef std::pair Property; + typedef CppUnitVector Properties; + + TestSuite &m_suite; + const TestNamer &m_namer; + TestFixtureFactory &m_factory; + +private: + Properties m_properties; +}; + + +/*! \brief Type-sage context used when creating test suite in HelperMacros. + * + * \sa TestSuiteBuilderContextBase. + */ +template +class TestSuiteBuilderContext : public TestSuiteBuilderContextBase +{ +public: + typedef Fixture FixtureType; + + TestSuiteBuilderContext( TestSuiteBuilderContextBase &contextBase ) + : TestSuiteBuilderContextBase( contextBase ) + { + } + + /*! \brief Returns a new TestFixture instance. + * \return A new fixture instance. The fixture instance is returned by + * the TestFixtureFactory passed on construction. The actual type + * is that of the fixture on which the static method suite() + * was called. + */ + FixtureType *makeFixture() const + { + return CPPUNIT_STATIC_CAST( FixtureType *, + TestSuiteBuilderContextBase::makeTestFixture() ); + } +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + +#endif // CPPUNIT_HELPER_TESTSUITEBUILDERCONTEXT_H + diff --git a/UnitTests/cppunit/include/cppunit/extensions/TestSuiteFactory.h b/UnitTests/cppunit/include/cppunit/extensions/TestSuiteFactory.h new file mode 100644 index 0000000..260b483 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TestSuiteFactory.h @@ -0,0 +1,27 @@ +#ifndef CPPUNIT_EXTENSIONS_TESTSUITEFACTORY_H +#define CPPUNIT_EXTENSIONS_TESTSUITEFACTORY_H + +#include + +CPPUNIT_NS_BEGIN + + + class Test; + + /*! \brief TestFactory for TestFixture that implements a static suite() method. + * \see AutoRegisterSuite. + */ + template + class TestSuiteFactory : public TestFactory + { + public: + virtual Test *makeTest() + { + return TestCaseType::suite(); + } + }; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_EXTENSIONS_TESTSUITEFACTORY_H diff --git a/UnitTests/cppunit/include/cppunit/extensions/TypeInfoHelper.h b/UnitTests/cppunit/include/cppunit/extensions/TypeInfoHelper.h new file mode 100644 index 0000000..c0ecdbc --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/TypeInfoHelper.h @@ -0,0 +1,33 @@ +#ifndef CPPUNIT_TYPEINFOHELPER_H +#define CPPUNIT_TYPEINFOHELPER_H + +#include + +#if CPPUNIT_HAVE_RTTI + +#include +#include + +CPPUNIT_NS_BEGIN + + + /**! \brief Helper to use type_info. + */ + class CPPUNIT_API TypeInfoHelper + { + public: + /*! \brief Get the class name of the specified type_info. + * \param info Info which the class name is extracted from. + * \return The string returned by type_info::name() without + * the "class" prefix. If the name is not prefixed + * by "class", it is returned as this. + */ + static std::string getClassName( const std::type_info &info ); + }; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_HAVE_RTTI + +#endif // CPPUNIT_TYPEINFOHELPER_H diff --git a/UnitTests/cppunit/include/cppunit/extensions/XmlInputHelper.h b/UnitTests/cppunit/include/cppunit/extensions/XmlInputHelper.h new file mode 100644 index 0000000..4f06e5b --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/extensions/XmlInputHelper.h @@ -0,0 +1,23 @@ +#ifndef CPPUNIT_EXTENSIONS_XMLINPUTHELPER_H +#define CPPUNIT_EXTENSIONS_XMLINPUTHELPER_H + +#include + + +/*! \brief Adds a parameterized test method to the suite. + * \param testMethod Name of the method of the test case to add to the + * suite. The signature of the method must be of + * type: void testMethod(std::istream& param_in, std::istream& exp_in); + * \see CPPUNIT_TEST_SUITE. + */ +#define CPPUNIT_TEST_XML( testMethod) \ + CPPUNIT_TEST_ADD( new CppUnit::ParameterizedTestCase( \ + context.getTestNameFor( #testMethod ), \ + #testMethod, \ + &TestFixtureType::testMethod, \ + context.makeFixture(), \ + context.getStringProperty( std::string("XmlFileName") ) ) ) + + + +#endif // CPPUNIT_EXTENSIONS_XMLINPUTHELPER_H \ No newline at end of file diff --git a/UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManager.h b/UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManager.h new file mode 100644 index 0000000..d70ccde --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManager.h @@ -0,0 +1,121 @@ +#ifndef CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGER_H +#define CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGER_H + +#include +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +CPPUNIT_NS_BEGIN + + +/*! \brief Manages dynamic libraries. + * + * The Dynamic Library Manager provides a platform independent way to work with + * dynamic library. It load a specific dynamic library, and can returns specific + * symbol exported by the dynamic library. + * + * If an error occurs, a DynamicLibraryManagerException is thrown. + * + * \internal Implementation of the OS independent methods is in + * DynamicLibraryManager.cpp. + * + * \internal Porting to a new platform: + * - Adds platform detection in config/SelectDllLoader.h. Should define a specific + * macro for that platform of the form: CPPUNIT_HAVE_XYZ_DLL_LOADER, where + * XYZ is the platform. + * - Makes a copy of UnixDynamicLibraryManager.cpp and named it after the platform. + * - Updated the 'guard' in your file (CPPUNIT_HAVE_XYZ_DLL_LOADER) so that it is + * only processed if the matching platform has been detected. + * - Change the implementation of methods doLoadLibrary(), doReleaseLibrary(), + * doFindSymbol() in your copy. Those methods usually maps directly to OS calls. + * - Adds the file to the project. + */ +class DynamicLibraryManager +{ +public: + typedef void *Symbol; + typedef void *LibraryHandle; + + /*! \brief Loads the specified library. + * \param libraryFileName Name of the library to load. + * \exception DynamicLibraryManagerException if a failure occurs while loading + * the library (fail to found or load the library). + */ + DynamicLibraryManager( const std::string &libraryFileName ); + + /// Releases the loaded library.. + ~DynamicLibraryManager(); + + /*! \brief Returns a pointer on the specified symbol exported by the library. + * \param symbol Name of the symbol exported by the library. + * \return Pointer on the symbol. Should be casted to the actual type. Never \c NULL. + * \exception DynamicLibraryManagerException if the symbol is not found. + */ + Symbol findSymbol( const std::string &symbol ); + +private: + /*! Loads the specified library. + * \param libraryName Name of the library to load. + * \exception DynamicLibraryManagerException if a failure occurs while loading + * the library (fail to found or load the library). + */ + void loadLibrary( const std::string &libraryName ); + + /*! Releases the loaded library. + * + * \warning Must NOT throw any exceptions (called from destructor). + */ + void releaseLibrary(); + + /*! Loads the specified library. + * + * May throw any exceptions (indicates failure). + * \param libraryName Name of the library to load. + * \return Handle of the loaded library. \c NULL indicates failure. + */ + LibraryHandle doLoadLibrary( const std::string &libraryName ); + + /*! Releases the loaded library. + * + * The handle of the library to free is in \c m_libraryHandle. It is never + * \c NULL. + * \warning Must NOT throw any exceptions (called from destructor). + */ + void doReleaseLibrary(); + + /*! Returns a pointer on the specified symbol exported by the library. + * + * May throw any exceptions (indicates failure). + * \param symbol Name of the symbol exported by the library. + * \return Pointer on the symbol. \c NULL indicates failure. + */ + Symbol doFindSymbol( const std::string &symbol ); + + /*! Returns detailed information about doLoadLibrary() failure. + * + * Called just after a failed call to doLoadLibrary() to get extra + * error information. + * + * \return Detailed information about the failure of the call to + * doLoadLibrary() that just failed. + */ + std::string getLastErrorDetail() const; + + /// Prevents the use of the copy constructor. + DynamicLibraryManager( const DynamicLibraryManager © ); + + /// Prevents the use of the copy operator. + void operator =( const DynamicLibraryManager © ); + +private: + LibraryHandle m_libraryHandle; + std::string m_libraryName; +}; + + +CPPUNIT_NS_END + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) + +#endif // CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGER_H diff --git a/UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManagerException.h b/UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManagerException.h new file mode 100644 index 0000000..11ebbd9 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/plugin/DynamicLibraryManagerException.h @@ -0,0 +1,53 @@ +#ifndef CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGEREXCEPTION_H +#define CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGEREXCEPTION_H + +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) +#include +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief Exception thrown by DynamicLibraryManager when a failure occurs. + * + * Use getCause() to know what function caused the failure. + * + */ +class DynamicLibraryManagerException : public std::runtime_error +{ +public: + enum Cause + { + /// Failed to load the dynamic library + loadingFailed =0, + /// Symbol not found in the dynamic library + symbolNotFound + }; + + /// Failed to load the dynamic library or Symbol not found in the dynamic library. + DynamicLibraryManagerException( const std::string &libraryName, + const std::string &errorDetail, + Cause cause ); + + ~DynamicLibraryManagerException() throw() + { + } + + Cause getCause() const; + + const char *what() const throw(); + +private: + std::string m_message; + Cause m_cause; +}; + + +CPPUNIT_NS_END + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) + +#endif // CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGEREXCEPTION_H diff --git a/UnitTests/cppunit/include/cppunit/plugin/PlugInManager.h b/UnitTests/cppunit/include/cppunit/plugin/PlugInManager.h new file mode 100644 index 0000000..6ecedc8 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/plugin/PlugInManager.h @@ -0,0 +1,113 @@ +#ifndef CPPUNIT_PLUGIN_PLUGINMANAGER_H +#define CPPUNIT_PLUGIN_PLUGINMANAGER_H + +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +struct CppUnitTestPlugIn; + +CPPUNIT_NS_BEGIN + + +class DynamicLibraryManager; +class TestResult; +class XmlOutputter; + + +/*! \brief Manges TestPlugIn. + */ +class CPPUNIT_API PlugInManager +{ +public: + /*! Constructs a PlugInManager object. + */ + PlugInManager(); + + /// Destructor. + virtual ~PlugInManager(); + + /*! \brief Loads the specified plug-in. + * + * After being loaded, the CppUnitTestPlugIn::initialize() is called. + * + * \param libraryFileName Name of the file that contains the TestPlugIn. + * \param parameters List of string passed to the plug-in. + * \return Pointer on the DynamicLibraryManager associated to the library. + * Valid until the library is unloaded. Never \c NULL. + * \exception DynamicLibraryManagerException is thrown if an error occurs during loading. + */ + void load( const std::string &libraryFileName, + const PlugInParameters ¶meters = PlugInParameters() ); + + /*! \brief Unloads the specified plug-in. + * \param libraryFileName Name of the file that contains the TestPlugIn passed + * to a previous call to load(). + */ + void unload( const std::string &libraryFileName ); + + /*! \brief Gives a chance to each loaded plug-in to register TestListener. + * + * For each plug-in, call CppUnitTestPlugIn::addListener(). + */ + void addListener( TestResult *eventManager ); + + /*! \brief Gives a chance to each loaded plug-in to unregister TestListener. + * For each plug-in, call CppUnitTestPlugIn::removeListener(). + */ + void removeListener( TestResult *eventManager ); + + /*! \brief Provides a way for the plug-in to register some XmlOutputterHook. + */ + void addXmlOutputterHooks( XmlOutputter *outputter ); + + /*! \brief Called when the XmlOutputter is destroyed. + * + * Can be used to free some resources allocated by addXmlOutputterHooks(). + */ + void removeXmlOutputterHooks(); + +protected: + /*! \brief (INTERNAL) Information about a specific plug-in. + */ + struct PlugInInfo + { + std::string m_fileName; + DynamicLibraryManager *m_manager; + CppUnitTestPlugIn *m_interface; + }; + + /*! Unloads the specified plug-in. + * \param plugIn Information about the plug-in. + */ + void unload( PlugInInfo &plugIn ); + +private: + /// Prevents the use of the copy constructor. + PlugInManager( const PlugInManager © ); + + /// Prevents the use of the copy operator. + void operator =( const PlugInManager © ); + +private: + typedef CppUnitDeque PlugIns; + PlugIns m_plugIns; +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) + + +#endif // CPPUNIT_PLUGIN_PLUGINMANAGER_H diff --git a/UnitTests/cppunit/include/cppunit/plugin/PlugInParameters.h b/UnitTests/cppunit/include/cppunit/plugin/PlugInParameters.h new file mode 100644 index 0000000..c67d0f1 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/plugin/PlugInParameters.h @@ -0,0 +1,36 @@ +#ifndef CPPUNIT_PLUGIN_PARAMETERS +#define CPPUNIT_PLUGIN_PARAMETERS + +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +#include +#include + +CPPUNIT_NS_BEGIN + +/*! \brief Test plug-ins parameters. + */ +class CPPUNIT_API PlugInParameters +{ +public: + /// Constructs plug-in parameters from the specified command-line. + PlugInParameters( const std::string &commandLine = "" ); + + virtual ~PlugInParameters(); + + /// Returns the command line that was passed on construction. + std::string getCommandLine() const; + +private: + std::string m_commandLine; +}; + + +CPPUNIT_NS_END + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) + + +#endif // CPPUNIT_PLUGIN_PARAMETERS diff --git a/UnitTests/cppunit/include/cppunit/plugin/TestPlugIn.h b/UnitTests/cppunit/include/cppunit/plugin/TestPlugIn.h new file mode 100644 index 0000000..bd0565c --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/plugin/TestPlugIn.h @@ -0,0 +1,200 @@ +#ifndef CPPUNIT_PLUGIN_TESTPLUGIN +#define CPPUNIT_PLUGIN_TESTPLUGIN + +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +#include + +CPPUNIT_NS_BEGIN + + +class Test; +class TestFactoryRegistry; +class TestResult; +class XmlOutputter; + +CPPUNIT_NS_END + +/*! \file + */ + + +/*! \brief Test plug-in interface. + * \ingroup WritingTestPlugIn + * + * This class define the interface implemented by test plug-in. A pointer to that + * interface is returned by the function exported by the test plug-in. + * + * Plug-in are loaded/unloaded by PlugInManager. When a plug-in is loaded, + * initialize() is called. Before unloading the plug-in, the PlugInManager + * call uninitialize(). + * + * addListener() and removeListener() are called respectively before and after + * the test run. + * + * addXmlOutputterHooks() and removeXmlOutputterHooks() are called respectively + * before and after writing the XML output using a XmlOutputter. + * + * \see CPPUNIT_PLUGIN_IMPLEMENT, CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL + * \see CppUnit::TestPlugInDefaultImpl, CppUnit::XmlOutputter. + */ +struct CPPUNIT_API CppUnitTestPlugIn +{ + /*! \brief Called just after loading the dynamic library. + * + * Override this method to add additional suite to the registry, though this + * is preferably done using the macros (CPPUNIT_TEST_SUITE_REGISTRATION...). + * If you are creating a custom listener to extends the plug-in runner, + * you can use this to configure the listener using the \a parameters. + * + * You could also use the parameters to specify some global parameter, such + * as test datas location, database name... + * + * N.B.: Parameters interface is not define yet, and the plug-in runner does + * not yet support plug-in parameter. + */ + virtual void initialize( CPPUNIT_NS::TestFactoryRegistry *registry, + const CPPUNIT_NS::PlugInParameters ¶meters ) =0; + + /*! \brief Gives a chance to the plug-in to register TestListener. + * + * Override this method to add a TestListener for the test run. This is useful + * if you are writing a custom TestListener, but also if you need to + * setUp some global resource: listen to TestListener::startTestRun(), + * and TestListener::endTestRun(). + */ + virtual void addListener( CPPUNIT_NS::TestResult *eventManager ) =0; + + /*! \brief Gives a chance to the plug-in to remove its registered TestListener. + * + * Override this method to remove a TestListener that has been added. + */ + virtual void removeListener( CPPUNIT_NS::TestResult *eventManager ) =0; + + /*! \brief Provides a way for the plug-in to register some XmlOutputterHook. + */ + virtual void addXmlOutputterHooks( CPPUNIT_NS::XmlOutputter *outputter ) =0; + + /*! \brief Called when the XmlOutputter is destroyed. + * + * Can be used to free some resources allocated by addXmlOutputterHooks(). + */ + virtual void removeXmlOutputterHooks() = 0; + + /*! \brief Called just before unloading the dynamic library. + * + * Override this method to unregister test factory added in initialize(). + * This is necessary to keep the TestFactoryRegistry 'clean'. When + * the plug-in is unloaded from memory, the TestFactoryRegistry will hold + * reference on test that are no longer available if they are not + * unregistered. + */ + virtual void uninitialize( CPPUNIT_NS::TestFactoryRegistry *registry ) =0; + + virtual ~CppUnitTestPlugIn() {} +}; + + + +/*! \brief Name of the function exported by a test plug-in. + * \ingroup WritingTestPlugIn + * + * The signature of the exported function is: + * \code + * CppUnitTestPlugIn *CPPUNIT_PLUGIN_EXPORTED_NAME(void); + * \endcode + */ +#define CPPUNIT_PLUGIN_EXPORTED_NAME cppunitTestPlugIn + +/*! \brief Type of the function exported by a plug-in. + * \ingroup WritingTestPlugIn + */ +typedef CppUnitTestPlugIn *(*TestPlugInSignature)(); + + +/*! \brief Implements the function exported by the test plug-in + * \ingroup WritingTestPlugIn + */ +#define CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL( TestPlugInInterfaceType ) \ + CPPUNIT_PLUGIN_EXPORT CppUnitTestPlugIn *CPPUNIT_PLUGIN_EXPORTED_NAME(void) \ + { \ + static TestPlugInInterfaceType plugIn; \ + return &plugIn; \ + } \ + typedef char __CppUnitPlugInExportFunctionDummyTypeDef // dummy typedef so it can end with ';' + + +// Note: This include should remain after definition of CppUnitTestPlugIn +#include + + +/*! \def CPPUNIT_PLUGIN_IMPLEMENT_MAIN() + * \brief Implements the 'main' function for the plug-in. + * + * This macros implements the main() function for dynamic library. + * For example, WIN32 requires a DllMain function, while some Unix + * requires a main() function. This macros takes care of the implementation. + */ + +// Win32 +#if defined(CPPUNIT_HAVE_WIN32_DLL_LOADER) +#if !defined(APIENTRY) +#define WIN32_LEAN_AND_MEAN +#define NOGDI +#define NOUSER +#define NOKERNEL +#define NOSOUND +#define NOMINMAX +#define BLENDFUNCTION void // for mingw & gcc +#include +#endif +#define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \ + BOOL APIENTRY DllMain( HANDLE hModule, \ + DWORD ul_reason_for_call, \ + LPVOID lpReserved ) \ + { \ + return TRUE; \ + } \ + typedef char __CppUnitPlugInImplementMainDummyTypeDef + +// Unix +#elif defined(CPPUNIT_HAVE_UNIX_DLL_LOADER) || defined(CPPUNIT_HAVE_UNIX_SHL_LOADER) +#define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \ + int main( int argc, char *argv[] ) \ + { \ + return 0; \ + } \ + typedef char __CppUnitPlugInImplementMainDummyTypeDef + + +// Other +#else // other platforms don't require anything specifics +#endif + + + +/*! \brief Implements and exports the test plug-in interface. + * \ingroup WritingTestPlugIn + * + * This macro exports the test plug-in function using the subclass, + * and implements the 'main' function for the plug-in using + * CPPUNIT_PLUGIN_IMPLEMENT_MAIN(). + * + * When using this macro, CppUnit must be linked as a DLL (shared library). + * Otherwise, tests registered to the TestFactoryRegistry in the DLL will + * not be visible to the DllPlugInTester. + * + * \see CppUnitTestPlugIn + * \see CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL(), CPPUNIT_PLUGIN_IMPLEMENT_MAIN(). + */ +#define CPPUNIT_PLUGIN_IMPLEMENT() \ + CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL( CPPUNIT_NS::TestPlugInDefaultImpl ); \ + CPPUNIT_PLUGIN_IMPLEMENT_MAIN() + + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) + + +#endif // CPPUNIT_PLUGIN_TESTPLUGIN diff --git a/UnitTests/cppunit/include/cppunit/plugin/TestPlugInDefaultImpl.h b/UnitTests/cppunit/include/cppunit/plugin/TestPlugInDefaultImpl.h new file mode 100644 index 0000000..8040b79 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/plugin/TestPlugInDefaultImpl.h @@ -0,0 +1,61 @@ +#ifndef CPPUNIT_PLUGIN_TESTPLUGINADAPTER +#define CPPUNIT_PLUGIN_TESTPLUGINADAPTER + +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 4660 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +CPPUNIT_NS_BEGIN + + +class TestSuite; + + +/*! \brief Default implementation of test plug-in interface. + * \ingroup WritingTestPlugIn + * + * Override getSuiteName() to specify the suite name. Default is "All Tests". + * + * CppUnitTestPlugIn::getTestSuite() returns a suite that contains + * all the test registered to the default test factory registry + * ( TestFactoryRegistry::getRegistry() ). + * + */ +class CPPUNIT_API TestPlugInDefaultImpl : public CppUnitTestPlugIn +{ +public: + TestPlugInDefaultImpl(); + + virtual ~TestPlugInDefaultImpl(); + + void initialize( TestFactoryRegistry *registry, + const PlugInParameters ¶meters ); + + void addListener( TestResult *eventManager ); + + void removeListener( TestResult *eventManager ); + + void addXmlOutputterHooks( XmlOutputter *outputter ); + + void removeXmlOutputterHooks(); + + void uninitialize( TestFactoryRegistry *registry ); +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) + +#endif // CPPUNIT_PLUGIN_TESTPLUGINADAPTER diff --git a/UnitTests/cppunit/include/cppunit/portability/CppUnitDeque.h b/UnitTests/cppunit/include/cppunit/portability/CppUnitDeque.h new file mode 100644 index 0000000..bbab21f --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/portability/CppUnitDeque.h @@ -0,0 +1,25 @@ +#ifndef CPPUNIT_PORTABILITY_CPPUNITDEQUE_H +#define CPPUNIT_PORTABILITY_CPPUNITDEQUE_H + +// The technic used is similar to the wrapper of STLPort. + +#include +#include + + +#if CPPUNIT_STD_NEED_ALLOCATOR + +template +class CppUnitDeque : public std::deque +{ +public: +}; + +#else // CPPUNIT_STD_NEED_ALLOCATOR + +#define CppUnitDeque std::deque + +#endif + +#endif // CPPUNIT_PORTABILITY_CPPUNITDEQUE_H + diff --git a/UnitTests/cppunit/include/cppunit/portability/CppUnitMap.h b/UnitTests/cppunit/include/cppunit/portability/CppUnitMap.h new file mode 100644 index 0000000..0cdc723 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/portability/CppUnitMap.h @@ -0,0 +1,29 @@ +#ifndef CPPUNIT_PORTABILITY_CPPUNITMAP_H +#define CPPUNIT_PORTABILITY_CPPUNITMAP_H + +// The technic used is similar to the wrapper of STLPort. + +#include +#include +#include + + +#if CPPUNIT_STD_NEED_ALLOCATOR + +template +class CppUnitMap : public std::map + ,CPPUNIT_STD_ALLOCATOR> +{ +public: +}; + +#else // CPPUNIT_STD_NEED_ALLOCATOR + +#define CppUnitMap std::map + +#endif + +#endif // CPPUNIT_PORTABILITY_CPPUNITMAP_H + diff --git a/UnitTests/cppunit/include/cppunit/portability/CppUnitSet.h b/UnitTests/cppunit/include/cppunit/portability/CppUnitSet.h new file mode 100644 index 0000000..18b8662 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/portability/CppUnitSet.h @@ -0,0 +1,28 @@ +#ifndef CPPUNIT_PORTABILITY_CPPUNITSET_H +#define CPPUNIT_PORTABILITY_CPPUNITSET_H + +// The technic used is similar to the wrapper of STLPort. + +#include +#include +#include + + +#if CPPUNIT_STD_NEED_ALLOCATOR + +template +class CppUnitSet : public std::set + ,CPPUNIT_STD_ALLOCATOR> +{ +public: +}; + +#else // CPPUNIT_STD_NEED_ALLOCATOR + +#define CppUnitSet std::set + +#endif + +#endif // CPPUNIT_PORTABILITY_CPPUNITSET_H + diff --git a/UnitTests/cppunit/include/cppunit/portability/CppUnitStack.h b/UnitTests/cppunit/include/cppunit/portability/CppUnitStack.h new file mode 100644 index 0000000..bc7785b --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/portability/CppUnitStack.h @@ -0,0 +1,26 @@ +#ifndef CPPUNIT_PORTABILITY_CPPUNITSTACK_H +#define CPPUNIT_PORTABILITY_CPPUNITSTACK_H + +// The technic used is similar to the wrapper of STLPort. + +#include +#include +#include + + +#if CPPUNIT_STD_NEED_ALLOCATOR + +template +class CppUnitStack : public std::stack > +{ +public: +}; + +#else // CPPUNIT_STD_NEED_ALLOCATOR + +#define CppUnitStack std::stack + +#endif + +#endif // CPPUNIT_PORTABILITY_CPPUNITSTACK_H \ No newline at end of file diff --git a/UnitTests/cppunit/include/cppunit/portability/CppUnitVector.h b/UnitTests/cppunit/include/cppunit/portability/CppUnitVector.h new file mode 100644 index 0000000..6666a63 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/portability/CppUnitVector.h @@ -0,0 +1,25 @@ +#ifndef CPPUNIT_PORTABILITY_CPPUNITVECTOR_H +#define CPPUNIT_PORTABILITY_CPPUNITVECTOR_H + +// The technic used is similar to the wrapper of STLPort. + +#include +#include + + +#if CPPUNIT_STD_NEED_ALLOCATOR + +template +class CppUnitVector : public std::vector +{ +public: +}; + +#else // CPPUNIT_STD_NEED_ALLOCATOR + +#define CppUnitVector std::vector + +#endif + +#endif // CPPUNIT_PORTABILITY_CPPUNITVECTOR_H + diff --git a/UnitTests/cppunit/include/cppunit/portability/FloatingPoint.h b/UnitTests/cppunit/include/cppunit/portability/FloatingPoint.h new file mode 100644 index 0000000..e8c91b3 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/portability/FloatingPoint.h @@ -0,0 +1,54 @@ +#ifndef CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED +#define CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED + +#include +#include + +CPPUNIT_NS_BEGIN + +/// \brief Tests if a floating-point is a NaN. +// According to IEEE-754 floating point standard, +// (see e.g. page 8 of +// http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps) +// all comparisons with NaN are false except "x != x", which is true. +// +// At least Microsoft Visual Studio 6 is known not to implement this test correctly. +// It emits the following code to test equality: +// fcomp qword ptr [nan] +// fnstsw ax // copie fp (floating-point) status register to ax +// test ah,40h // test bit 14 of ax (0x4000) => C3 of fp status register +// According to the following documentation on the x86 floating point status register, +// the C2 bit should be tested to test for NaN value. +// http://webster.cs.ucr.edu/AoA/Windows/HTML/RealArithmetic.html#1000117 +// In Microsoft Visual Studio 2003 & 2005, the test is implemented with: +// test ah,44h // Visual Studio 2005 test both C2 & C3... +// +// To work around this, a NaN is assumed to be detected if no strict ordering is found. +inline bool floatingPointIsUnordered( double x ) +{ + // x != x will detect a NaN on conformant platform + // (2.0 < x && x < 1.0) will detect a NaN on non conformant platform: + // => no ordering can be found for x. + return (x != x) || (2.0 < x && x < 1.0); +} + + +/// \brief Tests if a floating-point is finite. +/// @return \c true if x is neither a NaN, nor +inf, nor -inf, \c false otherwise. +inline int floatingPointIsFinite( double x ) +{ +#if defined(CPPUNIT_HAVE_ISFINITE) + return isfinite( x ); +#elif defined(CPPUNIT_HAVE_FINITE) + return finite( x ); +#elif defined(CPPUNIT_HAVE__FINITE) + return _finite(x); +#else + double testInf = x * 0.0; // Produce 0.0 if x is finite, a NaN otherwise. + return testInf == 0.0 && !floatingPointIsUnordered(testInf); +#endif +} + +CPPUNIT_NS_END + +#endif // CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED diff --git a/UnitTests/cppunit/include/cppunit/portability/Stream.h b/UnitTests/cppunit/include/cppunit/portability/Stream.h new file mode 100644 index 0000000..e9beb8c --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/portability/Stream.h @@ -0,0 +1,347 @@ +#ifndef CPPUNIT_PORTABILITY_STREAM_H_INCLUDED +#define CPPUNIT_PORTABILITY_STREAM_H_INCLUDED + +// This module define: +// Type CppUT::Stream (either std::stream or a custom type) +// Type CppUT::OStringStream (eitjer std::ostringstream, older alternate or a custom type) +// Functions stdCOut() & stdCErr() which returns a reference on cout & cerr stream (or our +// custom stream). + +#include + + +#if defined( CPPUNIT_NO_STREAM ) + +#include +#include +#include + +CPPUNIT_NS_BEGIN + +class StreamBuffer +{ +public: + virtual ~StreamBuffer() {} + + virtual void write( const char *text, unsigned int length ) = 0; + + virtual void flush() {} +}; + + +class StringStreamBuffer : public StreamBuffer +{ +public: + std::string str() const + { + return str_; + } + +public: // overridden from StreamBuffer + void write( const char *text, unsigned int length ) + { + str_.append( text, length ); + } + +private: + std::string str_; +}; + + +class FileStreamBuffer : public StreamBuffer +{ +public: + FileStreamBuffer( FILE *file ) + : file_( file ) + { + } + + FILE *file() const + { + return file_; + } + +public: // overridden from StreamBuffer + void write( const char *text, unsigned int length ) + { + if ( file_ ) + fwrite( text, sizeof(char), length, file_ ); + } + + void flush() + { + if ( file_ ) + fflush( file_ ); + } + +private: + FILE *file_; +}; + + +class OStream +{ +public: + OStream() + : buffer_( 0 ) + { + } + + OStream( StreamBuffer *buffer ) + : buffer_( buffer ) + { + } + + virtual ~OStream() + { + flush(); + } + + OStream &flush() + { + if ( buffer_ ) + buffer_->flush(); + return *this; + } + + void setBuffer( StreamBuffer *buffer ) + { + buffer_ = buffer; + } + + OStream &write( const char *text, unsigned int length ) + { + if ( buffer_ ) + buffer_->write( text, length ); + return *this; + } + + OStream &write( const char *text ) + { + return write( text, strlen(text) ); + } + + OStream &operator <<( bool v ) + { + const char *out = v ? "true" : "false"; + return write( out ); + } + + OStream &operator <<( short v ) + { + char buffer[64]; + sprintf( buffer, "%hd", v ); + return write( buffer ); + } + + OStream &operator <<( unsigned short v ) + { + char buffer[64]; + sprintf( buffer, "%hu", v ); + return write( buffer ); + } + + OStream &operator <<( int v ) + { + char buffer[64]; + sprintf( buffer, "%d", v ); + return write( buffer ); + } + + OStream &operator <<( unsigned int v ) + { + char buffer[64]; + sprintf( buffer, "%u", v ); + return write( buffer ); + } + + OStream &operator <<( long v ) + { + char buffer[64]; + sprintf( buffer, "%ld", v ); + return write( buffer ); + } + + OStream &operator <<( unsigned long v ) + { + char buffer[64]; + sprintf( buffer, "%lu", v ); + return write( buffer ); + } + + OStream &operator <<( float v ) + { + char buffer[128]; + sprintf( buffer, "%.16g", double(v) ); + return write( buffer ); + } + + OStream &operator <<( double v ) + { + char buffer[128]; + sprintf( buffer, "%.16g", v ); + return write( buffer ); + } + + OStream &operator <<( long double v ) + { + char buffer[128]; + sprintf( buffer, "%.16g", double(v) ); + return write( buffer ); + } + + OStream &operator <<( const void *v ) + { + char buffer[64]; + sprintf( buffer, "%p", v ); + return write( buffer ); + } + + OStream &operator <<( const char *v ) + { + return write( v ? v : "NULL" ); + } + + OStream &operator <<( char c ) + { + char buffer[16]; + sprintf( buffer, "%c", c ); + return write( buffer ); + } + + OStream &operator <<( const std::string &s ) + { + return write( s.c_str(), s.length() ); + } + +private: + StreamBuffer *buffer_; +}; + + +class OStringStream : public OStream +{ +public: + OStringStream() + : OStream( &buffer_ ) + { + } + + std::string str() const + { + return buffer_.str(); + } + +private: + StringStreamBuffer buffer_; +}; + + +class OFileStream : public OStream +{ +public: + OFileStream( FILE *file ) + : OStream( &buffer_ ) + , buffer_( file ) + , ownFile_( false ) + { + } + + OFileStream( const char *path ) + : OStream( &buffer_ ) + , buffer_( fopen( path, "wt" ) ) + , ownFile_( true ) + { + } + + virtual ~OFileStream() + { + if ( ownFile_ && buffer_.file() ) + fclose( buffer_.file() ); + } + +private: + FileStreamBuffer buffer_; + bool ownFile_; +}; + +inline OStream &stdCOut() +{ + static OFileStream stream( stdout ); + return stream; +} + +inline OStream &stdCErr() +{ + static OFileStream stream( stderr ); + return stream; +} + +CPPUNIT_NS_END + +#elif CPPUNIT_HAVE_SSTREAM // #if defined( CPPUNIT_NO_STREAM ) +# include +# include + + CPPUNIT_NS_BEGIN + typedef std::ostringstream OStringStream; // The standard C++ way + typedef std::ofstream OFileStream; + CPPUNIT_NS_END + + +#elif CPPUNIT_HAVE_CLASS_STRSTREAM +# include +# if CPPUNIT_HAVE_STRSTREAM +# include +# else // CPPUNIT_HAVE_STRSTREAM +# include +# endif // CPPUNIT_HAVE_CLASS_STRSTREAM + + CPPUNIT_NS_BEGIN + + class OStringStream : public std::ostrstream + { + public: + std::string str() + { +// (*this) << '\0'; +// std::string msg(std::ostrstream::str()); +// std::ostrstream::freeze(false); +// return msg; +// Alternative implementation that don't rely on freeze which is not +// available on some platforms: + return std::string( std::ostrstream::str(), pcount() ); + } + }; + + CPPUNIT_NS_END +#else // CPPUNIT_HAVE_CLASS_STRSTREAM +# error Cannot define CppUnit::OStringStream. +#endif // #if defined( CPPUNIT_NO_STREAM ) + + + +#if !defined( CPPUNIT_NO_STREAM ) + +#include + + CPPUNIT_NS_BEGIN + + typedef std::ostream OStream; + + inline OStream &stdCOut() + { + return std::cout; + } + + inline OStream &stdCErr() + { + return std::cerr; + } + + CPPUNIT_NS_END + +#endif // #if !defined( CPPUNIT_NO_STREAM ) + +#endif // CPPUNIT_PORTABILITY_STREAM_H_INCLUDED + diff --git a/UnitTests/cppunit/include/cppunit/tools/Algorithm.h b/UnitTests/cppunit/include/cppunit/tools/Algorithm.h new file mode 100644 index 0000000..e5746a2 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/tools/Algorithm.h @@ -0,0 +1,23 @@ +#ifndef CPPUNIT_TOOLS_ALGORITHM_H_INCLUDED +#define CPPUNIT_TOOLS_ALGORITHM_H_INCLUDED + +#include + +CPPUNIT_NS_BEGIN + +template +void +removeFromSequence( SequenceType &sequence, + const ValueType &valueToRemove ) +{ + for ( unsigned int index =0; index < sequence.size(); ++index ) + { + if ( sequence[ index ] == valueToRemove ) + sequence.erase( sequence.begin() + index ); + } +} + +CPPUNIT_NS_END + + +#endif // CPPUNIT_TOOLS_ALGORITHM_H_INCLUDED diff --git a/UnitTests/cppunit/include/cppunit/tools/StringTools.h b/UnitTests/cppunit/include/cppunit/tools/StringTools.h new file mode 100644 index 0000000..7a6b6d7 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/tools/StringTools.h @@ -0,0 +1,34 @@ +#ifndef CPPUNIT_TOOLS_STRINGTOOLS_H +#define CPPUNIT_TOOLS_STRINGTOOLS_H + +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +/*! \brief Tool functions to manipulate string. + */ +struct StringTools +{ + + typedef CppUnitVector Strings; + + static std::string CPPUNIT_API toString( int value ); + + static std::string CPPUNIT_API toString( double value ); + + static Strings CPPUNIT_API split( const std::string &text, + char separator ); + + static std::string CPPUNIT_API wrap( const std::string &text, + int wrapColumn = CPPUNIT_WRAP_COLUMN ); + +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TOOLS_STRINGTOOLS_H diff --git a/UnitTests/cppunit/include/cppunit/tools/XmlDocument.h b/UnitTests/cppunit/include/cppunit/tools/XmlDocument.h new file mode 100644 index 0000000..4ee7325 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/tools/XmlDocument.h @@ -0,0 +1,86 @@ +#ifndef CPPUNIT_TOOLS_XMLDOCUMENT_H +#define CPPUNIT_TOOLS_XMLDOCUMENT_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include + + +CPPUNIT_NS_BEGIN + + +class XmlElement; + + +/*! \brief A XML Document. + * + * A XmlDocument represents a XML file. It holds a pointer on the root XmlElement + * of the document. It also holds the encoding and style sheet used. + * + * By default, the XML document is stand-alone and tagged with enconding "ISO-8859-1". + */ +class CPPUNIT_API XmlDocument +{ +public: + /*! \brief Constructs a XmlDocument object. + * \param encoding Encoding used in the XML file (default is Latin-1, ISO-8859-1 ). + * \param styleSheet Name of the XSL style sheet file used. If empty then no + * style sheet will be specified in the output. + */ + XmlDocument( const std::string &encoding = "", + const std::string &styleSheet = "" ); + + /// Destructor. + virtual ~XmlDocument(); + + std::string encoding() const; + void setEncoding( const std::string &encoding = "" ); + + std::string styleSheet() const; + void setStyleSheet( const std::string &styleSheet = "" ); + + bool standalone() const; + + /*! \brief set the output document as standalone or not. + * + * For the output document, specify wether it's a standalone XML + * document, or not. + * + * \param standalone if true, the output will be specified as standalone. + * if false, it will be not. + */ + void setStandalone( bool standalone ); + + void setRootElement( XmlElement *rootElement ); + XmlElement &rootElement() const; + + std::string toString() const; + +private: + /// Prevents the use of the copy constructor. + XmlDocument( const XmlDocument © ); + + /// Prevents the use of the copy operator. + void operator =( const XmlDocument © ); + +protected: + std::string m_encoding; + std::string m_styleSheet; + XmlElement *m_rootElement; + bool m_standalone; +}; + + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + + +CPPUNIT_NS_END + +#endif // CPPUNIT_TOOLS_XMLDOCUMENT_H diff --git a/UnitTests/cppunit/include/cppunit/tools/XmlElement.h b/UnitTests/cppunit/include/cppunit/tools/XmlElement.h new file mode 100644 index 0000000..0b36bd2 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/tools/XmlElement.h @@ -0,0 +1,149 @@ +#ifndef CPPUNIT_TOOLS_XMLELEMENT_H +#define CPPUNIT_TOOLS_XMLELEMENT_H + +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + +#include +#include + + +CPPUNIT_NS_BEGIN + + +class XmlElement; + +#if CPPUNIT_NEED_DLL_DECL +// template class CPPUNIT_API std::deque; +#endif + + +/*! \brief A XML Element. + * + * A XML element has: + * - a name, specified on construction, + * - a content, specified on construction (may be empty), + * - zero or more attributes, added with addAttribute(), + * - zero or more child elements, added with addElement(). + */ +class CPPUNIT_API XmlElement +{ +public: + /*! \brief Constructs an element with the specified name and string content. + * \param elementName Name of the element. Must not be empty. + * \param content Content of the element. + */ + XmlElement( std::string elementName, + std::string content ="" ); + + /*! \brief Constructs an element with the specified name and numeric content. + * \param elementName Name of the element. Must not be empty. + * \param numericContent Content of the element. + */ + XmlElement( std::string elementName, + int numericContent ); + + /*! \brief Destructs the element and its child elements. + */ + virtual ~XmlElement(); + + /*! \brief Returns the name of the element. + * \return Name of the element. + */ + std::string name() const; + + /*! \brief Returns the content of the element. + * \return Content of the element. + */ + std::string content() const; + + /*! \brief Sets the name of the element. + * \param name New name for the element. + */ + void setName( const std::string &name ); + + /*! \brief Sets the content of the element. + * \param content New content for the element. + */ + void setContent( const std::string &content ); + + /*! \overload void setContent( const std::string &content ) + */ + void setContent( int numericContent ); + + /*! \brief Adds an attribute with the specified string value. + * \param attributeName Name of the attribute. Must not be an empty. + * \param value Value of the attribute. + */ + void addAttribute( std::string attributeName, + std::string value ); + + /*! \brief Adds an attribute with the specified numeric value. + * \param attributeName Name of the attribute. Must not be empty. + * \param numericValue Numeric value of the attribute. + */ + void addAttribute( std::string attributeName, + int numericValue ); + + /*! \brief Adds a child element to the element. + * \param element Child element to add. Must not be \c NULL. + */ + void addElement( XmlElement *element ); + + /*! \brief Returns the number of child elements. + * \return Number of child elements (element added with addElement()). + */ + int elementCount() const; + + /*! \brief Returns the child element at the specified index. + * \param index Zero based index of the element to return. + * \returns Element at the specified index. Never \c NULL. + * \exception std::invalid_argument if \a index < 0 or index >= elementCount(). + */ + XmlElement *elementAt( int index ) const; + + /*! \brief Returns the first child element with the specified name. + * \param name Name of the child element to return. + * \return First child element found which is named \a name. + * \exception std::invalid_argument if there is no child element with the specified + * name. + */ + XmlElement *elementFor( const std::string &name ) const; + + /*! \brief Returns a XML string that represents the element. + * \param indent String of spaces representing the amount of 'indent'. + * \return XML string that represents the element, its attributes and its + * child elements. + */ + std::string toString( const std::string &indent = "" ) const; + +private: + typedef std::pair Attribute; + + std::string attributesAsString() const; + std::string escape( std::string value ) const; + +private: + std::string m_name; + std::string m_content; + + typedef CppUnitDeque Attributes; + Attributes m_attributes; + + typedef CppUnitDeque Elements; + Elements m_elements; +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + + +#endif // CPPUNIT_TOOLS_XMLELEMENT_H diff --git a/UnitTests/cppunit/include/cppunit/ui/text/TestRunner.h b/UnitTests/cppunit/include/cppunit/ui/text/TestRunner.h new file mode 100644 index 0000000..023eb83 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/ui/text/TestRunner.h @@ -0,0 +1,24 @@ +#ifndef CPPUNIT_UI_TEXT_TESTRUNNER_H +#define CPPUNIT_UI_TEXT_TESTRUNNER_H + +#include + + +#if defined(CPPUNIT_HAVE_NAMESPACES) + +CPPUNIT_NS_BEGIN +namespace TextUi +{ + + /*! Text TestRunner (DEPRECATED). + * \deprecated Use TextTestRunner instead. + */ + typedef TextTestRunner TestRunner; + +} +CPPUNIT_NS_END + +#endif // defined(CPPUNIT_HAVE_NAMESPACES) + + +#endif // CPPUNIT_UI_TEXT_TESTRUNNER_H diff --git a/UnitTests/cppunit/include/cppunit/ui/text/TextTestRunner.h b/UnitTests/cppunit/include/cppunit/ui/text/TextTestRunner.h new file mode 100644 index 0000000..86da4d4 --- /dev/null +++ b/UnitTests/cppunit/include/cppunit/ui/text/TextTestRunner.h @@ -0,0 +1,97 @@ +#ifndef CPPUNIT_UI_TEXT_TEXTTESTRUNNER_H +#define CPPUNIT_UI_TEXT_TEXTTESTRUNNER_H + + +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +class Outputter; +class Test; +class TestSuite; +class TextOutputter; +class TestResult; +class TestResultCollector; + + + +/*! + * \brief A text mode test runner. + * \ingroup WritingTestResult + * \ingroup ExecutingTest + * + * The test runner manage the life cycle of the added tests. + * + * The test runner can run only one of the added tests or all the tests. + * + * TestRunner prints out a trace as the tests are executed followed by a + * summary at the end. The trace and summary print are optional. + * + * Here is an example of use: + * + * \code + * CppUnit::TextTestRunner runner; + * runner.addTest( ExampleTestCase::suite() ); + * runner.run( "", true ); // Run all tests and wait + * \endcode + * + * The trace is printed using a TextTestProgressListener. The summary is printed + * using a TextOutputter. + * + * You can specify an alternate Outputter at construction + * or later with setOutputter(). + * + * After construction, you can register additional TestListener to eventManager(), + * for a custom progress trace, for example. + * + * \code + * CppUnit::TextTestRunner runner; + * runner.addTest( ExampleTestCase::suite() ); + * runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( + * &runner.result(), + * std::cerr ) ); + * MyCustomProgressTestListener progress; + * runner.eventManager().addListener( &progress ); + * runner.run( "", true ); // Run all tests and wait + * \endcode + * + * \see CompilerOutputter, XmlOutputter, TextOutputter. + */ +class CPPUNIT_API TextTestRunner : public CPPUNIT_NS::TestRunner +{ +public: + TextTestRunner( Outputter *outputter =NULL ); + + virtual ~TextTestRunner(); + + bool run( std::string testPath ="", + bool doWait = false, + bool doPrintResult = true, + bool doPrintProgress = true ); + + void setOutputter( Outputter *outputter ); + + TestResultCollector &result() const; + + TestResult &eventManager() const; + +public: // overridden from TestRunner (to avoid hidden virtual function warning) + virtual void run( TestResult &controller, + const std::string &testPath = "" ); + +protected: + virtual void wait( bool doWait ); + virtual void printResult( bool doPrintResult ); + + TestResultCollector *m_result; + TestResult *m_eventManager; + Outputter *m_outputter; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_UI_TEXT_TEXTTESTRUNNER_H diff --git a/UnitTests/cppunit/src/cppunit/AdditionalMessage.cpp b/UnitTests/cppunit/src/cppunit/AdditionalMessage.cpp new file mode 100644 index 0000000..9f3da13 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/AdditionalMessage.cpp @@ -0,0 +1,41 @@ +#include + + +CPPUNIT_NS_BEGIN + + +AdditionalMessage::AdditionalMessage() +{ +} + + +AdditionalMessage::AdditionalMessage( const std::string &detail1 ) +{ + if ( !detail1.empty() ) + addDetail( detail1 ); +} + + +AdditionalMessage::AdditionalMessage( const char *detail1 ) +{ + if ( detail1 && !std::string( detail1 ).empty() ) + addDetail( std::string(detail1) ); +} + + +AdditionalMessage::AdditionalMessage( const Message &other ) + : SuperClass( other ) +{ +} + + +AdditionalMessage & +AdditionalMessage::operator =( const Message &other ) +{ + SuperClass::operator =( other ); + + return *this; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/Asserter.cpp b/UnitTests/cppunit/src/cppunit/Asserter.cpp new file mode 100644 index 0000000..a9cf95c --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/Asserter.cpp @@ -0,0 +1,101 @@ +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +void +Asserter::fail( std::string message, + const SourceLine &sourceLine ) +{ + fail( Message( "assertion failed", message ), sourceLine ); +} + + +void +Asserter::fail( const Message &message, + const SourceLine &sourceLine ) +{ + throw Exception( message, sourceLine ); +} + + +void +Asserter::failIf( bool shouldFail, + const Message &message, + const SourceLine &sourceLine ) +{ + if ( shouldFail ) + fail( message, sourceLine ); +} + + +void +Asserter::failIf( bool shouldFail, + std::string message, + const SourceLine &sourceLine ) +{ + failIf( shouldFail, Message( "assertion failed", message ), sourceLine ); +} + + +std::string +Asserter::makeExpected( const std::string &expectedValue ) +{ + return "Expected: " + expectedValue; +} + + +std::string +Asserter::makeActual( const std::string &actualValue ) +{ + return "Actual : " + actualValue; +} + + +Message +Asserter::makeNotEqualMessage( const std::string &expectedValue, + const std::string &actualValue, + const AdditionalMessage &additionalMessage, + const std::string &shortDescription ) +{ + Message message( shortDescription, + makeExpected( expectedValue ), + makeActual( actualValue ) ); + message.addDetail( additionalMessage ); + + return message; +} + + +void +Asserter::failNotEqual( std::string expected, + std::string actual, + const SourceLine &sourceLine, + const AdditionalMessage &additionalMessage, + std::string shortDescription ) +{ + fail( makeNotEqualMessage( expected, + actual, + additionalMessage, + shortDescription ), + sourceLine ); +} + + +void +Asserter::failNotEqualIf( bool shouldFail, + std::string expected, + std::string actual, + const SourceLine &sourceLine, + const AdditionalMessage &additionalMessage, + std::string shortDescription ) +{ + if ( shouldFail ) + failNotEqual( expected, actual, sourceLine, additionalMessage, shortDescription ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/BeOsDynamicLibraryManager.cpp b/UnitTests/cppunit/src/cppunit/BeOsDynamicLibraryManager.cpp new file mode 100644 index 0000000..b8568be --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/BeOsDynamicLibraryManager.cpp @@ -0,0 +1,49 @@ +#include + +#if defined(CPPUNIT_HAVE_BEOS_DLL_LOADER) +#include + +#include + + +CPPUNIT_NS_BEGIN + + +DynamicLibraryManager::LibraryHandle +DynamicLibraryManager::doLoadLibrary( const std::string &libraryName ) +{ + return (LibraryHandle)::load_add_on( libraryName.c_str() ); +} + + +void +DynamicLibraryManager::doReleaseLibrary() +{ + ::unload_add_on( (image_id)m_libraryHandle ); +} + + +DynamicLibraryManager::Symbol +DynamicLibraryManager::doFindSymbol( const std::string &symbol ) +{ + void *symbolPointer; + if ( ::get_image_symbol( (image_id)m_libraryHandle, + symbol.c_str(), + B_SYMBOL_TYPE_TEXT, + &symbolPointer ) == B_OK ) + return symnolPointer; + return NULL; +} + + +std::string +DynamicLibraryManager::getLastErrorDetail() const +{ + return ""; +} + + +CPPUNIT_NS_END + + +#endif // defined(CPPUNIT_HAVE_BEOS_DLL_LOADER) diff --git a/UnitTests/cppunit/src/cppunit/BriefTestProgressListener.cpp b/UnitTests/cppunit/src/cppunit/BriefTestProgressListener.cpp new file mode 100644 index 0000000..4ea8d35 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/BriefTestProgressListener.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +BriefTestProgressListener::BriefTestProgressListener() + : m_lastTestFailed( false ) +{ +} + + +BriefTestProgressListener::~BriefTestProgressListener() +{ +} + + +void +BriefTestProgressListener::startTest( Test *test ) +{ + stdCOut() << test->getName(); + stdCOut().flush(); + + m_lastTestFailed = false; +} + + +void +BriefTestProgressListener::addFailure( const TestFailure &failure ) +{ + stdCOut() << " : " << (failure.isError() ? "error" : "assertion"); + m_lastTestFailed = true; +} + + +void +BriefTestProgressListener::endTest( Test * ) +{ + if ( !m_lastTestFailed ) + stdCOut() << " : OK"; + stdCOut() << "\n"; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/CompilerOutputter.cpp b/UnitTests/cppunit/src/cppunit/CompilerOutputter.cpp new file mode 100644 index 0000000..8196a5f --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/CompilerOutputter.cpp @@ -0,0 +1,216 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +CompilerOutputter::CompilerOutputter( TestResultCollector *result, + OStream &stream, + const std::string &locationFormat ) + : m_result( result ) + , m_stream( stream ) + , m_locationFormat( locationFormat ) + , m_wrapColumn( CPPUNIT_WRAP_COLUMN ) +{ +} + + +CompilerOutputter::~CompilerOutputter() +{ +} + + +void +CompilerOutputter::setLocationFormat( const std::string &locationFormat ) +{ + m_locationFormat = locationFormat; +} + + +CompilerOutputter * +CompilerOutputter::defaultOutputter( TestResultCollector *result, + OStream &stream ) +{ + return new CompilerOutputter( result, stream ); +} + + +void +CompilerOutputter::write() +{ + if ( m_result->wasSuccessful() ) + printSuccess(); + else + printFailureReport(); +} + + +void +CompilerOutputter::printSuccess() +{ + m_stream << "OK (" << m_result->runTests() << ")\n"; +} + + +void +CompilerOutputter::printFailureReport() +{ + printFailuresList(); + printStatistics(); +} + + +void +CompilerOutputter::printFailuresList() +{ + for ( int index =0; index < m_result->testFailuresTotal(); ++index) + { + printFailureDetail( m_result->failures()[ index ] ); + } +} + + +void +CompilerOutputter::printFailureDetail( TestFailure *failure ) +{ + printFailureLocation( failure->sourceLine() ); + printFailureType( failure ); + printFailedTestName( failure ); + printFailureMessage( failure ); +} + + +void +CompilerOutputter::printFailureLocation( SourceLine sourceLine ) +{ + if ( !sourceLine.isValid() ) + { + m_stream << "##Failure Location unknown## : "; + return; + } + + std::string location; + for ( unsigned int index = 0; index < m_locationFormat.length(); ++index ) + { + char c = m_locationFormat[ index ]; + if ( c == '%' && ( index+1 < m_locationFormat.length() ) ) + { + char command = m_locationFormat[index+1]; + if ( processLocationFormatCommand( command, sourceLine ) ) + { + ++index; + continue; + } + } + + m_stream << c; + } +} + + +bool +CompilerOutputter::processLocationFormatCommand( char command, + const SourceLine &sourceLine ) +{ + switch ( command ) + { + case 'p': + m_stream << sourceLine.fileName(); + return true; + case 'l': + m_stream << sourceLine.lineNumber(); + return true; + case 'f': + m_stream << extractBaseName( sourceLine.fileName() ); + return true; + } + + return false; +} + + +std::string +CompilerOutputter::extractBaseName( const std::string &fileName ) const +{ + int indexLastDirectorySeparator = fileName.find_last_of( '/' ); + + if ( indexLastDirectorySeparator < 0 ) + indexLastDirectorySeparator = fileName.find_last_of( '\\' ); + + if ( indexLastDirectorySeparator < 0 ) + return fileName; + + return fileName.substr( indexLastDirectorySeparator +1 ); +} + + +void +CompilerOutputter::printFailureType( TestFailure *failure ) +{ + m_stream << (failure->isError() ? "Error" : "Assertion"); +} + + +void +CompilerOutputter::printFailedTestName( TestFailure *failure ) +{ + m_stream << "\nTest name: " << failure->failedTestName(); +} + + +void +CompilerOutputter::printFailureMessage( TestFailure *failure ) +{ + m_stream << "\n"; + Exception *thrownException = failure->thrownException(); + m_stream << thrownException->message().shortDescription() << "\n"; + + std::string message = thrownException->message().details(); + if ( m_wrapColumn > 0 ) + message = StringTools::wrap( message, m_wrapColumn ); + + m_stream << message << "\n"; +} + + +void +CompilerOutputter::printStatistics() +{ + m_stream << "Failures !!!\n"; + m_stream << "Run: " << m_result->runTests() << " " + << "Failure total: " << m_result->testFailuresTotal() << " " + << "Failures: " << m_result->testFailures() << " " + << "Errors: " << m_result->testErrors() + << "\n"; +} + + +void +CompilerOutputter::setWrapColumn( int wrapColumn ) +{ + m_wrapColumn = wrapColumn; +} + + +void +CompilerOutputter::setNoWrap() +{ + m_wrapColumn = 0; +} + + +int +CompilerOutputter::wrapColumn() const +{ + return m_wrapColumn; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/DefaultProtector.cpp b/UnitTests/cppunit/src/cppunit/DefaultProtector.cpp new file mode 100644 index 0000000..6fb306b --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/DefaultProtector.cpp @@ -0,0 +1,42 @@ +#include +#include +#include "DefaultProtector.h" + + +CPPUNIT_NS_BEGIN + + +bool +DefaultProtector::protect( const Functor &functor, + const ProtectorContext &context ) +{ + try + { + return functor(); + } + catch ( Exception &failure ) + { + reportFailure( context, failure ); + } + catch ( std::exception &e ) + { + std::string shortDescription( "uncaught exception of type " ); +#if CPPUNIT_USE_TYPEINFO_NAME + shortDescription += TypeInfoHelper::getClassName( typeid(e) ); +#else + shortDescription += "std::exception (or derived)."; +#endif + Message message( shortDescription, e.what() ); + reportError( context, message ); + } + catch ( ... ) + { + reportError( context, + Message( "uncaught exception of unknown type") ); + } + + return false; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/DefaultProtector.h b/UnitTests/cppunit/src/cppunit/DefaultProtector.h new file mode 100644 index 0000000..4a76ea0 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/DefaultProtector.h @@ -0,0 +1,27 @@ +#ifndef CPPUNIT_DEFAULTPROTECTOR_H +#define CPPUNIT_DEFAULTPROTECTOR_H + +#include + +CPPUNIT_NS_BEGIN + +/*! \brief Default protector that catch all exceptions (Implementation). + * + * Implementation detail. + * \internal This protector catch and generate a failure for the following + * exception types: + * - Exception + * - std::exception + * - ... + */ +class DefaultProtector : public Protector +{ +public: + bool protect( const Functor &functor, + const ProtectorContext &context ); +}; + +CPPUNIT_NS_END + +#endif // CPPUNIT_DEFAULTPROTECTOR_H + diff --git a/UnitTests/cppunit/src/cppunit/DllMain.cpp b/UnitTests/cppunit/src/cppunit/DllMain.cpp new file mode 100644 index 0000000..51fe31e --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/DllMain.cpp @@ -0,0 +1,16 @@ +#define WIN32_LEAN_AND_MEAN +#define NOGDI +#define NOUSER +#define NOKERNEL +#define NOSOUND +#define BLENDFUNCTION void // for mingw & gcc + +#include + +BOOL APIENTRY +DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved ) +{ + return TRUE; +} diff --git a/UnitTests/cppunit/src/cppunit/DynamicLibraryManager.cpp b/UnitTests/cppunit/src/cppunit/DynamicLibraryManager.cpp new file mode 100644 index 0000000..e6f6294 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/DynamicLibraryManager.cpp @@ -0,0 +1,77 @@ +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) +#include + +CPPUNIT_NS_BEGIN + + +DynamicLibraryManager::DynamicLibraryManager( const std::string &libraryFileName ) + : m_libraryHandle( NULL ) + , m_libraryName( libraryFileName ) +{ + loadLibrary( libraryFileName ); +} + + +DynamicLibraryManager::~DynamicLibraryManager() +{ + releaseLibrary(); +} + + +DynamicLibraryManager::Symbol +DynamicLibraryManager::findSymbol( const std::string &symbol ) +{ + try + { + Symbol symbolPointer = doFindSymbol( symbol ); + if ( symbolPointer != NULL ) + return symbolPointer; + } + catch ( ... ) + { + } + + throw DynamicLibraryManagerException( m_libraryName, + symbol, + DynamicLibraryManagerException::symbolNotFound ); + return NULL; // keep compiler happy +} + + +void +DynamicLibraryManager::loadLibrary( const std::string &libraryName ) +{ + try + { + releaseLibrary(); + m_libraryHandle = doLoadLibrary( libraryName ); + if ( m_libraryHandle != NULL ) + return; + } + catch (...) + { + } + + throw DynamicLibraryManagerException( m_libraryName, + getLastErrorDetail(), + DynamicLibraryManagerException::loadingFailed ); +} + + +void +DynamicLibraryManager::releaseLibrary() +{ + if ( m_libraryHandle != NULL ) + { + doReleaseLibrary(); + m_libraryHandle = NULL; + } +} + + +CPPUNIT_NS_END + + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) diff --git a/UnitTests/cppunit/src/cppunit/DynamicLibraryManagerException.cpp b/UnitTests/cppunit/src/cppunit/DynamicLibraryManagerException.cpp new file mode 100644 index 0000000..8498652 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/DynamicLibraryManagerException.cpp @@ -0,0 +1,41 @@ +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +CPPUNIT_NS_BEGIN + + +DynamicLibraryManagerException::DynamicLibraryManagerException( + const std::string &libraryName, + const std::string &errorDetail, + Cause cause ) + : std::runtime_error( "" ), + m_cause( cause ) +{ + if ( cause == loadingFailed ) + m_message = "Failed to load dynamic library: " + libraryName + "\n" + + errorDetail; + else + m_message = "Symbol [" + errorDetail + "] not found in dynamic libary:" + + libraryName; +} + + +DynamicLibraryManagerException::Cause +DynamicLibraryManagerException::getCause() const +{ + return m_cause; +} + + +const char * +DynamicLibraryManagerException::what() const throw() +{ + return m_message.c_str(); +} + + +CPPUNIT_NS_END + + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) diff --git a/UnitTests/cppunit/src/cppunit/Exception.cpp b/UnitTests/cppunit/src/cppunit/Exception.cpp new file mode 100644 index 0000000..3bbe24b --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/Exception.cpp @@ -0,0 +1,126 @@ +#include + + +CPPUNIT_NS_BEGIN + + +#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED +/*! + * \deprecated Use SourceLine::isValid() instead. + */ +const std::string Exception::UNKNOWNFILENAME = ""; + +/*! + * \deprecated Use SourceLine::isValid() instead. + */ +const long Exception::UNKNOWNLINENUMBER = -1; +#endif + + +Exception::Exception( const Exception &other ) + : std::exception( other ) +{ + m_message = other.m_message; + m_sourceLine = other.m_sourceLine; +} + + +Exception::Exception( const Message &message, + const SourceLine &sourceLine ) + : m_message( message ) + , m_sourceLine( sourceLine ) +{ +} + + +#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED +Exception::Exception( std::string message, + long lineNumber, + std::string fileName ) + : m_message( message ) + , m_sourceLine( fileName, lineNumber ) +{ +} +#endif + + +Exception::~Exception() throw() +{ +} + + +Exception & +Exception::operator =( const Exception& other ) +{ +// Don't call superclass operator =(). VC++ STL implementation +// has a bug. It calls the destructor and copy constructor of +// std::exception() which reset the virtual table to std::exception. +// SuperClass::operator =(other); + + if ( &other != this ) + { + m_message = other.m_message; + m_sourceLine = other.m_sourceLine; + } + + return *this; +} + + +const char* +Exception::what() const throw() +{ + Exception *mutableThis = CPPUNIT_CONST_CAST( Exception *, this ); + mutableThis->m_whatMessage = m_message.shortDescription() + "\n" + + m_message.details(); + return m_whatMessage.c_str(); +} + + +SourceLine +Exception::sourceLine() const +{ + return m_sourceLine; +} + + +Message +Exception::message() const +{ + return m_message; +} + + +void +Exception::setMessage( const Message &message ) +{ + m_message = message; +} + + +#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED +long +Exception::lineNumber() const +{ + return m_sourceLine.isValid() ? m_sourceLine.lineNumber() : + UNKNOWNLINENUMBER; +} + + +std::string +Exception::fileName() const +{ + return m_sourceLine.isValid() ? m_sourceLine.fileName() : + UNKNOWNFILENAME; +} +#endif + + +Exception * +Exception::clone() const +{ + return new Exception( *this ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/Message.cpp b/UnitTests/cppunit/src/cppunit/Message.cpp new file mode 100644 index 0000000..9d6a0e9 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/Message.cpp @@ -0,0 +1,170 @@ +#include +#include + + +CPPUNIT_NS_BEGIN + + +Message::Message() +{ +} + +Message::Message( const Message &other ) +{ + *this = other; +} + + +Message::Message( const std::string &shortDescription ) + : m_shortDescription( shortDescription ) +{ +} + + +Message::Message( const std::string &shortDescription, + const std::string &detail1 ) + : m_shortDescription( shortDescription ) +{ + addDetail( detail1 ); +} + + +Message::Message( const std::string &shortDescription, + const std::string &detail1, + const std::string &detail2 ) + : m_shortDescription( shortDescription ) +{ + addDetail( detail1, detail2 ); +} + + +Message::Message( const std::string &shortDescription, + const std::string &detail1, + const std::string &detail2, + const std::string &detail3 ) + : m_shortDescription( shortDescription ) +{ + addDetail( detail1, detail2, detail3 ); +} + +Message & +Message::operator =( const Message &other ) +{ + if ( this != &other ) + { + m_shortDescription = other.m_shortDescription.c_str(); + m_details.clear(); + Details::const_iterator it = other.m_details.begin(); + Details::const_iterator itEnd = other.m_details.end(); + while ( it != itEnd ) + m_details.push_back( (*it++).c_str() ); + } + + return *this; +} + + +const std::string & +Message::shortDescription() const +{ + return m_shortDescription; +} + + +int +Message::detailCount() const +{ + return m_details.size(); +} + + +std::string +Message::detailAt( int index ) const +{ + if ( index < 0 || index >= detailCount() ) + throw std::invalid_argument( "Message::detailAt() : invalid index" ); + + return m_details[ index ]; +} + + +std::string +Message::details() const +{ + std::string details; + for ( Details::const_iterator it = m_details.begin(); it != m_details.end(); ++it ) + { + details += "- "; + details += *it; + details += '\n'; + } + return details; +} + + +void +Message::clearDetails() +{ + m_details.clear(); +} + + +void +Message::addDetail( const std::string &detail ) +{ + m_details.push_back( detail ); +} + + +void +Message::addDetail( const std::string &detail1, + const std::string &detail2 ) +{ + addDetail( detail1 ); + addDetail( detail2 ); +} + + +void +Message::addDetail( const std::string &detail1, + const std::string &detail2, + const std::string &detail3 ) +{ + addDetail( detail1, detail2 ); + addDetail( detail3 ); +} + + +void +Message::addDetail( const Message &message ) +{ + m_details.insert( m_details.end(), + message.m_details.begin(), + message.m_details.end() ); +} + + +void +Message::setShortDescription( const std::string &shortDescription ) +{ + m_shortDescription = shortDescription; +} + + +bool +Message::operator ==( const Message &other ) const +{ + return m_shortDescription == other.m_shortDescription && + m_details == other.m_details; +} + + +bool +Message::operator !=( const Message &other ) const +{ + return !( *this == other ); +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/PlugInManager.cpp b/UnitTests/cppunit/src/cppunit/PlugInManager.cpp new file mode 100644 index 0000000..b595dee --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/PlugInManager.cpp @@ -0,0 +1,110 @@ +#include +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +PlugInManager::PlugInManager() +{ +} + + +PlugInManager::~PlugInManager() +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + unload( *it ); +} + + +void +PlugInManager::load( const std::string &libraryFileName, + const PlugInParameters ¶meters ) +{ + PlugInInfo info; + info.m_fileName = libraryFileName; + info.m_manager = new DynamicLibraryManager( libraryFileName ); + + TestPlugInSignature plug = (TestPlugInSignature)info.m_manager->findSymbol( + CPPUNIT_STRINGIZE( CPPUNIT_PLUGIN_EXPORTED_NAME ) ); + info.m_interface = (*plug)(); + + m_plugIns.push_back( info ); + + info.m_interface->initialize( &TestFactoryRegistry::getRegistry(), parameters ); +} + + +void +PlugInManager::unload( const std::string &libraryFileName ) +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + { + if ( (*it).m_fileName == libraryFileName ) + { + unload( *it ); + m_plugIns.erase( it ); + break; + } + } +} + + +void +PlugInManager::addListener( TestResult *eventManager ) +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + (*it).m_interface->addListener( eventManager ); +} + + +void +PlugInManager::removeListener( TestResult *eventManager ) +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + (*it).m_interface->removeListener( eventManager ); +} + + +void +PlugInManager::unload( PlugInInfo &plugIn ) +{ + try + { + plugIn.m_interface->uninitialize( &TestFactoryRegistry::getRegistry() ); + delete plugIn.m_manager; + } + catch (...) + { + delete plugIn.m_manager; + plugIn.m_manager = NULL; + throw; + } +} + + +void +PlugInManager::addXmlOutputterHooks( XmlOutputter *outputter ) +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + (*it).m_interface->addXmlOutputterHooks( outputter ); +} + + +void +PlugInManager::removeXmlOutputterHooks() +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + (*it).m_interface->removeXmlOutputterHooks(); +} + + +CPPUNIT_NS_END + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) diff --git a/UnitTests/cppunit/src/cppunit/PlugInParameters.cpp b/UnitTests/cppunit/src/cppunit/PlugInParameters.cpp new file mode 100644 index 0000000..1b532f9 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/PlugInParameters.cpp @@ -0,0 +1,28 @@ +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +CPPUNIT_NS_BEGIN + + +PlugInParameters::PlugInParameters( const std::string &commandLine ) + : m_commandLine( commandLine ) +{ +} + + +PlugInParameters::~PlugInParameters() +{ +} + + +std::string +PlugInParameters::getCommandLine() const +{ + return m_commandLine; +} + + +CPPUNIT_NS_END + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) diff --git a/UnitTests/cppunit/src/cppunit/Protector.cpp b/UnitTests/cppunit/src/cppunit/Protector.cpp new file mode 100644 index 0000000..5c171ec --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/Protector.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include "ProtectorContext.h" +#include + +CPPUNIT_NS_BEGIN + +Functor::~Functor() +{ +} + + +Protector::~Protector() +{ +} + + +void +Protector::reportError( const ProtectorContext &context, + const Exception &error ) const +{ + std::auto_ptr actualError( error.clone() ); + actualError->setMessage( actualMessage( actualError->message(), context ) ); + context.m_result->addError( context.m_test, + actualError.release() ); +} + + + +void +Protector::reportError( const ProtectorContext &context, + const Message &message, + const SourceLine &sourceLine ) const +{ + reportError( context, Exception( message, sourceLine ) ); +} + + +void +Protector::reportFailure( const ProtectorContext &context, + const Exception &failure ) const +{ + std::auto_ptr actualFailure( failure.clone() ); + actualFailure->setMessage( actualMessage( actualFailure->message(), context ) ); + context.m_result->addFailure( context.m_test, + actualFailure.release() ); +} + + +Message +Protector::actualMessage( const Message &message, + const ProtectorContext &context ) const +{ + Message theActualMessage; + if ( context.m_shortDescription.empty() ) + theActualMessage = message; + else + { + theActualMessage = Message( context.m_shortDescription, + message.shortDescription() ); + theActualMessage.addDetail( message ); + } + + return theActualMessage; +} + + + + +ProtectorGuard::ProtectorGuard( TestResult *result, + Protector *protector ) + : m_result( result ) +{ + m_result->pushProtector( protector ); +} + + +ProtectorGuard::~ProtectorGuard() +{ + m_result->popProtector(); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/ProtectorChain.cpp b/UnitTests/cppunit/src/cppunit/ProtectorChain.cpp new file mode 100644 index 0000000..f528341 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/ProtectorChain.cpp @@ -0,0 +1,86 @@ +#include "ProtectorChain.h" + +CPPUNIT_NS_BEGIN + + +class ProtectorChain::ProtectFunctor : public Functor +{ +public: + ProtectFunctor( Protector *protector, + const Functor &functor, + const ProtectorContext &context ) + : m_protector( protector ) + , m_functor( functor ) + , m_context( context ) + { + } + + bool operator()() const + { + return m_protector->protect( m_functor, m_context ); + } + +private: + Protector *m_protector; + const Functor &m_functor; + const ProtectorContext &m_context; +}; + + +ProtectorChain::~ProtectorChain() +{ + while ( count() > 0 ) + pop(); +} + + +void +ProtectorChain::push( Protector *protector ) +{ + m_protectors.push_back( protector ); +} + + +void +ProtectorChain::pop() +{ + delete m_protectors.back(); + m_protectors.pop_back(); +} + +int +ProtectorChain::count() const +{ + return m_protectors.size(); +} + + +bool +ProtectorChain::protect( const Functor &functor, + const ProtectorContext &context ) +{ + if ( m_protectors.empty() ) + return functor(); + + Functors functors; + for ( int index = m_protectors.size()-1; index >= 0; --index ) + { + const Functor &protectedFunctor = + functors.empty() ? functor : *functors.back(); + + functors.push_back( new ProtectFunctor( m_protectors[index], + protectedFunctor, + context ) ); + } + + const Functor &outermostFunctor = *functors.back(); + bool succeed = outermostFunctor(); + + for ( unsigned int deletingIndex = 0; deletingIndex < m_protectors.size(); ++deletingIndex ) + delete functors[deletingIndex]; + + return succeed; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/ProtectorChain.h b/UnitTests/cppunit/src/cppunit/ProtectorChain.h new file mode 100644 index 0000000..711b56f --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/ProtectorChain.h @@ -0,0 +1,51 @@ +#ifndef CPPUNIT_PROTECTORCHAIN_H +#define CPPUNIT_PROTECTORCHAIN_H + +#include +#include + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( push ) +#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#endif + + +CPPUNIT_NS_BEGIN + +/*! \brief Protector chain (Implementation). + * Implementation detail. + * \internal Protector that protect a Functor using a chain of nested Protector. + */ +class CPPUNIT_API ProtectorChain : public Protector +{ +public: + ~ProtectorChain(); + + void push( Protector *protector ); + + void pop(); + + int count() const; + + bool protect( const Functor &functor, + const ProtectorContext &context ); + +private: + class ProtectFunctor; + +private: + typedef CppUnitDeque Protectors; + Protectors m_protectors; + + typedef CppUnitDeque Functors; +}; + + +CPPUNIT_NS_END + +#if CPPUNIT_NEED_DLL_DECL +#pragma warning( pop ) +#endif + +#endif // CPPUNIT_PROTECTORCHAIN_H + diff --git a/UnitTests/cppunit/src/cppunit/ProtectorContext.h b/UnitTests/cppunit/src/cppunit/ProtectorContext.h new file mode 100644 index 0000000..c3d496c --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/ProtectorContext.h @@ -0,0 +1,38 @@ +#ifndef CPPUNIT_PROTECTORCONTEXT_H +#define CPPUNIT_PROTECTORCONTEXT_H + +#include +#include + +CPPUNIT_NS_BEGIN + +class Test; +class TestResult; + + +/*! \brief Protector context (Implementation). + * Implementation detail. + * \internal Context use to report failure in Protector. + */ +class CPPUNIT_API ProtectorContext +{ +public: + ProtectorContext( Test *test, + TestResult *result, + const std::string &shortDescription ) + : m_test( test ) + , m_result( result ) + , m_shortDescription( shortDescription ) + { + } + + Test *m_test; + TestResult *m_result; + std::string m_shortDescription; +}; + + +CPPUNIT_NS_END + +#endif // CPPUNIT_PROTECTORCONTEXT_H + diff --git a/UnitTests/cppunit/src/cppunit/RepeatedTest.cpp b/UnitTests/cppunit/src/cppunit/RepeatedTest.cpp new file mode 100644 index 0000000..2533ca1 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/RepeatedTest.cpp @@ -0,0 +1,29 @@ +#include +#include + +CPPUNIT_NS_BEGIN + + +// Counts the number of test cases that will be run by this test. +int +RepeatedTest::countTestCases() const +{ + return TestDecorator::countTestCases() * m_timesRepeat; +} + + +// Runs a repeated test +void +RepeatedTest::run( TestResult *result ) +{ + for ( int n = 0; n < m_timesRepeat; n++ ) + { + if ( result->shouldStop() ) + break; + + TestDecorator::run( result ); + } +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/ShlDynamicLibraryManager.cpp b/UnitTests/cppunit/src/cppunit/ShlDynamicLibraryManager.cpp new file mode 100644 index 0000000..9f4be22 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/ShlDynamicLibraryManager.cpp @@ -0,0 +1,53 @@ +#include + +#if defined(CPPUNIT_HAVE_UNIX_SHL_LOADER) +#include + +#include +#include + + +CPPUNIT_NS_BEGIN + + +DynamicLibraryManager::LibraryHandle +DynamicLibraryManager::doLoadLibrary( const std::string &libraryName ) +{ + return ::shl_load(libraryName.c_str(), BIND_IMMEDIATE, 0L); +} + + +void +DynamicLibraryManager::doReleaseLibrary() +{ + ::shl_unload( (shl_t)m_libraryHandle); +} + + +DynamicLibraryManager::Symbol +DynamicLibraryManager::doFindSymbol( const std::string &symbol ) +{ + DynamicLibraryManager::Symbol L_symaddr = 0; + if ( ::shl_findsym( (shl_t*)(&m_libraryHandle), + symbol.c_str(), + TYPE_UNDEFINED, + &L_symaddr ) == 0 ) + { + return L_symaddr; + } + + return 0; +} + + +std::string +DynamicLibraryManager::getLastErrorDetail() const +{ + return ""; +} + + +CPPUNIT_NS_END + + +#endif // defined(CPPUNIT_HAVE_UNIX_SHL_LOADER) diff --git a/UnitTests/cppunit/src/cppunit/SourceLine.cpp b/UnitTests/cppunit/src/cppunit/SourceLine.cpp new file mode 100644 index 0000000..dfadae3 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/SourceLine.cpp @@ -0,0 +1,81 @@ +#include + + +CPPUNIT_NS_BEGIN + + +SourceLine::SourceLine() : + m_lineNumber( -1 ) +{ +} + + +SourceLine::SourceLine( const SourceLine &other ) + : m_fileName( other.m_fileName.c_str() ) + , m_lineNumber( other.m_lineNumber ) +{ +} + + +SourceLine::SourceLine( const std::string &fileName, + int lineNumber ) + : m_fileName( fileName.c_str() ) + , m_lineNumber( lineNumber ) +{ +} + + +SourceLine & +SourceLine::operator =( const SourceLine &other ) +{ + if ( this != &other ) + { + m_fileName = other.m_fileName.c_str(); + m_lineNumber = other.m_lineNumber; + } + return *this; +} + + +SourceLine::~SourceLine() +{ +} + + +bool +SourceLine::isValid() const +{ + return !m_fileName.empty(); +} + + +int +SourceLine::lineNumber() const +{ + return m_lineNumber; +} + + +std::string +SourceLine::fileName() const +{ + return m_fileName; +} + + +bool +SourceLine::operator ==( const SourceLine &other ) const +{ + return m_fileName == other.m_fileName && + m_lineNumber == other.m_lineNumber; +} + + +bool +SourceLine::operator !=( const SourceLine &other ) const +{ + return !( *this == other ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/StringTools.cpp b/UnitTests/cppunit/src/cppunit/StringTools.cpp new file mode 100644 index 0000000..dc995d8 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/StringTools.cpp @@ -0,0 +1,80 @@ +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +std::string +StringTools::toString( int value ) +{ + OStringStream stream; + stream << value; + return stream.str(); +} + + +std::string +StringTools::toString( double value ) +{ + OStringStream stream; + stream << value; + return stream.str(); +} + + +StringTools::Strings +StringTools::split( const std::string &text, + char separator ) +{ + Strings splittedText; + + std::string::const_iterator itStart = text.begin(); + while ( !text.empty() ) + { + std::string::const_iterator itSeparator = std::find( itStart, + text.end(), + separator ); + splittedText.push_back( text.substr( itStart - text.begin(), + itSeparator - itStart ) ); + if ( itSeparator == text.end() ) + break; + itStart = itSeparator +1; + } + + return splittedText; +} + + +std::string +StringTools::wrap( const std::string &text, + int wrapColumn ) +{ + const char lineBreak = '\n'; + Strings lines = split( text, lineBreak ); + + std::string wrapped; + for ( Strings::const_iterator it = lines.begin(); it != lines.end(); ++it ) + { + if ( it != lines.begin() ) + wrapped += lineBreak; + + const std::string &line = *it; + unsigned int index =0; + while ( index < line.length() ) + { + std::string lineSlice( line.substr( index, wrapColumn ) ); + wrapped += lineSlice; + index += wrapColumn; + if ( index < line.length() ) + wrapped += lineBreak; + } + } + + return wrapped; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/SynchronizedObject.cpp b/UnitTests/cppunit/src/cppunit/SynchronizedObject.cpp new file mode 100644 index 0000000..1764538 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/SynchronizedObject.cpp @@ -0,0 +1,32 @@ +#include + + +CPPUNIT_NS_BEGIN + + +SynchronizedObject::SynchronizedObject( SynchronizationObject *syncObject ) + : m_syncObject( syncObject == 0 ? new SynchronizationObject() : + syncObject ) +{ +} + + +SynchronizedObject::~SynchronizedObject() +{ + delete m_syncObject; +} + + +/** Accept a new synchronization object for protection of this instance + * TestResult assumes ownership of the object + */ +void +SynchronizedObject::setSynchronizationObject( SynchronizationObject *syncObject ) +{ + delete m_syncObject; + m_syncObject = syncObject; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/Test.cpp b/UnitTests/cppunit/src/cppunit/Test.cpp new file mode 100644 index 0000000..fef8be7 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/Test.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +Test * +Test::getChildTestAt( int index ) const +{ + checkIsValidIndex( index ); + return doGetChildTestAt( index ); +} + + +Test * +Test::findTest( const std::string &testName ) const +{ + TestPath path; + Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this ); + mutableThis->findTestPath( testName, path ); + if ( !path.isValid() ) + throw std::invalid_argument( "No test named <" + testName + "> found in test <" + + getName() + ">." ); + return path.getChildTest(); +} + + +bool +Test::findTestPath( const std::string &testName, + TestPath &testPath ) const +{ + Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this ); + if ( getName() == testName ) + { + testPath.add( mutableThis ); + return true; + } + + int childCount = getChildTestCount(); + for ( int childIndex =0; childIndex < childCount; ++childIndex ) + { + if ( getChildTestAt( childIndex )->findTestPath( testName, testPath ) ) + { + testPath.insert( mutableThis, 0 ); + return true; + } + } + + return false; +} + + +bool +Test::findTestPath( const Test *test, + TestPath &testPath ) const +{ + Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this ); + if ( this == test ) + { + testPath.add( mutableThis ); + return true; + } + + int childCount = getChildTestCount(); + for ( int childIndex =0; childIndex < childCount; ++childIndex ) + { + if ( getChildTestAt( childIndex )->findTestPath( test, testPath ) ) + { + testPath.insert( mutableThis, 0 ); + return true; + } + } + + return false; +} + + +TestPath +Test::resolveTestPath( const std::string &testPath ) const +{ + Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this ); + return TestPath( mutableThis, testPath ); +} + + +void +Test::checkIsValidIndex( int index ) const +{ + if ( index < 0 || index >= getChildTestCount() ) + throw std::out_of_range( "Test::checkValidIndex(): invalid index" ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestAssert.cpp b/UnitTests/cppunit/src/cppunit/TestAssert.cpp new file mode 100644 index 0000000..6e4e794 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestAssert.cpp @@ -0,0 +1,46 @@ +#include +#include + +CPPUNIT_NS_BEGIN + + +void +assertDoubleEquals( double expected, + double actual, + double delta, + SourceLine sourceLine, + const std::string &message ) +{ + AdditionalMessage msg( "Delta : " + + assertion_traits::toString(delta) ); + msg.addDetail( AdditionalMessage(message) ); + + bool equal; + if ( floatingPointIsFinite(expected) && floatingPointIsFinite(actual) ) + equal = fabs( expected - actual ) <= delta; + else + { + // If expected or actual is not finite, it may be +inf, -inf or NaN (Not a Number). + // Value of +inf or -inf leads to a true equality regardless of delta if both + // expected and actual have the same value (infinity sign). + // NaN Value should always lead to a failed equality. + if ( floatingPointIsUnordered(expected) || floatingPointIsUnordered(actual) ) + { + equal = false; // expected or actual is a NaN + } + else // ordered values, +inf or -inf comparison + { + equal = expected == actual; + } + } + + Asserter::failNotEqualIf( !equal, + assertion_traits::toString(expected), + assertion_traits::toString(actual), + sourceLine, + msg, + "double equality assertion failed" ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestCase.cpp b/UnitTests/cppunit/src/cppunit/TestCase.cpp new file mode 100644 index 0000000..13c0525 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestCase.cpp @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include +#include + +#if CPPUNIT_USE_TYPEINFO_NAME +# include +#endif + +CPPUNIT_NS_BEGIN + +/*! \brief Functor to call test case method (Implementation). + * + * Implementation detail. + */ +class TestCaseMethodFunctor : public Functor +{ +public: + typedef void (TestCase::*Method)(); + + TestCaseMethodFunctor( TestCase *target, + Method method ) + : m_target( target ) + , m_method( method ) + { + } + + bool operator()() const + { + (m_target->*m_method)(); + return true; + } + +private: + TestCase *m_target; + Method m_method; +}; + + +/** Constructs a test case. + * \param name the name of the TestCase. + **/ +TestCase::TestCase( const std::string &name ) + : m_name(name) +{ +} + + +/// Run the test and catch any exceptions that are triggered by it +void +TestCase::run( TestResult *result ) +{ + result->startTest(this); +/* + try { + setUp(); + + try { + runTest(); + } + catch ( Exception &e ) { + Exception *copy = e.clone(); + result->addFailure( this, copy ); + } + catch ( std::exception &e ) { + result->addError( this, new Exception( Message( "uncaught std::exception", + e.what() ) ) ); + } + catch (...) { + Exception *e = new Exception( Message( "uncaught unknown exception" ) ); + result->addError( this, e ); + } + + try { + tearDown(); + } + catch (...) { + result->addError( this, new Exception( Message( "tearDown() failed" ) ) ); + } + } + catch (...) { + result->addError( this, new Exception( Message( "setUp() failed" ) ) ); + } +*/ + if ( result->protect( TestCaseMethodFunctor( this, &TestCase::setUp ), + this, + "setUp() failed" ) ) + { + result->protect( TestCaseMethodFunctor( this, &TestCase::runTest ), + this ); + } + + result->protect( TestCaseMethodFunctor( this, &TestCase::tearDown ), + this, + "tearDown() failed" ); + + result->endTest( this ); +} + + +/// All the work for runTest is deferred to subclasses +void +TestCase::runTest() +{ +} + + +/** Constructs a test case for a suite. + * \deprecated This constructor was used by fixture when TestFixture did not exist. + * Have your fixture inherits TestFixture instead of TestCase. + * \internal + * This TestCase was intended for use by the TestCaller and should not + * be used by a test case for which run() is called. + **/ +TestCase::TestCase() + : m_name( "" ) +{ +} + + +/// Destructs a test case +TestCase::~TestCase() +{ +} + + +/// Returns the name of the test case +std::string +TestCase::getName() const +{ + return m_name; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestCaseDecorator.cpp b/UnitTests/cppunit/src/cppunit/TestCaseDecorator.cpp new file mode 100644 index 0000000..a7229f4 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestCaseDecorator.cpp @@ -0,0 +1,47 @@ +#include + +CPPUNIT_NS_BEGIN + + +TestCaseDecorator::TestCaseDecorator( TestCase *test ) + : TestCase( test->getName() ), + m_test( test ) +{ +} + + +TestCaseDecorator::~TestCaseDecorator() +{ + delete m_test; +} + + +std::string +TestCaseDecorator::getName() const +{ + return m_test->getName(); +} + + +void +TestCaseDecorator::setUp() +{ + m_test->setUp(); +} + + +void +TestCaseDecorator::tearDown() +{ + m_test->tearDown(); +} + + +void +TestCaseDecorator::runTest() +{ + m_test->runTest(); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestComposite.cpp b/UnitTests/cppunit/src/cppunit/TestComposite.cpp new file mode 100644 index 0000000..4768791 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestComposite.cpp @@ -0,0 +1,77 @@ +#include +#include + + +CPPUNIT_NS_BEGIN + + +TestComposite::TestComposite( const std::string &name ) + : m_name( name ) +{ +} + + +TestComposite::~TestComposite() +{ +} + + +void +TestComposite::run( TestResult *result ) +{ + doStartSuite( result ); + doRunChildTests( result ); + doEndSuite( result ); +} + + +int +TestComposite::countTestCases() const +{ + int count = 0; + + int childCount = getChildTestCount(); + for ( int index =0; index < childCount; ++index ) + count += getChildTestAt( index )->countTestCases(); + + return count; +} + + +std::string +TestComposite::getName() const +{ + return m_name; +} + + +void +TestComposite::doStartSuite( TestResult *controller ) +{ + controller->startSuite( this ); +} + + +void +TestComposite::doRunChildTests( TestResult *controller ) +{ + int childCount = getChildTestCount(); + for ( int index =0; index < childCount; ++index ) + { + if ( controller->shouldStop() ) + break; + + getChildTestAt( index )->run( controller ); + } +} + + +void +TestComposite::doEndSuite( TestResult *controller ) +{ + controller->endSuite( this ); +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/TestDecorator.cpp b/UnitTests/cppunit/src/cppunit/TestDecorator.cpp new file mode 100644 index 0000000..4e25a6a --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestDecorator.cpp @@ -0,0 +1,53 @@ +#include + +CPPUNIT_NS_BEGIN + + +TestDecorator::TestDecorator( Test *test ) + : m_test( test) +{ +} + + +TestDecorator::~TestDecorator() +{ + delete m_test; +} + + +int +TestDecorator::countTestCases() const +{ + return m_test->countTestCases(); +} + + +void +TestDecorator::run( TestResult *result ) +{ + m_test->run(result); +} + + +std::string +TestDecorator::getName() const +{ + return m_test->getName(); +} + + +int +TestDecorator::getChildTestCount() const +{ + return m_test->getChildTestCount(); +} + + +Test * +TestDecorator::doGetChildTestAt( int index ) const +{ + return m_test->getChildTestAt( index ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestFactoryRegistry.cpp b/UnitTests/cppunit/src/cppunit/TestFactoryRegistry.cpp new file mode 100644 index 0000000..3457da3 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestFactoryRegistry.cpp @@ -0,0 +1,161 @@ +#include +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + +/*! \brief (INTERNAL) List of all TestFactoryRegistry. + */ +class TestFactoryRegistryList +{ +private: + typedef CppUnitMap > Registries; + Registries m_registries; + + enum State { + doNotChange =0, + notCreated, + exist, + destroyed + }; + + static State stateFlag( State newState = doNotChange ) + { + static State state = notCreated; + if ( newState != doNotChange ) + state = newState; + return state; + } + + static TestFactoryRegistryList *getInstance() + { + static TestFactoryRegistryList list; + return &list; + } + + TestFactoryRegistry *getInternalRegistry( const std::string &name ) + { + Registries::const_iterator foundIt = m_registries.find( name ); + if ( foundIt == m_registries.end() ) + { + TestFactoryRegistry *factory = new TestFactoryRegistry( name ); + m_registries.insert( std::pair( name, factory ) ); + return factory; + } + return (*foundIt).second; + } + +public: + TestFactoryRegistryList() + { + stateFlag( exist ); + } + + ~TestFactoryRegistryList() + { + for ( Registries::iterator it = m_registries.begin(); it != m_registries.end(); ++it ) + delete (*it).second; + + stateFlag( destroyed ); + } + + static TestFactoryRegistry *getRegistry( const std::string &name ) + { + // If the following assertion failed, then TestFactoryRegistry::getRegistry() + // was called during static variable destruction without checking the registry + // validity beforehand using TestFactoryRegistry::isValid() beforehand. + assert( isValid() ); + if ( !isValid() ) // release mode + return NULL; // => force CRASH + + return getInstance()->getInternalRegistry( name ); + } + + static bool isValid() + { + return stateFlag() != destroyed; + } +}; + + + +TestFactoryRegistry::TestFactoryRegistry( std::string name ) : + m_name( name ) +{ +} + + +TestFactoryRegistry::~TestFactoryRegistry() +{ +} + + +TestFactoryRegistry & +TestFactoryRegistry::getRegistry( const std::string &name ) +{ + return *TestFactoryRegistryList::getRegistry( name ); +} + + +void +TestFactoryRegistry::registerFactory( const std::string &, + TestFactory *factory ) +{ + registerFactory( factory ); +} + + +void +TestFactoryRegistry::registerFactory( TestFactory *factory ) +{ + m_factories.insert( factory ); +} + + +void +TestFactoryRegistry::unregisterFactory( TestFactory *factory ) +{ + m_factories.erase( factory ); +} + + +void +TestFactoryRegistry::addRegistry( const std::string &name ) +{ + registerFactory( &getRegistry( name ) ); +} + + +Test * +TestFactoryRegistry::makeTest() +{ + TestSuite *suite = new TestSuite( m_name ); + addTestToSuite( suite ); + return suite; +} + + +void +TestFactoryRegistry::addTestToSuite( TestSuite *suite ) +{ + for ( Factories::iterator it = m_factories.begin(); + it != m_factories.end(); + ++it ) + { + TestFactory *factory = *it; + suite->addTest( factory->makeTest() ); + } +} + + +bool +TestFactoryRegistry::isValid() +{ + return TestFactoryRegistryList::isValid(); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestFailure.cpp b/UnitTests/cppunit/src/cppunit/TestFailure.cpp new file mode 100644 index 0000000..e31e138 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestFailure.cpp @@ -0,0 +1,71 @@ +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +/// Constructs a TestFailure with the given test and exception. +TestFailure::TestFailure( Test *failedTest, + Exception *thrownException, + bool isError ) : + m_failedTest( failedTest ), + m_thrownException( thrownException ), + m_isError( isError ) +{ +} + +/// Deletes the owned exception. +TestFailure::~TestFailure() +{ + delete m_thrownException; +} + +/// Gets the failed test. +Test * +TestFailure::failedTest() const +{ + return m_failedTest; +} + + +/// Gets the thrown exception. Never \c NULL. +Exception * +TestFailure::thrownException() const +{ + return m_thrownException; +} + + +/// Gets the failure location. +SourceLine +TestFailure::sourceLine() const +{ + return m_thrownException->sourceLine(); +} + + +/// Indicates if the failure is a failed assertion or an error. +bool +TestFailure::isError() const +{ + return m_isError; +} + + +/// Gets the name of the failed test. +std::string +TestFailure::failedTestName() const +{ + return m_failedTest->getName(); +} + + +TestFailure * +TestFailure::clone() const +{ + return new TestFailure( m_failedTest, m_thrownException->clone(), m_isError ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestLeaf.cpp b/UnitTests/cppunit/src/cppunit/TestLeaf.cpp new file mode 100644 index 0000000..3d8767c --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestLeaf.cpp @@ -0,0 +1,28 @@ +#include + + +CPPUNIT_NS_BEGIN + + +int +TestLeaf::countTestCases() const +{ + return 1; +} + + +int +TestLeaf::getChildTestCount() const +{ + return 0; +} + + +Test * +TestLeaf::doGetChildTestAt( int index ) const +{ + checkIsValidIndex( index ); + return NULL; // never called, checkIsValidIndex() always throw. +} + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestNamer.cpp b/UnitTests/cppunit/src/cppunit/TestNamer.cpp new file mode 100644 index 0000000..eec9be9 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestNamer.cpp @@ -0,0 +1,44 @@ +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +#if CPPUNIT_HAVE_RTTI +TestNamer::TestNamer( const std::type_info &typeInfo ) +{ + m_fixtureName = TypeInfoHelper::getClassName( typeInfo ); +} +#endif + + +TestNamer::TestNamer( const std::string &fixtureName ) + : m_fixtureName( fixtureName ) +{ +} + + +TestNamer::~TestNamer() +{ +} + + +std::string +TestNamer::getFixtureName() const +{ + return m_fixtureName; +} + + +std::string +TestNamer::getTestNameFor( const std::string &testMethodName ) const +{ + return getFixtureName() + "::" + testMethodName; +} + + + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestPath.cpp b/UnitTests/cppunit/src/cppunit/TestPath.cpp new file mode 100644 index 0000000..a2783a2 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestPath.cpp @@ -0,0 +1,254 @@ +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +TestPath::TestPath() +{ +} + + +TestPath::TestPath( Test *root ) +{ + add( root ); +} + + +TestPath::TestPath( const TestPath &other, + int indexFirst, + int count ) +{ + int countAdjustment = 0; + if ( indexFirst < 0 ) + { + countAdjustment = indexFirst; + indexFirst = 0; + } + + if ( count < 0 ) + count = other.getTestCount(); + else + count += countAdjustment; + + int index = indexFirst; + while ( count-- > 0 && index < other.getTestCount() ) + add( other.getTestAt( index++ ) ); +} + + +TestPath::TestPath( Test *searchRoot, + const std::string &pathAsString ) +{ + PathTestNames testNames; + + Test *parentTest = findActualRoot( searchRoot, pathAsString, testNames ); + add( parentTest ); + + for ( unsigned int index = 1; index < testNames.size(); ++index ) + { + bool childFound = false; + for ( int childIndex =0; childIndex < parentTest->getChildTestCount(); ++childIndex ) + { + if ( parentTest->getChildTestAt( childIndex )->getName() == testNames[index] ) + { + childFound = true; + parentTest = parentTest->getChildTestAt( childIndex ); + break; + } + } + + if ( !childFound ) + throw std::invalid_argument( "TestPath::TestPath(): failed to resolve test name <"+ + testNames[index] + "> of path <" + pathAsString + ">" ); + + add( parentTest ); + } +} + + +TestPath::TestPath( const TestPath &other ) + : m_tests( other.m_tests ) +{ +} + + +TestPath::~TestPath() +{ +} + + +TestPath & +TestPath::operator =( const TestPath &other ) +{ + if ( &other != this ) + m_tests = other.m_tests; + return *this; +} + + +bool +TestPath::isValid() const +{ + return getTestCount() > 0; +} + + +void +TestPath::add( Test *test ) +{ + m_tests.push_back( test ); +} + + +void +TestPath::add( const TestPath &path ) +{ + for ( int index =0; index < path.getTestCount(); ++index ) + add( path.getTestAt( index ) ); +} + + +void +TestPath::insert( Test *test, + int index ) +{ + if ( index < 0 || index > getTestCount() ) + throw std::out_of_range( "TestPath::insert(): index out of range" ); + m_tests.insert( m_tests.begin() + index, test ); +} + +void +TestPath::insert( const TestPath &path, + int index ) +{ + int itemIndex = path.getTestCount() -1; + while ( itemIndex >= 0 ) + insert( path.getTestAt( itemIndex-- ), index ); +} + + +void +TestPath::removeTests() +{ + while ( isValid() ) + removeTest( 0 ); +} + + +void +TestPath::removeTest( int index ) +{ + checkIndexValid( index ); + m_tests.erase( m_tests.begin() + index ); +} + + +void +TestPath::up() +{ + checkIndexValid( 0 ); + removeTest( getTestCount() -1 ); +} + + +int +TestPath::getTestCount() const +{ + return m_tests.size(); +} + + +Test * +TestPath::getTestAt( int index ) const +{ + checkIndexValid( index ); + return m_tests[index]; +} + + +Test * +TestPath::getChildTest() const +{ + return getTestAt( getTestCount() -1 ); +} + + +void +TestPath::checkIndexValid( int index ) const +{ + if ( index < 0 || index >= getTestCount() ) + throw std::out_of_range( "TestPath::checkIndexValid(): index out of range" ); +} + + +std::string +TestPath::toString() const +{ + std::string asString( "/" ); + for ( int index =0; index < getTestCount(); ++index ) + { + if ( index > 0 ) + asString += '/'; + asString += getTestAt(index)->getName(); + } + + return asString; +} + + +Test * +TestPath::findActualRoot( Test *searchRoot, + const std::string &pathAsString, + PathTestNames &testNames ) +{ + bool isRelative = splitPathString( pathAsString, testNames ); + + if ( isRelative && pathAsString.empty() ) + return searchRoot; + + if ( testNames.empty() ) + throw std::invalid_argument( "TestPath::TestPath(): invalid root or root name in absolute path" ); + + Test *root = isRelative ? searchRoot->findTest( testNames[0] ) // throw if bad test name + : searchRoot; + if ( root->getName() != testNames[0] ) + throw std::invalid_argument( "TestPath::TestPath(): searchRoot does not match path root name" ); + + return root; +} + + +bool +TestPath::splitPathString( const std::string &pathAsString, + PathTestNames &testNames ) +{ + if ( pathAsString.empty() ) + return true; + + bool isRelative = pathAsString[0] != '/'; + + int index = (isRelative ? 0 : 1); + while ( true ) + { + int separatorIndex = pathAsString.find( '/', index ); + if ( separatorIndex >= 0 ) + { + testNames.push_back( pathAsString.substr( index, separatorIndex - index ) ); + index = separatorIndex + 1; + } + else + { + testNames.push_back( pathAsString.substr( index ) ); + break; + } + } + + return isRelative; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestPlugInDefaultImpl.cpp b/UnitTests/cppunit/src/cppunit/TestPlugInDefaultImpl.cpp new file mode 100644 index 0000000..086dea0 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestPlugInDefaultImpl.cpp @@ -0,0 +1,63 @@ +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +TestPlugInDefaultImpl::TestPlugInDefaultImpl() +{ +} + + +TestPlugInDefaultImpl::~TestPlugInDefaultImpl() +{ +} + + +void +TestPlugInDefaultImpl::initialize( TestFactoryRegistry *, + const PlugInParameters & ) +{ +} + + +void +TestPlugInDefaultImpl::addListener( TestResult * ) +{ +} + + +void +TestPlugInDefaultImpl::removeListener( TestResult * ) +{ +} + + +void +TestPlugInDefaultImpl::addXmlOutputterHooks( XmlOutputter * ) +{ +} + + +void +TestPlugInDefaultImpl::removeXmlOutputterHooks() +{ +} + + +void +TestPlugInDefaultImpl::uninitialize( TestFactoryRegistry * ) +{ +} + + +CPPUNIT_NS_END + + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) diff --git a/UnitTests/cppunit/src/cppunit/TestResult.cpp b/UnitTests/cppunit/src/cppunit/TestResult.cpp new file mode 100644 index 0000000..4b02c30 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestResult.cpp @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#include +#include +#include +#include "DefaultProtector.h" +#include "ProtectorChain.h" +#include "ProtectorContext.h" + +CPPUNIT_NS_BEGIN + + +TestResult::TestResult( SynchronizationObject *syncObject ) + : SynchronizedObject( syncObject ) + , m_protectorChain( new ProtectorChain() ) + , m_stop( false ) +{ + m_protectorChain->push( new DefaultProtector() ); +} + + +TestResult::~TestResult() +{ + stdCOut().flush(); + stdCErr().flush(); + delete m_protectorChain; +} + + +void +TestResult::reset() +{ + ExclusiveZone zone( m_syncObject ); + m_stop = false; +} + + +void +TestResult::addError( Test *test, + Exception *e ) +{ + TestFailure failure( test, e, true ); + addFailure( failure ); +} + + +void +TestResult::addFailure( Test *test, Exception *e ) +{ + TestFailure failure( test, e, false ); + addFailure( failure ); +} + + +void +TestResult::addFailure( const TestFailure &failure ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + (*it)->addFailure( failure ); +} + + +void +TestResult::startTest( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + (*it)->startTest( test ); +} + + +void +TestResult::endTest( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + (*it)->endTest( test ); +} + + +void +TestResult::startSuite( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + (*it)->startSuite( test ); +} + + +void +TestResult::endSuite( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + (*it)->endSuite( test ); +} + + +bool +TestResult::shouldStop() const +{ + ExclusiveZone zone( m_syncObject ); + return m_stop; +} + + +void +TestResult::stop() +{ + ExclusiveZone zone( m_syncObject ); + m_stop = true; +} + + +void +TestResult::addListener( TestListener *listener ) +{ + ExclusiveZone zone( m_syncObject ); + m_listeners.push_back( listener ); +} + + +void +TestResult::removeListener ( TestListener *listener ) +{ + ExclusiveZone zone( m_syncObject ); + removeFromSequence( m_listeners, listener ); +} + + +void +TestResult::runTest( Test *test ) +{ + startTestRun( test ); + test->run( this ); + endTestRun( test ); +} + + +void +TestResult::startTestRun( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + (*it)->startTestRun( test, this ); +} + + +void +TestResult::endTestRun( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + (*it)->endTestRun( test, this ); +} + + +bool +TestResult::protect( const Functor &functor, + Test *test, + const std::string &shortDescription ) +{ + ProtectorContext context( test, this, shortDescription ); + return m_protectorChain->protect( functor, context ); +} + + +void +TestResult::pushProtector( Protector *protector ) +{ + m_protectorChain->push( protector ); +} + + +void +TestResult::popProtector() +{ + m_protectorChain->pop(); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestResultCollector.cpp b/UnitTests/cppunit/src/cppunit/TestResultCollector.cpp new file mode 100644 index 0000000..4371c50 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestResultCollector.cpp @@ -0,0 +1,117 @@ +#include +#include + + +CPPUNIT_NS_BEGIN + + +TestResultCollector::TestResultCollector( SynchronizationObject *syncObject ) + : TestSuccessListener( syncObject ) +{ + reset(); +} + + +TestResultCollector::~TestResultCollector() +{ + freeFailures(); +} + + +void +TestResultCollector::freeFailures() +{ + TestFailures::iterator itFailure = m_failures.begin(); + while ( itFailure != m_failures.end() ) + delete *itFailure++; + m_failures.clear(); +} + + +void +TestResultCollector::reset() +{ + TestSuccessListener::reset(); + + ExclusiveZone zone( m_syncObject ); + freeFailures(); + m_testErrors = 0; + m_tests.clear(); +} + + +void +TestResultCollector::startTest( Test *test ) +{ + ExclusiveZone zone (m_syncObject); + m_tests.push_back( test ); +} + + +void +TestResultCollector::addFailure( const TestFailure &failure ) +{ + TestSuccessListener::addFailure( failure ); + + ExclusiveZone zone( m_syncObject ); + if ( failure.isError() ) + ++m_testErrors; + m_failures.push_back( failure.clone() ); +} + + +/// Gets the number of run tests. +int +TestResultCollector::runTests() const +{ + ExclusiveZone zone( m_syncObject ); + return m_tests.size(); +} + + +/// Gets the number of detected errors (uncaught exception). +int +TestResultCollector::testErrors() const +{ + ExclusiveZone zone( m_syncObject ); + return m_testErrors; +} + + +/// Gets the number of detected failures (failed assertion). +int +TestResultCollector::testFailures() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures.size() - m_testErrors; +} + + +/// Gets the total number of detected failures. +int +TestResultCollector::testFailuresTotal() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures.size(); +} + + +/// Returns a the list failures (random access collection). +const TestResultCollector::TestFailures & +TestResultCollector::failures() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures; +} + + +const TestResultCollector::Tests & +TestResultCollector::tests() const +{ + ExclusiveZone zone( m_syncObject ); + return m_tests; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/TestRunner.cpp b/UnitTests/cppunit/src/cppunit/TestRunner.cpp new file mode 100644 index 0000000..8d95a63 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestRunner.cpp @@ -0,0 +1,101 @@ +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +TestRunner::WrappingSuite::WrappingSuite( const std::string &name ) + : TestSuite( name ) +{ +} + + +int +TestRunner::WrappingSuite::getChildTestCount() const +{ + if ( hasOnlyOneTest() ) + return getUniqueChildTest()->getChildTestCount(); + return TestSuite::getChildTestCount(); +} + + +std::string +TestRunner::WrappingSuite::getName() const +{ + if ( hasOnlyOneTest() ) + return getUniqueChildTest()->getName(); + return TestSuite::getName(); +} + + +Test * +TestRunner::WrappingSuite::doGetChildTestAt( int index ) const +{ + if ( hasOnlyOneTest() ) + return getUniqueChildTest()->getChildTestAt( index ); + return TestSuite::doGetChildTestAt( index ); +} + + +void +TestRunner::WrappingSuite::run( TestResult *result ) +{ + if ( hasOnlyOneTest() ) + getUniqueChildTest()->run( result ); + else + TestSuite::run( result ); +} + + +bool +TestRunner::WrappingSuite::hasOnlyOneTest() const +{ + return TestSuite::getChildTestCount() == 1; +} + + +Test * +TestRunner::WrappingSuite::getUniqueChildTest() const +{ + return TestSuite::doGetChildTestAt( 0 ); +} + + + + + +TestRunner::TestRunner() + : m_suite( new WrappingSuite() ) +{ +} + + +TestRunner::~TestRunner() +{ + delete m_suite; +} + + +void +TestRunner::addTest( Test *test ) +{ + m_suite->addTest( test ); +} + + +void +TestRunner::run( TestResult &controller, + const std::string &testPath ) +{ + TestPath path = m_suite->resolveTestPath( testPath ); + Test *testToRun = path.getChildTest(); + + controller.runTest( testToRun ); +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/TestSetUp.cpp b/UnitTests/cppunit/src/cppunit/TestSetUp.cpp new file mode 100644 index 0000000..d4d8530 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestSetUp.cpp @@ -0,0 +1,32 @@ +#include + +CPPUNIT_NS_BEGIN + + +TestSetUp::TestSetUp( Test *test ) : TestDecorator( test ) +{ +} + + +void +TestSetUp::setUp() +{ +} + + +void +TestSetUp::tearDown() +{ +} + + +void +TestSetUp::run( TestResult *result ) +{ + setUp(); + TestDecorator::run(result); + tearDown(); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TestSuccessListener.cpp b/UnitTests/cppunit/src/cppunit/TestSuccessListener.cpp new file mode 100644 index 0000000..a5572a9 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestSuccessListener.cpp @@ -0,0 +1,44 @@ +#include + + +CPPUNIT_NS_BEGIN + + +TestSuccessListener::TestSuccessListener( SynchronizationObject *syncObject ) + : SynchronizedObject( syncObject ) + , m_success( true ) +{ +} + + +TestSuccessListener::~TestSuccessListener() +{ +} + + +void +TestSuccessListener::reset() +{ + ExclusiveZone zone( m_syncObject ); + m_success = true; +} + + +void +TestSuccessListener::addFailure( const TestFailure & ) +{ + ExclusiveZone zone( m_syncObject ); + m_success = false; +} + + +bool +TestSuccessListener::wasSuccessful() const +{ + ExclusiveZone zone( m_syncObject ); + return m_success; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/TestSuite.cpp b/UnitTests/cppunit/src/cppunit/TestSuite.cpp new file mode 100644 index 0000000..8dd2ea6 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestSuite.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +CPPUNIT_NS_BEGIN + + +/// Default constructor +TestSuite::TestSuite( std::string name ) + : TestComposite( name ) +{ +} + + +/// Destructor +TestSuite::~TestSuite() +{ + deleteContents(); +} + + +/// Deletes all tests in the suite. +void +TestSuite::deleteContents() +{ + int childCount = getChildTestCount(); + for ( int index =0; index < childCount; ++index ) + delete getChildTestAt( index ); + + m_tests.clear(); +} + + +/// Adds a test to the suite. +void +TestSuite::addTest( Test *test ) +{ + m_tests.push_back( test ); +} + + +const CppUnitVector & +TestSuite::getTests() const +{ + return m_tests; +} + + +int +TestSuite::getChildTestCount() const +{ + return m_tests.size(); +} + + +Test * +TestSuite::doGetChildTestAt( int index ) const +{ + return m_tests[index]; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/TestSuiteBuilderContext.cpp b/UnitTests/cppunit/src/cppunit/TestSuiteBuilderContext.cpp new file mode 100644 index 0000000..ff71b52 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TestSuiteBuilderContext.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + +TestSuiteBuilderContextBase::TestSuiteBuilderContextBase( + TestSuite &suite, + const TestNamer &namer, + TestFixtureFactory &factory ) + : m_suite( suite ) + , m_namer( namer ) + , m_factory( factory ) +{ +} + + +TestSuiteBuilderContextBase::~TestSuiteBuilderContextBase() +{ +} + + +void +TestSuiteBuilderContextBase::addTest( Test *test ) +{ + m_suite.addTest( test ); +} + + +std::string +TestSuiteBuilderContextBase::getFixtureName() const +{ + return m_namer.getFixtureName(); +} + + +std::string +TestSuiteBuilderContextBase::getTestNameFor( + const std::string &testMethodName ) const +{ + return m_namer.getTestNameFor( testMethodName ); +} + + +TestFixture * +TestSuiteBuilderContextBase::makeTestFixture() const +{ + return m_factory.makeFixture(); +} + + +void +TestSuiteBuilderContextBase::addProperty( const std::string &key, + const std::string &value ) +{ + Properties::iterator it = m_properties.begin(); + for ( ; it != m_properties.end(); ++it ) + { + if ( (*it).first == key ) + { + (*it).second = value; + return; + } + } + + Property property( key, value ); + m_properties.push_back( property ); +} + +const std::string +TestSuiteBuilderContextBase::getStringProperty( const std::string &key ) const +{ + Properties::const_iterator it = m_properties.begin(); + for ( ; it != m_properties.end(); ++it ) + { + if ( (*it).first == key ) + return (*it).second; + } + return ""; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TextOutputter.cpp b/UnitTests/cppunit/src/cppunit/TextOutputter.cpp new file mode 100644 index 0000000..f74214f --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TextOutputter.cpp @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +TextOutputter::TextOutputter( TestResultCollector *result, + OStream &stream ) + : m_result( result ) + , m_stream( stream ) +{ +} + + +TextOutputter::~TextOutputter() +{ +} + + +void +TextOutputter::write() +{ + printHeader(); + m_stream << "\n"; + printFailures(); + m_stream << "\n"; +} + + +void +TextOutputter::printFailures() +{ + TestResultCollector::TestFailures::const_iterator itFailure = m_result->failures().begin(); + int failureNumber = 1; + while ( itFailure != m_result->failures().end() ) + { + m_stream << "\n"; + printFailure( *itFailure++, failureNumber++ ); + } +} + + +void +TextOutputter::printFailure( TestFailure *failure, + int failureNumber ) +{ + printFailureListMark( failureNumber ); + m_stream << ' '; + printFailureTestName( failure ); + m_stream << ' '; + printFailureType( failure ); + m_stream << ' '; + printFailureLocation( failure->sourceLine() ); + m_stream << "\n"; + printFailureDetail( failure->thrownException() ); + m_stream << "\n"; +} + + +void +TextOutputter::printFailureListMark( int failureNumber ) +{ + m_stream << failureNumber << ")"; +} + + +void +TextOutputter::printFailureTestName( TestFailure *failure ) +{ + m_stream << "test: " << failure->failedTestName(); +} + + +void +TextOutputter::printFailureType( TestFailure *failure ) +{ + m_stream << "(" + << (failure->isError() ? "E" : "F") + << ")"; +} + + +void +TextOutputter::printFailureLocation( SourceLine sourceLine ) +{ + if ( !sourceLine.isValid() ) + return; + + m_stream << "line: " << sourceLine.lineNumber() + << ' ' << sourceLine.fileName(); +} + + +void +TextOutputter::printFailureDetail( Exception *thrownException ) +{ + m_stream << thrownException->message().shortDescription() << "\n"; + m_stream << thrownException->message().details(); +} + + +void +TextOutputter::printHeader() +{ + if ( m_result->wasSuccessful() ) + m_stream << "\nOK (" << m_result->runTests () << " tests)\n" ; + else + { + m_stream << "\n"; + printFailureWarning(); + printStatistics(); + } +} + + +void +TextOutputter::printFailureWarning() +{ + m_stream << "!!!FAILURES!!!\n"; +} + + +void +TextOutputter::printStatistics() +{ + m_stream << "Test Results:\n"; + + m_stream << "Run: " << m_result->runTests() + << " Failures: " << m_result->testFailures() + << " Errors: " << m_result->testErrors() + << "\n"; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/TextTestProgressListener.cpp b/UnitTests/cppunit/src/cppunit/TextTestProgressListener.cpp new file mode 100644 index 0000000..ea4fb17 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TextTestProgressListener.cpp @@ -0,0 +1,45 @@ +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +TextTestProgressListener::TextTestProgressListener() +{ +} + + +TextTestProgressListener::~TextTestProgressListener() +{ +} + + +void +TextTestProgressListener::startTest( Test * ) +{ + stdCOut() << "."; + stdCOut().flush(); +} + + +void +TextTestProgressListener::addFailure( const TestFailure &failure ) +{ + stdCOut() << ( failure.isError() ? "E" : "F" ); + stdCOut().flush(); +} + + +void +TextTestProgressListener::endTestRun( Test *, + TestResult * ) +{ + stdCOut() << "\n"; + stdCOut().flush(); +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/TextTestResult.cpp b/UnitTests/cppunit/src/cppunit/TextTestResult.cpp new file mode 100644 index 0000000..871eb6d --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TextTestResult.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +TextTestResult::TextTestResult() +{ + addListener( this ); +} + + +void +TextTestResult::addFailure( const TestFailure &failure ) +{ + TestResultCollector::addFailure( failure ); + stdCOut() << ( failure.isError() ? "E" : "F" ); +} + + +void +TextTestResult::startTest( Test *test ) +{ + TestResultCollector::startTest (test); + stdCOut() << "."; +} + + +void +TextTestResult::print( OStream &stream ) +{ + TextOutputter outputter( this, stream ); + outputter.write(); +} + + +OStream & +operator <<( OStream &stream, + TextTestResult &result ) +{ + result.print (stream); return stream; +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TextTestRunner.cpp b/UnitTests/cppunit/src/cppunit/TextTestRunner.cpp new file mode 100644 index 0000000..1534ec0 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TextTestRunner.cpp @@ -0,0 +1,144 @@ +// ==> Implementation of cppunit/ui/text/TestRunner.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +/*! Constructs a new text runner. + * \param outputter used to print text result. Owned by the runner. + */ +TextTestRunner::TextTestRunner( Outputter *outputter ) + : m_result( new TestResultCollector() ) + , m_eventManager( new TestResult() ) + , m_outputter( outputter ) +{ + if ( !m_outputter ) + m_outputter = new TextOutputter( m_result, stdCOut() ); + m_eventManager->addListener( m_result ); +} + + +TextTestRunner::~TextTestRunner() +{ + delete m_eventManager; + delete m_outputter; + delete m_result; +} + + +/*! Runs the named test case. + * + * \param testName Name of the test case to run. If an empty is given, then + * all added tests are run. The name can be the name of any + * test in the hierarchy. + * \param doWait if \c true then the user must press the RETURN key + * before the run() method exit. + * \param doPrintResult if \c true (default) then the test result are printed + * on the standard output. + * \param doPrintProgress if \c true (default) then TextTestProgressListener is + * used to show the progress. + * \return \c true is the test was successful, \c false if the test + * failed or was not found. + */ +bool +TextTestRunner::run( std::string testName, + bool doWait, + bool doPrintResult, + bool doPrintProgress ) +{ + TextTestProgressListener progress; + if ( doPrintProgress ) + m_eventManager->addListener( &progress ); + + TestRunner *pThis = this; + pThis->run( *m_eventManager, testName ); + + if ( doPrintProgress ) + m_eventManager->removeListener( &progress ); + + printResult( doPrintResult ); + wait( doWait ); + + return m_result->wasSuccessful(); +} + + +void +TextTestRunner::wait( bool doWait ) +{ +#if !defined( CPPUNIT_NO_STREAM ) + if ( doWait ) + { + stdCOut() << " to continue\n"; + stdCOut().flush(); + std::cin.get (); + } +#endif +} + + +void +TextTestRunner::printResult( bool doPrintResult ) +{ + stdCOut() << "\n"; + if ( doPrintResult ) + m_outputter->write(); +} + + +/*! Returns the result of the test run. + * Use this after calling run() to access the result of the test run. + */ +TestResultCollector & +TextTestRunner::result() const +{ + return *m_result; +} + + +/*! Returns the event manager. + * The instance of TestResult results returned is the one that is used to run the + * test. Use this to register additional TestListener before running the tests. + */ +TestResult & +TextTestRunner::eventManager() const +{ + return *m_eventManager; +} + + +/*! Specifies an alternate outputter. + * + * Notes that the outputter will be use after the test run only if \a printResult was + * \c true. + * \param outputter New outputter to use. The previous outputter is destroyed. + * The TextTestRunner assumes ownership of the outputter. + * \see CompilerOutputter, XmlOutputter, TextOutputter. + */ +void +TextTestRunner::setOutputter( Outputter *outputter ) +{ + delete m_outputter; + m_outputter = outputter; +} + + +void +TextTestRunner::run( TestResult &controller, + const std::string &testPath ) +{ + TestRunner::run( controller, testPath ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/TypeInfoHelper.cpp b/UnitTests/cppunit/src/cppunit/TypeInfoHelper.cpp new file mode 100644 index 0000000..ff1d662 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/TypeInfoHelper.cpp @@ -0,0 +1,54 @@ +#include +#include + +#if CPPUNIT_HAVE_RTTI + +#include + +#if CPPUNIT_HAVE_GCC_ABI_DEMANGLE +#include +#include +#endif + + +CPPUNIT_NS_BEGIN + + +std::string +TypeInfoHelper::getClassName( const std::type_info &info ) +{ +#if defined(CPPUNIT_HAVE_GCC_ABI_DEMANGLE) && CPPUNIT_HAVE_GCC_ABI_DEMANGLE + + int status = 0; + char* c_name = 0; + + c_name = abi::__cxa_demangle( info.name(), 0, 0, &status ); + + std::string name( c_name ); + free( c_name ); + +#else // CPPUNIT_HAVE_GCC_ABI_DEMANGLE + + static std::string classPrefix( "class " ); + std::string name( info.name() ); + + // Work around gcc 3.0 bug: strip number before type name. + unsigned int firstNotDigitIndex = 0; + while ( firstNotDigitIndex < name.length() && + name[firstNotDigitIndex] >= '0' && + name[firstNotDigitIndex] <= '9' ) + ++firstNotDigitIndex; + name = name.substr( firstNotDigitIndex ); + + if ( name.substr( 0, classPrefix.length() ) == classPrefix ) + return name.substr( classPrefix.length() ); + +#endif // CPPUNIT_HAVE_GCC_ABI_DEMANGLE + + return name; +} + + +CPPUNIT_NS_END + +#endif // CPPUNIT_HAVE_RTTI diff --git a/UnitTests/cppunit/src/cppunit/UnixDynamicLibraryManager.cpp b/UnitTests/cppunit/src/cppunit/UnixDynamicLibraryManager.cpp new file mode 100644 index 0000000..f235cce --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/UnixDynamicLibraryManager.cpp @@ -0,0 +1,44 @@ +#include + +#if defined(CPPUNIT_HAVE_UNIX_DLL_LOADER) +#include + +#include +#include + + +CPPUNIT_NS_BEGIN + + +DynamicLibraryManager::LibraryHandle +DynamicLibraryManager::doLoadLibrary( const std::string &libraryName ) +{ + return ::dlopen( libraryName.c_str(), RTLD_NOW | RTLD_GLOBAL ); +} + + +void +DynamicLibraryManager::doReleaseLibrary() +{ + ::dlclose( m_libraryHandle); +} + + +DynamicLibraryManager::Symbol +DynamicLibraryManager::doFindSymbol( const std::string &symbol ) +{ + return ::dlsym ( m_libraryHandle, symbol.c_str() ); +} + + +std::string +DynamicLibraryManager::getLastErrorDetail() const +{ + return ""; +} + + +CPPUNIT_NS_END + + +#endif // defined(CPPUNIT_HAVE_UNIX_DLL_LOADER) diff --git a/UnitTests/cppunit/src/cppunit/Win32DynamicLibraryManager.cpp b/UnitTests/cppunit/src/cppunit/Win32DynamicLibraryManager.cpp new file mode 100644 index 0000000..acadf46 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/Win32DynamicLibraryManager.cpp @@ -0,0 +1,73 @@ +#include + +#if defined(CPPUNIT_HAVE_WIN32_DLL_LOADER) +#include + +#define WIN32_LEAN_AND_MEAN +#define NOGDI +#define NOUSER +#define NOKERNEL +#define NOSOUND +#define NOMINMAX +#define BLENDFUNCTION void // for mingw & gcc +#include + + +CPPUNIT_NS_BEGIN + + +DynamicLibraryManager::LibraryHandle +DynamicLibraryManager::doLoadLibrary( const std::string &libraryName ) +{ + return ::LoadLibraryA( libraryName.c_str() ); +} + + +void +DynamicLibraryManager::doReleaseLibrary() +{ + ::FreeLibrary( (HINSTANCE)m_libraryHandle ); +} + + +DynamicLibraryManager::Symbol +DynamicLibraryManager::doFindSymbol( const std::string &symbol ) +{ + return (DynamicLibraryManager::Symbol)::GetProcAddress( + (HINSTANCE)m_libraryHandle, + symbol.c_str() ); +} + + +std::string +DynamicLibraryManager::getLastErrorDetail() const +{ + LPVOID lpMsgBuf; + ::FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPSTR) &lpMsgBuf, + 0, + NULL + ); + + std::string message = (LPCSTR)lpMsgBuf; + + // Display the string. +// ::MessageBoxA( NULL, (LPCSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); + + // Free the buffer. + ::LocalFree( lpMsgBuf ); + + return message; +} + + +CPPUNIT_NS_END + + +#endif // defined(CPPUNIT_HAVE_WIN32_DLL_LOADER) diff --git a/UnitTests/cppunit/src/cppunit/XmlDocument.cpp b/UnitTests/cppunit/src/cppunit/XmlDocument.cpp new file mode 100644 index 0000000..31f9115 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/XmlDocument.cpp @@ -0,0 +1,106 @@ +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +XmlDocument::XmlDocument( const std::string &encoding, + const std::string &styleSheet ) + : m_styleSheet( styleSheet ) + , m_rootElement( new XmlElement( "DummyRoot" ) ) + , m_standalone( true ) +{ + setEncoding( encoding ); +} + + +XmlDocument::~XmlDocument() +{ + delete m_rootElement; +} + + + +std::string +XmlDocument::encoding() const +{ + return m_encoding; +} + + +void +XmlDocument::setEncoding( const std::string &encoding ) +{ + m_encoding = encoding.empty() ? std::string("ISO-8859-1") : encoding; +} + + +std::string +XmlDocument::styleSheet() const +{ + return m_styleSheet; +} + + +void +XmlDocument::setStyleSheet( const std::string &styleSheet ) +{ + m_styleSheet = styleSheet; +} + + +bool +XmlDocument::standalone() const +{ + return m_standalone; +} + + +void +XmlDocument::setStandalone( bool standalone ) +{ + m_standalone = standalone; +} + + +void +XmlDocument::setRootElement( XmlElement *rootElement ) +{ + if ( rootElement == m_rootElement ) + return; + + delete m_rootElement; + m_rootElement = rootElement; +} + + +XmlElement & +XmlDocument::rootElement() const +{ + return *m_rootElement; +} + + +std::string +XmlDocument::toString() const +{ + std::string asString = "\n"; + + if ( !m_styleSheet.empty() ) + asString += "\n"; + + asString += m_rootElement->toString(); + + return asString; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/XmlElement.cpp b/UnitTests/cppunit/src/cppunit/XmlElement.cpp new file mode 100644 index 0000000..f930ad4 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/XmlElement.cpp @@ -0,0 +1,226 @@ +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +XmlElement::XmlElement( std::string elementName, + std::string content ) + : m_name( elementName ) + , m_content( content ) +{ +} + + +XmlElement::XmlElement( std::string elementName, + int numericContent ) + : m_name( elementName ) +{ + setContent( numericContent ); +} + + +XmlElement::~XmlElement() +{ + Elements::iterator itNode = m_elements.begin(); + while ( itNode != m_elements.end() ) + { + XmlElement *element = *itNode++; + delete element; + } +} + + +std::string +XmlElement::name() const +{ + return m_name; +} + + +std::string +XmlElement::content() const +{ + return m_content; +} + + +void +XmlElement::setName( const std::string &name ) +{ + m_name = name; +} + + +void +XmlElement::setContent( const std::string &content ) +{ + m_content = content; +} + + +void +XmlElement::setContent( int numericContent ) +{ + m_content = StringTools::toString( numericContent ); +} + + +void +XmlElement::addAttribute( std::string attributeName, + std::string value ) +{ + m_attributes.push_back( Attribute( attributeName, value ) ); +} + + +void +XmlElement::addAttribute( std::string attributeName, + int numericValue ) +{ + addAttribute( attributeName, StringTools::toString( numericValue ) ); +} + + +void +XmlElement::addElement( XmlElement *node ) +{ + m_elements.push_back( node ); +} + + +int +XmlElement::elementCount() const +{ + return m_elements.size(); +} + + +XmlElement * +XmlElement::elementAt( int index ) const +{ + if ( index < 0 || index >= elementCount() ) + throw std::invalid_argument( "XmlElement::elementAt(), out of range index" ); + + return m_elements[ index ]; +} + + +XmlElement * +XmlElement::elementFor( const std::string &name ) const +{ + Elements::const_iterator itElement = m_elements.begin(); + for ( ; itElement != m_elements.end(); ++itElement ) + { + if ( (*itElement)->name() == name ) + return *itElement; + } + + throw std::invalid_argument( "XmlElement::elementFor(), not matching child element found" ); + return NULL; // make some compilers happy. +} + + +std::string +XmlElement::toString( const std::string &indent ) const +{ + std::string element( indent ); + element += "<"; + element += m_name; + if ( !m_attributes.empty() ) + { + element += " "; + element += attributesAsString(); + } + element += ">"; + + if ( !m_elements.empty() ) + { + element += "\n"; + + std::string subNodeIndent( indent + " " ); + Elements::const_iterator itNode = m_elements.begin(); + while ( itNode != m_elements.end() ) + { + const XmlElement *node = *itNode++; + element += node->toString( subNodeIndent ); + } + + element += indent; + } + + if ( !m_content.empty() ) + { + element += escape( m_content ); + if ( !m_elements.empty() ) + { + element += "\n"; + element += indent; + } + } + + element += "\n"; + + return element; +} + + +std::string +XmlElement::attributesAsString() const +{ + std::string attributes; + Attributes::const_iterator itAttribute = m_attributes.begin(); + while ( itAttribute != m_attributes.end() ) + { + if ( !attributes.empty() ) + attributes += " "; + + const Attribute &attribute = *itAttribute++; + attributes += attribute.first; + attributes += "=\""; + attributes += escape( attribute.second ); + attributes += "\""; + } + return attributes; +} + + +std::string +XmlElement::escape( std::string value ) const +{ + std::string escaped; + for ( unsigned int index =0; index < value.length(); ++index ) + { + char c = value[index ]; + switch ( c ) // escape all predefined XML entity (safe?) + { + case '<': + escaped += "<"; + break; + case '>': + escaped += ">"; + break; + case '&': + escaped += "&"; + break; + case '\'': + escaped += "'"; + break; + case '"': + escaped += """; + break; + default: + escaped += c; + } + } + + return escaped; +} + + +CPPUNIT_NS_END + diff --git a/UnitTests/cppunit/src/cppunit/XmlOutputter.cpp b/UnitTests/cppunit/src/cppunit/XmlOutputter.cpp new file mode 100644 index 0000000..c605e33 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/XmlOutputter.cpp @@ -0,0 +1,205 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +CPPUNIT_NS_BEGIN + + +XmlOutputter::XmlOutputter( TestResultCollector *result, + OStream &stream, + std::string encoding ) + : m_result( result ) + , m_stream( stream ) + , m_xml( new XmlDocument( encoding ) ) +{ +} + + +XmlOutputter::~XmlOutputter() +{ + delete m_xml; +} + + +void +XmlOutputter::addHook( XmlOutputterHook *hook ) +{ + m_hooks.push_back( hook ); +} + + +void +XmlOutputter::removeHook( XmlOutputterHook *hook ) +{ + m_hooks.erase( std::find( m_hooks.begin(), m_hooks.end(), hook ) ); +} + + +void +XmlOutputter::write() +{ + setRootNode(); + m_stream << m_xml->toString(); +} + + +void +XmlOutputter::setStyleSheet( const std::string &styleSheet ) +{ + m_xml->setStyleSheet( styleSheet ); +} + + +void +XmlOutputter::setStandalone( bool standalone ) +{ + m_xml->setStandalone( standalone ); +} + + +void +XmlOutputter::setRootNode() +{ + XmlElement *rootNode = new XmlElement( "TestRun" ); + m_xml->setRootElement( rootNode ); + + for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->beginDocument( m_xml ); + + FailedTests failedTests; + fillFailedTestsMap( failedTests ); + + addFailedTests( failedTests, rootNode ); + addSuccessfulTests( failedTests, rootNode ); + addStatistics( rootNode ); + + for ( Hooks::iterator itEnd = m_hooks.begin(); itEnd != m_hooks.end(); ++itEnd ) + (*itEnd)->endDocument( m_xml ); +} + + +void +XmlOutputter::fillFailedTestsMap( FailedTests &failedTests ) +{ + const TestResultCollector::TestFailures &failures = m_result->failures(); + TestResultCollector::TestFailures::const_iterator itFailure = failures.begin(); + while ( itFailure != failures.end() ) + { + TestFailure *failure = *itFailure++; + failedTests.insert( std::pair(failure->failedTest(), failure ) ); + } +} + + +void +XmlOutputter::addFailedTests( FailedTests &failedTests, + XmlElement *rootNode ) +{ + XmlElement *testsNode = new XmlElement( "FailedTests" ); + rootNode->addElement( testsNode ); + + const TestResultCollector::Tests &tests = m_result->tests(); + for ( unsigned int testNumber = 0; testNumber < tests.size(); ++testNumber ) + { + Test *test = tests[testNumber]; + if ( failedTests.find( test ) != failedTests.end() ) + addFailedTest( test, failedTests[test], testNumber+1, testsNode ); + } +} + + +void +XmlOutputter::addSuccessfulTests( FailedTests &failedTests, + XmlElement *rootNode ) +{ + XmlElement *testsNode = new XmlElement( "SuccessfulTests" ); + rootNode->addElement( testsNode ); + + const TestResultCollector::Tests &tests = m_result->tests(); + for ( unsigned int testNumber = 0; testNumber < tests.size(); ++testNumber ) + { + Test *test = tests[testNumber]; + if ( failedTests.find( test ) == failedTests.end() ) + addSuccessfulTest( test, testNumber+1, testsNode ); + } +} + + +void +XmlOutputter::addStatistics( XmlElement *rootNode ) +{ + XmlElement *statisticsElement = new XmlElement( "Statistics" ); + rootNode->addElement( statisticsElement ); + statisticsElement->addElement( new XmlElement( "Tests", m_result->runTests() ) ); + statisticsElement->addElement( new XmlElement( "FailuresTotal", + m_result->testFailuresTotal() ) ); + statisticsElement->addElement( new XmlElement( "Errors", m_result->testErrors() ) ); + statisticsElement->addElement( new XmlElement( "Failures", m_result->testFailures() ) ); + + for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->statisticsAdded( m_xml, statisticsElement ); +} + + +void +XmlOutputter::addFailedTest( Test *test, + TestFailure *failure, + int testNumber, + XmlElement *testsNode ) +{ + Exception *thrownException = failure->thrownException(); + + XmlElement *testElement = new XmlElement( "FailedTest" ); + testsNode->addElement( testElement ); + testElement->addAttribute( "id", testNumber ); + testElement->addElement( new XmlElement( "Name", test->getName() ) ); + testElement->addElement( new XmlElement( "FailureType", + failure->isError() ? "Error" : + "Assertion" ) ); + + if ( failure->sourceLine().isValid() ) + addFailureLocation( failure, testElement ); + + testElement->addElement( new XmlElement( "Message", thrownException->what() ) ); + + for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->failTestAdded( m_xml, testElement, test, failure ); +} + + +void +XmlOutputter::addFailureLocation( TestFailure *failure, + XmlElement *testElement ) +{ + XmlElement *locationNode = new XmlElement( "Location" ); + testElement->addElement( locationNode ); + SourceLine sourceLine = failure->sourceLine(); + locationNode->addElement( new XmlElement( "File", sourceLine.fileName() ) ); + locationNode->addElement( new XmlElement( "Line", sourceLine.lineNumber() ) ); +} + + +void +XmlOutputter::addSuccessfulTest( Test *test, + int testNumber, + XmlElement *testsNode ) +{ + XmlElement *testElement = new XmlElement( "Test" ); + testsNode->addElement( testElement ); + testElement->addAttribute( "id", testNumber ); + testElement->addElement( new XmlElement( "Name", test->getName() ) ); + + for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->successfulTestAdded( m_xml, testElement, test ); +} + + +CPPUNIT_NS_END diff --git a/UnitTests/cppunit/src/cppunit/XmlOutputterHook.cpp b/UnitTests/cppunit/src/cppunit/XmlOutputterHook.cpp new file mode 100644 index 0000000..53d10f6 --- /dev/null +++ b/UnitTests/cppunit/src/cppunit/XmlOutputterHook.cpp @@ -0,0 +1,44 @@ +#include + + +CPPUNIT_NS_BEGIN + + +void +XmlOutputterHook::beginDocument( XmlDocument * ) +{ +} + + +void +XmlOutputterHook::endDocument( XmlDocument * ) +{ +} + + +void +XmlOutputterHook::failTestAdded( XmlDocument *, + XmlElement *, + Test *, + TestFailure * ) +{ +} + + +void +XmlOutputterHook::successfulTestAdded( XmlDocument *, + XmlElement *, + Test * ) +{ +} + + +void +XmlOutputterHook::statisticsAdded( XmlDocument *, + XmlElement * ) +{ +} + + +CPPUNIT_NS_END + diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..00ddb02 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.81 diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..0505895 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,3054 @@ +# checkbuild.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_SPLIT_TUPLE(TUPLE, OUTPUT-VARIABLES) +# Split a build-tuple into its component parts. A build tuple is +# constructed by CS_CREATE_TUPLE() and is comprised of compiler flags, +# linker flags, and library references. OUTPUT-VARIABLES is a +# comma-delimited list of shell variables which should receive the +# extracted compiler flags, linker flags, and library references, +# respectively. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_SPLIT_TUPLE], + [CS_SPLIT([$1], [cs_dummy,$2], [@]) + m4_map([_CS_SPLIT_TUPLE], [$2])]) + +AC_DEFUN([_CS_SPLIT_TUPLE], + [$1=`echo $$1 | sed 'y%@%:@% %'` + ]) + + + +#------------------------------------------------------------------------------ +# CS_CREATE_TUPLE([CFLAGS], [LFLAGS], [LIBS]) +# Construct a build-tuple which is comprised of compiler flags, linker +# flags, and library references. Build tuples are encoded so as to +# preserve whitespace in each component. This makes it possible for +# macros (such as CS_BUILD_IFELSE) which employ build tuples to accept +# whitespace-delimited lists of tuples, and for shell "for" statements to +# iterate over tuple lists without compromising whitespace embedded +# within individual flags or library references. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CREATE_TUPLE], [`echo @$1@$2@$3 | sed 'y% %@%:@%'`]) + + + +#------------------------------------------------------------------------------ +# CS_LANG_CFLAGS +# Return the literal string CFLAGS if the current language is C. Return +# the literal string CXXFLAGS if the current language is C++. Generic +# compiler test macros which need to modify or save the compiler flags +# can invoke this macro to get the name of the compiler flags environment +# variable (either CFLAGS or CXXFLAGS) depending upon the current +# language. For example: +# CS_LANG_CFLAGS="$CS_LANG_CFLAGS -Wall" +# With C, this expands to: +# CFLAGS="$CFLAGS -Wall" +# With C++, it expands to: +# CXXFLAGS="$CXXFLAGS -Wall" +#------------------------------------------------------------------------------ +AC_DEFUN([CS_LANG_CFLAGS], [AC_LANG_CASE([C], [CFLAGS], [C++], [CXXFLAGS])]) + + + +#------------------------------------------------------------------------------ +# CS_BUILD_IFELSE([PROGRAM], [FLAGS], [LANGUAGE], [ACTION-IF-BUILT], +# [ACTION-IF-NOT-BUILT], [OTHER-CFLAGS], [OTHER-LFLAGS], +# [OTHER-LIBS], [INHIBIT-OTHER-FLAGS], [ERROR-REGEX]) +# Try building a program using the supplied compiler flags, linker flags, +# and library references. PROGRAM is typically a program composed via +# AC_LANG_PROGRAM(). PROGRAM may be omitted if you are interested only +# in learning if the compiler or linker respects certain flags. LANGUAGE +# is typically either C or C++ and specifies which compiler to use for +# the test. If LANGUAGE is omitted, C is used. FLAGS is a whitespace +# delimited list of build tuples. Tuples are created with +# CS_CREATE_TUPLE() and are composed of up to three elements each. The +# first element represents compiler flags, the second linker flags, and +# the third libraries used when linking the program. Each tuple from +# FLAGS is attempted in order. If you want a build attempted with no +# special flags prior to builds with specialized flags, create an empty +# tuple with CS_CREATE_TUPLE() at the start of the FLAGS list. If the +# build is successful, then the shell variables cs_build_ok is set to +# "yes", cs_build_cflags, cs_build_lflags, and cs_build_libs are set to +# the tuple elements which resulted in the successful build, and +# ACTION-IF-BUILT is invoked. Upon successful build, no further tuples +# are consulted. If no tuple results in a successful build, then +# cs_build_ok is set to "no" and ACTION-IF-NOT-BUILT is invoked. +# OTHER-CFLAGS, OTHER-LFLAGS, and OTHER-LIBS specify additional compiler +# flags, linker flags, and libraries which should be used with each tuple +# build attempt. Upon successful build, these additional flags are also +# reflected in the variables cs_build_cflags, cs_build_lflags, and +# cs_build_libs unless INHIBIT-OTHER-FLAGS is a non-empty string. The +# optional ERROR-REGEX places an additional constraint upon the build +# check. If specified, ERROR-REGEX, which is a standard `grep' regular +# expression, is applied to output captured from the compiler and linker. +# If ERROR-REGEX matches, then the build is deemed a failure, and +# cs_build_ok is set to "no". This facility is useful for broken build +# tools which emit an error message yet still return success as a result. +# In such cases, it should be possible to detect the failure by scanning +# the tools' output. +# +# IMPLEMENTATION NOTES +# +# In Autoconf 2.57 and earlier, AC_LINK_IFELSE() invokes AC_TRY_EVAL(), +# which does not provide access to the captured output. To work around +# this limitation, we temporarily re-define AC_TRY_EVAL() as +# _AC_EVAL_STDERR(), which leaves the captured output in conftest.err +# (which we must also delete). In Autoconf 2.58, however, +# AC_LINK_IFELSE() instead already invokes _AC_EVAL_STDERR() on our +# behalf, however we must be careful to apply ERROR-REGEX within the +# invocation AC_LINK_IFELSE(), since AC_LINK_IFELSE() deletes +# conftest.err before it returns. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_BUILD_IFELSE], + [AC_LANG_PUSH(m4_default([$3],[C])) + cs_cflags_save="$CS_LANG_CFLAGS" + cs_lflags_save="$LDFLAGS" + cs_libs_save="$LIBS" + cs_build_ok=no + m4_ifval([$10], [m4_pushdef([AC_TRY_EVAL], [_AC_EVAL_STDERR]($$[1]))]) + + for cs_build_item in m4_default([$2],[CS_CREATE_TUPLE()]) + do + CS_SPLIT_TUPLE( + [$cs_build_item],[cs_cflags_test,cs_lflags_test,cs_libs_test]) + CS_LANG_CFLAGS="$cs_cflags_test $6 $cs_cflags_save" + LDFLAGS="$cs_lflags_test $7 $cs_lflags_save" + LIBS="$cs_libs_test $8 $cs_libs_save" + AC_LINK_IFELSE(m4_default([$1], [AC_LANG_PROGRAM([],[])]), + [m4_ifval([$10], + [AS_IF([AC_TRY_COMMAND( + [grep "AS_ESCAPE([$10])" conftest.err >/dev/null 2>&1])], + [cs_build_ok=no], [cs_build_ok=yes])], + [cs_build_ok=yes])]) + AS_IF([test $cs_build_ok = yes], [break]) + done + + m4_ifval([$10], [m4_popdef([AC_TRY_EVAL]) rm -f conftest.err]) + CS_LANG_CFLAGS=$cs_cflags_save + LDFLAGS=$cs_lflags_save + LIBS=$cs_libs_save + AC_LANG_POP(m4_default([$3],[C])) + + AS_IF([test $cs_build_ok = yes], + [cs_build_cflags=CS_TRIM([$cs_cflags_test[]m4_ifval([$9],[],[ $6])]) + cs_build_lflags=CS_TRIM([$cs_lflags_test[]m4_ifval([$9],[],[ $7])]) + cs_build_libs=CS_TRIM([$cs_libs_test[]m4_ifval([$9],[],[ $8])]) + $4], + [$5])]) + + + +#------------------------------------------------------------------------------ +# CS_CHECK_BUILD(MESSAGE, CACHE-VAR, [PROGRAM], [FLAGS], [LANGUAGE], +# [ACTION-IF-BUILT], [ACTION-IF-NOT-BUILT], [IGNORE-CACHE], +# [OTHER-CFLAGS], [OTHER-LFLAGS], [OTHER-LIBS], +# [INHIBIT-OTHER-FLAGS], [ERROR-REGEX]) +# Like CS_BUILD_IFELSE() but also prints "checking" and result messages, +# and optionally respects the cache. Sets CACHE-VAR to "yes" upon +# success, else "no" upon failure. Additionally, sets CACHE-VAR_cflags, +# CACHE-VAR_lflags, and CACHE-VAR_libs to the values which resulted in a +# successful build. If IGNORE-CACHE is "yes", then the cache variables +# are ignored upon entry to this macro, however they are still set to +# appropriate values upon exit. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_BUILD], + [AS_IF([test "$8" != yes], + [AC_CACHE_CHECK([$1], [$2], + [CS_BUILD_IFELSE([$3], [$4], [$5], + [$2=yes + $2_cflags=$cs_build_cflags + $2_lflags=$cs_build_lflags + $2_libs=$cs_build_libs], + [$2=no], [$9], [$10], [$11], [$12], [$13])])], + [AC_MSG_CHECKING([$1]) + CS_BUILD_IFELSE([$3], [$4], [$5], + [$2=yes + $2_cflags=$cs_build_cflags + $2_lflags=$cs_build_lflags + $2_libs=$cs_build_libs], + [$2=no], [$9], [$10], [$11], [$12], [$13]) + AC_MSG_RESULT([$$2])]) + AS_IF([test $$2 = yes], [$6], + [$2_cflags='' + $2_lflags='' + $2_libs='' + $7])]) + + + +#------------------------------------------------------------------------------ +# CS_CHECK_BUILD_FLAGS(MESSAGE, CACHE-VAR, FLAGS, [LANGUAGE], +# [ACTION-IF-RECOGNIZED], [ACTION-IF-NOT-RECOGNIZED], +# [OTHER-CFLAGS], [OTHER-LFLAGS], [OTHER-LIBS], +# [ERROR-REGEX]) +# Like CS_CHECK_BUILD(), but checks only if the compiler or linker +# recognizes a command-line option or options. MESSAGE is the "checking" +# message. CACHE-VAR is the shell cache variable which receives the flag +# or flags recognized by the compiler or linker. FLAGS is a +# whitespace-delimited list of build tuples created with +# CS_CREATE_TUPLE(). Each tuple from FLAGS is attempted in order until +# one is found which is recognized by the compiler. After that, no +# further flags are checked. LANGUAGE is typically either C or C++ and +# specifies which compiler to use for the test. If LANGUAGE is omitted, +# C is used. If a command-line option is recognized, then CACHE-VAR is +# set to the composite value of $cs_build_cflags, $cs_build_lflags, and +# $cs_build_libs of the FLAGS element which succeeded (not including the +# "other" flags) and ACTION-IF-RECOGNIZED is invoked. If no options are +# recognized, then CACHE-VAR is set to the empty string, and +# ACTION-IF-NOT-RECOGNIZED is invoked. As a convenience, in case +# comparing CACHE-VAR against the empty string to test for failure is +# undesirable, a second variable named CACHE-VAR_ok is set to the literal +# "no" upon failure, and to the same value as CACHE-VAR upon success. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_BUILD_FLAGS], + [AC_CACHE_CHECK([$1], [$2_ok], + [CS_BUILD_IFELSE([], [$3], [$4], + [$2=CS_TRIM([$cs_build_cflags $cs_build_lflags $cs_build_libs]) + $2_ok="$$2"], + [$2='' + $2_ok=no], [$7], [$8], [$9], [Y], [$10])]) + AS_IF([test "$$2_ok" != no], [$5], [$6])]) +#============================================================================== +# Copyright (C)2003-2006 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_CHECK_COMMON_TOOLS_LINK +# Checks for common tools related to linking. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_COMMON_TOOLS_LINK], + [ + # The default RANLIB in Jambase is wrong on some platforms, and is also + # unsuitable during cross-compilation, so we set the value unconditionally + # (sixth argument of CS_EMIT_BUILD_PROPERTY). + AC_PROG_RANLIB + CS_EMIT_BUILD_PROPERTY([RANLIB], [$RANLIB], [], [], [], [Y]) + + CS_CHECK_TOOLS([DLLTOOL], [dlltool]) + CS_EMIT_BUILD_PROPERTY([CMD.DLLTOOL], [$DLLTOOL]) + + CS_CHECK_TOOLS([DLLWRAP], [dllwrap]) + CS_EMIT_BUILD_PROPERTY([CMD.DLLWRAP], [$DLLWRAP]) + + CS_CHECK_TOOLS([WINDRES], [windres]) + CS_EMIT_BUILD_PROPERTY([CMD.WINDRES], [$WINDRES]) + + CS_CHECK_TOOLS([STRINGS], [strings]) + CS_EMIT_BUILD_PROPERTY([CMD.STRINGS], [$STRINGS]) + + CS_CHECK_TOOLS([OBJCOPY], [objcopy]) + CS_EMIT_BUILD_PROPERTY([CMD.OBJCOPY], [$OBJCOPY]) + + CS_CHECK_LIBTOOL + CS_EMIT_BUILD_PROPERTY([LIBTOOL], [$LIBTOOL]) + CS_EMIT_BUILD_PROPERTY([APPLE_LIBTOOL], [$APPLE_LIBTOOL]) + ]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_COMMON_TOOLS_BASIC +# Checks for basic tools for building things. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_COMMON_TOOLS_BASIC], + [CS_CHECK_MKDIR + CS_EMIT_BUILD_PROPERTY([CMD.MKDIR], [$MKDIR]) + CS_EMIT_BUILD_PROPERTY([CMD.MKDIRS], [$MKDIRS]) + + CS_CHECK_PROGS([INSTALL], [install]) + CS_EMIT_BUILD_PROPERTY([INSTALL], [$INSTALL])]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_COMMON_TOOLS_DOC_TEXINFO +# Checks for tools to generate documentation from texinfo files. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_COMMON_TOOLS_DOC_TEXINFO], + [CS_CHECK_PROGS([TEXI2DVI], [texi2dvi]) + CS_EMIT_BUILD_PROPERTY([CMD.TEXI2DVI], [$TEXI2DVI]) + + CS_CHECK_PROGS([TEXI2PDF], [texi2pdf]) + CS_EMIT_BUILD_PROPERTY([CMD.TEXI2PDF], [$TEXI2PDF]) + + CS_CHECK_PROGS([DVIPS], [dvips]) + CS_EMIT_BUILD_PROPERTY([CMD.DVIPS], [$DVIPS]) + + CS_CHECK_PROGS([DVIPDF], [dvipdf]) + CS_EMIT_BUILD_PROPERTY([CMD.DVIPDF], [$DVIPDF]) + + CS_CHECK_PROGS([MAKEINFO], [makeinfo]) + CS_EMIT_BUILD_PROPERTY([CMD.MAKEINFO], [$MAKEINFO])]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_COMMON_TOOLS_DOC_DOXYGEN +# Checks for tools to generate source documentation via doxygen. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_COMMON_TOOLS_DOC_DOXYGEN], + [CS_CHECK_PROGS([DOXYGEN], [doxygen]) + CS_EMIT_BUILD_PROPERTY([CMD.DOXYGEN], [$DOXYGEN]) + + CS_CHECK_TOOLS([DOT], [dot]) + CS_EMIT_BUILD_PROPERTY([CMD.DOT], [$DOT])]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_COMMON_LIBS +# Check for typical required libraries (libm, libmx, libdl, libnsl). +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_COMMON_LIBS], + [AC_LANG_PUSH([C]) + AC_CHECK_LIB([m], [pow], [cs_cv_libm_libs=-lm], [cs_cv_libm_libs=]) + AC_CHECK_LIB([m], [cosf], [cs_cv_libm_libs=-lm]) + AC_CHECK_LIB([mx], [cosf]) + AC_CHECK_LIB([dl], [dlopen], [cs_cv_libdl_libs=-ldl], [cs_cv_libdl_libs=]) + AC_CHECK_LIB([nsl], [gethostbyname]) + AC_LANG_POP([C])]) +# checkcppunit.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_CHECK_CPPUNIT([EMITTER]) +# Check if CppUnit (http://cppunit.sourceforge.net/), the unit-testing +# framework is available. The shell variable cs_cv_libcppunit is set to +# "yes" if CppUnit is discovered, else "no". If available, then the +# variables cs_cv_libcppunit_cflags, cs_cv_libcppunit_lflags, and +# cs_cv_libcppunit_libs are set. If EMITTER is provided, then +# CS_EMIT_BUILD_RESULT() is invoked with EMITTER in order to record the +# results in an output file. As a convenience, if EMITTER is the literal +# value "emit" or "yes", then CS_EMIT_BUILD_RESULT()'s default emitter +# will be used. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_CPPUNIT], + [CS_CHECK_LIB_WITH([cppunit], + [AC_LANG_PROGRAM([[#include ]], + [CppUnit::TextUi::TestRunner r; r.run();])], + [], [C++]) + + AS_IF([test $cs_cv_libcppunit = yes], + [CS_CHECK_BUILD([if cppunit is sufficiently recent], + [cs_cv_libcppunit_recent], + [AC_LANG_PROGRAM( + [[#include ]], + [CppUnit::BriefTestProgressListener b; b.startTest(0);])], + [], [C++], + [CS_EMIT_BUILD_RESULT([cs_cv_libcppunit], [CPPUNIT], + CS_EMITTER_OPTIONAL([$1]))], [], [], + [$cs_cv_libcppunit_cflags], + [$cs_cv_libcppunit_lflags], + [$cs_cv_libcppunit_libs])])]) +# checklib.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003-2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# cs_lib_paths_default +# Whitespace delimited list of directory tuples in which to search, by +# default, for external libraries. Each list item can specify an +# include|library directory tuple (for example, "/usr/include|/usr/lib"), +# or a single directory (for example, "/usr"). If the second form is +# used, then "include" and "lib" subdirectories of the directory are +# searched. If the library resources are not found, then the directory +# itself is searched. Thus, "/proj" is shorthand for +# "/proj/include|/proj/lib /proj|/proj". +# +# Present Cases: +# /usr/local -- Not all compilers search here by default, so we specify +# it manually. +# /sw -- Fink, the MacOS/X manager of Unix packages, installs here by +# default. +# /opt/local -- DarwinPorts installs here by default. +#------------------------------------------------------------------------------ +m4_define([cs_lib_paths_default], + [/usr/local/include|/usr/local/lib \ + /sw/include|/sw/lib \ + /opt/local/include|/opt/local/lib \ + /opt/include|/opt/lib]) + + + +#------------------------------------------------------------------------------ +# cs_pkg_paths_default +# Comma delimited list of additional directories in which the +# `pkg-config' command should search for its `.pc' files. +# +# Present Cases: +# /usr/local/lib/pkgconfig -- Although a common location for .pc files +# installed by "make install", many `pkg-config' commands neglect +# to search here automatically. +# /sw/lib/pkgconfig -- Fink, the MacOS/X manager of Unix packages, +# installs .pc files here by default. +# /opt/local/lib/pkgconfig -- DarwinPorts installs .pc files here by +# default. +#------------------------------------------------------------------------------ +m4_define([cs_pkg_paths_default], + [/usr/local/lib/pkgconfig, + /sw/lib/pkgconfig, + /opt/local/lib/pkgconfig, + /opt/lib/pkgconfig]) + + + +#------------------------------------------------------------------------------ +# CS_CHECK_LIB_WITH(LIBRARY, PROGRAM, [SEARCH-LIST], [LANGUAGE], +# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [OTHER-CFLAGS], +# [OTHER-LFLAGS], [OTHER-LIBS], [ALIASES]) +# Very roughly similar in concept to AC_CHECK_LIB(), but allows caller to +# to provide list of directories in which to search for LIBRARY; allows +# user to override library location via --with-LIBRARY=dir; and consults +# `pkg-config' (if present) and `LIBRARY-config' (if present, i.e. +# `sdl-config') in order to obtain compiler and linker flags. LIBRARY is +# the name of the library or MacOS/X framework which is to be located +# (for example, "readline" for `libreadline.a' or `readline.framework'). +# PROGRAM, which is typically composed with AC_LANG_PROGRAM(), is a +# program which references at least one function or symbol in LIBRARY. +# SEARCH-LIST is a whitespace-delimited list of paths in which to search +# for the library and its header files, in addition to those searched by +# the compiler and linker by default, and those referenced by the +# cs_lib_paths_default macro. Each list item can specify an +# `include|library' directory tuple (for example, +# "/usr/include|/usr/lib"), or a single directory (for example, "/usr"). +# If the second form is used, then "include" and "lib" subdirectories of +# the directory are searched. If the library resources are not found, +# then the directory itself is searched. Thus, "/proj" is shorthand for +# "/proj/include|/proj/lib /proj|/proj". Items in the search list can +# include wildcards. SEARCH-LIST can be overridden by the user with the +# --with-LIBRARY=dir option, in which case only "dir/include|dir/lib" and +# "dir|dir" are searched. If SEARCH-LIST is omitted and the user did not +# override the search list via --with-LIBRARY=dir, then only the +# directories normally searched by the compiler and the directories +# mentioned via cs_lib_paths_default are searched. LANGUAGE is typically +# either C or C++ and specifies which compiler to use for the test. If +# LANGUAGE is omitted, C is used. OTHER-CFLAGS, OTHER-LFLAGS, and +# OTHER-LIBS can specify additional compiler flags, linker flags, and +# libraries needed to successfully link with LIBRARY. The optional +# ALIASES is a comma-delimited list of library names for which to search +# in case LIBRARY is not located (for example "[sdl1.2, sdl12]" for +# libsdl1.2.a, sdl1.2.framework, libsdl12.a, and sdl12.framework). If +# the library or one of its aliases is found and can be successfully +# linked into a program, then the shell cache variable cs_cv_libLIBRARY +# is set to "yes"; cs_cv_libLIBRARY_cflags, cs_cv_libLIBRARY_lflags, and +# cs_cv_libLIBRARY_libs are set, respectively, to the compiler flags +# (including OTHER-CFLAGS), linker flags (including OTHER-LFLAGS), and +# library references (including OTHER-LIBS) which resulted in a +# successful build; and ACTION-IF-FOUND is invoked. If the library was +# not found or was unlinkable, or if the user disabled the library via +# --without-LIBRARY, then cs_cv_libLIBRARY is set to "no" and +# ACTION-IF-NOT-FOUND is invoked. Note that the exported shell variable +# names are always composed from LIBRARY regardless of whether the test +# succeeded because the primary library was discovered or one of the +# aliases. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_LIB_WITH], + [AC_ARG_WITH([$1], [AC_HELP_STRING([--with-$1=dir], + [specify location of lib$1 if not detected automatically; searches + dir/include, dir/lib, and dir])]) + + # Backward compatibility: Recognize --with-lib$1 as alias for --with-$1. + AS_IF([test -n "$with_lib$1" && test -z "$with_$1"], + [with_$1="$with_lib$1"]) + + AS_IF([test -z "$with_$1"], [with_$1=yes]) + AS_IF([test "$with_$1" != no], + [# If --with-$1 value is same as cached value, then assume other + # cached values are also valid; otherwise, ignore all cached values. + AS_IF([test "$with_$1" != "$cs_cv_with_$1"], + [cs_ignore_cache=yes], [cs_ignore_cache=no]) + + cs_check_lib_flags='' + AS_IF([test $with_$1 = yes], + [m4_foreach([cs_check_lib_alias], [$1, $10], + [_CS_CHECK_LIB_PKG_CONFIG_FLAGS([cs_check_lib_flags], + cs_check_lib_alias) + _CS_CHECK_LIB_CONFIG_FLAGS([cs_check_lib_flags], + cs_check_lib_alias) + ])]) + + AS_IF([test $with_$1 != yes], + [cs_check_lib_paths=$with_$1], + [cs_check_lib_paths="| cs_lib_paths_default $3"]) + m4_foreach([cs_check_lib_alias], [$1, $10], + [_CS_CHECK_LIB_CREATE_FLAGS([cs_check_lib_flags], + cs_check_lib_alias, [$cs_check_lib_paths]) + ]) + + CS_CHECK_BUILD([for lib$1], [cs_cv_lib$1], [$2], [$cs_check_lib_flags], + [$4], [], [], [$cs_ignore_cache], [$7], [$8], [$9])], + [cs_cv_lib$1=no]) + + cs_cv_with_$1="$with_$1" + AS_IF([test "$cs_cv_lib$1" = yes], [$5], [$6])]) + + + +#------------------------------------------------------------------------------ +# CS_CHECK_PKG_CONFIG +# Check if the `pkg-config' command is available and reasonably recent. +# This program acts as a central repository of build flags for various +# packages. For example, to determine the compiler flags for FreeType2 +# use, "pkg-config --cflags freetype2"; and "pkg-config --libs freetype2" +# to determine the linker flags. If `pkg-config' is found and is +# sufficiently recent, PKG_CONFIG is set and AC_SUBST() invoked. +#------------------------------------------------------------------------------ +m4_define([CS_PKG_CONFIG_MIN], [0.9.0]) +AC_DEFUN([CS_CHECK_PKG_CONFIG], + [AS_IF([test "$cs_prog_pkg_config_checked" != yes], + [CS_CHECK_TOOLS([PKG_CONFIG], [pkg-config]) + _CS_CHECK_PKG_CONFIG_PREPARE_PATH + cs_prog_pkg_config_checked=yes]) + AS_IF([test -z "$cs_cv_prog_pkg_config_ok"], + [AS_IF([test -n "$PKG_CONFIG"], + [AS_IF([$PKG_CONFIG --atleast-pkgconfig-version=CS_PKG_CONFIG_MIN], + [cs_cv_prog_pkg_config_ok=yes], + [cs_cv_prog_pkg_config_ok=no])], + [cs_cv_prog_pkg_config_ok=no])])]) + +AC_DEFUN([_CS_CHECK_PKG_CONFIG_PREPARE_PATH], + [PKG_CONFIG_PATH="m4_foreach([cs_pkg_path], [cs_pkg_paths_default], + [cs_pkg_path$PATH_SEPARATOR])$PKG_CONFIG_PATH" + export PKG_CONFIG_PATH]) + + + +#------------------------------------------------------------------------------ +# _CS_CHECK_LIB_PKG_CONFIG_FLAGS(VARIABLE, LIBRARY) +# Helper macro for CS_CHECK_LIB_WITH(). Checks if `pkg-config' knows +# about LIBRARY and, if so, appends a build tuple consisting of the +# compiler and linker flags reported by `pkg-config' to the list of +# tuples stored in the shell variable VARIABLE. +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_CHECK_LIB_PKG_CONFIG_FLAGS], + [CS_CHECK_PKG_CONFIG + AS_IF([test $cs_cv_prog_pkg_config_ok = yes], + [AC_CACHE_CHECK([if $PKG_CONFIG recognizes $2], [_CS_CLPCF_CVAR([$2])], + [AS_IF([$PKG_CONFIG --exists $2], + [_CS_CLPCF_CVAR([$2])=yes], [_CS_CLPCF_CVAR([$2])=no])]) + AS_IF([test $_CS_CLPCF_CVAR([$2]) = yes], + [_CS_CHECK_LIB_CONFIG_PROG_FLAGS([$1], [pkg_config_$2], + [$PKG_CONFIG], [$2])])])]) + +AC_DEFUN([_CS_CLPCF_CVAR], [AS_TR_SH([cs_cv_prog_pkg_config_$1])]) + + + +#------------------------------------------------------------------------------ +# _CS_CHECK_LIB_CONFIG_FLAGS(VARIABLE, LIBRARY) +# Helper macro for CS_CHECK_LIB_WITH(). Checks if `LIBRARY-config' +# (i.e. `sdl-config') exists and, if so, appends a build tuple consisting +# of the compiler and linker flags reported by `LIBRARY-config' to the +# list of tuples stored in the shell variable VARIABLE. +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_CHECK_LIB_CONFIG_FLAGS], + [CS_CHECK_TOOLS(_CS_CLCF_SHVAR([$2]), [$2-config]) + AS_IF([test -n "$_CS_CLCF_SHVAR([$2])"], + [AS_IF([test -z "$_CS_CLCF_CVAR([$2])"], + [AS_IF([$_CS_CLCF_SHVAR([$2]) --cflags --libs >/dev/null 2>&1], + [_CS_CLCF_CVAR([$2])=yes], [_CS_CLCF_CVAR([$2])=no])]) + AS_IF([test $_CS_CLCF_CVAR([$2]) = yes], + [_CS_CHECK_LIB_CONFIG_PROG_FLAGS([$1], [config_$2], + [$_CS_CLCF_SHVAR([$2])])])])]) + +AC_DEFUN([_CS_CLCF_CVAR], [AS_TR_SH([cs_cv_prog_config_$1_ok])]) +AC_DEFUN([_CS_CLCF_SHVAR], [m4_toupper(AS_TR_SH([CONFIG_$1]))]) + + + +#------------------------------------------------------------------------------ +# _CS_CHECK_LIB_CONFIG_PROG_FLAGS(VARIABLE, TAG, CONFIG-PROGRAM, [ARGS]) +# Helper macro for _CS_CHECK_LIB_PKG_CONFIG_FLAGS() and +# _CS_CHECK_LIB_CONFIG_FLAGS(). CONFIG-PROGRAM is a command which +# responds to the --cflags and --libs options and returns suitable +# compiler and linker flags for some package. ARGS, if supplied, is +# passed to CONFIG-PROGRAM after the --cflags or --libs argument. The +# results of the --cflags and --libs options are packed into a build +# tuple and appended to the list of tuples stored in the shell variable +# VARIABLE. TAG is used to compose the name of the cache variable. A good +# choice for TAG is some unique combination of the library name and +# configuration program. +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_CHECK_LIB_CONFIG_PROG_FLAGS], + [AS_IF([test -z "$_CS_CLCPF_CVAR([$2])"], + [cs_check_lib_cflag=CS_RUN_PATH_NORMALIZE([$3 --cflags $4]) + cs_check_lib_lflag='' + cs_check_lib_libs=CS_RUN_PATH_NORMALIZE([$3 --libs $4]) + _CS_CLCPF_CVAR([$2])=CS_CREATE_TUPLE( + [$cs_check_lib_cflag], + [$cs_check_lib_lflag], + [$cs_check_lib_libs])]) + $1="$$1 $_CS_CLCPF_CVAR([$2])"]) + +AC_DEFUN([_CS_CLCPF_CVAR], [AS_TR_SH([cs_cv_prog_$1_flags])]) + + + +#------------------------------------------------------------------------------ +# _CS_CHECK_LIB_CREATE_FLAGS(VARIABLE, LIBRARY, PATHS) +# Helper macro for CS_CHECK_LIB_WITH(). Constructs a list of build +# tuples suitable for CS_CHECK_BUILD() and appends the tuple list to the +# shell variable VARIABLE. LIBRARY and PATHS have the same meanings as +# the like-named arguments of CS_CHECK_LIB_WITH(). +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_CHECK_LIB_CREATE_FLAGS], + [for cs_lib_item in $3 + do + case $cs_lib_item in + *\|*) CS_SPLIT( + [$cs_lib_item], [cs_check_incdir,cs_check_libdir], [|]) + _CS_CHECK_LIB_CREATE_FLAG([$1], + [$cs_check_incdir], [$cs_check_libdir], [$2]) + ;; + *) _CS_CHECK_LIB_CREATE_FLAG([$1], + [$cs_lib_item/include], [$cs_lib_item/lib], [$2]) + _CS_CHECK_LIB_CREATE_FLAG( + [$1], [$cs_lib_item], [$cs_lib_item], [$2]) + ;; + esac + done]) + + + +#------------------------------------------------------------------------------ +# _CS_CHECK_LIB_CREATE_FLAG(VARIABLE, HEADER-DIR, LIBRARY-DIR, LIBRARY) +# Helper macro for _CS_CHECK_LIB_CREATE_FLAGS(). Constructs build tuples +# suitable for CS_CHECK_BUILD() for given header and library directories, +# and appends the tuples to the shell variable VARIABLE. Synthesizes +# tuples which check for LIBRARY as a MacOS/X framework, and a standard +# link library. +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_CHECK_LIB_CREATE_FLAG], + [AS_IF([test -n "$2"], [cs_check_lib_cflag="-I$2"], [cs_check_lib_cflag='']) + AS_IF([test -n "$3"], [cs_check_lib_lflag="-L$3"], [cs_check_lib_lflag='']) + AS_IF([test -n "$4"], + [cs_check_lib_libs="-l$4" + cs_check_lib_framework="-framework $4"], + [cs_check_lib_libs='' + cs_check_lib_framework='']) + $1="$$1 + CS_CREATE_TUPLE( + [$cs_check_lib_cflag], + [$cs_check_lib_lflag], + [$cs_check_lib_framework]) + CS_CREATE_TUPLE( + [$cs_check_lib_cflag], + [$cs_check_lib_lflag], + [$cs_check_lib_libs])"]) +# checklibtool.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2004 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_CHECK_LIBTOOL +# Find and identify the various implementations of libtool. In +# particular, this macro is aware of GNU libtool and Apple's libtool +# (which serves a completely different purpose). On MacOS/X, GNU libtool +# is typically named glibtool, however a user might also use Fink to +# install the unadorned libtool; and the Fink-installed version might +# shadow Apple's own libtool if it appears in the PATH before the Apple +# tool. This macro jumps through the necessary hoops to distinguish and +# locate the various implementations. Sets the shell variable LIBTOOL to +# the located GNU libtool (if any), and APPLE_LIBTOOL to the located +# Apple libtool. Invokes AC_SUBST() for LIBTOOL and APPLE_LIBTOOL. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_LIBTOOL], +[# GNU: Search for libtool before glibtool since Fink version is likely newer. +m4_define([cs_lt_path_gnu], + [/sw/bin$PATH_SEPARATOR/usr/local/bin$PATH_SEPARATOR$PATH]) +AS_IF([test -z "$LIBTOOL"], + [CS_CHECK_TOOLS([LIBTOOL_TEST], [libtool glibtool gnulibtool], [], + [cs_lt_path_gnu]) + AS_IF([test -n "$LIBTOOL_TEST"], + [CS_PATH_PROG([LIBTOOL_PATH], [$LIBTOOL_TEST], [], [cs_lt_path_gnu]) + CS_LIBTOOL_CLASSIFY([$LIBTOOL_PATH], + [LIBTOOL="$LIBTOOL_PATH"], + [AS_IF([test -z "$APPLE_LIBTOOL"], [APPLE_LIBTOOL="$LIBTOOL_PATH"]) + CS_CHECK_TOOLS([LIBTOOL], [glibtool gnulibtool])])])]) +AC_SUBST([LIBTOOL]) + +# Apple: Ensure that Apple libtool will be found before GNU libtool from Fink. +m4_define([cs_lt_path_apple],[/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH]) +AS_IF([test -z "$APPLE_LIBTOOL"], + [CS_PATH_PROG([CS_LT_APPLE], [libtool], [], [cs_lt_path_apple]) + CS_LIBTOOL_CLASSIFY([$CS_LT_APPLE], [], + [APPLE_LIBTOOL="$CS_LT_APPLE"])]) +AC_SUBST([APPLE_LIBTOOL])]) + +AC_DEFUN([CS_LIBTOOL_CLASSIFY], + [AS_IF([test -n "$1"], + [AC_MSG_CHECKING([classification of $1]) + CS_LIBTOOL_GNU_IFELSE([$1], + [AC_MSG_RESULT([gnu]) + $2], + [AC_MSG_RESULT([apple]) + $3])])]) + +AC_DEFUN([CS_LIBTOOL_GNU_IFELSE], + [AS_IF([AC_RUN_LOG([$1 --version 1>&2])], [$2], [$3])]) +#============================================================================== +# Copyright (C)2003-2006 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_CHECK_OPENGL +# Check for OpenGL. +# +# IMPLEMENTATION NOTES +# +# Some Mesa installations require pthread, so pthread flags are employed if +# available. +# +# The check for opengl32 needs to precede other checks because Cygwin users +# often have Mesa installed, and Mesa's OpenGL library is compiled without the +# __stdcall flags which results in link errors, whereas Microsoft's native +# opengl32 works fine. Conversely, some Unix implementations have Wine +# installed (Windows emulation layer) which includes an opengl32.so library. +# We need to avoid detection of this library on Unix since it would cause an +# undesirable dependence upon Wine. +# +# Many OpenGL libraries on Unix already contain GLX, so there is no separate +# GLX library, thus we first check for GLX using the discovered OpenGL library +# before attempting to locate a separate GLX-specific library. +# +# On MacOS/X, some users have XFree86 installed which creates a link from +# /usr/include/GL to /usr/X11R6/include/GL. We want to ignore this directory +# and instead check for Apple's OpenGL.framework, if we are not cross-building +# for Darwin. We accomplish this by placing the OpenGL.framework test ahead of +# the other tests. +# +# At least one user (Jorrit) has a strange installation in which inclusion of +# fails if an int32 is not present, thus we must take this into +# account. +#------------------------------------------------------------------------------ +m4_define([cs_define_int32], + [[#if !HAVE_TYPE_INT32 + typedef long int32; + #endif + ]]) + +# CS_GL_INCLUDE(CPP-MACRO,FALLBACK,HEADER) +AC_DEFUN([CS_GL_INCLUDE], + [[#if HAVE_WINDOWS_H + #if !HAVE_TYPE_INT32 + typedef long int32; + #endif + #include + #endif + #ifndef CS_HEADER_GLOBAL + #define CS_HEADER_GLOBAL(X,Y) CS_HEADER_GLOBAL_COMPOSE(X,Y) + #define CS_HEADER_GLOBAL_COMPOSE(X,Y) + #endif + #ifdef $1 + #include CS_HEADER_GLOBAL($1,$3) + #else + #include <$2/$3> + #endif]]) + +AC_DEFUN([CS_CHECK_OPENGL], + [AC_REQUIRE([CS_CHECK_HOST]) + AC_REQUIRE([CS_CHECK_COMMON_LIBS]) + AC_REQUIRE([CS_CHECK_PTHREAD]) + AC_REQUIRE([AC_PATH_X]) + AC_REQUIRE([AC_PATH_XTRA]) + AC_CHECK_TYPE([int32], [AC_DEFINE([HAVE_TYPE_INT32], [], + [Whether the int32 type is available])], []) + AC_CHECK_HEADERS([windows.h], [], [], [cs_define_int32]) + + # Apply plaform-specific flags if necessary. + cs_gl_plat_cflags='' + cs_gl_plat_lflags='' + cs_gl_plat_libs='' + AS_IF([test -n "$cs_cv_libm_cflags$cs_cv_libm_lflags$cs_cv_libm_libs"], + [cs_gl_plat_cflags="$cs_cv_libm_cflags $cs_gl_plat_cflags" + cs_gl_plat_lflags="$cs_cv_libm_lflags $cs_gl_plat_lflags" + cs_gl_plat_libs="$cs_cv_libm_libs $cs_gl_plat_libs"]) + AS_IF([test $cs_cv_sys_pthread = yes], + [cs_gl_plat_cflags="$cs_cv_sys_pthread_cflags $cs_gl_plat_cflags" + cs_gl_plat_lflags="$cs_cv_sys_pthread_lflags $cs_gl_plat_lflags" + cs_gl_plat_libs="$cs_cv_sys_pthread_libs $cs_gl_plat_libs"]) + AS_IF([test "$no_x" != yes], + [cs_gl_plat_cflags="$X_CFLAGS $cs_gl_plat_cflags" + cs_gl_plat_lflags="$cs_gl_plat_lflags" + cs_gl_plat_libs=" + $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS $cs_gl_plat_libs"]) + + # Mesa requested? + AC_ARG_WITH([mesa], [AC_HELP_STRING([--with-mesa], + [use Mesa OpenGL library if available (default YES)])], + [], [with_mesa=yes]) + + AS_IF([test $with_mesa != no], + [cs_mesa_gl=CS_CREATE_TUPLE([],[],[-lMesaGL])]) + + # MacOS/X or Darwin? + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_osx_gl=CS_CREATE_TUPLE([-DCS_OPENGL_PATH=OpenGL],[],[-framework OpenGL])]) + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_gl_plat_lflags="$cs_plat_lflags -Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"]) + + # Windows? + AS_IF([test $cs_host_family = windows], + [cs_win32_gl=CS_CREATE_TUPLE([],[],[-lopengl32])]) + + # Check for OpenGL. + CS_CHECK_BUILD([for OpenGL], [cs_cv_libgl], + [AC_LANG_PROGRAM([CS_GL_INCLUDE([CS_OPENGL_PATH],[GL],[gl.h])],[glEnd()])], + [$cs_win32_gl \ + $cs_osx_gl \ + CS_CREATE_TUPLE([],[],[-lGL]) \ + CS_CREATE_TUPLE([],[],[-lgl]) \ + $cs_mesa_gl], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libgl], [GL])], [], [], + [$cs_gl_plat_cflags], [$cs_gl_plat_lflags], [$cs_gl_plat_libs])]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_GLU +# Check for GLU. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_GLU], + [AC_REQUIRE([CS_CHECK_OPENGL]) + AS_IF([test $cs_cv_libgl = yes], + [AS_IF([test $with_mesa != no], + [cs_mesa_glu=CS_CREATE_TUPLE([],[],[-lMesaGLU])]) + + # MacOS/X or Darwin? + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_osx_glu=CS_CREATE_TUPLE([-DCS_GLU_PATH=OpenGL],[],[-framework OpenGL])]) + + # Windows? + AS_IF([test $cs_host_family = windows], + [cs_win32_glu=CS_CREATE_TUPLE([],[],[-lglu32])]) + + # Check for GLU. + CS_CHECK_BUILD([for GLU], [cs_cv_libglu], + [AC_LANG_PROGRAM( + [CS_GL_INCLUDE([CS_GLU_PATH],[GL],[glu.h])], [gluNewQuadric()])], + [$cs_osx_glu \ + CS_CREATE_TUPLE() \ + $cs_win32_glu \ + CS_CREATE_TUPLE([],[],[-lGLU]) \ + CS_CREATE_TUPLE([],[],[-lglu]) \ + $cs_mesa_glu], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libglu], [GLU])], [], [], + [$cs_cv_libgl_cflags], [$cs_cv_libgl_lflags], [$cs_cv_libgl_libs])])]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_GLX +# Check for GLX. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_GLX], + [AC_REQUIRE([CS_CHECK_OPENGL]) + AS_IF([test $cs_cv_libgl = yes], + [AS_IF([test $with_mesa != no], + [cs_mesa_glx=CS_CREATE_TUPLE([],[],[-lMesaGLX])]) + + # Check for GLX. + AS_IF([test "$no_x" != yes], + [CS_CHECK_BUILD([for GLX], [cs_cv_libglx], + [AC_LANG_PROGRAM([[#include ]], [glXWaitGL()])], + [CS_CREATE_TUPLE() \ + CS_CREATE_TUPLE([],[],[-lGLX]) \ + CS_CREATE_TUPLE([],[],[-lglx]) \ + $cs_mesa_glx], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libglx], [GLX])], [], [], + [$cs_cv_libgl_cflags], [$cs_cv_libgl_lflags], [$cs_cv_libgl_libs])])])]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_GLXEXT([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# Check for GLX extensions. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_GLXEXT], + [AC_REQUIRE([CS_CHECK_GLX]) + AS_IF([test x$cs_cv_libglx = "xyes"], + [# Check for GLX extensions. + CS_CHECK_BUILD([for GLX extensions], [cs_cv_libglx_extensions], + [AC_LANG_PROGRAM( + [[#define GLX_GLXEXT_PROTOTYPES + #include ]], + [glXGetProcAddressARB(0)])], + [CS_CREATE_TUPLE( + [$cs_cv_libglx_cflags], + [$cs_cv_libglx_lflags], + [$cs_cv_libglx_libs])], + [], [$1], [$2])])]) + + + +#------------------------------------------------------------------------------ +# CS_CHECK_GLUT +# Check for GLUT. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_GLUT], + [AC_REQUIRE([CS_CHECK_GLU]) + AS_IF([test x$cs_cv_libglu = "xyes"], + [# MacOS/X or Darwin? + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_osx_glut=CS_CREATE_TUPLE([-DCS_GLUT_PATH=GLUT],[],[-framework GLUT])]) + + # Windows? + AS_IF([test $cs_host_family = windows], + [cs_win32_glut=CS_CREATE_TUPLE([],[],[-lglut32])]) + + # Check for GLUT. + CS_CHECK_BUILD([for GLUT], [cs_cv_libglut], + [AC_LANG_PROGRAM( + [CS_GL_INCLUDE([CS_GLUT_PATH],[GL],[glut.h])], [glutSwapBuffers()])], + [$cs_osx_glut \ + CS_CREATE_TUPLE() \ + $cs_win32_glut \ + CS_CREATE_TUPLE([],[],[-lGLUT]) \ + CS_CREATE_TUPLE([],[],[-lglut])], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libglut], [GLUT])], [], [], + [$cs_cv_libgl_cflags $cs_cv_libglu_cflags], + [$cs_cv_libgl_lflags $cs_cv_libglu_lflags], + [$cs_cv_libgl_libs $cs_cv_libglu_libs])])]) + +# checkpic.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_COMPILER_PIC([LANGUAGE], [CACHE-VAR], [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# Check if compiler can be instructed to produce +# position-independent-code (PIC). This feature is required by some +# platforms when building plugin modules and shared libraries. If +# LANGUAGE is not provided, then `C' is assumed (other options include +# `C++'). If CACHE-VAR is not provided, then it defaults to the name +# "cs_cv_prog_compiler_pic". If a PIC-enabling option (such as `-fPIC') +# is discovered, then it is assigned to CACHE-VAR and ACTION-IF-FOUND is +# invoked; otherwise the empty string is assigned to CACHE-VAR and +# ACTION-IF-NOT-FOUND is invoked. +# +# IMPLEMENTATION NOTES +# +# On some platforms (such as Windows), the -fPIC option is superfluous +# and emits a warning "-fPIC ignored for target (all code is position +# independent)", despite the fact that the compiler accepts the option +# and returns a success code. We want to re-interpret the warning as a +# failure in order to avoid unnecessary compiler diagnostics in case the +# client inserts the result of this check into CFLAGS, for instance. We +# do so by attempting to promote warnings to errors using the result of +# CS_COMPILER_ERRORS(). As an extra safe-guard, we also scan the compiler +# output for an appropriate diagnostic because some gcc warnings fail to +# promote to error status despite use of -Werror. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_COMPILER_PIC], + [CS_COMPILER_ERRORS([$1], + [m4_default([$2_werror],[cs_cv_prog_compiler_pic_werror])]) + CS_CHECK_BUILD_FLAGS( + [how to enable m4_default([$1],[C]) PIC generation], + [m4_default([$2],[cs_cv_prog_compiler_pic])], + [CS_CREATE_TUPLE([-fPIC])], [$1], [$3], [$4], + [m4_default([$$2_werror],[$cs_cv_prog_compiler_pic_werror])], [], [], + [fPIC])]) + +# Backward-compatiblity alias. +AC_DEFUN([CS_CHECK_COMPILER_PIC], [CS_COMPILER_PIC([$1],[$2],[$3],[$4])]) +# checkprog.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2004 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# cs_bin_paths_default +# Comma delimited list of additional directories in which tools and +# commands might be found. +# +# Present Cases: +# /usr/local/bin -- Although a common location for executables, it is +# now-and-then absent from the default PATH setting. +# /sw/bin -- Fink, the MacOS/X manager of Unix packages, installs +# executables here. +#------------------------------------------------------------------------------ +m4_define([cs_bin_paths_default], [/usr/local/bin, /sw/bin]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_PROG(VARIABLE, PROGRAM, VALUE-IF-FOUND, [VALUE-IF-NOT-FOUND], +# [PATH], [REJECT]) +# Simple wrapper for AC_CHECK_PROG() which ensures that the search path +# is augmented by the directories mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_PROG], + [_CS_PROG_PATH_PREPARE + AC_CHECK_PROG([$1], [$2], [$3], [$4], + m4_ifval([$5], [_CS_PROG_CLIENT_PATH([$5])]), [$6])]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_PROGS(VARIABLE, PROGRAMS, [VALUE-IF-NOT-FOUND], [PATH]) +# Simple wrapper for AC_CHECK_PROGS() which ensures that the search path +# is augmented by the directories mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_PROGS], + [_CS_PROG_PATH_PREPARE + AC_CHECK_PROGS([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_TOOL(VARIABLE, TOOL, [VALUE-IF-NOT-FOUND], [PATH]) +# Simple wrapper for AC_CHECK_TOOL() which ensures that the search path +# is augmented by the directories mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_TOOL], + [_CS_PROG_PATH_PREPARE + AC_CHECK_TOOL([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_TOOLS(VARIABLE, TOOLS, [VALUE-IF-NOT-FOUND], [PATH]) +# Simple wrapper for AC_CHECK_TOOLS() which ensures that the search path +# is augmented by the directories mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_TOOLS], + [_CS_PROG_PATH_PREPARE + AC_CHECK_TOOLS([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) + + +#------------------------------------------------------------------------------ +# CS_PATH_PROG(VARIABLE, PROGRAM, [VALUE-IF-NOT-FOUND], [PATH]) +# Simple wrapper for AC_PATH_PROG() which ensures that the search path +# is augmented by the directories mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_PATH_PROG], + [_CS_PROG_PATH_PREPARE + AC_PATH_PROG([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) + + +#------------------------------------------------------------------------------ +# CS_PATH_PROGS(VARIABLE, PROGRAMS, [VALUE-IF-NOT-FOUND], [PATH]) +# Simple wrapper for AC_PATH_PROGS() which ensures that the search path +# is augmented by the directories mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_PATH_PROGS], + [_CS_PROG_PATH_PREPARE + AC_PATH_PROGS([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) + + +#------------------------------------------------------------------------------ +# CS_PATH_TOOL(VARIABLE, TOOL, [VALUE-IF-NOT-FOUND], [PATH]) +# Simple wrapper for AC_PATH_TOOL() which ensures that the search path +# is augmented by the directories mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_PATH_TOOL], + [_CS_PROG_PATH_PREPARE + AC_PATH_TOOL([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) + + +#------------------------------------------------------------------------------ +# _CS_PROG_PATH_PREPARE +# Ensure that the PATH environment variable mentions the set of +# directories listed in cs_bin_paths_default. These directories may not +# appear by default in the typical PATH, yet they might be common +# locations for tools and commands. +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_PROG_PATH_PREPARE], + [AS_REQUIRE([_AS_PATH_SEPARATOR_PREPARE]) + AS_IF([test "$cs_prog_path_prepared" != yes], + [cs_prog_path_prepared=yes + PATH="$PATH[]m4_foreach([cs_bin_path], [cs_bin_paths_default], + [$PATH_SEPARATOR[]cs_bin_path])" + export PATH])]) + + +#------------------------------------------------------------------------------ +# _CS_PROG_CLIENT_PATH(CLIENT-PATH) +# Given a client-supplied replacement for PATH, augment the list by +# appending the locations mentioned in cs_bin_paths_default. +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_PROG_CLIENT_PATH], + [AS_REQUIRE([_AS_PATH_SEPARATOR_PREPARE])dnl + $1[]m4_foreach([cs_bin_path], [cs_bin_paths_default], + [$PATH_SEPARATOR[]cs_bin_path])]) +# checkpthread.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003-2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_CHECK_PTHREAD([REJECT-MASK]) +# Check for pthread. Also check if the pthread implementation supports +# the recursive and timed mutex extensions. (Timed mutexes are needed for +# the NPTL: New Posix Thread Library on GNU/Linux if the mutex is going +# to be used with any of the timed condition-wait functions.) The shell +# variable cs_cv_sys_pthread is set to "yes" if pthread is available, +# else "no". If available, then the variables cs_cv_sys_pthread_cflags, +# cs_cv_sys_pthread_lflags, and cs_cv_sys_pthread_libs are set. (As a +# convenience, these variables can be emitted to an output file with +# CS_EMIT_BUILD_RESULT() by passing "cs_cv_sys_pthread" as its CACHE-VAR +# argument.) If the recursive mutex extension is supported, then +# cs_cv_sys_pthread_mutex_recursive will be set with the literal name of +# the constant which must be passed to pthread_mutexattr_settype() to +# enable this feature. The constant name will be typically +# PTHREAD_MUTEX_RECURSIVE or PTHREAD_MUTEX_RECURSIVE_NP. If the recursive +# mutex extension is not available, then +# cs_cv_sys_pthread_mutex_recursive will be set to "no". If the timed +# mutex extension is supported, then cs_cv_sys_pthread_mutex_timed will +# be set with the literal name of the constant which must be passed to +# pthread_mutexattr_settype() to enable this feature. The constant name +# will be typically PTHREAD_MUTEX_TIMED or PTHREAD_MUTEX_TIMED_NP. If the +# timed mutex extension is not available, then +# cs_cv_sys_pthread_mutex_timed will be set to "no". REJECT-MASK can be +# used to limit the platforms on which the pthread test is performed. It +# is compared against $host_os; matches are rejected. If omitted, then +# the test is performed on all platforms. Examples: To avoid testing on +# Cygwin, use "cygwin*"; to avoid testing on Cygwin and AIX, use +# "cygwin*|aix*". +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_PTHREAD], + [AC_REQUIRE([AC_CANONICAL_HOST]) + case $host_os in + m4_ifval([$1], + [$1) + cs_cv_sys_pthread=no + ;; + ]) + *) + CS_CHECK_BUILD([for pthread], [cs_cv_sys_pthread], + [AC_LANG_PROGRAM( + [[#include + #include + void* worker(void* p) { (void)p; return p; }]], + [pthread_t tid; + sem_t sem; + pthread_create(&tid, 0, worker, 0); + sem_init(&sem, 0, 0); + sem_destroy(&sem);])], + [cs_pthread_flags]) + ;; + esac + _CS_CHECK_MUTEX_FEATURE([PTHREAD_MUTEX_RECURSIVE], + [cs_cv_sys_pthread_mutex_recursive], [for pthread recursive mutexes])]) + +# _CS_CHECK_MUTEX_FEATURE(FEATURE, CACHE-VAR, MESSAGE) +AC_DEFUN([_CS_CHECK_MUTEX_FEATURE], + [AS_IF([test $cs_cv_sys_pthread = yes], + [AC_CACHE_CHECK([$3], [$2], + [CS_BUILD_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [pthread_mutexattr_t attr; + pthread_mutexattr_settype(&attr, CS_MUTEX_FEATURE);])], + [CS_CREATE_TUPLE([-DCS_MUTEX_FEATURE=$1]) \ + CS_CREATE_TUPLE([-DCS_MUTEX_FEATURE=$1_NP])], + [], + [$2=`echo $cs_build_cflags | sed 's/.*\($1_*N*P*\).*/\1/'`], + [$2=no], + [$cs_cv_sys_pthread_cflags -D_GNU_SOURCE], + [$cs_cv_sys_pthread_lflags], + [$cs_cv_sys_pthread_libs])])], + [$2=no])]) + +#------------------------------------------------------------------------------ +# CS_CHECK_PTHREAD_ATFORK(CACHE-VAR) +# Checks whether the pthread library contains pthread_atfork(). Sets +# CACHE-VAR to "yes" or "no", according to the test result. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_PTHREAD_ATFORK], + [AS_IF([test $cs_cv_sys_pthread = yes], + [AC_CACHE_CHECK([for pthread_atfork support], [$1], + [CS_BUILD_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [pthread_atfork (0, 0, 0);])], + [], [], + [$1=yes], [$1=no], + [$cs_cv_sys_pthread_cflags -D_GNU_SOURCE], + [$cs_cv_sys_pthread_lflags], + [$cs_cv_sys_pthread_libs])])], + [$1=no])]) + +m4_define([cs_pthread_flags], + [CS_CREATE_TUPLE() \ + CS_CREATE_TUPLE([], [], [-lpthread]) \ + CS_CREATE_TUPLE([], [], [-lpthread -lrt]) \ + CS_CREATE_TUPLE([-pthread], [-pthread], []) \ + CS_CREATE_TUPLE([-pthread], [-pthread], [-lpthread]) \ + CS_CREATE_TUPLE([-pthread], [-pthread], [-lc_r])]) +# checktt2.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2004,2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_CHECK_TEMPLATE_TOOLKIT2([EMITTER]) +# Check if Template Toolkit 2 (http://www.tt2.org/) is available. The +# shell variable cs_cv_perl_tt2 is set to "yes" if the package is +# discovered, else "no". Also sets the shell variable TTREE to the name +# path of the 'ttree' utility program and invokes AC_SUBST(). If EMITTER +# is provided and the package was discovered, then +# CS_EMIT_BUILD_PROPERTY() is invoked with EMITTER in order to record the +# value of the TTREE variable in an output file. As a convenience, if +# EMITTER is the literal value "emit" or "yes", then +# CS_EMIT_BUILD_RESULT()'s default emitter will be used. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_TEMPLATE_TOOLKIT2], + [CS_CHECK_PROGS([PERL], [perl5 perl]) + AS_IF([test -n "$PERL"], + [AC_CACHE_CHECK([for TemplateToolkit], [cs_cv_perl_tt2], + [AS_IF([AC_RUN_LOG( + [$PERL -M'Template 2.11' -MTemplate::Plugin -e 0 1>&2])], + [cs_cv_perl_tt2=yes], + [cs_cv_perl_tt2=no])]) + CS_PATH_PROGS([TTREE], [ttree]) + AS_IF([test $cs_cv_perl_tt2 = yes && test -n "$TTREE"], + [CS_EMIT_BUILD_PROPERTY([TTREE], [$TTREE], [], [], + CS_EMITTER_OPTIONAL([$1]))])])]) +# compiler.m4 -*- Autoconf -*- +#============================================================================= +# Copyright (C)2003 by Matze Braun +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================= + +#----------------------------------------------------------------------------- +# Detection of C and C++ compilers and setting flags +# +# CS_PROG_CC +# Detects the C compiler. Also takes care of the CFLAGS, CPPFLAGS and CC +# environment variables. This will filter out all -g and -O from the +# CFLAGS variable because Autoconf's -g and -O defaults are not always +# desired. This will also set the CMD.CC and COMPILER.CFLAGS variables +# in Jamconfig +# CS_PROG_CXX +# Detects the C++ compiler. Also takes care of the CXXFLAGS, CPPFLAGS +# and CXX environment variables. This will filter out all -g and -O from +# the CXXFLAGS variable because Autoconf's -g and -O defaults are not +# always desired. This will also set the CMD.C++ and COMPILER.C++FLAGS +# variables in Jamconfig +# CS_PROG_LINK +# Tries to determine a linker. This is done by checking if a C++ or +# Objecctive-C++ compiler is available in which case it is used for +# linking; otherwise the C or Objective-C compiler is used. This also +# sets the CMD.LINK and COMPILER.LFLAGS variables in Jamconfig and +# respects the LDFLAGS environment variable. Finally, checks if linker +# recognizes -shared and sets PLUGIN.LFLAGS; and checks if linker +# recognizes -soname and sets PLUGIN.LFLAGS.USE_SONAME to "yes". +#----------------------------------------------------------------------------- +AC_DEFUN([CS_PROG_CC],[ + CFLAGS="$CFLAGS" # Filter undesired flags + AS_IF([test -n "$CC"],[ + CS_EMIT_BUILD_PROPERTY([CMD.CC], [$CC]) + CS_EMIT_BUILD_PROPERTY([COMPILER.CFLAGS], [$CPPFLAGS $CFLAGS], [+]) + + # Check if compiler recognizes -pipe directive. + CS_EMIT_BUILD_FLAGS([if $CC accepts -pipe], [cs_cv_prog_cc_pipe], + [CS_CREATE_TUPLE([-pipe])], [C], [COMPILER.CFLAGS], [+]) + ]) +]) + +AC_DEFUN([CS_PROG_CXX],[ + CXXFLAGS="$CXXFLAGS" # Filter undesired flags + AS_IF([test -n "$CXX"],[ + CS_EMIT_BUILD_PROPERTY([CMD.C++], [$CXX]) + + CS_EMIT_BUILD_PROPERTY([COMPILER.C++FLAGS], [$CPPFLAGS $CXXFLAGS], [+]) + + # Check if compiler can be instructed to produce position-independent-code + # (PIC). This feature is required by some platforms when building plugin + # modules and shared libraries. + CS_COMPILER_PIC([C++], [cs_cv_prog_cxx_pic], + [CS_EMIT_BUILD_PROPERTY([COMPILER.C++FLAGS.PIC], + [$cs_cv_prog_cxx_pic])]) + ]) +]) + +AC_DEFUN([CS_PROG_LINK],[ + AC_REQUIRE([CS_PROG_CXX]) + AS_IF([test -n "$CXX"], + [CS_EMIT_BUILD_PROPERTY([CMD.LINK], [AS_ESCAPE([$(CMD.C++)])])], + [CS_EMIT_BUILD_PROPERTY([CMD.LINK], [AS_ESCAPE([$(CMD.CC)])])]) + + CS_EMIT_BUILD_PROPERTY([COMPILER.LFLAGS], [$LDFLAGS], [+]) + + # Check if compiler/linker recognizes -shared directive which is needed for + # linking plugin modules. Unfortunately, the Apple compiler (and possibly + # others) requires extra effort. Even though the compiler does not recognize + # the -shared option, it nevertheless returns a "success" result after emitting + # the warning "unrecognized option `-shared'". Worse, even -Werror fails to + # promote the warning to an error, so we must instead scan the compiler's + # output for an appropriate diagnostic. + CS_CHECK_BUILD_FLAGS([if -shared is accepted], [cs_cv_prog_link_shared], + [CS_CREATE_TUPLE([-shared $cs_cv_prog_cxx_pic])], [C++], + [CS_EMIT_BUILD_PROPERTY([PLUGIN.LFLAGS], [-shared], [+])], [], + [], [], [], [shared]) + + # Check if linker recognizes -soname which is used to assign a name internally + # to plugin modules. + CS_CHECK_BUILD([if -soname is accepted], [cs_cv_prog_link_soname], [], + [CS_CREATE_TUPLE([-Wl,-soname,foobar])], [C++], + [CS_EMIT_BUILD_PROPERTY([PLUGIN.LFLAGS.USE_SONAME], [yes])]) +]) +#------------------------------------------------------------------------------ +# Determine host platform. Recognized families: Unix, Windows, MacOS/X. +# Orginial Macros Copyright (C)2003 Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Determine host CPU. +# +# CS_CHECK_HOST_CPU +# Set the shell variable cs_host_cpu to a normalized form of the CPU name +# returned by config.guess/config.sub. Typically, Crystal Space's +# conception of CPU name is the same as that returned by +# config.guess/config.sub, but there may be exceptions as seen in the +# `case' statement. Also takes the normalized name, uppercases it to +# form a name suitable for the C preprocessor. Additionally sets the +# TARGET.PROCESSOR Jamconfig property. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_HOST_CPU], + [AC_REQUIRE([AC_CANONICAL_HOST]) + case $host_cpu in + [[Ii][3-9]86*|[Xx]86*]) cs_host_cpu=x86 ;; + *) cs_host_cpu=$host_cpu ;; + esac + cs_host_cpu_normalized="AS_TR_CPP([$cs_host_cpu])" + CS_JAMCONFIG_PROPERTY([TARGET.PROCESSOR], [$cs_host_cpu_normalized]) + ]) + + +#------------------------------------------------------------------------------ +# CS_CHECK_HOST +# Sets the shell variables cs_host_target cs_host_family, +# cs_host_os_normalized, and cs_host_os_normalized_uc. Emits appropriate +# CS_PLATFORM_UNIX, CS_PLATFORM_WIN32, CS_PLATFORM_MACOSX via +# AC_DEFINE(), and TARGET.OS and TARGET.OS.NORMALIZED to Jamconfig. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_HOST], + [AC_REQUIRE([AC_CANONICAL_HOST]) + CS_CHECK_HOST_CPU + cs_host_os_normalized='' + case $host_os in + mingw*|cygwin*) + cs_host_target=win32gcc + cs_host_family=windows + ;; + darwin*) + _CS_CHECK_HOST_DARWIN + ;; + *) + # Everything else is assumed to be Unix or Unix-like. + cs_host_target=unix + cs_host_family=unix + ;; + esac + + case $cs_host_family in + windows) + AC_DEFINE([CS_PLATFORM_WIN32], [], + [Define when compiling for Win32]) + AS_IF([test -z "$cs_host_os_normalized"], + [cs_host_os_normalized='Win32']) + ;; + unix) + AC_DEFINE([CS_PLATFORM_UNIX], [], + [Define when compiling for Unix and Unix-like (i.e. MacOS/X)]) + AS_IF([test -z "$cs_host_os_normalized"], + [cs_host_os_normalized='Unix']) + ;; + esac + + cs_host_os_normalized_uc="AS_TR_CPP([$cs_host_os_normalized])" + CS_JAMCONFIG_PROPERTY([TARGET.OS], [$cs_host_os_normalized_uc]) + CS_JAMCONFIG_PROPERTY([TARGET.OS.NORMALIZED], [$cs_host_os_normalized]) +]) + +AC_DEFUN([_CS_CHECK_HOST_DARWIN], + [AC_REQUIRE([CS_PROG_CC]) + AC_REQUIRE([CS_PROG_CXX]) + + # Both MacOS/X and Darwin are identified via $host_os as "darwin". We need + # a way to distinguish between the two. If Carbon.h is present, then + # assume MacOX/S; if not, assume Darwin. If --with-x=yes was invoked, and + # Carbon.h is present, then assume that user wants to cross-build for + # Darwin even though build host is MacOS/X. + # IMPLEMENTATION NOTE *1* + # The QuickTime 7.0 installer removes , which + # causes #include to fail unconditionally. Re-installing + # the QuickTime SDK should restore the header, however not all developers + # know to do this, so we work around the problem of the missing + # CarbonSound.h by #defining __CARBONSOUND__ in the test in order to + # prevent Carbon.h from attempting to #include the missing header. + # IMPLEMENTATION NOTE *2* + # At least one MacOS/X user switches between gcc 2.95 and gcc 3.3 with a + # script which toggles the values of CC, CXX, and CPP. Unfortunately, CPP + # was being set to run the preprocessor directly ("cpp", for instance) + # rather than running it via the compiler ("gcc -E", for instance). The + # problem with running the preprocessor directly is that __APPLE__ and + # __GNUC__ are not defined, which causes the Carbon.h check to fail. We + # avoid this problem by supplying a non-empty fourth argument to + # AC_CHECK_HEADER(), which causes it to test compile the header only (which + # is a more robust test), rather than also testing it via the preprocessor. + + AC_DEFINE([__CARBONSOUND__], [], + [Avoid problem caused by missing ]) + AC_CHECK_HEADER([Carbon/Carbon.h], + [cs_host_macosx=yes], [cs_host_macosx=no], [/* force compile */]) + + AS_IF([test $cs_host_macosx = yes], + [AC_MSG_CHECKING([for --with-x]) + AS_IF([test "${with_x+set}" = set && test "$with_x" = "yes"], + [AC_MSG_RESULT([yes (assume Darwin)]) + cs_host_macosx=no], + [AC_MSG_RESULT([no])])]) + + AS_IF([test $cs_host_macosx = yes], + [cs_host_target=macosx + cs_host_family=unix + cs_host_os_normalized='MacOS/X' + AC_DEFINE([CS_PLATFORM_MACOSX], [], + [Define when compiling for MacOS/X]) + + AC_CACHE_CHECK([for Objective-C compiler], [cs_cv_prog_objc], + [cs_cv_prog_objc="$CC"]) + CS_JAMCONFIG_PROPERTY([CMD.OBJC], [$cs_cv_prog_objc]) + AC_CACHE_CHECK([for Objective-C++ compiler], [cs_cv_prog_objcxx], + [cs_cv_prog_objcxx="$CXX"]) + CS_JAMCONFIG_PROPERTY([CMD.OBJC++], [$cs_cv_prog_objcxx])], + + [cs_host_target=unix + cs_host_family=unix])]) +# diagnose.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_MSG_ERROR(ERROR-DESCRIPTION, [EXIT-STATUS]) +# A convenience wrapper for AC_MSG_ERROR() which invokes AC_CACHE_SAVE() +# before aborting the script. Saving the cache should make subsequent +# re-invocations of the configure script faster once the user has +# corrected the problem(s) which caused the failure. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_MSG_ERROR], + [AC_CACHE_SAVE + AC_MSG_ERROR([$1], [$2])]) +# embed.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003,2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_META_INFO_EMBED([EMITTER], [GPL-OKAY]) +# Determine if plugin meta-information should be embedded or if it should +# exist in a stand-alone .csplugin file, and check if necessary tools and +# libraries are present. Sets the shell variable +# enable_meta_info_embedding to "yes" if the user requested embedding or +# if it was enabled by default; otherwise sets it to "no". +# +# If EMITTER is provided, then a subset of the following variables +# (depending upon platform and availability) are recorded by invoking +# CS_EMIT_BUILD_PROPERTY() with EMITTER. As a convenience, if EMITTER is +# the literal value "emit" or "yes", then CS_EMIT_BUILD_RESULT()'s +# default emitter will be used. +# +# EMBED_META := yes or no +# EMBED_META.CFLAGS := compiler flags +# EMBED_META.LFLAGS := linker flags +# CMD.WINDRES := windres.exe +# OBJCOPY.AVAILABLE := yes or no +# CMD.OBJCOPY := objcopy.exe +# LIBBFD.AVAILABLE := yes or no +# LIBBFD.CFLAGS := libbfd compiler flags +# LIBBFD.LFLAGS := libbfd linker flags +# ELF.AVAILABLE := yes or no +# +# In general, clients need only concern themselves with the various +# EMBED_META-related variables. For building plugin modules, utilize +# EMBED_META.CFLAGS when compiling, and EMBED_META.LFLAGS when linking. +# +# On Unix, when CS' own ELF metadata reader can't be used (because the +# necessary header file elf.h was not found) embedding is accomplished +# via libbfd, which carries a GPL license. Projects which carry licenses +# not compatible with GPL should consider carefully before enabling +# embedding on Unix. If your project is GPL-compatible, then set GPL-OKAY +# to "yes". This will indicate that it is safe to use libbfd if the ELF +# reader can not be used. If your project is not GPL-compatible, then +# set it to "no" in order to disable embedding on Unix if the ELF reader +# is not usable. (The user can still manually override the setting via +# the --enable-meta-info-embedding option.) +# +# IMPLEMENTATION NOTES +# +# Recent versions of Mingw supply libbfd and libiberty. Since Crystal +# Space uses native Win32 API for meta-information embedding on Windows, +# we do not require these libraries on Windows. More importantly, users +# do not want to see these GPL-licensed libraries appear in the link +# statement for plugin modules, thus we explicitly disable the libbfd +# test on Windows. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_META_INFO_EMBED], + [AC_REQUIRE([AC_CANONICAL_HOST]) + _CS_META_INFO_EMBED_ENABLE([$1], [$2]) + AS_IF([test $enable_meta_info_embedding = yes], + [_CS_META_INFO_EMBED_TOOLS([$1]) + AS_IF([test $cs_header_elf_h = yes], + [CS_EMIT_BUILD_PROPERTY([ELF.AVAILABLE], [yes], [], [], + CS_EMITTER_OPTIONAL([$1]))], + [case $host_os in + mingw*|cygwin*) ;; + *) + CS_CHECK_LIBBFD([$1], + [CS_EMIT_BUILD_PROPERTY([EMBED_META.CFLAGS], + [$cs_cv_libbfd_ok_cflags], [+], [], + CS_EMITTER_OPTIONAL([$1])) + CS_EMIT_BUILD_PROPERTY([EMBED_META.LFLAGS], + [$cs_cv_libbfd_ok_lflags $cs_cv_libbfd_ok_libs], + [+], [], CS_EMITTER_OPTIONAL([$1]))]) + ;; + esac])])]) + + +#------------------------------------------------------------------------------ +# _CS_META_INFO_EMBED_ENABLE([EMITTER], [GPL-OKAY]) +# Helper for CS_META_INFO_EMBED which adds an +# --enable-meta-info-embedding option to the configure script allowing +# the user to control embedding. Sets the shell variable +# enable_meta_info_embedding to yes or no. +# +# IMPLEMENTATION NOTES +# +# On Unix, embedding is enabled by default if elf.h is found and disabled +# by default unless overridden via GPL-OKAY because libbfd carries a GPL +# license which may be incompatible with a project's own license (such as +# LGPL). +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_META_INFO_EMBED_ENABLE], + [AC_REQUIRE([CS_CHECK_HOST]) + AC_CHECK_HEADERS([elf.h], [cs_header_elf_h=yes], [cs_header_elf_h=no]) + AC_MSG_CHECKING([whether to embed plugin meta-information]) + case $cs_host_target in + unix) AS_IF([test $cs_header_elf_h = yes], + [cs_embed_meta_info_default=yes], + [cs_embed_meta_info_default=m4_ifval([$2],[$2],[no])]) ;; + *) cs_embed_meta_info_default=yes ;; + esac + AC_ARG_ENABLE([meta-info-embedding], + [AC_HELP_STRING([--enable-meta-info-embedding], + [store plugin meta-information directly inside plugin modules if + supported by platform; if disabled, meta-information is stored in + stand-alone .csplugin files; this option is enabled by default for + non-Unix platforms and on Unix platforms with ELF-format object + files; it is disabled by default on Unix platforms if ELF is not + available and the project uses a non-GPL-compatible license (such + as LGPL) since the non-ELF Unix embedding technology requires the + GPL-licensed libbfd library; if ELF is not available, enable this + option on Unix only if you are certain you want a GPL-licensed + library infecting your project])], + [], [enable_meta_info_embedding=$cs_embed_meta_info_default]) + AC_MSG_RESULT([$enable_meta_info_embedding]) + CS_EMIT_BUILD_PROPERTY([EMBED_META], [$enable_meta_info_embedding], + [], [], CS_EMITTER_OPTIONAL([$1]))]) + + + +#------------------------------------------------------------------------------ +# _CS_META_INFO_EMBED_TOOLS([EMITTER]) +# Helper for CS_META_INFO_EMBED() which searches for tools required for +# plugin meta-info embedding. +#------------------------------------------------------------------------------ +AC_DEFUN([_CS_META_INFO_EMBED_TOOLS], + [CS_CHECK_TOOLS([WINDRES], [windres]) + CS_EMIT_BUILD_PROPERTY([CMD.WINDRES], [$WINDRES], [], [], + CS_EMITTER_OPTIONAL([$1])) + + CS_CHECK_TOOLS([OBJCOPY], [objcopy]) + AS_IF([test -n "$OBJCOPY"], + [CS_EMIT_BUILD_PROPERTY([OBJCOPY.AVAILABLE], [yes], [], [], + CS_EMITTER_OPTIONAL([$1])) + CS_EMIT_BUILD_PROPERTY([CMD.OBJCOPY], [$OBJCOPY], [], [], + CS_EMITTER_OPTIONAL([$1]))])]) + + + +#------------------------------------------------------------------------------ +# CS_CHECK_LIBBFD([EMITTER], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# Exhaustive check for a usable GPL-licensed libbfd, the Binary File +# Descriptor library, a component of binutils, which allows low-level +# manipulation of executable and object files. If EMITTER is provided, +# then the following variables are recorded by invoking +# CS_EMIT_BUILD_PROPERTY() with EMITTER. As a convenience, if EMITTER is +# the literal value "emit" or "yes", then CS_EMIT_BUILD_RESULT()'s +# default emitter will be used. +# +# LIBBFD.AVAILABLE := yes or no +# LIBBFD.CFLAGS := libbfd compiler flags +# LIBBFD.LFLAGS := libbfd linker flags +# +# The shell variable cs_cv_libbfd_ok is set to yes if a usable libbfd was +# discovered, else no. If found, the additional shell variables +# cs_cv_libbfd_ok_cflags, cs_cv_libbfd_ok_lflags, and +# cs_cv_libbfd_ok_libs are also set. +# +# WARNING +# +# libbfd carries a GPL license which is incompatible with the LGPL +# license of Crystal Space. Do not use this library with projects under +# less restrictive licenses, such as LGPL. +# +# IMPLEMENTATION NOTES +# +# It seems that some platforms have two version of libiberty installed: +# one from binutils and one from gcc. The binutils version resides in +# /usr/lib, whereas the gcc version resides in the gcc installation +# directory. The gcc version, by default, takes precedence at link time +# over the binutils version. Unfortunately, in broken cases, the gcc +# version of libiberty is missing htab_create_alloc() which is required +# by some libbfd functions. The extensive secondary check of libbfd +# catches this anomalous case of broken gcc libiberty. It turns out that +# it is possible to make the linker prefer the binutils version by +# specifying -L/usr/lib, thus the extensive test attempts to do so in an +# effort to resolve this unfortunate issue. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_LIBBFD], + [CS_CHECK_LIB_WITH([bfd], + [AC_LANG_PROGRAM([[#include ]], [bfd_init();])], + [], [], [], [], [], [], [-liberty]) + + AS_IF([test $cs_cv_libbfd = yes], + [CS_CHECK_BUILD([if libbfd is usable], [cs_cv_libbfd_ok], + [AC_LANG_PROGRAM([[#include ]], + [bfd* p; + asection* s; + bfd_init(); + p = bfd_openr(0,0); + bfd_check_format(p,bfd_object); + bfd_get_section_by_name(p,0); + bfd_section_size(p,s); + bfd_get_section_contents(p,s,0,0,0); + bfd_close(p);])], + [CS_CREATE_TUPLE() CS_CREATE_TUPLE([],[-L/usr/lib],[])], + [], [], [], [], + [$cs_cv_libbfd_cflags], + [$cs_cv_libbfd_lflags], + [$cs_cv_libbfd_libs])], + [cs_cv_libbfd_ok=no]) + + AS_IF([test $cs_cv_libbfd_ok = yes], + [CS_EMIT_BUILD_RESULT([cs_cv_libbfd_ok], [LIBBFD], + CS_EMITTER_OPTIONAL([$1])) + $2], + [$3])]) +# emit.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003-2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_EMIT_BUILD_PROPERTY(KEY, VALUE, [APPEND], [EMPTY-OKAY], [EMITTER], +# [UNCONDITIONAL]) +# A utility function which invokes an emitter to record the KEY/VALUE +# tuple if VALUE is not the empty string (after leading and trailing +# whitespace is stripped). If EMPTY-OKAY is not an empty string, then the +# property is emitted even if VALUE is empty; that is, it is emitted +# unconditionally. If APPEND is the empty string, then the emitter sets +# the key's value directly (though it may be overridden by the +# environment), otherwise the emitter appends VALUE to the existing value +# of the key. EMITTER is a macro name, such as CS_JAMCONFIG_PROPERTY or +# CS_MAKEFILE_PROPERTY, which performs the actual task of emitting the +# KEY/VALUE tuple; it should also accept APPEND as an optional third +# argument. If EMITTER is omitted, CS_JAMCONFIG_PROPERTY is used. Some +# emitters accept an optional fourth argument, UNCONDITIONAL, which +# instructs it to set KEY's value unconditionally, even if KEY already +# had been assigned a value via some other mechanism (such as imported +# from the environment, or from Jambase, in the case of +# CS_JAMCONFIG_PROPERTY). +#------------------------------------------------------------------------------ +AC_DEFUN([CS_EMIT_BUILD_PROPERTY], + [cs_build_prop_val="$2" + cs_build_prop_val=CS_TRIM([$cs_build_prop_val]) + m4_ifval([$4], + [CS_JAMCONFIG_PROPERTY([$1], [$cs_build_prop_val], [$3])], + AS_IF([test -n "$cs_build_prop_val"], + [m4_default([$5],[CS_JAMCONFIG_PROPERTY])( + [$1], [$cs_build_prop_val], [$3], [$6])]))]) + + + +#------------------------------------------------------------------------------ +# CS_EMIT_BUILD_RESULT(CACHE-VAR, PREFIX, [EMITTER]) +# Record the results of CS_CHECK_BUILD() or CS_CHECK_LIB_WITH() via some +# emitter. If CACHE-VAR indicates that the build succeeded, then the +# following properties are emitted: +# +# PREFIX.AVAILABLE = yes +# PREFIX.CFLAGS = $CACHE-VAR_cflags +# PREFIX.LFLAGS = $CACHE-VAR_lflags $CACHE-VAR_libs +# +# EMITTER is a macro name, such as CS_JAMCONFIG_PROPERTY or +# CS_MAKEFILE_PROPERTY, which performs the actual task of emitting the +# KEY/VALUE tuple. If EMITTER is omitted, CS_JAMCONFIG_PROPERTY is used. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_EMIT_BUILD_RESULT], + [AS_IF([test "$$1" = yes], + [CS_EMIT_BUILD_PROPERTY([$2.AVAILABLE], [yes], [], [], [$3]) + CS_EMIT_BUILD_PROPERTY([$2.CFLAGS], [$$1_cflags], [], [], [$3]) + CS_EMIT_BUILD_PROPERTY([$2.LFLAGS], [$$1_lflags $$1_libs], + [], [], [$3])])]) + + + +#------------------------------------------------------------------------------ +# CS_EMIT_BUILD_FLAGS(MESSAGE, CACHE-VAR, FLAGS, [LANGUAGE], EMITTER-KEY, +# [APPEND], [ACTION-IF-RECOGNIZED], +# [ACTION-IF-NOT-RECOGNIZED], [EMITTER]) +# A convenience wrapper for CS_CHECK_BUILD_FLAGS() which also records the +# results via CS_EMIT_BUILD_PROPERTY(). Checks if the compiler or linker +# recognizes a command-line option. MESSAGE is the "checking" message. +# CACHE-VAR is the shell cache variable which receives the flag +# recognized by the compiler or linker, or "no" if the flag was not +# recognized. FLAGS is a whitespace- delimited list of build tuples +# created with CS_CREATE_TUPLE(). Each tuple from FLAGS is attempted in +# order until one is found which is recognized by the compiler. After +# that, no further flags are checked. LANGUAGE is typically either C or +# C++ and specifies which compiler to use for the test. If LANGUAGE is +# omitted, C is used. EMITTER-KEY is the name to pass as the emitter's +# "key" argument if a usable flag is encountered. If APPEND is not the +# empty string, then the discovered flag is appended to the existing +# value of the EMITTER-KEY. If the command-line option was recognized, +# then ACTION-IF-RECOGNIZED is invoked, otherwise +# ACTION-IF-NOT-RECOGNIZED is invoked. EMITTER is a macro name, such as +# CS_JAMCONFIG_PROPERTY or CS_MAKEFILE_PROPERTY, which performs the +# actual task of emitting the KEY/VALUE tuple; it should also accept +# APPEND as an optional third argument. If EMITTER is omitted, +# CS_JAMCONFIG_PROPERTY is used. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_EMIT_BUILD_FLAGS], + [CS_CHECK_BUILD_FLAGS([$1], [$2], [$3], [$4], + [CS_EMIT_BUILD_PROPERTY([$5], [$$2], [$6], [], [$9]) + $7], + [$8])]) + + + +#------------------------------------------------------------------------------ +# CS_EMITTER_OPTIONAL([EMITTER]) +# The CS_EMIT_FOO() macros optionally accept an emitter. If no emitter is +# supplied to those macros, then a default emitter is chosen. Other +# macros, however, which perform testing and optionally emit the results +# may wish to interpret an omitted EMITTER as a request not to emit the +# results. CS_EMITTER_OPTIONAL() is a convenience macro to help in these +# cases. It should be passed to one of the CS_EMIT_FOO() macros in place +# of the literal EMITTER argument. It functions by re-interpretating +# EMITTER as follows: +# +# - If EMITTER is omitted, then CS_NULL_EMITTER is returned, effectively +# disabling output by the CS_EMIT_FOO() macro. +# - If EMITTER is the literal string "emit" or "yes", then it returns an +# empty string, which signals to the CS_EMIT_FOO() macro that is should +# use its default emitter. +# - Any other value for EMITTER is passed along as-is to the +# CS_EMIT_FOO() macro. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_EMITTER_OPTIONAL], + [m4_case([$1], + [], [[CS_NULL_EMITTER]], + [emit], [], + [yes], [], + [[$1]])]) + + + +#------------------------------------------------------------------------------ +# CS_NULL_EMITTER(KEY, VALUE, [APPEND]) +# A do-nothing emitter suitable for use as the EMITTER argument of one of +# the CS_EMIT_FOO() macros. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_NULL_EMITTER], [: +]) + + + +#------------------------------------------------------------------------------ +# CS_SUBST_EMITTER(KEY, VALUE, [APPEND]) +# An emitter wrapped around AC_SUBST(). Invokes +# AC_SUBST(AS_TR_SH(KEY),VALUE). The APPEND argument is ignored. +# Suitable for use as the EMITTER argument of one of the CS_EMIT_FOO() +# macros. The call to AS_TR_SH() ensures that KEY is transformed into a +# valid shell variable. For instance, if a macro attempts to emit +# MYLIB.CFLAGS and MYLIB.LFLAGS via CS_SUBST_EMITTER(), then the names +# will be transformed to MYLIB_CFLAGS and MYLIB_LFLAGS, respectively, for +# the invocation of AC_SUBST(). +#------------------------------------------------------------------------------ +AC_DEFUN([CS_SUBST_EMITTER], [AC_SUBST(AS_TR_SH([$1]),[$2])]) + + + +#------------------------------------------------------------------------------ +# CS_DEFINE_EMITTER(KEY, VALUE, [APPEND]) +# An emitter wrapped around AC_DEFINE_UNQUOTED(). Invokes +# AC_DEFINE_UNQUOTED(AS_TR_CPP(KEY),VALUE). The APPEND argument is +# ignored. Suitable for use as the EMITTER argument of one of the +# CS_EMIT_FOO() macros. The call to AS_TR_CPP() ensures that KEY is a +# well-formed token for the C-preprocessor. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_DEFINE_EMITTER], + [AC_DEFINE_UNQUOTED(AS_TR_CPP([$1]),[$2], + [Define when feature is available])]) +# headercache.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# Text cache facility for C-style #define properties. The cache is stored in +# the shell variable cs_header_text. +# +# CS_HEADER_APPEND(TEXT) +# Append text to the C header text cache. This is a cover for +# CS_TEXT_CACHE_APPEND(). +# +# CS_HEADER_PREPEND(TEXT) +# Prepend text to the C header text cache. This is a cover for +# CS_TEXT_CACHE_PREPEND(). +# +# CS_HEADER_PROPERTY(KEY, [VALUE]) +# Append a line of the form "#define KEY VALUE" to the C header text +# cache. If the VALUE argument is omitted, then the appended line has +# the simplified form "#define KEY". +# +# CS_HEADER_OUTPUT(FILENAME) +# Instruct config.status to write the C header text cache to the given +# filename. This is a cover for CS_TEXT_CACHE_OUTPUT(). +#------------------------------------------------------------------------------ +AC_DEFUN([CS_HEADER_APPEND], [CS_TEXT_CACHE_APPEND([cs_header_text], [$1])]) +AC_DEFUN([CS_HEADER_PREPEND], [CS_TEXT_CACHE_PREPEND([cs_header_text], [$1])]) +AC_DEFUN([CS_HEADER_PROPERTY], +[CS_HEADER_APPEND([@%:@define $1[]m4_ifval([$2], [ $2], []) +])]) +AC_DEFUN([CS_HEADER_OUTPUT], [CS_TEXT_CACHE_OUTPUT([cs_header_text], [$1])]) +#----------------------------------------------------------------------------- +# installdirs.m4 (c) Matze Braun +# Macro for emitting the installation paths gathered by Autoconf. +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# CS_OUTPUT_INSTALLDIRS([EMITTER], [RAW-BACKSLASHES]) +# Emit installation directories collected by Autoconf. EMITTER is a macro +# name, such as CS_JAMCONFIG_PROPERTY or CS_MAKEFILE_PROPERTY, which performs +# the actual task of emitting the KEY/VALUE tuple. If EMITTER is omitted, +# CS_JAMCONFIG_PROPERTY is used. If RAW-BACKSLASHES is not provided, then +# backslashes in emitted values are each escaped with an additional +# backslash. If RAW-BACKSLASHES is not the null value, then backslashes are +# emitted raw. The following properties are emitted: +# +# prefix +# exec_prefix +# bindir +# sbindir +# libexecdir +# datadir +# sysconfdir +# sharedstatedir +# localstatedir +# libdir +# includedir +# oldincludedir +# infodir +# mandir +#----------------------------------------------------------------------------- +AC_DEFUN([CS_OUTPUT_INSTALLDIRS],[ +# Handle the case when no prefix is given, and the special case when a path +# contains more than 2 slashes, these paths seem to be correct but Jam fails +# on them. +AS_IF([test $prefix = NONE], + [cs_install_prefix="$ac_default_prefix"], + [cs_install_prefix=`echo "$prefix" | sed -e 's:///*:/:g'`]) +AS_IF([test $exec_prefix = NONE], + [cs_install_exec_prefix="AS_ESCAPE([$(prefix)])"], + [cs_install_exec_prefix=`echo "$exec_prefix" | sed -e 's:///*:/:g'`]) + +_CS_OUTPUT_INSTALL_DIRS([$1], [prefix], + [CS_PREPARE_INSTALLPATH([$cs_install_prefix], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [exec_prefix], + [CS_PREPARE_INSTALLPATH([$cs_install_exec_prefix], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [bindir], + [CS_PREPARE_INSTALLPATH([$bindir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [sbindir], + [CS_PREPARE_INSTALLPATH([$sbindir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [libexecdir], + [CS_PREPARE_INSTALLPATH([$libexecdir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [datadir], + [CS_PREPARE_INSTALLPATH([$datadir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [sysconfdir], + [CS_PREPARE_INSTALLPATH([$sysconfdir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [sharedstatedir], + [CS_PREPARE_INSTALLPATH([$sharedstatedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [localstatedir], + [CS_PREPARE_INSTALLPATH([$localstatedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [libdir], + [CS_PREPARE_INSTALLPATH([$libdir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [includedir], + [CS_PREPARE_INSTALLPATH([$includedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [oldincludedir], + [CS_PREPARE_INSTALLPATH([$oldincludedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [infodir], + [CS_PREPARE_INSTALLPATH([$infodir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [mandir], + [CS_PREPARE_INSTALLPATH([$mandir], [$2])]) +]) + +AC_DEFUN([_CS_OUTPUT_INSTALL_DIRS], + [m4_default([$1], [CS_JAMCONFIG_PROPERTY])([$2], [$3])]) + + +#----------------------------------------------------------------------------- +# CS_PREPARE_INSTALLPATH(VALUE, [RAW-BACKSLASHES]) +# Transform variable references of the form ${bla} to $(bla) in VALUE and +# correctly quotes backslashes. This is needed if you need to emit some of +# the paths from Autoconf. RAW-BACKSLASHES has the same meaning as in +# CS_OUTPUT_INSTALLDIRS. +#----------------------------------------------------------------------------- +AC_DEFUN([CS_PREPARE_INSTALLPATH], +[`echo "$1" | sed 's/\${\([[a-zA-Z_][a-zA-Z_]]*\)}/$(\1)/g;m4_ifval([$2], + [s/\\/\\\\/g], [s/\\\\/\\\\\\\\/g])'`]) +# jamcache.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# Text cache facility for Jam-style properties. The cache is stored in +# the shell variable cs_jamfile_text. +# +# CS_JAMCONFIG_APPEND(TEXT) +# Append text to the Jam text cache. This is a cover for +# CS_TEXT_CACHE_APPEND(). +# +# CS_JAMCONFIG_PREPEND(TEXT) +# Prepend text to the Jam text cache. This is a cover for +# CS_TEXT_CACHE_PREPEND(). +# +# CS_JAMCONFIG_PROPERTY(KEY, VALUE, [APPEND], [UNCONDITIONAL]) +# Append a line of the form "KEY ?= VALUE" to the Jam text cache. If the +# APPEND argument is not the empty string, then VALUE is appended to the +# existing value of KEY using the form "KEY += VALUE". If the +# UNCONDITIONAL argument is not empty, then the value of KEY is set +# unconditionally "KEY = VALUE", rather than via "KEY ?= VALUE". APPEND +# takes precedence over UNCONDITIONAL. Note that if VALUE references +# other Jam variables, for example $(OBJS), then be sure to protect the +# value with AS_ESCAPE(). For example: +# CS_JAMCONFIG_PROPERTY([ALLOBJS], [AS_ESCAPE([$(OBJS) $(LIBOBJS)])]) +# +# CS_JAMCONFIG_OUTPUT(FILENAME) +# Instruct config.status to write the Jam text cache to the given +# filename. This is a cover for CS_TEXT_CACHE_OUTPUT(). +#------------------------------------------------------------------------------ +AC_DEFUN([CS_JAMCONFIG_APPEND], + [CS_TEXT_CACHE_APPEND([cs_jamconfig_text], [$1])]) +AC_DEFUN([CS_JAMCONFIG_PREPEND], + [CS_TEXT_CACHE_PREPEND([cs_jamconfig_text], [$1])]) +AC_DEFUN([CS_JAMCONFIG_PROPERTY], + [CS_JAMCONFIG_APPEND( + [$1 m4_ifval([$3], [+=], m4_ifval([$4], [=], [?=])) \"$2\" ; +])]) +AC_DEFUN([CS_JAMCONFIG_OUTPUT], + [CS_TEXT_CACHE_OUTPUT([cs_jamconfig_text], [$1])]) +# makecache.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# Text cache facility for makefile-style properties. The cache is stored in +# the shell variable cs_makefile_text. +# +# CS_MAKEFILE_APPEND(TEXT) +# Append text to the makefile text cache. This is a cover for +# CS_TEXT_CACHE_APPEND(). +# +# CS_MAKEFILE_PREPEND(TEXT) +# Prepend text to the makefile text cache. This is a cover for +# CS_TEXT_CACHE_PREPEND(). +# +# CS_MAKEFILE_PROPERTY(KEY, VALUE, [APPEND]) +# Append a line of the form "KEY = VALUE" to the makefile text cache. If +# the APPEND argument is not the empty string, then VALUE is appended to +# the existing value of KEY using the form "KEY += VALUE". Note that if +# VALUE references other makefile variables, for example $(OBJS), then be +# sure to protect the value with AS_ESCAPE(). For example: +# CS_MAKEFILE_PROPERTY([ALLOBJS], [AS_ESCAPE([$(OBJS) $(LIBOBJS)])]) +# +# CS_MAKEFILE_OUTPUT(FILENAME) +# Instruct config.status to write the makefile text cache to the given +# filename. This is a cover for CS_TEXT_CACHE_OUTPUT(). +#------------------------------------------------------------------------------ +AC_DEFUN([CS_MAKEFILE_APPEND], + [CS_TEXT_CACHE_APPEND([cs_makefile_text], [$1])]) +AC_DEFUN([CS_MAKEFILE_PREPEND], + [CS_TEXT_CACHE_PREPEND([cs_makefile_text], [$1])]) +AC_DEFUN([CS_MAKEFILE_PROPERTY], + [CS_MAKEFILE_APPEND([$1 m4_ifval([$3], [+=], [=]) $2 +])]) +AC_DEFUN([CS_MAKEFILE_OUTPUT],[CS_TEXT_CACHE_OUTPUT([cs_makefile_text], [$1])]) +# mkdir.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_CHECK_MKDIR +# Determine how to create a directory and a directory tree. Sets the +# shell variable MKDIR to the command which creates a directory, and +# MKDIRS to the command which creates a directory tree. Invokes +# AC_SUBST() for MKDIR and MKDIRS. +# +# IMPLEMENTATION NOTES +# We need to know the exact commands, so that we can emit them, thus the +# AS_MKDIR_P function is not what we want to use here since it does not +# provide access to the commands (and might not even discover suitable +# commands). First try "mkdir -p", then try the older "mkdirs". +# Finally, if the mkdir command failed to recognize -p, then it might +# have created a directory named "-p", so clean up that bogus directory. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_CHECK_MKDIR], + [AC_CACHE_CHECK([how to create a directory], [cs_cv_shell_mkdir], + [cs_cv_shell_mkdir='mkdir']) + AC_SUBST([MKDIR], [$cs_cv_shell_mkdir]) + + AC_CACHE_CHECK([how to create a directory tree], [cs_cv_shell_mkdir_p], + [if $cs_cv_shell_mkdir -p . 2>/dev/null; then + cs_cv_shell_mkdir_p='mkdir -p' + elif mkdirs . 2>/dev/null; then + cs_cv_shell_mkdir_p='mkdirs' + fi + test -d ./-p && rmdir ./-p]) + AS_VAR_SET_IF([cs_cv_shell_mkdir_p], + [AC_SUBST([MKDIRS], [$cs_cv_shell_mkdir_p])], + [CS_MSG_ERROR([do not know how to create a directory tree])])]) + + + +#------------------------------------------------------------------------------ +# Replacement for AS_MKDIR_P() from m4sugar/m4sh.m4 which fixes two problems +# which are present in Autoconf 2.57 and probably all earlier 2.5x versions. +# This bug, along with a patch, was submitted to the Autoconf GNATS database by +# Eric Sunshine as #227 on 17-Dec-2002. The bogus "-p" directory bug was fixed +# for Autoconf 2.58 on 26-Sep-2003. The "mkdirs" optimization was not accepted +# (since it is unnecessary; it's only an optimization). +# +# 1) Removes bogus "-p" directory which the stock AS_MKDIR_P() leaves laying +# around in the working directory if the mkdir command does not recognize +# the -p option. +# 2) Takes advantage of the older "mkdirs" program if it exists and if "mkdir +# -p" does not work. +#------------------------------------------------------------------------------ +m4_defun([_AS_MKDIR_P_PREPARE], +[if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p' +elif mkdirs . 2>/dev/null; then + as_mkdir_p='mkdirs' +else + as_mkdir_p='' +fi +test -d ./-p && rmdir ./-p +])# _AS_MKDIR_P_PREPARE + +m4_define([AS_MKDIR_P], +[AS_REQUIRE([_$0_PREPARE])dnl +{ if test -n "$as_mkdir_p"; then + $as_mkdir_p $1 + else + as_dir=$1 + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`AS_DIRNAME("$as_dir")` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || AS_ERROR([cannot create directory $1]); } +])# AS_MKDIR_P +#============================================================================== +# packageinfo.m4 +# Macros for setting general info on the package, such as name and version +# numbers and propagate them to the generated make and Jam property files. +# +# Copyright (C)2003 by Matthias Braun +# Copyright (C)2003,2004 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== + +#------------------------------------------------------------------------------ +# CS_PACKAGEINFO([LONGNAME], [COPYRIGHT, [HOMEPAGE]) +# Set additional information for the package. Note that the version +# number of your application should only contain numbers, because on +# Windows you can only set numerical values in some of the file +# properties (such as versioninfo .rc files). +#------------------------------------------------------------------------------ +AC_DEFUN([CS_PACKAGEINFO], + [PACKAGE_LONGNAME="[$1]" + PACKAGE_COPYRIGHT="[$2]" + PACKAGE_HOMEPAGE="[$3]" +]) + + +#------------------------------------------------------------------------------ +# CS_EMIT_PACKAGEINFO([EMITTER]) +# Emit extended package information using the provided EMITTER. EMITTER +# is a macro name, such as CS_JAMCONFIG_PROPERTY or CS_MAKEFILE_PROPERTY, +# which performs the actual task of emitting the KEY/VALUE tuple. If +# EMITTER is omitted, CS_JAMCONFIG_PROPERTY is used. For backward +# compatibility, if EMITTER is the literal value "jam", then +# CS_JAMCONFIG_PROPERTY is used; if it is "make", then +# CS_MAKEFILE_PROPERTY is used; however use of these literal names is +# highly discouraged. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_EMIT_PACKAGEINFO], + [_CS_EMIT_PACKAGEINFO([$1], [PACKAGE_NAME], [$PACKAGE_NAME]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_VERSION], [$PACKAGE_VERSION]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_STRING], [$PACKAGE_STRING]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_BUGREPORT], [$PACKAGE_BUGREPORT]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_LONGNAME], [$PACKAGE_LONGNAME]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_HOMEPAGE], [$PACKAGE_HOMEPAGE]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_COPYRIGHT], [$PACKAGE_COPYRIGHT]) + for cs_veritem in m4_translit(AC_PACKAGE_VERSION, [.], [ ]); do + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_VERSION_LIST], [$cs_veritem], [+]) + done + ]) + +AC_DEFUN([_CS_EMIT_PACKAGEINFO], + [m4_case([$1], + [make], [CS_MAKEFILE_PROPERTY([$2], [$3], [$4])], + [jam], [CS_JAMCONFIG_PROPERTY([$2], [$3], [$4])], + [], [CS_JAMCONFIG_PROPERTY([$2], [$3], [$4])], + [$1([$2], [$3], [$4])])]) +# path.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2004 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_PATH_NORMALIZE(STRING) +# Normalize a pathname at run-time by transliterating Windows/DOS +# backslashes to forward slashes. Also collapses whitespace. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_PATH_NORMALIZE], +[`echo "x$1" | tr '\\\\' '/' | sed 's/^x//;s/ */ /g;s/^ //;s/ $//'`]) + + +#------------------------------------------------------------------------------ +# CS_RUN_PATH_NORMALIZE(COMMAND) +# Normalize the pathname emitted by COMMAND by transliterating +# Windows/DOS backslashes to forward slashes. Also collapses whitespace. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_RUN_PATH_NORMALIZE], +[`AC_RUN_LOG([$1]) | tr '\\\\' '/' | sed 's/^x//;s/ */ /g;s/^ //;s/ $//'`]) +############################################################################### +# progver.m4 +# Written by Norman Kramer +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +############################################################################### +# +# From the input pattern we create regular expressions we send through sed +# to extract the version information from the standard input to sed. +# Then we extract from the resulting version string subparts. +# The same happens with the supplied version string. It too is split into its +# subparts according to the pattern. +# Then the subparts from the gathered version string and the supplied one are +# compared. +# +# How does the pattern look like ? +# It is a sequence of 9s and _s and separators. +# 9 denotes a non empty sequence of digits. +# _ denotes a non empty sequence of characters from the class [a-zA-Z]. +# | everything behind is optional +# Everything else is treated as a separator. +# Consecutive 9s and _s are compressed to contain only one of each type. +# For instance "99_.9.__abc9_" will become "9_.9._abc9_". +# +# How we find the parts we compare ? +# From this transformed string we yield the parts we will later compare. +# We break up the string as follows: +# Any sequence of separators represent one breakup. Additional breakups are +# placed behind every 9 and _ . +# So the example from above will give: +# +# "99_.9.__abc9_" ===compress==> "9_.9._abc9_" ===breakup==> "9" "_" "9" "_" "9" "_" +# +# How we create the regular expressions ? +# We take the compressed pattern and quote every separator. +# The we replace the 9s with [0-9][0-9]* +# and the _s with [a-zA-Z][a-zA-Z]* . +# The above example will become: +# +# "99_.9.__abc9_" ===compress==> "9_.9._abc9_" ===rexify==> +# [0-9][0-9]*[a-zA-Z][a-zA-Z]*\.[0-9][0-9]*\.[a-zA-Z][a-zA-Z]*\a\b\c[0-9][0-9]*[a-zA-Z][a-zA-Z]* +# +# Voila. +# +# To yield the subparts from the string we additionally enclose the +# 9s and _s with \( and \). +# +############################################################################### + +# **************************************************************** +# ** helper definitions ** +# **************************************************************** +m4_define([CS_VCHK_RUNTH], [m4_pushdef([i], [$1])m4_if($1,0,,[CS_VCHK_RUNTH(m4_decr($1), [$2])][$2])m4_popdef([i])]) +m4_define([CS_VCHK_PREFIX], []) +m4_define([CS_VCHK_SUFFIX], []) +m4_define([CS_VCHK_GROUPPREFIX], [\(]) +m4_define([CS_VCHK_GROUPSUFFIX], [\)]) +m4_define([CS_VCHK_CHAR], [[[[a-zA-Z]]]]) +m4_define([CS_VCHK_DIGIT], [[[0-9]]]) +m4_define([CS_VCHK_SEQUENCE], [CS_VCHK_PREFIX[]CS_VCHK_SINGLE[]CS_VCHK_SINGLE[]*CS_VCHK_SUFFIX[]]) +m4_define([CS_VCHK_OPTSEQUENCE], [CS_VCHK_PREFIX[]CS_VCHK_SINGLE[]*CS_VCHK_SUFFIX[]]) +m4_define([CS_VCHK_REXSEQ], [m4_bpatsubst($1, [$2], [[]CS_VCHK_SEQUENCE[]])]) +m4_define([CS_VCHK_GROUPINGON], [m4_pushdef([CS_VCHK_PREFIX], [CS_VCHK_GROUPPREFIX])m4_pushdef([CS_VCHK_SUFFIX], [CS_VCHK_GROUPSUFFIX])]) +m4_define([CS_VCHK_GROUPINGOFF], [m4_popdef([CS_VCHK_SUFFIX])m4_popdef([CS_VCHK_PREFIX])]) +m4_define([CS_VCHK_OPTON], [m4_pushdef([CS_VCHK_SEQUENCE], [CS_VCHK_OPTSEQUENCE])]) +m4_define([CS_VCHK_OPTOFF], [m4_popdef([CS_VCHK_SEQUENCE])]) +m4_define([CS_VCHK_RMOPT], [CS_VCHK_RMCHAR([$1], m4_index([$1], [|]))]) +m4_define([CS_VCHK_RMCHAR], [m4_if($2,-1,[$1],m4_substr([$1], 0, $2)[]m4_substr([$1], m4_incr($2)))]) +m4_define([CS_VCHK_RMALL], [m4_translit([$1], [|], [])]) +m4_define([CS_VCHK_CUTOFF], [m4_if(m4_index($1,[|]),-1, [$1], [m4_substr($1, 0, m4_index($1,[|]))])]) +m4_define([CS_VCHK_CYCLEOPT], [ +m4_if($2,-1,, [m4_pushdef([i], CS_VCHK_CUTOFF([$1])) m4_pushdef([j], CS_VCHK_DUMMY_TAIL([$1])) CS_VCHK_CYCLEOPT( CS_VCHK_RMOPT([$1]), m4_index($1, [|]), [$3])$3 m4_popdef([i]) m4_popdef([j])]) +]) +m4_define([CS_VCHK_TAIL], [m4_if(m4_index($1,[|]),-1, [], [m4_substr($1, m4_incr(m4_index($1,[|])))])]) +m4_define([CS_VCHK_DUMMY_COMPRESS], [m4_bpatsubst(m4_bpatsubst([$1], [__*], [A]), [99*], [0])]) +m4_define([CS_VCHK_DUMMY_TAIL], [CS_VCHK_DUMMY_COMPRESS(m4_translit(CS_VCHK_TAIL([$1]), [|], []))]) + +# **************************************************************** +# ** FlagsOn / FlagsOff ** +# **************************************************************** +m4_define([CS_VCHK_FLAGSON], +[m4_if($#, 0, [], + $1, [], [], + [$1], [group], [CS_VCHK_GROUPINGON[]], + [$1], [opt], [CS_VCHK_OPTON[]])dnl +m4_if($#, 0, [], $1, [], [], [CS_VCHK_FLAGSON(m4_shift($@))])]) + +m4_define([CS_VCHK_FLAGSOFF], +[m4_if($#, 0, [], + $1, [], [], + $1, [group], [CS_VCHK_GROUPINGOFF[]], + [$1], [opt], [CS_VCHK_OPTOFF[]])dnl +m4_if($#, 0, [], $1, [], [], [CS_VCHK_FLAGSOFF(m4_shift($@))])]) + +# **************************************************************** +# ** rexify / sedify ** +# **************************************************************** +m4_define([CS_VCHK_REXIFY], +[m4_pushdef([CS_VCHK_SINGLE], [$1])dnl +CS_VCHK_FLAGSON(m4_shift(m4_shift(m4_shift($@))))dnl +CS_VCHK_REXSEQ([$3], [$2])dnl +CS_VCHK_FLAGSOFF(m4_shift(m4_shift(m4_shift($@))))dnl +m4_popdef([CS_VCHK_SINGLE])]) + +m4_define([CS_VCHK_QUOTESEP], [m4_bpatsubst($1, [[^9_]], [\\\&])]) + +m4_define([CS_VCHK_REXCHAR], [CS_VCHK_REXIFY([CS_VCHK_CHAR], [__*], $@)]) +m4_define([CS_VCHK_REXDIGIT], [CS_VCHK_REXIFY([CS_VCHK_DIGIT], [99*], $@)]) +m4_define([CS_VCHK_SEDIFY], [CS_VCHK_REXDIGIT([CS_VCHK_REXCHAR([CS_VCHK_QUOTESEP([$1])], m4_shift($@))], m4_shift($@))]) +m4_define([CS_VCHK_SEDEXPRALL], [/CS_VCHK_SEDIFY([$1])/!d;s/.*\(CS_VCHK_SEDIFY([$1])\).*/\1/;q]) +m4_define([CS_VCHK_SEDEXPRNTH], [/CS_VCHK_SEDIFY([$1])/!d;s/.*CS_VCHK_SEDIFY([$1],[group]).*/\$2/]) + +# **************************************************************** +# ** Pattern splitting ** +# **************************************************************** +m4_define([CS_VCHK_SPLITSEP], [CS_VCHK_REXIFY([s], [[^9_][^9_]*], $@)]) +m4_define([CS_VCHK_SPLITDIGIT], [CS_VCHK_REXIFY([d], [99*], $@)]) +m4_define([CS_VCHK_SPLITCHAR], [CS_VCHK_REXIFY([c], [__*], $@)]) + +# **************************************************************** +# ** return a list of 's' 'd' 'c' 'e' chars denoting the kind ** +# ** pattern parts: separator, digit, char, end ** +# **************************************************************** +m4_define([CS_VCHK_PATTERNLIST], [m4_pushdef([CS_VCHK_SEQUENCE], [CS_VCHK_SINGLE ])dnl +m4_translit(CS_VCHK_SPLITDIGIT([CS_VCHK_SPLITCHAR([CS_VCHK_SPLITSEP([$1])])]), [ ], m4_if([$2],[],[ ],[$2]))e[]dnl +m4_popdef([CS_VCHK_SEQUENCE])]) + +# **************************************************************** +# ** Build the shell commands we emit to the configure script. ** +# **************************************************************** +m4_define([CS_VCHK_PATCOUNT], [m4_len(m4_bpatsubst(CS_VCHK_PATTERNLIST([$1]), [[^dc]]))]) + +# **************************************************************************************** +# ** CS_VCHK_EXTRACTVERSION(EXTRACT_CALL, MIN_VERSION, PATTERN, PRGPREFIX, COMPARISION) ** +# **************************************************************************************** +m4_define([CS_VCHK_EXTRACTVERSION], +[cs_prog_$4_is_version= +cs_prog_$4_min_version= +cs_prog_$4_is_suffix= +cs_prog_$4_min_suffix= +cs_prog_$4_is_suffix_done= +cs_prog_$4_min_suffix_done= +CS_VCHK_CYCLEOPT([$3], [], +[test -z $cs_prog_$4_is_version && cs_prog_$4_is_version=`$1 | sed 'CS_VCHK_SEDEXPRALL([i])'` +test -n "$cs_prog_$4_is_version" && test -z $cs_prog_$4_is_suffix_done && { cs_prog_$4_is_suffix_done=yes ; cs_prog_$4_is_suffix=j ; } +]) +CS_VCHK_CYCLEOPT([$3], , +[test -z $cs_prog_$4_min_version && cs_prog_$4_min_version=`echo $2 | sed 'CS_VCHK_SEDEXPRALL([i])'` +test -n "$cs_prog_$4_min_version" && test -z $cs_prog_$4_min_suffix_done && { cs_prog_$4_min_suffix_done=yes ; cs_prog_$4_min_suffix=j ; } +]) +CS_VCHK_RUNTH([CS_VCHK_PATCOUNT([$3])], + [cs_prog_$4_is_ver_[]i=`echo ${cs_prog_$4_is_version}${cs_prog_$4_is_suffix} | sed 'CS_VCHK_SEDEXPRNTH([CS_VCHK_RMALL([$3])], [i])'` +]) +CS_VCHK_RUNTH([CS_VCHK_PATCOUNT([$3])], + [cs_prog_$4_min_ver_[]i=`echo $cs_prog_$4_min_version${cs_prog_$4_min_suffix} | sed 'CS_VCHK_SEDEXPRNTH([CS_VCHK_RMALL([$3])], [i])'` +]) +cs_cv_prog_$4_version_ok='' +CS_VCHK_RUNTH([CS_VCHK_PATCOUNT([$3])], +[test -z "$cs_cv_prog_$4_version_ok" && { expr "$cs_prog_$4_is_ver_[]i" "$5" "$cs_prog_$4_min_ver_[]i" >/dev/null || cs_cv_prog_$4_version_ok=no ; } +test -z "$cs_cv_prog_$4_version_ok" && { expr "$cs_prog_$4_min_ver_[]i" "$5" "$cs_prog_$4_is_ver_[]i" >/dev/null || cs_cv_prog_$4_version_ok=yes ; } +]) +AS_IF([test -z "$cs_cv_prog_$4_version_ok"], [cs_cv_prog_$4_version_ok=yes]) +cs_cv_prog_$4_version_ok_annotated="$cs_cv_prog_$4_version_ok" +AS_IF([test -n "$cs_prog_$4_is_version"], + [cs_cv_prog_$4_version_ok_annotated="$cs_cv_prog_$4_version_ok_annotated (version $cs_prog_$4_is_version)"]) +]) + +############################################################################## +# CS_CHECK_PROG_VERSION(PROG, EXTRACT_CALL, VERSION, PATTERN, +# [ACTION-IF-OKAY], [ACTION-IF-NOT-OKAY], [CMP]) +# Check the version of a program PROG. +# Version information is emitted by EXTRACT_CALL (for instance "bison -V"). +# The discovered program version is compared against VERSION. +# The pattern of the version string matches PATTERN +# The extracted version and the supplied version are compared with the CMP +# operator. i.e. EXTRACTED_VERSION CMP SUPPLIED_VERSION +# CMP defaults to >= if not specified. +# ACTION-IF-OKAY is invoked if comparision yields true, otherwise +# ACTION-IF-NOT-OKAY is invoked. +# +# PATTERN literals: 9 .. marks a non empty sequence of digits +# _ .. marks a non empty sequence of characters from [a-zA-Z] +# | .. everything behind is optional +# .. everything else is taken as separator - it is better +# to not try stuff like space, slash or comma. +# +# The test results in cs_cv_prog_PROG_version_ok being either yes or no. +############################################################################## +AC_DEFUN([CS_CHECK_PROG_VERSION], +[AC_CACHE_CHECK([if $1 version m4_default([$7],[>=]) $3], + [AS_TR_SH([cs_cv_prog_$1_version_ok_annotated])], + [CS_VCHK_EXTRACTVERSION([$2], [$3], [$4], AS_TR_SH([$1]), + m4_default([$7],[>=]))]) +AS_IF([test "$AS_TR_SH([cs_cv_prog_$1_version_ok])" = yes], [$5], [$6])]) +# qualify.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_SYMBOL_QUALIFIER(MESSAGE, CACHE-VAR, QUALIFIERS, [SYMBOL], [LANG], +# [ACTION-IF-ACCEPTED], [ACTION-IF-NOT-ACCEPTED]) +# Test if a symbol can be qualified by one of the elements of the +# comma-separated list of QUALIFIERS. Examples of qualifiers include +# __attribute__((deprecated)), __declspec(dllimport), etc. MESSAGE is the +# "checking" message. CACHE-VAR is the variable which receives the +# qualifier which succeeded, or the the literal "no" if none were +# accepted. SYMBOL is the symbol to which the qualifier should be +# applied. If omitted, then SYMBOL defaults to "void f();". LANG is the +# language of the test, typically "C" or "C++". It defaults to "C" if +# omitted. ACTION-IF-ACCEPTED is invoked after CACHE-VAR is set if one of +# the qualifiers is accepted, else ACTION-IF-NOT-ACCEPTED is invoked. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_SYMBOL_QUALIFIER], + [AC_CACHE_CHECK([$1], [$2], + [$2='no' + m4_foreach([cs_symbol_qualifier], [$3], + [AS_IF([test "$$2" = no], + [CS_BUILD_IFELSE( + [AC_LANG_PROGRAM( + [cs_symbol_qualifier m4_default([$4],[void f()]);], + [])], + [], [$5], [$2='cs_symbol_qualifier'], [$2='no'])])])]) + AS_IF([test $$2 != no], [$6], [$7])]) +# split.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_SPLIT(LINE, [OUTPUT-VARIABLES], [DELIMITER], [FILLER]) +# Split LINE into individual tokens. Tokens are delimited by DELIMITER, +# which is the space character if omitted. OUTPUT-VARIABLES is a +# comma-delimited list of shell variables which should receive the +# extracted tokens. If there are too few tokens to fill the output +# variables, then the excess variables will be assigned the empty string. +# If there are too few output variables, then the excess tokens will be +# ignored. If OUTPUT-VARIABLES is omitted, then the split tokens will be +# assigned to the shell meta-variables $1, $2, $3, etc. When +# OUTPUT-VARIABLES is omitted, FILLER is assigned to meta-variables in +# cases where DELIMITER delimits a zero-length token. FILLER defaults +# to "filler". For example, if DELIMITER is "+" and OUTPUT-VARIABLES is +# omitted, given the line "one++three", $1 will be "one", $2 will be +# "filler", and $3 will be "three". +#------------------------------------------------------------------------------ +AC_DEFUN([CS_SPLIT], + [m4_define([cs_split_filler], m4_default([$4],[filler])) + set cs_split_filler `echo "$1" | awk 'BEGIN { FS="m4_default([$3],[ ])" } + { for (i=1; i <= NF; ++i) + { if ($i == "") print "cs_split_filler"; else print $i } }'` + shift + m4_map([_CS_SPLIT], [$2])]) + +AC_DEFUN([_CS_SPLIT], + [AS_IF([test $[@%:@] -eq 0], [$1=''], + [AS_IF([test "$[1]" = cs_split_filler], [$1=''], [$1=$[1]]) + shift])]) +# textcache.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# Text cache facility. These macros provide a way to incrementally store +# arbitrary text in a shell variable, and to write the saved text to a file. +# +# CS_TEXT_CACHE_APPEND(VARIABLE, TEXT) +# Append text to the contents of the named shell variable. If the text +# contains references to shell variables (such as $foo), then those +# references will be expanded. If expansion is not desired, then protect +# the text with AS_ESCAPE(). +# +# CS_TEXT_CACHE_PREPEND(VARIABLE, TEXT) +# Prepend text to the contents of the named shell variable. If the text +# contains references to shell variables (such as $foo), then those +# references will be expanded. If expansion is not desired, then protect +# the text with AS_ESCAPE(). +# +# CS_TEXT_CACHE_OUTPUT(VARIABLE, FILENAME) +# Instruct config.status to write the contents of the named shell +# variable to the given filename. If the file resides in a directory, +# the directory will be created, if necessary. If the output file +# already exists, and if the cached text is identical to the contents of +# the existing file, then the existing file is left alone, thus its time +# stamp remains unmolested. This heuristic may help to minimize rebuilds +# when the file is listed as a dependency in a makefile. +# +# *NOTE* +# There is a bug in Autoconf 2.57 and probably all earlier 2.5x versions +# which results in errors if AC_CONFIG_COMMANDS is invoked for a `tag' +# which represents a file in a directory which does not yet exist. +# Unfortunately, even invoking AS_MKDIR_P in the `cmd' portion of +# AC_CONFIG_COMMANDS does not solve the problem because the generated +# configure script attempts to access information about the directory +# before AS_MKDIR_P has a chance to create it. This forces us to invoke +# AS_MKDIR_P in the third argument to AC_CONFIG_COMMANDS (the +# `init-cmds') rather than the second (the `cmds'). This is undesirable +# because it means that the directory will be created anytime +# config.status is invoked (even for a simple --help), rather than being +# created only when requested to output the text cache. This bug was +# submitted to the Autoconf GNATS database by Eric Sunshine as #228 on +# 27-Dec-2002. It was fixed for Autoconf 2.58 on 26-Sep-2003. The +# official fix makes the assumption that `tag' always represents a file +# (as opposed to some generic target), and creates the file's directory +# is not present. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_TEXT_CACHE_APPEND], [$1="${$1}$2"]) +AC_DEFUN([CS_TEXT_CACHE_PREPEND], [$1="$2${$1}"]) +AC_DEFUN([CS_TEXT_CACHE_OUTPUT], + [AC_CONFIG_COMMANDS([$2], + [echo $ECHO_N "$$1$ECHO_C" > $tmp/tcache + AS_IF([diff $2 $tmp/tcache >/dev/null 2>&1], + [AC_MSG_NOTICE([$2 is unchanged])], + [rm -f $2 + cp $tmp/tcache $2]) + rm -f $tmp/tcache], + [$1='$$1' + cs_dir=`AS_DIRNAME([$2])` + AS_ESCAPE(AS_MKDIR_P([$cs_dir]), [$`\])])]) +# trim.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2003 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_TRIM(STRING) +# Strip leading and trailing spaces from STRING and collapse internal +# runs of multiple spaces to a single space. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_TRIM], [`echo x$1 | sed 's/^x//;s/ */ /g;s/^ //;s/ $//'`]) +# warnings.m4 -*- Autoconf -*- +#============================================================================== +# Copyright (C)2005 by Eric Sunshine +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; if not, write to the Free Software Foundation, +# Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +#============================================================================== +AC_PREREQ([2.56]) + +#------------------------------------------------------------------------------ +# CS_COMPILER_WARNINGS([LANGUAGE], [CACHE-VAR], [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# Check how to enable compilation warnings. If LANGUAGE is not provided, +# then `C' is assumed (other options include `C++'). If CACHE-VAR is not +# provided, then it defaults to the name +# "cs_cv_prog_compiler_enable_warnings". If an option for enabling +# warnings (such as `-Wall') is discovered, then it is assigned to +# CACHE-VAR and ACTION-IF-FOUND is invoked; otherwise the empty string is +# assigned to CACHE-VAR and ACTION-IF-NOT-FOUND is invoked. +# +# IMPLEMENTATION NOTES +# +# On some platforms, it is more appropriate to use -Wmost rather than +# -Wall even if the compiler understands both, thus we attempt -Wmost +# before -Wall. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_COMPILER_WARNINGS], + [CS_CHECK_BUILD_FLAGS( + [how to enable m4_default([$1],[C]) compilation warnings], + [m4_default([$2],[cs_cv_prog_compiler_enable_warnings])], + [CS_CREATE_TUPLE([-Wmost]) CS_CREATE_TUPLE([-Wall])], + [$1], [$3], [$4])]) + + + +#------------------------------------------------------------------------------ +# CS_COMPILER_ERRORS([LANGUAGE], [CACHE-VAR], [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# Check how to promote compilation diganostics from warning to error +# status. If LANGUAGE is not provided, then `C' is assumed (other options +# include `C++'). If CACHE-VAR is not provided, then it defaults to the +# name "cs_cv_prog_compiler_enable_errors". If an option for performing +# this promotion (such as `-Werror') is discovered, then it is assigned +# to CACHE-VAR and ACTION-IF-FOUND is invoked; otherwise the empty string +# is assigned to CACHE-VAR and ACTION-IF-NOT-FOUND is invoked. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_COMPILER_ERRORS], + [CS_CHECK_BUILD_FLAGS( + [how to treat m4_default([$1],[C]) warnings as errors], + [m4_default([$2],[cs_cv_prog_compiler_enable_errors])], + [CS_CREATE_TUPLE([-Werror])], [$1], [$3], [$4])]) + + + +#------------------------------------------------------------------------------ +# CS_COMPILER_IGNORE_UNUSED([LANGUAGE], [CACHE-VAR], [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# Check how to instruct compiler to ignore unused variables and +# arguments. This option may be useful for code generated by tools, such +# as Swig, Bison, and Flex, over which the client has no control, yet +# wishes to compile without excessive diagnostic spew. If LANGUAGE is +# not provided, then `C' is assumed (other options include `C++'). If +# CACHE-VAR is not provided, then it defaults to the name +# "cs_cv_prog_compiler_ignore_unused". If an option (such as +# `-Wno-unused') is discovered, then it is assigned to CACHE-VAR and +# ACTION-IF-FOUND is invoked; otherwise the empty string is assigned to +# CACHE-VAR and ACTION-IF-NOT-FOUND is invoked. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_COMPILER_IGNORE_UNUSED], + [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) unused variable warnings], + [m4_default([$2],[cs_cv_prog_compiler_ignore_unused])], + [CS_CREATE_TUPLE([-Wno-unused])], [$1], [$3], [$4])]) + + + +#------------------------------------------------------------------------------ +# CS_COMPILER_IGNORE_UNINITIALIZED([LANGUAGE], [CACHE-VAR], [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# Check how to instruct compiler to ignore uninitialized variables. This +# option may be useful for code generated by tools, such as Swig, Bison, +# and Flex, over which the client has no control, yet wishes to compile +# without excessive diagnostic spew. If LANGUAGE is not provided, then +# `C' is assumed (other options include `C++'). If CACHE-VAR is not +# provided, then it defaults to the name +# "cs_cv_prog_compiler_ignore_uninitialized". If an option (such as +# `-Wno-uninitialized') is discovered, then it is assigned to CACHE-VAR +# and ACTION-IF-FOUND is invoked; otherwise the empty string is assigned +# to CACHE-VAR and ACTION-IF-NOT-FOUND is invoked. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_COMPILER_IGNORE_UNINITIALIZED], + [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) uninitialized warnings], + [m4_default([$2], + [cs_cv_prog_compiler_ignore_uninitialized_variables])], + [CS_CREATE_TUPLE([-Wno-uninitialized])], [$1], [$3], [$4])]) + + + +#------------------------------------------------------------------------------ +# CS_COMPILER_IGNORE_PRAGMAS([LANGUAGE], [CACHE-VAR], [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# Check how to instruct compiler to ignore unrecognized #pragma +# directives. This option may be useful for code which contains +# unprotected #pragmas which are not understood by all compilers. If +# LANGUAGE is not provided, then `C' is assumed (other options include +# `C++'). If CACHE-VAR is not provided, then it defaults to the name +# "cs_cv_prog_compiler_ignore_unknown_pragmas". If an option (such as +# `-Wno-unknown-pragmas') is discovered, then it is assigned to CACHE-VAR +# and ACTION-IF-FOUND is invoked; otherwise the empty string is assigned +# to CACHE-VAR and ACTION-IF-NOT-FOUND is invoked. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_COMPILER_IGNORE_PRAGMAS], + [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) unknown [#pragma] warnings], + [m4_default([$2],[cs_cv_prog_compiler_ignore_unknown_pragmas])], + [CS_CREATE_TUPLE([-Wno-unknown-pragmas])], [$1], [$3], [$4])]) + + + +#------------------------------------------------------------------------------ +# CS_COMPILER_IGNORE_LONG_DOUBLE([LANGUAGE], [CACHE-VAR], [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# Check how to instruct compiler to suppress warnings about `long double' +# usage. This option may be useful for code generated by tools, such as +# Swig, Bison, and Flex, over which the client has no control, yet wishes +# to compile without excessive diagnostic spew. If LANGUAGE is not +# provided, then `C' is assumed (other options include `C++'). If +# CACHE-VAR is not provided, then it defaults to the name +# "cs_cv_prog_compiler_ignore_long_double". If an option (such as +# `-Wno-long-double') is discovered, then it is assigned to CACHE-VAR and +# ACTION-IF-FOUND is invoked; otherwise the empty string is assigned to +# CACHE-VAR and ACTION-IF-NOT-FOUND is invoked. +#------------------------------------------------------------------------------ +AC_DEFUN([CS_COMPILER_IGNORE_LONG_DOUBLE], + [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) `long double' warnings], + [m4_default([$2],[cs_cv_prog_compiler_ignore_long_double])], + [CS_CREATE_TUPLE([-Wno-long-double])], [$1], [$3], [$4])]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..d03536e --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,9414 @@ +# generated automatically by aclocal 1.11 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3293 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4]) +m4_define([LT_PACKAGE_REVISION], [1.3293]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4' +macro_revision='1.3293' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..35623fa --- /dev/null +++ b/autogen.sh @@ -0,0 +1,61 @@ +#! /bin/sh + +if [ "$USER" = "root" ]; then + echo "*** You cannot do this as "$USER" please use a normal user account." + exit 1 +fi +if test ! -f configure.ac ; then + echo "*** Please invoke this script from directory containing configure.ac." + exit 1 +fi + +echo "running aclocal" +aclocal +rc=$? + +if test $rc -eq 0; then + echo "running libtool" + libtoolize --force --automake --copy + rc=$? +else + echo "An error occured, autogen.sh stopping." + exit $rc +fi + +if test $rc -eq 0; then + echo "libtool worked." +else + echo "libtool not found. trying glibtool." + glibtoolize --force --automake --copy + rc=$? +fi + +if test $rc -eq 0; then + echo "running automake" + automake --add-missing --copy + rc=$? +else + echo "An error occured, autogen.sh stopping." + exit $rc +fi + +if test $rc -eq 0; then + echo "running autoheader" + autoheader + rc=$? +else + echo "An error occured, autogen.sh stopping." + exit $rc +fi + +if test $rc -eq 0; then + echo "running autoconf" + autoconf + rc=$? +else + echo "An error occured, autogen.sh stopping." + exit $rc +fi + +echo "autogen.sh complete" +exit $rc diff --git a/autom4te.cache/output.0 b/autom4te.cache/output.0 new file mode 100644 index 0000000..69091a4 --- /dev/null +++ b/autom4te.cache/output.0 @@ -0,0 +1,18219 @@ +@%:@! /bin/sh +@%:@ Guess values for system-dependent variables and create Makefiles. +@%:@ Generated by GNU Autoconf 2.68 for bullet 2.81. +@%:@ +@%:@ Report bugs to . +@%:@ +@%:@ +@%:@ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +@%:@ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +@%:@ Foundation, Inc. +@%:@ +@%:@ +@%:@ This configure script is free software; the Free Software Foundation +@%:@ gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in @%:@( + *posix*) : + set -o posix ;; @%:@( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in @%:@( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in @%:@(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in @%:@( + *posix*) : + set -o posix ;; @%:@( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in @%:@( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in @%:@ (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: bullet@erwincoumans.com about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +@%:@ as_fn_unset VAR +@%:@ --------------- +@%:@ Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +@%:@ as_fn_set_status STATUS +@%:@ ----------------------- +@%:@ Set @S|@? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} @%:@ as_fn_set_status + +@%:@ as_fn_exit STATUS +@%:@ ----------------- +@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} @%:@ as_fn_exit +@%:@ as_fn_append VAR VALUE +@%:@ ---------------------- +@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take +@%:@ advantage of any shell optimizations that allow amortized linear growth over +@%:@ repeated appends, instead of the typical quadratic growth present in naive +@%:@ implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +@%:@ as_fn_arith ARG... +@%:@ ------------------ +@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the +@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments +@%:@ must be portable across @S|@(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD] +@%:@ ---------------------------------------- +@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are +@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the +@%:@ script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} @%:@ as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in @%:@((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p' +elif mkdirs . 2>/dev/null; then + as_mkdir_p='mkdirs' +else + as_mkdir_p='' +fi +test -d ./-p && rmdir ./-p + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in @%:@( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in @%:@(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIB@&t@OBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='bullet' +PACKAGE_TARNAME='bullet' +PACKAGE_VERSION='2.81' +PACKAGE_STRING='bullet 2.81' +PACKAGE_BUGREPORT='bullet@erwincoumans.com' +PACKAGE_URL='' + +ac_unique_file="configure.ac" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIB@&t@OBJS +GL_LIBS +CONDITIONAL_BUILD_DEMOS_FALSE +CONDITIONAL_BUILD_DEMOS_TRUE +CONDITIONAL_BUILD_MULTITHREADED_FALSE +CONDITIONAL_BUILD_MULTITHREADED_TRUE +opengl_LIBS +CXXCPP +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +LIBTOOL +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_multithreaded +enable_demos +enable_debug +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures bullet 2.81 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + @<:@@S|@ac_default_prefix@:>@ + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + @<:@PREFIX@:>@ + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root @<:@DATAROOTDIR/doc/bullet@:>@ + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of bullet 2.81:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared@<:@=PKGS@:>@ build shared libraries @<:@default=yes@:>@ + --enable-static@<:@=PKGS@:>@ build static libraries @<:@default=yes@:>@ + --enable-fast-install@<:@=PKGS@:>@ + optimize for fast installation @<:@default=yes@:>@ + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-multithreaded build BulletMultiThreaded (default NO) + --disable-demos disable Bullet demos + --enable-debug build with debugging information (default NO) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects @<:@default=use + both@:>@ + --with-gnu-ld assume the C compiler uses GNU ld @<:@default=no@:>@ + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +bullet configure 2.81 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +@%:@ ac_fn_c_try_compile LINENO +@%:@ -------------------------- +@%:@ Try to compile conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_compile + +@%:@ ac_fn_cxx_try_compile LINENO +@%:@ ---------------------------- +@%:@ Try to compile conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_cxx_try_compile + +@%:@ ac_fn_c_try_link LINENO +@%:@ ----------------------- +@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_link + +@%:@ ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +@%:@ ------------------------------------------------------- +@%:@ Tests whether HEADER exists and can be compiled using the include files in +@%:@ INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +@%:@include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} @%:@ ac_fn_c_check_header_compile + +@%:@ ac_fn_c_try_cpp LINENO +@%:@ ---------------------- +@%:@ Try to preprocess conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_cpp + +@%:@ ac_fn_c_try_run LINENO +@%:@ ---------------------- +@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded. Assumes +@%:@ that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_run + +@%:@ ac_fn_c_check_func LINENO FUNC VAR +@%:@ ---------------------------------- +@%:@ Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} @%:@ ac_fn_c_check_func + +@%:@ ac_fn_cxx_try_cpp LINENO +@%:@ ------------------------ +@%:@ Try to preprocess conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_cxx_try_cpp + +@%:@ ac_fn_cxx_try_link LINENO +@%:@ ------------------------- +@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_cxx_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by bullet $as_me 2.81, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in @%:@(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in @%:@(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='bullet' + VERSION='2.81' + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +@%:@ Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $@%:@ != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "@%:@define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4' +macro_revision='1.3293' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +@%:@ Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +@%:@ Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +@%:@ Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "@%:@define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +@%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +@%:@define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + @%:@ Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + @%:@ Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +@%:@ Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + @%:@ Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +@%:@define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic@&t@ -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic@&t@ -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +@%:@ Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX@&t@ -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX@&t@ -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +case "$host" in + *-*-mingw*|*-*-cygwin*) + +$as_echo "@%:@define PLATFORM_WIN32 1" >>confdefs.h + + opengl_LIBS="-lunsupported_platform" + PLATFORM_STRING="Win32" + ;; + *-*-linux*) + +$as_echo "@%:@define PLATFORM_LINUX 1" >>confdefs.h + + opengl_LIBS="-lGL -lGLU -lglut" + PLATFORM_STRING="Linux" + ;; + *-*-darwin*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Hello" >&5 +$as_echo "$as_me: WARNING: Hello" >&2;} + +$as_echo "@%:@define PLATFORM_APPLE 1" >>confdefs.h + + opengl_LIBS="-framework AGL -framework OpenGL -framework GLUT" + PLATFORM_STRING="Apple" + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Please add $host to configure.ac checks!" >&5 +$as_echo "$as_me: WARNING: *** Please add $host to configure.ac checks!" >&2;} + ;; +esac + + +case "$host" in + i?86-* | k?-* | athlon-* | pentium*-) + +$as_echo "@%:@define ARCH_X86 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="X86" + ;; + x86_64-*) + +$as_echo "@%:@define ARCH_X86_64 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="-DUSE_ADDR64" + ARCH_STRING="X86-64" + ;; + ppc-* | powerpc-*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: HI THERE!" >&5 +$as_echo "$as_me: WARNING: HI THERE!" >&2;} + +$as_echo "@%:@define ARCH_PPC 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="PowerPC" + ;; + *) + as_fn_error $? "Unknown Architecture" "$LINENO" 5 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "@%:@define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "@%:@define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + + +#---------------------------------------------------------------------------- +# Setup for the configuration header. +#---------------------------------------------------------------------------- +ac_config_headers="$ac_config_headers config.h" + +#---------------------------------------------------------------------------- +# Package configuration switches. +#---------------------------------------------------------------------------- +@%:@ Check whether --enable-multithreaded was given. +if test "${enable_multithreaded+set}" = set; then : + enableval=$enable_multithreaded; disable_multithreaded=no +else + disable_multithreaded=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking BulletMultiThreaded" >&5 +$as_echo_n "checking BulletMultiThreaded... " >&6; } +if test "$disable_multithreaded" = yes; then : + build_multithreaded=no +else + build_multithreaded=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_multithreaded" >&5 +$as_echo "$build_multithreaded" >&6; } + if test "$build_multithreaded" = yes; then + CONDITIONAL_BUILD_MULTITHREADED_TRUE= + CONDITIONAL_BUILD_MULTITHREADED_FALSE='#' +else + CONDITIONAL_BUILD_MULTITHREADED_TRUE='#' + CONDITIONAL_BUILD_MULTITHREADED_FALSE= +fi + + +@%:@ Check whether --enable-demos was given. +if test "${enable_demos+set}" = set; then : + enableval=$enable_demos; +else + enable_demos=yes +fi + + if false; then + CONDITIONAL_BUILD_DEMOS_TRUE= + CONDITIONAL_BUILD_DEMOS_FALSE='#' +else + CONDITIONAL_BUILD_DEMOS_TRUE='#' + CONDITIONAL_BUILD_DEMOS_FALSE= +fi + + + + +case "$host" in + *-*-darwin*) + +$as_echo "@%:@define HAVE_APPLE_OPENGL_FRAMEWORK 1" >>confdefs.h + + GL_LIBS="-framework GLUT -framework OpenGL -framework Carbon -framework AGL" + have_glut=yes + have_glu=yes + have_gl=yes + ;; + *) + have_gl_headers=yes + for ac_header in GL/gl.h GL/glu.h GL/glext.h GL/glut.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef WIN32 + #include + #endif + #if HAVE_GL_GL_H + #include + #endif + #if HAVE_GL_GLU_H + #include + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +@%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + have_gl_headers=no +fi + +done + + have_gl=no + have_glu=no + have_glut=no + TEMP_LDFLAGS="$LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGL" >&5 +$as_echo_n "checking for main in -lGL... " >&6; } +if ${ac_cv_lib_GL_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_main=yes +else + ac_cv_lib_GL_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_main" >&5 +$as_echo "$ac_cv_lib_GL_main" >&6; } +if test "x$ac_cv_lib_GL_main" = xyes; then : + GL_LIBS="-lGL"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGLU" >&5 +$as_echo_n "checking for main in -lGLU... " >&6; } +if ${ac_cv_lib_GLU_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLU -lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GLU_main=yes +else + ac_cv_lib_GLU_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLU_main" >&5 +$as_echo "$ac_cv_lib_GLU_main" >&6; } +if test "x$ac_cv_lib_GLU_main" = xyes; then : + GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGLUT" >&5 +$as_echo_n "checking for main in -lGLUT... " >&6; } +if ${ac_cv_lib_GLUT_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLUT -lGLUT $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GLUT_main=yes +else + ac_cv_lib_GLUT_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLUT_main" >&5 +$as_echo "$ac_cv_lib_GLUT_main" >&6; } +if test "x$ac_cv_lib_GLUT_main" = xyes; then : + GL_LIBS="-lGLUT -LGLU $GL_LIBS"; have_glut=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 +$as_echo_n "checking for main in -lopengl32... " >&6; } +if ${ac_cv_lib_opengl32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_opengl32_main=yes +else + ac_cv_lib_opengl32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opengl32_main" >&5 +$as_echo "$ac_cv_lib_opengl32_main" >&6; } +if test "x$ac_cv_lib_opengl32_main" = xyes; then : + GL_LIBS="-lopengl32"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lglu32" >&5 +$as_echo_n "checking for main in -lglu32... " >&6; } +if ${ac_cv_lib_glu32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lglu32 -lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_glu32_main=yes +else + ac_cv_lib_glu32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glu32_main" >&5 +$as_echo "$ac_cv_lib_glu32_main" >&6; } +if test "x$ac_cv_lib_glu32_main" = xyes; then : + GL_LIBS="-lglu32 $GL_LIBS"; have_glu=yes +fi + + LDFLAGS="$TEMP_LDFLAGS" + if test $have_gl = no -o $have_glu = no -o $have_gl_headers = no; then + if test x$enable_demos = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See \`config.log' for details." >&5 +$as_echo "$as_me: WARNING: Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See \`config.log' for details." >&2;} + fi + enable_demos=no + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found OpenGL" >&5 +$as_echo "$as_me: Found OpenGL" >&6;} + fi + ;; +esac + + + + + + +if test "x$enable_demos" != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Building Bullet demos" >&5 +$as_echo "$as_me: Building Bullet demos" >&6;} + if true; then + CONDITIONAL_BUILD_DEMOS_TRUE= + CONDITIONAL_BUILD_DEMOS_FALSE='#' +else + CONDITIONAL_BUILD_DEMOS_TRUE='#' + CONDITIONAL_BUILD_DEMOS_FALSE= +fi + +fi + + + +@%:@ Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; +else + enable_debug=no +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build mode" >&5 +$as_echo_n "checking build mode... " >&6; } +if test $enable_debug = yes; then : + build_mode=debug +else + build_mode=optimize +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_mode" >&5 +$as_echo "$build_mode" >&6; } + + + +CFLAGS="$ARCH_SPECIFIC_CFLAGS $CFLAGS" +CXXFLAGS="$ARCH_SPECIFIC_CFLAGS $CXXFLAGS $CFLAGS" +#---------------------------------------------------------------------------- +# Emit generated files. +#---------------------------------------------------------------------------- +ac_config_files="$ac_config_files bullet.pc Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/OpenGL/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIB@&t@OBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIB@&t@OBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${CONDITIONAL_BUILD_MULTITHREADED_TRUE}" && test -z "${CONDITIONAL_BUILD_MULTITHREADED_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_MULTITHREADED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONDITIONAL_BUILD_DEMOS_TRUE}" && test -z "${CONDITIONAL_BUILD_DEMOS_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONDITIONAL_BUILD_DEMOS_TRUE}" && test -z "${CONDITIONAL_BUILD_DEMOS_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in @%:@( + *posix*) : + set -o posix ;; @%:@( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in @%:@( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in @%:@(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD] +@%:@ ---------------------------------------- +@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are +@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the +@%:@ script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} @%:@ as_fn_error + + +@%:@ as_fn_set_status STATUS +@%:@ ----------------------- +@%:@ Set @S|@? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} @%:@ as_fn_set_status + +@%:@ as_fn_exit STATUS +@%:@ ----------------- +@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} @%:@ as_fn_exit + +@%:@ as_fn_unset VAR +@%:@ --------------- +@%:@ Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +@%:@ as_fn_append VAR VALUE +@%:@ ---------------------- +@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take +@%:@ advantage of any shell optimizations that allow amortized linear growth over +@%:@ repeated appends, instead of the typical quadratic growth present in naive +@%:@ implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +@%:@ as_fn_arith ARG... +@%:@ ------------------ +@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the +@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments +@%:@ must be portable across @S|@(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in @%:@((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p' +elif mkdirs . 2>/dev/null; then + as_mkdir_p='mkdirs' +else + as_mkdir_p='' +fi +test -d ./-p && rmdir ./-p + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in @%:@( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in @%:@(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by bullet $as_me 2.81, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +bullet config.status 2.81 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX +@%:@@%:@ Running $as_me. @%:@@%:@ +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "bullet.pc") CONFIG_FILES="$CONFIG_FILES bullet.pc" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "Demos/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/Makefile" ;; + "Demos/SoftDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/SoftDemo/Makefile" ;; + "Demos/AllBulletDemos/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/AllBulletDemos/Makefile" ;; + "Demos/MultiThreadedDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/MultiThreadedDemo/Makefile" ;; + "Demos/OpenGL/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/OpenGL/Makefile" ;; + "Demos/BasicDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/BasicDemo/Makefile" ;; + "Demos/CcdPhysicsDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/CcdPhysicsDemo/Makefile" ;; + "Demos/VehicleDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/VehicleDemo/Makefile" ;; + "Demos/TerrainDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/TerrainDemo/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "Extras/Makefile") CONFIG_FILES="$CONFIG_FILES Extras/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { if test -n "$as_mkdir_p"; then + $as_mkdir_p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || as_fn_error $? "cannot create directory \"$ac_dir\"" "$LINENO" 5; } + + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { if test -n "$as_mkdir_p"; then + $as_mkdir_p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || as_fn_error $? "cannot create directory $dirpart/$fdir" "$LINENO" 5; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: + +Please type 'make' to build Bullet +" >&5 +$as_echo "$as_me: + +Please type 'make' to build Bullet +" >&6;} diff --git a/autom4te.cache/output.1 b/autom4te.cache/output.1 new file mode 100644 index 0000000..eba16fc --- /dev/null +++ b/autom4te.cache/output.1 @@ -0,0 +1,18215 @@ +@%:@! /bin/sh +@%:@ Guess values for system-dependent variables and create Makefiles. +@%:@ Generated by GNU Autoconf 2.68 for bullet 2.81. +@%:@ +@%:@ Report bugs to . +@%:@ +@%:@ +@%:@ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +@%:@ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +@%:@ Foundation, Inc. +@%:@ +@%:@ +@%:@ This configure script is free software; the Free Software Foundation +@%:@ gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in @%:@( + *posix*) : + set -o posix ;; @%:@( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in @%:@( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in @%:@(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in @%:@( + *posix*) : + set -o posix ;; @%:@( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in @%:@( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in @%:@ (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: bullet@erwincoumans.com about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +@%:@ as_fn_unset VAR +@%:@ --------------- +@%:@ Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +@%:@ as_fn_set_status STATUS +@%:@ ----------------------- +@%:@ Set @S|@? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} @%:@ as_fn_set_status + +@%:@ as_fn_exit STATUS +@%:@ ----------------- +@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} @%:@ as_fn_exit +@%:@ as_fn_append VAR VALUE +@%:@ ---------------------- +@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take +@%:@ advantage of any shell optimizations that allow amortized linear growth over +@%:@ repeated appends, instead of the typical quadratic growth present in naive +@%:@ implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +@%:@ as_fn_arith ARG... +@%:@ ------------------ +@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the +@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments +@%:@ must be portable across @S|@(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD] +@%:@ ---------------------------------------- +@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are +@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the +@%:@ script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} @%:@ as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in @%:@((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p' +elif mkdirs . 2>/dev/null; then + as_mkdir_p='mkdirs' +else + as_mkdir_p='' +fi +test -d ./-p && rmdir ./-p + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in @%:@( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in @%:@(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIB@&t@OBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='bullet' +PACKAGE_TARNAME='bullet' +PACKAGE_VERSION='2.81' +PACKAGE_STRING='bullet 2.81' +PACKAGE_BUGREPORT='bullet@erwincoumans.com' +PACKAGE_URL='' + +ac_unique_file="configure.ac" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIB@&t@OBJS +GL_LIBS +CONDITIONAL_BUILD_DEMOS_FALSE +CONDITIONAL_BUILD_DEMOS_TRUE +CONDITIONAL_BUILD_MULTITHREADED_FALSE +CONDITIONAL_BUILD_MULTITHREADED_TRUE +opengl_LIBS +CXXCPP +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +LIBTOOL +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_multithreaded +enable_demos +enable_debug +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures bullet 2.81 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + @<:@@S|@ac_default_prefix@:>@ + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + @<:@PREFIX@:>@ + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root @<:@DATAROOTDIR/doc/bullet@:>@ + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of bullet 2.81:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared@<:@=PKGS@:>@ build shared libraries @<:@default=yes@:>@ + --enable-static@<:@=PKGS@:>@ build static libraries @<:@default=yes@:>@ + --enable-fast-install@<:@=PKGS@:>@ + optimize for fast installation @<:@default=yes@:>@ + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-multithreaded build BulletMultiThreaded (default NO) + --disable-demos disable Bullet demos + --enable-debug build with debugging information (default NO) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects @<:@default=use + both@:>@ + --with-gnu-ld assume the C compiler uses GNU ld @<:@default=no@:>@ + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +bullet configure 2.81 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +@%:@ ac_fn_c_try_compile LINENO +@%:@ -------------------------- +@%:@ Try to compile conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_compile + +@%:@ ac_fn_cxx_try_compile LINENO +@%:@ ---------------------------- +@%:@ Try to compile conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_cxx_try_compile + +@%:@ ac_fn_c_try_link LINENO +@%:@ ----------------------- +@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_link + +@%:@ ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +@%:@ ------------------------------------------------------- +@%:@ Tests whether HEADER exists and can be compiled using the include files in +@%:@ INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +@%:@include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} @%:@ ac_fn_c_check_header_compile + +@%:@ ac_fn_c_try_cpp LINENO +@%:@ ---------------------- +@%:@ Try to preprocess conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_cpp + +@%:@ ac_fn_c_try_run LINENO +@%:@ ---------------------- +@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded. Assumes +@%:@ that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_c_try_run + +@%:@ ac_fn_c_check_func LINENO FUNC VAR +@%:@ ---------------------------------- +@%:@ Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} @%:@ ac_fn_c_check_func + +@%:@ ac_fn_cxx_try_cpp LINENO +@%:@ ------------------------ +@%:@ Try to preprocess conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_cxx_try_cpp + +@%:@ ac_fn_cxx_try_link LINENO +@%:@ ------------------------- +@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} @%:@ ac_fn_cxx_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by bullet $as_me 2.81, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in @%:@(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in @%:@(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='bullet' + VERSION='2.81' + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +@%:@ Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $@%:@ != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "@%:@define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4' +macro_revision='1.3293' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +@%:@ Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +@%:@ Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +@%:@ Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "@%:@define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +@%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +@%:@define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + @%:@ Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + @%:@ Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +@%:@ Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + @%:@ Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +@%:@define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic@&t@ -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic@&t@ -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +@%:@include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +@%:@ Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX@&t@ -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX@&t@ -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +case "$host" in + *-*-mingw*|*-*-cygwin*) + +$as_echo "@%:@define PLATFORM_WIN32 1" >>confdefs.h + + opengl_LIBS="-lunsupported_platform" + PLATFORM_STRING="Win32" + ;; + *-*-linux*) + +$as_echo "@%:@define PLATFORM_LINUX 1" >>confdefs.h + + opengl_LIBS="-lGL -lGLU -lglut" + PLATFORM_STRING="Linux" + ;; + *-*-darwin*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Hello" >&5 +$as_echo "$as_me: WARNING: Hello" >&2;} + +$as_echo "@%:@define PLATFORM_APPLE 1" >>confdefs.h + + opengl_LIBS="-framework AGL -framework OpenGL -framework GLUT" + PLATFORM_STRING="Apple" + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Please add $host to configure.ac checks!" >&5 +$as_echo "$as_me: WARNING: *** Please add $host to configure.ac checks!" >&2;} + ;; +esac + + +case "$host" in + i?86-* | k?-* | athlon-* | pentium*-) + +$as_echo "@%:@define ARCH_X86 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="X86" + ;; + x86_64-*) + +$as_echo "@%:@define ARCH_X86_64 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="-DUSE_ADDR64" + ARCH_STRING="X86-64" + ;; + ppc-* | powerpc-*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: HI THERE!" >&5 +$as_echo "$as_me: WARNING: HI THERE!" >&2;} + +$as_echo "@%:@define ARCH_PPC 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="PowerPC" + ;; + *) + as_fn_error $? "Unknown Architecture" "$LINENO" 5 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "@%:@define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "@%:@define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + + +#---------------------------------------------------------------------------- +# Setup for the configuration header. +#---------------------------------------------------------------------------- +ac_config_headers="$ac_config_headers config.h" + +#---------------------------------------------------------------------------- +# Package configuration switches. +#---------------------------------------------------------------------------- +@%:@ Check whether --enable-multithreaded was given. +if test "${enable_multithreaded+set}" = set; then : + enableval=$enable_multithreaded; disable_multithreaded=no +else + disable_multithreaded=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking BulletMultiThreaded" >&5 +$as_echo_n "checking BulletMultiThreaded... " >&6; } +if test "$disable_multithreaded" = yes; then : + build_multithreaded=no +else + build_multithreaded=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_multithreaded" >&5 +$as_echo "$build_multithreaded" >&6; } + if test "$build_multithreaded" = yes; then + CONDITIONAL_BUILD_MULTITHREADED_TRUE= + CONDITIONAL_BUILD_MULTITHREADED_FALSE='#' +else + CONDITIONAL_BUILD_MULTITHREADED_TRUE='#' + CONDITIONAL_BUILD_MULTITHREADED_FALSE= +fi + + +@%:@ Check whether --enable-demos was given. +if test "${enable_demos+set}" = set; then : + enableval=$enable_demos; +else + enable_demos=yes +fi + + if false; then + CONDITIONAL_BUILD_DEMOS_TRUE= + CONDITIONAL_BUILD_DEMOS_FALSE='#' +else + CONDITIONAL_BUILD_DEMOS_TRUE='#' + CONDITIONAL_BUILD_DEMOS_FALSE= +fi + + + + +case "$host" in + *-*-darwin*) + +$as_echo "@%:@define HAVE_APPLE_OPENGL_FRAMEWORK 1" >>confdefs.h + + GL_LIBS="-framework GLUT -framework OpenGL -framework Carbon -framework AGL" + have_glut=yes + have_glu=yes + have_gl=yes + ;; + *) + have_gl_headers=yes + for ac_header in GL/gl.h GL/glu.h GL/glext.h GL/glut.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef WIN32 + #include + #endif + #if HAVE_GL_GL_H + #include + #endif + #if HAVE_GL_GLU_H + #include + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +@%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + have_gl_headers=no +fi + +done + + have_gl=no + have_glu=no + have_glut=no + TEMP_LDFLAGS="$LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGL" >&5 +$as_echo_n "checking for main in -lGL... " >&6; } +if ${ac_cv_lib_GL_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_main=yes +else + ac_cv_lib_GL_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_main" >&5 +$as_echo "$ac_cv_lib_GL_main" >&6; } +if test "x$ac_cv_lib_GL_main" = xyes; then : + GL_LIBS="-lGL"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGLU" >&5 +$as_echo_n "checking for main in -lGLU... " >&6; } +if ${ac_cv_lib_GLU_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLU -lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GLU_main=yes +else + ac_cv_lib_GLU_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLU_main" >&5 +$as_echo "$ac_cv_lib_GLU_main" >&6; } +if test "x$ac_cv_lib_GLU_main" = xyes; then : + GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGLUT" >&5 +$as_echo_n "checking for main in -lGLUT... " >&6; } +if ${ac_cv_lib_GLUT_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLUT -lGLUT $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GLUT_main=yes +else + ac_cv_lib_GLUT_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLUT_main" >&5 +$as_echo "$ac_cv_lib_GLUT_main" >&6; } +if test "x$ac_cv_lib_GLUT_main" = xyes; then : + GL_LIBS="-lGLUT -LGLU $GL_LIBS"; have_glut=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 +$as_echo_n "checking for main in -lopengl32... " >&6; } +if ${ac_cv_lib_opengl32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_opengl32_main=yes +else + ac_cv_lib_opengl32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opengl32_main" >&5 +$as_echo "$ac_cv_lib_opengl32_main" >&6; } +if test "x$ac_cv_lib_opengl32_main" = xyes; then : + GL_LIBS="-lopengl32"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lglu32" >&5 +$as_echo_n "checking for main in -lglu32... " >&6; } +if ${ac_cv_lib_glu32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lglu32 -lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_glu32_main=yes +else + ac_cv_lib_glu32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glu32_main" >&5 +$as_echo "$ac_cv_lib_glu32_main" >&6; } +if test "x$ac_cv_lib_glu32_main" = xyes; then : + GL_LIBS="-lglu32 $GL_LIBS"; have_glu=yes +fi + + LDFLAGS="$TEMP_LDFLAGS" + if test $have_gl = no -o $have_glu = no -o $have_gl_headers = no; then + if test x$enable_demos = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See \`config.log' for details." >&5 +$as_echo "$as_me: WARNING: Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See \`config.log' for details." >&2;} + fi + enable_demos=no + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found OpenGL" >&5 +$as_echo "$as_me: Found OpenGL" >&6;} + fi + ;; +esac + + + + + + +if test "x$enable_demos" != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Building Bullet demos" >&5 +$as_echo "$as_me: Building Bullet demos" >&6;} + if true; then + CONDITIONAL_BUILD_DEMOS_TRUE= + CONDITIONAL_BUILD_DEMOS_FALSE='#' +else + CONDITIONAL_BUILD_DEMOS_TRUE='#' + CONDITIONAL_BUILD_DEMOS_FALSE= +fi + +fi + + + +@%:@ Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; +else + enable_debug=no +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build mode" >&5 +$as_echo_n "checking build mode... " >&6; } +if test $enable_debug = yes; then : + build_mode=debug +else + build_mode=optimize +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_mode" >&5 +$as_echo "$build_mode" >&6; } + + + +CFLAGS="$ARCH_SPECIFIC_CFLAGS $CFLAGS" +CXXFLAGS="$ARCH_SPECIFIC_CFLAGS $CXXFLAGS $CFLAGS" +#---------------------------------------------------------------------------- +# Emit generated files. +#---------------------------------------------------------------------------- +ac_config_files="$ac_config_files bullet.pc Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/OpenGL/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIB@&t@OBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIB@&t@OBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${CONDITIONAL_BUILD_MULTITHREADED_TRUE}" && test -z "${CONDITIONAL_BUILD_MULTITHREADED_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_MULTITHREADED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONDITIONAL_BUILD_DEMOS_TRUE}" && test -z "${CONDITIONAL_BUILD_DEMOS_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONDITIONAL_BUILD_DEMOS_TRUE}" && test -z "${CONDITIONAL_BUILD_DEMOS_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in @%:@( + *posix*) : + set -o posix ;; @%:@( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in @%:@( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in @%:@(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD] +@%:@ ---------------------------------------- +@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are +@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the +@%:@ script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} @%:@ as_fn_error + + +@%:@ as_fn_set_status STATUS +@%:@ ----------------------- +@%:@ Set @S|@? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} @%:@ as_fn_set_status + +@%:@ as_fn_exit STATUS +@%:@ ----------------- +@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} @%:@ as_fn_exit + +@%:@ as_fn_unset VAR +@%:@ --------------- +@%:@ Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +@%:@ as_fn_append VAR VALUE +@%:@ ---------------------- +@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take +@%:@ advantage of any shell optimizations that allow amortized linear growth over +@%:@ repeated appends, instead of the typical quadratic growth present in naive +@%:@ implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +@%:@ as_fn_arith ARG... +@%:@ ------------------ +@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the +@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments +@%:@ must be portable across @S|@(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in @%:@((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p' +elif mkdirs . 2>/dev/null; then + as_mkdir_p='mkdirs' +else + as_mkdir_p='' +fi +test -d ./-p && rmdir ./-p + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in @%:@( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in @%:@(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by bullet $as_me 2.81, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +bullet config.status 2.81 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX +@%:@@%:@ Running $as_me. @%:@@%:@ +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "bullet.pc") CONFIG_FILES="$CONFIG_FILES bullet.pc" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "Demos/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/Makefile" ;; + "Demos/SoftDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/SoftDemo/Makefile" ;; + "Demos/AllBulletDemos/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/AllBulletDemos/Makefile" ;; + "Demos/MultiThreadedDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/MultiThreadedDemo/Makefile" ;; + "Demos/OpenGL/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/OpenGL/Makefile" ;; + "Demos/BasicDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/BasicDemo/Makefile" ;; + "Demos/CcdPhysicsDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/CcdPhysicsDemo/Makefile" ;; + "Demos/VehicleDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/VehicleDemo/Makefile" ;; + "Demos/TerrainDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/TerrainDemo/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "Extras/Makefile") CONFIG_FILES="$CONFIG_FILES Extras/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { if test -n "$as_mkdir_p"; then + $as_mkdir_p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || as_fn_error $? "cannot create directory \"$ac_dir\"" "$LINENO" 5; } + + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { if test -n "$as_mkdir_p"; then + $as_mkdir_p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || as_fn_error $? "cannot create directory $dirpart/$fdir" "$LINENO" 5; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: + +Please type 'make' to build Bullet +" >&5 +$as_echo "$as_me: + +Please type 'make' to build Bullet +" >&6;} diff --git a/autom4te.cache/requests b/autom4te.cache/requests new file mode 100644 index 0000000..4d25fea --- /dev/null +++ b/autom4te.cache/requests @@ -0,0 +1,393 @@ +# This file was generated. +# It contains the lists of macros which have been traced. +# It can be safely removed. + +@request = ( + bless( [ + '0', + 1, + [ + '/usr/local/share/autoconf' + ], + [ + '/usr/local/share/autoconf/autoconf/autoconf.m4f', + '/usr/local/share/aclocal/argz.m4', + '/usr/local/share/aclocal/libtool.m4', + '/usr/local/share/aclocal/ltdl.m4', + '/usr/local/share/aclocal/ltoptions.m4', + '/usr/local/share/aclocal/ltsugar.m4', + '/usr/local/share/aclocal/ltversion.m4', + '/usr/local/share/aclocal/lt~obsolete.m4', + '/usr/local/share/aclocal-1.11/amversion.m4', + '/usr/local/share/aclocal-1.11/auxdir.m4', + '/usr/local/share/aclocal-1.11/cond.m4', + '/usr/local/share/aclocal-1.11/depend.m4', + '/usr/local/share/aclocal-1.11/depout.m4', + '/usr/local/share/aclocal-1.11/init.m4', + '/usr/local/share/aclocal-1.11/install-sh.m4', + '/usr/local/share/aclocal-1.11/lead-dot.m4', + '/usr/local/share/aclocal-1.11/make.m4', + '/usr/local/share/aclocal-1.11/minuso.m4', + '/usr/local/share/aclocal-1.11/missing.m4', + '/usr/local/share/aclocal-1.11/mkdirp.m4', + '/usr/local/share/aclocal-1.11/options.m4', + '/usr/local/share/aclocal-1.11/runlog.m4', + '/usr/local/share/aclocal-1.11/sanity.m4', + '/usr/local/share/aclocal-1.11/silent.m4', + '/usr/local/share/aclocal-1.11/strip.m4', + '/usr/local/share/aclocal-1.11/substnot.m4', + '/usr/local/share/aclocal-1.11/tar.m4', + 'acinclude.m4', + 'configure.ac' + ], + { + 'AM_ENABLE_STATIC' => 1, + 'CS_META_INFO_EMBED' => 1, + 'AC_LIBTOOL_LANG_RC_CONFIG' => 1, + 'CS_LIBTOOL_GNU_IFELSE' => 1, + 'AC_PROG_LIBTOOL' => 1, + '_LT_AC_LANG_CXX_CONFIG' => 1, + 'AM_SUBST_NOTMAKE' => 1, + 'CS_PATH_NORMALIZE' => 1, + 'CS_EMIT_BUILD_FLAGS' => 1, + 'CS_TRIM' => 1, + 'CS_COMPILER_IGNORE_UNINITIALIZED' => 1, + '_m4_warn' => 1, + 'CS_TEXT_CACHE_PREPEND' => 1, + 'LTOBSOLETE_VERSION' => 1, + 'AM_SANITY_CHECK' => 1, + 'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1, + 'LTSUGAR_VERSION' => 1, + '_LT_PROG_LTMAIN' => 1, + 'LT_SYS_SYMBOL_USCORE' => 1, + 'AC_LIBTOOL_GCJ' => 1, + 'LT_FUNC_DLSYM_USCORE' => 1, + 'AC_LIBTOOL_CONFIG' => 1, + 'CS_CHECK_COMMON_TOOLS_BASIC' => 1, + 'AC_LTDL_DLLIB' => 1, + '_AM_AUTOCONF_VERSION' => 1, + 'AM_DISABLE_SHARED' => 1, + '_LT_AC_LANG_CXX' => 1, + '_CS_SPLIT_TUPLE' => 1, + 'CS_CHECK_TOOL' => 1, + 'CS_PROG_CXX' => 1, + 'AC_PROG_NM' => 1, + 'CS_MSG_ERROR' => 1, + 'AC_PROG_LD_GNU' => 1, + 'AC_ENABLE_FAST_INSTALL' => 1, + 'CS_LIBTOOL_CLASSIFY' => 1, + 'LTDL_CONVENIENCE' => 1, + 'AC_LIBTOOL_PROG_CC_C_O' => 1, + 'CS_SPLIT' => 1, + 'LT_SUPPORTED_TAG' => 1, + 'AC_DEFUN_ONCE' => 1, + 'CS_CHECK_COMMON_TOOLS_DOC_DOXYGEN' => 1, + '_CS_CHECK_LIB_CREATE_FLAGS' => 1, + '_LT_AC_LANG_GCJ' => 1, + 'AC_LTDL_OBJDIR' => 1, + '_CS_CHECK_HOST_DARWIN' => 1, + 'CS_COMPILER_ERRORS' => 1, + '_LT_AC_PROG_ECHO_BACKSLASH' => 1, + 'CS_COMPILER_WARNINGS' => 1, + '_LT_AC_TRY_DLOPEN_SELF' => 1, + 'LT_AC_PROG_SED' => 1, + 'CS_PATH_PROG' => 1, + 'LTDL_INSTALLABLE' => 1, + '_LT_AC_LANG_GCJ_CONFIG' => 1, + 'AC_ENABLE_SHARED' => 1, + 'CS_JAMCONFIG_APPEND' => 1, + 'CS_CHECK_GLX' => 1, + '_LT_AC_TAGVAR' => 1, + 'AM_PROG_CC_C_O' => 1, + 'LT_LIB_DLLOAD' => 1, + 'm4_include' => 1, + '_AC_AM_CONFIG_HEADER_HOOK' => 1, + 'AM_MAKE_INCLUDE' => 1, + 'LT_CMD_MAX_LEN' => 1, + '_LT_AC_TAGCONFIG' => 1, + 'CS_CHECK_HOST_CPU' => 1, + 'CS_CHECK_BUILD_FLAGS' => 1, + 'CS_MAKEFILE_PREPEND' => 1, + '_LT_COMPILER_BOILERPLATE' => 1, + 'AC_LIBTOOL_SETUP' => 1, + 'AC_PROG_LD_RELOAD_FLAG' => 1, + 'AC_LTDL_DLSYM_USCORE' => 1, + 'CS_LANG_CFLAGS' => 1, + 'CS_PATH_PROGS' => 1, + 'AM_MISSING_HAS_RUN' => 1, + 'CS_CHECK_COMMON_TOOLS_LINK' => 1, + 'LT_CONFIG_LTDL_DIR' => 1, + 'AC_LIBTOOL_DLOPEN_SELF' => 1, + 'LT_OUTPUT' => 1, + '_CS_CLCF_CVAR' => 1, + 'AC_LIBTOOL_PROG_LD_SHLIBS' => 1, + 'CS_CHECK_GLXEXT' => 1, + 'CS_HEADER_APPEND' => 1, + 'AC_LIBTOOL_LINKER_OPTION' => 1, + 'AC_WITH_LTDL' => 1, + '_CS_PROG_CLIENT_PATH' => 1, + 'LT_AC_PROG_GCJ' => 1, + 'LT_SYS_DLOPEN_SELF' => 1, + 'CS_PACKAGEINFO' => 1, + '_LT_AC_PROG_CXXCPP' => 1, + 'AM_DISABLE_STATIC' => 1, + 'CS_SUBST_EMITTER' => 1, + 'CS_HEADER_PREPEND' => 1, + '_AC_PROG_LIBTOOL' => 1, + 'CS_HEADER_OUTPUT' => 1, + '_AM_IF_OPTION' => 1, + 'AC_PATH_TOOL_PREFIX' => 1, + 'm4_pattern_allow' => 1, + 'AC_LIBTOOL_F77' => 1, + 'AM_SET_LEADING_DOT' => 1, + '_LT_AC_SYS_COMPILER' => 1, + '_CS_CLCF_SHVAR' => 1, + 'AM_PROG_NM' => 1, + 'CS_GL_INCLUDE' => 1, + 'CS_PATH_TOOL' => 1, + 'AC_LIBLTDL_CONVENIENCE' => 1, + 'AC_DEPLIBS_CHECK_METHOD' => 1, + 'CS_CHECK_LIB_WITH' => 1, + 'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1, + 'AC_LTDL_ENABLE_INSTALL' => 1, + 'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1, + 'CS_EMIT_BUILD_PROPERTY' => 1, + '_CS_CHECK_LIB_CREATE_FLAG' => 1, + 'AM_INIT_AUTOMAKE' => 1, + 'AC_DISABLE_STATIC' => 1, + 'LT_PATH_NM' => 1, + 'CS_COMPILER_IGNORE_UNUSED' => 1, + 'AC_LTDL_SHLIBEXT' => 1, + '_LT_AC_LOCK' => 1, + '_LT_AC_LANG_RC_CONFIG' => 1, + 'CS_CHECK_PKG_CONFIG' => 1, + 'AC_LTDL_SHLIBPATH' => 1, + 'AM_AUX_DIR_EXPAND' => 1, + 'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1, + '_LT_COMPILER_OPTION' => 1, + '_CS_EMIT_PACKAGEINFO' => 1, + '_AM_SET_OPTIONS' => 1, + '_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, + 'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1, + 'AC_CHECK_LIBM' => 1, + 'LT_PATH_LD' => 1, + '_AM_MANGLE_OPTION' => 1, + 'CS_CHECK_HOST' => 1, + 'AC_LTDL_SYMBOL_USCORE' => 1, + 'AM_SET_DEPDIR' => 1, + 'CS_RUN_PATH_NORMALIZE' => 1, + '_LT_CC_BASENAME' => 1, + '_LT_LIBOBJ' => 1, + 'CS_PROG_LINK' => 1, + '_LT_AC_SHELL_INIT' => 1, + 'AC_DEFUN' => 1, + 'AM_PROG_MKDIR_P' => 1, + 'CS_CHECK_PROGS' => 1, + 'AM_AUTOMAKE_VERSION' => 1, + 'AM_MISSING_PROG' => 1, + 'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1, + '_LT_AC_LANG_C_CONFIG' => 1, + 'CS_TEXT_CACHE_OUTPUT' => 1, + 'AM_PROG_INSTALL_STRIP' => 1, + 'CS_BUILD_IFELSE' => 1, + 'AC_LIBTOOL_OBJDIR' => 1, + 'CS_HEADER_PROPERTY' => 1, + 'gl_FUNC_ARGZ' => 1, + 'CS_EMIT_BUILD_RESULT' => 1, + 'AC_LIBTOOL_PROG_COMPILER_PIC' => 1, + 'LT_LIB_M' => 1, + 'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1, + '_LT_AC_CHECK_DLFCN' => 1, + '_AM_PROG_TAR' => 1, + 'CS_CHECK_COMMON_TOOLS_DOC_TEXINFO' => 1, + '_LT_WITH_SYSROOT' => 1, + 'LT_SYS_DLOPEN_DEPLIBS' => 1, + '_LT_AC_LANG_F77' => 1, + '_CS_META_INFO_EMBED_ENABLE' => 1, + '_AM_SUBST_NOTMAKE' => 1, + '_LT_PROG_ECHO_BACKSLASH' => 1, + '_LTDL_SETUP' => 1, + '_CS_CHECK_LIB_CONFIG_FLAGS' => 1, + 'AM_PROG_LIBTOOL' => 1, + 'AM_PROG_LD' => 1, + 'AC_LIB_LTDL' => 1, + '_LT_AC_FILE_LTDLL_C' => 1, + 'CS_SPLIT_TUPLE' => 1, + 'AU_DEFUN' => 1, + 'AC_LIBTOOL_DLOPEN' => 1, + 'AC_PROG_LD' => 1, + 'CS_CHECK_MKDIR' => 1, + 'AC_LIBTOOL_FC' => 1, + '_AM_SET_OPTION' => 1, + 'AC_LTDL_PREOPEN' => 1, + '_LT_LINKER_BOILERPLATE' => 1, + 'CS_JAMCONFIG_PROPERTY' => 1, + 'AC_LIBTOOL_LANG_CXX_CONFIG' => 1, + '_LT_PREPARE_SED_QUOTE_VARS' => 1, + '_CS_CLCPF_CVAR' => 1, + 'gl_PREREQ_ARGZ' => 1, + '_CS_SPLIT' => 1, + 'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, + 'CS_TEXT_CACHE_APPEND' => 1, + 'LT_SYS_MODULE_EXT' => 1, + 'LT_PROG_RC' => 1, + 'CS_COMPILER_PIC' => 1, + 'CS_JAMCONFIG_PREPEND' => 1, + 'CS_PROG_CC' => 1, + '_LT_PATH_TOOL_PREFIX' => 1, + 'CS_CHECK_GLUT' => 1, + 'AC_LIBTOOL_RC' => 1, + 'AM_SILENT_RULES' => 1, + 'AC_DISABLE_FAST_INSTALL' => 1, + 'include' => 1, + '_LT_AC_SYS_LIBPATH_AIX' => 1, + 'AM_ENABLE_SHARED' => 1, + 'CS_COMPILER_IGNORE_LONG_DOUBLE' => 1, + 'CS_MAKEFILE_PROPERTY' => 1, + 'AC_ENABLE_STATIC' => 1, + 'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1, + '_LT_REQUIRED_DARWIN_CHECKS' => 1, + 'AC_LIBTOOL_LANG_F77_CONFIG' => 1, + 'CS_EMITTER_OPTIONAL' => 1, + 'AM_CONDITIONAL' => 1, + 'LTDL_INIT' => 1, + '_LT_PROG_F77' => 1, + '_LT_PROG_CXX' => 1, + 'LTVERSION_VERSION' => 1, + 'AM_PROG_INSTALL_SH' => 1, + 'CS_CHECK_OPENGL' => 1, + 'AC_PROG_EGREP' => 1, + 'AC_PATH_MAGIC' => 1, + 'AC_LTDL_SYSSEARCHPATH' => 1, + 'm4_pattern_forbid' => 1, + '_LT_LINKER_OPTION' => 1, + 'AC_LIBTOOL_COMPILER_OPTION' => 1, + 'AC_DISABLE_SHARED' => 1, + 'CS_CHECK_TEMPLATE_TOOLKIT2' => 1, + 'AC_LIBTOOL_WIN32_DLL' => 1, + 'LT_LANG' => 1, + '_CS_CLPCF_CVAR' => 1, + 'LT_SYS_DLSEARCH_PATH' => 1, + 'CS_CHECK_LIBTOOL' => 1, + '_CS_CHECK_PKG_CONFIG_PREPARE_PATH' => 1, + 'CS_OUTPUT_INSTALLDIRS' => 1, + 'CS_SYMBOL_QUALIFIER' => 1, + 'LT_AC_PROG_RC' => 1, + 'AC_LIBTOOL_CXX' => 1, + 'LT_INIT' => 1, + 'AM_DEP_TRACK' => 1, + 'CS_PREPARE_INSTALLPATH' => 1, + 'CS_MAKEFILE_OUTPUT' => 1, + '_CS_CHECK_LIB_PKG_CONFIG_FLAGS' => 1, + 'CS_EMIT_PACKAGEINFO' => 1, + 'CS_CHECK_TOOLS' => 1, + 'CS_CHECK_PROG_VERSION' => 1, + 'CS_CHECK_CPPUNIT' => 1, + 'LT_AC_PROG_EGREP' => 1, + '_LT_PROG_FC' => 1, + '_AM_DEPENDENCIES' => 1, + '_CS_PROG_PATH_PREPARE' => 1, + 'AC_LIBTOOL_LANG_C_CONFIG' => 1, + 'LTOPTIONS_VERSION' => 1, + 'CS_CHECK_BUILD' => 1, + 'AC_LIBLTDL_INSTALLABLE' => 1, + 'CS_NULL_EMITTER' => 1, + 'LT_PROG_GCJ' => 1, + 'CS_CHECK_LIBBFD' => 1, + 'CS_JAMCONFIG_OUTPUT' => 1, + 'CS_CHECK_GLU' => 1, + '_CS_META_INFO_EMBED_TOOLS' => 1, + 'CS_CHECK_COMMON_LIBS' => 1, + 'CS_DEFINE_EMITTER' => 1, + 'CS_CHECK_PTHREAD_ATFORK' => 1, + 'CS_MAKEFILE_APPEND' => 1, + 'CS_CREATE_TUPLE' => 1, + 'CS_CHECK_PROG' => 1, + 'LT_SYS_MODULE_PATH' => 1, + 'CS_CHECK_PTHREAD' => 1, + 'AC_LIBTOOL_POSTDEP_PREDEP' => 1, + 'LT_WITH_LTDL' => 1, + '_CS_CHECK_MUTEX_FEATURE' => 1, + 'CS_CHECK_COMPILER_PIC' => 1, + '_LT_AC_LANG_F77_CONFIG' => 1, + 'AM_RUN_LOG' => 1, + 'AC_LIBTOOL_PICMODE' => 1, + 'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1, + '_CS_OUTPUT_INSTALL_DIRS' => 1, + 'AC_LIBTOOL_SYS_LIB_STRIP' => 1, + 'CS_COMPILER_IGNORE_PRAGMAS' => 1, + 'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1, + '_CS_CHECK_LIB_CONFIG_PROG_FLAGS' => 1 + } + ], 'Autom4te::Request' ), + bless( [ + '1', + 1, + [ + '/usr/local/share/autoconf' + ], + [ + '/usr/local/share/autoconf/autoconf/autoconf.m4f', + 'aclocal.m4', + 'configure.ac' + ], + { + 'AM_PROG_F77_C_O' => 1, + '_LT_AC_TAGCONFIG' => 1, + 'm4_pattern_forbid' => 1, + 'AC_INIT' => 1, + '_AM_COND_IF' => 1, + 'AC_CANONICAL_TARGET' => 1, + 'AC_SUBST' => 1, + 'AC_CONFIG_LIBOBJ_DIR' => 1, + 'AC_FC_SRCEXT' => 1, + 'AC_CANONICAL_HOST' => 1, + 'AC_PROG_LIBTOOL' => 1, + 'AM_INIT_AUTOMAKE' => 1, + 'AM_PATH_GUILE' => 1, + 'AC_CONFIG_SUBDIRS' => 1, + 'AM_AUTOMAKE_VERSION' => 1, + 'LT_CONFIG_LTDL_DIR' => 1, + 'AC_REQUIRE_AUX_FILE' => 1, + 'AC_CONFIG_LINKS' => 1, + 'LT_SUPPORTED_TAG' => 1, + 'm4_sinclude' => 1, + 'AM_MAINTAINER_MODE' => 1, + 'AM_NLS' => 1, + 'AM_GNU_GETTEXT_INTL_SUBDIR' => 1, + 'AM_MAKEFILE_INCLUDE' => 1, + '_m4_warn' => 1, + 'AM_PROG_CXX_C_O' => 1, + '_AM_MAKEFILE_INCLUDE' => 1, + '_AM_COND_ENDIF' => 1, + 'AM_ENABLE_MULTILIB' => 1, + 'AM_PROG_MOC' => 1, + 'AM_SILENT_RULES' => 1, + 'AC_CONFIG_FILES' => 1, + 'LT_INIT' => 1, + 'include' => 1, + 'AM_PROG_AR' => 1, + 'AM_GNU_GETTEXT' => 1, + 'AC_LIBSOURCE' => 1, + 'AM_PROG_FC_C_O' => 1, + 'AC_CANONICAL_BUILD' => 1, + 'AC_FC_FREEFORM' => 1, + 'AH_OUTPUT' => 1, + '_AM_SUBST_NOTMAKE' => 1, + 'AC_CONFIG_AUX_DIR' => 1, + 'm4_pattern_allow' => 1, + 'sinclude' => 1, + 'AM_PROG_CC_C_O' => 1, + 'AM_XGETTEXT_OPTION' => 1, + 'AC_CANONICAL_SYSTEM' => 1, + 'AM_CONDITIONAL' => 1, + 'AC_CONFIG_HEADERS' => 1, + 'AC_DEFINE_TRACE_LITERAL' => 1, + 'AM_POT_TOOLS' => 1, + 'm4_include' => 1, + '_AM_COND_ELSE' => 1, + 'AC_SUBST_TRACE' => 1 + } + ], 'Autom4te::Request' ) + ); + diff --git a/autom4te.cache/traces.0 b/autom4te.cache/traces.0 new file mode 100644 index 0000000..3de4822 --- /dev/null +++ b/autom4te.cache/traces.0 @@ -0,0 +1,3415 @@ +m4trace:/usr/local/share/aclocal/argz.m4:76: -1- AC_DEFUN([gl_FUNC_ARGZ], [gl_PREREQ_ARGZ + +AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) + +AC_CHECK_TYPES([error_t], + [], + [AC_DEFINE([error_t], [int], + [Define to a type to use for `error_t' if it is not otherwise available.]) + AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h + does not typedef error_t.])], + [#if defined(HAVE_ARGZ_H) +# include +#endif]) + +ARGZ_H= +AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ + argz_next argz_stringify], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) + +dnl if have system argz functions, allow forced use of +dnl libltdl-supplied implementation (and default to do so +dnl on "known bad" systems). Could use a runtime check, but +dnl (a) detecting malloc issues is notoriously unreliable +dnl (b) only known system that declares argz functions, +dnl provides them, yet they are broken, is cygwin +dnl releases prior to 16-Mar-2007 (1.5.24 and earlier) +dnl So, it's more straightforward simply to special case +dnl this for known bad systems. +AS_IF([test -z "$ARGZ_H"], + [AC_CACHE_CHECK( + [if argz actually works], + [lt_cv_sys_argz_works], + [[case $host_os in #( + *cygwin*) + lt_cv_sys_argz_works=no + if test "$cross_compiling" != no; then + lt_cv_sys_argz_works="guessing no" + else + lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' + save_IFS=$IFS + IFS=-. + set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` + IFS=$save_IFS + lt_os_major=${2-0} + lt_os_minor=${3-0} + lt_os_micro=${4-0} + if test "$lt_os_major" -gt 1 \ + || { test "$lt_os_major" -eq 1 \ + && { test "$lt_os_minor" -gt 5 \ + || { test "$lt_os_minor" -eq 5 \ + && test "$lt_os_micro" -gt 24; }; }; }; then + lt_cv_sys_argz_works=yes + fi + fi + ;; #( + *) lt_cv_sys_argz_works=yes ;; + esac]]) + AS_IF([test "$lt_cv_sys_argz_works" = yes], + [AC_DEFINE([HAVE_WORKING_ARGZ], 1, + [This value is set to 1 to indicate that the system argz facility works])], + [ARGZ_H=argz.h + AC_LIBOBJ([argz])])]) + +AC_SUBST([ARGZ_H]) +]) +m4trace:/usr/local/share/aclocal/argz.m4:79: -1- AC_DEFUN([gl_PREREQ_ARGZ], [:]) +m4trace:/usr/local/share/aclocal/libtool.m4:104: -1- AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +]) +m4trace:/usr/local/share/aclocal/libtool.m4:107: -1- AU_DEFUN([AC_PROG_LIBTOOL], [m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:107: -1- AC_DEFUN([AC_PROG_LIBTOOL], [AC_DIAGNOSE([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:108: -1- AU_DEFUN([AM_PROG_LIBTOOL], [m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:108: -1- AC_DEFUN([AM_PROG_LIBTOOL], [AC_DIAGNOSE([obsolete], [The macro `AM_PROG_LIBTOOL' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_INIT], [LT_INIT($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:692: -1- AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +]) +m4trace:/usr/local/share/aclocal/libtool.m4:788: -1- AC_DEFUN([LT_SUPPORTED_TAG], []) +m4trace:/usr/local/share/aclocal/libtool.m4:811: -1- AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +]) +m4trace:/usr/local/share/aclocal/libtool.m4:861: -1- AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +m4trace:/usr/local/share/aclocal/libtool.m4:861: -1- AC_DEFUN([AC_LIBTOOL_CXX], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_CXX' is obsolete. +You should run autoupdate.])dnl +LT_LANG(C++)]) +m4trace:/usr/local/share/aclocal/libtool.m4:862: -1- AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +m4trace:/usr/local/share/aclocal/libtool.m4:862: -1- AC_DEFUN([AC_LIBTOOL_F77], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_F77' is obsolete. +You should run autoupdate.])dnl +LT_LANG(Fortran 77)]) +m4trace:/usr/local/share/aclocal/libtool.m4:863: -1- AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +m4trace:/usr/local/share/aclocal/libtool.m4:863: -1- AC_DEFUN([AC_LIBTOOL_FC], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_FC' is obsolete. +You should run autoupdate.])dnl +LT_LANG(Fortran)]) +m4trace:/usr/local/share/aclocal/libtool.m4:864: -1- AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +m4trace:/usr/local/share/aclocal/libtool.m4:864: -1- AC_DEFUN([AC_LIBTOOL_GCJ], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_GCJ' is obsolete. +You should run autoupdate.])dnl +LT_LANG(Java)]) +m4trace:/usr/local/share/aclocal/libtool.m4:865: -1- AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +m4trace:/usr/local/share/aclocal/libtool.m4:865: -1- AC_DEFUN([AC_LIBTOOL_RC], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_RC' is obsolete. +You should run autoupdate.])dnl +LT_LANG(Windows Resource)]) +m4trace:/usr/local/share/aclocal/libtool.m4:1210: -1- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1484: -1- AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +]) +m4trace:/usr/local/share/aclocal/libtool.m4:1487: -1- AU_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [m4_if($#, 0, [_LT_COMPILER_OPTION], [_LT_COMPILER_OPTION($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1487: -1- AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_COMPILER_OPTION' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [_LT_COMPILER_OPTION], [_LT_COMPILER_OPTION($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1528: -1- AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +]) +m4trace:/usr/local/share/aclocal/libtool.m4:1531: -1- AU_DEFUN([AC_LIBTOOL_LINKER_OPTION], [m4_if($#, 0, [_LT_LINKER_OPTION], [_LT_LINKER_OPTION($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1531: -1- AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_LINKER_OPTION' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [_LT_LINKER_OPTION], [_LT_LINKER_OPTION($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1668: -1- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +]) +m4trace:/usr/local/share/aclocal/libtool.m4:1671: -1- AU_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [m4_if($#, 0, [LT_CMD_MAX_LEN], [LT_CMD_MAX_LEN($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1671: -1- AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_SYS_MAX_CMD_LEN' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_CMD_MAX_LEN], [LT_CMD_MAX_LEN($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1896: -1- AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +]) +m4trace:/usr/local/share/aclocal/libtool.m4:1899: -1- AU_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [m4_if($#, 0, [LT_SYS_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:1899: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_DLOPEN_SELF' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_SYS_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:2930: -1- AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +]) +m4trace:/usr/local/share/aclocal/libtool.m4:2933: -1- AU_DEFUN([AC_PATH_TOOL_PREFIX], [m4_if($#, 0, [_LT_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:2933: -1- AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_DIAGNOSE([obsolete], [The macro `AC_PATH_TOOL_PREFIX' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [_LT_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:3042: -1- AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +]) +m4trace:/usr/local/share/aclocal/libtool.m4:3430: -1- AU_DEFUN([AM_PROG_NM], [m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:3430: -1- AC_DEFUN([AM_PROG_NM], [AC_DIAGNOSE([obsolete], [The macro `AM_PROG_NM' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:3431: -1- AU_DEFUN([AC_PROG_NM], [m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:3431: -1- AC_DEFUN([AC_PROG_NM], [AC_DIAGNOSE([obsolete], [The macro `AC_PROG_NM' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_PATH_NM], [LT_PATH_NM($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:3517: -1- AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +]) +m4trace:/usr/local/share/aclocal/libtool.m4:3520: -1- AU_DEFUN([AC_CHECK_LIBM], [m4_if($#, 0, [LT_LIB_M], [LT_LIB_M($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:3520: -1- AC_DEFUN([AC_CHECK_LIBM], [AC_DIAGNOSE([obsolete], [The macro `AC_CHECK_LIBM' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_LIB_M], [LT_LIB_M($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:7484: -1- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) +m4trace:/usr/local/share/aclocal/libtool.m4:7487: -1- AU_DEFUN([LT_AC_PROG_GCJ], [m4_if($#, 0, [LT_PROG_GCJ], [LT_PROG_GCJ($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:7487: -1- AC_DEFUN([LT_AC_PROG_GCJ], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_GCJ' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_PROG_GCJ], [LT_PROG_GCJ($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:7496: -1- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) +]) +m4trace:/usr/local/share/aclocal/libtool.m4:7499: -1- AU_DEFUN([LT_AC_PROG_RC], [m4_if($#, 0, [LT_PROG_RC], [LT_PROG_RC($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:7499: -1- AC_DEFUN([LT_AC_PROG_RC], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_RC' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_PROG_RC], [LT_PROG_RC($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:7619: -1- AU_DEFUN([LT_AC_PROG_SED], [m4_if($#, 0, [AC_PROG_SED], [AC_PROG_SED($@)])]) +m4trace:/usr/local/share/aclocal/libtool.m4:7619: -1- AC_DEFUN([LT_AC_PROG_SED], [AC_DIAGNOSE([obsolete], [The macro `LT_AC_PROG_SED' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [AC_PROG_SED], [AC_PROG_SED($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:19: -1- AC_DEFUN([LT_CONFIG_LTDL_DIR], [AC_BEFORE([$0], [LTDL_INIT]) +_$0($*) +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:77: -1- AC_DEFUN([LTDL_CONVENIENCE], [AC_BEFORE([$0], [LTDL_INIT])dnl +dnl Although the argument is deprecated and no longer documented, +dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one +dnl here make sure it is the same as any other declaration of libltdl's +dnl location! This also ensures lt_ltdl_dir is set when configure.ac is +dnl not yet using an explicit LT_CONFIG_LTDL_DIR. +m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl +_$0() +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:83: -1- AU_DEFUN([AC_LIBLTDL_CONVENIENCE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_CONVENIENCE]) +m4trace:/usr/local/share/aclocal/ltdl.m4:83: -1- AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBLTDL_CONVENIENCE' is obsolete. +You should run autoupdate.])dnl +_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_CONVENIENCE]) +m4trace:/usr/local/share/aclocal/ltdl.m4:133: -1- AC_DEFUN([LTDL_INSTALLABLE], [AC_BEFORE([$0], [LTDL_INIT])dnl +dnl Although the argument is deprecated and no longer documented, +dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one +dnl here make sure it is the same as any other declaration of libltdl's +dnl location! This also ensures lt_ltdl_dir is set when configure.ac is +dnl not yet using an explicit LT_CONFIG_LTDL_DIR. +m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl +_$0() +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:139: -1- AU_DEFUN([AC_LIBLTDL_INSTALLABLE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_INSTALLABLE]) +m4trace:/usr/local/share/aclocal/ltdl.m4:139: -1- AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBLTDL_INSTALLABLE' is obsolete. +You should run autoupdate.])dnl +_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_INSTALLABLE]) +m4trace:/usr/local/share/aclocal/ltdl.m4:216: -1- AC_DEFUN([_LT_LIBOBJ], [ + m4_pattern_allow([^_LT_LIBOBJS$]) + _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:349: -1- AC_DEFUN([LTDL_INIT], [dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +dnl We need to keep our own list of libobjs separate from our parent project, +dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while +dnl we look for our own LIBOBJs. +m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ])) +m4_pushdef([AC_LIBSOURCES]) + +dnl If not otherwise defined, default to the 1.5.x compatible subproject mode: +m4_if(_LTDL_MODE, [], + [m4_define([_LTDL_MODE], m4_default([$2], [subproject])) + m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])], + [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])]) + +AC_ARG_WITH([included_ltdl], + [AS_HELP_STRING([--with-included-ltdl], + [use the GNU ltdl sources included here])]) + +if test "x$with_included_ltdl" != xyes; then + # We are not being forced to use the included libltdl sources, so + # decide whether there is a useful installed version we can use. + AC_CHECK_HEADER([ltdl.h], + [AC_CHECK_DECL([lt_dlinterface_register], + [AC_CHECK_LIB([ltdl], [lt_dladvise_preload], + [with_included_ltdl=no], + [with_included_ltdl=yes])], + [with_included_ltdl=yes], + [AC_INCLUDES_DEFAULT + #include ])], + [with_included_ltdl=yes], + [AC_INCLUDES_DEFAULT] + ) +fi + +dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE +dnl was called yet, then for old times' sake, we assume libltdl is in an +dnl eponymous directory: +AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])]) + +AC_ARG_WITH([ltdl_include], + [AS_HELP_STRING([--with-ltdl-include=DIR], + [use the ltdl headers installed in DIR])]) + +if test -n "$with_ltdl_include"; then + if test -f "$with_ltdl_include/ltdl.h"; then : + else + AC_MSG_ERROR([invalid ltdl include directory: `$with_ltdl_include']) + fi +else + with_ltdl_include=no +fi + +AC_ARG_WITH([ltdl_lib], + [AS_HELP_STRING([--with-ltdl-lib=DIR], + [use the libltdl.la installed in DIR])]) + +if test -n "$with_ltdl_lib"; then + if test -f "$with_ltdl_lib/libltdl.la"; then : + else + AC_MSG_ERROR([invalid ltdl library directory: `$with_ltdl_lib']) + fi +else + with_ltdl_lib=no +fi + +case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in + ,yes,no,no,) + m4_case(m4_default(_LTDL_TYPE, [convenience]), + [convenience], [_LTDL_CONVENIENCE], + [installable], [_LTDL_INSTALLABLE], + [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)]) + ;; + ,no,no,no,) + # If the included ltdl is not to be used, then use the + # preinstalled libltdl we found. + AC_DEFINE([HAVE_LTDL], [1], + [Define this if a modern libltdl is already installed]) + LIBLTDL=-lltdl + LTDLDEPS= + LTDLINCL= + ;; + ,no*,no,*) + AC_MSG_ERROR([`--with-ltdl-include' and `--with-ltdl-lib' options must be used together]) + ;; + *) with_included_ltdl=no + LIBLTDL="-L$with_ltdl_lib -lltdl" + LTDLDEPS= + LTDLINCL="-I$with_ltdl_include" + ;; +esac +INCLTDL="$LTDLINCL" + +# Report our decision... +AC_MSG_CHECKING([where to find libltdl headers]) +AC_MSG_RESULT([$LTDLINCL]) +AC_MSG_CHECKING([where to find libltdl library]) +AC_MSG_RESULT([$LIBLTDL]) + +_LTDL_SETUP + +dnl restore autoconf definition. +m4_popdef([AC_LIBOBJ]) +m4_popdef([AC_LIBSOURCES]) + +AC_CONFIG_COMMANDS_PRE([ + _ltdl_libobjs= + _ltdl_ltlibobjs= + if test -n "$_LT_LIBOBJS"; then + # Remove the extension. + _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do + _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" + _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" + done + fi + AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs]) + AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs]) +]) + +# Only expand once: +m4_define([LTDL_INIT]) +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:352: -1- AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) +m4trace:/usr/local/share/aclocal/ltdl.m4:352: -1- AC_DEFUN([AC_LIB_LTDL], [AC_DIAGNOSE([obsolete], [The macro `AC_LIB_LTDL' is obsolete. +You should run autoupdate.])dnl +LTDL_INIT($@)]) +m4trace:/usr/local/share/aclocal/ltdl.m4:353: -1- AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) +m4trace:/usr/local/share/aclocal/ltdl.m4:353: -1- AC_DEFUN([AC_WITH_LTDL], [AC_DIAGNOSE([obsolete], [The macro `AC_WITH_LTDL' is obsolete. +You should run autoupdate.])dnl +LTDL_INIT($@)]) +m4trace:/usr/local/share/aclocal/ltdl.m4:354: -1- AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) +m4trace:/usr/local/share/aclocal/ltdl.m4:354: -1- AC_DEFUN([LT_WITH_LTDL], [AC_DIAGNOSE([obsolete], [The macro `LT_WITH_LTDL' is obsolete. +You should run autoupdate.])dnl +LTDL_INIT($@)]) +m4trace:/usr/local/share/aclocal/ltdl.m4:421: -1- AC_DEFUN([_LTDL_SETUP], [AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_SYS_MODULE_EXT])dnl +AC_REQUIRE([LT_SYS_MODULE_PATH])dnl +AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl +AC_REQUIRE([LT_LIB_DLLOAD])dnl +AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl +AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl +AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl +AC_REQUIRE([gl_FUNC_ARGZ])dnl + +m4_require([_LT_CHECK_OBJDIR])dnl +m4_require([_LT_HEADER_DLFCN])dnl +m4_require([_LT_CHECK_DLPREOPEN])dnl +m4_require([_LT_DECL_SED])dnl + +dnl Don't require this, or it will be expanded earlier than the code +dnl that sets the variables it relies on: +_LT_ENABLE_INSTALL + +dnl _LTDL_MODE specific code must be called at least once: +_LTDL_MODE_DISPATCH + +# In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS +# the user used. This is so that ltdl.h can pick up the parent projects +# config.h file, The first file in AC_CONFIG_HEADERS must contain the +# definitions required by ltdl.c. +# FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). +AC_CONFIG_COMMANDS_PRE([dnl +m4_pattern_allow([^LT_CONFIG_H$])dnl +m4_ifset([AH_HEADER], + [LT_CONFIG_H=AH_HEADER], + [m4_ifset([AC_LIST_HEADERS], + [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's,^[[ ]]*,,;s,[[ :]].*$,,'`], + [])])]) +AC_SUBST([LT_CONFIG_H]) + +AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h], + [], [], [AC_INCLUDES_DEFAULT]) + +AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])]) +AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])]) + +m4_pattern_allow([LT_LIBEXT])dnl +AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension]) + +name= +eval "lt_libprefix=\"$libname_spec\"" +m4_pattern_allow([LT_LIBPREFIX])dnl +AC_DEFINE_UNQUOTED([LT_LIBPREFIX],["$lt_libprefix"],[The archive prefix]) + +name=ltdl +eval "LTDLOPEN=\"$libname_spec\"" +AC_SUBST([LTDLOPEN]) +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:539: -1- AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_CACHE_CHECK([whether deplibs are loaded by dlopen], + [lt_cv_sys_dlopen_deplibs], + [# PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + lt_cv_sys_dlopen_deplibs=unknown + case $host_os in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + aix[[4-9]]*) + lt_cv_sys_dlopen_deplibs=yes + ;; + amigaos*) + case $host_cpu in + powerpc) + lt_cv_sys_dlopen_deplibs=no + ;; + esac + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + lt_cv_sys_dlopen_deplibs=yes + ;; + freebsd* | dragonfly*) + lt_cv_sys_dlopen_deplibs=yes + ;; + gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu) + # GNU and its variants, using gnu ld.so (Glibc) + lt_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + lt_cv_sys_dlopen_deplibs=yes + ;; + interix*) + lt_cv_sys_dlopen_deplibs=yes + ;; + irix[[12345]]*|irix6.[[01]]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + lt_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + lt_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + lt_cv_sys_dlopen_deplibs=yes + ;; + osf[[1234]]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explicitly say `no'. + lt_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + lt_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + lt_cv_sys_dlopen_deplibs=yes + ;; + qnx*) + lt_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + lt_cv_sys_dlopen_deplibs=yes + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + ]) +if test "$lt_cv_sys_dlopen_deplibs" != yes; then + AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], + [Define if the OS needs help to load dependent libraries for dlopen().]) +fi +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:542: -1- AU_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [m4_if($#, 0, [LT_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:542: -1- AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYS_DLOPEN_DEPLIBS' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:562: -1- AC_DEFUN([LT_SYS_MODULE_EXT], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([which extension is used for runtime loadable modules], + [libltdl_cv_shlibext], +[ +module=yes +eval libltdl_cv_shlibext=$shrext_cmds + ]) +if test -n "$libltdl_cv_shlibext"; then + m4_pattern_allow([LT_MODULE_EXT])dnl + AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"], + [Define to the extension used for runtime loadable modules, say, ".so".]) +fi +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:565: -1- AU_DEFUN([AC_LTDL_SHLIBEXT], [m4_if($#, 0, [LT_SYS_MODULE_EXT], [LT_SYS_MODULE_EXT($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:565: -1- AC_DEFUN([AC_LTDL_SHLIBEXT], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SHLIBEXT' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_SYS_MODULE_EXT], [LT_SYS_MODULE_EXT($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:581: -1- AC_DEFUN([LT_SYS_MODULE_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([which variable specifies run-time module search path], + [lt_cv_module_path_var], [lt_cv_module_path_var="$shlibpath_var"]) +if test -n "$lt_cv_module_path_var"; then + m4_pattern_allow([LT_MODULE_PATH_VAR])dnl + AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"], + [Define to the name of the environment variable that determines the run-time module search path.]) +fi +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:584: -1- AU_DEFUN([AC_LTDL_SHLIBPATH], [m4_if($#, 0, [LT_SYS_MODULE_PATH], [LT_SYS_MODULE_PATH($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:584: -1- AC_DEFUN([AC_LTDL_SHLIBPATH], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SHLIBPATH' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_SYS_MODULE_PATH], [LT_SYS_MODULE_PATH($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:609: -1- AC_DEFUN([LT_SYS_DLSEARCH_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([for the default library search path], + [lt_cv_sys_dlsearch_path], + [lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec"]) +if test -n "$lt_cv_sys_dlsearch_path"; then + sys_dlsearch_path= + for dir in $lt_cv_sys_dlsearch_path; do + if test -z "$sys_dlsearch_path"; then + sys_dlsearch_path="$dir" + else + sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir" + fi + done + m4_pattern_allow([LT_DLSEARCH_PATH])dnl + AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"], + [Define to the system default library search path.]) +fi +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:612: -1- AU_DEFUN([AC_LTDL_SYSSEARCHPATH], [m4_if($#, 0, [LT_SYS_DLSEARCH_PATH], [LT_SYS_DLSEARCH_PATH($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:612: -1- AC_DEFUN([AC_LTDL_SYSSEARCHPATH], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYSSEARCHPATH' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_SYS_DLSEARCH_PATH], [LT_SYS_DLSEARCH_PATH($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:728: -1- AC_DEFUN([LT_LIB_DLLOAD], [m4_pattern_allow([^LT_DLLOADERS$]) +LT_DLLOADERS= +AC_SUBST([LT_DLLOADERS]) + +AC_LANG_PUSH([C]) + +LIBADD_DLOPEN= +AC_SEARCH_LIBS([dlopen], [dl], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + if test "$ac_cv_search_dlopen" != "none required" ; then + LIBADD_DLOPEN="-ldl" + fi + libltdl_cv_lib_dl_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H +# include +#endif + ]], [[dlopen(0, 0);]])], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + libltdl_cv_func_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], + [AC_CHECK_LIB([svld], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])]) +if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes +then + lt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DLOPEN" + AC_CHECK_FUNCS([dlerror]) + LIBS="$lt_save_LIBS" +fi +AC_SUBST([LIBADD_DLOPEN]) + +LIBADD_SHL_LOAD= +AC_CHECK_FUNC([shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"], + [AC_CHECK_LIB([dld], [shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" + LIBADD_SHL_LOAD="-ldld"])]) +AC_SUBST([LIBADD_SHL_LOAD]) + +case $host_os in +darwin[[1567]].*) +# We only want this for pre-Mac OS X 10.4. + AC_CHECK_FUNC([_dyld_func_lookup], + [AC_DEFINE([HAVE_DYLD], [1], + [Define if you have the _dyld_func_lookup function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"]) + ;; +beos*) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" + ;; +cygwin* | mingw* | os2* | pw32*) + AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include ]]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" + ;; +esac + +AC_CHECK_LIB([dld], [dld_link], + [AC_DEFINE([HAVE_DLD], [1], + [Define if you have the GNU dld library.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"]) +AC_SUBST([LIBADD_DLD_LINK]) + +m4_pattern_allow([^LT_DLPREOPEN$]) +LT_DLPREOPEN= +if test -n "$LT_DLLOADERS" +then + for lt_loader in $LT_DLLOADERS; do + LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " + done + AC_DEFINE([HAVE_LIBDLLOADER], [1], + [Define if libdlloader will be built on this platform]) +fi +AC_SUBST([LT_DLPREOPEN]) + +dnl This isn't used anymore, but set it for backwards compatibility +LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" +AC_SUBST([LIBADD_DL]) + +AC_LANG_POP +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:731: -1- AU_DEFUN([AC_LTDL_DLLIB], [m4_if($#, 0, [LT_LIB_DLLOAD], [LT_LIB_DLLOAD($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:731: -1- AC_DEFUN([AC_LTDL_DLLIB], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_DLLIB' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_LIB_DLLOAD], [LT_LIB_DLLOAD($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:773: -1- AC_DEFUN([LT_SYS_SYMBOL_USCORE], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +AC_CACHE_CHECK([for _ prefix in compiled symbols], + [lt_cv_sys_symbol_underscore], + [lt_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext <<_LT_EOF +void nm_test_func(){} +int main(){nm_test_func;return 0;} +_LT_EOF + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + lt_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.c >&AS_MESSAGE_LOG_FD + fi + rm -rf conftest* + ]) + sys_symbol_underscore=$lt_cv_sys_symbol_underscore + AC_SUBST([sys_symbol_underscore]) +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:776: -1- AU_DEFUN([AC_LTDL_SYMBOL_USCORE], [m4_if($#, 0, [LT_SYS_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:776: -1- AC_DEFUN([AC_LTDL_SYMBOL_USCORE], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_SYMBOL_USCORE' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_SYS_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:805: -1- AC_DEFUN([LT_FUNC_DLSYM_USCORE], [AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl +if test x"$lt_cv_sys_symbol_underscore" = xyes; then + if test x"$libltdl_cv_func_dlopen" = xyes || + test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then + AC_CACHE_CHECK([whether we have to add an underscore for dlsym], + [libltdl_cv_need_uscore], + [libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DLOPEN" + _LT_TRY_DLOPEN_SELF( + [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], + [], [libltdl_cv_need_uscore=cross]) + LIBS="$save_LIBS" + ]) + fi +fi + +if test x"$libltdl_cv_need_uscore" = xyes; then + AC_DEFINE([NEED_USCORE], [1], + [Define if dlsym() requires a leading underscore in symbol names.]) +fi +]) +m4trace:/usr/local/share/aclocal/ltdl.m4:808: -1- AU_DEFUN([AC_LTDL_DLSYM_USCORE], [m4_if($#, 0, [LT_FUNC_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE($@)])]) +m4trace:/usr/local/share/aclocal/ltdl.m4:808: -1- AC_DEFUN([AC_LTDL_DLSYM_USCORE], [AC_DIAGNOSE([obsolete], [The macro `AC_LTDL_DLSYM_USCORE' is obsolete. +You should run autoupdate.])dnl +m4_if($#, 0, [LT_FUNC_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE($@)])]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:14: -1- AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:116: -1- AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:116: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_DLOPEN' is obsolete. +You should run autoupdate.])dnl +_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:152: -1- AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:152: -1- AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_WIN32_DLL' is obsolete. +You should run autoupdate.])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:197: -1- AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:201: -1- AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:203: -1- AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:203: -1- AC_DEFUN([AM_ENABLE_SHARED], [AC_DIAGNOSE([obsolete], [The macro `AM_ENABLE_SHARED' is obsolete. +You should run autoupdate.])dnl +AC_ENABLE_SHARED($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:204: -1- AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:204: -1- AC_DEFUN([AM_DISABLE_SHARED], [AC_DIAGNOSE([obsolete], [The macro `AM_DISABLE_SHARED' is obsolete. +You should run autoupdate.])dnl +AC_DISABLE_SHARED($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:251: -1- AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:255: -1- AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:257: -1- AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:257: -1- AC_DEFUN([AM_ENABLE_STATIC], [AC_DIAGNOSE([obsolete], [The macro `AM_ENABLE_STATIC' is obsolete. +You should run autoupdate.])dnl +AC_ENABLE_STATIC($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:258: -1- AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:258: -1- AC_DEFUN([AM_DISABLE_STATIC], [AC_DIAGNOSE([obsolete], [The macro `AM_DISABLE_STATIC' is obsolete. +You should run autoupdate.])dnl +AC_DISABLE_STATIC($@)]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:308: -1- AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:308: -1- AC_DEFUN([AC_ENABLE_FAST_INSTALL], [AC_DIAGNOSE([obsolete], [The macro `AC_ENABLE_FAST_INSTALL' is obsolete. +You should run autoupdate.])dnl +_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:315: -1- AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:315: -1- AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_DIAGNOSE([obsolete], [The macro `AC_DISABLE_FAST_INSTALL' is obsolete. +You should run autoupdate.])dnl +_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:348: -1- AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltoptions.m4:348: -1- AC_DEFUN([AC_LIBTOOL_PICMODE], [AC_DIAGNOSE([obsolete], [The macro `AC_LIBTOOL_PICMODE' is obsolete. +You should run autoupdate.])dnl +_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) +m4trace:/usr/local/share/aclocal/ltsugar.m4:13: -1- AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) +m4trace:/usr/local/share/aclocal/ltversion.m4:23: -1- AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4' +macro_revision='1.3293' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:36: -1- AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:40: -1- AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:41: -1- AC_DEFUN([_LT_AC_SHELL_INIT]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:42: -1- AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:44: -1- AC_DEFUN([_LT_AC_TAGVAR]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:45: -1- AC_DEFUN([AC_LTDL_ENABLE_INSTALL]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:46: -1- AC_DEFUN([AC_LTDL_PREOPEN]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:47: -1- AC_DEFUN([_LT_AC_SYS_COMPILER]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:48: -1- AC_DEFUN([_LT_AC_LOCK]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:49: -1- AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:50: -1- AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:51: -1- AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:52: -1- AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:53: -1- AC_DEFUN([AC_LIBTOOL_OBJDIR]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:54: -1- AC_DEFUN([AC_LTDL_OBJDIR]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:55: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:56: -1- AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:57: -1- AC_DEFUN([AC_PATH_MAGIC]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:58: -1- AC_DEFUN([AC_PROG_LD_GNU]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:59: -1- AC_DEFUN([AC_PROG_LD_RELOAD_FLAG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:60: -1- AC_DEFUN([AC_DEPLIBS_CHECK_METHOD]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:61: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:62: -1- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:63: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:64: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:65: -1- AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:66: -1- AC_DEFUN([LT_AC_PROG_EGREP]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:71: -1- AC_DEFUN([_AC_PROG_LIBTOOL]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:72: -1- AC_DEFUN([AC_LIBTOOL_SETUP]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:73: -1- AC_DEFUN([_LT_AC_CHECK_DLFCN]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:74: -1- AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:75: -1- AC_DEFUN([_LT_AC_TAGCONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:77: -1- AC_DEFUN([_LT_AC_LANG_CXX]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:78: -1- AC_DEFUN([_LT_AC_LANG_F77]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:79: -1- AC_DEFUN([_LT_AC_LANG_GCJ]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:80: -1- AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:81: -1- AC_DEFUN([_LT_AC_LANG_C_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:82: -1- AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:83: -1- AC_DEFUN([_LT_AC_LANG_CXX_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:84: -1- AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:85: -1- AC_DEFUN([_LT_AC_LANG_F77_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:86: -1- AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:87: -1- AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:88: -1- AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:89: -1- AC_DEFUN([_LT_AC_LANG_RC_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:90: -1- AC_DEFUN([AC_LIBTOOL_CONFIG]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:91: -1- AC_DEFUN([_LT_AC_FILE_LTDLL_C]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:93: -1- AC_DEFUN([_LT_AC_PROG_CXXCPP]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:96: -1- AC_DEFUN([_LT_PROG_F77]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:97: -1- AC_DEFUN([_LT_PROG_FC]) +m4trace:/usr/local/share/aclocal/lt~obsolete.m4:98: -1- AC_DEFUN([_LT_PROG_CXX]) +m4trace:/usr/local/share/aclocal-1.11/amversion.m4:20: -1- AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) +m4trace:/usr/local/share/aclocal-1.11/amversion.m4:37: -1- AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) +m4trace:/usr/local/share/aclocal-1.11/auxdir.m4:52: -1- AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) +m4trace:/usr/local/share/aclocal-1.11/cond.m4:35: -1- AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) +m4trace:/usr/local/share/aclocal-1.11/depend.m4:156: -1- AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) +m4trace:/usr/local/share/aclocal-1.11/depend.m4:166: -1- AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) +m4trace:/usr/local/share/aclocal-1.11/depend.m4:182: -1- AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) +m4trace:/usr/local/share/aclocal-1.11/depout.m4:65: -1- AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +]) +m4trace:/usr/local/share/aclocal-1.11/depout.m4:79: -1- AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) +m4trace:/usr/local/share/aclocal-1.11/init.m4:110: -1- AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) +m4trace:/usr/local/share/aclocal-1.11/init.m4:138: -1- AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) +m4trace:/usr/local/share/aclocal-1.11/install-sh.m4:21: -1- AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) +m4trace:/usr/local/share/aclocal-1.11/lead-dot.m4:21: -1- AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) +m4trace:/usr/local/share/aclocal-1.11/make.m4:51: -1- AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) +m4trace:/usr/local/share/aclocal-1.11/minuso.m4:35: -1- AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) +m4trace:/usr/local/share/aclocal-1.11/missing.m4:17: -1- AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) +m4trace:/usr/local/share/aclocal-1.11/missing.m4:42: -1- AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) +m4trace:/usr/local/share/aclocal-1.11/mkdirp.m4:26: -1- AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) +m4trace:/usr/local/share/aclocal-1.11/options.m4:14: -1- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) +m4trace:/usr/local/share/aclocal-1.11/options.m4:20: -1- AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +m4trace:/usr/local/share/aclocal-1.11/options.m4:26: -1- AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) +m4trace:/usr/local/share/aclocal-1.11/options.m4:32: -1- AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +m4trace:/usr/local/share/aclocal-1.11/runlog.m4:17: -1- AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) +m4trace:/usr/local/share/aclocal-1.11/sanity.m4:64: -1- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) +m4trace:/usr/local/share/aclocal-1.11/silent.m4:27: -1- AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], +[ --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0')]) +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) +m4trace:/usr/local/share/aclocal-1.11/strip.m4:28: -1- AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) +m4trace:/usr/local/share/aclocal-1.11/substnot.m4:14: -1- AC_DEFUN([_AM_SUBST_NOTMAKE]) +m4trace:/usr/local/share/aclocal-1.11/substnot.m4:19: -1- AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) +m4trace:/usr/local/share/aclocal-1.11/tar.m4:95: -1- AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) +m4trace:acinclude.m4:33: -1- AC_DEFUN([CS_SPLIT_TUPLE], [CS_SPLIT([$1], [cs_dummy,$2], [@]) + m4_map([_CS_SPLIT_TUPLE], [$2])]) +m4trace:acinclude.m4:37: -1- AC_DEFUN([_CS_SPLIT_TUPLE], [$1=`echo $$1 | sed 'y%@%:@% %'` + ]) +m4trace:acinclude.m4:51: -1- AC_DEFUN([CS_CREATE_TUPLE], [`echo @$1@$2@$3 | sed 'y% %@%:@%'`]) +m4trace:acinclude.m4:69: -1- AC_DEFUN([CS_LANG_CFLAGS], [AC_LANG_CASE([C], [CFLAGS], [C++], [CXXFLAGS])]) +m4trace:acinclude.m4:157: -1- AC_DEFUN([CS_BUILD_IFELSE], [AC_LANG_PUSH(m4_default([$3],[C])) + cs_cflags_save="$CS_LANG_CFLAGS" + cs_lflags_save="$LDFLAGS" + cs_libs_save="$LIBS" + cs_build_ok=no + m4_ifval([$10], [m4_pushdef([AC_TRY_EVAL], [_AC_EVAL_STDERR]($$[1]))]) + + for cs_build_item in m4_default([$2],[CS_CREATE_TUPLE()]) + do + CS_SPLIT_TUPLE( + [$cs_build_item],[cs_cflags_test,cs_lflags_test,cs_libs_test]) + CS_LANG_CFLAGS="$cs_cflags_test $6 $cs_cflags_save" + LDFLAGS="$cs_lflags_test $7 $cs_lflags_save" + LIBS="$cs_libs_test $8 $cs_libs_save" + AC_LINK_IFELSE(m4_default([$1], [AC_LANG_PROGRAM([],[])]), + [m4_ifval([$10], + [AS_IF([AC_TRY_COMMAND( + [grep "AS_ESCAPE([$10])" conftest.err >/dev/null 2>&1])], + [cs_build_ok=no], [cs_build_ok=yes])], + [cs_build_ok=yes])]) + AS_IF([test $cs_build_ok = yes], [break]) + done + + m4_ifval([$10], [m4_popdef([AC_TRY_EVAL]) rm -f conftest.err]) + CS_LANG_CFLAGS=$cs_cflags_save + LDFLAGS=$cs_lflags_save + LIBS=$cs_libs_save + AC_LANG_POP(m4_default([$3],[C])) + + AS_IF([test $cs_build_ok = yes], + [cs_build_cflags=CS_TRIM([$cs_cflags_test[]m4_ifval([$9],[],[ $6])]) + cs_build_lflags=CS_TRIM([$cs_lflags_test[]m4_ifval([$9],[],[ $7])]) + cs_build_libs=CS_TRIM([$cs_libs_test[]m4_ifval([$9],[],[ $8])]) + $4], + [$5])]) +m4trace:acinclude.m4:195: -1- AC_DEFUN([CS_CHECK_BUILD], [AS_IF([test "$8" != yes], + [AC_CACHE_CHECK([$1], [$2], + [CS_BUILD_IFELSE([$3], [$4], [$5], + [$2=yes + $2_cflags=$cs_build_cflags + $2_lflags=$cs_build_lflags + $2_libs=$cs_build_libs], + [$2=no], [$9], [$10], [$11], [$12], [$13])])], + [AC_MSG_CHECKING([$1]) + CS_BUILD_IFELSE([$3], [$4], [$5], + [$2=yes + $2_cflags=$cs_build_cflags + $2_lflags=$cs_build_lflags + $2_libs=$cs_build_libs], + [$2=no], [$9], [$10], [$11], [$12], [$13]) + AC_MSG_RESULT([$$2])]) + AS_IF([test $$2 = yes], [$6], + [$2_cflags='' + $2_lflags='' + $2_libs='' + $7])]) +m4trace:acinclude.m4:230: -1- AC_DEFUN([CS_CHECK_BUILD_FLAGS], [AC_CACHE_CHECK([$1], [$2_ok], + [CS_BUILD_IFELSE([], [$3], [$4], + [$2=CS_TRIM([$cs_build_cflags $cs_build_lflags $cs_build_libs]) + $2_ok="$$2"], + [$2='' + $2_ok=no], [$7], [$8], [$9], [Y], [$10])]) + AS_IF([test "$$2_ok" != no], [$5], [$6])]) +m4trace:acinclude.m4:281: -1- AC_DEFUN([CS_CHECK_COMMON_TOOLS_LINK], [ + # The default RANLIB in Jambase is wrong on some platforms, and is also + # unsuitable during cross-compilation, so we set the value unconditionally + # (sixth argument of CS_EMIT_BUILD_PROPERTY). + AC_PROG_RANLIB + CS_EMIT_BUILD_PROPERTY([RANLIB], [$RANLIB], [], [], [], [Y]) + + CS_CHECK_TOOLS([DLLTOOL], [dlltool]) + CS_EMIT_BUILD_PROPERTY([CMD.DLLTOOL], [$DLLTOOL]) + + CS_CHECK_TOOLS([DLLWRAP], [dllwrap]) + CS_EMIT_BUILD_PROPERTY([CMD.DLLWRAP], [$DLLWRAP]) + + CS_CHECK_TOOLS([WINDRES], [windres]) + CS_EMIT_BUILD_PROPERTY([CMD.WINDRES], [$WINDRES]) + + CS_CHECK_TOOLS([STRINGS], [strings]) + CS_EMIT_BUILD_PROPERTY([CMD.STRINGS], [$STRINGS]) + + CS_CHECK_TOOLS([OBJCOPY], [objcopy]) + CS_EMIT_BUILD_PROPERTY([CMD.OBJCOPY], [$OBJCOPY]) + + CS_CHECK_LIBTOOL + CS_EMIT_BUILD_PROPERTY([LIBTOOL], [$LIBTOOL]) + CS_EMIT_BUILD_PROPERTY([APPLE_LIBTOOL], [$APPLE_LIBTOOL]) + ]) +m4trace:acinclude.m4:294: -1- AC_DEFUN([CS_CHECK_COMMON_TOOLS_BASIC], [CS_CHECK_MKDIR + CS_EMIT_BUILD_PROPERTY([CMD.MKDIR], [$MKDIR]) + CS_EMIT_BUILD_PROPERTY([CMD.MKDIRS], [$MKDIRS]) + + CS_CHECK_PROGS([INSTALL], [install]) + CS_EMIT_BUILD_PROPERTY([INSTALL], [$INSTALL])]) +m4trace:acinclude.m4:315: -1- AC_DEFUN([CS_CHECK_COMMON_TOOLS_DOC_TEXINFO], [CS_CHECK_PROGS([TEXI2DVI], [texi2dvi]) + CS_EMIT_BUILD_PROPERTY([CMD.TEXI2DVI], [$TEXI2DVI]) + + CS_CHECK_PROGS([TEXI2PDF], [texi2pdf]) + CS_EMIT_BUILD_PROPERTY([CMD.TEXI2PDF], [$TEXI2PDF]) + + CS_CHECK_PROGS([DVIPS], [dvips]) + CS_EMIT_BUILD_PROPERTY([CMD.DVIPS], [$DVIPS]) + + CS_CHECK_PROGS([DVIPDF], [dvipdf]) + CS_EMIT_BUILD_PROPERTY([CMD.DVIPDF], [$DVIPDF]) + + CS_CHECK_PROGS([MAKEINFO], [makeinfo]) + CS_EMIT_BUILD_PROPERTY([CMD.MAKEINFO], [$MAKEINFO])]) +m4trace:acinclude.m4:327: -1- AC_DEFUN([CS_CHECK_COMMON_TOOLS_DOC_DOXYGEN], [CS_CHECK_PROGS([DOXYGEN], [doxygen]) + CS_EMIT_BUILD_PROPERTY([CMD.DOXYGEN], [$DOXYGEN]) + + CS_CHECK_TOOLS([DOT], [dot]) + CS_EMIT_BUILD_PROPERTY([CMD.DOT], [$DOT])]) +m4trace:acinclude.m4:341: -1- AC_DEFUN([CS_CHECK_COMMON_LIBS], [AC_LANG_PUSH([C]) + AC_CHECK_LIB([m], [pow], [cs_cv_libm_libs=-lm], [cs_cv_libm_libs=]) + AC_CHECK_LIB([m], [cosf], [cs_cv_libm_libs=-lm]) + AC_CHECK_LIB([mx], [cosf]) + AC_CHECK_LIB([dl], [dlopen], [cs_cv_libdl_libs=-ldl], [cs_cv_libdl_libs=]) + AC_CHECK_LIB([nsl], [gethostbyname]) + AC_LANG_POP([C])]) +m4trace:acinclude.m4:392: -1- AC_DEFUN([CS_CHECK_CPPUNIT], [CS_CHECK_LIB_WITH([cppunit], + [AC_LANG_PROGRAM([[#include ]], + [CppUnit::TextUi::TestRunner r; r.run();])], + [], [C++]) + + AS_IF([test $cs_cv_libcppunit = yes], + [CS_CHECK_BUILD([if cppunit is sufficiently recent], + [cs_cv_libcppunit_recent], + [AC_LANG_PROGRAM( + [[#include ]], + [CppUnit::BriefTestProgressListener b; b.startTest(0);])], + [], [C++], + [CS_EMIT_BUILD_RESULT([cs_cv_libcppunit], [CPPUNIT], + CS_EMITTER_OPTIONAL([$1]))], [], [], + [$cs_cv_libcppunit_cflags], + [$cs_cv_libcppunit_lflags], + [$cs_cv_libcppunit_libs])])]) +m4trace:acinclude.m4:550: -1- AC_DEFUN([CS_CHECK_LIB_WITH], [AC_ARG_WITH([$1], [AC_HELP_STRING([--with-$1=dir], + [specify location of lib$1 if not detected automatically; searches + dir/include, dir/lib, and dir])]) + + # Backward compatibility: Recognize --with-lib$1 as alias for --with-$1. + AS_IF([test -n "$with_lib$1" && test -z "$with_$1"], + [with_$1="$with_lib$1"]) + + AS_IF([test -z "$with_$1"], [with_$1=yes]) + AS_IF([test "$with_$1" != no], + [# If --with-$1 value is same as cached value, then assume other + # cached values are also valid; otherwise, ignore all cached values. + AS_IF([test "$with_$1" != "$cs_cv_with_$1"], + [cs_ignore_cache=yes], [cs_ignore_cache=no]) + + cs_check_lib_flags='' + AS_IF([test $with_$1 = yes], + [m4_foreach([cs_check_lib_alias], [$1, $10], + [_CS_CHECK_LIB_PKG_CONFIG_FLAGS([cs_check_lib_flags], + cs_check_lib_alias) + _CS_CHECK_LIB_CONFIG_FLAGS([cs_check_lib_flags], + cs_check_lib_alias) + ])]) + + AS_IF([test $with_$1 != yes], + [cs_check_lib_paths=$with_$1], + [cs_check_lib_paths="| cs_lib_paths_default $3"]) + m4_foreach([cs_check_lib_alias], [$1, $10], + [_CS_CHECK_LIB_CREATE_FLAGS([cs_check_lib_flags], + cs_check_lib_alias, [$cs_check_lib_paths]) + ]) + + CS_CHECK_BUILD([for lib$1], [cs_cv_lib$1], [$2], [$cs_check_lib_flags], + [$4], [], [], [$cs_ignore_cache], [$7], [$8], [$9])], + [cs_cv_lib$1=no]) + + cs_cv_with_$1="$with_$1" + AS_IF([test "$cs_cv_lib$1" = yes], [$5], [$6])]) +m4trace:acinclude.m4:574: -1- AC_DEFUN([CS_CHECK_PKG_CONFIG], [AS_IF([test "$cs_prog_pkg_config_checked" != yes], + [CS_CHECK_TOOLS([PKG_CONFIG], [pkg-config]) + _CS_CHECK_PKG_CONFIG_PREPARE_PATH + cs_prog_pkg_config_checked=yes]) + AS_IF([test -z "$cs_cv_prog_pkg_config_ok"], + [AS_IF([test -n "$PKG_CONFIG"], + [AS_IF([$PKG_CONFIG --atleast-pkgconfig-version=CS_PKG_CONFIG_MIN], + [cs_cv_prog_pkg_config_ok=yes], + [cs_cv_prog_pkg_config_ok=no])], + [cs_cv_prog_pkg_config_ok=no])])]) +m4trace:acinclude.m4:579: -1- AC_DEFUN([_CS_CHECK_PKG_CONFIG_PREPARE_PATH], [PKG_CONFIG_PATH="m4_foreach([cs_pkg_path], [cs_pkg_paths_default], + [cs_pkg_path$PATH_SEPARATOR])$PKG_CONFIG_PATH" + export PKG_CONFIG_PATH]) +m4trace:acinclude.m4:598: -1- AC_DEFUN([_CS_CHECK_LIB_PKG_CONFIG_FLAGS], [CS_CHECK_PKG_CONFIG + AS_IF([test $cs_cv_prog_pkg_config_ok = yes], + [AC_CACHE_CHECK([if $PKG_CONFIG recognizes $2], [_CS_CLPCF_CVAR([$2])], + [AS_IF([$PKG_CONFIG --exists $2], + [_CS_CLPCF_CVAR([$2])=yes], [_CS_CLPCF_CVAR([$2])=no])]) + AS_IF([test $_CS_CLPCF_CVAR([$2]) = yes], + [_CS_CHECK_LIB_CONFIG_PROG_FLAGS([$1], [pkg_config_$2], + [$PKG_CONFIG], [$2])])])]) +m4trace:acinclude.m4:600: -1- AC_DEFUN([_CS_CLPCF_CVAR], [AS_TR_SH([cs_cv_prog_pkg_config_$1])]) +m4trace:acinclude.m4:619: -1- AC_DEFUN([_CS_CHECK_LIB_CONFIG_FLAGS], [CS_CHECK_TOOLS(_CS_CLCF_SHVAR([$2]), [$2-config]) + AS_IF([test -n "$_CS_CLCF_SHVAR([$2])"], + [AS_IF([test -z "$_CS_CLCF_CVAR([$2])"], + [AS_IF([$_CS_CLCF_SHVAR([$2]) --cflags --libs >/dev/null 2>&1], + [_CS_CLCF_CVAR([$2])=yes], [_CS_CLCF_CVAR([$2])=no])]) + AS_IF([test $_CS_CLCF_CVAR([$2]) = yes], + [_CS_CHECK_LIB_CONFIG_PROG_FLAGS([$1], [config_$2], + [$_CS_CLCF_SHVAR([$2])])])])]) +m4trace:acinclude.m4:621: -1- AC_DEFUN([_CS_CLCF_CVAR], [AS_TR_SH([cs_cv_prog_config_$1_ok])]) +m4trace:acinclude.m4:622: -1- AC_DEFUN([_CS_CLCF_SHVAR], [m4_toupper(AS_TR_SH([CONFIG_$1]))]) +m4trace:acinclude.m4:648: -1- AC_DEFUN([_CS_CHECK_LIB_CONFIG_PROG_FLAGS], [AS_IF([test -z "$_CS_CLCPF_CVAR([$2])"], + [cs_check_lib_cflag=CS_RUN_PATH_NORMALIZE([$3 --cflags $4]) + cs_check_lib_lflag='' + cs_check_lib_libs=CS_RUN_PATH_NORMALIZE([$3 --libs $4]) + _CS_CLCPF_CVAR([$2])=CS_CREATE_TUPLE( + [$cs_check_lib_cflag], + [$cs_check_lib_lflag], + [$cs_check_lib_libs])]) + $1="$$1 $_CS_CLCPF_CVAR([$2])"]) +m4trace:acinclude.m4:650: -1- AC_DEFUN([_CS_CLCPF_CVAR], [AS_TR_SH([cs_cv_prog_$1_flags])]) +m4trace:acinclude.m4:676: -1- AC_DEFUN([_CS_CHECK_LIB_CREATE_FLAGS], [for cs_lib_item in $3 + do + case $cs_lib_item in + *\|*) CS_SPLIT( + [$cs_lib_item], [cs_check_incdir,cs_check_libdir], [|]) + _CS_CHECK_LIB_CREATE_FLAG([$1], + [$cs_check_incdir], [$cs_check_libdir], [$2]) + ;; + *) _CS_CHECK_LIB_CREATE_FLAG([$1], + [$cs_lib_item/include], [$cs_lib_item/lib], [$2]) + _CS_CHECK_LIB_CREATE_FLAG( + [$1], [$cs_lib_item], [$cs_lib_item], [$2]) + ;; + esac + done]) +m4trace:acinclude.m4:704: -1- AC_DEFUN([_CS_CHECK_LIB_CREATE_FLAG], [AS_IF([test -n "$2"], [cs_check_lib_cflag="-I$2"], [cs_check_lib_cflag='']) + AS_IF([test -n "$3"], [cs_check_lib_lflag="-L$3"], [cs_check_lib_lflag='']) + AS_IF([test -n "$4"], + [cs_check_lib_libs="-l$4" + cs_check_lib_framework="-framework $4"], + [cs_check_lib_libs='' + cs_check_lib_framework='']) + $1="$$1 + CS_CREATE_TUPLE( + [$cs_check_lib_cflag], + [$cs_check_lib_lflag], + [$cs_check_lib_framework]) + CS_CREATE_TUPLE( + [$cs_check_lib_cflag], + [$cs_check_lib_lflag], + [$cs_check_lib_libs])"]) +m4trace:acinclude.m4:760: -1- AC_DEFUN([CS_CHECK_LIBTOOL], [# GNU: Search for libtool before glibtool since Fink version is likely newer. +m4_define([cs_lt_path_gnu], + [/sw/bin$PATH_SEPARATOR/usr/local/bin$PATH_SEPARATOR$PATH]) +AS_IF([test -z "$LIBTOOL"], + [CS_CHECK_TOOLS([LIBTOOL_TEST], [libtool glibtool gnulibtool], [], + [cs_lt_path_gnu]) + AS_IF([test -n "$LIBTOOL_TEST"], + [CS_PATH_PROG([LIBTOOL_PATH], [$LIBTOOL_TEST], [], [cs_lt_path_gnu]) + CS_LIBTOOL_CLASSIFY([$LIBTOOL_PATH], + [LIBTOOL="$LIBTOOL_PATH"], + [AS_IF([test -z "$APPLE_LIBTOOL"], [APPLE_LIBTOOL="$LIBTOOL_PATH"]) + CS_CHECK_TOOLS([LIBTOOL], [glibtool gnulibtool])])])]) +AC_SUBST([LIBTOOL]) + +# Apple: Ensure that Apple libtool will be found before GNU libtool from Fink. +m4_define([cs_lt_path_apple],[/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH]) +AS_IF([test -z "$APPLE_LIBTOOL"], + [CS_PATH_PROG([CS_LT_APPLE], [libtool], [], [cs_lt_path_apple]) + CS_LIBTOOL_CLASSIFY([$CS_LT_APPLE], [], + [APPLE_LIBTOOL="$CS_LT_APPLE"])]) +AC_SUBST([APPLE_LIBTOOL])]) +m4trace:acinclude.m4:769: -1- AC_DEFUN([CS_LIBTOOL_CLASSIFY], [AS_IF([test -n "$1"], + [AC_MSG_CHECKING([classification of $1]) + CS_LIBTOOL_GNU_IFELSE([$1], + [AC_MSG_RESULT([gnu]) + $2], + [AC_MSG_RESULT([apple]) + $3])])]) +m4trace:acinclude.m4:772: -1- AC_DEFUN([CS_LIBTOOL_GNU_IFELSE], [AS_IF([AC_RUN_LOG([$1 --version 1>&2])], [$2], [$3])]) +m4trace:acinclude.m4:846: -1- AC_DEFUN([CS_GL_INCLUDE], [[#if HAVE_WINDOWS_H + #if !HAVE_TYPE_INT32 + typedef long int32; + #endif + #include + #endif + #ifndef CS_HEADER_GLOBAL + #define CS_HEADER_GLOBAL(X,Y) CS_HEADER_GLOBAL_COMPOSE(X,Y) + #define CS_HEADER_GLOBAL_COMPOSE(X,Y) + #endif + #ifdef $1 + #include CS_HEADER_GLOBAL($1,$3) + #else + #include <$2/$3> + #endif]]) +m4trace:acinclude.m4:903: -1- AC_DEFUN([CS_CHECK_OPENGL], [AC_REQUIRE([CS_CHECK_HOST]) + AC_REQUIRE([CS_CHECK_COMMON_LIBS]) + AC_REQUIRE([CS_CHECK_PTHREAD]) + AC_REQUIRE([AC_PATH_X]) + AC_REQUIRE([AC_PATH_XTRA]) + AC_CHECK_TYPE([int32], [AC_DEFINE([HAVE_TYPE_INT32], [], + [Whether the int32 type is available])], []) + AC_CHECK_HEADERS([windows.h], [], [], [cs_define_int32]) + + # Apply plaform-specific flags if necessary. + cs_gl_plat_cflags='' + cs_gl_plat_lflags='' + cs_gl_plat_libs='' + AS_IF([test -n "$cs_cv_libm_cflags$cs_cv_libm_lflags$cs_cv_libm_libs"], + [cs_gl_plat_cflags="$cs_cv_libm_cflags $cs_gl_plat_cflags" + cs_gl_plat_lflags="$cs_cv_libm_lflags $cs_gl_plat_lflags" + cs_gl_plat_libs="$cs_cv_libm_libs $cs_gl_plat_libs"]) + AS_IF([test $cs_cv_sys_pthread = yes], + [cs_gl_plat_cflags="$cs_cv_sys_pthread_cflags $cs_gl_plat_cflags" + cs_gl_plat_lflags="$cs_cv_sys_pthread_lflags $cs_gl_plat_lflags" + cs_gl_plat_libs="$cs_cv_sys_pthread_libs $cs_gl_plat_libs"]) + AS_IF([test "$no_x" != yes], + [cs_gl_plat_cflags="$X_CFLAGS $cs_gl_plat_cflags" + cs_gl_plat_lflags="$cs_gl_plat_lflags" + cs_gl_plat_libs=" + $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS $cs_gl_plat_libs"]) + + # Mesa requested? + AC_ARG_WITH([mesa], [AC_HELP_STRING([--with-mesa], + [use Mesa OpenGL library if available (default YES)])], + [], [with_mesa=yes]) + + AS_IF([test $with_mesa != no], + [cs_mesa_gl=CS_CREATE_TUPLE([],[],[-lMesaGL])]) + + # MacOS/X or Darwin? + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_osx_gl=CS_CREATE_TUPLE([-DCS_OPENGL_PATH=OpenGL],[],[-framework OpenGL])]) + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_gl_plat_lflags="$cs_plat_lflags -Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"]) + + # Windows? + AS_IF([test $cs_host_family = windows], + [cs_win32_gl=CS_CREATE_TUPLE([],[],[-lopengl32])]) + + # Check for OpenGL. + CS_CHECK_BUILD([for OpenGL], [cs_cv_libgl], + [AC_LANG_PROGRAM([CS_GL_INCLUDE([CS_OPENGL_PATH],[GL],[gl.h])],[glEnd()])], + [$cs_win32_gl \ + $cs_osx_gl \ + CS_CREATE_TUPLE([],[],[-lGL]) \ + CS_CREATE_TUPLE([],[],[-lgl]) \ + $cs_mesa_gl], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libgl], [GL])], [], [], + [$cs_gl_plat_cflags], [$cs_gl_plat_lflags], [$cs_gl_plat_libs])]) +m4trace:acinclude.m4:935: -1- AC_DEFUN([CS_CHECK_GLU], [AC_REQUIRE([CS_CHECK_OPENGL]) + AS_IF([test $cs_cv_libgl = yes], + [AS_IF([test $with_mesa != no], + [cs_mesa_glu=CS_CREATE_TUPLE([],[],[-lMesaGLU])]) + + # MacOS/X or Darwin? + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_osx_glu=CS_CREATE_TUPLE([-DCS_GLU_PATH=OpenGL],[],[-framework OpenGL])]) + + # Windows? + AS_IF([test $cs_host_family = windows], + [cs_win32_glu=CS_CREATE_TUPLE([],[],[-lglu32])]) + + # Check for GLU. + CS_CHECK_BUILD([for GLU], [cs_cv_libglu], + [AC_LANG_PROGRAM( + [CS_GL_INCLUDE([CS_GLU_PATH],[GL],[glu.h])], [gluNewQuadric()])], + [$cs_osx_glu \ + CS_CREATE_TUPLE() \ + $cs_win32_glu \ + CS_CREATE_TUPLE([],[],[-lGLU]) \ + CS_CREATE_TUPLE([],[],[-lglu]) \ + $cs_mesa_glu], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libglu], [GLU])], [], [], + [$cs_cv_libgl_cflags], [$cs_cv_libgl_lflags], [$cs_cv_libgl_libs])])]) +m4trace:acinclude.m4:957: -1- AC_DEFUN([CS_CHECK_GLX], [AC_REQUIRE([CS_CHECK_OPENGL]) + AS_IF([test $cs_cv_libgl = yes], + [AS_IF([test $with_mesa != no], + [cs_mesa_glx=CS_CREATE_TUPLE([],[],[-lMesaGLX])]) + + # Check for GLX. + AS_IF([test "$no_x" != yes], + [CS_CHECK_BUILD([for GLX], [cs_cv_libglx], + [AC_LANG_PROGRAM([[#include ]], [glXWaitGL()])], + [CS_CREATE_TUPLE() \ + CS_CREATE_TUPLE([],[],[-lGLX]) \ + CS_CREATE_TUPLE([],[],[-lglx]) \ + $cs_mesa_glx], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libglx], [GLX])], [], [], + [$cs_cv_libgl_cflags], [$cs_cv_libgl_lflags], [$cs_cv_libgl_libs])])])]) +m4trace:acinclude.m4:977: -1- AC_DEFUN([CS_CHECK_GLXEXT], [AC_REQUIRE([CS_CHECK_GLX]) + AS_IF([test x$cs_cv_libglx = "xyes"], + [# Check for GLX extensions. + CS_CHECK_BUILD([for GLX extensions], [cs_cv_libglx_extensions], + [AC_LANG_PROGRAM( + [[#define GLX_GLXEXT_PROTOTYPES + #include ]], + [glXGetProcAddressARB(0)])], + [CS_CREATE_TUPLE( + [$cs_cv_libglx_cflags], + [$cs_cv_libglx_lflags], + [$cs_cv_libglx_libs])], + [], [$1], [$2])])]) +m4trace:acinclude.m4:1008: -1- AC_DEFUN([CS_CHECK_GLUT], [AC_REQUIRE([CS_CHECK_GLU]) + AS_IF([test x$cs_cv_libglu = "xyes"], + [# MacOS/X or Darwin? + AS_IF([test "x$cs_host_macosx" = "xyes"], + [cs_osx_glut=CS_CREATE_TUPLE([-DCS_GLUT_PATH=GLUT],[],[-framework GLUT])]) + + # Windows? + AS_IF([test $cs_host_family = windows], + [cs_win32_glut=CS_CREATE_TUPLE([],[],[-lglut32])]) + + # Check for GLUT. + CS_CHECK_BUILD([for GLUT], [cs_cv_libglut], + [AC_LANG_PROGRAM( + [CS_GL_INCLUDE([CS_GLUT_PATH],[GL],[glut.h])], [glutSwapBuffers()])], + [$cs_osx_glut \ + CS_CREATE_TUPLE() \ + $cs_win32_glut \ + CS_CREATE_TUPLE([],[],[-lGLUT]) \ + CS_CREATE_TUPLE([],[],[-lglut])], [], + [CS_EMIT_BUILD_RESULT([cs_cv_libglut], [GLUT])], [], [], + [$cs_cv_libgl_cflags $cs_cv_libglu_cflags], + [$cs_cv_libgl_lflags $cs_cv_libglu_lflags], + [$cs_cv_libgl_libs $cs_cv_libglu_libs])])]) +m4trace:acinclude.m4:1065: -1- AC_DEFUN([CS_COMPILER_PIC], [CS_COMPILER_ERRORS([$1], + [m4_default([$2_werror],[cs_cv_prog_compiler_pic_werror])]) + CS_CHECK_BUILD_FLAGS( + [how to enable m4_default([$1],[C]) PIC generation], + [m4_default([$2],[cs_cv_prog_compiler_pic])], + [CS_CREATE_TUPLE([-fPIC])], [$1], [$3], [$4], + [m4_default([$$2_werror],[$cs_cv_prog_compiler_pic_werror])], [], [], + [fPIC])]) +m4trace:acinclude.m4:1068: -1- AC_DEFUN([CS_CHECK_COMPILER_PIC], [CS_COMPILER_PIC([$1],[$2],[$3],[$4])]) +m4trace:acinclude.m4:1113: -1- AC_DEFUN([CS_CHECK_PROG], [_CS_PROG_PATH_PREPARE + AC_CHECK_PROG([$1], [$2], [$3], [$4], + m4_ifval([$5], [_CS_PROG_CLIENT_PATH([$5])]), [$6])]) +m4trace:acinclude.m4:1124: -1- AC_DEFUN([CS_CHECK_PROGS], [_CS_PROG_PATH_PREPARE + AC_CHECK_PROGS([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) +m4trace:acinclude.m4:1135: -1- AC_DEFUN([CS_CHECK_TOOL], [_CS_PROG_PATH_PREPARE + AC_CHECK_TOOL([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) +m4trace:acinclude.m4:1146: -1- AC_DEFUN([CS_CHECK_TOOLS], [_CS_PROG_PATH_PREPARE + AC_CHECK_TOOLS([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) +m4trace:acinclude.m4:1157: -1- AC_DEFUN([CS_PATH_PROG], [_CS_PROG_PATH_PREPARE + AC_PATH_PROG([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) +m4trace:acinclude.m4:1168: -1- AC_DEFUN([CS_PATH_PROGS], [_CS_PROG_PATH_PREPARE + AC_PATH_PROGS([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) +m4trace:acinclude.m4:1179: -1- AC_DEFUN([CS_PATH_TOOL], [_CS_PROG_PATH_PREPARE + AC_PATH_TOOL([$1], [$2], [$3], + m4_ifval([$4], [_CS_PROG_CLIENT_PATH([$4])]))]) +m4trace:acinclude.m4:1195: -1- AC_DEFUN([_CS_PROG_PATH_PREPARE], [AS_REQUIRE([_AS_PATH_SEPARATOR_PREPARE]) + AS_IF([test "$cs_prog_path_prepared" != yes], + [cs_prog_path_prepared=yes + PATH="$PATH[]m4_foreach([cs_bin_path], [cs_bin_paths_default], + [$PATH_SEPARATOR[]cs_bin_path])" + export PATH])]) +m4trace:acinclude.m4:1206: -1- AC_DEFUN([_CS_PROG_CLIENT_PATH], [AS_REQUIRE([_AS_PATH_SEPARATOR_PREPARE])dnl + $1[]m4_foreach([cs_bin_path], [cs_bin_paths_default], + [$PATH_SEPARATOR[]cs_bin_path])]) +m4trace:acinclude.m4:1281: -1- AC_DEFUN([CS_CHECK_PTHREAD], [AC_REQUIRE([AC_CANONICAL_HOST]) + case $host_os in + m4_ifval([$1], + [$1) + cs_cv_sys_pthread=no + ;; + ]) + *) + CS_CHECK_BUILD([for pthread], [cs_cv_sys_pthread], + [AC_LANG_PROGRAM( + [[#include + #include + void* worker(void* p) { (void)p; return p; }]], + [pthread_t tid; + sem_t sem; + pthread_create(&tid, 0, worker, 0); + sem_init(&sem, 0, 0); + sem_destroy(&sem);])], + [cs_pthread_flags]) + ;; + esac + _CS_CHECK_MUTEX_FEATURE([PTHREAD_MUTEX_RECURSIVE], + [cs_cv_sys_pthread_mutex_recursive], [for pthread recursive mutexes])]) +m4trace:acinclude.m4:1300: -1- AC_DEFUN([_CS_CHECK_MUTEX_FEATURE], [AS_IF([test $cs_cv_sys_pthread = yes], + [AC_CACHE_CHECK([$3], [$2], + [CS_BUILD_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [pthread_mutexattr_t attr; + pthread_mutexattr_settype(&attr, CS_MUTEX_FEATURE);])], + [CS_CREATE_TUPLE([-DCS_MUTEX_FEATURE=$1]) \ + CS_CREATE_TUPLE([-DCS_MUTEX_FEATURE=$1_NP])], + [], + [$2=`echo $cs_build_cflags | sed 's/.*\($1_*N*P*\).*/\1/'`], + [$2=no], + [$cs_cv_sys_pthread_cflags -D_GNU_SOURCE], + [$cs_cv_sys_pthread_lflags], + [$cs_cv_sys_pthread_libs])])], + [$2=no])]) +m4trace:acinclude.m4:1319: -1- AC_DEFUN([CS_CHECK_PTHREAD_ATFORK], [AS_IF([test $cs_cv_sys_pthread = yes], + [AC_CACHE_CHECK([for pthread_atfork support], [$1], + [CS_BUILD_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [pthread_atfork (0, 0, 0);])], + [], [], + [$1=yes], [$1=no], + [$cs_cv_sys_pthread_cflags -D_GNU_SOURCE], + [$cs_cv_sys_pthread_lflags], + [$cs_cv_sys_pthread_libs])])], + [$1=no])]) +m4trace:acinclude.m4:1372: -1- AC_DEFUN([CS_CHECK_TEMPLATE_TOOLKIT2], [CS_CHECK_PROGS([PERL], [perl5 perl]) + AS_IF([test -n "$PERL"], + [AC_CACHE_CHECK([for TemplateToolkit], [cs_cv_perl_tt2], + [AS_IF([AC_RUN_LOG( + [$PERL -M'Template 2.11' -MTemplate::Plugin -e 0 1>&2])], + [cs_cv_perl_tt2=yes], + [cs_cv_perl_tt2=no])]) + CS_PATH_PROGS([TTREE], [ttree]) + AS_IF([test $cs_cv_perl_tt2 = yes && test -n "$TTREE"], + [CS_EMIT_BUILD_PROPERTY([TTREE], [$TTREE], [], [], + CS_EMITTER_OPTIONAL([$1]))])])]) +m4trace:acinclude.m4:1427: -1- AC_DEFUN([CS_PROG_CC], [ + CFLAGS="$CFLAGS" # Filter undesired flags + AS_IF([test -n "$CC"],[ + CS_EMIT_BUILD_PROPERTY([CMD.CC], [$CC]) + CS_EMIT_BUILD_PROPERTY([COMPILER.CFLAGS], [$CPPFLAGS $CFLAGS], [+]) + + # Check if compiler recognizes -pipe directive. + CS_EMIT_BUILD_FLAGS([if $CC accepts -pipe], [cs_cv_prog_cc_pipe], + [CS_CREATE_TUPLE([-pipe])], [C], [COMPILER.CFLAGS], [+]) + ]) +]) +m4trace:acinclude.m4:1443: -1- AC_DEFUN([CS_PROG_CXX], [ + CXXFLAGS="$CXXFLAGS" # Filter undesired flags + AS_IF([test -n "$CXX"],[ + CS_EMIT_BUILD_PROPERTY([CMD.C++], [$CXX]) + + CS_EMIT_BUILD_PROPERTY([COMPILER.C++FLAGS], [$CPPFLAGS $CXXFLAGS], [+]) + + # Check if compiler can be instructed to produce position-independent-code + # (PIC). This feature is required by some platforms when building plugin + # modules and shared libraries. + CS_COMPILER_PIC([C++], [cs_cv_prog_cxx_pic], + [CS_EMIT_BUILD_PROPERTY([COMPILER.C++FLAGS.PIC], + [$cs_cv_prog_cxx_pic])]) + ]) +]) +m4trace:acinclude.m4:1470: -1- AC_DEFUN([CS_PROG_LINK], [ + AC_REQUIRE([CS_PROG_CXX]) + AS_IF([test -n "$CXX"], + [CS_EMIT_BUILD_PROPERTY([CMD.LINK], [AS_ESCAPE([$(CMD.C++)])])], + [CS_EMIT_BUILD_PROPERTY([CMD.LINK], [AS_ESCAPE([$(CMD.CC)])])]) + + CS_EMIT_BUILD_PROPERTY([COMPILER.LFLAGS], [$LDFLAGS], [+]) + + # Check if compiler/linker recognizes -shared directive which is needed for + # linking plugin modules. Unfortunately, the Apple compiler (and possibly + # others) requires extra effort. Even though the compiler does not recognize + # the -shared option, it nevertheless returns a "success" result after emitting + # the warning "unrecognized option `-shared'". Worse, even -Werror fails to + # promote the warning to an error, so we must instead scan the compiler's + # output for an appropriate diagnostic. + CS_CHECK_BUILD_FLAGS([if -shared is accepted], [cs_cv_prog_link_shared], + [CS_CREATE_TUPLE([-shared $cs_cv_prog_cxx_pic])], [C++], + [CS_EMIT_BUILD_PROPERTY([PLUGIN.LFLAGS], [-shared], [+])], [], + [], [], [], [shared]) + + # Check if linker recognizes -soname which is used to assign a name internally + # to plugin modules. + CS_CHECK_BUILD([if -soname is accepted], [cs_cv_prog_link_soname], [], + [CS_CREATE_TUPLE([-Wl,-soname,foobar])], [C++], + [CS_EMIT_BUILD_PROPERTY([PLUGIN.LFLAGS.USE_SONAME], [yes])]) +]) +m4trace:acinclude.m4:1511: -1- AC_DEFUN([CS_CHECK_HOST_CPU], [AC_REQUIRE([AC_CANONICAL_HOST]) + case $host_cpu in + [[Ii][3-9]86*|[Xx]86*]) cs_host_cpu=x86 ;; + *) cs_host_cpu=$host_cpu ;; + esac + cs_host_cpu_normalized="AS_TR_CPP([$cs_host_cpu])" + CS_JAMCONFIG_PROPERTY([TARGET.PROCESSOR], [$cs_host_cpu_normalized]) + ]) +m4trace:acinclude.m4:1558: -1- AC_DEFUN([CS_CHECK_HOST], [AC_REQUIRE([AC_CANONICAL_HOST]) + CS_CHECK_HOST_CPU + cs_host_os_normalized='' + case $host_os in + mingw*|cygwin*) + cs_host_target=win32gcc + cs_host_family=windows + ;; + darwin*) + _CS_CHECK_HOST_DARWIN + ;; + *) + # Everything else is assumed to be Unix or Unix-like. + cs_host_target=unix + cs_host_family=unix + ;; + esac + + case $cs_host_family in + windows) + AC_DEFINE([CS_PLATFORM_WIN32], [], + [Define when compiling for Win32]) + AS_IF([test -z "$cs_host_os_normalized"], + [cs_host_os_normalized='Win32']) + ;; + unix) + AC_DEFINE([CS_PLATFORM_UNIX], [], + [Define when compiling for Unix and Unix-like (i.e. MacOS/X)]) + AS_IF([test -z "$cs_host_os_normalized"], + [cs_host_os_normalized='Unix']) + ;; + esac + + cs_host_os_normalized_uc="AS_TR_CPP([$cs_host_os_normalized])" + CS_JAMCONFIG_PROPERTY([TARGET.OS], [$cs_host_os_normalized_uc]) + CS_JAMCONFIG_PROPERTY([TARGET.OS.NORMALIZED], [$cs_host_os_normalized]) +]) +m4trace:acinclude.m4:1614: -1- AC_DEFUN([_CS_CHECK_HOST_DARWIN], [AC_REQUIRE([CS_PROG_CC]) + AC_REQUIRE([CS_PROG_CXX]) + + # Both MacOS/X and Darwin are identified via $host_os as "darwin". We need + # a way to distinguish between the two. If Carbon.h is present, then + # assume MacOX/S; if not, assume Darwin. If --with-x=yes was invoked, and + # Carbon.h is present, then assume that user wants to cross-build for + # Darwin even though build host is MacOS/X. + # IMPLEMENTATION NOTE *1* + # The QuickTime 7.0 installer removes , which + # causes #include to fail unconditionally. Re-installing + # the QuickTime SDK should restore the header, however not all developers + # know to do this, so we work around the problem of the missing + # CarbonSound.h by #defining __CARBONSOUND__ in the test in order to + # prevent Carbon.h from attempting to #include the missing header. + # IMPLEMENTATION NOTE *2* + # At least one MacOS/X user switches between gcc 2.95 and gcc 3.3 with a + # script which toggles the values of CC, CXX, and CPP. Unfortunately, CPP + # was being set to run the preprocessor directly ("cpp", for instance) + # rather than running it via the compiler ("gcc -E", for instance). The + # problem with running the preprocessor directly is that __APPLE__ and + # __GNUC__ are not defined, which causes the Carbon.h check to fail. We + # avoid this problem by supplying a non-empty fourth argument to + # AC_CHECK_HEADER(), which causes it to test compile the header only (which + # is a more robust test), rather than also testing it via the preprocessor. + + AC_DEFINE([__CARBONSOUND__], [], + [Avoid problem caused by missing ]) + AC_CHECK_HEADER([Carbon/Carbon.h], + [cs_host_macosx=yes], [cs_host_macosx=no], [/* force compile */]) + + AS_IF([test $cs_host_macosx = yes], + [AC_MSG_CHECKING([for --with-x]) + AS_IF([test "${with_x+set}" = set && test "$with_x" = "yes"], + [AC_MSG_RESULT([yes (assume Darwin)]) + cs_host_macosx=no], + [AC_MSG_RESULT([no])])]) + + AS_IF([test $cs_host_macosx = yes], + [cs_host_target=macosx + cs_host_family=unix + cs_host_os_normalized='MacOS/X' + AC_DEFINE([CS_PLATFORM_MACOSX], [], + [Define when compiling for MacOS/X]) + + AC_CACHE_CHECK([for Objective-C compiler], [cs_cv_prog_objc], + [cs_cv_prog_objc="$CC"]) + CS_JAMCONFIG_PROPERTY([CMD.OBJC], [$cs_cv_prog_objc]) + AC_CACHE_CHECK([for Objective-C++ compiler], [cs_cv_prog_objcxx], + [cs_cv_prog_objcxx="$CXX"]) + CS_JAMCONFIG_PROPERTY([CMD.OBJC++], [$cs_cv_prog_objcxx])], + + [cs_host_target=unix + cs_host_family=unix])]) +m4trace:acinclude.m4:1645: -1- AC_DEFUN([CS_MSG_ERROR], [AC_CACHE_SAVE + AC_MSG_ERROR([$1], [$2])]) +m4trace:acinclude.m4:1735: -1- AC_DEFUN([CS_META_INFO_EMBED], [AC_REQUIRE([AC_CANONICAL_HOST]) + _CS_META_INFO_EMBED_ENABLE([$1], [$2]) + AS_IF([test $enable_meta_info_embedding = yes], + [_CS_META_INFO_EMBED_TOOLS([$1]) + AS_IF([test $cs_header_elf_h = yes], + [CS_EMIT_BUILD_PROPERTY([ELF.AVAILABLE], [yes], [], [], + CS_EMITTER_OPTIONAL([$1]))], + [case $host_os in + mingw*|cygwin*) ;; + *) + CS_CHECK_LIBBFD([$1], + [CS_EMIT_BUILD_PROPERTY([EMBED_META.CFLAGS], + [$cs_cv_libbfd_ok_cflags], [+], [], + CS_EMITTER_OPTIONAL([$1])) + CS_EMIT_BUILD_PROPERTY([EMBED_META.LFLAGS], + [$cs_cv_libbfd_ok_lflags $cs_cv_libbfd_ok_libs], + [+], [], CS_EMITTER_OPTIONAL([$1]))]) + ;; + esac])])]) +m4trace:acinclude.m4:1777: -1- AC_DEFUN([_CS_META_INFO_EMBED_ENABLE], [AC_REQUIRE([CS_CHECK_HOST]) + AC_CHECK_HEADERS([elf.h], [cs_header_elf_h=yes], [cs_header_elf_h=no]) + AC_MSG_CHECKING([whether to embed plugin meta-information]) + case $cs_host_target in + unix) AS_IF([test $cs_header_elf_h = yes], + [cs_embed_meta_info_default=yes], + [cs_embed_meta_info_default=m4_ifval([$2],[$2],[no])]) ;; + *) cs_embed_meta_info_default=yes ;; + esac + AC_ARG_ENABLE([meta-info-embedding], + [AC_HELP_STRING([--enable-meta-info-embedding], + [store plugin meta-information directly inside plugin modules if + supported by platform; if disabled, meta-information is stored in + stand-alone .csplugin files; this option is enabled by default for + non-Unix platforms and on Unix platforms with ELF-format object + files; it is disabled by default on Unix platforms if ELF is not + available and the project uses a non-GPL-compatible license (such + as LGPL) since the non-ELF Unix embedding technology requires the + GPL-licensed libbfd library; if ELF is not available, enable this + option on Unix only if you are certain you want a GPL-licensed + library infecting your project])], + [], [enable_meta_info_embedding=$cs_embed_meta_info_default]) + AC_MSG_RESULT([$enable_meta_info_embedding]) + CS_EMIT_BUILD_PROPERTY([EMBED_META], [$enable_meta_info_embedding], + [], [], CS_EMITTER_OPTIONAL([$1]))]) +m4trace:acinclude.m4:1796: -1- AC_DEFUN([_CS_META_INFO_EMBED_TOOLS], [CS_CHECK_TOOLS([WINDRES], [windres]) + CS_EMIT_BUILD_PROPERTY([CMD.WINDRES], [$WINDRES], [], [], + CS_EMITTER_OPTIONAL([$1])) + + CS_CHECK_TOOLS([OBJCOPY], [objcopy]) + AS_IF([test -n "$OBJCOPY"], + [CS_EMIT_BUILD_PROPERTY([OBJCOPY.AVAILABLE], [yes], [], [], + CS_EMITTER_OPTIONAL([$1])) + CS_EMIT_BUILD_PROPERTY([CMD.OBJCOPY], [$OBJCOPY], [], [], + CS_EMITTER_OPTIONAL([$1]))])]) +m4trace:acinclude.m4:1867: -1- AC_DEFUN([CS_CHECK_LIBBFD], [CS_CHECK_LIB_WITH([bfd], + [AC_LANG_PROGRAM([[#include ]], [bfd_init();])], + [], [], [], [], [], [], [-liberty]) + + AS_IF([test $cs_cv_libbfd = yes], + [CS_CHECK_BUILD([if libbfd is usable], [cs_cv_libbfd_ok], + [AC_LANG_PROGRAM([[#include ]], + [bfd* p; + asection* s; + bfd_init(); + p = bfd_openr(0,0); + bfd_check_format(p,bfd_object); + bfd_get_section_by_name(p,0); + bfd_section_size(p,s); + bfd_get_section_contents(p,s,0,0,0); + bfd_close(p);])], + [CS_CREATE_TUPLE() CS_CREATE_TUPLE([],[-L/usr/lib],[])], + [], [], [], [], + [$cs_cv_libbfd_cflags], + [$cs_cv_libbfd_lflags], + [$cs_cv_libbfd_libs])], + [cs_cv_libbfd_ok=no]) + + AS_IF([test $cs_cv_libbfd_ok = yes], + [CS_EMIT_BUILD_RESULT([cs_cv_libbfd_ok], [LIBBFD], + CS_EMITTER_OPTIONAL([$1])) + $2], + [$3])]) +m4trace:acinclude.m4:1916: -1- AC_DEFUN([CS_EMIT_BUILD_PROPERTY], [cs_build_prop_val="$2" + cs_build_prop_val=CS_TRIM([$cs_build_prop_val]) + m4_ifval([$4], + [CS_JAMCONFIG_PROPERTY([$1], [$cs_build_prop_val], [$3])], + AS_IF([test -n "$cs_build_prop_val"], + [m4_default([$5],[CS_JAMCONFIG_PROPERTY])( + [$1], [$cs_build_prop_val], [$3], [$6])]))]) +m4trace:acinclude.m4:1939: -1- AC_DEFUN([CS_EMIT_BUILD_RESULT], [AS_IF([test "$$1" = yes], + [CS_EMIT_BUILD_PROPERTY([$2.AVAILABLE], [yes], [], [], [$3]) + CS_EMIT_BUILD_PROPERTY([$2.CFLAGS], [$$1_cflags], [], [], [$3]) + CS_EMIT_BUILD_PROPERTY([$2.LFLAGS], [$$1_lflags $$1_libs], + [], [], [$3])])]) +m4trace:acinclude.m4:1972: -1- AC_DEFUN([CS_EMIT_BUILD_FLAGS], [CS_CHECK_BUILD_FLAGS([$1], [$2], [$3], [$4], + [CS_EMIT_BUILD_PROPERTY([$5], [$$2], [$6], [], [$9]) + $7], + [$8])]) +m4trace:acinclude.m4:2000: -1- AC_DEFUN([CS_EMITTER_OPTIONAL], [m4_case([$1], + [], [[CS_NULL_EMITTER]], + [emit], [], + [yes], [], + [[$1]])]) +m4trace:acinclude.m4:2010: -1- AC_DEFUN([CS_NULL_EMITTER], [: +]) +m4trace:acinclude.m4:2025: -1- AC_DEFUN([CS_SUBST_EMITTER], [AC_SUBST(AS_TR_SH([$1]),[$2])]) +m4trace:acinclude.m4:2039: -1- AC_DEFUN([CS_DEFINE_EMITTER], [AC_DEFINE_UNQUOTED(AS_TR_CPP([$1]),[$2], + [Define when feature is available])]) +m4trace:acinclude.m4:2082: -1- AC_DEFUN([CS_HEADER_APPEND], [CS_TEXT_CACHE_APPEND([cs_header_text], [$1])]) +m4trace:acinclude.m4:2083: -1- AC_DEFUN([CS_HEADER_PREPEND], [CS_TEXT_CACHE_PREPEND([cs_header_text], [$1])]) +m4trace:acinclude.m4:2086: -1- AC_DEFUN([CS_HEADER_PROPERTY], [CS_HEADER_APPEND([@%:@define $1[]m4_ifval([$2], [ $2], []) +])]) +m4trace:acinclude.m4:2087: -1- AC_DEFUN([CS_HEADER_OUTPUT], [CS_TEXT_CACHE_OUTPUT([cs_header_text], [$1])]) +m4trace:acinclude.m4:2172: -1- AC_DEFUN([CS_OUTPUT_INSTALLDIRS], [ +# Handle the case when no prefix is given, and the special case when a path +# contains more than 2 slashes, these paths seem to be correct but Jam fails +# on them. +AS_IF([test $prefix = NONE], + [cs_install_prefix="$ac_default_prefix"], + [cs_install_prefix=`echo "$prefix" | sed -e 's:///*:/:g'`]) +AS_IF([test $exec_prefix = NONE], + [cs_install_exec_prefix="AS_ESCAPE([$(prefix)])"], + [cs_install_exec_prefix=`echo "$exec_prefix" | sed -e 's:///*:/:g'`]) + +_CS_OUTPUT_INSTALL_DIRS([$1], [prefix], + [CS_PREPARE_INSTALLPATH([$cs_install_prefix], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [exec_prefix], + [CS_PREPARE_INSTALLPATH([$cs_install_exec_prefix], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [bindir], + [CS_PREPARE_INSTALLPATH([$bindir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [sbindir], + [CS_PREPARE_INSTALLPATH([$sbindir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [libexecdir], + [CS_PREPARE_INSTALLPATH([$libexecdir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [datadir], + [CS_PREPARE_INSTALLPATH([$datadir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [sysconfdir], + [CS_PREPARE_INSTALLPATH([$sysconfdir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [sharedstatedir], + [CS_PREPARE_INSTALLPATH([$sharedstatedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [localstatedir], + [CS_PREPARE_INSTALLPATH([$localstatedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [libdir], + [CS_PREPARE_INSTALLPATH([$libdir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [includedir], + [CS_PREPARE_INSTALLPATH([$includedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [oldincludedir], + [CS_PREPARE_INSTALLPATH([$oldincludedir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [infodir], + [CS_PREPARE_INSTALLPATH([$infodir], [$2])]) +_CS_OUTPUT_INSTALL_DIRS([$1], [mandir], + [CS_PREPARE_INSTALLPATH([$mandir], [$2])]) +]) +m4trace:acinclude.m4:2175: -1- AC_DEFUN([_CS_OUTPUT_INSTALL_DIRS], [m4_default([$1], [CS_JAMCONFIG_PROPERTY])([$2], [$3])]) +m4trace:acinclude.m4:2187: -1- AC_DEFUN([CS_PREPARE_INSTALLPATH], [`echo "$1" | sed 's/\${\([[a-zA-Z_][a-zA-Z_]]*\)}/$(\1)/g;m4_ifval([$2], + [s/\\/\\\\/g], [s/\\\\/\\\\\\\\/g])'`]) +m4trace:acinclude.m4:2237: -1- AC_DEFUN([CS_JAMCONFIG_APPEND], [CS_TEXT_CACHE_APPEND([cs_jamconfig_text], [$1])]) +m4trace:acinclude.m4:2239: -1- AC_DEFUN([CS_JAMCONFIG_PREPEND], [CS_TEXT_CACHE_PREPEND([cs_jamconfig_text], [$1])]) +m4trace:acinclude.m4:2243: -1- AC_DEFUN([CS_JAMCONFIG_PROPERTY], [CS_JAMCONFIG_APPEND( + [$1 m4_ifval([$3], [+=], m4_ifval([$4], [=], [?=])) \"$2\" ; +])]) +m4trace:acinclude.m4:2245: -1- AC_DEFUN([CS_JAMCONFIG_OUTPUT], [CS_TEXT_CACHE_OUTPUT([cs_jamconfig_text], [$1])]) +m4trace:acinclude.m4:2292: -1- AC_DEFUN([CS_MAKEFILE_APPEND], [CS_TEXT_CACHE_APPEND([cs_makefile_text], [$1])]) +m4trace:acinclude.m4:2294: -1- AC_DEFUN([CS_MAKEFILE_PREPEND], [CS_TEXT_CACHE_PREPEND([cs_makefile_text], [$1])]) +m4trace:acinclude.m4:2297: -1- AC_DEFUN([CS_MAKEFILE_PROPERTY], [CS_MAKEFILE_APPEND([$1 m4_ifval([$3], [+=], [=]) $2 +])]) +m4trace:acinclude.m4:2298: -1- AC_DEFUN([CS_MAKEFILE_OUTPUT], [CS_TEXT_CACHE_OUTPUT([cs_makefile_text], [$1])]) +m4trace:acinclude.m4:2349: -1- AC_DEFUN([CS_CHECK_MKDIR], [AC_CACHE_CHECK([how to create a directory], [cs_cv_shell_mkdir], + [cs_cv_shell_mkdir='mkdir']) + AC_SUBST([MKDIR], [$cs_cv_shell_mkdir]) + + AC_CACHE_CHECK([how to create a directory tree], [cs_cv_shell_mkdir_p], + [if $cs_cv_shell_mkdir -p . 2>/dev/null; then + cs_cv_shell_mkdir_p='mkdir -p' + elif mkdirs . 2>/dev/null; then + cs_cv_shell_mkdir_p='mkdirs' + fi + test -d ./-p && rmdir ./-p]) + AS_VAR_SET_IF([cs_cv_shell_mkdir_p], + [AC_SUBST([MKDIRS], [$cs_cv_shell_mkdir_p])], + [CS_MSG_ERROR([do not know how to create a directory tree])])]) +m4trace:acinclude.m4:2427: -1- AC_DEFUN([CS_PACKAGEINFO], [PACKAGE_LONGNAME="[$1]" + PACKAGE_COPYRIGHT="[$2]" + PACKAGE_HOMEPAGE="[$3]" +]) +m4trace:acinclude.m4:2452: -1- AC_DEFUN([CS_EMIT_PACKAGEINFO], [_CS_EMIT_PACKAGEINFO([$1], [PACKAGE_NAME], [$PACKAGE_NAME]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_VERSION], [$PACKAGE_VERSION]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_STRING], [$PACKAGE_STRING]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_BUGREPORT], [$PACKAGE_BUGREPORT]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_LONGNAME], [$PACKAGE_LONGNAME]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_HOMEPAGE], [$PACKAGE_HOMEPAGE]) + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_COPYRIGHT], [$PACKAGE_COPYRIGHT]) + for cs_veritem in m4_translit(AC_PACKAGE_VERSION, [.], [ ]); do + _CS_EMIT_PACKAGEINFO([$1], [PACKAGE_VERSION_LIST], [$cs_veritem], [+]) + done + ]) +m4trace:acinclude.m4:2459: -1- AC_DEFUN([_CS_EMIT_PACKAGEINFO], [m4_case([$1], + [make], [CS_MAKEFILE_PROPERTY([$2], [$3], [$4])], + [jam], [CS_JAMCONFIG_PROPERTY([$2], [$3], [$4])], + [], [CS_JAMCONFIG_PROPERTY([$2], [$3], [$4])], + [$1([$2], [$3], [$4])])]) +m4trace:acinclude.m4:2487: -1- AC_DEFUN([CS_PATH_NORMALIZE], [`echo "x$1" | tr '\\\\' '/' | sed 's/^x//;s/ */ /g;s/^ //;s/ $//'`]) +m4trace:acinclude.m4:2496: -1- AC_DEFUN([CS_RUN_PATH_NORMALIZE], [`AC_RUN_LOG([$1]) | tr '\\\\' '/' | sed 's/^x//;s/ */ /g;s/^ //;s/ $//'`]) +m4trace:acinclude.m4:2703: -1- AC_DEFUN([CS_CHECK_PROG_VERSION], [AC_CACHE_CHECK([if $1 version m4_default([$7],[>=]) $3], + [AS_TR_SH([cs_cv_prog_$1_version_ok_annotated])], + [CS_VCHK_EXTRACTVERSION([$2], [$3], [$4], AS_TR_SH([$1]), + m4_default([$7],[>=]))]) +AS_IF([test "$AS_TR_SH([cs_cv_prog_$1_version_ok])" = yes], [$5], [$6])]) +m4trace:acinclude.m4:2749: -1- AC_DEFUN([CS_SYMBOL_QUALIFIER], [AC_CACHE_CHECK([$1], [$2], + [$2='no' + m4_foreach([cs_symbol_qualifier], [$3], + [AS_IF([test "$$2" = no], + [CS_BUILD_IFELSE( + [AC_LANG_PROGRAM( + [cs_symbol_qualifier m4_default([$4],[void f()]);], + [])], + [], [$5], [$2='cs_symbol_qualifier'], [$2='no'])])])]) + AS_IF([test $$2 != no], [$6], [$7])]) +m4trace:acinclude.m4:2793: -1- AC_DEFUN([CS_SPLIT], [m4_define([cs_split_filler], m4_default([$4],[filler])) + set cs_split_filler `echo "$1" | awk 'BEGIN { FS="m4_default([$3],[ ])" } + { for (i=1; i <= NF; ++i) + { if ($i == "") print "cs_split_filler"; else print $i } }'` + shift + m4_map([_CS_SPLIT], [$2])]) +m4trace:acinclude.m4:2798: -1- AC_DEFUN([_CS_SPLIT], [AS_IF([test $[@%:@] -eq 0], [$1=''], + [AS_IF([test "$[1]" = cs_split_filler], [$1=''], [$1=$[1]]) + shift])]) +m4trace:acinclude.m4:2864: -1- AC_DEFUN([CS_TEXT_CACHE_APPEND], [$1="${$1}$2"]) +m4trace:acinclude.m4:2865: -1- AC_DEFUN([CS_TEXT_CACHE_PREPEND], [$1="$2${$1}"]) +m4trace:acinclude.m4:2876: -1- AC_DEFUN([CS_TEXT_CACHE_OUTPUT], [AC_CONFIG_COMMANDS([$2], + [echo $ECHO_N "$$1$ECHO_C" > $tmp/tcache + AS_IF([diff $2 $tmp/tcache >/dev/null 2>&1], + [AC_MSG_NOTICE([$2 is unchanged])], + [rm -f $2 + cp $tmp/tcache $2]) + rm -f $tmp/tcache], + [$1='$$1' + cs_dir=`AS_DIRNAME([$2])` + AS_ESCAPE(AS_MKDIR_P([$cs_dir]), [$`\])])]) +m4trace:acinclude.m4:2903: -1- AC_DEFUN([CS_TRIM], [`echo x$1 | sed 's/^x//;s/ */ /g;s/^ //;s/ $//'`]) +m4trace:acinclude.m4:2947: -1- AC_DEFUN([CS_COMPILER_WARNINGS], [CS_CHECK_BUILD_FLAGS( + [how to enable m4_default([$1],[C]) compilation warnings], + [m4_default([$2],[cs_cv_prog_compiler_enable_warnings])], + [CS_CREATE_TUPLE([-Wmost]) CS_CREATE_TUPLE([-Wall])], + [$1], [$3], [$4])]) +m4trace:acinclude.m4:2966: -1- AC_DEFUN([CS_COMPILER_ERRORS], [CS_CHECK_BUILD_FLAGS( + [how to treat m4_default([$1],[C]) warnings as errors], + [m4_default([$2],[cs_cv_prog_compiler_enable_errors])], + [CS_CREATE_TUPLE([-Werror])], [$1], [$3], [$4])]) +m4trace:acinclude.m4:2988: -1- AC_DEFUN([CS_COMPILER_IGNORE_UNUSED], [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) unused variable warnings], + [m4_default([$2],[cs_cv_prog_compiler_ignore_unused])], + [CS_CREATE_TUPLE([-Wno-unused])], [$1], [$3], [$4])]) +m4trace:acinclude.m4:3011: -1- AC_DEFUN([CS_COMPILER_IGNORE_UNINITIALIZED], [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) uninitialized warnings], + [m4_default([$2], + [cs_cv_prog_compiler_ignore_uninitialized_variables])], + [CS_CREATE_TUPLE([-Wno-uninitialized])], [$1], [$3], [$4])]) +m4trace:acinclude.m4:3032: -1- AC_DEFUN([CS_COMPILER_IGNORE_PRAGMAS], [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) unknown [#pragma] warnings], + [m4_default([$2],[cs_cv_prog_compiler_ignore_unknown_pragmas])], + [CS_CREATE_TUPLE([-Wno-unknown-pragmas])], [$1], [$3], [$4])]) +m4trace:acinclude.m4:3054: -1- AC_DEFUN([CS_COMPILER_IGNORE_LONG_DOUBLE], [CS_CHECK_BUILD_FLAGS( + [how to suppress m4_default([$1],[C]) `long double' warnings], + [m4_default([$2],[cs_cv_prog_compiler_ignore_long_double])], + [CS_CREATE_TUPLE([-Wno-long-double])], [$1], [$3], [$4])]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^_?A[CHUM]_]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([_AC_]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) +m4trace:configure.ac:13: -1- m4_pattern_allow([^AS_FLAGS$]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^_?m4_]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^dnl$]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^_?AS_]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^SHELL$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PATH_SEPARATOR$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_NAME$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_VERSION$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_STRING$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_URL$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^exec_prefix$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^prefix$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^program_transform_name$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^bindir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^sbindir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^libexecdir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^datarootdir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^datadir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^sysconfdir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^sharedstatedir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^localstatedir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^includedir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^oldincludedir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^docdir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^infodir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^htmldir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^dvidir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^pdfdir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^psdir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^libdir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^localedir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^mandir$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_NAME$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_VERSION$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_STRING$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_URL$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^DEFS$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^ECHO_C$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^ECHO_N$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^ECHO_T$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^LIBS$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^build_alias$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^host_alias$]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^target_alias$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build_cpu$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build_vendor$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build_os$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host_cpu$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host_vendor$]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host_os$]) +m4trace:configure.ac:16: -1- AM_INIT_AUTOMAKE +m4trace:configure.ac:16: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) +m4trace:configure.ac:16: -1- AM_SET_CURRENT_AUTOMAKE_VERSION +m4trace:configure.ac:16: -1- AM_AUTOMAKE_VERSION([1.11]) +m4trace:configure.ac:16: -1- _AM_AUTOCONF_VERSION([2.68]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_PROGRAM$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_SCRIPT$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_DATA$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__isrc$]) +m4trace:configure.ac:16: -1- _AM_SUBST_NOTMAKE([am__isrc]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^CYGPATH_W$]) +m4trace:configure.ac:16: -1- _AM_SET_OPTIONS([]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^PACKAGE$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^VERSION$]) +m4trace:configure.ac:16: -1- _AM_IF_OPTION([no-define], [], [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])]) +m4trace:configure.ac:16: -2- _AM_MANGLE_OPTION([no-define]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^PACKAGE$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^VERSION$]) +m4trace:configure.ac:16: -1- AM_SANITY_CHECK +m4trace:configure.ac:16: -1- AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +m4trace:configure.ac:16: -1- AM_MISSING_HAS_RUN +m4trace:configure.ac:16: -1- AM_AUX_DIR_EXPAND +m4trace:configure.ac:16: -1- m4_pattern_allow([^ACLOCAL$]) +m4trace:configure.ac:16: -1- AM_MISSING_PROG([AUTOCONF], [autoconf]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AUTOCONF$]) +m4trace:configure.ac:16: -1- AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AUTOMAKE$]) +m4trace:configure.ac:16: -1- AM_MISSING_PROG([AUTOHEADER], [autoheader]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AUTOHEADER$]) +m4trace:configure.ac:16: -1- AM_MISSING_PROG([MAKEINFO], [makeinfo]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^MAKEINFO$]) +m4trace:configure.ac:16: -1- AM_PROG_INSTALL_SH +m4trace:configure.ac:16: -1- m4_pattern_allow([^install_sh$]) +m4trace:configure.ac:16: -1- AM_PROG_INSTALL_STRIP +m4trace:configure.ac:16: -1- m4_pattern_allow([^STRIP$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_STRIP_PROGRAM$]) +m4trace:configure.ac:16: -1- AM_PROG_MKDIR_P +m4trace:configure.ac:16: -1- m4_pattern_allow([^MKDIR_P$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^mkdir_p$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AWK$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^SET_MAKE$]) +m4trace:configure.ac:16: -1- AM_SET_LEADING_DOT +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__leading_dot$]) +m4trace:configure.ac:16: -1- _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +m4trace:configure.ac:16: -2- _AM_MANGLE_OPTION([tar-ustar]) +m4trace:configure.ac:16: -1- _AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])]) +m4trace:configure.ac:16: -2- _AM_MANGLE_OPTION([tar-pax]) +m4trace:configure.ac:16: -1- _AM_PROG_TAR([v7]) +m4trace:configure.ac:16: -1- AM_MISSING_PROG([AMTAR], [tar]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AMTAR$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__tar$]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__untar$]) +m4trace:configure.ac:16: -1- _AM_IF_OPTION([no-dependencies], [], [AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +m4trace:configure.ac:16: -2- _AM_MANGLE_OPTION([no-dependencies]) +m4trace:configure.ac:16: -1- _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])]) +m4trace:configure.ac:16: -2- _AM_MANGLE_OPTION([silent-rules]) +m4trace:configure.ac:17: -1- AM_PROG_CC_C_O +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CFLAGS$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^LDFLAGS$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^LIBS$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^ac_ct_CC$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^EXEEXT$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^OBJEXT$]) +m4trace:configure.ac:17: -1- _AM_DEPENDENCIES([CC]) +m4trace:configure.ac:17: -1- AM_SET_DEPDIR +m4trace:configure.ac:17: -1- m4_pattern_allow([^DEPDIR$]) +m4trace:configure.ac:17: -1- AM_OUTPUT_DEPENDENCY_COMMANDS +m4trace:configure.ac:17: -1- AM_MAKE_INCLUDE +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__include$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__quote$]) +m4trace:configure.ac:17: -1- AM_DEP_TRACK +m4trace:configure.ac:17: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^AMDEP_TRUE$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^AMDEP_FALSE$]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([AMDEP_TRUE]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([AMDEP_FALSE]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^AMDEPBACKSLASH$]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([AMDEPBACKSLASH]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CCDEPMODE$]) +m4trace:configure.ac:17: -1- AM_CONDITIONAL([am__fastdepCC], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^NO_MINUS_C_MINUS_O$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXX$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXXFLAGS$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^LDFLAGS$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^LIBS$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXX$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^ac_ct_CXX$]) +m4trace:configure.ac:18: -1- _AM_DEPENDENCIES([CXX]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXXDEPMODE$]) +m4trace:configure.ac:18: -1- AM_CONDITIONAL([am__fastdepCXX], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^am__fastdepCXX_TRUE$]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^am__fastdepCXX_FALSE$]) +m4trace:configure.ac:18: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_TRUE]) +m4trace:configure.ac:18: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_FALSE]) +m4trace:configure.ac:19: -1- AC_PROG_LIBTOOL +m4trace:configure.ac:19: -1- _m4_warn([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. +You should run autoupdate.], [/usr/local/share/aclocal/libtool.m4:107: AC_PROG_LIBTOOL is expanded from... +configure.ac:19: the top level]) +m4trace:configure.ac:19: -1- LT_INIT +m4trace:configure.ac:19: -1- m4_pattern_forbid([^_?LT_[A-Z_]+$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$]) +m4trace:configure.ac:19: -1- LTOPTIONS_VERSION +m4trace:configure.ac:19: -1- LTSUGAR_VERSION +m4trace:configure.ac:19: -1- LTVERSION_VERSION +m4trace:configure.ac:19: -1- LTOBSOLETE_VERSION +m4trace:configure.ac:19: -1- _LT_PROG_LTMAIN +m4trace:configure.ac:19: -1- m4_pattern_allow([^LIBTOOL$]) +m4trace:configure.ac:19: -1- _LT_PREPARE_SED_QUOTE_VARS +m4trace:configure.ac:19: -1- _LT_PROG_ECHO_BACKSLASH +m4trace:configure.ac:19: -1- LT_PATH_LD +m4trace:configure.ac:19: -1- m4_pattern_allow([^SED$]) +m4trace:configure.ac:19: -1- AC_PROG_EGREP +m4trace:configure.ac:19: -1- m4_pattern_allow([^GREP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^EGREP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^FGREP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^GREP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LD$]) +m4trace:configure.ac:19: -1- LT_PATH_NM +m4trace:configure.ac:19: -1- m4_pattern_allow([^DUMPBIN$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^ac_ct_DUMPBIN$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DUMPBIN$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^NM$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LN_S$]) +m4trace:configure.ac:19: -1- LT_CMD_MAX_LEN +m4trace:configure.ac:19: -1- m4_pattern_allow([^OBJDUMP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^OBJDUMP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DLLTOOL$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DLLTOOL$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^AR$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^ac_ct_AR$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^STRIP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^RANLIB$]) +m4trace:configure.ac:19: -1- _LT_WITH_SYSROOT +m4trace:configure.ac:19: -1- m4_pattern_allow([LT_OBJDIR]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LT_OBJDIR$]) +m4trace:configure.ac:19: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.ac:19: -1- _LT_PATH_TOOL_PREFIX([${ac_tool_prefix}file], [/usr/bin$PATH_SEPARATOR$PATH]) +m4trace:configure.ac:19: -1- _LT_PATH_TOOL_PREFIX([file], [/usr/bin$PATH_SEPARATOR$PATH]) +m4trace:configure.ac:19: -1- LT_SUPPORTED_TAG([CC]) +m4trace:configure.ac:19: -1- _LT_COMPILER_BOILERPLATE +m4trace:configure.ac:19: -1- _LT_LINKER_BOILERPLATE +m4trace:configure.ac:19: -1- _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], [lt_cv_prog_compiler_rtti_exceptions], [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, )="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, ) -fno-rtti -fno-exceptions"]) +m4trace:configure.ac:19: -1- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, ) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, )], [$_LT_TAGVAR(lt_prog_compiler_pic, )@&t@m4_if([],[],[ -DPIC],[m4_if([],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, ) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, )=" $_LT_TAGVAR(lt_prog_compiler_pic, )" ;; + esac], [_LT_TAGVAR(lt_prog_compiler_pic, )= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, )=no]) +m4trace:configure.ac:19: -1- _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_cv_prog_compiler_static_works], [$lt_tmp_static_flag], [], [_LT_TAGVAR(lt_prog_compiler_static, )=]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^MANIFEST_TOOL$]) +m4trace:configure.ac:19: -1- _LT_REQUIRED_DARWIN_CHECKS +m4trace:configure.ac:19: -1- m4_pattern_allow([^DSYMUTIL$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^NMEDIT$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LIPO$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^OTOOL$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^OTOOL64$]) +m4trace:configure.ac:19: -1- _LT_LINKER_OPTION([if $CC understands -b], [lt_cv_prog_compiler__b], [-b], [_LT_TAGVAR(archive_cmds, )='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, )='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags']) +m4trace:configure.ac:19: -1- LT_SYS_DLOPEN_SELF +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^STDC_HEADERS$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^HAVE_DLFCN_H$]) +m4trace:configure.ac:19: -1- LT_LANG([CXX]) +m4trace:configure.ac:19: -1- LT_SUPPORTED_TAG([CXX]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CXXCPP$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CXXCPP$]) +m4trace:configure.ac:19: -1- _LT_COMPILER_BOILERPLATE +m4trace:configure.ac:19: -1- _LT_LINKER_BOILERPLATE +m4trace:configure.ac:19: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.ac:19: -1- LT_PATH_LD +m4trace:configure.ac:19: -1- m4_pattern_allow([^LD$]) +m4trace:configure.ac:19: -1- _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, CXX) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, CXX)], [$_LT_TAGVAR(lt_prog_compiler_pic, CXX)@&t@m4_if([CXX],[],[ -DPIC],[m4_if([CXX],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, CXX) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, CXX)=" $_LT_TAGVAR(lt_prog_compiler_pic, CXX)" ;; + esac], [_LT_TAGVAR(lt_prog_compiler_pic, CXX)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, CXX)=no]) +m4trace:configure.ac:19: -1- _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_cv_prog_compiler_static_works_CXX], [$lt_tmp_static_flag], [], [_LT_TAGVAR(lt_prog_compiler_static, CXX)=]) +m4trace:configure.ac:23: -1- m4_pattern_allow([^PLATFORM_WIN32$]) +m4trace:configure.ac:28: -1- m4_pattern_allow([^PLATFORM_LINUX$]) +m4trace:configure.ac:34: -1- m4_pattern_allow([^PLATFORM_APPLE$]) +m4trace:configure.ac:42: -1- m4_pattern_allow([^opengl_LIBS$]) +m4trace:configure.ac:46: -1- m4_pattern_allow([^ARCH_X86$]) +m4trace:configure.ac:51: -1- m4_pattern_allow([^ARCH_X86_64$]) +m4trace:configure.ac:57: -1- m4_pattern_allow([^ARCH_PPC$]) +m4trace:configure.ac:65: -1- m4_pattern_allow([^WORDS_BIGENDIAN$]) +m4trace:configure.ac:65: -1- m4_pattern_allow([^AC_APPLE_UNIVERSAL_BUILD$]) +m4trace:configure.ac:78: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... +../../lib/autoconf/general.m4:1473: AC_ARG_ENABLE is expanded from... +configure.ac:78: the top level]) +m4trace:configure.ac:82: -1- AM_CONDITIONAL([CONDITIONAL_BUILD_MULTITHREADED], [test "$build_multithreaded" = yes]) +m4trace:configure.ac:82: -1- m4_pattern_allow([^CONDITIONAL_BUILD_MULTITHREADED_TRUE$]) +m4trace:configure.ac:82: -1- m4_pattern_allow([^CONDITIONAL_BUILD_MULTITHREADED_FALSE$]) +m4trace:configure.ac:82: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_MULTITHREADED_TRUE]) +m4trace:configure.ac:82: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_MULTITHREADED_FALSE]) +m4trace:configure.ac:89: -1- AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS], [false]) +m4trace:configure.ac:89: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_TRUE$]) +m4trace:configure.ac:89: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_FALSE$]) +m4trace:configure.ac:89: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:89: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:97: -1- m4_pattern_allow([^HAVE_APPLE_OPENGL_FRAMEWORK$]) +m4trace:configure.ac:140: -1- m4_pattern_allow([^GL_LIBS$]) +m4trace:configure.ac:145: -1- AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS], [true]) +m4trace:configure.ac:145: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_TRUE$]) +m4trace:configure.ac:145: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_FALSE$]) +m4trace:configure.ac:145: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:145: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:153: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... +../../lib/autoconf/general.m4:1473: AC_ARG_ENABLE is expanded from... +configure.ac:153: the top level]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^LIB@&t@OBJS$]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^LTLIBOBJS$]) +m4trace:configure.ac:167: -1- AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^am__EXEEXT_TRUE$]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^am__EXEEXT_FALSE$]) +m4trace:configure.ac:167: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_TRUE]) +m4trace:configure.ac:167: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_FALSE]) +m4trace:configure.ac:167: -1- _AC_AM_CONFIG_HEADER_HOOK(["$ac_file"]) +m4trace:configure.ac:167: -1- _AM_OUTPUT_DEPENDENCY_COMMANDS +m4trace:configure.ac:167: -1- _LT_PROG_LTMAIN diff --git a/autom4te.cache/traces.1 b/autom4te.cache/traces.1 new file mode 100644 index 0000000..c739909 --- /dev/null +++ b/autom4te.cache/traces.1 @@ -0,0 +1,638 @@ +m4trace:aclocal.m4:9414: -1- m4_include([acinclude.m4]) +m4trace:configure.ac:13: -1- AC_INIT([bullet], [2.81], [bullet@erwincoumans.com]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^_?A[CHUM]_]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([_AC_]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) +m4trace:configure.ac:13: -1- m4_pattern_allow([^AS_FLAGS$]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^_?m4_]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^dnl$]) +m4trace:configure.ac:13: -1- m4_pattern_forbid([^_?AS_]) +m4trace:configure.ac:13: -1- AC_SUBST([SHELL]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([SHELL]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^SHELL$]) +m4trace:configure.ac:13: -1- AC_SUBST([PATH_SEPARATOR]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([PATH_SEPARATOR]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PATH_SEPARATOR$]) +m4trace:configure.ac:13: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([PACKAGE_NAME]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_NAME$]) +m4trace:configure.ac:13: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([PACKAGE_TARNAME]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) +m4trace:configure.ac:13: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([PACKAGE_VERSION]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_VERSION$]) +m4trace:configure.ac:13: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([PACKAGE_STRING]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_STRING$]) +m4trace:configure.ac:13: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) +m4trace:configure.ac:13: -1- AC_SUBST([PACKAGE_URL], [m4_ifdef([AC_PACKAGE_URL], ['AC_PACKAGE_URL'])]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([PACKAGE_URL]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_URL$]) +m4trace:configure.ac:13: -1- AC_SUBST([exec_prefix], [NONE]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([exec_prefix]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^exec_prefix$]) +m4trace:configure.ac:13: -1- AC_SUBST([prefix], [NONE]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([prefix]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^prefix$]) +m4trace:configure.ac:13: -1- AC_SUBST([program_transform_name], [s,x,x,]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([program_transform_name]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^program_transform_name$]) +m4trace:configure.ac:13: -1- AC_SUBST([bindir], ['${exec_prefix}/bin']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([bindir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^bindir$]) +m4trace:configure.ac:13: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([sbindir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^sbindir$]) +m4trace:configure.ac:13: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([libexecdir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^libexecdir$]) +m4trace:configure.ac:13: -1- AC_SUBST([datarootdir], ['${prefix}/share']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([datarootdir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^datarootdir$]) +m4trace:configure.ac:13: -1- AC_SUBST([datadir], ['${datarootdir}']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([datadir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^datadir$]) +m4trace:configure.ac:13: -1- AC_SUBST([sysconfdir], ['${prefix}/etc']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([sysconfdir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^sysconfdir$]) +m4trace:configure.ac:13: -1- AC_SUBST([sharedstatedir], ['${prefix}/com']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([sharedstatedir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^sharedstatedir$]) +m4trace:configure.ac:13: -1- AC_SUBST([localstatedir], ['${prefix}/var']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([localstatedir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^localstatedir$]) +m4trace:configure.ac:13: -1- AC_SUBST([includedir], ['${prefix}/include']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([includedir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^includedir$]) +m4trace:configure.ac:13: -1- AC_SUBST([oldincludedir], ['/usr/include']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([oldincludedir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^oldincludedir$]) +m4trace:configure.ac:13: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], + ['${datarootdir}/doc/${PACKAGE_TARNAME}'], + ['${datarootdir}/doc/${PACKAGE}'])]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([docdir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^docdir$]) +m4trace:configure.ac:13: -1- AC_SUBST([infodir], ['${datarootdir}/info']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([infodir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^infodir$]) +m4trace:configure.ac:13: -1- AC_SUBST([htmldir], ['${docdir}']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([htmldir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^htmldir$]) +m4trace:configure.ac:13: -1- AC_SUBST([dvidir], ['${docdir}']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([dvidir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^dvidir$]) +m4trace:configure.ac:13: -1- AC_SUBST([pdfdir], ['${docdir}']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([pdfdir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^pdfdir$]) +m4trace:configure.ac:13: -1- AC_SUBST([psdir], ['${docdir}']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([psdir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^psdir$]) +m4trace:configure.ac:13: -1- AC_SUBST([libdir], ['${exec_prefix}/lib']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([libdir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^libdir$]) +m4trace:configure.ac:13: -1- AC_SUBST([localedir], ['${datarootdir}/locale']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([localedir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^localedir$]) +m4trace:configure.ac:13: -1- AC_SUBST([mandir], ['${datarootdir}/man']) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([mandir]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^mandir$]) +m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_NAME$]) +m4trace:configure.ac:13: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */ +@%:@undef PACKAGE_NAME]) +m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) +m4trace:configure.ac:13: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */ +@%:@undef PACKAGE_TARNAME]) +m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_VERSION$]) +m4trace:configure.ac:13: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */ +@%:@undef PACKAGE_VERSION]) +m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_STRING$]) +m4trace:configure.ac:13: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */ +@%:@undef PACKAGE_STRING]) +m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) +m4trace:configure.ac:13: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */ +@%:@undef PACKAGE_BUGREPORT]) +m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_URL]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^PACKAGE_URL$]) +m4trace:configure.ac:13: -1- AH_OUTPUT([PACKAGE_URL], [/* Define to the home page for this package. */ +@%:@undef PACKAGE_URL]) +m4trace:configure.ac:13: -1- AC_SUBST([DEFS]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([DEFS]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^DEFS$]) +m4trace:configure.ac:13: -1- AC_SUBST([ECHO_C]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([ECHO_C]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^ECHO_C$]) +m4trace:configure.ac:13: -1- AC_SUBST([ECHO_N]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([ECHO_N]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^ECHO_N$]) +m4trace:configure.ac:13: -1- AC_SUBST([ECHO_T]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([ECHO_T]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^ECHO_T$]) +m4trace:configure.ac:13: -1- AC_SUBST([LIBS]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([LIBS]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^LIBS$]) +m4trace:configure.ac:13: -1- AC_SUBST([build_alias]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([build_alias]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^build_alias$]) +m4trace:configure.ac:13: -1- AC_SUBST([host_alias]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([host_alias]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^host_alias$]) +m4trace:configure.ac:13: -1- AC_SUBST([target_alias]) +m4trace:configure.ac:13: -1- AC_SUBST_TRACE([target_alias]) +m4trace:configure.ac:13: -1- m4_pattern_allow([^target_alias$]) +m4trace:configure.ac:14: -1- AC_CANONICAL_HOST +m4trace:configure.ac:14: -1- AC_CANONICAL_BUILD +m4trace:configure.ac:14: -1- AC_REQUIRE_AUX_FILE([config.sub]) +m4trace:configure.ac:14: -1- AC_REQUIRE_AUX_FILE([config.guess]) +m4trace:configure.ac:14: -1- AC_SUBST([build], [$ac_cv_build]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([build]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build$]) +m4trace:configure.ac:14: -1- AC_SUBST([build_cpu], [$[1]]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([build_cpu]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build_cpu$]) +m4trace:configure.ac:14: -1- AC_SUBST([build_vendor], [$[2]]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([build_vendor]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build_vendor$]) +m4trace:configure.ac:14: -1- AC_SUBST([build_os]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([build_os]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^build_os$]) +m4trace:configure.ac:14: -1- AC_SUBST([host], [$ac_cv_host]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([host]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host$]) +m4trace:configure.ac:14: -1- AC_SUBST([host_cpu], [$[1]]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([host_cpu]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host_cpu$]) +m4trace:configure.ac:14: -1- AC_SUBST([host_vendor], [$[2]]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([host_vendor]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host_vendor$]) +m4trace:configure.ac:14: -1- AC_SUBST([host_os]) +m4trace:configure.ac:14: -1- AC_SUBST_TRACE([host_os]) +m4trace:configure.ac:14: -1- m4_pattern_allow([^host_os$]) +m4trace:configure.ac:16: -1- AM_INIT_AUTOMAKE +m4trace:configure.ac:16: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) +m4trace:configure.ac:16: -1- AM_AUTOMAKE_VERSION([1.11]) +m4trace:configure.ac:16: -1- AC_REQUIRE_AUX_FILE([install-sh]) +m4trace:configure.ac:16: -1- AC_SUBST([INSTALL_PROGRAM]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([INSTALL_PROGRAM]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_PROGRAM$]) +m4trace:configure.ac:16: -1- AC_SUBST([INSTALL_SCRIPT]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([INSTALL_SCRIPT]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_SCRIPT$]) +m4trace:configure.ac:16: -1- AC_SUBST([INSTALL_DATA]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([INSTALL_DATA]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_DATA$]) +m4trace:configure.ac:16: -1- AC_SUBST([am__isrc], [' -I$(srcdir)']) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([am__isrc]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__isrc$]) +m4trace:configure.ac:16: -1- _AM_SUBST_NOTMAKE([am__isrc]) +m4trace:configure.ac:16: -1- AC_SUBST([CYGPATH_W]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CYGPATH_W]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^CYGPATH_W$]) +m4trace:configure.ac:16: -1- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME']) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([PACKAGE]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^PACKAGE$]) +m4trace:configure.ac:16: -1- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION']) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([VERSION]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^VERSION$]) +m4trace:configure.ac:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^PACKAGE$]) +m4trace:configure.ac:16: -1- AH_OUTPUT([PACKAGE], [/* Name of package */ +@%:@undef PACKAGE]) +m4trace:configure.ac:16: -1- AC_DEFINE_TRACE_LITERAL([VERSION]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^VERSION$]) +m4trace:configure.ac:16: -1- AH_OUTPUT([VERSION], [/* Version number of package */ +@%:@undef VERSION]) +m4trace:configure.ac:16: -1- AC_REQUIRE_AUX_FILE([missing]) +m4trace:configure.ac:16: -1- AC_SUBST([ACLOCAL]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([ACLOCAL]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^ACLOCAL$]) +m4trace:configure.ac:16: -1- AC_SUBST([AUTOCONF]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([AUTOCONF]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AUTOCONF$]) +m4trace:configure.ac:16: -1- AC_SUBST([AUTOMAKE]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([AUTOMAKE]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AUTOMAKE$]) +m4trace:configure.ac:16: -1- AC_SUBST([AUTOHEADER]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([AUTOHEADER]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AUTOHEADER$]) +m4trace:configure.ac:16: -1- AC_SUBST([MAKEINFO]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([MAKEINFO]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^MAKEINFO$]) +m4trace:configure.ac:16: -1- AC_SUBST([install_sh]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([install_sh]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^install_sh$]) +m4trace:configure.ac:16: -1- AC_SUBST([STRIP]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([STRIP]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^STRIP$]) +m4trace:configure.ac:16: -1- AC_SUBST([INSTALL_STRIP_PROGRAM]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([INSTALL_STRIP_PROGRAM]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^INSTALL_STRIP_PROGRAM$]) +m4trace:configure.ac:16: -1- AC_REQUIRE_AUX_FILE([install-sh]) +m4trace:configure.ac:16: -1- AC_SUBST([MKDIR_P]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([MKDIR_P]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^MKDIR_P$]) +m4trace:configure.ac:16: -1- AC_SUBST([mkdir_p], ["$MKDIR_P"]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([mkdir_p]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^mkdir_p$]) +m4trace:configure.ac:16: -1- AC_SUBST([AWK]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([AWK]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AWK$]) +m4trace:configure.ac:16: -1- AC_SUBST([SET_MAKE]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([SET_MAKE]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^SET_MAKE$]) +m4trace:configure.ac:16: -1- AC_SUBST([am__leading_dot]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([am__leading_dot]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__leading_dot$]) +m4trace:configure.ac:16: -1- AC_SUBST([AMTAR]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([AMTAR]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^AMTAR$]) +m4trace:configure.ac:16: -1- AC_SUBST([am__tar]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([am__tar]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__tar$]) +m4trace:configure.ac:16: -1- AC_SUBST([am__untar]) +m4trace:configure.ac:16: -1- AC_SUBST_TRACE([am__untar]) +m4trace:configure.ac:16: -1- m4_pattern_allow([^am__untar$]) +m4trace:configure.ac:17: -1- AM_PROG_CC_C_O +m4trace:configure.ac:17: -1- AC_SUBST([CC]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CC]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- AC_SUBST([CFLAGS]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CFLAGS]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CFLAGS$]) +m4trace:configure.ac:17: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([LDFLAGS]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^LDFLAGS$]) +m4trace:configure.ac:17: -1- AC_SUBST([LIBS]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([LIBS]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^LIBS$]) +m4trace:configure.ac:17: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CPPFLAGS]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:17: -1- AC_SUBST([CC]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CC]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- AC_SUBST([CC]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CC]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- AC_SUBST([CC]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CC]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- AC_SUBST([CC]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CC]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CC$]) +m4trace:configure.ac:17: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([ac_ct_CC]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^ac_ct_CC$]) +m4trace:configure.ac:17: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([EXEEXT]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^EXEEXT$]) +m4trace:configure.ac:17: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([OBJEXT]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^OBJEXT$]) +m4trace:configure.ac:17: -1- AC_SUBST([DEPDIR], ["${am__leading_dot}deps"]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([DEPDIR]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^DEPDIR$]) +m4trace:configure.ac:17: -1- AC_SUBST([am__include]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([am__include]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__include$]) +m4trace:configure.ac:17: -1- AC_SUBST([am__quote]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([am__quote]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__quote$]) +m4trace:configure.ac:17: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +m4trace:configure.ac:17: -1- AC_SUBST([AMDEP_TRUE]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([AMDEP_TRUE]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^AMDEP_TRUE$]) +m4trace:configure.ac:17: -1- AC_SUBST([AMDEP_FALSE]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([AMDEP_FALSE]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^AMDEP_FALSE$]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([AMDEP_TRUE]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([AMDEP_FALSE]) +m4trace:configure.ac:17: -1- AC_SUBST([AMDEPBACKSLASH]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([AMDEPBACKSLASH]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^AMDEPBACKSLASH$]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([AMDEPBACKSLASH]) +m4trace:configure.ac:17: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([CCDEPMODE]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^CCDEPMODE$]) +m4trace:configure.ac:17: -1- AM_CONDITIONAL([am__fastdepCC], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) +m4trace:configure.ac:17: -1- AC_SUBST([am__fastdepCC_TRUE]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([am__fastdepCC_TRUE]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) +m4trace:configure.ac:17: -1- AC_SUBST([am__fastdepCC_FALSE]) +m4trace:configure.ac:17: -1- AC_SUBST_TRACE([am__fastdepCC_FALSE]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE]) +m4trace:configure.ac:17: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE]) +m4trace:configure.ac:17: -1- AC_DEFINE_TRACE_LITERAL([NO_MINUS_C_MINUS_O]) +m4trace:configure.ac:17: -1- m4_pattern_allow([^NO_MINUS_C_MINUS_O$]) +m4trace:configure.ac:17: -1- AH_OUTPUT([NO_MINUS_C_MINUS_O], [/* Define to 1 if your C compiler doesn\'t accept -c and -o together. */ +@%:@undef NO_MINUS_C_MINUS_O]) +m4trace:configure.ac:17: -1- AC_REQUIRE_AUX_FILE([compile]) +m4trace:configure.ac:18: -1- AC_SUBST([CXX]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([CXX]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXX$]) +m4trace:configure.ac:18: -1- AC_SUBST([CXXFLAGS]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([CXXFLAGS]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXXFLAGS$]) +m4trace:configure.ac:18: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([LDFLAGS]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^LDFLAGS$]) +m4trace:configure.ac:18: -1- AC_SUBST([LIBS]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([LIBS]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^LIBS$]) +m4trace:configure.ac:18: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([CPPFLAGS]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:18: -1- AC_SUBST([CXX]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([CXX]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXX$]) +m4trace:configure.ac:18: -1- AC_SUBST([ac_ct_CXX]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([ac_ct_CXX]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^ac_ct_CXX$]) +m4trace:configure.ac:18: -1- AC_SUBST([CXXDEPMODE], [depmode=$am_cv_CXX_dependencies_compiler_type]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([CXXDEPMODE]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^CXXDEPMODE$]) +m4trace:configure.ac:18: -1- AM_CONDITIONAL([am__fastdepCXX], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3]) +m4trace:configure.ac:18: -1- AC_SUBST([am__fastdepCXX_TRUE]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([am__fastdepCXX_TRUE]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^am__fastdepCXX_TRUE$]) +m4trace:configure.ac:18: -1- AC_SUBST([am__fastdepCXX_FALSE]) +m4trace:configure.ac:18: -1- AC_SUBST_TRACE([am__fastdepCXX_FALSE]) +m4trace:configure.ac:18: -1- m4_pattern_allow([^am__fastdepCXX_FALSE$]) +m4trace:configure.ac:18: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_TRUE]) +m4trace:configure.ac:18: -1- _AM_SUBST_NOTMAKE([am__fastdepCXX_FALSE]) +m4trace:configure.ac:19: -1- AC_PROG_LIBTOOL +m4trace:configure.ac:19: -1- _m4_warn([obsolete], [The macro `AC_PROG_LIBTOOL' is obsolete. +You should run autoupdate.], [aclocal.m4:128: AC_PROG_LIBTOOL is expanded from... +configure.ac:19: the top level]) +m4trace:configure.ac:19: -1- LT_INIT +m4trace:configure.ac:19: -1- m4_pattern_forbid([^_?LT_[A-Z_]+$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$]) +m4trace:configure.ac:19: -1- AC_REQUIRE_AUX_FILE([ltmain.sh]) +m4trace:configure.ac:19: -1- AC_SUBST([LIBTOOL]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([LIBTOOL]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LIBTOOL$]) +m4trace:configure.ac:19: -1- AC_SUBST([SED]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([SED]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^SED$]) +m4trace:configure.ac:19: -1- AC_SUBST([GREP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([GREP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^GREP$]) +m4trace:configure.ac:19: -1- AC_SUBST([EGREP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([EGREP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^EGREP$]) +m4trace:configure.ac:19: -1- AC_SUBST([FGREP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([FGREP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^FGREP$]) +m4trace:configure.ac:19: -1- AC_SUBST([GREP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([GREP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^GREP$]) +m4trace:configure.ac:19: -1- AC_SUBST([LD]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([LD]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LD$]) +m4trace:configure.ac:19: -1- AC_SUBST([DUMPBIN]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([DUMPBIN]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DUMPBIN$]) +m4trace:configure.ac:19: -1- AC_SUBST([ac_ct_DUMPBIN]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([ac_ct_DUMPBIN]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^ac_ct_DUMPBIN$]) +m4trace:configure.ac:19: -1- AC_SUBST([DUMPBIN]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([DUMPBIN]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DUMPBIN$]) +m4trace:configure.ac:19: -1- AC_SUBST([NM]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([NM]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^NM$]) +m4trace:configure.ac:19: -1- AC_SUBST([LN_S], [$as_ln_s]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([LN_S]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LN_S$]) +m4trace:configure.ac:19: -1- AC_SUBST([OBJDUMP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([OBJDUMP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^OBJDUMP$]) +m4trace:configure.ac:19: -1- AC_SUBST([OBJDUMP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([OBJDUMP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^OBJDUMP$]) +m4trace:configure.ac:19: -1- AC_SUBST([DLLTOOL]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([DLLTOOL]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DLLTOOL$]) +m4trace:configure.ac:19: -1- AC_SUBST([DLLTOOL]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([DLLTOOL]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DLLTOOL$]) +m4trace:configure.ac:19: -1- AC_SUBST([AR]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([AR]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^AR$]) +m4trace:configure.ac:19: -1- AC_SUBST([ac_ct_AR]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([ac_ct_AR]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^ac_ct_AR$]) +m4trace:configure.ac:19: -1- AC_SUBST([STRIP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([STRIP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^STRIP$]) +m4trace:configure.ac:19: -1- AC_SUBST([RANLIB]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([RANLIB]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^RANLIB$]) +m4trace:configure.ac:19: -1- m4_pattern_allow([LT_OBJDIR]) +m4trace:configure.ac:19: -1- AC_DEFINE_TRACE_LITERAL([LT_OBJDIR]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LT_OBJDIR$]) +m4trace:configure.ac:19: -1- AH_OUTPUT([LT_OBJDIR], [/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +@%:@undef LT_OBJDIR]) +m4trace:configure.ac:19: -1- LT_SUPPORTED_TAG([CC]) +m4trace:configure.ac:19: -1- AC_SUBST([MANIFEST_TOOL]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([MANIFEST_TOOL]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^MANIFEST_TOOL$]) +m4trace:configure.ac:19: -1- AC_SUBST([DSYMUTIL]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([DSYMUTIL]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^DSYMUTIL$]) +m4trace:configure.ac:19: -1- AC_SUBST([NMEDIT]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([NMEDIT]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^NMEDIT$]) +m4trace:configure.ac:19: -1- AC_SUBST([LIPO]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([LIPO]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LIPO$]) +m4trace:configure.ac:19: -1- AC_SUBST([OTOOL]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([OTOOL]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^OTOOL$]) +m4trace:configure.ac:19: -1- AC_SUBST([OTOOL64]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([OTOOL64]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^OTOOL64$]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_DLFCN_H]) +m4trace:configure.ac:19: -1- AC_SUBST([CPP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([CPP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPP$]) +m4trace:configure.ac:19: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([CPPFLAGS]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:19: -1- AC_SUBST([CPP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([CPP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPP$]) +m4trace:configure.ac:19: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^STDC_HEADERS$]) +m4trace:configure.ac:19: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ +@%:@undef STDC_HEADERS]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_SYS_TYPES_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_SYS_STAT_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_STDLIB_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_STRING_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_MEMORY_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_STRINGS_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_INTTYPES_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_STDINT_H]) +m4trace:configure.ac:19: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_UNISTD_H]) +m4trace:configure.ac:19: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DLFCN_H]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^HAVE_DLFCN_H$]) +m4trace:configure.ac:19: -1- LT_SUPPORTED_TAG([CXX]) +m4trace:configure.ac:19: -1- AC_SUBST([CXXCPP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([CXXCPP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CXXCPP$]) +m4trace:configure.ac:19: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([CPPFLAGS]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CPPFLAGS$]) +m4trace:configure.ac:19: -1- AC_SUBST([CXXCPP]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([CXXCPP]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^CXXCPP$]) +m4trace:configure.ac:19: -1- AC_SUBST([LD]) +m4trace:configure.ac:19: -1- AC_SUBST_TRACE([LD]) +m4trace:configure.ac:19: -1- m4_pattern_allow([^LD$]) +m4trace:configure.ac:23: -1- AC_DEFINE_TRACE_LITERAL([PLATFORM_WIN32]) +m4trace:configure.ac:23: -1- m4_pattern_allow([^PLATFORM_WIN32$]) +m4trace:configure.ac:23: -1- AH_OUTPUT([PLATFORM_WIN32], [/* Platform is Win32 */ +@%:@undef PLATFORM_WIN32]) +m4trace:configure.ac:28: -1- AC_DEFINE_TRACE_LITERAL([PLATFORM_LINUX]) +m4trace:configure.ac:28: -1- m4_pattern_allow([^PLATFORM_LINUX$]) +m4trace:configure.ac:28: -1- AH_OUTPUT([PLATFORM_LINUX], [/* Platform is Linux */ +@%:@undef PLATFORM_LINUX]) +m4trace:configure.ac:34: -1- AC_DEFINE_TRACE_LITERAL([PLATFORM_APPLE]) +m4trace:configure.ac:34: -1- m4_pattern_allow([^PLATFORM_APPLE$]) +m4trace:configure.ac:34: -1- AH_OUTPUT([PLATFORM_APPLE], [/* Platform is Apple */ +@%:@undef PLATFORM_APPLE]) +m4trace:configure.ac:42: -1- AC_SUBST([opengl_LIBS]) +m4trace:configure.ac:42: -1- AC_SUBST_TRACE([opengl_LIBS]) +m4trace:configure.ac:42: -1- m4_pattern_allow([^opengl_LIBS$]) +m4trace:configure.ac:46: -1- AC_DEFINE_TRACE_LITERAL([ARCH_X86]) +m4trace:configure.ac:46: -1- m4_pattern_allow([^ARCH_X86$]) +m4trace:configure.ac:46: -1- AH_OUTPUT([ARCH_X86], [/* Architecture is x86 */ +@%:@undef ARCH_X86]) +m4trace:configure.ac:51: -1- AC_DEFINE_TRACE_LITERAL([ARCH_X86_64]) +m4trace:configure.ac:51: -1- m4_pattern_allow([^ARCH_X86_64$]) +m4trace:configure.ac:51: -1- AH_OUTPUT([ARCH_X86_64], [/* Architecture is x86-64 */ +@%:@undef ARCH_X86_64]) +m4trace:configure.ac:57: -1- AC_DEFINE_TRACE_LITERAL([ARCH_PPC]) +m4trace:configure.ac:57: -1- m4_pattern_allow([^ARCH_PPC$]) +m4trace:configure.ac:57: -1- AH_OUTPUT([ARCH_PPC], [/* Architecture is PowerPC */ +@%:@undef ARCH_PPC]) +m4trace:configure.ac:65: -1- AH_OUTPUT([WORDS_BIGENDIAN], [/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif]) +m4trace:configure.ac:65: -1- AC_DEFINE_TRACE_LITERAL([WORDS_BIGENDIAN]) +m4trace:configure.ac:65: -1- m4_pattern_allow([^WORDS_BIGENDIAN$]) +m4trace:configure.ac:65: -1- AC_DEFINE_TRACE_LITERAL([AC_APPLE_UNIVERSAL_BUILD]) +m4trace:configure.ac:65: -1- m4_pattern_allow([^AC_APPLE_UNIVERSAL_BUILD$]) +m4trace:configure.ac:65: -1- AH_OUTPUT([AC_APPLE_UNIVERSAL_BUILD], [/* Define if building universal (internal helper macro) */ +@%:@undef AC_APPLE_UNIVERSAL_BUILD]) +m4trace:configure.ac:71: -1- AC_CONFIG_HEADERS([config.h]) +m4trace:configure.ac:78: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... +../../lib/autoconf/general.m4:1473: AC_ARG_ENABLE is expanded from... +configure.ac:78: the top level]) +m4trace:configure.ac:82: -1- AM_CONDITIONAL([CONDITIONAL_BUILD_MULTITHREADED], [test "$build_multithreaded" = yes]) +m4trace:configure.ac:82: -1- AC_SUBST([CONDITIONAL_BUILD_MULTITHREADED_TRUE]) +m4trace:configure.ac:82: -1- AC_SUBST_TRACE([CONDITIONAL_BUILD_MULTITHREADED_TRUE]) +m4trace:configure.ac:82: -1- m4_pattern_allow([^CONDITIONAL_BUILD_MULTITHREADED_TRUE$]) +m4trace:configure.ac:82: -1- AC_SUBST([CONDITIONAL_BUILD_MULTITHREADED_FALSE]) +m4trace:configure.ac:82: -1- AC_SUBST_TRACE([CONDITIONAL_BUILD_MULTITHREADED_FALSE]) +m4trace:configure.ac:82: -1- m4_pattern_allow([^CONDITIONAL_BUILD_MULTITHREADED_FALSE$]) +m4trace:configure.ac:82: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_MULTITHREADED_TRUE]) +m4trace:configure.ac:82: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_MULTITHREADED_FALSE]) +m4trace:configure.ac:89: -1- AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS], [false]) +m4trace:configure.ac:89: -1- AC_SUBST([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:89: -1- AC_SUBST_TRACE([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:89: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_TRUE$]) +m4trace:configure.ac:89: -1- AC_SUBST([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:89: -1- AC_SUBST_TRACE([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:89: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_FALSE$]) +m4trace:configure.ac:89: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:89: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:97: -1- AC_DEFINE_TRACE_LITERAL([HAVE_APPLE_OPENGL_FRAMEWORK]) +m4trace:configure.ac:97: -1- m4_pattern_allow([^HAVE_APPLE_OPENGL_FRAMEWORK$]) +m4trace:configure.ac:97: -1- AH_OUTPUT([HAVE_APPLE_OPENGL_FRAMEWORK], [/* Use the Apple OpenGL framework. */ +@%:@undef HAVE_APPLE_OPENGL_FRAMEWORK]) +m4trace:configure.ac:116: -1- AH_OUTPUT([HAVE_GL_GL_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_GL_GL_H]) +m4trace:configure.ac:116: -1- AH_OUTPUT([HAVE_GL_GLU_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_GL_GLU_H]) +m4trace:configure.ac:116: -1- AH_OUTPUT([HAVE_GL_GLEXT_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_GL_GLEXT_H]) +m4trace:configure.ac:116: -1- AH_OUTPUT([HAVE_GL_GLUT_H], [/* Define to 1 if you have the header file. */ +@%:@undef HAVE_GL_GLUT_H]) +m4trace:configure.ac:140: -1- AC_SUBST([GL_LIBS]) +m4trace:configure.ac:140: -1- AC_SUBST_TRACE([GL_LIBS]) +m4trace:configure.ac:140: -1- m4_pattern_allow([^GL_LIBS$]) +m4trace:configure.ac:145: -1- AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS], [true]) +m4trace:configure.ac:145: -1- AC_SUBST([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:145: -1- AC_SUBST_TRACE([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:145: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_TRUE$]) +m4trace:configure.ac:145: -1- AC_SUBST([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:145: -1- AC_SUBST_TRACE([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:145: -1- m4_pattern_allow([^CONDITIONAL_BUILD_DEMOS_FALSE$]) +m4trace:configure.ac:145: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_TRUE]) +m4trace:configure.ac:145: -1- _AM_SUBST_NOTMAKE([CONDITIONAL_BUILD_DEMOS_FALSE]) +m4trace:configure.ac:153: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... +../../lib/autoconf/general.m4:1473: AC_ARG_ENABLE is expanded from... +configure.ac:153: the top level]) +m4trace:configure.ac:166: -1- AC_CONFIG_FILES([bullet.pc Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/OpenGL/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile]) +m4trace:configure.ac:167: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([LIB@&t@OBJS]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^LIB@&t@OBJS$]) +m4trace:configure.ac:167: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([LTLIBOBJS]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^LTLIBOBJS$]) +m4trace:configure.ac:167: -1- AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"]) +m4trace:configure.ac:167: -1- AC_SUBST([am__EXEEXT_TRUE]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([am__EXEEXT_TRUE]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^am__EXEEXT_TRUE$]) +m4trace:configure.ac:167: -1- AC_SUBST([am__EXEEXT_FALSE]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([am__EXEEXT_FALSE]) +m4trace:configure.ac:167: -1- m4_pattern_allow([^am__EXEEXT_FALSE$]) +m4trace:configure.ac:167: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_TRUE]) +m4trace:configure.ac:167: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_FALSE]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([top_builddir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([top_build_prefix]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([srcdir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([abs_srcdir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([top_srcdir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([abs_top_srcdir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([builddir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([abs_builddir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([abs_top_builddir]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([INSTALL]) +m4trace:configure.ac:167: -1- AC_SUBST_TRACE([MKDIR_P]) +m4trace:configure.ac:167: -1- AC_REQUIRE_AUX_FILE([ltmain.sh]) diff --git a/build/Info.plist b/build/Info.plist new file mode 100755 index 0000000..cffa5f3 --- /dev/null +++ b/build/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + icon.png + + + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.5 + LSRequiresIPhoneOS + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortraitUpsideDown + + + diff --git a/build/autoexp_dat.txt b/build/autoexp_dat.txt new file mode 100644 index 0000000..386edf4 --- /dev/null +++ b/build/autoexp_dat.txt @@ -0,0 +1,66 @@ + +;------------------------------------------------------------------------------ +; Microsoft Visual Studio Debug Visualization for Bullet btVector3 and btAlignedObjectArray +; +; Copy and paste the contents of this file to the end of autoexp.dat, usually located at +; C:\Program Files\Microsoft Visual Studio 8\Common7\Packages\Debugger\autoexp.dat +;------------------------------------------------------------------------------ + + +[Visualizer] +;------------------------------------------------------------------------------ +; btVector3 +;------------------------------------------------------------------------------ +btVector3{ + children + ( + #array + ( + expr : ($c.m_floats)[$i], + size : 4 + ) + ) + + preview + ( + #( + "[", + #array + ( + expr : ($c.m_floats)[$i], + size : 4 + ), + "]" + ) + ) +} + +;------------------------------------------------------------------------------ +; btAlignedObjectArray +;------------------------------------------------------------------------------ +btAlignedObjectArray<*>{ + children + ( + #array + ( + expr : ($c.m_data)[$i], + size : $c.m_size + ) + ) + + preview + ( + #( + "[", + $c.m_size , + "](", + + #array + ( + expr : ($c.m_data)[$i], + size : $c.m_size + ), + ")" + ) + ) +} diff --git a/build/bullet.rc b/build/bullet.rc new file mode 100644 index 0000000..704b4d2 --- /dev/null +++ b/build/bullet.rc @@ -0,0 +1,29 @@ +// This file is generated automatically. + +1 VERSIONINFO +FILEVERSION 2, 79, 0, 0 +PRODUCTVERSION 2, 79, 0, 0 +#ifdef CS_DEBUG +FILEFLAGS 0x1 +#else +FILEFLAGS 0x0 +#endif +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "ProductName", "Bullet Continuous Collision Detection and Physics Library" + VALUE "ProductVersion", "2.79" + VALUE "FileVersion", "2.79" + VALUE "LegalCopyright", "Copyright (c) 2005-2011 Erwin Coumans" +#ifdef CS_DEBUG + VALUE "Comments", "Debug build" +#else + VALUE "Comments", "Release build" +#endif + VALUE "WWW", "http://www.bulletphysics.org" + } + } +} +1 ICON "bullet_ico.ico" diff --git a/build/bullet_ico.ico b/build/bullet_ico.ico new file mode 100644 index 0000000000000000000000000000000000000000..b006325fddc884810a0988639b4e631ad634a5ae GIT binary patch literal 21630 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 A;{X5v literal 0 HcmV?d00001 diff --git a/build/findDirectX11.lua b/build/findDirectX11.lua new file mode 100644 index 0000000..7f41abc --- /dev/null +++ b/build/findDirectX11.lua @@ -0,0 +1,36 @@ +function findDirectX11() + local dx11path = os.getenv("DXSDK_DIR") + if (dx11path) then + local filepath = string.format("%s%s",dx11path,"Include/D3D11.h") + headerdx11 = io.open(filepath, "r") + if (headerdx11) then + printf("Found DX11: '%s'", filepath) + return true + end + end + return false + end + +function initDirectX11() + configuration {} + + local dx11path = os.getenv("DXSDK_DIR") + defines { "ADL_ENABLE_DX11"} + includedirs {"$(DXSDK_DIR)/include"} + + configuration "x32" + libdirs {"$(DXSDK_DIR)/Lib/x86"} + configuration "x64" + libdirs {"$(DXSDK_DIR)/Lib/x64"} + configuration {} + links {"d3dcompiler", + "dxerr", + "dxguid", + "d3dx9", + "d3d9", + "winmm", + "comctl32", + "d3dx11" + } + return true +end \ No newline at end of file diff --git a/build/findOpenCL.lua b/build/findOpenCL.lua new file mode 100644 index 0000000..c77631f --- /dev/null +++ b/build/findOpenCL.lua @@ -0,0 +1,84 @@ + -- todo: add Apple OpenCL environment vars + + function findOpenCL_AMD() + local amdopenclpath = os.getenv("AMDAPPSDKROOT") + if (amdopenclpath) then + return true + end + return false + end + + function findOpenCL_NVIDIA() + local nvidiaopenclpath = os.getenv("CUDA_PATH") + if (nvidiaopenclpath) then + return true + end + return false + end + + function findOpenCL_Intel() + local intelopenclpath = os.getenv("INTELOCLSDKROOT") + if (intelopenclpath) then + return true + end + return false + end + + function initOpenCL_AMD() + configuration {} + local amdopenclpath = os.getenv("AMDAPPSDKROOT") + if (amdopenclpath) then + defines { "ADL_ENABLE_CL" , "CL_PLATFORM_AMD"} + includedirs { + "$(AMDAPPSDKROOT)/include" + } + configuration "x32" + libdirs {"$(AMDAPPSDKROOT)/lib/x86"} + configuration "x64" + libdirs {"$(AMDAPPSDKROOT)/lib/x86_64"} + configuration {} + links {"OpenCL"} + return true + end + return false + end + + + function initOpenCL_NVIDIA() + configuration {} + local nvidiaopenclpath = os.getenv("CUDA_PATH") + if (nvidiaopenclpath) then + defines { "ADL_ENABLE_CL" , "CL_PLATFORM_NVIDIA"} + includedirs { + "$(CUDA_PATH)/include" + } + configuration "x32" + libdirs {"$(CUDA_PATH)/lib/Win32"} + configuration "x64" + libdirs {"$(CUDA_PATH)/lib/x64"} + configuration {} + links {"OpenCL"} + return true + end + return false + end + + function initOpenCL_Intel() + configuration {} + local intelopenclpath = os.getenv("INTELOCLSDKROOT") + if (intelopenclpath) then + defines { "ADL_ENABLE_CL" , "CL_PLATFORM_INTEL"} + includedirs { + "$(INTELOCLSDKROOT)/include" + } + configuration "x32" + libdirs {"$(INTELOCLSDKROOT)/lib/x86"} + configuration "x64" + libdirs {"$(INTELOCLSDKROOT)/lib/x64"} + configuration {} + links {"OpenCL"} + return true + end + return false + end + \ No newline at end of file diff --git a/build/fruitstrap_osx b/build/fruitstrap_osx new file mode 100755 index 0000000000000000000000000000000000000000..22475fa3a8e3ddb80f8832f0293caf705162f803 GIT binary patch literal 33360 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 literal 0 HcmV?d00001 diff --git a/build/icon.png b/build/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0e1c1f11d3f6e7d54c65329440db6603c67e2e73 GIT binary patch literal 3742 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¨N61Th{kOChF>^)`gYYa^nzoNk&mgaXEc^a7>v^m8~*)7*>T zt~X5hli0lFMoM-}a-9r(i9%yKG?&S;-ycl}9m&bP!UK+-yO0mPMe>YGYlXYA>v*-- zpDM4qKq3a#jp_7Efm7xcLzTNT=p>UQMDCT zk5xtDiC@u6RJ{kNI#iCV@Bc}Iwo{hrdA$HtltDy<7F?C*R zQQ~)6upI@%-;wB9F%LQw^kB_HcO(w#+%0sN=;M(jRUo6#MQj7xpM65edDkoC58MF; z%m<}Dn|O6bwY#%x<9M@x*qAD#z#3Pt4hEc#)ogp7xF~gt4V9K5|67&sP-Uf5VT&$( zVtnd=RVY6d|7$;YP^n2Oor^1&-3LZ(2MZ*!PY8I4*K@=96Z=^C;XpmuuJ&-=l;J!K z#{SoC3h4$3C$It3xv2xAn6~>_q1MuYaBxgLrCH7!u?0pX(X>GPHK!piqu0z~wA5_$ zrvFqf@Ft5R>S8K4!W-o_R5A6LH=tJ=!T}&;XQ)dit0bTQAo<4d2(gNP9dd;tS%8MVe6Y}P5YX_64Fq=+r})a$xG>r11>$E!bqjgJ~NvW#gR-&(+)H<}L?Ob?G| zRq}C(6q|}?SAOpYN-a8kTfYTWO41+SM9{7rxKCbn!Zh&$_hv#L>L#YI_b0vz;BXz1!9vDQUYsfd5ubfRFH=A@eBDO?{gT*+3C0iaJfjY5w#2m zn%Ny`Vp##GK3-QhTANv15;G_%)9qfE3|?N6RSHp~M$g^;gq0iKZWtCgGHqK?0_xDL zoC62Qi>|T}@NK(9JP{xvs-FD>!~?-U&n(#T+!sqs)me*kZRH$B4Yt*ox4=G?WmHt$ zPer}xoR|wxYb3$KB#f%RBkxv%Y&!~CdtSwSYb}(?EQTV{fPL!kAJPyB<Rb}qiq$-+Sx_%Vo{bPqj`m&1C`d^^B5TS5JA=^YtbTQO~!5>*XeoY$3 zOCV=A`oVf6JNMy!^5W_Pv8#Gaw|*u5QGyECo-0gVWPKco;*P6Bl!zU2R}gH@Uyl3q zO*~E2*Salnp)5oI@nGk0L?EtGulM55hgyaciMk7;%8{CYO9}$fq)7{M03BzL;$KplFnBC%Ml6A%X!CE;4$D~Q*4zKCjToH9&B4|=EB*lqMRNk0R3QUyHb z-FXSeCq<1AlPU_5Zj*X8WEjV_qAVA7{}PGX-{-L-U#x|aS|VtY*!Jl{x?5h>s$2U5 z1@)t{{M!&i;vD)xWJBL8ap(+>gnZbF!;!cq2gfY}N0HGZuskhZ5}LlAS%!CF7!K97 zVkUf7n_GIrj)5`!fv zF*LI;v(btB!55d3g)ipBp)YYGol8;+-CNUghdeexc19l>BorLlWQ{Q-F|Sx)$sXK` zG$EQht{&DH$5?TvE)rZKE+7Facg(veH7Qe*#njl$v}&TZu8;!LfleE9&3C(8L{=^2s4n?wBd$Z>W}lWiAniA$3U~cGzXTU0nf;ZG)-|oJ#J5SoO{po+Yh5apwlgK{ zSIFaE09|igxCDx(NaB0C_;+oBWjG(TiV%1w4hp_w>R(0U^8UP@b6lUkt)|$WBz=u$ zSJpLSuEJ3ma^g-h^b9< zE*`i;*e^c`N|&Y?x0vOOCJ8sv=ow zeLNGsUvGNvn4U9|v_{!HEvk;a0M&?OKahU2pxP?jC6WsCb|U_N*4F#bfFLYVp(0k0huIgEFQv#<1avxT;`0a^TC!+Qdx}Xp4pJ z#DssIbkITvwr6EId3a(GD(Ln_QgE+`y1ZLqWZV}rK{gYQ8FwAc&@g5$73&y2M#GSr z20*&#-P43Nybz-}nJxt)`#8|lR%ZwYJ!3KYv~%<<0T#|jzG@R$_nM=SN1tTlre4O+)U z)t=`ms23(r0|_n5@yZfmpSO9}4f_+bz?>vSX`LeScr&?l2*1+6N9I{n1o8!3;F0cG zCd#P^9G<~(cA2}WtYzBpCpF29m@}+;!I6+Kf$Z-K$DL8z-d+@6us5PU08Lsk;3^V~ zi5>AFm>)%|be1#M{|m%$L}d{p%B8$OQ3jRxwk)0{o%luD;%qHWEY|PO0Du&^ZnW0J zb}gfCSA!&8R#W9j+|3`giea;L-@NNaNq;g-`bqw%8q%8@(QvfCh_MMCu@}w;9{VuN z=aEYkC`kN^?o;H6^m!|9GNRdbhhTKUQo(33LzVnHq#M2FSL1Rcxk zMw|z-|1D1Q^t{4UNqQr@Cd6X}vZ;|!?`};V$N&!^wliPI%-x;|Wxr9mf9C#$*{svi z?n`vgdiE}_nslSYHRmr8&pq#LDXRa$C(p*QOB!)btavZoH5xGUiz21Z=;;=H*X8 zC>2vf>=a0X@a;eqi8cch;9&QY@osMqn2S!Q`>*NPIka@K!*O?EX3=S@z}RbZ93lzf ziSztpn!|R}gz2DkdidOAv8~K~I_Da4IAw5f)K05BE~KTtELHqQw}E9W)lyZQQ$vU* z&*$`qnikxXoYMWLqAhP;(?yi|pSlD=uNaf8DLQw{n~tu{pst8u_r2#BP8~$E(iqCg zgAwS;64ImwWDET@>8Bqf4gl%(QDnzO#M%CU@96|NR9K}bu3d)mvkoI1f!Afx{fGFtCd&k`Ed)MyrMYg{@y5~}9+@PAHY z&UF>}yyHDi<1GTdCeYv&!QGo&*=sBGT&Az~rixn3dXIHTziVW$gF_rneRjQ@U73iw zW}jAo5@TZRsL9UOU<6^gFK+ee@s+mE&rl`fkrJNk8njf0ceqrKifX{?x zB(lUqwGxxOj_p*X9wlH(!c(3poqz9)wzDN>XPAh&-o<_$z>Uw$PsXOd(hdYpj*DQW zY3B8AT$S-$fMj|zu`TE7kQP^R^6?PIL^wJit)E+`fj46_GSyC_W`?-bM>G}@&|FF( z&Q5%wIz}h#F_sOfqfDEgGYSwgP8qG?*$^j=hfQjAAYTB+i|E}(iA@kMSy6g;BCh9R ziBPSRZFDp6jj9}*cVsUX%7xbh->~Y_!zHO@|4?um@*tZlBW=`H&;Yc4u`q$n5V}5; zBaU%4AsRIwfA9ffF|UasHHgt`PEMbkm^#1L<&_aiG*n)S6kV*zF66N;N}nu|A`|Q) zO9{6^(0uV?0fJ+L4yWP%qCQYo?=jv|FP(yWx{(vRyH$=ow|1pm>1V5qNt%9y$o*y= zo049$K42{V;%S?#Wb?wD!vTdzd3H^yW=wun+iBTDEQeULW~dbDTs6ODHk9(BP)f~g z3H;gI>W)D1*>!%^PLP*TLkM~)h0U1PSa2T?RGBkUWzJ}ofK*wks|2LVQmO=ij{#AO zn`*)s4uXiHWh5)CB#^T?h0 zh}tEs%d&#-WLAuMVWCA=MD0C6wk{eKBPPS!XwPD}NT`NMq#xwz*|0HN(K!f)ZNjiV zgITbSXuVdq6|^4;W9l8C&|K-aX~PPcQHeACDHI?qI;4KUQ+6E_BUN$emI{Qz$AMgp zN%>$3G1UfcWiCfyf@fMCRX8KOt>-g9b!e2KwEP3$Sn2#&Sv#kAQsaF)YOVs)N zf?%xjW)^HW<5=5Tceqkl8vBjsp+`;A-2>A&dpJF_$Qj(T`COD@X7MMo!M*Jl*?iUA zKMnSYpSFmeVL~#CCubwkR#!|l1Hc$+(2H3ek_GPNUKXvhtI?kmd|&t?d;tpmLA@Z2 zsxTvmcC9;F@!WIZ1$S^H-dbSEmb&E^;$4q<_ut@)QsiI_nqY$^q7~$v4aYDUlXsgr zNd(_VIDL{emDtK)FD_mORk33p(^UgTJ8l$V>@iT=Rvt1vdA9hA2cQZwRAIbV7s1VQ zi4EoG9E^@Jef5OYr3i?6Eg%BhbEuu1D$On}C3-2#h`QgI#&W2B7bp20m=to7?29tv z^6+yyitpma0(6td*1COao}Ta#S!?Sx9j_xi+Gx5s*;XLrI2~M8flJv1p3ZU+nP8o* z!-YOC#DK9ut^Z- zMj1(J&=>|9l8_y`a9MAS9uy*}wTadAXsM%5&G)6-D_Muf-)XovZS z&L9E%w3qGY5^ftYHT0DHQHXQCx3M{Okr@iW;K7hT<>vg?`I`53Z}Qgb8Tk%1tztZ$ zVo@iiFxxagQE^2Iq#uqy?m1EQi$Qxus%n1%oki8?qu7B2`of? z_iYi%D#X2$Hl&*Lf%4!)Ut{XVaUIjX`bvnu{dWQ|aF66*dm)QwC0uGjWi zcd}LS?BO?G??3#?Bli>}Klj?-tmZS5ZhU#);f8*;%U6Zp+l$#L2a_ctC6 zAAEV=YtJ^n_J&pQ@;x3dXIn}!LG2RDy_yY{d_cT+Eg9NWej5Kk&t#21sJUJo;eP0LA zjm-o9&N~Ir(yr1d3Zfymm~u z*;a3p33r3E#;P~XCIrs=;frWM-3JvAkq$j<X@0z6&j- zB$86}JOma|FN{cxeZtK>Kr*au020`XrzJcw&FMCegPli|P212krm}N)($^c-N8+%+ z4P;4Aj0hit#U9b19`)ZM2xvg&gX-!D)8@w_<&1^z3-`e~U~4DXf+}`V zIlCc{sR>vUdHs=o^@|wAUH>pFgS zi9!Sh>l%3x`&C}9kQZ*t&@UIu3zt^t7b1_nyCkMZicOH0N%jjAYsdHwoS-B7yk!o< z96HsH?;@vAH*-wGe!w58c{iJg^ZagD+oY^A2Tsrp+g( zrAMh<%usF8deop)3VC~7;}}VPfh^lD`V;`n5LGv7F(Rj+8|dA#L5d%s4NpjRKOSR(U+ztA?VTpC890dC$ z@rTJJ*3DdO(5DV#4`6%otRtaw^zbckL{P|6qGQF}iL`pG86^Ce1pSKt?Y|*tw7qpU z=}utP3z+qu)^Rx8bXJ+3YU89{x~1r+Vb>L4LN-wd!Fir*qI7I^-8bGpk!f@iI3s== z4p`$Qfxb5TqnLu2O5fLw1+4S6ZAiicB$ze0F2D<-=stucaAay(`Qi((Z819_292!4 zUPV0gJk4@f`)x)xN3kBB+HYGC1wGP;TnWR-9>&?zc!pVQ+Ww-pBUaH7Zi7C$j_So$Od)w-dzxfBabZEffAE-||ZMk-Q zd!=c)eQ080HQhzkfBjB8|7SF5dwCdcMBTz5qT=)&$IwRUb4-bW?p%pK1H#x6a!5l= z>)lTQIuz5C^0zwexIV&zsAc6gH%DF6!TowMmzvW0VMMK@o}7~?0d&#VxQ4l~;P0&N zgx84j!Ew2cKJz@0Y3R@fND?eVk{h8hY~fxr+>!VyBTaV|fW8#?V4FVNQN_zvdSK28 z!fEJ8&dh|jMsR$PeoE%23Dfs&c#h7%*2<{*9S*jEPH4(5WC4~PVKO(C_=ZO1_Zbum zJUp-G|9VU}U(o|7XG4wyC^q=kgv7&C5jd>#q+@moOysHE*|fw?JJW_a_**(ATnO5b zMa@ln=mpXB8%t{v{B74~QxELwr3%9qpIRpT=&s-MDodG5dC#W4y{pg8uF|jH+jYc# zt<rpeKz$Fp6C;lPzB^Swx&3fIVSg;y9yWRt|j!gsr9ol zHH%!mPhFl(ZQC{8&ix*_94Ff4vtJ+N72ouAG4;Vaxt@H9Qppo}@}6$$Hnw5N)YrNB z5*4~4I`EHVuGBo3=TkUzWcD*HTM_?o^ahHt39aXvZ4r1%&*@pHB8_G;IN>srR;!TV z2cLx?aiA6Oyw@(v2JOLoVS>9Z(0e(lomy`!WrBq*b}*mz?#qOj`q9(54cd>uMF^2t zayi0${WMZ>ga&W4`--W1ivI~*QMEwes!4abpvxG90Mz!&j{rn(lKklxxm2O=iMe62 zk7t8U+PD4*Sh?-8)`Ez71pz<+0K7`<6^jk|t&zx6=!lJF2oGzVe*ChQ zBVH*WG4XQRU>@D%HlDr#Y{n}hxN`?Aa`8?W{4LfNW=l�u8p(9~&C5FlR*e4cr2W zkeheTCh8zMuHFLIxx-XLJVuG}(b≥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 literal 0 HcmV?d00001 diff --git a/build/premake4.lua b/build/premake4.lua new file mode 100644 index 0000000..ed80bb5 --- /dev/null +++ b/build/premake4.lua @@ -0,0 +1,198 @@ +--add the 0 so the solution comes first in the directory (when sorted on name) +--print "uncomment this hello premake4 world for debugging the script" + +solution "0BulletSolution" + + newoption { + trigger = "ios", + description = "Enable iOS target (requires xcode4)" + } + + newoption { + trigger = "without-demos", + description = "Disable demos and extras" + } + + newoption { + trigger = "with-double-precision", + description = "Enable double precision build" + } + + + newoption { + trigger = "with-nacl", + description = "Enable Native Client build" + } + + newoption { + trigger = "with-dx11", + description = "Enable DirectX11 build" + } + + newoption { + trigger = "with-opencl", + description = "Enable OpenCL builds (various SDKs)" + } + + newoption { + trigger = "with-opencl-amd", + description = "Enable OpenCL builds (AMD SDK)" + } + + newoption { + trigger = "with-opencl-intel", + description = "Enable OpenCL builds (Intel SDK)" + } + newoption { + trigger = "with-opencl-nvidia", + description = "Enable OpenCL builds (NVIDIA SDK)" + } + + + configurations {"Release", "Debug"} + configuration "Release" + flags { "Optimize", "StaticRuntime", "NoMinimalRebuild", "FloatFast"} + configuration "Debug" + flags { "Symbols", "StaticRuntime" , "NoMinimalRebuild", "NoEditAndContinue" ,"FloatFast"} + + platforms {"x32", "x64"} + --platforms {"x32"} + + configuration {"Windows"} + defines { "_CRT_SECURE_NO_WARNINGS","_CRT_SECURE_NO_DEPRECATE"} + + configuration{} + + postfix=""; + + if _OPTIONS["with-double-precision"] then + defines {"BT_USE_DOUBLE_PRECISION"} + end + + if _ACTION == "xcode4" then + if _OPTIONS["ios"] then + postfix = "ios"; + xcodebuildsettings + { + 'INFOPLIST_FILE = "../../Test/Info.plist"', + 'CODE_SIGN_IDENTITY = "iPhone Developer"', + "SDKROOT = iphoneos", + 'ARCHS = "armv7"', + 'TARGETED_DEVICE_FAMILY = "1,2"', + 'VALID_ARCHS = "armv7"', + } + else + xcodebuildsettings + { + 'ARCHS = "$(ARCHS_STANDARD_32_BIT) $(ARCHS_STANDARD_64_BIT)"', + 'VALID_ARCHS = "x86_64 i386"', + } + end + else + + end + + act = "" + + if _ACTION then + act = _ACTION + end + configuration {"x32"} + targetsuffix ("_" .. act) + configuration "x64" + targetsuffix ("_" .. act .. "_64" ) + configuration {"x64", "debug"} + targetsuffix ("_" .. act .. "_x64_debug") + configuration {"x64", "release"} + targetsuffix ("_" .. act .. "_x64_release" ) + configuration {"x32", "debug"} + targetsuffix ("_" .. act .. "_debug" ) + + configuration{} + + + +if not _OPTIONS["with-nacl"] then + + flags { "NoRTTI"} + targetdir "../bin" + + -- Disable exception handling on MSVC 2008 and higher. MSVC 2005 without service pack has some linker issue (ConvexDecompositionDemo uses STL through HACD library) + if _ACTION == "vs2010" or _ACTION=="vs2008" then + flags { "NoExceptions"} + defines { "_HAS_EXCEPTIONS=0" } + end + + -- Multithreaded compiling + if _ACTION == "vs2010" then + buildoptions { "/MP" } + end + + +else + targetdir "../bin_html" +end + + + dofile ("findOpenCL.lua") + dofile ("findDirectX11.lua") + + language "C++" + + location("./" .. act .. postfix) + + + if _OPTIONS["with-dx11"] then + include "../Demos/DX11ClothDemo" + include "../src/BulletMultiThreaded/GpuSoftBodySolvers/DX11" + end + +--choose any OpenCL sdk that is installed on the system + if _OPTIONS["with-opencl"] then + include "../Demos/OpenCLClothDemo/AMD" + include "../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD" + include "../Demos/OpenCLClothDemo/NVidia" + include "../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia" + include "../Demos/OpenCLClothDemo/Intel" + include "../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel" + end + +--choose a particular OpenCL sdk, this is useful for distributing project files that just work for one OpenCL SDK + if _OPTIONS["with-opencl-amd"] then + include "../Demos/OpenCLClothDemo/AMD" + include "../Demos/OpenGL" + include "../Demos/SoftDemo/AMD" + include "../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD" + end + + if _OPTIONS["with-opencl-intel"] then + include "../Demos/OpenCLClothDemo/Intel" + include "../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel" + end + + if _OPTIONS["with-opencl-nvidia"] then + include "../Demos/OpenCLClothDemo/NVidia" + include "../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia" + end + + if not _OPTIONS["without-demos"] then + if not _OPTIONS["ios"] then + include "../Demos" + end + include "../Extras" + end + + + if _OPTIONS["with-nacl"] then + include "../Demos/NativeClient" + else + include "../src/LinearMath" + include "../src/BulletCollision" + include "../src/BulletDynamics" + include "../src/BulletSoftBody" + end + + include "../Test" + include "../Demos/HelloWorld" + include "../Demos/Benchmarks" + diff --git a/build/premake4_linux b/build/premake4_linux new file mode 100755 index 0000000000000000000000000000000000000000..1ce06624433691513eed6800bbc411cf4d4aac55 GIT binary patch literal 350460 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�%TMJG8$Tj`Wo`z!@?3*ufJNEBzphG|f? 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�r?G)YSUw2 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

    m%$b~J??)5?DD^1L^*38plUF(%sKz=1vUhwK z=Zm<6C_gtJ%oh~~Gp;EWV`Q>PjfsyOg6$o+s3n$fJ@-EOc z^ZBSS`aN_0$qfDUnLrK}M$wMx$n?CM2|WD`CZ1-|Nw{~?*+cDC%G?RiX_i?~FUH&8>>&`-KCr*+hf8=p0Nc-J?buG+Cpkn{K zF#kK+wJn(w?42uHqgWI(bZDn=S ztoE~;@Q%$Yu7&IMkKi^sZS^?3o7MWqczE|?w?QtV)z>b6E*tY)iPgA#2e+o$~l2hf&ncla4$ub;{FQwk6y=1Cgh;Q=YTcEr@E? z=gG&O#4Q-tm`yX28lXi3E}Salp$*79eN~tH>l74^Tyff}A(?{ZOuJe9Bo^b)SmUyck@GjJfkE_d; zIBkXH@K&?{sxAsY@7dk7jnlk3WIkPQ?1o9uV=zQ8WDbfRtU5J3n4veOIN25Vf2OB)v-0s{eioIb0jstnGa*A_+y+jrP`tRtHKHJG{XlJEWC^T6S;yR=7kX&b-wwnYyZO?v(AWjGCH z=T7if_{}YEJ_u&fW3gbSSz%)qWIg(Y30O0skkQtmSSmGFgfmp#L#H<9v}r$k9H9B3 zs3BdgST?)a&BekVp{2;-t!UP&@4<^++|n)jeGt4ZzZ+s#^aT1<%TsXRlUF+Cqr!KS zD%=bOqO!tCVXRlH?ha~4E+d$V<}+F~CwF>rb2k9Rpw)~?63#D)$m?z6wa~B87_h?jSSt%@3!J7CqyGI z3f8u1dfRoCk45HCyoy_@mU%tFO_4PKrq_RrNV4Vs8)-s6AW7Sn??q@Q+oToPuupwbM7qnNcwoI!#41}q3LUQ!E@0ehiI@DfGB(~aAqpLQsrC?o zvB=*QyvXmETwQY%Y$s0j!Ir9(-t6E76gFjPAtOvt(6`yX5EO{6#MNUZP8yP8(a)rz z{ul(dH!|ug8vL=qW$<*t@k=oA@~A_Ijhos1Tpk6#z5XQ)x+7+=nR763x;?aLFASBv z;Mf*SS}?VKQX0XF&ydXy7rm3g>fAL|?5lhOoJh9o)$v8GXh-x@tK19R9DG$2N4Ukf z`R+%wB)8j-!T1FSy%xg-xo>mP75(C}QnStd@;Hs(q^kVS2tH!q_AA7+uyiq&3Jc zp;ml|6B;`UJRLf)@v%XkWCXRL!kiQ`emhFy3n zk{O}5@$T5n4xb^b$Bsf{7@>MeY!=%sX)5rJBQ!?Cn?KEvNA?CLn;Qt( zTIw}6pl)0;k|G#pA2Q?#PXiZY+Jg!YZQDrG65?{J+1ZoW{bP{4kvHcaAOaR^;sSq;<<#%xmAT#q!@|5iW^LV%|HGjp z_#cP>ZK1QoR6TA7p*?}=rMVlJ_x|oBCw6*+@5X!0en0HksnOdUDg`FR+oHB5*GXIU zdXJF+Mq~E-Qpjz{n*iYM@LR+LM?>F)W`YWjG8U&LAEBsk9@n-f8*dA6-DBQ^Cl6{Hdyvr_2-h~AiIq+Z zehHCsM*~I9Rn7BZA-ig%9-Em?RA*I?6d-K-7odO<+J*EuY0~grl!ef>N;15foWX|? z5|^XzL`h8AoAarF;-!^lxEZr_(_*QroP|c{CANK70tVzZpH zF;kmeAqs~!;WM#tYN#z@4c3eJYF3^5eORoaEqITlqnXLFMufpUmK?Uhm0s%z-i~3r z8FsB8t5x3)nwcB0#>V|P7uT57XiwOIIcRHlt@>It7^ag}eJ@|?(QvP}`eD4Qk`|8U zQd1=W*iY?M(^suJ1r>nmTS=RtTZsXJiR5Y9_COC2KQ2RC(r$m2zGJr%N&Cc6P*M>K z!>tMZP{<%``UX^5=esCxa9}hPAIe)Y3L%)kJc5bb55BKz8>wy!7t>myPYoO|ON=8E zku#YnJE5$cR-;!$_c(oWH8dfGMCF#q&-V1Uu+D&ipc9owz3UKZ?^o^N_udT#SDirF zwC`+?(T>Y|>{;|NR{jVMN)-QRAF^-WjuP-^a2GdUgLFod4MckzaE6W^oecL1d~>ix zBzAdE!%1I&biY1vIL_ z<}_gqGfv&^2S7;aH^n-2eQMLO#>(zN06n%%-zt)ei|U1yb48%F2MV z6nOc837;v=m2+xKKjEb#@$(lLKNz$^Im6s~D-^_(kuhuL$k-j>Zg+cX{oNajV9n`C z(JNLpKMluIn^oXke>LZpwHv2Ek6MfQE^&^n_b~KRttAEu>BvFcRS5l(`6LUq^wanS z?!^B|ta1rdpeewu+KX`Bz_6-VsP?x~Q7zu#oKf}n$r4#Lw2UBXH(~$DupXE94f6ho zyk95f1AMRQ&-c(;yoW;%;(xMH(K(?9F3=y0)BWA4Q3vKet z&^4G()pgglHR)~h;0N6{NPB2IkPp3~Rj3Yvh3~J&wAsBxj~9! zexdd#>`i}$TH7GafU5mpOm-rpkxw+1l9{S|$md`|$8aoxS~eZ|M6^LIG#>d^?V=!y z7OwNaD9G}qb-bEdz$ZZ{_A*?x0u$X*~yoT;~a+G-4>1&OM;L5_7QT zDgdm*04AWg#m5(2Ky{1U1z4kE#%W{ybNFg*rM}R%&A-@-9q7x=t^8mQ@!(+gIHzkC79@OGaR^)Q5pD^b8eR}I$E%XQ#h$yq| z0Ne>m6`)XcS(a1$ll3nmAM|yI&pWgsh>D%Qjyf9=vfqREBh0i&>00iPwz#dbkk^24CtI!SWZFHEJ zrPy)&0DC2PPqWqx#|bJj74q9UOeHMx;l{+QrAk%s>qXF;+*B>c@GC7{wTl?ImYQtG z#ZkiOe+2b7N@+MM#s;n>RkIRMem<(k?rphDY)#2+Rs8|Zf2t%qL>UP7PB1tEP;A_p zvp;Y?PEiwo&WaK_a$vEUAwsvNexn8wsS3(u4Aww>8&Y&vtcpiZR12Bf<nmKK2SkcOTKDJ=FjUt$MFy z(r^sa1{_;VL$R;Emg-h{|IxQo_4jsApbhr4SzTuu`|nFCLWK^D+gW}FpFhewUR zEX}u~hv~^F@dp+n8Ys4%{))9`YhyV{m8AFK@;mCpU5);`-p?fbiJ4dlHBM&lzUvLV zHS0UFvfnI0u-S^Al$7c_R2IKA*RQYeW_W^G#(u0=PxTMIFMad>WKDe7XgT?%_kE*< zcT=D7c^gyi%Z$E&)?t#*15$`MD5f$zYRnrDl0V%y0AF#Kc;xj(GzKThyyn!S?qu z$}*xaV2S&eG)#r_ZvunWO>?1_p#_%~q}^4YnNkA6W%z=rIc5GpZv+uTmwjda>}ni> zQ<2uhu6OUK`AB(txT zFiR2YwSg4!-bhPKRFq?0aT?v{ocLxF{C6$M^xsvH#^8PGWCaui+F~v78z1Q5O#96m zuAlPD0|+0hH~Q^!SYdZYA5N>tM4-s*Hxc7fZ%B)#^1_YoPAJSt!DF-`dL*is%|G&6 zTrXk$Y+taiRTCYLSwLa>$Tz^2kzf3O;@$;5&Z^8Gf76CGgg{y?w5wehLqjH|ON-9<&VUbh8oLAwZo zii(KRg^59|(&cXZ|9+q6ocA)B6j=B7`S;VjbKY}(&U2pIdCuhp;9S1Vf912sk2he^ z2S?&@O6fbNV69qK7W9PfVeBu5!*0)hIRy9k^H|nevg(twPR8YOk^%nEZwO9*4SZIJ zq({XRfB13oFYQ9NPBEu_8_-9z4~bLr^%+Rbyly&iu(9k-X2&mAjIcRy=4ChplYR!Z z@A=^5?jOv=MC60hEIEVp1jikfzk3+0zCZIwy5ghd*otnD09utVcSrIVaRc|7;UAP_ zBS$Aj^7!WUE8X{#JV$>ZHDxa?!{^#2W**tLTu^rP#G7y03@DEO3RF2E^LtzzJCXs# z`H8$7G(LK&FXrqCO7gsAwxCtq7$z-_KGSjQY}C6Hf93ci3dlwFD@$0at$^VViM#0X znaQ&5`zvs>+h~=!6FYK5u44pCO-xS%U=0=MdIT3!e{_Wp?)q7vp;zqo`T; zJV>9eLao_rXX0+q58#&A?jJ+ul)veuXD|5SXee{6_Q3G5lFHrR0zkP7E_&=mo1VEp za|Gv@UdcQ<`m@}Q!%MKkp}DMn=@hKGACV8QVJTbB1sF9k7ifaCbW&}((o2?rb#KfZ z8~BB4Aku`WMDBxyYTuNr1 z&b*O639E=1e6jpU?UTIz?oscw7gykd-G_Frz{)ZdYAYb60y!P0j?(94KOig(nKBnj zX><+nI@vFV(o;Tq8sVeVxg3p;&c#IjAZ#7ImoxW4Q5avsK@wpgKMPIbL6vfhw*w+Y93F8!08qVGK@jlfuqa60h z81;SE!7TV&#u7ACamo7t5wGol#Lkyt6oU=x_jfZJcV==aG^TPP^B81G{tXyPL^#%W zPs{Cod=X^j!OC5~!Z>9&?#x~~ZM0%|@Kvlhbt5KoB-ei!(Tgsfk{Ot`?YRXnA8h>E z9<=5xA3pZp^dA~GNGhcZc8>&a&y!CO;y zvGMw2sdwQE>?QlSmG`WY{g1s?|JwCG%%*potC?sWC_=FK`!%8;r-g=gf{Y#l;@CLN zC{P3KG0t8`zJPeHgnbV5mb((musib`L7erkg1}bHz;(!(Z8I{jj5cH*!tI>(uccoZ z-ZvvNUnzI$B#;iiD}=Wd{7lbsQ2jJsr!55!uAs=lNgI*~+eS8M-Ki@o@SP=WW``;+ zy}l-k8CJtdcTG(FIS?kdDVO5X2PjL-dI&yP;XiN(Qs&hnpT;!@D{&z}7DR$o^h;-A zjR@z9Q4enH=hhSGo*}H9bAfe&Git@rLE_{6gCDk+OPRQGClC1QSIrg{}0= zD?i017SK$l`3cNlbK7B_ypa7+#qi=qPU>v1u_$y@LID4Og6Lf1BHArZwqj9cB~~o* zxyJb=%ZCr*j)IajK4etZVD&Re#%p{-U*^l-T($Rhdr&#Q-irc%zP4fU9|gi z7eT~?WawufM9Yypw%o%8cJ#ZV;Dm<(mrv2EHK8ISD7W5#KXcLUCRX?!j^_}oqSkk- zx*=GV&p6BNxZ(p)CL1g2FQtJE1(7brf%kH-w$azZ68sQn{thrjp><>7F&nolLTGl3 z?XhhLHYa~Z1AL3igaaUT5mZxd8I2g637YKWc25Cpuv3&Q<>>S|*ew7! zK@0Nw8N3Ge4fsA%m4m%Wp2oJ)52=JUKAvm7=eo3YbF0kOcxQq1=Bk{XRbh8S{&Fc= z=4npx-aUbJaoufg+}rGtt5?58_qMEtxL?=g$mUzI)&ec9>m(eY{PKV1~tsEq^e*WP1RK8DiXouk_ z6GRA_zN+#0QhD zsOi5obxU2(-|6NNgC}#h=gJG{Yuy~F|2;ga(IEK~PlJ$)ECWy{NGN+&}} ze;?*FH|yK7P)Wgr+)ZVG(!6Yz#Rwj1%4MlsA$$W*!dAD5`{jELYM*U8*TK%)%}k_*f#-A*ix8X zD?$PL@%&C86kmIS_>CN)6`kLDlE^}nN09!+mt@c|TCi5DxP1<_ynH`MTS=9lS*sYVMDb4Y|i z{V}UtxJkWO2QQ`@%SW_-__A~mt(jN>_QwYhi;X@vTwj0e#=#=ZEdz-4$A&(@{XSzm zP|XgEg>mFxQRtVMr_&D`bZsXGdQD5`A4Dc)67d+gmbs^vd_KH@U~PkIE4O<~o5*DG z&V2^5N*w_@r8)5TE&}#Kw^pGgn1EJYpXJitD&-Cn}zmkH_WQLxio5K`?&%t+S{?izFi=x+*g6@7(P}GU}|FPT+C5wjg zH@u7fFV~RIU;Q26xg47;&& zgDTX6J$fC30nmh8e#$$Cj_0Q;Xzf}ich#{)Lx+b7fcqBK9dyFsLNDGJ@@O@#?&@+{}ThTMGGPHgiAKyX!_%!d>`c{#843=dU=e9HtDMbpr z1e3-VAg4Wp?b@{)pTW#A^HOEgmOMzhvgr{_8i8y?dVo+JWPVcFbgZ)J5BYy(Eg*iG zj$*guC((t>mV5?0y7BO$jrq!(zbMm~Io2RmeeazlqP_(4`N`r2Qj?O2Q1cbQAdph; zkGmg;5c>ym^Eo1ABPXzO=}c~T=N8cbB4cNN3mIYWw81>LCIFPNr?%kRtH@qnHvIZz zEQ8R|ebVsjC#5H6PtL9?8!hMY41(@Q=QD6w_>{+z& z|NatbShi%DY0+=*R~p&*WkSXLxT!)x}{xlD;&8HB$dlF?Vrwqzi0Ps zGxCZZB+4}javMBa$El3#LA~xL2^R}d=9?CaCmCf9I?|nn(#sDtoa7v6m{fA0VRGq# zhBEw}jKA`-0}ZD*TOP0kWVY3};Oah0$8b>)!Xq`(mk;3P&eavUzy4b;(vm*emA|-w zZ>B4o;o`>^rhGkl>P-KPorH?Z+GLX30z`6JncH|2Gy82|4*2A;`F){jr76(L8NOCt z-dWhnR*Tgj2MCxK(E_#KYtYi;C`CmQ*T#Qo!+BWCC+iOhd(HeM>h!}1+J-o}Qv%geIcXV(5? z`1q;Ni$gP%_|#_j*mUG?ehO?4S#WuRNc4a2S@uD^9L0c}KBn|qwuDSlfeSi-lV-hg%WTj>4Ecg7`Fpy7e|VUl z%F2PN$P@M^ipZn+7m=2^pQ?Q=9HmcW@QD;u1W_(MpN>Y+_MmN>i*aoGoXo3Pr@Q$H zjtM=F#%_TX>D+*I8=xWG=_S;n{$z z3Zl;miqVtY#^>@Mg*vSKPUJbPLu|Va2c3R|DF+Wa z9V}ghOpdJ2`Aa;XUx^YshMtF)oS#U~z`2RMtZ{S@8QHW{ozI_zjPA5ma#6sHu0wME z38a~#MDOSlL2UN&irg)CD{aabgmSm|DRn!JbxJ-zvA+BsaQVTC;~=bE?d`f2f1z0Yu&#l4fhSABm-U4{Ww`#cQ->H8r z{UQ=);&>17i;o|L2*W1!u=JZN>W7}dS_~ovp}#$#2oY&1H&Y=ZYZf7ag@g!)4xh^Y z85EbvoWB9FhTf)S2InJ1DeYfh7fL(Lw)D0s?eVTa$InFlLTNbY4@$cTYYx2!*;fa5 zH{+wOkHR4SI#mrX@mn|JU@6xT`8mXuN^>_{VvsR|9nTZ0(nW$DiRfcQ<081AfiH>K ztTAv^b0E_Xu-Hn(dH4dq%#|VZG3z*^I4Rhf%ke6m!Rj?SgL7IpTC{KN^G`fH?;@W<+EW!fe;DHyfz3`tiBfhM={P$$`{{muUj; z3cD0*6)b4turk5OX|g%PjhrEoA*|eFFP~X^|M2V88GJL*SeRl^Tssw=#Bth{vog2@ z0OC{=Won*3K2s92YeKoTM>AIvgodL4pmagD;mu6r0^dbLo_hedz|ao26ZEZE0RS%W zRm?NQJcnJSt>ib`6igMxuGKPhpL2=wP3W9rt{80zOEI+NuB{lpf66cp`2HaC_~^Up zkEGtu13|gX6H6LuvFOV??ZiHw_kJ2G>6z$VeksDZ9w+@69AY9RaWER9X^a~|u3dl~ zi!pP1bJtO0;7*nz*zyf-kQ{0mNn^vvB%OpY`&HO480E*ZSBlTfR)uZdxbF`=1nvbp zIL`fANy?n!J$3jZBf!`20uMz(ekqNdC&~l)eGMxx8O{IpK?OwUsLjr z))64}W1I@M$)Cd>;*;8Ei2HP8GMp^g^6VLTOq-5l_mJyURrKPn%Sj7fhO=cm=0NwY zm~__^I7_~tO-{+)$Bn@<2i3U?6-54bFG(-|i)|jL|3T^irV)T*Da-A}CXMV4Da9$e zP7bBi*R|AN3$8GE`S@1W!kkWJi4IfqHP2|0ge4MUkQw0XfDdG=h~`Ed_T>949X#k zZyS?pQ-6kWN#Cghf)i(#)L(2))B7BRkOl7r2sfI)D)ajR->>zInyC+tyM2c=N8+J_ z>Pu^ZR2=2Kj1y4E2qIEYnHnGWCvNn<5^-Gj|VE8)hr@%+uxcgx)j%iPNdH;koS8cMZ zrergBvqqAx+V29=o4+Ua(l_Iq-o!Yh!o=+IGJfy*hO*Min}3cX*$d_Sx)UpR{ukar zM)=mQUYQGgL%*=T{H?RFoc*szM=fxDmEr6z>MG$VL27Y}4x%M)sff6xu87k}5phc) zAPI)eIZKMq0YKTUGr4hP!O$5xMWy*B#5Y(0>@P3N_0K0Fu2rd|CAI zxO`W~)PYpKdj(27EM#jhWGzbE_ZkeVq)7l-RZ+H^N$Q)KfkOr6(?cgpzr=%#RBql{$+?- zu*~Ji!PCYEaLklivU})oMae;%uq&LA_krz1PH~@rrNyf; zUZcNYg{AZH@r+$KvRRTof+FP6(G5)C8QF`T~YtQ033eL5N7Q{e&Qc-(CL@BYao**=!??%p|em;uK(!p;G3nX@30#t z>s0OJzo0GL??!-!_scg{$?R>@VTj_pq(JA5JhooP%K%=0lM}bP;rsHSA@fyI9=|P} zk0K?HBBl|EJ-ZG_f=Lj<7#9a)Ga}JPyFVcD7<_Aa_ ze&CJaHzrkn{56CreL%mMK1cT1@V@MApT7(vQS!#|Xa7)nRpcRLm~?QtY{?yYPzy2l z=Ey^%*y1sT;j0mT(u6;Z@F6dZ(g5JRa~bp9E5Lz|4P!nJGjegpsgQ3by z8Ves};WI}DG2jy0QF-OZPn%xqjI<)gnr$S1dO9EC=C6?Smukmv<{**i{}d#Ey(+rn z)=u>3di?Fd->2|*2mXG7zgO{R`RsbZId?H;BDZFDpK}H_LPS0_x`p@0AKd@D)Ar}5 z3-)njBXZ}&$Uc4(z4=fHH{xLP%T3Q82Rheeo9~tP86>Z)`!%Wj$4{k=gJqO8SnB7g zpT{P{FhDzW7)~4cH^9NzZz2{^!-F4jvbbYr#S8dQO17mGcSx@AQ^K#_1KMKZzHDXf zPcsjF<6pk?r7vN-^<$ZbxZV1-i6#5H_g4VM%!)jTe`&>{tIGx`TB@`7^2*Ax1tf%t z7>}i|(#DwDfH@cl8CYHPp|XKz-LAp-y{s&QBjcCO$gDVee8rpCQ#ZUXPir1B2iJdX zJd|BEBh$PWU*3VUA#w-3pU{tyyGLGzLqK{5bRHrOvB7LorujBp+L&p+6MKO(&G%$C z9?D@)cJp1s&s>7*f+}}E0PJKV_huq{NA6?!W|X`Kpf;9pLeW$*1J7yL^L5o@xzZA> zp8p(X<@dMJxV(R~6wgO1|7!ovhg07|&!%YMgN-FZ)QH(o0)bt^PdYdwkKy5tmFCQC zC@ITqye+%&&fK~Q-LF^VrqyRQ-iyt4WfN1?+2*?_bVynE!s3Cf#2&_1R*9515^r=9 z=%PVUr={K_*V~B~?nW(yiyUWO2J!bWhG7`8Z(<7jkngoMe@HTABKM|G&)rgwd_Fn% z-dE}8H|QwEE%^6>IVYf32uE%^=&)D7GQKlJqZyRBH+OScne!^HG~7FK4Rj8G%Qaw^ zFNWhTR0Kq_79e+OPpU!IN`fDb16)cef#sLRg)1Qw#rIgla5Wp-cuN~$S5Me@GHe1@bxtiCxswS>Ij7z9D^_cHFg=H)HCUEiJ1x5o=LO2n9l9&?s%3+p zWL_m39G{5$3q@i+jLr0sz1fwR;DR>q1=)eDhOeJcc2WwPyYD56Rsez7QrsT2xBKDq zgf#c%n#vzpv~uPRr=uHXawDnLBrpCH+&r`oKC(4XP{2Q?HLgU+fntUu_dJqq-iKCl zr9c%#L1eE_lD`Y(fz}l=v(8pRd_W0aAI`3L)!n-o*(*WpUBpoO=-`b%L(>P39&ZNX zeu&w?=w}US8YOq&3>Y?F=QP1j40nK6X)ojdV(gD>SqV>r8Yf~1X@qt$% zjT@@&$Tr?IZS-`K$Fy0Xx{3Hc8ufZPT-uq5SQf#qQ*(STH0H zIRJxo+*$Gv*&l@dp$e?elspN}DA{sPrgYI|jK-RRnnqe+FB?{z zo*g;_!I7z$ez0-6cw@fEkDFEQTn3PoX4ZhaG<-*8gzT{LuW z@(hXIH(Gw~&^^P?znN{E{AT_Asp;eur8u@ni#NYY+AG^JIH{y^*BJyoy*JZ8WB9@A zWkn1A@H3~WKU^t`V)ro$QX_Ipry7Y{Hgc+B7J`$s(|ot)5)^azr)$RPWg~}Sb-Q#b zc@O2lBgQ4U?5y9c_Tfz_pl+=g()|Sz&I4 z?@4^6=Iz1vq=jz=W|t#>N6@BpnS9q&_(v{ z|J`)D7kluQ-ME)yhe|BC9gj1X6p<+{KL}zF+`8j9M(WNBAwQXnhTX_&7~xhhz^Fq- zB;axgEMSsSY;!pj4J6o>dkJmJ3>c~RgN&3e(9ipoE>IUpZ|0N}8S{kI_%72EueK!}_RflA$j}>1nU*w`6G0>b6B{J_N_Z#Pm7CAH_37 z27!S&L5&15$%KQA6Lew}WqY3!pN^MZ7qfdOkSLkqfGq28k0buKRjWibDWmT*z!mJ zFI(Oy*yf2U8rd>&rfg{5iv#A6WroaX$=tjb_Bp1hv@{V{F+mQT z6~o%eg#9~WN6IAWPp9OC0{aC9b_ge>8P2k!fLDR~#Y~s3&5Wy&I-m$aaglE1&lNye zNve8ehLgtWKIk+|)pvjCbncd6S4+iolUWv>!!YPDN4Ba&W(4ZXJO$M%)0B{-*FaGp z8aWPO59)E7$u_~5#`41{Sf!bwZgg0GhlUrIIH@BG_OUCj+=A!;B8yf~nwoiZtsKT?s~St7I4$X=L^r6Y5(K;>c8;NdN7h__aouw$q;t;TD{sElB#`h+dL zS}}3RvsPZi8(7(8P@u>dG*n#FHdI;o-%z$_MOo?$asLeI^{1k?M*a#E!6mWxa!G6+ z$Z9gO!)4)A{uNinMsQUK2I&w!w=_L}4{lPx%=mUm*oOqAs?yU?2Zwdzq5SWW1&d~t zyRa9T^oo(Eb$Y7i!1=sKHACuDR3w)yk8EQ_bW0((=Ro~z9^|)KD*-dm+=QbF47bl? zI82r;!!_^QKVl~1^$(@r)|kG4#WbLV!Gx)zEijlcIo)!mNY@8j~_5Y9oqjpFa8$a^cq>sK%@dl-Mb7X&^`S%Agd9cLz2Pswe3)v_eI zef$b8o`Gdw#e{3>s?2Gb<)xMPmEj|nrJ09D?Gm#&+JkzyXL9&rdPFAt=FQu{ zETFd3X~!oaZl#oW+>++@0^$p<*rhmmHbq7Np9QMW&*dCk3P5p1r@L{F*Bf97ta%Eq z+Bi8o$?V+3)Oq-|(0_)IwQ|{Oxiz>}=a1WFU^Rxf4$#P^3l3U$^Kv*o=vc_#jS#N+ zoshYqZ1fw}lZ!JR*hpG2T2E5IsGnn?pGOF1K>XA{UAg>e@hP)HSjO);9gGzztDRAD zRcY4v$bipP;z)Ldc9?lK-$IqU(JK;zYH+#HhwMJiZqAb*O2#hpUr zetuT!XXgVFfX%Tzbc1ZrMK9c9z}NA73J{VvevFwc`VwZ|XRg)0U|}Pdd6tzBfk^l` zDzV-19Z@Lty5n9_eB~84y)dN#a1lr>xIKPsqJs^Xk)ye9AN@~P)H%$tRMFV@iCs*= z)#s<@a{q(S;?3#O151z3`$Wl7xCZ0~320ve`}Ul7}X|GdEyOG=QC<8qJU62BY`;& zkelav99E+u&!o@KHM|L7kEW5 zNx9pN+@C?3A#>fB zj(rN9=w$+b_|}c=R{%HTD<0rVj4N3T(N6xWXx0?eZv}vub|PUMrkL`{W5@AHlk}OO zQI|~x|XbaWn?7J2hcCg7mSin5M_PMwtN zLOD9_@}EZ?QmVy$#PxRZZ z)0AC1h)euAo*Gc`|4KKYSXnAAHHiD&FV>mSUp#AgKNk@y@*i>ez$F;4>G6CSdF6oN zT$m!q^R00(VPub?zWgf!UAhLOaWk@2J4f&>cn6@UZO3f+zXld$WVto#rU#KIg0GNN z71+xNYy%cVPPa{L+Ug?PGX>x_w)`hV_HGozg;SG&DH*aq!mu%;*ACkT)&~djY6LL^ z`OEQJc)~(AOL@3+5h3-r+=BY4LdmUvL{xqk>OgCvN~3IDRO#NiXu&A&Qw9MzDKDr> z_aL(o749xI|Be{5djX`B+tK?zR2MliQh^rDX(z(}i!L5~soePoRPIH)B=eOVz%kn+ zWZQH83U>SfGmZ;UD&I)(f1WPQJTQ7Px^WWj<6izGE*d-|^CZ}aHVriw+IkZ5VU!wL z-X2MzY9(SJkXe9)iiSjs%>V8s3))UXvdJ#~@E1Yz`tG7vs<{Jm01gnZHUMoeGG#

    ~6OyK0ynY7A|C74h|v7bXv6Nnig$zh!cs~Z3*WvyBx!&;3Azh9g-Y+6^k>S2PF(OmzIT%%9sJERIk ziQ$^N?|w$_SITg40RnOI-%V289%bbmT~z)Utfp+_Zu@!%2iK?6ua*L@`wHA41s>$q z2VA4myfYKo@yp&FzxbTlOtDLUsk-wQ6jWA$$^?xg=V8Qk^lp0LTLg^IeK@=O{QsE< z-nf^``$uxScR*qju-xu%&PE8dv>H7H7r;d4H@j7$a*)Zv$n4}J%s{5dzl5Ie`g!Hf zDM+up4+q^M_u%JO*e-ydUt{eNKhI_&cjD)8CUOUU{u^s~_<0U%b@+K68#3?%8|zm5 zjASA=Ty zoAGl&R@6Rr*?kIcbF$5!#ZNffd>ekS$K($DgtE;q~G))F|BJxHig?Xp3h%|vW1e{ zr5oX)3o^Ll6vxFj-FU{1*WP!-nLBVD?YnopHY{SZm)lOBudBO>nBhG*_^a&l-qX^W0+qg`!tt-U1|`?et z#1R~A{=ReANGdoO9IS%MD2Ck1_JO#;CN%{EBLx2695C?z7r+K`W7X)H20fD85A^&( zuKB?QcwdvNTS5Kz^5mBhS=?QFYUYUVbFTTv(YjT6{4SdBRP^xT7b)#t;IaobpOKnN zNIU%i0bnkHQiC}F;e$+2e3_rt{vP*yqR#K|QMvl}>_0kJ;h^sPAmR?}d_OZg%SLAe zist8`%G}?*=VZXJS&e{0*I=l2N!8vUilO!rQnCgzcIp(|qKgLfEG<9SXl*dukZPt$ z?$`l*&tKIz43rv|(U=^xxbjuVft|aT@y?S}Bk-NSooIRh*vNkhq521|uVY8BDDg|C zZbqDL`LSMS(o+79Eyl>uLnAtuJ6_#%&q>bl>b3IRAkVAhxmlhck!QO+yX4s;&whEP z*cvao;&5aN1iv!^HzC&N}ivU=WX)5L!Nia^DcSbEzf)8d9OV8%JWhneq(DbCx{A@|+{j`SQF#o)^h;u{;~(*(lGI@@$glT6u1e=T-9DEYFX~vt6ED z^6ZgkzdTd&9F*tv^4uZMo$}lx&zt3Wt2{p?&(F&9HhJD5&pYLLmpt#5=RNYgSDt(2 z`7L?wljno-d`O;$@2 zy$tPV=-(Ln2}5@>G{Vr|GV}&RTtn!Z3Wgow=Q6vh7`mRJ^B5Xn=n{sy7;0kZ!wg-` z&<2J&8M=(26hjRReT<OwKK#)8Tk-HB^a`iwG82~h%>UBp)f;>8N&5@&Ipm% z6=5jM5IzLujGW03cj}EyV`z|}a)v(65S2vNXBc`J!_)NzhIm+_>#Gd?nxO*>J;~6M z3_ZfoVTK-L=no8WJ*}$*bUShnLsJ;~Cx*^q=r)Gx7~&VAx)w9EhoL5hZeXaLp%g>c zGIR|?pJeDG4E;SrS1`1fp(chNWav_c9%JYthMs1qjv?*?ADP9_BpA#i?_ub4hByiA zn#B;m=ht-}LvMm1x*8dx%cW}rL!5+keT1Q>8R})|35Kp?=z9#^%FsTBKF`p74E-BJ zcQf=IhW>$}|6+(o^16P(&@BwT!q85Jreex9@==CD4D~ZKpP>$h8W`Hl&{~GpG1S7) zN`|&EM4{02afYza16UY>NeaGXD8$fShA_)y# zYiT;wl^94a46UmRt%?n#lhK}dZ?dgx`@r?McV5)X8vLw5KQD*BOfSZH*5k`g&u1DQE4{ z)vJ~*45j<}2NJ1RTPoHbiVX}T214;Z$sbB3q&G{~t_p>#leOheTePn)kqT8O@qZ!y zoF&Ord%VwSKybiG^vC*~fmUZArlDB09rsSJ?{Sd1x_x2DX=z%sv@z1?^hJAPp|(U{ zM^C&h73x5Xy@~d8Pb^eZovd+^sc2hwD6us*(9x6FCM`Ry(e_YupfgRlLuXgFYiys> z8w1+f0hjiUDh!s(2qIzSWr1umnhXe)B`B%vE6rUuxbzSv;O=_j_Genh04 zf#|l_wP|z=0aU@CBz}N36^zM5K7+xueM3~KF$iJX=z zBJ0+#TC>`T_ebLcNk^aETb-5`kW35!Z3FQRZbw%w3fl%^(G-S2M*_r@N++Fd1JQnG zdpy?DUKGWq@s<`3rU9@{N30aEinb=vVOO4Gf@j zk!eP|t&90X(U8Y%UY?%V)>u!dH=Rs{T4SNUMBm)LSZ6d9-x_miPqH{2;8&R|wOVf}N ziGB`pDk_AY1~H<#e$rfjG>u_HfDygv9;Y>t=!r$qxdCE-aJx595JIVeL=XFrZbN@! z=td&clK`!^fxbe?_(w6|Mie;~R8|CbL+eR)l117Qz5PA0L6qtPNDxv=5pL1;SZlhI zT-KFHbo1A8Urz!9#)yGfXB=Q`XE@!jvKxJn{P@*;2-vjLK(sB^N}f@H>Ao*?%1^GV ztHaY--zTK&K>9kA>TU-_gfXT!N@3rX?(23!mjv@H7O{P?ql6TodXWH101ng&Le5Cfi{d8bYQ9_InXAxw#Pb9Hv~{LnPMyUeOp%) zvMoI@0A(Pp_oe%jqEzG|$x#SJ@DxfZ7!D*?Y@jdN6B2|%QMSmCTpZ$%rOH8`^3H*T zSSOvLONe!Os@7SuY1tNMnM0IO^jfusjz&|dSZ_ZDT?rvdI@*??XqRy;ngNO1;;AlV zf`k0XM{4-E>n0}X|CAZ+4o(2eYF8w6w@ zg=Ba(;Z6)h2et?55lI<}whbhb$q>a9{-9^)Et@OSr8SZ6YeyLfqZBNPM7pyJxq1_b zaSaF!KWlgmZNxP;O=SGBBcF`5V%9xri!)noQMHJmDmg$Ret#H=62# z*y>NG9FQu1$cKQkov5NV3&o*ndlE@dl(Al_>lR$l=`3H>6q)U4ie$tPKnYr5$r1!h z>yo7Eo(@lpS+gXG*40cP(m|oVp@Tfa!1$ZkCXIx`8dq!Hs{3o9*(6S50CKd4a&fx_ zy`@EDv%>3i^rVwr!Yn{UECyK+OKojUcR=CAF}^J=ooyH-Fd{TIIEKj%3=*ebEVNW_ zzw}3qI6Q$lpbbKJz=4t&2v>s-s@oj&-Dw3B-7q1X7VsV9OR#Q+o_LfXvj6KDzaps$$8uXg??i_ED^_%_tTS zi%+F{4Wla9`xvqT?7xV%LSVFkw4+HN6gFAkdGd7HV!$I3y7+)C*$JuE4;n~t7+?=M z9RrN$f$qjL(YatgpAcAsPA_Ugjt-3cHdtxx`0Hy=^qL=#PP>D~y7+LC*FvSD)h<4q z{53^$ccV67h+rEi8OjE6Qd%w5(p*9C2FKE?xG)r7I#%jpnU^q)drLM?;BlMrB536)UXp z7@PANHxXkSFF%=sG&e^Jy zD8t!Z)2d7DL=QoyeLLD?AJA5kjFjBo+X{P2w3v$nr>&pTTk7;9i53e5w^%EZ1w5N_ z7AX)XjbZFS^Io2hBJv$V0%S-DYDvGwr2IRr5l{fn%6p!%bg}hIvXPEH^>9^I?I+eH8~rW zu4L+vB6kd8WGSQDH`0I0uR7~!GsG|CDaf#rBDux4Hkf^l<0W~kP2F^ zl7Eot{$VgS|G7GRmMbssXIRFRqEmTbd%GL5A&MaY7Gn#6(FrTMpY16{|9f%V_#>Vx% z8v_?|lk&x#7X;oyVH(t8fJwa9HmucwPGc}oPS-#u`)Z-@#~N_7y)+rtO)`#2U6f#; ze8~3Lf#U5=a!g>PaRSH5AarUP{tk5ug;Z`i(O&4RG!=ruXxP>vQaUsUTV)%qMN|lJ z2fNO?XI#bT_0?1%s>N|JC18L^I@L)RrUDd`uhx;U*a;@g39bnm@=FZ3Nr1tGIm5v$ zx7Mjy0{0lO74P#QYx97!dH($Qjx}E)XgO6vhx$1q1{N?aiNb`T=8z;etI4A9!OpP8 znXMuWThmN)YO1SiYKvvD98t3c={_^cHeaKXtgaIVR(nlo8;DL>w4L#BjB zqx@B~sU{TdKtG^7syk``p$oiAqNatU^Wj;u&%LBBys3IFtY6xJp(H$$#$=-}z@i3L zZ4YMMVrk0EE)?c`tJV~oXGeQpfj?;OxuLT?1gq^53agDw&E6C3L?yNro4zgHj`<#%VRXw&N1WE}lrGSc4)Z!h zHqCoZWCZh0r(oFWOr~4m66k~K*#>J>BheGcO}I(ucR_l(A9GJwk2J*G$(z0kDbui{ zTdg2!brg<1Gl}YsZI`~#?2P2XI#iDIp_BT$^4ZAiv*oSiB@`Tui0ShmJxV=E; zXerT}g#QQKvvns10)8gc8e$O){P^~)0Hcl6xD^>100mGkYS$nbL2TMH)?A~o*I+UR z*&ulkj9rUIw7nfqA`A{g_^Dc2+T+Hxi7+komX>s1FP=m=o+%09Veo+fm4oqbIS_RN z&?-@?1@W+Uaq0*oF_B7OOaQIi)@`Q01e25n&lQZU_Ke`F;apgHv(g+5rzlR=T6eU z^}Zn;3QXfVoEqSkY#mRr>9P%6LTG_8xZY`5vzBiNfcAT%-LV$&=f#tl zbtigg6Sj2$MWFEh?J}Qii6<|-pcQ5!j4{N63fs1|^T#4To|Jqd3EN?qsZ8|8iV-O3 zvVbBX*a#3(z1^&nQ=260JxI2JUPjP>aMI~`JDoM8z%EP;*F~C_elXIqY)y0X($$U5 z+g)9BP-5-X>sGB;xxrZ(S=#8;WY<=LHDQVJJgieLI4^WrGzsta+SouhK{X}r3rv87m30UW$t zkPEA##ZpyO9#7PXJ2qT34=gjUryZTHgWl>uzc2`HvWI@1SU@!(O}upB+E9DK;$DWJ zt}axyunM#zd4&SJiWbULA*_T!;t+KLC}Srz$#kMEoK6oBe6m)0tiDbpwwQP5+Pmjv|tM+l%7f3W0(eo z=Fr#WCww~Fds0fa1V=?om|5lsSI9t^T}m>xm5IW&3&ny2qL(ZQ#oO(hj-K|k<-!Xtji**(op=M5h?8W^@~Xj$ zE<}9Qobsx8RDYwr?HcIsZ!-bfruHQX1zP2W*zj;vX!egM3%vq5%ENat;aBTVKus#k?06l z#oD^CRb=Iw^&2)^z1CJx?ltJ;giZ&E%tXha+lcu!gW(2j=nLdQvNXSa8p|u-8Q9&BBs34%TXG5lA zzBDI9TC6QM{g-C9#e3S@U_mCsjI}z?#kAmgTePP;HsArJgltQqEvf06M7+=Dfs`b2 zG-EGvfIp-v8IZ6oT3fC*9oa{cY2So6 z+j1^M2T>-~@Chr3Ifaj;$PExMRl-LkAQ^pcUK3^(_$gq<8}gC~O&B#Kor9# z30MQYl#J4r6z>j-f00fo<&sqZO!Q6?3N@;KEM4^_w!MPVABSoJ&JuO9V6A3<0g*A! zLi#zvHM65NFzonlEy1@MKbdan_(?D@ei9QHKPr#_)%SA{s^(Ev8bWUuzVs*^cz|~Z zirAxrkc2>s>Td{KcEINtAd<+o^(n|ARf77%#Aqnm1hga zx@LKz5K%U>ZL~0lg$3!BE&HX6OGMHms9`&k=g^^b+BXP_u_mIu$}dShVdcsy_3C+e zMp=wsQLQkhNhxcj>saCwe9>6IX05&?7j%emaEB^GB$I;`IY5lq3jyQ681xV#A@DOQ z^7A*uh_E3j4OoDe0+y_hWgpFb6)9#`fzcT3?}5t>voi=D5qQ!|tr&R)5|tJVFL2r2 zfFLZblV6c6QlQS7Hy9z4&teFCU~D5z0UpIBimsimG`Ic!?~IyW=7=H_2=GF&dRX7b`nO+?q0BSWz?DM$8{vP-0% z0EX>&A`kM8VPOAYAYBGS!QfNb*R)LtOoWbeynPTL&9_qyky#YXnu^W7NJT9|tt!@7 z0ywhMCcwm80t3R#tE7b3TFNhhSd^K>Xhvxj?;@|tWxZT!h<5q zYcZxAFbxbihCV$2LPndKL9(!#9@+7+`Q2!Rz(_;tl5!>m@#0R}kR&qS&29q3dL3rl zMas^Br$%t9VzWp|fMj`FQ+<+B@D>z1*hAp)oft1-fv7nGM}R>o^7zQHpoHs5a<#pi z0j3ufnP2T2JI&2P*M}S{2)j{guz^H65XB1IlmM-h0$p)pM$ouCd^{N*Qwh3d^-T~N z@njoqI%~vP(Mbj^h9~%`>)JSNs7uPT7d~aJdQ7$bveEM$Rjf6)_4iBNZG(gQ8)%Ph z_nxp>T|0ay4R=WkUFOF$--YJK>s-eG6y&zVK=<2irK-*?0{J>tTE>%l3gVrPg*f-? zP;(^%D|G1f5?w9%l@=J*>w9+AXmAXfywjR}wE zoq4A-9+7xpswKW;6PWY=>wN5J7mU2mB~1Q)A}Qm zoD^~MlC1B@E+#Q>7&3KZm(RJ?b=7mLKU_VlI$T{_UA?825~sSldI8wXl-J?&6|0^N zZ!xlAr__nFnM~)Mpf0I{qLXfe@ft*?^H>)>Kg{PT141Qu@aFPni0_U}fE*#7dNcy#O?n!bdj|_4yJ;NplG%dgE-Q0cm{X@BXi);> zSt5-1eAL8K3#QlfWh1t*Pm)=zN*`*O*G$_@Wm1|#Lry=aH(PR%C&H2mQZYDtW9(Q8 zH-jslcXhyYMYrRv4Su>lY~1gGyfG*U+Y}uKO%=JQ)-p!kEM9oD;|e{Tbm~inu^OX1 zZ5&!#J^Khfgjgo{TS-HjEuc$IU=jHzoZ2K%h9hh#tnq^gjNht2AXt)XnIm8r=LHIk z?~&QMNvhgn4OHKPW{^4*2yDHB!000o*4T87TDGnLxg-_HZY;@SpaDtZcG_CR{xmIa z1%wol0ovBKF$4-e=|>cgA4)UUK7r_hXX?UHM7nkav8^$H3DqQ3BWi`4E8XGFd3u+E>8W)1dLO>t$YZ4ChuE}nJ(yaD8i{$ zEQ$#s>Y||{J&Mg><6Hic-M8RriWdr}g8I#Xj2W>21nzj*UB6~Pl5$uk49mm}9+e`c z0i$Gqg9QprI~RQ(L-_Xy*wqwEbvm0ZGVAdVu5$AUsc%eY6%Nc~J@R}@YQ#oPNR`$e zOLBaNST)uqWLS$&!XR7WID}bXP6$hzM3iZcam5ga-SC~Uw^$4MUtq3V<&RDi6>*A+ zP2F42m#qSdaIlBwB~ZAQ zp}$U<9b55Xd}W#)-STA&OBLvckc7MhGi;K$Ez(hH2(84Zx1vO5a-0A)o{qu-klC!w z?HcY2_m0)*Due9<*NT8_FSnw=yt9C>ctKTgo?H5|`2{+y!Y-%qgp^jpkmp53y^PRF zD7G{}0;}02A(fKE3}20pYFkxs}3A-srYoa0g#nTBcC_o-cvei9&Lg6)NK5NoS45SCN7VX7h<)(qYtv~d1|NX2V;3!QTo-##o;7sr>J zHz#y9WIH7yem2D^Ys{|II&Adi?np#x%{;Cfp; zexmkHQ14Z(iNW(PoIie71~tPwtKM#@mC=o_?ZU>G@mq-ZGhMrB4Q(r!^r{+^)qp3G z^xb;;R5HVxg2hf`_APuG`xZ&`wIQu#{jznd)^3pLiwH|@0`~dgjH=QaDT1{=hRnW6 zWXrhNg4n}_2yH!ST(Y#B zdk4`MF_Nu8Z4$#AYA(1*Yruq% zg&2f(lP$i*)i~p3P;r4RQ!L}_kF_mbT#wP&5)lq+$}w6{)kx6Rp=L(M_~WslsB6ps zG%GeMFA1U3?qx=t(ukb{JJ~L^g?m$VxLgU<1c%s-cE{6$0TQq(Q_I!i)Kxg@g0JTV?d}~tsq1b1xUR}~qK57`*dm=cz*9Bk`a(Fa zQH&!_)^9PrvxgA5#D{3NbAlFa(Bw4J1=Az?Yj}f;>|ijJ%n6;ZBU8`|c63t|8%YEn zS_aV|#}(w~K{46-ZF?R?k%Bx@Cz)gmM=%N=;T#nwOWlDqXK8%S`o2!=%aCz4X{grb zvR-@B0~$5So<5oGsWE~h0XTAl!K~x4KKK#Uzl7`Y`fQ5U?T-ng4n+wo>>s#h+zN5< zjYm{k`Z}eIuXdB-Rc<1}s7~v)TqQ>2|6h>*31F*98?7^kZfsA@tM8D6Pi%;RXgP__ zNSN;4PX7X80ndlcK%3F9BDY9JmArF#1;a|(8J)87RH*nLEYol?jBaA_P+81zPKx-rxT{alM*MD*#8dmjq ziWoGVH(edWz8n!(#hFaXnLMh1gLlGd!E+iX1Ovx-fq-OKOG0DAIgXQjBHu;qsUVg% zEKaD@MG#SfXp7MC@%9!RA@5A%@}{JcB9axySZ-6#bMf3>t6I*q6Yw+_Hih$QkfT=l zoTwSe`F5HZ(>+%knd8?%ZKRPW)J7%?wGo1rz>L%%S09DOQ%G1HH}Xw3&ZEjdQ70*U zvcm9|I?41!I2mETR>Es>y=2OGL|ec){yJ4B6{S^^?JcB(=JFhkRyz0^8BaQxEdNiW zgRl8bZ!H~6Zeb^G9YuhCZlM*FHjZ$wlO~;Hp|%<-fE+03I|l%z)o7EM5vVc1YhrZ6 z_OVV)g##OW=>b7e{#4bt?i`YHowO}${u;u1k=@wpicg9PREyh4G!O1dZHvQVlG~l! z%T`a+3Tzsj^lCTYQcL4ZlN?+i7R+)H!ErO11uV(4X#vcpz&e&)$E0+T)lib0pY?rM zP?!}78WuG0py>%=_f_c%F;|%27DyW0G+%YdOoSaXzWOY2ywzc97j~V)9N+88$u0== z%_(ogrEBd_fii{o|qQA<}kh04sLR55Zje>tTBWMBjUc) zv3f3JnH>pkf`!~17xmiUl-1zbZ3L^%Zb7XP71C&Sd!`)ZzJ}fGo_T2q%S{Q&Noh0y z45sYtZEbMLPyuxj;bsCblD$sQD$1}RtKv-3Ie(Dc0)v**+(^)XB^@uDwSN>pkRvjd z#4l8k@qRM^1d%)xPkv)T5(%En@d2YT4R`}g<*6=#I-ni|dzfV4_6P%v zkI^*f{z!6ij1`w zn<@D71$HdH(CrxulO?Y!PvGWW;Vz4G(<`5y8fXMIjWNf=(K)T2lSZjwaj4Z`v(KEP zA5zCmfhAu62`a@=0^?B`NF=aVz+AwAn-JmQGBOM2;Q%YVO9_h%I4z2Sul1R-cKG8- z#iZOe&=;~~CkR8Hjy_Bdr843^RPMeDLeQu{60+IP4qyeF)XnBMTNCaX>}x|s*i@r~ zDfRhc1J&AEeVL?`0Yi%gN+=*6CQKsnD3IzN?gD6VDcM+H5E-ahV3FCWEsZ;lVN`oq z;d`Kn0z*FGp9d7^-K7@g)xgLo=LlDr&DU{mU*^_6vb7y#&(1JoU62mGF?3Lf1T&!^ zeOqbc)=F*@F7u{Xwgdb{-zn?;WN5PM%`l2&PTEXvAN6WRB~9*oQR0>hWeiOUdObXi zlgZ%IqEN*l?8RQP2>93X1*33vslnmdsR6f>?6+@QrNN&s156cmwSbyY%8;|SrO`Bk zAr<#{P|p~QN|bb1vrU=DG5fn+jJdsh%mQrA})Q(h2x-5wI^`n ztle#eD`v1x2&(cG1@Fs#EX{~Su|)jN~F*7N?yZK zvpBg;tS~fVv9*kvn<#@$;GEuH&P`Jx1lXZJWNUPi|#b%$wV=*kmGtYPC})AKI`bI2yF$ zJ7|m0rDWWd7FNzS#S2e&p_m8S6sicbjFK9ROnDI~tPmjT3VTBz0M)#g+nC4(KtiE) z3BD~ff(h4ZFxI58%iZ4E%mkUYuf#ivIN6mctGa681CSkxGR=3)}!OEB#~u{xu^2A2X~xsgETuj&Di6&HP%X`dLF*2S;z z7TJO1-&ke}Lny0pYUVI@@0d%FY!~w=0%d^JEGlkvN{#Kekbr%ib+R#B;^u^E&Z(Ib z3RRsG?d@NLRXCedesz~O&K^q+o<$xf3mg_&2{s##lci>{*3vUx9W@tghR$&_Y#u<4 zs&mdBoZmQJBb)ndmZi*MP$8Xh2hOD@i#$*XELL}C2G~j#4<&s&JcI*{A4T?f8y`v_mvuCvy-odF^iVF8mX0=PSKYa6Mqol7L*Aq4hs4CVsz5`Kt|PWFkSI;Ap+=utUmrLN+PBWp5=%+W1I zRrK4?8Y&%zjTe9kUJ#TL|iMiBaXqeZX z_*;iviSqUuDt+^8#$uSmR17G`Clul_9Pi=s?6_p)S5H>N8DWM_2xsyuQo?rbxCtAW zT)1_vo7s%iLm^&7*RAJ4wRV6bG^}daFD#f-Xoy)Tn~Kn`iZ94TuBYaQ34gI(V(f1aw}9gRxo{qD{9*n#`oH!dccDlsG7EQ;qgh%d?xhS&x#;H5A=w zR%zQ}xgvSpXn$UJF!4zXA|tF*A-LtR%QI&7)M&U)ddia+>t#P-6D|-Gf*X^JYeeI1 zOg6IIS{FKx=3r3dnOD@rR1EdAyGTR#WGs(I7bXrhB+)QsegO*1@pR98fEkL znUnXpn{l>6;skukEaX!cok<+4is3l3PwFBM2Gqy#<0&~(l9ibv1zd9U3oy}Xc7#zx z*o_pUZ32PbWhx$d+f)EYNXTgR@Tq_&Ldp!jTgq1LV_3py*;i-vfd=i}B-Yv|Hl^o8 zfxiu#Q4~U;3Vvva@D)~ZLXd5tcMh?h(=KdGaN-G1B}@uqJK$k=Z0v}`0C3|dJ}kyh zI36kxfN(n~pbZ!OxP{iJ174gZTDi`xRuPMMg;F8(M&2T%AU|s)!@BZAq@CS!>rzlr ze)iFrHZFt96-x{(?;kxe`<|dU@5yzM4d__0?+y;Rk%(?Ci&8^WqzK^4)fOZ%(iM<` zRRv@+RsrBDH-sqtr_eHjOQNlb;|ky)Qpn#_B{BepTnwgsfY_5Ru`ug|;Ku=FZJ+2K zYl5m4HgIZnMdu#Aei*QgDAfw2Bd*}L;|8p_Bdi*tK>k`WliWn4*|#mCv{c=IoPD)% zQ@>Oc%u$7zZ+uY4t{4z5MimHP!q#ba>bN_^c=s!2Fa=kk8mQe^H6LxPuW=4%F#uGe zv31x>a($GT9WGpIJxY&pbXa7!NL~#JM6Jno5xKr7Odar165Q%c$_bU*lu#AOD~($w zWKfi~RV0Wd!Qi;c(#IVT81CQ&ae^_iZTV1D8!C5I5K&m5(cNxKU1R_NXl+Z5K29li zChJxwR`D}_DX98Txp0I5y=uK{0$8pIf~UhEYOn}&LG|d>r6ljG$s2oVh9jyd)D5*f z>p*iW*d6is!oIW~gOIJz@wq{i(6n0vGeK9658aC7>)uV%MZ2?G0-ac9k+>7iX2>p;T7ZrwU46DjL zL|T0;D;pS5KVorplBcjGgI5j&2wcMbkxI^Mj<&5?PbE;;anIzIZkTaL=d|mBVbc28 zE};54_l9=3FpAY)fYze5SJg$0#w~_p9v#v#@niUZK_fjKMQG%m!3R2Ud*J6_jV$Cn zla=fz%v5d|D9E%LSyL7Pe=B@$9X_9N-bLy$Tv~yD_Gu z1%=Lh*J^uvR+eiQy*)x z6{GY4#^iGMfEWPCx13o~ z+JqTrCQ^{acFZJ;=ss;Pn9DQX^h5Dno|A1D<`sa+wgrHoV?sbuV=n2pjhQ^a2#*1& z#wt?IyWM|m!3(q?_Fdo%0k#L*jUa^7+ce=pE2lH08lmzr6pqXE{H`t@Cn7P@J@5`z zZ!A9r{AQ@b(1YQ|zz&b1GaWz^^nY=M=uZPESl|BwCMyHjH$6n9u6M&5<|qdSf;??c zc8KAOcXx5dCV+rsNbI{zW|oaJ^BjXtql>-5e^R3a(yIzAx$N9?$Ax4p9{*2)Ia?cc zEG1#>6e~%Cr7jM#(_OSCO4S~ormtI=&`LY1Dm$7>g@x4In^OIW*%rx3-nIeYkOTMCGNCfJQrqEV=iwpNsV3Uo? zC3!=+>q0GRDIsjnqMDBl@u)sxb!`e7U+=g?|Hqu3vF4mzCf98ydjFMJ7Xgo-G;Qjz ztD8n^70ZVPeYrSY#-AlL_NlnyiYLuT$@vu?+u^Wbjfh2rHB3~%L?L%tE5)>--f&$T zDPE~u%J+Vp)i8C7>H`1ZfX!Hw&9-VUAQV4D6)v~ICLn57)`2`)nYRwBRm=W4>~usP z^HCPlKrQtIqXUd->JkJIDEl{tNZfuU1K7f9ptfs>2I|**H`_BT%!-rgmd`ddG5!T% zsa%W_%XV(Vfp*KM1YG|Wi1!G(e`W7$rLTfWZ1GQn5q@)@#Q`;Ev&10z!f^P|Nr3y{VUYBa@q0Qnm%Fcajb#}>n zyM?cKtsq+;phRBaMl%Bv&{kNfH+QgX#@_;xkW1GDSXo%(<_6pm%KOz_!Q9H*dl*f_ z!|XhBH8`LX2!h_rA}|+`(rkp|jSJ>v0}h(;fdii$a0$*csfJukuSoHR(`6~i+xTH? zHLS|w%&|qOASlpz1EH?-c-i3XMs}B4i8CwQTm9RRT#gZ#b$Kf6!=7m$;7H5C!!QJ0 zuwIlA3c8^BUp?PK{@RrjvWZ){k5`2BC}a3h6+<@^P=XV~2<(8rrNEGQM6Gn<%jk^` zM`mm-(wrjoEi?EOLosSKNCw8?8;&O9Rw)$QwWj4kj-V}=al{^}7;|~MB@FzoTihhx zY`)?Y-A2=D2<*wy+W3SQ(BzVysqA*Geww^qgWg5=n$0f#0WedCH7X2?qBPQQ)uNxi z5NSFs98>FK`eYawakmHvGVnz)-l=G4Q_3PNwg!O{NvJbktUS>S*;GTuuGzB0rn)eZ z4Gh1v_W1W%u~9Wjt+9pKW`S{HlsF330c~QfT8&yOL^%dbWDSDpYC=M$7$m3`dNhJ!^V9_>?7c}*j+5>)Z!&Y*;s#JC6zYaT0gw@NGG34;3rFqwwy+1xW>Yd;eAxLbK?mAf`tjZoD z0{Bz^rHXccoq4ZtmoY)Uswa=*w{e(Yh#Ed$4bNPrB|Y?*(eTOZc4x1LxL`os3alB) zLe3=^w2&_-W@Ia?aQIn+VC|*tE2V&NeZ$ZxJ@?1jjaJ1Ko_F3#a{oD~YW1KYT%@mJ z3`D!?_l_$ZY9Hh3TN@Dk!qszKTs#8-0-6RVVJR32 zR*_fDJ}Fm-Dyp%PETeG~-oH+nqmdU~I5YO@Eq2uP=m%KgR#rZE&t3wViJe{#XL!3F zF*`28>w z4^4dJFK{wiQW*Hl<7N442Y+G(q~LE*MCpO)VJqtreuJeTItNH#%nSu~Lg2XwaLcWA zXg6D+-N2C;)}_2yr?*s~apeC+F_gmj1dvbFBO^os}C_z>c?;+Fq1;_yx zArfFX0Zn}OqLMS6=@tr3E?5eCgnWh`z=WOR5`#4|kD^l3d2bVG&7Yt=|GQ|+k=PDm zv?J-W#{Cp`@?T5c^jYhY6r!(maHN*`6Cjv=V?~IV)PkI)&WfZW!qI(v-1k88B1&i= z7r0p)ypRw#?e(j=Xk740NN5H2! zK!U@j`U;+;x;vTl5Pmv<>DhmXHK8cWU?cU4&j$<_z)fN>7&ld2)lo8bg0YyJXq_iA zShocHY&zJU{H&IZ2%AB|@rTFY+7Lwov=^aA9FKys^eLKwzoq^i9^2qw?tBs^sE(tn zvpkX)UjL=vC7l4h20CM&xIqpk+bXJXmIcvRVwjc&HqM_re?Fla03$lsLWPZ`{5hH$ zwbMb^UYOv`dZ$y;Ro9*s|H-JJSZ0|^J1H{c{k!m;l06Z>+kJ#!6l4A)D8_0w#^s69 z1>{}g*K10$+)?T~u|g&wD8*1(CKbBg9L*+N`27Mv93<=51g+u|yWuA#HNQyrhI;On zCC*k)Mn{C`KUwrE`*b!f5ONe)p@=&O{zAQ>T9k&ZdDnc?&>~<*v zbZAGo(FW+|cdaMm)5F&^`8ZinA?0ZT*KaU2IA(FX8>JHUF{(LOXZg02RxcqQV2#Sz}g z=z-V_pCR2{5~S=+x?8(;}6Z=g~r{J5wDbP=BKl2OP9-ENctHZDbyAg;^|2p%S3dmxAr zS|>Ud5@|%W2SN(TgPex0~YOOm~N|SX<$E9=gVZ0W>#Cd2Bf|f zl^BdGt#_qWO zSC5g_w^|)?`jlYQ3?^UY#E74yM9z8y)P;jD)K$XY!<-1GLEtzySHK4pfZh?GJ%7({ zlfhc`9dr=>)Rq)0f`GYAf~nNxS8;~|H6{1uG1RXtveo8+zcg*jXT@woAW;HUcvfz* z)YxxBWw)sLKt<5ZcnNll2Su_n7IJQkPu^Dtlku?(NKqHLcf?2~8aH%2Zwv`j8-zD~ zVQt7Rj(5?$xqDu}C_}e3ZpVemAmaFdicEPN*B20{%;OqRi)`z@6=5qpG}?ue0i3M4 zyH>1XBi%YXHy|?KJ+lsyGi0N5fr;(|dbCpE@=O4?jF=uc0K$1IDcNnb2>AftVedGj-V@ZP5{LiLvgN$*c* z0z}E`AXx?fpQ6Pr4eh)Dq8>@y;Gj)HDjJexb@|4@0RS6I53;}!KL)FCS|-`qYL=!Q zJ$cz2K*Y5#HXq|?(sYpphO2QWwH0kyR1{95l9Z!!V!Wht#5HI-Q79XCoG~}~K7RTpi$iw!lkG{1hRj4?nwETCJ#?Sp~PwLsRepgHZ_gpx~Ih}pD`y&&7iu=#>Q9^ z;U*adS`Tj~5a=sD5JH0 z6r?&H5uA9R@TrsW!r(EQ9{f_H4SiX0TYUnIpvCshm8o_h+Cg1O-eH1^fSEp~?YA{_ zrxZ7}OR8Y2!d!m9s2O4oM<$l@S$LbP;zjI^w;|q0nevv$@3*limJqG$w`@H2wx(%8 ziaK!}+h<^?wqiAtVupH=OX6t6_z&bjQE`7H`%xJq6&6}DsommW1th4b;Gsz_O!DeH zAS$18IL8ej+xWFT61|aniVBIF)P^bNglt@XrAllu$I63%ehWx6A^@vBk~84M7JYWR z8`RY<8YmXIr44>Jpm!`$T{2J)j`FB$(F&{sM~A|1)B(OK#Ih52+Lvkog2A=z6<=sh z2D+w|Knu-RxBJePQ&S#Ud@qa9Ant4l3i=`~us4#Au}!BQgNE`VcZnmQZa|_aZu8X>we8mIe-64wV?0jr_FyfOt=GEa^<{DR1PKu>!}YtfdB<5fq=+>3}6L< z%7=SWLs@0XG~>i4qjvqlRHz}1%6+NjMrO)%iB(TlNJX@n0D!RS!gDZJGBQ4}t?_(Y z^Dc~He0_kL{>ND0uZ zUqjK|g&oH%PX=-wH6pqDRA0`Dnk=i(4O=o@2YbX3ngM5C4kK|gRqe& zfg>ehyH;suH|i|+LL}b?_p0$*x^qjkgsvhn)vA@qDfApfu?gR%oE?i(=$7Dkq)93l zgkc+sIoX|ExvucE0@nb_kU2{LI!&?lPqnKcH1|wz2g6Z_@;O4$>N0$}GJ!%)`lJiI z=%g3Lo-8kO1RKjjZU?I0lg~rbsydjp;<3Zjr8bN4eF3WD<8oMb&nzn+e5F@VWxit9 zQcc)On+?wN`8Nzi^QVm`?R(%#wzjY8@r0)Oq#%c6A2oN(YpBT7_T)heF{EXs^4d$m z)&`P=KaGP(bJ()^uFC0rM-Ba|bA%TRdH;hNYNdv48OWqsqO;M1RRb}!BI#%kXun_u zkDH1WcOfUX#m%I^nn}D4*j=4)ZCairHkQPsoRN+(vx!HwEWyIALA9))hM6TC6XIxY zIR`EcDe=BFSui2u&Q#18Wanbo^BkqiR5?e)SEQn#gS|D+3TR(WJi99@g9-30!~ew5 zmboP3uZZ>X9ckpnjgo`eWWXxul#<970Vr>I>&Mgz=JyJhj%7$2X2wTTPeb^g0~yf@hA zACLL+=cQly2(0wO!&=xEC=ry%S&1Ny#|7*rr+nHo;-=XWsM4enx+<2QM({MOmfj*c zNtjI&_eXG0p1Xem@U%>#1K1InGhG?mHw9`C#M0|q+;&F z=*V)5hIiJ-P1Z7b`LLG{^t`rM3m%Q%b1&;+6EEHi-7It62N%%C586C9g7oU-@*EOyO0!maFoEja z9%IKwGz*%gyNa|z?G&bd1Ukb51bFNh-gh|e9X(Zk({By*wl}`llBc`7Tl~vUTE@S5 z#I^X%gRT6qvnj1L&hwO~%5ljMzw2RE{)xAu$@BW>w09tX;p&=4(3VVh*ifhZ z{&Gos$F3{hsCP`RtftR$);1LJcPy3zx3QcbPyxN*{~wU3NP>TpS$Lk*CnZ*J-1W6< z9LM#w>-^`2{<`V^e9n)z@Jn?AXn*MUfw+jHyG6Q8np{k{F)Y3QsnD5}%*7q?#whH# z>cuXZ9&EV4RHfd;c`2lNnO3mfyzc43?d;B$i?p-Xjj?}ScISIbZN{#tZ!lglb<6f# za0?_HfnK>`3XB1kPxngUX9|syY4Rmf$~yU|y)(|-d1+@6)$`>xBRxiyPYFcT=iD;3mG!5XG@+h}Agka4bFdD%JyO0E*^k2Wm z#sN}F3YspKLNu~Hj-pY^c#?bNOH-<69}1bVWh{{f3@M14gMFT3EOBdG*U~!oh+A6u zs>uhn4oLTFGedSVZm(AmmwDr`8Ta5Az8k%(ypd2 zq{2&;s#0PY?65B)ex1|No6-0klECyXV2?|Q)z#GR3o*Ag`5^P8O)qMmwAIDUleW9K zd6LVjka<*y;Zn1Sr7Etdf<{-`;&CiWZxAoYCTP7#z)nwxSoB6=ZtXdV^L$p);0Y4> z)H*PLw(_a+7tUYZ{KDctQbD3j5+Gp!WO(QL>dh~>gQqZ%lxc5@$`uO3RlPV$0!97T zb`RByyZ1KkZ$9Yl^&zd-uHU$M>+>(Z{OWJrm%KEA(Xy)66GJh?Nm-ruQT=W8Z&xM9 zwu`I^NtkXlDjQtCwR-(lZqn9Et-;?`uZKR)Z*b$*>Ww9O;NJK6jRm0#;qw<}pFP{U zuXp1_X}yj2s0R}qR3S0IHIl$r%>E)?k^7*c?gx9}@MMd{NbEw+Y;IrSxxoG#nFpN> zq_ArEg@1_uFQG$U3rOsfj8dHJ^qS-wP+h0h?kHgp@{Oyr(iM1nDZlh)(YcE4ow21e z{FYoM`>6ZV?tj=BZKJDIai>HwN;Ik$U-U_U<{=ovlIq z11YF2t_cUgQoRLj&WGTT`qN4Ec}l=^rYy*56O{^qQ~Em{#!c{ix@d;0B%ztjjn1RFyM5kHVuUD$O#s_T0tIUbrzGa%|yngs9Qw{x&Sjk zdNHCX9L|XKF__3XMB9p5QZ16fq`k@jV2md#_}_#wd#Mc;HknZ`Jv>{MrMVI0&=eyM z-~&ZIFBVKC6yXOIghb5!v0cEkaOR{A+cb~WbA!Ymm*PUIT)w68igdN!reX4-lO#8a z)VFVB7p#EIdq-L)t%VcJS4zrA=$0 z(AgRR2e@=PgV^??LBDMYVc6eLjG0@H8?AVCM!1F~5!5-Mpo>6Ut#AdUDFoN=5c>8B z#?nUKQ6soCkD(P@)Aoka74j{7?$LwWS7**Tk#)RsEt!y*>o9M_{vGFbIturC6_duf z!!kmkT*;r%3`1ii{C69hMBe|6gM-f}G+61Ad75e-NrC3byU9mJVxj4>#~~oZ+bis5 zL$&b&Q`JqGVX*_vn;k@8%+{L}6duyocEn4QA{nc$3|ca2rA=!6T$l^H6l+06aaVEM zlJX_wP;-3br|z7K4f7k9!Vm2zY60vj&oq}$suv2|m{!`)waF^<^QNoKcz(eA>GI5H z+;pGL2mUwFoXT3LU^V3LI)5x_38l*b3|E3>W4L&ZrBxLBwz-t@no;ZZnTZ998{7}) zcbNsbr^Z!*eDUkj6q0V2GKoeCB@e_eNRVymTqIktR_5yyZ)U$!sc)MoP+J^{L#jb* z2#Q-Pa9H{#i#N@g6p|!Umc`6`Vck2Af@uKF)&%i_jc^mPG$YAaHDjdE1WiUV=wPHY z3Llv)-kN&c_+PrvR9TauHrA)d9AOKE5?L~lY}j*y%M#wW04|_et!G(_YtKzMYF!f7 zUU*m@7n%n@8Rzycn%Jhz-+2(TO7E*ro+KA>F$gH zuo9d{N$Bl+a&0`~CSL!m@6u(HK7a0187F3>sBx6x}XN|M%En#D$+ z9RgOktCUHqoi$0EWIkCPKPQi|S;1khdHJum^NhUY5^KZ4k*tro<5?l_mxL*l-4jR% zagNfgNPb%K~F<+&Gxopc!DwF>)ViX1WlETFP7$uLyvR0F;?`WGF?`*T!_S zum`^Ki+sj&m(d5yD!@|bEDzi9Ya5rcyz~T}q}M|iX@C3_7NiL!Vb8L6VCyh!HJD#- zAeeNqq0Lef1Ch;zazKwvYAH8Uv$#E_ZmAWS!yuLx2qzIDO`Y|Ol~5d}HZu;+T+eWa zwFI8bjY38<5}BvZW|p!hMW2rVxZF*m#We(yLc=P*C3S7#SkXwJ9sp zq|uQ4vf{lcd*VZ^ro%Cxqgjv-5}{`R{95B{&5ByA1fgR(?`%BX+TN8y z**vnQQiwcfezUgumUOA3te-|J4Qw*LcI$&u9cyf1BfgLlcg8s8Y&0A|Dnm6d7}o$9gYXP>?Q*e;i2YoV_zhBA z+-5LW1vF*R4{0`~=sW@9JS53+gPqNrTQ_%3G(10#C);*A&p{ybj_9p(Y75g7<#`wc zrt`rt&n^#Wp=Gt1y9jVt83RtVek1(>Opj-*^yuv<1L&7E?t9^DF<+>!xmqjuC%4dV z(n7wo%_pfYle7>!J3K^s9{+=ZN6yZwZUM>{`S!!zhtD?g8COz^%Z2oBR^50#9wP&~ zS8c2#g%fI9PK4kjD_?spPObb>Niq=bu>9`vv+BEz4V<#?_ty{q`q!(S3V9ePAHU1$NO` zxh`&w^ugA{mI->w8yi@}TPS+fwsKLWllV1ukq>&<1f%Y|VjOmB?dY_3g?YFO$o+b7 zbkgL8`@<=6Fll)JFWi-J4zMu~5@_U7=NpVQhu^*%;P?`jXL_bi?%?R*?%{(2T#yAj zhhtMH<-Guw-Phnjz8B4@#DBtQ_jc~DR*wfW`4_9w2a~}7e>+RQ?hW6Z+N^#rf7>)7 zc@u9*3#86NeOFrN*Iu&~cEP*6IKPC4W~(PV)pLglO(gGAqe^GT->TNeemg9SGOuYm zHXgJ-pEW!Mc4>m%STITr&&hP*#>{hZ4=OcH>(xyDj=^Byw^KQn&512e0K8- z9KX;e&+!uphS%oQ9-h4BSvg=d+?KzVm}V8<7O|1=M?*{R$d#BXE&Djq1LX}D+<@>F zLoSB&9vlI%SoS$LfG}VDtwLP`e3Bdsw`H=AX6{$MZ{Ck2re%+ryuK!CEq#wQ9sN(E zbHo%a+&(U`A@}r|k>7FOpweVDw&5C{`3IdV)d=TupgU)L8k9ERd?P}jRw^M=7N7%*LFZzET4q&Fu0>~1kZN%nj-=+reJKNbbSkr zA{pyY6S~w@&|xKDePwmx+-e2N(gH*Ym0o3HzxqTOWsx;(??G<+)t#I+AevRX;tvkK zU`xMy$vdx!inv3#J)_p;vC zPfgVi34TW>Qev?d)*#yF>1z1n`d`RMLHHeda)`E+ON z$zv{b1VAd-c(VP^r(55Bznh9Wm#5Wbn9Ir=;jfljcy`%u4U|y-Z8t%;su#M7n&Rer z+*}5e`2tSUDGmP=DgCKg`18s3F0k7PU+^dSMj=IAV=FYO9K2WwZc)zlWf{WWa^7~$ zK3H+N6tgPfqr`LVv#^tKa|Y{wQHkpO$Lbb*uDF`Sh}Tk*I8{8~dJ7A|_>0iK7Be|M zxZM#bPF2KYE_bhgZj)i%Gp{ef!n=8th_){MHVPRF$!E7w)a!zNsXuyP=<$~IC{4kr zCblnbyv&>A-UhQoRpUSJZp@iR;{$HtmP_+IjShn-d}%0{en?}t-;o4G|ABuVfO)X) zcmFLcu(-oKs9w)zC%4zvVH|L0{$w~lox)eaYf8uKhM^7Z6GwPM98~=uF6QyznGI#* z%Ur~Wz?Y#2O#S5H=H2aW2@GuHlcTvc%j`eGmbq_Vr zGMsRA#CCS??rv@58ge=Q!{J_r@#EIx`%iw{yic+KMm#~A`q4T&f(PpOVlS0Hzj-6# z$c0rd`{GtnhBZtsyZ7Wd*BAT`aDDla%I%OG%6{SD(NmmiX4GdY7yIC(EepuRa^9JF z8+*`{;Y3^2L0C>!QF_nba!q==Uga6n{&@NUeeS;}CR`1DP`6mP$;mNzS#XmFxDiyw zS&nOPbf7&XTC@FgY6tCfa1MKL=l{mFJFA{!4AP_K%Kg zbZe{S)Md2E8QoZA4Pg>vr+SGnP@}$xs<7X3^)VxifdKdA>KjkD)Hf36sI>z$pTS9$Pc}yW{53MXLt!=%S5S*7( zp?2k!V5Y-ekv0W7#x7Dx9}7hPyxnTtf8!O6^hC}OObJDSjJ~8od#RRUG>J5*EZ5`- zT#=!~-iZRNBdb=jUHXyk4{Hn>i`*2tkV4Hl$9%Pn8@(vz0Rx@HJbpn^ulUN8$i5xj zZnQtF-|sZ9b^OwNIJYs11lDItL!R|zh(Ll z=rHJz)m_ubg}EzI3XSDHp8WRnE1)FjL+c0?i7}zj5(^yTKoJgMCv=vRq=B2%5@`@H zMVV}kB<~>s&YffxECh9MnWj1xN>OU$ZcL_^1OnwAT0OlgwIsXJC1e37a@G6|SbsX{tkz z-V=^uy5y5RbET^V5xt~Vn#L#M>7@{99{$Kl<5rOJ#!UeX!N%7wy?YH^Rt>9f?o^*@ z{}3s4`-P)XNj|?AzDz3vOo^1W7%pw2XjA=w_Wa-BOX>~Yq@b~R#anaHkqvH>LX3v3 zFB+4ic~$1SY;j?hzooUAeafz3@=vkY!eRkQlXB0x`{4EoNMIpiKVEeHf)`q;B_-XJ zi&-tv4HZre_)gT4)o9u5QgT9v0T622b^d6E@GjXl-6u^o(7{^PJ4X{)`PhPj+iw|3 z`>PZx$FszOB86!PPQOjD-MA&BkWqRE{$ji;Cadik5gKdwIiYQDu?N1oW`8rS|I^eg zIW2zL8|!V>_*v#0T=jGHZK!T;2`VU4uerDEvzvxu|YG( zeRlVb$Zoos2?Il&Q~J+@kg%JJW$W;{*!6MO$BZFkR@4))RVgz_A|DFXBZIFfRl(h4 zW}ZtUmwOM+;b~%=;ih7nWef^U!)L}vF`tGgC2-QcRt0ysFB1+GdrcBqr$MH5YEMEnGXRpL5HdW8i#u^1X) z%vbAn|0Lr3`cPY5>+wsFWnwIqM3A*7U?5~tixO1_Yl_IR3MGxArxp|1UK2kQPr1Ou zbbwYsQpjL3TZzSmMlgxf^10OE%0>+fY11?qT)7yHI5b?-LT3YC*pPbZ5^LZj=#hO7 zl*dOT6uup_LzXMY0$ngw@~K{%&WFIp={4_EErs;#VB}wQq>JwnJ)wfph2Q5=h4aRJ zTgAo4F&n$*;N^mTcuz+pGN0Beo~)n}^(QMZrVLaE6G7TpUax{VRzl9kc%aKrQ{!ZV z@sD!{M*h8{FYdVRf|*N ztjfg@DC7{8K5jtjvH%<=Zwj8j9msR+F+b%yj+X^I^hx*nV`*K#_sVu|oI z*DrA^iezL;Jz_#1$}~+&G*y@bmEYI}BIpmb*e;M*;}`-=w2S=3#f~h}`LFbu?a(Y9 zv*qyCke19Lif5q4thr$ohJvd>{AXUL0d)h62~Z4x=1 z{^bPk2lV;_=GUyEIYN7QJ0g*TvoGD56R(^k{AQH{$9eN$%(!MVy!4_bV%W0y6tjlP zaN%_d+0fvn8=mAfC5AeA_zzB_VtX4zKrYW;tLx5K*n&O?{qlxSy*QKwMdWuK{-?UA z+C(d$esNYDk1-wtUZ+Ee4)n5~zpbt*5Y~hLgCuW?Z>)Go96Fc(f}Kk)-~h&IA#t@p zK*$5z#%Wz4Hd!6{tV@-j@dyCkg=K$bEwYm-KWWg;Uw9BcN~Jqs+0_>u{d4j)$PL=g z7l1FkjzxpqT&93MhU#uy0meU0U-)11AQ;FL;{L>>>~li}q|O_#u7QI;ZJ*rPmW4gq z)Sy@~qdBpVzpcpCkh-gy$-9TdN9+=wEo_CB5%Z zuu1w}hmZ=$ap{N6l}$9}PG%~zu*`m9`{c`ULX6?CNO6XTy5T%0@-m6W1`SH5&-mL0 zA=QOHC3yzbO8}^uF_oh9ld#hd?bp{SnpQ&#CHgg?$EWpx9{V#)4^EHN*b1hpg;ZP6 zEOP~r$UkiK?VMDHnHkP-F+!0LPBjH+Q?CU^IMb#CTABvc>uX$Z(yvgh20En;g2nI0 zLDuvkGO+ga-Ej6A2X-bfp$@uxF$*EW-pn}~eJc%?DR|bs3i#_?O;mL{3js~37 zUfJ}`RimC|*``Nxrl$ugh%TSSo34dti*!JSvg4C-K#?~FdrGYJHJf~lM2AW`p;Ua3 zg$6m23Jrw&>ynVx8FpHP!F-9$L<5gg{*VamJ*{$wpb)&#iC*lS#9!Zx*Rf#;NDYDe zr%a$aD!KtmxmmQ_9PEa{8>eR*mA6JF63!4p-!S z4!@6IZf$OPZXR_tsmu(tdfVV|Oz$#(&OR9ynh|hRj zp32Uo(i@&E_`uOiq4yYVBLpu{@G=W*nHXNKNYe1Dx$zSJKpnJ}4w3~_3D<}ULA&Fu zEa6VDbdgvl1|wyw+_?h)WLp6LW+6=+SZqsk(1Hn3O7r5(>ZaAgH&(et8|jd)CKIi( zGY3ushzDBWfAV@P?3}sqh$i#4ZZucrZZw*u_+Ky&oFfmYkyg%D%QuXzgrQp&mLaeL8E&nd zEPNI@aFO$=b!wNj35|A;1Zq0QuF;h;bCg4*t#W;&A)I1JWpc2DjBtTr!kC8ZNG8iu z%J_$YW)gOuDGZMISkz!0Iv3`>cnr$X&8xC@eJoaTTruKjmlt*AUoc02M^>BL+%3s`bmlhoajWw>uXp1i z;uGeeKgP?BAx^#Ab~Y6!ql=~h+`z_T)vrc}yoxV{8kx}vYHBmJr}g{=&IizgvQ6nJ z#1`ZZ3}SH7f`(K9Dt5Mw^`*Iv>ji#uKLYlQ!_=Rcd7NrTq*2J=I)MKsKCAT!ywB^8 z$~g3qL!jiK$p2)X^HdhFPS^6++ZRZGQl9}p&tWv57U@#mJ^y4wT@WZUBy-!(-GHY6 zxdVe$z&U^IImvV?2A`S}{YVR;56rxIbrzAdb$6fD~ypwJ# zz!4wpuKQgD*=f;S3n`)RLx!^daNuDo*+6oCBAXgjrl|s{%>vn{@y}esdx3gV9%;1# zlSMR?>1+~>D^u@F#7GkS7*4;wT9ubHBw3+QVq<-LbSlSBAu|TSL{W0E;vleBx5ix$ ziY2-7XAoK?lie%gwtenW(!^BrT#TQH;5D~=sV*{rSfB|$w6&6m);i&Z>1eG1qze&9 zy`+H$wSv)#8mF_zk=vNG7iGuh{GHVM`P45+5l|&ZhgE69JEy%8&S~3txp0!r9 zvV$SwC5A81)Pn4V{FJrCBzcaRGoLnN? z_@xTmp5Sd;PF-yP{yUl#Sdr!8oI#}00hy9~<Xz1Toy!Xgpp?R(<(zv5kh8Mz^;%R34{@mtY)0^my;f2X;nNb zCaqXiO|+O|O1un&@sc6Z5a_I<*q10M*EIaMUAAii_W`QsLlBHgbTN)G{2-%J>&O3v z7UVy^Vd7cardG^{iP$+aYhzK;62Nu{#k>Pdk|3kF$3&Zy1nGGMDft^(9>5T!_G?iFo`{K_fu2e`lc z=*Qk<#PhuLcRK6u@C*JE?;FKkS5I&W#xb67Po7d|ofl8=Qz(^3-?e#Lsl53vz(c7$ zKyQGhbRW+O9|G*N5nrMA5-B>BPrOktFgUyjQ#X+IbGzERLesvt)MoK_wd}2?cWJ-gzKhfHBeG( zf3W`)FA<+k`U8a9HH_N|b7Oq+z69Bu_5c!so3QOoPwJg)=w7J8c2>hZj<}dDsh|b) z_Ioei_Hq;uGW7;=d*Kt?YdVm zIqBfu$qbeAn_GN~7Pr=})m!YRCMhW2In-~o=)nRLW#VjxegS1f!Zfm?BA50j)T@|H zdZQ^E7TMaf3ZhEZ|isrY=yC1by4~KhrPVRjoTGCx|(bO95L4jnZWCQ)_qfAxIPMCF}D66f= zYgtpr^YTdmmjPDOd$R`-}UEY<<&t&14|eiJ}cWW{=r^2mQU|bgZPc8$C413Spah}mmB)VxV;7x6=Q)m?58BPzpNevqGL55g7th_;N09jO`04KM zmU2p{GnvhX?Gs=fv`N%?Q(#S#Iu=YzchjcXG)7w|%*4?&2eCx5;qL4sghMGyYyz5D zQ46U1i zj?)M5Vq~$r0Asn3$k1*ell<7U#goa}$YW6K?5Ks2*8vet|l?u!9}M?PtpZP zu}=!fSJ!;oj&-hdt`z%P?7B|Pn6T!e)0|rut_72O>>j&zspiea7sBze6oK*XGF*|p!uD(# z;#dO67uWpJn30seVm(Vr0BhP_TZw|~;IXu}eWSh@*KcW&*1k*Wko~j`7I01ZbZDI} z?yCZ43F5x_pLvW@%OVCYOEeRuG}{4m^47~yN>)O{Y4VI$WXMXPLToaosjl5FYdhoK zuR_qlLTs%Aojpm-Itc!wKJq^p7yQaM$w|@KnHR-- z`&iUVPXzQPo__1z67G*mK9RsC@b2-S-V&&=*jqA}J^28j$xDPKpcM;;5}FhN*fYN!zKK6@ zFOcIg%W8P@t1qgq{CW1(7q75d(H|!#{rp!0c-#2T0}qHwy@aAJjmmMiLaAfs`0(0F zS)Qr9nqZ!soOX}i-ss}-3_$Cvz_yl|#Ma6ny=Z2uEStzQ^*;`W_Xlsa*IY&B0(B}Z zo~rKFXDhf2^T~G`ueKg)D4Yh04;5Fcp5Wdwwwf^FT zJpVKJSGDpPPLSYHHvqlA`NKc9cDJ`Tu3lZ`Q#cjA$#SXcq#|4|`*t`Pk9blD7d%Xc zT(I#u3)vz=O6k=rXbB54JYWx_{?RGUcSYFi?}o!ylT+m6UU~Uan7?hqtW}ztAvkKu zb62pxmOCoulI0B~I#mAa<(kivEK;N{F0d`m3w1endXp8KnxDm_EWJUs#hzK8iMUSC2j(O1h_Ds@F;4&OrdQZe5`rM1PYDZeeZg%uPmS19urQn}88l~jZF&1H+- z*{fKj@r31*cl4p_CvT4>-|w`5@*d`{pfDr!;WRgG>4j5qW3a61f+#cY?(3k1GuXOX za(RM)`k#8{$$z~p^^uRzidIf~K9nWzD_$nQh8xK3b!By`n-29nt-#6tm}6*L_4&$9QA}&Q z&Q2|v-s8hql=zlcpcEG)^4Z^!R?kyn61G7WYNyX-?abTcr@U3E{H}GOOjr%;R#^Z^ zpL*Ed{>;3c7tXS$N)!o~t13&~&K)LUva74owyY*Bax{#Z&EZr9w@=WzJZtCrE8U|u zwumzAYdx-MeFp^lOGx)$l1Br z!UDSYYjeABbv}n8Vf4!j3*H+Wj&O&G{hMdsuVzRhj~XGq;q{qGIcLoGWvHllQ2{om z5UOap68>II+eCq*6m1RX9_GrRfHC8UhUI=DV z(KRd}x@432)=x#Xb&uB<1WCHTA<_R8dy zv-lkkTMG6|C@CAyAK~U}S4(*L7bMR31XocVAK1ph(qlf~iCG$ysp|g>6|ZCt8v6Is z@K?H9d@T-PY-U`?eUc{Wl1kN`{pqOK{MVl@m#K;;iOt*FN3*miN<|$vVp%pxwB4TXA6(*awoj0ZJ+NCdxv+Z$y)Zcpa1K0IFrJlY8;D(!f@@hKwo5hTJ~t9 zFsV_X+oDFF_q%t_+eBrZ<|eA6-J%zkMckUEQ zWB436GQ`67kZwvPZ=-HeQ9kJN;}C@cPebt-g2_eh+q<;Ao>BrV{6tMPO*wvOQS(U% zBl{fql^qT#N*)J;rxDJ%yBohj0+tH#V?BT;%O8)CsODS!3}j+1^E18rROim)4Qzzz zQ_E{@u0g@aPDT#D<{|u{;bn%7#ba^DCnD2|WYgo|7#ey^sjC48H&?0muz9~ zq*xZkE*t~l+TSS(+QGbZUV7Zc!f3w5-Uzd`jurU^7YcFuuv&CnBJ2X~>^|&8NZ6uT zQdbvLEk46J)8hk)mZF9&nsw`#uOTCkZ$Sv|w?+k(m0d8v%>L)}g)&9^>ep*I%e1mY zs&tW1o$E#*qAWkds7Y9+A9%5syWkdLn@~#c1Kg7MhSO6tC*nM1> zXlEHUc7fxYnivl+5&MjXSRTsq-j?{eK1@}9W>~8r1h4^kw{PEroW5adWO%kws-Q-C zqCQrwJY|aQR{iGJfV*FMr7H26PeJbqD5;9LxDW z0AqZSPcP;gvXt=dE{T^U{lc|kT!&Wd_`$_;gTUJa)_(Dw4>H728L zZX5H1^bAWTXD$}UlYKZ%LKiq*l8?uxF7Q>m=I9!^-Th z()7L}4_l4vt5?4H(dWII4QEGyftPl_y&}hd^h}9t;$TFK=lWQEe&P{(K|7z7*Q>p3 zGeEL;J$ju|&f?iDIaHLk1aNmQdbIx4s#5GF>jgI>$px}$T5Bh=_&)3vdFS^nMsvM` zv0PDt+`w?RHT5lB&CBtwkufh%IcmWgPnk$(p03BMvE!lBbiga#r6b3@WTywDzlomi z4|r+GwAoX&&YpxC%g_a#M7r=NH+L-hjLtZ$bsHBamg|3f=H#xY*-bpLzK|){_7f#| zW=%RW4ULe!`&>~kN7Dmu<_q;-zaI4V5yXQ_rqkwMEJ}Fdzu5~nj<7&T96}}_AZ`pP zOQh;LPHr&rBvE8eV+`RGf)f-+hGKN|dunMr7cfeloROe(1fa zvQD?zX80KIN+X+PcG^37Fh0VV1$LNij10jgy^d4+5I8oI=t#ytoWdWLvr>Y5>fGp6 z_UG%!AA0DG3As-0ZZH*Z@xnUN}(hC^d! zQ>7Eh+PZSZVv^JU4cYsYRTI8?!NdL;HbsN#E2@aD!%cE@SmYlDO|ieloG#tCd@HYk z13JV8=VWDES~axzAD^CGyZiMOCV9E$`W%BC+Yt(XGpcv=s(-vceYH1$$g7nSE@98Y z1EkD)ois)@^2d6lq$D#}`d;gmo$&5tPQOV^Hr-2glW1 zUMYm7ut!Dv>dCge_>L%|Zvp$tnT+b)LL1_gRVon_+^Io6LI}0Nb=8Dh%Sq?e1Nkxs zxjwvmoz{i=+k`m5O&3v5an->~UWz#xPjOAQ2LD7LEF?hABB}MJ3Px2cuX@!LTv-2sW3H`Md3lK6xHl)Q2=VgTQKqmZD4D&CK#)G(J(vyd4-Tjb3gg+RltvYZPeaaW za|a=X;#NtQ>*XA5m~dn^XS2ZJ8lVx++0u1$FjqtuD$)a*VqX2D2VazfB$EZ}4E_>s z8>_|9oHJ0LRw()f$uEh5z^)B{^Mv9+-4o)srUO*(pbM6fz(N;wv%YIovw%(YKmK(( zo_&3Js{a~iMC6KY4NKJ=b)z0)K&}V8TX45}tYJc9CvVH?!}3CvTX0w&V$(-G814PM z35}s;ogi)-{nq(uj@*XaU*;89~#2IXkfK2rf*rgpXRz4pAwv(Z4K=i#p6!CU3 z|04OY$H!O>P32}LEGV^bJk^UhiqdFsWK$i)lD1i0)n%*ROI^U~9&Pd>XbWAs+R1fN z$FUB(cK|PENv3HGhok~2#d%hbfP)Nvx-5s1PtqO+00344@WF^4B%&;O7=(dL9aVBc zf|7TyleObF?XhXEgsXdTHn~K~SzumBzby{# z1792npNEYsK^VN}{a)<|rz+=1(#zRgHjaKeJ3t)0jG9v-UZvn^^%wzHRipQD(-h70 zozB`iBF92R3Fn3d2IJbYo@K~VgT>V4>9elihN~D^PA?bVIE^qnb)dzIef=AT zTwkjT2OB+Jg!TT*oFDU_vS=rn#6UjkVYl)uI|<9#Je)~@9TN`7`w!$3JxA|1X^PcX z`qj9FOCd=(5!P{cW`tQcQmKpt}n#m_-Q@M+K=9dpJ6+ z7{j{H;}+Oa(y!k=epVgs@97~7eC<>P8&CjYgbWZ~yddw!z@v^)JrFQrbW-kZ@{ zDi{{Rp{PJ|6N2996xVv@iAr(QAhPt9aPK4jmq{6UwjgnuV{}wKIh~!H&NQaVnc1RV zKgN~s47R$;R^Q3O4C-}uIJ1m8+?^bra<^)#m1x5e`mQzICbm=_Kf-W8gY|dO$#8@| zw3%pJ%X`o%S*?`b@~@5_A3!!{EdZF)LE^5p`3uom=Y{6Y1KBV3vY5Eq7LzrfQ_R1! zb@g@Nh%F~>!7HZi`f)hF&STT%eXz7(h_+Re?vOm(z_?<;Z{HNj!p|-CHwe` z<24q6_9#t;zKw@nF*AcH9{61beDJ4=fa}F(H=nfGNS+*9;=pGfqnX>;MIl_WH1dU zd`p`%c|tBIm~l?(BNFeGm->ZD^*UkH(C%61bf8AnFI^a2_V}^kkJZp11yGyB;pBo< z#fZWNOQ5-_Jj@tWdV!ZO&@NB8(2+KEFV*ED3={cd84>u~IYwR&G3UT(XugeF=Z&Kd z==T~(M1>;>Xl|V1w$)=nG*b)H$f?WKV4*h{RCDTqj`3%`u7JyRi=XwnJ21~j16ust zp!u!d>XAJRYPrdXqUYB0%j!^eUk@ky+jzmz3iDkdn%0ZdYQb>{UJ48|eU0w0>D9+Rjc?F?pVAUVOiNVC700U4kvM4S@ zuNjdMk1*w#7K6VZK-Gyu+U*Y{uwn~kuknf8(gK4MuOHwuvGz%=oqce``7_5<>i4|3 z?>^ww6Vz5KT$E8Sl-2LbF=GChv$Un{S zb?f2ghK8z$`ZL35K3jlk=9fUE!Fcp(>Ea`2jCwLv5_+r=BgR;x+97l}-9!<&JG$X1Zrq3Nu zjE%7|dpemQAiHvPEuB79oByfA)gc>T)#~-&=%gcJe>&yS8~!#2#r_!{z+vYjuH1~Z zZTZyay9YW!VN~_=b23hZy z!p|GXdRVhxZL|bp!d)y_TF5gdVO*X@bw0Ka;G!Ml;2B7bE^$#Els(rx(A~4y$?f%Z zBg*XT6W13s2fQQPCe~(Ke%GrQD~JKf z8?F4Az4F-R6~L;MZW>S?vZd=A%MU~xX?<@v0yLg$pyVNrVqXLX+?tC4wc750sPh3X+T)=+@*K~ISS9>}H36PuA5K@W zu(greUro?n z%MlNn$3D53I`!H6_S4OIoM_6UR@>M)vMp>S4+=6|JXPCl4h}8LhZ~|a6=H@gM&ERu zYj!A_DzR)T8_rQFe*f7wy|MHnOQ%HoucX%ix0`T&c%`%yjY&it=Du z7DeI?)Aajbuc8u_4b&B^(>8S2H&youmfi;kRdK?EJt>{kzozHIr*lHr?2;-&M7-fff=uK>&#EA1S$@ z<@4vc>GS8Y?HS&KU)=ca)719v)6mp6faZ5=T$h>;4;Tiri(S&!sr6Ep#&%55&uR7{9MGLbzhqFP&1N(7u-lI++BwGb5u+p*ikDdQ!dqL1Zh*{vZww`Zl2DQ3aDVf` z)?+y8RrS}l5SboYx7;YpGL`(TA{VlH0!Pg(iGi8EW@qv& zI_`Msi-<4AosMtebG>0LKZ3NVb-t0c;I@P_3cS&^FF=RZ2M6bwe}TUvg$au=R_chaBEZAm*Z zw>7t&=kyAIkYQc^5u3YD)y?K)sgG^82$zP;O&!OrO(5dNb1YP{J6~CjUKO1e3=(9V ze?r>#&XRBW^mHVyC8o5is~7VDT+{qC6UD2MR8L~$Jh~s{^?@O=lw^j{PdE@5QH4qx zaIam7uL4BG-H$5qCQ~`syaUO$?!ZK}SsON9Q|zpdMOa7ZAAodRwM4Y*IdbP9j_MaB zc)f?Ekf)E)ve`>wE;1XUWo*Bprrna%nWlA! zV&Q4Sz{&X=ZV!*GVb<-xMr+#mdUL#J5?aHs`+xP;H1llC|4Uw8ixyT!-q_w2@ijdU z`8ESW(RL%C88XcJh0d1K3C)|dF_mdI1++1s0v3@L>m}=tAd&`C<#X=MDv(!^Zoi15 z*5C8zc^K$VRg!vK#TJU%zuFBg5%Y)l9raej*T51w8>T!OB<*5xdV7gI^lQYvZ3bj0 z@{T3vy%HrZw!5C6^;$wX#8VrZEWVG=nb>YTE zQNsS)qv`02tK)p+l(ixP`Ib){B9WXF$e*nDgn6{RVwtYJ$uSaH5PCxkm!@g}4DvBVP|I>NHY=9+oUIl5@s%!)pCL)AZK=7Z%?kMzo5! z1Jp+O$q9&(>)(z}j~u+M5UGSkhncBojAgBM%uXE)5HPMO8`XB3Fg9DGP0XP*%{~$?DFwKurp*mFg8hm<5pwr|z z&$&x%wqAR_tpEmO9BISFfH~2oWzL@9oAgqmvae_)zN`s8aeu8ZkG6Rw%_7R%yD(yU zZ=64`0kXy|U!`Dg^d8?uPvhVDdttIarImGtE}=TRpliicKSu*YKY#Vb#)6BtW*WB# zCWVrPsYv}4yJRgh&S?hd;*eW5 zL~lcn-kR{KqcI#!2a}m)U?cT5U9=17$NCa76aZ}6K%SZcXoKW~JqOgr7zb2G$mkO{ zI1%F_)57WI1YNyao0?SMLnx;+72iG@zZ*=DFw9VK59(a~oB23h^&0a#G*?|Gi2afi zl+;V4j@Dby#TnNR_IhRvq}tknC3Agv;9H;@`B zqX9xxldOiwqB%5QevLGQOR|FoI8>;2xLGMZNQ(4|fnQtetnD8iVZD7iI_dS_NML@7 zRX2EubxwALOMSQ_J(F-w`4a*5W3h==}@tqJA-`UV~ zLQ_ZZi%zg#Gr@5Hv0dk(fpyb&n~!bu5^BcJJFuHbm#q0-L>`|^$~+B`j9_;p!G&6o zY+|*F)X#k3PwmxUU-Cm#d3llLz}GZ&nLZ-M%27Eq8;;{H+`_QH=@gkOfB{BC-U_XU zvefPvSzk!N!~Zda1kN4q4RKe@d%Y0)hn=;@o4d%4dX0>D&3(r$(?}Mo_6Eoxn(58c z`Tn(|!P|lRts2gj1qYHTJR;e;9H1_tEio@lMMW_5)il6hLA^e^4UbYcLevB?m@1R) z%;!0e9;wSR6_g-Dvg;tlZ4cO`*u&G!2b)hfA2U~_T)?-%OK&Nt8&cP4?w4r@czq(h znaavB1LL%L88S6RYSvyRoHNKcUu(ikR{rWaglMGoxcTVb=KTlQk7}mn)H-z&+tRD( zKt+nH2sY$&xObje%{tw9vi(o(6XZ>)KsxV!N=ZBtIqLz2Ro_kB!Iv!vXjAQnF3ns} zu5ZtQVUo^&igcd;cawoQ)TMH3K3mBwBMU#D%d1p_5`}gt_l393diu( z^Ks6EiEC-BGIy{5T_25)#)so-9oOmI{_O7nrYleUkp-8ig+8FtG&ke&e=<0+SfQuA2)j@ zAq0^f%*~?7wHBbdXb=mv#(V{ogB`YrnFcR+zW7iVeQ)&5tHM%s>SH*@T_vSvNfMO`*|C4M(u2<0E6W%%;m+9 z__XqMdy~q@=of#4Jq^XSuSD-c9$oRp)w$t3PDnboeU2v*C&fG>aWEsZ%T_hk0I(qc zU-cO?bew?pCx80#Il2Bz_}d?ea|p&0J)rigbc`uGx#YK~t5ZnI7G*_Zil2fio3~`9 zm}RCf?`?`bqzu401+x)jbMageeeST_$FJmla}k#O@3N<+|Baz?H6w97ap={-Cinob zTtN8h!D3N%B@u~c+gw~2?8jw+uO}eh+`80;vbMKXXR&wZ)UR)D>C9;#f95OvnXl0K zX<>#4^h^w$Q0;u;lJ#~vJKZ0S5qrq7-TbXq%Oe(c_h*V%eD1dhoOez8+v$yK*S;DZ zwqMi!!*GfR5XNIh;P@R2html4N+1GEhk1VTAYjih#=?6+#4NHC)+p<&Z?!Wxp=!{ykN6 zk*Qa_uue!=QV-(^JKS!B```Q6>>J2V@ujmbZqbUOqYnOr2|e2zpWXc88b3V8pB4Vb z*IzG1NY}5mK*DaiZ73$%#O}EL;2S6W&fU3JcQ<%Qy!sZMsd}<4P*wxho|?7@S!t*njxS|hXPwDESpUbib&@UJX=_94l-D`)W%ZjkI(~r?`xaapB-Chv zgwq27eQPMt$XLTm>g4uW4=p0`w7TyC+rE}0qx>I9I*E1L5w-rQJ=|is=NbH{pt$`gFh*|H*fd{t5Y=ve0%4nSHhoYMKN!a z_y#YM36xHdUH;LSN!w>PAps!(*OoFVDI zokBz-cdh!OpwYQ)JCr?bC@i~tKjh>zLh_KyJCRa8SIQ`NYl@ZyOTnYH#0w$OvZU0> z!15c9Myq(p-)qxJ|5fVkPUU|B8Pt?gM>60W&nHOMBlU_Yb!q2d(8m8XhymJysWmH5 zhm{&LX%hbr|I7#P7FSgWM`J2phvp4~&C>$!#1Q7g_6S+rf&OzV$vjU=fXHg`)djC$ z37BzYbO>UtPBl0?6y0D*<;XdcAb)?h%0~EDdPa(g?5mv;r z2@pg|gpemS*tw+MYbZJ53w{}&T=EvDXs5Ha!5J_2Y^#70T&Ow1fn0f1uN85Zw!(dd z5T%@|=xet_(1>UWs5Dg&c7k*bL2XxbAr`^`1hputMAcHPFH=zSwA-h}xLqVW2t{@| zfk~Se_Q&|sNj7-|MO-6;+>Q!MZOehQ-TM1D}R@4XixX50UTI4lWV_zs42s zGLp)AA1J9e|CChYgT!bH1KcQ70PZNnuc_45yx)X)Ev)C);!-pT#<*wom+ zn}Vccma(ZBz<(Q?y0k4VDlV|0MZF8zPQ=-lvYo8=fwuFjKPB={iTo{D9e;rBECgtg zcUx5a4H9|jmrJ-Cmhau#(oz|gllxZITsGSdcWyHWS`NHh)wJ-^9R)lyKft|lcd9EtO@10( zxrAD4)~OvLS%2yora40E)sfUdi^5$QPn|?bz9pX4W$+S7z zH}H0}fFHj*8t?V&_$==H*PlB`+u><_C*VfBn3PCiUcAgmIFzHl5_8YTEI4%CDfdfF zW#2Mg(~x?lJ{tKU{eI#F|CoD}ty)KWG8iLvHz>4A5id~;oi<1u!NnkA(8_DmA` z_t2PLC+)3xEk5F_V@|ZT7&y&@T_dienaTZ2Hk(wd(2Ke`r)Sr27l#}@&khK`&=}yl zi78%s#8pebU^4)B$sdp+ehbP7WOsV_BqpxW)E&}AteuwQ?azJOWtj6CbxX{N7|f4h zJDB!U8%-gD5s_C_b!g68e0AJjyJdRDT&|P;IbotVZmnMVhSX9e{Q2sYr-P$yHHWlR zuuy`Z)J3W2mb-qFkJZqD$t(vHWQP;tj#fUMvu7ugN@wj{d^kekpgi~t#|CRR5P-RT zypp;TxnFlMwMY97I&?%bO!`rX0jCGcarewY5Bno(oqSSpK@r6`yE)Lt7@WH~9lALk zvBTf!0!UA=n7!i5zpCWE+1UC1?$d4k4gG8tD6PcnAv}pAd*Vk+_fPvX_i5B!0QqC; zB9oQqFki!tVAX-!v-Y%FRT1OFr- zhVyr@Ma0>?7Pn76R2wvU{YE&%e&59J9ec4-$pGr#J;CD~>O^h9r65?N0t=^8oaj7y z|Bu0YSZQ7?GMLb@Xs_iZ%BVz21Wm(Ja>0=L9y;v~`w3RX!%=TGo}d@y$N5-2Ji%dmRtw_=IMAmVEoVg6v<~ExN7N{% zI>{=j)Xcbd3oa52xq!Iw)#o>^-}vIo8#XDZvGID)fAe5Gc>&ZRClbNlJ%XIEBM$r4wZDClDYP}}!|0-@cO-mM5at{f1T`p) z6vU#L()027#~vOUHz6@WK$9mYv*GdZe+L;TN0iEy8}&B(HUGN9mhB}cg8^0#^O!}o zL22jXl#xxNDyTa?83$2mVx2>sXFJq;R0jUeZun zYnShVlR|i>XL@(KIhl+nb7%QM5A)-d=a129JmjTPMC?{pPsss5@3c|tZlr?UdOA25 z;6YR94c7+9Hb&ZFSl&6s;A$0jIE9P+^*B7ZoB;>)2EFr5f;>lGpp%05?oYd*m`&!G z+#a(@3J+j*wsE5!pH~f4eAy_02Gm!%13rluwv6RaXf~G^=zDO$vFM`Hqa%877aOSf zeDsc?y4WM`-P5jZ5Q>byZ5!ygP9b{tI3^QJ>%BcXEzQ^5VH6bAA?1nmUa2Y-B zXg(6zoQKl13d7(ly`go{BgR(zKn>&-$a+vYN2mJ()@ZI>9CWDUa3dVVRK8hPXVZGZ z?>Vk1RgYbgtNnpToR6JFv>?a*YW}dqSS<(YL!IJ4kwhU~&VV&JiIjdd9C#lA-Pyj6$MX*1)iQ`wSHY>$^Yd#x8zFlZnq&X`syqMd;SR1#984BfrTU)@ zq=up)%ZQrx50&tu;A?mk97Q(E;;H3Dr|G|X`Q%XC2QeG9GWzE&AOYxb(mQS`dG_>S z%hw;r6F%2>KfN~G#PUakX|^`mHjXiBS(j<&x*!P+W$^@S=!p&2>#Na#>cFKu@2%`U zq9|O^&~X|c!K(|%mo=Y_`p(=&qq3Zyg|5kbb%Jv1<%i+m9Rb@<(Lfo9eche#en-^u z_E37FDlzU0>#4e8($qpgUp`isnzY06h@QB+0Bp5Bw_vvwpJ>1+mfI(*z+h1>g#j6a zr)ld6k$%vz9#OD*XUCYq{!tINFEDa{^^$#mE7xTdu?AJbR_@8<7WWG7svoKf3nos* zE}r{on33Y6`Khd2EC`ZIlom)DP-|Hr8FKLc^Mh!bcyA^2N8|}4ac{(C7JX4Z0v_u{ zp<7a7n6!8NxZe6TjoNTHpixc-P@Pj#E&E_WZ4+2w=JL~GtE=WM1)28v2r)LJ@eDl| z`sujdyrYj?7f5y3nBAw(HtBXfxchKtljk#-<7-jTSg*EJOaat{gpI$(au#8e3Aysk zf1#9@?sBW`PKQAvoI~o5_n`^z@O%_+QR!a4@%fF;fB9V1;m>7VQ1(h&5KWaFNbFh# zF|#`zb!n=Nzy6hK$8a}6Gz1|oug<7w=rP_&aYldcT4&OLe)nwa{+;AP=aAMS$r0E^ z^rG2G=2pa)-i;^wUWHS`ZgfHaNDVEf(f-;XUYu4rk0?LX5yo)lQMM-Z#;MzWCXmhI zDQp@?>dwMFnJc@>v22fK?i@yND#)N04}Qji=?ngPnL3|Bfmthy>oc4boZ05`k(R>MuaEb?qRcyjRQ!3NqP3Y*`B)9P>~ffizg2)kf| z9s5}~bX8YXToV!j3>6z1g9#ii@4Jl2;59v{zuX#Q5BR852b8Xuc-sakVr9^xRA8nj z(C0kq4z|%2=ll{D=B5M5X331EQ_q?n&Vu9K$qW8#0%@&^5@8vgm{7dJI*KW=Z4)lm zu=9UPK=CV7$l>=!S)%lakYmVc`CJ#)A2v1~+8*d+7qDrTL0)e+AG)E{95=Lz??$3GTleHxz1J7a(eQQ#q6$KH{8^WZlPC>IM?vTTF`yCWAL8dn02MH$5n zbr3d2_KdKldZIssE)O<7RpNp{_^h_qccT)E>9z=6kc6X^84lAXM4V>0hT(jq00c z{edw>0F}OekM0rDg5Q>R7<`8*`<=56qx7dU%=E%M|J@?=Mc+YshJn>wW}I;EC_ zBRH331l5T)fYvFENYfDAG&Qnh3tT{PBk2>++iV&vF7^T6`wSZ}(Vm;(yp zKSa!R&ag4amN_O1QwsEAA`t+)3`V7ZWzl<+8oVY-Ne-Z_q2^fe+1c5Q)1ekb{&@U!cXum}+&G#};1=9xXX!#P6-%GFpoyGImCp=#v)2~2vZ&iMd8))R zBkLtUKhk-OL(qLKetk8&J2k5wz1o(+1fb*J1h$53o!opO(y5dlXpG3ilir>T%%9r- ze$Yc;(I)qFr@#*1f2O?`G_^!UHT1#k{eAtfJvWSG~ zFE&Nxxl9A;KGRu-xg@herL z3t*>_Ge$*x;LC{k8w|m=3OFafc=2u(y1z8JswLVHJGF`@bKx9aQJ-;h{*&D zf2sG5>-tY;@Vl=5^b_(`d7}r`Rr6Q4zMbbrN233fU^-0jOCQJ|P7`wkrn<8)&Q_u@ zw5lZPm3P0HA;D?`^MNq9`1^O`s)}Q3TURXM$*Y-ahaP<|RQ`><6}gb-Im#-)G6YUJM|jJ{n1wH+i%zP3vf{l>uutZmX+J?6tO~%&YXgnFDqUgxiO^3Nw5)2?ge{(D#0EvuGv7!cJ@q$Q$ zXZZH9EU#&HX=yW^jg3YzTzLq@5jya^E=P`b-e<~8Ss(XC z<%&dGu&&@XAW~?ivY`lU!Bq=OBolTHS19Wv62UDfSQ?2hWWew2)^{&+Y6}qSFRgR9^JpY%guXPi>IY2IwBM1NPNJ?Gyf8%x*0dvC#qLlVkjto z#HShq^K6cAsiB1FGX%Yw0__%*b^M-?vrg*7kIoO@)Kh(Xqr8 za8a@APy|Al#4Yz_SJ%JH8l~O5o@>^WKG9#9>!=>>*Zon>h*=Dg!r#$z0tbJn0V(3u z!SN>c7RQx{N3>V!J^lNvOY)dLvY{vy?n3>nRk0LgauZi`T#%_%pg3#sQ!M?*%sk%b zTF(;4ZDUGnu;u32pf3k+v6N?)zoY=9A+~d_v4jCUjk^4oXZKIeBGmJqGG9%I@GhYJoE)ckPh@xrP&(O&pD~7H2VN|ux-EThmAN! z(v(b|`kKG;@MfHhPa6ax<+3+R}TD4R(6RP7j zM{kFdvE*yfR2tNI8gmI&MMl6VZP1(G*{f*M3M6Gd3;$0J%`MB%&^BCa?aS#Q zGPXG4m+AxR{D731T21stGJ(EQyRUfKtJR4#HVe`oV|cSvM@7Zl53SL;-QW=PvLk9# z^{!B`)R>;*UVf~{j>hkKlqHjIk*GD>WK$7fNj`??e>dwmsA(PjW>IW_iV|64_2x`+ z1Y5^Q^j&_ysd`i@*sVPr{N}MlC~+7do9GF4LbJxz!f1G8x>i;@*>}Y0{)lwH;HaC&m7uDaD-OjX_D-dp{!nPen{pdp9>4Mq}QL`_5kf`~c> z^pAo86$mQgB%+Q46%+^>R1E*`TaSJAKIhz9RXqa($#nltoqP6suf6tKYp=cb+K_#K z^KphbrQD%Me2?WQj7w@t(z&F(EmB z#98t+5t~%T!#(|(~xWBkdxOV4pPJcin%p`EZIGc%}JiOL{b%NJn)409&m-P_(Rd< z4us4+jpn?=&!OcJX01z4i3xKbc>L*S|f8|r78lMp1m zHw8ISItP6RgLT1}XJ<2PSUEn>EJsIla86+xEOcn*EIDe=#TEz`oSuI#J0s^-Nom}Z z3Qa63&4kyk!R>UhmZAagXooVDbZ4P6%k1g}M@EWbv*Vp9aOy~9KLyKF1c-`QSt%AG zdhk#kMo>3}(i_UWnz6}A2=Y98!WR$Spxb`NV6RX9W!I+L@fr&_CR@wFjGP_QGf z^Nl(*K@zL6V%tE>XGF)9!wP+lOT{NG8oXWjj9cvc4T?H?20FnuAfh7K9XYbaxE3#j zdLGEYP{(aZE3MHUl?Sco4zz8}afdobK;0b02(vjaqEFY6lw0WC#niWPMaM5ZM7;Ik zkOg}i`*T5?WWtj9GG+9@H}e(MG-FT!CjM3VBuy zg0GHh0?F^$+dkF+whJci3wm@gsoD8j&kYNr9=2QALOLEm6U~q>?{m31J^Cz#L_Dp~ z!P3;0SzS5ds#f4s_8g+bY13U5D#@}@k`$ty!4?{`C@La~o2nMJx$oQHKAQ{nH?}-Q zJqnbCnPpjW#pfH=r%yl;>`T7LDO?m4uW#}Tp2}C-a<_QT37%oY+`ifn?RFo+|nxrN<=40YWyV+S?q{zENq#roOk(0^M z!8GEgY&!dCG(Ed41pTO%iYwe)O=G3)_OYl)Ojk#x3^+Il>WA^K%0LfDr5re|XjoVR~_pSKG!VOd(r;VY0(9_=6ccARwR^$0WQ}aHc zM55TP*nF2DN$p$BFP9HDE)rh`>e$#3Rpxlw%1%^KkIWNQ!nJLbbfBH+2x8Tbv?g%Q zZFG4Kj0uwQs(8YZySz;vDPgag=0HZ1Q~^cn&@NClNqd?Qlam55*^oHq@B`O^$#SX% z?7lXAbo}UT@D9amB+>ANPVFq#sO&-wt6uE6t6E~h_kVV zpH-tTOKd-}X!)JoNt|3YZmD>+xf2@;>XfcAFOK7BvGN}d9sr6yDu5pw_6Q((#I12C zR?%!y&AatHM0&U%DAaRbp@5_G{>=>>L#I+U*TR>w;d+BU*>23u%;On>dDAx=?Dqw6 z3$r>mtVkaTiOgYsrh992NUr>QkCJL-mv?rWF z{Ein=kzZwBHJ|9NLuV%iLx59{b07eDZZ5mz3-#(7YB`s|&<0vrMp77^jfg8W*liW> zWN^XEazTA2cT`7fWyGKwpWIl6K^JgkILEld>8S5Or7$i-l`GS(sCYHK^h?+wGu zgU9S)3)aQm?NKUE50CpBQa@ESD#gna-CUb+R9ofi7pDxAIIIB`ib9U&+B&JU(u+_) zrBo4DkHjS=dllHQHn;CRH!Ffip?JRvs72?6bf1LD2AME;Gz#v}un@*rZkzx+@fA`6 z;uuzjbb#I&X3b{SW{#bV!e}}>mRFIA4PDdq60t9*)tVz%b8=c)Z`by-RNM_#^$fE2 zutm+CP{eKEDs3<)P-Vps(7#fjq{KzkZ1HT0R^?)^-xHq$)H&5+tWJ(c`E5w?GY=o`O`( zGa;q;(8ECrPL{3PH_TK1Tl9JxsO%^T<*5t(B+!a zD*r9crDt^=X5L?(^523z$7qs5$|(Zz$?@M}!xc{at;2td2zXHHxVIJxNr@6zv=5?w zfGi+pp%>-DWuv}Zbh!`~AjJ)ecyqOCePN4!*$k#+r(7CazKLiPYg?SFS8_vHYaEKs zByjCf*!|UYM@+23Y2tV~Zos*NOV8Yy^`-s3)Mwqrtzx1AX)+KTKE@TsULFLm@~X!D zg1N}cLn5EM5DvVOU1g3C>X})@>5h2kI~+PuiCD4dS61i(3H~H>k5_e2Sk6!x3Gvcf z`;_yCc-ml-(9bbHfmF@(8o-~Y96&s24j^>81!5VyyK$oIDw2>$^sur;yQL!fXGphQ((MzDd|a;XBSBTp z2qzL>R400me?^p_Ros~`A18XnXIZ|^A)i~azudqG8+8re{mN(ij3|s&d+oDYAw;MYSL)hP(`6D zLt>CdKW_g;>k#3d!d2tRUy|i~KEa+u*>hdOl4I|5ID(*>%ncWlH zpZ6g$4vLm4aq~H$2>86|xt^(TnTTiOOsqac77B3`KOBJPgE+}2q5V%o>PqJr;<{f;Qk3%{U2O59(2kfeSc;pDv)x7AtaLkjC@Wej37M8gli_!FcA%CA!Go zE6SC}r>U)cW~xl>5+M8l#s7_f=t4N?G=pBQOkm?7&hnhZT1bHO|Z&EQW*G%_53I2_^czbGk zeA)S%3hdTQUr(7kc{QW9Ks#bMqzC?z`>b_!57X*+e|{yF5OG3;yF1t^fDDF&&=T;5 zn2Wi}SMoneSNR$!CjFjX1rVeVHz$d%GV*l;EzT)n$@>W~D&Mo3-+CcB@yPvdWe#0F0mUUXtgV({_(pHFx=B^2E+yIPs4dM9Dq95U z?_XEh3GJG-m9toV6@F{Wy{lm1TB9!Tsx=uEnSz2ak_R^CwYH$pEhvtAuFbhzoC^Y@ z=^heYLA+G020(DQmK!VeI66^q;1+8>V%M|1_ggm7t+>RbM<7_D4yg8KD}e0b%{Hd# zJiv!*)|NYKRQM?GM0tyhlF-uK|Wbz543E6V(8jsbC zB!ntsb{1?Qwz$^zl%wk!VX0P>L+8nEbeH=j=N2w5G;oxu9lQk=T@V-;&Mhs@ zHD?!bq?)VxVHu~Py>YK#|Jo*Gf>dF`LY2P(E7TfmOJFS&137iNb#`=7Iqw~Vat{t? zoI*Pq!18df&pDjc&Th{pUidJ(f{(sA`pAG9jDV4FRNos59W}~LLQG-!9Z)|0MKP{N zyR81C214Z=HFB{8*VAPiNV@#QG#V4PeyX#2 zGBs7%AVg0rt_&XZ<<`=KFy0_EqVKN6M@}^_zUi3^LM2jT0G$89Hbij}G6RJQ{ zz(;%^MP?`ZDS(!Ca9oO#>o8<8l+SL~|Gc8247aiOmc+#^S{#LjwpbI?%`^8jn#6HRa$PEeE4Bba-L5-RiXF zyEXH1q&knjKB=2WwFE>f5rWx*JJfOD zK$!v&Rno;IVCY15QrY{IZt@J<=XjK#tzE%d)S?WwApIyVQX;T$Q4etF=)8cPLRP-e zHAL6h=KNQ%^+M{2<+-#WsKp2uKpppAk766~Omj?}<6Pf)i2#t;tyob6Wj+~r$(GI~8*D`_7Aadh^&K)C7gZo} z%<*j9L&hrxmpco3bGQx&5JV?Q1m6vfSyCqU{|_#2xX6GVHcfgk1bQ*tC_`W#r=m`y zFiF5(ZZyK#ahjYb^q`2eg2?10Rjg;N%)nE)WJ6e)tq5#)?Y{NI&RcFivGdlQ=(6WE zHMwM4CyIMD~V2~gD~Xf z$9*@3Z(NaMF1zy_%3C?PFnDxexpRkp?Bp!kxl^6ATqNtgevZ5sr1x&+5#IF z0$}Rq+bC}Cwq;sqg6U6mPOy5V_+6>ML*JlA)}zy2hjnTzfssY%Hbe_ESdMD9jVS*e*b;%m|5QfQ!|? z24KqB3mo_Vy2U)Pvcz)>D5o>Enh5k^89mnZkqm*sb9GZg`D_p=gnA^4degX&hpuB; zU)`_jDOJ@!!wt$MAxt|~nsRo_mwoUH*Xk}eyDQo+nbx{vq-imy2S=CB z*TyD~+qDj+0`>tGLrqUX7wd#>5_x#x96Uu%I*GEq{7`(w2;RT@fl!2)ehh@vap}UG zI7$lrTz{~pN+LppTxildM91yb;a;k^H|y_Ru|;L(EE>R|Bk9{9cF`X#c%qsYmsA6@ zTn=tbGhkUr%We7P;;F{uQ(eE4MLlIP+z_;|+#Mdg;fC5hGwo&UI^0$pyB4L%Qlo>L zuy7{;T^^ro;!1#(R=W%AIN$8r@o`1eKu@q7GcWm~@Prg3R_lH}JvSsYMDP$=d0wBS z?y}?v&}{%*=j=lF^zdMPw&V9-AXh1N99NT{g3dcirfqSLKmdtm;-VJ!FKyqs+ZUeQ zW~VFKvpZ@bH5@QVm29GeGPp7UptjXKSGe~>E`oqPt}Xn|LzC=j1Ofa5ElI0sH#_GB zH(b%^YPWS~bGcXxZLLhX6KW}Teb1UbkHNX&mca=Ltr8Bj+DrM3F`NSFa8E3qY|h~h zGq>yQG428#1M(U}dQ(NeTrI!>9u5%k;T3wZuJP@O2Wgox;7XXGC`#BQqs9?4``ursLU!;_$pt zQL>IK#uAVFv{?|5Sux#-r|i#Q20@>69;Njpt5O#061?`@LR!Jur2hm`h0yt1=w za&))H39`hur*U3~`H7d7=ebepL=H3ziqI|CAgjJ;&PL|3tinGrV zfA5HgpgeCp>IA)H5v}$<5S@FuQ%S%3A$0FZ_-S@f(raWqG}GxKPVN8pVZH7(f#2*M zNn-&+N3`HJhIoQ=-$I0BkVJx|YPF)X)^@KVH=p#@c;`Gt(%n8K3PtV-JjSkB(j>?+ zE|qWE3@;VN*+1PX+|sfy%|%ngs#LZ%0|td<*!fZg&R@I7S6a&$iM=Cf2%%qC#zvDZ zFW6^VP_ik4k6aH+5T67ZN6zI=)-|L^z)U(ajExu9+%pbG&~RaO(Do1c{Z(>bRgG5f z9osCwV{mu8~f1@4404u3?|F zxe$c>2J>jpoUHDh5+v~KyXreYM3SJ020Mb?38RC3)UoazF_e=KfsSrIM-5bJLa|92 z7kx(1%o#F0xd^&MMc@{CCzc0VFtu%iB)Reu%%>C^H#s>~BP~cntkHt$cIA}Q`nUz1 zPIKwx;`t+xL#2?>IG}GCwy0_&=UJF=Qk($V%!h9*Z0TXnDFM%Okj~&nFh~=m6}X0Z zVNpbaJd+>9QL?AgTwM3F3Lnffq^~{V(Bx2>lEsJ`MQuna_})Tk7zPS-`^FX*AWD`h z^XPay$hJopvD%}x>Ao9x?$Qe}@*v|QHm!+Z>AdbiZY0quPX4eF0N|u#p)~uF*}e58 z*A4rm3)4~b`$7#OY^7j8<%Ea<>FlKVC}ZX0>8Gb+%ASw}1*uM4)6-ZGYK$ko7R~Ng zf#8(ejENo~*o+O*W^8c4%2`oGK*H+MsFY$SyFaQtjW*R-6F1fJ5{iQWoFbgmY&W@i zG0-0|=C!DO^k+>WwIkubrC@!T zrJW-2;!W5dH`=V z3xly7nuC&;;oX_egMefQySg>#b84-5&JYAku}}(Q=82&@?q0^R5HRT4Lbo2OBHOAR zMUHl@1A2+`PPL}m?X{>(hUU40fQ3$XTdmV<)}rR4Fx>iQ_2dPbI8h_EV2#qmpsQ;M ztTsabOoE9*ls#Im(fMw(Er9ErY5R6BAmAJWIKXzqOovazGo7dF)xGmbQZN#Fd|^-Xei<*W%uZ;WJx7B}A{z ze56P-C&k`G?6?C(61T}C;x!pLFe2U%5R@=yg&9(wO+!dxSa#l&gvEK2K^5d$sQeyF z%7$gxQh@1ent&fp92_Bdf$RiSA+H|~L zsU8AV3GUPFEqHS|b#AW`1rs zPFqmQ)lTUzreSe|lD>&JP&+gOx_ZZ;StGZW{j{KyD^@w8z)0i=G>cr%fLmpCW&L9P z)O<{xZu))P#Pd*!glw8Wdt#kUE(~C4K zYEC3uO6ktBl=e}Qwz;Gyqf_0etQwPM#YI?8S4>CY<>-x?t~W{47;)~{fHKc2XU41G z;gc?&mw`Hxx)sOaR0W4Y!MPmc&{sRCj!zV}z#6a~ttQr*qP<(3In}9~|Fy8nWLY{7 z%c?lwV@W;cdODSLnfnFJ^HAW;?X!}{*s{GN9?B_eN{%@3Jqydbca>A>(uE0Ag{KHn ztyY&pcV}g0w#i{)r-&Ug-Gw71!1LiKLcK3bwXsVIf-SWVM1p7-4j`)tQ50zsvX64u zizIzeCznH$f^bK8qYKq@igI9oqDoRX)8Jr&w&hS1)rFlHPw$4+J6eZA%XfOJ)-Ts~ z9X>FYAO=c5I)8Y6)~nJF)R5|!3O700ol#uYj-ST>EzDw7Th@A1VdB`KV^gauqO?)9 zS`=W!-yw^|CAPquZHOjH1LA;E6OS)1fb!#%=%D>#>kebLX<`5QZjdl*G(P2V7r8I+r(rXufYGYuwH-caJt+ z67HoP^xhnTPG*tY7f@O`1x;CgQ826`ebwTaa$;k-u%%P91@qJ(9?6$U;e+LnU56ZI z3ODz;?@OMk>Cx$fV}}mzPw@T_WG|R0K=*|u#mu7MS23*5JnL~!Ryql!CD^nGExBv- z*u*$nQoOoRaRKu_X=BB8Xr^?miW%B^yUaj^FrW{GELUB{btom3daSHfz71V3@D6Y| zaboX?eE- zKl!4{mglIly1ek>)h3jZNaqw(D?Yd!b;3T_2}ue9psAD@lF`VpN1u7CTw7Pjgym9{ zhhKS?pmYk*@>^Fx2gU1oGP~r9N_wjU*5?HX0k?g zbB?sS$2(w*6{S0+2QZj7*#eM_f$Qgr8v{i)hyicUxT=0zZO^tEPcn-1rOLTpY`8Gv zlX3!9uvJq_xCszGyI=1X&p;~p>9_fHr ztdfuwZ2NGs$swd82|z9bKuh=c)KwQi)dR0AS#wTw1w#E2{5b#}Irmcpp~=uN7i_32 zqc~3$0w9-=C_4+Yp3e86Dk2O+6y8e<%kW0Gcnl-Bus8>(ldP=Ru2Pr~RSn00^1At| ze?`)CIIYBTk~S2u!7CoS*(qG1eQu+`QBO;C3S0=SnrcT{vX+|U?gI85;xdmeEp+2Z z2V*%rFW4L17g}*8QzHFO!oVvZ-!v>QoItXz?k>=4_Sot&_LcMfO#;Hg?1CG?(?Sq1 zl}mzBO9lKnGP=x-dytzmu)`kbybhAMhgPl@jB=CM~F>Zt&S-dG3fVhNL6>_?)L+*cuhJZp+I4oNQbd} zTinMqFuqxApK7w#-#1F%rL29z*-1FbE#r^NPk-^&ceJ_Ax9Y*JOYDU`Y28*rj@WLDFFwvNBw-HaNlbEq3Insh)ehT#XtNckvQ@5j)l;e~ zD~k(ifutwJQU(I_J3NEk&h@dD2}scAg_G%uW#1C=jvbqZ^0eJuT_L$GB(Sk6b(j!0 zLYD)tsO6SHiy<6l-^qx~#2_jZ>eC#sbDCGIL#TJWBN-B$Z7;wR;3-&EIcPfUV|SD^Y)<*S`;Ye_nPfXx-1 ztQt>L^|ohA3=#6xI&F8XgV6f0Zz&`!1LpFz(s4nsApXc6wC`pTk-1+9Ge;(k4D=+Y z`W8|(Afye0?;R)Loe>wL%TYC{tYp8#+_*7sk*Xy$~!=*ap0xZ_IJ)HLvGci%kus9{oq;)!Ob(mxcsC^MH ziI6c~1Y^CnxQaFA0T}-ZR&w7(HP8vCj$nX>gi-%6Ugubx05_ zjgBXYWSmT3eP`nB#@Y!kjJlEXv$< z=BKoErdJncs8d}S7VDx=Sa;(J_!gHsP*p!sH6$`=<{_1M%xqfG?|ykbP$})07A9Y= z2E#+eS)7>Gsiw*rphq}E&6OJvUs;T#E9jaK$sq!AxvmGlZhTgSVY%s=RnB2x=TH(CCMsD@>TC?%Uz?}plBLm3E24bB1r_B7 zTx5A(tnH!*WWG!scV9DM4XtCw)lkPRx_Pp^8F~11hg){BO`S)wkwCd6ga!LH{>G93 zWD6vmrEnz-oYguR2P8D1B2l_QRVr~^$YXaL9S9~y1h5We9XaY)l`^h9tnwubN|T#C zY?V41^o}uDz)o*Z6qRvgqOFW0$oQlVZ6#aknuR^=oKtjf_FgH=HzM1;~FE34_|IVX=8~iW7XQyV#7y!rVaOB z1Lz91>F*kpCd-qa5ejuJ>A?GL+SsSnMH_Oz!2uO z{bbXLi-Sg1z$6K|rA-3c@chjCho?CVUfxK4V)w4)n zz$nCF0ZYU!D&Z|{UI;dufiA?LJ?kbrB<;B4DST+wSPrOc|LgILSE zZP*o`isp!dRYgaub?Y^1noNMCu_(lv7<^L)ZGu}OORn&dXIQZlAd(>#j0-jBl(Hp4 zdVIP!^uL(rI5-4)#}69ChOd1vf>~ru>WWLD$D*WUlu~D>lTL|PwA#9U`J4mkZP8ko z1q<_rl?~_z8a~#ze$uGI5Jp+WfQ@kYs`;jbwX+ezsuVwWsZgSSBbt>ko7%>LzB1?!Uzu?cka8* z9IPb%Riwf3aTaN795A#kJ%QuLTk_K_>EV_{F#8HQ<+J|TFXvPnE5J9?4qZG$Q^Eo~ zg^c733mOPTZ1PvxD;D0>Y0oxvTh~mNL#Pv=faiLG<4$geuNTXGYS^J6qPe%Hnt>8& zw4V5Q`o_=t48{(pp5#+Q6)YDT4L_FCpuR*1OQ0);=Wf?xC($rfO@cHYdI%YzNbrKz z8WRyJ3VHet$iTK>Bjkgo7*y|nG^nb-r>QqlZK z3&Q!@N5at%NG!TKUu*kENY$9w%yfyiv!4k(9?A3DUn0q$cyL6w#3(JDYYT~A@) zsi64a7}#p39nW0Db_NBmdJqO2F112@!Vl*8k*ClKHCG{F)YWy~z9@zZeA^b|gpgUX z{)2ga4&+rs2*RG~S%%f`4>be2D@YV`rA^r30Ww=UIi(nKk5j!Ohtg<;z-^n!Y8_5L zElnz!>8>f*z1z4asv=r15Yg7tpgxMBe43V+pjbUA->U)*wU;_go+cyfh&#a2sk zYpa|j*?=fV7l}{5EjNy2)LhlI`K{YMApi}aY=J`~Ad^Uml5zQCWrKT6w}1|?6;eD> zASo0r%u0YSFD)MiGn}KopIR7)rk@r{FKBlH9}W}cXPL;mLvT1_WHh`S0m-B9S*GgZ z);h~nG1=PihOID67Li}XgH9EVI6EsRnsmLjuw2z1sARsf4@6aT8~&Ory80zO;{#%q zjC-j3OLM-dTI)S;=f4`_z)?XY>@jJo9On8;JyceK4YGOG;3`9VtR%;jhqa-hFWUB- z>odNRx86X$xyA5!H`@wi-gr#I50oXd)dK}=W4Q)Gw>pG-taZwaSdj1a%+iHpeRk1n z#Tg;3(0Eg@GbB^OROoXu&%lv0dupDscMK_LBfIZrBWBW$>pI-kxM;_y07b#P`~v&_ z%C@a`({_t8T|~4NZD{j=h{gpw6r%OwnZ+VtW^ z53z6m3{LXf@<|*?boMD-C$-doy(1NgD0Bc)36*`qyj8ed%m(t%EsyuEd4kdV0Bo`um@d%P36`>JkqVdNF)+#*b{AcdRE*0L?C+x} z(B@)crEC@?mnv3WWMm28*6q*3h8}u5x5WU)Hn~g{rB38qXieW71HN=!OUYBh{wLDa zgOhdV8wqV6Nr-!ebO7h|%iYH5RtrwrbrE9>V5NBcEG+v->HtM96(*B|Yo-@9MzsWD zCsS%nPXJ&a-U%uxy_pHyp*)hoQjMVfREhAhQ+h#JI8v_JfGpe#73m&}9X_aRdwiJh z@ix6sU*DD&>n${#+Y=a5g0It~-P}}=bA^w;*>P=av^uGkjjlka+}N~X9NaZ1339Pk zi(gBfK<55LOBhl0iGWejAtr68qo2mo%nLN6jZk-Imbc|iUJ9CG6T zM*(-50LxF(;4w84<+H+%aKP<-eF9ERFb4;|@YQNv~NP-LMz6gF~l1o{%WSiqc&cGt0mRYA8* z4V;gC;ENVR5@yoWh)-3973X$dLN)d%Ct?%ye1;A~dJLxecngt6^96CEgf4NNB}9oM z6BLOfh#bi#hg1n#B1dC-5pv^FzT2XE@?Um#I%s9SC1mzGAm{ze(uzA8KwdEfBIU;% zaO5v5ZK^ja%Iw@qAe3_wQ_cLz&c@J0+36EDZ^Wk)@6ceJU>0w9 zL%W1-<)<|ntul+YFgf5DHMbs`s{RH5K2?L~<=MvU21>NOu<8;W7o-F0F0`-}6&IZz z-i-UECpcM0jukWuRy2!JVwj>Y!64hbj)ME0^JE?Al`2K2ABu77b7i6w!zM$Ig8Dl# zvDykyvtxn9iBVlc2Rs&w7@r=}L%_*eRh~>CJxQ~sCTULO@T!BTOd8qYOHTDpqRaIj z-bt)F+ltQ*=rO+_KB%iNU4F63iV$kg*WmEUpl3A`cea!#O=;joAL%7KVb zOUn#?cdTy_a>oNhNQw=41u&pSDHKWxvS)HX*g#2qGS}Fu$qH?!YJIqRZK%I%7Dt*2 zQ{0{n64!9G+V<_d*;B5vGu)8DfvJ2A2ow({m*r)(U(D!(5o51eYivr_zBndXyf+Jl zt^dky!xf-Md^L_)Fz`@W`2w6Fu7$03{=~US>7mpM%`G`MXxS5g4US#66R5fmnBG#{ zI5T^Wa)Xkv{+EYEH;0waT3K;b2Y^(K5Zhw+zdZ>;8*e}7!RzFzuu5V^hTV(GelaMV zF*wET^fofRq>C!&U>dK2g_ENV-XazEKPf`R@r${c%$9djvJSZwJQ*KR@$)4#nNRK+ z6EDua4T~2lmo^45&h1nNLMw>%!Tm#Op1e`4vALCAz@ddy!)w~E<1|H*3IH-hftbkT z#GyoKr!OADOtOyk=!VjWIrrcZ)~*Nvjl%U?Po@VCG$Q72;P}Di0VWiqDm{3(`wrVF zDU4qQ>nkvAt2W49fUhzo1#ogFJvk@Rr$_#LECSB>pcopL&nc206h};U-JqrkyF(Nv zJTOS4dY|zjx`+@B;HhT&9$e230n0T^swM580=*~zA+F3dL=+>mKCkM);>?*=d!K0~ zlRE4)G}>c{(#>e;2yi<$sH^CSZD5VIPl*#S^*oi-Qc6Kdrs&Ne)P*4pHVr*N-dsMD z@5lu(FjS;MQS(WO5)^B0C;%j_n^-=x&~E81^w)Q&_U#!xw5__?tb~}jjCD`p5Sa`D zs^}bC#&x+1U3d&zzHYcz4O@q{4Pgj^PF^*>p^R~yoIl*ebut07O1+WjxJzd2nABKG z6e%+jkXLi~^b%S%h@}8ix+4^aMZcW1QM~Fk(AQ2<% zIJ0_Eo%{f2L~_a(GTLp#Yh4wq)p2=Yx@Gs8p%Jz`G|rMIyOA;xd1i^Eo$`BOSHZJ` z7pbC<+h4w8HXVD+O;s#OWmT7#8of;bLkD&My@3)EQsi$WsQ(1)aCtof9PYbn`sE@MFy+!x;BOukz#k`L+$snv-TAm$yLh7JwF1Cl0nfV12u8WgGDx{9}^Mk39)5|KR3O**m z=hrAOXmQp~TGpMeRd(*V5~Wk#6TU)f?zFB**1ShOprbu=brdli-kg1V!zy&G5=nQWXbTMzzmt?qgm%Ki)d4}AuuKTHimJGvARFQi`D|RqHgzW+P>XaT;^k#jF2p=50 zW28LAqwVX^iW`sKrcO$wDUn*dCvex&VuC2KLG=~*&02;Eg-T2>j0~ovE+@y9HkZ~Z zQclU?;sF^$F@dn3D4?*yDYn3e0wbX!f&s}*J1ZNuK`-NiXB+V}jz)rtEzC(I27#Zy0+kSuFk_S0>lkPnBTSLId$MK5IaLKVns3na}@RN zsJUbiMb*eE7m$1BHteBTS=(znZI6$8kJ@-`sEm6Y0FFynuqL}Dla}DKdgKL8Y8BkS z@PN;JEvs`sQpx;lxK3LqEWMI~s@P=5@ERGW!DH~igyO$3^D$WY~?X!^eoFr6=|v^q{@U?6xh8AeQPaCN0kCk z=F8u6ypkGtc>xr6xp@}XSz}Js1}?xW_X5{Lb`+(CB!iN6H#|JT7e-s|KDAiH-7DoV zatJ9; zz}A!t1GBUKvo?5Yc2?4b!h!{@fObHyup__|PIWZ;vEwOh^xiE=-VkR-- zTosgwWY^9jtP>Ih!`i+{!N~WEh9wCmFh+UV(I6@Ts_?u7pSBbgFecYuUl&AVwh_x) zUpXn8X#hg8UO_S04Psrha4WxNg_5YAQ|NNNSVvgnXL$#1uO29iSj2&*)H}UdHNsj* zce6wYGFgJDMJX#kz)HBD7b9BXRLyp~)gH#>K{|DY)Y8|y?Qwf^aHs}NRHwECmp$M; zGt08gt9vvxmUFwBO6e8%SihV+uM-lm+o8K=QgdFh^YLx)(7G-Xu?OhXlSD9by(D7K zQzRm%8Bacmcwz`bn9iU9KAq2Edk5F)%r-|bA#nF(w}Uwz0_SGBGsT&`ryimkUSgP( zz2>9S2G8*2MNzzUeaKJf^Z&C1$h2?50WdclX7U|WFi@#Qaj8yCQc?ofGhJ}hb&68B z-mswr8(vcwh;3q&a$(^9!TQV~4WR~uThb1Q7=mXtcuJgocvxj1L=q_>O?vKJMd;jl zn6g*bH{XUqFL9tcda0tcrK&((19vpJON`e3Wv{#tey&IO!t8QILBW@I4og|Q67WsG zT{gP9q~PW|43hFkIl%%x=-M5AV?4+i`IDuH3kGMBj)%& zV4Ip|QLe7f0@W1bqBMmhD=T$e31i6w-?XfL$vPamkc=Z!pGBBfCD<7v#!w z8>W!Wc0CW4!cHyB$2H*?`>AG~ff9Q<#K}4%uBv|8l603AJr#N+O+C#pDPVDxGqkF$ zjFBXq2mY@B61s9T_{wytEC{fT(&;P-6?(53EVaRmF4R}7&3c6MVV$le@*YW8{hW6z zpQi#B>9i*C7^zIBW@ro%ty+^u zlWz|9N%ukVF+KBz^_g^MwzX6TvQTHLS+_H<+{}We>keGFDWFGU=J)GS<7)}}RRHqJ zgLd_fECNwgSQ-LI08x*sJe%D@i+ly}iTd27^(f2j@as0{GQ(4syELy zXIEtd?*vXW7vbcX*cUKzm%*84eWqRReYrwmNK)6ubXe#g2{TD!qU|*r>_pdzH#h__ z*ps`62r|eN5PS@0=X=rGg-#$o!;&au8FuYk&Vn?7xJQX-mac;eIF7Z?!W{HLegYx6 zz+>?G9eeJrdH`X#;y7K$4$oX`X?Vvr$niJdbo16HA-J+v0DpO94$)kBCj}sAhQfEm zOLO5%)oFn{a&e!p!`I@a7~fnCp+*o`Z^x?rz|DEQ#;`;b2wX9n#MaM@9>w7X!pO^Z z=l-1!Ko#nJ%=?7!AY!Om%#o8aWE}_)Fi6molRZ8+c@n!6ivXwWpgB2EL1jQb7r2Sx zWvXPLSjAXC0=***1(Hj0B^GOC(p1R9j!K~%HNBlr>oB0POhobJYx<&`vI3tcxa+FZ zwVRE*GpEEJL$=AZu>HJSc*^WZCe9&k2mTi3^Ika$jh>1%;LpLCU!z>u6Y3KZp+7rW71O&JD8&pu!y(P(^MA zusKNQ32~FWrNf5QgEj0#VSw^vR@^C1rkxQm!EQc>iBnR!Kd~&eP7)btitM93+?t;U zd<-Kt++~c47a(wg#LdIHy@p7tkH;zGj>jNJPgw$#p`H7LP;dg|FDigMEiVFn98oa@ zar8Fs4ZcW+A`Z7~@sJdw$>M;)GBlVMy{B0@BM>ayn$TTsF9%pgu#R&nunUY$&!d2| zajRftr1qTaZa6-D;FcS%dkzMNVHfm`4Lg$@%sVx}xRV2jG>Dsp-jJF{5T6kCP#&#L z3i6zLZY;({S!vc;M#%c){(JY6{2YLQfSW?C#W&RUH*s327RUNdSM7!o6eZ*vr-7(I zYdg#!wg&9Ubh_8SRwAVKXv8M&%G;#xs?MRF8_l6Pn70$u%itD~zb~Ioqjqs4= zhLPKAfCjYmap`)GrJak@fv;9gSi*(5C`UeXaQ&r>-3_$~?32fBN#VdmJs}J6ygLIg zBkhBrB$Msdx$^>IQtED-GCD10I(2v=S)9YVIGH?h5B_37lF~SKqnO0$)jvZ@wx|_Zi(?hMD>88If+afd3%jU zI1952a^ZnZ7WfSTbrt{62bT}hWf2P4fjuh~fCSrR@;U0`fcR>AwmGeKl>3h#JT%>y zJa%;a_}KJRWBlMTrMfPDN7NIJlti}%daGEFFUpft<(b}B?6+h3MiR^xj4!S+BO0fG zRguJOz0f7EEF22TbJUrZTdhth%+O3pM2PiCzRn@wUf&CrTW6O!G&Tlu@Nn>$t{hfSf=p*pVm}xkL1}AxH~$G`@G5e|&v?Xlt|^3kn2>S=gPI;lq&{?7WHt zOw}Lbq-`hcwvzV+^+d;bF&dAt53SICY2e_<)cFqhG2FR`)@tN{?*Vj1L}wl40@(os zI5BW-d24aC>$gH$s2ESll`ED>uydgk*(pUWA(nG6;?@Wy!GsZ*bBs)8BGEFc7nn*} zKq}1sD%9ijU*}XGgh}N-;3b8s{?mINsNHLF8`|^{rIJ>sgf$}DE<_sgK~BjBN<`L4 zT>D-vvsNW6)f2#)r#AT$l7kWnY7TPo47!Z^{5j}2Pc?JNAqYWvDS6{^F-1h*Q85KN zJk#L_#_*tsqZC%rDf@S>XA0D!vY4`OxRFm#WLdO=l_ z#qEm-q5}rGx5(Urp!!9w7fpxkAu0y_3D>SiajO16t3BR?ZRvR$GSRUlC@8Oqz^NO+ zafg8~lEQ}2_X(BS^Umj^Qo@AZ0{oq{fUXn{BqlAX2sZ^6p^aubHs?#CT*lQCgEA~( zDFD{CV=H$EBsho$XO!aflp&M}R5C`uG@$&XYQ=oPb8%+GTK?vrDX zj$N1+0;n9t^A18M71U7@Dv-)oF9|$+*%ITnVspq^XIt{GVuJ*)T-53hCSajaOotQO z@4(1olZArTmsbD=MBf(VTGEq*DHw+ZUPv72KH02&n26(|A}@U|NioHwft&MmgE0=Y zl=+a|TMBFbh_N6(5%mW5%E*HSpu37Lvan$m95hfnZiGkkOGY=H225aF*pWUb;cBcm zEyvX>=T)2_Ew|qqHzm}OHqgc~lKB{7o$GC^*1 z)nd=bpisouDuw*(syl77%_yfRijPLm0u7_28+aCG1!QO5UT-T}xyAmv;k%9=p4d8a za$z~#6D~w8$s6riS7k<-zFFPTU384$igHJVrLnYw%RtP<#mP!?n4~;{IUiBXc)nR# zL2D3ZH|BUWT?;%hDc#qDreX@~Wh*+DsY?VH#YA*Bp%+FR&<3U3y~!{58P}ebl-J@? zqKjG~H0-$L!2X+WzIFG3iCgyUyz$2Iu^qccN5^*DtaL){W>p!DHUKIYv>ia4AO=|J z>mZmr$0zpRy6cu(cieLG?%m_#x9k9Unz(groRzIbM!gTjP8$+TjCc&W_m7q3$%Vy* z?)hAG?$-A8UC#W_c&sm`aJ46nBtit8ScY!HJd#DKvL)zul?ghj56FO;i3)`VtmqJo zFSH#QrN)%@;(QzaMu@wagJ!uyML^+YkUp9-8*V0u$s${Y)r=f~|ry zJ1Z$G=wmsNvIwo!I2^g~s|V`9Djou9j3gH!f|NYM{E-@3kf$KeM5ClsYdvtNkP=XM z;8HShVSyA$0id*oLwS3gMprL806Dg{G?#kM%rKzHdePeiX(4It#ns7rS9M{{AmEY7 zZL(%1oeL8_ZA(7yxyCgr2-O7eBhWyFc!2~Gvglm)2x7LE&1G6{=@L z817KIlXMyo!1GJDUXb!)DjzcCP0vSOq@Bm516gB59WY61GCNr_L>7Cb(7ar=9?yQP zJwpogI*u7K?vx_syX11AXhc~N=`7Dm*_br+#6IWW`ljWDTJT#n#|@{)fdy37_IT)l()(zpEiB`D3(8T({%<#y zz$E^ggNG4PW+S4Y$KWdQwX?5#GJB~VPCS$CxVjnXoQ_%}u{te@ZMF{3(Fd}DXhnF6 zGvDy&b(>fn!O12N7l**%grB{P`430OXX;?DMLo@7d{NKeMdbjjmft=~QhIn8ai2`Lb`kPM| z)m!AL(&8T%f6a9wz=I1ITjQ>gVnoqBpH9WrJf5jk6bJk1_AwlRAfBYLPz7tX?(}4= zd3T>|wrVZuHK@b^Be`X?xqGI)Fte=7q{>BfoFGM(YJgX}sgW5Va&AzfB#M8X{-D92 z?J*^mECoTOfJAWvbNs2+%Jcko#FAAzW421sDl%#Z$CkNd;VVCc;1-v4+NP8+=Zh?j z)p;g&kW$H+35n8Y;RfV;RBB+NUS#i;&dE+%#%*sk5 zS!`qq%V;z!2>rcdGRvWW%+>M@Ef6E?B-iX+RicGlW}OctuOI^&^Nq0HAdjqOWTsu@ zM6}{k(Wt6fIqZePx_z(|y>&p^QZ^pmV@)@?GyToG!9@wWEgOh#8ZI4o*!s z4jeo*5&9GtqK>`Ly<-2cY@^Pe;HP+xyJo^h0zQXERy*wx87fNIuvm%q3K&1=I}FJt z0n+7%)6!CK9F4K=$fQt*#y+G|u^M&!3D9Widr>5`l;X)Dk>=T1X541 z2A2J$BcIxK8saOS>E;SX5GZs6RPFAGhEUJZvFYQZhv-O$o@VrDJAxo((cfD%uS9vL4!Hs091tFiy!G)oI9)yYgLOQXJi!0fig*4buzc&jMM7FOuCW^F1vHU0vcB%&pn zqb1s0K?X6E=!4aHR&_rVW&$}wpM26^cAeB*#w$HHj%gLqNF7#XAQwr=^URN*m|r(M zb>Cq^Y-=Fnw~JuhyTi4ilsQaK9G-OEfXfH>e@j}N59`KQ_}J0O`x=vXjZRGfH;)~h z1bidOV2u$WyBKR68a;C7@zFb3fFd`_IJLZb>#bp64dJw9M_Lo-W}A9(Y=0JF3~Azs zF!Qm=$;QOJV-u6q))gd}NT%>gj!jP=>|Z=N6nhYrFPTaZK=T`z{is$%5E-#OgJR%A zVw?ip&3^J2bQu1lN0;Zo!Qd=<)!e7|9{9LbkY5^rY6GY+eelR}vVr?1rUGOuI(~7` z1v&u|>jf|G{asr4_9ji#@{W4w6l2zs9SQlP7|X*4zfDEQLlbvT976X}LXx0Ps9>cD zM@tu7!|oh>aGu(a<%N5(FyA8X}z2$*nZ`(iLQoPW8fjQjvYNb34zJv*T!8F zqvI143FDDpyA+~M$g0w$3|4-pRVp#$lYJ$eT4e{|v<#=1psp9ZMDrk)j7>~U9X-|< zhkSkHpiIaiy&iatW`PLqKYC~iJv(^!==20IZhGR_5p*pgI?0e%TzS7n71PHiMyDJ1 zj2@!^JJlGSYD^qEcJvr2Mhw5aw>>3cmeCm9fAsit=1){*xn3^}xdsF>DzrQ1anUs_GGOsY1`7@(?6DL^7U=sK3~G))$;D}jRF z4h(y);trS4c^h;??A|emuel;s?3)wQ!wruLS{-(j_j6-ugBH>xs*u8TV$?CX!A#nM zf_@_ysZ?~Lpn6R@Npct&-S)*F^aksRNH5IY5acK+g%#02L>2qkNMU&;^EZ@;hMUXS zq+JI)cQ14nPQvwXegdXP(j&V6?YjJ`%JYdpe=Vi$WgVs`&@R)*Ej7*5jm{@;fFiw9 z6_7BJJRqqv6R?iV5T4W#!sz65B0-Y!3}xCO?L>i09DrdZRY08b@I2v^e&|HEjhLe+ z#hekiwh>EUn^;2+S(WScG?_c};Z|93_g(}USott6_I_pegs4<$W2sV)ZYAdFb95&n z#B%Q2wctbgc5jbMHL9g_P{d&&cdQ9 zc;X4vL>nGH>q_s$uaVZKPLS9Et6i0<+{qK7#FC@(d=Iiz0=LPmAvhT*7F=ddl|xZd z9f=A8!WjGv3$c(RFd^Yj;E<4m1oJ`biOxp(p2DTS1g_5rM$JliRDu` zX9EX;^fiie6#NCkTX(B7nxnF|XzZkN-w}_j&rY>hBxN|XC3~!%@P02zOohWe6P`(= zF#jO41&j=kQlDC+f|oIZZn2W$KzJ;#9jmAfnn8eyAJz$}nh1q;kT_&@s1RCqu+u8F z;`DZTwm`>Es;5Ei8TYE`A`UiYG2*iR5udrJCbTtn+T5WK zAHm);RIe~Fi1VwuBV?-$MFyF+dAIoqZ(GX`%EqSRf4mY=^l&v@(yQQ$<$fl5K-U8{ z>hYK*nW9mXqRrPBM*&b`Lu8a3l91JDPmqH$R2nP_YI+Da%rw>zW$>}$tQ9j}AB-e} zArd{COCo@bLujOtl1)BB<$`7_fMhXSGJ?XjGYFK-lBS<@rOA%VdR&-EH&^^UFunJ|e5U8C*$5CYzNa)ys z2E=JAm40ez=oT7)+jUj|96trmD)Puq2f}2#8#F9Y>`L|0%tsWXO1!O z)uA;+&ZCf&K8N5g5eu?G*N(&+>;>O~;S{cQEgmGD+A`C1Y!#6WP})Cfy4sZGZf0~$ zY>r9_4xaSE#*T^l;lW_6&NIe$2>pKQ<-=-cTykig!0k_{W_&na^$7R{xd;G=* z4ZtGIa-uzw*YEsudZx1^t{a%P=yi{T^488rS+fBPt9TlaZWv8)R_jiAm@Hox5m4$x ziNXFQv@|b+ivJ;zrZ53R!9zneajOuAg=nb!M;NaQZh(U~XK}75e4se;x(FcQ-?zb> z9(Qs@MWEytsZ>mzsjh_>9bhaMDzenIp%m`8fW9ohOGj}M=s^kI7mIouk0MWWt%l(S zB`mZn7LYxo+)vB~(zu58&?9fDoOHYhp;8h6UX;6yW_x;6%@T&w+>fVLUBj5SYE}!0PCX~X zk}ST83&SMO zZZO6W6D-WGRC0{aB}jFgq8U49Pru8bF18^y$W`rdLYrkzTM2FMRW&f9P{I6ghWN6S&%o&#SRijQf1 zYmXFHZE^3OcwF!rLKni1GAif{S6t=vrryd9h^Bhnn8OGtIShiVBdiJ>{&{*#*AHVSXicv;xsH!*>IM?V^ru1i!s=~5jG(<7be8! z0oMYpLaT3-k!(Tn02iq*&UJEe+Qjq;z^S-jq!KnY4_I9LLN4drG$bPrcl>JHN&b7I+yl)W+7 z4%WK>#8+m!`QlZO9tbFa4zLzj6B5ohXW-YoSr7hl`twZB=h}&Q3&7*RTK%U^ffTqH zW9N+mrwAF8r#enGY`7crsxqw8g)~8sD*o0{(LvQ@xU>{%y_OKbJfpyJ1jQ{c%r`q- znP;xyJQMM5D?>PUk3z&cdi#bHb%T9@!1cbi2r(0A0t z{t>pU_Ybn+uqPri%b9(CiztP>&|OnDR$11@!CD!~x0Ji`@{Ak|KH#zr4f^JXBPy}2 zM(e`Eqc50f+&yt@3bw65XR_1LIVw#|%)l;lX-6hgrQ2J(}DZ{v5EmT{>Py@^e~agBGqM6G*ec8euTA zDkpeB=xvyca5_5+uYRgW(tASPDwte(2o>6WpREV6%hZ;`Lq@>VP)V;n!)15@u!`EO zy7iz|%Z$8`)T$M{LlDar(pfHBD5qSdi*X!|&s-2{555QWy%RxyFv>Jp_9?3$KR0dOyaoR*v458q{#~}lzsn!zzbl^Pe*zBs^THQT zzi{%!i#wmbcY5(9^6!N&eBtTAM;>|PvB##TpMLV>%bt;a>tvqe;g{6~o(_MG-z9it z3;{O<&A^qHUP1`_zs;LBF@ya3sEvnz_k2HWF{L+)dX`1TZ{o=KHCeU?Z$2|`(MtK7 z?Ys(D^Ynm02=IST&$6fg%%#~g@O(Xzl8`|?fMqhGfv zt0B(^er{8C#jkD3z6Q^;@O(3#9e8fTGmhs7o_q0}#IuO!44#Mad>5YA;`#S@ege+t*to;Tuo8=iOK`LB3Bgy(;Q2hB%iaTc;rRwU*Wsz-xdqRDJcsby zjpv1UUWBKM=bzwt1)hJ6=k<7g49}bJ`~seL;rUHGAI9@Xcs_yWukmERz9}2P^9(%C z#xsm(7oNR%4&a%@^KE$M@GRpwhv%huUWw=X@ca;-|AgnQc>W8X_u%;;o=5R~49}nH@$pw_JW_^oW0{6o3mf| z)y>&mzrH#9#^2hUz2(u(+3P>CIs2n8Y|g%VU`zHJ*KEo5Z{3oe#q(e5Te9cgwk6wg z$Cm6rK5t9*kG^$Fc6fSA_J(`6WPi7?C3{A9OLo(cBM zw_lol=3iZ!eb>LeG+X$0mu7$d2F2m;dLPCN&+GC0D4v1e*pxMnWZ75a{Xg)o;r(BZ zX4w$lw}2LG$NLey_u&0kc<;sg(6?sULA>9L_c4a!eGlH>aV*PD;{9>FPvL#nRF*B_ z{j+#?@c!_0mc0b;oyW86pW*!~yuS1fD;^^S5}i_ixHB#d8fF{(C*%jSC8o-+W1y{RqB4jrV`T`%fOq zvY)~G{C8y8FEZUr6<#mJ``!5d|L|r%KZN%O@%_AimSrEo`^_)Ye!u3QXW1X)`>S4_ zWq*P9&3G68z32m*vKF2*c-X!Rc*p;q`CibAyRz(${u}7cUuW5$;r;P*m>YOc|5}#) zFTBUD!F~HX1`B0X9 zH|l)_zQ2I)_V0jC{Pw2oIll`!jQ0$}zXtC;2p$`GSiA=BLkNEz z-v1uY8}R%%o}a|?(|F#D=dE~t4$nLByc^H^@$lb!erHp*@QEyYAKq`p`vZ7?67S!^ z`b_!J`b_(_c2a?pE zo)tXj@w^nzzrgb^@q9O)*Wmd#czyuS590YzJU@=-C-M9Yp10xoc|4Ecc?X_%;dvjP z58(L-oAA@jij~ozKk6|1iEE#q$`RKg09C@G!0a zyW(jmw@cz-S4{_pqk{f*}#7vMei?Pw$3 z|L_9ZiT9`Q{v6)7z65j$@5k_F|9|r#@bo{zy!t1bvMcfaJG}iL=i}cXY||fum*F8@ zBhBNyW!P8a`FcFh#>0Pq0{ZcTNKbn73DDyIgx~)e&(GrdMLfTZ=iPXI1J8fM^Lu#y z0MBE1{uIw=@WlW2ehhf@NFH`4zOQ-{#tHA2<9#>Y55EPx0Pi2gyNUPlH$x`G`=fZD z#rqrI3b^6@g|~r*;{DZlzZUQJ;QjCMe(ldcj0~0&qJ=m z`%QTN7T%xzg}gldu;4i;LszngKW=KLFKqH~I0Mc6H(h&X z4`1@?=i{pNIh3_}vH=qgWX&G_Xr3|4+K0aO`8fHwU#^)RYptB02zS9BKXxd4b=IDY z65QGB9>&gure@@{MCz@Rh#b>jjJa20PzDP<0QJ3IIyQ;j3`U>$>gPA^#E!(wVwayU z1T2nBjn2){VDjj^df#HioJ5SZv1ijfDu-}b*1;v*L3NY%n22jpT@7os9$a0~b{t&JW6w$K@nsg3hrR@%jRwZ0)n>5| zZ<6mNTyzERsnWogX;4Sh!SfteCVYj3hM}H^0UIM;=@D(%mU-$|hd{bX_0ZQwp)2P- z^mQ8AZHZ?a7WsM)!NqYv1BCpLgb0E_mkSq4G8Au+(8bpBsTVB)pR)E(NC5VC?E8)U zo|$cR82Kjoz*SWIc&mJLXXNAU{;`WukML`@sl9ure4NIXHKX1oU%1Vy4FEFWJsJSF z%h$mL*S))T?AXoV_gQeKnFPN-1f#qp=0g&r?fkI)7UX-BA9D-y^W2nT(H~_%^W1^} z;4%G>zJHv*=VupN9ZB~I`E0i4ndwvd;e-BJ`J7)|?MNM;lTYki3Yb1GUyCinkIgJ~ zsWr!9UM3&QIJ!T3I%)nZB%+0jN|NALO0eP)^S@fZSG%+PdaZwTl1#6YV9X+^^7Zy5 zeflB$C{^?Zi#VrPAYUC^2O*t*qkcANlH^bo_G?-kKB0 zeV!i#HqrIq5xAPWX-|^+;Vnq85^(Ni@>v?4S7`8Aw(6DgdsR{G)%eu7^h2eOkZ@o%({GbdN2i*J%|qY3s~ zCdJ$3!yEUAe8E?MgMp>LQv>0POo@YkDumzTpDjhT_xZOD&-?wevm!L;L-s9{IRWyA zEk;N{67#6Vz?_rq`KWy^&uSHq+4suHwxIsU?b{pt3Ht^oV)jqjXSX$%)biO7zAAI( zbMh^IB$9NWXSh++hcD6J0?L=khtaQB$j8zOx5-)SEBU>;Y;!H!+{ms5t8I6)AH>SE zk)4ORP4x@rT+h8pICpB8EkX90>$A;Er$JVmv$!|3LEB&Oogdf)BZrn8 z?9Bev^_wB@ZOPvCtStKnqm31iPPOvOeiTjqiOq)^+1sB+%x`3$_^KB)vY&qXosH}x z&lqoHFMsCoM)ujSJJ86!_v^>%Io8k>T_{`_pfn zXk>r+jZ=;6N1lCGBYX7O(~a!&-*k5)dspq-8rcV*Gl{8~{oZw35S?XTbxtP0-*4_@ zFWoZJU4hlaZ1#~Yr?NlT($0SOl7;LGm#k#pe`z=S&db2nfA5Of>|b2j%zpFAxm952 z$FE$>K6xeDPsI6-r=6$4PWFyxZpnTHC2wwav+vmgRA236Z@ePAd@=jgE#2&0mk1S_ z&)#;$>WWzYWbeFUKKs=xmYPUPLzC=v1E(R0WIy!`6mh1xnEmz^(!K1n|6oh@x^DvL ze)5~N@ITu!oBi>X*_GYw&6ni4UxU(KcZF5*=1|EmULl3PS69a?68`wwJB zXAeI!+YF$*;}U7WXRu-L4pxGo4{Ff+5%ieUoBh!xGiS4ZH;`=+!2Rtd*eRcFX8-YN zomEhdN55`M_Tx1Suv|Zoz4p>h_G6dfF0XF(8vytx5wn@h@+U4uj~27<9LTOblYRQq zJK3wzZSvm}o&;>lh$ps1Ps+Q7X1`usq) znO0QU%P#Yv|BV*^>~l~bu20Xt_p(;@(aX?<=WG%J_rv)8+Civ^XWcM6`@m&Z*6&=l z3M`t#U}V34+4AbrNi^zvpSC4?`ygQd82|k6wNPk!E8lW?UdG!m4_SZ78~!Voo9CSD z-Ip&~6)%69_x4{t&1!fxYIyIpDEvFF!=E?u&!hbFf38CpAVU5A<=T>uUcM#!-1Uff z)i>kMPw~(DzL`l*od%*=yT9`atLR-5KR3fK=jgKMEnW= ze42k=wH1F}egpoz?*>c!Ax->VB>v6kBJ6DT*cIox*{@%jZ3z{=^hz71pMDzftJ}=J z@7Y_j_iw{~h`9I9-f`uM4EW0iIP9;1;S3Tfw*U5kI5na;oW12~Ds>_APj5#X-do3? z?;Am-B60nXD_^{diSUB})kj7U^BMkm*G@#YAmn`EN*=sA4aE7kNbs+BA?|Z5W%iK)n2n*(H#`k6%pMuYei{Az-CL0Gzuk&IzjYh_ zy!v+h`D^}p^IlZ8kp1yM_HiWp{9Xh-atHo=o`3#eAO5`NdHC~o{`oBbeD3-9^XH@Z z^CSE5=Xd$%d&cnRPx$B8$MNU;C-CR54&cw5?u3GTCi{V_z*FIT45I0quYv`C_O`3w zxM?o?z*VcuIIxoa-Bp+b4`02Kz3pnGno}@7cJ-<3Pp_WMUUdzOlMw%7*XYvZC$GUI ze$zF)VMt*3178JTVxDo?^2V#?=Capb4T^FXYJcgspl>>Q@4G6eCojX!;V&U-3mb*0 z@QJGow?2K9u%5rZYD@O_FF^iZI)p!OKY~9W#D?4E`Ru!|K7}Jl$ntI!@f*`9Lh0R` zul9NH+h9>-GTBGah__+eZ8MIPSUvB*8iWE%6s(l9KS1;^-;0tz&ObkSAO8Ff|GfO$ z*yPod*%z*EcG+YxnasWu_5Jn<#DDA`|@{X|F`!Z;B^#d|Mtq*Bq4-idNH=aKq$7sbofKu zFvUi8FfAnEa3mec!jg_SlCVVyC8maMdW(V3n<=IfOz#kSPfQ6NULb^!1j6^bXP)Pr z(ZR%d|JQ{-eb*OV-u1nE?wy^T-JPA?ot@F9HR@cCdFDw==G(fn)0Xsech-`2?mo1n zZ_v|A#yU^gt4osN+3QPog^c8F1$kMMR`nsHYo};5vsnq^LEY;?Jzfs#1ugPXv&6Ia z(dhiC8oj{i@)nH_ZPjRYn?|3vkr(Nk_w2HzLTh5#CCfG!vkz9LU9jxBc#G zU{&1|y)nSj`?=NPQSaPO&i0p!8RAhK-nUGT*v2@6(#%HH3(>J^H z0zLcHm9QmWrz_b7OBb6P=~6X2N54IFVfZb(Zt2eKC|&G2vpbezQcO}ABA?Cgv6I6k}c5*99Ie_Oheeauh<8VaLEXGiwuZaKTFf7WMu zc2fT_+3EfJW=CGZayNwW`(ga$m4wlm-PT_jr)minnmV#$w1!u%#ysH~{i-5C{giB; zBA`^sURtK8YKhacd0J6tF`Q?g_773~LMxc31^Q;k=&5_(?CCH*S5MgcW^ae_Z?1#y z(6jWu+37qX?@N_0tuwoO868)^gUjdy$sS*3=keJyipFn$kNZ^^KYb_sVHn?hKl~ZB z2l^13&zI3%QlTOHQp?PJg5OTmo5H@?Z5k_yO6}5I8#%Jd*+c&(7?VHVb4(akR z{@@Gvynod6;Q>bW;Ij2aH4c_NF8Q*5@Y9?yo~v=TXnl6hav=k0?P$vWupEy&LU!`p za>bI0dvW5G1)A4_V99j zv#b8ey5}9)N8`hfVtm!njDP(b#z&pN__-4qpK}u9|2diQJu?|!bG8baiz=fJD^M9N zyJh)OcHi>)Xl`0OpTAr_T$2u4p*=fg1zo?2)3VoB=$jpS4vQatt`_f82<52kwdM2E zw3#ZzcB=ljl6v+ES)VaGWFIddL;8IAzS-kiKymslcJl8=FO@rAIjgqAEblfRtY-fre!y;sOw%R_JyL*TPrqZAFLQ} zJ?~p7>pRAaS@Tw8dyCoiD}{n;cFRf={HHrtQmpT0y=UA*eARwO_VtRo7De-_m9j-# zJ$t1X%J~+`C0g_YEu% zVw|s8Z~uX?PkoZ{>?ixw#8}VKFVARR*c^7#<14G(ji&nS8U1kcpOBwR-F@E@c z#vg?7GpcDrG*4Vb+2%E?bQY)Te&GI9TCx{c377GsRwWM%9XDl{tBFBIq%zHR^b@iE~!#n_c)uUuj>y z#rVi~7{Brni>Pp+CVR8%SL3X>MdC&O!|ZqfJ-iy%^z09seZeOzbNZ)@Kl@BdKkeli z11UY8I*@f`mk*>s`RKqHqK?#jclO>uU3@yT69!JpJ|3uy`DRssT7)2fH?S?6Jutgp zGyiy7KZW`6?fR)tS8I0bz-+GO{_bw({ws{Xx)(m?{(gN_*2w-ikO1D4^U34PzxxTs z$NhovQ(^qhldMKj>uk-=RAqmaA+H-mPRzO9kzJ(w^SW*_!;1%HR}Si%z5E`_-ts=< z55xF{58#hJQaFq1?Em{9_0$}T)iVbdvNH#3OJmvLhQX{R+%VocSP$j6;@&@4dm`Sb z95+~TrEE8Mu#WMs2=t1>7S)DQ+~zuW_2BrFAbV881v3_v@Xq0k?>w6ETfbp^$Z=u* zOfA??#m$!N(AD)s)eie3R}UL_-0EC8I#kjrWHZ&gf=-AtSMQr$c?XMr7RFcq9)32A zue(!$eZM|?es%WX=c_k&WT&jrn%xtggmmbUv@ZA;4hdiIW|!$Hh&Jn*AzfWMtmh0- zrp^`;Afgf=f8>i2PvZL0pFAlQf*U(Du=GS@m=+{Ly-MCIW;Xi7uLMvsDr`HIN9?u<;^;KN-Jm-@&+Oof`Vb5=VGo(Rf zrR;Q0s)txcWs2SeZ20g>pk@WtMctrhH`O=qRetq`OA^T;AYWl=`mzRA?7@rZw z=Y;XBFh227ex3IO<3Bu2hUw^0y#8ldSpNloP~tn|kCvl{XTgWv-!1W-@%3;fyWD)( z{bds08K37kH=7T;zii?=?7kkX1SUSt_>agL zZ$7M9AwHWXzB7K!>RGm@`LO$XNK+2q8Gn5_Q_Y9n_cSCv&iKEObAb7<`@(Yg&iKF5 zgo@`OePH+ZPkd+mFXWtIKJ5PTiSLZR#2Q(4k@>LuI<(92amF7iXO8*sg8T_`R1OXC zhuv4y%HcZ`ew&=<&4=AzCGnl{kCyY1`LO$bOx9|KGyYX_{$)PwzN#yixIkE+!SXZ#6r8q9~?KP(B~8UJxPstO;%hZp2eS}V&AH6M20 z<4k;<3IA$2l>NCL!S0`%#K#$bydK}4XFlxy_{4X{KTXax=ELrfO?+qkm*m`HKJ5OA ziSLa6shoSwhuv2-=)kp_;f#Opk5$jueAxZk#COK;zmDo5n-9D1$2{RX<2T8fXFlw{ zrwP6@{&jLbFdugR@FYIY_?s!S);&nrU$FZJC%!ZOjb!e9qYt~UT^*SCIOD$}=lkZv z?$1noXZ+%NS*Bal5Fgn6Z4=)a{{}fj%!l2-F!7!7ch|*lQ}bc>^|?XdTFr3Ae_GBM z^Wg>g6NhHmMDt;~yqR_tqibhTT^d6`1%q z<6k4^b@O5OYZKoY|0_A~nh(1_GVz`9x7JO?KRo_o_s1o^GybpT{P24*{;>NVX02v8 zDzh=Rh#NGk)VwbRTCvjDvr&2KSxuzmW5y`LO#3C%!ZOw2>+|nh(3*nfT85 z@5}k8`LO$b4Ag3dGk(`7wNLQ~3623G3LvofeA9i1#>jWlzXZ(Y-vj>|G zyRRZ!*>}djOwI=8!|snwd}sU*<%}{PUXZ_`7M^52?0#JmzBA#^l#??bcK_#z?~MPE zoRayl`<}b}ITx7^yT5bdJL9jb z%=c#VVfS}Wd}sVa0?~K2}c3Jka`LO$1G;pnEIOFdp=Y8{G_fJiH=lNah zztpk~a{2q-58}0cUh<5W?}snZeC~_kIpP^nFR$wa{lcH{yGm54%4# z@tyJcw!GPV*!^`9-x+^bIo;;N?)&jss~OJt$IAJ&`LO$b{NOv|^X>b|=ELrvn8e2! zpKsyMHy?Ii*>GUOcg9~#1)ZzShuz;b@tyH=a&9socHi@J!gt1}4T5{khuxo-gzt<` zTLmwg54*pA;ydHhromh0!|ro@!^FoKpSBM^H6M0g#g?+~j87X0Uz-oR@A(7aJLA)q z!jFC!&llMJLK40+K5Z@xG9Pw-Y~nkI_{bShG_U%623D&ZBZO# zKJ5N46Wv{_+3?7qjD_&DR!w#Dh@!|q>~gzt<`8yKnz8S-A({SOk~8K1T?t}`EY z|MtXp#-~k<`^<-*5p%rr=gZ~=aIHqpEK55a@7l634r#ly0LFL5r@f9Z%!hICchca# zGd}HlEV6jqcG&&p1@1fJ)BeX&=ELqEm4xq%{}(v}%!l3g{adRU&iIowv99^B`_q!} zo$()#vx)hz``Yb+3EvriRXvOzWj^fwmI4^x8DBN%vq|Q|IHc$I1Telc{xA2|ac@41 zga42Q_u*zaYiU1a*Z0dhjh7N1VmwcLjPalw`emoW{j#k6s(vAy`IRv)l+&Of`MW~Q z^MtgF@#DPmf*-|w4eu2B{r%JLRlsKJ5MqiSLa6oSe1Hhuznvl*4z%-&{L(xcRXAQxe}9f0mrB&4=B8JMo?I zkJJTkd-GxUhbF!={ta?=Gaq(;v&47Ce_u|6`LO#ZCB8HMfsMLX623G3+j9Dw54-$Gem z^I`WdNPK7f6BnzxlBHD<{4){)cjoG9PyT$;5ZY|9!ij510?Tzki=fe4Oz&?@*p) zKJ31lqX}HA|DEw~=v2AQeAxZDNqn5~JG*pGWIpWvgd{%B_;aV}p2&RI{Ye6t_&DP) z)vadB%!hHqf_BTU(tNIu@a^Im3Y$M)*Cxiq&6&8-mfHqP$7Nynivk$m8J{-a zwlp8cA#K-4!gt1}ZMbpf!|s2U_|EvWA-A*nu=~_JhKY|eK5fnIWj?G~AwF*<;XC8g zCf!u?VfQ`Ggzt=hn4AO5hut5Qgzt<`8+XT=54*2ffeGIkpSJMMHXn9>YT`TN(`Mc! z=ELrn1Tf({0C|XnKJ5O`#COJjNzTjW!|v~r_|Evlj@PxueAs<8!5g?%Go10~&D4Fq`LO$ICgD5d z_d7+$|FUua!tVPyLio=3SIOybKJ5N;N%+qAzdluEKl5St_fC9g{5Rx`FdugRA^}W% zobiu3UB|2WFb?_K;~Ly|#^3D>g<(GI{|+&V1PYEfe1v|2aAPnh(2wX5u^J z7d3I9`LO%DB)&8LJ#vmQA9kO5WN@uU&iL1ytLJa#!|v~#gzr4Rvd2YQ*7KGt#MOCA z&3U@MFBgv=cn@)P-omuU&6&6zF8?807WTO9koeB{kIQ++eAsM zkDMm+VfU{~d}sVsFVeNfeAxY8CB8HMS#pjxA9jCs;ydH-c(Lw-%!l1SA@QB@UzBsM z`LO$ECB8F$$0fSfm=C*ONPK7f7vx-PKJ5O3eIwUuhBN-GEA?E$eAxZ7lklDAcP>Ay zWgF!3_msH$T;A#`; z_jgHrXZ)?MR@rVvi<{W}ulrQu<2=7@@2_Qj+gBD>Z~KYmiXhaVDGZ~I*^%Qn-9DHm&A9*A8@^{LFU8mZLh-4ov#zyBOvx6Fs#Z%ce<{6pm2 zWj^fwp^5K2zhmPuE$hd|(_)T|*OK}GeQ(q|wUy)kg%1-~9~*Zh>vAS;cgg>YEem_x z9!Pv={G)DCzQ0Ob7wrDliSLYmpPZ%4huvR4@tyHMk+Y)tu>1QZzB7K)&8oL*KJ5Om z#COI&RnCUy!|rQV;9AXa#-A-`jQOzpLlWN^{~0;8=ELq!O?+qkpWLG71Lni-5A9cp zk28MD?{$qgA9kN6oZ(uHobhkIQ}u?;hjEDS&PjZn@fVw`XXEC>?!TV+&iEh5Io5pG z{dX3r#K#%`nR}HVnGd@^EeYQlfBbzaPn!?Be{kYE<3B8Cw)wF8t0%tm{LZyIwQPf2 z{vHrl=ffW;%!XCt@eg;1XGFcct|^*ky|o&_Z^_}_d7kcEQ~Wm!#*0^cg7#~pzevxhuuFZ@tyJSlrz+P z*!_&YBOq|KmQ9Yc<0epMDxnF&}o{_YuA`KK($PYd-A$mPve^@#zoZ67ymAXC}Tg zKK)5tYd-A$k%{k&pFNpnx0(;TKRNN8@h8infx02a?(6axmaWwcXMFm#c+`B@eNPj7 zXMFm{c;0+?K|cL+ykEC3K`LO%L6W=+6FJ~POKk@&X z_|EvJJgfJ8=EENTZi(-VPyZ|1m=C+ZW8ypG)9=dm=ELr9llac~^xrbkeAxYK65ko0 zeqMGrA9nxD#COKORZgAxu=~GCd}sX4Ur>48eAxYb;ydG?DQAE4VfXh;d}sW>$T{46 z*!`a;K767auCp7==@;4>2+ym<=h^%d#aA28693+Kw)j4{pXzp9r9Q@tXNy_a{I1t8 z%kk^=>*DI`^`sZ|oOw_@=HcVS)z|CO6*l45YUIrJzAgW2TNcLQdhKa~?~Fg{CB5eu z9M=WAe}tBS@tyG>kTY;_^kE#r|6}4i<6rc$$^_=a?$1hmXZ&qn(J^g4?EVRf?~MP9 zoNdg9-Ty`6JL7Ngs-BgY54(S(0It=@8UHP9%pQZ|_QE)9F9VG4jKA2QbiE!NeHe$| z&r5t~{7dC@n-9DHnE)nyXZ&+s(>sO1F??9FLim$@Q1PAdKX^~~v*yF@4@lzUjQ@l8 zW7`T`zhL*rB)&8L1UXj@j`4xr_dK~4N6X$MXORBq4`+Vo#l3PGf{|rUh^x;F`m!pj z08ZTCgTyn;Crr}W^LEzjOgx)EP+nlm!tRgPGBCa~KK(U)Wj^fw7K!hS|Dl}kuMy)0 zFUY6=r)A8C-JhIQ;jqqUXV{e zRy&#xyYFdE{GEwE{ax*1KJ314WA*mFCTB16;RX5hpS6$qu=}3ogzrpz=x3|TeAxYo z$^LT2r$4Sk&4=CpY2rKM({I;t=ELrP+xCu=bEf(5f_(Y`yU={teJ|^>z0Smk{=%*@ zA6}48zhXC;54-=fWP6@0HXnB1)13G?j8A`N&zTRqKSKcH zJLA*u*&F7=IOHckPU7#3PycA2nGd`FZTpLU)V?+!UXV|JYd=r~$m?MDw@TvUOnm5< zZCUeS_rEPZ^xrnneE8e^b>vVMI`PJDFVBpS)1Y|qw}rSm-=3)OpVfS}1%6XJBkJY# zUa4u~z9IkFpd^4mtpYtv}N&k{akIYm=C+}`wri^fgknPM?*s(m5;To z^MT^(ZK2=ARo05}f!7yTZ_B0%kf2$YGjY4|3td}nSr~_H*;j-6&iM3!ccuBT`>!P7 zJLA)L-p%HRe)KH-#}eNepZ@snF(3BuZ%*RljDOVEs?TRW?EZm??~LD9#-GfG-M>lz z*J|X9e{GHWVKX1bA$^KT{GIU!^;Ms6=ELsK(=ssOJL6~l)Z(dbb~z4V{v-Sj4KThl zK7AD~VLt4BW8ypG)92yJ=ELq^n)uH6^p&`#`LO%565knrus#6T(0thaa}(bg|MzmX zG#_?cU#pQb+cH}IOj{PlVc)Hi_|EvhlrzhG*!?XN-x>dOIainu zyWgDn&iL66)CZ#Z@FU{tZP`d3YOO}jEW43DVtm(@g>l%HoCf!u@lTfXsrj(`w7=!P zGyZlzQh$!?#B_$;*Dfjh&iHL|RxlrS|JlTc*O0?;^0AJS;o?D>#~=Ruj)#$Q8iJu~ zv)GS^_mgG+p76JY^SyN|;VdQgaPWygecoQJ`5ag9t>Wr^v5CdAR*o~v(qHGW_2ROy zW`%vRW8ypG-z{fz^I`XC+X=4K$QhshKS!AlyWg6G?~G4Bp|$42?(dNJ&iM2vx~KWD z`%2bwe4O#=ceLJo*!@w7?~G6Xq;2NI?vG1+XMFlG?KU5Fzb^5e@#*h$hWW7j>_50x zBWHa2MLpSk*!@EUFupTB{imL7K8!O&!zmivcgBBN&L!rN)W7dzyFnqe0G~>_X zzduc$svhsI@L_s7_>_|EvZ%Nbxk?7p8<_|EvB$XUmH*nJge0^>X5zqgY5 zk~SZ9e`Ml2Umu=}lv?~K3QAoaIwKJ5MuiSLYmqMSR-huzn$RNz|8aK^u0 z&V%N|?jM!-&iGpmuF0M^A9jDYB>kQ7Pg)obZmZ$9k)K0mDZ z&iE^iP+!UB!|v~x#K#%GZe#VQY(DIMhX5u%&iK!6qJEZ##q%A;;dqre_z z`0!zJxUOygZ?0>{%4yJg_&ZfxU9P)ul=@5`9*)5L-GIup+mM%QFF z*|IPW>GspacgCM5=Wg?1_s>auXZ!=ls6TG=VfPP9d}sWB$x**bp^OT<|AWML#{b^f zn(S@!VfQ}~z_l7Vzo$*)L zLDzKiVfTM2fY}!3`E5%<%lfty#ns!=xuc#N=;n2Z!hu&4S8t1M8O!T(CT<6f*L|)n z3u{)`kEbQu;*7tHDs0U%A9mmO9oyoJe}|ka%!l27F$v!p|FoTIvK!2Y-Di7X!gt1B zSu^f1A9jDO#COIYDd#@(VfVL6d}sUvv?~K39#G32{^I`WdNqlGgTjjiK zKJ327S*z^PuIxNHpPLW6?`e+jO!&u4lA{cpV$HaHWpC)IR`LO%yASiIHW;o*?yL(NxiTSYmzf8h+#(!7NSo2}` z_egwa{84+3`yFWKce`oyr@-^9M=ELqEnZ(B#e?nbNcAojL z`+rY-XZ&sJYqHDDhuvR4@tyJal{3eD*!`*Bt8A|`{ww>`WOtblyFW7t-xdB?K-c`hu!zQrB*YX@h_CKllidwhbG}W;}6+akM;dCZ4#INpAm#NQeJZaKd*A9jCy;ydI2Xu6(jnGd_a zZQ?uQ?=0sY^I`YBtWv8P@MChgFKGWa_XRJ?@$>WzarJrnj>11|(|E4ICyA@iQ!N(a zzgL1lds&+JIOA_|U`_U8^I`X|NWyoHZvb~-?x$Y zIOG5BS9<f?5= zWV@V+=PmNjuw`M7r!G-}iKjFEhjM;rKJ0#T;=|X-8KnRDyHgylp|^hfHS`%dzKwqr zvyE>g&!YEGCUwvjaU0=d#MRrV$Li%cI}_)&BWtp+ZCTjktVaW7-x>cLIg4)@*9E&j zCGnl{`yQqDT;{{>SEmW{@mu8#G9O-$|D2rl&4=Cphw?kPRwL&IX6R3sgK~OqsbxKF zM~bV{_7BI`WG`Fz@O$FwwDoH)>vA3@Uik!FPjw?jz6Z1VAsYN#!*|BNPfnxxu>1RH z85rLgfB16ZeYVGaXZ)FR4m2Nj|BS?U#$WFw9ZTlJ?$;;2Gyd^%&NLr(|CGdc z#$Wy9n(QL;VfXJ(d}sW3s~udc~1)_jgnn9jgwXj}R7b!~54s~OJ3?KAmnY#o<{-Ph?+-WF&4 zVb|!nqWQ4!0FT~aBI^_DA>|dJCy5Pn10;GCfYb4v{Jim2yYFSUigT>YB zx=`T{92?gKuOqHrmmd!cIyO$yvJHwCf9Hy;*EQerDZ)0ojFJL zl7F2o3*!vYphszC-+6xNaEF%lxIHMYj@yX}bIQ0FH+Y)3I&OWnQr1g4I1{&1=BVD9 zEeqoiw}Xv<`LO#pCB8HMgL1wyA9i0w#&Ud|@xPYy!|md>!0t~ni9swy{pJZAnyk1}To-(ZxO!b($+6))zjghOmi2Z0UCg@POzs{2rtr_Gjq8HX6IZW`KCJxM zaONC&`!3aan;4gcafWDkI*A*+oE+|PCg~n$P2;`A8ySBrX4(10e_J^o|A}Ja|ApfJ zk$8}n;qTj){W@88X`QUTEI#qS_3oPNX3ZaB{E)bM+b_28Yvnk5JU7?Fo+UJ&K77X* z)6e51WBTCxnKAw4<&EissmYlBlG=^w3u&4${SeJCrjMcHjOh<(rZIi-%rd5Lh%1fh z_u)ok`gFL%o0xR3GW;x1#_Cp^sf zrQ=kO%9wWc&N8MAx{Hlz&+S@c+7r9qc;NZ^PQbX|1v*cSX=CawW7>oI$e8w#{%%a$ zNBwl{vhB2Sw2U!r#jI&eJ1`p<)5go@#S+d?U`Z=WwI(*hlmX-I#V59y6wmg%^xzKjBT| zJswki6l2;w_^UB(8hmX`dj&tx`OLa#i=e+TA1nI-}Jp}%=dbKG3HymuZ;Q5?)%F3Iez$tuD>zg z$E|A2w{Pnh^IhAP#(cB3tuf!DO*H0PvptRZj;vtJH)2I&zFpeinD3H~Fy@=1lZ^SE z=zL?o6}rlp?|^PH<{O`Tjro4(DPz9PdBvFTZr(BGo0`8E^S#X1#(WF&{XJtk@SV#N z#(Z0`f-!ab2OHllUe}m9`I{M2-+qiSb?GMpjNJ-e@{-rXJnTjj6je#h7|o9mdqT zI?$Nb;gspB-unEFfC8dEpv_r}yaddQeMMb8;iU+7(9>H>XkOg*2k zjH$!3xXOGSGt|#n(U`h7Ya3IqW)oxT%#1XqKFp5B)OFd#n0hRG8B<54(U|%tCF5=D z^`6L>dLu_0QzvAmG4(ypHKvZlCC1cexXGBh3ilgR58(-8>KMFg%=`C08}n}cLu20m zes0XW-LH*#Z~Ft4eMuAE$u4Qk`_|=*d6&AHG4Dy&Hs&4ZP-EV2Ze+~6%WaH#FS(sD z?;L+>%sZ@K81sIrV9dLxeT{jqbg(h+agH(O9nERRynmTx%)6DVjd>4pt1-{~?=t3o z`AN8+u6z2n>rckC%l)n~ZJT^%Oxq@38}rTJV!601--Ru2%=avVjHv^>t}*ZZH-*2a za`Ehb+1Bt6#p;J>dt>@1+QpduiS{z4f1+k%+7fR!rY-S9+!r5hOj|A|xi3E5n6_Ll zF{Uk-n~Z78<@fIBd*=s?`4;j?_r)(6^DX3??&w>d4~+S)=by&ZM_Od>xQ&O1moU!s zoM8=Po<(eA%(IA5#ypFdEM9UkeJ`nouzzm6thnBIRdG?gNX=4`RPV&*57PWoU>(Ce zU;VAkUs3ZfwfUM|H$(S~rKQX4w+pmnN&%8uk+?ESR>AW_kz0Gxv8?IN`$(VLcxz{Ca*S${nBgV8x z+G0#wsRtX==ITktwE20VG3|?9XH46ncNySDaW=wnCi|SsQIMBBF za>lenzLqg$ozeAC_~B=_Bb9;~#6;YmMnk=uTt$U3$Wp zKAT=M?(EXNjPd3jdZuGczeqpQcCzp2Luv(M`e#|)n7*qvFs2`|k;e3q^iyN{XW84B zzE|3e>4*AYWBQmr!I=K9&oic<_p6NiY@&0=c-lzi1IF|({E{(!0e@)x!nTC1Q%WBR?_)|ftRcQfu9rTced`l>D&(@*r_#`H;jqVZRX=lRC;T|V2G zKGyFtrcdf;e7^iQj33gvJ~5{4%}nV|`qO9e(#G`vySg!b4UaIUAMi28^ufK0G5wYA zWqgpfx7C<_mJc+3Y74cSVEn$)_7r2jcn-$%3? z^KHe!#(bl3tZ}HDWK6xL%Z#aabOWp~|DbE%y*7WVt8~5?Q_trWW9kdNYfK%6&yA^% z(ND)c+eO`jWsIpuvAQvJLN;_q{zzl$$xJk+9>re9v{lt?Ogm=NjcFt6C}Y}BJHwc^ zur4&FO}6WdX%p;TW7Gv0TI&Nbsc;>V4@RG6Jr;Yn7-Ci~3JFNGOyOietFrK7z{$WepuG5rO%Nc*BI1e`7Y+XI$ zHJ+et+}ijR&7Wv|v;4h{hsxR4xJ`VNG3|4lY5c|ND*qTSA?HTpi9_}L*7#`6f6jQ0 z(&W#^GqtY28SgMcWr)@o|J$`6mo`37yqfXT>#M9|yt{Za?Oy4~-jnB~jJ>QsqL#{EtVLcst#-9&W9%B5a{FjXH3V~x^n1>^TOPO$Z>O352Onrt^ zjj20vp)qwZt}~{N!R^M>0eHlicl6I1^A7!w#=PTx+n9IIUl{Yw^at&6+sCe^|HU=B z70UFtZo;Dy-ZkO2$XZ12IwSXik4gB7gzroExrEiQJo|Ew0gda)xrG(#1_``(%lJMUX{yO1BOOlsI|0>}l5n%yek|c<5`Ht`_Y?jk z;YDbXL-H*@Ooqyk^2f6W%!CpCr6}!aF5AIpIAM zo|15T!qXEzG~uHYJ~`ow623X%xd}g%@KXuDobVe7f0po92`|xANw;MZUMb;$3I90Z z4HBmR@qIK*)zG4$RYRMGqK0-2`)Vj@=+Hp_GLE=V~}l!*4ar(r~_p3p8A);ddG?(r~ecOEg@n;W7=EYq&zgl^U+naJ7bO zG|bj;t%mC~T(98<4RbWysNp6JH*2^>!>t-_({Q_nJ2d=W!<`!DYPd_o-5T!EaIc2@ zG~BP@0Symocu2#;8XnQ`sD{ThJg(sh4S&$^q=u(7Jgwmw4bN(LPQ&vWUeNHOhL<$F ztlcOU+{@BhEQ?+0bWckL*YI))cY z)0*4ri(RexwvOQqh5ZUG#rEOtr9x|dYGLCZzYevzLuCzZZl6+YD-4}pUu-CBJhXn3 zE$TL`%Mb4;)eoOi?C2cc(v=^&$*>KFZ5(E0E&2B5VfFJ}<%H(CQohtZd~95Gp)`CC z!qjxBdA~x#*nDSx_#}(Y(0pfGzPo$>uFiaGVM=Fx$JCB}>!uVNnmhLEY#%0LT3vJ6sPi??fJIm`Z&>4=XIC5v!m6iTI{rB#z11`S=Ub`Z1_ zJz4A9>lN)R*O(gUXewEVHSX7#u9G=EX6S@!DU^@O9_iT` zj=A!2)LCpx4zuQtbgHG$(a|}@kM6?0U3oh?743AY(B6`-w=~qwO%J#FDTVr}I;iTW z#_eiuD71AdXY88Z(p=YjGshS`<&QdcCgk!ZB^SruLcDrZk|@TZuB)-Jxvg1;hYp6x z7BM9@CoD;y3#V$9tK^Xra-0(^XL&}P;m1v(wY{_3f7RwSHd}@ewK%DDjk9%iwUr7n zCzy~6lyBIltE02BZMGmb^Ay#u@vNclqLG z(_P_$)l!%5DD>u&&f^!)I`&A8Sqt@~^EkxI%jjHp%*pFjx{KFEWn3JfR$dsL)AY1b zK3;=H=PI5KXC_NsZEdmipi>b!95UgTG?e;cyfT!3jbX|s8EkI8qgYDPU zx_nd2dPnCPish4dbaHr)&NbCHw>8Fe)kJc=4^ur)qtPMTNCGNfS>rFs2|GGhzBrHe zD{R>Cb`_c8DLgvY<603W6#?6%J=piX7snRW&@ z1K}s7eOOFKlJ4M29D&Vk`|0*zA1^_U*TqJK5>-0@;_MJyi>?KJ9E{f1~@#8IQ; zDeY5ZD(hi6o6@~n{S-@0C7 zRhZr$mkOJ~6!}3|syxSoDbLXEuoPf{ofQR=G+%1&jHj(OSjCHGB`fpmi&ntb>|#fl z9YRumhGMLH*n&q-*+?v=jMqt6ERp2q#mr!Q*3wYdo3Dd0cF9$+p-|V=v{279PoP{w zT`sO2DqlDvPbn64G)0b=m&m$fWEaN?9Sk}RO3EtZbaJhUGs?G#nk;Afk;^O4{7Rsj z=oyG+q=AH@Sfh$^imu;@==3csnoYn~ssweo=%CHVqO2FELK0*-eh>Nhu#GlWi(i^l_S}jRZ*|oNz$=wO4vrF&ce-`NS$!NSm8XxM&~b&s>bZVRX^nW6v67J=31It zxoJ+N${{p1*HkKU3(ez+MqPVLx_pKZRKib6&||}WWcg4X%eAQduxKnrTpd9w5_YNp zYZoFpiBbN|SHbT08wvkE#8FvRahftOjoFwmPZz`_tbi>%`Rcug36YBj%C5QajBcT3 zJuzu=WA*=N9TeKP;AFcOfXDem-WCexy*3>~;pA0W7qO~@6_S%y*L@w_2@&m<=g?eeUo3#|C_u8z1xW(gq56aDPUoFf-Jthtr!yX*2@kvO?Y4^~R)TxEG5t?Pw za_zwF$nz$?V`_6dS24TA((=5J4M(z`A{9#ZJV#sB-PW1+WqBg21IXWL1ihu$)}&&& zJ(AUWe2u!v&QA&FfW^>W`R<{^+Dh*hPi1PY`A)s)?!7M$J$^~X#;k>!wRs$Lj)J+o zt_DVWN8zX|uw!SwZA8L`^#$r9gb=itGA2i(2A;Bpd3u&-)YwwwEq$2VsPogYR8jQo zq^!3Tn>O6Q9I;VrUdKiVqO}}Hg{Ax@%xvctDNu=w)2OYX*xF-4nUnvjP4(zkwz^|q zs)vN7wf+9PFwP{i(aXcuUYo5Dw|JE86mA&Fsu%8I77~YSWhXKO?!a^5oZd;fO0llF zDdXi)Z$4Qqdda!Uiy>aAEzIn>oJir_o8`VOElSgUyPCrb>lQ9`UEvMAr`&g;{6ymR`I&4h54DEv_s+|W2}U4Q|0*+x_CX_!nHgU&u!Uot<}{^ZzObTG}U+N zBUb%`EWQEG3Gxjd~ zp)j4Ynr7;LDwO$!ULP}H%%p_MRTOTX>`YVTz;yEz6$N0Gc=U66OV-g%+*A^^x9h_; z-e8l>!z8p>))Jqu_S)mqq8In=&-{V&!rZy#1k&4J>TiYp5MN9C>vC>R!~J-?dML{; zl)N5pLAL~T@tCO76`!ho+UMblWl!35d!al;J2$*|jSqQ*Dw~+cYh!y(9^Tnd0IOG) zrTizp#PMrcs6<%~z-~X{-A9ajPE}%>n^am0ca!1Tqv{sL2EA*$ugQ@ON_EbGG{jZsE9A9sD>+;D>i5|Cm9WuSVG?d7*tPOS7t81KI<|~!r`dg{e zNI?3{(uOIRZpSt zP_$TWi?P%VA;TBVMDiMQNXqik3$A{XaZpKn)P9|hFJ zt$-d;Hc)4m5L$}U2sPxjI%l+?P3S|E`l*FZn-#NL%aO|&bH3E6ORfd2dvh|oe0jb0 zivnatVZ|Z0XQ~`T{2?lJ-IN&kIo9WGGAsTct4XS^l1jv3Gef9+yP{kc4lfh~@gz0O zqfpQis&w?)(>KO09(CKthiD5kFZIOXT-}}$no^SMqv}@poyYbeH&lA6zI3US@7_;W zX|9`^=0NhvDS3UT(iNVx=s{+&qq$uFID{L1@|DE8t6_e~mA5A_s_adhTF_P6@~{{u zRzt91SxtlphKZ*IbnY+)GVi*M7hpbMMWhU z)sM?l_A=0iC^|C2&S>zj#WJ>epbak(g9KAxfx>}K-ACE=^p3lthM5j*5(fb zI(zREG(|1$lU>;G&epna-Rdsfy+Yz}%v%hM%g?=c2^Eeicd@(VbRxEey2Zmb+F+9n zvz9KsOz*{YK`eSPnRivq>yUjf%&f1RKqT|7IbJkyDV(6^U{*Z@+<`(oFxg&Ez~fZZ z57}GGe!ce~R@7qZ?v~Vw-&JSs!uifMCQYazwaZS*s&!RSK|EL2+!l)BT&U~GB*NTK zwa$v@yX7h$nCa{bc}e-F@O_!r72b`@M$9qUhr5N7wfq$wo2`|^?=1M$v$s*@O2xaW z#1bD=wCvy9d#l$Gx40|!R5?mjB^Kss5)+2>-BYE-^o`t}l{=W7Tddd?BAQy$D?RTWRu^0D*1XtLMfN2 zpVrWelgT0&6Ddx7=Sfsf6dg%o?nL!LVed{Pk7PNaY{tS!EMIpxqMAE4-MFszR!Y+@ z^%%yavZ?PpoqVm9NWDArZtfs{oU5Yald zcb}v&ewMbx^}A12OA#dwbs#!aXS#k$FFyK`NXBHU%=pgJsJY_67lrUXg&AqvF9-$w#*%|`OBX@a;VibO zu0?M>a;l@LgsPhL-6mMo%9Kp1BS(X7y*9xtdP=C)ysEi=r^SRyTBsgGv0g1Z=}As} za}yGdN)1fv@tsb@WGX&cOXhUcmzrt3qL;R8=h0KD()^v?VdQL9W}BinrXADN+(570 zg77ReSB|E(q$=j$?V(b&G9{Cq|9LZk;d_wqy%#M&l-pQq43Bri>!ZnfFj&n)BsOCl`q5rrN z(f_uNjLHw?N-NE8Dej}vwGb~%Fn8;1c zH>%UcXI9Dcj|Dsp$<^+mM#prE9R61;>N%dTG{u5!u62r6JStZ^t9~evyy4O<|9;IS zYs~i>E#uFx9hRzwTF9qjF;ttDG`JF{(&kn4ZN5IH2=l>8dpp$))mD=hhq zMzNB%v=nev16Vy8%<9>omC`FVoE5)KvcTuxs8%Sg$9BHLI&9i9?J!H3M<{bplattw z)rUBtO)YVc4?g%Y{j`PYasE9?;Od5o{`XBC=@bqhL&f7E1gdPR+>TRRrRG$%aHKh; zik|%VB9%R~o!TSU(k#D2O=;7SvCX`6Ri=QrBKZHD9Nn{i1CvleP1(z10Lyt9WZSnkK3Qr3nv8ZLaognY+3X zR_?>o23pI#42-Wddm6JgMR`0QHH7v^%M;&dyY!pQn|ck!r1jXaIQu;|Pa7x8ZKj6F z@Hnm9VrklzY0|i>_XUwO)*2Spk+mksTaMw-zxg*2l_`sf(y*^+e#Tl6*#=e8L`oBmOQz#3J=s?=u>6IQ*RUn=#W!$ehu zYOfC+O;(-Mr>@k?4vXr9Pk&WzP&s+3Dqr_#v8U3Kkb>Exs#5Vc8zPFeR)VTET7y<` zGHqEX%&Bg)C`_wdsUORqRWo7rs3Vrs^P3f%IYquvtC^*8J-Qtt`w1(lzVsx;hH~|D zmiEqQ0;{mnqxYBaB}7{(VNRvt*6>~BH+os>*=bO9 zRuYy;^VcxrTY6?nv)$nNML$kdPO~tbCJ3udw=Lvfl@6}Hk)8GIhk+^Wrg(Tou5?1A zldt>(C!$RxJ!|Q5Q0ei-VaZ+hf;dhykx=dR9Tx+lKT>6dpqQT~!EZdlUM zS*0ao@}b!62}f+0vKL4`sYVjZKk+2CGDX8)Zh0$46P5A1ws(y7^4# zAW@C^P$xj>wXFHYYZ6DMK3=3)aFGydB8J+9{1B%8eNDukwHCGS_{xw)Lv25ZnhLQR zUicwa+~NmzbeI+D<$R;w$v57gTi|2Hjn)OTr7%XDylwbEh>PH^J5R`R{?m4a&Ye^_ zBYMo997KrFdKtD2n}S1PtLfiPB!mx|q02ER20+b4B0#?RMt zI`!(k`CYS3Sh{twL9!FVuKAfvPZzx(>l=8S)6mRX}n6aII$fZ-A(E-S7@$6{}+n- z4qqK{g&yo0tx3*Col;ufTFi@$Qlz*<%g)h1^#Qg4^0-3I!O?rCCeB$|HxV06@(hnmc8h3iW{gW zpx(-9IHuy;u#OlkIgm#y)Yl1{sS`MCCjYC)ruYNf%Z!e8zNOZ^G)F}eWz7l=EcKk_ zO(C>}^pewF7aCdaEU8wqQdD#FFZ|zGZ0NbHP8!x7vZmyha878XYe?K<<<@Jv+QN(Bq+um8+{|HW_rvOoWy5C53}|M>6!^56fgFaM<<|G!`V(vQ!406!)GZ$bdSasdCh zPygk=va+(cxVX&B%<}T`<>lql($e_&_{GJ=>+9>8nVF@frT^HUtgNiq*x28N0DnvX zpI-nE2>_2)03QrIoe0+TJ(xRPYAXNYW00DGT zPE!Ct=GbNc01MB@-uJ%$mwNIh z%eJH$2@>1b|8shZgKSGb`@#XS-Cew6zSyg0H%^xnNGf30r!#wMZ7EljMkZh>sL)MusmQKg=TKo9?lCHty z$_Qh%QdZkHLaravf1a$e&UPWRnyA>$7R1%fd&Sp40NdH@)uT(E{>&=AnwnogE!dWX zdR_>=zNqZ4RF|L!_Wnd7iOlcxGV4O*RHu+ppt>P3iOla=)x!`7uDH}2BMFJjZ&iI$ znxi@o*CeG^f%#ol-M5&I&oFQoM5MR0`8}_!1E&$fDo{NWu{J65JFPm$Ob;lwvp+

    !;44`Dpu`CWDHGV5YyBYcYnbR@RwlS|pMouZ8{)r-Pq zxCYLhmT@)+F%!Y*eIsqx7SOqqtc&{j(y$A@9wjZ?-|(rWvkh|{yAWt0>I^HqvB)-* z&2PZ_3%s^z^Si;ESF#@QsS#X(`Bi&kOyvqAQ8sDY?Unq?g!u)$u~4OI*j7puZZOm9 z+h!rLsEb#;H&)8ZtM5XdqvjXojfE;pfA~a=K|X<&Xv2{HLZETh z#r`Cnt1-w2Y;Lr0CN#~u*qDYT zjO+w=HY>we4m1xepNDwfk?#NQAbq9z`|5tMPFF=zL>C$zL%R&2rpuERYDxB&pO9{8 zs$2I1;NG=B+AN0GwO6ews8x1-KcOX^!&a2=5 zwO08fhtLY5i**^a&4MdLv*tBw|7MNJP*9_$h!~6YgUw<1f$l;0jWUC1HB4V@cSUAQk?aJuF$13z?bI*S9k zWCu=nvAww#$CC0cgK1x}>~uZ7FE)Rt3^4b-@e~=B?mupC;^E^vu9?vFb@j4&i_Gvd z_l3=*CS2?=qYi-`<37O6S4&%w>F9AP3T>8=4B<>}E_i zrEpLub6a9YH=(@IO)6$fa!;39;A`F?Gp1`~clC9~)#XoJ>#3Q~N9sMirn+jzbg@2z z9^La`ZYFy>jL-ApPt5b>hZ(Y^%bxpD?tBOgSJx1vd&FEcsj)|9L^reNTwl;QLud$; zeKq6W1a_Rkotw!1IoB67MuwZ3Fs(v|K1K#j3FD^KOh<7JeS8;ci{(?oywhMh0(t0j z6HtsEGMvG1^t^T8bdLeLFLJtkD2`d>1v?W(rwh4c*f269mluv_C^}upCBr!lW;5=f z%TRc_(DrWfY0LPwSSHaTm;l~l(}luC+wo-HdZP@JY zi>}r$FbRKw6TvDIT|rTh@;wO!OD%QYJp+5Yd5i4#=alq*0bsqF=9-@g`t5b_qLlp6 z#prCpkH`W8ImkFY9&i-ItkQoDlG2QY z`H>RIle)iC>j#)3oh%kO{yKU|rh#eL%zY#nzxQc5IG!3T1* zhDS~{Dz9(=U9vM7S`$%O#cF*kI9+AsO$?wbcGc6+N>o;vz89OWy7DqZaJ_j!ZhwaPxC5a2p%^wVRs}Oi_3bjbm!0(Bb?;D zH>8Ue+dG=e)HmL%;YWWnqYHXu--L-%*TlbsW_P+HOj(o6GNEfh!X`$&gmo`;<9iJt z=(fHVo-Tf0`5oyd_LS$c_iN4RSM>Ma>T-M_-L*j9jeZKWZP<}+V&w5Bq*fCs$EUYy zMim|V=DOYJCim-y;Qq>APuPeq7?-mTx@U^AiuKoF)LpFU-Gy%YB|m&M&7IxdCtc+0 z>vo}=4j+(}^{_lLPpG&3>_Ar#@PMIvdl+<4c+KgGqDjg`7lYTBuJH9fT=rykH%0e0 zCVor4`#9b8ZA!5_+NrO9D{d5~FsF;~%S`Et-<|XmA(t*HrmtmL&}t0ej_??bajS-_ zy@qrp3xhDwyy^nSqXy&bxu(0rwx%k&vIsr|vtM39I8r_6dE}d}^)TH(U1@kE%!@A7Rqkxq3LS*J(^bE?S)Z;dZhEcIm)mAMBH`}V zmL>hhViUfrF1c3UasA!;v0eiyIPr7MB7?$=!o&6j(jyUf>y z6#3EUd}q4nRmGKRelp#S?nzZ~RXV-cf$jw&inKYT=MDSK@UVB}{cjV;|3kOuebwm& zDe414f;3cvA-hn$OE1)O!o&8EKN9LFye4;F%W~Yyu>4pxw_KeTcUp}Mq651}zaBV^ z;HG}A+oWdB7fBbx*2Up*(ON~$+w=KIw+gra_?GRInF8$PNbh)x0@n`) z`)L>@?UGiHuzUIW?1#zSYG4D8j7Z00Ea2&d&gxLVShk$5H6Vj1zw}8wimYWsx084n z`_$+*Ew$uyshP3aq2oR4;clLdp2n%PE zUdPoiqFbkSjXmNtCAD(Q?lHPttdTx_(%7T#kfGyr zIKx3d$Dbk%%|~PT9$S;~NPnq`hm$bFWwREN(RH7C?u1sCqs{1&1YN7q8W6tu(V#o% z&{O*{*hBWL58P|^7)`%b>qTa$naYW#jz=fs$%Jd^+`a8ahKt30oCBL3rYuA3vj?uv zL1l$b+u7zI_Oqbr+TQch4i9@guR7^juHA|Jw;uOo#j=zK*>Q9jx~}a@7NyU%3URrAux7 zAjCVQc7v)HR&6(Ledetfoi4SCj?-gSF)9kR7PR>phE`Do={rs>O}Fn} zC+x?$l{muN_6&nth5KCIVt9){x5ho`tr%&q#Y^=j!e=%tW$F*- zn&-y0g4_F4>j7mypOk)|T{Ty9ty;W^t@)*GI8kljKU>X~<3yf7n{x`9HOFZ+_#?on zZ`!Vs_wfJ9u2c8=h4r9!82)e7+WdKZ4%-^N;7XM$RjO2}82UdYPu^%}+x;y70000< KMNUMnLSTZl?!Ko0 literal 0 HcmV?d00001 diff --git a/compile b/compile new file mode 100755 index 0000000..ec64c62 --- /dev/null +++ b/compile @@ -0,0 +1,143 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software +# Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; +esac + +ofile= +cfile= +eat= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..da83314 --- /dev/null +++ b/config.guess @@ -0,0 +1,1561 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2009-04-27' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd | genuineintel) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..11b564d --- /dev/null +++ b/config.h.in @@ -0,0 +1,113 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Architecture is PowerPC */ +#undef ARCH_PPC + +/* Architecture is x86 */ +#undef ARCH_X86 + +/* Architecture is x86-64 */ +#undef ARCH_X86_64 + +/* Use the Apple OpenGL framework. */ +#undef HAVE_APPLE_OPENGL_FRAMEWORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GL_GLEXT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GL_GLUT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GL_GLU_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GL_GL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Platform is Apple */ +#undef PLATFORM_APPLE + +/* Platform is Linux */ +#undef PLATFORM_LINUX + +/* Platform is Win32 */ +#undef PLATFORM_WIN32 + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..a39437d --- /dev/null +++ b/config.sub @@ -0,0 +1,1686 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2009-04-17' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..9750634 --- /dev/null +++ b/configure @@ -0,0 +1,18215 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for bullet 2.81. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: bullet@erwincoumans.com about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p' +elif mkdirs . 2>/dev/null; then + as_mkdir_p='mkdirs' +else + as_mkdir_p='' +fi +test -d ./-p && rmdir ./-p + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='bullet' +PACKAGE_TARNAME='bullet' +PACKAGE_VERSION='2.81' +PACKAGE_STRING='bullet 2.81' +PACKAGE_BUGREPORT='bullet@erwincoumans.com' +PACKAGE_URL='' + +ac_unique_file="configure.ac" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +GL_LIBS +CONDITIONAL_BUILD_DEMOS_FALSE +CONDITIONAL_BUILD_DEMOS_TRUE +CONDITIONAL_BUILD_MULTITHREADED_FALSE +CONDITIONAL_BUILD_MULTITHREADED_TRUE +opengl_LIBS +CXXCPP +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +LIBTOOL +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_multithreaded +enable_demos +enable_debug +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures bullet 2.81 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/bullet] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of bullet 2.81:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-multithreaded build BulletMultiThreaded (default NO) + --disable-demos disable Bullet demos + --enable-debug build with debugging information (default NO) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +bullet configure 2.81 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by bullet $as_me 2.81, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='bullet' + VERSION='2.81' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4' +macro_revision='1.3293' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +case "$host" in + *-*-mingw*|*-*-cygwin*) + +$as_echo "#define PLATFORM_WIN32 1" >>confdefs.h + + opengl_LIBS="-lunsupported_platform" + PLATFORM_STRING="Win32" + ;; + *-*-linux*) + +$as_echo "#define PLATFORM_LINUX 1" >>confdefs.h + + opengl_LIBS="-lGL -lGLU -lglut" + PLATFORM_STRING="Linux" + ;; + *-*-darwin*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Hello" >&5 +$as_echo "$as_me: WARNING: Hello" >&2;} + +$as_echo "#define PLATFORM_APPLE 1" >>confdefs.h + + opengl_LIBS="-framework AGL -framework OpenGL -framework GLUT" + PLATFORM_STRING="Apple" + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Please add $host to configure.ac checks!" >&5 +$as_echo "$as_me: WARNING: *** Please add $host to configure.ac checks!" >&2;} + ;; +esac + + +case "$host" in + i?86-* | k?-* | athlon-* | pentium*-) + +$as_echo "#define ARCH_X86 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="X86" + ;; + x86_64-*) + +$as_echo "#define ARCH_X86_64 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="-DUSE_ADDR64" + ARCH_STRING="X86-64" + ;; + ppc-* | powerpc-*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: HI THERE!" >&5 +$as_echo "$as_me: WARNING: HI THERE!" >&2;} + +$as_echo "#define ARCH_PPC 1" >>confdefs.h + + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="PowerPC" + ;; + *) + as_fn_error $? "Unknown Architecture" "$LINENO" 5 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + + +#---------------------------------------------------------------------------- +# Setup for the configuration header. +#---------------------------------------------------------------------------- +ac_config_headers="$ac_config_headers config.h" + +#---------------------------------------------------------------------------- +# Package configuration switches. +#---------------------------------------------------------------------------- +# Check whether --enable-multithreaded was given. +if test "${enable_multithreaded+set}" = set; then : + enableval=$enable_multithreaded; disable_multithreaded=no +else + disable_multithreaded=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking BulletMultiThreaded" >&5 +$as_echo_n "checking BulletMultiThreaded... " >&6; } +if test "$disable_multithreaded" = yes; then : + build_multithreaded=no +else + build_multithreaded=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_multithreaded" >&5 +$as_echo "$build_multithreaded" >&6; } + if test "$build_multithreaded" = yes; then + CONDITIONAL_BUILD_MULTITHREADED_TRUE= + CONDITIONAL_BUILD_MULTITHREADED_FALSE='#' +else + CONDITIONAL_BUILD_MULTITHREADED_TRUE='#' + CONDITIONAL_BUILD_MULTITHREADED_FALSE= +fi + + +# Check whether --enable-demos was given. +if test "${enable_demos+set}" = set; then : + enableval=$enable_demos; +else + enable_demos=yes +fi + + if false; then + CONDITIONAL_BUILD_DEMOS_TRUE= + CONDITIONAL_BUILD_DEMOS_FALSE='#' +else + CONDITIONAL_BUILD_DEMOS_TRUE='#' + CONDITIONAL_BUILD_DEMOS_FALSE= +fi + + + + +case "$host" in + *-*-darwin*) + +$as_echo "#define HAVE_APPLE_OPENGL_FRAMEWORK 1" >>confdefs.h + + GL_LIBS="-framework GLUT -framework OpenGL -framework Carbon -framework AGL" + have_glut=yes + have_glu=yes + have_gl=yes + ;; + *) + have_gl_headers=yes + for ac_header in GL/gl.h GL/glu.h GL/glext.h GL/glut.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef WIN32 + #include + #endif + #if HAVE_GL_GL_H + #include + #endif + #if HAVE_GL_GLU_H + #include + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + have_gl_headers=no +fi + +done + + have_gl=no + have_glu=no + have_glut=no + TEMP_LDFLAGS="$LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGL" >&5 +$as_echo_n "checking for main in -lGL... " >&6; } +if ${ac_cv_lib_GL_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_main=yes +else + ac_cv_lib_GL_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_main" >&5 +$as_echo "$ac_cv_lib_GL_main" >&6; } +if test "x$ac_cv_lib_GL_main" = xyes; then : + GL_LIBS="-lGL"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGLU" >&5 +$as_echo_n "checking for main in -lGLU... " >&6; } +if ${ac_cv_lib_GLU_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLU -lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GLU_main=yes +else + ac_cv_lib_GLU_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLU_main" >&5 +$as_echo "$ac_cv_lib_GLU_main" >&6; } +if test "x$ac_cv_lib_GLU_main" = xyes; then : + GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGLUT" >&5 +$as_echo_n "checking for main in -lGLUT... " >&6; } +if ${ac_cv_lib_GLUT_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLUT -lGLUT $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GLUT_main=yes +else + ac_cv_lib_GLUT_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLUT_main" >&5 +$as_echo "$ac_cv_lib_GLUT_main" >&6; } +if test "x$ac_cv_lib_GLUT_main" = xyes; then : + GL_LIBS="-lGLUT -LGLU $GL_LIBS"; have_glut=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 +$as_echo_n "checking for main in -lopengl32... " >&6; } +if ${ac_cv_lib_opengl32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_opengl32_main=yes +else + ac_cv_lib_opengl32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opengl32_main" >&5 +$as_echo "$ac_cv_lib_opengl32_main" >&6; } +if test "x$ac_cv_lib_opengl32_main" = xyes; then : + GL_LIBS="-lopengl32"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lglu32" >&5 +$as_echo_n "checking for main in -lglu32... " >&6; } +if ${ac_cv_lib_glu32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lglu32 -lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_glu32_main=yes +else + ac_cv_lib_glu32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glu32_main" >&5 +$as_echo "$ac_cv_lib_glu32_main" >&6; } +if test "x$ac_cv_lib_glu32_main" = xyes; then : + GL_LIBS="-lglu32 $GL_LIBS"; have_glu=yes +fi + + LDFLAGS="$TEMP_LDFLAGS" + if test $have_gl = no -o $have_glu = no -o $have_gl_headers = no; then + if test x$enable_demos = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See \`config.log' for details." >&5 +$as_echo "$as_me: WARNING: Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See \`config.log' for details." >&2;} + fi + enable_demos=no + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found OpenGL" >&5 +$as_echo "$as_me: Found OpenGL" >&6;} + fi + ;; +esac + + + + + + +if test "x$enable_demos" != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Building Bullet demos" >&5 +$as_echo "$as_me: Building Bullet demos" >&6;} + if true; then + CONDITIONAL_BUILD_DEMOS_TRUE= + CONDITIONAL_BUILD_DEMOS_FALSE='#' +else + CONDITIONAL_BUILD_DEMOS_TRUE='#' + CONDITIONAL_BUILD_DEMOS_FALSE= +fi + +fi + + + +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; +else + enable_debug=no +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build mode" >&5 +$as_echo_n "checking build mode... " >&6; } +if test $enable_debug = yes; then : + build_mode=debug +else + build_mode=optimize +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_mode" >&5 +$as_echo "$build_mode" >&6; } + + + +CFLAGS="$ARCH_SPECIFIC_CFLAGS $CFLAGS" +CXXFLAGS="$ARCH_SPECIFIC_CFLAGS $CXXFLAGS $CFLAGS" +#---------------------------------------------------------------------------- +# Emit generated files. +#---------------------------------------------------------------------------- +ac_config_files="$ac_config_files bullet.pc Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/OpenGL/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${CONDITIONAL_BUILD_MULTITHREADED_TRUE}" && test -z "${CONDITIONAL_BUILD_MULTITHREADED_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_MULTITHREADED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONDITIONAL_BUILD_DEMOS_TRUE}" && test -z "${CONDITIONAL_BUILD_DEMOS_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONDITIONAL_BUILD_DEMOS_TRUE}" && test -z "${CONDITIONAL_BUILD_DEMOS_FALSE}"; then + as_fn_error $? "conditional \"CONDITIONAL_BUILD_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p' +elif mkdirs . 2>/dev/null; then + as_mkdir_p='mkdirs' +else + as_mkdir_p='' +fi +test -d ./-p && rmdir ./-p + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by bullet $as_me 2.81, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +bullet config.status 2.81 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "bullet.pc") CONFIG_FILES="$CONFIG_FILES bullet.pc" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "Demos/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/Makefile" ;; + "Demos/SoftDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/SoftDemo/Makefile" ;; + "Demos/AllBulletDemos/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/AllBulletDemos/Makefile" ;; + "Demos/MultiThreadedDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/MultiThreadedDemo/Makefile" ;; + "Demos/OpenGL/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/OpenGL/Makefile" ;; + "Demos/BasicDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/BasicDemo/Makefile" ;; + "Demos/CcdPhysicsDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/CcdPhysicsDemo/Makefile" ;; + "Demos/VehicleDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/VehicleDemo/Makefile" ;; + "Demos/TerrainDemo/Makefile") CONFIG_FILES="$CONFIG_FILES Demos/TerrainDemo/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "Extras/Makefile") CONFIG_FILES="$CONFIG_FILES Extras/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { if test -n "$as_mkdir_p"; then + $as_mkdir_p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || as_fn_error $? "cannot create directory \"$ac_dir\"" "$LINENO" 5; } + + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { if test -n "$as_mkdir_p"; then + $as_mkdir_p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || as_fn_error $? "cannot create directory $dirpart/$fdir" "$LINENO" 5; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: + +Please type 'make' to build Bullet +" >&5 +$as_echo "$as_me: + +Please type 'make' to build Bullet +" >&6;} diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..1d79361 --- /dev/null +++ b/configure.ac @@ -0,0 +1,172 @@ +#---------------------------------------------------------------------------- +# Autoconf input script. Invoke the ./autogen.sh script to generate a +# configure script from this file. +#---------------------------------------------------------------------------- +AC_PREREQ([2.54]) + +#---------------------------------------------------------------------------- +# Initialize Autoconf. +#---------------------------------------------------------------------------- +AC_INIT( + [bullet], + [2.81], + [bullet@erwincoumans.com]) +AC_CANONICAL_HOST +AC_CONFIG_SRCDIR([configure.ac]) +AM_INIT_AUTOMAKE +AM_PROG_CC_C_O +AC_PROG_CXX +AC_PROG_LIBTOOL + +case "$host" in + *-*-mingw*|*-*-cygwin*) + AC_DEFINE(PLATFORM_WIN32, 1, [Platform is Win32]) + opengl_LIBS="-lunsupported_platform" + PLATFORM_STRING="Win32" + ;; + *-*-linux*) + AC_DEFINE(PLATFORM_LINUX, 1, [Platform is Linux]) + opengl_LIBS="-lGL -lGLU -lglut" + PLATFORM_STRING="Linux" + ;; + *-*-darwin*) + AC_MSG_WARN([Hello]) + AC_DEFINE(PLATFORM_APPLE, 1, [Platform is Apple]) + opengl_LIBS="-framework AGL -framework OpenGL -framework GLUT" + PLATFORM_STRING="Apple" + ;; + *) + AC_MSG_WARN([*** Please add $host to configure.ac checks!]) + ;; +esac +AC_SUBST(opengl_LIBS) + +case "$host" in + i?86-* | k?-* | athlon-* | pentium*-) + AC_DEFINE(ARCH_X86, 1, [Architecture is x86]) + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="X86" + ;; + x86_64-*) + AC_DEFINE(ARCH_X86_64, 1, [Architecture is x86-64]) + ARCH_SPECIFIC_CFLAGS="-DUSE_ADDR64" + ARCH_STRING="X86-64" + ;; + ppc-* | powerpc-*) + AC_MSG_WARN([HI THERE!]) + AC_DEFINE(ARCH_PPC, 1, [Architecture is PowerPC]) + ARCH_SPECIFIC_CFLAGS="" + ARCH_STRING="PowerPC" + ;; + *) + AC_MSG_ERROR([Unknown Architecture]) + ;; +esac +AC_C_BIGENDIAN + + +#---------------------------------------------------------------------------- +# Setup for the configuration header. +#---------------------------------------------------------------------------- +AC_CONFIG_HEADERS([config.h]) +#---------------------------------------------------------------------------- +# Package configuration switches. +#---------------------------------------------------------------------------- +AC_ARG_ENABLE([multithreaded], + [AC_HELP_STRING([--enable-multithreaded], + [build BulletMultiThreaded (default NO)])], + [disable_multithreaded=no], [disable_multithreaded=yes]) +AC_MSG_CHECKING([BulletMultiThreaded]) +AS_IF([test "$disable_multithreaded" = yes], [build_multithreaded=no], [build_multithreaded=yes]) +AC_MSG_RESULT([$build_multithreaded]) +AM_CONDITIONAL([CONDITIONAL_BUILD_MULTITHREADED], [test "$build_multithreaded" = yes]) + +AC_ARG_ENABLE([demos], + [AS_HELP_STRING([--disable-demos], + [disable Bullet demos])], + [], + [enable_demos=yes]) +AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS], [false]) + +dnl Check for OpenGL and GLUT + + +case "$host" in + *-*-darwin*) + AC_DEFINE([HAVE_APPLE_OPENGL_FRAMEWORK], [1], + [Use the Apple OpenGL framework.]) + GL_LIBS="-framework GLUT -framework OpenGL -framework Carbon -framework AGL" + have_glut=yes + have_glu=yes + have_gl=yes + ;; + *) + have_gl_headers=yes + AC_CHECK_HEADERS(GL/gl.h GL/glu.h GL/glext.h GL/glut.h, , + [have_gl_headers=no], + [[#ifdef WIN32 + #include + #endif + #if HAVE_GL_GL_H + #include + #endif + #if HAVE_GL_GLU_H + #include + #endif + ]]) + have_gl=no + have_glu=no + have_glut=no + TEMP_LDFLAGS="$LDFLAGS" + AC_CHECK_LIB(GL, main, [GL_LIBS="-lGL"; have_gl=yes]) + AC_CHECK_LIB(GLU, main, [GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes], , -lGL) + AC_CHECK_LIB(GLUT, main, [GL_LIBS="-lGLUT -LGLU $GL_LIBS"; have_glut=yes], ,-lGLUT) + AC_CHECK_LIB(opengl32, main, [GL_LIBS="-lopengl32"; have_gl=yes]) + AC_CHECK_LIB(glu32, main, [GL_LIBS="-lglu32 $GL_LIBS"; have_glu=yes], , -lopengl32) + LDFLAGS="$TEMP_LDFLAGS" + if test $have_gl = no -o $have_glu = no -o $have_gl_headers = no; then + if test x$enable_demos = xyes; then + AC_MSG_WARN([Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See `config.log' for details.]) + fi + enable_demos=no + else + AC_MSG_NOTICE([Found OpenGL]) + fi + ;; +esac + + + +AC_SUBST(GL_LIBS) + + +if test "x$enable_demos" != xno; then + AC_MSG_NOTICE([Building Bullet demos]) + AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS],[true]) +fi + + + +AC_ARG_ENABLE([debug], + [AC_HELP_STRING([--enable-debug], + [build with debugging information (default NO)])], + [], [enable_debug=no]) + +AC_MSG_CHECKING([build mode]) +AS_IF([test $enable_debug = yes], [build_mode=debug], [build_mode=optimize]) +AC_MSG_RESULT([$build_mode]) + + + +CFLAGS="$ARCH_SPECIFIC_CFLAGS $CFLAGS" +CXXFLAGS="$ARCH_SPECIFIC_CFLAGS $CXXFLAGS $CFLAGS" +#---------------------------------------------------------------------------- +# Emit generated files. +#---------------------------------------------------------------------------- +AC_CONFIG_FILES([bullet.pc Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/OpenGL/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile]) +AC_OUTPUT + +AC_MSG_NOTICE([ + +Please type 'make' to build Bullet +]) diff --git a/convex0.bin b/convex0.bin new file mode 100644 index 0000000000000000000000000000000000000000..83493fca3834f02b26c09a25e2a5d77f515bc876 GIT binary patch literal 548 zcmY+ADNhA46oor8ovoRDGZ;`95*G8!n>IKc{{TmVCt*nt!w*0}o$qIttJ4 z0D>a~6!-SEq15#B&guD1rz2_&)1NO1YPeuij(T=*&hdm62Hi)L^. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/docs/BulletQuickstart.pdf b/docs/BulletQuickstart.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7af5ce1ed2f296bd1ad1790e862658eba906ba24 GIT binary patch literal 147920 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

  3. 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 VojmH>-js`l6P1QWLS7Q}-vBF5YF+>U literal 0 HcmV?d00001 diff --git a/docs/BulletQuickstart.tex b/docs/BulletQuickstart.tex new file mode 100644 index 0000000..c724267 --- /dev/null +++ b/docs/BulletQuickstart.tex @@ -0,0 +1,106 @@ + +% Bullet Physics manual +% http://bulletphysics.org +% Written by Erwin Coumans + +% Preamble (global definitions of the book/manual) +% Use openany option for documentclass to avoid empty page after TOC + +%\documentclass[openany]{book} +%scrbook is easier on the eyes, and use a bigger font +\documentclass[openany,DIV=calc,16pt]{scrbook} + +% The english package can help breaking words +\usepackage[english]{babel} + +%The Charter or Utopia font is easier on the eyes for screen +\renewcommand{\familydefault}{bch}%Charter font +%\renewcommand{\familydefault}{put} %Utopia font + + +% Titlepic allows us to use a picture on the frontpage +\usepackage{titlepic} +\usepackage{graphicx} + +\usepackage[a4paper, left=2cm, right=1cm, top=2cm, bottom=3.5cm]{geometry} +\usepackage[latin1]{inputenc} + +% If using \doublespacing include the setspace package +% \usepackage{setspace} +\usepackage{fancyhdr} +\usepackage{tocloft} + + +% The hyperref package already include package url +\usepackage[colorlinks=true]{hyperref} +% \setcounter{secnumdepth}{4} +\usepackage{makeidx}\makeindex + +%support for C++ source code snippets +%you can even import existing C++ code as-is +%or a range of lines within markers beween rangeprefix/rangesuffix +\usepackage{listings} +\usepackage{color} +\renewcommand{\lstlistingname}{Source Code} +\renewcommand{\lstlistlistingname}{Source Code Listings} +\lstset{ + tabsize=2, language=C++, keywordstyle=\color[rgb]{0,0,1}, + commentstyle=\color[rgb]{0.133,0.545,0.133}, + stringstyle=\color[rgb]{0.627,0.126,0.941}, + breaklines=true, + numberstyle=\tiny, + basicstyle=\ttfamily\tiny, + rangeprefix=///-----, rangesuffix=-----, + includerangemarker=false, + numbers=left, stepnumber=1, + frame=single, +} + + +% Set the tolerance so TeX really breaks the line +% and don't run into the right margin (avoid overfull boxes) +\tolerance=10000 + +%end of preamble + +\begin{document} + +% \pagestyle{fancy} + +%\pagenumbering{} +% + \title{\textbf{Bullet 2.81 Quickstart Guide}} + \titlepic{\includegraphics[width=0.7\textwidth]{bullet_logo_2010_9.eps}} +% + \author{Erwin Coumans} + \maketitle + + + \renewcommand{\cftchapdotsep}{\cftdotsep} + \tableofcontents + + + \pagenumbering{arabic} + +% \fancyhf{} +% \doublespacing + +% include all the chapters as separate tex files +% on Mac OSX it is really nice to use the Texpad application for automatic navigation + + \include{intro} + \include{building} + \include{helloworld} + \include{faq} + + \clearpage + \addcontentsline{toc}{chapter}{Source code listings} + \lstlistoflistings + + \clearpage + \addcontentsline{toc}{chapter}{Index} + \printindex + + +\end{document} + diff --git a/docs/building.tex b/docs/building.tex new file mode 100644 index 0000000..a4dd8a7 --- /dev/null +++ b/docs/building.tex @@ -0,0 +1,45 @@ +\chapter{Building the Bullet SDK and demos} +Windows developers can download the zipped sources of Bullet from \url{http://bullet.googlecode.com}. Mac OS X, Linux and other developers should download the gzipped tar archive. +Bullet provides several build systems. + +\section{Microsoft Visual Studio} +After unzipping the source code you can open the \path{Bullet/build/vs2010/0BulletSolution.sln}, hit F5 and your first Bullet demo will run. Note that by default Visual Studio uses an unoptimized Debug configuration that is very slow. It is best to enable the Release configuration. + +\section{Using Premake} +\index{premake}\href{http://industriousone.com/premake}{Premake} is a meta build system based on the Lua scripting language that can generate project files for Microsoft Visual Studio, Apple Xcode as well as Makefiles for GNU make and other build systems. Bullet comes with Premake executables for Windows, Mac OSX and Linux. +\subsection{Premake Visual Studio project generation} +You can double-click on \path{Bullet/build/vs2010.bat} to generate Visual Studio 2010 project files and solution. This batch file calls Premake. Just open \path{Bullet/build/vs2010/0BulletSolution.sln} +\subsection{Premake Mac OSX Xcode project generation} +On Mac OSX it is easiest to open a Terminal window and switch current directory to Bullet/build and use the following command to generate XCode projects: + \begin{lstlisting}[caption=Premake for Mac OSX, label=premake_osx] +cd Bullet/build +./premake_osx xcode4 +open xcode4/0BulletSolution.xcworkspace +\end{lstlisting} + +\subsection{Premake iOS Xcode project generation} +XCode project generation for iOS, such as iPhone and iPad, is similar to Mac OSX. Just provide the --ios option to premake and premake will automatically customize the project and append ios to the directory: + \begin{lstlisting}[caption=Premake for iOS, label=premake_ios] +cd Bullet/build +./premake_osx --ios xcode4 +open xcode4ios/0BulletSolution.xcworkspace +\end{lstlisting} +Note that Bullet comes with a modified version of \path{premake_osx} that enables the iOS specific customizations that are required by XCode. +\subsection{Premake GNU Makefile generation} +You can also generate GNU Makefiles for Mac OSX or Linux using premake: +\begin{lstlisting}[caption=Premake to GNU Makefile, label=premake_make] +cd Bullet/build +./premake_osx gmake +cd gmake +make config=release64 +\end{lstlisting} +\section{Using cmake} +Similar to premake, CMake adds support for many other build environments and platforms, including Microsoft Visual Studio, XCode for Mac OSX, KDevelop for Linux and Unix Makefiles. Download and install \index{CMake}CMake from \url{http://cmake.org} and use the CMake cmake-gui tool. +\section{Using autotools} +Open a shell terminal and go to the Bullet root directory. Then execute +\begin{lstlisting}[caption=autotools to Makefile, label=autotools_make] +./autogen.sh +./configure +make +\end{lstlisting} +The \path{autogen.sh} step is optional and not needed for downloaded packages. diff --git a/docs/bullet_logo_2010_9.eps b/docs/bullet_logo_2010_9.eps new file mode 100644 index 0000000..b4061d3 --- /dev/null +++ b/docs/bullet_logo_2010_9.eps @@ -0,0 +1,1815 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: cairo 1.8.6 (http://cairographics.org) +%%CreationDate: Sat Feb 06 02:01:21 2010 +%%Pages: 1 +%%BoundingBox: 0 0 262 96 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +/cairo_eps_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +/q { gsave } bind def +/Q { grestore } bind def +/cm { 6 array astore concat } bind def +/w { setlinewidth } bind def +/J { setlinecap } bind def +/j { setlinejoin } bind def +/M { setmiterlimit } bind def +/d { setdash } bind def +/m { moveto } bind def +/l { lineto } bind def +/c { curveto } bind def +/h { closepath } bind def +/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto + 0 exch rlineto 0 rlineto closepath } bind def +/S { stroke } bind def +/f { fill } bind def +/f* { eofill } bind def +/B { fill stroke } bind def +/B* { eofill stroke } bind def +/n { newpath } bind def +/W { clip } bind def +/W* { eoclip } bind def +/BT { } bind def +/ET { } bind def +/pdfmark where { pop globaldict /?pdfmark /exec load put } + { globaldict begin /?pdfmark /pop load def /pdfmark + /cleartomark load def end } ifelse +/BDC { mark 3 1 roll /BDC pdfmark } bind def +/EMC { mark /EMC pdfmark } bind def +/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def +/Tj { show currentpoint cairo_store_point } bind def +/TJ { + { + dup + type /stringtype eq + { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse + } forall + currentpoint cairo_store_point +} bind def +/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore + cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def +/Tf { pop /cairo_font exch def /cairo_font_matrix where + { pop cairo_selectfont } if } bind def +/Td { matrix translate cairo_font_matrix matrix concatmatrix dup + /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point + /cairo_font where { pop cairo_selectfont } if } bind def +/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def + cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def +/g { setgray } bind def +/rg { setrgbcolor } bind def +/d1 { setcachedevice } bind def +%%EndProlog +11 dict begin +/FontType 42 def +/FontName /f-0-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0042 put +Encoding 2 /uni0055 put +Encoding 3 /uni004C put +Encoding 4 /uni0045 put +Encoding 5 /uni0054 put +/CharStrings 6 dict dup begin +/.notdef 0 def +/uni0042 1 def +/uni0055 2 def +/uni004C 3 def +/uni0045 4 def +/uni0054 5 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700021f090000003680000004a63767420b6ae99420000 +03b40000055c6670676ddcad863100000910000005a9676c7966fa0e9463000000ac000002bc +68656164d015fad800000ebc00000036686865611123079400000ef400000024686d747818d9 +025600000f18000000186c6f636102ea023a00000f300000000e6d61787003b504ac00000f40 +0000002070726570fbaaa82600000f600000073c00020100000005000500000300070050b105 +04b80126b2000607bb012600020001020cb50303000a0605b80125b60303024a090704b80125 +b4010049089fb9011e00182b4e10f43c4df53c4e10f63c4d10f53c003f3c10fd3cf53c10f53c +3130211121112521112101000400fc2003c0fc400500fb002004c00000000003005400000428 +06530011001b00230045b5080518080813b8024340121c1c121d77110812770002057f181820 +7f0cb80249b625121d65115d2410f6fd3c10f6fd3c10ed003fed3fed12392fed19392f011112 +3931301321321e01151406071e011d01140e01232101113633323635342e0103113e013d0134 +265401a4c7cd7e598392684ba4fefe1901a51b0f3e221c2d4159312c06533ebdd28e701e2199 +9e96a49e3a053efe98013d904c3d10fd9dfe3b03326297682c0000000001004effde04110653 +001500224009150d11770609146501b80249b5170e650b5d1610f6ed10f4ed003fed2f3c3130 +0111140e0223222e02190121111416333236351104111876c18391de6e1401a5172328170653 +fbc6b8959d51609aab011203befb426a3b417904a90000010054000002f906530005001a400d +028504080503d0070165045d0610f6ed10e6002f3fed313001112111211101f90100fd5b0653 +faf1febc0653000100540000032e0653000b003fb900040245402060070107070b0385000209 +850b080916134309090d020205790d0308650b5d0c10f6fd3c10f4392f11392f2b003fed3ffd +11392f71ed31301321112111211121112111215402befee70107fef90135fd260653febcfecd +feccfe9cfebc00000001000c000003a4065300070040402401068507040802656f05010f051f +055f05bf05df05ef050620056f0502050506019609062f10e4014bb03250587c5911392f185d +7172ed003f2ffd3c3130011123112111231103a4fafe5bf90653febcfaf1050f014400000000 +0002000300000000001400010000000000340004002000000004000400010000f005ffff0000 +f000ffff10000001000000000006001600000000000600000001000200030004000500000653 +00000653002206530022052f00180000ffde0000ffe80000ffdeff43ffd80653000000000000 +0342ffed066e000000000000000000000000000000000000000000000000000005e600000000 +0000000000000000000000000000000000000000000000000227000000000000000000000000 +00000000000000000000000000000000000000000000000001a1000001a10000000000000000 +000000000000000000000000000000000024003f00410055ffdb00ea006700eb0054003c0071 +0048ffbd00040025019401a5000701940008000c004300c9014b00f9010003c2ffc000480043 +0062009a00f000f4011203a2ffab008e0194000c00d2013001a5008d000c001c004000cb0144 +017d03cf0001000c0025011501310144017b0026005800f4012f016a0194ffb7ffdbfff40000 +00200024003b005f007e00d20100015ffff40008000c004f00540060013d02140266000c001a +0022002500490076009400b900c000c500d5013801680169016d016e018701af023102ac030b +03c20410ffca0008003f004c0081008400a600ac0108010f01140137014f01940195ffe70001 +000c00300054004e0062006900720075009700cf00d800f600f900f9010b0123012a01440163 +017e019401d8024f02670279038904afffabffc7fff3000300240033003600390056005b0075 +00780081009200930095009b009c00a500b100c700c900cc00cd00cf00d500db00e600f00100 +010b010e010f0114011c012a014a0153016001690176017c018601a001c901e402a505940691 +ff00ff69ff7dfff4000b000c001600200020002100310032003e00430048004b004e00540055 +00550058005e0066006800710074007400750079007f00810085008500910096009700980098 +009b00a200a500b100b900bb00bc00c100c300d300d500d600e200ef00f200f50105010a0118 +011a01260144014c017001720185018b01920194019f01a301af01b801bc01bd01f701fc021a +021f022b0242024702500259027a02c502da02db03040336034c038b039703ac03dc03ee03f4 +0402042f047804c30513054306070693fe11fecfff0dff2dff96ffabffafffc9000300080013 +001d002200230024002400250028002b00360039004d004d004e004f00510054005400610069 +007300730074007400740081008e008f009a009d00a400a500a500ae00ae00b000b700bd00c3 +00c400c900ce00d900dc00e600ee00f000f300f300f400f800fa010001020103011d011f0121 +012201230125013201380139014101410146014a014d0168016a0171017a017a01820187018b +01940195019a01a501a501c001c001c001d301d401ef01fa01fd021302360237024502460247 +024f025a026a027a0283029202a502ab02b103040308031f03340376037c039d03a703bd03bf +03e103fa040a04250428044804770483049204cc0500050f056105640567059c05e405ed05fc +068406b70710075c079b07eb0818019401a50194000000000000000000000000000000eb00eb +014400eb019401a501940048ffb70027ffd9000afff602310054ffab0030ffd0000afff6024e +0027ffd900f90014000cfff4019001b800fc011f013400d201870031ffb1ffdb00fc009601d2 +0170017d01490094017d0077028300ef0168016801cc00fe01b6013d017a010f01bc01690221 +00ba0374007e020b00c7011d008900e0010c012800f60066019e0085008f00d3002501580274 +023c0152029902c90037024f00ac03a600f4027a00a6010000f7022c00e50254ffe7054b0270 +021800f2018a018a0300030000ac00ac007f005c004f00ac00a500b00011003f012800ec013a +00ce020b00400084018501540052042f01ea01c0011e0037003e023c0217020d01f801e20225 +047b404044434241403f3e3d3c383734333231302f2e2d2c2b2a292827262524232221201f1e +1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201002c4523466020b026 +60b004262348482d2c452346236120b02661b004262348482d2c45234660b0206120b04660b0 +04262348482d2c4523462361b0206020b02661b02061b004262348482d2c45234660b0406120 +b06660b004262348482d2c4523462361b0406020b02661b04061b004262348482d2c0110203c +003c2d2c20452320b0cd442320b8015a51582320b08d44235920b0ed51582320b04d44235920 +b0042651582320b00d44235921212d2c20204518684420b001602045b04676688a4560442d2c +01b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0462370b101463e01b0462370b10246 +453ab10200080d2d2c45b04a234445b04923442d2c2045b00325456164b050515845441b2121 +592d2cb00143632362b0002342b00f2b2d2c2045b0004360442d2c01b00643b00743650a2d2c +2069b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b00361592d2c45b0112bb0 +472344b0477ae4182d2cb801a65458b00943b801005458b9004aff80b14980444459592d2cb0 +1243588745b0112bb0472344b0477ae41b038a45186920b04723448a8a8720b0a05158b0112b +b0472344b0477ae41b21b0477ae45959182d2c2d2c4b52582145441b23458c20b00325455258 +441b212159592d2c01182f2d2c20b0032545b049234445b04a23444565234520b00325606a20 +b009234223688a6a606120b01a8ab000527921b21a4a40b9ffe0004a45208a54582321b03f1b +235961441cb114008a5279b34940204945208a54582321b03f1b235961442d2cb11011432343 +0b2d2cb10e0f4323430b2d2cb10c0d4323430b2d2cb10c0d432343650b2d2cb10e0f43234365 +0b2d2cb11011432343650b2d2c4b525845441b2121592d2c0120b003252349b04060b0206320 +b000525823b002253823b002256538008a63381b212121212159012d2c4569b00943608a103a +2d2c01b005251023208af500b0016023edec2d2c01b005251023208af500b0016123edec2d2c +01b0062510f500edec2d2c20b001600110203c003c2d2c20b001610110203c003c2d2cb02b2b +b02a2a2d2c00b00743b006430b2d2c3eb02a2a2d2c352d2c76b04b23701020b04b4520b00050 +58b00161593a2f182d2c21210c6423648bb84000622d2c21b08051580c6423648bb82000621b +b200402f2b59b002602d2c21b0c051580c6423648bb81555621bb200802f2b59b002602d2c0c +6423648bb84000626023212d2cb4000100000015b00826b00826b00826b008260f1016134568 +3ab001162d2cb4000100000015b00826b00826b00826b008260f1016134568653ab001162d2c +4523204520b10405258a505826618a8b1b26608a8c59442d2c462346608a8a462320468a608a +61b8ff8062232010238ab14b4b8a70456020b0005058b00161b8ffba8b1bb0468c59b0106068 +013a2d2cb0332bb02a2a2d2cb0134358031b02592d2cb0134358021b03592d2c01b0022545b0 +0225456460b0408b6ab00325456a6120b00425456a208a8b65b0042523448cb0032523442121 +2d2c01456823456961b00325456a6120b00425456a208a8b65b0042523448cb0032523442121 +2d2c018a8a45642345646164422d2c01b0022543b04054b0022543b000545a58b003252045b0 +40614459b0022543b00054b0022543b040545a58b004252045b040604459212121212d2c014b +525843b00225452361441b2121592d2c014b525843b00225452360441b2121592d2c4b5258b0 +0425b0042549b00425b00425496120b0005458212043b0005558b00325b00325b8ffc038b8ff +c038591bb04054582043b0005458b00225b8ffc038591b2043b0005458b00325b00325b8ffc0 +38b8ffc0381bb00325b8ffc03859595959212121212d2c4b52584365381b2121592d2c4b5258 +43381b2121592d000000000100000005000085924a7a5f0f3cf5001b080000000000a692c6fa +00000000c142e82dfef7fd5b0a170958000000090001000000000000000100000812fe500000 +0a46fef7fef70a1700010000000000000000000000000000000606000100046b00540460004e +030b00540353005403b0000c0000003e009c00d200f0012a015e000000010000000600f2003c +0052000500020010002f004500000315033600030001b902a202a3b22a1f30be02a3007002a3 +00c002a300030116b6651f1f00d601d6b8024cb22a1f8bb80245b5141fb074321fb8025db28c +391fb80155b25c241fb801e4b2941f1fbd028a02890032001f0154027c4017641f306c406c50 +6c036c94151f9394301f37ab54341f00ba026f00c0026fb402ba7f341fbc029a02980023001f +029fb294141fb8029eb294321fb80165b265331fb80289b265321fb80113b265141fb8024eb3 +65281f50410a0282006002820070028200e0028200040280027fb22f1f30411d027f0040027f +0050027f00030030027f0040027f00b0027f00c0027f00040030027f0040027f0050027f0060 +027f00b0027f00c0027f00d0027fb507d067e06702b801d5b267151fb8025cb2941f1fb8025e +b2941e1fb80114b394151f4fbe0256008f025600cf025600030256401086361fb686361f2086 +40868086c08604b80252401186361f8694361f00464600000012110840b8021cb41809180990 +be01d200070090015f00070090010540160790e90790a907907e07905f07905b079058079056 +07410a024002340064001f023f02380064001f01210239b2641faabc02380064001f018a0235 +b2641f95b80235b2641f71b80234b2641f70bb0112000102a60236b2651fd041090239002800 +1f024a02370065001f02490235b2651f05bc02340065001f01630235b2651fd4b80234b2651f +9ab80236b2651f96b80239b2651f89b80236b2651f81b80239b2651f79b80235b2651f5db802 +34b2651f53410902340065001f028402320065001f02a0022db2651f55b80231b21e1f984111 +02320065001f023c022e0042001f023b022d0042001f023c02300065001f023b022fb2651f61 +b8022eb2651f60b8022db2651f5e4109022d0065001f023900160800004002360237b216173f +4109023602370017003e02360237003c02340235b3163e090fba0235001f0235b2023d3f4122 +0235006f02350002008002340001023402350065023a003d005f0234008f0234009f023400af +023400bf02340005000f0234001f023400020232001408000040022f0230b214153f4109022f +02300015003e022f0230003c022d022eb3143e096f4112022e007f022e00af022e00ef022e00 +04000f022e001f022e004f022e00b0022d00f0022db205400fb8022eb2013910411a022d0020 +022d0050022d0090022d0004003f022e007f022e00af022e00e0022d000400cf022e00ff022e +0002022d022e00940233b23d09dfbb022d0001000f022db201451f410d022d000100bf022d00 +ef022d00ff022d0003001f022d004f022db502b865321f6dbb022900c8001f0246b35c081f5c +b80229b2081f77bb02280014001f0245b2851e1fb80244b385281fe0ba024300010243b3851e +1f85bc02280014001f01dc021db2641f67b8021db2321f94b8021eb2961f7bb8021eb2961fbb +bb022b0026001f024fb265291fb8024eb365321f30410e011200900112000200400112008001 +1200d0011200e0011200040112b265081fb80242b265261fb80113b265321fb80241b365291f +65bc021d00fa001f0187021db2081f7fb8021db3fa1f0900b8021eb20145b0410a021d00d002 +1e0002022c022a0032001f022b022ab2321f374112022902270008001f022802270014001f02 +1e021c0032001f021d021c0032001f022a021cb3321f3710410d021c00b0021c000200c0021c +0001022702260014001f021c0226402b081f2408220820081e081c081a081808160814081208 +10080e080c080a0808080608040802080008002038014bb0c063004b6220b0f65323b8010a51 +5ab005234201b0124b004b544218b013034b024b5342b0382b4bb8080052b0372b4bb009505b +58b101018e59b0382bb00288b801005458b80119b101018e851bb0124358b90001012c858d1b +b90001012c858d59592b1db0644b5358b0781d59b0324b5358b0901d5900162b2b2b2b2b2b2b +2b2b2b2b2b2b2b2b2b2b2b2b18012b002b01b9021c021c457d69441873742b2b012b2b002b2b +2b2b2b755e735e012b2b2b2b2b2b2b73742b2b2b2b2b2b2b002b2b732b2b2b2b2b2b2b737475 +5e73745e2b7374755e735e73745e2b2b2b2b2b73742b74755e735e2b2b2b2b2b2b2b2b2b2b2b +2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b732b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b01 +4b5079bc001f01980007001f0135b6071fe0071f73072b2b2b2b4b5379bc0090019800070090 +0135b60790e0079073072b2b2b2b180145695342014b5058b108004259435c58b108004259b3 +020b0a124358601b2159421610703eb0124358b93b21187e1bba040001a8000b2b59b00c2342 +b00d2342b0124358b92d412d411bba04000400000b2b59b00e2342b00f2342b0124358b9187e +3b211bba01a80400000b2b59b0102342b0112342012b2b732b2b732b2b2b2b757374752b732b +2b2b2b2b2b2b2bb802a14568b060456a61b061456a60b0944569206061b8026f2344732b2b2b +2b742b2b002b2b2b2b2b2b752b732b00b0034568b802954568b0408b60b0202344b0074568b8 +02964568b0408b60b022234400> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-1-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0050 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0050 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001740000004263767420178b170c0000 +01b8000000986670676d97486b110000025000000619676c7966b4278d95000000ac000000c8 +68656164ee14e98a0000086c00000036686865610ea7036e000008a400000024686d747808fb +0120000008c8000000086c6f636100640014000008d0000000066d61787002590395000008d8 +0000002070726570ee7b813d000008f80000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000200a0000004a10528000c0019004a +400a061e9013a013b0130313b8ffc04010090f4813130c1b0a0d1eb00cc00c020cb8ffc0400e +080c480c0d1f09090b0d191f0010003fed3f392fed012f2b5dfdc41112392f2b5ded31301321 +321e02151404232111231321323e0235342e022321a001fa66bc8f56ff00fcfef1f6f6011444 +5f3c1c29475d33fef10528235b9b78d3d3fe0f02d31931472f3945270d000000000200030000 +0000001400010000000000340004002000000004000400010000f001ffff0000f000ffff1000 +0001000000000006000e000000000002000000010000052805280000ffec00f600d200d400fa +00f600b70102009201890000ffea00db0528053e03bb03d2ffeafe7cfe900444028e00000000 +00000000000000f000dc00c800d200b2008a00d7000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000403b5451504f4e4d4c4b4a4948474645 +44434241403f3e3d3c3b3a39383736352f2e2d2c2826252423221f181411100f0d0b0a090807 +060504030201002c4523466020b02660b004262348482d2c452346236120b02661b004262348 +482d2c45234660b0206120b04660b004262348482d2c4523462361b0206020b02661b02061b0 +04262348482d2c45234660b0406120b06660b004262348482d2c4523462361b0406020b02661 +b04061b004262348482d2c0110203c003c2d2c20452320b0cd442320b8015a51582320b08d44 +235920b0ed51582320b04d44235920b0042651582320b00d44235921212d2c20204518684420 +b001602045b04676688a4560442d2c01b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0 +282370b101283e01b0282370b10228453ab10200080d2d2c2045b00325456164b05051584544 +1b2121592d2c2045b0004360442d2c01b00643b00743650a2d2c2069b04061b0008b20b12cc0 +8a8cb8100062602b0c642364615c58b00361592d2c8a03458a8a87b0112bb0292344b0297ae4 +182d2c4565b02c234445b02b23442d2c4b525845441b2121592d2c01b005251023208af500b0 +016023edec2d2c01b005251023208af500b0016123edec2d2c01b0062510f500edec2d2c20b0 +01600110203c003c2d2c20b001610110203c003c2d2c00b00743b006430b2d2c21210c642364 +8bb84000622d2c21b08051580c6423648bb82000621bb200402f2b59b002602d2c21b0c05158 +0c6423648bb81555621bb200802f2b59b002602d2c0c6423648bb84000626023212d2c452345 +6023456023456023766818b08062202d2cb00426b00426b00425b0042545234520b003266062 +636820b0032661658a2344442d2c2045b0005458b040442045b04061441b2121592d2c45b130 +2f4523456160b0016069442d2c4b5158b02f2370b01423421b2121592d2c4b515820b0032545 +695358441b2121591b2121592d2c45b01443b0006063b0016069442d2cb02f45442d2c452320 +458a60442d2c45234560442d2c4b235158b90033ffe0b134201bb3330034005944442d2cb016 +4358b00326458a586466b01f601b64b020606620581b21b04059b001615923586559b0292344 +2310b029e01b2121212121592d2cb0164358b004254564b020606620581b21b04059b0016123 +586559b0292344b00425b00725082058021b0359b0052510b004252046b0042523423cb00725 +10b006252046b00425b0016023423c2058011b0059b0052510b00425b029e0b0072510b00625 +b029e0b00425b00725082058021b0359b00425b003254348b00625b00325b0016043481b2159 +212121212121212d2cb0164358b004254564b020606620581b21b04059b0016123581b6559b0 +292344b00525b00825082058021b0359b0042510b005252046b0042523423cb00425b0072508 +b0072510b006252046b00425b0016023423c2058011b0059b0042510b00525b029e0b0292045 +6544b0072510b00625b029e0b00525b00825082058021b0359b00525b003254348b00425b007 +2508b00625b00325b0016043481b2159212121212121212d2c02b00425202046b004252342b0 +052508b003254548212121212d2c02b0032520b0042508b0022543482121212d2c4523204518 +20b00050205823652359236820b040505821b04059235865598a60442d2c4b53234b515a5820 +458a60441b2121592d2c4b545820458a60441b2121592d2c4b53234b515a58381b2121592d2c +4b5458381b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a5823381b2121592d2c00 +208a49b0005158b04023208a3812341b2121592d2c462346608a8a462320468a608a61b8ff80 +62232010238ab14b4b8a70456020b0005058b00161b8ffba8b1bb0468c59b0106068013a2d2c +208a2349648a2353583c1b21592d2cb1020042b123018851b1400188535a58b9100000208854 +58b202010243604259b12401885158b920000040885458b2020202436042b12401885458b202 +2002436042004b014b5258b2020802436042591bb940000080885458b202040243604259b940 +00008063b80100885458b202080243604259b94000010063b80200885458b202100243604259 +b94000020063b80400885458b202400243604259595959592d000000000100000005e666e562 +51eb5f0f3cf5001b080000000000c3738d9600000000c5c82d5ffb20fab90a84087800010009 +0002000000000000000100000800fab801000aa2fb20fe110a84000100000000000000000000 +0000000000020400008004fb00a00000001400640000000100000002007f0008008700070002 +001000400055000001df024c0003000140590704181f24042b1f1f05271f1e04271fbf0401af +04019f04013f04012f04011f04010f04011615231f1110231f13122c1f0302231f140d231f0e +0d231f0100231f2f17012f15012f14012f0d012f02012f10012f12012f0001b1020042b21711 +018820b022518a2378b0405278b10a2088b810005578b1020142b0031c212101b0124b004b54 +42b013014b004b5342b0024358004bb03c524bb008505b58b101018e591b4bb80190524bb008 +505b58b101018e5959b00288b8010054b00488b8020054b012435a5b58b80119b101018e851b +b900010100b04b60858d59b0501db0644b5358b0801d59b0324b5358b0901d59007373737373 +7373732b2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-2-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0048 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0048 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001580000004263767420178b170c0000 +019c000000986670676d97486b110000023400000619676c79663224714e000000ac000000ac +68656164ee14e98a0000085000000036686865610ea7036e0000088800000024686d74780962 +0120000008ac000000086c6f636100560014000008b4000000066d61787002590395000008bc +0000002070726570ee7b813d000008dc0000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000100a0000004c20528000b00554025 +0b1e0910012001300103000110012001d0010401010d0603071e000601b006c006e0060306b8 +ffc0400f080c4806091f020201070b1004010d003fc43fc412392fed012f2b5d71fdc4111239 +2f5d71c4ed313021231121112311331121113304c2f8fdccf6f60234f80249fdb70528fe0401 +fc0000000002000300000000001400010000000000340004002000000004000400010000f001 +ffff0000f000ffff10000001000000000006000e000000000002000000010000052805280000 +ffec00f600d200d400fa00f600b70102009201890000ffea00db0528053e03bb03d2ffeafe7c +fe900444028e0000000000000000000000f000dc00c800d200b2008a00d70000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000403b5451504f +4e4d4c4b4a494847464544434241403f3e3d3c3b3a39383736352f2e2d2c2826252423221f18 +1411100f0d0b0a090807060504030201002c4523466020b02660b004262348482d2c45234623 +6120b02661b004262348482d2c45234660b0206120b04660b004262348482d2c4523462361b0 +206020b02661b02061b004262348482d2c45234660b0406120b06660b004262348482d2c4523 +462361b0406020b02661b04061b004262348482d2c0110203c003c2d2c20452320b0cd442320 +b8015a51582320b08d44235920b0ed51582320b04d44235920b0042651582320b00d44235921 +212d2c20204518684420b001602045b04676688a4560442d2c01b10b0a432343650a2d2c00b1 +0a0b4323430b2d2c00b0282370b101283e01b0282370b10228453ab10200080d2d2c2045b003 +25456164b050515845441b2121592d2c2045b0004360442d2c01b00643b00743650a2d2c2069 +b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b00361592d2c8a03458a8a87b0 +112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c4b525845441b2121592d2c01 +b005251023208af500b0016023edec2d2c01b005251023208af500b0016123edec2d2c01b006 +2510f500edec2d2c20b001600110203c003c2d2c20b001610110203c003c2d2c00b00743b006 +430b2d2c21210c6423648bb84000622d2c21b08051580c6423648bb82000621bb200402f2b59 +b002602d2c21b0c051580c6423648bb81555621bb200802f2b59b002602d2c0c6423648bb840 +00626023212d2c4523456023456023456023766818b08062202d2cb00426b00426b00425b004 +2545234520b003266062636820b0032661658a2344442d2c2045b0005458b040442045b04061 +441b2121592d2c45b1302f4523456160b0016069442d2c4b5158b02f2370b01423421b212159 +2d2c4b515820b0032545695358441b2121591b2121592d2c45b01443b0006063b0016069442d +2cb02f45442d2c452320458a60442d2c45234560442d2c4b235158b90033ffe0b134201bb333 +0034005944442d2cb0164358b00326458a586466b01f601b64b020606620581b21b04059b001 +615923586559b02923442310b029e01b2121212121592d2cb0164358b004254564b020606620 +581b21b04059b0016123586559b0292344b00425b00725082058021b0359b0052510b0042520 +46b0042523423cb0072510b006252046b00425b0016023423c2058011b0059b0052510b00425 +b029e0b0072510b00625b029e0b00425b00725082058021b0359b00425b003254348b00625b0 +0325b0016043481b2159212121212121212d2cb0164358b004254564b020606620581b21b040 +59b0016123581b6559b0292344b00525b00825082058021b0359b0042510b005252046b00425 +23423cb00425b0072508b0072510b006252046b00425b0016023423c2058011b0059b0042510 +b00525b029e0b02920456544b0072510b00625b029e0b00525b00825082058021b0359b00525 +b003254348b00425b0072508b00625b00325b0016043481b2159212121212121212d2c02b004 +25202046b004252342b0052508b003254548212121212d2c02b0032520b0042508b002254348 +2121212d2c452320451820b00050205823652359236820b040505821b04059235865598a6044 +2d2c4b53234b515a5820458a60441b2121592d2c4b545820458a60441b2121592d2c4b53234b +515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a +5823381b2121592d2c00208a49b0005158b04023208a3812341b2121592d2c462346608a8a46 +2320468a608a61b8ff8062232010238ab14b4b8a70456020b0005058b00161b8ffba8b1bb046 +8c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1020042b123018851b1400188 +535a58b910000020885458b202010243604259b12401885158b920000040885458b202020243 +6042b12401885458b2022002436042004b014b5258b2020802436042591bb940000080885458 +b202040243604259b94000008063b80100885458b202080243604259b94000010063b8020088 +5458b202100243604259b94000020063b80400885458b202400243604259595959592d000000 +000100000005e666e8b68b915f0f3cf5001b080000000000c3738d9600000000c5c82d5ffb20 +fab90a840878000100090002000000000000000100000800fab801000aa2fb20fe110a840001 +0000000000000000000000000000000204000080056200a00000001400560000000100000002 +007f0008008700070002001000400055000001df024c0003000140590704181f24042b1f1f05 +271f1e04271fbf0401af04019f04013f04012f04011f04010f04011615231f1110231f13122c +1f0302231f140d231f0e0d231f0100231f2f17012f15012f14012f0d012f02012f10012f1201 +2f0001b1020042b21711018820b022518a2378b0405278b10a2088b810005578b1020142b003 +1c212101b0124b004b5442b013014b004b5342b0024358004bb03c524bb008505b58b101018e +591b4bb80190524bb008505b58b101018e5959b00288b8010054b00488b8020054b012435a5b +58b80119b101018e851bb900010100b04b60858d59b0501db0644b5358b0801d59b0324b5358 +b0901d590073737373737373732b2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-3-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0059 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0059 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001640000004263767420178b170c0000 +01a8000000986670676d97486b110000024000000619676c7966e625d8da000000ac000000b8 +68656164ee14e98a0000085c00000036686865610ea7036e0000089400000024686d7478093e +0099000008b8000000086c6f6361005c0014000008c0000000066d61787002590395000008c8 +0000002070726570ee7b813d000008e80000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000100190000052505280008005d4034 +07060708062405041405041b050105040708000107010824000114000114000100011e100420 +040204040103050800060510030d003f3fc4d4c411123939012f5dfddd5d872b1000c187057d +10c4011810dd5d872b087d10c431300101112311012101010525fdf6f7fdf5012a015d015b05 +28fd03fdd5022b02fdfdea021600000000020003000000000014000100000000003400040020 +00000004000400010000f001ffff0000f000ffff10000001000000000006000e000000000002 +000000010000052805280000ffec00f600d200d400fa00f600b70102009201890000ffea00db +0528053e03bb03d2ffeafe7cfe900444028e0000000000000000000000f000dc00c800d200b2 +008a00d700000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000403b5451504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a3938373635 +2f2e2d2c2826252423221f181411100f0d0b0a090807060504030201002c4523466020b02660 +b004262348482d2c452346236120b02661b004262348482d2c45234660b0206120b04660b004 +262348482d2c4523462361b0206020b02661b02061b004262348482d2c45234660b0406120b0 +6660b004262348482d2c4523462361b0406020b02661b04061b004262348482d2c0110203c00 +3c2d2c20452320b0cd442320b8015a51582320b08d44235920b0ed51582320b04d44235920b0 +042651582320b00d44235921212d2c20204518684420b001602045b04676688a4560442d2c01 +b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b101283e01b0282370b1022845 +3ab10200080d2d2c2045b00325456164b050515845441b2121592d2c2045b0004360442d2c01 +b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b0 +0361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c +4b525845441b2121592d2c01b005251023208af500b0016023edec2d2c01b005251023208af5 +00b0016123edec2d2c01b0062510f500edec2d2c20b001600110203c003c2d2c20b001610110 +203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000622d2c21b08051580c642364 +8bb82000621bb200402f2b59b002602d2c21b0c051580c6423648bb81555621bb200802f2b59 +b002602d2c0c6423648bb84000626023212d2c4523456023456023456023766818b08062202d +2cb00426b00426b00425b0042545234520b003266062636820b0032661658a2344442d2c2045 +b0005458b040442045b04061441b2121592d2c45b1302f4523456160b0016069442d2c4b5158 +b02f2370b01423421b2121592d2c4b515820b0032545695358441b2121591b2121592d2c45b0 +1443b0006063b0016069442d2cb02f45442d2c452320458a60442d2c45234560442d2c4b2351 +58b90033ffe0b134201bb3330034005944442d2cb0164358b00326458a586466b01f601b64b0 +20606620581b21b04059b001615923586559b02923442310b029e01b2121212121592d2cb016 +4358b004254564b020606620581b21b04059b0016123586559b0292344b00425b00725082058 +021b0359b0052510b004252046b0042523423cb0072510b006252046b00425b0016023423c20 +58011b0059b0052510b00425b029e0b0072510b00625b029e0b00425b00725082058021b0359 +b00425b003254348b00625b00325b0016043481b2159212121212121212d2cb0164358b00425 +4564b020606620581b21b04059b0016123581b6559b0292344b00525b00825082058021b0359 +b0042510b005252046b0042523423cb00425b0072508b0072510b006252046b00425b0016023 +423c2058011b0059b0042510b00525b029e0b02920456544b0072510b00625b029e0b00525b0 +0825082058021b0359b00525b003254348b00425b0072508b00625b00325b0016043481b2159 +212121212121212d2c02b00425202046b004252342b0052508b003254548212121212d2c02b0 +032520b0042508b0022543482121212d2c452320451820b00050205823652359236820b04050 +5821b04059235865598a60442d2c4b53234b515a5820458a60441b2121592d2c4b545820458a +60441b2121592d2c4b53234b515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c +2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0005158b04023208a3812341b +2121592d2c462346608a8a462320468a608a61b8ff8062232010238ab14b4b8a70456020b000 +5058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1 +020042b123018851b1400188535a58b910000020885458b202010243604259b12401885158b9 +20000040885458b2020202436042b12401885458b2022002436042004b014b5258b202080243 +6042591bb940000080885458b202040243604259b94000008063b80100885458b20208024360 +4259b94000010063b80200885458b202100243604259b94000020063b80400885458b2024002 +43604259595959592d000000000100000005e66680efbd0f5f0f3cf5001b080000000000c373 +8d9600000000c5c82d5ffb20fab90a840878000100090002000000000000000100000800fab8 +01000aa2fb20fe110a8400010000000000000000000000000000000204000080053e00190000 +0014005c0000000100000002007f0008008700070002001000400055000001df024c00030001 +40590704181f24042b1f1f05271f1e04271fbf0401af04019f04013f04012f04011f04010f04 +011615231f1110231f13122c1f0302231f140d231f0e0d231f0100231f2f17012f15012f1401 +2f0d012f02012f10012f12012f0001b1020042b21711018820b022518a2378b0405278b10a20 +88b810005578b1020142b0031c212101b0124b004b5442b013014b004b5342b0024358004bb0 +3c524bb008505b58b101018e591b4bb80190524bb008505b58b101018e5959b00288b8010054 +b00488b8020054b012435a5b58b80119b101018e851bb900010100b04b60858d59b0501db064 +4b5358b0801d59b0324b5358b0901d590073737373737373732b2b2b2b2b2b2b737373737373 +732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-4-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0053 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0053 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001f00000004263767420178b170c0000 +0234000000986670676d97486b11000002cc00000619676c79665c1182fa000000ac00000144 +68656164ee14e98a000008e800000036686865610ea7036e0000092000000024686d747808f8 +00e400000944000000086c6f636100a200140000094c000000066d6178700259039500000954 +0000002070726570ee7b813d000009740000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad880042800010064ffeb0494053e003a00784019 +2924301e0a1e1e1f1f0f000a100a200a03a00ab00ac00a030ab8ffc0400e090f480a0a143c00 +1e3a3a241e14b8ffc0401c080c48140f003a013a3a213504290108291e1e19051f350e211f19 +11003fed3fed11392f395e5d1112392f5d39012f2bed332fed1112392f2b5d7139332fed10ed +11393130011e0333323e0235342e02272e0335343e0233321e0217232623220615141e02171e +0515140e0223222e022701550c3b556a3b3c6347262554886371a46932467fb26c6cb4875209 +f02ae1787f1c3d5f443b7d776a502e4b86b76d88ce8d4f0901b93d593b1c182d4128283a2c26 +1518435b784e538d6639396a9b61bc51461d2b231e0e0d1d2a3b56744d5b976d3d437aaa6700 +000000000002000300000000001400010000000000340004002000000004000400010000f001 +ffff0000f000ffff10000001000000000006000e000000000002000000010000052805280000 +ffec00f600d200d400fa00f600b70102009201890000ffea00db0528053e03bb03d2ffeafe7c +fe900444028e0000000000000000000000f000dc00c800d200b2008a00d70000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000403b5451504f +4e4d4c4b4a494847464544434241403f3e3d3c3b3a39383736352f2e2d2c2826252423221f18 +1411100f0d0b0a090807060504030201002c4523466020b02660b004262348482d2c45234623 +6120b02661b004262348482d2c45234660b0206120b04660b004262348482d2c4523462361b0 +206020b02661b02061b004262348482d2c45234660b0406120b06660b004262348482d2c4523 +462361b0406020b02661b04061b004262348482d2c0110203c003c2d2c20452320b0cd442320 +b8015a51582320b08d44235920b0ed51582320b04d44235920b0042651582320b00d44235921 +212d2c20204518684420b001602045b04676688a4560442d2c01b10b0a432343650a2d2c00b1 +0a0b4323430b2d2c00b0282370b101283e01b0282370b10228453ab10200080d2d2c2045b003 +25456164b050515845441b2121592d2c2045b0004360442d2c01b00643b00743650a2d2c2069 +b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b00361592d2c8a03458a8a87b0 +112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c4b525845441b2121592d2c01 +b005251023208af500b0016023edec2d2c01b005251023208af500b0016123edec2d2c01b006 +2510f500edec2d2c20b001600110203c003c2d2c20b001610110203c003c2d2c00b00743b006 +430b2d2c21210c6423648bb84000622d2c21b08051580c6423648bb82000621bb200402f2b59 +b002602d2c21b0c051580c6423648bb81555621bb200802f2b59b002602d2c0c6423648bb840 +00626023212d2c4523456023456023456023766818b08062202d2cb00426b00426b00425b004 +2545234520b003266062636820b0032661658a2344442d2c2045b0005458b040442045b04061 +441b2121592d2c45b1302f4523456160b0016069442d2c4b5158b02f2370b01423421b212159 +2d2c4b515820b0032545695358441b2121591b2121592d2c45b01443b0006063b0016069442d +2cb02f45442d2c452320458a60442d2c45234560442d2c4b235158b90033ffe0b134201bb333 +0034005944442d2cb0164358b00326458a586466b01f601b64b020606620581b21b04059b001 +615923586559b02923442310b029e01b2121212121592d2cb0164358b004254564b020606620 +581b21b04059b0016123586559b0292344b00425b00725082058021b0359b0052510b0042520 +46b0042523423cb0072510b006252046b00425b0016023423c2058011b0059b0052510b00425 +b029e0b0072510b00625b029e0b00425b00725082058021b0359b00425b003254348b00625b0 +0325b0016043481b2159212121212121212d2cb0164358b004254564b020606620581b21b040 +59b0016123581b6559b0292344b00525b00825082058021b0359b0042510b005252046b00425 +23423cb00425b0072508b0072510b006252046b00425b0016023423c2058011b0059b0042510 +b00525b029e0b02920456544b0072510b00625b029e0b00525b00825082058021b0359b00525 +b003254348b00425b0072508b00625b00325b0016043481b2159212121212121212d2c02b004 +25202046b004252342b0052508b003254548212121212d2c02b0032520b0042508b002254348 +2121212d2c452320451820b00050205823652359236820b040505821b04059235865598a6044 +2d2c4b53234b515a5820458a60441b2121592d2c4b545820458a60441b2121592d2c4b53234b +515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a +5823381b2121592d2c00208a49b0005158b04023208a3812341b2121592d2c462346608a8a46 +2320468a608a61b8ff8062232010238ab14b4b8a70456020b0005058b00161b8ffba8b1bb046 +8c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1020042b123018851b1400188 +535a58b910000020885458b202010243604259b12401885158b920000040885458b202020243 +6042b12401885458b2022002436042004b014b5258b2020802436042591bb940000080885458 +b202040243604259b94000008063b80100885458b202080243604259b94000010063b8020088 +5458b202100243604259b94000020063b80400885458b202400243604259595959592d000000 +000100000005e666951862c15f0f3cf5001b080000000000c3738d9600000000c5c82d5ffb20 +fab90a840878000100090002000000000000000100000800fab801000aa2fb20fe110a840001 +000000000000000000000000000000020400008004f800640000001400a20000000100000002 +007f0008008700070002001000400055000001df024c0003000140590704181f24042b1f1f05 +271f1e04271fbf0401af04019f04013f04012f04011f04010f04011615231f1110231f13122c +1f0302231f140d231f0e0d231f0100231f2f17012f15012f14012f0d012f02012f10012f1201 +2f0001b1020042b21711018820b022518a2378b0405278b10a2088b810005578b1020142b003 +1c212101b0124b004b5442b013014b004b5342b0024358004bb03c524bb008505b58b101018e +591b4bb80190524bb008505b58b101018e5959b00288b8010054b00488b8020054b012435a5b +58b80119b101018e851bb900010100b04b60858d59b0501db0644b5358b0801d59b0324b5358 +b0901d590073737373737373732b2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-5-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0049 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0049 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001180000004263767420178b170c0000 +015c000000986670676d97486b11000001f400000619676c7966b5b1895d000000ac0000006c +68656164ee14e98a0000081000000036686865610ea7036e0000084800000024686d74780635 +01200000086c000000086c6f63610036001400000874000000066d617870025903950000087c +0000002070726570ee7b813d0000089c0000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000100a00000019505280003002a4011 +031e00011001200103b001c001e0010301b8ffc0b7080c48010310010d003f3f012f2b5d71ed +3130212311330195f5f505280000000000020003000000000014000100000000003400040020 +00000004000400010000f001ffff0000f000ffff10000001000000000006000e000000000002 +000000010000052805280000ffec00f600d200d400fa00f600b70102009201890000ffea00db +0528053e03bb03d2ffeafe7cfe900444028e0000000000000000000000f000dc00c800d200b2 +008a00d700000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000403b5451504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a3938373635 +2f2e2d2c2826252423221f181411100f0d0b0a090807060504030201002c4523466020b02660 +b004262348482d2c452346236120b02661b004262348482d2c45234660b0206120b04660b004 +262348482d2c4523462361b0206020b02661b02061b004262348482d2c45234660b0406120b0 +6660b004262348482d2c4523462361b0406020b02661b04061b004262348482d2c0110203c00 +3c2d2c20452320b0cd442320b8015a51582320b08d44235920b0ed51582320b04d44235920b0 +042651582320b00d44235921212d2c20204518684420b001602045b04676688a4560442d2c01 +b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b101283e01b0282370b1022845 +3ab10200080d2d2c2045b00325456164b050515845441b2121592d2c2045b0004360442d2c01 +b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b0 +0361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c +4b525845441b2121592d2c01b005251023208af500b0016023edec2d2c01b005251023208af5 +00b0016123edec2d2c01b0062510f500edec2d2c20b001600110203c003c2d2c20b001610110 +203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000622d2c21b08051580c642364 +8bb82000621bb200402f2b59b002602d2c21b0c051580c6423648bb81555621bb200802f2b59 +b002602d2c0c6423648bb84000626023212d2c4523456023456023456023766818b08062202d +2cb00426b00426b00425b0042545234520b003266062636820b0032661658a2344442d2c2045 +b0005458b040442045b04061441b2121592d2c45b1302f4523456160b0016069442d2c4b5158 +b02f2370b01423421b2121592d2c4b515820b0032545695358441b2121591b2121592d2c45b0 +1443b0006063b0016069442d2cb02f45442d2c452320458a60442d2c45234560442d2c4b2351 +58b90033ffe0b134201bb3330034005944442d2cb0164358b00326458a586466b01f601b64b0 +20606620581b21b04059b001615923586559b02923442310b029e01b2121212121592d2cb016 +4358b004254564b020606620581b21b04059b0016123586559b0292344b00425b00725082058 +021b0359b0052510b004252046b0042523423cb0072510b006252046b00425b0016023423c20 +58011b0059b0052510b00425b029e0b0072510b00625b029e0b00425b00725082058021b0359 +b00425b003254348b00625b00325b0016043481b2159212121212121212d2cb0164358b00425 +4564b020606620581b21b04059b0016123581b6559b0292344b00525b00825082058021b0359 +b0042510b005252046b0042523423cb00425b0072508b0072510b006252046b00425b0016023 +423c2058011b0059b0042510b00525b029e0b02920456544b0072510b00625b029e0b00525b0 +0825082058021b0359b00525b003254348b00425b0072508b00625b00325b0016043481b2159 +212121212121212d2c02b00425202046b004252342b0052508b003254548212121212d2c02b0 +032520b0042508b0022543482121212d2c452320451820b00050205823652359236820b04050 +5821b04059235865598a60442d2c4b53234b515a5820458a60441b2121592d2c4b545820458a +60441b2121592d2c4b53234b515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c +2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0005158b04023208a3812341b +2121592d2c462346608a8a462320468a608a61b8ff8062232010238ab14b4b8a70456020b000 +5058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1 +020042b123018851b1400188535a58b910000020885458b202010243604259b12401885158b9 +20000040885458b2020202436042b12401885458b2022002436042004b014b5258b202080243 +6042591bb940000080885458b202040243604259b94000008063b80100885458b20208024360 +4259b94000010063b80200885458b202100243604259b94000020063b80400885458b2024002 +43604259595959592d000000000100000005e666e8365df35f0f3cf5001b080000000000c373 +8d9600000000c5c82d5ffb20fab90a840878000100090002000000000000000100000800fab8 +01000aa2fb20fe110a8400010000000000000000000000000000000204000080023500a00000 +001400360000000100000002007f0008008700070002001000400055000001df024c00030001 +40590704181f24042b1f1f05271f1e04271fbf0401af04019f04013f04012f04011f04010f04 +011615231f1110231f13122c1f0302231f140d231f0e0d231f0100231f2f17012f15012f1401 +2f0d012f02012f10012f12012f0001b1020042b21711018820b022518a2378b0405278b10a20 +88b810005578b1020142b0031c212101b0124b004b5442b013014b004b5342b0024358004bb0 +3c524bb008505b58b101018e591b4bb80190524bb008505b58b101018e5959b00288b8010054 +b00488b8020054b012435a5b58b80119b101018e851bb900010100b04b60858d59b0501db064 +4b5358b0801d59b0324b5358b0901d590073737373737373732b2b2b2b2b2b2b737373737373 +732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-6-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0043 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0043 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001800000004263767420178b170c0000 +01c4000000986670676d97486b110000025c00000619676c7966fe8c5eaf000000ac000000d4 +68656164ee14e98a0000087800000036686865610ea7036e000008b000000024686d74780955 +00e4000008d4000000086c6f6361006a0014000008dc000000066d61787002590395000008e4 +0000002070726570ee7b813d000009040000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad880042800010064ffeb04f1053e0027003ab627 +1e0000131e12b8ffc04018080d481212290a1e201d301d021d27051f2211130f1f180e003fed +cd3fedcd012f5ded12392f2bed332fed3130012e0323220e0215141e0233323637330e032322 +2e0235343e0233321e021703f30a344c62375588603434608753779c14fd0e5d8fbb6d8fe5a0 +5758a1e58d66b690621103893350371d3c74ab706fac773d7b756fab753c60b2fc9c9cfcb160 +3e72a26300000002000300000000001400010000000000340004002000000004000400010000 +f001ffff0000f000ffff10000001000000000006000e00000000000200000001000005280528 +0000ffec00f600d200d400fa00f600b70102009201890000ffea00db0528053e03bb03d2ffea +fe7cfe900444028e0000000000000000000000f000dc00c800d200b2008a00d7000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000403b5451 +504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a39383736352f2e2d2c282625242322 +1f181411100f0d0b0a090807060504030201002c4523466020b02660b004262348482d2c4523 +46236120b02661b004262348482d2c45234660b0206120b04660b004262348482d2c45234623 +61b0206020b02661b02061b004262348482d2c45234660b0406120b06660b004262348482d2c +4523462361b0406020b02661b04061b004262348482d2c0110203c003c2d2c20452320b0cd44 +2320b8015a51582320b08d44235920b0ed51582320b04d44235920b0042651582320b00d4423 +5921212d2c20204518684420b001602045b04676688a4560442d2c01b10b0a432343650a2d2c +00b10a0b4323430b2d2c00b0282370b101283e01b0282370b10228453ab10200080d2d2c2045 +b00325456164b050515845441b2121592d2c2045b0004360442d2c01b00643b00743650a2d2c +2069b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b00361592d2c8a03458a8a +87b0112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c4b525845441b2121592d +2c01b005251023208af500b0016023edec2d2c01b005251023208af500b0016123edec2d2c01 +b0062510f500edec2d2c20b001600110203c003c2d2c20b001610110203c003c2d2c00b00743 +b006430b2d2c21210c6423648bb84000622d2c21b08051580c6423648bb82000621bb200402f +2b59b002602d2c21b0c051580c6423648bb81555621bb200802f2b59b002602d2c0c6423648b +b84000626023212d2c4523456023456023456023766818b08062202d2cb00426b00426b00425 +b0042545234520b003266062636820b0032661658a2344442d2c2045b0005458b040442045b0 +4061441b2121592d2c45b1302f4523456160b0016069442d2c4b5158b02f2370b01423421b21 +21592d2c4b515820b0032545695358441b2121591b2121592d2c45b01443b0006063b0016069 +442d2cb02f45442d2c452320458a60442d2c45234560442d2c4b235158b90033ffe0b134201b +b3330034005944442d2cb0164358b00326458a586466b01f601b64b020606620581b21b04059 +b001615923586559b02923442310b029e01b2121212121592d2cb0164358b004254564b02060 +6620581b21b04059b0016123586559b0292344b00425b00725082058021b0359b0052510b004 +252046b0042523423cb0072510b006252046b00425b0016023423c2058011b0059b0052510b0 +0425b029e0b0072510b00625b029e0b00425b00725082058021b0359b00425b003254348b006 +25b00325b0016043481b2159212121212121212d2cb0164358b004254564b020606620581b21 +b04059b0016123581b6559b0292344b00525b00825082058021b0359b0042510b005252046b0 +042523423cb00425b0072508b0072510b006252046b00425b0016023423c2058011b0059b004 +2510b00525b029e0b02920456544b0072510b00625b029e0b00525b00825082058021b0359b0 +0525b003254348b00425b0072508b00625b00325b0016043481b2159212121212121212d2c02 +b00425202046b004252342b0052508b003254548212121212d2c02b0032520b0042508b00225 +43482121212d2c452320451820b00050205823652359236820b040505821b04059235865598a +60442d2c4b53234b515a5820458a60441b2121592d2c4b545820458a60441b2121592d2c4b53 +234b515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b +515a5823381b2121592d2c00208a49b0005158b04023208a3812341b2121592d2c462346608a +8a462320468a608a61b8ff8062232010238ab14b4b8a70456020b0005058b00161b8ffba8b1b +b0468c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1020042b123018851b140 +0188535a58b910000020885458b202010243604259b12401885158b920000040885458b20202 +02436042b12401885458b2022002436042004b014b5258b2020802436042591bb94000008088 +5458b202040243604259b94000008063b80100885458b202080243604259b94000010063b802 +00885458b202100243604259b94000020063b80400885458b202400243604259595959592d00 +0000000100000005e6664fd8afb75f0f3cf5001b080000000000c3738d9600000000c5c82d5f +fb20fab90a840878000100090002000000000000000100000800fab801000aa2fb20fe110a84 +000100000000000000000000000000000002040000800555006400000014006a000000010000 +0002007f0008008700070002001000400055000001df024c0003000140590704181f24042b1f +1f05271f1e04271fbf0401af04019f04013f04012f04011f04010f04011615231f1110231f13 +122c1f0302231f140d231f0e0d231f0100231f2f17012f15012f14012f0d012f02012f10012f +12012f0001b1020042b21711018820b022518a2378b0405278b10a2088b810005578b1020142 +b0031c212101b0124b004b5442b013014b004b5342b0024358004bb03c524bb008505b58b101 +018e591b4bb80190524bb008505b58b101018e5959b00288b8010054b00488b8020054b01243 +5a5b58b80119b101018e851bb900010100b04b60858d59b0501db0644b5358b0801d59b0324b +5358b0901d590073737373737373732b2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-7-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0053 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0053 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001f00000004263767420178b170c0000 +0234000000986670676d97486b11000002cc00000619676c79665c1182fa000000ac00000144 +68656164ee14e98a000008e800000036686865610ea7036e0000092000000024686d747808f8 +00e400000944000000086c6f636100a200140000094c000000066d6178700259039500000954 +0000002070726570ee7b813d000009740000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad880042800010064ffeb0494053e003a00784019 +2924301e0a1e1e1f1f0f000a100a200a03a00ab00ac00a030ab8ffc0400e090f480a0a143c00 +1e3a3a241e14b8ffc0401c080c48140f003a013a3a213504290108291e1e19051f350e211f19 +11003fed3fed11392f395e5d1112392f5d39012f2bed332fed1112392f2b5d7139332fed10ed +11393130011e0333323e0235342e02272e0335343e0233321e0217232623220615141e02171e +0515140e0223222e022701550c3b556a3b3c6347262554886371a46932467fb26c6cb4875209 +f02ae1787f1c3d5f443b7d776a502e4b86b76d88ce8d4f0901b93d593b1c182d4128283a2c26 +1518435b784e538d6639396a9b61bc51461d2b231e0e0d1d2a3b56744d5b976d3d437aaa6700 +000000000002000300000000001400010000000000340004002000000004000400010000f001 +ffff0000f000ffff10000001000000000006000e000000000002000000010000052805280000 +ffec00f600d200d400fa00f600b70102009201890000ffea00db0528053e03bb03d2ffeafe7c +fe900444028e0000000000000000000000f000dc00c800d200b2008a00d70000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000403b5451504f +4e4d4c4b4a494847464544434241403f3e3d3c3b3a39383736352f2e2d2c2826252423221f18 +1411100f0d0b0a090807060504030201002c4523466020b02660b004262348482d2c45234623 +6120b02661b004262348482d2c45234660b0206120b04660b004262348482d2c4523462361b0 +206020b02661b02061b004262348482d2c45234660b0406120b06660b004262348482d2c4523 +462361b0406020b02661b04061b004262348482d2c0110203c003c2d2c20452320b0cd442320 +b8015a51582320b08d44235920b0ed51582320b04d44235920b0042651582320b00d44235921 +212d2c20204518684420b001602045b04676688a4560442d2c01b10b0a432343650a2d2c00b1 +0a0b4323430b2d2c00b0282370b101283e01b0282370b10228453ab10200080d2d2c2045b003 +25456164b050515845441b2121592d2c2045b0004360442d2c01b00643b00743650a2d2c2069 +b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b00361592d2c8a03458a8a87b0 +112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c4b525845441b2121592d2c01 +b005251023208af500b0016023edec2d2c01b005251023208af500b0016123edec2d2c01b006 +2510f500edec2d2c20b001600110203c003c2d2c20b001610110203c003c2d2c00b00743b006 +430b2d2c21210c6423648bb84000622d2c21b08051580c6423648bb82000621bb200402f2b59 +b002602d2c21b0c051580c6423648bb81555621bb200802f2b59b002602d2c0c6423648bb840 +00626023212d2c4523456023456023456023766818b08062202d2cb00426b00426b00425b004 +2545234520b003266062636820b0032661658a2344442d2c2045b0005458b040442045b04061 +441b2121592d2c45b1302f4523456160b0016069442d2c4b5158b02f2370b01423421b212159 +2d2c4b515820b0032545695358441b2121591b2121592d2c45b01443b0006063b0016069442d +2cb02f45442d2c452320458a60442d2c45234560442d2c4b235158b90033ffe0b134201bb333 +0034005944442d2cb0164358b00326458a586466b01f601b64b020606620581b21b04059b001 +615923586559b02923442310b029e01b2121212121592d2cb0164358b004254564b020606620 +581b21b04059b0016123586559b0292344b00425b00725082058021b0359b0052510b0042520 +46b0042523423cb0072510b006252046b00425b0016023423c2058011b0059b0052510b00425 +b029e0b0072510b00625b029e0b00425b00725082058021b0359b00425b003254348b00625b0 +0325b0016043481b2159212121212121212d2cb0164358b004254564b020606620581b21b040 +59b0016123581b6559b0292344b00525b00825082058021b0359b0042510b005252046b00425 +23423cb00425b0072508b0072510b006252046b00425b0016023423c2058011b0059b0042510 +b00525b029e0b02920456544b0072510b00625b029e0b00525b00825082058021b0359b00525 +b003254348b00425b0072508b00625b00325b0016043481b2159212121212121212d2c02b004 +25202046b004252342b0052508b003254548212121212d2c02b0032520b0042508b002254348 +2121212d2c452320451820b00050205823652359236820b040505821b04059235865598a6044 +2d2c4b53234b515a5820458a60441b2121592d2c4b545820458a60441b2121592d2c4b53234b +515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a +5823381b2121592d2c00208a49b0005158b04023208a3812341b2121592d2c462346608a8a46 +2320468a608a61b8ff8062232010238ab14b4b8a70456020b0005058b00161b8ffba8b1bb046 +8c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1020042b123018851b1400188 +535a58b910000020885458b202010243604259b12401885158b920000040885458b202020243 +6042b12401885458b2022002436042004b014b5258b2020802436042591bb940000080885458 +b202040243604259b94000008063b80100885458b202080243604259b94000010063b8020088 +5458b202100243604259b94000020063b80400885458b202400243604259595959592d000000 +000100000005e666951862c15f0f3cf5001b080000000000c3738d9600000000c5c82d5ffb20 +fab90a840878000100090002000000000000000100000800fab801000aa2fb20fe110a840001 +000000000000000000000000000000020400008004f800640000001400a20000000100000002 +007f0008008700070002001000400055000001df024c0003000140590704181f24042b1f1f05 +271f1e04271fbf0401af04019f04013f04012f04011f04010f04011615231f1110231f13122c +1f0302231f140d231f0e0d231f0100231f2f17012f15012f14012f0d012f02012f10012f1201 +2f0001b1020042b21711018820b022518a2378b0405278b10a2088b810005578b1020142b003 +1c212101b0124b004b5442b013014b004b5342b0024358004bb03c524bb008505b58b101018e +591b4bb80190524bb008505b58b101018e5959b00288b8010054b00488b8020054b012435a5b +58b80119b101018e851bb900010100b04b60858d59b0501db0644b5358b0801d59b0324b5358 +b0901d590073737373737373732b2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-8-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni004C put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni004C 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001240000004263767420178b170c0000 +0168000000986670676d97486b110000020000000619676c79663a46b4af000000ac00000078 +68656164ee14e98a0000081c00000036686865610ea7036e0000085400000024686d74780844 +012000000878000000086c6f6361003c001400000880000000066d6178700259039500000888 +0000002070726570ee7b813d000008a80000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000100a0000003f405280005002e400e +0005100520050308050507041e01b8ffc0400a080c48010210041f010d003fed3f012f2bed12 +392f5e5d313021211133112103f4fcacf6025e0528fbbb000000000000020003000000000014 +00010000000000340004002000000004000400010000f001ffff0000f000ffff100000010000 +00000006000e000000000002000000010000052805280000ffec00f600d200d400fa00f600b7 +0102009201890000ffea00db0528053e03bb03d2ffeafe7cfe900444028e0000000000000000 +000000f000dc00c800d200b2008a00d700000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000403b5451504f4e4d4c4b4a494847464544434241 +403f3e3d3c3b3a39383736352f2e2d2c2826252423221f181411100f0d0b0a09080706050403 +0201002c4523466020b02660b004262348482d2c452346236120b02661b004262348482d2c45 +234660b0206120b04660b004262348482d2c4523462361b0206020b02661b02061b004262348 +482d2c45234660b0406120b06660b004262348482d2c4523462361b0406020b02661b04061b0 +04262348482d2c0110203c003c2d2c20452320b0cd442320b8015a51582320b08d44235920b0 +ed51582320b04d44235920b0042651582320b00d44235921212d2c20204518684420b0016020 +45b04676688a4560442d2c01b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b1 +01283e01b0282370b10228453ab10200080d2d2c2045b00325456164b050515845441b212159 +2d2c2045b0004360442d2c01b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb810 +0062602b0c642364615c58b00361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c45 +65b02c234445b02b23442d2c4b525845441b2121592d2c01b005251023208af500b0016023ed +ec2d2c01b005251023208af500b0016123edec2d2c01b0062510f500edec2d2c20b001600110 +203c003c2d2c20b001610110203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000 +622d2c21b08051580c6423648bb82000621bb200402f2b59b002602d2c21b0c051580c642364 +8bb81555621bb200802f2b59b002602d2c0c6423648bb84000626023212d2c45234560234560 +23456023766818b08062202d2cb00426b00426b00425b0042545234520b003266062636820b0 +032661658a2344442d2c2045b0005458b040442045b04061441b2121592d2c45b1302f452345 +6160b0016069442d2c4b5158b02f2370b01423421b2121592d2c4b515820b003254569535844 +1b2121591b2121592d2c45b01443b0006063b0016069442d2cb02f45442d2c452320458a6044 +2d2c45234560442d2c4b235158b90033ffe0b134201bb3330034005944442d2cb0164358b003 +26458a586466b01f601b64b020606620581b21b04059b001615923586559b02923442310b029 +e01b2121212121592d2cb0164358b004254564b020606620581b21b04059b0016123586559b0 +292344b00425b00725082058021b0359b0052510b004252046b0042523423cb0072510b00625 +2046b00425b0016023423c2058011b0059b0052510b00425b029e0b0072510b00625b029e0b0 +0425b00725082058021b0359b00425b003254348b00625b00325b0016043481b215921212121 +2121212d2cb0164358b004254564b020606620581b21b04059b0016123581b6559b0292344b0 +0525b00825082058021b0359b0042510b005252046b0042523423cb00425b0072508b0072510 +b006252046b00425b0016023423c2058011b0059b0042510b00525b029e0b02920456544b007 +2510b00625b029e0b00525b00825082058021b0359b00525b003254348b00425b0072508b006 +25b00325b0016043481b2159212121212121212d2c02b00425202046b004252342b0052508b0 +03254548212121212d2c02b0032520b0042508b0022543482121212d2c452320451820b00050 +205823652359236820b040505821b04059235865598a60442d2c4b53234b515a5820458a6044 +1b2121592d2c4b545820458a60441b2121592d2c4b53234b515a58381b2121592d2c4b545838 +1b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0 +005158b04023208a3812341b2121592d2c462346608a8a462320468a608a61b8ff8062232010 +238ab14b4b8a70456020b0005058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349 +648a2353583c1b21592d2cb1020042b123018851b1400188535a58b910000020885458b20201 +0243604259b12401885158b920000040885458b2020202436042b12401885458b20220024360 +42004b014b5258b2020802436042591bb940000080885458b202040243604259b94000008063 +b80100885458b202080243604259b94000010063b80200885458b202100243604259b9400002 +0063b80400885458b202400243604259595959592d000000000100000005e666dae206d75f0f +3cf5001b080000000000c3738d9600000000c5c82d5ffb20fab90a8408780001000900020000 +00000000000100000800fab801000aa2fb20fe110a8400010000000000000000000000000000 +000204000080044400a000000014003c0000000100000002007f000800870007000200100040 +0055000001df024c0003000140590704181f24042b1f1f05271f1e04271fbf0401af04019f04 +013f04012f04011f04010f04011615231f1110231f13122c1f0302231f140d231f0e0d231f01 +00231f2f17012f15012f14012f0d012f02012f10012f12012f0001b1020042b21711018820b0 +22518a2378b0405278b10a2088b810005578b1020142b0031c212101b0124b004b5442b01301 +4b004b5342b0024358004bb03c524bb008505b58b101018e591b4bb80190524bb008505b58b1 +01018e5959b00288b8010054b00488b8020054b012435a5b58b80119b101018e851bb9000101 +00b04b60858d59b0501db0644b5358b0801d59b0324b5358b0901d590073737373737373732b +2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-9-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0049 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0049 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001180000004263767420178b170c0000 +015c000000986670676d97486b11000001f400000619676c7966b5b1895d000000ac0000006c +68656164ee14e98a0000081000000036686865610ea7036e0000084800000024686d74780635 +01200000086c000000086c6f63610036001400000874000000066d617870025903950000087c +0000002070726570ee7b813d0000089c0000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000100a00000019505280003002a4011 +031e00011001200103b001c001e0010301b8ffc0b7080c48010310010d003f3f012f2b5d71ed +3130212311330195f5f505280000000000020003000000000014000100000000003400040020 +00000004000400010000f001ffff0000f000ffff10000001000000000006000e000000000002 +000000010000052805280000ffec00f600d200d400fa00f600b70102009201890000ffea00db +0528053e03bb03d2ffeafe7cfe900444028e0000000000000000000000f000dc00c800d200b2 +008a00d700000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000403b5451504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a3938373635 +2f2e2d2c2826252423221f181411100f0d0b0a090807060504030201002c4523466020b02660 +b004262348482d2c452346236120b02661b004262348482d2c45234660b0206120b04660b004 +262348482d2c4523462361b0206020b02661b02061b004262348482d2c45234660b0406120b0 +6660b004262348482d2c4523462361b0406020b02661b04061b004262348482d2c0110203c00 +3c2d2c20452320b0cd442320b8015a51582320b08d44235920b0ed51582320b04d44235920b0 +042651582320b00d44235921212d2c20204518684420b001602045b04676688a4560442d2c01 +b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b101283e01b0282370b1022845 +3ab10200080d2d2c2045b00325456164b050515845441b2121592d2c2045b0004360442d2c01 +b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b0 +0361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c +4b525845441b2121592d2c01b005251023208af500b0016023edec2d2c01b005251023208af5 +00b0016123edec2d2c01b0062510f500edec2d2c20b001600110203c003c2d2c20b001610110 +203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000622d2c21b08051580c642364 +8bb82000621bb200402f2b59b002602d2c21b0c051580c6423648bb81555621bb200802f2b59 +b002602d2c0c6423648bb84000626023212d2c4523456023456023456023766818b08062202d +2cb00426b00426b00425b0042545234520b003266062636820b0032661658a2344442d2c2045 +b0005458b040442045b04061441b2121592d2c45b1302f4523456160b0016069442d2c4b5158 +b02f2370b01423421b2121592d2c4b515820b0032545695358441b2121591b2121592d2c45b0 +1443b0006063b0016069442d2cb02f45442d2c452320458a60442d2c45234560442d2c4b2351 +58b90033ffe0b134201bb3330034005944442d2cb0164358b00326458a586466b01f601b64b0 +20606620581b21b04059b001615923586559b02923442310b029e01b2121212121592d2cb016 +4358b004254564b020606620581b21b04059b0016123586559b0292344b00425b00725082058 +021b0359b0052510b004252046b0042523423cb0072510b006252046b00425b0016023423c20 +58011b0059b0052510b00425b029e0b0072510b00625b029e0b00425b00725082058021b0359 +b00425b003254348b00625b00325b0016043481b2159212121212121212d2cb0164358b00425 +4564b020606620581b21b04059b0016123581b6559b0292344b00525b00825082058021b0359 +b0042510b005252046b0042523423cb00425b0072508b0072510b006252046b00425b0016023 +423c2058011b0059b0042510b00525b029e0b02920456544b0072510b00625b029e0b00525b0 +0825082058021b0359b00525b003254348b00425b0072508b00625b00325b0016043481b2159 +212121212121212d2c02b00425202046b004252342b0052508b003254548212121212d2c02b0 +032520b0042508b0022543482121212d2c452320451820b00050205823652359236820b04050 +5821b04059235865598a60442d2c4b53234b515a5820458a60441b2121592d2c4b545820458a +60441b2121592d2c4b53234b515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c +2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0005158b04023208a3812341b +2121592d2c462346608a8a462320468a608a61b8ff8062232010238ab14b4b8a70456020b000 +5058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1 +020042b123018851b1400188535a58b910000020885458b202010243604259b12401885158b9 +20000040885458b2020202436042b12401885458b2022002436042004b014b5258b202080243 +6042591bb940000080885458b202040243604259b94000008063b80100885458b20208024360 +4259b94000010063b80200885458b202100243604259b94000020063b80400885458b2024002 +43604259595959592d000000000100000005e666e8365df35f0f3cf5001b080000000000c373 +8d9600000000c5c82d5ffb20fab90a840878000100090002000000000000000100000800fab8 +01000aa2fb20fe110a8400010000000000000000000000000000000204000080023500a00000 +001400360000000100000002007f0008008700070002001000400055000001df024c00030001 +40590704181f24042b1f1f05271f1e04271fbf0401af04019f04013f04012f04011f04010f04 +011615231f1110231f13122c1f0302231f140d231f0e0d231f0100231f2f17012f15012f1401 +2f0d012f02012f10012f12012f0001b1020042b21711018820b022518a2378b0405278b10a20 +88b810005578b1020142b0031c212101b0124b004b5442b013014b004b5342b0024358004bb0 +3c524bb008505b58b101018e591b4bb80190524bb008505b58b101018e5959b00288b8010054 +b00488b8020054b012435a5b58b80119b101018e851bb900010100b04b60858d59b0501db064 +4b5358b0801d59b0324b5358b0901d590073737373737373732b2b2b2b2b2b2b737373737373 +732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-10-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0042 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0042 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001c40000004263767420178b170c0000 +0208000000986670676d97486b11000002a000000619676c796635437db5000000ac00000118 +68656164ee14e98a000008bc00000036686865610ea7036e000008f400000024686d747808f8 +012000000918000000086c6f6361008c001400000920000000066d6178700259039500000928 +0000002070726570ee7b813d000009480000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000300a00000049405280012001d0027 +0076401d060e160e260e660e04080e270b1e1717001e0021019021a021b0210321b8ffc04013 +090d482121042913271eb004c004028f040104b8ffc04017080c48040e131f3f264f26022626 +1e1d1f05101e1f040d003fed3fed11392f5ded39012f2b5d5dfdc41112392f2b5d71ed332fed +11395e5d313001140623211121321e02151406071e030133323635342e02232311213235342e +0223230494fdfcfe0501e36aad7a433e4130462f17fd02ec736d19395b43dc0104fd1a406a50 +ed0191c6cb0528315c8453547c301741505b015f455124362411fc9eae2d422b150000000002 +000300000000001400010000000000340004002000000004000400010000f001ffff0000f000 +ffff10000001000000000006000e000000000002000000010000052805280000ffec00f600d2 +00d400fa00f600b70102009201890000ffea00db0528053e03bb03d2ffeafe7cfe900444028e +0000000000000000000000f000dc00c800d200b2008a00d70000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000403b5451504f4e4d4c4b4a49 +4847464544434241403f3e3d3c3b3a39383736352f2e2d2c2826252423221f181411100f0d0b +0a090807060504030201002c4523466020b02660b004262348482d2c452346236120b02661b0 +04262348482d2c45234660b0206120b04660b004262348482d2c4523462361b0206020b02661 +b02061b004262348482d2c45234660b0406120b06660b004262348482d2c4523462361b04060 +20b02661b04061b004262348482d2c0110203c003c2d2c20452320b0cd442320b8015a515823 +20b08d44235920b0ed51582320b04d44235920b0042651582320b00d44235921212d2c202045 +18684420b001602045b04676688a4560442d2c01b10b0a432343650a2d2c00b10a0b4323430b +2d2c00b0282370b101283e01b0282370b10228453ab10200080d2d2c2045b00325456164b050 +515845441b2121592d2c2045b0004360442d2c01b00643b00743650a2d2c2069b04061b0008b +20b12cc08a8cb8100062602b0c642364615c58b00361592d2c8a03458a8a87b0112bb0292344 +b0297ae4182d2c4565b02c234445b02b23442d2c4b525845441b2121592d2c01b00525102320 +8af500b0016023edec2d2c01b005251023208af500b0016123edec2d2c01b0062510f500edec +2d2c20b001600110203c003c2d2c20b001610110203c003c2d2c00b00743b006430b2d2c2121 +0c6423648bb84000622d2c21b08051580c6423648bb82000621bb200402f2b59b002602d2c21 +b0c051580c6423648bb81555621bb200802f2b59b002602d2c0c6423648bb84000626023212d +2c4523456023456023456023766818b08062202d2cb00426b00426b00425b0042545234520b0 +03266062636820b0032661658a2344442d2c2045b0005458b040442045b04061441b2121592d +2c45b1302f4523456160b0016069442d2c4b5158b02f2370b01423421b2121592d2c4b515820 +b0032545695358441b2121591b2121592d2c45b01443b0006063b0016069442d2cb02f45442d +2c452320458a60442d2c45234560442d2c4b235158b90033ffe0b134201bb333003400594444 +2d2cb0164358b00326458a586466b01f601b64b020606620581b21b04059b001615923586559 +b02923442310b029e01b2121212121592d2cb0164358b004254564b020606620581b21b04059 +b0016123586559b0292344b00425b00725082058021b0359b0052510b004252046b004252342 +3cb0072510b006252046b00425b0016023423c2058011b0059b0052510b00425b029e0b00725 +10b00625b029e0b00425b00725082058021b0359b00425b003254348b00625b00325b0016043 +481b2159212121212121212d2cb0164358b004254564b020606620581b21b04059b001612358 +1b6559b0292344b00525b00825082058021b0359b0042510b005252046b0042523423cb00425 +b0072508b0072510b006252046b00425b0016023423c2058011b0059b0042510b00525b029e0 +b02920456544b0072510b00625b029e0b00525b00825082058021b0359b00525b003254348b0 +0425b0072508b00625b00325b0016043481b2159212121212121212d2c02b00425202046b004 +252342b0052508b003254548212121212d2c02b0032520b0042508b0022543482121212d2c45 +2320451820b00050205823652359236820b040505821b04059235865598a60442d2c4b53234b +515a5820458a60441b2121592d2c4b545820458a60441b2121592d2c4b53234b515a58381b21 +21592d2c4b5458381b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a5823381b2121 +592d2c00208a49b0005158b04023208a3812341b2121592d2c462346608a8a462320468a608a +61b8ff8062232010238ab14b4b8a70456020b0005058b00161b8ffba8b1bb0468c59b0106068 +013a2d2c208a2349648a2353583c1b21592d2cb1020042b123018851b1400188535a58b91000 +0020885458b202010243604259b12401885158b920000040885458b2020202436042b1240188 +5458b2022002436042004b014b5258b2020802436042591bb940000080885458b20204024360 +4259b94000008063b80100885458b202080243604259b94000010063b80200885458b2021002 +43604259b94000020063b80400885458b202400243604259595959592d000000000100000005 +e666e2e06e8b5f0f3cf5001b080000000000c3738d9600000000c5c82d5ffb20fab90a840878 +000100090002000000000000000100000800fab801000aa2fb20fe110a840001000000000000 +000000000000000000020400008004f800a000000014008c0000000100000002007f00080087 +00070002001000400055000001df024c0003000140590704181f24042b1f1f05271f1e04271f +bf0401af04019f04013f04012f04011f04010f04011615231f1110231f13122c1f0302231f14 +0d231f0e0d231f0100231f2f17012f15012f14012f0d012f02012f10012f12012f0001b10200 +42b21711018820b022518a2378b0405278b10a2088b810005578b1020142b0031c212101b012 +4b004b5442b013014b004b5342b0024358004bb03c524bb008505b58b101018e591b4bb80190 +524bb008505b58b101018e5959b00288b8010054b00488b8020054b012435a5b58b80119b101 +018e851bb900010100b04b60858d59b0501db0644b5358b0801d59b0324b5358b0901d590073 +737373737373732b2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-11-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0052 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0052 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001bc0000004263767420178b170c0000 +0200000000986670676d97486b110000029800000619676c79664a8630a4000000ac00000110 +68656164ee14e98a000008b400000036686865610ea7036e000008ec00000024686d7478096a +012000000910000000086c6f63610088001400000918000000066d6178700259039500000920 +0000002070726570ee7b813d000009400000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000200a0000005100528001a0025006b +4026180001001a1a2419181419180715010815181b1919121e0021102120210321210827061b +1e08b8ffc04015080c480818001a1b1f15050507251f09101a19070d003fc4c43fed11392f33 +ed123939012f2bfdc41112392f5ded322f1239395e5d872b7d10c4015d3130012e0323211123 +1121321e021716161514060716161713210121323e02353426232103880d2e3c4929fef8f702 +503560585025414175662b441a8efef6fd910148425e3c1c6d72fe9f0167253f2e1afded0528 +0512241f379e5379ad2e206348fe7902f6122a43315852000000000000020003000000000014 +00010000000000340004002000000004000400010000f001ffff0000f000ffff100000010000 +00000006000e000000000002000000010000052805280000ffec00f600d200d400fa00f600b7 +0102009201890000ffea00db0528053e03bb03d2ffeafe7cfe900444028e0000000000000000 +000000f000dc00c800d200b2008a00d700000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000403b5451504f4e4d4c4b4a494847464544434241 +403f3e3d3c3b3a39383736352f2e2d2c2826252423221f181411100f0d0b0a09080706050403 +0201002c4523466020b02660b004262348482d2c452346236120b02661b004262348482d2c45 +234660b0206120b04660b004262348482d2c4523462361b0206020b02661b02061b004262348 +482d2c45234660b0406120b06660b004262348482d2c4523462361b0406020b02661b04061b0 +04262348482d2c0110203c003c2d2c20452320b0cd442320b8015a51582320b08d44235920b0 +ed51582320b04d44235920b0042651582320b00d44235921212d2c20204518684420b0016020 +45b04676688a4560442d2c01b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b1 +01283e01b0282370b10228453ab10200080d2d2c2045b00325456164b050515845441b212159 +2d2c2045b0004360442d2c01b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb810 +0062602b0c642364615c58b00361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c45 +65b02c234445b02b23442d2c4b525845441b2121592d2c01b005251023208af500b0016023ed +ec2d2c01b005251023208af500b0016123edec2d2c01b0062510f500edec2d2c20b001600110 +203c003c2d2c20b001610110203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000 +622d2c21b08051580c6423648bb82000621bb200402f2b59b002602d2c21b0c051580c642364 +8bb81555621bb200802f2b59b002602d2c0c6423648bb84000626023212d2c45234560234560 +23456023766818b08062202d2cb00426b00426b00425b0042545234520b003266062636820b0 +032661658a2344442d2c2045b0005458b040442045b04061441b2121592d2c45b1302f452345 +6160b0016069442d2c4b5158b02f2370b01423421b2121592d2c4b515820b003254569535844 +1b2121591b2121592d2c45b01443b0006063b0016069442d2cb02f45442d2c452320458a6044 +2d2c45234560442d2c4b235158b90033ffe0b134201bb3330034005944442d2cb0164358b003 +26458a586466b01f601b64b020606620581b21b04059b001615923586559b02923442310b029 +e01b2121212121592d2cb0164358b004254564b020606620581b21b04059b0016123586559b0 +292344b00425b00725082058021b0359b0052510b004252046b0042523423cb0072510b00625 +2046b00425b0016023423c2058011b0059b0052510b00425b029e0b0072510b00625b029e0b0 +0425b00725082058021b0359b00425b003254348b00625b00325b0016043481b215921212121 +2121212d2cb0164358b004254564b020606620581b21b04059b0016123581b6559b0292344b0 +0525b00825082058021b0359b0042510b005252046b0042523423cb00425b0072508b0072510 +b006252046b00425b0016023423c2058011b0059b0042510b00525b029e0b02920456544b007 +2510b00625b029e0b00525b00825082058021b0359b00525b003254348b00425b0072508b006 +25b00325b0016043481b2159212121212121212d2c02b00425202046b004252342b0052508b0 +03254548212121212d2c02b0032520b0042508b0022543482121212d2c452320451820b00050 +205823652359236820b040505821b04059235865598a60442d2c4b53234b515a5820458a6044 +1b2121592d2c4b545820458a60441b2121592d2c4b53234b515a58381b2121592d2c4b545838 +1b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0 +005158b04023208a3812341b2121592d2c462346608a8a462320468a608a61b8ff8062232010 +238ab14b4b8a70456020b0005058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349 +648a2353583c1b21592d2cb1020042b123018851b1400188535a58b910000020885458b20201 +0243604259b12401885158b920000040885458b2020202436042b12401885458b20220024360 +42004b014b5258b2020802436042591bb940000080885458b202040243604259b94000008063 +b80100885458b202080243604259b94000010063b80200885458b202100243604259b9400002 +0063b80400885458b202400243604259595959592d000000000100000005e666b77f08fd5f0f +3cf5001b080000000000c3738d9600000000c5c82d5ffb20fab90a8408780001000900020000 +00000000000100000800fab801000aa2fb20fe110a8400010000000000000000000000000000 +000204000080056a00a00000001400880000000100000002007f000800870007000200100040 +0055000001df024c0003000140590704181f24042b1f1f05271f1e04271fbf0401af04019f04 +013f04012f04011f04010f04011615231f1110231f13122c1f0302231f140d231f0e0d231f01 +00231f2f17012f15012f14012f0d012f02012f10012f12012f0001b1020042b21711018820b0 +22518a2378b0405278b10a2088b810005578b1020142b0031c212101b0124b004b5442b01301 +4b004b5342b0024358004bb03c524bb008505b58b101018e591b4bb80190524bb008505b58b1 +01018e5959b00288b8010054b00488b8020054b012435a5b58b80119b101018e851bb9000101 +00b04b60858d59b0501db0644b5358b0801d59b0324b5358b0901d590073737373737373732b +2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-12-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0041 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0041 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001b80000004263767420178b170c0000 +01fc000000986670676d97486b110000029400000619676c7966e1c853b3000000ac0000010c +68656164ee14e98a000008b000000036686865610ea7036e000008e800000024686d7478090a +00850000090c000000086c6f63610086001400000914000000066d617870025903950000091c +0000002070726570ee7b813d0000093c0000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000200050000050505290002000a00a7 +406706020107014809013909011d09010f090116070104070109070107240809140809a00801 +08080500010401470a01360a01120a01000a011904010b04010a04010424030a14030a0303ab +01010106051f000002100220024002040202070a091007080403080d01002f3fd4c410c43fc4 +12392f5dc4fdc4013d2f5dc9182f872b877dc4015d5d5d5d5d5d1087c4c401c9182f5d872b87 +7dc4015d5d5d5d5d5d1087c4c4313001030301210321032101330315a0970327feed90fe328a +fefb01fcea024b01a3fe5dfdb5017afe86052900000000000002000300000000001400010000 +000000340004002000000004000400010000f001ffff0000f000ffff10000001000000000006 +000e000000000002000000010000052805280000ffec00f600d200d400fa00f600b701020092 +01890000ffea00db0528053e03bb03d2ffeafe7cfe900444028e0000000000000000000000f0 +00dc00c800d200b2008a00d70000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000403b5451504f4e4d4c4b4a494847464544434241403f3e3d +3c3b3a39383736352f2e2d2c2826252423221f181411100f0d0b0a090807060504030201002c +4523466020b02660b004262348482d2c452346236120b02661b004262348482d2c45234660b0 +206120b04660b004262348482d2c4523462361b0206020b02661b02061b004262348482d2c45 +234660b0406120b06660b004262348482d2c4523462361b0406020b02661b04061b004262348 +482d2c0110203c003c2d2c20452320b0cd442320b8015a51582320b08d44235920b0ed515823 +20b04d44235920b0042651582320b00d44235921212d2c20204518684420b001602045b04676 +688a4560442d2c01b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b101283e01 +b0282370b10228453ab10200080d2d2c2045b00325456164b050515845441b2121592d2c2045 +b0004360442d2c01b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb8100062602b +0c642364615c58b00361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c4565b02c23 +4445b02b23442d2c4b525845441b2121592d2c01b005251023208af500b0016023edec2d2c01 +b005251023208af500b0016123edec2d2c01b0062510f500edec2d2c20b001600110203c003c +2d2c20b001610110203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000622d2c21 +b08051580c6423648bb82000621bb200402f2b59b002602d2c21b0c051580c6423648bb81555 +621bb200802f2b59b002602d2c0c6423648bb84000626023212d2c4523456023456023456023 +766818b08062202d2cb00426b00426b00425b0042545234520b003266062636820b003266165 +8a2344442d2c2045b0005458b040442045b04061441b2121592d2c45b1302f4523456160b001 +6069442d2c4b5158b02f2370b01423421b2121592d2c4b515820b0032545695358441b212159 +1b2121592d2c45b01443b0006063b0016069442d2cb02f45442d2c452320458a60442d2c4523 +4560442d2c4b235158b90033ffe0b134201bb3330034005944442d2cb0164358b00326458a58 +6466b01f601b64b020606620581b21b04059b001615923586559b02923442310b029e01b2121 +212121592d2cb0164358b004254564b020606620581b21b04059b0016123586559b0292344b0 +0425b00725082058021b0359b0052510b004252046b0042523423cb0072510b006252046b004 +25b0016023423c2058011b0059b0052510b00425b029e0b0072510b00625b029e0b00425b007 +25082058021b0359b00425b003254348b00625b00325b0016043481b2159212121212121212d +2cb0164358b004254564b020606620581b21b04059b0016123581b6559b0292344b00525b008 +25082058021b0359b0042510b005252046b0042523423cb00425b0072508b0072510b0062520 +46b00425b0016023423c2058011b0059b0042510b00525b029e0b02920456544b0072510b006 +25b029e0b00525b00825082058021b0359b00525b003254348b00425b0072508b00625b00325 +b0016043481b2159212121212121212d2c02b00425202046b004252342b0052508b003254548 +212121212d2c02b0032520b0042508b0022543482121212d2c452320451820b0005020582365 +2359236820b040505821b04059235865598a60442d2c4b53234b515a5820458a60441b212159 +2d2c4b545820458a60441b2121592d2c4b53234b515a58381b2121592d2c4b5458381b212159 +2d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0005158b0 +4023208a3812341b2121592d2c462346608a8a462320468a608a61b8ff8062232010238ab14b +4b8a70456020b0005058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349648a2353 +583c1b21592d2cb1020042b123018851b1400188535a58b910000020885458b2020102436042 +59b12401885158b920000040885458b2020202436042b12401885458b2022002436042004b01 +4b5258b2020802436042591bb940000080885458b202040243604259b94000008063b8010088 +5458b202080243604259b94000010063b80200885458b202100243604259b94000020063b804 +00885458b202400243604259595959592d000000000100000005e66689bec43d5f0f3cf5001b +080000000000c3738d9600000000c5c82d5ffb20fab90a840878000100090002000000000000 +000100000800fab801000aa2fb20fe110a840001000000000000000000000000000000020400 +0080050a00050000001400860000000100000002007f00080087000700020010004000550000 +01df024c0003000140590704181f24042b1f1f05271f1e04271fbf0401af04019f04013f0401 +2f04011f04010f04011615231f1110231f13122c1f0302231f140d231f0e0d231f0100231f2f +17012f15012f14012f0d012f02012f10012f12012f0001b1020042b21711018820b022518a23 +78b0405278b10a2088b810005578b1020142b0031c212101b0124b004b5442b013014b004b53 +42b0024358004bb03c524bb008505b58b101018e591b4bb80190524bb008505b58b101018e59 +59b00288b8010054b00488b8020054b012435a5b58b80119b101018e851bb900010100b04b60 +858d59b0501db0644b5358b0801d59b0324b5358b0901d590073737373737373732b2b2b2b2b +2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-13-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0052 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0052 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001bc0000004263767420178b170c0000 +0200000000986670676d97486b110000029800000619676c79664a8630a4000000ac00000110 +68656164ee14e98a000008b400000036686865610ea7036e000008ec00000024686d7478096a +012000000910000000086c6f63610088001400000918000000066d6178700259039500000920 +0000002070726570ee7b813d000009400000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000200a0000005100528001a0025006b +4026180001001a1a2419181419180715010815181b1919121e0021102120210321210827061b +1e08b8ffc04015080c480818001a1b1f15050507251f09101a19070d003fc4c43fed11392f33 +ed123939012f2bfdc41112392f5ded322f1239395e5d872b7d10c4015d3130012e0323211123 +1121321e021716161514060716161713210121323e02353426232103880d2e3c4929fef8f702 +503560585025414175662b441a8efef6fd910148425e3c1c6d72fe9f0167253f2e1afded0528 +0512241f379e5379ad2e206348fe7902f6122a43315852000000000000020003000000000014 +00010000000000340004002000000004000400010000f001ffff0000f000ffff100000010000 +00000006000e000000000002000000010000052805280000ffec00f600d200d400fa00f600b7 +0102009201890000ffea00db0528053e03bb03d2ffeafe7cfe900444028e0000000000000000 +000000f000dc00c800d200b2008a00d700000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000403b5451504f4e4d4c4b4a494847464544434241 +403f3e3d3c3b3a39383736352f2e2d2c2826252423221f181411100f0d0b0a09080706050403 +0201002c4523466020b02660b004262348482d2c452346236120b02661b004262348482d2c45 +234660b0206120b04660b004262348482d2c4523462361b0206020b02661b02061b004262348 +482d2c45234660b0406120b06660b004262348482d2c4523462361b0406020b02661b04061b0 +04262348482d2c0110203c003c2d2c20452320b0cd442320b8015a51582320b08d44235920b0 +ed51582320b04d44235920b0042651582320b00d44235921212d2c20204518684420b0016020 +45b04676688a4560442d2c01b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b1 +01283e01b0282370b10228453ab10200080d2d2c2045b00325456164b050515845441b212159 +2d2c2045b0004360442d2c01b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb810 +0062602b0c642364615c58b00361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c45 +65b02c234445b02b23442d2c4b525845441b2121592d2c01b005251023208af500b0016023ed +ec2d2c01b005251023208af500b0016123edec2d2c01b0062510f500edec2d2c20b001600110 +203c003c2d2c20b001610110203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000 +622d2c21b08051580c6423648bb82000621bb200402f2b59b002602d2c21b0c051580c642364 +8bb81555621bb200802f2b59b002602d2c0c6423648bb84000626023212d2c45234560234560 +23456023766818b08062202d2cb00426b00426b00425b0042545234520b003266062636820b0 +032661658a2344442d2c2045b0005458b040442045b04061441b2121592d2c45b1302f452345 +6160b0016069442d2c4b5158b02f2370b01423421b2121592d2c4b515820b003254569535844 +1b2121591b2121592d2c45b01443b0006063b0016069442d2cb02f45442d2c452320458a6044 +2d2c45234560442d2c4b235158b90033ffe0b134201bb3330034005944442d2cb0164358b003 +26458a586466b01f601b64b020606620581b21b04059b001615923586559b02923442310b029 +e01b2121212121592d2cb0164358b004254564b020606620581b21b04059b0016123586559b0 +292344b00425b00725082058021b0359b0052510b004252046b0042523423cb0072510b00625 +2046b00425b0016023423c2058011b0059b0052510b00425b029e0b0072510b00625b029e0b0 +0425b00725082058021b0359b00425b003254348b00625b00325b0016043481b215921212121 +2121212d2cb0164358b004254564b020606620581b21b04059b0016123581b6559b0292344b0 +0525b00825082058021b0359b0042510b005252046b0042523423cb00425b0072508b0072510 +b006252046b00425b0016023423c2058011b0059b0042510b00525b029e0b02920456544b007 +2510b00625b029e0b00525b00825082058021b0359b00525b003254348b00425b0072508b006 +25b00325b0016043481b2159212121212121212d2c02b00425202046b004252342b0052508b0 +03254548212121212d2c02b0032520b0042508b0022543482121212d2c452320451820b00050 +205823652359236820b040505821b04059235865598a60442d2c4b53234b515a5820458a6044 +1b2121592d2c4b545820458a60441b2121592d2c4b53234b515a58381b2121592d2c4b545838 +1b2121592d2c2d2c2d2c2d2c2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0 +005158b04023208a3812341b2121592d2c462346608a8a462320468a608a61b8ff8062232010 +238ab14b4b8a70456020b0005058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349 +648a2353583c1b21592d2cb1020042b123018851b1400188535a58b910000020885458b20201 +0243604259b12401885158b920000040885458b2020202436042b12401885458b20220024360 +42004b014b5258b2020802436042591bb940000080885458b202040243604259b94000008063 +b80100885458b202080243604259b94000010063b80200885458b202100243604259b9400002 +0063b80400885458b202400243604259595959592d000000000100000005e666b77f08fd5f0f +3cf5001b080000000000c3738d9600000000c5c82d5ffb20fab90a8408780001000900020000 +00000000000100000800fab801000aa2fb20fe110a8400010000000000000000000000000000 +000204000080056a00a00000001400880000000100000002007f000800870007000200100040 +0055000001df024c0003000140590704181f24042b1f1f05271f1e04271fbf0401af04019f04 +013f04012f04011f04010f04011615231f1110231f13122c1f0302231f140d231f0e0d231f01 +00231f2f17012f15012f14012f0d012f02012f10012f12012f0001b1020042b21711018820b0 +22518a2378b0405278b10a2088b810005578b1020142b0031c212101b0124b004b5442b01301 +4b004b5342b0024358004bb03c524bb008505b58b101018e591b4bb80190524bb008505b58b1 +01018e5959b00288b8010054b00488b8020054b012435a5b58b80119b101018e851bb9000101 +00b04b60858d59b0501db0644b5358b0801d59b0324b5358b0901d590073737373737373732b +2b2b2b2b2b2b737373737373732b2b2b2b0000> +] def +FontName currentdict end definefont pop +11 dict begin +/FontType 42 def +/FontName /f-14-0 def +/PaintType 0 def +/FontMatrix [ 1 0 0 1 0 0 ] def +/FontBBox [ 0 0 0 0 ] def +/Encoding 256 array def +0 1 255 { Encoding exch /.notdef put } for +Encoding 1 /uni0059 put +/CharStrings 2 dict dup begin +/.notdef 0 def +/uni0059 1 def +end readonly def +/sfnts [ +<00010000000a008000030020636d61700015f07e000001640000004263767420178b170c0000 +01a8000000986670676d97486b110000024000000619676c7966e625d8da000000ac000000b8 +68656164ee14e98a0000085c00000036686865610ea7036e0000089400000024686d7478093e +0099000008b8000000086c6f6361005c0014000008c0000000066d61787002590395000008c8 +0000002070726570ee7b813d000008e80000010f000200800000038005280003000700003311 +211125211121800300fd800200fe000528fad8800428000100190000052505280008005d4034 +07060708062405041405041b050105040708000107010824000114000114000100011e100420 +040204040103050800060510030d003f3fc4d4c411123939012f5dfddd5d872b1000c187057d +10c4011810dd5d872b087d10c431300101112311012101010525fdf6f7fdf5012a015d015b05 +28fd03fdd5022b02fdfdea021600000000020003000000000014000100000000003400040020 +00000004000400010000f001ffff0000f000ffff10000001000000000006000e000000000002 +000000010000052805280000ffec00f600d200d400fa00f600b70102009201890000ffea00db +0528053e03bb03d2ffeafe7cfe900444028e0000000000000000000000f000dc00c800d200b2 +008a00d700000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000403b5451504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a3938373635 +2f2e2d2c2826252423221f181411100f0d0b0a090807060504030201002c4523466020b02660 +b004262348482d2c452346236120b02661b004262348482d2c45234660b0206120b04660b004 +262348482d2c4523462361b0206020b02661b02061b004262348482d2c45234660b0406120b0 +6660b004262348482d2c4523462361b0406020b02661b04061b004262348482d2c0110203c00 +3c2d2c20452320b0cd442320b8015a51582320b08d44235920b0ed51582320b04d44235920b0 +042651582320b00d44235921212d2c20204518684420b001602045b04676688a4560442d2c01 +b10b0a432343650a2d2c00b10a0b4323430b2d2c00b0282370b101283e01b0282370b1022845 +3ab10200080d2d2c2045b00325456164b050515845441b2121592d2c2045b0004360442d2c01 +b00643b00743650a2d2c2069b04061b0008b20b12cc08a8cb8100062602b0c642364615c58b0 +0361592d2c8a03458a8a87b0112bb0292344b0297ae4182d2c4565b02c234445b02b23442d2c +4b525845441b2121592d2c01b005251023208af500b0016023edec2d2c01b005251023208af5 +00b0016123edec2d2c01b0062510f500edec2d2c20b001600110203c003c2d2c20b001610110 +203c003c2d2c00b00743b006430b2d2c21210c6423648bb84000622d2c21b08051580c642364 +8bb82000621bb200402f2b59b002602d2c21b0c051580c6423648bb81555621bb200802f2b59 +b002602d2c0c6423648bb84000626023212d2c4523456023456023456023766818b08062202d +2cb00426b00426b00425b0042545234520b003266062636820b0032661658a2344442d2c2045 +b0005458b040442045b04061441b2121592d2c45b1302f4523456160b0016069442d2c4b5158 +b02f2370b01423421b2121592d2c4b515820b0032545695358441b2121591b2121592d2c45b0 +1443b0006063b0016069442d2cb02f45442d2c452320458a60442d2c45234560442d2c4b2351 +58b90033ffe0b134201bb3330034005944442d2cb0164358b00326458a586466b01f601b64b0 +20606620581b21b04059b001615923586559b02923442310b029e01b2121212121592d2cb016 +4358b004254564b020606620581b21b04059b0016123586559b0292344b00425b00725082058 +021b0359b0052510b004252046b0042523423cb0072510b006252046b00425b0016023423c20 +58011b0059b0052510b00425b029e0b0072510b00625b029e0b00425b00725082058021b0359 +b00425b003254348b00625b00325b0016043481b2159212121212121212d2cb0164358b00425 +4564b020606620581b21b04059b0016123581b6559b0292344b00525b00825082058021b0359 +b0042510b005252046b0042523423cb00425b0072508b0072510b006252046b00425b0016023 +423c2058011b0059b0042510b00525b029e0b02920456544b0072510b00625b029e0b00525b0 +0825082058021b0359b00525b003254348b00425b0072508b00625b00325b0016043481b2159 +212121212121212d2c02b00425202046b004252342b0052508b003254548212121212d2c02b0 +032520b0042508b0022543482121212d2c452320451820b00050205823652359236820b04050 +5821b04059235865598a60442d2c4b53234b515a5820458a60441b2121592d2c4b545820458a +60441b2121592d2c4b53234b515a58381b2121592d2c4b5458381b2121592d2c2d2c2d2c2d2c +2d2c208a08234b538a4b515a5823381b2121592d2c00208a49b0005158b04023208a3812341b +2121592d2c462346608a8a462320468a608a61b8ff8062232010238ab14b4b8a70456020b000 +5058b00161b8ffba8b1bb0468c59b0106068013a2d2c208a2349648a2353583c1b21592d2cb1 +020042b123018851b1400188535a58b910000020885458b202010243604259b12401885158b9 +20000040885458b2020202436042b12401885458b2022002436042004b014b5258b202080243 +6042591bb940000080885458b202040243604259b94000008063b80100885458b20208024360 +4259b94000010063b80200885458b202100243604259b94000020063b80400885458b2024002 +43604259595959592d000000000100000005e66680efbd0f5f0f3cf5001b080000000000c373 +8d9600000000c5c82d5ffb20fab90a840878000100090002000000000000000100000800fab8 +01000aa2fb20fe110a8400010000000000000000000000000000000204000080053e00190000 +0014005c0000000100000002007f0008008700070002001000400055000001df024c00030001 +40590704181f24042b1f1f05271f1e04271fbf0401af04019f04013f04012f04011f04010f04 +011615231f1110231f13122c1f0302231f140d231f0e0d231f0100231f2f17012f15012f1401 +2f0d012f02012f10012f12012f0001b1020042b21711018820b022518a2378b0405278b10a20 +88b810005578b1020142b0031c212101b0124b004b5442b013014b004b5342b0024358004bb0 +3c524bb008505b58b101018e591b4bb80190524bb008505b58b101018e5959b00288b8010054 +b00488b8020054b012435a5b58b80119b101018e851bb900010100b04b60858d59b0501db064 +4b5358b0801d59b0324b5358b0901d590073737373737373732b2b2b2b2b2b2b737373737373 +732b2b2b2b0000> +] def +FontName currentdict end definefont pop +%%Page: 1 1 +%%BeginPageSetup +%%PageBoundingBox: 0 0 262 96 +%%EndPageSetup +q +0.701961 g +120.16 62.468 m 120.168 59.538 l 120.359 59.308 l 120.16 62.468 l h +120.16 62.468 m 120.359 59.308 l 120.352 62.179 l 120.16 62.468 l h +120.227 36.124 m 120.23 33.198 l 120.422 33.484 l 120.223 36.124 l h +120.227 36.124 m 120.422 33.484 l 120.414 36.351 l 120.227 36.124 l h +126.207 62.452 m 126.199 33.21 l 126.273 33.495 l 126.207 62.452 l h +126.207 62.452 m 126.273 33.495 l 126.281 62.163 l 126.207 62.452 l h +94.578 59.612 m 120.168 59.538 l 120.16 62.468 l 94.578 59.612 l h +122.57 59.538 m 126.207 62.452 l 122.563 62.452 l 122.57 59.538 l h +122.57 59.538 m 126.199 33.21 l 126.207 62.452 l 122.57 59.538 l h +95.242 56.71 m 120.168 59.538 l 94.578 59.612 l 95.242 56.71 l h +95.242 56.71 m 122.57 59.538 l 120.168 59.538 l 95.242 56.71 l h +95.242 56.71 m 122.629 36.124 l 122.609 43.929 122.59 51.734 122.57 +59.538 c 95.242 56.71 l h +122.629 36.124 m 126.199 33.21 l 122.57 59.538 l 122.629 36.124 l h +94.578 59.612 m 120.16 62.468 l 93.73 62.468 l 94.578 59.612 l h +95.723 53.773 m 122.629 36.124 l 95.242 56.71 l 95.723 53.773 l h +96.016 50.812 m 122.629 36.124 l 95.723 53.773 l 96.016 50.812 l h +96.117 47.839 m 122.629 36.124 l 96.016 50.812 l 96.117 47.839 l h +96.027 44.862 m 122.629 36.124 l 96.117 47.839 l 96.027 44.862 l h +95.75 41.902 m 122.629 36.124 l 96.027 44.862 l 95.75 41.902 l h +95.285 38.96 m 122.629 36.124 l 95.75 41.902 l 95.285 38.96 l h +94.637 36.058 m 120.227 36.124 l 95.285 38.96 l 94.637 36.058 l h +120.227 36.124 m 122.629 36.124 l 95.285 38.96 l 120.227 36.124 l h +94.637 36.058 m 120.23 33.198 l 120.227 36.124 l 94.637 36.058 l h +122.637 33.21 m 126.199 33.21 l 122.629 36.124 l 122.633 33.21 l h +93.801 33.198 m 120.23 33.198 l 94.637 36.058 l 93.801 33.198 l h +93.801 33.198 m f +1 0.603922 0 rg +45.156 0.452 m 48.172 0.366 l 51.191 0.464 l 45.156 0.452 l h +45.156 0.452 m 51.191 0.464 l 42.148 0.726 l 45.156 0.452 l h +42.148 0.726 m 51.191 0.464 l 54.195 0.753 l 42.148 0.726 l h +42.148 0.726 m 54.195 0.753 l 39.164 1.183 l 42.148 0.726 l h +39.164 1.183 m 54.195 0.753 l 57.176 1.226 l 39.164 1.183 l h +39.164 1.183 m 57.176 1.226 l 36.219 1.823 l 39.164 1.183 l h +36.219 1.823 m 57.176 1.226 l 60.121 1.882 l 36.219 1.823 l h +36.219 1.823 m 60.121 1.882 l 33.316 2.648 l 36.219 1.823 l h +33.316 2.648 m 60.121 1.882 l 63.02 2.718 l 33.316 2.648 l h +33.316 2.648 m 63.02 2.718 l 30.473 3.648 l 33.316 2.648 l h +30.473 3.648 m 63.02 2.718 l 65.855 3.734 l 30.473 3.648 l h +30.473 3.648 m 65.855 3.734 l 27.699 4.823 l 30.473 3.648 l h +27.699 4.823 m 65.855 3.734 l 68.625 4.921 l 27.699 4.823 l h +27.699 4.823 m 68.625 4.921 l 25.008 6.167 l 27.699 4.823 l h +25.008 6.167 m 68.625 4.921 l 71.313 6.277 l 25.008 6.167 l h +25.008 6.167 m 71.313 6.277 l 22.402 7.679 l 25.008 6.167 l h +22.402 7.679 m 71.313 6.277 l 73.906 7.796 l 22.402 7.679 l h +22.402 7.679 m 73.906 7.796 l 19.902 9.343 l 22.402 7.679 l h +19.902 9.343 m 73.906 7.796 l 76.398 9.476 l 19.902 9.343 l h +19.902 9.343 m 76.398 9.476 l 17.512 11.163 l 19.902 9.343 l h +17.512 11.163 m 76.398 9.476 l 78.781 11.304 l 17.512 11.163 l h +17.512 11.163 m 78.781 11.304 l 15.242 13.124 l 17.512 11.163 l h +15.242 13.124 m 78.781 11.304 l 81.039 13.277 l 15.242 13.124 l h +15.242 13.124 m 81.039 13.277 l 13.102 15.222 l 15.242 13.124 l h +13.102 15.222 m 81.039 13.277 l 83.168 15.386 l 13.102 15.222 l h +13.102 15.222 m 83.168 15.386 l 11.102 17.448 l 13.102 15.222 l h +11.102 17.448 m 83.168 15.386 l 85.16 17.624 l 11.102 17.448 l h +11.102 17.448 m 85.16 17.624 l 9.246 19.796 l 11.102 17.448 l h +9.246 19.796 m 85.16 17.624 l 87.004 19.98 l 9.246 19.796 l h +9.246 19.796 m 87.004 19.98 l 7.543 22.253 l 9.246 19.796 l h +7.543 22.253 m 87.004 19.98 l 88.695 22.444 l 7.543 22.253 l h +7.543 22.253 m 88.695 22.444 l 6 24.812 l 7.543 22.253 l h +6 24.812 m 88.695 22.444 l 90.227 25.007 l 6 24.812 l h +6 24.812 m 90.227 25.007 l 4.621 27.456 l 6 24.812 l h +4.621 27.456 m 90.227 25.007 l 91.59 27.663 l 4.621 27.456 l h +4.621 27.456 m 91.59 27.663 l 3.418 30.187 l 4.621 27.456 l h +3.418 30.187 m 91.59 27.663 l 92.785 30.394 l 3.418 30.187 l h +3.418 30.187 m 92.785 30.394 l 2.387 32.984 l 3.418 30.187 l h +2.387 32.984 m 92.785 30.394 l 93.801 33.198 l 2.387 32.984 l h +2.387 32.984 m 93.801 33.198 l 67.582 33.198 l 2.387 32.984 l h +2.387 32.984 m 67.582 33.198 l 66.648 33.226 l 2.387 32.984 l h +2.387 32.984 m 66.648 33.226 l 65.719 33.312 l 2.387 32.984 l h +2.387 32.984 m 65.719 33.312 l 64.797 33.452 l 2.387 32.984 l h +2.387 32.984 m 64.797 33.452 l 63.887 33.652 l 2.387 32.984 l h +2.387 32.984 m 63.887 33.652 l 62.988 33.905 l 2.387 32.984 l h +2.387 32.984 m 62.988 33.905 l 62.109 34.218 l 2.387 32.984 l h +2.387 32.984 m 62.109 34.218 l 61.254 34.581 l 2.387 32.984 l h +2.387 32.984 m 61.254 34.581 l 60.422 34.995 l 2.387 32.984 l h +2.387 32.984 m 60.422 34.995 l 59.617 35.464 l 2.387 32.984 l h +2.387 32.984 m 59.617 35.464 l 1.539 35.839 l 2.387 32.984 l h +1.539 35.839 m 59.617 35.464 l 58.844 35.98 l 1.539 35.839 l h +1.539 35.839 m 58.844 35.98 l 58.105 36.542 l 1.539 35.839 l h +1.539 35.839 m 58.105 36.542 l 57.406 37.148 l 1.539 35.839 l h +1.539 35.839 m 57.406 37.148 l 56.742 37.796 l 1.539 35.839 l h +1.539 35.839 m 56.742 37.796 l 56.125 38.487 l 1.539 35.839 l h +1.539 35.839 m 56.125 38.487 l 0.871 38.741 l 1.539 35.839 l h +0.871 38.741 m 56.125 38.487 l 55.551 39.214 l 0.871 38.741 l h +0.871 38.741 m 55.551 39.214 l 55.027 39.972 l 0.871 38.741 l h +0.871 38.741 m 55.027 39.972 l 54.551 40.761 l 0.871 38.741 l h +0.871 38.741 m 54.551 40.761 l 54.125 41.581 l 0.871 38.741 l h +0.871 38.741 m 54.125 41.581 l 0.395 41.679 l 0.871 38.741 l h +0.395 41.679 m 54.125 41.581 l 53.754 42.425 l 0.395 41.679 l h +0.395 41.679 m 53.754 42.425 l 53.434 43.288 l 0.395 41.679 l h +0.395 41.679 m 53.434 43.288 l 53.172 44.171 l 0.395 41.679 l h +0.395 41.679 m 53.172 44.171 l 0.102 44.64 l 0.395 41.679 l h +0.102 44.64 m 53.172 44.171 l 52.969 45.069 l 0.102 44.64 l h +0.102 44.64 m 52.969 45.069 l 52.82 45.98 l 0.102 44.64 l h +0.102 44.64 m 52.82 45.98 l 52.73 46.894 l 0.102 44.64 l h +0.102 44.64 m 52.73 46.894 l 0 47.612 l 0.102 44.64 l h +0 47.612 m 52.73 46.894 l 52.699 47.812 l 0 47.612 l h +0 47.612 m 52.699 47.812 l 52.727 48.734 l 0 47.612 l h +0 47.612 m 52.727 48.734 l 52.813 49.648 l 0 47.612 l h +0 47.612 m 52.813 49.648 l 52.957 50.558 l 0 47.612 l h +0 47.612 m 52.957 50.558 l 0.09 50.585 l 0 47.612 l h +0.09 50.585 m 52.957 50.558 l 53.16 51.452 l 0.09 50.585 l h +0.09 50.585 m 53.16 51.452 l 53.418 52.339 l 0.09 50.585 l h +0.09 50.585 m 53.418 52.339 l 53.734 53.202 l 0.09 50.585 l h +0.09 50.585 m 53.734 53.202 l 0.363 53.55 l 0.09 50.585 l h +0.363 53.55 m 53.734 53.202 l 54.102 54.05 l 0.363 53.55 l h +0.363 53.55 m 54.102 54.05 l 54.523 54.87 l 0.363 53.55 l h +0.363 53.55 m 54.523 54.87 l 55 55.659 l 0.363 53.55 l h +0.363 53.55 m 55 55.659 l 55.52 56.421 l 0.363 53.55 l h +0.363 53.55 m 55.52 56.421 l 0.828 56.487 l 0.363 53.55 l h +0.828 56.487 m 55.52 56.421 l 56.094 57.152 l 0.828 56.487 l h +0.828 56.487 m 56.094 57.152 l 56.707 57.843 l 0.828 56.487 l h +0.828 56.487 m 56.707 57.843 l 57.367 58.491 l 0.828 56.487 l h +0.828 56.487 m 57.367 58.491 l 58.066 59.101 l 0.828 56.487 l h +0.828 56.487 m 58.066 59.101 l 1.48 59.394 l 0.828 56.487 l h +1.48 59.394 m 58.066 59.101 l 58.801 59.667 l 1.48 59.394 l h +1.48 59.394 m 58.801 59.667 l 59.574 60.187 l 1.48 59.394 l h +1.48 59.394 m 59.574 60.187 l 60.375 60.655 l 1.48 59.394 l h +1.48 59.394 m 60.375 60.655 l 61.207 61.073 l 1.48 59.394 l h +1.48 59.394 m 61.207 61.073 l 62.063 61.441 l 1.48 59.394 l h +1.48 59.394 m 62.063 61.441 l 62.941 61.753 l 1.48 59.394 l h +1.48 59.394 m 62.941 61.753 l 63.836 62.011 l 1.48 59.394 l h +1.48 59.394 m 63.836 62.011 l 64.746 62.214 l 1.48 59.394 l h +1.48 59.394 m 64.746 62.214 l 2.316 62.253 l 1.48 59.394 l h +2.316 62.253 m 64.746 62.214 l 65.668 62.359 l 2.316 62.253 l h +2.316 62.253 m 65.668 62.359 l 66.598 62.448 l 2.316 62.253 l h +2.316 62.253 m 66.598 62.448 l 67.531 62.48 l 2.316 62.253 l h +67.531 62.48 m 93.73 62.468 l 3.332 65.054 l 67.531 62.48 l h +2.316 62.253 m 67.531 62.48 l 3.332 65.054 l 2.316 62.253 l h +3.332 65.054 m 93.73 62.468 l 92.699 65.265 l 3.332 65.054 l h +3.332 65.054 m 92.699 65.265 l 4.523 67.788 l 3.332 65.054 l h +4.523 67.788 m 92.699 65.265 l 91.492 67.991 l 4.523 67.788 l h +4.523 67.788 m 91.492 67.991 l 5.891 70.441 l 4.523 67.788 l h +5.891 70.441 m 91.492 67.991 l 90.117 70.64 l 5.891 70.441 l h +5.891 70.441 m 90.117 70.64 l 7.422 73.007 l 5.891 70.441 l h +7.422 73.007 m 90.117 70.64 l 88.574 73.198 l 7.422 73.007 l h +7.422 73.007 m 88.574 73.198 l 9.113 75.472 l 7.422 73.007 l h +9.113 75.472 m 88.574 73.198 l 86.871 75.655 l 9.113 75.472 l h +9.113 75.472 m 86.871 75.655 l 10.957 77.827 l 9.113 75.472 l h +10.957 77.827 m 86.871 75.655 l 85.016 77.999 l 10.957 77.827 l h +10.957 77.827 m 85.016 77.999 l 12.949 80.062 l 10.957 77.827 l h +12.949 80.062 m 85.016 77.999 l 83.012 80.226 l 12.949 80.062 l h +12.949 80.062 m 83.012 80.226 l 15.078 82.171 l 12.949 80.062 l h +15.078 82.171 m 83.012 80.226 l 80.875 82.327 l 15.078 82.171 l h +15.078 82.171 m 80.875 82.327 l 17.336 84.144 l 15.078 82.171 l h +17.336 84.144 m 80.875 82.327 l 78.605 84.288 l 17.336 84.144 l h +17.336 84.144 m 78.605 84.288 l 19.719 85.976 l 17.336 84.144 l h +19.719 85.976 m 78.605 84.288 l 76.215 86.105 l 19.719 85.976 l h +19.719 85.976 m 76.215 86.105 l 22.211 87.652 l 19.719 85.976 l h +22.211 87.652 m 76.215 86.105 l 73.715 87.773 l 22.211 87.652 l h +22.211 87.652 m 73.715 87.773 l 24.805 89.171 l 22.211 87.652 l h +24.805 89.171 m 73.715 87.773 l 71.109 89.28 l 24.805 89.171 l h +24.805 89.171 m 71.109 89.28 l 27.492 90.53 l 24.805 89.171 l h +27.492 90.53 m 71.109 89.28 l 68.418 90.624 l 27.492 90.53 l h +27.492 90.53 m 68.418 90.624 l 30.262 91.718 l 27.492 90.53 l h +30.262 91.718 m 68.418 90.624 l 65.645 91.8 l 30.262 91.718 l h +30.262 91.718 m 65.645 91.8 l 33.098 92.734 l 30.262 91.718 l h +33.098 92.734 m 65.645 91.8 l 62.801 92.804 l 33.098 92.734 l h +33.098 92.734 m 62.801 92.804 l 35.996 93.569 l 33.098 92.734 l h +35.996 93.569 m 62.801 92.804 l 59.898 93.624 l 35.996 93.569 l h +35.996 93.569 m 59.898 93.624 l 38.941 94.226 l 35.996 93.569 l h +38.941 94.226 m 59.898 93.624 l 56.953 94.269 l 38.941 94.226 l h +38.941 94.226 m 56.953 94.269 l 41.922 94.698 l 38.941 94.226 l h +41.922 94.698 m 56.953 94.269 l 53.969 94.726 l 41.922 94.698 l h +41.922 94.698 m 53.969 94.726 l 44.926 94.984 l 41.922 94.698 l h +44.926 94.984 m 53.969 94.726 l 50.961 94.999 l 44.926 94.984 l h +44.926 94.984 m 50.961 94.999 l 47.945 95.085 l 44.926 94.984 l h +66.648 33.226 m 68.805 33.484 l 67.891 33.511 l 66.648 33.226 l h +66.648 33.226 m 67.582 33.198 l 68.805 33.484 l 66.648 33.226 l h +65.719 33.312 m 67.891 33.511 l 66.98 33.593 l 65.719 33.312 l h +65.719 33.312 m 66.648 33.226 l 67.891 33.511 l 65.719 33.312 l h +64.797 33.452 m 66.98 33.593 l 66.074 33.734 l 64.797 33.452 l h +64.797 33.452 m 65.719 33.312 l 66.98 33.593 l 64.797 33.452 l h +63.887 33.652 m 66.074 33.734 l 65.184 33.929 l 63.887 33.652 l h +63.887 33.652 m 64.797 33.452 l 66.074 33.734 l 63.887 33.652 l h +62.988 33.905 m 65.184 33.929 l 64.301 34.179 l 62.988 33.905 l h +62.988 33.905 m 63.887 33.652 l 65.184 33.929 l 62.988 33.905 l h +62.109 34.218 m 64.301 34.179 l 63.441 34.484 l 62.109 34.218 l h +62.109 34.218 m 62.988 33.905 l 64.301 34.179 l 62.109 34.218 l h +61.254 34.581 m 63.441 34.484 l 62.602 34.839 l 61.254 34.581 l h +61.254 34.581 m 62.109 34.218 l 63.441 34.484 l 61.254 34.581 l h +60.422 34.995 m 62.602 34.839 l 61.785 35.245 l 60.422 34.995 l h +60.422 34.995 m 61.254 34.581 l 62.602 34.839 l 60.422 34.995 l h +59.617 35.464 m 61.785 35.245 l 60.996 35.702 l 59.617 35.464 l h +59.617 35.464 m 60.422 34.995 l 61.785 35.245 l 59.617 35.464 l h +58.844 35.98 m 60.996 35.702 l 60.238 36.21 l 58.844 35.98 l h +58.844 35.98 m 59.617 35.464 l 60.996 35.702 l 58.844 35.98 l h +58.105 36.542 m 60.238 36.21 l 59.516 36.761 l 58.105 36.542 l h +58.105 36.542 m 58.844 35.98 l 60.238 36.21 l 58.105 36.542 l h +57.406 37.148 m 59.516 36.761 l 58.828 37.355 l 57.406 37.148 l h +57.406 37.148 m 58.105 36.542 l 59.516 36.761 l 57.406 37.148 l h +56.742 37.8 m 58.828 37.355 l 58.18 37.991 l 56.742 37.8 l h +56.742 37.8 m 57.406 37.148 l 58.828 37.355 l 56.742 37.8 l h +56.125 38.487 m 58.18 37.991 l 57.574 38.667 l 56.125 38.487 l h +56.125 38.487 m 56.742 37.8 l 58.18 37.991 l 56.125 38.487 l h +55.551 39.214 m 57.574 38.667 l 57.012 39.378 l 55.551 39.214 l h +55.551 39.214 m 56.125 38.487 l 57.574 38.667 l 55.551 39.214 l h +55.027 39.972 m 57.012 39.378 l 56.496 40.124 l 55.027 39.972 l h +55.027 39.972 m 55.551 39.214 l 57.012 39.378 l 55.027 39.972 l h +54.551 40.761 m 56.496 40.124 l 56.027 40.898 l 54.551 40.761 l h +54.551 40.761 m 55.027 39.972 l 56.496 40.124 l 54.551 40.761 l h +54.125 41.581 m 56.027 40.898 l 55.609 41.702 l 54.125 41.581 l h +54.125 41.581 m 54.551 40.761 l 56.027 40.898 l 54.125 41.581 l h +53.754 42.425 m 55.609 41.702 l 55.246 42.53 l 53.754 42.425 l h +53.754 42.425 m 54.125 41.581 l 55.609 41.702 l 53.754 42.425 l h +53.434 43.292 m 55.246 42.53 l 54.934 43.378 l 53.434 43.292 l h +53.434 43.292 m 53.754 42.425 l 55.246 42.53 l 53.434 43.292 l h +53.172 44.171 m 54.934 43.378 l 54.68 44.241 l 53.172 44.171 l h +53.172 44.171 m 53.434 43.292 l 54.934 43.378 l 53.172 44.171 l h +52.969 45.069 m 54.68 44.241 l 54.477 45.12 l 52.969 45.069 l h +52.969 45.069 m 53.172 44.171 l 54.68 44.241 l 52.969 45.069 l h +52.82 45.98 m 54.477 45.12 l 54.332 46.011 l 52.82 45.98 l h +52.82 45.98 m 52.969 45.069 l 54.477 45.12 l 52.82 45.98 l h +52.73 46.894 m 54.332 46.011 l 54.246 46.909 l 52.73 46.894 l h +52.73 46.894 m 52.82 45.98 l 54.332 46.011 l 52.73 46.894 l h +52.699 47.812 m 54.246 46.909 l 54.215 47.812 l 52.699 47.812 l h +52.699 47.812 m 52.73 46.894 l 54.246 46.909 l 52.699 47.812 l h +52.727 48.734 m 54.215 47.812 l 54.242 48.714 l 52.727 48.734 l h +52.727 48.734 m 52.699 47.812 l 54.215 47.812 l 52.727 48.734 l h +52.813 49.648 m 54.242 48.714 l 54.328 49.609 l 52.813 49.648 l h +52.813 49.648 m 52.727 48.734 l 54.242 48.714 l 52.813 49.648 l h +52.957 50.558 m 54.328 49.609 l 54.469 50.499 l 52.957 50.558 l h +52.957 50.558 m 52.813 49.648 l 54.328 49.609 l 52.957 50.558 l h +53.16 51.456 m 54.469 50.499 l 54.664 51.382 l 53.16 51.456 l h +53.16 51.456 m 52.957 50.558 l 54.469 50.499 l 53.16 51.456 l h +53.418 52.339 m 54.664 51.382 l 54.918 52.249 l 53.418 52.339 l h +53.418 52.339 m 53.16 51.456 l 54.664 51.382 l 53.418 52.339 l h +53.734 53.202 m 54.918 52.249 l 55.227 53.097 l 53.734 53.202 l h +53.734 53.202 m 53.418 52.339 l 54.918 52.249 l 53.734 53.202 l h +54.102 54.05 m 55.227 53.097 l 55.59 53.925 l 54.102 54.05 l h +54.102 54.05 m 53.734 53.202 l 55.227 53.097 l 54.102 54.05 l h +54.523 54.87 m 55.59 53.925 l 56.004 54.73 l 54.523 54.87 l h +54.523 54.87 m 54.102 54.05 l 55.59 53.925 l 54.523 54.87 l h +55 55.659 m 56.004 54.73 l 56.469 55.507 l 55 55.659 l h +55 55.659 m 54.523 54.87 l 56.004 54.73 l 55 55.659 l h +55.52 56.421 m 56.469 55.507 l 56.98 56.253 l 55.52 56.421 l h +55.52 56.421 m 55 55.659 l 56.469 55.507 l 55.52 56.421 l h +56.094 57.152 m 56.98 56.253 l 57.539 56.964 l 56.094 57.152 l h +56.094 57.152 m 55.52 56.421 l 56.98 56.253 l 56.094 57.152 l h +56.707 57.843 m 57.539 56.964 l 58.145 57.644 l 56.707 57.843 l h +56.707 57.843 m 56.094 57.152 l 57.539 56.964 l 56.707 57.843 l h +57.367 58.491 m 58.145 57.644 l 58.789 58.28 l 57.367 58.491 l h +57.367 58.491 m 56.707 57.843 l 58.145 57.644 l 57.367 58.491 l h +58.066 59.105 m 58.789 58.28 l 59.477 58.878 l 58.066 59.105 l h +58.066 59.105 m 57.367 58.491 l 58.789 58.28 l 58.066 59.105 l h +58.801 59.667 m 59.477 58.878 l 60.199 59.433 l 58.801 59.667 l h +58.801 59.667 m 58.066 59.105 l 59.477 58.878 l 58.801 59.667 l h +59.574 60.187 m 60.199 59.433 l 60.953 59.941 l 59.574 60.187 l h +59.574 60.187 m 58.801 59.667 l 60.199 59.433 l 59.574 60.187 l h +60.375 60.655 m 60.953 59.941 l 61.738 60.402 l 60.375 60.655 l h +60.375 60.655 m 59.574 60.187 l 60.953 59.941 l 60.375 60.655 l h +61.207 61.073 m 61.738 60.402 l 62.555 60.812 l 61.207 61.073 l h +61.207 61.073 m 60.375 60.655 l 61.738 60.402 l 61.207 61.073 l h +62.063 61.441 m 62.555 60.812 l 63.395 61.171 l 62.063 61.441 l h +62.063 61.441 m 61.207 61.073 l 62.555 60.812 l 62.063 61.441 l h +62.941 61.753 m 63.395 61.171 l 64.254 61.48 l 62.941 61.753 l h +62.941 61.753 m 62.063 61.441 l 63.395 61.171 l 62.941 61.753 l h +63.836 62.011 m 64.254 61.48 l 65.133 61.734 l 63.836 62.011 l h +63.836 62.011 m 62.941 61.753 l 64.254 61.48 l 63.836 62.011 l h +64.746 62.214 m 65.133 61.734 l 66.023 61.929 l 64.746 62.214 l h +64.746 62.214 m 63.836 62.011 l 65.133 61.734 l 64.746 62.214 l h +65.668 62.359 m 66.023 61.929 l 66.93 62.073 l 65.668 62.359 l h +65.668 62.359 m 64.746 62.214 l 66.023 61.929 l 65.668 62.359 l h +66.598 62.448 m 66.93 62.073 l 67.84 62.159 l 66.598 62.448 l h +66.598 62.448 m 65.668 62.359 l 66.93 62.073 l 66.598 62.448 l h +67.531 62.48 m 67.84 62.159 l 68.754 62.191 l 67.531 62.48 l h +67.531 62.48 m 66.598 62.448 l 67.84 62.159 l 67.531 62.48 l h +67.582 33.198 m 94.508 33.484 l 68.805 33.484 l 67.582 33.198 l h +67.582 33.198 m 93.801 33.198 l 94.508 33.484 l 67.582 33.198 l h +78.781 11.304 m 77.449 10.226 l 79.785 12.019 l 78.781 11.304 l h +78.781 11.304 m 76.398 9.476 l 77.449 10.226 l 78.781 11.304 l h +81.039 13.277 m 79.785 12.019 l 82 13.952 l 81.039 13.277 l h +81.039 13.277 m 78.781 11.304 l 79.785 12.019 l 81.039 13.277 l h +83.168 15.386 m 82 13.952 l 84.086 16.023 l 83.168 15.386 l h +83.168 15.386 m 81.039 13.277 l 82 13.952 l 83.168 15.386 l h +85.16 17.624 m 84.086 16.023 l 86.039 18.214 l 85.16 17.624 l h +85.16 17.624 m 83.168 15.386 l 84.086 16.023 l 85.16 17.624 l h +87.004 19.98 m 86.039 18.214 l 87.848 20.523 l 87.004 19.98 l h +87.004 19.98 m 85.16 17.624 l 86.039 18.214 l 87.004 19.98 l h +88.695 22.444 m 87.848 20.523 l 89.508 22.941 l 88.695 22.444 l h +88.695 22.444 m 87.004 19.98 l 87.848 20.523 l 88.695 22.444 l h +90.227 25.007 m 89.508 22.941 l 91.008 25.452 l 90.227 25.007 l h +90.227 25.007 m 88.695 22.444 l 89.508 22.941 l 90.227 25.007 l h +91.59 27.663 m 90.227 25.007 l 91.008 25.452 l 91.59 27.663 l h +93.73 62.468 m 68.754 62.191 l 94.441 62.179 l 93.73 62.468 l h +93.73 62.468 m 67.531 62.48 l 68.754 62.191 l 93.73 62.468 l h +90.117 70.64 m 92.25 67.593 l 90.898 70.191 l 90.117 70.64 l h +90.117 70.64 m 91.492 67.991 l 92.25 67.593 l 90.117 70.64 l h +88.574 73.198 m 90.898 70.191 l 89.387 72.698 l 88.574 73.198 l h +88.574 73.198 m 90.117 70.64 l 90.898 70.191 l 88.574 73.198 l h +86.871 75.655 m 89.387 72.698 l 87.715 75.105 l 86.871 75.655 l h +86.871 75.655 m 88.574 73.198 l 89.387 72.698 l 86.871 75.655 l h +85.016 77.999 m 87.715 75.105 l 85.895 77.405 l 85.016 77.999 l h +85.016 77.999 m 86.871 75.655 l 87.715 75.105 l 85.016 77.999 l h +83.012 80.226 m 85.895 77.405 l 83.934 79.589 l 83.012 80.226 l h +83.012 80.226 m 85.016 77.999 l 85.895 77.405 l 83.012 80.226 l h +80.875 82.327 m 83.934 79.589 l 81.836 81.648 l 80.875 82.327 l h +80.875 82.327 m 83.012 80.226 l 83.934 79.589 l 80.875 82.327 l h +78.605 84.288 m 81.836 81.648 l 79.609 83.573 l 78.605 84.288 l h +78.605 84.288 m 80.875 82.327 l 81.836 81.648 l 78.605 84.288 l h +76.215 86.105 m 79.609 83.573 l 77.27 85.355 l 76.215 86.105 l h +76.215 86.105 m 78.605 84.288 l 79.609 83.573 l 76.215 86.105 l h +91.492 67.991 m 92.699 65.265 l 93.43 64.921 l 91.492 67.991 l h +91.492 67.991 m 93.43 64.921 l 92.25 67.593 l 91.492 67.991 l h +92.699 65.265 m 93.73 62.468 l 94.441 62.179 l 92.699 65.265 l h +92.699 65.265 m 94.441 62.179 l 93.43 64.921 l 92.699 65.265 l h +93.801 33.198 m 92.785 30.394 l 93.512 30.734 l 93.801 33.198 l h +93.801 33.198 m 93.512 30.734 l 94.508 33.484 l 93.801 33.198 l h +92.785 30.394 m 91.59 27.663 l 92.344 28.054 l 92.785 30.394 l h +92.785 30.394 m 92.344 28.054 l 93.512 30.734 l 92.785 30.394 l h +91.59 27.663 m 91.008 25.452 l 92.344 28.054 l 91.59 27.663 l h +91.59 27.663 m f +128.605 51.343 m 128.605 44.323 l 183.871 47.831 l 128.605 51.343 l h +260.77 62.452 m 128.609 62.452 l 128.609 56.605 l 260.77 62.452 l h +128.605 39.058 m 128.602 33.21 l 260.762 33.21 l 128.605 39.058 l h +128.605 39.058 m 258.199 33.495 l 128.629 39.23 l 128.605 39.058 l h +128.605 39.058 m 260.762 33.21 l 258.199 33.495 l 128.605 39.058 l h +128.605 56.605 m 258.203 62.163 l 260.77 62.452 l 128.605 56.605 l h +128.605 56.605 m 128.633 56.429 l 258.203 62.163 l 128.605 56.605 l h +128.605 56.605 m f +0.701961 g +BT +60.913132 0 0 22.53534 93.670855 11.585044 Tm +/f-0-0 1 Tf +[<010203>-1<0304>-1<05>]TJ +ET +0 g +57.547 65.73 m 40.297 75.804 l 49.949 92.702 l 67.199 82.632 l 57.547 +65.73 l h +57.547 65.73 m f +43.293 47.835 m 23.574 51.515 l 26.746 70.632 l 46.469 66.952 l 43.293 +47.835 l h +43.293 47.835 m f +47.531 27.269 m 27.715 24.116 l 24.027 43.144 l 43.844 46.296 l 47.531 +27.269 l h +47.531 27.269 m f +59.633 23.691 m 59.359 4.011 l 39.605 3.753 l 39.879 23.437 l 59.633 +23.691 l h +59.633 23.691 m f +BT +13.363021 0 0 14.275113 94.96445 0.00000172127 Tm +/f-1-0 1 Tf +<01>Tj +14.826648 0 0 14.275113 106.759489 -0.000000768731 Tm +/f-2-0 1 Tf +<01>Tj +14.826647 0 0 14.275112 119.430098 -0.000000768731 Tm +/f-3-0 1 Tf +<01>Tj +/f-4-0 1 Tf +0.794147 0.010254 Td +<01>Tj +/f-5-0 1 Tf +0.803797 -0.010254 Td +<01>Tj +/f-6-0 1 Tf +0.467029 0.010254 Td +<01>Tj +/f-7-0 1 Tf +[<>-107<01>]TJ +/f-8-0 1 Tf +2.632227 -0.010254 Td +<01>Tj +/f-9-0 1 Tf +[<>-154<01>]TJ +/f-10-0 1 Tf +[<>-199<01>]TJ +/f-11-0 1 Tf +[<>-130<01>]TJ +/f-12-0 1 Tf +[<>-129<01>]TJ +/f-13-0 1 Tf +[<>-155<01>]TJ +/f-14-0 1 Tf +[<>-109<01>]TJ +ET +Q +showpage +%%Trailer +count op_count sub {pop} repeat +countdictstack dict_count sub {end} repeat +cairo_eps_state restore +%%EOF diff --git a/docs/faq.tex b/docs/faq.tex new file mode 100644 index 0000000..6979d78 --- /dev/null +++ b/docs/faq.tex @@ -0,0 +1,3 @@ + +\chapter{Frequently asked questions} +Here is a placeholder for a future FAQ. For more information it is best to visit the Bullet Physics forums and wiki at \url{http://bulletphysics.org}. diff --git a/docs/helloworld.tex b/docs/helloworld.tex new file mode 100644 index 0000000..1c417d8 --- /dev/null +++ b/docs/helloworld.tex @@ -0,0 +1,15 @@ +\chapter{Hello World} +\section{C++ console program} +Let's discuss the creation of a basic Bullet simulation from the beginning to the end. For simplicity we print the state of the simulation to console using printf, instead of using 3D graphics to display the objects. The source code of this tutorial is located in \path{Demos/HelloWorld/HelloWorld.cpp}. + +It is a good idea to try to compile, link and run this HelloWorld.cpp program first. + +As you can see in \ref{helloworld_includefiles} you can include a convenience header file \path{btBulletDynamicsCommon.h}. + +\lstinputlisting[caption=HelloWorld.cpp include header, label=helloworld_includefiles,linerange=includes_start-includes_end]{../Demos/HelloWorld/HelloWorld.cpp} +Now we create the dynamics world: +\lstinputlisting[caption=HelloWorld.cpp initialize world, label=stepsimulation,linerange=initialization_start-initialization_end]{../Demos/HelloWorld/HelloWorld.cpp} +Once the world is created you can step the simulation as follows: +\lstinputlisting[caption=HelloWorld.cpp step simulation, label=stepsimulation,linerange=stepsimulation_start-stepsimulation_end]{../Demos/HelloWorld/HelloWorld.cpp} +At the end of the program you delete all objects in the reverse order of creation. Here is the cleanup listing of our HelloWorld.cpp program. +\lstinputlisting[caption=HelloWorld.cpp cleanup, label=cleanup,linerange=cleanup_start-cleanup_end]{../Demos/HelloWorld/HelloWorld.cpp} diff --git a/docs/intro.tex b/docs/intro.tex new file mode 100644 index 0000000..9bb737c --- /dev/null +++ b/docs/intro.tex @@ -0,0 +1,36 @@ + +%Use the \path{Demos/MyDemo} instead of \texttt{Demos/MyDemo} otherwise text doesn't wrap +%and runs into the right margin + +\chapter{Introduction to Bullet} +%\section{blablaIntroduction} +Bullet Physics is a professional open source collision detection, rigid body and soft body dynamics library. The library is free for commercial use under the \index{zlib license} \href{http://opensource.org/licenses/zlib-license.php}{zlib license}. + +\section{Main Features} + +\begin{itemize} + \item Open source C++ code under zlib license and free for any commercial use on all platforms including PLAYSTATION 3, XBox 360, Wii, PC, Linux, Mac OSX, Android and iPhone + \item Discrete and continuous collision detection including ray and convex sweep test. Collision shapes include concave and convex meshes and all basic primitives + \item Fast and stable rigid body dynamics constraint solver, vehicle dynamics, character controller and slider, hinge, generic 6DOF and cone twist constraint for ragdolls + \item Soft Body dynamics for cloth, rope and deformable volumes with two-way interaction with rigid bodies, including constraint support + \item Maya Dynamica plugin, Blender integration, COLLADA physics import/export support +\end{itemize} + +\section{Contact and Support} +\begin{itemize} + \item Public forum for support and feedback is available at \url{http://bulletphysics.org} + \item PLAYSTATION 3 licensed developers can download an optimized version for Cell SPU through Sony \href{https://ps3.scedev.net/projects/spubullet}{PS3 Devnet}. +\end{itemize} + +\section{What's new} +\subsection{New in Bullet 2.81} +\begin{itemize} + \item SIMD and Neon optimizations for iOS and Mac OSX, thanks to a contribution from Apple + \item Rolling Friction using a constraint, thanks to Erin Catto for the idea. See \path{Demos/RollingFrictionDemo/RollingFrictionDemo.cpp} + \item XML serialization. See \path{Bullet/Demos/BulletXmlImportDemo} and \path{Bullet/Demos/SerializeDemo} + \item Gear constraint. See \path{Bullet/Demos/ConstraintDemo}. + \item Improved continuous collision response, feeding speculative contacts to the constraint solver. See \path{Bullet/Demos/CcdPhysicsDemo} + \item Improved premake4 build system including support for Mac OSX, Linux and iOS + \item Refactoring of collision detection pipeline using stack allocation instead of modifying the collision object. This will allow better future multithreading optimizations. +\end{itemize} + diff --git a/docs/titlepic.sty b/docs/titlepic.sty new file mode 100644 index 0000000..974885c --- /dev/null +++ b/docs/titlepic.sty @@ -0,0 +1,68 @@ +% titlepic.sty is a LaTeX package to show a picture on the cover produced by \maketitle. +% By Thomas ten Cate . Free software, no warranty of any kind. +% +% Version history: +% 1.1: now more self-contained, comes with a PDF manual +% 1.0: first release +% +% ----------------------------------------------------------------------------- + +% No idea whether it works on older LaTeXes. +\NeedsTeXFormat{LaTeX2e} + +% Package identification and version number. +\ProvidesPackage{titlepic}[2009/08/03 1.1 Package to display a picture on the title page] + +% Declare the options. +\DeclareOption{tt}{\gdef\@tptopspace{}\gdef\@tpsepspace{\vskip 3em}} +\DeclareOption{tc}{\gdef\@tptopspace{}\gdef\@tpsepspace{\vfil}} +\DeclareOption{cc}{\gdef\@tptopspace{\null\vfil}\gdef\@tpsepspace{\vskip 3em}} +\ExecuteOptions{cc} +\ProcessOptions + +% Define the sole command introduced by this package. +% Very similar to the definition of \title, etc. +\def\titlepic#1{\gdef\@titlepic{#1}} +\def\@titlepic{\@empty} % default: no picture + +% If a title page was requested from the document class (article/report/book), +% override \maketitle to show our picture. +\if@titlepage +\renewcommand\maketitle{ + \begin{titlepage}% + \let\footnotesize\small + \let\footnoterule\relax + \let \footnote \thanks + \@tptopspace% + \begin{center}% + {\LARGE \@title \par}% + \vskip 3em% + {\large + \lineskip .75em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par% + }% + \vskip 1.5em% + {\large \@date \par}% % Set date in \large size. + \end{center}\par + \@tpsepspace% + {\centering\@titlepic\par} + \vfil + \@thanks + \end{titlepage}% + \setcounter{footnote}{0}% + \global\let\thanks\relax + \global\let\maketitle\relax + \global\let\@thanks\@empty + \global\let\@author\@empty + \global\let\@date\@empty + \global\let\@title\@empty + \global\let\@titlepic\@empty + \global\let\title\relax + \global\let\author\relax + \global\let\date\relax + \global\let\and\relax + \global\let\titlepic\relax +} +\fi diff --git a/file.obj b/file.obj new file mode 100644 index 0000000..15047b0 --- /dev/null +++ b/file.obj @@ -0,0 +1,3578 @@ +v 0.000118 -0.390977 -0.478607 +v 0.017389 -0.390977 -0.478271 +v 0.029547 -0.390983 -0.429828 +v 0.000118 -0.390983 -0.429848 +v 0.017389 -0.390977 -0.478271 +v 0.017389 -0.342855 -0.474044 +v 0.029547 -0.317820 -0.429577 +v 0.029547 -0.390983 -0.429828 +v 0.017389 -0.342855 -0.474044 +v 0.000118 -0.331762 -0.473074 +v 0.000118 -0.306727 -0.429520 +v 0.029547 -0.317820 -0.429577 +v -0.017152 -0.342855 -0.474044 +v -0.029311 -0.317820 -0.429577 +v -0.017152 -0.342855 -0.474044 +v -0.017152 -0.390977 -0.478271 +v -0.029311 -0.390983 -0.429828 +v -0.029311 -0.317820 -0.429577 +v -0.017152 -0.390977 -0.478271 +v -0.029311 -0.390983 -0.429828 +v 0.017389 -0.391071 -0.377731 +v 0.000118 -0.391100 -0.378066 +v 0.017389 -0.336012 -0.378305 +v 0.017389 -0.391071 -0.377731 +v 0.029547 -0.317820 -0.429577 +v 0.000118 -0.306727 -0.429520 +v 0.000118 -0.324876 -0.378305 +v 0.017389 -0.336012 -0.378305 +v 0.000118 -0.306727 -0.429520 +v -0.029311 -0.317820 -0.429577 +v -0.017152 -0.336012 -0.378305 +v 0.000118 -0.324876 -0.378305 +v -0.017152 -0.391071 -0.377731 +v -0.017152 -0.336012 -0.378305 +v -0.017152 -0.391071 -0.377731 +v 0.017389 -0.355018 -0.311310 +v 0.000118 -0.358745 -0.310312 +v 0.017389 -0.313071 -0.327714 +v 0.017389 -0.355018 -0.311310 +v 0.000118 -0.302315 -0.330597 +v 0.017389 -0.313071 -0.327714 +v -0.017152 -0.313071 -0.327714 +v 0.000118 -0.302315 -0.330597 +v -0.017152 -0.355018 -0.311310 +v -0.017152 -0.313071 -0.327714 +v -0.017152 -0.355018 -0.311310 +v 0.027414 -0.282077 -0.242925 +v 0.000118 -0.286749 -0.239005 +v 0.027414 -0.244765 -0.265699 +v 0.027414 -0.282077 -0.242925 +v 0.000118 -0.231283 -0.277012 +v 0.027414 -0.244765 -0.265699 +v -0.027178 -0.244765 -0.265699 +v 0.000118 -0.231283 -0.277012 +v -0.027178 -0.282077 -0.242925 +v -0.027178 -0.244765 -0.265699 +v -0.027178 -0.282077 -0.242925 +v 0.035601 -0.254040 -0.188841 +v 0.000118 -0.261848 -0.187464 +v 0.035601 -0.172486 -0.190596 +v 0.035601 -0.254040 -0.188841 +v 0.000118 -0.149955 -0.194569 +v 0.035601 -0.172486 -0.190596 +v -0.035364 -0.172486 -0.190596 +v 0.000118 -0.149955 -0.194569 +v -0.035364 -0.254040 -0.188841 +v -0.035364 -0.172486 -0.190596 +v -0.035364 -0.254040 -0.188841 +v 0.000118 -0.360973 -0.484897 +v 0.017389 -0.390977 -0.478271 +v 0.000118 -0.390977 -0.478607 +v 0.017389 -0.342855 -0.474044 +v 0.000118 -0.331762 -0.473074 +v -0.017152 -0.342855 -0.474044 +v -0.017152 -0.390977 -0.478271 +v 0.035601 -0.232880 -0.098411 +v 0.000118 -0.240808 -0.098411 +v 0.035601 -0.144967 -0.098411 +v 0.035601 -0.232880 -0.098411 +v 0.000118 -0.122088 -0.098411 +v 0.035601 -0.144967 -0.098411 +v -0.035364 -0.144967 -0.098411 +v 0.000118 -0.122088 -0.098411 +v -0.035364 -0.232880 -0.098411 +v -0.035364 -0.144967 -0.098411 +v -0.035364 -0.232880 -0.098411 +v 0.478607 -0.390977 0.000118 +v 0.478271 -0.390977 0.017389 +v 0.429828 -0.390983 0.029547 +v 0.429848 -0.390983 0.000118 +v 0.478271 -0.390977 0.017389 +v 0.474044 -0.342855 0.017389 +v 0.429577 -0.317820 0.029547 +v 0.429828 -0.390983 0.029547 +v 0.474044 -0.342855 0.017389 +v 0.473074 -0.331762 0.000118 +v 0.429520 -0.306727 0.000118 +v 0.429577 -0.317820 0.029547 +v 0.474044 -0.342855 -0.017152 +v 0.429577 -0.317820 -0.029311 +v 0.474044 -0.342855 -0.017152 +v 0.478271 -0.390977 -0.017152 +v 0.429828 -0.390983 -0.029311 +v 0.429577 -0.317820 -0.029311 +v 0.478271 -0.390977 -0.017152 +v 0.429828 -0.390983 -0.029311 +v 0.377731 -0.391071 0.017389 +v 0.378066 -0.391100 0.000118 +v 0.378305 -0.336012 0.017389 +v 0.377731 -0.391071 0.017389 +v 0.429577 -0.317820 0.029547 +v 0.429520 -0.306727 0.000118 +v 0.378305 -0.324876 0.000118 +v 0.378305 -0.336012 0.017389 +v 0.429520 -0.306727 0.000118 +v 0.429577 -0.317820 -0.029311 +v 0.378305 -0.336012 -0.017152 +v 0.378305 -0.324876 0.000118 +v 0.377731 -0.391071 -0.017152 +v 0.378305 -0.336012 -0.017152 +v 0.377731 -0.391071 -0.017152 +v 0.311310 -0.355018 0.017389 +v 0.310312 -0.358745 0.000118 +v 0.327714 -0.313071 0.017389 +v 0.311310 -0.355018 0.017389 +v 0.330597 -0.302315 0.000118 +v 0.327714 -0.313071 0.017389 +v 0.327714 -0.313071 -0.017152 +v 0.330597 -0.302315 0.000118 +v 0.311310 -0.355018 -0.017152 +v 0.327714 -0.313071 -0.017152 +v 0.311310 -0.355018 -0.017152 +v 0.242925 -0.282077 0.027414 +v 0.239005 -0.286749 0.000118 +v 0.265699 -0.244765 0.027414 +v 0.242925 -0.282077 0.027414 +v 0.277012 -0.231283 0.000118 +v 0.265699 -0.244765 0.027414 +v 0.265699 -0.244765 -0.027178 +v 0.277012 -0.231283 0.000118 +v 0.242925 -0.282077 -0.027178 +v 0.265699 -0.244765 -0.027178 +v 0.242925 -0.282077 -0.027178 +v 0.188841 -0.254040 0.035601 +v 0.187464 -0.261848 0.000118 +v 0.190596 -0.172486 0.035601 +v 0.188841 -0.254040 0.035601 +v 0.194569 -0.149955 0.000118 +v 0.190596 -0.172486 0.035601 +v 0.190596 -0.172486 -0.035364 +v 0.194569 -0.149955 0.000118 +v 0.188841 -0.254040 -0.035364 +v 0.190596 -0.172486 -0.035364 +v 0.188841 -0.254040 -0.035364 +v 0.484897 -0.360973 0.000118 +v 0.478271 -0.390977 0.017389 +v 0.478607 -0.390977 0.000118 +v 0.474044 -0.342855 0.017389 +v 0.473074 -0.331762 0.000118 +v 0.474044 -0.342855 -0.017152 +v 0.478271 -0.390977 -0.017152 +v 0.098411 -0.232880 0.035601 +v 0.098411 -0.240808 0.000118 +v 0.098411 -0.144967 0.035601 +v 0.098411 -0.232880 0.035601 +v 0.098411 -0.122088 0.000118 +v 0.098411 -0.144967 0.035601 +v 0.098411 -0.144967 -0.035364 +v 0.098411 -0.122088 0.000118 +v 0.098411 -0.232880 -0.035364 +v 0.098411 -0.144967 -0.035364 +v 0.098411 -0.232880 -0.035364 +v -0.000118 -0.390977 0.478607 +v -0.017389 -0.390977 0.478271 +v -0.029547 -0.390983 0.429828 +v -0.000118 -0.390983 0.429848 +v -0.017389 -0.390977 0.478271 +v -0.017389 -0.342855 0.474044 +v -0.029547 -0.317820 0.429577 +v -0.029547 -0.390983 0.429828 +v -0.017389 -0.342855 0.474044 +v -0.000118 -0.331762 0.473074 +v -0.000118 -0.306727 0.429520 +v -0.029547 -0.317820 0.429577 +v 0.017152 -0.342855 0.474044 +v 0.029310 -0.317820 0.429577 +v 0.017152 -0.342855 0.474044 +v 0.017152 -0.390977 0.478271 +v 0.029310 -0.390983 0.429828 +v 0.029310 -0.317820 0.429577 +v 0.017152 -0.390977 0.478271 +v 0.029310 -0.390983 0.429828 +v -0.017389 -0.391071 0.377731 +v -0.000118 -0.391100 0.378066 +v -0.017389 -0.336012 0.378305 +v -0.017389 -0.391071 0.377731 +v -0.029547 -0.317820 0.429577 +v -0.000118 -0.306727 0.429520 +v -0.000118 -0.324876 0.378305 +v -0.017389 -0.336012 0.378305 +v -0.000118 -0.306727 0.429520 +v 0.029310 -0.317820 0.429577 +v 0.017152 -0.336012 0.378305 +v -0.000118 -0.324876 0.378305 +v 0.017152 -0.391071 0.377731 +v 0.017152 -0.336012 0.378305 +v 0.017152 -0.391071 0.377731 +v -0.017389 -0.355018 0.311310 +v -0.000118 -0.358745 0.310312 +v -0.017389 -0.313071 0.327714 +v -0.017389 -0.355018 0.311310 +v -0.000118 -0.302315 0.330597 +v -0.017389 -0.313071 0.327714 +v 0.017152 -0.313071 0.327714 +v -0.000118 -0.302315 0.330597 +v 0.017152 -0.355018 0.311310 +v 0.017152 -0.313071 0.327714 +v 0.017152 -0.355018 0.311310 +v -0.027414 -0.282077 0.242925 +v -0.000118 -0.286749 0.239005 +v -0.027414 -0.244765 0.265699 +v -0.027414 -0.282077 0.242925 +v -0.000118 -0.231283 0.277012 +v -0.027414 -0.244765 0.265699 +v 0.027178 -0.244765 0.265699 +v -0.000118 -0.231283 0.277012 +v 0.027178 -0.282077 0.242925 +v 0.027178 -0.244765 0.265699 +v 0.027178 -0.282077 0.242925 +v -0.035601 -0.254040 0.188841 +v -0.000118 -0.261848 0.187464 +v -0.035601 -0.172486 0.190596 +v -0.035601 -0.254040 0.188841 +v -0.000118 -0.149955 0.194569 +v -0.035601 -0.172486 0.190596 +v 0.035364 -0.172486 0.190596 +v -0.000118 -0.149955 0.194569 +v 0.035364 -0.254040 0.188841 +v 0.035364 -0.172486 0.190596 +v 0.035364 -0.254040 0.188841 +v -0.000118 -0.360973 0.484897 +v -0.017389 -0.390977 0.478271 +v -0.000118 -0.390977 0.478607 +v -0.017389 -0.342855 0.474044 +v -0.000118 -0.331762 0.473074 +v 0.017152 -0.342855 0.474044 +v 0.017152 -0.390977 0.478271 +v -0.035601 -0.232880 0.098411 +v -0.000118 -0.240808 0.098411 +v -0.035601 -0.144967 0.098411 +v -0.035601 -0.232880 0.098411 +v -0.000118 -0.122088 0.098411 +v -0.035601 -0.144967 0.098411 +v 0.035364 -0.144967 0.098411 +v -0.000118 -0.122088 0.098411 +v 0.035364 -0.232880 0.098411 +v 0.035364 -0.144967 0.098411 +v 0.035364 -0.232880 0.098411 +v -0.478607 -0.390977 -0.000118 +v -0.478271 -0.390977 -0.017389 +v -0.429828 -0.390983 -0.029547 +v -0.429848 -0.390983 -0.000118 +v -0.478271 -0.390977 -0.017389 +v -0.474044 -0.342855 -0.017389 +v -0.429577 -0.317820 -0.029547 +v -0.429828 -0.390983 -0.029547 +v -0.474044 -0.342855 -0.017389 +v -0.473074 -0.331762 -0.000118 +v -0.429520 -0.306727 -0.000118 +v -0.429577 -0.317820 -0.029547 +v -0.474044 -0.342855 0.017152 +v -0.429577 -0.317820 0.029310 +v -0.474044 -0.342855 0.017152 +v -0.478271 -0.390977 0.017152 +v -0.429828 -0.390983 0.029310 +v -0.429577 -0.317820 0.029310 +v -0.478271 -0.390977 0.017152 +v -0.429828 -0.390983 0.029310 +v -0.377731 -0.391071 -0.017389 +v -0.378066 -0.391100 -0.000118 +v -0.378305 -0.336012 -0.017389 +v -0.377731 -0.391071 -0.017389 +v -0.429577 -0.317820 -0.029547 +v -0.429520 -0.306727 -0.000118 +v -0.378305 -0.324876 -0.000118 +v -0.378305 -0.336012 -0.017389 +v -0.429520 -0.306727 -0.000118 +v -0.429577 -0.317820 0.029310 +v -0.378305 -0.336012 0.017152 +v -0.378305 -0.324876 -0.000118 +v -0.377731 -0.391071 0.017152 +v -0.378305 -0.336012 0.017152 +v -0.377731 -0.391071 0.017152 +v -0.311310 -0.355018 -0.017389 +v -0.310312 -0.358745 -0.000118 +v -0.327714 -0.313071 -0.017389 +v -0.311310 -0.355018 -0.017389 +v -0.330597 -0.302315 -0.000118 +v -0.327714 -0.313071 -0.017389 +v -0.327714 -0.313071 0.017152 +v -0.330597 -0.302315 -0.000118 +v -0.311310 -0.355018 0.017152 +v -0.327714 -0.313071 0.017152 +v -0.311310 -0.355018 0.017152 +v -0.242925 -0.282077 -0.027414 +v -0.239005 -0.286749 -0.000118 +v -0.265699 -0.244765 -0.027414 +v -0.242925 -0.282077 -0.027414 +v -0.277012 -0.231283 -0.000118 +v -0.265699 -0.244765 -0.027414 +v -0.265699 -0.244765 0.027178 +v -0.277012 -0.231283 -0.000118 +v -0.242925 -0.282077 0.027178 +v -0.265699 -0.244765 0.027178 +v -0.242925 -0.282077 0.027178 +v -0.188841 -0.254040 -0.035601 +v -0.187464 -0.261848 -0.000118 +v -0.190596 -0.172486 -0.035601 +v -0.188841 -0.254040 -0.035601 +v -0.194569 -0.149955 -0.000118 +v -0.190596 -0.172486 -0.035601 +v -0.190596 -0.172486 0.035364 +v -0.194569 -0.149955 -0.000118 +v -0.188841 -0.254040 0.035364 +v -0.190596 -0.172486 0.035364 +v -0.188841 -0.254040 0.035364 +v -0.484897 -0.360973 -0.000118 +v -0.478271 -0.390977 -0.017389 +v -0.478607 -0.390977 -0.000118 +v -0.474044 -0.342855 -0.017389 +v -0.473074 -0.331762 -0.000118 +v -0.474044 -0.342855 0.017152 +v -0.478271 -0.390977 0.017152 +v -0.098411 -0.232880 -0.035601 +v -0.098411 -0.240808 -0.000118 +v -0.098411 -0.144967 -0.035601 +v -0.098411 -0.232880 -0.035601 +v -0.098411 -0.122088 -0.000118 +v -0.098411 -0.144967 -0.035601 +v -0.098411 -0.144967 0.035364 +v -0.098411 -0.122088 -0.000118 +v -0.098411 -0.232880 0.035364 +v -0.098411 -0.144967 0.035364 +v -0.098411 -0.232880 0.035364 +v 0.000000 -0.094464 0.000000 +v 0.043796 -0.094464 0.105844 +v 0.105811 -0.094464 0.043875 +v -0.043875 -0.094464 0.105811 +v -0.105844 -0.094464 0.043796 +v -0.105811 -0.094464 -0.043875 +v -0.043796 -0.094464 -0.105844 +v 0.043875 -0.094464 -0.105811 +v 0.105844 -0.094464 -0.043796 +v 0.043796 -0.255563 0.105844 +v 0.105811 -0.255563 0.043875 +v 0.105811 -0.094464 0.043875 +v 0.043796 -0.094464 0.105844 +v -0.043875 -0.255563 0.105811 +v 0.043796 -0.255563 0.105844 +v 0.043796 -0.094464 0.105844 +v -0.043875 -0.094464 0.105811 +v -0.105844 -0.255563 0.043796 +v -0.043875 -0.255563 0.105811 +v -0.043875 -0.094464 0.105811 +v -0.105844 -0.094464 0.043796 +v -0.105811 -0.255563 -0.043875 +v -0.105844 -0.255563 0.043796 +v -0.105844 -0.094464 0.043796 +v -0.105811 -0.094464 -0.043875 +v -0.043796 -0.255563 -0.105844 +v -0.105811 -0.255563 -0.043875 +v -0.105811 -0.094464 -0.043875 +v -0.043796 -0.094464 -0.105844 +v 0.043875 -0.255563 -0.105811 +v -0.043796 -0.255563 -0.105844 +v -0.043796 -0.094464 -0.105844 +v 0.043875 -0.094464 -0.105811 +v 0.105844 -0.255563 -0.043796 +v 0.043875 -0.255563 -0.105811 +v 0.043875 -0.094464 -0.105811 +v 0.105844 -0.094464 -0.043796 +v 0.105811 -0.255563 0.043875 +v 0.105844 -0.255563 -0.043796 +v 0.105844 -0.094464 -0.043796 +v 0.105811 -0.094464 0.043875 +v 0.000000 -0.255563 0.000000 +v 0.105811 -0.255563 0.043875 +v 0.043796 -0.255563 0.105844 +v -0.043875 -0.255563 0.105811 +v -0.105844 -0.255563 0.043796 +v -0.105811 -0.255563 -0.043875 +v -0.043796 -0.255563 -0.105844 +v 0.043875 -0.255563 -0.105811 +v 0.105844 -0.255563 -0.043796 +v -0.275954 0.604340 0.275954 +v -0.275954 0.604340 -0.275954 +v -0.275954 0.612392 -0.275954 +v -0.275954 0.612392 0.275954 +v -0.275954 0.604340 -0.275954 +v 0.275954 0.604340 -0.275954 +v 0.275954 0.612392 -0.275954 +v -0.275954 0.612392 -0.275954 +v 0.275954 0.604340 -0.275954 +v 0.275954 0.604340 0.275954 +v 0.275954 0.612392 0.275954 +v 0.275954 0.612392 -0.275954 +v 0.275954 0.604340 0.275954 +v -0.275954 0.604340 0.275954 +v -0.275954 0.612392 0.275954 +v 0.275954 0.612392 0.275954 +v -0.275954 0.612392 0.275954 +v -0.275954 0.612392 -0.275954 +v -0.284007 0.611587 -0.284007 +v -0.284007 0.611587 0.284007 +v -0.275954 0.612392 -0.275954 +v 0.275954 0.612392 -0.275954 +v 0.284007 0.611587 -0.284007 +v -0.284007 0.611587 -0.284007 +v 0.275954 0.612392 -0.275954 +v 0.275954 0.612392 0.275954 +v 0.284007 0.611587 0.284007 +v 0.284007 0.611587 -0.284007 +v 0.275954 0.612392 0.275954 +v -0.275954 0.612392 0.275954 +v -0.284007 0.611587 0.284007 +v 0.284007 0.611587 0.284007 +v -0.284007 0.611587 0.284007 +v -0.284007 0.611587 -0.284007 +v -0.284007 0.603535 -0.284007 +v -0.284007 0.603535 0.284007 +v -0.284007 0.611587 -0.284007 +v 0.284007 0.611587 -0.284007 +v 0.284007 0.603535 -0.284007 +v -0.284007 0.603535 -0.284007 +v 0.284007 0.611587 -0.284007 +v 0.284007 0.611587 0.284007 +v 0.284007 0.603535 0.284007 +v 0.284007 0.603535 -0.284007 +v 0.284007 0.611587 0.284007 +v -0.284007 0.611587 0.284007 +v -0.284007 0.603535 0.284007 +v 0.284007 0.603535 0.284007 +v -0.507297 0.549194 0.507297 +v 0.507297 0.549194 0.507297 +v 0.507297 0.550000 0.507297 +v -0.507297 0.550000 0.507297 +v 0.507297 0.549194 0.507297 +v 0.507297 0.549194 -0.507297 +v 0.507297 0.550000 -0.507297 +v 0.507297 0.550000 0.507297 +v 0.507297 0.549194 -0.507297 +v -0.507297 0.549194 -0.507297 +v -0.507297 0.550000 -0.507297 +v 0.507297 0.550000 -0.507297 +v -0.507297 0.549194 -0.507297 +v -0.507297 0.549194 0.507297 +v -0.507297 0.550000 0.507297 +v -0.507297 0.550000 -0.507297 +v 0.507297 0.558052 0.507297 +v -0.507297 0.558052 0.507297 +v 0.507297 0.558052 -0.507297 +v 0.507297 0.558052 0.507297 +v -0.507297 0.558052 -0.507297 +v 0.507297 0.558052 -0.507297 +v -0.507297 0.558052 0.507297 +v -0.507297 0.558052 -0.507297 +v 0.499245 0.566104 0.499245 +v -0.499245 0.566104 0.499245 +v 0.499245 0.566104 -0.499245 +v 0.499245 0.566104 0.499245 +v -0.499245 0.566104 -0.499245 +v 0.499245 0.566104 -0.499245 +v -0.499245 0.566104 0.499245 +v -0.499245 0.566104 -0.499245 +v 0.499245 0.574157 0.499245 +v -0.499245 0.574157 0.499245 +v 0.499245 0.574157 -0.499245 +v 0.499245 0.574157 0.499245 +v -0.499245 0.574157 -0.499245 +v 0.499245 0.574157 -0.499245 +v -0.499245 0.574157 0.499245 +v -0.499245 0.574157 -0.499245 +v 0.491193 0.582209 0.491193 +v -0.491193 0.582209 0.491193 +v 0.491193 0.582209 -0.491193 +v 0.491193 0.582209 0.491193 +v -0.491193 0.582209 -0.491193 +v 0.491193 0.582209 -0.491193 +v -0.491193 0.582209 0.491193 +v -0.491193 0.582209 -0.491193 +v -0.491193 0.582209 0.491193 +v 0.491193 0.582209 0.491193 +v 0.483140 0.583014 0.483140 +v -0.483140 0.583014 0.483140 +v 0.491193 0.582209 0.491193 +v 0.491193 0.582209 -0.491193 +v 0.483140 0.583014 -0.483140 +v 0.483140 0.583014 0.483140 +v 0.491193 0.582209 -0.491193 +v -0.491193 0.582209 -0.491193 +v -0.483140 0.583014 -0.483140 +v 0.483140 0.583014 -0.483140 +v -0.491193 0.582209 -0.491193 +v -0.491193 0.582209 0.491193 +v -0.483140 0.583014 0.483140 +v -0.483140 0.583014 -0.483140 +v -0.314041 0.591939 -0.314041 +v -0.314041 0.591939 0.314041 +v 0.314041 0.591939 -0.314041 +v -0.314041 0.591939 -0.314041 +v 0.314041 0.591939 0.314041 +v 0.314041 0.591939 -0.314041 +v -0.314041 0.591939 0.314041 +v 0.314041 0.591939 0.314041 +v -0.322094 0.591134 -0.322094 +v -0.322094 0.591134 0.322094 +v 0.322094 0.591134 -0.322094 +v -0.322094 0.591134 -0.322094 +v 0.322094 0.591134 0.322094 +v 0.322094 0.591134 -0.322094 +v -0.322094 0.591134 0.322094 +v 0.322094 0.591134 0.322094 +v -0.322094 0.583082 -0.322094 +v -0.322094 0.583082 0.322094 +v 0.322094 0.583082 -0.322094 +v -0.322094 0.583082 -0.322094 +v 0.322094 0.583082 0.322094 +v 0.322094 0.583082 -0.322094 +v -0.322094 0.583082 0.322094 +v 0.322094 0.583082 0.322094 +v -0.322094 0.583082 0.322094 +v -0.322094 0.583082 -0.322094 +v -0.483140 0.575029 -0.483140 +v -0.483140 0.575029 0.483140 +v -0.322094 0.583082 -0.322094 +v 0.322094 0.583082 -0.322094 +v 0.483140 0.575029 -0.483140 +v -0.483140 0.575029 -0.483140 +v 0.322094 0.583082 -0.322094 +v 0.322094 0.583082 0.322094 +v 0.483140 0.575029 0.483140 +v 0.483140 0.575029 -0.483140 +v 0.322094 0.583082 0.322094 +v -0.322094 0.583082 0.322094 +v -0.483140 0.575029 0.483140 +v 0.483140 0.575029 0.483140 +v -0.483140 0.575029 0.483140 +v -0.483140 0.575029 -0.483140 +v -0.483140 0.583014 -0.483140 +v -0.483140 0.583014 0.483140 +v -0.483140 0.575029 -0.483140 +v 0.483140 0.575029 -0.483140 +v 0.483140 0.583014 -0.483140 +v -0.483140 0.583014 -0.483140 +v 0.483140 0.575029 -0.483140 +v 0.483140 0.575029 0.483140 +v 0.483140 0.583014 0.483140 +v 0.483140 0.583014 -0.483140 +v 0.483140 0.575029 0.483140 +v -0.483140 0.575029 0.483140 +v -0.483140 0.583014 0.483140 +v 0.483140 0.583014 0.483140 +v 0.275954 0.604340 -0.275954 +v -0.275954 0.604340 -0.275954 +v -0.275954 0.604340 0.275954 +v 0.275954 0.604340 0.275954 +v 0.507297 0.549194 -0.507297 +v 0.507297 0.549194 0.507297 +v -0.507297 0.549194 0.507297 +v -0.507297 0.549194 -0.507297 +v 0.061122 0.493612 0.044408 +v 0.075551 0.493612 0.000000 +v 0.153763 0.549783 0.000000 +v 0.124397 0.549782 0.090379 +v 0.023346 0.493612 0.071853 +v 0.047515 0.549782 0.146237 +v -0.023346 0.493612 0.071853 +v -0.047515 0.549782 0.146237 +v -0.061122 0.493612 0.044408 +v -0.124396 0.549782 0.090380 +v -0.075551 0.493612 0.000000 +v -0.153763 0.549783 0.000000 +v -0.061122 0.493612 -0.044407 +v -0.124397 0.549783 -0.090379 +v -0.023346 0.493612 -0.071853 +v -0.047515 0.549783 -0.146237 +v 0.023346 0.493612 -0.071853 +v 0.047515 0.549783 -0.146237 +v 0.061122 0.493612 -0.044407 +v 0.124396 0.549783 -0.090379 +v 0.039643 0.457110 0.028802 +v 0.049002 0.457110 0.000000 +v 0.015142 0.457110 0.046603 +v -0.015142 0.457110 0.046603 +v -0.039643 0.457110 0.028802 +v -0.049002 0.457110 0.000000 +v -0.039643 0.457110 -0.028802 +v -0.015142 0.457110 -0.046603 +v 0.015142 0.457110 -0.046603 +v 0.039643 0.457110 -0.028802 +v 0.065534 -0.100432 0.047613 +v 0.081005 -0.100432 0.000000 +v 0.081005 -0.082613 0.000000 +v 0.065534 -0.082613 0.047613 +v 0.025032 -0.100432 0.077040 +v 0.065534 -0.100432 0.047613 +v 0.065534 -0.082613 0.047613 +v 0.025032 -0.082613 0.077040 +v -0.025032 -0.100432 0.077040 +v 0.025032 -0.100432 0.077040 +v 0.025032 -0.082613 0.077040 +v -0.025032 -0.082613 0.077040 +v -0.065534 -0.100432 0.047613 +v -0.025032 -0.100432 0.077040 +v -0.025032 -0.082613 0.077040 +v -0.065534 -0.082613 0.047613 +v -0.081005 -0.100432 0.000000 +v -0.065534 -0.100432 0.047613 +v -0.065534 -0.082613 0.047613 +v -0.081005 -0.082613 0.000000 +v -0.065534 -0.100432 -0.047613 +v -0.081005 -0.100432 0.000000 +v -0.081005 -0.082613 0.000000 +v -0.065534 -0.082613 -0.047613 +v -0.025032 -0.100432 -0.077040 +v -0.065534 -0.100432 -0.047613 +v -0.065534 -0.082613 -0.047613 +v -0.025032 -0.082613 -0.077040 +v 0.025032 -0.100432 -0.077040 +v -0.025032 -0.100432 -0.077040 +v -0.025032 -0.082613 -0.077040 +v 0.025032 -0.082613 -0.077040 +v 0.065534 -0.100432 -0.047613 +v 0.025032 -0.100432 -0.077040 +v 0.025032 -0.082613 -0.077040 +v 0.065534 -0.082613 -0.047613 +v 0.081005 -0.100432 0.000000 +v 0.065534 -0.100432 -0.047613 +v 0.065534 -0.082613 -0.047613 +v 0.081005 -0.082613 0.000000 +v 0.065534 -0.082613 0.047613 +v 0.081005 -0.082613 0.000000 +v 0.062269 -0.081722 0.000000 +v 0.050377 -0.081722 0.036601 +v 0.025032 -0.082613 0.077040 +v 0.065534 -0.082613 0.047613 +v 0.050377 -0.081722 0.036601 +v 0.019242 -0.081722 0.059221 +v -0.025032 -0.082613 0.077040 +v 0.025032 -0.082613 0.077040 +v 0.019242 -0.081722 0.059221 +v -0.019242 -0.081722 0.059221 +v -0.065534 -0.082613 0.047613 +v -0.025032 -0.082613 0.077040 +v -0.019242 -0.081722 0.059221 +v -0.050377 -0.081722 0.036601 +v -0.081005 -0.082613 0.000000 +v -0.065534 -0.082613 0.047613 +v -0.050377 -0.081722 0.036601 +v -0.062269 -0.081722 0.000000 +v -0.065534 -0.082613 -0.047613 +v -0.081005 -0.082613 0.000000 +v -0.062269 -0.081722 0.000000 +v -0.050377 -0.081722 -0.036601 +v -0.025032 -0.082613 -0.077040 +v -0.065534 -0.082613 -0.047613 +v -0.050377 -0.081722 -0.036601 +v -0.019242 -0.081722 -0.059221 +v 0.025032 -0.082613 -0.077040 +v -0.025032 -0.082613 -0.077040 +v -0.019242 -0.081722 -0.059221 +v 0.019242 -0.081722 -0.059221 +v 0.065534 -0.082613 -0.047613 +v 0.025032 -0.082613 -0.077040 +v 0.019242 -0.081722 -0.059221 +v 0.050377 -0.081722 -0.036601 +v 0.081005 -0.082613 0.000000 +v 0.065534 -0.082613 -0.047613 +v 0.050377 -0.081722 -0.036601 +v 0.062269 -0.081722 0.000000 +v 0.050377 -0.081722 0.036601 +v 0.062269 -0.081722 0.000000 +v 0.062269 -0.063904 0.000000 +v 0.050377 -0.063904 0.036601 +v 0.019242 -0.081722 0.059221 +v 0.050377 -0.081722 0.036601 +v 0.050377 -0.063904 0.036601 +v 0.019242 -0.063904 0.059221 +v -0.019242 -0.081722 0.059221 +v 0.019242 -0.081722 0.059221 +v 0.019242 -0.063904 0.059221 +v -0.019242 -0.063904 0.059221 +v -0.050377 -0.081722 0.036601 +v -0.019242 -0.081722 0.059221 +v -0.019242 -0.063904 0.059221 +v -0.050377 -0.063904 0.036601 +v -0.062269 -0.081722 0.000000 +v -0.050377 -0.081722 0.036601 +v -0.050377 -0.063904 0.036601 +v -0.062269 -0.063904 0.000000 +v -0.050377 -0.081722 -0.036601 +v -0.062269 -0.081722 0.000000 +v -0.062269 -0.063904 0.000000 +v -0.050377 -0.063904 -0.036601 +v -0.019242 -0.081722 -0.059221 +v -0.050377 -0.081722 -0.036601 +v -0.050377 -0.063904 -0.036601 +v -0.019242 -0.063904 -0.059221 +v 0.019242 -0.081722 -0.059221 +v -0.019242 -0.081722 -0.059221 +v -0.019242 -0.063904 -0.059221 +v 0.019242 -0.063904 -0.059221 +v 0.050377 -0.081722 -0.036601 +v 0.019242 -0.081722 -0.059221 +v 0.019242 -0.063904 -0.059221 +v 0.050377 -0.063904 -0.036601 +v 0.062269 -0.081722 0.000000 +v 0.050377 -0.081722 -0.036601 +v 0.050377 -0.063904 -0.036601 +v 0.062269 -0.063904 0.000000 +v 0.050377 -0.063904 0.036601 +v 0.062269 -0.063904 0.000000 +v 0.071637 -0.059449 0.000000 +v 0.057955 -0.059449 0.042107 +v 0.019242 -0.063904 0.059221 +v 0.050377 -0.063904 0.036601 +v 0.057955 -0.059449 0.042107 +v 0.022137 -0.059449 0.068131 +v -0.019242 -0.063904 0.059221 +v 0.019242 -0.063904 0.059221 +v 0.022137 -0.059449 0.068131 +v -0.022137 -0.059449 0.068131 +v -0.050377 -0.063904 0.036601 +v -0.019242 -0.063904 0.059221 +v -0.022137 -0.059449 0.068131 +v -0.057955 -0.059449 0.042107 +v -0.062269 -0.063904 0.000000 +v -0.050377 -0.063904 0.036601 +v -0.057955 -0.059449 0.042107 +v -0.071637 -0.059449 0.000000 +v -0.050377 -0.063904 -0.036601 +v -0.062269 -0.063904 0.000000 +v -0.071637 -0.059449 0.000000 +v -0.057955 -0.059449 -0.042107 +v -0.019242 -0.063904 -0.059221 +v -0.050377 -0.063904 -0.036601 +v -0.057955 -0.059449 -0.042107 +v -0.022137 -0.059449 -0.068131 +v 0.019242 -0.063904 -0.059221 +v -0.019242 -0.063904 -0.059221 +v -0.022137 -0.059449 -0.068131 +v 0.022137 -0.059449 -0.068131 +v 0.050377 -0.063904 -0.036601 +v 0.019242 -0.063904 -0.059221 +v 0.022137 -0.059449 -0.068131 +v 0.057955 -0.059449 -0.042107 +v 0.062269 -0.063904 0.000000 +v 0.050377 -0.063904 -0.036601 +v 0.057955 -0.059449 -0.042107 +v 0.071637 -0.059449 0.000000 +v 0.057955 -0.059449 0.042107 +v 0.071637 -0.059449 0.000000 +v 0.071637 -0.050540 0.000000 +v 0.057955 -0.050540 0.042107 +v 0.022137 -0.059449 0.068131 +v 0.057955 -0.059449 0.042107 +v 0.057955 -0.050540 0.042107 +v 0.022137 -0.050540 0.068131 +v -0.022137 -0.059449 0.068131 +v 0.022137 -0.059449 0.068131 +v 0.022137 -0.050540 0.068131 +v -0.022137 -0.050540 0.068131 +v -0.057955 -0.059449 0.042107 +v -0.022137 -0.059449 0.068131 +v -0.022137 -0.050540 0.068131 +v -0.057955 -0.050540 0.042107 +v -0.071637 -0.059449 0.000000 +v -0.057955 -0.059449 0.042107 +v -0.057955 -0.050540 0.042107 +v -0.071637 -0.050540 0.000000 +v -0.057955 -0.059449 -0.042107 +v -0.071637 -0.059449 0.000000 +v -0.071637 -0.050540 0.000000 +v -0.057955 -0.050540 -0.042107 +v -0.022137 -0.059449 -0.068131 +v -0.057955 -0.059449 -0.042107 +v -0.057955 -0.050540 -0.042107 +v -0.022137 -0.050540 -0.068131 +v 0.022137 -0.059449 -0.068131 +v -0.022137 -0.059449 -0.068131 +v -0.022137 -0.050540 -0.068131 +v 0.022137 -0.050540 -0.068131 +v 0.057955 -0.059449 -0.042107 +v 0.022137 -0.059449 -0.068131 +v 0.022137 -0.050540 -0.068131 +v 0.057955 -0.050540 -0.042107 +v 0.071637 -0.059449 0.000000 +v 0.057955 -0.059449 -0.042107 +v 0.057955 -0.050540 -0.042107 +v 0.071637 -0.050540 0.000000 +v 0.057955 -0.050540 0.042107 +v 0.071637 -0.050540 0.000000 +v 0.062269 -0.046085 0.000000 +v 0.050377 -0.046085 0.036601 +v 0.022137 -0.050540 0.068131 +v 0.057955 -0.050540 0.042107 +v 0.050377 -0.046085 0.036601 +v 0.019242 -0.046085 0.059221 +v -0.022137 -0.050540 0.068131 +v 0.022137 -0.050540 0.068131 +v 0.019242 -0.046085 0.059221 +v -0.019242 -0.046085 0.059221 +v -0.057955 -0.050540 0.042107 +v -0.022137 -0.050540 0.068131 +v -0.019242 -0.046085 0.059221 +v -0.050377 -0.046085 0.036601 +v -0.071637 -0.050540 0.000000 +v -0.057955 -0.050540 0.042107 +v -0.050377 -0.046085 0.036601 +v -0.062269 -0.046085 0.000000 +v -0.057955 -0.050540 -0.042107 +v -0.071637 -0.050540 0.000000 +v -0.062269 -0.046085 0.000000 +v -0.050377 -0.046085 -0.036601 +v -0.022137 -0.050540 -0.068131 +v -0.057955 -0.050540 -0.042107 +v -0.050377 -0.046085 -0.036601 +v -0.019242 -0.046085 -0.059221 +v 0.022137 -0.050540 -0.068131 +v -0.022137 -0.050540 -0.068131 +v -0.019242 -0.046085 -0.059221 +v 0.019242 -0.046085 -0.059221 +v 0.057955 -0.050540 -0.042107 +v 0.022137 -0.050540 -0.068131 +v 0.019242 -0.046085 -0.059221 +v 0.050377 -0.046085 -0.036601 +v 0.071637 -0.050540 0.000000 +v 0.057955 -0.050540 -0.042107 +v 0.050377 -0.046085 -0.036601 +v 0.062269 -0.046085 0.000000 +v 0.050377 -0.046085 0.036601 +v 0.062269 -0.046085 0.000000 +v 0.062269 -0.037015 0.000000 +v 0.050377 -0.037015 0.036601 +v 0.019242 -0.046085 0.059221 +v 0.050377 -0.046085 0.036601 +v 0.050377 -0.037015 0.036601 +v 0.019242 -0.037015 0.059221 +v -0.019242 -0.046085 0.059221 +v 0.019242 -0.046085 0.059221 +v 0.019242 -0.037015 0.059221 +v -0.019242 -0.037015 0.059221 +v -0.050377 -0.046085 0.036601 +v -0.019242 -0.046085 0.059221 +v -0.019242 -0.037015 0.059221 +v -0.050377 -0.037015 0.036601 +v -0.062269 -0.046085 0.000000 +v -0.050377 -0.046085 0.036601 +v -0.050377 -0.037015 0.036601 +v -0.062269 -0.037015 0.000000 +v -0.050377 -0.046085 -0.036601 +v -0.062269 -0.046085 0.000000 +v -0.062269 -0.037015 0.000000 +v -0.050377 -0.037015 -0.036601 +v -0.019242 -0.046085 -0.059221 +v -0.050377 -0.046085 -0.036601 +v -0.050377 -0.037015 -0.036601 +v -0.019242 -0.037015 -0.059221 +v 0.019242 -0.046085 -0.059221 +v -0.019242 -0.046085 -0.059221 +v -0.019242 -0.037015 -0.059221 +v 0.019242 -0.037015 -0.059221 +v 0.050377 -0.046085 -0.036601 +v 0.019242 -0.046085 -0.059221 +v 0.019242 -0.037015 -0.059221 +v 0.050377 -0.037015 -0.036601 +v 0.062269 -0.046085 0.000000 +v 0.050377 -0.046085 -0.036601 +v 0.050377 -0.037015 -0.036601 +v 0.062269 -0.037015 0.000000 +v 0.035221 0.414309 0.025590 +v 0.043536 0.414309 0.000000 +v 0.049002 0.457110 0.000000 +v 0.039643 0.457110 0.028802 +v 0.013453 0.414309 0.041405 +v 0.015142 0.457110 0.046603 +v -0.013453 0.414309 0.041405 +v -0.015142 0.457110 0.046603 +v -0.035221 0.414309 0.025590 +v -0.039643 0.457110 0.028802 +v -0.043536 0.414309 0.000000 +v -0.049002 0.457110 0.000000 +v -0.035221 0.414309 -0.025590 +v -0.039643 0.457110 -0.028802 +v -0.013453 0.414309 -0.041405 +v -0.015142 0.457110 -0.046603 +v 0.013453 0.414309 -0.041405 +v 0.015142 0.457110 -0.046603 +v 0.035221 0.414309 -0.025590 +v 0.013453 0.414309 -0.041405 +v 0.015142 0.457110 -0.046603 +v 0.039643 0.457110 -0.028802 +v 0.051175 0.223460 0.037181 +v 0.063256 0.223460 0.000000 +v 0.019547 0.223460 0.060160 +v -0.019547 0.223460 0.060160 +v -0.051175 0.223460 0.037181 +v -0.063256 0.223460 0.000000 +v -0.051175 0.223460 -0.037181 +v -0.019547 0.223460 -0.060160 +v 0.019547 0.223460 -0.060160 +v 0.051176 0.223460 -0.037181 +v 0.019547 0.223460 -0.060160 +v 0.076220 0.102045 0.055377 +v 0.094213 0.102045 0.000000 +v 0.029113 0.102045 0.089602 +v -0.029113 0.102045 0.089602 +v -0.076220 0.102045 0.055377 +v -0.094213 0.102045 0.000000 +v -0.076220 0.102045 -0.055377 +v -0.029113 0.102045 -0.089602 +v 0.029113 0.102045 -0.089602 +v 0.076220 0.102045 -0.055377 +v 0.029113 0.102045 -0.089602 +v 0.068919 -0.002139 0.050073 +v 0.085189 -0.002139 0.000000 +v 0.026325 -0.002139 0.081019 +v -0.026325 -0.002139 0.081019 +v -0.068919 -0.002139 0.050073 +v -0.085189 -0.002139 0.000000 +v -0.068919 -0.002139 -0.050073 +v -0.026325 -0.002139 -0.081019 +v 0.026325 -0.002139 -0.081019 +v 0.068919 -0.002139 -0.050073 +v 0.026325 -0.002139 -0.081019 +v 0.050377 -0.037015 0.036601 +v 0.062269 -0.037015 0.000000 +v 0.019242 -0.037015 0.059221 +v -0.019242 -0.037015 0.059221 +v -0.050377 -0.037015 0.036601 +v -0.062269 -0.037015 0.000000 +v -0.050377 -0.037015 -0.036601 +v -0.019242 -0.037015 -0.059221 +v 0.019242 -0.037015 -0.059221 +v 0.050377 -0.037015 -0.036601 +v 0.019242 -0.037015 -0.059221 +vt 0.017083 0.467481 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077277 0.475172 +vt 0.017498 0.425773 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.077301 0.425780 +vt 0.022716 0.366365 +vt 0.023914 0.320840 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077611 0.335458 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.141617 0.425888 +vt 0.141203 0.458853 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.077611 0.335458 +vt 0.077682 0.295421 +vt 0.140908 0.303558 +vt 0.140908 0.357917 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.140908 0.357917 +vt 0.140908 0.303558 +vt 0.141617 0.425888 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.223614 0.381380 +vt 0.233628 0.407934 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.187732 0.293268 +vt 0.203363 0.329596 +vt 0.203363 0.329596 +vt 0.187732 0.293268 +vt 0.223614 0.381380 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.308037 0.291333 +vt 0.324950 0.321248 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.264859 0.213261 +vt 0.279922 0.245271 +vt 0.279922 0.245271 +vt 0.264859 0.213261 +vt 0.308037 0.291333 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.377000 0.255623 +vt 0.378700 0.295995 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.367735 0.111762 +vt 0.372639 0.156040 +vt 0.372639 0.156040 +vt 0.367735 0.111762 +vt 0.377000 0.255623 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.393655 0.410963 +vt 0.467714 0.453591 +vt 0.467714 0.410963 +vt 0.348935 0.453591 +vt 0.321554 0.410963 +vt 0.348935 0.368334 +vt 0.467714 0.368334 +vt 0.486443 0.230599 +vt 0.486443 0.273314 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.486443 0.071872 +vt 0.486443 0.122067 +vt 0.486443 0.122067 +vt 0.486443 0.071872 +vt 0.486443 0.230599 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.017083 0.467481 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077277 0.475172 +vt 0.017498 0.425773 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.077301 0.425780 +vt 0.022716 0.366365 +vt 0.023914 0.320840 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077611 0.335458 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.141617 0.425888 +vt 0.141203 0.458853 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.077611 0.335458 +vt 0.077682 0.295421 +vt 0.140908 0.303558 +vt 0.140908 0.357917 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.140908 0.357917 +vt 0.140908 0.303558 +vt 0.141617 0.425888 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.223614 0.381380 +vt 0.233628 0.407934 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.187732 0.293268 +vt 0.203363 0.329596 +vt 0.203363 0.329596 +vt 0.187732 0.293268 +vt 0.223614 0.381380 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.308037 0.291333 +vt 0.324950 0.321248 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.264859 0.213261 +vt 0.279922 0.245271 +vt 0.279922 0.245271 +vt 0.264859 0.213261 +vt 0.308037 0.291333 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.377000 0.255623 +vt 0.378700 0.295995 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.367735 0.111762 +vt 0.372639 0.156040 +vt 0.372639 0.156040 +vt 0.367735 0.111762 +vt 0.377000 0.255623 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.393655 0.410963 +vt 0.467714 0.453591 +vt 0.467714 0.410963 +vt 0.348935 0.453591 +vt 0.321554 0.410963 +vt 0.348935 0.368334 +vt 0.467714 0.368334 +vt 0.486443 0.230599 +vt 0.486443 0.273314 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.486443 0.071872 +vt 0.486443 0.122067 +vt 0.486443 0.122067 +vt 0.486443 0.071872 +vt 0.486443 0.230599 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.017083 0.467481 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077277 0.475172 +vt 0.017498 0.425773 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.077301 0.425780 +vt 0.022716 0.366365 +vt 0.023914 0.320840 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077611 0.335458 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.141617 0.425888 +vt 0.141203 0.458853 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.077611 0.335458 +vt 0.077682 0.295421 +vt 0.140908 0.303558 +vt 0.140908 0.357917 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.140908 0.357917 +vt 0.140908 0.303558 +vt 0.141617 0.425888 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.223614 0.381380 +vt 0.233628 0.407934 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.187732 0.293268 +vt 0.203363 0.329596 +vt 0.203363 0.329596 +vt 0.187732 0.293268 +vt 0.223614 0.381380 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.308037 0.291333 +vt 0.324950 0.321248 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.264859 0.213261 +vt 0.279922 0.245271 +vt 0.279922 0.245271 +vt 0.264859 0.213261 +vt 0.308037 0.291333 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.377000 0.255623 +vt 0.378700 0.295995 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.367735 0.111762 +vt 0.372639 0.156040 +vt 0.372639 0.156040 +vt 0.367735 0.111762 +vt 0.377000 0.255623 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.393655 0.410963 +vt 0.467714 0.453591 +vt 0.467714 0.410963 +vt 0.348935 0.453591 +vt 0.321554 0.410963 +vt 0.348935 0.368334 +vt 0.467714 0.368334 +vt 0.486443 0.230599 +vt 0.486443 0.273314 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.486443 0.071872 +vt 0.486443 0.122067 +vt 0.486443 0.122067 +vt 0.486443 0.071872 +vt 0.486443 0.230599 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.017083 0.467481 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077277 0.475172 +vt 0.017498 0.425773 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.077301 0.425780 +vt 0.022716 0.366365 +vt 0.023914 0.320840 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.077611 0.335458 +vt 0.022716 0.366365 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.077611 0.335458 +vt 0.017498 0.425773 +vt 0.077301 0.425780 +vt 0.141617 0.425888 +vt 0.141203 0.458853 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.077611 0.335458 +vt 0.077682 0.295421 +vt 0.140908 0.303558 +vt 0.140908 0.357917 +vt 0.077682 0.295421 +vt 0.077611 0.335458 +vt 0.140908 0.357917 +vt 0.140908 0.303558 +vt 0.141617 0.425888 +vt 0.140908 0.357917 +vt 0.141617 0.425888 +vt 0.223614 0.381380 +vt 0.233628 0.407934 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.187732 0.293268 +vt 0.203363 0.329596 +vt 0.203363 0.329596 +vt 0.187732 0.293268 +vt 0.223614 0.381380 +vt 0.203363 0.329596 +vt 0.223614 0.381380 +vt 0.308037 0.291333 +vt 0.324950 0.321248 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.264859 0.213261 +vt 0.279922 0.245271 +vt 0.279922 0.245271 +vt 0.264859 0.213261 +vt 0.308037 0.291333 +vt 0.279922 0.245271 +vt 0.308037 0.291333 +vt 0.377000 0.255623 +vt 0.378700 0.295995 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.367735 0.111762 +vt 0.372639 0.156040 +vt 0.372639 0.156040 +vt 0.367735 0.111762 +vt 0.377000 0.255623 +vt 0.372639 0.156040 +vt 0.377000 0.255623 +vt 0.393655 0.410963 +vt 0.467714 0.453591 +vt 0.467714 0.410963 +vt 0.348935 0.453591 +vt 0.321554 0.410963 +vt 0.348935 0.368334 +vt 0.467714 0.368334 +vt 0.486443 0.230599 +vt 0.486443 0.273314 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.486443 0.071872 +vt 0.486443 0.122067 +vt 0.486443 0.122067 +vt 0.486443 0.071872 +vt 0.486443 0.230599 +vt 0.486443 0.122067 +vt 0.486443 0.230599 +vt 0.000000 1.000000 +vt 0.312949 0.385343 +vt 0.374010 0.385343 +vt 0.251887 0.385343 +vt 0.190825 0.385343 +vt 0.129763 0.385343 +vt 0.068702 0.385343 +vt 0.496134 0.385343 +vt 0.435072 0.385343 +vt 0.312949 0.498276 +vt 0.374010 0.498276 +vt 0.374010 0.385343 +vt 0.312949 0.385343 +vt 0.251887 0.498276 +vt 0.312949 0.498276 +vt 0.312949 0.385343 +vt 0.251887 0.385343 +vt 0.190825 0.498276 +vt 0.251887 0.498276 +vt 0.251887 0.385343 +vt 0.190825 0.385343 +vt 0.129763 0.498276 +vt 0.190825 0.498276 +vt 0.190825 0.385343 +vt 0.129763 0.385343 +vt 0.068702 0.498276 +vt 0.129763 0.498276 +vt 0.129763 0.385343 +vt 0.068702 0.385343 +vt 0.007640 0.498276 +vt 0.068702 0.498276 +vt 0.068702 0.385343 +vt 0.007640 0.385343 +vt 0.435072 0.498276 +vt 0.496134 0.498276 +vt 0.496134 0.385343 +vt 0.435072 0.385343 +vt 0.321935 0.273341 +vt 0.321962 0.201250 +vt 0.321962 0.201250 +vt 0.321935 0.273341 +vt 0.234927 0.237263 +vt 0.321935 0.273341 +vt 0.270940 0.324298 +vt 0.198849 0.324271 +vt 0.147891 0.273276 +vt 0.147918 0.201184 +vt 0.198914 0.150227 +vt 0.271005 0.150254 +vt 0.321962 0.201250 +vt 0.143227 0.361033 +vt 0.143227 0.144695 +vt 0.135916 0.138034 +vt 0.135916 0.368993 +vt 0.143227 0.144695 +vt 0.359565 0.144695 +vt 0.366875 0.138034 +vt 0.135916 0.138034 +vt 0.359565 0.144695 +vt 0.359565 0.361033 +vt 0.366875 0.368993 +vt 0.366875 0.138034 +vt 0.359565 0.361033 +vt 0.143227 0.361033 +vt 0.135916 0.368993 +vt 0.366875 0.368993 +vt 0.135916 0.368993 +vt 0.135916 0.138034 +vt 0.113352 0.114821 +vt 0.113352 0.390908 +vt 0.135916 0.138034 +vt 0.366875 0.138034 +vt 0.389439 0.114821 +vt 0.113352 0.114821 +vt 0.366875 0.138034 +vt 0.366875 0.368993 +vt 0.389439 0.390908 +vt 0.389439 0.114821 +vt 0.366875 0.368993 +vt 0.135916 0.368993 +vt 0.113352 0.390908 +vt 0.389439 0.390908 +vt 0.113352 0.390908 +vt 0.113352 0.114821 +vt 0.121903 0.123372 +vt 0.121903 0.382356 +vt 0.113352 0.114821 +vt 0.389439 0.114821 +vt 0.380888 0.123372 +vt 0.121903 0.123372 +vt 0.389439 0.114821 +vt 0.389439 0.390908 +vt 0.380888 0.382356 +vt 0.380888 0.123372 +vt 0.389439 0.390908 +vt 0.113352 0.390908 +vt 0.121903 0.382356 +vt 0.380888 0.382356 +vt 0.004820 0.499440 +vt 0.497971 0.499440 +vt 0.497971 0.499440 +vt 0.004820 0.499440 +vt 0.497971 0.499440 +vt 0.497971 0.006289 +vt 0.497971 0.006289 +vt 0.497971 0.499440 +vt 0.497971 0.006289 +vt 0.004820 0.006289 +vt 0.004820 0.006289 +vt 0.497971 0.006289 +vt 0.004820 0.006289 +vt 0.004820 0.499440 +vt 0.004820 0.499440 +vt 0.004820 0.006289 +vt 0.497971 0.499440 +vt 0.004820 0.499440 +vt 0.497971 0.006289 +vt 0.497971 0.499440 +vt 0.004820 0.006289 +vt 0.497971 0.006289 +vt 0.004820 0.499440 +vt 0.004820 0.006289 +vt 0.491654 0.493123 +vt 0.011137 0.493123 +vt 0.491654 0.012605 +vt 0.491654 0.493123 +vt 0.011137 0.012605 +vt 0.491654 0.012605 +vt 0.011137 0.493123 +vt 0.011137 0.012605 +vt 0.482370 0.483838 +vt 0.020421 0.483838 +vt 0.482370 0.021890 +vt 0.482370 0.483838 +vt 0.020421 0.021890 +vt 0.482370 0.021890 +vt 0.020421 0.483838 +vt 0.020421 0.021890 +vt 0.470567 0.472035 +vt 0.032224 0.472035 +vt 0.470567 0.033693 +vt 0.470567 0.472035 +vt 0.032224 0.033693 +vt 0.470567 0.033693 +vt 0.032224 0.472035 +vt 0.032224 0.033693 +vt 0.032224 0.472035 +vt 0.470567 0.472035 +vt 0.459013 0.460481 +vt 0.043778 0.460481 +vt 0.470567 0.472035 +vt 0.470567 0.033693 +vt 0.459013 0.045247 +vt 0.459013 0.460481 +vt 0.470567 0.033693 +vt 0.032224 0.033693 +vt 0.043778 0.045247 +vt 0.459013 0.045247 +vt 0.032224 0.033693 +vt 0.032224 0.472035 +vt 0.043778 0.460481 +vt 0.043778 0.045247 +vt 0.098754 0.100222 +vt 0.098754 0.405506 +vt 0.404037 0.100222 +vt 0.098754 0.100222 +vt 0.404037 0.405506 +vt 0.404037 0.100222 +vt 0.098754 0.405506 +vt 0.404037 0.405506 +vt 0.094840 0.096308 +vt 0.094840 0.409420 +vt 0.407951 0.096308 +vt 0.094840 0.096308 +vt 0.407951 0.409420 +vt 0.407951 0.096308 +vt 0.094840 0.409420 +vt 0.407951 0.409420 +vt 0.087012 0.088481 +vt 0.087012 0.417248 +vt 0.415779 0.088481 +vt 0.087012 0.088481 +vt 0.415779 0.417248 +vt 0.415779 0.088481 +vt 0.087012 0.417248 +vt 0.415779 0.417248 +vt 0.586243 0.413570 +vt 0.586243 0.086583 +vt 0.504496 0.004836 +vt 0.504496 0.495317 +vt 0.586243 0.086583 +vt 0.913231 0.086583 +vt 0.994978 0.004836 +vt 0.504496 0.004836 +vt 0.913231 0.086583 +vt 0.913231 0.413570 +vt 0.994978 0.495317 +vt 0.994978 0.004836 +vt 0.913231 0.413570 +vt 0.586243 0.413570 +vt 0.504496 0.495317 +vt 0.994978 0.495317 +vt 0.052083 0.452177 +vt 0.052083 0.053552 +vt 0.043778 0.045247 +vt 0.043778 0.460481 +vt 0.052083 0.053552 +vt 0.450708 0.053552 +vt 0.459013 0.045247 +vt 0.043778 0.045247 +vt 0.450708 0.053552 +vt 0.450708 0.452177 +vt 0.459013 0.460481 +vt 0.459013 0.045247 +vt 0.450708 0.452177 +vt 0.052083 0.452177 +vt 0.043778 0.460481 +vt 0.459013 0.460481 +vt 0.997798 0.502710 +vt 0.503545 0.502710 +vt 0.503545 0.996963 +vt 0.997798 0.996963 +vt 0.497971 0.006289 +vt 0.497971 0.499440 +vt 0.004820 0.499440 +vt 0.004820 0.006289 +vt 0.366183 0.254192 +vt 0.376207 0.221754 +vt 0.430543 0.221754 +vt 0.410142 0.287774 +vt 0.339940 0.274240 +vt 0.356731 0.328576 +vt 0.307501 0.274241 +vt 0.290711 0.328576 +vt 0.281258 0.254192 +vt 0.237300 0.287774 +vt 0.271234 0.221754 +vt 0.216899 0.221754 +vt 0.281258 0.189315 +vt 0.237300 0.155734 +vt 0.307501 0.169267 +vt 0.290711 0.114932 +vt 0.339940 0.169267 +vt 0.356731 0.114932 +vt 0.366183 0.189315 +vt 0.410142 0.155734 +vt 0.351262 0.242793 +vt 0.357763 0.221754 +vt 0.334240 0.255796 +vt 0.313201 0.255796 +vt 0.296180 0.242793 +vt 0.289678 0.221754 +vt 0.296180 0.200714 +vt 0.313201 0.187711 +vt 0.334240 0.187711 +vt 0.351262 0.200714 +vt 0.350121 0.494170 +vt 0.396949 0.494170 +vt 0.396949 0.469050 +vt 0.350121 0.469050 +vt 0.300793 0.494170 +vt 0.350121 0.494170 +vt 0.350121 0.469050 +vt 0.300793 0.469050 +vt 0.249801 0.494170 +vt 0.300793 0.494170 +vt 0.300793 0.469050 +vt 0.249801 0.469050 +vt 0.200473 0.494170 +vt 0.249801 0.494170 +vt 0.249801 0.469050 +vt 0.200473 0.469050 +vt 0.153645 0.494170 +vt 0.200473 0.494170 +vt 0.200473 0.469050 +vt 0.153645 0.469050 +vt 0.106818 0.494170 +vt 0.153645 0.494170 +vt 0.153645 0.469050 +vt 0.106818 0.469050 +vt 0.057489 0.494170 +vt 0.106818 0.494170 +vt 0.106818 0.469050 +vt 0.057489 0.469050 +vt 0.006498 0.494170 +vt 0.057489 0.494170 +vt 0.057489 0.469050 +vt 0.006498 0.469050 +vt 0.443776 0.494170 +vt 0.493105 0.494170 +vt 0.493105 0.469050 +vt 0.443776 0.469050 +vt 0.396949 0.494170 +vt 0.443776 0.494170 +vt 0.443776 0.469050 +vt 0.396949 0.469050 +vt 0.350121 0.469050 +vt 0.396949 0.469050 +vt 0.396949 0.467794 +vt 0.350121 0.467794 +vt 0.300793 0.469050 +vt 0.350121 0.469050 +vt 0.350121 0.467794 +vt 0.300793 0.467794 +vt 0.249801 0.469050 +vt 0.300793 0.469050 +vt 0.300793 0.467794 +vt 0.249801 0.467794 +vt 0.200473 0.469050 +vt 0.249801 0.469050 +vt 0.249801 0.467794 +vt 0.200473 0.467794 +vt 0.153645 0.469050 +vt 0.200473 0.469050 +vt 0.200473 0.467794 +vt 0.153645 0.467794 +vt 0.106818 0.469050 +vt 0.153645 0.469050 +vt 0.153645 0.467794 +vt 0.106818 0.467794 +vt 0.057489 0.469050 +vt 0.106818 0.469050 +vt 0.106818 0.467794 +vt 0.057489 0.467794 +vt 0.006498 0.469050 +vt 0.057489 0.469050 +vt 0.057489 0.467794 +vt 0.006498 0.467794 +vt 0.443776 0.469050 +vt 0.493105 0.469050 +vt 0.493105 0.467794 +vt 0.443776 0.467794 +vt 0.396949 0.469050 +vt 0.443776 0.469050 +vt 0.443776 0.467794 +vt 0.396949 0.467794 +vt 0.350121 0.467794 +vt 0.396949 0.467794 +vt 0.396949 0.442675 +vt 0.350121 0.442675 +vt 0.300793 0.467794 +vt 0.350121 0.467794 +vt 0.350121 0.442675 +vt 0.300793 0.442675 +vt 0.249801 0.467794 +vt 0.300793 0.467794 +vt 0.300793 0.442675 +vt 0.249801 0.442675 +vt 0.200473 0.467794 +vt 0.249801 0.467794 +vt 0.249801 0.442675 +vt 0.200473 0.442675 +vt 0.153645 0.467794 +vt 0.200473 0.467794 +vt 0.200473 0.442675 +vt 0.153645 0.442675 +vt 0.106818 0.467794 +vt 0.153645 0.467794 +vt 0.153645 0.442675 +vt 0.106818 0.442675 +vt 0.057489 0.467794 +vt 0.106818 0.467794 +vt 0.106818 0.442675 +vt 0.057489 0.442675 +vt 0.006498 0.467794 +vt 0.057489 0.467794 +vt 0.057489 0.442675 +vt 0.006498 0.442675 +vt 0.443776 0.467794 +vt 0.493105 0.467794 +vt 0.493105 0.442675 +vt 0.443776 0.442675 +vt 0.396949 0.467794 +vt 0.443776 0.467794 +vt 0.443776 0.442675 +vt 0.396949 0.442675 +vt 0.350121 0.442675 +vt 0.396949 0.442675 +vt 0.396949 0.436395 +vt 0.350121 0.436395 +vt 0.300793 0.442675 +vt 0.350121 0.442675 +vt 0.350121 0.436395 +vt 0.300793 0.436395 +vt 0.249801 0.442675 +vt 0.300793 0.442675 +vt 0.300793 0.436395 +vt 0.249801 0.436395 +vt 0.200473 0.442675 +vt 0.249801 0.442675 +vt 0.249801 0.436395 +vt 0.200473 0.436395 +vt 0.153645 0.442675 +vt 0.200473 0.442675 +vt 0.200473 0.436395 +vt 0.153645 0.436395 +vt 0.106818 0.442675 +vt 0.153645 0.442675 +vt 0.153645 0.436395 +vt 0.106818 0.436395 +vt 0.057489 0.442675 +vt 0.106818 0.442675 +vt 0.106818 0.436395 +vt 0.057489 0.436395 +vt 0.006498 0.442675 +vt 0.057489 0.442675 +vt 0.057489 0.436395 +vt 0.006498 0.436395 +vt 0.443776 0.442675 +vt 0.493105 0.442675 +vt 0.493105 0.436395 +vt 0.443776 0.436395 +vt 0.396949 0.442675 +vt 0.443776 0.442675 +vt 0.443776 0.436395 +vt 0.396949 0.436395 +vt 0.350121 0.436395 +vt 0.396949 0.436395 +vt 0.396949 0.423835 +vt 0.350121 0.423835 +vt 0.300793 0.436395 +vt 0.350121 0.436395 +vt 0.350121 0.423835 +vt 0.300793 0.423835 +vt 0.249801 0.436395 +vt 0.300793 0.436395 +vt 0.300793 0.423835 +vt 0.249801 0.423835 +vt 0.200473 0.436395 +vt 0.249801 0.436395 +vt 0.249801 0.423835 +vt 0.200473 0.423835 +vt 0.153645 0.436395 +vt 0.200473 0.436395 +vt 0.200473 0.423835 +vt 0.153645 0.423835 +vt 0.106818 0.436395 +vt 0.153645 0.436395 +vt 0.153645 0.423835 +vt 0.106818 0.423835 +vt 0.057489 0.436395 +vt 0.106818 0.436395 +vt 0.106818 0.423835 +vt 0.057489 0.423835 +vt 0.006498 0.436395 +vt 0.057489 0.436395 +vt 0.057489 0.423835 +vt 0.006498 0.423835 +vt 0.443776 0.436395 +vt 0.493105 0.436395 +vt 0.493105 0.423835 +vt 0.443776 0.423835 +vt 0.396949 0.436395 +vt 0.443776 0.436395 +vt 0.443776 0.423835 +vt 0.396949 0.423835 +vt 0.350121 0.423835 +vt 0.396949 0.423835 +vt 0.396949 0.417555 +vt 0.350121 0.417555 +vt 0.300793 0.423835 +vt 0.350121 0.423835 +vt 0.350121 0.417555 +vt 0.300793 0.417555 +vt 0.249801 0.423835 +vt 0.300793 0.423835 +vt 0.300793 0.417555 +vt 0.249801 0.417555 +vt 0.200473 0.423835 +vt 0.249801 0.423835 +vt 0.249801 0.417555 +vt 0.200473 0.417555 +vt 0.153645 0.423835 +vt 0.200473 0.423835 +vt 0.200473 0.417555 +vt 0.153645 0.417555 +vt 0.106818 0.423835 +vt 0.153645 0.423835 +vt 0.153645 0.417555 +vt 0.106818 0.417555 +vt 0.057489 0.423835 +vt 0.106818 0.423835 +vt 0.106818 0.417555 +vt 0.057489 0.417555 +vt 0.006498 0.423835 +vt 0.057489 0.423835 +vt 0.057489 0.417555 +vt 0.006498 0.417555 +vt 0.443776 0.423835 +vt 0.493105 0.423835 +vt 0.493105 0.417555 +vt 0.443776 0.417555 +vt 0.396949 0.423835 +vt 0.443776 0.423835 +vt 0.443776 0.417555 +vt 0.396949 0.417555 +vt 0.350121 0.417555 +vt 0.396949 0.417555 +vt 0.396949 0.404768 +vt 0.350121 0.404768 +vt 0.300793 0.417555 +vt 0.350121 0.417555 +vt 0.350121 0.404768 +vt 0.300793 0.404768 +vt 0.249801 0.417555 +vt 0.300793 0.417555 +vt 0.300793 0.404768 +vt 0.249801 0.404768 +vt 0.200473 0.417555 +vt 0.249801 0.417555 +vt 0.249801 0.404768 +vt 0.200473 0.404768 +vt 0.153645 0.417555 +vt 0.200473 0.417555 +vt 0.200473 0.404768 +vt 0.153645 0.404768 +vt 0.106818 0.417555 +vt 0.153645 0.417555 +vt 0.153645 0.404768 +vt 0.106818 0.404768 +vt 0.057489 0.417555 +vt 0.106818 0.417555 +vt 0.106818 0.404768 +vt 0.057489 0.404768 +vt 0.006498 0.417555 +vt 0.057489 0.417555 +vt 0.057489 0.404768 +vt 0.006498 0.404768 +vt 0.443776 0.417555 +vt 0.493105 0.417555 +vt 0.493105 0.404768 +vt 0.443776 0.404768 +vt 0.396949 0.417555 +vt 0.443776 0.417555 +vt 0.443776 0.404768 +vt 0.396949 0.404768 +vt 0.350998 0.547962 +vt 0.398319 0.547961 +vt 0.398319 0.498824 +vt 0.350998 0.498825 +vt 0.301150 0.547961 +vt 0.301150 0.498825 +vt 0.249620 0.547961 +vt 0.249620 0.498825 +vt 0.199772 0.547962 +vt 0.199772 0.498825 +vt 0.152451 0.547962 +vt 0.152451 0.498824 +vt 0.105130 0.547961 +vt 0.105130 0.498824 +vt 0.055282 0.547962 +vt 0.055282 0.498824 +vt 0.003753 0.547962 +vt 0.003753 0.498824 +vt 0.445640 0.547961 +vt 0.495488 0.547962 +vt 0.495488 0.498824 +vt 0.445640 0.498824 +vt 0.350998 0.737698 +vt 0.398319 0.737698 +vt 0.301150 0.737698 +vt 0.249620 0.737698 +vt 0.199772 0.737698 +vt 0.152451 0.737698 +vt 0.105130 0.737698 +vt 0.055282 0.737698 +vt 0.003753 0.737698 +vt 0.445640 0.737698 +vt 0.495488 0.737698 +vt 0.350998 0.858405 +vt 0.398319 0.858405 +vt 0.301150 0.858405 +vt 0.249620 0.858405 +vt 0.199772 0.858405 +vt 0.152451 0.858405 +vt 0.105130 0.858405 +vt 0.055282 0.858405 +vt 0.003753 0.858405 +vt 0.445640 0.858405 +vt 0.495488 0.858405 +vt 0.350998 0.961982 +vt 0.398319 0.961982 +vt 0.301150 0.961982 +vt 0.249620 0.961982 +vt 0.199772 0.961982 +vt 0.152451 0.961982 +vt 0.105130 0.961982 +vt 0.055282 0.961982 +vt 0.003753 0.961982 +vt 0.445640 0.961982 +vt 0.495488 0.961982 +vt 0.350998 0.996654 +vt 0.398319 0.996654 +vt 0.301150 0.996654 +vt 0.249620 0.996654 +vt 0.199772 0.996654 +vt 0.152451 0.996654 +vt 0.105130 0.996654 +vt 0.055282 0.996654 +vt 0.003753 0.996654 +vt 0.445640 0.996654 +vt 0.495488 0.996654 +vn 0.000001 -0.000117 -1.000000 +vn 0.000007 -0.000119 -1.000000 +vn 0.000004 -0.000642 -1.000000 +vn 0.000290 -0.001097 -0.999999 +vn 0.965539 -0.259953 0.012557 +vn 0.960748 -0.276359 0.024272 +vn 0.995038 -0.099144 0.008333 +vn 0.997311 0.073275 0.000826 +vn 0.384905 -0.746403 0.542891 +vn -0.062420 -0.728758 0.681921 +vn 0.161475 -0.510903 0.844336 +vn 0.298440 -0.528902 0.794478 +vn -0.388088 -0.822360 0.416066 +vn -0.374937 -0.503238 0.778571 +vn -0.967185 -0.253827 0.011142 +vn -0.969696 -0.243379 0.021376 +vn -0.995359 -0.095953 0.007360 +vn -0.997773 0.066697 0.000871 +vn -0.000005 -0.000117 -1.000000 +vn -0.000578 -0.001225 -0.999999 +vn -0.002059 0.162154 -0.986763 +vn 0.036715 0.227361 -0.973118 +vn 0.988150 0.153490 0.000530 +vn 0.997092 0.076202 0.000795 +vn 0.419290 0.355620 0.835302 +vn 0.335340 0.314686 0.887986 +vn 0.476829 0.120448 0.870704 +vn 0.548589 -0.115983 0.828008 +vn -0.425538 0.336785 0.839936 +vn -0.326355 0.383871 0.863791 +vn -0.479491 0.111072 0.870489 +vn -0.546378 -0.151051 0.823805 +vn -0.988094 0.153853 0.000548 +vn -0.996980 0.077652 0.000810 +vn -0.071204 0.307808 -0.948780 +vn 0.134041 0.542848 -0.829065 +vn 0.038742 0.586621 -0.808935 +vn 0.999191 -0.037450 -0.014645 +vn 0.997224 -0.066926 -0.032638 +vn 0.508477 -0.486691 0.710340 +vn 0.518399 -0.586423 0.622391 +vn -0.510691 -0.477362 0.715067 +vn -0.519541 -0.586094 0.621748 +vn -0.999321 -0.034320 -0.013421 +vn -0.997248 -0.066385 -0.032993 +vn -0.208233 0.626135 -0.751394 +vn 0.208454 0.614903 -0.760553 +vn 0.003597 0.581754 -0.813357 +vn 0.994885 -0.089661 -0.046525 +vn 0.994269 -0.101688 -0.032983 +vn 0.510524 -0.657019 0.554699 +vn 0.512927 -0.632907 0.579944 +vn -0.512007 -0.660652 0.548989 +vn -0.514396 -0.638014 0.573004 +vn -0.992961 -0.104288 -0.056137 +vn -0.993472 -0.105450 -0.043510 +vn -0.215729 0.522222 -0.825073 +vn 0.214294 0.359182 -0.908332 +vn 0.000134 0.334072 -0.942548 +vn 0.997269 -0.072312 -0.015018 +vn 0.998775 -0.049471 -0.001064 +vn 0.525393 -0.499573 0.688759 +vn 0.520961 -0.381681 0.763491 +vn -0.527026 -0.502395 0.685451 +vn -0.522284 -0.373646 0.766556 +vn -0.997005 -0.073521 -0.023992 +vn -0.999371 -0.035442 -0.000762 +vn -0.214604 0.292047 -0.932016 +vn -0.000002 -0.996240 0.086630 +vn 0.254654 -0.964745 -0.066466 +vn -0.000002 -0.978728 -0.205161 +vn 0.384905 -0.746403 0.542891 +vn -0.062420 -0.728758 0.681921 +vn -0.388088 -0.822360 0.416066 +vn -0.254657 -0.964744 -0.066466 +vn 0.215116 0.223526 -0.950664 +vn -0.074129 0.228601 -0.970694 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.532664 -0.238851 0.811923 +vn 0.525606 -0.243348 0.815181 +vn -0.532938 -0.238769 0.811767 +vn -0.526504 -0.236645 0.816574 +vn -1.000000 -0.000000 0.000000 +vn -1.000000 -0.000000 0.000000 +vn -0.212589 0.222631 -0.951442 +vn 0.000117 0.000000 -1.000000 +vn 0.000118 0.000007 -1.000000 +vn 0.000642 0.000004 -1.000000 +vn 0.001097 0.000289 -0.999999 +vn 0.259953 0.965539 0.012557 +vn 0.276358 0.960748 0.024272 +vn 0.099144 0.995038 0.008333 +vn -0.073275 0.997311 0.000826 +vn 0.746403 0.384905 0.542891 +vn 0.728758 -0.062420 0.681921 +vn 0.510903 0.161476 0.844336 +vn 0.528902 0.298440 0.794478 +vn 0.822360 -0.388088 0.416066 +vn 0.503238 -0.374936 0.778572 +vn 0.253827 -0.967185 0.011142 +vn 0.243379 -0.969696 0.021376 +vn 0.095953 -0.995359 0.007360 +vn -0.066697 -0.997773 0.000871 +vn 0.000117 -0.000006 -1.000000 +vn 0.001225 -0.000578 -0.999999 +vn -0.162154 -0.002061 -0.986763 +vn -0.227361 0.036714 -0.973118 +vn -0.153490 0.988150 0.000530 +vn -0.076202 0.997092 0.000795 +vn -0.355620 0.419290 0.835302 +vn -0.314686 0.335340 0.887986 +vn -0.120448 0.476829 0.870704 +vn 0.115983 0.548589 0.828008 +vn -0.336785 -0.425537 0.839937 +vn -0.383871 -0.326354 0.863792 +vn -0.111072 -0.479490 0.870490 +vn 0.151051 -0.546377 0.823805 +vn -0.153853 -0.988094 0.000549 +vn -0.077652 -0.996980 0.000810 +vn -0.307808 -0.071204 -0.948780 +vn -0.542849 0.134040 -0.829065 +vn -0.586621 0.038742 -0.808935 +vn 0.037450 0.999191 -0.014646 +vn 0.066926 0.997224 -0.032638 +vn 0.486691 0.508477 0.710340 +vn 0.586423 0.518399 0.622390 +vn 0.477362 -0.510691 0.715067 +vn 0.586095 -0.519541 0.621748 +vn 0.034320 -0.999321 -0.013421 +vn 0.066385 -0.997248 -0.032993 +vn -0.626135 -0.208233 -0.751394 +vn -0.614903 0.208454 -0.760553 +vn -0.581754 0.003596 -0.813357 +vn 0.089661 0.994885 -0.046525 +vn 0.101687 0.994269 -0.032983 +vn 0.657019 0.510524 0.554699 +vn 0.632907 0.512927 0.579944 +vn 0.660652 -0.512006 0.548989 +vn 0.638015 -0.514396 0.573004 +vn 0.104288 -0.992961 -0.056137 +vn 0.105450 -0.993472 -0.043510 +vn -0.522222 -0.215730 -0.825073 +vn -0.359182 0.214294 -0.908332 +vn -0.334072 0.000134 -0.942547 +vn 0.072312 0.997269 -0.015018 +vn 0.049471 0.998775 -0.001064 +vn 0.499573 0.525393 0.688759 +vn 0.381681 0.520961 0.763491 +vn 0.502395 -0.527026 0.685451 +vn 0.373646 -0.522284 0.766556 +vn 0.073521 -0.997005 -0.023992 +vn 0.035442 -0.999371 -0.000762 +vn -0.292047 -0.214604 -0.932016 +vn 0.996240 -0.000002 0.086630 +vn 0.964745 0.254654 -0.066466 +vn 0.978728 -0.000002 -0.205161 +vn 0.746403 0.384905 0.542891 +vn 0.728758 -0.062420 0.681921 +vn 0.822360 -0.388088 0.416066 +vn 0.964744 -0.254658 -0.066466 +vn -0.223526 0.215116 -0.950664 +vn -0.228601 -0.074129 -0.970694 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn 0.238851 0.532664 0.811923 +vn 0.243348 0.525606 0.815181 +vn 0.238770 -0.532938 0.811767 +vn 0.236645 -0.526504 0.816574 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.222631 -0.212589 -0.951442 +vn -0.000001 0.000116 -1.000000 +vn -0.000009 0.000119 -1.000000 +vn -0.000005 0.000642 -1.000000 +vn -0.000289 0.001096 -0.999999 +vn -0.965539 0.259953 0.012557 +vn -0.960748 0.276358 0.024272 +vn -0.995038 0.099144 0.008333 +vn -0.997311 -0.073275 0.000826 +vn -0.384905 0.746403 0.542891 +vn 0.062420 0.728758 0.681921 +vn -0.161475 0.510903 0.844336 +vn -0.298440 0.528902 0.794478 +vn 0.388088 0.822361 0.416066 +vn 0.374936 0.503239 0.778571 +vn 0.967185 0.253827 0.011142 +vn 0.969696 0.243379 0.021376 +vn 0.995359 0.095953 0.007360 +vn 0.997773 -0.066696 0.000871 +vn 0.000006 0.000116 -1.000000 +vn 0.000578 0.001225 -0.999999 +vn 0.002061 -0.162154 -0.986763 +vn -0.036715 -0.227361 -0.973118 +vn -0.988150 -0.153490 0.000530 +vn -0.997092 -0.076202 0.000795 +vn -0.419290 -0.355620 0.835302 +vn -0.335340 -0.314686 0.887986 +vn -0.476829 -0.120448 0.870704 +vn -0.548589 0.115983 0.828008 +vn 0.425538 -0.336785 0.839937 +vn 0.326355 -0.383871 0.863791 +vn 0.479490 -0.111072 0.870490 +vn 0.546377 0.151051 0.823806 +vn 0.988094 -0.153853 0.000549 +vn 0.996980 -0.077652 0.000810 +vn 0.071202 -0.307807 -0.948781 +vn -0.134041 -0.542849 -0.829065 +vn -0.038743 -0.586621 -0.808935 +vn -0.999191 0.037450 -0.014645 +vn -0.997224 0.066925 -0.032638 +vn -0.508477 0.486691 0.710340 +vn -0.518400 0.586423 0.622390 +vn 0.510690 0.477362 0.715067 +vn 0.519540 0.586095 0.621748 +vn 0.999321 0.034320 -0.013421 +vn 0.997248 0.066385 -0.032993 +vn 0.208233 -0.626135 -0.751394 +vn -0.208455 -0.614903 -0.760553 +vn -0.003597 -0.581754 -0.813357 +vn -0.994885 0.089660 -0.046525 +vn -0.994269 0.101687 -0.032983 +vn -0.510524 0.657019 0.554699 +vn -0.512927 0.632907 0.579944 +vn 0.512006 0.660652 0.548989 +vn 0.514396 0.638015 0.573004 +vn 0.992961 0.104288 -0.056137 +vn 0.993472 0.105451 -0.043510 +vn 0.215730 -0.522222 -0.825072 +vn -0.214294 -0.359182 -0.908332 +vn -0.000134 -0.334072 -0.942547 +vn -0.997269 0.072312 -0.015018 +vn -0.998775 0.049471 -0.001064 +vn -0.525393 0.499573 0.688759 +vn -0.520961 0.381681 0.763491 +vn 0.527026 0.502395 0.685451 +vn 0.522284 0.373646 0.766556 +vn 0.997005 0.073521 -0.023992 +vn 0.999371 0.035442 -0.000762 +vn 0.214604 -0.292047 -0.932016 +vn 0.000002 0.996240 0.086630 +vn -0.254654 0.964745 -0.066466 +vn 0.000002 0.978728 -0.205161 +vn -0.384905 0.746403 0.542891 +vn 0.062420 0.728758 0.681921 +vn 0.388088 0.822361 0.416066 +vn 0.254658 0.964744 -0.066466 +vn -0.215116 -0.223526 -0.950664 +vn 0.074129 -0.228601 -0.970694 +vn -1.000000 -0.000000 -0.000000 +vn -1.000000 -0.000000 -0.000000 +vn -0.532664 0.238851 0.811923 +vn -0.525606 0.243348 0.815181 +vn 0.532938 0.238770 0.811767 +vn 0.526504 0.236645 0.816574 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.212589 -0.222631 -0.951442 +vn -0.000117 -0.000002 -1.000000 +vn -0.000120 -0.000009 -1.000000 +vn -0.000642 -0.000005 -1.000000 +vn -0.001096 -0.000290 -0.999999 +vn -0.259953 -0.965540 0.012557 +vn -0.276358 -0.960748 0.024272 +vn -0.099144 -0.995038 0.008333 +vn 0.073275 -0.997311 0.000826 +vn -0.746403 -0.384905 0.542891 +vn -0.728758 0.062420 0.681921 +vn -0.510903 -0.161475 0.844336 +vn -0.528903 -0.298440 0.794478 +vn -0.822360 0.388088 0.416066 +vn -0.503238 0.374937 0.778571 +vn -0.253827 0.967185 0.011142 +vn -0.243379 0.969696 0.021376 +vn -0.095953 0.995359 0.007360 +vn 0.066697 0.997773 0.000871 +vn -0.000116 0.000005 -1.000000 +vn -0.001225 0.000578 -0.999999 +vn 0.162155 0.002059 -0.986763 +vn 0.227361 -0.036715 -0.973118 +vn 0.153490 -0.988150 0.000530 +vn 0.076203 -0.997092 0.000795 +vn 0.355621 -0.419290 0.835302 +vn 0.314686 -0.335340 0.887986 +vn 0.120448 -0.476829 0.870704 +vn -0.115983 -0.548589 0.828008 +vn 0.336785 0.425538 0.839937 +vn 0.383871 0.326355 0.863791 +vn 0.111072 0.479490 0.870490 +vn -0.151051 0.546377 0.823805 +vn 0.153853 0.988094 0.000548 +vn 0.077652 0.996980 0.000810 +vn 0.307808 0.071202 -0.948781 +vn 0.542849 -0.134041 -0.829065 +vn 0.586621 -0.038743 -0.808934 +vn -0.037450 -0.999191 -0.014645 +vn -0.066925 -0.997224 -0.032638 +vn -0.486691 -0.508477 0.710340 +vn -0.586423 -0.518400 0.622390 +vn -0.477362 0.510691 0.715067 +vn -0.586095 0.519541 0.621748 +vn -0.034320 0.999321 -0.013421 +vn -0.066385 0.997248 -0.032993 +vn 0.626135 0.208232 -0.751395 +vn 0.614903 -0.208454 -0.760553 +vn 0.581754 -0.003597 -0.813357 +vn -0.089660 -0.994885 -0.046525 +vn -0.101687 -0.994269 -0.032983 +vn -0.657019 -0.510525 0.554699 +vn -0.632907 -0.512927 0.579944 +vn -0.660652 0.512007 0.548988 +vn -0.638015 0.514396 0.573004 +vn -0.104288 0.992961 -0.056137 +vn -0.105451 0.993472 -0.043510 +vn 0.522222 0.215729 -0.825072 +vn 0.359182 -0.214295 -0.908331 +vn 0.334072 -0.000134 -0.942547 +vn -0.072312 -0.997269 -0.015018 +vn -0.049471 -0.998775 -0.001064 +vn -0.499573 -0.525393 0.688759 +vn -0.381681 -0.520961 0.763491 +vn -0.502395 0.527026 0.685451 +vn -0.373646 0.522284 0.766556 +vn -0.073521 0.997005 -0.023992 +vn -0.035442 0.999371 -0.000763 +vn 0.292047 0.214604 -0.932016 +vn -0.996240 0.000002 0.086630 +vn -0.964745 -0.254654 -0.066466 +vn -0.978728 0.000002 -0.205161 +vn -0.746403 -0.384905 0.542891 +vn -0.728758 0.062420 0.681921 +vn -0.822360 0.388088 0.416066 +vn -0.964744 0.254657 -0.066466 +vn 0.223526 -0.215116 -0.950664 +vn 0.228601 0.074129 -0.970694 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.238851 -0.532664 0.811923 +vn -0.243348 -0.525606 0.815181 +vn -0.238770 0.532938 0.811767 +vn -0.236645 0.526504 0.816574 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn 0.222631 0.212589 -0.951442 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.706842 0.707371 0.000000 +vn 0.706842 0.707371 0.000000 +vn 0.706842 0.707371 0.000000 +vn 0.706842 0.707371 0.000000 +vn -0.000374 1.000000 0.000000 +vn -0.000374 1.000000 0.000000 +vn -0.000374 1.000000 0.000000 +vn -0.000374 1.000000 0.000000 +vn -0.707371 0.706842 0.000000 +vn -0.707371 0.706842 0.000000 +vn -0.707371 0.706842 0.000000 +vn -0.707371 0.706842 0.000000 +vn -1.000000 -0.000374 0.000000 +vn -1.000000 -0.000374 0.000000 +vn -1.000000 -0.000374 0.000000 +vn -1.000000 -0.000374 0.000000 +vn -0.706842 -0.707371 -0.000000 +vn -0.706842 -0.707371 -0.000000 +vn -0.706842 -0.707371 -0.000000 +vn -0.706842 -0.707371 0.000000 +vn 0.000374 -1.000000 -0.000000 +vn 0.000374 -1.000000 0.000000 +vn 0.000374 -1.000000 -0.000000 +vn 0.000374 -1.000000 -0.000000 +vn 0.707371 -0.706842 -0.000000 +vn 0.707371 -0.706842 -0.000000 +vn 0.707371 -0.706842 -0.000000 +vn 0.707371 -0.706842 -0.000000 +vn 1.000000 0.000374 0.000000 +vn 1.000000 0.000374 0.000000 +vn 1.000000 0.000374 0.000000 +vn 1.000000 0.000374 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.099506 0.000000 0.995037 +vn -0.099506 0.000000 0.995037 +vn -0.099506 0.000000 0.995037 +vn -0.099506 0.000000 0.995037 +vn 0.000000 -0.099506 0.995037 +vn 0.000000 -0.099506 0.995037 +vn 0.000000 -0.099506 0.995037 +vn 0.000000 -0.099506 0.995037 +vn 0.099506 0.000000 0.995037 +vn 0.099506 0.000000 0.995037 +vn 0.099506 0.000000 0.995037 +vn 0.099506 0.000000 0.995037 +vn 0.000000 0.099506 0.995037 +vn 0.000000 0.099506 0.995037 +vn 0.000000 0.099506 0.995037 +vn 0.000000 0.099506 0.995037 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -0.929987 0.000000 0.367592 +vn -0.677867 0.000000 0.735184 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -0.929987 0.367592 +vn 0.000000 -0.677867 0.735184 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.929987 0.000000 0.367592 +vn 0.677867 0.000000 0.735184 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 0.929987 0.367592 +vn 0.000000 0.677867 0.735184 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.967538 0.252725 +vn 0.000000 0.862856 0.505449 +vn 0.967538 0.000000 0.252725 +vn 0.862856 0.000000 0.505449 +vn -0.000000 -0.967538 0.252725 +vn -0.000000 -0.862856 0.505449 +vn -0.967538 0.000000 0.252725 +vn -0.862856 0.000000 0.505449 +vn 0.000000 0.862856 0.505449 +vn 0.000000 0.967538 0.252725 +vn 0.862856 0.000000 0.505449 +vn 0.967538 0.000000 0.252725 +vn -0.000000 -0.862856 0.505449 +vn -0.000000 -0.967538 0.252725 +vn -0.862856 0.000000 0.505449 +vn -0.967538 0.000000 0.252725 +vn 0.000000 0.967538 0.252725 +vn 0.000000 0.862856 0.505449 +vn 0.967538 0.000000 0.252724 +vn 0.862857 0.000000 0.505449 +vn -0.000000 -0.967538 0.252724 +vn -0.000000 -0.862857 0.505448 +vn -0.967538 0.000000 0.252725 +vn -0.862857 0.000000 0.505449 +vn 0.000000 0.707107 0.707107 +vn 0.000000 0.707107 0.707107 +vn 0.707108 0.000000 0.707106 +vn 0.707107 0.000000 0.707107 +vn -0.000000 -0.707108 0.707105 +vn -0.000000 -0.707108 0.707105 +vn -0.707108 0.000000 0.707106 +vn -0.707108 0.000000 0.707105 +vn 0.000000 0.099506 0.995037 +vn 0.000000 0.099506 0.995037 +vn 0.000000 0.099506 0.995037 +vn 0.000000 0.099506 0.995037 +vn 0.099506 0.000000 0.995037 +vn 0.099501 0.000000 0.995037 +vn 0.099506 0.000000 0.995037 +vn 0.099506 0.000000 0.995037 +vn -0.000000 -0.099501 0.995037 +vn -0.000000 -0.099501 0.995037 +vn -0.000000 -0.099501 0.995037 +vn -0.000000 -0.099501 0.995037 +vn -0.099501 0.000000 0.995037 +vn -0.099506 0.000000 0.995037 +vn -0.099501 0.000000 0.995037 +vn -0.099501 0.000000 0.995037 +vn -0.275482 0.000000 0.961306 +vn -0.187896 0.000000 0.982189 +vn 0.000000 -0.275482 0.961306 +vn 0.000000 -0.187896 0.982189 +vn 0.275482 0.000000 0.961306 +vn 0.187896 0.000000 0.982189 +vn 0.000000 0.275482 0.961306 +vn 0.000000 0.187896 0.982189 +vn -0.516067 0.000000 0.856548 +vn -0.903649 0.000000 0.428274 +vn 0.000000 -0.516067 0.856548 +vn 0.000000 -0.903649 0.428274 +vn 0.516067 0.000000 0.856548 +vn 0.903649 0.000000 0.428274 +vn 0.000000 0.516067 0.856548 +vn 0.000000 0.903649 0.428274 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.049938 0.000000 0.998752 +vn -0.049938 0.000000 0.998752 +vn -0.049938 0.000000 0.998752 +vn -0.049938 0.000000 0.998752 +vn 0.000000 -0.049938 0.998752 +vn 0.000000 -0.049938 0.998752 +vn 0.000000 -0.049938 0.998752 +vn 0.000000 -0.049938 0.998752 +vn 0.049938 0.000000 0.998752 +vn 0.049938 0.000000 0.998752 +vn 0.049938 0.000000 0.998752 +vn 0.049938 0.000000 0.998752 +vn 0.000000 0.049938 0.998752 +vn 0.000000 0.049938 0.998752 +vn 0.000000 0.049938 0.998752 +vn 0.000000 0.049938 0.998752 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 1.000000 -0.000002 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 -0.000002 +vn 0.000000 1.000000 -0.000005 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 -1.000000 0.000002 +vn 0.000000 -1.000000 0.000005 +vn -0.000000 -1.000000 0.000002 +vn -0.000000 -1.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.562661 0.423331 -0.710072 +vn 0.704032 0.011758 -0.710070 +vn 0.582173 0.063049 -0.810617 +vn 0.433925 0.393201 -0.810618 +vn 0.206373 0.673207 -0.710072 +vn 0.119934 0.573161 -0.810618 +vn -0.228742 0.665939 -0.710072 +vn -0.239867 0.534192 -0.810618 +vn -0.576487 0.404302 -0.710072 +vn -0.508049 0.291177 -0.810618 +vn -0.704032 -0.011763 -0.710070 +vn -0.582173 -0.063055 -0.810616 +vn -0.562662 -0.423334 -0.710070 +vn -0.433926 -0.393204 -0.810616 +vn -0.206373 -0.673209 -0.710070 +vn -0.119934 -0.573164 -0.810616 +vn 0.228743 -0.665941 -0.710070 +vn 0.239869 -0.534195 -0.810616 +vn 0.576487 -0.404306 -0.710070 +vn 0.508049 -0.291182 -0.810616 +vn 0.745732 0.553468 -0.370886 +vn 0.928631 0.009435 -0.370885 +vn 0.277988 0.886096 -0.370886 +vn -0.295936 0.880264 -0.370886 +vn -0.756825 0.538201 -0.370886 +vn -0.928631 -0.009437 -0.370885 +vn -0.745732 -0.553469 -0.370885 +vn -0.277989 -0.886096 -0.370885 +vn 0.295937 -0.880265 -0.370885 +vn 0.756824 -0.538202 -0.370885 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 -0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.951056 -0.309017 0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.047494 0.015432 0.998752 +vn 0.047493 0.015432 0.998752 +vn 0.047494 0.015432 0.998752 +vn 0.047494 0.015432 0.998752 +vn 0.029353 0.040401 0.998752 +vn 0.029353 0.040401 0.998752 +vn 0.029353 0.040401 0.998752 +vn 0.029353 0.040401 0.998752 +vn 0.000000 0.049938 0.998752 +vn 0.000000 0.049938 0.998752 +vn 0.000000 0.049938 0.998752 +vn 0.000000 0.049938 0.998752 +vn -0.029353 0.040401 0.998752 +vn -0.029353 0.040401 0.998752 +vn -0.029353 0.040401 0.998752 +vn -0.029353 0.040401 0.998752 +vn -0.047493 0.015431 0.998752 +vn -0.047494 0.015432 0.998752 +vn -0.047493 0.015431 0.998752 +vn -0.047493 0.015431 0.998752 +vn -0.047493 -0.015432 0.998752 +vn -0.047493 -0.015432 0.998752 +vn -0.047493 -0.015432 0.998752 +vn -0.047493 -0.015432 0.998752 +vn -0.029353 -0.040400 0.998752 +vn -0.029353 -0.040400 0.998752 +vn -0.029353 -0.040400 0.998752 +vn -0.029353 -0.040400 0.998752 +vn 0.000000 -0.049937 0.998752 +vn 0.000000 -0.049937 0.998752 +vn 0.000000 -0.049937 0.998752 +vn 0.000000 -0.049937 0.998752 +vn 0.029353 -0.040399 0.998752 +vn 0.029353 -0.040400 0.998752 +vn 0.029353 -0.040399 0.998752 +vn 0.029353 -0.040399 0.998752 +vn 0.047493 -0.015432 0.998752 +vn 0.047493 -0.015432 0.998752 +vn 0.047493 -0.015432 0.998752 +vn 0.047493 -0.015432 0.998752 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 -0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.951056 -0.309017 0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.425325 0.138196 -0.894427 +vn 0.425326 0.138197 -0.894427 +vn 0.425325 0.138196 -0.894427 +vn 0.425325 0.138196 -0.894427 +vn 0.262866 0.361804 -0.894427 +vn 0.262865 0.361803 -0.894427 +vn 0.262866 0.361804 -0.894427 +vn 0.262866 0.361804 -0.894427 +vn -0.000000 0.447215 -0.894427 +vn 0.000000 0.447214 -0.894427 +vn -0.000000 0.447215 -0.894427 +vn -0.000000 0.447215 -0.894427 +vn -0.262865 0.361803 -0.894427 +vn -0.262866 0.361804 -0.894427 +vn -0.262865 0.361803 -0.894427 +vn -0.262865 0.361803 -0.894427 +vn -0.425326 0.138196 -0.894427 +vn -0.425325 0.138196 -0.894427 +vn -0.425326 0.138196 -0.894427 +vn -0.425326 0.138196 -0.894427 +vn -0.425326 -0.138196 -0.894427 +vn -0.425326 -0.138196 -0.894427 +vn -0.425326 -0.138196 -0.894427 +vn -0.425326 -0.138196 -0.894427 +vn -0.262865 -0.361804 -0.894427 +vn -0.262865 -0.361804 -0.894427 +vn -0.262865 -0.361804 -0.894427 +vn -0.262865 -0.361804 -0.894427 +vn 0.000000 -0.447214 -0.894427 +vn 0.000000 -0.447214 -0.894427 +vn 0.000000 -0.447214 -0.894427 +vn 0.000000 -0.447214 -0.894427 +vn 0.262865 -0.361804 -0.894427 +vn 0.262865 -0.361804 -0.894427 +vn 0.262865 -0.361804 -0.894427 +vn 0.262865 -0.361804 -0.894427 +vn 0.425326 -0.138196 -0.894427 +vn 0.425326 -0.138196 -0.894427 +vn 0.425326 -0.138196 -0.894427 +vn 0.425326 -0.138196 -0.894427 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.587786 0.809017 -0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587786 0.809017 -0.000000 +vn 0.587786 0.809017 -0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 -0.000001 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 -0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.951056 -0.309017 0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.951056 -0.309017 -0.000000 +vn 0.425325 0.138197 0.894427 +vn 0.425326 0.138197 0.894427 +vn 0.425325 0.138197 0.894427 +vn 0.425325 0.138197 0.894427 +vn 0.262866 0.361803 0.894427 +vn 0.262866 0.361804 0.894427 +vn 0.262866 0.361803 0.894427 +vn 0.262866 0.361803 0.894427 +vn 0.000000 0.447214 0.894427 +vn -0.000000 0.447213 0.894427 +vn 0.000000 0.447214 0.894427 +vn 0.000000 0.447214 0.894427 +vn -0.262866 0.361804 0.894427 +vn -0.262865 0.361804 0.894427 +vn -0.262866 0.361804 0.894427 +vn -0.262866 0.361804 0.894427 +vn -0.425326 0.138197 0.894427 +vn -0.425326 0.138197 0.894427 +vn -0.425326 0.138197 0.894427 +vn -0.425326 0.138197 0.894427 +vn -0.425324 -0.138197 0.894428 +vn -0.425326 -0.138197 0.894427 +vn -0.425324 -0.138197 0.894428 +vn -0.425324 -0.138197 0.894428 +vn -0.262866 -0.361803 0.894427 +vn -0.262865 -0.361802 0.894428 +vn -0.262866 -0.361803 0.894427 +vn -0.262866 -0.361803 0.894427 +vn 0.000000 -0.447213 0.894427 +vn 0.000000 -0.447213 0.894427 +vn 0.000000 -0.447213 0.894427 +vn 0.000000 -0.447213 0.894427 +vn 0.262866 -0.361802 0.894427 +vn 0.262866 -0.361803 0.894427 +vn 0.262866 -0.361802 0.894427 +vn 0.262866 -0.361802 0.894427 +vn 0.425326 -0.138198 0.894427 +vn 0.425325 -0.138197 0.894427 +vn 0.425326 -0.138198 0.894427 +vn 0.425326 -0.138198 0.894427 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000001 +vn 0.951056 0.309017 0.000000 +vn 0.951056 0.309017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.587785 0.809017 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.587785 0.809017 0.000001 +vn -0.587785 0.809017 0.000000 +vn -0.587785 0.809017 0.000001 +vn -0.587785 0.809017 0.000001 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000001 +vn -0.951056 0.309017 0.000000 +vn -0.951056 0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 -0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.951056 -0.309017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn -0.587785 -0.809017 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.587785 -0.809017 0.000000 +vn 0.951056 -0.309017 0.000001 +vn 0.951056 -0.309017 0.000000 +vn 0.951056 -0.309017 0.000001 +vn 0.951056 -0.309017 0.000001 +vn 0.808878 0.587853 -0.012040 +vn 0.999927 0.000136 -0.012040 +vn 0.928631 0.009435 -0.370885 +vn 0.745732 0.553468 -0.370886 +vn 0.308865 0.951030 -0.012040 +vn 0.277988 0.886096 -0.370886 +vn -0.309124 0.950945 -0.012040 +vn -0.295936 0.880264 -0.370886 +vn -0.809038 0.587632 -0.012040 +vn -0.756825 0.538201 -0.370886 +vn -0.999927 -0.000136 -0.012040 +vn -0.928631 -0.009437 -0.370885 +vn -0.808878 -0.587853 -0.012040 +vn -0.745732 -0.553469 -0.370885 +vn -0.308865 -0.951030 -0.012040 +vn -0.277989 -0.886096 -0.370885 +vn 0.309124 -0.950945 -0.012040 +vn 0.295937 -0.880265 -0.370885 +vn 0.809038 -0.587632 -0.012040 +vn 0.309124 -0.950945 -0.012040 +vn 0.295937 -0.880265 -0.370885 +vn 0.756824 -0.538202 -0.370885 +vn 0.797207 0.577639 0.175482 +vn 0.984482 -0.001267 0.175482 +vn 0.305427 0.935906 0.175482 +vn -0.303017 0.936689 0.175482 +vn -0.795718 0.579689 0.175482 +vn -0.984482 0.001267 0.175482 +vn -0.797207 -0.577639 0.175482 +vn -0.305426 -0.935906 0.175482 +vn 0.303017 -0.936689 0.175482 +vn 0.795718 -0.579689 0.175482 +vn 0.303017 -0.936689 0.175482 +vn 0.805510 0.586917 0.081747 +vn 0.996652 0.001359 0.081747 +vn 0.306690 0.948292 0.081747 +vn -0.309275 0.947452 0.081747 +vn -0.807107 0.584718 0.081747 +vn -0.996652 -0.001359 0.081747 +vn -0.805510 -0.586917 0.081747 +vn -0.306690 -0.948292 0.081747 +vn 0.309275 -0.947452 0.081747 +vn 0.807107 -0.584718 0.081747 +vn 0.309275 -0.947452 0.081747 +vn 0.768673 0.548289 -0.329426 +vn 0.944145 -0.008240 -0.329426 +vn 0.299593 0.895389 -0.329426 +vn -0.283921 0.900482 -0.329426 +vn -0.758987 0.561621 -0.329426 +vn -0.944145 0.008240 -0.329426 +vn -0.768673 -0.548289 -0.329426 +vn -0.299593 -0.895389 -0.329426 +vn 0.283921 -0.900482 -0.329426 +vn 0.758987 -0.561620 -0.329426 +vn 0.283921 -0.900482 -0.329426 +vn 0.726320 0.416280 -0.546965 +vn 0.832289 -0.090142 -0.546964 +vn 0.342922 0.763698 -0.546965 +vn -0.171461 0.819409 -0.546965 +vn -0.620351 0.562133 -0.546965 +vn -0.832288 0.090142 -0.546965 +vn -0.726320 -0.416280 -0.546965 +vn -0.342922 -0.763698 -0.546965 +vn 0.171461 -0.819409 -0.546965 +vn 0.620351 -0.562134 -0.546965 +vn 0.171461 -0.819409 -0.546965 +f 1/1/1 2/2/2 3/3/3 +f 3/3/3 4/4/4 1/1/1 +f 5/5/5 6/6/6 7/7/7 +f 7/7/7 8/8/8 5/5/5 +f 9/9/9 10/10/10 11/11/11 +f 11/11/11 12/12/12 9/9/9 +f 10/10/10 13/13/13 14/14/14 +f 14/14/14 11/11/11 10/10/10 +f 15/15/15 16/16/16 17/17/17 +f 17/17/17 18/18/18 15/15/15 +f 19/19/19 1/1/1 4/4/4 +f 4/4/4 20/20/20 19/19/19 +f 4/4/4 3/3/3 21/21/21 +f 21/21/21 22/22/22 4/4/4 +f 8/8/8 7/7/7 23/23/23 +f 23/23/23 24/24/24 8/8/8 +f 25/25/25 26/26/26 27/27/27 +f 27/27/27 28/28/28 25/25/25 +f 29/29/29 30/30/30 31/31/31 +f 31/31/31 32/32/32 29/29/29 +f 18/18/18 17/17/17 33/33/33 +f 33/33/33 34/34/34 18/18/18 +f 20/20/20 4/4/4 22/22/22 +f 22/22/22 35/35/35 20/20/20 +f 22/22/22 21/21/21 36/36/36 +f 36/36/36 37/37/37 22/22/22 +f 24/24/24 23/23/23 38/38/38 +f 38/38/38 39/39/39 24/24/24 +f 28/28/28 27/27/27 40/40/40 +f 40/40/40 41/41/41 28/28/28 +f 32/32/32 31/31/31 42/42/42 +f 42/42/42 43/43/43 32/32/32 +f 34/34/34 33/33/33 44/44/44 +f 44/44/44 45/45/45 34/34/34 +f 35/35/35 22/22/22 37/37/37 +f 37/37/37 46/46/46 35/35/35 +f 37/37/37 36/36/36 47/47/47 +f 47/47/47 48/48/48 37/37/37 +f 39/39/39 38/38/38 49/49/49 +f 49/49/49 50/50/50 39/39/39 +f 41/41/41 40/40/40 51/51/51 +f 51/51/51 52/52/52 41/41/41 +f 43/43/43 42/42/42 53/53/53 +f 53/53/53 54/54/54 43/43/43 +f 45/45/45 44/44/44 55/55/55 +f 55/55/55 56/56/56 45/45/45 +f 46/46/46 37/37/37 48/48/48 +f 48/48/48 57/57/57 46/46/46 +f 48/48/48 47/47/47 58/58/58 +f 58/58/58 59/59/59 48/48/48 +f 50/50/50 49/49/49 60/60/60 +f 60/60/60 61/61/61 50/50/50 +f 52/52/52 51/51/51 62/62/62 +f 62/62/62 63/63/63 52/52/52 +f 54/54/54 53/53/53 64/64/64 +f 64/64/64 65/65/65 54/54/54 +f 56/56/56 55/55/55 66/66/66 +f 66/66/66 67/67/67 56/56/56 +f 57/57/57 48/48/48 59/59/59 +f 59/59/59 68/68/68 57/57/57 +f 69/69/69 70/70/70 71/71/71 +f 69/69/69 72/72/72 70/70/70 +f 69/69/69 73/73/73 72/72/72 +f 69/69/69 74/74/74 73/73/73 +f 69/69/69 75/75/75 74/74/74 +f 69/69/69 71/71/71 75/75/75 +f 76/76/76 77/77/77 59/59/59 +f 76/76/76 59/59/59 58/58/58 +f 78/78/78 79/79/79 61/61/61 +f 78/78/78 61/61/61 60/60/60 +f 80/80/80 81/81/81 63/63/63 +f 80/80/80 63/63/63 62/62/62 +f 82/82/82 83/83/83 65/65/65 +f 82/82/82 65/65/65 64/64/64 +f 84/84/84 85/85/85 67/67/67 +f 84/84/84 67/67/67 66/66/66 +f 77/77/77 86/86/86 68/68/68 +f 77/77/77 68/68/68 59/59/59 +f 87/87/87 88/88/88 89/89/89 +f 89/89/89 90/90/90 87/87/87 +f 91/91/91 92/92/92 93/93/93 +f 93/93/93 94/94/94 91/91/91 +f 95/95/95 96/96/96 97/97/97 +f 97/97/97 98/98/98 95/95/95 +f 96/96/96 99/99/99 100/100/100 +f 100/100/100 97/97/97 96/96/96 +f 101/101/101 102/102/102 103/103/103 +f 103/103/103 104/104/104 101/101/101 +f 105/105/105 87/87/87 90/90/90 +f 90/90/90 106/106/106 105/105/105 +f 90/90/90 89/89/89 107/107/107 +f 107/107/107 108/108/108 90/90/90 +f 94/94/94 93/93/93 109/109/109 +f 109/109/109 110/110/110 94/94/94 +f 111/111/111 112/112/112 113/113/113 +f 113/113/113 114/114/114 111/111/111 +f 115/115/115 116/116/116 117/117/117 +f 117/117/117 118/118/118 115/115/115 +f 104/104/104 103/103/103 119/119/119 +f 119/119/119 120/120/120 104/104/104 +f 106/106/106 90/90/90 108/108/108 +f 108/108/108 121/121/121 106/106/106 +f 108/108/108 107/107/107 122/122/122 +f 122/122/122 123/123/123 108/108/108 +f 110/110/110 109/109/109 124/124/124 +f 124/124/124 125/125/125 110/110/110 +f 114/114/114 113/113/113 126/126/126 +f 126/126/126 127/127/127 114/114/114 +f 118/118/118 117/117/117 128/128/128 +f 128/128/128 129/129/129 118/118/118 +f 120/120/120 119/119/119 130/130/130 +f 130/130/130 131/131/131 120/120/120 +f 121/121/121 108/108/108 123/123/123 +f 123/123/123 132/132/132 121/121/121 +f 123/123/123 122/122/122 133/133/133 +f 133/133/133 134/134/134 123/123/123 +f 125/125/125 124/124/124 135/135/135 +f 135/135/135 136/136/136 125/125/125 +f 127/127/127 126/126/126 137/137/137 +f 137/137/137 138/138/138 127/127/127 +f 129/129/129 128/128/128 139/139/139 +f 139/139/139 140/140/140 129/129/129 +f 131/131/131 130/130/130 141/141/141 +f 141/141/141 142/142/142 131/131/131 +f 132/132/132 123/123/123 134/134/134 +f 134/134/134 143/143/143 132/132/132 +f 134/134/134 133/133/133 144/144/144 +f 144/144/144 145/145/145 134/134/134 +f 136/136/136 135/135/135 146/146/146 +f 146/146/146 147/147/147 136/136/136 +f 138/138/138 137/137/137 148/148/148 +f 148/148/148 149/149/149 138/138/138 +f 140/140/140 139/139/139 150/150/150 +f 150/150/150 151/151/151 140/140/140 +f 142/142/142 141/141/141 152/152/152 +f 152/152/152 153/153/153 142/142/142 +f 143/143/143 134/134/134 145/145/145 +f 145/145/145 154/154/154 143/143/143 +f 155/155/155 156/156/156 157/157/157 +f 155/155/155 158/158/158 156/156/156 +f 155/155/155 159/159/159 158/158/158 +f 155/155/155 160/160/160 159/159/159 +f 155/155/155 161/161/161 160/160/160 +f 155/155/155 157/157/157 161/161/161 +f 162/162/162 163/163/163 145/145/145 +f 162/162/162 145/145/145 144/144/144 +f 164/164/164 165/165/165 147/147/147 +f 164/164/164 147/147/147 146/146/146 +f 166/166/166 167/167/167 149/149/149 +f 166/166/166 149/149/149 148/148/148 +f 168/168/168 169/169/169 151/151/151 +f 168/168/168 151/151/151 150/150/150 +f 170/170/170 171/171/171 153/153/153 +f 170/170/170 153/153/153 152/152/152 +f 163/163/163 172/172/172 154/154/154 +f 163/163/163 154/154/154 145/145/145 +f 173/173/173 174/174/174 175/175/175 +f 175/175/175 176/176/176 173/173/173 +f 177/177/177 178/178/178 179/179/179 +f 179/179/179 180/180/180 177/177/177 +f 181/181/181 182/182/182 183/183/183 +f 183/183/183 184/184/184 181/181/181 +f 182/182/182 185/185/185 186/186/186 +f 186/186/186 183/183/183 182/182/182 +f 187/187/187 188/188/188 189/189/189 +f 189/189/189 190/190/190 187/187/187 +f 191/191/191 173/173/173 176/176/176 +f 176/176/176 192/192/192 191/191/191 +f 176/176/176 175/175/175 193/193/193 +f 193/193/193 194/194/194 176/176/176 +f 180/180/180 179/179/179 195/195/195 +f 195/195/195 196/196/196 180/180/180 +f 197/197/197 198/198/198 199/199/199 +f 199/199/199 200/200/200 197/197/197 +f 201/201/201 202/202/202 203/203/203 +f 203/203/203 204/204/204 201/201/201 +f 190/190/190 189/189/189 205/205/205 +f 205/205/205 206/206/206 190/190/190 +f 192/192/192 176/176/176 194/194/194 +f 194/194/194 207/207/207 192/192/192 +f 194/194/194 193/193/193 208/208/208 +f 208/208/208 209/209/209 194/194/194 +f 196/196/196 195/195/195 210/210/210 +f 210/210/210 211/211/211 196/196/196 +f 200/200/200 199/199/199 212/212/212 +f 212/212/212 213/213/213 200/200/200 +f 204/204/204 203/203/203 214/214/214 +f 214/214/214 215/215/215 204/204/204 +f 206/206/206 205/205/205 216/216/216 +f 216/216/216 217/217/217 206/206/206 +f 207/207/207 194/194/194 209/209/209 +f 209/209/209 218/218/218 207/207/207 +f 209/209/209 208/208/208 219/219/219 +f 219/219/219 220/220/220 209/209/209 +f 211/211/211 210/210/210 221/221/221 +f 221/221/221 222/222/222 211/211/211 +f 213/213/213 212/212/212 223/223/223 +f 223/223/223 224/224/224 213/213/213 +f 215/215/215 214/214/214 225/225/225 +f 225/225/225 226/226/226 215/215/215 +f 217/217/217 216/216/216 227/227/227 +f 227/227/227 228/228/228 217/217/217 +f 218/218/218 209/209/209 220/220/220 +f 220/220/220 229/229/229 218/218/218 +f 220/220/220 219/219/219 230/230/230 +f 230/230/230 231/231/231 220/220/220 +f 222/222/222 221/221/221 232/232/232 +f 232/232/232 233/233/233 222/222/222 +f 224/224/224 223/223/223 234/234/234 +f 234/234/234 235/235/235 224/224/224 +f 226/226/226 225/225/225 236/236/236 +f 236/236/236 237/237/237 226/226/226 +f 228/228/228 227/227/227 238/238/238 +f 238/238/238 239/239/239 228/228/228 +f 229/229/229 220/220/220 231/231/231 +f 231/231/231 240/240/240 229/229/229 +f 241/241/241 242/242/242 243/243/243 +f 241/241/241 244/244/244 242/242/242 +f 241/241/241 245/245/245 244/244/244 +f 241/241/241 246/246/246 245/245/245 +f 241/241/241 247/247/247 246/246/246 +f 241/241/241 243/243/243 247/247/247 +f 248/248/248 249/249/249 231/231/231 +f 248/248/248 231/231/231 230/230/230 +f 250/250/250 251/251/251 233/233/233 +f 250/250/250 233/233/233 232/232/232 +f 252/252/252 253/253/253 235/235/235 +f 252/252/252 235/235/235 234/234/234 +f 254/254/254 255/255/255 237/237/237 +f 254/254/254 237/237/237 236/236/236 +f 256/256/256 257/257/257 239/239/239 +f 256/256/256 239/239/239 238/238/238 +f 249/249/249 258/258/258 240/240/240 +f 249/249/249 240/240/240 231/231/231 +f 259/259/259 260/260/260 261/261/261 +f 261/261/261 262/262/262 259/259/259 +f 263/263/263 264/264/264 265/265/265 +f 265/265/265 266/266/266 263/263/263 +f 267/267/267 268/268/268 269/269/269 +f 269/269/269 270/270/270 267/267/267 +f 268/268/268 271/271/271 272/272/272 +f 272/272/272 269/269/269 268/268/268 +f 273/273/273 274/274/274 275/275/275 +f 275/275/275 276/276/276 273/273/273 +f 277/277/277 259/259/259 262/262/262 +f 262/262/262 278/278/278 277/277/277 +f 262/262/262 261/261/261 279/279/279 +f 279/279/279 280/280/280 262/262/262 +f 266/266/266 265/265/265 281/281/281 +f 281/281/281 282/282/282 266/266/266 +f 283/283/283 284/284/284 285/285/285 +f 285/285/285 286/286/286 283/283/283 +f 287/287/287 288/288/288 289/289/289 +f 289/289/289 290/290/290 287/287/287 +f 276/276/276 275/275/275 291/291/291 +f 291/291/291 292/292/292 276/276/276 +f 278/278/278 262/262/262 280/280/280 +f 280/280/280 293/293/293 278/278/278 +f 280/280/280 279/279/279 294/294/294 +f 294/294/294 295/295/295 280/280/280 +f 282/282/282 281/281/281 296/296/296 +f 296/296/296 297/297/297 282/282/282 +f 286/286/286 285/285/285 298/298/298 +f 298/298/298 299/299/299 286/286/286 +f 290/290/290 289/289/289 300/300/300 +f 300/300/300 301/301/301 290/290/290 +f 292/292/292 291/291/291 302/302/302 +f 302/302/302 303/303/303 292/292/292 +f 293/293/293 280/280/280 295/295/295 +f 295/295/295 304/304/304 293/293/293 +f 295/295/295 294/294/294 305/305/305 +f 305/305/305 306/306/306 295/295/295 +f 297/297/297 296/296/296 307/307/307 +f 307/307/307 308/308/308 297/297/297 +f 299/299/299 298/298/298 309/309/309 +f 309/309/309 310/310/310 299/299/299 +f 301/301/301 300/300/300 311/311/311 +f 311/311/311 312/312/312 301/301/301 +f 303/303/303 302/302/302 313/313/313 +f 313/313/313 314/314/314 303/303/303 +f 304/304/304 295/295/295 306/306/306 +f 306/306/306 315/315/315 304/304/304 +f 306/306/306 305/305/305 316/316/316 +f 316/316/316 317/317/317 306/306/306 +f 308/308/308 307/307/307 318/318/318 +f 318/318/318 319/319/319 308/308/308 +f 310/310/310 309/309/309 320/320/320 +f 320/320/320 321/321/321 310/310/310 +f 312/312/312 311/311/311 322/322/322 +f 322/322/322 323/323/323 312/312/312 +f 314/314/314 313/313/313 324/324/324 +f 324/324/324 325/325/325 314/314/314 +f 315/315/315 306/306/306 317/317/317 +f 317/317/317 326/326/326 315/315/315 +f 327/327/327 328/328/328 329/329/329 +f 327/327/327 330/330/330 328/328/328 +f 327/327/327 331/331/331 330/330/330 +f 327/327/327 332/332/332 331/331/331 +f 327/327/327 333/333/333 332/332/332 +f 327/327/327 329/329/329 333/333/333 +f 334/334/334 335/335/335 317/317/317 +f 334/334/334 317/317/317 316/316/316 +f 336/336/336 337/337/337 319/319/319 +f 336/336/336 319/319/319 318/318/318 +f 338/338/338 339/339/339 321/321/321 +f 338/338/338 321/321/321 320/320/320 +f 340/340/340 341/341/341 323/323/323 +f 340/340/340 323/323/323 322/322/322 +f 342/342/342 343/343/343 325/325/325 +f 342/342/342 325/325/325 324/324/324 +f 335/335/335 344/344/344 326/326/326 +f 335/335/335 326/326/326 317/317/317 +f 345/345/345 346/346/346 347/347/347 +f 345/345/345 348/348/348 346/346/346 +f 345/345/345 349/349/349 348/348/348 +f 345/345/345 350/350/350 349/349/349 +f 345/345/345 351/351/351 350/350/350 +f 345/345/345 352/352/352 351/351/351 +f 345/345/345 353/353/353 352/352/352 +f 345/345/345 347/347/347 353/353/353 +f 354/354/354 355/355/355 356/356/356 +f 354/354/354 356/356/356 357/357/357 +f 358/358/358 359/359/359 360/360/360 +f 358/358/358 360/360/360 361/361/361 +f 362/362/362 363/363/363 364/364/364 +f 362/362/362 364/364/364 365/365/365 +f 366/366/366 367/367/367 368/368/368 +f 366/366/366 368/368/368 369/369/369 +f 370/370/370 371/371/371 372/372/372 +f 370/370/370 372/372/372 373/373/373 +f 374/374/374 375/375/375 376/376/376 +f 374/374/374 376/376/376 377/377/377 +f 378/378/378 379/379/379 380/380/380 +f 378/378/378 380/380/380 381/381/381 +f 382/382/382 383/383/383 384/384/384 +f 382/382/382 384/384/384 385/385/385 +f 386/386/386 387/387/387 388/388/388 +f 386/386/386 388/388/388 389/389/389 +f 386/386/386 389/389/389 390/390/390 +f 386/386/386 390/390/390 391/391/391 +f 386/386/386 391/391/391 392/392/392 +f 386/386/386 392/392/392 393/393/393 +f 386/386/386 393/393/393 394/394/394 +f 386/386/386 394/394/394 387/387/387 +f 395/395/395 396/396/396 397/397/397 +f 397/397/397 398/398/398 395/395/395 +f 399/399/399 400/400/400 401/401/401 +f 401/401/401 402/402/402 399/399/399 +f 403/403/403 404/404/404 405/405/405 +f 405/405/405 406/406/406 403/403/403 +f 407/407/407 408/408/408 409/409/409 +f 409/409/409 410/410/410 407/407/407 +f 411/411/411 412/412/412 413/413/413 +f 413/413/413 414/414/414 411/411/411 +f 415/415/415 416/416/416 417/417/417 +f 417/417/417 418/418/418 415/415/415 +f 419/419/419 420/420/420 421/421/421 +f 421/421/421 422/422/422 419/419/419 +f 423/423/423 424/424/424 425/425/425 +f 425/425/425 426/426/426 423/423/423 +f 427/427/427 428/428/428 429/429/429 +f 429/429/429 430/430/430 427/427/427 +f 431/431/431 432/432/432 433/433/433 +f 433/433/433 434/434/434 431/431/431 +f 435/435/435 436/436/436 437/437/437 +f 437/437/437 438/438/438 435/435/435 +f 439/439/439 440/440/440 441/441/441 +f 441/441/441 442/442/442 439/439/439 +f 443/443/443 444/444/444 445/445/445 +f 445/445/445 446/446/446 443/443/443 +f 447/447/447 448/448/448 449/449/449 +f 449/449/449 450/450/450 447/447/447 +f 451/451/451 452/452/452 453/453/453 +f 453/453/453 454/454/454 451/451/451 +f 455/455/455 456/456/456 457/457/457 +f 457/457/457 458/458/458 455/455/455 +f 446/446/446 445/445/445 459/459/459 +f 459/459/459 460/460/460 446/446/446 +f 450/450/450 449/449/449 461/461/461 +f 461/461/461 462/462/462 450/450/450 +f 454/454/454 453/453/453 463/463/463 +f 463/463/463 464/464/464 454/454/454 +f 458/458/458 457/457/457 465/465/465 +f 465/465/465 466/466/466 458/458/458 +f 460/460/460 459/459/459 467/467/467 +f 467/467/467 468/468/468 460/460/460 +f 462/462/462 461/461/461 469/469/469 +f 469/469/469 470/470/470 462/462/462 +f 464/464/464 463/463/463 471/471/471 +f 471/471/471 472/472/472 464/464/464 +f 466/466/466 465/465/465 473/473/473 +f 473/473/473 474/474/474 466/466/466 +f 468/468/468 467/467/467 475/475/475 +f 475/475/475 476/476/476 468/468/468 +f 470/470/470 469/469/469 477/477/477 +f 477/477/477 478/478/478 470/470/470 +f 472/472/472 471/471/471 479/479/479 +f 479/479/479 480/480/480 472/472/472 +f 474/474/474 473/473/473 481/481/481 +f 481/481/481 482/482/482 474/474/474 +f 476/476/476 475/475/475 483/483/483 +f 483/483/483 484/484/484 476/476/476 +f 478/478/478 477/477/477 485/485/485 +f 485/485/485 486/486/486 478/478/478 +f 480/480/480 479/479/479 487/487/487 +f 487/487/487 488/488/488 480/480/480 +f 482/482/482 481/481/481 489/489/489 +f 489/489/489 490/490/490 482/482/482 +f 491/491/491 492/492/492 493/493/493 +f 493/493/493 494/494/494 491/491/491 +f 495/495/495 496/496/496 497/497/497 +f 497/497/497 498/498/498 495/495/495 +f 499/499/499 500/500/500 501/501/501 +f 501/501/501 502/502/502 499/499/499 +f 503/503/503 504/504/504 505/505/505 +f 505/505/505 506/506/506 503/503/503 +f 430/430/430 429/429/429 507/507/507 +f 507/507/507 508/508/508 430/430/430 +f 434/434/434 433/433/433 509/509/509 +f 509/509/509 510/510/510 434/434/434 +f 438/438/438 437/437/437 511/511/511 +f 511/511/511 512/512/512 438/438/438 +f 442/442/442 441/441/441 513/513/513 +f 513/513/513 514/514/514 442/442/442 +f 508/508/508 507/507/507 515/515/515 +f 515/515/515 516/516/516 508/508/508 +f 510/510/510 509/509/509 517/517/517 +f 517/517/517 518/518/518 510/510/510 +f 512/512/512 511/511/511 519/519/519 +f 519/519/519 520/520/520 512/512/512 +f 514/514/514 513/513/513 521/521/521 +f 521/521/521 522/522/522 514/514/514 +f 516/516/516 515/515/515 523/523/523 +f 523/523/523 524/524/524 516/516/516 +f 518/518/518 517/517/517 525/525/525 +f 525/525/525 526/526/526 518/518/518 +f 520/520/520 519/519/519 527/527/527 +f 527/527/527 528/528/528 520/520/520 +f 522/522/522 521/521/521 529/529/529 +f 529/529/529 530/530/530 522/522/522 +f 531/531/531 532/532/532 533/533/533 +f 533/533/533 534/534/534 531/531/531 +f 535/535/535 536/536/536 537/537/537 +f 537/537/537 538/538/538 535/535/535 +f 539/539/539 540/540/540 541/541/541 +f 541/541/541 542/542/542 539/539/539 +f 543/543/543 544/544/544 545/545/545 +f 545/545/545 546/546/546 543/543/543 +f 547/547/547 548/548/548 549/549/549 +f 549/549/549 550/550/550 547/547/547 +f 551/551/551 552/552/552 553/553/553 +f 553/553/553 554/554/554 551/551/551 +f 555/555/555 556/556/556 557/557/557 +f 557/557/557 558/558/558 555/555/555 +f 559/559/559 560/560/560 561/561/561 +f 561/561/561 562/562/562 559/559/559 +f 563/563/563 564/564/564 565/565/565 +f 565/565/565 566/566/566 563/563/563 +f 567/567/567 568/568/568 569/569/569 +f 569/569/569 570/570/570 567/567/567 +f 571/571/571 572/572/572 573/573/573 +f 573/573/573 574/574/574 571/571/571 +f 575/575/575 571/571/571 574/574/574 +f 574/574/574 576/576/576 575/575/575 +f 577/577/577 575/575/575 576/576/576 +f 576/576/576 578/578/578 577/577/577 +f 579/579/579 577/577/577 578/578/578 +f 578/578/578 580/580/580 579/579/579 +f 581/581/581 579/579/579 580/580/580 +f 580/580/580 582/582/582 581/581/581 +f 583/583/583 581/581/581 582/582/582 +f 582/582/582 584/584/584 583/583/583 +f 585/585/585 583/583/583 584/584/584 +f 584/584/584 586/586/586 585/585/585 +f 587/587/587 585/585/585 586/586/586 +f 586/586/586 588/588/588 587/587/587 +f 589/589/589 587/587/587 588/588/588 +f 588/588/588 590/590/590 589/589/589 +f 572/572/572 589/589/589 590/590/590 +f 590/590/590 573/573/573 572/572/572 +f 591/591/591 592/592/592 572/572/572 +f 572/572/572 571/571/571 591/591/591 +f 593/593/593 591/591/591 571/571/571 +f 571/571/571 575/575/575 593/593/593 +f 594/594/594 593/593/593 575/575/575 +f 575/575/575 577/577/577 594/594/594 +f 595/595/595 594/594/594 577/577/577 +f 577/577/577 579/579/579 595/595/595 +f 596/596/596 595/595/595 579/579/579 +f 579/579/579 581/581/581 596/596/596 +f 597/597/597 596/596/596 581/581/581 +f 581/581/581 583/583/583 597/597/597 +f 598/598/598 597/597/597 583/583/583 +f 583/583/583 585/585/585 598/598/598 +f 599/599/599 598/598/598 585/585/585 +f 585/585/585 587/587/587 599/599/599 +f 600/600/600 599/599/599 587/587/587 +f 587/587/587 589/589/589 600/600/600 +f 592/592/592 600/600/600 589/589/589 +f 589/589/589 572/572/572 592/592/592 +f 601/601/601 602/602/602 603/603/603 +f 603/603/603 604/604/604 601/601/601 +f 605/605/605 606/606/606 607/607/607 +f 607/607/607 608/608/608 605/605/605 +f 609/609/609 610/610/610 611/611/611 +f 611/611/611 612/612/612 609/609/609 +f 613/613/613 614/614/614 615/615/615 +f 615/615/615 616/616/616 613/613/613 +f 617/617/617 618/618/618 619/619/619 +f 619/619/619 620/620/620 617/617/617 +f 621/621/621 622/622/622 623/623/623 +f 623/623/623 624/624/624 621/621/621 +f 625/625/625 626/626/626 627/627/627 +f 627/627/627 628/628/628 625/625/625 +f 629/629/629 630/630/630 631/631/631 +f 631/631/631 632/632/632 629/629/629 +f 633/633/633 634/634/634 635/635/635 +f 635/635/635 636/636/636 633/633/633 +f 637/637/637 638/638/638 639/639/639 +f 639/639/639 640/640/640 637/637/637 +f 641/641/641 642/642/642 643/643/643 +f 643/643/643 644/644/644 641/641/641 +f 645/645/645 646/646/646 647/647/647 +f 647/647/647 648/648/648 645/645/645 +f 649/649/649 650/650/650 651/651/651 +f 651/651/651 652/652/652 649/649/649 +f 653/653/653 654/654/654 655/655/655 +f 655/655/655 656/656/656 653/653/653 +f 657/657/657 658/658/658 659/659/659 +f 659/659/659 660/660/660 657/657/657 +f 661/661/661 662/662/662 663/663/663 +f 663/663/663 664/664/664 661/661/661 +f 665/665/665 666/666/666 667/667/667 +f 667/667/667 668/668/668 665/665/665 +f 669/669/669 670/670/670 671/671/671 +f 671/671/671 672/672/672 669/669/669 +f 673/673/673 674/674/674 675/675/675 +f 675/675/675 676/676/676 673/673/673 +f 677/677/677 678/678/678 679/679/679 +f 679/679/679 680/680/680 677/677/677 +f 681/681/681 682/682/682 683/683/683 +f 683/683/683 684/684/684 681/681/681 +f 685/685/685 686/686/686 687/687/687 +f 687/687/687 688/688/688 685/685/685 +f 689/689/689 690/690/690 691/691/691 +f 691/691/691 692/692/692 689/689/689 +f 693/693/693 694/694/694 695/695/695 +f 695/695/695 696/696/696 693/693/693 +f 697/697/697 698/698/698 699/699/699 +f 699/699/699 700/700/700 697/697/697 +f 701/701/701 702/702/702 703/703/703 +f 703/703/703 704/704/704 701/701/701 +f 705/705/705 706/706/706 707/707/707 +f 707/707/707 708/708/708 705/705/705 +f 709/709/709 710/710/710 711/711/711 +f 711/711/711 712/712/712 709/709/709 +f 713/713/713 714/714/714 715/715/715 +f 715/715/715 716/716/716 713/713/713 +f 717/717/717 718/718/718 719/719/719 +f 719/719/719 720/720/720 717/717/717 +f 721/721/721 722/722/722 723/723/723 +f 723/723/723 724/724/724 721/721/721 +f 725/725/725 726/726/726 727/727/727 +f 727/727/727 728/728/728 725/725/725 +f 729/729/729 730/730/730 731/731/731 +f 731/731/731 732/732/732 729/729/729 +f 733/733/733 734/734/734 735/735/735 +f 735/735/735 736/736/736 733/733/733 +f 737/737/737 738/738/738 739/739/739 +f 739/739/739 740/740/740 737/737/737 +f 741/741/741 742/742/742 743/743/743 +f 743/743/743 744/744/744 741/741/741 +f 745/745/745 746/746/746 747/747/747 +f 747/747/747 748/748/748 745/745/745 +f 749/749/749 750/750/750 751/751/751 +f 751/751/751 752/752/752 749/749/749 +f 753/753/753 754/754/754 755/755/755 +f 755/755/755 756/756/756 753/753/753 +f 757/757/757 758/758/758 759/759/759 +f 759/759/759 760/760/760 757/757/757 +f 761/761/761 762/762/762 763/763/763 +f 763/763/763 764/764/764 761/761/761 +f 765/765/765 766/766/766 767/767/767 +f 767/767/767 768/768/768 765/765/765 +f 769/769/769 770/770/770 771/771/771 +f 771/771/771 772/772/772 769/769/769 +f 773/773/773 774/774/774 775/775/775 +f 775/775/775 776/776/776 773/773/773 +f 777/777/777 778/778/778 779/779/779 +f 779/779/779 780/780/780 777/777/777 +f 781/781/781 782/782/782 783/783/783 +f 783/783/783 784/784/784 781/781/781 +f 785/785/785 786/786/786 787/787/787 +f 787/787/787 788/788/788 785/785/785 +f 789/789/789 790/790/790 791/791/791 +f 791/791/791 792/792/792 789/789/789 +f 793/793/793 794/794/794 795/795/795 +f 795/795/795 796/796/796 793/793/793 +f 797/797/797 798/798/798 799/799/799 +f 799/799/799 800/800/800 797/797/797 +f 801/801/801 802/802/802 803/803/803 +f 803/803/803 804/804/804 801/801/801 +f 805/805/805 806/806/806 807/807/807 +f 807/807/807 808/808/808 805/805/805 +f 809/809/809 810/810/810 811/811/811 +f 811/811/811 812/812/812 809/809/809 +f 813/813/813 814/814/814 815/815/815 +f 815/815/815 816/816/816 813/813/813 +f 817/817/817 818/818/818 819/819/819 +f 819/819/819 820/820/820 817/817/817 +f 821/821/821 822/822/822 823/823/823 +f 823/823/823 824/824/824 821/821/821 +f 825/825/825 826/826/826 827/827/827 +f 827/827/827 828/828/828 825/825/825 +f 829/829/829 830/830/830 831/831/831 +f 831/831/831 832/832/832 829/829/829 +f 833/833/833 834/834/834 835/835/835 +f 835/835/835 836/836/836 833/833/833 +f 837/837/837 838/838/838 839/839/839 +f 839/839/839 840/840/840 837/837/837 +f 841/841/841 842/842/842 843/843/843 +f 843/843/843 844/844/844 841/841/841 +f 845/845/845 846/846/846 847/847/847 +f 847/847/847 848/848/848 845/845/845 +f 849/849/849 850/850/850 851/851/851 +f 851/851/851 852/852/852 849/849/849 +f 853/853/853 854/854/854 855/855/855 +f 855/855/855 856/856/856 853/853/853 +f 857/857/857 858/858/858 859/859/859 +f 859/859/859 860/860/860 857/857/857 +f 861/861/861 862/862/862 863/863/863 +f 863/863/863 864/864/864 861/861/861 +f 865/865/865 866/866/866 867/867/867 +f 867/867/867 868/868/868 865/865/865 +f 869/869/869 870/870/870 871/871/871 +f 871/871/871 872/872/872 869/869/869 +f 873/873/873 874/874/874 875/875/875 +f 875/875/875 876/876/876 873/873/873 +f 877/877/877 878/878/878 879/879/879 +f 879/879/879 880/880/880 877/877/877 +f 881/881/881 882/882/882 883/883/883 +f 881/881/881 883/883/883 884/884/884 +f 885/885/885 881/881/881 884/884/884 +f 885/885/885 884/884/884 886/886/886 +f 887/887/887 885/885/885 886/886/886 +f 887/887/887 886/886/886 888/888/888 +f 889/889/889 887/887/887 888/888/888 +f 889/889/889 888/888/888 890/890/890 +f 891/891/891 889/889/889 890/890/890 +f 891/891/891 890/890/890 892/892/892 +f 893/893/893 891/891/891 892/892/892 +f 893/893/893 892/892/892 894/894/894 +f 895/895/895 893/893/893 894/894/894 +f 895/895/895 894/894/894 896/896/896 +f 897/897/897 895/895/895 896/896/896 +f 897/897/897 896/896/896 898/898/898 +f 899/899/899 900/900/900 901/901/901 +f 899/899/899 901/901/901 902/902/902 +f 882/882/882 899/899/899 902/902/902 +f 882/882/882 902/902/902 883/883/883 +f 903/903/903 904/904/904 882/882/882 +f 903/903/903 882/882/882 881/881/881 +f 905/905/905 903/903/903 881/881/881 +f 905/905/905 881/881/881 885/885/885 +f 906/906/906 905/905/905 885/885/885 +f 906/906/906 885/885/885 887/887/887 +f 907/907/907 906/906/906 887/887/887 +f 907/907/907 887/887/887 889/889/889 +f 908/908/908 907/907/907 889/889/889 +f 908/908/908 889/889/889 891/891/891 +f 909/909/909 908/908/908 891/891/891 +f 909/909/909 891/891/891 893/893/893 +f 910/910/910 909/909/909 893/893/893 +f 910/910/910 893/893/893 895/895/895 +f 911/911/911 910/910/910 895/895/895 +f 911/911/911 895/895/895 897/897/897 +f 912/912/912 913/913/913 900/900/900 +f 912/912/912 900/900/900 899/899/899 +f 904/904/904 912/912/912 899/899/899 +f 904/904/904 899/899/899 882/882/882 +f 914/914/914 915/915/915 904/904/904 +f 914/914/914 904/904/904 903/903/903 +f 916/916/916 914/914/914 903/903/903 +f 916/916/916 903/903/903 905/905/905 +f 917/917/917 916/916/916 905/905/905 +f 917/917/917 905/905/905 906/906/906 +f 918/918/918 917/917/917 906/906/906 +f 918/918/918 906/906/906 907/907/907 +f 919/919/919 918/918/918 907/907/907 +f 919/919/919 907/907/907 908/908/908 +f 920/920/920 919/919/919 908/908/908 +f 920/920/920 908/908/908 909/909/909 +f 921/921/921 920/920/920 909/909/909 +f 921/921/921 909/909/909 910/910/910 +f 922/922/922 921/921/921 910/910/910 +f 922/922/922 910/910/910 911/911/911 +f 923/923/923 924/924/924 913/913/913 +f 923/923/923 913/913/913 912/912/912 +f 915/915/915 923/923/923 912/912/912 +f 915/915/915 912/912/912 904/904/904 +f 925/925/925 926/926/926 915/915/915 +f 925/925/925 915/915/915 914/914/914 +f 927/927/927 925/925/925 914/914/914 +f 927/927/927 914/914/914 916/916/916 +f 928/928/928 927/927/927 916/916/916 +f 928/928/928 916/916/916 917/917/917 +f 929/929/929 928/928/928 917/917/917 +f 929/929/929 917/917/917 918/918/918 +f 930/930/930 929/929/929 918/918/918 +f 930/930/930 918/918/918 919/919/919 +f 931/931/931 930/930/930 919/919/919 +f 931/931/931 919/919/919 920/920/920 +f 932/932/932 931/931/931 920/920/920 +f 932/932/932 920/920/920 921/921/921 +f 933/933/933 932/932/932 921/921/921 +f 933/933/933 921/921/921 922/922/922 +f 934/934/934 935/935/935 924/924/924 +f 934/934/934 924/924/924 923/923/923 +f 926/926/926 934/934/934 923/923/923 +f 926/926/926 923/923/923 915/915/915 +f 936/936/936 937/937/937 926/926/926 +f 936/936/936 926/926/926 925/925/925 +f 938/938/938 936/936/936 925/925/925 +f 938/938/938 925/925/925 927/927/927 +f 939/939/939 938/938/938 927/927/927 +f 939/939/939 927/927/927 928/928/928 +f 940/940/940 939/939/939 928/928/928 +f 940/940/940 928/928/928 929/929/929 +f 941/941/941 940/940/940 929/929/929 +f 941/941/941 929/929/929 930/930/930 +f 942/942/942 941/941/941 930/930/930 +f 942/942/942 930/930/930 931/931/931 +f 943/943/943 942/942/942 931/931/931 +f 943/943/943 931/931/931 932/932/932 +f 944/944/944 943/943/943 932/932/932 +f 944/944/944 932/932/932 933/933/933 +f 945/945/945 946/946/946 935/935/935 +f 945/945/945 935/935/935 934/934/934 +f 937/937/937 945/945/945 934/934/934 +f 937/937/937 934/934/934 926/926/926 diff --git a/glut64.dll b/glut64.dll new file mode 100644 index 0000000000000000000000000000000000000000..5df6d9885c753c5a8132c604d7677131f0704b56 GIT binary patch literal 272896 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 G;J*P491%kR literal 0 HcmV?d00001 diff --git a/heightfield128x128.raw b/heightfield128x128.raw new file mode 100644 index 0000000..21656bb --- /dev/null +++ b/heightfield128x128.raw @@ -0,0 +1,37 @@ +ˆ}u]OYQC=104?KNXo~‚tmqvŽ¡¹ÆÆÅÌÈ¿¾µ¦u`V_cV;4102238CFIO[go}„‹£¹ÆÏÏ¿©—†r`]]Y]]QD=5+!"+5FE=968AAK]irn|“®ºÆÒåéòûúïåÜ̵žœž¥Ÿžœvy|…‚weYSSE:,-6@IFPfyyifjrŽœ®ÅÌÉž»»²Ÿƒi\TceS8-%#&%.G^sƒ—ª±·ÁÏÞÛ˹§Žvqttsh\ZTLC;49DIRSF>52449:?Jex† ¯ÅÒàææããàØÌ»­œ–’ŠŠyt‚u²œ‹xiYOC?KORm|x€zƒ‹’ž§µ¼¾¹²®¤ŽlWJSljWB/#',162-6CVl|”¬ºÅÊÑÜÜÊ°¡˜‘‹‘€ohlocQG;8?FROD=2284**:Lgt}¤²ÅÊÕÛßÕÓÑÌÁ°©«¦™†ŠƒŠ|x‡„ȳ¢ ›‡k^UMN_km}‹‘Œ„Œ‘’–¡¬·±«©ˆjULPb`T>% %(('(,5DP\q“¯ÀÌÐÕ×Ò¼¤ž£§¡›š•‹}€qTF8.0;6,+'""(-,,0:F@>AGO]o€‘­ÂÏ×ÑÌÉÁ´¶ÇÐÉþ·¯Ÿ‹}jP;,%! +:ALLKOU^krr‡Ÿª®©žys~•¡´º¾µº¾¿ËÓÜÔÀ¢ôôôïåÚÑ××Ð×ϼ¦—„mXXdg^Q[R>6329CE6*+*+)(#"!##'-5>IONHBGQj‡ž­¼ÄÍÌÊʼ´¸ÆÎÈÊȾª‚yiM6(## +?Nfƒ™¨·ÁÊÁ·µ±­°¿ÇÀÅËÁ¯ŽzucC+#$$!%4CGFFO`kmgdduƒ—¡”‡†€…‹—«´¸»ºÁÁÏÕÚØÏ»¯ûûúüûîçäààÞ̲Ÿ“yhWRORM:76(""$!&"!# %/1389DNQTLA>AWo†™¤®¸²²²¦¡¤¯µ­°·µ¦…qiW?+$%##$).?HEFNehffebsˆ”‘ƒ…‡›˜ª·¼¹ÄÏÏÓÑÓÐ̼³üÿýýü÷öñëåÚħ™€iWMOIA.&$ &-49?>CVbZPE=AGO^aghkmpxz|rou‰“¥¬¤¢­¾ÑÜ×ÎÁ±¬°®ìõùöó÷üöìØË·¥š™“qO;20*#  + (2?GP_noi_XZ]nvrx€ž ›­ÌÖÑÉÿ»°ž–“‡rk]L9##(.:@BIU[^qsmipwz~}vot~…’Ÿ¨¨«²ÂÔÜÐǺ¯œ£ãñôñêòöôåÏŵ¦›˜…mG0*# #+6DIRciid^bgqzvx†“Ÿ¡¤¼ØäæâÚÕÏɳ–Ž‰yi]RE-#,9CJJLTVZmppt~yyxrjir}Š›¥¯§¯ÃÎÕÏÀ¨›‡…ŠÍäêæàåæßÑËÀ´¤˜“~^C2!  ##(+07ARac\^cnzŠ’”“ž¨·ÊßèéëìåßÖ½œŒƒxl`RJ6 +1@GF;7:DLT[kpnpsund]cjl~”°¶¯²®¡Ž~wtoh¢¡®°¼º°¬¬£ª¡|vqeG*  +&8;1,/;JP[jqpt•§©ªª¯¶¯«·ÅÌÕÞÞÞáÚË°šŽˆˆrWHD7&#.78;=@B>658DIJY[dqpfhd^f`_i€› ¤Ÿ‚tikopŒ‹–›Ÿ¤œ™•…Ž‡vc^ZM;#  %4:979?O]`fnq}ŽŸ°·²­®©©¯¸ÄÒÙÛÛÚÚÒ¿«š“‘…~mVLF9.-16>?CFDDLKE?7:@BNRWa`emk^bZXYpŠ‘•‰vupjgi|x…€…Š†„zmabaTJE=9#  + + + (4<7GJJJKGFQSPD9?CGAIS]`jo_URMRVat…’tpefjuxw~yxx}|vshVLNPIA?=9$    "6B=AKRY^gqx…—±ÃÊÎĪ £«ÀÎÎÌÏØÜÍ¿³¬¦‘|ptnSA8;DMTY^\TTU[[ZM=DLOKV_a^bZQECIMONZu‡whgddnplqwpqt{ypj\KFA?:59;6$ %$)39?JTYVX^en ¼ÄÌÖÒ¿²«°ÄÎÐÍÌÛàÕÁ®•…ulnoYD64AO\gkhc]cjoiYDDNTZ^__QKHF<;AJNJ\jri]cjjpjaikhemxsujRBB=5-,.8>,!#-2/*+-10$".03AKNPKOY]g‚¡»ÂÐáàÓdz¬ºÄÊÑÔÖÖϲ™“”‡qimf]O?:HWdrvumkqolkXJOUWa[U[JFC>::=IEGXeqnhqmntrfc[XTYelniPG<91*,*387+%2<;5234981)#!!,206CONE?ALQ\v—°¼ËÜàÙÒ¿®­ºÃËÕÐÌÆ»«š’„posj]QHKbszƒ„Š†~xwvm^RXZ^`ROOJG@56AEFVbmbNB:81)*146>9++.-2DD96424:9872.-398?MXP>9?BGZu‘§²½Í×ØѲ­µ¼ÈÎÄÀÅ»¯›†uorj^SVbt‹“Ž“–‡‚‚}g][\fc[YRPOE13;ENT]\Q?6;=1)-;MUO@:@IVXX]VL=4435NqŸ¬¯¹¼°±¸»º¹¼ÀÄÄƾ°­¨¡ ˆyokegyš¬®¦œ‘™œ˜››‹vwwtxƒˆ~sab^\e]bf_[ZaT\fn{xok]Q(5:FVWSRNSOMDCJSSQOWU[ZZQKGFD83@QPOJEOV]Z`\QA620.0Gi†–Ÿ¦®©›’ž´»¹··¼ÁÀ²ª°µ´²¥—ƒ}{|Ž­º¶³«¡›œ¢§¡’‹€ƒˆ™—ˆqnkh_[ffbWQ\bifhnha_ZM$+8BCMW[TSWSLEJRVQUW]akaVXURQRJAJURONNVX\Y^bT@3322;Ni}†™˜’ˆ€Ž¤®¯««µ¸±¯®±µ¸µ§–”••™¢¸ÉÊÆ»µ š£¬§œ•Œ~‚Œš¡£˜‹{~xkZ^hf^XWcwp``]YTPUQ27?EJU\[W\``ZNNV_]`ceim__gjii`_XW]^XWZ``_^YXUOEFB=KZiux}}y{‚‚‰š¥¦¢§°±®°°¬«°ª¡œ˜™£©«¯½ÑÛâÙÊ®˜“›™‡€}}Œ’›¥ œŒ„‚zmph^^fot‹‚h[PPNNUP?DIO]e`aefjjhZLO]kmoljgkty…†~xg`bfb_cec]YJGIKKPMCJ^ikilifp€ƒ…–›˜˜£««© šž¢ š›Ÿ£±¾ÄËØäêèÖÁ¤•Žv€‡Ž‹Šœ«²¹© ™|qg^grvyw]IELYRRHHS[ipfquntmncRJYjqrslfvŠŽ“–˜Ž€oefjc_bXJA866J[nqk\R[gv„‰‰‰‘’†€Ž––›Ÿ°ÉÞæåêõóòéÕÁ§Žˆ‰“Ÿ¢¦®§§¬·¼»½¸¯¦…ldXKRS]s……{u~njffkz‚‹ŒŠ–•ƒugSJRW\aklkw|Š“¢¯º±ŸwjfkhWE8,""''-3006849BR`a`[RQ_wŒ”ŠŽ™–“‡y~‰¦¬ÄÖÛÜçôøñçʸ¥„†—¥©«¬¨ª±¶¿Åľµ¦|mdSJFUm‚€}||wyx\h‡•ŠˆŒ–ž›‰ql]MAFGQX\]kt•©¸Æ½«šŠ}qjcSFC1#"" "$+1.48604CNRRQPOZrˆ•”™¤Ÿ~njvžŸ£µËÕ×ãñ÷íÝ̽©•ŒŠ™©¬¤ ©¯´¹»ÄÄÇÆ·¥m\NN^n{{|}‰T^{‰’“•–œ¡zoreUIA=FMOTgu‡š³ÂÇż¬ ’|nbRLH6" $+-475106;@?@EHWnƒ“–œ¥Ÿˆwqgp‹—™¢²ÅÓÜæïòèÒÉø¦¥¡¤´®Ÿœ«²¯³¸ÅÆÇɽª’…w\RS`r|ˆƒ~y‚–`ezš¤¯«ž›™†zynm`OFCIJJP`|—¦»ÆÉÐÍÅ´œ€scUTL<,$"#,104;;6:;9;@EC?F½±¥–ŒˆŠˆŒ†ƒ•”œŸœ¢¨§«ÃÖÕÑÏÕßÜÙÎÎÌÏÓÔȱxme\O<7119?6.+))*,.009KZ``fmvƒ†zux{}¤£¦¸¹±²´®¦¨§¤›———‡wqz†‰ƒ†Ž’•šxp_XbYI:;@@:<:;BD?<½®¨šŠ~uz„ƒ~‡”Ÿ›¤©±¶½ÓÛÚ×ÏÐÜåçÜÙØÒÕÖɬyhYJA;3/2>@6.*'&$%*.2>S`dcer{xvzwuxƒ†š­±´´½Á»¸¹²¦˜› ¢ —ŽŠ‚ƒ“Ž‹‡‰‰{gd^WZUL>?>CDEEB@AA9°¨¦”€qq{yy~˜¤§¶¾ÄÊÐÞçæáÜÛâíòêáÙÑÖ̸™…vdQ@84--8>;4,(%! '/8CTiupmq|‡~rpptz‰‘¨¿ÂÊÎÌȾ²¯¯©˜–™ž¨¤“’–¦Ÿ›‘‡‚…zkXITVXOJ?DBKMNOMC?=9ª¦¥£œƒxs}xy€œ¨´ÁÈÑÕØãçìîììñõóìâÜÔÌ»©˜…ycG9/(#(7B:1,&$#(08GVk†‚‹‚oefo~‘™³ÉÎÓÚ×ÌÁ´ª©§™•›Ÿ¦£šŸ¡¨®¨§”ƒ{xgWE:DPUQMFEEOSSXVNGCEµ´°­ ƒy|„ˆˆŠ‘¦­»ÉÏÕØáéèñ÷ôó÷óëåÝÜØÊ°¡™†zb=.*%&&2B=53/+*1:FWgz‰˜š”Œ†‚vgeu‡‘›¨½ÐÙ×ÕÎĽ¼±¦¡•‘¡¥§¯²¬«¯·­¢¤—†vk]O>92/))&2DF;;;717BOd}‘ ©®¦–†~xnm|‡‹–¨ÁØÞÖÍÁ¶¶»¸¯¨œš¦«±¼º²®¹»®›”˜ŠxbXVJCDGPZUUZPLS]^PDKNX¹Èȳ¦‰…‹”””›«¾ÍÙÚÙáñïïõôéìèÙ×ÕÛÙDz–‡sWG;63-('7LM;48>:=IVlŽ§´µ¸¾²¡—Š„yqr|ƒ‰–®ÇÔÑɶ­¯°½À»­®»¾À¼±­©°·­–”‹w^SRRMKV][TZfeZWYXLELRXª·Ãƾ°™‰‡ˆ‡‘š«¸Ç×åæéñðïñìÞÜÚÌËÈËÌ¿­“v\G=772.+-:NN=36>=>N`xš±ÀÇÈô§›•‹vlou{‚‘ªÀÅ÷­ª±¼ÄÇÂÈÏÒм¥™œ§ª¤™‡}m_QLQ[^hifbgnvhZUTQOUYZ­¯´¹µªž…€‚”¨°ºÍáðõõöõðìä×ÑÎÁ¼¼Âǹ¢ZG:5350002>OQLDABDJ^u‡œ°ÄÊÅ·©šŒ‹†|vsqrx€‚•¯ºÀÀµ°¸¿ÈËÐÒÑÕÒº¤˜Œ™£¢~l\YRKOcpmhnqr{yhYXYTY\`dú®¨¢˜‹~u|‚—«¯½Îçô÷öôöðçÚÓÎÆ¿¸ºÅÅ­’kJ<5-)'&-6=EOVWOOSY_u‹’™¬ÀĶ¨‰„}{xyunr€…™³¾½µ´¿ÀÅÅËÌÈÇõª¢Œ–“‰yeRVVPSjwnfnw||l^aZRVXjoÎö¢““‘ƒyos™©±½ÏãïòðïóêÝÊÉÅ»¼»¿Á¾žxXD0+%!+@JLT[]YY]ir‡œ¢¢ª¸Ã·§ž“‡vrtxwrr}ƒ~ˆ¢¬°³´¹·´¹»¾½¹°ª§Ÿ“ˆ€‚ƒ€o]U^XZhx~~ywz€‚}ug_PNMUqpÇ·¡Š…†}utu–©±¼ÐØáæîðìáÓÅÈÇÁ¾¾½¹´—kP>,$$.=LYbfijiqˆ—ª°¯±ºÄ­œŽxpkktvv{}‚†|Š–¥°°«¥«±²¦˜•š—•‹wnof]UZc^dv{‡‰†‰Žzn^QGIPWmp¹²­¥”€}€ƒ‹™ ©´ÂÆÐÝìóíßÏÄÇËÌÈ¿»³ª’nUE4&)29J_hgmv€Ž”—¡­´·º¿Äų–‚m]^iqmhu„{uw{‡—§¦—‹‘ž¨ª—„†‘˜˜€scRR]glhemxŠ™ƒ‡t]JDCIU_pj¢•˜¡‰Œ‰‰‰‡Ÿž£¯±´ÁÕâîëÛƾ½ÃÈÆ¿¼±¤‘vcVE/+18FU_gmw†–Ÿ¡¦ª­®±³¸¿³—~iRP]d\S_prtolpw†ŒŒ~€Š”¡˜€€Ž”’ŽŠiTXiqsne`tŠ“’ŠshmdKDJ[mwrou~†‹“ˆ}}‹Œ•Ÿ£«¸ÇÔÚÜÑƽ»±±Ã¿º²¢Š}ujY8))127?CTdjy‚ˆ”š“˜››£ª¨«¬qP<9<=91>Ykkgehec`]Y]hs~‡~~‡‹†|pkcflhjwworz}zl^QB8458DZq}|]eŽˆŒŽ}mp|…Ž’•š§¸ÊÖÒÐËù¶¸¿º³§•„}uthJ3.9<>FLSafw‡—–“–•¥´¶®¦™…a=./121.9Sbfb\ROWXPIK[jdcgqxvsutttupeYWees„wwtoi]IJFA86F_r{VWr‹‘‹†‚n\`lx„“™¬ºÂº¿Ãº¦©´°¯§›‹†„nX?6>AAJW]enŽ‘‹‹“›¬¶·°¢˜€\>005534:@NZXQFHNNGA=?@K[msx‡‘“’ŽŠ†Œ™©´·±¡‘qTF=::720/081+-.17>>843-!#)./.489@CJTSJGWksxƒ†˜ ª¯­¡“||we\TPLUYZ\dBSdo„ƒkO:=EVn}|‡Š„{ŠŠˆ…{mdcgkxqmp|…‚wbPLIGS^femzvy‚‰‡„Œ—¦¯¦vbXOCFA96240**+&$$$" *50/4BVZVUer|”™©¯®»¸¨›‰Œˆo`RIGIPZ]d?LVcy~|p\JAKXm}„„}~…ƒ„ƒ€teXQPU^ZVYcw€}m`YTV[\`]aq{vutu}}€‡Š—Ÿš‰viXMGD>9><60%#./'-?TZ]_m‡Š›©´³µ½¹ª–‹€€iVGD@@IY]`=JUanfkgdUCHRcuƒƒyƒŒ„…‚uhXODEHGKLPSas}rkjddkigc^eywmc\ivƒ|ƒ’ŽqhWKJKH@EB8/' '+$*CX\`jt’—˜¥»Ã¼¾¹´§}pjm^F?<8;DTYa;FVaaW\dcTLFMYn|Œ”ŽƒzhXLKIIB74>ISYb:AO[STU\^[YOVZo|ŒŠ‰~uobMAEPO=8@FHJHLYnyzy€€{ofgoxxpjt}~|xtssn`ZYY\\]WKH7(#!%!!'-/:BMZahvv~•£¸ÆÅ÷¬®šƒskgXWKD<7DKP]b>GGKGMMN[`aac`s‡ŽŽ}th]M>CKH?7=C=;9BPe{Š‹‡zpfgv‡ŒŠ‰ˆ‰€|tf^_c_VX^cc\TKF8'"""%%(*/-*+00=>CKZdchhcy’”œ•}zk[SJFC?>9:?64;CVk›© ”Š}umsŠœ¡Ÿ˜’pmaTSW[Z[bbdcYQG8*'.+" !(*+.320/17>@FQ]fibY^lx~œ²¸²©¨Ÿ‰yaMITYVMSQLORd~AGC?<;FSbjiidj”™šž •{vi^YMD>;713/0:I_o—¥¢œ–…yux¦­ª¡—‚siYLINZbhrqkig_SH;8;40.(,63684028DLNPbmmmjajigj€­±¦ž„zcPOPPKGKKGJPnGEC<;HV_bdmg[hwŽš›¤œ“‚uy|riXL@7,'&$'7N`l{’œ˜‰|t€–®»´¤„‚udYOKNVanz€|sppgVLOKHE=2,349?>:?AFHHSq}nnxz{tkk{¢¨•‰€qhYRNJDGGH??>GZ_aclmaR[_yŠ‘›š’€w}~ri_N=/%! 2Ofov‰Ž‡†€zŒ¡³¿· ˆ}yk\XVURYbm{„‰…}}saY_\WUN>114;HPKLFEDJ[x…}w„…zzywuˆ˜—•†wmlbPONRPMI;5Fhy;:=GVacelqdWMNPc}”š¡›…†‚vleX@8/+ -Gemn~„‚ƒ‹‡ƒ’¤·¼¯œ‘…~t_W\_Z`l{‡Ž‘Ž†yrkhge_WL?8?N][Vgyƒ†Š…z…ymZL7*" !)4IVfkls‡Ÿµ³ŸžŸ¢¶Ã¶¢£«§œ“–‰‡ƒƒ‰‘››’’…Š’“‰xl[LKRfyŠ’‡…††„ywsivuyxh\WYahoz„…Ž“”œ˜‚geffkgkoa\2-'!#)/9JYddt€ˆ†|ndcikfleVB,$ $')0=CIFET^USNC:31.--.4@JXk{||z{‚‰’•ŽŠ‹“˜‘˜–”™§®°·³©¥ž–˜¡¡¤§¦¨­³­ž˜ ««³µºÆÄ·ªŸ‰{phqkbbuynrƒ‘‘‰‚ttt}†Ž”–™†„}|ƒ~E7$""$,@IIBBD=756:AJNIJFMJG:)**%&/7>E]t€‡„€ƒ~{…‹„|‡ž¦™“š–•¦¬ªª«¦œ•‡‚Œ––™¢§°º»ª›¡«ª©²½À»°ž’vm`aeahs{y~Œ—˜˜‰qnow„ˆšŸ™ŽŒ””‡E4'*(!&6<91.30/*./6=IFC?DJJA,++''+37A]t€›™‘Œ‡‚|vxyƒ—¤§™’Š–¥©§£¥¤—€zˆ—•–¢¦­¿Å² ž¨¨§±¸¹¸¬ž|pdYV`[gr}†‡Ž’•šƒigiou€ƒ‹ž«£ž–œŸ˜‹G=73.)$#'(--&&'&'#(*/0?AA@@FF?2*+&&)08Har“œž—‘ƒvru|Š”œˆŒ“—¥§¢¡ ˜„‚—™¢¬§ª¹À´¦£¥ª¨­³¹¶£š~j\TT[\cn~Š‘•‹‰ydZZ^bp…Ž›­°µµ®¥ž“SOK=1/+#'('$#!")-/:>KXkz††……yu|€ˆ‘’Œ‚”¢š’œ¢Ÿœœ™‹’œ©´¶¨©¶¿À··»¶´¸º¾¸ž”‡ucWSMP\fp†•›ž’‚uldVTWT`vŠ“¥´ÀË»´­¦bZYE3.,*)+'&.0575=CE=?935;CM\bm{€Œƒvmrypmt‰‹„ƒ…†ŸªŸ˜¢¥ ž§© —•›¨²»º°±¹ÂÍÏËÊÃÀÀÇÇįžŽ}nd^ROXesŽ™¡£’}kbZSQTYVj€Œ—§ºÆÅ¿½¸iZZI50,*&&#!(,.*-;ORPUNLFO]gvx‚†•‡ukpqljmwyropx…“¢­¤š¢¬«¯«Ÿ”‘‘™¬·»»¿¾¿ÎØÜÔÈÄÈÄÊÉÍðš‡viddV\ev‰–£ {h_XOPQZ]mzˆ’Ÿ¸ÅÈÄËÅaMMD<3,# #%!!3R___abcmx~†‡‡‰‡–Œxozypgdilc]_i~Š•¤¥›š¤®±¦œ™›˜œ­ºÀÁÉÏÕååäÝÒÊËÆÇÐÐÌÀ®{nii`[Zf–‹n^\QKNW\ju€‰˜¢µÁÇÈÌÈQFA<9/#  .MZVWcl•“•‘‘”–Œ~y{ue[Z]^[[jx¤”¤£¡¡œŸž «¸ÀÇÓÜçñêèäÞÝÒÌÎÓÍû®•sod_SN]nv|unbTMDANZcyƒ™Ÿ§«¹À»·I;2+*#  +,GOLTj€›­§›”‘“–•¢™†‚ˆvhXQRVYiw{‡“‚‰Ÿ£•’™¤³¿ÇÍÖÚâéââåæéÝÒÐÐʺ³¦ŽulibZMEMR^a_bd[OIEN]q€Œˆ” ¤ž–ž±«¤F5.# + !(2AJQ`¢¹É¾±¨ž˜“˜Ÿ©¦ˆ‘‹wdQNMRery|†‰yz–¨Ÿ”Œ’¡³ÁÈÈÎÖÜÚ×ÙäîíàÕÌÍʽ®ž‡qg]VTJ<=HNKMM[_TPLPcs‹•œŸ¢ž–˜žŸ¢>.' "+6>FOXpš·ÈÚÛÏü¬Ÿ ¦®«›¢™Žƒr_TJGR_hnw‚ƒ~z‰Ÿš‹Šˆ¢²¼¾½½ÂÇËÑØáëçÚÍÁ¸´¯¡“}jb[OHE96=?B?=FQOQQVlw‹—¢§¤«¡––—7-"   ,4>LMZl‰¦ÃÔäæÚÏË¿´­©±·³¬¦˜ˆ}viUMHADTejmpxv€’…}„Ž£²·¹º·¶¸¿ÉÔÛÝ×Ç»®Ÿ––eSNMA=?<>657732@KNXan¦±°°³£•“•+% +!19AJQa‚¯ÄÔßàÓÓÐÇÆ¿¹ÃÉĵ ™—„wpaWPJA9AQWQQ\\dqztkvŠ ­µ´¸¸±¯²¸Æ̼µªš–Œ€xviP?><>=@@E:31.+.8CMUbwˆ“¡®³°­±©ž˜›Ÿ&  + ,7@IHUj‚¡¸ÆÉÓÜØÖÕËÊÍÓÜÛÒ»¥Ÿ’yfjcQIG>6>HE@AEFM[b]Zi„£³²°¶²£œ› ­«›–‹ƒ…~wiYH:143AJEBE?761/*1>IW_w‡‘™¦«¨¦¬­¦¥¯±' + + +  (1BQRWg}š·ÊÌÓÜãâà××ÕÜèßÔ¿¦šŒxfh`NE?:8?BA<:417?BKPZxœ²¹»¹±©›“™Ž‡pnuoieSC7,+3>EKLH><;2/++=Q[fuˆ“ž§©¦¤¬ª®²º-   "&/@Wdhl}”¸ÌÐÔÛîïìëèäçãÙÓĬ™qmeXLC:68=><4*$''&1DWo¥¶¼±§£•ŠzrodXVWUXZSH;,,55:LYQCA?520-DZbk…‘§¦ ¤««¯²°³¸6"  +  $*3IWfx{|®ÀÈÒàíïññìëéßÚÖǵ¦–‰{weO?2.2675*$7RlŸ©£”†xk[W]VNH??C@??1)'.38EVSCA93-.3G`rx‘©´º®®¯¯¼½²µ±E2&   $0;GVi}~‡“Ÿ«½ÆÛêòõóñîçáÜ×Í»¥—ŠrbPD7.,**)#+BUez‹”‹†ƒufZIAIK?407=967*!$(-9M^VI;,'$,9Tu‡‘¢§²¼Ëĵ¬ª»¸³»ºT?,$+.2?MQ^vz„’œŸªµÄÚìñôðíéàÛÔÓ̺¢”Œ‡ocVC0),*'!-9Mgv€zjdhaK?<=?6,&+145+ (09N]UH8+%%(6_{¦¯¹ÀÅÎÎƶ­¼½¾¸ÄSE1!"-:?CCGX]esŽ¢³´¸ÁÍáñîïçãåßÔÑ̸¨—ˆ„|q_LC?90+)),*#!%03<;1+++5=Qbz’¤§°¶ÇÊÑÈÁÊÓÏÌÏÙMIA75/*"$)0>SZcbcl}€ƒ…ž©©«´ÂÑâèïêÝŸ¸ÅÈ¿½Áº©—‰|aUE0)+( #$ #030+,24ALG?1('''%"#24/2/+(*=HXh‚™©¡©½ÉÅÊÌÍÎÈÊÊÎËMPK><13+#*)2>Tchinmx‰‹Š‰’¥¨›¦¹ÊØÝßÙѾ©£¨©«©®²§†j`WJ7+**"#*%&3>BGH:+# "" #/44752.19CKbwŠ£«µÀ»ÊÌËÀ¹ÄÉƹV^WKDAE=//2>N`heiokzˆŒ——š¢“‘ž®¿ÔØÐƸ´¥–”š™„h^XOB-"   $#&/69591%#)8>=54;824AXf{—­¼»½½Æ˽²­½¼±¯dpi^PSWG:8@ESdnlmwuvƒ”§¦¢œ›‘–š±ÀÄƹª¥˜ˆ||z{ˆ…yaNORI3%"  +&*0+,)%$139BLJC@67CKTRh‡ªª«³¹Àµ§¥°º²°flom`geRBHMX`jjmou~|‰¡®®œ•˜˜•‘‘™§µ¿Ä¶Ÿ•“‘‰€}|~ƒ„xgTGIJA2)#  + +  $# "!!%(# (2=BDKNH=;=MSWM[w™¢¨£±½¬¨±¶®¦iqyyvxp`[XV[gmkmuz‰…Œ¢®©Ÿ˜›¦¤ £§¨°·»¯––•‡{~‚ˆy^L=::62)    (*1,''5DLHDF?>6ANW^SXks˜˜˜¥·³­²´«žuzyy|yf^Xgkilx„†‘£«ªŸ¡£¯­¯´±±±³³ª™–’“Š‡}…‡†~kU:/10/& + +%0857;=LLFAD@A?LX_c]]i~ˆŒ…“›ž°­±´³¬¢u~wv{|Š}gb_hignq{†Š“¤«¥Ÿ¤¬¸·µ´³«©«©˜¦¨Š•“ƒkR:*+23%  &09>EPOUTL?ABHKVfkgcdnˆ‰‡†™™Ÿ±¯·¼¾º±irgkt{Šzqngs}z‚‡”•—¡§ žœ§´´·³°ª¦¤¤š¡¥²·ª›––œšŒqUE30?OY_ilqz‰”˜•––¦¬«P?:9==;>Ncx‰ž¦¢¦°¯®§ ©®­³¹¿Ä¾Â¿¼°ª§²½¼³´ÃÉÎËĶ£™Ž~whXNE4#   + %)15.-24B?>KLPNJKLOT_ndfsx~zŒ€vz}|ˆ™••QFC@A@@W[UUYk€ £¥Ÿ—’œ˜Œ˜›‘¯´¤¢¤¦¬¢¢°³®«¯½ÕãÛžºµ³¯ž‹„}tdK7-##)2?QYM<,$&% %(""&-99@S]lleedp{tkdgjeegq}Œž˜‰~rnnlrq€†~|r:=>=ETca`lr–– ¨ª ™’…€‚zr‡¢¥–›¡š˜™š˜œ¤²ÎÝØËÉÎÍÇÆ´ž–‘ƒsbM=.),3>BET^VE6(&%!',! #$$&7BR^euxru{ˆ‰ƒzumfky|‰•ž¤“Šviknlhnz{nl37:EP[jrwƒ‚Ž ¢¥¦¨¢šŠ†zgd`Ykƒ‹’š–Žz€„~™¯¿ÈÊÍÓ×Õ×ÙÊ´¦žƒw]E20&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/jenga.dae b/jenga.dae new file mode 100644 index 0000000..19c85d0 --- /dev/null +++ b/jenga.dae @@ -0,0 +1,5632 @@ + + + + + Illusoft Collada 1.4.0 plugin for Blender - http://colladablender.illusoft.com + Blender v:242 - Illusoft Collada Exporter v:0.2.65 + + + file:///Users/erwin/Desktop/physics_demos-2.42-preview34/jenga_physics_test.blend + + 2006-07-18T10:32:54.891550 + 2006-07-18T10:32:54.891607 + Z_UP + + + + + + + 49.13434 + 0.1 + 100.0 + + + + + + + + + + + + + + + + + + + + + + + 0.0 0.0 0.0 1.0 + + + 0.4 0.4 0.4 1.0 + + + 0.8 0.8 0.8 1.0 + + + 0.5 0.5 0.5 1.0 + + + 12.5 + + + 1.0 1.0 1.0 1.0 + + + 0.8 + + + 1 1 1 1 + + + 0.0 + + + + + + + + + + + 4.628 0.542 0.0 4.461 0.379 0.0 4.461 0.369 0.0 4.539 0.369 0.0 4.539 0.132 0.0 4.54308 0.09343 0.0 4.5553 0.05944 0.0 4.57563 0.03112 0.0 4.60404 0.00956 0.0 4.6405 -0.00418 0.0 4.685 -0.009 0.0 4.70092 -0.00796 0.0 4.719 -0.005 0.0 4.73825 -0.00038 0.0 4.75767 0.00567 0.0 4.77625 0.01288 0.0 4.793 0.021 0.0 4.793 0.104 0.0 4.77524 0.09392 0.0 4.75793 0.08567 0.0 4.741 0.07925 0.0 4.72441 0.07467 0.0 4.70809 0.07192 0.0 4.692 0.071 0.0 4.67823 0.07236 0.0 4.66385 0.07685 0.0 4.65025 0.08513 0.0 4.63882 0.09781 0.0 4.63094 0.11556 0.0 4.628 0.139 0.0 4.628 0.369 0.0 4.77 0.369 0.0 4.77 0.449 0.0 4.628 0.449 0.0 4.134 0.449 0.0 4.134 0.0 0.0 4.223 0.0 0.0 4.223 0.235 0.0 4.22684 0.27196 0.0 4.2377 0.305 0.0 4.25463 0.33288 0.0 4.27663 0.35433 0.0 4.30275 0.36813 0.0 4.332 0.373 0.0 4.34357 0.37155 0.0 4.35685 0.36737 0.0 4.37125 0.36075 0.0 4.38615 0.35196 0.0 4.40094 0.34129 0.0 4.415 0.329 0.0 4.462 0.406 0.0 4.44373 0.422 0.0 4.42582 0.43504 0.0 4.40813 0.44513 0.0 4.39052 0.4523 0.0 4.37286 0.45658 0.0 4.355 0.458 0.0 4.33391 0.45519 0.0 4.31263 0.44652 0.0 4.29113 0.43163 0.0 4.26937 0.41015 0.0 4.24734 0.38173 0.0 4.225 0.346 0.0 4.223 0.346 0.0 4.223 0.449 0.0 4.049 0.08 0.0 4.0392 0.07301 0.0 4.02993 0.06711 0.0 4.02138 0.06238 0.0 4.01374 0.05889 0.0 4.00722 0.05674 0.0 4.002 0.056 0.0 3.99692 0.05652 0.0 3.9927 0.05819 0.0 3.98938 0.06113 0.0 3.98696 0.06548 0.0 3.9855 0.07139 0.0 3.985 0.079 0.0 3.985 0.31 0.0 3.97925 0.35638 0.0 3.96296 0.3937 0.0 3.93763 0.42225 0.0 3.9047 0.4423 0.0 3.86567 0.45412 0.0 3.822 0.458 0.0 3.79082 0.45633 0.0 3.76226 0.4513 0.0 3.73625 0.44288 0.0 3.71274 0.43104 0.0 3.69168 0.41575 0.0 3.673 0.397 0.0 3.673 0.3 0.0 3.69505 0.32319 0.0 3.71804 0.34185 0.0 3.74175 0.35612 0.0 3.76596 0.36615 0.0 3.79045 0.37206 0.0 3.815 0.374 0.0 3.83975 0.37204 0.0 3.86 0.36596 0.0 3.87575 0.3555 0.0 3.887 0.34037 0.0 3.89375 0.3203 0.0 3.896 0.295 0.0 3.896 0.271 0.0 3.817 0.243 0.0 3.78067 0.22963 0.0 3.74533 0.21441 0.0 3.7135 0.19563 0.0 3.68767 0.17159 0.0 3.67033 0.14062 0.0 3.664 0.101 0.0 3.66757 0.07271 0.0 3.67785 0.0467 0.0 3.69425 0.02425 0.0 3.71615 0.00663 0.0 3.74294 -0.00488 0.0 3.774 -0.009 0.0 3.79449 -0.00775 0.0 3.81493 -0.00396 0.0 3.83525 0.00238 0.0 3.85541 0.0113 0.0 3.87534 0.02283 0.0 3.895 0.037 0.0 3.90011 0.02248 0.0 3.90752 0.01085 0.0 3.91738 0.002 0.0 3.92982 -0.00419 0.0 3.94498 -0.00781 0.0 3.963 -0.009 0.0 3.97625 -0.00828 0.0 3.98863 -0.00593 0.0 4.00113 -0.00163 0.0 4.0147 0.00493 0.0 4.03034 0.01403 0.0 4.049 0.026 0.0 3.896 0.091 0.0 3.88383 0.08027 0.0 3.87133 0.07119 0.0 3.8585 0.06387 0.0 3.84533 0.05848 0.0 3.83183 0.05514 0.0 3.818 0.054 0.0 3.80041 0.0561 0.0 3.78496 0.06211 0.0 3.77213 0.07163 0.0 3.76237 0.08422 0.0 3.75617 0.09949 0.0 3.754 0.117 0.0 3.75924 0.14138 0.0 3.77393 0.162 0.0 3.7965 0.17963 0.0 3.82541 0.195 0.0 3.85909 0.20888 0.0 3.896 0.222 0.0 3.472 0.542 0.0 3.305 0.379 0.0 3.305 0.369 0.0 3.383 0.369 0.0 3.383 0.132 0.0 3.38708 0.09343 0.0 3.3993 0.05944 0.0 3.41963 0.03112 0.0 3.44804 0.00956 0.0 3.48451 -0.00418 0.0 3.529 -0.009 0.0 3.54492 -0.00796 0.0 3.563 -0.005 0.0 3.58225 -0.00038 0.0 3.60167 0.00567 0.0 3.62025 0.01288 0.0 3.637 0.021 0.0 3.637 0.104 0.0 3.61924 0.09392 0.0 3.60193 0.08567 0.0 3.585 0.07925 0.0 3.56841 0.07467 0.0 3.55209 0.07192 0.0 3.536 0.071 0.0 3.52223 0.07236 0.0 3.50785 0.07685 0.0 3.49425 0.08513 0.0 3.48282 0.09781 0.0 3.47494 0.11556 0.0 3.472 0.139 0.0 3.472 0.369 0.0 3.614 0.369 0.0 3.614 0.449 0.0 3.472 0.449 0.0 3.244 0.421 0.0 3.22082 0.43242 0.0 3.19822 0.4417 0.0 3.17613 0.44888 0.0 3.15444 0.45396 0.0 3.1331 0.457 0.0 3.112 0.458 0.0 3.06979 0.45424 0.0 3.03363 0.44326 0.0 3.00425 0.4255 0.0 2.98237 0.40141 0.0 2.96871 0.37143 0.0 2.964 0.336 0.0 2.97956 0.28229 0.0 3.01845 0.24 0.0 3.069 0.20588 0.0 3.11956 0.17667 0.0 3.15844 0.14913 0.0 3.174 0.12 0.0 3.17161 0.10525 0.0 3.16489 0.093 0.0 3.1545 0.08325 0.0 3.14111 0.076 0.0 3.12539 0.07125 0.0 3.108 0.069 0.0 3.08864 0.07059 0.0 3.06678 0.07541 0.0 3.04275 0.0835 0.0 3.01689 0.09493 0.0 2.98953 0.10974 0.0 2.961 0.128 0.0 2.961 0.032 0.0 2.98888 0.01855 0.0 3.015 0.00804 0.0 3.04013 0.00025 0.0 3.065 -0.00504 0.0 3.09038 -0.00805 0.0 3.117 -0.009 0.0 3.15748 -0.00471 0.0 3.19315 0.00767 0.0 3.22288 0.02737 0.0 3.24552 0.05367 0.0 3.25994 0.08579 0.0 3.265 0.123 0.0 3.26266 0.1449 0.0 3.25526 0.16522 0.0 3.24225 0.18488 0.0 3.22307 0.20478 0.0 3.19718 0.22585 0.0 3.164 0.249 0.0 3.1285 0.27025 0.0 3.10063 0.28833 0.0 3.07988 0.30375 0.0 3.0657 0.317 0.0 3.05759 0.32858 0.0 3.055 0.339 0.0 3.05687 0.35037 0.0 3.0623 0.3603 0.0 3.071 0.3685 0.0 3.0827 0.3747 0.0 3.09713 0.37863 0.0 3.114 0.38 0.0 3.13162 0.37881 0.0 3.15126 0.37515 0.0 3.17263 0.36887 0.0 3.19541 0.35985 0.0 3.2193 0.34794 0.0 3.244 0.333 0.0 2.879 0.13 0.0 2.85307 0.11419 0.0 2.82719 0.10089 0.0 2.80125 0.09025 0.0 2.77515 0.08244 0.0 2.74877 0.07764 0.0 2.722 0.076 0.0 2.68193 0.07982 0.0 2.64774 0.09122 0.0 2.6195 0.11013 0.0 2.59726 0.13644 0.0 2.58107 0.1701 0.0 2.571 0.211 0.0 2.887 0.211 0.0 2.88082 0.28694 0.0 2.86289 0.34881 0.0 2.83413 0.39675 0.0 2.79544 0.43085 0.0 2.74776 0.45123 0.0 2.692 0.458 0.0 2.63339 0.45056 0.0 2.58244 0.42911 0.0 2.5405 0.395 0.0 2.50889 0.34956 0.0 2.48894 0.29411 0.0 2.482 0.23 0.0 2.48843 0.16924 0.0 2.50741 0.11293 0.0 2.5385 0.064 0.0 2.58126 0.02541 0.0 2.63524 9e-05 0.0 2.7 -0.009 0.0 2.7359 -0.00757 0.0 2.76819 -0.00326 0.0 2.79775 0.004 0.0 2.82548 0.01426 0.0 2.85227 0.02757 0.0 2.879 0.044 0.0 2.573 0.27 0.0 2.58141 0.30288 0.0 2.59459 0.33033 0.0 2.6125 0.35213 0.0 2.63507 0.368 0.0 2.66226 0.37771 0.0 2.694 0.381 0.0 2.72344 0.3775 0.0 2.74856 0.36733 0.0 2.769 0.351 0.0 2.78445 0.329 0.0 2.79456 0.30183 0.0 2.799 0.27 0.0 2.114 0.449 0.0 2.114 0.0 0.0 2.203 0.0 0.0 2.203 0.235 0.0 2.20684 0.27196 0.0 2.2177 0.305 0.0 2.23463 0.33288 0.0 2.25663 0.35433 0.0 2.28275 0.36813 0.0 2.312 0.373 0.0 2.32357 0.37155 0.0 2.33685 0.36737 0.0 2.35125 0.36075 0.0 2.36615 0.35196 0.0 2.38094 0.34129 0.0 2.395 0.329 0.0 2.442 0.406 0.0 2.42373 0.422 0.0 2.40582 0.43504 0.0 2.38813 0.44513 0.0 2.37052 0.4523 0.0 2.35286 0.45658 0.0 2.335 0.458 0.0 2.31391 0.45519 0.0 2.29263 0.44652 0.0 2.27113 0.43163 0.0 2.24937 0.41015 0.0 2.22734 0.38173 0.0 2.205 0.346 0.0 2.203 0.346 0.0 2.203 0.449 0.0 1.488 0.458 0.0 1.42392 0.45 0.0 1.367 0.4273 0.0 1.31925 0.39187 0.0 1.28267 0.3457 0.0 1.25925 0.29075 0.0 1.251 0.229 0.0 1.25897 0.16345 0.0 1.28178 0.10596 0.0 1.31775 0.05825 0.0 1.36522 0.02204 0.0 1.42253 -0.00095 0.0 1.488 -0.009 0.0 1.556 -0.00123 0.0 1.615 0.02115 0.0 1.6635 0.05675 0.0 1.7 0.10419 0.0 1.723 0.16206 0.0 1.731 0.229 0.0 1.72279 0.29214 0.0 1.69933 0.34748 0.0 1.66238 0.39338 0.0 1.61367 0.42819 0.0 1.55496 0.45027 0.0 1.487 0.378 0.0 1.52924 0.37293 0.0 1.56622 0.35844 0.0 1.59688 0.33563 0.0 1.62011 0.30556 0.0 1.63485 0.26932 0.0 1.64 0.228 0.0 1.63519 0.18269 0.0 1.62122 0.14419 0.0 1.59875 0.11313 0.0 1.56844 0.09015 0.0 1.53097 0.07589 0.0 1.487 0.071 0.0 1.4464 0.07611 0.0 1.41119 0.09085 0.0 1.38225 0.11437 0.0 1.36048 0.14581 0.0 1.34677 0.18431 0.0 1.342 0.229 0.0 1.34691 0.2699 0.0 1.36093 0.30585 0.0 1.383 0.33575 0.0 1.41207 0.35848 0.0 1.44709 0.37294 0.0 1.049 0.542 0.0 0.882 0.379 0.0 0.882 0.369 0.0 0.96 0.369 0.0 0.96 0.132 0.0 0.96408 0.09343 0.0 0.9763 0.05944 0.0 0.99663 0.03112 0.0 1.02504 0.00956 0.0 1.0615 -0.00418 0.0 1.106 -0.009 0.0 1.12192 -0.00796 0.0 1.14 -0.005 0.0 1.15925 -0.00038 0.0 1.17867 0.00567 0.0 1.19725 0.01288 0.0 1.214 0.021 0.0 1.214 0.104 0.0 1.19624 0.09392 0.0 1.17893 0.08567 0.0 1.162 0.07925 0.0 1.14541 0.07467 0.0 1.12909 0.07192 0.0 1.113 0.071 0.0 1.09923 0.07236 0.0 1.08485 0.07685 0.0 1.07125 0.08513 0.0 1.05981 0.09781 0.0 1.05194 0.11556 0.0 1.049 0.139 0.0 1.049 0.369 0.0 1.191 0.369 0.0 1.191 0.449 0.0 1.049 0.449 0.0 0.077 0.682 0.0 0.077 0.0 0.0 0.175 0.0 0.0 0.175 0.296 0.0 0.216 0.296 0.0 0.24052 0.29417 0.0 0.26515 0.28667 0.0 0.2915 0.2705 0.0 0.32119 0.24267 0.0 0.35581 0.20017 0.0 0.397 0.14 0.0 0.487 0.0 0.0 0.604 0.0 0.0 0.58281 0.02931 0.0 0.56544 0.05344 0.0 0.55075 0.07425 0.0 0.53756 0.09356 0.0 0.52469 0.11319 0.0 0.511 0.135 0.0 0.48599 0.17567 0.0 0.46226 0.21267 0.0 0.43875 0.246 0.0 0.41441 0.27567 0.0 0.38818 0.30167 0.0 0.359 0.324 0.0 0.39279 0.34095 0.0 0.421 0.36263 0.0 0.44337 0.38875 0.0 0.45967 0.41904 0.0 0.46962 0.45321 0.0 0.473 0.491 0.0 0.46599 0.54612 0.0 0.44559 0.59296 0.0 0.41275 0.63075 0.0 0.36841 0.6587 0.0 0.31351 0.67605 0.0 0.249 0.682 0.0 0.175 0.598 0.0 0.238 0.598 0.0 0.28084 0.59481 0.0 0.31474 0.58552 0.0 0.34025 0.5705 0.0 0.35793 0.55015 0.0 0.36832 0.52485 0.0 0.372 0.495 0.0 0.36971 0.46699 0.0 0.36104 0.44089 0.0 0.34475 0.41813 0.0 0.31963 0.40011 0.0 0.28445 0.38826 0.0 0.238 0.384 0.0 0.175 0.384 0.0 + + + + + + + + + + 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    1 0 0 1 33 2 1 3 33 4 32 5 1 6 32 7 31 8 2 9 1 10 31 11 3 12 2 13 31 14 4 15 3 16 30 17 30 18 3 19 31 20 4 21 30 22 29 23 4 24 29 25 28 26 5 27 4 28 28 29 5 30 28 31 27 32 18 33 17 34 16 35 5 36 27 37 26 38 19 39 18 40 16 41 6 42 5 43 26 44 20 45 19 46 16 47 6 48 26 49 25 50 21 51 20 52 16 53 6 54 25 55 24 56 22 57 21 58 16 59 6 60 24 61 23 62 23 63 22 64 16 65 6 66 23 67 16 68 7 69 6 70 16 71 8 72 7 73 16 74 8 75 16 76 15 77 8 78 15 79 14 80 9 81 8 82 14 83 9 84 14 85 13 86 9 87 13 88 12 89 10 90 9 91 12 92 10 93 12 94 11 95 57 96 56 97 55 98 57 99 55 100 54 101 58 102 57 103 54 104 58 105 54 106 53 107 35 108 34 109 64 110 35 111 64 112 63 113 59 114 58 115 53 116 59 117 53 118 52 119 59 120 52 121 51 122 60 123 59 124 51 125 60 126 51 127 50 128 61 129 60 130 50 131 61 132 50 133 43 134 43 135 50 136 44 137 44 138 50 139 45 140 45 141 50 142 46 143 46 144 50 145 47 146 47 147 50 148 48 149 48 150 50 151 49 152 62 153 61 154 42 155 42 156 61 157 43 158 62 159 42 160 41 161 62 162 41 163 40 164 35 165 63 166 62 167 35 168 62 169 39 170 39 171 62 172 40 173 35 174 39 175 38 176 35 177 38 178 37 179 35 180 37 181 36 182 85 183 84 184 83 185 86 186 85 187 83 188 86 189 83 190 82 191 87 192 86 193 82 194 88 195 87 196 82 197 88 198 82 199 81 200 89 201 88 202 81 203 89 204 81 205 80 206 90 207 89 208 80 209 91 210 90 211 92 212 92 213 90 214 93 215 93 216 90 217 94 218 94 219 90 220 95 221 95 222 90 223 96 224 96 225 90 226 97 227 97 228 90 229 80 230 97 231 80 232 98 233 98 234 80 235 79 236 99 237 98 238 79 239 100 240 99 241 79 242 100 243 79 244 78 245 101 246 100 247 78 248 102 249 101 250 78 251 103 252 102 253 78 254 103 255 78 256 77 257 104 258 103 259 77 260 105 261 104 262 154 263 154 264 104 265 77 266 106 267 105 268 154 269 107 270 106 271 154 272 107 273 154 274 153 275 136 276 154 277 77 278 108 279 107 280 153 281 108 282 153 283 152 284 109 285 108 286 152 287 109 288 152 289 151 290 109 291 151 292 150 293 110 294 109 295 150 296 110 297 150 298 149 299 110 300 149 301 148 302 111 303 110 304 148 305 111 306 148 307 147 308 112 309 111 310 147 311 112 312 147 313 146 314 137 315 136 316 77 317 112 318 146 319 145 320 138 321 137 322 77 323 66 324 65 325 135 326 138 327 77 328 76 329 67 330 66 331 135 332 113 333 112 334 145 335 113 336 145 337 144 338 138 339 76 340 75 341 139 342 138 343 75 344 68 345 67 346 135 347 139 348 75 349 74 350 140 351 139 352 74 353 69 354 68 355 135 356 113 357 144 358 143 359 140 360 74 361 73 362 70 363 69 364 135 365 141 366 140 367 73 368 141 369 73 370 72 371 71 372 70 373 135 374 141 375 72 376 71 377 113 378 143 379 142 380 141 381 71 382 135 383 142 384 141 385 135 386 113 387 142 388 123 389 123 390 142 391 135 392 114 393 113 394 123 395 114 396 123 397 122 398 124 399 123 400 135 401 124 402 135 403 134 404 115 405 114 406 122 407 115 408 122 409 121 410 125 411 124 412 134 413 125 414 134 415 133 416 115 417 121 418 120 419 126 420 125 421 133 422 116 423 115 424 120 425 126 426 133 427 132 428 116 429 120 430 119 431 127 432 126 433 132 434 127 435 132 436 131 437 116 438 119 439 118 440 128 441 127 442 131 443 117 444 116 445 118 446 128 447 131 448 130 449 129 450 128 451 130 452 156 453 155 454 188 455 156 456 188 457 187 458 156 459 187 460 186 461 157 462 156 463 186 464 158 465 157 466 186 467 159 468 158 469 185 470 185 471 158 472 186 473 159 474 185 475 184 476 159 477 184 478 183 479 160 480 159 481 183 482 160 483 183 484 182 485 173 486 172 487 171 488 160 489 182 490 181 491 174 492 173 493 171 494 161 495 160 496 181 497 175 498 174 499 171 500 161 501 181 502 180 503 176 504 175 505 171 506 161 507 180 508 179 509 177 510 176 511 171 512 161 513 179 514 178 515 178 516 177 517 171 518 161 519 178 520 171 521 162 522 161 523 171 524 163 525 162 526 171 527 163 528 171 529 170 530 163 531 170 532 169 533 164 534 163 535 169 536 164 537 169 538 168 539 164 540 168 541 167 542 165 543 164 544 167 545 165 546 167 547 166 548 196 549 195 550 194 551 196 552 194 553 193 554 197 555 196 556 193 557 197 558 193 559 192 560 197 561 192 562 191 563 198 564 197 565 191 566 198 567 191 568 190 569 198 570 190 571 189 572 199 573 198 574 189 575 199 576 189 577 250 578 250 579 189 580 251 581 251 582 189 583 252 584 252 585 189 586 253 587 253 588 189 589 254 590 254 591 189 592 255 593 255 594 189 595 256 596 200 597 199 598 250 599 200 600 250 601 249 602 200 603 249 604 248 605 200 606 248 607 247 608 201 609 200 610 247 611 201 612 247 613 246 614 201 615 246 616 245 617 201 618 245 619 244 620 201 621 244 622 243 623 202 624 201 625 243 626 202 627 243 628 242 629 202 630 242 631 241 632 202 633 241 634 240 635 202 636 240 637 239 638 203 639 202 640 239 641 203 642 239 643 238 644 203 645 238 646 237 647 204 648 203 649 237 650 204 651 237 652 236 653 205 654 204 655 236 656 205 657 236 658 235 659 205 660 235 661 234 662 206 663 205 664 234 665 206 666 234 667 233 668 207 669 206 670 233 671 207 672 233 673 232 674 220 675 219 676 218 677 207 678 232 679 231 680 208 681 207 682 231 683 220 684 218 685 217 686 209 687 208 688 231 689 220 690 217 691 216 692 210 693 209 694 231 695 210 696 231 697 230 698 220 699 216 700 215 701 211 702 210 703 230 704 212 705 211 706 230 707 220 708 215 709 214 710 213 711 212 712 230 713 220 714 214 715 213 716 220 717 213 718 230 719 220 720 230 721 229 722 221 723 220 724 229 725 221 726 229 727 228 728 222 729 221 730 228 731 223 732 222 733 228 734 223 735 228 736 227 737 224 738 223 739 227 740 224 741 227 742 226 743 225 744 224 745 226 746 277 747 276 748 275 749 277 750 275 751 274 752 278 753 277 754 274 755 278 756 274 757 273 758 279 759 278 760 273 761 279 762 273 763 301 764 301 765 273 766 302 767 302 768 273 769 272 770 280 771 279 772 300 773 300 774 279 775 301 776 280 777 300 778 299 779 303 780 302 781 272 782 280 783 299 784 298 785 304 786 303 787 272 788 280 789 298 790 297 791 305 792 304 793 272 794 281 795 280 796 297 797 305 798 272 799 271 800 281 801 297 802 296 803 306 804 305 805 271 806 281 807 296 808 295 809 307 810 306 811 271 812 282 813 281 814 295 815 307 816 271 817 270 818 282 819 295 820 307 821 282 822 307 823 270 824 283 825 282 826 269 827 269 828 282 829 270 830 283 831 269 832 268 833 283 834 268 835 267 836 284 837 283 838 267 839 284 840 267 841 266 842 258 843 257 844 294 845 259 846 258 847 294 848 285 849 284 850 266 851 285 852 266 853 265 854 260 855 259 856 294 857 285 858 265 859 264 860 261 861 260 862 294 863 262 864 261 865 294 866 285 867 264 868 263 869 263 870 262 871 294 872 285 873 263 874 294 875 286 876 285 877 294 878 286 879 294 880 293 881 286 882 293 883 292 884 287 885 286 886 292 887 287 888 292 889 291 890 287 891 291 892 290 893 288 894 287 895 290 896 288 897 290 898 289 899 331 900 330 901 329 902 331 903 329 904 328 905 332 906 331 907 328 908 332 909 328 910 327 911 309 912 308 913 338 914 309 915 338 916 337 917 333 918 332 919 327 920 333 921 327 922 326 923 333 924 326 925 325 926 334 927 333 928 325 929 334 930 325 931 324 932 335 933 334 934 324 935 335 936 324 937 317 938 317 939 324 940 318 941 318 942 324 943 319 944 319 945 324 946 320 947 320 948 324 949 321 950 321 951 324 952 322 953 322 954 324 955 323 956 336 957 335 958 316 959 316 960 335 961 317 962 336 963 316 964 315 965 336 966 315 967 314 968 309 969 337 970 336 971 309 972 336 973 313 974 313 975 336 976 314 977 309 978 313 979 312 980 309 981 312 982 311 983 309 984 311 985 310 986 340 987 339 988 362 989 340 990 362 991 361 992 341 993 340 994 361 995 341 996 361 997 360 998 342 999 341 1000 360 1001 342 1002 360 1003 363 1004 363 1005 360 1006 364 1007 364 1008 360 1009 359 1010 343 1011 342 1012 386 1013 386 1014 342 1015 363 1016 343 1017 386 1018 385 1019 365 1020 364 1021 359 1022 343 1023 385 1024 384 1025 366 1026 365 1027 359 1028 366 1029 359 1030 358 1031 344 1032 343 1033 384 1034 344 1035 384 1036 383 1037 367 1038 366 1039 358 1040 344 1041 383 1042 382 1043 368 1044 367 1045 358 1046 368 1047 358 1048 357 1049 345 1050 344 1051 382 1052 345 1053 382 1054 381 1055 369 1056 368 1057 357 1058 346 1059 345 1060 381 1061 346 1062 381 1063 380 1064 369 1065 357 1066 356 1067 370 1068 369 1069 356 1070 346 1071 380 1072 379 1073 371 1074 370 1075 356 1076 347 1077 346 1078 379 1079 371 1080 356 1081 355 1082 347 1083 379 1084 378 1085 372 1086 371 1087 355 1088 347 1089 378 1090 377 1091 373 1092 372 1093 355 1094 348 1095 347 1096 377 1097 373 1098 355 1099 354 1100 348 1101 377 1102 376 1103 374 1104 373 1105 354 1106 348 1107 376 1108 375 1109 375 1110 374 1111 354 1112 348 1113 375 1114 354 1115 349 1116 348 1117 354 1118 349 1119 354 1120 353 1121 350 1122 349 1123 353 1124 350 1125 353 1126 352 1127 351 1128 350 1129 352 1130 388 1131 387 1132 420 1133 388 1134 420 1135 419 1136 388 1137 419 1138 418 1139 389 1140 388 1141 418 1142 390 1143 389 1144 418 1145 391 1146 390 1147 417 1148 417 1149 390 1150 418 1151 391 1152 417 1153 416 1154 391 1155 416 1156 415 1157 392 1158 391 1159 415 1160 392 1161 415 1162 414 1163 405 1164 404 1165 403 1166 392 1167 414 1168 413 1169 406 1170 405 1171 403 1172 393 1173 392 1174 413 1175 407 1176 406 1177 403 1178 393 1179 413 1180 412 1181 408 1182 407 1183 403 1184 393 1185 412 1186 411 1187 409 1188 408 1189 403 1190 393 1191 411 1192 410 1193 410 1194 409 1195 403 1196 393 1197 410 1198 403 1199 394 1200 393 1201 403 1202 395 1203 394 1204 403 1205 395 1206 403 1207 402 1208 395 1209 402 1210 401 1211 396 1212 395 1213 401 1214 396 1215 401 1216 400 1217 396 1218 400 1219 399 1220 397 1221 396 1222 399 1223 397 1224 399 1225 398 1226 422 1227 421 1228 458 1229 458 1230 421 1231 457 1232 458 1233 457 1234 456 1235 458 1236 456 1237 455 1238 458 1239 455 1240 454 1241 458 1242 454 1243 459 1244 459 1245 454 1246 453 1247 422 1248 458 1249 472 1250 460 1251 459 1252 453 1253 461 1254 460 1255 453 1256 461 1257 453 1258 452 1259 462 1260 461 1261 452 1262 463 1263 462 1264 452 1265 464 1266 463 1267 452 1268 464 1269 452 1270 451 1271 465 1272 464 1273 451 1274 466 1275 465 1276 451 1277 466 1278 451 1279 450 1280 467 1281 466 1282 450 1283 467 1284 450 1285 449 1286 468 1287 467 1288 449 1289 468 1290 449 1291 448 1292 469 1293 468 1294 448 1295 470 1296 469 1297 448 1298 470 1299 448 1300 447 1301 471 1302 470 1303 447 1304 422 1305 472 1306 424 1307 424 1308 472 1309 471 1310 424 1311 471 1312 447 1313 424 1314 447 1315 446 1316 424 1317 446 1318 445 1319 424 1320 445 1321 444 1322 424 1323 444 1324 425 1325 425 1326 444 1327 426 1328 426 1329 444 1330 443 1331 422 1332 424 1333 423 1334 427 1335 426 1336 443 1337 428 1338 427 1339 443 1340 428 1341 443 1342 442 1343 429 1344 428 1345 442 1346 429 1347 442 1348 441 1349 430 1350 429 1351 441 1352 430 1353 441 1354 440 1355 431 1356 430 1357 440 1358 431 1359 440 1360 439 1361 432 1362 431 1363 439 1364 432 1365 439 1366 438 1367 432 1368 438 1369 437 1370 432 1371 437 1372 436 1373 432 1374 436 1375 435 1376 432 1377 435 1378 434 1379 432 1380 434 1381 433 1382

    + + + + + + + 9.646 -1.87 0.0 9.62007 -1.88581 0.0 9.59419 -1.89911 0.0 9.56825 -1.90975 0.0 9.54215 -1.91756 0.0 9.51577 -1.92236 0.0 9.489 -1.924 0.0 9.44893 -1.92018 0.0 9.41474 -1.90878 0.0 9.3865 -1.88988 0.0 9.36426 -1.86356 0.0 9.34807 -1.8299 0.0 9.338 -1.789 0.0 9.654 -1.789 0.0 9.64782 -1.71306 0.0 9.62989 -1.65119 0.0 9.60113 -1.60325 0.0 9.56245 -1.56915 0.0 9.51476 -1.54877 0.0 9.459 -1.542 0.0 9.40039 -1.54944 0.0 9.34945 -1.57089 0.0 9.3075 -1.605 0.0 9.27589 -1.65044 0.0 9.25595 -1.70589 0.0 9.249 -1.77 0.0 9.25543 -1.83076 0.0 9.27441 -1.88707 0.0 9.3055 -1.936 0.0 9.34826 -1.97459 0.0 9.40224 -1.99991 0.0 9.467 -2.009 0.0 9.5029 -2.00757 0.0 9.53519 -2.00326 0.0 9.56475 -1.996 0.0 9.59248 -1.98574 0.0 9.61927 -1.97243 0.0 9.646 -1.956 0.0 9.34 -1.73 0.0 9.34841 -1.69712 0.0 9.36159 -1.66967 0.0 9.3795 -1.64787 0.0 9.40208 -1.632 0.0 9.42926 -1.62229 0.0 9.461 -1.619 0.0 9.49045 -1.6225 0.0 9.51556 -1.63267 0.0 9.536 -1.649 0.0 9.55145 -1.671 0.0 9.56156 -1.69817 0.0 9.566 -1.73 0.0 9.042 -1.458 0.0 8.875 -1.621 0.0 8.875 -1.631 0.0 8.953 -1.631 0.0 8.953 -1.868 0.0 8.95708 -1.90657 0.0 8.9693 -1.94056 0.0 8.98963 -1.96888 0.0 9.01804 -1.99044 0.0 9.05451 -2.00418 0.0 9.099 -2.009 0.0 9.11492 -2.00796 0.0 9.133 -2.005 0.0 9.15225 -2.00038 0.0 9.17167 -1.99433 0.0 9.19025 -1.98713 0.0 9.207 -1.979 0.0 9.207 -1.896 0.0 9.18924 -1.90608 0.0 9.17193 -1.91433 0.0 9.155 -1.92075 0.0 9.13841 -1.92533 0.0 9.12209 -1.92808 0.0 9.106 -1.929 0.0 9.09223 -1.92764 0.0 9.07785 -1.92315 0.0 9.06425 -1.91488 0.0 9.05282 -1.90219 0.0 9.04494 -1.88444 0.0 9.042 -1.861 0.0 9.042 -1.631 0.0 9.184 -1.631 0.0 9.184 -1.551 0.0 9.042 -1.551 0.0 8.859 -1.92 0.0 8.8492 -1.92699 0.0 8.83993 -1.93289 0.0 8.83138 -1.93762 0.0 8.82374 -1.94111 0.0 8.81722 -1.94326 0.0 8.812 -1.944 0.0 8.80692 -1.94348 0.0 8.8027 -1.94181 0.0 8.79938 -1.93887 0.0 8.79696 -1.93452 0.0 8.7955 -1.92861 0.0 8.795 -1.921 0.0 8.795 -1.69 0.0 8.78925 -1.64362 0.0 8.77296 -1.6063 0.0 8.74763 -1.57775 0.0 8.7147 -1.5577 0.0 8.67567 -1.54588 0.0 8.632 -1.542 0.0 8.60083 -1.54367 0.0 8.57226 -1.5487 0.0 8.54625 -1.55712 0.0 8.52274 -1.56896 0.0 8.50168 -1.58425 0.0 8.483 -1.603 0.0 8.483 -1.7 0.0 8.50505 -1.67681 0.0 8.52804 -1.65815 0.0 8.55175 -1.64387 0.0 8.57596 -1.63385 0.0 8.60045 -1.62794 0.0 8.625 -1.626 0.0 8.64975 -1.62796 0.0 8.67 -1.63404 0.0 8.68575 -1.6445 0.0 8.697 -1.65963 0.0 8.70375 -1.6797 0.0 8.706 -1.705 0.0 8.706 -1.729 0.0 8.627 -1.757 0.0 8.59067 -1.77037 0.0 8.55533 -1.78559 0.0 8.5235 -1.80437 0.0 8.49767 -1.82841 0.0 8.48033 -1.85938 0.0 8.474 -1.899 0.0 8.47757 -1.92729 0.0 8.48785 -1.9533 0.0 8.50425 -1.97575 0.0 8.52615 -1.99337 0.0 8.55294 -2.00488 0.0 8.584 -2.009 0.0 8.60449 -2.00775 0.0 8.62493 -2.00396 0.0 8.64525 -1.99762 0.0 8.66541 -1.9887 0.0 8.68534 -1.97717 0.0 8.705 -1.963 0.0 8.71011 -1.97752 0.0 8.71752 -1.98915 0.0 8.72738 -1.998 0.0 8.73982 -2.00419 0.0 8.75498 -2.00781 0.0 8.773 -2.009 0.0 8.78625 -2.00828 0.0 8.79863 -2.00593 0.0 8.81113 -2.00162 0.0 8.8247 -1.99507 0.0 8.84034 -1.98597 0.0 8.859 -1.974 0.0 8.706 -1.909 0.0 8.69383 -1.91973 0.0 8.68133 -1.92881 0.0 8.6685 -1.93612 0.0 8.65533 -1.94152 0.0 8.64183 -1.94486 0.0 8.628 -1.946 0.0 8.61041 -1.9439 0.0 8.59496 -1.93789 0.0 8.58212 -1.92838 0.0 8.57237 -1.91578 0.0 8.56617 -1.90051 0.0 8.564 -1.883 0.0 8.56924 -1.85863 0.0 8.58393 -1.838 0.0 8.6065 -1.82038 0.0 8.63541 -1.805 0.0 8.6691 -1.79113 0.0 8.706 -1.778 0.0 8.442 -1.551 0.0 8.257 -1.551 0.0 8.20047 -1.55581 0.0 8.15241 -1.56985 0.0 8.11363 -1.5925 0.0 8.08493 -1.62315 0.0 8.06712 -1.66119 0.0 8.061 -1.706 0.0 8.06167 -1.72208 0.0 8.06367 -1.73733 0.0 8.067 -1.75175 0.0 8.07167 -1.76533 0.0 8.07767 -1.77808 0.0 8.085 -1.79 0.0 8.09417 -1.80158 0.0 8.10467 -1.81233 0.0 8.1165 -1.82225 0.0 8.12967 -1.83133 0.0 8.14417 -1.83958 0.0 8.16 -1.847 0.0 8.16 -1.849 0.0 8.13981 -1.8552 0.0 8.12248 -1.86359 0.0 8.10837 -1.87388 0.0 8.09785 -1.88574 0.0 8.09127 -1.89888 0.0 8.089 -1.913 0.0 8.09018 -1.92285 0.0 8.09378 -1.93244 0.0 8.09988 -1.94187 0.0 8.10856 -1.95122 0.0 8.1199 -1.96057 0.0 8.134 -1.97 0.0 8.09855 -1.9812 0.0 8.07004 -1.99593 0.0 8.04825 -2.01438 0.0 8.03296 -2.03674 0.0 8.02395 -2.06322 0.0 8.021 -2.094 0.0 8.02793 -2.1315 0.0 8.04778 -2.16437 0.0 8.07913 -2.19163 0.0 8.12056 -2.2123 0.0 8.17065 -2.22541 0.0 8.228 -2.23 0.0 8.28988 -2.22559 0.0 8.34207 -2.2127 0.0 8.38387 -2.19188 0.0 8.41459 -2.16363 0.0 8.43353 -2.1285 0.0 8.44 -2.087 0.0 8.43704 -2.05927 0.0 8.42763 -2.03348 0.0 8.411 -2.01025 0.0 8.38637 -1.99019 0.0 8.35296 -1.9739 0.0 8.31 -1.962 0.0 8.2686 -1.95319 0.0 8.23448 -1.94452 0.0 8.20775 -1.93563 0.0 8.18852 -1.92615 0.0 8.1769 -1.91573 0.0 8.173 -1.904 0.0 8.18232 -1.88375 0.0 8.20685 -1.87263 0.0 8.2415 -1.86563 0.0 8.28115 -1.8577 0.0 8.32069 -1.84384 0.0 8.355 -1.819 0.0 8.3654 -1.8068 0.0 8.37522 -1.7917 0.0 8.38388 -1.7745 0.0 8.39078 -1.75596 0.0 8.39535 -1.73687 0.0 8.397 -1.718 0.0 8.39595 -1.69998 0.0 8.39259 -1.68348 0.0 8.38663 -1.66787 0.0 8.37774 -1.65252 0.0 8.36563 -1.63677 0.0 8.35 -1.62 0.0 8.442 -1.62 0.0 8.317 -1.707 0.0 8.3141 -1.73024 0.0 8.30582 -1.75056 0.0 8.29275 -1.76738 0.0 8.27552 -1.78011 0.0 8.25473 -1.78818 0.0 8.231 -1.791 0.0 8.20558 -1.78833 0.0 8.18367 -1.78063 0.0 8.16575 -1.76838 0.0 8.15234 -1.75204 0.0 8.14392 -1.73209 0.0 8.141 -1.709 0.0 8.14419 -1.68772 0.0 8.15319 -1.66844 0.0 8.16713 -1.652 0.0 8.18515 -1.63922 0.0 8.20639 -1.63094 0.0 8.23 -1.628 0.0 8.25276 -1.63087 0.0 8.27345 -1.63893 0.0 8.29113 -1.65138 0.0 8.30489 -1.66741 0.0 8.31382 -1.68622 0.0 8.354 -2.094 0.0 8.35023 -2.11305 0.0 8.33919 -2.12907 0.0 8.32125 -2.14188 0.0 8.29681 -2.15126 0.0 8.26627 -2.15703 0.0 8.23 -2.159 0.0 8.19262 -2.15701 0.0 8.16159 -2.15111 0.0 8.13713 -2.14138 0.0 8.11941 -2.12789 0.0 8.10863 -2.11074 0.0 8.105 -2.09 0.0 8.10839 -2.07107 0.0 8.11811 -2.05459 0.0 8.1335 -2.041 0.0 8.15389 -2.03074 0.0 8.17861 -2.02426 0.0 8.207 -2.022 0.0 8.23699 -2.02338 0.0 8.26956 -2.028 0.0 8.30113 -2.03663 0.0 8.32811 -2.05 0.0 8.34693 -2.06888 0.0 7.956 -1.551 0.0 7.867 -1.551 0.0 7.867 -2.0 0.0 7.956 -2.0 0.0 7.965 -1.415 0.0 7.96309 -1.401 0.0 7.9577 -1.38837 0.0 7.94938 -1.37762 0.0 7.93863 -1.3693 0.0 7.926 -1.36391 0.0 7.912 -1.362 0.0 7.89801 -1.36391 0.0 7.88537 -1.3693 0.0 7.87463 -1.37762 0.0 7.8663 -1.38837 0.0 7.86091 -1.401 0.0 7.859 -1.415 0.0 7.86091 -1.429 0.0 7.8663 -1.44163 0.0 7.87463 -1.45238 0.0 7.88537 -1.4607 0.0 7.89801 -1.46609 0.0 7.912 -1.468 0.0 7.926 -1.46609 0.0 7.93863 -1.4607 0.0 7.94938 -1.45238 0.0 7.9577 -1.44163 0.0 7.96309 -1.429 0.0 7.57 -2.009 0.0 7.6 -2.009 0.0 7.798 -1.551 0.0 7.703 -1.551 0.0 7.585 -1.827 0.0 7.464 -1.551 0.0 7.367 -1.551 0.0 7.348 -1.92 0.0 7.3382 -1.92699 0.0 7.32893 -1.93289 0.0 7.32038 -1.93762 0.0 7.31274 -1.94111 0.0 7.30622 -1.94326 0.0 7.301 -1.944 0.0 7.29592 -1.94348 0.0 7.2917 -1.94181 0.0 7.28837 -1.93887 0.0 7.28596 -1.93452 0.0 7.2845 -1.92861 0.0 7.284 -1.921 0.0 7.284 -1.69 0.0 7.27825 -1.64362 0.0 7.26196 -1.6063 0.0 7.23663 -1.57775 0.0 7.2037 -1.5577 0.0 7.16467 -1.54588 0.0 7.121 -1.542 0.0 7.08982 -1.54367 0.0 7.06126 -1.5487 0.0 7.03525 -1.55712 0.0 7.01174 -1.56896 0.0 6.99068 -1.58425 0.0 6.972 -1.603 0.0 6.972 -1.7 0.0 6.99405 -1.67681 0.0 7.01704 -1.65815 0.0 7.04075 -1.64387 0.0 7.06496 -1.63385 0.0 7.08945 -1.62794 0.0 7.114 -1.626 0.0 7.13875 -1.62796 0.0 7.159 -1.63404 0.0 7.17475 -1.6445 0.0 7.186 -1.65963 0.0 7.19275 -1.6797 0.0 7.195 -1.705 0.0 7.195 -1.729 0.0 7.116 -1.757 0.0 7.07967 -1.77037 0.0 7.04433 -1.78559 0.0 7.0125 -1.80437 0.0 6.98667 -1.82841 0.0 6.96933 -1.85938 0.0 6.963 -1.899 0.0 6.96657 -1.92729 0.0 6.97685 -1.9533 0.0 6.99325 -1.97575 0.0 7.01515 -1.99337 0.0 7.04194 -2.00488 0.0 7.073 -2.009 0.0 7.09349 -2.00775 0.0 7.11393 -2.00396 0.0 7.13425 -1.99762 0.0 7.15441 -1.9887 0.0 7.17434 -1.97717 0.0 7.194 -1.963 0.0 7.19911 -1.97752 0.0 7.20652 -1.98915 0.0 7.21638 -1.998 0.0 7.22882 -2.00419 0.0 7.24398 -2.00781 0.0 7.262 -2.009 0.0 7.27525 -2.00828 0.0 7.28763 -2.00593 0.0 7.30013 -2.00162 0.0 7.3137 -1.99507 0.0 7.32934 -1.98597 0.0 7.348 -1.974 0.0 7.195 -1.909 0.0 7.18283 -1.91973 0.0 7.17033 -1.92881 0.0 7.1575 -1.93612 0.0 7.14433 -1.94152 0.0 7.13083 -1.94486 0.0 7.117 -1.946 0.0 7.09941 -1.9439 0.0 7.08396 -1.93789 0.0 7.07113 -1.92838 0.0 7.06137 -1.91578 0.0 7.05517 -1.90051 0.0 7.053 -1.883 0.0 7.05824 -1.85863 0.0 7.07293 -1.838 0.0 7.0955 -1.82038 0.0 7.12441 -1.805 0.0 7.15809 -1.79113 0.0 7.195 -1.778 0.0 6.587 -1.551 0.0 6.498 -1.551 0.0 6.498 -2.0 0.0 6.587 -2.0 0.0 6.587 -1.678 0.0 6.60717 -1.65687 0.0 6.62604 -1.64026 0.0 6.64412 -1.62787 0.0 6.66196 -1.61941 0.0 6.68008 -1.61455 0.0 6.699 -1.613 0.0 6.72427 -1.61649 0.0 6.74582 -1.62659 0.0 6.76325 -1.64275 0.0 6.77619 -1.66441 0.0 6.78423 -1.69101 0.0 6.787 -1.722 0.0 6.787 -2.0 0.0 6.876 -2.0 0.0 6.876 -1.723 0.0 6.87057 -1.66688 0.0 6.85522 -1.62141 0.0 6.83138 -1.58637 0.0 6.80044 -1.56159 0.0 6.76385 -1.54687 0.0 6.723 -1.542 0.0 6.69807 -1.54405 0.0 6.67359 -1.55007 0.0 6.65 -1.55987 0.0 6.62774 -1.57326 0.0 6.60726 -1.59003 0.0 6.589 -1.61 0.0 6.587 -1.61 0.0 5.88 -1.542 0.0 5.81592 -1.55 0.0 5.759 -1.5727 0.0 5.71125 -1.60812 0.0 5.67467 -1.6543 0.0 5.65125 -1.70925 0.0 5.643 -1.771 0.0 5.65097 -1.83655 0.0 5.67378 -1.89404 0.0 5.70975 -1.94175 0.0 5.75722 -1.97796 0.0 5.81453 -2.00095 0.0 5.88 -2.009 0.0 5.948 -2.00123 0.0 6.007 -1.97885 0.0 6.0555 -1.94325 0.0 6.092 -1.89581 0.0 6.115 -1.83794 0.0 6.123 -1.771 0.0 6.11479 -1.70786 0.0 6.09133 -1.65252 0.0 6.05438 -1.60662 0.0 6.00567 -1.57181 0.0 5.94696 -1.54973 0.0 5.879 -1.622 0.0 5.92124 -1.62707 0.0 5.95822 -1.64156 0.0 5.98888 -1.66437 0.0 6.01211 -1.69444 0.0 6.02685 -1.73068 0.0 6.032 -1.772 0.0 6.02719 -1.81731 0.0 6.01322 -1.85581 0.0 5.99075 -1.88687 0.0 5.96044 -1.90985 0.0 5.92297 -1.92411 0.0 5.879 -1.929 0.0 5.8384 -1.92389 0.0 5.80319 -1.90915 0.0 5.77425 -1.88563 0.0 5.75248 -1.85419 0.0 5.73877 -1.81569 0.0 5.734 -1.771 0.0 5.73891 -1.7301 0.0 5.75293 -1.69415 0.0 5.775 -1.66425 0.0 5.80407 -1.64152 0.0 5.83909 -1.62706 0.0 5.441 -1.458 0.0 5.274 -1.621 0.0 5.274 -1.631 0.0 5.352 -1.631 0.0 5.352 -1.868 0.0 5.35608 -1.90657 0.0 5.3683 -1.94056 0.0 5.38863 -1.96888 0.0 5.41704 -1.99044 0.0 5.4535 -2.00418 0.0 5.498 -2.009 0.0 5.51392 -2.00796 0.0 5.532 -2.005 0.0 5.55125 -2.00038 0.0 5.57067 -1.99433 0.0 5.58925 -1.98713 0.0 5.606 -1.979 0.0 5.606 -1.896 0.0 5.58824 -1.90608 0.0 5.57093 -1.91433 0.0 5.554 -1.92075 0.0 5.53741 -1.92533 0.0 5.52109 -1.92808 0.0 5.505 -1.929 0.0 5.49123 -1.92764 0.0 5.47685 -1.92315 0.0 5.46325 -1.91488 0.0 5.45182 -1.90219 0.0 5.44394 -1.88444 0.0 5.441 -1.861 0.0 5.441 -1.631 0.0 5.583 -1.631 0.0 5.583 -1.551 0.0 5.441 -1.551 0.0 4.935 -1.579 0.0 4.91182 -1.56758 0.0 4.88922 -1.5583 0.0 4.86713 -1.55112 0.0 4.84544 -1.54604 0.0 4.8241 -1.543 0.0 4.803 -1.542 0.0 4.76079 -1.54576 0.0 4.72463 -1.55674 0.0 4.69525 -1.5745 0.0 4.67337 -1.59859 0.0 4.65971 -1.62857 0.0 4.655 -1.664 0.0 4.67056 -1.71771 0.0 4.70944 -1.76 0.0 4.76 -1.79412 0.0 4.81056 -1.82333 0.0 4.84944 -1.85087 0.0 4.865 -1.88 0.0 4.86261 -1.89475 0.0 4.85589 -1.907 0.0 4.8455 -1.91675 0.0 4.83211 -1.924 0.0 4.81639 -1.92875 0.0 4.799 -1.931 0.0 4.77964 -1.92941 0.0 4.75778 -1.92459 0.0 4.73375 -1.9165 0.0 4.70789 -1.90507 0.0 4.68053 -1.89026 0.0 4.652 -1.872 0.0 4.652 -1.968 0.0 4.67987 -1.98145 0.0 4.706 -1.99196 0.0 4.73112 -1.99975 0.0 4.756 -2.00504 0.0 4.78137 -2.00805 0.0 4.808 -2.009 0.0 4.84848 -2.00471 0.0 4.88415 -1.99233 0.0 4.91388 -1.97262 0.0 4.93652 -1.94633 0.0 4.95094 -1.91421 0.0 4.956 -1.877 0.0 4.95366 -1.8551 0.0 4.94626 -1.83478 0.0 4.93325 -1.81512 0.0 4.91407 -1.79522 0.0 4.88818 -1.77415 0.0 4.855 -1.751 0.0 4.8195 -1.72975 0.0 4.79163 -1.71167 0.0 4.77087 -1.69625 0.0 4.7567 -1.683 0.0 4.74859 -1.67142 0.0 4.746 -1.661 0.0 4.74787 -1.64963 0.0 4.7533 -1.6397 0.0 4.762 -1.6315 0.0 4.7737 -1.6253 0.0 4.78813 -1.62137 0.0 4.805 -1.62 0.0 4.82262 -1.62119 0.0 4.84226 -1.62485 0.0 4.86363 -1.63112 0.0 4.88641 -1.64015 0.0 4.9103 -1.65206 0.0 4.935 -1.667 0.0 4.611 -1.551 0.0 4.511 -1.551 0.0 4.395 -1.804 0.0 4.274 -1.551 0.0 4.173 -1.551 0.0 4.347 -1.904 0.0 4.194 -2.23 0.0 4.293 -2.23 0.0 4.132 -1.87 0.0 4.10606 -1.88581 0.0 4.08018 -1.89911 0.0 4.05425 -1.90975 0.0 4.02815 -1.91756 0.0 4.00177 -1.92236 0.0 3.975 -1.924 0.0 3.93493 -1.92018 0.0 3.90074 -1.90878 0.0 3.8725 -1.88988 0.0 3.85026 -1.86356 0.0 3.83407 -1.8299 0.0 3.824 -1.789 0.0 4.14 -1.789 0.0 4.13382 -1.71306 0.0 4.11589 -1.65119 0.0 4.08712 -1.60325 0.0 4.04844 -1.56915 0.0 4.00076 -1.54877 0.0 3.945 -1.542 0.0 3.88639 -1.54944 0.0 3.83544 -1.57089 0.0 3.7935 -1.605 0.0 3.76189 -1.65044 0.0 3.74194 -1.70589 0.0 3.735 -1.77 0.0 3.74143 -1.83076 0.0 3.76041 -1.88707 0.0 3.7915 -1.936 0.0 3.83426 -1.97459 0.0 3.88824 -1.99991 0.0 3.953 -2.009 0.0 3.9889 -2.00757 0.0 4.02118 -2.00326 0.0 4.05075 -1.996 0.0 4.07848 -1.98574 0.0 4.10527 -1.97243 0.0 4.132 -1.956 0.0 3.826 -1.73 0.0 3.83441 -1.69712 0.0 3.84759 -1.66967 0.0 3.8655 -1.64787 0.0 3.88807 -1.632 0.0 3.91526 -1.62229 0.0 3.947 -1.619 0.0 3.97644 -1.6225 0.0 4.00156 -1.63267 0.0 4.022 -1.649 0.0 4.03744 -1.671 0.0 4.04756 -1.69817 0.0 4.052 -1.73 0.0 3.675 -1.551 0.0 3.569 -1.551 0.0 3.37 -1.771 0.0 3.595 -2.0 0.0 3.715 -2.0 0.0 3.483 -1.771 0.0 3.366 -1.318 0.0 3.277 -1.318 0.0 3.277 -2.0 0.0 3.366 -2.0 0.0 2.61 -1.551 0.0 2.61 -2.0 0.0 2.699 -2.0 0.0 2.699 -1.765 0.0 2.70284 -1.72804 0.0 2.7137 -1.695 0.0 2.73062 -1.66712 0.0 2.75263 -1.64567 0.0 2.77875 -1.63187 0.0 2.808 -1.627 0.0 2.81956 -1.62845 0.0 2.83285 -1.63263 0.0 2.84725 -1.63925 0.0 2.86215 -1.64804 0.0 2.87694 -1.65871 0.0 2.891 -1.671 0.0 2.938 -1.594 0.0 2.91973 -1.578 0.0 2.90181 -1.56496 0.0 2.88412 -1.55487 0.0 2.86652 -1.5477 0.0 2.84886 -1.54342 0.0 2.831 -1.542 0.0 2.80991 -1.54481 0.0 2.78863 -1.55348 0.0 2.76712 -1.56837 0.0 2.74537 -1.58985 0.0 2.72334 -1.61827 0.0 2.701 -1.654 0.0 2.699 -1.654 0.0 2.699 -1.551 0.0 2.262 -1.542 0.0 2.19792 -1.55 0.0 2.141 -1.5727 0.0 2.09325 -1.60812 0.0 2.05667 -1.6543 0.0 2.03325 -1.70925 0.0 2.025 -1.771 0.0 2.03297 -1.83655 0.0 2.05578 -1.89404 0.0 2.09175 -1.94175 0.0 2.13922 -1.97796 0.0 2.19653 -2.00095 0.0 2.262 -2.009 0.0 2.33 -2.00123 0.0 2.389 -1.97885 0.0 2.4375 -1.94325 0.0 2.474 -1.89581 0.0 2.497 -1.83794 0.0 2.505 -1.771 0.0 2.49679 -1.70786 0.0 2.47333 -1.65252 0.0 2.43637 -1.60662 0.0 2.38767 -1.57181 0.0 2.32896 -1.54973 0.0 2.261 -1.622 0.0 2.30324 -1.62707 0.0 2.34022 -1.64156 0.0 2.37087 -1.66437 0.0 2.39411 -1.69444 0.0 2.40885 -1.73068 0.0 2.414 -1.772 0.0 2.40919 -1.81731 0.0 2.39522 -1.85581 0.0 2.37275 -1.88687 0.0 2.34244 -1.90985 0.0 2.30497 -1.92411 0.0 2.261 -1.929 0.0 2.2204 -1.92389 0.0 2.18519 -1.90915 0.0 2.15625 -1.88563 0.0 2.13448 -1.85419 0.0 2.12077 -1.81569 0.0 2.116 -1.771 0.0 2.12091 -1.7301 0.0 2.13493 -1.69415 0.0 2.157 -1.66425 0.0 2.18607 -1.64152 0.0 2.22109 -1.62706 0.0 1.928 -1.579 0.0 1.90482 -1.56758 0.0 1.88222 -1.5583 0.0 1.86013 -1.55112 0.0 1.83844 -1.54604 0.0 1.8171 -1.543 0.0 1.796 -1.542 0.0 1.75379 -1.54576 0.0 1.71763 -1.55674 0.0 1.68825 -1.5745 0.0 1.66637 -1.59859 0.0 1.65271 -1.62857 0.0 1.648 -1.664 0.0 1.66356 -1.71771 0.0 1.70244 -1.76 0.0 1.753 -1.79412 0.0 1.80356 -1.82333 0.0 1.84244 -1.85087 0.0 1.858 -1.88 0.0 1.85561 -1.89475 0.0 1.84889 -1.907 0.0 1.8385 -1.91675 0.0 1.82511 -1.924 0.0 1.80939 -1.92875 0.0 1.792 -1.931 0.0 1.77264 -1.92941 0.0 1.75078 -1.92459 0.0 1.72675 -1.9165 0.0 1.70089 -1.90507 0.0 1.67353 -1.89026 0.0 1.645 -1.872 0.0 1.645 -1.968 0.0 1.67287 -1.98145 0.0 1.699 -1.99196 0.0 1.72412 -1.99975 0.0 1.749 -2.00504 0.0 1.77437 -2.00805 0.0 1.801 -2.009 0.0 1.84148 -2.00471 0.0 1.87715 -1.99233 0.0 1.90687 -1.97262 0.0 1.92952 -1.94633 0.0 1.94394 -1.91421 0.0 1.949 -1.877 0.0 1.94666 -1.8551 0.0 1.93926 -1.83478 0.0 1.92625 -1.81512 0.0 1.90707 -1.79522 0.0 1.88118 -1.77415 0.0 1.848 -1.751 0.0 1.8125 -1.72975 0.0 1.78463 -1.71167 0.0 1.76387 -1.69625 0.0 1.7497 -1.683 0.0 1.74159 -1.67142 0.0 1.739 -1.661 0.0 1.74087 -1.64963 0.0 1.7463 -1.6397 0.0 1.755 -1.6315 0.0 1.7667 -1.6253 0.0 1.78113 -1.62137 0.0 1.798 -1.62 0.0 1.81562 -1.62119 0.0 1.83526 -1.62485 0.0 1.85663 -1.63112 0.0 1.87941 -1.64015 0.0 1.9033 -1.65206 0.0 1.928 -1.667 0.0 1.277 -1.551 0.0 1.277 -2.0 0.0 1.366 -2.0 0.0 1.366 -1.765 0.0 1.36984 -1.72804 0.0 1.3807 -1.695 0.0 1.39762 -1.66712 0.0 1.41963 -1.64567 0.0 1.44575 -1.63187 0.0 1.475 -1.627 0.0 1.48656 -1.62845 0.0 1.49985 -1.63263 0.0 1.51425 -1.63925 0.0 1.52915 -1.64804 0.0 1.54394 -1.65871 0.0 1.558 -1.671 0.0 1.605 -1.594 0.0 1.58673 -1.578 0.0 1.56881 -1.56496 0.0 1.55112 -1.55487 0.0 1.53352 -1.5477 0.0 1.51586 -1.54342 0.0 1.498 -1.542 0.0 1.47691 -1.54481 0.0 1.45563 -1.55348 0.0 1.43412 -1.56837 0.0 1.41237 -1.58985 0.0 1.39034 -1.61827 0.0 1.368 -1.654 0.0 1.366 -1.654 0.0 1.366 -1.551 0.0 1.145 -2.0 0.0 1.145 -1.551 0.0 1.056 -1.551 0.0 1.056 -1.872 0.0 1.04078 -1.8909 0.0 1.02426 -1.90656 0.0 1.00662 -1.91887 0.0 0.98807 -1.92778 0.0 0.9688 -1.93318 0.0 0.949 -1.935 0.0 0.921 -1.93204 0.0 0.89804 -1.92333 0.0 0.88013 -1.90912 0.0 0.8673 -1.88967 0.0 0.85958 -1.86521 0.0 0.857 -1.836 0.0 0.857 -1.551 0.0 0.768 -1.551 0.0 0.768 -1.83 0.0 0.77316 -1.88284 0.0 0.78796 -1.92707 0.0 0.81138 -1.96225 0.0 0.84237 -1.98793 0.0 0.87992 -2.00366 0.0 0.923 -2.009 0.0 0.94556 -2.00689 0.0 0.96881 -2.00078 0.0 0.99212 -1.991 0.0 1.01485 -1.97789 0.0 1.03636 -1.96178 0.0 1.056 -1.943 0.0 1.056 -2.0 0.0 0.656 -1.365 0.0 0.61124 -1.34731 0.0 0.56956 -1.33315 0.0 0.53038 -1.32237 0.0 0.49311 -1.31485 0.0 0.45718 -1.31044 0.0 0.422 -1.309 0.0 0.31895 -1.32122 0.0 0.22859 -1.35611 0.0 0.15363 -1.411 0.0 0.09674 -1.48322 0.0 0.06063 -1.57011 0.0 0.048 -1.669 0.0 0.05748 -1.74384 0.0 0.08652 -1.8207 0.0 0.136 -1.89263 0.0 0.20681 -1.95263 0.0 0.29985 -1.99375 0.0 0.416 -2.009 0.0 0.4668 -2.00699 0.0 0.5127 -2.00122 0.0 0.5545 -1.99212 0.0 0.59296 -1.98011 0.0 0.62887 -1.9656 0.0 0.663 -1.949 0.0 0.663 -1.842 0.0 0.62398 -1.86506 0.0 0.58419 -1.88419 0.0 0.544 -1.89925 0.0 0.50381 -1.91015 0.0 0.46402 -1.91677 0.0 0.425 -1.919 0.0 0.34761 -1.91044 0.0 0.28056 -1.88585 0.0 0.2255 -1.84687 0.0 0.18411 -1.79515 0.0 0.15806 -1.73231 0.0 0.149 -1.66 0.0 0.15831 -1.58858 0.0 0.18485 -1.52567 0.0 0.2265 -1.47325 0.0 0.28115 -1.43333 0.0 0.34669 -1.40792 0.0 0.421 -1.399 0.0 0.46 -1.40086 0.0 0.49837 -1.40652 0.0 0.53663 -1.41612 0.0 0.5753 -1.42981 0.0 0.61491 -1.44773 0.0 0.656 -1.47 0.0 14.542 -0.458 0.0 14.375 -0.621 0.0 14.375 -0.631 0.0 14.453 -0.631 0.0 14.453 -0.868 0.0 14.45708 -0.90657 0.0 14.4693 -0.94056 0.0 14.48962 -0.96887 0.0 14.51804 -0.99044 0.0 14.5545 -1.00418 0.0 14.599 -1.009 0.0 14.61492 -1.00796 0.0 14.633 -1.005 0.0 14.65225 -1.00038 0.0 14.67167 -0.99433 0.0 14.69025 -0.98713 0.0 14.707 -0.979 0.0 14.707 -0.896 0.0 14.68924 -0.90608 0.0 14.67193 -0.91433 0.0 14.655 -0.92075 0.0 14.63841 -0.92533 0.0 14.62209 -0.92808 0.0 14.606 -0.929 0.0 14.59223 -0.92764 0.0 14.57785 -0.92315 0.0 14.56425 -0.91487 0.0 14.55281 -0.90219 0.0 14.54494 -0.88444 0.0 14.542 -0.861 0.0 14.542 -0.631 0.0 14.684 -0.631 0.0 14.684 -0.551 0.0 14.542 -0.551 0.0 14.096 -0.542 0.0 14.03192 -0.55 0.0 13.975 -0.5727 0.0 13.92725 -0.60812 0.0 13.89067 -0.6543 0.0 13.86725 -0.70925 0.0 13.859 -0.771 0.0 13.86697 -0.83655 0.0 13.88978 -0.89404 0.0 13.92575 -0.94175 0.0 13.97322 -0.97796 0.0 14.03053 -1.00095 0.0 14.096 -1.009 0.0 14.164 -1.00123 0.0 14.223 -0.97885 0.0 14.2715 -0.94325 0.0 14.308 -0.89581 0.0 14.331 -0.83794 0.0 14.339 -0.771 0.0 14.33079 -0.70786 0.0 14.30733 -0.65252 0.0 14.27037 -0.60662 0.0 14.22167 -0.57181 0.0 14.16296 -0.54973 0.0 14.095 -0.622 0.0 14.13724 -0.62707 0.0 14.17422 -0.64156 0.0 14.20488 -0.66438 0.0 14.22811 -0.69444 0.0 14.24285 -0.73068 0.0 14.248 -0.772 0.0 14.24319 -0.81731 0.0 14.22922 -0.85581 0.0 14.20675 -0.88688 0.0 14.17644 -0.90985 0.0 14.13897 -0.92411 0.0 14.095 -0.929 0.0 14.0544 -0.92389 0.0 14.01919 -0.90915 0.0 13.99025 -0.88563 0.0 13.96848 -0.85419 0.0 13.95477 -0.81569 0.0 13.95 -0.771 0.0 13.95491 -0.7301 0.0 13.96893 -0.69415 0.0 13.991 -0.66425 0.0 14.02007 -0.64152 0.0 14.05509 -0.62706 0.0 13.473 -0.318 0.0 13.384 -0.318 0.0 13.384 -1.0 0.0 13.473 -1.0 0.0 13.473 -0.678 0.0 13.49317 -0.65687 0.0 13.51204 -0.64026 0.0 13.53012 -0.62788 0.0 13.54796 -0.61941 0.0 13.56608 -0.61455 0.0 13.585 -0.613 0.0 13.61027 -0.61649 0.0 13.63181 -0.62659 0.0 13.64925 -0.64275 0.0 13.66219 -0.66441 0.0 13.67023 -0.69101 0.0 13.673 -0.722 0.0 13.673 -1.0 0.0 13.762 -1.0 0.0 13.762 -0.725 0.0 13.75678 -0.66874 0.0 13.74189 -0.62289 0.0 13.7185 -0.58737 0.0 13.68778 -0.56211 0.0 13.65089 -0.54701 0.0 13.609 -0.542 0.0 13.58407 -0.54405 0.0 13.55959 -0.55007 0.0 13.536 -0.55987 0.0 13.51374 -0.57326 0.0 13.49326 -0.59003 0.0 13.475 -0.61 0.0 13.473 -0.61 0.0 13.262 -0.579 0.0 13.23882 -0.56758 0.0 13.21622 -0.5583 0.0 13.19412 -0.55112 0.0 13.17244 -0.54604 0.0 13.1511 -0.543 0.0 13.13 -0.542 0.0 13.08779 -0.54576 0.0 13.05163 -0.55674 0.0 13.02225 -0.5745 0.0 13.00037 -0.59859 0.0 12.98671 -0.62857 0.0 12.982 -0.664 0.0 12.99755 -0.71771 0.0 13.03644 -0.76 0.0 13.087 -0.79412 0.0 13.13755 -0.82333 0.0 13.17644 -0.85088 0.0 13.192 -0.88 0.0 13.18961 -0.89475 0.0 13.18289 -0.907 0.0 13.1725 -0.91675 0.0 13.15911 -0.924 0.0 13.14339 -0.92875 0.0 13.126 -0.931 0.0 13.10664 -0.92941 0.0 13.08478 -0.92459 0.0 13.06075 -0.9165 0.0 13.03489 -0.90507 0.0 13.00753 -0.89026 0.0 12.979 -0.872 0.0 12.979 -0.968 0.0 13.00688 -0.98145 0.0 13.033 -0.99196 0.0 13.05812 -0.99975 0.0 13.083 -1.00504 0.0 13.10837 -1.00805 0.0 13.135 -1.009 0.0 13.17548 -1.00471 0.0 13.21115 -0.99233 0.0 13.24087 -0.97262 0.0 13.26352 -0.94633 0.0 13.27794 -0.91421 0.0 13.283 -0.877 0.0 13.28066 -0.8551 0.0 13.27326 -0.83478 0.0 13.26025 -0.81512 0.0 13.24107 -0.79522 0.0 13.21518 -0.77415 0.0 13.182 -0.751 0.0 13.1465 -0.72975 0.0 13.11863 -0.71167 0.0 13.09788 -0.69625 0.0 13.0837 -0.683 0.0 13.07559 -0.67142 0.0 13.073 -0.661 0.0 13.07487 -0.64963 0.0 13.0803 -0.6397 0.0 13.089 -0.6315 0.0 13.1007 -0.6253 0.0 13.11513 -0.62137 0.0 13.132 -0.62 0.0 13.14962 -0.62119 0.0 13.16926 -0.62485 0.0 13.19063 -0.63113 0.0 13.21341 -0.64015 0.0 13.2373 -0.65206 0.0 13.262 -0.667 0.0 12.66 -0.551 0.0 12.56 -0.551 0.0 12.444 -0.804 0.0 12.323 -0.551 0.0 12.222 -0.551 0.0 12.396 -0.904 0.0 12.243 -1.23 0.0 12.342 -1.23 0.0 12.157 -0.318 0.0 12.068 -0.318 0.0 12.068 -1.0 0.0 12.157 -1.0 0.0 11.649 -0.989 0.0 11.66546 -0.99534 0.0 11.681 -1.00041 0.0 11.69588 -1.00425 0.0 11.71033 -1.00693 0.0 11.72463 -1.00849 0.0 11.739 -1.009 0.0 11.80207 -1.00134 0.0 11.85722 -0.97937 0.0 11.90287 -0.94462 0.0 11.93744 -0.89863 0.0 11.95935 -0.84291 0.0 11.967 -0.779 0.0 11.95965 -0.71072 0.0 11.93785 -0.65411 0.0 11.902 -0.6095 0.0 11.85248 -0.57722 0.0 11.78969 -0.55761 0.0 11.714 -0.551 0.0 11.56 -0.551 0.0 11.56 -1.23 0.0 11.649 -1.23 0.0 11.649 -0.631 0.0 11.73 -0.631 0.0 11.7745 -0.63543 0.0 11.81096 -0.64844 0.0 11.83938 -0.66962 0.0 11.8597 -0.69856 0.0 11.87192 -0.73482 0.0 11.876 -0.778 0.0 11.87117 -0.81939 0.0 11.85737 -0.85581 0.0 11.83563 -0.88613 0.0 11.80696 -0.90919 0.0 11.77241 -0.92386 0.0 11.733 -0.929 0.0 11.71893 -0.92842 0.0 11.70478 -0.9267 0.0 11.69063 -0.92387 0.0 11.67656 -0.91996 0.0 11.66265 -0.915 0.0 11.649 -0.909 0.0 11.149 -0.989 0.0 11.16546 -0.99534 0.0 11.181 -1.00041 0.0 11.19588 -1.00425 0.0 11.21033 -1.00693 0.0 11.22463 -1.00849 0.0 11.239 -1.009 0.0 11.30207 -1.00134 0.0 11.35722 -0.97937 0.0 11.40287 -0.94462 0.0 11.43744 -0.89863 0.0 11.45935 -0.84291 0.0 11.467 -0.779 0.0 11.45965 -0.71072 0.0 11.43785 -0.65411 0.0 11.402 -0.6095 0.0 11.35248 -0.57722 0.0 11.28969 -0.55761 0.0 11.214 -0.551 0.0 11.06 -0.551 0.0 11.06 -1.23 0.0 11.149 -1.23 0.0 11.149 -0.631 0.0 11.23 -0.631 0.0 11.2745 -0.63543 0.0 11.31096 -0.64844 0.0 11.33938 -0.66962 0.0 11.3597 -0.69856 0.0 11.37192 -0.73482 0.0 11.376 -0.778 0.0 11.37117 -0.81939 0.0 11.35737 -0.85581 0.0 11.33563 -0.88613 0.0 11.30696 -0.90919 0.0 11.27241 -0.92386 0.0 11.233 -0.929 0.0 11.21893 -0.92842 0.0 11.20478 -0.9267 0.0 11.19063 -0.92387 0.0 11.17656 -0.91996 0.0 11.16265 -0.915 0.0 11.149 -0.909 0.0 10.987 -0.92 0.0 10.9772 -0.92699 0.0 10.96793 -0.93289 0.0 10.95938 -0.93762 0.0 10.95174 -0.94111 0.0 10.94522 -0.94326 0.0 10.94 -0.944 0.0 10.93492 -0.94348 0.0 10.9307 -0.94181 0.0 10.92737 -0.93888 0.0 10.92496 -0.93452 0.0 10.9235 -0.92861 0.0 10.923 -0.921 0.0 10.923 -0.69 0.0 10.91725 -0.64362 0.0 10.90096 -0.6063 0.0 10.87563 -0.57775 0.0 10.8427 -0.5577 0.0 10.80367 -0.54588 0.0 10.76 -0.542 0.0 10.72882 -0.54367 0.0 10.70026 -0.5487 0.0 10.67425 -0.55712 0.0 10.65074 -0.56896 0.0 10.62968 -0.58425 0.0 10.611 -0.603 0.0 10.611 -0.7 0.0 10.63305 -0.67681 0.0 10.65604 -0.65815 0.0 10.67975 -0.64387 0.0 10.70396 -0.63385 0.0 10.72845 -0.62794 0.0 10.753 -0.626 0.0 10.77775 -0.62796 0.0 10.798 -0.63404 0.0 10.81375 -0.6445 0.0 10.825 -0.65963 0.0 10.83175 -0.6797 0.0 10.834 -0.705 0.0 10.834 -0.729 0.0 10.755 -0.757 0.0 10.71867 -0.77037 0.0 10.68333 -0.78559 0.0 10.6515 -0.80437 0.0 10.62567 -0.82841 0.0 10.60833 -0.85938 0.0 10.602 -0.899 0.0 10.60557 -0.92729 0.0 10.61585 -0.9533 0.0 10.63225 -0.97575 0.0 10.65415 -0.99337 0.0 10.68094 -1.00488 0.0 10.712 -1.009 0.0 10.73249 -1.00775 0.0 10.75293 -1.00396 0.0 10.77325 -0.99762 0.0 10.79341 -0.9887 0.0 10.81334 -0.97717 0.0 10.833 -0.963 0.0 10.83811 -0.97752 0.0 10.84552 -0.98915 0.0 10.85538 -0.998 0.0 10.86782 -1.00419 0.0 10.88298 -1.00781 0.0 10.901 -1.009 0.0 10.91425 -1.00828 0.0 10.92663 -1.00593 0.0 10.93913 -1.00162 0.0 10.9527 -0.99507 0.0 10.96834 -0.98597 0.0 10.987 -0.974 0.0 10.834 -0.909 0.0 10.82183 -0.91973 0.0 10.80933 -0.92881 0.0 10.7965 -0.93613 0.0 10.78333 -0.94152 0.0 10.76983 -0.94486 0.0 10.756 -0.946 0.0 10.73841 -0.9439 0.0 10.72296 -0.93789 0.0 10.71012 -0.92838 0.0 10.70037 -0.91578 0.0 10.69417 -0.90051 0.0 10.692 -0.883 0.0 10.69724 -0.85862 0.0 10.71193 -0.838 0.0 10.7345 -0.82038 0.0 10.76341 -0.805 0.0 10.79709 -0.79112 0.0 10.834 -0.778 0.0 10.019 -0.542 0.0 9.95492 -0.55 0.0 9.898 -0.5727 0.0 9.85025 -0.60812 0.0 9.81367 -0.6543 0.0 9.79025 -0.70925 0.0 9.782 -0.771 0.0 9.78997 -0.83655 0.0 9.81278 -0.89404 0.0 9.84875 -0.94175 0.0 9.89622 -0.97796 0.0 9.95353 -1.00095 0.0 10.019 -1.009 0.0 10.087 -1.00123 0.0 10.146 -0.97885 0.0 10.1945 -0.94325 0.0 10.231 -0.89581 0.0 10.254 -0.83794 0.0 10.262 -0.771 0.0 10.25379 -0.70786 0.0 10.23033 -0.65252 0.0 10.19337 -0.60662 0.0 10.14467 -0.57181 0.0 10.08596 -0.54973 0.0 10.018 -0.622 0.0 10.06024 -0.62707 0.0 10.09722 -0.64156 0.0 10.12788 -0.66438 0.0 10.15111 -0.69444 0.0 10.16585 -0.73068 0.0 10.171 -0.772 0.0 10.16619 -0.81731 0.0 10.15222 -0.85581 0.0 10.12975 -0.88688 0.0 10.09944 -0.90985 0.0 10.06197 -0.92411 0.0 10.018 -0.929 0.0 9.9774 -0.92389 0.0 9.94219 -0.90915 0.0 9.91325 -0.88563 0.0 9.89148 -0.85419 0.0 9.87777 -0.81569 0.0 9.873 -0.771 0.0 9.87791 -0.7301 0.0 9.89193 -0.69415 0.0 9.914 -0.66425 0.0 9.94307 -0.64152 0.0 9.97809 -0.62706 0.0 9.58 -0.458 0.0 9.413 -0.621 0.0 9.413 -0.631 0.0 9.491 -0.631 0.0 9.491 -0.868 0.0 9.49508 -0.90657 0.0 9.5073 -0.94056 0.0 9.52763 -0.96887 0.0 9.55604 -0.99044 0.0 9.5925 -1.00418 0.0 9.637 -1.009 0.0 9.65292 -1.00796 0.0 9.671 -1.005 0.0 9.69025 -1.00038 0.0 9.70967 -0.99433 0.0 9.72825 -0.98713 0.0 9.745 -0.979 0.0 9.745 -0.896 0.0 9.72724 -0.90608 0.0 9.70993 -0.91433 0.0 9.693 -0.92075 0.0 9.67641 -0.92533 0.0 9.66009 -0.92808 0.0 9.644 -0.929 0.0 9.63023 -0.92764 0.0 9.61585 -0.92315 0.0 9.60225 -0.91487 0.0 9.59081 -0.90219 0.0 9.58294 -0.88444 0.0 9.58 -0.861 0.0 9.58 -0.631 0.0 9.722 -0.631 0.0 9.722 -0.551 0.0 9.58 -0.551 0.0 9.094 -0.87 0.0 9.06806 -0.88581 0.0 9.04218 -0.89911 0.0 9.01625 -0.90975 0.0 8.99015 -0.91756 0.0 8.96377 -0.92236 0.0 8.937 -0.924 0.0 8.89693 -0.92018 0.0 8.86274 -0.90878 0.0 8.8345 -0.88987 0.0 8.81226 -0.86356 0.0 8.79607 -0.8299 0.0 8.786 -0.789 0.0 9.102 -0.789 0.0 9.09582 -0.71306 0.0 9.07789 -0.65119 0.0 9.04912 -0.60325 0.0 9.01044 -0.56915 0.0 8.96276 -0.54877 0.0 8.907 -0.542 0.0 8.84839 -0.54944 0.0 8.79745 -0.57089 0.0 8.7555 -0.605 0.0 8.72389 -0.65044 0.0 8.70395 -0.70589 0.0 8.697 -0.77 0.0 8.70343 -0.83076 0.0 8.72241 -0.88707 0.0 8.7535 -0.936 0.0 8.79626 -0.97459 0.0 8.85024 -0.99991 0.0 8.915 -1.009 0.0 8.9509 -1.00757 0.0 8.98318 -1.00326 0.0 9.01275 -0.996 0.0 9.04048 -0.98574 0.0 9.06727 -0.97243 0.0 9.094 -0.956 0.0 8.788 -0.73 0.0 8.79641 -0.69713 0.0 8.80959 -0.66967 0.0 8.8275 -0.64787 0.0 8.85007 -0.632 0.0 8.87726 -0.62229 0.0 8.909 -0.619 0.0 8.93845 -0.6225 0.0 8.96356 -0.63267 0.0 8.984 -0.649 0.0 8.99944 -0.671 0.0 9.00956 -0.69817 0.0 9.014 -0.73 0.0 8.595 -0.579 0.0 8.57182 -0.56758 0.0 8.54922 -0.5583 0.0 8.52712 -0.55112 0.0 8.50544 -0.54604 0.0 8.4841 -0.543 0.0 8.463 -0.542 0.0 8.42079 -0.54576 0.0 8.38463 -0.55674 0.0 8.35525 -0.5745 0.0 8.33337 -0.59859 0.0 8.31971 -0.62857 0.0 8.315 -0.664 0.0 8.33055 -0.71771 0.0 8.36944 -0.76 0.0 8.42 -0.79412 0.0 8.47055 -0.82333 0.0 8.50944 -0.85088 0.0 8.525 -0.88 0.0 8.52261 -0.89475 0.0 8.51589 -0.907 0.0 8.5055 -0.91675 0.0 8.49211 -0.924 0.0 8.47639 -0.92875 0.0 8.459 -0.931 0.0 8.43964 -0.92941 0.0 8.41778 -0.92459 0.0 8.39375 -0.9165 0.0 8.36789 -0.90507 0.0 8.34053 -0.89026 0.0 8.312 -0.872 0.0 8.312 -0.968 0.0 8.33988 -0.98145 0.0 8.366 -0.99196 0.0 8.39112 -0.99975 0.0 8.416 -1.00504 0.0 8.44137 -1.00805 0.0 8.468 -1.009 0.0 8.50848 -1.00471 0.0 8.54415 -0.99233 0.0 8.57387 -0.97262 0.0 8.59652 -0.94633 0.0 8.61094 -0.91421 0.0 8.616 -0.877 0.0 8.61366 -0.8551 0.0 8.60626 -0.83478 0.0 8.59325 -0.81512 0.0 8.57407 -0.79522 0.0 8.54818 -0.77415 0.0 8.515 -0.751 0.0 8.4795 -0.72975 0.0 8.45163 -0.71167 0.0 8.43088 -0.69625 0.0 8.4167 -0.683 0.0 8.40859 -0.67142 0.0 8.406 -0.661 0.0 8.40787 -0.64963 0.0 8.4133 -0.6397 0.0 8.422 -0.6315 0.0 8.4337 -0.6253 0.0 8.44813 -0.62137 0.0 8.465 -0.62 0.0 8.48262 -0.62119 0.0 8.50226 -0.62485 0.0 8.52363 -0.63113 0.0 8.54641 -0.64015 0.0 8.5703 -0.65206 0.0 8.595 -0.667 0.0 8.208 -1.0 0.0 8.208 -0.551 0.0 8.119 -0.551 0.0 8.119 -0.872 0.0 8.10378 -0.8909 0.0 8.08726 -0.90656 0.0 8.06962 -0.91887 0.0 8.05107 -0.92778 0.0 8.0318 -0.93318 0.0 8.012 -0.935 0.0 7.984 -0.93204 0.0 7.96104 -0.92333 0.0 7.94313 -0.90912 0.0 7.9303 -0.88967 0.0 7.92258 -0.86521 0.0 7.92 -0.836 0.0 7.92 -0.551 0.0 7.831 -0.551 0.0 7.831 -0.83 0.0 7.83616 -0.88284 0.0 7.85096 -0.92707 0.0 7.87438 -0.96225 0.0 7.90537 -0.98793 0.0 7.94292 -1.00366 0.0 7.986 -1.009 0.0 8.00856 -1.00689 0.0 8.03182 -1.00078 0.0 8.05513 -0.991 0.0 8.07785 -0.97789 0.0 8.09936 -0.96178 0.0 8.119 -0.943 0.0 8.119 -1.0 0.0 7.492 -0.542 0.0 7.42792 -0.55 0.0 7.371 -0.5727 0.0 7.32325 -0.60812 0.0 7.28667 -0.6543 0.0 7.26325 -0.70925 0.0 7.255 -0.771 0.0 7.26297 -0.83655 0.0 7.28578 -0.89404 0.0 7.32175 -0.94175 0.0 7.36922 -0.97796 0.0 7.42653 -1.00095 0.0 7.492 -1.009 0.0 7.56 -1.00123 0.0 7.619 -0.97885 0.0 7.6675 -0.94325 0.0 7.704 -0.89581 0.0 7.727 -0.83794 0.0 7.735 -0.771 0.0 7.72679 -0.70786 0.0 7.70333 -0.65252 0.0 7.66638 -0.60662 0.0 7.61767 -0.57181 0.0 7.55896 -0.54973 0.0 7.491 -0.622 0.0 7.53324 -0.62707 0.0 7.57022 -0.64156 0.0 7.60088 -0.66438 0.0 7.62411 -0.69444 0.0 7.63885 -0.73068 0.0 7.644 -0.772 0.0 7.63919 -0.81731 0.0 7.62522 -0.85581 0.0 7.60275 -0.88688 0.0 7.57244 -0.90985 0.0 7.53497 -0.92411 0.0 7.491 -0.929 0.0 7.4504 -0.92389 0.0 7.41519 -0.90915 0.0 7.38625 -0.88563 0.0 7.36448 -0.85419 0.0 7.35077 -0.81569 0.0 7.346 -0.771 0.0 7.35091 -0.7301 0.0 7.36493 -0.69415 0.0 7.387 -0.66425 0.0 7.41607 -0.64152 0.0 7.45109 -0.62706 0.0 6.507 -0.551 0.0 6.507 -1.0 0.0 6.596 -1.0 0.0 6.596 -0.674 0.0 6.61402 -0.65485 0.0 6.63148 -0.64011 0.0 6.649 -0.62937 0.0 6.66719 -0.62222 0.0 6.68665 -0.61824 0.0 6.708 -0.617 0.0 6.72928 -0.61963 0.0 6.74856 -0.62774 0.0 6.765 -0.64162 0.0 6.77778 -0.66159 0.0 6.78606 -0.68795 0.0 6.789 -0.721 0.0 6.789 -1.0 0.0 6.878 -1.0 0.0 6.878 -0.674 0.0 6.89451 -0.65825 0.0 6.9117 -0.64433 0.0 6.92913 -0.63275 0.0 6.9463 -0.624 0.0 6.96275 -0.61858 0.0 6.978 -0.617 0.0 7.0026 -0.62006 0.0 7.02478 -0.62911 0.0 7.04363 -0.644 0.0 7.05822 -0.66456 0.0 7.06765 -0.69061 0.0 7.071 -0.722 0.0 7.071 -1.0 0.0 7.16 -1.0 0.0 7.16 -0.718 0.0 7.15528 -0.66816 0.0 7.14159 -0.62526 0.0 7.11963 -0.59025 0.0 7.09007 -0.56407 0.0 7.05363 -0.54768 0.0 7.011 -0.542 0.0 6.98038 -0.54494 0.0 6.95233 -0.55322 0.0 6.92663 -0.566 0.0 6.903 -0.58244 0.0 6.88121 -0.60172 0.0 6.861 -0.623 0.0 6.84462 -0.5986 0.0 6.82559 -0.57844 0.0 6.80413 -0.56262 0.0 6.78041 -0.55122 0.0 6.75463 -0.54432 0.0 6.727 -0.542 0.0 6.70591 -0.54384 0.0 6.68459 -0.54941 0.0 6.663 -0.55875 0.0 6.64107 -0.57193 0.0 6.61876 -0.58899 0.0 6.596 -0.61 0.0 6.596 -0.551 0.0 6.004 -0.458 0.0 5.837 -0.621 0.0 5.837 -0.631 0.0 5.915 -0.631 0.0 5.915 -0.868 0.0 5.91908 -0.90657 0.0 5.9313 -0.94056 0.0 5.95163 -0.96887 0.0 5.98004 -0.99044 0.0 6.0165 -1.00418 0.0 6.061 -1.009 0.0 6.07692 -1.00796 0.0 6.095 -1.005 0.0 6.11425 -1.00038 0.0 6.13367 -0.99433 0.0 6.15225 -0.98713 0.0 6.169 -0.979 0.0 6.169 -0.896 0.0 6.15124 -0.90608 0.0 6.13393 -0.91433 0.0 6.117 -0.92075 0.0 6.10041 -0.92533 0.0 6.08409 -0.92808 0.0 6.068 -0.929 0.0 6.05423 -0.92764 0.0 6.03985 -0.92315 0.0 6.02625 -0.91487 0.0 6.01482 -0.90219 0.0 6.00694 -0.88444 0.0 6.004 -0.861 0.0 6.004 -0.631 0.0 6.146 -0.631 0.0 6.146 -0.551 0.0 6.004 -0.551 0.0 5.883 -0.318 0.0 5.84619 -0.31024 0.0 5.81348 -0.30859 0.0 5.7845 -0.3125 0.0 5.75885 -0.32141 0.0 5.73615 -0.33476 0.0 5.716 -0.352 0.0 5.69928 -0.37069 0.0 5.68522 -0.39148 0.0 5.674 -0.4155 0.0 5.66578 -0.44385 0.0 5.66072 -0.47765 0.0 5.659 -0.518 0.0 5.659 -0.551 0.0 5.596 -0.551 0.0 5.596 -0.631 0.0 5.659 -0.631 0.0 5.659 -1.0 0.0 5.748 -1.0 0.0 5.748 -0.631 0.0 5.829 -0.631 0.0 5.829 -0.551 0.0 5.748 -0.551 0.0 5.748 -0.508 0.0 5.75004 -0.47582 0.0 5.75663 -0.44856 0.0 5.7685 -0.42662 0.0 5.78637 -0.41044 0.0 5.81096 -0.40043 0.0 5.843 -0.397 0.0 5.85048 -0.39718 0.0 5.85715 -0.39774 0.0 5.86338 -0.39875 0.0 5.86952 -0.40026 0.0 5.87594 -0.40232 0.0 5.883 -0.405 0.0 5.546 -0.87 0.0 5.52007 -0.88581 0.0 5.49419 -0.89911 0.0 5.46825 -0.90975 0.0 5.44215 -0.91756 0.0 5.41577 -0.92236 0.0 5.389 -0.924 0.0 5.34893 -0.92018 0.0 5.31474 -0.90878 0.0 5.2865 -0.88987 0.0 5.26426 -0.86356 0.0 5.24807 -0.8299 0.0 5.238 -0.789 0.0 5.554 -0.789 0.0 5.54782 -0.71306 0.0 5.52989 -0.65119 0.0 5.50113 -0.60325 0.0 5.46244 -0.56915 0.0 5.41476 -0.54877 0.0 5.359 -0.542 0.0 5.30039 -0.54944 0.0 5.24944 -0.57089 0.0 5.2075 -0.605 0.0 5.17589 -0.65044 0.0 5.15594 -0.70589 0.0 5.149 -0.77 0.0 5.15543 -0.83076 0.0 5.17441 -0.88707 0.0 5.2055 -0.936 0.0 5.24826 -0.97459 0.0 5.30224 -0.99991 0.0 5.367 -1.009 0.0 5.4029 -1.00757 0.0 5.43519 -1.00326 0.0 5.46475 -0.996 0.0 5.49248 -0.98574 0.0 5.51927 -0.97243 0.0 5.546 -0.956 0.0 5.24 -0.73 0.0 5.24841 -0.69713 0.0 5.26159 -0.66967 0.0 5.2795 -0.64787 0.0 5.30207 -0.632 0.0 5.32926 -0.62229 0.0 5.361 -0.619 0.0 5.39044 -0.6225 0.0 5.41556 -0.63267 0.0 5.436 -0.649 0.0 5.45144 -0.671 0.0 5.46156 -0.69817 0.0 5.466 -0.73 0.0 5.043 -0.318 0.0 4.954 -0.318 0.0 4.954 -1.0 0.0 5.043 -1.0 0.0 4.451 -1.118 0.0 4.4871 -1.10365 0.0 4.51645 -1.08356 0.0 4.53913 -1.05913 0.0 4.55522 -1.03178 0.0 4.56482 -1.00293 0.0 4.568 -0.974 0.0 4.56573 -0.94633 0.0 4.55915 -0.92263 0.0 4.54863 -0.90338 0.0 4.53452 -0.88904 0.0 4.51719 -0.88009 0.0 4.497 -0.877 0.0 4.48082 -0.87893 0.0 4.46659 -0.88444 0.0 4.45475 -0.89312 0.0 4.44574 -0.90456 0.0 4.44001 -0.91832 0.0 4.438 -0.934 0.0 4.43962 -0.94954 0.0 4.44426 -0.96296 0.0 4.45163 -0.974 0.0 4.46141 -0.98237 0.0 4.4733 -0.9878 0.0 4.487 -0.99 0.0 4.48975 -1.00905 0.0 4.489 -1.02937 0.0 4.48475 -1.04975 0.0 4.477 -1.06896 0.0 4.46575 -1.08579 0.0 4.451 -1.099 0.0 3.68 -0.551 0.0 3.68 -1.0 0.0 3.769 -1.0 0.0 3.769 -0.674 0.0 3.78702 -0.65485 0.0 3.80448 -0.64011 0.0 3.822 -0.62937 0.0 3.84019 -0.62222 0.0 3.85965 -0.61824 0.0 3.881 -0.617 0.0 3.90228 -0.61963 0.0 3.92156 -0.62774 0.0 3.938 -0.64162 0.0 3.95078 -0.66159 0.0 3.95906 -0.68795 0.0 3.962 -0.721 0.0 3.962 -1.0 0.0 4.051 -1.0 0.0 4.051 -0.674 0.0 4.06751 -0.65825 0.0 4.0847 -0.64433 0.0 4.10213 -0.63275 0.0 4.1193 -0.624 0.0 4.13575 -0.61858 0.0 4.151 -0.617 0.0 4.1756 -0.62006 0.0 4.19778 -0.62911 0.0 4.21663 -0.644 0.0 4.23122 -0.66456 0.0 4.24065 -0.69061 0.0 4.244 -0.722 0.0 4.244 -1.0 0.0 4.333 -1.0 0.0 4.333 -0.718 0.0 4.32828 -0.66816 0.0 4.31459 -0.62526 0.0 4.29263 -0.59025 0.0 4.26307 -0.56407 0.0 4.22663 -0.54768 0.0 4.184 -0.542 0.0 4.15338 -0.54494 0.0 4.12533 -0.55322 0.0 4.09963 -0.566 0.0 4.076 -0.58244 0.0 4.05421 -0.60172 0.0 4.034 -0.623 0.0 4.01762 -0.5986 0.0 3.99859 -0.57844 0.0 3.97713 -0.56262 0.0 3.95341 -0.55122 0.0 3.92763 -0.54432 0.0 3.9 -0.542 0.0 3.87891 -0.54384 0.0 3.85759 -0.54941 0.0 3.836 -0.55875 0.0 3.81407 -0.57193 0.0 3.79176 -0.58899 0.0 3.769 -0.61 0.0 3.769 -0.551 0.0 3.556 -0.551 0.0 3.467 -0.551 0.0 3.467 -1.0 0.0 3.556 -1.0 0.0 3.565 -0.415 0.0 3.56309 -0.401 0.0 3.5577 -0.38837 0.0 3.54938 -0.37762 0.0 3.53863 -0.3693 0.0 3.526 -0.36391 0.0 3.512 -0.362 0.0 3.498 -0.36391 0.0 3.48537 -0.3693 0.0 3.47463 -0.37762 0.0 3.4663 -0.38837 0.0 3.46091 -0.401 0.0 3.459 -0.415 0.0 3.46091 -0.429 0.0 3.4663 -0.44163 0.0 3.47463 -0.45237 0.0 3.48537 -0.4607 0.0 3.498 -0.46609 0.0 3.512 -0.468 0.0 3.526 -0.46609 0.0 3.53863 -0.4607 0.0 3.54938 -0.45237 0.0 3.5577 -0.44163 0.0 3.56309 -0.429 0.0 3.386 -0.92 0.0 3.3762 -0.92699 0.0 3.36693 -0.93289 0.0 3.35838 -0.93762 0.0 3.35074 -0.94111 0.0 3.34422 -0.94326 0.0 3.339 -0.944 0.0 3.33392 -0.94348 0.0 3.3297 -0.94181 0.0 3.32638 -0.93888 0.0 3.32396 -0.93452 0.0 3.3225 -0.92861 0.0 3.322 -0.921 0.0 3.322 -0.69 0.0 3.31625 -0.64362 0.0 3.29996 -0.6063 0.0 3.27463 -0.57775 0.0 3.2417 -0.5577 0.0 3.20267 -0.54588 0.0 3.159 -0.542 0.0 3.12782 -0.54367 0.0 3.09926 -0.5487 0.0 3.07325 -0.55712 0.0 3.04974 -0.56896 0.0 3.02868 -0.58425 0.0 3.01 -0.603 0.0 3.01 -0.7 0.0 3.03205 -0.67681 0.0 3.05504 -0.65815 0.0 3.07875 -0.64387 0.0 3.10296 -0.63385 0.0 3.12745 -0.62794 0.0 3.152 -0.626 0.0 3.17675 -0.62796 0.0 3.197 -0.63404 0.0 3.21275 -0.6445 0.0 3.224 -0.65963 0.0 3.23075 -0.6797 0.0 3.233 -0.705 0.0 3.233 -0.729 0.0 3.154 -0.757 0.0 3.11767 -0.77037 0.0 3.08233 -0.78559 0.0 3.0505 -0.80437 0.0 3.02467 -0.82841 0.0 3.00733 -0.85938 0.0 3.001 -0.899 0.0 3.00457 -0.92729 0.0 3.01485 -0.9533 0.0 3.03125 -0.97575 0.0 3.05315 -0.99337 0.0 3.07994 -1.00488 0.0 3.111 -1.009 0.0 3.13149 -1.00775 0.0 3.15193 -1.00396 0.0 3.17225 -0.99762 0.0 3.19241 -0.9887 0.0 3.21234 -0.97717 0.0 3.232 -0.963 0.0 3.23711 -0.97752 0.0 3.24452 -0.98915 0.0 3.25438 -0.998 0.0 3.26681 -1.00419 0.0 3.28198 -1.00781 0.0 3.3 -1.009 0.0 3.31325 -1.00828 0.0 3.32563 -1.00593 0.0 3.33813 -1.00162 0.0 3.3517 -0.99507 0.0 3.36734 -0.98597 0.0 3.386 -0.974 0.0 3.233 -0.909 0.0 3.22083 -0.91973 0.0 3.20833 -0.92881 0.0 3.1955 -0.93613 0.0 3.18233 -0.94152 0.0 3.16883 -0.94486 0.0 3.155 -0.946 0.0 3.13741 -0.9439 0.0 3.12196 -0.93789 0.0 3.10913 -0.92838 0.0 3.09937 -0.91578 0.0 3.09317 -0.90051 0.0 3.091 -0.883 0.0 3.09624 -0.85862 0.0 3.11093 -0.838 0.0 3.1335 -0.82038 0.0 3.16241 -0.805 0.0 3.19609 -0.79112 0.0 3.233 -0.778 0.0 2.656 -0.87 0.0 2.63006 -0.88581 0.0 2.60419 -0.89911 0.0 2.57825 -0.90975 0.0 2.55215 -0.91756 0.0 2.52577 -0.92236 0.0 2.499 -0.924 0.0 2.45893 -0.92018 0.0 2.42474 -0.90878 0.0 2.3965 -0.88987 0.0 2.37426 -0.86356 0.0 2.35807 -0.8299 0.0 2.348 -0.789 0.0 2.664 -0.789 0.0 2.65782 -0.71306 0.0 2.63989 -0.65119 0.0 2.61113 -0.60325 0.0 2.57244 -0.56915 0.0 2.52476 -0.54877 0.0 2.469 -0.542 0.0 2.41039 -0.54944 0.0 2.35944 -0.57089 0.0 2.3175 -0.605 0.0 2.28589 -0.65044 0.0 2.26594 -0.70589 0.0 2.259 -0.77 0.0 2.26543 -0.83076 0.0 2.28441 -0.88707 0.0 2.3155 -0.936 0.0 2.35826 -0.97459 0.0 2.41224 -0.99991 0.0 2.477 -1.009 0.0 2.5129 -1.00757 0.0 2.54519 -1.00326 0.0 2.57475 -0.996 0.0 2.60248 -0.98574 0.0 2.62927 -0.97243 0.0 2.656 -0.956 0.0 2.35 -0.73 0.0 2.35841 -0.69713 0.0 2.37159 -0.66967 0.0 2.3895 -0.64787 0.0 2.41207 -0.632 0.0 2.43926 -0.62229 0.0 2.471 -0.619 0.0 2.50044 -0.6225 0.0 2.52556 -0.63267 0.0 2.546 -0.649 0.0 2.56144 -0.671 0.0 2.57156 -0.69817 0.0 2.576 -0.73 0.0 2.157 -0.579 0.0 2.13382 -0.56758 0.0 2.11122 -0.5583 0.0 2.08913 -0.55112 0.0 2.06744 -0.54604 0.0 2.0461 -0.543 0.0 2.025 -0.542 0.0 1.98279 -0.54576 0.0 1.94663 -0.55674 0.0 1.91725 -0.5745 0.0 1.89537 -0.59859 0.0 1.88171 -0.62857 0.0 1.877 -0.664 0.0 1.89256 -0.71771 0.0 1.93144 -0.76 0.0 1.982 -0.79412 0.0 2.03256 -0.82333 0.0 2.07144 -0.85088 0.0 2.087 -0.88 0.0 2.08461 -0.89475 0.0 2.07789 -0.907 0.0 2.0675 -0.91675 0.0 2.05411 -0.924 0.0 2.03839 -0.92875 0.0 2.021 -0.931 0.0 2.00164 -0.92941 0.0 1.97978 -0.92459 0.0 1.95575 -0.9165 0.0 1.92989 -0.90507 0.0 1.90253 -0.89026 0.0 1.874 -0.872 0.0 1.874 -0.968 0.0 1.90188 -0.98145 0.0 1.928 -0.99196 0.0 1.95313 -0.99975 0.0 1.978 -1.00504 0.0 2.00337 -1.00805 0.0 2.03 -1.009 0.0 2.07048 -1.00471 0.0 2.10615 -0.99233 0.0 2.13587 -0.97262 0.0 2.15852 -0.94633 0.0 2.17294 -0.91421 0.0 2.178 -0.877 0.0 2.17566 -0.8551 0.0 2.16826 -0.83478 0.0 2.15525 -0.81512 0.0 2.13607 -0.79522 0.0 2.11018 -0.77415 0.0 2.077 -0.751 0.0 2.0415 -0.72975 0.0 2.01363 -0.71167 0.0 1.99288 -0.69625 0.0 1.9787 -0.683 0.0 1.97059 -0.67142 0.0 1.968 -0.661 0.0 1.96987 -0.64963 0.0 1.9753 -0.6397 0.0 1.984 -0.6315 0.0 1.9957 -0.6253 0.0 2.01013 -0.62137 0.0 2.027 -0.62 0.0 2.04462 -0.62119 0.0 2.06426 -0.62485 0.0 2.08562 -0.63113 0.0 2.10841 -0.64015 0.0 2.1323 -0.65206 0.0 2.157 -0.667 0.0 1.77 -1.0 0.0 1.77 -0.551 0.0 1.681 -0.551 0.0 1.681 -0.872 0.0 1.66578 -0.8909 0.0 1.64926 -0.90656 0.0 1.63163 -0.91887 0.0 1.61307 -0.92778 0.0 1.5938 -0.93318 0.0 1.574 -0.935 0.0 1.546 -0.93204 0.0 1.52304 -0.92333 0.0 1.50513 -0.90912 0.0 1.4923 -0.88967 0.0 1.48458 -0.86521 0.0 1.482 -0.836 0.0 1.482 -0.551 0.0 1.393 -0.551 0.0 1.393 -0.83 0.0 1.39816 -0.88284 0.0 1.41296 -0.92707 0.0 1.43638 -0.96225 0.0 1.46737 -0.98793 0.0 1.50492 -1.00366 0.0 1.548 -1.009 0.0 1.57056 -1.00689 0.0 1.59381 -1.00078 0.0 1.61713 -0.991 0.0 1.63985 -0.97789 0.0 1.66136 -0.96178 0.0 1.681 -0.943 0.0 1.681 -1.0 0.0 1.054 -0.542 0.0 0.98992 -0.55 0.0 0.933 -0.5727 0.0 0.88525 -0.60812 0.0 0.84867 -0.6543 0.0 0.82525 -0.70925 0.0 0.817 -0.771 0.0 0.82497 -0.83655 0.0 0.84778 -0.89404 0.0 0.88375 -0.94175 0.0 0.93122 -0.97796 0.0 0.98853 -1.00095 0.0 1.054 -1.009 0.0 1.122 -1.00123 0.0 1.181 -0.97885 0.0 1.2295 -0.94325 0.0 1.266 -0.89581 0.0 1.289 -0.83794 0.0 1.297 -0.771 0.0 1.28879 -0.70786 0.0 1.26533 -0.65252 0.0 1.22838 -0.60662 0.0 1.17967 -0.57181 0.0 1.12096 -0.54973 0.0 1.053 -0.622 0.0 1.09524 -0.62707 0.0 1.13222 -0.64156 0.0 1.16288 -0.66438 0.0 1.18611 -0.69444 0.0 1.20085 -0.73068 0.0 1.206 -0.772 0.0 1.20119 -0.81731 0.0 1.18722 -0.85581 0.0 1.16475 -0.88688 0.0 1.13444 -0.90985 0.0 1.09697 -0.92411 0.0 1.053 -0.929 0.0 1.0124 -0.92389 0.0 0.97719 -0.90915 0.0 0.94825 -0.88563 0.0 0.92648 -0.85419 0.0 0.91277 -0.81569 0.0 0.908 -0.771 0.0 0.91291 -0.7301 0.0 0.92693 -0.69415 0.0 0.949 -0.66425 0.0 0.97807 -0.64152 0.0 1.01309 -0.62706 0.0 0.709 -0.318 0.0 0.618 -0.318 0.0 0.391 -0.598 0.0 0.165 -0.318 0.0 0.073 -0.318 0.0 0.073 -1.0 0.0 0.171 -1.0 0.0 0.171 -0.469 0.0 0.173 -0.469 0.0 0.383 -0.733 0.0 0.399 -0.733 0.0 0.609 -0.469 0.0 0.611 -0.469 0.0 0.611 -1.0 0.0 0.709 -1.0 0.0 7.379 0.542 0.0 7.212 0.379 0.0 7.212 0.369 0.0 7.29 0.369 0.0 7.29 0.132 0.0 7.29408 0.09343 0.0 7.3063 0.05944 0.0 7.32663 0.03112 0.0 7.35504 0.00956 0.0 7.39151 -0.00418 0.0 7.436 -0.009 0.0 7.45192 -0.00796 0.0 7.47 -0.005 0.0 7.48925 -0.00038 0.0 7.50867 0.00567 0.0 7.52725 0.01288 0.0 7.544 0.021 0.0 7.544 0.104 0.0 7.52624 0.09392 0.0 7.50893 0.08567 0.0 7.492 0.07925 0.0 7.47541 0.07467 0.0 7.45909 0.07192 0.0 7.443 0.071 0.0 7.42923 0.07236 0.0 7.41485 0.07685 0.0 7.40125 0.08513 0.0 7.38982 0.09781 0.0 7.38194 0.11556 0.0 7.379 0.139 0.0 7.379 0.369 0.0 7.521 0.369 0.0 7.521 0.449 0.0 7.379 0.449 0.0 7.151 0.421 0.0 7.12782 0.43242 0.0 7.10522 0.4417 0.0 7.08313 0.44888 0.0 7.06145 0.45396 0.0 7.0401 0.457 0.0 7.019 0.458 0.0 6.97679 0.45424 0.0 6.94063 0.44326 0.0 6.91125 0.4255 0.0 6.88937 0.40141 0.0 6.87571 0.37143 0.0 6.871 0.336 0.0 6.88656 0.28229 0.0 6.92545 0.24 0.0 6.976 0.20588 0.0 7.02656 0.17667 0.0 7.06545 0.14913 0.0 7.081 0.12 0.0 7.07861 0.10525 0.0 7.07189 0.093 0.0 7.0615 0.08325 0.0 7.04811 0.076 0.0 7.03239 0.07125 0.0 7.015 0.069 0.0 6.99564 0.07059 0.0 6.97378 0.07541 0.0 6.94975 0.0835 0.0 6.92389 0.09493 0.0 6.89653 0.10974 0.0 6.868 0.128 0.0 6.868 0.032 0.0 6.89588 0.01855 0.0 6.922 0.00804 0.0 6.94713 0.00025 0.0 6.972 -0.00504 0.0 6.99738 -0.00805 0.0 7.024 -0.009 0.0 7.06448 -0.00471 0.0 7.10015 0.00767 0.0 7.12988 0.02737 0.0 7.15252 0.05367 0.0 7.16694 0.08579 0.0 7.172 0.123 0.0 7.16966 0.1449 0.0 7.16226 0.16522 0.0 7.14925 0.18488 0.0 7.13007 0.20478 0.0 7.10418 0.22585 0.0 7.071 0.249 0.0 7.0355 0.27025 0.0 7.00763 0.28833 0.0 6.98688 0.30375 0.0 6.9727 0.317 0.0 6.96459 0.32858 0.0 6.962 0.339 0.0 6.96387 0.35037 0.0 6.9693 0.3603 0.0 6.978 0.3685 0.0 6.9897 0.3747 0.0 7.00413 0.37863 0.0 7.021 0.38 0.0 7.03862 0.37881 0.0 7.05826 0.37515 0.0 7.07963 0.36887 0.0 7.10241 0.35985 0.0 7.1263 0.34794 0.0 7.151 0.333 0.0 6.786 0.13 0.0 6.76007 0.11419 0.0 6.73419 0.10089 0.0 6.70825 0.09025 0.0 6.68215 0.08244 0.0 6.65577 0.07764 0.0 6.629 0.076 0.0 6.58893 0.07982 0.0 6.55474 0.09122 0.0 6.5265 0.11013 0.0 6.50426 0.13644 0.0 6.48807 0.1701 0.0 6.478 0.211 0.0 6.794 0.211 0.0 6.78782 0.28694 0.0 6.76989 0.34881 0.0 6.74113 0.39675 0.0 6.70245 0.43085 0.0 6.65476 0.45123 0.0 6.599 0.458 0.0 6.54039 0.45056 0.0 6.48945 0.42911 0.0 6.4475 0.395 0.0 6.41589 0.34956 0.0 6.39595 0.29411 0.0 6.389 0.23 0.0 6.39543 0.16924 0.0 6.41441 0.11293 0.0 6.4455 0.064 0.0 6.48826 0.02541 0.0 6.54224 9e-05 0.0 6.607 -0.009 0.0 6.6429 -0.00757 0.0 6.67519 -0.00326 0.0 6.70475 0.004 0.0 6.73248 0.01426 0.0 6.75927 0.02757 0.0 6.786 0.044 0.0 6.48 0.27 0.0 6.48841 0.30288 0.0 6.50159 0.33033 0.0 6.5195 0.35213 0.0 6.54207 0.368 0.0 6.56926 0.37771 0.0 6.601 0.381 0.0 6.63045 0.3775 0.0 6.65556 0.36733 0.0 6.676 0.351 0.0 6.69144 0.329 0.0 6.70156 0.30183 0.0 6.706 0.27 0.0 6.331 0.682 0.0 5.761 0.682 0.0 5.761 0.594 0.0 5.997 0.594 0.0 5.997 0.0 0.0 6.095 0.0 0.0 6.095 0.594 0.0 6.331 0.594 0.0 5.405 0.421 0.0 5.38182 0.43242 0.0 5.35922 0.4417 0.0 5.33713 0.44888 0.0 5.31544 0.45396 0.0 5.2941 0.457 0.0 5.273 0.458 0.0 5.23079 0.45424 0.0 5.19463 0.44326 0.0 5.16525 0.4255 0.0 5.14337 0.40141 0.0 5.12971 0.37143 0.0 5.125 0.336 0.0 5.14056 0.28229 0.0 5.17944 0.24 0.0 5.23 0.20588 0.0 5.28056 0.17667 0.0 5.31945 0.14913 0.0 5.335 0.12 0.0 5.33261 0.10525 0.0 5.32589 0.093 0.0 5.3155 0.08325 0.0 5.30211 0.076 0.0 5.28639 0.07125 0.0 5.269 0.069 0.0 5.24964 0.07059 0.0 5.22778 0.07541 0.0 5.20375 0.0835 0.0 5.17789 0.09493 0.0 5.15053 0.10974 0.0 5.122 0.128 0.0 5.122 0.032 0.0 5.14988 0.01855 0.0 5.176 0.00804 0.0 5.20113 0.00025 0.0 5.226 -0.00504 0.0 5.25138 -0.00805 0.0 5.278 -0.009 0.0 5.31848 -0.00471 0.0 5.35415 0.00767 0.0 5.38388 0.02737 0.0 5.40652 0.05367 0.0 5.42094 0.08579 0.0 5.426 0.123 0.0 5.42366 0.1449 0.0 5.41626 0.16522 0.0 5.40325 0.18488 0.0 5.38407 0.20478 0.0 5.35818 0.22585 0.0 5.325 0.249 0.0 5.2895 0.27025 0.0 5.26163 0.28833 0.0 5.24088 0.30375 0.0 5.2267 0.317 0.0 5.21859 0.32858 0.0 5.216 0.339 0.0 5.21787 0.35037 0.0 5.2233 0.3603 0.0 5.232 0.3685 0.0 5.2437 0.3747 0.0 5.25813 0.37863 0.0 5.275 0.38 0.0 5.29262 0.37881 0.0 5.31226 0.37515 0.0 5.33363 0.36887 0.0 5.35641 0.35985 0.0 5.3803 0.34794 0.0 5.405 0.333 0.0 5.036 0.427 0.0 5.01505 0.43589 0.0 4.99474 0.44348 0.0 4.97437 0.44963 0.0 4.95326 0.45419 0.0 4.9307 0.45702 0.0 4.906 0.458 0.0 4.84233 0.45035 0.0 4.788 0.42815 0.0 4.744 0.3925 0.0 4.71133 0.34452 0.0 4.691 0.28531 0.0 4.684 0.216 0.0 4.69158 0.1535 0.0 4.71333 0.099 0.0 4.74775 0.054 0.0 4.79333 0.02 0.0 4.84858 -0.0015 0.0 4.912 -0.009 0.0 4.93616 -0.00805 0.0 4.96096 -0.00537 0.0 4.98537 -0.00125 0.0 5.00837 0.00404 0.0 5.02892 0.01021 0.0 5.046 0.017 0.0 5.046 0.105 0.0 5.0242 0.09583 0.0 5.00359 0.08833 0.0 4.98387 0.0825 0.0 4.96474 0.07833 0.0 4.94588 0.07583 0.0 4.927 0.075 0.0 4.8838 0.07958 0.0 4.8467 0.09296 0.0 4.8165 0.11463 0.0 4.79396 0.14404 0.0 4.77987 0.18067 0.0 4.775 0.224 0.0 4.77952 0.26686 0.0 4.79252 0.30385 0.0 4.81313 0.33413 0.0 4.84048 0.35681 0.0 4.87373 0.37106 0.0 4.912 0.376 0.0 4.93119 0.3751 0.0 4.95015 0.37215 0.0 4.9695 0.36675 0.0 4.98985 0.35852 0.0 5.01182 0.34706 0.0 5.036 0.332 0.0 4.578 0.449 0.0 4.489 0.449 0.0 4.489 0.0 0.0 4.578 0.0 0.0 4.587 0.585 0.0 4.58509 0.599 0.0 4.5797 0.61163 0.0 4.57137 0.62238 0.0 4.56063 0.6307 0.0 4.548 0.63609 0.0 4.534 0.638 0.0 4.52 0.63609 0.0 4.50737 0.6307 0.0 4.49662 0.62238 0.0 4.4883 0.61163 0.0 4.48291 0.599 0.0 4.481 0.585 0.0 4.48291 0.571 0.0 4.4883 0.55837 0.0 4.49663 0.54763 0.0 4.50737 0.5393 0.0 4.52001 0.53391 0.0 4.534 0.532 0.0 4.548 0.53391 0.0 4.56063 0.5393 0.0 4.57138 0.54763 0.0 4.5797 0.55837 0.0 4.58509 0.571 0.0 4.363 0.421 0.0 4.33982 0.43242 0.0 4.31722 0.4417 0.0 4.29513 0.44888 0.0 4.27344 0.45396 0.0 4.2521 0.457 0.0 4.231 0.458 0.0 4.18879 0.45424 0.0 4.15263 0.44326 0.0 4.12325 0.4255 0.0 4.10137 0.40141 0.0 4.08771 0.37143 0.0 4.083 0.336 0.0 4.09856 0.28229 0.0 4.13744 0.24 0.0 4.188 0.20588 0.0 4.23856 0.17667 0.0 4.27744 0.14913 0.0 4.293 0.12 0.0 4.29061 0.10525 0.0 4.28389 0.093 0.0 4.2735 0.08325 0.0 4.26011 0.076 0.0 4.24439 0.07125 0.0 4.227 0.069 0.0 4.20764 0.07059 0.0 4.18578 0.07541 0.0 4.16175 0.0835 0.0 4.13589 0.09493 0.0 4.10853 0.10974 0.0 4.08 0.128 0.0 4.08 0.032 0.0 4.10787 0.01855 0.0 4.134 0.00804 0.0 4.15912 0.00025 0.0 4.184 -0.00504 0.0 4.20937 -0.00805 0.0 4.236 -0.009 0.0 4.27648 -0.00471 0.0 4.31215 0.00767 0.0 4.34188 0.02737 0.0 4.36452 0.05367 0.0 4.37894 0.08579 0.0 4.384 0.123 0.0 4.38166 0.1449 0.0 4.37426 0.16522 0.0 4.36125 0.18488 0.0 4.34207 0.20478 0.0 4.31618 0.22585 0.0 4.283 0.249 0.0 4.2475 0.27025 0.0 4.21963 0.28833 0.0 4.19887 0.30375 0.0 4.1847 0.317 0.0 4.17659 0.32858 0.0 4.174 0.339 0.0 4.17587 0.35037 0.0 4.1813 0.3603 0.0 4.19 0.3685 0.0 4.2017 0.3747 0.0 4.21613 0.37863 0.0 4.233 0.38 0.0 4.25062 0.37881 0.0 4.27026 0.37515 0.0 4.29163 0.36887 0.0 4.31441 0.35985 0.0 4.3383 0.34794 0.0 4.363 0.333 0.0 4.039 0.449 0.0 3.939 0.449 0.0 3.823 0.196 0.0 3.702 0.449 0.0 3.601 0.449 0.0 3.775 0.096 0.0 3.622 -0.23 0.0 3.721 -0.23 0.0 3.251 0.682 0.0 3.162 0.682 0.0 3.162 0.0 0.0 3.251 0.0 0.0 3.251 0.322 0.0 3.27117 0.34313 0.0 3.29004 0.35974 0.0 3.30813 0.37213 0.0 3.32596 0.38059 0.0 3.34408 0.38545 0.0 3.363 0.387 0.0 3.38827 0.38351 0.0 3.40982 0.37341 0.0 3.42725 0.35725 0.0 3.44019 0.33559 0.0 3.44823 0.30899 0.0 3.451 0.278 0.0 3.451 0.0 0.0 3.54 0.0 0.0 3.54 0.275 0.0 3.53478 0.33126 0.0 3.51989 0.37711 0.0 3.4965 0.41263 0.0 3.46578 0.43789 0.0 3.42889 0.45299 0.0 3.387 0.458 0.0 3.36207 0.45595 0.0 3.33759 0.44993 0.0 3.314 0.44013 0.0 3.29174 0.42674 0.0 3.27126 0.40997 0.0 3.253 0.39 0.0 3.251 0.39 0.0 2.661 0.682 0.0 2.661 0.0 0.0 2.759 0.0 0.0 2.759 0.295 0.0 2.861 0.295 0.0 2.9329 0.30172 0.0 2.99085 0.32074 0.0 3.03525 0.35038 0.0 3.06648 0.38893 0.0 3.08493 0.4347 0.0 3.091 0.486 0.0 3.08527 0.53802 0.0 3.06785 0.58481 0.0 3.03838 0.6245 0.0 2.99648 0.65519 0.0 2.94181 0.67498 0.0 2.874 0.682 0.0 2.759 0.594 0.0 2.874 0.594 0.0 2.9135 0.58977 0.0 2.94363 0.57815 0.0 2.96538 0.56075 0.0 2.9797 0.53919 0.0 2.98759 0.51506 0.0 2.99 0.49 0.0 2.98618 0.45846 0.0 2.97511 0.43204 0.0 2.95737 0.411 0.0 2.93356 0.39563 0.0 2.90424 0.3862 0.0 2.87 0.383 0.0 2.759 0.383 0.0 2.147 0.542 0.0 1.98 0.379 0.0 1.98 0.369 0.0 2.058 0.369 0.0 2.058 0.132 0.0 2.06208 0.09343 0.0 2.0743 0.05944 0.0 2.09462 0.03112 0.0 2.12304 0.00956 0.0 2.1595 -0.00418 0.0 2.204 -0.009 0.0 2.21992 -0.00796 0.0 2.238 -0.005 0.0 2.25725 -0.00038 0.0 2.27667 0.00567 0.0 2.29525 0.01288 0.0 2.312 0.021 0.0 2.312 0.104 0.0 2.29424 0.09392 0.0 2.27693 0.08567 0.0 2.26 0.07925 0.0 2.24341 0.07467 0.0 2.22709 0.07192 0.0 2.211 0.071 0.0 2.19723 0.07236 0.0 2.18285 0.07685 0.0 2.16925 0.08513 0.0 2.15781 0.09781 0.0 2.14994 0.11556 0.0 2.147 0.139 0.0 2.147 0.369 0.0 2.289 0.369 0.0 2.289 0.449 0.0 2.147 0.449 0.0 1.939 0.13 0.0 1.91306 0.11419 0.0 1.88719 0.10089 0.0 1.86125 0.09025 0.0 1.83515 0.08244 0.0 1.80877 0.07764 0.0 1.782 0.076 0.0 1.74193 0.07982 0.0 1.70774 0.09122 0.0 1.6795 0.11013 0.0 1.65726 0.13644 0.0 1.64107 0.1701 0.0 1.631 0.211 0.0 1.947 0.211 0.0 1.94082 0.28694 0.0 1.92289 0.34881 0.0 1.89412 0.39675 0.0 1.85544 0.43085 0.0 1.80776 0.45123 0.0 1.752 0.458 0.0 1.69339 0.45056 0.0 1.64244 0.42911 0.0 1.6005 0.395 0.0 1.56889 0.34956 0.0 1.54894 0.29411 0.0 1.542 0.23 0.0 1.54843 0.16924 0.0 1.56741 0.11293 0.0 1.5985 0.064 0.0 1.64126 0.02541 0.0 1.69524 9e-05 0.0 1.76 -0.009 0.0 1.7959 -0.00757 0.0 1.82819 -0.00326 0.0 1.85775 0.004 0.0 1.88548 0.01426 0.0 1.91227 0.02757 0.0 1.939 0.044 0.0 1.633 0.27 0.0 1.64141 0.30288 0.0 1.65459 0.33033 0.0 1.6725 0.35213 0.0 1.69507 0.368 0.0 1.72226 0.37771 0.0 1.754 0.381 0.0 1.78344 0.3775 0.0 1.80856 0.36733 0.0 1.829 0.351 0.0 1.84444 0.329 0.0 1.85456 0.30183 0.0 1.859 0.27 0.0 1.436 0.682 0.0 1.347 0.682 0.0 1.347 0.0 0.0 1.436 0.0 0.0 1.217 0.682 0.0 1.128 0.682 0.0 1.128 0.0 0.0 1.217 0.0 0.0 1.0 0.0 0.0 1.0 0.449 0.0 0.911 0.449 0.0 0.911 0.128 0.0 0.89578 0.1091 0.0 0.87926 0.09344 0.0 0.86163 0.08113 0.0 0.84307 0.07222 0.0 0.8238 0.06682 0.0 0.804 0.065 0.0 0.776 0.06796 0.0 0.75304 0.07667 0.0 0.73513 0.09088 0.0 0.7223 0.11033 0.0 0.71458 0.13479 0.0 0.712 0.164 0.0 0.712 0.449 0.0 0.623 0.449 0.0 0.623 0.17 0.0 0.62816 0.11716 0.0 0.64296 0.07293 0.0 0.66638 0.03775 0.0 0.69737 0.01207 0.0 0.73492 -0.00366 0.0 0.778 -0.009 0.0 0.80056 -0.00689 0.0 0.82381 -0.00078 0.0 0.84712 0.009 0.0 0.86985 0.02211 0.0 0.89136 0.03822 0.0 0.911 0.057 0.0 0.911 0.0 0.0 0.075 0.0 0.0 0.309 0.0 0.0 0.38571 0.00765 0.0 0.44567 0.02852 0.0 0.49013 0.0595 0.0 0.52033 0.09748 0.0 0.53754 0.13935 0.0 0.543 0.182 0.0 0.53794 0.22581 0.0 0.52315 0.26481 0.0 0.49925 0.29838 0.0 0.46685 0.32585 0.0 0.42656 0.34661 0.0 0.379 0.36 0.0 0.379 0.362 0.0 0.41136 0.37795 0.0 0.43752 0.39696 0.0 0.45763 0.41925 0.0 0.47181 0.44504 0.0 0.48023 0.47455 0.0 0.483 0.508 0.0 0.47765 0.55075 0.0 0.46122 0.59133 0.0 0.43313 0.62725 0.0 0.39278 0.656 0.0 0.3396 0.67508 0.0 0.273 0.682 0.0 0.075 0.682 0.0 0.173 0.594 0.0 0.263 0.594 0.0 0.30306 0.5905 0.0 0.33385 0.5807 0.0 0.35625 0.56563 0.0 0.37115 0.5463 0.0 0.37944 0.52375 0.0 0.382 0.499 0.0 0.37807 0.46558 0.0 0.36622 0.4383 0.0 0.34638 0.41713 0.0 0.31844 0.40204 0.0 0.28235 0.393 0.0 0.238 0.39 0.0 0.173 0.39 0.0 0.173 0.302 0.0 0.291 0.302 0.0 0.33795 0.29845 0.0 0.37593 0.2883 0.0 0.40513 0.27225 0.0 0.42574 0.25104 0.0 0.43797 0.22538 0.0 0.442 0.196 0.0 0.43917 0.17029 0.0 0.4297 0.14533 0.0 0.41212 0.12288 0.0 0.38496 0.10467 0.0 0.34675 0.09246 0.0 0.296 0.088 0.0 0.173 0.088 0.0 + + + + + + + + + + 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    20 0 19 1 18 2 20 3 18 4 17 5 21 6 20 7 17 8 21 9 17 10 16 11 22 12 21 13 16 14 22 15 16 16 44 17 44 18 16 19 45 20 45 21 16 22 15 23 23 24 22 25 43 26 43 27 22 28 44 29 23 30 43 31 42 32 46 33 45 34 15 35 23 36 42 37 41 38 47 39 46 40 15 41 23 42 41 43 40 44 48 45 47 46 15 47 24 48 23 49 40 50 48 51 15 52 14 53 24 54 40 55 39 56 49 57 48 58 14 59 24 60 39 61 38 62 50 63 49 64 14 65 25 66 24 67 38 68 50 69 14 70 13 71 25 72 38 73 50 74 25 75 50 76 13 77 26 78 25 79 12 80 12 81 25 82 13 83 26 84 12 85 11 86 26 87 11 88 10 89 27 90 26 91 10 92 27 93 10 94 9 95 1 96 0 97 37 98 2 99 1 100 37 101 28 102 27 103 9 104 28 105 9 106 8 107 3 108 2 109 37 110 28 111 8 112 7 113 4 114 3 115 37 116 5 117 4 118 37 119 28 120 7 121 6 122 6 123 5 124 37 125 28 126 6 127 37 128 29 129 28 130 37 131 29 132 37 133 36 134 29 135 36 136 35 137 30 138 29 139 35 140 30 141 35 142 34 143 30 144 34 145 33 146 31 147 30 148 33 149 31 150 33 151 32 152 52 153 51 154 84 155 52 156 84 157 83 158 52 159 83 160 82 161 53 162 52 163 82 164 54 165 53 166 82 167 55 168 54 169 81 170 81 171 54 172 82 173 55 174 81 175 80 176 55 177 80 178 79 179 56 180 55 181 79 182 56 183 79 184 78 185 69 186 68 187 67 188 56 189 78 190 77 191 70 192 69 193 67 194 57 195 56 196 77 197 71 198 70 199 67 200 57 201 77 202 76 203 72 204 71 205 67 206 57 207 76 208 75 209 73 210 72 211 67 212 57 213 75 214 74 215 74 216 73 217 67 218 57 219 74 220 67 221 58 222 57 223 67 224 59 225 58 226 67 227 59 228 67 229 66 230 59 231 66 232 65 233 60 234 59 235 65 236 60 237 65 238 64 239 60 240 64 241 63 242 61 243 60 244 63 245 61 246 63 247 62 248 105 249 104 250 103 251 106 252 105 253 103 254 106 255 103 256 102 257 107 258 106 259 102 260 108 261 107 262 102 263 108 264 102 265 101 266 109 267 108 268 101 269 109 270 101 271 100 272 110 273 109 274 100 275 111 276 110 277 112 278 112 279 110 280 113 281 113 282 110 283 114 284 114 285 110 286 115 287 115 288 110 289 116 290 116 291 110 292 117 293 117 294 110 295 100 296 117 297 100 298 118 299 118 300 100 301 99 302 119 303 118 304 99 305 120 306 119 307 99 308 120 309 99 310 98 311 121 312 120 313 98 314 122 315 121 316 98 317 123 318 122 319 98 320 123 321 98 322 97 323 124 324 123 325 97 326 125 327 124 328 174 329 174 330 124 331 97 332 126 333 125 334 174 335 127 336 126 337 174 338 127 339 174 340 173 341 156 342 174 343 97 344 128 345 127 346 173 347 128 348 173 349 172 350 129 351 128 352 172 353 129 354 172 355 171 356 129 357 171 358 170 359 130 360 129 361 170 362 130 363 170 364 169 365 130 366 169 367 168 368 131 369 130 370 168 371 131 372 168 373 167 374 132 375 131 376 167 377 132 378 167 379 166 380 157 381 156 382 97 383 132 384 166 385 165 386 158 387 157 388 97 389 86 390 85 391 155 392 158 393 97 394 96 395 87 396 86 397 155 398 133 399 132 400 165 401 133 402 165 403 164 404 158 405 96 406 95 407 159 408 158 409 95 410 88 411 87 412 155 413 159 414 95 415 94 416 160 417 159 418 94 419 89 420 88 421 155 422 133 423 164 424 163 425 160 426 94 427 93 428 90 429 89 430 155 431 161 432 160 433 93 434 161 435 93 436 92 437 91 438 90 439 155 440 161 441 92 442 91 443 133 444 163 445 162 446 161 447 91 448 155 449 162 450 161 451 155 452 133 453 162 454 143 455 143 456 162 457 155 458 134 459 133 460 143 461 134 462 143 463 142 464 144 465 143 466 155 467 144 468 155 469 154 470 135 471 134 472 142 473 135 474 142 475 141 476 145 477 144 478 154 479 145 480 154 481 153 482 135 483 141 484 140 485 146 486 145 487 153 488 136 489 135 490 140 491 146 492 153 493 152 494 136 495 140 496 139 497 147 498 146 499 152 500 147 501 152 502 151 503 136 504 139 505 138 506 148 507 147 508 151 509 137 510 136 511 138 512 148 513 151 514 150 515 149 516 148 517 150 518 177 519 176 520 175 521 177 522 175 523 256 524 178 525 177 526 256 527 179 528 178 529 256 530 180 531 179 532 255 533 255 534 179 535 256 536 180 537 255 538 275 539 275 540 255 541 254 542 181 543 180 544 274 545 274 546 180 547 275 548 276 549 275 550 254 551 277 552 276 553 254 554 181 555 274 556 273 557 277 558 254 559 253 560 278 561 277 562 253 563 181 564 273 565 272 566 279 567 278 568 253 569 181 570 272 571 271 572 279 573 253 574 252 575 182 576 181 577 271 578 280 579 279 580 252 581 280 582 252 583 251 584 182 585 271 586 270 587 280 588 251 589 250 590 257 591 280 592 250 593 182 594 270 595 269 596 257 597 250 598 249 599 183 600 182 601 269 602 258 603 257 604 249 605 183 606 269 607 268 608 258 609 249 610 248 611 184 612 183 613 268 614 259 615 258 616 248 617 184 618 268 619 267 620 259 621 248 622 247 623 185 624 184 625 267 626 260 627 259 628 247 629 186 630 185 631 267 632 186 633 267 634 266 635 260 636 247 637 246 638 187 639 186 640 266 641 261 642 260 643 246 644 187 645 266 646 265 647 261 648 246 649 245 650 188 651 187 652 265 653 262 654 261 655 245 656 188 657 265 658 264 659 263 660 262 661 245 662 188 663 264 664 263 665 189 666 188 667 263 668 189 669 263 670 245 671 189 672 245 673 244 674 190 675 189 676 244 677 190 678 244 679 243 680 191 681 190 682 243 683 191 684 243 685 242 686 192 687 191 688 242 689 193 690 192 691 242 692 194 693 193 694 242 695 194 696 242 697 241 698 195 699 194 700 241 701 196 702 195 703 241 704 197 705 196 706 241 707 197 708 241 709 240 710 198 711 197 712 240 713 198 714 240 715 239 716 198 717 239 718 238 719 199 720 198 721 238 722 199 723 238 724 237 725 200 726 199 727 237 728 201 729 200 730 237 731 201 732 237 733 236 734 202 735 201 736 236 737 202 738 236 739 235 740 203 741 202 742 235 743 203 744 235 745 234 746 204 747 203 748 234 749 204 750 234 751 233 752 205 753 204 754 233 755 205 756 233 757 232 758 206 759 205 760 232 761 206 762 232 763 231 764 207 765 206 766 231 767 207 768 231 769 230 770 208 771 207 772 230 773 208 774 230 775 229 776 209 777 208 778 229 779 209 780 229 781 228 782 210 783 209 784 228 785 210 786 228 787 299 788 299 789 228 790 300 791 300 792 228 793 227 794 211 795 210 796 298 797 298 798 210 799 299 800 301 801 300 802 227 803 211 804 298 805 297 806 302 807 301 808 227 809 211 810 297 811 296 812 302 813 227 814 226 815 303 816 302 817 226 818 212 819 211 820 296 821 212 822 296 823 295 824 304 825 303 826 226 827 212 828 295 829 294 830 304 831 226 832 225 833 213 834 212 835 294 836 281 837 304 838 225 839 213 840 294 841 293 842 281 843 225 844 224 845 213 846 293 847 292 848 214 849 213 850 292 851 282 852 281 853 224 854 214 855 292 856 291 857 283 858 282 859 224 860 214 861 291 862 290 863 283 864 224 865 223 866 284 867 283 868 223 869 215 870 214 871 290 872 215 873 290 874 289 875 285 876 284 877 223 878 215 879 289 880 288 881 286 882 285 883 223 884 215 885 288 886 287 887 287 888 286 889 223 890 215 891 287 892 223 893 215 894 223 895 222 896 216 897 215 898 222 899 217 900 216 901 222 902 217 903 222 904 221 905 218 906 217 907 221 908 218 909 221 910 220 911 219 912 218 913 220 914 316 915 315 916 314 917 317 918 316 919 314 920 317 921 314 922 313 923 318 924 317 925 313 926 318 927 313 928 312 929 319 930 318 931 312 932 319 933 312 934 311 935 320 936 319 937 311 938 320 939 311 940 310 941 321 942 320 943 310 944 321 945 310 946 309 947 322 948 321 949 309 950 322 951 309 952 332 953 323 954 322 955 332 956 323 957 332 958 331 959 324 960 323 961 331 962 324 963 331 964 330 965 325 966 324 967 330 968 325 969 330 970 329 971 326 972 325 973 329 974 326 975 329 976 328 977 327 978 326 979 328 980 307 981 306 982 305 983 307 984 305 985 308 986 333 987 339 988 338 989 333 990 338 991 337 992 337 993 336 994 335 995 337 996 335 997 334 998 333 999 337 1000 334 1001 360 1002 359 1003 358 1004 361 1005 360 1006 358 1007 361 1008 358 1009 357 1010 362 1011 361 1012 357 1013 363 1014 362 1015 357 1016 363 1017 357 1018 356 1019 364 1020 363 1021 356 1022 364 1023 356 1024 355 1025 365 1026 364 1027 355 1028 366 1029 365 1030 367 1031 367 1032 365 1033 368 1034 368 1035 365 1036 369 1037 369 1038 365 1039 370 1040 370 1041 365 1042 371 1043 371 1044 365 1045 372 1046 372 1047 365 1048 355 1049 372 1050 355 1051 373 1052 373 1053 355 1054 354 1055 374 1056 373 1057 354 1058 375 1059 374 1060 354 1061 375 1062 354 1063 353 1064 376 1065 375 1066 353 1067 377 1068 376 1069 353 1070 378 1071 377 1072 353 1073 378 1074 353 1075 352 1076 379 1077 378 1078 352 1079 380 1080 379 1081 429 1082 429 1083 379 1084 352 1085 381 1086 380 1087 429 1088 382 1089 381 1090 429 1091 382 1092 429 1093 428 1094 411 1095 429 1096 352 1097 383 1098 382 1099 428 1100 383 1101 428 1102 427 1103 384 1104 383 1105 427 1106 384 1107 427 1108 426 1109 384 1110 426 1111 425 1112 385 1113 384 1114 425 1115 385 1116 425 1117 424 1118 385 1119 424 1120 423 1121 386 1122 385 1123 423 1124 386 1125 423 1126 422 1127 387 1128 386 1129 422 1130 387 1131 422 1132 421 1133 412 1134 411 1135 352 1136 387 1137 421 1138 420 1139 413 1140 412 1141 352 1142 341 1143 340 1144 410 1145 413 1146 352 1147 351 1148 342 1149 341 1150 410 1151 388 1152 387 1153 420 1154 388 1155 420 1156 419 1157 413 1158 351 1159 350 1160 414 1161 413 1162 350 1163 343 1164 342 1165 410 1166 414 1167 350 1168 349 1169 415 1170 414 1171 349 1172 344 1173 343 1174 410 1175 388 1176 419 1177 418 1178 415 1179 349 1180 348 1181 345 1182 344 1183 410 1184 416 1185 415 1186 348 1187 416 1188 348 1189 347 1190 346 1191 345 1192 410 1193 416 1194 347 1195 346 1196 388 1197 418 1198 417 1199 416 1200 346 1201 410 1202 417 1203 416 1204 410 1205 388 1206 417 1207 398 1208 398 1209 417 1210 410 1211 389 1212 388 1213 398 1214 389 1215 398 1216 397 1217 399 1218 398 1219 410 1220 399 1221 410 1222 409 1223 390 1224 389 1225 397 1226 390 1227 397 1228 396 1229 400 1230 399 1231 409 1232 400 1233 409 1234 408 1235 390 1236 396 1237 395 1238 401 1239 400 1240 408 1241 391 1242 390 1243 395 1244 401 1245 408 1246 407 1247 391 1248 395 1249 394 1250 402 1251 401 1252 407 1253 402 1254 407 1255 406 1256 391 1257 394 1258 393 1259 403 1260 402 1261 406 1262 392 1263 391 1264 393 1265 403 1266 406 1267 405 1268 404 1269 403 1270 405 1271 456 1272 455 1273 454 1274 457 1275 456 1276 454 1277 457 1278 454 1279 453 1280 458 1281 457 1282 453 1283 432 1284 431 1285 430 1286 432 1287 430 1288 462 1289 459 1290 458 1291 453 1292 459 1293 453 1294 452 1295 460 1296 459 1297 452 1298 460 1299 452 1300 451 1301 461 1302 460 1303 440 1304 440 1305 460 1306 451 1307 432 1308 462 1309 461 1310 432 1311 461 1312 434 1313 434 1314 461 1315 435 1316 435 1317 461 1318 436 1319 436 1320 461 1321 437 1322 437 1323 461 1324 438 1325 438 1326 461 1327 439 1328 439 1329 461 1330 440 1331 441 1332 440 1333 451 1334 442 1335 441 1336 451 1337 442 1338 451 1339 450 1340 443 1341 442 1342 450 1343 444 1344 443 1345 450 1346 445 1347 444 1348 450 1349 445 1350 450 1351 449 1352 432 1353 434 1354 433 1355 446 1356 445 1357 449 1358 447 1359 446 1360 449 1361 447 1362 449 1363 448 1364 464 1365 463 1366 486 1367 464 1368 486 1369 485 1370 465 1371 464 1372 485 1373 465 1374 485 1375 484 1376 466 1377 465 1378 484 1379 466 1380 484 1381 487 1382 487 1383 484 1384 488 1385 488 1386 484 1387 483 1388 467 1389 466 1390 510 1391 510 1392 466 1393 487 1394 467 1395 510 1396 509 1397 489 1398 488 1399 483 1400 467 1401 509 1402 508 1403 490 1404 489 1405 483 1406 490 1407 483 1408 482 1409 468 1410 467 1411 508 1412 468 1413 508 1414 507 1415 491 1416 490 1417 482 1418 468 1419 507 1420 506 1421 492 1422 491 1423 482 1424 492 1425 482 1426 481 1427 469 1428 468 1429 506 1430 469 1431 506 1432 505 1433 493 1434 492 1435 481 1436 470 1437 469 1438 505 1439 470 1440 505 1441 504 1442 493 1443 481 1444 480 1445 494 1446 493 1447 480 1448 470 1449 504 1450 503 1451 495 1452 494 1453 480 1454 471 1455 470 1456 503 1457 495 1458 480 1459 479 1460 471 1461 503 1462 502 1463 496 1464 495 1465 479 1466 471 1467 502 1468 501 1469 497 1470 496 1471 479 1472 472 1473 471 1474 501 1475 497 1476 479 1477 478 1478 472 1479 501 1480 500 1481 498 1482 497 1483 478 1484 472 1485 500 1486 499 1487 499 1488 498 1489 478 1490 472 1491 499 1492 478 1493 473 1494 472 1495 478 1496 473 1497 478 1498 477 1499 474 1500 473 1501 477 1502 474 1503 477 1504 476 1505 475 1506 474 1507 476 1508 512 1509 511 1510 544 1511 512 1512 544 1513 543 1514 512 1515 543 1516 542 1517 513 1518 512 1519 542 1520 514 1521 513 1522 542 1523 515 1524 514 1525 541 1526 541 1527 514 1528 542 1529 515 1530 541 1531 540 1532 515 1533 540 1534 539 1535 516 1536 515 1537 539 1538 516 1539 539 1540 538 1541 529 1542 528 1543 527 1544 516 1545 538 1546 537 1547 530 1548 529 1549 527 1550 517 1551 516 1552 537 1553 531 1554 530 1555 527 1556 517 1557 537 1558 536 1559 532 1560 531 1561 527 1562 517 1563 536 1564 535 1565 533 1566 532 1567 527 1568 517 1569 535 1570 534 1571 534 1572 533 1573 527 1574 517 1575 534 1576 527 1577 518 1578 517 1579 527 1580 519 1581 518 1582 527 1583 519 1584 527 1585 526 1586 519 1587 526 1588 525 1589 520 1590 519 1591 525 1592 520 1593 525 1594 524 1595 520 1596 524 1597 523 1598 521 1599 520 1600 523 1601 521 1602 523 1603 522 1604 552 1605 551 1606 550 1607 552 1608 550 1609 549 1610 553 1611 552 1612 549 1613 553 1614 549 1615 548 1616 553 1617 548 1618 547 1619 554 1620 553 1621 547 1622 554 1623 547 1624 546 1625 554 1626 546 1627 545 1628 555 1629 554 1630 545 1631 555 1632 545 1633 606 1634 606 1635 545 1636 607 1637 607 1638 545 1639 608 1640 608 1641 545 1642 609 1643 609 1644 545 1645 610 1646 610 1647 545 1648 611 1649 611 1650 545 1651 612 1652 556 1653 555 1654 606 1655 556 1656 606 1657 605 1658 556 1659 605 1660 604 1661 556 1662 604 1663 603 1664 557 1665 556 1666 603 1667 557 1668 603 1669 602 1670 557 1671 602 1672 601 1673 557 1674 601 1675 600 1676 557 1677 600 1678 599 1679 558 1680 557 1681 599 1682 558 1683 599 1684 598 1685 558 1686 598 1687 597 1688 558 1689 597 1690 596 1691 558 1692 596 1693 595 1694 559 1695 558 1696 595 1697 559 1698 595 1699 594 1700 559 1701 594 1702 593 1703 560 1704 559 1705 593 1706 560 1707 593 1708 592 1709 561 1710 560 1711 592 1712 561 1713 592 1714 591 1715 561 1716 591 1717 590 1718 562 1719 561 1720 590 1721 562 1722 590 1723 589 1724 563 1725 562 1726 589 1727 563 1728 589 1729 588 1730 576 1731 575 1732 574 1733 563 1734 588 1735 587 1736 564 1737 563 1738 587 1739 576 1740 574 1741 573 1742 565 1743 564 1744 587 1745 576 1746 573 1747 572 1748 566 1749 565 1750 587 1751 566 1752 587 1753 586 1754 576 1755 572 1756 571 1757 567 1758 566 1759 586 1760 568 1761 567 1762 586 1763 576 1764 571 1765 570 1766 569 1767 568 1768 586 1769 576 1770 570 1771 569 1772 576 1773 569 1774 586 1775 576 1776 586 1777 585 1778 577 1779 576 1780 585 1781 577 1782 585 1783 584 1784 578 1785 577 1786 584 1787 579 1788 578 1789 584 1790 579 1791 584 1792 583 1793 580 1794 579 1795 583 1796 580 1797 583 1798 582 1799 581 1800 580 1801 582 1802 618 1803 617 1804 616 1805 618 1806 616 1807 615 1808 615 1809 614 1810 613 1811 615 1812 613 1813 620 1814 618 1815 615 1816 620 1817 619 1818 618 1819 620 1820 641 1821 640 1822 639 1823 641 1824 639 1825 638 1826 642 1827 641 1828 638 1829 642 1830 638 1831 637 1832 643 1833 642 1834 637 1835 643 1836 637 1837 665 1838 665 1839 637 1840 666 1841 666 1842 637 1843 636 1844 644 1845 643 1846 664 1847 664 1848 643 1849 665 1850 644 1851 664 1852 663 1853 667 1854 666 1855 636 1856 644 1857 663 1858 662 1859 668 1860 667 1861 636 1862 644 1863 662 1864 661 1865 669 1866 668 1867 636 1868 645 1869 644 1870 661 1871 669 1872 636 1873 635 1874 645 1875 661 1876 660 1877 670 1878 669 1879 635 1880 645 1881 660 1882 659 1883 671 1884 670 1885 635 1886 646 1887 645 1888 659 1889 671 1890 635 1891 634 1892 646 1893 659 1894 671 1895 646 1896 671 1897 634 1898 647 1899 646 1900 633 1901 633 1902 646 1903 634 1904 647 1905 633 1906 632 1907 647 1908 632 1909 631 1910 648 1911 647 1912 631 1913 648 1914 631 1915 630 1916 622 1917 621 1918 658 1919 623 1920 622 1921 658 1922 649 1923 648 1924 630 1925 649 1926 630 1927 629 1928 624 1929 623 1930 658 1931 649 1932 629 1933 628 1934 625 1935 624 1936 658 1937 626 1938 625 1939 658 1940 649 1941 628 1942 627 1943 627 1944 626 1945 658 1946 649 1947 627 1948 658 1949 650 1950 649 1951 658 1952 650 1953 658 1954 657 1955 650 1956 657 1957 656 1958 651 1959 650 1960 656 1961 651 1962 656 1963 655 1964 651 1965 655 1966 654 1967 652 1968 651 1969 654 1970 652 1971 654 1972 653 1973 680 1974 679 1975 678 1976 680 1977 678 1978 681 1979 674 1980 673 1981 672 1982 674 1983 672 1984 677 1985 675 1986 674 1987 677 1988 675 1989 677 1990 676 1991 705 1992 704 1993 703 1994 705 1995 703 1996 702 1997 706 1998 705 1999 702 2000 706 2001 702 2002 701 2003 683 2004 682 2005 712 2006 683 2007 712 2008 711 2009 707 2010 706 2011 701 2012 707 2013 701 2014 700 2015 707 2016 700 2017 699 2018 708 2019 707 2020 699 2021 708 2022 699 2023 698 2024 709 2025 708 2026 698 2027 709 2028 698 2029 691 2030 691 2031 698 2032 692 2033 692 2034 698 2035 693 2036 693 2037 698 2038 694 2039 694 2040 698 2041 695 2042 695 2043 698 2044 696 2045 696 2046 698 2047 697 2048 710 2049 709 2050 690 2051 690 2052 709 2053 691 2054 710 2055 690 2056 689 2057 710 2058 689 2059 688 2060 683 2061 711 2062 710 2063 683 2064 710 2065 687 2066 687 2067 710 2068 688 2069 683 2070 687 2071 686 2072 683 2073 686 2074 685 2075 683 2076 685 2077 684 2078 714 2079 713 2080 736 2081 714 2082 736 2083 735 2084 715 2085 714 2086 735 2087 715 2088 735 2089 734 2090 716 2091 715 2092 734 2093 716 2094 734 2095 737 2096 737 2097 734 2098 738 2099 738 2100 734 2101 733 2102 717 2103 716 2104 760 2105 760 2106 716 2107 737 2108 717 2109 760 2110 759 2111 739 2112 738 2113 733 2114 717 2115 759 2116 758 2117 740 2118 739 2119 733 2120 740 2121 733 2122 732 2123 718 2124 717 2125 758 2126 718 2127 758 2128 757 2129 741 2130 740 2131 732 2132 718 2133 757 2134 756 2135 742 2136 741 2137 732 2138 742 2139 732 2140 731 2141 719 2142 718 2143 756 2144 719 2145 756 2146 755 2147 743 2148 742 2149 731 2150 720 2151 719 2152 755 2153 720 2154 755 2155 754 2156 743 2157 731 2158 730 2159 744 2160 743 2161 730 2162 720 2163 754 2164 753 2165 745 2166 744 2167 730 2168 721 2169 720 2170 753 2171 745 2172 730 2173 729 2174 721 2175 753 2176 752 2177 746 2178 745 2179 729 2180 721 2181 752 2182 751 2183 747 2184 746 2185 729 2186 722 2187 721 2188 751 2189 747 2190 729 2191 728 2192 722 2193 751 2194 750 2195 748 2196 747 2197 728 2198 722 2199 750 2200 749 2201 749 2202 748 2203 728 2204 722 2205 749 2206 728 2207 723 2208 722 2209 728 2210 723 2211 728 2212 727 2213 724 2214 723 2215 727 2216 724 2217 727 2218 726 2219 725 2220 724 2221 726 2222 768 2223 767 2224 766 2225 768 2226 766 2227 765 2228 769 2229 768 2230 765 2231 769 2232 765 2233 764 2234 769 2235 764 2236 763 2237 770 2238 769 2239 763 2240 770 2241 763 2242 762 2243 770 2244 762 2245 761 2246 771 2247 770 2248 761 2249 771 2250 761 2251 822 2252 822 2253 761 2254 823 2255 823 2256 761 2257 824 2258 824 2259 761 2260 825 2261 825 2262 761 2263 826 2264 826 2265 761 2266 827 2267 827 2268 761 2269 828 2270 772 2271 771 2272 822 2273 772 2274 822 2275 821 2276 772 2277 821 2278 820 2279 772 2280 820 2281 819 2282 773 2283 772 2284 819 2285 773 2286 819 2287 818 2288 773 2289 818 2290 817 2291 773 2292 817 2293 816 2294 773 2295 816 2296 815 2297 774 2298 773 2299 815 2300 774 2301 815 2302 814 2303 774 2304 814 2305 813 2306 774 2307 813 2308 812 2309 774 2310 812 2311 811 2312 775 2313 774 2314 811 2315 775 2316 811 2317 810 2318 775 2319 810 2320 809 2321 776 2322 775 2323 809 2324 776 2325 809 2326 808 2327 777 2328 776 2329 808 2330 777 2331 808 2332 807 2333 777 2334 807 2335 806 2336 778 2337 777 2338 806 2339 778 2340 806 2341 805 2342 779 2343 778 2344 805 2345 779 2346 805 2347 804 2348 792 2349 791 2350 790 2351 779 2352 804 2353 803 2354 780 2355 779 2356 803 2357 792 2358 790 2359 789 2360 781 2361 780 2362 803 2363 792 2364 789 2365 788 2366 782 2367 781 2368 803 2369 782 2370 803 2371 802 2372 792 2373 788 2374 787 2375 783 2376 782 2377 802 2378 784 2379 783 2380 802 2381 792 2382 787 2383 786 2384 785 2385 784 2386 802 2387 792 2388 786 2389 785 2390 792 2391 785 2392 802 2393 792 2394 802 2395 801 2396 793 2397 792 2398 801 2399 793 2400 801 2401 800 2402 794 2403 793 2404 800 2405 795 2406 794 2407 800 2408 795 2409 800 2410 799 2411 796 2412 795 2413 799 2414 796 2415 799 2416 798 2417 797 2418 796 2419 798 2420 852 2421 851 2422 850 2423 852 2424 850 2425 849 2426 853 2427 852 2428 849 2429 853 2430 849 2431 848 2432 830 2433 829 2434 859 2435 830 2436 859 2437 858 2438 854 2439 853 2440 848 2441 854 2442 848 2443 847 2444 854 2445 847 2446 846 2447 855 2448 854 2449 846 2450 855 2451 846 2452 845 2453 856 2454 855 2455 845 2456 856 2457 845 2458 838 2459 838 2460 845 2461 839 2462 839 2463 845 2464 840 2465 840 2466 845 2467 841 2468 841 2469 845 2470 842 2471 842 2472 845 2473 843 2474 843 2475 845 2476 844 2477 857 2478 856 2479 837 2480 837 2481 856 2482 838 2483 857 2484 837 2485 836 2486 857 2487 836 2488 835 2489 830 2490 858 2491 857 2492 830 2493 857 2494 834 2495 834 2496 857 2497 835 2498 830 2499 834 2500 833 2501 830 2502 833 2503 832 2504 830 2505 832 2506 831 2507 878 2508 877 2509 876 2510 878 2511 876 2512 875 2513 863 2514 862 2515 861 2516 863 2517 861 2518 860 2519 879 2520 878 2521 875 2522 879 2523 875 2524 874 2525 879 2526 874 2527 873 2528 864 2529 863 2530 860 2531 880 2532 879 2533 873 2534 880 2535 873 2536 872 2537 865 2538 864 2539 860 2540 866 2541 865 2542 890 2543 890 2544 865 2545 860 2546 880 2547 872 2548 871 2549 867 2550 866 2551 890 2552 880 2553 871 2554 870 2555 881 2556 880 2557 870 2558 868 2559 867 2560 890 2561 881 2562 870 2563 869 2564 869 2565 868 2566 890 2567 881 2568 869 2569 890 2570 881 2571 890 2572 889 2573 891 2574 890 2575 860 2576 881 2577 889 2578 888 2579 882 2580 881 2581 888 2582 882 2583 888 2584 887 2585 883 2586 882 2587 887 2588 883 2589 887 2590 886 2591 883 2592 886 2593 885 2594 884 2595 883 2596 885 2597 899 2598 898 2599 897 2600 899 2601 897 2602 896 2603 899 2604 896 2605 895 2606 900 2607 899 2608 895 2609 900 2610 895 2611 894 2612 900 2613 894 2614 893 2615 900 2616 893 2617 892 2618 901 2619 900 2620 892 2621 901 2622 892 2623 935 2624 935 2625 892 2626 936 2627 936 2628 892 2629 937 2630 937 2631 892 2632 938 2633 938 2634 892 2635 939 2636 939 2637 892 2638 940 2639 940 2640 892 2641 941 2642 901 2643 935 2644 934 2645 901 2646 934 2647 933 2648 902 2649 901 2650 933 2651 902 2652 933 2653 932 2654 902 2655 932 2656 931 2657 903 2658 902 2659 931 2660 903 2661 931 2662 930 2663 904 2664 903 2665 930 2666 904 2667 930 2668 929 2669 904 2670 929 2671 928 2672 905 2673 904 2674 928 2675 905 2676 928 2677 927 2678 906 2679 905 2680 927 2681 906 2682 927 2683 926 2684 907 2685 906 2686 926 2687 918 2688 917 2689 916 2690 907 2691 926 2692 925 2693 919 2694 918 2695 916 2696 920 2697 919 2698 916 2699 907 2700 925 2701 924 2702 908 2703 907 2704 924 2705 921 2706 920 2707 916 2708 922 2709 921 2710 916 2711 908 2712 924 2713 923 2714 923 2715 922 2716 916 2717 908 2718 923 2719 916 2720 908 2721 916 2722 915 2723 909 2724 908 2725 915 2726 909 2727 915 2728 914 2729 909 2730 914 2731 913 2732 909 2733 913 2734 912 2735 910 2736 909 2737 912 2738 910 2739 912 2740 911 2741 943 2742 942 2743 975 2744 943 2745 975 2746 974 2747 943 2748 974 2749 973 2750 944 2751 943 2752 973 2753 945 2754 944 2755 973 2756 946 2757 945 2758 972 2759 972 2760 945 2761 973 2762 946 2763 972 2764 971 2765 946 2766 971 2767 970 2768 947 2769 946 2770 970 2771 947 2772 970 2773 969 2774 960 2775 959 2776 958 2777 947 2778 969 2779 968 2780 961 2781 960 2782 958 2783 948 2784 947 2785 968 2786 962 2787 961 2788 958 2789 948 2790 968 2791 967 2792 963 2793 962 2794 958 2795 948 2796 967 2797 966 2798 964 2799 963 2800 958 2801 948 2802 966 2803 965 2804 965 2805 964 2806 958 2807 948 2808 965 2809 958 2810 949 2811 948 2812 958 2813 950 2814 949 2815 958 2816 950 2817 958 2818 957 2819 950 2820 957 2821 956 2822 951 2823 950 2824 956 2825 951 2826 956 2827 955 2828 951 2829 955 2830 954 2831 952 2832 951 2833 954 2834 952 2835 954 2836 953 2837 977 2838 976 2839 999 2840 977 2841 999 2842 998 2843 978 2844 977 2845 998 2846 978 2847 998 2848 997 2849 979 2850 978 2851 997 2852 979 2853 997 2854 1000 2855 1000 2856 997 2857 1001 2858 1001 2859 997 2860 996 2861 980 2862 979 2863 1023 2864 1023 2865 979 2866 1000 2867 980 2868 1023 2869 1022 2870 1002 2871 1001 2872 996 2873 980 2874 1022 2875 1021 2876 1003 2877 1002 2878 996 2879 1003 2880 996 2881 995 2882 981 2883 980 2884 1021 2885 981 2886 1021 2887 1020 2888 1004 2889 1003 2890 995 2891 981 2892 1020 2893 1019 2894 1005 2895 1004 2896 995 2897 1005 2898 995 2899 994 2900 982 2901 981 2902 1019 2903 982 2904 1019 2905 1018 2906 1006 2907 1005 2908 994 2909 983 2910 982 2911 1018 2912 983 2913 1018 2914 1017 2915 1006 2916 994 2917 993 2918 1007 2919 1006 2920 993 2921 983 2922 1017 2923 1016 2924 1008 2925 1007 2926 993 2927 984 2928 983 2929 1016 2930 1008 2931 993 2932 992 2933 984 2934 1016 2935 1015 2936 1009 2937 1008 2938 992 2939 984 2940 1015 2941 1014 2942 1010 2943 1009 2944 992 2945 985 2946 984 2947 1014 2948 1010 2949 992 2950 991 2951 985 2952 1014 2953 1013 2954 1011 2955 1010 2956 991 2957 985 2958 1013 2959 1012 2960 1012 2961 1011 2962 991 2963 985 2964 1012 2965 991 2966 986 2967 985 2968 991 2969 986 2970 991 2971 990 2972 987 2973 986 2974 990 2975 987 2976 990 2977 989 2978 988 2979 987 2980 989 2981 1026 2982 1025 2983 1024 2984 1026 2985 1024 2986 1056 2987 1050 2988 1049 2989 1048 2990 1051 2991 1050 2992 1048 2993 1051 2994 1048 2995 1047 2996 1052 2997 1051 2998 1047 2999 1053 3000 1052 3001 1047 3002 1053 3003 1047 3004 1046 3005 1054 3006 1053 3007 1046 3008 1054 3009 1046 3010 1045 3011 1055 3012 1054 3013 1034 3014 1034 3015 1054 3016 1045 3017 1026 3018 1056 3019 1055 3020 1026 3021 1055 3022 1028 3023 1028 3024 1055 3025 1029 3026 1029 3027 1055 3028 1030 3029 1030 3030 1055 3031 1031 3032 1031 3033 1055 3034 1032 3035 1032 3036 1055 3037 1033 3038 1033 3039 1055 3040 1034 3041 1035 3042 1034 3043 1045 3044 1036 3045 1035 3046 1045 3047 1036 3048 1045 3049 1044 3050 1037 3051 1036 3052 1044 3053 1038 3054 1037 3055 1044 3056 1039 3057 1038 3058 1044 3059 1039 3060 1044 3061 1043 3062 1026 3063 1028 3064 1027 3065 1040 3066 1039 3067 1043 3068 1041 3069 1040 3070 1043 3071 1041 3072 1043 3073 1042 3074 1064 3075 1063 3076 1062 3077 1064 3078 1062 3079 1061 3080 1065 3081 1064 3082 1061 3083 1065 3084 1061 3085 1060 3086 1065 3087 1060 3088 1059 3089 1066 3090 1065 3091 1059 3092 1066 3093 1059 3094 1058 3095 1066 3096 1058 3097 1057 3098 1067 3099 1066 3100 1057 3101 1067 3102 1057 3103 1118 3104 1118 3105 1057 3106 1119 3107 1119 3108 1057 3109 1120 3110 1120 3111 1057 3112 1121 3113 1121 3114 1057 3115 1122 3116 1122 3117 1057 3118 1123 3119 1123 3120 1057 3121 1124 3122 1068 3123 1067 3124 1118 3125 1068 3126 1118 3127 1117 3128 1068 3129 1117 3130 1116 3131 1068 3132 1116 3133 1115 3134 1069 3135 1068 3136 1115 3137 1069 3138 1115 3139 1114 3140 1069 3141 1114 3142 1113 3143 1069 3144 1113 3145 1112 3146 1069 3147 1112 3148 1111 3149 1070 3150 1069 3151 1111 3152 1070 3153 1111 3154 1110 3155 1070 3156 1110 3157 1109 3158 1070 3159 1109 3160 1108 3161 1070 3162 1108 3163 1107 3164 1071 3165 1070 3166 1107 3167 1071 3168 1107 3169 1106 3170 1071 3171 1106 3172 1105 3173 1072 3174 1071 3175 1105 3176 1072 3177 1105 3178 1104 3179 1073 3180 1072 3181 1104 3182 1073 3183 1104 3184 1103 3185 1073 3186 1103 3187 1102 3188 1074 3189 1073 3190 1102 3191 1074 3192 1102 3193 1101 3194 1075 3195 1074 3196 1101 3197 1075 3198 1101 3199 1100 3200 1088 3201 1087 3202 1086 3203 1075 3204 1100 3205 1099 3206 1076 3207 1075 3208 1099 3209 1088 3210 1086 3211 1085 3212 1077 3213 1076 3214 1099 3215 1088 3216 1085 3217 1084 3218 1078 3219 1077 3220 1099 3221 1078 3222 1099 3223 1098 3224 1088 3225 1084 3226 1083 3227 1079 3228 1078 3229 1098 3230 1080 3231 1079 3232 1098 3233 1088 3234 1083 3235 1082 3236 1081 3237 1080 3238 1098 3239 1088 3240 1082 3241 1081 3242 1088 3243 1081 3244 1098 3245 1088 3246 1098 3247 1097 3248 1089 3249 1088 3250 1097 3251 1089 3252 1097 3253 1096 3254 1090 3255 1089 3256 1096 3257 1091 3258 1090 3259 1096 3260 1091 3261 1096 3262 1095 3263 1092 3264 1091 3265 1095 3266 1092 3267 1095 3268 1094 3269 1093 3270 1092 3271 1094 3272 1130 3273 1129 3274 1128 3275 1130 3276 1128 3277 1127 3278 1127 3279 1126 3280 1125 3281 1127 3282 1125 3283 1132 3284 1130 3285 1127 3286 1132 3287 1131 3288 1130 3289 1132 3290 1135 3291 1134 3292 1133 3293 1135 3294 1133 3295 1136 3296 1157 3297 1156 3298 1159 3299 1159 3300 1156 3301 1155 3302 1159 3303 1155 3304 1154 3305 1159 3306 1154 3307 1153 3308 1159 3309 1153 3310 1152 3311 1159 3312 1152 3313 1160 3314 1160 3315 1152 3316 1161 3317 1161 3318 1152 3319 1151 3320 1157 3321 1159 3322 1178 3323 1162 3324 1161 3325 1151 3326 1163 3327 1162 3328 1151 3329 1163 3330 1151 3331 1150 3332 1164 3333 1163 3334 1150 3335 1165 3336 1164 3337 1150 3338 1165 3339 1150 3340 1149 3341 1166 3342 1165 3343 1149 3344 1167 3345 1166 3346 1149 3347 1167 3348 1149 3349 1148 3350 1168 3351 1167 3352 1148 3353 1168 3354 1148 3355 1147 3356 1169 3357 1168 3358 1147 3359 1170 3360 1169 3361 1147 3362 1170 3363 1147 3364 1146 3365 1157 3366 1178 3367 1177 3368 1171 3369 1170 3370 1146 3371 1157 3372 1177 3373 1137 3374 1137 3375 1177 3376 1176 3377 1137 3378 1176 3379 1175 3380 1172 3381 1171 3382 1146 3383 1137 3384 1175 3385 1174 3386 1137 3387 1174 3388 1173 3389 1137 3390 1173 3391 1172 3392 1137 3393 1172 3394 1146 3395 1137 3396 1146 3397 1145 3398 1137 3399 1145 3400 1144 3401 1157 3402 1137 3403 1158 3404 1138 3405 1137 3406 1144 3407 1139 3408 1138 3409 1144 3410 1140 3411 1139 3412 1144 3413 1140 3414 1144 3415 1143 3416 1141 3417 1140 3418 1143 3419 1142 3420 1141 3421 1143 3422 1199 3423 1198 3424 1201 3425 1201 3426 1198 3427 1197 3428 1201 3429 1197 3430 1196 3431 1201 3432 1196 3433 1195 3434 1201 3435 1195 3436 1194 3437 1201 3438 1194 3439 1202 3440 1202 3441 1194 3442 1203 3443 1203 3444 1194 3445 1193 3446 1199 3447 1201 3448 1220 3449 1204 3450 1203 3451 1193 3452 1205 3453 1204 3454 1193 3455 1205 3456 1193 3457 1192 3458 1206 3459 1205 3460 1192 3461 1207 3462 1206 3463 1192 3464 1207 3465 1192 3466 1191 3467 1208 3468 1207 3469 1191 3470 1209 3471 1208 3472 1191 3473 1209 3474 1191 3475 1190 3476 1210 3477 1209 3478 1190 3479 1210 3480 1190 3481 1189 3482 1211 3483 1210 3484 1189 3485 1212 3486 1211 3487 1189 3488 1212 3489 1189 3490 1188 3491 1199 3492 1220 3493 1219 3494 1213 3495 1212 3496 1188 3497 1199 3498 1219 3499 1179 3500 1179 3501 1219 3502 1218 3503 1179 3504 1218 3505 1217 3506 1214 3507 1213 3508 1188 3509 1179 3510 1217 3511 1216 3512 1179 3513 1216 3514 1215 3515 1179 3516 1215 3517 1214 3518 1179 3519 1214 3520 1188 3521 1179 3522 1188 3523 1187 3524 1179 3525 1187 3526 1186 3527 1199 3528 1179 3529 1200 3530 1180 3531 1179 3532 1186 3533 1181 3534 1180 3535 1186 3536 1182 3537 1181 3538 1186 3539 1182 3540 1186 3541 1185 3542 1183 3543 1182 3544 1185 3545 1184 3546 1183 3547 1185 3548 1241 3549 1240 3550 1239 3551 1242 3552 1241 3553 1239 3554 1242 3555 1239 3556 1238 3557 1243 3558 1242 3559 1238 3560 1244 3561 1243 3562 1238 3563 1244 3564 1238 3565 1237 3566 1245 3567 1244 3568 1237 3569 1245 3570 1237 3571 1236 3572 1246 3573 1245 3574 1236 3575 1247 3576 1246 3577 1248 3578 1248 3579 1246 3580 1249 3581 1249 3582 1246 3583 1250 3584 1250 3585 1246 3586 1251 3587 1251 3588 1246 3589 1252 3590 1252 3591 1246 3592 1253 3593 1253 3594 1246 3595 1236 3596 1253 3597 1236 3598 1254 3599 1254 3600 1236 3601 1235 3602 1255 3603 1254 3604 1235 3605 1256 3606 1255 3607 1235 3608 1256 3609 1235 3610 1234 3611 1257 3612 1256 3613 1234 3614 1258 3615 1257 3616 1234 3617 1259 3618 1258 3619 1234 3620 1259 3621 1234 3622 1233 3623 1260 3624 1259 3625 1233 3626 1261 3627 1260 3628 1310 3629 1310 3630 1260 3631 1233 3632 1262 3633 1261 3634 1310 3635 1263 3636 1262 3637 1310 3638 1263 3639 1310 3640 1309 3641 1292 3642 1310 3643 1233 3644 1264 3645 1263 3646 1309 3647 1264 3648 1309 3649 1308 3650 1265 3651 1264 3652 1308 3653 1265 3654 1308 3655 1307 3656 1265 3657 1307 3658 1306 3659 1266 3660 1265 3661 1306 3662 1266 3663 1306 3664 1305 3665 1266 3666 1305 3667 1304 3668 1267 3669 1266 3670 1304 3671 1267 3672 1304 3673 1303 3674 1268 3675 1267 3676 1303 3677 1268 3678 1303 3679 1302 3680 1293 3681 1292 3682 1233 3683 1268 3684 1302 3685 1301 3686 1294 3687 1293 3688 1233 3689 1222 3690 1221 3691 1291 3692 1294 3693 1233 3694 1232 3695 1223 3696 1222 3697 1291 3698 1269 3699 1268 3700 1301 3701 1269 3702 1301 3703 1300 3704 1294 3705 1232 3706 1231 3707 1295 3708 1294 3709 1231 3710 1224 3711 1223 3712 1291 3713 1295 3714 1231 3715 1230 3716 1296 3717 1295 3718 1230 3719 1225 3720 1224 3721 1291 3722 1269 3723 1300 3724 1299 3725 1296 3726 1230 3727 1229 3728 1226 3729 1225 3730 1291 3731 1297 3732 1296 3733 1229 3734 1297 3735 1229 3736 1228 3737 1227 3738 1226 3739 1291 3740 1297 3741 1228 3742 1227 3743 1269 3744 1299 3745 1298 3746 1297 3747 1227 3748 1291 3749 1298 3750 1297 3751 1291 3752 1269 3753 1298 3754 1279 3755 1279 3756 1298 3757 1291 3758 1270 3759 1269 3760 1279 3761 1270 3762 1279 3763 1278 3764 1280 3765 1279 3766 1291 3767 1280 3768 1291 3769 1290 3770 1271 3771 1270 3772 1278 3773 1271 3774 1278 3775 1277 3776 1281 3777 1280 3778 1290 3779 1281 3780 1290 3781 1289 3782 1271 3783 1277 3784 1276 3785 1282 3786 1281 3787 1289 3788 1272 3789 1271 3790 1276 3791 1282 3792 1289 3793 1288 3794 1272 3795 1276 3796 1275 3797 1283 3798 1282 3799 1288 3800 1283 3801 1288 3802 1287 3803 1272 3804 1275 3805 1274 3806 1284 3807 1283 3808 1287 3809 1273 3810 1272 3811 1274 3812 1284 3813 1287 3814 1286 3815 1285 3816 1284 3817 1286 3818 1312 3819 1311 3820 1334 3821 1312 3822 1334 3823 1333 3824 1313 3825 1312 3826 1333 3827 1313 3828 1333 3829 1332 3830 1314 3831 1313 3832 1332 3833 1314 3834 1332 3835 1335 3836 1335 3837 1332 3838 1336 3839 1336 3840 1332 3841 1331 3842 1315 3843 1314 3844 1358 3845 1358 3846 1314 3847 1335 3848 1315 3849 1358 3850 1357 3851 1337 3852 1336 3853 1331 3854 1315 3855 1357 3856 1356 3857 1338 3858 1337 3859 1331 3860 1338 3861 1331 3862 1330 3863 1316 3864 1315 3865 1356 3866 1316 3867 1356 3868 1355 3869 1339 3870 1338 3871 1330 3872 1316 3873 1355 3874 1354 3875 1340 3876 1339 3877 1330 3878 1340 3879 1330 3880 1329 3881 1317 3882 1316 3883 1354 3884 1317 3885 1354 3886 1353 3887 1341 3888 1340 3889 1329 3890 1318 3891 1317 3892 1353 3893 1318 3894 1353 3895 1352 3896 1341 3897 1329 3898 1328 3899 1342 3900 1341 3901 1328 3902 1318 3903 1352 3904 1351 3905 1343 3906 1342 3907 1328 3908 1319 3909 1318 3910 1351 3911 1343 3912 1328 3913 1327 3914 1319 3915 1351 3916 1350 3917 1344 3918 1343 3919 1327 3920 1319 3921 1350 3922 1349 3923 1345 3924 1344 3925 1327 3926 1320 3927 1319 3928 1349 3929 1345 3930 1327 3931 1326 3932 1320 3933 1349 3934 1348 3935 1346 3936 1345 3937 1326 3938 1320 3939 1348 3940 1347 3941 1347 3942 1346 3943 1326 3944 1320 3945 1347 3946 1326 3947 1321 3948 1320 3949 1326 3950 1321 3951 1326 3952 1325 3953 1322 3954 1321 3955 1325 3956 1322 3957 1325 3958 1324 3959 1323 3960 1322 3961 1324 3962 1360 3963 1359 3964 1392 3965 1360 3966 1392 3967 1391 3968 1360 3969 1391 3970 1390 3971 1361 3972 1360 3973 1390 3974 1362 3975 1361 3976 1390 3977 1363 3978 1362 3979 1389 3980 1389 3981 1362 3982 1390 3983 1363 3984 1389 3985 1388 3986 1363 3987 1388 3988 1387 3989 1364 3990 1363 3991 1387 3992 1364 3993 1387 3994 1386 3995 1377 3996 1376 3997 1375 3998 1364 3999 1386 4000 1385 4001 1378 4002 1377 4003 1375 4004 1365 4005 1364 4006 1385 4007 1379 4008 1378 4009 1375 4010 1365 4011 1385 4012 1384 4013 1380 4014 1379 4015 1375 4016 1365 4017 1384 4018 1383 4019 1381 4020 1380 4021 1375 4022 1365 4023 1383 4024 1382 4025 1382 4026 1381 4027 1375 4028 1365 4029 1382 4030 1375 4031 1366 4032 1365 4033 1375 4034 1367 4035 1366 4036 1375 4037 1367 4038 1375 4039 1374 4040 1367 4041 1374 4042 1373 4043 1368 4044 1367 4045 1373 4046 1368 4047 1373 4048 1372 4049 1368 4050 1372 4051 1371 4052 1369 4053 1368 4054 1371 4055 1369 4056 1371 4057 1370 4058 1413 4059 1412 4060 1411 4061 1413 4062 1411 4063 1410 4064 1414 4065 1413 4066 1410 4067 1414 4068 1410 4069 1409 4070 1415 4071 1414 4072 1409 4073 1415 4074 1409 4075 1437 4076 1437 4077 1409 4078 1438 4079 1438 4080 1409 4081 1408 4082 1416 4083 1415 4084 1436 4085 1436 4086 1415 4087 1437 4088 1416 4089 1436 4090 1435 4091 1439 4092 1438 4093 1408 4094 1416 4095 1435 4096 1434 4097 1440 4098 1439 4099 1408 4100 1416 4101 1434 4102 1433 4103 1441 4104 1440 4105 1408 4106 1417 4107 1416 4108 1433 4109 1441 4110 1408 4111 1407 4112 1417 4113 1433 4114 1432 4115 1442 4116 1441 4117 1407 4118 1417 4119 1432 4120 1431 4121 1443 4122 1442 4123 1407 4124 1418 4125 1417 4126 1431 4127 1443 4128 1407 4129 1406 4130 1418 4131 1431 4132 1443 4133 1418 4134 1443 4135 1406 4136 1419 4137 1418 4138 1405 4139 1405 4140 1418 4141 1406 4142 1419 4143 1405 4144 1404 4145 1419 4146 1404 4147 1403 4148 1420 4149 1419 4150 1403 4151 1420 4152 1403 4153 1402 4154 1394 4155 1393 4156 1430 4157 1395 4158 1394 4159 1430 4160 1421 4161 1420 4162 1402 4163 1421 4164 1402 4165 1401 4166 1396 4167 1395 4168 1430 4169 1421 4170 1401 4171 1400 4172 1397 4173 1396 4174 1430 4175 1398 4176 1397 4177 1430 4178 1421 4179 1400 4180 1399 4181 1399 4182 1398 4183 1430 4184 1421 4185 1399 4186 1430 4187 1422 4188 1421 4189 1430 4190 1422 4191 1430 4192 1429 4193 1422 4194 1429 4195 1428 4196 1423 4197 1422 4198 1428 4199 1423 4200 1428 4201 1427 4202 1423 4203 1427 4204 1426 4205 1424 4206 1423 4207 1426 4208 1424 4209 1426 4210 1425 4211 1451 4212 1450 4213 1449 4214 1451 4215 1449 4216 1448 4217 1452 4218 1451 4219 1448 4220 1452 4221 1448 4222 1447 4223 1452 4224 1447 4225 1446 4226 1453 4227 1452 4228 1446 4229 1453 4230 1446 4231 1445 4232 1453 4233 1445 4234 1444 4235 1454 4236 1453 4237 1444 4238 1454 4239 1444 4240 1505 4241 1505 4242 1444 4243 1506 4244 1506 4245 1444 4246 1507 4247 1507 4248 1444 4249 1508 4250 1508 4251 1444 4252 1509 4253 1509 4254 1444 4255 1510 4256 1510 4257 1444 4258 1511 4259 1455 4260 1454 4261 1505 4262 1455 4263 1505 4264 1504 4265 1455 4266 1504 4267 1503 4268 1455 4269 1503 4270 1502 4271 1456 4272 1455 4273 1502 4274 1456 4275 1502 4276 1501 4277 1456 4278 1501 4279 1500 4280 1456 4281 1500 4282 1499 4283 1456 4284 1499 4285 1498 4286 1457 4287 1456 4288 1498 4289 1457 4290 1498 4291 1497 4292 1457 4293 1497 4294 1496 4295 1457 4296 1496 4297 1495 4298 1457 4299 1495 4300 1494 4301 1458 4302 1457 4303 1494 4304 1458 4305 1494 4306 1493 4307 1458 4308 1493 4309 1492 4310 1459 4311 1458 4312 1492 4313 1459 4314 1492 4315 1491 4316 1460 4317 1459 4318 1491 4319 1460 4320 1491 4321 1490 4322 1460 4323 1490 4324 1489 4325 1461 4326 1460 4327 1489 4328 1461 4329 1489 4330 1488 4331 1462 4332 1461 4333 1488 4334 1462 4335 1488 4336 1487 4337 1475 4338 1474 4339 1473 4340 1462 4341 1487 4342 1486 4343 1463 4344 1462 4345 1486 4346 1475 4347 1473 4348 1472 4349 1464 4350 1463 4351 1486 4352 1475 4353 1472 4354 1471 4355 1465 4356 1464 4357 1486 4358 1465 4359 1486 4360 1485 4361 1475 4362 1471 4363 1470 4364 1466 4365 1465 4366 1485 4367 1467 4368 1466 4369 1485 4370 1475 4371 1470 4372 1469 4373 1468 4374 1467 4375 1485 4376 1475 4377 1469 4378 1468 4379 1475 4380 1468 4381 1485 4382 1475 4383 1485 4384 1484 4385 1476 4386 1475 4387 1484 4388 1476 4389 1484 4390 1483 4391 1477 4392 1476 4393 1483 4394 1478 4395 1477 4396 1483 4397 1478 4398 1483 4399 1482 4400 1479 4401 1478 4402 1482 4403 1479 4404 1482 4405 1481 4406 1480 4407 1479 4408 1481 4409 1530 4410 1529 4411 1528 4412 1530 4413 1528 4414 1527 4415 1515 4416 1514 4417 1513 4418 1515 4419 1513 4420 1512 4421 1531 4422 1530 4423 1527 4424 1531 4425 1527 4426 1526 4427 1531 4428 1526 4429 1525 4430 1516 4431 1515 4432 1512 4433 1532 4434 1531 4435 1525 4436 1532 4437 1525 4438 1524 4439 1517 4440 1516 4441 1512 4442 1518 4443 1517 4444 1542 4445 1542 4446 1517 4447 1512 4448 1532 4449 1524 4450 1523 4451 1519 4452 1518 4453 1542 4454 1532 4455 1523 4456 1522 4457 1533 4458 1532 4459 1522 4460 1520 4461 1519 4462 1542 4463 1533 4464 1522 4465 1521 4466 1521 4467 1520 4468 1542 4469 1533 4470 1521 4471 1542 4472 1533 4473 1542 4474 1541 4475 1543 4476 1542 4477 1512 4478 1533 4479 1541 4480 1540 4481 1534 4482 1533 4483 1540 4484 1534 4485 1540 4486 1539 4487 1535 4488 1534 4489 1539 4490 1535 4491 1539 4492 1538 4493 1535 4494 1538 4495 1537 4496 1536 4497 1535 4498 1537 4499 1545 4500 1544 4501 1567 4502 1545 4503 1567 4504 1566 4505 1546 4506 1545 4507 1566 4508 1546 4509 1566 4510 1565 4511 1547 4512 1546 4513 1565 4514 1547 4515 1565 4516 1568 4517 1568 4518 1565 4519 1569 4520 1569 4521 1565 4522 1564 4523 1548 4524 1547 4525 1591 4526 1591 4527 1547 4528 1568 4529 1548 4530 1591 4531 1590 4532 1570 4533 1569 4534 1564 4535 1548 4536 1590 4537 1589 4538 1571 4539 1570 4540 1564 4541 1571 4542 1564 4543 1563 4544 1549 4545 1548 4546 1589 4547 1549 4548 1589 4549 1588 4550 1572 4551 1571 4552 1563 4553 1549 4554 1588 4555 1587 4556 1573 4557 1572 4558 1563 4559 1573 4560 1563 4561 1562 4562 1550 4563 1549 4564 1587 4565 1550 4566 1587 4567 1586 4568 1574 4569 1573 4570 1562 4571 1551 4572 1550 4573 1586 4574 1551 4575 1586 4576 1585 4577 1574 4578 1562 4579 1561 4580 1575 4581 1574 4582 1561 4583 1551 4584 1585 4585 1584 4586 1576 4587 1575 4588 1561 4589 1552 4590 1551 4591 1584 4592 1576 4593 1561 4594 1560 4595 1552 4596 1584 4597 1583 4598 1577 4599 1576 4600 1560 4601 1552 4602 1583 4603 1582 4604 1578 4605 1577 4606 1560 4607 1553 4608 1552 4609 1582 4610 1578 4611 1560 4612 1559 4613 1553 4614 1582 4615 1581 4616 1579 4617 1578 4618 1559 4619 1553 4620 1581 4621 1580 4622 1580 4623 1579 4624 1559 4625 1553 4626 1580 4627 1559 4628 1554 4629 1553 4630 1559 4631 1554 4632 1559 4633 1558 4634 1555 4635 1554 4636 1558 4637 1555 4638 1558 4639 1557 4640 1556 4641 1555 4642 1557 4643 1644 4644 1643 4645 1642 4646 1632 4647 1631 4648 1630 4649 1645 4650 1644 4651 1642 4652 1645 4653 1642 4654 1641 4655 1633 4656 1632 4657 1630 4658 1633 4659 1630 4660 1629 4661 1646 4662 1645 4663 1641 4664 1593 4665 1592 4666 1650 4667 1593 4668 1650 4669 1649 4670 1646 4671 1641 4672 1640 4673 1634 4674 1633 4675 1629 4676 1647 4677 1646 4678 1640 4679 1647 4680 1640 4681 1639 4682 1634 4683 1629 4684 1628 4685 1635 4686 1634 4687 1628 4688 1648 4689 1647 4690 1639 4691 1648 4692 1639 4693 1638 4694 1636 4695 1635 4696 1628 4697 1649 4698 1648 4699 1638 4700 1636 4701 1628 4702 1627 4703 1649 4704 1638 4705 1637 4706 1637 4707 1636 4708 1616 4709 1616 4710 1636 4711 1627 4712 1593 4713 1649 4714 1595 4715 1595 4716 1649 4717 1596 4718 1596 4719 1649 4720 1597 4721 1597 4722 1649 4723 1598 4724 1598 4725 1649 4726 1599 4727 1599 4728 1649 4729 1600 4730 1600 4731 1649 4732 1601 4733 1601 4734 1649 4735 1637 4736 1602 4737 1601 4738 1637 4739 1637 4740 1616 4741 1615 4742 1617 4743 1616 4744 1627 4745 1637 4746 1615 4747 1614 4748 1603 4749 1602 4750 1637 4751 1618 4752 1617 4753 1627 4754 1603 4755 1637 4756 1614 4757 1603 4758 1614 4759 1613 4760 1618 4761 1627 4762 1626 4763 1604 4764 1603 4765 1613 4766 1619 4767 1618 4768 1626 4769 1604 4770 1613 4771 1612 4772 1605 4773 1604 4774 1612 4775 1620 4776 1619 4777 1626 4778 1605 4779 1612 4780 1611 4781 1605 4782 1611 4783 1610 4784 1606 4785 1605 4786 1610 4787 1621 4788 1620 4789 1626 4790 1621 4791 1626 4792 1625 4793 1593 4794 1595 4795 1594 4796 1606 4797 1610 4798 1609 4799 1607 4800 1606 4801 1609 4802 1622 4803 1621 4804 1625 4805 1622 4806 1625 4807 1624 4808 1608 4809 1607 4810 1609 4811 1623 4812 1622 4813 1624 4814 1652 4815 1651 4816 1684 4817 1652 4818 1684 4819 1683 4820 1652 4821 1683 4822 1682 4823 1653 4824 1652 4825 1682 4826 1654 4827 1653 4828 1682 4829 1655 4830 1654 4831 1681 4832 1681 4833 1654 4834 1682 4835 1655 4836 1681 4837 1680 4838 1655 4839 1680 4840 1679 4841 1656 4842 1655 4843 1679 4844 1656 4845 1679 4846 1678 4847 1669 4848 1668 4849 1667 4850 1656 4851 1678 4852 1677 4853 1670 4854 1669 4855 1667 4856 1657 4857 1656 4858 1677 4859 1671 4860 1670 4861 1667 4862 1657 4863 1677 4864 1676 4865 1672 4866 1671 4867 1667 4868 1657 4869 1676 4870 1675 4871 1673 4872 1672 4873 1667 4874 1657 4875 1675 4876 1674 4877 1674 4878 1673 4879 1667 4880 1657 4881 1674 4882 1667 4883 1658 4884 1657 4885 1667 4886 1659 4887 1658 4888 1667 4889 1659 4890 1667 4891 1666 4892 1659 4893 1666 4894 1665 4895 1660 4896 1659 4897 1665 4898 1660 4899 1665 4900 1664 4901 1660 4902 1664 4903 1663 4904 1661 4905 1660 4906 1663 4907 1661 4908 1663 4909 1662 4910 1688 4911 1687 4912 1686 4913 1688 4914 1686 4915 1685 4916 1689 4917 1688 4918 1685 4919 1689 4920 1685 4921 1720 4922 1690 4923 1689 4924 1720 4925 1691 4926 1690 4927 1717 4928 1717 4929 1690 4930 1718 4931 1718 4932 1690 4933 1719 4934 1719 4935 1690 4936 1720 4937 1692 4938 1691 4939 1717 4940 1693 4941 1692 4942 1714 4943 1714 4944 1692 4945 1715 4946 1715 4947 1692 4948 1716 4949 1716 4950 1692 4951 1717 4952 1694 4953 1693 4954 1713 4955 1713 4956 1693 4957 1714 4958 1694 4959 1713 4960 1712 4961 1694 4962 1712 4963 1711 4964 1695 4965 1694 4966 1711 4967 1695 4968 1711 4969 1710 4970 1696 4971 1695 4972 1710 4973 1696 4974 1710 4975 1709 4976 1696 4977 1709 4978 1708 4979 1697 4980 1696 4981 1708 4982 1697 4983 1708 4984 1707 4985 1698 4986 1697 4987 1707 4988 1700 4989 1699 4990 1698 4991 1700 4992 1698 4993 1707 4994 1700 4995 1707 4996 1706 4997 1700 4998 1706 4999 1705 5000 1701 5001 1700 5002 1705 5003 1702 5004 1701 5005 1704 5006 1704 5007 1701 5008 1705 5009 1702 5010 1704 5011 1703 5012 1741 5013 1740 5014 1739 5015 1741 5016 1739 5017 1738 5018 1742 5019 1741 5020 1738 5021 1742 5022 1738 5023 1737 5024 1743 5025 1742 5026 1737 5027 1743 5028 1737 5029 1765 5030 1765 5031 1737 5032 1766 5033 1766 5034 1737 5035 1736 5036 1744 5037 1743 5038 1764 5039 1764 5040 1743 5041 1765 5042 1744 5043 1764 5044 1763 5045 1767 5046 1766 5047 1736 5048 1744 5049 1763 5050 1762 5051 1768 5052 1767 5053 1736 5054 1744 5055 1762 5056 1761 5057 1769 5058 1768 5059 1736 5060 1745 5061 1744 5062 1761 5063 1769 5064 1736 5065 1735 5066 1745 5067 1761 5068 1760 5069 1770 5070 1769 5071 1735 5072 1745 5073 1760 5074 1759 5075 1771 5076 1770 5077 1735 5078 1746 5079 1745 5080 1759 5081 1771 5082 1735 5083 1734 5084 1746 5085 1759 5086 1771 5087 1746 5088 1771 5089 1734 5090 1747 5091 1746 5092 1733 5093 1733 5094 1746 5095 1734 5096 1747 5097 1733 5098 1732 5099 1747 5100 1732 5101 1731 5102 1748 5103 1747 5104 1731 5105 1748 5106 1731 5107 1730 5108 1722 5109 1721 5110 1758 5111 1723 5112 1722 5113 1758 5114 1749 5115 1748 5116 1730 5117 1749 5118 1730 5119 1729 5120 1724 5121 1723 5122 1758 5123 1749 5124 1729 5125 1728 5126 1725 5127 1724 5128 1758 5129 1726 5130 1725 5131 1758 5132 1749 5133 1728 5134 1727 5135 1727 5136 1726 5137 1758 5138 1749 5139 1727 5140 1758 5141 1750 5142 1749 5143 1758 5144 1750 5145 1758 5146 1757 5147 1750 5148 1757 5149 1756 5150 1751 5151 1750 5152 1756 5153 1751 5154 1756 5155 1755 5156 1751 5157 1755 5158 1754 5159 1752 5160 1751 5161 1754 5162 1752 5163 1754 5164 1753 5165 1774 5166 1773 5167 1772 5168 1774 5169 1772 5170 1775 5171 1789 5172 1788 5173 1787 5174 1790 5175 1789 5176 1787 5177 1790 5178 1787 5179 1786 5180 1791 5181 1790 5182 1786 5183 1791 5184 1786 5185 1785 5186 1792 5187 1791 5188 1785 5189 1792 5190 1785 5191 1784 5192 1793 5193 1792 5194 1784 5195 1794 5196 1793 5197 1784 5198 1794 5199 1784 5200 1783 5201 1795 5202 1794 5203 1783 5204 1795 5205 1783 5206 1782 5207 1796 5208 1795 5209 1782 5210 1797 5211 1796 5212 1782 5213 1797 5214 1782 5215 1781 5216 1798 5217 1797 5218 1781 5219 1799 5220 1798 5221 1800 5222 1800 5223 1798 5224 1781 5225 1801 5226 1800 5227 1781 5228 1801 5229 1781 5230 1780 5231 1802 5232 1801 5233 1780 5234 1803 5235 1802 5236 1780 5237 1803 5238 1780 5239 1779 5240 1804 5241 1803 5242 1779 5243 1804 5244 1779 5245 1778 5246 1805 5247 1804 5248 1778 5249 1805 5250 1778 5251 1777 5252 1806 5253 1805 5254 1777 5255 1776 5256 1806 5257 1777 5258 1859 5259 1858 5260 1857 5261 1847 5262 1846 5263 1845 5264 1860 5265 1859 5266 1857 5267 1860 5268 1857 5269 1856 5270 1848 5271 1847 5272 1845 5273 1848 5274 1845 5275 1844 5276 1861 5277 1860 5278 1856 5279 1808 5280 1807 5281 1865 5282 1808 5283 1865 5284 1864 5285 1861 5286 1856 5287 1855 5288 1849 5289 1848 5290 1844 5291 1862 5292 1861 5293 1855 5294 1862 5295 1855 5296 1854 5297 1849 5298 1844 5299 1843 5300 1850 5301 1849 5302 1843 5303 1863 5304 1862 5305 1854 5306 1863 5307 1854 5308 1853 5309 1851 5310 1850 5311 1843 5312 1864 5313 1863 5314 1853 5315 1851 5316 1843 5317 1842 5318 1864 5319 1853 5320 1852 5321 1852 5322 1851 5323 1831 5324 1831 5325 1851 5326 1842 5327 1808 5328 1864 5329 1810 5330 1810 5331 1864 5332 1811 5333 1811 5334 1864 5335 1812 5336 1812 5337 1864 5338 1813 5339 1813 5340 1864 5341 1814 5342 1814 5343 1864 5344 1815 5345 1815 5346 1864 5347 1816 5348 1816 5349 1864 5350 1852 5351 1817 5352 1816 5353 1852 5354 1852 5355 1831 5356 1830 5357 1832 5358 1831 5359 1842 5360 1852 5361 1830 5362 1829 5363 1818 5364 1817 5365 1852 5366 1833 5367 1832 5368 1842 5369 1818 5370 1852 5371 1829 5372 1818 5373 1829 5374 1828 5375 1833 5376 1842 5377 1841 5378 1819 5379 1818 5380 1828 5381 1834 5382 1833 5383 1841 5384 1819 5385 1828 5386 1827 5387 1820 5388 1819 5389 1827 5390 1835 5391 1834 5392 1841 5393 1820 5394 1827 5395 1826 5396 1820 5397 1826 5398 1825 5399 1821 5400 1820 5401 1825 5402 1836 5403 1835 5404 1841 5405 1836 5406 1841 5407 1840 5408 1808 5409 1810 5410 1809 5411 1821 5412 1825 5413 1824 5414 1822 5415 1821 5416 1824 5417 1837 5418 1836 5419 1840 5420 1837 5421 1840 5422 1839 5423 1823 5424 1822 5425 1824 5426 1838 5427 1837 5428 1839 5429 1877 5430 1876 5431 1875 5432 1878 5433 1877 5434 1875 5435 1878 5436 1875 5437 1874 5438 1879 5439 1878 5440 1874 5441 1879 5442 1874 5443 1873 5444 1880 5445 1879 5446 1873 5447 1880 5448 1873 5449 1872 5450 1881 5451 1880 5452 1872 5453 1881 5454 1872 5455 1871 5456 1882 5457 1881 5458 1871 5459 1882 5460 1871 5461 1870 5462 1883 5463 1882 5464 1870 5465 1883 5466 1870 5467 1893 5468 1884 5469 1883 5470 1893 5471 1884 5472 1893 5473 1892 5474 1885 5475 1884 5476 1892 5477 1885 5478 1892 5479 1891 5480 1886 5481 1885 5482 1891 5483 1886 5484 1891 5485 1890 5486 1887 5487 1886 5488 1890 5489 1887 5490 1890 5491 1889 5492 1888 5493 1887 5494 1889 5495 1868 5496 1867 5497 1866 5498 1868 5499 1866 5500 1869 5501 1914 5502 1913 5503 1912 5504 1915 5505 1914 5506 1912 5507 1915 5508 1912 5509 1911 5510 1916 5511 1915 5512 1911 5513 1917 5514 1916 5515 1911 5516 1917 5517 1911 5518 1910 5519 1918 5520 1917 5521 1910 5522 1918 5523 1910 5524 1909 5525 1919 5526 1918 5527 1909 5528 1920 5529 1919 5530 1921 5531 1921 5532 1919 5533 1922 5534 1922 5535 1919 5536 1923 5537 1923 5538 1919 5539 1924 5540 1924 5541 1919 5542 1925 5543 1925 5544 1919 5545 1926 5546 1926 5547 1919 5548 1909 5549 1926 5550 1909 5551 1927 5552 1927 5553 1909 5554 1908 5555 1928 5556 1927 5557 1908 5558 1929 5559 1928 5560 1908 5561 1929 5562 1908 5563 1907 5564 1930 5565 1929 5566 1907 5567 1931 5568 1930 5569 1907 5570 1932 5571 1931 5572 1907 5573 1932 5574 1907 5575 1906 5576 1933 5577 1932 5578 1906 5579 1934 5580 1933 5581 1983 5582 1983 5583 1933 5584 1906 5585 1935 5586 1934 5587 1983 5588 1936 5589 1935 5590 1983 5591 1936 5592 1983 5593 1982 5594 1965 5595 1983 5596 1906 5597 1937 5598 1936 5599 1982 5600 1937 5601 1982 5602 1981 5603 1938 5604 1937 5605 1981 5606 1938 5607 1981 5608 1980 5609 1938 5610 1980 5611 1979 5612 1939 5613 1938 5614 1979 5615 1939 5616 1979 5617 1978 5618 1939 5619 1978 5620 1977 5621 1940 5622 1939 5623 1977 5624 1940 5625 1977 5626 1976 5627 1941 5628 1940 5629 1976 5630 1941 5631 1976 5632 1975 5633 1966 5634 1965 5635 1906 5636 1941 5637 1975 5638 1974 5639 1967 5640 1966 5641 1906 5642 1895 5643 1894 5644 1964 5645 1967 5646 1906 5647 1905 5648 1896 5649 1895 5650 1964 5651 1942 5652 1941 5653 1974 5654 1942 5655 1974 5656 1973 5657 1967 5658 1905 5659 1904 5660 1968 5661 1967 5662 1904 5663 1897 5664 1896 5665 1964 5666 1968 5667 1904 5668 1903 5669 1969 5670 1968 5671 1903 5672 1898 5673 1897 5674 1964 5675 1942 5676 1973 5677 1972 5678 1969 5679 1903 5680 1902 5681 1899 5682 1898 5683 1964 5684 1970 5685 1969 5686 1902 5687 1970 5688 1902 5689 1901 5690 1900 5691 1899 5692 1964 5693 1970 5694 1901 5695 1900 5696 1942 5697 1972 5698 1971 5699 1970 5700 1900 5701 1964 5702 1971 5703 1970 5704 1964 5705 1942 5706 1971 5707 1952 5708 1952 5709 1971 5710 1964 5711 1943 5712 1942 5713 1952 5714 1943 5715 1952 5716 1951 5717 1953 5718 1952 5719 1964 5720 1953 5721 1964 5722 1963 5723 1944 5724 1943 5725 1951 5726 1944 5727 1951 5728 1950 5729 1954 5730 1953 5731 1963 5732 1954 5733 1963 5734 1962 5735 1944 5736 1950 5737 1949 5738 1955 5739 1954 5740 1962 5741 1945 5742 1944 5743 1949 5744 1955 5745 1962 5746 1961 5747 1945 5748 1949 5749 1948 5750 1956 5751 1955 5752 1961 5753 1956 5754 1961 5755 1960 5756 1945 5757 1948 5758 1947 5759 1957 5760 1956 5761 1960 5762 1946 5763 1945 5764 1947 5765 1957 5766 1960 5767 1959 5768 1958 5769 1957 5770 1959 5771 2004 5772 2003 5773 2002 5774 2004 5775 2002 5776 2001 5777 2005 5778 2004 5779 2001 5780 2005 5781 2001 5782 2000 5783 2006 5784 2005 5785 2000 5786 2006 5787 2000 5788 2028 5789 2028 5790 2000 5791 2029 5792 2029 5793 2000 5794 1999 5795 2007 5796 2006 5797 2027 5798 2027 5799 2006 5800 2028 5801 2007 5802 2027 5803 2026 5804 2030 5805 2029 5806 1999 5807 2007 5808 2026 5809 2025 5810 2031 5811 2030 5812 1999 5813 2007 5814 2025 5815 2024 5816 2032 5817 2031 5818 1999 5819 2008 5820 2007 5821 2024 5822 2032 5823 1999 5824 1998 5825 2008 5826 2024 5827 2023 5828 2033 5829 2032 5830 1998 5831 2008 5832 2023 5833 2022 5834 2034 5835 2033 5836 1998 5837 2009 5838 2008 5839 2022 5840 2034 5841 1998 5842 1997 5843 2009 5844 2022 5845 2034 5846 2009 5847 2034 5848 1997 5849 2010 5850 2009 5851 1996 5852 1996 5853 2009 5854 1997 5855 2010 5856 1996 5857 1995 5858 2010 5859 1995 5860 1994 5861 2011 5862 2010 5863 1994 5864 2011 5865 1994 5866 1993 5867 1985 5868 1984 5869 2021 5870 1986 5871 1985 5872 2021 5873 2012 5874 2011 5875 1993 5876 2012 5877 1993 5878 1992 5879 1987 5880 1986 5881 2021 5882 2012 5883 1992 5884 1991 5885 1988 5886 1987 5887 2021 5888 1989 5889 1988 5890 2021 5891 2012 5892 1991 5893 1990 5894 1990 5895 1989 5896 2021 5897 2012 5898 1990 5899 2021 5900 2013 5901 2012 5902 2021 5903 2013 5904 2021 5905 2020 5906 2013 5907 2020 5908 2019 5909 2014 5910 2013 5911 2019 5912 2014 5913 2019 5914 2018 5915 2014 5916 2018 5917 2017 5918 2015 5919 2014 5920 2017 5921 2015 5922 2017 5923 2016 5924 2042 5925 2041 5926 2040 5927 2042 5928 2040 5929 2039 5930 2043 5931 2042 5932 2039 5933 2043 5934 2039 5935 2038 5936 2043 5937 2038 5938 2037 5939 2044 5940 2043 5941 2037 5942 2044 5943 2037 5944 2036 5945 2044 5946 2036 5947 2035 5948 2045 5949 2044 5950 2035 5951 2045 5952 2035 5953 2096 5954 2096 5955 2035 5956 2097 5957 2097 5958 2035 5959 2098 5960 2098 5961 2035 5962 2099 5963 2099 5964 2035 5965 2100 5966 2100 5967 2035 5968 2101 5969 2101 5970 2035 5971 2102 5972 2046 5973 2045 5974 2096 5975 2046 5976 2096 5977 2095 5978 2046 5979 2095 5980 2094 5981 2046 5982 2094 5983 2093 5984 2047 5985 2046 5986 2093 5987 2047 5988 2093 5989 2092 5990 2047 5991 2092 5992 2091 5993 2047 5994 2091 5995 2090 5996 2047 5997 2090 5998 2089 5999 2048 6000 2047 6001 2089 6002 2048 6003 2089 6004 2088 6005 2048 6006 2088 6007 2087 6008 2048 6009 2087 6010 2086 6011 2048 6012 2086 6013 2085 6014 2049 6015 2048 6016 2085 6017 2049 6018 2085 6019 2084 6020 2049 6021 2084 6022 2083 6023 2050 6024 2049 6025 2083 6026 2050 6027 2083 6028 2082 6029 2051 6030 2050 6031 2082 6032 2051 6033 2082 6034 2081 6035 2051 6036 2081 6037 2080 6038 2052 6039 2051 6040 2080 6041 2052 6042 2080 6043 2079 6044 2053 6045 2052 6046 2079 6047 2053 6048 2079 6049 2078 6050 2066 6051 2065 6052 2064 6053 2053 6054 2078 6055 2077 6056 2054 6057 2053 6058 2077 6059 2066 6060 2064 6061 2063 6062 2055 6063 2054 6064 2077 6065 2066 6066 2063 6067 2062 6068 2056 6069 2055 6070 2077 6071 2056 6072 2077 6073 2076 6074 2066 6075 2062 6076 2061 6077 2057 6078 2056 6079 2076 6080 2058 6081 2057 6082 2076 6083 2066 6084 2061 6085 2060 6086 2059 6087 2058 6088 2076 6089 2066 6090 2060 6091 2059 6092 2066 6093 2059 6094 2076 6095 2066 6096 2076 6097 2075 6098 2067 6099 2066 6100 2075 6101 2067 6102 2075 6103 2074 6104 2068 6105 2067 6106 2074 6107 2069 6108 2068 6109 2074 6110 2069 6111 2074 6112 2073 6113 2070 6114 2069 6115 2073 6116 2070 6117 2073 6118 2072 6119 2071 6120 2070 6121 2072 6122 2121 6123 2120 6124 2119 6125 2121 6126 2119 6127 2118 6128 2106 6129 2105 6130 2104 6131 2106 6132 2104 6133 2103 6134 2122 6135 2121 6136 2118 6137 2122 6138 2118 6139 2117 6140 2122 6141 2117 6142 2116 6143 2107 6144 2106 6145 2103 6146 2123 6147 2122 6148 2116 6149 2123 6150 2116 6151 2115 6152 2108 6153 2107 6154 2103 6155 2109 6156 2108 6157 2133 6158 2133 6159 2108 6160 2103 6161 2123 6162 2115 6163 2114 6164 2110 6165 2109 6166 2133 6167 2123 6168 2114 6169 2113 6170 2124 6171 2123 6172 2113 6173 2111 6174 2110 6175 2133 6176 2124 6177 2113 6178 2112 6179 2112 6180 2111 6181 2133 6182 2124 6183 2112 6184 2133 6185 2124 6186 2133 6187 2132 6188 2134 6189 2133 6190 2103 6191 2124 6192 2132 6193 2131 6194 2125 6195 2124 6196 2131 6197 2125 6198 2131 6199 2130 6200 2126 6201 2125 6202 2130 6203 2126 6204 2130 6205 2129 6206 2126 6207 2129 6208 2128 6209 2127 6210 2126 6211 2128 6212 2136 6213 2135 6214 2158 6215 2136 6216 2158 6217 2157 6218 2137 6219 2136 6220 2157 6221 2137 6222 2157 6223 2156 6224 2138 6225 2137 6226 2156 6227 2138 6228 2156 6229 2159 6230 2159 6231 2156 6232 2160 6233 2160 6234 2156 6235 2155 6236 2139 6237 2138 6238 2182 6239 2182 6240 2138 6241 2159 6242 2139 6243 2182 6244 2181 6245 2161 6246 2160 6247 2155 6248 2139 6249 2181 6250 2180 6251 2162 6252 2161 6253 2155 6254 2162 6255 2155 6256 2154 6257 2140 6258 2139 6259 2180 6260 2140 6261 2180 6262 2179 6263 2163 6264 2162 6265 2154 6266 2140 6267 2179 6268 2178 6269 2164 6270 2163 6271 2154 6272 2164 6273 2154 6274 2153 6275 2141 6276 2140 6277 2178 6278 2141 6279 2178 6280 2177 6281 2165 6282 2164 6283 2153 6284 2142 6285 2141 6286 2177 6287 2142 6288 2177 6289 2176 6290 2165 6291 2153 6292 2152 6293 2166 6294 2165 6295 2152 6296 2142 6297 2176 6298 2175 6299 2167 6300 2166 6301 2152 6302 2143 6303 2142 6304 2175 6305 2167 6306 2152 6307 2151 6308 2143 6309 2175 6310 2174 6311 2168 6312 2167 6313 2151 6314 2143 6315 2174 6316 2173 6317 2169 6318 2168 6319 2151 6320 2144 6321 2143 6322 2173 6323 2169 6324 2151 6325 2150 6326 2144 6327 2173 6328 2172 6329 2170 6330 2169 6331 2150 6332 2144 6333 2172 6334 2171 6335 2171 6336 2170 6337 2150 6338 2144 6339 2171 6340 2150 6341 2145 6342 2144 6343 2150 6344 2145 6345 2150 6346 2149 6347 2146 6348 2145 6349 2149 6350 2146 6351 2149 6352 2148 6353 2147 6354 2146 6355 2148 6356 2188 6357 2187 6358 2186 6359 2188 6360 2186 6361 2190 6362 2190 6363 2186 6364 2191 6365 2191 6366 2186 6367 2185 6368 2185 6369 2184 6370 2183 6371 2185 6372 2183 6373 2194 6374 2194 6375 2183 6376 2195 6377 2195 6378 2183 6379 2197 6380 2188 6381 2190 6382 2189 6383 2192 6384 2191 6385 2185 6386 2185 6387 2194 6388 2193 6389 2196 6390 2195 6391 2197 6392 2192 6393 2185 6394 2193 6395 2199 6396 2198 6397 2231 6398 2199 6399 2231 6400 2230 6401 2199 6402 2230 6403 2229 6404 2200 6405 2199 6406 2229 6407 2201 6408 2200 6409 2229 6410 2202 6411 2201 6412 2228 6413 2228 6414 2201 6415 2229 6416 2202 6417 2228 6418 2227 6419 2202 6420 2227 6421 2226 6422 2203 6423 2202 6424 2226 6425 2203 6426 2226 6427 2225 6428 2216 6429 2215 6430 2214 6431 2203 6432 2225 6433 2224 6434 2217 6435 2216 6436 2214 6437 2204 6438 2203 6439 2224 6440 2218 6441 2217 6442 2214 6443 2204 6444 2224 6445 2223 6446 2219 6447 2218 6448 2214 6449 2204 6450 2223 6451 2222 6452 2220 6453 2219 6454 2214 6455 2204 6456 2222 6457 2221 6458 2221 6459 2220 6460 2214 6461 2204 6462 2221 6463 2214 6464 2205 6465 2204 6466 2214 6467 2206 6468 2205 6469 2214 6470 2206 6471 2214 6472 2213 6473 2206 6474 2213 6475 2212 6476 2207 6477 2206 6478 2212 6479 2207 6480 2212 6481 2211 6482 2207 6483 2211 6484 2210 6485 2208 6486 2207 6487 2210 6488 2208 6489 2210 6490 2209 6491 2239 6492 2238 6493 2237 6494 2239 6495 2237 6496 2236 6497 2240 6498 2239 6499 2236 6500 2240 6501 2236 6502 2235 6503 2240 6504 2235 6505 2234 6506 2241 6507 2240 6508 2234 6509 2241 6510 2234 6511 2233 6512 2241 6513 2233 6514 2232 6515 2242 6516 2241 6517 2232 6518 2242 6519 2232 6520 2293 6521 2293 6522 2232 6523 2294 6524 2294 6525 2232 6526 2295 6527 2295 6528 2232 6529 2296 6530 2296 6531 2232 6532 2297 6533 2297 6534 2232 6535 2298 6536 2298 6537 2232 6538 2299 6539 2243 6540 2242 6541 2293 6542 2243 6543 2293 6544 2292 6545 2243 6546 2292 6547 2291 6548 2243 6549 2291 6550 2290 6551 2244 6552 2243 6553 2290 6554 2244 6555 2290 6556 2289 6557 2244 6558 2289 6559 2288 6560 2244 6561 2288 6562 2287 6563 2244 6564 2287 6565 2286 6566 2245 6567 2244 6568 2286 6569 2245 6570 2286 6571 2285 6572 2245 6573 2285 6574 2284 6575 2245 6576 2284 6577 2283 6578 2245 6579 2283 6580 2282 6581 2246 6582 2245 6583 2282 6584 2246 6585 2282 6586 2281 6587 2246 6588 2281 6589 2280 6590 2247 6591 2246 6592 2280 6593 2247 6594 2280 6595 2279 6596 2248 6597 2247 6598 2279 6599 2248 6600 2279 6601 2278 6602 2248 6603 2278 6604 2277 6605 2249 6606 2248 6607 2277 6608 2249 6609 2277 6610 2276 6611 2250 6612 2249 6613 2276 6614 2250 6615 2276 6616 2275 6617 2263 6618 2262 6619 2261 6620 2250 6621 2275 6622 2274 6623 2251 6624 2250 6625 2274 6626 2263 6627 2261 6628 2260 6629 2252 6630 2251 6631 2274 6632 2263 6633 2260 6634 2259 6635 2253 6636 2252 6637 2274 6638 2253 6639 2274 6640 2273 6641 2263 6642 2259 6643 2258 6644 2254 6645 2253 6646 2273 6647 2255 6648 2254 6649 2273 6650 2263 6651 2258 6652 2257 6653 2256 6654 2255 6655 2273 6656 2263 6657 2257 6658 2256 6659 2263 6660 2256 6661 2273 6662 2263 6663 2273 6664 2272 6665 2264 6666 2263 6667 2272 6668 2264 6669 2272 6670 2271 6671 2265 6672 2264 6673 2271 6674 2266 6675 2265 6676 2271 6677 2266 6678 2271 6679 2270 6680 2267 6681 2266 6682 2270 6683 2267 6684 2270 6685 2269 6686 2268 6687 2267 6688 2269 6689 2320 6690 2319 6691 2318 6692 2320 6693 2318 6694 2317 6695 2321 6696 2320 6697 2317 6698 2321 6699 2317 6700 2316 6701 2322 6702 2321 6703 2316 6704 2322 6705 2316 6706 2344 6707 2344 6708 2316 6709 2345 6710 2345 6711 2316 6712 2315 6713 2323 6714 2322 6715 2343 6716 2343 6717 2322 6718 2344 6719 2323 6720 2343 6721 2342 6722 2346 6723 2345 6724 2315 6725 2323 6726 2342 6727 2341 6728 2347 6729 2346 6730 2315 6731 2323 6732 2341 6733 2340 6734 2348 6735 2347 6736 2315 6737 2324 6738 2323 6739 2340 6740 2348 6741 2315 6742 2314 6743 2324 6744 2340 6745 2339 6746 2349 6747 2348 6748 2314 6749 2324 6750 2339 6751 2338 6752 2350 6753 2349 6754 2314 6755 2325 6756 2324 6757 2338 6758 2350 6759 2314 6760 2313 6761 2325 6762 2338 6763 2350 6764 2325 6765 2350 6766 2313 6767 2326 6768 2325 6769 2312 6770 2312 6771 2325 6772 2313 6773 2326 6774 2312 6775 2311 6776 2326 6777 2311 6778 2310 6779 2327 6780 2326 6781 2310 6782 2327 6783 2310 6784 2309 6785 2301 6786 2300 6787 2337 6788 2302 6789 2301 6790 2337 6791 2328 6792 2327 6793 2309 6794 2328 6795 2309 6796 2308 6797 2303 6798 2302 6799 2337 6800 2328 6801 2308 6802 2307 6803 2304 6804 2303 6805 2337 6806 2305 6807 2304 6808 2337 6809 2328 6810 2307 6811 2306 6812 2306 6813 2305 6814 2337 6815 2328 6816 2306 6817 2337 6818 2329 6819 2328 6820 2337 6821 2329 6822 2337 6823 2336 6824 2329 6825 2336 6826 2335 6827 2330 6828 2329 6829 2335 6830 2330 6831 2335 6832 2334 6833 2330 6834 2334 6835 2333 6836 2331 6837 2330 6838 2333 6839 2331 6840 2333 6841 2332 6842 2353 6843 2352 6844 2351 6845 2353 6846 2351 6847 2358 6848 2354 6849 2353 6850 2358 6851 2355 6852 2354 6853 2357 6854 2357 6855 2354 6856 2358 6857 2355 6858 2357 6859 2356 6860 2366 6861 2365 6862 2364 6863 2366 6864 2364 6865 2363 6866 2367 6867 2366 6868 2363 6869 2367 6870 2363 6871 2362 6872 2367 6873 2362 6874 2361 6875 2368 6876 2367 6877 2361 6878 2368 6879 2361 6880 2360 6881 2368 6882 2360 6883 2359 6884 2369 6885 2368 6886 2359 6887 2369 6888 2359 6889 2420 6890 2420 6891 2359 6892 2421 6893 2421 6894 2359 6895 2422 6896 2422 6897 2359 6898 2423 6899 2423 6900 2359 6901 2424 6902 2424 6903 2359 6904 2425 6905 2425 6906 2359 6907 2426 6908 2370 6909 2369 6910 2420 6911 2370 6912 2420 6913 2419 6914 2370 6915 2419 6916 2418 6917 2370 6918 2418 6919 2417 6920 2371 6921 2370 6922 2417 6923 2371 6924 2417 6925 2416 6926 2371 6927 2416 6928 2415 6929 2371 6930 2415 6931 2414 6932 2371 6933 2414 6934 2413 6935 2372 6936 2371 6937 2413 6938 2372 6939 2413 6940 2412 6941 2372 6942 2412 6943 2411 6944 2372 6945 2411 6946 2410 6947 2372 6948 2410 6949 2409 6950 2373 6951 2372 6952 2409 6953 2373 6954 2409 6955 2408 6956 2373 6957 2408 6958 2407 6959 2374 6960 2373 6961 2407 6962 2374 6963 2407 6964 2406 6965 2375 6966 2374 6967 2406 6968 2375 6969 2406 6970 2405 6971 2375 6972 2405 6973 2404 6974 2376 6975 2375 6976 2404 6977 2376 6978 2404 6979 2403 6980 2377 6981 2376 6982 2403 6983 2377 6984 2403 6985 2402 6986 2390 6987 2389 6988 2388 6989 2377 6990 2402 6991 2401 6992 2378 6993 2377 6994 2401 6995 2390 6996 2388 6997 2387 6998 2379 6999 2378 7000 2401 7001 2390 7002 2387 7003 2386 7004 2380 7005 2379 7006 2401 7007 2380 7008 2401 7009 2400 7010 2390 7011 2386 7012 2385 7013 2381 7014 2380 7015 2400 7016 2382 7017 2381 7018 2400 7019 2390 7020 2385 7021 2384 7022 2383 7023 2382 7024 2400 7025 2390 7026 2384 7027 2383 7028 2390 7029 2383 7030 2400 7031 2390 7032 2400 7033 2399 7034 2391 7035 2390 7036 2399 7037 2391 7038 2399 7039 2398 7040 2392 7041 2391 7042 2398 7043 2393 7044 2392 7045 2398 7046 2393 7047 2398 7048 2397 7049 2394 7050 2393 7051 2397 7052 2394 7053 2397 7054 2396 7055 2395 7056 2394 7057 2396 7058 2434 7059 2433 7060 2432 7061 2434 7062 2432 7063 2431 7064 2434 7065 2431 7066 2430 7067 2435 7068 2434 7069 2430 7070 2435 7071 2430 7072 2429 7073 2435 7074 2429 7075 2428 7076 2435 7077 2428 7078 2427 7079 2436 7080 2435 7081 2427 7082 2436 7083 2427 7084 2470 7085 2470 7086 2427 7087 2471 7088 2471 7089 2427 7090 2472 7091 2472 7092 2427 7093 2473 7094 2473 7095 2427 7096 2474 7097 2474 7098 2427 7099 2475 7100 2475 7101 2427 7102 2476 7103 2437 7104 2436 7105 2469 7106 2469 7107 2436 7108 2470 7109 2437 7110 2469 7111 2468 7112 2437 7113 2468 7114 2467 7115 2438 7116 2437 7117 2467 7118 2438 7119 2467 7120 2466 7121 2438 7122 2466 7123 2465 7124 2439 7125 2438 7126 2465 7127 2439 7128 2465 7129 2464 7130 2439 7131 2464 7132 2463 7133 2440 7134 2439 7135 2463 7136 2440 7137 2463 7138 2462 7139 2441 7140 2440 7141 2462 7142 2441 7143 2462 7144 2461 7145 2441 7146 2461 7147 2460 7148 2453 7149 2452 7150 2451 7151 2442 7152 2441 7153 2460 7154 2454 7155 2453 7156 2451 7157 2442 7158 2460 7159 2459 7160 2455 7161 2454 7162 2451 7163 2456 7164 2455 7165 2451 7166 2442 7167 2459 7168 2458 7169 2457 7170 2456 7171 2451 7172 2458 7173 2457 7174 2451 7175 2442 7176 2458 7177 2451 7178 2443 7179 2442 7180 2451 7181 2444 7182 2443 7183 2451 7184 2444 7185 2451 7186 2450 7187 2444 7188 2450 7189 2449 7190 2444 7191 2449 7192 2448 7193 2444 7194 2448 7195 2447 7196 2445 7197 2444 7198 2447 7199 2445 7200 2447 7201 2446 7202 2488 7203 2487 7204 2486 7205 2489 7206 2488 7207 2486 7208 2489 7209 2486 7210 2485 7211 2490 7212 2489 7213 2485 7214 2490 7215 2485 7216 2484 7217 2491 7218 2490 7219 2484 7220 2491 7221 2484 7222 2483 7223 2492 7224 2491 7225 2483 7226 2492 7227 2483 7228 2482 7229 2493 7230 2492 7231 2482 7232 2493 7233 2482 7234 2481 7235 2494 7236 2493 7237 2481 7238 2494 7239 2481 7240 2504 7241 2494 7242 2504 7243 2503 7244 2495 7245 2494 7246 2503 7247 2495 7248 2503 7249 2502 7250 2496 7251 2495 7252 2502 7253 2496 7254 2502 7255 2501 7256 2497 7257 2496 7258 2501 7259 2497 7260 2501 7261 2500 7262 2498 7263 2497 7264 2500 7265 2498 7266 2500 7267 2499 7268 2479 7269 2478 7270 2477 7271 2479 7272 2477 7273 2480 7274 2512 7275 2511 7276 2510 7277 2512 7278 2510 7279 2509 7280 2513 7281 2512 7282 2509 7283 2513 7284 2509 7285 2508 7286 2513 7287 2508 7288 2507 7289 2514 7290 2513 7291 2507 7292 2514 7293 2507 7294 2506 7295 2514 7296 2506 7297 2505 7298 2515 7299 2514 7300 2505 7301 2515 7302 2505 7303 2566 7304 2566 7305 2505 7306 2567 7307 2567 7308 2505 7309 2568 7310 2568 7311 2505 7312 2569 7313 2569 7314 2505 7315 2570 7316 2570 7317 2505 7318 2571 7319 2571 7320 2505 7321 2572 7322 2516 7323 2515 7324 2566 7325 2516 7326 2566 7327 2565 7328 2516 7329 2565 7330 2564 7331 2516 7332 2564 7333 2563 7334 2517 7335 2516 7336 2563 7337 2517 7338 2563 7339 2562 7340 2517 7341 2562 7342 2561 7343 2517 7344 2561 7345 2560 7346 2517 7347 2560 7348 2559 7349 2518 7350 2517 7351 2559 7352 2518 7353 2559 7354 2558 7355 2518 7356 2558 7357 2557 7358 2518 7359 2557 7360 2556 7361 2518 7362 2556 7363 2555 7364 2519 7365 2518 7366 2555 7367 2519 7368 2555 7369 2554 7370 2519 7371 2554 7372 2553 7373 2520 7374 2519 7375 2553 7376 2520 7377 2553 7378 2552 7379 2521 7380 2520 7381 2552 7382 2521 7383 2552 7384 2551 7385 2521 7386 2551 7387 2550 7388 2522 7389 2521 7390 2550 7391 2522 7392 2550 7393 2549 7394 2523 7395 2522 7396 2549 7397 2523 7398 2549 7399 2548 7400 2536 7401 2535 7402 2534 7403 2523 7404 2548 7405 2547 7406 2524 7407 2523 7408 2547 7409 2536 7410 2534 7411 2533 7412 2525 7413 2524 7414 2547 7415 2536 7416 2533 7417 2532 7418 2526 7419 2525 7420 2547 7421 2526 7422 2547 7423 2546 7424 2536 7425 2532 7426 2531 7427 2527 7428 2526 7429 2546 7430 2528 7431 2527 7432 2546 7433 2536 7434 2531 7435 2530 7436 2529 7437 2528 7438 2546 7439 2536 7440 2530 7441 2529 7442 2536 7443 2529 7444 2546 7445 2536 7446 2546 7447 2545 7448 2537 7449 2536 7450 2545 7451 2537 7452 2545 7453 2544 7454 2538 7455 2537 7456 2544 7457 2539 7458 2538 7459 2544 7460 2539 7461 2544 7462 2543 7463 2540 7464 2539 7465 2543 7466 2540 7467 2543 7468 2542 7469 2541 7470 2540 7471 2542 7472 2578 7473 2577 7474 2576 7475 2578 7476 2576 7477 2575 7478 2575 7479 2574 7480 2573 7481 2575 7482 2573 7483 2580 7484 2578 7485 2575 7486 2580 7487 2579 7488 2578 7489 2580 7490 2583 7491 2582 7492 2581 7493 2583 7494 2581 7495 2613 7496 2607 7497 2606 7498 2605 7499 2608 7500 2607 7501 2605 7502 2608 7503 2605 7504 2604 7505 2609 7506 2608 7507 2604 7508 2610 7509 2609 7510 2604 7511 2610 7512 2604 7513 2603 7514 2611 7515 2610 7516 2603 7517 2611 7518 2603 7519 2602 7520 2612 7521 2611 7522 2591 7523 2591 7524 2611 7525 2602 7526 2583 7527 2613 7528 2612 7529 2583 7530 2612 7531 2585 7532 2585 7533 2612 7534 2586 7535 2586 7536 2612 7537 2587 7538 2587 7539 2612 7540 2588 7541 2588 7542 2612 7543 2589 7544 2589 7545 2612 7546 2590 7547 2590 7548 2612 7549 2591 7550 2592 7551 2591 7552 2602 7553 2593 7554 2592 7555 2602 7556 2593 7557 2602 7558 2601 7559 2594 7560 2593 7561 2601 7562 2595 7563 2594 7564 2601 7565 2596 7566 2595 7567 2601 7568 2596 7569 2601 7570 2600 7571 2583 7572 2585 7573 2584 7574 2597 7575 2596 7576 2600 7577 2598 7578 2597 7579 2600 7580 2598 7581 2600 7582 2599 7583 2615 7584 2614 7585 2631 7586 2631 7587 2614 7588 2630 7589 2631 7590 2630 7591 2629 7592 2631 7593 2629 7594 2628 7595 2631 7596 2628 7597 2627 7598 2631 7599 2627 7600 2632 7601 2632 7602 2627 7603 2626 7604 2615 7605 2631 7606 2645 7607 2633 7608 2632 7609 2626 7610 2634 7611 2633 7612 2626 7613 2634 7614 2626 7615 2625 7616 2635 7617 2634 7618 2625 7619 2636 7620 2635 7621 2625 7622 2637 7623 2636 7624 2625 7625 2637 7626 2625 7627 2624 7628 2638 7629 2637 7630 2624 7631 2639 7632 2638 7633 2624 7634 2639 7635 2624 7636 2623 7637 2640 7638 2639 7639 2623 7640 2640 7641 2623 7642 2622 7643 2641 7644 2640 7645 2622 7646 2642 7647 2641 7648 2622 7649 2643 7650 2642 7651 2622 7652 2643 7653 2622 7654 2621 7655 2644 7656 2643 7657 2621 7658 2615 7659 2645 7660 2617 7661 2617 7662 2645 7663 2644 7664 2617 7665 2644 7666 2621 7667 2617 7668 2621 7669 2620 7670 2617 7671 2620 7672 2619 7673 2617 7674 2619 7675 2618 7676 2615 7677 2617 7678 2616 7679 2647 7680 2646 7681 2679 7682 2647 7683 2679 7684 2678 7685 2647 7686 2678 7687 2677 7688 2648 7689 2647 7690 2677 7691 2649 7692 2648 7693 2677 7694 2650 7695 2649 7696 2676 7697 2676 7698 2649 7699 2677 7700 2650 7701 2676 7702 2675 7703 2650 7704 2675 7705 2674 7706 2651 7707 2650 7708 2674 7709 2651 7710 2674 7711 2673 7712 2664 7713 2663 7714 2662 7715 2651 7716 2673 7717 2672 7718 2665 7719 2664 7720 2662 7721 2652 7722 2651 7723 2672 7724 2666 7725 2665 7726 2662 7727 2652 7728 2672 7729 2671 7730 2667 7731 2666 7732 2662 7733 2652 7734 2671 7735 2670 7736 2668 7737 2667 7738 2662 7739 2652 7740 2670 7741 2669 7742 2669 7743 2668 7744 2662 7745 2652 7746 2669 7747 2662 7748 2653 7749 2652 7750 2662 7751 2654 7752 2653 7753 2662 7754 2654 7755 2662 7756 2661 7757 2654 7758 2661 7759 2660 7760 2655 7761 2654 7762 2660 7763 2655 7764 2660 7765 2659 7766 2655 7767 2659 7768 2658 7769 2656 7770 2655 7771 2658 7772 2656 7773 2658 7774 2657 7775 2700 7776 2699 7777 2698 7778 2700 7779 2698 7780 2697 7781 2701 7782 2700 7783 2697 7784 2701 7785 2697 7786 2696 7787 2702 7788 2701 7789 2696 7790 2702 7791 2696 7792 2724 7793 2724 7794 2696 7795 2725 7796 2725 7797 2696 7798 2695 7799 2703 7800 2702 7801 2723 7802 2723 7803 2702 7804 2724 7805 2703 7806 2723 7807 2722 7808 2726 7809 2725 7810 2695 7811 2703 7812 2722 7813 2721 7814 2727 7815 2726 7816 2695 7817 2703 7818 2721 7819 2720 7820 2728 7821 2727 7822 2695 7823 2704 7824 2703 7825 2720 7826 2728 7827 2695 7828 2694 7829 2704 7830 2720 7831 2719 7832 2729 7833 2728 7834 2694 7835 2704 7836 2719 7837 2718 7838 2730 7839 2729 7840 2694 7841 2705 7842 2704 7843 2718 7844 2730 7845 2694 7846 2693 7847 2705 7848 2718 7849 2730 7850 2705 7851 2730 7852 2693 7853 2706 7854 2705 7855 2692 7856 2692 7857 2705 7858 2693 7859 2706 7860 2692 7861 2691 7862 2706 7863 2691 7864 2690 7865 2707 7866 2706 7867 2690 7868 2707 7869 2690 7870 2689 7871 2681 7872 2680 7873 2717 7874 2682 7875 2681 7876 2717 7877 2708 7878 2707 7879 2689 7880 2708 7881 2689 7882 2688 7883 2683 7884 2682 7885 2717 7886 2708 7887 2688 7888 2687 7889 2684 7890 2683 7891 2717 7892 2685 7893 2684 7894 2717 7895 2708 7896 2687 7897 2686 7898 2686 7899 2685 7900 2717 7901 2708 7902 2686 7903 2717 7904 2709 7905 2708 7906 2717 7907 2709 7908 2717 7909 2716 7910 2709 7911 2716 7912 2715 7913 2710 7914 2709 7915 2715 7916 2710 7917 2715 7918 2714 7919 2710 7920 2714 7921 2713 7922 2711 7923 2710 7924 2713 7925 2711 7926 2713 7927 2712 7928 2733 7929 2732 7930 2731 7931 2733 7932 2731 7933 2734 7934 2737 7935 2736 7936 2735 7937 2737 7938 2735 7939 2738 7940 2757 7941 2756 7942 2755 7943 2757 7944 2755 7945 2754 7946 2742 7947 2741 7948 2740 7949 2742 7950 2740 7951 2739 7952 2758 7953 2757 7954 2754 7955 2758 7956 2754 7957 2753 7958 2758 7959 2753 7960 2752 7961 2743 7962 2742 7963 2739 7964 2759 7965 2758 7966 2752 7967 2759 7968 2752 7969 2751 7970 2744 7971 2743 7972 2739 7973 2745 7974 2744 7975 2769 7976 2769 7977 2744 7978 2739 7979 2759 7980 2751 7981 2750 7982 2746 7983 2745 7984 2769 7985 2759 7986 2750 7987 2749 7988 2760 7989 2759 7990 2749 7991 2747 7992 2746 7993 2769 7994 2760 7995 2749 7996 2748 7997 2748 7998 2747 7999 2769 8000 2760 8001 2748 8002 2769 8003 2760 8004 2769 8005 2768 8006 2770 8007 2769 8008 2739 8009 2760 8010 2768 8011 2767 8012 2761 8013 2760 8014 2767 8015 2761 8016 2767 8017 2766 8018 2762 8019 2761 8020 2766 8021 2762 8022 2766 8023 2765 8024 2762 8025 2765 8026 2764 8027 2763 8028 2762 8029 2764 8030 2771 8031 2798 8032 2799 8033 2799 8034 2798 8035 2797 8036 2799 8037 2797 8038 2796 8039 2799 8040 2796 8041 2795 8042 2799 8043 2795 8044 2794 8045 2799 8046 2794 8047 2800 8048 2800 8049 2794 8050 2793 8051 2771 8052 2799 8053 2813 8054 2801 8055 2800 8056 2793 8057 2801 8058 2793 8059 2792 8060 2802 8061 2801 8062 2792 8063 2803 8064 2802 8065 2792 8066 2804 8067 2803 8068 2792 8069 2804 8070 2792 8071 2791 8072 2805 8073 2804 8074 2791 8075 2806 8076 2805 8077 2791 8078 2806 8079 2791 8080 2790 8081 2807 8082 2806 8083 2790 8084 2807 8085 2790 8086 2789 8087 2808 8088 2807 8089 2789 8090 2808 8091 2789 8092 2788 8093 2809 8094 2808 8095 2788 8096 2809 8097 2788 8098 2787 8099 2810 8100 2809 8101 2787 8102 2811 8103 2810 8104 2787 8105 2811 8106 2787 8107 2786 8108 2812 8109 2811 8110 2786 8111 2771 8112 2813 8113 2814 8114 2814 8115 2813 8116 2812 8117 2814 8118 2812 8119 2786 8120 2814 8121 2786 8122 2785 8123 2814 8124 2785 8125 2784 8126 2814 8127 2784 8128 2783 8129 2814 8130 2783 8131 2782 8132 2814 8133 2782 8134 2815 8135 2815 8136 2782 8137 2781 8138 2771 8139 2814 8140 2828 8141 2816 8142 2815 8143 2781 8144 2817 8145 2816 8146 2781 8147 2817 8148 2781 8149 2780 8150 2818 8151 2817 8152 2780 8153 2819 8154 2818 8155 2780 8156 2819 8157 2780 8158 2779 8159 2820 8160 2819 8161 2779 8162 2820 8163 2779 8164 2778 8165 2821 8166 2820 8167 2778 8168 2822 8169 2821 8170 2778 8171 2822 8172 2778 8173 2777 8174 2823 8175 2822 8176 2777 8177 2824 8178 2823 8179 2777 8180 2824 8181 2777 8182 2776 8183 2825 8184 2824 8185 2776 8186 2826 8187 2825 8188 2776 8189 2826 8190 2776 8191 2775 8192 2827 8193 2826 8194 2775 8195 2771 8196 2828 8197 2827 8198 2771 8199 2827 8200 2775 8201 2771 8202 2775 8203 2774 8204 2771 8205 2774 8206 2773 8207 2771 8208 2773 8209 2772 8210

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.17588 0.7857 -1.0 1.30656 0.5412 -1.0 1.38704 0.2759 -1.0 1.41421 0.0 -1.0 1.38704 -0.2759 -1.0 1.30656 -0.5412 -1.0 1.17588 -0.78569 -1.0 1.0 -1.0 -1.0 0.78569 -1.17588 -1.0 0.5412 -1.30656 -1.0 0.2759 -1.38704 -1.0 -0.0 -1.41421 -1.0 -0.2759 -1.38704 -1.0 -0.5412 -1.30656 -1.0 -0.7857 -1.17588 -1.0 -1.0 -1.0 -1.0 -1.17588 -0.78569 -1.0 -1.30656 -0.5412 -1.0 -1.38704 -0.2759 -1.0 -1.41421 0.0 -1.0 -1.38704 0.2759 -1.0 -1.30656 0.5412 -1.0 -1.17587 0.7857 -1.0 -1.0 1.0 -1.0 -0.78569 1.17588 -1.0 -0.54119 1.30656 -1.0 -0.2759 1.38704 -1.0 0.0 1.41421 -1.0 0.2759 1.38704 -1.0 0.5412 1.30656 -1.0 0.7857 1.17587 -1.0 0.0 -0.0 1.0 -0.0 0.0 -1.0 + + + + + + + + + + 0.62694 0.62694 -0.46245 0.73721 0.49257 -0.46245 0.81912 0.33927 -0.46245 0.86959 0.17295 -0.46245 0.88662 0.0 -0.46245 0.86959 -0.17295 -0.46245 0.81912 -0.33927 -0.46245 0.73721 -0.49257 -0.46245 0.62694 -0.62694 -0.46245 0.49257 -0.73721 -0.46245 0.33927 -0.81912 -0.46245 0.17295 -0.86959 -0.46245 0.0 -0.88662 -0.46245 -0.17295 -0.86959 -0.46245 -0.33927 -0.81912 -0.46245 -0.49257 -0.73721 -0.46245 -0.62694 -0.62694 -0.46245 -0.73721 -0.49257 -0.46245 -0.81912 -0.33927 -0.46245 -0.86959 -0.17295 -0.46245 -0.88662 0.0 -0.46245 -0.86959 0.17295 -0.46245 -0.81912 0.33927 -0.46245 -0.73721 0.49257 -0.46245 -0.62694 0.62694 -0.46245 -0.49257 0.73721 -0.46245 -0.33927 0.81915 -0.46245 -0.17295 0.86959 -0.46245 0.0 0.88662 -0.46245 0.17295 0.86959 -0.46245 0.33927 0.81912 -0.46245 0.49257 0.73721 -0.46245 0.0 0.0 1.0 0.0 0.0 -1.0 + + + + + + + + + + 0.89466 0.14214 1.02385 0.18062 0.53437 0.50208 0.53437 0.50208 0.77134 0.1159 0.89466 0.14214 0.53437 0.50208 0.65189 0.10064 0.77134 0.1159 0.53437 0.50208 0.53438 0.09564 0.65189 0.10064 0.53437 0.50208 0.41686 0.10064 0.53438 0.09564 0.53437 0.50208 0.29742 0.1159 0.41686 0.10064 0.53437 0.50208 0.17409 0.14214 0.29742 0.1159 0.53437 0.50208 0.0449 0.18062 0.17409 0.14214 0.53437 0.50208 -0.09221 0.23313 0.0449 0.18062 0.53437 0.50208 -0.23937 0.30206 -0.09221 0.23313 0.53437 0.50208 -0.39881 0.39046 -0.23937 0.30206 0.53437 0.50208 -0.57289 0.50208 -0.39881 0.39046 0.53437 0.50208 -0.39881 0.6137 -0.57289 0.50208 0.53437 0.50208 -0.23937 0.70209 -0.39881 0.6137 0.53437 0.50208 -0.09221 0.77103 -0.23937 0.70209 0.53437 0.50208 0.0449 0.82354 -0.09221 0.77103 0.53437 0.50208 0.17409 0.86202 0.0449 0.82354 0.53437 0.50208 0.29741 0.88826 0.17409 0.86202 0.53437 0.50208 0.41686 0.90351 0.29741 0.88826 0.53437 0.50208 0.53437 0.90852 0.41686 0.90351 0.53437 0.50208 0.65189 0.90351 0.53437 0.90852 0.53437 0.50208 0.77133 0.88826 0.65189 0.90351 0.53437 0.50208 0.89466 0.86202 0.77133 0.88826 0.53437 0.50208 1.02385 0.82354 0.89466 0.86202 0.53437 0.50208 1.16096 0.77103 1.02385 0.82354 0.53437 0.50208 1.30812 0.70209 1.16096 0.77103 0.53437 0.50208 1.46756 0.6137 1.30812 0.70209 0.53437 0.50208 1.64164 0.50208 1.46756 0.6137 0.53437 0.50208 1.46756 0.39046 1.64164 0.50208 0.53437 0.50208 1.30812 0.30207 1.46756 0.39046 0.53437 0.50208 1.16096 0.23313 1.30812 0.30207 0.53437 0.50208 1.02385 0.18062 1.16096 0.23313 0.53437 0.50208 1.02385 0.18062 0.89466 0.14214 0.53437 0.50208 0.89466 0.14214 0.77134 0.1159 0.53437 0.50208 0.77134 0.1159 0.65189 0.10064 0.53437 0.50208 0.65189 0.10064 0.53438 0.09564 0.53437 0.50208 0.53438 0.09564 0.41686 0.10064 0.53437 0.50208 0.41686 0.10064 0.29742 0.1159 0.53437 0.50208 0.29742 0.1159 0.17409 0.14214 0.53437 0.50208 0.17409 0.14214 0.0449 0.18062 0.53437 0.50208 0.0449 0.18062 -0.09221 0.23313 0.53437 0.50208 -0.09221 0.23313 -0.23937 0.30206 0.53437 0.50208 -0.23937 0.30206 -0.39881 0.39046 0.53437 0.50208 -0.39881 0.39046 -0.57289 0.50208 0.53437 0.50208 -0.57289 0.50208 -0.39881 0.6137 0.53437 0.50208 -0.39881 0.6137 -0.23937 0.70209 0.53437 0.50208 -0.23937 0.70209 -0.09221 0.77103 0.53437 0.50208 -0.09221 0.77103 0.0449 0.82354 0.53437 0.50208 0.0449 0.82354 0.17409 0.86202 0.53437 0.50208 0.17409 0.86202 0.29741 0.88826 0.53437 0.50208 0.29741 0.88826 0.41686 0.90351 0.53437 0.50208 0.41686 0.90351 0.53437 0.90852 0.53437 0.50208 0.53437 0.90852 0.65189 0.90351 0.53437 0.50208 0.65189 0.90351 0.77133 0.88826 0.53437 0.50208 0.77133 0.88826 0.89466 0.86202 0.53437 0.50208 0.89466 0.86202 1.02385 0.82354 0.53437 0.50208 1.02385 0.82354 1.16096 0.77103 0.53437 0.50208 1.16096 0.77103 1.30812 0.70209 0.53437 0.50208 1.30812 0.70209 1.46756 0.6137 0.53437 0.50208 1.46756 0.6137 1.64164 0.50208 0.53437 0.50208 1.64164 0.50208 1.46756 0.39046 0.53437 0.50208 1.46756 0.39046 1.30812 0.30207 0.53437 0.50208 1.30812 0.30207 1.16096 0.23313 1.16096 0.23313 1.02385 0.18062 0.53437 0.50208 + + + + + + + + + + + + + + +

    1 0 0 1 32 2 32 3 2 4 1 5 32 6 3 7 2 8 32 9 4 10 3 11 32 12 5 13 4 14 32 15 6 16 5 17 32 18 7 19 6 20 32 21 8 22 7 23 32 24 9 25 8 26 32 27 10 28 9 29 32 30 11 31 10 32 32 33 12 34 11 35 32 36 13 37 12 38 32 39 14 40 13 41 32 42 15 43 14 44 32 45 16 46 15 47 32 48 17 49 16 50 32 51 18 52 17 53 32 54 19 55 18 56 32 57 20 58 19 59 32 60 21 61 20 62 32 63 22 64 21 65 32 66 23 67 22 68 32 69 24 70 23 71 32 72 25 73 24 74 32 75 26 76 25 77 32 78 27 79 26 80 32 81 28 82 27 83 32 84 29 85 28 86 32 87 30 88 29 89 32 90 31 91 30 92 32 93 0 94 31 95 33 96 0 97 1 98 33 99 1 100 2 101 33 102 2 103 3 104 33 105 3 106 4 107 33 108 4 109 5 110 33 111 5 112 6 113 33 114 6 115 7 116 33 117 7 118 8 119 33 120 8 121 9 122 33 123 9 124 10 125 33 126 10 127 11 128 33 129 11 130 12 131 33 132 12 133 13 134 33 135 13 136 14 137 33 138 14 139 15 140 33 141 15 142 16 143 33 144 16 145 17 146 33 147 17 148 18 149 33 150 18 151 19 152 33 153 19 154 20 155 33 156 20 157 21 158 33 159 21 160 22 161 33 162 22 163 23 164 33 165 23 166 24 167 33 168 24 169 25 170 33 171 25 172 26 173 33 174 26 175 27 176 33 177 27 178 28 179 33 180 28 181 29 182 33 183 29 184 30 185 33 186 30 187 31 188 31 189 0 190 33 191

    +
    +
    +
    + + + + 1.19619 0.58226 -1.0 0.41454 -0.7869 -1.0 -1.39461 0.06574 -1.0 -0.80381 0.58226 -1.0 1.19619 0.58226 1.0 0.41454 -0.7869 1.0 -1.39461 0.06574 1.0 -0.80381 0.58226 1.0 + + + + + + + + + + 0.61278 0.35575 -0.70562 0.24885 -0.7882 -0.56285 -0.73128 -0.1023 -0.67431 -0.31007 0.82577 -0.47108 0.61278 0.35575 0.70562 0.24885 -0.7882 0.56285 -0.73128 -0.1023 0.67431 -0.31007 0.82577 0.47108 + + + + + + + + + + 0.72873 0.47178 0.60186 0.37916 0.37041 0.15993 0.72873 0.47178 0.60186 0.37916 0.37041 0.15993 1.02857 0.44771 0.453 0.33992 -0.02857 0.44771 1.02857 0.44771 0.453 0.33992 -0.02857 0.44771 0.72873 0.47178 1.02857 0.44771 0.60116 0.61947 0.72873 0.47178 1.02857 0.44771 0.60116 0.61947 0.60186 0.37916 0.60116 0.61947 -0.02857 0.44771 0.60186 0.37916 0.60116 0.61947 -0.02857 0.44771 0.37041 0.15993 -0.02857 0.44771 0.453 0.33992 0.37041 0.15993 -0.02857 0.44771 0.453 0.33992 1.02857 0.44771 0.72873 0.47178 0.50417 0.38059 1.02857 0.44771 0.72873 0.47178 0.50417 0.38059 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + + + + 1.12341 0.59904 -1.0 0.34176 -0.77012 -1.0 -1.46739 0.08252 -1.0 -0.87659 0.59904 -1.0 1.12341 0.59904 1.0 0.34176 -0.77012 1.0 -1.46739 0.08252 1.0 -0.87659 0.59904 1.0 + + + + + + + + + + 0.61278 0.35575 -0.70562 0.24885 -0.7882 -0.56285 -0.73128 -0.1023 -0.67431 -0.31007 0.82577 -0.47108 0.61278 0.35575 0.70562 0.24885 -0.7882 0.56285 -0.73128 -0.1023 0.67431 -0.31007 0.82577 0.47108 + + + + + + + + + + 0.72873 0.47178 0.60186 0.37916 0.37041 0.15993 0.72873 0.47178 0.60186 0.37916 0.37041 0.15993 1.02857 0.44771 0.453 0.33992 -0.02857 0.44771 1.02857 0.44771 0.453 0.33992 -0.02857 0.44771 0.72873 0.47178 1.02857 0.44771 0.60116 0.61947 0.72873 0.47178 1.02857 0.44771 0.60116 0.61947 0.60186 0.37916 0.60116 0.61947 -0.02857 0.44771 0.60186 0.37916 0.60116 0.61947 -0.02857 0.44771 0.37041 0.15993 -0.02857 0.44771 0.453 0.33992 0.37041 0.15993 -0.02857 0.44771 0.453 0.33992 1.02857 0.44771 0.72873 0.47178 0.50417 0.38059 1.02857 0.44771 0.72873 0.47178 0.50417 0.38059 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + + + + 1.35033 0.45305 -1.0 0.56868 -0.9161 -1.0 -1.24047 -0.06347 -1.0 -0.64967 0.45305 -1.0 1.35033 0.45305 1.0 0.56868 -0.9161 1.0 -1.24047 -0.06347 1.0 -0.64967 0.45305 1.0 + + + + + + + + + + 0.61278 0.35575 -0.70562 0.24885 -0.7882 -0.56285 -0.73128 -0.1023 -0.67431 -0.31007 0.82577 -0.47108 0.61278 0.35575 0.70562 0.24885 -0.7882 0.56285 -0.73128 -0.1023 0.67431 -0.31007 0.82577 0.47108 + + + + + + + + + + 0.72873 0.47178 0.60186 0.37916 0.37041 0.15993 0.72873 0.47178 0.60186 0.37916 0.37041 0.15993 1.02857 0.44771 0.453 0.33992 -0.02857 0.44771 1.02857 0.44771 0.453 0.33992 -0.02857 0.44771 0.72873 0.47178 1.02857 0.44771 0.60116 0.61947 0.72873 0.47178 1.02857 0.44771 0.60116 0.61947 0.60186 0.37916 0.60116 0.61947 -0.02857 0.44771 0.60186 0.37916 0.60116 0.61947 -0.02857 0.44771 0.37041 0.15993 -0.02857 0.44771 0.453 0.33992 0.37041 0.15993 -0.02857 0.44771 0.453 0.33992 1.02857 0.44771 0.72873 0.47178 0.50417 0.38059 1.02857 0.44771 0.72873 0.47178 0.50417 0.38059 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + + + + 0.0 -0.0 -1.41421 1.02332 -0.74348 -0.63246 -0.39087 -1.20299 -0.63246 -1.26491 -0.0 -0.63246 -0.39087 1.20299 -0.63246 1.02332 0.74348 -0.63246 0.39087 -1.20299 0.63246 -1.02332 -0.74348 0.63246 -1.02332 0.74348 0.63246 0.39087 1.20299 0.63246 1.26491 0.0 0.63246 -0.0 0.0 1.41421 0.6015 -0.43701 -1.20301 -0.22975 -0.7071 -1.20301 0.37175 -1.14412 -0.74351 0.6015 0.43701 -1.20301 1.203 -0.0 -0.7435 -0.74349 -0.0 -1.203 -0.97325 -0.7071 -0.7435 -0.22975 0.7071 -1.20301 -0.97325 0.7071 -0.7435 0.37175 1.14412 -0.74351 1.345 0.43701 -0.0 1.345 -0.43701 0.0 0.83125 -1.14412 0.0 -0.0 -1.41421 0.0 -0.83125 -1.14412 0.0 -1.345 -0.43701 0.0 -1.345 0.43701 -0.0 -0.83125 1.14412 -0.0 0.0 1.41421 -0.0 0.83125 1.14412 -0.0 0.97325 -0.7071 0.7435 -0.37175 -1.14412 0.74351 -1.203 0.0 0.7435 -0.37175 1.14412 0.74351 0.97325 0.7071 0.7435 0.74349 0.0 1.203 0.22975 -0.7071 1.20301 -0.6015 -0.43701 1.20301 -0.6015 0.43701 1.20301 0.22975 0.7071 1.20301 + + + + + + + + + + 0.0 0.0 -1.0 0.72359 -0.52571 -0.44719 -0.27638 -0.85064 -0.44719 -0.89441 0.0 -0.44719 -0.27638 0.85064 -0.44719 0.72359 0.52571 -0.44719 0.27638 -0.85064 0.44722 -0.72359 -0.52571 0.44719 -0.72359 0.52571 0.44719 0.27638 0.85064 0.44719 0.89441 0.0 0.44719 0.0 0.0 1.0 0.42531 -0.309 -0.85064 -0.16245 -0.49998 -0.85064 0.26286 -0.80898 -0.52571 0.42531 0.309 -0.85064 0.85064 0.0 -0.52571 -0.52571 0.0 -0.85064 -0.68816 -0.49998 -0.52571 -0.16245 0.49998 -0.85064 -0.68816 0.49998 -0.52571 0.26286 0.80898 -0.52571 0.95105 0.309 0.0 0.95105 -0.309 0.0 0.58776 -0.80902 0.0 0.0 -1.0 0.0 -0.58776 -0.80902 0.0 -0.95105 -0.309 0.0 -0.95105 0.309 0.0 -0.58776 0.80902 0.0 0.0 1.0 0.0 0.58776 0.80902 0.0 0.68816 -0.49998 0.52571 -0.26286 -0.80898 0.52571 -0.85064 0.0 0.52571 -0.26286 0.80898 0.52571 0.68816 0.49998 0.52571 0.52571 0.0 0.85064 0.16245 -0.49998 0.85064 -0.42531 -0.309 0.85064 -0.42531 0.309 0.85064 0.16245 0.49998 0.85064 + + + + + + + + + + 0.75311 0.11158 0.95018 0.21117 0.82689 0.27054 0.95018 0.21117 0.75311 0.11158 1.14943 0.09989 0.46246 0.11286 1.14943 0.09989 0.75311 0.11158 1.14943 0.09989 1.07744 0.2618 0.95018 0.21117 0.90005 0.39508 0.82689 0.27054 0.95018 0.21117 0.95018 0.21117 1.00617 0.39104 0.90005 0.39508 0.95447 0.53487 0.90005 0.39508 1.00617 0.39104 0.95018 0.21117 1.07744 0.2618 1.00617 0.39104 0.32261 0.22952 0.14943 0.09989 0.46246 0.11286 0.14943 0.09989 0.32261 0.22952 0.19133 0.29524 0.27674 0.38955 0.19133 0.29524 0.32261 0.22952 0.19133 0.29524 0.07744 0.2618 0.14943 0.09989 0.20413 0.49383 0.19133 0.29524 0.27674 0.38955 0.19133 0.29524 0.20413 0.49383 0.10855 0.42958 0.13244 0.59936 0.10855 0.42958 0.20413 0.49383 0.10855 0.42958 0.07744 0.2618 0.19133 0.29524 0.04129 0.57872 0.10855 0.42958 0.13244 0.59936 0.10855 0.42958 0.04129 0.57872 0.00617 0.39104 0.95447 0.53487 1.00617 0.39104 1.04129 0.57872 0.00617 0.39104 0.07744 0.2618 0.10855 0.42958 0.79899 0.43978 0.82689 0.27054 0.90005 0.39508 0.90005 0.39508 0.86836 0.58509 0.79899 0.43978 0.77674 0.61045 0.79899 0.43978 0.86836 0.58509 0.86836 0.58509 0.90005 0.39508 0.95447 0.53487 0.59019 0.23871 0.46246 0.11286 0.75311 0.11158 0.75311 0.11158 0.71658 0.30753 0.59019 0.23871 0.63244 0.40064 0.59019 0.23871 0.71658 0.30753 0.71658 0.30753 0.75311 0.11158 0.82689 0.27054 0.36836 0.41491 0.27674 0.38955 0.32261 0.22952 0.32261 0.22952 0.45654 0.28896 0.36836 0.41491 0.45447 0.46513 0.36836 0.41491 0.45654 0.28896 0.45654 0.28896 0.32261 0.22952 0.46246 0.11286 0.21658 0.69247 0.13244 0.59936 0.20413 0.49383 0.20413 0.49383 0.29899 0.56022 0.21658 0.69247 0.32689 0.72946 0.21658 0.69247 0.29899 0.56022 0.29899 0.56022 0.20413 0.49383 0.27674 0.38955 0.95654 0.71104 0.95447 0.53487 1.04129 0.57872 1.04129 0.57872 1.09019 0.76129 0.95654 0.71104 0.96246 0.88714 0.95654 0.71104 1.09019 0.76129 0.09019 0.76129 0.04129 0.57872 0.13244 0.59936 0.70413 0.50617 0.79899 0.43978 0.77674 0.61045 0.79899 0.43978 0.70413 0.50617 0.71658 0.30753 0.63244 0.40064 0.71658 0.30753 0.70413 0.50617 0.71658 0.30753 0.82689 0.27054 0.79899 0.43978 0.54129 0.42128 0.59019 0.23871 0.63244 0.40064 0.59019 0.23871 0.54129 0.42128 0.45654 0.28896 0.45447 0.46513 0.45654 0.28896 0.54129 0.42128 0.45654 0.28896 0.46246 0.11286 0.59019 0.23871 0.40005 0.60492 0.36836 0.41491 0.45447 0.46513 0.36836 0.41491 0.40005 0.60492 0.29899 0.56022 0.32689 0.72946 0.29899 0.56022 0.40005 0.60492 0.29899 0.56022 0.27674 0.38955 0.36836 0.41491 0.25311 0.88842 0.21658 0.69247 0.32689 0.72946 0.21658 0.69247 0.25311 0.88842 0.09019 0.76129 0.96246 0.88714 1.09019 0.76129 1.25311 0.88842 0.09019 0.76129 0.13244 0.59936 0.21658 0.69247 0.82261 0.77048 0.95654 0.71104 0.96246 0.88714 0.95654 0.71104 0.82261 0.77048 0.86836 0.58509 0.77674 0.61045 0.86836 0.58509 0.82261 0.77048 0.86836 0.58509 0.95447 0.53487 0.95654 0.71104 0.60855 0.57042 0.63244 0.40064 0.70413 0.50617 0.70413 0.50617 0.69133 0.70476 0.60855 0.57042 0.57744 0.7382 0.60855 0.57042 0.69133 0.70476 0.69133 0.70476 0.70413 0.50617 0.77674 0.61045 0.50617 0.60896 0.45447 0.46513 0.54129 0.42128 0.54129 0.42128 0.60855 0.57042 0.50617 0.60896 0.57744 0.7382 0.50617 0.60896 0.60855 0.57042 0.60855 0.57042 0.54129 0.42128 0.63244 0.40064 0.45018 0.78883 0.32689 0.72946 0.40005 0.60492 0.40005 0.60492 0.50617 0.60896 0.45018 0.78883 0.57744 0.7382 0.45018 0.78883 0.50617 0.60896 0.50617 0.60896 0.40005 0.60492 0.45447 0.46513 0.64943 0.90011 0.96246 0.88714 1.25311 0.88842 0.25311 0.88842 0.45018 0.78883 0.64943 0.90011 0.57744 0.7382 0.64943 0.90011 0.45018 0.78883 0.45018 0.78883 0.25311 0.88842 0.32689 0.72946 0.69133 0.70476 0.77674 0.61045 0.82261 0.77048 0.82261 0.77048 0.64943 0.90011 0.69133 0.70476 0.57744 0.7382 0.69133 0.70476 0.64943 0.90011 0.64943 0.90011 0.82261 0.77048 0.96246 0.88714 + + + + + + + + + + + + + + +

    14 0 12 1 1 2 12 3 14 4 13 5 2 6 13 7 14 8 13 9 0 10 12 11 16 12 1 13 12 14 12 15 15 16 16 17 5 18 16 19 15 20 12 21 0 22 15 23 18 24 13 25 2 26 13 27 18 28 17 29 3 30 17 31 18 32 17 33 0 34 13 35 20 36 17 37 3 38 17 39 20 40 19 41 4 42 19 43 20 44 19 45 0 46 17 47 21 48 19 49 4 50 19 51 21 52 15 53 5 54 15 55 21 56 15 57 0 58 19 59 23 60 1 61 16 62 16 63 22 64 23 65 10 66 23 67 22 68 22 69 16 70 5 71 25 72 2 73 14 74 14 75 24 76 25 77 6 78 25 79 24 80 24 81 14 82 1 83 27 84 3 85 18 86 18 87 26 88 27 89 7 90 27 91 26 92 26 93 18 94 2 95 29 96 4 97 20 98 20 99 28 100 29 101 8 102 29 103 28 104 28 105 20 106 3 107 31 108 5 109 21 110 21 111 30 112 31 113 9 114 31 115 30 116 30 117 21 118 4 119 32 120 23 121 10 122 23 123 32 124 24 125 6 126 24 127 32 128 24 129 1 130 23 131 33 132 25 133 6 134 25 135 33 136 26 137 7 138 26 139 33 140 26 141 2 142 25 143 34 144 27 145 7 146 27 147 34 148 28 149 8 150 28 151 34 152 28 153 3 154 27 155 35 156 29 157 8 158 29 159 35 160 30 161 9 162 30 163 35 164 30 165 4 166 29 167 36 168 31 169 9 170 31 171 36 172 22 173 10 174 22 175 36 176 22 177 5 178 31 179 38 180 6 181 32 182 32 183 37 184 38 185 11 186 38 187 37 188 37 189 32 190 10 191 39 192 7 193 33 194 33 195 38 196 39 197 11 198 39 199 38 200 38 201 33 202 6 203 40 204 8 205 34 206 34 207 39 208 40 209 11 210 40 211 39 212 39 213 34 214 7 215 41 216 9 217 35 218 35 219 40 220 41 221 11 222 41 223 40 224 40 225 35 226 8 227 37 228 10 229 36 230 36 231 41 232 37 233 11 234 37 235 41 236 41 237 36 238 9 239

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 1.0 -1.0 1.0 1.0 1.0 1.0 -1.0 1.0 -1.0 -1.0 1.0 -1.0 1.0 1.0 + + + + + + + + + + 0.57735 0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.42013 0.42013 -0.42013 0.49402 0.33009 -0.42013 0.54892 0.22737 -0.42013 0.58273 0.11591 -0.42013 0.59415 0.0 -0.42013 0.58273 -0.11591 -0.42013 0.54892 -0.22737 -0.42013 0.49402 -0.33009 -0.42013 0.42013 -0.42013 -0.42013 0.33009 -0.49402 -0.42013 0.22737 -0.54892 -0.42013 0.11591 -0.58273 -0.42013 -0.0 -0.59415 -0.42013 -0.11591 -0.58273 -0.42013 -0.22737 -0.54892 -0.42013 -0.33009 -0.49402 -0.42013 -0.42013 -0.42013 -0.42013 -0.49402 -0.33009 -0.42013 -0.54892 -0.22737 -0.42013 -0.58273 -0.11591 -0.42013 -0.59415 0.0 -0.42013 -0.58273 0.11591 -0.42013 -0.54892 0.22737 -0.42013 -0.49402 0.33009 -0.42013 -0.42013 0.42013 -0.42013 -0.33009 0.49402 -0.42013 -0.22737 0.54892 -0.42013 -0.11591 0.58273 -0.42013 0.0 0.59415 -0.42013 0.11591 0.58273 -0.42013 0.22737 0.54892 -0.42013 0.33009 0.49402 -0.42013 -0.0 0.0 0.42013 -0.0 0.0 -0.42013 + + + + + + + + + + 0.62694 0.62694 -0.46245 0.73721 0.49257 -0.46245 0.81912 0.33927 -0.46245 0.86959 0.17295 -0.46245 0.88662 0.0 -0.46245 0.86959 -0.17295 -0.46245 0.81912 -0.33927 -0.46245 0.73721 -0.49257 -0.46245 0.62694 -0.62694 -0.46245 0.49257 -0.73721 -0.46245 0.33927 -0.81912 -0.46245 0.17295 -0.86959 -0.46245 0.0 -0.88662 -0.46245 -0.17295 -0.86959 -0.46245 -0.33927 -0.81912 -0.46245 -0.49257 -0.73721 -0.46245 -0.62694 -0.62694 -0.46245 -0.73721 -0.49257 -0.46245 -0.81912 -0.33927 -0.46245 -0.86959 -0.17295 -0.46245 -0.88662 0.0 -0.46245 -0.86959 0.17295 -0.46245 -0.81912 0.33927 -0.46245 -0.73721 0.49257 -0.46245 -0.62694 0.62694 -0.46245 -0.49257 0.73721 -0.46245 -0.33927 0.81915 -0.46245 -0.17295 0.86959 -0.46245 0.0 0.88662 -0.46245 0.17295 0.86959 -0.46245 0.33927 0.81912 -0.46245 0.49257 0.73721 -0.46245 0.0 0.0 1.0 0.0 0.0 -1.0 + + + + + + + + + + 0.89466 0.14214 1.02385 0.18062 0.53437 0.50208 0.53437 0.50208 0.77134 0.1159 0.89466 0.14214 0.53437 0.50208 0.65189 0.10064 0.77134 0.1159 0.53437 0.50208 0.53438 0.09564 0.65189 0.10064 0.53437 0.50208 0.41686 0.10064 0.53438 0.09564 0.53437 0.50208 0.29742 0.1159 0.41686 0.10064 0.53437 0.50208 0.17409 0.14214 0.29742 0.1159 0.53437 0.50208 0.0449 0.18062 0.17409 0.14214 0.53437 0.50208 -0.09221 0.23313 0.0449 0.18062 0.53437 0.50208 -0.23937 0.30206 -0.09221 0.23313 0.53437 0.50208 -0.39881 0.39046 -0.23937 0.30206 0.53437 0.50208 -0.57289 0.50208 -0.39881 0.39046 0.53437 0.50208 -0.39881 0.6137 -0.57289 0.50208 0.53437 0.50208 -0.23937 0.70209 -0.39881 0.6137 0.53437 0.50208 -0.09221 0.77103 -0.23937 0.70209 0.53437 0.50208 0.0449 0.82354 -0.09221 0.77103 0.53437 0.50208 0.17409 0.86202 0.0449 0.82354 0.53437 0.50208 0.29741 0.88826 0.17409 0.86202 0.53437 0.50208 0.41686 0.90351 0.29741 0.88826 0.53437 0.50208 0.53437 0.90852 0.41686 0.90351 0.53437 0.50208 0.65189 0.90351 0.53437 0.90852 0.53437 0.50208 0.77133 0.88826 0.65189 0.90351 0.53437 0.50208 0.89466 0.86202 0.77133 0.88826 0.53437 0.50208 1.02385 0.82354 0.89466 0.86202 0.53437 0.50208 1.16096 0.77103 1.02385 0.82354 0.53437 0.50208 1.30812 0.70209 1.16096 0.77103 0.53437 0.50208 1.46756 0.6137 1.30812 0.70209 0.53437 0.50208 1.64164 0.50208 1.46756 0.6137 0.53437 0.50208 1.46756 0.39046 1.64164 0.50208 0.53437 0.50208 1.30812 0.30207 1.46756 0.39046 0.53437 0.50208 1.16096 0.23313 1.30812 0.30207 0.53437 0.50208 1.02385 0.18062 1.16096 0.23313 0.53437 0.50208 1.02385 0.18062 0.89466 0.14214 0.53437 0.50208 0.89466 0.14214 0.77134 0.1159 0.53437 0.50208 0.77134 0.1159 0.65189 0.10064 0.53437 0.50208 0.65189 0.10064 0.53438 0.09564 0.53437 0.50208 0.53438 0.09564 0.41686 0.10064 0.53437 0.50208 0.41686 0.10064 0.29742 0.1159 0.53437 0.50208 0.29742 0.1159 0.17409 0.14214 0.53437 0.50208 0.17409 0.14214 0.0449 0.18062 0.53437 0.50208 0.0449 0.18062 -0.09221 0.23313 0.53437 0.50208 -0.09221 0.23313 -0.23937 0.30206 0.53437 0.50208 -0.23937 0.30206 -0.39881 0.39046 0.53437 0.50208 -0.39881 0.39046 -0.57289 0.50208 0.53437 0.50208 -0.57289 0.50208 -0.39881 0.6137 0.53437 0.50208 -0.39881 0.6137 -0.23937 0.70209 0.53437 0.50208 -0.23937 0.70209 -0.09221 0.77103 0.53437 0.50208 -0.09221 0.77103 0.0449 0.82354 0.53437 0.50208 0.0449 0.82354 0.17409 0.86202 0.53437 0.50208 0.17409 0.86202 0.29741 0.88826 0.53437 0.50208 0.29741 0.88826 0.41686 0.90351 0.53437 0.50208 0.41686 0.90351 0.53437 0.90852 0.53437 0.50208 0.53437 0.90852 0.65189 0.90351 0.53437 0.50208 0.65189 0.90351 0.77133 0.88826 0.53437 0.50208 0.77133 0.88826 0.89466 0.86202 0.53437 0.50208 0.89466 0.86202 1.02385 0.82354 0.53437 0.50208 1.02385 0.82354 1.16096 0.77103 0.53437 0.50208 1.16096 0.77103 1.30812 0.70209 0.53437 0.50208 1.30812 0.70209 1.46756 0.6137 0.53437 0.50208 1.46756 0.6137 1.64164 0.50208 0.53437 0.50208 1.64164 0.50208 1.46756 0.39046 0.53437 0.50208 1.46756 0.39046 1.30812 0.30207 0.53437 0.50208 1.30812 0.30207 1.16096 0.23313 1.16096 0.23313 1.02385 0.18062 0.53437 0.50208 + + + + + + + + + + + + + + +

    1 0 0 1 32 2 32 3 2 4 1 5 32 6 3 7 2 8 32 9 4 10 3 11 32 12 5 13 4 14 32 15 6 16 5 17 32 18 7 19 6 20 32 21 8 22 7 23 32 24 9 25 8 26 32 27 10 28 9 29 32 30 11 31 10 32 32 33 12 34 11 35 32 36 13 37 12 38 32 39 14 40 13 41 32 42 15 43 14 44 32 45 16 46 15 47 32 48 17 49 16 50 32 51 18 52 17 53 32 54 19 55 18 56 32 57 20 58 19 59 32 60 21 61 20 62 32 63 22 64 21 65 32 66 23 67 22 68 32 69 24 70 23 71 32 72 25 73 24 74 32 75 26 76 25 77 32 78 27 79 26 80 32 81 28 82 27 83 32 84 29 85 28 86 32 87 30 88 29 89 32 90 31 91 30 92 32 93 0 94 31 95 33 96 0 97 1 98 33 99 1 100 2 101 33 102 2 103 3 104 33 105 3 106 4 107 33 108 4 109 5 110 33 111 5 112 6 113 33 114 6 115 7 116 33 117 7 118 8 119 33 120 8 121 9 122 33 123 9 124 10 125 33 126 10 127 11 128 33 129 11 130 12 131 33 132 12 133 13 134 33 135 13 136 14 137 33 138 14 139 15 140 33 141 15 142 16 143 33 144 16 145 17 146 33 147 17 148 18 149 33 150 18 151 19 152 33 153 19 154 20 155 33 156 20 157 21 158 33 159 21 160 22 161 33 162 22 163 23 164 33 165 23 166 24 167 33 168 24 169 25 170 33 171 25 172 26 173 33 174 26 175 27 176 33 177 27 178 28 179 33 180 28 181 29 182 33 183 29 184 30 185 33 186 30 187 31 188 31 189 0 190 33 191

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.17588 0.7857 -1.0 1.30656 0.5412 -1.0 1.38704 0.2759 -1.0 1.41421 0.0 -1.0 1.38704 -0.2759 -1.0 1.30656 -0.5412 -1.0 1.17588 -0.78569 -1.0 1.0 -1.0 -1.0 0.78569 -1.17588 -1.0 0.5412 -1.30656 -1.0 0.2759 -1.38704 -1.0 -0.0 -1.41421 -1.0 -0.2759 -1.38704 -1.0 -0.5412 -1.30656 -1.0 -0.7857 -1.17588 -1.0 -1.0 -1.0 -1.0 -1.17588 -0.78569 -1.0 -1.30656 -0.5412 -1.0 -1.38704 -0.2759 -1.0 -1.41421 0.0 -1.0 -1.38704 0.2759 -1.0 -1.30656 0.5412 -1.0 -1.17587 0.7857 -1.0 -1.0 1.0 -1.0 -0.78569 1.17588 -1.0 -0.54119 1.30656 -1.0 -0.2759 1.38704 -1.0 0.0 1.41421 -1.0 0.2759 1.38704 -1.0 0.5412 1.30656 -1.0 0.7857 1.17587 -1.0 0.0 -0.0 1.0 -0.0 0.0 -1.0 + + + + + + + + + + 0.62694 0.62694 -0.46245 0.73721 0.49257 -0.46245 0.81912 0.33927 -0.46245 0.86959 0.17295 -0.46245 0.88662 0.0 -0.46245 0.86959 -0.17295 -0.46245 0.81912 -0.33927 -0.46245 0.73721 -0.49257 -0.46245 0.62694 -0.62694 -0.46245 0.49257 -0.73721 -0.46245 0.33927 -0.81912 -0.46245 0.17295 -0.86959 -0.46245 0.0 -0.88662 -0.46245 -0.17295 -0.86959 -0.46245 -0.33927 -0.81912 -0.46245 -0.49257 -0.73721 -0.46245 -0.62694 -0.62694 -0.46245 -0.73721 -0.49257 -0.46245 -0.81912 -0.33927 -0.46245 -0.86959 -0.17295 -0.46245 -0.88662 0.0 -0.46245 -0.86959 0.17295 -0.46245 -0.81912 0.33927 -0.46245 -0.73721 0.49257 -0.46245 -0.62694 0.62694 -0.46245 -0.49257 0.73721 -0.46245 -0.33927 0.81915 -0.46245 -0.17295 0.86959 -0.46245 0.0 0.88662 -0.46245 0.17295 0.86959 -0.46245 0.33927 0.81912 -0.46245 0.49257 0.73721 -0.46245 0.0 0.0 1.0 0.0 0.0 -1.0 + + + + + + + + + + 0.89466 0.14214 1.02385 0.18062 0.53437 0.50208 0.53437 0.50208 0.77134 0.1159 0.89466 0.14214 0.53437 0.50208 0.65189 0.10064 0.77134 0.1159 0.53437 0.50208 0.53438 0.09564 0.65189 0.10064 0.53437 0.50208 0.41686 0.10064 0.53438 0.09564 0.53437 0.50208 0.29742 0.1159 0.41686 0.10064 0.53437 0.50208 0.17409 0.14214 0.29742 0.1159 0.53437 0.50208 0.0449 0.18062 0.17409 0.14214 0.53437 0.50208 -0.09221 0.23313 0.0449 0.18062 0.53437 0.50208 -0.23937 0.30206 -0.09221 0.23313 0.53437 0.50208 -0.39881 0.39046 -0.23937 0.30206 0.53437 0.50208 -0.57289 0.50208 -0.39881 0.39046 0.53437 0.50208 -0.39881 0.6137 -0.57289 0.50208 0.53437 0.50208 -0.23937 0.70209 -0.39881 0.6137 0.53437 0.50208 -0.09221 0.77103 -0.23937 0.70209 0.53437 0.50208 0.0449 0.82354 -0.09221 0.77103 0.53437 0.50208 0.17409 0.86202 0.0449 0.82354 0.53437 0.50208 0.29741 0.88826 0.17409 0.86202 0.53437 0.50208 0.41686 0.90351 0.29741 0.88826 0.53437 0.50208 0.53437 0.90852 0.41686 0.90351 0.53437 0.50208 0.65189 0.90351 0.53437 0.90852 0.53437 0.50208 0.77133 0.88826 0.65189 0.90351 0.53437 0.50208 0.89466 0.86202 0.77133 0.88826 0.53437 0.50208 1.02385 0.82354 0.89466 0.86202 0.53437 0.50208 1.16096 0.77103 1.02385 0.82354 0.53437 0.50208 1.30812 0.70209 1.16096 0.77103 0.53437 0.50208 1.46756 0.6137 1.30812 0.70209 0.53437 0.50208 1.64164 0.50208 1.46756 0.6137 0.53437 0.50208 1.46756 0.39046 1.64164 0.50208 0.53437 0.50208 1.30812 0.30207 1.46756 0.39046 0.53437 0.50208 1.16096 0.23313 1.30812 0.30207 0.53437 0.50208 1.02385 0.18062 1.16096 0.23313 0.53437 0.50208 1.02385 0.18062 0.89466 0.14214 0.53437 0.50208 0.89466 0.14214 0.77134 0.1159 0.53437 0.50208 0.77134 0.1159 0.65189 0.10064 0.53437 0.50208 0.65189 0.10064 0.53438 0.09564 0.53437 0.50208 0.53438 0.09564 0.41686 0.10064 0.53437 0.50208 0.41686 0.10064 0.29742 0.1159 0.53437 0.50208 0.29742 0.1159 0.17409 0.14214 0.53437 0.50208 0.17409 0.14214 0.0449 0.18062 0.53437 0.50208 0.0449 0.18062 -0.09221 0.23313 0.53437 0.50208 -0.09221 0.23313 -0.23937 0.30206 0.53437 0.50208 -0.23937 0.30206 -0.39881 0.39046 0.53437 0.50208 -0.39881 0.39046 -0.57289 0.50208 0.53437 0.50208 -0.57289 0.50208 -0.39881 0.6137 0.53437 0.50208 -0.39881 0.6137 -0.23937 0.70209 0.53437 0.50208 -0.23937 0.70209 -0.09221 0.77103 0.53437 0.50208 -0.09221 0.77103 0.0449 0.82354 0.53437 0.50208 0.0449 0.82354 0.17409 0.86202 0.53437 0.50208 0.17409 0.86202 0.29741 0.88826 0.53437 0.50208 0.29741 0.88826 0.41686 0.90351 0.53437 0.50208 0.41686 0.90351 0.53437 0.90852 0.53437 0.50208 0.53437 0.90852 0.65189 0.90351 0.53437 0.50208 0.65189 0.90351 0.77133 0.88826 0.53437 0.50208 0.77133 0.88826 0.89466 0.86202 0.53437 0.50208 0.89466 0.86202 1.02385 0.82354 0.53437 0.50208 1.02385 0.82354 1.16096 0.77103 0.53437 0.50208 1.16096 0.77103 1.30812 0.70209 0.53437 0.50208 1.30812 0.70209 1.46756 0.6137 0.53437 0.50208 1.46756 0.6137 1.64164 0.50208 0.53437 0.50208 1.64164 0.50208 1.46756 0.39046 0.53437 0.50208 1.46756 0.39046 1.30812 0.30207 0.53437 0.50208 1.30812 0.30207 1.16096 0.23313 1.16096 0.23313 1.02385 0.18062 0.53437 0.50208 + + + + + + + + + + + + + + +

    1 0 0 1 32 2 32 3 2 4 1 5 32 6 3 7 2 8 32 9 4 10 3 11 32 12 5 13 4 14 32 15 6 16 5 17 32 18 7 19 6 20 32 21 8 22 7 23 32 24 9 25 8 26 32 27 10 28 9 29 32 30 11 31 10 32 32 33 12 34 11 35 32 36 13 37 12 38 32 39 14 40 13 41 32 42 15 43 14 44 32 45 16 46 15 47 32 48 17 49 16 50 32 51 18 52 17 53 32 54 19 55 18 56 32 57 20 58 19 59 32 60 21 61 20 62 32 63 22 64 21 65 32 66 23 67 22 68 32 69 24 70 23 71 32 72 25 73 24 74 32 75 26 76 25 77 32 78 27 79 26 80 32 81 28 82 27 83 32 84 29 85 28 86 32 87 30 88 29 89 32 90 31 91 30 92 32 93 0 94 31 95 33 96 0 97 1 98 33 99 1 100 2 101 33 102 2 103 3 104 33 105 3 106 4 107 33 108 4 109 5 110 33 111 5 112 6 113 33 114 6 115 7 116 33 117 7 118 8 119 33 120 8 121 9 122 33 123 9 124 10 125 33 126 10 127 11 128 33 129 11 130 12 131 33 132 12 133 13 134 33 135 13 136 14 137 33 138 14 139 15 140 33 141 15 142 16 143 33 144 16 145 17 146 33 147 17 148 18 149 33 150 18 151 19 152 33 153 19 154 20 155 33 156 20 157 21 158 33 159 21 160 22 161 33 162 22 163 23 164 33 165 23 166 24 167 33 168 24 169 25 170 33 171 25 172 26 173 33 174 26 175 27 176 33 177 27 178 28 179 33 180 28 181 29 182 33 183 29 184 30 185 33 186 30 187 31 188 31 189 0 190 33 191

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.17588 0.7857 -1.0 1.30656 0.5412 -1.0 1.38704 0.2759 -1.0 1.41421 0.0 -1.0 1.38704 -0.2759 -1.0 1.30656 -0.5412 -1.0 1.17588 -0.78569 -1.0 1.0 -1.0 -1.0 0.78569 -1.17588 -1.0 0.5412 -1.30656 -1.0 0.2759 -1.38704 -1.0 -0.0 -1.41421 -1.0 -0.2759 -1.38704 -1.0 -0.5412 -1.30656 -1.0 -0.7857 -1.17588 -1.0 -1.0 -1.0 -1.0 -1.17588 -0.78569 -1.0 -1.30656 -0.5412 -1.0 -1.38704 -0.2759 -1.0 -1.41421 0.0 -1.0 -1.38704 0.2759 -1.0 -1.30656 0.5412 -1.0 -1.17587 0.7857 -1.0 -1.0 1.0 -1.0 -0.78569 1.17588 -1.0 -0.54119 1.30656 -1.0 -0.2759 1.38704 -1.0 0.0 1.41421 -1.0 0.2759 1.38704 -1.0 0.5412 1.30656 -1.0 0.7857 1.17587 -1.0 1.0 1.0 1.0 1.17588 0.78569 1.0 1.30656 0.54119 1.0 1.38704 0.2759 1.0 1.41421 -0.0 1.0 1.38704 -0.2759 1.0 1.30656 -0.5412 1.0 1.17587 -0.7857 1.0 1.0 -1.0 1.0 0.78569 -1.17588 1.0 0.5412 -1.30656 1.0 0.2759 -1.38704 1.0 0.0 -1.41421 1.0 -0.2759 -1.38704 1.0 -0.54119 -1.30656 1.0 -0.78569 -1.17588 1.0 -1.0 -1.0 1.0 -1.17587 -0.7857 1.0 -1.30656 -0.5412 1.0 -1.38704 -0.2759 1.0 -1.41421 -1e-05 1.0 -1.38704 0.27589 1.0 -1.30657 0.54119 1.0 -1.17588 0.78569 1.0 -1.00001 0.99999 1.0 -0.7857 1.17587 1.0 -0.5412 1.30656 1.0 -0.27591 1.38704 1.0 -1e-05 1.41421 1.0 0.27589 1.38704 1.0 0.54119 1.30657 1.0 0.78569 1.17588 1.0 -0.0 0.0 -1.0 0.0 -0.0 1.0 + + + + + + + + + + 0.49876 0.49876 -0.70879 0.5865 0.39189 -0.70879 0.65169 0.26994 -0.70879 0.69182 0.13761 -0.70879 0.70537 0.0 -0.70879 0.69182 -0.13761 -0.70879 0.65169 -0.26994 -0.70879 0.5865 -0.39189 -0.70879 0.49876 -0.49876 -0.70879 0.39189 -0.5865 -0.70879 0.26994 -0.65169 -0.70879 0.13761 -0.69182 -0.70879 0.0 -0.70537 -0.70879 -0.13761 -0.69182 -0.70879 -0.26994 -0.65169 -0.70879 -0.39189 -0.5865 -0.70879 -0.49876 -0.49876 -0.70879 -0.5865 -0.39189 -0.70879 -0.65169 -0.26994 -0.70879 -0.69182 -0.13761 -0.70879 -0.70537 0.0 -0.70879 -0.69182 0.13761 -0.70879 -0.65169 0.26994 -0.70879 -0.5865 0.39189 -0.70879 -0.49876 0.49876 -0.70879 -0.39189 0.5865 -0.70879 -0.26994 0.65169 -0.70879 -0.13761 0.69182 -0.70879 0.0 0.70537 -0.70879 0.13761 0.69182 -0.70879 0.26994 0.65169 -0.70879 0.39189 0.5865 -0.70879 0.49876 0.49876 0.70879 0.5865 0.39189 0.70879 0.65169 0.26994 0.70879 0.69182 0.13761 0.70879 0.70537 0.0 0.70879 0.69182 -0.13761 0.70879 0.65169 -0.26994 0.70879 0.5865 -0.39189 0.70879 0.49876 -0.49876 0.70879 0.39189 -0.5865 0.70879 0.26994 -0.65169 0.70879 0.13761 -0.69182 0.70879 0.0 -0.70537 0.70879 -0.13761 -0.69182 0.70879 -0.26994 -0.65169 0.70879 -0.39189 -0.5865 0.70879 -0.49876 -0.49876 0.70879 -0.5865 -0.39189 0.70879 -0.65169 -0.26994 0.70879 -0.69182 -0.13761 0.70879 -0.70537 0.0 0.70879 -0.69182 0.13761 0.70879 -0.65169 0.26994 0.70879 -0.5865 0.39189 0.70879 -0.49876 0.49876 0.70879 -0.39189 0.5865 0.70879 -0.26994 0.65169 0.70879 -0.13761 0.69182 0.70879 0.0 0.70537 0.70879 0.13761 0.69182 0.70879 0.26994 0.65169 0.70879 0.39189 0.5865 0.70879 0.0 0.0 -1.0 0.0 0.0 1.0 + + + + + + + + + + 1.10675 0.0 0.625 0.0 0.59375 0.0 0.60675 1.0 0.59375 1.0 0.625 1.0 0.10675 0.0 0.59375 0.0 0.5625 0.0 0.60675 1.0 0.5625 1.0 0.59375 1.0 0.10675 0.0 0.5625 0.0 0.53125 0.0 0.60675 1.0 0.53125 1.0 0.5625 1.0 0.10675 0.0 0.53125 0.0 0.5 0.0 0.60675 1.0 0.5 1.0 0.53125 1.0 0.10675 0.0 0.5 0.0 0.46875 0.0 0.60675 1.0 0.46875 1.0 0.5 1.0 0.10675 0.0 0.46875 0.0 0.4375 0.0 0.60675 1.0 0.4375 1.0 0.46875 1.0 0.10675 0.0 0.4375 0.0 0.40625 0.0 0.60675 1.0 0.40625 1.0 0.4375 1.0 0.10675 0.0 0.40625 0.0 0.375 0.0 0.60675 1.0 0.375 1.0 0.40625 1.0 0.10675 0.0 0.375 0.0 0.34375 0.0 0.60675 1.0 0.34375 1.0 0.375 1.0 0.10675 0.0 0.34375 0.0 0.3125 0.0 0.60675 1.0 0.3125 1.0 0.34375 1.0 0.10675 0.0 0.3125 0.0 0.28125 0.0 0.60675 1.0 0.28125 1.0 0.3125 1.0 0.10675 0.0 0.28125 0.0 0.25 0.0 0.60675 1.0 0.25 1.0 0.28125 1.0 0.10675 0.0 0.25 0.0 0.21875 0.0 0.60675 1.0 0.21875 1.0 0.25 1.0 0.10675 0.0 0.21875 0.0 0.1875 0.0 0.60675 1.0 0.1875 1.0 0.21875 1.0 0.10675 0.0 0.1875 0.0 0.15625 0.0 0.60675 1.0 0.15625 1.0 0.1875 1.0 0.10675 0.0 0.15625 0.0 0.125 0.0 0.60675 1.0 0.125 1.0 0.15625 1.0 0.10675 0.0 0.125 0.0 0.09375 0.0 0.60675 1.0 1.09375 1.0 0.125 1.0 0.10675 0.0 0.09375 0.0 0.0625 0.0 0.60675 1.0 1.0625 1.0 1.09375 1.0 0.10675 0.0 0.0625 0.0 0.03125 0.0 0.60675 1.0 1.03125 1.0 1.0625 1.0 1.10675 0.0 1.03125 0.0 1.0 0.0 0.60675 1.0 1.0 1.0 1.03125 1.0 1.10675 0.0 1.0 0.0 0.96875 -0.0 0.60675 1.0 0.96875 1.0 1.0 1.0 1.10675 0.0 0.96875 -0.0 0.9375 -0.0 0.60675 1.0 0.9375 1.0 0.96875 1.0 1.10675 0.0 0.9375 -0.0 0.90625 0.0 0.60675 1.0 0.90625 1.0 0.9375 1.0 1.10675 0.0 0.90625 0.0 0.875 0.0 0.60675 1.0 0.875 1.0 0.90625 1.0 1.10675 0.0 0.875 0.0 0.84375 -0.0 0.60675 1.0 0.84375 1.0 0.875 1.0 1.10675 0.0 0.84375 -0.0 0.8125 -0.0 0.60675 1.0 0.8125 1.0 0.84375 1.0 1.10675 0.0 0.8125 -0.0 0.78125 -0.0 0.60675 1.0 0.78125 1.0 0.8125 1.0 1.10675 0.0 0.78125 -0.0 0.75 -0.0 0.60675 1.0 0.75 1.0 0.78125 1.0 1.10675 0.0 0.75 -0.0 0.71875 -0.0 0.60675 1.0 0.71875 1.0 0.75 1.0 1.10675 0.0 0.71875 -0.0 0.6875 -0.0 0.60675 1.0 0.6875 1.0 0.71875 1.0 1.10675 0.0 0.6875 -0.0 0.65625 -0.0 0.60675 1.0 0.65625 1.0 0.6875 1.0 0.65625 -0.0 0.625 0.0 1.10675 0.0 0.60675 1.0 0.625 1.0 0.65625 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.625 1.0 0.625 0.0 0.65625 -0.0 0.625 1.0 0.625 0.0 0.65625 -0.0 + + + + + + + + + + + + + + +

    64 0 0 1 1 2 65 3 33 4 32 5 64 6 1 7 2 8 65 9 34 10 33 11 64 12 2 13 3 14 65 15 35 16 34 17 64 18 3 19 4 20 65 21 36 22 35 23 64 24 4 25 5 26 65 27 37 28 36 29 64 30 5 31 6 32 65 33 38 34 37 35 64 36 6 37 7 38 65 39 39 40 38 41 64 42 7 43 8 44 65 45 40 46 39 47 64 48 8 49 9 50 65 51 41 52 40 53 64 54 9 55 10 56 65 57 42 58 41 59 64 60 10 61 11 62 65 63 43 64 42 65 64 66 11 67 12 68 65 69 44 70 43 71 64 72 12 73 13 74 65 75 45 76 44 77 64 78 13 79 14 80 65 81 46 82 45 83 64 84 14 85 15 86 65 87 47 88 46 89 64 90 15 91 16 92 65 93 48 94 47 95 64 96 16 97 17 98 65 99 49 100 48 101 64 102 17 103 18 104 65 105 50 106 49 107 64 108 18 109 19 110 65 111 51 112 50 113 64 114 19 115 20 116 65 117 52 118 51 119 64 120 20 121 21 122 65 123 53 124 52 125 64 126 21 127 22 128 65 129 54 130 53 131 64 132 22 133 23 134 65 135 55 136 54 137 64 138 23 139 24 140 65 141 56 142 55 143 64 144 24 145 25 146 65 147 57 148 56 149 64 150 25 151 26 152 65 153 58 154 57 155 64 156 26 157 27 158 65 159 59 160 58 161 64 162 27 163 28 164 65 165 60 166 59 167 64 168 28 169 29 170 65 171 61 172 60 173 64 174 29 175 30 176 65 177 62 178 61 179 64 180 30 181 31 182 65 183 63 184 62 185 31 186 0 187 64 188 65 189 32 190 63 191 0 192 32 193 33 194 33 195 1 196 0 197 1 198 33 199 34 200 34 201 2 202 1 203 2 204 34 205 35 206 35 207 3 208 2 209 3 210 35 211 36 212 36 213 4 214 3 215 4 216 36 217 37 218 37 219 5 220 4 221 5 222 37 223 38 224 38 225 6 226 5 227 6 228 38 229 39 230 39 231 7 232 6 233 7 234 39 235 40 236 40 237 8 238 7 239 8 240 40 241 41 242 41 243 9 244 8 245 9 246 41 247 42 248 42 249 10 250 9 251 10 252 42 253 43 254 43 255 11 256 10 257 11 258 43 259 44 260 44 261 12 262 11 263 12 264 44 265 45 266 45 267 13 268 12 269 13 270 45 271 46 272 46 273 14 274 13 275 14 276 46 277 47 278 47 279 15 280 14 281 15 282 47 283 48 284 48 285 16 286 15 287 16 288 48 289 49 290 49 291 17 292 16 293 17 294 49 295 50 296 50 297 18 298 17 299 18 300 50 301 51 302 51 303 19 304 18 305 19 306 51 307 52 308 52 309 20 310 19 311 20 312 52 313 53 314 53 315 21 316 20 317 21 318 53 319 54 320 54 321 22 322 21 323 22 324 54 325 55 326 55 327 23 328 22 329 23 330 55 331 56 332 56 333 24 334 23 335 24 336 56 337 57 338 57 339 25 340 24 341 25 342 57 343 58 344 58 345 26 346 25 347 26 348 58 349 59 350 59 351 27 352 26 353 27 354 59 355 60 356 60 357 28 358 27 359 28 360 60 361 61 362 61 363 29 364 28 365 29 366 61 367 62 368 62 369 30 370 29 371 30 372 62 373 63 374 63 375 31 376 30 377 32 378 0 379 31 380 31 381 63 382 32 383

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.17588 0.7857 -1.0 1.30656 0.5412 -1.0 1.38704 0.2759 -1.0 1.41421 0.0 -1.0 1.38704 -0.2759 -1.0 1.30656 -0.5412 -1.0 1.17588 -0.78569 -1.0 1.0 -1.0 -1.0 0.78569 -1.17588 -1.0 0.5412 -1.30656 -1.0 0.2759 -1.38704 -1.0 -0.0 -1.41421 -1.0 -0.2759 -1.38704 -1.0 -0.5412 -1.30656 -1.0 -0.7857 -1.17588 -1.0 -1.0 -1.0 -1.0 -1.17588 -0.78569 -1.0 -1.30656 -0.5412 -1.0 -1.38704 -0.2759 -1.0 -1.41421 0.0 -1.0 -1.38704 0.2759 -1.0 -1.30656 0.5412 -1.0 -1.17587 0.7857 -1.0 -1.0 1.0 -1.0 -0.78569 1.17588 -1.0 -0.54119 1.30656 -1.0 -0.2759 1.38704 -1.0 0.0 1.41421 -1.0 0.2759 1.38704 -1.0 0.5412 1.30656 -1.0 0.7857 1.17587 -1.0 1.0 1.0 1.0 1.17588 0.78569 1.0 1.30656 0.54119 1.0 1.38704 0.2759 1.0 1.41421 -0.0 1.0 1.38704 -0.2759 1.0 1.30656 -0.5412 1.0 1.17587 -0.7857 1.0 1.0 -1.0 1.0 0.78569 -1.17588 1.0 0.5412 -1.30656 1.0 0.2759 -1.38704 1.0 0.0 -1.41421 1.0 -0.2759 -1.38704 1.0 -0.54119 -1.30656 1.0 -0.78569 -1.17588 1.0 -1.0 -1.0 1.0 -1.17587 -0.7857 1.0 -1.30656 -0.5412 1.0 -1.38704 -0.2759 1.0 -1.41421 -1e-05 1.0 -1.38704 0.27589 1.0 -1.30657 0.54119 1.0 -1.17588 0.78569 1.0 -1.00001 0.99999 1.0 -0.7857 1.17587 1.0 -0.5412 1.30656 1.0 -0.27591 1.38704 1.0 -1e-05 1.41421 1.0 0.27589 1.38704 1.0 0.54119 1.30657 1.0 0.78569 1.17588 1.0 -0.0 0.0 -1.0 0.0 -0.0 1.0 + + + + + + + + + + 0.49876 0.49876 -0.70879 0.5865 0.39189 -0.70879 0.65169 0.26994 -0.70879 0.69182 0.13761 -0.70879 0.70537 0.0 -0.70879 0.69182 -0.13761 -0.70879 0.65169 -0.26994 -0.70879 0.5865 -0.39189 -0.70879 0.49876 -0.49876 -0.70879 0.39189 -0.5865 -0.70879 0.26994 -0.65169 -0.70879 0.13761 -0.69182 -0.70879 0.0 -0.70537 -0.70879 -0.13761 -0.69182 -0.70879 -0.26994 -0.65169 -0.70879 -0.39189 -0.5865 -0.70879 -0.49876 -0.49876 -0.70879 -0.5865 -0.39189 -0.70879 -0.65169 -0.26994 -0.70879 -0.69182 -0.13761 -0.70879 -0.70537 0.0 -0.70879 -0.69182 0.13761 -0.70879 -0.65169 0.26994 -0.70879 -0.5865 0.39189 -0.70879 -0.49876 0.49876 -0.70879 -0.39189 0.5865 -0.70879 -0.26994 0.65169 -0.70879 -0.13761 0.69182 -0.70879 0.0 0.70537 -0.70879 0.13761 0.69182 -0.70879 0.26994 0.65169 -0.70879 0.39189 0.5865 -0.70879 0.49876 0.49876 0.70879 0.5865 0.39189 0.70879 0.65169 0.26994 0.70879 0.69182 0.13761 0.70879 0.70537 0.0 0.70879 0.69182 -0.13761 0.70879 0.65169 -0.26994 0.70879 0.5865 -0.39189 0.70879 0.49876 -0.49876 0.70879 0.39189 -0.5865 0.70879 0.26994 -0.65169 0.70879 0.13761 -0.69182 0.70879 0.0 -0.70537 0.70879 -0.13761 -0.69182 0.70879 -0.26994 -0.65169 0.70879 -0.39189 -0.5865 0.70879 -0.49876 -0.49876 0.70879 -0.5865 -0.39189 0.70879 -0.65169 -0.26994 0.70879 -0.69182 -0.13761 0.70879 -0.70537 0.0 0.70879 -0.69182 0.13761 0.70879 -0.65169 0.26994 0.70879 -0.5865 0.39189 0.70879 -0.49876 0.49876 0.70879 -0.39189 0.5865 0.70879 -0.26994 0.65169 0.70879 -0.13761 0.69182 0.70879 0.0 0.70537 0.70879 0.13761 0.69182 0.70879 0.26994 0.65169 0.70879 0.39189 0.5865 0.70879 0.0 0.0 -1.0 0.0 0.0 1.0 + + + + + + + + + + 1.10675 0.0 0.625 0.0 0.59375 0.0 0.60675 1.0 0.59375 1.0 0.625 1.0 0.10675 0.0 0.59375 0.0 0.5625 0.0 0.60675 1.0 0.5625 1.0 0.59375 1.0 0.10675 0.0 0.5625 0.0 0.53125 0.0 0.60675 1.0 0.53125 1.0 0.5625 1.0 0.10675 0.0 0.53125 0.0 0.5 0.0 0.60675 1.0 0.5 1.0 0.53125 1.0 0.10675 0.0 0.5 0.0 0.46875 0.0 0.60675 1.0 0.46875 1.0 0.5 1.0 0.10675 0.0 0.46875 0.0 0.4375 0.0 0.60675 1.0 0.4375 1.0 0.46875 1.0 0.10675 0.0 0.4375 0.0 0.40625 0.0 0.60675 1.0 0.40625 1.0 0.4375 1.0 0.10675 0.0 0.40625 0.0 0.375 0.0 0.60675 1.0 0.375 1.0 0.40625 1.0 0.10675 0.0 0.375 0.0 0.34375 0.0 0.60675 1.0 0.34375 1.0 0.375 1.0 0.10675 0.0 0.34375 0.0 0.3125 0.0 0.60675 1.0 0.3125 1.0 0.34375 1.0 0.10675 0.0 0.3125 0.0 0.28125 0.0 0.60675 1.0 0.28125 1.0 0.3125 1.0 0.10675 0.0 0.28125 0.0 0.25 0.0 0.60675 1.0 0.25 1.0 0.28125 1.0 0.10675 0.0 0.25 0.0 0.21875 0.0 0.60675 1.0 0.21875 1.0 0.25 1.0 0.10675 0.0 0.21875 0.0 0.1875 0.0 0.60675 1.0 0.1875 1.0 0.21875 1.0 0.10675 0.0 0.1875 0.0 0.15625 0.0 0.60675 1.0 0.15625 1.0 0.1875 1.0 0.10675 0.0 0.15625 0.0 0.125 0.0 0.60675 1.0 0.125 1.0 0.15625 1.0 0.10675 0.0 0.125 0.0 0.09375 0.0 0.60675 1.0 1.09375 1.0 0.125 1.0 0.10675 0.0 0.09375 0.0 0.0625 0.0 0.60675 1.0 1.0625 1.0 1.09375 1.0 0.10675 0.0 0.0625 0.0 0.03125 0.0 0.60675 1.0 1.03125 1.0 1.0625 1.0 1.10675 0.0 1.03125 0.0 1.0 0.0 0.60675 1.0 1.0 1.0 1.03125 1.0 1.10675 0.0 1.0 0.0 0.96875 -0.0 0.60675 1.0 0.96875 1.0 1.0 1.0 1.10675 0.0 0.96875 -0.0 0.9375 -0.0 0.60675 1.0 0.9375 1.0 0.96875 1.0 1.10675 0.0 0.9375 -0.0 0.90625 0.0 0.60675 1.0 0.90625 1.0 0.9375 1.0 1.10675 0.0 0.90625 0.0 0.875 0.0 0.60675 1.0 0.875 1.0 0.90625 1.0 1.10675 0.0 0.875 0.0 0.84375 -0.0 0.60675 1.0 0.84375 1.0 0.875 1.0 1.10675 0.0 0.84375 -0.0 0.8125 -0.0 0.60675 1.0 0.8125 1.0 0.84375 1.0 1.10675 0.0 0.8125 -0.0 0.78125 -0.0 0.60675 1.0 0.78125 1.0 0.8125 1.0 1.10675 0.0 0.78125 -0.0 0.75 -0.0 0.60675 1.0 0.75 1.0 0.78125 1.0 1.10675 0.0 0.75 -0.0 0.71875 -0.0 0.60675 1.0 0.71875 1.0 0.75 1.0 1.10675 0.0 0.71875 -0.0 0.6875 -0.0 0.60675 1.0 0.6875 1.0 0.71875 1.0 1.10675 0.0 0.6875 -0.0 0.65625 -0.0 0.60675 1.0 0.65625 1.0 0.6875 1.0 0.65625 -0.0 0.625 0.0 1.10675 0.0 0.60675 1.0 0.625 1.0 0.65625 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.625 1.0 0.625 0.0 0.65625 -0.0 0.625 1.0 0.625 0.0 0.65625 -0.0 + + + + + + + + + + + + + + +

    64 0 0 1 1 2 65 3 33 4 32 5 64 6 1 7 2 8 65 9 34 10 33 11 64 12 2 13 3 14 65 15 35 16 34 17 64 18 3 19 4 20 65 21 36 22 35 23 64 24 4 25 5 26 65 27 37 28 36 29 64 30 5 31 6 32 65 33 38 34 37 35 64 36 6 37 7 38 65 39 39 40 38 41 64 42 7 43 8 44 65 45 40 46 39 47 64 48 8 49 9 50 65 51 41 52 40 53 64 54 9 55 10 56 65 57 42 58 41 59 64 60 10 61 11 62 65 63 43 64 42 65 64 66 11 67 12 68 65 69 44 70 43 71 64 72 12 73 13 74 65 75 45 76 44 77 64 78 13 79 14 80 65 81 46 82 45 83 64 84 14 85 15 86 65 87 47 88 46 89 64 90 15 91 16 92 65 93 48 94 47 95 64 96 16 97 17 98 65 99 49 100 48 101 64 102 17 103 18 104 65 105 50 106 49 107 64 108 18 109 19 110 65 111 51 112 50 113 64 114 19 115 20 116 65 117 52 118 51 119 64 120 20 121 21 122 65 123 53 124 52 125 64 126 21 127 22 128 65 129 54 130 53 131 64 132 22 133 23 134 65 135 55 136 54 137 64 138 23 139 24 140 65 141 56 142 55 143 64 144 24 145 25 146 65 147 57 148 56 149 64 150 25 151 26 152 65 153 58 154 57 155 64 156 26 157 27 158 65 159 59 160 58 161 64 162 27 163 28 164 65 165 60 166 59 167 64 168 28 169 29 170 65 171 61 172 60 173 64 174 29 175 30 176 65 177 62 178 61 179 64 180 30 181 31 182 65 183 63 184 62 185 31 186 0 187 64 188 65 189 32 190 63 191 0 192 32 193 33 194 33 195 1 196 0 197 1 198 33 199 34 200 34 201 2 202 1 203 2 204 34 205 35 206 35 207 3 208 2 209 3 210 35 211 36 212 36 213 4 214 3 215 4 216 36 217 37 218 37 219 5 220 4 221 5 222 37 223 38 224 38 225 6 226 5 227 6 228 38 229 39 230 39 231 7 232 6 233 7 234 39 235 40 236 40 237 8 238 7 239 8 240 40 241 41 242 41 243 9 244 8 245 9 246 41 247 42 248 42 249 10 250 9 251 10 252 42 253 43 254 43 255 11 256 10 257 11 258 43 259 44 260 44 261 12 262 11 263 12 264 44 265 45 266 45 267 13 268 12 269 13 270 45 271 46 272 46 273 14 274 13 275 14 276 46 277 47 278 47 279 15 280 14 281 15 282 47 283 48 284 48 285 16 286 15 287 16 288 48 289 49 290 49 291 17 292 16 293 17 294 49 295 50 296 50 297 18 298 17 299 18 300 50 301 51 302 51 303 19 304 18 305 19 306 51 307 52 308 52 309 20 310 19 311 20 312 52 313 53 314 53 315 21 316 20 317 21 318 53 319 54 320 54 321 22 322 21 323 22 324 54 325 55 326 55 327 23 328 22 329 23 330 55 331 56 332 56 333 24 334 23 335 24 336 56 337 57 338 57 339 25 340 24 341 25 342 57 343 58 344 58 345 26 346 25 347 26 348 58 349 59 350 59 351 27 352 26 353 27 354 59 355 60 356 60 357 28 358 27 359 28 360 60 361 61 362 61 363 29 364 28 365 29 366 61 367 62 368 62 369 30 370 29 371 30 372 62 373 63 374 63 375 31 376 30 377 32 378 0 379 31 380 31 381 63 382 32 383

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.17588 0.7857 -1.0 1.30656 0.5412 -1.0 1.38704 0.2759 -1.0 1.41421 0.0 -1.0 1.38704 -0.2759 -1.0 1.30656 -0.5412 -1.0 1.17588 -0.78569 -1.0 1.0 -1.0 -1.0 0.78569 -1.17588 -1.0 0.5412 -1.30656 -1.0 0.2759 -1.38704 -1.0 -0.0 -1.41421 -1.0 -0.2759 -1.38704 -1.0 -0.5412 -1.30656 -1.0 -0.7857 -1.17588 -1.0 -1.0 -1.0 -1.0 -1.17588 -0.78569 -1.0 -1.30656 -0.5412 -1.0 -1.38704 -0.2759 -1.0 -1.41421 0.0 -1.0 -1.38704 0.2759 -1.0 -1.30656 0.5412 -1.0 -1.17587 0.7857 -1.0 -1.0 1.0 -1.0 -0.78569 1.17588 -1.0 -0.54119 1.30656 -1.0 -0.2759 1.38704 -1.0 0.0 1.41421 -1.0 0.2759 1.38704 -1.0 0.5412 1.30656 -1.0 0.7857 1.17587 -1.0 1.0 1.0 1.0 1.17588 0.78569 1.0 1.30656 0.54119 1.0 1.38704 0.2759 1.0 1.41421 -0.0 1.0 1.38704 -0.2759 1.0 1.30656 -0.5412 1.0 1.17587 -0.7857 1.0 1.0 -1.0 1.0 0.78569 -1.17588 1.0 0.5412 -1.30656 1.0 0.2759 -1.38704 1.0 0.0 -1.41421 1.0 -0.2759 -1.38704 1.0 -0.54119 -1.30656 1.0 -0.78569 -1.17588 1.0 -1.0 -1.0 1.0 -1.17587 -0.7857 1.0 -1.30656 -0.5412 1.0 -1.38704 -0.2759 1.0 -1.41421 -1e-05 1.0 -1.38704 0.27589 1.0 -1.30657 0.54119 1.0 -1.17588 0.78569 1.0 -1.00001 0.99999 1.0 -0.7857 1.17587 1.0 -0.5412 1.30656 1.0 -0.27591 1.38704 1.0 -1e-05 1.41421 1.0 0.27589 1.38704 1.0 0.54119 1.30657 1.0 0.78569 1.17588 1.0 -0.0 0.0 -1.0 0.0 -0.0 1.0 + + + + + + + + + + 0.49876 0.49876 -0.70879 0.5865 0.39189 -0.70879 0.65169 0.26994 -0.70879 0.69182 0.13761 -0.70879 0.70537 0.0 -0.70879 0.69182 -0.13761 -0.70879 0.65169 -0.26994 -0.70879 0.5865 -0.39189 -0.70879 0.49876 -0.49876 -0.70879 0.39189 -0.5865 -0.70879 0.26994 -0.65169 -0.70879 0.13761 -0.69182 -0.70879 0.0 -0.70537 -0.70879 -0.13761 -0.69182 -0.70879 -0.26994 -0.65169 -0.70879 -0.39189 -0.5865 -0.70879 -0.49876 -0.49876 -0.70879 -0.5865 -0.39189 -0.70879 -0.65169 -0.26994 -0.70879 -0.69182 -0.13761 -0.70879 -0.70537 0.0 -0.70879 -0.69182 0.13761 -0.70879 -0.65169 0.26994 -0.70879 -0.5865 0.39189 -0.70879 -0.49876 0.49876 -0.70879 -0.39189 0.5865 -0.70879 -0.26994 0.65169 -0.70879 -0.13761 0.69182 -0.70879 0.0 0.70537 -0.70879 0.13761 0.69182 -0.70879 0.26994 0.65169 -0.70879 0.39189 0.5865 -0.70879 0.49876 0.49876 0.70879 0.5865 0.39189 0.70879 0.65169 0.26994 0.70879 0.69182 0.13761 0.70879 0.70537 0.0 0.70879 0.69182 -0.13761 0.70879 0.65169 -0.26994 0.70879 0.5865 -0.39189 0.70879 0.49876 -0.49876 0.70879 0.39189 -0.5865 0.70879 0.26994 -0.65169 0.70879 0.13761 -0.69182 0.70879 0.0 -0.70537 0.70879 -0.13761 -0.69182 0.70879 -0.26994 -0.65169 0.70879 -0.39189 -0.5865 0.70879 -0.49876 -0.49876 0.70879 -0.5865 -0.39189 0.70879 -0.65169 -0.26994 0.70879 -0.69182 -0.13761 0.70879 -0.70537 0.0 0.70879 -0.69182 0.13761 0.70879 -0.65169 0.26994 0.70879 -0.5865 0.39189 0.70879 -0.49876 0.49876 0.70879 -0.39189 0.5865 0.70879 -0.26994 0.65169 0.70879 -0.13761 0.69182 0.70879 0.0 0.70537 0.70879 0.13761 0.69182 0.70879 0.26994 0.65169 0.70879 0.39189 0.5865 0.70879 0.0 0.0 -1.0 0.0 0.0 1.0 + + + + + + + + + + 1.10675 0.0 0.625 0.0 0.59375 0.0 0.60675 1.0 0.59375 1.0 0.625 1.0 0.10675 0.0 0.59375 0.0 0.5625 0.0 0.60675 1.0 0.5625 1.0 0.59375 1.0 0.10675 0.0 0.5625 0.0 0.53125 0.0 0.60675 1.0 0.53125 1.0 0.5625 1.0 0.10675 0.0 0.53125 0.0 0.5 0.0 0.60675 1.0 0.5 1.0 0.53125 1.0 0.10675 0.0 0.5 0.0 0.46875 0.0 0.60675 1.0 0.46875 1.0 0.5 1.0 0.10675 0.0 0.46875 0.0 0.4375 0.0 0.60675 1.0 0.4375 1.0 0.46875 1.0 0.10675 0.0 0.4375 0.0 0.40625 0.0 0.60675 1.0 0.40625 1.0 0.4375 1.0 0.10675 0.0 0.40625 0.0 0.375 0.0 0.60675 1.0 0.375 1.0 0.40625 1.0 0.10675 0.0 0.375 0.0 0.34375 0.0 0.60675 1.0 0.34375 1.0 0.375 1.0 0.10675 0.0 0.34375 0.0 0.3125 0.0 0.60675 1.0 0.3125 1.0 0.34375 1.0 0.10675 0.0 0.3125 0.0 0.28125 0.0 0.60675 1.0 0.28125 1.0 0.3125 1.0 0.10675 0.0 0.28125 0.0 0.25 0.0 0.60675 1.0 0.25 1.0 0.28125 1.0 0.10675 0.0 0.25 0.0 0.21875 0.0 0.60675 1.0 0.21875 1.0 0.25 1.0 0.10675 0.0 0.21875 0.0 0.1875 0.0 0.60675 1.0 0.1875 1.0 0.21875 1.0 0.10675 0.0 0.1875 0.0 0.15625 0.0 0.60675 1.0 0.15625 1.0 0.1875 1.0 0.10675 0.0 0.15625 0.0 0.125 0.0 0.60675 1.0 0.125 1.0 0.15625 1.0 0.10675 0.0 0.125 0.0 0.09375 0.0 0.60675 1.0 1.09375 1.0 0.125 1.0 0.10675 0.0 0.09375 0.0 0.0625 0.0 0.60675 1.0 1.0625 1.0 1.09375 1.0 0.10675 0.0 0.0625 0.0 0.03125 0.0 0.60675 1.0 1.03125 1.0 1.0625 1.0 1.10675 0.0 1.03125 0.0 1.0 0.0 0.60675 1.0 1.0 1.0 1.03125 1.0 1.10675 0.0 1.0 0.0 0.96875 -0.0 0.60675 1.0 0.96875 1.0 1.0 1.0 1.10675 0.0 0.96875 -0.0 0.9375 -0.0 0.60675 1.0 0.9375 1.0 0.96875 1.0 1.10675 0.0 0.9375 -0.0 0.90625 0.0 0.60675 1.0 0.90625 1.0 0.9375 1.0 1.10675 0.0 0.90625 0.0 0.875 0.0 0.60675 1.0 0.875 1.0 0.90625 1.0 1.10675 0.0 0.875 0.0 0.84375 -0.0 0.60675 1.0 0.84375 1.0 0.875 1.0 1.10675 0.0 0.84375 -0.0 0.8125 -0.0 0.60675 1.0 0.8125 1.0 0.84375 1.0 1.10675 0.0 0.8125 -0.0 0.78125 -0.0 0.60675 1.0 0.78125 1.0 0.8125 1.0 1.10675 0.0 0.78125 -0.0 0.75 -0.0 0.60675 1.0 0.75 1.0 0.78125 1.0 1.10675 0.0 0.75 -0.0 0.71875 -0.0 0.60675 1.0 0.71875 1.0 0.75 1.0 1.10675 0.0 0.71875 -0.0 0.6875 -0.0 0.60675 1.0 0.6875 1.0 0.71875 1.0 1.10675 0.0 0.6875 -0.0 0.65625 -0.0 0.60675 1.0 0.65625 1.0 0.6875 1.0 0.65625 -0.0 0.625 0.0 1.10675 0.0 0.60675 1.0 0.625 1.0 0.65625 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.625 1.0 0.625 0.0 0.65625 -0.0 0.625 1.0 0.625 0.0 0.65625 -0.0 + + + + + + + + + + + + + + +

    64 0 0 1 1 2 65 3 33 4 32 5 64 6 1 7 2 8 65 9 34 10 33 11 64 12 2 13 3 14 65 15 35 16 34 17 64 18 3 19 4 20 65 21 36 22 35 23 64 24 4 25 5 26 65 27 37 28 36 29 64 30 5 31 6 32 65 33 38 34 37 35 64 36 6 37 7 38 65 39 39 40 38 41 64 42 7 43 8 44 65 45 40 46 39 47 64 48 8 49 9 50 65 51 41 52 40 53 64 54 9 55 10 56 65 57 42 58 41 59 64 60 10 61 11 62 65 63 43 64 42 65 64 66 11 67 12 68 65 69 44 70 43 71 64 72 12 73 13 74 65 75 45 76 44 77 64 78 13 79 14 80 65 81 46 82 45 83 64 84 14 85 15 86 65 87 47 88 46 89 64 90 15 91 16 92 65 93 48 94 47 95 64 96 16 97 17 98 65 99 49 100 48 101 64 102 17 103 18 104 65 105 50 106 49 107 64 108 18 109 19 110 65 111 51 112 50 113 64 114 19 115 20 116 65 117 52 118 51 119 64 120 20 121 21 122 65 123 53 124 52 125 64 126 21 127 22 128 65 129 54 130 53 131 64 132 22 133 23 134 65 135 55 136 54 137 64 138 23 139 24 140 65 141 56 142 55 143 64 144 24 145 25 146 65 147 57 148 56 149 64 150 25 151 26 152 65 153 58 154 57 155 64 156 26 157 27 158 65 159 59 160 58 161 64 162 27 163 28 164 65 165 60 166 59 167 64 168 28 169 29 170 65 171 61 172 60 173 64 174 29 175 30 176 65 177 62 178 61 179 64 180 30 181 31 182 65 183 63 184 62 185 31 186 0 187 64 188 65 189 32 190 63 191 0 192 32 193 33 194 33 195 1 196 0 197 1 198 33 199 34 200 34 201 2 202 1 203 2 204 34 205 35 206 35 207 3 208 2 209 3 210 35 211 36 212 36 213 4 214 3 215 4 216 36 217 37 218 37 219 5 220 4 221 5 222 37 223 38 224 38 225 6 226 5 227 6 228 38 229 39 230 39 231 7 232 6 233 7 234 39 235 40 236 40 237 8 238 7 239 8 240 40 241 41 242 41 243 9 244 8 245 9 246 41 247 42 248 42 249 10 250 9 251 10 252 42 253 43 254 43 255 11 256 10 257 11 258 43 259 44 260 44 261 12 262 11 263 12 264 44 265 45 266 45 267 13 268 12 269 13 270 45 271 46 272 46 273 14 274 13 275 14 276 46 277 47 278 47 279 15 280 14 281 15 282 47 283 48 284 48 285 16 286 15 287 16 288 48 289 49 290 49 291 17 292 16 293 17 294 49 295 50 296 50 297 18 298 17 299 18 300 50 301 51 302 51 303 19 304 18 305 19 306 51 307 52 308 52 309 20 310 19 311 20 312 52 313 53 314 53 315 21 316 20 317 21 318 53 319 54 320 54 321 22 322 21 323 22 324 54 325 55 326 55 327 23 328 22 329 23 330 55 331 56 332 56 333 24 334 23 335 24 336 56 337 57 338 57 339 25 340 24 341 25 342 57 343 58 344 58 345 26 346 25 347 26 348 58 349 59 350 59 351 27 352 26 353 27 354 59 355 60 356 60 357 28 358 27 359 28 360 60 361 61 362 61 363 29 364 28 365 29 366 61 367 62 368 62 369 30 370 29 371 30 372 62 373 63 374 63 375 31 376 30 377 32 378 0 379 31 380 31 381 63 382 32 383

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.17588 0.7857 -1.0 1.30656 0.5412 -1.0 1.38704 0.2759 -1.0 1.41421 0.0 -1.0 1.38704 -0.2759 -1.0 1.30656 -0.5412 -1.0 1.17588 -0.78569 -1.0 1.0 -1.0 -1.0 0.78569 -1.17588 -1.0 0.5412 -1.30656 -1.0 0.2759 -1.38704 -1.0 -0.0 -1.41421 -1.0 -0.2759 -1.38704 -1.0 -0.5412 -1.30656 -1.0 -0.7857 -1.17588 -1.0 -1.0 -1.0 -1.0 -1.17588 -0.78569 -1.0 -1.30656 -0.5412 -1.0 -1.38704 -0.2759 -1.0 -1.41421 0.0 -1.0 -1.38704 0.2759 -1.0 -1.30656 0.5412 -1.0 -1.17587 0.7857 -1.0 -1.0 1.0 -1.0 -0.78569 1.17588 -1.0 -0.54119 1.30656 -1.0 -0.2759 1.38704 -1.0 0.0 1.41421 -1.0 0.2759 1.38704 -1.0 0.5412 1.30656 -1.0 0.7857 1.17587 -1.0 1.0 1.0 1.0 1.17588 0.78569 1.0 1.30656 0.54119 1.0 1.38704 0.2759 1.0 1.41421 -0.0 1.0 1.38704 -0.2759 1.0 1.30656 -0.5412 1.0 1.17587 -0.7857 1.0 1.0 -1.0 1.0 0.78569 -1.17588 1.0 0.5412 -1.30656 1.0 0.2759 -1.38704 1.0 0.0 -1.41421 1.0 -0.2759 -1.38704 1.0 -0.54119 -1.30656 1.0 -0.78569 -1.17588 1.0 -1.0 -1.0 1.0 -1.17587 -0.7857 1.0 -1.30656 -0.5412 1.0 -1.38704 -0.2759 1.0 -1.41421 -1e-05 1.0 -1.38704 0.27589 1.0 -1.30657 0.54119 1.0 -1.17588 0.78569 1.0 -1.00001 0.99999 1.0 -0.7857 1.17587 1.0 -0.5412 1.30656 1.0 -0.27591 1.38704 1.0 -1e-05 1.41421 1.0 0.27589 1.38704 1.0 0.54119 1.30657 1.0 0.78569 1.17588 1.0 -0.0 0.0 -1.0 0.0 -0.0 1.0 + + + + + + + + + + 0.49876 0.49876 -0.70879 0.5865 0.39189 -0.70879 0.65169 0.26994 -0.70879 0.69182 0.13761 -0.70879 0.70537 0.0 -0.70879 0.69182 -0.13761 -0.70879 0.65169 -0.26994 -0.70879 0.5865 -0.39189 -0.70879 0.49876 -0.49876 -0.70879 0.39189 -0.5865 -0.70879 0.26994 -0.65169 -0.70879 0.13761 -0.69182 -0.70879 0.0 -0.70537 -0.70879 -0.13761 -0.69182 -0.70879 -0.26994 -0.65169 -0.70879 -0.39189 -0.5865 -0.70879 -0.49876 -0.49876 -0.70879 -0.5865 -0.39189 -0.70879 -0.65169 -0.26994 -0.70879 -0.69182 -0.13761 -0.70879 -0.70537 0.0 -0.70879 -0.69182 0.13761 -0.70879 -0.65169 0.26994 -0.70879 -0.5865 0.39189 -0.70879 -0.49876 0.49876 -0.70879 -0.39189 0.5865 -0.70879 -0.26994 0.65169 -0.70879 -0.13761 0.69182 -0.70879 0.0 0.70537 -0.70879 0.13761 0.69182 -0.70879 0.26994 0.65169 -0.70879 0.39189 0.5865 -0.70879 0.49876 0.49876 0.70879 0.5865 0.39189 0.70879 0.65169 0.26994 0.70879 0.69182 0.13761 0.70879 0.70537 0.0 0.70879 0.69182 -0.13761 0.70879 0.65169 -0.26994 0.70879 0.5865 -0.39189 0.70879 0.49876 -0.49876 0.70879 0.39189 -0.5865 0.70879 0.26994 -0.65169 0.70879 0.13761 -0.69182 0.70879 0.0 -0.70537 0.70879 -0.13761 -0.69182 0.70879 -0.26994 -0.65169 0.70879 -0.39189 -0.5865 0.70879 -0.49876 -0.49876 0.70879 -0.5865 -0.39189 0.70879 -0.65169 -0.26994 0.70879 -0.69182 -0.13761 0.70879 -0.70537 0.0 0.70879 -0.69182 0.13761 0.70879 -0.65169 0.26994 0.70879 -0.5865 0.39189 0.70879 -0.49876 0.49876 0.70879 -0.39189 0.5865 0.70879 -0.26994 0.65169 0.70879 -0.13761 0.69182 0.70879 0.0 0.70537 0.70879 0.13761 0.69182 0.70879 0.26994 0.65169 0.70879 0.39189 0.5865 0.70879 0.0 0.0 -1.0 0.0 0.0 1.0 + + + + + + + + + + 1.10675 0.0 0.625 0.0 0.59375 0.0 0.60675 1.0 0.59375 1.0 0.625 1.0 0.10675 0.0 0.59375 0.0 0.5625 0.0 0.60675 1.0 0.5625 1.0 0.59375 1.0 0.10675 0.0 0.5625 0.0 0.53125 0.0 0.60675 1.0 0.53125 1.0 0.5625 1.0 0.10675 0.0 0.53125 0.0 0.5 0.0 0.60675 1.0 0.5 1.0 0.53125 1.0 0.10675 0.0 0.5 0.0 0.46875 0.0 0.60675 1.0 0.46875 1.0 0.5 1.0 0.10675 0.0 0.46875 0.0 0.4375 0.0 0.60675 1.0 0.4375 1.0 0.46875 1.0 0.10675 0.0 0.4375 0.0 0.40625 0.0 0.60675 1.0 0.40625 1.0 0.4375 1.0 0.10675 0.0 0.40625 0.0 0.375 0.0 0.60675 1.0 0.375 1.0 0.40625 1.0 0.10675 0.0 0.375 0.0 0.34375 0.0 0.60675 1.0 0.34375 1.0 0.375 1.0 0.10675 0.0 0.34375 0.0 0.3125 0.0 0.60675 1.0 0.3125 1.0 0.34375 1.0 0.10675 0.0 0.3125 0.0 0.28125 0.0 0.60675 1.0 0.28125 1.0 0.3125 1.0 0.10675 0.0 0.28125 0.0 0.25 0.0 0.60675 1.0 0.25 1.0 0.28125 1.0 0.10675 0.0 0.25 0.0 0.21875 0.0 0.60675 1.0 0.21875 1.0 0.25 1.0 0.10675 0.0 0.21875 0.0 0.1875 0.0 0.60675 1.0 0.1875 1.0 0.21875 1.0 0.10675 0.0 0.1875 0.0 0.15625 0.0 0.60675 1.0 0.15625 1.0 0.1875 1.0 0.10675 0.0 0.15625 0.0 0.125 0.0 0.60675 1.0 0.125 1.0 0.15625 1.0 0.10675 0.0 0.125 0.0 0.09375 0.0 0.60675 1.0 1.09375 1.0 0.125 1.0 0.10675 0.0 0.09375 0.0 0.0625 0.0 0.60675 1.0 1.0625 1.0 1.09375 1.0 0.10675 0.0 0.0625 0.0 0.03125 0.0 0.60675 1.0 1.03125 1.0 1.0625 1.0 1.10675 0.0 1.03125 0.0 1.0 0.0 0.60675 1.0 1.0 1.0 1.03125 1.0 1.10675 0.0 1.0 0.0 0.96875 -0.0 0.60675 1.0 0.96875 1.0 1.0 1.0 1.10675 0.0 0.96875 -0.0 0.9375 -0.0 0.60675 1.0 0.9375 1.0 0.96875 1.0 1.10675 0.0 0.9375 -0.0 0.90625 0.0 0.60675 1.0 0.90625 1.0 0.9375 1.0 1.10675 0.0 0.90625 0.0 0.875 0.0 0.60675 1.0 0.875 1.0 0.90625 1.0 1.10675 0.0 0.875 0.0 0.84375 -0.0 0.60675 1.0 0.84375 1.0 0.875 1.0 1.10675 0.0 0.84375 -0.0 0.8125 -0.0 0.60675 1.0 0.8125 1.0 0.84375 1.0 1.10675 0.0 0.8125 -0.0 0.78125 -0.0 0.60675 1.0 0.78125 1.0 0.8125 1.0 1.10675 0.0 0.78125 -0.0 0.75 -0.0 0.60675 1.0 0.75 1.0 0.78125 1.0 1.10675 0.0 0.75 -0.0 0.71875 -0.0 0.60675 1.0 0.71875 1.0 0.75 1.0 1.10675 0.0 0.71875 -0.0 0.6875 -0.0 0.60675 1.0 0.6875 1.0 0.71875 1.0 1.10675 0.0 0.6875 -0.0 0.65625 -0.0 0.60675 1.0 0.65625 1.0 0.6875 1.0 0.65625 -0.0 0.625 0.0 1.10675 0.0 0.60675 1.0 0.625 1.0 0.65625 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.625 1.0 0.625 0.0 0.65625 -0.0 0.625 1.0 0.625 0.0 0.65625 -0.0 + + + + + + + + + + + + + + +

    64 0 0 1 1 2 65 3 33 4 32 5 64 6 1 7 2 8 65 9 34 10 33 11 64 12 2 13 3 14 65 15 35 16 34 17 64 18 3 19 4 20 65 21 36 22 35 23 64 24 4 25 5 26 65 27 37 28 36 29 64 30 5 31 6 32 65 33 38 34 37 35 64 36 6 37 7 38 65 39 39 40 38 41 64 42 7 43 8 44 65 45 40 46 39 47 64 48 8 49 9 50 65 51 41 52 40 53 64 54 9 55 10 56 65 57 42 58 41 59 64 60 10 61 11 62 65 63 43 64 42 65 64 66 11 67 12 68 65 69 44 70 43 71 64 72 12 73 13 74 65 75 45 76 44 77 64 78 13 79 14 80 65 81 46 82 45 83 64 84 14 85 15 86 65 87 47 88 46 89 64 90 15 91 16 92 65 93 48 94 47 95 64 96 16 97 17 98 65 99 49 100 48 101 64 102 17 103 18 104 65 105 50 106 49 107 64 108 18 109 19 110 65 111 51 112 50 113 64 114 19 115 20 116 65 117 52 118 51 119 64 120 20 121 21 122 65 123 53 124 52 125 64 126 21 127 22 128 65 129 54 130 53 131 64 132 22 133 23 134 65 135 55 136 54 137 64 138 23 139 24 140 65 141 56 142 55 143 64 144 24 145 25 146 65 147 57 148 56 149 64 150 25 151 26 152 65 153 58 154 57 155 64 156 26 157 27 158 65 159 59 160 58 161 64 162 27 163 28 164 65 165 60 166 59 167 64 168 28 169 29 170 65 171 61 172 60 173 64 174 29 175 30 176 65 177 62 178 61 179 64 180 30 181 31 182 65 183 63 184 62 185 31 186 0 187 64 188 65 189 32 190 63 191 0 192 32 193 33 194 33 195 1 196 0 197 1 198 33 199 34 200 34 201 2 202 1 203 2 204 34 205 35 206 35 207 3 208 2 209 3 210 35 211 36 212 36 213 4 214 3 215 4 216 36 217 37 218 37 219 5 220 4 221 5 222 37 223 38 224 38 225 6 226 5 227 6 228 38 229 39 230 39 231 7 232 6 233 7 234 39 235 40 236 40 237 8 238 7 239 8 240 40 241 41 242 41 243 9 244 8 245 9 246 41 247 42 248 42 249 10 250 9 251 10 252 42 253 43 254 43 255 11 256 10 257 11 258 43 259 44 260 44 261 12 262 11 263 12 264 44 265 45 266 45 267 13 268 12 269 13 270 45 271 46 272 46 273 14 274 13 275 14 276 46 277 47 278 47 279 15 280 14 281 15 282 47 283 48 284 48 285 16 286 15 287 16 288 48 289 49 290 49 291 17 292 16 293 17 294 49 295 50 296 50 297 18 298 17 299 18 300 50 301 51 302 51 303 19 304 18 305 19 306 51 307 52 308 52 309 20 310 19 311 20 312 52 313 53 314 53 315 21 316 20 317 21 318 53 319 54 320 54 321 22 322 21 323 22 324 54 325 55 326 55 327 23 328 22 329 23 330 55 331 56 332 56 333 24 334 23 335 24 336 56 337 57 338 57 339 25 340 24 341 25 342 57 343 58 344 58 345 26 346 25 347 26 348 58 349 59 350 59 351 27 352 26 353 27 354 59 355 60 356 60 357 28 358 27 359 28 360 60 361 61 362 61 363 29 364 28 365 29 366 61 367 62 368 62 369 30 370 29 371 30 372 62 373 63 374 63 375 31 376 30 377 32 378 0 379 31 380 31 381 63 382 32 383

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.17588 0.7857 -1.0 1.30656 0.5412 -1.0 1.38704 0.2759 -1.0 1.41421 0.0 -1.0 1.38704 -0.2759 -1.0 1.30656 -0.5412 -1.0 1.17588 -0.78569 -1.0 1.0 -1.0 -1.0 0.78569 -1.17588 -1.0 0.5412 -1.30656 -1.0 0.2759 -1.38704 -1.0 -0.0 -1.41421 -1.0 -0.2759 -1.38704 -1.0 -0.5412 -1.30656 -1.0 -0.7857 -1.17588 -1.0 -1.0 -1.0 -1.0 -1.17588 -0.78569 -1.0 -1.30656 -0.5412 -1.0 -1.38704 -0.2759 -1.0 -1.41421 0.0 -1.0 -1.38704 0.2759 -1.0 -1.30656 0.5412 -1.0 -1.17587 0.7857 -1.0 -1.0 1.0 -1.0 -0.78569 1.17588 -1.0 -0.54119 1.30656 -1.0 -0.2759 1.38704 -1.0 0.0 1.41421 -1.0 0.2759 1.38704 -1.0 0.5412 1.30656 -1.0 0.7857 1.17587 -1.0 1.0 1.0 1.0 1.17588 0.78569 1.0 1.30656 0.54119 1.0 1.38704 0.2759 1.0 1.41421 -0.0 1.0 1.38704 -0.2759 1.0 1.30656 -0.5412 1.0 1.17587 -0.7857 1.0 1.0 -1.0 1.0 0.78569 -1.17588 1.0 0.5412 -1.30656 1.0 0.2759 -1.38704 1.0 0.0 -1.41421 1.0 -0.2759 -1.38704 1.0 -0.54119 -1.30656 1.0 -0.78569 -1.17588 1.0 -1.0 -1.0 1.0 -1.17587 -0.7857 1.0 -1.30656 -0.5412 1.0 -1.38704 -0.2759 1.0 -1.41421 -1e-05 1.0 -1.38704 0.27589 1.0 -1.30657 0.54119 1.0 -1.17588 0.78569 1.0 -1.00001 0.99999 1.0 -0.7857 1.17587 1.0 -0.5412 1.30656 1.0 -0.27591 1.38704 1.0 -1e-05 1.41421 1.0 0.27589 1.38704 1.0 0.54119 1.30657 1.0 0.78569 1.17588 1.0 -0.0 0.0 -1.0 0.0 -0.0 1.0 + + + + + + + + + + 0.49876 0.49876 -0.70879 0.5865 0.39189 -0.70879 0.65169 0.26994 -0.70879 0.69182 0.13761 -0.70879 0.70537 0.0 -0.70879 0.69182 -0.13761 -0.70879 0.65169 -0.26994 -0.70879 0.5865 -0.39189 -0.70879 0.49876 -0.49876 -0.70879 0.39189 -0.5865 -0.70879 0.26994 -0.65169 -0.70879 0.13761 -0.69182 -0.70879 0.0 -0.70537 -0.70879 -0.13761 -0.69182 -0.70879 -0.26994 -0.65169 -0.70879 -0.39189 -0.5865 -0.70879 -0.49876 -0.49876 -0.70879 -0.5865 -0.39189 -0.70879 -0.65169 -0.26994 -0.70879 -0.69182 -0.13761 -0.70879 -0.70537 0.0 -0.70879 -0.69182 0.13761 -0.70879 -0.65169 0.26994 -0.70879 -0.5865 0.39189 -0.70879 -0.49876 0.49876 -0.70879 -0.39189 0.5865 -0.70879 -0.26994 0.65169 -0.70879 -0.13761 0.69182 -0.70879 0.0 0.70537 -0.70879 0.13761 0.69182 -0.70879 0.26994 0.65169 -0.70879 0.39189 0.5865 -0.70879 0.49876 0.49876 0.70879 0.5865 0.39189 0.70879 0.65169 0.26994 0.70879 0.69182 0.13761 0.70879 0.70537 0.0 0.70879 0.69182 -0.13761 0.70879 0.65169 -0.26994 0.70879 0.5865 -0.39189 0.70879 0.49876 -0.49876 0.70879 0.39189 -0.5865 0.70879 0.26994 -0.65169 0.70879 0.13761 -0.69182 0.70879 0.0 -0.70537 0.70879 -0.13761 -0.69182 0.70879 -0.26994 -0.65169 0.70879 -0.39189 -0.5865 0.70879 -0.49876 -0.49876 0.70879 -0.5865 -0.39189 0.70879 -0.65169 -0.26994 0.70879 -0.69182 -0.13761 0.70879 -0.70537 0.0 0.70879 -0.69182 0.13761 0.70879 -0.65169 0.26994 0.70879 -0.5865 0.39189 0.70879 -0.49876 0.49876 0.70879 -0.39189 0.5865 0.70879 -0.26994 0.65169 0.70879 -0.13761 0.69182 0.70879 0.0 0.70537 0.70879 0.13761 0.69182 0.70879 0.26994 0.65169 0.70879 0.39189 0.5865 0.70879 0.0 0.0 -1.0 0.0 0.0 1.0 + + + + + + + + + + 1.10675 0.0 0.625 0.0 0.59375 0.0 0.60675 1.0 0.59375 1.0 0.625 1.0 0.10675 0.0 0.59375 0.0 0.5625 0.0 0.60675 1.0 0.5625 1.0 0.59375 1.0 0.10675 0.0 0.5625 0.0 0.53125 0.0 0.60675 1.0 0.53125 1.0 0.5625 1.0 0.10675 0.0 0.53125 0.0 0.5 0.0 0.60675 1.0 0.5 1.0 0.53125 1.0 0.10675 0.0 0.5 0.0 0.46875 0.0 0.60675 1.0 0.46875 1.0 0.5 1.0 0.10675 0.0 0.46875 0.0 0.4375 0.0 0.60675 1.0 0.4375 1.0 0.46875 1.0 0.10675 0.0 0.4375 0.0 0.40625 0.0 0.60675 1.0 0.40625 1.0 0.4375 1.0 0.10675 0.0 0.40625 0.0 0.375 0.0 0.60675 1.0 0.375 1.0 0.40625 1.0 0.10675 0.0 0.375 0.0 0.34375 0.0 0.60675 1.0 0.34375 1.0 0.375 1.0 0.10675 0.0 0.34375 0.0 0.3125 0.0 0.60675 1.0 0.3125 1.0 0.34375 1.0 0.10675 0.0 0.3125 0.0 0.28125 0.0 0.60675 1.0 0.28125 1.0 0.3125 1.0 0.10675 0.0 0.28125 0.0 0.25 0.0 0.60675 1.0 0.25 1.0 0.28125 1.0 0.10675 0.0 0.25 0.0 0.21875 0.0 0.60675 1.0 0.21875 1.0 0.25 1.0 0.10675 0.0 0.21875 0.0 0.1875 0.0 0.60675 1.0 0.1875 1.0 0.21875 1.0 0.10675 0.0 0.1875 0.0 0.15625 0.0 0.60675 1.0 0.15625 1.0 0.1875 1.0 0.10675 0.0 0.15625 0.0 0.125 0.0 0.60675 1.0 0.125 1.0 0.15625 1.0 0.10675 0.0 0.125 0.0 0.09375 0.0 0.60675 1.0 1.09375 1.0 0.125 1.0 0.10675 0.0 0.09375 0.0 0.0625 0.0 0.60675 1.0 1.0625 1.0 1.09375 1.0 0.10675 0.0 0.0625 0.0 0.03125 0.0 0.60675 1.0 1.03125 1.0 1.0625 1.0 1.10675 0.0 1.03125 0.0 1.0 0.0 0.60675 1.0 1.0 1.0 1.03125 1.0 1.10675 0.0 1.0 0.0 0.96875 -0.0 0.60675 1.0 0.96875 1.0 1.0 1.0 1.10675 0.0 0.96875 -0.0 0.9375 -0.0 0.60675 1.0 0.9375 1.0 0.96875 1.0 1.10675 0.0 0.9375 -0.0 0.90625 0.0 0.60675 1.0 0.90625 1.0 0.9375 1.0 1.10675 0.0 0.90625 0.0 0.875 0.0 0.60675 1.0 0.875 1.0 0.90625 1.0 1.10675 0.0 0.875 0.0 0.84375 -0.0 0.60675 1.0 0.84375 1.0 0.875 1.0 1.10675 0.0 0.84375 -0.0 0.8125 -0.0 0.60675 1.0 0.8125 1.0 0.84375 1.0 1.10675 0.0 0.8125 -0.0 0.78125 -0.0 0.60675 1.0 0.78125 1.0 0.8125 1.0 1.10675 0.0 0.78125 -0.0 0.75 -0.0 0.60675 1.0 0.75 1.0 0.78125 1.0 1.10675 0.0 0.75 -0.0 0.71875 -0.0 0.60675 1.0 0.71875 1.0 0.75 1.0 1.10675 0.0 0.71875 -0.0 0.6875 -0.0 0.60675 1.0 0.6875 1.0 0.71875 1.0 1.10675 0.0 0.6875 -0.0 0.65625 -0.0 0.60675 1.0 0.65625 1.0 0.6875 1.0 0.65625 -0.0 0.625 0.0 1.10675 0.0 0.60675 1.0 0.625 1.0 0.65625 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.625 0.0 0.625 1.0 0.59375 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.59375 0.0 0.59375 1.0 0.5625 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.5625 0.0 0.5625 1.0 0.53125 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.53125 0.0 0.53125 1.0 0.5 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.5 0.0 0.5 1.0 0.46875 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.46875 0.0 0.46875 1.0 0.4375 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.4375 0.0 0.4375 1.0 0.40625 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.40625 0.0 0.40625 1.0 0.375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.375 0.0 0.375 1.0 0.34375 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.34375 0.0 0.34375 1.0 0.3125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.3125 0.0 0.3125 1.0 0.28125 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.28125 0.0 0.28125 1.0 0.25 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.25 0.0 0.25 1.0 0.21875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.21875 0.0 0.21875 1.0 0.1875 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.1875 0.0 0.1875 1.0 0.15625 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.15625 0.0 0.15625 1.0 0.125 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.125 0.0 0.125 1.0 0.09375 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.09375 0.0 0.09375 1.0 0.0625 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 0.0625 0.0 0.0625 1.0 0.03125 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.03125 0.0 1.03125 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 1.0 0.0 1.0 1.0 0.96875 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.96875 -0.0 0.96875 1.0 0.9375 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.9375 -0.0 0.9375 1.0 0.90625 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.90625 0.0 0.90625 1.0 0.875 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.875 0.0 0.875 1.0 0.84375 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.84375 -0.0 0.84375 1.0 0.8125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.8125 -0.0 0.8125 1.0 0.78125 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.78125 -0.0 0.78125 1.0 0.75 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.75 -0.0 0.75 1.0 0.71875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.71875 -0.0 0.71875 1.0 0.6875 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.6875 -0.0 0.6875 1.0 0.65625 1.0 0.625 1.0 0.625 0.0 0.65625 -0.0 0.625 1.0 0.625 0.0 0.65625 -0.0 + + + + + + + + + + + + + + +

    64 0 0 1 1 2 65 3 33 4 32 5 64 6 1 7 2 8 65 9 34 10 33 11 64 12 2 13 3 14 65 15 35 16 34 17 64 18 3 19 4 20 65 21 36 22 35 23 64 24 4 25 5 26 65 27 37 28 36 29 64 30 5 31 6 32 65 33 38 34 37 35 64 36 6 37 7 38 65 39 39 40 38 41 64 42 7 43 8 44 65 45 40 46 39 47 64 48 8 49 9 50 65 51 41 52 40 53 64 54 9 55 10 56 65 57 42 58 41 59 64 60 10 61 11 62 65 63 43 64 42 65 64 66 11 67 12 68 65 69 44 70 43 71 64 72 12 73 13 74 65 75 45 76 44 77 64 78 13 79 14 80 65 81 46 82 45 83 64 84 14 85 15 86 65 87 47 88 46 89 64 90 15 91 16 92 65 93 48 94 47 95 64 96 16 97 17 98 65 99 49 100 48 101 64 102 17 103 18 104 65 105 50 106 49 107 64 108 18 109 19 110 65 111 51 112 50 113 64 114 19 115 20 116 65 117 52 118 51 119 64 120 20 121 21 122 65 123 53 124 52 125 64 126 21 127 22 128 65 129 54 130 53 131 64 132 22 133 23 134 65 135 55 136 54 137 64 138 23 139 24 140 65 141 56 142 55 143 64 144 24 145 25 146 65 147 57 148 56 149 64 150 25 151 26 152 65 153 58 154 57 155 64 156 26 157 27 158 65 159 59 160 58 161 64 162 27 163 28 164 65 165 60 166 59 167 64 168 28 169 29 170 65 171 61 172 60 173 64 174 29 175 30 176 65 177 62 178 61 179 64 180 30 181 31 182 65 183 63 184 62 185 31 186 0 187 64 188 65 189 32 190 63 191 0 192 32 193 33 194 33 195 1 196 0 197 1 198 33 199 34 200 34 201 2 202 1 203 2 204 34 205 35 206 35 207 3 208 2 209 3 210 35 211 36 212 36 213 4 214 3 215 4 216 36 217 37 218 37 219 5 220 4 221 5 222 37 223 38 224 38 225 6 226 5 227 6 228 38 229 39 230 39 231 7 232 6 233 7 234 39 235 40 236 40 237 8 238 7 239 8 240 40 241 41 242 41 243 9 244 8 245 9 246 41 247 42 248 42 249 10 250 9 251 10 252 42 253 43 254 43 255 11 256 10 257 11 258 43 259 44 260 44 261 12 262 11 263 12 264 44 265 45 266 45 267 13 268 12 269 13 270 45 271 46 272 46 273 14 274 13 275 14 276 46 277 47 278 47 279 15 280 14 281 15 282 47 283 48 284 48 285 16 286 15 287 16 288 48 289 49 290 49 291 17 292 16 293 17 294 49 295 50 296 50 297 18 298 17 299 18 300 50 301 51 302 51 303 19 304 18 305 19 306 51 307 52 308 52 309 20 310 19 311 20 312 52 313 53 314 53 315 21 316 20 317 21 318 53 319 54 320 54 321 22 322 21 323 22 324 54 325 55 326 55 327 23 328 22 329 23 330 55 331 56 332 56 333 24 334 23 335 24 336 56 337 57 338 57 339 25 340 24 341 25 342 57 343 58 344 58 345 26 346 25 347 26 348 58 349 59 350 59 351 27 352 26 353 27 354 59 355 60 356 60 357 28 358 27 359 28 360 60 361 61 362 61 363 29 364 28 365 29 366 61 367 62 368 62 369 30 370 29 371 30 372 62 373 63 374 63 375 31 376 30 377 32 378 0 379 31 380 31 381 63 382 32 383

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -0.98953 0.47376 3.0 -0.98953 -0.47376 3.0 0.98953 -0.47376 3.0 0.98953 0.47376 -3.0 -0.98954 0.47376 -3.0 -0.98953 -0.47376 -3.0 0.98953 -0.47376 -3.0 0.98953 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -0.98953 0.47376 3.0 -0.98953 -0.47376 3.0 0.98953 -0.47376 3.0 0.98953 0.47376 -3.0 -0.98954 0.47376 -3.0 -0.98953 -0.47376 -3.0 0.98953 -0.47376 -3.0 0.98953 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -0.98953 0.47376 3.0 -0.98953 -0.47376 3.0 0.98953 -0.47376 3.0 0.98953 0.47376 -3.0 -0.98954 0.47376 -3.0 -0.98953 -0.47376 -3.0 0.98953 -0.47376 -3.0 0.98953 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -0.98953 0.47376 3.0 -0.98953 -0.47376 3.0 0.98953 -0.47376 3.0 0.98953 0.47376 -3.0 -0.98954 0.47376 -3.0 -0.98953 -0.47376 -3.0 0.98953 -0.47376 -3.0 0.98953 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -0.98953 0.47376 3.0 -0.98953 -0.47376 3.0 0.98953 -0.47376 3.0 0.98953 0.47376 -3.0 -0.98954 0.47376 -3.0 -0.98953 -0.47376 -3.0 0.98953 -0.47376 -3.0 0.98953 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -0.98953 0.47376 3.0 -0.98953 -0.47376 3.0 0.98953 -0.47376 3.0 0.98953 0.47376 -3.0 -0.98954 0.47376 -3.0 -0.98953 -0.47376 -3.0 0.98953 -0.47376 -3.0 0.98953 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.22491 -0.46923 0.2223 0.22491 -0.46923 -0.2223 0.22491 0.46923 -0.2223 0.22491 0.46923 0.2223 -0.22491 -0.46923 0.2223 -0.22491 -0.46923 -0.2223 -0.22491 0.46923 -0.2223 -0.22491 0.46923 0.2223 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.5076 0.17099 0.5076 0.02724 0.81102 0.02724 0.5076 0.17099 0.5076 0.02724 0.81102 0.02724 0.5076 0.17099 0.81102 0.17099 0.81102 0.02724 0.5076 0.17099 0.81102 0.17099 0.81102 0.02724 0.2494 0.17099 0.10396 0.17099 0.10396 0.02724 0.2494 0.17099 0.10396 0.17099 0.10396 0.02724 0.2494 0.48019 0.10396 0.48019 0.10396 0.78361 0.2494 0.48019 0.10396 0.48019 0.10396 0.78361 0.2494 0.67389 0.10396 0.67389 0.10396 0.81764 0.2494 0.67389 0.10396 0.67389 0.10396 0.81764 0.7506 0.48019 0.89604 0.48019 0.89604 0.78361 0.7506 0.48019 0.89604 0.48019 0.89604 0.78361 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.22491 -0.46923 0.2223 0.22491 -0.46923 -0.2223 0.22491 0.46923 -0.2223 0.22491 0.46923 0.2223 -0.22491 -0.46923 0.2223 -0.22491 -0.46923 -0.2223 -0.22491 0.46923 -0.2223 -0.22491 0.46923 0.2223 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.22491 -0.46923 0.2223 0.22491 -0.46923 -0.2223 0.22491 0.46923 -0.2223 0.22491 0.46923 0.2223 -0.22491 -0.46923 0.2223 -0.22491 -0.46923 -0.2223 -0.22491 0.46923 -0.2223 -0.22491 0.46923 0.2223 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.22491 -0.46923 0.2223 0.22491 -0.46923 -0.2223 0.22491 0.46923 -0.2223 0.22491 0.46923 0.2223 -0.22491 -0.46923 0.2223 -0.22491 -0.46923 -0.2223 -0.22491 0.46923 -0.2223 -0.22491 0.46923 0.2223 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.22491 -0.46923 0.2223 0.22491 -0.46923 -0.2223 0.22491 0.46923 -0.2223 0.22491 0.46923 0.2223 -0.22491 -0.46923 0.2223 -0.22491 -0.46923 -0.2223 -0.22491 0.46923 -0.2223 -0.22491 0.46923 0.2223 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.47933 -1.0 0.47376 0.47933 -1.0 -0.47376 0.47933 1.0 -0.47376 0.47933 1.0 0.47376 -0.47933 -1.0 0.47376 -0.47933 -1.0 -0.47376 -0.47933 1.0 -0.47376 -0.47933 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 1.0 1.0 -1.0 1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 1.0 -1.0 1.0 1.0 1.0 1.0 -1.0 1.0 -1.0 -1.0 1.0 -1.0 1.0 1.0 + + + + + + + + + + 0.57735 0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.47933 -1.0 0.47376 0.47933 -1.0 -0.47376 0.47933 1.0 -0.47376 0.47933 1.0 0.47376 -0.47933 -1.0 0.47376 -0.47933 -1.0 -0.47376 -0.47933 1.0 -0.47376 -0.47933 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.47933 -1.0 0.47376 0.47933 -1.0 -0.47376 0.47933 1.0 -0.47376 0.47933 1.0 0.47376 -0.47933 -1.0 0.47376 -0.47933 -1.0 -0.47376 -0.47933 1.0 -0.47376 -0.47933 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.47933 -1.0 0.47376 0.47933 -1.0 -0.47376 0.47933 1.0 -0.47376 0.47933 1.0 0.47376 -0.47933 -1.0 0.47376 -0.47933 -1.0 -0.47376 -0.47933 1.0 -0.47376 -0.47933 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 0.47933 -1.0 0.47376 0.47933 -1.0 -0.47376 0.47933 1.0 -0.47376 0.47933 1.0 0.47376 -0.47933 -1.0 0.47376 -0.47933 -1.0 -0.47376 -0.47933 1.0 -0.47376 -0.47933 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 1.0 3.0 0.5 1.0 3.0 -0.5 -1.0 3.0 -0.5 -1.0 3.0 0.5 1.0 -3.0 0.5 1.0 -3.0 -0.5 -1.0 -3.0 -0.5 -1.0 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 0.5 -0.49 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 0.5 0.01 -0.5 0.01 -0.5 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.5 0.0 0.5 -3.0 -0.5 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.5 0.0 0.5 3.0 -0.5 3.0 0.5 0.0 0.5 3.0 -0.5 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.97962 3.0 0.5 0.97962 3.0 -0.5 -0.97962 3.0 -0.5 -0.97962 3.0 0.5 0.97962 -3.0 0.5 0.97962 -3.0 -0.5 -0.97962 -3.0 -0.5 -0.97962 -3.0 0.5 + + + + + + + + + + 0.57735 0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 + + + + + + + + + + 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 0.48981 -0.49 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 0.48981 0.01 -0.48981 0.01 -0.48981 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 1.0 0.01 -2.0 0.01 -2.0 -0.49 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.48981 0.0 0.48981 -3.0 -0.48981 -3.0 0.0 0.51 -3.0 0.51 -3.0 1.01 0.0 0.51 -3.0 0.51 -3.0 1.01 0.48981 0.0 0.48981 3.0 -0.48981 3.0 0.48981 0.0 0.48981 3.0 -0.48981 3.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 0.47933 -1.0 0.47376 0.47933 -1.0 -0.47376 0.47933 1.0 -0.47376 0.47933 1.0 0.47376 -0.47933 -1.0 0.47376 -0.47933 -1.0 -0.47376 -0.47933 1.0 -0.47376 -0.47933 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + + + + + +

    0 1 2 2 3 0 4 7 6 6 5 4 0 4 5 5 1 0 1 5 6 6 2 1 2 6 7 7 3 2 4 0 3 3 7 4

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -1.0 0.47376 3.0 -1.0 -0.47376 3.0 1.0 -0.47376 3.0 1.0 0.47376 -3.0 -1.0 0.47376 -3.0 -1.0 -0.47376 -3.0 1.0 -0.47376 -3.0 1.0 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 0.49688 0.0 0.02312 1.0 0.02312 0.0 0.49688 0.0 0.02312 1.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 1.0 0.49688 2.0 0.49688 2.0 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.49688 -2.5 0.49688 -2.5 0.02312 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.0 -2.5 0.0 -2.5 1.0 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 0.02312 -2.5 0.02312 -2.5 0.49688 0.5 1.0 3.5 1.0 3.5 2.0 0.5 1.0 3.5 1.0 3.5 2.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 3.0 -0.98953 0.47376 3.0 -0.98953 -0.47376 3.0 0.98953 -0.47376 3.0 0.98953 0.47376 -3.0 -0.98954 0.47376 -3.0 -0.98953 -0.47376 -3.0 0.98953 -0.47376 -3.0 0.98953 0.47376 + + + + + + + + + + 0.57735 -0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 + + + + + + + + + + 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 + + + + + + + + + + + + + + +

    0 0 1 1 2 2 2 3 3 4 0 5 4 6 7 7 6 8 6 9 5 10 4 11 0 12 4 13 5 14 5 15 1 16 0 17 1 18 5 19 6 20 6 21 2 22 1 23 2 24 6 25 7 26 7 27 3 28 2 29 4 30 0 31 3 32 3 33 7 34 4 35

    +
    +
    +
    + + + + 15.68421 15.68421 0.0 15.68421 -15.68421 0.0 -15.68421 -15.68421 0.0 -15.6842 15.68421 0.0 0.0 15.68421 0.0 -15.68421 0.0 0.0 0.0 -15.68421 0.0 15.68421 -0.0 0.0 0.0 -0.0 0.0 7.84211 15.68421 0.0 -7.8421 15.68421 0.0 -15.68421 -7.8421 0.0 -15.68421 7.84211 0.0 7.84211 -15.68421 0.0 -7.84211 -15.68421 0.0 15.68421 7.8421 0.0 15.68421 -7.84211 0.0 -7.8421 0.0 0.0 0.0 7.8421 0.0 7.84211 -0.0 0.0 0.0 -7.84211 0.0 -7.8421 7.84211 0.0 7.84211 7.8421 0.0 -7.8421 -7.84211 0.0 7.84211 -7.84211 0.0 + + + + + + + + + + 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 + + + + + + + + + + + + + + +

    10 3 12 12 21 10 4 10 21 21 18 4 21 12 5 5 17 21 18 21 17 17 8 18 9 4 18 18 22 9 0 9 22 22 15 0 22 18 8 8 19 22 15 22 19 19 7 15 17 5 11 11 23 17 8 17 23 23 20 8 23 11 2 2 14 23 20 23 14 14 6 20 19 8 20 20 24 19 7 19 24 24 16 7 24 20 6 6 13 24 16 24 13 13 1 16

    +
    +
    +
    + + + + d:/bullet_logo.JPG + + + + + + + 1.0 1.0 0.71397 + 0.0 + 0.0 + 0.0 + + + + + + + + + + + + + + + + + + + + + + -14.55524 -12.21748 -0.85392 + 0.0 0.0 1.0 -0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 90.0 + + + + + + + + -14.51144 -12.21746 1.49207 + 0.0 0.0 1.0 -0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 90.0 + 0.59992 0.59992 0.59992 + + + + + + + + -10.54595 9.00056 -7.95634 + 0.0 0.0 1.0 161.23931 + 0.0 1.0 0.0 7.87085 + 1.0 0.0 0.0 -1.43785 + + + + + + + + + + -11.51412 -12.21752 -6.47685 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 -40.16574 + 1.0 0.0 0.0 89.99999 + + + + + + + + + + -10.80608 -12.21753 -8.20963 + 0.0 0.0 1.0 179.99999 + 0.0 1.0 0.0 -68.68968 + 1.0 0.0 0.0 -90.0 + + + + + + + + + + -12.13872 -12.21753 -8.73677 + 0.0 0.0 1.0 -0.0 + 0.0 1.0 0.0 61.88929 + 1.0 0.0 0.0 89.99999 + + + + + + + + + + -11.09567 -3.46707 -5.6227 + 0.0 0.0 1.0 13.53526 + 0.0 1.0 0.0 -3.36769 + 1.0 0.0 0.0 31.10502 + + + + + + + + + + -5.6758 9.44806 -7.98855 + 0.0 0.0 1.0 90.0 + 0.0 1.0 0.0 -30.45178 + 1.0 0.0 0.0 90.0 + + + + 5.76483 -5.12569 1.3994 + 0.0 0.0 1.0 -5.78135 + 0.0 1.0 0.0 8.39643 + 1.0 0.0 0.0 -226.35694 + + + + + + + + + + -4.6651 -3.31256 -8.47664 + 0.0 0.0 1.0 165.33786 + 0.0 1.0 0.0 -9.4701 + 1.0 0.0 0.0 164.1133 + + + + + + + + + + 12.0373 6.52345 -7.84086 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 -36.81686 + + + + + + + + + + 10.69918 0.32979 -8.69131 + 0.0 0.0 1.0 -38.06934 + 0.0 1.0 0.0 0.0 + 1.0 0.0 0.0 0.0 + + + + + + + + + + 10.6716 0.3339 -6.5472 + 0.0 0.0 1.0 -38.06934 + 0.0 1.0 0.0 0.0 + 1.0 0.0 0.0 0.0 + + + + + + + + + + 10.64675 0.37131 -4.4428 + 0.0 0.0 1.0 -38.06934 + 0.0 1.0 0.0 0.0 + 1.0 0.0 0.0 0.0 + + + + + + + + + + 13.39988 -6.62079 -7.48373 + 0.0 0.0 1.0 -23.42368 + 0.0 1.0 0.0 -47.70962 + 1.0 0.0 0.0 14.68375 + + + + + + + + + + 1.07068 1.0946 -9.17122 + + + + + + + + + + 3.07068 1.0946 -9.17122 + + + + + + + + + + -0.92932 1.0946 -9.17122 + + + + + + + + + + -0.92932 1.0946 -7.17122 + + + + + + + + + + 3.07068 1.0946 -7.17122 + + + + + + + + + + 1.07068 1.0946 -7.17122 + + + + + + + + + + 1.07068 3.0946 -8.17122 + + + + + + + + + + 1.07068 -0.9054 -8.17122 + + + + + + + + + + 1.07068 1.0946 -8.17122 + + + + + + + + + + 1.07068 1.0946 -6.17122 + + + + + + + + + + 1.07068 -0.9054 -6.17122 + + + + + + + + + + 1.07068 3.0946 -6.17122 + + + + + + + + + + 1.07068 1.0946 -5.17122 + + + + + + + + + + 3.07068 1.0946 -5.17122 + + + + + + + + + + -0.92932 1.0946 -5.17122 + + + + + + + + + + -0.92932 1.0946 -3.17122 + + + + + + + + + + 3.07068 1.0946 -3.17122 + + + + + + + + + + 1.07068 1.0946 -3.17122 + + + + + + + + + + 1.07068 3.0946 -4.17122 + + + + + + + + + + 1.07068 -0.9054 -4.17122 + + + + + + + + + + 1.07068 1.0946 -4.17122 + + + + + + + + + + 1.07068 1.0946 -2.17122 + + + + + + + + + + 1.07068 -0.9054 -2.17122 + + + + + + + + + + 1.07068 3.0946 -2.17122 + + + + + + + + + + 1.07068 1.0946 -1.17122 + + + + + + + + + + 3.07068 1.0946 -1.17122 + + + + + + + + + + -0.92932 1.0946 -1.17122 + + + + + + + + + + -0.92932 1.0946 0.82878 + + + + + + + + + + 3.07068 1.0946 0.82878 + + + + + + + + + + 1.07068 1.0946 0.82878 + + + + + + + + + + 1.07068 3.0946 -0.17122 + + + + + + + + + + 1.07068 -0.9054 -0.17122 + + + + + + + + + + 1.07068 1.0946 -0.17122 + + + + + + + + + + 1.07068 1.0946 1.82878 + + + + + + + + + + 1.07068 -0.9054 1.82878 + + + + + + + + + + 1.07068 3.0946 1.82878 + + + + + + + + + + 1.07068 1.0946 2.82878 + + + + + + + + + + 3.07068 1.0946 2.82878 + + + + + + + + + + -0.92932 1.0946 2.82878 + + + + + + + + + + 1.07068 -12.41267 -2.84635 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 -146.99812 + + + + + + + + + + 1.07068 -12.65713 -3.97696 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 -146.99812 + + + + + + + + + + 1.07068 -12.93214 -4.92423 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 -146.99812 + + + + + + + + + + 1.07068 -15.19337 -5.0159 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 -146.99812 + + + + + + + + + + 1.07068 -13.57384 -7.5827 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 -0.0 + 1.0 0.0 0.0 -146.99812 + + + + + + + + + + 0.62583 12.00328 -8.00472 + 0.0 0.0 1.0 3.21265 + 0.0 1.0 0.0 -12.03335 + 1.0 0.0 0.0 66.50218 + + + + + + + + + + 1.28844 9.15244 -3.68906 + + + + 1.07068 -7.9054 -7.17122 + + + + + + + + + + 1.07068 -8.9054 -8.17122 + + + + + + + + + + 1.07068 -6.9054 -8.17122 + + + + + + + + + + 1.07068 -7.9054 -9.17122 + + + + + + + + + + -6.69969 -10.22419 -7.75589 + 0.0 0.0 1.0 -0.18482 + 0.0 1.0 0.0 -14.9718 + 1.0 0.0 0.0 -1.78118 + + + + + + + + + + 3.07068 1.0946 4.82878 + + + + + + + + + + 1.07068 1.0946 4.82878 + + + + + + + + + + 1.07068 -5.9054 -9.17122 + + + + + + + + + + 1.07068 3.0946 3.82878 + + + + + + + + + + 1.07068 -0.9054 3.82878 + + + + + + + + + + 1.07068 1.0946 3.82878 + + + + + + + + + + 0.31712 0.02145 -9.78565 + + + + + + + + + + 9.62214 -5.88949 -0.13709 + 0.0 0.0 1.0 106.93632 + 0.0 1.0 0.0 3.16371 + 1.0 0.0 0.0 37.26105 + + + + -7.40201 -33.19793 -3.19828 + 0.0 0.0 1.0 0.0 + 0.0 1.0 0.0 0.0 + 1.0 0.0 0.0 90.0 + + + + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + + + + + + + 2.358 0.3455 0.0 + + + false + 1.0 + + + + + + + + + + 7.3295 1.456 0.0 + + + false + 1.0 + + + + + + + + + + 1.0 + 1.0 + 0 0 + 1.0 + + + true + 1.0 + + + + + + + + + + + true + 1.0 + + + + + + + + + + + true + 1.0 + + + + + + + + + + + true + 1.0 + + + + + + + + + + 1.4 + + + true + 1.0 + + + + + + + + + + 1.0 1.0 1.0 + + + true + 1.0 + + + + + + + + + + 1.0 + 1.0 + 0 0 + 0.42013 + + + true + 1.0 + + + + + + + + + + 1.0 + 1.0 + 0 0 + 1.0 + + + true + 1.0 + + + + + + + + + + 1.0 + 1.0 + 1.0 + + + true + 1.0 + + + + + + + + + + 1.0 + 1.0 + 1.0 + + + true + 1.0 + + + + + + + + + + 1.0 + 1.0 + 1.0 + + + true + 1.0 + + + + + + + + + + 1.0 + 1.0 + 1.0 + + + true + 1.0 + + + + + + + + + + 1.0 + 1.0 + 1.0 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 0.98954 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 0.98954 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 0.98954 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 0.98954 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 0.98954 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 0.98954 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 0.22491 0.46923 0.2223 + + + true + 1.0 + + + + + + + + + + 0.22491 0.46923 0.2223 + + + true + 1.0 + + + + + + + + + + 0.22491 0.46923 0.2223 + + + true + 1.0 + + + + + + + + + + 0.22491 0.46923 0.2223 + + + true + 1.0 + + + + + + + + + + 0.22491 0.46923 0.2223 + + + true + 1.0 + + + + + + + + + + 0.47933 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 1.0 1.0 1.0 + + + false + 1.0 + + + + + + + + + + 0.47933 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 0.47933 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 0.47933 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 0.47933 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 1.0 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 0.97962 3.0 0.5 + + + true + 1.0 + + + + + + + + + + 0.47933 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 1.0 0.47376 + + + true + 1.0 + + + + + + + + + + 3.0 0.98954 0.47376 + + + true + 1.0 + + + + + + + + + + + false + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 0 -9.810000 + 0.0166666 + + + + + + + + diff --git a/lib/readme.txt b/lib/readme.txt new file mode 100644 index 0000000..b384ca2 --- /dev/null +++ b/lib/readme.txt @@ -0,0 +1,13 @@ +At the moment there are no binary packages from Bullet library. +Once this is done, the libraries will be placed here + +LinearMath +BulletCollision +BulletDynamics + +The C-API will be available in the include folder. + +For now, there is only C++ files, see src/btBulletCollisionCommon.h and src/btBulletDynamicsCommon.h + +http://bullet.googlecode.com +Erwin Coumans diff --git a/ltmain.sh b/ltmain.sh new file mode 100755 index 0000000..3061e3c --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,9636 @@ + +# libtool (GNU libtool) 2.4 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4 +TIMESTAMP="" +package_revision=1.3293 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${EGREP="grep -E"} +: ${FGREP="grep -F"} +: ${GREP="grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' + + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_apped perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/missing b/missing new file mode 100755 index 0000000..28055d2 --- /dev/null +++ b/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/Bullet-C-Api.h b/src/Bullet-C-Api.h new file mode 100644 index 0000000..f27a17d --- /dev/null +++ b/src/Bullet-C-Api.h @@ -0,0 +1,176 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h" +*/ + +#ifndef BULLET_C_API_H +#define BULLET_C_API_H + +#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name + +#ifdef BT_USE_DOUBLE_PRECISION +typedef double plReal; +#else +typedef float plReal; +#endif + +typedef plReal plVector3[3]; +typedef plReal plQuaternion[4]; + +#ifdef __cplusplus +extern "C" { +#endif + +/** Particular physics SDK (C-API) */ + PL_DECLARE_HANDLE(plPhysicsSdkHandle); + +/** Dynamics world, belonging to some physics SDK (C-API)*/ + PL_DECLARE_HANDLE(plDynamicsWorldHandle); + +/** Rigid Body that can be part of a Dynamics World (C-API)*/ + PL_DECLARE_HANDLE(plRigidBodyHandle); + +/** Collision Shape/Geometry, property of a Rigid Body (C-API)*/ + PL_DECLARE_HANDLE(plCollisionShapeHandle); + +/** Constraint for Rigid Bodies (C-API)*/ + PL_DECLARE_HANDLE(plConstraintHandle); + +/** Triangle Mesh interface (C-API)*/ + PL_DECLARE_HANDLE(plMeshInterfaceHandle); + +/** Broadphase Scene/Proxy Handles (C-API)*/ + PL_DECLARE_HANDLE(plCollisionBroadphaseHandle); + PL_DECLARE_HANDLE(plBroadphaseProxyHandle); + PL_DECLARE_HANDLE(plCollisionWorldHandle); + +/** + Create and Delete a Physics SDK +*/ + + extern plPhysicsSdkHandle plNewBulletSdk(void); //this could be also another sdk, like ODE, PhysX etc. + extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk); + +/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */ + + typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2); + + extern plCollisionBroadphaseHandle plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback); + + extern void plDestroyBroadphase(plCollisionBroadphaseHandle bp); + + extern plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ); + + extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle); + + extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ); + +/* todo: add pair cache support with queries like add/remove/find pair */ + + extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk); + +/* todo: add/remove objects */ + + +/* Dynamics World */ + + extern plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk); + + extern void plDeleteDynamicsWorld(plDynamicsWorldHandle world); + + extern void plStepSimulation(plDynamicsWorldHandle, plReal timeStep); + + extern void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object); + + extern void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object); + + +/* Rigid Body */ + + extern plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape ); + + extern void plDeleteRigidBody(plRigidBodyHandle body); + + +/* Collision Shape definition */ + + extern plCollisionShapeHandle plNewSphereShape(plReal radius); + extern plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z); + extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height); + extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height); + extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height); + extern plCollisionShapeHandle plNewCompoundShape(void); + extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn); + + extern void plDeleteShape(plCollisionShapeHandle shape); + + /* Convex Meshes */ + extern plCollisionShapeHandle plNewConvexHullShape(void); + extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z); +/* Concave static triangle meshes */ + extern plMeshInterfaceHandle plNewMeshInterface(void); + extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2); + extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle); + + extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling); + +/* SOLID has Response Callback/Table/Management */ +/* PhysX has Triggers, User Callbacks and filtering */ +/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */ + +/* typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle rbHandle, plVector3 pos); */ +/* typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle rbHandle, plQuaternion orientation); */ + + /* get world transform */ + extern void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix); + extern void plGetPosition(plRigidBodyHandle object,plVector3 position); + extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation); + + /* set world transform (position/orientation) */ + extern void plSetPosition(plRigidBodyHandle object, const plVector3 position); + extern void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation); + extern void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient); + extern void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix); + + typedef struct plRayCastResult { + plRigidBodyHandle m_body; + plCollisionShapeHandle m_shape; + plVector3 m_positionWorld; + plVector3 m_normalWorld; + } plRayCastResult; + + extern int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res); + + /* Sweep API */ + + /* extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */ + + /* Continuous Collision Detection API */ + + // needed for source/blender/blenkernel/intern/collision.c + double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]); + +#ifdef __cplusplus +} +#endif + + +#endif //BULLET_C_API_H + diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp new file mode 100644 index 0000000..7776330 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp @@ -0,0 +1,37 @@ + +//Bullet Continuous Collision Detection and Physics Library +//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + + +// +// btAxisSweep3 +// +// Copyright (c) 2006 Simon Hobbs +// +// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +#include "btAxisSweep3.h" + + +btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator) +:btAxisSweep3Internal(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator) +{ + // 1 handle is reserved as sentinel + btAssert(maxHandles > 1 && maxHandles < 32767); + +} + + +bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator) +:btAxisSweep3Internal(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator) +{ + // 1 handle is reserved as sentinel + btAssert(maxHandles > 1 && maxHandles < 2147483647); +} diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h new file mode 100644 index 0000000..cd6e1a8 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h @@ -0,0 +1,1051 @@ +//Bullet Continuous Collision Detection and Physics Library +//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +// +// btAxisSweep3.h +// +// Copyright (c) 2006 Simon Hobbs +// +// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. + +#ifndef BT_AXIS_SWEEP_3_H +#define BT_AXIS_SWEEP_3_H + +#include "LinearMath/btVector3.h" +#include "btOverlappingPairCache.h" +#include "btBroadphaseInterface.h" +#include "btBroadphaseProxy.h" +#include "btOverlappingPairCallback.h" +#include "btDbvtBroadphase.h" + +//#define DEBUG_BROADPHASE 1 +#define USE_OVERLAP_TEST_ON_REMOVES 1 + +/// The internal templace class btAxisSweep3Internal implements the sweep and prune broadphase. +/// It uses quantized integers to represent the begin and end points for each of the 3 axis. +/// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead. +template +class btAxisSweep3Internal : public btBroadphaseInterface +{ +protected: + + BP_FP_INT_TYPE m_bpHandleMask; + BP_FP_INT_TYPE m_handleSentinel; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + class Edge + { + public: + BP_FP_INT_TYPE m_pos; // low bit is min/max + BP_FP_INT_TYPE m_handle; + + BP_FP_INT_TYPE IsMax() const {return static_cast(m_pos & 1);} + }; + +public: + class Handle : public btBroadphaseProxy + { + public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + // indexes into the edge arrays + BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 +// BP_FP_INT_TYPE m_uniqueId; + btBroadphaseProxy* m_dbvtProxy;//for faster raycast + //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject + + SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;} + SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];} + }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry + + +protected: + btVector3 m_worldAabbMin; // overall system bounds + btVector3 m_worldAabbMax; // overall system bounds + + btVector3 m_quantize; // scaling factor for quantization + + BP_FP_INT_TYPE m_numHandles; // number of active handles + BP_FP_INT_TYPE m_maxHandles; // max number of handles + Handle* m_pHandles; // handles pool + + BP_FP_INT_TYPE m_firstFreeHandle; // free handles list + + Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) + void* m_pEdgesRawPtr[3]; + + btOverlappingPairCache* m_pairCache; + + ///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache. + btOverlappingPairCallback* m_userPairCallback; + + bool m_ownsPairCache; + + int m_invalidPair; + + ///additional dynamic aabb structure, used to accelerate ray cast queries. + ///can be disabled using a optional argument in the constructor + btDbvtBroadphase* m_raycastAccelerator; + btOverlappingPairCache* m_nullPairCache; + + + // allocation/deallocation + BP_FP_INT_TYPE allocHandle(); + void freeHandle(BP_FP_INT_TYPE handle); + + + bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1); + +#ifdef DEBUG_BROADPHASE + void debugPrintAxis(int axis,bool checkCardinality=true); +#endif //DEBUG_BROADPHASE + + //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); + //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); + + + + void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + +public: + + btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false); + + virtual ~btAxisSweep3Internal(); + + BP_FP_INT_TYPE getNumHandles() const + { + return m_numHandles; + } + + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + + BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); + void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher); + void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); + SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} + + virtual void resetPool(btDispatcher* dispatcher); + + void processAllOverlappingPairs(btOverlapCallback* callback); + + //Broadphase Interface + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); + virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; + + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)); + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); + + + void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const; + ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result + void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; + + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + btOverlappingPairCache* getOverlappingPairCache() + { + return m_pairCache; + } + const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_pairCache; + } + + void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback) + { + m_userPairCallback = pairCallback; + } + const btOverlappingPairCallback* getOverlappingPairUserCallback() const + { + return m_userPairCallback; + } + + ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame + ///will add some transform later + virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const + { + aabbMin = m_worldAabbMin; + aabbMax = m_worldAabbMax; + } + + virtual void printStats() + { +/* printf("btAxisSweep3.h\n"); + printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles); + printf("aabbMin=%f,%f,%f,aabbMax=%f,%f,%f\n",m_worldAabbMin.getX(),m_worldAabbMin.getY(),m_worldAabbMin.getZ(), + m_worldAabbMax.getX(),m_worldAabbMax.getY(),m_worldAabbMax.getZ()); + */ + + } + +}; + +//////////////////////////////////////////////////////////////////// + + + + +#ifdef DEBUG_BROADPHASE +#include + +template +void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality) +{ + int numEdges = m_pHandles[0].m_maxEdges[axis]; + printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); + + int i; + for (i=0;im_handle); + int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; + char beginOrEnd; + beginOrEnd=pEdge->IsMax()?'E':'B'; + printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); + } + + if (checkCardinality) + btAssert(numEdges == m_numHandles*2+1); +} +#endif //DEBUG_BROADPHASE + +template +btBroadphaseProxy* btAxisSweep3Internal::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy) +{ + (void)shapeType; + BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy); + + Handle* handle = getHandle(handleId); + + if (m_raycastAccelerator) + { + btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0); + handle->m_dbvtProxy = rayProxy; + } + return handle; +} + + + +template +void btAxisSweep3Internal::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + Handle* handle = static_cast(proxy); + if (m_raycastAccelerator) + m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher); + removeHandle(static_cast(handle->m_uniqueId), dispatcher); +} + +template +void btAxisSweep3Internal::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) +{ + Handle* handle = static_cast(proxy); + handle->m_aabbMin = aabbMin; + handle->m_aabbMax = aabbMax; + updateHandle(static_cast(handle->m_uniqueId), aabbMin, aabbMax,dispatcher); + if (m_raycastAccelerator) + m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher); + +} + +template +void btAxisSweep3Internal::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) +{ + if (m_raycastAccelerator) + { + m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax); + } else + { + //choose axis? + BP_FP_INT_TYPE axis = 0; + //for each proxy + for (BP_FP_INT_TYPE i=1;i +void btAxisSweep3Internal::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) +{ + if (m_raycastAccelerator) + { + m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback); + } else + { + //choose axis? + BP_FP_INT_TYPE axis = 0; + //for each proxy + for (BP_FP_INT_TYPE i=1;im_aabbMin,handle->m_aabbMax)) + { + callback.process(handle); + } + } + } + } +} + + + +template +void btAxisSweep3Internal::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +{ + Handle* pHandle = static_cast(proxy); + aabbMin = pHandle->m_aabbMin; + aabbMax = pHandle->m_aabbMax; +} + + +template +void btAxisSweep3Internal::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +{ + Handle* pHandle = static_cast(proxy); + + unsigned short vecInMin[3]; + unsigned short vecInMax[3]; + + vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ; + vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ; + vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ; + vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ; + vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ; + vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ; + + aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ())); + aabbMin += m_worldAabbMin; + + aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ())); + aabbMax += m_worldAabbMin; +} + + + + +template +btAxisSweep3Internal::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator) +:m_bpHandleMask(handleMask), +m_handleSentinel(handleSentinel), +m_pairCache(pairCache), +m_userPairCallback(0), +m_ownsPairCache(false), +m_invalidPair(0), +m_raycastAccelerator(0) +{ + BP_FP_INT_TYPE maxHandles = static_cast(userMaxHandles+1);//need to add one sentinel handle + + if (!m_pairCache) + { + void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16); + m_pairCache = new(ptr) btHashedOverlappingPairCache(); + m_ownsPairCache = true; + } + + if (!disableRaycastAccelerator) + { + m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache(); + m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache); + m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs + } + + //btAssert(bounds.HasVolume()); + + // init bounds + m_worldAabbMin = worldAabbMin; + m_worldAabbMax = worldAabbMax; + + btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; + + BP_FP_INT_TYPE maxInt = m_handleSentinel; + + m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; + + // allocate handles buffer, using btAlignedAlloc, and put all handles on free list + m_pHandles = new Handle[maxHandles]; + + m_maxHandles = maxHandles; + m_numHandles = 0; + + // handle 0 is reserved as the null index, and is also used as the sentinel + m_firstFreeHandle = 1; + { + for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++) + m_pHandles[i].SetNextFree(static_cast(i + 1)); + m_pHandles[maxHandles - 1].SetNextFree(0); + } + + { + // allocate edge buffers + for (int i = 0; i < 3; i++) + { + m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16); + m_pEdges[i] = new(m_pEdgesRawPtr[i]) Edge[maxHandles * 2]; + } + } + //removed overlap management + + // make boundary sentinels + + m_pHandles[0].m_clientObject = 0; + + for (int axis = 0; axis < 3; axis++) + { + m_pHandles[0].m_minEdges[axis] = 0; + m_pHandles[0].m_maxEdges[axis] = 1; + + m_pEdges[axis][0].m_pos = 0; + m_pEdges[axis][0].m_handle = 0; + m_pEdges[axis][1].m_pos = m_handleSentinel; + m_pEdges[axis][1].m_handle = 0; +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + + } + +} + +template +btAxisSweep3Internal::~btAxisSweep3Internal() +{ + if (m_raycastAccelerator) + { + m_nullPairCache->~btOverlappingPairCache(); + btAlignedFree(m_nullPairCache); + m_raycastAccelerator->~btDbvtBroadphase(); + btAlignedFree (m_raycastAccelerator); + } + + for (int i = 2; i >= 0; i--) + { + btAlignedFree(m_pEdgesRawPtr[i]); + } + delete [] m_pHandles; + + if (m_ownsPairCache) + { + m_pairCache->~btOverlappingPairCache(); + btAlignedFree(m_pairCache); + } +} + +template +void btAxisSweep3Internal::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const +{ +#ifdef OLD_CLAMPING_METHOD + ///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax] + ///see http://code.google.com/p/bullet/issues/detail?id=87 + btVector3 clampedPoint(point); + clampedPoint.setMax(m_worldAabbMin); + clampedPoint.setMin(m_worldAabbMax); + btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize; + out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax); + out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax); + out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax); +#else + btVector3 v = (point - m_worldAabbMin) * m_quantize; + out[0]=(v[0]<=0)?(BP_FP_INT_TYPE)isMax:(v[0]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0]&m_bpHandleMask)|isMax); + out[1]=(v[1]<=0)?(BP_FP_INT_TYPE)isMax:(v[1]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1]&m_bpHandleMask)|isMax); + out[2]=(v[2]<=0)?(BP_FP_INT_TYPE)isMax:(v[2]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2]&m_bpHandleMask)|isMax); +#endif //OLD_CLAMPING_METHOD +} + + +template +BP_FP_INT_TYPE btAxisSweep3Internal::allocHandle() +{ + btAssert(m_firstFreeHandle); + + BP_FP_INT_TYPE handle = m_firstFreeHandle; + m_firstFreeHandle = getHandle(handle)->GetNextFree(); + m_numHandles++; + + return handle; +} + +template +void btAxisSweep3Internal::freeHandle(BP_FP_INT_TYPE handle) +{ + btAssert(handle > 0 && handle < m_maxHandles); + + getHandle(handle)->SetNextFree(m_firstFreeHandle); + m_firstFreeHandle = handle; + + m_numHandles--; +} + + +template +BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy) +{ + // quantize the bounds + BP_FP_INT_TYPE min[3], max[3]; + quantize(min, aabbMin, 0); + quantize(max, aabbMax, 1); + + // allocate a handle + BP_FP_INT_TYPE handle = allocHandle(); + + + Handle* pHandle = getHandle(handle); + + pHandle->m_uniqueId = static_cast(handle); + //pHandle->m_pOverlaps = 0; + pHandle->m_clientObject = pOwner; + pHandle->m_collisionFilterGroup = collisionFilterGroup; + pHandle->m_collisionFilterMask = collisionFilterMask; + pHandle->m_multiSapParentProxy = multiSapProxy; + + // compute current limit of edge arrays + BP_FP_INT_TYPE limit = static_cast(m_numHandles * 2); + + + // insert new edges just inside the max boundary edge + for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) + { + + m_pHandles[0].m_maxEdges[axis] += 2; + + m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; + + m_pEdges[axis][limit - 1].m_pos = min[axis]; + m_pEdges[axis][limit - 1].m_handle = handle; + + m_pEdges[axis][limit].m_pos = max[axis]; + m_pEdges[axis][limit].m_handle = handle; + + pHandle->m_minEdges[axis] = static_cast(limit - 1); + pHandle->m_maxEdges[axis] = limit; + } + + // now sort the new edges to their correct position + sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false); + sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false); + sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false); + sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false); + sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true); + sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true); + + + return handle; +} + + +template +void btAxisSweep3Internal::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher) +{ + + Handle* pHandle = getHandle(handle); + + //explicitly remove the pairs containing the proxy + //we could do it also in the sortMinUp (passing true) + ///@todo: compare performance + if (!m_pairCache->hasDeferredRemoval()) + { + m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher); + } + + // compute current limit of edge arrays + int limit = static_cast(m_numHandles * 2); + + int axis; + + for (axis = 0;axis<3;axis++) + { + m_pHandles[0].m_maxEdges[axis] -= 2; + } + + // remove the edges by sorting them up to the end of the list + for ( axis = 0; axis < 3; axis++) + { + Edge* pEdges = m_pEdges[axis]; + BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis]; + pEdges[max].m_pos = m_handleSentinel; + + sortMaxUp(axis,max,dispatcher,false); + + + BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; + pEdges[i].m_pos = m_handleSentinel; + + + sortMinUp(axis,i,dispatcher,false); + + pEdges[limit-1].m_handle = 0; + pEdges[limit-1].m_pos = m_handleSentinel; + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis,false); +#endif //DEBUG_BROADPHASE + + + } + + + // free the handle + freeHandle(handle); + + +} + +template +void btAxisSweep3Internal::resetPool(btDispatcher* /*dispatcher*/) +{ + if (m_numHandles == 0) + { + m_firstFreeHandle = 1; + { + for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++) + m_pHandles[i].SetNextFree(static_cast(i + 1)); + m_pHandles[m_maxHandles - 1].SetNextFree(0); + } + } +} + + +extern int gOverlappingPairs; +//#include + +template +void btAxisSweep3Internal::calculateOverlappingPairs(btDispatcher* dispatcher) +{ + + if (m_pairCache->hasDeferredRemoval()) + { + + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + + + int i; + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;iprocessOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + m_pairCache->cleanOverlappingPair(pair,dispatcher); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } + + ///if you don't like to skip the invalid pairs in the array, execute following code: + #define CLEAN_INVALID_PAIRS 1 + #ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + #endif//CLEAN_INVALID_PAIRS + + //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size()); + } + +} + + +template +bool btAxisSweep3Internal::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + const Handle* pHandleA = static_cast(proxy0); + const Handle* pHandleB = static_cast(proxy1); + + //optimization 1: check the array index (memory address), instead of the m_pos + + for (int axis = 0; axis < 3; axis++) + { + if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || + pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) + { + return false; + } + } + return true; +} + +template +bool btAxisSweep3Internal::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1) +{ + //optimization 1: check the array index (memory address), instead of the m_pos + + if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] || + pHandleB->m_maxEdges[axis0] < pHandleA->m_minEdges[axis0] || + pHandleA->m_maxEdges[axis1] < pHandleB->m_minEdges[axis1] || + pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1]) + { + return false; + } + return true; +} + +template +void btAxisSweep3Internal::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) +{ +// btAssert(bounds.IsFinite()); + //btAssert(bounds.HasVolume()); + + Handle* pHandle = getHandle(handle); + + // quantize the new bounds + BP_FP_INT_TYPE min[3], max[3]; + quantize(min, aabbMin, 0); + quantize(max, aabbMax, 1); + + // update changed edges + for (int axis = 0; axis < 3; axis++) + { + BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis]; + BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis]; + + int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos; + int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos; + + m_pEdges[axis][emin].m_pos = min[axis]; + m_pEdges[axis][emax].m_pos = max[axis]; + + // expand (only adds overlaps) + if (dmin < 0) + sortMinDown(axis, emin,dispatcher,true); + + if (dmax > 0) + sortMaxUp(axis, emax,dispatcher,true); + + // shrink (only removes overlaps) + if (dmin > 0) + sortMinUp(axis, emin,dispatcher,true); + + if (dmax < 0) + sortMaxDown(axis, emax,dispatcher,true); + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + } + + +} + + + + +// sorting a min edge downwards can only ever *add* overlaps +template +void btAxisSweep3Internal::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps) +{ + + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pPrev = pEdge - 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pEdge->m_pos < pPrev->m_pos) + { + Handle* pHandlePrev = getHandle(pPrev->m_handle); + + if (pPrev->IsMax()) + { + // if previous edge is a maximum check the bounds and add an overlap if necessary + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; + if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev,axis1,axis2)) + { + m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev); + if (m_userPairCallback) + m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev); + + //AddOverlap(pEdge->m_handle, pPrev->m_handle); + + } + + // update edge reference in other handle + pHandlePrev->m_maxEdges[axis]++; + } + else + pHandlePrev->m_minEdges[axis]++; + + pHandleEdge->m_minEdges[axis]--; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pPrev; + *pPrev = swap; + + // decrement + pEdge--; + pPrev--; + } + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + +} + +// sorting a min edge upwards can only ever *remove* overlaps +template +void btAxisSweep3Internal::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) +{ + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pNext = pEdge + 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) + { + Handle* pHandleNext = getHandle(pNext->m_handle); + + if (pNext->IsMax()) + { + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pNext->m_handle); + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; + + // if next edge is maximum remove any overlap between the two handles + if (updateOverlaps +#ifdef USE_OVERLAP_TEST_ON_REMOVES + && testOverlap2D(handle0,handle1,axis1,axis2) +#endif //USE_OVERLAP_TEST_ON_REMOVES + ) + { + + + m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); + if (m_userPairCallback) + m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher); + + } + + + // update edge reference in other handle + pHandleNext->m_maxEdges[axis]--; + } + else + pHandleNext->m_minEdges[axis]--; + + pHandleEdge->m_minEdges[axis]++; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pNext; + *pNext = swap; + + // increment + pEdge++; + pNext++; + } + + +} + +// sorting a max edge downwards can only ever *remove* overlaps +template +void btAxisSweep3Internal::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) +{ + + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pPrev = pEdge - 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pEdge->m_pos < pPrev->m_pos) + { + Handle* pHandlePrev = getHandle(pPrev->m_handle); + + if (!pPrev->IsMax()) + { + // if previous edge was a minimum remove any overlap between the two handles + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pPrev->m_handle); + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; + + if (updateOverlaps +#ifdef USE_OVERLAP_TEST_ON_REMOVES + && testOverlap2D(handle0,handle1,axis1,axis2) +#endif //USE_OVERLAP_TEST_ON_REMOVES + ) + { + //this is done during the overlappingpairarray iteration/narrowphase collision + + + m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); + if (m_userPairCallback) + m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher); + + + + } + + // update edge reference in other handle + pHandlePrev->m_minEdges[axis]++;; + } + else + pHandlePrev->m_maxEdges[axis]++; + + pHandleEdge->m_maxEdges[axis]--; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pPrev; + *pPrev = swap; + + // decrement + pEdge--; + pPrev--; + } + + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + +} + +// sorting a max edge upwards can only ever *add* overlaps +template +void btAxisSweep3Internal::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps) +{ + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pNext = pEdge + 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) + { + Handle* pHandleNext = getHandle(pNext->m_handle); + + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; + + if (!pNext->IsMax()) + { + // if next edge is a minimum check the bounds and add an overlap if necessary + if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext,axis1,axis2)) + { + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pNext->m_handle); + m_pairCache->addOverlappingPair(handle0,handle1); + if (m_userPairCallback) + m_userPairCallback->addOverlappingPair(handle0,handle1); + } + + // update edge reference in other handle + pHandleNext->m_minEdges[axis]--; + } + else + pHandleNext->m_maxEdges[axis]--; + + pHandleEdge->m_maxEdges[axis]++; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pNext; + *pNext = swap; + + // increment + pEdge++; + pNext++; + } + +} + + + +//////////////////////////////////////////////////////////////////// + + +/// The btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase. +/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using 16 bit integer coordinates instead of floats. +/// For large worlds and many objects, use bt32BitAxisSweep3 or btDbvtBroadphase instead. bt32BitAxisSweep3 has higher precision and allows more then 16384 objects at the cost of more memory and bit of performance. +class btAxisSweep3 : public btAxisSweep3Internal +{ +public: + + btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); + +}; + +/// The bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSweep3 sweep and prune. +/// This comes at the cost of more memory per handle, and a bit slower performance. +/// It uses arrays rather then lists for storage of the 3 axis. +class bt32BitAxisSweep3 : public btAxisSweep3Internal +{ +public: + + bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); + +}; + +#endif + diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h new file mode 100644 index 0000000..f1bf005 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h @@ -0,0 +1,82 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BROADPHASE_INTERFACE_H +#define BT_BROADPHASE_INTERFACE_H + + + +struct btDispatcherInfo; +class btDispatcher; +#include "btBroadphaseProxy.h" + +class btOverlappingPairCache; + + + +struct btBroadphaseAabbCallback +{ + virtual ~btBroadphaseAabbCallback() {} + virtual bool process(const btBroadphaseProxy* proxy) = 0; +}; + + +struct btBroadphaseRayCallback : public btBroadphaseAabbCallback +{ + ///added some cached data to accelerate ray-AABB tests + btVector3 m_rayDirectionInverse; + unsigned int m_signs[3]; + btScalar m_lambda_max; + + virtual ~btBroadphaseRayCallback() {} +}; + +#include "LinearMath/btVector3.h" + +///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs. +///Some implementations for this broadphase interface include btAxisSweep3, bt32BitAxisSweep3 and btDbvtBroadphase. +///The actual overlapping pair management, storage, adding and removing of pairs is dealt by the btOverlappingPairCache class. +class btBroadphaseInterface +{ +public: + virtual ~btBroadphaseInterface() {} + + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0; + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0; + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0; + virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0; + + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0; + + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) = 0; + + ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb + virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0; + + virtual btOverlappingPairCache* getOverlappingPairCache()=0; + virtual const btOverlappingPairCache* getOverlappingPairCache() const =0; + + ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame + ///will add some transform later + virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0; + + ///reset broadphase internal structures, to ensure determinism/reproducability + virtual void resetPool(btDispatcher* dispatcher) { (void) dispatcher; }; + + virtual void printStats() = 0; + +}; + +#endif //BT_BROADPHASE_INTERFACE_H diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp new file mode 100644 index 0000000..f4d7341 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp @@ -0,0 +1,17 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBroadphaseProxy.h" + diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h new file mode 100644 index 0000000..bb58b82 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -0,0 +1,270 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BROADPHASE_PROXY_H +#define BT_BROADPHASE_PROXY_H + +#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedAllocator.h" + + +/// btDispatcher uses these types +/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave +/// to facilitate type checking +/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code +enum BroadphaseNativeTypes +{ + // polyhedral convex shapes + BOX_SHAPE_PROXYTYPE, + TRIANGLE_SHAPE_PROXYTYPE, + TETRAHEDRAL_SHAPE_PROXYTYPE, + CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE, + CONVEX_HULL_SHAPE_PROXYTYPE, + CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE, + CUSTOM_POLYHEDRAL_SHAPE_TYPE, +//implicit convex shapes +IMPLICIT_CONVEX_SHAPES_START_HERE, + SPHERE_SHAPE_PROXYTYPE, + MULTI_SPHERE_SHAPE_PROXYTYPE, + CAPSULE_SHAPE_PROXYTYPE, + CONE_SHAPE_PROXYTYPE, + CONVEX_SHAPE_PROXYTYPE, + CYLINDER_SHAPE_PROXYTYPE, + UNIFORM_SCALING_SHAPE_PROXYTYPE, + MINKOWSKI_SUM_SHAPE_PROXYTYPE, + MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, + BOX_2D_SHAPE_PROXYTYPE, + CONVEX_2D_SHAPE_PROXYTYPE, + CUSTOM_CONVEX_SHAPE_TYPE, +//concave shapes +CONCAVE_SHAPES_START_HERE, + //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! + TRIANGLE_MESH_SHAPE_PROXYTYPE, + SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE, + ///used for demo integration FAST/Swift collision library and Bullet + FAST_CONCAVE_MESH_PROXYTYPE, + //terrain + TERRAIN_SHAPE_PROXYTYPE, +///Used for GIMPACT Trimesh integration + GIMPACT_SHAPE_PROXYTYPE, +///Multimaterial mesh + MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, + + EMPTY_SHAPE_PROXYTYPE, + STATIC_PLANE_PROXYTYPE, + CUSTOM_CONCAVE_SHAPE_TYPE, +CONCAVE_SHAPES_END_HERE, + + COMPOUND_SHAPE_PROXYTYPE, + + SOFTBODY_SHAPE_PROXYTYPE, + HFFLUID_SHAPE_PROXYTYPE, + HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE, + INVALID_SHAPE_PROXYTYPE, + + MAX_BROADPHASE_COLLISION_TYPES + +}; + + +///The btBroadphaseProxy is the main class that can be used with the Bullet broadphases. +///It stores collision shape type information, collision filter information and a client object, typically a btCollisionObject or btRigidBody. +ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy +{ + +BT_DECLARE_ALIGNED_ALLOCATOR(); + + ///optional filtering to cull potential collisions + enum CollisionFilterGroups + { + DefaultFilter = 1, + StaticFilter = 2, + KinematicFilter = 4, + DebrisFilter = 8, + SensorTrigger = 16, + CharacterFilter = 32, + AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger + }; + + //Usually the client btCollisionObject or Rigidbody class + void* m_clientObject; + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + void* m_multiSapParentProxy; + int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. + + btVector3 m_aabbMin; + btVector3 m_aabbMax; + + SIMD_FORCE_INLINE int getUid() const + { + return m_uniqueId; + } + + //used for memory pools + btBroadphaseProxy() :m_clientObject(0),m_multiSapParentProxy(0) + { + } + + btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0) + :m_clientObject(userPtr), + m_collisionFilterGroup(collisionFilterGroup), + m_collisionFilterMask(collisionFilterMask), + m_aabbMin(aabbMin), + m_aabbMax(aabbMax) + { + m_multiSapParentProxy = multiSapParentProxy; + } + + + + static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType) + { + return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE); + } + + static SIMD_FORCE_INLINE bool isConvex(int proxyType) + { + return (proxyType < CONCAVE_SHAPES_START_HERE); + } + + static SIMD_FORCE_INLINE bool isNonMoving(int proxyType) + { + return (isConcave(proxyType) && !(proxyType==GIMPACT_SHAPE_PROXYTYPE)); + } + + static SIMD_FORCE_INLINE bool isConcave(int proxyType) + { + return ((proxyType > CONCAVE_SHAPES_START_HERE) && + (proxyType < CONCAVE_SHAPES_END_HERE)); + } + static SIMD_FORCE_INLINE bool isCompound(int proxyType) + { + return (proxyType == COMPOUND_SHAPE_PROXYTYPE); + } + + static SIMD_FORCE_INLINE bool isSoftBody(int proxyType) + { + return (proxyType == SOFTBODY_SHAPE_PROXYTYPE); + } + + static SIMD_FORCE_INLINE bool isInfinite(int proxyType) + { + return (proxyType == STATIC_PLANE_PROXYTYPE); + } + + static SIMD_FORCE_INLINE bool isConvex2d(int proxyType) + { + return (proxyType == BOX_2D_SHAPE_PROXYTYPE) || (proxyType == CONVEX_2D_SHAPE_PROXYTYPE); + } + + +} +; + +class btCollisionAlgorithm; + +struct btBroadphaseProxy; + + + +///The btBroadphasePair class contains a pair of aabb-overlapping objects. +///A btDispatcher can search a btCollisionAlgorithm that performs exact/narrowphase collision detection on the actual collision shapes. +ATTRIBUTE_ALIGNED16(struct) btBroadphasePair +{ + btBroadphasePair () + : + m_pProxy0(0), + m_pProxy1(0), + m_algorithm(0), + m_internalInfo1(0) + { + } + +BT_DECLARE_ALIGNED_ALLOCATOR(); + + btBroadphasePair(const btBroadphasePair& other) + : m_pProxy0(other.m_pProxy0), + m_pProxy1(other.m_pProxy1), + m_algorithm(other.m_algorithm), + m_internalInfo1(other.m_internalInfo1) + { + } + btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) + { + + //keep them sorted, so the std::set operations work + if (proxy0.m_uniqueId < proxy1.m_uniqueId) + { + m_pProxy0 = &proxy0; + m_pProxy1 = &proxy1; + } + else + { + m_pProxy0 = &proxy1; + m_pProxy1 = &proxy0; + } + + m_algorithm = 0; + m_internalInfo1 = 0; + + } + + btBroadphaseProxy* m_pProxy0; + btBroadphaseProxy* m_pProxy1; + + mutable btCollisionAlgorithm* m_algorithm; + union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version. + +}; + +/* +//comparison for set operation, see Solid DT_Encounter +SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b) +{ + return a.m_pProxy0 < b.m_pProxy0 || + (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1); +} +*/ + + + +class btBroadphasePairSortPredicate +{ + public: + + bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b ) const + { + const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1; + const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1; + const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1; + const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1; + + return uidA0 > uidB0 || + (a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) || + (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); + } +}; + + +SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b) +{ + return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1); +} + + +#endif //BT_BROADPHASE_PROXY_H + diff --git a/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp new file mode 100644 index 0000000..c95d1be --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp @@ -0,0 +1,23 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btCollisionAlgorithm.h" +#include "btDispatcher.h" + +btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) +{ + m_dispatcher = ci.m_dispatcher1; +} + diff --git a/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h new file mode 100644 index 0000000..4056562 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h @@ -0,0 +1,81 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COLLISION_ALGORITHM_H +#define BT_COLLISION_ALGORITHM_H + +#include "LinearMath/btScalar.h" +#include "LinearMath/btAlignedObjectArray.h" + +struct btBroadphaseProxy; +class btDispatcher; +class btManifoldResult; +class btCollisionObject; +struct btCollisionObjectWrapper; +struct btDispatcherInfo; +class btPersistentManifold; + +typedef btAlignedObjectArray btManifoldArray; + +struct btCollisionAlgorithmConstructionInfo +{ + btCollisionAlgorithmConstructionInfo() + :m_dispatcher1(0), + m_manifold(0) + { + } + btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp) + :m_dispatcher1(dispatcher) + { + (void)temp; + } + + btDispatcher* m_dispatcher1; + btPersistentManifold* m_manifold; + +// int getDispatcherId(); + +}; + + +///btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatcher. +///It is persistent over frames +class btCollisionAlgorithm +{ + +protected: + + btDispatcher* m_dispatcher; + +protected: +// int getDispatcherId(); + +public: + + btCollisionAlgorithm() {}; + + btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); + + virtual ~btCollisionAlgorithm() {}; + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) = 0; +}; + + +#endif //BT_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/BroadphaseCollision/btDbvt.cpp b/src/BulletCollision/BroadphaseCollision/btDbvt.cpp new file mode 100644 index 0000000..95443af --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btDbvt.cpp @@ -0,0 +1,1295 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +///btDbvt implementation by Nathanael Presson + +#include "btDbvt.h" + +// +typedef btAlignedObjectArray tNodeArray; +typedef btAlignedObjectArray tConstNodeArray; + +// +struct btDbvtNodeEnumerator : btDbvt::ICollide +{ + tConstNodeArray nodes; + void Process(const btDbvtNode* n) { nodes.push_back(n); } +}; + +// +static DBVT_INLINE int indexof(const btDbvtNode* node) +{ + return(node->parent->childs[1]==node); +} + +// +static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a, + const btDbvtVolume& b) +{ +#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE) + ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]); + btDbvtVolume& res=*(btDbvtVolume*)locals; +#else + btDbvtVolume res; +#endif + Merge(a,b,res); + return(res); +} + +// volume+edge lengths +static DBVT_INLINE btScalar size(const btDbvtVolume& a) +{ + const btVector3 edges=a.Lengths(); + return( edges.x()*edges.y()*edges.z()+ + edges.x()+edges.y()+edges.z()); +} + +// +static void getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth) +{ + if(node->isinternal()) + { + getmaxdepth(node->childs[0],depth+1,maxdepth); + getmaxdepth(node->childs[1],depth+1,maxdepth); + } else maxdepth=btMax(maxdepth,depth); +} + +// +static DBVT_INLINE void deletenode( btDbvt* pdbvt, + btDbvtNode* node) +{ + btAlignedFree(pdbvt->m_free); + pdbvt->m_free=node; +} + +// +static void recursedeletenode( btDbvt* pdbvt, + btDbvtNode* node) +{ + if(!node->isleaf()) + { + recursedeletenode(pdbvt,node->childs[0]); + recursedeletenode(pdbvt,node->childs[1]); + } + if(node==pdbvt->m_root) pdbvt->m_root=0; + deletenode(pdbvt,node); +} + +// +static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, + btDbvtNode* parent, + void* data) +{ + btDbvtNode* node; + if(pdbvt->m_free) + { node=pdbvt->m_free;pdbvt->m_free=0; } + else + { node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); } + node->parent = parent; + node->data = data; + node->childs[1] = 0; + return(node); +} + +// +static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, + btDbvtNode* parent, + const btDbvtVolume& volume, + void* data) +{ + btDbvtNode* node=createnode(pdbvt,parent,data); + node->volume=volume; + return(node); +} + +// +static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, + btDbvtNode* parent, + const btDbvtVolume& volume0, + const btDbvtVolume& volume1, + void* data) +{ + btDbvtNode* node=createnode(pdbvt,parent,data); + Merge(volume0,volume1,node->volume); + return(node); +} + +// +static void insertleaf( btDbvt* pdbvt, + btDbvtNode* root, + btDbvtNode* leaf) +{ + if(!pdbvt->m_root) + { + pdbvt->m_root = leaf; + leaf->parent = 0; + } + else + { + if(!root->isleaf()) + { + do { + root=root->childs[Select( leaf->volume, + root->childs[0]->volume, + root->childs[1]->volume)]; + } while(!root->isleaf()); + } + btDbvtNode* prev=root->parent; + btDbvtNode* node=createnode(pdbvt,prev,leaf->volume,root->volume,0); + if(prev) + { + prev->childs[indexof(root)] = node; + node->childs[0] = root;root->parent=node; + node->childs[1] = leaf;leaf->parent=node; + do { + if(!prev->volume.Contain(node->volume)) + Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); + else + break; + node=prev; + } while(0!=(prev=node->parent)); + } + else + { + node->childs[0] = root;root->parent=node; + node->childs[1] = leaf;leaf->parent=node; + pdbvt->m_root = node; + } + } +} + +// +static btDbvtNode* removeleaf( btDbvt* pdbvt, + btDbvtNode* leaf) +{ + if(leaf==pdbvt->m_root) + { + pdbvt->m_root=0; + return(0); + } + else + { + btDbvtNode* parent=leaf->parent; + btDbvtNode* prev=parent->parent; + btDbvtNode* sibling=parent->childs[1-indexof(leaf)]; + if(prev) + { + prev->childs[indexof(parent)]=sibling; + sibling->parent=prev; + deletenode(pdbvt,parent); + while(prev) + { + const btDbvtVolume pb=prev->volume; + Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); + if(NotEqual(pb,prev->volume)) + { + prev=prev->parent; + } else break; + } + return(prev?prev:pdbvt->m_root); + } + else + { + pdbvt->m_root=sibling; + sibling->parent=0; + deletenode(pdbvt,parent); + return(pdbvt->m_root); + } + } +} + +// +static void fetchleaves(btDbvt* pdbvt, + btDbvtNode* root, + tNodeArray& leaves, + int depth=-1) +{ + if(root->isinternal()&&depth) + { + fetchleaves(pdbvt,root->childs[0],leaves,depth-1); + fetchleaves(pdbvt,root->childs[1],leaves,depth-1); + deletenode(pdbvt,root); + } + else + { + leaves.push_back(root); + } +} + +// +static void split( const tNodeArray& leaves, + tNodeArray& left, + tNodeArray& right, + const btVector3& org, + const btVector3& axis) +{ + left.resize(0); + right.resize(0); + for(int i=0,ni=leaves.size();ivolume.Center()-org)<0) + left.push_back(leaves[i]); + else + right.push_back(leaves[i]); + } +} + +// +static btDbvtVolume bounds( const tNodeArray& leaves) +{ +#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE + ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]); + btDbvtVolume& volume=*(btDbvtVolume*)locals; + volume=leaves[0]->volume; +#else + btDbvtVolume volume=leaves[0]->volume; +#endif + for(int i=1,ni=leaves.size();ivolume,volume); + } + return(volume); +} + +// +static void bottomup( btDbvt* pdbvt, + tNodeArray& leaves) +{ + while(leaves.size()>1) + { + btScalar minsize=SIMD_INFINITY; + int minidx[2]={-1,-1}; + for(int i=0;ivolume,leaves[j]->volume)); + if(szvolume,n[1]->volume,0); + p->childs[0] = n[0]; + p->childs[1] = n[1]; + n[0]->parent = p; + n[1]->parent = p; + leaves[minidx[0]] = p; + leaves.swap(minidx[1],leaves.size()-1); + leaves.pop_back(); + } +} + +// +static btDbvtNode* topdown(btDbvt* pdbvt, + tNodeArray& leaves, + int bu_treshold) +{ + static const btVector3 axis[]={btVector3(1,0,0), + btVector3(0,1,0), + btVector3(0,0,1)}; + if(leaves.size()>1) + { + if(leaves.size()>bu_treshold) + { + const btDbvtVolume vol=bounds(leaves); + const btVector3 org=vol.Center(); + tNodeArray sets[2]; + int bestaxis=-1; + int bestmidp=leaves.size(); + int splitcount[3][2]={{0,0},{0,0},{0,0}}; + int i; + for( i=0;ivolume.Center()-org; + for(int j=0;j<3;++j) + { + ++splitcount[j][btDot(x,axis[j])>0?1:0]; + } + } + for( i=0;i<3;++i) + { + if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) + { + const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1])); + if(midp=0) + { + sets[0].reserve(splitcount[bestaxis][0]); + sets[1].reserve(splitcount[bestaxis][1]); + split(leaves,sets[0],sets[1],org,axis[bestaxis]); + } + else + { + sets[0].reserve(leaves.size()/2+1); + sets[1].reserve(leaves.size()/2); + for(int i=0,ni=leaves.size();ichilds[0]=topdown(pdbvt,sets[0],bu_treshold); + node->childs[1]=topdown(pdbvt,sets[1],bu_treshold); + node->childs[0]->parent=node; + node->childs[1]->parent=node; + return(node); + } + else + { + bottomup(pdbvt,leaves); + return(leaves[0]); + } + } + return(leaves[0]); +} + +// +static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n,btDbvtNode*& r) +{ + btDbvtNode* p=n->parent; + btAssert(n->isinternal()); + if(p>n) + { + const int i=indexof(n); + const int j=1-i; + btDbvtNode* s=p->childs[j]; + btDbvtNode* q=p->parent; + btAssert(n==p->childs[i]); + if(q) q->childs[indexof(p)]=n; else r=n; + s->parent=n; + p->parent=n; + n->parent=q; + p->childs[0]=n->childs[0]; + p->childs[1]=n->childs[1]; + n->childs[0]->parent=p; + n->childs[1]->parent=p; + n->childs[i]=p; + n->childs[j]=s; + btSwap(p->volume,n->volume); + return(p); + } + return(n); +} + +#if 0 +static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count) +{ + while(n&&(count--)) n=n->parent; + return(n); +} +#endif + +// +// Api +// + +// +btDbvt::btDbvt() +{ + m_root = 0; + m_free = 0; + m_lkhd = -1; + m_leaves = 0; + m_opath = 0; +} + +// +btDbvt::~btDbvt() +{ + clear(); +} + +// +void btDbvt::clear() +{ + if(m_root) + recursedeletenode(this,m_root); + btAlignedFree(m_free); + m_free=0; + m_lkhd = -1; + m_stkStack.clear(); + m_opath = 0; + +} + +// +void btDbvt::optimizeBottomUp() +{ + if(m_root) + { + tNodeArray leaves; + leaves.reserve(m_leaves); + fetchleaves(this,m_root,leaves); + bottomup(this,leaves); + m_root=leaves[0]; + } +} + +// +void btDbvt::optimizeTopDown(int bu_treshold) +{ + if(m_root) + { + tNodeArray leaves; + leaves.reserve(m_leaves); + fetchleaves(this,m_root,leaves); + m_root=topdown(this,leaves,bu_treshold); + } +} + +// +void btDbvt::optimizeIncremental(int passes) +{ + if(passes<0) passes=m_leaves; + if(m_root&&(passes>0)) + { + do { + btDbvtNode* node=m_root; + unsigned bit=0; + while(node->isinternal()) + { + node=sort(node,m_root)->childs[(m_opath>>bit)&1]; + bit=(bit+1)&(sizeof(unsigned)*8-1); + } + update(node); + ++m_opath; + } while(--passes); + } +} + +// +btDbvtNode* btDbvt::insert(const btDbvtVolume& volume,void* data) +{ + btDbvtNode* leaf=createnode(this,0,volume,data); + insertleaf(this,m_root,leaf); + ++m_leaves; + return(leaf); +} + +// +void btDbvt::update(btDbvtNode* leaf,int lookahead) +{ + btDbvtNode* root=removeleaf(this,leaf); + if(root) + { + if(lookahead>=0) + { + for(int i=0;(iparent;++i) + { + root=root->parent; + } + } else root=m_root; + } + insertleaf(this,root,leaf); +} + +// +void btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume) +{ + btDbvtNode* root=removeleaf(this,leaf); + if(root) + { + if(m_lkhd>=0) + { + for(int i=0;(iparent;++i) + { + root=root->parent; + } + } else root=m_root; + } + leaf->volume=volume; + insertleaf(this,root,leaf); +} + +// +bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin) +{ + if(leaf->volume.Contain(volume)) return(false); + volume.Expand(btVector3(margin,margin,margin)); + volume.SignedExpand(velocity); + update(leaf,volume); + return(true); +} + +// +bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity) +{ + if(leaf->volume.Contain(volume)) return(false); + volume.SignedExpand(velocity); + update(leaf,volume); + return(true); +} + +// +bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin) +{ + if(leaf->volume.Contain(volume)) return(false); + volume.Expand(btVector3(margin,margin,margin)); + update(leaf,volume); + return(true); +} + +// +void btDbvt::remove(btDbvtNode* leaf) +{ + removeleaf(this,leaf); + deletenode(this,leaf); + --m_leaves; +} + +// +void btDbvt::write(IWriter* iwriter) const +{ + btDbvtNodeEnumerator nodes; + nodes.nodes.reserve(m_leaves*2); + enumNodes(m_root,nodes); + iwriter->Prepare(m_root,nodes.nodes.size()); + for(int i=0;iparent) p=nodes.nodes.findLinearSearch(n->parent); + if(n->isinternal()) + { + const int c0=nodes.nodes.findLinearSearch(n->childs[0]); + const int c1=nodes.nodes.findLinearSearch(n->childs[1]); + iwriter->WriteNode(n,i,p,c0,c1); + } + else + { + iwriter->WriteLeaf(n,i,p); + } + } +} + +// +void btDbvt::clone(btDbvt& dest,IClone* iclone) const +{ + dest.clear(); + if(m_root!=0) + { + btAlignedObjectArray stack; + stack.reserve(m_leaves); + stack.push_back(sStkCLN(m_root,0)); + do { + const int i=stack.size()-1; + const sStkCLN e=stack[i]; + btDbvtNode* n=createnode(&dest,e.parent,e.node->volume,e.node->data); + stack.pop_back(); + if(e.parent!=0) + e.parent->childs[i&1]=n; + else + dest.m_root=n; + if(e.node->isinternal()) + { + stack.push_back(sStkCLN(e.node->childs[0],n)); + stack.push_back(sStkCLN(e.node->childs[1],n)); + } + else + { + iclone->CloneLeaf(n); + } + } while(stack.size()>0); + } +} + +// +int btDbvt::maxdepth(const btDbvtNode* node) +{ + int depth=0; + if(node) getmaxdepth(node,1,depth); + return(depth); +} + +// +int btDbvt::countLeaves(const btDbvtNode* node) +{ + if(node->isinternal()) + return(countLeaves(node->childs[0])+countLeaves(node->childs[1])); + else + return(1); +} + +// +void btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray& leaves) +{ + if(node->isinternal()) + { + extractLeaves(node->childs[0],leaves); + extractLeaves(node->childs[1],leaves); + } + else + { + leaves.push_back(node); + } +} + +// +#if DBVT_ENABLE_BENCHMARK + +#include +#include +#include "LinearMath/btQuickProf.h" + +/* +q6600,2.4ghz + +/Ox /Ob2 /Oi /Ot /I "." /I "..\.." /I "..\..\src" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "WIN32" +/GF /FD /MT /GS- /Gy /arch:SSE2 /Zc:wchar_t- /Fp"..\..\out\release8\build\libbulletcollision\libbulletcollision.pch" +/Fo"..\..\out\release8\build\libbulletcollision\\" +/Fd"..\..\out\release8\build\libbulletcollision\bulletcollision.pdb" +/W3 /nologo /c /Wp64 /Zi /errorReport:prompt + +Benchmarking dbvt... +World scale: 100.000000 +Extents base: 1.000000 +Extents range: 4.000000 +Leaves: 8192 +sizeof(btDbvtVolume): 32 bytes +sizeof(btDbvtNode): 44 bytes +[1] btDbvtVolume intersections: 3499 ms (-1%) +[2] btDbvtVolume merges: 1934 ms (0%) +[3] btDbvt::collideTT: 5485 ms (-21%) +[4] btDbvt::collideTT self: 2814 ms (-20%) +[5] btDbvt::collideTT xform: 7379 ms (-1%) +[6] btDbvt::collideTT xform,self: 7270 ms (-2%) +[7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s) +[8] insert/remove: 2093 ms (0%),(1001983 ir/s) +[9] updates (teleport): 1879 ms (-3%),(1116100 u/s) +[10] updates (jitter): 1244 ms (-4%),(1685813 u/s) +[11] optimize (incremental): 2514 ms (0%),(1668000 o/s) +[12] btDbvtVolume notequal: 3659 ms (0%) +[13] culling(OCL+fullsort): 2218 ms (0%),(461 t/s) +[14] culling(OCL+qsort): 3688 ms (5%),(2221 t/s) +[15] culling(KDOP+qsort): 1139 ms (-1%),(7192 t/s) +[16] insert/remove batch(256): 5092 ms (0%),(823704 bir/s) +[17] btDbvtVolume select: 3419 ms (0%) +*/ + +struct btDbvtBenchmark +{ + struct NilPolicy : btDbvt::ICollide + { + NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {} + void Process(const btDbvtNode*,const btDbvtNode*) { ++m_pcount; } + void Process(const btDbvtNode*) { ++m_pcount; } + void Process(const btDbvtNode*,btScalar depth) + { + ++m_pcount; + if(m_checksort) + { if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); } + } + int m_pcount; + btScalar m_depth; + bool m_checksort; + }; + struct P14 : btDbvt::ICollide + { + struct Node + { + const btDbvtNode* leaf; + btScalar depth; + }; + void Process(const btDbvtNode* leaf,btScalar depth) + { + Node n; + n.leaf = leaf; + n.depth = depth; + } + static int sortfnc(const Node& a,const Node& b) + { + if(a.depthb.depth) return(-1); + return(0); + } + btAlignedObjectArray m_nodes; + }; + struct P15 : btDbvt::ICollide + { + struct Node + { + const btDbvtNode* leaf; + btScalar depth; + }; + void Process(const btDbvtNode* leaf) + { + Node n; + n.leaf = leaf; + n.depth = dot(leaf->volume.Center(),m_axis); + } + static int sortfnc(const Node& a,const Node& b) + { + if(a.depthb.depth) return(-1); + return(0); + } + btAlignedObjectArray m_nodes; + btVector3 m_axis; + }; + static btScalar RandUnit() + { + return(rand()/(btScalar)RAND_MAX); + } + static btVector3 RandVector3() + { + return(btVector3(RandUnit(),RandUnit(),RandUnit())); + } + static btVector3 RandVector3(btScalar cs) + { + return(RandVector3()*cs-btVector3(cs,cs,cs)/2); + } + static btDbvtVolume RandVolume(btScalar cs,btScalar eb,btScalar es) + { + return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es)); + } + static btTransform RandTransform(btScalar cs) + { + btTransform t; + t.setOrigin(RandVector3(cs)); + t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized()); + return(t); + } + static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt) + { + dbvt.clear(); + for(int i=0;i volumes; + btAlignedObjectArray results; + volumes.resize(cfgLeaves); + results.resize(cfgLeaves); + for(int i=0;i volumes; + btAlignedObjectArray results; + volumes.resize(cfgLeaves); + results.resize(cfgLeaves); + for(int i=0;i transforms; + btDbvtBenchmark::NilPolicy policy; + transforms.resize(cfgBenchmark5_Iterations); + for(int i=0;i transforms; + btDbvtBenchmark::NilPolicy policy; + transforms.resize(cfgBenchmark6_Iterations); + for(int i=0;i rayorg; + btAlignedObjectArray raydir; + btDbvtBenchmark::NilPolicy policy; + rayorg.resize(cfgBenchmark7_Iterations); + raydir.resize(cfgBenchmark7_Iterations); + for(int i=0;i leaves; + btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + dbvt.optimizeTopDown(); + dbvt.extractLeaves(dbvt.m_root,leaves); + printf("[9] updates (teleport): "); + wallclock.reset(); + for(int i=0;i(leaves[rand()%cfgLeaves]), + btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale)); + } + } + const int time=(int)wallclock.getTimeMilliseconds(); + const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations; + printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time); + } + if(cfgBenchmark10_Enable) + {// Benchmark 10 + srand(380843); + btDbvt dbvt; + btAlignedObjectArray leaves; + btAlignedObjectArray vectors; + vectors.resize(cfgBenchmark10_Iterations); + for(int i=0;i(leaves[rand()%cfgLeaves]); + btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d); + dbvt.update(l,v); + } + } + const int time=(int)wallclock.getTimeMilliseconds(); + const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations; + printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time); + } + if(cfgBenchmark11_Enable) + {// Benchmark 11 + srand(380843); + btDbvt dbvt; + btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + dbvt.optimizeTopDown(); + printf("[11] optimize (incremental): "); + wallclock.reset(); + for(int i=0;i volumes; + btAlignedObjectArray results; + volumes.resize(cfgLeaves); + results.resize(cfgLeaves); + for(int i=0;i vectors; + btDbvtBenchmark::NilPolicy policy; + vectors.resize(cfgBenchmark13_Iterations); + for(int i=0;i vectors; + btDbvtBenchmark::P14 policy; + vectors.resize(cfgBenchmark14_Iterations); + for(int i=0;i vectors; + btDbvtBenchmark::P15 policy; + vectors.resize(cfgBenchmark15_Iterations); + for(int i=0;i batch; + btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + dbvt.optimizeTopDown(); + batch.reserve(cfgBenchmark16_BatchCount); + printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount); + wallclock.reset(); + for(int i=0;i volumes; + btAlignedObjectArray results; + btAlignedObjectArray indices; + volumes.resize(cfgLeaves); + results.resize(cfgLeaves); + indices.resize(cfgLeaves); + for(int i=0;i= 1400) +#define DBVT_USE_TEMPLATE 1 +#else +#define DBVT_USE_TEMPLATE 0 +#endif +#else +#define DBVT_USE_TEMPLATE 0 +#endif + +// Use only intrinsics instead of inline asm +#define DBVT_USE_INTRINSIC_SSE 1 + +// Using memmov for collideOCL +#define DBVT_USE_MEMMOVE 1 + +// Enable benchmarking code +#define DBVT_ENABLE_BENCHMARK 0 + +// Inlining +#define DBVT_INLINE SIMD_FORCE_INLINE + +// Specific methods implementation + +//SSE gives errors on a MSVC 7.1 +#if defined (BT_USE_SSE) //&& defined (_WIN32) +#define DBVT_SELECT_IMPL DBVT_IMPL_SSE +#define DBVT_MERGE_IMPL DBVT_IMPL_SSE +#define DBVT_INT0_IMPL DBVT_IMPL_SSE +#else +#define DBVT_SELECT_IMPL DBVT_IMPL_GENERIC +#define DBVT_MERGE_IMPL DBVT_IMPL_GENERIC +#define DBVT_INT0_IMPL DBVT_IMPL_GENERIC +#endif + +#if (DBVT_SELECT_IMPL==DBVT_IMPL_SSE)|| \ + (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)|| \ + (DBVT_INT0_IMPL==DBVT_IMPL_SSE) +#include +#endif + +// +// Auto config and checks +// + +#if DBVT_USE_TEMPLATE +#define DBVT_VIRTUAL +#define DBVT_VIRTUAL_DTOR(a) +#define DBVT_PREFIX template +#define DBVT_IPOLICY T& policy +#define DBVT_CHECKTYPE static const ICollide& typechecker=*(T*)1;(void)typechecker; +#else +#define DBVT_VIRTUAL_DTOR(a) virtual ~a() {} +#define DBVT_VIRTUAL virtual +#define DBVT_PREFIX +#define DBVT_IPOLICY ICollide& policy +#define DBVT_CHECKTYPE +#endif + +#if DBVT_USE_MEMMOVE +#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#include +#endif +#include +#endif + +#ifndef DBVT_USE_TEMPLATE +#error "DBVT_USE_TEMPLATE undefined" +#endif + +#ifndef DBVT_USE_MEMMOVE +#error "DBVT_USE_MEMMOVE undefined" +#endif + +#ifndef DBVT_ENABLE_BENCHMARK +#error "DBVT_ENABLE_BENCHMARK undefined" +#endif + +#ifndef DBVT_SELECT_IMPL +#error "DBVT_SELECT_IMPL undefined" +#endif + +#ifndef DBVT_MERGE_IMPL +#error "DBVT_MERGE_IMPL undefined" +#endif + +#ifndef DBVT_INT0_IMPL +#error "DBVT_INT0_IMPL undefined" +#endif + +// +// Defaults volumes +// + +/* btDbvtAabbMm */ +struct btDbvtAabbMm +{ + DBVT_INLINE btVector3 Center() const { return((mi+mx)/2); } + DBVT_INLINE btVector3 Lengths() const { return(mx-mi); } + DBVT_INLINE btVector3 Extents() const { return((mx-mi)/2); } + DBVT_INLINE const btVector3& Mins() const { return(mi); } + DBVT_INLINE const btVector3& Maxs() const { return(mx); } + static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e); + static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r); + static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx); + static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n); + static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n); + DBVT_INLINE void Expand(const btVector3& e); + DBVT_INLINE void SignedExpand(const btVector3& e); + DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const; + DBVT_INLINE int Classify(const btVector3& n,btScalar o,int s) const; + DBVT_INLINE btScalar ProjectMinimum(const btVector3& v,unsigned signs) const; + DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + + DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, + const btVector3& b); + + DBVT_INLINE friend btScalar Proximity( const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + DBVT_INLINE friend int Select( const btDbvtAabbMm& o, + const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + DBVT_INLINE friend void Merge( const btDbvtAabbMm& a, + const btDbvtAabbMm& b, + btDbvtAabbMm& r); + DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + + DBVT_INLINE btVector3& tMins() { return(mi); } + DBVT_INLINE btVector3& tMaxs() { return(mx); } + +private: + DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const; +private: + btVector3 mi,mx; +}; + +// Types +typedef btDbvtAabbMm btDbvtVolume; + +/* btDbvtNode */ +struct btDbvtNode +{ + btDbvtVolume volume; + btDbvtNode* parent; + DBVT_INLINE bool isleaf() const { return(childs[1]==0); } + DBVT_INLINE bool isinternal() const { return(!isleaf()); } + union + { + btDbvtNode* childs[2]; + void* data; + int dataAsInt; + }; +}; + +///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree). +///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes. +///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure. +struct btDbvt +{ + /* Stack element */ + struct sStkNN + { + const btDbvtNode* a; + const btDbvtNode* b; + sStkNN() {} + sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {} + }; + struct sStkNP + { + const btDbvtNode* node; + int mask; + sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {} + }; + struct sStkNPS + { + const btDbvtNode* node; + int mask; + btScalar value; + sStkNPS() {} + sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {} + }; + struct sStkCLN + { + const btDbvtNode* node; + btDbvtNode* parent; + sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {} + }; + // Policies/Interfaces + + /* ICollide */ + struct ICollide + { + DBVT_VIRTUAL_DTOR(ICollide) + DBVT_VIRTUAL void Process(const btDbvtNode*,const btDbvtNode*) {} + DBVT_VIRTUAL void Process(const btDbvtNode*) {} + DBVT_VIRTUAL void Process(const btDbvtNode* n,btScalar) { Process(n); } + DBVT_VIRTUAL bool Descent(const btDbvtNode*) { return(true); } + DBVT_VIRTUAL bool AllLeaves(const btDbvtNode*) { return(true); } + }; + /* IWriter */ + struct IWriter + { + virtual ~IWriter() {} + virtual void Prepare(const btDbvtNode* root,int numnodes)=0; + virtual void WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0; + virtual void WriteLeaf(const btDbvtNode*,int index,int parent)=0; + }; + /* IClone */ + struct IClone + { + virtual ~IClone() {} + virtual void CloneLeaf(btDbvtNode*) {} + }; + + // Constants + enum { + SIMPLE_STACKSIZE = 64, + DOUBLE_STACKSIZE = SIMPLE_STACKSIZE*2 + }; + + // Fields + btDbvtNode* m_root; + btDbvtNode* m_free; + int m_lkhd; + int m_leaves; + unsigned m_opath; + + + btAlignedObjectArray m_stkStack; + mutable btAlignedObjectArray m_rayTestStack; + + + // Methods + btDbvt(); + ~btDbvt(); + void clear(); + bool empty() const { return(0==m_root); } + void optimizeBottomUp(); + void optimizeTopDown(int bu_treshold=128); + void optimizeIncremental(int passes); + btDbvtNode* insert(const btDbvtVolume& box,void* data); + void update(btDbvtNode* leaf,int lookahead=-1); + void update(btDbvtNode* leaf,btDbvtVolume& volume); + bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin); + bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity); + bool update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin); + void remove(btDbvtNode* leaf); + void write(IWriter* iwriter) const; + void clone(btDbvt& dest,IClone* iclone=0) const; + static int maxdepth(const btDbvtNode* node); + static int countLeaves(const btDbvtNode* node); + static void extractLeaves(const btDbvtNode* node,btAlignedObjectArray& leaves); +#if DBVT_ENABLE_BENCHMARK + static void benchmark(); +#else + static void benchmark(){} +#endif + // DBVT_IPOLICY must support ICollide policy/interface + DBVT_PREFIX + static void enumNodes( const btDbvtNode* root, + DBVT_IPOLICY); + DBVT_PREFIX + static void enumLeaves( const btDbvtNode* root, + DBVT_IPOLICY); + DBVT_PREFIX + void collideTT( const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY); + + DBVT_PREFIX + void collideTTpersistentStack( const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY); +#if 0 + DBVT_PREFIX + void collideTT( const btDbvtNode* root0, + const btDbvtNode* root1, + const btTransform& xform, + DBVT_IPOLICY); + DBVT_PREFIX + void collideTT( const btDbvtNode* root0, + const btTransform& xform0, + const btDbvtNode* root1, + const btTransform& xform1, + DBVT_IPOLICY); +#endif + + DBVT_PREFIX + void collideTV( const btDbvtNode* root, + const btDbvtVolume& volume, + DBVT_IPOLICY) const; + ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc) + ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time + DBVT_PREFIX + static void rayTest( const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + DBVT_IPOLICY); + ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections + ///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts + DBVT_PREFIX + void rayTestInternal( const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& rayDirectionInverse, + unsigned int signs[3], + btScalar lambda_max, + const btVector3& aabbMin, + const btVector3& aabbMax, + DBVT_IPOLICY) const; + + DBVT_PREFIX + static void collideKDOP(const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + int count, + DBVT_IPOLICY); + DBVT_PREFIX + static void collideOCL( const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + const btVector3& sortaxis, + int count, + DBVT_IPOLICY, + bool fullsort=true); + DBVT_PREFIX + static void collideTU( const btDbvtNode* root, + DBVT_IPOLICY); + // Helpers + static DBVT_INLINE int nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h) + { + int m=0; + while(l>1; + if(a[i[m]].value>=v) l=m+1; else h=m; + } + return(h); + } + static DBVT_INLINE int allocate( btAlignedObjectArray& ifree, + btAlignedObjectArray& stock, + const sStkNPS& value) + { + int i; + if(ifree.size()>0) + { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; } + else + { i=stock.size();stock.push_back(value); } + return(i); + } + // +private: + btDbvt(const btDbvt&) {} +}; + +// +// Inline's +// + +// +inline btDbvtAabbMm btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e) +{ + btDbvtAabbMm box; + box.mi=c-e;box.mx=c+e; + return(box); +} + +// +inline btDbvtAabbMm btDbvtAabbMm::FromCR(const btVector3& c,btScalar r) +{ + return(FromCE(c,btVector3(r,r,r))); +} + +// +inline btDbvtAabbMm btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx) +{ + btDbvtAabbMm box; + box.mi=mi;box.mx=mx; + return(box); +} + +// +inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3* pts,int n) +{ + btDbvtAabbMm box; + box.mi=box.mx=pts[0]; + for(int i=1;i0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]); + if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]); + if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]); +} + +// +DBVT_INLINE bool btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const +{ + return( (mi.x()<=a.mi.x())&& + (mi.y()<=a.mi.y())&& + (mi.z()<=a.mi.z())&& + (mx.x()>=a.mx.x())&& + (mx.y()>=a.mx.y())&& + (mx.z()>=a.mx.z())); +} + +// +DBVT_INLINE int btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const +{ + btVector3 pi,px; + switch(s) + { + case (0+0+0): px=btVector3(mi.x(),mi.y(),mi.z()); + pi=btVector3(mx.x(),mx.y(),mx.z());break; + case (1+0+0): px=btVector3(mx.x(),mi.y(),mi.z()); + pi=btVector3(mi.x(),mx.y(),mx.z());break; + case (0+2+0): px=btVector3(mi.x(),mx.y(),mi.z()); + pi=btVector3(mx.x(),mi.y(),mx.z());break; + case (1+2+0): px=btVector3(mx.x(),mx.y(),mi.z()); + pi=btVector3(mi.x(),mi.y(),mx.z());break; + case (0+0+4): px=btVector3(mi.x(),mi.y(),mx.z()); + pi=btVector3(mx.x(),mx.y(),mi.z());break; + case (1+0+4): px=btVector3(mx.x(),mi.y(),mx.z()); + pi=btVector3(mi.x(),mx.y(),mi.z());break; + case (0+2+4): px=btVector3(mi.x(),mx.y(),mx.z()); + pi=btVector3(mx.x(),mi.y(),mi.z());break; + case (1+2+4): px=btVector3(mx.x(),mx.y(),mx.z()); + pi=btVector3(mi.x(),mi.y(),mi.z());break; + } + if((btDot(n,px)+o)<0) return(-1); + if((btDot(n,pi)+o)>=0) return(+1); + return(0); +} + +// +DBVT_INLINE btScalar btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const +{ + const btVector3* b[]={&mx,&mi}; + const btVector3 p( b[(signs>>0)&1]->x(), + b[(signs>>1)&1]->y(), + b[(signs>>2)&1]->z()); + return(btDot(p,v)); +} + +// +DBVT_INLINE void btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const +{ + for(int i=0;i<3;++i) + { + if(d[i]<0) + { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; } + else + { smi+=mi[i]*d[i];smx+=mx[i]*d[i]; } + } +} + +// +DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, + const btDbvtAabbMm& b) +{ +#if DBVT_INT0_IMPL == DBVT_IMPL_SSE + const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)), + _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi)))); +#if defined (_WIN32) + const __int32* pu((const __int32*)&rt); +#else + const int* pu((const int*)&rt); +#endif + return((pu[0]|pu[1]|pu[2])==0); +#else + return( (a.mi.x()<=b.mx.x())&& + (a.mx.x()>=b.mi.x())&& + (a.mi.y()<=b.mx.y())&& + (a.mx.y()>=b.mi.y())&& + (a.mi.z()<=b.mx.z())&& + (a.mx.z()>=b.mi.z())); +#endif +} + + + +// +DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, + const btVector3& b) +{ + return( (b.x()>=a.mi.x())&& + (b.y()>=a.mi.y())&& + (b.z()>=a.mi.z())&& + (b.x()<=a.mx.x())&& + (b.y()<=a.mx.y())&& + (b.z()<=a.mx.z())); +} + + + + + +////////////////////////////////////// + + +// +DBVT_INLINE btScalar Proximity( const btDbvtAabbMm& a, + const btDbvtAabbMm& b) +{ + const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx); + return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z())); +} + + + +// +DBVT_INLINE int Select( const btDbvtAabbMm& o, + const btDbvtAabbMm& a, + const btDbvtAabbMm& b) +{ +#if DBVT_SELECT_IMPL == DBVT_IMPL_SSE + +#if defined (_WIN32) + static ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; +#else + static ATTRIBUTE_ALIGNED16(const unsigned int) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x00000000 /*0x7fffffff*/}; +#endif + ///@todo: the intrinsic version is 11% slower +#if DBVT_USE_INTRINSIC_SSE + + union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory + { + __m128 ssereg; + float floats[4]; + int ints[4]; + }; + + __m128 omi(_mm_load_ps(o.mi)); + omi=_mm_add_ps(omi,_mm_load_ps(o.mx)); + __m128 ami(_mm_load_ps(a.mi)); + ami=_mm_add_ps(ami,_mm_load_ps(a.mx)); + ami=_mm_sub_ps(ami,omi); + ami=_mm_and_ps(ami,_mm_load_ps((const float*)mask)); + __m128 bmi(_mm_load_ps(b.mi)); + bmi=_mm_add_ps(bmi,_mm_load_ps(b.mx)); + bmi=_mm_sub_ps(bmi,omi); + bmi=_mm_and_ps(bmi,_mm_load_ps((const float*)mask)); + __m128 t0(_mm_movehl_ps(ami,ami)); + ami=_mm_add_ps(ami,t0); + ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1)); + __m128 t1(_mm_movehl_ps(bmi,bmi)); + bmi=_mm_add_ps(bmi,t1); + bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1)); + + btSSEUnion tmp; + tmp.ssereg = _mm_cmple_ss(bmi,ami); + return tmp.ints[0]&1; + +#else + ATTRIBUTE_ALIGNED16(__int32 r[1]); + __asm + { + mov eax,o + mov ecx,a + mov edx,b + movaps xmm0,[eax] + movaps xmm5,mask + addps xmm0,[eax+16] + movaps xmm1,[ecx] + movaps xmm2,[edx] + addps xmm1,[ecx+16] + addps xmm2,[edx+16] + subps xmm1,xmm0 + subps xmm2,xmm0 + andps xmm1,xmm5 + andps xmm2,xmm5 + movhlps xmm3,xmm1 + movhlps xmm4,xmm2 + addps xmm1,xmm3 + addps xmm2,xmm4 + pshufd xmm3,xmm1,1 + pshufd xmm4,xmm2,1 + addss xmm1,xmm3 + addss xmm2,xmm4 + cmpless xmm2,xmm1 + movss r,xmm2 + } + return(r[0]&1); +#endif +#else + return(Proximity(o,a)b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i]; + } +#endif +} + +// +DBVT_INLINE bool NotEqual( const btDbvtAabbMm& a, + const btDbvtAabbMm& b) +{ + return( (a.mi.x()!=b.mi.x())|| + (a.mi.y()!=b.mi.y())|| + (a.mi.z()!=b.mi.z())|| + (a.mx.x()!=b.mx.x())|| + (a.mx.y()!=b.mx.y())|| + (a.mx.z()!=b.mx.z())); +} + +// +// Inline's +// + +// +DBVT_PREFIX +inline void btDbvt::enumNodes( const btDbvtNode* root, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + policy.Process(root); + if(root->isinternal()) + { + enumNodes(root->childs[0],policy); + enumNodes(root->childs[1],policy); + } +} + +// +DBVT_PREFIX +inline void btDbvt::enumLeaves( const btDbvtNode* root, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if(root->isinternal()) + { + enumLeaves(root->childs[0],policy); + enumLeaves(root->childs[1],policy); + } + else + { + policy.Process(root); + } +} + +// +DBVT_PREFIX +inline void btDbvt::collideTT( const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if(root0&&root1) + { + int depth=1; + int treshold=DOUBLE_STACKSIZE-4; + btAlignedObjectArray stkStack; + stkStack.resize(DOUBLE_STACKSIZE); + stkStack[0]=sStkNN(root0,root1); + do { + sStkNN p=stkStack[--depth]; + if(depth>treshold) + { + stkStack.resize(stkStack.size()*2); + treshold=stkStack.size()-4; + } + if(p.a==p.b) + { + if(p.a->isinternal()) + { + stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); + stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); + stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); + } + } + else if(Intersect(p.a->volume,p.b->volume)) + { + if(p.a->isinternal()) + { + if(p.b->isinternal()) + { + stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); + stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); + stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); + stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); + } + else + { + stkStack[depth++]=sStkNN(p.a->childs[0],p.b); + stkStack[depth++]=sStkNN(p.a->childs[1],p.b); + } + } + else + { + if(p.b->isinternal()) + { + stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); + stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); + } + else + { + policy.Process(p.a,p.b); + } + } + } + } while(depth); + } +} + + + +DBVT_PREFIX +inline void btDbvt::collideTTpersistentStack( const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if(root0&&root1) + { + int depth=1; + int treshold=DOUBLE_STACKSIZE-4; + + m_stkStack.resize(DOUBLE_STACKSIZE); + m_stkStack[0]=sStkNN(root0,root1); + do { + sStkNN p=m_stkStack[--depth]; + if(depth>treshold) + { + m_stkStack.resize(m_stkStack.size()*2); + treshold=m_stkStack.size()-4; + } + if(p.a==p.b) + { + if(p.a->isinternal()) + { + m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); + m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); + m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); + } + } + else if(Intersect(p.a->volume,p.b->volume)) + { + if(p.a->isinternal()) + { + if(p.b->isinternal()) + { + m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); + m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); + m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); + m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); + } + else + { + m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b); + m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b); + } + } + else + { + if(p.b->isinternal()) + { + m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); + m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); + } + else + { + policy.Process(p.a,p.b); + } + } + } + } while(depth); + } +} + +#if 0 +// +DBVT_PREFIX +inline void btDbvt::collideTT( const btDbvtNode* root0, + const btDbvtNode* root1, + const btTransform& xform, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if(root0&&root1) + { + int depth=1; + int treshold=DOUBLE_STACKSIZE-4; + btAlignedObjectArray stkStack; + stkStack.resize(DOUBLE_STACKSIZE); + stkStack[0]=sStkNN(root0,root1); + do { + sStkNN p=stkStack[--depth]; + if(Intersect(p.a->volume,p.b->volume,xform)) + { + if(depth>treshold) + { + stkStack.resize(stkStack.size()*2); + treshold=stkStack.size()-4; + } + if(p.a->isinternal()) + { + if(p.b->isinternal()) + { + stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); + stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); + stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); + stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); + } + else + { + stkStack[depth++]=sStkNN(p.a->childs[0],p.b); + stkStack[depth++]=sStkNN(p.a->childs[1],p.b); + } + } + else + { + if(p.b->isinternal()) + { + stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); + stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); + } + else + { + policy.Process(p.a,p.b); + } + } + } + } while(depth); + } +} +// +DBVT_PREFIX +inline void btDbvt::collideTT( const btDbvtNode* root0, + const btTransform& xform0, + const btDbvtNode* root1, + const btTransform& xform1, + DBVT_IPOLICY) +{ + const btTransform xform=xform0.inverse()*xform1; + collideTT(root0,root1,xform,policy); +} +#endif + +// +DBVT_PREFIX +inline void btDbvt::collideTV( const btDbvtNode* root, + const btDbvtVolume& vol, + DBVT_IPOLICY) const +{ + DBVT_CHECKTYPE + if(root) + { + ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); + btAlignedObjectArray stack; + stack.resize(0); + stack.reserve(SIMPLE_STACKSIZE); + stack.push_back(root); + do { + const btDbvtNode* n=stack[stack.size()-1]; + stack.pop_back(); + if(Intersect(n->volume,volume)) + { + if(n->isinternal()) + { + stack.push_back(n->childs[0]); + stack.push_back(n->childs[1]); + } + else + { + policy.Process(n); + } + } + } while(stack.size()>0); + } +} + +DBVT_PREFIX +inline void btDbvt::rayTestInternal( const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& rayDirectionInverse, + unsigned int signs[3], + btScalar lambda_max, + const btVector3& aabbMin, + const btVector3& aabbMax, + DBVT_IPOLICY) const +{ + (void) rayTo; + DBVT_CHECKTYPE + if(root) + { + btVector3 resultNormal; + + int depth=1; + int treshold=DOUBLE_STACKSIZE-2; + btAlignedObjectArray& stack = m_rayTestStack; + stack.resize(DOUBLE_STACKSIZE); + stack[0]=root; + btVector3 bounds[2]; + do + { + const btDbvtNode* node=stack[--depth]; + bounds[0] = node->volume.Mins()-aabbMax; + bounds[1] = node->volume.Maxs()-aabbMin; + btScalar tmin=1.f,lambda_min=0.f; + unsigned int result1=false; + result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); + if(result1) + { + if(node->isinternal()) + { + if(depth>treshold) + { + stack.resize(stack.size()*2); + treshold=stack.size()-2; + } + stack[depth++]=node->childs[0]; + stack[depth++]=node->childs[1]; + } + else + { + policy.Process(node); + } + } + } while(depth); + } +} + +// +DBVT_PREFIX +inline void btDbvt::rayTest( const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if(root) + { + btVector3 rayDir = (rayTo-rayFrom); + rayDir.normalize (); + + ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT + btVector3 rayDirectionInverse; + rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; + rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; + rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2]; + unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; + + btScalar lambda_max = rayDir.dot(rayTo-rayFrom); + + btVector3 resultNormal; + + btAlignedObjectArray stack; + + int depth=1; + int treshold=DOUBLE_STACKSIZE-2; + + stack.resize(DOUBLE_STACKSIZE); + stack[0]=root; + btVector3 bounds[2]; + do { + const btDbvtNode* node=stack[--depth]; + + bounds[0] = node->volume.Mins(); + bounds[1] = node->volume.Maxs(); + + btScalar tmin=1.f,lambda_min=0.f; + unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); + +#ifdef COMPARE_BTRAY_AABB2 + btScalar param=1.f; + bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal); + btAssert(result1 == result2); +#endif //TEST_BTRAY_AABB2 + + if(result1) + { + if(node->isinternal()) + { + if(depth>treshold) + { + stack.resize(stack.size()*2); + treshold=stack.size()-2; + } + stack[depth++]=node->childs[0]; + stack[depth++]=node->childs[1]; + } + else + { + policy.Process(node); + } + } + } while(depth); + + } +} + +// +DBVT_PREFIX +inline void btDbvt::collideKDOP(const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + int count, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if(root) + { + const int inside=(1< stack; + int signs[sizeof(unsigned)*8]; + btAssert(count=0)?1:0)+ + ((normals[i].y()>=0)?2:0)+ + ((normals[i].z()>=0)?4:0); + } + stack.reserve(SIMPLE_STACKSIZE); + stack.push_back(sStkNP(root,0)); + do { + sStkNP se=stack[stack.size()-1]; + bool out=false; + stack.pop_back(); + for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); + switch(side) + { + case -1: out=true;break; + case +1: se.mask|=j;break; + } + } + } + if(!out) + { + if((se.mask!=inside)&&(se.node->isinternal())) + { + stack.push_back(sStkNP(se.node->childs[0],se.mask)); + stack.push_back(sStkNP(se.node->childs[1],se.mask)); + } + else + { + if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy); + } + } + } while(stack.size()); + } +} + +// +DBVT_PREFIX +inline void btDbvt::collideOCL( const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + const btVector3& sortaxis, + int count, + DBVT_IPOLICY, + bool fsort) +{ + DBVT_CHECKTYPE + if(root) + { + const unsigned srtsgns=(sortaxis[0]>=0?1:0)+ + (sortaxis[1]>=0?2:0)+ + (sortaxis[2]>=0?4:0); + const int inside=(1< stock; + btAlignedObjectArray ifree; + btAlignedObjectArray stack; + int signs[sizeof(unsigned)*8]; + btAssert(count=0)?1:0)+ + ((normals[i].y()>=0)?2:0)+ + ((normals[i].z()>=0)?4:0); + } + stock.reserve(SIMPLE_STACKSIZE); + stack.reserve(SIMPLE_STACKSIZE); + ifree.reserve(SIMPLE_STACKSIZE); + stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns)))); + do { + const int id=stack[stack.size()-1]; + sStkNPS se=stock[id]; + stack.pop_back();ifree.push_back(id); + if(se.mask!=inside) + { + bool out=false; + for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); + switch(side) + { + case -1: out=true;break; + case +1: se.mask|=j;break; + } + } + } + if(out) continue; + } + if(policy.Descent(se.node)) + { + if(se.node->isinternal()) + { + const btDbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]}; + sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)), + sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))}; + const int q=nes[0].value0)) + { + /* Insert 0 */ + j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size()); + stack.push_back(0); +#if DBVT_USE_MEMMOVE + memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); +#else + for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; +#endif + stack[j]=allocate(ifree,stock,nes[q]); + /* Insert 1 */ + j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size()); + stack.push_back(0); +#if DBVT_USE_MEMMOVE + memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); +#else + for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; +#endif + stack[j]=allocate(ifree,stock,nes[1-q]); + } + else + { + stack.push_back(allocate(ifree,stock,nes[q])); + stack.push_back(allocate(ifree,stock,nes[1-q])); + } + } + else + { + policy.Process(se.node,se.value); + } + } + } while(stack.size()); + } +} + +// +DBVT_PREFIX +inline void btDbvt::collideTU( const btDbvtNode* root, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if(root) + { + btAlignedObjectArray stack; + stack.reserve(SIMPLE_STACKSIZE); + stack.push_back(root); + do { + const btDbvtNode* n=stack[stack.size()-1]; + stack.pop_back(); + if(policy.Descent(n)) + { + if(n->isinternal()) + { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } + else + { policy.Process(n); } + } + } while(stack.size()>0); + } +} + +// +// PP Cleanup +// + +#undef DBVT_USE_MEMMOVE +#undef DBVT_USE_TEMPLATE +#undef DBVT_VIRTUAL_DTOR +#undef DBVT_VIRTUAL +#undef DBVT_PREFIX +#undef DBVT_IPOLICY +#undef DBVT_CHECKTYPE +#undef DBVT_IMPL_GENERIC +#undef DBVT_IMPL_SSE +#undef DBVT_USE_INTRINSIC_SSE +#undef DBVT_SELECT_IMPL +#undef DBVT_MERGE_IMPL +#undef DBVT_INT0_IMPL + +#endif diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp new file mode 100644 index 0000000..75cfac6 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp @@ -0,0 +1,796 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///btDbvtBroadphase implementation by Nathanael Presson + +#include "btDbvtBroadphase.h" + +// +// Profiling +// + +#if DBVT_BP_PROFILE||DBVT_BP_ENABLE_BENCHMARK +#include +#endif + +#if DBVT_BP_PROFILE +struct ProfileScope +{ + __forceinline ProfileScope(btClock& clock,unsigned long& value) : + m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds()) + { + } + __forceinline ~ProfileScope() + { + (*m_value)+=m_clock->getTimeMicroseconds()-m_base; + } + btClock* m_clock; + unsigned long* m_value; + unsigned long m_base; +}; +#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_) +#else +#define SPC(_value_) +#endif + +// +// Helpers +// + +// +template +static inline void listappend(T* item,T*& list) +{ + item->links[0]=0; + item->links[1]=list; + if(list) list->links[0]=item; + list=item; +} + +// +template +static inline void listremove(T* item,T*& list) +{ + if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1]; + if(item->links[1]) item->links[1]->links[0]=item->links[0]; +} + +// +template +static inline int listcount(T* root) +{ + int n=0; + while(root) { ++n;root=root->links[1]; } + return(n); +} + +// +template +static inline void clear(T& value) +{ + static const struct ZeroDummy : T {} zerodummy; + value=zerodummy; +} + +// +// Colliders +// + +/* Tree collider */ +struct btDbvtTreeCollider : btDbvt::ICollide +{ + btDbvtBroadphase* pbp; + btDbvtProxy* proxy; + btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {} + void Process(const btDbvtNode* na,const btDbvtNode* nb) + { + if(na!=nb) + { + btDbvtProxy* pa=(btDbvtProxy*)na->data; + btDbvtProxy* pb=(btDbvtProxy*)nb->data; +#if DBVT_BP_SORTPAIRS + if(pa->m_uniqueId>pb->m_uniqueId) + btSwap(pa,pb); +#endif + pbp->m_paircache->addOverlappingPair(pa,pb); + ++pbp->m_newpairs; + } + } + void Process(const btDbvtNode* n) + { + Process(n,proxy->leaf); + } +}; + +// +// btDbvtBroadphase +// + +// +btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache) +{ + m_deferedcollide = false; + m_needcleanup = true; + m_releasepaircache = (paircache!=0)?false:true; + m_prediction = 0; + m_stageCurrent = 0; + m_fixedleft = 0; + m_fupdates = 1; + m_dupdates = 0; + m_cupdates = 10; + m_newpairs = 1; + m_updates_call = 0; + m_updates_done = 0; + m_updates_ratio = 0; + m_paircache = paircache? paircache : new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); + m_gid = 0; + m_pid = 0; + m_cid = 0; + for(int i=0;i<=STAGECOUNT;++i) + { + m_stageRoots[i]=0; + } +#if DBVT_BP_PROFILE + clear(m_profiling); +#endif +} + +// +btDbvtBroadphase::~btDbvtBroadphase() +{ + if(m_releasepaircache) + { + m_paircache->~btOverlappingPairCache(); + btAlignedFree(m_paircache); + } +} + +// +btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin, + const btVector3& aabbMax, + int /*shapeType*/, + void* userPtr, + short int collisionFilterGroup, + short int collisionFilterMask, + btDispatcher* /*dispatcher*/, + void* /*multiSapProxy*/) +{ + btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( aabbMin,aabbMax,userPtr, + collisionFilterGroup, + collisionFilterMask); + + btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); + + //bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); + proxy->stage = m_stageCurrent; + proxy->m_uniqueId = ++m_gid; + proxy->leaf = m_sets[0].insert(aabb,proxy); + listappend(proxy,m_stageRoots[m_stageCurrent]); + if(!m_deferedcollide) + { + btDbvtTreeCollider collider(this); + collider.proxy=proxy; + m_sets[0].collideTV(m_sets[0].m_root,aabb,collider); + m_sets[1].collideTV(m_sets[1].m_root,aabb,collider); + } + return(proxy); +} + +// +void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy, + btDispatcher* dispatcher) +{ + btDbvtProxy* proxy=(btDbvtProxy*)absproxy; + if(proxy->stage==STAGECOUNT) + m_sets[1].remove(proxy->leaf); + else + m_sets[0].remove(proxy->leaf); + listremove(proxy,m_stageRoots[proxy->stage]); + m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); + btAlignedFree(proxy); + m_needcleanup=true; +} + +void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const +{ + btDbvtProxy* proxy=(btDbvtProxy*)absproxy; + aabbMin = proxy->m_aabbMin; + aabbMax = proxy->m_aabbMax; +} + +struct BroadphaseRayTester : btDbvt::ICollide +{ + btBroadphaseRayCallback& m_rayCallback; + BroadphaseRayTester(btBroadphaseRayCallback& orgCallback) + :m_rayCallback(orgCallback) + { + } + void Process(const btDbvtNode* leaf) + { + btDbvtProxy* proxy=(btDbvtProxy*)leaf->data; + m_rayCallback.process(proxy); + } +}; + +void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) +{ + BroadphaseRayTester callback(rayCallback); + + m_sets[0].rayTestInternal( m_sets[0].m_root, + rayFrom, + rayTo, + rayCallback.m_rayDirectionInverse, + rayCallback.m_signs, + rayCallback.m_lambda_max, + aabbMin, + aabbMax, + callback); + + m_sets[1].rayTestInternal( m_sets[1].m_root, + rayFrom, + rayTo, + rayCallback.m_rayDirectionInverse, + rayCallback.m_signs, + rayCallback.m_lambda_max, + aabbMin, + aabbMax, + callback); + +} + + +struct BroadphaseAabbTester : btDbvt::ICollide +{ + btBroadphaseAabbCallback& m_aabbCallback; + BroadphaseAabbTester(btBroadphaseAabbCallback& orgCallback) + :m_aabbCallback(orgCallback) + { + } + void Process(const btDbvtNode* leaf) + { + btDbvtProxy* proxy=(btDbvtProxy*)leaf->data; + m_aabbCallback.process(proxy); + } +}; + +void btDbvtBroadphase::aabbTest(const btVector3& aabbMin,const btVector3& aabbMax,btBroadphaseAabbCallback& aabbCallback) +{ + BroadphaseAabbTester callback(aabbCallback); + + const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(aabbMin,aabbMax); + //process all children, that overlap with the given AABB bounds + m_sets[0].collideTV(m_sets[0].m_root,bounds,callback); + m_sets[1].collideTV(m_sets[1].m_root,bounds,callback); + +} + + + +// +void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, + const btVector3& aabbMin, + const btVector3& aabbMax, + btDispatcher* /*dispatcher*/) +{ + btDbvtProxy* proxy=(btDbvtProxy*)absproxy; + ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); +#if DBVT_BP_PREVENTFALSEUPDATE + if(NotEqual(aabb,proxy->leaf->volume)) +#endif + { + bool docollide=false; + if(proxy->stage==STAGECOUNT) + {/* fixed -> dynamic set */ + m_sets[1].remove(proxy->leaf); + proxy->leaf=m_sets[0].insert(aabb,proxy); + docollide=true; + } + else + {/* dynamic set */ + ++m_updates_call; + if(Intersect(proxy->leaf->volume,aabb)) + {/* Moving */ + + const btVector3 delta=aabbMin-proxy->m_aabbMin; + btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction); + if(delta[0]<0) velocity[0]=-velocity[0]; + if(delta[1]<0) velocity[1]=-velocity[1]; + if(delta[2]<0) velocity[2]=-velocity[2]; + if ( +#ifdef DBVT_BP_MARGIN + m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN) +#else + m_sets[0].update(proxy->leaf,aabb,velocity) +#endif + ) + { + ++m_updates_done; + docollide=true; + } + } + else + {/* Teleporting */ + m_sets[0].update(proxy->leaf,aabb); + ++m_updates_done; + docollide=true; + } + } + listremove(proxy,m_stageRoots[proxy->stage]); + proxy->m_aabbMin = aabbMin; + proxy->m_aabbMax = aabbMax; + proxy->stage = m_stageCurrent; + listappend(proxy,m_stageRoots[m_stageCurrent]); + if(docollide) + { + m_needcleanup=true; + if(!m_deferedcollide) + { + btDbvtTreeCollider collider(this); + m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); + } + } + } +} + + +// +void btDbvtBroadphase::setAabbForceUpdate( btBroadphaseProxy* absproxy, + const btVector3& aabbMin, + const btVector3& aabbMax, + btDispatcher* /*dispatcher*/) +{ + btDbvtProxy* proxy=(btDbvtProxy*)absproxy; + ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); + bool docollide=false; + if(proxy->stage==STAGECOUNT) + {/* fixed -> dynamic set */ + m_sets[1].remove(proxy->leaf); + proxy->leaf=m_sets[0].insert(aabb,proxy); + docollide=true; + } + else + {/* dynamic set */ + ++m_updates_call; + /* Teleporting */ + m_sets[0].update(proxy->leaf,aabb); + ++m_updates_done; + docollide=true; + } + listremove(proxy,m_stageRoots[proxy->stage]); + proxy->m_aabbMin = aabbMin; + proxy->m_aabbMax = aabbMax; + proxy->stage = m_stageCurrent; + listappend(proxy,m_stageRoots[m_stageCurrent]); + if(docollide) + { + m_needcleanup=true; + if(!m_deferedcollide) + { + btDbvtTreeCollider collider(this); + m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); + } + } +} + +// +void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +{ + collide(dispatcher); +#if DBVT_BP_PROFILE + if(0==(m_pid%DBVT_BP_PROFILING_RATE)) + { + printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs()); + unsigned int total=m_profiling.m_total; + if(total<=0) total=1; + printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE); + printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE); + printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE); + printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); + const unsigned long sum=m_profiling.m_ddcollide+ + m_profiling.m_fdcollide+ + m_profiling.m_cleanup; + printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); + printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE)); + clear(m_profiling); + m_clock.reset(); + } +#endif + + performDeferredRemoval(dispatcher); + +} + +void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher) +{ + + if (m_paircache->hasDeferredRemoval()) + { + + btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray(); + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); + + int invalidPair = 0; + + + int i; + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;ileaf->volume,pb->leaf->volume); + + if (hasOverlap) + { + needsRemoval = false; + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + m_paircache->cleanOverlappingPair(pair,dispatcher); + + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + invalidPair++; + } + + } + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); + overlappingPairArray.resize(overlappingPairArray.size() - invalidPair); + } +} + +// +void btDbvtBroadphase::collide(btDispatcher* dispatcher) +{ + /*printf("---------------------------------------------------------\n"); + printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves); + printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves); + printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs()); + { + int i; + for (i=0;igetNumOverlappingPairs();i++) + { + printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(), + getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid()); + } + printf("\n"); + } +*/ + + + + SPC(m_profiling.m_total); + /* optimize */ + m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); + if(m_fixedleft) + { + const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; + m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); + m_fixedleft=btMax(0,m_fixedleft-count); + } + /* dynamic -> fixed set */ + m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; + btDbvtProxy* current=m_stageRoots[m_stageCurrent]; + if(current) + { + btDbvtTreeCollider collider(this); + do { + btDbvtProxy* next=current->links[1]; + listremove(current,m_stageRoots[current->stage]); + listappend(current,m_stageRoots[STAGECOUNT]); +#if DBVT_BP_ACCURATESLEEPING + m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); + collider.proxy=current; + btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); + btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); +#endif + m_sets[0].remove(current->leaf); + ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); + current->leaf = m_sets[1].insert(curAabb,current); + current->stage = STAGECOUNT; + current = next; + } while(current); + m_fixedleft=m_sets[1].m_leaves; + m_needcleanup=true; + } + /* collide dynamics */ + { + btDbvtTreeCollider collider(this); + if(m_deferedcollide) + { + SPC(m_profiling.m_fdcollide); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider); + } + if(m_deferedcollide) + { + SPC(m_profiling.m_ddcollide); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider); + } + } + /* clean up */ + if(m_needcleanup) + { + SPC(m_profiling.m_cleanup); + btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); + if(pairs.size()>0) + { + + int ni=btMin(pairs.size(),btMax(m_newpairs,(pairs.size()*m_cupdates)/100)); + for(int i=0;ileaf->volume,pb->leaf->volume)) + { +#if DBVT_BP_SORTPAIRS + if(pa->m_uniqueId>pb->m_uniqueId) + btSwap(pa,pb); +#endif + m_paircache->removeOverlappingPair(pa,pb,dispatcher); + --ni;--i; + } + } + if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; + } + } + ++m_pid; + m_newpairs=1; + m_needcleanup=false; + if(m_updates_call>0) + { m_updates_ratio=m_updates_done/(btScalar)m_updates_call; } + else + { m_updates_ratio=0; } + m_updates_done/=2; + m_updates_call/=2; +} + +// +void btDbvtBroadphase::optimize() +{ + m_sets[0].optimizeTopDown(); + m_sets[1].optimizeTopDown(); +} + +// +btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() +{ + return(m_paircache); +} + +// +const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const +{ + return(m_paircache); +} + +// +void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const +{ + + ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds; + + if(!m_sets[0].empty()) + if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, + m_sets[1].m_root->volume,bounds); + else + bounds=m_sets[0].m_root->volume; + else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; + else + bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0); + aabbMin=bounds.Mins(); + aabbMax=bounds.Maxs(); +} + +void btDbvtBroadphase::resetPool(btDispatcher* dispatcher) +{ + + int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves; + if (!totalObjects) + { + //reset internal dynamic tree data structures + m_sets[0].clear(); + m_sets[1].clear(); + + m_deferedcollide = false; + m_needcleanup = true; + m_stageCurrent = 0; + m_fixedleft = 0; + m_fupdates = 1; + m_dupdates = 0; + m_cupdates = 10; + m_newpairs = 1; + m_updates_call = 0; + m_updates_done = 0; + m_updates_ratio = 0; + + m_gid = 0; + m_pid = 0; + m_cid = 0; + for(int i=0;i<=STAGECOUNT;++i) + { + m_stageRoots[i]=0; + } + } +} + +// +void btDbvtBroadphase::printStats() +{} + +// +#if DBVT_BP_ENABLE_BENCHMARK + +struct btBroadphaseBenchmark +{ + struct Experiment + { + const char* name; + int object_count; + int update_count; + int spawn_count; + int iterations; + btScalar speed; + btScalar amplitude; + }; + struct Object + { + btVector3 center; + btVector3 extents; + btBroadphaseProxy* proxy; + btScalar time; + void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi) + { + time += speed; + center[0] = btCos(time*(btScalar)2.17)*amplitude+ + btSin(time)*amplitude/2; + center[1] = btCos(time*(btScalar)1.38)*amplitude+ + btSin(time)*amplitude; + center[2] = btSin(time*(btScalar)0.777)*amplitude; + pbi->setAabb(proxy,center-extents,center+extents,0); + } + }; + static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); } + static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); } + static void OutputTime(const char* name,btClock& c,unsigned count=0) + { + const unsigned long us=c.getTimeMicroseconds(); + const unsigned long ms=(us+500)/1000; + const btScalar sec=us/(btScalar)(1000*1000); + if(count>0) + printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec); + else + printf("%s : %u us (%u ms)\r\n",name,us,ms); + } +}; + +void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi) +{ + static const btBroadphaseBenchmark::Experiment experiments[]= + { + {"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100}, + /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100}, + {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/ + }; + static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]); + btAlignedObjectArray objects; + btClock wallclock; + /* Begin */ + for(int iexp=0;iexpcenter[0]=btBroadphaseBenchmark::UnitRand()*50; + po->center[1]=btBroadphaseBenchmark::UnitRand()*50; + po->center[2]=btBroadphaseBenchmark::UnitRand()*50; + po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2; + po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2; + po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2; + po->time=btBroadphaseBenchmark::UnitRand()*2000; + po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0); + objects.push_back(po); + } + btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock); + /* First update */ + wallclock.reset(); + for(int i=0;iupdate(speed,amplitude,pbi); + } + btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock); + /* Updates */ + wallclock.reset(); + for(int i=0;iupdate(speed,amplitude,pbi); + } + pbi->calculateOverlappingPairs(0); + } + btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations); + /* Clean up */ + wallclock.reset(); + for(int i=0;idestroyProxy(objects[i]->proxy,0); + delete objects[i]; + } + objects.resize(0); + btBroadphaseBenchmark::OutputTime("\tRelease",wallclock); + } + +} +#else +void btDbvtBroadphase::benchmark(btBroadphaseInterface*) +{} +#endif + +#if DBVT_BP_PROFILE +#undef SPC +#endif + diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h new file mode 100644 index 0000000..18b64ad --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h @@ -0,0 +1,146 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///btDbvtBroadphase implementation by Nathanael Presson +#ifndef BT_DBVT_BROADPHASE_H +#define BT_DBVT_BROADPHASE_H + +#include "BulletCollision/BroadphaseCollision/btDbvt.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" + +// +// Compile time config +// + +#define DBVT_BP_PROFILE 0 +//#define DBVT_BP_SORTPAIRS 1 +#define DBVT_BP_PREVENTFALSEUPDATE 0 +#define DBVT_BP_ACCURATESLEEPING 0 +#define DBVT_BP_ENABLE_BENCHMARK 0 +#define DBVT_BP_MARGIN (btScalar)0.05 + +#if DBVT_BP_PROFILE +#define DBVT_BP_PROFILING_RATE 256 +#include "LinearMath/btQuickprof.h" +#endif + +// +// btDbvtProxy +// +struct btDbvtProxy : btBroadphaseProxy +{ + /* Fields */ + //btDbvtAabbMm aabb; + btDbvtNode* leaf; + btDbvtProxy* links[2]; + int stage; + /* ctor */ + btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) : + btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask) + { + links[0]=links[1]=0; + } +}; + +typedef btAlignedObjectArray btDbvtProxyArray; + +///The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees (see btDbvt). +///One tree is used for static/non-moving objects, and another tree is used for dynamic objects. Objects can move from one tree to the other. +///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases btAxisSweep3 and bt32BitAxisSweep3. +struct btDbvtBroadphase : btBroadphaseInterface +{ + /* Config */ + enum { + DYNAMIC_SET = 0, /* Dynamic set index */ + FIXED_SET = 1, /* Fixed set index */ + STAGECOUNT = 2 /* Number of stages */ + }; + /* Fields */ + btDbvt m_sets[2]; // Dbvt sets + btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list + btOverlappingPairCache* m_paircache; // Pair cache + btScalar m_prediction; // Velocity prediction + int m_stageCurrent; // Current stage + int m_fupdates; // % of fixed updates per frame + int m_dupdates; // % of dynamic updates per frame + int m_cupdates; // % of cleanup updates per frame + int m_newpairs; // Number of pairs created + int m_fixedleft; // Fixed optimization left + unsigned m_updates_call; // Number of updates call + unsigned m_updates_done; // Number of updates done + btScalar m_updates_ratio; // m_updates_done/m_updates_call + int m_pid; // Parse id + int m_cid; // Cleanup index + int m_gid; // Gen id + bool m_releasepaircache; // Release pair cache on delete + bool m_deferedcollide; // Defere dynamic/static collision to collide call + bool m_needcleanup; // Need to run cleanup? +#if DBVT_BP_PROFILE + btClock m_clock; + struct { + unsigned long m_total; + unsigned long m_ddcollide; + unsigned long m_fdcollide; + unsigned long m_cleanup; + unsigned long m_jobcount; + } m_profiling; +#endif + /* Methods */ + btDbvtBroadphase(btOverlappingPairCache* paircache=0); + ~btDbvtBroadphase(); + void collide(btDispatcher* dispatcher); + void optimize(); + + /* btBroadphaseInterface Implementation */ + btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)); + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); + + virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + virtual btOverlappingPairCache* getOverlappingPairCache(); + virtual const btOverlappingPairCache* getOverlappingPairCache() const; + virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; + virtual void printStats(); + + + ///reset broadphase internal structures, to ensure determinism/reproducability + virtual void resetPool(btDispatcher* dispatcher); + + void performDeferredRemoval(btDispatcher* dispatcher); + + void setVelocityPrediction(btScalar prediction) + { + m_prediction = prediction; + } + btScalar getVelocityPrediction() const + { + return m_prediction; + } + + ///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. + ///it is not part of the btBroadphaseInterface but specific to btDbvtBroadphase. + ///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see + ///http://code.google.com/p/bullet/issues/detail?id=223 + void setAabbForceUpdate( btBroadphaseProxy* absproxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* /*dispatcher*/); + + static void benchmark(btBroadphaseInterface*); + + +}; + +#endif diff --git a/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp b/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp new file mode 100644 index 0000000..2076822 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp @@ -0,0 +1,22 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btDispatcher.h" + +btDispatcher::~btDispatcher() +{ + +} + diff --git a/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/src/BulletCollision/BroadphaseCollision/btDispatcher.h new file mode 100644 index 0000000..1ebb377 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btDispatcher.h @@ -0,0 +1,110 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_DISPATCHER_H +#define BT_DISPATCHER_H +#include "LinearMath/btScalar.h" + +class btCollisionAlgorithm; +struct btBroadphaseProxy; +class btRigidBody; +class btCollisionObject; +class btOverlappingPairCache; +struct btCollisionObjectWrapper; + +class btPersistentManifold; +class btStackAlloc; +class btPoolAllocator; + +struct btDispatcherInfo +{ + enum DispatchFunc + { + DISPATCH_DISCRETE = 1, + DISPATCH_CONTINUOUS + }; + btDispatcherInfo() + :m_timeStep(btScalar(0.)), + m_stepCount(0), + m_dispatchFunc(DISPATCH_DISCRETE), + m_timeOfImpact(btScalar(1.)), + m_useContinuous(true), + m_debugDraw(0), + m_enableSatConvex(false), + m_enableSPU(true), + m_useEpa(true), + m_allowedCcdPenetration(btScalar(0.04)), + m_useConvexConservativeDistanceUtil(false), + m_convexConservativeDistanceThreshold(0.0f), + m_stackAllocator(0) + { + + } + btScalar m_timeStep; + int m_stepCount; + int m_dispatchFunc; + mutable btScalar m_timeOfImpact; + bool m_useContinuous; + class btIDebugDraw* m_debugDraw; + bool m_enableSatConvex; + bool m_enableSPU; + bool m_useEpa; + btScalar m_allowedCcdPenetration; + bool m_useConvexConservativeDistanceUtil; + btScalar m_convexConservativeDistanceThreshold; + btStackAlloc* m_stackAllocator; +}; + +///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs. +///For example for pairwise collision detection, calculating contact points stored in btPersistentManifold or user callbacks (game logic). +class btDispatcher +{ + + +public: + virtual ~btDispatcher() ; + + virtual btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold=0) = 0; + + virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1)=0; + + virtual void releaseManifold(btPersistentManifold* manifold)=0; + + virtual void clearManifold(btPersistentManifold* manifold)=0; + + virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1) = 0; + + virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1)=0; + + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) =0; + + virtual int getNumManifolds() const = 0; + + virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0; + + virtual btPersistentManifold** getInternalManifoldPointer() = 0; + + virtual btPoolAllocator* getInternalManifoldPool() = 0; + + virtual const btPoolAllocator* getInternalManifoldPool() const = 0; + + virtual void* allocateCollisionAlgorithm(int size) = 0; + + virtual void freeCollisionAlgorithm(void* ptr) = 0; + +}; + + +#endif //BT_DISPATCHER_H diff --git a/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp new file mode 100644 index 0000000..81369fe --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp @@ -0,0 +1,489 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btMultiSapBroadphase.h" + +#include "btSimpleBroadphase.h" +#include "LinearMath/btAabbUtil2.h" +#include "btQuantizedBvh.h" + +/// btSapBroadphaseArray m_sapBroadphases; + +/// btOverlappingPairCache* m_overlappingPairs; +extern int gOverlappingPairs; + +/* +class btMultiSapSortedOverlappingPairCache : public btSortedOverlappingPairCache +{ +public: + + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + { + return btSortedOverlappingPairCache::addOverlappingPair((btBroadphaseProxy*)proxy0->m_multiSapParentProxy,(btBroadphaseProxy*)proxy1->m_multiSapParentProxy); + } +}; + +*/ + +btMultiSapBroadphase::btMultiSapBroadphase(int /*maxProxies*/,btOverlappingPairCache* pairCache) +:m_overlappingPairs(pairCache), +m_optimizedAabbTree(0), +m_ownsPairCache(false), +m_invalidPair(0) +{ + if (!m_overlappingPairs) + { + m_ownsPairCache = true; + void* mem = btAlignedAlloc(sizeof(btSortedOverlappingPairCache),16); + m_overlappingPairs = new (mem)btSortedOverlappingPairCache(); + } + + struct btMultiSapOverlapFilterCallback : public btOverlapFilterCallback + { + virtual ~btMultiSapOverlapFilterCallback() + {} + // return true when pairs need collision + virtual bool needBroadphaseCollision(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) const + { + btBroadphaseProxy* multiProxy0 = (btBroadphaseProxy*)childProxy0->m_multiSapParentProxy; + btBroadphaseProxy* multiProxy1 = (btBroadphaseProxy*)childProxy1->m_multiSapParentProxy; + + bool collides = (multiProxy0->m_collisionFilterGroup & multiProxy1->m_collisionFilterMask) != 0; + collides = collides && (multiProxy1->m_collisionFilterGroup & multiProxy0->m_collisionFilterMask); + + return collides; + } + }; + + void* mem = btAlignedAlloc(sizeof(btMultiSapOverlapFilterCallback),16); + m_filterCallback = new (mem)btMultiSapOverlapFilterCallback(); + + m_overlappingPairs->setOverlapFilterCallback(m_filterCallback); +// mem = btAlignedAlloc(sizeof(btSimpleBroadphase),16); +// m_simpleBroadphase = new (mem) btSimpleBroadphase(maxProxies,m_overlappingPairs); +} + +btMultiSapBroadphase::~btMultiSapBroadphase() +{ + if (m_ownsPairCache) + { + m_overlappingPairs->~btOverlappingPairCache(); + btAlignedFree(m_overlappingPairs); + } +} + + +void btMultiSapBroadphase::buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax) +{ + m_optimizedAabbTree = new btQuantizedBvh(); + m_optimizedAabbTree->setQuantizationValues(bvhAabbMin,bvhAabbMax); + QuantizedNodeArray& nodes = m_optimizedAabbTree->getLeafNodeArray(); + for (int i=0;igetBroadphaseAabb(aabbMin,aabbMax); + m_optimizedAabbTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0); + m_optimizedAabbTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1); + int partId = 0; + node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | i; + nodes.push_back(node); + } + m_optimizedAabbTree->buildInternal(); +} + +btBroadphaseProxy* btMultiSapBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* /*ignoreMe*/) +{ + //void* ignoreMe -> we could think of recursive multi-sap, if someone is interested + + void* mem = btAlignedAlloc(sizeof(btMultiSapProxy),16); + btMultiSapProxy* proxy = new (mem)btMultiSapProxy(aabbMin, aabbMax,shapeType,userPtr, collisionFilterGroup,collisionFilterMask); + m_multiSapProxies.push_back(proxy); + + ///this should deal with inserting/removal into child broadphases + setAabb(proxy,aabbMin,aabbMax,dispatcher); + return proxy; +} + +void btMultiSapBroadphase::destroyProxy(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/) +{ + ///not yet + btAssert(0); + +} + + +void btMultiSapBroadphase::addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase) +{ + void* mem = btAlignedAlloc(sizeof(btBridgeProxy),16); + btBridgeProxy* bridgeProxyRef = new(mem) btBridgeProxy; + bridgeProxyRef->m_childProxy = childProxy; + bridgeProxyRef->m_childBroadphase = childBroadphase; + parentMultiSapProxy->m_bridgeProxies.push_back(bridgeProxyRef); +} + + +bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax); +bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax) +{ +return +amin.getX() >= bmin.getX() && amax.getX() <= bmax.getX() && +amin.getY() >= bmin.getY() && amax.getY() <= bmax.getY() && +amin.getZ() >= bmin.getZ() && amax.getZ() <= bmax.getZ(); +} + + + + + + +void btMultiSapBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +{ + btMultiSapProxy* multiProxy = static_cast(proxy); + aabbMin = multiProxy->m_aabbMin; + aabbMax = multiProxy->m_aabbMax; +} + +void btMultiSapBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax) +{ + for (int i=0;i + +void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher) +{ + btMultiSapProxy* multiProxy = static_cast(proxy); + multiProxy->m_aabbMin = aabbMin; + multiProxy->m_aabbMax = aabbMax; + + +// bool fullyContained = false; +// bool alreadyInSimple = false; + + + + + struct MyNodeOverlapCallback : public btNodeOverlapCallback + { + btMultiSapBroadphase* m_multiSap; + btMultiSapProxy* m_multiProxy; + btDispatcher* m_dispatcher; + + MyNodeOverlapCallback(btMultiSapBroadphase* multiSap,btMultiSapProxy* multiProxy,btDispatcher* dispatcher) + :m_multiSap(multiSap), + m_multiProxy(multiProxy), + m_dispatcher(dispatcher) + { + + } + + virtual void processNode(int /*nodeSubPart*/, int broadphaseIndex) + { + btBroadphaseInterface* childBroadphase = m_multiSap->getBroadphaseArray()[broadphaseIndex]; + + int containingBroadphaseIndex = -1; + //already found? + for (int i=0;im_bridgeProxies.size();i++) + { + + if (m_multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase) + { + containingBroadphaseIndex = i; + break; + } + } + if (containingBroadphaseIndex<0) + { + //add it + btBroadphaseProxy* childProxy = childBroadphase->createProxy(m_multiProxy->m_aabbMin,m_multiProxy->m_aabbMax,m_multiProxy->m_shapeType,m_multiProxy->m_clientObject,m_multiProxy->m_collisionFilterGroup,m_multiProxy->m_collisionFilterMask, m_dispatcher,m_multiProxy); + m_multiSap->addToChildBroadphase(m_multiProxy,childProxy,childBroadphase); + + } + } + }; + + MyNodeOverlapCallback myNodeCallback(this,multiProxy,dispatcher); + + + + + if (m_optimizedAabbTree) + m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); + + int i; + + for ( i=0;im_bridgeProxies.size();i++) + { + btVector3 worldAabbMin,worldAabbMax; + multiProxy->m_bridgeProxies[i]->m_childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax); + bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax); + if (!overlapsBroadphase) + { + //remove it now + btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[i]; + + btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy; + bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher); + + multiProxy->m_bridgeProxies.swap( i,multiProxy->m_bridgeProxies.size()-1); + multiProxy->m_bridgeProxies.pop_back(); + + } + } + + + /* + + if (1) + { + + //find broadphase that contain this multiProxy + int numChildBroadphases = getBroadphaseArray().size(); + for (int i=0;igetBroadphaseAabb(worldAabbMin,worldAabbMax); + bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax); + + // fullyContained = fullyContained || boxIsContainedWithinBox(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax); + int containingBroadphaseIndex = -1; + + //if already contains this + + for (int i=0;im_bridgeProxies.size();i++) + { + if (multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase) + { + containingBroadphaseIndex = i; + } + alreadyInSimple = alreadyInSimple || (multiProxy->m_bridgeProxies[i]->m_childBroadphase == m_simpleBroadphase); + } + + if (overlapsBroadphase) + { + if (containingBroadphaseIndex<0) + { + btBroadphaseProxy* childProxy = childBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher); + childProxy->m_multiSapParentProxy = multiProxy; + addToChildBroadphase(multiProxy,childProxy,childBroadphase); + } + } else + { + if (containingBroadphaseIndex>=0) + { + //remove + btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[containingBroadphaseIndex]; + + btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy; + bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher); + + multiProxy->m_bridgeProxies.swap( containingBroadphaseIndex,multiProxy->m_bridgeProxies.size()-1); + multiProxy->m_bridgeProxies.pop_back(); + } + } + } + + + ///If we are in no other child broadphase, stick the proxy in the global 'simple' broadphase (brute force) + ///hopefully we don't end up with many entries here (can assert/provide feedback on stats) + if (0)//!multiProxy->m_bridgeProxies.size()) + { + ///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision + ///this is needed to be able to calculate the aabb overlap + btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher); + childProxy->m_multiSapParentProxy = multiProxy; + addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase); + } + } + + if (!multiProxy->m_bridgeProxies.size()) + { + ///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision + ///this is needed to be able to calculate the aabb overlap + btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher); + childProxy->m_multiSapParentProxy = multiProxy; + addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase); + } +*/ + + + //update + for ( i=0;im_bridgeProxies.size();i++) + { + btBridgeProxy* bridgeProxyRef = multiProxy->m_bridgeProxies[i]; + bridgeProxyRef->m_childBroadphase->setAabb(bridgeProxyRef->m_childProxy,aabbMin,aabbMax,dispatcher); + } + +} +bool stopUpdating=false; + + + +class btMultiSapBroadphasePairSortPredicate +{ + public: + + bool operator() ( const btBroadphasePair& a1, const btBroadphasePair& b1 ) const + { + btMultiSapBroadphase::btMultiSapProxy* aProxy0 = a1.m_pProxy0 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy0->m_multiSapParentProxy : 0; + btMultiSapBroadphase::btMultiSapProxy* aProxy1 = a1.m_pProxy1 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy1->m_multiSapParentProxy : 0; + btMultiSapBroadphase::btMultiSapProxy* bProxy0 = b1.m_pProxy0 ? (btMultiSapBroadphase::btMultiSapProxy*)b1.m_pProxy0->m_multiSapParentProxy : 0; + btMultiSapBroadphase::btMultiSapProxy* bProxy1 = b1.m_pProxy1 ? (btMultiSapBroadphase::btMultiSapProxy*)b1.m_pProxy1->m_multiSapParentProxy : 0; + + return aProxy0 > bProxy0 || + (aProxy0 == bProxy0 && aProxy1 > bProxy1) || + (aProxy0 == bProxy0 && aProxy1 == bProxy1 && a1.m_algorithm > b1.m_algorithm); + } +}; + + + ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb +void btMultiSapBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +{ + +// m_simpleBroadphase->calculateOverlappingPairs(dispatcher); + + if (!stopUpdating && getOverlappingPairCache()->hasDeferredRemoval()) + { + + btBroadphasePairArray& overlappingPairArray = getOverlappingPairCache()->getOverlappingPairArray(); + + // quicksort(overlappingPairArray,0,overlappingPairArray.size()); + + overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate()); + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + // overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + + + int i; + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;im_multiSapParentProxy : 0; + btMultiSapProxy* aProxy1 = pair.m_pProxy1 ? (btMultiSapProxy*)pair.m_pProxy1->m_multiSapParentProxy : 0; + btMultiSapProxy* bProxy0 = previousPair.m_pProxy0 ? (btMultiSapProxy*)previousPair.m_pProxy0->m_multiSapParentProxy : 0; + btMultiSapProxy* bProxy1 = previousPair.m_pProxy1 ? (btMultiSapProxy*)previousPair.m_pProxy1->m_multiSapParentProxy : 0; + + bool isDuplicate = (aProxy0 == bProxy0) && (aProxy1 == bProxy1); + + previousPair = pair; + + bool needsRemoval = false; + + if (!isDuplicate) + { + bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1); + + if (hasOverlap) + { + needsRemoval = false;//callback->processOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + getOverlappingPairCache()->cleanOverlappingPair(pair,dispatcher); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } + + ///if you don't like to skip the invalid pairs in the array, execute following code: + #define CLEAN_INVALID_PAIRS 1 + #ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + //overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate()); + overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + #endif//CLEAN_INVALID_PAIRS + + //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size()); + } + + +} + + +bool btMultiSapBroadphase::testAabbOverlap(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) +{ + btMultiSapProxy* multiSapProxy0 = (btMultiSapProxy*)childProxy0->m_multiSapParentProxy; + btMultiSapProxy* multiSapProxy1 = (btMultiSapProxy*)childProxy1->m_multiSapParentProxy; + + return TestAabbAgainstAabb2(multiSapProxy0->m_aabbMin,multiSapProxy0->m_aabbMax, + multiSapProxy1->m_aabbMin,multiSapProxy1->m_aabbMax); + +} + + +void btMultiSapBroadphase::printStats() +{ +/* printf("---------------------------------\n"); + + printf("btMultiSapBroadphase.h\n"); + printf("numHandles = %d\n",m_multiSapProxies.size()); + //find broadphase that contain this multiProxy + int numChildBroadphases = getBroadphaseArray().size(); + for (int i=0;iprintStats(); + + } + */ + +} + +void btMultiSapBroadphase::resetPool(btDispatcher* dispatcher) +{ + // not yet +} diff --git a/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h b/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h new file mode 100644 index 0000000..7bcfe6b --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h @@ -0,0 +1,151 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_MULTI_SAP_BROADPHASE +#define BT_MULTI_SAP_BROADPHASE + +#include "btBroadphaseInterface.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "btOverlappingPairCache.h" + + +class btBroadphaseInterface; +class btSimpleBroadphase; + + +typedef btAlignedObjectArray btSapBroadphaseArray; + +///The btMultiSapBroadphase is a research project, not recommended to use in production. Use btAxisSweep3 or btDbvtBroadphase instead. +///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases. +///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time. +///A btQuantizedBvh acceleration structures finds overlapping SAPs for each btBroadphaseProxy. +///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=328 +///and http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329 +class btMultiSapBroadphase :public btBroadphaseInterface +{ + btSapBroadphaseArray m_sapBroadphases; + + btSimpleBroadphase* m_simpleBroadphase; + + btOverlappingPairCache* m_overlappingPairs; + + class btQuantizedBvh* m_optimizedAabbTree; + + + bool m_ownsPairCache; + + btOverlapFilterCallback* m_filterCallback; + + int m_invalidPair; + + struct btBridgeProxy + { + btBroadphaseProxy* m_childProxy; + btBroadphaseInterface* m_childBroadphase; + }; + + +public: + + struct btMultiSapProxy : public btBroadphaseProxy + { + + ///array with all the entries that this proxy belongs to + btAlignedObjectArray m_bridgeProxies; + btVector3 m_aabbMin; + btVector3 m_aabbMax; + + int m_shapeType; + +/* void* m_userPtr; + short int m_collisionFilterGroup; + short int m_collisionFilterMask; +*/ + btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) + :btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask), + m_aabbMin(aabbMin), + m_aabbMax(aabbMax), + m_shapeType(shapeType) + { + m_multiSapParentProxy =this; + } + + + }; + +protected: + + + btAlignedObjectArray m_multiSapProxies; + +public: + + btMultiSapBroadphase(int maxProxies = 16384,btOverlappingPairCache* pairCache=0); + + + btSapBroadphaseArray& getBroadphaseArray() + { + return m_sapBroadphases; + } + + const btSapBroadphaseArray& getBroadphaseArray() const + { + return m_sapBroadphases; + } + + virtual ~btMultiSapBroadphase(); + + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy); + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); + virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; + + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0)); + + void addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase); + + ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + virtual btOverlappingPairCache* getOverlappingPairCache() + { + return m_overlappingPairs; + } + virtual const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_overlappingPairs; + } + + ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame + ///will add some transform later + virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const + { + aabbMin.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + aabbMax.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + } + + void buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax); + + virtual void printStats(); + + void quicksort (btBroadphasePairArray& a, int lo, int hi); + + ///reset broadphase internal structures, to ensure determinism/reproducability + virtual void resetPool(btDispatcher* dispatcher); + +}; + +#endif //BT_MULTI_SAP_BROADPHASE diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp new file mode 100644 index 0000000..041bbe0 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp @@ -0,0 +1,633 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btOverlappingPairCache.h" + +#include "btDispatcher.h" +#include "btCollisionAlgorithm.h" +#include "LinearMath/btAabbUtil2.h" + +#include + +int gOverlappingPairs = 0; + +int gRemovePairs =0; +int gAddedPairs =0; +int gFindPairs =0; + + + + +btHashedOverlappingPairCache::btHashedOverlappingPairCache(): + m_overlapFilterCallback(0), + m_blockedForChanges(false), + m_ghostPairCallback(0) +{ + int initialAllocatedSize= 2; + m_overlappingPairArray.reserve(initialAllocatedSize); + growTables(); +} + + + + +btHashedOverlappingPairCache::~btHashedOverlappingPairCache() +{ +} + + + +void btHashedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) +{ + if (pair.m_algorithm) + { + { + pair.m_algorithm->~btCollisionAlgorithm(); + dispatcher->freeCollisionAlgorithm(pair.m_algorithm); + pair.m_algorithm=0; + } + } +} + + + + +void btHashedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + + class CleanPairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_cleanProxy; + btOverlappingPairCache* m_pairCache; + btDispatcher* m_dispatcher; + + public: + CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) + :m_cleanProxy(cleanProxy), + m_pairCache(pairCache), + m_dispatcher(dispatcher) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + if ((pair.m_pProxy0 == m_cleanProxy) || + (pair.m_pProxy1 == m_cleanProxy)) + { + m_pairCache->cleanOverlappingPair(pair,m_dispatcher); + } + return false; + } + + }; + + CleanPairCallback cleanPairs(proxy,this,dispatcher); + + processAllOverlappingPairs(&cleanPairs,dispatcher); + +} + + + + +void btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + + class RemovePairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_obsoleteProxy; + + public: + RemovePairCallback(btBroadphaseProxy* obsoleteProxy) + :m_obsoleteProxy(obsoleteProxy) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + return ((pair.m_pProxy0 == m_obsoleteProxy) || + (pair.m_pProxy1 == m_obsoleteProxy)); + } + + }; + + + RemovePairCallback removeCallback(proxy); + + processAllOverlappingPairs(&removeCallback,dispatcher); +} + + + + + +btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) +{ + gFindPairs++; + if(proxy0->m_uniqueId>proxy1->m_uniqueId) + btSwap(proxy0,proxy1); + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + + /*if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2);*/ + + int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + + if (hash >= m_hashTable.size()) + { + return NULL; + } + + int index = m_hashTable[hash]; + while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) + { + index = m_next[index]; + } + + if (index == BT_NULL_PAIR) + { + return NULL; + } + + btAssert(index < m_overlappingPairArray.size()); + + return &m_overlappingPairArray[index]; +} + +//#include + +void btHashedOverlappingPairCache::growTables() +{ + + int newCapacity = m_overlappingPairArray.capacity(); + + if (m_hashTable.size() < newCapacity) + { + //grow hashtable and next table + int curHashtableSize = m_hashTable.size(); + + m_hashTable.resize(newCapacity); + m_next.resize(newCapacity); + + + int i; + + for (i= 0; i < newCapacity; ++i) + { + m_hashTable[i] = BT_NULL_PAIR; + } + for (i = 0; i < newCapacity; ++i) + { + m_next[i] = BT_NULL_PAIR; + } + + for(i=0;igetUid(); + int proxyId2 = pair.m_pProxy1->getUid(); + /*if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2);*/ + int hashValue = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask + m_next[i] = m_hashTable[hashValue]; + m_hashTable[hashValue] = i; + } + + + } +} + +btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) +{ + if(proxy0->m_uniqueId>proxy1->m_uniqueId) + btSwap(proxy0,proxy1); + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + + /*if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2);*/ + + int hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask + + + btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); + if (pair != NULL) + { + return pair; + } + /*for(int i=0;i%u\r\n",proxyId1,proxyId2); + internalFindPair(proxy0, proxy1, hash); + } + }*/ + int count = m_overlappingPairArray.size(); + int oldCapacity = m_overlappingPairArray.capacity(); + void* mem = &m_overlappingPairArray.expandNonInitializing(); + + //this is where we add an actual pair, so also call the 'ghost' + if (m_ghostPairCallback) + m_ghostPairCallback->addOverlappingPair(proxy0,proxy1); + + int newCapacity = m_overlappingPairArray.capacity(); + + if (oldCapacity < newCapacity) + { + growTables(); + //hash with new capacity + hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + } + + pair = new (mem) btBroadphasePair(*proxy0,*proxy1); +// pair->m_pProxy0 = proxy0; +// pair->m_pProxy1 = proxy1; + pair->m_algorithm = 0; + pair->m_internalTmpValue = 0; + + + m_next[count] = m_hashTable[hash]; + m_hashTable[hash] = count; + + return pair; +} + + + +void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher) +{ + gRemovePairs++; + if(proxy0->m_uniqueId>proxy1->m_uniqueId) + btSwap(proxy0,proxy1); + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + + /*if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2);*/ + + int hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + + btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); + if (pair == NULL) + { + return 0; + } + + cleanOverlappingPair(*pair,dispatcher); + + void* userData = pair->m_internalInfo1; + + btAssert(pair->m_pProxy0->getUid() == proxyId1); + btAssert(pair->m_pProxy1->getUid() == proxyId2); + + int pairIndex = int(pair - &m_overlappingPairArray[0]); + btAssert(pairIndex < m_overlappingPairArray.size()); + + // Remove the pair from the hash table. + int index = m_hashTable[hash]; + btAssert(index != BT_NULL_PAIR); + + int previous = BT_NULL_PAIR; + while (index != pairIndex) + { + previous = index; + index = m_next[index]; + } + + if (previous != BT_NULL_PAIR) + { + btAssert(m_next[previous] == pairIndex); + m_next[previous] = m_next[pairIndex]; + } + else + { + m_hashTable[hash] = m_next[pairIndex]; + } + + // We now move the last pair into spot of the + // pair being removed. We need to fix the hash + // table indices to support the move. + + int lastPairIndex = m_overlappingPairArray.size() - 1; + + if (m_ghostPairCallback) + m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher); + + // If the removed pair is the last pair, we are done. + if (lastPairIndex == pairIndex) + { + m_overlappingPairArray.pop_back(); + return userData; + } + + // Remove the last pair from the hash table. + const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex]; + /* missing swap here too, Nat. */ + int lastHash = static_cast(getHash(static_cast(last->m_pProxy0->getUid()), static_cast(last->m_pProxy1->getUid())) & (m_overlappingPairArray.capacity()-1)); + + index = m_hashTable[lastHash]; + btAssert(index != BT_NULL_PAIR); + + previous = BT_NULL_PAIR; + while (index != lastPairIndex) + { + previous = index; + index = m_next[index]; + } + + if (previous != BT_NULL_PAIR) + { + btAssert(m_next[previous] == lastPairIndex); + m_next[previous] = m_next[lastPairIndex]; + } + else + { + m_hashTable[lastHash] = m_next[lastPairIndex]; + } + + // Copy the last pair into the remove pair's spot. + m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex]; + + // Insert the last pair into the hash table + m_next[pairIndex] = m_hashTable[lastHash]; + m_hashTable[lastHash] = pairIndex; + + m_overlappingPairArray.pop_back(); + + return userData; +} +//#include + +void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) +{ + + int i; + +// printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size()); + for (i=0;iprocessOverlap(*pair)) + { + removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher); + + gOverlappingPairs--; + } else + { + i++; + } + } +} + +void btHashedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher) +{ + ///need to keep hashmap in sync with pair address, so rebuild all + btBroadphasePairArray tmpPairs; + int i; + for (i=0;iremoveOverlappingPair(proxy0, proxy1,dispatcher); + + m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1); + m_overlappingPairArray.pop_back(); + return userData; + } + } + + return 0; +} + + + + + + + + +btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + //don't add overlap with own + btAssert(proxy0 != proxy1); + + if (!needsBroadphaseCollision(proxy0,proxy1)) + return 0; + + void* mem = &m_overlappingPairArray.expandNonInitializing(); + btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1); + + gOverlappingPairs++; + gAddedPairs++; + + if (m_ghostPairCallback) + m_ghostPairCallback->addOverlappingPair(proxy0, proxy1); + return pair; + +} + +///this findPair becomes really slow. Either sort the list to speedup the query, or +///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed. +///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address) +///Also we can use a 2D bitmap, which can be useful for a future GPU implementation + btBroadphasePair* btSortedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + if (!needsBroadphaseCollision(proxy0,proxy1)) + return 0; + + btBroadphasePair tmpPair(*proxy0,*proxy1); + int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair); + + if (findIndex < m_overlappingPairArray.size()) + { + //btAssert(it != m_overlappingPairSet.end()); + btBroadphasePair* pair = &m_overlappingPairArray[findIndex]; + return pair; + } + return 0; +} + + + + + + + + + + +//#include + +void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) +{ + + int i; + + for (i=0;iprocessOverlap(*pair)) + { + cleanOverlappingPair(*pair,dispatcher); + pair->m_pProxy0 = 0; + pair->m_pProxy1 = 0; + m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + m_overlappingPairArray.pop_back(); + gOverlappingPairs--; + } else + { + i++; + } + } +} + + + + +btSortedOverlappingPairCache::btSortedOverlappingPairCache(): + m_blockedForChanges(false), + m_hasDeferredRemoval(true), + m_overlapFilterCallback(0), + m_ghostPairCallback(0) +{ + int initialAllocatedSize= 2; + m_overlappingPairArray.reserve(initialAllocatedSize); +} + +btSortedOverlappingPairCache::~btSortedOverlappingPairCache() +{ +} + +void btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) +{ + if (pair.m_algorithm) + { + { + pair.m_algorithm->~btCollisionAlgorithm(); + dispatcher->freeCollisionAlgorithm(pair.m_algorithm); + pair.m_algorithm=0; + gRemovePairs--; + } + } +} + + +void btSortedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + + class CleanPairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_cleanProxy; + btOverlappingPairCache* m_pairCache; + btDispatcher* m_dispatcher; + + public: + CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) + :m_cleanProxy(cleanProxy), + m_pairCache(pairCache), + m_dispatcher(dispatcher) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + if ((pair.m_pProxy0 == m_cleanProxy) || + (pair.m_pProxy1 == m_cleanProxy)) + { + m_pairCache->cleanOverlappingPair(pair,m_dispatcher); + } + return false; + } + + }; + + CleanPairCallback cleanPairs(proxy,this,dispatcher); + + processAllOverlappingPairs(&cleanPairs,dispatcher); + +} + + +void btSortedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + + class RemovePairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_obsoleteProxy; + + public: + RemovePairCallback(btBroadphaseProxy* obsoleteProxy) + :m_obsoleteProxy(obsoleteProxy) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + return ((pair.m_pProxy0 == m_obsoleteProxy) || + (pair.m_pProxy1 == m_obsoleteProxy)); + } + + }; + + RemovePairCallback removeCallback(proxy); + + processAllOverlappingPairs(&removeCallback,dispatcher); +} + +void btSortedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher) +{ + //should already be sorted +} + diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h new file mode 100644 index 0000000..7a3806c --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h @@ -0,0 +1,469 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_OVERLAPPING_PAIR_CACHE_H +#define BT_OVERLAPPING_PAIR_CACHE_H + + +#include "btBroadphaseInterface.h" +#include "btBroadphaseProxy.h" +#include "btOverlappingPairCallback.h" + +#include "LinearMath/btAlignedObjectArray.h" +class btDispatcher; + +typedef btAlignedObjectArray btBroadphasePairArray; + +struct btOverlapCallback +{ + virtual ~btOverlapCallback() + {} + //return true for deletion of the pair + virtual bool processOverlap(btBroadphasePair& pair) = 0; + +}; + +struct btOverlapFilterCallback +{ + virtual ~btOverlapFilterCallback() + {} + // return true when pairs need collision + virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0; +}; + + + + + + + +extern int gRemovePairs; +extern int gAddedPairs; +extern int gFindPairs; + +const int BT_NULL_PAIR=0xffffffff; + +///The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases. +///The btHashedOverlappingPairCache and btSortedOverlappingPairCache classes are two implementations. +class btOverlappingPairCache : public btOverlappingPairCallback +{ +public: + virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor + + virtual btBroadphasePair* getOverlappingPairArrayPtr() = 0; + + virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0; + + virtual btBroadphasePairArray& getOverlappingPairArray() = 0; + + virtual void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0; + + virtual int getNumOverlappingPairs() const = 0; + + virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0; + + virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0; + + virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0; + + virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0; + + virtual bool hasDeferredRemoval() = 0; + + virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0; + + virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0; + + +}; + +/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com +class btHashedOverlappingPairCache : public btOverlappingPairCache +{ + btBroadphasePairArray m_overlappingPairArray; + btOverlapFilterCallback* m_overlapFilterCallback; + bool m_blockedForChanges; + + +public: + btHashedOverlappingPairCache(); + virtual ~btHashedOverlappingPairCache(); + + + void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + + virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); + + SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const + { + if (m_overlapFilterCallback) + return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + + bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; + collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + + return collides; + } + + // Add a pair and return the new pair. If the pair already exists, + // no new pair is created and the old one is returned. + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + { + gAddedPairs++; + + if (!needsBroadphaseCollision(proxy0,proxy1)) + return 0; + + return internalAddPair(proxy0,proxy1); + } + + + + void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + + + virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); + + virtual btBroadphasePair* getOverlappingPairArrayPtr() + { + return &m_overlappingPairArray[0]; + } + + const btBroadphasePair* getOverlappingPairArrayPtr() const + { + return &m_overlappingPairArray[0]; + } + + btBroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } + + const btBroadphasePairArray& getOverlappingPairArray() const + { + return m_overlappingPairArray; + } + + void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); + + + + btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); + + int GetCount() const { return m_overlappingPairArray.size(); } +// btBroadphasePair* GetPairs() { return m_pairs; } + + btOverlapFilterCallback* getOverlapFilterCallback() + { + return m_overlapFilterCallback; + } + + void setOverlapFilterCallback(btOverlapFilterCallback* callback) + { + m_overlapFilterCallback = callback; + } + + int getNumOverlappingPairs() const + { + return m_overlappingPairArray.size(); + } +private: + + btBroadphasePair* internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + void growTables(); + + SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2) + { + return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2; + } + + /* + // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm + // This assumes proxyId1 and proxyId2 are 16-bit. + SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2) + { + int key = (proxyId2 << 16) | proxyId1; + key = ~key + (key << 15); + key = key ^ (key >> 12); + key = key + (key << 2); + key = key ^ (key >> 4); + key = key * 2057; + key = key ^ (key >> 16); + return key; + } + */ + + + + SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2) + { + int key = static_cast(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16)); + // Thomas Wang's hash + + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return static_cast(key); + } + + + + + + SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash) + { + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + #if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat. + if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2); + #endif + + int index = m_hashTable[hash]; + + while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) + { + index = m_next[index]; + } + + if ( index == BT_NULL_PAIR ) + { + return NULL; + } + + btAssert(index < m_overlappingPairArray.size()); + + return &m_overlappingPairArray[index]; + } + + virtual bool hasDeferredRemoval() + { + return false; + } + + virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) + { + m_ghostPairCallback = ghostPairCallback; + } + + virtual void sortOverlappingPairs(btDispatcher* dispatcher); + + +protected: + + btAlignedObjectArray m_hashTable; + btAlignedObjectArray m_next; + btOverlappingPairCallback* m_ghostPairCallback; + +}; + + + + +///btSortedOverlappingPairCache maintains the objects with overlapping AABB +///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase +class btSortedOverlappingPairCache : public btOverlappingPairCache +{ + protected: + //avoid brute-force finding all the time + btBroadphasePairArray m_overlappingPairArray; + + //during the dispatch, check that user doesn't destroy/create proxy + bool m_blockedForChanges; + + ///by default, do the removal during the pair traversal + bool m_hasDeferredRemoval; + + //if set, use the callback instead of the built in filter in needBroadphaseCollision + btOverlapFilterCallback* m_overlapFilterCallback; + + btOverlappingPairCallback* m_ghostPairCallback; + + public: + + btSortedOverlappingPairCache(); + virtual ~btSortedOverlappingPairCache(); + + virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); + + void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); + + void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); + + btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + + void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + + void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + + + inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const + { + if (m_overlapFilterCallback) + return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + + bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; + collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + + return collides; + } + + btBroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } + + const btBroadphasePairArray& getOverlappingPairArray() const + { + return m_overlappingPairArray; + } + + + + + btBroadphasePair* getOverlappingPairArrayPtr() + { + return &m_overlappingPairArray[0]; + } + + const btBroadphasePair* getOverlappingPairArrayPtr() const + { + return &m_overlappingPairArray[0]; + } + + int getNumOverlappingPairs() const + { + return m_overlappingPairArray.size(); + } + + btOverlapFilterCallback* getOverlapFilterCallback() + { + return m_overlapFilterCallback; + } + + void setOverlapFilterCallback(btOverlapFilterCallback* callback) + { + m_overlapFilterCallback = callback; + } + + virtual bool hasDeferredRemoval() + { + return m_hasDeferredRemoval; + } + + virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) + { + m_ghostPairCallback = ghostPairCallback; + } + + virtual void sortOverlappingPairs(btDispatcher* dispatcher); + + +}; + + + +///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing. +class btNullPairCache : public btOverlappingPairCache +{ + + btBroadphasePairArray m_overlappingPairArray; + +public: + + virtual btBroadphasePair* getOverlappingPairArrayPtr() + { + return &m_overlappingPairArray[0]; + } + const btBroadphasePair* getOverlappingPairArrayPtr() const + { + return &m_overlappingPairArray[0]; + } + btBroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } + + virtual void cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/) + { + + } + + virtual int getNumOverlappingPairs() const + { + return 0; + } + + virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/) + { + + } + + virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/) + { + } + + virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/) + { + } + + virtual btBroadphasePair* findPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/) + { + return 0; + } + + virtual bool hasDeferredRemoval() + { + return true; + } + + virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */) + { + + } + + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/) + { + return 0; + } + + virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/) + { + return 0; + } + + virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/) + { + } + + virtual void sortOverlappingPairs(btDispatcher* dispatcher) + { + (void) dispatcher; + } + + +}; + + +#endif //BT_OVERLAPPING_PAIR_CACHE_H + + diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h new file mode 100644 index 0000000..9c7b6f8 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h @@ -0,0 +1,40 @@ + +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef OVERLAPPING_PAIR_CALLBACK_H +#define OVERLAPPING_PAIR_CALLBACK_H + +class btDispatcher; +struct btBroadphasePair; + +///The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache. +class btOverlappingPairCallback +{ +public: + virtual ~btOverlappingPairCallback() + { + + } + + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0; + + virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher) = 0; + + virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher) = 0; + +}; + +#endif //OVERLAPPING_PAIR_CALLBACK_H diff --git a/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp new file mode 100644 index 0000000..c911435 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp @@ -0,0 +1,1375 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btQuantizedBvh.h" + +#include "LinearMath/btAabbUtil2.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btSerializer.h" + +#define RAYAABB2 + +btQuantizedBvh::btQuantizedBvh() : + m_bulletVersion(BT_BULLET_VERSION), + m_useQuantization(false), + //m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) + m_traversalMode(TRAVERSAL_STACKLESS) + //m_traversalMode(TRAVERSAL_RECURSIVE) + ,m_subtreeHeaderCount(0) //PCK: add this line +{ + m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY); + m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); +} + + + + + +void btQuantizedBvh::buildInternal() +{ + ///assumes that caller filled in the m_quantizedLeafNodes + m_useQuantization = true; + int numLeafNodes = 0; + + if (m_useQuantization) + { + //now we have an array of leafnodes in m_leafNodes + numLeafNodes = m_quantizedLeafNodes.size(); + + m_quantizedContiguousNodes.resize(2*numLeafNodes); + + } + + m_curNodeIndex = 0; + + buildTree(0,numLeafNodes); + + ///if the entire tree is small then subtree size, we need to create a header info for the tree + if(m_useQuantization && !m_SubtreeHeaders.size()) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); + subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); + subtree.m_rootNodeIndex = 0; + subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex(); + } + + //PCK: update the copy of the size + m_subtreeHeaderCount = m_SubtreeHeaders.size(); + + //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary + m_quantizedLeafNodes.clear(); + m_leafNodes.clear(); +} + + + +///just for debugging, to visualize the individual patches/subtrees +#ifdef DEBUG_PATCH_COLORS +btVector3 color[4]= +{ + btVector3(1,0,0), + btVector3(0,1,0), + btVector3(0,0,1), + btVector3(0,1,1) +}; +#endif //DEBUG_PATCH_COLORS + + + +void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin) +{ + //enlarge the AABB to avoid division by zero when initializing the quantization values + btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin); + m_bvhAabbMin = bvhAabbMin - clampValue; + m_bvhAabbMax = bvhAabbMax + clampValue; + btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin; + m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize; + m_useQuantization = true; +} + + + + +btQuantizedBvh::~btQuantizedBvh() +{ +} + +#ifdef DEBUG_TREE_BUILDING +int gStackDepth = 0; +int gMaxStackDepth = 0; +#endif //DEBUG_TREE_BUILDING + +void btQuantizedBvh::buildTree (int startIndex,int endIndex) +{ +#ifdef DEBUG_TREE_BUILDING + gStackDepth++; + if (gStackDepth > gMaxStackDepth) + gMaxStackDepth = gStackDepth; +#endif //DEBUG_TREE_BUILDING + + + int splitAxis, splitIndex, i; + int numIndices =endIndex-startIndex; + int curIndex = m_curNodeIndex; + + btAssert(numIndices>0); + + if (numIndices==1) + { +#ifdef DEBUG_TREE_BUILDING + gStackDepth--; +#endif //DEBUG_TREE_BUILDING + + assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex); + + m_curNodeIndex++; + return; + } + //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. + + splitAxis = calcSplittingAxis(startIndex,endIndex); + + splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis); + + int internalNodeIndex = m_curNodeIndex; + + //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value. + //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values + setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization + setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization + + + for (i=startIndex;im_escapeIndex; + + int leftChildNodexIndex = m_curNodeIndex; + + //build left child tree + buildTree(startIndex,splitIndex); + + int rightChildNodexIndex = m_curNodeIndex; + //build right child tree + buildTree(splitIndex,endIndex); + +#ifdef DEBUG_TREE_BUILDING + gStackDepth--; +#endif //DEBUG_TREE_BUILDING + + int escapeIndex = m_curNodeIndex - curIndex; + + if (m_useQuantization) + { + //escapeIndex is the number of nodes of this subtree + const int sizeQuantizedNode =sizeof(btQuantizedBvhNode); + const int treeSizeInBytes = escapeIndex * sizeQuantizedNode; + if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES) + { + updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex); + } + } else + { + + } + + setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex); + +} + +void btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex) +{ + btAssert(m_useQuantization); + + btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex]; + int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex(); + int leftSubTreeSizeInBytes = leftSubTreeSize * static_cast(sizeof(btQuantizedBvhNode)); + + btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex]; + int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex(); + int rightSubTreeSizeInBytes = rightSubTreeSize * static_cast(sizeof(btQuantizedBvhNode)); + + if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); + subtree.setAabbFromQuantizeNode(leftChildNode); + subtree.m_rootNodeIndex = leftChildNodexIndex; + subtree.m_subtreeSize = leftSubTreeSize; + } + + if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); + subtree.setAabbFromQuantizeNode(rightChildNode); + subtree.m_rootNodeIndex = rightChildNodexIndex; + subtree.m_subtreeSize = rightSubTreeSize; + } + + //PCK: update the copy of the size + m_subtreeHeaderCount = m_SubtreeHeaders.size(); +} + + +int btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis) +{ + int i; + int splitIndex =startIndex; + int numIndices = endIndex - startIndex; + btScalar splitValue; + + btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); + for (i=startIndex;i splitValue) + { + //swap + swapLeafNodes(i,splitIndex); + splitIndex++; + } + } + + //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex + //otherwise the tree-building might fail due to stack-overflows in certain cases. + //unbalanced1 is unsafe: it can cause stack overflows + //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); + + //unbalanced2 should work too: always use center (perfect balanced trees) + //bool unbalanced2 = true; + + //this should be safe too: + int rangeBalancedIndices = numIndices/3; + bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + + if (unbalanced) + { + splitIndex = startIndex+ (numIndices>>1); + } + + bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); + (void)unbal; + btAssert(!unbal); + + return splitIndex; +} + + +int btQuantizedBvh::calcSplittingAxis(int startIndex,int endIndex) +{ + int i; + + btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.)); + int numIndices = endIndex-startIndex; + + for (i=startIndex;im_aabbMinOrg,rootNode->m_aabbMaxOrg); + isLeafNode = rootNode->m_escapeIndex == -1; + + //PCK: unsigned instead of bool + if (isLeafNode && (aabbOverlap != 0)) + { + nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); + } + + //PCK: unsigned instead of bool + if ((aabbOverlap != 0) || isLeafNode) + { + rootNode++; + curIndex++; + } else + { + escapeIndex = rootNode->m_escapeIndex; + rootNode += escapeIndex; + curIndex += escapeIndex; + } + } + if (maxIterations < walkIterations) + maxIterations = walkIterations; + +} + +/* +///this was the original recursive traversal, before we optimized towards stackless traversal +void btQuantizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax); + if (aabbOverlap) + { + isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild); + if (isLeafNode) + { + nodeCallback->processNode(rootNode); + } else + { + walkTree(rootNode->m_leftChild,nodeCallback,aabbMin,aabbMax); + walkTree(rootNode->m_rightChild,nodeCallback,aabbMin,aabbMax); + } + } + +} +*/ + +void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +{ + btAssert(m_useQuantization); + + bool isLeafNode; + //PCK: unsigned instead of bool + unsigned aabbOverlap; + + //PCK: unsigned instead of bool + aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax); + isLeafNode = currentNode->isLeafNode(); + + //PCK: unsigned instead of bool + if (aabbOverlap != 0) + { + if (isLeafNode) + { + nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex()); + } else + { + //process left and right children + const btQuantizedBvhNode* leftChildNode = currentNode+1; + walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + + const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex(); + walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + } + } +} + + + +void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const +{ + btAssert(!m_useQuantization); + + const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0]; + int escapeIndex, curIndex = 0; + int walkIterations = 0; + bool isLeafNode; + //PCK: unsigned instead of bool + unsigned aabbOverlap=0; + unsigned rayBoxOverlap=0; + btScalar lambda_max = 1.0; + + /* Quick pruning by quantized box */ + btVector3 rayAabbMin = raySource; + btVector3 rayAabbMax = raySource; + rayAabbMin.setMin(rayTarget); + rayAabbMax.setMax(rayTarget); + + /* Add box cast extents to bounding box */ + rayAabbMin += aabbMin; + rayAabbMax += aabbMax; + +#ifdef RAYAABB2 + btVector3 rayDir = (rayTarget-raySource); + rayDir.normalize (); + lambda_max = rayDir.dot(rayTarget-raySource); + ///what about division by zero? --> just set rayDirection[i] to 1.0 + btVector3 rayDirectionInverse; + rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; + rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; + rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2]; + unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; +#endif + + btVector3 bounds[2]; + + while (curIndex < m_curNodeIndex) + { + btScalar param = 1.0; + //catch bugs in tree data + btAssert (walkIterations < m_curNodeIndex); + + walkIterations++; + + bounds[0] = rootNode->m_aabbMinOrg; + bounds[1] = rootNode->m_aabbMaxOrg; + /* Add box cast extents */ + bounds[0] -= aabbMax; + bounds[1] -= aabbMin; + + aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg); + //perhaps profile if it is worth doing the aabbOverlap test first + +#ifdef RAYAABB2 + ///careful with this check: need to check division by zero (above) and fix the unQuantize method + ///thanks Joerg/hiker for the reproduction case! + ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 + rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false; + +#else + btVector3 normal; + rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal); +#endif + + isLeafNode = rootNode->m_escapeIndex == -1; + + //PCK: unsigned instead of bool + if (isLeafNode && (rayBoxOverlap != 0)) + { + nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); + } + + //PCK: unsigned instead of bool + if ((rayBoxOverlap != 0) || isLeafNode) + { + rootNode++; + curIndex++; + } else + { + escapeIndex = rootNode->m_escapeIndex; + rootNode += escapeIndex; + curIndex += escapeIndex; + } + } + if (maxIterations < walkIterations) + maxIterations = walkIterations; + +} + + + +void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const +{ + btAssert(m_useQuantization); + + int curIndex = startNodeIndex; + int walkIterations = 0; + int subTreeSize = endNodeIndex - startNodeIndex; + (void)subTreeSize; + + const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; + int escapeIndex; + + bool isLeafNode; + //PCK: unsigned instead of bool + unsigned boxBoxOverlap = 0; + unsigned rayBoxOverlap = 0; + + btScalar lambda_max = 1.0; + +#ifdef RAYAABB2 + btVector3 rayDirection = (rayTarget-raySource); + rayDirection.normalize (); + lambda_max = rayDirection.dot(rayTarget-raySource); + ///what about division by zero? --> just set rayDirection[i] to 1.0 + rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0]; + rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[1]; + rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[2]; + unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0}; +#endif + + /* Quick pruning by quantized box */ + btVector3 rayAabbMin = raySource; + btVector3 rayAabbMax = raySource; + rayAabbMin.setMin(rayTarget); + rayAabbMax.setMax(rayTarget); + + /* Add box cast extents to bounding box */ + rayAabbMin += aabbMin; + rayAabbMax += aabbMax; + + unsigned short int quantizedQueryAabbMin[3]; + unsigned short int quantizedQueryAabbMax[3]; + quantizeWithClamp(quantizedQueryAabbMin,rayAabbMin,0); + quantizeWithClamp(quantizedQueryAabbMax,rayAabbMax,1); + + while (curIndex < endNodeIndex) + { + +//#define VISUALLY_ANALYZE_BVH 1 +#ifdef VISUALLY_ANALYZE_BVH + //some code snippet to debugDraw aabb, to visually analyze bvh structure + static int drawPatch = 0; + //need some global access to a debugDrawer + extern btIDebugDraw* debugDrawerPtr; + if (curIndex==drawPatch) + { + btVector3 aabbMin,aabbMax; + aabbMin = unQuantize(rootNode->m_quantizedAabbMin); + aabbMax = unQuantize(rootNode->m_quantizedAabbMax); + btVector3 color(1,0,0); + debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); + } +#endif//VISUALLY_ANALYZE_BVH + + //catch bugs in tree data + btAssert (walkIterations < subTreeSize); + + walkIterations++; + //PCK: unsigned instead of bool + // only interested if this is closer than any previous hit + btScalar param = 1.0; + rayBoxOverlap = 0; + boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + isLeafNode = rootNode->isLeafNode(); + if (boxBoxOverlap) + { + btVector3 bounds[2]; + bounds[0] = unQuantize(rootNode->m_quantizedAabbMin); + bounds[1] = unQuantize(rootNode->m_quantizedAabbMax); + /* Add box cast extents */ + bounds[0] -= aabbMax; + bounds[1] -= aabbMin; + btVector3 normal; +#if 0 + bool ra2 = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max); + bool ra = btRayAabb (raySource, rayTarget, bounds[0], bounds[1], param, normal); + if (ra2 != ra) + { + printf("functions don't match\n"); + } +#endif +#ifdef RAYAABB2 + ///careful with this check: need to check division by zero (above) and fix the unQuantize method + ///thanks Joerg/hiker for the reproduction case! + ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 + + //BT_PROFILE("btRayAabb2"); + rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max); + +#else + rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); +#endif + } + + if (isLeafNode && rayBoxOverlap) + { + nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex()); + } + + //PCK: unsigned instead of bool + if ((rayBoxOverlap != 0) || isLeafNode) + { + rootNode++; + curIndex++; + } else + { + escapeIndex = rootNode->getEscapeIndex(); + rootNode += escapeIndex; + curIndex += escapeIndex; + } + } + if (maxIterations < walkIterations) + maxIterations = walkIterations; + +} + +void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const +{ + btAssert(m_useQuantization); + + int curIndex = startNodeIndex; + int walkIterations = 0; + int subTreeSize = endNodeIndex - startNodeIndex; + (void)subTreeSize; + + const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; + int escapeIndex; + + bool isLeafNode; + //PCK: unsigned instead of bool + unsigned aabbOverlap; + + while (curIndex < endNodeIndex) + { + +//#define VISUALLY_ANALYZE_BVH 1 +#ifdef VISUALLY_ANALYZE_BVH + //some code snippet to debugDraw aabb, to visually analyze bvh structure + static int drawPatch = 0; + //need some global access to a debugDrawer + extern btIDebugDraw* debugDrawerPtr; + if (curIndex==drawPatch) + { + btVector3 aabbMin,aabbMax; + aabbMin = unQuantize(rootNode->m_quantizedAabbMin); + aabbMax = unQuantize(rootNode->m_quantizedAabbMax); + btVector3 color(1,0,0); + debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); + } +#endif//VISUALLY_ANALYZE_BVH + + //catch bugs in tree data + btAssert (walkIterations < subTreeSize); + + walkIterations++; + //PCK: unsigned instead of bool + aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + isLeafNode = rootNode->isLeafNode(); + + if (isLeafNode && aabbOverlap) + { + nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex()); + } + + //PCK: unsigned instead of bool + if ((aabbOverlap != 0) || isLeafNode) + { + rootNode++; + curIndex++; + } else + { + escapeIndex = rootNode->getEscapeIndex(); + rootNode += escapeIndex; + curIndex += escapeIndex; + } + } + if (maxIterations < walkIterations) + maxIterations = walkIterations; + +} + +//This traversal can be called from Playstation 3 SPU +void btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +{ + btAssert(m_useQuantization); + + int i; + + + for (i=0;im_SubtreeHeaders.size();i++) + { + const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; + + //PCK: unsigned instead of bool + unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + if (overlap != 0) + { + walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax, + subtree.m_rootNodeIndex, + subtree.m_rootNodeIndex+subtree.m_subtreeSize); + } + } +} + + +void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const +{ + reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0)); +} + + +void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const +{ + //always use stackless + + if (m_useQuantization) + { + walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex); + } + else + { + walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex); + } + /* + { + //recursive traversal + btVector3 qaabbMin = raySource; + btVector3 qaabbMax = raySource; + qaabbMin.setMin(rayTarget); + qaabbMax.setMax(rayTarget); + qaabbMin += aabbMin; + qaabbMax += aabbMax; + reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax); + } + */ + +} + + +void btQuantizedBvh::swapLeafNodes(int i,int splitIndex) +{ + if (m_useQuantization) + { + btQuantizedBvhNode tmp = m_quantizedLeafNodes[i]; + m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex]; + m_quantizedLeafNodes[splitIndex] = tmp; + } else + { + btOptimizedBvhNode tmp = m_leafNodes[i]; + m_leafNodes[i] = m_leafNodes[splitIndex]; + m_leafNodes[splitIndex] = tmp; + } +} + +void btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex) +{ + if (m_useQuantization) + { + m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex]; + } else + { + m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex]; + } +} + +//PCK: include +#include + +#if 0 +//PCK: consts +static const unsigned BVH_ALIGNMENT = 16; +static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1; + +static const unsigned BVH_ALIGNMENT_BLOCKS = 2; +#endif + + +unsigned int btQuantizedBvh::getAlignmentSerializationPadding() +{ + // I changed this to 0 since the extra padding is not needed or used. + return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT; +} + +unsigned btQuantizedBvh::calculateSerializeBufferSize() const +{ + unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding(); + baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount; + if (m_useQuantization) + { + return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode); + } + return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode); +} + +bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const +{ + btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size()); + m_subtreeHeaderCount = m_SubtreeHeaders.size(); + +/* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + { + ///check alignedment for buffer? + btAssert(0); + return false; + } +*/ + + btQuantizedBvh *targetBvh = (btQuantizedBvh *)o_alignedDataBuffer; + + // construct the class so the virtual function table, etc will be set up + // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor + new (targetBvh) btQuantizedBvh; + + if (i_swapEndian) + { + targetBvh->m_curNodeIndex = static_cast(btSwapEndian(m_curNodeIndex)); + + + btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin); + btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax); + btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization); + + targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode); + targetBvh->m_subtreeHeaderCount = static_cast(btSwapEndian(m_subtreeHeaderCount)); + } + else + { + targetBvh->m_curNodeIndex = m_curNodeIndex; + targetBvh->m_bvhAabbMin = m_bvhAabbMin; + targetBvh->m_bvhAabbMax = m_bvhAabbMax; + targetBvh->m_bvhQuantization = m_bvhQuantization; + targetBvh->m_traversalMode = m_traversalMode; + targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount; + } + + targetBvh->m_useQuantization = m_useQuantization; + + unsigned char *nodeData = (unsigned char *)targetBvh; + nodeData += sizeof(btQuantizedBvh); + + unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + int nodeCount = m_curNodeIndex; + + if (m_useQuantization) + { + targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]); + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]); + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast(btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex)); + } + } + else + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]; + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]; + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex; + + + } + } + nodeData += sizeof(btQuantizedBvhNode) * nodeCount; + + // this clears the pointer in the member variable it doesn't really do anything to the data + // it does call the destructor on the contained objects, but they are all classes with no destructor defined + // so the memory (which is not freed) is left alone + targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(NULL, 0, 0); + } + else + { + targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); + btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); + + targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast(btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex)); + targetBvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast(btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart)); + targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast(btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex)); + } + } + else + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg; + targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg; + + targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex; + targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart; + targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex; + } + } + nodeData += sizeof(btOptimizedBvhNode) * nodeCount; + + // this clears the pointer in the member variable it doesn't really do anything to the data + // it does call the destructor on the contained objects, but they are all classes with no destructor defined + // so the memory (which is not freed) is left alone + targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0); + } + + sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + // Now serialize the subtree headers + targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount); + if (i_swapEndian) + { + for (int i = 0; i < m_subtreeHeaderCount; i++) + { + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]); + + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]); + + targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast(btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex)); + targetBvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast(btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize)); + } + } + else + { + for (int i = 0; i < m_subtreeHeaderCount; i++) + { + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]); + + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]); + + targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex); + targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize); + + // need to clear padding in destination buffer + targetBvh->m_SubtreeHeaders[i].m_padding[0] = 0; + targetBvh->m_SubtreeHeaders[i].m_padding[1] = 0; + targetBvh->m_SubtreeHeaders[i].m_padding[2] = 0; + } + } + nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount; + + // this clears the pointer in the member variable it doesn't really do anything to the data + // it does call the destructor on the contained objects, but they are all classes with no destructor defined + // so the memory (which is not freed) is left alone + targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0); + + // this wipes the virtual function table pointer at the start of the buffer for the class + *((void**)o_alignedDataBuffer) = NULL; + + return true; +} + +btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) +{ + + if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + { + return NULL; + } + btQuantizedBvh *bvh = (btQuantizedBvh *)i_alignedDataBuffer; + + if (i_swapEndian) + { + bvh->m_curNodeIndex = static_cast(btSwapEndian(bvh->m_curNodeIndex)); + + btUnSwapVector3Endian(bvh->m_bvhAabbMin); + btUnSwapVector3Endian(bvh->m_bvhAabbMax); + btUnSwapVector3Endian(bvh->m_bvhQuantization); + + bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode); + bvh->m_subtreeHeaderCount = static_cast(btSwapEndian(bvh->m_subtreeHeaderCount)); + } + + unsigned int calculatedBufSize = bvh->calculateSerializeBufferSize(); + btAssert(calculatedBufSize <= i_dataBufferSize); + + if (calculatedBufSize > i_dataBufferSize) + { + return NULL; + } + + unsigned char *nodeData = (unsigned char *)bvh; + nodeData += sizeof(btQuantizedBvh); + + unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + int nodeCount = bvh->m_curNodeIndex; + + // Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor + // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor + new (bvh) btQuantizedBvh(*bvh, false); + + if (bvh->m_useQuantization) + { + bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]); + + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]); + + bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast(btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex)); + } + } + nodeData += sizeof(btQuantizedBvhNode) * nodeCount; + } + else + { + bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); + btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); + + bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex)); + bvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart)); + bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex)); + } + } + nodeData += sizeof(btOptimizedBvhNode) * nodeCount; + } + + sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + // Now serialize the subtree headers + bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount); + if (i_swapEndian) + { + for (int i = 0; i < bvh->m_subtreeHeaderCount; i++) + { + bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]); + + bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]); + + bvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast(btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex)); + bvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast(btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize)); + } + } + + return bvh; +} + +// Constructor that prevents btVector3's default constructor from being called +btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) : +m_bvhAabbMin(self.m_bvhAabbMin), +m_bvhAabbMax(self.m_bvhAabbMax), +m_bvhQuantization(self.m_bvhQuantization), +m_bulletVersion(BT_BULLET_VERSION) +{ + +} + +void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData) +{ + m_bvhAabbMax.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMax); + m_bvhAabbMin.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMin); + m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization); + + m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex; + m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0; + + { + int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes; + m_contiguousNodes.resize(numElem); + + if (numElem) + { + btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr; + + for (int i=0;im_aabbMaxOrg); + m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg); + m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex; + m_contiguousNodes[i].m_subPart = memPtr->m_subPart; + m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex; + } + } + } + + { + int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes; + m_quantizedContiguousNodes.resize(numElem); + + if (numElem) + { + btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr; + for (int i=0;im_escapeIndexOrTriangleIndex; + m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; + m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; + m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; + m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; + m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1]; + m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2]; + } + } + } + + m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode); + + { + int numElem = quantizedBvhFloatData.m_numSubtreeHeaders; + m_SubtreeHeaders.resize(numElem); + if (numElem) + { + btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr; + for (int i=0;im_quantizedAabbMax[0] ; + m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; + m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; + m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; + m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1]; + m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2]; + m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex; + m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize; + } + } + } +} + +void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData) +{ + m_bvhAabbMax.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMax); + m_bvhAabbMin.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMin); + m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization); + + m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex; + m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0; + + { + int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes; + m_contiguousNodes.resize(numElem); + + if (numElem) + { + btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr; + + for (int i=0;im_aabbMaxOrg); + m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg); + m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex; + m_contiguousNodes[i].m_subPart = memPtr->m_subPart; + m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex; + } + } + } + + { + int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes; + m_quantizedContiguousNodes.resize(numElem); + + if (numElem) + { + btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr; + for (int i=0;im_escapeIndexOrTriangleIndex; + m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; + m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; + m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; + m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; + m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1]; + m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2]; + } + } + } + + m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode); + + { + int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders; + m_SubtreeHeaders.resize(numElem); + if (numElem) + { + btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr; + for (int i=0;im_quantizedAabbMax[0] ; + m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; + m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; + m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; + m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1]; + m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2]; + m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex; + m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize; + } + } + } + +} + + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer; + + m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax); + m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin); + m_bvhQuantization.serialize(quantizedData->m_bvhQuantization); + + quantizedData->m_curNodeIndex = m_curNodeIndex; + quantizedData->m_useQuantization = m_useQuantization; + + quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size(); + quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0); + if (quantizedData->m_contiguousNodesPtr) + { + int sz = sizeof(btOptimizedBvhNodeData); + int numElem = m_contiguousNodes.size(); + btChunk* chunk = serializer->allocate(sz,numElem); + btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr; + for (int i=0;im_aabbMaxOrg); + m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg); + memPtr->m_escapeIndex = m_contiguousNodes[i].m_escapeIndex; + memPtr->m_subPart = m_contiguousNodes[i].m_subPart; + memPtr->m_triangleIndex = m_contiguousNodes[i].m_triangleIndex; + } + serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]); + } + + quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size(); +// printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes); + quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0); + if (quantizedData->m_quantizedContiguousNodesPtr) + { + int sz = sizeof(btQuantizedBvhNodeData); + int numElem = m_quantizedContiguousNodes.size(); + btChunk* chunk = serializer->allocate(sz,numElem); + btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr; + for (int i=0;im_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex; + memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0]; + memPtr->m_quantizedAabbMax[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[1]; + memPtr->m_quantizedAabbMax[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[2]; + memPtr->m_quantizedAabbMin[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[0]; + memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1]; + memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2]; + } + serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]); + } + + quantizedData->m_traversalMode = int(m_traversalMode); + quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size(); + + quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0); + if (quantizedData->m_subTreeInfoPtr) + { + int sz = sizeof(btBvhSubtreeInfoData); + int numElem = m_SubtreeHeaders.size(); + btChunk* chunk = serializer->allocate(sz,numElem); + btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr; + for (int i=0;im_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0]; + memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1]; + memPtr->m_quantizedAabbMax[2] = m_SubtreeHeaders[i].m_quantizedAabbMax[2]; + memPtr->m_quantizedAabbMin[0] = m_SubtreeHeaders[i].m_quantizedAabbMin[0]; + memPtr->m_quantizedAabbMin[1] = m_SubtreeHeaders[i].m_quantizedAabbMin[1]; + memPtr->m_quantizedAabbMin[2] = m_SubtreeHeaders[i].m_quantizedAabbMin[2]; + + memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex; + memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize; + } + serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]); + } + return btQuantizedBvhDataName; +} + + + + + diff --git a/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h new file mode 100644 index 0000000..78382da --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h @@ -0,0 +1,581 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_QUANTIZED_BVH_H +#define BT_QUANTIZED_BVH_H + +class btSerializer; + +//#define DEBUG_CHECK_DEQUANTIZATION 1 +#ifdef DEBUG_CHECK_DEQUANTIZATION +#ifdef __SPU__ +#define printf spu_printf +#endif //__SPU__ + +#include +#include +#endif //DEBUG_CHECK_DEQUANTIZATION + +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedAllocator.h" + +#ifdef BT_USE_DOUBLE_PRECISION +#define btQuantizedBvhData btQuantizedBvhDoubleData +#define btOptimizedBvhNodeData btOptimizedBvhNodeDoubleData +#define btQuantizedBvhDataName "btQuantizedBvhDoubleData" +#else +#define btQuantizedBvhData btQuantizedBvhFloatData +#define btOptimizedBvhNodeData btOptimizedBvhNodeFloatData +#define btQuantizedBvhDataName "btQuantizedBvhFloatData" +#endif + + + +//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp + + +//Note: currently we have 16 bytes per quantized node +#define MAX_SUBTREE_SIZE_IN_BYTES 2048 + +// 10 gives the potential for 1024 parts, with at most 2^21 (2097152) (minus one +// actually) triangles each (since the sign bit is reserved +#define MAX_NUM_PARTS_IN_BITS 10 + +///btQuantizedBvhNode is a compressed aabb node, 16 bytes. +///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). +ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + //12 bytes + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; + //4 bytes + int m_escapeIndexOrTriangleIndex; + + bool isLeafNode() const + { + //skipindex is negative (internal node), triangleindex >=0 (leafnode) + return (m_escapeIndexOrTriangleIndex >= 0); + } + int getEscapeIndex() const + { + btAssert(!isLeafNode()); + return -m_escapeIndexOrTriangleIndex; + } + int getTriangleIndex() const + { + btAssert(isLeafNode()); + unsigned int x=0; + unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS); + // Get only the lower bits where the triangle index is stored + return (m_escapeIndexOrTriangleIndex&~(y)); + } + int getPartId() const + { + btAssert(isLeafNode()); + // Get only the highest bits where the part index is stored + return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS)); + } +} +; + +/// btOptimizedBvhNode contains both internal and leaf node information. +/// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes. +ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + //32 bytes + btVector3 m_aabbMinOrg; + btVector3 m_aabbMaxOrg; + + //4 + int m_escapeIndex; + + //8 + //for child nodes + int m_subPart; + int m_triangleIndex; + +//pad the size to 64 bytes + char m_padding[20]; +}; + + +///btBvhSubtreeInfo provides info to gather a subtree of limited size +ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo +{ +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + //12 bytes + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; + //4 bytes, points to the root of the subtree + int m_rootNodeIndex; + //4 bytes + int m_subtreeSize; + int m_padding[3]; + + btBvhSubtreeInfo() + { + //memset(&m_padding[0], 0, sizeof(m_padding)); + } + + + void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode) + { + m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0]; + m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1]; + m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2]; + m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0]; + m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1]; + m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2]; + } +} +; + + +class btNodeOverlapCallback +{ +public: + virtual ~btNodeOverlapCallback() {}; + + virtual void processNode(int subPart, int triangleIndex) = 0; +}; + +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btAlignedObjectArray.h" + + + +///for code readability: +typedef btAlignedObjectArray NodeArray; +typedef btAlignedObjectArray QuantizedNodeArray; +typedef btAlignedObjectArray BvhSubtreeInfoArray; + + +///The btQuantizedBvh class stores an AABB tree that can be quickly traversed on CPU and Cell SPU. +///It is used by the btBvhTriangleMeshShape as midphase, and by the btMultiSapBroadphase. +///It is recommended to use quantization for better performance and lower memory requirements. +ATTRIBUTE_ALIGNED16(class) btQuantizedBvh +{ +public: + enum btTraversalMode + { + TRAVERSAL_STACKLESS = 0, + TRAVERSAL_STACKLESS_CACHE_FRIENDLY, + TRAVERSAL_RECURSIVE + }; + +protected: + + + btVector3 m_bvhAabbMin; + btVector3 m_bvhAabbMax; + btVector3 m_bvhQuantization; + + int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess. + + int m_curNodeIndex; + //quantization data + bool m_useQuantization; + + + + NodeArray m_leafNodes; + NodeArray m_contiguousNodes; + QuantizedNodeArray m_quantizedLeafNodes; + QuantizedNodeArray m_quantizedContiguousNodes; + + btTraversalMode m_traversalMode; + BvhSubtreeInfoArray m_SubtreeHeaders; + + //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray + mutable int m_subtreeHeaderCount; + + + + + + ///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!) + ///this might be refactored into a virtual, it is usually not calculated at run-time + void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin) + { + if (m_useQuantization) + { + quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin,0); + } else + { + m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin; + + } + } + void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax) + { + if (m_useQuantization) + { + quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax,1); + } else + { + m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax; + } + } + + btVector3 getAabbMin(int nodeIndex) const + { + if (m_useQuantization) + { + return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]); + } + //non-quantized + return m_leafNodes[nodeIndex].m_aabbMinOrg; + + } + btVector3 getAabbMax(int nodeIndex) const + { + if (m_useQuantization) + { + return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]); + } + //non-quantized + return m_leafNodes[nodeIndex].m_aabbMaxOrg; + + } + + + void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) + { + if (m_useQuantization) + { + m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex; + } + else + { + m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex; + } + + } + + void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax) + { + if (m_useQuantization) + { + unsigned short int quantizedAabbMin[3]; + unsigned short int quantizedAabbMax[3]; + quantize(quantizedAabbMin,newAabbMin,0); + quantize(quantizedAabbMax,newAabbMax,1); + for (int i=0;i<3;i++) + { + if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i]) + m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i]; + + if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i]) + m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i]; + + } + } else + { + //non-quantized + m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin); + m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); + } + } + + void swapLeafNodes(int firstIndex,int secondIndex); + + void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex); + +protected: + + + + void buildTree (int startIndex,int endIndex); + + int calcSplittingAxis(int startIndex,int endIndex); + + int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis); + + void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; + void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; + void walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; + + ///tree traversal designed for small-memory processors like PS3 SPU + void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + + ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal + void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + + ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal + void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const; + + + + + void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btQuantizedBvh(); + + virtual ~btQuantizedBvh(); + + + ///***************************************** expert/internal use only ************************* + void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0)); + QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; } + ///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized + void buildInternal(); + ///***************************************** expert/internal use only ************************* + + void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; + void reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const; + void reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const; + + SIMD_FORCE_INLINE void quantize(unsigned short* out, const btVector3& point,int isMax) const + { + + btAssert(m_useQuantization); + + btAssert(point.getX() <= m_bvhAabbMax.getX()); + btAssert(point.getY() <= m_bvhAabbMax.getY()); + btAssert(point.getZ() <= m_bvhAabbMax.getZ()); + + btAssert(point.getX() >= m_bvhAabbMin.getX()); + btAssert(point.getY() >= m_bvhAabbMin.getY()); + btAssert(point.getZ() >= m_bvhAabbMin.getZ()); + + btVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization; + ///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative + ///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly) + ///@todo: double-check this + if (isMax) + { + out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1)); + out[1] = (unsigned short) (((unsigned short)(v.getY()+btScalar(1.)) | 1)); + out[2] = (unsigned short) (((unsigned short)(v.getZ()+btScalar(1.)) | 1)); + } else + { + out[0] = (unsigned short) (((unsigned short)(v.getX()) & 0xfffe)); + out[1] = (unsigned short) (((unsigned short)(v.getY()) & 0xfffe)); + out[2] = (unsigned short) (((unsigned short)(v.getZ()) & 0xfffe)); + } + + +#ifdef DEBUG_CHECK_DEQUANTIZATION + btVector3 newPoint = unQuantize(out); + if (isMax) + { + if (newPoint.getX() < point.getX()) + { + printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); + } + if (newPoint.getY() < point.getY()) + { + printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); + } + if (newPoint.getZ() < point.getZ()) + { + + printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); + } + } else + { + if (newPoint.getX() > point.getX()) + { + printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); + } + if (newPoint.getY() > point.getY()) + { + printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); + } + if (newPoint.getZ() > point.getZ()) + { + printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); + } + } +#endif //DEBUG_CHECK_DEQUANTIZATION + + } + + + SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point2,int isMax) const + { + + btAssert(m_useQuantization); + + btVector3 clampedPoint(point2); + clampedPoint.setMax(m_bvhAabbMin); + clampedPoint.setMin(m_bvhAabbMax); + + quantize(out,clampedPoint,isMax); + + } + + SIMD_FORCE_INLINE btVector3 unQuantize(const unsigned short* vecIn) const + { + btVector3 vecOut; + vecOut.setValue( + (btScalar)(vecIn[0]) / (m_bvhQuantization.getX()), + (btScalar)(vecIn[1]) / (m_bvhQuantization.getY()), + (btScalar)(vecIn[2]) / (m_bvhQuantization.getZ())); + vecOut += m_bvhAabbMin; + return vecOut; + } + + ///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees. + void setTraversalMode(btTraversalMode traversalMode) + { + m_traversalMode = traversalMode; + } + + + SIMD_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() + { + return m_quantizedContiguousNodes; + } + + + SIMD_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() + { + return m_SubtreeHeaders; + } + +//////////////////////////////////////////////////////////////////// + + /////Calculate space needed to store BVH for serialization + unsigned calculateSerializeBufferSize() const; + + /// Data buffer MUST be 16 byte aligned + virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const; + + ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' + static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); + + static unsigned int getAlignmentSerializationPadding(); +////////////////////////////////////////////////////////////////////// + + + virtual int calculateSerializeBufferSizeNew() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + virtual void deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData); + + virtual void deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData); + + +//////////////////////////////////////////////////////////////////// + + SIMD_FORCE_INLINE bool isQuantized() + { + return m_useQuantization; + } + +private: + // Special "copy" constructor that allows for in-place deserialization + // Prevents btVector3's default constructor from being called, but doesn't inialize much else + // ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need) + btQuantizedBvh(btQuantizedBvh &other, bool ownsMemory); + +} +; + + +struct btBvhSubtreeInfoData +{ + int m_rootNodeIndex; + int m_subtreeSize; + unsigned short m_quantizedAabbMin[3]; + unsigned short m_quantizedAabbMax[3]; +}; + +struct btOptimizedBvhNodeFloatData +{ + btVector3FloatData m_aabbMinOrg; + btVector3FloatData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; +}; + +struct btOptimizedBvhNodeDoubleData +{ + btVector3DoubleData m_aabbMinOrg; + btVector3DoubleData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; +}; + + +struct btQuantizedBvhNodeData +{ + unsigned short m_quantizedAabbMin[3]; + unsigned short m_quantizedAabbMax[3]; + int m_escapeIndexOrTriangleIndex; +}; + +struct btQuantizedBvhFloatData +{ + btVector3FloatData m_bvhAabbMin; + btVector3FloatData m_bvhAabbMax; + btVector3FloatData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeFloatData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + btBvhSubtreeInfoData *m_subTreeInfoPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + +}; + +struct btQuantizedBvhDoubleData +{ + btVector3DoubleData m_bvhAabbMin; + btVector3DoubleData m_bvhAabbMax; + btVector3DoubleData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeDoubleData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + + int m_traversalMode; + int m_numSubtreeHeaders; + btBvhSubtreeInfoData *m_subTreeInfoPtr; +}; + + +SIMD_FORCE_INLINE int btQuantizedBvh::calculateSerializeBufferSizeNew() const +{ + return sizeof(btQuantizedBvhData); +} + + + +#endif //BT_QUANTIZED_BVH_H diff --git a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp new file mode 100644 index 0000000..752fcd0 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @@ -0,0 +1,349 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSimpleBroadphase.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btAabbUtil2.h" + +#include + +extern int gOverlappingPairs; + +void btSimpleBroadphase::validate() +{ + for (int i=0;i~btOverlappingPairCache(); + btAlignedFree(m_pairCache); + } +} + + +btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* /*dispatcher*/,void* multiSapProxy) +{ + if (m_numHandles >= m_maxHandles) + { + btAssert(0); + return 0; //should never happen, but don't let the game crash ;-) + } + btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); + + int newHandleIndex = allocHandle(); + btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy); + + return proxy; +} + +class RemovingOverlapCallback : public btOverlapCallback +{ +protected: + virtual bool processOverlap(btBroadphasePair& pair) + { + (void)pair; + btAssert(0); + return false; + } +}; + +class RemovePairContainingProxy +{ + + btBroadphaseProxy* m_targetProxy; + public: + virtual ~RemovePairContainingProxy() + { + } +protected: + virtual bool processOverlap(btBroadphasePair& pair) + { + btSimpleBroadphaseProxy* proxy0 = static_cast(pair.m_pProxy0); + btSimpleBroadphaseProxy* proxy1 = static_cast(pair.m_pProxy1); + + return ((m_targetProxy == proxy0 || m_targetProxy == proxy1)); + }; +}; + +void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher) +{ + + btSimpleBroadphaseProxy* proxy0 = static_cast(proxyOrg); + freeHandle(proxy0); + + m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher); + + //validate(); + +} + +void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +{ + const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); + aabbMin = sbp->m_aabbMin; + aabbMax = sbp->m_aabbMax; +} + +void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/) +{ + btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); + sbp->m_aabbMin = aabbMin; + sbp->m_aabbMax = aabbMax; +} + +void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax) +{ + for (int i=0; i <= m_LastHandleIndex; i++) + { + btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; + if(!proxy->m_clientObject) + { + continue; + } + rayCallback.process(proxy); + } +} + + +void btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) +{ + for (int i=0; i <= m_LastHandleIndex; i++) + { + btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; + if(!proxy->m_clientObject) + { + continue; + } + if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax)) + { + callback.process(proxy); + } + } +} + + + + + + + +bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1) +{ + return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && + proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] && + proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2]; + +} + + + +//then remove non-overlapping ones +class CheckOverlapCallback : public btOverlapCallback +{ +public: + virtual bool processOverlap(btBroadphasePair& pair) + { + return (!btSimpleBroadphase::aabbOverlap(static_cast(pair.m_pProxy0),static_cast(pair.m_pProxy1))); + } +}; + +void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +{ + //first check for new overlapping pairs + int i,j; + if (m_numHandles >= 0) + { + int new_largest_index = -1; + for (i=0; i <= m_LastHandleIndex; i++) + { + btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i]; + if(!proxy0->m_clientObject) + { + continue; + } + new_largest_index = i; + for (j=i+1; j <= m_LastHandleIndex; j++) + { + btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j]; + btAssert(proxy0 != proxy1); + if(!proxy1->m_clientObject) + { + continue; + } + + btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); + btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); + + if (aabbOverlap(p0,p1)) + { + if ( !m_pairCache->findPair(proxy0,proxy1)) + { + m_pairCache->addOverlappingPair(proxy0,proxy1); + } + } else + { + if (!m_pairCache->hasDeferredRemoval()) + { + if ( m_pairCache->findPair(proxy0,proxy1)) + { + m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher); + } + } + } + } + } + + m_LastHandleIndex = new_largest_index; + + if (m_ownsPairCache && m_pairCache->hasDeferredRemoval()) + { + + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;iprocessOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + m_pairCache->cleanOverlappingPair(pair,dispatcher); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } + + ///if you don't like to skip the invalid pairs in the array, execute following code: +#define CLEAN_INVALID_PAIRS 1 +#ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; +#endif//CLEAN_INVALID_PAIRS + + } + } +} + + +bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); + btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); + return aabbOverlap(p0,p1); +} + +void btSimpleBroadphase::resetPool(btDispatcher* dispatcher) +{ + //not yet +} diff --git a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h new file mode 100644 index 0000000..7cb3c40 --- /dev/null +++ b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h @@ -0,0 +1,171 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SIMPLE_BROADPHASE_H +#define BT_SIMPLE_BROADPHASE_H + + +#include "btOverlappingPairCache.h" + + +struct btSimpleBroadphaseProxy : public btBroadphaseProxy +{ + int m_nextFree; + +// int m_handleId; + + + btSimpleBroadphaseProxy() {}; + + btSimpleBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy) + :btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy) + { + (void)shapeType; + } + + + SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;} + SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;} + + + + +}; + +///The SimpleBroadphase is just a unit-test for btAxisSweep3, bt32BitAxisSweep3, or btDbvtBroadphase, so use those classes instead. +///It is a brute force aabb culling broadphase based on O(n^2) aabb checks +class btSimpleBroadphase : public btBroadphaseInterface +{ + +protected: + + int m_numHandles; // number of active handles + int m_maxHandles; // max number of handles + int m_LastHandleIndex; + + btSimpleBroadphaseProxy* m_pHandles; // handles pool + + void* m_pHandlesRawPtr; + int m_firstFreeHandle; // free handles list + + int allocHandle() + { + btAssert(m_numHandles < m_maxHandles); + int freeHandle = m_firstFreeHandle; + m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree(); + m_numHandles++; + if(freeHandle > m_LastHandleIndex) + { + m_LastHandleIndex = freeHandle; + } + return freeHandle; + } + + void freeHandle(btSimpleBroadphaseProxy* proxy) + { + int handle = int(proxy-m_pHandles); + btAssert(handle >= 0 && handle < m_maxHandles); + if(handle == m_LastHandleIndex) + { + m_LastHandleIndex--; + } + proxy->SetNextFree(m_firstFreeHandle); + m_firstFreeHandle = handle; + + proxy->m_clientObject = 0; + + m_numHandles--; + } + + btOverlappingPairCache* m_pairCache; + bool m_ownsPairCache; + + int m_invalidPair; + + + + inline btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) + { + btSimpleBroadphaseProxy* proxy0 = static_cast(proxy); + return proxy0; + } + + inline const btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const + { + const btSimpleBroadphaseProxy* proxy0 = static_cast(proxy); + return proxy0; + } + + ///reset broadphase internal structures, to ensure determinism/reproducability + virtual void resetPool(btDispatcher* dispatcher); + + + void validate(); + +protected: + + + + +public: + btSimpleBroadphase(int maxProxies=16384,btOverlappingPairCache* overlappingPairCache=0); + virtual ~btSimpleBroadphase(); + + + static bool aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1); + + + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy); + + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); + virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; + + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0)); + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); + + btOverlappingPairCache* getOverlappingPairCache() + { + return m_pairCache; + } + const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_pairCache; + } + + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + + ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame + ///will add some transform later + virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const + { + aabbMin.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + aabbMax.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + } + + virtual void printStats() + { +// printf("btSimpleBroadphase.h\n"); +// printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles); + } +}; + + + +#endif //BT_SIMPLE_BROADPHASE_H + diff --git a/src/BulletCollision/CMakeLists.txt b/src/BulletCollision/CMakeLists.txt new file mode 100644 index 0000000..e740e98 --- /dev/null +++ b/src/BulletCollision/CMakeLists.txt @@ -0,0 +1,279 @@ +INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src ) + +SET(BulletCollision_SRCS + BroadphaseCollision/btAxisSweep3.cpp + BroadphaseCollision/btBroadphaseProxy.cpp + BroadphaseCollision/btCollisionAlgorithm.cpp + BroadphaseCollision/btDbvt.cpp + BroadphaseCollision/btDbvtBroadphase.cpp + BroadphaseCollision/btDispatcher.cpp + BroadphaseCollision/btMultiSapBroadphase.cpp + BroadphaseCollision/btOverlappingPairCache.cpp + BroadphaseCollision/btQuantizedBvh.cpp + BroadphaseCollision/btSimpleBroadphase.cpp + CollisionDispatch/btActivatingCollisionAlgorithm.cpp + CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp + CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp + CollisionDispatch/btBoxBoxDetector.cpp + CollisionDispatch/btCollisionDispatcher.cpp + CollisionDispatch/btCollisionObject.cpp + CollisionDispatch/btCollisionWorld.cpp + CollisionDispatch/btCompoundCollisionAlgorithm.cpp + CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp + CollisionDispatch/btConvexConvexAlgorithm.cpp + CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp + CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp + CollisionDispatch/btDefaultCollisionConfiguration.cpp + CollisionDispatch/btEmptyCollisionAlgorithm.cpp + CollisionDispatch/btGhostObject.cpp + CollisionDispatch/btInternalEdgeUtility.cpp + CollisionDispatch/btInternalEdgeUtility.h + CollisionDispatch/btManifoldResult.cpp + CollisionDispatch/btSimulationIslandManager.cpp + CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp + CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp + CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp + CollisionDispatch/btUnionFind.cpp + CollisionDispatch/SphereTriangleDetector.cpp + CollisionShapes/btBoxShape.cpp + CollisionShapes/btBox2dShape.cpp + CollisionShapes/btBvhTriangleMeshShape.cpp + CollisionShapes/btCapsuleShape.cpp + CollisionShapes/btCollisionShape.cpp + CollisionShapes/btCompoundShape.cpp + CollisionShapes/btConcaveShape.cpp + CollisionShapes/btConeShape.cpp + CollisionShapes/btConvexHullShape.cpp + CollisionShapes/btConvexInternalShape.cpp + CollisionShapes/btConvexPointCloudShape.cpp + CollisionShapes/btConvexPolyhedron.cpp + CollisionShapes/btConvexShape.cpp + CollisionShapes/btConvex2dShape.cpp + CollisionShapes/btConvexTriangleMeshShape.cpp + CollisionShapes/btCylinderShape.cpp + CollisionShapes/btEmptyShape.cpp + CollisionShapes/btHeightfieldTerrainShape.cpp + CollisionShapes/btMinkowskiSumShape.cpp + CollisionShapes/btMultimaterialTriangleMeshShape.cpp + CollisionShapes/btMultiSphereShape.cpp + CollisionShapes/btOptimizedBvh.cpp + CollisionShapes/btPolyhedralConvexShape.cpp + CollisionShapes/btScaledBvhTriangleMeshShape.cpp + CollisionShapes/btShapeHull.cpp + CollisionShapes/btSphereShape.cpp + CollisionShapes/btStaticPlaneShape.cpp + CollisionShapes/btStridingMeshInterface.cpp + CollisionShapes/btTetrahedronShape.cpp + CollisionShapes/btTriangleBuffer.cpp + CollisionShapes/btTriangleCallback.cpp + CollisionShapes/btTriangleIndexVertexArray.cpp + CollisionShapes/btTriangleIndexVertexMaterialArray.cpp + CollisionShapes/btTriangleMesh.cpp + CollisionShapes/btTriangleMeshShape.cpp + CollisionShapes/btUniformScalingShape.cpp + Gimpact/btContactProcessing.cpp + Gimpact/btGenericPoolAllocator.cpp + Gimpact/btGImpactBvh.cpp + Gimpact/btGImpactCollisionAlgorithm.cpp + Gimpact/btGImpactQuantizedBvh.cpp + Gimpact/btGImpactShape.cpp + Gimpact/btTriangleShapeEx.cpp + Gimpact/gim_box_set.cpp + Gimpact/gim_contact.cpp + Gimpact/gim_memory.cpp + Gimpact/gim_tri_collision.cpp + NarrowPhaseCollision/btContinuousConvexCollision.cpp + NarrowPhaseCollision/btConvexCast.cpp + NarrowPhaseCollision/btGjkConvexCast.cpp + NarrowPhaseCollision/btGjkEpa2.cpp + NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp + NarrowPhaseCollision/btGjkPairDetector.cpp + NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp + NarrowPhaseCollision/btPersistentManifold.cpp + NarrowPhaseCollision/btRaycastCallback.cpp + NarrowPhaseCollision/btSubSimplexConvexCast.cpp + NarrowPhaseCollision/btVoronoiSimplexSolver.cpp + NarrowPhaseCollision/btPolyhedralContactClipping.cpp +) + +SET(Root_HDRS + ../btBulletCollisionCommon.h +) +SET(BroadphaseCollision_HDRS + BroadphaseCollision/btAxisSweep3.h + BroadphaseCollision/btBroadphaseInterface.h + BroadphaseCollision/btBroadphaseProxy.h + BroadphaseCollision/btCollisionAlgorithm.h + BroadphaseCollision/btDbvt.h + BroadphaseCollision/btDbvtBroadphase.h + BroadphaseCollision/btDispatcher.h + BroadphaseCollision/btMultiSapBroadphase.h + BroadphaseCollision/btOverlappingPairCache.h + BroadphaseCollision/btOverlappingPairCallback.h + BroadphaseCollision/btQuantizedBvh.h + BroadphaseCollision/btSimpleBroadphase.h +) +SET(CollisionDispatch_HDRS + CollisionDispatch/btActivatingCollisionAlgorithm.h + CollisionDispatch/btBoxBoxCollisionAlgorithm.h + CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h + CollisionDispatch/btBoxBoxDetector.h + CollisionDispatch/btCollisionConfiguration.h + CollisionDispatch/btCollisionCreateFunc.h + CollisionDispatch/btCollisionDispatcher.h + CollisionDispatch/btCollisionObject.h + CollisionDispatch/btCollisionWorld.h + CollisionDispatch/btCompoundCollisionAlgorithm.h + CollisionDispatch/btConvexConcaveCollisionAlgorithm.h + CollisionDispatch/btConvexConvexAlgorithm.h + CollisionDispatch/btConvex2dConvex2dAlgorithm.h + CollisionDispatch/btConvexPlaneCollisionAlgorithm.h + CollisionDispatch/btDefaultCollisionConfiguration.h + CollisionDispatch/btEmptyCollisionAlgorithm.h + CollisionDispatch/btGhostObject.h + CollisionDispatch/btManifoldResult.h + CollisionDispatch/btSimulationIslandManager.h + CollisionDispatch/btSphereBoxCollisionAlgorithm.h + CollisionDispatch/btSphereSphereCollisionAlgorithm.h + CollisionDispatch/btSphereTriangleCollisionAlgorithm.h + CollisionDispatch/btUnionFind.h + CollisionDispatch/SphereTriangleDetector.h +) +SET(CollisionShapes_HDRS + CollisionShapes/btBoxShape.h + CollisionShapes/btBox2dShape.h + CollisionShapes/btBvhTriangleMeshShape.h + CollisionShapes/btCapsuleShape.h + CollisionShapes/btCollisionMargin.h + CollisionShapes/btCollisionShape.h + CollisionShapes/btCompoundShape.h + CollisionShapes/btConcaveShape.h + CollisionShapes/btConeShape.h + CollisionShapes/btConvexHullShape.h + CollisionShapes/btConvexInternalShape.h + CollisionShapes/btConvexPointCloudShape.h + CollisionShapes/btConvexPolyhedron.h + CollisionShapes/btConvexShape.h + CollisionShapes/btConvex2dShape.h + CollisionShapes/btConvexTriangleMeshShape.h + CollisionShapes/btCylinderShape.h + CollisionShapes/btEmptyShape.h + CollisionShapes/btHeightfieldTerrainShape.h + CollisionShapes/btMaterial.h + CollisionShapes/btMinkowskiSumShape.h + CollisionShapes/btMultimaterialTriangleMeshShape.h + CollisionShapes/btMultiSphereShape.h + CollisionShapes/btOptimizedBvh.h + CollisionShapes/btPolyhedralConvexShape.h + CollisionShapes/btScaledBvhTriangleMeshShape.h + CollisionShapes/btShapeHull.h + CollisionShapes/btSphereShape.h + CollisionShapes/btStaticPlaneShape.h + CollisionShapes/btStridingMeshInterface.h + CollisionShapes/btTetrahedronShape.h + CollisionShapes/btTriangleBuffer.h + CollisionShapes/btTriangleCallback.h + CollisionShapes/btTriangleIndexVertexArray.h + CollisionShapes/btTriangleIndexVertexMaterialArray.h + CollisionShapes/btTriangleInfoMap.h + CollisionShapes/btTriangleMesh.h + CollisionShapes/btTriangleMeshShape.h + CollisionShapes/btTriangleShape.h + CollisionShapes/btUniformScalingShape.h +) +SET(Gimpact_HDRS + Gimpact/btBoxCollision.h + Gimpact/btClipPolygon.h + Gimpact/btContactProcessing.h + Gimpact/btGenericPoolAllocator.h + Gimpact/btGeometryOperations.h + Gimpact/btGImpactBvh.h + Gimpact/btGImpactCollisionAlgorithm.h + Gimpact/btGImpactMassUtil.h + Gimpact/btGImpactQuantizedBvh.h + Gimpact/btGImpactShape.h + Gimpact/btQuantization.h + Gimpact/btTriangleShapeEx.h + Gimpact/gim_array.h + Gimpact/gim_basic_geometry_operations.h + Gimpact/gim_bitset.h + Gimpact/gim_box_collision.h + Gimpact/gim_box_set.h + Gimpact/gim_clip_polygon.h + Gimpact/gim_contact.h + Gimpact/gim_geom_types.h + Gimpact/gim_geometry.h + Gimpact/gim_hash_table.h + Gimpact/gim_linear_math.h + Gimpact/gim_math.h + Gimpact/gim_memory.h + Gimpact/gim_radixsort.h + Gimpact/gim_tri_collision.h +) +SET(NarrowPhaseCollision_HDRS + NarrowPhaseCollision/btContinuousConvexCollision.h + NarrowPhaseCollision/btConvexCast.h + NarrowPhaseCollision/btConvexPenetrationDepthSolver.h + NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h + NarrowPhaseCollision/btGjkConvexCast.h + NarrowPhaseCollision/btGjkEpa2.h + NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h + NarrowPhaseCollision/btGjkPairDetector.h + NarrowPhaseCollision/btManifoldPoint.h + NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h + NarrowPhaseCollision/btPersistentManifold.h + NarrowPhaseCollision/btPointCollector.h + NarrowPhaseCollision/btRaycastCallback.h + NarrowPhaseCollision/btSimplexSolverInterface.h + NarrowPhaseCollision/btSubSimplexConvexCast.h + NarrowPhaseCollision/btVoronoiSimplexSolver.h + NarrowPhaseCollision/btPolyhedralContactClipping.h +) + +SET(BulletCollision_HDRS + ${Root_HDRS} + ${BroadphaseCollision_HDRS} + ${CollisionDispatch_HDRS} + ${CollisionShapes_HDRS} + ${Gimpact_HDRS} + ${NarrowPhaseCollision_HDRS} +) + + +ADD_LIBRARY(BulletCollision ${BulletCollision_SRCS} ${BulletCollision_HDRS}) +SET_TARGET_PROPERTIES(BulletCollision PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletCollision PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletCollision LinearMath) +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #INSTALL of other files requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletCollision DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletCollision DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + INSTALL(FILES ../btBulletCollisionCommon.h +DESTINATION ${INCLUDE_INSTALL_DIR}/BulletCollision) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletCollision PROPERTIES FRAMEWORK true) + + SET_TARGET_PROPERTIES(BulletCollision PROPERTIES PUBLIC_HEADER "${Root_HDRS}") + # Have to list out sub-directories manually: + SET_PROPERTY(SOURCE ${BroadphaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/BroadphaseCollision) + SET_PROPERTY(SOURCE ${CollisionDispatch_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionDispatch) + SET_PROPERTY(SOURCE ${CollisionShapes_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionShapes) + SET_PROPERTY(SOURCE ${Gimpact_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Gimpact) + SET_PROPERTY(SOURCE ${NarrowPhaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/NarrowPhaseCollision) + + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp new file mode 100644 index 0000000..6340178 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp @@ -0,0 +1,200 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "LinearMath/btScalar.h" +#include "SphereTriangleDetector.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + + +SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold) +:m_sphere(sphere), +m_triangle(triangle), +m_contactBreakingThreshold(contactBreakingThreshold) +{ + +} + +void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults) +{ + + (void)debugDraw; + const btTransform& transformA = input.m_transformA; + const btTransform& transformB = input.m_transformB; + + btVector3 point,normal; + btScalar timeOfImpact = btScalar(1.); + btScalar depth = btScalar(0.); +// output.m_distance = btScalar(BT_LARGE_FLOAT); + //move sphere into triangle space + btTransform sphereInTr = transformB.inverseTimes(transformA); + + if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold)) + { + if (swapResults) + { + btVector3 normalOnB = transformB.getBasis()*normal; + btVector3 normalOnA = -normalOnB; + btVector3 pointOnA = transformB*point+normalOnB*depth; + output.addContactPoint(normalOnA,pointOnA,depth); + } else + { + output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth); + } + } + +} + + + +// See also geometrictools.com +// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv +btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest); + +btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) { + btVector3 diff = p - from; + btVector3 v = to - from; + btScalar t = v.dot(diff); + + if (t > 0) { + btScalar dotVV = v.dot(v); + if (t < dotVV) { + t /= dotVV; + diff -= t*v; + } else { + t = 1; + diff -= v; + } + } else + t = 0; + + nearest = from + t*v; + return diff.dot(diff); +} + +bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal) { + btVector3 lp(p); + btVector3 lnormal(normal); + + return pointInTriangle(vertices, lnormal, &lp); +} + +bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold) +{ + + const btVector3* vertices = &m_triangle->getVertexPtr(0); + + btScalar radius = m_sphere->getRadius(); + btScalar radiusWithThreshold = radius + contactBreakingThreshold; + + btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]); + normal.normalize(); + btVector3 p1ToCentre = sphereCenter - vertices[0]; + btScalar distanceFromPlane = p1ToCentre.dot(normal); + + if (distanceFromPlane < btScalar(0.)) + { + //triangle facing the other way + distanceFromPlane *= btScalar(-1.); + normal *= btScalar(-1.); + } + + bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold; + + // Check for contact / intersection + bool hasContact = false; + btVector3 contactPoint; + if (isInsideContactPlane) { + if (facecontains(sphereCenter,vertices,normal)) { + // Inside the contact wedge - touches a point on the shell plane + hasContact = true; + contactPoint = sphereCenter - normal*distanceFromPlane; + } else { + // Could be inside one of the contact capsules + btScalar contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold; + btVector3 nearestOnEdge; + for (int i = 0; i < m_triangle->getNumEdges(); i++) { + + btVector3 pa; + btVector3 pb; + + m_triangle->getEdge(i,pa,pb); + + btScalar distanceSqr = SegmentSqrDistance(pa,pb,sphereCenter, nearestOnEdge); + if (distanceSqr < contactCapsuleRadiusSqr) { + // Yep, we're inside a capsule + hasContact = true; + contactPoint = nearestOnEdge; + } + + } + } + } + + if (hasContact) { + btVector3 contactToCentre = sphereCenter - contactPoint; + btScalar distanceSqr = contactToCentre.length2(); + + if (distanceSqr < radiusWithThreshold*radiusWithThreshold) + { + if (distanceSqr>SIMD_EPSILON) + { + btScalar distance = btSqrt(distanceSqr); + resultNormal = contactToCentre; + resultNormal.normalize(); + point = contactPoint; + depth = -(radius-distance); + } else + { + resultNormal = normal; + point = contactPoint; + depth = -radius; + } + return true; + } + } + + return false; +} + + +bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ) +{ + const btVector3* p1 = &vertices[0]; + const btVector3* p2 = &vertices[1]; + const btVector3* p3 = &vertices[2]; + + btVector3 edge1( *p2 - *p1 ); + btVector3 edge2( *p3 - *p2 ); + btVector3 edge3( *p1 - *p3 ); + + btVector3 p1_to_p( *p - *p1 ); + btVector3 p2_to_p( *p - *p2 ); + btVector3 p3_to_p( *p - *p3 ); + + btVector3 edge1_normal( edge1.cross(normal)); + btVector3 edge2_normal( edge2.cross(normal)); + btVector3 edge3_normal( edge3.cross(normal)); + + btScalar r1, r2, r3; + r1 = edge1_normal.dot( p1_to_p ); + r2 = edge2_normal.dot( p2_to_p ); + r3 = edge3_normal.dot( p3_to_p ); + if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) || + ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) ) + return true; + return false; + +} diff --git a/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h new file mode 100644 index 0000000..22953af --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h @@ -0,0 +1,51 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPHERE_TRIANGLE_DETECTOR_H +#define BT_SPHERE_TRIANGLE_DETECTOR_H + +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" + + + +class btSphereShape; +class btTriangleShape; + + + +/// sphere-triangle to match the btDiscreteCollisionDetectorInterface +struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface +{ + virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false); + + SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold); + + virtual ~SphereTriangleDetector() {}; + + bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold); + +private: + + + bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ); + bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal); + + btSphereShape* m_sphere; + btTriangleShape* m_triangle; + btScalar m_contactBreakingThreshold; + +}; +#endif //BT_SPHERE_TRIANGLE_DETECTOR_H + diff --git a/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp new file mode 100644 index 0000000..57f1464 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp @@ -0,0 +1,47 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btActivatingCollisionAlgorithm.h" +#include "btCollisionDispatcher.h" +#include "btCollisionObject.h" + +btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci) +:btCollisionAlgorithm(ci) +//, +//m_colObj0(0), +//m_colObj1(0) +{ +} +btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* ) +:btCollisionAlgorithm(ci) +//, +//m_colObj0(0), +//m_colObj1(0) +{ +// if (ci.m_dispatcher1->needsCollision(colObj0,colObj1)) +// { +// m_colObj0 = colObj0; +// m_colObj1 = colObj1; +// +// m_colObj0->activate(); +// m_colObj1->activate(); +// } +} + +btActivatingCollisionAlgorithm::~btActivatingCollisionAlgorithm() +{ +// m_colObj0->activate(); +// m_colObj1->activate(); +} diff --git a/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h new file mode 100644 index 0000000..489812b --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BT_ACTIVATING_COLLISION_ALGORITHM_H +#define __BT_ACTIVATING_COLLISION_ALGORITHM_H + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" + +///This class is not enabled yet (work-in-progress) to more aggressively activate objects. +class btActivatingCollisionAlgorithm : public btCollisionAlgorithm +{ +// btCollisionObject* m_colObj0; +// btCollisionObject* m_colObj1; + +public: + + btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci); + + btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + + virtual ~btActivatingCollisionAlgorithm(); + +}; +#endif //__BT_ACTIVATING_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp new file mode 100644 index 0000000..2c36277 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp @@ -0,0 +1,421 @@ +/* +Bullet Continuous Collision Detection and Physics Library +* The b2CollidePolygons routines are Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///btBox2dBox2dCollisionAlgorithm, with modified b2CollidePolygons routines from the Box2D library. +///The modifications include: switching from b2Vec to btVector3, redefinition of b2Dot, b2Cross + +#include "btBox2dBox2dCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.h" +#include "BulletCollision/CollisionShapes/btBox2dShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +#define USE_PERSISTENT_CONTACTS 1 + +btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap) +: btActivatingCollisionAlgorithm(ci,obj0Wrap,obj1Wrap), +m_ownManifold(false), +m_manifoldPtr(mf) +{ + if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject())) + { + m_manifoldPtr = m_dispatcher->getNewManifold(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject()); + m_ownManifold = true; + } +} + +btBox2dBox2dCollisionAlgorithm::~btBox2dBox2dCollisionAlgorithm() +{ + + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } + +} + + +void b2CollidePolygons(btManifoldResult* manifold, const btBox2dShape* polyA, const btTransform& xfA, const btBox2dShape* polyB, const btTransform& xfB); + +//#include +void btBox2dBox2dCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + if (!m_manifoldPtr) + return; + + + const btBox2dShape* box0 = (const btBox2dShape*)body0Wrap->getCollisionShape(); + const btBox2dShape* box1 = (const btBox2dShape*)body1Wrap->getCollisionShape(); + + resultOut->setPersistentManifold(m_manifoldPtr); + + b2CollidePolygons(resultOut,box0,body0Wrap->getWorldTransform(),box1,body1Wrap->getWorldTransform()); + + // refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + +} + +btScalar btBox2dBox2dCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +{ + //not yet + return 1.f; +} + + +struct ClipVertex +{ + btVector3 v; + int id; + //b2ContactID id; + //b2ContactID id; +}; + +#define b2Dot(a,b) (a).dot(b) +#define b2Mul(a,b) (a)*(b) +#define b2MulT(a,b) (a).transpose()*(b) +#define b2Cross(a,b) (a).cross(b) +#define btCrossS(a,s) btVector3(s * a.getY(), -s * a.getX(),0.f) + +int b2_maxManifoldPoints =2; + +static int ClipSegmentToLine(ClipVertex vOut[2], ClipVertex vIn[2], + const btVector3& normal, btScalar offset) +{ + // Start with no output points + int numOut = 0; + + // Calculate the distance of end points to the line + btScalar distance0 = b2Dot(normal, vIn[0].v) - offset; + btScalar distance1 = b2Dot(normal, vIn[1].v) - offset; + + // If the points are behind the plane + if (distance0 <= 0.0f) vOut[numOut++] = vIn[0]; + if (distance1 <= 0.0f) vOut[numOut++] = vIn[1]; + + // If the points are on different sides of the plane + if (distance0 * distance1 < 0.0f) + { + // Find intersection point of edge and plane + btScalar interp = distance0 / (distance0 - distance1); + vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v); + if (distance0 > 0.0f) + { + vOut[numOut].id = vIn[0].id; + } + else + { + vOut[numOut].id = vIn[1].id; + } + ++numOut; + } + + return numOut; +} + +// Find the separation between poly1 and poly2 for a give edge normal on poly1. +static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1, int edge1, + const btBox2dShape* poly2, const btTransform& xf2) +{ + const btVector3* vertices1 = poly1->getVertices(); + const btVector3* normals1 = poly1->getNormals(); + + int count2 = poly2->getVertexCount(); + const btVector3* vertices2 = poly2->getVertices(); + + btAssert(0 <= edge1 && edge1 < poly1->getVertexCount()); + + // Convert normal from poly1's frame into poly2's frame. + btVector3 normal1World = b2Mul(xf1.getBasis(), normals1[edge1]); + btVector3 normal1 = b2MulT(xf2.getBasis(), normal1World); + + // Find support vertex on poly2 for -normal. + int index = 0; + btScalar minDot = BT_LARGE_FLOAT; + + if( count2 > 0 ) + index = (int) normal1.minDot( vertices2, count2, minDot); + + btVector3 v1 = b2Mul(xf1, vertices1[edge1]); + btVector3 v2 = b2Mul(xf2, vertices2[index]); + btScalar separation = b2Dot(v2 - v1, normal1World); + return separation; +} + +// Find the max separation between poly1 and poly2 using edge normals from poly1. +static btScalar FindMaxSeparation(int* edgeIndex, + const btBox2dShape* poly1, const btTransform& xf1, + const btBox2dShape* poly2, const btTransform& xf2) +{ + int count1 = poly1->getVertexCount(); + const btVector3* normals1 = poly1->getNormals(); + + // Vector pointing from the centroid of poly1 to the centroid of poly2. + btVector3 d = b2Mul(xf2, poly2->getCentroid()) - b2Mul(xf1, poly1->getCentroid()); + btVector3 dLocal1 = b2MulT(xf1.getBasis(), d); + + // Find edge normal on poly1 that has the largest projection onto d. + int edge = 0; + btScalar maxDot; + if( count1 > 0 ) + edge = (int) dLocal1.maxDot( normals1, count1, maxDot); + + // Get the separation for the edge normal. + btScalar s = EdgeSeparation(poly1, xf1, edge, poly2, xf2); + if (s > 0.0f) + { + return s; + } + + // Check the separation for the previous edge normal. + int prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1; + btScalar sPrev = EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); + if (sPrev > 0.0f) + { + return sPrev; + } + + // Check the separation for the next edge normal. + int nextEdge = edge + 1 < count1 ? edge + 1 : 0; + btScalar sNext = EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); + if (sNext > 0.0f) + { + return sNext; + } + + // Find the best edge and the search direction. + int bestEdge; + btScalar bestSeparation; + int increment; + if (sPrev > s && sPrev > sNext) + { + increment = -1; + bestEdge = prevEdge; + bestSeparation = sPrev; + } + else if (sNext > s) + { + increment = 1; + bestEdge = nextEdge; + bestSeparation = sNext; + } + else + { + *edgeIndex = edge; + return s; + } + + // Perform a local search for the best edge normal. + for ( ; ; ) + { + if (increment == -1) + edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1; + else + edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0; + + s = EdgeSeparation(poly1, xf1, edge, poly2, xf2); + if (s > 0.0f) + { + return s; + } + + if (s > bestSeparation) + { + bestEdge = edge; + bestSeparation = s; + } + else + { + break; + } + } + + *edgeIndex = bestEdge; + return bestSeparation; +} + +static void FindIncidentEdge(ClipVertex c[2], + const btBox2dShape* poly1, const btTransform& xf1, int edge1, + const btBox2dShape* poly2, const btTransform& xf2) +{ + const btVector3* normals1 = poly1->getNormals(); + + int count2 = poly2->getVertexCount(); + const btVector3* vertices2 = poly2->getVertices(); + const btVector3* normals2 = poly2->getNormals(); + + btAssert(0 <= edge1 && edge1 < poly1->getVertexCount()); + + // Get the normal of the reference edge in poly2's frame. + btVector3 normal1 = b2MulT(xf2.getBasis(), b2Mul(xf1.getBasis(), normals1[edge1])); + + // Find the incident edge on poly2. + int index = 0; + btScalar minDot = BT_LARGE_FLOAT; + for (int i = 0; i < count2; ++i) + { + btScalar dot = b2Dot(normal1, normals2[i]); + if (dot < minDot) + { + minDot = dot; + index = i; + } + } + + // Build the clip vertices for the incident edge. + int i1 = index; + int i2 = i1 + 1 < count2 ? i1 + 1 : 0; + + c[0].v = b2Mul(xf2, vertices2[i1]); +// c[0].id.features.referenceEdge = (unsigned char)edge1; +// c[0].id.features.incidentEdge = (unsigned char)i1; +// c[0].id.features.incidentVertex = 0; + + c[1].v = b2Mul(xf2, vertices2[i2]); +// c[1].id.features.referenceEdge = (unsigned char)edge1; +// c[1].id.features.incidentEdge = (unsigned char)i2; +// c[1].id.features.incidentVertex = 1; +} + +// Find edge normal of max separation on A - return if separating axis is found +// Find edge normal of max separation on B - return if separation axis is found +// Choose reference edge as min(minA, minB) +// Find incident edge +// Clip + +// The normal points from 1 to 2 +void b2CollidePolygons(btManifoldResult* manifold, + const btBox2dShape* polyA, const btTransform& xfA, + const btBox2dShape* polyB, const btTransform& xfB) +{ + + int edgeA = 0; + btScalar separationA = FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB); + if (separationA > 0.0f) + return; + + int edgeB = 0; + btScalar separationB = FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA); + if (separationB > 0.0f) + return; + + const btBox2dShape* poly1; // reference poly + const btBox2dShape* poly2; // incident poly + btTransform xf1, xf2; + int edge1; // reference edge + unsigned char flip; + const btScalar k_relativeTol = 0.98f; + const btScalar k_absoluteTol = 0.001f; + + // TODO_ERIN use "radius" of poly for absolute tolerance. + if (separationB > k_relativeTol * separationA + k_absoluteTol) + { + poly1 = polyB; + poly2 = polyA; + xf1 = xfB; + xf2 = xfA; + edge1 = edgeB; + flip = 1; + } + else + { + poly1 = polyA; + poly2 = polyB; + xf1 = xfA; + xf2 = xfB; + edge1 = edgeA; + flip = 0; + } + + ClipVertex incidentEdge[2]; + FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); + + int count1 = poly1->getVertexCount(); + const btVector3* vertices1 = poly1->getVertices(); + + btVector3 v11 = vertices1[edge1]; + btVector3 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0]; + + //btVector3 dv = v12 - v11; + btVector3 sideNormal = b2Mul(xf1.getBasis(), v12 - v11); + sideNormal.normalize(); + btVector3 frontNormal = btCrossS(sideNormal, 1.0f); + + + v11 = b2Mul(xf1, v11); + v12 = b2Mul(xf1, v12); + + btScalar frontOffset = b2Dot(frontNormal, v11); + btScalar sideOffset1 = -b2Dot(sideNormal, v11); + btScalar sideOffset2 = b2Dot(sideNormal, v12); + + // Clip incident edge against extruded edge1 side edges. + ClipVertex clipPoints1[2]; + clipPoints1[0].v.setValue(0,0,0); + clipPoints1[1].v.setValue(0,0,0); + + ClipVertex clipPoints2[2]; + clipPoints2[0].v.setValue(0,0,0); + clipPoints2[1].v.setValue(0,0,0); + + + int np; + + // Clip to box side 1 + np = ClipSegmentToLine(clipPoints1, incidentEdge, -sideNormal, sideOffset1); + + if (np < 2) + return; + + // Clip to negative box side 1 + np = ClipSegmentToLine(clipPoints2, clipPoints1, sideNormal, sideOffset2); + + if (np < 2) + { + return; + } + + // Now clipPoints2 contains the clipped points. + btVector3 manifoldNormal = flip ? -frontNormal : frontNormal; + + int pointCount = 0; + for (int i = 0; i < b2_maxManifoldPoints; ++i) + { + btScalar separation = b2Dot(frontNormal, clipPoints2[i].v) - frontOffset; + + if (separation <= 0.0f) + { + + //b2ManifoldPoint* cp = manifold->points + pointCount; + //btScalar separation = separation; + //cp->localPoint1 = b2MulT(xfA, clipPoints2[i].v); + //cp->localPoint2 = b2MulT(xfB, clipPoints2[i].v); + + manifold->addContactPoint(-manifoldNormal,clipPoints2[i].v,separation); + +// cp->id = clipPoints2[i].id; +// cp->id.features.flip = flip; + ++pointCount; + } + } + +// manifold->pointCount = pointCount;} +} diff --git a/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h new file mode 100644 index 0000000..6ea6e89 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h @@ -0,0 +1,66 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H +#define BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H + +#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" + +class btPersistentManifold; + +///box-box collision detection +class btBox2dBox2dCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + +public: + btBox2dBox2dCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btActivatingCollisionAlgorithm(ci) {} + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + + virtual ~btBox2dBox2dCollisionAlgorithm(); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr && m_ownManifold) + { + manifoldArray.push_back(m_manifoldPtr); + } + } + + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + int bbsize = sizeof(btBox2dBox2dCollisionAlgorithm); + void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize); + return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0Wrap,body1Wrap); + } + }; + +}; + +#endif //BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H + diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp new file mode 100644 index 0000000..ac68968 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp @@ -0,0 +1,84 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBoxBoxCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "btBoxBoxDetector.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" +#define USE_PERSISTENT_CONTACTS 1 + +btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) +: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), +m_ownManifold(false), +m_manifoldPtr(mf) +{ + if (!m_manifoldPtr && m_dispatcher->needsCollision(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject())) + { + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_ownManifold = true; + } +} + +btBoxBoxCollisionAlgorithm::~btBoxBoxCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btBoxBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + if (!m_manifoldPtr) + return; + + + const btBoxShape* box0 = (btBoxShape*)body0Wrap->getCollisionShape(); + const btBoxShape* box1 = (btBoxShape*)body1Wrap->getCollisionShape(); + + + + /// report a contact. internally this will be kept persistent, and contact reduction is done + resultOut->setPersistentManifold(m_manifoldPtr); +#ifndef USE_PERSISTENT_CONTACTS + m_manifoldPtr->clearManifold(); +#endif //USE_PERSISTENT_CONTACTS + + btDiscreteCollisionDetectorInterface::ClosestPointInput input; + input.m_maximumDistanceSquared = BT_LARGE_FLOAT; + input.m_transformA = body0Wrap->getWorldTransform(); + input.m_transformB = body1Wrap->getWorldTransform(); + + btBoxBoxDetector detector(box0,box1); + detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + +#ifdef USE_PERSISTENT_CONTACTS + // refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } +#endif //USE_PERSISTENT_CONTACTS + +} + +btScalar btBoxBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +{ + //not yet + return 1.f; +} diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h new file mode 100644 index 0000000..59808df --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h @@ -0,0 +1,66 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BOX_BOX__COLLISION_ALGORITHM_H +#define BT_BOX_BOX__COLLISION_ALGORITHM_H + +#include "btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" + +class btPersistentManifold; + +///box-box collision detection +class btBoxBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + +public: + btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btActivatingCollisionAlgorithm(ci) {} + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + + virtual ~btBoxBoxCollisionAlgorithm(); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr && m_ownManifold) + { + manifoldArray.push_back(m_manifoldPtr); + } + } + + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + int bbsize = sizeof(btBoxBoxCollisionAlgorithm); + void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize); + return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap); + } + }; + +}; + +#endif //BT_BOX_BOX__COLLISION_ALGORITHM_H + diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp new file mode 100644 index 0000000..7043bde --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp @@ -0,0 +1,718 @@ +/* + * Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith + * Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. + * All rights reserved. Email: russ@q12.org Web: www.q12.org + Bullet Continuous Collision Detection and Physics Library + Bullet is Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///ODE box-box collision detection is adapted to work with Bullet + +#include "btBoxBoxDetector.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" + +#include +#include + +btBoxBoxDetector::btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2) +: m_box1(box1), +m_box2(box2) +{ + +} + + +// given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and +// generate contact points. this returns 0 if there is no contact otherwise +// it returns the number of contacts generated. +// `normal' returns the contact normal. +// `depth' returns the maximum penetration depth along that normal. +// `return_code' returns a number indicating the type of contact that was +// detected: +// 1,2,3 = box 2 intersects with a face of box 1 +// 4,5,6 = box 1 intersects with a face of box 2 +// 7..15 = edge-edge contact +// `maxc' is the maximum number of contacts allowed to be generated, i.e. +// the size of the `contact' array. +// `contact' and `skip' are the contact array information provided to the +// collision functions. this function only fills in the position and depth +// fields. +struct dContactGeom; +#define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) +#define dInfinity FLT_MAX + + +/*PURE_INLINE btScalar dDOT (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); } +PURE_INLINE btScalar dDOT13 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,3); } +PURE_INLINE btScalar dDOT31 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,1); } +PURE_INLINE btScalar dDOT33 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,3); } +*/ +static btScalar dDOT (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); } +static btScalar dDOT44 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,4); } +static btScalar dDOT41 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,1); } +static btScalar dDOT14 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,4); } +#define dMULTIPLYOP1_331(A,op,B,C) \ +{\ + (A)[0] op dDOT41((B),(C)); \ + (A)[1] op dDOT41((B+1),(C)); \ + (A)[2] op dDOT41((B+2),(C)); \ +} + +#define dMULTIPLYOP0_331(A,op,B,C) \ +{ \ + (A)[0] op dDOT((B),(C)); \ + (A)[1] op dDOT((B+4),(C)); \ + (A)[2] op dDOT((B+8),(C)); \ +} + +#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) +#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) + +typedef btScalar dMatrix3[4*3]; + +void dLineClosestApproach (const btVector3& pa, const btVector3& ua, + const btVector3& pb, const btVector3& ub, + btScalar *alpha, btScalar *beta); +void dLineClosestApproach (const btVector3& pa, const btVector3& ua, + const btVector3& pb, const btVector3& ub, + btScalar *alpha, btScalar *beta) +{ + btVector3 p; + p[0] = pb[0] - pa[0]; + p[1] = pb[1] - pa[1]; + p[2] = pb[2] - pa[2]; + btScalar uaub = dDOT(ua,ub); + btScalar q1 = dDOT(ua,p); + btScalar q2 = -dDOT(ub,p); + btScalar d = 1-uaub*uaub; + if (d <= btScalar(0.0001f)) { + // @@@ this needs to be made more robust + *alpha = 0; + *beta = 0; + } + else { + d = 1.f/d; + *alpha = (q1 + uaub*q2)*d; + *beta = (uaub*q1 + q2)*d; + } +} + + + +// find all the intersection points between the 2D rectangle with vertices +// at (+/-h[0],+/-h[1]) and the 2D quadrilateral with vertices (p[0],p[1]), +// (p[2],p[3]),(p[4],p[5]),(p[6],p[7]). +// +// the intersection points are returned as x,y pairs in the 'ret' array. +// the number of intersection points is returned by the function (this will +// be in the range 0 to 8). + +static int intersectRectQuad2 (btScalar h[2], btScalar p[8], btScalar ret[16]) +{ + // q (and r) contain nq (and nr) coordinate points for the current (and + // chopped) polygons + int nq=4,nr=0; + btScalar buffer[16]; + btScalar *q = p; + btScalar *r = ret; + for (int dir=0; dir <= 1; dir++) { + // direction notation: xy[0] = x axis, xy[1] = y axis + for (int sign=-1; sign <= 1; sign += 2) { + // chop q along the line xy[dir] = sign*h[dir] + btScalar *pq = q; + btScalar *pr = r; + nr = 0; + for (int i=nq; i > 0; i--) { + // go through all points in q and all lines between adjacent points + if (sign*pq[dir] < h[dir]) { + // this point is inside the chopping line + pr[0] = pq[0]; + pr[1] = pq[1]; + pr += 2; + nr++; + if (nr & 8) { + q = r; + goto done; + } + } + btScalar *nextq = (i > 1) ? pq+2 : q; + if ((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir])) { + // this line crosses the chopping line + pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) / + (nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]); + pr[dir] = sign*h[dir]; + pr += 2; + nr++; + if (nr & 8) { + q = r; + goto done; + } + } + pq += 2; + } + q = r; + r = (q==ret) ? buffer : ret; + nq = nr; + } + } + done: + if (q != ret) memcpy (ret,q,nr*2*sizeof(btScalar)); + return nr; +} + + +#define M__PI 3.14159265f + +// given n points in the plane (array p, of size 2*n), generate m points that +// best represent the whole set. the definition of 'best' here is not +// predetermined - the idea is to select points that give good box-box +// collision detection behavior. the chosen point indexes are returned in the +// array iret (of size m). 'i0' is always the first entry in the array. +// n must be in the range [1..8]. m must be in the range [1..n]. i0 must be +// in the range [0..n-1]. + +void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]); +void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]) +{ + // compute the centroid of the polygon in cx,cy + int i,j; + btScalar a,cx,cy,q; + if (n==1) { + cx = p[0]; + cy = p[1]; + } + else if (n==2) { + cx = btScalar(0.5)*(p[0] + p[2]); + cy = btScalar(0.5)*(p[1] + p[3]); + } + else { + a = 0; + cx = 0; + cy = 0; + for (i=0; i<(n-1); i++) { + q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1]; + a += q; + cx += q*(p[i*2]+p[i*2+2]); + cy += q*(p[i*2+1]+p[i*2+3]); + } + q = p[n*2-2]*p[1] - p[0]*p[n*2-1]; + if (btFabs(a+q) > SIMD_EPSILON) + { + a = 1.f/(btScalar(3.0)*(a+q)); + } else + { + a=BT_LARGE_FLOAT; + } + cx = a*(cx + q*(p[n*2-2]+p[0])); + cy = a*(cy + q*(p[n*2-1]+p[1])); + } + + // compute the angle of each point w.r.t. the centroid + btScalar A[8]; + for (i=0; i M__PI) a -= 2*M__PI; + btScalar maxdiff=1e9,diff; + + *iret = i0; // iret is not allowed to keep this value, but it sometimes does, when diff=#QNAN0 + + for (i=0; i M__PI) diff = 2*M__PI - diff; + if (diff < maxdiff) { + maxdiff = diff; + *iret = i; + } + } + } +#if defined(DEBUG) || defined (_DEBUG) + btAssert (*iret != i0); // ensure iret got set +#endif + avail[*iret] = 0; + iret++; + } +} + + + +int dBoxBox2 (const btVector3& p1, const dMatrix3 R1, + const btVector3& side1, const btVector3& p2, + const dMatrix3 R2, const btVector3& side2, + btVector3& normal, btScalar *depth, int *return_code, + int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output); +int dBoxBox2 (const btVector3& p1, const dMatrix3 R1, + const btVector3& side1, const btVector3& p2, + const dMatrix3 R2, const btVector3& side2, + btVector3& normal, btScalar *depth, int *return_code, + int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output) +{ + const btScalar fudge_factor = btScalar(1.05); + btVector3 p,pp,normalC(0.f,0.f,0.f); + const btScalar *normalR = 0; + btScalar A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33, + Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l; + int i,j,invert_normal,code; + + // get vector from centers of box 1 to box 2, relative to box 1 + p = p2 - p1; + dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1 + + // get side lengths / 2 + A[0] = side1[0]*btScalar(0.5); + A[1] = side1[1]*btScalar(0.5); + A[2] = side1[2]*btScalar(0.5); + B[0] = side2[0]*btScalar(0.5); + B[1] = side2[1]*btScalar(0.5); + B[2] = side2[2]*btScalar(0.5); + + // Rij is R1'*R2, i.e. the relative rotation between R1 and R2 + R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); + R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); + R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); + + Q11 = btFabs(R11); Q12 = btFabs(R12); Q13 = btFabs(R13); + Q21 = btFabs(R21); Q22 = btFabs(R22); Q23 = btFabs(R23); + Q31 = btFabs(R31); Q32 = btFabs(R32); Q33 = btFabs(R33); + + // for all 15 possible separating axes: + // * see if the axis separates the boxes. if so, return 0. + // * find the depth of the penetration along the separating axis (s2) + // * if this is the largest depth so far, record it. + // the normal vector will be set to the separating axis with the smallest + // depth. note: normalR is set to point to a column of R1 or R2 if that is + // the smallest depth normal so far. otherwise normalR is 0 and normalC is + // set to a vector relative to body 1. invert_normal is 1 if the sign of + // the normal should be flipped. + +#define TST(expr1,expr2,norm,cc) \ + s2 = btFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = norm; \ + invert_normal = ((expr1) < 0); \ + code = (cc); \ + } + + s = -dInfinity; + invert_normal = 0; + code = 0; + + // separating axis = u1,u2,u3 + TST (pp[0],(A[0] + B[0]*Q11 + B[1]*Q12 + B[2]*Q13),R1+0,1); + TST (pp[1],(A[1] + B[0]*Q21 + B[1]*Q22 + B[2]*Q23),R1+1,2); + TST (pp[2],(A[2] + B[0]*Q31 + B[1]*Q32 + B[2]*Q33),R1+2,3); + + // separating axis = v1,v2,v3 + TST (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4); + TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5); + TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6); + + // note: cross product axes need to be scaled when s is computed. + // normal (n1,n2,n3) is relative to box 1. +#undef TST +#define TST(expr1,expr2,n1,n2,n3,cc) \ + s2 = btFabs(expr1) - (expr2); \ + if (s2 > SIMD_EPSILON) return 0; \ + l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \ + if (l > SIMD_EPSILON) { \ + s2 /= l; \ + if (s2*fudge_factor > s) { \ + s = s2; \ + normalR = 0; \ + normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \ + invert_normal = ((expr1) < 0); \ + code = (cc); \ + } \ + } + + btScalar fudge2 (1.0e-5f); + + Q11 += fudge2; + Q12 += fudge2; + Q13 += fudge2; + + Q21 += fudge2; + Q22 += fudge2; + Q23 += fudge2; + + Q31 += fudge2; + Q32 += fudge2; + Q33 += fudge2; + + // separating axis = u1 x (v1,v2,v3) + TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7); + TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8); + TST(pp[2]*R23-pp[1]*R33,(A[1]*Q33+A[2]*Q23+B[0]*Q12+B[1]*Q11),0,-R33,R23,9); + + // separating axis = u2 x (v1,v2,v3) + TST(pp[0]*R31-pp[2]*R11,(A[0]*Q31+A[2]*Q11+B[1]*Q23+B[2]*Q22),R31,0,-R11,10); + TST(pp[0]*R32-pp[2]*R12,(A[0]*Q32+A[2]*Q12+B[0]*Q23+B[2]*Q21),R32,0,-R12,11); + TST(pp[0]*R33-pp[2]*R13,(A[0]*Q33+A[2]*Q13+B[0]*Q22+B[1]*Q21),R33,0,-R13,12); + + // separating axis = u3 x (v1,v2,v3) + TST(pp[1]*R11-pp[0]*R21,(A[0]*Q21+A[1]*Q11+B[1]*Q33+B[2]*Q32),-R21,R11,0,13); + TST(pp[1]*R12-pp[0]*R22,(A[0]*Q22+A[1]*Q12+B[0]*Q33+B[2]*Q31),-R22,R12,0,14); + TST(pp[1]*R13-pp[0]*R23,(A[0]*Q23+A[1]*Q13+B[0]*Q32+B[1]*Q31),-R23,R13,0,15); + +#undef TST + + if (!code) return 0; + + // if we get to this point, the boxes interpenetrate. compute the normal + // in global coordinates. + if (normalR) { + normal[0] = normalR[0]; + normal[1] = normalR[4]; + normal[2] = normalR[8]; + } + else { + dMULTIPLY0_331 (normal,R1,normalC); + } + if (invert_normal) { + normal[0] = -normal[0]; + normal[1] = -normal[1]; + normal[2] = -normal[2]; + } + *depth = -s; + + // compute contact point(s) + + if (code > 6) { + // an edge from box 1 touches an edge from box 2. + // find a point pa on the intersecting edge of box 1 + btVector3 pa; + btScalar sign; + for (i=0; i<3; i++) pa[i] = p1[i]; + for (j=0; j<3; j++) { + sign = (dDOT14(normal,R1+j) > 0) ? btScalar(1.0) : btScalar(-1.0); + for (i=0; i<3; i++) pa[i] += sign * A[j] * R1[i*4+j]; + } + + // find a point pb on the intersecting edge of box 2 + btVector3 pb; + for (i=0; i<3; i++) pb[i] = p2[i]; + for (j=0; j<3; j++) { + sign = (dDOT14(normal,R2+j) > 0) ? btScalar(-1.0) : btScalar(1.0); + for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j]; + } + + btScalar alpha,beta; + btVector3 ua,ub; + for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4]; + for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4]; + + dLineClosestApproach (pa,ua,pb,ub,&alpha,&beta); + for (i=0; i<3; i++) pa[i] += ua[i]*alpha; + for (i=0; i<3; i++) pb[i] += ub[i]*beta; + + { + + //contact[0].pos[i] = btScalar(0.5)*(pa[i]+pb[i]); + //contact[0].depth = *depth; + btVector3 pointInWorld; + +#ifdef USE_CENTER_POINT + for (i=0; i<3; i++) + pointInWorld[i] = (pa[i]+pb[i])*btScalar(0.5); + output.addContactPoint(-normal,pointInWorld,-*depth); +#else + output.addContactPoint(-normal,pb,-*depth); + +#endif // + *return_code = code; + } + return 1; + } + + // okay, we have a face-something intersection (because the separating + // axis is perpendicular to a face). define face 'a' to be the reference + // face (i.e. the normal vector is perpendicular to this) and face 'b' to be + // the incident face (the closest face of the other box). + + const btScalar *Ra,*Rb,*pa,*pb,*Sa,*Sb; + if (code <= 3) { + Ra = R1; + Rb = R2; + pa = p1; + pb = p2; + Sa = A; + Sb = B; + } + else { + Ra = R2; + Rb = R1; + pa = p2; + pb = p1; + Sa = B; + Sb = A; + } + + // nr = normal vector of reference face dotted with axes of incident box. + // anr = absolute values of nr. + btVector3 normal2,nr,anr; + if (code <= 3) { + normal2[0] = normal[0]; + normal2[1] = normal[1]; + normal2[2] = normal[2]; + } + else { + normal2[0] = -normal[0]; + normal2[1] = -normal[1]; + normal2[2] = -normal[2]; + } + dMULTIPLY1_331 (nr,Rb,normal2); + anr[0] = btFabs (nr[0]); + anr[1] = btFabs (nr[1]); + anr[2] = btFabs (nr[2]); + + // find the largest compontent of anr: this corresponds to the normal + // for the indident face. the other axis numbers of the indicent face + // are stored in a1,a2. + int lanr,a1,a2; + if (anr[1] > anr[0]) { + if (anr[1] > anr[2]) { + a1 = 0; + lanr = 1; + a2 = 2; + } + else { + a1 = 0; + a2 = 1; + lanr = 2; + } + } + else { + if (anr[0] > anr[2]) { + lanr = 0; + a1 = 1; + a2 = 2; + } + else { + a1 = 0; + a2 = 1; + lanr = 2; + } + } + + // compute center point of incident face, in reference-face coordinates + btVector3 center; + if (nr[lanr] < 0) { + for (i=0; i<3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i*4+lanr]; + } + else { + for (i=0; i<3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i*4+lanr]; + } + + // find the normal and non-normal axis numbers of the reference box + int codeN,code1,code2; + if (code <= 3) codeN = code-1; else codeN = code-4; + if (codeN==0) { + code1 = 1; + code2 = 2; + } + else if (codeN==1) { + code1 = 0; + code2 = 2; + } + else { + code1 = 0; + code2 = 1; + } + + // find the four corners of the incident face, in reference-face coordinates + btScalar quad[8]; // 2D coordinate of incident face (x,y pairs) + btScalar c1,c2,m11,m12,m21,m22; + c1 = dDOT14 (center,Ra+code1); + c2 = dDOT14 (center,Ra+code2); + // optimize this? - we have already computed this data above, but it is not + // stored in an easy-to-index format. for now it's quicker just to recompute + // the four dot products. + m11 = dDOT44 (Ra+code1,Rb+a1); + m12 = dDOT44 (Ra+code1,Rb+a2); + m21 = dDOT44 (Ra+code2,Rb+a1); + m22 = dDOT44 (Ra+code2,Rb+a2); + { + btScalar k1 = m11*Sb[a1]; + btScalar k2 = m21*Sb[a1]; + btScalar k3 = m12*Sb[a2]; + btScalar k4 = m22*Sb[a2]; + quad[0] = c1 - k1 - k3; + quad[1] = c2 - k2 - k4; + quad[2] = c1 - k1 + k3; + quad[3] = c2 - k2 + k4; + quad[4] = c1 + k1 + k3; + quad[5] = c2 + k2 + k4; + quad[6] = c1 + k1 - k3; + quad[7] = c2 + k2 - k4; + } + + // find the size of the reference face + btScalar rect[2]; + rect[0] = Sa[code1]; + rect[1] = Sa[code2]; + + // intersect the incident and reference faces + btScalar ret[16]; + int n = intersectRectQuad2 (rect,quad,ret); + if (n < 1) return 0; // this should never happen + + // convert the intersection points into reference-face coordinates, + // and compute the contact position and depth for each point. only keep + // those points that have a positive (penetrating) depth. delete points in + // the 'ret' array as necessary so that 'point' and 'ret' correspond. + btScalar point[3*8]; // penetrating contact points + btScalar dep[8]; // depths for those points + btScalar det1 = 1.f/(m11*m22 - m12*m21); + m11 *= det1; + m12 *= det1; + m21 *= det1; + m22 *= det1; + int cnum = 0; // number of penetrating contact points found + for (j=0; j < n; j++) { + btScalar k1 = m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2); + btScalar k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2); + for (i=0; i<3; i++) point[cnum*3+i] = + center[i] + k1*Rb[i*4+a1] + k2*Rb[i*4+a2]; + dep[cnum] = Sa[codeN] - dDOT(normal2,point+cnum*3); + if (dep[cnum] >= 0) { + ret[cnum*2] = ret[j*2]; + ret[cnum*2+1] = ret[j*2+1]; + cnum++; + } + } + if (cnum < 1) return 0; // this should never happen + + // we can't generate more contacts than we actually have + if (maxc > cnum) maxc = cnum; + if (maxc < 1) maxc = 1; + + if (cnum <= maxc) { + + if (code<4) + { + // we have less contacts than we need, so we use them all + for (j=0; j < cnum; j++) + { + btVector3 pointInWorld; + for (i=0; i<3; i++) + pointInWorld[i] = point[j*3+i] + pa[i]; + output.addContactPoint(-normal,pointInWorld,-dep[j]); + + } + } else + { + // we have less contacts than we need, so we use them all + for (j=0; j < cnum; j++) + { + btVector3 pointInWorld; + for (i=0; i<3; i++) + pointInWorld[i] = point[j*3+i] + pa[i]-normal[i]*dep[j]; + //pointInWorld[i] = point[j*3+i] + pa[i]; + output.addContactPoint(-normal,pointInWorld,-dep[j]); + } + } + } + else { + // we have more contacts than are wanted, some of them must be culled. + // find the deepest point, it is always the first contact. + int i1 = 0; + btScalar maxdepth = dep[0]; + for (i=1; i maxdepth) { + maxdepth = dep[i]; + i1 = i; + } + } + + int iret[8]; + cullPoints2 (cnum,ret,maxc,i1,iret); + + for (j=0; j < maxc; j++) { +// dContactGeom *con = CONTACT(contact,skip*j); + // for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i]; + // con->depth = dep[iret[j]]; + + btVector3 posInWorld; + for (i=0; i<3; i++) + posInWorld[i] = point[iret[j]*3+i] + pa[i]; + if (code<4) + { + output.addContactPoint(-normal,posInWorld,-dep[iret[j]]); + } else + { + output.addContactPoint(-normal,posInWorld-normal*dep[iret[j]],-dep[iret[j]]); + } + } + cnum = maxc; + } + + *return_code = code; + return cnum; +} + +void btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* /*debugDraw*/,bool /*swapResults*/) +{ + + const btTransform& transformA = input.m_transformA; + const btTransform& transformB = input.m_transformB; + + int skip = 0; + dContactGeom *contact = 0; + + dMatrix3 R1; + dMatrix3 R2; + + for (int j=0;j<3;j++) + { + R1[0+4*j] = transformA.getBasis()[j].x(); + R2[0+4*j] = transformB.getBasis()[j].x(); + + R1[1+4*j] = transformA.getBasis()[j].y(); + R2[1+4*j] = transformB.getBasis()[j].y(); + + + R1[2+4*j] = transformA.getBasis()[j].z(); + R2[2+4*j] = transformB.getBasis()[j].z(); + + } + + + + btVector3 normal; + btScalar depth; + int return_code; + int maxc = 4; + + + dBoxBox2 (transformA.getOrigin(), + R1, + 2.f*m_box1->getHalfExtentsWithMargin(), + transformB.getOrigin(), + R2, + 2.f*m_box2->getHalfExtentsWithMargin(), + normal, &depth, &return_code, + maxc, contact, skip, + output + ); + +} diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h new file mode 100644 index 0000000..3924377 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h @@ -0,0 +1,44 @@ +/* + * Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith + * Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. + * All rights reserved. Email: russ@q12.org Web: www.q12.org + +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_BOX_BOX_DETECTOR_H +#define BT_BOX_BOX_DETECTOR_H + + +class btBoxShape; +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" + + +/// btBoxBoxDetector wraps the ODE box-box collision detector +/// re-distributed under the Zlib license with permission from Russell L. Smith +struct btBoxBoxDetector : public btDiscreteCollisionDetectorInterface +{ + const btBoxShape* m_box1; + const btBoxShape* m_box2; + +public: + + btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2); + + virtual ~btBoxBoxDetector() {}; + + virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false); + +}; + +#endif //BT_BOX_BOX_DETECTOR_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h b/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h new file mode 100644 index 0000000..f63e092 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h @@ -0,0 +1,48 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COLLISION_CONFIGURATION +#define BT_COLLISION_CONFIGURATION + +struct btCollisionAlgorithmCreateFunc; + +class btStackAlloc; +class btPoolAllocator; + +///btCollisionConfiguration allows to configure Bullet collision detection +///stack allocator size, default collision algorithms and persistent manifold pool size +///@todo: describe the meaning +class btCollisionConfiguration +{ + +public: + + virtual ~btCollisionConfiguration() + { + } + + ///memory pools + virtual btPoolAllocator* getPersistentManifoldPool() = 0; + + virtual btPoolAllocator* getCollisionAlgorithmPool() = 0; + + virtual btStackAlloc* getStackAllocator() = 0; + + virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0; + +}; + +#endif //BT_COLLISION_CONFIGURATION + diff --git a/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h new file mode 100644 index 0000000..62ee66c --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h @@ -0,0 +1,45 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COLLISION_CREATE_FUNC +#define BT_COLLISION_CREATE_FUNC + +#include "LinearMath/btAlignedObjectArray.h" +class btCollisionAlgorithm; +class btCollisionObject; +struct btCollisionObjectWrapper; +struct btCollisionAlgorithmConstructionInfo; + +///Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm +struct btCollisionAlgorithmCreateFunc +{ + bool m_swapped; + + btCollisionAlgorithmCreateFunc() + :m_swapped(false) + { + } + virtual ~btCollisionAlgorithmCreateFunc(){}; + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + + (void)body0Wrap; + (void)body1Wrap; + return 0; + } +}; +#endif //BT_COLLISION_CREATE_FUNC + diff --git a/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp new file mode 100644 index 0000000..d1ef1ff --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp @@ -0,0 +1,314 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btCollisionDispatcher.h" + + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" + +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "LinearMath/btPoolAllocator.h" +#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +int gNumManifold = 0; + +#ifdef BT_DEBUG +#include +#endif + + +btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): +m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD), + m_collisionConfiguration(collisionConfiguration) +{ + int i; + + setNearCallback(defaultNearCallback); + + m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool(); + + m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool(); + + for (i=0;igetCollisionAlgorithmCreateFunc(i,j); + btAssert(m_doubleDispatch[i][j]); + } + } + + +} + + +void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc) +{ + m_doubleDispatch[proxyType0][proxyType1] = createFunc; +} + +btCollisionDispatcher::~btCollisionDispatcher() +{ +} + +btPersistentManifold* btCollisionDispatcher::getNewManifold(const btCollisionObject* body0,const btCollisionObject* body1) +{ + gNumManifold++; + + //btAssert(gNumManifold < 65535); + + + + //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance) + + btScalar contactBreakingThreshold = (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ? + btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold) , body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold)) + : gContactBreakingThreshold ; + + btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold()); + + void* mem = 0; + + if (m_persistentManifoldPoolAllocator->getFreeCount()) + { + mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold)); + } else + { + //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert. + if ((m_dispatcherFlags&CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION)==0) + { + mem = btAlignedAlloc(sizeof(btPersistentManifold),16); + } else + { + btAssert(0); + //make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration + return 0; + } + } + btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold); + manifold->m_index1a = m_manifoldsPtr.size(); + m_manifoldsPtr.push_back(manifold); + + return manifold; +} + +void btCollisionDispatcher::clearManifold(btPersistentManifold* manifold) +{ + manifold->clearManifold(); +} + + +void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold) +{ + + gNumManifold--; + + //printf("releaseManifold: gNumManifold %d\n",gNumManifold); + clearManifold(manifold); + + int findIndex = manifold->m_index1a; + btAssert(findIndex < m_manifoldsPtr.size()); + m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1); + m_manifoldsPtr[findIndex]->m_index1a = findIndex; + m_manifoldsPtr.pop_back(); + + manifold->~btPersistentManifold(); + if (m_persistentManifoldPoolAllocator->validPtr(manifold)) + { + m_persistentManifoldPoolAllocator->freeMemory(manifold); + } else + { + btAlignedFree(manifold); + } + +} + + + +btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold) +{ + + btCollisionAlgorithmConstructionInfo ci; + + ci.m_dispatcher1 = this; + ci.m_manifold = sharedManifold; + btCollisionAlgorithm* algo = m_doubleDispatch[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0Wrap,body1Wrap); + + return algo; +} + + + + +bool btCollisionDispatcher::needsResponse(const btCollisionObject* body0,const btCollisionObject* body1) +{ + //here you can do filtering + bool hasResponse = + (body0->hasContactResponse() && body1->hasContactResponse()); + //no response between two static/kinematic bodies: + hasResponse = hasResponse && + ((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject())); + return hasResponse; +} + +bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const btCollisionObject* body1) +{ + btAssert(body0); + btAssert(body1); + + bool needsCollision = true; + +#ifdef BT_DEBUG + if (!(m_dispatcherFlags & btCollisionDispatcher::CD_STATIC_STATIC_REPORTED)) + { + //broadphase filtering already deals with this + if (body0->isStaticOrKinematicObject() && body1->isStaticOrKinematicObject()) + { + m_dispatcherFlags |= btCollisionDispatcher::CD_STATIC_STATIC_REPORTED; + printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n"); + } + } +#endif //BT_DEBUG + + if ((!body0->isActive()) && (!body1->isActive())) + needsCollision = false; + else if (!body0->checkCollideWith(body1)) + needsCollision = false; + + return needsCollision ; + +} + + + +///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc) +///this is useful for the collision dispatcher. +class btCollisionPairCallback : public btOverlapCallback +{ + const btDispatcherInfo& m_dispatchInfo; + btCollisionDispatcher* m_dispatcher; + +public: + + btCollisionPairCallback(const btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher) + :m_dispatchInfo(dispatchInfo), + m_dispatcher(dispatcher) + { + } + + /*btCollisionPairCallback& operator=(btCollisionPairCallback& other) + { + m_dispatchInfo = other.m_dispatchInfo; + m_dispatcher = other.m_dispatcher; + return *this; + } + */ + + + virtual ~btCollisionPairCallback() {} + + + virtual bool processOverlap(btBroadphasePair& pair) + { + (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo); + + return false; + } +}; + + + +void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) +{ + //m_blockedForChanges = true; + + btCollisionPairCallback collisionCallback(dispatchInfo,this); + + pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher); + + //m_blockedForChanges = false; + +} + + + + +//by default, Bullet will use this near callback +void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo) +{ + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + + if (dispatcher.needsCollision(colObj0,colObj1)) + { + btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform()); + btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform()); + + + //dispatcher will keep algorithms persistent in the collision pair + if (!collisionPair.m_algorithm) + { + collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap); + } + + if (collisionPair.m_algorithm) + { + btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap); + + if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) + { + //discrete collision detection query + + collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult); + } else + { + //continuous collision detection query, time of impact (toi) + btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult); + if (dispatchInfo.m_timeOfImpact > toi) + dispatchInfo.m_timeOfImpact = toi; + + } + } + } + +} + + +void* btCollisionDispatcher::allocateCollisionAlgorithm(int size) +{ + if (m_collisionAlgorithmPoolAllocator->getFreeCount()) + { + return m_collisionAlgorithmPoolAllocator->allocate(size); + } + + //warn user for overflow? + return btAlignedAlloc(static_cast(size), 16); +} + +void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr) +{ + if (m_collisionAlgorithmPoolAllocator->validPtr(ptr)) + { + m_collisionAlgorithmPoolAllocator->freeMemory(ptr); + } else + { + btAlignedFree(ptr); + } +} diff --git a/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h new file mode 100644 index 0000000..92696ee --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h @@ -0,0 +1,171 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COLLISION__DISPATCHER_H +#define BT_COLLISION__DISPATCHER_H + +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" + +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" + +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "LinearMath/btAlignedObjectArray.h" + +class btIDebugDraw; +class btOverlappingPairCache; +class btPoolAllocator; +class btCollisionConfiguration; + +#include "btCollisionCreateFunc.h" + +#define USE_DISPATCH_REGISTRY_ARRAY 1 + +class btCollisionDispatcher; +///user can override this nearcallback for collision filtering and more finegrained control over collision detection +typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo); + + +///btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs. +///Time of Impact, Closest Points and Penetration Depth. +class btCollisionDispatcher : public btDispatcher +{ + +protected: + + int m_dispatcherFlags; + + btAlignedObjectArray m_manifoldsPtr; + + btManifoldResult m_defaultManifoldResult; + + btNearCallback m_nearCallback; + + btPoolAllocator* m_collisionAlgorithmPoolAllocator; + + btPoolAllocator* m_persistentManifoldPoolAllocator; + + btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]; + + btCollisionConfiguration* m_collisionConfiguration; + + +public: + + enum DispatcherFlags + { + CD_STATIC_STATIC_REPORTED = 1, + CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD = 2, + CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION = 4 + }; + + int getDispatcherFlags() const + { + return m_dispatcherFlags; + } + + void setDispatcherFlags(int flags) + { + m_dispatcherFlags = flags; + } + + ///registerCollisionCreateFunc allows registration of custom/alternative collision create functions + void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc); + + int getNumManifolds() const + { + return int( m_manifoldsPtr.size()); + } + + btPersistentManifold** getInternalManifoldPointer() + { + return m_manifoldsPtr.size()? &m_manifoldsPtr[0] : 0; + } + + btPersistentManifold* getManifoldByIndexInternal(int index) + { + return m_manifoldsPtr[index]; + } + + const btPersistentManifold* getManifoldByIndexInternal(int index) const + { + return m_manifoldsPtr[index]; + } + + btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration); + + virtual ~btCollisionDispatcher(); + + virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1); + + virtual void releaseManifold(btPersistentManifold* manifold); + + + virtual void clearManifold(btPersistentManifold* manifold); + + btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold = 0); + + virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1); + + virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1); + + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ; + + void setNearCallback(btNearCallback nearCallback) + { + m_nearCallback = nearCallback; + } + + btNearCallback getNearCallback() const + { + return m_nearCallback; + } + + //by default, Bullet will use this near callback + static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo); + + virtual void* allocateCollisionAlgorithm(int size); + + virtual void freeCollisionAlgorithm(void* ptr); + + btCollisionConfiguration* getCollisionConfiguration() + { + return m_collisionConfiguration; + } + + const btCollisionConfiguration* getCollisionConfiguration() const + { + return m_collisionConfiguration; + } + + void setCollisionConfiguration(btCollisionConfiguration* config) + { + m_collisionConfiguration = config; + } + + virtual btPoolAllocator* getInternalManifoldPool() + { + return m_persistentManifoldPoolAllocator; + } + + virtual const btPoolAllocator* getInternalManifoldPool() const + { + return m_persistentManifoldPoolAllocator; + } + +}; + +#endif //BT_COLLISION__DISPATCHER_H + diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp new file mode 100644 index 0000000..cf8ed59 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp @@ -0,0 +1,116 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btCollisionObject.h" +#include "LinearMath/btSerializer.h" + +btCollisionObject::btCollisionObject() + : m_anisotropicFriction(1.f,1.f,1.f), + m_hasAnisotropicFriction(false), + m_contactProcessingThreshold(BT_LARGE_FLOAT), + m_broadphaseHandle(0), + m_collisionShape(0), + m_extensionPointer(0), + m_rootCollisionShape(0), + m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT), + m_islandTag1(-1), + m_companionId(-1), + m_activationState1(1), + m_deactivationTime(btScalar(0.)), + m_friction(btScalar(0.5)), + m_rollingFriction(0.0f), + m_restitution(btScalar(0.)), + m_internalType(CO_COLLISION_OBJECT), + m_userObjectPointer(0), + m_hitFraction(btScalar(1.)), + m_ccdSweptSphereRadius(btScalar(0.)), + m_ccdMotionThreshold(btScalar(0.)), + m_checkCollideWith(false) +{ + m_worldTransform.setIdentity(); +} + +btCollisionObject::~btCollisionObject() +{ +} + +void btCollisionObject::setActivationState(int newState) const +{ + if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION)) + m_activationState1 = newState; +} + +void btCollisionObject::forceActivationState(int newState) const +{ + m_activationState1 = newState; +} + +void btCollisionObject::activate(bool forceActivation) const +{ + if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT))) + { + setActivationState(ACTIVE_TAG); + m_deactivationTime = btScalar(0.); + } +} + +const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* serializer) const +{ + + btCollisionObjectData* dataOut = (btCollisionObjectData*)dataBuffer; + + m_worldTransform.serialize(dataOut->m_worldTransform); + m_interpolationWorldTransform.serialize(dataOut->m_interpolationWorldTransform); + m_interpolationLinearVelocity.serialize(dataOut->m_interpolationLinearVelocity); + m_interpolationAngularVelocity.serialize(dataOut->m_interpolationAngularVelocity); + m_anisotropicFriction.serialize(dataOut->m_anisotropicFriction); + dataOut->m_hasAnisotropicFriction = m_hasAnisotropicFriction; + dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold; + dataOut->m_broadphaseHandle = 0; + dataOut->m_collisionShape = serializer->getUniquePointer(m_collisionShape); + dataOut->m_rootCollisionShape = 0;//@todo + dataOut->m_collisionFlags = m_collisionFlags; + dataOut->m_islandTag1 = m_islandTag1; + dataOut->m_companionId = m_companionId; + dataOut->m_activationState1 = m_activationState1; + dataOut->m_deactivationTime = m_deactivationTime; + dataOut->m_friction = m_friction; + dataOut->m_rollingFriction = m_rollingFriction; + dataOut->m_restitution = m_restitution; + dataOut->m_internalType = m_internalType; + + char* name = (char*) serializer->findNameForPointer(this); + dataOut->m_name = (char*)serializer->getUniquePointer(name); + if (dataOut->m_name) + { + serializer->serializeName(name); + } + dataOut->m_hitFraction = m_hitFraction; + dataOut->m_ccdSweptSphereRadius = m_ccdSweptSphereRadius; + dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold; + dataOut->m_checkCollideWith = m_checkCollideWith; + + return btCollisionObjectDataName; +} + + +void btCollisionObject::serializeSingleObject(class btSerializer* serializer) const +{ + int len = calculateSerializeBufferSize(); + btChunk* chunk = serializer->allocate(len,1); + const char* structType = serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_COLLISIONOBJECT_CODE,(void*)this); +} diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/src/BulletCollision/CollisionDispatch/btCollisionObject.h new file mode 100644 index 0000000..2f17967 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -0,0 +1,534 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COLLISION_OBJECT_H +#define BT_COLLISION_OBJECT_H + +#include "LinearMath/btTransform.h" + +//island management, m_activationState1 +#define ACTIVE_TAG 1 +#define ISLAND_SLEEPING 2 +#define WANTS_DEACTIVATION 3 +#define DISABLE_DEACTIVATION 4 +#define DISABLE_SIMULATION 5 + +struct btBroadphaseProxy; +class btCollisionShape; +struct btCollisionShapeData; +#include "LinearMath/btMotionState.h" +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btAlignedObjectArray.h" + +typedef btAlignedObjectArray btCollisionObjectArray; + +#ifdef BT_USE_DOUBLE_PRECISION +#define btCollisionObjectData btCollisionObjectDoubleData +#define btCollisionObjectDataName "btCollisionObjectDoubleData" +#else +#define btCollisionObjectData btCollisionObjectFloatData +#define btCollisionObjectDataName "btCollisionObjectFloatData" +#endif + + +/// btCollisionObject can be used to manage collision detection objects. +/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy. +/// They can be added to the btCollisionWorld. +ATTRIBUTE_ALIGNED16(class) btCollisionObject +{ + +protected: + + btTransform m_worldTransform; + + ///m_interpolationWorldTransform is used for CCD and interpolation + ///it can be either previous or future (predicted) transform + btTransform m_interpolationWorldTransform; + //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) + //without destroying the continuous interpolated motion (which uses this interpolation velocities) + btVector3 m_interpolationLinearVelocity; + btVector3 m_interpolationAngularVelocity; + + btVector3 m_anisotropicFriction; + int m_hasAnisotropicFriction; + btScalar m_contactProcessingThreshold; + + btBroadphaseProxy* m_broadphaseHandle; + btCollisionShape* m_collisionShape; + ///m_extensionPointer is used by some internal low-level Bullet extensions. + void* m_extensionPointer; + + ///m_rootCollisionShape is temporarily used to store the original collision shape + ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes + ///If it is NULL, the m_collisionShape is not temporarily replaced. + btCollisionShape* m_rootCollisionShape; + + int m_collisionFlags; + + int m_islandTag1; + int m_companionId; + + mutable int m_activationState1; + mutable btScalar m_deactivationTime; + + btScalar m_friction; + btScalar m_restitution; + btScalar m_rollingFriction; + + ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc. + ///do not assign your own m_internalType unless you write a new dynamics object class. + int m_internalType; + + ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer + void* m_userObjectPointer; + + ///time of impact calculation + btScalar m_hitFraction; + + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: + btScalar m_ccdSweptSphereRadius; + + /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold + btScalar m_ccdMotionThreshold; + + /// If some object should have elaborate collision filtering by sub-classes + int m_checkCollideWith; + + virtual bool checkCollideWithOverride(const btCollisionObject* /* co */) const + { + return true; + } + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + enum CollisionFlags + { + CF_STATIC_OBJECT= 1, + CF_KINEMATIC_OBJECT= 2, + CF_NO_CONTACT_RESPONSE = 4, + CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution) + CF_CHARACTER_OBJECT = 16, + CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing + CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing + }; + + enum CollisionObjectTypes + { + CO_COLLISION_OBJECT =1, + CO_RIGID_BODY=2, + ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter + ///It is useful for collision sensors, explosion objects, character controller etc. + CO_GHOST_OBJECT=4, + CO_SOFT_BODY=8, + CO_HF_FLUID=16, + CO_USER_TYPE=32 + }; + + enum AnisotropicFrictionFlags + { + CF_ANISOTROPIC_FRICTION_DISABLED=0, + CF_ANISOTROPIC_FRICTION = 1, + CF_ANISOTROPIC_ROLLING_FRICTION = 2 + }; + + SIMD_FORCE_INLINE bool mergesSimulationIslands() const + { + ///static objects, kinematic and object without contact response don't merge islands + return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0); + } + + const btVector3& getAnisotropicFriction() const + { + return m_anisotropicFriction; + } + void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION) + { + m_anisotropicFriction = anisotropicFriction; + bool isUnity = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f); + m_hasAnisotropicFriction = isUnity?frictionMode : 0; + } + bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const + { + return (m_hasAnisotropicFriction&frictionMode)!=0; + } + + ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default. + ///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges + void setContactProcessingThreshold( btScalar contactProcessingThreshold) + { + m_contactProcessingThreshold = contactProcessingThreshold; + } + btScalar getContactProcessingThreshold() const + { + return m_contactProcessingThreshold; + } + + SIMD_FORCE_INLINE bool isStaticObject() const { + return (m_collisionFlags & CF_STATIC_OBJECT) != 0; + } + + SIMD_FORCE_INLINE bool isKinematicObject() const + { + return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0; + } + + SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const + { + return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ; + } + + SIMD_FORCE_INLINE bool hasContactResponse() const { + return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0; + } + + + btCollisionObject(); + + virtual ~btCollisionObject(); + + virtual void setCollisionShape(btCollisionShape* collisionShape) + { + m_collisionShape = collisionShape; + m_rootCollisionShape = collisionShape; + } + + SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const + { + return m_collisionShape; + } + + SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() + { + return m_collisionShape; + } + + + + + + ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions. + ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead. + void* internalGetExtensionPointer() const + { + return m_extensionPointer; + } + ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions + ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead. + void internalSetExtensionPointer(void* pointer) + { + m_extensionPointer = pointer; + } + + SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;} + + void setActivationState(int newState) const; + + void setDeactivationTime(btScalar time) + { + m_deactivationTime = time; + } + btScalar getDeactivationTime() const + { + return m_deactivationTime; + } + + void forceActivationState(int newState) const; + + void activate(bool forceActivation = false) const; + + SIMD_FORCE_INLINE bool isActive() const + { + return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION)); + } + + void setRestitution(btScalar rest) + { + m_restitution = rest; + } + btScalar getRestitution() const + { + return m_restitution; + } + void setFriction(btScalar frict) + { + m_friction = frict; + } + btScalar getFriction() const + { + return m_friction; + } + + void setRollingFriction(btScalar frict) + { + m_rollingFriction = frict; + } + btScalar getRollingFriction() const + { + return m_rollingFriction; + } + + + ///reserved for Bullet internal usage + int getInternalType() const + { + return m_internalType; + } + + btTransform& getWorldTransform() + { + return m_worldTransform; + } + + const btTransform& getWorldTransform() const + { + return m_worldTransform; + } + + void setWorldTransform(const btTransform& worldTrans) + { + m_worldTransform = worldTrans; + } + + + SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle() + { + return m_broadphaseHandle; + } + + SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const + { + return m_broadphaseHandle; + } + + void setBroadphaseHandle(btBroadphaseProxy* handle) + { + m_broadphaseHandle = handle; + } + + + const btTransform& getInterpolationWorldTransform() const + { + return m_interpolationWorldTransform; + } + + btTransform& getInterpolationWorldTransform() + { + return m_interpolationWorldTransform; + } + + void setInterpolationWorldTransform(const btTransform& trans) + { + m_interpolationWorldTransform = trans; + } + + void setInterpolationLinearVelocity(const btVector3& linvel) + { + m_interpolationLinearVelocity = linvel; + } + + void setInterpolationAngularVelocity(const btVector3& angvel) + { + m_interpolationAngularVelocity = angvel; + } + + const btVector3& getInterpolationLinearVelocity() const + { + return m_interpolationLinearVelocity; + } + + const btVector3& getInterpolationAngularVelocity() const + { + return m_interpolationAngularVelocity; + } + + SIMD_FORCE_INLINE int getIslandTag() const + { + return m_islandTag1; + } + + void setIslandTag(int tag) + { + m_islandTag1 = tag; + } + + SIMD_FORCE_INLINE int getCompanionId() const + { + return m_companionId; + } + + void setCompanionId(int id) + { + m_companionId = id; + } + + SIMD_FORCE_INLINE btScalar getHitFraction() const + { + return m_hitFraction; + } + + void setHitFraction(btScalar hitFraction) + { + m_hitFraction = hitFraction; + } + + + SIMD_FORCE_INLINE int getCollisionFlags() const + { + return m_collisionFlags; + } + + void setCollisionFlags(int flags) + { + m_collisionFlags = flags; + } + + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: + btScalar getCcdSweptSphereRadius() const + { + return m_ccdSweptSphereRadius; + } + + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: + void setCcdSweptSphereRadius(btScalar radius) + { + m_ccdSweptSphereRadius = radius; + } + + btScalar getCcdMotionThreshold() const + { + return m_ccdMotionThreshold; + } + + btScalar getCcdSquareMotionThreshold() const + { + return m_ccdMotionThreshold*m_ccdMotionThreshold; + } + + + + /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold + void setCcdMotionThreshold(btScalar ccdMotionThreshold) + { + m_ccdMotionThreshold = ccdMotionThreshold; + } + + ///users can point to their objects, userPointer is not used by Bullet + void* getUserPointer() const + { + return m_userObjectPointer; + } + + ///users can point to their objects, userPointer is not used by Bullet + void setUserPointer(void* userPointer) + { + m_userObjectPointer = userPointer; + } + + + inline bool checkCollideWith(const btCollisionObject* co) const + { + if (m_checkCollideWith) + return checkCollideWithOverride(co); + + return true; + } + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; + + virtual void serializeSingleObject(class btSerializer* serializer) const; + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btCollisionObjectDoubleData +{ + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + + btTransformDoubleData m_worldTransform; + btTransformDoubleData m_interpolationWorldTransform; + btVector3DoubleData m_interpolationLinearVelocity; + btVector3DoubleData m_interpolationAngularVelocity; + btVector3DoubleData m_anisotropicFriction; + double m_contactProcessingThreshold; + double m_deactivationTime; + double m_friction; + double m_rollingFriction; + double m_restitution; + double m_hitFraction; + double m_ccdSweptSphereRadius; + double m_ccdMotionThreshold; + + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + + char m_padding[4]; +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btCollisionObjectFloatData +{ + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + + btTransformFloatData m_worldTransform; + btTransformFloatData m_interpolationWorldTransform; + btVector3FloatData m_interpolationLinearVelocity; + btVector3FloatData m_interpolationAngularVelocity; + btVector3FloatData m_anisotropicFriction; + float m_contactProcessingThreshold; + float m_deactivationTime; + float m_friction; + float m_rollingFriction; + + float m_restitution; + float m_hitFraction; + float m_ccdSweptSphereRadius; + float m_ccdMotionThreshold; + + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + char m_padding[4]; +}; + + + +SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const +{ + return sizeof(btCollisionObjectData); +} + + + +#endif //BT_COLLISION_OBJECT_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h b/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h new file mode 100644 index 0000000..ac2e85c --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h @@ -0,0 +1,40 @@ +#ifndef BT_COLLISION_OBJECT_WRAPPER_H +#define BT_COLLISION_OBJECT_WRAPPER_H + +///btCollisionObjectWrapperis an internal data structure. +///Most users can ignore this and use btCollisionObject and btCollisionShape instead +class btCollisionShape; +class btCollisionObject; +class btTransform; +#include "LinearMath/btScalar.h" // for SIMD_FORCE_INLINE definition + +#define BT_DECLARE_STACK_ONLY_OBJECT \ + private: \ + void* operator new(size_t size); \ + void operator delete(void*); + +struct btCollisionObjectWrapper; +struct btCollisionObjectWrapper +{ +BT_DECLARE_STACK_ONLY_OBJECT + +private: + btCollisionObjectWrapper(const btCollisionObjectWrapper&); // not implemented. Not allowed. + btCollisionObjectWrapper* operator=(const btCollisionObjectWrapper&); + +public: + const btCollisionObjectWrapper* m_parent; + const btCollisionShape* m_shape; + const btCollisionObject* m_collisionObject; + const btTransform& m_worldTransform; + + btCollisionObjectWrapper(const btCollisionObjectWrapper* parent, const btCollisionShape* shape, const btCollisionObject* collisionObject, const btTransform& worldTransform) + : m_parent(parent), m_shape(shape), m_collisionObject(collisionObject), m_worldTransform(worldTransform) + {} + + SIMD_FORCE_INLINE const btTransform& getWorldTransform() const { return m_worldTransform; } + SIMD_FORCE_INLINE const btCollisionObject* getCollisionObject() const { return m_collisionObject; } + SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { return m_shape; } +}; + +#endif //BT_COLLISION_OBJECT_WRAPPER_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp new file mode 100644 index 0000000..91f4c62 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -0,0 +1,1539 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btCollisionWorld.h" +#include "btCollisionDispatcher.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/BroadphaseCollision/btDbvt.h" +#include "LinearMath/btAabbUtil2.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btStackAlloc.h" +#include "LinearMath/btSerializer.h" +#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +//#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION + + +//#define USE_BRUTEFORCE_RAYBROADPHASE 1 +//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest +//#define RECALCULATE_AABB_RAYCAST 1 + +//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor) +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" + + +///for debug drawing + +//for debug rendering +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionShapes/btConeShape.h" +#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btTriangleCallback.h" +#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" + + + +btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration) +:m_dispatcher1(dispatcher), +m_broadphasePairCache(pairCache), +m_debugDrawer(0), +m_forceUpdateAllAabbs(true) +{ + m_stackAlloc = collisionConfiguration->getStackAllocator(); + m_dispatchInfo.m_stackAllocator = m_stackAlloc; +} + + +btCollisionWorld::~btCollisionWorld() +{ + + //clean up remaining objects + int i; + for (i=0;igetBroadphaseHandle(); + if (bp) + { + // + // only clear the cached algorithms + // + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); + getBroadphase()->destroyProxy(bp,m_dispatcher1); + collisionObject->setBroadphaseHandle(0); + } + } + + +} + + + + + + + + + + +void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask) +{ + + btAssert(collisionObject); + + //check that the object isn't already added + btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size()); + + m_collisionObjects.push_back(collisionObject); + + //calculate new AABB + btTransform trans = collisionObject->getWorldTransform(); + + btVector3 minAabb; + btVector3 maxAabb; + collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb); + + int type = collisionObject->getCollisionShape()->getShapeType(); + collisionObject->setBroadphaseHandle( getBroadphase()->createProxy( + minAabb, + maxAabb, + type, + collisionObject, + collisionFilterGroup, + collisionFilterMask, + m_dispatcher1,0 + )) ; + + + + + +} + + + +void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj) +{ + btVector3 minAabb,maxAabb; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); + //need to increase the aabb for contact thresholds + btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold); + minAabb -= contactThreshold; + maxAabb += contactThreshold; + + if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject()) + { + btVector3 minAabb2,maxAabb2; + colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2); + minAabb2 -= contactThreshold; + maxAabb2 += contactThreshold; + minAabb.setMin(minAabb2); + maxAabb.setMax(maxAabb2); + } + + btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache; + + //moving objects should be moderately sized, probably something wrong if not + if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12))) + { + bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); + } else + { + //something went wrong, investigate + //this assert is unwanted in 3D modelers (danger of loosing work) + colObj->setActivationState(DISABLE_SIMULATION); + + static bool reportMe = true; + if (reportMe && m_debugDrawer) + { + reportMe = false; + m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation"); + m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n"); + m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n"); + m_debugDrawer->reportErrorWarning("Thanks.\n"); + } + } +} + +void btCollisionWorld::updateAabbs() +{ + BT_PROFILE("updateAabbs"); + + btTransform predictedTrans; + for ( int i=0;iisActive()) + { + updateSingleAabb(colObj); + } + } +} + + +void btCollisionWorld::computeOverlappingPairs() +{ + BT_PROFILE("calculateOverlappingPairs"); + m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); +} + +void btCollisionWorld::performDiscreteCollisionDetection() +{ + BT_PROFILE("performDiscreteCollisionDetection"); + + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + + updateAabbs(); + + computeOverlappingPairs(); + + btDispatcher* dispatcher = getDispatcher(); + { + BT_PROFILE("dispatchAllCollisionPairs"); + if (dispatcher) + dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); + } + +} + + + +void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) +{ + + + //bool removeFromBroadphase = false; + + { + + btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle(); + if (bp) + { + // + // only clear the cached algorithms + // + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); + getBroadphase()->destroyProxy(bp,m_dispatcher1); + collisionObject->setBroadphaseHandle(0); + } + } + + + //swapremove + m_collisionObjects.remove(collisionObject); + +} + + +void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback) +{ + btCollisionObjectWrapper colObWrap(0,collisionShape,collisionObject,colObjWorldTransform); + btCollisionWorld::rayTestSingleInternal(rayFromTrans,rayToTrans,&colObWrap,resultCallback); +} + +void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans, + const btCollisionObjectWrapper* collisionObjectWrap, + RayResultCallback& resultCallback) +{ + btSphereShape pointShape(btScalar(0.0)); + pointShape.setMargin(0.f); + const btConvexShape* castShape = &pointShape; + const btCollisionShape* collisionShape = collisionObjectWrap->getCollisionShape(); + const btTransform& colObjWorldTransform = collisionObjectWrap->getWorldTransform(); + + if (collisionShape->isConvex()) + { + // BT_PROFILE("rayTestConvex"); + btConvexCast::CastResult castResult; + castResult.m_fraction = resultCallback.m_closestHitFraction; + + btConvexShape* convexShape = (btConvexShape*) collisionShape; + btVoronoiSimplexSolver simplexSolver; +#define USE_SUBSIMPLEX_CONVEX_CAST 1 +#ifdef USE_SUBSIMPLEX_CONVEX_CAST + btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver); +#else + //btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver); + //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); +#endif //#USE_SUBSIMPLEX_CONVEX_CAST + + if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) + { + //add hit + if (castResult.m_normal.length2() > btScalar(0.0001)) + { + if (castResult.m_fraction < resultCallback.m_closestHitFraction) + { +#ifdef USE_SUBSIMPLEX_CONVEX_CAST + //rotate normal into worldspace + castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal; +#endif //USE_SUBSIMPLEX_CONVEX_CAST + + castResult.m_normal.normalize(); + btCollisionWorld::LocalRayResult localRayResult + ( + collisionObjectWrap->getCollisionObject(), + 0, + castResult.m_normal, + castResult.m_fraction + ); + + bool normalInWorldSpace = true; + resultCallback.addSingleResult(localRayResult, normalInWorldSpace); + + } + } + } + } else { + if (collisionShape->isConcave()) + { + // BT_PROFILE("rayTestConcave"); + if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + ///optimized version for btBvhTriangleMeshShape + btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; + btTransform worldTocollisionObject = colObjWorldTransform.inverse(); + btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin(); + btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin(); + + //ConvexCast::CastResult + struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback + { + btCollisionWorld::RayResultCallback* m_resultCallback; + const btCollisionObject* m_collisionObject; + btTriangleMeshShape* m_triangleMesh; + + btTransform m_colObjWorldTransform; + + BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, + btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform): + //@BP Mod + btTriangleRaycastCallback(from,to, resultCallback->m_flags), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh), + m_colObjWorldTransform(colObjWorldTransform) + { + } + + + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = partId; + shapeInfo.m_triangleIndex = triangleIndex; + + btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal; + + btCollisionWorld::LocalRayResult rayResult + (m_collisionObject, + &shapeInfo, + hitNormalWorld, + hitFraction); + + bool normalInWorldSpace = true; + return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace); + } + + }; + + BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform); + rcb.m_hitFraction = resultCallback.m_closestHitFraction; + triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal); + } else + { + //generic (slower) case + btConcaveShape* concaveShape = (btConcaveShape*)collisionShape; + + btTransform worldTocollisionObject = colObjWorldTransform.inverse(); + + btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin(); + btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin(); + + //ConvexCast::CastResult + + struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback + { + btCollisionWorld::RayResultCallback* m_resultCallback; + const btCollisionObject* m_collisionObject; + btConcaveShape* m_triangleMesh; + + btTransform m_colObjWorldTransform; + + BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, + btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform): + //@BP Mod + btTriangleRaycastCallback(from,to, resultCallback->m_flags), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh), + m_colObjWorldTransform(colObjWorldTransform) + { + } + + + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = partId; + shapeInfo.m_triangleIndex = triangleIndex; + + btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal; + + btCollisionWorld::LocalRayResult rayResult + (m_collisionObject, + &shapeInfo, + hitNormalWorld, + hitFraction); + + bool normalInWorldSpace = true; + return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace); + } + + }; + + + BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform); + rcb.m_hitFraction = resultCallback.m_closestHitFraction; + + btVector3 rayAabbMinLocal = rayFromLocal; + rayAabbMinLocal.setMin(rayToLocal); + btVector3 rayAabbMaxLocal = rayFromLocal; + rayAabbMaxLocal.setMax(rayToLocal); + + concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal); + } + } else { + // BT_PROFILE("rayTestCompound"); + if (collisionShape->isCompound()) + { + struct LocalInfoAdder2 : public RayResultCallback + { + RayResultCallback* m_userCallback; + int m_i; + + LocalInfoAdder2 (int i, RayResultCallback *user) + : m_userCallback(user), m_i(i) + { + m_closestHitFraction = m_userCallback->m_closestHitFraction; + m_flags = m_userCallback->m_flags; + } + virtual bool needsCollision(btBroadphaseProxy* p) const + { + return m_userCallback->needsCollision(p); + } + + virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = -1; + shapeInfo.m_triangleIndex = m_i; + if (r.m_localShapeInfo == NULL) + r.m_localShapeInfo = &shapeInfo; + + const btScalar result = m_userCallback->addSingleResult(r, b); + m_closestHitFraction = m_userCallback->m_closestHitFraction; + return result; + } + }; + + struct RayTester : btDbvt::ICollide + { + const btCollisionObject* m_collisionObject; + const btCompoundShape* m_compoundShape; + const btTransform& m_colObjWorldTransform; + const btTransform& m_rayFromTrans; + const btTransform& m_rayToTrans; + RayResultCallback& m_resultCallback; + + RayTester(const btCollisionObject* collisionObject, + const btCompoundShape* compoundShape, + const btTransform& colObjWorldTransform, + const btTransform& rayFromTrans, + const btTransform& rayToTrans, + RayResultCallback& resultCallback): + m_collisionObject(collisionObject), + m_compoundShape(compoundShape), + m_colObjWorldTransform(colObjWorldTransform), + m_rayFromTrans(rayFromTrans), + m_rayToTrans(rayToTrans), + m_resultCallback(resultCallback) + { + + } + + void ProcessLeaf(int i) + { + const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i); + const btTransform& childTrans = m_compoundShape->getChildTransform(i); + btTransform childWorldTrans = m_colObjWorldTransform * childTrans; + + btCollisionObjectWrapper tmpOb(0,childCollisionShape,m_collisionObject,childWorldTrans); + // replace collision shape so that callback can determine the triangle + + + + LocalInfoAdder2 my_cb(i, &m_resultCallback); + + rayTestSingleInternal( + m_rayFromTrans, + m_rayToTrans, + &tmpOb, + my_cb); + + } + + void Process(const btDbvtNode* leaf) + { + ProcessLeaf(leaf->dataAsInt); + } + }; + + const btCompoundShape* compoundShape = static_cast(collisionShape); + const btDbvt* dbvt = compoundShape->getDynamicAabbTree(); + + + RayTester rayCB( + collisionObjectWrap->getCollisionObject(), + compoundShape, + colObjWorldTransform, + rayFromTrans, + rayToTrans, + resultCallback); +#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION + if (dbvt) + { + btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin(); + btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin(); + btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB); + } + else +#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION + { + for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i) + { + rayCB.ProcessLeaf(i); + } + } + } + } + } +} + +void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + ConvexResultCallback& resultCallback, btScalar allowedPenetration) +{ + btCollisionObjectWrapper tmpOb(0,collisionShape,collisionObject,colObjWorldTransform); + btCollisionWorld::objectQuerySingleInternal(castShape,convexFromTrans,convexToTrans,&tmpOb,resultCallback,allowedPenetration); +} + +void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans, + const btCollisionObjectWrapper* colObjWrap, + ConvexResultCallback& resultCallback, btScalar allowedPenetration) +{ + const btCollisionShape* collisionShape = colObjWrap->getCollisionShape(); + const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform(); + + if (collisionShape->isConvex()) + { + //BT_PROFILE("convexSweepConvex"); + btConvexCast::CastResult castResult; + castResult.m_allowedPenetration = allowedPenetration; + castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//?? + + btConvexShape* convexShape = (btConvexShape*) collisionShape; + btVoronoiSimplexSolver simplexSolver; + btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver; + + btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver); + //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver); + //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver); + + btConvexCast* castPtr = &convexCaster1; + + + + if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) + { + //add hit + if (castResult.m_normal.length2() > btScalar(0.0001)) + { + if (castResult.m_fraction < resultCallback.m_closestHitFraction) + { + castResult.m_normal.normalize(); + btCollisionWorld::LocalConvexResult localConvexResult + ( + colObjWrap->getCollisionObject(), + 0, + castResult.m_normal, + castResult.m_hitPoint, + castResult.m_fraction + ); + + bool normalInWorldSpace = true; + resultCallback.addSingleResult(localConvexResult, normalInWorldSpace); + + } + } + } + } else { + if (collisionShape->isConcave()) + { + if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + //BT_PROFILE("convexSweepbtBvhTriangleMesh"); + btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; + btTransform worldTocollisionObject = colObjWorldTransform.inverse(); + btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin(); + btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin(); + // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation + btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis()); + + //ConvexCast::CastResult + struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback + { + btCollisionWorld::ConvexResultCallback* m_resultCallback; + const btCollisionObject* m_collisionObject; + btTriangleMeshShape* m_triangleMesh; + + BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to, + btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld): + btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh) + { + } + + + virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex ) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = partId; + shapeInfo.m_triangleIndex = triangleIndex; + if (hitFraction <= m_resultCallback->m_closestHitFraction) + { + + btCollisionWorld::LocalConvexResult convexResult + (m_collisionObject, + &shapeInfo, + hitNormalLocal, + hitPointLocal, + hitFraction); + + bool normalInWorldSpace = true; + + + return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace); + } + return hitFraction; + } + + }; + + BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),triangleMesh, colObjWorldTransform); + tccb.m_hitFraction = resultCallback.m_closestHitFraction; + tccb.m_allowedPenetration = allowedPenetration; + btVector3 boxMinLocal, boxMaxLocal; + castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal); + triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal); + } else + { + if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE) + { + btConvexCast::CastResult castResult; + castResult.m_allowedPenetration = allowedPenetration; + castResult.m_fraction = resultCallback.m_closestHitFraction; + btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape; + btContinuousConvexCollision convexCaster1(castShape,planeShape); + btConvexCast* castPtr = &convexCaster1; + + if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) + { + //add hit + if (castResult.m_normal.length2() > btScalar(0.0001)) + { + if (castResult.m_fraction < resultCallback.m_closestHitFraction) + { + castResult.m_normal.normalize(); + btCollisionWorld::LocalConvexResult localConvexResult + ( + colObjWrap->getCollisionObject(), + 0, + castResult.m_normal, + castResult.m_hitPoint, + castResult.m_fraction + ); + + bool normalInWorldSpace = true; + resultCallback.addSingleResult(localConvexResult, normalInWorldSpace); + } + } + } + + } else + { + //BT_PROFILE("convexSweepConcave"); + btConcaveShape* concaveShape = (btConcaveShape*)collisionShape; + btTransform worldTocollisionObject = colObjWorldTransform.inverse(); + btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin(); + btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin(); + // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation + btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis()); + + //ConvexCast::CastResult + struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback + { + btCollisionWorld::ConvexResultCallback* m_resultCallback; + const btCollisionObject* m_collisionObject; + btConcaveShape* m_triangleMesh; + + BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to, + btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld): + btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh) + { + } + + + virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex ) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = partId; + shapeInfo.m_triangleIndex = triangleIndex; + if (hitFraction <= m_resultCallback->m_closestHitFraction) + { + + btCollisionWorld::LocalConvexResult convexResult + (m_collisionObject, + &shapeInfo, + hitNormalLocal, + hitPointLocal, + hitFraction); + + bool normalInWorldSpace = false; + + return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace); + } + return hitFraction; + } + + }; + + BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),concaveShape, colObjWorldTransform); + tccb.m_hitFraction = resultCallback.m_closestHitFraction; + tccb.m_allowedPenetration = allowedPenetration; + btVector3 boxMinLocal, boxMaxLocal; + castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal); + + btVector3 rayAabbMinLocal = convexFromLocal; + rayAabbMinLocal.setMin(convexToLocal); + btVector3 rayAabbMaxLocal = convexFromLocal; + rayAabbMaxLocal.setMax(convexToLocal); + rayAabbMinLocal += boxMinLocal; + rayAabbMaxLocal += boxMaxLocal; + concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal); + } + } + } else { + ///@todo : use AABB tree or other BVH acceleration structure! + if (collisionShape->isCompound()) + { + BT_PROFILE("convexSweepCompound"); + const btCompoundShape* compoundShape = static_cast(collisionShape); + int i=0; + for (i=0;igetNumChildShapes();i++) + { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i); + btTransform childWorldTrans = colObjWorldTransform * childTrans; + + struct LocalInfoAdder : public ConvexResultCallback { + ConvexResultCallback* m_userCallback; + int m_i; + + LocalInfoAdder (int i, ConvexResultCallback *user) + : m_userCallback(user), m_i(i) + { + m_closestHitFraction = m_userCallback->m_closestHitFraction; + } + virtual bool needsCollision(btBroadphaseProxy* p) const + { + return m_userCallback->needsCollision(p); + } + virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult& r, bool b) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = -1; + shapeInfo.m_triangleIndex = m_i; + if (r.m_localShapeInfo == NULL) + r.m_localShapeInfo = &shapeInfo; + const btScalar result = m_userCallback->addSingleResult(r, b); + m_closestHitFraction = m_userCallback->m_closestHitFraction; + return result; + + } + }; + + LocalInfoAdder my_cb(i, &resultCallback); + + btCollisionObjectWrapper tmpObj(colObjWrap,childCollisionShape,colObjWrap->getCollisionObject(),childWorldTrans); + + objectQuerySingleInternal(castShape, convexFromTrans,convexToTrans, + &tmpObj,my_cb, allowedPenetration); + + } + } + } + } +} + + +struct btSingleRayCallback : public btBroadphaseRayCallback +{ + + btVector3 m_rayFromWorld; + btVector3 m_rayToWorld; + btTransform m_rayFromTrans; + btTransform m_rayToTrans; + btVector3 m_hitNormal; + + const btCollisionWorld* m_world; + btCollisionWorld::RayResultCallback& m_resultCallback; + + btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback) + :m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld), + m_world(world), + m_resultCallback(resultCallback) + { + m_rayFromTrans.setIdentity(); + m_rayFromTrans.setOrigin(m_rayFromWorld); + m_rayToTrans.setIdentity(); + m_rayToTrans.setOrigin(m_rayToWorld); + + btVector3 rayDir = (rayToWorld-rayFromWorld); + + rayDir.normalize (); + ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT + m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; + m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; + m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2]; + m_signs[0] = m_rayDirectionInverse[0] < 0.0; + m_signs[1] = m_rayDirectionInverse[1] < 0.0; + m_signs[2] = m_rayDirectionInverse[2] < 0.0; + + m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld); + + } + + + + virtual bool process(const btBroadphaseProxy* proxy) + { + ///terminate further ray tests, once the closestHitFraction reached zero + if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) + return false; + + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + + //only perform raycast if filterMask matches + if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + { + //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); + //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; +#if 0 +#ifdef RECALCULATE_AABB + btVector3 collisionObjectAabbMin,collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); +#else + //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax); + const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin; + const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax; +#endif +#endif + //btScalar hitLambda = m_resultCallback.m_closestHitFraction; + //culling already done by broadphase + //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal)) + { + m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback); + } + } + return true; + } +}; + +void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const +{ + //BT_PROFILE("rayTest"); + /// use the broadphase to accelerate the search for objects, based on their aabb + /// and for each object with ray-aabb overlap, perform an exact ray test + btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback); + +#ifndef USE_BRUTEFORCE_RAYBROADPHASE + m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB); +#else + for (int i=0;igetNumCollisionObjects();i++) + { + rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); + } +#endif //USE_BRUTEFORCE_RAYBROADPHASE + +} + + +struct btSingleSweepCallback : public btBroadphaseRayCallback +{ + + btTransform m_convexFromTrans; + btTransform m_convexToTrans; + btVector3 m_hitNormal; + const btCollisionWorld* m_world; + btCollisionWorld::ConvexResultCallback& m_resultCallback; + btScalar m_allowedCcdPenetration; + const btConvexShape* m_castShape; + + + btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration) + :m_convexFromTrans(convexFromTrans), + m_convexToTrans(convexToTrans), + m_world(world), + m_resultCallback(resultCallback), + m_allowedCcdPenetration(allowedPenetration), + m_castShape(castShape) + { + btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin()); + btVector3 rayDir = unnormalizedRayDir.normalized(); + ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT + m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; + m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; + m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2]; + m_signs[0] = m_rayDirectionInverse[0] < 0.0; + m_signs[1] = m_rayDirectionInverse[1] < 0.0; + m_signs[2] = m_rayDirectionInverse[2] < 0.0; + + m_lambda_max = rayDir.dot(unnormalizedRayDir); + + } + + virtual bool process(const btBroadphaseProxy* proxy) + { + ///terminate further convex sweep tests, once the closestHitFraction reached zero + if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) + return false; + + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + + //only perform raycast if filterMask matches + if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { + //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); + m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback, + m_allowedCcdPenetration); + } + + return true; + } +}; + + + +void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const +{ + + BT_PROFILE("convexSweepTest"); + /// use the broadphase to accelerate the search for objects, based on their aabb + /// and for each object with ray-aabb overlap, perform an exact ray test + /// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical + + + + btTransform convexFromTrans,convexToTrans; + convexFromTrans = convexFromWorld; + convexToTrans = convexToWorld; + btVector3 castShapeAabbMin, castShapeAabbMax; + /* Compute AABB that encompasses angular movement */ + { + btVector3 linVel, angVel; + btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0f, linVel, angVel); + btVector3 zeroLinVel; + zeroLinVel.setValue(0,0,0); + btTransform R; + R.setIdentity (); + R.setRotation (convexFromTrans.getRotation()); + castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax); + } + +#ifndef USE_BRUTEFORCE_RAYBROADPHASE + + btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration); + + m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax); + +#else + /// go over all objects, and if the ray intersects their aabb + cast shape aabb, + // do a ray-shape query using convexCaster (CCD) + int i; + for (i=0;igetBroadphaseHandle())) { + //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); + btVector3 collisionObjectAabbMin,collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); + AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax); + btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing + btVector3 hitNormal; + if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) + { + objectQuerySingle(castShape, convexFromTrans,convexToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + resultCallback, + allowedCcdPenetration); + } + } + } +#endif //USE_BRUTEFORCE_RAYBROADPHASE +} + + + +struct btBridgedManifoldResult : public btManifoldResult +{ + + btCollisionWorld::ContactResultCallback& m_resultCallback; + + btBridgedManifoldResult( const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap,btCollisionWorld::ContactResultCallback& resultCallback ) + :btManifoldResult(obj0Wrap,obj1Wrap), + m_resultCallback(resultCallback) + { + } + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); + btVector3 pointA = pointInWorld + normalOnBInWorld * depth; + btVector3 localA; + btVector3 localB; + if (isSwapped) + { + localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); + } else + { + localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); + } + + btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); + newPt.m_positionWorldOnA = pointA; + newPt.m_positionWorldOnB = pointInWorld; + + //BP mod, store contact triangles. + if (isSwapped) + { + newPt.m_partId0 = m_partId1; + newPt.m_partId1 = m_partId0; + newPt.m_index0 = m_index1; + newPt.m_index1 = m_index0; + } else + { + newPt.m_partId0 = m_partId0; + newPt.m_partId1 = m_partId1; + newPt.m_index0 = m_index0; + newPt.m_index1 = m_index1; + } + + //experimental feature info, for per-triangle material etc. + const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap; + const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap; + m_resultCallback.addSingleResult(newPt,obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1); + + } + +}; + + + +struct btSingleContactCallback : public btBroadphaseAabbCallback +{ + + btCollisionObject* m_collisionObject; + btCollisionWorld* m_world; + btCollisionWorld::ContactResultCallback& m_resultCallback; + + + btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback) + :m_collisionObject(collisionObject), + m_world(world), + m_resultCallback(resultCallback) + { + } + + virtual bool process(const btBroadphaseProxy* proxy) + { + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + if (collisionObject == m_collisionObject) + return true; + + //only perform raycast if filterMask matches + if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + { + btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform()); + btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform()); + + btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1); + if (algorithm) + { + btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback); + //discrete collision detection query + + algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult); + + algorithm->~btCollisionAlgorithm(); + m_world->getDispatcher()->freeCollisionAlgorithm(algorithm); + } + } + return true; + } +}; + + +///contactTest performs a discrete collision test against all objects in the btCollisionWorld, and calls the resultCallback. +///it reports one or more contact points for every overlapping object (including the one with deepest penetration) +void btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCallback& resultCallback) +{ + btVector3 aabbMin,aabbMax; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax); + btSingleContactCallback contactCB(colObj,this,resultCallback); + + m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB); +} + + +///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected. +///it reports one or more contact points (including the one with deepest penetration) +void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback) +{ + btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform()); + btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform()); + + btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB); + if (algorithm) + { + btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback); + //discrete collision detection query + algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult); + + algorithm->~btCollisionAlgorithm(); + getDispatcher()->freeCollisionAlgorithm(algorithm); + } + +} + + + + +class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback +{ + btIDebugDraw* m_debugDrawer; + btVector3 m_color; + btTransform m_worldTrans; + +public: + + DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) : + m_debugDrawer(debugDrawer), + m_color(color), + m_worldTrans(worldTrans) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + processTriangle(triangle,partId,triangleIndex); + } + + virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; + + btVector3 wv0,wv1,wv2; + wv0 = m_worldTrans*triangle[0]; + wv1 = m_worldTrans*triangle[1]; + wv2 = m_worldTrans*triangle[2]; + btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.); + + if (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawNormals ) + { + btVector3 normal = (wv1-wv0).cross(wv2-wv0); + normal.normalize(); + btVector3 normalColor(1,1,0); + m_debugDrawer->drawLine(center,center+normal,normalColor); + } + m_debugDrawer->drawLine(wv0,wv1,m_color); + m_debugDrawer->drawLine(wv1,wv2,m_color); + m_debugDrawer->drawLine(wv2,wv0,m_color); + } +}; + + +void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color) +{ + // Draw a small simplex at the center of the object + getDebugDrawer()->drawTransform(worldTransform,1); + + if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) + { + const btCompoundShape* compoundShape = static_cast(shape); + for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* colShape = compoundShape->getChildShape(i); + debugDrawObject(worldTransform*childTrans,colShape,color); + } + + } else + { + + switch (shape->getShapeType()) + { + + case BOX_SHAPE_PROXYTYPE: + { + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtents = boxShape->getHalfExtentsWithMargin(); + getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color); + break; + } + + case SPHERE_SHAPE_PROXYTYPE: + { + const btSphereShape* sphereShape = static_cast(shape); + btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin + + getDebugDrawer()->drawSphere(radius, worldTransform, color); + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + const btMultiSphereShape* multiSphereShape = static_cast(shape); + + btTransform childTransform; + childTransform.setIdentity(); + + for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--) + { + childTransform.setOrigin(multiSphereShape->getSpherePosition(i)); + getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color); + } + + break; + } + case CAPSULE_SHAPE_PROXYTYPE: + { + const btCapsuleShape* capsuleShape = static_cast(shape); + + btScalar radius = capsuleShape->getRadius(); + btScalar halfHeight = capsuleShape->getHalfHeight(); + + int upAxis = capsuleShape->getUpAxis(); + getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color); + break; + } + case CONE_SHAPE_PROXYTYPE: + { + const btConeShape* coneShape = static_cast(shape); + btScalar radius = coneShape->getRadius();//+coneShape->getMargin(); + btScalar height = coneShape->getHeight();//+coneShape->getMargin(); + + int upAxis= coneShape->getConeUpIndex(); + getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color); + break; + + } + case CYLINDER_SHAPE_PROXYTYPE: + { + const btCylinderShape* cylinder = static_cast(shape); + int upAxis = cylinder->getUpAxis(); + btScalar radius = cylinder->getRadius(); + btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis]; + getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color); + break; + } + + case STATIC_PLANE_PROXYTYPE: + { + const btStaticPlaneShape* staticPlaneShape = static_cast(shape); + btScalar planeConst = staticPlaneShape->getPlaneConstant(); + const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); + getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color); + break; + + } + default: + { + + /// for polyhedral shapes + if (shape->isPolyhedral()) + { + btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape; + + int i; + if (polyshape->getConvexPolyhedron()) + { + const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron(); + for (i=0;im_faces.size();i++) + { + btVector3 centroid(0,0,0); + int numVerts = poly->m_faces[i].m_indices.size(); + if (numVerts) + { + int lastV = poly->m_faces[i].m_indices[numVerts-1]; + for (int v=0;vm_faces[i].m_indices.size();v++) + { + int curVert = poly->m_faces[i].m_indices[v]; + centroid+=poly->m_vertices[curVert]; + getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color); + lastV = curVert; + } + } + centroid*= btScalar(1.f)/btScalar(numVerts); + if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals) + { + btVector3 normalColor(1,1,0); + btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]); + getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor); + } + + } + + + } else + { + for (i=0;igetNumEdges();i++) + { + btVector3 a,b; + polyshape->getEdge(i,a,b); + btVector3 wa = worldTransform * a; + btVector3 wb = worldTransform * b; + getDebugDrawer()->drawLine(wa,wb,color); + } + } + + + } + + if (shape->isConcave()) + { + btConcaveShape* concaveMesh = (btConcaveShape*) shape; + + ///@todo pass camera, for some culling? no -> we are not a graphics lib + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + + DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); + concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); + + } + + if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE) + { + btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape; + //todo: pass camera for some culling + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + //DebugDrawcallback drawCallback; + DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); + convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax); + } + + + + } + + } + } +} + + +void btCollisionWorld::debugDrawWorld() +{ + if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints) + { + int numManifolds = getDispatcher()->getNumManifolds(); + btVector3 color(1,1,0); + for (int i=0;igetManifoldByIndexInternal(i); + //btCollisionObject* obA = static_cast(contactManifold->getBody0()); + //btCollisionObject* obB = static_cast(contactManifold->getBody1()); + + int numContacts = contactManifold->getNumContacts(); + for (int j=0;jgetContactPoint(j); + getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); + } + } + } + + if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))) + { + int i; + + for ( i=0;igetCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0) + { + if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)) + { + btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.)); + switch(colObj->getActivationState()) + { + case ACTIVE_TAG: + color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break; + case ISLAND_SLEEPING: + color = btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break; + case WANTS_DEACTIVATION: + color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break; + case DISABLE_DEACTIVATION: + color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break; + case DISABLE_SIMULATION: + color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break; + default: + { + color = btVector3(btScalar(1),btScalar(0.),btScalar(0.)); + } + }; + + debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color); + } + if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) + { + btVector3 minAabb,maxAabb; + btVector3 colorvec(1,0,0); + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); + btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold); + minAabb -= contactThreshold; + maxAabb += contactThreshold; + + btVector3 minAabb2,maxAabb2; + + if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject()) + { + colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2); + minAabb2 -= contactThreshold; + maxAabb2 += contactThreshold; + minAabb.setMin(minAabb2); + maxAabb.setMax(maxAabb2); + } + + m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec); + } + } + + } + } +} + + +void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer) +{ + int i; + //serialize all collision objects + for (i=0;igetInternalType() == btCollisionObject::CO_COLLISION_OBJECT) + { + colObj->serializeSingleObject(serializer); + } + } + + ///keep track of shapes already serialized + btHashMap serializedShapes; + + for (i=0;igetCollisionShape(); + + if (!serializedShapes.find(shape)) + { + serializedShapes.insert(shape,shape); + shape->serializeSingleShape(serializer); + } + } + +} + + +void btCollisionWorld::serialize(btSerializer* serializer) +{ + + serializer->startSerialization(); + + serializeCollisionObjects(serializer); + + serializer->finishSerialization(); +} + diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h new file mode 100644 index 0000000..9412242 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h @@ -0,0 +1,522 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://bulletphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +/** + * @mainpage Bullet Documentation + * + * @section intro_sec Introduction + * Bullet Collision Detection & Physics SDK + * + * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ). + * + * The main documentation is Bullet_User_Manual.pdf, included in the source code distribution. + * There is the Physics Forum for feedback and general Collision Detection and Physics discussions. + * Please visit http://www.bulletphysics.com + * + * @section install_sec Installation + * + * @subsection step1 Step 1: Download + * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list + * + * @subsection step2 Step 2: Building + * Bullet main build system for all platforms is cmake, you can download http://www.cmake.org + * cmake can autogenerate projectfiles for Microsoft Visual Studio, Apple Xcode, KDevelop and Unix Makefiles. + * The easiest is to run the CMake cmake-gui graphical user interface and choose the options and generate projectfiles. + * You can also use cmake in the command-line. Here are some examples for various platforms: + * cmake . -G "Visual Studio 9 2008" + * cmake . -G Xcode + * cmake . -G "Unix Makefiles" + * Although cmake is recommended, you can also use autotools for UNIX: ./autogen.sh ./configure to create a Makefile and then run make. + * + * @subsection step3 Step 3: Testing demos + * Try to run and experiment with BasicDemo executable as a starting point. + * Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation. + * The Dependencies can be seen in this documentation under Directories + * + * @subsection step4 Step 4: Integrating in your application, full Rigid Body and Soft Body simulation + * Check out BasicDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform. + * Check out SoftDemo how to use soft body dynamics, using btSoftRigidDynamicsWorld. + * @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras) + * Bullet Collision Detection can also be used without the Dynamics/Extras. + * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo. + * @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation. + * Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector. + * + * @section copyright Copyright + * For up-to-data information and copyright and contributors list check out the Bullet_User_Manual.pdf + * + */ + + + +#ifndef BT_COLLISION_WORLD_H +#define BT_COLLISION_WORLD_H + +class btStackAlloc; +class btCollisionShape; +class btConvexShape; +class btBroadphaseInterface; +class btSerializer; + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "btCollisionObject.h" +#include "btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "LinearMath/btAlignedObjectArray.h" + +///CollisionWorld is interface and container for the collision detection +class btCollisionWorld +{ + + +protected: + + btAlignedObjectArray m_collisionObjects; + + btDispatcher* m_dispatcher1; + + btDispatcherInfo m_dispatchInfo; + + btStackAlloc* m_stackAlloc; + + btBroadphaseInterface* m_broadphasePairCache; + + btIDebugDraw* m_debugDrawer; + + ///m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs + ///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB) + bool m_forceUpdateAllAabbs; + + void serializeCollisionObjects(btSerializer* serializer); + +public: + + //this constructor doesn't own the dispatcher and paircache/broadphase + btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); + + virtual ~btCollisionWorld(); + + void setBroadphase(btBroadphaseInterface* pairCache) + { + m_broadphasePairCache = pairCache; + } + + const btBroadphaseInterface* getBroadphase() const + { + return m_broadphasePairCache; + } + + btBroadphaseInterface* getBroadphase() + { + return m_broadphasePairCache; + } + + btOverlappingPairCache* getPairCache() + { + return m_broadphasePairCache->getOverlappingPairCache(); + } + + + btDispatcher* getDispatcher() + { + return m_dispatcher1; + } + + const btDispatcher* getDispatcher() const + { + return m_dispatcher1; + } + + void updateSingleAabb(btCollisionObject* colObj); + + virtual void updateAabbs(); + + ///the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSimulation) + ///it can be useful to use if you perform ray tests without collision detection/simulation + virtual void computeOverlappingPairs(); + + + virtual void setDebugDrawer(btIDebugDraw* debugDrawer) + { + m_debugDrawer = debugDrawer; + } + + virtual btIDebugDraw* getDebugDrawer() + { + return m_debugDrawer; + } + + virtual void debugDrawWorld(); + + virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); + + + ///LocalShapeInfo gives extra information for complex shapes + ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart + struct LocalShapeInfo + { + int m_shapePart; + int m_triangleIndex; + + //const btCollisionShape* m_shapeTemp; + //const btTransform* m_shapeLocalTransform; + }; + + struct LocalRayResult + { + LocalRayResult(const btCollisionObject* collisionObject, + LocalShapeInfo* localShapeInfo, + const btVector3& hitNormalLocal, + btScalar hitFraction) + :m_collisionObject(collisionObject), + m_localShapeInfo(localShapeInfo), + m_hitNormalLocal(hitNormalLocal), + m_hitFraction(hitFraction) + { + } + + const btCollisionObject* m_collisionObject; + LocalShapeInfo* m_localShapeInfo; + btVector3 m_hitNormalLocal; + btScalar m_hitFraction; + + }; + + ///RayResultCallback is used to report new raycast results + struct RayResultCallback + { + btScalar m_closestHitFraction; + const btCollisionObject* m_collisionObject; + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback.h. Apply any of the EFlags defined there on m_flags here to invoke. + unsigned int m_flags; + + virtual ~RayResultCallback() + { + } + bool hasHit() const + { + return (m_collisionObject != 0); + } + + RayResultCallback() + :m_closestHitFraction(btScalar(1.)), + m_collisionObject(0), + m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), + m_collisionFilterMask(btBroadphaseProxy::AllFilter), + //@BP Mod + m_flags(0) + { + } + + virtual bool needsCollision(btBroadphaseProxy* proxy0) const + { + bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; + collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); + return collides; + } + + + virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0; + }; + + struct ClosestRayResultCallback : public RayResultCallback + { + ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) + :m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld) + { + } + + btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; + + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + + virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) + { + //caller already does the filter on the m_closestHitFraction + btAssert(rayResult.m_hitFraction <= m_closestHitFraction); + + m_closestHitFraction = rayResult.m_hitFraction; + m_collisionObject = rayResult.m_collisionObject; + if (normalInWorldSpace) + { + m_hitNormalWorld = rayResult.m_hitNormalLocal; + } else + { + ///need to transform normal into worldspace + m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + } + m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); + return rayResult.m_hitFraction; + } + }; + + struct AllHitsRayResultCallback : public RayResultCallback + { + AllHitsRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) + :m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld) + { + } + + btAlignedObjectArray m_collisionObjects; + + btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; + + btAlignedObjectArray m_hitNormalWorld; + btAlignedObjectArray m_hitPointWorld; + btAlignedObjectArray m_hitFractions; + + virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) + { + m_collisionObject = rayResult.m_collisionObject; + m_collisionObjects.push_back(rayResult.m_collisionObject); + btVector3 hitNormalWorld; + if (normalInWorldSpace) + { + hitNormalWorld = rayResult.m_hitNormalLocal; + } else + { + ///need to transform normal into worldspace + hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + } + m_hitNormalWorld.push_back(hitNormalWorld); + btVector3 hitPointWorld; + hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); + m_hitPointWorld.push_back(hitPointWorld); + m_hitFractions.push_back(rayResult.m_hitFraction); + return m_closestHitFraction; + } + }; + + + struct LocalConvexResult + { + LocalConvexResult(const btCollisionObject* hitCollisionObject, + LocalShapeInfo* localShapeInfo, + const btVector3& hitNormalLocal, + const btVector3& hitPointLocal, + btScalar hitFraction + ) + :m_hitCollisionObject(hitCollisionObject), + m_localShapeInfo(localShapeInfo), + m_hitNormalLocal(hitNormalLocal), + m_hitPointLocal(hitPointLocal), + m_hitFraction(hitFraction) + { + } + + const btCollisionObject* m_hitCollisionObject; + LocalShapeInfo* m_localShapeInfo; + btVector3 m_hitNormalLocal; + btVector3 m_hitPointLocal; + btScalar m_hitFraction; + }; + + ///RayResultCallback is used to report new raycast results + struct ConvexResultCallback + { + btScalar m_closestHitFraction; + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + + ConvexResultCallback() + :m_closestHitFraction(btScalar(1.)), + m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), + m_collisionFilterMask(btBroadphaseProxy::AllFilter) + { + } + + virtual ~ConvexResultCallback() + { + } + + bool hasHit() const + { + return (m_closestHitFraction < btScalar(1.)); + } + + + + virtual bool needsCollision(btBroadphaseProxy* proxy0) const + { + bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; + collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); + return collides; + } + + virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) = 0; + }; + + struct ClosestConvexResultCallback : public ConvexResultCallback + { + ClosestConvexResultCallback(const btVector3& convexFromWorld,const btVector3& convexToWorld) + :m_convexFromWorld(convexFromWorld), + m_convexToWorld(convexToWorld), + m_hitCollisionObject(0) + { + } + + btVector3 m_convexFromWorld;//used to calculate hitPointWorld from hitFraction + btVector3 m_convexToWorld; + + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + const btCollisionObject* m_hitCollisionObject; + + virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) + { +//caller already does the filter on the m_closestHitFraction + btAssert(convexResult.m_hitFraction <= m_closestHitFraction); + + m_closestHitFraction = convexResult.m_hitFraction; + m_hitCollisionObject = convexResult.m_hitCollisionObject; + if (normalInWorldSpace) + { + m_hitNormalWorld = convexResult.m_hitNormalLocal; + } else + { + ///need to transform normal into worldspace + m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; + } + m_hitPointWorld = convexResult.m_hitPointLocal; + return convexResult.m_hitFraction; + } + }; + + ///ContactResultCallback is used to report contact points + struct ContactResultCallback + { + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + + ContactResultCallback() + :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), + m_collisionFilterMask(btBroadphaseProxy::AllFilter) + { + } + + virtual ~ContactResultCallback() + { + } + + virtual bool needsCollision(btBroadphaseProxy* proxy0) const + { + bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; + collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); + return collides; + } + + virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) = 0; + }; + + + + int getNumCollisionObjects() const + { + return int(m_collisionObjects.size()); + } + + /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback + /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. + virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; + + /// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback + /// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback. + void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const; + + ///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback. + ///it reports one or more contact points for every overlapping object (including the one with deepest penetration) + void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback); + + ///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected. + ///it reports one or more contact points (including the one with deepest penetration) + void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback); + + + /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. + /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. + /// This allows more customization. + static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback); + + static void rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans, + const btCollisionObjectWrapper* collisionObjectWrap, + RayResultCallback& resultCallback); + + /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest. + static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + ConvexResultCallback& resultCallback, btScalar allowedPenetration); + + static void objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans, + const btCollisionObjectWrapper* colObjWrap, + ConvexResultCallback& resultCallback, btScalar allowedPenetration); + + virtual void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter); + + btCollisionObjectArray& getCollisionObjectArray() + { + return m_collisionObjects; + } + + const btCollisionObjectArray& getCollisionObjectArray() const + { + return m_collisionObjects; + } + + + virtual void removeCollisionObject(btCollisionObject* collisionObject); + + virtual void performDiscreteCollisionDetection(); + + btDispatcherInfo& getDispatchInfo() + { + return m_dispatchInfo; + } + + const btDispatcherInfo& getDispatchInfo() const + { + return m_dispatchInfo; + } + + bool getForceUpdateAllAabbs() const + { + return m_forceUpdateAllAabbs; + } + void setForceUpdateAllAabbs( bool forceUpdateAllAabbs) + { + m_forceUpdateAllAabbs = forceUpdateAllAabbs; + } + + ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo) + virtual void serialize(btSerializer* serializer); + +}; + + +#endif //BT_COLLISION_WORLD_H diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp new file mode 100644 index 0000000..290d677 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp @@ -0,0 +1,366 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/BroadphaseCollision/btDbvt.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btAabbUtil2.h" +#include "btManifoldResult.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped) +:btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), +m_isSwapped(isSwapped), +m_sharedManifold(ci.m_manifold) +{ + m_ownsManifold = false; + + const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap; + btAssert (colObjWrap->getCollisionShape()->isCompound()); + + const btCompoundShape* compoundShape = static_cast(colObjWrap->getCollisionShape()); + m_compoundShapeRevision = compoundShape->getUpdateRevision(); + + + preallocateChildAlgorithms(body0Wrap,body1Wrap); +} + +void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) +{ + const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap; + btAssert (colObjWrap->getCollisionShape()->isCompound()); + + const btCompoundShape* compoundShape = static_cast(colObjWrap->getCollisionShape()); + + int numChildren = compoundShape->getNumChildShapes(); + int i; + + m_childCollisionAlgorithms.resize(numChildren); + for (i=0;igetDynamicAabbTree()) + { + m_childCollisionAlgorithms[i] = 0; + } else + { + + const btCollisionShape* childShape = compoundShape->getChildShape(i); + + btCollisionObjectWrapper childWrap(colObjWrap,childShape,colObjWrap->getCollisionObject(),colObjWrap->getWorldTransform());//wrong child trans, but unused (hopefully) + m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(&childWrap,otherObjWrap,m_sharedManifold); + } + } +} + +void btCompoundCollisionAlgorithm::removeChildAlgorithms() +{ + int numChildren = m_childCollisionAlgorithms.size(); + int i; + for (i=0;i~btCollisionAlgorithm(); + m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]); + } + } +} + +btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm() +{ + removeChildAlgorithms(); +} + + + + +struct btCompoundLeafCallback : btDbvt::ICollide +{ + +public: + + const btCollisionObjectWrapper* m_compoundColObjWrap; + const btCollisionObjectWrapper* m_otherObjWrap; + btDispatcher* m_dispatcher; + const btDispatcherInfo& m_dispatchInfo; + btManifoldResult* m_resultOut; + btCollisionAlgorithm** m_childCollisionAlgorithms; + btPersistentManifold* m_sharedManifold; + + btCompoundLeafCallback (const btCollisionObjectWrapper* compoundObjWrap,const btCollisionObjectWrapper* otherObjWrap,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut,btCollisionAlgorithm** childCollisionAlgorithms,btPersistentManifold* sharedManifold) + :m_compoundColObjWrap(compoundObjWrap),m_otherObjWrap(otherObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut), + m_childCollisionAlgorithms(childCollisionAlgorithms), + m_sharedManifold(sharedManifold) + { + + } + + + void ProcessChildShape(const btCollisionShape* childShape,int index) + { + btAssert(index>=0); + const btCompoundShape* compoundShape = static_cast(m_compoundColObjWrap->getCollisionShape()); + btAssert(indexgetNumChildShapes()); + + + //backup + btTransform orgTrans = m_compoundColObjWrap->getWorldTransform(); + btTransform orgInterpolationTrans = m_compoundColObjWrap->getWorldTransform(); + const btTransform& childTrans = compoundShape->getChildTransform(index); + btTransform newChildWorldTrans = orgTrans*childTrans ; + + //perform an AABB check first + btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1; + childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0); + m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1); + + if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1)) + { + + btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap,childShape,m_compoundColObjWrap->getCollisionObject(),newChildWorldTrans); + + + //the contactpoint is still projected back using the original inverted worldtrans + if (!m_childCollisionAlgorithms[index]) + m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(&compoundWrap,m_otherObjWrap,m_sharedManifold); + + + const btCollisionObjectWrapper* tmpWrap = 0; + + ///detect swapping case + if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject()) + { + tmpWrap = m_resultOut->getBody0Wrap(); + m_resultOut->setBody0Wrap(&compoundWrap); + m_resultOut->setShapeIdentifiersA(-1,index); + } else + { + tmpWrap = m_resultOut->getBody1Wrap(); + m_resultOut->setBody1Wrap(&compoundWrap); + m_resultOut->setShapeIdentifiersB(-1,index); + } + + + m_childCollisionAlgorithms[index]->processCollision(&compoundWrap,m_otherObjWrap,m_dispatchInfo,m_resultOut); + +#if 0 + if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) + { + btVector3 worldAabbMin,worldAabbMax; + m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1)); + m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1)); + } +#endif + + if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject()) + { + m_resultOut->setBody0Wrap(tmpWrap); + } else + { + m_resultOut->setBody1Wrap(tmpWrap); + } + + } + } + void Process(const btDbvtNode* leaf) + { + int index = leaf->dataAsInt; + + const btCompoundShape* compoundShape = static_cast(m_compoundColObjWrap->getCollisionShape()); + const btCollisionShape* childShape = compoundShape->getChildShape(index); + +#if 0 + if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) + { + btVector3 worldAabbMin,worldAabbMax; + btTransform orgTrans = m_compoundColObjWrap->getWorldTransform(); + btTransformAabb(leaf->volume.Mins(),leaf->volume.Maxs(),0.,orgTrans,worldAabbMin,worldAabbMax); + m_dispatchInfo.m_debugDraw->drawAabb(worldAabbMin,worldAabbMax,btVector3(1,0,0)); + } +#endif + + ProcessChildShape(childShape,index); + + } +}; + + + + + + +void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap; + + btAssert (colObjWrap->getCollisionShape()->isCompound()); + const btCompoundShape* compoundShape = static_cast(colObjWrap->getCollisionShape()); + + ///btCompoundShape might have changed: + ////make sure the internal child collision algorithm caches are still valid + if (compoundShape->getUpdateRevision() != m_compoundShapeRevision) + { + ///clear and update all + removeChildAlgorithms(); + + preallocateChildAlgorithms(body0Wrap,body1Wrap); + } + + + const btDbvt* tree = compoundShape->getDynamicAabbTree(); + //use a dynamic aabb tree to cull potential child-overlaps + btCompoundLeafCallback callback(colObjWrap,otherObjWrap,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold); + + ///we need to refresh all contact manifolds + ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep + ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm + { + int i; + btManifoldArray manifoldArray; + for (i=0;igetAllContactManifolds(manifoldArray); + for (int m=0;mgetNumContacts()) + { + resultOut->setPersistentManifold(manifoldArray[m]); + resultOut->refreshContactPoints(); + resultOut->setPersistentManifold(0);//??necessary? + } + } + manifoldArray.resize(0); + } + } + } + + if (tree) + { + + btVector3 localAabbMin,localAabbMax; + btTransform otherInCompoundSpace; + otherInCompoundSpace = colObjWrap->getWorldTransform().inverse() * otherObjWrap->getWorldTransform(); + otherObjWrap->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax); + + const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + //process all children, that overlap with the given AABB bounds + tree->collideTV(tree->m_root,bounds,callback); + + } else + { + //iterate over all children, perform an AABB check inside ProcessChildShape + int numChildren = m_childCollisionAlgorithms.size(); + int i; + for (i=0;igetChildShape(i),i); + } + } + + { + //iterate over all children, perform an AABB check inside ProcessChildShape + int numChildren = m_childCollisionAlgorithms.size(); + int i; + btManifoldArray manifoldArray; + const btCollisionShape* childShape = 0; + btTransform orgTrans; + btTransform orgInterpolationTrans; + btTransform newChildWorldTrans; + btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1; + + for (i=0;igetChildShape(i); + //if not longer overlapping, remove the algorithm + orgTrans = colObjWrap->getWorldTransform(); + orgInterpolationTrans = colObjWrap->getWorldTransform(); + const btTransform& childTrans = compoundShape->getChildTransform(i); + newChildWorldTrans = orgTrans*childTrans ; + + //perform an AABB check first + childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0); + otherObjWrap->getCollisionShape()->getAabb(otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1); + + if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1)) + { + m_childCollisionAlgorithms[i]->~btCollisionAlgorithm(); + m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]); + m_childCollisionAlgorithms[i] = 0; + } + } + } + } +} + +btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + btAssert(0); + //needs to be fixed, using btCollisionObjectWrapper and NOT modifying internal data structures + btCollisionObject* colObj = m_isSwapped? body1 : body0; + btCollisionObject* otherObj = m_isSwapped? body0 : body1; + + btAssert (colObj->getCollisionShape()->isCompound()); + + btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); + + //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps + //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals + //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means: + //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1 + //then use each overlapping node AABB against Tree0 + //and vise versa. + + btScalar hitFraction = btScalar(1.); + + int numChildren = m_childCollisionAlgorithms.size(); + int i; + btTransform orgTrans; + btScalar frac; + for (i=0;igetChildShape(i); + + //backup + orgTrans = colObj->getWorldTransform(); + + const btTransform& childTrans = compoundShape->getChildTransform(i); + //btTransform newChildWorldTrans = orgTrans*childTrans ; + colObj->setWorldTransform( orgTrans*childTrans ); + + //btCollisionShape* tmpShape = colObj->getCollisionShape(); + //colObj->internalSetTemporaryCollisionShape( childShape ); + frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut); + if (fracinternalSetTemporaryCollisionShape( tmpShape); + colObj->setWorldTransform( orgTrans); + } + return hitFraction; + +} + + + diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h new file mode 100644 index 0000000..b16fc52 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h @@ -0,0 +1,86 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COMPOUND_COLLISION_ALGORITHM_H +#define BT_COMPOUND_COLLISION_ALGORITHM_H + +#include "btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" + +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +class btDispatcher; +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "btCollisionCreateFunc.h" +#include "LinearMath/btAlignedObjectArray.h" +class btDispatcher; +class btCollisionObject; + +/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes +class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ + btAlignedObjectArray m_childCollisionAlgorithms; + bool m_isSwapped; + + class btPersistentManifold* m_sharedManifold; + bool m_ownsManifold; + + int m_compoundShapeRevision;//to keep track of changes, so that childAlgorithm array can be updated + + void removeChildAlgorithms(); + + void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + +public: + + btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + + virtual ~btCompoundCollisionAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + int i; + for (i=0;igetAllContactManifolds(manifoldArray); + } + } + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); + return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,false); + } + }; + + struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); + return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,true); + } + }; + +}; + +#endif //BT_COMPOUND_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp new file mode 100644 index 0000000..3e1afed --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp @@ -0,0 +1,247 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConvex2dConvex2dAlgorithm.h" + +//#include +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" + + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" + +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" + + + +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) +{ + m_numPerturbationIterations = 0; + m_minimumPointsPerturbationThreshold = 3; + m_simplexSolver = simplexSolver; + m_pdSolver = pdSolver; +} + +btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc() +{ +} + +btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold) +: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), +m_simplexSolver(simplexSolver), +m_pdSolver(pdSolver), +m_ownManifold (false), +m_manifoldPtr(mf), +m_lowLevelOfDetail(false), + m_numPerturbationIterations(numPerturbationIterations), +m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) +{ + (void)body0Wrap; + (void)body1Wrap; +} + + + + +btConvex2dConvex2dAlgorithm::~btConvex2dConvex2dAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btConvex2dConvex2dAlgorithm ::setLowLevelOfDetail(bool useLowLevel) +{ + m_lowLevelOfDetail = useLowLevel; +} + + + +extern btScalar gContactBreakingThreshold; + + +// +// Convex-Convex collision algorithm +// +void btConvex2dConvex2dAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + + if (!m_manifoldPtr) + { + //swapped? + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_ownManifold = true; + } + resultOut->setPersistentManifold(m_manifoldPtr); + + //comment-out next line to test multi-contact generation + //resultOut->getPersistentManifold()->clearManifold(); + + + const btConvexShape* min0 = static_cast(body0Wrap->getCollisionShape()); + const btConvexShape* min1 = static_cast(body1Wrap->getCollisionShape()); + + btVector3 normalOnB; + btVector3 pointOnBWorld; + + { + + + btGjkPairDetector::ClosestPointInput input; + + btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver); + //TODO: if (dispatchInfo.m_useContinuous) + gjkPairDetector.setMinkowskiA(min0); + gjkPairDetector.setMinkowskiB(min1); + + { + input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); + input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; + } + + input.m_stackAlloc = dispatchInfo.m_stackAllocator; + input.m_transformA = body0Wrap->getWorldTransform(); + input.m_transformB = body1Wrap->getWorldTransform(); + + gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + + btVector3 v0,v1; + btVector3 sepNormalWorldSpace; + + } + + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + +} + + + + +btScalar btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold + + ///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold + ///col0->m_worldTransform, + btScalar resultFraction = btScalar(1.); + + + btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2(); + btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2(); + + if (squareMot0 < col0->getCcdSquareMotionThreshold() && + squareMot1 < col1->getCcdSquareMotionThreshold()) + return resultFraction; + + + //An adhoc way of testing the Continuous Collision Detection algorithms + //One object is approximated as a sphere, to simplify things + //Starting in penetration should report no time of impact + //For proper CCD, better accuracy and handling of 'allowed' penetration should be added + //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) + + + /// Convex0 against sphere for Convex1 + { + btConvexShape* convex0 = static_cast(col0->getCollisionShape()); + + btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btConvexCast::CastResult result; + btVoronoiSimplexSolver voronoiSimplex; + //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); + ///Simplification, one object is simplified as a sphere + btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex); + //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), + col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + { + + //store result.m_fraction in both bodies + + if (col0->getHitFraction()> result.m_fraction) + col0->setHitFraction( result.m_fraction ); + + if (col1->getHitFraction() > result.m_fraction) + col1->setHitFraction( result.m_fraction); + + if (resultFraction > result.m_fraction) + resultFraction = result.m_fraction; + + } + + + + + } + + /// Sphere (for convex0) against Convex1 + { + btConvexShape* convex1 = static_cast(col1->getCollisionShape()); + + btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btConvexCast::CastResult result; + btVoronoiSimplexSolver voronoiSimplex; + //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); + ///Simplification, one object is simplified as a sphere + btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex); + //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), + col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + { + + //store result.m_fraction in both bodies + + if (col0->getHitFraction() > result.m_fraction) + col0->setHitFraction( result.m_fraction); + + if (col1->getHitFraction() > result.m_fraction) + col1->setHitFraction( result.m_fraction); + + if (resultFraction > result.m_fraction) + resultFraction = result.m_fraction; + + } + } + + return resultFraction; + +} + diff --git a/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h new file mode 100644 index 0000000..18d9385 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h @@ -0,0 +1,95 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H +#define BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H + +#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil + +class btConvexPenetrationDepthSolver; + + +///The convex2dConvex2dAlgorithm collision algorithm support 2d collision detection for btConvex2dShape +///Currently it requires the btMinkowskiPenetrationDepthSolver, it has support for 2d penetration depth computation +class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm +{ + btSimplexSolverInterface* m_simplexSolver; + btConvexPenetrationDepthSolver* m_pdSolver; + + + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_lowLevelOfDetail; + + int m_numPerturbationIterations; + int m_minimumPointsPerturbationThreshold; + +public: + + btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold); + + + virtual ~btConvex2dConvex2dAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + ///should we use m_ownManifold to avoid adding duplicates? + if (m_manifoldPtr && m_ownManifold) + manifoldArray.push_back(m_manifoldPtr); + } + + + void setLowLevelOfDetail(bool useLowLevel); + + + const btPersistentManifold* getManifold() + { + return m_manifoldPtr; + } + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + + btConvexPenetrationDepthSolver* m_pdSolver; + btSimplexSolverInterface* m_simplexSolver; + int m_numPerturbationIterations; + int m_minimumPointsPerturbationThreshold; + + CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); + + virtual ~CreateFunc(); + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvex2dConvex2dAlgorithm)); + return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); + } + }; + + +}; + +#endif //BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp new file mode 100644 index 0000000..6905e97 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @@ -0,0 +1,329 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btConvexConcaveCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionShapes/btConcaveShape.h" +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped) +: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), +m_isSwapped(isSwapped), +m_btConvexTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped) +{ +} + +btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm() +{ +} + +void btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray& manifoldArray) +{ + if (m_btConvexTriangleCallback.m_manifoldPtr) + { + manifoldArray.push_back(m_btConvexTriangleCallback.m_manifoldPtr); + } +} + + +btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped): + m_dispatcher(dispatcher), + m_dispatchInfoPtr(0) +{ + m_convexBodyWrap = isSwapped? body1Wrap:body0Wrap; + m_triBodyWrap = isSwapped? body0Wrap:body1Wrap; + + // + // create the manifold from the dispatcher 'manifold pool' + // + m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBodyWrap->getCollisionObject(),m_triBodyWrap->getCollisionObject()); + + clearCache(); +} + +btConvexTriangleCallback::~btConvexTriangleCallback() +{ + clearCache(); + m_dispatcher->releaseManifold( m_manifoldPtr ); + +} + + +void btConvexTriangleCallback::clearCache() +{ + m_dispatcher->clearManifold(m_manifoldPtr); +} + + + +void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) +{ + + //just for debugging purposes + //printf("triangle %d",m_triangleCount++); + + + //aabb filter is already applied! + + btCollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher1 = m_dispatcher; + + //const btCollisionObject* ob = static_cast(m_triBodyWrap->getCollisionObject()); + + +#if 0 + ///debug drawing of the overlapping triangles + if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe )) + { + btVector3 color(1,1,0); + btTransform& tr = ob->getWorldTransform(); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color); + } +#endif + + if (m_convexBodyWrap->getCollisionShape()->isConvex()) + { + btTriangleShape tm(triangle[0],triangle[1],triangle[2]); + tm.setMargin(m_collisionMarginTriangle); + + + btCollisionObjectWrapper triObWrap(m_triBodyWrap,&tm,m_triBodyWrap->getCollisionObject(),m_triBodyWrap->getWorldTransform());//correct transform? + btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap,&triObWrap,m_manifoldPtr); + + const btCollisionObjectWrapper* tmpWrap = 0; + + if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject()) + { + tmpWrap = m_resultOut->getBody0Wrap(); + m_resultOut->setBody0Wrap(&triObWrap); + m_resultOut->setShapeIdentifiersA(partId,triangleIndex); + } + else + { + tmpWrap = m_resultOut->getBody1Wrap(); + m_resultOut->setBody1Wrap(&triObWrap); + m_resultOut->setShapeIdentifiersB(partId,triangleIndex); + } + + colAlgo->processCollision(m_convexBodyWrap,&triObWrap,*m_dispatchInfoPtr,m_resultOut); + + if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject()) + { + m_resultOut->setBody0Wrap(tmpWrap); + } else + { + m_resultOut->setBody1Wrap(tmpWrap); + } + + + + colAlgo->~btCollisionAlgorithm(); + ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); + } + +} + + + +void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut) +{ + m_convexBodyWrap = convexBodyWrap; + m_triBodyWrap = triBodyWrap; + + m_dispatchInfoPtr = &dispatchInfo; + m_collisionMarginTriangle = collisionMarginTriangle; + m_resultOut = resultOut; + + //recalc aabbs + btTransform convexInTriangleSpace; + convexInTriangleSpace = m_triBodyWrap->getWorldTransform().inverse() * m_convexBodyWrap->getWorldTransform(); + const btCollisionShape* convexShape = static_cast(m_convexBodyWrap->getCollisionShape()); + //CollisionShape* triangleShape = static_cast(triBody->m_collisionShape); + convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax); + btScalar extraMargin = collisionMarginTriangle; + btVector3 extra(extraMargin,extraMargin,extraMargin); + + m_aabbMax += extra; + m_aabbMin -= extra; + +} + +void btConvexConcaveCollisionAlgorithm::clearCache() +{ + m_btConvexTriangleCallback.clearCache(); + +} + +void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + + + const btCollisionObjectWrapper* convexBodyWrap = m_isSwapped ? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* triBodyWrap = m_isSwapped ? body0Wrap : body1Wrap; + + if (triBodyWrap->getCollisionShape()->isConcave()) + { + + + + const btConcaveShape* concaveShape = static_cast( triBodyWrap->getCollisionShape()); + + if (convexBodyWrap->getCollisionShape()->isConvex()) + { + btScalar collisionMarginTriangle = concaveShape->getMargin(); + + resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr); + m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,convexBodyWrap,triBodyWrap,resultOut); + + m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBodyWrap->getCollisionObject(),triBodyWrap->getCollisionObject()); + + concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax()); + + resultOut->refreshContactPoints(); + + m_btConvexTriangleCallback.clearWrapperData(); + + } + + } + +} + + +btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + btCollisionObject* convexbody = m_isSwapped ? body1 : body0; + btCollisionObject* triBody = m_isSwapped ? body0 : body1; + + + //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) + + //only perform CCD above a certain threshold, this prevents blocking on the long run + //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame... + btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2(); + if (squareMot0 < convexbody->getCcdSquareMotionThreshold()) + { + return btScalar(1.); + } + + //const btVector3& from = convexbody->m_worldTransform.getOrigin(); + //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin(); + //todo: only do if the motion exceeds the 'radius' + + btTransform triInv = triBody->getWorldTransform().inverse(); + btTransform convexFromLocal = triInv * convexbody->getWorldTransform(); + btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform(); + + struct LocalTriangleSphereCastCallback : public btTriangleCallback + { + btTransform m_ccdSphereFromTrans; + btTransform m_ccdSphereToTrans; + btTransform m_meshTransform; + + btScalar m_ccdSphereRadius; + btScalar m_hitFraction; + + + LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) + :m_ccdSphereFromTrans(from), + m_ccdSphereToTrans(to), + m_ccdSphereRadius(ccdSphereRadius), + m_hitFraction(hitFraction) + { + } + + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; + //do a swept sphere for now + btTransform ident; + ident.setIdentity(); + btConvexCast::CastResult castResult; + castResult.m_fraction = m_hitFraction; + btSphereShape pointShape(m_ccdSphereRadius); + btTriangleShape triShape(triangle[0],triangle[1],triangle[2]); + btVoronoiSimplexSolver simplexSolver; + btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver); + //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); + //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); + //local space? + + if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans, + ident,ident,castResult)) + { + if (m_hitFraction > castResult.m_fraction) + m_hitFraction = castResult.m_fraction; + } + + } + + }; + + + + + + if (triBody->getCollisionShape()->isConcave()) + { + btVector3 rayAabbMin = convexFromLocal.getOrigin(); + rayAabbMin.setMin(convexToLocal.getOrigin()); + btVector3 rayAabbMax = convexFromLocal.getOrigin(); + rayAabbMax.setMax(convexToLocal.getOrigin()); + btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius(); + rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + + btScalar curHitFraction = btScalar(1.); //is this available? + LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal, + convexbody->getCcdSweptSphereRadius(),curHitFraction); + + raycastCallback.m_hitFraction = convexbody->getHitFraction(); + + btCollisionObject* concavebody = triBody; + + btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); + + if (triangleMesh) + { + triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); + } + + + + if (raycastCallback.m_hitFraction < convexbody->getHitFraction()) + { + convexbody->setHitFraction( raycastCallback.m_hitFraction); + return raycastCallback.m_hitFraction; + } + } + + return btScalar(1.); + +} diff --git a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h new file mode 100644 index 0000000..e90d06e --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h @@ -0,0 +1,121 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H +#define BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H + +#include "btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionShapes/btTriangleCallback.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +class btDispatcher; +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "btCollisionCreateFunc.h" + +///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called. +class btConvexTriangleCallback : public btTriangleCallback +{ + const btCollisionObjectWrapper* m_convexBodyWrap; + const btCollisionObjectWrapper* m_triBodyWrap; + + btVector3 m_aabbMin; + btVector3 m_aabbMax ; + + + btManifoldResult* m_resultOut; + btDispatcher* m_dispatcher; + const btDispatcherInfo* m_dispatchInfoPtr; + btScalar m_collisionMarginTriangle; + +public: +int m_triangleCount; + + btPersistentManifold* m_manifoldPtr; + + btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + + void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut); + + void clearWrapperData() + { + m_convexBodyWrap = 0; + m_triBodyWrap = 0; + } + virtual ~btConvexTriangleCallback(); + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); + + void clearCache(); + + SIMD_FORCE_INLINE const btVector3& getAabbMin() const + { + return m_aabbMin; + } + SIMD_FORCE_INLINE const btVector3& getAabbMax() const + { + return m_aabbMax; + } + +}; + + + + +/// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes. +class btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ + + bool m_isSwapped; + + btConvexTriangleCallback m_btConvexTriangleCallback; + + + +public: + + btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + + virtual ~btConvexConcaveCollisionAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray); + + void clearCache(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); + return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false); + } + }; + + struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); + return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true); + } + }; + +}; + +#endif //BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp new file mode 100644 index 0000000..62f98a8 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp @@ -0,0 +1,784 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///Specialized capsule-capsule collision algorithm has been added for Bullet 2.75 release to increase ragdoll performance +///If you experience problems with capsule-capsule collision, try to define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER and report it in the Bullet forums +///with reproduction case +//define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER 1 +//#define ZERO_MARGIN + +#include "btConvexConvexAlgorithm.h" + +//#include +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" + + + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" + +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" + + + +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +/////////// + + + +static SIMD_FORCE_INLINE void segmentsClosestPoints( + btVector3& ptsVector, + btVector3& offsetA, + btVector3& offsetB, + btScalar& tA, btScalar& tB, + const btVector3& translation, + const btVector3& dirA, btScalar hlenA, + const btVector3& dirB, btScalar hlenB ) +{ + // compute the parameters of the closest points on each line segment + + btScalar dirA_dot_dirB = btDot(dirA,dirB); + btScalar dirA_dot_trans = btDot(dirA,translation); + btScalar dirB_dot_trans = btDot(dirB,translation); + + btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB; + + if ( denom == 0.0f ) { + tA = 0.0f; + } else { + tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom; + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } + + tB = tA * dirA_dot_dirB - dirB_dot_trans; + + if ( tB < -hlenB ) { + tB = -hlenB; + tA = tB * dirA_dot_dirB + dirA_dot_trans; + + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } else if ( tB > hlenB ) { + tB = hlenB; + tA = tB * dirA_dot_dirB + dirA_dot_trans; + + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } + + // compute the closest points relative to segment centers. + + offsetA = dirA * tA; + offsetB = dirB * tB; + + ptsVector = translation - offsetA + offsetB; +} + + +static SIMD_FORCE_INLINE btScalar capsuleCapsuleDistance( + btVector3& normalOnB, + btVector3& pointOnB, + btScalar capsuleLengthA, + btScalar capsuleRadiusA, + btScalar capsuleLengthB, + btScalar capsuleRadiusB, + int capsuleAxisA, + int capsuleAxisB, + const btTransform& transformA, + const btTransform& transformB, + btScalar distanceThreshold ) +{ + btVector3 directionA = transformA.getBasis().getColumn(capsuleAxisA); + btVector3 translationA = transformA.getOrigin(); + btVector3 directionB = transformB.getBasis().getColumn(capsuleAxisB); + btVector3 translationB = transformB.getOrigin(); + + // translation between centers + + btVector3 translation = translationB - translationA; + + // compute the closest points of the capsule line segments + + btVector3 ptsVector; // the vector between the closest points + + btVector3 offsetA, offsetB; // offsets from segment centers to their closest points + btScalar tA, tB; // parameters on line segment + + segmentsClosestPoints( ptsVector, offsetA, offsetB, tA, tB, translation, + directionA, capsuleLengthA, directionB, capsuleLengthB ); + + btScalar distance = ptsVector.length() - capsuleRadiusA - capsuleRadiusB; + + if ( distance > distanceThreshold ) + return distance; + + btScalar lenSqr = ptsVector.length2(); + if (lenSqr<= (SIMD_EPSILON*SIMD_EPSILON)) + { + //degenerate case where 2 capsules are likely at the same location: take a vector tangential to 'directionA' + btVector3 q; + btPlaneSpace1(directionA,normalOnB,q); + } else + { + // compute the contact normal + normalOnB = ptsVector*-btRecipSqrt(lenSqr); + } + pointOnB = transformB.getOrigin()+offsetB + normalOnB * capsuleRadiusB; + + return distance; +} + + + + + + + +////////// + + + + + +btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) +{ + m_numPerturbationIterations = 0; + m_minimumPointsPerturbationThreshold = 3; + m_simplexSolver = simplexSolver; + m_pdSolver = pdSolver; +} + +btConvexConvexAlgorithm::CreateFunc::~CreateFunc() +{ +} + +btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold) +: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), +m_simplexSolver(simplexSolver), +m_pdSolver(pdSolver), +m_ownManifold (false), +m_manifoldPtr(mf), +m_lowLevelOfDetail(false), +#ifdef USE_SEPDISTANCE_UTIL2 +m_sepDistance((static_cast(body0->getCollisionShape()))->getAngularMotionDisc(), + (static_cast(body1->getCollisionShape()))->getAngularMotionDisc()), +#endif +m_numPerturbationIterations(numPerturbationIterations), +m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) +{ + (void)body0Wrap; + (void)body1Wrap; +} + + + + +btConvexConvexAlgorithm::~btConvexConvexAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel) +{ + m_lowLevelOfDetail = useLowLevel; +} + + +struct btPerturbedContactResult : public btManifoldResult +{ + btManifoldResult* m_originalManifoldResult; + btTransform m_transformA; + btTransform m_transformB; + btTransform m_unPerturbedTransform; + bool m_perturbA; + btIDebugDraw* m_debugDrawer; + + + btPerturbedContactResult(btManifoldResult* originalResult,const btTransform& transformA,const btTransform& transformB,const btTransform& unPerturbedTransform,bool perturbA,btIDebugDraw* debugDrawer) + :m_originalManifoldResult(originalResult), + m_transformA(transformA), + m_transformB(transformB), + m_unPerturbedTransform(unPerturbedTransform), + m_perturbA(perturbA), + m_debugDrawer(debugDrawer) + { + } + virtual ~ btPerturbedContactResult() + { + } + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar orgDepth) + { + btVector3 endPt,startPt; + btScalar newDepth; + btVector3 newNormal; + + if (m_perturbA) + { + btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth; + endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg); + newDepth = (endPt - pointInWorld).dot(normalOnBInWorld); + startPt = endPt+normalOnBInWorld*newDepth; + } else + { + endPt = pointInWorld + normalOnBInWorld*orgDepth; + startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld); + newDepth = (endPt - startPt).dot(normalOnBInWorld); + + } + +//#define DEBUG_CONTACTS 1 +#ifdef DEBUG_CONTACTS + m_debugDrawer->drawLine(startPt,endPt,btVector3(1,0,0)); + m_debugDrawer->drawSphere(startPt,0.05,btVector3(0,1,0)); + m_debugDrawer->drawSphere(endPt,0.05,btVector3(0,0,1)); +#endif //DEBUG_CONTACTS + + + m_originalManifoldResult->addContactPoint(normalOnBInWorld,startPt,newDepth); + } + +}; + +extern btScalar gContactBreakingThreshold; + + +// +// Convex-Convex collision algorithm +// +void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + + if (!m_manifoldPtr) + { + //swapped? + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_ownManifold = true; + } + resultOut->setPersistentManifold(m_manifoldPtr); + + //comment-out next line to test multi-contact generation + //resultOut->getPersistentManifold()->clearManifold(); + + + const btConvexShape* min0 = static_cast(body0Wrap->getCollisionShape()); + const btConvexShape* min1 = static_cast(body1Wrap->getCollisionShape()); + + btVector3 normalOnB; + btVector3 pointOnBWorld; +#ifndef BT_DISABLE_CAPSULE_CAPSULE_COLLIDER + if ((min0->getShapeType() == CAPSULE_SHAPE_PROXYTYPE) && (min1->getShapeType() == CAPSULE_SHAPE_PROXYTYPE)) + { + btCapsuleShape* capsuleA = (btCapsuleShape*) min0; + btCapsuleShape* capsuleB = (btCapsuleShape*) min1; + // btVector3 localScalingA = capsuleA->getLocalScaling(); + // btVector3 localScalingB = capsuleB->getLocalScaling(); + + btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); + + btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(), + capsuleB->getHalfHeight(),capsuleB->getRadius(),capsuleA->getUpAxis(),capsuleB->getUpAxis(), + body0Wrap->getWorldTransform(),body1Wrap->getWorldTransform(),threshold); + + if (dist=(SIMD_EPSILON*SIMD_EPSILON)); + resultOut->addContactPoint(normalOnB,pointOnBWorld,dist); + } + resultOut->refreshContactPoints(); + return; + } +#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER + + + + +#ifdef USE_SEPDISTANCE_UTIL2 + if (dispatchInfo.m_useConvexConservativeDistanceUtil) + { + m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform()); + } + + if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f) +#endif //USE_SEPDISTANCE_UTIL2 + + { + + + btGjkPairDetector::ClosestPointInput input; + + btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver); + //TODO: if (dispatchInfo.m_useContinuous) + gjkPairDetector.setMinkowskiA(min0); + gjkPairDetector.setMinkowskiB(min1); + +#ifdef USE_SEPDISTANCE_UTIL2 + if (dispatchInfo.m_useConvexConservativeDistanceUtil) + { + input.m_maximumDistanceSquared = BT_LARGE_FLOAT; + } else +#endif //USE_SEPDISTANCE_UTIL2 + { + //if (dispatchInfo.m_convexMaxDistanceUseCPT) + //{ + // input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold(); + //} else + //{ + input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); +// } + + input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; + } + + input.m_stackAlloc = dispatchInfo.m_stackAllocator; + input.m_transformA = body0Wrap->getWorldTransform(); + input.m_transformB = body1Wrap->getWorldTransform(); + + + + + +#ifdef USE_SEPDISTANCE_UTIL2 + btScalar sepDist = 0.f; + if (dispatchInfo.m_useConvexConservativeDistanceUtil) + { + sepDist = gjkPairDetector.getCachedSeparatingDistance(); + if (sepDist>SIMD_EPSILON) + { + sepDist += dispatchInfo.m_convexConservativeDistanceThreshold; + //now perturbe directions to get multiple contact points + + } + } +#endif //USE_SEPDISTANCE_UTIL2 + + if (min0->isPolyhedral() && min1->isPolyhedral()) + { + + + struct btDummyResult : public btDiscreteCollisionDetectorInterface::Result + { + virtual void setShapeIdentifiersA(int partId0,int index0){} + virtual void setShapeIdentifiersB(int partId1,int index1){} + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + } + }; + + + struct btWithoutMarginResult : public btDiscreteCollisionDetectorInterface::Result + { + btDiscreteCollisionDetectorInterface::Result* m_originalResult; + btVector3 m_reportedNormalOnWorld; + btScalar m_marginOnA; + btScalar m_marginOnB; + btScalar m_reportedDistance; + + bool m_foundResult; + btWithoutMarginResult(btDiscreteCollisionDetectorInterface::Result* result, btScalar marginOnA, btScalar marginOnB) + :m_originalResult(result), + m_marginOnA(marginOnA), + m_marginOnB(marginOnB), + m_foundResult(false) + { + } + + virtual void setShapeIdentifiersA(int partId0,int index0){} + virtual void setShapeIdentifiersB(int partId1,int index1){} + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorldOrg,btScalar depthOrg) + { + m_reportedDistance = depthOrg; + m_reportedNormalOnWorld = normalOnBInWorld; + + btVector3 adjustedPointB = pointInWorldOrg - normalOnBInWorld*m_marginOnB; + m_reportedDistance = depthOrg+(m_marginOnA+m_marginOnB); + if (m_reportedDistance<0.f) + { + m_foundResult = true; + } + m_originalResult->addContactPoint(normalOnBInWorld,adjustedPointB,m_reportedDistance); + } + }; + + + btDummyResult dummy; + +///btBoxShape is an exception: its vertices are created WITH margin so don't subtract it + + btScalar min0Margin = min0->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min0->getMargin(); + btScalar min1Margin = min1->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min1->getMargin(); + + btWithoutMarginResult withoutMargin(resultOut, min0Margin,min1Margin); + + btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*) min0; + btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1; + if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron()) + { + + + + + btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); + + btScalar minDist = -1e30f; + btVector3 sepNormalWorldSpace; + bool foundSepAxis = true; + + if (dispatchInfo.m_enableSatConvex) + { + foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis( + *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), + body1Wrap->getWorldTransform(), + sepNormalWorldSpace,*resultOut); + } else + { +#ifdef ZERO_MARGIN + gjkPairDetector.setIgnoreMargin(true); + gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); +#else + + + gjkPairDetector.getClosestPoints(input,withoutMargin,dispatchInfo.m_debugDraw); + //gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw); +#endif //ZERO_MARGIN + //btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); + //if (l2>SIMD_EPSILON) + { + sepNormalWorldSpace = withoutMargin.m_reportedNormalOnWorld;//gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2); + //minDist = -1e30f;//gjkPairDetector.getCachedSeparatingDistance(); + minDist = withoutMargin.m_reportedDistance;//gjkPairDetector.getCachedSeparatingDistance()+min0->getMargin()+min1->getMargin(); + +#ifdef ZERO_MARGIN + foundSepAxis = true;//gjkPairDetector.getCachedSeparatingDistance()<0.f; +#else + foundSepAxis = withoutMargin.m_foundResult && minDist<0;//-(min0->getMargin()+min1->getMargin()); +#endif + } + } + if (foundSepAxis) + { + +// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); + + btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), + body1Wrap->getWorldTransform(), minDist-threshold, threshold, *resultOut); + + } + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + return; + + } else + { + //we can also deal with convex versus triangle (without connectivity data) + if (polyhedronA->getConvexPolyhedron() && polyhedronB->getShapeType()==TRIANGLE_SHAPE_PROXYTYPE) + { + + btVertexArray vertices; + btTriangleShape* tri = (btTriangleShape*)polyhedronB; + vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[0]); + vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[1]); + vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[2]); + + //tri->initializePolyhedralFeatures(); + + btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); + + btVector3 sepNormalWorldSpace; + btScalar minDist =-1e30f; + btScalar maxDist = threshold; + + bool foundSepAxis = false; + if (0) + { + polyhedronB->initializePolyhedralFeatures(); + foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis( + *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), + body1Wrap->getWorldTransform(), + sepNormalWorldSpace,*resultOut); + // printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); + + } else + { +#ifdef ZERO_MARGIN + gjkPairDetector.setIgnoreMargin(true); + gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); +#else + gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw); +#endif//ZERO_MARGIN + + btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); + if (l2>SIMD_EPSILON) + { + sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2); + //minDist = gjkPairDetector.getCachedSeparatingDistance(); + //maxDist = threshold; + minDist = gjkPairDetector.getCachedSeparatingDistance()-min0->getMargin()-min1->getMargin(); + foundSepAxis = true; + } + } + + + if (foundSepAxis) + { + btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut); + } + + + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + + return; + } + + } + + + } + + gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + + //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects + + //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points + if (m_numPerturbationIterations && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold) + { + + int i; + btVector3 v0,v1; + btVector3 sepNormalWorldSpace; + btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); + + if (l2>SIMD_EPSILON) + { + sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2); + + btPlaneSpace1(sepNormalWorldSpace,v0,v1); + + + bool perturbeA = true; + const btScalar angleLimit = 0.125f * SIMD_PI; + btScalar perturbeAngle; + btScalar radiusA = min0->getAngularMotionDisc(); + btScalar radiusB = min1->getAngularMotionDisc(); + if (radiusA < radiusB) + { + perturbeAngle = gContactBreakingThreshold /radiusA; + perturbeA = true; + } else + { + perturbeAngle = gContactBreakingThreshold / radiusB; + perturbeA = false; + } + if ( perturbeAngle > angleLimit ) + perturbeAngle = angleLimit; + + btTransform unPerturbedTransform; + if (perturbeA) + { + unPerturbedTransform = input.m_transformA; + } else + { + unPerturbedTransform = input.m_transformB; + } + + for ( i=0;iSIMD_EPSILON) + { + btQuaternion perturbeRot(v0,perturbeAngle); + btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations)); + btQuaternion rotq(sepNormalWorldSpace,iterationAngle); + + + if (perturbeA) + { + input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0Wrap->getWorldTransform().getBasis()); + input.m_transformB = body1Wrap->getWorldTransform(); + #ifdef DEBUG_CONTACTS + dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0); + #endif //DEBUG_CONTACTS + } else + { + input.m_transformA = body0Wrap->getWorldTransform(); + input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1Wrap->getWorldTransform().getBasis()); + #ifdef DEBUG_CONTACTS + dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0); + #endif + } + + btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw); + gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw); + } + } + } + } + + + +#ifdef USE_SEPDISTANCE_UTIL2 + if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist>SIMD_EPSILON)) + { + m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform()); + } +#endif //USE_SEPDISTANCE_UTIL2 + + + } + + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + +} + + + +bool disableCcd = false; +btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold + + ///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold + ///col0->m_worldTransform, + btScalar resultFraction = btScalar(1.); + + + btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2(); + btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2(); + + if (squareMot0 < col0->getCcdSquareMotionThreshold() && + squareMot1 < col1->getCcdSquareMotionThreshold()) + return resultFraction; + + if (disableCcd) + return btScalar(1.); + + + //An adhoc way of testing the Continuous Collision Detection algorithms + //One object is approximated as a sphere, to simplify things + //Starting in penetration should report no time of impact + //For proper CCD, better accuracy and handling of 'allowed' penetration should be added + //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) + + + /// Convex0 against sphere for Convex1 + { + btConvexShape* convex0 = static_cast(col0->getCollisionShape()); + + btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btConvexCast::CastResult result; + btVoronoiSimplexSolver voronoiSimplex; + //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); + ///Simplification, one object is simplified as a sphere + btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex); + //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), + col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + { + + //store result.m_fraction in both bodies + + if (col0->getHitFraction()> result.m_fraction) + col0->setHitFraction( result.m_fraction ); + + if (col1->getHitFraction() > result.m_fraction) + col1->setHitFraction( result.m_fraction); + + if (resultFraction > result.m_fraction) + resultFraction = result.m_fraction; + + } + + + + + } + + /// Sphere (for convex0) against Convex1 + { + btConvexShape* convex1 = static_cast(col1->getCollisionShape()); + + btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btConvexCast::CastResult result; + btVoronoiSimplexSolver voronoiSimplex; + //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); + ///Simplification, one object is simplified as a sphere + btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex); + //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), + col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + { + + //store result.m_fraction in both bodies + + if (col0->getHitFraction() > result.m_fraction) + col0->setHitFraction( result.m_fraction); + + if (col1->getHitFraction() > result.m_fraction) + col1->setHitFraction( result.m_fraction); + + if (resultFraction > result.m_fraction) + resultFraction = result.m_fraction; + + } + } + + return resultFraction; + +} + diff --git a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h new file mode 100644 index 0000000..51db0c6 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h @@ -0,0 +1,108 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_CONVEX_ALGORITHM_H +#define BT_CONVEX_CONVEX_ALGORITHM_H + +#include "btActivatingCollisionAlgorithm.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "btCollisionCreateFunc.h" +#include "btCollisionDispatcher.h" +#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil + +class btConvexPenetrationDepthSolver; + +///Enabling USE_SEPDISTANCE_UTIL2 requires 100% reliable distance computation. However, when using large size ratios GJK can be imprecise +///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions. +///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util +///for certain pairs that have a small size ratio + +//#define USE_SEPDISTANCE_UTIL2 1 + +///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects. +///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal. +///This idea was described by Gino van den Bergen in this forum topic http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=4&t=288&p=888#p888 +class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm +{ +#ifdef USE_SEPDISTANCE_UTIL2 + btConvexSeparatingDistanceUtil m_sepDistance; +#endif + btSimplexSolverInterface* m_simplexSolver; + btConvexPenetrationDepthSolver* m_pdSolver; + + + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_lowLevelOfDetail; + + int m_numPerturbationIterations; + int m_minimumPointsPerturbationThreshold; + + + ///cache separating vector to speedup collision detection + + +public: + + btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold); + + virtual ~btConvexConvexAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + ///should we use m_ownManifold to avoid adding duplicates? + if (m_manifoldPtr && m_ownManifold) + manifoldArray.push_back(m_manifoldPtr); + } + + + void setLowLevelOfDetail(bool useLowLevel); + + + const btPersistentManifold* getManifold() + { + return m_manifoldPtr; + } + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + + btConvexPenetrationDepthSolver* m_pdSolver; + btSimplexSolverInterface* m_simplexSolver; + int m_numPerturbationIterations; + int m_minimumPointsPerturbationThreshold; + + CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); + + virtual ~CreateFunc(); + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm)); + return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); + } + }; + + +}; + +#endif //BT_CONVEX_CONVEX_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp new file mode 100644 index 0000000..cce2d95 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp @@ -0,0 +1,174 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConvexPlaneCollisionAlgorithm.h" + +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +//#include + +btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold) +: btCollisionAlgorithm(ci), +m_ownManifold(false), +m_manifoldPtr(mf), +m_isSwapped(isSwapped), +m_numPerturbationIterations(numPerturbationIterations), +m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) +{ + const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? col1Wrap : col0Wrap; + const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? col0Wrap : col1Wrap; + + if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject())) + { + m_manifoldPtr = m_dispatcher->getNewManifold(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject()); + m_ownManifold = true; + } +} + + +btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap; + + btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape(); + btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape(); + + bool hasCollision = false; + const btVector3& planeNormal = planeShape->getPlaneNormal(); + const btScalar& planeConstant = planeShape->getPlaneConstant(); + + btTransform convexWorldTransform = convexObjWrap->getWorldTransform(); + btTransform convexInPlaneTrans; + convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexWorldTransform; + //now perturbe the convex-world transform + convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot); + btTransform planeInConvex; + planeInConvex= convexWorldTransform.inverse() * planeObjWrap->getWorldTransform(); + + btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); + + btVector3 vtxInPlane = convexInPlaneTrans(vtx); + btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); + + btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal; + btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected; + + hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold(); + resultOut->setPersistentManifold(m_manifoldPtr); + if (hasCollision) + { + /// report a contact. internally this will be kept persistent, and contact reduction is done + btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal; + btVector3 pOnB = vtxInPlaneWorld; + resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance); + } +} + + +void btConvexPlaneCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)dispatchInfo; + if (!m_manifoldPtr) + return; + + const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap; + + btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape(); + btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape(); + + bool hasCollision = false; + const btVector3& planeNormal = planeShape->getPlaneNormal(); + const btScalar& planeConstant = planeShape->getPlaneConstant(); + btTransform planeInConvex; + planeInConvex= convexObjWrap->getWorldTransform().inverse() * planeObjWrap->getWorldTransform(); + btTransform convexInPlaneTrans; + convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexObjWrap->getWorldTransform(); + + btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); + btVector3 vtxInPlane = convexInPlaneTrans(vtx); + btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); + + btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal; + btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected; + + hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold(); + resultOut->setPersistentManifold(m_manifoldPtr); + if (hasCollision) + { + /// report a contact. internally this will be kept persistent, and contact reduction is done + btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal; + btVector3 pOnB = vtxInPlaneWorld; + resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance); + } + + //the perturbation algorithm doesn't work well with implicit surfaces such as spheres, cylinder and cones: + //they keep on rolling forever because of the additional off-center contact points + //so only enable the feature for polyhedral shapes (btBoxShape, btConvexHullShape etc) + if (convexShape->isPolyhedral() && resultOut->getPersistentManifold()->getNumContacts()getAngularMotionDisc(); + perturbeAngle = gContactBreakingThreshold / radius; + if ( perturbeAngle > angleLimit ) + perturbeAngle = angleLimit; + + btQuaternion perturbeRot(v0,perturbeAngle); + for (int i=0;igetNumContacts()) + { + resultOut->refreshContactPoints(); + } + } +} + +btScalar btConvexPlaneCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + (void)col0; + (void)col1; + + //not yet + return btScalar(1.); +} diff --git a/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h new file mode 100644 index 0000000..d28c430 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h @@ -0,0 +1,84 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_PLANE_COLLISION_ALGORITHM_H +#define BT_CONVEX_PLANE_COLLISION_ALGORITHM_H + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +class btPersistentManifold; +#include "btCollisionDispatcher.h" + +#include "LinearMath/btVector3.h" + +/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection. +/// Other features are frame-coherency (persistent data) and collision response. +class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_isSwapped; + int m_numPerturbationIterations; + int m_minimumPointsPerturbationThreshold; + +public: + + btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold); + + virtual ~btConvexPlaneCollisionAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + void collideSingleContact (const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr && m_ownManifold) + { + manifoldArray.push_back(m_manifoldPtr); + } + } + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + int m_numPerturbationIterations; + int m_minimumPointsPerturbationThreshold; + + CreateFunc() + : m_numPerturbationIterations(1), + m_minimumPointsPerturbationThreshold(0) + { + } + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm)); + if (!m_swapped) + { + return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); + } else + { + return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); + } + } + }; + +}; + +#endif //BT_CONVEX_PLANE_COLLISION_ALGORITHM_H + diff --git a/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp new file mode 100644 index 0000000..7faee6f --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp @@ -0,0 +1,309 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btDefaultCollisionConfiguration.h" + +#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" +#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM +#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM +#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" + + + +#include "LinearMath/btStackAlloc.h" +#include "LinearMath/btPoolAllocator.h" + + + + + +btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo) +//btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool) +{ + + void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16); + m_simplexSolver = new (mem)btVoronoiSimplexSolver(); + + if (constructionInfo.m_useEpaPenetrationAlgorithm) + { + mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16); + m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver; + }else + { + mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16); + m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver; + } + + //default CreationFunctions, filling the m_doubleDispatch table + mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16); + m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver); + mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); + m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); + m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc; + mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16); + m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16); + m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc; + mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16); + m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc; + + mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16); + m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc; +#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM + mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); + m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); + m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc; + m_boxSphereCF->m_swapped = true; +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM + + mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); + m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); + m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; + m_triangleSphereCF->m_swapped = true; + + mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc),16); + m_boxBoxCF = new(mem)btBoxBoxCollisionAlgorithm::CreateFunc; + + //convex versus plane + mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16); + m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16); + m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc; + m_planeConvexCF->m_swapped = true; + + ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool + int maxSize = sizeof(btConvexConvexAlgorithm); + int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm); + int maxSize3 = sizeof(btCompoundCollisionAlgorithm); + int sl = sizeof(btConvexSeparatingDistanceUtil); + sl = sizeof(btGjkPairDetector); + int collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3); + + if (constructionInfo.m_stackAlloc) + { + m_ownsStackAllocator = false; + this->m_stackAlloc = constructionInfo.m_stackAlloc; + } else + { + m_ownsStackAllocator = true; + void* mem = btAlignedAlloc(sizeof(btStackAlloc),16); + m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize); + } + + if (constructionInfo.m_persistentManifoldPool) + { + m_ownsPersistentManifoldPool = false; + m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool; + } else + { + m_ownsPersistentManifoldPool = true; + void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); + m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize); + } + + if (constructionInfo.m_collisionAlgorithmPool) + { + m_ownsCollisionAlgorithmPool = false; + m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool; + } else + { + m_ownsCollisionAlgorithmPool = true; + void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); + m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize); + } + + +} + +btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration() +{ + if (m_ownsStackAllocator) + { + m_stackAlloc->destroy(); + m_stackAlloc->~btStackAlloc(); + btAlignedFree(m_stackAlloc); + } + if (m_ownsCollisionAlgorithmPool) + { + m_collisionAlgorithmPool->~btPoolAllocator(); + btAlignedFree(m_collisionAlgorithmPool); + } + if (m_ownsPersistentManifoldPool) + { + m_persistentManifoldPool->~btPoolAllocator(); + btAlignedFree(m_persistentManifoldPool); + } + + m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_convexConvexCreateFunc); + + m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_convexConcaveCreateFunc); + m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_swappedConvexConcaveCreateFunc); + + m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_compoundCreateFunc); + + m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_swappedCompoundCreateFunc); + + m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_emptyCreateFunc); + + m_sphereSphereCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_sphereSphereCF); + +#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM + m_sphereBoxCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_sphereBoxCF); + m_boxSphereCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_boxSphereCF); +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM + + m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_sphereTriangleCF); + m_triangleSphereCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_triangleSphereCF); + m_boxBoxCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_boxBoxCF); + + m_convexPlaneCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_convexPlaneCF); + m_planeConvexCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_planeConvexCF); + + m_simplexSolver->~btVoronoiSimplexSolver(); + btAlignedFree(m_simplexSolver); + + m_pdSolver->~btConvexPenetrationDepthSolver(); + + btAlignedFree(m_pdSolver); + + +} + + +btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) +{ + + + + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + { + return m_sphereSphereCF; + } +#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE)) + { + return m_sphereBoxCF; + } + + if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + { + return m_boxSphereCF; + } +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM + + + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE)) + { + return m_sphereTriangleCF; + } + + if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + { + return m_triangleSphereCF; + } + + if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE)) + { + return m_boxBoxCF; + } + + if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE)) + { + return m_convexPlaneCF; + } + + if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE)) + { + return m_planeConvexCF; + } + + + + if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1)) + { + return m_convexConvexCreateFunc; + } + + if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1)) + { + return m_convexConcaveCreateFunc; + } + + if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0)) + { + return m_swappedConvexConcaveCreateFunc; + } + + if (btBroadphaseProxy::isCompound(proxyType0)) + { + return m_compoundCreateFunc; + } else + { + if (btBroadphaseProxy::isCompound(proxyType1)) + { + return m_swappedCompoundCreateFunc; + } + } + + //failed to find an algorithm + return m_emptyCreateFunc; +} + +void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold) +{ + btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc; + convexConvex->m_numPerturbationIterations = numPerturbationIterations; + convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold; +} + +void btDefaultCollisionConfiguration::setPlaneConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold) +{ + btConvexPlaneCollisionAlgorithm::CreateFunc* cpCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_convexPlaneCF; + cpCF->m_numPerturbationIterations = numPerturbationIterations; + cpCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold; + + btConvexPlaneCollisionAlgorithm::CreateFunc* pcCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_planeConvexCF; + pcCF->m_numPerturbationIterations = numPerturbationIterations; + pcCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold; +} diff --git a/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h new file mode 100644 index 0000000..474785b --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h @@ -0,0 +1,135 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_DEFAULT_COLLISION_CONFIGURATION +#define BT_DEFAULT_COLLISION_CONFIGURATION + +#include "btCollisionConfiguration.h" +class btVoronoiSimplexSolver; +class btConvexPenetrationDepthSolver; + +struct btDefaultCollisionConstructionInfo +{ + btStackAlloc* m_stackAlloc; + btPoolAllocator* m_persistentManifoldPool; + btPoolAllocator* m_collisionAlgorithmPool; + int m_defaultMaxPersistentManifoldPoolSize; + int m_defaultMaxCollisionAlgorithmPoolSize; + int m_customCollisionAlgorithmMaxElementSize; + int m_defaultStackAllocatorSize; + int m_useEpaPenetrationAlgorithm; + + btDefaultCollisionConstructionInfo() + :m_stackAlloc(0), + m_persistentManifoldPool(0), + m_collisionAlgorithmPool(0), + m_defaultMaxPersistentManifoldPoolSize(4096), + m_defaultMaxCollisionAlgorithmPoolSize(4096), + m_customCollisionAlgorithmMaxElementSize(0), + m_defaultStackAllocatorSize(0), + m_useEpaPenetrationAlgorithm(true) + { + } +}; + + + +///btCollisionConfiguration allows to configure Bullet collision detection +///stack allocator, pool memory allocators +///@todo: describe the meaning +class btDefaultCollisionConfiguration : public btCollisionConfiguration +{ + +protected: + + int m_persistentManifoldPoolSize; + + btStackAlloc* m_stackAlloc; + bool m_ownsStackAllocator; + + btPoolAllocator* m_persistentManifoldPool; + bool m_ownsPersistentManifoldPool; + + + btPoolAllocator* m_collisionAlgorithmPool; + bool m_ownsCollisionAlgorithmPool; + + //default simplex/penetration depth solvers + btVoronoiSimplexSolver* m_simplexSolver; + btConvexPenetrationDepthSolver* m_pdSolver; + + //default CreationFunctions, filling the m_doubleDispatch table + btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_compoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_emptyCreateFunc; + btCollisionAlgorithmCreateFunc* m_sphereSphereCF; + btCollisionAlgorithmCreateFunc* m_sphereBoxCF; + btCollisionAlgorithmCreateFunc* m_boxSphereCF; + + btCollisionAlgorithmCreateFunc* m_boxBoxCF; + btCollisionAlgorithmCreateFunc* m_sphereTriangleCF; + btCollisionAlgorithmCreateFunc* m_triangleSphereCF; + btCollisionAlgorithmCreateFunc* m_planeConvexCF; + btCollisionAlgorithmCreateFunc* m_convexPlaneCF; + +public: + + + btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo()); + + virtual ~btDefaultCollisionConfiguration(); + + ///memory pools + virtual btPoolAllocator* getPersistentManifoldPool() + { + return m_persistentManifoldPool; + } + + virtual btPoolAllocator* getCollisionAlgorithmPool() + { + return m_collisionAlgorithmPool; + } + + virtual btStackAlloc* getStackAllocator() + { + return m_stackAlloc; + } + + virtual btVoronoiSimplexSolver* getSimplexSolver() + { + return m_simplexSolver; + } + + + virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); + + ///Use this method to allow to generate multiple contact points between at once, between two objects using the generic convex-convex algorithm. + ///By default, this feature is disabled for best performance. + ///@param numPerturbationIterations controls the number of collision queries. Set it to zero to disable the feature. + ///@param minimumPointsPerturbationThreshold is the minimum number of points in the contact cache, above which the feature is disabled + ///3 is a good value for both params, if you want to enable the feature. This is because the default contact cache contains a maximum of 4 points, and one collision query at the unperturbed orientation is performed first. + ///See Bullet/Demos/CollisionDemo for an example how this feature gathers multiple points. + ///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection. + void setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3); + + void setPlaneConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3); + +}; + +#endif //BT_DEFAULT_COLLISION_CONFIGURATION + diff --git a/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp new file mode 100644 index 0000000..5fa1c8b --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp @@ -0,0 +1,34 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btEmptyCollisionAlgorithm.h" + + + +btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btCollisionAlgorithm(ci) +{ +} + +void btEmptyAlgorithm::processCollision (const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* ,const btDispatcherInfo& ,btManifoldResult* ) +{ +} + +btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* ) +{ + return btScalar(1.); +} + + diff --git a/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h new file mode 100644 index 0000000..cb0f152 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h @@ -0,0 +1,54 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_EMPTY_ALGORITH +#define BT_EMPTY_ALGORITH +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "btCollisionCreateFunc.h" +#include "btCollisionDispatcher.h" + +#define ATTRIBUTE_ALIGNED(a) + +///EmptyAlgorithm is a stub for unsupported collision pairs. +///The dispatcher can dispatch a persistent btEmptyAlgorithm to avoid a search every frame. +class btEmptyAlgorithm : public btCollisionAlgorithm +{ + +public: + + btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + } + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + (void)body0Wrap; + (void)body1Wrap; + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm)); + return new(mem) btEmptyAlgorithm(ci); + } + }; + +} ATTRIBUTE_ALIGNED(16); + +#endif //BT_EMPTY_ALGORITH diff --git a/src/BulletCollision/CollisionDispatch/btGhostObject.cpp b/src/BulletCollision/CollisionDispatch/btGhostObject.cpp new file mode 100644 index 0000000..86141fa --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btGhostObject.cpp @@ -0,0 +1,171 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btGhostObject.h" +#include "btCollisionWorld.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "LinearMath/btAabbUtil2.h" + +btGhostObject::btGhostObject() +{ + m_internalType = CO_GHOST_OBJECT; +} + +btGhostObject::~btGhostObject() +{ + ///btGhostObject should have been removed from the world, so no overlapping objects + btAssert(!m_overlappingObjects.size()); +} + + +void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy) +{ + btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; + btAssert(otherObject); + ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure + int index = m_overlappingObjects.findLinearSearch(otherObject); + if (index==m_overlappingObjects.size()) + { + //not found + m_overlappingObjects.push_back(otherObject); + } +} + +void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy) +{ + btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; + btAssert(otherObject); + int index = m_overlappingObjects.findLinearSearch(otherObject); + if (index~btHashedOverlappingPairCache(); + btAlignedFree( m_hashPairCache ); +} + +void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy) +{ + btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle(); + btAssert(actualThisProxy); + + btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; + btAssert(otherObject); + int index = m_overlappingObjects.findLinearSearch(otherObject); + if (index==m_overlappingObjects.size()) + { + m_overlappingObjects.push_back(otherObject); + m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy); + } +} + +void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1) +{ + btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; + btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle(); + btAssert(actualThisProxy); + + btAssert(otherObject); + int index = m_overlappingObjects.findLinearSearch(otherObject); + if (indexremoveOverlappingPair(actualThisProxy,otherProxy,dispatcher); + } +} + + +void btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const +{ + btTransform convexFromTrans,convexToTrans; + convexFromTrans = convexFromWorld; + convexToTrans = convexToWorld; + btVector3 castShapeAabbMin, castShapeAabbMax; + /* Compute AABB that encompasses angular movement */ + { + btVector3 linVel, angVel; + btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel); + btTransform R; + R.setIdentity (); + R.setRotation (convexFromTrans.getRotation()); + castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax); + } + + /// go over all objects, and if the ray intersects their aabb + cast shape aabb, + // do a ray-shape query using convexCaster (CCD) + int i; + for (i=0;igetBroadphaseHandle())) { + //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); + btVector3 collisionObjectAabbMin,collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); + AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax); + btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing + btVector3 hitNormal; + if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) + { + btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + resultCallback, + allowedCcdPenetration); + } + } + } + +} + +void btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const +{ + btTransform rayFromTrans; + rayFromTrans.setIdentity(); + rayFromTrans.setOrigin(rayFromWorld); + btTransform rayToTrans; + rayToTrans.setIdentity(); + rayToTrans.setOrigin(rayToWorld); + + + int i; + for (i=0;igetBroadphaseHandle())) + { + btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + resultCallback); + } + } +} + diff --git a/src/BulletCollision/CollisionDispatch/btGhostObject.h b/src/BulletCollision/CollisionDispatch/btGhostObject.h new file mode 100644 index 0000000..8ec8613 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btGhostObject.h @@ -0,0 +1,175 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_GHOST_OBJECT_H +#define BT_GHOST_OBJECT_H + + +#include "btCollisionObject.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h" +#include "LinearMath/btAlignedAllocator.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "btCollisionWorld.h" + +class btConvexShape; + +class btDispatcher; + +///The btGhostObject can keep track of all objects that are overlapping +///By default, this overlap is based on the AABB +///This is useful for creating a character controller, collision sensors/triggers, explosions etc. +///We plan on adding rayTest and other queries for the btGhostObject +ATTRIBUTE_ALIGNED16(class) btGhostObject : public btCollisionObject +{ +protected: + + btAlignedObjectArray m_overlappingObjects; + +public: + + btGhostObject(); + + virtual ~btGhostObject(); + + void convexSweepTest(const class btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = 0.f) const; + + void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; + + ///this method is mainly for expert/internal use only. + virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0); + ///this method is mainly for expert/internal use only. + virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0); + + int getNumOverlappingObjects() const + { + return m_overlappingObjects.size(); + } + + btCollisionObject* getOverlappingObject(int index) + { + return m_overlappingObjects[index]; + } + + const btCollisionObject* getOverlappingObject(int index) const + { + return m_overlappingObjects[index]; + } + + btAlignedObjectArray& getOverlappingPairs() + { + return m_overlappingObjects; + } + + const btAlignedObjectArray getOverlappingPairs() const + { + return m_overlappingObjects; + } + + // + // internal cast + // + + static const btGhostObject* upcast(const btCollisionObject* colObj) + { + if (colObj->getInternalType()==CO_GHOST_OBJECT) + return (const btGhostObject*)colObj; + return 0; + } + static btGhostObject* upcast(btCollisionObject* colObj) + { + if (colObj->getInternalType()==CO_GHOST_OBJECT) + return (btGhostObject*)colObj; + return 0; + } + +}; + +class btPairCachingGhostObject : public btGhostObject +{ + btHashedOverlappingPairCache* m_hashPairCache; + +public: + + btPairCachingGhostObject(); + + virtual ~btPairCachingGhostObject(); + + ///this method is mainly for expert/internal use only. + virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0); + + virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0); + + btHashedOverlappingPairCache* getOverlappingPairCache() + { + return m_hashPairCache; + } + +}; + + + +///The btGhostPairCallback interfaces and forwards adding and removal of overlapping pairs from the btBroadphaseInterface to btGhostObject. +class btGhostPairCallback : public btOverlappingPairCallback +{ + +public: + btGhostPairCallback() + { + } + + virtual ~btGhostPairCallback() + { + + } + + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + { + btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject; + btGhostObject* ghost0 = btGhostObject::upcast(colObj0); + btGhostObject* ghost1 = btGhostObject::upcast(colObj1); + if (ghost0) + ghost0->addOverlappingObjectInternal(proxy1, proxy0); + if (ghost1) + ghost1->addOverlappingObjectInternal(proxy0, proxy1); + return 0; + } + + virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher) + { + btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject; + btGhostObject* ghost0 = btGhostObject::upcast(colObj0); + btGhostObject* ghost1 = btGhostObject::upcast(colObj1); + if (ghost0) + ghost0->removeOverlappingObjectInternal(proxy1,dispatcher,proxy0); + if (ghost1) + ghost1->removeOverlappingObjectInternal(proxy0,dispatcher,proxy1); + return 0; + } + + virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/) + { + btAssert(0); + //need to keep track of all ghost objects and call them here + //m_hashPairCache->removeOverlappingPairsContainingProxy(proxy0,dispatcher); + } + + + +}; + +#endif + diff --git a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp new file mode 100644 index 0000000..73fa4e8 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp @@ -0,0 +1,842 @@ +#include "btInternalEdgeUtility.h" + +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +//#define DEBUG_INTERNAL_EDGE + +#ifdef DEBUG_INTERNAL_EDGE +#include +#endif //DEBUG_INTERNAL_EDGE + + +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW +static btIDebugDraw* gDebugDrawer = 0; + +void btSetDebugDrawer(btIDebugDraw* debugDrawer) +{ + gDebugDrawer = debugDrawer; +} + +static void btDebugDrawLine(const btVector3& from,const btVector3& to, const btVector3& color) +{ + if (gDebugDrawer) + gDebugDrawer->drawLine(from,to,color); +} +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + +static int btGetHash(int partId, int triangleIndex) +{ + int hash = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; + return hash; +} + + + +static btScalar btGetAngle(const btVector3& edgeA, const btVector3& normalA,const btVector3& normalB) +{ + const btVector3 refAxis0 = edgeA; + const btVector3 refAxis1 = normalA; + const btVector3 swingAxis = normalB; + btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); + return angle; +} + + +struct btConnectivityProcessor : public btTriangleCallback +{ + int m_partIdA; + int m_triangleIndexA; + btVector3* m_triangleVerticesA; + btTriangleInfoMap* m_triangleInfoMap; + + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) + { + //skip self-collisions + if ((m_partIdA == partId) && (m_triangleIndexA == triangleIndex)) + return; + + //skip duplicates (disabled for now) + //if ((m_partIdA <= partId) && (m_triangleIndexA <= triangleIndex)) + // return; + + //search for shared vertices and edges + int numshared = 0; + int sharedVertsA[3]={-1,-1,-1}; + int sharedVertsB[3]={-1,-1,-1}; + + ///skip degenerate triangles + btScalar crossBSqr = ((triangle[1]-triangle[0]).cross(triangle[2]-triangle[0])).length2(); + if (crossBSqr < m_triangleInfoMap->m_equalVertexThreshold) + return; + + + btScalar crossASqr = ((m_triangleVerticesA[1]-m_triangleVerticesA[0]).cross(m_triangleVerticesA[2]-m_triangleVerticesA[0])).length2(); + ///skip degenerate triangles + if (crossASqr< m_triangleInfoMap->m_equalVertexThreshold) + return; + +#if 0 + printf("triangle A[0] = (%f,%f,%f)\ntriangle A[1] = (%f,%f,%f)\ntriangle A[2] = (%f,%f,%f)\n", + m_triangleVerticesA[0].getX(),m_triangleVerticesA[0].getY(),m_triangleVerticesA[0].getZ(), + m_triangleVerticesA[1].getX(),m_triangleVerticesA[1].getY(),m_triangleVerticesA[1].getZ(), + m_triangleVerticesA[2].getX(),m_triangleVerticesA[2].getY(),m_triangleVerticesA[2].getZ()); + + printf("partId=%d, triangleIndex=%d\n",partId,triangleIndex); + printf("triangle B[0] = (%f,%f,%f)\ntriangle B[1] = (%f,%f,%f)\ntriangle B[2] = (%f,%f,%f)\n", + triangle[0].getX(),triangle[0].getY(),triangle[0].getZ(), + triangle[1].getX(),triangle[1].getY(),triangle[1].getZ(), + triangle[2].getX(),triangle[2].getY(),triangle[2].getZ()); +#endif + + for (int i=0;i<3;i++) + { + for (int j=0;j<3;j++) + { + if ( (m_triangleVerticesA[i]-triangle[j]).length2() < m_triangleInfoMap->m_equalVertexThreshold) + { + sharedVertsA[numshared] = i; + sharedVertsB[numshared] = j; + numshared++; + ///degenerate case + if(numshared >= 3) + return; + } + } + ///degenerate case + if(numshared >= 3) + return; + } + switch (numshared) + { + case 0: + { + break; + } + case 1: + { + //shared vertex + break; + } + case 2: + { + //shared edge + //we need to make sure the edge is in the order V2V0 and not V0V2 so that the signs are correct + if (sharedVertsA[0] == 0 && sharedVertsA[1] == 2) + { + sharedVertsA[0] = 2; + sharedVertsA[1] = 0; + int tmp = sharedVertsB[1]; + sharedVertsB[1] = sharedVertsB[0]; + sharedVertsB[0] = tmp; + } + + int hash = btGetHash(m_partIdA,m_triangleIndexA); + + btTriangleInfo* info = m_triangleInfoMap->find(hash); + if (!info) + { + btTriangleInfo tmp; + m_triangleInfoMap->insert(hash,tmp); + info = m_triangleInfoMap->find(hash); + } + + int sumvertsA = sharedVertsA[0]+sharedVertsA[1]; + int otherIndexA = 3-sumvertsA; + + + btVector3 edge(m_triangleVerticesA[sharedVertsA[1]]-m_triangleVerticesA[sharedVertsA[0]]); + + btTriangleShape tA(m_triangleVerticesA[0],m_triangleVerticesA[1],m_triangleVerticesA[2]); + int otherIndexB = 3-(sharedVertsB[0]+sharedVertsB[1]); + + btTriangleShape tB(triangle[sharedVertsB[1]],triangle[sharedVertsB[0]],triangle[otherIndexB]); + //btTriangleShape tB(triangle[0],triangle[1],triangle[2]); + + btVector3 normalA; + btVector3 normalB; + tA.calcNormal(normalA); + tB.calcNormal(normalB); + edge.normalize(); + btVector3 edgeCrossA = edge.cross(normalA).normalize(); + + { + btVector3 tmp = m_triangleVerticesA[otherIndexA]-m_triangleVerticesA[sharedVertsA[0]]; + if (edgeCrossA.dot(tmp) < 0) + { + edgeCrossA*=-1; + } + } + + btVector3 edgeCrossB = edge.cross(normalB).normalize(); + + { + btVector3 tmp = triangle[otherIndexB]-triangle[sharedVertsB[0]]; + if (edgeCrossB.dot(tmp) < 0) + { + edgeCrossB*=-1; + } + } + + btScalar angle2 = 0; + btScalar ang4 = 0.f; + + + btVector3 calculatedEdge = edgeCrossA.cross(edgeCrossB); + btScalar len2 = calculatedEdge.length2(); + + btScalar correctedAngle(0); + btVector3 calculatedNormalB = normalA; + bool isConvex = false; + + if (len2m_planarEpsilon) + { + angle2 = 0.f; + ang4 = 0.f; + } else + { + + calculatedEdge.normalize(); + btVector3 calculatedNormalA = calculatedEdge.cross(edgeCrossA); + calculatedNormalA.normalize(); + angle2 = btGetAngle(calculatedNormalA,edgeCrossA,edgeCrossB); + ang4 = SIMD_PI-angle2; + btScalar dotA = normalA.dot(edgeCrossB); + ///@todo: check if we need some epsilon, due to floating point imprecision + isConvex = (dotA<0.); + + correctedAngle = isConvex ? ang4 : -ang4; + btQuaternion orn2(calculatedEdge,-correctedAngle); + calculatedNormalB = btMatrix3x3(orn2)*normalA; + + + } + + + + + + //alternatively use + //btVector3 calculatedNormalB2 = quatRotate(orn,normalA); + + + switch (sumvertsA) + { + case 1: + { + btVector3 edge = m_triangleVerticesA[0]-m_triangleVerticesA[1]; + btQuaternion orn(edge,-correctedAngle); + btVector3 computedNormalB = quatRotate(orn,normalA); + btScalar bla = computedNormalB.dot(normalB); + if (bla<0) + { + computedNormalB*=-1; + info->m_flags |= TRI_INFO_V0V1_SWAP_NORMALB; + } +#ifdef DEBUG_INTERNAL_EDGE + if ((computedNormalB-normalB).length()>0.0001) + { + printf("warning: normals not identical\n"); + } +#endif//DEBUG_INTERNAL_EDGE + + info->m_edgeV0V1Angle = -correctedAngle; + + if (isConvex) + info->m_flags |= TRI_INFO_V0V1_CONVEX; + break; + } + case 2: + { + btVector3 edge = m_triangleVerticesA[2]-m_triangleVerticesA[0]; + btQuaternion orn(edge,-correctedAngle); + btVector3 computedNormalB = quatRotate(orn,normalA); + if (computedNormalB.dot(normalB)<0) + { + computedNormalB*=-1; + info->m_flags |= TRI_INFO_V2V0_SWAP_NORMALB; + } + +#ifdef DEBUG_INTERNAL_EDGE + if ((computedNormalB-normalB).length()>0.0001) + { + printf("warning: normals not identical\n"); + } +#endif //DEBUG_INTERNAL_EDGE + info->m_edgeV2V0Angle = -correctedAngle; + if (isConvex) + info->m_flags |= TRI_INFO_V2V0_CONVEX; + break; + } + case 3: + { + btVector3 edge = m_triangleVerticesA[1]-m_triangleVerticesA[2]; + btQuaternion orn(edge,-correctedAngle); + btVector3 computedNormalB = quatRotate(orn,normalA); + if (computedNormalB.dot(normalB)<0) + { + info->m_flags |= TRI_INFO_V1V2_SWAP_NORMALB; + computedNormalB*=-1; + } +#ifdef DEBUG_INTERNAL_EDGE + if ((computedNormalB-normalB).length()>0.0001) + { + printf("warning: normals not identical\n"); + } +#endif //DEBUG_INTERNAL_EDGE + info->m_edgeV1V2Angle = -correctedAngle; + + if (isConvex) + info->m_flags |= TRI_INFO_V1V2_CONVEX; + break; + } + } + + break; + } + default: + { + // printf("warning: duplicate triangle\n"); + } + + } + } +}; +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// + +void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap) +{ + //the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there! + if (trimeshShape->getTriangleInfoMap()) + return; + + trimeshShape->setTriangleInfoMap(triangleInfoMap); + + btStridingMeshInterface* meshInterface = trimeshShape->getMeshInterface(); + const btVector3& meshScaling = meshInterface->getScaling(); + + for (int partId = 0; partId< meshInterface->getNumSubParts();partId++) + { + const unsigned char *vertexbase = 0; + int numverts = 0; + PHY_ScalarType type = PHY_INTEGER; + int stride = 0; + const unsigned char *indexbase = 0; + int indexstride = 0; + int numfaces = 0; + PHY_ScalarType indicestype = PHY_INTEGER; + //PHY_ScalarType indexType=0; + + btVector3 triangleVerts[3]; + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId); + btVector3 aabbMin,aabbMax; + + for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++) + { + unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride); + + for (int j=2;j>=0;j--) + { + + int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; + if (type == PHY_FLOAT) + { + float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + triangleVerts[j] = btVector3( + graphicsbase[0]*meshScaling.getX(), + graphicsbase[1]*meshScaling.getY(), + graphicsbase[2]*meshScaling.getZ()); + } + else + { + double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); + triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ())); + } + } + aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + aabbMin.setMin(triangleVerts[0]); + aabbMax.setMax(triangleVerts[0]); + aabbMin.setMin(triangleVerts[1]); + aabbMax.setMax(triangleVerts[1]); + aabbMin.setMin(triangleVerts[2]); + aabbMax.setMax(triangleVerts[2]); + + btConnectivityProcessor connectivityProcessor; + connectivityProcessor.m_partIdA = partId; + connectivityProcessor.m_triangleIndexA = triangleIndex; + connectivityProcessor.m_triangleVerticesA = &triangleVerts[0]; + connectivityProcessor.m_triangleInfoMap = triangleInfoMap; + + trimeshShape->processAllTriangles(&connectivityProcessor,aabbMin,aabbMax); + } + + } + +} + + + + +// Given a point and a line segment (defined by two points), compute the closest point +// in the line. Cap the point at the endpoints of the line segment. +void btNearestPointInLineSegment(const btVector3 &point, const btVector3& line0, const btVector3& line1, btVector3& nearestPoint) +{ + btVector3 lineDelta = line1 - line0; + + // Handle degenerate lines + if ( lineDelta.fuzzyZero()) + { + nearestPoint = line0; + } + else + { + btScalar delta = (point-line0).dot(lineDelta) / (lineDelta).dot(lineDelta); + + // Clamp the point to conform to the segment's endpoints + if ( delta < 0 ) + delta = 0; + else if ( delta > 1 ) + delta = 1; + + nearestPoint = line0 + lineDelta*delta; + } +} + + + + +bool btClampNormal(const btVector3& edge,const btVector3& tri_normal_org,const btVector3& localContactNormalOnB, btScalar correctedEdgeAngle, btVector3 & clampedLocalNormal) +{ + btVector3 tri_normal = tri_normal_org; + //we only have a local triangle normal, not a local contact normal -> only normal in world space... + //either compute the current angle all in local space, or all in world space + + btVector3 edgeCross = edge.cross(tri_normal).normalize(); + btScalar curAngle = btGetAngle(edgeCross,tri_normal,localContactNormalOnB); + + if (correctedEdgeAngle<0) + { + if (curAngle < correctedEdgeAngle) + { + btScalar diffAngle = correctedEdgeAngle-curAngle; + btQuaternion rotation(edge,diffAngle ); + clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB; + return true; + } + } + + if (correctedEdgeAngle>=0) + { + if (curAngle > correctedEdgeAngle) + { + btScalar diffAngle = correctedEdgeAngle-curAngle; + btQuaternion rotation(edge,diffAngle ); + clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB; + return true; + } + } + return false; +} + + + +/// Changes a btManifoldPoint collision normal to the normal from the mesh. +void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,const btCollisionObjectWrapper* colObj1Wrap, int partId0, int index0, int normalAdjustFlags) +{ + //btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE); + if (colObj0Wrap->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE) + return; + + btBvhTriangleMeshShape* trimesh = 0; + + if( colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE ) + trimesh = ((btScaledBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape())->getChildShape(); + else + trimesh = (btBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape(); + + btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap(); + if (!triangleInfoMapPtr) + return; + + int hash = btGetHash(partId0,index0); + + + btTriangleInfo* info = triangleInfoMapPtr->find(hash); + if (!info) + return; + + btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f; + + const btTriangleShape* tri_shape = static_cast(colObj0Wrap->getCollisionShape()); + btVector3 v0,v1,v2; + tri_shape->getVertex(0,v0); + tri_shape->getVertex(1,v1); + tri_shape->getVertex(2,v2); + + //btVector3 center = (v0+v1+v2)*btScalar(1./3.); + + btVector3 red(1,0,0), green(0,1,0),blue(0,0,1),white(1,1,1),black(0,0,0); + btVector3 tri_normal; + tri_shape->calcNormal(tri_normal); + + //btScalar dot = tri_normal.dot(cp.m_normalWorldOnB); + btVector3 nearest; + btNearestPointInLineSegment(cp.m_localPointB,v0,v1,nearest); + + btVector3 contact = cp.m_localPointB; +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + const btTransform& tr = colObj0->getWorldTransform(); + btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,red); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + + + bool isNearEdge = false; + + int numConcaveEdgeHits = 0; + int numConvexEdgeHits = 0; + + btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; + localContactNormalOnB.normalize();//is this necessary? + + // Get closest edge + int bestedge=-1; + btScalar disttobestedge=BT_LARGE_FLOAT; + // + // Edge 0 -> 1 + if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { + btVector3 nearest; + btNearestPointInLineSegment( cp.m_localPointB, v0, v1, nearest ); + btScalar len=(contact-nearest).length(); + // + if( len < disttobestedge ) + { + bestedge=0; + disttobestedge=len; + } + } + // Edge 1 -> 2 + if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { + btVector3 nearest; + btNearestPointInLineSegment( cp.m_localPointB, v1, v2, nearest ); + btScalar len=(contact-nearest).length(); + // + if( len < disttobestedge ) + { + bestedge=1; + disttobestedge=len; + } + } + // Edge 2 -> 0 + if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { + btVector3 nearest; + btNearestPointInLineSegment( cp.m_localPointB, v2, v0, nearest ); + btScalar len=(contact-nearest).length(); + // + if( len < disttobestedge ) + { + bestedge=2; + disttobestedge=len; + } + } + +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btVector3 upfix=tri_normal * btVector3(0.1f,0.1f,0.1f); + btDebugDrawLine(tr * v0 + upfix, tr * v1 + upfix, red ); +#endif + if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black); +#endif + btScalar len = (contact-nearest).length(); + if(lenm_edgeDistanceThreshold) + if( bestedge==0 ) + { + btVector3 edge(v0-v1); + isNearEdge = true; + + if (info->m_edgeV0V1Angle==btScalar(0)) + { + numConcaveEdgeHits++; + } else + { + + bool isEdgeConvex = (info->m_flags & TRI_INFO_V0V1_CONVEX); + btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); + #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white); + #endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btVector3 nA = swapFactor * tri_normal; + + btQuaternion orn(edge,info->m_edgeV0V1Angle); + btVector3 computedNormalB = quatRotate(orn,tri_normal); + if (info->m_flags & TRI_INFO_V0V1_SWAP_NORMALB) + computedNormalB*=-1; + btVector3 nB = swapFactor*computedNormalB; + + btScalar NdotA = localContactNormalOnB.dot(nA); + btScalar NdotB = localContactNormalOnB.dot(nB); + bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotBm_convexEpsilon); + +#ifdef DEBUG_INTERNAL_EDGE + { + + btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red); + } +#endif //DEBUG_INTERNAL_EDGE + + + if (backFacingNormal) + { + numConcaveEdgeHits++; + } + else + { + numConvexEdgeHits++; + btVector3 clampedLocalNormal; + bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal); + if (isClamped) + { + if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0)) + { + btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. (what about cp.m_distance1?) + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + + } + } + } + } + } + } + + btNearestPointInLineSegment(contact,v1,v2,nearest); +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,green); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * v1 + upfix, tr * v2 + upfix , green ); +#endif + + if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + + + btScalar len = (contact-nearest).length(); + if(lenm_edgeDistanceThreshold) + if( bestedge==1 ) + { + isNearEdge = true; +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btVector3 edge(v1-v2); + + isNearEdge = true; + + if (info->m_edgeV1V2Angle == btScalar(0)) + { + numConcaveEdgeHits++; + } else + { + bool isEdgeConvex = (info->m_flags & TRI_INFO_V1V2_CONVEX)!=0; + btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); + #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white); + #endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btVector3 nA = swapFactor * tri_normal; + + btQuaternion orn(edge,info->m_edgeV1V2Angle); + btVector3 computedNormalB = quatRotate(orn,tri_normal); + if (info->m_flags & TRI_INFO_V1V2_SWAP_NORMALB) + computedNormalB*=-1; + btVector3 nB = swapFactor*computedNormalB; + +#ifdef DEBUG_INTERNAL_EDGE + { + btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red); + } +#endif //DEBUG_INTERNAL_EDGE + + + btScalar NdotA = localContactNormalOnB.dot(nA); + btScalar NdotB = localContactNormalOnB.dot(nB); + bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotBm_convexEpsilon); + + if (backFacingNormal) + { + numConcaveEdgeHits++; + } + else + { + numConvexEdgeHits++; + btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; + btVector3 clampedLocalNormal; + bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal); + if (isClamped) + { + if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0)) + { + btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + } + } + } + } + } + } + + btNearestPointInLineSegment(contact,v2,v0,nearest); +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,blue); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * v2 + upfix, tr * v0 + upfix , blue ); +#endif + + if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { + +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btScalar len = (contact-nearest).length(); + if(lenm_edgeDistanceThreshold) + if( bestedge==2 ) + { + isNearEdge = true; +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btVector3 edge(v2-v0); + + if (info->m_edgeV2V0Angle==btScalar(0)) + { + numConcaveEdgeHits++; + } else + { + + bool isEdgeConvex = (info->m_flags & TRI_INFO_V2V0_CONVEX)!=0; + btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); + #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white); + #endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btVector3 nA = swapFactor * tri_normal; + btQuaternion orn(edge,info->m_edgeV2V0Angle); + btVector3 computedNormalB = quatRotate(orn,tri_normal); + if (info->m_flags & TRI_INFO_V2V0_SWAP_NORMALB) + computedNormalB*=-1; + btVector3 nB = swapFactor*computedNormalB; + +#ifdef DEBUG_INTERNAL_EDGE + { + btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red); + } +#endif //DEBUG_INTERNAL_EDGE + + btScalar NdotA = localContactNormalOnB.dot(nA); + btScalar NdotB = localContactNormalOnB.dot(nB); + bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotBm_convexEpsilon); + + if (backFacingNormal) + { + numConcaveEdgeHits++; + } + else + { + numConvexEdgeHits++; + // printf("hitting convex edge\n"); + + + btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; + btVector3 clampedLocalNormal; + bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal); + if (isClamped) + { + if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0)) + { + btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + } + } + } + } + + + } + } + +#ifdef DEBUG_INTERNAL_EDGE + { + btVector3 color(0,1,1); + btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+cp.m_normalWorldOnB*10,color); + } +#endif //DEBUG_INTERNAL_EDGE + + if (isNearEdge) + { + + if (numConcaveEdgeHits>0) + { + if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_DOUBLE_SIDED)!=0) + { + //fix tri_normal so it pointing the same direction as the current local contact normal + if (tri_normal.dot(localContactNormalOnB) < 0) + { + tri_normal *= -1; + } + cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis()*tri_normal; + } else + { + btVector3 newNormal = tri_normal *frontFacing; + //if the tri_normal is pointing opposite direction as the current local contact normal, skip it + btScalar d = newNormal.dot(localContactNormalOnB) ; + if (d< 0) + { + return; + } + //modify the normal to be the triangle normal (or backfacing normal) + cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() *newNormal; + } + + // Reproject collision point along normal. + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + } + } +} diff --git a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h new file mode 100644 index 0000000..7d9aafe --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h @@ -0,0 +1,47 @@ + +#ifndef BT_INTERNAL_EDGE_UTILITY_H +#define BT_INTERNAL_EDGE_UTILITY_H + +#include "LinearMath/btHashMap.h" +#include "LinearMath/btVector3.h" + +#include "BulletCollision/CollisionShapes/btTriangleInfoMap.h" + +///The btInternalEdgeUtility helps to avoid or reduce artifacts due to wrong collision normals caused by internal edges. +///See also http://code.google.com/p/bullet/issues/detail?id=27 + +class btBvhTriangleMeshShape; +class btCollisionObject; +struct btCollisionObjectWrapper; +class btManifoldPoint; +class btIDebugDraw; + + + +enum btInternalEdgeAdjustFlags +{ + BT_TRIANGLE_CONVEX_BACKFACE_MODE = 1, + BT_TRIANGLE_CONCAVE_DOUBLE_SIDED = 2, //double sided options are experimental, single sided is recommended + BT_TRIANGLE_CONVEX_DOUBLE_SIDED = 4 +}; + + +///Call btGenerateInternalEdgeInfo to create triangle info, store in the shape 'userInfo' +void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap); + + +///Call the btFixMeshNormal to adjust the collision normal, using the triangle info map (generated using btGenerateInternalEdgeInfo) +///If this info map is missing, or the triangle is not store in this map, nothing will be done +void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* trimeshColObj0Wrap,const btCollisionObjectWrapper* otherColObj1Wrap, int partId0, int index0, int normalAdjustFlags = 0); + +///Enable the BT_INTERNAL_EDGE_DEBUG_DRAW define and call btSetDebugDrawer, to get visual info to see if the internal edge utility works properly. +///If the utility doesn't work properly, you might have to adjust the threshold values in btTriangleInfoMap +//#define BT_INTERNAL_EDGE_DEBUG_DRAW + +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW +void btSetDebugDrawer(btIDebugDraw* debugDrawer); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + +#endif //BT_INTERNAL_EDGE_UTILITY_H + diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp new file mode 100644 index 0000000..4b2986a --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp @@ -0,0 +1,154 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btManifoldResult.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +///This is to allow MaterialCombiner/Custom Friction/Restitution values +ContactAddedCallback gContactAddedCallback=0; + + + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1) +{ + btScalar friction = body0->getRollingFriction() * body1->getRollingFriction(); + + const btScalar MAX_FRICTION = btScalar(10.); + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +btScalar btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1) +{ + btScalar friction = body0->getFriction() * body1->getFriction(); + + const btScalar MAX_FRICTION = btScalar(10.); + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1) +{ + return body0->getRestitution() * body1->getRestitution(); +} + + + +btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + :m_manifoldPtr(0), + m_body0Wrap(body0Wrap), + m_body1Wrap(body1Wrap) +#ifdef DEBUG_PART_INDEX + ,m_partId0(-1), + m_partId1(-1), + m_index0(-1), + m_index1(-1) +#endif //DEBUG_PART_INDEX +{ +} + + +void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) +{ + btAssert(m_manifoldPtr); + //order in manifold needs to match + + if (depth > m_manifoldPtr->getContactBreakingThreshold()) +// if (depth > m_manifoldPtr->getContactProcessingThreshold()) + return; + + bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); + + btVector3 pointA = pointInWorld + normalOnBInWorld * depth; + + btVector3 localA; + btVector3 localB; + + if (isSwapped) + { + localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); + } else + { + localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); + } + + btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); + newPt.m_positionWorldOnA = pointA; + newPt.m_positionWorldOnB = pointInWorld; + + int insertIndex = m_manifoldPtr->getCacheEntry(newPt); + + newPt.m_combinedFriction = calculateCombinedFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); + newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); + newPt.m_combinedRollingFriction = calculateCombinedRollingFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); + btPlaneSpace1(newPt.m_normalWorldOnB,newPt.m_lateralFrictionDir1,newPt.m_lateralFrictionDir2); + + + + //BP mod, store contact triangles. + if (isSwapped) + { + newPt.m_partId0 = m_partId1; + newPt.m_partId1 = m_partId0; + newPt.m_index0 = m_index1; + newPt.m_index1 = m_index0; + } else + { + newPt.m_partId0 = m_partId0; + newPt.m_partId1 = m_partId1; + newPt.m_index0 = m_index0; + newPt.m_index1 = m_index1; + } + //printf("depth=%f\n",depth); + ///@todo, check this for any side effects + if (insertIndex >= 0) + { + //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); + m_manifoldPtr->replaceContactPoint(newPt,insertIndex); + } else + { + insertIndex = m_manifoldPtr->addManifoldPoint(newPt); + } + + //User can override friction and/or restitution + if (gContactAddedCallback && + //and if either of the two bodies requires custom material + ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) || + (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))) + { + //experimental feature info, for per-triangle material etc. + const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap; + const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap; + (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1); + } + +} + diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/src/BulletCollision/CollisionDispatch/btManifoldResult.h new file mode 100644 index 0000000..977b9a0 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.h @@ -0,0 +1,150 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_MANIFOLD_RESULT_H +#define BT_MANIFOLD_RESULT_H + +class btCollisionObject; +struct btCollisionObjectWrapper; + +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +class btManifoldPoint; + +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" + +#include "LinearMath/btTransform.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" + +typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1); +extern ContactAddedCallback gContactAddedCallback; + +//#define DEBUG_PART_INDEX 1 + + +///btManifoldResult is a helper class to manage contact results. +class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result +{ +protected: + + btPersistentManifold* m_manifoldPtr; + + const btCollisionObjectWrapper* m_body0Wrap; + const btCollisionObjectWrapper* m_body1Wrap; + int m_partId0; + int m_partId1; + int m_index0; + int m_index1; + + +public: + + btManifoldResult() +#ifdef DEBUG_PART_INDEX + : + m_partId0(-1), + m_partId1(-1), + m_index0(-1), + m_index1(-1) +#endif //DEBUG_PART_INDEX + { + } + + btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + + virtual ~btManifoldResult() {}; + + void setPersistentManifold(btPersistentManifold* manifoldPtr) + { + m_manifoldPtr = manifoldPtr; + } + + const btPersistentManifold* getPersistentManifold() const + { + return m_manifoldPtr; + } + btPersistentManifold* getPersistentManifold() + { + return m_manifoldPtr; + } + + virtual void setShapeIdentifiersA(int partId0,int index0) + { + m_partId0=partId0; + m_index0=index0; + } + + virtual void setShapeIdentifiersB( int partId1,int index1) + { + m_partId1=partId1; + m_index1=index1; + } + + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth); + + SIMD_FORCE_INLINE void refreshContactPoints() + { + btAssert(m_manifoldPtr); + if (!m_manifoldPtr->getNumContacts()) + return; + + bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); + + if (isSwapped) + { + m_manifoldPtr->refreshContactPoints(m_body1Wrap->getCollisionObject()->getWorldTransform(),m_body0Wrap->getCollisionObject()->getWorldTransform()); + } else + { + m_manifoldPtr->refreshContactPoints(m_body0Wrap->getCollisionObject()->getWorldTransform(),m_body1Wrap->getCollisionObject()->getWorldTransform()); + } + } + + const btCollisionObjectWrapper* getBody0Wrap() const + { + return m_body0Wrap; + } + const btCollisionObjectWrapper* getBody1Wrap() const + { + return m_body1Wrap; + } + + void setBody0Wrap(const btCollisionObjectWrapper* obj0Wrap) + { + m_body0Wrap = obj0Wrap; + } + + void setBody1Wrap(const btCollisionObjectWrapper* obj1Wrap) + { + m_body1Wrap = obj1Wrap; + } + + const btCollisionObject* getBody0Internal() const + { + return m_body0Wrap->getCollisionObject(); + } + + const btCollisionObject* getBody1Internal() const + { + return m_body1Wrap->getCollisionObject(); + } + + /// in the future we can let the user override the methods to combine restitution and friction + static btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1); + static btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1); +}; + +#endif //BT_MANIFOLD_RESULT_H diff --git a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp new file mode 100644 index 0000000..1344782 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp @@ -0,0 +1,450 @@ + +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "LinearMath/btScalar.h" +#include "btSimulationIslandManager.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" + +//#include +#include "LinearMath/btQuickprof.h" + +btSimulationIslandManager::btSimulationIslandManager(): +m_splitIslands(true) +{ +} + +btSimulationIslandManager::~btSimulationIslandManager() +{ +} + + +void btSimulationIslandManager::initUnionFind(int n) +{ + m_unionFind.reset(n); +} + + +void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btCollisionWorld* colWorld) +{ + + { + btOverlappingPairCache* pairCachePtr = colWorld->getPairCache(); + const int numOverlappingPairs = pairCachePtr->getNumOverlappingPairs(); + if (numOverlappingPairs) + { + btBroadphasePair* pairPtr = pairCachePtr->getOverlappingPairArrayPtr(); + + for (int i=0;im_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + + if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && + ((colObj1) && ((colObj1)->mergesSimulationIslands()))) + { + + m_unionFind.unite((colObj0)->getIslandTag(), + (colObj1)->getIslandTag()); + } + } + } + } +} + +#ifdef STATIC_SIMULATION_ISLAND_OPTIMIZATION +void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher) +{ + + // put the index into m_controllers into m_tag + int index = 0; + { + + int i; + for (i=0;igetCollisionObjectArray().size(); i++) + { + btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + //Adding filtering here + if (!collisionObject->isStaticOrKinematicObject()) + { + collisionObject->setIslandTag(index++); + } + collisionObject->setCompanionId(-1); + collisionObject->setHitFraction(btScalar(1.)); + } + } + // do the union find + + initUnionFind( index ); + + findUnions(dispatcher,colWorld); +} + +void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) +{ + // put the islandId ('find' value) into m_tag + { + int index = 0; + int i; + for (i=0;igetCollisionObjectArray().size();i++) + { + btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + if (!collisionObject->isStaticOrKinematicObject()) + { + collisionObject->setIslandTag( m_unionFind.find(index) ); + //Set the correct object offset in Collision Object Array + m_unionFind.getElement(index).m_sz = i; + collisionObject->setCompanionId(-1); + index++; + } else + { + collisionObject->setIslandTag(-1); + collisionObject->setCompanionId(-2); + } + } + } +} + + +#else //STATIC_SIMULATION_ISLAND_OPTIMIZATION +void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher) +{ + + initUnionFind( int (colWorld->getCollisionObjectArray().size())); + + // put the index into m_controllers into m_tag + { + + int index = 0; + int i; + for (i=0;igetCollisionObjectArray().size(); i++) + { + btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + collisionObject->setIslandTag(index); + collisionObject->setCompanionId(-1); + collisionObject->setHitFraction(btScalar(1.)); + index++; + + } + } + // do the union find + + findUnions(dispatcher,colWorld); +} + +void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) +{ + // put the islandId ('find' value) into m_tag + { + + + int index = 0; + int i; + for (i=0;igetCollisionObjectArray().size();i++) + { + btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + if (!collisionObject->isStaticOrKinematicObject()) + { + collisionObject->setIslandTag( m_unionFind.find(index) ); + collisionObject->setCompanionId(-1); + } else + { + collisionObject->setIslandTag(-1); + collisionObject->setCompanionId(-2); + } + index++; + } + } +} + +#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION + +inline int getIslandId(const btPersistentManifold* lhs) +{ + int islandId; + const btCollisionObject* rcolObj0 = static_cast(lhs->getBody0()); + const btCollisionObject* rcolObj1 = static_cast(lhs->getBody1()); + islandId= rcolObj0->getIslandTag()>=0?rcolObj0->getIslandTag():rcolObj1->getIslandTag(); + return islandId; + +} + + + +/// function object that routes calls to operator< +class btPersistentManifoldSortPredicate +{ + public: + + SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs ) const + { + return getIslandId(lhs) < getIslandId(rhs); + } +}; + + +void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld) +{ + + BT_PROFILE("islandUnionFindAndQuickSort"); + + btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); + + m_islandmanifold.resize(0); + + //we are going to sort the unionfind array, and store the element id in the size + //afterwards, we clean unionfind, to make sure no-one uses it anymore + + getUnionFind().sortIslands(); + int numElem = getUnionFind().getNumElements(); + + int endIslandIndex=1; + int startIslandIndex; + + + //update the sleeping state for bodies, if all are sleeping + for ( startIslandIndex=0;startIslandIndexgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) + { +// printf("error in island management\n"); + } + + btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + if (colObj0->getIslandTag() == islandId) + { + if (colObj0->getActivationState()== ACTIVE_TAG) + { + allSleeping = false; + } + if (colObj0->getActivationState()== DISABLE_DEACTIVATION) + { + allSleeping = false; + } + } + } + + + if (allSleeping) + { + int idx; + for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) + { +// printf("error in island management\n"); + } + + btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + + if (colObj0->getIslandTag() == islandId) + { + colObj0->setActivationState( ISLAND_SLEEPING ); + } + } + } else + { + + int idx; + for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) + { +// printf("error in island management\n"); + } + + btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + + if (colObj0->getIslandTag() == islandId) + { + if ( colObj0->getActivationState() == ISLAND_SLEEPING) + { + colObj0->setActivationState( WANTS_DEACTIVATION); + colObj0->setDeactivationTime(0.f); + } + } + } + } + } + + + int i; + int maxNumManifolds = dispatcher->getNumManifolds(); + +//#define SPLIT_ISLANDS 1 +//#ifdef SPLIT_ISLANDS + + +//#endif //SPLIT_ISLANDS + + + for (i=0;igetManifoldByIndexInternal(i); + + const btCollisionObject* colObj0 = static_cast(manifold->getBody0()); + const btCollisionObject* colObj1 = static_cast(manifold->getBody1()); + + ///@todo: check sleeping conditions! + if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || + ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING)) + { + + //kinematic objects don't merge islands, but wake up all connected objects + if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) + { + if (colObj0->hasContactResponse()) + colObj1->activate(); + } + if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) + { + if (colObj1->hasContactResponse()) + colObj0->activate(); + } + if(m_splitIslands) + { + //filtering for response + if (dispatcher->needsResponse(colObj0,colObj1)) + m_islandmanifold.push_back(manifold); + } + } + } +} + + + +///@todo: this is random access, it can be walked 'cache friendly'! +void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback) +{ + btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); + + buildIslands(dispatcher,collisionWorld); + + int endIslandIndex=1; + int startIslandIndex; + int numElem = getUnionFind().getNumElements(); + + BT_PROFILE("processIslands"); + + if(!m_splitIslands) + { + btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer(); + int maxNumManifolds = dispatcher->getNumManifolds(); + callback->processIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1); + } + else + { + // Sort manifolds, based on islands + // Sort the vector using predicate and std::sort + //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate); + + int numManifolds = int (m_islandmanifold.size()); + + //tried a radix sort, but quicksort/heapsort seems still faster + //@todo rewrite island management + m_islandmanifold.quickSort(btPersistentManifoldSortPredicate()); + //m_islandmanifold.heapSort(btPersistentManifoldSortPredicate()); + + //now process all active islands (sets of manifolds for now) + + int startManifoldIndex = 0; + int endManifoldIndex = 1; + + //int islandId; + + + + // printf("Start Islands\n"); + + //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated + for ( startIslandIndex=0;startIslandIndexisActive()) + islandSleeping = false; + } + + + //find the accompanying contact manifold for this islandId + int numIslandManifolds = 0; + btPersistentManifold** startManifold = 0; + + if (startManifoldIndexprocessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId); + // printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds); + } + + if (numIslandManifolds) + { + startManifoldIndex = endManifoldIndex; + } + + m_islandBodies.resize(0); + } + } // else if(!splitIslands) + +} diff --git a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h new file mode 100644 index 0000000..e24c6af --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h @@ -0,0 +1,81 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SIMULATION_ISLAND_MANAGER_H +#define BT_SIMULATION_ISLAND_MANAGER_H + +#include "BulletCollision/CollisionDispatch/btUnionFind.h" +#include "btCollisionCreateFunc.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "btCollisionObject.h" + +class btCollisionObject; +class btCollisionWorld; +class btDispatcher; +class btPersistentManifold; + + +///SimulationIslandManager creates and handles simulation islands, using btUnionFind +class btSimulationIslandManager +{ + btUnionFind m_unionFind; + + btAlignedObjectArray m_islandmanifold; + btAlignedObjectArray m_islandBodies; + + bool m_splitIslands; + +public: + btSimulationIslandManager(); + virtual ~btSimulationIslandManager(); + + + void initUnionFind(int n); + + + btUnionFind& getUnionFind() { return m_unionFind;} + + virtual void updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher); + virtual void storeIslandActivationState(btCollisionWorld* world); + + + void findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld); + + + + struct IslandCallback + { + virtual ~IslandCallback() {}; + + virtual void processIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0; + }; + + void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback); + + void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld); + + bool getSplitIslands() + { + return m_splitIslands; + } + void setSplitIslands(bool doSplitIslands) + { + m_splitIslands = doSplitIslands; + } + +}; + +#endif //BT_SIMULATION_ISLAND_MANAGER_H + diff --git a/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp new file mode 100644 index 0000000..e8b567e --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp @@ -0,0 +1,214 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSphereBoxCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" +//#include + +btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped) +: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap), +m_ownManifold(false), +m_manifoldPtr(mf), +m_isSwapped(isSwapped) +{ + const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? col1Wrap : col0Wrap; + const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? col0Wrap : col1Wrap; + + if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject())) + { + m_manifoldPtr = m_dispatcher->getNewManifold(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject()); + m_ownManifold = true; + } +} + + +btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + + + +void btSphereBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) +{ + (void)dispatchInfo; + (void)resultOut; + if (!m_manifoldPtr) + return; + + const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? body0Wrap : body1Wrap; + + btVector3 pOnBox; + + btVector3 normalOnSurfaceB; + btScalar penetrationDepth; + btVector3 sphereCenter = sphereObjWrap->getWorldTransform().getOrigin(); + const btSphereShape* sphere0 = (const btSphereShape*)sphereObjWrap->getCollisionShape(); + btScalar radius = sphere0->getRadius(); + btScalar maxContactDistance = m_manifoldPtr->getContactBreakingThreshold(); + + resultOut->setPersistentManifold(m_manifoldPtr); + + if (getSphereDistance(boxObjWrap, pOnBox, normalOnSurfaceB, penetrationDepth, sphereCenter, radius, maxContactDistance)) + { + /// report a contact. internally this will be kept persistent, and contact reduction is done + resultOut->addContactPoint(normalOnSurfaceB, pOnBox, penetrationDepth); + } + + if (m_ownManifold) + { + if (m_manifoldPtr->getNumContacts()) + { + resultOut->refreshContactPoints(); + } + } + +} + +btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + (void)col0; + (void)col1; + + //not yet + return btScalar(1.); +} + + +bool btSphereBoxCollisionAlgorithm::getSphereDistance(const btCollisionObjectWrapper* boxObjWrap, btVector3& pointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& sphereCenter, btScalar fRadius, btScalar maxContactDistance ) +{ + const btBoxShape* boxShape= (const btBoxShape*)boxObjWrap->getCollisionShape(); + btVector3 const &boxHalfExtent = boxShape->getHalfExtentsWithoutMargin(); + btScalar boxMargin = boxShape->getMargin(); + penetrationDepth = 1.0f; + + // convert the sphere position to the box's local space + btTransform const &m44T = boxObjWrap->getWorldTransform(); + btVector3 sphereRelPos = m44T.invXform(sphereCenter); + + // Determine the closest point to the sphere center in the box + btVector3 closestPoint = sphereRelPos; + closestPoint.setX( btMin(boxHalfExtent.getX(), closestPoint.getX()) ); + closestPoint.setX( btMax(-boxHalfExtent.getX(), closestPoint.getX()) ); + closestPoint.setY( btMin(boxHalfExtent.getY(), closestPoint.getY()) ); + closestPoint.setY( btMax(-boxHalfExtent.getY(), closestPoint.getY()) ); + closestPoint.setZ( btMin(boxHalfExtent.getZ(), closestPoint.getZ()) ); + closestPoint.setZ( btMax(-boxHalfExtent.getZ(), closestPoint.getZ()) ); + + btScalar intersectionDist = fRadius + boxMargin; + btScalar contactDist = intersectionDist + maxContactDistance; + normal = sphereRelPos - closestPoint; + + //if there is no penetration, we are done + btScalar dist2 = normal.length2(); + if (dist2 > contactDist * contactDist) + { + return false; + } + + btScalar distance; + + //special case if the sphere center is inside the box + if (dist2 <= SIMD_EPSILON) + { + distance = -getSpherePenetration(boxHalfExtent, sphereRelPos, closestPoint, normal); + } + else //compute the penetration details + { + distance = normal.length(); + normal /= distance; + } + + pointOnBox = closestPoint + normal * boxMargin; +// v3PointOnSphere = sphereRelPos - (normal * fRadius); + penetrationDepth = distance - intersectionDist; + + // transform back in world space + btVector3 tmp = m44T(pointOnBox); + pointOnBox = tmp; +// tmp = m44T(v3PointOnSphere); +// v3PointOnSphere = tmp; + tmp = m44T.getBasis() * normal; + normal = tmp; + + return true; +} + +btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal ) +{ + //project the center of the sphere on the closest face of the box + btScalar faceDist = boxHalfExtent.getX() - sphereRelPos.getX(); + btScalar minDist = faceDist; + closestPoint.setX( boxHalfExtent.getX() ); + normal.setValue(btScalar(1.0f), btScalar(0.0f), btScalar(0.0f)); + + faceDist = boxHalfExtent.getX() + sphereRelPos.getX(); + if (faceDist < minDist) + { + minDist = faceDist; + closestPoint = sphereRelPos; + closestPoint.setX( -boxHalfExtent.getX() ); + normal.setValue(btScalar(-1.0f), btScalar(0.0f), btScalar(0.0f)); + } + + faceDist = boxHalfExtent.getY() - sphereRelPos.getY(); + if (faceDist < minDist) + { + minDist = faceDist; + closestPoint = sphereRelPos; + closestPoint.setY( boxHalfExtent.getY() ); + normal.setValue(btScalar(0.0f), btScalar(1.0f), btScalar(0.0f)); + } + + faceDist = boxHalfExtent.getY() + sphereRelPos.getY(); + if (faceDist < minDist) + { + minDist = faceDist; + closestPoint = sphereRelPos; + closestPoint.setY( -boxHalfExtent.getY() ); + normal.setValue(btScalar(0.0f), btScalar(-1.0f), btScalar(0.0f)); + } + + faceDist = boxHalfExtent.getZ() - sphereRelPos.getZ(); + if (faceDist < minDist) + { + minDist = faceDist; + closestPoint = sphereRelPos; + closestPoint.setZ( boxHalfExtent.getZ() ); + normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(1.0f)); + } + + faceDist = boxHalfExtent.getZ() + sphereRelPos.getZ(); + if (faceDist < minDist) + { + minDist = faceDist; + closestPoint = sphereRelPos; + closestPoint.setZ( -boxHalfExtent.getZ() ); + normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(-1.0f)); + } + + return minDist; +} diff --git a/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h new file mode 100644 index 0000000..eefaedc --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h @@ -0,0 +1,75 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPHERE_BOX_COLLISION_ALGORITHM_H +#define BT_SPHERE_BOX_COLLISION_ALGORITHM_H + +#include "btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +class btPersistentManifold; +#include "btCollisionDispatcher.h" + +#include "LinearMath/btVector3.h" + +/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection. +/// Other features are frame-coherency (persistent data) and collision response. +class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_isSwapped; + +public: + + btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, bool isSwapped); + + virtual ~btSphereBoxCollisionAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr && m_ownManifold) + { + manifoldArray.push_back(m_manifoldPtr); + } + } + + bool getSphereDistance( const btCollisionObjectWrapper* boxObjWrap, btVector3& v3PointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& v3SphereCenter, btScalar fRadius, btScalar maxContactDistance ); + + btScalar getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal ); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm)); + if (!m_swapped) + { + return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false); + } else + { + return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true); + } + } + }; + +}; + +#endif //BT_SPHERE_BOX_COLLISION_ALGORITHM_H + diff --git a/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp new file mode 100644 index 0000000..36ba21f --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp @@ -0,0 +1,106 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSphereSphereCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap) +: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap), +m_ownManifold(false), +m_manifoldPtr(mf) +{ + if (!m_manifoldPtr) + { + m_manifoldPtr = m_dispatcher->getNewManifold(col0Wrap->getCollisionObject(),col1Wrap->getCollisionObject()); + m_ownManifold = true; + } +} + +btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btSphereSphereCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)dispatchInfo; + + if (!m_manifoldPtr) + return; + + resultOut->setPersistentManifold(m_manifoldPtr); + + btSphereShape* sphere0 = (btSphereShape*)col0Wrap->getCollisionShape(); + btSphereShape* sphere1 = (btSphereShape*)col1Wrap->getCollisionShape(); + + btVector3 diff = col0Wrap->getWorldTransform().getOrigin()- col1Wrap->getWorldTransform().getOrigin(); + btScalar len = diff.length(); + btScalar radius0 = sphere0->getRadius(); + btScalar radius1 = sphere1->getRadius(); + +#ifdef CLEAR_MANIFOLD + m_manifoldPtr->clearManifold(); //don't do this, it disables warmstarting +#endif + + ///iff distance positive, don't generate a new contact + if ( len > (radius0+radius1)) + { +#ifndef CLEAR_MANIFOLD + resultOut->refreshContactPoints(); +#endif //CLEAR_MANIFOLD + return; + } + ///distance (negative means penetration) + btScalar dist = len - (radius0+radius1); + + btVector3 normalOnSurfaceB(1,0,0); + if (len > SIMD_EPSILON) + { + normalOnSurfaceB = diff / len; + } + + ///point on A (worldspace) + ///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB; + ///point on B (worldspace) + btVector3 pos1 = col1Wrap->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB; + + /// report a contact. internally this will be kept persistent, and contact reduction is done + + + resultOut->addContactPoint(normalOnSurfaceB,pos1,dist); + +#ifndef CLEAR_MANIFOLD + resultOut->refreshContactPoints(); +#endif //CLEAR_MANIFOLD + +} + +btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)col0; + (void)col1; + (void)dispatchInfo; + (void)resultOut; + + //not yet + return btScalar(1.); +} diff --git a/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h new file mode 100644 index 0000000..3517a56 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h @@ -0,0 +1,66 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H +#define BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H + +#include "btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +#include "btCollisionDispatcher.h" + +class btPersistentManifold; + +/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. +/// Other features are frame-coherency (persistent data) and collision response. +/// Also provides the most basic sample for custom/user btCollisionAlgorithm +class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + +public: + btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap); + + btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btActivatingCollisionAlgorithm(ci) {} + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr && m_ownManifold) + { + manifoldArray.push_back(m_manifoldPtr); + } + } + + virtual ~btSphereSphereCollisionAlgorithm(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm)); + return new(mem) btSphereSphereCollisionAlgorithm(0,ci,col0Wrap,col1Wrap); + } + }; + +}; + +#endif //BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H + diff --git a/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp new file mode 100644 index 0000000..280a4d3 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp @@ -0,0 +1,84 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btSphereTriangleCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "SphereTriangleDetector.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped) +: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), +m_ownManifold(false), +m_manifoldPtr(mf), +m_swapped(swapped) +{ + if (!m_manifoldPtr) + { + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_ownManifold = true; + } +} + +btSphereTriangleCollisionAlgorithm::~btSphereTriangleCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btSphereTriangleCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + if (!m_manifoldPtr) + return; + + const btCollisionObjectWrapper* sphereObjWrap = m_swapped? col1Wrap : col0Wrap; + const btCollisionObjectWrapper* triObjWrap = m_swapped? col0Wrap : col1Wrap; + + btSphereShape* sphere = (btSphereShape*)sphereObjWrap->getCollisionShape(); + btTriangleShape* triangle = (btTriangleShape*)triObjWrap->getCollisionShape(); + + /// report a contact. internally this will be kept persistent, and contact reduction is done + resultOut->setPersistentManifold(m_manifoldPtr); + SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold()); + + btDiscreteCollisionDetectorInterface::ClosestPointInput input; + input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);///@todo: tighter bounds + input.m_transformA = sphereObjWrap->getWorldTransform(); + input.m_transformB = triObjWrap->getWorldTransform(); + + bool swapResults = m_swapped; + + detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw,swapResults); + + if (m_ownManifold) + resultOut->refreshContactPoints(); + +} + +btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + (void)col0; + (void)col1; + + //not yet + return btScalar(1.); +} diff --git a/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h new file mode 100644 index 0000000..6b6e39a --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h @@ -0,0 +1,69 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H +#define BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H + +#include "btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +class btPersistentManifold; +#include "btCollisionDispatcher.h" + +/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. +/// Other features are frame-coherency (persistent data) and collision response. +/// Also provides the most basic sample for custom/user btCollisionAlgorithm +class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_swapped; + +public: + btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped); + + btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btActivatingCollisionAlgorithm(ci) {} + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr && m_ownManifold) + { + manifoldArray.push_back(m_manifoldPtr); + } + } + + virtual ~btSphereTriangleCollisionAlgorithm(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm)); + + return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_swapped); + } + }; + +}; + +#endif //BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H + diff --git a/src/BulletCollision/CollisionDispatch/btUnionFind.cpp b/src/BulletCollision/CollisionDispatch/btUnionFind.cpp new file mode 100644 index 0000000..5222933 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btUnionFind.cpp @@ -0,0 +1,82 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btUnionFind.h" + + + +btUnionFind::~btUnionFind() +{ + Free(); + +} + +btUnionFind::btUnionFind() +{ + +} + +void btUnionFind::allocate(int N) +{ + m_elements.resize(N); +} +void btUnionFind::Free() +{ + m_elements.clear(); +} + + +void btUnionFind::reset(int N) +{ + allocate(N); + + for (int i = 0; i < N; i++) + { + m_elements[i].m_id = i; m_elements[i].m_sz = 1; + } +} + + +class btUnionFindElementSortPredicate +{ + public: + + bool operator() ( const btElement& lhs, const btElement& rhs ) const + { + return lhs.m_id < rhs.m_id; + } +}; + +///this is a special operation, destroying the content of btUnionFind. +///it sorts the elements, based on island id, in order to make it easy to iterate over islands +void btUnionFind::sortIslands() +{ + + //first store the original body index, and islandId + int numElements = m_elements.size(); + + for (int i=0;i m_elements; + + public: + + btUnionFind(); + ~btUnionFind(); + + + //this is a special operation, destroying the content of btUnionFind. + //it sorts the elements, based on island id, in order to make it easy to iterate over islands + void sortIslands(); + + void reset(int N); + + SIMD_FORCE_INLINE int getNumElements() const + { + return int(m_elements.size()); + } + SIMD_FORCE_INLINE bool isRoot(int x) const + { + return (x == m_elements[x].m_id); + } + + btElement& getElement(int index) + { + return m_elements[index]; + } + const btElement& getElement(int index) const + { + return m_elements[index]; + } + + void allocate(int N); + void Free(); + + + + + int find(int p, int q) + { + return (find(p) == find(q)); + } + + void unite(int p, int q) + { + int i = find(p), j = find(q); + if (i == j) + return; + +#ifndef USE_PATH_COMPRESSION + //weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) ) + if (m_elements[i].m_sz < m_elements[j].m_sz) + { + m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; + } + else + { + m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz; + } +#else + m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; +#endif //USE_PATH_COMPRESSION + } + + int find(int x) + { + //btAssert(x < m_N); + //btAssert(x >= 0); + + while (x != m_elements[x].m_id) + { + //not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically + + #ifdef USE_PATH_COMPRESSION + const btElement* elementPtr = &m_elements[m_elements[x].m_id]; + m_elements[x].m_id = elementPtr->m_id; + x = elementPtr->m_id; + #else// + x = m_elements[x].m_id; + #endif + //btAssert(x < m_N); + //btAssert(x >= 0); + + } + return x; + } + + + }; + + +#endif //BT_UNION_FIND_H diff --git a/src/BulletCollision/CollisionShapes/btBox2dShape.cpp b/src/BulletCollision/CollisionShapes/btBox2dShape.cpp new file mode 100644 index 0000000..ecce028 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btBox2dShape.cpp @@ -0,0 +1,42 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBox2dShape.h" + + +//{ + + +void btBox2dShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax); +} + + +void btBox2dShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + //btScalar margin = btScalar(0.); + btVector3 halfExtents = getHalfExtentsWithMargin(); + + btScalar lx=btScalar(2.)*(halfExtents.x()); + btScalar ly=btScalar(2.)*(halfExtents.y()); + btScalar lz=btScalar(2.)*(halfExtents.z()); + + inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + ly*ly)); + +} + diff --git a/src/BulletCollision/CollisionShapes/btBox2dShape.h b/src/BulletCollision/CollisionShapes/btBox2dShape.h new file mode 100644 index 0000000..ce33378 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btBox2dShape.h @@ -0,0 +1,371 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_OBB_BOX_2D_SHAPE_H +#define BT_OBB_BOX_2D_SHAPE_H + +#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btMinMax.h" + +///The btBox2dShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space. +ATTRIBUTE_ALIGNED16(class) btBox2dShape: public btPolyhedralConvexShape +{ + + //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead + + btVector3 m_centroid; + btVector3 m_vertices[4]; + btVector3 m_normals[4]; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btVector3 getHalfExtentsWithMargin() const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents += margin; + return halfExtents; + } + + const btVector3& getHalfExtentsWithoutMargin() const + { + return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included + } + + + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents += margin; + + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + } + + SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + { + const btVector3& halfExtents = getHalfExtentsWithoutMargin(); + + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + } + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + { + const btVector3& halfExtents = getHalfExtentsWithoutMargin(); + + for (int i=0;iboxHalfExtents.getY()) + minDimension = boxHalfExtents.getY(); + setSafeMargin(minDimension); + + m_shapeType = BOX_2D_SHAPE_PROXYTYPE; + btVector3 margin(getMargin(),getMargin(),getMargin()); + m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin; + }; + + virtual void setMargin(btScalar collisionMargin) + { + //correct the m_implicitShapeDimensions for the margin + btVector3 oldMargin(getMargin(),getMargin(),getMargin()); + btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; + + btConvexInternalShape::setMargin(collisionMargin); + btVector3 newMargin(getMargin(),getMargin(),getMargin()); + m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin; + + } + virtual void setLocalScaling(const btVector3& scaling) + { + btVector3 oldMargin(getMargin(),getMargin(),getMargin()); + btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; + btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling; + + btConvexInternalShape::setLocalScaling(scaling); + + m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin; + + } + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + + + + + int getVertexCount() const + { + return 4; + } + + virtual int getNumVertices()const + { + return 4; + } + + const btVector3* getVertices() const + { + return &m_vertices[0]; + } + + const btVector3* getNormals() const + { + return &m_normals[0]; + } + + + + + + + + virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const + { + //this plane might not be aligned... + btVector4 plane ; + getPlaneEquation(plane,i); + planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ()); + planeSupport = localGetSupportingVertex(-planeNormal); + } + + + const btVector3& getCentroid() const + { + return m_centroid; + } + + virtual int getNumPlanes() const + { + return 6; + } + + + + virtual int getNumEdges() const + { + return 12; + } + + + virtual void getVertex(int i,btVector3& vtx) const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + + vtx = btVector3( + halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1), + halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1), + halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); + } + + + virtual void getPlaneEquation(btVector4& plane,int i) const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + + switch (i) + { + case 0: + plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x()); + break; + case 1: + plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x()); + break; + case 2: + plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y()); + break; + case 3: + plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y()); + break; + case 4: + plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z()); + break; + case 5: + plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z()); + break; + default: + btAssert(0); + } + } + + + virtual void getEdge(int i,btVector3& pa,btVector3& pb) const + //virtual void getEdge(int i,Edge& edge) const + { + int edgeVert0 = 0; + int edgeVert1 = 0; + + switch (i) + { + case 0: + edgeVert0 = 0; + edgeVert1 = 1; + break; + case 1: + edgeVert0 = 0; + edgeVert1 = 2; + break; + case 2: + edgeVert0 = 1; + edgeVert1 = 3; + + break; + case 3: + edgeVert0 = 2; + edgeVert1 = 3; + break; + case 4: + edgeVert0 = 0; + edgeVert1 = 4; + break; + case 5: + edgeVert0 = 1; + edgeVert1 = 5; + + break; + case 6: + edgeVert0 = 2; + edgeVert1 = 6; + break; + case 7: + edgeVert0 = 3; + edgeVert1 = 7; + break; + case 8: + edgeVert0 = 4; + edgeVert1 = 5; + break; + case 9: + edgeVert0 = 4; + edgeVert1 = 6; + break; + case 10: + edgeVert0 = 5; + edgeVert1 = 7; + break; + case 11: + edgeVert0 = 6; + edgeVert1 = 7; + break; + default: + btAssert(0); + + } + + getVertex(edgeVert0,pa ); + getVertex(edgeVert1,pb ); + } + + + + + + virtual bool isInside(const btVector3& pt,btScalar tolerance) const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + + //btScalar minDist = 2*tolerance; + + bool result = (pt.x() <= (halfExtents.x()+tolerance)) && + (pt.x() >= (-halfExtents.x()-tolerance)) && + (pt.y() <= (halfExtents.y()+tolerance)) && + (pt.y() >= (-halfExtents.y()-tolerance)) && + (pt.z() <= (halfExtents.z()+tolerance)) && + (pt.z() >= (-halfExtents.z()-tolerance)); + + return result; + } + + + //debugging + virtual const char* getName()const + { + return "Box2d"; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 6; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + switch (index) + { + case 0: + penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); + break; + case 1: + penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); + break; + case 2: + penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); + break; + case 3: + penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); + break; + case 4: + penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); + break; + case 5: + penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); + break; + default: + btAssert(0); + } + } + +}; + +#endif //BT_OBB_BOX_2D_SHAPE_H + + diff --git a/src/BulletCollision/CollisionShapes/btBoxShape.cpp b/src/BulletCollision/CollisionShapes/btBoxShape.cpp new file mode 100644 index 0000000..3859138 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btBoxShape.cpp @@ -0,0 +1,51 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include "btBoxShape.h" + +btBoxShape::btBoxShape( const btVector3& boxHalfExtents) +: btPolyhedralConvexShape() +{ + m_shapeType = BOX_SHAPE_PROXYTYPE; + + setSafeMargin(boxHalfExtents); + + btVector3 margin(getMargin(),getMargin(),getMargin()); + m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin; +}; + + + + +void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax); +} + + +void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + //btScalar margin = btScalar(0.); + btVector3 halfExtents = getHalfExtentsWithMargin(); + + btScalar lx=btScalar(2.)*(halfExtents.x()); + btScalar ly=btScalar(2.)*(halfExtents.y()); + btScalar lz=btScalar(2.)*(halfExtents.z()); + + inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + ly*ly)); + +} + diff --git a/src/BulletCollision/CollisionShapes/btBoxShape.h b/src/BulletCollision/CollisionShapes/btBoxShape.h new file mode 100644 index 0000000..715e3f2 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btBoxShape.h @@ -0,0 +1,314 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_OBB_BOX_MINKOWSKI_H +#define BT_OBB_BOX_MINKOWSKI_H + +#include "btPolyhedralConvexShape.h" +#include "btCollisionMargin.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btMinMax.h" + +///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space. +ATTRIBUTE_ALIGNED16(class) btBoxShape: public btPolyhedralConvexShape +{ + + //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead + + +public: + +BT_DECLARE_ALIGNED_ALLOCATOR(); + + btVector3 getHalfExtentsWithMargin() const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents += margin; + return halfExtents; + } + + const btVector3& getHalfExtentsWithoutMargin() const + { + return m_implicitShapeDimensions;//scaling is included, margin is not + } + + + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents += margin; + + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + } + + SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + { + const btVector3& halfExtents = getHalfExtentsWithoutMargin(); + + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + } + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + { + const btVector3& halfExtents = getHalfExtentsWithoutMargin(); + + for (int i=0;i>1)) - halfExtents.y() * ((i&2)>>1), + halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); + } + + + virtual void getPlaneEquation(btVector4& plane,int i) const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + + switch (i) + { + case 0: + plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x()); + break; + case 1: + plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x()); + break; + case 2: + plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y()); + break; + case 3: + plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y()); + break; + case 4: + plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z()); + break; + case 5: + plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z()); + break; + default: + btAssert(0); + } + } + + + virtual void getEdge(int i,btVector3& pa,btVector3& pb) const + //virtual void getEdge(int i,Edge& edge) const + { + int edgeVert0 = 0; + int edgeVert1 = 0; + + switch (i) + { + case 0: + edgeVert0 = 0; + edgeVert1 = 1; + break; + case 1: + edgeVert0 = 0; + edgeVert1 = 2; + break; + case 2: + edgeVert0 = 1; + edgeVert1 = 3; + + break; + case 3: + edgeVert0 = 2; + edgeVert1 = 3; + break; + case 4: + edgeVert0 = 0; + edgeVert1 = 4; + break; + case 5: + edgeVert0 = 1; + edgeVert1 = 5; + + break; + case 6: + edgeVert0 = 2; + edgeVert1 = 6; + break; + case 7: + edgeVert0 = 3; + edgeVert1 = 7; + break; + case 8: + edgeVert0 = 4; + edgeVert1 = 5; + break; + case 9: + edgeVert0 = 4; + edgeVert1 = 6; + break; + case 10: + edgeVert0 = 5; + edgeVert1 = 7; + break; + case 11: + edgeVert0 = 6; + edgeVert1 = 7; + break; + default: + btAssert(0); + + } + + getVertex(edgeVert0,pa ); + getVertex(edgeVert1,pb ); + } + + + + + + virtual bool isInside(const btVector3& pt,btScalar tolerance) const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + + //btScalar minDist = 2*tolerance; + + bool result = (pt.x() <= (halfExtents.x()+tolerance)) && + (pt.x() >= (-halfExtents.x()-tolerance)) && + (pt.y() <= (halfExtents.y()+tolerance)) && + (pt.y() >= (-halfExtents.y()-tolerance)) && + (pt.z() <= (halfExtents.z()+tolerance)) && + (pt.z() >= (-halfExtents.z()-tolerance)); + + return result; + } + + + //debugging + virtual const char* getName()const + { + return "Box"; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 6; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + switch (index) + { + case 0: + penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); + break; + case 1: + penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); + break; + case 2: + penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); + break; + case 3: + penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); + break; + case 4: + penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); + break; + case 5: + penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); + break; + default: + btAssert(0); + } + } + +}; + + +#endif //BT_OBB_BOX_MINKOWSKI_H + + diff --git a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp new file mode 100644 index 0000000..ace4cfa --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp @@ -0,0 +1,466 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//#define DISABLE_BVH + +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" +#include "LinearMath/btSerializer.h" + +///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. +///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. +btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh) +:btTriangleMeshShape(meshInterface), +m_bvh(0), +m_triangleInfoMap(0), +m_useQuantizedAabbCompression(useQuantizedAabbCompression), +m_ownsBvh(false) +{ + m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; + //construct bvh from meshInterface +#ifndef DISABLE_BVH + + if (buildBvh) + { + buildOptimizedBvh(); + } + +#endif //DISABLE_BVH + +} + +btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh) +:btTriangleMeshShape(meshInterface), +m_bvh(0), +m_triangleInfoMap(0), +m_useQuantizedAabbCompression(useQuantizedAabbCompression), +m_ownsBvh(false) +{ + m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; + //construct bvh from meshInterface +#ifndef DISABLE_BVH + + if (buildBvh) + { + void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); + m_bvh = new (mem) btOptimizedBvh(); + + m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + m_ownsBvh = true; + } + +#endif //DISABLE_BVH + +} + +void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax) +{ + m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax ); + + m_localAabbMin.setMin(aabbMin); + m_localAabbMax.setMax(aabbMax); +} + + +void btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax) +{ + m_bvh->refit( m_meshInterface, aabbMin,aabbMax ); + + recalcLocalAabb(); +} + +btBvhTriangleMeshShape::~btBvhTriangleMeshShape() +{ + if (m_ownsBvh) + { + m_bvh->~btOptimizedBvh(); + btAlignedFree(m_bvh); + } +} + +void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget) +{ + struct MyNodeOverlapCallback : public btNodeOverlapCallback + { + btStridingMeshInterface* m_meshInterface; + btTriangleCallback* m_callback; + + MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) + :m_meshInterface(meshInterface), + m_callback(callback) + { + } + + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) + { + btVector3 m_triangle[3]; + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + nodeSubPart); + + unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); + btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); + + const btVector3& meshScaling = m_meshInterface->getScaling(); + for (int j=2;j>=0;j--) + { + int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; + + if (type == PHY_FLOAT) + { + float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + + m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); + } + else + { + double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); + + m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); + } + } + + /* Perform ray vs. triangle collision here */ + m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); + m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); + } + }; + + MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); + + m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget); +} + +void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax) +{ + struct MyNodeOverlapCallback : public btNodeOverlapCallback + { + btStridingMeshInterface* m_meshInterface; + btTriangleCallback* m_callback; + + MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) + :m_meshInterface(meshInterface), + m_callback(callback) + { + } + + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) + { + btVector3 m_triangle[3]; + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + nodeSubPart); + + unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); + btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); + + const btVector3& meshScaling = m_meshInterface->getScaling(); + for (int j=2;j>=0;j--) + { + int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; + + if (type == PHY_FLOAT) + { + float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + + m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); + } + else + { + double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); + + m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); + } + } + + /* Perform ray vs. triangle collision here */ + m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); + m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); + } + }; + + MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); + + m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax); +} + +//perform bvh tree traversal and report overlapping triangles to 'callback' +void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + +#ifdef DISABLE_BVH + //brute force traverse all triangles + btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax); +#else + + //first get all the nodes + + + struct MyNodeOverlapCallback : public btNodeOverlapCallback + { + btStridingMeshInterface* m_meshInterface; + btTriangleCallback* m_callback; + btVector3 m_triangle[3]; + + + MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) + :m_meshInterface(meshInterface), + m_callback(callback) + { + } + + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) + { + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + nodeSubPart); + + unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); + btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT||indicestype==PHY_UCHAR); + + const btVector3& meshScaling = m_meshInterface->getScaling(); + for (int j=2;j>=0;j--) + { + + int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:indicestype==PHY_INTEGER?gfxbase[j]:((unsigned char*)gfxbase)[j]; + + +#ifdef DEBUG_TRIANGLE_MESH + printf("%d ,",graphicsindex); +#endif //DEBUG_TRIANGLE_MESH + if (type == PHY_FLOAT) + { + float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + + m_triangle[j] = btVector3( + graphicsbase[0]*meshScaling.getX(), + graphicsbase[1]*meshScaling.getY(), + graphicsbase[2]*meshScaling.getZ()); + } + else + { + double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); + + m_triangle[j] = btVector3( + btScalar(graphicsbase[0])*meshScaling.getX(), + btScalar(graphicsbase[1])*meshScaling.getY(), + btScalar(graphicsbase[2])*meshScaling.getZ()); + } +#ifdef DEBUG_TRIANGLE_MESH + printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z()); +#endif //DEBUG_TRIANGLE_MESH + } + + m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); + m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); + } + + }; + + MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); + + m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); + + +#endif//DISABLE_BVH + + +} + +void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) +{ + if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) + { + btTriangleMeshShape::setLocalScaling(scaling); + buildOptimizedBvh(); + } +} + +void btBvhTriangleMeshShape::buildOptimizedBvh() +{ + if (m_ownsBvh) + { + m_bvh->~btOptimizedBvh(); + btAlignedFree(m_bvh); + } + ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work + void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); + m_bvh = new(mem) btOptimizedBvh(); + //rebuild the bvh... + m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax); + m_ownsBvh = true; +} + +void btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling) +{ + btAssert(!m_bvh); + btAssert(!m_ownsBvh); + + m_bvh = bvh; + m_ownsBvh = false; + // update the scaling without rebuilding the bvh + if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) + { + btTriangleMeshShape::setLocalScaling(scaling); + } +} + + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btTriangleMeshShapeData* trimeshData = (btTriangleMeshShapeData*) dataBuffer; + + btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer); + + m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer); + + trimeshData->m_collisionMargin = float(m_collisionMargin); + + + + if (m_bvh && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_BVH)) + { + void* chunk = serializer->findPointer(m_bvh); + if (chunk) + { +#ifdef BT_USE_DOUBLE_PRECISION + trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)chunk; + trimeshData->m_quantizedFloatBvh = 0; +#else + trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)chunk; + trimeshData->m_quantizedDoubleBvh= 0; +#endif //BT_USE_DOUBLE_PRECISION + } else + { + +#ifdef BT_USE_DOUBLE_PRECISION + trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh); + trimeshData->m_quantizedFloatBvh = 0; +#else + trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh); + trimeshData->m_quantizedDoubleBvh= 0; +#endif //BT_USE_DOUBLE_PRECISION + + int sz = m_bvh->calculateSerializeBufferSizeNew(); + btChunk* chunk = serializer->allocate(sz,1); + const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,m_bvh); + } + } else + { + trimeshData->m_quantizedFloatBvh = 0; + trimeshData->m_quantizedDoubleBvh = 0; + } + + + + if (m_triangleInfoMap && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_TRIANGLEINFOMAP)) + { + void* chunk = serializer->findPointer(m_triangleInfoMap); + if (chunk) + { + trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)chunk; + } else + { + trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)serializer->getUniquePointer(m_triangleInfoMap); + int sz = m_triangleInfoMap->calculateSerializeBufferSize(); + btChunk* chunk = serializer->allocate(sz,1); + const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,m_triangleInfoMap); + } + } else + { + trimeshData->m_triangleInfoMap = 0; + } + + return "btTriangleMeshShapeData"; +} + +void btBvhTriangleMeshShape::serializeSingleBvh(btSerializer* serializer) const +{ + if (m_bvh) + { + int len = m_bvh->calculateSerializeBufferSizeNew(); //make sure not to use calculateSerializeBufferSize because it is used for in-place + btChunk* chunk = serializer->allocate(len,1); + const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,(void*)m_bvh); + } +} + +void btBvhTriangleMeshShape::serializeSingleTriangleInfoMap(btSerializer* serializer) const +{ + if (m_triangleInfoMap) + { + int len = m_triangleInfoMap->calculateSerializeBufferSize(); + btChunk* chunk = serializer->allocate(len,1); + const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,(void*)m_triangleInfoMap); + } +} + + + + diff --git a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h new file mode 100644 index 0000000..d1c2162 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h @@ -0,0 +1,139 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BVH_TRIANGLE_MESH_SHAPE_H +#define BT_BVH_TRIANGLE_MESH_SHAPE_H + +#include "btTriangleMeshShape.h" +#include "btOptimizedBvh.h" +#include "LinearMath/btAlignedAllocator.h" +#include "btTriangleInfoMap.h" + +///The btBvhTriangleMeshShape is a static-triangle mesh shape with several optimizations, such as bounding volume hierarchy and cache friendly traversal for PlayStation 3 Cell SPU. It is recommended to enable useQuantizedAabbCompression for better memory usage. +///It takes a triangle mesh as input, for example a btTriangleMesh or btTriangleIndexVertexArray. The btBvhTriangleMeshShape class allows for triangle mesh deformations by a refit or partialRefit method. +///Instead of building the bounding volume hierarchy acceleration structure, it is also possible to serialize (save) and deserialize (load) the structure from disk. +///See Demos\ConcaveDemo\ConcavePhysicsDemo.cpp for an example. +ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape +{ + + btOptimizedBvh* m_bvh; + btTriangleInfoMap* m_triangleInfoMap; + + bool m_useQuantizedAabbCompression; + bool m_ownsBvh; + bool m_pad[11];////need padding due to alignment + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + + btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true); + + ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb + btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true); + + virtual ~btBvhTriangleMeshShape(); + + bool getOwnsBvh () const + { + return m_ownsBvh; + } + + + + void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget); + void performConvexcast (btTriangleCallback* callback, const btVector3& boxSource, const btVector3& boxTarget, const btVector3& boxMin, const btVector3& boxMax); + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + void refitTree(const btVector3& aabbMin,const btVector3& aabbMax); + + ///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks + void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax); + + //debugging + virtual const char* getName()const {return "BVHTRIANGLEMESH";} + + + virtual void setLocalScaling(const btVector3& scaling); + + btOptimizedBvh* getOptimizedBvh() + { + return m_bvh; + } + + void setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& localScaling=btVector3(1,1,1)); + + void buildOptimizedBvh(); + + bool usesQuantizedAabbCompression() const + { + return m_useQuantizedAabbCompression; + } + + void setTriangleInfoMap(btTriangleInfoMap* triangleInfoMap) + { + m_triangleInfoMap = triangleInfoMap; + } + + const btTriangleInfoMap* getTriangleInfoMap() const + { + return m_triangleInfoMap; + } + + btTriangleInfoMap* getTriangleInfoMap() + { + return m_triangleInfoMap; + } + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + virtual void serializeSingleBvh(btSerializer* serializer) const; + + virtual void serializeSingleTriangleInfoMap(btSerializer* serializer) const; + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btTriangleMeshShapeData +{ + btCollisionShapeData m_collisionShapeData; + + btStridingMeshInterfaceData m_meshInterface; + + btQuantizedBvhFloatData *m_quantizedFloatBvh; + btQuantizedBvhDoubleData *m_quantizedDoubleBvh; + + btTriangleInfoMapData *m_triangleInfoMap; + + float m_collisionMargin; + + char m_pad3[4]; + +}; + + +SIMD_FORCE_INLINE int btBvhTriangleMeshShape::calculateSerializeBufferSize() const +{ + return sizeof(btTriangleMeshShapeData); +} + + + +#endif //BT_BVH_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp b/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp new file mode 100644 index 0000000..864df26 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp @@ -0,0 +1,171 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btCapsuleShape.h" + +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" +#include "LinearMath/btQuaternion.h" + +btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInternalShape () +{ + m_shapeType = CAPSULE_SHAPE_PROXYTYPE; + m_upAxis = 1; + m_implicitShapeDimensions.setValue(radius,0.5f*height,radius); +} + + + btVector3 btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +{ + + btVector3 supVec(0,0,0); + + btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + + btVector3 vtx; + btScalar newDot; + + btScalar radius = getRadius(); + + + { + btVector3 pos(0,0,0); + pos[getUpAxis()] = getHalfHeight(); + + vtx = pos +vec*(radius) - vec * getMargin(); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + { + btVector3 pos(0,0,0); + pos[getUpAxis()] = -getHalfHeight(); + + vtx = pos +vec*(radius) - vec * getMargin(); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + + return supVec; + +} + + void btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + + + btScalar radius = getRadius(); + + for (int j=0;j maxDot) + { + maxDot = newDot; + supportVerticesOut[j] = vtx; + } + } + { + btVector3 pos(0,0,0); + pos[getUpAxis()] = -getHalfHeight(); + vtx = pos +vec*(radius) - vec * getMargin(); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supportVerticesOut[j] = vtx; + } + } + + } +} + + +void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + //as an approximation, take the inertia of the box that bounds the spheres + + btTransform ident; + ident.setIdentity(); + + + btScalar radius = getRadius(); + + btVector3 halfExtents(radius,radius,radius); + halfExtents[getUpAxis()]+=getHalfHeight(); + + btScalar margin = CONVEX_DISTANCE_MARGIN; + + btScalar lx=btScalar(2.)*(halfExtents[0]+margin); + btScalar ly=btScalar(2.)*(halfExtents[1]+margin); + btScalar lz=btScalar(2.)*(halfExtents[2]+margin); + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(.08333333); + + inertia[0] = scaledmass * (y2+z2); + inertia[1] = scaledmass * (x2+z2); + inertia[2] = scaledmass * (x2+y2); + +} + +btCapsuleShapeX::btCapsuleShapeX(btScalar radius,btScalar height) +{ + m_upAxis = 0; + m_implicitShapeDimensions.setValue(0.5f*height, radius,radius); +} + + + + + + +btCapsuleShapeZ::btCapsuleShapeZ(btScalar radius,btScalar height) +{ + m_upAxis = 2; + m_implicitShapeDimensions.setValue(radius,radius,0.5f*height); +} + + + + diff --git a/src/BulletCollision/CollisionShapes/btCapsuleShape.h b/src/BulletCollision/CollisionShapes/btCapsuleShape.h new file mode 100644 index 0000000..7578bb2 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCapsuleShape.h @@ -0,0 +1,184 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CAPSULE_SHAPE_H +#define BT_CAPSULE_SHAPE_H + +#include "btConvexInternalShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types + + +///The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned around the X axis and btCapsuleShapeZ around the Z axis. +///The total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps. +///The btCapsuleShape is a convex hull of two spheres. The btMultiSphereShape is a more general collision shape that takes the convex hull of multiple sphere, so it can also represent a capsule when just using two spheres. +ATTRIBUTE_ALIGNED16(class) btCapsuleShape : public btConvexInternalShape +{ +protected: + int m_upAxis; + +protected: + ///only used for btCapsuleShapeZ and btCapsuleShapeX subclasses. + btCapsuleShape() : btConvexInternalShape() {m_shapeType = CAPSULE_SHAPE_PROXYTYPE;}; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btCapsuleShape(btScalar radius,btScalar height); + + ///CollisionShape Interface + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + /// btConvexShape Interface + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual void setMargin(btScalar collisionMargin) + { + //correct the m_implicitShapeDimensions for the margin + btVector3 oldMargin(getMargin(),getMargin(),getMargin()); + btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; + + btConvexInternalShape::setMargin(collisionMargin); + btVector3 newMargin(getMargin(),getMargin(),getMargin()); + m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin; + + } + + virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const + { + btVector3 halfExtents(getRadius(),getRadius(),getRadius()); + halfExtents[m_upAxis] = getRadius() + getHalfHeight(); + halfExtents += btVector3(getMargin(),getMargin(),getMargin()); + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + + aabbMin = center - extent; + aabbMax = center + extent; + } + + virtual const char* getName()const + { + return "CapsuleShape"; + } + + int getUpAxis() const + { + return m_upAxis; + } + + btScalar getRadius() const + { + int radiusAxis = (m_upAxis+2)%3; + return m_implicitShapeDimensions[radiusAxis]; + } + + btScalar getHalfHeight() const + { + return m_implicitShapeDimensions[m_upAxis]; + } + + virtual void setLocalScaling(const btVector3& scaling) + { + btVector3 oldMargin(getMargin(),getMargin(),getMargin()); + btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; + btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling; + + btConvexInternalShape::setLocalScaling(scaling); + + m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin; + + } + + virtual btVector3 getAnisotropicRollingFrictionDirection() const + { + btVector3 aniDir(0,0,0); + aniDir[getUpAxis()]=1; + return aniDir; + } + + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///btCapsuleShapeX represents a capsule around the Z axis +///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps. +class btCapsuleShapeX : public btCapsuleShape +{ +public: + + btCapsuleShapeX(btScalar radius,btScalar height); + + //debugging + virtual const char* getName()const + { + return "CapsuleX"; + } + + + +}; + +///btCapsuleShapeZ represents a capsule around the Z axis +///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps. +class btCapsuleShapeZ : public btCapsuleShape +{ +public: + btCapsuleShapeZ(btScalar radius,btScalar height); + + //debugging + virtual const char* getName()const + { + return "CapsuleZ"; + } + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btCapsuleShapeData +{ + btConvexInternalShapeData m_convexInternalShapeData; + + int m_upAxis; + + char m_padding[4]; +}; + +SIMD_FORCE_INLINE int btCapsuleShape::calculateSerializeBufferSize() const +{ + return sizeof(btCapsuleShapeData); +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btCapsuleShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btCapsuleShapeData* shapeData = (btCapsuleShapeData*) dataBuffer; + + btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer); + + shapeData->m_upAxis = m_upAxis; + + return "btCapsuleShapeData"; +} + +#endif //BT_CAPSULE_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btCollisionMargin.h b/src/BulletCollision/CollisionShapes/btCollisionMargin.h new file mode 100644 index 0000000..474bf1f --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCollisionMargin.h @@ -0,0 +1,27 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COLLISION_MARGIN_H +#define BT_COLLISION_MARGIN_H + +///The CONVEX_DISTANCE_MARGIN is a default collision margin for convex collision shapes derived from btConvexInternalShape. +///This collision margin is used by Gjk and some other algorithms +///Note that when creating small objects, you need to make sure to set a smaller collision margin, using the 'setMargin' API +#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01) + + + +#endif //BT_COLLISION_MARGIN_H + diff --git a/src/BulletCollision/CollisionShapes/btCollisionShape.cpp b/src/BulletCollision/CollisionShapes/btCollisionShape.cpp new file mode 100644 index 0000000..39ee21c --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCollisionShape.cpp @@ -0,0 +1,119 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "LinearMath/btSerializer.h" + +/* + Make sure this dummy function never changes so that it + can be used by probes that are checking whether the + library is actually installed. +*/ +extern "C" +{ +void btBulletCollisionProbe (); + +void btBulletCollisionProbe () {} +} + + + +void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const +{ + btTransform tr; + tr.setIdentity(); + btVector3 aabbMin,aabbMax; + + getAabb(tr,aabbMin,aabbMax); + + radius = (aabbMax-aabbMin).length()*btScalar(0.5); + center = (aabbMin+aabbMax)*btScalar(0.5); +} + + +btScalar btCollisionShape::getContactBreakingThreshold(btScalar defaultContactThreshold) const +{ + return getAngularMotionDisc() * defaultContactThreshold; +} + +btScalar btCollisionShape::getAngularMotionDisc() const +{ + ///@todo cache this value, to improve performance + btVector3 center; + btScalar disc; + getBoundingSphere(center,disc); + disc += (center).length(); + return disc; +} + +void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const +{ + //start with static aabb + getAabb(curTrans,temporalAabbMin,temporalAabbMax); + + btScalar temporalAabbMaxx = temporalAabbMax.getX(); + btScalar temporalAabbMaxy = temporalAabbMax.getY(); + btScalar temporalAabbMaxz = temporalAabbMax.getZ(); + btScalar temporalAabbMinx = temporalAabbMin.getX(); + btScalar temporalAabbMiny = temporalAabbMin.getY(); + btScalar temporalAabbMinz = temporalAabbMin.getZ(); + + // add linear motion + btVector3 linMotion = linvel*timeStep; + ///@todo: simd would have a vector max/min operation, instead of per-element access + if (linMotion.x() > btScalar(0.)) + temporalAabbMaxx += linMotion.x(); + else + temporalAabbMinx += linMotion.x(); + if (linMotion.y() > btScalar(0.)) + temporalAabbMaxy += linMotion.y(); + else + temporalAabbMiny += linMotion.y(); + if (linMotion.z() > btScalar(0.)) + temporalAabbMaxz += linMotion.z(); + else + temporalAabbMinz += linMotion.z(); + + //add conservative angular motion + btScalar angularMotion = angvel.length() * getAngularMotionDisc() * timeStep; + btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); + temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); + temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); + + temporalAabbMin -= angularMotion3d; + temporalAabbMax += angularMotion3d; +} + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btCollisionShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btCollisionShapeData* shapeData = (btCollisionShapeData*) dataBuffer; + char* name = (char*) serializer->findNameForPointer(this); + shapeData->m_name = (char*)serializer->getUniquePointer(name); + if (shapeData->m_name) + { + serializer->serializeName(name); + } + shapeData->m_shapeType = m_shapeType; + //shapeData->m_padding//?? + return "btCollisionShapeData"; +} + +void btCollisionShape::serializeSingleShape(btSerializer* serializer) const +{ + int len = calculateSerializeBufferSize(); + btChunk* chunk = serializer->allocate(len,1); + const char* structType = serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,(void*)this); +} \ No newline at end of file diff --git a/src/BulletCollision/CollisionShapes/btCollisionShape.h b/src/BulletCollision/CollisionShapes/btCollisionShape.h new file mode 100644 index 0000000..ff017a2 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCollisionShape.h @@ -0,0 +1,159 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COLLISION_SHAPE_H +#define BT_COLLISION_SHAPE_H + +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types +class btSerializer; + + +///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects. +ATTRIBUTE_ALIGNED16(class) btCollisionShape +{ +protected: + int m_shapeType; + void* m_userPointer; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0) + { + } + + virtual ~btCollisionShape() + { + } + + ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + + virtual void getBoundingSphere(btVector3& center,btScalar& radius) const; + + ///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations. + virtual btScalar getAngularMotionDisc() const; + + virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const; + + + ///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep) + ///result is conservative + void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const; + + + + SIMD_FORCE_INLINE bool isPolyhedral() const + { + return btBroadphaseProxy::isPolyhedral(getShapeType()); + } + + SIMD_FORCE_INLINE bool isConvex2d() const + { + return btBroadphaseProxy::isConvex2d(getShapeType()); + } + + SIMD_FORCE_INLINE bool isConvex() const + { + return btBroadphaseProxy::isConvex(getShapeType()); + } + SIMD_FORCE_INLINE bool isNonMoving() const + { + return btBroadphaseProxy::isNonMoving(getShapeType()); + } + SIMD_FORCE_INLINE bool isConcave() const + { + return btBroadphaseProxy::isConcave(getShapeType()); + } + SIMD_FORCE_INLINE bool isCompound() const + { + return btBroadphaseProxy::isCompound(getShapeType()); + } + + SIMD_FORCE_INLINE bool isSoftBody() const + { + return btBroadphaseProxy::isSoftBody(getShapeType()); + } + + ///isInfinite is used to catch simulation error (aabb check) + SIMD_FORCE_INLINE bool isInfinite() const + { + return btBroadphaseProxy::isInfinite(getShapeType()); + } + +#ifndef __SPU__ + virtual void setLocalScaling(const btVector3& scaling) =0; + virtual const btVector3& getLocalScaling() const =0; + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0; + + +//debugging support + virtual const char* getName()const =0 ; +#endif //__SPU__ + + + int getShapeType() const { return m_shapeType; } + + ///the getAnisotropicRollingFrictionDirection can be used in combination with setAnisotropicFriction + ///See Bullet/Demos/RollingFrictionDemo for an example + virtual btVector3 getAnisotropicRollingFrictionDirection() const + { + return btVector3(1,1,1); + } + virtual void setMargin(btScalar margin) = 0; + virtual btScalar getMargin() const = 0; + + + ///optional user data pointer + void setUserPointer(void* userPtr) + { + m_userPointer = userPtr; + } + + void* getUserPointer() const + { + return m_userPointer; + } + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + virtual void serializeSingleShape(btSerializer* serializer) const; + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btCollisionShapeData +{ + char *m_name; + int m_shapeType; + char m_padding[4]; +}; + +SIMD_FORCE_INLINE int btCollisionShape::calculateSerializeBufferSize() const +{ + return sizeof(btCollisionShapeData); +} + + + +#endif //BT_COLLISION_SHAPE_H + diff --git a/src/BulletCollision/CollisionShapes/btCompoundShape.cpp b/src/BulletCollision/CollisionShapes/btCompoundShape.cpp new file mode 100644 index 0000000..12f422f --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCompoundShape.cpp @@ -0,0 +1,354 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btCompoundShape.h" +#include "btCollisionShape.h" +#include "BulletCollision/BroadphaseCollision/btDbvt.h" +#include "LinearMath/btSerializer.h" + +btCompoundShape::btCompoundShape(bool enableDynamicAabbTree) +: m_localAabbMin(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)), +m_localAabbMax(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)), +m_dynamicAabbTree(0), +m_updateRevision(1), +m_collisionMargin(btScalar(0.)), +m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)) +{ + m_shapeType = COMPOUND_SHAPE_PROXYTYPE; + + if (enableDynamicAabbTree) + { + void* mem = btAlignedAlloc(sizeof(btDbvt),16); + m_dynamicAabbTree = new(mem) btDbvt(); + btAssert(mem==m_dynamicAabbTree); + } +} + + +btCompoundShape::~btCompoundShape() +{ + if (m_dynamicAabbTree) + { + m_dynamicAabbTree->~btDbvt(); + btAlignedFree(m_dynamicAabbTree); + } +} + +void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape) +{ + m_updateRevision++; + //m_childTransforms.push_back(localTransform); + //m_childShapes.push_back(shape); + btCompoundShapeChild child; + child.m_node = 0; + child.m_transform = localTransform; + child.m_childShape = shape; + child.m_childShapeType = shape->getShapeType(); + child.m_childMargin = shape->getMargin(); + + + //extend the local aabbMin/aabbMax + btVector3 localAabbMin,localAabbMax; + shape->getAabb(localTransform,localAabbMin,localAabbMax); + for (int i=0;i<3;i++) + { + if (m_localAabbMin[i] > localAabbMin[i]) + { + m_localAabbMin[i] = localAabbMin[i]; + } + if (m_localAabbMax[i] < localAabbMax[i]) + { + m_localAabbMax[i] = localAabbMax[i]; + } + + } + if (m_dynamicAabbTree) + { + const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + int index = m_children.size(); + child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index); + } + + m_children.push_back(child); + +} + +void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform,bool shouldRecalculateLocalAabb) +{ + m_children[childIndex].m_transform = newChildTransform; + + if (m_dynamicAabbTree) + { + ///update the dynamic aabb tree + btVector3 localAabbMin,localAabbMax; + m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax); + ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + //int index = m_children.size()-1; + m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds); + } + + if (shouldRecalculateLocalAabb) + { + recalculateLocalAabb(); + } +} + +void btCompoundShape::removeChildShapeByIndex(int childShapeIndex) +{ + m_updateRevision++; + btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size()); + if (m_dynamicAabbTree) + { + m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node); + } + m_children.swap(childShapeIndex,m_children.size()-1); + if (m_dynamicAabbTree) + m_children[childShapeIndex].m_node->dataAsInt = childShapeIndex; + m_children.pop_back(); + +} + + + +void btCompoundShape::removeChildShape(btCollisionShape* shape) +{ + m_updateRevision++; + // Find the children containing the shape specified, and remove those children. + //note: there might be multiple children using the same shape! + for(int i = m_children.size()-1; i >= 0 ; i--) + { + if(m_children[i].m_childShape == shape) + { + removeChildShapeByIndex(i); + } + } + + + + recalculateLocalAabb(); +} + +void btCompoundShape::recalculateLocalAabb() +{ + // Recalculate the local aabb + // Brute force, it iterates over all the shapes left. + + m_localAabbMin = btVector3(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + m_localAabbMax = btVector3(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + + //extend the local aabbMin/aabbMax + for (int j = 0; j < m_children.size(); j++) + { + btVector3 localAabbMin,localAabbMax; + m_children[j].m_childShape->getAabb(m_children[j].m_transform, localAabbMin, localAabbMax); + for (int i=0;i<3;i++) + { + if (m_localAabbMin[i] > localAabbMin[i]) + m_localAabbMin[i] = localAabbMin[i]; + if (m_localAabbMax[i] < localAabbMax[i]) + m_localAabbMax[i] = localAabbMax[i]; + } + } +} + +///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); + btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); + + //avoid an illegal AABB when there are no children + if (!m_children.size()) + { + localHalfExtents.setValue(0,0,0); + localCenter.setValue(0,0,0); + } + localHalfExtents += btVector3(getMargin(),getMargin(),getMargin()); + + + btMatrix3x3 abs_b = trans.getBasis().absolute(); + + btVector3 center = trans(localCenter); + + btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMin = center-extent; + aabbMax = center+extent; + +} + +void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + //approximation: take the inertia from the aabb for now + btTransform ident; + ident.setIdentity(); + btVector3 aabbMin,aabbMax; + getAabb(ident,aabbMin,aabbMax); + + btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); + + btScalar lx=btScalar(2.)*(halfExtents.x()); + btScalar ly=btScalar(2.)*(halfExtents.y()); + btScalar lz=btScalar(2.)*(halfExtents.z()); + + inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz); + inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz); + inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly); + +} + + + + +void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const +{ + int n = m_children.size(); + + btScalar totalMass = 0; + btVector3 center(0, 0, 0); + int k; + + for (k = 0; k < n; k++) + { + btAssert(masses[k]>0); + center += m_children[k].m_transform.getOrigin() * masses[k]; + totalMass += masses[k]; + } + + btAssert(totalMass>0); + + center /= totalMass; + principal.setOrigin(center); + + btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0); + for ( k = 0; k < n; k++) + { + btVector3 i; + m_children[k].m_childShape->calculateLocalInertia(masses[k], i); + + const btTransform& t = m_children[k].m_transform; + btVector3 o = t.getOrigin() - center; + + //compute inertia tensor in coordinate system of compound shape + btMatrix3x3 j = t.getBasis().transpose(); + j[0] *= i[0]; + j[1] *= i[1]; + j[2] *= i[2]; + j = t.getBasis() * j; + + //add inertia tensor + tensor[0] += j[0]; + tensor[1] += j[1]; + tensor[2] += j[2]; + + //compute inertia tensor of pointmass at o + btScalar o2 = o.length2(); + j[0].setValue(o2, 0, 0); + j[1].setValue(0, o2, 0); + j[2].setValue(0, 0, o2); + j[0] += o * -o.x(); + j[1] += o * -o.y(); + j[2] += o * -o.z(); + + //add inertia tensor of pointmass + tensor[0] += masses[k] * j[0]; + tensor[1] += masses[k] * j[1]; + tensor[2] += masses[k] * j[2]; + } + + tensor.diagonalize(principal.getBasis(), btScalar(0.00001), 20); + inertia.setValue(tensor[0][0], tensor[1][1], tensor[2][2]); +} + + + +void btCompoundShape::setLocalScaling(const btVector3& scaling) +{ + + for(int i = 0; i < m_children.size(); i++) + { + btTransform childTrans = getChildTransform(i); + btVector3 childScale = m_children[i].m_childShape->getLocalScaling(); +// childScale = childScale * (childTrans.getBasis() * scaling); + childScale = childScale * scaling / m_localScaling; + m_children[i].m_childShape->setLocalScaling(childScale); + childTrans.setOrigin((childTrans.getOrigin())*scaling); + updateChildTransform(i, childTrans,false); + } + + m_localScaling = scaling; + recalculateLocalAabb(); + +} + + +void btCompoundShape::createAabbTreeFromChildren() +{ + if ( !m_dynamicAabbTree ) + { + void* mem = btAlignedAlloc(sizeof(btDbvt),16); + m_dynamicAabbTree = new(mem) btDbvt(); + btAssert(mem==m_dynamicAabbTree); + + for ( int index = 0; index < m_children.size(); index++ ) + { + btCompoundShapeChild &child = m_children[index]; + + //extend the local aabbMin/aabbMax + btVector3 localAabbMin,localAabbMax; + child.m_childShape->getAabb(child.m_transform,localAabbMin,localAabbMax); + + const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index); + } + } +} + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btCompoundShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + + btCompoundShapeData* shapeData = (btCompoundShapeData*) dataBuffer; + btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer); + + shapeData->m_collisionMargin = float(m_collisionMargin); + shapeData->m_numChildShapes = m_children.size(); + shapeData->m_childShapePtr = 0; + if (shapeData->m_numChildShapes) + { + btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData),shapeData->m_numChildShapes); + btCompoundShapeChildData* memPtr = (btCompoundShapeChildData*)chunk->m_oldPtr; + shapeData->m_childShapePtr = (btCompoundShapeChildData*)serializer->getUniquePointer(memPtr); + + for (int i=0;im_numChildShapes;i++,memPtr++) + { + memPtr->m_childMargin = float(m_children[i].m_childMargin); + memPtr->m_childShape = (btCollisionShapeData*)serializer->getUniquePointer(m_children[i].m_childShape); + //don't serialize shapes that already have been serialized + if (!serializer->findPointer(m_children[i].m_childShape)) + { + btChunk* chunk = serializer->allocate(m_children[i].m_childShape->calculateSerializeBufferSize(),1); + const char* structType = m_children[i].m_childShape->serialize(chunk->m_oldPtr,serializer); + serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,m_children[i].m_childShape); + } + + memPtr->m_childShapeType = m_children[i].m_childShapeType; + m_children[i].m_transform.serializeFloat(memPtr->m_transform); + } + serializer->finalizeChunk(chunk,"btCompoundShapeChildData",BT_ARRAY_CODE,chunk->m_oldPtr); + } + return "btCompoundShapeData"; +} + diff --git a/src/BulletCollision/CollisionShapes/btCompoundShape.h b/src/BulletCollision/CollisionShapes/btCompoundShape.h new file mode 100644 index 0000000..141034a --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCompoundShape.h @@ -0,0 +1,212 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_COMPOUND_SHAPE_H +#define BT_COMPOUND_SHAPE_H + +#include "btCollisionShape.h" + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" +#include "btCollisionMargin.h" +#include "LinearMath/btAlignedObjectArray.h" + +//class btOptimizedBvh; +struct btDbvt; + +ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btTransform m_transform; + btCollisionShape* m_childShape; + int m_childShapeType; + btScalar m_childMargin; + struct btDbvtNode* m_node; +}; + +SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompoundShapeChild& c2) +{ + return ( c1.m_transform == c2.m_transform && + c1.m_childShape == c2.m_childShape && + c1.m_childShapeType == c2.m_childShapeType && + c1.m_childMargin == c2.m_childMargin ); +} + +/// The btCompoundShape allows to store multiple other btCollisionShapes +/// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape. +/// It has an (optional) dynamic aabb tree to accelerate early rejection tests. +/// @todo: This aabb tree can also be use to speed up ray tests on btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25 +/// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape) +ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape +{ + btAlignedObjectArray m_children; + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + + btDbvt* m_dynamicAabbTree; + + ///increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be updated + int m_updateRevision; + + btScalar m_collisionMargin; + +protected: + btVector3 m_localScaling; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btCompoundShape(bool enableDynamicAabbTree = true); + + virtual ~btCompoundShape(); + + void addChildShape(const btTransform& localTransform,btCollisionShape* shape); + + /// Remove all children shapes that contain the specified shape + virtual void removeChildShape(btCollisionShape* shape); + + void removeChildShapeByIndex(int childShapeindex); + + + int getNumChildShapes() const + { + return int (m_children.size()); + } + + btCollisionShape* getChildShape(int index) + { + return m_children[index].m_childShape; + } + const btCollisionShape* getChildShape(int index) const + { + return m_children[index].m_childShape; + } + + btTransform& getChildTransform(int index) + { + return m_children[index].m_transform; + } + const btTransform& getChildTransform(int index) const + { + return m_children[index].m_transform; + } + + ///set a new transform for a child, and update internal data structures (local aabb and dynamic tree) + void updateChildTransform(int childIndex, const btTransform& newChildTransform, bool shouldRecalculateLocalAabb = true); + + + btCompoundShapeChild* getChildList() + { + return &m_children[0]; + } + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + /** Re-calculate the local Aabb. Is called at the end of removeChildShapes. + Use this yourself if you modify the children or their transforms. */ + virtual void recalculateLocalAabb(); + + virtual void setLocalScaling(const btVector3& scaling); + + virtual const btVector3& getLocalScaling() const + { + return m_localScaling; + } + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + virtual void setMargin(btScalar margin) + { + m_collisionMargin = margin; + } + virtual btScalar getMargin() const + { + return m_collisionMargin; + } + virtual const char* getName()const + { + return "Compound"; + } + + const btDbvt* getDynamicAabbTree() const + { + return m_dynamicAabbTree; + } + + btDbvt* getDynamicAabbTree() + { + return m_dynamicAabbTree; + } + + void createAabbTreeFromChildren(); + + ///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia + ///and the center of mass to the current coordinate system. "masses" points to an array of masses of the children. The resulting transform + ///"principal" has to be applied inversely to all children transforms in order for the local coordinate system of the compound + ///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform + ///of the collision object by the principal transform. + void calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const; + + int getUpdateRevision() const + { + return m_updateRevision; + } + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btCompoundShapeChildData +{ + btTransformFloatData m_transform; + btCollisionShapeData *m_childShape; + int m_childShapeType; + float m_childMargin; +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btCompoundShapeData +{ + btCollisionShapeData m_collisionShapeData; + + btCompoundShapeChildData *m_childShapePtr; + + int m_numChildShapes; + + float m_collisionMargin; + +}; + + +SIMD_FORCE_INLINE int btCompoundShape::calculateSerializeBufferSize() const +{ + return sizeof(btCompoundShapeData); +} + + + + + + + +#endif //BT_COMPOUND_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConcaveShape.cpp b/src/BulletCollision/CollisionShapes/btConcaveShape.cpp new file mode 100644 index 0000000..58ff84a --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConcaveShape.cpp @@ -0,0 +1,27 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btConcaveShape.h" + +btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.)) +{ + +} + +btConcaveShape::~btConcaveShape() +{ + +} diff --git a/src/BulletCollision/CollisionShapes/btConcaveShape.h b/src/BulletCollision/CollisionShapes/btConcaveShape.h new file mode 100644 index 0000000..2917cc5 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConcaveShape.h @@ -0,0 +1,62 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONCAVE_SHAPE_H +#define BT_CONCAVE_SHAPE_H + +#include "btCollisionShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "btTriangleCallback.h" + +/// PHY_ScalarType enumerates possible scalar types. +/// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use +typedef enum PHY_ScalarType { + PHY_FLOAT, + PHY_DOUBLE, + PHY_INTEGER, + PHY_SHORT, + PHY_FIXEDPOINT88, + PHY_UCHAR +} PHY_ScalarType; + +///The btConcaveShape class provides an interface for non-moving (static) concave shapes. +///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape. +ATTRIBUTE_ALIGNED16(class) btConcaveShape : public btCollisionShape +{ +protected: + btScalar m_collisionMargin; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btConcaveShape(); + + virtual ~btConcaveShape(); + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0; + + virtual btScalar getMargin() const { + return m_collisionMargin; + } + virtual void setMargin(btScalar collisionMargin) + { + m_collisionMargin = collisionMargin; + } + + + +}; + +#endif //BT_CONCAVE_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConeShape.cpp b/src/BulletCollision/CollisionShapes/btConeShape.cpp new file mode 100644 index 0000000..5e83087 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConeShape.cpp @@ -0,0 +1,143 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConeShape.h" + + + +btConeShape::btConeShape (btScalar radius,btScalar height): btConvexInternalShape (), +m_radius (radius), +m_height(height) +{ + m_shapeType = CONE_SHAPE_PROXYTYPE; + setConeUpIndex(1); + btVector3 halfExtents; + m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height)); +} + +btConeShapeZ::btConeShapeZ (btScalar radius,btScalar height): +btConeShape(radius,height) +{ + setConeUpIndex(2); +} + +btConeShapeX::btConeShapeX (btScalar radius,btScalar height): +btConeShape(radius,height) +{ + setConeUpIndex(0); +} + +///choose upAxis index +void btConeShape::setConeUpIndex(int upIndex) +{ + switch (upIndex) + { + case 0: + m_coneIndices[0] = 1; + m_coneIndices[1] = 0; + m_coneIndices[2] = 2; + break; + case 1: + m_coneIndices[0] = 0; + m_coneIndices[1] = 1; + m_coneIndices[2] = 2; + break; + case 2: + m_coneIndices[0] = 0; + m_coneIndices[1] = 2; + m_coneIndices[2] = 1; + break; + default: + btAssert(0); + }; +} + +btVector3 btConeShape::coneLocalSupport(const btVector3& v) const +{ + + btScalar halfHeight = m_height * btScalar(0.5); + + if (v[m_coneIndices[1]] > v.length() * m_sinAngle) + { + btVector3 tmp; + + tmp[m_coneIndices[0]] = btScalar(0.); + tmp[m_coneIndices[1]] = halfHeight; + tmp[m_coneIndices[2]] = btScalar(0.); + return tmp; + } + else { + btScalar s = btSqrt(v[m_coneIndices[0]] * v[m_coneIndices[0]] + v[m_coneIndices[2]] * v[m_coneIndices[2]]); + if (s > SIMD_EPSILON) { + btScalar d = m_radius / s; + btVector3 tmp; + tmp[m_coneIndices[0]] = v[m_coneIndices[0]] * d; + tmp[m_coneIndices[1]] = -halfHeight; + tmp[m_coneIndices[2]] = v[m_coneIndices[2]] * d; + return tmp; + } + else { + btVector3 tmp; + tmp[m_coneIndices[0]] = btScalar(0.); + tmp[m_coneIndices[1]] = -halfHeight; + tmp[m_coneIndices[2]] = btScalar(0.); + return tmp; + } + } + +} + +btVector3 btConeShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const +{ + return coneLocalSupport(vec); +} + +void btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + for (int i=0;ilocalGetSupportingVertexWithoutMargin(vec); +} + +void btConvex2dShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors); +} + + +btVector3 btConvex2dShape::localGetSupportingVertex(const btVector3& vec)const +{ + return m_childConvexShape->localGetSupportingVertex(vec); +} + + +void btConvex2dShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + ///this linear upscaling is not realistic, but we don't deal with large mass ratios... + m_childConvexShape->calculateLocalInertia(mass,inertia); +} + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btConvex2dShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + m_childConvexShape->getAabb(t,aabbMin,aabbMax); +} + +void btConvex2dShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + m_childConvexShape->getAabbSlow(t,aabbMin,aabbMax); +} + +void btConvex2dShape::setLocalScaling(const btVector3& scaling) +{ + m_childConvexShape->setLocalScaling(scaling); +} + +const btVector3& btConvex2dShape::getLocalScaling() const +{ + return m_childConvexShape->getLocalScaling(); +} + +void btConvex2dShape::setMargin(btScalar margin) +{ + m_childConvexShape->setMargin(margin); +} +btScalar btConvex2dShape::getMargin() const +{ + return m_childConvexShape->getMargin(); +} + +int btConvex2dShape::getNumPreferredPenetrationDirections() const +{ + return m_childConvexShape->getNumPreferredPenetrationDirections(); +} + +void btConvex2dShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const +{ + m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector); +} diff --git a/src/BulletCollision/CollisionShapes/btConvex2dShape.h b/src/BulletCollision/CollisionShapes/btConvex2dShape.h new file mode 100644 index 0000000..bbd1caf --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvex2dShape.h @@ -0,0 +1,82 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_2D_SHAPE_H +#define BT_CONVEX_2D_SHAPE_H + +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types + +///The btConvex2dShape allows to use arbitrary convex shapes as 2d convex shapes, with the Z component assumed to be 0. +///For 2d boxes, the btBox2dShape is recommended. +ATTRIBUTE_ALIGNED16(class) btConvex2dShape : public btConvexShape +{ + btConvexShape* m_childConvexShape; + + public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btConvex2dShape( btConvexShape* convexChildShape); + + virtual ~btConvex2dShape(); + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + btConvexShape* getChildShape() + { + return m_childConvexShape; + } + + const btConvexShape* getChildShape() const + { + return m_childConvexShape; + } + + virtual const char* getName()const + { + return "Convex2dShape"; + } + + + + /////////////////////////// + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void setLocalScaling(const btVector3& scaling) ; + virtual const btVector3& getLocalScaling() const ; + + virtual void setMargin(btScalar margin); + virtual btScalar getMargin() const; + + virtual int getNumPreferredPenetrationDirections() const; + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; + + +}; + +#endif //BT_CONVEX_2D_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp b/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp new file mode 100644 index 0000000..4d0ca14 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp @@ -0,0 +1,245 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConvexHullShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btSerializer.h" + +btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape () +{ + m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE; + m_unscaledPoints.resize(numPoints); + + unsigned char* pointsAddress = (unsigned char*)points; + + for (int i=0;im_convexInternalShapeData, serializer); + + int numElem = m_unscaledPoints.size(); + shapeData->m_numUnscaledPoints = numElem; +#ifdef BT_USE_DOUBLE_PRECISION + shapeData->m_unscaledPointsFloatPtr = 0; + shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0; +#else + shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0; + shapeData->m_unscaledPointsDoublePtr = 0; +#endif + + if (numElem) + { + int sz = sizeof(btVector3Data); + // int sz2 = sizeof(btVector3DoubleData); + // int sz3 = sizeof(btVector3FloatData); + btChunk* chunk = serializer->allocate(sz,numElem); + btVector3Data* memPtr = (btVector3Data*)chunk->m_oldPtr; + for (int i=0;ifinalizeChunk(chunk,btVector3DataName,BT_ARRAY_CODE,(void*)&m_unscaledPoints[0]); + } + + return "btConvexHullShapeData"; +} + +void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const +{ +#if 1 + minProj = FLT_MAX; + maxProj = -FLT_MAX; + + int numVerts = m_unscaledPoints.size(); + for(int i=0;i maxProj) + { + maxProj = dp; + witnesPtMax=pt; + } + } +#else + btVector3 localAxis = dir*trans.getBasis(); + witnesPtMin = trans(localGetSupportingVertex(localAxis)); + witnesPtMax = trans(localGetSupportingVertex(-localAxis)); + + minProj = witnesPtMin.dot(dir); + maxProj = witnesPtMax.dot(dir); +#endif + + if(minProj>maxProj) + { + btSwap(minProj,maxProj); + btSwap(witnesPtMin,witnesPtMax); + } + + +} + + diff --git a/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/src/BulletCollision/CollisionShapes/btConvexHullShape.h new file mode 100644 index 0000000..f4e8f64 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexHullShape.h @@ -0,0 +1,122 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_HULL_SHAPE_H +#define BT_CONVEX_HULL_SHAPE_H + +#include "btPolyhedralConvexShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "LinearMath/btAlignedObjectArray.h" + + +///The btConvexHullShape implements an implicit convex hull of an array of vertices. +///Bullet provides a general and fast collision detector for convex shapes based on GJK and EPA using localGetSupportingVertex. +ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexAabbCachingShape +{ + btAlignedObjectArray m_unscaledPoints; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + + ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory. + ///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint. + ///btConvexHullShape make an internal copy of the points. + btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3)); + + void addPoint(const btVector3& point); + + + btVector3* getUnscaledPoints() + { + return &m_unscaledPoints[0]; + } + + const btVector3* getUnscaledPoints() const + { + return &m_unscaledPoints[0]; + } + + ///getPoints is obsolete, please use getUnscaledPoints + const btVector3* getPoints() const + { + return getUnscaledPoints(); + } + + + + + SIMD_FORCE_INLINE btVector3 getScaledPoint(int i) const + { + return m_unscaledPoints[i] * m_localScaling; + } + + SIMD_FORCE_INLINE int getNumPoints() const + { + return m_unscaledPoints.size(); + } + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + + virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const; + + + //debugging + virtual const char* getName()const {return "Convex";} + + + virtual int getNumVertices() const; + virtual int getNumEdges() const; + virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; + virtual void getVertex(int i,btVector3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; + virtual bool isInside(const btVector3& pt,btScalar tolerance) const; + + ///in case we receive negative scaling + virtual void setLocalScaling(const btVector3& scaling); + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btConvexHullShapeData +{ + btConvexInternalShapeData m_convexInternalShapeData; + + btVector3FloatData *m_unscaledPointsFloatPtr; + btVector3DoubleData *m_unscaledPointsDoublePtr; + + int m_numUnscaledPoints; + char m_padding3[4]; + +}; + + +SIMD_FORCE_INLINE int btConvexHullShape::calculateSerializeBufferSize() const +{ + return sizeof(btConvexHullShapeData); +} + + +#endif //BT_CONVEX_HULL_SHAPE_H + diff --git a/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp b/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp new file mode 100644 index 0000000..083d60b --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp @@ -0,0 +1,151 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btConvexInternalShape.h" + + + +btConvexInternalShape::btConvexInternalShape() +: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), +m_collisionMargin(CONVEX_DISTANCE_MARGIN) +{ +} + + +void btConvexInternalShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling.absolute(); +} + + + +void btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const +{ +#ifndef __SPU__ + //use localGetSupportingVertexWithoutMargin? + btScalar margin = getMargin(); + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + + btVector3 sv = localGetSupportingVertex(vec*trans.getBasis()); + + btVector3 tmp = trans(sv); + maxAabb[i] = tmp[i]+margin; + vec[i] = btScalar(-1.); + tmp = trans(localGetSupportingVertex(vec*trans.getBasis())); + minAabb[i] = tmp[i]-margin; + } +#endif +} + + + +btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const +{ +#ifndef __SPU__ + + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + + if ( getMargin()!=btScalar(0.) ) + { + btVector3 vecnorm = vec; + if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + vecnorm.normalize(); + supVertex+= getMargin() * vecnorm; + } + return supVertex; + +#else + btAssert(0); + return btVector3(0,0,0); +#endif //__SPU__ + + } + + +btConvexInternalAabbCachingShape::btConvexInternalAabbCachingShape() + : btConvexInternalShape(), +m_localAabbMin(1,1,1), +m_localAabbMax(-1,-1,-1), +m_isLocalAabbValid(false) +{ +} + + +void btConvexInternalAabbCachingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin()); +} + +void btConvexInternalAabbCachingShape::setLocalScaling(const btVector3& scaling) +{ + btConvexInternalShape::setLocalScaling(scaling); + recalcLocalAabb(); +} + + +void btConvexInternalAabbCachingShape::recalcLocalAabb() +{ + m_isLocalAabbValid = true; + + #if 1 + static const btVector3 _directions[] = + { + btVector3( 1., 0., 0.), + btVector3( 0., 1., 0.), + btVector3( 0., 0., 1.), + btVector3( -1., 0., 0.), + btVector3( 0., -1., 0.), + btVector3( 0., 0., -1.) + }; + + btVector3 _supporting[] = + { + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.) + }; + + batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6); + + for ( int i = 0; i < 3; ++i ) + { + m_localAabbMax[i] = _supporting[i][i] + m_collisionMargin; + m_localAabbMin[i] = _supporting[i + 3][i] - m_collisionMargin; + } + + #else + + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + btVector3 tmp = localGetSupportingVertex(vec); + m_localAabbMax[i] = tmp[i]+m_collisionMargin; + vec[i] = btScalar(-1.); + tmp = localGetSupportingVertex(vec); + m_localAabbMin[i] = tmp[i]-m_collisionMargin; + } + #endif +} diff --git a/src/BulletCollision/CollisionShapes/btConvexInternalShape.h b/src/BulletCollision/CollisionShapes/btConvexInternalShape.h new file mode 100644 index 0000000..37e04f5 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexInternalShape.h @@ -0,0 +1,224 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_INTERNAL_SHAPE_H +#define BT_CONVEX_INTERNAL_SHAPE_H + +#include "btConvexShape.h" +#include "LinearMath/btAabbUtil2.h" + + +///The btConvexInternalShape is an internal base class, shared by most convex shape implementations. +///The btConvexInternalShape uses a default collision margin set to CONVEX_DISTANCE_MARGIN. +///This collision margin used by Gjk and some other algorithms, see also btCollisionMargin.h +///Note that when creating small shapes (derived from btConvexInternalShape), +///you need to make sure to set a smaller collision margin, using the 'setMargin' API +///There is a automatic mechanism 'setSafeMargin' used by btBoxShape and btCylinderShape +ATTRIBUTE_ALIGNED16(class) btConvexInternalShape : public btConvexShape +{ + + protected: + + //local scaling. collisionMargin is not scaled ! + btVector3 m_localScaling; + + btVector3 m_implicitShapeDimensions; + + btScalar m_collisionMargin; + + btScalar m_padding; + + btConvexInternalShape(); + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + virtual ~btConvexInternalShape() + { + + } + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + + const btVector3& getImplicitShapeDimensions() const + { + return m_implicitShapeDimensions; + } + + ///warning: use setImplicitShapeDimensions with care + ///changing a collision shape while the body is in the world is not recommended, + ///it is best to remove the body from the world, then make the change, and re-add it + ///alternatively flush the contact points, see documentation for 'cleanProxyFromPairs' + void setImplicitShapeDimensions(const btVector3& dimensions) + { + m_implicitShapeDimensions = dimensions; + } + + void setSafeMargin(btScalar minDimension, btScalar defaultMarginMultiplier = 0.1f) + { + btScalar safeMargin = defaultMarginMultiplier*minDimension; + if (safeMargin < getMargin()) + { + setMargin(safeMargin); + } + } + void setSafeMargin(const btVector3& halfExtents, btScalar defaultMarginMultiplier = 0.1f) + { + //see http://code.google.com/p/bullet/issues/detail?id=349 + //this margin check could could be added to other collision shapes too, + //or add some assert/warning somewhere + btScalar minDimension=halfExtents[halfExtents.minAxis()]; + setSafeMargin(minDimension, defaultMarginMultiplier); + } + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + getAabbSlow(t,aabbMin,aabbMax); + } + + + + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const + { + return m_localScaling; + } + + const btVector3& getLocalScalingNV() const + { + return m_localScaling; + } + + virtual void setMargin(btScalar margin) + { + m_collisionMargin = margin; + } + virtual btScalar getMargin() const + { + return m_collisionMargin; + } + + btScalar getMarginNV() const + { + return m_collisionMargin; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 0; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + (void)penetrationVector; + (void)index; + btAssert(0); + } + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btConvexInternalShapeData +{ + btCollisionShapeData m_collisionShapeData; + + btVector3FloatData m_localScaling; + + btVector3FloatData m_implicitShapeDimensions; + + float m_collisionMargin; + + int m_padding; + +}; + + + +SIMD_FORCE_INLINE int btConvexInternalShape::calculateSerializeBufferSize() const +{ + return sizeof(btConvexInternalShapeData); +} + +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btConvexInternalShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btConvexInternalShapeData* shapeData = (btConvexInternalShapeData*) dataBuffer; + btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer); + + m_implicitShapeDimensions.serializeFloat(shapeData->m_implicitShapeDimensions); + m_localScaling.serializeFloat(shapeData->m_localScaling); + shapeData->m_collisionMargin = float(m_collisionMargin); + + return "btConvexInternalShapeData"; +} + + + + +///btConvexInternalAabbCachingShape adds local aabb caching for convex shapes, to avoid expensive bounding box calculations +class btConvexInternalAabbCachingShape : public btConvexInternalShape +{ + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + bool m_isLocalAabbValid; + +protected: + + btConvexInternalAabbCachingShape(); + + void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax) + { + m_isLocalAabbValid = true; + m_localAabbMin = aabbMin; + m_localAabbMax = aabbMax; + } + + inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const + { + btAssert(m_isLocalAabbValid); + aabbMin = m_localAabbMin; + aabbMax = m_localAabbMax; + } + + inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const + { + + //lazy evaluation of local aabb + btAssert(m_isLocalAabbValid); + btTransformAabb(m_localAabbMin,m_localAabbMax,margin,trans,aabbMin,aabbMax); + } + +public: + + virtual void setLocalScaling(const btVector3& scaling); + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + void recalcLocalAabb(); + +}; + +#endif //BT_CONVEX_INTERNAL_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp new file mode 100644 index 0000000..ad1d1bf --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp @@ -0,0 +1,139 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConvexPointCloudShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "LinearMath/btQuaternion.h" + +void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; + recalcLocalAabb(); +} + +#ifndef __SPU__ +btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +{ + btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.)); + btScalar maxDot = btScalar(-BT_LARGE_FLOAT); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + + if( m_numPoints > 0 ) + { + // Here we take advantage of dot(a*b, c) = dot( a, b*c) to do less work. Note this transformation is true mathematically, not numerically. + // btVector3 scaled = vec * m_localScaling; + int index = (int) vec.maxDot( &m_unscaledPoints[0], m_numPoints, maxDot); //FIXME: may violate encapsulation of m_unscaledPoints + return getScaledPoint(index); + } + + return supVec; +} + +void btConvexPointCloudShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + for( int j = 0; j < numVectors; j++ ) + { + const btVector3& vec = vectors[j] * m_localScaling; // dot( a*c, b) = dot(a, b*c) + btScalar maxDot; + int index = (int) vec.maxDot( &m_unscaledPoints[0], m_numPoints, maxDot); + supportVerticesOut[j][3] = btScalar(-BT_LARGE_FLOAT); + if( 0 <= index ) + { + //WARNING: don't swap next lines, the w component would get overwritten! + supportVerticesOut[j] = getScaledPoint(index); + supportVerticesOut[j][3] = maxDot; + } + } + +} + + + +btVector3 btConvexPointCloudShape::localGetSupportingVertex(const btVector3& vec)const +{ + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + + if ( getMargin()!=btScalar(0.) ) + { + btVector3 vecnorm = vec; + if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + vecnorm.normalize(); + supVertex+= getMargin() * vecnorm; + } + return supVertex; +} + + +#endif + + + + + + +//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection +//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo +int btConvexPointCloudShape::getNumVertices() const +{ + return m_numPoints; +} + +int btConvexPointCloudShape::getNumEdges() const +{ + return 0; +} + +void btConvexPointCloudShape::getEdge(int i,btVector3& pa,btVector3& pb) const +{ + btAssert (0); +} + +void btConvexPointCloudShape::getVertex(int i,btVector3& vtx) const +{ + vtx = m_unscaledPoints[i]*m_localScaling; +} + +int btConvexPointCloudShape::getNumPlanes() const +{ + return 0; +} + +void btConvexPointCloudShape::getPlane(btVector3& ,btVector3& ,int ) const +{ + + btAssert(0); +} + +//not yet +bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const +{ + btAssert(0); + return false; +} + diff --git a/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h new file mode 100644 index 0000000..54b5afa --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h @@ -0,0 +1,105 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_POINT_CLOUD_SHAPE_H +#define BT_CONVEX_POINT_CLOUD_SHAPE_H + +#include "btPolyhedralConvexShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "LinearMath/btAlignedObjectArray.h" + +///The btConvexPointCloudShape implements an implicit convex hull of an array of vertices. +ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexAabbCachingShape +{ + btVector3* m_unscaledPoints; + int m_numPoints; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btConvexPointCloudShape() + { + m_localScaling.setValue(1.f,1.f,1.f); + m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE; + m_unscaledPoints = 0; + m_numPoints = 0; + } + + btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true) + { + m_localScaling = localScaling; + m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE; + m_unscaledPoints = points; + m_numPoints = numPoints; + + if (computeAabb) + recalcLocalAabb(); + } + + void setPoints (btVector3* points, int numPoints, bool computeAabb = true,const btVector3& localScaling=btVector3(1.f,1.f,1.f)) + { + m_unscaledPoints = points; + m_numPoints = numPoints; + m_localScaling = localScaling; + + if (computeAabb) + recalcLocalAabb(); + } + + SIMD_FORCE_INLINE btVector3* getUnscaledPoints() + { + return m_unscaledPoints; + } + + SIMD_FORCE_INLINE const btVector3* getUnscaledPoints() const + { + return m_unscaledPoints; + } + + SIMD_FORCE_INLINE int getNumPoints() const + { + return m_numPoints; + } + + SIMD_FORCE_INLINE btVector3 getScaledPoint( int index) const + { + return m_unscaledPoints[index] * m_localScaling; + } + +#ifndef __SPU__ + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; +#endif + + + //debugging + virtual const char* getName()const {return "ConvexPointCloud";} + + virtual int getNumVertices() const; + virtual int getNumEdges() const; + virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; + virtual void getVertex(int i,btVector3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; + virtual bool isInside(const btVector3& pt,btScalar tolerance) const; + + ///in case we receive negative scaling + virtual void setLocalScaling(const btVector3& scaling); +}; + + +#endif //BT_CONVEX_POINT_CLOUD_SHAPE_H + diff --git a/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp new file mode 100644 index 0000000..c31df91 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp @@ -0,0 +1,302 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +///This file was written by Erwin Coumans +///Separating axis rest based on work from Pierre Terdiman, see +///And contact clipping based on work from Simon Hobbs + +#include "btConvexPolyhedron.h" +#include "LinearMath/btHashMap.h" + +btConvexPolyhedron::btConvexPolyhedron() +{ + +} +btConvexPolyhedron::~btConvexPolyhedron() +{ + +} + + +inline bool IsAlmostZero(const btVector3& v) +{ + if(fabsf(v.x())>1e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false; + return true; +} + +struct btInternalVertexPair +{ + btInternalVertexPair(short int v0,short int v1) + :m_v0(v0), + m_v1(v1) + { + if (m_v1>m_v0) + btSwap(m_v0,m_v1); + } + short int m_v0; + short int m_v1; + int getHash() const + { + return m_v0+(m_v1<<16); + } + bool equals(const btInternalVertexPair& other) const + { + return m_v0==other.m_v0 && m_v1==other.m_v1; + } +}; + +struct btInternalEdge +{ + btInternalEdge() + :m_face0(-1), + m_face1(-1) + { + } + short int m_face0; + short int m_face1; +}; + +// + +#ifdef TEST_INTERNAL_OBJECTS +bool btConvexPolyhedron::testContainment() const +{ + for(int p=0;p<8;p++) + { + btVector3 LocalPt; + if(p==0) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], m_extents[2]); + else if(p==1) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], -m_extents[2]); + else if(p==2) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], m_extents[2]); + else if(p==3) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], -m_extents[2]); + else if(p==4) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], m_extents[2]); + else if(p==5) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], -m_extents[2]); + else if(p==6) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], m_extents[2]); + else if(p==7) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], -m_extents[2]); + + for(int i=0;i0.0f) + return false; + } + } + return true; +} +#endif + +void btConvexPolyhedron::initialize() +{ + + btHashMap edges; + + btScalar TotalArea = 0.0f; + + m_localCenter.setValue(0, 0, 0); + for(int i=0;im_face0>=0); + btAssert(edptr->m_face1<0); + edptr->m_face1 = i; + } else + { + btInternalEdge ed; + ed.m_face0 = i; + edges.insert(vp,ed); + } + } + } + +#ifdef USE_CONNECTED_FACES + for(int i=0;im_face0>=0); + btAssert(edptr->m_face1>=0); + + int connectedFace = (edptr->m_face0==i)?edptr->m_face1:edptr->m_face0; + m_faces[i].m_connectedFaces[j] = connectedFace; + } + } +#endif//USE_CONNECTED_FACES + + for(int i=0;iMaxX) MaxX = pt.x(); + if(pt.y()MaxY) MaxY = pt.y(); + if(pt.z()MaxZ) MaxZ = pt.z(); + } + mC.setValue(MaxX+MinX, MaxY+MinY, MaxZ+MinZ); + mE.setValue(MaxX-MinX, MaxY-MinY, MaxZ-MinZ); + + + +// const btScalar r = m_radius / sqrtf(2.0f); + const btScalar r = m_radius / sqrtf(3.0f); + const int LargestExtent = mE.maxAxis(); + const btScalar Step = (mE[LargestExtent]*0.5f - r)/1024.0f; + m_extents[0] = m_extents[1] = m_extents[2] = r; + m_extents[LargestExtent] = mE[LargestExtent]*0.5f; + bool FoundBox = false; + for(int j=0;j<1024;j++) + { + if(testContainment()) + { + FoundBox = true; + break; + } + + m_extents[LargestExtent] -= Step; + } + if(!FoundBox) + { + m_extents[0] = m_extents[1] = m_extents[2] = r; + } + else + { + // Refine the box + const btScalar Step = (m_radius - r)/1024.0f; + const int e0 = (1< maxProj) + { + maxProj = dp; + witnesPtMax = pt; + } + } + if(minProj>maxProj) + { + btSwap(minProj,maxProj); + btSwap(witnesPtMin,witnesPtMax); + } +} diff --git a/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h new file mode 100644 index 0000000..75679eb --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h @@ -0,0 +1,65 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +///This file was written by Erwin Coumans + + +#ifndef _BT_POLYHEDRAL_FEATURES_H +#define _BT_POLYHEDRAL_FEATURES_H + +#include "LinearMath/btTransform.h" +#include "LinearMath/btAlignedObjectArray.h" + +#define TEST_INTERNAL_OBJECTS 1 + + +struct btFace +{ + btAlignedObjectArray m_indices; +// btAlignedObjectArray m_connectedFaces; + btScalar m_plane[4]; +}; + + +ATTRIBUTE_ALIGNED16(class) btConvexPolyhedron +{ + public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btConvexPolyhedron(); + virtual ~btConvexPolyhedron(); + + btAlignedObjectArray m_vertices; + btAlignedObjectArray m_faces; + btAlignedObjectArray m_uniqueEdges; + + btVector3 m_localCenter; + btVector3 m_extents; + btScalar m_radius; + btVector3 mC; + btVector3 mE; + + void initialize(); + bool testContainment() const; + + void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const; +}; + + +#endif //_BT_POLYHEDRAL_FEATURES_H + + diff --git a/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/src/BulletCollision/CollisionShapes/btConvexShape.cpp new file mode 100644 index 0000000..3ffa422 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexShape.cpp @@ -0,0 +1,445 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConvexShape.h" +#include "btTriangleShape.h" +#include "btSphereShape.h" +#include "btCylinderShape.h" +#include "btCapsuleShape.h" +#include "btConvexHullShape.h" +#include "btConvexPointCloudShape.h" + +///not supported on IBM SDK, until we fix the alignment of btVector3 +#if defined (__CELLOS_LV2__) && defined (__SPU__) +#include +static inline vec_float4 vec_dot3( vec_float4 vec0, vec_float4 vec1 ) +{ + vec_float4 result; + result = spu_mul( vec0, vec1 ); + result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); + return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result ); +} +#endif //__SPU__ + +btConvexShape::btConvexShape () +{ +} + +btConvexShape::~btConvexShape() +{ + +} + + +void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const +{ + btVector3 localAxis = dir*trans.getBasis(); + btVector3 vtx1 = trans(localGetSupportingVertex(localAxis)); + btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis)); + + min = vtx1.dot(dir); + max = vtx2.dot(dir); + + if(min>max) + { + btScalar tmp = min; + min = max; + max = tmp; + } +} + + +static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling) +{ + + btVector3 vec = localDirOrg * localScaling; + +#if defined (__CELLOS_LV2__) && defined (__SPU__) + + btVector3 localDir = vec; + + vec_float4 v_distMax = {-FLT_MAX,0,0,0}; + vec_int4 v_idxMax = {-999,0,0,0}; + int v=0; + int numverts = numPoints; + + for(;v<(int)numverts-4;v+=4) { + vec_float4 p0 = vec_dot3(points[v ].get128(),localDir.get128()); + vec_float4 p1 = vec_dot3(points[v+1].get128(),localDir.get128()); + vec_float4 p2 = vec_dot3(points[v+2].get128(),localDir.get128()); + vec_float4 p3 = vec_dot3(points[v+3].get128(),localDir.get128()); + const vec_int4 i0 = {v ,0,0,0}; + const vec_int4 i1 = {v+1,0,0,0}; + const vec_int4 i2 = {v+2,0,0,0}; + const vec_int4 i3 = {v+3,0,0,0}; + vec_uint4 retGt01 = spu_cmpgt(p0,p1); + vec_float4 pmax01 = spu_sel(p1,p0,retGt01); + vec_int4 imax01 = spu_sel(i1,i0,retGt01); + vec_uint4 retGt23 = spu_cmpgt(p2,p3); + vec_float4 pmax23 = spu_sel(p3,p2,retGt23); + vec_int4 imax23 = spu_sel(i3,i2,retGt23); + vec_uint4 retGt0123 = spu_cmpgt(pmax01,pmax23); + vec_float4 pmax0123 = spu_sel(pmax23,pmax01,retGt0123); + vec_int4 imax0123 = spu_sel(imax23,imax01,retGt0123); + vec_uint4 retGtMax = spu_cmpgt(v_distMax,pmax0123); + v_distMax = spu_sel(pmax0123,v_distMax,retGtMax); + v_idxMax = spu_sel(imax0123,v_idxMax,retGtMax); + } + for(;v<(int)numverts;v++) { + vec_float4 p = vec_dot3(points[v].get128(),localDir.get128()); + const vec_int4 i = {v,0,0,0}; + vec_uint4 retGtMax = spu_cmpgt(v_distMax,p); + v_distMax = spu_sel(p,v_distMax,retGtMax); + v_idxMax = spu_sel(i,v_idxMax,retGtMax); + } + int ptIndex = spu_extract(v_idxMax,0); + const btVector3& supVec= points[ptIndex] * localScaling; + return supVec; +#else + + btScalar maxDot; + long ptIndex = vec.maxDot( points, numPoints, maxDot); + btAssert(ptIndex >= 0); + btVector3 supVec = points[ptIndex] * localScaling; + return supVec; +#endif //__SPU__ +} + +btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const +{ + switch (m_shapeType) + { + case SPHERE_SHAPE_PROXYTYPE: + { + return btVector3(0,0,0); + } + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* convexShape = (btBoxShape*)this; + const btVector3& halfExtents = convexShape->getImplicitShapeDimensions(); + +#if defined( __APPLE__ ) && (defined( BT_USE_SSE )||defined( BT_USE_NEON )) + #if defined( BT_USE_SSE ) + return btVector3( _mm_xor_ps( _mm_and_ps( localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f }), halfExtents.mVec128 )); + #elif defined( BT_USE_NEON ) + return btVector3( (float32x4_t) (((uint32x4_t) localDir.mVec128 & (uint32x4_t){ 0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t) halfExtents.mVec128 )); + #else + #error unknown vector arch + #endif +#else + return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()), + btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()), + btFsels(localDir.z(), halfExtents.z(), -halfExtents.z())); +#endif + } + case TRIANGLE_SHAPE_PROXYTYPE: + { + btTriangleShape* triangleShape = (btTriangleShape*)this; + btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ()); + btVector3* vertices = &triangleShape->m_vertices1[0]; + btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]); + btVector3 sup = vertices[dots.maxAxis()]; + return btVector3(sup.getX(),sup.getY(),sup.getZ()); + } + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShape* cylShape = (btCylinderShape*)this; + //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis) + + btVector3 halfExtents = cylShape->getImplicitShapeDimensions(); + btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ()); + int cylinderUpAxis = cylShape->getUpAxis(); + int XX(1),YY(0),ZZ(2); + + switch (cylinderUpAxis) + { + case 0: + { + XX = 1; + YY = 0; + ZZ = 2; + } + break; + case 1: + { + XX = 0; + YY = 1; + ZZ = 2; + } + break; + case 2: + { + XX = 0; + YY = 2; + ZZ = 1; + + } + break; + default: + btAssert(0); + break; + }; + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + btVector3 tmp; + btScalar d ; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()); + } else { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()); + } + } + case CAPSULE_SHAPE_PROXYTYPE: + { + btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ()); + + btCapsuleShape* capsuleShape = (btCapsuleShape*)this; + btScalar halfHeight = capsuleShape->getHalfHeight(); + int capsuleUpAxis = capsuleShape->getUpAxis(); + + btScalar radius = capsuleShape->getRadius(); + btVector3 supVec(0,0,0); + + btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + btVector3 vtx; + btScalar newDot; + { + btVector3 pos(0,0,0); + pos[capsuleUpAxis] = halfHeight; + + //vtx = pos +vec*(radius); + vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV(); + newDot = vec.dot(vtx); + + + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + { + btVector3 pos(0,0,0); + pos[capsuleUpAxis] = -halfHeight; + + //vtx = pos +vec*(radius); + vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV(); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + return btVector3(supVec.getX(),supVec.getY(),supVec.getZ()); + } + case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + { + btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this; + btVector3* points = convexPointCloudShape->getUnscaledPoints (); + int numPoints = convexPointCloudShape->getNumPoints (); + return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV()); + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexHullShape* convexHullShape = (btConvexHullShape*)this; + btVector3* points = convexHullShape->getUnscaledPoints(); + int numPoints = convexHullShape->getNumPoints (); + return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV()); + } + default: +#ifndef __SPU__ + return this->localGetSupportingVertexWithoutMargin (localDir); +#else + btAssert (0); +#endif + } + + // should never reach here + btAssert (0); + return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f)); +} + +btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const +{ + btVector3 localDirNorm = localDir; + if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + localDirNorm.normalize (); + + return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm; +} + +/* TODO: This should be bumped up to btCollisionShape () */ +btScalar btConvexShape::getMarginNonVirtual () const +{ + switch (m_shapeType) + { + case SPHERE_SHAPE_PROXYTYPE: + { + btSphereShape* sphereShape = (btSphereShape*)this; + return sphereShape->getRadius (); + } + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* convexShape = (btBoxShape*)this; + return convexShape->getMarginNV (); + } + case TRIANGLE_SHAPE_PROXYTYPE: + { + btTriangleShape* triangleShape = (btTriangleShape*)this; + return triangleShape->getMarginNV (); + } + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShape* cylShape = (btCylinderShape*)this; + return cylShape->getMarginNV(); + } + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShape* capsuleShape = (btCapsuleShape*)this; + return capsuleShape->getMarginNV(); + } + case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + /* fall through */ + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this; + return convexHullShape->getMarginNV(); + } + default: +#ifndef __SPU__ + return this->getMargin (); +#else + btAssert (0); +#endif + } + + // should never reach here + btAssert (0); + return btScalar(0.0f); +} +#ifndef __SPU__ +void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const +{ + switch (m_shapeType) + { + case SPHERE_SHAPE_PROXYTYPE: + { + btSphereShape* sphereShape = (btSphereShape*)this; + btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX(); + btScalar margin = radius + sphereShape->getMarginNonVirtual(); + const btVector3& center = t.getOrigin(); + btVector3 extent(margin,margin,margin); + aabbMin = center - extent; + aabbMax = center + extent; + } + break; + case CYLINDER_SHAPE_PROXYTYPE: + /* fall through */ + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* convexShape = (btBoxShape*)this; + btScalar margin=convexShape->getMarginNonVirtual(); + btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); + halfExtents += btVector3(margin,margin,margin); + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + + aabbMin = center - extent; + aabbMax = center + extent; + break; + } + case TRIANGLE_SHAPE_PROXYTYPE: + { + btTriangleShape* triangleShape = (btTriangleShape*)this; + btScalar margin = triangleShape->getMarginNonVirtual(); + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + + btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()); + + btVector3 tmp = t(sv); + aabbMax[i] = tmp[i]+margin; + vec[i] = btScalar(-1.); + tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis())); + aabbMin[i] = tmp[i]-margin; + } + } + break; + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShape* capsuleShape = (btCapsuleShape*)this; + btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius()); + int m_upAxis = capsuleShape->getUpAxis(); + halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight(); + halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual()); + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMin = center - extent; + aabbMax = center + extent; + } + break; + case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this; + btScalar margin = convexHullShape->getMarginNonVirtual(); + convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin); + } + break; + default: +#ifndef __SPU__ + this->getAabb (t, aabbMin, aabbMax); +#else + btAssert (0); +#endif + break; + } + + // should never reach here + btAssert (0); +} + +#endif //__SPU__ diff --git a/src/BulletCollision/CollisionShapes/btConvexShape.h b/src/BulletCollision/CollisionShapes/btConvexShape.h new file mode 100644 index 0000000..290cd9f --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexShape.h @@ -0,0 +1,84 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_SHAPE_INTERFACE1 +#define BT_CONVEX_SHAPE_INTERFACE1 + +#include "btCollisionShape.h" + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" +#include "btCollisionMargin.h" +#include "LinearMath/btAlignedAllocator.h" + +#define MAX_PREFERRED_PENETRATION_DIRECTIONS 10 + +/// The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape, btConvexHullShape etc. +/// It describes general convex shapes using the localGetSupportingVertex interface, used by collision detectors such as btGjkPairDetector. +ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape +{ + + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btConvexShape (); + + virtual ~btConvexShape(); + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const = 0; + + //////// + #ifndef __SPU__ + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const=0; + #endif //#ifndef __SPU__ + + btVector3 localGetSupportVertexWithoutMarginNonVirtual (const btVector3& vec) const; + btVector3 localGetSupportVertexNonVirtual (const btVector3& vec) const; + btScalar getMarginNonVirtual () const; + void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; + + virtual void project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const; + + + //notice that the vectors should be unit length + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + + virtual void setLocalScaling(const btVector3& scaling) =0; + virtual const btVector3& getLocalScaling() const =0; + + virtual void setMargin(btScalar margin)=0; + + virtual btScalar getMargin() const=0; + + virtual int getNumPreferredPenetrationDirections() const=0; + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0; + + + + +}; + + + +#endif //BT_CONVEX_SHAPE_INTERFACE1 diff --git a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp new file mode 100644 index 0000000..0f9ced5 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp @@ -0,0 +1,315 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "LinearMath/btQuaternion.h" +#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h" + + +btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb) +: btPolyhedralConvexAabbCachingShape(), m_stridingMesh(meshInterface) +{ + m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; + if ( calcAabb ) + recalcLocalAabb(); +} + + + + +///It's not nice to have all this virtual function overhead, so perhaps we can also gather the points once +///but then we are duplicating +class LocalSupportVertexCallback: public btInternalTriangleIndexCallback +{ + + btVector3 m_supportVertexLocal; +public: + + btScalar m_maxDot; + btVector3 m_supportVecLocal; + + LocalSupportVertexCallback(const btVector3& supportVecLocal) + : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), + m_maxDot(btScalar(-BT_LARGE_FLOAT)), + m_supportVecLocal(supportVecLocal) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + (void)triangleIndex; + (void)partId; + + for (int i=0;i<3;i++) + { + btScalar dot = m_supportVecLocal.dot(triangle[i]); + if (dot > m_maxDot) + { + m_maxDot = dot; + m_supportVertexLocal = triangle[i]; + } + } + } + + btVector3 GetSupportVertexLocal() + { + return m_supportVertexLocal; + } + +}; + + + + + +btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +{ + btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + + LocalSupportVertexCallback supportCallback(vec); + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); + supVec = supportCallback.GetSupportVertexLocal(); + + return supVec; +} + +void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + //use 'w' component of supportVerticesOut? + { + for (int i=0;iInternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); + supportVerticesOut[j] = supportCallback.GetSupportVertexLocal(); + } + +} + + + +btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec)const +{ + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + + if ( getMargin()!=btScalar(0.) ) + { + btVector3 vecnorm = vec; + if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + vecnorm.normalize(); + supVertex+= getMargin() * vecnorm; + } + return supVertex; +} + + + + + + + + + +//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection +//Please note that you can debug-draw btConvexTriangleMeshShape with the Raytracer Demo +int btConvexTriangleMeshShape::getNumVertices() const +{ + //cache this? + return 0; + +} + +int btConvexTriangleMeshShape::getNumEdges() const +{ + return 0; +} + +void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const +{ + btAssert(0); +} + +void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const +{ + btAssert(0); +} + +int btConvexTriangleMeshShape::getNumPlanes() const +{ + return 0; +} + +void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int ) const +{ + btAssert(0); +} + +//not yet +bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const +{ + btAssert(0); + return false; +} + + + +void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling) +{ + m_stridingMesh->setScaling(scaling); + + recalcLocalAabb(); + +} + + +const btVector3& btConvexTriangleMeshShape::getLocalScaling() const +{ + return m_stridingMesh->getScaling(); +} + +void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const +{ + class CenterCallback: public btInternalTriangleIndexCallback + { + bool first; + btVector3 ref; + btVector3 sum; + btScalar volume; + + public: + + CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) + { + (void) triangleIndex; + (void) partId; + if (first) + { + ref = triangle[0]; + first = false; + } + else + { + btScalar vol = btFabs((triangle[0] - ref).triple(triangle[1] - ref, triangle[2] - ref)); + sum += (btScalar(0.25) * vol) * ((triangle[0] + triangle[1] + triangle[2] + ref)); + volume += vol; + } + } + + btVector3 getCenter() + { + return (volume > 0) ? sum / volume : ref; + } + + btScalar getVolume() + { + return volume * btScalar(1. / 6); + } + + }; + + class InertiaCallback: public btInternalTriangleIndexCallback + { + btMatrix3x3 sum; + btVector3 center; + + public: + + InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) + { + (void) triangleIndex; + (void) partId; + btMatrix3x3 i; + btVector3 a = triangle[0] - center; + btVector3 b = triangle[1] - center; + btVector3 c = triangle[2] - center; + btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6); + for (int j = 0; j < 3; j++) + { + for (int k = 0; k <= j; k++) + { + i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k]) + + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j])); + } + } + btScalar i00 = -i[0][0]; + btScalar i11 = -i[1][1]; + btScalar i22 = -i[2][2]; + i[0][0] = i11 + i22; + i[1][1] = i22 + i00; + i[2][2] = i00 + i11; + sum[0] += i[0]; + sum[1] += i[1]; + sum[2] += i[2]; + } + + btMatrix3x3& getInertia() + { + return sum; + } + + }; + + CenterCallback centerCallback; + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + m_stridingMesh->InternalProcessAllTriangles(¢erCallback, -aabbMax, aabbMax); + btVector3 center = centerCallback.getCenter(); + principal.setOrigin(center); + volume = centerCallback.getVolume(); + + InertiaCallback inertiaCallback(center); + m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax); + + btMatrix3x3& i = inertiaCallback.getInertia(); + i.diagonalize(principal.getBasis(), btScalar(0.00001), 20); + inertia.setValue(i[0][0], i[1][1], i[2][2]); + inertia /= volume; +} + diff --git a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h new file mode 100644 index 0000000..f338865 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h @@ -0,0 +1,77 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_CONVEX_TRIANGLEMESH_SHAPE_H +#define BT_CONVEX_TRIANGLEMESH_SHAPE_H + + +#include "btPolyhedralConvexShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types + + +/// The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good as btConvexHullShape. +/// A small benefit of this class is that it uses the btStridingMeshInterface, so you can avoid the duplication of the triangle mesh data. Nevertheless, most users should use the much better performing btConvexHullShape instead. +ATTRIBUTE_ALIGNED16(class) btConvexTriangleMeshShape : public btPolyhedralConvexAabbCachingShape +{ + + class btStridingMeshInterface* m_stridingMesh; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface, bool calcAabb = true); + + class btStridingMeshInterface* getMeshInterface() + { + return m_stridingMesh; + } + const class btStridingMeshInterface* getMeshInterface() const + { + return m_stridingMesh; + } + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + //debugging + virtual const char* getName()const {return "ConvexTrimesh";} + + virtual int getNumVertices() const; + virtual int getNumEdges() const; + virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; + virtual void getVertex(int i,btVector3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; + virtual bool isInside(const btVector3& pt,btScalar tolerance) const; + + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; + + ///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia + ///and the center of mass to the current coordinate system. A mass of 1 is assumed, for other masses just multiply the computed "inertia" + ///by the mass. The resulting transform "principal" has to be applied inversely to the mesh in order for the local coordinate system of the + ///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform + ///of the collision object by the principal transform. This method also computes the volume of the convex mesh. + void calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const; + +}; + + + +#endif //BT_CONVEX_TRIANGLEMESH_SHAPE_H + + + diff --git a/src/BulletCollision/CollisionShapes/btCylinderShape.cpp b/src/BulletCollision/CollisionShapes/btCylinderShape.cpp new file mode 100644 index 0000000..6cfe43b --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btCylinderShape.cpp @@ -0,0 +1,281 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btCylinderShape.h" + +btCylinderShape::btCylinderShape (const btVector3& halfExtents) +:btConvexInternalShape(), +m_upAxis(1) +{ + setSafeMargin(halfExtents); + + btVector3 margin(getMargin(),getMargin(),getMargin()); + m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin; + m_shapeType = CYLINDER_SHAPE_PROXYTYPE; +} + + +btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents) +:btCylinderShape(halfExtents) +{ + m_upAxis = 0; + +} + + +btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents) +:btCylinderShape(halfExtents) +{ + m_upAxis = 2; + +} + +void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax); +} + +void btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + +//Until Bullet 2.77 a box approximation was used, so uncomment this if you need backwards compatibility +//#define USE_BOX_INERTIA_APPROXIMATION 1 +#ifndef USE_BOX_INERTIA_APPROXIMATION + + /* + cylinder is defined as following: + * + * - principle axis aligned along y by default, radius in x, z-value not used + * - for btCylinderShapeX: principle axis aligned along x, radius in y direction, z-value not used + * - for btCylinderShapeZ: principle axis aligned along z, radius in x direction, y-value not used + * + */ + + btScalar radius2; // square of cylinder radius + btScalar height2; // square of cylinder height + btVector3 halfExtents = getHalfExtentsWithMargin(); // get cylinder dimension + btScalar div12 = mass / 12.f; + btScalar div4 = mass / 4.f; + btScalar div2 = mass / 2.f; + int idxRadius, idxHeight; + + switch (m_upAxis) // get indices of radius and height of cylinder + { + case 0: // cylinder is aligned along x + idxRadius = 1; + idxHeight = 0; + break; + case 2: // cylinder is aligned along z + idxRadius = 0; + idxHeight = 2; + break; + default: // cylinder is aligned along y + idxRadius = 0; + idxHeight = 1; + } + + // calculate squares + radius2 = halfExtents[idxRadius] * halfExtents[idxRadius]; + height2 = btScalar(4.) * halfExtents[idxHeight] * halfExtents[idxHeight]; + + // calculate tensor terms + btScalar t1 = div12 * height2 + div4 * radius2; + btScalar t2 = div2 * radius2; + + switch (m_upAxis) // set diagonal elements of inertia tensor + { + case 0: // cylinder is aligned along x + inertia.setValue(t2,t1,t1); + break; + case 2: // cylinder is aligned along z + inertia.setValue(t1,t1,t2); + break; + default: // cylinder is aligned along y + inertia.setValue(t1,t2,t1); + } +#else //USE_BOX_INERTIA_APPROXIMATION + //approximation of box shape + btVector3 halfExtents = getHalfExtentsWithMargin(); + + btScalar lx=btScalar(2.)*(halfExtents.x()); + btScalar ly=btScalar(2.)*(halfExtents.y()); + btScalar lz=btScalar(2.)*(halfExtents.z()); + + inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + ly*ly)); +#endif //USE_BOX_INERTIA_APPROXIMATION +} + + +SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v) +{ +const int cylinderUpAxis = 0; +const int XX = 1; +const int YY = 0; +const int ZZ = 2; + + //mapping depends on how cylinder local orientation is + // extents of the cylinder is: X,Y is for radius, and Z for height + + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + + btVector3 tmp; + btScalar d ; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return tmp; + } + + +} + + + + + + +inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v) +{ + +const int cylinderUpAxis = 1; +const int XX = 0; +const int YY = 1; +const int ZZ = 2; + + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + + btVector3 tmp; + btScalar d ; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return tmp; + } + +} + +inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v) +{ +const int cylinderUpAxis = 2; +const int XX = 0; +const int YY = 2; +const int ZZ = 1; + + //mapping depends on how cylinder local orientation is + // extents of the cylinder is: X,Y is for radius, and Z for height + + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + + btVector3 tmp; + btScalar d ; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return tmp; + } + + +} + +btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec); +} + + +btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec); +} +btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec); +} + +void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + for (int i=0;im_convexInternalShapeData,serializer); + + shapeData->m_upAxis = m_upAxis; + + return "btCylinderShapeData"; +} + + + +#endif //BT_CYLINDER_MINKOWSKI_H + diff --git a/src/BulletCollision/CollisionShapes/btEmptyShape.cpp b/src/BulletCollision/CollisionShapes/btEmptyShape.cpp new file mode 100644 index 0000000..a9e6df5 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btEmptyShape.cpp @@ -0,0 +1,50 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btEmptyShape.h" + + +#include "btCollisionShape.h" + + +btEmptyShape::btEmptyShape() : btConcaveShape () +{ + m_shapeType = EMPTY_SHAPE_PROXYTYPE; +} + + +btEmptyShape::~btEmptyShape() +{ +} + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btEmptyShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + btVector3 margin(getMargin(),getMargin(),getMargin()); + + aabbMin = t.getOrigin() - margin; + + aabbMax = t.getOrigin() + margin; + +} + +void btEmptyShape::calculateLocalInertia(btScalar ,btVector3& ) const +{ + btAssert(0); +} + + + diff --git a/src/BulletCollision/CollisionShapes/btEmptyShape.h b/src/BulletCollision/CollisionShapes/btEmptyShape.h new file mode 100644 index 0000000..069a794 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btEmptyShape.h @@ -0,0 +1,72 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_EMPTY_SHAPE_H +#define BT_EMPTY_SHAPE_H + +#include "btConcaveShape.h" + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" +#include "btCollisionMargin.h" + + + + +/// The btEmptyShape is a collision shape without actual collision detection shape, so most users should ignore this class. +/// It can be replaced by another shape during runtime, but the inertia tensor should be recomputed. +ATTRIBUTE_ALIGNED16(class) btEmptyShape : public btConcaveShape +{ +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btEmptyShape(); + + virtual ~btEmptyShape(); + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + + virtual void setLocalScaling(const btVector3& scaling) + { + m_localScaling = scaling; + } + virtual const btVector3& getLocalScaling() const + { + return m_localScaling; + } + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + virtual const char* getName()const + { + return "Empty"; + } + + virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const + { + } + +protected: + btVector3 m_localScaling; + +}; + + + +#endif //BT_EMPTY_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp new file mode 100644 index 0000000..8d4080a --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp @@ -0,0 +1,410 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btHeightfieldTerrainShape.h" + +#include "LinearMath/btTransformUtil.h" + + + +btHeightfieldTerrainShape::btHeightfieldTerrainShape +( +int heightStickWidth, int heightStickLength, const void* heightfieldData, +btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis, +PHY_ScalarType hdt, bool flipQuadEdges +) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + heightScale, minHeight, maxHeight, upAxis, hdt, + flipQuadEdges); +} + + + +btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,const void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges) +{ + // legacy constructor: support only float or unsigned char, + // and min height is zero + PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR; + btScalar minHeight = 0.0f; + + // previously, height = uchar * maxHeight / 65535. + // So to preserve legacy behavior, heightScale = maxHeight / 65535 + btScalar heightScale = maxHeight / 65535; + + initialize(heightStickWidth, heightStickLength, heightfieldData, + heightScale, minHeight, maxHeight, upAxis, hdt, + flipQuadEdges); +} + + + +void btHeightfieldTerrainShape::initialize +( +int heightStickWidth, int heightStickLength, const void* heightfieldData, +btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, +PHY_ScalarType hdt, bool flipQuadEdges +) +{ + // validation + btAssert(heightStickWidth > 1 && "bad width"); + btAssert(heightStickLength > 1 && "bad length"); + btAssert(heightfieldData && "null heightfield data"); + // btAssert(heightScale) -- do we care? Trust caller here + btAssert(minHeight <= maxHeight && "bad min/max height"); + btAssert(upAxis >= 0 && upAxis < 3 && + "bad upAxis--should be in range [0,2]"); + btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT && + "Bad height data type enum"); + + // initialize member variables + m_shapeType = TERRAIN_SHAPE_PROXYTYPE; + m_heightStickWidth = heightStickWidth; + m_heightStickLength = heightStickLength; + m_minHeight = minHeight; + m_maxHeight = maxHeight; + m_width = (btScalar) (heightStickWidth - 1); + m_length = (btScalar) (heightStickLength - 1); + m_heightScale = heightScale; + m_heightfieldDataUnknown = heightfieldData; + m_heightDataType = hdt; + m_flipQuadEdges = flipQuadEdges; + m_useDiamondSubdivision = false; + m_useZigzagSubdivision = false; + m_upAxis = upAxis; + m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.)); + + // determine min/max axis-aligned bounding box (aabb) values + switch (m_upAxis) + { + case 0: + { + m_localAabbMin.setValue(m_minHeight, 0, 0); + m_localAabbMax.setValue(m_maxHeight, m_width, m_length); + break; + } + case 1: + { + m_localAabbMin.setValue(0, m_minHeight, 0); + m_localAabbMax.setValue(m_width, m_maxHeight, m_length); + break; + }; + case 2: + { + m_localAabbMin.setValue(0, 0, m_minHeight); + m_localAabbMax.setValue(m_width, m_length, m_maxHeight); + break; + } + default: + { + //need to get valid m_upAxis + btAssert(0 && "Bad m_upAxis"); + } + } + + // remember origin (defined as exact middle of aabb) + m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax); +} + + + +btHeightfieldTerrainShape::~btHeightfieldTerrainShape() +{ +} + + + +void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5); + + btVector3 localOrigin(0, 0, 0); + localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5); + localOrigin *= m_localScaling; + + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + extent += btVector3(getMargin(),getMargin(),getMargin()); + + aabbMin = center - extent; + aabbMax = center + extent; +} + + +/// This returns the "raw" (user's initial) height, not the actual height. +/// The actual height needs to be adjusted to be relative to the center +/// of the heightfield's AABB. +btScalar +btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const +{ + btScalar val = 0.f; + switch (m_heightDataType) + { + case PHY_FLOAT: + { + val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x]; + break; + } + + case PHY_UCHAR: + { + unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x]; + val = heightFieldValue * m_heightScale; + break; + } + + case PHY_SHORT: + { + short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x]; + val = hfValue * m_heightScale; + break; + } + + default: + { + btAssert(!"Bad m_heightDataType"); + } + } + + return val; +} + + + + +/// this returns the vertex in bullet-local coordinates +void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const +{ + btAssert(x>=0); + btAssert(y>=0); + btAssert(xstartX) + startX = quantizedAabbMin[1]; + if (quantizedAabbMax[1]startJ) + startJ = quantizedAabbMin[2]; + if (quantizedAabbMax[2]startX) + startX = quantizedAabbMin[0]; + if (quantizedAabbMax[0]startJ) + startJ = quantizedAabbMin[2]; + if (quantizedAabbMax[2]startX) + startX = quantizedAabbMin[0]; + if (quantizedAabbMax[0]startJ) + startJ = quantizedAabbMin[1]; + if (quantizedAabbMax[1]processTriangle(vertices,x,j); + //second triangle + getVertex(x,j,vertices[0]); + getVertex(x+1,j+1,vertices[1]); + getVertex(x,j+1,vertices[2]); + callback->processTriangle(vertices,x,j); + } else + { + //first triangle + getVertex(x,j,vertices[0]); + getVertex(x,j+1,vertices[1]); + getVertex(x+1,j,vertices[2]); + callback->processTriangle(vertices,x,j); + //second triangle + getVertex(x+1,j,vertices[0]); + getVertex(x,j+1,vertices[1]); + getVertex(x+1,j+1,vertices[2]); + callback->processTriangle(vertices,x,j); + } + } + } + + + +} + +void btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia) const +{ + //moving concave objects not supported + + inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +} + +void btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; +} +const btVector3& btHeightfieldTerrainShape::getLocalScaling() const +{ + return m_localScaling; +} diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h new file mode 100644 index 0000000..4a7a4a4 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h @@ -0,0 +1,167 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_HEIGHTFIELD_TERRAIN_SHAPE_H +#define BT_HEIGHTFIELD_TERRAIN_SHAPE_H + +#include "btConcaveShape.h" + +///btHeightfieldTerrainShape simulates a 2D heightfield terrain +/** + The caller is responsible for maintaining the heightfield array; this + class does not make a copy. + + The heightfield can be dynamic so long as the min/max height values + capture the extremes (heights must always be in that range). + + The local origin of the heightfield is assumed to be the exact + center (as determined by width and length and height, with each + axis multiplied by the localScaling). + + \b NOTE: be careful with coordinates. If you have a heightfield with a local + min height of -100m, and a max height of +500m, you may be tempted to place it + at the origin (0,0) and expect the heights in world coordinates to be + -100 to +500 meters. + Actually, the heights will be -300 to +300m, because bullet will re-center + the heightfield based on its AABB (which is determined by the min/max + heights). So keep in mind that once you create a btHeightfieldTerrainShape + object, the heights will be adjusted relative to the center of the AABB. This + is different to the behavior of many rendering engines, but is useful for + physics engines. + + Most (but not all) rendering and heightfield libraries assume upAxis = 1 + (that is, the y-axis is "up"). This class allows any of the 3 coordinates + to be "up". Make sure your choice of axis is consistent with your rendering + system. + + The heightfield heights are determined from the data type used for the + heightfieldData array. + + - PHY_UCHAR: height at a point is the uchar value at the + grid point, multipled by heightScale. uchar isn't recommended + because of its inability to deal with negative values, and + low resolution (8-bit). + + - PHY_SHORT: height at a point is the short int value at that grid + point, multipled by heightScale. + + - PHY_FLOAT: height at a point is the float value at that grid + point. heightScale is ignored when using the float heightfield + data type. + + Whatever the caller specifies as minHeight and maxHeight will be honored. + The class will not inspect the heightfield to discover the actual minimum + or maximum heights. These values are used to determine the heightfield's + axis-aligned bounding box, multiplied by localScaling. + + For usage and testing see the TerrainDemo. + */ +ATTRIBUTE_ALIGNED16(class) btHeightfieldTerrainShape : public btConcaveShape +{ +protected: + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + btVector3 m_localOrigin; + + ///terrain data + int m_heightStickWidth; + int m_heightStickLength; + btScalar m_minHeight; + btScalar m_maxHeight; + btScalar m_width; + btScalar m_length; + btScalar m_heightScale; + union + { + const unsigned char* m_heightfieldDataUnsignedChar; + const short* m_heightfieldDataShort; + const btScalar* m_heightfieldDataFloat; + const void* m_heightfieldDataUnknown; + }; + + PHY_ScalarType m_heightDataType; + bool m_flipQuadEdges; + bool m_useDiamondSubdivision; + bool m_useZigzagSubdivision; + + int m_upAxis; + + btVector3 m_localScaling; + + virtual btScalar getRawHeightFieldValue(int x,int y) const; + void quantizeWithClamp(int* out, const btVector3& point,int isMax) const; + void getVertex(int x,int y,btVector3& vertex) const; + + + + /// protected initialization + /** + Handles the work of constructors so that public constructors can be + backwards-compatible without a lot of copy/paste. + */ + void initialize(int heightStickWidth, int heightStickLength, + const void* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, int upAxis, + PHY_ScalarType heightDataType, bool flipQuadEdges); + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + /// preferred constructor + /** + This constructor supports a range of heightfield + data types, and allows for a non-zero minimum height value. + heightScale is needed for any integer-based heightfield data types. + */ + btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength, + const void* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, + int upAxis, PHY_ScalarType heightDataType, + bool flipQuadEdges); + + /// legacy constructor + /** + The legacy constructor assumes the heightfield has a minimum height + of zero. Only unsigned char or floats are supported. For legacy + compatibility reasons, heightScale is calculated as maxHeight / 65535 + (and is only used when useFloatData = false). + */ + btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,const void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges); + + virtual ~btHeightfieldTerrainShape(); + + + void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;} + + ///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625 + void setUseZigzagSubdivision(bool useZigzagSubdivision=true) { m_useZigzagSubdivision = useZigzagSubdivision;} + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + virtual void setLocalScaling(const btVector3& scaling); + + virtual const btVector3& getLocalScaling() const; + + //debugging + virtual const char* getName()const {return "HEIGHTFIELD";} + +}; + +#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btMaterial.h b/src/BulletCollision/CollisionShapes/btMaterial.h new file mode 100644 index 0000000..866f9b4 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMaterial.h @@ -0,0 +1,35 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/// This file was created by Alex Silverman + +#ifndef BT_MATERIAL_H +#define BT_MATERIAL_H + +// Material class to be used by btMultimaterialTriangleMeshShape to store triangle properties +class btMaterial +{ + // public members so that materials can change due to world events +public: + btScalar m_friction; + btScalar m_restitution; + int pad[2]; + + btMaterial(){} + btMaterial(btScalar fric, btScalar rest) { m_friction = fric; m_restitution = rest; } +}; + +#endif // BT_MATERIAL_H + diff --git a/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp new file mode 100644 index 0000000..06707e2 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp @@ -0,0 +1,60 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btMinkowskiSumShape.h" + + +btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB) +: btConvexInternalShape (), +m_shapeA(shapeA), +m_shapeB(shapeB) +{ + m_shapeType = MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE; + m_transA.setIdentity(); + m_transB.setIdentity(); +} + +btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec*m_transA.getBasis())); + btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(-vec*m_transB.getBasis())); + return supVertexA - supVertexB; +} + +void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + ///@todo: could make recursive use of batching. probably this shape is not used frequently. + for (int i=0;igetMargin() + m_shapeB->getMargin(); +} + + +void btMinkowskiSumShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + (void)mass; + btAssert(0); + inertia.setValue(0,0,0); +} diff --git a/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h new file mode 100644 index 0000000..a3f9a47 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h @@ -0,0 +1,62 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_MINKOWSKI_SUM_SHAPE_H +#define BT_MINKOWSKI_SUM_SHAPE_H + +#include "btConvexInternalShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types + +/// The btMinkowskiSumShape is only for advanced users. This shape represents implicit based minkowski sum of two convex implicit shapes. +ATTRIBUTE_ALIGNED16(class) btMinkowskiSumShape : public btConvexInternalShape +{ + + btTransform m_transA; + btTransform m_transB; + const btConvexShape* m_shapeA; + const btConvexShape* m_shapeB; + +public: + +BT_DECLARE_ALIGNED_ALLOCATOR(); + + btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB); + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + void setTransformA(const btTransform& transA) { m_transA = transA;} + void setTransformB(const btTransform& transB) { m_transB = transB;} + + const btTransform& getTransformA()const { return m_transA;} + const btTransform& GetTransformB()const { return m_transB;} + + + virtual btScalar getMargin() const; + + const btConvexShape* getShapeA() const { return m_shapeA;} + const btConvexShape* getShapeB() const { return m_shapeB;} + + virtual const char* getName()const + { + return "MinkowskiSum"; + } +}; + +#endif //BT_MINKOWSKI_SUM_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp b/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp new file mode 100644 index 0000000..5bae242 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp @@ -0,0 +1,180 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btSerializer.h" + +btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres) +:btConvexInternalAabbCachingShape () +{ + m_shapeType = MULTI_SPHERE_SHAPE_PROXYTYPE; + //btScalar startMargin = btScalar(BT_LARGE_FLOAT); + + m_localPositionArray.resize(numSpheres); + m_radiArray.resize(numSpheres); + for (int i=0;i maxDot ) + { + maxDot = newDot; + supVec = temp[i]; + } + } + + return supVec; + +} + + void btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + + for (int j=0;j maxDot ) + { + maxDot = newDot; + supportVerticesOut[j] = temp[i]; + } + } + + } +} + + + + + + + + +void btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + //as an approximation, take the inertia of the box that bounds the spheres + + btVector3 localAabbMin,localAabbMax; + getCachedLocalAabb(localAabbMin,localAabbMax); + btVector3 halfExtents = (localAabbMax-localAabbMin)*btScalar(0.5); + + btScalar lx=btScalar(2.)*(halfExtents.x()); + btScalar ly=btScalar(2.)*(halfExtents.y()); + btScalar lz=btScalar(2.)*(halfExtents.z()); + + inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + ly*ly)); + +} + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btMultiSphereShapeData* shapeData = (btMultiSphereShapeData*) dataBuffer; + btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer); + + int numElem = m_localPositionArray.size(); + shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)serializer->getUniquePointer((void*)&m_localPositionArray[0]): 0; + + shapeData->m_localPositionArraySize = numElem; + if (numElem) + { + btChunk* chunk = serializer->allocate(sizeof(btPositionAndRadius),numElem); + btPositionAndRadius* memPtr = (btPositionAndRadius*)chunk->m_oldPtr; + for (int i=0;im_pos); + memPtr->m_radius = float(m_radiArray[i]); + } + serializer->finalizeChunk(chunk,"btPositionAndRadius",BT_ARRAY_CODE,(void*)&m_localPositionArray[0]); + } + + return "btMultiSphereShapeData"; +} + + diff --git a/src/BulletCollision/CollisionShapes/btMultiSphereShape.h b/src/BulletCollision/CollisionShapes/btMultiSphereShape.h new file mode 100644 index 0000000..5d3b402 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMultiSphereShape.h @@ -0,0 +1,101 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_MULTI_SPHERE_MINKOWSKI_H +#define BT_MULTI_SPHERE_MINKOWSKI_H + +#include "btConvexInternalShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAabbUtil2.h" + + + +///The btMultiSphereShape represents the convex hull of a collection of spheres. You can create special capsules or other smooth volumes. +///It is possible to animate the spheres for deformation, but call 'recalcLocalAabb' after changing any sphere position/radius +ATTRIBUTE_ALIGNED16(class) btMultiSphereShape : public btConvexInternalAabbCachingShape +{ + + btAlignedObjectArray m_localPositionArray; + btAlignedObjectArray m_radiArray; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres); + + ///CollisionShape Interface + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + /// btConvexShape Interface + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + int getSphereCount() const + { + return m_localPositionArray.size(); + } + + const btVector3& getSpherePosition(int index) const + { + return m_localPositionArray[index]; + } + + btScalar getSphereRadius(int index) const + { + return m_radiArray[index]; + } + + + virtual const char* getName()const + { + return "MultiSphere"; + } + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + + +struct btPositionAndRadius +{ + btVector3FloatData m_pos; + float m_radius; +}; + +struct btMultiSphereShapeData +{ + btConvexInternalShapeData m_convexInternalShapeData; + + btPositionAndRadius *m_localPositionArrayPtr; + int m_localPositionArraySize; + char m_padding[4]; +}; + + + +SIMD_FORCE_INLINE int btMultiSphereShape::calculateSerializeBufferSize() const +{ + return sizeof(btMultiSphereShapeData); +} + + + +#endif //BT_MULTI_SPHERE_MINKOWSKI_H diff --git a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp new file mode 100644 index 0000000..58799ac --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp @@ -0,0 +1,45 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/// This file was created by Alex Silverman + +#include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h" +//#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" + + +///Obtains the material for a specific triangle +const btMaterial * btMultimaterialTriangleMeshShape::getMaterialProperties(int partID, int triIndex) +{ + const unsigned char * materialBase = 0; + int numMaterials; + PHY_ScalarType materialType; + int materialStride; + const unsigned char * triangleMaterialBase = 0; + int numTriangles; + int triangleMaterialStride; + PHY_ScalarType triangleType; + + ((btTriangleIndexVertexMaterialArray*)m_meshInterface)->getLockedReadOnlyMaterialBase(&materialBase, numMaterials, materialType, materialStride, + &triangleMaterialBase, numTriangles, triangleMaterialStride, triangleType, partID); + + // return the pointer to the place with the friction for the triangle + // TODO: This depends on whether it's a moving mesh or not + // BUG IN GIMPACT + //return (btScalar*)(&materialBase[triangleMaterialBase[(triIndex-1) * triangleMaterialStride] * materialStride]); + int * matInd = (int *)(&(triangleMaterialBase[(triIndex * triangleMaterialStride)])); + btMaterial *matVal = (btMaterial *)(&(materialBase[*matInd * materialStride])); + return (matVal); +} diff --git a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h new file mode 100644 index 0000000..2b92ab7 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h @@ -0,0 +1,120 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/// This file was created by Alex Silverman + +#ifndef BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H +#define BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H + +#include "btBvhTriangleMeshShape.h" +#include "btMaterial.h" + +///The BvhTriangleMaterialMeshShape extends the btBvhTriangleMeshShape. Its main contribution is the interface into a material array, which allows per-triangle friction and restitution. +ATTRIBUTE_ALIGNED16(class) btMultimaterialTriangleMeshShape : public btBvhTriangleMeshShape +{ + btAlignedObjectArray m_materialList; + int ** m_triangleMaterials; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true): + btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh) + { + m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; + + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); + + for(int i = 0; i < meshInterface->getNumSubParts(); i++) + { + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + i); + //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces, 16)); + } + } + + ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb + btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true): + btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh) + { + m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; + + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); + + for(int i = 0; i < meshInterface->getNumSubParts(); i++) + { + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + i); + //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces * 2, 16)); + } + } + + virtual ~btMultimaterialTriangleMeshShape() + { +/* + for(int i = 0; i < m_meshInterface->getNumSubParts(); i++) + { + btAlignedFree(m_materialValues[i]); + m_materialLookup[i] = NULL; + } + btAlignedFree(m_materialValues); + m_materialLookup = NULL; +*/ + } + //debugging + virtual const char* getName()const {return "MULTIMATERIALTRIANGLEMESH";} + + ///Obtains the material for a specific triangle + const btMaterial * getMaterialProperties(int partID, int triIndex); + +} +; + +#endif //BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp b/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp new file mode 100644 index 0000000..6f36775 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp @@ -0,0 +1,391 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btOptimizedBvh.h" +#include "btStridingMeshInterface.h" +#include "LinearMath/btAabbUtil2.h" +#include "LinearMath/btIDebugDraw.h" + + +btOptimizedBvh::btOptimizedBvh() +{ +} + +btOptimizedBvh::~btOptimizedBvh() +{ +} + + +void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax) +{ + m_useQuantization = useQuantizedAabbCompression; + + + // NodeArray triangleNodes; + + struct NodeTriangleCallback : public btInternalTriangleIndexCallback + { + + NodeArray& m_triangleNodes; + + NodeTriangleCallback& operator=(NodeTriangleCallback& other) + { + m_triangleNodes.copyFromArray(other.m_triangleNodes); + return *this; + } + + NodeTriangleCallback(NodeArray& triangleNodes) + :m_triangleNodes(triangleNodes) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + btOptimizedBvhNode node; + btVector3 aabbMin,aabbMax; + aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + aabbMin.setMin(triangle[0]); + aabbMax.setMax(triangle[0]); + aabbMin.setMin(triangle[1]); + aabbMax.setMax(triangle[1]); + aabbMin.setMin(triangle[2]); + aabbMax.setMax(triangle[2]); + + //with quantization? + node.m_aabbMinOrg = aabbMin; + node.m_aabbMaxOrg = aabbMax; + + node.m_escapeIndex = -1; + + //for child nodes + node.m_subPart = partId; + node.m_triangleIndex = triangleIndex; + m_triangleNodes.push_back(node); + } + }; + struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback + { + QuantizedNodeArray& m_triangleNodes; + const btQuantizedBvh* m_optimizedTree; // for quantization + + QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other) + { + m_triangleNodes.copyFromArray(other.m_triangleNodes); + m_optimizedTree = other.m_optimizedTree; + return *this; + } + + QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btQuantizedBvh* tree) + :m_triangleNodes(triangleNodes),m_optimizedTree(tree) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + // The partId and triangle index must fit in the same (positive) integer + btAssert(partId < (1<=0); + + btQuantizedBvhNode node; + btVector3 aabbMin,aabbMax; + aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + aabbMin.setMin(triangle[0]); + aabbMax.setMax(triangle[0]); + aabbMin.setMin(triangle[1]); + aabbMax.setMax(triangle[1]); + aabbMin.setMin(triangle[2]); + aabbMax.setMax(triangle[2]); + + //PCK: add these checks for zero dimensions of aabb + const btScalar MIN_AABB_DIMENSION = btScalar(0.002); + const btScalar MIN_AABB_HALF_DIMENSION = btScalar(0.001); + if (aabbMax.x() - aabbMin.x() < MIN_AABB_DIMENSION) + { + aabbMax.setX(aabbMax.x() + MIN_AABB_HALF_DIMENSION); + aabbMin.setX(aabbMin.x() - MIN_AABB_HALF_DIMENSION); + } + if (aabbMax.y() - aabbMin.y() < MIN_AABB_DIMENSION) + { + aabbMax.setY(aabbMax.y() + MIN_AABB_HALF_DIMENSION); + aabbMin.setY(aabbMin.y() - MIN_AABB_HALF_DIMENSION); + } + if (aabbMax.z() - aabbMin.z() < MIN_AABB_DIMENSION) + { + aabbMax.setZ(aabbMax.z() + MIN_AABB_HALF_DIMENSION); + aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION); + } + + m_optimizedTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0); + m_optimizedTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1); + + node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; + + m_triangleNodes.push_back(node); + } + }; + + + + int numLeafNodes = 0; + + + if (m_useQuantization) + { + + //initialize quantization values + setQuantizationValues(bvhAabbMin,bvhAabbMax); + + QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this); + + + triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax); + + //now we have an array of leafnodes in m_leafNodes + numLeafNodes = m_quantizedLeafNodes.size(); + + + m_quantizedContiguousNodes.resize(2*numLeafNodes); + + + } else + { + NodeTriangleCallback callback(m_leafNodes); + + btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + + triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax); + + //now we have an array of leafnodes in m_leafNodes + numLeafNodes = m_leafNodes.size(); + + m_contiguousNodes.resize(2*numLeafNodes); + } + + m_curNodeIndex = 0; + + buildTree(0,numLeafNodes); + + ///if the entire tree is small then subtree size, we need to create a header info for the tree + if(m_useQuantization && !m_SubtreeHeaders.size()) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); + subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); + subtree.m_rootNodeIndex = 0; + subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex(); + } + + //PCK: update the copy of the size + m_subtreeHeaderCount = m_SubtreeHeaders.size(); + + //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary + m_quantizedLeafNodes.clear(); + m_leafNodes.clear(); +} + + + + +void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax) +{ + if (m_useQuantization) + { + + setQuantizationValues(aabbMin,aabbMax); + + updateBvhNodes(meshInterface,0,m_curNodeIndex,0); + + ///now update all subtree headers + + int i; + for (i=0;i m_bvhAabbMin.getX()); + btAssert(aabbMin.getY() > m_bvhAabbMin.getY()); + btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ()); + + btAssert(aabbMax.getX() < m_bvhAabbMax.getX()); + btAssert(aabbMax.getY() < m_bvhAabbMax.getY()); + btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ()); + + ///we should update all quantization values, using updateBvhNodes(meshInterface); + ///but we only update chunks that overlap the given aabb + + unsigned short quantizedQueryAabbMin[3]; + unsigned short quantizedQueryAabbMax[3]; + + quantize(&quantizedQueryAabbMin[0],aabbMin,0); + quantize(&quantizedQueryAabbMax[0],aabbMax,1); + + int i; + for (i=0;im_SubtreeHeaders.size();i++) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; + + //PCK: unsigned instead of bool + unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + if (overlap != 0) + { + updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i); + + subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); + } + } + +} + +void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index) +{ + (void)index; + + btAssert(m_useQuantization); + + int curNodeSubPart=-1; + + //get access info to trianglemesh data + const unsigned char *vertexbase = 0; + int numverts = 0; + PHY_ScalarType type = PHY_INTEGER; + int stride = 0; + const unsigned char *indexbase = 0; + int indexstride = 0; + int numfaces = 0; + PHY_ScalarType indicestype = PHY_INTEGER; + + btVector3 triangleVerts[3]; + btVector3 aabbMin,aabbMax; + const btVector3& meshScaling = meshInterface->getScaling(); + + int i; + for (i=endNode-1;i>=firstNode;i--) + { + + + btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; + if (curNode.isLeafNode()) + { + //recalc aabb from triangle data + int nodeSubPart = curNode.getPartId(); + int nodeTriangleIndex = curNode.getTriangleIndex(); + if (nodeSubPart != curNodeSubPart) + { + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); + + curNodeSubPart = nodeSubPart; + btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); + } + //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, + + unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); + + + for (int j=2;j>=0;j--) + { + + int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; + if (type == PHY_FLOAT) + { + float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + triangleVerts[j] = btVector3( + graphicsbase[0]*meshScaling.getX(), + graphicsbase[1]*meshScaling.getY(), + graphicsbase[2]*meshScaling.getZ()); + } + else + { + double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); + triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ())); + } + } + + + + aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + aabbMin.setMin(triangleVerts[0]); + aabbMax.setMax(triangleVerts[0]); + aabbMin.setMin(triangleVerts[1]); + aabbMax.setMax(triangleVerts[1]); + aabbMin.setMin(triangleVerts[2]); + aabbMax.setMax(triangleVerts[2]); + + quantize(&curNode.m_quantizedAabbMin[0],aabbMin,0); + quantize(&curNode.m_quantizedAabbMax[0],aabbMax,1); + + } else + { + //combine aabb from both children + + btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1]; + + btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] : + &m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()]; + + + { + for (int i=0;i<3;i++) + { + curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; + if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i]) + curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i]; + + curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; + if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) + curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; + } + } + } + + } + + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); + + +} + +///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' +btOptimizedBvh* btOptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) +{ + btQuantizedBvh* bvh = btQuantizedBvh::deSerializeInPlace(i_alignedDataBuffer,i_dataBufferSize,i_swapEndian); + + //we don't add additional data so just do a static upcast + return static_cast(bvh); +} diff --git a/src/BulletCollision/CollisionShapes/btOptimizedBvh.h b/src/BulletCollision/CollisionShapes/btOptimizedBvh.h new file mode 100644 index 0000000..715961f --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btOptimizedBvh.h @@ -0,0 +1,65 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///Contains contributions from Disney Studio's + +#ifndef BT_OPTIMIZED_BVH_H +#define BT_OPTIMIZED_BVH_H + +#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" + +class btStridingMeshInterface; + + +///The btOptimizedBvh extends the btQuantizedBvh to create AABB tree for triangle meshes, through the btStridingMeshInterface. +ATTRIBUTE_ALIGNED16(class) btOptimizedBvh : public btQuantizedBvh +{ + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + +protected: + +public: + + btOptimizedBvh(); + + virtual ~btOptimizedBvh(); + + void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax); + + void refit(btStridingMeshInterface* triangles,const btVector3& aabbMin,const btVector3& aabbMax); + + void refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax); + + void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index); + + /// Data buffer MUST be 16 byte aligned + virtual bool serializeInPlace(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const + { + return btQuantizedBvh::serialize(o_alignedDataBuffer,i_dataBufferSize,i_swapEndian); + + } + + ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' + static btOptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); + + +}; + + +#endif //BT_OPTIMIZED_BVH_H + + diff --git a/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp new file mode 100644 index 0000000..7dec689 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp @@ -0,0 +1,497 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" +#include "btConvexPolyhedron.h" +#include "LinearMath/btConvexHullComputer.h" +#include +#include "LinearMath/btGeometryUtil.h" +#include "LinearMath/btGrahamScan2dConvexHull.h" + + +btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(), +m_polyhedron(0) +{ + +} + +btPolyhedralConvexShape::~btPolyhedralConvexShape() +{ + if (m_polyhedron) + { + m_polyhedron->~btConvexPolyhedron(); + btAlignedFree(m_polyhedron); + } +} + + +bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMargin) +{ + + if (m_polyhedron) + { + m_polyhedron->~btConvexPolyhedron(); + btAlignedFree(m_polyhedron); + } + + void* mem = btAlignedAlloc(sizeof(btConvexPolyhedron),16); + m_polyhedron = new (mem) btConvexPolyhedron; + + btAlignedObjectArray orgVertices; + + for (int i=0;i planeEquations; + btGeometryUtil::getPlaneEquationsFromVertices(orgVertices,planeEquations); + + btAlignedObjectArray shiftedPlaneEquations; + for (int p=0;p tmpVertices; + + btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,tmpVertices); + + conv.compute(&tmpVertices[0].getX(), sizeof(btVector3),tmpVertices.size(),0.f,0.f); + } else + { + + conv.compute(&orgVertices[0].getX(), sizeof(btVector3),orgVertices.size(),0.f,0.f); + } + + + + btAlignedObjectArray faceNormals; + int numFaces = conv.faces.size(); + faceNormals.resize(numFaces); + btConvexHullComputer* convexUtil = &conv; + + + btAlignedObjectArray tmpFaces; + tmpFaces.resize(numFaces); + + int numVertices = convexUtil->vertices.size(); + m_polyhedron->m_vertices.resize(numVertices); + for (int p=0;pm_vertices[p] = convexUtil->vertices[p]; + } + + + for (int i=0;ifaces[i]; + //printf("face=%d\n",face); + const btConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face]; + const btConvexHullComputer::Edge* edge = firstEdge; + + btVector3 edges[3]; + int numEdges = 0; + //compute face normals + + do + { + + int src = edge->getSourceVertex(); + tmpFaces[i].m_indices.push_back(src); + int targ = edge->getTargetVertex(); + btVector3 wa = convexUtil->vertices[src]; + + btVector3 wb = convexUtil->vertices[targ]; + btVector3 newEdge = wb-wa; + newEdge.normalize(); + if (numEdges<2) + edges[numEdges++] = newEdge; + + edge = edge->getNextEdgeOfFace(); + } while (edge!=firstEdge); + + btScalar planeEq = 1e30f; + + + if (numEdges==2) + { + faceNormals[i] = edges[0].cross(edges[1]); + faceNormals[i].normalize(); + tmpFaces[i].m_plane[0] = faceNormals[i].getX(); + tmpFaces[i].m_plane[1] = faceNormals[i].getY(); + tmpFaces[i].m_plane[2] = faceNormals[i].getZ(); + tmpFaces[i].m_plane[3] = planeEq; + + } + else + { + btAssert(0);//degenerate? + faceNormals[i].setZero(); + } + + for (int v=0;vm_vertices[tmpFaces[i].m_indices[v]].dot(faceNormals[i]); + if (planeEq>eq) + { + planeEq=eq; + } + } + tmpFaces[i].m_plane[3] = -planeEq; + } + + //merge coplanar faces and copy them to m_polyhedron + + btScalar faceWeldThreshold= 0.999f; + btAlignedObjectArray todoFaces; + for (int i=0;i coplanarFaceGroup; + int refFace = todoFaces[todoFaces.size()-1]; + + coplanarFaceGroup.push_back(refFace); + btFace& faceA = tmpFaces[refFace]; + todoFaces.pop_back(); + + btVector3 faceNormalA(faceA.m_plane[0],faceA.m_plane[1],faceA.m_plane[2]); + for (int j=todoFaces.size()-1;j>=0;j--) + { + int i = todoFaces[j]; + btFace& faceB = tmpFaces[i]; + btVector3 faceNormalB(faceB.m_plane[0],faceB.m_plane[1],faceB.m_plane[2]); + if (faceNormalA.dot(faceNormalB)>faceWeldThreshold) + { + coplanarFaceGroup.push_back(i); + todoFaces.remove(i); + } + } + + + bool did_merge = false; + if (coplanarFaceGroup.size()>1) + { + //do the merge: use Graham Scan 2d convex hull + + btAlignedObjectArray orgpoints; + btVector3 averageFaceNormal(0,0,0); + + for (int i=0;im_faces.push_back(tmpFaces[coplanarFaceGroup[i]]); + + btFace& face = tmpFaces[coplanarFaceGroup[i]]; + btVector3 faceNormal(face.m_plane[0],face.m_plane[1],face.m_plane[2]); + averageFaceNormal+=faceNormal; + for (int f=0;fm_vertices[orgIndex]; + + bool found = false; + + for (int i=0;i hull; + + averageFaceNormal.normalize(); + GrahamScanConvexHull2D(orgpoints,hull,averageFaceNormal); + + for (int i=0;im_faces.push_back(combinedFace); + } + } + if(!did_merge) + { + for (int i=0;im_faces.push_back(face); + } + + } + + + + } + + m_polyhedron->initialize(); + + return true; +} + +#ifndef MIN + #define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#endif + +btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +{ + + + btVector3 supVec(0,0,0); +#ifndef __SPU__ + int i; + btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + + btVector3 vtx; + btScalar newDot; + + for( int k = 0; k < getNumVertices(); k += 128 ) + { + btVector3 temp[128]; + int inner_count = MIN(getNumVertices() - k, 128); + for( i = 0; i < inner_count; i++ ) + getVertex(i,temp[i]); + i = (int) vec.maxDot( temp, inner_count, newDot); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = temp[i]; + } + } + +#endif //__SPU__ + return supVec; +} + + + +void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ +#ifndef __SPU__ + int i; + + btVector3 vtx; + btScalar newDot; + + for (i=0;i supportVerticesOut[j][3]) + { + supportVerticesOut[j] = temp[i]; + supportVerticesOut[j][3] = newDot; + } + } + } + +#endif //__SPU__ +} + + + +void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ +#ifndef __SPU__ + //not yet, return box inertia + + btScalar margin = getMargin(); + + btTransform ident; + ident.setIdentity(); + btVector3 aabbMin,aabbMax; + getAabb(ident,aabbMin,aabbMax); + btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); + + btScalar lx=btScalar(2.)*(halfExtents.x()+margin); + btScalar ly=btScalar(2.)*(halfExtents.y()+margin); + btScalar lz=btScalar(2.)*(halfExtents.z()+margin); + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(0.08333333); + + inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); +#endif //__SPU__ +} + + + +void btPolyhedralConvexAabbCachingShape::setLocalScaling(const btVector3& scaling) +{ + btConvexInternalShape::setLocalScaling(scaling); + recalcLocalAabb(); +} + +btPolyhedralConvexAabbCachingShape::btPolyhedralConvexAabbCachingShape() +:btPolyhedralConvexShape(), +m_localAabbMin(1,1,1), +m_localAabbMax(-1,-1,-1), +m_isLocalAabbValid(false) +{ +} + +void btPolyhedralConvexAabbCachingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin()); +} + +void btPolyhedralConvexAabbCachingShape::recalcLocalAabb() +{ + m_isLocalAabbValid = true; + + #if 1 + static const btVector3 _directions[] = + { + btVector3( 1., 0., 0.), + btVector3( 0., 1., 0.), + btVector3( 0., 0., 1.), + btVector3( -1., 0., 0.), + btVector3( 0., -1., 0.), + btVector3( 0., 0., -1.) + }; + + btVector3 _supporting[] = + { + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.) + }; + + batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6); + + for ( int i = 0; i < 3; ++i ) + { + m_localAabbMax[i] = _supporting[i][i] + m_collisionMargin; + m_localAabbMin[i] = _supporting[i + 3][i] - m_collisionMargin; + } + + #else + + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + btVector3 tmp = localGetSupportingVertex(vec); + m_localAabbMax[i] = tmp[i]; + vec[i] = btScalar(-1.); + tmp = localGetSupportingVertex(vec); + m_localAabbMin[i] = tmp[i]; + } + #endif +} + + + + diff --git a/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h new file mode 100644 index 0000000..961d001 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h @@ -0,0 +1,116 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_POLYHEDRAL_CONVEX_SHAPE_H +#define BT_POLYHEDRAL_CONVEX_SHAPE_H + +#include "LinearMath/btMatrix3x3.h" +#include "btConvexInternalShape.h" +class btConvexPolyhedron; + + +///The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes. +ATTRIBUTE_ALIGNED16(class) btPolyhedralConvexShape : public btConvexInternalShape +{ + + +protected: + + btConvexPolyhedron* m_polyhedron; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + + btPolyhedralConvexShape(); + + virtual ~btPolyhedralConvexShape(); + + ///optional method mainly used to generate multiple contact points by clipping polyhedral features (faces/edges) + ///experimental/work-in-progress + virtual bool initializePolyhedralFeatures(int shiftVerticesByMargin=0); + + const btConvexPolyhedron* getConvexPolyhedron() const + { + return m_polyhedron; + } + + //brute force implementations + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + + virtual int getNumVertices() const = 0 ; + virtual int getNumEdges() const = 0; + virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0; + virtual void getVertex(int i,btVector3& vtx) const = 0; + virtual int getNumPlanes() const = 0; + virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0; +// virtual int getIndex(int i) const = 0 ; + + virtual bool isInside(const btVector3& pt,btScalar tolerance) const = 0; + +}; + + +///The btPolyhedralConvexAabbCachingShape adds aabb caching to the btPolyhedralConvexShape +class btPolyhedralConvexAabbCachingShape : public btPolyhedralConvexShape +{ + + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + bool m_isLocalAabbValid; + +protected: + + void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax) + { + m_isLocalAabbValid = true; + m_localAabbMin = aabbMin; + m_localAabbMax = aabbMax; + } + + inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const + { + btAssert(m_isLocalAabbValid); + aabbMin = m_localAabbMin; + aabbMax = m_localAabbMax; + } + +public: + + btPolyhedralConvexAabbCachingShape(); + + inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const + { + + //lazy evaluation of local aabb + btAssert(m_isLocalAabbValid); + btTransformAabb(m_localAabbMin,m_localAabbMax,margin,trans,aabbMin,aabbMax); + } + + virtual void setLocalScaling(const btVector3& scaling); + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + void recalcLocalAabb(); + +}; + +#endif //BT_POLYHEDRAL_CONVEX_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp new file mode 100644 index 0000000..6a337c7 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp @@ -0,0 +1,121 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btScaledBvhTriangleMeshShape.h" + +btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling) +:m_localScaling(localScaling),m_bvhTriMeshShape(childShape) +{ + m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE; +} + +btScaledBvhTriangleMeshShape::~btScaledBvhTriangleMeshShape() +{ +} + + +class btScaledTriangleCallback : public btTriangleCallback +{ + btTriangleCallback* m_originalCallback; + + btVector3 m_localScaling; + +public: + + btScaledTriangleCallback(btTriangleCallback* originalCallback,const btVector3& localScaling) + :m_originalCallback(originalCallback), + m_localScaling(localScaling) + { + } + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) + { + btVector3 newTriangle[3]; + newTriangle[0] = triangle[0]*m_localScaling; + newTriangle[1] = triangle[1]*m_localScaling; + newTriangle[2] = triangle[2]*m_localScaling; + m_originalCallback->processTriangle(&newTriangle[0],partId,triangleIndex); + } +}; + +void btScaledBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + btScaledTriangleCallback scaledCallback(callback,m_localScaling); + + btVector3 invLocalScaling(1.f/m_localScaling.getX(),1.f/m_localScaling.getY(),1.f/m_localScaling.getZ()); + btVector3 scaledAabbMin,scaledAabbMax; + + ///support negative scaling + scaledAabbMin[0] = m_localScaling.getX() >= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0]; + scaledAabbMin[1] = m_localScaling.getY() >= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1]; + scaledAabbMin[2] = m_localScaling.getZ() >= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2]; + scaledAabbMin[3] = 0.f; + + scaledAabbMax[0] = m_localScaling.getX() <= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0]; + scaledAabbMax[1] = m_localScaling.getY() <= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1]; + scaledAabbMax[2] = m_localScaling.getZ() <= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2]; + scaledAabbMax[3] = 0.f; + + + m_bvhTriMeshShape->processAllTriangles(&scaledCallback,scaledAabbMin,scaledAabbMax); +} + + +void btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + btVector3 localAabbMin = m_bvhTriMeshShape->getLocalAabbMin(); + btVector3 localAabbMax = m_bvhTriMeshShape->getLocalAabbMax(); + + btVector3 tmpLocalAabbMin = localAabbMin * m_localScaling; + btVector3 tmpLocalAabbMax = localAabbMax * m_localScaling; + + localAabbMin[0] = (m_localScaling.getX() >= 0.) ? tmpLocalAabbMin[0] : tmpLocalAabbMax[0]; + localAabbMin[1] = (m_localScaling.getY() >= 0.) ? tmpLocalAabbMin[1] : tmpLocalAabbMax[1]; + localAabbMin[2] = (m_localScaling.getZ() >= 0.) ? tmpLocalAabbMin[2] : tmpLocalAabbMax[2]; + localAabbMax[0] = (m_localScaling.getX() <= 0.) ? tmpLocalAabbMin[0] : tmpLocalAabbMax[0]; + localAabbMax[1] = (m_localScaling.getY() <= 0.) ? tmpLocalAabbMin[1] : tmpLocalAabbMax[1]; + localAabbMax[2] = (m_localScaling.getZ() <= 0.) ? tmpLocalAabbMin[2] : tmpLocalAabbMax[2]; + + btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin); + btScalar margin = m_bvhTriMeshShape->getMargin(); + localHalfExtents += btVector3(margin,margin,margin); + btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin); + + btMatrix3x3 abs_b = trans.getBasis().absolute(); + + btVector3 center = trans(localCenter); + + btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMin = center - extent; + aabbMax = center + extent; + +} + +void btScaledBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; +} + +const btVector3& btScaledBvhTriangleMeshShape::getLocalScaling() const +{ + return m_localScaling; +} + +void btScaledBvhTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + ///don't make this a movable object! +// btAssert(0); +} diff --git a/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h new file mode 100644 index 0000000..39049ea --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h @@ -0,0 +1,95 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H +#define BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H + +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" + + +///The btScaledBvhTriangleMeshShape allows to instance a scaled version of an existing btBvhTriangleMeshShape. +///Note that each btBvhTriangleMeshShape still can have its own local scaling, independent from this btScaledBvhTriangleMeshShape 'localScaling' +ATTRIBUTE_ALIGNED16(class) btScaledBvhTriangleMeshShape : public btConcaveShape +{ + + + btVector3 m_localScaling; + + btBvhTriangleMeshShape* m_bvhTriMeshShape; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + + btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling); + + virtual ~btScaledBvhTriangleMeshShape(); + + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + btBvhTriangleMeshShape* getChildShape() + { + return m_bvhTriMeshShape; + } + + const btBvhTriangleMeshShape* getChildShape() const + { + return m_bvhTriMeshShape; + } + + //debugging + virtual const char* getName()const {return "SCALEDBVHTRIANGLEMESH";} + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btScaledTriangleMeshShapeData +{ + btTriangleMeshShapeData m_trimeshShapeData; + + btVector3FloatData m_localScaling; +}; + + +SIMD_FORCE_INLINE int btScaledBvhTriangleMeshShape::calculateSerializeBufferSize() const +{ + return sizeof(btScaledTriangleMeshShapeData); +} + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btScaledBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btScaledTriangleMeshShapeData* scaledMeshData = (btScaledTriangleMeshShapeData*) dataBuffer; + m_bvhTriMeshShape->serialize(&scaledMeshData->m_trimeshShapeData,serializer); + scaledMeshData->m_trimeshShapeData.m_collisionShapeData.m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE; + m_localScaling.serializeFloat(scaledMeshData->m_localScaling); + return "btScaledTriangleMeshShapeData"; +} + + +#endif //BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btShapeHull.cpp b/src/BulletCollision/CollisionShapes/btShapeHull.cpp new file mode 100644 index 0000000..3beaf86 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btShapeHull.cpp @@ -0,0 +1,170 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//btShapeHull was implemented by John McCutchan. + + +#include "btShapeHull.h" +#include "LinearMath/btConvexHull.h" + +#define NUM_UNITSPHERE_POINTS 42 + +btShapeHull::btShapeHull (const btConvexShape* shape) +{ + m_shape = shape; + m_vertices.clear (); + m_indices.clear(); + m_numIndices = 0; +} + +btShapeHull::~btShapeHull () +{ + m_indices.clear(); + m_vertices.clear (); +} + +bool +btShapeHull::buildHull (btScalar /*margin*/) +{ + int numSampleDirections = NUM_UNITSPHERE_POINTS; + { + int numPDA = m_shape->getNumPreferredPenetrationDirections(); + if (numPDA) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + getUnitSpherePoints()[numSampleDirections] = norm; + numSampleDirections++; + } + } + } + + btVector3 supportPoints[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + int i; + for (i = 0; i < numSampleDirections; i++) + { + supportPoints[i] = m_shape->localGetSupportingVertex(getUnitSpherePoints()[i]); + } + + HullDesc hd; + hd.mFlags = QF_TRIANGLES; + hd.mVcount = static_cast(numSampleDirections); + +#ifdef BT_USE_DOUBLE_PRECISION + hd.mVertices = &supportPoints[0]; + hd.mVertexStride = sizeof(btVector3); +#else + hd.mVertices = &supportPoints[0]; + hd.mVertexStride = sizeof (btVector3); +#endif + + HullLibrary hl; + HullResult hr; + if (hl.CreateConvexHull (hd, hr) == QE_FAIL) + { + return false; + } + + m_vertices.resize (static_cast(hr.mNumOutputVertices)); + + + for (i = 0; i < static_cast(hr.mNumOutputVertices); i++) + { + m_vertices[i] = hr.m_OutputVertices[i]; + } + m_numIndices = hr.mNumIndices; + m_indices.resize(static_cast(m_numIndices)); + for (i = 0; i < static_cast(m_numIndices); i++) + { + m_indices[i] = hr.m_Indices[i]; + } + + // free temporary hull result that we just copied + hl.ReleaseResult (hr); + + return true; +} + +int +btShapeHull::numTriangles () const +{ + return static_cast(m_numIndices / 3); +} + +int +btShapeHull::numVertices () const +{ + return m_vertices.size (); +} + +int +btShapeHull::numIndices () const +{ + return static_cast(m_numIndices); +} + + +btVector3* btShapeHull::getUnitSpherePoints() +{ + static btVector3 sUnitSpherePoints[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = + { + btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), + btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), + btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), + btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), + btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), + btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), + btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), + btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), + btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), + btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), + btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), + btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), + btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), + btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), + btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), + btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), + btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), + btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), + btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), + btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), + btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), + btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), + btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), + btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), + btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), + btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), + btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), + btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), + btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), + btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), + btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), + btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), + btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), + btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), + btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), + btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), + btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), + btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), + btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), + btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), + btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), + btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) + }; + return sUnitSpherePoints; +} + diff --git a/src/BulletCollision/CollisionShapes/btShapeHull.h b/src/BulletCollision/CollisionShapes/btShapeHull.h new file mode 100644 index 0000000..e959f19 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btShapeHull.h @@ -0,0 +1,61 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///btShapeHull implemented by John McCutchan. + +#ifndef BT_SHAPE_HULL_H +#define BT_SHAPE_HULL_H + +#include "LinearMath/btAlignedObjectArray.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" + + +///The btShapeHull class takes a btConvexShape, builds a simplified convex hull using btConvexHull and provides triangle indices and vertices. +///It can be useful for to simplify a complex convex object and for visualization of a non-polyhedral convex object. +///It approximates the convex hull using the supporting vertex of 42 directions. +ATTRIBUTE_ALIGNED16(class) btShapeHull +{ +protected: + + btAlignedObjectArray m_vertices; + btAlignedObjectArray m_indices; + unsigned int m_numIndices; + const btConvexShape* m_shape; + + static btVector3* getUnitSpherePoints(); + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btShapeHull (const btConvexShape* shape); + ~btShapeHull (); + + bool buildHull (btScalar margin); + + int numTriangles () const; + int numVertices () const; + int numIndices () const; + + const btVector3* getVertexPointer() const + { + return &m_vertices[0]; + } + const unsigned int* getIndexPointer() const + { + return &m_indices[0]; + } +}; + +#endif //BT_SHAPE_HULL_H diff --git a/src/BulletCollision/CollisionShapes/btSphereShape.cpp b/src/BulletCollision/CollisionShapes/btSphereShape.cpp new file mode 100644 index 0000000..b9a736c --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btSphereShape.cpp @@ -0,0 +1,71 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSphereShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "LinearMath/btQuaternion.h" + +btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + (void)vec; + return btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); +} + +void btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + (void)vectors; + + for (int i=0;iprocessTriangle(triangle,0,0); + + triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius; + triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius; + triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius; + + callback->processTriangle(triangle,0,1); + +} + +void btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + (void)mass; + + //moving concave objects not supported + + inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +} + +void btStaticPlaneShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; +} +const btVector3& btStaticPlaneShape::getLocalScaling() const +{ + return m_localScaling; +} diff --git a/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h new file mode 100644 index 0000000..e6e3288 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h @@ -0,0 +1,105 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_STATIC_PLANE_SHAPE_H +#define BT_STATIC_PLANE_SHAPE_H + +#include "btConcaveShape.h" + + +///The btStaticPlaneShape simulates an infinite non-moving (static) collision plane. +ATTRIBUTE_ALIGNED16(class) btStaticPlaneShape : public btConcaveShape +{ +protected: + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + + btVector3 m_planeNormal; + btScalar m_planeConstant; + btVector3 m_localScaling; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant); + + virtual ~btStaticPlaneShape(); + + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; + + const btVector3& getPlaneNormal() const + { + return m_planeNormal; + } + + const btScalar& getPlaneConstant() const + { + return m_planeConstant; + } + + //debugging + virtual const char* getName()const {return "STATICPLANE";} + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btStaticPlaneShapeData +{ + btCollisionShapeData m_collisionShapeData; + + btVector3FloatData m_localScaling; + btVector3FloatData m_planeNormal; + float m_planeConstant; + char m_pad[4]; +}; + + +SIMD_FORCE_INLINE int btStaticPlaneShape::calculateSerializeBufferSize() const +{ + return sizeof(btStaticPlaneShapeData); +} + +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btStaticPlaneShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) dataBuffer; + btCollisionShape::serialize(&planeData->m_collisionShapeData,serializer); + + m_localScaling.serializeFloat(planeData->m_localScaling); + m_planeNormal.serializeFloat(planeData->m_planeNormal); + planeData->m_planeConstant = float(m_planeConstant); + + return "btStaticPlaneShapeData"; +} + + +#endif //BT_STATIC_PLANE_SHAPE_H + + + diff --git a/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp new file mode 100644 index 0000000..b3d4496 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp @@ -0,0 +1,381 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btStridingMeshInterface.h" +#include "LinearMath/btSerializer.h" + +btStridingMeshInterface::~btStridingMeshInterface() +{ + +} + + +void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + (void)aabbMin; + (void)aabbMax; + int numtotalphysicsverts = 0; + int part,graphicssubparts = getNumSubParts(); + const unsigned char * vertexbase; + const unsigned char * indexbase; + int indexstride; + PHY_ScalarType type; + PHY_ScalarType gfxindextype; + int stride,numverts,numtriangles; + int gfxindex; + btVector3 triangle[3]; + + btVector3 meshScaling = getScaling(); + + ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype + for (part=0;partinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + case PHY_SHORT: + { + for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + case PHY_UCHAR: + { + for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + default: + btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); + } + break; + } + + case PHY_DOUBLE: + { + double* graphicsbase; + + switch (gfxindextype) + { + case PHY_INTEGER: + { + for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + case PHY_SHORT: + { + for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + case PHY_UCHAR: + { + for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + default: + btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); + } + break; + } + default: + btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); + } + + unLockReadOnlyVertexBase(part); + } +} + +void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax) +{ + + struct AabbCalculationCallback : public btInternalTriangleIndexCallback + { + btVector3 m_aabbMin; + btVector3 m_aabbMax; + + AabbCalculationCallback() + { + m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + (void)partId; + (void)triangleIndex; + + m_aabbMin.setMin(triangle[0]); + m_aabbMax.setMax(triangle[0]); + m_aabbMin.setMin(triangle[1]); + m_aabbMax.setMax(triangle[1]); + m_aabbMin.setMin(triangle[2]); + m_aabbMax.setMax(triangle[2]); + } + }; + + //first calculate the total aabb for all triangles + AabbCalculationCallback aabbCallback; + aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax); + + aabbMin = aabbCallback.m_aabbMin; + aabbMax = aabbCallback.m_aabbMax; +} + + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer; + + trimeshData->m_numMeshParts = getNumSubParts(); + + //void* uniquePtr = 0; + + trimeshData->m_meshPartsPtr = 0; + + if (trimeshData->m_numMeshParts) + { + btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts); + btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr; + trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr); + + + // int numtotalphysicsverts = 0; + int part,graphicssubparts = getNumSubParts(); + const unsigned char * vertexbase; + const unsigned char * indexbase; + int indexstride; + PHY_ScalarType type; + PHY_ScalarType gfxindextype; + int stride,numverts,numtriangles; + int gfxindex; + // btVector3 triangle[3]; + + // btVector3 meshScaling = getScaling(); + + ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype + for (part=0;partm_numTriangles = numtriangles;//indices = 3*numtriangles + memPtr->m_numVertices = numverts; + memPtr->m_indices16 = 0; + memPtr->m_indices32 = 0; + memPtr->m_3indices16 = 0; + memPtr->m_3indices8 = 0; + memPtr->m_vertices3f = 0; + memPtr->m_vertices3d = 0; + + + switch (gfxindextype) + { + case PHY_INTEGER: + { + int numindices = numtriangles*3; + + if (numindices) + { + btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices); + btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr; + memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices); + for (gfxindex=0;gfxindexfinalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + } + break; + } + case PHY_SHORT: + { + if (numtriangles) + { + btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles); + btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr; + memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices); + for (gfxindex=0;gfxindexfinalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + } + break; + } + case PHY_UCHAR: + { + if (numtriangles) + { + btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles); + btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr; + memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices); + for (gfxindex=0;gfxindexfinalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + } + break; + } + default: + { + btAssert(0); + //unknown index type + } + } + + switch (type) + { + case PHY_FLOAT: + { + float* graphicsbase; + + if (numverts) + { + btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts); + btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr; + memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices); + for (int i=0;ifinalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + } + break; + } + + case PHY_DOUBLE: + { + if (numverts) + { + btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts); + btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr; + memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices); + for (int i=0;ifinalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + } + break; + } + + default: + btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); + } + + unLockReadOnlyVertexBase(part); + } + + serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr); + } + + + m_scaling.serializeFloat(trimeshData->m_scaling); + return "btStridingMeshInterfaceData"; +} diff --git a/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h new file mode 100644 index 0000000..9fbe139 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h @@ -0,0 +1,164 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_STRIDING_MESHINTERFACE_H +#define BT_STRIDING_MESHINTERFACE_H + +#include "LinearMath/btVector3.h" +#include "btTriangleCallback.h" +#include "btConcaveShape.h" + + + + + +/// The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes. +/// Using index striding of 3*sizeof(integer) it can use triangle arrays, using index striding of 1*sizeof(integer) it can handle triangle strips. +/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory. +ATTRIBUTE_ALIGNED16(class ) btStridingMeshInterface +{ + protected: + + btVector3 m_scaling; + + public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btStridingMeshInterface() :m_scaling(btScalar(1.),btScalar(1.),btScalar(1.)) + { + + } + + virtual ~btStridingMeshInterface(); + + + + virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + ///brute force method to calculate aabb + void calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax); + + /// get read and write access to a subpart of a triangle mesh + /// this subpart has a continuous array of vertices and indices + /// in this way the mesh can be handled as chunks of memory with striding + /// very similar to OpenGL vertexarray support + /// make a call to unLockVertexBase when the read and write access is finished + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0; + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const=0; + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart)=0; + + virtual void unLockReadOnlyVertexBase(int subpart) const=0; + + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const=0; + + virtual void preallocateVertices(int numverts)=0; + virtual void preallocateIndices(int numindices)=0; + + virtual bool hasPremadeAabb() const { return false; } + virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const + { + (void) aabbMin; + (void) aabbMax; + } + virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const + { + (void) aabbMin; + (void) aabbMax; + } + + const btVector3& getScaling() const { + return m_scaling; + } + void setScaling(const btVector3& scaling) + { + m_scaling = scaling; + } + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +struct btIntIndexData +{ + int m_value; +}; + +struct btShortIntIndexData +{ + short m_value; + char m_pad[2]; +}; + +struct btShortIntIndexTripletData +{ + short m_values[3]; + char m_pad[2]; +}; + +struct btCharIndexTripletData +{ + unsigned char m_values[3]; + char m_pad; +}; + + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btMeshPartData +{ + btVector3FloatData *m_vertices3f; + btVector3DoubleData *m_vertices3d; + + btIntIndexData *m_indices32; + btShortIntIndexTripletData *m_3indices16; + btCharIndexTripletData *m_3indices8; + + btShortIntIndexData *m_indices16;//backwards compatibility + + int m_numTriangles;//length of m_indices = m_numTriangles + int m_numVertices; +}; + + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btStridingMeshInterfaceData +{ + btMeshPartData *m_meshPartsPtr; + btVector3FloatData m_scaling; + int m_numMeshParts; + char m_padding[4]; +}; + + + + +SIMD_FORCE_INLINE int btStridingMeshInterface::calculateSerializeBufferSize() const +{ + return sizeof(btStridingMeshInterfaceData); +} + + + +#endif //BT_STRIDING_MESHINTERFACE_H diff --git a/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp b/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp new file mode 100644 index 0000000..52f346b --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp @@ -0,0 +1,218 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btTetrahedronShape.h" +#include "LinearMath/btMatrix3x3.h" + +btBU_Simplex1to4::btBU_Simplex1to4() : btPolyhedralConvexAabbCachingShape (), +m_numVertices(0) +{ + m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexAabbCachingShape (), +m_numVertices(0) +{ + m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; + addVertex(pt0); +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1) : btPolyhedralConvexAabbCachingShape (), +m_numVertices(0) +{ + m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; + addVertex(pt0); + addVertex(pt1); +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexAabbCachingShape (), +m_numVertices(0) +{ + m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; + addVertex(pt0); + addVertex(pt1); + addVertex(pt2); +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexAabbCachingShape (), +m_numVertices(0) +{ + m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; + addVertex(pt0); + addVertex(pt1); + addVertex(pt2); + addVertex(pt3); +} + + +void btBU_Simplex1to4::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ +#if 1 + btPolyhedralConvexAabbCachingShape::getAabb(t,aabbMin,aabbMax); +#else + aabbMin.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + aabbMax.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + + //just transform the vertices in worldspace, and take their AABB + for (int i=0;iprocessAllTriangles(&triBuf,aabbMin, aabbMax); +/// for (int i=0;i m_triangleBuffer; + +public: + + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); + + int getNumTriangles() const + { + return int(m_triangleBuffer.size()); + } + + const btTriangle& getTriangle(int index) const + { + return m_triangleBuffer[index]; + } + + void clearBuffer() + { + m_triangleBuffer.clear(); + } + +}; + + +#endif //BT_TRIANGLE_BUFFER_H + diff --git a/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp b/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp new file mode 100644 index 0000000..f558bf6 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp @@ -0,0 +1,28 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btTriangleCallback.h" + +btTriangleCallback::~btTriangleCallback() +{ + +} + + +btInternalTriangleIndexCallback::~btInternalTriangleIndexCallback() +{ + +} + diff --git a/src/BulletCollision/CollisionShapes/btTriangleCallback.h b/src/BulletCollision/CollisionShapes/btTriangleCallback.h new file mode 100644 index 0000000..461c57f --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleCallback.h @@ -0,0 +1,42 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_TRIANGLE_CALLBACK_H +#define BT_TRIANGLE_CALLBACK_H + +#include "LinearMath/btVector3.h" + + +///The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTriangles. +///This callback is called by processAllTriangles for all btConcaveShape derived class, such as btBvhTriangleMeshShape, btStaticPlaneShape and btHeightfieldTerrainShape. +class btTriangleCallback +{ +public: + + virtual ~btTriangleCallback(); + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) = 0; +}; + +class btInternalTriangleIndexCallback +{ +public: + + virtual ~btInternalTriangleIndexCallback(); + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) = 0; +}; + + + +#endif //BT_TRIANGLE_CALLBACK_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp new file mode 100644 index 0000000..a665024 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp @@ -0,0 +1,95 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btTriangleIndexVertexArray.h" + +btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride) +: m_hasAabb(0) +{ + btIndexedMesh mesh; + + mesh.m_numTriangles = numTriangles; + mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase; + mesh.m_triangleIndexStride = triangleIndexStride; + mesh.m_numVertices = numVertices; + mesh.m_vertexBase = (const unsigned char *)vertexBase; + mesh.m_vertexStride = vertexStride; + + addIndexedMesh(mesh); + +} + +btTriangleIndexVertexArray::~btTriangleIndexVertexArray() +{ + +} + +void btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) +{ + btAssert(subpart< getNumSubParts() ); + + btIndexedMesh& mesh = m_indexedMeshes[subpart]; + + numverts = mesh.m_numVertices; + (*vertexbase) = (unsigned char *) mesh.m_vertexBase; + + type = mesh.m_vertexType; + + vertexStride = mesh.m_vertexStride; + + numfaces = mesh.m_numTriangles; + + (*indexbase) = (unsigned char *)mesh.m_triangleIndexBase; + indexstride = mesh.m_triangleIndexStride; + indicestype = mesh.m_indexType; +} + +void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const +{ + const btIndexedMesh& mesh = m_indexedMeshes[subpart]; + + numverts = mesh.m_numVertices; + (*vertexbase) = (const unsigned char *)mesh.m_vertexBase; + + type = mesh.m_vertexType; + + vertexStride = mesh.m_vertexStride; + + numfaces = mesh.m_numTriangles; + (*indexbase) = (const unsigned char *)mesh.m_triangleIndexBase; + indexstride = mesh.m_triangleIndexStride; + indicestype = mesh.m_indexType; +} + +bool btTriangleIndexVertexArray::hasPremadeAabb() const +{ + return (m_hasAabb == 1); +} + + +void btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const +{ + m_aabbMin = aabbMin; + m_aabbMax = aabbMax; + m_hasAabb = 1; // this is intentionally an int see notes in header +} + +void btTriangleIndexVertexArray::getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const +{ + *aabbMin = m_aabbMin; + *aabbMax = m_aabbMax; +} + + diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h new file mode 100644 index 0000000..9e1544e --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h @@ -0,0 +1,133 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_TRIANGLE_INDEX_VERTEX_ARRAY_H +#define BT_TRIANGLE_INDEX_VERTEX_ARRAY_H + +#include "btStridingMeshInterface.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btScalar.h" + + +///The btIndexedMesh indexes a single vertex and index array. Multiple btIndexedMesh objects can be passed into a btTriangleIndexVertexArray using addIndexedMesh. +///Instead of the number of indices, we pass the number of triangles. +ATTRIBUTE_ALIGNED16( struct) btIndexedMesh +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + int m_numTriangles; + const unsigned char * m_triangleIndexBase; + // Size in byte of the indices for one triangle (3*sizeof(index_type) if the indices are tightly packed) + int m_triangleIndexStride; + int m_numVertices; + const unsigned char * m_vertexBase; + // Size of a vertex, in bytes + int m_vertexStride; + + // The index type is set when adding an indexed mesh to the + // btTriangleIndexVertexArray, do not set it manually + PHY_ScalarType m_indexType; + + // The vertex type has a default type similar to Bullet's precision mode (float or double) + // but can be set manually if you for example run Bullet with double precision but have + // mesh data in single precision.. + PHY_ScalarType m_vertexType; + + + btIndexedMesh() + :m_indexType(PHY_INTEGER), +#ifdef BT_USE_DOUBLE_PRECISION + m_vertexType(PHY_DOUBLE) +#else // BT_USE_DOUBLE_PRECISION + m_vertexType(PHY_FLOAT) +#endif // BT_USE_DOUBLE_PRECISION + { + } +} +; + + +typedef btAlignedObjectArray IndexedMeshArray; + +///The btTriangleIndexVertexArray allows to access multiple triangle meshes, by indexing into existing triangle/index arrays. +///Additional meshes can be added using addIndexedMesh +///No duplcate is made of the vertex/index data, it only indexes into external vertex/index arrays. +///So keep those arrays around during the lifetime of this btTriangleIndexVertexArray. +ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshInterface +{ +protected: + IndexedMeshArray m_indexedMeshes; + int m_pad[2]; + mutable int m_hasAabb; // using int instead of bool to maintain alignment + mutable btVector3 m_aabbMin; + mutable btVector3 m_aabbMax; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btTriangleIndexVertexArray() : m_hasAabb(0) + { + } + + virtual ~btTriangleIndexVertexArray(); + + //just to be backwards compatible + btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride); + + void addIndexedMesh(const btIndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER) + { + m_indexedMeshes.push_back(mesh); + m_indexedMeshes[m_indexedMeshes.size()-1].m_indexType = indexType; + } + + + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart) {(void)subpart;} + + virtual void unLockReadOnlyVertexBase(int subpart) const {(void)subpart;} + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const { + return (int)m_indexedMeshes.size(); + } + + IndexedMeshArray& getIndexedMeshArray() + { + return m_indexedMeshes; + } + + const IndexedMeshArray& getIndexedMeshArray() const + { + return m_indexedMeshes; + } + + virtual void preallocateVertices(int numverts){(void) numverts;} + virtual void preallocateIndices(int numindices){(void) numindices;} + + virtual bool hasPremadeAabb() const; + virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const; + virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const; + +} +; + +#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp new file mode 100644 index 0000000..dc56294 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp @@ -0,0 +1,86 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///This file was created by Alex Silverman + +#include "btTriangleIndexVertexMaterialArray.h" + +btTriangleIndexVertexMaterialArray::btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride, + int numVertices,btScalar* vertexBase,int vertexStride, + int numMaterials, unsigned char* materialBase, int materialStride, + int* triangleMaterialsBase, int materialIndexStride) : +btTriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride) +{ + btMaterialProperties mat; + + mat.m_numMaterials = numMaterials; + mat.m_materialBase = materialBase; + mat.m_materialStride = materialStride; +#ifdef BT_USE_DOUBLE_PRECISION + mat.m_materialType = PHY_DOUBLE; +#else + mat.m_materialType = PHY_FLOAT; +#endif + + mat.m_numTriangles = numTriangles; + mat.m_triangleMaterialsBase = (unsigned char *)triangleMaterialsBase; + mat.m_triangleMaterialStride = materialIndexStride; + mat.m_triangleType = PHY_INTEGER; + + addMaterialProperties(mat); +} + + +void btTriangleIndexVertexMaterialArray::getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) +{ + btAssert(subpart< getNumSubParts() ); + + btMaterialProperties& mats = m_materials[subpart]; + + numMaterials = mats.m_numMaterials; + (*materialBase) = (unsigned char *) mats.m_materialBase; +#ifdef BT_USE_DOUBLE_PRECISION + materialType = PHY_DOUBLE; +#else + materialType = PHY_FLOAT; +#endif + materialStride = mats.m_materialStride; + + numTriangles = mats.m_numTriangles; + (*triangleMaterialBase) = (unsigned char *)mats.m_triangleMaterialsBase; + triangleMaterialStride = mats.m_triangleMaterialStride; + triangleType = mats.m_triangleType; +} + +void btTriangleIndexVertexMaterialArray::getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) +{ + btMaterialProperties& mats = m_materials[subpart]; + + numMaterials = mats.m_numMaterials; + (*materialBase) = (const unsigned char *) mats.m_materialBase; +#ifdef BT_USE_DOUBLE_PRECISION + materialType = PHY_DOUBLE; +#else + materialType = PHY_FLOAT; +#endif + materialStride = mats.m_materialStride; + + numTriangles = mats.m_numTriangles; + (*triangleMaterialBase) = (const unsigned char *)mats.m_triangleMaterialsBase; + triangleMaterialStride = mats.m_triangleMaterialStride; + triangleType = mats.m_triangleType; +} diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h new file mode 100644 index 0000000..ba4f7b4 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h @@ -0,0 +1,84 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///This file was created by Alex Silverman + +#ifndef BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H +#define BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H + +#include "btTriangleIndexVertexArray.h" + + +ATTRIBUTE_ALIGNED16( struct) btMaterialProperties +{ + ///m_materialBase ==========> 2 btScalar values make up one material, friction then restitution + int m_numMaterials; + const unsigned char * m_materialBase; + int m_materialStride; + PHY_ScalarType m_materialType; + ///m_numTriangles <=========== This exists in the btIndexedMesh object for the same subpart, but since we're + /// padding the structure, it can be reproduced at no real cost + ///m_triangleMaterials =====> 1 integer value makes up one entry + /// eg: m_triangleMaterials[1] = 5; // This will set triangle 2 to use material 5 + int m_numTriangles; + const unsigned char * m_triangleMaterialsBase; + int m_triangleMaterialStride; + ///m_triangleType <========== Automatically set in addMaterialProperties + PHY_ScalarType m_triangleType; +}; + +typedef btAlignedObjectArray MaterialArray; + +///Teh btTriangleIndexVertexMaterialArray is built on TriangleIndexVertexArray +///The addition of a material array allows for the utilization of the partID and +///triangleIndex that are returned in the ContactAddedCallback. As with +///TriangleIndexVertexArray, no duplicate is made of the material data, so it +///is the users responsibility to maintain the array during the lifetime of the +///TriangleIndexVertexMaterialArray. +ATTRIBUTE_ALIGNED16(class) btTriangleIndexVertexMaterialArray : public btTriangleIndexVertexArray +{ +protected: + MaterialArray m_materials; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btTriangleIndexVertexMaterialArray() + { + } + + btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride, + int numVertices,btScalar* vertexBase,int vertexStride, + int numMaterials, unsigned char* materialBase, int materialStride, + int* triangleMaterialsBase, int materialIndexStride); + + virtual ~btTriangleIndexVertexMaterialArray() {} + + void addMaterialProperties(const btMaterialProperties& mat, PHY_ScalarType triangleType = PHY_INTEGER) + { + m_materials.push_back(mat); + m_materials[m_materials.size()-1].m_triangleType = triangleType; + } + + virtual void getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType ,int subpart = 0); + + virtual void getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart = 0); + +} +; + +#endif //BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h b/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h new file mode 100644 index 0000000..17deef8 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h @@ -0,0 +1,241 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2010 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _BT_TRIANGLE_INFO_MAP_H +#define _BT_TRIANGLE_INFO_MAP_H + + +#include "LinearMath/btHashMap.h" +#include "LinearMath/btSerializer.h" + + +///for btTriangleInfo m_flags +#define TRI_INFO_V0V1_CONVEX 1 +#define TRI_INFO_V1V2_CONVEX 2 +#define TRI_INFO_V2V0_CONVEX 4 + +#define TRI_INFO_V0V1_SWAP_NORMALB 8 +#define TRI_INFO_V1V2_SWAP_NORMALB 16 +#define TRI_INFO_V2V0_SWAP_NORMALB 32 + + +///The btTriangleInfo structure stores information to adjust collision normals to avoid collisions against internal edges +///it can be generated using +struct btTriangleInfo +{ + btTriangleInfo() + { + m_edgeV0V1Angle = SIMD_2_PI; + m_edgeV1V2Angle = SIMD_2_PI; + m_edgeV2V0Angle = SIMD_2_PI; + m_flags=0; + } + + int m_flags; + + btScalar m_edgeV0V1Angle; + btScalar m_edgeV1V2Angle; + btScalar m_edgeV2V0Angle; + +}; + +typedef btHashMap btInternalTriangleInfoMap; + + +///The btTriangleInfoMap stores edge angle information for some triangles. You can compute this information yourself or using btGenerateInternalEdgeInfo. +struct btTriangleInfoMap : public btInternalTriangleInfoMap +{ + btScalar m_convexEpsilon;///used to determine if an edge or contact normal is convex, using the dot product + btScalar m_planarEpsilon; ///used to determine if a triangle edge is planar with zero angle + btScalar m_equalVertexThreshold; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared' + btScalar m_edgeDistanceThreshold; ///used to determine edge contacts: if the closest distance between a contact point and an edge is smaller than this distance threshold it is considered to "hit the edge" + btScalar m_maxEdgeAngleThreshold; //ignore edges that connect triangles at an angle larger than this m_maxEdgeAngleThreshold + btScalar m_zeroAreaThreshold; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold) + + + btTriangleInfoMap() + { + m_convexEpsilon = 0.00f; + m_planarEpsilon = 0.0001f; + m_equalVertexThreshold = btScalar(0.0001)*btScalar(0.0001); + m_edgeDistanceThreshold = btScalar(0.1); + m_zeroAreaThreshold = btScalar(0.0001)*btScalar(0.0001); + m_maxEdgeAngleThreshold = SIMD_2_PI; + } + virtual ~btTriangleInfoMap() {} + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + void deSerialize(struct btTriangleInfoMapData& data); + +}; + +///those fields have to be float and not btScalar for the serialization to work properly +struct btTriangleInfoData +{ + int m_flags; + float m_edgeV0V1Angle; + float m_edgeV1V2Angle; + float m_edgeV2V0Angle; +}; + +struct btTriangleInfoMapData +{ + int *m_hashTablePtr; + int *m_nextPtr; + btTriangleInfoData *m_valueArrayPtr; + int *m_keyArrayPtr; + + float m_convexEpsilon; + float m_planarEpsilon; + float m_equalVertexThreshold; + float m_edgeDistanceThreshold; + float m_zeroAreaThreshold; + + int m_nextSize; + int m_hashTableSize; + int m_numValues; + int m_numKeys; + char m_padding[4]; +}; + +SIMD_FORCE_INLINE int btTriangleInfoMap::calculateSerializeBufferSize() const +{ + return sizeof(btTriangleInfoMapData); +} + +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*) dataBuffer; + tmapData->m_convexEpsilon = (float)m_convexEpsilon; + tmapData->m_planarEpsilon = (float)m_planarEpsilon; + tmapData->m_equalVertexThreshold =(float) m_equalVertexThreshold; + tmapData->m_edgeDistanceThreshold = (float)m_edgeDistanceThreshold; + tmapData->m_zeroAreaThreshold = (float)m_zeroAreaThreshold; + + tmapData->m_hashTableSize = m_hashTable.size(); + + tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)serializer->getUniquePointer((void*)&m_hashTable[0]) : 0; + if (tmapData->m_hashTablePtr) + { + //serialize an int buffer + int sz = sizeof(int); + int numElem = tmapData->m_hashTableSize; + btChunk* chunk = serializer->allocate(sz,numElem); + int* memPtr = (int*)chunk->m_oldPtr; + for (int i=0;ifinalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_hashTable[0]); + + } + + tmapData->m_nextSize = m_next.size(); + tmapData->m_nextPtr = tmapData->m_nextSize? (int*)serializer->getUniquePointer((void*)&m_next[0]): 0; + if (tmapData->m_nextPtr) + { + int sz = sizeof(int); + int numElem = tmapData->m_nextSize; + btChunk* chunk = serializer->allocate(sz,numElem); + int* memPtr = (int*)chunk->m_oldPtr; + for (int i=0;ifinalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_next[0]); + } + + tmapData->m_numValues = m_valueArray.size(); + tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]): 0; + if (tmapData->m_valueArrayPtr) + { + int sz = sizeof(btTriangleInfoData); + int numElem = tmapData->m_numValues; + btChunk* chunk = serializer->allocate(sz,numElem); + btTriangleInfoData* memPtr = (btTriangleInfoData*)chunk->m_oldPtr; + for (int i=0;im_edgeV0V1Angle = (float)m_valueArray[i].m_edgeV0V1Angle; + memPtr->m_edgeV1V2Angle = (float)m_valueArray[i].m_edgeV1V2Angle; + memPtr->m_edgeV2V0Angle = (float)m_valueArray[i].m_edgeV2V0Angle; + memPtr->m_flags = m_valueArray[i].m_flags; + } + serializer->finalizeChunk(chunk,"btTriangleInfoData",BT_ARRAY_CODE,(void*) &m_valueArray[0]); + } + + tmapData->m_numKeys = m_keyArray.size(); + tmapData->m_keyArrayPtr = tmapData->m_numKeys ? (int*)serializer->getUniquePointer((void*)&m_keyArray[0]) : 0; + if (tmapData->m_keyArrayPtr) + { + int sz = sizeof(int); + int numElem = tmapData->m_numValues; + btChunk* chunk = serializer->allocate(sz,numElem); + int* memPtr = (int*)chunk->m_oldPtr; + for (int i=0;ifinalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*) &m_keyArray[0]); + + } + return "btTriangleInfoMapData"; +} + + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE void btTriangleInfoMap::deSerialize(btTriangleInfoMapData& tmapData ) +{ + + + m_convexEpsilon = tmapData.m_convexEpsilon; + m_planarEpsilon = tmapData.m_planarEpsilon; + m_equalVertexThreshold = tmapData.m_equalVertexThreshold; + m_edgeDistanceThreshold = tmapData.m_edgeDistanceThreshold; + m_zeroAreaThreshold = tmapData.m_zeroAreaThreshold; + m_hashTable.resize(tmapData.m_hashTableSize); + int i =0; + for (i=0;i m_4componentVertices; + btAlignedObjectArray m_3componentVertices; + + btAlignedObjectArray m_32bitIndices; + btAlignedObjectArray m_16bitIndices; + bool m_use32bitIndices; + bool m_use4componentVertices; + + + public: + btScalar m_weldingThreshold; + + btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true); + + bool getUse32bitIndices() const + { + return m_use32bitIndices; + } + + bool getUse4componentVertices() const + { + return m_use4componentVertices; + } + ///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes. + ///In general it is better to directly use btTriangleIndexVertexArray instead. + void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false); + + int getNumTriangles() const; + + virtual void preallocateVertices(int numverts); + virtual void preallocateIndices(int numindices); + + ///findOrAddVertex is an internal method, use addTriangle instead + int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices); + ///addIndex is an internal method, use addTriangle instead + void addIndex(int index); + +}; + +#endif //BT_TRIANGLE_MESH_H + diff --git a/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp new file mode 100644 index 0000000..0e17951 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp @@ -0,0 +1,207 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btTriangleMeshShape.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btQuaternion.h" +#include "btStridingMeshInterface.h" +#include "LinearMath/btAabbUtil2.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + + +btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface) +: btConcaveShape (), m_meshInterface(meshInterface) +{ + m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; + if(meshInterface->hasPremadeAabb()) + { + meshInterface->getPremadeAabb(&m_localAabbMin, &m_localAabbMax); + } + else + { + recalcLocalAabb(); + } +} + + +btTriangleMeshShape::~btTriangleMeshShape() +{ + +} + + + + +void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + + btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); + localHalfExtents += btVector3(getMargin(),getMargin(),getMargin()); + btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); + + btMatrix3x3 abs_b = trans.getBasis().absolute(); + + btVector3 center = trans(localCenter); + + btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMin = center - extent; + aabbMax = center + extent; +} + +void btTriangleMeshShape::recalcLocalAabb() +{ + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + btVector3 tmp = localGetSupportingVertex(vec); + m_localAabbMax[i] = tmp[i]+m_collisionMargin; + vec[i] = btScalar(-1.); + tmp = localGetSupportingVertex(vec); + m_localAabbMin[i] = tmp[i]-m_collisionMargin; + } +} + + + +class SupportVertexCallback : public btTriangleCallback +{ + + btVector3 m_supportVertexLocal; +public: + + btTransform m_worldTrans; + btScalar m_maxDot; + btVector3 m_supportVecLocal; + + SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans) + : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-BT_LARGE_FLOAT)) + + { + m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis(); + } + + virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; + for (int i=0;i<3;i++) + { + btScalar dot = m_supportVecLocal.dot(triangle[i]); + if (dot > m_maxDot) + { + m_maxDot = dot; + m_supportVertexLocal = triangle[i]; + } + } + } + + btVector3 GetSupportVertexWorldSpace() + { + return m_worldTrans(m_supportVertexLocal); + } + + btVector3 GetSupportVertexLocal() + { + return m_supportVertexLocal; + } + +}; + + +void btTriangleMeshShape::setLocalScaling(const btVector3& scaling) +{ + m_meshInterface->setScaling(scaling); + recalcLocalAabb(); +} + +const btVector3& btTriangleMeshShape::getLocalScaling() const +{ + return m_meshInterface->getScaling(); +} + + + + + + +//#define DEBUG_TRIANGLE_MESH + + + +void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + struct FilteredCallback : public btInternalTriangleIndexCallback + { + btTriangleCallback* m_callback; + btVector3 m_aabbMin; + btVector3 m_aabbMax; + + FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) + :m_callback(callback), + m_aabbMin(aabbMin), + m_aabbMax(aabbMax) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax)) + { + //check aabb in triangle-space, before doing this + m_callback->processTriangle(triangle,partId,triangleIndex); + } + + } + + }; + + FilteredCallback filterCallback(callback,aabbMin,aabbMax); + + m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax); +} + + + + + +void btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + (void)mass; + //moving concave objects not supported + btAssert(0); + inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +} + + +btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const +{ + btVector3 supportVertex; + + btTransform ident; + ident.setIdentity(); + + SupportVertexCallback supportCallback(vec,ident); + + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + + processAllTriangles(&supportCallback,-aabbMax,aabbMax); + + supportVertex = supportCallback.GetSupportVertexLocal(); + + return supportVertex; +} + + diff --git a/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h new file mode 100644 index 0000000..453e580 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h @@ -0,0 +1,90 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_TRIANGLE_MESH_SHAPE_H +#define BT_TRIANGLE_MESH_SHAPE_H + +#include "btConcaveShape.h" +#include "btStridingMeshInterface.h" + + +///The btTriangleMeshShape is an internal concave triangle mesh interface. Don't use this class directly, use btBvhTriangleMeshShape instead. +ATTRIBUTE_ALIGNED16(class) btTriangleMeshShape : public btConcaveShape +{ +protected: + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + btStridingMeshInterface* m_meshInterface; + + ///btTriangleMeshShape constructor has been disabled/protected, so that users will not mistakenly use this class. + ///Don't use btTriangleMeshShape but use btBvhTriangleMeshShape instead! + btTriangleMeshShape(btStridingMeshInterface* meshInterface); + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + virtual ~btTriangleMeshShape(); + + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + { + btAssert(0); + return localGetSupportingVertex(vec); + } + + void recalcLocalAabb(); + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; + + btStridingMeshInterface* getMeshInterface() + { + return m_meshInterface; + } + + const btStridingMeshInterface* getMeshInterface() const + { + return m_meshInterface; + } + + const btVector3& getLocalAabbMin() const + { + return m_localAabbMin; + } + const btVector3& getLocalAabbMax() const + { + return m_localAabbMax; + } + + + + //debugging + virtual const char* getName()const {return "TRIANGLEMESH";} + + + +}; + + + + +#endif //BT_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleShape.h b/src/BulletCollision/CollisionShapes/btTriangleShape.h new file mode 100644 index 0000000..a8a80f8 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleShape.h @@ -0,0 +1,184 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_OBB_TRIANGLE_MINKOWSKI_H +#define BT_OBB_TRIANGLE_MINKOWSKI_H + +#include "btConvexShape.h" +#include "btBoxShape.h" + +ATTRIBUTE_ALIGNED16(class) btTriangleShape : public btPolyhedralConvexShape +{ + + +public: + +BT_DECLARE_ALIGNED_ALLOCATOR(); + + btVector3 m_vertices1[3]; + + virtual int getNumVertices() const + { + return 3; + } + + btVector3& getVertexPtr(int index) + { + return m_vertices1[index]; + } + + const btVector3& getVertexPtr(int index) const + { + return m_vertices1[index]; + } + virtual void getVertex(int index,btVector3& vert) const + { + vert = m_vertices1[index]; + } + + virtual int getNumEdges() const + { + return 3; + } + + virtual void getEdge(int i,btVector3& pa,btVector3& pb) const + { + getVertex(i,pa); + getVertex((i+1)%3,pb); + } + + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const + { +// btAssert(0); + getAabbSlow(t,aabbMin,aabbMax); + } + + btVector3 localGetSupportingVertexWithoutMargin(const btVector3& dir)const + { + btVector3 dots = dir.dot3(m_vertices1[0], m_vertices1[1], m_vertices1[2]); + return m_vertices1[dots.maxAxis()]; + + } + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + { + for (int i=0;i= -tolerance && dist <= tolerance) + { + //inside check on edge-planes + int i; + for (i=0;i<3;i++) + { + btVector3 pa,pb; + getEdge(i,pa,pb); + btVector3 edge = pb-pa; + btVector3 edgeNormal = edge.cross(normal); + edgeNormal.normalize(); + btScalar dist = pt.dot( edgeNormal); + btScalar edgeConst = pa.dot(edgeNormal); + dist -= edgeConst; + if (dist < -tolerance) + return false; + } + + return true; + } + + return false; + } + //debugging + virtual const char* getName()const + { + return "Triangle"; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 2; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + calcNormal(penetrationVector); + if (index) + penetrationVector *= btScalar(-1.); + } + + +}; + +#endif //BT_OBB_TRIANGLE_MINKOWSKI_H + diff --git a/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp b/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp new file mode 100644 index 0000000..b148bbd --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp @@ -0,0 +1,160 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btUniformScalingShape.h" + +btUniformScalingShape::btUniformScalingShape( btConvexShape* convexChildShape,btScalar uniformScalingFactor): +btConvexShape (), m_childConvexShape(convexChildShape), +m_uniformScalingFactor(uniformScalingFactor) +{ + m_shapeType = UNIFORM_SCALING_SHAPE_PROXYTYPE; +} + +btUniformScalingShape::~btUniformScalingShape() +{ +} + + +btVector3 btUniformScalingShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + btVector3 tmpVertex; + tmpVertex = m_childConvexShape->localGetSupportingVertexWithoutMargin(vec); + return tmpVertex*m_uniformScalingFactor; +} + +void btUniformScalingShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors); + int i; + for (i=0;ilocalGetSupportingVertex(vec); + return tmpVertex*m_uniformScalingFactor; +} + + +void btUniformScalingShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + + ///this linear upscaling is not realistic, but we don't deal with large mass ratios... + btVector3 tmpInertia; + m_childConvexShape->calculateLocalInertia(mass,tmpInertia); + inertia = tmpInertia * m_uniformScalingFactor; +} + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btUniformScalingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + getAabbSlow(trans,aabbMin,aabbMax); + +} + +void btUniformScalingShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ +#if 1 + btVector3 _directions[] = + { + btVector3( 1., 0., 0.), + btVector3( 0., 1., 0.), + btVector3( 0., 0., 1.), + btVector3( -1., 0., 0.), + btVector3( 0., -1., 0.), + btVector3( 0., 0., -1.) + }; + + btVector3 _supporting[] = + { + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.), + btVector3( 0., 0., 0.) + }; + + for (int i=0;i<6;i++) + { + _directions[i] = _directions[i]*t.getBasis(); + } + + batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6); + + btVector3 aabbMin1(0,0,0),aabbMax1(0,0,0); + + for ( int i = 0; i < 3; ++i ) + { + aabbMax1[i] = t(_supporting[i])[i]; + aabbMin1[i] = t(_supporting[i + 3])[i]; + } + btVector3 marginVec(getMargin(),getMargin(),getMargin()); + aabbMin = aabbMin1-marginVec; + aabbMax = aabbMax1+marginVec; + +#else + + btScalar margin = getMargin(); + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + btVector3 sv = localGetSupportingVertex(vec*t.getBasis()); + btVector3 tmp = t(sv); + aabbMax[i] = tmp[i]+margin; + vec[i] = btScalar(-1.); + sv = localGetSupportingVertex(vec*t.getBasis()); + tmp = t(sv); + aabbMin[i] = tmp[i]-margin; + } + +#endif +} + +void btUniformScalingShape::setLocalScaling(const btVector3& scaling) +{ + m_childConvexShape->setLocalScaling(scaling); +} + +const btVector3& btUniformScalingShape::getLocalScaling() const +{ + return m_childConvexShape->getLocalScaling(); +} + +void btUniformScalingShape::setMargin(btScalar margin) +{ + m_childConvexShape->setMargin(margin); +} +btScalar btUniformScalingShape::getMargin() const +{ + return m_childConvexShape->getMargin() * m_uniformScalingFactor; +} + +int btUniformScalingShape::getNumPreferredPenetrationDirections() const +{ + return m_childConvexShape->getNumPreferredPenetrationDirections(); +} + +void btUniformScalingShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const +{ + m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector); +} diff --git a/src/BulletCollision/CollisionShapes/btUniformScalingShape.h b/src/BulletCollision/CollisionShapes/btUniformScalingShape.h new file mode 100644 index 0000000..a10f58d --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btUniformScalingShape.h @@ -0,0 +1,89 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_UNIFORM_SCALING_SHAPE_H +#define BT_UNIFORM_SCALING_SHAPE_H + +#include "btConvexShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types + +///The btUniformScalingShape allows to re-use uniform scaled instances of btConvexShape in a memory efficient way. +///Istead of using btUniformScalingShape, it is better to use the non-uniform setLocalScaling method on convex shapes that implement it. +ATTRIBUTE_ALIGNED16(class) btUniformScalingShape : public btConvexShape +{ + btConvexShape* m_childConvexShape; + + btScalar m_uniformScalingFactor; + + public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btUniformScalingShape( btConvexShape* convexChildShape, btScalar uniformScalingFactor); + + virtual ~btUniformScalingShape(); + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + btScalar getUniformScalingFactor() const + { + return m_uniformScalingFactor; + } + + btConvexShape* getChildShape() + { + return m_childConvexShape; + } + + const btConvexShape* getChildShape() const + { + return m_childConvexShape; + } + + virtual const char* getName()const + { + return "UniformScalingShape"; + } + + + + /////////////////////////// + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void setLocalScaling(const btVector3& scaling) ; + virtual const btVector3& getLocalScaling() const ; + + virtual void setMargin(btScalar margin); + virtual btScalar getMargin() const; + + virtual int getNumPreferredPenetrationDirections() const; + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; + + +}; + +#endif //BT_UNIFORM_SCALING_SHAPE_H diff --git a/src/BulletCollision/Doxyfile b/src/BulletCollision/Doxyfile new file mode 100644 index 0000000..4ecb6ac --- /dev/null +++ b/src/BulletCollision/Doxyfile @@ -0,0 +1,746 @@ +# Doxyfile 1.2.4 + +# This file describes the settings to be used by doxygen for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. +PROJECT_NAME = "Bullet Continuous Collision Detection Library" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, +# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian, +# Polish, Portuguese and Slovene. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a class diagram (in Html and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. + +CLASS_DIAGRAMS = YES + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The ENABLE_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +FILE_PATTERNS = *.h *.cpp *.c + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Netscape 4.0+ +# or Internet explorer 4.0+). + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using a WORD or other. +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Warning: This feature +# is still experimental and very incomplete. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = ../../generic/extern + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other +# documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented header file showing +# the documented files that directly or indirectly include this file + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = c:\program files\doxygen\bin + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/src/BulletCollision/Gimpact/btBoxCollision.h b/src/BulletCollision/Gimpact/btBoxCollision.h new file mode 100644 index 0000000..0a0357e --- /dev/null +++ b/src/BulletCollision/Gimpact/btBoxCollision.h @@ -0,0 +1,645 @@ +#ifndef BT_BOX_COLLISION_H_INCLUDED +#define BT_BOX_COLLISION_H_INCLUDED + +/*! \file gim_box_collision.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "LinearMath/btTransform.h" + + +///Swap numbers +#define BT_SWAP_NUMBERS(a,b){ \ + a = a+b; \ + b = a-b; \ + a = a-b; \ +}\ + + +#define BT_MAX(a,b) (ab?b:a) + +#define BT_GREATER(x, y) btFabs(x) > (y) + +#define BT_MAX3(a,b,c) BT_MAX(a,BT_MAX(b,c)) +#define BT_MIN3(a,b,c) BT_MIN(a,BT_MIN(b,c)) + + + + + + +enum eBT_PLANE_INTERSECTION_TYPE +{ + BT_CONST_BACK_PLANE = 0, + BT_CONST_COLLIDE_PLANE, + BT_CONST_FRONT_PLANE +}; + +//SIMD_FORCE_INLINE bool test_cross_edge_box( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, const btVector3 & extend, +// int dir_index0, +// int dir_index1 +// int component_index0, +// int component_index1) +//{ +// // dir coords are -z and y +// +// const btScalar dir0 = -edge[dir_index0]; +// const btScalar dir1 = edge[dir_index1]; +// btScalar pmin = pointa[component_index0]*dir0 + pointa[component_index1]*dir1; +// btScalar pmax = pointb[component_index0]*dir0 + pointb[component_index1]*dir1; +// //find minmax +// if(pmin>pmax) +// { +// BT_SWAP_NUMBERS(pmin,pmax); +// } +// //find extends +// const btScalar rad = extend[component_index0] * absolute_edge[dir_index0] + +// extend[component_index1] * absolute_edge[dir_index1]; +// +// if(pmin>rad || -rad>pmax) return false; +// return true; +//} +// +//SIMD_FORCE_INLINE bool test_cross_edge_box_X_axis( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, btVector3 & extend) +//{ +// +// return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,2,1,1,2); +//} +// +// +//SIMD_FORCE_INLINE bool test_cross_edge_box_Y_axis( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, btVector3 & extend) +//{ +// +// return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,0,2,2,0); +//} +// +//SIMD_FORCE_INLINE bool test_cross_edge_box_Z_axis( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, btVector3 & extend) +//{ +// +// return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1); +//} + + +#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\ +{\ + const btScalar dir0 = -edge[i_dir_0];\ + const btScalar dir1 = edge[i_dir_1];\ + btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\ + btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\ + if(pmin>pmax)\ + {\ + BT_SWAP_NUMBERS(pmin,pmax); \ + }\ + const btScalar abs_dir0 = absolute_edge[i_dir_0];\ + const btScalar abs_dir1 = absolute_edge[i_dir_1];\ + const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\ + if(pmin>rad || -rad>pmax) return false;\ +}\ + + +#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ +{\ + TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\ +}\ + +#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ +{\ + TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\ +}\ + +#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ +{\ + TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\ +}\ + + +//! Returns the dot product between a vec3f and the col of a matrix +SIMD_FORCE_INLINE btScalar bt_mat3_dot_col( +const btMatrix3x3 & mat, const btVector3 & vec3, int colindex) +{ + return vec3[0]*mat[0][colindex] + vec3[1]*mat[1][colindex] + vec3[2]*mat[2][colindex]; +} + + +//! Class for transforming a model1 to the space of model0 +ATTRIBUTE_ALIGNED16 (class) BT_BOX_BOX_TRANSFORM_CACHE +{ +public: + btVector3 m_T1to0;//!< Transforms translation of model1 to model 0 + btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1 + btMatrix3x3 m_AR;//!< Absolute value of m_R1to0 + + SIMD_FORCE_INLINE void calc_absolute_matrix() + { +// static const btVector3 vepsi(1e-6f,1e-6f,1e-6f); +// m_AR[0] = vepsi + m_R1to0[0].absolute(); +// m_AR[1] = vepsi + m_R1to0[1].absolute(); +// m_AR[2] = vepsi + m_R1to0[2].absolute(); + + int i,j; + + for(i=0;i<3;i++) + { + for(j=0;j<3;j++ ) + { + m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]); + } + } + + } + + BT_BOX_BOX_TRANSFORM_CACHE() + { + } + + + + //! Calc the transformation relative 1 to 0. Inverts matrics by transposing + SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1) + { + + btTransform temp_trans = trans0.inverse(); + temp_trans = temp_trans * trans1; + + m_T1to0 = temp_trans.getOrigin(); + m_R1to0 = temp_trans.getBasis(); + + + calc_absolute_matrix(); + } + + //! Calcs the full invertion of the matrices. Useful for scaling matrices + SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1) + { + m_R1to0 = trans0.getBasis().inverse(); + m_T1to0 = m_R1to0 * (-trans0.getOrigin()); + + m_T1to0 += m_R1to0*trans1.getOrigin(); + m_R1to0 *= trans1.getBasis(); + + calc_absolute_matrix(); + } + + SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) const + { + return point.dot3( m_R1to0[0], m_R1to0[1], m_R1to0[2] ) + m_T1to0; + } +}; + + +#define BOX_PLANE_EPSILON 0.000001f + +//! Axis aligned box +ATTRIBUTE_ALIGNED16 (class) btAABB +{ +public: + btVector3 m_min; + btVector3 m_max; + + btAABB() + {} + + + btAABB(const btVector3 & V1, + const btVector3 & V2, + const btVector3 & V3) + { + m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); + } + + btAABB(const btVector3 & V1, + const btVector3 & V2, + const btVector3 & V3, + btScalar margin) + { + m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); + + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + btAABB(const btAABB &other): + m_min(other.m_min),m_max(other.m_max) + { + } + + btAABB(const btAABB &other,btScalar margin ): + m_min(other.m_min),m_max(other.m_max) + { + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + SIMD_FORCE_INLINE void invalidate() + { + m_min[0] = SIMD_INFINITY; + m_min[1] = SIMD_INFINITY; + m_min[2] = SIMD_INFINITY; + m_max[0] = -SIMD_INFINITY; + m_max[1] = -SIMD_INFINITY; + m_max[2] = -SIMD_INFINITY; + } + + SIMD_FORCE_INLINE void increment_margin(btScalar margin) + { + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + SIMD_FORCE_INLINE void copy_with_margin(const btAABB &other, btScalar margin) + { + m_min[0] = other.m_min[0] - margin; + m_min[1] = other.m_min[1] - margin; + m_min[2] = other.m_min[2] - margin; + + m_max[0] = other.m_max[0] + margin; + m_max[1] = other.m_max[1] + margin; + m_max[2] = other.m_max[2] + margin; + } + + template + SIMD_FORCE_INLINE void calc_from_triangle( + const CLASS_POINT & V1, + const CLASS_POINT & V2, + const CLASS_POINT & V3) + { + m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); + } + + template + SIMD_FORCE_INLINE void calc_from_triangle_margin( + const CLASS_POINT & V1, + const CLASS_POINT & V2, + const CLASS_POINT & V3, btScalar margin) + { + m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); + + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + //! Apply a transform to an AABB + SIMD_FORCE_INLINE void appy_transform(const btTransform & trans) + { + btVector3 center = (m_max+m_min)*0.5f; + btVector3 extends = m_max - center; + // Compute new center + center = trans(center); + + btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(), + trans.getBasis().getRow(1).absolute(), + trans.getBasis().getRow(2).absolute()); + + m_min = center - textends; + m_max = center + textends; + } + + + //! Apply a transform to an AABB + SIMD_FORCE_INLINE void appy_transform_trans_cache(const BT_BOX_BOX_TRANSFORM_CACHE & trans) + { + btVector3 center = (m_max+m_min)*0.5f; + btVector3 extends = m_max - center; + // Compute new center + center = trans.transform(center); + + btVector3 textends = extends.dot3(trans.m_R1to0.getRow(0).absolute(), + trans.m_R1to0.getRow(1).absolute(), + trans.m_R1to0.getRow(2).absolute()); + + m_min = center - textends; + m_max = center + textends; + } + + //! Merges a Box + SIMD_FORCE_INLINE void merge(const btAABB & box) + { + m_min[0] = BT_MIN(m_min[0],box.m_min[0]); + m_min[1] = BT_MIN(m_min[1],box.m_min[1]); + m_min[2] = BT_MIN(m_min[2],box.m_min[2]); + + m_max[0] = BT_MAX(m_max[0],box.m_max[0]); + m_max[1] = BT_MAX(m_max[1],box.m_max[1]); + m_max[2] = BT_MAX(m_max[2],box.m_max[2]); + } + + //! Merges a point + template + SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point) + { + m_min[0] = BT_MIN(m_min[0],point[0]); + m_min[1] = BT_MIN(m_min[1],point[1]); + m_min[2] = BT_MIN(m_min[2],point[2]); + + m_max[0] = BT_MAX(m_max[0],point[0]); + m_max[1] = BT_MAX(m_max[1],point[1]); + m_max[2] = BT_MAX(m_max[2],point[2]); + } + + //! Gets the extend and center + SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend) const + { + center = (m_max+m_min)*0.5f; + extend = m_max - center; + } + + //! Finds the intersecting box between this box and the other. + SIMD_FORCE_INLINE void find_intersection(const btAABB & other, btAABB & intersection) const + { + intersection.m_min[0] = BT_MAX(other.m_min[0],m_min[0]); + intersection.m_min[1] = BT_MAX(other.m_min[1],m_min[1]); + intersection.m_min[2] = BT_MAX(other.m_min[2],m_min[2]); + + intersection.m_max[0] = BT_MIN(other.m_max[0],m_max[0]); + intersection.m_max[1] = BT_MIN(other.m_max[1],m_max[1]); + intersection.m_max[2] = BT_MIN(other.m_max[2],m_max[2]); + } + + + SIMD_FORCE_INLINE bool has_collision(const btAABB & other) const + { + if(m_min[0] > other.m_max[0] || + m_max[0] < other.m_min[0] || + m_min[1] > other.m_max[1] || + m_max[1] < other.m_min[1] || + m_min[2] > other.m_max[2] || + m_max[2] < other.m_min[2]) + { + return false; + } + return true; + } + + /*! \brief Finds the Ray intersection parameter. + \param aabb Aligned box + \param vorigin A vec3f with the origin of the ray + \param vdir A vec3f with the direction of the ray + */ + SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir) const + { + btVector3 extents,center; + this->get_center_extend(center,extents);; + + btScalar Dx = vorigin[0] - center[0]; + if(BT_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return false; + btScalar Dy = vorigin[1] - center[1]; + if(BT_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return false; + btScalar Dz = vorigin[2] - center[2]; + if(BT_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return false; + + + btScalar f = vdir[1] * Dz - vdir[2] * Dy; + if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false; + f = vdir[2] * Dx - vdir[0] * Dz; + if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false; + f = vdir[0] * Dy - vdir[1] * Dx; + if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false; + return true; + } + + + SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const + { + btVector3 center = (m_max+m_min)*0.5f; + btVector3 extend = m_max-center; + + btScalar _fOrigin = direction.dot(center); + btScalar _fMaximumExtent = extend.dot(direction.absolute()); + vmin = _fOrigin - _fMaximumExtent; + vmax = _fOrigin + _fMaximumExtent; + } + + SIMD_FORCE_INLINE eBT_PLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const + { + btScalar _fmin,_fmax; + this->projection_interval(plane,_fmin,_fmax); + + if(plane[3] > _fmax + BOX_PLANE_EPSILON) + { + return BT_CONST_BACK_PLANE; // 0 + } + + if(plane[3]+BOX_PLANE_EPSILON >=_fmin) + { + return BT_CONST_COLLIDE_PLANE; //1 + } + return BT_CONST_FRONT_PLANE;//2 + } + + SIMD_FORCE_INLINE bool overlapping_trans_conservative(const btAABB & box, btTransform & trans1_to_0) const + { + btAABB tbox = box; + tbox.appy_transform(trans1_to_0); + return has_collision(tbox); + } + + SIMD_FORCE_INLINE bool overlapping_trans_conservative2(const btAABB & box, + const BT_BOX_BOX_TRANSFORM_CACHE & trans1_to_0) const + { + btAABB tbox = box; + tbox.appy_transform_trans_cache(trans1_to_0); + return has_collision(tbox); + } + + //! transcache is the transformation cache from box to this AABB + SIMD_FORCE_INLINE bool overlapping_trans_cache( + const btAABB & box,const BT_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) const + { + + //Taken from OPCODE + btVector3 ea,eb;//extends + btVector3 ca,cb;//extends + get_center_extend(ca,ea); + box.get_center_extend(cb,eb); + + + btVector3 T; + btScalar t,t2; + int i; + + // Class I : A's basis vectors + for(i=0;i<3;i++) + { + T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; + t = transcache.m_AR[i].dot(eb) + ea[i]; + if(BT_GREATER(T[i], t)) return false; + } + // Class II : B's basis vectors + for(i=0;i<3;i++) + { + t = bt_mat3_dot_col(transcache.m_R1to0,T,i); + t2 = bt_mat3_dot_col(transcache.m_AR,ea,i) + eb[i]; + if(BT_GREATER(t,t2)) return false; + } + // Class III : 9 cross products + if(fulltest) + { + int j,m,n,o,p,q,r; + for(i=0;i<3;i++) + { + m = (i+1)%3; + n = (i+2)%3; + o = i==0?1:0; + p = i==2?1:2; + for(j=0;j<3;j++) + { + q = j==2?1:2; + r = j==0?1:0; + t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j]; + t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] + + eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r]; + if(BT_GREATER(t,t2)) return false; + } + } + } + return true; + } + + //! Simple test for planes. + SIMD_FORCE_INLINE bool collide_plane( + const btVector4 & plane) const + { + eBT_PLANE_INTERSECTION_TYPE classify = plane_classify(plane); + return (classify == BT_CONST_COLLIDE_PLANE); + } + + //! test for a triangle, with edges + SIMD_FORCE_INLINE bool collide_triangle_exact( + const btVector3 & p1, + const btVector3 & p2, + const btVector3 & p3, + const btVector4 & triangle_plane) const + { + if(!collide_plane(triangle_plane)) return false; + + btVector3 center,extends; + this->get_center_extend(center,extends); + + const btVector3 v1(p1 - center); + const btVector3 v2(p2 - center); + const btVector3 v3(p3 - center); + + //First axis + btVector3 diff(v2 - v1); + btVector3 abs_diff = diff.absolute(); + //Test With X axis + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends); + //Test With Y axis + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends); + //Test With Z axis + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends); + + + diff = v3 - v2; + abs_diff = diff.absolute(); + //Test With X axis + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends); + //Test With Y axis + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends); + //Test With Z axis + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends); + + diff = v1 - v3; + abs_diff = diff.absolute(); + //Test With X axis + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends); + //Test With Y axis + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends); + //Test With Z axis + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends); + + return true; + } +}; + + +//! Compairison of transformation objects +SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2) +{ + if(!(t1.getOrigin() == t2.getOrigin()) ) return false; + + if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false; + if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false; + if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false; + return true; +} + + + +#endif // GIM_BOX_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btClipPolygon.h b/src/BulletCollision/Gimpact/btClipPolygon.h new file mode 100644 index 0000000..de0a523 --- /dev/null +++ b/src/BulletCollision/Gimpact/btClipPolygon.h @@ -0,0 +1,182 @@ +#ifndef BT_CLIP_POLYGON_H_INCLUDED +#define BT_CLIP_POLYGON_H_INCLUDED + +/*! \file btClipPolygon.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "LinearMath/btTransform.h" +#include "LinearMath/btGeometryUtil.h" + + +SIMD_FORCE_INLINE btScalar bt_distance_point_plane(const btVector4 & plane,const btVector3 &point) +{ + return point.dot(plane) - plane[3]; +} + +/*! Vector blending +Takes two vectors a, b, blends them together*/ +SIMD_FORCE_INLINE void bt_vec_blend(btVector3 &vr, const btVector3 &va,const btVector3 &vb, btScalar blend_factor) +{ + vr = (1-blend_factor)*va + blend_factor*vb; +} + +//! This function calcs the distance from a 3D plane +SIMD_FORCE_INLINE void bt_plane_clip_polygon_collect( + const btVector3 & point0, + const btVector3 & point1, + btScalar dist0, + btScalar dist1, + btVector3 * clipped, + int & clipped_count) +{ + bool _prevclassif = (dist0>SIMD_EPSILON); + bool _classif = (dist1>SIMD_EPSILON); + if(_classif!=_prevclassif) + { + btScalar blendfactor = -dist0/(dist1-dist0); + bt_vec_blend(clipped[clipped_count],point0,point1,blendfactor); + clipped_count++; + } + if(!_classif) + { + clipped[clipped_count] = point1; + clipped_count++; + } +} + + +//! Clips a polygon by a plane +/*! +*\return The count of the clipped counts +*/ +SIMD_FORCE_INLINE int bt_plane_clip_polygon( + const btVector4 & plane, + const btVector3 * polygon_points, + int polygon_point_count, + btVector3 * clipped) +{ + int clipped_count = 0; + + + //clip first point + btScalar firstdist = bt_distance_point_plane(plane,polygon_points[0]);; + if(!(firstdist>SIMD_EPSILON)) + { + clipped[clipped_count] = polygon_points[0]; + clipped_count++; + } + + btScalar olddist = firstdist; + for(int i=1;iSIMD_EPSILON)) + { + clipped[clipped_count] = point0; + clipped_count++; + } + + // point 1 + btScalar olddist = firstdist; + btScalar dist = bt_distance_point_plane(plane,point1); + + bt_plane_clip_polygon_collect( + point0,point1, + olddist, + dist, + clipped, + clipped_count); + + olddist = dist; + + + // point 2 + dist = bt_distance_point_plane(plane,point2); + + bt_plane_clip_polygon_collect( + point1,point2, + olddist, + dist, + clipped, + clipped_count); + olddist = dist; + + + + //RETURN TO FIRST point0 + bt_plane_clip_polygon_collect( + point2,point0, + olddist, + firstdist, + clipped, + clipped_count); + + return clipped_count; +} + + + + + +#endif // GIM_TRI_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btContactProcessing.cpp b/src/BulletCollision/Gimpact/btContactProcessing.cpp new file mode 100644 index 0000000..eed31d8 --- /dev/null +++ b/src/BulletCollision/Gimpact/btContactProcessing.cpp @@ -0,0 +1,181 @@ + +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include "btContactProcessing.h" + +#define MAX_COINCIDENT 8 + +struct CONTACT_KEY_TOKEN +{ + unsigned int m_key; + int m_value; + CONTACT_KEY_TOKEN() + { + } + + CONTACT_KEY_TOKEN(unsigned int key,int token) + { + m_key = key; + m_value = token; + } + + CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken) + { + m_key = rtoken.m_key; + m_value = rtoken.m_value; + } + + inline bool operator <(const CONTACT_KEY_TOKEN& other) const + { + return (m_key < other.m_key); + } + + inline bool operator >(const CONTACT_KEY_TOKEN& other) const + { + return (m_key > other.m_key); + } + +}; + +class CONTACT_KEY_TOKEN_COMP +{ + public: + + bool operator() ( const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b ) const + { + return ( a < b ); + } +}; + + +void btContactArray::merge_contacts( + const btContactArray & contacts, bool normal_contact_average) +{ + clear(); + + int i; + if(contacts.size()==0) return; + + + if(contacts.size()==1) + { + push_back(contacts[0]); + return; + } + + btAlignedObjectArray keycontacts; + + keycontacts.reserve(contacts.size()); + + //fill key contacts + + for ( i = 0;im_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//) + { + *pcontact = *scontact; + coincident_count = 0; + } + else if(normal_contact_average) + { + if(btFabs(pcontact->m_depth - scontact->m_depth)m_normal; + coincident_count++; + } + } + } + } + else + {//add new contact + + if(normal_contact_average && coincident_count>0) + { + pcontact->interpolate_normals(coincident_normals,coincident_count); + coincident_count = 0; + } + + push_back(*scontact); + pcontact = &(*this)[this->size()-1]; + } + last_key = key; + } +} + +void btContactArray::merge_contacts_unique(const btContactArray & contacts) +{ + clear(); + + if(contacts.size()==0) return; + + if(contacts.size()==1) + { + push_back(contacts[0]); + return; + } + + GIM_CONTACT average_contact = contacts[0]; + + for (int i=1;i +{ +public: + btContactArray() + { + reserve(64); + } + + SIMD_FORCE_INLINE void push_contact( + const btVector3 &point,const btVector3 & normal, + btScalar depth, int feature1, int feature2) + { + push_back( GIM_CONTACT(point,normal,depth,feature1,feature2) ); + } + + SIMD_FORCE_INLINE void push_triangle_contacts( + const GIM_TRIANGLE_CONTACT & tricontact, + int feature1,int feature2) + { + for(int i = 0;i splitValue) + { + //swap + primitive_boxes.swap(i,splitIndex); + //swapLeafNodes(i,splitIndex); + splitIndex++; + } + } + + //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex + //otherwise the tree-building might fail due to stack-overflows in certain cases. + //unbalanced1 is unsafe: it can cause stack overflows + //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); + + //unbalanced2 should work too: always use center (perfect balanced trees) + //bool unbalanced2 = true; + + //this should be safe too: + int rangeBalancedIndices = numIndices/3; + bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + + if (unbalanced) + { + splitIndex = startIndex+ (numIndices>>1); + } + + btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); + + return splitIndex; + +} + + +void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex) +{ + int curIndex = m_num_nodes; + m_num_nodes++; + + btAssert((endIndex-startIndex)>0); + + if ((endIndex-startIndex)==1) + { + //We have a leaf node + setNodeBound(curIndex,primitive_boxes[startIndex].m_bound); + m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data); + + return; + } + //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. + + //split axis + int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex); + + splitIndex = _sort_and_calc_splitting_index( + primitive_boxes,startIndex,endIndex, + splitIndex//split axis + ); + + + //calc this node bounding box + + btAABB node_bound; + node_bound.invalidate(); + + for (int i=startIndex;iget_primitive_box(getNodeData(nodecount),leafbox); + setNodeBound(nodecount,leafbox); + } + else + { + //const GIM_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount); + //get left bound + btAABB bound; + bound.invalidate(); + + btAABB temp_box; + + int child_node = getLeftNode(nodecount); + if(child_node) + { + getNodeBound(child_node,temp_box); + bound.merge(temp_box); + } + + child_node = getRightNode(nodecount); + if(child_node) + { + getNodeBound(child_node,temp_box); + bound.merge(temp_box); + } + + setNodeBound(nodecount,bound); + } + } +} + +//! this rebuild the entire set +void btGImpactBvh::buildSet() +{ + //obtain primitive boxes + GIM_BVH_DATA_ARRAY primitive_boxes; + primitive_boxes.resize(m_primitive_manager->get_primitive_count()); + + for (int i = 0;iget_primitive_box(i,primitive_boxes[i].m_bound); + primitive_boxes[i].m_data = i; + } + + m_box_tree.build_tree(primitive_boxes); +} + +//! returns the indices of the primitives in the m_primitive_manager +bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const +{ + int curIndex = 0; + int numNodes = getNodeCount(); + + while (curIndex < numNodes) + { + btAABB bound; + getNodeBound(curIndex,bound); + + //catch bugs in tree data + + bool aabbOverlap = bound.has_collision(box); + bool isleafnode = isLeafNode(curIndex); + + if (isleafnode && aabbOverlap) + { + collided_results.push_back(getNodeData(curIndex)); + } + + if (aabbOverlap || isleafnode) + { + //next subnode + curIndex++; + } + else + { + //skip node + curIndex+= getEscapeNodeIndex(curIndex); + } + } + if(collided_results.size()>0) return true; + return false; +} + + + +//! returns the indices of the primitives in the m_primitive_manager +bool btGImpactBvh::rayQuery( + const btVector3 & ray_dir,const btVector3 & ray_origin , + btAlignedObjectArray & collided_results) const +{ + int curIndex = 0; + int numNodes = getNodeCount(); + + while (curIndex < numNodes) + { + btAABB bound; + getNodeBound(curIndex,bound); + + //catch bugs in tree data + + bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir); + bool isleafnode = isLeafNode(curIndex); + + if (isleafnode && aabbOverlap) + { + collided_results.push_back(getNodeData( curIndex)); + } + + if (aabbOverlap || isleafnode) + { + //next subnode + curIndex++; + } + else + { + //skip node + curIndex+= getEscapeNodeIndex(curIndex); + } + } + if(collided_results.size()>0) return true; + return false; +} + + +SIMD_FORCE_INLINE bool _node_collision( + btGImpactBvh * boxset0, btGImpactBvh * boxset1, + const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, + int node0 ,int node1, bool complete_primitive_tests) +{ + btAABB box0; + boxset0->getNodeBound(node0,box0); + btAABB box1; + boxset1->getNodeBound(node1,box1); + + return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests ); +// box1.appy_transform_trans_cache(trans_cache_1to0); +// return box0.has_collision(box1); + +} + + +//stackless recursive collision routine +static void _find_collision_pairs_recursive( + btGImpactBvh * boxset0, btGImpactBvh * boxset1, + btPairSet * collision_pairs, + const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, + int node0, int node1, bool complete_primitive_tests) +{ + + + + if( _node_collision( + boxset0,boxset1,trans_cache_1to0, + node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes + + if(boxset0->isLeafNode(node0)) + { + if(boxset1->isLeafNode(node1)) + { + // collision result + collision_pairs->push_pair( + boxset0->getNodeData(node0),boxset1->getNodeData(node1)); + return; + } + else + { + + //collide left recursive + + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + node0,boxset1->getLeftNode(node1),false); + + //collide right recursive + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + node0,boxset1->getRightNode(node1),false); + + + } + } + else + { + if(boxset1->isLeafNode(node1)) + { + + //collide left recursive + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getLeftNode(node0),node1,false); + + + //collide right recursive + + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getRightNode(node0),node1,false); + + + } + else + { + //collide left0 left1 + + + + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false); + + //collide left0 right1 + + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false); + + + //collide right0 left1 + + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false); + + //collide right0 right1 + + _find_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getRightNode(node0),boxset1->getRightNode(node1),false); + + }// else if node1 is not a leaf + }// else if node0 is not a leaf +} + + +void btGImpactBvh::find_collision(btGImpactBvh * boxset0, const btTransform & trans0, + btGImpactBvh * boxset1, const btTransform & trans1, + btPairSet & collision_pairs) +{ + + if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return; + + BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0; + + trans_cache_1to0.calc_from_homogenic(trans0,trans1); + +#ifdef TRI_COLLISION_PROFILING + bt_begin_gim02_tree_time(); +#endif //TRI_COLLISION_PROFILING + + _find_collision_pairs_recursive( + boxset0,boxset1, + &collision_pairs,trans_cache_1to0,0,0,true); +#ifdef TRI_COLLISION_PROFILING + bt_end_gim02_tree_time(); +#endif //TRI_COLLISION_PROFILING + +} + diff --git a/src/BulletCollision/Gimpact/btGImpactBvh.h b/src/BulletCollision/Gimpact/btGImpactBvh.h new file mode 100644 index 0000000..6174ae9 --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactBvh.h @@ -0,0 +1,396 @@ +#ifndef GIM_BOX_SET_H_INCLUDED +#define GIM_BOX_SET_H_INCLUDED + +/*! \file gim_box_set.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "LinearMath/btAlignedObjectArray.h" + +#include "btBoxCollision.h" +#include "btTriangleShapeEx.h" + + + + + +//! Overlapping pair +struct GIM_PAIR +{ + int m_index1; + int m_index2; + GIM_PAIR() + {} + + GIM_PAIR(const GIM_PAIR & p) + { + m_index1 = p.m_index1; + m_index2 = p.m_index2; + } + + GIM_PAIR(int index1, int index2) + { + m_index1 = index1; + m_index2 = index2; + } +}; + +//! A pairset array +class btPairSet: public btAlignedObjectArray +{ +public: + btPairSet() + { + reserve(32); + } + inline void push_pair(int index1,int index2) + { + push_back(GIM_PAIR(index1,index2)); + } + + inline void push_pair_inv(int index1,int index2) + { + push_back(GIM_PAIR(index2,index1)); + } +}; + + +///GIM_BVH_DATA is an internal GIMPACT collision structure to contain axis aligned bounding box +struct GIM_BVH_DATA +{ + btAABB m_bound; + int m_data; +}; + +//! Node Structure for trees +class GIM_BVH_TREE_NODE +{ +public: + btAABB m_bound; +protected: + int m_escapeIndexOrDataIndex; +public: + GIM_BVH_TREE_NODE() + { + m_escapeIndexOrDataIndex = 0; + } + + SIMD_FORCE_INLINE bool isLeafNode() const + { + //skipindex is negative (internal node), triangleindex >=0 (leafnode) + return (m_escapeIndexOrDataIndex>=0); + } + + SIMD_FORCE_INLINE int getEscapeIndex() const + { + //btAssert(m_escapeIndexOrDataIndex < 0); + return -m_escapeIndexOrDataIndex; + } + + SIMD_FORCE_INLINE void setEscapeIndex(int index) + { + m_escapeIndexOrDataIndex = -index; + } + + SIMD_FORCE_INLINE int getDataIndex() const + { + //btAssert(m_escapeIndexOrDataIndex >= 0); + + return m_escapeIndexOrDataIndex; + } + + SIMD_FORCE_INLINE void setDataIndex(int index) + { + m_escapeIndexOrDataIndex = index; + } + +}; + + +class GIM_BVH_DATA_ARRAY:public btAlignedObjectArray +{ +}; + + +class GIM_BVH_TREE_NODE_ARRAY:public btAlignedObjectArray +{ +}; + + + + +//! Basic Box tree structure +class btBvhTree +{ +protected: + int m_num_nodes; + GIM_BVH_TREE_NODE_ARRAY m_node_array; +protected: + int _sort_and_calc_splitting_index( + GIM_BVH_DATA_ARRAY & primitive_boxes, + int startIndex, int endIndex, int splitAxis); + + int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); + + void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); +public: + btBvhTree() + { + m_num_nodes = 0; + } + + //! prototype functions for box tree management + //!@{ + void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes); + + SIMD_FORCE_INLINE void clearNodes() + { + m_node_array.clear(); + m_num_nodes = 0; + } + + //! node count + SIMD_FORCE_INLINE int getNodeCount() const + { + return m_num_nodes; + } + + //! tells if the node is a leaf + SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const + { + return m_node_array[nodeindex].isLeafNode(); + } + + SIMD_FORCE_INLINE int getNodeData(int nodeindex) const + { + return m_node_array[nodeindex].getDataIndex(); + } + + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + { + bound = m_node_array[nodeindex].m_bound; + } + + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + { + m_node_array[nodeindex].m_bound = bound; + } + + SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const + { + return nodeindex+1; + } + + SIMD_FORCE_INLINE int getRightNode(int nodeindex) const + { + if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2; + return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex(); + } + + SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const + { + return m_node_array[nodeindex].getEscapeIndex(); + } + + SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const + { + return &m_node_array[index]; + } + + //!@} +}; + + +//! Prototype Base class for primitive classification +/*! +This class is a wrapper for primitive collections. +This tells relevant info for the Bounding Box set classes, which take care of space classification. +This class can manage Compound shapes and trimeshes, and if it is managing trimesh then the Hierarchy Bounding Box classes will take advantage of primitive Vs Box overlapping tests for getting optimal results and less Per Box compairisons. +*/ +class btPrimitiveManagerBase +{ +public: + + virtual ~btPrimitiveManagerBase() {} + + //! determines if this manager consist on only triangles, which special case will be optimized + virtual bool is_trimesh() const = 0; + virtual int get_primitive_count() const = 0; + virtual void get_primitive_box(int prim_index ,btAABB & primbox) const = 0; + //! retrieves only the points of the triangle, and the collision margin + virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const= 0; +}; + + +//! Structure for containing Boxes +/*! +This class offers an structure for managing a box tree of primitives. +Requires a Primitive prototype (like btPrimitiveManagerBase ) +*/ +class btGImpactBvh +{ +protected: + btBvhTree m_box_tree; + btPrimitiveManagerBase * m_primitive_manager; + +protected: + //stackless refit + void refit(); +public: + + //! this constructor doesn't build the tree. you must call buildSet + btGImpactBvh() + { + m_primitive_manager = NULL; + } + + //! this constructor doesn't build the tree. you must call buildSet + btGImpactBvh(btPrimitiveManagerBase * primitive_manager) + { + m_primitive_manager = primitive_manager; + } + + SIMD_FORCE_INLINE btAABB getGlobalBox() const + { + btAABB totalbox; + getNodeBound(0, totalbox); + return totalbox; + } + + SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager) + { + m_primitive_manager = primitive_manager; + } + + SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const + { + return m_primitive_manager; + } + + +//! node manager prototype functions +///@{ + + //! this attemps to refit the box set. + SIMD_FORCE_INLINE void update() + { + refit(); + } + + //! this rebuild the entire set + void buildSet(); + + //! returns the indices of the primitives in the m_primitive_manager + bool boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const; + + //! returns the indices of the primitives in the m_primitive_manager + SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box, + const btTransform & transform, btAlignedObjectArray & collided_results) const + { + btAABB transbox=box; + transbox.appy_transform(transform); + return boxQuery(transbox,collided_results); + } + + //! returns the indices of the primitives in the m_primitive_manager + bool rayQuery( + const btVector3 & ray_dir,const btVector3 & ray_origin , + btAlignedObjectArray & collided_results) const; + + //! tells if this set has hierarcht + SIMD_FORCE_INLINE bool hasHierarchy() const + { + return true; + } + + //! tells if this set is a trimesh + SIMD_FORCE_INLINE bool isTrimesh() const + { + return m_primitive_manager->is_trimesh(); + } + + //! node count + SIMD_FORCE_INLINE int getNodeCount() const + { + return m_box_tree.getNodeCount(); + } + + //! tells if the node is a leaf + SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const + { + return m_box_tree.isLeafNode(nodeindex); + } + + SIMD_FORCE_INLINE int getNodeData(int nodeindex) const + { + return m_box_tree.getNodeData(nodeindex); + } + + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + { + m_box_tree.getNodeBound(nodeindex, bound); + } + + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + { + m_box_tree.setNodeBound(nodeindex, bound); + } + + + SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const + { + return m_box_tree.getLeftNode(nodeindex); + } + + SIMD_FORCE_INLINE int getRightNode(int nodeindex) const + { + return m_box_tree.getRightNode(nodeindex); + } + + SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const + { + return m_box_tree.getEscapeNodeIndex(nodeindex); + } + + SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const + { + m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle); + } + + + SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const + { + return m_box_tree.get_node_pointer(index); + } + +#ifdef TRI_COLLISION_PROFILING + static float getAverageTreeCollisionTime(); +#endif //TRI_COLLISION_PROFILING + + static void find_collision(btGImpactBvh * boxset1, const btTransform & trans1, + btGImpactBvh * boxset2, const btTransform & trans2, + btPairSet & collision_pairs); +}; + + +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp new file mode 100644 index 0000000..5997e44 --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp @@ -0,0 +1,880 @@ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/* +Author: Francisco Len Nßjera +Concave-Concave Collision + +*/ + +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "btGImpactCollisionAlgorithm.h" +#include "btContactProcessing.h" +#include "LinearMath/btQuickprof.h" + + +//! Class for accessing the plane equation +class btPlaneShape : public btStaticPlaneShape +{ +public: + + btPlaneShape(const btVector3& v, float f) + :btStaticPlaneShape(v,f) + { + } + + void get_plane_equation(btVector4 &equation) + { + equation[0] = m_planeNormal[0]; + equation[1] = m_planeNormal[1]; + equation[2] = m_planeNormal[2]; + equation[3] = m_planeConstant; + } + + + void get_plane_equation_transformed(const btTransform & trans,btVector4 &equation) const + { + equation[0] = trans.getBasis().getRow(0).dot(m_planeNormal); + equation[1] = trans.getBasis().getRow(1).dot(m_planeNormal); + equation[2] = trans.getBasis().getRow(2).dot(m_planeNormal); + equation[3] = trans.getOrigin().dot(m_planeNormal) + m_planeConstant; + } +}; + + + +////////////////////////////////////////////////////////////////////////////////////////////// +#ifdef TRI_COLLISION_PROFILING + +btClock g_triangle_clock; + +float g_accum_triangle_collision_time = 0; +int g_count_triangle_collision = 0; + +void bt_begin_gim02_tri_time() +{ + g_triangle_clock.reset(); +} + +void bt_end_gim02_tri_time() +{ + g_accum_triangle_collision_time += g_triangle_clock.getTimeMicroseconds(); + g_count_triangle_collision++; +} +#endif //TRI_COLLISION_PROFILING +//! Retrieving shapes shapes +/*! +Declared here due of insuficent space on Pool allocators +*/ +//!@{ +class GIM_ShapeRetriever +{ +public: + const btGImpactShapeInterface * m_gim_shape; + btTriangleShapeEx m_trishape; + btTetrahedronShapeEx m_tetrashape; + +public: + class ChildShapeRetriever + { + public: + GIM_ShapeRetriever * m_parent; + virtual const btCollisionShape * getChildShape(int index) + { + return m_parent->m_gim_shape->getChildShape(index); + } + virtual ~ChildShapeRetriever() {} + }; + + class TriangleShapeRetriever:public ChildShapeRetriever + { + public: + + virtual btCollisionShape * getChildShape(int index) + { + m_parent->m_gim_shape->getBulletTriangle(index,m_parent->m_trishape); + return &m_parent->m_trishape; + } + virtual ~TriangleShapeRetriever() {} + }; + + class TetraShapeRetriever:public ChildShapeRetriever + { + public: + + virtual btCollisionShape * getChildShape(int index) + { + m_parent->m_gim_shape->getBulletTetrahedron(index,m_parent->m_tetrashape); + return &m_parent->m_tetrashape; + } + }; +public: + ChildShapeRetriever m_child_retriever; + TriangleShapeRetriever m_tri_retriever; + TetraShapeRetriever m_tetra_retriever; + ChildShapeRetriever * m_current_retriever; + + GIM_ShapeRetriever(const btGImpactShapeInterface * gim_shape) + { + m_gim_shape = gim_shape; + //select retriever + if(m_gim_shape->needsRetrieveTriangles()) + { + m_current_retriever = &m_tri_retriever; + } + else if(m_gim_shape->needsRetrieveTetrahedrons()) + { + m_current_retriever = &m_tetra_retriever; + } + else + { + m_current_retriever = &m_child_retriever; + } + + m_current_retriever->m_parent = this; + } + + const btCollisionShape * getChildShape(int index) + { + return m_current_retriever->getChildShape(index); + } + + +}; + + + +//!@} + + +#ifdef TRI_COLLISION_PROFILING + +//! Gets the average time in miliseconds of tree collisions +float btGImpactCollisionAlgorithm::getAverageTreeCollisionTime() +{ + return btGImpactBoxSet::getAverageTreeCollisionTime(); + +} + +//! Gets the average time in miliseconds of triangle collisions +float btGImpactCollisionAlgorithm::getAverageTriangleCollisionTime() +{ + if(g_count_triangle_collision == 0) return 0; + + float avgtime = g_accum_triangle_collision_time; + avgtime /= (float)g_count_triangle_collision; + + g_accum_triangle_collision_time = 0; + g_count_triangle_collision = 0; + + return avgtime; +} + +#endif //TRI_COLLISION_PROFILING + + + +btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) +: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap) +{ + m_manifoldPtr = NULL; + m_convex_algorithm = NULL; +} + +btGImpactCollisionAlgorithm::~btGImpactCollisionAlgorithm() +{ + clearCache(); +} + + + + + +void btGImpactCollisionAlgorithm::addContactPoint(const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btVector3 & point, + const btVector3 & normal, + btScalar distance) +{ + m_resultOut->setShapeIdentifiersA(m_part0,m_triface0); + m_resultOut->setShapeIdentifiersB(m_part1,m_triface1); + checkManifold(body0Wrap,body1Wrap); + m_resultOut->addContactPoint(normal,point,distance); +} + + +void btGImpactCollisionAlgorithm::shape_vs_shape_collision( + const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btCollisionShape * shape0, + const btCollisionShape * shape1) +{ + + + { + btCollisionObjectWrapper ob0(body0Wrap,shape0,body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform()); + btCollisionObjectWrapper ob1(body1Wrap,shape1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform()); + + btCollisionAlgorithm* algor = newAlgorithm(&ob0,&ob1); + // post : checkManifold is called + + m_resultOut->setShapeIdentifiersA(m_part0,m_triface0); + m_resultOut->setShapeIdentifiersB(m_part1,m_triface1); + + algor->processCollision(&ob0,&ob1,*m_dispatchInfo,m_resultOut); + + algor->~btCollisionAlgorithm(); + m_dispatcher->freeCollisionAlgorithm(algor); + } + +} + +void btGImpactCollisionAlgorithm::convex_vs_convex_collision( + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btCollisionShape* shape0, + const btCollisionShape* shape1) +{ + + m_resultOut->setShapeIdentifiersA(m_part0,m_triface0); + m_resultOut->setShapeIdentifiersB(m_part1,m_triface1); + + btCollisionObjectWrapper ob0(body0Wrap,shape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform()); + btCollisionObjectWrapper ob1(body1Wrap,shape1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform()); + checkConvexAlgorithm(&ob0,&ob1); + m_convex_algorithm->processCollision(&ob0,&ob1,*m_dispatchInfo,m_resultOut); + + +} + + + + +void btGImpactCollisionAlgorithm::gimpact_vs_gimpact_find_pairs( + const btTransform & trans0, + const btTransform & trans1, + const btGImpactShapeInterface * shape0, + const btGImpactShapeInterface * shape1,btPairSet & pairset) +{ + if(shape0->hasBoxSet() && shape1->hasBoxSet()) + { + btGImpactBoxSet::find_collision(shape0->getBoxSet(),trans0,shape1->getBoxSet(),trans1,pairset); + } + else + { + btAABB boxshape0; + btAABB boxshape1; + int i = shape0->getNumChildShapes(); + + while(i--) + { + shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max); + + int j = shape1->getNumChildShapes(); + while(j--) + { + shape1->getChildAabb(i,trans1,boxshape1.m_min,boxshape1.m_max); + + if(boxshape1.has_collision(boxshape0)) + { + pairset.push_pair(i,j); + } + } + } + } + + +} + + +void btGImpactCollisionAlgorithm::gimpact_vs_shape_find_pairs( + const btTransform & trans0, + const btTransform & trans1, + const btGImpactShapeInterface * shape0, + const btCollisionShape * shape1, + btAlignedObjectArray & collided_primitives) +{ + + btAABB boxshape; + + + if(shape0->hasBoxSet()) + { + btTransform trans1to0 = trans0.inverse(); + trans1to0 *= trans1; + + shape1->getAabb(trans1to0,boxshape.m_min,boxshape.m_max); + + shape0->getBoxSet()->boxQuery(boxshape, collided_primitives); + } + else + { + shape1->getAabb(trans1,boxshape.m_min,boxshape.m_max); + + btAABB boxshape0; + int i = shape0->getNumChildShapes(); + + while(i--) + { + shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max); + + if(boxshape.has_collision(boxshape0)) + { + collided_primitives.push_back(i); + } + } + + } + +} + + +void btGImpactCollisionAlgorithm::collide_gjk_triangles(const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactMeshShapePart * shape0, + const btGImpactMeshShapePart * shape1, + const int * pairs, int pair_count) +{ + btTriangleShapeEx tri0; + btTriangleShapeEx tri1; + + shape0->lockChildShapes(); + shape1->lockChildShapes(); + + const int * pair_pointer = pairs; + + while(pair_count--) + { + + m_triface0 = *(pair_pointer); + m_triface1 = *(pair_pointer+1); + pair_pointer+=2; + + + + shape0->getBulletTriangle(m_triface0,tri0); + shape1->getBulletTriangle(m_triface1,tri1); + + + //collide two convex shapes + if(tri0.overlap_test_conservative(tri1)) + { + convex_vs_convex_collision(body0Wrap,body1Wrap,&tri0,&tri1); + } + + } + + shape0->unlockChildShapes(); + shape1->unlockChildShapes(); +} + +void btGImpactCollisionAlgorithm::collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart * shape0, + const btGImpactMeshShapePart * shape1, + const int * pairs, int pair_count) +{ + btTransform orgtrans0 = body0Wrap->getWorldTransform(); + btTransform orgtrans1 = body1Wrap->getWorldTransform(); + + btPrimitiveTriangle ptri0; + btPrimitiveTriangle ptri1; + GIM_TRIANGLE_CONTACT contact_data; + + shape0->lockChildShapes(); + shape1->lockChildShapes(); + + const int * pair_pointer = pairs; + + while(pair_count--) + { + + m_triface0 = *(pair_pointer); + m_triface1 = *(pair_pointer+1); + pair_pointer+=2; + + + shape0->getPrimitiveTriangle(m_triface0,ptri0); + shape1->getPrimitiveTriangle(m_triface1,ptri1); + + #ifdef TRI_COLLISION_PROFILING + bt_begin_gim02_tri_time(); + #endif + + ptri0.applyTransform(orgtrans0); + ptri1.applyTransform(orgtrans1); + + + //build planes + ptri0.buildTriPlane(); + ptri1.buildTriPlane(); + // test conservative + + + + if(ptri0.overlap_test_conservative(ptri1)) + { + if(ptri0.find_triangle_collision_clip_method(ptri1,contact_data)) + { + + int j = contact_data.m_point_count; + while(j--) + { + + addContactPoint(body0Wrap, body1Wrap, + contact_data.m_points[j], + contact_data.m_separating_normal, + -contact_data.m_penetration_depth); + } + } + } + + #ifdef TRI_COLLISION_PROFILING + bt_end_gim02_tri_time(); + #endif + + } + + shape0->unlockChildShapes(); + shape1->unlockChildShapes(); + +} + + +void btGImpactCollisionAlgorithm::gimpact_vs_gimpact( + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactShapeInterface * shape0, + const btGImpactShapeInterface * shape1) +{ + + if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE) + { + const btGImpactMeshShape * meshshape0 = static_cast(shape0); + m_part0 = meshshape0->getMeshPartCount(); + + while(m_part0--) + { + gimpact_vs_gimpact(body0Wrap,body1Wrap,meshshape0->getMeshPart(m_part0),shape1); + } + + return; + } + + if(shape1->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE) + { + const btGImpactMeshShape * meshshape1 = static_cast(shape1); + m_part1 = meshshape1->getMeshPartCount(); + + while(m_part1--) + { + + gimpact_vs_gimpact(body0Wrap,body1Wrap,shape0,meshshape1->getMeshPart(m_part1)); + + } + + return; + } + + + btTransform orgtrans0 = body0Wrap->getWorldTransform(); + btTransform orgtrans1 = body1Wrap->getWorldTransform(); + + btPairSet pairset; + + gimpact_vs_gimpact_find_pairs(orgtrans0,orgtrans1,shape0,shape1,pairset); + + if(pairset.size()== 0) return; + + if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART && + shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART) + { + const btGImpactMeshShapePart * shapepart0 = static_cast(shape0); + const btGImpactMeshShapePart * shapepart1 = static_cast(shape1); + //specialized function + #ifdef BULLET_TRIANGLE_COLLISION + collide_gjk_triangles(body0Wrap,body1Wrap,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size()); + #else + collide_sat_triangles(body0Wrap,body1Wrap,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size()); + #endif + + return; + } + + //general function + + shape0->lockChildShapes(); + shape1->lockChildShapes(); + + GIM_ShapeRetriever retriever0(shape0); + GIM_ShapeRetriever retriever1(shape1); + + bool child_has_transform0 = shape0->childrenHasTransform(); + bool child_has_transform1 = shape1->childrenHasTransform(); + + int i = pairset.size(); + while(i--) + { + GIM_PAIR * pair = &pairset[i]; + m_triface0 = pair->m_index1; + m_triface1 = pair->m_index2; + const btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0); + const btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1); + + btTransform tr0 = body0Wrap->getWorldTransform(); + btTransform tr1 = body1Wrap->getWorldTransform(); + + if(child_has_transform0) + { + tr0 = orgtrans0*shape0->getChildTransform(m_triface0); + } + + if(child_has_transform1) + { + tr1 = orgtrans1*shape1->getChildTransform(m_triface1); + } + + btCollisionObjectWrapper ob0(body0Wrap,colshape0,body0Wrap->getCollisionObject(),tr0); + btCollisionObjectWrapper ob1(body1Wrap,colshape1,body1Wrap->getCollisionObject(),tr1); + + //collide two convex shapes + convex_vs_convex_collision(&ob0,&ob1,colshape0,colshape1); + } + + shape0->unlockChildShapes(); + shape1->unlockChildShapes(); +} + +void btGImpactCollisionAlgorithm::gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactShapeInterface * shape0, + const btCollisionShape * shape1,bool swapped) +{ + if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE) + { + const btGImpactMeshShape * meshshape0 = static_cast(shape0); + int& part = swapped ? m_part1 : m_part0; + part = meshshape0->getMeshPartCount(); + + while(part--) + { + + gimpact_vs_shape(body0Wrap, + body1Wrap, + meshshape0->getMeshPart(part), + shape1,swapped); + + } + + return; + } + + #ifdef GIMPACT_VS_PLANE_COLLISION + if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART && + shape1->getShapeType() == STATIC_PLANE_PROXYTYPE) + { + const btGImpactMeshShapePart * shapepart = static_cast(shape0); + const btStaticPlaneShape * planeshape = static_cast(shape1); + gimpacttrimeshpart_vs_plane_collision(body0Wrap,body1Wrap,shapepart,planeshape,swapped); + return; + } + + #endif + + + + if(shape1->isCompound()) + { + const btCompoundShape * compoundshape = static_cast(shape1); + gimpact_vs_compoundshape(body0Wrap,body1Wrap,shape0,compoundshape,swapped); + return; + } + else if(shape1->isConcave()) + { + const btConcaveShape * concaveshape = static_cast(shape1); + gimpact_vs_concave(body0Wrap,body1Wrap,shape0,concaveshape,swapped); + return; + } + + + btTransform orgtrans0 = body0Wrap->getWorldTransform(); + + btTransform orgtrans1 = body1Wrap->getWorldTransform(); + + btAlignedObjectArray collided_results; + + gimpact_vs_shape_find_pairs(orgtrans0,orgtrans1,shape0,shape1,collided_results); + + if(collided_results.size() == 0) return; + + + shape0->lockChildShapes(); + + GIM_ShapeRetriever retriever0(shape0); + + + bool child_has_transform0 = shape0->childrenHasTransform(); + + + int i = collided_results.size(); + + while(i--) + { + int child_index = collided_results[i]; + if(swapped) + m_triface1 = child_index; + else + m_triface0 = child_index; + + const btCollisionShape * colshape0 = retriever0.getChildShape(child_index); + + btTransform tr0 = body0Wrap->getWorldTransform(); + + if(child_has_transform0) + { + tr0 = orgtrans0*shape0->getChildTransform(child_index); + } + + btCollisionObjectWrapper ob0(body0Wrap,colshape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform()); + + //collide two shapes + if(swapped) + { + shape_vs_shape_collision(body1Wrap,&ob0,shape1,colshape0); + } + else + { + shape_vs_shape_collision(&ob0,body1Wrap,colshape0,shape1); + } + + } + + shape0->unlockChildShapes(); + +} + +void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface * shape0, + const btCompoundShape * shape1,bool swapped) +{ + btTransform orgtrans1 = body1Wrap->getWorldTransform(); + + int i = shape1->getNumChildShapes(); + while(i--) + { + + const btCollisionShape * colshape1 = shape1->getChildShape(i); + btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i); + + btCollisionObjectWrapper ob1(body1Wrap,colshape1,body1Wrap->getCollisionObject(),childtrans1); + //collide child shape + gimpact_vs_shape(body0Wrap, &ob1, + shape0,colshape1,swapped); + } +} + +void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision( + const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactMeshShapePart * shape0, + const btStaticPlaneShape * shape1,bool swapped) +{ + + + btTransform orgtrans0 = body0Wrap->getWorldTransform(); + btTransform orgtrans1 = body1Wrap->getWorldTransform(); + + const btPlaneShape * planeshape = static_cast(shape1); + btVector4 plane; + planeshape->get_plane_equation_transformed(orgtrans1,plane); + + //test box against plane + + btAABB tribox; + shape0->getAabb(orgtrans0,tribox.m_min,tribox.m_max); + tribox.increment_margin(planeshape->getMargin()); + + if( tribox.plane_classify(plane)!= BT_CONST_COLLIDE_PLANE) return; + + shape0->lockChildShapes(); + + btScalar margin = shape0->getMargin() + planeshape->getMargin(); + + btVector3 vertex; + int vi = shape0->getVertexCount(); + while(vi--) + { + shape0->getVertex(vi,vertex); + vertex = orgtrans0(vertex); + + btScalar distance = vertex.dot(plane) - plane[3] - margin; + + if(distance<0.0)//add contact + { + if(swapped) + { + addContactPoint(body1Wrap, body0Wrap, + vertex, + -plane, + distance); + } + else + { + addContactPoint(body0Wrap, body1Wrap, + vertex, + plane, + distance); + } + } + } + + shape0->unlockChildShapes(); +} + + + + +class btGImpactTriangleCallback: public btTriangleCallback +{ +public: + btGImpactCollisionAlgorithm * algorithm; + const btCollisionObjectWrapper * body0Wrap; + const btCollisionObjectWrapper * body1Wrap; + const btGImpactShapeInterface * gimpactshape0; + bool swapped; + btScalar margin; + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) + { + btTriangleShapeEx tri1(triangle[0],triangle[1],triangle[2]); + tri1.setMargin(margin); + if(swapped) + { + algorithm->setPart0(partId); + algorithm->setFace0(triangleIndex); + } + else + { + algorithm->setPart1(partId); + algorithm->setFace1(triangleIndex); + } + algorithm->gimpact_vs_shape( + body0Wrap,body1Wrap,gimpactshape0,&tri1,swapped); + } +}; + + + + +void btGImpactCollisionAlgorithm::gimpact_vs_concave( + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactShapeInterface * shape0, + const btConcaveShape * shape1,bool swapped) +{ + //create the callback + btGImpactTriangleCallback tricallback; + tricallback.algorithm = this; + tricallback.body0Wrap = body0Wrap; + tricallback.body1Wrap = body1Wrap; + tricallback.gimpactshape0 = shape0; + tricallback.swapped = swapped; + tricallback.margin = shape1->getMargin(); + + //getting the trimesh AABB + btTransform gimpactInConcaveSpace; + + gimpactInConcaveSpace = body1Wrap->getWorldTransform().inverse() * body0Wrap->getWorldTransform(); + + btVector3 minAABB,maxAABB; + shape0->getAabb(gimpactInConcaveSpace,minAABB,maxAABB); + + shape1->processAllTriangles(&tricallback,minAABB,maxAABB); + +} + + + +void btGImpactCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + clearCache(); + + m_resultOut = resultOut; + m_dispatchInfo = &dispatchInfo; + const btGImpactShapeInterface * gimpactshape0; + const btGImpactShapeInterface * gimpactshape1; + + if (body0Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE) + { + gimpactshape0 = static_cast(body0Wrap->getCollisionShape()); + + if( body1Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE ) + { + gimpactshape1 = static_cast(body1Wrap->getCollisionShape()); + + gimpact_vs_gimpact(body0Wrap,body1Wrap,gimpactshape0,gimpactshape1); + } + else + { + gimpact_vs_shape(body0Wrap,body1Wrap,gimpactshape0,body1Wrap->getCollisionShape(),false); + } + + } + else if (body1Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE ) + { + gimpactshape1 = static_cast(body1Wrap->getCollisionShape()); + + gimpact_vs_shape(body1Wrap,body0Wrap,gimpactshape1,body0Wrap->getCollisionShape(),true); + } +} + + +btScalar btGImpactCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + return 1.f; + +} + +///////////////////////////////////// REGISTERING ALGORITHM ////////////////////////////////////////////// + + + +//! Use this function for register the algorithm externally +void btGImpactCollisionAlgorithm::registerAlgorithm(btCollisionDispatcher * dispatcher) +{ + + static btGImpactCollisionAlgorithm::CreateFunc s_gimpact_cf; + + int i; + + for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ ) + { + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,i ,&s_gimpact_cf); + } + + for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ ) + { + dispatcher->registerCollisionCreateFunc(i,GIMPACT_SHAPE_PROXYTYPE ,&s_gimpact_cf); + } + +} diff --git a/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h new file mode 100644 index 0000000..c01b1ee --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h @@ -0,0 +1,306 @@ +/*! \file btGImpactShape.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H +#define BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H + +#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +class btDispatcher; +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" + +#include "LinearMath/btAlignedObjectArray.h" + +#include "btGImpactShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + + +//! Collision Algorithm for GImpact Shapes +/*! +For register this algorithm in Bullet, proceed as following: + \code +btCollisionDispatcher * dispatcher = static_cast(m_dynamicsWorld ->getDispatcher()); +btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher); + \endcode +*/ +class btGImpactCollisionAlgorithm : public btActivatingCollisionAlgorithm +{ +protected: + btCollisionAlgorithm * m_convex_algorithm; + btPersistentManifold * m_manifoldPtr; + btManifoldResult* m_resultOut; + const btDispatcherInfo * m_dispatchInfo; + int m_triface0; + int m_part0; + int m_triface1; + int m_part1; + + + //! Creates a new contact point + SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0,const btCollisionObject* body1) + { + m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1); + return m_manifoldPtr; + } + + SIMD_FORCE_INLINE void destroyConvexAlgorithm() + { + if(m_convex_algorithm) + { + m_convex_algorithm->~btCollisionAlgorithm(); + m_dispatcher->freeCollisionAlgorithm( m_convex_algorithm); + m_convex_algorithm = NULL; + } + } + + SIMD_FORCE_INLINE void destroyContactManifolds() + { + if(m_manifoldPtr == NULL) return; + m_dispatcher->releaseManifold(m_manifoldPtr); + m_manifoldPtr = NULL; + } + + SIMD_FORCE_INLINE void clearCache() + { + destroyContactManifolds(); + destroyConvexAlgorithm(); + + m_triface0 = -1; + m_part0 = -1; + m_triface1 = -1; + m_part1 = -1; + } + + SIMD_FORCE_INLINE btPersistentManifold* getLastManifold() + { + return m_manifoldPtr; + } + + + // Call before process collision + SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + if(getLastManifold() == 0) + { + newContactManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + } + + m_resultOut->setPersistentManifold(getLastManifold()); + } + + // Call before process collision + SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + checkManifold(body0Wrap,body1Wrap); + + btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm( + body0Wrap,body1Wrap,getLastManifold()); + return convex_algorithm ; + } + + // Call before process collision + SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + if(m_convex_algorithm) return; + m_convex_algorithm = newAlgorithm(body0Wrap,body1Wrap); + } + + + + + void addContactPoint(const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btVector3 & point, + const btVector3 & normal, + btScalar distance); + +//! Collision routines +//!@{ + + void collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart * shape0, + const btGImpactMeshShapePart * shape1, + const int * pairs, int pair_count); + + void collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart * shape0, + const btGImpactMeshShapePart * shape1, + const int * pairs, int pair_count); + + + + + void shape_vs_shape_collision( + const btCollisionObjectWrapper* body0, + const btCollisionObjectWrapper* body1, + const btCollisionShape * shape0, + const btCollisionShape * shape1); + + void convex_vs_convex_collision(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btCollisionShape* shape0, + const btCollisionShape* shape1); + + + + void gimpact_vs_gimpact_find_pairs( + const btTransform & trans0, + const btTransform & trans1, + const btGImpactShapeInterface * shape0, + const btGImpactShapeInterface * shape1,btPairSet & pairset); + + void gimpact_vs_shape_find_pairs( + const btTransform & trans0, + const btTransform & trans1, + const btGImpactShapeInterface * shape0, + const btCollisionShape * shape1, + btAlignedObjectArray & collided_primitives); + + + void gimpacttrimeshpart_vs_plane_collision( + const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactMeshShapePart * shape0, + const btStaticPlaneShape * shape1,bool swapped); + + +public: + + btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + + virtual ~btGImpactCollisionAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr) + manifoldArray.push_back(m_manifoldPtr); + } + + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm)); + return new(mem) btGImpactCollisionAlgorithm(ci,body0Wrap,body1Wrap); + } + }; + + //! Use this function for register the algorithm externally + static void registerAlgorithm(btCollisionDispatcher * dispatcher); +#ifdef TRI_COLLISION_PROFILING + //! Gets the average time in miliseconds of tree collisions + static float getAverageTreeCollisionTime(); + + //! Gets the average time in miliseconds of triangle collisions + static float getAverageTriangleCollisionTime(); +#endif //TRI_COLLISION_PROFILING + + //! Collides two gimpact shapes + /*! + \pre shape0 and shape1 couldn't be btGImpactMeshShape objects + */ + + + void gimpact_vs_gimpact(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactShapeInterface * shape0, + const btGImpactShapeInterface * shape1); + + void gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface * shape0, + const btCollisionShape * shape1,bool swapped); + + void gimpact_vs_compoundshape(const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactShapeInterface * shape0, + const btCompoundShape * shape1,bool swapped); + + void gimpact_vs_concave( + const btCollisionObjectWrapper * body0Wrap, + const btCollisionObjectWrapper * body1Wrap, + const btGImpactShapeInterface * shape0, + const btConcaveShape * shape1,bool swapped); + + + + + /// Accessor/Mutator pairs for Part and triangleID + void setFace0(int value) + { + m_triface0 = value; + } + int getFace0() + { + return m_triface0; + } + void setFace1(int value) + { + m_triface1 = value; + } + int getFace1() + { + return m_triface1; + } + void setPart0(int value) + { + m_part0 = value; + } + int getPart0() + { + return m_part0; + } + void setPart1(int value) + { + m_part1 = value; + } + int getPart1() + { + return m_part1; + } + +}; + + +//algorithm details +//#define BULLET_TRIANGLE_COLLISION 1 +#define GIMPACT_VS_PLANE_COLLISION 1 + + + +#endif //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/Gimpact/btGImpactMassUtil.h b/src/BulletCollision/Gimpact/btGImpactMassUtil.h new file mode 100644 index 0000000..2543aef --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactMassUtil.h @@ -0,0 +1,60 @@ +/*! \file btGImpactMassUtil.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef GIMPACT_MASS_UTIL_H +#define GIMPACT_MASS_UTIL_H + +#include "LinearMath/btTransform.h" + + + +SIMD_FORCE_INLINE btVector3 gim_inertia_add_transformed( + const btVector3 & source_inertia, const btVector3 & added_inertia, const btTransform & transform) +{ + btMatrix3x3 rotatedTensor = transform.getBasis().scaled(added_inertia) * transform.getBasis().transpose(); + + btScalar x2 = transform.getOrigin()[0]; + x2*= x2; + btScalar y2 = transform.getOrigin()[1]; + y2*= y2; + btScalar z2 = transform.getOrigin()[2]; + z2*= z2; + + btScalar ix = rotatedTensor[0][0]*(y2+z2); + btScalar iy = rotatedTensor[1][1]*(x2+z2); + btScalar iz = rotatedTensor[2][2]*(x2+y2); + + return btVector3(source_inertia[0]+ix,source_inertia[1]+iy,source_inertia[2] + iz); +} + +SIMD_FORCE_INLINE btVector3 gim_get_point_inertia(const btVector3 & point, btScalar mass) +{ + btScalar x2 = point[0]*point[0]; + btScalar y2 = point[1]*point[1]; + btScalar z2 = point[2]*point[2]; + return btVector3(mass*(y2+z2),mass*(x2+z2),mass*(x2+y2)); +} + + +#endif //GIMPACT_MESH_SHAPE_H diff --git a/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp new file mode 100644 index 0000000..4528758 --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp @@ -0,0 +1,528 @@ +/*! \file gim_box_set.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btGImpactQuantizedBvh.h" +#include "LinearMath/btQuickprof.h" + +#ifdef TRI_COLLISION_PROFILING +btClock g_q_tree_clock; + + +float g_q_accum_tree_collision_time = 0; +int g_q_count_traversing = 0; + + +void bt_begin_gim02_q_tree_time() +{ + g_q_tree_clock.reset(); +} + +void bt_end_gim02_q_tree_time() +{ + g_q_accum_tree_collision_time += g_q_tree_clock.getTimeMicroseconds(); + g_q_count_traversing++; +} + + +//! Gets the average time in miliseconds of tree collisions +float btGImpactQuantizedBvh::getAverageTreeCollisionTime() +{ + if(g_q_count_traversing == 0) return 0; + + float avgtime = g_q_accum_tree_collision_time; + avgtime /= (float)g_q_count_traversing; + + g_q_accum_tree_collision_time = 0; + g_q_count_traversing = 0; + return avgtime; + +// float avgtime = g_q_count_traversing; +// g_q_count_traversing = 0; +// return avgtime; + +} + +#endif //TRI_COLLISION_PROFILING + +/////////////////////// btQuantizedBvhTree ///////////////////////////////// + +void btQuantizedBvhTree::calc_quantization( + GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin) +{ + //calc globa box + btAABB global_bound; + global_bound.invalidate(); + + for (int i=0;i splitValue) + { + //swap + primitive_boxes.swap(i,splitIndex); + //swapLeafNodes(i,splitIndex); + splitIndex++; + } + } + + //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex + //otherwise the tree-building might fail due to stack-overflows in certain cases. + //unbalanced1 is unsafe: it can cause stack overflows + //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); + + //unbalanced2 should work too: always use center (perfect balanced trees) + //bool unbalanced2 = true; + + //this should be safe too: + int rangeBalancedIndices = numIndices/3; + bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + + if (unbalanced) + { + splitIndex = startIndex+ (numIndices>>1); + } + + btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); + + return splitIndex; + +} + + +void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex) +{ + int curIndex = m_num_nodes; + m_num_nodes++; + + btAssert((endIndex-startIndex)>0); + + if ((endIndex-startIndex)==1) + { + //We have a leaf node + setNodeBound(curIndex,primitive_boxes[startIndex].m_bound); + m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data); + + return; + } + //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. + + //split axis + int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex); + + splitIndex = _sort_and_calc_splitting_index( + primitive_boxes,startIndex,endIndex, + splitIndex//split axis + ); + + + //calc this node bounding box + + btAABB node_bound; + node_bound.invalidate(); + + for (int i=startIndex;iget_primitive_box(getNodeData(nodecount),leafbox); + setNodeBound(nodecount,leafbox); + } + else + { + //const GIM_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount); + //get left bound + btAABB bound; + bound.invalidate(); + + btAABB temp_box; + + int child_node = getLeftNode(nodecount); + if(child_node) + { + getNodeBound(child_node,temp_box); + bound.merge(temp_box); + } + + child_node = getRightNode(nodecount); + if(child_node) + { + getNodeBound(child_node,temp_box); + bound.merge(temp_box); + } + + setNodeBound(nodecount,bound); + } + } +} + +//! this rebuild the entire set +void btGImpactQuantizedBvh::buildSet() +{ + //obtain primitive boxes + GIM_BVH_DATA_ARRAY primitive_boxes; + primitive_boxes.resize(m_primitive_manager->get_primitive_count()); + + for (int i = 0;iget_primitive_box(i,primitive_boxes[i].m_bound); + primitive_boxes[i].m_data = i; + } + + m_box_tree.build_tree(primitive_boxes); +} + +//! returns the indices of the primitives in the m_primitive_manager +bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const +{ + int curIndex = 0; + int numNodes = getNodeCount(); + + //quantize box + + unsigned short quantizedMin[3]; + unsigned short quantizedMax[3]; + + m_box_tree.quantizePoint(quantizedMin,box.m_min); + m_box_tree.quantizePoint(quantizedMax,box.m_max); + + + while (curIndex < numNodes) + { + + //catch bugs in tree data + + bool aabbOverlap = m_box_tree.testQuantizedBoxOverlapp(curIndex, quantizedMin,quantizedMax); + bool isleafnode = isLeafNode(curIndex); + + if (isleafnode && aabbOverlap) + { + collided_results.push_back(getNodeData(curIndex)); + } + + if (aabbOverlap || isleafnode) + { + //next subnode + curIndex++; + } + else + { + //skip node + curIndex+= getEscapeNodeIndex(curIndex); + } + } + if(collided_results.size()>0) return true; + return false; +} + + + +//! returns the indices of the primitives in the m_primitive_manager +bool btGImpactQuantizedBvh::rayQuery( + const btVector3 & ray_dir,const btVector3 & ray_origin , + btAlignedObjectArray & collided_results) const +{ + int curIndex = 0; + int numNodes = getNodeCount(); + + while (curIndex < numNodes) + { + btAABB bound; + getNodeBound(curIndex,bound); + + //catch bugs in tree data + + bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir); + bool isleafnode = isLeafNode(curIndex); + + if (isleafnode && aabbOverlap) + { + collided_results.push_back(getNodeData( curIndex)); + } + + if (aabbOverlap || isleafnode) + { + //next subnode + curIndex++; + } + else + { + //skip node + curIndex+= getEscapeNodeIndex(curIndex); + } + } + if(collided_results.size()>0) return true; + return false; +} + + +SIMD_FORCE_INLINE bool _quantized_node_collision( + const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1, + const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, + int node0 ,int node1, bool complete_primitive_tests) +{ + btAABB box0; + boxset0->getNodeBound(node0,box0); + btAABB box1; + boxset1->getNodeBound(node1,box1); + + return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests ); +// box1.appy_transform_trans_cache(trans_cache_1to0); +// return box0.has_collision(box1); + +} + + +//stackless recursive collision routine +static void _find_quantized_collision_pairs_recursive( + const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1, + btPairSet * collision_pairs, + const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, + int node0, int node1, bool complete_primitive_tests) +{ + + + + if( _quantized_node_collision( + boxset0,boxset1,trans_cache_1to0, + node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes + + if(boxset0->isLeafNode(node0)) + { + if(boxset1->isLeafNode(node1)) + { + // collision result + collision_pairs->push_pair( + boxset0->getNodeData(node0),boxset1->getNodeData(node1)); + return; + } + else + { + + //collide left recursive + + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + node0,boxset1->getLeftNode(node1),false); + + //collide right recursive + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + node0,boxset1->getRightNode(node1),false); + + + } + } + else + { + if(boxset1->isLeafNode(node1)) + { + + //collide left recursive + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getLeftNode(node0),node1,false); + + + //collide right recursive + + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getRightNode(node0),node1,false); + + + } + else + { + //collide left0 left1 + + + + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false); + + //collide left0 right1 + + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false); + + + //collide right0 left1 + + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false); + + //collide right0 right1 + + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + collision_pairs,trans_cache_1to0, + boxset0->getRightNode(node0),boxset1->getRightNode(node1),false); + + }// else if node1 is not a leaf + }// else if node0 is not a leaf +} + + +void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh * boxset0, const btTransform & trans0, + const btGImpactQuantizedBvh * boxset1, const btTransform & trans1, + btPairSet & collision_pairs) +{ + + if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return; + + BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0; + + trans_cache_1to0.calc_from_homogenic(trans0,trans1); + +#ifdef TRI_COLLISION_PROFILING + bt_begin_gim02_q_tree_time(); +#endif //TRI_COLLISION_PROFILING + + _find_quantized_collision_pairs_recursive( + boxset0,boxset1, + &collision_pairs,trans_cache_1to0,0,0,true); +#ifdef TRI_COLLISION_PROFILING + bt_end_gim02_q_tree_time(); +#endif //TRI_COLLISION_PROFILING + +} + + diff --git a/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h new file mode 100644 index 0000000..e6e52ff --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h @@ -0,0 +1,372 @@ +#ifndef GIM_QUANTIZED_SET_H_INCLUDED +#define GIM_QUANTIZED_SET_H_INCLUDED + +/*! \file btGImpactQuantizedBvh.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btGImpactBvh.h" +#include "btQuantization.h" + + + + + +///btQuantizedBvhNode is a compressed aabb node, 16 bytes. +///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). +ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE +{ + //12 bytes + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; + //4 bytes + int m_escapeIndexOrDataIndex; + + BT_QUANTIZED_BVH_NODE() + { + m_escapeIndexOrDataIndex = 0; + } + + SIMD_FORCE_INLINE bool isLeafNode() const + { + //skipindex is negative (internal node), triangleindex >=0 (leafnode) + return (m_escapeIndexOrDataIndex>=0); + } + + SIMD_FORCE_INLINE int getEscapeIndex() const + { + //btAssert(m_escapeIndexOrDataIndex < 0); + return -m_escapeIndexOrDataIndex; + } + + SIMD_FORCE_INLINE void setEscapeIndex(int index) + { + m_escapeIndexOrDataIndex = -index; + } + + SIMD_FORCE_INLINE int getDataIndex() const + { + //btAssert(m_escapeIndexOrDataIndex >= 0); + + return m_escapeIndexOrDataIndex; + } + + SIMD_FORCE_INLINE void setDataIndex(int index) + { + m_escapeIndexOrDataIndex = index; + } + + SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp( + unsigned short * quantizedMin,unsigned short * quantizedMax) const + { + if(m_quantizedAabbMin[0] > quantizedMax[0] || + m_quantizedAabbMax[0] < quantizedMin[0] || + m_quantizedAabbMin[1] > quantizedMax[1] || + m_quantizedAabbMax[1] < quantizedMin[1] || + m_quantizedAabbMin[2] > quantizedMax[2] || + m_quantizedAabbMax[2] < quantizedMin[2]) + { + return false; + } + return true; + } + +}; + + + +class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray +{ +}; + + + + +//! Basic Box tree structure +class btQuantizedBvhTree +{ +protected: + int m_num_nodes; + GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array; + btAABB m_global_bound; + btVector3 m_bvhQuantization; +protected: + void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) ); + + int _sort_and_calc_splitting_index( + GIM_BVH_DATA_ARRAY & primitive_boxes, + int startIndex, int endIndex, int splitAxis); + + int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); + + void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); +public: + btQuantizedBvhTree() + { + m_num_nodes = 0; + } + + //! prototype functions for box tree management + //!@{ + void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes); + + SIMD_FORCE_INLINE void quantizePoint( + unsigned short * quantizedpoint, const btVector3 & point) const + { + bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization); + } + + + SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp( + int node_index, + unsigned short * quantizedMin,unsigned short * quantizedMax) const + { + return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax); + } + + SIMD_FORCE_INLINE void clearNodes() + { + m_node_array.clear(); + m_num_nodes = 0; + } + + //! node count + SIMD_FORCE_INLINE int getNodeCount() const + { + return m_num_nodes; + } + + //! tells if the node is a leaf + SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const + { + return m_node_array[nodeindex].isLeafNode(); + } + + SIMD_FORCE_INLINE int getNodeData(int nodeindex) const + { + return m_node_array[nodeindex].getDataIndex(); + } + + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + { + bound.m_min = bt_unquantize( + m_node_array[nodeindex].m_quantizedAabbMin, + m_global_bound.m_min,m_bvhQuantization); + + bound.m_max = bt_unquantize( + m_node_array[nodeindex].m_quantizedAabbMax, + m_global_bound.m_min,m_bvhQuantization); + } + + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + { + bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMin, + bound.m_min, + m_global_bound.m_min, + m_global_bound.m_max, + m_bvhQuantization); + + bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMax, + bound.m_max, + m_global_bound.m_min, + m_global_bound.m_max, + m_bvhQuantization); + } + + SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const + { + return nodeindex+1; + } + + SIMD_FORCE_INLINE int getRightNode(int nodeindex) const + { + if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2; + return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex(); + } + + SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const + { + return m_node_array[nodeindex].getEscapeIndex(); + } + + SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const + { + return &m_node_array[index]; + } + + //!@} +}; + + + +//! Structure for containing Boxes +/*! +This class offers an structure for managing a box tree of primitives. +Requires a Primitive prototype (like btPrimitiveManagerBase ) +*/ +class btGImpactQuantizedBvh +{ +protected: + btQuantizedBvhTree m_box_tree; + btPrimitiveManagerBase * m_primitive_manager; + +protected: + //stackless refit + void refit(); +public: + + //! this constructor doesn't build the tree. you must call buildSet + btGImpactQuantizedBvh() + { + m_primitive_manager = NULL; + } + + //! this constructor doesn't build the tree. you must call buildSet + btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager) + { + m_primitive_manager = primitive_manager; + } + + SIMD_FORCE_INLINE btAABB getGlobalBox() const + { + btAABB totalbox; + getNodeBound(0, totalbox); + return totalbox; + } + + SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager) + { + m_primitive_manager = primitive_manager; + } + + SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const + { + return m_primitive_manager; + } + + +//! node manager prototype functions +///@{ + + //! this attemps to refit the box set. + SIMD_FORCE_INLINE void update() + { + refit(); + } + + //! this rebuild the entire set + void buildSet(); + + //! returns the indices of the primitives in the m_primitive_manager + bool boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const; + + //! returns the indices of the primitives in the m_primitive_manager + SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box, + const btTransform & transform, btAlignedObjectArray & collided_results) const + { + btAABB transbox=box; + transbox.appy_transform(transform); + return boxQuery(transbox,collided_results); + } + + //! returns the indices of the primitives in the m_primitive_manager + bool rayQuery( + const btVector3 & ray_dir,const btVector3 & ray_origin , + btAlignedObjectArray & collided_results) const; + + //! tells if this set has hierarcht + SIMD_FORCE_INLINE bool hasHierarchy() const + { + return true; + } + + //! tells if this set is a trimesh + SIMD_FORCE_INLINE bool isTrimesh() const + { + return m_primitive_manager->is_trimesh(); + } + + //! node count + SIMD_FORCE_INLINE int getNodeCount() const + { + return m_box_tree.getNodeCount(); + } + + //! tells if the node is a leaf + SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const + { + return m_box_tree.isLeafNode(nodeindex); + } + + SIMD_FORCE_INLINE int getNodeData(int nodeindex) const + { + return m_box_tree.getNodeData(nodeindex); + } + + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + { + m_box_tree.getNodeBound(nodeindex, bound); + } + + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + { + m_box_tree.setNodeBound(nodeindex, bound); + } + + + SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const + { + return m_box_tree.getLeftNode(nodeindex); + } + + SIMD_FORCE_INLINE int getRightNode(int nodeindex) const + { + return m_box_tree.getRightNode(nodeindex); + } + + SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const + { + return m_box_tree.getEscapeNodeIndex(nodeindex); + } + + SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const + { + m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle); + } + + + SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const + { + return m_box_tree.get_node_pointer(index); + } + +#ifdef TRI_COLLISION_PROFILING + static float getAverageTreeCollisionTime(); +#endif //TRI_COLLISION_PROFILING + + static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1, + const btGImpactQuantizedBvh * boxset2, const btTransform & trans2, + btPairSet & collision_pairs); +}; + + +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btGImpactShape.cpp b/src/BulletCollision/Gimpact/btGImpactShape.cpp new file mode 100644 index 0000000..cceace5 --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactShape.cpp @@ -0,0 +1,203 @@ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btGImpactShape.h" +#include "btGImpactMassUtil.h" + + +#define CALC_EXACT_INERTIA 1 + +void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + lockChildShapes(); +#ifdef CALC_EXACT_INERTIA + inertia.setValue(0.f,0.f,0.f); + + int i = this->getNumChildShapes(); + btScalar shapemass = mass/btScalar(i); + + while(i--) + { + btVector3 temp_inertia; + m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia); + if(childrenHasTransform()) + { + inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]); + } + else + { + inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity()); + } + + } + +#else + + // Calc box inertia + + btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0]; + btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1]; + btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2]; + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(0.08333333); + + inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + +#endif + unlockChildShapes(); +} + + + +void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + lockChildShapes(); + + +#ifdef CALC_EXACT_INERTIA + inertia.setValue(0.f,0.f,0.f); + + int i = this->getVertexCount(); + btScalar pointmass = mass/btScalar(i); + + while(i--) + { + btVector3 pointintertia; + this->getVertex(i,pointintertia); + pointintertia = gim_get_point_inertia(pointintertia,pointmass); + inertia+=pointintertia; + } + +#else + + // Calc box inertia + + btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0]; + btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1]; + btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2]; + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(0.08333333); + + inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + +#endif + + unlockChildShapes(); +} + +void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + +#ifdef CALC_EXACT_INERTIA + inertia.setValue(0.f,0.f,0.f); + + int i = this->getMeshPartCount(); + btScalar partmass = mass/btScalar(i); + + while(i--) + { + btVector3 partinertia; + getMeshPart(i)->calculateLocalInertia(partmass,partinertia); + inertia+=partinertia; + } + +#else + + // Calc box inertia + + btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0]; + btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1]; + btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2]; + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(0.08333333); + + inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + +#endif +} + +void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const +{ +} + + +void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + lockChildShapes(); + btAABB box; + box.m_min = aabbMin; + box.m_max = aabbMax; + + btAlignedObjectArray collided; + m_box_set.boxQuery(box,collided); + + if(collided.size()==0) + { + unlockChildShapes(); + return; + } + + int part = (int)getPart(); + btPrimitiveTriangle triangle; + int i = collided.size(); + while(i--) + { + this->getPrimitiveTriangle(collided[i],triangle); + callback->processTriangle(triangle.m_vertices,part,collided[i]); + } + unlockChildShapes(); + +} + +void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + int i = m_mesh_parts.size(); + while(i--) + { + m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax); + } +} + + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*) dataBuffer; + + btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer); + + m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer); + + trimeshData->m_collisionMargin = float(m_collisionMargin); + + localScaling.serializeFloat(trimeshData->m_localScaling); + + trimeshData->m_gimpactSubType = int(getGImpactShapeType()); + + return "btGImpactMeshShapeData"; +} + diff --git a/src/BulletCollision/Gimpact/btGImpactShape.h b/src/BulletCollision/Gimpact/btGImpactShape.h new file mode 100644 index 0000000..dbcd4d7 --- /dev/null +++ b/src/BulletCollision/Gimpact/btGImpactShape.h @@ -0,0 +1,1171 @@ +/*! \file btGImpactShape.h +\author Francisco Len Nßjera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef GIMPACT_SHAPE_H +#define GIMPACT_SHAPE_H + +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "BulletCollision/CollisionShapes/btConcaveShape.h" +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btAlignedObjectArray.h" + +#include "btGImpactQuantizedBvh.h" // box tree class + + +//! declare Quantized trees, (you can change to float based trees) +typedef btGImpactQuantizedBvh btGImpactBoxSet; + +enum eGIMPACT_SHAPE_TYPE +{ + CONST_GIMPACT_COMPOUND_SHAPE = 0, + CONST_GIMPACT_TRIMESH_SHAPE_PART, + CONST_GIMPACT_TRIMESH_SHAPE +}; + + +//! Helper class for tetrahedrons +class btTetrahedronShapeEx:public btBU_Simplex1to4 +{ +public: + btTetrahedronShapeEx() + { + m_numVertices = 4; + } + + + SIMD_FORCE_INLINE void setVertices( + const btVector3 & v0,const btVector3 & v1, + const btVector3 & v2,const btVector3 & v3) + { + m_vertices[0] = v0; + m_vertices[1] = v1; + m_vertices[2] = v2; + m_vertices[3] = v3; + recalcLocalAabb(); + } +}; + + +//! Base class for gimpact shapes +class btGImpactShapeInterface : public btConcaveShape +{ +protected: + btAABB m_localAABB; + bool m_needs_update; + btVector3 localScaling; + btGImpactBoxSet m_box_set;// optionally boxset + + //! use this function for perfofm refit in bounding boxes + //! use this function for perfofm refit in bounding boxes + virtual void calcLocalAABB() + { + lockChildShapes(); + if(m_box_set.getNodeCount() == 0) + { + m_box_set.buildSet(); + } + else + { + m_box_set.update(); + } + unlockChildShapes(); + + m_localAABB = m_box_set.getGlobalBox(); + } + + +public: + btGImpactShapeInterface() + { + m_shapeType=GIMPACT_SHAPE_PROXYTYPE; + m_localAABB.invalidate(); + m_needs_update = true; + localScaling.setValue(1.f,1.f,1.f); + } + + + //! performs refit operation + /*! + Updates the entire Box set of this shape. + \pre postUpdate() must be called for attemps to calculating the box set, else this function + will does nothing. + \post if m_needs_update == true, then it calls calcLocalAABB(); + */ + SIMD_FORCE_INLINE void updateBound() + { + if(!m_needs_update) return; + calcLocalAABB(); + m_needs_update = false; + } + + //! If the Bounding box is not updated, then this class attemps to calculate it. + /*! + \post Calls updateBound() for update the box set. + */ + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + btAABB transformedbox = m_localAABB; + transformedbox.appy_transform(t); + aabbMin = transformedbox.m_min; + aabbMax = transformedbox.m_max; + } + + //! Tells to this object that is needed to refit the box set + virtual void postUpdate() + { + m_needs_update = true; + } + + //! Obtains the local box, which is the global calculated box of the total of subshapes + SIMD_FORCE_INLINE const btAABB & getLocalBox() + { + return m_localAABB; + } + + + virtual int getShapeType() const + { + return GIMPACT_SHAPE_PROXYTYPE; + } + + /*! + \post You must call updateBound() for update the box set. + */ + virtual void setLocalScaling(const btVector3& scaling) + { + localScaling = scaling; + postUpdate(); + } + + virtual const btVector3& getLocalScaling() const + { + return localScaling; + } + + + virtual void setMargin(btScalar margin) + { + m_collisionMargin = margin; + int i = getNumChildShapes(); + while(i--) + { + btCollisionShape* child = getChildShape(i); + child->setMargin(margin); + } + + m_needs_update = true; + } + + + //! Subshape member functions + //!@{ + + //! Base method for determinig which kind of GIMPACT shape we get + virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ; + + //! gets boxset + SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const + { + return &m_box_set; + } + + //! Determines if this class has a hierarchy structure for sorting its primitives + SIMD_FORCE_INLINE bool hasBoxSet() const + { + if(m_box_set.getNodeCount() == 0) return false; + return true; + } + + //! Obtains the primitive manager + virtual const btPrimitiveManagerBase * getPrimitiveManager() const = 0; + + + //! Gets the number of children + virtual int getNumChildShapes() const = 0; + + //! if true, then its children must get transforms. + virtual bool childrenHasTransform() const = 0; + + //! Determines if this shape has triangles + virtual bool needsRetrieveTriangles() const = 0; + + //! Determines if this shape has tetrahedrons + virtual bool needsRetrieveTetrahedrons() const = 0; + + virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const = 0; + + virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const = 0; + + + + //! call when reading child shapes + virtual void lockChildShapes() const + { + } + + virtual void unlockChildShapes() const + { + } + + //! if this trimesh + SIMD_FORCE_INLINE void getPrimitiveTriangle(int index,btPrimitiveTriangle & triangle) const + { + getPrimitiveManager()->get_primitive_triangle(index,triangle); + } + + + //! Retrieves the bound from a child + /*! + */ + virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + btAABB child_aabb; + getPrimitiveManager()->get_primitive_box(child_index,child_aabb); + child_aabb.appy_transform(t); + aabbMin = child_aabb.m_min; + aabbMax = child_aabb.m_max; + } + + //! Gets the children + virtual btCollisionShape* getChildShape(int index) = 0; + + + //! Gets the child + virtual const btCollisionShape* getChildShape(int index) const = 0; + + //! Gets the children transform + virtual btTransform getChildTransform(int index) const = 0; + + //! Sets the children transform + /*! + \post You must call updateBound() for update the box set. + */ + virtual void setChildTransform(int index, const btTransform & transform) = 0; + + //!@} + + + //! virtual method for ray collision + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const + { + (void) rayFrom; (void) rayTo; (void) resultCallback; + } + + //! Function for retrieve triangles. + /*! + It gives the triangles in local space + */ + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const + { + (void) callback; (void) aabbMin; (void) aabbMax; + } + + //!@} + +}; + + +//! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once +/*! +This class only can manage Convex subshapes +*/ +class btGImpactCompoundShape : public btGImpactShapeInterface +{ +public: + //! compound primitive manager + class CompoundPrimitiveManager:public btPrimitiveManagerBase + { + public: + virtual ~CompoundPrimitiveManager() {} + btGImpactCompoundShape * m_compoundShape; + + + CompoundPrimitiveManager(const CompoundPrimitiveManager& compound) + : btPrimitiveManagerBase() + { + m_compoundShape = compound.m_compoundShape; + } + + CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape) + { + m_compoundShape = compoundShape; + } + + CompoundPrimitiveManager() + { + m_compoundShape = NULL; + } + + virtual bool is_trimesh() const + { + return false; + } + + virtual int get_primitive_count() const + { + return (int )m_compoundShape->getNumChildShapes(); + } + + virtual void get_primitive_box(int prim_index ,btAABB & primbox) const + { + btTransform prim_trans; + if(m_compoundShape->childrenHasTransform()) + { + prim_trans = m_compoundShape->getChildTransform(prim_index); + } + else + { + prim_trans.setIdentity(); + } + const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index); + shape->getAabb(prim_trans,primbox.m_min,primbox.m_max); + } + + virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const + { + btAssert(0); + (void) prim_index; (void) triangle; + } + + }; + + + +protected: + CompoundPrimitiveManager m_primitive_manager; + btAlignedObjectArray m_childTransforms; + btAlignedObjectArray m_childShapes; + + +public: + + btGImpactCompoundShape(bool children_has_transform = true) + { + (void) children_has_transform; + m_primitive_manager.m_compoundShape = this; + m_box_set.setPrimitiveManager(&m_primitive_manager); + } + + virtual ~btGImpactCompoundShape() + { + } + + + //! if true, then its children must get transforms. + virtual bool childrenHasTransform() const + { + if(m_childTransforms.size()==0) return false; + return true; + } + + + //! Obtains the primitive manager + virtual const btPrimitiveManagerBase * getPrimitiveManager() const + { + return &m_primitive_manager; + } + + //! Obtains the compopund primitive manager + SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager() + { + return &m_primitive_manager; + } + + //! Gets the number of children + virtual int getNumChildShapes() const + { + return m_childShapes.size(); + } + + + //! Use this method for adding children. Only Convex shapes are allowed. + void addChildShape(const btTransform& localTransform,btCollisionShape* shape) + { + btAssert(shape->isConvex()); + m_childTransforms.push_back(localTransform); + m_childShapes.push_back(shape); + } + + //! Use this method for adding children. Only Convex shapes are allowed. + void addChildShape(btCollisionShape* shape) + { + btAssert(shape->isConvex()); + m_childShapes.push_back(shape); + } + + //! Gets the children + virtual btCollisionShape* getChildShape(int index) + { + return m_childShapes[index]; + } + + //! Gets the children + virtual const btCollisionShape* getChildShape(int index) const + { + return m_childShapes[index]; + } + + //! Retrieves the bound from a child + /*! + */ + virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + + if(childrenHasTransform()) + { + m_childShapes[child_index]->getAabb(t*m_childTransforms[child_index],aabbMin,aabbMax); + } + else + { + m_childShapes[child_index]->getAabb(t,aabbMin,aabbMax); + } + } + + + //! Gets the children transform + virtual btTransform getChildTransform(int index) const + { + btAssert(m_childTransforms.size() == m_childShapes.size()); + return m_childTransforms[index]; + } + + //! Sets the children transform + /*! + \post You must call updateBound() for update the box set. + */ + virtual void setChildTransform(int index, const btTransform & transform) + { + btAssert(m_childTransforms.size() == m_childShapes.size()); + m_childTransforms[index] = transform; + postUpdate(); + } + + //! Determines if this shape has triangles + virtual bool needsRetrieveTriangles() const + { + return false; + } + + //! Determines if this shape has tetrahedrons + virtual bool needsRetrieveTetrahedrons() const + { + return false; + } + + + virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const + { + (void) prim_index; (void) triangle; + btAssert(0); + } + + virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const + { + (void) prim_index; (void) tetrahedron; + btAssert(0); + } + + + //! Calculates the exact inertia tensor for this shape + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + virtual const char* getName()const + { + return "GImpactCompound"; + } + + virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const + { + return CONST_GIMPACT_COMPOUND_SHAPE; + } + +}; + + + +//! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface. +/*! +- Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh +- When making operations with this shape, you must call lock before accessing to the trimesh primitives, and then call unlock +- You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices. + +*/ +class btGImpactMeshShapePart : public btGImpactShapeInterface +{ +public: + //! Trimesh primitive manager + /*! + Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism + */ + class TrimeshPrimitiveManager:public btPrimitiveManagerBase + { + public: + btScalar m_margin; + btStridingMeshInterface * m_meshInterface; + btVector3 m_scale; + int m_part; + int m_lock_count; + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + TrimeshPrimitiveManager() + { + m_meshInterface = NULL; + m_part = 0; + m_margin = 0.01f; + m_scale = btVector3(1.f,1.f,1.f); + m_lock_count = 0; + vertexbase = 0; + numverts = 0; + stride = 0; + indexbase = 0; + indexstride = 0; + numfaces = 0; + } + + TrimeshPrimitiveManager(const TrimeshPrimitiveManager & manager) + : btPrimitiveManagerBase() + { + m_meshInterface = manager.m_meshInterface; + m_part = manager.m_part; + m_margin = manager.m_margin; + m_scale = manager.m_scale; + m_lock_count = 0; + vertexbase = 0; + numverts = 0; + stride = 0; + indexbase = 0; + indexstride = 0; + numfaces = 0; + + } + + TrimeshPrimitiveManager( + btStridingMeshInterface * meshInterface, int part) + { + m_meshInterface = meshInterface; + m_part = part; + m_scale = m_meshInterface->getScaling(); + m_margin = 0.1f; + m_lock_count = 0; + vertexbase = 0; + numverts = 0; + stride = 0; + indexbase = 0; + indexstride = 0; + numfaces = 0; + + } + + virtual ~TrimeshPrimitiveManager() {} + + void lock() + { + if(m_lock_count>0) + { + m_lock_count++; + return; + } + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase,numverts, + type, stride,&indexbase, indexstride, numfaces,indicestype,m_part); + + m_lock_count = 1; + } + + void unlock() + { + if(m_lock_count == 0) return; + if(m_lock_count>1) + { + --m_lock_count; + return; + } + m_meshInterface->unLockReadOnlyVertexBase(m_part); + vertexbase = NULL; + m_lock_count = 0; + } + + virtual bool is_trimesh() const + { + return true; + } + + virtual int get_primitive_count() const + { + return (int )numfaces; + } + + SIMD_FORCE_INLINE int get_vertex_count() const + { + return (int )numverts; + } + + SIMD_FORCE_INLINE void get_indices(int face_index,int &i0,int &i1,int &i2) const + { + if(indicestype == PHY_SHORT) + { + unsigned short * s_indices = (unsigned short *)(indexbase + face_index*indexstride); + i0 = s_indices[0]; + i1 = s_indices[1]; + i2 = s_indices[2]; + } + else + { + int * i_indices = (int *)(indexbase + face_index*indexstride); + i0 = i_indices[0]; + i1 = i_indices[1]; + i2 = i_indices[2]; + } + } + + SIMD_FORCE_INLINE void get_vertex(int vertex_index, btVector3 & vertex) const + { + if(type == PHY_DOUBLE) + { + double * dvertices = (double *)(vertexbase + vertex_index*stride); + vertex[0] = btScalar(dvertices[0]*m_scale[0]); + vertex[1] = btScalar(dvertices[1]*m_scale[1]); + vertex[2] = btScalar(dvertices[2]*m_scale[2]); + } + else + { + float * svertices = (float *)(vertexbase + vertex_index*stride); + vertex[0] = svertices[0]*m_scale[0]; + vertex[1] = svertices[1]*m_scale[1]; + vertex[2] = svertices[2]*m_scale[2]; + } + } + + virtual void get_primitive_box(int prim_index ,btAABB & primbox) const + { + btPrimitiveTriangle triangle; + get_primitive_triangle(prim_index,triangle); + primbox.calc_from_triangle_margin( + triangle.m_vertices[0], + triangle.m_vertices[1],triangle.m_vertices[2],triangle.m_margin); + } + + virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const + { + int indices[3]; + get_indices(prim_index,indices[0],indices[1],indices[2]); + get_vertex(indices[0],triangle.m_vertices[0]); + get_vertex(indices[1],triangle.m_vertices[1]); + get_vertex(indices[2],triangle.m_vertices[2]); + triangle.m_margin = m_margin; + } + + SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const + { + int indices[3]; + get_indices(prim_index,indices[0],indices[1],indices[2]); + get_vertex(indices[0],triangle.m_vertices1[0]); + get_vertex(indices[1],triangle.m_vertices1[1]); + get_vertex(indices[2],triangle.m_vertices1[2]); + triangle.setMargin(m_margin); + } + + }; + + +protected: + TrimeshPrimitiveManager m_primitive_manager; +public: + + btGImpactMeshShapePart() + { + m_box_set.setPrimitiveManager(&m_primitive_manager); + } + + + btGImpactMeshShapePart(btStridingMeshInterface * meshInterface, int part) + { + m_primitive_manager.m_meshInterface = meshInterface; + m_primitive_manager.m_part = part; + m_box_set.setPrimitiveManager(&m_primitive_manager); + } + + virtual ~btGImpactMeshShapePart() + { + } + + //! if true, then its children must get transforms. + virtual bool childrenHasTransform() const + { + return false; + } + + + //! call when reading child shapes + virtual void lockChildShapes() const + { + void * dummy = (void*)(m_box_set.getPrimitiveManager()); + TrimeshPrimitiveManager * dummymanager = static_cast(dummy); + dummymanager->lock(); + } + + virtual void unlockChildShapes() const + { + void * dummy = (void*)(m_box_set.getPrimitiveManager()); + TrimeshPrimitiveManager * dummymanager = static_cast(dummy); + dummymanager->unlock(); + } + + //! Gets the number of children + virtual int getNumChildShapes() const + { + return m_primitive_manager.get_primitive_count(); + } + + + //! Gets the children + virtual btCollisionShape* getChildShape(int index) + { + (void) index; + btAssert(0); + return NULL; + } + + + + //! Gets the child + virtual const btCollisionShape* getChildShape(int index) const + { + (void) index; + btAssert(0); + return NULL; + } + + //! Gets the children transform + virtual btTransform getChildTransform(int index) const + { + (void) index; + btAssert(0); + return btTransform(); + } + + //! Sets the children transform + /*! + \post You must call updateBound() for update the box set. + */ + virtual void setChildTransform(int index, const btTransform & transform) + { + (void) index; + (void) transform; + btAssert(0); + } + + + //! Obtains the primitive manager + virtual const btPrimitiveManagerBase * getPrimitiveManager() const + { + return &m_primitive_manager; + } + + SIMD_FORCE_INLINE TrimeshPrimitiveManager * getTrimeshPrimitiveManager() + { + return &m_primitive_manager; + } + + + + + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + + + + virtual const char* getName()const + { + return "GImpactMeshShapePart"; + } + + virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const + { + return CONST_GIMPACT_TRIMESH_SHAPE_PART; + } + + //! Determines if this shape has triangles + virtual bool needsRetrieveTriangles() const + { + return true; + } + + //! Determines if this shape has tetrahedrons + virtual bool needsRetrieveTetrahedrons() const + { + return false; + } + + virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const + { + m_primitive_manager.get_bullet_triangle(prim_index,triangle); + } + + virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const + { + (void) prim_index; + (void) tetrahedron; + btAssert(0); + } + + + + SIMD_FORCE_INLINE int getVertexCount() const + { + return m_primitive_manager.get_vertex_count(); + } + + SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 & vertex) const + { + m_primitive_manager.get_vertex(vertex_index,vertex); + } + + SIMD_FORCE_INLINE void setMargin(btScalar margin) + { + m_primitive_manager.m_margin = margin; + postUpdate(); + } + + SIMD_FORCE_INLINE btScalar getMargin() const + { + return m_primitive_manager.m_margin; + } + + virtual void setLocalScaling(const btVector3& scaling) + { + m_primitive_manager.m_scale = scaling; + postUpdate(); + } + + virtual const btVector3& getLocalScaling() const + { + return m_primitive_manager.m_scale; + } + + SIMD_FORCE_INLINE int getPart() const + { + return (int)m_primitive_manager.m_part; + } + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; +}; + + +//! This class manages a mesh supplied by the btStridingMeshInterface interface. +/*! +Set of btGImpactMeshShapePart parts +- Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh + +- You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices. + +*/ +class btGImpactMeshShape : public btGImpactShapeInterface +{ + btStridingMeshInterface* m_meshInterface; + +protected: + btAlignedObjectArray m_mesh_parts; + void buildMeshParts(btStridingMeshInterface * meshInterface) + { + for (int i=0;igetNumSubParts() ;++i ) + { + btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i); + m_mesh_parts.push_back(newpart); + } + } + + //! use this function for perfofm refit in bounding boxes + virtual void calcLocalAABB() + { + m_localAABB.invalidate(); + int i = m_mesh_parts.size(); + while(i--) + { + m_mesh_parts[i]->updateBound(); + m_localAABB.merge(m_mesh_parts[i]->getLocalBox()); + } + } + +public: + btGImpactMeshShape(btStridingMeshInterface * meshInterface) + { + m_meshInterface = meshInterface; + buildMeshParts(meshInterface); + } + + virtual ~btGImpactMeshShape() + { + int i = m_mesh_parts.size(); + while(i--) + { + btGImpactMeshShapePart * part = m_mesh_parts[i]; + delete part; + } + m_mesh_parts.clear(); + } + + + btStridingMeshInterface* getMeshInterface() + { + return m_meshInterface; + } + + const btStridingMeshInterface* getMeshInterface() const + { + return m_meshInterface; + } + + int getMeshPartCount() const + { + return m_mesh_parts.size(); + } + + btGImpactMeshShapePart * getMeshPart(int index) + { + return m_mesh_parts[index]; + } + + + + const btGImpactMeshShapePart * getMeshPart(int index) const + { + return m_mesh_parts[index]; + } + + + virtual void setLocalScaling(const btVector3& scaling) + { + localScaling = scaling; + + int i = m_mesh_parts.size(); + while(i--) + { + btGImpactMeshShapePart * part = m_mesh_parts[i]; + part->setLocalScaling(scaling); + } + + m_needs_update = true; + } + + virtual void setMargin(btScalar margin) + { + m_collisionMargin = margin; + + int i = m_mesh_parts.size(); + while(i--) + { + btGImpactMeshShapePart * part = m_mesh_parts[i]; + part->setMargin(margin); + } + + m_needs_update = true; + } + + //! Tells to this object that is needed to refit all the meshes + virtual void postUpdate() + { + int i = m_mesh_parts.size(); + while(i--) + { + btGImpactMeshShapePart * part = m_mesh_parts[i]; + part->postUpdate(); + } + + m_needs_update = true; + } + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + + //! Obtains the primitive manager + virtual const btPrimitiveManagerBase * getPrimitiveManager() const + { + btAssert(0); + return NULL; + } + + + //! Gets the number of children + virtual int getNumChildShapes() const + { + btAssert(0); + return 0; + } + + + //! if true, then its children must get transforms. + virtual bool childrenHasTransform() const + { + btAssert(0); + return false; + } + + //! Determines if this shape has triangles + virtual bool needsRetrieveTriangles() const + { + btAssert(0); + return false; + } + + //! Determines if this shape has tetrahedrons + virtual bool needsRetrieveTetrahedrons() const + { + btAssert(0); + return false; + } + + virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const + { + (void) prim_index; (void) triangle; + btAssert(0); + } + + virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const + { + (void) prim_index; (void) tetrahedron; + btAssert(0); + } + + //! call when reading child shapes + virtual void lockChildShapes() const + { + btAssert(0); + } + + virtual void unlockChildShapes() const + { + btAssert(0); + } + + + + + //! Retrieves the bound from a child + /*! + */ + virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + (void) child_index; (void) t; (void) aabbMin; (void) aabbMax; + btAssert(0); + } + + //! Gets the children + virtual btCollisionShape* getChildShape(int index) + { + (void) index; + btAssert(0); + return NULL; + } + + + //! Gets the child + virtual const btCollisionShape* getChildShape(int index) const + { + (void) index; + btAssert(0); + return NULL; + } + + //! Gets the children transform + virtual btTransform getChildTransform(int index) const + { + (void) index; + btAssert(0); + return btTransform(); + } + + //! Sets the children transform + /*! + \post You must call updateBound() for update the box set. + */ + virtual void setChildTransform(int index, const btTransform & transform) + { + (void) index; (void) transform; + btAssert(0); + } + + + virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const + { + return CONST_GIMPACT_TRIMESH_SHAPE; + } + + + virtual const char* getName()const + { + return "GImpactMesh"; + } + + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const; + + //! Function for retrieve triangles. + /*! + It gives the triangles in local space + */ + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btGImpactMeshShapeData +{ + btCollisionShapeData m_collisionShapeData; + + btStridingMeshInterfaceData m_meshInterface; + + btVector3FloatData m_localScaling; + + float m_collisionMargin; + + int m_gimpactSubType; +}; + +SIMD_FORCE_INLINE int btGImpactMeshShape::calculateSerializeBufferSize() const +{ + return sizeof(btGImpactMeshShapeData); +} + + +#endif //GIMPACT_MESH_SHAPE_H diff --git a/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp b/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp new file mode 100644 index 0000000..5d07d1a --- /dev/null +++ b/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp @@ -0,0 +1,283 @@ +/*! \file btGenericPoolAllocator.cpp +\author Francisco Leon Najera. email projectileman@yahoo.com + +General purpose allocator class +*/ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btGenericPoolAllocator.h" + + + +/// *************** btGenericMemoryPool ******************/////////// + +size_t btGenericMemoryPool::allocate_from_free_nodes(size_t num_elements) +{ + size_t ptr = BT_UINT_MAX; + + if(m_free_nodes_count == 0) return BT_UINT_MAX; + // find an avaliable free node with the correct size + size_t revindex = m_free_nodes_count; + + while(revindex-- && ptr == BT_UINT_MAX) + { + if(m_allocated_sizes[m_free_nodes[revindex]]>=num_elements) + { + ptr = revindex; + } + } + if(ptr == BT_UINT_MAX) return BT_UINT_MAX; // not found + + + revindex = ptr; + ptr = m_free_nodes[revindex]; + // post: ptr contains the node index, and revindex the index in m_free_nodes + + size_t finalsize = m_allocated_sizes[ptr]; + finalsize -= num_elements; + + m_allocated_sizes[ptr] = num_elements; + + // post: finalsize>=0, m_allocated_sizes[ptr] has the requested size + + if(finalsize>0) // preserve free node, there are some free memory + { + m_free_nodes[revindex] = ptr + num_elements; + m_allocated_sizes[ptr + num_elements] = finalsize; + } + else // delete free node + { + // swap with end + m_free_nodes[revindex] = m_free_nodes[m_free_nodes_count-1]; + m_free_nodes_count--; + } + + return ptr; +} + +size_t btGenericMemoryPool::allocate_from_pool(size_t num_elements) +{ + if(m_allocated_count+num_elements>m_max_element_count) return BT_UINT_MAX; + + size_t ptr = m_allocated_count; + + m_allocated_sizes[m_allocated_count] = num_elements; + m_allocated_count+=num_elements; + + return ptr; +} + + +void btGenericMemoryPool::init_pool(size_t element_size, size_t element_count) +{ + m_allocated_count = 0; + m_free_nodes_count = 0; + + m_element_size = element_size; + m_max_element_count = element_count; + + + + + m_pool = (unsigned char *) btAlignedAlloc(m_element_size*m_max_element_count,16); + m_free_nodes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16); + m_allocated_sizes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16); + + for (size_t i = 0;i< m_max_element_count;i++ ) + { + m_allocated_sizes[i] = 0; + } +} + +void btGenericMemoryPool::end_pool() +{ + btAlignedFree(m_pool); + btAlignedFree(m_free_nodes); + btAlignedFree(m_allocated_sizes); + m_allocated_count = 0; + m_free_nodes_count = 0; +} + + +//! Allocates memory in pool +/*! +\param size_bytes size in bytes of the buffer +*/ +void * btGenericMemoryPool::allocate(size_t size_bytes) +{ + + size_t module = size_bytes%m_element_size; + size_t element_count = size_bytes/m_element_size; + if(module>0) element_count++; + + size_t alloc_pos = allocate_from_free_nodes(element_count); + // a free node is found + if(alloc_pos != BT_UINT_MAX) + { + return get_element_data(alloc_pos); + } + // allocate directly on pool + alloc_pos = allocate_from_pool(element_count); + + if(alloc_pos == BT_UINT_MAX) return NULL; // not space + return get_element_data(alloc_pos); +} + +bool btGenericMemoryPool::freeMemory(void * pointer) +{ + unsigned char * pointer_pos = (unsigned char *)pointer; + unsigned char * pool_pos = (unsigned char *)m_pool; + // calc offset + if(pointer_pos=get_pool_capacity()) return false;// far away + + // find free position + m_free_nodes[m_free_nodes_count] = offset/m_element_size; + m_free_nodes_count++; + return true; +} + + +/// *******************! btGenericPoolAllocator *******************!/// + + +btGenericPoolAllocator::~btGenericPoolAllocator() +{ + // destroy pools + size_t i; + for (i=0;iend_pool(); + btAlignedFree(m_pools[i]); + } +} + + +// creates a pool +btGenericMemoryPool * btGenericPoolAllocator::push_new_pool() +{ + if(m_pool_count >= BT_DEFAULT_MAX_POOLS) return NULL; + + btGenericMemoryPool * newptr = (btGenericMemoryPool *)btAlignedAlloc(sizeof(btGenericMemoryPool),16); + + m_pools[m_pool_count] = newptr; + + m_pools[m_pool_count]->init_pool(m_pool_element_size,m_pool_element_count); + + m_pool_count++; + return newptr; +} + +void * btGenericPoolAllocator::failback_alloc(size_t size_bytes) +{ + + btGenericMemoryPool * pool = NULL; + + + if(size_bytes<=get_pool_capacity()) + { + pool = push_new_pool(); + } + + if(pool==NULL) // failback + { + return btAlignedAlloc(size_bytes,16); + } + + return pool->allocate(size_bytes); +} + +bool btGenericPoolAllocator::failback_free(void * pointer) +{ + btAlignedFree(pointer); + return true; +} + + +//! Allocates memory in pool +/*! +\param size_bytes size in bytes of the buffer +*/ +void * btGenericPoolAllocator::allocate(size_t size_bytes) +{ + void * ptr = NULL; + + size_t i = 0; + while(iallocate(size_bytes); + ++i; + } + + if(ptr) return ptr; + + return failback_alloc(size_bytes); +} + +bool btGenericPoolAllocator::freeMemory(void * pointer) +{ + bool result = false; + + size_t i = 0; + while(ifreeMemory(pointer); + ++i; + } + + if(result) return true; + + return failback_free(pointer); +} + +/// ************** STANDARD ALLOCATOR ***************************/// + + +#define BT_DEFAULT_POOL_SIZE 32768 +#define BT_DEFAULT_POOL_ELEMENT_SIZE 8 + +// main allocator +class GIM_STANDARD_ALLOCATOR: public btGenericPoolAllocator +{ +public: + GIM_STANDARD_ALLOCATOR():btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE,BT_DEFAULT_POOL_SIZE) + { + } +}; + +// global allocator +GIM_STANDARD_ALLOCATOR g_main_allocator; + + +void * btPoolAlloc(size_t size) +{ + return g_main_allocator.allocate(size); +} + +void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize) +{ + void * newptr = btPoolAlloc(newsize); + size_t copysize = oldsize +#include +#include +#include "LinearMath/btAlignedAllocator.h" + +#define BT_UINT_MAX UINT_MAX +#define BT_DEFAULT_MAX_POOLS 16 + + +//! Generic Pool class +class btGenericMemoryPool +{ +public: + unsigned char * m_pool; //[m_element_size*m_max_element_count]; + size_t * m_free_nodes; //[m_max_element_count];//! free nodes + size_t * m_allocated_sizes;//[m_max_element_count];//! Number of elements allocated per node + size_t m_allocated_count; + size_t m_free_nodes_count; +protected: + size_t m_element_size; + size_t m_max_element_count; + + size_t allocate_from_free_nodes(size_t num_elements); + size_t allocate_from_pool(size_t num_elements); + +public: + + void init_pool(size_t element_size, size_t element_count); + + void end_pool(); + + + btGenericMemoryPool(size_t element_size, size_t element_count) + { + init_pool(element_size, element_count); + } + + ~btGenericMemoryPool() + { + end_pool(); + } + + + inline size_t get_pool_capacity() + { + return m_element_size*m_max_element_count; + } + + inline size_t gem_element_size() + { + return m_element_size; + } + + inline size_t get_max_element_count() + { + return m_max_element_count; + } + + inline size_t get_allocated_count() + { + return m_allocated_count; + } + + inline size_t get_free_positions_count() + { + return m_free_nodes_count; + } + + inline void * get_element_data(size_t element_index) + { + return &m_pool[element_index*m_element_size]; + } + + //! Allocates memory in pool + /*! + \param size_bytes size in bytes of the buffer + */ + void * allocate(size_t size_bytes); + + bool freeMemory(void * pointer); +}; + + + + +//! Generic Allocator with pools +/*! +General purpose Allocator which can create Memory Pools dynamiacally as needed. +*/ +class btGenericPoolAllocator +{ +protected: + size_t m_pool_element_size; + size_t m_pool_element_count; +public: + btGenericMemoryPool * m_pools[BT_DEFAULT_MAX_POOLS]; + size_t m_pool_count; + + + inline size_t get_pool_capacity() + { + return m_pool_element_size*m_pool_element_count; + } + + +protected: + // creates a pool + btGenericMemoryPool * push_new_pool(); + + void * failback_alloc(size_t size_bytes); + + bool failback_free(void * pointer); +public: + + btGenericPoolAllocator(size_t pool_element_size, size_t pool_element_count) + { + m_pool_count = 0; + m_pool_element_size = pool_element_size; + m_pool_element_count = pool_element_count; + } + + virtual ~btGenericPoolAllocator(); + + //! Allocates memory in pool + /*! + \param size_bytes size in bytes of the buffer + */ + void * allocate(size_t size_bytes); + + bool freeMemory(void * pointer); +}; + + + +void * btPoolAlloc(size_t size); +void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize); +void btPoolFree(void *ptr); + + +#endif diff --git a/src/BulletCollision/Gimpact/btGeometryOperations.h b/src/BulletCollision/Gimpact/btGeometryOperations.h new file mode 100644 index 0000000..60f0651 --- /dev/null +++ b/src/BulletCollision/Gimpact/btGeometryOperations.h @@ -0,0 +1,212 @@ +#ifndef BT_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED +#define BT_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED + +/*! \file btGeometryOperations.h +*\author Francisco Leon Najera + +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBoxCollision.h" + + + + + +#define PLANEDIREPSILON 0.0000001f +#define PARALELENORMALS 0.000001f + + +#define BT_CLAMP(number,minval,maxval) (numbermaxval?maxval:number)) + +/// Calc a plane from a triangle edge an a normal. plane is a vec4f +SIMD_FORCE_INLINE void bt_edge_plane(const btVector3 & e1,const btVector3 & e2, const btVector3 & normal,btVector4 & plane) +{ + btVector3 planenormal = (e2-e1).cross(normal); + planenormal.normalize(); + plane.setValue(planenormal[0],planenormal[1],planenormal[2],e2.dot(planenormal)); +} + + + +//***************** SEGMENT and LINE FUNCTIONS **********************************/// + +/*! Finds the closest point(cp) to (v) on a segment (e1,e2) + */ +SIMD_FORCE_INLINE void bt_closest_point_on_segment( + btVector3 & cp, const btVector3 & v, + const btVector3 &e1,const btVector3 &e2) +{ + btVector3 n = e2-e1; + cp = v - e1; + btScalar _scalar = cp.dot(n)/n.dot(n); + if(_scalar <0.0f) + { + cp = e1; + } + else if(_scalar >1.0f) + { + cp = e2; + } + else + { + cp = _scalar*n + e1; + } +} + + +//! line plane collision +/*! +*\return + -0 if the ray never intersects + -1 if the ray collides in front + -2 if the ray collides in back +*/ + +SIMD_FORCE_INLINE int bt_line_plane_collision( + const btVector4 & plane, + const btVector3 & vDir, + const btVector3 & vPoint, + btVector3 & pout, + btScalar &tparam, + btScalar tmin, btScalar tmax) +{ + + btScalar _dotdir = vDir.dot(plane); + + if(btFabs(_dotdir)tmax) + { + returnvalue = 0; + tparam = tmax; + } + pout = tparam*vDir + vPoint; + return returnvalue; +} + + +//! Find closest points on segments +SIMD_FORCE_INLINE void bt_segment_collision( + const btVector3 & vA1, + const btVector3 & vA2, + const btVector3 & vB1, + const btVector3 & vB2, + btVector3 & vPointA, + btVector3 & vPointB) +{ + btVector3 AD = vA2 - vA1; + btVector3 BD = vB2 - vB1; + btVector3 N = AD.cross(BD); + btScalar tp = N.length2(); + + btVector4 _M;//plane + + if(tp_M[1]) + { + invert_b_order = true; + BT_SWAP_NUMBERS(_M[0],_M[1]); + } + _M[2] = vA1.dot(AD); + _M[3] = vA2.dot(AD); + //mid points + N[0] = (_M[0]+_M[1])*0.5f; + N[1] = (_M[2]+_M[3])*0.5f; + + if(N[0]=0.0f) + { + if (_dist>m_penetration_depth) + { + m_penetration_depth = _dist; + point_indices[0] = _k; + m_point_count=1; + } + else if ((_dist+SIMD_EPSILON)>=m_penetration_depth) + { + point_indices[m_point_count] = _k; + m_point_count++; + } + } + } + + for ( _k=0;_k0.0f&&dis1>0.0f&&dis2>0.0f) return false; + + // classify points on this triangle + dis0 = bt_distance_point_plane(other.m_plane,m_vertices[0]) - total_margin; + + dis1 = bt_distance_point_plane(other.m_plane,m_vertices[1]) - total_margin; + + dis2 = bt_distance_point_plane(other.m_plane,m_vertices[2]) - total_margin; + + if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false; + + return true; +} + +int btPrimitiveTriangle::clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points ) +{ + // edge 0 + + btVector3 temp_points[MAX_TRI_CLIPPING]; + + + btVector4 edgeplane; + + get_edge_plane(0,edgeplane); + + + int clipped_count = bt_plane_clip_triangle( + edgeplane,other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],temp_points); + + if (clipped_count == 0) return 0; + + btVector3 temp_points1[MAX_TRI_CLIPPING]; + + + // edge 1 + get_edge_plane(1,edgeplane); + + + clipped_count = bt_plane_clip_polygon(edgeplane,temp_points,clipped_count,temp_points1); + + if (clipped_count == 0) return 0; + + // edge 2 + get_edge_plane(2,edgeplane); + + clipped_count = bt_plane_clip_polygon( + edgeplane,temp_points1,clipped_count,clipped_points); + + return clipped_count; +} + +bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts) +{ + btScalar margin = m_margin + other.m_margin; + + btVector3 clipped_points[MAX_TRI_CLIPPING]; + int clipped_count; + //create planes + // plane v vs U points + + GIM_TRIANGLE_CONTACT contacts1; + + contacts1.m_separating_normal = m_plane; + + + clipped_count = clip_triangle(other,clipped_points); + + if (clipped_count == 0 ) + { + return false;//Reject + } + + //find most deep interval face1 + contacts1.merge_points(contacts1.m_separating_normal,margin,clipped_points,clipped_count); + if (contacts1.m_point_count == 0) return false; // too far + //Normal pointing to this triangle + contacts1.m_separating_normal *= -1.f; + + + //Clip tri1 by tri2 edges + GIM_TRIANGLE_CONTACT contacts2; + contacts2.m_separating_normal = other.m_plane; + + clipped_count = other.clip_triangle(*this,clipped_points); + + if (clipped_count == 0 ) + { + return false;//Reject + } + + //find most deep interval face1 + contacts2.merge_points(contacts2.m_separating_normal,margin,clipped_points,clipped_count); + if (contacts2.m_point_count == 0) return false; // too far + + + + + ////check most dir for contacts + if (contacts2.m_penetration_depth0.0f&&dis1>0.0f&&dis2>0.0f) return false; + + // classify points on this triangle + dis0 = bt_distance_point_plane(plane1,m_vertices1[0]) - total_margin; + + dis1 = bt_distance_point_plane(plane1,m_vertices1[1]) - total_margin; + + dis2 = bt_distance_point_plane(plane1,m_vertices1[2]) - total_margin; + + if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false; + + return true; +} + + diff --git a/src/BulletCollision/Gimpact/btTriangleShapeEx.h b/src/BulletCollision/Gimpact/btTriangleShapeEx.h new file mode 100644 index 0000000..973c2ed --- /dev/null +++ b/src/BulletCollision/Gimpact/btTriangleShapeEx.h @@ -0,0 +1,180 @@ +/*! \file btGImpactShape.h +\author Francisco Leon Najera +*/ +/* +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef GIMPACT_TRIANGLE_SHAPE_EX_H +#define GIMPACT_TRIANGLE_SHAPE_EX_H + +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "btBoxCollision.h" +#include "btClipPolygon.h" +#include "btGeometryOperations.h" + + +#define MAX_TRI_CLIPPING 16 + +//! Structure for collision +struct GIM_TRIANGLE_CONTACT +{ + btScalar m_penetration_depth; + int m_point_count; + btVector4 m_separating_normal; + btVector3 m_points[MAX_TRI_CLIPPING]; + + SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT& other) + { + m_penetration_depth = other.m_penetration_depth; + m_separating_normal = other.m_separating_normal; + m_point_count = other.m_point_count; + int i = m_point_count; + while(i--) + { + m_points[i] = other.m_points[i]; + } + } + + GIM_TRIANGLE_CONTACT() + { + } + + GIM_TRIANGLE_CONTACT(const GIM_TRIANGLE_CONTACT& other) + { + copy_from(other); + } + + //! classify points that are closer + void merge_points(const btVector4 & plane, + btScalar margin, const btVector3 * points, int point_count); + +}; + + + +class btPrimitiveTriangle +{ +public: + btVector3 m_vertices[3]; + btVector4 m_plane; + btScalar m_margin; + btScalar m_dummy; + btPrimitiveTriangle():m_margin(0.01f) + { + + } + + + SIMD_FORCE_INLINE void buildTriPlane() + { + btVector3 normal = (m_vertices[1]-m_vertices[0]).cross(m_vertices[2]-m_vertices[0]); + normal.normalize(); + m_plane.setValue(normal[0],normal[1],normal[2],m_vertices[0].dot(normal)); + } + + //! Test if triangles could collide + bool overlap_test_conservative(const btPrimitiveTriangle& other); + + //! Calcs the plane which is paralele to the edge and perpendicular to the triangle plane + /*! + \pre this triangle must have its plane calculated. + */ + SIMD_FORCE_INLINE void get_edge_plane(int edge_index, btVector4 &plane) const + { + const btVector3 & e0 = m_vertices[edge_index]; + const btVector3 & e1 = m_vertices[(edge_index+1)%3]; + bt_edge_plane(e0,e1,m_plane,plane); + } + + void applyTransform(const btTransform& t) + { + m_vertices[0] = t(m_vertices[0]); + m_vertices[1] = t(m_vertices[1]); + m_vertices[2] = t(m_vertices[2]); + } + + //! Clips the triangle against this + /*! + \pre clipped_points must have MAX_TRI_CLIPPING size, and this triangle must have its plane calculated. + \return the number of clipped points + */ + int clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points ); + + //! Find collision using the clipping method + /*! + \pre this triangle and other must have their triangles calculated + */ + bool find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts); +}; + + + +//! Helper class for colliding Bullet Triangle Shapes +/*! +This class implements a better getAabb method than the previous btTriangleShape class +*/ +class btTriangleShapeEx: public btTriangleShape +{ +public: + + btTriangleShapeEx():btTriangleShape(btVector3(0,0,0),btVector3(0,0,0),btVector3(0,0,0)) + { + } + + btTriangleShapeEx(const btVector3& p0,const btVector3& p1,const btVector3& p2): btTriangleShape(p0,p1,p2) + { + } + + btTriangleShapeEx(const btTriangleShapeEx & other): btTriangleShape(other.m_vertices1[0],other.m_vertices1[1],other.m_vertices1[2]) + { + } + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const + { + btVector3 tv0 = t(m_vertices1[0]); + btVector3 tv1 = t(m_vertices1[1]); + btVector3 tv2 = t(m_vertices1[2]); + + btAABB trianglebox(tv0,tv1,tv2,m_collisionMargin); + aabbMin = trianglebox.m_min; + aabbMax = trianglebox.m_max; + } + + void applyTransform(const btTransform& t) + { + m_vertices1[0] = t(m_vertices1[0]); + m_vertices1[1] = t(m_vertices1[1]); + m_vertices1[2] = t(m_vertices1[2]); + } + + SIMD_FORCE_INLINE void buildTriPlane(btVector4 & plane) const + { + btVector3 normal = (m_vertices1[1]-m_vertices1[0]).cross(m_vertices1[2]-m_vertices1[0]); + normal.normalize(); + plane.setValue(normal[0],normal[1],normal[2],m_vertices1[0].dot(normal)); + } + + bool overlap_test_conservative(const btTriangleShapeEx& other); +}; + + +#endif //GIMPACT_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/Gimpact/gim_array.h b/src/BulletCollision/Gimpact/gim_array.h new file mode 100644 index 0000000..27e6f32 --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_array.h @@ -0,0 +1,324 @@ +#ifndef GIM_ARRAY_H_INCLUDED +#define GIM_ARRAY_H_INCLUDED +/*! \file gim_array.h +\author Francisco Leon Najera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "gim_memory.h" + + +#define GIM_ARRAY_GROW_INCREMENT 2 +#define GIM_ARRAY_GROW_FACTOR 2 + +//! Very simple array container with fast access and simd memory +template +class gim_array +{ +public: +//! properties +//!@{ + T *m_data; + GUINT m_size; + GUINT m_allocated_size; +//!@} +//! protected operations +//!@{ + + inline void destroyData() + { + m_allocated_size = 0; + if(m_data==NULL) return; + gim_free(m_data); + m_data = NULL; + } + + inline bool resizeData(GUINT newsize) + { + if(newsize==0) + { + destroyData(); + return true; + } + + if(m_size>0) + { + m_data = (T*)gim_realloc(m_data,m_size*sizeof(T),newsize*sizeof(T)); + } + else + { + m_data = (T*)gim_alloc(newsize*sizeof(T)); + } + m_allocated_size = newsize; + return true; + } + + inline bool growingCheck() + { + if(m_allocated_size<=m_size) + { + GUINT requestsize = m_size; + m_size = m_allocated_size; + if(resizeData((requestsize+GIM_ARRAY_GROW_INCREMENT)*GIM_ARRAY_GROW_FACTOR)==false) return false; + } + return true; + } + +//!@} +//! public operations +//!@{ + inline bool reserve(GUINT size) + { + if(m_allocated_size>=size) return false; + return resizeData(size); + } + + inline void clear_range(GUINT start_range) + { + while(m_size>start_range) + { + m_data[--m_size].~T(); + } + } + + inline void clear() + { + if(m_size==0)return; + clear_range(0); + } + + inline void clear_memory() + { + clear(); + destroyData(); + } + + gim_array() + { + m_data = 0; + m_size = 0; + m_allocated_size = 0; + } + + gim_array(GUINT reservesize) + { + m_data = 0; + m_size = 0; + + m_allocated_size = 0; + reserve(reservesize); + } + + ~gim_array() + { + clear_memory(); + } + + inline GUINT size() const + { + return m_size; + } + + inline GUINT max_size() const + { + return m_allocated_size; + } + + inline T & operator[](size_t i) + { + return m_data[i]; + } + inline const T & operator[](size_t i) const + { + return m_data[i]; + } + + inline T * pointer(){ return m_data;} + inline const T * pointer() const + { return m_data;} + + + inline T * get_pointer_at(GUINT i) + { + return m_data + i; + } + + inline const T * get_pointer_at(GUINT i) const + { + return m_data + i; + } + + inline T & at(GUINT i) + { + return m_data[i]; + } + + inline const T & at(GUINT i) const + { + return m_data[i]; + } + + inline T & front() + { + return *m_data; + } + + inline const T & front() const + { + return *m_data; + } + + inline T & back() + { + return m_data[m_size-1]; + } + + inline const T & back() const + { + return m_data[m_size-1]; + } + + + inline void swap(GUINT i, GUINT j) + { + gim_swap_elements(m_data,i,j); + } + + inline void push_back(const T & obj) + { + this->growingCheck(); + m_data[m_size] = obj; + m_size++; + } + + //!Simply increase the m_size, doesn't call the new element constructor + inline void push_back_mem() + { + this->growingCheck(); + m_size++; + } + + inline void push_back_memcpy(const T & obj) + { + this->growingCheck(); + irr_simd_memcpy(&m_data[m_size],&obj,sizeof(T)); + m_size++; + } + + inline void pop_back() + { + m_size--; + m_data[m_size].~T(); + } + + //!Simply decrease the m_size, doesn't call the deleted element destructor + inline void pop_back_mem() + { + m_size--; + } + + //! fast erase + inline void erase(GUINT index) + { + if(indexgrowingCheck(); + for(GUINT i = m_size;i>index;i--) + { + gim_simd_memcpy(m_data+i,m_data+i-1,sizeof(T)); + } + m_size++; + } + + inline void insert(const T & obj,GUINT index) + { + insert_mem(index); + m_data[index] = obj; + } + + inline void resize(GUINT size, bool call_constructor = true, const T& fillData=T()) + { + if(size>m_size) + { + reserve(size); + if(call_constructor) + { + while(m_size +SIMD_FORCE_INLINE bool POINT_IN_HULL( + const CLASS_POINT& point,const CLASS_PLANE * planes,GUINT plane_count) +{ + GREAL _dis; + for (GUINT _i = 0;_i< plane_count;++_i) + { + _dis = DISTANCE_PLANE_POINT(planes[_i],point); + if(_dis>0.0f) return false; + } + return true; +} + +template +SIMD_FORCE_INLINE void PLANE_CLIP_SEGMENT( + const CLASS_POINT& s1, + const CLASS_POINT &s2,const CLASS_PLANE &plane,CLASS_POINT &clipped) +{ + GREAL _dis1,_dis2; + _dis1 = DISTANCE_PLANE_POINT(plane,s1); + VEC_DIFF(clipped,s2,s1); + _dis2 = VEC_DOT(clipped,plane); + VEC_SCALE(clipped,-_dis1/_dis2,clipped); + VEC_SUM(clipped,clipped,s1); +} + +enum ePLANE_INTERSECTION_TYPE +{ + G_BACK_PLANE = 0, + G_COLLIDE_PLANE, + G_FRONT_PLANE +}; + +enum eLINE_PLANE_INTERSECTION_TYPE +{ + G_FRONT_PLANE_S1 = 0, + G_FRONT_PLANE_S2, + G_BACK_PLANE_S1, + G_BACK_PLANE_S2, + G_COLLIDE_PLANE_S1, + G_COLLIDE_PLANE_S2 +}; + +//! Confirms if the plane intersect the edge or nor +/*! +intersection type must have the following values +
      +
    • 0 : Segment in front of plane, s1 closest +
    • 1 : Segment in front of plane, s2 closest +
    • 2 : Segment in back of plane, s1 closest +
    • 3 : Segment in back of plane, s2 closest +
    • 4 : Segment collides plane, s1 in back +
    • 5 : Segment collides plane, s2 in back +
    +*/ + +template +SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT2( + const CLASS_POINT& s1, + const CLASS_POINT &s2, + const CLASS_PLANE &plane,CLASS_POINT &clipped) +{ + GREAL _dis1 = DISTANCE_PLANE_POINT(plane,s1); + GREAL _dis2 = DISTANCE_PLANE_POINT(plane,s2); + if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON) + { + if(_dis1<_dis2) return G_FRONT_PLANE_S1; + return G_FRONT_PLANE_S2; + } + else if(_dis1 _dis2) return G_BACK_PLANE_S1; + return G_BACK_PLANE_S2; + } + + VEC_DIFF(clipped,s2,s1); + _dis2 = VEC_DOT(clipped,plane); + VEC_SCALE(clipped,-_dis1/_dis2,clipped); + VEC_SUM(clipped,clipped,s1); + if(_dis1<_dis2) return G_COLLIDE_PLANE_S1; + return G_COLLIDE_PLANE_S2; +} + +//! Confirms if the plane intersect the edge or not +/*! +clipped1 and clipped2 are the vertices behind the plane. +clipped1 is the closest + +intersection_type must have the following values +
      +
    • 0 : Segment in front of plane, s1 closest +
    • 1 : Segment in front of plane, s2 closest +
    • 2 : Segment in back of plane, s1 closest +
    • 3 : Segment in back of plane, s2 closest +
    • 4 : Segment collides plane, s1 in back +
    • 5 : Segment collides plane, s2 in back +
    +*/ +template +SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT_CLOSEST( + const CLASS_POINT& s1, + const CLASS_POINT &s2, + const CLASS_PLANE &plane, + CLASS_POINT &clipped1,CLASS_POINT &clipped2) +{ + eLINE_PLANE_INTERSECTION_TYPE intersection_type = PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1); + switch(intersection_type) + { + case G_FRONT_PLANE_S1: + VEC_COPY(clipped1,s1); + VEC_COPY(clipped2,s2); + break; + case G_FRONT_PLANE_S2: + VEC_COPY(clipped1,s2); + VEC_COPY(clipped2,s1); + break; + case G_BACK_PLANE_S1: + VEC_COPY(clipped1,s1); + VEC_COPY(clipped2,s2); + break; + case G_BACK_PLANE_S2: + VEC_COPY(clipped1,s2); + VEC_COPY(clipped2,s1); + break; + case G_COLLIDE_PLANE_S1: + VEC_COPY(clipped2,s1); + break; + case G_COLLIDE_PLANE_S2: + VEC_COPY(clipped2,s2); + break; + } + return intersection_type; +} + + +//! Finds the 2 smallest cartesian coordinates of a plane normal +#define PLANE_MINOR_AXES(plane, i0, i1) VEC_MINOR_AXES(plane, i0, i1) + +//! Ray plane collision in one way +/*! +Intersects plane in one way only. The ray must face the plane (normals must be in opossite directions).
    +It uses the PLANEDIREPSILON constant. +*/ +template +SIMD_FORCE_INLINE bool RAY_PLANE_COLLISION( + const CLASS_PLANE & plane, + const CLASS_POINT & vDir, + const CLASS_POINT & vPoint, + CLASS_POINT & pout,T &tparam) +{ + GREAL _dis,_dotdir; + _dotdir = VEC_DOT(plane,vDir); + if(_dotdir +SIMD_FORCE_INLINE GUINT LINE_PLANE_COLLISION( + const CLASS_PLANE & plane, + const CLASS_POINT & vDir, + const CLASS_POINT & vPoint, + CLASS_POINT & pout, + T &tparam, + T tmin, T tmax) +{ + GREAL _dis,_dotdir; + _dotdir = VEC_DOT(plane,vDir); + if(btFabs(_dotdir)tmax) + { + returnvalue = 0; + tparam = tmax; + } + + VEC_SCALE(pout,tparam,vDir); + VEC_SUM(pout,vPoint,pout); + return returnvalue; +} + +/*! \brief Returns the Ray on which 2 planes intersect if they do. + Written by Rodrigo Hernandez on ODE convex collision + + \param p1 Plane 1 + \param p2 Plane 2 + \param p Contains the origin of the ray upon returning if planes intersect + \param d Contains the direction of the ray upon returning if planes intersect + \return true if the planes intersect, 0 if paralell. + +*/ +template +SIMD_FORCE_INLINE bool INTERSECT_PLANES( + const CLASS_PLANE &p1, + const CLASS_PLANE &p2, + CLASS_POINT &p, + CLASS_POINT &d) +{ + VEC_CROSS(d,p1,p2); + GREAL denom = VEC_DOT(d, d); + if(GIM_IS_ZERO(denom)) return false; + vec3f _n; + _n[0]=p1[3]*p2[0] - p2[3]*p1[0]; + _n[1]=p1[3]*p2[1] - p2[3]*p1[1]; + _n[2]=p1[3]*p2[2] - p2[3]*p1[2]; + VEC_CROSS(p,_n,d); + p[0]/=denom; + p[1]/=denom; + p[2]/=denom; + return true; +} + +//***************** SEGMENT and LINE FUNCTIONS **********************************/// + +/*! Finds the closest point(cp) to (v) on a segment (e1,e2) + */ +template +SIMD_FORCE_INLINE void CLOSEST_POINT_ON_SEGMENT( + CLASS_POINT & cp, const CLASS_POINT & v, + const CLASS_POINT &e1,const CLASS_POINT &e2) +{ + vec3f _n; + VEC_DIFF(_n,e2,e1); + VEC_DIFF(cp,v,e1); + GREAL _scalar = VEC_DOT(cp, _n); + _scalar/= VEC_DOT(_n, _n); + if(_scalar <0.0f) + { + VEC_COPY(cp,e1); + } + else if(_scalar >1.0f) + { + VEC_COPY(cp,e2); + } + else + { + VEC_SCALE(cp,_scalar,_n); + VEC_SUM(cp,cp,e1); + } +} + + +/*! \brief Finds the line params where these lines intersect. + +\param dir1 Direction of line 1 +\param point1 Point of line 1 +\param dir2 Direction of line 2 +\param point2 Point of line 2 +\param t1 Result Parameter for line 1 +\param t2 Result Parameter for line 2 +\param dointersect 0 if the lines won't intersect, else 1 + +*/ +template +SIMD_FORCE_INLINE bool LINE_INTERSECTION_PARAMS( + const CLASS_POINT & dir1, + CLASS_POINT & point1, + const CLASS_POINT & dir2, + CLASS_POINT & point2, + T& t1,T& t2) +{ + GREAL det; + GREAL e1e1 = VEC_DOT(dir1,dir1); + GREAL e1e2 = VEC_DOT(dir1,dir2); + GREAL e2e2 = VEC_DOT(dir2,dir2); + vec3f p1p2; + VEC_DIFF(p1p2,point1,point2); + GREAL p1p2e1 = VEC_DOT(p1p2,dir1); + GREAL p1p2e2 = VEC_DOT(p1p2,dir2); + det = e1e2*e1e2 - e1e1*e2e2; + if(GIM_IS_ZERO(det)) return false; + t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det; + t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det; + return true; +} + +//! Find closest points on segments +template +SIMD_FORCE_INLINE void SEGMENT_COLLISION( + const CLASS_POINT & vA1, + const CLASS_POINT & vA2, + const CLASS_POINT & vB1, + const CLASS_POINT & vB2, + CLASS_POINT & vPointA, + CLASS_POINT & vPointB) +{ + CLASS_POINT _AD,_BD,_N; + vec4f _M;//plane + VEC_DIFF(_AD,vA2,vA1); + VEC_DIFF(_BD,vB2,vB1); + VEC_CROSS(_N,_AD,_BD); + GREAL _tp = VEC_DOT(_N,_N); + if(_tp_M[1]) + { + invert_b_order = true; + GIM_SWAP_NUMBERS(_M[0],_M[1]); + } + _M[2] = VEC_DOT(vA1,_AD); + _M[3] = VEC_DOT(vA2,_AD); + //mid points + _N[0] = (_M[0]+_M[1])*0.5f; + _N[1] = (_M[2]+_M[3])*0.5f; + + if(_N[0]<_N[1]) + { + if(_M[1]<_M[2]) + { + vPointB = invert_b_order?vB1:vB2; + vPointA = vA1; + } + else if(_M[1]<_M[3]) + { + vPointB = invert_b_order?vB1:vB2; + CLOSEST_POINT_ON_SEGMENT(vPointA,vPointB,vA1,vA2); + } + else + { + vPointA = vA2; + CLOSEST_POINT_ON_SEGMENT(vPointB,vPointA,vB1,vB2); + } + } + else + { + if(_M[3]<_M[0]) + { + vPointB = invert_b_order?vB2:vB1; + vPointA = vA2; + } + else if(_M[3]<_M[1]) + { + vPointA = vA2; + CLOSEST_POINT_ON_SEGMENT(vPointB,vPointA,vB1,vB2); + } + else + { + vPointB = invert_b_order?vB1:vB2; + CLOSEST_POINT_ON_SEGMENT(vPointA,vPointB,vA1,vA2); + } + } + return; + } + + + VEC_CROSS(_M,_N,_BD); + _M[3] = VEC_DOT(_M,vB1); + + LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,btScalar(0), btScalar(1)); + /*Closest point on segment*/ + VEC_DIFF(vPointB,vPointA,vB1); + _tp = VEC_DOT(vPointB, _BD); + _tp/= VEC_DOT(_BD, _BD); + _tp = GIM_CLAMP(_tp,0.0f,1.0f); + VEC_SCALE(vPointB,_tp,_BD); + VEC_SUM(vPointB,vPointB,vB1); +} + + + + +//! Line box intersection in one dimension +/*! + +*\param pos Position of the ray +*\param dir Projection of the Direction of the ray +*\param bmin Minimum bound of the box +*\param bmax Maximum bound of the box +*\param tfirst the minimum projection. Assign to 0 at first. +*\param tlast the maximum projection. Assign to INFINITY at first. +*\return true if there is an intersection. +*/ +template +SIMD_FORCE_INLINE bool BOX_AXIS_INTERSECT(T pos, T dir,T bmin, T bmax, T & tfirst, T & tlast) +{ + if(GIM_IS_ZERO(dir)) + { + return !(pos < bmin || pos > bmax); + } + GREAL a0 = (bmin - pos) / dir; + GREAL a1 = (bmax - pos) / dir; + if(a0 > a1) GIM_SWAP_NUMBERS(a0, a1); + tfirst = GIM_MAX(a0, tfirst); + tlast = GIM_MIN(a1, tlast); + if (tlast < tfirst) return false; + return true; +} + + +//! Sorts 3 componets +template +SIMD_FORCE_INLINE void SORT_3_INDICES( + const T * values, + GUINT * order_indices) +{ + //get minimum + order_indices[0] = values[0] < values[1] ? (values[0] < values[2] ? 0 : 2) : (values[1] < values[2] ? 1 : 2); + + //get second and third + GUINT i0 = (order_indices[0] + 1)%3; + GUINT i1 = (i0 + 1)%3; + + if(values[i0] < values[i1]) + { + order_indices[1] = i0; + order_indices[2] = i1; + } + else + { + order_indices[1] = i1; + order_indices[2] = i0; + } +} + + + + + +#endif // GIM_VECTOR_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_bitset.h b/src/BulletCollision/Gimpact/gim_bitset.h new file mode 100644 index 0000000..7dee48a --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_bitset.h @@ -0,0 +1,123 @@ +#ifndef GIM_BITSET_H_INCLUDED +#define GIM_BITSET_H_INCLUDED +/*! \file gim_bitset.h +\author Francisco Leon Najera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "gim_array.h" + + +#define GUINT_BIT_COUNT 32 +#define GUINT_EXPONENT 5 + +class gim_bitset +{ +public: + gim_array m_container; + + gim_bitset() + { + + } + + gim_bitset(GUINT bits_count) + { + resize(bits_count); + } + + ~gim_bitset() + { + } + + inline bool resize(GUINT newsize) + { + GUINT oldsize = m_container.size(); + m_container.resize(newsize/GUINT_BIT_COUNT + 1,false); + while(oldsize=size()) + { + resize(bit_index); + } + m_container[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1))); + } + + ///Return 0 or 1 + inline char get(GUINT bit_index) + { + if(bit_index>=size()) + { + return 0; + } + char value = m_container[bit_index >> GUINT_EXPONENT] & + (1 << (bit_index & (GUINT_BIT_COUNT-1))); + return value; + } + + inline void clear(GUINT bit_index) + { + m_container[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT-1))); + } +}; + + + + + +#endif // GIM_CONTAINERS_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_box_collision.h b/src/BulletCollision/Gimpact/gim_box_collision.h new file mode 100644 index 0000000..9c57263 --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_box_collision.h @@ -0,0 +1,588 @@ +#ifndef GIM_BOX_COLLISION_H_INCLUDED +#define GIM_BOX_COLLISION_H_INCLUDED + +/*! \file gim_box_collision.h +\author Francisco Leon Najera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ +#include "gim_basic_geometry_operations.h" +#include "LinearMath/btTransform.h" + + + +//SIMD_FORCE_INLINE bool test_cross_edge_box( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, const btVector3 & extend, +// int dir_index0, +// int dir_index1 +// int component_index0, +// int component_index1) +//{ +// // dir coords are -z and y +// +// const btScalar dir0 = -edge[dir_index0]; +// const btScalar dir1 = edge[dir_index1]; +// btScalar pmin = pointa[component_index0]*dir0 + pointa[component_index1]*dir1; +// btScalar pmax = pointb[component_index0]*dir0 + pointb[component_index1]*dir1; +// //find minmax +// if(pmin>pmax) +// { +// GIM_SWAP_NUMBERS(pmin,pmax); +// } +// //find extends +// const btScalar rad = extend[component_index0] * absolute_edge[dir_index0] + +// extend[component_index1] * absolute_edge[dir_index1]; +// +// if(pmin>rad || -rad>pmax) return false; +// return true; +//} +// +//SIMD_FORCE_INLINE bool test_cross_edge_box_X_axis( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, btVector3 & extend) +//{ +// +// return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,2,1,1,2); +//} +// +// +//SIMD_FORCE_INLINE bool test_cross_edge_box_Y_axis( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, btVector3 & extend) +//{ +// +// return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,0,2,2,0); +//} +// +//SIMD_FORCE_INLINE bool test_cross_edge_box_Z_axis( +// const btVector3 & edge, +// const btVector3 & absolute_edge, +// const btVector3 & pointa, +// const btVector3 & pointb, btVector3 & extend) +//{ +// +// return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1); +//} + +#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\ +{\ + const btScalar dir0 = -edge[i_dir_0];\ + const btScalar dir1 = edge[i_dir_1];\ + btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\ + btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\ + if(pmin>pmax)\ + {\ + GIM_SWAP_NUMBERS(pmin,pmax); \ + }\ + const btScalar abs_dir0 = absolute_edge[i_dir_0];\ + const btScalar abs_dir1 = absolute_edge[i_dir_1];\ + const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\ + if(pmin>rad || -rad>pmax) return false;\ +}\ + + +#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ +{\ + TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\ +}\ + +#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ +{\ + TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\ +}\ + +#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ +{\ + TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\ +}\ + + + +//! Class for transforming a model1 to the space of model0 +class GIM_BOX_BOX_TRANSFORM_CACHE +{ +public: + btVector3 m_T1to0;//!< Transforms translation of model1 to model 0 + btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1 + btMatrix3x3 m_AR;//!< Absolute value of m_R1to0 + + SIMD_FORCE_INLINE void calc_absolute_matrix() + { + static const btVector3 vepsi(1e-6f,1e-6f,1e-6f); + m_AR[0] = vepsi + m_R1to0[0].absolute(); + m_AR[1] = vepsi + m_R1to0[1].absolute(); + m_AR[2] = vepsi + m_R1to0[2].absolute(); + } + + GIM_BOX_BOX_TRANSFORM_CACHE() + { + } + + + GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0) + { + COPY_MATRIX_3X3(m_R1to0,trans1_to_0) + MAT_GET_TRANSLATION(trans1_to_0,m_T1to0) + calc_absolute_matrix(); + } + + //! Calc the transformation relative 1 to 0. Inverts matrics by transposing + SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1) + { + + m_R1to0 = trans0.getBasis().transpose(); + m_T1to0 = m_R1to0 * (-trans0.getOrigin()); + + m_T1to0 += m_R1to0*trans1.getOrigin(); + m_R1to0 *= trans1.getBasis(); + + calc_absolute_matrix(); + } + + //! Calcs the full invertion of the matrices. Useful for scaling matrices + SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1) + { + m_R1to0 = trans0.getBasis().inverse(); + m_T1to0 = m_R1to0 * (-trans0.getOrigin()); + + m_T1to0 += m_R1to0*trans1.getOrigin(); + m_R1to0 *= trans1.getBasis(); + + calc_absolute_matrix(); + } + + SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) + { + return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0; + } +}; + + +#define BOX_PLANE_EPSILON 0.000001f + +//! Axis aligned box +class GIM_AABB +{ +public: + btVector3 m_min; + btVector3 m_max; + + GIM_AABB() + {} + + + GIM_AABB(const btVector3 & V1, + const btVector3 & V2, + const btVector3 & V3) + { + m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); + } + + GIM_AABB(const btVector3 & V1, + const btVector3 & V2, + const btVector3 & V3, + GREAL margin) + { + m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); + + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + GIM_AABB(const GIM_AABB &other): + m_min(other.m_min),m_max(other.m_max) + { + } + + GIM_AABB(const GIM_AABB &other,btScalar margin ): + m_min(other.m_min),m_max(other.m_max) + { + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + SIMD_FORCE_INLINE void invalidate() + { + m_min[0] = G_REAL_INFINITY; + m_min[1] = G_REAL_INFINITY; + m_min[2] = G_REAL_INFINITY; + m_max[0] = -G_REAL_INFINITY; + m_max[1] = -G_REAL_INFINITY; + m_max[2] = -G_REAL_INFINITY; + } + + SIMD_FORCE_INLINE void increment_margin(btScalar margin) + { + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + SIMD_FORCE_INLINE void copy_with_margin(const GIM_AABB &other, btScalar margin) + { + m_min[0] = other.m_min[0] - margin; + m_min[1] = other.m_min[1] - margin; + m_min[2] = other.m_min[2] - margin; + + m_max[0] = other.m_max[0] + margin; + m_max[1] = other.m_max[1] + margin; + m_max[2] = other.m_max[2] + margin; + } + + template + SIMD_FORCE_INLINE void calc_from_triangle( + const CLASS_POINT & V1, + const CLASS_POINT & V2, + const CLASS_POINT & V3) + { + m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); + } + + template + SIMD_FORCE_INLINE void calc_from_triangle_margin( + const CLASS_POINT & V1, + const CLASS_POINT & V2, + const CLASS_POINT & V3, btScalar margin) + { + m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); + m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); + m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); + + m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); + m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); + m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); + + m_min[0] -= margin; + m_min[1] -= margin; + m_min[2] -= margin; + m_max[0] += margin; + m_max[1] += margin; + m_max[2] += margin; + } + + //! Apply a transform to an AABB + SIMD_FORCE_INLINE void appy_transform(const btTransform & trans) + { + btVector3 center = (m_max+m_min)*0.5f; + btVector3 extends = m_max - center; + // Compute new center + center = trans(center); + + btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(), + trans.getBasis().getRow(1).absolute(), + trans.getBasis().getRow(2).absolute()); + + m_min = center - textends; + m_max = center + textends; + } + + //! Merges a Box + SIMD_FORCE_INLINE void merge(const GIM_AABB & box) + { + m_min[0] = GIM_MIN(m_min[0],box.m_min[0]); + m_min[1] = GIM_MIN(m_min[1],box.m_min[1]); + m_min[2] = GIM_MIN(m_min[2],box.m_min[2]); + + m_max[0] = GIM_MAX(m_max[0],box.m_max[0]); + m_max[1] = GIM_MAX(m_max[1],box.m_max[1]); + m_max[2] = GIM_MAX(m_max[2],box.m_max[2]); + } + + //! Merges a point + template + SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point) + { + m_min[0] = GIM_MIN(m_min[0],point[0]); + m_min[1] = GIM_MIN(m_min[1],point[1]); + m_min[2] = GIM_MIN(m_min[2],point[2]); + + m_max[0] = GIM_MAX(m_max[0],point[0]); + m_max[1] = GIM_MAX(m_max[1],point[1]); + m_max[2] = GIM_MAX(m_max[2],point[2]); + } + + //! Gets the extend and center + SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend) const + { + center = (m_max+m_min)*0.5f; + extend = m_max - center; + } + + //! Finds the intersecting box between this box and the other. + SIMD_FORCE_INLINE void find_intersection(const GIM_AABB & other, GIM_AABB & intersection) const + { + intersection.m_min[0] = GIM_MAX(other.m_min[0],m_min[0]); + intersection.m_min[1] = GIM_MAX(other.m_min[1],m_min[1]); + intersection.m_min[2] = GIM_MAX(other.m_min[2],m_min[2]); + + intersection.m_max[0] = GIM_MIN(other.m_max[0],m_max[0]); + intersection.m_max[1] = GIM_MIN(other.m_max[1],m_max[1]); + intersection.m_max[2] = GIM_MIN(other.m_max[2],m_max[2]); + } + + + SIMD_FORCE_INLINE bool has_collision(const GIM_AABB & other) const + { + if(m_min[0] > other.m_max[0] || + m_max[0] < other.m_min[0] || + m_min[1] > other.m_max[1] || + m_max[1] < other.m_min[1] || + m_min[2] > other.m_max[2] || + m_max[2] < other.m_min[2]) + { + return false; + } + return true; + } + + /*! \brief Finds the Ray intersection parameter. + \param aabb Aligned box + \param vorigin A vec3f with the origin of the ray + \param vdir A vec3f with the direction of the ray + */ + SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir) + { + btVector3 extents,center; + this->get_center_extend(center,extents);; + + btScalar Dx = vorigin[0] - center[0]; + if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return false; + btScalar Dy = vorigin[1] - center[1]; + if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return false; + btScalar Dz = vorigin[2] - center[2]; + if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return false; + + + btScalar f = vdir[1] * Dz - vdir[2] * Dy; + if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false; + f = vdir[2] * Dx - vdir[0] * Dz; + if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false; + f = vdir[0] * Dy - vdir[1] * Dx; + if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false; + return true; + } + + + SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const + { + btVector3 center = (m_max+m_min)*0.5f; + btVector3 extend = m_max-center; + + btScalar _fOrigin = direction.dot(center); + btScalar _fMaximumExtent = extend.dot(direction.absolute()); + vmin = _fOrigin - _fMaximumExtent; + vmax = _fOrigin + _fMaximumExtent; + } + + SIMD_FORCE_INLINE ePLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const + { + btScalar _fmin,_fmax; + this->projection_interval(plane,_fmin,_fmax); + + if(plane[3] > _fmax + BOX_PLANE_EPSILON) + { + return G_BACK_PLANE; // 0 + } + + if(plane[3]+BOX_PLANE_EPSILON >=_fmin) + { + return G_COLLIDE_PLANE; //1 + } + return G_FRONT_PLANE;//2 + } + + SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB & box, btTransform & trans1_to_0) + { + GIM_AABB tbox = box; + tbox.appy_transform(trans1_to_0); + return has_collision(tbox); + } + + //! transcache is the transformation cache from box to this AABB + SIMD_FORCE_INLINE bool overlapping_trans_cache( + const GIM_AABB & box,const GIM_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) + { + + //Taken from OPCODE + btVector3 ea,eb;//extends + btVector3 ca,cb;//extends + get_center_extend(ca,ea); + box.get_center_extend(cb,eb); + + + btVector3 T; + btScalar t,t2; + int i; + + // Class I : A's basis vectors + for(i=0;i<3;i++) + { + T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; + t = transcache.m_AR[i].dot(eb) + ea[i]; + if(GIM_GREATER(T[i], t)) return false; + } + // Class II : B's basis vectors + for(i=0;i<3;i++) + { + t = MAT_DOT_COL(transcache.m_R1to0,T,i); + t2 = MAT_DOT_COL(transcache.m_AR,ea,i) + eb[i]; + if(GIM_GREATER(t,t2)) return false; + } + // Class III : 9 cross products + if(fulltest) + { + int j,m,n,o,p,q,r; + for(i=0;i<3;i++) + { + m = (i+1)%3; + n = (i+2)%3; + o = i==0?1:0; + p = i==2?1:2; + for(j=0;j<3;j++) + { + q = j==2?1:2; + r = j==0?1:0; + t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j]; + t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] + + eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r]; + if(GIM_GREATER(t,t2)) return false; + } + } + } + return true; + } + + //! Simple test for planes. + SIMD_FORCE_INLINE bool collide_plane( + const btVector4 & plane) + { + ePLANE_INTERSECTION_TYPE classify = plane_classify(plane); + return (classify == G_COLLIDE_PLANE); + } + + //! test for a triangle, with edges + SIMD_FORCE_INLINE bool collide_triangle_exact( + const btVector3 & p1, + const btVector3 & p2, + const btVector3 & p3, + const btVector4 & triangle_plane) + { + if(!collide_plane(triangle_plane)) return false; + + btVector3 center,extends; + this->get_center_extend(center,extends); + + const btVector3 v1(p1 - center); + const btVector3 v2(p2 - center); + const btVector3 v3(p3 - center); + + //First axis + btVector3 diff(v2 - v1); + btVector3 abs_diff = diff.absolute(); + //Test With X axis + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends); + //Test With Y axis + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends); + //Test With Z axis + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends); + + + diff = v3 - v2; + abs_diff = diff.absolute(); + //Test With X axis + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends); + //Test With Y axis + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends); + //Test With Z axis + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends); + + diff = v1 - v3; + abs_diff = diff.absolute(); + //Test With X axis + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends); + //Test With Y axis + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends); + //Test With Z axis + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends); + + return true; + } +}; + + +//! Compairison of transformation objects +SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2) +{ + if(!(t1.getOrigin() == t2.getOrigin()) ) return false; + + if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false; + if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false; + if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false; + return true; +} + + + +#endif // GIM_BOX_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_box_set.cpp b/src/BulletCollision/Gimpact/gim_box_set.cpp new file mode 100644 index 0000000..0c3d7ba --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_box_set.cpp @@ -0,0 +1,182 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "gim_box_set.h" + + +GUINT GIM_BOX_TREE::_calc_splitting_axis( + gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex) +{ + GUINT i; + + btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.)); + GUINT numIndices = endIndex-startIndex; + + for (i=startIndex;i & primitive_boxes, GUINT startIndex, + GUINT endIndex, GUINT splitAxis) +{ + GUINT i; + GUINT splitIndex =startIndex; + GUINT numIndices = endIndex - startIndex; + + // average of centers + btScalar splitValue = 0.0f; + for (i=startIndex;i splitValue) + { + //swap + primitive_boxes.swap(i,splitIndex); + splitIndex++; + } + } + + //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex + //otherwise the tree-building might fail due to stack-overflows in certain cases. + //unbalanced1 is unsafe: it can cause stack overflows + //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); + + //unbalanced2 should work too: always use center (perfect balanced trees) + //bool unbalanced2 = true; + + //this should be safe too: + GUINT rangeBalancedIndices = numIndices/3; + bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + + if (unbalanced) + { + splitIndex = startIndex+ (numIndices>>1); + } + + btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); + + return splitIndex; +} + + +void GIM_BOX_TREE::_build_sub_tree(gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex) +{ + GUINT current_index = m_num_nodes++; + + btAssert((endIndex-startIndex)>0); + + if((endIndex-startIndex) == 1) //we got a leaf + { + m_node_array[current_index].m_left = 0; + m_node_array[current_index].m_right = 0; + m_node_array[current_index].m_escapeIndex = 0; + + m_node_array[current_index].m_bound = primitive_boxes[startIndex].m_bound; + m_node_array[current_index].m_data = primitive_boxes[startIndex].m_data; + return; + } + + //configure inner node + + GUINT splitIndex; + + //calc this node bounding box + m_node_array[current_index].m_bound.invalidate(); + for (splitIndex=startIndex;splitIndex & primitive_boxes) +{ + // initialize node count to 0 + m_num_nodes = 0; + // allocate nodes + m_node_array.resize(primitive_boxes.size()*2); + + _build_sub_tree(primitive_boxes, 0, primitive_boxes.size()); +} + + diff --git a/src/BulletCollision/Gimpact/gim_box_set.h b/src/BulletCollision/Gimpact/gim_box_set.h new file mode 100644 index 0000000..61d190a --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_box_set.h @@ -0,0 +1,674 @@ +#ifndef GIM_BOX_SET_H_INCLUDED +#define GIM_BOX_SET_H_INCLUDED + +/*! \file gim_box_set.h +\author Francisco Leon Najera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "gim_array.h" +#include "gim_radixsort.h" +#include "gim_box_collision.h" +#include "gim_tri_collision.h" + + + +//! Overlapping pair +struct GIM_PAIR +{ + GUINT m_index1; + GUINT m_index2; + GIM_PAIR() + {} + + GIM_PAIR(const GIM_PAIR & p) + { + m_index1 = p.m_index1; + m_index2 = p.m_index2; + } + + GIM_PAIR(GUINT index1, GUINT index2) + { + m_index1 = index1; + m_index2 = index2; + } +}; + +//! A pairset array +class gim_pair_set: public gim_array +{ +public: + gim_pair_set():gim_array(32) + { + } + inline void push_pair(GUINT index1,GUINT index2) + { + push_back(GIM_PAIR(index1,index2)); + } + + inline void push_pair_inv(GUINT index1,GUINT index2) + { + push_back(GIM_PAIR(index2,index1)); + } +}; + + +//! Prototype Base class for primitive classification +/*! +This class is a wrapper for primitive collections. +This tells relevant info for the Bounding Box set classes, which take care of space classification. +This class can manage Compound shapes and trimeshes, and if it is managing trimesh then the Hierarchy Bounding Box classes will take advantage of primitive Vs Box overlapping tests for getting optimal results and less Per Box compairisons. +*/ +class GIM_PRIMITIVE_MANAGER_PROTOTYPE +{ +public: + + virtual ~GIM_PRIMITIVE_MANAGER_PROTOTYPE() {} + //! determines if this manager consist on only triangles, which special case will be optimized + virtual bool is_trimesh() = 0; + virtual GUINT get_primitive_count() = 0; + virtual void get_primitive_box(GUINT prim_index ,GIM_AABB & primbox) = 0; + virtual void get_primitive_triangle(GUINT prim_index,GIM_TRIANGLE & triangle) = 0; +}; + + +struct GIM_AABB_DATA +{ + GIM_AABB m_bound; + GUINT m_data; +}; + +//! Node Structure for trees +struct GIM_BOX_TREE_NODE +{ + GIM_AABB m_bound; + GUINT m_left;//!< Left subtree + GUINT m_right;//!< Right subtree + GUINT m_escapeIndex;//!< Scape index for traversing + GUINT m_data;//!< primitive index if apply + + GIM_BOX_TREE_NODE() + { + m_left = 0; + m_right = 0; + m_escapeIndex = 0; + m_data = 0; + } + + SIMD_FORCE_INLINE bool is_leaf_node() const + { + return (!m_left && !m_right); + } +}; + +//! Basic Box tree structure +class GIM_BOX_TREE +{ +protected: + GUINT m_num_nodes; + gim_array m_node_array; +protected: + GUINT _sort_and_calc_splitting_index( + gim_array & primitive_boxes, + GUINT startIndex, GUINT endIndex, GUINT splitAxis); + + GUINT _calc_splitting_axis(gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex); + + void _build_sub_tree(gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex); +public: + GIM_BOX_TREE() + { + m_num_nodes = 0; + } + + //! prototype functions for box tree management + //!@{ + void build_tree(gim_array & primitive_boxes); + + SIMD_FORCE_INLINE void clearNodes() + { + m_node_array.clear(); + m_num_nodes = 0; + } + + //! node count + SIMD_FORCE_INLINE GUINT getNodeCount() const + { + return m_num_nodes; + } + + //! tells if the node is a leaf + SIMD_FORCE_INLINE bool isLeafNode(GUINT nodeindex) const + { + return m_node_array[nodeindex].is_leaf_node(); + } + + SIMD_FORCE_INLINE GUINT getNodeData(GUINT nodeindex) const + { + return m_node_array[nodeindex].m_data; + } + + SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound) const + { + bound = m_node_array[nodeindex].m_bound; + } + + SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound) + { + m_node_array[nodeindex].m_bound = bound; + } + + SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex) const + { + return m_node_array[nodeindex].m_left; + } + + SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex) const + { + return m_node_array[nodeindex].m_right; + } + + SIMD_FORCE_INLINE GUINT getScapeNodeIndex(GUINT nodeindex) const + { + return m_node_array[nodeindex].m_escapeIndex; + } + + //!@} +}; + + +//! Generic Box Tree Template +/*! +This class offers an structure for managing a box tree of primitives. +Requires a Primitive prototype (like GIM_PRIMITIVE_MANAGER_PROTOTYPE ) and +a Box tree structure ( like GIM_BOX_TREE). +*/ +template +class GIM_BOX_TREE_TEMPLATE_SET +{ +protected: + _GIM_PRIMITIVE_MANAGER_PROTOTYPE m_primitive_manager; + _GIM_BOX_TREE_PROTOTYPE m_box_tree; +protected: + //stackless refit + SIMD_FORCE_INLINE void refit() + { + GUINT nodecount = getNodeCount(); + while(nodecount--) + { + if(isLeafNode(nodecount)) + { + GIM_AABB leafbox; + m_primitive_manager.get_primitive_box(getNodeData(nodecount),leafbox); + setNodeBound(nodecount,leafbox); + } + else + { + //get left bound + GUINT childindex = getLeftNodeIndex(nodecount); + GIM_AABB bound; + getNodeBound(childindex,bound); + //get right bound + childindex = getRightNodeIndex(nodecount); + GIM_AABB bound2; + getNodeBound(childindex,bound2); + bound.merge(bound2); + + setNodeBound(nodecount,bound); + } + } + } +public: + + GIM_BOX_TREE_TEMPLATE_SET() + { + } + + SIMD_FORCE_INLINE GIM_AABB getGlobalBox() const + { + GIM_AABB totalbox; + getNodeBound(0, totalbox); + return totalbox; + } + + SIMD_FORCE_INLINE void setPrimitiveManager(const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & primitive_manager) + { + m_primitive_manager = primitive_manager; + } + + const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager() const + { + return m_primitive_manager; + } + + _GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager() + { + return m_primitive_manager; + } + +//! node manager prototype functions +///@{ + + //! this attemps to refit the box set. + SIMD_FORCE_INLINE void update() + { + refit(); + } + + //! this rebuild the entire set + SIMD_FORCE_INLINE void buildSet() + { + //obtain primitive boxes + gim_array primitive_boxes; + primitive_boxes.resize(m_primitive_manager.get_primitive_count(),false); + + for (GUINT i = 0;i & collided_results) const + { + GUINT curIndex = 0; + GUINT numNodes = getNodeCount(); + + while (curIndex < numNodes) + { + GIM_AABB bound; + getNodeBound(curIndex,bound); + + //catch bugs in tree data + + bool aabbOverlap = bound.has_collision(box); + bool isleafnode = isLeafNode(curIndex); + + if (isleafnode && aabbOverlap) + { + collided_results.push_back(getNodeData(curIndex)); + } + + if (aabbOverlap || isleafnode) + { + //next subnode + curIndex++; + } + else + { + //skip node + curIndex+= getScapeNodeIndex(curIndex); + } + } + if(collided_results.size()>0) return true; + return false; + } + + //! returns the indices of the primitives in the m_primitive_manager + SIMD_FORCE_INLINE bool boxQueryTrans(const GIM_AABB & box, + const btTransform & transform, gim_array & collided_results) const + { + GIM_AABB transbox=box; + transbox.appy_transform(transform); + return boxQuery(transbox,collided_results); + } + + //! returns the indices of the primitives in the m_primitive_manager + SIMD_FORCE_INLINE bool rayQuery( + const btVector3 & ray_dir,const btVector3 & ray_origin , + gim_array & collided_results) const + { + GUINT curIndex = 0; + GUINT numNodes = getNodeCount(); + + while (curIndex < numNodes) + { + GIM_AABB bound; + getNodeBound(curIndex,bound); + + //catch bugs in tree data + + bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir); + bool isleafnode = isLeafNode(curIndex); + + if (isleafnode && aabbOverlap) + { + collided_results.push_back(getNodeData( curIndex)); + } + + if (aabbOverlap || isleafnode) + { + //next subnode + curIndex++; + } + else + { + //skip node + curIndex+= getScapeNodeIndex(curIndex); + } + } + if(collided_results.size()>0) return true; + return false; + } + + //! tells if this set has hierarcht + SIMD_FORCE_INLINE bool hasHierarchy() const + { + return true; + } + + //! tells if this set is a trimesh + SIMD_FORCE_INLINE bool isTrimesh() const + { + return m_primitive_manager.is_trimesh(); + } + + //! node count + SIMD_FORCE_INLINE GUINT getNodeCount() const + { + return m_box_tree.getNodeCount(); + } + + //! tells if the node is a leaf + SIMD_FORCE_INLINE bool isLeafNode(GUINT nodeindex) const + { + return m_box_tree.isLeafNode(nodeindex); + } + + SIMD_FORCE_INLINE GUINT getNodeData(GUINT nodeindex) const + { + return m_box_tree.getNodeData(nodeindex); + } + + SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound) const + { + m_box_tree.getNodeBound(nodeindex, bound); + } + + SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound) + { + m_box_tree.setNodeBound(nodeindex, bound); + } + + SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex) const + { + return m_box_tree.getLeftNodeIndex(nodeindex); + } + + SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex) const + { + return m_box_tree.getRightNodeIndex(nodeindex); + } + + SIMD_FORCE_INLINE GUINT getScapeNodeIndex(GUINT nodeindex) const + { + return m_box_tree.getScapeNodeIndex(nodeindex); + } + + SIMD_FORCE_INLINE void getNodeTriangle(GUINT nodeindex,GIM_TRIANGLE & triangle) const + { + m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex),triangle); + } + +}; + +//! Class for Box Tree Sets +/*! +this has the GIM_BOX_TREE implementation for bounding boxes. +*/ +template +class GIM_BOX_TREE_SET: public GIM_BOX_TREE_TEMPLATE_SET< _GIM_PRIMITIVE_MANAGER_PROTOTYPE, GIM_BOX_TREE> +{ +public: + +}; + + + + + +/// GIM_BOX_SET collision methods +template +class GIM_TREE_TREE_COLLIDER +{ +public: + gim_pair_set * m_collision_pairs; + BOX_SET_CLASS0 * m_boxset0; + BOX_SET_CLASS1 * m_boxset1; + GUINT current_node0; + GUINT current_node1; + bool node0_is_leaf; + bool node1_is_leaf; + bool t0_is_trimesh; + bool t1_is_trimesh; + bool node0_has_triangle; + bool node1_has_triangle; + GIM_AABB m_box0; + GIM_AABB m_box1; + GIM_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0; + btTransform trans_cache_0to1; + GIM_TRIANGLE m_tri0; + btVector4 m_tri0_plane; + GIM_TRIANGLE m_tri1; + btVector4 m_tri1_plane; + + +public: + GIM_TREE_TREE_COLLIDER() + { + current_node0 = G_UINT_INFINITY; + current_node1 = G_UINT_INFINITY; + } +protected: + SIMD_FORCE_INLINE void retrieve_node0_triangle(GUINT node0) + { + if(node0_has_triangle) return; + m_boxset0->getNodeTriangle(node0,m_tri0); + //transform triangle + m_tri0.m_vertices[0] = trans_cache_0to1(m_tri0.m_vertices[0]); + m_tri0.m_vertices[1] = trans_cache_0to1(m_tri0.m_vertices[1]); + m_tri0.m_vertices[2] = trans_cache_0to1(m_tri0.m_vertices[2]); + m_tri0.get_plane(m_tri0_plane); + + node0_has_triangle = true; + } + + SIMD_FORCE_INLINE void retrieve_node1_triangle(GUINT node1) + { + if(node1_has_triangle) return; + m_boxset1->getNodeTriangle(node1,m_tri1); + //transform triangle + m_tri1.m_vertices[0] = trans_cache_1to0.transform(m_tri1.m_vertices[0]); + m_tri1.m_vertices[1] = trans_cache_1to0.transform(m_tri1.m_vertices[1]); + m_tri1.m_vertices[2] = trans_cache_1to0.transform(m_tri1.m_vertices[2]); + m_tri1.get_plane(m_tri1_plane); + + node1_has_triangle = true; + } + + SIMD_FORCE_INLINE void retrieve_node0_info(GUINT node0) + { + if(node0 == current_node0) return; + m_boxset0->getNodeBound(node0,m_box0); + node0_is_leaf = m_boxset0->isLeafNode(node0); + node0_has_triangle = false; + current_node0 = node0; + } + + SIMD_FORCE_INLINE void retrieve_node1_info(GUINT node1) + { + if(node1 == current_node1) return; + m_boxset1->getNodeBound(node1,m_box1); + node1_is_leaf = m_boxset1->isLeafNode(node1); + node1_has_triangle = false; + current_node1 = node1; + } + + SIMD_FORCE_INLINE bool node_collision(GUINT node0 ,GUINT node1) + { + retrieve_node0_info(node0); + retrieve_node1_info(node1); + bool result = m_box0.overlapping_trans_cache(m_box1,trans_cache_1to0,true); + if(!result) return false; + + if(t0_is_trimesh && node0_is_leaf) + { + //perform primitive vs box collision + retrieve_node0_triangle(node0); + //do triangle vs box collision + m_box1.increment_margin(m_tri0.m_margin); + + result = m_box1.collide_triangle_exact( + m_tri0.m_vertices[0],m_tri0.m_vertices[1],m_tri0.m_vertices[2],m_tri0_plane); + + m_box1.increment_margin(-m_tri0.m_margin); + + if(!result) return false; + return true; + } + else if(t1_is_trimesh && node1_is_leaf) + { + //perform primitive vs box collision + retrieve_node1_triangle(node1); + //do triangle vs box collision + m_box0.increment_margin(m_tri1.m_margin); + + result = m_box0.collide_triangle_exact( + m_tri1.m_vertices[0],m_tri1.m_vertices[1],m_tri1.m_vertices[2],m_tri1_plane); + + m_box0.increment_margin(-m_tri1.m_margin); + + if(!result) return false; + return true; + } + return true; + } + + //stackless collision routine + void find_collision_pairs() + { + gim_pair_set stack_collisions; + stack_collisions.reserve(32); + + //add the first pair + stack_collisions.push_pair(0,0); + + + while(stack_collisions.size()) + { + //retrieve the last pair and pop + GUINT node0 = stack_collisions.back().m_index1; + GUINT node1 = stack_collisions.back().m_index2; + stack_collisions.pop_back(); + if(node_collision(node0,node1)) // a collision is found + { + if(node0_is_leaf) + { + if(node1_is_leaf) + { + m_collision_pairs->push_pair(m_boxset0->getNodeData(node0),m_boxset1->getNodeData(node1)); + } + else + { + //collide left + stack_collisions.push_pair(node0,m_boxset1->getLeftNodeIndex(node1)); + + //collide right + stack_collisions.push_pair(node0,m_boxset1->getRightNodeIndex(node1)); + } + } + else + { + if(node1_is_leaf) + { + //collide left + stack_collisions.push_pair(m_boxset0->getLeftNodeIndex(node0),node1); + //collide right + stack_collisions.push_pair(m_boxset0->getRightNodeIndex(node0),node1); + } + else + { + GUINT left0 = m_boxset0->getLeftNodeIndex(node0); + GUINT right0 = m_boxset0->getRightNodeIndex(node0); + GUINT left1 = m_boxset1->getLeftNodeIndex(node1); + GUINT right1 = m_boxset1->getRightNodeIndex(node1); + //collide left + stack_collisions.push_pair(left0,left1); + //collide right + stack_collisions.push_pair(left0,right1); + //collide left + stack_collisions.push_pair(right0,left1); + //collide right + stack_collisions.push_pair(right0,right1); + + }// else if node1 is not a leaf + }// else if node0 is not a leaf + + }// if(node_collision(node0,node1)) + }//while(stack_collisions.size()) + } +public: + void find_collision(BOX_SET_CLASS0 * boxset1, const btTransform & trans1, + BOX_SET_CLASS1 * boxset2, const btTransform & trans2, + gim_pair_set & collision_pairs, bool complete_primitive_tests = true) + { + m_collision_pairs = &collision_pairs; + m_boxset0 = boxset1; + m_boxset1 = boxset2; + + trans_cache_1to0.calc_from_homogenic(trans1,trans2); + + trans_cache_0to1 = trans2.inverse(); + trans_cache_0to1 *= trans1; + + + if(complete_primitive_tests) + { + t0_is_trimesh = boxset1->getPrimitiveManager().is_trimesh(); + t1_is_trimesh = boxset2->getPrimitiveManager().is_trimesh(); + } + else + { + t0_is_trimesh = false; + t1_is_trimesh = false; + } + + find_collision_pairs(); + } +}; + + +#endif // GIM_BOXPRUNING_H_INCLUDED + + diff --git a/src/BulletCollision/Gimpact/gim_clip_polygon.h b/src/BulletCollision/Gimpact/gim_clip_polygon.h new file mode 100644 index 0000000..e342459 --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_clip_polygon.h @@ -0,0 +1,210 @@ +#ifndef GIM_CLIP_POLYGON_H_INCLUDED +#define GIM_CLIP_POLYGON_H_INCLUDED + +/*! \file gim_tri_collision.h +\author Francisco Leon Najera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +//! This function calcs the distance from a 3D plane +class DISTANCE_PLANE_3D_FUNC +{ +public: + template + inline GREAL operator()(const CLASS_PLANE & plane, const CLASS_POINT & point) + { + return DISTANCE_PLANE_POINT(plane, point); + } +}; + + + +template +SIMD_FORCE_INLINE void PLANE_CLIP_POLYGON_COLLECT( + const CLASS_POINT & point0, + const CLASS_POINT & point1, + GREAL dist0, + GREAL dist1, + CLASS_POINT * clipped, + GUINT & clipped_count) +{ + GUINT _prevclassif = (dist0>G_EPSILON); + GUINT _classif = (dist1>G_EPSILON); + if(_classif!=_prevclassif) + { + GREAL blendfactor = -dist0/(dist1-dist0); + VEC_BLEND(clipped[clipped_count],point0,point1,blendfactor); + clipped_count++; + } + if(!_classif) + { + VEC_COPY(clipped[clipped_count],point1); + clipped_count++; + } +} + + +//! Clips a polygon by a plane +/*! +*\return The count of the clipped counts +*/ +template +SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON_GENERIC( + const CLASS_PLANE & plane, + const CLASS_POINT * polygon_points, + GUINT polygon_point_count, + CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func) +{ + GUINT clipped_count = 0; + + + //clip first point + GREAL firstdist = distance_func(plane,polygon_points[0]);; + if(!(firstdist>G_EPSILON)) + { + VEC_COPY(clipped[clipped_count],polygon_points[0]); + clipped_count++; + } + + GREAL olddist = firstdist; + for(GUINT _i=1;_i +SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE_GENERIC( + const CLASS_PLANE & plane, + const CLASS_POINT & point0, + const CLASS_POINT & point1, + const CLASS_POINT & point2, + CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func) +{ + GUINT clipped_count = 0; + + //clip first point + GREAL firstdist = distance_func(plane,point0);; + if(!(firstdist>G_EPSILON)) + { + VEC_COPY(clipped[clipped_count],point0); + clipped_count++; + } + + // point 1 + GREAL olddist = firstdist; + GREAL dist = distance_func(plane,point1); + + PLANE_CLIP_POLYGON_COLLECT( + point0,point1, + olddist, + dist, + clipped, + clipped_count); + + olddist = dist; + + + // point 2 + dist = distance_func(plane,point2); + + PLANE_CLIP_POLYGON_COLLECT( + point1,point2, + olddist, + dist, + clipped, + clipped_count); + olddist = dist; + + + + //RETURN TO FIRST point + PLANE_CLIP_POLYGON_COLLECT( + point2,point0, + olddist, + firstdist, + clipped, + clipped_count); + + return clipped_count; +} + + +template +SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON3D( + const CLASS_PLANE & plane, + const CLASS_POINT * polygon_points, + GUINT polygon_point_count, + CLASS_POINT * clipped) +{ + return PLANE_CLIP_POLYGON_GENERIC(plane,polygon_points,polygon_point_count,clipped,DISTANCE_PLANE_3D_FUNC()); +} + + +template +SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE3D( + const CLASS_PLANE & plane, + const CLASS_POINT & point0, + const CLASS_POINT & point1, + const CLASS_POINT & point2, + CLASS_POINT * clipped) +{ + return PLANE_CLIP_TRIANGLE_GENERIC(plane,point0,point1,point2,clipped,DISTANCE_PLANE_3D_FUNC()); +} + + + +#endif // GIM_TRI_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_contact.cpp b/src/BulletCollision/Gimpact/gim_contact.cpp new file mode 100644 index 0000000..20e41de --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_contact.cpp @@ -0,0 +1,146 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "gim_contact.h" + +#define MAX_COINCIDENT 8 + +void gim_contact_array::merge_contacts( + const gim_contact_array & contacts, bool normal_contact_average) +{ + clear(); + + if(contacts.size()==1) + { + push_back(contacts.back()); + return; + } + + gim_array keycontacts(contacts.size()); + keycontacts.resize(contacts.size(),false); + + //fill key contacts + + GUINT i; + + for (i = 0;im_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//) + { + *pcontact = *scontact; + coincident_count = 0; + } + else if(normal_contact_average) + { + if(btFabs(pcontact->m_depth - scontact->m_depth)m_normal; + coincident_count++; + } + } + } + } + else + {//add new contact + + if(normal_contact_average && coincident_count>0) + { + pcontact->interpolate_normals(coincident_normals,coincident_count); + coincident_count = 0; + } + + push_back(*scontact); + pcontact = &back(); + } + last_key = key; + } +} + +void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts) +{ + clear(); + + if(contacts.size()==1) + { + push_back(contacts.back()); + return; + } + + GIM_CONTACT average_contact = contacts.back(); + + for (GUINT i=1;i +{ +public: + gim_contact_array():gim_array(64) + { + } + + SIMD_FORCE_INLINE void push_contact(const btVector3 &point,const btVector3 & normal, + GREAL depth, GUINT feature1, GUINT feature2) + { + push_back_mem(); + GIM_CONTACT & newele = back(); + newele.m_point = point; + newele.m_normal = normal; + newele.m_depth = depth; + newele.m_feature1 = feature1; + newele.m_feature2 = feature2; + } + + SIMD_FORCE_INLINE void push_triangle_contacts( + const GIM_TRIANGLE_CONTACT_DATA & tricontact, + GUINT feature1,GUINT feature2) + { + for(GUINT i = 0;i +struct GIM_HASH_TABLE_NODE +{ + GUINT m_key; + T m_data; + GIM_HASH_TABLE_NODE() + { + } + + GIM_HASH_TABLE_NODE(const GIM_HASH_TABLE_NODE & value) + { + m_key = value.m_key; + m_data = value.m_data; + } + + GIM_HASH_TABLE_NODE(GUINT key, const T & data) + { + m_key = key; + m_data = data; + } + + bool operator <(const GIM_HASH_TABLE_NODE & other) const + { + ///inverse order, further objects are first + if(m_key < other.m_key) return true; + return false; + } + + bool operator >(const GIM_HASH_TABLE_NODE & other) const + { + ///inverse order, further objects are first + if(m_key > other.m_key) return true; + return false; + } + + bool operator ==(const GIM_HASH_TABLE_NODE & other) const + { + ///inverse order, further objects are first + if(m_key == other.m_key) return true; + return false; + } +}; + +///Macro for getting the key +class GIM_HASH_NODE_GET_KEY +{ +public: + template + inline GUINT operator()( const T& a) + { + return a.m_key; + } +}; + + + +///Macro for comparing the key and the element +class GIM_HASH_NODE_CMP_KEY_MACRO +{ +public: + template + inline int operator() ( const T& a, GUINT key) + { + return ((int)(a.m_key - key)); + } +}; + +///Macro for comparing Hash nodes +class GIM_HASH_NODE_CMP_MACRO +{ +public: + template + inline int operator() ( const T& a, const T& b ) + { + return ((int)(a.m_key - b.m_key)); + } +}; + + + + + +//! Sorting for hash table +/*! +switch automatically between quicksort and radixsort +*/ +template +void gim_sort_hash_node_array(T * array, GUINT array_count) +{ + if(array_count + +
      +
    • if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes. +When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable. +
    • If node_size != 0, then this container becomes a hash table for ever +
    + +*/ +template +class gim_hash_table +{ +protected: + typedef GIM_HASH_TABLE_NODE _node_type; + + //!The nodes + //array< _node_type, SuperAllocator<_node_type> > m_nodes; + gim_array< _node_type > m_nodes; + //SuperBufferedArray< _node_type > m_nodes; + bool m_sorted; + + ///Hash table data management. The hash table has the indices to the corresponding m_nodes array + GUINT * m_hash_table;//!< + GUINT m_table_size;//!< + GUINT m_node_size;//!< + GUINT m_min_hash_table_size; + + + + //! Returns the cell index + inline GUINT _find_cell(GUINT hashkey) + { + _node_type * nodesptr = m_nodes.pointer(); + GUINT start_index = (hashkey%m_table_size)*m_node_size; + GUINT end_index = start_index + m_node_size; + + while(start_index= m_nodes.size()) return false; + if(m_nodes[index].m_key != GIM_INVALID_HASH) + { + //Search for the avaliable cell in buffer + GUINT cell_index = _find_cell(m_nodes[index].m_key); + + btAssert(cell_index!=GIM_INVALID_HASH); + btAssert(m_hash_table[cell_index]==index); + + m_hash_table[cell_index] = GIM_INVALID_HASH; + } + + return this->_erase_unsorted(index); + } + + //! erase by key in hash table + inline bool _erase_hash_table(GUINT hashkey) + { + if(hashkey == GIM_INVALID_HASH) return false; + + //Search for the avaliable cell in buffer + GUINT cell_index = _find_cell(hashkey); + if(cell_index ==GIM_INVALID_HASH) return false; + + GUINT index = m_hash_table[cell_index]; + m_hash_table[cell_index] = GIM_INVALID_HASH; + + return this->_erase_unsorted(index); + } + + + + //! insert an element in hash table + /*! + If the element exists, this won't insert the element + \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted + If so, the element has been inserted at the last position of the array. + */ + inline GUINT _insert_hash_table(GUINT hashkey, const T & value) + { + if(hashkey==GIM_INVALID_HASH) + { + //Insert anyway + _insert_unsorted(hashkey,value); + return GIM_INVALID_HASH; + } + + GUINT cell_index = _assign_hash_table_cell(hashkey); + + GUINT value_key = m_hash_table[cell_index]; + + if(value_key!= GIM_INVALID_HASH) return value_key;// Not overrited + + m_hash_table[cell_index] = m_nodes.size(); + + _insert_unsorted(hashkey,value); + return GIM_INVALID_HASH; + } + + //! insert an element in hash table. + /*! + If the element exists, this replaces the element. + \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted + If so, the element has been inserted at the last position of the array. + */ + inline GUINT _insert_hash_table_replace(GUINT hashkey, const T & value) + { + if(hashkey==GIM_INVALID_HASH) + { + //Insert anyway + _insert_unsorted(hashkey,value); + return GIM_INVALID_HASH; + } + + GUINT cell_index = _assign_hash_table_cell(hashkey); + + GUINT value_key = m_hash_table[cell_index]; + + if(value_key!= GIM_INVALID_HASH) + {//replaces the existing + m_nodes[value_key] = _node_type(hashkey,value); + return value_key;// index of the replaced element + } + + m_hash_table[cell_index] = m_nodes.size(); + + _insert_unsorted(hashkey,value); + return GIM_INVALID_HASH; + + } + + + ///Sorted array data management. The hash table has the indices to the corresponding m_nodes array + inline bool _erase_sorted(GUINT index) + { + if(index>=(GUINT)m_nodes.size()) return false; + m_nodes.erase_sorted(index); + if(m_nodes.size()<2) m_sorted = false; + return true; + } + + //! faster, but unsorted + inline bool _erase_unsorted(GUINT index) + { + if(index>=m_nodes.size()) return false; + + GUINT lastindex = m_nodes.size()-1; + if(indexcheck_for_switching_to_hashtable(); + } + + //! Insert an element in an ordered array + inline GUINT _insert_sorted(GUINT hashkey, const T & value) + { + if(hashkey==GIM_INVALID_HASH || size()==0) + { + m_nodes.push_back(_node_type(hashkey,value)); + return GIM_INVALID_HASH; + } + //Insert at last position + //Sort element + + + GUINT result_ind=0; + GUINT last_index = m_nodes.size()-1; + _node_type * ptr = m_nodes.pointer(); + + bool found = gim_binary_search_ex( + ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO()); + + + //Insert before found index + if(found) + { + return result_ind; + } + else + { + _insert_in_pos(hashkey, value, result_ind); + } + return GIM_INVALID_HASH; + } + + inline GUINT _insert_sorted_replace(GUINT hashkey, const T & value) + { + if(hashkey==GIM_INVALID_HASH || size()==0) + { + m_nodes.push_back(_node_type(hashkey,value)); + return GIM_INVALID_HASH; + } + //Insert at last position + //Sort element + GUINT result_ind; + GUINT last_index = m_nodes.size()-1; + _node_type * ptr = m_nodes.pointer(); + + bool found = gim_binary_search_ex( + ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO()); + + //Insert before found index + if(found) + { + m_nodes[result_ind] = _node_type(hashkey,value); + } + else + { + _insert_in_pos(hashkey, value, result_ind); + } + return result_ind; + } + + //! Fast insertion in m_nodes array + inline GUINT _insert_unsorted(GUINT hashkey, const T & value) + { + m_nodes.push_back(_node_type(hashkey,value)); + m_sorted = false; + return GIM_INVALID_HASH; + } + + + +public: + + /*! +
  4. if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes. + When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable. +
  5. If node_size != 0, then this container becomes a hash table for ever + + */ + gim_hash_table(GUINT reserve_size = GIM_DEFAULT_HASH_TABLE_SIZE, + GUINT node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE, + GUINT min_hash_table_size = GIM_INVALID_HASH) + { + m_hash_table = NULL; + m_table_size = 0; + m_sorted = false; + m_node_size = node_size; + m_min_hash_table_size = min_hash_table_size; + + if(m_node_size!=0) + { + if(reserve_size!=0) + { + m_nodes.reserve(reserve_size); + _reserve_table_memory(reserve_size); + _invalidate_keys(); + } + else + { + m_nodes.reserve(GIM_DEFAULT_HASH_TABLE_SIZE); + _reserve_table_memory(GIM_DEFAULT_HASH_TABLE_SIZE); + _invalidate_keys(); + } + } + else if(reserve_size!=0) + { + m_nodes.reserve(reserve_size); + } + + } + + ~gim_hash_table() + { + _destroy(); + } + + inline bool is_hash_table() + { + if(m_hash_table) return true; + return false; + } + + inline bool is_sorted() + { + if(size()<2) return true; + return m_sorted; + } + + bool sort() + { + if(is_sorted()) return true; + if(m_nodes.size()<2) return false; + + + _node_type * ptr = m_nodes.pointer(); + GUINT siz = m_nodes.size(); + gim_sort_hash_node_array(ptr,siz); + m_sorted=true; + + + + if(m_hash_table) + { + _rehash(); + } + return true; + } + + bool switch_to_hashtable() + { + if(m_hash_table) return false; + if(m_node_size==0) m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE; + if(m_nodes.size()m_hash_table) return true; + + if(!(m_nodes.size()< m_min_hash_table_size)) + { + if(m_node_size == 0) + { + m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE; + } + + _resize_table(m_nodes.size()+1); + return true; + } + return false; + } + + inline void set_sorted(bool value) + { + m_sorted = value; + } + + //! Retrieves the amount of keys. + inline GUINT size() const + { + return m_nodes.size(); + } + + //! Retrieves the hash key. + inline GUINT get_key(GUINT index) const + { + return m_nodes[index].m_key; + } + + //! Retrieves the value by index + /*! + */ + inline T * get_value_by_index(GUINT index) + { + return &m_nodes[index].m_data; + } + + inline const T& operator[](GUINT index) const + { + return m_nodes[index].m_data; + } + + inline T& operator[](GUINT index) + { + return m_nodes[index].m_data; + } + + //! Finds the index of the element with the key + /*! + \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted + If so, the element has been inserted at the last position of the array. + */ + inline GUINT find(GUINT hashkey) + { + if(m_hash_table) + { + GUINT cell_index = _find_cell(hashkey); + if(cell_index==GIM_INVALID_HASH) return GIM_INVALID_HASH; + return m_hash_table[cell_index]; + } + GUINT last_index = m_nodes.size(); + if(last_index<2) + { + if(last_index==0) return GIM_INVALID_HASH; + if(m_nodes[0].m_key == hashkey) return 0; + return GIM_INVALID_HASH; + } + else if(m_sorted) + { + //Binary search + GUINT result_ind = 0; + last_index--; + _node_type * ptr = m_nodes.pointer(); + + bool found = gim_binary_search_ex(ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO()); + + + if(found) return result_ind; + } + return GIM_INVALID_HASH; + } + + //! Retrieves the value associated with the index + /*! + \return the found element, or null + */ + inline T * get_value(GUINT hashkey) + { + GUINT index = find(hashkey); + if(index == GIM_INVALID_HASH) return NULL; + return &m_nodes[index].m_data; + } + + + /*! + */ + inline bool erase_by_index(GUINT index) + { + if(index > m_nodes.size()) return false; + + if(m_hash_table == NULL) + { + if(is_sorted()) + { + return this->_erase_sorted(index); + } + else + { + return this->_erase_unsorted(index); + } + } + else + { + return this->_erase_by_index_hash_table(index); + } + return false; + } + + + + inline bool erase_by_index_unsorted(GUINT index) + { + if(index > m_nodes.size()) return false; + + if(m_hash_table == NULL) + { + return this->_erase_unsorted(index); + } + else + { + return this->_erase_by_index_hash_table(index); + } + return false; + } + + + + /*! + + */ + inline bool erase_by_key(GUINT hashkey) + { + if(size()==0) return false; + + if(m_hash_table) + { + return this->_erase_hash_table(hashkey); + } + //Binary search + + if(is_sorted()==false) return false; + + GUINT result_ind = find(hashkey); + if(result_ind!= GIM_INVALID_HASH) + { + return this->_erase_sorted(result_ind); + } + return false; + } + + void clear() + { + m_nodes.clear(); + + if(m_hash_table==NULL) return; + GUINT datasize = m_table_size*m_node_size; + //Initialize the hashkeys. + GUINT i; + for(i=0;i_insert_hash_table(hashkey,element); + } + if(this->is_sorted()) + { + return this->_insert_sorted(hashkey,element); + } + return this->_insert_unsorted(hashkey,element); + } + + //! Insert an element into the hash, and could overrite an existing object with the same hash. + /*! + \return If GIM_INVALID_HASH, the object has been inserted succesfully. Else it returns the position + of the replaced element. + */ + inline GUINT insert_override(GUINT hashkey, const T & element) + { + if(m_hash_table) + { + return this->_insert_hash_table_replace(hashkey,element); + } + if(this->is_sorted()) + { + return this->_insert_sorted_replace(hashkey,element); + } + this->_insert_unsorted(hashkey,element); + return m_nodes.size(); + } + + + + //! Insert an element into the hash,But if this container is a sorted array, this inserts it unsorted + /*! + */ + inline GUINT insert_unsorted(GUINT hashkey,const T & element) + { + if(m_hash_table) + { + return this->_insert_hash_table(hashkey,element); + } + return this->_insert_unsorted(hashkey,element); + } + + +}; + + + +#endif // GIM_CONTAINERS_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_linear_math.h b/src/BulletCollision/Gimpact/gim_linear_math.h new file mode 100644 index 0000000..64f11b4 --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_linear_math.h @@ -0,0 +1,1573 @@ +#ifndef GIM_LINEAR_H_INCLUDED +#define GIM_LINEAR_H_INCLUDED + +/*! \file gim_linear_math.h +*\author Francisco Leon Najera +Type Independant Vector and matrix operations. +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "gim_math.h" +#include "gim_geom_types.h" + + + + +//! Zero out a 2D vector +#define VEC_ZERO_2(a) \ +{ \ + (a)[0] = (a)[1] = 0.0f; \ +}\ + + +//! Zero out a 3D vector +#define VEC_ZERO(a) \ +{ \ + (a)[0] = (a)[1] = (a)[2] = 0.0f; \ +}\ + + +/// Zero out a 4D vector +#define VEC_ZERO_4(a) \ +{ \ + (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \ +}\ + + +/// Vector copy +#define VEC_COPY_2(b,a) \ +{ \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ +}\ + + +/// Copy 3D vector +#define VEC_COPY(b,a) \ +{ \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + (b)[2] = (a)[2]; \ +}\ + + +/// Copy 4D vector +#define VEC_COPY_4(b,a) \ +{ \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + (b)[2] = (a)[2]; \ + (b)[3] = (a)[3]; \ +}\ + +/// VECTOR SWAP +#define VEC_SWAP(b,a) \ +{ \ + GIM_SWAP_NUMBERS((b)[0],(a)[0]);\ + GIM_SWAP_NUMBERS((b)[1],(a)[1]);\ + GIM_SWAP_NUMBERS((b)[2],(a)[2]);\ +}\ + +/// Vector difference +#define VEC_DIFF_2(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ +}\ + + +/// Vector difference +#define VEC_DIFF(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ + (v21)[2] = (v2)[2] - (v1)[2]; \ +}\ + + +/// Vector difference +#define VEC_DIFF_4(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ + (v21)[2] = (v2)[2] - (v1)[2]; \ + (v21)[3] = (v2)[3] - (v1)[3]; \ +}\ + + +/// Vector sum +#define VEC_SUM_2(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ +}\ + + +/// Vector sum +#define VEC_SUM(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ + (v21)[2] = (v2)[2] + (v1)[2]; \ +}\ + + +/// Vector sum +#define VEC_SUM_4(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ + (v21)[2] = (v2)[2] + (v1)[2]; \ + (v21)[3] = (v2)[3] + (v1)[3]; \ +}\ + + +/// scalar times vector +#define VEC_SCALE_2(c,a,b) \ +{ \ + (c)[0] = (a)*(b)[0]; \ + (c)[1] = (a)*(b)[1]; \ +}\ + + +/// scalar times vector +#define VEC_SCALE(c,a,b) \ +{ \ + (c)[0] = (a)*(b)[0]; \ + (c)[1] = (a)*(b)[1]; \ + (c)[2] = (a)*(b)[2]; \ +}\ + + +/// scalar times vector +#define VEC_SCALE_4(c,a,b) \ +{ \ + (c)[0] = (a)*(b)[0]; \ + (c)[1] = (a)*(b)[1]; \ + (c)[2] = (a)*(b)[2]; \ + (c)[3] = (a)*(b)[3]; \ +}\ + + +/// accumulate scaled vector +#define VEC_ACCUM_2(c,a,b) \ +{ \ + (c)[0] += (a)*(b)[0]; \ + (c)[1] += (a)*(b)[1]; \ +}\ + + +/// accumulate scaled vector +#define VEC_ACCUM(c,a,b) \ +{ \ + (c)[0] += (a)*(b)[0]; \ + (c)[1] += (a)*(b)[1]; \ + (c)[2] += (a)*(b)[2]; \ +}\ + + +/// accumulate scaled vector +#define VEC_ACCUM_4(c,a,b) \ +{ \ + (c)[0] += (a)*(b)[0]; \ + (c)[1] += (a)*(b)[1]; \ + (c)[2] += (a)*(b)[2]; \ + (c)[3] += (a)*(b)[3]; \ +}\ + + +/// Vector dot product +#define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1]) + + +/// Vector dot product +#define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]) + +/// Vector dot product +#define VEC_DOT_4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3]) + +/// vector impact parameter (squared) +#define VEC_IMPACT_SQ(bsq,direction,position) {\ + GREAL _llel_ = VEC_DOT(direction, position);\ + bsq = VEC_DOT(position, position) - _llel_*_llel_;\ +}\ + + +/// vector impact parameter +#define VEC_IMPACT(bsq,direction,position) {\ + VEC_IMPACT_SQ(bsq,direction,position); \ + GIM_SQRT(bsq,bsq); \ +}\ + +/// Vector length +#define VEC_LENGTH_2(a,l)\ +{\ + GREAL _pp = VEC_DOT_2(a,a);\ + GIM_SQRT(_pp,l);\ +}\ + + +/// Vector length +#define VEC_LENGTH(a,l)\ +{\ + GREAL _pp = VEC_DOT(a,a);\ + GIM_SQRT(_pp,l);\ +}\ + + +/// Vector length +#define VEC_LENGTH_4(a,l)\ +{\ + GREAL _pp = VEC_DOT_4(a,a);\ + GIM_SQRT(_pp,l);\ +}\ + +/// Vector inv length +#define VEC_INV_LENGTH_2(a,l)\ +{\ + GREAL _pp = VEC_DOT_2(a,a);\ + GIM_INV_SQRT(_pp,l);\ +}\ + + +/// Vector inv length +#define VEC_INV_LENGTH(a,l)\ +{\ + GREAL _pp = VEC_DOT(a,a);\ + GIM_INV_SQRT(_pp,l);\ +}\ + + +/// Vector inv length +#define VEC_INV_LENGTH_4(a,l)\ +{\ + GREAL _pp = VEC_DOT_4(a,a);\ + GIM_INV_SQRT(_pp,l);\ +}\ + + + +/// distance between two points +#define VEC_DISTANCE(_len,_va,_vb) {\ + vec3f _tmp_; \ + VEC_DIFF(_tmp_, _vb, _va); \ + VEC_LENGTH(_tmp_,_len); \ +}\ + + +/// Vector length +#define VEC_CONJUGATE_LENGTH(a,l)\ +{\ + GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\ + GIM_SQRT(_pp,l);\ +}\ + + +/// Vector length +#define VEC_NORMALIZE(a) { \ + GREAL len;\ + VEC_INV_LENGTH(a,len); \ + if(lenA[1]?(A[0]>A[2]?0:2):(A[1]>A[2]?1:2);\ +}\ + +//! Finds the 2 smallest cartesian coordinates from a vector +#define VEC_MINOR_AXES(vec, i0, i1)\ +{\ + VEC_MAYOR_COORD(vec,i0);\ + i0 = (i0+1)%3;\ + i1 = (i0+1)%3;\ +}\ + + + + +#define VEC_EQUAL(v1,v2) (v1[0]==v2[0]&&v1[1]==v2[1]&&v1[2]==v2[2]) + +#define VEC_NEAR_EQUAL(v1,v2) (GIM_NEAR_EQUAL(v1[0],v2[0])&&GIM_NEAR_EQUAL(v1[1],v2[1])&&GIM_NEAR_EQUAL(v1[2],v2[2])) + + +/// Vector cross +#define X_AXIS_CROSS_VEC(dst,src)\ +{ \ + dst[0] = 0.0f; \ + dst[1] = -src[2]; \ + dst[2] = src[1]; \ +}\ + +#define Y_AXIS_CROSS_VEC(dst,src)\ +{ \ + dst[0] = src[2]; \ + dst[1] = 0.0f; \ + dst[2] = -src[0]; \ +}\ + +#define Z_AXIS_CROSS_VEC(dst,src)\ +{ \ + dst[0] = -src[1]; \ + dst[1] = src[0]; \ + dst[2] = 0.0f; \ +}\ + + + + + + +/// initialize matrix +#define IDENTIFY_MATRIX_3X3(m) \ +{ \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ +}\ + +/*! initialize matrix */ +#define IDENTIFY_MATRIX_4X4(m) \ +{ \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! initialize matrix */ +#define ZERO_MATRIX_4X4(m) \ +{ \ + m[0][0] = 0.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 0.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 0.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 0.0; \ +}\ + +/*! matrix rotation X */ +#define ROTX_CS(m,cosine,sine) \ +{ \ + /* rotation about the x-axis */ \ + \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = (cosine); \ + m[1][2] = (sine); \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = -(sine); \ + m[2][2] = (cosine); \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! matrix rotation Y */ +#define ROTY_CS(m,cosine,sine) \ +{ \ + /* rotation about the y-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = 0.0; \ + m[0][2] = -(sine); \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = (sine); \ + m[2][1] = 0.0; \ + m[2][2] = (cosine); \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! matrix rotation Z */ +#define ROTZ_CS(m,cosine,sine) \ +{ \ + /* rotation about the z-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = (sine); \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = -(sine); \ + m[1][1] = (cosine); \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! matrix copy */ +#define COPY_MATRIX_2X2(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + \ +}\ + + +/*! matrix copy */ +#define COPY_MATRIX_2X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ +}\ + + +/*! matrix copy */ +#define COPY_MATRIX_3X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ +}\ + + +/*! matrix copy */ +#define COPY_MATRIX_4X4(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + b[0][3] = a[0][3]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + b[1][3] = a[1][3]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[2][3]; \ + \ + b[3][0] = a[3][0]; \ + b[3][1] = a[3][1]; \ + b[3][2] = a[3][2]; \ + b[3][3] = a[3][3]; \ +}\ + + +/*! matrix transpose */ +#define TRANSPOSE_MATRIX_2X2(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ +}\ + + +/*! matrix transpose */ +#define TRANSPOSE_MATRIX_3X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ +}\ + + +/*! matrix transpose */ +#define TRANSPOSE_MATRIX_4X4(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + b[0][3] = a[3][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + b[1][3] = a[3][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[3][2]; \ + \ + b[3][0] = a[0][3]; \ + b[3][1] = a[1][3]; \ + b[3][2] = a[2][3]; \ + b[3][3] = a[3][3]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_MATRIX_2X2(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_MATRIX_3X3(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + b[0][2] = (s) * a[0][2]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ + b[1][2] = (s) * a[1][2]; \ + \ + b[2][0] = (s) * a[2][0]; \ + b[2][1] = (s) * a[2][1]; \ + b[2][2] = (s) * a[2][2]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_MATRIX_4X4(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + b[0][2] = (s) * a[0][2]; \ + b[0][3] = (s) * a[0][3]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ + b[1][2] = (s) * a[1][2]; \ + b[1][3] = (s) * a[1][3]; \ + \ + b[2][0] = (s) * a[2][0]; \ + b[2][1] = (s) * a[2][1]; \ + b[2][2] = (s) * a[2][2]; \ + b[2][3] = (s) * a[2][3]; \ + \ + b[3][0] = s * a[3][0]; \ + b[3][1] = s * a[3][1]; \ + b[3][2] = s * a[3][2]; \ + b[3][3] = s * a[3][3]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_VEC_MATRIX_2X2(b,svec,a) \ +{ \ + b[0][0] = svec[0] * a[0][0]; \ + b[1][0] = svec[0] * a[1][0]; \ + \ + b[0][1] = svec[1] * a[0][1]; \ + b[1][1] = svec[1] * a[1][1]; \ +}\ + + +/*! multiply matrix by scalar. Each columns is scaled by each scalar vector component */ +#define SCALE_VEC_MATRIX_3X3(b,svec,a) \ +{ \ + b[0][0] = svec[0] * a[0][0]; \ + b[1][0] = svec[0] * a[1][0]; \ + b[2][0] = svec[0] * a[2][0]; \ + \ + b[0][1] = svec[1] * a[0][1]; \ + b[1][1] = svec[1] * a[1][1]; \ + b[2][1] = svec[1] * a[2][1]; \ + \ + b[0][2] = svec[2] * a[0][2]; \ + b[1][2] = svec[2] * a[1][2]; \ + b[2][2] = svec[2] * a[2][2]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_VEC_MATRIX_4X4(b,svec,a) \ +{ \ + b[0][0] = svec[0] * a[0][0]; \ + b[1][0] = svec[0] * a[1][0]; \ + b[2][0] = svec[0] * a[2][0]; \ + b[3][0] = svec[0] * a[3][0]; \ + \ + b[0][1] = svec[1] * a[0][1]; \ + b[1][1] = svec[1] * a[1][1]; \ + b[2][1] = svec[1] * a[2][1]; \ + b[3][1] = svec[1] * a[3][1]; \ + \ + b[0][2] = svec[2] * a[0][2]; \ + b[1][2] = svec[2] * a[1][2]; \ + b[2][2] = svec[2] * a[2][2]; \ + b[3][2] = svec[2] * a[3][2]; \ + \ + b[0][3] = svec[3] * a[0][3]; \ + b[1][3] = svec[3] * a[1][3]; \ + b[2][3] = svec[3] * a[2][3]; \ + b[3][3] = svec[3] * a[3][3]; \ +}\ + + +/*! multiply matrix by scalar */ +#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ +}\ + + +/*! multiply matrix by scalar */ +#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + b[0][2] += (s) * a[0][2]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ + b[1][2] += (s) * a[1][2]; \ + \ + b[2][0] += (s) * a[2][0]; \ + b[2][1] += (s) * a[2][1]; \ + b[2][2] += (s) * a[2][2]; \ +}\ + + +/*! multiply matrix by scalar */ +#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + b[0][2] += (s) * a[0][2]; \ + b[0][3] += (s) * a[0][3]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ + b[1][2] += (s) * a[1][2]; \ + b[1][3] += (s) * a[1][3]; \ + \ + b[2][0] += (s) * a[2][0]; \ + b[2][1] += (s) * a[2][1]; \ + b[2][2] += (s) * a[2][2]; \ + b[2][3] += (s) * a[2][3]; \ + \ + b[3][0] += (s) * a[3][0]; \ + b[3][1] += (s) * a[3][1]; \ + b[3][2] += (s) * a[3][2]; \ + b[3][3] += (s) * a[3][3]; \ +}\ + +/*! matrix product */ +/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ +#define MATRIX_PRODUCT_2X2(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \ + \ +}\ + +/*! matrix product */ +/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ +#define MATRIX_PRODUCT_3X3(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \ + c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \ + c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \ + \ + c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \ + c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \ + c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \ +}\ + + +/*! matrix product */ +/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ +#define MATRIX_PRODUCT_4X4(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\ + c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\ + c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\ + c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\ + c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\ + \ + c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\ + c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\ + c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\ + c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\ + \ + c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\ + c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\ + c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\ + c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\ +}\ + + +/*! matrix times vector */ +#define MAT_DOT_VEC_2X2(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \ +}\ + + +/*! matrix times vector */ +#define MAT_DOT_VEC_3X3(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \ + p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \ +}\ + + +/*! matrix times vector +v is a vec4f +*/ +#define MAT_DOT_VEC_4X4(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \ + p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \ + p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \ +}\ + +/*! matrix times vector +v is a vec3f +and m is a mat4f
    +Last column is added as the position +*/ +#define MAT_DOT_VEC_3X4(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]; \ + p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]; \ +}\ + + +/*! vector transpose times matrix */ +/*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */ +#define VEC_DOT_MAT_3X3(p,v,m) \ +{ \ + p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \ + p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \ + p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \ +}\ + + +/*! affine matrix times vector */ +/** The matrix is assumed to be an affine matrix, with last two + * entries representing a translation */ +#define MAT_DOT_VEC_2X3(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \ +}\ + +//! Transform a plane +#define MAT_TRANSFORM_PLANE_4X4(pout,m,plane)\ +{ \ + pout[0] = m[0][0]*plane[0] + m[0][1]*plane[1] + m[0][2]*plane[2];\ + pout[1] = m[1][0]*plane[0] + m[1][1]*plane[1] + m[1][2]*plane[2];\ + pout[2] = m[2][0]*plane[0] + m[2][1]*plane[1] + m[2][2]*plane[2];\ + pout[3] = m[0][3]*pout[0] + m[1][3]*pout[1] + m[2][3]*pout[2] + plane[3];\ +}\ + + + +/** inverse transpose of matrix times vector + * + * This macro computes inverse transpose of matrix m, + * and multiplies vector v into it, to yeild vector p + * + * DANGER !!! Do Not use this on normal vectors!!! + * It will leave normals the wrong length !!! + * See macro below for use on normals. + */ +#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \ +{ \ + GREAL det; \ + \ + det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \ + p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ + p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ + \ + /* if matrix not singular, and not orthonormal, then renormalize */ \ + if ((det!=1.0f) && (det != 0.0f)) { \ + det = 1.0f / det; \ + p[0] *= det; \ + p[1] *= det; \ + } \ +}\ + + +/** transform normal vector by inverse transpose of matrix + * and then renormalize the vector + * + * This macro computes inverse transpose of matrix m, + * and multiplies vector v into it, to yeild vector p + * Vector p is then normalized. + */ +#define NORM_XFORM_2X2(p,m,v) \ +{ \ + GREAL len; \ + \ + /* do nothing if off-diagonals are zero and diagonals are \ + * equal */ \ + if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \ + p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ + p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ + \ + len = p[0]*p[0] + p[1]*p[1]; \ + GIM_INV_SQRT(len,len); \ + p[0] *= len; \ + p[1] *= len; \ + } else { \ + VEC_COPY_2 (p, v); \ + } \ +}\ + + +/** outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ +#define OUTER_PRODUCT_2X2(m,v,t) \ +{ \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ +}\ + + +/** outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ +#define OUTER_PRODUCT_3X3(m,v,t) \ +{ \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + m[0][2] = v[0] * t[2]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ + m[1][2] = v[1] * t[2]; \ + \ + m[2][0] = v[2] * t[0]; \ + m[2][1] = v[2] * t[1]; \ + m[2][2] = v[2] * t[2]; \ +}\ + + +/** outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ +#define OUTER_PRODUCT_4X4(m,v,t) \ +{ \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + m[0][2] = v[0] * t[2]; \ + m[0][3] = v[0] * t[3]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ + m[1][2] = v[1] * t[2]; \ + m[1][3] = v[1] * t[3]; \ + \ + m[2][0] = v[2] * t[0]; \ + m[2][1] = v[2] * t[1]; \ + m[2][2] = v[2] * t[2]; \ + m[2][3] = v[2] * t[3]; \ + \ + m[3][0] = v[3] * t[0]; \ + m[3][1] = v[3] * t[1]; \ + m[3][2] = v[3] * t[2]; \ + m[3][3] = v[3] * t[3]; \ +}\ + + +/** outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ +#define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \ +{ \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ +}\ + + +/** outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ +#define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \ +{ \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + m[0][2] += v[0] * t[2]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ + m[1][2] += v[1] * t[2]; \ + \ + m[2][0] += v[2] * t[0]; \ + m[2][1] += v[2] * t[1]; \ + m[2][2] += v[2] * t[2]; \ +}\ + + +/** outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ +#define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \ +{ \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + m[0][2] += v[0] * t[2]; \ + m[0][3] += v[0] * t[3]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ + m[1][2] += v[1] * t[2]; \ + m[1][3] += v[1] * t[3]; \ + \ + m[2][0] += v[2] * t[0]; \ + m[2][1] += v[2] * t[1]; \ + m[2][2] += v[2] * t[2]; \ + m[2][3] += v[2] * t[3]; \ + \ + m[3][0] += v[3] * t[0]; \ + m[3][1] += v[3] * t[1]; \ + m[3][2] += v[3] * t[2]; \ + m[3][3] += v[3] * t[3]; \ +}\ + + +/** determinant of matrix + * + * Computes determinant of matrix m, returning d + */ +#define DETERMINANT_2X2(d,m) \ +{ \ + d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \ +}\ + + +/** determinant of matrix + * + * Computes determinant of matrix m, returning d + */ +#define DETERMINANT_3X3(d,m) \ +{ \ + d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \ + d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \ + d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \ +}\ + + +/** i,j,th cofactor of a 4x4 matrix + * + */ +#define COFACTOR_4X4_IJ(fac,m,i,j) \ +{ \ + GUINT __ii[4], __jj[4], __k; \ + \ + for (__k=0; __k +*/ +#define INV_MAT_DOT_VEC_3X3(p,m,v) \ +{ \ + p[0] = MAT_DOT_COL(m,v,0); \ + p[1] = MAT_DOT_COL(m,v,1); \ + p[2] = MAT_DOT_COL(m,v,2); \ +}\ + + + +#endif // GIM_VECTOR_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_math.h b/src/BulletCollision/Gimpact/gim_math.h new file mode 100644 index 0000000..939079e --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_math.h @@ -0,0 +1,157 @@ +#ifndef GIM_MATH_H_INCLUDED +#define GIM_MATH_H_INCLUDED +/*! \file gim_math.h +\author Francisco Leon Najera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "LinearMath/btScalar.h" + + + +#define GREAL btScalar +#define GREAL2 double +#define GINT int +#define GUINT unsigned int +#define GSHORT short +#define GUSHORT unsigned short +#define GINT64 long long +#define GUINT64 unsigned long long + + + +#define G_PI 3.14159265358979f +#define G_HALF_PI 1.5707963f +//267948966 +#define G_TWO_PI 6.28318530f +//71795864 +#define G_ROOT3 1.73205f +#define G_ROOT2 1.41421f +#define G_UINT_INFINITY 0xffffffff //!< A very very high value +#define G_REAL_INFINITY FLT_MAX +#define G_SIGN_BITMASK 0x80000000 +#define G_EPSILON SIMD_EPSILON + + + +enum GIM_SCALAR_TYPES +{ + G_STYPE_REAL =0, + G_STYPE_REAL2, + G_STYPE_SHORT, + G_STYPE_USHORT, + G_STYPE_INT, + G_STYPE_UINT, + G_STYPE_INT64, + G_STYPE_UINT64 +}; + + + +#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f) +#define G_RADTODEG(X) ((X)*180.0f/3.1415926f) + +//! Integer representation of a floating-point value. +#define GIM_IR(x) ((GUINT&)(x)) + +//! Signed integer representation of a floating-point value. +#define GIM_SIR(x) ((GINT&)(x)) + +//! Absolute integer representation of a floating-point value +#define GIM_AIR(x) (GIM_IR(x)&0x7fffffff) + +//! Floating-point representation of an integer value. +#define GIM_FR(x) ((GREAL&)(x)) + +#define GIM_MAX(a,b) (ab?b:a) + +#define GIM_MAX3(a,b,c) GIM_MAX(a,GIM_MAX(b,c)) +#define GIM_MIN3(a,b,c) GIM_MIN(a,GIM_MIN(b,c)) + +#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON) + +#define GIM_IS_NEGATIVE(value) (value <= -G_EPSILON) + +#define GIM_IS_POSISITVE(value) (value >= G_EPSILON) + +#define GIM_NEAR_EQUAL(v1,v2) GIM_IS_ZERO((v1-v2)) + +///returns a clamped number +#define GIM_CLAMP(number,minval,maxval) (numbermaxval?maxval:number)) + +#define GIM_GREATER(x, y) btFabs(x) > (y) + +///Swap numbers +#define GIM_SWAP_NUMBERS(a,b){ \ + a = a+b; \ + b = a-b; \ + a = a-b; \ +}\ + +#define GIM_INV_SQRT(va,isva)\ +{\ + if(va<=0.0000001f)\ + {\ + isva = G_REAL_INFINITY;\ + }\ + else\ + {\ + GREAL _x = va * 0.5f;\ + GUINT _y = 0x5f3759df - ( GIM_IR(va) >> 1);\ + isva = GIM_FR(_y);\ + isva = isva * ( 1.5f - ( _x * isva * isva ) );\ + }\ +}\ + +#define GIM_SQRT(va,sva)\ +{\ + GIM_INV_SQRT(va,sva);\ + sva = 1.0f/sva;\ +}\ + +//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html +inline GREAL gim_inv_sqrt(GREAL f) +{ + GREAL r; + GIM_INV_SQRT(f,r); + return r; +} + +inline GREAL gim_sqrt(GREAL f) +{ + GREAL r; + GIM_SQRT(f,r); + return r; +} + + + +#endif // GIM_MATH_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_memory.cpp b/src/BulletCollision/Gimpact/gim_memory.cpp new file mode 100644 index 0000000..1636eb7 --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_memory.cpp @@ -0,0 +1,135 @@ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "gim_memory.h" +#include "stdlib.h" + +#ifdef GIM_SIMD_MEMORY +#include "LinearMath/btAlignedAllocator.h" +#endif + +static gim_alloc_function *g_allocfn = 0; +static gim_alloca_function *g_allocafn = 0; +static gim_realloc_function *g_reallocfn = 0; +static gim_free_function *g_freefn = 0; + +void gim_set_alloc_handler (gim_alloc_function *fn) +{ + g_allocfn = fn; +} + +void gim_set_alloca_handler (gim_alloca_function *fn) +{ + g_allocafn = fn; +} + +void gim_set_realloc_handler (gim_realloc_function *fn) +{ + g_reallocfn = fn; +} + +void gim_set_free_handler (gim_free_function *fn) +{ + g_freefn = fn; +} + +gim_alloc_function *gim_get_alloc_handler() +{ + return g_allocfn; +} + +gim_alloca_function *gim_get_alloca_handler() +{ + return g_allocafn; +} + + +gim_realloc_function *gim_get_realloc_handler () +{ + return g_reallocfn; +} + + +gim_free_function *gim_get_free_handler () +{ + return g_freefn; +} + + +void * gim_alloc(size_t size) +{ + void * ptr; + if (g_allocfn) + { + ptr = g_allocfn(size); + } + else + { +#ifdef GIM_SIMD_MEMORY + ptr = btAlignedAlloc(size,16); +#else + ptr = malloc(size); +#endif + } + return ptr; +} + +void * gim_alloca(size_t size) +{ + if (g_allocafn) return g_allocafn(size); else return gim_alloc(size); +} + + +void * gim_realloc(void *ptr, size_t oldsize, size_t newsize) +{ + void * newptr = gim_alloc(newsize); + size_t copysize = oldsize + +#ifdef PREFETCH +#include // for prefetch +#define pfval 64 +#define pfval2 128 +//! Prefetch 64 +#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0) +//! Prefetch 128 +#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0) +#else +//! Prefetch 64 +#define pf(_x,_i) +//! Prefetch 128 +#define pf2(_x,_i) +#endif + + +///Functions for manip packed arrays of numbers +#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\ +{\ + for (GUINT _i_=0;_i_=SIMD_T_SIZE) + { + *(ui_dst_ptr++) = *(ui_src_ptr++); + copysize-=SIMD_T_SIZE; + } + if(copysize==0) return; +*/ + + char * c_src_ptr = (char *)src; + char * c_dst_ptr = (char *)dst; + while(copysize>0) + { + *(c_dst_ptr++) = *(c_src_ptr++); + copysize--; + } + return; +#else + memcpy(dst,src,copysize); +#endif +} + + + +template +inline void gim_swap_elements(T* _array,size_t _i,size_t _j) +{ + T _e_tmp_ = _array[_i]; + _array[_i] = _array[_j]; + _array[_j] = _e_tmp_; +} + + +template +inline void gim_swap_elements_memcpy(T* _array,size_t _i,size_t _j) +{ + char _e_tmp_[sizeof(T)]; + gim_simd_memcpy(_e_tmp_,&_array[_i],sizeof(T)); + gim_simd_memcpy(&_array[_i],&_array[_j],sizeof(T)); + gim_simd_memcpy(&_array[_j],_e_tmp_,sizeof(T)); +} + +template +inline void gim_swap_elements_ptr(char * _array,size_t _i,size_t _j) +{ + char _e_tmp_[SIZE]; + _i*=SIZE; + _j*=SIZE; + gim_simd_memcpy(_e_tmp_,_array+_i,SIZE); + gim_simd_memcpy(_array+_i,_array+_j,SIZE); + gim_simd_memcpy(_array+_j,_e_tmp_,SIZE); +} + +#endif // GIM_MEMORY_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_radixsort.h b/src/BulletCollision/Gimpact/gim_radixsort.h new file mode 100644 index 0000000..c246ef1 --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_radixsort.h @@ -0,0 +1,406 @@ +#ifndef GIM_RADIXSORT_H_INCLUDED +#define GIM_RADIXSORT_H_INCLUDED +/*! \file gim_radixsort.h +\author Francisco Leon Najera. +Based on the work of Michael Herf : "fast floating-point radix sort" +Avaliable on http://www.stereopsis.com/radix.html +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "gim_memory.h" + +///Macros for sorting. +//! Prototype for comparators +class less_comparator +{ + public: + + template + inline int operator() ( const T& a, const Z& b ) + { + return ( ab?1:0)); + } +}; + +//! Prototype for comparators +class integer_comparator +{ + public: + + template + inline int operator() ( const T& a, const T& b ) + { + return (int)(a-b); + } +}; + +//!Prototype for getting the integer representation of an object +class uint_key_func +{ +public: + template + inline GUINT operator()( const T& a) + { + return (GUINT)a; + } +}; + + +//!Prototype for copying elements +class copy_elements_func +{ +public: + template + inline void operator()(T& a,T& b) + { + a = b; + } +}; + +//!Prototype for copying elements +class memcopy_elements_func +{ +public: + template + inline void operator()(T& a,T& b) + { + gim_simd_memcpy(&a,&b,sizeof(T)); + } +}; + + +//! @{ +struct GIM_RSORT_TOKEN +{ + GUINT m_key; + GUINT m_value; + GIM_RSORT_TOKEN() + { + } + GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken) + { + m_key = rtoken.m_key; + m_value = rtoken.m_value; + } + + inline bool operator <(const GIM_RSORT_TOKEN& other) const + { + return (m_key < other.m_key); + } + + inline bool operator >(const GIM_RSORT_TOKEN& other) const + { + return (m_key > other.m_key); + } +}; + +//! Prototype for comparators +class GIM_RSORT_TOKEN_COMPARATOR +{ + public: + + inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b ) + { + return (int)((a.m_key) - (b.m_key)); + } +}; + + + +#define kHist 2048 +// ---- utils for accessing 11-bit quantities +#define D11_0(x) (x & 0x7FF) +#define D11_1(x) (x >> 11 & 0x7FF) +#define D11_2(x) (x >> 22 ) + + + +///Radix sort for unsigned integer keys +inline void gim_radix_sort_rtokens( + GIM_RSORT_TOKEN * array, + GIM_RSORT_TOKEN * sorted, GUINT element_count) +{ + GUINT i; + GUINT b0[kHist * 3]; + GUINT *b1 = b0 + kHist; + GUINT *b2 = b1 + kHist; + for (i = 0; i < kHist * 3; ++i) + { + b0[i] = 0; + } + GUINT fi; + GUINT pos; + for (i = 0; i < element_count; ++i) + { + fi = array[i].m_key; + b0[D11_0(fi)] ++; + b1[D11_1(fi)] ++; + b2[D11_2(fi)] ++; + } + { + GUINT sum0 = 0, sum1 = 0, sum2 = 0; + GUINT tsum; + for (i = 0; i < kHist; ++i) + { + tsum = b0[i] + sum0; + b0[i] = sum0 - 1; + sum0 = tsum; + tsum = b1[i] + sum1; + b1[i] = sum1 - 1; + sum1 = tsum; + tsum = b2[i] + sum2; + b2[i] = sum2 - 1; + sum2 = tsum; + } + } + for (i = 0; i < element_count; ++i) + { + fi = array[i].m_key; + pos = D11_0(fi); + pos = ++b0[pos]; + sorted[pos].m_key = array[i].m_key; + sorted[pos].m_value = array[i].m_value; + } + for (i = 0; i < element_count; ++i) + { + fi = sorted[i].m_key; + pos = D11_1(fi); + pos = ++b1[pos]; + array[pos].m_key = sorted[i].m_key; + array[pos].m_value = sorted[i].m_value; + } + for (i = 0; i < element_count; ++i) + { + fi = array[i].m_key; + pos = D11_2(fi); + pos = ++b2[pos]; + sorted[pos].m_key = array[i].m_key; + sorted[pos].m_value = array[i].m_value; + } +} + + + + +/// Get the sorted tokens from an array. For generic use. Tokens are IRR_RSORT_TOKEN +/*! +*\param array Array of elements to sort +*\param sorted_tokens Tokens of sorted elements +*\param element_count element count +*\param uintkey_macro Functor which retrieves the integer representation of an array element +*/ +template +void gim_radix_sort_array_tokens( + T* array , + GIM_RSORT_TOKEN * sorted_tokens, + GUINT element_count,GETKEY_CLASS uintkey_macro) +{ + GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count); + for (GUINT _i=0;_i +void gim_radix_sort( + T * array, GUINT element_count, + GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro) +{ + GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count); + gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro); + T * _original_array = (T *) gim_alloc(sizeof(T)*element_count); + gim_simd_memcpy(_original_array,array,sizeof(T)*element_count); + for (GUINT _i=0;_i +bool gim_binary_search_ex( + const T* _array, GUINT _start_i, + GUINT _end_i,GUINT & _result_index, + const KEYCLASS & _search_key, + COMP_CLASS _comp_macro) +{ + GUINT _k; + int _comp_result; + GUINT _i = _start_i; + GUINT _j = _end_i+1; + while (_i < _j) + { + _k = (_j+_i-1)/2; + _comp_result = _comp_macro(_array[_k], _search_key); + if (_comp_result == 0) + { + _result_index = _k; + return true; + } + else if (_comp_result < 0) + { + _i = _k+1; + } + else + { + _j = _k; + } + } + _result_index = _i; + return false; +} + + + +//! Failsafe Iterative binary search,Template version +/*! +If the element is not found, it returns the nearest upper element position, may be the further position after the last element. +\param _array +\param _start_i the beginning of the array +\param _end_i the ending index of the array +\param _search_key Value to find +\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value +\return true if found, else false +*/ +template +bool gim_binary_search( + const T*_array,GUINT _start_i, + GUINT _end_i,const T & _search_key, + GUINT & _result_index) +{ + GUINT _i = _start_i; + GUINT _j = _end_i+1; + GUINT _k; + while(_i < _j) + { + _k = (_j+_i-1)/2; + if(_array[_k]==_search_key) + { + _result_index = _k; + return true; + } + else if (_array[_k]<_search_key) + { + _i = _k+1; + } + else + { + _j = _k; + } + } + _result_index = _i; + return false; +} + + + +///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ +template +void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc) +{ + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ + + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n/2) + { + int child = 2*k; + + if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp , pArr[child - 1])<0) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; + } + else + { + break; + } + } + pArr[k - 1] = temp; +} /*downHeap*/ + + +template +void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc) +{ + /* sort a[0..N-1], N.B. 0 to N-1 */ + GUINT k; + GUINT n = element_count; + for (k = n/2; k > 0; k--) + { + gim_down_heap(pArr, k, n, CompareFunc); + } + + /* a[1..N] is now a heap */ + while ( n>=2 ) + { + gim_swap_elements(pArr,0,n-1); /* largest of a[0..n-1] */ + --n; + /* restore a[1..i-1] heap */ + gim_down_heap(pArr, 1, n, CompareFunc); + } +} + + + + +#endif // GIM_RADIXSORT_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_tri_collision.cpp b/src/BulletCollision/Gimpact/gim_tri_collision.cpp new file mode 100644 index 0000000..f9727e1 --- /dev/null +++ b/src/BulletCollision/Gimpact/gim_tri_collision.cpp @@ -0,0 +1,640 @@ + +/*! \file gim_tri_collision.h +\author Francisco Leon Najera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "gim_tri_collision.h" + + +#define TRI_LOCAL_EPSILON 0.000001f +#define MIN_EDGE_EDGE_DIS 0.00001f + + +class GIM_TRIANGLE_CALCULATION_CACHE +{ +public: + GREAL margin; + btVector3 tu_vertices[3]; + btVector3 tv_vertices[3]; + btVector4 tu_plane; + btVector4 tv_plane; + btVector3 closest_point_u; + btVector3 closest_point_v; + btVector3 edge_edge_dir; + btVector3 distances; + GREAL du[4]; + GREAL du0du1; + GREAL du0du2; + GREAL dv[4]; + GREAL dv0dv1; + GREAL dv0dv2; + btVector3 temp_points[MAX_TRI_CLIPPING]; + btVector3 temp_points1[MAX_TRI_CLIPPING]; + btVector3 contact_points[MAX_TRI_CLIPPING]; + + + + //! if returns false, the faces are paralele + SIMD_FORCE_INLINE bool compute_intervals( + const GREAL &D0, + const GREAL &D1, + const GREAL &D2, + const GREAL &D0D1, + const GREAL &D0D2, + GREAL & scale_edge0, + GREAL & scale_edge1, + GUINT &edge_index0, + GUINT &edge_index1) + { + if(D0D1>0.0f) + { + /* here we know that D0D2<=0.0 */ + /* that is D0, D1 are on the same side, D2 on the other or on the plane */ + scale_edge0 = -D2/(D0-D2); + scale_edge1 = -D1/(D2-D1); + edge_index0 = 2;edge_index1 = 1; + } + else if(D0D2>0.0f) + { + /* here we know that d0d1<=0.0 */ + scale_edge0 = -D0/(D1-D0); + scale_edge1 = -D1/(D2-D1); + edge_index0 = 0;edge_index1 = 1; + } + else if(D1*D2>0.0f || D0!=0.0f) + { + /* here we know that d0d1<=0.0 or that D0!=0.0 */ + scale_edge0 = -D0/(D1-D0); + scale_edge1 = -D2/(D0-D2); + edge_index0 = 0 ;edge_index1 = 2; + } + else + { + return false; + } + return true; + } + + + //! clip triangle + /*! + */ + SIMD_FORCE_INLINE GUINT clip_triangle( + const btVector4 & tri_plane, + const btVector3 * tripoints, + const btVector3 * srcpoints, + btVector3 * clip_points) + { + // edge 0 + + btVector4 edgeplane; + + EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane); + + GUINT clipped_count = PLANE_CLIP_TRIANGLE3D( + edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points); + + if(clipped_count == 0) return 0; + + // edge 1 + + EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane); + + clipped_count = PLANE_CLIP_POLYGON3D( + edgeplane,temp_points,clipped_count,temp_points1); + + if(clipped_count == 0) return 0; + + // edge 2 + + EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane); + + clipped_count = PLANE_CLIP_POLYGON3D( + edgeplane,temp_points1,clipped_count,clip_points); + + return clipped_count; + + + /*GUINT i0 = (tri_plane.closestAxis()+1)%3; + GUINT i1 = (i0+1)%3; + // edge 0 + btVector3 temp_points[MAX_TRI_CLIPPING]; + btVector3 temp_points1[MAX_TRI_CLIPPING]; + + GUINT clipped_count= PLANE_CLIP_TRIANGLE_GENERIC( + 0,srcpoints[0],srcpoints[1],srcpoints[2],temp_points, + DISTANCE_EDGE(tripoints[0],tripoints[1],i0,i1)); + + + if(clipped_count == 0) return 0; + + // edge 1 + clipped_count = PLANE_CLIP_POLYGON_GENERIC( + 0,temp_points,clipped_count,temp_points1, + DISTANCE_EDGE(tripoints[1],tripoints[2],i0,i1)); + + if(clipped_count == 0) return 0; + + // edge 2 + clipped_count = PLANE_CLIP_POLYGON_GENERIC( + 0,temp_points1,clipped_count,clipped_points, + DISTANCE_EDGE(tripoints[2],tripoints[0],i0,i1)); + + return clipped_count;*/ + } + + SIMD_FORCE_INLINE void sort_isect( + GREAL & isect0,GREAL & isect1,GUINT &e0,GUINT &e1,btVector3 & vec0,btVector3 & vec1) + { + if(isect1=isect_v[1]) // face U casts face V + { + return 1; + } + else if(isect_v[0]<=isect_u[0]) // face V casts face U + { + return 2; + } + // closest points + closest_point_u = up_e1; + closest_point_v = vp_e0; + // calc edges and separation + + if(isect_u[1]+ MIN_EDGE_EDGE_DIS=isect_u[1]) // face V casts face U + { + return 2; + } + else if(isect_u[0]<=isect_v[0]) // face U casts face V + { + return 1; + } + // closest points + closest_point_u = up_e0; + closest_point_v = vp_e1; + // calc edges and separation + + if(isect_v[1]+MIN_EDGE_EDGE_DIS0.0f && du0du2>0.0f) // same sign on all of them + not equal 0 ? + { + if(du[0]<0) //we need test behind the triangle plane + { + distances[0] = GIM_MAX3(du[0],du[1],du[2]); + distances[0] = -distances[0]; + if(distances[0]>margin) return false; //never intersect + + //reorder triangle v + VEC_SWAP(tv_vertices[0],tv_vertices[1]); + VEC_SCALE_4(tv_plane,-1.0f,tv_plane); + } + else + { + distances[0] = GIM_MIN3(du[0],du[1],du[2]); + if(distances[0]>margin) return false; //never intersect + } + } + else + { + //Look if we need to invert the triangle + distances[0] = (du[0]+du[1]+du[2])/3.0f; //centroid + + if(distances[0]<0.0f) + { + //reorder triangle v + VEC_SWAP(tv_vertices[0],tv_vertices[1]); + VEC_SCALE_4(tv_plane,-1.0f,tv_plane); + + distances[0] = GIM_MAX3(du[0],du[1],du[2]); + distances[0] = -distances[0]; + } + else + { + distances[0] = GIM_MIN3(du[0],du[1],du[2]); + } + } + + + // plane U vs V points + + TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],tu_plane); + + dv[0] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[0]); + dv[1] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[1]); + dv[2] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[2]); + + dv0dv1 = dv[0] * dv[1]; + dv0dv2 = dv[0] * dv[2]; + + + if(dv0dv1>0.0f && dv0dv2>0.0f) // same sign on all of them + not equal 0 ? + { + if(dv[0]<0) //we need test behind the triangle plane + { + distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]); + distances[1] = -distances[1]; + if(distances[1]>margin) return false; //never intersect + + //reorder triangle u + VEC_SWAP(tu_vertices[0],tu_vertices[1]); + VEC_SCALE_4(tu_plane,-1.0f,tu_plane); + } + else + { + distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]); + if(distances[1]>margin) return false; //never intersect + } + } + else + { + //Look if we need to invert the triangle + distances[1] = (dv[0]+dv[1]+dv[2])/3.0f; //centroid + + if(distances[1]<0.0f) + { + //reorder triangle v + VEC_SWAP(tu_vertices[0],tu_vertices[1]); + VEC_SCALE_4(tu_plane,-1.0f,tu_plane); + + distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]); + distances[1] = -distances[1]; + } + else + { + distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]); + } + } + + GUINT bl; + /* bl = cross_line_intersection_test(); + if(bl==3) + { + //take edge direction too + bl = distances.maxAxis(); + } + else + {*/ + bl = 0; + if(distances[0]margin) return false; + + contacts.m_penetration_depth = -distances[2] + margin; + contacts.m_points[0] = closest_point_v; + contacts.m_point_count = 1; + VEC_COPY(contacts.m_separating_normal,edge_edge_dir); + + return true; + } + + //clip face against other + + + GUINT point_count; + //TODO + if(bl == 0) //clip U points against V + { + point_count = clip_triangle(tv_plane,tv_vertices,tu_vertices,contact_points); + if(point_count == 0) return false; + contacts.merge_points(tv_plane,margin,contact_points,point_count); + } + else //clip V points against U + { + point_count = clip_triangle(tu_plane,tu_vertices,tv_vertices,contact_points); + if(point_count == 0) return false; + contacts.merge_points(tu_plane,margin,contact_points,point_count); + contacts.m_separating_normal *= -1.f; + } + if(contacts.m_point_count == 0) return false; + return true; + } + +}; + + +/*class GIM_TRIANGLE_CALCULATION_CACHE +{ +public: + GREAL margin; + GUINT clipped_count; + btVector3 tu_vertices[3]; + btVector3 tv_vertices[3]; + btVector3 temp_points[MAX_TRI_CLIPPING]; + btVector3 temp_points1[MAX_TRI_CLIPPING]; + btVector3 clipped_points[MAX_TRI_CLIPPING]; + GIM_TRIANGLE_CONTACT_DATA contacts1; + GIM_TRIANGLE_CONTACT_DATA contacts2; + + + //! clip triangle + GUINT clip_triangle( + const btVector4 & tri_plane, + const btVector3 * tripoints, + const btVector3 * srcpoints, + btVector3 * clipped_points) + { + // edge 0 + + btVector4 edgeplane; + + EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane); + + GUINT clipped_count = PLANE_CLIP_TRIANGLE3D( + edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points); + + if(clipped_count == 0) return 0; + + // edge 1 + + EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane); + + clipped_count = PLANE_CLIP_POLYGON3D( + edgeplane,temp_points,clipped_count,temp_points1); + + if(clipped_count == 0) return 0; + + // edge 2 + + EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane); + + clipped_count = PLANE_CLIP_POLYGON3D( + edgeplane,temp_points1,clipped_count,clipped_points); + + return clipped_count; + } + + + + + //! collides only on one side + bool triangle_collision( + const btVector3 & u0, + const btVector3 & u1, + const btVector3 & u2, + GREAL margin_u, + const btVector3 & v0, + const btVector3 & v1, + const btVector3 & v2, + GREAL margin_v, + GIM_TRIANGLE_CONTACT_DATA & contacts) + { + + margin = margin_u + margin_v; + + + tu_vertices[0] = u0; + tu_vertices[1] = u1; + tu_vertices[2] = u2; + + tv_vertices[0] = v0; + tv_vertices[1] = v1; + tv_vertices[2] = v2; + + //create planes + // plane v vs U points + + + TRIANGLE_PLANE(tv_vertices[0],tv_vertices[1],tv_vertices[2],contacts1.m_separating_normal); + + clipped_count = clip_triangle( + contacts1.m_separating_normal,tv_vertices,tu_vertices,clipped_points); + + if(clipped_count == 0 ) + { + return false;//Reject + } + + //find most deep interval face1 + contacts1.merge_points(contacts1.m_separating_normal,margin,clipped_points,clipped_count); + if(contacts1.m_point_count == 0) return false; // too far + + //Normal pointing to triangle1 + //contacts1.m_separating_normal *= -1.f; + + //Clip tri1 by tri2 edges + + TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],contacts2.m_separating_normal); + + clipped_count = clip_triangle( + contacts2.m_separating_normal,tu_vertices,tv_vertices,clipped_points); + + if(clipped_count == 0 ) + { + return false;//Reject + } + + //find most deep interval face1 + contacts2.merge_points(contacts2.m_separating_normal,margin,clipped_points,clipped_count); + if(contacts2.m_point_count == 0) return false; // too far + + contacts2.m_separating_normal *= -1.f; + + ////check most dir for contacts + if(contacts2.m_penetration_depth + SIMD_FORCE_INLINE void mergepoints_generic(const CLASS_PLANE & plane, + GREAL margin, const btVector3 * points, GUINT point_count, DISTANCE_FUNC distance_func) + { + m_point_count = 0; + m_penetration_depth= -1000.0f; + + GUINT point_indices[MAX_TRI_CLIPPING]; + + GUINT _k; + + for(_k=0;_k=0.0f) + { + if(_dist>m_penetration_depth) + { + m_penetration_depth = _dist; + point_indices[0] = _k; + m_point_count=1; + } + else if((_dist+G_EPSILON)>=m_penetration_depth) + { + point_indices[m_point_count] = _k; + m_point_count++; + } + } + } + + for( _k=0;_k u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1] + + --> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1] + + --> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2] + + --> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2] + + --> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1] + + --> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) + +if 0.0<= u+v <=1.0 then they are inside of triangle + + \return false if the point is outside of triangle.This function doesn't take the margin + */ + SIMD_FORCE_INLINE bool get_uv_parameters( + const btVector3 & point, + const btVector3 & tri_plane, + GREAL & u, GREAL & v) const + { + btVector3 _axe1 = m_vertices[1]-m_vertices[0]; + btVector3 _axe2 = m_vertices[2]-m_vertices[0]; + btVector3 _vecproj = point - m_vertices[0]; + GUINT _i1 = (tri_plane.closestAxis()+1)%3; + GUINT _i2 = (_i1+1)%3; + if(btFabs(_axe2[_i2])G_EPSILON) + { + return false; + } + } + return true; + } + + //! is point in triangle beam? + /*! + Test if point is in triangle, with m_margin tolerance + */ + SIMD_FORCE_INLINE bool is_point_inside(const btVector3 & point, const btVector3 & tri_normal) const + { + //Test with edge 0 + btVector4 edge_plane; + this->get_edge_plane(0,tri_normal,edge_plane); + GREAL dist = DISTANCE_PLANE_POINT(edge_plane,point); + if(dist-m_margin>0.0f) return false; // outside plane + + this->get_edge_plane(1,tri_normal,edge_plane); + dist = DISTANCE_PLANE_POINT(edge_plane,point); + if(dist-m_margin>0.0f) return false; // outside plane + + this->get_edge_plane(2,tri_normal,edge_plane); + dist = DISTANCE_PLANE_POINT(edge_plane,point); + if(dist-m_margin>0.0f) return false; // outside plane + return true; + } + + + //! Bidireccional ray collision + SIMD_FORCE_INLINE bool ray_collision( + const btVector3 & vPoint, + const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal, + GREAL & tparam, GREAL tmax = G_REAL_INFINITY) + { + btVector4 faceplane; + { + btVector3 dif1 = m_vertices[1] - m_vertices[0]; + btVector3 dif2 = m_vertices[2] - m_vertices[0]; + VEC_CROSS(faceplane,dif1,dif2); + faceplane[3] = m_vertices[0].dot(faceplane); + } + + GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax); + if(res == 0) return false; + if(! is_point_inside(pout,faceplane)) return false; + + if(res==2) //invert normal + { + triangle_normal.setValue(-faceplane[0],-faceplane[1],-faceplane[2]); + } + else + { + triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]); + } + + VEC_NORMALIZE(triangle_normal); + + return true; + } + + + //! one direccion ray collision + SIMD_FORCE_INLINE bool ray_collision_front_side( + const btVector3 & vPoint, + const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal, + GREAL & tparam, GREAL tmax = G_REAL_INFINITY) + { + btVector4 faceplane; + { + btVector3 dif1 = m_vertices[1] - m_vertices[0]; + btVector3 dif2 = m_vertices[2] - m_vertices[0]; + VEC_CROSS(faceplane,dif1,dif2); + faceplane[3] = m_vertices[0].dot(faceplane); + } + + GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax); + if(res != 1) return false; + + if(!is_point_inside(pout,faceplane)) return false; + + triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]); + + VEC_NORMALIZE(triangle_normal); + + return true; + } + +}; + + + + +#endif // GIM_TRI_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp new file mode 100644 index 0000000..940282f --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp @@ -0,0 +1,242 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btContinuousConvexCollision.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "LinearMath/btTransformUtil.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +#include "btGjkPairDetector.h" +#include "btPointCollector.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" + + + +btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver) +:m_simplexSolver(simplexSolver), +m_penetrationDepthSolver(penetrationDepthSolver), +m_convexA(convexA),m_convexB1(convexB),m_planeShape(0) +{ +} + + +btContinuousConvexCollision::btContinuousConvexCollision( const btConvexShape* convexA,const btStaticPlaneShape* plane) +:m_simplexSolver(0), +m_penetrationDepthSolver(0), +m_convexA(convexA),m_convexB1(0),m_planeShape(plane) +{ +} + + +/// This maximum should not be necessary. It allows for untested/degenerate cases in production code. +/// You don't want your game ever to lock-up. +#define MAX_ITERATIONS 64 + +void btContinuousConvexCollision::computeClosestPoints( const btTransform& transA, const btTransform& transB,btPointCollector& pointCollector) +{ + if (m_convexB1) + { + m_simplexSolver->reset(); + btGjkPairDetector gjk(m_convexA,m_convexB1,m_convexA->getShapeType(),m_convexB1->getShapeType(),m_convexA->getMargin(),m_convexB1->getMargin(),m_simplexSolver,m_penetrationDepthSolver); + btGjkPairDetector::ClosestPointInput input; + input.m_transformA = transA; + input.m_transformB = transB; + gjk.getClosestPoints(input,pointCollector,0); + } else + { + //convex versus plane + const btConvexShape* convexShape = m_convexA; + const btStaticPlaneShape* planeShape = m_planeShape; + + const btVector3& planeNormal = planeShape->getPlaneNormal(); + const btScalar& planeConstant = planeShape->getPlaneConstant(); + + btTransform convexWorldTransform = transA; + btTransform convexInPlaneTrans; + convexInPlaneTrans= transB.inverse() * convexWorldTransform; + btTransform planeInConvex; + planeInConvex= convexWorldTransform.inverse() * transB; + + btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); + + btVector3 vtxInPlane = convexInPlaneTrans(vtx); + btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); + + btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal; + btVector3 vtxInPlaneWorld = transB * vtxInPlaneProjected; + btVector3 normalOnSurfaceB = transB.getBasis() * planeNormal; + + pointCollector.addContactPoint( + normalOnSurfaceB, + vtxInPlaneWorld, + distance); + } +} + +bool btContinuousConvexCollision::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) +{ + + + /// compute linear and angular velocity for this interval, to interpolate + btVector3 linVelA,angVelA,linVelB,angVelB; + btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA); + btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB); + + + btScalar boundingRadiusA = m_convexA->getAngularMotionDisc(); + btScalar boundingRadiusB = m_convexB1?m_convexB1->getAngularMotionDisc():0.f; + + btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB; + btVector3 relLinVel = (linVelB-linVelA); + + btScalar relLinVelocLength = (linVelB-linVelA).length(); + + if ((relLinVelocLength+maxAngularProjectedVelocity) == 0.f) + return false; + + + + btScalar lambda = btScalar(0.); + btVector3 v(1,0,0); + + int maxIter = MAX_ITERATIONS; + + btVector3 n; + n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + bool hasResult = false; + btVector3 c; + + btScalar lastLambda = lambda; + //btScalar epsilon = btScalar(0.001); + + int numIter = 0; + //first solution, using GJK + + + btScalar radius = 0.001f; +// result.drawCoordSystem(sphereTr); + + btPointCollector pointCollector1; + + { + + computeClosestPoints(fromA,fromB,pointCollector1); + + hasResult = pointCollector1.m_hasResult; + c = pointCollector1.m_pointInWorld; + } + + if (hasResult) + { + btScalar dist; + dist = pointCollector1.m_distance + result.m_allowedPenetration; + n = pointCollector1.m_normalOnBInWorld; + btScalar projectedLinearVelocity = relLinVel.dot(n); + if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON) + return false; + + //not close enough + while (dist > radius) + { + if (result.m_debugDrawer) + { + result.m_debugDrawer->drawSphere(c,0.2f,btVector3(1,1,1)); + } + btScalar dLambda = btScalar(0.); + + projectedLinearVelocity = relLinVel.dot(n); + + + //don't report time of impact for motion away from the contact normal (or causes minor penetration) + if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON) + return false; + + dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity); + + + + lambda = lambda + dLambda; + + if (lambda > btScalar(1.)) + return false; + + if (lambda < btScalar(0.)) + return false; + + + //todo: next check with relative epsilon + if (lambda <= lastLambda) + { + return false; + //n.setValue(0,0,0); + break; + } + lastLambda = lambda; + + + + //interpolate to next lambda + btTransform interpolatedTransA,interpolatedTransB,relativeTrans; + + btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA); + btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB); + relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA); + + if (result.m_debugDrawer) + { + result.m_debugDrawer->drawSphere(interpolatedTransA.getOrigin(),0.2f,btVector3(1,0,0)); + } + + result.DebugDraw( lambda ); + + btPointCollector pointCollector; + computeClosestPoints(interpolatedTransA,interpolatedTransB,pointCollector); + + if (pointCollector.m_hasResult) + { + dist = pointCollector.m_distance+result.m_allowedPenetration; + c = pointCollector.m_pointInWorld; + n = pointCollector.m_normalOnBInWorld; + } else + { + result.reportFailure(-1, numIter); + return false; + } + + numIter++; + if (numIter > maxIter) + { + result.reportFailure(-2, numIter); + return false; + } + } + + result.m_fraction = lambda; + result.m_normal = n; + result.m_hitPoint = c; + return true; + } + + return false; + +} + diff --git a/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h new file mode 100644 index 0000000..bdc0572 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h @@ -0,0 +1,59 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_CONTINUOUS_COLLISION_CONVEX_CAST_H +#define BT_CONTINUOUS_COLLISION_CONVEX_CAST_H + +#include "btConvexCast.h" +#include "btSimplexSolverInterface.h" +class btConvexPenetrationDepthSolver; +class btConvexShape; +class btStaticPlaneShape; + +/// btContinuousConvexCollision implements angular and linear time of impact for convex objects. +/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis). +/// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent. +/// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops +class btContinuousConvexCollision : public btConvexCast +{ + btSimplexSolverInterface* m_simplexSolver; + btConvexPenetrationDepthSolver* m_penetrationDepthSolver; + const btConvexShape* m_convexA; + //second object is either a convex or a plane (code sharing) + const btConvexShape* m_convexB1; + const btStaticPlaneShape* m_planeShape; + + void computeClosestPoints( const btTransform& transA, const btTransform& transB,struct btPointCollector& pointCollector); + +public: + + btContinuousConvexCollision (const btConvexShape* shapeA,const btConvexShape* shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); + + btContinuousConvexCollision(const btConvexShape* shapeA,const btStaticPlaneShape* plane ); + + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); + + +}; + + +#endif //BT_CONTINUOUS_COLLISION_CONVEX_CAST_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp b/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp new file mode 100644 index 0000000..d2a1310 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp @@ -0,0 +1,20 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btConvexCast.h" + +btConvexCast::~btConvexCast() +{ +} diff --git a/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h b/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h new file mode 100644 index 0000000..bfd79d0 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h @@ -0,0 +1,73 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_CONVEX_CAST_H +#define BT_CONVEX_CAST_H + +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" +class btMinkowskiSumShape; +#include "LinearMath/btIDebugDraw.h" + +/// btConvexCast is an interface for Casting +class btConvexCast +{ +public: + + + virtual ~btConvexCast(); + + ///RayResult stores the closest result + /// alternatively, add a callback method to decide about closest/all results + struct CastResult + { + //virtual bool addRayResult(const btVector3& normal,btScalar fraction) = 0; + + virtual void DebugDraw(btScalar fraction) {(void)fraction;} + virtual void drawCoordSystem(const btTransform& trans) {(void)trans;} + virtual void reportFailure(int errNo, int numIterations) {(void)errNo;(void)numIterations;} + CastResult() + :m_fraction(btScalar(BT_LARGE_FLOAT)), + m_debugDrawer(0), + m_allowedPenetration(btScalar(0)) + { + } + + + virtual ~CastResult() {}; + + btTransform m_hitTransformA; + btTransform m_hitTransformB; + btVector3 m_normal; + btVector3 m_hitPoint; + btScalar m_fraction; //input and output + btIDebugDraw* m_debugDrawer; + btScalar m_allowedPenetration; + + }; + + + /// cast a convex against another convex object + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) = 0; +}; + +#endif //BT_CONVEX_CAST_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h b/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h new file mode 100644 index 0000000..72eb5ae --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h @@ -0,0 +1,42 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_CONVEX_PENETRATION_DEPTH_H +#define BT_CONVEX_PENETRATION_DEPTH_H + +class btStackAlloc; +class btVector3; +#include "btSimplexSolverInterface.h" +class btConvexShape; +class btTransform; + +///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation. +class btConvexPenetrationDepthSolver +{ +public: + + virtual ~btConvexPenetrationDepthSolver() {}; + virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, + const btConvexShape* convexA,const btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc + ) = 0; + + +}; +#endif //BT_CONVEX_PENETRATION_DEPTH_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h b/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h new file mode 100644 index 0000000..f958cc5 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h @@ -0,0 +1,91 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H +#define BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H + +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +class btStackAlloc; + +/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations +/// This interface allows to query for closest points and penetration depth between two (convex) objects +/// the closest point is on the second object (B), and the normal points from the surface on B towards A. +/// distance is between closest points on B and closest point on A. So you can calculate closest point on A +/// by taking closestPointInA = closestPointInB + m_distance * m_normalOnSurfaceB +struct btDiscreteCollisionDetectorInterface +{ + + struct Result + { + + virtual ~Result(){} + + ///setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material combiner + virtual void setShapeIdentifiersA(int partId0,int index0)=0; + virtual void setShapeIdentifiersB(int partId1,int index1)=0; + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)=0; + }; + + struct ClosestPointInput + { + ClosestPointInput() + :m_maximumDistanceSquared(btScalar(BT_LARGE_FLOAT)), + m_stackAlloc(0) + { + } + + btTransform m_transformA; + btTransform m_transformB; + btScalar m_maximumDistanceSquared; + btStackAlloc* m_stackAlloc; + }; + + virtual ~btDiscreteCollisionDetectorInterface() {}; + + // + // give either closest points (distance > 0) or penetration (distance) + // the normal always points from B towards A + // + virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false) = 0; + +}; + +struct btStorageResult : public btDiscreteCollisionDetectorInterface::Result +{ + btVector3 m_normalOnSurfaceB; + btVector3 m_closestPointInB; + btScalar m_distance; //negative means penetration ! + + btStorageResult() : m_distance(btScalar(BT_LARGE_FLOAT)) + { + + } + virtual ~btStorageResult() {}; + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + if (depth < m_distance) + { + m_normalOnSurfaceB = normalOnBInWorld; + m_closestPointInB = pointInWorld; + m_distance = depth; + } + } +}; + +#endif //BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp new file mode 100644 index 0000000..bef697a --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp @@ -0,0 +1,176 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btGjkConvexCast.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "btGjkPairDetector.h" +#include "btPointCollector.h" +#include "LinearMath/btTransformUtil.h" + +#ifdef BT_USE_DOUBLE_PRECISION +#define MAX_ITERATIONS 64 +#else +#define MAX_ITERATIONS 32 +#endif + +btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) +:m_simplexSolver(simplexSolver), +m_convexA(convexA), +m_convexB(convexB) +{ +} + +bool btGjkConvexCast::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) +{ + + + m_simplexSolver->reset(); + + /// compute linear velocity for this interval, to interpolate + //assume no rotation/angular velocity, assert here? + btVector3 linVelA,linVelB; + linVelA = toA.getOrigin()-fromA.getOrigin(); + linVelB = toB.getOrigin()-fromB.getOrigin(); + + btScalar radius = btScalar(0.001); + btScalar lambda = btScalar(0.); + btVector3 v(1,0,0); + + int maxIter = MAX_ITERATIONS; + + btVector3 n; + n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + bool hasResult = false; + btVector3 c; + btVector3 r = (linVelA-linVelB); + + btScalar lastLambda = lambda; + //btScalar epsilon = btScalar(0.001); + + int numIter = 0; + //first solution, using GJK + + + btTransform identityTrans; + identityTrans.setIdentity(); + + +// result.drawCoordSystem(sphereTr); + + btPointCollector pointCollector; + + + btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,0);//m_penetrationDepthSolver); + btGjkPairDetector::ClosestPointInput input; + + //we don't use margins during CCD + // gjk.setIgnoreMargin(true); + + input.m_transformA = fromA; + input.m_transformB = fromB; + gjk.getClosestPoints(input,pointCollector,0); + + hasResult = pointCollector.m_hasResult; + c = pointCollector.m_pointInWorld; + + if (hasResult) + { + btScalar dist; + dist = pointCollector.m_distance; + n = pointCollector.m_normalOnBInWorld; + + + + //not close enough + while (dist > radius) + { + numIter++; + if (numIter > maxIter) + { + return false; //todo: report a failure + } + btScalar dLambda = btScalar(0.); + + btScalar projectedLinearVelocity = r.dot(n); + + dLambda = dist / (projectedLinearVelocity); + + lambda = lambda - dLambda; + + if (lambda > btScalar(1.)) + return false; + + if (lambda < btScalar(0.)) + return false; + + //todo: next check with relative epsilon + if (lambda <= lastLambda) + { + return false; + //n.setValue(0,0,0); + break; + } + lastLambda = lambda; + + //interpolate to next lambda + result.DebugDraw( lambda ); + input.m_transformA.getOrigin().setInterpolate3(fromA.getOrigin(),toA.getOrigin(),lambda); + input.m_transformB.getOrigin().setInterpolate3(fromB.getOrigin(),toB.getOrigin(),lambda); + + gjk.getClosestPoints(input,pointCollector,0); + if (pointCollector.m_hasResult) + { + if (pointCollector.m_distance < btScalar(0.)) + { + result.m_fraction = lastLambda; + n = pointCollector.m_normalOnBInWorld; + result.m_normal=n; + result.m_hitPoint = pointCollector.m_pointInWorld; + return true; + } + c = pointCollector.m_pointInWorld; + n = pointCollector.m_normalOnBInWorld; + dist = pointCollector.m_distance; + } else + { + //?? + return false; + } + + } + + //is n normalized? + //don't report time of impact for motion away from the contact normal (or causes minor penetration) + if (n.dot(r)>=-result.m_allowedPenetration) + return false; + + result.m_fraction = lambda; + result.m_normal = n; + result.m_hitPoint = c; + return true; + } + + return false; + + +} + diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h new file mode 100644 index 0000000..6a42ee6 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h @@ -0,0 +1,50 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_GJK_CONVEX_CAST_H +#define BT_GJK_CONVEX_CAST_H + +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "LinearMath/btVector3.h" +#include "btConvexCast.h" +class btConvexShape; +class btMinkowskiSumShape; +#include "btSimplexSolverInterface.h" + +///GjkConvexCast performs a raycast on a convex object using support mapping. +class btGjkConvexCast : public btConvexCast +{ + btSimplexSolverInterface* m_simplexSolver; + const btConvexShape* m_convexA; + const btConvexShape* m_convexB; + +public: + + btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver); + + /// cast a convex against another convex object + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); + +}; + +#endif //BT_GJK_CONVEX_CAST_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp new file mode 100644 index 0000000..3268f06 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp @@ -0,0 +1,1031 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the +use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software in a +product, an acknowledgment in the product documentation would be appreciated +but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* +GJK-EPA collision solver by Nathanael Presson, 2008 +*/ +#include "BulletCollision/CollisionShapes/btConvexInternalShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "btGjkEpa2.h" + +#if defined(DEBUG) || defined (_DEBUG) +#include //for debug printf +#ifdef __SPU__ +#include +#define printf spu_printf +#endif //__SPU__ +#endif + +namespace gjkepa2_impl +{ + + // Config + + /* GJK */ +#define GJK_MAX_ITERATIONS 128 +#define GJK_ACCURARY ((btScalar)0.0001) +#define GJK_MIN_DISTANCE ((btScalar)0.0001) +#define GJK_DUPLICATED_EPS ((btScalar)0.0001) +#define GJK_SIMPLEX2_EPS ((btScalar)0.0) +#define GJK_SIMPLEX3_EPS ((btScalar)0.0) +#define GJK_SIMPLEX4_EPS ((btScalar)0.0) + + /* EPA */ +#define EPA_MAX_VERTICES 64 +#define EPA_MAX_FACES (EPA_MAX_VERTICES*2) +#define EPA_MAX_ITERATIONS 255 +#define EPA_ACCURACY ((btScalar)0.0001) +#define EPA_FALLBACK (10*EPA_ACCURACY) +#define EPA_PLANE_EPS ((btScalar)0.00001) +#define EPA_INSIDE_EPS ((btScalar)0.01) + + + // Shorthands + typedef unsigned int U; + typedef unsigned char U1; + + // MinkowskiDiff + struct MinkowskiDiff + { + const btConvexShape* m_shapes[2]; + btMatrix3x3 m_toshape1; + btTransform m_toshape0; +#ifdef __SPU__ + bool m_enableMargin; +#else + btVector3 (btConvexShape::*Ls)(const btVector3&) const; +#endif//__SPU__ + + + MinkowskiDiff() + { + + } +#ifdef __SPU__ + void EnableMargin(bool enable) + { + m_enableMargin = enable; + } + inline btVector3 Support0(const btVector3& d) const + { + if (m_enableMargin) + { + return m_shapes[0]->localGetSupportVertexNonVirtual(d); + } else + { + return m_shapes[0]->localGetSupportVertexWithoutMarginNonVirtual(d); + } + } + inline btVector3 Support1(const btVector3& d) const + { + if (m_enableMargin) + { + return m_toshape0*(m_shapes[1]->localGetSupportVertexNonVirtual(m_toshape1*d)); + } else + { + return m_toshape0*(m_shapes[1]->localGetSupportVertexWithoutMarginNonVirtual(m_toshape1*d)); + } + } +#else + void EnableMargin(bool enable) + { + if(enable) + Ls=&btConvexShape::localGetSupportVertexNonVirtual; + else + Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual; + } + inline btVector3 Support0(const btVector3& d) const + { + return(((m_shapes[0])->*(Ls))(d)); + } + inline btVector3 Support1(const btVector3& d) const + { + return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d)); + } +#endif //__SPU__ + + inline btVector3 Support(const btVector3& d) const + { + return(Support0(d)-Support1(-d)); + } + btVector3 Support(const btVector3& d,U index) const + { + if(index) + return(Support1(d)); + else + return(Support0(d)); + } + }; + + typedef MinkowskiDiff tShape; + + + // GJK + struct GJK + { + /* Types */ + struct sSV + { + btVector3 d,w; + }; + struct sSimplex + { + sSV* c[4]; + btScalar p[4]; + U rank; + }; + struct eStatus { enum _ { + Valid, + Inside, + Failed };}; + /* Fields */ + tShape m_shape; + btVector3 m_ray; + btScalar m_distance; + sSimplex m_simplices[2]; + sSV m_store[4]; + sSV* m_free[4]; + U m_nfree; + U m_current; + sSimplex* m_simplex; + eStatus::_ m_status; + /* Methods */ + GJK() + { + Initialize(); + } + void Initialize() + { + m_ray = btVector3(0,0,0); + m_nfree = 0; + m_status = eStatus::Failed; + m_current = 0; + m_distance = 0; + } + eStatus::_ Evaluate(const tShape& shapearg,const btVector3& guess) + { + U iterations=0; + btScalar sqdist=0; + btScalar alpha=0; + btVector3 lastw[4]; + U clastw=0; + /* Initialize solver */ + m_free[0] = &m_store[0]; + m_free[1] = &m_store[1]; + m_free[2] = &m_store[2]; + m_free[3] = &m_store[3]; + m_nfree = 4; + m_current = 0; + m_status = eStatus::Valid; + m_shape = shapearg; + m_distance = 0; + /* Initialize simplex */ + m_simplices[0].rank = 0; + m_ray = guess; + const btScalar sqrl= m_ray.length2(); + appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0)); + m_simplices[0].p[0] = 1; + m_ray = m_simplices[0].c[0]->w; + sqdist = sqrl; + lastw[0] = + lastw[1] = + lastw[2] = + lastw[3] = m_ray; + /* Loop */ + do { + const U next=1-m_current; + sSimplex& cs=m_simplices[m_current]; + sSimplex& ns=m_simplices[next]; + /* Check zero */ + const btScalar rl=m_ray.length(); + if(rlw; + bool found=false; + for(U i=0;i<4;++i) + { + if((w-lastw[i]).length2()w, + cs.c[1]->w, + weights,mask);break; + case 3: sqdist=projectorigin( cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + weights,mask);break; + case 4: sqdist=projectorigin( cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + cs.c[3]->w, + weights,mask);break; + } + if(sqdist>=0) + {/* Valid */ + ns.rank = 0; + m_ray = btVector3(0,0,0); + m_current = next; + for(U i=0,ni=cs.rank;iw*weights[i]; + } + else + { + m_free[m_nfree++] = cs.c[i]; + } + } + if(mask==15) m_status=eStatus::Inside; + } + else + {/* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + m_status=((++iterations)rank) + { + case 1: + { + for(U i=0;i<3;++i) + { + btVector3 axis=btVector3(0,0,0); + axis[i]=1; + appendvertice(*m_simplex, axis); + if(EncloseOrigin()) return(true); + removevertice(*m_simplex); + appendvertice(*m_simplex,-axis); + if(EncloseOrigin()) return(true); + removevertice(*m_simplex); + } + } + break; + case 2: + { + const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w; + for(U i=0;i<3;++i) + { + btVector3 axis=btVector3(0,0,0); + axis[i]=1; + const btVector3 p=btCross(d,axis); + if(p.length2()>0) + { + appendvertice(*m_simplex, p); + if(EncloseOrigin()) return(true); + removevertice(*m_simplex); + appendvertice(*m_simplex,-p); + if(EncloseOrigin()) return(true); + removevertice(*m_simplex); + } + } + } + break; + case 3: + { + const btVector3 n=btCross(m_simplex->c[1]->w-m_simplex->c[0]->w, + m_simplex->c[2]->w-m_simplex->c[0]->w); + if(n.length2()>0) + { + appendvertice(*m_simplex,n); + if(EncloseOrigin()) return(true); + removevertice(*m_simplex); + appendvertice(*m_simplex,-n); + if(EncloseOrigin()) return(true); + removevertice(*m_simplex); + } + } + break; + case 4: + { + if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, + m_simplex->c[1]->w-m_simplex->c[3]->w, + m_simplex->c[2]->w-m_simplex->c[3]->w))>0) + return(true); + } + break; + } + return(false); + } + /* Internals */ + void getsupport(const btVector3& d,sSV& sv) const + { + sv.d = d/d.length(); + sv.w = m_shape.Support(sv.d); + } + void removevertice(sSimplex& simplex) + { + m_free[m_nfree++]=simplex.c[--simplex.rank]; + } + void appendvertice(sSimplex& simplex,const btVector3& v) + { + simplex.p[simplex.rank]=0; + simplex.c[simplex.rank]=m_free[--m_nfree]; + getsupport(v,*simplex.c[simplex.rank++]); + } + static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c) + { + return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()- + a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+ + a.x()*b.y()*c.z()-a.z()*b.y()*c.x()); + } + static btScalar projectorigin( const btVector3& a, + const btVector3& b, + btScalar* w,U& m) + { + const btVector3 d=b-a; + const btScalar l=d.length2(); + if(l>GJK_SIMPLEX2_EPS) + { + const btScalar t(l>0?-btDot(a,d)/l:0); + if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); } + else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); } + else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); } + } + return(-1); + } + static btScalar projectorigin( const btVector3& a, + const btVector3& b, + const btVector3& c, + btScalar* w,U& m) + { + static const U imd3[]={1,2,0}; + const btVector3* vt[]={&a,&b,&c}; + const btVector3 dl[]={a-b,b-c,c-a}; + const btVector3 n=btCross(dl[0],dl[1]); + const btScalar l=n.length2(); + if(l>GJK_SIMPLEX3_EPS) + { + btScalar mindist=-1; + btScalar subw[2]={0.f,0.f}; + U subm(0); + for(U i=0;i<3;++i) + { + if(btDot(*vt[i],btCross(dl[i],n))>0) + { + const U j=imd3[i]; + const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm)); + if((mindist<0)||(subd(((subm&1)?1<GJK_SIMPLEX4_EPS)) + { + btScalar mindist=-1; + btScalar subw[3]={0.f,0.f,0.f}; + U subm(0); + for(U i=0;i<3;++i) + { + const U j=imd3[i]; + const btScalar s=vl*btDot(d,btCross(dl[i],dl[j])); + if(s>0) + { + const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm); + if((mindist<0)||(subd((subm&1?1<e[ea]=(U1)eb;fa->f[ea]=fb; + fb->e[eb]=(U1)ea;fb->f[eb]=fa; + } + static inline void append(sList& list,sFace* face) + { + face->l[0] = 0; + face->l[1] = list.root; + if(list.root) list.root->l[0]=face; + list.root = face; + ++list.count; + } + static inline void remove(sList& list,sFace* face) + { + if(face->l[1]) face->l[1]->l[0]=face->l[0]; + if(face->l[0]) face->l[0]->l[1]=face->l[1]; + if(face==list.root) list.root=face->l[1]; + --list.count; + } + + + void Initialize() + { + m_status = eStatus::Failed; + m_normal = btVector3(0,0,0); + m_depth = 0; + m_nextsv = 0; + for(U i=0;i1)&&gjk.EncloseOrigin()) + { + + /* Clean up */ + while(m_hull.root) + { + sFace* f = m_hull.root; + remove(m_hull,f); + append(m_stock,f); + } + m_status = eStatus::Valid; + m_nextsv = 0; + /* Orient simplex */ + if(gjk.det( simplex.c[0]->w-simplex.c[3]->w, + simplex.c[1]->w-simplex.c[3]->w, + simplex.c[2]->w-simplex.c[3]->w)<0) + { + btSwap(simplex.c[0],simplex.c[1]); + btSwap(simplex.p[0],simplex.p[1]); + } + /* Build initial hull */ + sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true), + newface(simplex.c[1],simplex.c[0],simplex.c[3],true), + newface(simplex.c[2],simplex.c[1],simplex.c[3],true), + newface(simplex.c[0],simplex.c[2],simplex.c[3],true)}; + if(m_hull.count==4) + { + sFace* best=findbest(); + sFace outer=*best; + U pass=0; + U iterations=0; + bind(tetra[0],0,tetra[1],0); + bind(tetra[0],1,tetra[2],0); + bind(tetra[0],2,tetra[3],0); + bind(tetra[1],1,tetra[3],2); + bind(tetra[1],2,tetra[2],1); + bind(tetra[2],2,tetra[3],1); + m_status=eStatus::Valid; + for(;iterationspass = (U1)(++pass); + gjk.getsupport(best->n,*w); + const btScalar wdist=btDot(best->n,w->w)-best->d; + if(wdist>EPA_ACCURACY) + { + for(U j=0;(j<3)&&valid;++j) + { + valid&=expand( pass,w, + best->f[j],best->e[j], + horizon); + } + if(valid&&(horizon.nf>=3)) + { + bind(horizon.cf,1,horizon.ff,2); + remove(m_hull,best); + append(m_stock,best); + best=findbest(); + outer=*best; + } else { m_status=eStatus::InvalidHull;break; } + } else { m_status=eStatus::AccuraryReached;break; } + } else { m_status=eStatus::OutOfVertices;break; } + } + const btVector3 projection=outer.n*outer.d; + m_normal = outer.n; + m_depth = outer.d; + m_result.rank = 3; + m_result.c[0] = outer.c[0]; + m_result.c[1] = outer.c[1]; + m_result.c[2] = outer.c[2]; + m_result.p[0] = btCross( outer.c[1]->w-projection, + outer.c[2]->w-projection).length(); + m_result.p[1] = btCross( outer.c[2]->w-projection, + outer.c[0]->w-projection).length(); + m_result.p[2] = btCross( outer.c[0]->w-projection, + outer.c[1]->w-projection).length(); + const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2]; + m_result.p[0] /= sum; + m_result.p[1] /= sum; + m_result.p[2] /= sum; + return(m_status); + } + } + /* Fallback */ + m_status = eStatus::FallBack; + m_normal = -guess; + const btScalar nl=m_normal.length(); + if(nl>0) + m_normal = m_normal/nl; + else + m_normal = btVector3(1,0,0); + m_depth = 0; + m_result.rank=1; + m_result.c[0]=simplex.c[0]; + m_result.p[0]=1; + return(m_status); + } + bool getedgedist(sFace* face, sSV* a, sSV* b, btScalar& dist) + { + const btVector3 ba = b->w - a->w; + const btVector3 n_ab = btCross(ba, face->n); // Outward facing edge normal direction, on triangle plane + const btScalar a_dot_nab = btDot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required + + if(a_dot_nab < 0) + { + // Outside of edge a->b + + const btScalar ba_l2 = ba.length2(); + const btScalar a_dot_ba = btDot(a->w, ba); + const btScalar b_dot_ba = btDot(b->w, ba); + + if(a_dot_ba > 0) + { + // Pick distance vertex a + dist = a->w.length(); + } + else if(b_dot_ba < 0) + { + // Pick distance vertex b + dist = b->w.length(); + } + else + { + // Pick distance to edge a->b + const btScalar a_dot_b = btDot(a->w, b->w); + dist = btSqrt(btMax((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (btScalar)0)); + } + + return true; + } + + return false; + } + sFace* newface(sSV* a,sSV* b,sSV* c,bool forced) + { + if(m_stock.root) + { + sFace* face=m_stock.root; + remove(m_stock,face); + append(m_hull,face); + face->pass = 0; + face->c[0] = a; + face->c[1] = b; + face->c[2] = c; + face->n = btCross(b->w-a->w,c->w-a->w); + const btScalar l=face->n.length(); + const bool v=l>EPA_ACCURACY; + + if(v) + { + if(!(getedgedist(face, a, b, face->d) || + getedgedist(face, b, c, face->d) || + getedgedist(face, c, a, face->d))) + { + // Origin projects to the interior of the triangle + // Use distance to triangle plane + face->d = btDot(a->w, face->n) / l; + } + + face->n /= l; + if(forced || (face->d >= -EPA_PLANE_EPS)) + { + return face; + } + else + m_status=eStatus::NonConvex; + } + else + m_status=eStatus::Degenerated; + + remove(m_hull, face); + append(m_stock, face); + return 0; + + } + m_status = m_stock.root ? eStatus::OutOfVertices : eStatus::OutOfFaces; + return 0; + } + sFace* findbest() + { + sFace* minf=m_hull.root; + btScalar mind=minf->d*minf->d; + for(sFace* f=minf->l[1];f;f=f->l[1]) + { + const btScalar sqd=f->d*f->d; + if(sqdpass!=pass) + { + const U e1=i1m3[e]; + if((btDot(f->n,w->w)-f->d)<-EPA_PLANE_EPS) + { + sFace* nf=newface(f->c[e1],f->c[e],w,false); + if(nf) + { + bind(nf,0,f,e); + if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf; + horizon.cf=nf; + ++horizon.nf; + return(true); + } + } + else + { + const U e2=i2m3[e]; + f->pass = (U1)pass; + if( expand(pass,w,f->f[e1],f->e[e1],horizon)&& + expand(pass,w,f->f[e2],f->e[e2],horizon)) + { + remove(m_hull,f); + append(m_stock,f); + return(true); + } + } + } + return(false); + } + + }; + + // + static void Initialize( const btConvexShape* shape0,const btTransform& wtrs0, + const btConvexShape* shape1,const btTransform& wtrs1, + btGjkEpaSolver2::sResults& results, + tShape& shape, + bool withmargins) + { + /* Results */ + results.witnesses[0] = + results.witnesses[1] = btVector3(0,0,0); + results.status = btGjkEpaSolver2::sResults::Separated; + /* Shape */ + shape.m_shapes[0] = shape0; + shape.m_shapes[1] = shape1; + shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis()); + shape.m_toshape0 = wtrs0.inverseTimes(wtrs1); + shape.EnableMargin(withmargins); + } + +} + +// +// Api +// + +using namespace gjkepa2_impl; + +// +int btGjkEpaSolver2::StackSizeRequirement() +{ + return(sizeof(GJK)+sizeof(EPA)); +} + +// +bool btGjkEpaSolver2::Distance( const btConvexShape* shape0, + const btTransform& wtrs0, + const btConvexShape* shape1, + const btTransform& wtrs1, + const btVector3& guess, + sResults& results) +{ + tShape shape; + Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false); + GJK gjk; + GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess); + if(gjk_status==GJK::eStatus::Valid) + { + btVector3 w0=btVector3(0,0,0); + btVector3 w1=btVector3(0,0,0); + for(U i=0;irank;++i) + { + const btScalar p=gjk.m_simplex->p[i]; + w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; + w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; + } + results.witnesses[0] = wtrs0*w0; + results.witnesses[1] = wtrs0*w1; + results.normal = w0-w1; + results.distance = results.normal.length(); + results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1; + return(true); + } + else + { + results.status = gjk_status==GJK::eStatus::Inside? + sResults::Penetrating : + sResults::GJK_Failed ; + return(false); + } +} + +// +bool btGjkEpaSolver2::Penetration( const btConvexShape* shape0, + const btTransform& wtrs0, + const btConvexShape* shape1, + const btTransform& wtrs1, + const btVector3& guess, + sResults& results, + bool usemargins) +{ + tShape shape; + Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins); + GJK gjk; + GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess); + switch(gjk_status) + { + case GJK::eStatus::Inside: + { + EPA epa; + EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess); + if(epa_status!=EPA::eStatus::Failed) + { + btVector3 w0=btVector3(0,0,0); + for(U i=0;id,0)*epa.m_result.p[i]; + } + results.status = sResults::Penetrating; + results.witnesses[0] = wtrs0*w0; + results.witnesses[1] = wtrs0*(w0-epa.m_normal*epa.m_depth); + results.normal = -epa.m_normal; + results.distance = -epa.m_depth; + return(true); + } else results.status=sResults::EPA_Failed; + } + break; + case GJK::eStatus::Failed: + results.status=sResults::GJK_Failed; + break; + default: + { + } + } + return(false); +} + +#ifndef __SPU__ +// +btScalar btGjkEpaSolver2::SignedDistance(const btVector3& position, + btScalar margin, + const btConvexShape* shape0, + const btTransform& wtrs0, + sResults& results) +{ + tShape shape; + btSphereShape shape1(margin); + btTransform wtrs1(btQuaternion(0,0,0,1),position); + Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false); + GJK gjk; + GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,btVector3(1,1,1)); + if(gjk_status==GJK::eStatus::Valid) + { + btVector3 w0=btVector3(0,0,0); + btVector3 w1=btVector3(0,0,0); + for(U i=0;irank;++i) + { + const btScalar p=gjk.m_simplex->p[i]; + w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; + w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; + } + results.witnesses[0] = wtrs0*w0; + results.witnesses[1] = wtrs0*w1; + const btVector3 delta= results.witnesses[1]- + results.witnesses[0]; + const btScalar margin= shape0->getMarginNonVirtual()+ + shape1.getMarginNonVirtual(); + const btScalar length= delta.length(); + results.normal = delta/length; + results.witnesses[0] += results.normal*margin; + return(length-margin); + } + else + { + if(gjk_status==GJK::eStatus::Inside) + { + if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results)) + { + const btVector3 delta= results.witnesses[0]- + results.witnesses[1]; + const btScalar length= delta.length(); + if (length >= SIMD_EPSILON) + results.normal = delta/length; + return(-length); + } + } + } + return(SIMD_INFINITY); +} + +// +bool btGjkEpaSolver2::SignedDistance(const btConvexShape* shape0, + const btTransform& wtrs0, + const btConvexShape* shape1, + const btTransform& wtrs1, + const btVector3& guess, + sResults& results) +{ + if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results)) + return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false)); + else + return(true); +} +#endif //__SPU__ + +/* Symbols cleanup */ + +#undef GJK_MAX_ITERATIONS +#undef GJK_ACCURARY +#undef GJK_MIN_DISTANCE +#undef GJK_DUPLICATED_EPS +#undef GJK_SIMPLEX2_EPS +#undef GJK_SIMPLEX3_EPS +#undef GJK_SIMPLEX4_EPS + +#undef EPA_MAX_VERTICES +#undef EPA_MAX_FACES +#undef EPA_MAX_ITERATIONS +#undef EPA_ACCURACY +#undef EPA_FALLBACK +#undef EPA_PLANE_EPS +#undef EPA_INSIDE_EPS diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h new file mode 100644 index 0000000..ac501d5 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h @@ -0,0 +1,75 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the +use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software in a +product, an acknowledgment in the product documentation would be appreciated +but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* +GJK-EPA collision solver by Nathanael Presson, 2008 +*/ +#ifndef BT_GJK_EPA2_H +#define BT_GJK_EPA2_H + +#include "BulletCollision/CollisionShapes/btConvexShape.h" + +///btGjkEpaSolver contributed under zlib by Nathanael Presson +struct btGjkEpaSolver2 +{ +struct sResults + { + enum eStatus + { + Separated, /* Shapes doesnt penetrate */ + Penetrating, /* Shapes are penetrating */ + GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ + EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */ + } status; + btVector3 witnesses[2]; + btVector3 normal; + btScalar distance; + }; + +static int StackSizeRequirement(); + +static bool Distance( const btConvexShape* shape0,const btTransform& wtrs0, + const btConvexShape* shape1,const btTransform& wtrs1, + const btVector3& guess, + sResults& results); + +static bool Penetration(const btConvexShape* shape0,const btTransform& wtrs0, + const btConvexShape* shape1,const btTransform& wtrs1, + const btVector3& guess, + sResults& results, + bool usemargins=true); +#ifndef __SPU__ +static btScalar SignedDistance( const btVector3& position, + btScalar margin, + const btConvexShape* shape, + const btTransform& wtrs, + sResults& results); + +static bool SignedDistance( const btConvexShape* shape0,const btTransform& wtrs0, + const btConvexShape* shape1,const btTransform& wtrs1, + const btVector3& guess, + sResults& results); +#endif //__SPU__ + +}; + +#endif //BT_GJK_EPA2_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp new file mode 100644 index 0000000..c6dc3f3 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp @@ -0,0 +1,66 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +EPA Copyright (c) Ricardo Padrela 2006 + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "btGjkEpaPenetrationDepthSolver.h" + + +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" + +bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver, + const btConvexShape* pConvexA, const btConvexShape* pConvexB, + const btTransform& transformA, const btTransform& transformB, + btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, + class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc ) +{ + + (void)debugDraw; + (void)v; + (void)simplexSolver; + +// const btScalar radialmargin(btScalar(0.)); + + btVector3 guessVector(transformA.getOrigin()-transformB.getOrigin()); + btGjkEpaSolver2::sResults results; + + + if(btGjkEpaSolver2::Penetration(pConvexA,transformA, + pConvexB,transformB, + guessVector,results)) + + { + // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); + //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); + wWitnessOnA = results.witnesses[0]; + wWitnessOnB = results.witnesses[1]; + v = results.normal; + return true; + } else + { + if(btGjkEpaSolver2::Distance(pConvexA,transformA,pConvexB,transformB,guessVector,results)) + { + wWitnessOnA = results.witnesses[0]; + wWitnessOnB = results.witnesses[1]; + v = results.normal; + return false; + } + } + + return false; +} + + diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h new file mode 100644 index 0000000..a49689a --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h @@ -0,0 +1,43 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +EPA Copyright (c) Ricardo Padrela 2006 + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_GJP_EPA_PENETRATION_DEPTH_H +#define BT_GJP_EPA_PENETRATION_DEPTH_H + +#include "btConvexPenetrationDepthSolver.h" + +///EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to +///calculate the penetration depth between two convex shapes. +class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver +{ + public : + + btGjkEpaPenetrationDepthSolver() + { + } + + bool calcPenDepth( btSimplexSolverInterface& simplexSolver, + const btConvexShape* pConvexA, const btConvexShape* pConvexB, + const btTransform& transformA, const btTransform& transformB, + btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc ); + + private : + +}; + +#endif // BT_GJP_EPA_PENETRATION_DEPTH_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp new file mode 100644 index 0000000..8af16b9 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp @@ -0,0 +1,457 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btGjkPairDetector.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" + + + +#if defined(DEBUG) || defined (_DEBUG) +//#define TEST_NON_VIRTUAL 1 +#include //for debug printf +#ifdef __SPU__ +#include +#define printf spu_printf +//#define DEBUG_SPU_COLLISION_DETECTION 1 +#endif //__SPU__ +#endif + +//must be above the machine epsilon +#define REL_ERROR2 btScalar(1.0e-6) + +//temp globals, to improve GJK/EPA/penetration calculations +int gNumDeepPenetrationChecks = 0; +int gNumGjkChecks = 0; + + +btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) +:m_cachedSeparatingAxis(btScalar(0.),btScalar(1.),btScalar(0.)), +m_penetrationDepthSolver(penetrationDepthSolver), +m_simplexSolver(simplexSolver), +m_minkowskiA(objectA), +m_minkowskiB(objectB), +m_shapeTypeA(objectA->getShapeType()), +m_shapeTypeB(objectB->getShapeType()), +m_marginA(objectA->getMargin()), +m_marginB(objectB->getMargin()), +m_ignoreMargin(false), +m_lastUsedMethod(-1), +m_catchDegeneracies(1) +{ +} +btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) +:m_cachedSeparatingAxis(btScalar(0.),btScalar(1.),btScalar(0.)), +m_penetrationDepthSolver(penetrationDepthSolver), +m_simplexSolver(simplexSolver), +m_minkowskiA(objectA), +m_minkowskiB(objectB), +m_shapeTypeA(shapeTypeA), +m_shapeTypeB(shapeTypeB), +m_marginA(marginA), +m_marginB(marginB), +m_ignoreMargin(false), +m_lastUsedMethod(-1), +m_catchDegeneracies(1) +{ +} + +void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults) +{ + (void)swapResults; + + getClosestPointsNonVirtual(input,output,debugDraw); +} + +#ifdef __SPU__ +void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) +#else +void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) +#endif +{ + m_cachedSeparatingDistance = 0.f; + + btScalar distance=btScalar(0.); + btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 pointOnA,pointOnB; + btTransform localTransA = input.m_transformA; + btTransform localTransB = input.m_transformB; + btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5); + localTransA.getOrigin() -= positionOffset; + localTransB.getOrigin() -= positionOffset; + + bool check2d = m_minkowskiA->isConvex2d() && m_minkowskiB->isConvex2d(); + + btScalar marginA = m_marginA; + btScalar marginB = m_marginB; + + gNumGjkChecks++; + +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("inside gjk\n"); +#endif + //for CCD we don't use margins + if (m_ignoreMargin) + { + marginA = btScalar(0.); + marginB = btScalar(0.); +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("ignoring margin\n"); +#endif + } + + m_curIter = 0; + int gGjkMaxIter = 1000;//this is to catch invalid input, perhaps check for #NaN? + m_cachedSeparatingAxis.setValue(0,1,0); + + bool isValid = false; + bool checkSimplex = false; + bool checkPenetration = true; + m_degenerateSimplex = 0; + + m_lastUsedMethod = -1; + + { + btScalar squaredDistance = BT_LARGE_FLOAT; + btScalar delta = btScalar(0.); + + btScalar margin = marginA + marginB; + + + + m_simplexSolver->reset(); + + for ( ; ; ) + //while (true) + { + + btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis(); + btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis(); + +#if 1 + + btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); + btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); + +// btVector3 pInA = localGetSupportingVertexWithoutMargin(m_shapeTypeA, m_minkowskiA, seperatingAxisInA,input.m_convexVertexData[0]);//, &featureIndexA); +// btVector3 qInB = localGetSupportingVertexWithoutMargin(m_shapeTypeB, m_minkowskiB, seperatingAxisInB,input.m_convexVertexData[1]);//, &featureIndexB); + +#else +#ifdef __SPU__ + btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); + btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); +#else + btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA); + btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); +#ifdef TEST_NON_VIRTUAL + btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA); + btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); + btAssert((pInAv-pInA).length() < 0.0001); + btAssert((qInBv-qInB).length() < 0.0001); +#endif // +#endif //__SPU__ +#endif + + + btVector3 pWorld = localTransA(pInA); + btVector3 qWorld = localTransB(qInB); + +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("got local supporting vertices\n"); +#endif + + if (check2d) + { + pWorld[2] = 0.f; + qWorld[2] = 0.f; + } + + btVector3 w = pWorld - qWorld; + delta = m_cachedSeparatingAxis.dot(w); + + // potential exit, they don't overlap + if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared)) + { + m_degenerateSimplex = 10; + checkSimplex=true; + //checkPenetration = false; + break; + } + + //exit 0: the new point is already in the simplex, or we didn't come any closer + if (m_simplexSolver->inSimplex(w)) + { + m_degenerateSimplex = 1; + checkSimplex = true; + break; + } + // are we getting any closer ? + btScalar f0 = squaredDistance - delta; + btScalar f1 = squaredDistance * REL_ERROR2; + + if (f0 <= f1) + { + if (f0 <= btScalar(0.)) + { + m_degenerateSimplex = 2; + } else + { + m_degenerateSimplex = 11; + } + checkSimplex = true; + break; + } + +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("addVertex 1\n"); +#endif + //add current vertex to simplex + m_simplexSolver->addVertex(w, pWorld, qWorld); +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("addVertex 2\n"); +#endif + btVector3 newCachedSeparatingAxis; + + //calculate the closest point to the origin (update vector v) + if (!m_simplexSolver->closest(newCachedSeparatingAxis)) + { + m_degenerateSimplex = 3; + checkSimplex = true; + break; + } + + if(newCachedSeparatingAxis.length2()previousSquaredDistance) + { + m_degenerateSimplex = 7; + squaredDistance = previousSquaredDistance; + checkSimplex = false; + break; + } +#endif // + + + //redundant m_simplexSolver->compute_points(pointOnA, pointOnB); + + //are we getting any closer ? + if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance) + { +// m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + checkSimplex = true; + m_degenerateSimplex = 12; + + break; + } + + m_cachedSeparatingAxis = newCachedSeparatingAxis; + + //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject + if (m_curIter++ > gGjkMaxIter) + { + #if defined(DEBUG) || defined (_DEBUG) || defined (DEBUG_SPU_COLLISION_DETECTION) + + printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter); + printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n", + m_cachedSeparatingAxis.getX(), + m_cachedSeparatingAxis.getY(), + m_cachedSeparatingAxis.getZ(), + squaredDistance, + m_minkowskiA->getShapeType(), + m_minkowskiB->getShapeType()); + + #endif + break; + + } + + + bool check = (!m_simplexSolver->fullSimplex()); + //bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex()); + + if (!check) + { + //do we need this backup_closest here ? +// m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + m_degenerateSimplex = 13; + break; + } + } + + if (checkSimplex) + { + m_simplexSolver->compute_points(pointOnA, pointOnB); + normalInB = m_cachedSeparatingAxis; + btScalar lenSqr =m_cachedSeparatingAxis.length2(); + + //valid normal + if (lenSqr < 0.0001) + { + m_degenerateSimplex = 5; + } + if (lenSqr > SIMD_EPSILON*SIMD_EPSILON) + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + normalInB *= rlen; //normalize + btScalar s = btSqrt(squaredDistance); + + btAssert(s > btScalar(0.0)); + pointOnA -= m_cachedSeparatingAxis * (marginA / s); + pointOnB += m_cachedSeparatingAxis * (marginB / s); + distance = ((btScalar(1.)/rlen) - margin); + isValid = true; + + m_lastUsedMethod = 1; + } else + { + m_lastUsedMethod = 2; + } + } + + bool catchDegeneratePenetrationCase = + (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < 0.01)); + + //if (checkPenetration && !isValid) + if (checkPenetration && (!isValid || catchDegeneratePenetrationCase )) + { + //penetration case + + //if there is no way to handle penetrations, bail out + if (m_penetrationDepthSolver) + { + // Penetration depth case. + btVector3 tmpPointOnA,tmpPointOnB; + + gNumDeepPenetrationChecks++; + m_cachedSeparatingAxis.setZero(); + + bool isValid2 = m_penetrationDepthSolver->calcPenDepth( + *m_simplexSolver, + m_minkowskiA,m_minkowskiB, + localTransA,localTransB, + m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB, + debugDraw,input.m_stackAlloc + ); + + + if (isValid2) + { + btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA; + btScalar lenSqr = tmpNormalInB.length2(); + if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON)) + { + tmpNormalInB = m_cachedSeparatingAxis; + lenSqr = m_cachedSeparatingAxis.length2(); + } + + if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON)) + { + tmpNormalInB /= btSqrt(lenSqr); + btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length(); + //only replace valid penetrations when the result is deeper (check) + if (!isValid || (distance2 < distance)) + { + distance = distance2; + pointOnA = tmpPointOnA; + pointOnB = tmpPointOnB; + normalInB = tmpNormalInB; + isValid = true; + m_lastUsedMethod = 3; + } else + { + m_lastUsedMethod = 8; + } + } else + { + m_lastUsedMethod = 9; + } + } else + + { + ///this is another degenerate case, where the initial GJK calculation reports a degenerate case + ///EPA reports no penetration, and the second GJK (using the supporting vector without margin) + ///reports a valid positive distance. Use the results of the second GJK instead of failing. + ///thanks to Jacob.Langford for the reproduction case + ///http://code.google.com/p/bullet/issues/detail?id=250 + + + if (m_cachedSeparatingAxis.length2() > btScalar(0.)) + { + btScalar distance2 = (tmpPointOnA-tmpPointOnB).length()-margin; + //only replace valid distances when the distance is less + if (!isValid || (distance2 < distance)) + { + distance = distance2; + pointOnA = tmpPointOnA; + pointOnB = tmpPointOnB; + pointOnA -= m_cachedSeparatingAxis * marginA ; + pointOnB += m_cachedSeparatingAxis * marginB ; + normalInB = m_cachedSeparatingAxis; + normalInB.normalize(); + isValid = true; + m_lastUsedMethod = 6; + } else + { + m_lastUsedMethod = 5; + } + } + } + + } + + } + } + + + + if (isValid && ((distance < 0) || (distance*distance < input.m_maximumDistanceSquared))) + { +#if 0 +///some debugging +// if (check2d) + { + printf("n = %2.3f,%2.3f,%2.3f. ",normalInB[0],normalInB[1],normalInB[2]); + printf("distance = %2.3f exit=%d deg=%d\n",distance,m_lastUsedMethod,m_degenerateSimplex); + } +#endif + + m_cachedSeparatingAxis = normalInB; + m_cachedSeparatingDistance = distance; + + output.addContactPoint( + normalInB, + pointOnB+positionOffset, + distance); + + } + + +} + + + + + diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h new file mode 100644 index 0000000..f0043b8 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h @@ -0,0 +1,103 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + + +#ifndef BT_GJK_PAIR_DETECTOR_H +#define BT_GJK_PAIR_DETECTOR_H + +#include "btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +class btConvexShape; +#include "btSimplexSolverInterface.h" +class btConvexPenetrationDepthSolver; + +/// btGjkPairDetector uses GJK to implement the btDiscreteCollisionDetectorInterface +class btGjkPairDetector : public btDiscreteCollisionDetectorInterface +{ + + + btVector3 m_cachedSeparatingAxis; + btConvexPenetrationDepthSolver* m_penetrationDepthSolver; + btSimplexSolverInterface* m_simplexSolver; + const btConvexShape* m_minkowskiA; + const btConvexShape* m_minkowskiB; + int m_shapeTypeA; + int m_shapeTypeB; + btScalar m_marginA; + btScalar m_marginB; + + bool m_ignoreMargin; + btScalar m_cachedSeparatingDistance; + + +public: + + //some debugging to fix degeneracy problems + int m_lastUsedMethod; + int m_curIter; + int m_degenerateSimplex; + int m_catchDegeneracies; + + + btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); + btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); + virtual ~btGjkPairDetector() {}; + + virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false); + + void getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw); + + + void setMinkowskiA(const btConvexShape* minkA) + { + m_minkowskiA = minkA; + } + + void setMinkowskiB(const btConvexShape* minkB) + { + m_minkowskiB = minkB; + } + void setCachedSeperatingAxis(const btVector3& seperatingAxis) + { + m_cachedSeparatingAxis = seperatingAxis; + } + + const btVector3& getCachedSeparatingAxis() const + { + return m_cachedSeparatingAxis; + } + btScalar getCachedSeparatingDistance() const + { + return m_cachedSeparatingDistance; + } + + void setPenetrationDepthSolver(btConvexPenetrationDepthSolver* penetrationDepthSolver) + { + m_penetrationDepthSolver = penetrationDepthSolver; + } + + ///don't use setIgnoreMargin, it's for Bullet's internal use + void setIgnoreMargin(bool ignoreMargin) + { + m_ignoreMargin = ignoreMargin; + } + + +}; + +#endif //BT_GJK_PAIR_DETECTOR_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h new file mode 100644 index 0000000..e40fb1d --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h @@ -0,0 +1,156 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_MANIFOLD_CONTACT_POINT_H +#define BT_MANIFOLD_CONTACT_POINT_H + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransformUtil.h" + +#ifdef PFX_USE_FREE_VECTORMATH + #include "physics_effects/base_level/solver/pfx_constraint_row.h" +typedef sce::PhysicsEffects::PfxConstraintRow btConstraintRow; +#else + // Don't change following order of parameters + ATTRIBUTE_ALIGNED16(struct) btConstraintRow { + btScalar m_normal[3]; + btScalar m_rhs; + btScalar m_jacDiagInv; + btScalar m_lowerLimit; + btScalar m_upperLimit; + btScalar m_accumImpulse; + }; + typedef btConstraintRow PfxConstraintRow; +#endif //PFX_USE_FREE_VECTORMATH + + + +/// ManifoldContactPoint collects and maintains persistent contactpoints. +/// used to improve stability and performance of rigidbody dynamics response. +class btManifoldPoint + { + public: + btManifoldPoint() + :m_userPersistentData(0), + m_lateralFrictionInitialized(false), + m_appliedImpulse(0.f), + m_appliedImpulseLateral1(0.f), + m_appliedImpulseLateral2(0.f), + m_contactMotion1(0.f), + m_contactMotion2(0.f), + m_contactCFM1(0.f), + m_contactCFM2(0.f), + m_lifeTime(0) + { + } + + btManifoldPoint( const btVector3 &pointA, const btVector3 &pointB, + const btVector3 &normal, + btScalar distance ) : + m_localPointA( pointA ), + m_localPointB( pointB ), + m_normalWorldOnB( normal ), + m_distance1( distance ), + m_combinedFriction(btScalar(0.)), + m_combinedRollingFriction(btScalar(0.)), + m_combinedRestitution(btScalar(0.)), + m_userPersistentData(0), + m_lateralFrictionInitialized(false), + m_appliedImpulse(0.f), + m_appliedImpulseLateral1(0.f), + m_appliedImpulseLateral2(0.f), + m_contactMotion1(0.f), + m_contactMotion2(0.f), + m_contactCFM1(0.f), + m_contactCFM2(0.f), + m_lifeTime(0) + { + + } + + + + btVector3 m_localPointA; + btVector3 m_localPointB; + btVector3 m_positionWorldOnB; + ///m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity + btVector3 m_positionWorldOnA; + btVector3 m_normalWorldOnB; + + btScalar m_distance1; + btScalar m_combinedFriction; + btScalar m_combinedRollingFriction; + btScalar m_combinedRestitution; + + //BP mod, store contact triangles. + int m_partId0; + int m_partId1; + int m_index0; + int m_index1; + + mutable void* m_userPersistentData; + bool m_lateralFrictionInitialized; + + btScalar m_appliedImpulse; + btScalar m_appliedImpulseLateral1; + btScalar m_appliedImpulseLateral2; + btScalar m_contactMotion1; + btScalar m_contactMotion2; + btScalar m_contactCFM1; + btScalar m_contactCFM2; + + int m_lifeTime;//lifetime of the contactpoint in frames + + btVector3 m_lateralFrictionDir1; + btVector3 m_lateralFrictionDir2; + + + + + btScalar getDistance() const + { + return m_distance1; + } + int getLifeTime() const + { + return m_lifeTime; + } + + const btVector3& getPositionWorldOnA() const { + return m_positionWorldOnA; +// return m_positionWorldOnB + m_normalWorldOnB * m_distance1; + } + + const btVector3& getPositionWorldOnB() const + { + return m_positionWorldOnB; + } + + void setDistance(btScalar dist) + { + m_distance1 = dist; + } + + ///this returns the most recent applied impulse, to satisfy contact constraints by the constraint solver + btScalar getAppliedImpulse() const + { + return m_appliedImpulse; + } + + + + }; + +#endif //BT_MANIFOLD_CONTACT_POINT_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp new file mode 100644 index 0000000..fe31f08 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp @@ -0,0 +1,362 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btMinkowskiPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" + +#define NUM_UNITSPHERE_POINTS 42 + + +bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver, + const btConvexShape* convexA,const btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc + ) +{ + + (void)stackAlloc; + (void)v; + + bool check2d= convexA->isConvex2d() && convexB->isConvex2d(); + + struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result + { + + btIntermediateResult():m_hasResult(false) + { + } + + btVector3 m_normalOnBInWorld; + btVector3 m_pointInWorld; + btScalar m_depth; + bool m_hasResult; + + virtual void setShapeIdentifiersA(int partId0,int index0) + { + (void)partId0; + (void)index0; + } + virtual void setShapeIdentifiersB(int partId1,int index1) + { + (void)partId1; + (void)index1; + } + void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + m_normalOnBInWorld = normalOnBInWorld; + m_pointInWorld = pointInWorld; + m_depth = depth; + m_hasResult = true; + } + }; + + //just take fixed number of orientation, and sample the penetration depth in that direction + btScalar minProj = btScalar(BT_LARGE_FLOAT); + btVector3 minNorm(btScalar(0.), btScalar(0.), btScalar(0.)); + btVector3 minA,minB; + btVector3 seperatingAxisInA,seperatingAxisInB; + btVector3 pInA,qInB,pWorld,qWorld,w; + +#ifndef __SPU__ +#define USE_BATCHED_SUPPORT 1 +#endif +#ifdef USE_BATCHED_SUPPORT + + btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 supportVerticesBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 seperatingAxisInABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + int i; + + int numSampleDirections = NUM_UNITSPHERE_POINTS; + + for (i=0;igetNumPreferredPenetrationDirections(); + if (numPDA) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transA.getBasis() * norm; + getPenetrationDirections()[numSampleDirections] = norm; + seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); + seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); + numSampleDirections++; + } + } + } + + { + int numPDB = convexB->getNumPreferredPenetrationDirections(); + if (numPDB) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transB.getBasis() * norm; + getPenetrationDirections()[numSampleDirections] = norm; + seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); + seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); + numSampleDirections++; + } + } + } + + + + + convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections); + convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections); + + for (i=0;i0.01) + { + + seperatingAxisInA = seperatingAxisInABatch[i]; + seperatingAxisInB = seperatingAxisInBBatch[i]; + + pInA = supportVerticesABatch[i]; + qInB = supportVerticesBBatch[i]; + + pWorld = transA(pInA); + qWorld = transB(qInB); + if (check2d) + { + pWorld[2] = 0.f; + qWorld[2] = 0.f; + } + + w = qWorld - pWorld; + btScalar delta = norm.dot(w); + //find smallest delta + if (delta < minProj) + { + minProj = delta; + minNorm = norm; + minA = pWorld; + minB = qWorld; + } + } + } +#else + + int numSampleDirections = NUM_UNITSPHERE_POINTS; + +#ifndef __SPU__ + { + int numPDA = convexA->getNumPreferredPenetrationDirections(); + if (numPDA) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transA.getBasis() * norm; + getPenetrationDirections()[numSampleDirections] = norm; + numSampleDirections++; + } + } + } + + { + int numPDB = convexB->getNumPreferredPenetrationDirections(); + if (numPDB) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transB.getBasis() * norm; + getPenetrationDirections()[numSampleDirections] = norm; + numSampleDirections++; + } + } + } +#endif // __SPU__ + + for (int i=0;ilocalGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); + qInB = convexB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); + pWorld = transA(pInA); + qWorld = transB(qInB); + w = qWorld - pWorld; + btScalar delta = norm.dot(w); + //find smallest delta + if (delta < minProj) + { + minProj = delta; + minNorm = norm; + minA = pWorld; + minB = qWorld; + } + } +#endif //USE_BATCHED_SUPPORT + + //add the margins + + minA += minNorm*convexA->getMarginNonVirtual(); + minB -= minNorm*convexB->getMarginNonVirtual(); + //no penetration + if (minProj < btScalar(0.)) + return false; + + btScalar extraSeparation = 0.5f;///scale dependent + minProj += extraSeparation+(convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual()); + + + + + +//#define DEBUG_DRAW 1 +#ifdef DEBUG_DRAW + if (debugDraw) + { + btVector3 color(0,1,0); + debugDraw->drawLine(minA,minB,color); + color = btVector3 (1,1,1); + btVector3 vec = minB-minA; + btScalar prj2 = minNorm.dot(vec); + debugDraw->drawLine(minA,minA+(minNorm*minProj),color); + + } +#endif //DEBUG_DRAW + + + + btGjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0); + + btScalar offsetDist = minProj; + btVector3 offset = minNorm * offsetDist; + + + + btGjkPairDetector::ClosestPointInput input; + + btVector3 newOrg = transA.getOrigin() + offset; + + btTransform displacedTrans = transA; + displacedTrans.setOrigin(newOrg); + + input.m_transformA = displacedTrans; + input.m_transformB = transB; + input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);//minProj; + + btIntermediateResult res; + gjkdet.setCachedSeperatingAxis(-minNorm); + gjkdet.getClosestPoints(input,res,debugDraw); + + btScalar correctedMinNorm = minProj - res.m_depth; + + + //the penetration depth is over-estimated, relax it + btScalar penetration_relaxation= btScalar(1.); + minNorm*=penetration_relaxation; + + + if (res.m_hasResult) + { + + pa = res.m_pointInWorld - minNorm * correctedMinNorm; + pb = res.m_pointInWorld; + v = minNorm; + +#ifdef DEBUG_DRAW + if (debugDraw) + { + btVector3 color(1,0,0); + debugDraw->drawLine(pa,pb,color); + } +#endif//DEBUG_DRAW + + + } + return res.m_hasResult; +} + +btVector3* btMinkowskiPenetrationDepthSolver::getPenetrationDirections() +{ + static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = + { + btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), + btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), + btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), + btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), + btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), + btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), + btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), + btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), + btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), + btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), + btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), + btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), + btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), + btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), + btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), + btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), + btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), + btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), + btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), + btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), + btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), + btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), + btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), + btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), + btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), + btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), + btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), + btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), + btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), + btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), + btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), + btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), + btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), + btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), + btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), + btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), + btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), + btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), + btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), + btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), + btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), + btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) + }; + + return sPenetrationDirections; +} + + diff --git a/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h new file mode 100644 index 0000000..6a8fe52 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h @@ -0,0 +1,40 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_MINKOWSKI_PENETRATION_DEPTH_SOLVER_H +#define BT_MINKOWSKI_PENETRATION_DEPTH_SOLVER_H + +#include "btConvexPenetrationDepthSolver.h" + +///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation. +///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points. +class btMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver +{ +protected: + + static btVector3* getPenetrationDirections(); + +public: + + virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, + const btConvexShape* convexA,const btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc + ); +}; + +#endif //BT_MINKOWSKI_PENETRATION_DEPTH_SOLVER_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp new file mode 100644 index 0000000..4d92e85 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp @@ -0,0 +1,305 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btPersistentManifold.h" +#include "LinearMath/btTransform.h" + + +btScalar gContactBreakingThreshold = btScalar(0.02); +ContactDestroyedCallback gContactDestroyedCallback = 0; +ContactProcessedCallback gContactProcessedCallback = 0; +///gContactCalcArea3Points will approximate the convex hull area using 3 points +///when setting it to false, it will use 4 points to compute the area: it is more accurate but slower +bool gContactCalcArea3Points = true; + + +btPersistentManifold::btPersistentManifold() +:btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE), +m_body0(0), +m_body1(0), +m_cachedPoints (0), +m_index1a(0) +{ +} + + + + +#ifdef DEBUG_PERSISTENCY +#include +void btPersistentManifold::DebugPersistency() +{ + int i; + printf("DebugPersistency : numPoints %d\n",m_cachedPoints); + for (i=0;i1) + printf("error in clearUserCache\n"); + } + } + btAssert(occurance<=0); +#endif //DEBUG_PERSISTENCY + + if (pt.m_userPersistentData && gContactDestroyedCallback) + { + (*gContactDestroyedCallback)(pt.m_userPersistentData); + pt.m_userPersistentData = 0; + } + +#ifdef DEBUG_PERSISTENCY + DebugPersistency(); +#endif + } + + +} + +static inline btScalar calcArea4Points(const btVector3 &p0,const btVector3 &p1,const btVector3 &p2,const btVector3 &p3) +{ + // It calculates possible 3 area constructed from random 4 points and returns the biggest one. + + btVector3 a[3],b[3]; + a[0] = p0 - p1; + a[1] = p0 - p2; + a[2] = p0 - p3; + b[0] = p2 - p3; + b[1] = p1 - p3; + b[2] = p1 - p2; + + //todo: Following 3 cross production can be easily optimized by SIMD. + btVector3 tmp0 = a[0].cross(b[0]); + btVector3 tmp1 = a[1].cross(b[1]); + btVector3 tmp2 = a[2].cross(b[2]); + + return btMax(btMax(tmp0.length2(),tmp1.length2()),tmp2.length2()); +} + +int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt) +{ + //calculate 4 possible cases areas, and take biggest area + //also need to keep 'deepest' + + int maxPenetrationIndex = -1; +#define KEEP_DEEPEST_POINT 1 +#ifdef KEEP_DEEPEST_POINT + btScalar maxPenetration = pt.getDistance(); + for (int i=0;i<4;i++) + { + if (m_pointCache[i].getDistance() < maxPenetration) + { + maxPenetrationIndex = i; + maxPenetration = m_pointCache[i].getDistance(); + } + } +#endif //KEEP_DEEPEST_POINT + + btScalar res0(btScalar(0.)),res1(btScalar(0.)),res2(btScalar(0.)),res3(btScalar(0.)); + + if (gContactCalcArea3Points) + { + if (maxPenetrationIndex != 0) + { + btVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA; + btVector3 b0 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + btVector3 cross = a0.cross(b0); + res0 = cross.length2(); + } + if (maxPenetrationIndex != 1) + { + btVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA; + btVector3 b1 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + btVector3 cross = a1.cross(b1); + res1 = cross.length2(); + } + + if (maxPenetrationIndex != 2) + { + btVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA; + btVector3 b2 = m_pointCache[3].m_localPointA-m_pointCache[1].m_localPointA; + btVector3 cross = a2.cross(b2); + res2 = cross.length2(); + } + + if (maxPenetrationIndex != 3) + { + btVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA; + btVector3 b3 = m_pointCache[2].m_localPointA-m_pointCache[1].m_localPointA; + btVector3 cross = a3.cross(b3); + res3 = cross.length2(); + } + } + else + { + if(maxPenetrationIndex != 0) { + res0 = calcArea4Points(pt.m_localPointA,m_pointCache[1].m_localPointA,m_pointCache[2].m_localPointA,m_pointCache[3].m_localPointA); + } + + if(maxPenetrationIndex != 1) { + res1 = calcArea4Points(pt.m_localPointA,m_pointCache[0].m_localPointA,m_pointCache[2].m_localPointA,m_pointCache[3].m_localPointA); + } + + if(maxPenetrationIndex != 2) { + res2 = calcArea4Points(pt.m_localPointA,m_pointCache[0].m_localPointA,m_pointCache[1].m_localPointA,m_pointCache[3].m_localPointA); + } + + if(maxPenetrationIndex != 3) { + res3 = calcArea4Points(pt.m_localPointA,m_pointCache[0].m_localPointA,m_pointCache[1].m_localPointA,m_pointCache[2].m_localPointA); + } + } + btVector4 maxvec(res0,res1,res2,res3); + int biggestarea = maxvec.closestAxis4(); + return biggestarea; + +} + + +int btPersistentManifold::getCacheEntry(const btManifoldPoint& newPoint) const +{ + btScalar shortestDist = getContactBreakingThreshold() * getContactBreakingThreshold(); + int size = getNumContacts(); + int nearestPoint = -1; + for( int i = 0; i < size; i++ ) + { + const btManifoldPoint &mp = m_pointCache[i]; + + btVector3 diffA = mp.m_localPointA- newPoint.m_localPointA; + const btScalar distToManiPoint = diffA.dot(diffA); + if( distToManiPoint < shortestDist ) + { + shortestDist = distToManiPoint; + nearestPoint = i; + } + } + return nearestPoint; +} + +int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint, bool isPredictive) +{ + if (!isPredictive) + { + btAssert(validContactDistance(newPoint)); + } + + int insertIndex = getNumContacts(); + if (insertIndex == MANIFOLD_CACHE_SIZE) + { +#if MANIFOLD_CACHE_SIZE >= 4 + //sort cache so best points come first, based on area + insertIndex = sortCachedPoints(newPoint); +#else + insertIndex = 0; +#endif + clearUserCache(m_pointCache[insertIndex]); + + } else + { + m_cachedPoints++; + + + } + if (insertIndex<0) + insertIndex=0; + + btAssert(m_pointCache[insertIndex].m_userPersistentData==0); + m_pointCache[insertIndex] = newPoint; + return insertIndex; +} + +btScalar btPersistentManifold::getContactBreakingThreshold() const +{ + return m_contactBreakingThreshold; +} + + + +void btPersistentManifold::refreshContactPoints(const btTransform& trA,const btTransform& trB) +{ + int i; +#ifdef DEBUG_PERSISTENCY + printf("refreshContactPoints posA = (%f,%f,%f) posB = (%f,%f,%f)\n", + trA.getOrigin().getX(), + trA.getOrigin().getY(), + trA.getOrigin().getZ(), + trB.getOrigin().getX(), + trB.getOrigin().getY(), + trB.getOrigin().getZ()); +#endif //DEBUG_PERSISTENCY + /// first refresh worldspace positions and distance + for (i=getNumContacts()-1;i>=0;i--) + { + btManifoldPoint &manifoldPoint = m_pointCache[i]; + manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA ); + manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB ); + manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB); + manifoldPoint.m_lifeTime++; + } + + /// then + btScalar distance2d; + btVector3 projectedDifference,projectedPoint; + for (i=getNumContacts()-1;i>=0;i--) + { + + btManifoldPoint &manifoldPoint = m_pointCache[i]; + //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction) + if (!validContactDistance(manifoldPoint)) + { + removeContactPoint(i); + } else + { + //contact also becomes invalid when relative movement orthogonal to normal exceeds margin + projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1; + projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint; + distance2d = projectedDifference.dot(projectedDifference); + if (distance2d > getContactBreakingThreshold()*getContactBreakingThreshold() ) + { + removeContactPoint(i); + } else + { + //contact point processed callback + if (gContactProcessedCallback) + (*gContactProcessedCallback)(manifoldPoint,(void*)m_body0,(void*)m_body1); + } + } + } +#ifdef DEBUG_PERSISTENCY + DebugPersistency(); +#endif // +} + + + + + diff --git a/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h new file mode 100644 index 0000000..2ceaab7 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h @@ -0,0 +1,240 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_PERSISTENT_MANIFOLD_H +#define BT_PERSISTENT_MANIFOLD_H + + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "btManifoldPoint.h" +class btCollisionObject; +#include "LinearMath/btAlignedAllocator.h" + +struct btCollisionResult; + +///maximum contact breaking and merging threshold +extern btScalar gContactBreakingThreshold; + +typedef bool (*ContactDestroyedCallback)(void* userPersistentData); +typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1); +extern ContactDestroyedCallback gContactDestroyedCallback; +extern ContactProcessedCallback gContactProcessedCallback; + +//the enum starts at 1024 to avoid type conflicts with btTypedConstraint +enum btContactManifoldTypes +{ + MIN_CONTACT_MANIFOLD_TYPE = 1024, + BT_PERSISTENT_MANIFOLD_TYPE +}; + +#define MANIFOLD_CACHE_SIZE 4 + +///btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping in the broadphase. +///Those contact points are created by the collision narrow phase. +///The cache can be empty, or hold 1,2,3 or 4 points. Some collision algorithms (GJK) might only add one point at a time. +///updates/refreshes old contact points, and throw them away if necessary (distance becomes too large) +///reduces the cache to 4 points, when more then 4 points are added, using following rules: +///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points +///note that some pairs of objects might have more then one contact manifold. + + +ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject +//ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject +{ + + btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]; + + /// this two body pointers can point to the physics rigidbody class. + const btCollisionObject* m_body0; + const btCollisionObject* m_body1; + + int m_cachedPoints; + + btScalar m_contactBreakingThreshold; + btScalar m_contactProcessingThreshold; + + + /// sort cached points so most isolated points come first + int sortCachedPoints(const btManifoldPoint& pt); + + int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt); + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + int m_companionIdA; + int m_companionIdB; + + int m_index1a; + + btPersistentManifold(); + + btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold) + : btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE), + m_body0(body0),m_body1(body1),m_cachedPoints(0), + m_contactBreakingThreshold(contactBreakingThreshold), + m_contactProcessingThreshold(contactProcessingThreshold) + { + } + + SIMD_FORCE_INLINE const btCollisionObject* getBody0() const { return m_body0;} + SIMD_FORCE_INLINE const btCollisionObject* getBody1() const { return m_body1;} + + void setBodies(const btCollisionObject* body0,const btCollisionObject* body1) + { + m_body0 = body0; + m_body1 = body1; + } + + void clearUserCache(btManifoldPoint& pt); + +#ifdef DEBUG_PERSISTENCY + void DebugPersistency(); +#endif // + + SIMD_FORCE_INLINE int getNumContacts() const { return m_cachedPoints;} + /// the setNumContacts API is usually not used, except when you gather/fill all contacts manually + void setNumContacts(int cachedPoints) + { + m_cachedPoints = cachedPoints; + } + + + SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const + { + btAssert(index < m_cachedPoints); + return m_pointCache[index]; + } + + SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index) + { + btAssert(index < m_cachedPoints); + return m_pointCache[index]; + } + + ///@todo: get this margin from the current physics / collision environment + btScalar getContactBreakingThreshold() const; + + btScalar getContactProcessingThreshold() const + { + return m_contactProcessingThreshold; + } + + void setContactBreakingThreshold(btScalar contactBreakingThreshold) + { + m_contactBreakingThreshold = contactBreakingThreshold; + } + + void setContactProcessingThreshold(btScalar contactProcessingThreshold) + { + m_contactProcessingThreshold = contactProcessingThreshold; + } + + + + + int getCacheEntry(const btManifoldPoint& newPoint) const; + + int addManifoldPoint( const btManifoldPoint& newPoint, bool isPredictive=false); + + void removeContactPoint (int index) + { + clearUserCache(m_pointCache[index]); + + int lastUsedIndex = getNumContacts() - 1; +// m_pointCache[index] = m_pointCache[lastUsedIndex]; + if(index != lastUsedIndex) + { + m_pointCache[index] = m_pointCache[lastUsedIndex]; + //get rid of duplicated userPersistentData pointer + m_pointCache[lastUsedIndex].m_userPersistentData = 0; + m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f; + m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false; + m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f; + m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f; + m_pointCache[lastUsedIndex].m_lifeTime = 0; + } + + btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0); + m_cachedPoints--; + } + void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex) + { + btAssert(validContactDistance(newPoint)); + +#define MAINTAIN_PERSISTENCY 1 +#ifdef MAINTAIN_PERSISTENCY + int lifeTime = m_pointCache[insertIndex].getLifeTime(); + btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse; + btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1; + btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2; +// bool isLateralFrictionInitialized = m_pointCache[insertIndex].m_lateralFrictionInitialized; + + + + btAssert(lifeTime>=0); + void* cache = m_pointCache[insertIndex].m_userPersistentData; + + m_pointCache[insertIndex] = newPoint; + + m_pointCache[insertIndex].m_userPersistentData = cache; + m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse; + m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1; + m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2; + + m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse; + m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1; + m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2; + + + m_pointCache[insertIndex].m_lifeTime = lifeTime; +#else + clearUserCache(m_pointCache[insertIndex]); + m_pointCache[insertIndex] = newPoint; + +#endif + } + + + bool validContactDistance(const btManifoldPoint& pt) const + { + return pt.m_distance1 <= getContactBreakingThreshold(); + } + /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin + void refreshContactPoints( const btTransform& trA,const btTransform& trB); + + + SIMD_FORCE_INLINE void clearManifold() + { + int i; + for (i=0;i //for FLT_MAX + +int gExpectedNbTests=0; +int gActualNbTests = 0; +bool gUseInternalObject = true; + +// Clips a face to the back of a plane +void btPolyhedralContactClipping::clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS) +{ + + int ve; + btScalar ds, de; + int numVerts = pVtxIn.size(); + if (numVerts < 2) + return; + + btVector3 firstVertex=pVtxIn[pVtxIn.size()-1]; + btVector3 endVertex = pVtxIn[0]; + + ds = planeNormalWS.dot(firstVertex)+planeEqWS; + + for (ve = 0; ve < numVerts; ve++) + { + endVertex=pVtxIn[ve]; + + de = planeNormalWS.dot(endVertex)+planeEqWS; + + if (ds<0) + { + if (de<0) + { + // Start < 0, end < 0, so output endVertex + ppVtxOut.push_back(endVertex); + } + else + { + // Start < 0, end >= 0, so output intersection + ppVtxOut.push_back( firstVertex.lerp(endVertex,btScalar(ds * 1.f/(ds - de)))); + } + } + else + { + if (de<0) + { + // Start >= 0, end < 0 so output intersection and end + ppVtxOut.push_back(firstVertex.lerp(endVertex,btScalar(ds * 1.f/(ds - de)))); + ppVtxOut.push_back(endVertex); + } + } + firstVertex = endVertex; + ds = de; + } +} + + +static bool TestSepAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btVector3& sep_axis, btScalar& depth, btVector3& witnessPointA, btVector3& witnessPointB) +{ + btScalar Min0,Max0; + btScalar Min1,Max1; + btVector3 witnesPtMinA,witnesPtMaxA; + btVector3 witnesPtMinB,witnesPtMaxB; + + hullA.project(transA,sep_axis, Min0, Max0,witnesPtMinA,witnesPtMaxA); + hullB.project(transB, sep_axis, Min1, Max1,witnesPtMinB,witnesPtMaxB); + + if(Max0=0.0f); + btScalar d1 = Max1 - Min0; + btAssert(d1>=0.0f); + if (d01e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false; + return true; +} + +#ifdef TEST_INTERNAL_OBJECTS + +inline void BoxSupport(const btScalar extents[3], const btScalar sv[3], btScalar p[3]) +{ + // This version is ~11.000 cycles (4%) faster overall in one of the tests. +// IR(p[0]) = IR(extents[0])|(IR(sv[0])&SIGN_BITMASK); +// IR(p[1]) = IR(extents[1])|(IR(sv[1])&SIGN_BITMASK); +// IR(p[2]) = IR(extents[2])|(IR(sv[2])&SIGN_BITMASK); + p[0] = sv[0] < 0.0f ? -extents[0] : extents[0]; + p[1] = sv[1] < 0.0f ? -extents[1] : extents[1]; + p[2] = sv[2] < 0.0f ? -extents[2] : extents[2]; +} + +void InverseTransformPoint3x3(btVector3& out, const btVector3& in, const btTransform& tr) +{ + const btMatrix3x3& rot = tr.getBasis(); + const btVector3& r0 = rot[0]; + const btVector3& r1 = rot[1]; + const btVector3& r2 = rot[2]; + + const btScalar x = r0.x()*in.x() + r1.x()*in.y() + r2.x()*in.z(); + const btScalar y = r0.y()*in.x() + r1.y()*in.y() + r2.y()*in.z(); + const btScalar z = r0.z()*in.x() + r1.z()*in.y() + r2.z()*in.z(); + + out.setValue(x, y, z); +} + + bool TestInternalObjects( const btTransform& trans0, const btTransform& trans1, const btVector3& delta_c, const btVector3& axis, const btConvexPolyhedron& convex0, const btConvexPolyhedron& convex1, btScalar dmin) +{ + const btScalar dp = delta_c.dot(axis); + + btVector3 localAxis0; + InverseTransformPoint3x3(localAxis0, axis,trans0); + btVector3 localAxis1; + InverseTransformPoint3x3(localAxis1, axis,trans1); + + btScalar p0[3]; + BoxSupport(convex0.m_extents, localAxis0, p0); + btScalar p1[3]; + BoxSupport(convex1.m_extents, localAxis1, p1); + + const btScalar Radius0 = p0[0]*localAxis0.x() + p0[1]*localAxis0.y() + p0[2]*localAxis0.z(); + const btScalar Radius1 = p1[0]*localAxis1.x() + p1[1]*localAxis1.y() + p1[2]*localAxis1.z(); + + const btScalar MinRadius = Radius0>convex0.m_radius ? Radius0 : convex0.m_radius; + const btScalar MaxRadius = Radius1>convex1.m_radius ? Radius1 : convex1.m_radius; + + const btScalar MinMaxRadius = MaxRadius + MinRadius; + const btScalar d0 = MinMaxRadius + dp; + const btScalar d1 = MinMaxRadius - dp; + + const btScalar depth = d0dmin) + return false; + return true; +} +#endif //TEST_INTERNAL_OBJECTS + + + + SIMD_FORCE_INLINE void btSegmentsClosestPoints( + btVector3& ptsVector, + btVector3& offsetA, + btVector3& offsetB, + btScalar& tA, btScalar& tB, + const btVector3& translation, + const btVector3& dirA, btScalar hlenA, + const btVector3& dirB, btScalar hlenB ) +{ + // compute the parameters of the closest points on each line segment + + btScalar dirA_dot_dirB = btDot(dirA,dirB); + btScalar dirA_dot_trans = btDot(dirA,translation); + btScalar dirB_dot_trans = btDot(dirB,translation); + + btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB; + + if ( denom == 0.0f ) { + tA = 0.0f; + } else { + tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom; + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } + + tB = tA * dirA_dot_dirB - dirB_dot_trans; + + if ( tB < -hlenB ) { + tB = -hlenB; + tA = tB * dirA_dot_dirB + dirA_dot_trans; + + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } else if ( tB > hlenB ) { + tB = hlenB; + tA = tB * dirA_dot_dirB + dirA_dot_trans; + + if ( tA < -hlenA ) + tA = -hlenA; + else if ( tA > hlenA ) + tA = hlenA; + } + + // compute the closest points relative to segment centers. + + offsetA = dirA * tA; + offsetB = dirB * tB; + + ptsVector = translation - offsetA + offsetB; +} + + + +bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut) +{ + gActualSATPairTests++; + +//#ifdef TEST_INTERNAL_OBJECTS + const btVector3 c0 = transA * hullA.m_localCenter; + const btVector3 c1 = transB * hullB.m_localCenter; + const btVector3 DeltaC2 = c0 - c1; +//#endif + + btScalar dmin = FLT_MAX; + int curPlaneTests=0; + + int numFacesA = hullA.m_faces.size(); + // Test normals from hullA + for(int i=0;i=0&&edgeB>=0) + { +// printf("edge-edge\n"); + //add an edge-edge contact + + btVector3 ptsVector; + btVector3 offsetA; + btVector3 offsetB; + btScalar tA; + btScalar tB; + + btVector3 translation = witnessPointB-witnessPointA; + + btVector3 dirA = worldEdgeA; + btVector3 dirB = worldEdgeB; + + btScalar hlenB = 1e30f; + btScalar hlenA = 1e30f; + + btSegmentsClosestPoints(ptsVector,offsetA,offsetB,tA,tB, + translation, + dirA, hlenA, + dirB,hlenB); + + btScalar nlSqrt = ptsVector.length2(); + if (nlSqrt>SIMD_EPSILON) + { + btScalar nl = btSqrt(nlSqrt); + ptsVector *= 1.f/nl; + if (ptsVector.dot(DeltaC2)<0.f) + { + ptsVector*=-1.f; + } + btVector3 ptOnB = witnessPointB + offsetB; + btScalar distance = nl; + resultOut.addContactPoint(ptsVector, ptOnB,-distance); + } + + } + + + if((DeltaC2.dot(sep))<0.0f) + sep = -sep; + + return true; +} + +void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut) +{ + btVertexArray worldVertsB2; + btVertexArray* pVtxIn = &worldVertsB1; + btVertexArray* pVtxOut = &worldVertsB2; + pVtxOut->reserve(pVtxIn->size()); + + int closestFaceA=-1; + { + btScalar dmin = FLT_MAX; + for(int face=0;faceresize(0); + } + + + +//#define ONLY_REPORT_DEEPEST_POINT + + btVector3 point; + + + // only keep points that are behind the witness face + { + btVector3 localPlaneNormal (polyA.m_plane[0],polyA.m_plane[1],polyA.m_plane[2]); + btScalar localPlaneEq = polyA.m_plane[3]; + btVector3 planeNormalWS = transA.getBasis()*localPlaneNormal; + btScalar planeEqWS=localPlaneEq-planeNormalWS.dot(transA.getOrigin()); + for (int i=0;isize();i++) + { + btVector3 vtx = pVtxIn->at(i); + btScalar depth = planeNormalWS.dot(vtx)+planeEqWS; + if (depth <=minDist) + { +// printf("clamped: depth=%f to minDist=%f\n",depth,minDist); + depth = minDist; + } + + if (depth <=maxDist) + { + btVector3 point = pVtxIn->at(i); +#ifdef ONLY_REPORT_DEEPEST_POINT + curMaxDist = depth; +#else +#if 0 + if (depth<-3) + { + printf("error in btPolyhedralContactClipping depth = %f\n", depth); + printf("likely wrong separatingNormal passed in\n"); + } +#endif + resultOut.addContactPoint(separatingNormal,point,depth); +#endif + } + } + } +#ifdef ONLY_REPORT_DEEPEST_POINT + if (curMaxDist dmax) + { + dmax = d; + closestFaceB = face; + } + } + } + btVertexArray worldVertsB1; + { + const btFace& polyB = hullB.m_faces[closestFaceB]; + const int numVertices = polyB.m_indices.size(); + for(int e0=0;e0=0) + clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, minDist, maxDist,resultOut); + +} diff --git a/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h new file mode 100644 index 0000000..b87bd4f --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +///This file was written by Erwin Coumans + + +#ifndef BT_POLYHEDRAL_CONTACT_CLIPPING_H +#define BT_POLYHEDRAL_CONTACT_CLIPPING_H + + +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btTransform.h" +#include "btDiscreteCollisionDetectorInterface.h" + +class btConvexPolyhedron; + +typedef btAlignedObjectArray btVertexArray; + +// Clips a face to the back of a plane +struct btPolyhedralContactClipping +{ + static void clipHullAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut); + static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut); + + static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut); + + ///the clipFace method is used internally + static void clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS); + +}; + +#endif // BT_POLYHEDRAL_CONTACT_CLIPPING_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp new file mode 100644 index 0000000..786efd1 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp @@ -0,0 +1,178 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//#include + +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "btRaycastCallback.h" + +btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags) + : + m_from(from), + m_to(to), + //@BP Mod + m_flags(flags), + m_hitFraction(btScalar(1.)) +{ + +} + + + +void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) +{ + const btVector3 &vert0=triangle[0]; + const btVector3 &vert1=triangle[1]; + const btVector3 &vert2=triangle[2]; + + btVector3 v10; v10 = vert1 - vert0 ; + btVector3 v20; v20 = vert2 - vert0 ; + + btVector3 triangleNormal; triangleNormal = v10.cross( v20 ); + + const btScalar dist = vert0.dot(triangleNormal); + btScalar dist_a = triangleNormal.dot(m_from) ; + dist_a-= dist; + btScalar dist_b = triangleNormal.dot(m_to); + dist_b -= dist; + + if ( dist_a * dist_b >= btScalar(0.0) ) + { + return ; // same sign + } + + if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a <= btScalar(0.0))) + { + // Backface, skip check + return; + } + + + const btScalar proj_length=dist_a-dist_b; + const btScalar distance = (dist_a)/(proj_length); + // Now we have the intersection point on the plane, we'll see if it's inside the triangle + // Add an epsilon as a tolerance for the raycast, + // in case the ray hits exacly on the edge of the triangle. + // It must be scaled for the triangle size. + + if(distance < m_hitFraction) + { + + + btScalar edge_tolerance =triangleNormal.length2(); + edge_tolerance *= btScalar(-0.0001); + btVector3 point; point.setInterpolate3( m_from, m_to, distance); + { + btVector3 v0p; v0p = vert0 - point; + btVector3 v1p; v1p = vert1 - point; + btVector3 cp0; cp0 = v0p.cross( v1p ); + + if ( (btScalar)(cp0.dot(triangleNormal)) >=edge_tolerance) + { + + + btVector3 v2p; v2p = vert2 - point; + btVector3 cp1; + cp1 = v1p.cross( v2p); + if ( (btScalar)(cp1.dot(triangleNormal)) >=edge_tolerance) + { + btVector3 cp2; + cp2 = v2p.cross(v0p); + + if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) + { + //@BP Mod + // Triangle normal isn't normalized + triangleNormal.normalize(); + + //@BP Mod - Allow for unflipped normal when raycasting against backfaces + if (((m_flags & kF_KeepUnflippedNormal) == 0) && (dist_a <= btScalar(0.0))) + { + m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex); + } + else + { + m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex); + } + } + } + } + } + } +} + + +btTriangleConvexcastCallback::btTriangleConvexcastCallback (const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin) +{ + m_convexShape = convexShape; + m_convexShapeFrom = convexShapeFrom; + m_convexShapeTo = convexShapeTo; + m_triangleToWorld = triangleToWorld; + m_hitFraction = 1.0f; + m_triangleCollisionMargin = triangleCollisionMargin; + m_allowedPenetration = 0.f; +} + +void +btTriangleConvexcastCallback::processTriangle (btVector3* triangle, int partId, int triangleIndex) +{ + btTriangleShape triangleShape (triangle[0], triangle[1], triangle[2]); + triangleShape.setMargin(m_triangleCollisionMargin); + + btVoronoiSimplexSolver simplexSolver; + btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver; + +//#define USE_SUBSIMPLEX_CONVEX_CAST 1 +//if you reenable USE_SUBSIMPLEX_CONVEX_CAST see commented out code below +#ifdef USE_SUBSIMPLEX_CONVEX_CAST + btSubsimplexConvexCast convexCaster(m_convexShape, &triangleShape, &simplexSolver); +#else + //btGjkConvexCast convexCaster(m_convexShape,&triangleShape,&simplexSolver); + btContinuousConvexCollision convexCaster(m_convexShape,&triangleShape,&simplexSolver,&gjkEpaPenetrationSolver); +#endif //#USE_SUBSIMPLEX_CONVEX_CAST + + btConvexCast::CastResult castResult; + castResult.m_fraction = btScalar(1.); + castResult.m_allowedPenetration = m_allowedPenetration; + if (convexCaster.calcTimeOfImpact(m_convexShapeFrom,m_convexShapeTo,m_triangleToWorld, m_triangleToWorld, castResult)) + { + //add hit + if (castResult.m_normal.length2() > btScalar(0.0001)) + { + if (castResult.m_fraction < m_hitFraction) + { +/* btContinuousConvexCast's normal is already in world space */ +/* +#ifdef USE_SUBSIMPLEX_CONVEX_CAST + //rotate normal into worldspace + castResult.m_normal = m_convexShapeFrom.getBasis() * castResult.m_normal; +#endif //USE_SUBSIMPLEX_CONVEX_CAST +*/ + castResult.m_normal.normalize(); + + reportHit (castResult.m_normal, + castResult.m_hitPoint, + castResult.m_fraction, + partId, + triangleIndex); + } + } + } +} diff --git a/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h new file mode 100644 index 0000000..f012889 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h @@ -0,0 +1,72 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_RAYCAST_TRI_CALLBACK_H +#define BT_RAYCAST_TRI_CALLBACK_H + +#include "BulletCollision/CollisionShapes/btTriangleCallback.h" +#include "LinearMath/btTransform.h" +struct btBroadphaseProxy; +class btConvexShape; + +class btTriangleRaycastCallback: public btTriangleCallback +{ +public: + + //input + btVector3 m_from; + btVector3 m_to; + + //@BP Mod - allow backface filtering and unflipped normals + enum EFlags + { + kF_None = 0, + kF_FilterBackfaces = 1 << 0, + kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle + + kF_Terminator = 0xFFFFFFFF + }; + unsigned int m_flags; + + btScalar m_hitFraction; + + btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags=0); + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); + + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) = 0; + +}; + +class btTriangleConvexcastCallback : public btTriangleCallback +{ +public: + const btConvexShape* m_convexShape; + btTransform m_convexShapeFrom; + btTransform m_convexShapeTo; + btTransform m_triangleToWorld; + btScalar m_hitFraction; + btScalar m_triangleCollisionMargin; + btScalar m_allowedPenetration; + + btTriangleConvexcastCallback (const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin); + + virtual void processTriangle (btVector3* triangle, int partId, int triangleIndex); + + virtual btScalar reportHit (const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex) = 0; +}; + +#endif //BT_RAYCAST_TRI_CALLBACK_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h b/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h new file mode 100644 index 0000000..da8a139 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h @@ -0,0 +1,63 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_SIMPLEX_SOLVER_INTERFACE_H +#define BT_SIMPLEX_SOLVER_INTERFACE_H + +#include "LinearMath/btVector3.h" + +#define NO_VIRTUAL_INTERFACE 1 +#ifdef NO_VIRTUAL_INTERFACE +#include "btVoronoiSimplexSolver.h" +#define btSimplexSolverInterface btVoronoiSimplexSolver +#else + +/// btSimplexSolverInterface can incrementally calculate distance between origin and up to 4 vertices +/// Used by GJK or Linear Casting. Can be implemented by the Johnson-algorithm or alternative approaches based on +/// voronoi regions or barycentric coordinates +class btSimplexSolverInterface +{ + public: + virtual ~btSimplexSolverInterface() {}; + + virtual void reset() = 0; + + virtual void addVertex(const btVector3& w, const btVector3& p, const btVector3& q) = 0; + + virtual bool closest(btVector3& v) = 0; + + virtual btScalar maxVertex() = 0; + + virtual bool fullSimplex() const = 0; + + virtual int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const = 0; + + virtual bool inSimplex(const btVector3& w) = 0; + + virtual void backup_closest(btVector3& v) = 0; + + virtual bool emptySimplex() const = 0; + + virtual void compute_points(btVector3& p1, btVector3& p2) = 0; + + virtual int numVertices() const =0; + + +}; +#endif +#endif //BT_SIMPLEX_SOLVER_INTERFACE_H + diff --git a/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp new file mode 100644 index 0000000..18eb662 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp @@ -0,0 +1,160 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btSubSimplexConvexCast.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" + +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "btPointCollector.h" +#include "LinearMath/btTransformUtil.h" + +btSubsimplexConvexCast::btSubsimplexConvexCast (const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) +:m_simplexSolver(simplexSolver), +m_convexA(convexA),m_convexB(convexB) +{ +} + +///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases. +///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565 +#ifdef BT_USE_DOUBLE_PRECISION +#define MAX_ITERATIONS 64 +#else +#define MAX_ITERATIONS 32 +#endif +bool btSubsimplexConvexCast::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) +{ + + m_simplexSolver->reset(); + + btVector3 linVelA,linVelB; + linVelA = toA.getOrigin()-fromA.getOrigin(); + linVelB = toB.getOrigin()-fromB.getOrigin(); + + btScalar lambda = btScalar(0.); + + btTransform interpolatedTransA = fromA; + btTransform interpolatedTransB = fromB; + + ///take relative motion + btVector3 r = (linVelA-linVelB); + btVector3 v; + + btVector3 supVertexA = fromA(m_convexA->localGetSupportingVertex(-r*fromA.getBasis())); + btVector3 supVertexB = fromB(m_convexB->localGetSupportingVertex(r*fromB.getBasis())); + v = supVertexA-supVertexB; + int maxIter = MAX_ITERATIONS; + + btVector3 n; + n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + bool hasResult = false; + btVector3 c; + + btScalar lastLambda = lambda; + + + btScalar dist2 = v.length2(); +#ifdef BT_USE_DOUBLE_PRECISION + btScalar epsilon = btScalar(0.0001); +#else + btScalar epsilon = btScalar(0.0001); +#endif //BT_USE_DOUBLE_PRECISION + btVector3 w,p; + btScalar VdotR; + + while ( (dist2 > epsilon) && maxIter--) + { + supVertexA = interpolatedTransA(m_convexA->localGetSupportingVertex(-v*interpolatedTransA.getBasis())); + supVertexB = interpolatedTransB(m_convexB->localGetSupportingVertex(v*interpolatedTransB.getBasis())); + w = supVertexA-supVertexB; + + btScalar VdotW = v.dot(w); + + if (lambda > btScalar(1.0)) + { + return false; + } + + if ( VdotW > btScalar(0.)) + { + VdotR = v.dot(r); + + if (VdotR >= -(SIMD_EPSILON*SIMD_EPSILON)) + return false; + else + { + lambda = lambda - VdotW / VdotR; + //interpolate to next lambda + // x = s + lambda * r; + interpolatedTransA.getOrigin().setInterpolate3(fromA.getOrigin(),toA.getOrigin(),lambda); + interpolatedTransB.getOrigin().setInterpolate3(fromB.getOrigin(),toB.getOrigin(),lambda); + //m_simplexSolver->reset(); + //check next line + w = supVertexA-supVertexB; + lastLambda = lambda; + n = v; + hasResult = true; + } + } + ///Just like regular GJK only add the vertex if it isn't already (close) to current vertex, it would lead to divisions by zero and NaN etc. + if (!m_simplexSolver->inSimplex(w)) + m_simplexSolver->addVertex( w, supVertexA , supVertexB); + + if (m_simplexSolver->closest(v)) + { + dist2 = v.length2(); + hasResult = true; + //todo: check this normal for validity + //n=v; + //printf("V=%f , %f, %f\n",v[0],v[1],v[2]); + //printf("DIST2=%f\n",dist2); + //printf("numverts = %i\n",m_simplexSolver->numVertices()); + } else + { + dist2 = btScalar(0.); + } + } + + //int numiter = MAX_ITERATIONS - maxIter; +// printf("number of iterations: %d", numiter); + + //don't report a time of impact when moving 'away' from the hitnormal + + + result.m_fraction = lambda; + if (n.length2() >= (SIMD_EPSILON*SIMD_EPSILON)) + result.m_normal = n.normalized(); + else + result.m_normal = btVector3(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + + //don't report time of impact for motion away from the contact normal (or causes minor penetration) + if (result.m_normal.dot(r)>=-result.m_allowedPenetration) + return false; + + btVector3 hitA,hitB; + m_simplexSolver->compute_points(hitA,hitB); + result.m_hitPoint=hitB; + return true; +} + + + + diff --git a/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h new file mode 100644 index 0000000..6c81279 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h @@ -0,0 +1,50 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_SUBSIMPLEX_CONVEX_CAST_H +#define BT_SUBSIMPLEX_CONVEX_CAST_H + +#include "btConvexCast.h" +#include "btSimplexSolverInterface.h" +class btConvexShape; + +/// btSubsimplexConvexCast implements Gino van den Bergens' paper +///"Ray Casting against bteral Convex Objects with Application to Continuous Collision Detection" +/// GJK based Ray Cast, optimized version +/// Objects should not start in overlap, otherwise results are not defined. +class btSubsimplexConvexCast : public btConvexCast +{ + btSimplexSolverInterface* m_simplexSolver; + const btConvexShape* m_convexA; + const btConvexShape* m_convexB; + +public: + + btSubsimplexConvexCast (const btConvexShape* shapeA,const btConvexShape* shapeB,btSimplexSolverInterface* simplexSolver); + + //virtual ~btSubsimplexConvexCast(); + ///SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects. + ///Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using btGjkPairDetector. + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); + +}; + +#endif //BT_SUBSIMPLEX_CONVEX_CAST_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp new file mode 100644 index 0000000..a775198 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp @@ -0,0 +1,609 @@ + +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + Elsevier CDROM license agreements grants nonexclusive license to use the software + for any purpose, commercial or non-commercial as long as the following credit is included + identifying the original source of the software: + + Parts of the source are "from the book Real-Time Collision Detection by + Christer Ericson, published by Morgan Kaufmann Publishers, + (c) 2005 Elsevier Inc." + +*/ + + +#include "btVoronoiSimplexSolver.h" + +#define VERTA 0 +#define VERTB 1 +#define VERTC 2 +#define VERTD 3 + +#define CATCH_DEGENERATE_TETRAHEDRON 1 +void btVoronoiSimplexSolver::removeVertex(int index) +{ + + btAssert(m_numVertices>0); + m_numVertices--; + m_simplexVectorW[index] = m_simplexVectorW[m_numVertices]; + m_simplexPointsP[index] = m_simplexPointsP[m_numVertices]; + m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices]; +} + +void btVoronoiSimplexSolver::reduceVertices (const btUsageBitfield& usedVerts) +{ + if ((numVertices() >= 4) && (!usedVerts.usedVertexD)) + removeVertex(3); + + if ((numVertices() >= 3) && (!usedVerts.usedVertexC)) + removeVertex(2); + + if ((numVertices() >= 2) && (!usedVerts.usedVertexB)) + removeVertex(1); + + if ((numVertices() >= 1) && (!usedVerts.usedVertexA)) + removeVertex(0); + +} + + + + + +//clear the simplex, remove all the vertices +void btVoronoiSimplexSolver::reset() +{ + m_cachedValidClosest = false; + m_numVertices = 0; + m_needsUpdate = true; + m_lastW = btVector3(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + m_cachedBC.reset(); +} + + + + //add a vertex +void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btVector3& p, const btVector3& q) +{ + m_lastW = w; + m_needsUpdate = true; + + m_simplexVectorW[m_numVertices] = w; + m_simplexPointsP[m_numVertices] = p; + m_simplexPointsQ[m_numVertices] = q; + + m_numVertices++; +} + +bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() +{ + + if (m_needsUpdate) + { + m_cachedBC.reset(); + + m_needsUpdate = false; + + switch (numVertices()) + { + case 0: + m_cachedValidClosest = false; + break; + case 1: + { + m_cachedP1 = m_simplexPointsP[0]; + m_cachedP2 = m_simplexPointsQ[0]; + m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0] + m_cachedBC.reset(); + m_cachedBC.setBarycentricCoordinates(btScalar(1.),btScalar(0.),btScalar(0.),btScalar(0.)); + m_cachedValidClosest = m_cachedBC.isValid(); + break; + }; + case 2: + { + //closest point origin from line segment + const btVector3& from = m_simplexVectorW[0]; + const btVector3& to = m_simplexVectorW[1]; + btVector3 nearest; + + btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 diff = p - from; + btVector3 v = to - from; + btScalar t = v.dot(diff); + + if (t > 0) { + btScalar dotVV = v.dot(v); + if (t < dotVV) { + t /= dotVV; + diff -= t*v; + m_cachedBC.m_usedVertices.usedVertexA = true; + m_cachedBC.m_usedVertices.usedVertexB = true; + } else { + t = 1; + diff -= v; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexB = true; + } + } else + { + t = 0; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexA = true; + } + m_cachedBC.setBarycentricCoordinates(1-t,t); + nearest = from + t*v; + + m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); + m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); + m_cachedV = m_cachedP1 - m_cachedP2; + + reduceVertices(m_cachedBC.m_usedVertices); + + m_cachedValidClosest = m_cachedBC.isValid(); + break; + } + case 3: + { + //closest point origin from triangle + btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); + + const btVector3& a = m_simplexVectorW[0]; + const btVector3& b = m_simplexVectorW[1]; + const btVector3& c = m_simplexVectorW[2]; + + closestPtPointTriangle(p,a,b,c,m_cachedBC); + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedV = m_cachedP1-m_cachedP2; + + reduceVertices (m_cachedBC.m_usedVertices); + m_cachedValidClosest = m_cachedBC.isValid(); + + break; + } + case 4: + { + + + btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); + + const btVector3& a = m_simplexVectorW[0]; + const btVector3& b = m_simplexVectorW[1]; + const btVector3& c = m_simplexVectorW[2]; + const btVector3& d = m_simplexVectorW[3]; + + bool hasSeperation = closestPtPointTetrahedron(p,a,b,c,d,m_cachedBC); + + if (hasSeperation) + { + + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedV = m_cachedP1-m_cachedP2; + reduceVertices (m_cachedBC.m_usedVertices); + } else + { +// printf("sub distance got penetration\n"); + + if (m_cachedBC.m_degenerate) + { + m_cachedValidClosest = false; + } else + { + m_cachedValidClosest = true; + //degenerate case == false, penetration = true + zero + m_cachedV.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + } + break; + } + + m_cachedValidClosest = m_cachedBC.isValid(); + + //closest point origin from tetrahedron + break; + } + default: + { + m_cachedValidClosest = false; + } + }; + } + + return m_cachedValidClosest; + +} + +//return/calculate the closest vertex +bool btVoronoiSimplexSolver::closest(btVector3& v) +{ + bool succes = updateClosestVectorAndPoints(); + v = m_cachedV; + return succes; +} + + + +btScalar btVoronoiSimplexSolver::maxVertex() +{ + int i, numverts = numVertices(); + btScalar maxV = btScalar(0.); + for (i=0;i= btScalar(0.0) && d4 <= d3) + { + result.m_closestPointOnSimplex = b; + result.m_usedVertices.usedVertexB = true; + result.setBarycentricCoordinates(0,1,0); + + return true; // b; // barycentric coordinates (0,1,0) + } + // Check if P in edge region of AB, if so return projection of P onto AB + btScalar vc = d1*d4 - d3*d2; + if (vc <= btScalar(0.0) && d1 >= btScalar(0.0) && d3 <= btScalar(0.0)) { + btScalar v = d1 / (d1 - d3); + result.m_closestPointOnSimplex = a + v * ab; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexB = true; + result.setBarycentricCoordinates(1-v,v,0); + return true; + //return a + v * ab; // barycentric coordinates (1-v,v,0) + } + + // Check if P in vertex region outside C + btVector3 cp = p - c; + btScalar d5 = ab.dot(cp); + btScalar d6 = ac.dot(cp); + if (d6 >= btScalar(0.0) && d5 <= d6) + { + result.m_closestPointOnSimplex = c; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(0,0,1); + return true;//c; // barycentric coordinates (0,0,1) + } + + // Check if P in edge region of AC, if so return projection of P onto AC + btScalar vb = d5*d2 - d1*d6; + if (vb <= btScalar(0.0) && d2 >= btScalar(0.0) && d6 <= btScalar(0.0)) { + btScalar w = d2 / (d2 - d6); + result.m_closestPointOnSimplex = a + w * ac; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(1-w,0,w); + return true; + //return a + w * ac; // barycentric coordinates (1-w,0,w) + } + + // Check if P in edge region of BC, if so return projection of P onto BC + btScalar va = d3*d6 - d5*d4; + if (va <= btScalar(0.0) && (d4 - d3) >= btScalar(0.0) && (d5 - d6) >= btScalar(0.0)) { + btScalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + + result.m_closestPointOnSimplex = b + w * (c - b); + result.m_usedVertices.usedVertexB = true; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(0,1-w,w); + return true; + // return b + w * (c - b); // barycentric coordinates (0,1-w,w) + } + + // P inside face region. Compute Q through its barycentric coordinates (u,v,w) + btScalar denom = btScalar(1.0) / (va + vb + vc); + btScalar v = vb * denom; + btScalar w = vc * denom; + + result.m_closestPointOnSimplex = a + ab * v + ac * w; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexB = true; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(1-v-w,v,w); + + return true; +// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = btScalar(1.0) - v - w + +} + + + + + +/// Test if point p and d lie on opposite sides of plane through abc +int btVoronoiSimplexSolver::pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d) +{ + btVector3 normal = (b-a).cross(c-a); + + btScalar signp = (p - a).dot(normal); // [AP AB AC] + btScalar signd = (d - a).dot( normal); // [AD AB AC] + +#ifdef CATCH_DEGENERATE_TETRAHEDRON +#ifdef BT_USE_DOUBLE_PRECISION +if (signd * signd < (btScalar(1e-8) * btScalar(1e-8))) + { + return -1; + } +#else + if (signd * signd < (btScalar(1e-4) * btScalar(1e-4))) + { +// printf("affine dependent/degenerate\n");// + return -1; + } +#endif + +#endif + // Points on opposite sides if expression signs are opposite + return signp * signd < btScalar(0.); +} + + +bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult) +{ + btSubSimplexClosestResult tempResult; + + // Start out assuming point inside all halfspaces, so closest to itself + finalResult.m_closestPointOnSimplex = p; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = true; + finalResult.m_usedVertices.usedVertexB = true; + finalResult.m_usedVertices.usedVertexC = true; + finalResult.m_usedVertices.usedVertexD = true; + + int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d); + int pointOutsideACD = pointOutsideOfPlane(p, a, c, d, b); + int pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c); + int pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a); + + if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) + { + finalResult.m_degenerate = true; + return false; + } + + if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) + { + return false; + } + + + btScalar bestSqDist = FLT_MAX; + // If point outside face abc then compute closest point on abc + if (pointOutsideABC) + { + closestPtPointTriangle(p, a, b, c,tempResult); + btVector3 q = tempResult.m_closestPointOnSimplex; + + btScalar sqDist = (q - p).dot( q - p); + // Update best closest point if (squared) distance is less than current best + if (sqDist < bestSqDist) { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + //convert result bitmask! + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; + finalResult.setBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC], + 0 + ); + + } + } + + + // Repeat test for face acd + if (pointOutsideACD) + { + closestPtPointTriangle(p, a, c, d,tempResult); + btVector3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + + btScalar sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC; + finalResult.setBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + 0, + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC] + ); + + } + } + // Repeat test for face adb + + + if (pointOutsideADB) + { + closestPtPointTriangle(p, a, d, b,tempResult); + btVector3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + + btScalar sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC; + + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; + finalResult.setBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + 0, + tempResult.m_barycentricCoords[VERTB] + ); + + } + } + // Repeat test for face bdc + + + if (pointOutsideBDC) + { + closestPtPointTriangle(p, b, d, c,tempResult); + btVector3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + btScalar sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + // + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; + + finalResult.setBarycentricCoordinates( + 0, + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + tempResult.m_barycentricCoords[VERTB] + ); + + } + } + + //help! we ended up full ! + + if (finalResult.m_usedVertices.usedVertexA && + finalResult.m_usedVertices.usedVertexB && + finalResult.m_usedVertices.usedVertexC && + finalResult.m_usedVertices.usedVertexD) + { + return true; + } + + return true; +} + diff --git a/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h new file mode 100644 index 0000000..2f389e2 --- /dev/null +++ b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h @@ -0,0 +1,181 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_VORONOI_SIMPLEX_SOLVER_H +#define BT_VORONOI_SIMPLEX_SOLVER_H + +#include "btSimplexSolverInterface.h" + + + +#define VORONOI_SIMPLEX_MAX_VERTS 5 + +///disable next define, or use defaultCollisionConfiguration->getSimplexSolver()->setEqualVertexThreshold(0.f) to disable/configure +#define BT_USE_EQUAL_VERTEX_THRESHOLD +#define VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD 0.0001f + + +struct btUsageBitfield{ + btUsageBitfield() + { + reset(); + } + + void reset() + { + usedVertexA = false; + usedVertexB = false; + usedVertexC = false; + usedVertexD = false; + } + unsigned short usedVertexA : 1; + unsigned short usedVertexB : 1; + unsigned short usedVertexC : 1; + unsigned short usedVertexD : 1; + unsigned short unused1 : 1; + unsigned short unused2 : 1; + unsigned short unused3 : 1; + unsigned short unused4 : 1; +}; + + +struct btSubSimplexClosestResult +{ + btVector3 m_closestPointOnSimplex; + //MASK for m_usedVertices + //stores the simplex vertex-usage, using the MASK, + // if m_usedVertices & MASK then the related vertex is used + btUsageBitfield m_usedVertices; + btScalar m_barycentricCoords[4]; + bool m_degenerate; + + void reset() + { + m_degenerate = false; + setBarycentricCoordinates(); + m_usedVertices.reset(); + } + bool isValid() + { + bool valid = (m_barycentricCoords[0] >= btScalar(0.)) && + (m_barycentricCoords[1] >= btScalar(0.)) && + (m_barycentricCoords[2] >= btScalar(0.)) && + (m_barycentricCoords[3] >= btScalar(0.)); + + + return valid; + } + void setBarycentricCoordinates(btScalar a=btScalar(0.),btScalar b=btScalar(0.),btScalar c=btScalar(0.),btScalar d=btScalar(0.)) + { + m_barycentricCoords[0] = a; + m_barycentricCoords[1] = b; + m_barycentricCoords[2] = c; + m_barycentricCoords[3] = d; + } + +}; + +/// btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin. +/// Can be used with GJK, as an alternative to Johnson distance algorithm. +#ifdef NO_VIRTUAL_INTERFACE +ATTRIBUTE_ALIGNED16(class) btVoronoiSimplexSolver +#else +ATTRIBUTE_ALIGNED16(class) btVoronoiSimplexSolver : public btSimplexSolverInterface +#endif +{ +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + int m_numVertices; + + btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; + btVector3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; + btVector3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; + + + + btVector3 m_cachedP1; + btVector3 m_cachedP2; + btVector3 m_cachedV; + btVector3 m_lastW; + + btScalar m_equalVertexThreshold; + bool m_cachedValidClosest; + + + btSubSimplexClosestResult m_cachedBC; + + bool m_needsUpdate; + + void removeVertex(int index); + void reduceVertices (const btUsageBitfield& usedVerts); + bool updateClosestVectorAndPoints(); + + bool closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult); + int pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d); + bool closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result); + +public: + + btVoronoiSimplexSolver() + : m_equalVertexThreshold(VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD) + { + } + void reset(); + + void addVertex(const btVector3& w, const btVector3& p, const btVector3& q); + + void setEqualVertexThreshold(btScalar threshold) + { + m_equalVertexThreshold = threshold; + } + + btScalar getEqualVertexThreshold() const + { + return m_equalVertexThreshold; + } + + bool closest(btVector3& v); + + btScalar maxVertex(); + + bool fullSimplex() const + { + return (m_numVertices == 4); + } + + int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const; + + bool inSimplex(const btVector3& w); + + void backup_closest(btVector3& v) ; + + bool emptySimplex() const ; + + void compute_points(btVector3& p1, btVector3& p2) ; + + int numVertices() const + { + return m_numVertices; + } + + +}; + +#endif //BT_VORONOI_SIMPLEX_SOLVER_H + diff --git a/src/BulletCollision/premake4.lua b/src/BulletCollision/premake4.lua new file mode 100644 index 0000000..094b306 --- /dev/null +++ b/src/BulletCollision/premake4.lua @@ -0,0 +1,11 @@ + project "BulletCollision" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + "..", + } + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/src/BulletDynamics/CMakeLists.txt b/src/BulletDynamics/CMakeLists.txt new file mode 100644 index 0000000..100cd7a --- /dev/null +++ b/src/BulletDynamics/CMakeLists.txt @@ -0,0 +1,114 @@ +INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src ) + + + +SET(BulletDynamics_SRCS + Character/btKinematicCharacterController.cpp + ConstraintSolver/btConeTwistConstraint.cpp + ConstraintSolver/btContactConstraint.cpp + ConstraintSolver/btGearConstraint.cpp + ConstraintSolver/btGeneric6DofConstraint.cpp + ConstraintSolver/btGeneric6DofSpringConstraint.cpp + ConstraintSolver/btHinge2Constraint.cpp + ConstraintSolver/btHingeConstraint.cpp + ConstraintSolver/btPoint2PointConstraint.cpp + ConstraintSolver/btSequentialImpulseConstraintSolver.cpp + ConstraintSolver/btSliderConstraint.cpp + ConstraintSolver/btSolve2LinearConstraint.cpp + ConstraintSolver/btTypedConstraint.cpp + ConstraintSolver/btUniversalConstraint.cpp + Dynamics/btDiscreteDynamicsWorld.cpp + Dynamics/btRigidBody.cpp + Dynamics/btSimpleDynamicsWorld.cpp + Dynamics/Bullet-C-API.cpp + Vehicle/btRaycastVehicle.cpp + Vehicle/btWheelInfo.cpp +) + +SET(Root_HDRS + ../btBulletDynamicsCommon.h + ../btBulletCollisionCommon.h +) +SET(ConstraintSolver_HDRS + ConstraintSolver/btConeTwistConstraint.h + ConstraintSolver/btConstraintSolver.h + ConstraintSolver/btContactConstraint.h + ConstraintSolver/btContactSolverInfo.h + ConstraintSolver/btGearConstraint.h + ConstraintSolver/btGeneric6DofConstraint.h + ConstraintSolver/btGeneric6DofSpringConstraint.h + ConstraintSolver/btHinge2Constraint.h + ConstraintSolver/btHingeConstraint.h + ConstraintSolver/btJacobianEntry.h + ConstraintSolver/btPoint2PointConstraint.h + ConstraintSolver/btSequentialImpulseConstraintSolver.h + ConstraintSolver/btSliderConstraint.h + ConstraintSolver/btSolve2LinearConstraint.h + ConstraintSolver/btSolverBody.h + ConstraintSolver/btSolverConstraint.h + ConstraintSolver/btTypedConstraint.h + ConstraintSolver/btUniversalConstraint.h +) +SET(Dynamics_HDRS + Dynamics/btActionInterface.h + Dynamics/btDiscreteDynamicsWorld.h + Dynamics/btDynamicsWorld.h + Dynamics/btSimpleDynamicsWorld.h + Dynamics/btRigidBody.h +) +SET(Vehicle_HDRS + Vehicle/btRaycastVehicle.h + Vehicle/btVehicleRaycaster.h + Vehicle/btWheelInfo.h +) + +SET(Character_HDRS + Character/btCharacterControllerInterface.h + Character/btKinematicCharacterController.h +) + + + +SET(BulletDynamics_HDRS + ${Root_HDRS} + ${ConstraintSolver_HDRS} + ${Dynamics_HDRS} + ${Vehicle_HDRS} + ${Character_HDRS} +) + + +ADD_LIBRARY(BulletDynamics ${BulletDynamics_SRCS} ${BulletDynamics_HDRS}) +SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletDynamics BulletCollision LinearMath) +ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletDynamics DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletDynamics DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + INSTALL(FILES ../btBulletDynamicsCommon.h +DESTINATION ${INCLUDE_INSTALL_DIR}/BulletDynamics) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES PUBLIC_HEADER "${Root_HDRS}") + # Have to list out sub-directories manually: + SET_PROPERTY(SOURCE ${ConstraintSolver_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/ConstraintSolver) + SET_PROPERTY(SOURCE ${Dynamics_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Dynamics) + SET_PROPERTY(SOURCE ${Vehicle_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Vehicle) + SET_PROPERTY(SOURCE ${Character_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Character) + + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletDynamics/Character/btCharacterControllerInterface.h b/src/BulletDynamics/Character/btCharacterControllerInterface.h new file mode 100644 index 0000000..c81813c --- /dev/null +++ b/src/BulletDynamics/Character/btCharacterControllerInterface.h @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CHARACTER_CONTROLLER_INTERFACE_H +#define BT_CHARACTER_CONTROLLER_INTERFACE_H + +#include "LinearMath/btVector3.h" +#include "BulletDynamics/Dynamics/btActionInterface.h" + +class btCollisionShape; +class btRigidBody; +class btCollisionWorld; + +class btCharacterControllerInterface : public btActionInterface +{ +public: + btCharacterControllerInterface () {}; + virtual ~btCharacterControllerInterface () {}; + + virtual void setWalkDirection(const btVector3& walkDirection) = 0; + virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0; + virtual void reset () = 0; + virtual void warp (const btVector3& origin) = 0; + + virtual void preStep ( btCollisionWorld* collisionWorld) = 0; + virtual void playerStep (btCollisionWorld* collisionWorld, btScalar dt) = 0; + virtual bool canJump () const = 0; + virtual void jump () = 0; + + virtual bool onGround () const = 0; +}; + +#endif //BT_CHARACTER_CONTROLLER_INTERFACE_H + diff --git a/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/src/BulletDynamics/Character/btKinematicCharacterController.cpp new file mode 100644 index 0000000..3b9a7f1 --- /dev/null +++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp @@ -0,0 +1,655 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/CollisionDispatch/btGhostObject.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "LinearMath/btDefaultMotionState.h" +#include "btKinematicCharacterController.h" + + +// static helper method +static btVector3 +getNormalizedVector(const btVector3& v) +{ + btVector3 n = v.normalized(); + if (n.length() < SIMD_EPSILON) { + n.setValue(0, 0, 0); + } + return n; +} + + +///@todo Interact with dynamic objects, +///Ride kinematicly animated platforms properly +///More realistic (or maybe just a config option) falling +/// -> Should integrate falling velocity manually and use that in stepDown() +///Support jumping +///Support ducking +class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback +{ +public: + btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + { + m_me = me; + } + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) + { + if (rayResult.m_collisionObject == m_me) + return 1.0; + + return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); + } +protected: + btCollisionObject* m_me; +}; + +class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback +{ +public: + btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me, const btVector3& up, btScalar minSlopeDot) + : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + , m_me(me) + , m_up(up) + , m_minSlopeDot(minSlopeDot) + { + } + + virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) + { + if (convexResult.m_hitCollisionObject == m_me) + return btScalar(1.0); + + btVector3 hitNormalWorld; + if (normalInWorldSpace) + { + hitNormalWorld = convexResult.m_hitNormalLocal; + } else + { + ///need to transform normal into worldspace + hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; + } + + btScalar dotUp = m_up.dot(hitNormalWorld); + if (dotUp < m_minSlopeDot) { + return btScalar(1.0); + } + + return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace); + } +protected: + btCollisionObject* m_me; + const btVector3 m_up; + btScalar m_minSlopeDot; +}; + +/* + * Returns the reflection direction of a ray going 'direction' hitting a surface with normal 'normal' + * + * from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html + */ +btVector3 btKinematicCharacterController::computeReflectionDirection (const btVector3& direction, const btVector3& normal) +{ + return direction - (btScalar(2.0) * direction.dot(normal)) * normal; +} + +/* + * Returns the portion of 'direction' that is parallel to 'normal' + */ +btVector3 btKinematicCharacterController::parallelComponent (const btVector3& direction, const btVector3& normal) +{ + btScalar magnitude = direction.dot(normal); + return normal * magnitude; +} + +/* + * Returns the portion of 'direction' that is perpindicular to 'normal' + */ +btVector3 btKinematicCharacterController::perpindicularComponent (const btVector3& direction, const btVector3& normal) +{ + return direction - parallelComponent(direction, normal); +} + +btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, int upAxis) +{ + m_upAxis = upAxis; + m_addedMargin = 0.02; + m_walkDirection.setValue(0,0,0); + m_useGhostObjectSweepTest = true; + m_ghostObject = ghostObject; + m_stepHeight = stepHeight; + m_turnAngle = btScalar(0.0); + m_convexShape=convexShape; + m_useWalkDirection = true; // use walk direction by default, legacy behavior + m_velocityTimeInterval = 0.0; + m_verticalVelocity = 0.0; + m_verticalOffset = 0.0; + m_gravity = 9.8 * 3 ; // 3G acceleration. + m_fallSpeed = 55.0; // Terminal velocity of a sky diver in m/s. + m_jumpSpeed = 10.0; // ? + m_wasOnGround = false; + m_wasJumping = false; + setMaxSlope(btRadians(45.0)); +} + +btKinematicCharacterController::~btKinematicCharacterController () +{ +} + +btPairCachingGhostObject* btKinematicCharacterController::getGhostObject() +{ + return m_ghostObject; +} + +bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* collisionWorld) +{ + // Here we must refresh the overlapping paircache as the penetrating movement itself or the + // previous recovery iteration might have used setWorldTransform and pushed us into an object + // that is not in the previous cache contents from the last timestep, as will happen if we + // are pushed into a new AABB overlap. Unhandled this means the next convex sweep gets stuck. + // + // Do this by calling the broadphase's setAabb with the moved AABB, this will update the broadphase + // paircache and the ghostobject's internal paircache at the same time. /BW + + btVector3 minAabb, maxAabb; + m_convexShape->getAabb(m_ghostObject->getWorldTransform(), minAabb,maxAabb); + collisionWorld->getBroadphase()->setAabb(m_ghostObject->getBroadphaseHandle(), + minAabb, + maxAabb, + collisionWorld->getDispatcher()); + + bool penetration = false; + + collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher()); + + m_currentPosition = m_ghostObject->getWorldTransform().getOrigin(); + + btScalar maxPen = btScalar(0.0); + for (int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++) + { + m_manifoldArray.resize(0); + + btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i]; + + if (collisionPair->m_algorithm) + collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray); + + + for (int j=0;jgetBody0() == m_ghostObject ? btScalar(-1.0) : btScalar(1.0); + for (int p=0;pgetNumContacts();p++) + { + const btManifoldPoint&pt = manifold->getContactPoint(p); + + btScalar dist = pt.getDistance(); + + if (dist < 0.0) + { + if (dist < maxPen) + { + maxPen = dist; + m_touchingNormal = pt.m_normalWorldOnB * directionSign;//?? + + } + m_currentPosition += pt.m_normalWorldOnB * directionSign * dist * btScalar(0.2); + penetration = true; + } else { + //printf("touching %f\n", dist); + } + } + + //manifold->clearManifold(); + } + } + btTransform newTrans = m_ghostObject->getWorldTransform(); + newTrans.setOrigin(m_currentPosition); + m_ghostObject->setWorldTransform(newTrans); +// printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]); + return penetration; +} + +void btKinematicCharacterController::stepUp ( btCollisionWorld* world) +{ + // phase 1: up + btTransform start, end; + m_targetPosition = m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.f?m_verticalOffset:0.f)); + + start.setIdentity (); + end.setIdentity (); + + /* FIXME: Handle penetration properly */ + start.setOrigin (m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_convexShape->getMargin() + m_addedMargin)); + end.setOrigin (m_targetPosition); + + btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, -getUpAxisDirections()[m_upAxis], btScalar(0.7071)); + callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; + callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + + if (m_useGhostObjectSweepTest) + { + m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration); + } + else + { + world->convexSweepTest (m_convexShape, start, end, callback); + } + + if (callback.hasHit()) + { + // Only modify the position if the hit was a slope and not a wall or ceiling. + if(callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > 0.0) + { + // we moved up only a fraction of the step height + m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction; + m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); + } + m_verticalVelocity = 0.0; + m_verticalOffset = 0.0; + } else { + m_currentStepOffset = m_stepHeight; + m_currentPosition = m_targetPosition; + } +} + +void btKinematicCharacterController::updateTargetPositionBasedOnCollision (const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag) +{ + btVector3 movementDirection = m_targetPosition - m_currentPosition; + btScalar movementLength = movementDirection.length(); + if (movementLength>SIMD_EPSILON) + { + movementDirection.normalize(); + + btVector3 reflectDir = computeReflectionDirection (movementDirection, hitNormal); + reflectDir.normalize(); + + btVector3 parallelDir, perpindicularDir; + + parallelDir = parallelComponent (reflectDir, hitNormal); + perpindicularDir = perpindicularComponent (reflectDir, hitNormal); + + m_targetPosition = m_currentPosition; + if (0)//tangentMag != 0.0) + { + btVector3 parComponent = parallelDir * btScalar (tangentMag*movementLength); +// printf("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]); + m_targetPosition += parComponent; + } + + if (normalMag != 0.0) + { + btVector3 perpComponent = perpindicularDir * btScalar (normalMag*movementLength); +// printf("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]); + m_targetPosition += perpComponent; + } + } else + { +// printf("movementLength don't normalize a zero vector\n"); + } +} + +void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove) +{ + // printf("m_normalizedDirection=%f,%f,%f\n", + // m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]); + // phase 2: forward and strafe + btTransform start, end; + m_targetPosition = m_currentPosition + walkMove; + + start.setIdentity (); + end.setIdentity (); + + btScalar fraction = 1.0; + btScalar distance2 = (m_currentPosition-m_targetPosition).length2(); +// printf("distance2=%f\n",distance2); + + if (m_touchingContact) + { + if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0)) + { + updateTargetPositionBasedOnCollision (m_touchingNormal); + } + } + + int maxIter = 10; + + while (fraction > btScalar(0.01) && maxIter-- > 0) + { + start.setOrigin (m_currentPosition); + end.setOrigin (m_targetPosition); + btVector3 sweepDirNegative(m_currentPosition - m_targetPosition); + + btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, sweepDirNegative, btScalar(0.0)); + callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; + callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + + + btScalar margin = m_convexShape->getMargin(); + m_convexShape->setMargin(margin + m_addedMargin); + + + if (m_useGhostObjectSweepTest) + { + m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + } else + { + collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + } + + m_convexShape->setMargin(margin); + + + fraction -= callback.m_closestHitFraction; + + if (callback.hasHit()) + { + // we moved only a fraction + btScalar hitDistance; + hitDistance = (callback.m_hitPointWorld - m_currentPosition).length(); + +// m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); + + updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld); + btVector3 currentDir = m_targetPosition - m_currentPosition; + distance2 = currentDir.length2(); + if (distance2 > SIMD_EPSILON) + { + currentDir.normalize(); + /* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */ + if (currentDir.dot(m_normalizedDirection) <= btScalar(0.0)) + { + break; + } + } else + { +// printf("currentDir: don't normalize a zero vector\n"); + break; + } + + } else { + // we moved whole way + m_currentPosition = m_targetPosition; + } + + // if (callback.m_closestHitFraction == 0.f) + // break; + + } +} + +void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt) +{ + btTransform start, end; + + // phase 3: down + /*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0; + btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + additionalDownStep); + btScalar downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt; + btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity; + m_targetPosition -= (step_drop + gravity_drop);*/ + + btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt; + if(downVelocity > 0.0 && downVelocity < m_stepHeight + && (m_wasOnGround || !m_wasJumping)) + { + downVelocity = m_stepHeight; + } + + btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity); + m_targetPosition -= step_drop; + + start.setIdentity (); + end.setIdentity (); + + start.setOrigin (m_currentPosition); + end.setOrigin (m_targetPosition); + + btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine); + callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; + callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + + if (m_useGhostObjectSweepTest) + { + m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + } else + { + collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + } + + if (callback.hasHit()) + { + // we dropped a fraction of the height -> hit floor + m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); + m_verticalVelocity = 0.0; + m_verticalOffset = 0.0; + m_wasJumping = false; + } else { + // we dropped the full height + + m_currentPosition = m_targetPosition; + } +} + + + +void btKinematicCharacterController::setWalkDirection +( +const btVector3& walkDirection +) +{ + m_useWalkDirection = true; + m_walkDirection = walkDirection; + m_normalizedDirection = getNormalizedVector(m_walkDirection); +} + + + +void btKinematicCharacterController::setVelocityForTimeInterval +( +const btVector3& velocity, +btScalar timeInterval +) +{ +// printf("setVelocity!\n"); +// printf(" interval: %f\n", timeInterval); +// printf(" velocity: (%f, %f, %f)\n", +// velocity.x(), velocity.y(), velocity.z()); + + m_useWalkDirection = false; + m_walkDirection = velocity; + m_normalizedDirection = getNormalizedVector(m_walkDirection); + m_velocityTimeInterval = timeInterval; +} + + + +void btKinematicCharacterController::reset () +{ +} + +void btKinematicCharacterController::warp (const btVector3& origin) +{ + btTransform xform; + xform.setIdentity(); + xform.setOrigin (origin); + m_ghostObject->setWorldTransform (xform); +} + + +void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld) +{ + + int numPenetrationLoops = 0; + m_touchingContact = false; + while (recoverFromPenetration (collisionWorld)) + { + numPenetrationLoops++; + m_touchingContact = true; + if (numPenetrationLoops > 4) + { + //printf("character could not recover from penetration = %d\n", numPenetrationLoops); + break; + } + } + + m_currentPosition = m_ghostObject->getWorldTransform().getOrigin(); + m_targetPosition = m_currentPosition; +// printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]); + + +} + +#include + +void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, btScalar dt) +{ +// printf("playerStep(): "); +// printf(" dt = %f", dt); + + // quick check... + if (!m_useWalkDirection && m_velocityTimeInterval <= 0.0) { +// printf("\n"); + return; // no motion + } + + m_wasOnGround = onGround(); + + // Update fall velocity. + m_verticalVelocity -= m_gravity * dt; + if(m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed) + { + m_verticalVelocity = m_jumpSpeed; + } + if(m_verticalVelocity < 0.0 && btFabs(m_verticalVelocity) > btFabs(m_fallSpeed)) + { + m_verticalVelocity = -btFabs(m_fallSpeed); + } + m_verticalOffset = m_verticalVelocity * dt; + + + btTransform xform; + xform = m_ghostObject->getWorldTransform (); + +// printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]); +// printf("walkSpeed=%f\n",walkSpeed); + + stepUp (collisionWorld); + if (m_useWalkDirection) { + stepForwardAndStrafe (collisionWorld, m_walkDirection); + } else { + //printf(" time: %f", m_velocityTimeInterval); + // still have some time left for moving! + btScalar dtMoving = + (dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval; + m_velocityTimeInterval -= dt; + + // how far will we move while we are moving? + btVector3 move = m_walkDirection * dtMoving; + + //printf(" dtMoving: %f", dtMoving); + + // okay, step + stepForwardAndStrafe(collisionWorld, move); + } + stepDown (collisionWorld, dt); + + // printf("\n"); + + xform.setOrigin (m_currentPosition); + m_ghostObject->setWorldTransform (xform); +} + +void btKinematicCharacterController::setFallSpeed (btScalar fallSpeed) +{ + m_fallSpeed = fallSpeed; +} + +void btKinematicCharacterController::setJumpSpeed (btScalar jumpSpeed) +{ + m_jumpSpeed = jumpSpeed; +} + +void btKinematicCharacterController::setMaxJumpHeight (btScalar maxJumpHeight) +{ + m_maxJumpHeight = maxJumpHeight; +} + +bool btKinematicCharacterController::canJump () const +{ + return onGround(); +} + +void btKinematicCharacterController::jump () +{ + if (!canJump()) + return; + + m_verticalVelocity = m_jumpSpeed; + m_wasJumping = true; + +#if 0 + currently no jumping. + btTransform xform; + m_rigidBody->getMotionState()->getWorldTransform (xform); + btVector3 up = xform.getBasis()[1]; + up.normalize (); + btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0); + m_rigidBody->applyCentralImpulse (up * magnitude); +#endif +} + +void btKinematicCharacterController::setGravity(btScalar gravity) +{ + m_gravity = gravity; +} + +btScalar btKinematicCharacterController::getGravity() const +{ + return m_gravity; +} + +void btKinematicCharacterController::setMaxSlope(btScalar slopeRadians) +{ + m_maxSlopeRadians = slopeRadians; + m_maxSlopeCosine = btCos(slopeRadians); +} + +btScalar btKinematicCharacterController::getMaxSlope() const +{ + return m_maxSlopeRadians; +} + +bool btKinematicCharacterController::onGround () const +{ + return m_verticalVelocity == 0.0 && m_verticalOffset == 0.0; +} + + +btVector3* btKinematicCharacterController::getUpAxisDirections() +{ + static btVector3 sUpAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) }; + + return sUpAxisDirection; +} + +void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer) +{ +} diff --git a/src/BulletDynamics/Character/btKinematicCharacterController.h b/src/BulletDynamics/Character/btKinematicCharacterController.h new file mode 100644 index 0000000..8ec6373 --- /dev/null +++ b/src/BulletDynamics/Character/btKinematicCharacterController.h @@ -0,0 +1,166 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_KINEMATIC_CHARACTER_CONTROLLER_H +#define BT_KINEMATIC_CHARACTER_CONTROLLER_H + +#include "LinearMath/btVector3.h" + +#include "btCharacterControllerInterface.h" + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" + + +class btCollisionShape; +class btConvexShape; +class btRigidBody; +class btCollisionWorld; +class btCollisionDispatcher; +class btPairCachingGhostObject; + +///btKinematicCharacterController is an object that supports a sliding motion in a world. +///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations. +///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user. +ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterControllerInterface +{ +protected: + + btScalar m_halfHeight; + + btPairCachingGhostObject* m_ghostObject; + btConvexShape* m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast + + btScalar m_verticalVelocity; + btScalar m_verticalOffset; + btScalar m_fallSpeed; + btScalar m_jumpSpeed; + btScalar m_maxJumpHeight; + btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value) + btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization) + btScalar m_gravity; + + btScalar m_turnAngle; + + btScalar m_stepHeight; + + btScalar m_addedMargin;//@todo: remove this and fix the code + + ///this is the desired walk direction, set by the user + btVector3 m_walkDirection; + btVector3 m_normalizedDirection; + + //some internal variables + btVector3 m_currentPosition; + btScalar m_currentStepOffset; + btVector3 m_targetPosition; + + ///keep track of the contact manifolds + btManifoldArray m_manifoldArray; + + bool m_touchingContact; + btVector3 m_touchingNormal; + + bool m_wasOnGround; + bool m_wasJumping; + bool m_useGhostObjectSweepTest; + bool m_useWalkDirection; + btScalar m_velocityTimeInterval; + int m_upAxis; + + static btVector3* getUpAxisDirections(); + + btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal); + btVector3 parallelComponent (const btVector3& direction, const btVector3& normal); + btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal); + + bool recoverFromPenetration ( btCollisionWorld* collisionWorld); + void stepUp (btCollisionWorld* collisionWorld); + void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); + void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove); + void stepDown (btCollisionWorld* collisionWorld, btScalar dt); +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, int upAxis = 1); + ~btKinematicCharacterController (); + + + ///btActionInterface interface + virtual void updateAction( btCollisionWorld* collisionWorld,btScalar deltaTime) + { + preStep ( collisionWorld); + playerStep (collisionWorld, deltaTime); + } + + ///btActionInterface interface + void debugDraw(btIDebugDraw* debugDrawer); + + void setUpAxis (int axis) + { + if (axis < 0) + axis = 0; + if (axis > 2) + axis = 2; + m_upAxis = axis; + } + + /// This should probably be called setPositionIncrementPerSimulatorStep. + /// This is neither a direction nor a velocity, but the amount to + /// increment the position each simulation iteration, regardless + /// of dt. + /// This call will reset any velocity set by setVelocityForTimeInterval(). + virtual void setWalkDirection(const btVector3& walkDirection); + + /// Caller provides a velocity with which the character should move for + /// the given time period. After the time period, velocity is reset + /// to zero. + /// This call will reset any walk direction set by setWalkDirection(). + /// Negative time intervals will result in no motion. + virtual void setVelocityForTimeInterval(const btVector3& velocity, + btScalar timeInterval); + + void reset (); + void warp (const btVector3& origin); + + void preStep ( btCollisionWorld* collisionWorld); + void playerStep ( btCollisionWorld* collisionWorld, btScalar dt); + + void setFallSpeed (btScalar fallSpeed); + void setJumpSpeed (btScalar jumpSpeed); + void setMaxJumpHeight (btScalar maxJumpHeight); + bool canJump () const; + + void jump (); + + void setGravity(btScalar gravity); + btScalar getGravity() const; + + /// The max slope determines the maximum angle that the controller can walk up. + /// The slope angle is measured in radians. + void setMaxSlope(btScalar slopeRadians); + btScalar getMaxSlope() const; + + btPairCachingGhostObject* getGhostObject(); + void setUseGhostSweepTest(bool useGhostObjectSweepTest) + { + m_useGhostObjectSweepTest = useGhostObjectSweepTest; + } + + bool onGround () const; +}; + +#endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H diff --git a/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp new file mode 100644 index 0000000..4558927 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp @@ -0,0 +1,1135 @@ +/* +Bullet Continuous Collision Detection and Physics Library +btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Marcus Hennix +*/ + + +#include "btConeTwistConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btMinMax.h" +#include + + + +//#define CONETWIST_USE_OBSOLETE_SOLVER true +#define CONETWIST_USE_OBSOLETE_SOLVER false +#define CONETWIST_DEF_FIX_THRESH btScalar(.05f) + + +SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis, const btMatrix3x3& invInertiaWorld) +{ + btVector3 vec = axis * invInertiaWorld; + return axis.dot(vec); +} + + + + +btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB, + const btTransform& rbAFrame,const btTransform& rbBFrame) + :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), + m_angularOnly(false), + m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) +{ + init(); +} + +btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) + :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE,rbA),m_rbAFrame(rbAFrame), + m_angularOnly(false), + m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) +{ + m_rbBFrame = m_rbAFrame; + init(); +} + + +void btConeTwistConstraint::init() +{ + m_angularOnly = false; + m_solveTwistLimit = false; + m_solveSwingLimit = false; + m_bMotorEnabled = false; + m_maxMotorImpulse = btScalar(-1); + + setLimit(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + m_damping = btScalar(0.01); + m_fixThresh = CONETWIST_DEF_FIX_THRESH; + m_flags = 0; + m_linCFM = btScalar(0.f); + m_linERP = btScalar(0.7f); + m_angCFM = btScalar(0.f); +} + + +void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) +{ + if (m_useSolveConstraintObsolete) + { + info->m_numConstraintRows = 0; + info->nub = 0; + } + else + { + info->m_numConstraintRows = 3; + info->nub = 3; + calcAngleInfo2(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld()); + if(m_solveSwingLimit) + { + info->m_numConstraintRows++; + info->nub--; + if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) + { + info->m_numConstraintRows++; + info->nub--; + } + } + if(m_solveTwistLimit) + { + info->m_numConstraintRows++; + info->nub--; + } + } +} + +void btConeTwistConstraint::getInfo1NonVirtual (btConstraintInfo1* info) +{ + //always reserve 6 rows: object transform is not available on SPU + info->m_numConstraintRows = 6; + info->nub = 0; + +} + + +void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info) +{ + getInfo2NonVirtual(info,m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld()); +} + +void btConeTwistConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB) +{ + calcAngleInfo2(transA,transB,invInertiaWorldA,invInertiaWorldB); + + btAssert(!m_useSolveConstraintObsolete); + // set jacobian + info->m_J1linearAxis[0] = 1; + info->m_J1linearAxis[info->rowskip+1] = 1; + info->m_J1linearAxis[2*info->rowskip+2] = 1; + btVector3 a1 = transA.getBasis() * m_rbAFrame.getOrigin(); + { + btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); + btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip); + btVector3 a1neg = -a1; + a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + } + btVector3 a2 = transB.getBasis() * m_rbBFrame.getOrigin(); + { + btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); + btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip); + a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + } + // set right hand side + btScalar linERP = (m_flags & BT_CONETWIST_FLAGS_LIN_ERP) ? m_linERP : info->erp; + btScalar k = info->fps * linERP; + int j; + for (j=0; j<3; j++) + { + info->m_constraintError[j*info->rowskip] = k * (a2[j] + transB.getOrigin()[j] - a1[j] - transA.getOrigin()[j]); + info->m_lowerLimit[j*info->rowskip] = -SIMD_INFINITY; + info->m_upperLimit[j*info->rowskip] = SIMD_INFINITY; + if(m_flags & BT_CONETWIST_FLAGS_LIN_CFM) + { + info->cfm[j*info->rowskip] = m_linCFM; + } + } + int row = 3; + int srow = row * info->rowskip; + btVector3 ax1; + // angular limits + if(m_solveSwingLimit) + { + btScalar *J1 = info->m_J1angularAxis; + btScalar *J2 = info->m_J2angularAxis; + if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) + { + btTransform trA = transA*m_rbAFrame; + btVector3 p = trA.getBasis().getColumn(1); + btVector3 q = trA.getBasis().getColumn(2); + int srow1 = srow + info->rowskip; + J1[srow+0] = p[0]; + J1[srow+1] = p[1]; + J1[srow+2] = p[2]; + J1[srow1+0] = q[0]; + J1[srow1+1] = q[1]; + J1[srow1+2] = q[2]; + J2[srow+0] = -p[0]; + J2[srow+1] = -p[1]; + J2[srow+2] = -p[2]; + J2[srow1+0] = -q[0]; + J2[srow1+1] = -q[1]; + J2[srow1+2] = -q[2]; + btScalar fact = info->fps * m_relaxationFactor; + info->m_constraintError[srow] = fact * m_swingAxis.dot(p); + info->m_constraintError[srow1] = fact * m_swingAxis.dot(q); + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + info->m_lowerLimit[srow1] = -SIMD_INFINITY; + info->m_upperLimit[srow1] = SIMD_INFINITY; + srow = srow1 + info->rowskip; + } + else + { + ax1 = m_swingAxis * m_relaxationFactor * m_relaxationFactor; + J1[srow+0] = ax1[0]; + J1[srow+1] = ax1[1]; + J1[srow+2] = ax1[2]; + J2[srow+0] = -ax1[0]; + J2[srow+1] = -ax1[1]; + J2[srow+2] = -ax1[2]; + btScalar k = info->fps * m_biasFactor; + + info->m_constraintError[srow] = k * m_swingCorrection; + if(m_flags & BT_CONETWIST_FLAGS_ANG_CFM) + { + info->cfm[srow] = m_angCFM; + } + // m_swingCorrection is always positive or 0 + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + srow += info->rowskip; + } + } + if(m_solveTwistLimit) + { + ax1 = m_twistAxis * m_relaxationFactor * m_relaxationFactor; + btScalar *J1 = info->m_J1angularAxis; + btScalar *J2 = info->m_J2angularAxis; + J1[srow+0] = ax1[0]; + J1[srow+1] = ax1[1]; + J1[srow+2] = ax1[2]; + J2[srow+0] = -ax1[0]; + J2[srow+1] = -ax1[1]; + J2[srow+2] = -ax1[2]; + btScalar k = info->fps * m_biasFactor; + info->m_constraintError[srow] = k * m_twistCorrection; + if(m_flags & BT_CONETWIST_FLAGS_ANG_CFM) + { + info->cfm[srow] = m_angCFM; + } + if(m_twistSpan > 0.0f) + { + + if(m_twistCorrection > 0.0f) + { + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = 0; + } + } + else + { + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + srow += info->rowskip; + } +} + + + +void btConeTwistConstraint::buildJacobian() +{ + if (m_useSolveConstraintObsolete) + { + m_appliedImpulse = btScalar(0.); + m_accTwistLimitImpulse = btScalar(0.); + m_accSwingLimitImpulse = btScalar(0.); + m_accMotorImpulse = btVector3(0.,0.,0.); + + if (!m_angularOnly) + { + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + btVector3 relPos = pivotBInW - pivotAInW; + + btVector3 normal[3]; + if (relPos.length2() > SIMD_EPSILON) + { + normal[0] = relPos.normalized(); + } + else + { + normal[0].setValue(btScalar(1.0),0,0); + } + + btPlaneSpace1(normal[0], normal[1], normal[2]); + + for (int i=0;i<3;i++) + { + new (&m_jac[i]) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normal[i], + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + } + } + + calcAngleInfo2(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld()); + } +} + + + +void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) +{ + #ifndef __SPU__ + if (m_useSolveConstraintObsolete) + { + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + + btScalar tau = btScalar(0.3); + + //linear part + if (!m_angularOnly) + { + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + btVector3 vel1; + bodyA.internalGetVelocityInLocalPointObsolete(rel_pos1,vel1); + btVector3 vel2; + bodyB.internalGetVelocityInLocalPointObsolete(rel_pos2,vel2); + btVector3 vel = vel1 - vel2; + + for (int i=0;i<3;i++) + { + const btVector3& normal = m_jac[i].m_linearJointAxis; + btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); + + btScalar rel_vel; + rel_vel = normal.dot(vel); + //positional error (zeroth order error) + btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal + btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; + m_appliedImpulse += impulse; + + btVector3 ftorqueAxis1 = rel_pos1.cross(normal); + btVector3 ftorqueAxis2 = rel_pos2.cross(normal); + bodyA.internalApplyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse); + bodyB.internalApplyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse); + + } + } + + // apply motor + if (m_bMotorEnabled) + { + // compute current and predicted transforms + btTransform trACur = m_rbA.getCenterOfMassTransform(); + btTransform trBCur = m_rbB.getCenterOfMassTransform(); + btVector3 omegaA; bodyA.internalGetAngularVelocity(omegaA); + btVector3 omegaB; bodyB.internalGetAngularVelocity(omegaB); + btTransform trAPred; trAPred.setIdentity(); + btVector3 zerovec(0,0,0); + btTransformUtil::integrateTransform( + trACur, zerovec, omegaA, timeStep, trAPred); + btTransform trBPred; trBPred.setIdentity(); + btTransformUtil::integrateTransform( + trBCur, zerovec, omegaB, timeStep, trBPred); + + // compute desired transforms in world + btTransform trPose(m_qTarget); + btTransform trABDes = m_rbBFrame * trPose * m_rbAFrame.inverse(); + btTransform trADes = trBPred * trABDes; + btTransform trBDes = trAPred * trABDes.inverse(); + + // compute desired omegas in world + btVector3 omegaADes, omegaBDes; + + btTransformUtil::calculateVelocity(trACur, trADes, timeStep, zerovec, omegaADes); + btTransformUtil::calculateVelocity(trBCur, trBDes, timeStep, zerovec, omegaBDes); + + // compute delta omegas + btVector3 dOmegaA = omegaADes - omegaA; + btVector3 dOmegaB = omegaBDes - omegaB; + + // compute weighted avg axis of dOmega (weighting based on inertias) + btVector3 axisA, axisB; + btScalar kAxisAInv = 0, kAxisBInv = 0; + + if (dOmegaA.length2() > SIMD_EPSILON) + { + axisA = dOmegaA.normalized(); + kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(axisA); + } + + if (dOmegaB.length2() > SIMD_EPSILON) + { + axisB = dOmegaB.normalized(); + kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(axisB); + } + + btVector3 avgAxis = kAxisAInv * axisA + kAxisBInv * axisB; + + static bool bDoTorque = true; + if (bDoTorque && avgAxis.length2() > SIMD_EPSILON) + { + avgAxis.normalize(); + kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(avgAxis); + kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(avgAxis); + btScalar kInvCombined = kAxisAInv + kAxisBInv; + + btVector3 impulse = (kAxisAInv * dOmegaA - kAxisBInv * dOmegaB) / + (kInvCombined * kInvCombined); + + if (m_maxMotorImpulse >= 0) + { + btScalar fMaxImpulse = m_maxMotorImpulse; + if (m_bNormalizedMotorStrength) + fMaxImpulse = fMaxImpulse/kAxisAInv; + + btVector3 newUnclampedAccImpulse = m_accMotorImpulse + impulse; + btScalar newUnclampedMag = newUnclampedAccImpulse.length(); + if (newUnclampedMag > fMaxImpulse) + { + newUnclampedAccImpulse.normalize(); + newUnclampedAccImpulse *= fMaxImpulse; + impulse = newUnclampedAccImpulse - m_accMotorImpulse; + } + m_accMotorImpulse += impulse; + } + + btScalar impulseMag = impulse.length(); + btVector3 impulseAxis = impulse / impulseMag; + + bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag); + bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag); + + } + } + else if (m_damping > SIMD_EPSILON) // no motor: do a little damping + { + btVector3 angVelA; bodyA.internalGetAngularVelocity(angVelA); + btVector3 angVelB; bodyB.internalGetAngularVelocity(angVelB); + btVector3 relVel = angVelB - angVelA; + if (relVel.length2() > SIMD_EPSILON) + { + btVector3 relVelAxis = relVel.normalized(); + btScalar m_kDamping = btScalar(1.) / + (getRigidBodyA().computeAngularImpulseDenominator(relVelAxis) + + getRigidBodyB().computeAngularImpulseDenominator(relVelAxis)); + btVector3 impulse = m_damping * m_kDamping * relVel; + + btScalar impulseMag = impulse.length(); + btVector3 impulseAxis = impulse / impulseMag; + bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag); + bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag); + } + } + + // joint limits + { + ///solve angular part + btVector3 angVelA; + bodyA.internalGetAngularVelocity(angVelA); + btVector3 angVelB; + bodyB.internalGetAngularVelocity(angVelB); + + // solve swing limit + if (m_solveSwingLimit) + { + btScalar amplitude = m_swingLimitRatio * m_swingCorrection*m_biasFactor/timeStep; + btScalar relSwingVel = (angVelB - angVelA).dot(m_swingAxis); + if (relSwingVel > 0) + amplitude += m_swingLimitRatio * relSwingVel * m_relaxationFactor; + btScalar impulseMag = amplitude * m_kSwing; + + // Clamp the accumulated impulse + btScalar temp = m_accSwingLimitImpulse; + m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) ); + impulseMag = m_accSwingLimitImpulse - temp; + + btVector3 impulse = m_swingAxis * impulseMag; + + // don't let cone response affect twist + // (this can happen since body A's twist doesn't match body B's AND we use an elliptical cone limit) + { + btVector3 impulseTwistCouple = impulse.dot(m_twistAxisA) * m_twistAxisA; + btVector3 impulseNoTwistCouple = impulse - impulseTwistCouple; + impulse = impulseNoTwistCouple; + } + + impulseMag = impulse.length(); + btVector3 noTwistSwingAxis = impulse / impulseMag; + + bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*noTwistSwingAxis, impulseMag); + bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*noTwistSwingAxis, -impulseMag); + } + + + // solve twist limit + if (m_solveTwistLimit) + { + btScalar amplitude = m_twistLimitRatio * m_twistCorrection*m_biasFactor/timeStep; + btScalar relTwistVel = (angVelB - angVelA).dot( m_twistAxis ); + if (relTwistVel > 0) // only damp when moving towards limit (m_twistAxis flipping is important) + amplitude += m_twistLimitRatio * relTwistVel * m_relaxationFactor; + btScalar impulseMag = amplitude * m_kTwist; + + // Clamp the accumulated impulse + btScalar temp = m_accTwistLimitImpulse; + m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) ); + impulseMag = m_accTwistLimitImpulse - temp; + + // btVector3 impulse = m_twistAxis * impulseMag; + + bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*m_twistAxis,impulseMag); + bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*m_twistAxis,-impulseMag); + } + } + } +#else +btAssert(0); +#endif //__SPU__ +} + + + + +void btConeTwistConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} + + +#ifndef __SPU__ +void btConeTwistConstraint::calcAngleInfo() +{ + m_swingCorrection = btScalar(0.); + m_twistLimitSign = btScalar(0.); + m_solveTwistLimit = false; + m_solveSwingLimit = false; + + btVector3 b1Axis1,b1Axis2,b1Axis3; + btVector3 b2Axis1,b2Axis2; + + b1Axis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(0); + b2Axis1 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(0); + + btScalar swing1=btScalar(0.),swing2 = btScalar(0.); + + btScalar swx=btScalar(0.),swy = btScalar(0.); + btScalar thresh = btScalar(10.); + btScalar fact; + + // Get Frame into world space + if (m_swingSpan1 >= btScalar(0.05f)) + { + b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1); + swx = b2Axis1.dot(b1Axis1); + swy = b2Axis1.dot(b1Axis2); + swing1 = btAtan2Fast(swy, swx); + fact = (swy*swy + swx*swx) * thresh * thresh; + fact = fact / (fact + btScalar(1.0)); + swing1 *= fact; + } + + if (m_swingSpan2 >= btScalar(0.05f)) + { + b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2); + swx = b2Axis1.dot(b1Axis1); + swy = b2Axis1.dot(b1Axis3); + swing2 = btAtan2Fast(swy, swx); + fact = (swy*swy + swx*swx) * thresh * thresh; + fact = fact / (fact + btScalar(1.0)); + swing2 *= fact; + } + + btScalar RMaxAngle1Sq = 1.0f / (m_swingSpan1*m_swingSpan1); + btScalar RMaxAngle2Sq = 1.0f / (m_swingSpan2*m_swingSpan2); + btScalar EllipseAngle = btFabs(swing1*swing1)* RMaxAngle1Sq + btFabs(swing2*swing2) * RMaxAngle2Sq; + + if (EllipseAngle > 1.0f) + { + m_swingCorrection = EllipseAngle-1.0f; + m_solveSwingLimit = true; + // Calculate necessary axis & factors + m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3)); + m_swingAxis.normalize(); + btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f; + m_swingAxis *= swingAxisSign; + } + + // Twist limits + if (m_twistSpan >= btScalar(0.)) + { + btVector3 b2Axis2 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(1); + btQuaternion rotationArc = shortestArcQuat(b2Axis1,b1Axis1); + btVector3 TwistRef = quatRotate(rotationArc,b2Axis2); + btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) ); + m_twistAngle = twist; + +// btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.); + btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? btScalar(1.0f) : btScalar(0.); + if (twist <= -m_twistSpan*lockedFreeFactor) + { + m_twistCorrection = -(twist + m_twistSpan); + m_solveTwistLimit = true; + m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; + m_twistAxis.normalize(); + m_twistAxis *= -1.0f; + } + else if (twist > m_twistSpan*lockedFreeFactor) + { + m_twistCorrection = (twist - m_twistSpan); + m_solveTwistLimit = true; + m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; + m_twistAxis.normalize(); + } + } +} +#endif //__SPU__ + +static btVector3 vTwist(1,0,0); // twist axis in constraint's space + + + +void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTransform& transB, const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB) +{ + m_swingCorrection = btScalar(0.); + m_twistLimitSign = btScalar(0.); + m_solveTwistLimit = false; + m_solveSwingLimit = false; + // compute rotation of A wrt B (in constraint space) + if (m_bMotorEnabled && (!m_useSolveConstraintObsolete)) + { // it is assumed that setMotorTarget() was alredy called + // and motor target m_qTarget is within constraint limits + // TODO : split rotation to pure swing and pure twist + // compute desired transforms in world + btTransform trPose(m_qTarget); + btTransform trA = transA * m_rbAFrame; + btTransform trB = transB * m_rbBFrame; + btTransform trDeltaAB = trB * trPose * trA.inverse(); + btQuaternion qDeltaAB = trDeltaAB.getRotation(); + btVector3 swingAxis = btVector3(qDeltaAB.x(), qDeltaAB.y(), qDeltaAB.z()); + float swingAxisLen2 = swingAxis.length2(); + if(btFuzzyZero(swingAxisLen2)) + { + return; + } + m_swingAxis = swingAxis; + m_swingAxis.normalize(); + m_swingCorrection = qDeltaAB.getAngle(); + if(!btFuzzyZero(m_swingCorrection)) + { + m_solveSwingLimit = true; + } + return; + } + + + { + // compute rotation of A wrt B (in constraint space) + btQuaternion qA = transA.getRotation() * m_rbAFrame.getRotation(); + btQuaternion qB = transB.getRotation() * m_rbBFrame.getRotation(); + btQuaternion qAB = qB.inverse() * qA; + // split rotation into cone and twist + // (all this is done from B's perspective. Maybe I should be averaging axes...) + btVector3 vConeNoTwist = quatRotate(qAB, vTwist); vConeNoTwist.normalize(); + btQuaternion qABCone = shortestArcQuat(vTwist, vConeNoTwist); qABCone.normalize(); + btQuaternion qABTwist = qABCone.inverse() * qAB; qABTwist.normalize(); + + if (m_swingSpan1 >= m_fixThresh && m_swingSpan2 >= m_fixThresh) + { + btScalar swingAngle, swingLimit = 0; btVector3 swingAxis; + computeConeLimitInfo(qABCone, swingAngle, swingAxis, swingLimit); + + if (swingAngle > swingLimit * m_limitSoftness) + { + m_solveSwingLimit = true; + + // compute limit ratio: 0->1, where + // 0 == beginning of soft limit + // 1 == hard/real limit + m_swingLimitRatio = 1.f; + if (swingAngle < swingLimit && m_limitSoftness < 1.f - SIMD_EPSILON) + { + m_swingLimitRatio = (swingAngle - swingLimit * m_limitSoftness)/ + (swingLimit - swingLimit * m_limitSoftness); + } + + // swing correction tries to get back to soft limit + m_swingCorrection = swingAngle - (swingLimit * m_limitSoftness); + + // adjustment of swing axis (based on ellipse normal) + adjustSwingAxisToUseEllipseNormal(swingAxis); + + // Calculate necessary axis & factors + m_swingAxis = quatRotate(qB, -swingAxis); + + m_twistAxisA.setValue(0,0,0); + + m_kSwing = btScalar(1.) / + (computeAngularImpulseDenominator(m_swingAxis,invInertiaWorldA) + + computeAngularImpulseDenominator(m_swingAxis,invInertiaWorldB)); + } + } + else + { + // you haven't set any limits; + // or you're trying to set at least one of the swing limits too small. (if so, do you really want a conetwist constraint?) + // anyway, we have either hinge or fixed joint + btVector3 ivA = transA.getBasis() * m_rbAFrame.getBasis().getColumn(0); + btVector3 jvA = transA.getBasis() * m_rbAFrame.getBasis().getColumn(1); + btVector3 kvA = transA.getBasis() * m_rbAFrame.getBasis().getColumn(2); + btVector3 ivB = transB.getBasis() * m_rbBFrame.getBasis().getColumn(0); + btVector3 target; + btScalar x = ivB.dot(ivA); + btScalar y = ivB.dot(jvA); + btScalar z = ivB.dot(kvA); + if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) + { // fixed. We'll need to add one more row to constraint + if((!btFuzzyZero(y)) || (!(btFuzzyZero(z)))) + { + m_solveSwingLimit = true; + m_swingAxis = -ivB.cross(ivA); + } + } + else + { + if(m_swingSpan1 < m_fixThresh) + { // hinge around Y axis + if(!(btFuzzyZero(y))) + { + m_solveSwingLimit = true; + if(m_swingSpan2 >= m_fixThresh) + { + y = btScalar(0.f); + btScalar span2 = btAtan2(z, x); + if(span2 > m_swingSpan2) + { + x = btCos(m_swingSpan2); + z = btSin(m_swingSpan2); + } + else if(span2 < -m_swingSpan2) + { + x = btCos(m_swingSpan2); + z = -btSin(m_swingSpan2); + } + } + } + } + else + { // hinge around Z axis + if(!btFuzzyZero(z)) + { + m_solveSwingLimit = true; + if(m_swingSpan1 >= m_fixThresh) + { + z = btScalar(0.f); + btScalar span1 = btAtan2(y, x); + if(span1 > m_swingSpan1) + { + x = btCos(m_swingSpan1); + y = btSin(m_swingSpan1); + } + else if(span1 < -m_swingSpan1) + { + x = btCos(m_swingSpan1); + y = -btSin(m_swingSpan1); + } + } + } + } + target[0] = x * ivA[0] + y * jvA[0] + z * kvA[0]; + target[1] = x * ivA[1] + y * jvA[1] + z * kvA[1]; + target[2] = x * ivA[2] + y * jvA[2] + z * kvA[2]; + target.normalize(); + m_swingAxis = -ivB.cross(target); + m_swingCorrection = m_swingAxis.length(); + m_swingAxis.normalize(); + } + } + + if (m_twistSpan >= btScalar(0.f)) + { + btVector3 twistAxis; + computeTwistLimitInfo(qABTwist, m_twistAngle, twistAxis); + + if (m_twistAngle > m_twistSpan*m_limitSoftness) + { + m_solveTwistLimit = true; + + m_twistLimitRatio = 1.f; + if (m_twistAngle < m_twistSpan && m_limitSoftness < 1.f - SIMD_EPSILON) + { + m_twistLimitRatio = (m_twistAngle - m_twistSpan * m_limitSoftness)/ + (m_twistSpan - m_twistSpan * m_limitSoftness); + } + + // twist correction tries to get back to soft limit + m_twistCorrection = m_twistAngle - (m_twistSpan * m_limitSoftness); + + m_twistAxis = quatRotate(qB, -twistAxis); + + m_kTwist = btScalar(1.) / + (computeAngularImpulseDenominator(m_twistAxis,invInertiaWorldA) + + computeAngularImpulseDenominator(m_twistAxis,invInertiaWorldB)); + } + + if (m_solveSwingLimit) + m_twistAxisA = quatRotate(qA, -twistAxis); + } + else + { + m_twistAngle = btScalar(0.f); + } + } +} + + + +// given a cone rotation in constraint space, (pre: twist must already be removed) +// this method computes its corresponding swing angle and axis. +// more interestingly, it computes the cone/swing limit (angle) for this cone "pose". +void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone, + btScalar& swingAngle, // out + btVector3& vSwingAxis, // out + btScalar& swingLimit) // out +{ + swingAngle = qCone.getAngle(); + if (swingAngle > SIMD_EPSILON) + { + vSwingAxis = btVector3(qCone.x(), qCone.y(), qCone.z()); + vSwingAxis.normalize(); +#if 0 + // non-zero twist?! this should never happen. + btAssert(fabs(vSwingAxis.x()) <= SIMD_EPSILON)); +#endif + + // Compute limit for given swing. tricky: + // Given a swing axis, we're looking for the intersection with the bounding cone ellipse. + // (Since we're dealing with angles, this ellipse is embedded on the surface of a sphere.) + + // For starters, compute the direction from center to surface of ellipse. + // This is just the perpendicular (ie. rotate 2D vector by PI/2) of the swing axis. + // (vSwingAxis is the cone rotation (in z,y); change vars and rotate to (x,y) coords.) + btScalar xEllipse = vSwingAxis.y(); + btScalar yEllipse = -vSwingAxis.z(); + + // Now, we use the slope of the vector (using x/yEllipse) and find the length + // of the line that intersects the ellipse: + // x^2 y^2 + // --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits) + // a^2 b^2 + // Do the math and it should be clear. + + swingLimit = m_swingSpan1; // if xEllipse == 0, we have a pure vSwingAxis.z rotation: just use swingspan1 + if (fabs(xEllipse) > SIMD_EPSILON) + { + btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse); + btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2); + norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1); + btScalar swingLimit2 = (1 + surfaceSlope2) / norm; + swingLimit = sqrt(swingLimit2); + } + + // test! + /*swingLimit = m_swingSpan2; + if (fabs(vSwingAxis.z()) > SIMD_EPSILON) + { + btScalar mag_2 = m_swingSpan1*m_swingSpan1 + m_swingSpan2*m_swingSpan2; + btScalar sinphi = m_swingSpan2 / sqrt(mag_2); + btScalar phi = asin(sinphi); + btScalar theta = atan2(fabs(vSwingAxis.y()),fabs(vSwingAxis.z())); + btScalar alpha = 3.14159f - theta - phi; + btScalar sinalpha = sin(alpha); + swingLimit = m_swingSpan1 * sinphi/sinalpha; + }*/ + } + else if (swingAngle < 0) + { + // this should never happen! +#if 0 + btAssert(0); +#endif + } +} + +btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const +{ + // compute x/y in ellipse using cone angle (0 -> 2*PI along surface of cone) + btScalar xEllipse = btCos(fAngleInRadians); + btScalar yEllipse = btSin(fAngleInRadians); + + // Use the slope of the vector (using x/yEllipse) and find the length + // of the line that intersects the ellipse: + // x^2 y^2 + // --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits) + // a^2 b^2 + // Do the math and it should be clear. + + float swingLimit = m_swingSpan1; // if xEllipse == 0, just use axis b (1) + if (fabs(xEllipse) > SIMD_EPSILON) + { + btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse); + btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2); + norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1); + btScalar swingLimit2 = (1 + surfaceSlope2) / norm; + swingLimit = sqrt(swingLimit2); + } + + // convert into point in constraint space: + // note: twist is x-axis, swing 1 and 2 are along the z and y axes respectively + btVector3 vSwingAxis(0, xEllipse, -yEllipse); + btQuaternion qSwing(vSwingAxis, swingLimit); + btVector3 vPointInConstraintSpace(fLength,0,0); + return quatRotate(qSwing, vPointInConstraintSpace); +} + +// given a twist rotation in constraint space, (pre: cone must already be removed) +// this method computes its corresponding angle and axis. +void btConeTwistConstraint::computeTwistLimitInfo(const btQuaternion& qTwist, + btScalar& twistAngle, // out + btVector3& vTwistAxis) // out +{ + btQuaternion qMinTwist = qTwist; + twistAngle = qTwist.getAngle(); + + if (twistAngle > SIMD_PI) // long way around. flip quat and recalculate. + { + qMinTwist = -(qTwist); + twistAngle = qMinTwist.getAngle(); + } + if (twistAngle < 0) + { + // this should never happen +#if 0 + btAssert(0); +#endif + } + + vTwistAxis = btVector3(qMinTwist.x(), qMinTwist.y(), qMinTwist.z()); + if (twistAngle > SIMD_EPSILON) + vTwistAxis.normalize(); +} + + +void btConeTwistConstraint::adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const +{ + // the swing axis is computed as the "twist-free" cone rotation, + // but the cone limit is not circular, but elliptical (if swingspan1 != swingspan2). + // so, if we're outside the limits, the closest way back inside the cone isn't + // along the vector back to the center. better (and more stable) to use the ellipse normal. + + // convert swing axis to direction from center to surface of ellipse + // (ie. rotate 2D vector by PI/2) + btScalar y = -vSwingAxis.z(); + btScalar z = vSwingAxis.y(); + + // do the math... + if (fabs(z) > SIMD_EPSILON) // avoid division by 0. and we don't need an update if z == 0. + { + // compute gradient/normal of ellipse surface at current "point" + btScalar grad = y/z; + grad *= m_swingSpan2 / m_swingSpan1; + + // adjust y/z to represent normal at point (instead of vector to point) + if (y > 0) + y = fabs(grad * z); + else + y = -fabs(grad * z); + + // convert ellipse direction back to swing axis + vSwingAxis.setZ(-y); + vSwingAxis.setY( z); + vSwingAxis.normalize(); + } +} + + + +void btConeTwistConstraint::setMotorTarget(const btQuaternion &q) +{ + btTransform trACur = m_rbA.getCenterOfMassTransform(); + btTransform trBCur = m_rbB.getCenterOfMassTransform(); +// btTransform trABCur = trBCur.inverse() * trACur; +// btQuaternion qABCur = trABCur.getRotation(); +// btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame); + //btQuaternion qConstraintCur = trConstraintCur.getRotation(); + + btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * q * m_rbAFrame.getRotation(); + setMotorTargetInConstraintSpace(qConstraint); +} + + +void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion &q) +{ + m_qTarget = q; + + // clamp motor target to within limits + { + btScalar softness = 1.f;//m_limitSoftness; + + // split into twist and cone + btVector3 vTwisted = quatRotate(m_qTarget, vTwist); + btQuaternion qTargetCone = shortestArcQuat(vTwist, vTwisted); qTargetCone.normalize(); + btQuaternion qTargetTwist = qTargetCone.inverse() * m_qTarget; qTargetTwist.normalize(); + + // clamp cone + if (m_swingSpan1 >= btScalar(0.05f) && m_swingSpan2 >= btScalar(0.05f)) + { + btScalar swingAngle, swingLimit; btVector3 swingAxis; + computeConeLimitInfo(qTargetCone, swingAngle, swingAxis, swingLimit); + + if (fabs(swingAngle) > SIMD_EPSILON) + { + if (swingAngle > swingLimit*softness) + swingAngle = swingLimit*softness; + else if (swingAngle < -swingLimit*softness) + swingAngle = -swingLimit*softness; + qTargetCone = btQuaternion(swingAxis, swingAngle); + } + } + + // clamp twist + if (m_twistSpan >= btScalar(0.05f)) + { + btScalar twistAngle; btVector3 twistAxis; + computeTwistLimitInfo(qTargetTwist, twistAngle, twistAxis); + + if (fabs(twistAngle) > SIMD_EPSILON) + { + // eddy todo: limitSoftness used here??? + if (twistAngle > m_twistSpan*softness) + twistAngle = m_twistSpan*softness; + else if (twistAngle < -m_twistSpan*softness) + twistAngle = -m_twistSpan*softness; + qTargetTwist = btQuaternion(twistAxis, twistAngle); + } + } + + m_qTarget = qTargetCone * qTargetTwist; + } +} + +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///If no axis is provided, it uses the default axis for this constraint. +void btConeTwistConstraint::setParam(int num, btScalar value, int axis) +{ + switch(num) + { + case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_STOP_ERP : + if((axis >= 0) && (axis < 3)) + { + m_linERP = value; + m_flags |= BT_CONETWIST_FLAGS_LIN_ERP; + } + else + { + m_biasFactor = value; + } + break; + case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_STOP_CFM : + if((axis >= 0) && (axis < 3)) + { + m_linCFM = value; + m_flags |= BT_CONETWIST_FLAGS_LIN_CFM; + } + else + { + m_angCFM = value; + m_flags |= BT_CONETWIST_FLAGS_ANG_CFM; + } + break; + default: + btAssertConstrParams(0); + break; + } +} + +///return the local value of parameter +btScalar btConeTwistConstraint::getParam(int num, int axis) const +{ + btScalar retVal = 0; + switch(num) + { + case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_STOP_ERP : + if((axis >= 0) && (axis < 3)) + { + btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_LIN_ERP); + retVal = m_linERP; + } + else if((axis >= 3) && (axis < 6)) + { + retVal = m_biasFactor; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_STOP_CFM : + if((axis >= 0) && (axis < 3)) + { + btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_LIN_CFM); + retVal = m_linCFM; + } + else if((axis >= 3) && (axis < 6)) + { + btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_ANG_CFM); + retVal = m_angCFM; + } + else + { + btAssertConstrParams(0); + } + break; + default : + btAssertConstrParams(0); + } + return retVal; +} + + +void btConeTwistConstraint::setFrames(const btTransform & frameA, const btTransform & frameB) +{ + m_rbAFrame = frameA; + m_rbBFrame = frameB; + buildJacobian(); + //calculateTransforms(); +} + + + + diff --git a/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h new file mode 100644 index 0000000..09c048b --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h @@ -0,0 +1,349 @@ +/* +Bullet Continuous Collision Detection and Physics Library +btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Marcus Hennix +*/ + + + +/* +Overview: + +btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc). +It is a fixed translation, 3 degree-of-freedom (DOF) rotational "joint". +It divides the 3 rotational DOFs into swing (movement within a cone) and twist. +Swing is divided into swing1 and swing2 which can have different limits, giving an elliptical shape. +(Note: the cone's base isn't flat, so this ellipse is "embedded" on the surface of a sphere.) + +In the contraint's frame of reference: +twist is along the x-axis, +and swing 1 and 2 are along the z and y axes respectively. +*/ + + + +#ifndef BT_CONETWISTCONSTRAINT_H +#define BT_CONETWISTCONSTRAINT_H + +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + +enum btConeTwistFlags +{ + BT_CONETWIST_FLAGS_LIN_CFM = 1, + BT_CONETWIST_FLAGS_LIN_ERP = 2, + BT_CONETWIST_FLAGS_ANG_CFM = 4 +}; + +///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) +ATTRIBUTE_ALIGNED16(class) btConeTwistConstraint : public btTypedConstraint +{ +#ifdef IN_PARALLELL_SOLVER +public: +#endif + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + + btTransform m_rbAFrame; + btTransform m_rbBFrame; + + btScalar m_limitSoftness; + btScalar m_biasFactor; + btScalar m_relaxationFactor; + + btScalar m_damping; + + btScalar m_swingSpan1; + btScalar m_swingSpan2; + btScalar m_twistSpan; + + btScalar m_fixThresh; + + btVector3 m_swingAxis; + btVector3 m_twistAxis; + + btScalar m_kSwing; + btScalar m_kTwist; + + btScalar m_twistLimitSign; + btScalar m_swingCorrection; + btScalar m_twistCorrection; + + btScalar m_twistAngle; + + btScalar m_accSwingLimitImpulse; + btScalar m_accTwistLimitImpulse; + + bool m_angularOnly; + bool m_solveTwistLimit; + bool m_solveSwingLimit; + + bool m_useSolveConstraintObsolete; + + // not yet used... + btScalar m_swingLimitRatio; + btScalar m_twistLimitRatio; + btVector3 m_twistAxisA; + + // motor + bool m_bMotorEnabled; + bool m_bNormalizedMotorStrength; + btQuaternion m_qTarget; + btScalar m_maxMotorImpulse; + btVector3 m_accMotorImpulse; + + // parameters + int m_flags; + btScalar m_linCFM; + btScalar m_linERP; + btScalar m_angCFM; + +protected: + + void init(); + + void computeConeLimitInfo(const btQuaternion& qCone, // in + btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs + + void computeTwistLimitInfo(const btQuaternion& qTwist, // in + btScalar& twistAngle, btVector3& vTwistAxis); // all outs + + void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const; + + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame); + + btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame); + + virtual void buildJacobian(); + + virtual void getInfo1 (btConstraintInfo1* info); + + void getInfo1NonVirtual(btConstraintInfo1* info); + + virtual void getInfo2 (btConstraintInfo2* info); + + void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB); + + virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep); + + + void updateRHS(btScalar timeStep); + + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } + + void setAngularOnly(bool angularOnly) + { + m_angularOnly = angularOnly; + } + + void setLimit(int limitIndex,btScalar limitValue) + { + switch (limitIndex) + { + case 3: + { + m_twistSpan = limitValue; + break; + } + case 4: + { + m_swingSpan2 = limitValue; + break; + } + case 5: + { + m_swingSpan1 = limitValue; + break; + } + default: + { + } + }; + } + + // setLimit(), a few notes: + // _softness: + // 0->1, recommend ~0.8->1. + // describes % of limits where movement is free. + // beyond this softness %, the limit is gradually enforced until the "hard" (1.0) limit is reached. + // _biasFactor: + // 0->1?, recommend 0.3 +/-0.3 or so. + // strength with which constraint resists zeroth order (angular, not angular velocity) limit violation. + // __relaxationFactor: + // 0->1, recommend to stay near 1. + // the lower the value, the less the constraint will fight velocities which violate the angular limits. + void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + { + m_swingSpan1 = _swingSpan1; + m_swingSpan2 = _swingSpan2; + m_twistSpan = _twistSpan; + + m_limitSoftness = _softness; + m_biasFactor = _biasFactor; + m_relaxationFactor = _relaxationFactor; + } + + const btTransform& getAFrame() { return m_rbAFrame; }; + const btTransform& getBFrame() { return m_rbBFrame; }; + + inline int getSolveTwistLimit() + { + return m_solveTwistLimit; + } + + inline int getSolveSwingLimit() + { + return m_solveTwistLimit; + } + + inline btScalar getTwistLimitSign() + { + return m_twistLimitSign; + } + + void calcAngleInfo(); + void calcAngleInfo2(const btTransform& transA, const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB); + + inline btScalar getSwingSpan1() + { + return m_swingSpan1; + } + inline btScalar getSwingSpan2() + { + return m_swingSpan2; + } + inline btScalar getTwistSpan() + { + return m_twistSpan; + } + inline btScalar getTwistAngle() + { + return m_twistAngle; + } + bool isPastSwingLimit() { return m_solveSwingLimit; } + + void setDamping(btScalar damping) { m_damping = damping; } + + void enableMotor(bool b) { m_bMotorEnabled = b; } + void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; } + void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; } + + btScalar getFixThresh() { return m_fixThresh; } + void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; } + + // setMotorTarget: + // q: the desired rotation of bodyA wrt bodyB. + // note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability) + // note: don't forget to enableMotor() + void setMotorTarget(const btQuaternion &q); + + // same as above, but q is the desired rotation of frameA wrt frameB in constraint space + void setMotorTargetInConstraintSpace(const btQuaternion &q); + + btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const; + + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///If no axis is provided, it uses the default axis for this constraint. + virtual void setParam(int num, btScalar value, int axis = -1); + + virtual void setFrames(const btTransform& frameA, const btTransform& frameB); + + const btTransform& getFrameOffsetA() const + { + return m_rbAFrame; + } + + const btTransform& getFrameOffsetB() const + { + return m_rbBFrame; + } + + + ///return the local value of parameter + virtual btScalar getParam(int num, int axis = -1) const; + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btConeTwistConstraintData +{ + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + + //limits + float m_swingSpan1; + float m_swingSpan2; + float m_twistSpan; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + + float m_damping; + + char m_pad[4]; + +}; + + + +SIMD_FORCE_INLINE int btConeTwistConstraint::calculateSerializeBufferSize() const +{ + return sizeof(btConeTwistConstraintData); + +} + + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btConeTwistConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btConeTwistConstraintData* cone = (btConeTwistConstraintData*) dataBuffer; + btTypedConstraint::serialize(&cone->m_typeConstraintData,serializer); + + m_rbAFrame.serializeFloat(cone->m_rbAFrame); + m_rbBFrame.serializeFloat(cone->m_rbBFrame); + + cone->m_swingSpan1 = float(m_swingSpan1); + cone->m_swingSpan2 = float(m_swingSpan2); + cone->m_twistSpan = float(m_twistSpan); + cone->m_limitSoftness = float(m_limitSoftness); + cone->m_biasFactor = float(m_biasFactor); + cone->m_relaxationFactor = float(m_relaxationFactor); + cone->m_damping = float(m_damping); + + return "btConeTwistConstraintData"; +} + + +#endif //BT_CONETWISTCONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h b/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h new file mode 100644 index 0000000..6f67310 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h @@ -0,0 +1,52 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONSTRAINT_SOLVER_H +#define BT_CONSTRAINT_SOLVER_H + +#include "LinearMath/btScalar.h" + +class btPersistentManifold; +class btRigidBody; +class btCollisionObject; +class btTypedConstraint; +struct btContactSolverInfo; +struct btBroadphaseProxy; +class btIDebugDraw; +class btStackAlloc; +class btDispatcher; +/// btConstraintSolver provides solver interface +class btConstraintSolver +{ + +public: + + virtual ~btConstraintSolver() {} + + virtual void prepareSolve (int /* numBodies */, int /* numManifolds */) {;} + + ///solve a group of constraints + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) = 0; + + virtual void allSolved (const btContactSolverInfo& /* info */,class btIDebugDraw* /* debugDrawer */, btStackAlloc* /* stackAlloc */) {;} + + ///clear internal cached data and reset random seed + virtual void reset() = 0; +}; + + + + +#endif //BT_CONSTRAINT_SOLVER_H diff --git a/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp new file mode 100644 index 0000000..9d60d99 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp @@ -0,0 +1,178 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btContactConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btContactSolverInfo.h" +#include "LinearMath/btMinMax.h" +#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" + + + +btContactConstraint::btContactConstraint(btPersistentManifold* contactManifold,btRigidBody& rbA,btRigidBody& rbB) +:btTypedConstraint(CONTACT_CONSTRAINT_TYPE,rbA,rbB), + m_contactManifold(*contactManifold) +{ + +} + +btContactConstraint::~btContactConstraint() +{ + +} + +void btContactConstraint::setContactManifold(btPersistentManifold* contactManifold) +{ + m_contactManifold = *contactManifold; +} + +void btContactConstraint::getInfo1 (btConstraintInfo1* info) +{ + +} + +void btContactConstraint::getInfo2 (btConstraintInfo2* info) +{ + +} + +void btContactConstraint::buildJacobian() +{ + +} + + + + + +#include "btContactConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btContactSolverInfo.h" +#include "LinearMath/btMinMax.h" +#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" + + + +//response between two dynamic objects without friction and no restitution, assuming 0 penetration depth +btScalar resolveSingleCollision( + btRigidBody* body1, + btCollisionObject* colObj2, + const btVector3& contactPositionWorld, + const btVector3& contactNormalOnB, + const btContactSolverInfo& solverInfo, + btScalar distance) +{ + btRigidBody* body2 = btRigidBody::upcast(colObj2); + + + const btVector3& normal = contactNormalOnB; + + btVector3 rel_pos1 = contactPositionWorld - body1->getWorldTransform().getOrigin(); + btVector3 rel_pos2 = contactPositionWorld - colObj2->getWorldTransform().getOrigin(); + + btVector3 vel1 = body1->getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2? body2->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = normal.dot(vel); + + btScalar combinedRestitution = 0.f; + btScalar restitution = combinedRestitution* -rel_vel; + + btScalar positionalError = solverInfo.m_erp *-distance /solverInfo.m_timeStep ; + btScalar velocityError = -(1.0f + restitution) * rel_vel;// * damping; + btScalar denom0 = body1->computeImpulseDenominator(contactPositionWorld,normal); + btScalar denom1 = body2? body2->computeImpulseDenominator(contactPositionWorld,normal) : 0.f; + btScalar relaxation = 1.f; + btScalar jacDiagABInv = relaxation/(denom0+denom1); + + btScalar penetrationImpulse = positionalError * jacDiagABInv; + btScalar velocityImpulse = velocityError * jacDiagABInv; + + btScalar normalImpulse = penetrationImpulse+velocityImpulse; + normalImpulse = 0.f > normalImpulse ? 0.f: normalImpulse; + + body1->applyImpulse(normal*(normalImpulse), rel_pos1); + if (body2) + body2->applyImpulse(-normal*(normalImpulse), rel_pos2); + + return normalImpulse; +} + + +//bilateral constraint between two dynamic objects +void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, + btRigidBody& body2, const btVector3& pos2, + btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep) +{ + (void)timeStep; + (void)distance; + + + btScalar normalLenSqr = normal.length2(); + btAssert(btFabs(normalLenSqr) < btScalar(1.1)); + if (normalLenSqr > btScalar(1.1)) + { + impulse = btScalar(0.); + return; + } + btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + //this jacobian entry could be re-used for all iterations + + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + + btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), + body2.getCenterOfMassTransform().getBasis().transpose(), + rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(), + body2.getInvInertiaDiagLocal(),body2.getInvMass()); + + btScalar jacDiagAB = jac.getDiagonal(); + btScalar jacDiagABInv = btScalar(1.) / jacDiagAB; + + btScalar rel_vel = jac.getRelativeVelocity( + body1.getLinearVelocity(), + body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(), + body2.getLinearVelocity(), + body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity()); + btScalar a; + a=jacDiagABInv; + + + rel_vel = normal.dot(vel); + + //todo: move this into proper structure + btScalar contactDamping = btScalar(0.2); + +#ifdef ONLY_USE_LINEAR_MASS + btScalar massTerm = btScalar(1.) / (body1.getInvMass() + body2.getInvMass()); + impulse = - contactDamping * rel_vel * massTerm; +#else + btScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv; + impulse = velocityImpulse; +#endif +} + + + + diff --git a/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/src/BulletDynamics/ConstraintSolver/btContactConstraint.h new file mode 100644 index 0000000..477c79d --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btContactConstraint.h @@ -0,0 +1,71 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONTACT_CONSTRAINT_H +#define BT_CONTACT_CONSTRAINT_H + +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" + +///btContactConstraint can be automatically created to solve contact constraints using the unified btTypedConstraint interface +ATTRIBUTE_ALIGNED16(class) btContactConstraint : public btTypedConstraint +{ +protected: + + btPersistentManifold m_contactManifold; + +public: + + + btContactConstraint(btPersistentManifold* contactManifold,btRigidBody& rbA,btRigidBody& rbB); + + void setContactManifold(btPersistentManifold* contactManifold); + + btPersistentManifold* getContactManifold() + { + return &m_contactManifold; + } + + const btPersistentManifold* getContactManifold() const + { + return &m_contactManifold; + } + + virtual ~btContactConstraint(); + + virtual void getInfo1 (btConstraintInfo1* info); + + virtual void getInfo2 (btConstraintInfo2* info); + + ///obsolete methods + virtual void buildJacobian(); + + +}; + +///very basic collision resolution without friction +btScalar resolveSingleCollision(btRigidBody* body1, class btCollisionObject* colObj2, const btVector3& contactPositionWorld,const btVector3& contactNormalOnB, const struct btContactSolverInfo& solverInfo,btScalar distance); + + +///resolveSingleBilateral is an obsolete methods used for vehicle friction between two dynamic objects +void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, + btRigidBody& body2, const btVector3& pos2, + btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep); + + + +#endif //BT_CONTACT_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h new file mode 100644 index 0000000..c07e9bb --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -0,0 +1,159 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONTACT_SOLVER_INFO +#define BT_CONTACT_SOLVER_INFO + +#include "LinearMath/btScalar.h" + +enum btSolverMode +{ + SOLVER_RANDMIZE_ORDER = 1, + SOLVER_FRICTION_SEPARATE = 2, + SOLVER_USE_WARMSTARTING = 4, + SOLVER_USE_2_FRICTION_DIRECTIONS = 16, + SOLVER_ENABLE_FRICTION_DIRECTION_CACHING = 32, + SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64, + SOLVER_CACHE_FRIENDLY = 128, + SOLVER_SIMD = 256, + SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS = 512, + SOLVER_ALLOW_ZERO_LENGTH_FRICTION_DIRECTIONS = 1024 +}; + +struct btContactSolverInfoData +{ + + + btScalar m_tau; + btScalar m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + btScalar m_friction; + btScalar m_timeStep; + btScalar m_restitution; + int m_numIterations; + btScalar m_maxErrorReduction; + btScalar m_sor; + btScalar m_erp;//used as Baumgarte factor + btScalar m_erp2;//used in Split Impulse + btScalar m_globalCfm;//constraint force mixing + int m_splitImpulse; + btScalar m_splitImpulsePenetrationThreshold; + btScalar m_splitImpulseTurnErp; + btScalar m_linearSlop; + btScalar m_warmstartingFactor; + + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + btScalar m_maxGyroscopicForce; + btScalar m_singleAxisRollingFrictionThreshold; + + +}; + +struct btContactSolverInfo : public btContactSolverInfoData +{ + + + + inline btContactSolverInfo() + { + m_tau = btScalar(0.6); + m_damping = btScalar(1.0); + m_friction = btScalar(0.3); + m_timeStep = btScalar(1.f/60.f); + m_restitution = btScalar(0.); + m_maxErrorReduction = btScalar(20.); + m_numIterations = 10; + m_erp = btScalar(0.2); + m_erp2 = btScalar(0.8); + m_globalCfm = btScalar(0.); + m_sor = btScalar(1.); + m_splitImpulse = true; + m_splitImpulsePenetrationThreshold = -.04f; + m_splitImpulseTurnErp = 0.1f; + m_linearSlop = btScalar(0.0); + m_warmstartingFactor=btScalar(0.85); + //m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD | SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION|SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;// | SOLVER_RANDMIZE_ORDER; + m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD;// | SOLVER_RANDMIZE_ORDER; + m_restingContactRestitutionThreshold = 2;//unused as of 2.81 + m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit + m_maxGyroscopicForce = 100.f; ///only used to clamp forces for bodies that have their BT_ENABLE_GYROPSCOPIC_FORCE flag set (using btRigidBody::setFlag) + m_singleAxisRollingFrictionThreshold = 1e30f;///if the velocity is above this threshold, it will use a single constraint row (axis), otherwise 3 rows. + } +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btContactSolverInfoDoubleData +{ + double m_tau; + double m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + double m_friction; + double m_timeStep; + double m_restitution; + double m_maxErrorReduction; + double m_sor; + double m_erp;//used as Baumgarte factor + double m_erp2;//used in Split Impulse + double m_globalCfm;//constraint force mixing + double m_splitImpulsePenetrationThreshold; + double m_splitImpulseTurnErp; + double m_linearSlop; + double m_warmstartingFactor; + double m_maxGyroscopicForce; + double m_singleAxisRollingFrictionThreshold; + + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; + +}; +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btContactSolverInfoFloatData +{ + float m_tau; + float m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + float m_friction; + float m_timeStep; + + float m_restitution; + float m_maxErrorReduction; + float m_sor; + float m_erp;//used as Baumgarte factor + + float m_erp2;//used in Split Impulse + float m_globalCfm;//constraint force mixing + float m_splitImpulsePenetrationThreshold; + float m_splitImpulseTurnErp; + + float m_linearSlop; + float m_warmstartingFactor; + float m_maxGyroscopicForce; + float m_singleAxisRollingFrictionThreshold; + + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + + int m_splitImpulse; + char m_padding[4]; +}; + + + +#endif //BT_CONTACT_SOLVER_INFO diff --git a/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp new file mode 100644 index 0000000..446e69d --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp @@ -0,0 +1,54 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2012 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/// Implemented by Erwin Coumans. The idea for the constraint comes from Dimitris Papavasiliou. + +#include "btGearConstraint.h" + +btGearConstraint::btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio) +:btTypedConstraint(GEAR_CONSTRAINT_TYPE,rbA,rbB), +m_axisInA(axisInA), +m_axisInB(axisInB), +m_ratio(ratio) +{ +} + +btGearConstraint::~btGearConstraint () +{ +} + +void btGearConstraint::getInfo1 (btConstraintInfo1* info) +{ + info->m_numConstraintRows = 1; + info->nub = 1; +} + +void btGearConstraint::getInfo2 (btConstraintInfo2* info) +{ + btVector3 globalAxisA, globalAxisB; + + globalAxisA = m_rbA.getWorldTransform().getBasis()*this->m_axisInA; + globalAxisB = m_rbB.getWorldTransform().getBasis()*this->m_axisInB; + + info->m_J1angularAxis[0] = globalAxisA[0]; + info->m_J1angularAxis[1] = globalAxisA[1]; + info->m_J1angularAxis[2] = globalAxisA[2]; + + info->m_J2angularAxis[0] = m_ratio*globalAxisB[0]; + info->m_J2angularAxis[1] = m_ratio*globalAxisB[1]; + info->m_J2angularAxis[2] = m_ratio*globalAxisB[2]; + +} + diff --git a/src/BulletDynamics/ConstraintSolver/btGearConstraint.h b/src/BulletDynamics/ConstraintSolver/btGearConstraint.h new file mode 100644 index 0000000..b768894 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btGearConstraint.h @@ -0,0 +1,56 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2012 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_GEAR_CONSTRAINT_H +#define BT_GEAR_CONSTRAINT_H + +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +///The btGeatConstraint will couple the angular velocity for two bodies around given local axis and ratio. +///See Bullet/Demos/ConstraintDemo for an example use. +class btGearConstraint : public btTypedConstraint +{ +protected: + btVector3 m_axisInA; + btVector3 m_axisInB; + bool m_useFrameA; + btScalar m_ratio; + +public: + btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); + virtual ~btGearConstraint (); + + ///internal method used by the constraint solver, don't use them directly + virtual void getInfo1 (btConstraintInfo1* info); + + ///internal method used by the constraint solver, don't use them directly + virtual void getInfo2 (btConstraintInfo2* info); + + virtual void setParam(int num, btScalar value, int axis = -1) + { + btAssert(0); + }; + + ///return the local value of parameter + virtual btScalar getParam(int num, int axis = -1) const + { + btAssert(0); + return 0.f; + } + +}; + +#endif //BT_GEAR_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp new file mode 100644 index 0000000..d4b4a9a --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -0,0 +1,1064 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +/* +2007-09-09 +Refactored by Francisco Le?n +email: projectileman@yahoo.com +http://gimpact.sf.net +*/ + +#include "btGeneric6DofConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btTransformUtil.h" +#include + + + +#define D6_USE_OBSOLETE_METHOD false +#define D6_USE_FRAME_OFFSET true + + + + + + +btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) +: btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB) +, m_frameInA(frameInA) +, m_frameInB(frameInB), +m_useLinearReferenceFrameA(useLinearReferenceFrameA), +m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), +m_flags(0), +m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD) +{ + calculateTransforms(); +} + + + +btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) + : btTypedConstraint(D6_CONSTRAINT_TYPE, getFixedBody(), rbB), + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameB), + m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), + m_flags(0), + m_useSolveConstraintObsolete(false) +{ + ///not providing rigidbody A means implicitly using worldspace for body A + m_frameInA = rbB.getCenterOfMassTransform() * m_frameInB; + calculateTransforms(); +} + + + + +#define GENERIC_D6_DISABLE_WARMSTARTING 1 + + + +btScalar btGetMatrixElem(const btMatrix3x3& mat, int index); +btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) +{ + int i = index%3; + int j = index/3; + return mat[i][j]; +} + + + +///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html +bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz); +bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) +{ + // // rot = cy*cz -cy*sz sy + // // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx + // // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy + // + + btScalar fi = btGetMatrixElem(mat,2); + if (fi < btScalar(1.0f)) + { + if (fi > btScalar(-1.0f)) + { + xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); + xyz[1] = btAsin(btGetMatrixElem(mat,2)); + xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); + return true; + } + else + { + // WARNING. Not unique. XA - ZA = -atan2(r10,r11) + xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[1] = -SIMD_HALF_PI; + xyz[2] = btScalar(0.0); + return false; + } + } + else + { + // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) + xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[1] = SIMD_HALF_PI; + xyz[2] = 0.0; + } + return false; +} + +//////////////////////////// btRotationalLimitMotor //////////////////////////////////// + +int btRotationalLimitMotor::testLimitValue(btScalar test_value) +{ + if(m_loLimit>m_hiLimit) + { + m_currentLimit = 0;//Free from violation + return 0; + } + if (test_value < m_loLimit) + { + m_currentLimit = 1;//low limit violation + m_currentLimitError = test_value - m_loLimit; + if(m_currentLimitError>SIMD_PI) + m_currentLimitError-=SIMD_2_PI; + else if(m_currentLimitError<-SIMD_PI) + m_currentLimitError+=SIMD_2_PI; + return 1; + } + else if (test_value> m_hiLimit) + { + m_currentLimit = 2;//High limit violation + m_currentLimitError = test_value - m_hiLimit; + if(m_currentLimitError>SIMD_PI) + m_currentLimitError-=SIMD_2_PI; + else if(m_currentLimitError<-SIMD_PI) + m_currentLimitError+=SIMD_2_PI; + return 2; + }; + + m_currentLimit = 0;//Free from violation + return 0; + +} + + + +btScalar btRotationalLimitMotor::solveAngularLimits( + btScalar timeStep,btVector3& axis,btScalar jacDiagABInv, + btRigidBody * body0, btRigidBody * body1 ) +{ + if (needApplyTorques()==false) return 0.0f; + + btScalar target_velocity = m_targetVelocity; + btScalar maxMotorForce = m_maxMotorForce; + + //current error correction + if (m_currentLimit!=0) + { + target_velocity = -m_stopERP*m_currentLimitError/(timeStep); + maxMotorForce = m_maxLimitForce; + } + + maxMotorForce *= timeStep; + + // current velocity difference + + btVector3 angVelA = body0->getAngularVelocity(); + btVector3 angVelB = body1->getAngularVelocity(); + + btVector3 vel_diff; + vel_diff = angVelA-angVelB; + + + + btScalar rel_vel = axis.dot(vel_diff); + + // correction velocity + btScalar motor_relvel = m_limitSoftness*(target_velocity - m_damping*rel_vel); + + + if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON ) + { + return 0.0f;//no need for applying force + } + + + // correction impulse + btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv; + + // clip correction impulse + btScalar clippedMotorImpulse; + + ///@todo: should clip against accumulated impulse + if (unclippedMotorImpulse>0.0f) + { + clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse; + } + else + { + clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse; + } + + + // sort with accumulated impulses + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); + + btScalar oldaccumImpulse = m_accumulatedImpulse; + btScalar sum = oldaccumImpulse + clippedMotorImpulse; + m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; + + clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse; + + btVector3 motorImp = clippedMotorImpulse * axis; + + body0->applyTorqueImpulse(motorImp); + body1->applyTorqueImpulse(-motorImp); + + return clippedMotorImpulse; + + +} + +//////////////////////////// End btRotationalLimitMotor //////////////////////////////////// + + + + +//////////////////////////// btTranslationalLimitMotor //////////////////////////////////// + + +int btTranslationalLimitMotor::testLimitValue(int limitIndex, btScalar test_value) +{ + btScalar loLimit = m_lowerLimit[limitIndex]; + btScalar hiLimit = m_upperLimit[limitIndex]; + if(loLimit > hiLimit) + { + m_currentLimit[limitIndex] = 0;//Free from violation + m_currentLimitError[limitIndex] = btScalar(0.f); + return 0; + } + + if (test_value < loLimit) + { + m_currentLimit[limitIndex] = 2;//low limit violation + m_currentLimitError[limitIndex] = test_value - loLimit; + return 2; + } + else if (test_value> hiLimit) + { + m_currentLimit[limitIndex] = 1;//High limit violation + m_currentLimitError[limitIndex] = test_value - hiLimit; + return 1; + }; + + m_currentLimit[limitIndex] = 0;//Free from violation + m_currentLimitError[limitIndex] = btScalar(0.f); + return 0; +} + + + +btScalar btTranslationalLimitMotor::solveLinearAxis( + btScalar timeStep, + btScalar jacDiagABInv, + btRigidBody& body1,const btVector3 &pointInA, + btRigidBody& body2,const btVector3 &pointInB, + int limit_index, + const btVector3 & axis_normal_on_a, + const btVector3 & anchorPos) +{ + + ///find relative velocity + // btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition(); + // btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition(); + btVector3 rel_pos1 = anchorPos - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = anchorPos - body2.getCenterOfMassPosition(); + + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar rel_vel = axis_normal_on_a.dot(vel); + + + + /// apply displacement correction + + //positional error (zeroth order error) + btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); + + btScalar minLimit = m_lowerLimit[limit_index]; + btScalar maxLimit = m_upperLimit[limit_index]; + + //handle the limits + if (minLimit < maxLimit) + { + { + if (depth > maxLimit) + { + depth -= maxLimit; + lo = btScalar(0.); + + } + else + { + if (depth < minLimit) + { + depth -= minLimit; + hi = btScalar(0.); + } + else + { + return 0.0f; + } + } + } + } + + btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv; + + + + + btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index]; + btScalar sum = oldNormalImpulse + normalImpulse; + m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; + normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse; + + btVector3 impulse_vector = axis_normal_on_a * normalImpulse; + body1.applyImpulse( impulse_vector, rel_pos1); + body2.applyImpulse(-impulse_vector, rel_pos2); + + + + return normalImpulse; +} + +//////////////////////////// btTranslationalLimitMotor //////////////////////////////////// + +void btGeneric6DofConstraint::calculateAngleInfo() +{ + btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis(); + matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff); + // in euler angle mode we do not actually constrain the angular velocity + // along the axes axis[0] and axis[2] (although we do use axis[1]) : + // + // to get constrain w2-w1 along ...not + // ------ --------------------- ------ + // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] + // d(angle[1])/dt = 0 ax[1] + // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] + // + // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. + // to prove the result for angle[0], write the expression for angle[0] from + // GetInfo1 then take the derivative. to prove this for angle[2] it is + // easier to take the euler rate expression for d(angle[2])/dt with respect + // to the components of w and set that to 0. + btVector3 axis0 = m_calculatedTransformB.getBasis().getColumn(0); + btVector3 axis2 = m_calculatedTransformA.getBasis().getColumn(2); + + m_calculatedAxis[1] = axis2.cross(axis0); + m_calculatedAxis[0] = m_calculatedAxis[1].cross(axis2); + m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]); + + m_calculatedAxis[0].normalize(); + m_calculatedAxis[1].normalize(); + m_calculatedAxis[2].normalize(); + +} + +void btGeneric6DofConstraint::calculateTransforms() +{ + calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); +} + +void btGeneric6DofConstraint::calculateTransforms(const btTransform& transA,const btTransform& transB) +{ + m_calculatedTransformA = transA * m_frameInA; + m_calculatedTransformB = transB * m_frameInB; + calculateLinearInfo(); + calculateAngleInfo(); + if(m_useOffsetForConstraintFrame) + { // get weight factors depending on masses + btScalar miA = getRigidBodyA().getInvMass(); + btScalar miB = getRigidBodyB().getInvMass(); + m_hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON); + btScalar miS = miA + miB; + if(miS > btScalar(0.f)) + { + m_factA = miB / miS; + } + else + { + m_factA = btScalar(0.5f); + } + m_factB = btScalar(1.0f) - m_factA; + } +} + + + +void btGeneric6DofConstraint::buildLinearJacobian( + btJacobianEntry & jacLinear,const btVector3 & normalWorld, + const btVector3 & pivotAInW,const btVector3 & pivotBInW) +{ + new (&jacLinear) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normalWorld, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); +} + + + +void btGeneric6DofConstraint::buildAngularJacobian( + btJacobianEntry & jacAngular,const btVector3 & jointAxisW) +{ + new (&jacAngular) btJacobianEntry(jointAxisW, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + +} + + + +bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) +{ + btScalar angle = m_calculatedAxisAngleDiff[axis_index]; + angle = btAdjustAngleToLimits(angle, m_angularLimits[axis_index].m_loLimit, m_angularLimits[axis_index].m_hiLimit); + m_angularLimits[axis_index].m_currentPosition = angle; + //test limits + m_angularLimits[axis_index].testLimitValue(angle); + return m_angularLimits[axis_index].needApplyTorques(); +} + + + +void btGeneric6DofConstraint::buildJacobian() +{ +#ifndef __SPU__ + if (m_useSolveConstraintObsolete) + { + + // Clear accumulated impulses for the next simulation step + m_linearLimits.m_accumulatedImpulse.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); + int i; + for(i = 0; i < 3; i++) + { + m_angularLimits[i].m_accumulatedImpulse = btScalar(0.); + } + //calculates transform + calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + + // const btVector3& pivotAInW = m_calculatedTransformA.getOrigin(); + // const btVector3& pivotBInW = m_calculatedTransformB.getOrigin(); + calcAnchorPos(); + btVector3 pivotAInW = m_AnchorPos; + btVector3 pivotBInW = m_AnchorPos; + + // not used here + // btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + // btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + btVector3 normalWorld; + //linear part + for (i=0;i<3;i++) + { + if (m_linearLimits.isLimited(i)) + { + if (m_useLinearReferenceFrameA) + normalWorld = m_calculatedTransformA.getBasis().getColumn(i); + else + normalWorld = m_calculatedTransformB.getBasis().getColumn(i); + + buildLinearJacobian( + m_jacLinear[i],normalWorld , + pivotAInW,pivotBInW); + + } + } + + // angular part + for (i=0;i<3;i++) + { + //calculates error angle + if (testAngularLimitMotor(i)) + { + normalWorld = this->getAxis(i); + // Create angular atom + buildAngularJacobian(m_jacAng[i],normalWorld); + } + } + + } +#endif //__SPU__ + +} + + +void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) +{ + if (m_useSolveConstraintObsolete) + { + info->m_numConstraintRows = 0; + info->nub = 0; + } else + { + //prepare constraint + calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + info->m_numConstraintRows = 0; + info->nub = 6; + int i; + //test linear limits + for(i = 0; i < 3; i++) + { + if(m_linearLimits.needApplyForce(i)) + { + info->m_numConstraintRows++; + info->nub--; + } + } + //test angular limits + for (i=0;i<3 ;i++ ) + { + if(testAngularLimitMotor(i)) + { + info->m_numConstraintRows++; + info->nub--; + } + } + } +} + +void btGeneric6DofConstraint::getInfo1NonVirtual (btConstraintInfo1* info) +{ + if (m_useSolveConstraintObsolete) + { + info->m_numConstraintRows = 0; + info->nub = 0; + } else + { + //pre-allocate all 6 + info->m_numConstraintRows = 6; + info->nub = 0; + } +} + + +void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) +{ + btAssert(!m_useSolveConstraintObsolete); + + const btTransform& transA = m_rbA.getCenterOfMassTransform(); + const btTransform& transB = m_rbB.getCenterOfMassTransform(); + const btVector3& linVelA = m_rbA.getLinearVelocity(); + const btVector3& linVelB = m_rbB.getLinearVelocity(); + const btVector3& angVelA = m_rbA.getAngularVelocity(); + const btVector3& angVelB = m_rbB.getAngularVelocity(); + + if(m_useOffsetForConstraintFrame) + { // for stability better to solve angular limits first + int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB); + setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB); + } + else + { // leave old version for compatibility + int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB); + setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB); + } + +} + + +void btGeneric6DofConstraint::getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +{ + + btAssert(!m_useSolveConstraintObsolete); + //prepare constraint + calculateTransforms(transA,transB); + + int i; + for (i=0;i<3 ;i++ ) + { + testAngularLimitMotor(i); + } + + if(m_useOffsetForConstraintFrame) + { // for stability better to solve angular limits first + int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB); + setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB); + } + else + { // leave old version for compatibility + int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB); + setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB); + } +} + + + +int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +{ +// int row = 0; + //solve linear limits + btRotationalLimitMotor limot; + for (int i=0;i<3 ;i++ ) + { + if(m_linearLimits.needApplyForce(i)) + { // re-use rotational motor code + limot.m_bounce = btScalar(0.f); + limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; + limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i]; + limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; + limot.m_damping = m_linearLimits.m_damping; + limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; + limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; + limot.m_limitSoftness = m_linearLimits.m_limitSoftness; + limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; + limot.m_maxLimitForce = btScalar(0.f); + limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; + limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; + btVector3 axis = m_calculatedTransformA.getBasis().getColumn(i); + int flags = m_flags >> (i * BT_6DOF_FLAGS_AXIS_SHIFT); + limot.m_normalCFM = (flags & BT_6DOF_FLAGS_CFM_NORM) ? m_linearLimits.m_normalCFM[i] : info->cfm[0]; + limot.m_stopCFM = (flags & BT_6DOF_FLAGS_CFM_STOP) ? m_linearLimits.m_stopCFM[i] : info->cfm[0]; + limot.m_stopERP = (flags & BT_6DOF_FLAGS_ERP_STOP) ? m_linearLimits.m_stopERP[i] : info->erp; + if(m_useOffsetForConstraintFrame) + { + int indx1 = (i + 1) % 3; + int indx2 = (i + 2) % 3; + int rotAllowed = 1; // rotations around orthos to current axis + if(m_angularLimits[indx1].m_currentLimit && m_angularLimits[indx2].m_currentLimit) + { + rotAllowed = 0; + } + row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0, rotAllowed); + } + else + { + row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0); + } + } + } + return row; +} + + + +int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +{ + btGeneric6DofConstraint * d6constraint = this; + int row = row_offset; + //solve angular limits + for (int i=0;i<3 ;i++ ) + { + if(d6constraint->getRotationalLimitMotor(i)->needApplyTorques()) + { + btVector3 axis = d6constraint->getAxis(i); + int flags = m_flags >> ((i + 3) * BT_6DOF_FLAGS_AXIS_SHIFT); + if(!(flags & BT_6DOF_FLAGS_CFM_NORM)) + { + m_angularLimits[i].m_normalCFM = info->cfm[0]; + } + if(!(flags & BT_6DOF_FLAGS_CFM_STOP)) + { + m_angularLimits[i].m_stopCFM = info->cfm[0]; + } + if(!(flags & BT_6DOF_FLAGS_ERP_STOP)) + { + m_angularLimits[i].m_stopERP = info->erp; + } + row += get_limit_motor_info2(d6constraint->getRotationalLimitMotor(i), + transA,transB,linVelA,linVelB,angVelA,angVelB, info,row,axis,1); + } + } + + return row; +} + + + + +void btGeneric6DofConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} + + +void btGeneric6DofConstraint::setFrames(const btTransform& frameA, const btTransform& frameB) +{ + m_frameInA = frameA; + m_frameInB = frameB; + buildJacobian(); + calculateTransforms(); +} + + + +btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const +{ + return m_calculatedAxis[axis_index]; +} + + +btScalar btGeneric6DofConstraint::getRelativePivotPosition(int axisIndex) const +{ + return m_calculatedLinearDiff[axisIndex]; +} + + +btScalar btGeneric6DofConstraint::getAngle(int axisIndex) const +{ + return m_calculatedAxisAngleDiff[axisIndex]; +} + + + +void btGeneric6DofConstraint::calcAnchorPos(void) +{ + btScalar imA = m_rbA.getInvMass(); + btScalar imB = m_rbB.getInvMass(); + btScalar weight; + if(imB == btScalar(0.0)) + { + weight = btScalar(1.0); + } + else + { + weight = imA / (imA + imB); + } + const btVector3& pA = m_calculatedTransformA.getOrigin(); + const btVector3& pB = m_calculatedTransformB.getOrigin(); + m_AnchorPos = pA * weight + pB * (btScalar(1.0) - weight); + return; +} + + + +void btGeneric6DofConstraint::calculateLinearInfo() +{ + m_calculatedLinearDiff = m_calculatedTransformB.getOrigin() - m_calculatedTransformA.getOrigin(); + m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff; + for(int i = 0; i < 3; i++) + { + m_linearLimits.m_currentLinearDiff[i] = m_calculatedLinearDiff[i]; + m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]); + } +} + + + +int btGeneric6DofConstraint::get_limit_motor_info2( + btRotationalLimitMotor * limot, + const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB, + btConstraintInfo2 *info, int row, btVector3& ax1, int rotational,int rotAllowed) +{ + int srow = row * info->rowskip; + int powered = limot->m_enableMotor; + int limit = limot->m_currentLimit; + if (powered || limit) + { // if the joint is powered, or has joint limits, add in the extra row + btScalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis; + btScalar *J2 = rotational ? info->m_J2angularAxis : 0; + J1[srow+0] = ax1[0]; + J1[srow+1] = ax1[1]; + J1[srow+2] = ax1[2]; + if(rotational) + { + J2[srow+0] = -ax1[0]; + J2[srow+1] = -ax1[1]; + J2[srow+2] = -ax1[2]; + } + if((!rotational)) + { + if (m_useOffsetForConstraintFrame) + { + btVector3 tmpA, tmpB, relA, relB; + // get vector from bodyB to frameB in WCS + relB = m_calculatedTransformB.getOrigin() - transB.getOrigin(); + // get its projection to constraint axis + btVector3 projB = ax1 * relB.dot(ax1); + // get vector directed from bodyB to constraint axis (and orthogonal to it) + btVector3 orthoB = relB - projB; + // same for bodyA + relA = m_calculatedTransformA.getOrigin() - transA.getOrigin(); + btVector3 projA = ax1 * relA.dot(ax1); + btVector3 orthoA = relA - projA; + // get desired offset between frames A and B along constraint axis + btScalar desiredOffs = limot->m_currentPosition - limot->m_currentLimitError; + // desired vector from projection of center of bodyA to projection of center of bodyB to constraint axis + btVector3 totalDist = projA + ax1 * desiredOffs - projB; + // get offset vectors relA and relB + relA = orthoA + totalDist * m_factA; + relB = orthoB - totalDist * m_factB; + tmpA = relA.cross(ax1); + tmpB = relB.cross(ax1); + if(m_hasStaticBody && (!rotAllowed)) + { + tmpA *= m_factA; + tmpB *= m_factB; + } + int i; + for (i=0; i<3; i++) info->m_J1angularAxis[srow+i] = tmpA[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[srow+i] = -tmpB[i]; + } else + { + btVector3 ltd; // Linear Torque Decoupling vector + btVector3 c = m_calculatedTransformB.getOrigin() - transA.getOrigin(); + ltd = c.cross(ax1); + info->m_J1angularAxis[srow+0] = ltd[0]; + info->m_J1angularAxis[srow+1] = ltd[1]; + info->m_J1angularAxis[srow+2] = ltd[2]; + + c = m_calculatedTransformB.getOrigin() - transB.getOrigin(); + ltd = -c.cross(ax1); + info->m_J2angularAxis[srow+0] = ltd[0]; + info->m_J2angularAxis[srow+1] = ltd[1]; + info->m_J2angularAxis[srow+2] = ltd[2]; + } + } + // if we're limited low and high simultaneously, the joint motor is + // ineffective + if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = 0; + info->m_constraintError[srow] = btScalar(0.f); + if (powered) + { + info->cfm[srow] = limot->m_normalCFM; + if(!limit) + { + btScalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity; + + btScalar mot_fact = getMotorFactor( limot->m_currentPosition, + limot->m_loLimit, + limot->m_hiLimit, + tag_vel, + info->fps * limot->m_stopERP); + info->m_constraintError[srow] += mot_fact * limot->m_targetVelocity; + info->m_lowerLimit[srow] = -limot->m_maxMotorForce; + info->m_upperLimit[srow] = limot->m_maxMotorForce; + } + } + if(limit) + { + btScalar k = info->fps * limot->m_stopERP; + if(!rotational) + { + info->m_constraintError[srow] += k * limot->m_currentLimitError; + } + else + { + info->m_constraintError[srow] += -k * limot->m_currentLimitError; + } + info->cfm[srow] = limot->m_stopCFM; + if (limot->m_loLimit == limot->m_hiLimit) + { // limited low and high simultaneously + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { + if (limit == 1) + { + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = 0; + } + // deal with bounce + if (limot->m_bounce > 0) + { + // calculate joint velocity + btScalar vel; + if (rotational) + { + vel = angVelA.dot(ax1); +//make sure that if no body -> angVelB == zero vec +// if (body1) + vel -= angVelB.dot(ax1); + } + else + { + vel = linVelA.dot(ax1); +//make sure that if no body -> angVelB == zero vec +// if (body1) + vel -= linVelB.dot(ax1); + } + // only apply bounce if the velocity is incoming, and if the + // resulting c[] exceeds what we already have. + if (limit == 1) + { + if (vel < 0) + { + btScalar newc = -limot->m_bounce* vel; + if (newc > info->m_constraintError[srow]) + info->m_constraintError[srow] = newc; + } + } + else + { + if (vel > 0) + { + btScalar newc = -limot->m_bounce * vel; + if (newc < info->m_constraintError[srow]) + info->m_constraintError[srow] = newc; + } + } + } + } + } + return 1; + } + else return 0; +} + + + + + + + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///If no axis is provided, it uses the default axis for this constraint. +void btGeneric6DofConstraint::setParam(int num, btScalar value, int axis) +{ + if((axis >= 0) && (axis < 3)) + { + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + m_linearLimits.m_stopERP[axis] = value; + m_flags |= BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); + break; + case BT_CONSTRAINT_STOP_CFM : + m_linearLimits.m_stopCFM[axis] = value; + m_flags |= BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); + break; + case BT_CONSTRAINT_CFM : + m_linearLimits.m_normalCFM[axis] = value; + m_flags |= BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); + break; + default : + btAssertConstrParams(0); + } + } + else if((axis >=3) && (axis < 6)) + { + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + m_angularLimits[axis - 3].m_stopERP = value; + m_flags |= BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); + break; + case BT_CONSTRAINT_STOP_CFM : + m_angularLimits[axis - 3].m_stopCFM = value; + m_flags |= BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); + break; + case BT_CONSTRAINT_CFM : + m_angularLimits[axis - 3].m_normalCFM = value; + m_flags |= BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); + break; + default : + btAssertConstrParams(0); + } + } + else + { + btAssertConstrParams(0); + } +} + + ///return the local value of parameter +btScalar btGeneric6DofConstraint::getParam(int num, int axis) const +{ + btScalar retVal = 0; + if((axis >= 0) && (axis < 3)) + { + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); + retVal = m_linearLimits.m_stopERP[axis]; + break; + case BT_CONSTRAINT_STOP_CFM : + btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); + retVal = m_linearLimits.m_stopCFM[axis]; + break; + case BT_CONSTRAINT_CFM : + btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); + retVal = m_linearLimits.m_normalCFM[axis]; + break; + default : + btAssertConstrParams(0); + } + } + else if((axis >=3) && (axis < 6)) + { + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); + retVal = m_angularLimits[axis - 3].m_stopERP; + break; + case BT_CONSTRAINT_STOP_CFM : + btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); + retVal = m_angularLimits[axis - 3].m_stopCFM; + break; + case BT_CONSTRAINT_CFM : + btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); + retVal = m_angularLimits[axis - 3].m_normalCFM; + break; + default : + btAssertConstrParams(0); + } + } + else + { + btAssertConstrParams(0); + } + return retVal; +} + + + +void btGeneric6DofConstraint::setAxis(const btVector3& axis1,const btVector3& axis2) +{ + btVector3 zAxis = axis1.normalized(); + btVector3 yAxis = axis2.normalized(); + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + + btTransform frameInW; + frameInW.setIdentity(); + frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + + // now get constraint frame in local coordinate systems + m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW; + m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW; + + calculateTransforms(); +} diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h new file mode 100644 index 0000000..0409f95 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -0,0 +1,616 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/// 2009 March: btGeneric6DofConstraint refactored by Roman Ponomarev +/// Added support for generic constraint solver through getInfo1/getInfo2 methods + +/* +2007-09-09 +btGeneric6DofConstraint Refactored by Francisco Le?n +email: projectileman@yahoo.com +http://gimpact.sf.net +*/ + + +#ifndef BT_GENERIC_6DOF_CONSTRAINT_H +#define BT_GENERIC_6DOF_CONSTRAINT_H + +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + + + + +//! Rotation Limit structure for generic joints +class btRotationalLimitMotor +{ +public: + //! limit_parameters + //!@{ + btScalar m_loLimit;//!< joint limit + btScalar m_hiLimit;//!< joint limit + btScalar m_targetVelocity;//!< target motor velocity + btScalar m_maxMotorForce;//!< max force on motor + btScalar m_maxLimitForce;//!< max force on limit + btScalar m_damping;//!< Damping. + btScalar m_limitSoftness;//! Relaxation factor + btScalar m_normalCFM;//!< Constraint force mixing factor + btScalar m_stopERP;//!< Error tolerance factor when joint is at limit + btScalar m_stopCFM;//!< Constraint force mixing factor when joint is at limit + btScalar m_bounce;//!< restitution factor + bool m_enableMotor; + + //!@} + + //! temp_variables + //!@{ + btScalar m_currentLimitError;//! How much is violated this limit + btScalar m_currentPosition; //! current value of angle + int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit + btScalar m_accumulatedImpulse; + //!@} + + btRotationalLimitMotor() + { + m_accumulatedImpulse = 0.f; + m_targetVelocity = 0; + m_maxMotorForce = 0.1f; + m_maxLimitForce = 300.0f; + m_loLimit = 1.0f; + m_hiLimit = -1.0f; + m_normalCFM = 0.f; + m_stopERP = 0.2f; + m_stopCFM = 0.f; + m_bounce = 0.0f; + m_damping = 1.0f; + m_limitSoftness = 0.5f; + m_currentLimit = 0; + m_currentLimitError = 0; + m_enableMotor = false; + } + + btRotationalLimitMotor(const btRotationalLimitMotor & limot) + { + m_targetVelocity = limot.m_targetVelocity; + m_maxMotorForce = limot.m_maxMotorForce; + m_limitSoftness = limot.m_limitSoftness; + m_loLimit = limot.m_loLimit; + m_hiLimit = limot.m_hiLimit; + m_normalCFM = limot.m_normalCFM; + m_stopERP = limot.m_stopERP; + m_stopCFM = limot.m_stopCFM; + m_bounce = limot.m_bounce; + m_currentLimit = limot.m_currentLimit; + m_currentLimitError = limot.m_currentLimitError; + m_enableMotor = limot.m_enableMotor; + } + + + + //! Is limited + bool isLimited() + { + if(m_loLimit > m_hiLimit) return false; + return true; + } + + //! Need apply correction + bool needApplyTorques() + { + if(m_currentLimit == 0 && m_enableMotor == false) return false; + return true; + } + + //! calculates error + /*! + calculates m_currentLimit and m_currentLimitError. + */ + int testLimitValue(btScalar test_value); + + //! apply the correction impulses for two bodies + btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1); + +}; + + + +class btTranslationalLimitMotor +{ +public: + btVector3 m_lowerLimit;//!< the constraint lower limits + btVector3 m_upperLimit;//!< the constraint upper limits + btVector3 m_accumulatedImpulse; + //! Linear_Limit_parameters + //!@{ + btScalar m_limitSoftness;//!< Softness for linear limit + btScalar m_damping;//!< Damping for linear limit + btScalar m_restitution;//! Bounce parameter for linear limit + btVector3 m_normalCFM;//!< Constraint force mixing factor + btVector3 m_stopERP;//!< Error tolerance factor when joint is at limit + btVector3 m_stopCFM;//!< Constraint force mixing factor when joint is at limit + //!@} + bool m_enableMotor[3]; + btVector3 m_targetVelocity;//!< target motor velocity + btVector3 m_maxMotorForce;//!< max force on motor + btVector3 m_currentLimitError;//! How much is violated this limit + btVector3 m_currentLinearDiff;//! Current relative offset of constraint frames + int m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit + + btTranslationalLimitMotor() + { + m_lowerLimit.setValue(0.f,0.f,0.f); + m_upperLimit.setValue(0.f,0.f,0.f); + m_accumulatedImpulse.setValue(0.f,0.f,0.f); + m_normalCFM.setValue(0.f, 0.f, 0.f); + m_stopERP.setValue(0.2f, 0.2f, 0.2f); + m_stopCFM.setValue(0.f, 0.f, 0.f); + + m_limitSoftness = 0.7f; + m_damping = btScalar(1.0f); + m_restitution = btScalar(0.5f); + for(int i=0; i < 3; i++) + { + m_enableMotor[i] = false; + m_targetVelocity[i] = btScalar(0.f); + m_maxMotorForce[i] = btScalar(0.f); + } + } + + btTranslationalLimitMotor(const btTranslationalLimitMotor & other ) + { + m_lowerLimit = other.m_lowerLimit; + m_upperLimit = other.m_upperLimit; + m_accumulatedImpulse = other.m_accumulatedImpulse; + + m_limitSoftness = other.m_limitSoftness ; + m_damping = other.m_damping; + m_restitution = other.m_restitution; + m_normalCFM = other.m_normalCFM; + m_stopERP = other.m_stopERP; + m_stopCFM = other.m_stopCFM; + + for(int i=0; i < 3; i++) + { + m_enableMotor[i] = other.m_enableMotor[i]; + m_targetVelocity[i] = other.m_targetVelocity[i]; + m_maxMotorForce[i] = other.m_maxMotorForce[i]; + } + } + + //! Test limit + /*! + - free means upper < lower, + - locked means upper == lower + - limited means upper > lower + - limitIndex: first 3 are linear, next 3 are angular + */ + inline bool isLimited(int limitIndex) + { + return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); + } + inline bool needApplyForce(int limitIndex) + { + if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false; + return true; + } + int testLimitValue(int limitIndex, btScalar test_value); + + + btScalar solveLinearAxis( + btScalar timeStep, + btScalar jacDiagABInv, + btRigidBody& body1,const btVector3 &pointInA, + btRigidBody& body2,const btVector3 &pointInB, + int limit_index, + const btVector3 & axis_normal_on_a, + const btVector3 & anchorPos); + + +}; + +enum bt6DofFlags +{ + BT_6DOF_FLAGS_CFM_NORM = 1, + BT_6DOF_FLAGS_CFM_STOP = 2, + BT_6DOF_FLAGS_ERP_STOP = 4 +}; +#define BT_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis + + +/// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space +/*! +btGeneric6DofConstraint can leave any of the 6 degree of freedom 'free' or 'locked'. +currently this limit supports rotational motors
    +
      +
    • For Linear limits, use btGeneric6DofConstraint.setLinearUpperLimit, btGeneric6DofConstraint.setLinearLowerLimit. You can set the parameters with the btTranslationalLimitMotor structure accsesible through the btGeneric6DofConstraint.getTranslationalLimitMotor method. +At this moment translational motors are not supported. May be in the future.
    • + +
    • For Angular limits, use the btRotationalLimitMotor structure for configuring the limit. +This is accessible through btGeneric6DofConstraint.getLimitMotor method, +This brings support for limit parameters and motors.
    • + +
    • Angulars limits have these possible ranges: + + + + + + + + + + + + + + + + + + +
      AXISMIN ANGLEMAX ANGLE
      X-PIPI
      Y-PI/2PI/2
      Z-PIPI
      +
    • +
    + +*/ +ATTRIBUTE_ALIGNED16(class) btGeneric6DofConstraint : public btTypedConstraint +{ +protected: + + //! relative_frames + //!@{ + btTransform m_frameInA;//!< the constraint space w.r.t body A + btTransform m_frameInB;//!< the constraint space w.r.t body B + //!@} + + //! Jacobians + //!@{ + btJacobianEntry m_jacLinear[3];//!< 3 orthogonal linear constraints + btJacobianEntry m_jacAng[3];//!< 3 orthogonal angular constraints + //!@} + + //! Linear_Limit_parameters + //!@{ + btTranslationalLimitMotor m_linearLimits; + //!@} + + + //! hinge_parameters + //!@{ + btRotationalLimitMotor m_angularLimits[3]; + //!@} + + +protected: + //! temporal variables + //!@{ + btScalar m_timeStep; + btTransform m_calculatedTransformA; + btTransform m_calculatedTransformB; + btVector3 m_calculatedAxisAngleDiff; + btVector3 m_calculatedAxis[3]; + btVector3 m_calculatedLinearDiff; + btScalar m_factA; + btScalar m_factB; + bool m_hasStaticBody; + + btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes + + bool m_useLinearReferenceFrameA; + bool m_useOffsetForConstraintFrame; + + int m_flags; + + //!@} + + btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other) + { + btAssert(0); + (void) other; + return *this; + } + + + int setAngularLimits(btConstraintInfo2 *info, int row_offset,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); + + int setLinearLimits(btConstraintInfo2 *info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); + + void buildLinearJacobian( + btJacobianEntry & jacLinear,const btVector3 & normalWorld, + const btVector3 & pivotAInW,const btVector3 & pivotBInW); + + void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW); + + // tests linear limits + void calculateLinearInfo(); + + //! calcs the euler angles between the two bodies. + void calculateAngleInfo(); + + + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + ///for backwards compatibility during the transition to 'getInfo/getInfo2' + bool m_useSolveConstraintObsolete; + + btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); + + //! Calcs global transform of the offsets + /*! + Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies. + \sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo + */ + void calculateTransforms(const btTransform& transA,const btTransform& transB); + + void calculateTransforms(); + + //! Gets the global transform of the offset for body A + /*! + \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. + */ + const btTransform & getCalculatedTransformA() const + { + return m_calculatedTransformA; + } + + //! Gets the global transform of the offset for body B + /*! + \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. + */ + const btTransform & getCalculatedTransformB() const + { + return m_calculatedTransformB; + } + + const btTransform & getFrameOffsetA() const + { + return m_frameInA; + } + + const btTransform & getFrameOffsetB() const + { + return m_frameInB; + } + + + btTransform & getFrameOffsetA() + { + return m_frameInA; + } + + btTransform & getFrameOffsetB() + { + return m_frameInB; + } + + + //! performs Jacobian calculation, and also calculates angle differences and axis + virtual void buildJacobian(); + + virtual void getInfo1 (btConstraintInfo1* info); + + void getInfo1NonVirtual (btConstraintInfo1* info); + + virtual void getInfo2 (btConstraintInfo2* info); + + void getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); + + + void updateRHS(btScalar timeStep); + + //! Get the rotation axis in global coordinates + /*! + \pre btGeneric6DofConstraint.buildJacobian must be called previously. + */ + btVector3 getAxis(int axis_index) const; + + //! Get the relative Euler angle + /*! + \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. + */ + btScalar getAngle(int axis_index) const; + + //! Get the relative position of the constraint pivot + /*! + \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. + */ + btScalar getRelativePivotPosition(int axis_index) const; + + void setFrames(const btTransform & frameA, const btTransform & frameB); + + //! Test angular limit. + /*! + Calculates angular correction and returns true if limit needs to be corrected. + \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. + */ + bool testAngularLimitMotor(int axis_index); + + void setLinearLowerLimit(const btVector3& linearLower) + { + m_linearLimits.m_lowerLimit = linearLower; + } + + void getLinearLowerLimit(btVector3& linearLower) + { + linearLower = m_linearLimits.m_lowerLimit; + } + + void setLinearUpperLimit(const btVector3& linearUpper) + { + m_linearLimits.m_upperLimit = linearUpper; + } + + void getLinearUpperLimit(btVector3& linearUpper) + { + linearUpper = m_linearLimits.m_upperLimit; + } + + void setAngularLowerLimit(const btVector3& angularLower) + { + for(int i = 0; i < 3; i++) + m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]); + } + + void getAngularLowerLimit(btVector3& angularLower) + { + for(int i = 0; i < 3; i++) + angularLower[i] = m_angularLimits[i].m_loLimit; + } + + void setAngularUpperLimit(const btVector3& angularUpper) + { + for(int i = 0; i < 3; i++) + m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]); + } + + void getAngularUpperLimit(btVector3& angularUpper) + { + for(int i = 0; i < 3; i++) + angularUpper[i] = m_angularLimits[i].m_hiLimit; + } + + //! Retrieves the angular limit informacion + btRotationalLimitMotor * getRotationalLimitMotor(int index) + { + return &m_angularLimits[index]; + } + + //! Retrieves the limit informacion + btTranslationalLimitMotor * getTranslationalLimitMotor() + { + return &m_linearLimits; + } + + //first 3 are linear, next 3 are angular + void setLimit(int axis, btScalar lo, btScalar hi) + { + if(axis<3) + { + m_linearLimits.m_lowerLimit[axis] = lo; + m_linearLimits.m_upperLimit[axis] = hi; + } + else + { + lo = btNormalizeAngle(lo); + hi = btNormalizeAngle(hi); + m_angularLimits[axis-3].m_loLimit = lo; + m_angularLimits[axis-3].m_hiLimit = hi; + } + } + + //! Test limit + /*! + - free means upper < lower, + - locked means upper == lower + - limited means upper > lower + - limitIndex: first 3 are linear, next 3 are angular + */ + bool isLimited(int limitIndex) + { + if(limitIndex<3) + { + return m_linearLimits.isLimited(limitIndex); + + } + return m_angularLimits[limitIndex-3].isLimited(); + } + + virtual void calcAnchorPos(void); // overridable + + int get_limit_motor_info2( btRotationalLimitMotor * limot, + const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB, + btConstraintInfo2 *info, int row, btVector3& ax1, int rotational, int rotAllowed = false); + + // access for UseFrameOffset + bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; } + void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; } + + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///If no axis is provided, it uses the default axis for this constraint. + virtual void setParam(int num, btScalar value, int axis = -1); + ///return the local value of parameter + virtual btScalar getParam(int num, int axis = -1) const; + + void setAxis( const btVector3& axis1, const btVector3& axis2); + + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btGeneric6DofConstraintData +{ + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTransformFloatData m_rbBFrame; + + btVector3FloatData m_linearUpperLimit; + btVector3FloatData m_linearLowerLimit; + + btVector3FloatData m_angularUpperLimit; + btVector3FloatData m_angularLowerLimit; + + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; +}; + +SIMD_FORCE_INLINE int btGeneric6DofConstraint::calculateSerializeBufferSize() const +{ + return sizeof(btGeneric6DofConstraintData); +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btGeneric6DofConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +{ + + btGeneric6DofConstraintData* dof = (btGeneric6DofConstraintData*)dataBuffer; + btTypedConstraint::serialize(&dof->m_typeConstraintData,serializer); + + m_frameInA.serializeFloat(dof->m_rbAFrame); + m_frameInB.serializeFloat(dof->m_rbBFrame); + + + int i; + for (i=0;i<3;i++) + { + dof->m_angularLowerLimit.m_floats[i] = float(m_angularLimits[i].m_loLimit); + dof->m_angularUpperLimit.m_floats[i] = float(m_angularLimits[i].m_hiLimit); + dof->m_linearLowerLimit.m_floats[i] = float(m_linearLimits.m_lowerLimit[i]); + dof->m_linearUpperLimit.m_floats[i] = float(m_linearLimits.m_upperLimit[i]); + } + + dof->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA? 1 : 0; + dof->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame ? 1 : 0; + + return "btGeneric6DofConstraintData"; +} + + + + + +#endif //BT_GENERIC_6DOF_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp new file mode 100644 index 0000000..6f76588 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp @@ -0,0 +1,185 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btGeneric6DofSpringConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" + + +btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) + : btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA) +{ + init(); +} + + +btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) + : btGeneric6DofConstraint(rbB, frameInB, useLinearReferenceFrameB) +{ + init(); +} + + +void btGeneric6DofSpringConstraint::init() +{ + m_objectType = D6_SPRING_CONSTRAINT_TYPE; + + for(int i = 0; i < 6; i++) + { + m_springEnabled[i] = false; + m_equilibriumPoint[i] = btScalar(0.f); + m_springStiffness[i] = btScalar(0.f); + m_springDamping[i] = btScalar(1.f); + } +} + + +void btGeneric6DofSpringConstraint::enableSpring(int index, bool onOff) +{ + btAssert((index >= 0) && (index < 6)); + m_springEnabled[index] = onOff; + if(index < 3) + { + m_linearLimits.m_enableMotor[index] = onOff; + } + else + { + m_angularLimits[index - 3].m_enableMotor = onOff; + } +} + + + +void btGeneric6DofSpringConstraint::setStiffness(int index, btScalar stiffness) +{ + btAssert((index >= 0) && (index < 6)); + m_springStiffness[index] = stiffness; +} + + +void btGeneric6DofSpringConstraint::setDamping(int index, btScalar damping) +{ + btAssert((index >= 0) && (index < 6)); + m_springDamping[index] = damping; +} + + +void btGeneric6DofSpringConstraint::setEquilibriumPoint() +{ + calculateTransforms(); + int i; + + for( i = 0; i < 3; i++) + { + m_equilibriumPoint[i] = m_calculatedLinearDiff[i]; + } + for(i = 0; i < 3; i++) + { + m_equilibriumPoint[i + 3] = m_calculatedAxisAngleDiff[i]; + } +} + + + +void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index) +{ + btAssert((index >= 0) && (index < 6)); + calculateTransforms(); + if(index < 3) + { + m_equilibriumPoint[index] = m_calculatedLinearDiff[index]; + } + else + { + m_equilibriumPoint[index] = m_calculatedAxisAngleDiff[index - 3]; + } +} + +void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index, btScalar val) +{ + btAssert((index >= 0) && (index < 6)); + m_equilibriumPoint[index] = val; +} + + +void btGeneric6DofSpringConstraint::internalUpdateSprings(btConstraintInfo2* info) +{ + // it is assumed that calculateTransforms() have been called before this call + int i; + //btVector3 relVel = m_rbB.getLinearVelocity() - m_rbA.getLinearVelocity(); + for(i = 0; i < 3; i++) + { + if(m_springEnabled[i]) + { + // get current position of constraint + btScalar currPos = m_calculatedLinearDiff[i]; + // calculate difference + btScalar delta = currPos - m_equilibriumPoint[i]; + // spring force is (delta * m_stiffness) according to Hooke's Law + btScalar force = delta * m_springStiffness[i]; + btScalar velFactor = info->fps * m_springDamping[i] / btScalar(info->m_numIterations); + m_linearLimits.m_targetVelocity[i] = velFactor * force; + m_linearLimits.m_maxMotorForce[i] = btFabs(force) / info->fps; + } + } + for(i = 0; i < 3; i++) + { + if(m_springEnabled[i + 3]) + { + // get current position of constraint + btScalar currPos = m_calculatedAxisAngleDiff[i]; + // calculate difference + btScalar delta = currPos - m_equilibriumPoint[i+3]; + // spring force is (-delta * m_stiffness) according to Hooke's Law + btScalar force = -delta * m_springStiffness[i+3]; + btScalar velFactor = info->fps * m_springDamping[i+3] / btScalar(info->m_numIterations); + m_angularLimits[i].m_targetVelocity = velFactor * force; + m_angularLimits[i].m_maxMotorForce = btFabs(force) / info->fps; + } + } +} + + +void btGeneric6DofSpringConstraint::getInfo2(btConstraintInfo2* info) +{ + // this will be called by constraint solver at the constraint setup stage + // set current motor parameters + internalUpdateSprings(info); + // do the rest of job for constraint setup + btGeneric6DofConstraint::getInfo2(info); +} + + +void btGeneric6DofSpringConstraint::setAxis(const btVector3& axis1,const btVector3& axis2) +{ + btVector3 zAxis = axis1.normalized(); + btVector3 yAxis = axis2.normalized(); + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + + btTransform frameInW; + frameInW.setIdentity(); + frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + + // now get constraint frame in local coordinate systems + m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW; + m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW; + + calculateTransforms(); +} + + + diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h new file mode 100644 index 0000000..6fabb30 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h @@ -0,0 +1,102 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_GENERIC_6DOF_SPRING_CONSTRAINT_H +#define BT_GENERIC_6DOF_SPRING_CONSTRAINT_H + + +#include "LinearMath/btVector3.h" +#include "btTypedConstraint.h" +#include "btGeneric6DofConstraint.h" + + +/// Generic 6 DOF constraint that allows to set spring motors to any translational and rotational DOF + +/// DOF index used in enableSpring() and setStiffness() means: +/// 0 : translation X +/// 1 : translation Y +/// 2 : translation Z +/// 3 : rotation X (3rd Euler rotational around new position of X axis, range [-PI+epsilon, PI-epsilon] ) +/// 4 : rotation Y (2nd Euler rotational around new position of Y axis, range [-PI/2+epsilon, PI/2-epsilon] ) +/// 5 : rotation Z (1st Euler rotational around Z axis, range [-PI+epsilon, PI-epsilon] ) + +ATTRIBUTE_ALIGNED16(class) btGeneric6DofSpringConstraint : public btGeneric6DofConstraint +{ +protected: + bool m_springEnabled[6]; + btScalar m_equilibriumPoint[6]; + btScalar m_springStiffness[6]; + btScalar m_springDamping[6]; // between 0 and 1 (1 == no damping) + void init(); + void internalUpdateSprings(btConstraintInfo2* info); +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + btGeneric6DofSpringConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); + void enableSpring(int index, bool onOff); + void setStiffness(int index, btScalar stiffness); + void setDamping(int index, btScalar damping); + void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF + void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF + void setEquilibriumPoint(int index, btScalar val); + + virtual void setAxis( const btVector3& axis1, const btVector3& axis2); + + virtual void getInfo2 (btConstraintInfo2* info); + + virtual int calculateSerializeBufferSize() const; + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + +}; + + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btGeneric6DofSpringConstraintData +{ + btGeneric6DofConstraintData m_6dofData; + + int m_springEnabled[6]; + float m_equilibriumPoint[6]; + float m_springStiffness[6]; + float m_springDamping[6]; +}; + +SIMD_FORCE_INLINE int btGeneric6DofSpringConstraint::calculateSerializeBufferSize() const +{ + return sizeof(btGeneric6DofSpringConstraintData); +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btGeneric6DofSpringConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btGeneric6DofSpringConstraintData* dof = (btGeneric6DofSpringConstraintData*)dataBuffer; + btGeneric6DofConstraint::serialize(&dof->m_6dofData,serializer); + + int i; + for (i=0;i<6;i++) + { + dof->m_equilibriumPoint[i] = (float)m_equilibriumPoint[i]; + dof->m_springDamping[i] = (float)m_springDamping[i]; + dof->m_springEnabled[i] = m_springEnabled[i]? 1 : 0; + dof->m_springStiffness[i] = (float)m_springStiffness[i]; + } + return "btGeneric6DofSpringConstraintData"; +} + +#endif // BT_GENERIC_6DOF_SPRING_CONSTRAINT_H + diff --git a/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp new file mode 100644 index 0000000..29123d5 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp @@ -0,0 +1,66 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btHinge2Constraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" + + + +// constructor +// anchor, axis1 and axis2 are in world coordinate system +// axis1 must be orthogonal to axis2 +btHinge2Constraint::btHinge2Constraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2) +: btGeneric6DofSpringConstraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(), true), + m_anchor(anchor), + m_axis1(axis1), + m_axis2(axis2) +{ + // build frame basis + // 6DOF constraint uses Euler angles and to define limits + // it is assumed that rotational order is : + // Z - first, allowed limits are (-PI,PI); + // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number + // used to prevent constraint from instability on poles; + // new position of X, allowed limits are (-PI,PI); + // So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs + // Build the frame in world coordinate system first + btVector3 zAxis = axis1.normalize(); + btVector3 xAxis = axis2.normalize(); + btVector3 yAxis = zAxis.cross(xAxis); // we want right coordinate system + btTransform frameInW; + frameInW.setIdentity(); + frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + frameInW.setOrigin(anchor); + // now get constraint frame in local coordinate systems + m_frameInA = rbA.getCenterOfMassTransform().inverse() * frameInW; + m_frameInB = rbB.getCenterOfMassTransform().inverse() * frameInW; + // sei limits + setLinearLowerLimit(btVector3(0.f, 0.f, -1.f)); + setLinearUpperLimit(btVector3(0.f, 0.f, 1.f)); + // like front wheels of a car + setAngularLowerLimit(btVector3(1.f, 0.f, -SIMD_HALF_PI * 0.5f)); + setAngularUpperLimit(btVector3(-1.f, 0.f, SIMD_HALF_PI * 0.5f)); + // enable suspension + enableSpring(2, true); + setStiffness(2, SIMD_PI * SIMD_PI * 4.f); // period 1 sec for 1 kilogramm weel :-) + setDamping(2, 0.01f); + setEquilibriumPoint(); +} + diff --git a/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h new file mode 100644 index 0000000..9a00498 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h @@ -0,0 +1,60 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_HINGE2_CONSTRAINT_H +#define BT_HINGE2_CONSTRAINT_H + + + +#include "LinearMath/btVector3.h" +#include "btTypedConstraint.h" +#include "btGeneric6DofSpringConstraint.h" + + + +// Constraint similar to ODE Hinge2 Joint +// has 3 degrees of frredom: +// 2 rotational degrees of freedom, similar to Euler rotations around Z (axis 1) and X (axis 2) +// 1 translational (along axis Z) with suspension spring + +ATTRIBUTE_ALIGNED16(class) btHinge2Constraint : public btGeneric6DofSpringConstraint +{ +protected: + btVector3 m_anchor; + btVector3 m_axis1; + btVector3 m_axis2; +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + // constructor + // anchor, axis1 and axis2 are in world coordinate system + // axis1 must be orthogonal to axis2 + btHinge2Constraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2); + // access + const btVector3& getAnchor() { return m_calculatedTransformA.getOrigin(); } + const btVector3& getAnchor2() { return m_calculatedTransformB.getOrigin(); } + const btVector3& getAxis1() { return m_axis1; } + const btVector3& getAxis2() { return m_axis2; } + btScalar getAngle1() { return getAngle(2); } + btScalar getAngle2() { return getAngle(0); } + // limits + void setUpperLimit(btScalar ang1max) { setAngularUpperLimit(btVector3(-1.f, 0.f, ang1max)); } + void setLowerLimit(btScalar ang1min) { setAngularLowerLimit(btVector3( 1.f, 0.f, ang1min)); } +}; + + + +#endif // BT_HINGE2_CONSTRAINT_H + diff --git a/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp new file mode 100644 index 0000000..20b35fb --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp @@ -0,0 +1,1034 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btHingeConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btMinMax.h" +#include +#include "btSolverBody.h" + + + +//#define HINGE_USE_OBSOLETE_SOLVER false +#define HINGE_USE_OBSOLETE_SOLVER false + +#define HINGE_USE_FRAME_OFFSET true + +#ifndef __SPU__ + + + + + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, + const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA) + :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB), +#ifdef _BT_USE_CENTER_LIMIT_ + m_limit(), +#endif + m_angularOnly(false), + m_enableAngularMotor(false), + m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), + m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), + m_useReferenceFrameA(useReferenceFrameA), + m_flags(0) +{ + m_rbAFrame.getOrigin() = pivotInA; + + // since no frame is given, assume this to be zero angle and just pick rb transform axis + btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0); + + btVector3 rbAxisA2; + btScalar projection = axisInA.dot(rbAxisA1); + if (projection >= 1.0f - SIMD_EPSILON) { + rbAxisA1 = -rbA.getCenterOfMassTransform().getBasis().getColumn(2); + rbAxisA2 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); + } else if (projection <= -1.0f + SIMD_EPSILON) { + rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(2); + rbAxisA2 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); + } else { + rbAxisA2 = axisInA.cross(rbAxisA1); + rbAxisA1 = rbAxisA2.cross(axisInA); + } + + m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), + rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), + rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + + btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); + btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); + + m_rbBFrame.getOrigin() = pivotInB; + m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), + rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), + rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); + +#ifndef _BT_USE_CENTER_LIMIT_ + //start with free + m_lowerLimit = btScalar(1.0f); + m_upperLimit = btScalar(-1.0f); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; +#endif + m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); +} + + + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA) +:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), +#ifdef _BT_USE_CENTER_LIMIT_ +m_limit(), +#endif +m_angularOnly(false), m_enableAngularMotor(false), +m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), +m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), +m_useReferenceFrameA(useReferenceFrameA), +m_flags(0) +{ + + // since no frame is given, assume this to be zero angle and just pick rb transform axis + // fixed axis in worldspace + btVector3 rbAxisA1, rbAxisA2; + btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2); + + m_rbAFrame.getOrigin() = pivotInA; + m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), + rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), + rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + + btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * axisInA; + + btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); + btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); + + + m_rbBFrame.getOrigin() = rbA.getCenterOfMassTransform()(pivotInA); + m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), + rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), + rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); + +#ifndef _BT_USE_CENTER_LIMIT_ + //start with free + m_lowerLimit = btScalar(1.0f); + m_upperLimit = btScalar(-1.0f); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; +#endif + m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); +} + + + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, + const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA) +:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), +#ifdef _BT_USE_CENTER_LIMIT_ +m_limit(), +#endif +m_angularOnly(false), +m_enableAngularMotor(false), +m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), +m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), +m_useReferenceFrameA(useReferenceFrameA), +m_flags(0) +{ +#ifndef _BT_USE_CENTER_LIMIT_ + //start with free + m_lowerLimit = btScalar(1.0f); + m_upperLimit = btScalar(-1.0f); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; +#endif + m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); +} + + + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA) +:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA),m_rbAFrame(rbAFrame),m_rbBFrame(rbAFrame), +#ifdef _BT_USE_CENTER_LIMIT_ +m_limit(), +#endif +m_angularOnly(false), +m_enableAngularMotor(false), +m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), +m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), +m_useReferenceFrameA(useReferenceFrameA), +m_flags(0) +{ + ///not providing rigidbody B means implicitly using worldspace for body B + + m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(m_rbAFrame.getOrigin()); +#ifndef _BT_USE_CENTER_LIMIT_ + //start with free + m_lowerLimit = btScalar(1.0f); + m_upperLimit = btScalar(-1.0f); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; +#endif + m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); +} + + + +void btHingeConstraint::buildJacobian() +{ + if (m_useSolveConstraintObsolete) + { + m_appliedImpulse = btScalar(0.); + m_accMotorImpulse = btScalar(0.); + + if (!m_angularOnly) + { + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + btVector3 relPos = pivotBInW - pivotAInW; + + btVector3 normal[3]; + if (relPos.length2() > SIMD_EPSILON) + { + normal[0] = relPos.normalized(); + } + else + { + normal[0].setValue(btScalar(1.0),0,0); + } + + btPlaneSpace1(normal[0], normal[1], normal[2]); + + for (int i=0;i<3;i++) + { + new (&m_jac[i]) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normal[i], + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + } + } + + //calculate two perpendicular jointAxis, orthogonal to hingeAxis + //these two jointAxis require equal angular velocities for both bodies + + //this is unused for now, it's a todo + btVector3 jointAxis0local; + btVector3 jointAxis1local; + + btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local); + + btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; + btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; + btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); + + new (&m_jacAng[0]) btJacobianEntry(jointAxis0, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + + new (&m_jacAng[1]) btJacobianEntry(jointAxis1, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + + new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + + // clear accumulator + m_accLimitImpulse = btScalar(0.); + + // test angular limit + testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + + //Compute K = J*W*J' for hinge axis + btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); + m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + + getRigidBodyB().computeAngularImpulseDenominator(axisA)); + + } +} + + +#endif //__SPU__ + + +void btHingeConstraint::getInfo1(btConstraintInfo1* info) +{ + if (m_useSolveConstraintObsolete) + { + info->m_numConstraintRows = 0; + info->nub = 0; + } + else + { + info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular + info->nub = 1; + //always add the row, to avoid computation (data is not available yet) + //prepare constraint + testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + if(getSolveLimit() || getEnableAngularMotor()) + { + info->m_numConstraintRows++; // limit 3rd anguar as well + info->nub--; + } + + } +} + +void btHingeConstraint::getInfo1NonVirtual(btConstraintInfo1* info) +{ + if (m_useSolveConstraintObsolete) + { + info->m_numConstraintRows = 0; + info->nub = 0; + } + else + { + //always add the 'limit' row, to avoid computation (data is not available yet) + info->m_numConstraintRows = 6; // Fixed 3 linear + 2 angular + info->nub = 0; + } +} + +void btHingeConstraint::getInfo2 (btConstraintInfo2* info) +{ + if(m_useOffsetForConstraintFrame) + { + getInfo2InternalUsingFrameOffset(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getAngularVelocity(),m_rbB.getAngularVelocity()); + } + else + { + getInfo2Internal(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getAngularVelocity(),m_rbB.getAngularVelocity()); + } +} + + +void btHingeConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB) +{ + ///the regular (virtual) implementation getInfo2 already performs 'testLimit' during getInfo1, so we need to do it now + testLimit(transA,transB); + + getInfo2Internal(info,transA,transB,angVelA,angVelB); +} + + +void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB) +{ + + btAssert(!m_useSolveConstraintObsolete); + int i, skip = info->rowskip; + // transforms in world space + btTransform trA = transA*m_rbAFrame; + btTransform trB = transB*m_rbBFrame; + // pivot point + btVector3 pivotAInW = trA.getOrigin(); + btVector3 pivotBInW = trB.getOrigin(); +#if 0 + if (0) + { + for (i=0;i<6;i++) + { + info->m_J1linearAxis[i*skip]=0; + info->m_J1linearAxis[i*skip+1]=0; + info->m_J1linearAxis[i*skip+2]=0; + + info->m_J1angularAxis[i*skip]=0; + info->m_J1angularAxis[i*skip+1]=0; + info->m_J1angularAxis[i*skip+2]=0; + + info->m_J2angularAxis[i*skip]=0; + info->m_J2angularAxis[i*skip+1]=0; + info->m_J2angularAxis[i*skip+2]=0; + + info->m_constraintError[i*skip]=0.f; + } + } +#endif //#if 0 + // linear (all fixed) + + if (!m_angularOnly) + { + info->m_J1linearAxis[0] = 1; + info->m_J1linearAxis[skip + 1] = 1; + info->m_J1linearAxis[2 * skip + 2] = 1; + } + + + + + btVector3 a1 = pivotAInW - transA.getOrigin(); + { + btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); + btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + skip); + btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * skip); + btVector3 a1neg = -a1; + a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + } + btVector3 a2 = pivotBInW - transB.getOrigin(); + { + btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); + btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + skip); + btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * skip); + a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + } + // linear RHS + btScalar k = info->fps * info->erp; + if (!m_angularOnly) + { + for(i = 0; i < 3; i++) + { + info->m_constraintError[i * skip] = k * (pivotBInW[i] - pivotAInW[i]); + } + } + // make rotations around X and Y equal + // the hinge axis should be the only unconstrained + // rotational axis, the angular velocity of the two bodies perpendicular to + // the hinge axis should be equal. thus the constraint equations are + // p*w1 - p*w2 = 0 + // q*w1 - q*w2 = 0 + // where p and q are unit vectors normal to the hinge axis, and w1 and w2 + // are the angular velocity vectors of the two bodies. + // get hinge axis (Z) + btVector3 ax1 = trA.getBasis().getColumn(2); + // get 2 orthos to hinge axis (X, Y) + btVector3 p = trA.getBasis().getColumn(0); + btVector3 q = trA.getBasis().getColumn(1); + // set the two hinge angular rows + int s3 = 3 * info->rowskip; + int s4 = 4 * info->rowskip; + + info->m_J1angularAxis[s3 + 0] = p[0]; + info->m_J1angularAxis[s3 + 1] = p[1]; + info->m_J1angularAxis[s3 + 2] = p[2]; + info->m_J1angularAxis[s4 + 0] = q[0]; + info->m_J1angularAxis[s4 + 1] = q[1]; + info->m_J1angularAxis[s4 + 2] = q[2]; + + info->m_J2angularAxis[s3 + 0] = -p[0]; + info->m_J2angularAxis[s3 + 1] = -p[1]; + info->m_J2angularAxis[s3 + 2] = -p[2]; + info->m_J2angularAxis[s4 + 0] = -q[0]; + info->m_J2angularAxis[s4 + 1] = -q[1]; + info->m_J2angularAxis[s4 + 2] = -q[2]; + // compute the right hand side of the constraint equation. set relative + // body velocities along p and q to bring the hinge back into alignment. + // if ax1,ax2 are the unit length hinge axes as computed from body1 and + // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). + // if `theta' is the angle between ax1 and ax2, we need an angular velocity + // along u to cover angle erp*theta in one step : + // |angular_velocity| = angle/time = erp*theta / stepsize + // = (erp*fps) * theta + // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| + // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) + // ...as ax1 and ax2 are unit length. if theta is smallish, + // theta ~= sin(theta), so + // angular_velocity = (erp*fps) * (ax1 x ax2) + // ax1 x ax2 is in the plane space of ax1, so we project the angular + // velocity to p and q to find the right hand side. + btVector3 ax2 = trB.getBasis().getColumn(2); + btVector3 u = ax1.cross(ax2); + info->m_constraintError[s3] = k * u.dot(p); + info->m_constraintError[s4] = k * u.dot(q); + // check angular limits + int nrow = 4; // last filled row + int srow; + btScalar limit_err = btScalar(0.0); + int limit = 0; + if(getSolveLimit()) + { +#ifdef _BT_USE_CENTER_LIMIT_ + limit_err = m_limit.getCorrection() * m_referenceSign; +#else + limit_err = m_correction * m_referenceSign; +#endif + limit = (limit_err > btScalar(0.0)) ? 1 : 2; + + } + // if the hinge has joint limits or motor, add in the extra row + int powered = 0; + if(getEnableAngularMotor()) + { + powered = 1; + } + if(limit || powered) + { + nrow++; + srow = nrow * info->rowskip; + info->m_J1angularAxis[srow+0] = ax1[0]; + info->m_J1angularAxis[srow+1] = ax1[1]; + info->m_J1angularAxis[srow+2] = ax1[2]; + + info->m_J2angularAxis[srow+0] = -ax1[0]; + info->m_J2angularAxis[srow+1] = -ax1[1]; + info->m_J2angularAxis[srow+2] = -ax1[2]; + + btScalar lostop = getLowerLimit(); + btScalar histop = getUpperLimit(); + if(limit && (lostop == histop)) + { // the joint motor is ineffective + powered = 0; + } + info->m_constraintError[srow] = btScalar(0.0f); + btScalar currERP = (m_flags & BT_HINGE_FLAGS_ERP_STOP) ? m_stopERP : info->erp; + if(powered) + { + if(m_flags & BT_HINGE_FLAGS_CFM_NORM) + { + info->cfm[srow] = m_normalCFM; + } + btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * currERP); + info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign; + info->m_lowerLimit[srow] = - m_maxMotorImpulse; + info->m_upperLimit[srow] = m_maxMotorImpulse; + } + if(limit) + { + k = info->fps * currERP; + info->m_constraintError[srow] += k * limit_err; + if(m_flags & BT_HINGE_FLAGS_CFM_STOP) + { + info->cfm[srow] = m_stopCFM; + } + if(lostop == histop) + { + // limited low and high simultaneously + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else if(limit == 1) + { // low limit + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { // high limit + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = 0; + } + // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) +#ifdef _BT_USE_CENTER_LIMIT_ + btScalar bounce = m_limit.getRelaxationFactor(); +#else + btScalar bounce = m_relaxationFactor; +#endif + if(bounce > btScalar(0.0)) + { + btScalar vel = angVelA.dot(ax1); + vel -= angVelB.dot(ax1); + // only apply bounce if the velocity is incoming, and if the + // resulting c[] exceeds what we already have. + if(limit == 1) + { // low limit + if(vel < 0) + { + btScalar newc = -bounce * vel; + if(newc > info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + else + { // high limit - all those computations are reversed + if(vel > 0) + { + btScalar newc = -bounce * vel; + if(newc < info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + } +#ifdef _BT_USE_CENTER_LIMIT_ + info->m_constraintError[srow] *= m_limit.getBiasFactor(); +#else + info->m_constraintError[srow] *= m_biasFactor; +#endif + } // if(limit) + } // if angular limit or powered +} + + +void btHingeConstraint::setFrames(const btTransform & frameA, const btTransform & frameB) +{ + m_rbAFrame = frameA; + m_rbBFrame = frameB; + buildJacobian(); +} + + +void btHingeConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} + + +btScalar btHingeConstraint::getHingeAngle() +{ + return getHingeAngle(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); +} + +btScalar btHingeConstraint::getHingeAngle(const btTransform& transA,const btTransform& transB) +{ + const btVector3 refAxis0 = transA.getBasis() * m_rbAFrame.getBasis().getColumn(0); + const btVector3 refAxis1 = transA.getBasis() * m_rbAFrame.getBasis().getColumn(1); + const btVector3 swingAxis = transB.getBasis() * m_rbBFrame.getBasis().getColumn(1); +// btScalar angle = btAtan2Fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); + btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); + return m_referenceSign * angle; +} + + + +void btHingeConstraint::testLimit(const btTransform& transA,const btTransform& transB) +{ + // Compute limit information + m_hingeAngle = getHingeAngle(transA,transB); +#ifdef _BT_USE_CENTER_LIMIT_ + m_limit.test(m_hingeAngle); +#else + m_correction = btScalar(0.); + m_limitSign = btScalar(0.); + m_solveLimit = false; + if (m_lowerLimit <= m_upperLimit) + { + m_hingeAngle = btAdjustAngleToLimits(m_hingeAngle, m_lowerLimit, m_upperLimit); + if (m_hingeAngle <= m_lowerLimit) + { + m_correction = (m_lowerLimit - m_hingeAngle); + m_limitSign = 1.0f; + m_solveLimit = true; + } + else if (m_hingeAngle >= m_upperLimit) + { + m_correction = m_upperLimit - m_hingeAngle; + m_limitSign = -1.0f; + m_solveLimit = true; + } + } +#endif + return; +} + + +static btVector3 vHinge(0, 0, btScalar(1)); + +void btHingeConstraint::setMotorTarget(const btQuaternion& qAinB, btScalar dt) +{ + // convert target from body to constraint space + btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * qAinB * m_rbAFrame.getRotation(); + qConstraint.normalize(); + + // extract "pure" hinge component + btVector3 vNoHinge = quatRotate(qConstraint, vHinge); vNoHinge.normalize(); + btQuaternion qNoHinge = shortestArcQuat(vHinge, vNoHinge); + btQuaternion qHinge = qNoHinge.inverse() * qConstraint; + qHinge.normalize(); + + // compute angular target, clamped to limits + btScalar targetAngle = qHinge.getAngle(); + if (targetAngle > SIMD_PI) // long way around. flip quat and recalculate. + { + qHinge = -(qHinge); + targetAngle = qHinge.getAngle(); + } + if (qHinge.getZ() < 0) + targetAngle = -targetAngle; + + setMotorTarget(targetAngle, dt); +} + +void btHingeConstraint::setMotorTarget(btScalar targetAngle, btScalar dt) +{ +#ifdef _BT_USE_CENTER_LIMIT_ + m_limit.fit(targetAngle); +#else + if (m_lowerLimit < m_upperLimit) + { + if (targetAngle < m_lowerLimit) + targetAngle = m_lowerLimit; + else if (targetAngle > m_upperLimit) + targetAngle = m_upperLimit; + } +#endif + // compute angular velocity + btScalar curAngle = getHingeAngle(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + btScalar dAngle = targetAngle - curAngle; + m_motorTargetVelocity = dAngle / dt; +} + + + +void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB) +{ + btAssert(!m_useSolveConstraintObsolete); + int i, s = info->rowskip; + // transforms in world space + btTransform trA = transA*m_rbAFrame; + btTransform trB = transB*m_rbBFrame; + // pivot point +// btVector3 pivotAInW = trA.getOrigin(); +// btVector3 pivotBInW = trB.getOrigin(); +#if 1 + // difference between frames in WCS + btVector3 ofs = trB.getOrigin() - trA.getOrigin(); + // now get weight factors depending on masses + btScalar miA = getRigidBodyA().getInvMass(); + btScalar miB = getRigidBodyB().getInvMass(); + bool hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON); + btScalar miS = miA + miB; + btScalar factA, factB; + if(miS > btScalar(0.f)) + { + factA = miB / miS; + } + else + { + factA = btScalar(0.5f); + } + factB = btScalar(1.0f) - factA; + // get the desired direction of hinge axis + // as weighted sum of Z-orthos of frameA and frameB in WCS + btVector3 ax1A = trA.getBasis().getColumn(2); + btVector3 ax1B = trB.getBasis().getColumn(2); + btVector3 ax1 = ax1A * factA + ax1B * factB; + ax1.normalize(); + // fill first 3 rows + // we want: velA + wA x relA == velB + wB x relB + btTransform bodyA_trans = transA; + btTransform bodyB_trans = transB; + int s0 = 0; + int s1 = s; + int s2 = s * 2; + int nrow = 2; // last filled row + btVector3 tmpA, tmpB, relA, relB, p, q; + // get vector from bodyB to frameB in WCS + relB = trB.getOrigin() - bodyB_trans.getOrigin(); + // get its projection to hinge axis + btVector3 projB = ax1 * relB.dot(ax1); + // get vector directed from bodyB to hinge axis (and orthogonal to it) + btVector3 orthoB = relB - projB; + // same for bodyA + relA = trA.getOrigin() - bodyA_trans.getOrigin(); + btVector3 projA = ax1 * relA.dot(ax1); + btVector3 orthoA = relA - projA; + btVector3 totalDist = projA - projB; + // get offset vectors relA and relB + relA = orthoA + totalDist * factA; + relB = orthoB - totalDist * factB; + // now choose average ortho to hinge axis + p = orthoB * factA + orthoA * factB; + btScalar len2 = p.length2(); + if(len2 > SIMD_EPSILON) + { + p /= btSqrt(len2); + } + else + { + p = trA.getBasis().getColumn(1); + } + // make one more ortho + q = ax1.cross(p); + // fill three rows + tmpA = relA.cross(p); + tmpB = relB.cross(p); + for (i=0; i<3; i++) info->m_J1angularAxis[s0+i] = tmpA[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[s0+i] = -tmpB[i]; + tmpA = relA.cross(q); + tmpB = relB.cross(q); + if(hasStaticBody && getSolveLimit()) + { // to make constraint between static and dynamic objects more rigid + // remove wA (or wB) from equation if angular limit is hit + tmpB *= factB; + tmpA *= factA; + } + for (i=0; i<3; i++) info->m_J1angularAxis[s1+i] = tmpA[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[s1+i] = -tmpB[i]; + tmpA = relA.cross(ax1); + tmpB = relB.cross(ax1); + if(hasStaticBody) + { // to make constraint between static and dynamic objects more rigid + // remove wA (or wB) from equation + tmpB *= factB; + tmpA *= factA; + } + for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = tmpA[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = -tmpB[i]; + + btScalar k = info->fps * info->erp; + + if (!m_angularOnly) + { + for (i=0; i<3; i++) info->m_J1linearAxis[s0+i] = p[i]; + for (i=0; i<3; i++) info->m_J1linearAxis[s1+i] = q[i]; + for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = ax1[i]; + + // compute three elements of right hand side + + btScalar rhs = k * p.dot(ofs); + info->m_constraintError[s0] = rhs; + rhs = k * q.dot(ofs); + info->m_constraintError[s1] = rhs; + rhs = k * ax1.dot(ofs); + info->m_constraintError[s2] = rhs; + } + // the hinge axis should be the only unconstrained + // rotational axis, the angular velocity of the two bodies perpendicular to + // the hinge axis should be equal. thus the constraint equations are + // p*w1 - p*w2 = 0 + // q*w1 - q*w2 = 0 + // where p and q are unit vectors normal to the hinge axis, and w1 and w2 + // are the angular velocity vectors of the two bodies. + int s3 = 3 * s; + int s4 = 4 * s; + info->m_J1angularAxis[s3 + 0] = p[0]; + info->m_J1angularAxis[s3 + 1] = p[1]; + info->m_J1angularAxis[s3 + 2] = p[2]; + info->m_J1angularAxis[s4 + 0] = q[0]; + info->m_J1angularAxis[s4 + 1] = q[1]; + info->m_J1angularAxis[s4 + 2] = q[2]; + + info->m_J2angularAxis[s3 + 0] = -p[0]; + info->m_J2angularAxis[s3 + 1] = -p[1]; + info->m_J2angularAxis[s3 + 2] = -p[2]; + info->m_J2angularAxis[s4 + 0] = -q[0]; + info->m_J2angularAxis[s4 + 1] = -q[1]; + info->m_J2angularAxis[s4 + 2] = -q[2]; + // compute the right hand side of the constraint equation. set relative + // body velocities along p and q to bring the hinge back into alignment. + // if ax1A,ax1B are the unit length hinge axes as computed from bodyA and + // bodyB, we need to rotate both bodies along the axis u = (ax1 x ax2). + // if "theta" is the angle between ax1 and ax2, we need an angular velocity + // along u to cover angle erp*theta in one step : + // |angular_velocity| = angle/time = erp*theta / stepsize + // = (erp*fps) * theta + // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| + // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) + // ...as ax1 and ax2 are unit length. if theta is smallish, + // theta ~= sin(theta), so + // angular_velocity = (erp*fps) * (ax1 x ax2) + // ax1 x ax2 is in the plane space of ax1, so we project the angular + // velocity to p and q to find the right hand side. + k = info->fps * info->erp; + btVector3 u = ax1A.cross(ax1B); + info->m_constraintError[s3] = k * u.dot(p); + info->m_constraintError[s4] = k * u.dot(q); +#endif + // check angular limits + nrow = 4; // last filled row + int srow; + btScalar limit_err = btScalar(0.0); + int limit = 0; + if(getSolveLimit()) + { +#ifdef _BT_USE_CENTER_LIMIT_ + limit_err = m_limit.getCorrection() * m_referenceSign; +#else + limit_err = m_correction * m_referenceSign; +#endif + limit = (limit_err > btScalar(0.0)) ? 1 : 2; + + } + // if the hinge has joint limits or motor, add in the extra row + int powered = 0; + if(getEnableAngularMotor()) + { + powered = 1; + } + if(limit || powered) + { + nrow++; + srow = nrow * info->rowskip; + info->m_J1angularAxis[srow+0] = ax1[0]; + info->m_J1angularAxis[srow+1] = ax1[1]; + info->m_J1angularAxis[srow+2] = ax1[2]; + + info->m_J2angularAxis[srow+0] = -ax1[0]; + info->m_J2angularAxis[srow+1] = -ax1[1]; + info->m_J2angularAxis[srow+2] = -ax1[2]; + + btScalar lostop = getLowerLimit(); + btScalar histop = getUpperLimit(); + if(limit && (lostop == histop)) + { // the joint motor is ineffective + powered = 0; + } + info->m_constraintError[srow] = btScalar(0.0f); + btScalar currERP = (m_flags & BT_HINGE_FLAGS_ERP_STOP) ? m_stopERP : info->erp; + if(powered) + { + if(m_flags & BT_HINGE_FLAGS_CFM_NORM) + { + info->cfm[srow] = m_normalCFM; + } + btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * currERP); + info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign; + info->m_lowerLimit[srow] = - m_maxMotorImpulse; + info->m_upperLimit[srow] = m_maxMotorImpulse; + } + if(limit) + { + k = info->fps * currERP; + info->m_constraintError[srow] += k * limit_err; + if(m_flags & BT_HINGE_FLAGS_CFM_STOP) + { + info->cfm[srow] = m_stopCFM; + } + if(lostop == histop) + { + // limited low and high simultaneously + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else if(limit == 1) + { // low limit + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { // high limit + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = 0; + } + // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) +#ifdef _BT_USE_CENTER_LIMIT_ + btScalar bounce = m_limit.getRelaxationFactor(); +#else + btScalar bounce = m_relaxationFactor; +#endif + if(bounce > btScalar(0.0)) + { + btScalar vel = angVelA.dot(ax1); + vel -= angVelB.dot(ax1); + // only apply bounce if the velocity is incoming, and if the + // resulting c[] exceeds what we already have. + if(limit == 1) + { // low limit + if(vel < 0) + { + btScalar newc = -bounce * vel; + if(newc > info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + else + { // high limit - all those computations are reversed + if(vel > 0) + { + btScalar newc = -bounce * vel; + if(newc < info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + } +#ifdef _BT_USE_CENTER_LIMIT_ + info->m_constraintError[srow] *= m_limit.getBiasFactor(); +#else + info->m_constraintError[srow] *= m_biasFactor; +#endif + } // if(limit) + } // if angular limit or powered +} + + +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///If no axis is provided, it uses the default axis for this constraint. +void btHingeConstraint::setParam(int num, btScalar value, int axis) +{ + if((axis == -1) || (axis == 5)) + { + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + m_stopERP = value; + m_flags |= BT_HINGE_FLAGS_ERP_STOP; + break; + case BT_CONSTRAINT_STOP_CFM : + m_stopCFM = value; + m_flags |= BT_HINGE_FLAGS_CFM_STOP; + break; + case BT_CONSTRAINT_CFM : + m_normalCFM = value; + m_flags |= BT_HINGE_FLAGS_CFM_NORM; + break; + default : + btAssertConstrParams(0); + } + } + else + { + btAssertConstrParams(0); + } +} + +///return the local value of parameter +btScalar btHingeConstraint::getParam(int num, int axis) const +{ + btScalar retVal = 0; + if((axis == -1) || (axis == 5)) + { + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + btAssertConstrParams(m_flags & BT_HINGE_FLAGS_ERP_STOP); + retVal = m_stopERP; + break; + case BT_CONSTRAINT_STOP_CFM : + btAssertConstrParams(m_flags & BT_HINGE_FLAGS_CFM_STOP); + retVal = m_stopCFM; + break; + case BT_CONSTRAINT_CFM : + btAssertConstrParams(m_flags & BT_HINGE_FLAGS_CFM_NORM); + retVal = m_normalCFM; + break; + default : + btAssertConstrParams(0); + } + } + else + { + btAssertConstrParams(0); + } + return retVal; +} + + diff --git a/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h new file mode 100644 index 0000000..a7f2cca --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h @@ -0,0 +1,383 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* Hinge Constraint by Dirk Gregorius. Limits added by Marcus Hennix at Starbreeze Studios */ + +#ifndef BT_HINGECONSTRAINT_H +#define BT_HINGECONSTRAINT_H + +#define _BT_USE_CENTER_LIMIT_ 1 + + +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + +#ifdef BT_USE_DOUBLE_PRECISION +#define btHingeConstraintData btHingeConstraintDoubleData +#define btHingeConstraintDataName "btHingeConstraintDoubleData" +#else +#define btHingeConstraintData btHingeConstraintFloatData +#define btHingeConstraintDataName "btHingeConstraintFloatData" +#endif //BT_USE_DOUBLE_PRECISION + + + +enum btHingeFlags +{ + BT_HINGE_FLAGS_CFM_STOP = 1, + BT_HINGE_FLAGS_ERP_STOP = 2, + BT_HINGE_FLAGS_CFM_NORM = 4 +}; + + +/// hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space +/// axis defines the orientation of the hinge axis +ATTRIBUTE_ALIGNED16(class) btHingeConstraint : public btTypedConstraint +{ +#ifdef IN_PARALLELL_SOLVER +public: +#endif + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor + + btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTransform m_rbBFrame; + + btScalar m_motorTargetVelocity; + btScalar m_maxMotorImpulse; + + +#ifdef _BT_USE_CENTER_LIMIT_ + btAngularLimit m_limit; +#else + btScalar m_lowerLimit; + btScalar m_upperLimit; + btScalar m_limitSign; + btScalar m_correction; + + btScalar m_limitSoftness; + btScalar m_biasFactor; + btScalar m_relaxationFactor; + + bool m_solveLimit; +#endif + + btScalar m_kHinge; + + + btScalar m_accLimitImpulse; + btScalar m_hingeAngle; + btScalar m_referenceSign; + + bool m_angularOnly; + bool m_enableAngularMotor; + bool m_useSolveConstraintObsolete; + bool m_useOffsetForConstraintFrame; + bool m_useReferenceFrameA; + + btScalar m_accMotorImpulse; + + int m_flags; + btScalar m_normalCFM; + btScalar m_stopCFM; + btScalar m_stopERP; + + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false); + + btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false); + + btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false); + + btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false); + + + virtual void buildJacobian(); + + virtual void getInfo1 (btConstraintInfo1* info); + + void getInfo1NonVirtual(btConstraintInfo1* info); + + virtual void getInfo2 (btConstraintInfo2* info); + + void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); + + void getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); + void getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); + + + void updateRHS(btScalar timeStep); + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } + + btRigidBody& getRigidBodyA() + { + return m_rbA; + } + + btRigidBody& getRigidBodyB() + { + return m_rbB; + } + + btTransform& getFrameOffsetA() + { + return m_rbAFrame; + } + + btTransform& getFrameOffsetB() + { + return m_rbBFrame; + } + + void setFrames(const btTransform& frameA, const btTransform& frameB); + + void setAngularOnly(bool angularOnly) + { + m_angularOnly = angularOnly; + } + + void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse) + { + m_enableAngularMotor = enableMotor; + m_motorTargetVelocity = targetVelocity; + m_maxMotorImpulse = maxMotorImpulse; + } + + // extra motor API, including ability to set a target rotation (as opposed to angular velocity) + // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to + // maintain a given angular target. + void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; } + void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; } + void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B. + void setMotorTarget(btScalar targetAngle, btScalar dt); + + + void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + { +#ifdef _BT_USE_CENTER_LIMIT_ + m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor); +#else + m_lowerLimit = btNormalizeAngle(low); + m_upperLimit = btNormalizeAngle(high); + m_limitSoftness = _softness; + m_biasFactor = _biasFactor; + m_relaxationFactor = _relaxationFactor; +#endif + } + + void setAxis(btVector3& axisInA) + { + btVector3 rbAxisA1, rbAxisA2; + btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2); + btVector3 pivotInA = m_rbAFrame.getOrigin(); +// m_rbAFrame.getOrigin() = pivotInA; + m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), + rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), + rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + + btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA; + + btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); + btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); + + m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA)); + + m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), + rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), + rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); + m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis(); + + } + + btScalar getLowerLimit() const + { +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.getLow(); +#else + return m_lowerLimit; +#endif + } + + btScalar getUpperLimit() const + { +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.getHigh(); +#else + return m_upperLimit; +#endif + } + + + btScalar getHingeAngle(); + + btScalar getHingeAngle(const btTransform& transA,const btTransform& transB); + + void testLimit(const btTransform& transA,const btTransform& transB); + + + const btTransform& getAFrame() const { return m_rbAFrame; }; + const btTransform& getBFrame() const { return m_rbBFrame; }; + + btTransform& getAFrame() { return m_rbAFrame; }; + btTransform& getBFrame() { return m_rbBFrame; }; + + inline int getSolveLimit() + { +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.isLimit(); +#else + return m_solveLimit; +#endif + } + + inline btScalar getLimitSign() + { +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.getSign(); +#else + return m_limitSign; +#endif + } + + inline bool getAngularOnly() + { + return m_angularOnly; + } + inline bool getEnableAngularMotor() + { + return m_enableAngularMotor; + } + inline btScalar getMotorTargetVelosity() + { + return m_motorTargetVelocity; + } + inline btScalar getMaxMotorImpulse() + { + return m_maxMotorImpulse; + } + // access for UseFrameOffset + bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; } + void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; } + + + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///If no axis is provided, it uses the default axis for this constraint. + virtual void setParam(int num, btScalar value, int axis = -1); + ///return the local value of parameter + virtual btScalar getParam(int num, int axis = -1) const; + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btHingeConstraintDoubleData +{ + btTypedConstraintData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTransformDoubleData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + +}; +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btHingeConstraintFloatData +{ + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTransformFloatData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + +}; + + + +SIMD_FORCE_INLINE int btHingeConstraint::calculateSerializeBufferSize() const +{ + return sizeof(btHingeConstraintData); +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer; + btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer); + + m_rbAFrame.serialize(hingeData->m_rbAFrame); + m_rbBFrame.serialize(hingeData->m_rbBFrame); + + hingeData->m_angularOnly = m_angularOnly; + hingeData->m_enableAngularMotor = m_enableAngularMotor; + hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse); + hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity); + hingeData->m_useReferenceFrameA = m_useReferenceFrameA; +#ifdef _BT_USE_CENTER_LIMIT_ + hingeData->m_lowerLimit = float(m_limit.getLow()); + hingeData->m_upperLimit = float(m_limit.getHigh()); + hingeData->m_limitSoftness = float(m_limit.getSoftness()); + hingeData->m_biasFactor = float(m_limit.getBiasFactor()); + hingeData->m_relaxationFactor = float(m_limit.getRelaxationFactor()); +#else + hingeData->m_lowerLimit = float(m_lowerLimit); + hingeData->m_upperLimit = float(m_upperLimit); + hingeData->m_limitSoftness = float(m_limitSoftness); + hingeData->m_biasFactor = float(m_biasFactor); + hingeData->m_relaxationFactor = float(m_relaxationFactor); +#endif + + return btHingeConstraintDataName; +} + +#endif //BT_HINGECONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h b/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h new file mode 100644 index 0000000..125580d --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h @@ -0,0 +1,155 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_JACOBIAN_ENTRY_H +#define BT_JACOBIAN_ENTRY_H + +#include "LinearMath/btMatrix3x3.h" + + +//notes: +// Another memory optimization would be to store m_1MinvJt in the remaining 3 w components +// which makes the btJacobianEntry memory layout 16 bytes +// if you only are interested in angular part, just feed massInvA and massInvB zero + +/// Jacobian entry is an abstraction that allows to describe constraints +/// it can be used in combination with a constraint solver +/// Can be used to relate the effect of an impulse to the constraint error +ATTRIBUTE_ALIGNED16(class) btJacobianEntry +{ +public: + btJacobianEntry() {}; + //constraint between two different rigidbodies + btJacobianEntry( + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + const btVector3& rel_pos1,const btVector3& rel_pos2, + const btVector3& jointAxis, + const btVector3& inertiaInvA, + const btScalar massInvA, + const btVector3& inertiaInvB, + const btScalar massInvB) + :m_linearJointAxis(jointAxis) + { + m_aJ = world2A*(rel_pos1.cross(m_linearJointAxis)); + m_bJ = world2B*(rel_pos2.cross(-m_linearJointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = inertiaInvB * m_bJ; + m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + //angular constraint between two different rigidbodies + btJacobianEntry(const btVector3& jointAxis, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + const btVector3& inertiaInvA, + const btVector3& inertiaInvB) + :m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) + { + m_aJ= world2A*jointAxis; + m_bJ = world2B*-jointAxis; + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = inertiaInvB * m_bJ; + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + //angular constraint between two different rigidbodies + btJacobianEntry(const btVector3& axisInA, + const btVector3& axisInB, + const btVector3& inertiaInvA, + const btVector3& inertiaInvB) + : m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) + , m_aJ(axisInA) + , m_bJ(-axisInB) + { + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = inertiaInvB * m_bJ; + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + //constraint on one rigidbody + btJacobianEntry( + const btMatrix3x3& world2A, + const btVector3& rel_pos1,const btVector3& rel_pos2, + const btVector3& jointAxis, + const btVector3& inertiaInvA, + const btScalar massInvA) + :m_linearJointAxis(jointAxis) + { + m_aJ= world2A*(rel_pos1.cross(jointAxis)); + m_bJ = world2A*(rel_pos2.cross(-jointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); + m_Adiag = massInvA + m_0MinvJt.dot(m_aJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + btScalar getDiagonal() const { return m_Adiag; } + + // for two constraints on the same rigidbody (for example vehicle friction) + btScalar getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA) const + { + const btJacobianEntry& jacA = *this; + btScalar lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis); + btScalar ang = jacA.m_0MinvJt.dot(jacB.m_aJ); + return lin + ang; + } + + + + // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies) + btScalar getNonDiagonal(const btJacobianEntry& jacB,const btScalar massInvA,const btScalar massInvB) const + { + const btJacobianEntry& jacA = *this; + btVector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis; + btVector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ; + btVector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ; + btVector3 lin0 = massInvA * lin ; + btVector3 lin1 = massInvB * lin; + btVector3 sum = ang0+ang1+lin0+lin1; + return sum[0]+sum[1]+sum[2]; + } + + btScalar getRelativeVelocity(const btVector3& linvelA,const btVector3& angvelA,const btVector3& linvelB,const btVector3& angvelB) + { + btVector3 linrel = linvelA - linvelB; + btVector3 angvela = angvelA * m_aJ; + btVector3 angvelb = angvelB * m_bJ; + linrel *= m_linearJointAxis; + angvela += angvelb; + angvela += linrel; + btScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2]; + return rel_vel2 + SIMD_EPSILON; + } +//private: + + btVector3 m_linearJointAxis; + btVector3 m_aJ; + btVector3 m_bJ; + btVector3 m_0MinvJt; + btVector3 m_1MinvJt; + //Optimization: can be stored in the w/last component of one of the vectors + btScalar m_Adiag; + +}; + +#endif //BT_JACOBIAN_ENTRY_H diff --git a/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp new file mode 100644 index 0000000..11b2ec8 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp @@ -0,0 +1,230 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btPoint2PointConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include + + + + + +btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) +:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB), +m_flags(0), +m_useSolveConstraintObsolete(false) +{ + +} + + +btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) +:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)), +m_flags(0), +m_useSolveConstraintObsolete(false) +{ + +} + +void btPoint2PointConstraint::buildJacobian() +{ + + ///we need it for both methods + { + m_appliedImpulse = btScalar(0.); + + btVector3 normal(0,0,0); + + for (int i=0;i<3;i++) + { + normal[i] = 1; + new (&m_jac[i]) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(), + m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(), + normal, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + normal[i] = 0; + } + } + + +} + +void btPoint2PointConstraint::getInfo1 (btConstraintInfo1* info) +{ + getInfo1NonVirtual(info); +} + +void btPoint2PointConstraint::getInfo1NonVirtual (btConstraintInfo1* info) +{ + if (m_useSolveConstraintObsolete) + { + info->m_numConstraintRows = 0; + info->nub = 0; + } else + { + info->m_numConstraintRows = 3; + info->nub = 3; + } +} + + + + +void btPoint2PointConstraint::getInfo2 (btConstraintInfo2* info) +{ + getInfo2NonVirtual(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); +} + +void btPoint2PointConstraint::getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& body0_trans, const btTransform& body1_trans) +{ + btAssert(!m_useSolveConstraintObsolete); + + //retrieve matrices + + // anchor points in global coordinates with respect to body PORs. + + // set jacobian + info->m_J1linearAxis[0] = 1; + info->m_J1linearAxis[info->rowskip+1] = 1; + info->m_J1linearAxis[2*info->rowskip+2] = 1; + + btVector3 a1 = body0_trans.getBasis()*getPivotInA(); + { + btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); + btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip); + btVector3 a1neg = -a1; + a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + } + + /*info->m_J2linearAxis[0] = -1; + info->m_J2linearAxis[s+1] = -1; + info->m_J2linearAxis[2*s+2] = -1; + */ + + btVector3 a2 = body1_trans.getBasis()*getPivotInB(); + + { + // btVector3 a2n = -a2; + btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); + btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip); + a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + } + + + + // set right hand side + btScalar currERP = (m_flags & BT_P2P_FLAGS_ERP) ? m_erp : info->erp; + btScalar k = info->fps * currERP; + int j; + for (j=0; j<3; j++) + { + info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]); + //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); + } + if(m_flags & BT_P2P_FLAGS_CFM) + { + for (j=0; j<3; j++) + { + info->cfm[j*info->rowskip] = m_cfm; + } + } + + btScalar impulseClamp = m_setting.m_impulseClamp;// + for (j=0; j<3; j++) + { + if (m_setting.m_impulseClamp > 0) + { + info->m_lowerLimit[j*info->rowskip] = -impulseClamp; + info->m_upperLimit[j*info->rowskip] = impulseClamp; + } + } + info->m_damping = m_setting.m_damping; + +} + + + +void btPoint2PointConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} + +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///If no axis is provided, it uses the default axis for this constraint. +void btPoint2PointConstraint::setParam(int num, btScalar value, int axis) +{ + if(axis != -1) + { + btAssertConstrParams(0); + } + else + { + switch(num) + { + case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_STOP_ERP : + m_erp = value; + m_flags |= BT_P2P_FLAGS_ERP; + break; + case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_STOP_CFM : + m_cfm = value; + m_flags |= BT_P2P_FLAGS_CFM; + break; + default: + btAssertConstrParams(0); + } + } +} + +///return the local value of parameter +btScalar btPoint2PointConstraint::getParam(int num, int axis) const +{ + btScalar retVal(SIMD_INFINITY); + if(axis != -1) + { + btAssertConstrParams(0); + } + else + { + switch(num) + { + case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_STOP_ERP : + btAssertConstrParams(m_flags & BT_P2P_FLAGS_ERP); + retVal = m_erp; + break; + case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_STOP_CFM : + btAssertConstrParams(m_flags & BT_P2P_FLAGS_CFM); + retVal = m_cfm; + break; + default: + btAssertConstrParams(0); + } + } + return retVal; +} + diff --git a/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h new file mode 100644 index 0000000..1e13416 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h @@ -0,0 +1,163 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_POINT2POINTCONSTRAINT_H +#define BT_POINT2POINTCONSTRAINT_H + +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + + +#ifdef BT_USE_DOUBLE_PRECISION +#define btPoint2PointConstraintData btPoint2PointConstraintDoubleData +#define btPoint2PointConstraintDataName "btPoint2PointConstraintDoubleData" +#else +#define btPoint2PointConstraintData btPoint2PointConstraintFloatData +#define btPoint2PointConstraintDataName "btPoint2PointConstraintFloatData" +#endif //BT_USE_DOUBLE_PRECISION + +struct btConstraintSetting +{ + btConstraintSetting() : + m_tau(btScalar(0.3)), + m_damping(btScalar(1.)), + m_impulseClamp(btScalar(0.)) + { + } + btScalar m_tau; + btScalar m_damping; + btScalar m_impulseClamp; +}; + +enum btPoint2PointFlags +{ + BT_P2P_FLAGS_ERP = 1, + BT_P2P_FLAGS_CFM = 2 +}; + +/// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space +ATTRIBUTE_ALIGNED16(class) btPoint2PointConstraint : public btTypedConstraint +{ +#ifdef IN_PARALLELL_SOLVER +public: +#endif + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + + btVector3 m_pivotInA; + btVector3 m_pivotInB; + + int m_flags; + btScalar m_erp; + btScalar m_cfm; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + ///for backwards compatibility during the transition to 'getInfo/getInfo2' + bool m_useSolveConstraintObsolete; + + btConstraintSetting m_setting; + + btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB); + + btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA); + + + virtual void buildJacobian(); + + virtual void getInfo1 (btConstraintInfo1* info); + + void getInfo1NonVirtual (btConstraintInfo1* info); + + virtual void getInfo2 (btConstraintInfo2* info); + + void getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& body0_trans, const btTransform& body1_trans); + + void updateRHS(btScalar timeStep); + + void setPivotA(const btVector3& pivotA) + { + m_pivotInA = pivotA; + } + + void setPivotB(const btVector3& pivotB) + { + m_pivotInB = pivotB; + } + + const btVector3& getPivotInA() const + { + return m_pivotInA; + } + + const btVector3& getPivotInB() const + { + return m_pivotInB; + } + + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///If no axis is provided, it uses the default axis for this constraint. + virtual void setParam(int num, btScalar value, int axis = -1); + ///return the local value of parameter + virtual btScalar getParam(int num, int axis = -1) const; + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btPoint2PointConstraintFloatData +{ + btTypedConstraintData m_typeConstraintData; + btVector3FloatData m_pivotInA; + btVector3FloatData m_pivotInB; +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btPoint2PointConstraintDoubleData +{ + btTypedConstraintData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; +}; + + +SIMD_FORCE_INLINE int btPoint2PointConstraint::calculateSerializeBufferSize() const +{ + return sizeof(btPoint2PointConstraintData); + +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btPoint2PointConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btPoint2PointConstraintData* p2pData = (btPoint2PointConstraintData*)dataBuffer; + + btTypedConstraint::serialize(&p2pData->m_typeConstraintData,serializer); + m_pivotInA.serialize(p2pData->m_pivotInA); + m_pivotInB.serialize(p2pData->m_pivotInB); + + return btPoint2PointConstraintDataName; +} + +#endif //BT_POINT2POINTCONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp new file mode 100644 index 0000000..89cf46c --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -0,0 +1,1650 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//#define COMPUTE_IMPULSE_DENOM 1 +//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms. + +#include "btSequentialImpulseConstraintSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" + +#include "LinearMath/btIDebugDraw.h" +//#include "btJacobianEntry.h" +#include "LinearMath/btMinMax.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include +#include "LinearMath/btStackAlloc.h" +#include "LinearMath/btQuickprof.h" +//#include "btSolverBody.h" +//#include "btSolverConstraint.h" +#include "LinearMath/btAlignedObjectArray.h" +#include //for memset + +int gNumSplitImpulseRecoveries = 0; + +#include "BulletDynamics/Dynamics/btRigidBody.h" + +btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver() +:m_btSeed2(0) +{ + +} + +btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver() +{ +} + +#ifdef USE_SIMD +#include +#define btVecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e)) +static inline __m128 btSimdDot3( __m128 vec0, __m128 vec1 ) +{ + __m128 result = _mm_mul_ps( vec0, vec1); + return _mm_add_ps( btVecSplat( result, 0 ), _mm_add_ps( btVecSplat( result, 1 ), btVecSplat( result, 2 ) ) ); +} +#endif//USE_SIMD + +// Project Gauss Seidel or the equivalent Sequential Impulse +void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) +{ +#ifdef USE_SIMD + __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm))); + __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128)); + __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),btSimdDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128)); + deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); + deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); + btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); + btSimdScalar resultLowerLess,resultUpperLess; + resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); + resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); + __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); + deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); + c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); + __m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp); + deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) ); + c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1) ); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128); + __m128 impulseMagnitude = deltaImpulse; + body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); + body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); + body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); + body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); +#else + resolveSingleConstraintRowGeneric(body1,body2,c); +#endif +} + +// Project Gauss Seidel or the equivalent Sequential Impulse + void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) +{ + btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm; + const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity()); + const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity()); + +// const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn; + deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + + const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; + if (sum < c.m_lowerLimit) + { + deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; + c.m_appliedImpulse = c.m_lowerLimit; + } + else if (sum > c.m_upperLimit) + { + deltaImpulse = c.m_upperLimit-c.m_appliedImpulse; + c.m_appliedImpulse = c.m_upperLimit; + } + else + { + c.m_appliedImpulse = sum; + } + + body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); + body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); +} + + void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) +{ +#ifdef USE_SIMD + __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm))); + __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128)); + __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),btSimdDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128)); + deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); + deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); + btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); + btSimdScalar resultLowerLess,resultUpperLess; + resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); + resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); + __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); + deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); + c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128); + __m128 impulseMagnitude = deltaImpulse; + body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); + body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); + body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); + body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); +#else + resolveSingleConstraintRowLowerLimit(body1,body2,c); +#endif +} + +// Project Gauss Seidel or the equivalent Sequential Impulse + void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) +{ + btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm; + const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity()); + const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity()); + + deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; + if (sum < c.m_lowerLimit) + { + deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; + c.m_appliedImpulse = c.m_lowerLimit; + } + else + { + c.m_appliedImpulse = sum; + } + body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); + body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); +} + + +void btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFriendly( + btSolverBody& body1, + btSolverBody& body2, + const btSolverConstraint& c) +{ + if (c.m_rhsPenetration) + { + gNumSplitImpulseRecoveries++; + btScalar deltaImpulse = c.m_rhsPenetration-btScalar(c.m_appliedPushImpulse)*c.m_cfm; + const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetPushVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity()); + const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity()); + + deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + const btScalar sum = btScalar(c.m_appliedPushImpulse) + deltaImpulse; + if (sum < c.m_lowerLimit) + { + deltaImpulse = c.m_lowerLimit-c.m_appliedPushImpulse; + c.m_appliedPushImpulse = c.m_lowerLimit; + } + else + { + c.m_appliedPushImpulse = sum; + } + body1.internalApplyPushImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); + body2.internalApplyPushImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); + } +} + + void btSequentialImpulseConstraintSolver::resolveSplitPenetrationSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) +{ +#ifdef USE_SIMD + if (!c.m_rhsPenetration) + return; + + gNumSplitImpulseRecoveries++; + + __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedPushImpulse); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse),_mm_set1_ps(c.m_cfm))); + __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal.mVec128,body1.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128)); + __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128),btSimdDot3((c.m_contactNormal).mVec128,body2.internalGetPushVelocity().mVec128)); + deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); + deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); + btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); + btSimdScalar resultLowerLess,resultUpperLess; + resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); + resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); + __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); + deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); + c.m_appliedPushImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128); + __m128 impulseMagnitude = deltaImpulse; + body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); + body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); + body2.internalGetPushVelocity().mVec128 = _mm_sub_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); + body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); +#else + resolveSplitPenetrationImpulseCacheFriendly(body1,body2,c); +#endif +} + + + +unsigned long btSequentialImpulseConstraintSolver::btRand2() +{ + m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff; + return m_btSeed2; +} + + + +//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1) +int btSequentialImpulseConstraintSolver::btRandInt2 (int n) +{ + // seems good; xor-fold and modulus + const unsigned long un = static_cast(n); + unsigned long r = btRand2(); + + // note: probably more aggressive than it needs to be -- might be + // able to get away without one or two of the innermost branches. + if (un <= 0x00010000UL) { + r ^= (r >> 16); + if (un <= 0x00000100UL) { + r ^= (r >> 8); + if (un <= 0x00000010UL) { + r ^= (r >> 4); + if (un <= 0x00000004UL) { + r ^= (r >> 2); + if (un <= 0x00000002UL) { + r ^= (r >> 1); + } + } + } + } + } + + return (int) (r % un); +} + + + +void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject) +{ + + btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0; + + solverBody->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); + solverBody->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); + solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f); + solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f); + + if (rb) + { + solverBody->m_worldTransform = rb->getWorldTransform(); + solverBody->internalSetInvMass(btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor()); + solverBody->m_originalBody = rb; + solverBody->m_angularFactor = rb->getAngularFactor(); + solverBody->m_linearFactor = rb->getLinearFactor(); + solverBody->m_linearVelocity = rb->getLinearVelocity(); + solverBody->m_angularVelocity = rb->getAngularVelocity(); + } else + { + solverBody->m_worldTransform.setIdentity(); + solverBody->internalSetInvMass(btVector3(0,0,0)); + solverBody->m_originalBody = 0; + solverBody->m_angularFactor.setValue(1,1,1); + solverBody->m_linearFactor.setValue(1,1,1); + solverBody->m_linearVelocity.setValue(0,0,0); + solverBody->m_angularVelocity.setValue(0,0,0); + } + + +} + + + + + + +btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution) +{ + btScalar rest = restitution * -rel_vel; + return rest; +} + + + +static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode); +static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode) +{ + + + if (colObj && colObj->hasAnisotropicFriction(frictionMode)) + { + // transform to local coordinates + btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis(); + const btVector3& friction_scaling = colObj->getAnisotropicFriction(); + //apply anisotropic friction + loc_lateral *= friction_scaling; + // ... and transform it back to global coordinates + frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral; + } + +} + + + + +void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip) +{ + + + solverConstraint.m_contactNormal = normalAxis; + btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB]; + + btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody; + btRigidBody* body1 = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody; + + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + + solverConstraint.m_friction = cp.m_combinedFriction; + solverConstraint.m_originalContactPoint = 0; + + solverConstraint.m_appliedImpulse = 0.f; + solverConstraint.m_appliedPushImpulse = 0.f; + + { + btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal); + solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0); + } + { + btVector3 ftorqueAxis1 = rel_pos2.cross(-solverConstraint.m_contactNormal); + solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0); + } + + { + btVector3 vec; + btScalar denom0 = 0.f; + btScalar denom1 = 0.f; + if (body0) + { + vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); + denom0 = body0->getInvMass() + normalAxis.dot(vec); + } + if (body1) + { + vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); + denom1 = body1->getInvMass() + normalAxis.dot(vec); + } + btScalar denom = relaxation/(denom0+denom1); + solverConstraint.m_jacDiagABInv = denom; + } + + { + + + btScalar rel_vel; + btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?solverBodyA.m_linearVelocity:btVector3(0,0,0)) + + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0)); + btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?solverBodyB.m_linearVelocity:btVector3(0,0,0)) + + solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0)); + + rel_vel = vel1Dotn+vel2Dotn; + +// btScalar positionalError = 0.f; + + btSimdScalar velocityError = desiredVelocity - rel_vel; + btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv); + solverConstraint.m_rhs = velocityImpulse; + solverConstraint.m_cfm = cfmSlip; + solverConstraint.m_lowerLimit = 0; + solverConstraint.m_upperLimit = 1e10f; + + } +} + +btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip) +{ + btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing(); + solverConstraint.m_frictionIndex = frictionIndex; + setupFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, + colObj0, colObj1, relaxation, desiredVelocity, cfmSlip); + return solverConstraint; +} + + +void btSequentialImpulseConstraintSolver::setupRollingFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis1,int solverBodyIdA,int solverBodyIdB, + btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2, + btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, + btScalar desiredVelocity, btScalar cfmSlip) + +{ + btVector3 normalAxis(0,0,0); + + + solverConstraint.m_contactNormal = normalAxis; + btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB]; + + btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody; + btRigidBody* body1 = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody; + + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + + solverConstraint.m_friction = cp.m_combinedRollingFriction; + solverConstraint.m_originalContactPoint = 0; + + solverConstraint.m_appliedImpulse = 0.f; + solverConstraint.m_appliedPushImpulse = 0.f; + + { + btVector3 ftorqueAxis1 = -normalAxis1; + solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0); + } + { + btVector3 ftorqueAxis1 = normalAxis1; + solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0); + } + + + { + btVector3 iMJaA = body0?body0->getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal:btVector3(0,0,0); + btVector3 iMJaB = body1?body1->getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal:btVector3(0,0,0); + btScalar sum = 0; + sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); + sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); + solverConstraint.m_jacDiagABInv = btScalar(1.)/sum; + } + + { + + + btScalar rel_vel; + btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?solverBodyA.m_linearVelocity:btVector3(0,0,0)) + + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0)); + btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?solverBodyB.m_linearVelocity:btVector3(0,0,0)) + + solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0)); + + rel_vel = vel1Dotn+vel2Dotn; + +// btScalar positionalError = 0.f; + + btSimdScalar velocityError = desiredVelocity - rel_vel; + btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv); + solverConstraint.m_rhs = velocityImpulse; + solverConstraint.m_cfm = cfmSlip; + solverConstraint.m_lowerLimit = 0; + solverConstraint.m_upperLimit = 1e10f; + + } +} + + + + + + + + +btSolverConstraint& btSequentialImpulseConstraintSolver::addRollingFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip) +{ + btSolverConstraint& solverConstraint = m_tmpSolverContactRollingFrictionConstraintPool.expandNonInitializing(); + solverConstraint.m_frictionIndex = frictionIndex; + setupRollingFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, + colObj0, colObj1, relaxation, desiredVelocity, cfmSlip); + return solverConstraint; +} + + +int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body) +{ + + int solverBodyIdA = -1; + + if (body.getCompanionId() >= 0) + { + //body has already been converted + solverBodyIdA = body.getCompanionId(); + btAssert(solverBodyIdA < m_tmpSolverBodyPool.size()); + } else + { + btRigidBody* rb = btRigidBody::upcast(&body); + //convert both active and kinematic objects (for their velocity) + if (rb && (rb->getInvMass() || rb->isKinematicObject())) + { + solverBodyIdA = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&solverBody,&body); + body.setCompanionId(solverBodyIdA); + } else + { + return 0;//assume first one is a fixed solver body + } + } + + return solverBodyIdA; + +} +#include + + +void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint, + int solverBodyIdA, int solverBodyIdB, + btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, + btVector3& vel, btScalar& rel_vel, btScalar& relaxation, + btVector3& rel_pos1, btVector3& rel_pos2) +{ + + const btVector3& pos1 = cp.getPositionWorldOnA(); + const btVector3& pos2 = cp.getPositionWorldOnB(); + + btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; + + btRigidBody* rb0 = bodyA->m_originalBody; + btRigidBody* rb1 = bodyB->m_originalBody; + +// btVector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); +// btVector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin(); + rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); + rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); + + relaxation = 1.f; + + btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0); + btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0); + + { +#ifdef COMPUTE_IMPULSE_DENOM + btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); + btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); +#else + btVector3 vec; + btScalar denom0 = 0.f; + btScalar denom1 = 0.f; + if (rb0) + { + vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); + denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec); + } + if (rb1) + { + vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); + denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec); + } +#endif //COMPUTE_IMPULSE_DENOM + + btScalar denom = relaxation/(denom0+denom1); + solverConstraint.m_jacDiagABInv = denom; + } + + solverConstraint.m_contactNormal = cp.m_normalWorldOnB; + solverConstraint.m_relpos1CrossNormal = torqueAxis0; + solverConstraint.m_relpos2CrossNormal = -torqueAxis1; + + btScalar restitution = 0.f; + btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop; + + { + btVector3 vel1,vel2; + + vel1 = rb0? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0); + vel2 = rb1? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); + + // btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); + vel = vel1 - vel2; + rel_vel = cp.m_normalWorldOnB.dot(vel); + + + + solverConstraint.m_friction = cp.m_combinedFriction; + + + restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); + if (restitution <= btScalar(0.)) + { + restitution = 0.f; + }; + } + + + ///warm starting (or zero if disabled) + if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + { + solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; + if (rb0) + bodyA->internalApplyImpulse(solverConstraint.m_contactNormal*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse); + if (rb1) + bodyB->internalApplyImpulse(solverConstraint.m_contactNormal*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse); + } else + { + solverConstraint.m_appliedImpulse = 0.f; + } + + solverConstraint.m_appliedPushImpulse = 0.f; + + { + btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0?bodyA->m_linearVelocity:btVector3(0,0,0)) + + solverConstraint.m_relpos1CrossNormal.dot(rb0?bodyA->m_angularVelocity:btVector3(0,0,0)); + btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1?bodyB->m_linearVelocity:btVector3(0,0,0)) + + solverConstraint.m_relpos2CrossNormal.dot(rb1?bodyB->m_angularVelocity:btVector3(0,0,0)); + btScalar rel_vel = vel1Dotn+vel2Dotn; + + btScalar positionalError = 0.f; + btScalar velocityError = restitution - rel_vel;// * damping; + + + btScalar erp = infoGlobal.m_erp2; + if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) + { + erp = infoGlobal.m_erp; + } + + if (penetration>0) + { + positionalError = 0; + + velocityError -= penetration / infoGlobal.m_timeStep; + } else + { + positionalError = -penetration * erp/infoGlobal.m_timeStep; + } + + btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; + + if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) + { + //combine position and velocity into rhs + solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + solverConstraint.m_rhsPenetration = 0.f; + + } else + { + //split position and velocity into rhs and m_rhsPenetration + solverConstraint.m_rhs = velocityImpulse; + solverConstraint.m_rhsPenetration = penetrationImpulse; + } + solverConstraint.m_cfm = 0.f; + solverConstraint.m_lowerLimit = 0; + solverConstraint.m_upperLimit = 1e10f; + } + + + + +} + + + +void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, + int solverBodyIdA, int solverBodyIdB, + btManifoldPoint& cp, const btContactSolverInfo& infoGlobal) +{ + + btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; + + btRigidBody* rb0 = bodyA->m_originalBody; + btRigidBody* rb1 = bodyB->m_originalBody; + + { + btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex]; + if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + { + frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor; + if (rb0) + bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse); + if (rb1) + bodyB->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-(btScalar)frictionConstraint1.m_appliedImpulse); + } else + { + frictionConstraint1.m_appliedImpulse = 0.f; + } + } + + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) + { + btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1]; + if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + { + frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; + if (rb0) + bodyA->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse); + if (rb1) + bodyB->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-(btScalar)frictionConstraint2.m_appliedImpulse); + } else + { + frictionConstraint2.m_appliedImpulse = 0.f; + } + } +} + + + + +void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal) +{ + btCollisionObject* colObj0=0,*colObj1=0; + + colObj0 = (btCollisionObject*)manifold->getBody0(); + colObj1 = (btCollisionObject*)manifold->getBody1(); + + int solverBodyIdA = getOrInitSolverBody(*colObj0); + int solverBodyIdB = getOrInitSolverBody(*colObj1); + +// btRigidBody* bodyA = btRigidBody::upcast(colObj0); +// btRigidBody* bodyB = btRigidBody::upcast(colObj1); + + btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB]; + + + + ///avoid collision response between two static objects + if (!solverBodyA || (!solverBodyA->m_originalBody && (!solverBodyB || !solverBodyB->m_originalBody))) + return; + + int rollingFriction=1; + for (int j=0;jgetNumContacts();j++) + { + + btManifoldPoint& cp = manifold->getContactPoint(j); + + if (cp.getDistance() <= manifold->getContactProcessingThreshold()) + { + btVector3 rel_pos1; + btVector3 rel_pos2; + btScalar relaxation; + btScalar rel_vel; + btVector3 vel; + + int frictionIndex = m_tmpSolverContactConstraintPool.size(); + btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expandNonInitializing(); +// btRigidBody* rb0 = btRigidBody::upcast(colObj0); +// btRigidBody* rb1 = btRigidBody::upcast(colObj1); + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + + solverConstraint.m_originalContactPoint = &cp; + + setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, vel, rel_vel, relaxation, rel_pos1, rel_pos2); + +// const btVector3& pos1 = cp.getPositionWorldOnA(); +// const btVector3& pos2 = cp.getPositionWorldOnB(); + + /////setup the friction constraints + + solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size(); + + btVector3 angVelA,angVelB; + solverBodyA->getAngularVelocity(angVelA); + solverBodyB->getAngularVelocity(angVelB); + btVector3 relAngVel = angVelB-angVelA; + + if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0)) + { + //only a single rollingFriction per manifold + rollingFriction--; + if (relAngVel.length()>infoGlobal.m_singleAxisRollingFrictionThreshold) + { + relAngVel.normalize(); + applyAnisotropicFriction(colObj0,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + if (relAngVel.length()>0.001) + addRollingFrictionConstraint(relAngVel,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + + } else + { + addRollingFrictionConstraint(cp.m_normalWorldOnB,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + btVector3 axis0,axis1; + btPlaneSpace1(cp.m_normalWorldOnB,axis0,axis1); + applyAnisotropicFriction(colObj0,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj0,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + if (axis0.length()>0.001) + addRollingFrictionConstraint(axis0,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + if (axis1.length()>0.001) + addRollingFrictionConstraint(axis1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + + } + } + + ///Bullet has several options to set the friction directions + ///By default, each contact has only a single friction direction that is recomputed automatically very frame + ///based on the relative linear velocity. + ///If the relative velocity it zero, it will automatically compute a friction direction. + + ///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS. + ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction. + /// + ///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity. + /// + ///The user can manually override the friction directions for certain contacts using a contact callback, + ///and set the cp.m_lateralFrictionInitialized to true + ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2) + ///this will give a conveyor belt effect + /// + if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized) + { + cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; + btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); + if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON) + { + cp.m_lateralFrictionDir1 *= 1.f/btSqrt(lat_rel_vel); + if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) + { + cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); + cp.m_lateralFrictionDir2.normalize();//?? + applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + + } + + applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + + } else + { + btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); + + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) + { + applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + } + + applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION)) + { + cp.m_lateralFrictionInitialized = true; + } + } + + } else + { + addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.m_contactMotion1, cp.m_contactCFM1); + + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) + addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2); + + setFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal); + } + + + + + } + } +} + +btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) +{ + BT_PROFILE("solveGroupCacheFriendlySetup"); + (void)stackAlloc; + (void)debugDrawer; + + m_maxOverrideNumSolverIterations = 0; + +#ifdef BT_DEBUG + //make sure that dynamic bodies exist for all (enabled) constraints + for (int i=0;iisEnabled()) + { + if (!constraint->getRigidBodyA().isStaticOrKinematicObject()) + { + bool found=false; + for (int b=0;bgetRigidBodyA()==bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + if (!constraint->getRigidBodyB().isStaticOrKinematicObject()) + { + bool found=false; + for (int b=0;bgetRigidBodyB()==bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + } + } + //make sure that dynamic bodies exist for all contact manifolds + for (int i=0;igetBody0()->isStaticOrKinematicObject()) + { + bool found=false; + for (int b=0;bgetBody0()==bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject()) + { + bool found=false; + for (int b=0;bgetBody1()==bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + } +#endif //BT_DEBUG + + + for (int i = 0; i < numBodies; i++) + { + bodies[i]->setCompanionId(-1); + } + + + m_tmpSolverBodyPool.reserve(numBodies+1); + m_tmpSolverBodyPool.resize(0); + + btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&fixedBody,0); + + //convert all bodies + + for (int i=0;igetInvMass()) + { + btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId]; + btVector3 gyroForce (0,0,0); + if (body->getFlags()&BT_ENABLE_GYROPSCOPIC_FORCE) + { + gyroForce = body->computeGyroscopicForce(infoGlobal.m_maxGyroscopicForce); + } + solverBody.m_linearVelocity += body->getTotalForce()*body->getInvMass()*infoGlobal.m_timeStep; + solverBody.m_angularVelocity += (body->getTotalTorque()-gyroForce)*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep; + } + } + + if (1) + { + int j; + for (j=0;jbuildJacobian(); + constraint->internalSetAppliedImpulse(0.0f); + } + } + + //btRigidBody* rb0=0,*rb1=0; + + //if (1) + { + { + + int totalNumRows = 0; + int i; + + m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints); + //calculate the total number of contraint rows + for (i=0;igetJointFeedback(); + if (fb) + { + fb->m_appliedForceBodyA.setZero(); + fb->m_appliedTorqueBodyA.setZero(); + fb->m_appliedForceBodyB.setZero(); + fb->m_appliedTorqueBodyB.setZero(); + } + + if (constraints[i]->isEnabled()) + { + } + if (constraints[i]->isEnabled()) + { + constraints[i]->getInfo1(&info1); + } else + { + info1.m_numConstraintRows = 0; + info1.nub = 0; + } + totalNumRows += info1.m_numConstraintRows; + } + m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows); + + + ///setup the btSolverConstraints + int currentRow = 0; + + for (i=0;igetRigidBodyA(); + btRigidBody& rbB = constraint->getRigidBodyB(); + + int solverBodyIdA = getOrInitSolverBody(rbA); + int solverBodyIdB = getOrInitSolverBody(rbB); + + btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; + + + + + int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations; + if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations) + m_maxOverrideNumSolverIterations = overrideNumSolverIterations; + + + int j; + for ( j=0;jinternalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); + bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); + bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); + bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); + bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); + bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); + bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); + bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); + + + btTypedConstraint::btConstraintInfo2 info2; + info2.fps = 1.f/infoGlobal.m_timeStep; + info2.erp = infoGlobal.m_erp; + info2.m_J1linearAxis = currentConstraintRow->m_contactNormal; + info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; + info2.m_J2linearAxis = 0; + info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; + info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this + ///the size of btSolverConstraint needs be a multiple of btScalar + btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint)); + info2.m_constraintError = ¤tConstraintRow->m_rhs; + currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; + info2.m_damping = infoGlobal.m_damping; + info2.cfm = ¤tConstraintRow->m_cfm; + info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit; + info2.m_upperLimit = ¤tConstraintRow->m_upperLimit; + info2.m_numIterations = infoGlobal.m_numIterations; + constraints[i]->getInfo2(&info2); + + ///finalize the constraint setup + for ( j=0;j=constraints[i]->getBreakingImpulseThreshold()) + { + solverConstraint.m_upperLimit = constraints[i]->getBreakingImpulseThreshold(); + } + + if (solverConstraint.m_lowerLimit<=-constraints[i]->getBreakingImpulseThreshold()) + { + solverConstraint.m_lowerLimit = -constraints[i]->getBreakingImpulseThreshold(); + } + + solverConstraint.m_originalContactPoint = constraint; + + { + const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal; + solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor(); + } + { + const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; + solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor(); + } + + { + btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass(); + btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal; + btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal? + btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal; + + btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal); + sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); + sum += iMJlB.dot(solverConstraint.m_contactNormal); + sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); + btScalar fsum = btFabs(sum); + btAssert(fsum > SIMD_EPSILON); + solverConstraint.m_jacDiagABInv = fsum>SIMD_EPSILON?btScalar(1.)/sum : 0.f; + } + + + ///fix rhs + ///todo: add force/torque accelerators + { + btScalar rel_vel; + btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()); + btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()); + + rel_vel = vel1Dotn+vel2Dotn; + + btScalar restitution = 0.f; + btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 + btScalar velocityError = restitution - rel_vel * info2.m_damping; + btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; + solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + solverConstraint.m_appliedImpulse = 0.f; + + } + } + } + currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows; + } + } + + { + int i; + btPersistentManifold* manifold = 0; +// btCollisionObject* colObj0=0,*colObj1=0; + + + for (i=0;iisEnabled()) + { + int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA()); + int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB()); + btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; + btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; + constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep); + } + } + + ///solve all contact constraints using SIMD, if available + if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS) + { + int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); + int multiplier = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)? 2 : 1; + + for (int c=0;cbtScalar(0)) + { + solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + } + } + + if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) + { + + btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier+1]]; + + if (totalImpulse>btScalar(0)) + { + solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + } + } + } + } + + } + else//SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS + { + //solve the friction constraints after all contact constraints, don't interleave them + int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); + int j; + + for (j=0;jbtScalar(0)) + { + solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + } + } + + + int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); + for (j=0;jbtScalar(0)) + { + btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; + if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction) + rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; + + rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; + rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; + + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint); + } + } + + + } + } + } else + { + //non-SIMD version + ///solve all joint constraints + for (int j=0;jisEnabled()) + { + int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA()); + int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB()); + btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; + btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; + constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep); + } + } + ///solve all contact constraints + int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); + for (int j=0;jbtScalar(0)) + { + solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + + resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + } + } + + int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); + for (int j=0;jbtScalar(0)) + { + btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; + if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction) + rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; + + rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; + rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; + + resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint); + } + } + } + } + return 0.f; +} + + +void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) +{ + int iteration; + if (infoGlobal.m_splitImpulse) + { + if (infoGlobal.m_solverMode & SOLVER_SIMD) + { + for ( iteration = 0;iteration infoGlobal.m_numIterations? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations; + + for ( int iteration = 0 ; iteration< maxIterations ; iteration++) + //for ( int iteration = maxIterations-1 ; iteration >= 0;iteration--) + { + solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc); + } + + } + return 0.f; +} + +btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal) +{ + int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); + int i,j; + + if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + { + for (j=0;jm_appliedImpulse = solveManifold.m_appliedImpulse; + // float f = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; + // printf("pt->m_appliedImpulseLateral1 = %f\n", f); + pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; + //printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1); + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) + { + pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse; + } + //do a callback here? + } + } + + numPoolConstraints = m_tmpSolverNonContactConstraintPool.size(); + for (j=0;jgetJointFeedback(); + if (fb) + { + fb->m_appliedForceBodyA += solverConstr.m_contactNormal*solverConstr.m_appliedImpulse*constr->getRigidBodyA().getLinearFactor()/infoGlobal.m_timeStep; + fb->m_appliedForceBodyB += -solverConstr.m_contactNormal*solverConstr.m_appliedImpulse*constr->getRigidBodyB().getLinearFactor()/infoGlobal.m_timeStep; + fb->m_appliedTorqueBodyA += solverConstr.m_relpos1CrossNormal* constr->getRigidBodyA().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; + fb->m_appliedTorqueBodyB += -solverConstr.m_relpos1CrossNormal* constr->getRigidBodyB().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; + + } + + constr->internalSetAppliedImpulse(solverConstr.m_appliedImpulse); + if (btFabs(solverConstr.m_appliedImpulse)>=constr->getBreakingImpulseThreshold()) + { + constr->setEnabled(false); + } + } + + + + for ( i=0;isetLinearVelocity(m_tmpSolverBodyPool[i].m_linearVelocity); + m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(m_tmpSolverBodyPool[i].m_angularVelocity); + if (infoGlobal.m_splitImpulse) + m_tmpSolverBodyPool[i].m_originalBody->setWorldTransform(m_tmpSolverBodyPool[i].m_worldTransform); + + m_tmpSolverBodyPool[i].m_originalBody->setCompanionId(-1); + } + } + + m_tmpSolverContactConstraintPool.resizeNoInitialize(0); + m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0); + m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(0); + m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(0); + + m_tmpSolverBodyPool.resizeNoInitialize(0); + return 0.f; +} + + + +/// btSequentialImpulseConstraintSolver Sequentially applies impulses +btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/) +{ + + BT_PROFILE("solveGroup"); + //you need to provide at least some bodies + + solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc); + + solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc); + + solveGroupCacheFriendlyFinish(bodies, numBodies, infoGlobal); + + return 0.f; +} + +void btSequentialImpulseConstraintSolver::reset() +{ + m_btSeed2 = 0; +} + + diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h new file mode 100644 index 0000000..2eea6be --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h @@ -0,0 +1,141 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H +#define BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H + +class btIDebugDraw; +class btPersistentManifold; +class btStackAlloc; +class btDispatcher; +class btCollisionObject; +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/ConstraintSolver/btSolverBody.h" +#include "BulletDynamics/ConstraintSolver/btSolverConstraint.h" +#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" +#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h" + +///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method. +ATTRIBUTE_ALIGNED16(class) btSequentialImpulseConstraintSolver : public btConstraintSolver +{ +protected: + btAlignedObjectArray m_tmpSolverBodyPool; + btConstraintArray m_tmpSolverContactConstraintPool; + btConstraintArray m_tmpSolverNonContactConstraintPool; + btConstraintArray m_tmpSolverContactFrictionConstraintPool; + btConstraintArray m_tmpSolverContactRollingFrictionConstraintPool; + + btAlignedObjectArray m_orderTmpConstraintPool; + btAlignedObjectArray m_orderNonContactConstraintPool; + btAlignedObjectArray m_orderFrictionConstraintPool; + btAlignedObjectArray m_tmpConstraintSizesPool; + int m_maxOverrideNumSolverIterations; + + void setupFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB, + btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2, + btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, + btScalar desiredVelocity=0., btScalar cfmSlip=0.); + + void setupRollingFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB, + btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2, + btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, + btScalar desiredVelocity=0., btScalar cfmSlip=0.); + + btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0., btScalar cfmSlip=0.); + btSolverConstraint& addRollingFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0, btScalar cfmSlip=0.f); + + + void setupContactConstraint(btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, + const btContactSolverInfo& infoGlobal, btVector3& vel, btScalar& rel_vel, btScalar& relaxation, + btVector3& rel_pos1, btVector3& rel_pos2); + + void setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, int solverBodyIdA,int solverBodyIdB, + btManifoldPoint& cp, const btContactSolverInfo& infoGlobal); + + ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction + unsigned long m_btSeed2; + + + btScalar restitutionCurve(btScalar rel_vel, btScalar restitution); + + void convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal); + + + void resolveSplitPenetrationSIMD( + btSolverBody& bodyA,btSolverBody& bodyB, + const btSolverConstraint& contactConstraint); + + void resolveSplitPenetrationImpulseCacheFriendly( + btSolverBody& bodyA,btSolverBody& bodyB, + const btSolverConstraint& contactConstraint); + + //internal method + int getOrInitSolverBody(btCollisionObject& body); + void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject); + + void resolveSingleConstraintRowGeneric(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); + + void resolveSingleConstraintRowGenericSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); + + void resolveSingleConstraintRowLowerLimit(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); + + void resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); + +protected: + + + virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal); + btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + + virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btSequentialImpulseConstraintSolver(); + virtual ~btSequentialImpulseConstraintSolver(); + + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher); + + + + ///clear internal cached data and reset random seed + virtual void reset(); + + unsigned long btRand2(); + + int btRandInt2 (int n); + + void setRandSeed(unsigned long seed) + { + m_btSeed2 = seed; + } + unsigned long getRandSeed() const + { + return m_btSeed2; + } + +}; + + + + +#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H + diff --git a/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp new file mode 100755 index 0000000..b69f46d --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp @@ -0,0 +1,857 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* +Added by Roman Ponomarev (rponom@gmail.com) +April 04, 2008 +*/ + + + +#include "btSliderConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" +#include + +#define USE_OFFSET_FOR_CONSTANT_FRAME true + +void btSliderConstraint::initParams() +{ + m_lowerLinLimit = btScalar(1.0); + m_upperLinLimit = btScalar(-1.0); + m_lowerAngLimit = btScalar(0.); + m_upperAngLimit = btScalar(0.); + m_softnessDirLin = SLIDER_CONSTRAINT_DEF_SOFTNESS; + m_restitutionDirLin = SLIDER_CONSTRAINT_DEF_RESTITUTION; + m_dampingDirLin = btScalar(0.); + m_cfmDirLin = SLIDER_CONSTRAINT_DEF_CFM; + m_softnessDirAng = SLIDER_CONSTRAINT_DEF_SOFTNESS; + m_restitutionDirAng = SLIDER_CONSTRAINT_DEF_RESTITUTION; + m_dampingDirAng = btScalar(0.); + m_cfmDirAng = SLIDER_CONSTRAINT_DEF_CFM; + m_softnessOrthoLin = SLIDER_CONSTRAINT_DEF_SOFTNESS; + m_restitutionOrthoLin = SLIDER_CONSTRAINT_DEF_RESTITUTION; + m_dampingOrthoLin = SLIDER_CONSTRAINT_DEF_DAMPING; + m_cfmOrthoLin = SLIDER_CONSTRAINT_DEF_CFM; + m_softnessOrthoAng = SLIDER_CONSTRAINT_DEF_SOFTNESS; + m_restitutionOrthoAng = SLIDER_CONSTRAINT_DEF_RESTITUTION; + m_dampingOrthoAng = SLIDER_CONSTRAINT_DEF_DAMPING; + m_cfmOrthoAng = SLIDER_CONSTRAINT_DEF_CFM; + m_softnessLimLin = SLIDER_CONSTRAINT_DEF_SOFTNESS; + m_restitutionLimLin = SLIDER_CONSTRAINT_DEF_RESTITUTION; + m_dampingLimLin = SLIDER_CONSTRAINT_DEF_DAMPING; + m_cfmLimLin = SLIDER_CONSTRAINT_DEF_CFM; + m_softnessLimAng = SLIDER_CONSTRAINT_DEF_SOFTNESS; + m_restitutionLimAng = SLIDER_CONSTRAINT_DEF_RESTITUTION; + m_dampingLimAng = SLIDER_CONSTRAINT_DEF_DAMPING; + m_cfmLimAng = SLIDER_CONSTRAINT_DEF_CFM; + + m_poweredLinMotor = false; + m_targetLinMotorVelocity = btScalar(0.); + m_maxLinMotorForce = btScalar(0.); + m_accumulatedLinMotorImpulse = btScalar(0.0); + + m_poweredAngMotor = false; + m_targetAngMotorVelocity = btScalar(0.); + m_maxAngMotorForce = btScalar(0.); + m_accumulatedAngMotorImpulse = btScalar(0.0); + + m_flags = 0; + m_flags = 0; + + m_useOffsetForConstraintFrame = USE_OFFSET_FOR_CONSTANT_FRAME; + + calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); +} + + + + + +btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) + : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB), + m_useSolveConstraintObsolete(false), + m_frameInA(frameInA), + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameA) +{ + initParams(); +} + + + +btSliderConstraint::btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA) + : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, getFixedBody(), rbB), + m_useSolveConstraintObsolete(false), + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameA) +{ + ///not providing rigidbody A means implicitly using worldspace for body A + m_frameInA = rbB.getCenterOfMassTransform() * m_frameInB; +// m_frameInA.getOrigin() = m_rbA.getCenterOfMassTransform()(m_frameInA.getOrigin()); + + initParams(); +} + + + + + + +void btSliderConstraint::getInfo1(btConstraintInfo1* info) +{ + if (m_useSolveConstraintObsolete) + { + info->m_numConstraintRows = 0; + info->nub = 0; + } + else + { + info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular + info->nub = 2; + //prepare constraint + calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + testAngLimits(); + testLinLimits(); + if(getSolveLinLimit() || getPoweredLinMotor()) + { + info->m_numConstraintRows++; // limit 3rd linear as well + info->nub--; + } + if(getSolveAngLimit() || getPoweredAngMotor()) + { + info->m_numConstraintRows++; // limit 3rd angular as well + info->nub--; + } + } +} + +void btSliderConstraint::getInfo1NonVirtual(btConstraintInfo1* info) +{ + + info->m_numConstraintRows = 6; // Fixed 2 linear + 2 angular + 1 limit (even if not used) + info->nub = 0; +} + +void btSliderConstraint::getInfo2(btConstraintInfo2* info) +{ + getInfo2NonVirtual(info,m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(), m_rbA.getLinearVelocity(),m_rbB.getLinearVelocity(), m_rbA.getInvMass(),m_rbB.getInvMass()); +} + + + + + + + +void btSliderConstraint::calculateTransforms(const btTransform& transA,const btTransform& transB) +{ + if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete)) + { + m_calculatedTransformA = transA * m_frameInA; + m_calculatedTransformB = transB * m_frameInB; + } + else + { + m_calculatedTransformA = transB * m_frameInB; + m_calculatedTransformB = transA * m_frameInA; + } + m_realPivotAInW = m_calculatedTransformA.getOrigin(); + m_realPivotBInW = m_calculatedTransformB.getOrigin(); + m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X + if(m_useLinearReferenceFrameA || m_useSolveConstraintObsolete) + { + m_delta = m_realPivotBInW - m_realPivotAInW; + } + else + { + m_delta = m_realPivotAInW - m_realPivotBInW; + } + m_projPivotInW = m_realPivotAInW + m_sliderAxis.dot(m_delta) * m_sliderAxis; + btVector3 normalWorld; + int i; + //linear part + for(i = 0; i < 3; i++) + { + normalWorld = m_calculatedTransformA.getBasis().getColumn(i); + m_depth[i] = m_delta.dot(normalWorld); + } +} + + + +void btSliderConstraint::testLinLimits(void) +{ + m_solveLinLim = false; + m_linPos = m_depth[0]; + if(m_lowerLinLimit <= m_upperLinLimit) + { + if(m_depth[0] > m_upperLinLimit) + { + m_depth[0] -= m_upperLinLimit; + m_solveLinLim = true; + } + else if(m_depth[0] < m_lowerLinLimit) + { + m_depth[0] -= m_lowerLinLimit; + m_solveLinLim = true; + } + else + { + m_depth[0] = btScalar(0.); + } + } + else + { + m_depth[0] = btScalar(0.); + } +} + + + +void btSliderConstraint::testAngLimits(void) +{ + m_angDepth = btScalar(0.); + m_solveAngLim = false; + if(m_lowerAngLimit <= m_upperAngLimit) + { + const btVector3 axisA0 = m_calculatedTransformA.getBasis().getColumn(1); + const btVector3 axisA1 = m_calculatedTransformA.getBasis().getColumn(2); + const btVector3 axisB0 = m_calculatedTransformB.getBasis().getColumn(1); +// btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0)); + btScalar rot = btAtan2(axisB0.dot(axisA1), axisB0.dot(axisA0)); + rot = btAdjustAngleToLimits(rot, m_lowerAngLimit, m_upperAngLimit); + m_angPos = rot; + if(rot < m_lowerAngLimit) + { + m_angDepth = rot - m_lowerAngLimit; + m_solveAngLim = true; + } + else if(rot > m_upperAngLimit) + { + m_angDepth = rot - m_upperAngLimit; + m_solveAngLim = true; + } + } +} + +btVector3 btSliderConstraint::getAncorInA(void) +{ + btVector3 ancorInA; + ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * btScalar(0.5) * m_sliderAxis; + ancorInA = m_rbA.getCenterOfMassTransform().inverse() * ancorInA; + return ancorInA; +} + + + +btVector3 btSliderConstraint::getAncorInB(void) +{ + btVector3 ancorInB; + ancorInB = m_frameInB.getOrigin(); + return ancorInB; +} + + +void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB, const btVector3& linVelA,const btVector3& linVelB, btScalar rbAinvMass,btScalar rbBinvMass ) +{ + const btTransform& trA = getCalculatedTransformA(); + const btTransform& trB = getCalculatedTransformB(); + + btAssert(!m_useSolveConstraintObsolete); + int i, s = info->rowskip; + + btScalar signFact = m_useLinearReferenceFrameA ? btScalar(1.0f) : btScalar(-1.0f); + + // difference between frames in WCS + btVector3 ofs = trB.getOrigin() - trA.getOrigin(); + // now get weight factors depending on masses + btScalar miA = rbAinvMass; + btScalar miB = rbBinvMass; + bool hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON); + btScalar miS = miA + miB; + btScalar factA, factB; + if(miS > btScalar(0.f)) + { + factA = miB / miS; + } + else + { + factA = btScalar(0.5f); + } + factB = btScalar(1.0f) - factA; + btVector3 ax1, p, q; + btVector3 ax1A = trA.getBasis().getColumn(0); + btVector3 ax1B = trB.getBasis().getColumn(0); + if(m_useOffsetForConstraintFrame) + { + // get the desired direction of slider axis + // as weighted sum of X-orthos of frameA and frameB in WCS + ax1 = ax1A * factA + ax1B * factB; + ax1.normalize(); + // construct two orthos to slider axis + btPlaneSpace1 (ax1, p, q); + } + else + { // old way - use frameA + ax1 = trA.getBasis().getColumn(0); + // get 2 orthos to slider axis (Y, Z) + p = trA.getBasis().getColumn(1); + q = trA.getBasis().getColumn(2); + } + // make rotations around these orthos equal + // the slider axis should be the only unconstrained + // rotational axis, the angular velocity of the two bodies perpendicular to + // the slider axis should be equal. thus the constraint equations are + // p*w1 - p*w2 = 0 + // q*w1 - q*w2 = 0 + // where p and q are unit vectors normal to the slider axis, and w1 and w2 + // are the angular velocity vectors of the two bodies. + info->m_J1angularAxis[0] = p[0]; + info->m_J1angularAxis[1] = p[1]; + info->m_J1angularAxis[2] = p[2]; + info->m_J1angularAxis[s+0] = q[0]; + info->m_J1angularAxis[s+1] = q[1]; + info->m_J1angularAxis[s+2] = q[2]; + + info->m_J2angularAxis[0] = -p[0]; + info->m_J2angularAxis[1] = -p[1]; + info->m_J2angularAxis[2] = -p[2]; + info->m_J2angularAxis[s+0] = -q[0]; + info->m_J2angularAxis[s+1] = -q[1]; + info->m_J2angularAxis[s+2] = -q[2]; + // compute the right hand side of the constraint equation. set relative + // body velocities along p and q to bring the slider back into alignment. + // if ax1A,ax1B are the unit length slider axes as computed from bodyA and + // bodyB, we need to rotate both bodies along the axis u = (ax1 x ax2). + // if "theta" is the angle between ax1 and ax2, we need an angular velocity + // along u to cover angle erp*theta in one step : + // |angular_velocity| = angle/time = erp*theta / stepsize + // = (erp*fps) * theta + // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| + // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) + // ...as ax1 and ax2 are unit length. if theta is smallish, + // theta ~= sin(theta), so + // angular_velocity = (erp*fps) * (ax1 x ax2) + // ax1 x ax2 is in the plane space of ax1, so we project the angular + // velocity to p and q to find the right hand side. +// btScalar k = info->fps * info->erp * getSoftnessOrthoAng(); + btScalar currERP = (m_flags & BT_SLIDER_FLAGS_ERP_ORTANG) ? m_softnessOrthoAng : m_softnessOrthoAng * info->erp; + btScalar k = info->fps * currERP; + + btVector3 u = ax1A.cross(ax1B); + info->m_constraintError[0] = k * u.dot(p); + info->m_constraintError[s] = k * u.dot(q); + if(m_flags & BT_SLIDER_FLAGS_CFM_ORTANG) + { + info->cfm[0] = m_cfmOrthoAng; + info->cfm[s] = m_cfmOrthoAng; + } + + int nrow = 1; // last filled row + int srow; + btScalar limit_err; + int limit; + int powered; + + // next two rows. + // we want: velA + wA x relA == velB + wB x relB ... but this would + // result in three equations, so we project along two orthos to the slider axis + + btTransform bodyA_trans = transA; + btTransform bodyB_trans = transB; + nrow++; + int s2 = nrow * s; + nrow++; + int s3 = nrow * s; + btVector3 tmpA(0,0,0), tmpB(0,0,0), relA(0,0,0), relB(0,0,0), c(0,0,0); + if(m_useOffsetForConstraintFrame) + { + // get vector from bodyB to frameB in WCS + relB = trB.getOrigin() - bodyB_trans.getOrigin(); + // get its projection to slider axis + btVector3 projB = ax1 * relB.dot(ax1); + // get vector directed from bodyB to slider axis (and orthogonal to it) + btVector3 orthoB = relB - projB; + // same for bodyA + relA = trA.getOrigin() - bodyA_trans.getOrigin(); + btVector3 projA = ax1 * relA.dot(ax1); + btVector3 orthoA = relA - projA; + // get desired offset between frames A and B along slider axis + btScalar sliderOffs = m_linPos - m_depth[0]; + // desired vector from projection of center of bodyA to projection of center of bodyB to slider axis + btVector3 totalDist = projA + ax1 * sliderOffs - projB; + // get offset vectors relA and relB + relA = orthoA + totalDist * factA; + relB = orthoB - totalDist * factB; + // now choose average ortho to slider axis + p = orthoB * factA + orthoA * factB; + btScalar len2 = p.length2(); + if(len2 > SIMD_EPSILON) + { + p /= btSqrt(len2); + } + else + { + p = trA.getBasis().getColumn(1); + } + // make one more ortho + q = ax1.cross(p); + // fill two rows + tmpA = relA.cross(p); + tmpB = relB.cross(p); + for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = tmpA[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = -tmpB[i]; + tmpA = relA.cross(q); + tmpB = relB.cross(q); + if(hasStaticBody && getSolveAngLimit()) + { // to make constraint between static and dynamic objects more rigid + // remove wA (or wB) from equation if angular limit is hit + tmpB *= factB; + tmpA *= factA; + } + for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = tmpA[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = -tmpB[i]; + for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i]; + for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i]; + } + else + { // old way - maybe incorrect if bodies are not on the slider axis + // see discussion "Bug in slider constraint" http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=4024&start=0 + c = bodyB_trans.getOrigin() - bodyA_trans.getOrigin(); + btVector3 tmp = c.cross(p); + for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = factA*tmp[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = factB*tmp[i]; + tmp = c.cross(q); + for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = factA*tmp[i]; + for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = factB*tmp[i]; + + for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i]; + for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i]; + } + // compute two elements of right hand side + + // k = info->fps * info->erp * getSoftnessOrthoLin(); + currERP = (m_flags & BT_SLIDER_FLAGS_ERP_ORTLIN) ? m_softnessOrthoLin : m_softnessOrthoLin * info->erp; + k = info->fps * currERP; + + btScalar rhs = k * p.dot(ofs); + info->m_constraintError[s2] = rhs; + rhs = k * q.dot(ofs); + info->m_constraintError[s3] = rhs; + if(m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN) + { + info->cfm[s2] = m_cfmOrthoLin; + info->cfm[s3] = m_cfmOrthoLin; + } + + + // check linear limits + limit_err = btScalar(0.0); + limit = 0; + if(getSolveLinLimit()) + { + limit_err = getLinDepth() * signFact; + limit = (limit_err > btScalar(0.0)) ? 2 : 1; + } + powered = 0; + if(getPoweredLinMotor()) + { + powered = 1; + } + // if the slider has joint limits or motor, add in the extra row + if (limit || powered) + { + nrow++; + srow = nrow * info->rowskip; + info->m_J1linearAxis[srow+0] = ax1[0]; + info->m_J1linearAxis[srow+1] = ax1[1]; + info->m_J1linearAxis[srow+2] = ax1[2]; + // linear torque decoupling step: + // + // we have to be careful that the linear constraint forces (+/- ax1) applied to the two bodies + // do not create a torque couple. in other words, the points that the + // constraint force is applied at must lie along the same ax1 axis. + // a torque couple will result in limited slider-jointed free + // bodies from gaining angular momentum. + if(m_useOffsetForConstraintFrame) + { + // this is needed only when bodyA and bodyB are both dynamic. + if(!hasStaticBody) + { + tmpA = relA.cross(ax1); + tmpB = relB.cross(ax1); + info->m_J1angularAxis[srow+0] = tmpA[0]; + info->m_J1angularAxis[srow+1] = tmpA[1]; + info->m_J1angularAxis[srow+2] = tmpA[2]; + info->m_J2angularAxis[srow+0] = -tmpB[0]; + info->m_J2angularAxis[srow+1] = -tmpB[1]; + info->m_J2angularAxis[srow+2] = -tmpB[2]; + } + } + else + { // The old way. May be incorrect if bodies are not on the slider axis + btVector3 ltd; // Linear Torque Decoupling vector (a torque) + ltd = c.cross(ax1); + info->m_J1angularAxis[srow+0] = factA*ltd[0]; + info->m_J1angularAxis[srow+1] = factA*ltd[1]; + info->m_J1angularAxis[srow+2] = factA*ltd[2]; + info->m_J2angularAxis[srow+0] = factB*ltd[0]; + info->m_J2angularAxis[srow+1] = factB*ltd[1]; + info->m_J2angularAxis[srow+2] = factB*ltd[2]; + } + // right-hand part + btScalar lostop = getLowerLinLimit(); + btScalar histop = getUpperLinLimit(); + if(limit && (lostop == histop)) + { // the joint motor is ineffective + powered = 0; + } + info->m_constraintError[srow] = 0.; + info->m_lowerLimit[srow] = 0.; + info->m_upperLimit[srow] = 0.; + currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN) ? m_softnessLimLin : info->erp; + if(powered) + { + if(m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN) + { + info->cfm[srow] = m_cfmDirLin; + } + btScalar tag_vel = getTargetLinMotorVelocity(); + btScalar mot_fact = getMotorFactor(m_linPos, m_lowerLinLimit, m_upperLinLimit, tag_vel, info->fps * currERP); + info->m_constraintError[srow] -= signFact * mot_fact * getTargetLinMotorVelocity(); + info->m_lowerLimit[srow] += -getMaxLinMotorForce() * info->fps; + info->m_upperLimit[srow] += getMaxLinMotorForce() * info->fps; + } + if(limit) + { + k = info->fps * currERP; + info->m_constraintError[srow] += k * limit_err; + if(m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN) + { + info->cfm[srow] = m_cfmLimLin; + } + if(lostop == histop) + { // limited low and high simultaneously + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else if(limit == 1) + { // low limit + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = 0; + } + else + { // high limit + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + // bounce (we'll use slider parameter abs(1.0 - m_dampingLimLin) for that) + btScalar bounce = btFabs(btScalar(1.0) - getDampingLimLin()); + if(bounce > btScalar(0.0)) + { + btScalar vel = linVelA.dot(ax1); + vel -= linVelB.dot(ax1); + vel *= signFact; + // only apply bounce if the velocity is incoming, and if the + // resulting c[] exceeds what we already have. + if(limit == 1) + { // low limit + if(vel < 0) + { + btScalar newc = -bounce * vel; + if (newc > info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + else + { // high limit - all those computations are reversed + if(vel > 0) + { + btScalar newc = -bounce * vel; + if(newc < info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + } + info->m_constraintError[srow] *= getSoftnessLimLin(); + } // if(limit) + } // if linear limit + // check angular limits + limit_err = btScalar(0.0); + limit = 0; + if(getSolveAngLimit()) + { + limit_err = getAngDepth(); + limit = (limit_err > btScalar(0.0)) ? 1 : 2; + } + // if the slider has joint limits, add in the extra row + powered = 0; + if(getPoweredAngMotor()) + { + powered = 1; + } + if(limit || powered) + { + nrow++; + srow = nrow * info->rowskip; + info->m_J1angularAxis[srow+0] = ax1[0]; + info->m_J1angularAxis[srow+1] = ax1[1]; + info->m_J1angularAxis[srow+2] = ax1[2]; + + info->m_J2angularAxis[srow+0] = -ax1[0]; + info->m_J2angularAxis[srow+1] = -ax1[1]; + info->m_J2angularAxis[srow+2] = -ax1[2]; + + btScalar lostop = getLowerAngLimit(); + btScalar histop = getUpperAngLimit(); + if(limit && (lostop == histop)) + { // the joint motor is ineffective + powered = 0; + } + currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMANG) ? m_softnessLimAng : info->erp; + if(powered) + { + if(m_flags & BT_SLIDER_FLAGS_CFM_DIRANG) + { + info->cfm[srow] = m_cfmDirAng; + } + btScalar mot_fact = getMotorFactor(m_angPos, m_lowerAngLimit, m_upperAngLimit, getTargetAngMotorVelocity(), info->fps * currERP); + info->m_constraintError[srow] = mot_fact * getTargetAngMotorVelocity(); + info->m_lowerLimit[srow] = -getMaxAngMotorForce() * info->fps; + info->m_upperLimit[srow] = getMaxAngMotorForce() * info->fps; + } + if(limit) + { + k = info->fps * currERP; + info->m_constraintError[srow] += k * limit_err; + if(m_flags & BT_SLIDER_FLAGS_CFM_LIMANG) + { + info->cfm[srow] = m_cfmLimAng; + } + if(lostop == histop) + { + // limited low and high simultaneously + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else if(limit == 1) + { // low limit + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { // high limit + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = 0; + } + // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) + btScalar bounce = btFabs(btScalar(1.0) - getDampingLimAng()); + if(bounce > btScalar(0.0)) + { + btScalar vel = m_rbA.getAngularVelocity().dot(ax1); + vel -= m_rbB.getAngularVelocity().dot(ax1); + // only apply bounce if the velocity is incoming, and if the + // resulting c[] exceeds what we already have. + if(limit == 1) + { // low limit + if(vel < 0) + { + btScalar newc = -bounce * vel; + if(newc > info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + else + { // high limit - all those computations are reversed + if(vel > 0) + { + btScalar newc = -bounce * vel; + if(newc < info->m_constraintError[srow]) + { + info->m_constraintError[srow] = newc; + } + } + } + } + info->m_constraintError[srow] *= getSoftnessLimAng(); + } // if(limit) + } // if angular limit or powered +} + + +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///If no axis is provided, it uses the default axis for this constraint. +void btSliderConstraint::setParam(int num, btScalar value, int axis) +{ + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + if(axis < 1) + { + m_softnessLimLin = value; + m_flags |= BT_SLIDER_FLAGS_ERP_LIMLIN; + } + else if(axis < 3) + { + m_softnessOrthoLin = value; + m_flags |= BT_SLIDER_FLAGS_ERP_ORTLIN; + } + else if(axis == 3) + { + m_softnessLimAng = value; + m_flags |= BT_SLIDER_FLAGS_ERP_LIMANG; + } + else if(axis < 6) + { + m_softnessOrthoAng = value; + m_flags |= BT_SLIDER_FLAGS_ERP_ORTANG; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_CFM : + if(axis < 1) + { + m_cfmDirLin = value; + m_flags |= BT_SLIDER_FLAGS_CFM_DIRLIN; + } + else if(axis == 3) + { + m_cfmDirAng = value; + m_flags |= BT_SLIDER_FLAGS_CFM_DIRANG; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_STOP_CFM : + if(axis < 1) + { + m_cfmLimLin = value; + m_flags |= BT_SLIDER_FLAGS_CFM_LIMLIN; + } + else if(axis < 3) + { + m_cfmOrthoLin = value; + m_flags |= BT_SLIDER_FLAGS_CFM_ORTLIN; + } + else if(axis == 3) + { + m_cfmLimAng = value; + m_flags |= BT_SLIDER_FLAGS_CFM_LIMANG; + } + else if(axis < 6) + { + m_cfmOrthoAng = value; + m_flags |= BT_SLIDER_FLAGS_CFM_ORTANG; + } + else + { + btAssertConstrParams(0); + } + break; + } +} + +///return the local value of parameter +btScalar btSliderConstraint::getParam(int num, int axis) const +{ + btScalar retVal(SIMD_INFINITY); + switch(num) + { + case BT_CONSTRAINT_STOP_ERP : + if(axis < 1) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN); + retVal = m_softnessLimLin; + } + else if(axis < 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTLIN); + retVal = m_softnessOrthoLin; + } + else if(axis == 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMANG); + retVal = m_softnessLimAng; + } + else if(axis < 6) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTANG); + retVal = m_softnessOrthoAng; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_CFM : + if(axis < 1) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN); + retVal = m_cfmDirLin; + } + else if(axis == 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRANG); + retVal = m_cfmDirAng; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_STOP_CFM : + if(axis < 1) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN); + retVal = m_cfmLimLin; + } + else if(axis < 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN); + retVal = m_cfmOrthoLin; + } + else if(axis == 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMANG); + retVal = m_cfmLimAng; + } + else if(axis < 6) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTANG); + retVal = m_cfmOrthoAng; + } + else + { + btAssertConstrParams(0); + } + break; + } + return retVal; +} + + + diff --git a/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h new file mode 100755 index 0000000..ca8e715 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h @@ -0,0 +1,335 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* +Added by Roman Ponomarev (rponom@gmail.com) +April 04, 2008 + +TODO: + - add clamping od accumulated impulse to improve stability + - add conversion for ODE constraint solver +*/ + +#ifndef BT_SLIDER_CONSTRAINT_H +#define BT_SLIDER_CONSTRAINT_H + + + +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + + + +class btRigidBody; + + + +#define SLIDER_CONSTRAINT_DEF_SOFTNESS (btScalar(1.0)) +#define SLIDER_CONSTRAINT_DEF_DAMPING (btScalar(1.0)) +#define SLIDER_CONSTRAINT_DEF_RESTITUTION (btScalar(0.7)) +#define SLIDER_CONSTRAINT_DEF_CFM (btScalar(0.f)) + + +enum btSliderFlags +{ + BT_SLIDER_FLAGS_CFM_DIRLIN = (1 << 0), + BT_SLIDER_FLAGS_ERP_DIRLIN = (1 << 1), + BT_SLIDER_FLAGS_CFM_DIRANG = (1 << 2), + BT_SLIDER_FLAGS_ERP_DIRANG = (1 << 3), + BT_SLIDER_FLAGS_CFM_ORTLIN = (1 << 4), + BT_SLIDER_FLAGS_ERP_ORTLIN = (1 << 5), + BT_SLIDER_FLAGS_CFM_ORTANG = (1 << 6), + BT_SLIDER_FLAGS_ERP_ORTANG = (1 << 7), + BT_SLIDER_FLAGS_CFM_LIMLIN = (1 << 8), + BT_SLIDER_FLAGS_ERP_LIMLIN = (1 << 9), + BT_SLIDER_FLAGS_CFM_LIMANG = (1 << 10), + BT_SLIDER_FLAGS_ERP_LIMANG = (1 << 11) +}; + + +ATTRIBUTE_ALIGNED16(class) btSliderConstraint : public btTypedConstraint +{ +protected: + ///for backwards compatibility during the transition to 'getInfo/getInfo2' + bool m_useSolveConstraintObsolete; + bool m_useOffsetForConstraintFrame; + btTransform m_frameInA; + btTransform m_frameInB; + // use frameA fo define limits, if true + bool m_useLinearReferenceFrameA; + // linear limits + btScalar m_lowerLinLimit; + btScalar m_upperLinLimit; + // angular limits + btScalar m_lowerAngLimit; + btScalar m_upperAngLimit; + // softness, restitution and damping for different cases + // DirLin - moving inside linear limits + // LimLin - hitting linear limit + // DirAng - moving inside angular limits + // LimAng - hitting angular limit + // OrthoLin, OrthoAng - against constraint axis + btScalar m_softnessDirLin; + btScalar m_restitutionDirLin; + btScalar m_dampingDirLin; + btScalar m_cfmDirLin; + + btScalar m_softnessDirAng; + btScalar m_restitutionDirAng; + btScalar m_dampingDirAng; + btScalar m_cfmDirAng; + + btScalar m_softnessLimLin; + btScalar m_restitutionLimLin; + btScalar m_dampingLimLin; + btScalar m_cfmLimLin; + + btScalar m_softnessLimAng; + btScalar m_restitutionLimAng; + btScalar m_dampingLimAng; + btScalar m_cfmLimAng; + + btScalar m_softnessOrthoLin; + btScalar m_restitutionOrthoLin; + btScalar m_dampingOrthoLin; + btScalar m_cfmOrthoLin; + + btScalar m_softnessOrthoAng; + btScalar m_restitutionOrthoAng; + btScalar m_dampingOrthoAng; + btScalar m_cfmOrthoAng; + + // for interlal use + bool m_solveLinLim; + bool m_solveAngLim; + + int m_flags; + + btJacobianEntry m_jacLin[3]; + btScalar m_jacLinDiagABInv[3]; + + btJacobianEntry m_jacAng[3]; + + btScalar m_timeStep; + btTransform m_calculatedTransformA; + btTransform m_calculatedTransformB; + + btVector3 m_sliderAxis; + btVector3 m_realPivotAInW; + btVector3 m_realPivotBInW; + btVector3 m_projPivotInW; + btVector3 m_delta; + btVector3 m_depth; + btVector3 m_relPosA; + btVector3 m_relPosB; + + btScalar m_linPos; + btScalar m_angPos; + + btScalar m_angDepth; + btScalar m_kAngle; + + bool m_poweredLinMotor; + btScalar m_targetLinMotorVelocity; + btScalar m_maxLinMotorForce; + btScalar m_accumulatedLinMotorImpulse; + + bool m_poweredAngMotor; + btScalar m_targetAngMotorVelocity; + btScalar m_maxAngMotorForce; + btScalar m_accumulatedAngMotorImpulse; + + //------------------------ + void initParams(); +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + // constructors + btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA); + + // overrides + + virtual void getInfo1 (btConstraintInfo1* info); + + void getInfo1NonVirtual(btConstraintInfo1* info); + + virtual void getInfo2 (btConstraintInfo2* info); + + void getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB, btScalar rbAinvMass,btScalar rbBinvMass); + + + // access + const btRigidBody& getRigidBodyA() const { return m_rbA; } + const btRigidBody& getRigidBodyB() const { return m_rbB; } + const btTransform & getCalculatedTransformA() const { return m_calculatedTransformA; } + const btTransform & getCalculatedTransformB() const { return m_calculatedTransformB; } + const btTransform & getFrameOffsetA() const { return m_frameInA; } + const btTransform & getFrameOffsetB() const { return m_frameInB; } + btTransform & getFrameOffsetA() { return m_frameInA; } + btTransform & getFrameOffsetB() { return m_frameInB; } + btScalar getLowerLinLimit() { return m_lowerLinLimit; } + void setLowerLinLimit(btScalar lowerLimit) { m_lowerLinLimit = lowerLimit; } + btScalar getUpperLinLimit() { return m_upperLinLimit; } + void setUpperLinLimit(btScalar upperLimit) { m_upperLinLimit = upperLimit; } + btScalar getLowerAngLimit() { return m_lowerAngLimit; } + void setLowerAngLimit(btScalar lowerLimit) { m_lowerAngLimit = btNormalizeAngle(lowerLimit); } + btScalar getUpperAngLimit() { return m_upperAngLimit; } + void setUpperAngLimit(btScalar upperLimit) { m_upperAngLimit = btNormalizeAngle(upperLimit); } + bool getUseLinearReferenceFrameA() { return m_useLinearReferenceFrameA; } + btScalar getSoftnessDirLin() { return m_softnessDirLin; } + btScalar getRestitutionDirLin() { return m_restitutionDirLin; } + btScalar getDampingDirLin() { return m_dampingDirLin ; } + btScalar getSoftnessDirAng() { return m_softnessDirAng; } + btScalar getRestitutionDirAng() { return m_restitutionDirAng; } + btScalar getDampingDirAng() { return m_dampingDirAng; } + btScalar getSoftnessLimLin() { return m_softnessLimLin; } + btScalar getRestitutionLimLin() { return m_restitutionLimLin; } + btScalar getDampingLimLin() { return m_dampingLimLin; } + btScalar getSoftnessLimAng() { return m_softnessLimAng; } + btScalar getRestitutionLimAng() { return m_restitutionLimAng; } + btScalar getDampingLimAng() { return m_dampingLimAng; } + btScalar getSoftnessOrthoLin() { return m_softnessOrthoLin; } + btScalar getRestitutionOrthoLin() { return m_restitutionOrthoLin; } + btScalar getDampingOrthoLin() { return m_dampingOrthoLin; } + btScalar getSoftnessOrthoAng() { return m_softnessOrthoAng; } + btScalar getRestitutionOrthoAng() { return m_restitutionOrthoAng; } + btScalar getDampingOrthoAng() { return m_dampingOrthoAng; } + void setSoftnessDirLin(btScalar softnessDirLin) { m_softnessDirLin = softnessDirLin; } + void setRestitutionDirLin(btScalar restitutionDirLin) { m_restitutionDirLin = restitutionDirLin; } + void setDampingDirLin(btScalar dampingDirLin) { m_dampingDirLin = dampingDirLin; } + void setSoftnessDirAng(btScalar softnessDirAng) { m_softnessDirAng = softnessDirAng; } + void setRestitutionDirAng(btScalar restitutionDirAng) { m_restitutionDirAng = restitutionDirAng; } + void setDampingDirAng(btScalar dampingDirAng) { m_dampingDirAng = dampingDirAng; } + void setSoftnessLimLin(btScalar softnessLimLin) { m_softnessLimLin = softnessLimLin; } + void setRestitutionLimLin(btScalar restitutionLimLin) { m_restitutionLimLin = restitutionLimLin; } + void setDampingLimLin(btScalar dampingLimLin) { m_dampingLimLin = dampingLimLin; } + void setSoftnessLimAng(btScalar softnessLimAng) { m_softnessLimAng = softnessLimAng; } + void setRestitutionLimAng(btScalar restitutionLimAng) { m_restitutionLimAng = restitutionLimAng; } + void setDampingLimAng(btScalar dampingLimAng) { m_dampingLimAng = dampingLimAng; } + void setSoftnessOrthoLin(btScalar softnessOrthoLin) { m_softnessOrthoLin = softnessOrthoLin; } + void setRestitutionOrthoLin(btScalar restitutionOrthoLin) { m_restitutionOrthoLin = restitutionOrthoLin; } + void setDampingOrthoLin(btScalar dampingOrthoLin) { m_dampingOrthoLin = dampingOrthoLin; } + void setSoftnessOrthoAng(btScalar softnessOrthoAng) { m_softnessOrthoAng = softnessOrthoAng; } + void setRestitutionOrthoAng(btScalar restitutionOrthoAng) { m_restitutionOrthoAng = restitutionOrthoAng; } + void setDampingOrthoAng(btScalar dampingOrthoAng) { m_dampingOrthoAng = dampingOrthoAng; } + void setPoweredLinMotor(bool onOff) { m_poweredLinMotor = onOff; } + bool getPoweredLinMotor() { return m_poweredLinMotor; } + void setTargetLinMotorVelocity(btScalar targetLinMotorVelocity) { m_targetLinMotorVelocity = targetLinMotorVelocity; } + btScalar getTargetLinMotorVelocity() { return m_targetLinMotorVelocity; } + void setMaxLinMotorForce(btScalar maxLinMotorForce) { m_maxLinMotorForce = maxLinMotorForce; } + btScalar getMaxLinMotorForce() { return m_maxLinMotorForce; } + void setPoweredAngMotor(bool onOff) { m_poweredAngMotor = onOff; } + bool getPoweredAngMotor() { return m_poweredAngMotor; } + void setTargetAngMotorVelocity(btScalar targetAngMotorVelocity) { m_targetAngMotorVelocity = targetAngMotorVelocity; } + btScalar getTargetAngMotorVelocity() { return m_targetAngMotorVelocity; } + void setMaxAngMotorForce(btScalar maxAngMotorForce) { m_maxAngMotorForce = maxAngMotorForce; } + btScalar getMaxAngMotorForce() { return m_maxAngMotorForce; } + + btScalar getLinearPos() const { return m_linPos; } + btScalar getAngularPos() const { return m_angPos; } + + + + // access for ODE solver + bool getSolveLinLimit() { return m_solveLinLim; } + btScalar getLinDepth() { return m_depth[0]; } + bool getSolveAngLimit() { return m_solveAngLim; } + btScalar getAngDepth() { return m_angDepth; } + // shared code used by ODE solver + void calculateTransforms(const btTransform& transA,const btTransform& transB); + void testLinLimits(); + void testAngLimits(); + // access for PE Solver + btVector3 getAncorInA(); + btVector3 getAncorInB(); + // access for UseFrameOffset + bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; } + void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; } + + void setFrames(const btTransform& frameA, const btTransform& frameB) + { + m_frameInA=frameA; + m_frameInB=frameB; + calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + buildJacobian(); + } + + + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///If no axis is provided, it uses the default axis for this constraint. + virtual void setParam(int num, btScalar value, int axis = -1); + ///return the local value of parameter + virtual btScalar getParam(int num, int axis = -1) const; + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btSliderConstraintData +{ + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTransformFloatData m_rbBFrame; + + float m_linearUpperLimit; + float m_linearLowerLimit; + + float m_angularUpperLimit; + float m_angularLowerLimit; + + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; + +}; + + +SIMD_FORCE_INLINE int btSliderConstraint::calculateSerializeBufferSize() const +{ + return sizeof(btSliderConstraintData); +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btSliderConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +{ + + btSliderConstraintData* sliderData = (btSliderConstraintData*) dataBuffer; + btTypedConstraint::serialize(&sliderData->m_typeConstraintData,serializer); + + m_frameInA.serializeFloat(sliderData->m_rbAFrame); + m_frameInB.serializeFloat(sliderData->m_rbBFrame); + + sliderData->m_linearUpperLimit = float(m_upperLinLimit); + sliderData->m_linearLowerLimit = float(m_lowerLinLimit); + + sliderData->m_angularUpperLimit = float(m_upperAngLimit); + sliderData->m_angularLowerLimit = float(m_lowerAngLimit); + + sliderData->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA; + sliderData->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame; + + return "btSliderConstraintData"; +} + + + +#endif //BT_SLIDER_CONSTRAINT_H + diff --git a/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp new file mode 100644 index 0000000..0c7dbd6 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp @@ -0,0 +1,255 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btSolve2LinearConstraint.h" + +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" + + +void btSolve2LinearConstraint::resolveUnilateralPairConstraint( + btRigidBody* body1, + btRigidBody* body2, + + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1) +{ + (void)linvelA; + (void)linvelB; + (void)angvelB; + (void)angvelA; + + + + imp0 = btScalar(0.); + imp1 = btScalar(0.); + + btScalar len = btFabs(normalA.length()) - btScalar(1.); + if (btFabs(len) >= SIMD_EPSILON) + return; + + btAssert(len < SIMD_EPSILON); + + + //this jacobian entry could be re-used for all iterations + btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + + //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + + const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); + const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + +// btScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv + btScalar massTerm = btScalar(1.) / (invMassA + invMassB); + + + // calculate rhs (or error) terms + const btScalar dv0 = depthA * m_tau * massTerm - vel0 * m_damping; + const btScalar dv1 = depthB * m_tau * massTerm - vel1 * m_damping; + + + // dC/dv * dv = -C + + // jacobian * impulse = -error + // + + //impulse = jacobianInverse * -error + + // inverting 2x2 symmetric system (offdiagonal are equal!) + // + + + btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); + btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); + + //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + //[a b] [d -c] + //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) + + //[jA nD] * [imp0] = [dv0] + //[nD jB] [imp1] [dv1] + +} + + + +void btSolve2LinearConstraint::resolveBilateralPairConstraint( + btRigidBody* body1, + btRigidBody* body2, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1) +{ + + (void)linvelA; + (void)linvelB; + (void)angvelA; + (void)angvelB; + + + + imp0 = btScalar(0.); + imp1 = btScalar(0.); + + btScalar len = btFabs(normalA.length()) - btScalar(1.); + if (btFabs(len) >= SIMD_EPSILON) + return; + + btAssert(len < SIMD_EPSILON); + + + //this jacobian entry could be re-used for all iterations + btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + + //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + + const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); + const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + + // calculate rhs (or error) terms + const btScalar dv0 = depthA * m_tau - vel0 * m_damping; + const btScalar dv1 = depthB * m_tau - vel1 * m_damping; + + // dC/dv * dv = -C + + // jacobian * impulse = -error + // + + //impulse = jacobianInverse * -error + + // inverting 2x2 symmetric system (offdiagonal are equal!) + // + + + btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); + btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); + + //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + //[a b] [d -c] + //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) + + //[jA nD] * [imp0] = [dv0] + //[nD jB] [imp1] [dv1] + + if ( imp0 > btScalar(0.0)) + { + if ( imp1 > btScalar(0.0) ) + { + //both positive + } + else + { + imp1 = btScalar(0.); + + // now imp0>0 imp1<0 + imp0 = dv0 / jacA.getDiagonal(); + if ( imp0 > btScalar(0.0) ) + { + } else + { + imp0 = btScalar(0.); + } + } + } + else + { + imp0 = btScalar(0.); + + imp1 = dv1 / jacB.getDiagonal(); + if ( imp1 <= btScalar(0.0) ) + { + imp1 = btScalar(0.); + // now imp0>0 imp1<0 + imp0 = dv0 / jacA.getDiagonal(); + if ( imp0 > btScalar(0.0) ) + { + } else + { + imp0 = btScalar(0.); + } + } else + { + } + } +} + + +/* +void btSolve2LinearConstraint::resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btMatrix3x3& invInertiaBWS, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1) +{ + +} +*/ + diff --git a/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h new file mode 100644 index 0000000..e8bfabf --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h @@ -0,0 +1,107 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOLVE_2LINEAR_CONSTRAINT_H +#define BT_SOLVE_2LINEAR_CONSTRAINT_H + +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btVector3.h" + + +class btRigidBody; + + + +/// constraint class used for lateral tyre friction. +class btSolve2LinearConstraint +{ + btScalar m_tau; + btScalar m_damping; + +public: + + btSolve2LinearConstraint(btScalar tau,btScalar damping) + { + m_tau = tau; + m_damping = damping; + } + // + // solve unilateral constraint (equality, direct method) + // + void resolveUnilateralPairConstraint( + btRigidBody* body0, + btRigidBody* body1, + + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1); + + + // + // solving 2x2 lcp problem (inequality, direct solution ) + // + void resolveBilateralPairConstraint( + btRigidBody* body0, + btRigidBody* body1, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1); + +/* + void resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btMatrix3x3& invInertiaBWS, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1); + +*/ + +}; + +#endif //BT_SOLVE_2LINEAR_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/src/BulletDynamics/ConstraintSolver/btSolverBody.h new file mode 100644 index 0000000..4e1a8df --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSolverBody.h @@ -0,0 +1,293 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOLVER_BODY_H +#define BT_SOLVER_BODY_H + +class btRigidBody; +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" + +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btTransformUtil.h" + +///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision +#ifdef BT_USE_SSE +#define USE_SIMD 1 +#endif // + + +#ifdef USE_SIMD + +struct btSimdScalar +{ + SIMD_FORCE_INLINE btSimdScalar() + { + + } + + SIMD_FORCE_INLINE btSimdScalar(float fl) + :m_vec128 (_mm_set1_ps(fl)) + { + } + + SIMD_FORCE_INLINE btSimdScalar(__m128 v128) + :m_vec128(v128) + { + } + union + { + __m128 m_vec128; + float m_floats[4]; + int m_ints[4]; + btScalar m_unusedPadding; + }; + SIMD_FORCE_INLINE __m128 get128() + { + return m_vec128; + } + + SIMD_FORCE_INLINE const __m128 get128() const + { + return m_vec128; + } + + SIMD_FORCE_INLINE void set128(__m128 v128) + { + m_vec128 = v128; + } + + SIMD_FORCE_INLINE operator __m128() + { + return m_vec128; + } + SIMD_FORCE_INLINE operator const __m128() const + { + return m_vec128; + } + + SIMD_FORCE_INLINE operator float() const + { + return m_floats[0]; + } + +}; + +///@brief Return the elementwise product of two btSimdScalar +SIMD_FORCE_INLINE btSimdScalar +operator*(const btSimdScalar& v1, const btSimdScalar& v2) +{ + return btSimdScalar(_mm_mul_ps(v1.get128(),v2.get128())); +} + +///@brief Return the elementwise product of two btSimdScalar +SIMD_FORCE_INLINE btSimdScalar +operator+(const btSimdScalar& v1, const btSimdScalar& v2) +{ + return btSimdScalar(_mm_add_ps(v1.get128(),v2.get128())); +} + + +#else +#define btSimdScalar btScalar +#endif + +///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. +ATTRIBUTE_ALIGNED64 (struct) btSolverBody +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + btTransform m_worldTransform; + btVector3 m_deltaLinearVelocity; + btVector3 m_deltaAngularVelocity; + btVector3 m_angularFactor; + btVector3 m_linearFactor; + btVector3 m_invMass; + btVector3 m_pushVelocity; + btVector3 m_turnVelocity; + btVector3 m_linearVelocity; + btVector3 m_angularVelocity; + + btRigidBody* m_originalBody; + void setWorldTransform(const btTransform& worldTransform) + { + m_worldTransform = worldTransform; + } + + const btTransform& getWorldTransform() const + { + return m_worldTransform; + } + + SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const + { + if (m_originalBody) + velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + else + velocity.setValue(0,0,0); + } + + SIMD_FORCE_INLINE void getAngularVelocity(btVector3& angVel) const + { + if (m_originalBody) + angVel =m_angularVelocity+m_deltaAngularVelocity; + else + angVel.setValue(0,0,0); + } + + + //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position + SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude) + { + if (m_originalBody) + { + m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; + m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + } + } + + SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) + { + if (m_originalBody) + { + m_pushVelocity += linearComponent*impulseMagnitude*m_linearFactor; + m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + } + } + + + + const btVector3& getDeltaLinearVelocity() const + { + return m_deltaLinearVelocity; + } + + const btVector3& getDeltaAngularVelocity() const + { + return m_deltaAngularVelocity; + } + + const btVector3& getPushVelocity() const + { + return m_pushVelocity; + } + + const btVector3& getTurnVelocity() const + { + return m_turnVelocity; + } + + + //////////////////////////////////////////////// + ///some internal methods, don't use them + + btVector3& internalGetDeltaLinearVelocity() + { + return m_deltaLinearVelocity; + } + + btVector3& internalGetDeltaAngularVelocity() + { + return m_deltaAngularVelocity; + } + + const btVector3& internalGetAngularFactor() const + { + return m_angularFactor; + } + + const btVector3& internalGetInvMass() const + { + return m_invMass; + } + + void internalSetInvMass(const btVector3& invMass) + { + m_invMass = invMass; + } + + btVector3& internalGetPushVelocity() + { + return m_pushVelocity; + } + + btVector3& internalGetTurnVelocity() + { + return m_turnVelocity; + } + + SIMD_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const + { + velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + } + + SIMD_FORCE_INLINE void internalGetAngularVelocity(btVector3& angVel) const + { + angVel = m_angularVelocity+m_deltaAngularVelocity; + } + + + //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position + SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude) + { + if (m_originalBody) + { + m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; + m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + } + } + + + + + void writebackVelocity() + { + if (m_originalBody) + { + m_linearVelocity +=m_deltaLinearVelocity; + m_angularVelocity += m_deltaAngularVelocity; + + //m_originalBody->setCompanionId(-1); + } + } + + + void writebackVelocityAndTransform(btScalar timeStep, btScalar splitImpulseTurnErp) + { + (void) timeStep; + if (m_originalBody) + { + m_linearVelocity += m_deltaLinearVelocity; + m_angularVelocity += m_deltaAngularVelocity; + + //correct the position/orientation based on push/turn recovery + btTransform newTransform; + if (m_pushVelocity[0]!=0.f || m_pushVelocity[1]!=0 || m_pushVelocity[2]!=0 || m_turnVelocity[0]!=0.f || m_turnVelocity[1]!=0 || m_turnVelocity[2]!=0) + { + // btQuaternion orn = m_worldTransform.getRotation(); + btTransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform); + m_worldTransform = newTransform; + } + //m_worldTransform.setRotation(orn); + //m_originalBody->setCompanionId(-1); + } + } + + + +}; + +#endif //BT_SOLVER_BODY_H + + diff --git a/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h new file mode 100644 index 0000000..c3951f6 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h @@ -0,0 +1,79 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOLVER_CONSTRAINT_H +#define BT_SOLVER_CONSTRAINT_H + +class btRigidBody; +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" +#include "btJacobianEntry.h" +#include "LinearMath/btAlignedObjectArray.h" + +//#define NO_FRICTION_TANGENTIALS 1 +#include "btSolverBody.h" + + +///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. +ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btVector3 m_relpos1CrossNormal; + btVector3 m_contactNormal; + + btVector3 m_relpos2CrossNormal; + //btVector3 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal + + btVector3 m_angularComponentA; + btVector3 m_angularComponentB; + + mutable btSimdScalar m_appliedPushImpulse; + mutable btSimdScalar m_appliedImpulse; + + btScalar m_friction; + btScalar m_jacDiagABInv; + btScalar m_rhs; + btScalar m_cfm; + + btScalar m_lowerLimit; + btScalar m_upperLimit; + btScalar m_rhsPenetration; + union + { + void* m_originalContactPoint; + btScalar m_unusedPadding4; + }; + + int m_overrideNumSolverIterations; + int m_frictionIndex; + int m_solverBodyIdA; + int m_solverBodyIdB; + + + enum btSolverConstraintType + { + BT_SOLVER_CONTACT_1D = 0, + BT_SOLVER_FRICTION_1D + }; +}; + +typedef btAlignedObjectArray btConstraintArray; + + +#endif //BT_SOLVER_CONSTRAINT_H + + + diff --git a/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp new file mode 100644 index 0000000..465c074 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp @@ -0,0 +1,222 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btTypedConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btSerializer.h" + + +#define DEFAULT_DEBUGDRAW_SIZE btScalar(0.3f) + +btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA) +:btTypedObject(type), +m_userConstraintType(-1), +m_userConstraintId(-1), +m_breakingImpulseThreshold(SIMD_INFINITY), +m_isEnabled(true), +m_needsFeedback(false), +m_overrideNumSolverIterations(-1), +m_rbA(rbA), +m_rbB(getFixedBody()), +m_appliedImpulse(btScalar(0.)), +m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE), +m_jointFeedback(0) +{ +} + + +btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB) +:btTypedObject(type), +m_userConstraintType(-1), +m_userConstraintId(-1), +m_breakingImpulseThreshold(SIMD_INFINITY), +m_isEnabled(true), +m_needsFeedback(false), +m_overrideNumSolverIterations(-1), +m_rbA(rbA), +m_rbB(rbB), +m_appliedImpulse(btScalar(0.)), +m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE), +m_jointFeedback(0) +{ +} + + + + +btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact) +{ + if(lowLim > uppLim) + { + return btScalar(1.0f); + } + else if(lowLim == uppLim) + { + return btScalar(0.0f); + } + btScalar lim_fact = btScalar(1.0f); + btScalar delta_max = vel / timeFact; + if(delta_max < btScalar(0.0f)) + { + if((pos >= lowLim) && (pos < (lowLim - delta_max))) + { + lim_fact = (lowLim - pos) / delta_max; + } + else if(pos < lowLim) + { + lim_fact = btScalar(0.0f); + } + else + { + lim_fact = btScalar(1.0f); + } + } + else if(delta_max > btScalar(0.0f)) + { + if((pos <= uppLim) && (pos > (uppLim - delta_max))) + { + lim_fact = (uppLim - pos) / delta_max; + } + else if(pos > uppLim) + { + lim_fact = btScalar(0.0f); + } + else + { + lim_fact = btScalar(1.0f); + } + } + else + { + lim_fact = btScalar(0.0f); + } + return lim_fact; +} + +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +{ + btTypedConstraintData* tcd = (btTypedConstraintData*) dataBuffer; + + tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA); + tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB); + char* name = (char*) serializer->findNameForPointer(this); + tcd->m_name = (char*)serializer->getUniquePointer(name); + if (tcd->m_name) + { + serializer->serializeName(name); + } + + tcd->m_objectType = m_objectType; + tcd->m_needsFeedback = m_needsFeedback; + tcd->m_overrideNumSolverIterations = m_overrideNumSolverIterations; + tcd->m_breakingImpulseThreshold = float(m_breakingImpulseThreshold); + tcd->m_isEnabled = m_isEnabled? 1: 0; + + tcd->m_userConstraintId =m_userConstraintId; + tcd->m_userConstraintType =m_userConstraintType; + + tcd->m_appliedImpulse = float(m_appliedImpulse); + tcd->m_dbgDrawSize = float(m_dbgDrawSize ); + + tcd->m_disableCollisionsBetweenLinkedBodies = false; + + int i; + for (i=0;im_disableCollisionsBetweenLinkedBodies = true; + for (i=0;im_disableCollisionsBetweenLinkedBodies = true; + + return "btTypedConstraintData"; +} + +btRigidBody& btTypedConstraint::getFixedBody() +{ + static btRigidBody s_fixed(0, 0,0); + s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + return s_fixed; +} + + +void btAngularLimit::set(btScalar low, btScalar high, btScalar _softness, btScalar _biasFactor, btScalar _relaxationFactor) +{ + m_halfRange = (high - low) / 2.0f; + m_center = btNormalizeAngle(low + m_halfRange); + m_softness = _softness; + m_biasFactor = _biasFactor; + m_relaxationFactor = _relaxationFactor; +} + +void btAngularLimit::test(const btScalar angle) +{ + m_correction = 0.0f; + m_sign = 0.0f; + m_solveLimit = false; + + if (m_halfRange >= 0.0f) + { + btScalar deviation = btNormalizeAngle(angle - m_center); + if (deviation < -m_halfRange) + { + m_solveLimit = true; + m_correction = - (deviation + m_halfRange); + m_sign = +1.0f; + } + else if (deviation > m_halfRange) + { + m_solveLimit = true; + m_correction = m_halfRange - deviation; + m_sign = -1.0f; + } + } +} + + +btScalar btAngularLimit::getError() const +{ + return m_correction * m_sign; +} + +void btAngularLimit::fit(btScalar& angle) const +{ + if (m_halfRange > 0.0f) + { + btScalar relativeAngle = btNormalizeAngle(angle - m_center); + if (!btEqual(relativeAngle, m_halfRange)) + { + if (relativeAngle > 0.0f) + { + angle = getHigh(); + } + else + { + angle = getLow(); + } + } + } +} + +btScalar btAngularLimit::getLow() const +{ + return btNormalizeAngle(m_center - m_halfRange); +} + +btScalar btAngularLimit::getHigh() const +{ + return btNormalizeAngle(m_center + m_halfRange); +} diff --git a/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h new file mode 100644 index 0000000..441fa37 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h @@ -0,0 +1,482 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_TYPED_CONSTRAINT_H +#define BT_TYPED_CONSTRAINT_H + + +#include "LinearMath/btScalar.h" +#include "btSolverConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + +class btSerializer; + +//Don't change any of the existing enum values, so add enum types at the end for serialization compatibility +enum btTypedConstraintType +{ + POINT2POINT_CONSTRAINT_TYPE=3, + HINGE_CONSTRAINT_TYPE, + CONETWIST_CONSTRAINT_TYPE, + D6_CONSTRAINT_TYPE, + SLIDER_CONSTRAINT_TYPE, + CONTACT_CONSTRAINT_TYPE, + D6_SPRING_CONSTRAINT_TYPE, + GEAR_CONSTRAINT_TYPE, + MAX_CONSTRAINT_TYPE +}; + + +enum btConstraintParams +{ + BT_CONSTRAINT_ERP=1, + BT_CONSTRAINT_STOP_ERP, + BT_CONSTRAINT_CFM, + BT_CONSTRAINT_STOP_CFM +}; + +#if 1 + #define btAssertConstrParams(_par) btAssert(_par) +#else + #define btAssertConstrParams(_par) +#endif + + +ATTRIBUTE_ALIGNED16(struct) btJointFeedback +{ + btVector3 m_appliedForceBodyA; + btVector3 m_appliedTorqueBodyA; + btVector3 m_appliedForceBodyB; + btVector3 m_appliedTorqueBodyB; +}; + + +///TypedConstraint is the baseclass for Bullet constraints and vehicles +ATTRIBUTE_ALIGNED16(class) btTypedConstraint : public btTypedObject +{ + int m_userConstraintType; + + union + { + int m_userConstraintId; + void* m_userConstraintPtr; + }; + + btScalar m_breakingImpulseThreshold; + bool m_isEnabled; + bool m_needsFeedback; + int m_overrideNumSolverIterations; + + + btTypedConstraint& operator=(btTypedConstraint& other) + { + btAssert(0); + (void) other; + return *this; + } + +protected: + btRigidBody& m_rbA; + btRigidBody& m_rbB; + btScalar m_appliedImpulse; + btScalar m_dbgDrawSize; + btJointFeedback* m_jointFeedback; + + ///internal method used by the constraint solver, don't use them directly + btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact); + + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + virtual ~btTypedConstraint() {}; + btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA); + btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB); + + struct btConstraintInfo1 { + int m_numConstraintRows,nub; + }; + + static btRigidBody& getFixedBody(); + + struct btConstraintInfo2 { + // integrator parameters: frames per second (1/stepsize), default error + // reduction parameter (0..1). + btScalar fps,erp; + + // for the first and second body, pointers to two (linear and angular) + // n*3 jacobian sub matrices, stored by rows. these matrices will have + // been initialized to 0 on entry. if the second body is zero then the + // J2xx pointers may be 0. + btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis; + + // elements to jump from one row to the next in J's + int rowskip; + + // right hand sides of the equation J*v = c + cfm * lambda. cfm is the + // "constraint force mixing" vector. c is set to zero on entry, cfm is + // set to a constant value (typically very small or zero) value on entry. + btScalar *m_constraintError,*cfm; + + // lo and hi limits for variables (set to -/+ infinity on entry). + btScalar *m_lowerLimit,*m_upperLimit; + + // findex vector for variables. see the LCP solver interface for a + // description of what this does. this is set to -1 on entry. + // note that the returned indexes are relative to the first index of + // the constraint. + int *findex; + // number of solver iterations + int m_numIterations; + + //damping of the velocity + btScalar m_damping; + }; + + int getOverrideNumSolverIterations() const + { + return m_overrideNumSolverIterations; + } + + ///override the number of constraint solver iterations used to solve this constraint + ///-1 will use the default number of iterations, as specified in SolverInfo.m_numIterations + void setOverrideNumSolverIterations(int overideNumIterations) + { + m_overrideNumSolverIterations = overideNumIterations; + } + + ///internal method used by the constraint solver, don't use them directly + virtual void buildJacobian() {}; + + ///internal method used by the constraint solver, don't use them directly + virtual void setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep) + { + (void)ca; + (void)solverBodyA; + (void)solverBodyB; + (void)timeStep; + } + + ///internal method used by the constraint solver, don't use them directly + virtual void getInfo1 (btConstraintInfo1* info)=0; + + ///internal method used by the constraint solver, don't use them directly + virtual void getInfo2 (btConstraintInfo2* info)=0; + + ///internal method used by the constraint solver, don't use them directly + void internalSetAppliedImpulse(btScalar appliedImpulse) + { + m_appliedImpulse = appliedImpulse; + } + ///internal method used by the constraint solver, don't use them directly + btScalar internalGetAppliedImpulse() + { + return m_appliedImpulse; + } + + + btScalar getBreakingImpulseThreshold() const + { + return m_breakingImpulseThreshold; + } + + void setBreakingImpulseThreshold(btScalar threshold) + { + m_breakingImpulseThreshold = threshold; + } + + bool isEnabled() const + { + return m_isEnabled; + } + + void setEnabled(bool enabled) + { + m_isEnabled=enabled; + } + + + ///internal method used by the constraint solver, don't use them directly + virtual void solveConstraintObsolete(btSolverBody& /*bodyA*/,btSolverBody& /*bodyB*/,btScalar /*timeStep*/) {}; + + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } + + btRigidBody& getRigidBodyA() + { + return m_rbA; + } + btRigidBody& getRigidBodyB() + { + return m_rbB; + } + + int getUserConstraintType() const + { + return m_userConstraintType ; + } + + void setUserConstraintType(int userConstraintType) + { + m_userConstraintType = userConstraintType; + }; + + void setUserConstraintId(int uid) + { + m_userConstraintId = uid; + } + + int getUserConstraintId() const + { + return m_userConstraintId; + } + + void setUserConstraintPtr(void* ptr) + { + m_userConstraintPtr = ptr; + } + + void* getUserConstraintPtr() + { + return m_userConstraintPtr; + } + + void setJointFeedback(btJointFeedback* jointFeedback) + { + m_jointFeedback = jointFeedback; + } + + const btJointFeedback* getJointFeedback() const + { + return m_jointFeedback; + } + + btJointFeedback* getJointFeedback() + { + return m_jointFeedback; + } + + + int getUid() const + { + return m_userConstraintId; + } + + bool needsFeedback() const + { + return m_needsFeedback; + } + + ///enableFeedback will allow to read the applied linear and angular impulse + ///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information + void enableFeedback(bool needsFeedback) + { + m_needsFeedback = needsFeedback; + } + + ///getAppliedImpulse is an estimated total applied impulse. + ///This feedback could be used to determine breaking constraints or playing sounds. + btScalar getAppliedImpulse() const + { + btAssert(m_needsFeedback); + return m_appliedImpulse; + } + + btTypedConstraintType getConstraintType () const + { + return btTypedConstraintType(m_objectType); + } + + void setDbgDrawSize(btScalar dbgDrawSize) + { + m_dbgDrawSize = dbgDrawSize; + } + btScalar getDbgDrawSize() + { + return m_dbgDrawSize; + } + + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///If no axis is provided, it uses the default axis for this constraint. + virtual void setParam(int num, btScalar value, int axis = -1) = 0; + + ///return the local value of parameter + virtual btScalar getParam(int num, int axis = -1) const = 0; + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + +}; + +// returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits +// all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI]) +SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians) +{ + if(angleLowerLimitInRadians >= angleUpperLimitInRadians) + { + return angleInRadians; + } + else if(angleInRadians < angleLowerLimitInRadians) + { + btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians)); + btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians)); + return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI); + } + else if(angleInRadians > angleUpperLimitInRadians) + { + btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians)); + btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians)); + return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians; + } + else + { + return angleInRadians; + } +} + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btTypedConstraintData +{ + btRigidBodyData *m_rbA; + btRigidBodyData *m_rbB; + char *m_name; + + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + + float m_appliedImpulse; + float m_dbgDrawSize; + + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + + float m_breakingImpulseThreshold; + int m_isEnabled; + +}; + +SIMD_FORCE_INLINE int btTypedConstraint::calculateSerializeBufferSize() const +{ + return sizeof(btTypedConstraintData); +} + + + +class btAngularLimit +{ +private: + btScalar + m_center, + m_halfRange, + m_softness, + m_biasFactor, + m_relaxationFactor, + m_correction, + m_sign; + + bool + m_solveLimit; + +public: + /// Default constructor initializes limit as inactive, allowing free constraint movement + btAngularLimit() + :m_center(0.0f), + m_halfRange(-1.0f), + m_softness(0.9f), + m_biasFactor(0.3f), + m_relaxationFactor(1.0f), + m_correction(0.0f), + m_sign(0.0f), + m_solveLimit(false) + {} + + /// Sets all limit's parameters. + /// When low > high limit becomes inactive. + /// When high - low > 2PI limit is ineffective too becouse no angle can exceed the limit + void set(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f); + + /// Checks conastaint angle against limit. If limit is active and the angle violates the limit + /// correction is calculated. + void test(const btScalar angle); + + /// Returns limit's softness + inline btScalar getSoftness() const + { + return m_softness; + } + + /// Returns limit's bias factor + inline btScalar getBiasFactor() const + { + return m_biasFactor; + } + + /// Returns limit's relaxation factor + inline btScalar getRelaxationFactor() const + { + return m_relaxationFactor; + } + + /// Returns correction value evaluated when test() was invoked + inline btScalar getCorrection() const + { + return m_correction; + } + + /// Returns sign value evaluated when test() was invoked + inline btScalar getSign() const + { + return m_sign; + } + + /// Gives half of the distance between min and max limit angle + inline btScalar getHalfRange() const + { + return m_halfRange; + } + + /// Returns true when the last test() invocation recognized limit violation + inline bool isLimit() const + { + return m_solveLimit; + } + + /// Checks given angle against limit. If limit is active and angle doesn't fit it, the angle + /// returned is modified so it equals to the limit closest to given angle. + void fit(btScalar& angle) const; + + /// Returns correction value multiplied by sign value + btScalar getError() const; + + btScalar getLow() const; + + btScalar getHigh() const; + +}; + + + +#endif //BT_TYPED_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp new file mode 100644 index 0000000..b009f41 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp @@ -0,0 +1,87 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btUniversalConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" + + + +#define UNIV_EPS btScalar(0.01f) + + +// constructor +// anchor, axis1 and axis2 are in world coordinate system +// axis1 must be orthogonal to axis2 +btUniversalConstraint::btUniversalConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& anchor, const btVector3& axis1, const btVector3& axis2) +: btGeneric6DofConstraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(), true), + m_anchor(anchor), + m_axis1(axis1), + m_axis2(axis2) +{ + // build frame basis + // 6DOF constraint uses Euler angles and to define limits + // it is assumed that rotational order is : + // Z - first, allowed limits are (-PI,PI); + // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number + // used to prevent constraint from instability on poles; + // new position of X, allowed limits are (-PI,PI); + // So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs + // Build the frame in world coordinate system first + btVector3 zAxis = m_axis1.normalize(); + btVector3 yAxis = m_axis2.normalize(); + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + btTransform frameInW; + frameInW.setIdentity(); + frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + frameInW.setOrigin(anchor); + // now get constraint frame in local coordinate systems + m_frameInA = rbA.getCenterOfMassTransform().inverse() * frameInW; + m_frameInB = rbB.getCenterOfMassTransform().inverse() * frameInW; + // sei limits + setLinearLowerLimit(btVector3(0., 0., 0.)); + setLinearUpperLimit(btVector3(0., 0., 0.)); + setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI + UNIV_EPS, -SIMD_PI + UNIV_EPS)); + setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI - UNIV_EPS, SIMD_PI - UNIV_EPS)); +} + +void btUniversalConstraint::setAxis(const btVector3& axis1,const btVector3& axis2) +{ + m_axis1 = axis1; + m_axis2 = axis2; + + btVector3 zAxis = axis1.normalized(); + btVector3 yAxis = axis2.normalized(); + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + + btTransform frameInW; + frameInW.setIdentity(); + frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + frameInW.setOrigin(m_anchor); + + // now get constraint frame in local coordinate systems + m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW; + m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW; + + calculateTransforms(); +} + + diff --git a/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h new file mode 100644 index 0000000..9e70841 --- /dev/null +++ b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h @@ -0,0 +1,65 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_UNIVERSAL_CONSTRAINT_H +#define BT_UNIVERSAL_CONSTRAINT_H + + + +#include "LinearMath/btVector3.h" +#include "btTypedConstraint.h" +#include "btGeneric6DofConstraint.h" + + + +/// Constraint similar to ODE Universal Joint +/// has 2 rotatioonal degrees of freedom, similar to Euler rotations around Z (axis 1) +/// and Y (axis 2) +/// Description from ODE manual : +/// "Given axis 1 on body 1, and axis 2 on body 2 that is perpendicular to axis 1, it keeps them perpendicular. +/// In other words, rotation of the two bodies about the direction perpendicular to the two axes will be equal." + +ATTRIBUTE_ALIGNED16(class) btUniversalConstraint : public btGeneric6DofConstraint +{ +protected: + btVector3 m_anchor; + btVector3 m_axis1; + btVector3 m_axis2; +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + // constructor + // anchor, axis1 and axis2 are in world coordinate system + // axis1 must be orthogonal to axis2 + btUniversalConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& anchor, const btVector3& axis1, const btVector3& axis2); + // access + const btVector3& getAnchor() { return m_calculatedTransformA.getOrigin(); } + const btVector3& getAnchor2() { return m_calculatedTransformB.getOrigin(); } + const btVector3& getAxis1() { return m_axis1; } + const btVector3& getAxis2() { return m_axis2; } + btScalar getAngle1() { return getAngle(2); } + btScalar getAngle2() { return getAngle(1); } + // limits + void setUpperLimit(btScalar ang1max, btScalar ang2max) { setAngularUpperLimit(btVector3(0.f, ang1max, ang2max)); } + void setLowerLimit(btScalar ang1min, btScalar ang2min) { setAngularLowerLimit(btVector3(0.f, ang1min, ang2min)); } + + void setAxis( const btVector3& axis1, const btVector3& axis2); +}; + + + +#endif // BT_UNIVERSAL_CONSTRAINT_H + diff --git a/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/src/BulletDynamics/Dynamics/Bullet-C-API.cpp new file mode 100644 index 0000000..bd8e274 --- /dev/null +++ b/src/BulletDynamics/Dynamics/Bullet-C-API.cpp @@ -0,0 +1,405 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including +*/ + +#include "Bullet-C-Api.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btAlignedAllocator.h" + + + +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" + + +/* + Create and Delete a Physics SDK +*/ + +struct btPhysicsSdk +{ + +// btDispatcher* m_dispatcher; +// btOverlappingPairCache* m_pairCache; +// btConstraintSolver* m_constraintSolver + + btVector3 m_worldAabbMin; + btVector3 m_worldAabbMax; + + + //todo: version, hardware/optimization settings etc? + btPhysicsSdk() + :m_worldAabbMin(-1000,-1000,-1000), + m_worldAabbMax(1000,1000,1000) + { + + } + + +}; + +plPhysicsSdkHandle plNewBulletSdk() +{ + void* mem = btAlignedAlloc(sizeof(btPhysicsSdk),16); + return (plPhysicsSdkHandle)new (mem)btPhysicsSdk; +} + +void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk) +{ + btPhysicsSdk* phys = reinterpret_cast(physicsSdk); + btAlignedFree(phys); +} + + +/* Dynamics World */ +plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle) +{ + btPhysicsSdk* physicsSdk = reinterpret_cast(physicsSdkHandle); + void* mem = btAlignedAlloc(sizeof(btDefaultCollisionConfiguration),16); + btDefaultCollisionConfiguration* collisionConfiguration = new (mem)btDefaultCollisionConfiguration(); + mem = btAlignedAlloc(sizeof(btCollisionDispatcher),16); + btDispatcher* dispatcher = new (mem)btCollisionDispatcher(collisionConfiguration); + mem = btAlignedAlloc(sizeof(btAxisSweep3),16); + btBroadphaseInterface* pairCache = new (mem)btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax); + mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); + btConstraintSolver* constraintSolver = new(mem) btSequentialImpulseConstraintSolver(); + + mem = btAlignedAlloc(sizeof(btDiscreteDynamicsWorld),16); + return (plDynamicsWorldHandle) new (mem)btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration); +} +void plDeleteDynamicsWorld(plDynamicsWorldHandle world) +{ + //todo: also clean up the other allocations, axisSweep, pairCache,dispatcher,constraintSolver,collisionConfiguration + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAlignedFree(dynamicsWorld); +} + +void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAssert(dynamicsWorld); + dynamicsWorld->stepSimulation(timeStep); +} + +void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAssert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + + dynamicsWorld->addRigidBody(body); +} + +void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAssert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + + dynamicsWorld->removeRigidBody(body); +} + +/* Rigid Body */ + +plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape ) +{ + btTransform trans; + trans.setIdentity(); + btVector3 localInertia(0,0,0); + btCollisionShape* shape = reinterpret_cast( cshape); + btAssert(shape); + if (mass) + { + shape->calculateLocalInertia(mass,localInertia); + } + void* mem = btAlignedAlloc(sizeof(btRigidBody),16); + btRigidBody::btRigidBodyConstructionInfo rbci(mass, 0,shape,localInertia); + btRigidBody* body = new (mem)btRigidBody(rbci); + body->setWorldTransform(trans); + body->setUserPointer(user_data); + return (plRigidBodyHandle) body; +} + +void plDeleteRigidBody(plRigidBodyHandle cbody) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody); + btAssert(body); + btAlignedFree( body); +} + + +/* Collision Shape definition */ + +plCollisionShapeHandle plNewSphereShape(plReal radius) +{ + void* mem = btAlignedAlloc(sizeof(btSphereShape),16); + return (plCollisionShapeHandle) new (mem)btSphereShape(radius); + +} + +plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z) +{ + void* mem = btAlignedAlloc(sizeof(btBoxShape),16); + return (plCollisionShapeHandle) new (mem)btBoxShape(btVector3(x,y,z)); +} + +plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height) +{ + //capsule is convex hull of 2 spheres, so use btMultiSphereShape + + const int numSpheres = 2; + btVector3 positions[numSpheres] = {btVector3(0,height,0),btVector3(0,-height,0)}; + btScalar radi[numSpheres] = {radius,radius}; + void* mem = btAlignedAlloc(sizeof(btMultiSphereShape),16); + return (plCollisionShapeHandle) new (mem)btMultiSphereShape(positions,radi,numSpheres); +} +plCollisionShapeHandle plNewConeShape(plReal radius, plReal height) +{ + void* mem = btAlignedAlloc(sizeof(btConeShape),16); + return (plCollisionShapeHandle) new (mem)btConeShape(radius,height); +} + +plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height) +{ + void* mem = btAlignedAlloc(sizeof(btCylinderShape),16); + return (plCollisionShapeHandle) new (mem)btCylinderShape(btVector3(radius,height,radius)); +} + +/* Convex Meshes */ +plCollisionShapeHandle plNewConvexHullShape() +{ + void* mem = btAlignedAlloc(sizeof(btConvexHullShape),16); + return (plCollisionShapeHandle) new (mem)btConvexHullShape(); +} + + +/* Concave static triangle meshes */ +plMeshInterfaceHandle plNewMeshInterface() +{ + return 0; +} + +plCollisionShapeHandle plNewCompoundShape() +{ + void* mem = btAlignedAlloc(sizeof(btCompoundShape),16); + return (plCollisionShapeHandle) new (mem)btCompoundShape(); +} + +void plAddChildShape(plCollisionShapeHandle compoundShapeHandle,plCollisionShapeHandle childShapeHandle, plVector3 childPos,plQuaternion childOrn) +{ + btCollisionShape* colShape = reinterpret_cast(compoundShapeHandle); + btAssert(colShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE); + btCompoundShape* compoundShape = reinterpret_cast(colShape); + btCollisionShape* childShape = reinterpret_cast(childShapeHandle); + btTransform localTrans; + localTrans.setIdentity(); + localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2])); + localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3])); + compoundShape->addChildShape(localTrans,childShape); +} + +void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient) +{ + btQuaternion orn; + orn.setEuler(yaw,pitch,roll); + orient[0] = orn.getX(); + orient[1] = orn.getY(); + orient[2] = orn.getZ(); + orient[3] = orn.getW(); + +} + + +// extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2); +// extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle); + + +void plAddVertex(plCollisionShapeHandle cshape, plReal x,plReal y,plReal z) +{ + btCollisionShape* colShape = reinterpret_cast( cshape); + (void)colShape; + btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE); + btConvexHullShape* convexHullShape = reinterpret_cast( cshape); + convexHullShape->addPoint(btVector3(x,y,z)); + +} + +void plDeleteShape(plCollisionShapeHandle cshape) +{ + btCollisionShape* shape = reinterpret_cast( cshape); + btAssert(shape); + btAlignedFree(shape); +} +void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling) +{ + btCollisionShape* shape = reinterpret_cast( cshape); + btAssert(shape); + btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]); + shape->setLocalScaling(scaling); +} + + + +void plSetPosition(plRigidBodyHandle object, const plVector3 position) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btVector3 pos(position[0],position[1],position[2]); + btTransform worldTrans = body->getWorldTransform(); + worldTrans.setOrigin(pos); + body->setWorldTransform(worldTrans); +} + +void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btQuaternion orn(orientation[0],orientation[1],orientation[2],orientation[3]); + btTransform worldTrans = body->getWorldTransform(); + worldTrans.setRotation(orn); + body->setWorldTransform(worldTrans); +} + +void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btTransform& worldTrans = body->getWorldTransform(); + worldTrans.setFromOpenGLMatrix(matrix); +} + +void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + body->getWorldTransform().getOpenGLMatrix(matrix); + +} + +void plGetPosition(plRigidBodyHandle object,plVector3 position) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + const btVector3& pos = body->getWorldTransform().getOrigin(); + position[0] = pos.getX(); + position[1] = pos.getY(); + position[2] = pos.getZ(); +} + +void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + const btQuaternion& orn = body->getWorldTransform().getRotation(); + orientation[0] = orn.getX(); + orientation[1] = orn.getY(); + orientation[2] = orn.getZ(); + orientation[3] = orn.getW(); +} + + + +//plRigidBodyHandle plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); + +// extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); + +double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]) +{ + btVector3 vp(p1[0], p1[1], p1[2]); + btTriangleShape trishapeA(vp, + btVector3(p2[0], p2[1], p2[2]), + btVector3(p3[0], p3[1], p3[2])); + trishapeA.setMargin(0.000001f); + btVector3 vq(q1[0], q1[1], q1[2]); + btTriangleShape trishapeB(vq, + btVector3(q2[0], q2[1], q2[2]), + btVector3(q3[0], q3[1], q3[2])); + trishapeB.setMargin(0.000001f); + + // btVoronoiSimplexSolver sGjkSimplexSolver; + // btGjkEpaPenetrationDepthSolver penSolverPtr; + + static btSimplexSolverInterface sGjkSimplexSolver; + sGjkSimplexSolver.reset(); + + static btGjkEpaPenetrationDepthSolver Solver0; + static btMinkowskiPenetrationDepthSolver Solver1; + + btConvexPenetrationDepthSolver* Solver = NULL; + + Solver = &Solver1; + + btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); + + convexConvex.m_catchDegeneracies = 1; + + // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0); + + btPointCollector gjkOutput; + btGjkPairDetector::ClosestPointInput input; + + + btTransform tr; + tr.setIdentity(); + + input.m_transformA = tr; + input.m_transformB = tr; + + convexConvex.getClosestPoints(input, gjkOutput, 0); + + + if (gjkOutput.m_hasResult) + { + + pb[0] = pa[0] = gjkOutput.m_pointInWorld[0]; + pb[1] = pa[1] = gjkOutput.m_pointInWorld[1]; + pb[2] = pa[2] = gjkOutput.m_pointInWorld[2]; + + pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance; + pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance; + pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance; + + normal[0] = gjkOutput.m_normalOnBInWorld[0]; + normal[1] = gjkOutput.m_normalOnBInWorld[1]; + normal[2] = gjkOutput.m_normalOnBInWorld[2]; + + return gjkOutput.m_distance; + } + return -1.0f; +} + diff --git a/src/BulletDynamics/Dynamics/btActionInterface.h b/src/BulletDynamics/Dynamics/btActionInterface.h new file mode 100644 index 0000000..e1fea3a --- /dev/null +++ b/src/BulletDynamics/Dynamics/btActionInterface.h @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _BT_ACTION_INTERFACE_H +#define _BT_ACTION_INTERFACE_H + +class btIDebugDraw; +class btCollisionWorld; + +#include "LinearMath/btScalar.h" +#include "btRigidBody.h" + +///Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWorld +class btActionInterface +{ +protected: + + static btRigidBody& getFixedBody(); + + +public: + + virtual ~btActionInterface() + { + } + + virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0; + + virtual void debugDraw(btIDebugDraw* debugDrawer) = 0; + +}; + +#endif //_BT_ACTION_INTERFACE_H + diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp new file mode 100644 index 0000000..9ff2d9f --- /dev/null +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -0,0 +1,1466 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btDiscreteDynamicsWorld.h" + +//collision detection +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btQuickprof.h" + +//rigidbody & constraints +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" +#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" +#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" +#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" +#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" +#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" + + +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + + +#include "BulletDynamics/Dynamics/btActionInterface.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btMotionState.h" + +#include "LinearMath/btSerializer.h" + +#if 0 +btAlignedObjectArray debugContacts; +btAlignedObjectArray debugNormals; +int startHit=2; +int firstHit=startHit; +#endif + +SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) +{ + int islandId; + + const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); + const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); + islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag(); + return islandId; + +} + + +class btSortConstraintOnIslandPredicate +{ + public: + + bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) const + { + int rIslandId0,lIslandId0; + rIslandId0 = btGetConstraintIslandId(rhs); + lIslandId0 = btGetConstraintIslandId(lhs); + return lIslandId0 < rIslandId0; + } +}; + +struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback +{ + btContactSolverInfo* m_solverInfo; + btConstraintSolver* m_solver; + btTypedConstraint** m_sortedConstraints; + int m_numConstraints; + btIDebugDraw* m_debugDrawer; + btStackAlloc* m_stackAlloc; + btDispatcher* m_dispatcher; + + btAlignedObjectArray m_bodies; + btAlignedObjectArray m_manifolds; + btAlignedObjectArray m_constraints; + + + InplaceSolverIslandCallback( + btConstraintSolver* solver, + btStackAlloc* stackAlloc, + btDispatcher* dispatcher) + :m_solverInfo(NULL), + m_solver(solver), + m_sortedConstraints(NULL), + m_numConstraints(0), + m_debugDrawer(NULL), + m_stackAlloc(stackAlloc), + m_dispatcher(dispatcher) + { + + } + + InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other) + { + btAssert(0); + (void)other; + return *this; + } + + SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer) + { + btAssert(solverInfo); + m_solverInfo = solverInfo; + m_sortedConstraints = sortedConstraints; + m_numConstraints = numConstraints; + m_debugDrawer = debugDrawer; + m_bodies.resize (0); + m_manifolds.resize (0); + m_constraints.resize (0); + } + + + virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) + { + if (islandId<0) + { + ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id + m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); + } else + { + //also add all non-contact constraints/joints for this island + btTypedConstraint** startConstraint = 0; + int numCurConstraints = 0; + int i; + + //find the first constraint for this island + for (i=0;im_minimumSolverBatchSize<=1) + { + m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); + } else + { + + for (i=0;im_solverInfo->m_minimumSolverBatchSize) + { + processConstraints(); + } else + { + //printf("deferred\n"); + } + } + } + } + void processConstraints() + { + + btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0; + btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0; + btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0; + + m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); + m_bodies.resize(0); + m_manifolds.resize(0); + m_constraints.resize(0); + + } + +}; + + + +btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) +:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), +m_sortedConstraints (), +m_solverIslandCallback ( NULL ), +m_constraintSolver(constraintSolver), +m_gravity(0,-10,0), +m_localTime(0), +m_synchronizeAllMotionStates(false), +m_applySpeculativeContactRestitution(false), +m_profileTimings(0) + +{ + if (!m_constraintSolver) + { + void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); + m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver; + m_ownsConstraintSolver = true; + } else + { + m_ownsConstraintSolver = false; + } + + { + void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16); + m_islandManager = new (mem) btSimulationIslandManager(); + } + + m_ownsIslandManager = true; + + { + void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback),16); + m_solverIslandCallback = new (mem) InplaceSolverIslandCallback (m_constraintSolver, m_stackAlloc, dispatcher); + } +} + + +btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld() +{ + //only delete it when we created it + if (m_ownsIslandManager) + { + m_islandManager->~btSimulationIslandManager(); + btAlignedFree( m_islandManager); + } + if (m_solverIslandCallback) + { + m_solverIslandCallback->~InplaceSolverIslandCallback(); + btAlignedFree(m_solverIslandCallback); + } + if (m_ownsConstraintSolver) + { + + m_constraintSolver->~btConstraintSolver(); + btAlignedFree(m_constraintSolver); + } +} + +void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep) +{ +///would like to iterate over m_nonStaticRigidBodies, but unfortunately old API allows +///to switch status _after_ adding kinematic objects to the world +///fix it for Bullet 3.x release + for (int i=0;igetActivationState() != ISLAND_SLEEPING) + { + if (body->isKinematicObject()) + { + //to calculate velocities next frame + body->saveKinematicState(timeStep); + } + } + } + +} + +void btDiscreteDynamicsWorld::debugDrawWorld() +{ + BT_PROFILE("debugDrawWorld"); + + btCollisionWorld::debugDrawWorld(); + + bool drawConstraints = false; + if (getDebugDrawer()) + { + int mode = getDebugDrawer()->getDebugMode(); + if(mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)) + { + drawConstraints = true; + } + } + if(drawConstraints) + { + for(int i = getNumConstraints()-1; i>=0 ;i--) + { + btTypedConstraint* constraint = getConstraint(i); + debugDrawConstraint(constraint); + } + } + + + + if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawNormals))) + { + int i; + + if (getDebugDrawer() && getDebugDrawer()->getDebugMode()) + { + for (i=0;idebugDraw(m_debugDrawer); + } + } + } +} + +void btDiscreteDynamicsWorld::clearForces() +{ + ///@todo: iterate over awake simulation islands! + for ( int i=0;iclearForces(); + } +} + +///apply gravity, call this once per timestep +void btDiscreteDynamicsWorld::applyGravity() +{ + ///@todo: iterate over awake simulation islands! + for ( int i=0;iisActive()) + { + body->applyGravity(); + } + } +} + + +void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body) +{ + btAssert(body); + + if (body->getMotionState() && !body->isStaticOrKinematicObject()) + { + //we need to call the update at least once, even for sleeping objects + //otherwise the 'graphics' transform never updates properly + ///@todo: add 'dirty' flag + //if (body->getActivationState() != ISLAND_SLEEPING) + { + btTransform interpolatedTransform; + btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), + body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform); + body->getMotionState()->setWorldTransform(interpolatedTransform); + } + } +} + + +void btDiscreteDynamicsWorld::synchronizeMotionStates() +{ + BT_PROFILE("synchronizeMotionStates"); + if (m_synchronizeAllMotionStates) + { + //iterate over all collision objects + for ( int i=0;iisActive()) + synchronizeSingleMotionState(body); + } + } +} + + +int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) +{ + startProfiling(timeStep); + + BT_PROFILE("stepSimulation"); + + int numSimulationSubSteps = 0; + + if (maxSubSteps) + { + //fixed timestep with interpolation + m_localTime += timeStep; + if (m_localTime >= fixedTimeStep) + { + numSimulationSubSteps = int( m_localTime / fixedTimeStep); + m_localTime -= numSimulationSubSteps * fixedTimeStep; + } + } else + { + //variable timestep + fixedTimeStep = timeStep; + m_localTime = timeStep; + if (btFuzzyZero(timeStep)) + { + numSimulationSubSteps = 0; + maxSubSteps = 0; + } else + { + numSimulationSubSteps = 1; + maxSubSteps = 1; + } + } + + //process some debugging flags + if (getDebugDrawer()) + { + btIDebugDraw* debugDrawer = getDebugDrawer (); + gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0; + } + if (numSimulationSubSteps) + { + + //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt + int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps; + + saveKinematicState(fixedTimeStep*clampedSimulationSteps); + + applyGravity(); + + + + for (int i=0;iisActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY)) + { + body->setGravity(gravity); + } + } +} + +btVector3 btDiscreteDynamicsWorld::getGravity () const +{ + return m_gravity; +} + +void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask) +{ + btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask); +} + +void btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) +{ + btRigidBody* body = btRigidBody::upcast(collisionObject); + if (body) + removeRigidBody(body); + else + btCollisionWorld::removeCollisionObject(collisionObject); +} + +void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body) +{ + m_nonStaticRigidBodies.remove(body); + btCollisionWorld::removeCollisionObject(body); +} + + +void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body) +{ + if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY)) + { + body->setGravity(m_gravity); + } + + if (body->getCollisionShape()) + { + if (!body->isStaticObject()) + { + m_nonStaticRigidBodies.push_back(body); + } else + { + body->setActivationState(ISLAND_SLEEPING); + } + + bool isDynamic = !(body->isStaticObject() || body->isKinematicObject()); + short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter); + short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + + addCollisionObject(body,collisionFilterGroup,collisionFilterMask); + } +} + +void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask) +{ + if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY)) + { + body->setGravity(m_gravity); + } + + if (body->getCollisionShape()) + { + if (!body->isStaticObject()) + { + m_nonStaticRigidBodies.push_back(body); + } + else + { + body->setActivationState(ISLAND_SLEEPING); + } + addCollisionObject(body,group,mask); + } +} + + +void btDiscreteDynamicsWorld::updateActions(btScalar timeStep) +{ + BT_PROFILE("updateActions"); + + for ( int i=0;iupdateAction( this, timeStep); + } +} + + +void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) +{ + BT_PROFILE("updateActivationState"); + + for ( int i=0;iupdateDeactivation(timeStep); + + if (body->wantsSleeping()) + { + if (body->isStaticOrKinematicObject()) + { + body->setActivationState(ISLAND_SLEEPING); + } else + { + if (body->getActivationState() == ACTIVE_TAG) + body->setActivationState( WANTS_DEACTIVATION ); + if (body->getActivationState() == ISLAND_SLEEPING) + { + body->setAngularVelocity(btVector3(0,0,0)); + body->setLinearVelocity(btVector3(0,0,0)); + } + + } + } else + { + if (body->getActivationState() != DISABLE_DEACTIVATION) + body->setActivationState( ACTIVE_TAG ); + } + } + } +} + +void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies) +{ + m_constraints.push_back(constraint); + if (disableCollisionsBetweenLinkedBodies) + { + constraint->getRigidBodyA().addConstraintRef(constraint); + constraint->getRigidBodyB().addConstraintRef(constraint); + } +} + +void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint) +{ + m_constraints.remove(constraint); + constraint->getRigidBodyA().removeConstraintRef(constraint); + constraint->getRigidBodyB().removeConstraintRef(constraint); +} + +void btDiscreteDynamicsWorld::addAction(btActionInterface* action) +{ + m_actions.push_back(action); +} + +void btDiscreteDynamicsWorld::removeAction(btActionInterface* action) +{ + m_actions.remove(action); +} + + +void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle) +{ + addAction(vehicle); +} + +void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle) +{ + removeAction(vehicle); +} + +void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character) +{ + addAction(character); +} + +void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character) +{ + removeAction(character); +} + + + + +void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) +{ + BT_PROFILE("solveConstraints"); + + m_sortedConstraints.resize( m_constraints.size()); + int i; + for (i=0;isetup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer()); + m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); + + /// solve all the constraints for this island + m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),m_solverIslandCallback); + + m_solverIslandCallback->processConstraints(); + + m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc); +} + + +void btDiscreteDynamicsWorld::calculateSimulationIslands() +{ + BT_PROFILE("calculateSimulationIslands"); + + getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); + + { + //merge islands based on speculative contact manifolds too + for (int i=0;im_predictiveManifolds.size();i++) + { + btPersistentManifold* manifold = m_predictiveManifolds[i]; + + const btCollisionObject* colObj0 = manifold->getBody0(); + const btCollisionObject* colObj1 = manifold->getBody1(); + + if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && + ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) + { + if (colObj0->isActive() || colObj1->isActive()) + { + + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), + (colObj1)->getIslandTag()); + } + } + } + } + + { + int i; + int numConstraints = int(m_constraints.size()); + for (i=0;i< numConstraints ; i++ ) + { + btTypedConstraint* constraint = m_constraints[i]; + if (constraint->isEnabled()) + { + const btRigidBody* colObj0 = &constraint->getRigidBodyA(); + const btRigidBody* colObj1 = &constraint->getRigidBodyB(); + + if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && + ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) + { + if (colObj0->isActive() || colObj1->isActive()) + { + + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), + (colObj1)->getIslandTag()); + } + } + } + } + } + + //Store the island id in each body + getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld()); + + +} + + + + +class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback +{ +public: + + btCollisionObject* m_me; + btScalar m_allowedPenetration; + btOverlappingPairCache* m_pairCache; + btDispatcher* m_dispatcher; + +public: + btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : + btCollisionWorld::ClosestConvexResultCallback(fromA,toA), + m_me(me), + m_allowedPenetration(0.0f), + m_pairCache(pairCache), + m_dispatcher(dispatcher) + { + } + + virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) + { + if (convexResult.m_hitCollisionObject == m_me) + return 1.0f; + + //ignore result if there is no contact response + if(!convexResult.m_hitCollisionObject->hasContactResponse()) + return 1.0f; + + btVector3 linVelA,linVelB; + linVelA = m_convexToWorld-m_convexFromWorld; + linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin(); + + btVector3 relativeVelocity = (linVelA-linVelB); + //don't report time of impact for motion away from the contact normal (or causes minor penetration) + if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration) + return 1.f; + + return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace); + } + + virtual bool needsCollision(btBroadphaseProxy* proxy0) const + { + //don't collide with itself + if (proxy0->m_clientObject == m_me) + return false; + + ///don't do CCD when the collision filters are not matching + if (!ClosestConvexResultCallback::needsCollision(proxy0)) + return false; + + btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; + + //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179 + if (m_dispatcher->needsResponse(m_me,otherObj)) + { +#if 0 + ///don't do CCD when there are already contact points (touching contact/penetration) + btAlignedObjectArray manifoldArray; + btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0); + if (collisionPair) + { + if (collisionPair->m_algorithm) + { + manifoldArray.resize(0); + collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); + for (int j=0;jgetNumContacts()>0) + return false; + } + } + } +#endif + return true; + } + + return false; + } + + +}; + +///internal debugging variable. this value shouldn't be too high +int gNumClampedCcdMotions=0; + + +void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep) +{ + BT_PROFILE("createPredictiveContacts"); + + { + BT_PROFILE("release predictive contact manifolds"); + + for (int i=0;im_dispatcher1->releaseManifold(manifold); + } + m_predictiveManifolds.clear(); + } + + btTransform predictedTrans; + for ( int i=0;isetHitFraction(1.f); + + if (body->isActive() && (!body->isStaticOrKinematicObject())) + { + + body->predictIntegratedTransform(timeStep, predictedTrans); + + btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); + + if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) + { + BT_PROFILE("predictive convexSweepTest"); + if (body->getCollisionShape()->isConvex()) + { + gNumClampedCcdMotions++; +#ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY + class StaticOnlyCallback : public btClosestNotMeConvexResultCallback + { + public: + + StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : + btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) + { + } + + virtual bool needsCollision(btBroadphaseProxy* proxy0) const + { + btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; + if (!otherObj->isStaticOrKinematicObject()) + return false; + return btClosestNotMeConvexResultCallback::needsCollision(proxy0); + } + }; + + StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); +#else + btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); +#endif + //btConvexShape* convexShape = static_cast(body->getCollisionShape()); + btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast(body->getCollisionShape()); + sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; + + sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; + sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; + btTransform modifiedPredictedTrans = predictedTrans; + modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); + + convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); + if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) + { + + btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction; + btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld); + + + btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject); + m_predictiveManifolds.push_back(manifold); + + btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec; + btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB; + + btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance); + + bool isPredictive = true; + int index = manifold->addManifoldPoint(newPoint, isPredictive); + btManifoldPoint& pt = manifold->getContactPoint(index); + pt.m_combinedRestitution = 0; + pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject); + pt.m_positionWorldOnA = body->getWorldTransform().getOrigin(); + pt.m_positionWorldOnB = worldPointB; + + } + } + } + } + } +} +void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) +{ + BT_PROFILE("integrateTransforms"); + btTransform predictedTrans; + for ( int i=0;isetHitFraction(1.f); + + if (body->isActive() && (!body->isStaticOrKinematicObject())) + { + + body->predictIntegratedTransform(timeStep, predictedTrans); + + btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); + + + + if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) + { + BT_PROFILE("CCD motion clamping"); + if (body->getCollisionShape()->isConvex()) + { + gNumClampedCcdMotions++; +#ifdef USE_STATIC_ONLY + class StaticOnlyCallback : public btClosestNotMeConvexResultCallback + { + public: + + StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : + btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) + { + } + + virtual bool needsCollision(btBroadphaseProxy* proxy0) const + { + btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; + if (!otherObj->isStaticOrKinematicObject()) + return false; + return btClosestNotMeConvexResultCallback::needsCollision(proxy0); + } + }; + + StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); +#else + btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); +#endif + //btConvexShape* convexShape = static_cast(body->getCollisionShape()); + btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast(body->getCollisionShape()); + sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; + + sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; + sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; + btTransform modifiedPredictedTrans = predictedTrans; + modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); + + convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); + if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) + { + + //printf("clamped integration to hit fraction = %f\n",fraction); + body->setHitFraction(sweepResults.m_closestHitFraction); + body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); + body->setHitFraction(0.f); + body->proceedToTransform( predictedTrans); + +#if 0 + btVector3 linVel = body->getLinearVelocity(); + + btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep; + btScalar maxSpeedSqr = maxSpeed*maxSpeed; + if (linVel.length2()>maxSpeedSqr) + { + linVel.normalize(); + linVel*= maxSpeed; + body->setLinearVelocity(linVel); + btScalar ms2 = body->getLinearVelocity().length2(); + body->predictIntegratedTransform(timeStep, predictedTrans); + + btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); + btScalar smt = body->getCcdSquareMotionThreshold(); + printf("sm2=%f\n",sm2); + } +#else + + //don't apply the collision response right now, it will happen next frame + //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution. + //btScalar appliedImpulse = 0.f; + //btScalar depth = 0.f; + //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); + + +#endif + + continue; + } + } + } + + + body->proceedToTransform( predictedTrans); + + } + + } + + ///this should probably be switched on by default, but it is not well tested yet + if (m_applySpeculativeContactRestitution) + { + BT_PROFILE("apply speculative contact restitution"); + for (int i=0;igetBody0()); + btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1()); + + for (int p=0;pgetNumContacts();p++) + { + const btManifoldPoint& pt = manifold->getContactPoint(p); + btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1); + + if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f) + //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f) + { + btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution; + + const btVector3& pos1 = pt.getPositionWorldOnA(); + const btVector3& pos2 = pt.getPositionWorldOnB(); + + btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin(); + btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin(); + + if (body0) + body0->applyImpulse(imp,rel_pos0); + if (body1) + body1->applyImpulse(-imp,rel_pos1); + } + } + } + } + +} + + + + + + +void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +{ + BT_PROFILE("predictUnconstraintMotion"); + for ( int i=0;iisStaticOrKinematicObject()) + { + //don't integrate/update velocities here, it happens in the constraint solver + + //damping + body->applyDamping(timeStep); + + body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); + } + } +} + + +void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep) +{ + (void)timeStep; + +#ifndef BT_NO_PROFILE + CProfileManager::Reset(); +#endif //BT_NO_PROFILE + +} + + + + + + +void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint) +{ + bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0; + bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0; + btScalar dbgDrawSize = constraint->getDbgDrawSize(); + if(dbgDrawSize <= btScalar(0.f)) + { + return; + } + + switch(constraint->getConstraintType()) + { + case POINT2POINT_CONSTRAINT_TYPE: + { + btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint; + btTransform tr; + tr.setIdentity(); + btVector3 pivot = p2pC->getPivotInA(); + pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot; + tr.setOrigin(pivot); + getDebugDrawer()->drawTransform(tr, dbgDrawSize); + // that ideally should draw the same frame + pivot = p2pC->getPivotInB(); + pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot; + tr.setOrigin(pivot); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + } + break; + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* pHinge = (btHingeConstraint*)constraint; + btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + btScalar minAng = pHinge->getLowerLimit(); + btScalar maxAng = pHinge->getUpperLimit(); + if(minAng == maxAng) + { + break; + } + bool drawSect = true; + if(minAng > maxAng) + { + minAng = btScalar(0.f); + maxAng = SIMD_2_PI; + drawSect = false; + } + if(drawLimits) + { + btVector3& center = tr.getOrigin(); + btVector3 normal = tr.getBasis().getColumn(2); + btVector3 axis = tr.getBasis().getColumn(0); + getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect); + } + } + break; + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint; + btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + if(drawLimits) + { + //const btScalar length = btScalar(5); + const btScalar length = dbgDrawSize; + static int nSegments = 8*4; + btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments); + btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length); + pPrev = tr * pPrev; + for (int i=0; iGetPointForAngle(fAngleInRadians, length); + pCur = tr * pCur; + getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0)); + + if (i%(nSegments/8) == 0) + getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0)); + + pPrev = pCur; + } + btScalar tws = pCT->getTwistSpan(); + btScalar twa = pCT->getTwistAngle(); + bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f)); + if(useFrameB) + { + tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); + } + else + { + tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame(); + } + btVector3 pivot = tr.getOrigin(); + btVector3 normal = tr.getBasis().getColumn(0); + btVector3 axis1 = tr.getBasis().getColumn(1); + getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true); + + } + } + break; + case D6_SPRING_CONSTRAINT_TYPE: + case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint; + btTransform tr = p6DOF->getCalculatedTransformA(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = p6DOF->getCalculatedTransformB(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + if(drawLimits) + { + tr = p6DOF->getCalculatedTransformA(); + const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin(); + btVector3 up = tr.getBasis().getColumn(2); + btVector3 axis = tr.getBasis().getColumn(0); + btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit; + btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit; + btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit; + btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit; + getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0)); + axis = tr.getBasis().getColumn(1); + btScalar ay = p6DOF->getAngle(1); + btScalar az = p6DOF->getAngle(2); + btScalar cy = btCos(ay); + btScalar sy = btSin(ay); + btScalar cz = btCos(az); + btScalar sz = btSin(az); + btVector3 ref; + ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2]; + ref[1] = -sz*axis[0] + cz*axis[1]; + ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2]; + tr = p6DOF->getCalculatedTransformB(); + btVector3 normal = -tr.getBasis().getColumn(0); + btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit; + btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit; + if(minFi > maxFi) + { + getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false); + } + else if(minFi < maxFi) + { + getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true); + } + tr = p6DOF->getCalculatedTransformA(); + btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit; + btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit; + getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0)); + } + } + break; + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraint* pSlider = (btSliderConstraint*)constraint; + btTransform tr = pSlider->getCalculatedTransformA(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = pSlider->getCalculatedTransformB(); + if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + if(drawLimits) + { + btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB(); + btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f); + btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f); + getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0)); + btVector3 normal = tr.getBasis().getColumn(0); + btVector3 axis = tr.getBasis().getColumn(1); + btScalar a_min = pSlider->getLowerAngLimit(); + btScalar a_max = pSlider->getUpperAngLimit(); + const btVector3& center = pSlider->getCalculatedTransformB().getOrigin(); + getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true); + } + } + break; + default : + break; + } + return; +} + + + + + +void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) +{ + if (m_ownsConstraintSolver) + { + btAlignedFree( m_constraintSolver); + } + m_ownsConstraintSolver = false; + m_constraintSolver = solver; + m_solverIslandCallback->m_solver = solver; +} + +btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver() +{ + return m_constraintSolver; +} + + +int btDiscreteDynamicsWorld::getNumConstraints() const +{ + return int(m_constraints.size()); +} +btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) +{ + return m_constraints[index]; +} +const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const +{ + return m_constraints[index]; +} + + + +void btDiscreteDynamicsWorld::serializeRigidBodies(btSerializer* serializer) +{ + int i; + //serialize all collision objects + for (i=0;igetInternalType() & btCollisionObject::CO_RIGID_BODY) + { + int len = colObj->calculateSerializeBufferSize(); + btChunk* chunk = serializer->allocate(len,1); + const char* structType = colObj->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj); + } + } + + for (i=0;icalculateSerializeBufferSize(); + btChunk* chunk = serializer->allocate(size,1); + const char* structType = constraint->serialize(chunk->m_oldPtr,serializer); + serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint); + } +} + + + + +void btDiscreteDynamicsWorld::serializeDynamicsWorldInfo(btSerializer* serializer) +{ +#ifdef BT_USE_DOUBLE_PRECISION + int len = sizeof(btDynamicsWorldDoubleData); + btChunk* chunk = serializer->allocate(len,1); + btDynamicsWorldDoubleData* worldInfo = (btDynamicsWorldDoubleData*)chunk->m_oldPtr; +#else//BT_USE_DOUBLE_PRECISION + int len = sizeof(btDynamicsWorldFloatData); + btChunk* chunk = serializer->allocate(len,1); + btDynamicsWorldFloatData* worldInfo = (btDynamicsWorldFloatData*)chunk->m_oldPtr; +#endif//BT_USE_DOUBLE_PRECISION + + memset(worldInfo ,0x00,len); + + m_gravity.serialize(worldInfo->m_gravity); + worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau; + worldInfo->m_solverInfo.m_damping = getSolverInfo().m_damping; + worldInfo->m_solverInfo.m_friction = getSolverInfo().m_friction; + worldInfo->m_solverInfo.m_timeStep = getSolverInfo().m_timeStep; + + worldInfo->m_solverInfo.m_restitution = getSolverInfo().m_restitution; + worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction; + worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor; + worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp; + + worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2; + worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm; + worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold; + worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp; + + worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop; + worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor; + worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce; + worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold; + + worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations; + worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode; + worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold; + worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize; + + worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse; + +#ifdef BT_USE_DOUBLE_PRECISION + const char* structType = "btDynamicsWorldDoubleData"; +#else//BT_USE_DOUBLE_PRECISION + const char* structType = "btDynamicsWorldFloatData"; +#endif//BT_USE_DOUBLE_PRECISION + serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo); +} + +void btDiscreteDynamicsWorld::serialize(btSerializer* serializer) +{ + + serializer->startSerialization(); + + serializeDynamicsWorldInfo(serializer); + + serializeRigidBodies(serializer); + + serializeCollisionObjects(serializer); + + serializer->finishSerialization(); +} + diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h new file mode 100644 index 0000000..fa934c4 --- /dev/null +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -0,0 +1,221 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_DISCRETE_DYNAMICS_WORLD_H +#define BT_DISCRETE_DYNAMICS_WORLD_H + +#include "btDynamicsWorld.h" + +class btDispatcher; +class btOverlappingPairCache; +class btConstraintSolver; +class btSimulationIslandManager; +class btTypedConstraint; +class btActionInterface; +class btPersistentManifold; +class btIDebugDraw; +struct InplaceSolverIslandCallback; + +#include "LinearMath/btAlignedObjectArray.h" + + +///btDiscreteDynamicsWorld provides discrete rigid body simulation +///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController +ATTRIBUTE_ALIGNED16(class) btDiscreteDynamicsWorld : public btDynamicsWorld +{ +protected: + + btAlignedObjectArray m_sortedConstraints; + InplaceSolverIslandCallback* m_solverIslandCallback; + + btConstraintSolver* m_constraintSolver; + + btSimulationIslandManager* m_islandManager; + + btAlignedObjectArray m_constraints; + + btAlignedObjectArray m_nonStaticRigidBodies; + + btVector3 m_gravity; + + //for variable timesteps + btScalar m_localTime; + //for variable timesteps + + bool m_ownsIslandManager; + bool m_ownsConstraintSolver; + bool m_synchronizeAllMotionStates; + bool m_applySpeculativeContactRestitution; + + btAlignedObjectArray m_actions; + + int m_profileTimings; + + btAlignedObjectArray m_predictiveManifolds; + + virtual void predictUnconstraintMotion(btScalar timeStep); + + virtual void integrateTransforms(btScalar timeStep); + + virtual void calculateSimulationIslands(); + + virtual void solveConstraints(btContactSolverInfo& solverInfo); + + void updateActivationState(btScalar timeStep); + + void updateActions(btScalar timeStep); + + void startProfiling(btScalar timeStep); + + virtual void internalSingleStepSimulation( btScalar timeStep); + + void createPredictiveContacts(btScalar timeStep); + + virtual void saveKinematicState(btScalar timeStep); + + void serializeRigidBodies(btSerializer* serializer); + + void serializeDynamicsWorldInfo(btSerializer* serializer); + +public: + + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + ///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those + btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + + virtual ~btDiscreteDynamicsWorld(); + + ///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's + virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); + + + virtual void synchronizeMotionStates(); + + ///this can be useful to synchronize a single rigid body -> graphics object + void synchronizeSingleMotionState(btRigidBody* body); + + virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false); + + virtual void removeConstraint(btTypedConstraint* constraint); + + virtual void addAction(btActionInterface*); + + virtual void removeAction(btActionInterface*); + + btSimulationIslandManager* getSimulationIslandManager() + { + return m_islandManager; + } + + const btSimulationIslandManager* getSimulationIslandManager() const + { + return m_islandManager; + } + + btCollisionWorld* getCollisionWorld() + { + return this; + } + + virtual void setGravity(const btVector3& gravity); + + virtual btVector3 getGravity () const; + + virtual void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::StaticFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + + virtual void addRigidBody(btRigidBody* body); + + virtual void addRigidBody(btRigidBody* body, short group, short mask); + + virtual void removeRigidBody(btRigidBody* body); + + ///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject + virtual void removeCollisionObject(btCollisionObject* collisionObject); + + + void debugDrawConstraint(btTypedConstraint* constraint); + + virtual void debugDrawWorld(); + + virtual void setConstraintSolver(btConstraintSolver* solver); + + virtual btConstraintSolver* getConstraintSolver(); + + virtual int getNumConstraints() const; + + virtual btTypedConstraint* getConstraint(int index) ; + + virtual const btTypedConstraint* getConstraint(int index) const; + + + virtual btDynamicsWorldType getWorldType() const + { + return BT_DISCRETE_DYNAMICS_WORLD; + } + + ///the forces on each rigidbody is accumulating together with gravity. clear this after each timestep. + virtual void clearForces(); + + ///apply gravity, call this once per timestep + virtual void applyGravity(); + + virtual void setNumTasks(int numTasks) + { + (void) numTasks; + } + + ///obsolete, use updateActions instead + virtual void updateVehicles(btScalar timeStep) + { + updateActions(timeStep); + } + + ///obsolete, use addAction instead + virtual void addVehicle(btActionInterface* vehicle); + ///obsolete, use removeAction instead + virtual void removeVehicle(btActionInterface* vehicle); + ///obsolete, use addAction instead + virtual void addCharacter(btActionInterface* character); + ///obsolete, use removeAction instead + virtual void removeCharacter(btActionInterface* character); + + void setSynchronizeAllMotionStates(bool synchronizeAll) + { + m_synchronizeAllMotionStates = synchronizeAll; + } + bool getSynchronizeAllMotionStates() const + { + return m_synchronizeAllMotionStates; + } + + void setApplySpeculativeContactRestitution(bool enable) + { + m_applySpeculativeContactRestitution = enable; + } + + bool getApplySpeculativeContactRestitution() const + { + return m_applySpeculativeContactRestitution; + } + + ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo) + virtual void serialize(btSerializer* serializer); + +}; + +#endif //BT_DISCRETE_DYNAMICS_WORLD_H diff --git a/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDynamicsWorld.h new file mode 100644 index 0000000..7d5c621 --- /dev/null +++ b/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -0,0 +1,166 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_DYNAMICS_WORLD_H +#define BT_DYNAMICS_WORLD_H + +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" + +class btTypedConstraint; +class btActionInterface; +class btConstraintSolver; +class btDynamicsWorld; + + +/// Type for the callback for each tick +typedef void (*btInternalTickCallback)(btDynamicsWorld *world, btScalar timeStep); + +enum btDynamicsWorldType +{ + BT_SIMPLE_DYNAMICS_WORLD=1, + BT_DISCRETE_DYNAMICS_WORLD=2, + BT_CONTINUOUS_DYNAMICS_WORLD=3, + BT_SOFT_RIGID_DYNAMICS_WORLD=4 +}; + +///The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc. +class btDynamicsWorld : public btCollisionWorld +{ + +protected: + btInternalTickCallback m_internalTickCallback; + btInternalTickCallback m_internalPreTickCallback; + void* m_worldUserInfo; + + btContactSolverInfo m_solverInfo; + +public: + + + btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration) + :btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0),m_internalPreTickCallback(0), m_worldUserInfo(0) + { + } + + virtual ~btDynamicsWorld() + { + } + + ///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds. + ///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'. + ///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'. + ///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant. + virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0; + + virtual void debugDrawWorld() = 0; + + virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) + { + (void)constraint; (void)disableCollisionsBetweenLinkedBodies; + } + + virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;} + + virtual void addAction(btActionInterface* action) = 0; + + virtual void removeAction(btActionInterface* action) = 0; + + //once a rigidbody is added to the dynamics world, it will get this gravity assigned + //existing rigidbodies in the world get gravity assigned too, during this method + virtual void setGravity(const btVector3& gravity) = 0; + virtual btVector3 getGravity () const = 0; + + virtual void synchronizeMotionStates() = 0; + + virtual void addRigidBody(btRigidBody* body) = 0; + + virtual void addRigidBody(btRigidBody* body, short group, short mask) = 0; + + virtual void removeRigidBody(btRigidBody* body) = 0; + + virtual void setConstraintSolver(btConstraintSolver* solver) = 0; + + virtual btConstraintSolver* getConstraintSolver() = 0; + + virtual int getNumConstraints() const { return 0; } + + virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; } + + virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; } + + virtual btDynamicsWorldType getWorldType() const=0; + + virtual void clearForces() = 0; + + /// Set the callback for when an internal tick (simulation substep) happens, optional user info + void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo=0,bool isPreTick=false) + { + if (isPreTick) + { + m_internalPreTickCallback = cb; + } else + { + m_internalTickCallback = cb; + } + m_worldUserInfo = worldUserInfo; + } + + void setWorldUserInfo(void* worldUserInfo) + { + m_worldUserInfo = worldUserInfo; + } + + void* getWorldUserInfo() const + { + return m_worldUserInfo; + } + + btContactSolverInfo& getSolverInfo() + { + return m_solverInfo; + } + + + ///obsolete, use addAction instead. + virtual void addVehicle(btActionInterface* vehicle) {(void)vehicle;} + ///obsolete, use removeAction instead + virtual void removeVehicle(btActionInterface* vehicle) {(void)vehicle;} + ///obsolete, use addAction instead. + virtual void addCharacter(btActionInterface* character) {(void)character;} + ///obsolete, use removeAction instead + virtual void removeCharacter(btActionInterface* character) {(void)character;} + + +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btDynamicsWorldDoubleData +{ + btContactSolverInfoDoubleData m_solverInfo; + btVector3DoubleData m_gravity; +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btDynamicsWorldFloatData +{ + btContactSolverInfoFloatData m_solverInfo; + btVector3FloatData m_gravity; +}; + + +#endif //BT_DYNAMICS_WORLD_H + + diff --git a/src/BulletDynamics/Dynamics/btRigidBody.cpp b/src/BulletDynamics/Dynamics/btRigidBody.cpp new file mode 100644 index 0000000..222f900 --- /dev/null +++ b/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -0,0 +1,400 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btRigidBody.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "LinearMath/btMinMax.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btMotionState.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "LinearMath/btSerializer.h" + +//'temporarily' global variables +btScalar gDeactivationTime = btScalar(2.); +bool gDisableDeactivation = false; +static int uniqueId = 0; + + +btRigidBody::btRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) +{ + setupRigidBody(constructionInfo); +} + +btRigidBody::btRigidBody(btScalar mass, btMotionState *motionState, btCollisionShape *collisionShape, const btVector3 &localInertia) +{ + btRigidBodyConstructionInfo cinfo(mass,motionState,collisionShape,localInertia); + setupRigidBody(cinfo); +} + +void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) +{ + + m_internalType=CO_RIGID_BODY; + + m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + m_angularFactor.setValue(1,1,1); + m_linearFactor.setValue(1,1,1); + m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping); + + m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold; + m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold; + m_optionalMotionState = constructionInfo.m_motionState; + m_contactSolverType = 0; + m_frictionSolverType = 0; + m_additionalDamping = constructionInfo.m_additionalDamping; + m_additionalDampingFactor = constructionInfo.m_additionalDampingFactor; + m_additionalLinearDampingThresholdSqr = constructionInfo.m_additionalLinearDampingThresholdSqr; + m_additionalAngularDampingThresholdSqr = constructionInfo.m_additionalAngularDampingThresholdSqr; + m_additionalAngularDampingFactor = constructionInfo.m_additionalAngularDampingFactor; + + if (m_optionalMotionState) + { + m_optionalMotionState->getWorldTransform(m_worldTransform); + } else + { + m_worldTransform = constructionInfo.m_startWorldTransform; + } + + m_interpolationWorldTransform = m_worldTransform; + m_interpolationLinearVelocity.setValue(0,0,0); + m_interpolationAngularVelocity.setValue(0,0,0); + + //moved to btCollisionObject + m_friction = constructionInfo.m_friction; + m_rollingFriction = constructionInfo.m_rollingFriction; + m_restitution = constructionInfo.m_restitution; + + setCollisionShape( constructionInfo.m_collisionShape ); + m_debugBodyId = uniqueId++; + + setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia); + updateInertiaTensor(); + + m_rigidbodyFlags = 0; + + + m_deltaLinearVelocity.setZero(); + m_deltaAngularVelocity.setZero(); + m_invMass = m_inverseMass*m_linearFactor; + m_pushVelocity.setZero(); + m_turnVelocity.setZero(); + + + +} + + +void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) +{ + btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform); +} + +void btRigidBody::saveKinematicState(btScalar timeStep) +{ + //todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities + if (timeStep != btScalar(0.)) + { + //if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform + if (getMotionState()) + getMotionState()->getWorldTransform(m_worldTransform); + btVector3 linVel,angVel; + + btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity); + m_interpolationLinearVelocity = m_linearVelocity; + m_interpolationAngularVelocity = m_angularVelocity; + m_interpolationWorldTransform = m_worldTransform; + //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ()); + } +} + +void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const +{ + getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax); +} + + + + +void btRigidBody::setGravity(const btVector3& acceleration) +{ + if (m_inverseMass != btScalar(0.0)) + { + m_gravity = acceleration * (btScalar(1.0) / m_inverseMass); + } + m_gravity_acceleration = acceleration; +} + + + + + + +void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping) +{ + m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); + m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); +} + + + + +///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping +void btRigidBody::applyDamping(btScalar timeStep) +{ + //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74 + //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway + +//#define USE_OLD_DAMPING_METHOD 1 +#ifdef USE_OLD_DAMPING_METHOD + m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); + m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); +#else + m_linearVelocity *= btPow(btScalar(1)-m_linearDamping, timeStep); + m_angularVelocity *= btPow(btScalar(1)-m_angularDamping, timeStep); +#endif + + if (m_additionalDamping) + { + //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc. + //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete + if ((m_angularVelocity.length2() < m_additionalAngularDampingThresholdSqr) && + (m_linearVelocity.length2() < m_additionalLinearDampingThresholdSqr)) + { + m_angularVelocity *= m_additionalDampingFactor; + m_linearVelocity *= m_additionalDampingFactor; + } + + + btScalar speed = m_linearVelocity.length(); + if (speed < m_linearDamping) + { + btScalar dampVel = btScalar(0.005); + if (speed > dampVel) + { + btVector3 dir = m_linearVelocity.normalized(); + m_linearVelocity -= dir * dampVel; + } else + { + m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + } + } + + btScalar angSpeed = m_angularVelocity.length(); + if (angSpeed < m_angularDamping) + { + btScalar angDampVel = btScalar(0.005); + if (angSpeed > angDampVel) + { + btVector3 dir = m_angularVelocity.normalized(); + m_angularVelocity -= dir * angDampVel; + } else + { + m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + } + } + } +} + + +void btRigidBody::applyGravity() +{ + if (isStaticOrKinematicObject()) + return; + + applyCentralForce(m_gravity); + +} + +void btRigidBody::proceedToTransform(const btTransform& newTrans) +{ + setCenterOfMassTransform( newTrans ); +} + + +void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia) +{ + if (mass == btScalar(0.)) + { + m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; + m_inverseMass = btScalar(0.); + } else + { + m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT); + m_inverseMass = btScalar(1.0) / mass; + } + + //Fg = m * a + m_gravity = mass * m_gravity_acceleration; + + m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0), + inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0), + inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0)); + + m_invMass = m_linearFactor*m_inverseMass; +} + + +void btRigidBody::updateInertiaTensor() +{ + m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose(); +} + + +btVector3 btRigidBody::computeGyroscopicForce(btScalar maxGyroscopicForce) const +{ + btVector3 inertiaLocal; + inertiaLocal[0] = 1.f/getInvInertiaDiagLocal()[0]; + inertiaLocal[1] = 1.f/getInvInertiaDiagLocal()[1]; + inertiaLocal[2] = 1.f/getInvInertiaDiagLocal()[2]; + btMatrix3x3 inertiaTensorWorld = getWorldTransform().getBasis().scaled(inertiaLocal) * getWorldTransform().getBasis().transpose(); + btVector3 tmp = inertiaTensorWorld*getAngularVelocity(); + btVector3 gf = getAngularVelocity().cross(tmp); + btScalar l2 = gf.length2(); + if (l2>maxGyroscopicForce*maxGyroscopicForce) + { + gf *= btScalar(1.)/btSqrt(l2)*maxGyroscopicForce; + } + return gf; +} + +void btRigidBody::integrateVelocities(btScalar step) +{ + if (isStaticOrKinematicObject()) + return; + + m_linearVelocity += m_totalForce * (m_inverseMass * step); + m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step; + +#define MAX_ANGVEL SIMD_HALF_PI + /// clamp angular velocity. collision calculations will fail on higher angular velocities + btScalar angvel = m_angularVelocity.length(); + if (angvel*step > MAX_ANGVEL) + { + m_angularVelocity *= (MAX_ANGVEL/step) /angvel; + } + +} + +btQuaternion btRigidBody::getOrientation() const +{ + btQuaternion orn; + m_worldTransform.getBasis().getRotation(orn); + return orn; +} + + +void btRigidBody::setCenterOfMassTransform(const btTransform& xform) +{ + + if (isKinematicObject()) + { + m_interpolationWorldTransform = m_worldTransform; + } else + { + m_interpolationWorldTransform = xform; + } + m_interpolationLinearVelocity = getLinearVelocity(); + m_interpolationAngularVelocity = getAngularVelocity(); + m_worldTransform = xform; + updateInertiaTensor(); +} + + +bool btRigidBody::checkCollideWithOverride(const btCollisionObject* co) const +{ + const btRigidBody* otherRb = btRigidBody::upcast(co); + if (!otherRb) + return true; + + for (int i = 0; i < m_constraintRefs.size(); ++i) + { + const btTypedConstraint* c = m_constraintRefs[i]; + if (c->isEnabled()) + if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb) + return false; + } + + return true; +} + + + +void btRigidBody::addConstraintRef(btTypedConstraint* c) +{ + int index = m_constraintRefs.findLinearSearch(c); + if (index == m_constraintRefs.size()) + m_constraintRefs.push_back(c); + + m_checkCollideWith = true; +} + +void btRigidBody::removeConstraintRef(btTypedConstraint* c) +{ + m_constraintRefs.remove(c); + m_checkCollideWith = m_constraintRefs.size() > 0; +} + +int btRigidBody::calculateSerializeBufferSize() const +{ + int sz = sizeof(btRigidBodyData); + return sz; +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const +{ + btRigidBodyData* rbd = (btRigidBodyData*) dataBuffer; + + btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer); + + m_invInertiaTensorWorld.serialize(rbd->m_invInertiaTensorWorld); + m_linearVelocity.serialize(rbd->m_linearVelocity); + m_angularVelocity.serialize(rbd->m_angularVelocity); + rbd->m_inverseMass = m_inverseMass; + m_angularFactor.serialize(rbd->m_angularFactor); + m_linearFactor.serialize(rbd->m_linearFactor); + m_gravity.serialize(rbd->m_gravity); + m_gravity_acceleration.serialize(rbd->m_gravity_acceleration); + m_invInertiaLocal.serialize(rbd->m_invInertiaLocal); + m_totalForce.serialize(rbd->m_totalForce); + m_totalTorque.serialize(rbd->m_totalTorque); + rbd->m_linearDamping = m_linearDamping; + rbd->m_angularDamping = m_angularDamping; + rbd->m_additionalDamping = m_additionalDamping; + rbd->m_additionalDampingFactor = m_additionalDampingFactor; + rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr; + rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr; + rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor; + rbd->m_linearSleepingThreshold=m_linearSleepingThreshold; + rbd->m_angularSleepingThreshold = m_angularSleepingThreshold; + + return btRigidBodyDataName; +} + + + +void btRigidBody::serializeSingleObject(class btSerializer* serializer) const +{ + btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(),1); + const char* structType = serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,(void*)this); +} + + diff --git a/src/BulletDynamics/Dynamics/btRigidBody.h b/src/BulletDynamics/Dynamics/btRigidBody.h new file mode 100644 index 0000000..c5bf63b --- /dev/null +++ b/src/BulletDynamics/Dynamics/btRigidBody.h @@ -0,0 +1,600 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_RIGIDBODY_H +#define BT_RIGIDBODY_H + +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" + +class btCollisionShape; +class btMotionState; +class btTypedConstraint; + + +extern btScalar gDeactivationTime; +extern bool gDisableDeactivation; + +#ifdef BT_USE_DOUBLE_PRECISION +#define btRigidBodyData btRigidBodyDoubleData +#define btRigidBodyDataName "btRigidBodyDoubleData" +#else +#define btRigidBodyData btRigidBodyFloatData +#define btRigidBodyDataName "btRigidBodyFloatData" +#endif //BT_USE_DOUBLE_PRECISION + + +enum btRigidBodyFlags +{ + BT_DISABLE_WORLD_GRAVITY = 1, + ///The BT_ENABLE_GYROPSCOPIC_FORCE can easily introduce instability + ///So generally it is best to not enable it. + ///If really needed, run at a high frequency like 1000 Hertz: ///See Demos/GyroscopicDemo for an example use + BT_ENABLE_GYROPSCOPIC_FORCE = 2 +}; + + +///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape. +///It is recommended for performance and memory use to share btCollisionShape objects whenever possible. +///There are 3 types of rigid bodies: +///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics. +///- B) Fixed objects with zero mass. They are not moving (basically collision objects) +///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform. +///Bullet automatically deactivates dynamic rigid bodies, when the velocity is below a threshold for a given time. +///Deactivated (sleeping) rigid bodies don't take any processing time, except a minor broadphase collision detection impact (to allow active objects to activate/wake up sleeping objects) +class btRigidBody : public btCollisionObject +{ + + btMatrix3x3 m_invInertiaTensorWorld; + btVector3 m_linearVelocity; + btVector3 m_angularVelocity; + btScalar m_inverseMass; + btVector3 m_linearFactor; + + btVector3 m_gravity; + btVector3 m_gravity_acceleration; + btVector3 m_invInertiaLocal; + btVector3 m_totalForce; + btVector3 m_totalTorque; + + btScalar m_linearDamping; + btScalar m_angularDamping; + + bool m_additionalDamping; + btScalar m_additionalDampingFactor; + btScalar m_additionalLinearDampingThresholdSqr; + btScalar m_additionalAngularDampingThresholdSqr; + btScalar m_additionalAngularDampingFactor; + + + btScalar m_linearSleepingThreshold; + btScalar m_angularSleepingThreshold; + + //m_optionalMotionState allows to automatic synchronize the world transform for active objects + btMotionState* m_optionalMotionState; + + //keep track of typed constraints referencing this rigid body + btAlignedObjectArray m_constraintRefs; + + int m_rigidbodyFlags; + + int m_debugBodyId; + + +protected: + + ATTRIBUTE_ALIGNED64(btVector3 m_deltaLinearVelocity); + btVector3 m_deltaAngularVelocity; + btVector3 m_angularFactor; + btVector3 m_invMass; + btVector3 m_pushVelocity; + btVector3 m_turnVelocity; + + +public: + + + ///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body. + ///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument) + ///You can use the motion state to synchronize the world transform between physics and graphics objects. + ///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state, + ///m_startWorldTransform is only used when you don't provide a motion state. + struct btRigidBodyConstructionInfo + { + btScalar m_mass; + + ///When a motionState is provided, the rigid body will initialize its world transform from the motion state + ///In this case, m_startWorldTransform is ignored. + btMotionState* m_motionState; + btTransform m_startWorldTransform; + + btCollisionShape* m_collisionShape; + btVector3 m_localInertia; + btScalar m_linearDamping; + btScalar m_angularDamping; + + ///best simulation results when friction is non-zero + btScalar m_friction; + ///the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling forever. + ///See Bullet/Demos/RollingFrictionDemo for usage + btScalar m_rollingFriction; + ///best simulation results using zero restitution. + btScalar m_restitution; + + btScalar m_linearSleepingThreshold; + btScalar m_angularSleepingThreshold; + + //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc. + //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete + bool m_additionalDamping; + btScalar m_additionalDampingFactor; + btScalar m_additionalLinearDampingThresholdSqr; + btScalar m_additionalAngularDampingThresholdSqr; + btScalar m_additionalAngularDampingFactor; + + btRigidBodyConstructionInfo( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)): + m_mass(mass), + m_motionState(motionState), + m_collisionShape(collisionShape), + m_localInertia(localInertia), + m_linearDamping(btScalar(0.)), + m_angularDamping(btScalar(0.)), + m_friction(btScalar(0.5)), + m_rollingFriction(btScalar(0)), + m_restitution(btScalar(0.)), + m_linearSleepingThreshold(btScalar(0.8)), + m_angularSleepingThreshold(btScalar(1.f)), + m_additionalDamping(false), + m_additionalDampingFactor(btScalar(0.005)), + m_additionalLinearDampingThresholdSqr(btScalar(0.01)), + m_additionalAngularDampingThresholdSqr(btScalar(0.01)), + m_additionalAngularDampingFactor(btScalar(0.01)) + { + m_startWorldTransform.setIdentity(); + } + }; + + ///btRigidBody constructor using construction info + btRigidBody( const btRigidBodyConstructionInfo& constructionInfo); + + ///btRigidBody constructor for backwards compatibility. + ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo) + btRigidBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)); + + + virtual ~btRigidBody() + { + //No constraints should point to this rigidbody + //Remove constraints from the dynamics world before you delete the related rigidbodies. + btAssert(m_constraintRefs.size()==0); + } + +protected: + + ///setupRigidBody is only used internally by the constructor + void setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo); + +public: + + void proceedToTransform(const btTransform& newTrans); + + ///to keep collision detection and dynamics separate we don't store a rigidbody pointer + ///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast + static const btRigidBody* upcast(const btCollisionObject* colObj) + { + if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY) + return (const btRigidBody*)colObj; + return 0; + } + static btRigidBody* upcast(btCollisionObject* colObj) + { + if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY) + return (btRigidBody*)colObj; + return 0; + } + + /// continuous collision detection needs prediction + void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ; + + void saveKinematicState(btScalar step); + + void applyGravity(); + + void setGravity(const btVector3& acceleration); + + const btVector3& getGravity() const + { + return m_gravity_acceleration; + } + + void setDamping(btScalar lin_damping, btScalar ang_damping); + + btScalar getLinearDamping() const + { + return m_linearDamping; + } + + btScalar getAngularDamping() const + { + return m_angularDamping; + } + + btScalar getLinearSleepingThreshold() const + { + return m_linearSleepingThreshold; + } + + btScalar getAngularSleepingThreshold() const + { + return m_angularSleepingThreshold; + } + + void applyDamping(btScalar timeStep); + + SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { + return m_collisionShape; + } + + SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() { + return m_collisionShape; + } + + void setMassProps(btScalar mass, const btVector3& inertia); + + const btVector3& getLinearFactor() const + { + return m_linearFactor; + } + void setLinearFactor(const btVector3& linearFactor) + { + m_linearFactor = linearFactor; + m_invMass = m_linearFactor*m_inverseMass; + } + btScalar getInvMass() const { return m_inverseMass; } + const btMatrix3x3& getInvInertiaTensorWorld() const { + return m_invInertiaTensorWorld; + } + + void integrateVelocities(btScalar step); + + void setCenterOfMassTransform(const btTransform& xform); + + void applyCentralForce(const btVector3& force) + { + m_totalForce += force*m_linearFactor; + } + + const btVector3& getTotalForce() const + { + return m_totalForce; + }; + + const btVector3& getTotalTorque() const + { + return m_totalTorque; + }; + + const btVector3& getInvInertiaDiagLocal() const + { + return m_invInertiaLocal; + }; + + void setInvInertiaDiagLocal(const btVector3& diagInvInertia) + { + m_invInertiaLocal = diagInvInertia; + } + + void setSleepingThresholds(btScalar linear,btScalar angular) + { + m_linearSleepingThreshold = linear; + m_angularSleepingThreshold = angular; + } + + void applyTorque(const btVector3& torque) + { + m_totalTorque += torque*m_angularFactor; + } + + void applyForce(const btVector3& force, const btVector3& rel_pos) + { + applyCentralForce(force); + applyTorque(rel_pos.cross(force*m_linearFactor)); + } + + void applyCentralImpulse(const btVector3& impulse) + { + m_linearVelocity += impulse *m_linearFactor * m_inverseMass; + } + + void applyTorqueImpulse(const btVector3& torque) + { + m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; + } + + void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) + { + if (m_inverseMass != btScalar(0.)) + { + applyCentralImpulse(impulse); + if (m_angularFactor) + { + applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor)); + } + } + } + + void clearForces() + { + m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + } + + void updateInertiaTensor(); + + const btVector3& getCenterOfMassPosition() const { + return m_worldTransform.getOrigin(); + } + btQuaternion getOrientation() const; + + const btTransform& getCenterOfMassTransform() const { + return m_worldTransform; + } + const btVector3& getLinearVelocity() const { + return m_linearVelocity; + } + const btVector3& getAngularVelocity() const { + return m_angularVelocity; + } + + + inline void setLinearVelocity(const btVector3& lin_vel) + { + m_linearVelocity = lin_vel; + } + + inline void setAngularVelocity(const btVector3& ang_vel) + { + m_angularVelocity = ang_vel; + } + + btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const + { + //we also calculate lin/ang velocity for kinematic objects + return m_linearVelocity + m_angularVelocity.cross(rel_pos); + + //for kinematic objects, we could also use use: + // return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep; + } + + void translate(const btVector3& v) + { + m_worldTransform.getOrigin() += v; + } + + + void getAabb(btVector3& aabbMin,btVector3& aabbMax) const; + + + + + + SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const + { + btVector3 r0 = pos - getCenterOfMassPosition(); + + btVector3 c0 = (r0).cross(normal); + + btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0); + + return m_inverseMass + normal.dot(vec); + + } + + SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const + { + btVector3 vec = axis * getInvInertiaTensorWorld(); + return axis.dot(vec); + } + + SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep) + { + if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION)) + return; + + if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) && + (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold)) + { + m_deactivationTime += timeStep; + } else + { + m_deactivationTime=btScalar(0.); + setActivationState(0); + } + + } + + SIMD_FORCE_INLINE bool wantsSleeping() + { + + if (getActivationState() == DISABLE_DEACTIVATION) + return false; + + //disable deactivation + if (gDisableDeactivation || (gDeactivationTime == btScalar(0.))) + return false; + + if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION)) + return true; + + if (m_deactivationTime> gDeactivationTime) + { + return true; + } + return false; + } + + + + const btBroadphaseProxy* getBroadphaseProxy() const + { + return m_broadphaseHandle; + } + btBroadphaseProxy* getBroadphaseProxy() + { + return m_broadphaseHandle; + } + void setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy) + { + m_broadphaseHandle = broadphaseProxy; + } + + //btMotionState allows to automatic synchronize the world transform for active objects + btMotionState* getMotionState() + { + return m_optionalMotionState; + } + const btMotionState* getMotionState() const + { + return m_optionalMotionState; + } + void setMotionState(btMotionState* motionState) + { + m_optionalMotionState = motionState; + if (m_optionalMotionState) + motionState->getWorldTransform(m_worldTransform); + } + + //for experimental overriding of friction/contact solver func + int m_contactSolverType; + int m_frictionSolverType; + + void setAngularFactor(const btVector3& angFac) + { + m_angularFactor = angFac; + } + + void setAngularFactor(btScalar angFac) + { + m_angularFactor.setValue(angFac,angFac,angFac); + } + const btVector3& getAngularFactor() const + { + return m_angularFactor; + } + + //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase? + bool isInWorld() const + { + return (getBroadphaseProxy() != 0); + } + + virtual bool checkCollideWithOverride(const btCollisionObject* co) const; + + void addConstraintRef(btTypedConstraint* c); + void removeConstraintRef(btTypedConstraint* c); + + btTypedConstraint* getConstraintRef(int index) + { + return m_constraintRefs[index]; + } + + int getNumConstraintRefs() const + { + return m_constraintRefs.size(); + } + + void setFlags(int flags) + { + m_rigidbodyFlags = flags; + } + + int getFlags() const + { + return m_rigidbodyFlags; + } + + btVector3 computeGyroscopicForce(btScalar maxGyroscopicForce) const; + + /////////////////////////////////////////////// + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; + + virtual void serializeSingleObject(class btSerializer* serializer) const; + +}; + +//@todo add m_optionalMotionState and m_constraintRefs to btRigidBodyData +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btRigidBodyFloatData +{ + btCollisionObjectFloatData m_collisionObjectData; + btMatrix3x3FloatData m_invInertiaTensorWorld; + btVector3FloatData m_linearVelocity; + btVector3FloatData m_angularVelocity; + btVector3FloatData m_angularFactor; + btVector3FloatData m_linearFactor; + btVector3FloatData m_gravity; + btVector3FloatData m_gravity_acceleration; + btVector3FloatData m_invInertiaLocal; + btVector3FloatData m_totalForce; + btVector3FloatData m_totalTorque; + float m_inverseMass; + float m_linearDamping; + float m_angularDamping; + float m_additionalDampingFactor; + float m_additionalLinearDampingThresholdSqr; + float m_additionalAngularDampingThresholdSqr; + float m_additionalAngularDampingFactor; + float m_linearSleepingThreshold; + float m_angularSleepingThreshold; + int m_additionalDamping; +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btRigidBodyDoubleData +{ + btCollisionObjectDoubleData m_collisionObjectData; + btMatrix3x3DoubleData m_invInertiaTensorWorld; + btVector3DoubleData m_linearVelocity; + btVector3DoubleData m_angularVelocity; + btVector3DoubleData m_angularFactor; + btVector3DoubleData m_linearFactor; + btVector3DoubleData m_gravity; + btVector3DoubleData m_gravity_acceleration; + btVector3DoubleData m_invInertiaLocal; + btVector3DoubleData m_totalForce; + btVector3DoubleData m_totalTorque; + double m_inverseMass; + double m_linearDamping; + double m_angularDamping; + double m_additionalDampingFactor; + double m_additionalLinearDampingThresholdSqr; + double m_additionalAngularDampingThresholdSqr; + double m_additionalAngularDampingFactor; + double m_linearSleepingThreshold; + double m_angularSleepingThreshold; + int m_additionalDamping; + char m_padding[4]; +}; + + + +#endif //BT_RIGIDBODY_H + diff --git a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp new file mode 100644 index 0000000..5fc2f3c --- /dev/null +++ b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp @@ -0,0 +1,280 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSimpleDynamicsWorld.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" + + +/* + Make sure this dummy function never changes so that it + can be used by probes that are checking whether the + library is actually installed. +*/ +extern "C" +{ + void btBulletDynamicsProbe (); + void btBulletDynamicsProbe () {} +} + + + + +btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) +:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), +m_constraintSolver(constraintSolver), +m_ownsConstraintSolver(false), +m_gravity(0,0,-10) +{ + +} + + +btSimpleDynamicsWorld::~btSimpleDynamicsWorld() +{ + if (m_ownsConstraintSolver) + btAlignedFree( m_constraintSolver); +} + +int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) +{ + (void)fixedTimeStep; + (void)maxSubSteps; + + + ///apply gravity, predict motion + predictUnconstraintMotion(timeStep); + + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_debugDraw = getDebugDrawer(); + + ///perform collision detection + performDiscreteCollisionDetection(); + + ///solve contact constraints + int numManifolds = m_dispatcher1->getNumManifolds(); + if (numManifolds) + { + btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer(); + + btContactSolverInfo infoGlobal; + infoGlobal.m_timeStep = timeStep; + m_constraintSolver->prepareSolve(0,numManifolds); + m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc,m_dispatcher1); + m_constraintSolver->allSolved(infoGlobal,m_debugDrawer, m_stackAlloc); + } + + ///integrate transforms + integrateTransforms(timeStep); + + updateAabbs(); + + synchronizeMotionStates(); + + clearForces(); + + return 1; + +} + +void btSimpleDynamicsWorld::clearForces() +{ + ///@todo: iterate over awake simulation islands! + for ( int i=0;iclearForces(); + } + } +} + + +void btSimpleDynamicsWorld::setGravity(const btVector3& gravity) +{ + m_gravity = gravity; + for ( int i=0;isetGravity(gravity); + } + } +} + +btVector3 btSimpleDynamicsWorld::getGravity () const +{ + return m_gravity; +} + +void btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body) +{ + btCollisionWorld::removeCollisionObject(body); +} + +void btSimpleDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) +{ + btRigidBody* body = btRigidBody::upcast(collisionObject); + if (body) + removeRigidBody(body); + else + btCollisionWorld::removeCollisionObject(collisionObject); +} + + +void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body) +{ + body->setGravity(m_gravity); + + if (body->getCollisionShape()) + { + addCollisionObject(body); + } +} + +void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask) +{ + body->setGravity(m_gravity); + + if (body->getCollisionShape()) + { + addCollisionObject(body,group,mask); + } +} + + +void btSimpleDynamicsWorld::debugDrawWorld() +{ + +} + +void btSimpleDynamicsWorld::addAction(btActionInterface* action) +{ + +} + +void btSimpleDynamicsWorld::removeAction(btActionInterface* action) +{ + +} + + +void btSimpleDynamicsWorld::updateAabbs() +{ + btTransform predictedTrans; + for ( int i=0;iisActive() && (!body->isStaticObject())) + { + btVector3 minAabb,maxAabb; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); + btBroadphaseInterface* bp = getBroadphase(); + bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); + } + } + } +} + +void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep) +{ + btTransform predictedTrans; + for ( int i=0;iisActive() && (!body->isStaticObject())) + { + body->predictIntegratedTransform(timeStep, predictedTrans); + body->proceedToTransform( predictedTrans); + } + } + } +} + + + +void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +{ + for ( int i=0;iisStaticObject()) + { + if (body->isActive()) + { + body->applyGravity(); + body->integrateVelocities( timeStep); + body->applyDamping(timeStep); + body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); + } + } + } + } +} + + +void btSimpleDynamicsWorld::synchronizeMotionStates() +{ + ///@todo: iterate over awake simulation islands! + for ( int i=0;igetMotionState()) + { + if (body->getActivationState() != ISLAND_SLEEPING) + { + body->getMotionState()->setWorldTransform(body->getWorldTransform()); + } + } + } + +} + + +void btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) +{ + if (m_ownsConstraintSolver) + { + btAlignedFree(m_constraintSolver); + } + m_ownsConstraintSolver = false; + m_constraintSolver = solver; +} + +btConstraintSolver* btSimpleDynamicsWorld::getConstraintSolver() +{ + return m_constraintSolver; +} diff --git a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h new file mode 100644 index 0000000..d48d2e3 --- /dev/null +++ b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h @@ -0,0 +1,89 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SIMPLE_DYNAMICS_WORLD_H +#define BT_SIMPLE_DYNAMICS_WORLD_H + +#include "btDynamicsWorld.h" + +class btDispatcher; +class btOverlappingPairCache; +class btConstraintSolver; + +///The btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds. +///Please use btDiscreteDynamicsWorld instead +class btSimpleDynamicsWorld : public btDynamicsWorld +{ +protected: + + btConstraintSolver* m_constraintSolver; + + bool m_ownsConstraintSolver; + + void predictUnconstraintMotion(btScalar timeStep); + + void integrateTransforms(btScalar timeStep); + + btVector3 m_gravity; + +public: + + + + ///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver + btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + + virtual ~btSimpleDynamicsWorld(); + + ///maxSubSteps/fixedTimeStep for interpolation is currently ignored for btSimpleDynamicsWorld, use btDiscreteDynamicsWorld instead + virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); + + virtual void setGravity(const btVector3& gravity); + + virtual btVector3 getGravity () const; + + virtual void addRigidBody(btRigidBody* body); + + virtual void addRigidBody(btRigidBody* body, short group, short mask); + + virtual void removeRigidBody(btRigidBody* body); + + virtual void debugDrawWorld(); + + virtual void addAction(btActionInterface* action); + + virtual void removeAction(btActionInterface* action); + + ///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject + virtual void removeCollisionObject(btCollisionObject* collisionObject); + + virtual void updateAabbs(); + + virtual void synchronizeMotionStates(); + + virtual void setConstraintSolver(btConstraintSolver* solver); + + virtual btConstraintSolver* getConstraintSolver(); + + virtual btDynamicsWorldType getWorldType() const + { + return BT_SIMPLE_DYNAMICS_WORLD; + } + + virtual void clearForces(); + +}; + +#endif //BT_SIMPLE_DYNAMICS_WORLD_H diff --git a/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp new file mode 100644 index 0000000..77b475b --- /dev/null +++ b/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp @@ -0,0 +1,771 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "LinearMath/btVector3.h" +#include "btRaycastVehicle.h" + +#include "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h" +#include "BulletDynamics/ConstraintSolver/btJacobianEntry.h" +#include "LinearMath/btQuaternion.h" +#include "BulletDynamics/Dynamics/btDynamicsWorld.h" +#include "btVehicleRaycaster.h" +#include "btWheelInfo.h" +#include "LinearMath/btMinMax.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" + +#define ROLLING_INFLUENCE_FIX + + +btRigidBody& btActionInterface::getFixedBody() +{ + static btRigidBody s_fixed(0, 0,0); + s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + return s_fixed; +} + +btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ) +:m_vehicleRaycaster(raycaster), +m_pitchControl(btScalar(0.)) +{ + m_chassisBody = chassis; + m_indexRightAxis = 0; + m_indexUpAxis = 2; + m_indexForwardAxis = 1; + defaultInit(tuning); +} + + +void btRaycastVehicle::defaultInit(const btVehicleTuning& tuning) +{ + (void)tuning; + m_currentVehicleSpeedKmHour = btScalar(0.); + m_steeringValue = btScalar(0.); + +} + + + +btRaycastVehicle::~btRaycastVehicle() +{ +} + + +// +// basically most of the code is general for 2 or 4 wheel vehicles, but some of it needs to be reviewed +// +btWheelInfo& btRaycastVehicle::addWheel( const btVector3& connectionPointCS, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel) +{ + + btWheelInfoConstructionInfo ci; + + ci.m_chassisConnectionCS = connectionPointCS; + ci.m_wheelDirectionCS = wheelDirectionCS0; + ci.m_wheelAxleCS = wheelAxleCS; + ci.m_suspensionRestLength = suspensionRestLength; + ci.m_wheelRadius = wheelRadius; + ci.m_suspensionStiffness = tuning.m_suspensionStiffness; + ci.m_wheelsDampingCompression = tuning.m_suspensionCompression; + ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping; + ci.m_frictionSlip = tuning.m_frictionSlip; + ci.m_bIsFrontWheel = isFrontWheel; + ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm; + ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce; + + m_wheelInfo.push_back( btWheelInfo(ci)); + + btWheelInfo& wheel = m_wheelInfo[getNumWheels()-1]; + + updateWheelTransformsWS( wheel , false ); + updateWheelTransform(getNumWheels()-1,false); + return wheel; +} + + + + +const btTransform& btRaycastVehicle::getWheelTransformWS( int wheelIndex ) const +{ + btAssert(wheelIndex < getNumWheels()); + const btWheelInfo& wheel = m_wheelInfo[wheelIndex]; + return wheel.m_worldTransform; + +} + +void btRaycastVehicle::updateWheelTransform( int wheelIndex , bool interpolatedTransform) +{ + + btWheelInfo& wheel = m_wheelInfo[ wheelIndex ]; + updateWheelTransformsWS(wheel,interpolatedTransform); + btVector3 up = -wheel.m_raycastInfo.m_wheelDirectionWS; + const btVector3& right = wheel.m_raycastInfo.m_wheelAxleWS; + btVector3 fwd = up.cross(right); + fwd = fwd.normalize(); +// up = right.cross(fwd); +// up.normalize(); + + //rotate around steering over de wheelAxleWS + btScalar steering = wheel.m_steering; + + btQuaternion steeringOrn(up,steering);//wheel.m_steering); + btMatrix3x3 steeringMat(steeringOrn); + + btQuaternion rotatingOrn(right,-wheel.m_rotation); + btMatrix3x3 rotatingMat(rotatingOrn); + + btMatrix3x3 basis2( + right[0],fwd[0],up[0], + right[1],fwd[1],up[1], + right[2],fwd[2],up[2] + ); + + wheel.m_worldTransform.setBasis(steeringMat * rotatingMat * basis2); + wheel.m_worldTransform.setOrigin( + wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength + ); +} + +void btRaycastVehicle::resetSuspension() +{ + + int i; + for (i=0;igetMotionState())) + { + getRigidBody()->getMotionState()->getWorldTransform(chassisTrans); + } + + wheel.m_raycastInfo.m_hardPointWS = chassisTrans( wheel.m_chassisConnectionPointCS ); + wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() * wheel.m_wheelDirectionCS ; + wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.getBasis() * wheel.m_wheelAxleCS; +} + +btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) +{ + updateWheelTransformsWS( wheel,false); + + + btScalar depth = -1; + + btScalar raylen = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius; + + btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen); + const btVector3& source = wheel.m_raycastInfo.m_hardPointWS; + wheel.m_raycastInfo.m_contactPointWS = source + rayvector; + const btVector3& target = wheel.m_raycastInfo.m_contactPointWS; + + btScalar param = btScalar(0.); + + btVehicleRaycaster::btVehicleRaycasterResult rayResults; + + btAssert(m_vehicleRaycaster); + + void* object = m_vehicleRaycaster->castRay(source,target,rayResults); + + wheel.m_raycastInfo.m_groundObject = 0; + + if (object) + { + param = rayResults.m_distFraction; + depth = raylen * rayResults.m_distFraction; + wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld; + wheel.m_raycastInfo.m_isInContact = true; + + wheel.m_raycastInfo.m_groundObject = &getFixedBody();///@todo for driving on dynamic/movable objects!; + //wheel.m_raycastInfo.m_groundObject = object; + + + btScalar hitDistance = param*raylen; + wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius; + //clamp on max suspension travel + + btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01); + btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01); + if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) + { + wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength; + } + if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength) + { + wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength; + } + + wheel.m_raycastInfo.m_contactPointWS = rayResults.m_hitPointInWorld; + + btScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS ); + + btVector3 chassis_velocity_at_contactPoint; + btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-getRigidBody()->getCenterOfMassPosition(); + + chassis_velocity_at_contactPoint = getRigidBody()->getVelocityInLocalPoint(relpos); + + btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); + + if ( denominator >= btScalar(-0.1)) + { + wheel.m_suspensionRelativeVelocity = btScalar(0.0); + wheel.m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); + } + else + { + btScalar inv = btScalar(-1.) / denominator; + wheel.m_suspensionRelativeVelocity = projVel * inv; + wheel.m_clippedInvContactDotSuspension = inv; + } + + } else + { + //put wheel info as in rest position + wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength(); + wheel.m_suspensionRelativeVelocity = btScalar(0.0); + wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS; + wheel.m_clippedInvContactDotSuspension = btScalar(1.0); + } + + return depth; +} + + +const btTransform& btRaycastVehicle::getChassisWorldTransform() const +{ + /*if (getRigidBody()->getMotionState()) + { + btTransform chassisWorldTrans; + getRigidBody()->getMotionState()->getWorldTransform(chassisWorldTrans); + return chassisWorldTrans; + } + */ + + + return getRigidBody()->getCenterOfMassTransform(); +} + + +void btRaycastVehicle::updateVehicle( btScalar step ) +{ + { + for (int i=0;igetLinearVelocity().length(); + + const btTransform& chassisTrans = getChassisWorldTransform(); + + btVector3 forwardW ( + chassisTrans.getBasis()[0][m_indexForwardAxis], + chassisTrans.getBasis()[1][m_indexForwardAxis], + chassisTrans.getBasis()[2][m_indexForwardAxis]); + + if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.)) + { + m_currentVehicleSpeedKmHour *= btScalar(-1.); + } + + // + // simulate suspension + // + + int i=0; + for (i=0;i wheel.m_maxSuspensionForce) + { + suspensionForce = wheel.m_maxSuspensionForce; + } + btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; + btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); + + getRigidBody()->applyImpulse(impulse, relpos); + + } + + + + updateFriction( step); + + + for (i=0;igetCenterOfMassPosition(); + btVector3 vel = getRigidBody()->getVelocityInLocalPoint( relpos ); + + if (wheel.m_raycastInfo.m_isInContact) + { + const btTransform& chassisWorldTransform = getChassisWorldTransform(); + + btVector3 fwd ( + chassisWorldTransform.getBasis()[0][m_indexForwardAxis], + chassisWorldTransform.getBasis()[1][m_indexForwardAxis], + chassisWorldTransform.getBasis()[2][m_indexForwardAxis]); + + btScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS); + fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; + + btScalar proj2 = fwd.dot(vel); + + wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius); + wheel.m_rotation += wheel.m_deltaRotation; + + } else + { + wheel.m_rotation += wheel.m_deltaRotation; + } + + wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact + + } + + + +} + + +void btRaycastVehicle::setSteeringValue(btScalar steering,int wheel) +{ + btAssert(wheel>=0 && wheel < getNumWheels()); + + btWheelInfo& wheelInfo = getWheelInfo(wheel); + wheelInfo.m_steering = steering; +} + + + +btScalar btRaycastVehicle::getSteeringValue(int wheel) const +{ + return getWheelInfo(wheel).m_steering; +} + + +void btRaycastVehicle::applyEngineForce(btScalar force, int wheel) +{ + btAssert(wheel>=0 && wheel < getNumWheels()); + btWheelInfo& wheelInfo = getWheelInfo(wheel); + wheelInfo.m_engineForce = force; +} + + +const btWheelInfo& btRaycastVehicle::getWheelInfo(int index) const +{ + btAssert((index >= 0) && (index < getNumWheels())); + + return m_wheelInfo[index]; +} + +btWheelInfo& btRaycastVehicle::getWheelInfo(int index) +{ + btAssert((index >= 0) && (index < getNumWheels())); + + return m_wheelInfo[index]; +} + +void btRaycastVehicle::setBrake(btScalar brake,int wheelIndex) +{ + btAssert((wheelIndex >= 0) && (wheelIndex < getNumWheels())); + getWheelInfo(wheelIndex).m_brake = brake; +} + + +void btRaycastVehicle::updateSuspension(btScalar deltaTime) +{ + (void)deltaTime; + + btScalar chassisMass = btScalar(1.) / m_chassisBody->getInvMass(); + + for (int w_it=0; w_itcomputeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); + btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); + btScalar relaxation = 1.f; + m_jacDiagABInv = relaxation/(denom0+denom1); + } + + + +}; + +btScalar calcRollingFriction(btWheelContactPoint& contactPoint); +btScalar calcRollingFriction(btWheelContactPoint& contactPoint) +{ + + btScalar j1=0.f; + + const btVector3& contactPosWorld = contactPoint.m_frictionPositionWorld; + + btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition(); + btVector3 rel_pos2 = contactPosWorld - contactPoint.m_body1->getCenterOfMassPosition(); + + btScalar maxImpulse = contactPoint.m_maxImpulse; + + btVector3 vel1 = contactPoint.m_body0->getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = contactPoint.m_body1->getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar vrel = contactPoint.m_frictionDirectionWorld.dot(vel); + + // calculate j that moves us to zero relative velocity + j1 = -vrel * contactPoint.m_jacDiagABInv; + btSetMin(j1, maxImpulse); + btSetMax(j1, -maxImpulse); + + return j1; +} + + + + +btScalar sideFrictionStiffness2 = btScalar(1.0); +void btRaycastVehicle::updateFriction(btScalar timeStep) +{ + + //calculate the impulse, so that the wheels don't move sidewards + int numWheel = getNumWheels(); + if (!numWheel) + return; + + m_forwardWS.resize(numWheel); + m_axle.resize(numWheel); + m_forwardImpulse.resize(numWheel); + m_sideImpulse.resize(numWheel); + + int numWheelsOnGround = 0; + + + //collapse all those loops into one! + for (int i=0;i maximpSquared) + { + sliding = true; + + btScalar factor = maximp / btSqrt(impulseSquared); + + m_wheelInfo[wheel].m_skidInfo *= factor; + } + } + + } + } + + + + + if (sliding) + { + for (int wheel = 0;wheel < getNumWheels(); wheel++) + { + if (m_sideImpulse[wheel] != btScalar(0.)) + { + if (m_wheelInfo[wheel].m_skidInfo< btScalar(1.)) + { + m_forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; + m_sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; + } + } + } + } + + // apply the impulses + { + for (int wheel = 0;wheelgetCenterOfMassPosition(); + + if (m_forwardImpulse[wheel] != btScalar(0.)) + { + m_chassisBody->applyImpulse(m_forwardWS[wheel]*(m_forwardImpulse[wheel]),rel_pos); + } + if (m_sideImpulse[wheel] != btScalar(0.)) + { + class btRigidBody* groundObject = (class btRigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject; + + btVector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS - + groundObject->getCenterOfMassPosition(); + + + btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel]; + +#if defined ROLLING_INFLUENCE_FIX // fix. It only worked if car's up was along Y - VT. + btVector3 vChassisWorldUp = getRigidBody()->getCenterOfMassTransform().getBasis().getColumn(m_indexUpAxis); + rel_pos -= vChassisWorldUp * (vChassisWorldUp.dot(rel_pos) * (1.f-wheelInfo.m_rollInfluence)); +#else + rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence; +#endif + m_chassisBody->applyImpulse(sideImp,rel_pos); + + //apply friction impulse on the ground + groundObject->applyImpulse(-sideImp,rel_pos2); + } + } + } + + +} + + + +void btRaycastVehicle::debugDraw(btIDebugDraw* debugDrawer) +{ + + for (int v=0;vgetNumWheels();v++) + { + btVector3 wheelColor(0,1,1); + if (getWheelInfo(v).m_raycastInfo.m_isInContact) + { + wheelColor.setValue(0,0,1); + } else + { + wheelColor.setValue(1,0,1); + } + + btVector3 wheelPosWS = getWheelInfo(v).m_worldTransform.getOrigin(); + + btVector3 axle = btVector3( + getWheelInfo(v).m_worldTransform.getBasis()[0][getRightAxis()], + getWheelInfo(v).m_worldTransform.getBasis()[1][getRightAxis()], + getWheelInfo(v).m_worldTransform.getBasis()[2][getRightAxis()]); + + //debug wheels (cylinders) + debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor); + debugDrawer->drawLine(wheelPosWS,getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor); + + } +} + + +void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) +{ +// RayResultCallback& resultCallback; + + btCollisionWorld::ClosestRayResultCallback rayCallback(from,to); + + m_dynamicsWorld->rayTest(from, to, rayCallback); + + if (rayCallback.hasHit()) + { + + const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); + if (body && body->hasContactResponse()) + { + result.m_hitPointInWorld = rayCallback.m_hitPointWorld; + result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; + result.m_hitNormalInWorld.normalize(); + result.m_distFraction = rayCallback.m_closestHitFraction; + return (void*)body; + } + } + return 0; +} + diff --git a/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/src/BulletDynamics/Vehicle/btRaycastVehicle.h new file mode 100644 index 0000000..f59555f --- /dev/null +++ b/src/BulletDynamics/Vehicle/btRaycastVehicle.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef BT_RAYCASTVEHICLE_H +#define BT_RAYCASTVEHICLE_H + +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "btVehicleRaycaster.h" +class btDynamicsWorld; +#include "LinearMath/btAlignedObjectArray.h" +#include "btWheelInfo.h" +#include "BulletDynamics/Dynamics/btActionInterface.h" + +class btVehicleTuning; + +///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle. +class btRaycastVehicle : public btActionInterface +{ + + btAlignedObjectArray m_forwardWS; + btAlignedObjectArray m_axle; + btAlignedObjectArray m_forwardImpulse; + btAlignedObjectArray m_sideImpulse; + + ///backwards compatibility + int m_userConstraintType; + int m_userConstraintId; + +public: + class btVehicleTuning + { + public: + + btVehicleTuning() + :m_suspensionStiffness(btScalar(5.88)), + m_suspensionCompression(btScalar(0.83)), + m_suspensionDamping(btScalar(0.88)), + m_maxSuspensionTravelCm(btScalar(500.)), + m_frictionSlip(btScalar(10.5)), + m_maxSuspensionForce(btScalar(6000.)) + { + } + btScalar m_suspensionStiffness; + btScalar m_suspensionCompression; + btScalar m_suspensionDamping; + btScalar m_maxSuspensionTravelCm; + btScalar m_frictionSlip; + btScalar m_maxSuspensionForce; + + }; +private: + + btScalar m_tau; + btScalar m_damping; + btVehicleRaycaster* m_vehicleRaycaster; + btScalar m_pitchControl; + btScalar m_steeringValue; + btScalar m_currentVehicleSpeedKmHour; + + btRigidBody* m_chassisBody; + + int m_indexRightAxis; + int m_indexUpAxis; + int m_indexForwardAxis; + + void defaultInit(const btVehicleTuning& tuning); + +public: + + //constructor to create a car from an existing rigidbody + btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ); + + virtual ~btRaycastVehicle() ; + + + ///btActionInterface interface + virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step) + { + (void) collisionWorld; + updateVehicle(step); + } + + + ///btActionInterface interface + void debugDraw(btIDebugDraw* debugDrawer); + + const btTransform& getChassisWorldTransform() const; + + btScalar rayCast(btWheelInfo& wheel); + + virtual void updateVehicle(btScalar step); + + + void resetSuspension(); + + btScalar getSteeringValue(int wheel) const; + + void setSteeringValue(btScalar steering,int wheel); + + + void applyEngineForce(btScalar force, int wheel); + + const btTransform& getWheelTransformWS( int wheelIndex ) const; + + void updateWheelTransform( int wheelIndex, bool interpolatedTransform = true ); + +// void setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth); + + btWheelInfo& addWheel( const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS,btScalar suspensionRestLength,btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel); + + inline int getNumWheels() const { + return int (m_wheelInfo.size()); + } + + btAlignedObjectArray m_wheelInfo; + + + const btWheelInfo& getWheelInfo(int index) const; + + btWheelInfo& getWheelInfo(int index); + + void updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform = true); + + + void setBrake(btScalar brake,int wheelIndex); + + void setPitchControl(btScalar pitch) + { + m_pitchControl = pitch; + } + + void updateSuspension(btScalar deltaTime); + + virtual void updateFriction(btScalar timeStep); + + + + inline btRigidBody* getRigidBody() + { + return m_chassisBody; + } + + const btRigidBody* getRigidBody() const + { + return m_chassisBody; + } + + inline int getRightAxis() const + { + return m_indexRightAxis; + } + inline int getUpAxis() const + { + return m_indexUpAxis; + } + + inline int getForwardAxis() const + { + return m_indexForwardAxis; + } + + + ///Worldspace forward vector + btVector3 getForwardVector() const + { + const btTransform& chassisTrans = getChassisWorldTransform(); + + btVector3 forwardW ( + chassisTrans.getBasis()[0][m_indexForwardAxis], + chassisTrans.getBasis()[1][m_indexForwardAxis], + chassisTrans.getBasis()[2][m_indexForwardAxis]); + + return forwardW; + } + + ///Velocity of vehicle (positive if velocity vector has same direction as foward vector) + btScalar getCurrentSpeedKmHour() const + { + return m_currentVehicleSpeedKmHour; + } + + virtual void setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) + { + m_indexRightAxis = rightIndex; + m_indexUpAxis = upIndex; + m_indexForwardAxis = forwardIndex; + } + + + ///backwards compatibility + int getUserConstraintType() const + { + return m_userConstraintType ; + } + + void setUserConstraintType(int userConstraintType) + { + m_userConstraintType = userConstraintType; + }; + + void setUserConstraintId(int uid) + { + m_userConstraintId = uid; + } + + int getUserConstraintId() const + { + return m_userConstraintId; + } + +}; + +class btDefaultVehicleRaycaster : public btVehicleRaycaster +{ + btDynamicsWorld* m_dynamicsWorld; +public: + btDefaultVehicleRaycaster(btDynamicsWorld* world) + :m_dynamicsWorld(world) + { + } + + virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result); + +}; + + +#endif //BT_RAYCASTVEHICLE_H + diff --git a/src/BulletDynamics/Vehicle/btVehicleRaycaster.h b/src/BulletDynamics/Vehicle/btVehicleRaycaster.h new file mode 100644 index 0000000..3cc909c --- /dev/null +++ b/src/BulletDynamics/Vehicle/btVehicleRaycaster.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://bulletphysics.org + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef BT_VEHICLE_RAYCASTER_H +#define BT_VEHICLE_RAYCASTER_H + +#include "LinearMath/btVector3.h" + +/// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting +struct btVehicleRaycaster +{ +virtual ~btVehicleRaycaster() +{ +} + struct btVehicleRaycasterResult + { + btVehicleRaycasterResult() :m_distFraction(btScalar(-1.)){}; + btVector3 m_hitPointInWorld; + btVector3 m_hitNormalInWorld; + btScalar m_distFraction; + }; + + virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) = 0; + +}; + +#endif //BT_VEHICLE_RAYCASTER_H + diff --git a/src/BulletDynamics/Vehicle/btWheelInfo.cpp b/src/BulletDynamics/Vehicle/btWheelInfo.cpp new file mode 100644 index 0000000..ef93c16 --- /dev/null +++ b/src/BulletDynamics/Vehicle/btWheelInfo.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "btWheelInfo.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" // for pointvelocity + + +btScalar btWheelInfo::getSuspensionRestLength() const +{ + + return m_suspensionRestLength1; + +} + +void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo) +{ + (void)raycastInfo; + + + if (m_raycastInfo.m_isInContact) + + { + btScalar project= m_raycastInfo.m_contactNormalWS.dot( m_raycastInfo.m_wheelDirectionWS ); + btVector3 chassis_velocity_at_contactPoint; + btVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.getCenterOfMassPosition(); + chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint( relpos ); + btScalar projVel = m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); + if ( project >= btScalar(-0.1)) + { + m_suspensionRelativeVelocity = btScalar(0.0); + m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); + } + else + { + btScalar inv = btScalar(-1.) / project; + m_suspensionRelativeVelocity = projVel * inv; + m_clippedInvContactDotSuspension = inv; + } + + } + + else // Not in contact : position wheel in a nice (rest length) position + { + m_raycastInfo.m_suspensionLength = this->getSuspensionRestLength(); + m_suspensionRelativeVelocity = btScalar(0.0); + m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS; + m_clippedInvContactDotSuspension = btScalar(1.0); + } +} diff --git a/src/BulletDynamics/Vehicle/btWheelInfo.h b/src/BulletDynamics/Vehicle/btWheelInfo.h new file mode 100644 index 0000000..f916053 --- /dev/null +++ b/src/BulletDynamics/Vehicle/btWheelInfo.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef BT_WHEEL_INFO_H +#define BT_WHEEL_INFO_H + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" + +class btRigidBody; + +struct btWheelInfoConstructionInfo +{ + btVector3 m_chassisConnectionCS; + btVector3 m_wheelDirectionCS; + btVector3 m_wheelAxleCS; + btScalar m_suspensionRestLength; + btScalar m_maxSuspensionTravelCm; + btScalar m_wheelRadius; + + btScalar m_suspensionStiffness; + btScalar m_wheelsDampingCompression; + btScalar m_wheelsDampingRelaxation; + btScalar m_frictionSlip; + btScalar m_maxSuspensionForce; + bool m_bIsFrontWheel; + +}; + +/// btWheelInfo contains information per wheel about friction and suspension. +struct btWheelInfo +{ + struct RaycastInfo + { + //set by raycaster + btVector3 m_contactNormalWS;//contactnormal + btVector3 m_contactPointWS;//raycast hitpoint + btScalar m_suspensionLength; + btVector3 m_hardPointWS;//raycast starting point + btVector3 m_wheelDirectionWS; //direction in worldspace + btVector3 m_wheelAxleWS; // axle in worldspace + bool m_isInContact; + void* m_groundObject; //could be general void* ptr + }; + + RaycastInfo m_raycastInfo; + + btTransform m_worldTransform; + + btVector3 m_chassisConnectionPointCS; //const + btVector3 m_wheelDirectionCS;//const + btVector3 m_wheelAxleCS; // const or modified by steering + btScalar m_suspensionRestLength1;//const + btScalar m_maxSuspensionTravelCm; + btScalar getSuspensionRestLength() const; + btScalar m_wheelsRadius;//const + btScalar m_suspensionStiffness;//const + btScalar m_wheelsDampingCompression;//const + btScalar m_wheelsDampingRelaxation;//const + btScalar m_frictionSlip; + btScalar m_steering; + btScalar m_rotation; + btScalar m_deltaRotation; + btScalar m_rollInfluence; + btScalar m_maxSuspensionForce; + + btScalar m_engineForce; + + btScalar m_brake; + + bool m_bIsFrontWheel; + + void* m_clientInfo;//can be used to store pointer to sync transforms... + + btWheelInfo(btWheelInfoConstructionInfo& ci) + + { + + m_suspensionRestLength1 = ci.m_suspensionRestLength; + m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm; + + m_wheelsRadius = ci.m_wheelRadius; + m_suspensionStiffness = ci.m_suspensionStiffness; + m_wheelsDampingCompression = ci.m_wheelsDampingCompression; + m_wheelsDampingRelaxation = ci.m_wheelsDampingRelaxation; + m_chassisConnectionPointCS = ci.m_chassisConnectionCS; + m_wheelDirectionCS = ci.m_wheelDirectionCS; + m_wheelAxleCS = ci.m_wheelAxleCS; + m_frictionSlip = ci.m_frictionSlip; + m_steering = btScalar(0.); + m_engineForce = btScalar(0.); + m_rotation = btScalar(0.); + m_deltaRotation = btScalar(0.); + m_brake = btScalar(0.); + m_rollInfluence = btScalar(0.1); + m_bIsFrontWheel = ci.m_bIsFrontWheel; + m_maxSuspensionForce = ci.m_maxSuspensionForce; + + } + + void updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo); + + btScalar m_clippedInvContactDotSuspension; + btScalar m_suspensionRelativeVelocity; + //calculated by suspension + btScalar m_wheelsSuspensionForce; + btScalar m_skidInfo; + +}; + +#endif //BT_WHEEL_INFO_H + diff --git a/src/BulletDynamics/premake4.lua b/src/BulletDynamics/premake4.lua new file mode 100644 index 0000000..9af6d3a --- /dev/null +++ b/src/BulletDynamics/premake4.lua @@ -0,0 +1,11 @@ + project "BulletDynamics" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + "..", + } + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/src/BulletMultiThreaded/CMakeLists.txt b/src/BulletMultiThreaded/CMakeLists.txt new file mode 100644 index 0000000..6eeeb6d --- /dev/null +++ b/src/BulletMultiThreaded/CMakeLists.txt @@ -0,0 +1,123 @@ +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${VECTOR_MATH_INCLUDE} +) + +SET(BulletMultiThreaded_SRCS + SpuFakeDma.cpp + SpuLibspe2Support.cpp + btThreadSupportInterface.cpp + Win32ThreadSupport.cpp + PosixThreadSupport.cpp + SequentialThreadSupport.cpp + SpuSampleTaskProcess.cpp + SpuCollisionObjectWrapper.cpp + SpuCollisionTaskProcess.cpp + SpuGatheringCollisionDispatcher.cpp + SpuContactManifoldCollisionAlgorithm.cpp + btParallelConstraintSolver.cpp + + #SPURS_PEGatherScatterTask/SpuPEGatherScatterTask.cpp + #SpuPEGatherScatterTaskProcess.cpp + + SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp + SpuNarrowPhaseCollisionTask/SpuContactResult.cpp + SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp + SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp + SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp + + #Some GPU related stuff, mainly CUDA and perhaps OpenCL + btGpu3DGridBroadphase.cpp +) + +SET(Root_HDRS + PlatformDefinitions.h + PpuAddressSpace.h + SpuFakeDma.h + SpuDoubleBuffer.h + SpuLibspe2Support.h + btThreadSupportInterface.h + Win32ThreadSupport.h + PosixThreadSupport.h + SequentialThreadSupport.h + SpuSampleTaskProcess.h + SpuCollisionObjectWrapper.cpp + SpuCollisionObjectWrapper.h + SpuCollisionTaskProcess.h + SpuGatheringCollisionDispatcher.h + SpuContactManifoldCollisionAlgorithm.h + btParallelConstraintSolver.h + + #SPURS_PEGatherScatterTask/SpuPEGatherScatterTask.h + #SpuPEGatherScatterTaskProcess.h + + #Some GPU related stuff, mainly CUDA and perhaps OpenCL + btGpu3DGridBroadphase.h + btGpu3DGridBroadphaseSharedCode.h + btGpu3DGridBroadphaseSharedDefs.h + btGpu3DGridBroadphaseSharedTypes.h + btGpuDefines.h + btGpuUtilsSharedCode.h + btGpuUtilsSharedDefs.h +) + +SET(SpuNarrowPhaseCollisionTask_HDRS + SpuNarrowPhaseCollisionTask/Box.h + SpuNarrowPhaseCollisionTask/boxBoxDistance.h + SpuNarrowPhaseCollisionTask/SpuContactResult.h + SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h + SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h + SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h + SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h + SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h +) + +SET(BulletMultiThreaded_HDRS + ${Root_HDRS} + ${SpuNarrowPhaseCollisionTask_HDRS} +) + +ADD_LIBRARY(BulletMultiThreaded ${BulletMultiThreaded_SRCS} ${BulletMultiThreaded_HDRS}) +SET_TARGET_PROPERTIES(BulletMultiThreaded PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletMultiThreaded PROPERTIES SOVERSION ${BULLET_VERSION}) + + +SUBDIRS(GpuSoftBodySolvers) + + +IF (BUILD_SHARED_LIBS) + IF (UNIX) + TARGET_LINK_LIBRARIES(BulletMultiThreaded BulletDynamics BulletCollision pthread) + ELSE() + TARGET_LINK_LIBRARIES(BulletMultiThreaded BulletDynamics BulletCollision) + ENDIF() +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #INSTALL of other files requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) +# IF(INSTALL_EXTRA_LIBS) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletMultiThreaded DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletMultiThreaded DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY +${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING +PATTERN "*.h" PATTERN ".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) +# ENDIF (INSTALL_EXTRA_LIBS) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletMultiThreaded PROPERTIES FRAMEWORK true) + + SET_TARGET_PROPERTIES(BulletMultiThreaded PROPERTIES PUBLIC_HEADER "${Root_HDRS}") + # Have to list out sub-directories manually: + SET_PROPERTY(SOURCE ${SpuNarrowPhaseCollisionTask_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/SpuNarrowPhaseCollisionTask) + + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/CMakeLists.txt new file mode 100644 index 0000000..d895176 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/CMakeLists.txt @@ -0,0 +1,13 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + + +SUBDIRS ( + OpenCL +) + +IF( USE_DX11 ) + SUBDIRS( DX11 ) +ENDIF( USE_DX11 ) diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/CMakeLists.txt new file mode 100644 index 0000000..e488771 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/CMakeLists.txt @@ -0,0 +1,83 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + +SET(DXSDK_DIR $ENV{DXSDK_DIR}) +SET(DX11_INCLUDE_PATH "${DIRECTX_SDK_BASE_DIR}/Include" CACHE DOCSTRING "Microsoft directX SDK include path") + + +INCLUDE_DIRECTORIES( +${DX11_INCLUDE_PATH} "../Shared/" +${VECTOR_MATH_INCLUDE} +) + +SET(BulletSoftBodyDX11Solvers_SRCS + btSoftBodySolver_DX11.cpp + btSoftBodySolver_DX11SIMDAware.cpp +) + +SET(BulletSoftBodyDX11Solvers_HDRS + btSoftBodySolver_DX11.h + btSoftBodySolver_DX11SIMDAware.h + ../Shared/btSoftBodySolverData.h + btSoftBodySolverVertexData_DX11.h + btSoftBodySolverTriangleData_DX11.h + btSoftBodySolverLinkData_DX11.h + btSoftBodySolverLinkData_DX11SIMDAware.h + btSoftBodySolverBuffer_DX11.h + btSoftBodySolverVertexBuffer_DX11.h + +) + +# OpenCL and HLSL Shaders. +# Build rules generated to stringify these into headers +# which are needed by some of the sources +SET(BulletSoftBodyDX11Solvers_Shaders + OutputToVertexArray + UpdateNormals + Integrate + UpdatePositions + UpdateNodes + ComputeBounds + SolvePositions + SolvePositionsSIMDBatched + SolveCollisionsAndUpdateVelocities + SolveCollisionsAndUpdateVelocitiesSIMDBatched + UpdatePositionsFromVelocities + ApplyForces + PrepareLinks + VSolveLinks +) + +foreach(f ${BulletSoftBodyDX11Solvers_Shaders}) + LIST(APPEND BulletSoftBodyDX11Solvers_HLSL "HLSL/${f}.hlsl") +endforeach(f) + + + +ADD_LIBRARY(BulletSoftBodySolvers_DX11 ${BulletSoftBodyDX11Solvers_SRCS} ${BulletSoftBodyDX11Solvers_HDRS} ${BulletSoftBodyDX11Solvers_HLSL}) +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_DX11 BulletSoftBody BulletDynamics) +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_DX11 DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_DX11 DESTINATION lib${LIB_SUFFIX}) +#headers are already installed by BulletMultiThreaded library + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_DX11 PROPERTIES PUBLIC_HEADER "${BulletSoftBodyDX11Solvers_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ApplyForces.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ApplyForces.hlsl new file mode 100644 index 0000000..9f9ac07 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ApplyForces.hlsl @@ -0,0 +1,95 @@ +MSTRINGIFY( + +cbuffer ApplyForcesCB : register( b0 ) +{ + unsigned int numNodes; + float solverdt; + float epsilon; + int padding3; +}; + + +StructuredBuffer g_vertexClothIdentifier : register( t0 ); +StructuredBuffer g_vertexNormal : register( t1 ); +StructuredBuffer g_vertexArea : register( t2 ); +StructuredBuffer g_vertexInverseMass : register( t3 ); +// TODO: These could be combined into a lift/drag factor array along with medium density +StructuredBuffer g_clothLiftFactor : register( t4 ); +StructuredBuffer g_clothDragFactor : register( t5 ); +StructuredBuffer g_clothWindVelocity : register( t6 ); +StructuredBuffer g_clothAcceleration : register( t7 ); +StructuredBuffer g_clothMediumDensity : register( t8 ); + +RWStructuredBuffer g_vertexForceAccumulator : register( u0 ); +RWStructuredBuffer g_vertexVelocity : register( u1 ); + +float3 projectOnAxis( float3 v, float3 a ) +{ + return (a*dot(v, a)); +} + +[numthreads(128, 1, 1)] +void +ApplyForcesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + unsigned int nodeID = DTid.x; + if( nodeID < numNodes ) + { + int clothId = g_vertexClothIdentifier[nodeID]; + float nodeIM = g_vertexInverseMass[nodeID]; + + if( nodeIM > 0.0f ) + { + float3 nodeV = g_vertexVelocity[nodeID].xyz; + float3 normal = g_vertexNormal[nodeID].xyz; + float area = g_vertexArea[nodeID]; + float3 nodeF = g_vertexForceAccumulator[nodeID].xyz; + + // Read per-cloth values + float3 clothAcceleration = g_clothAcceleration[clothId].xyz; + float3 clothWindVelocity = g_clothWindVelocity[clothId].xyz; + float liftFactor = g_clothLiftFactor[clothId]; + float dragFactor = g_clothDragFactor[clothId]; + float mediumDensity = g_clothMediumDensity[clothId]; + + // Apply the acceleration to the cloth rather than do this via a force + nodeV += (clothAcceleration*solverdt); + + g_vertexVelocity[nodeID] = float4(nodeV, 0.f); + + float3 relativeWindVelocity = nodeV - clothWindVelocity; + float relativeSpeedSquared = dot(relativeWindVelocity, relativeWindVelocity); + + if( relativeSpeedSquared > epsilon ) + { + // Correct direction of normal relative to wind direction and get dot product + normal = normal * (dot(normal, relativeWindVelocity) < 0 ? -1.f : 1.f); + float dvNormal = dot(normal, relativeWindVelocity); + if( dvNormal > 0 ) + { + float3 force = float3(0.f, 0.f, 0.f); + float c0 = area * dvNormal * relativeSpeedSquared / 2.f; + float c1 = c0 * mediumDensity; + force += normal * (-c1 * liftFactor); + force += normalize(relativeWindVelocity)*(-c1 * dragFactor); + + float dtim = solverdt * nodeIM; + float3 forceDTIM = force * dtim; + + float3 nodeFPlusForce = nodeF + force; + + // m_nodesf[i] -= ProjectOnAxis(m_nodesv[i], force.normalized())/dtim; + float3 nodeFMinus = nodeF - (projectOnAxis(nodeV, normalize(force))/dtim); + + nodeF = nodeFPlusForce; + if( dot(forceDTIM, forceDTIM) > dot(nodeV, nodeV) ) + nodeF = nodeFMinus; + + g_vertexForceAccumulator[nodeID] = float4(nodeF, 0.0f); + } + } + } + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ComputeBounds.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ComputeBounds.hlsl new file mode 100644 index 0000000..e21f959 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/ComputeBounds.hlsl @@ -0,0 +1,83 @@ +MSTRINGIFY( + +cbuffer ComputeBoundsCB : register( b0 ) +{ + int numNodes; + int numSoftBodies; + int padding1; + int padding2; +}; + +// Node indices for each link +StructuredBuffer g_vertexClothIdentifier : register( t0 ); +StructuredBuffer g_vertexPositions : register( t1 ); + +RWStructuredBuffer g_clothMinBounds : register( u0 ); +RWStructuredBuffer g_clothMaxBounds : register( u1 ); + +groupshared uint4 clothMinBounds[256]; +groupshared uint4 clothMaxBounds[256]; + +[numthreads(128, 1, 1)] +void +ComputeBoundsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + const unsigned int UINT_MAX = 0xffffffff; + + // Init min and max bounds arrays + if( GTid.x < numSoftBodies ) + { + clothMinBounds[GTid.x] = uint4(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX); + clothMaxBounds[GTid.x] = uint4(0,0,0,0); + } + + AllMemoryBarrierWithGroupSync(); + + int nodeID = DTid.x; + if( nodeID < numNodes ) + { + int clothIdentifier = g_vertexClothIdentifier[nodeID]; + if( clothIdentifier >= 0 ) + { + float3 position = g_vertexPositions[nodeID].xyz; + + // Reinterpret position as uint + uint3 positionUInt = uint3(asuint(position.x), asuint(position.y), asuint(position.z)); + + // Invert sign bit of positives and whole of negatives to allow comparison as unsigned ints + //positionUInt.x ^= uint((-int(positionUInt.x >> 31) | 0x80000000)); + //positionUInt.y ^= uint((-int(positionUInt.y >> 31) | 0x80000000)); + //positionUInt.z ^= uint((-int(positionUInt.z >> 31) | 0x80000000)); + positionUInt.x ^= (1+~(positionUInt.x >> 31) | 0x80000000); + positionUInt.y ^= (1+~(positionUInt.y >> 31) | 0x80000000); + positionUInt.z ^= (1+~(positionUInt.z >> 31) | 0x80000000); + + // Min/max with the LDS values + InterlockedMin(clothMinBounds[clothIdentifier].x, positionUInt.x); + InterlockedMin(clothMinBounds[clothIdentifier].y, positionUInt.y); + InterlockedMin(clothMinBounds[clothIdentifier].z, positionUInt.z); + + InterlockedMax(clothMaxBounds[clothIdentifier].x, positionUInt.x); + InterlockedMax(clothMaxBounds[clothIdentifier].y, positionUInt.y); + InterlockedMax(clothMaxBounds[clothIdentifier].z, positionUInt.z); + } + } + + AllMemoryBarrierWithGroupSync(); + + + // Use global atomics to update the global versions of the data + if( GTid.x < numSoftBodies ) + { + InterlockedMin(g_clothMinBounds[GTid.x].x, clothMinBounds[GTid.x].x); + InterlockedMin(g_clothMinBounds[GTid.x].y, clothMinBounds[GTid.x].y); + InterlockedMin(g_clothMinBounds[GTid.x].z, clothMinBounds[GTid.x].z); + + InterlockedMax(g_clothMaxBounds[GTid.x].x, clothMaxBounds[GTid.x].x); + InterlockedMax(g_clothMaxBounds[GTid.x].y, clothMaxBounds[GTid.x].y); + InterlockedMax(g_clothMaxBounds[GTid.x].z, clothMaxBounds[GTid.x].z); + } +} + + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/Integrate.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/Integrate.hlsl new file mode 100644 index 0000000..e43870b --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/Integrate.hlsl @@ -0,0 +1,41 @@ +MSTRINGIFY( + +cbuffer IntegrateCB : register( b0 ) +{ + int numNodes; + float solverdt; + int padding1; + int padding2; +}; + +// Node indices for each link +StructuredBuffer g_vertexInverseMasses : register( t0 ); + +RWStructuredBuffer g_vertexPositions : register( u0 ); +RWStructuredBuffer g_vertexVelocity : register( u1 ); +RWStructuredBuffer g_vertexPreviousPositions : register( u2 ); +RWStructuredBuffer g_vertexForceAccumulator : register( u3 ); + +[numthreads(128, 1, 1)] +void +IntegrateKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int nodeID = DTid.x; + if( nodeID < numNodes ) + { + float3 position = g_vertexPositions[nodeID].xyz; + float3 velocity = g_vertexVelocity[nodeID].xyz; + float3 force = g_vertexForceAccumulator[nodeID].xyz; + float inverseMass = g_vertexInverseMasses[nodeID]; + + g_vertexPreviousPositions[nodeID] = float4(position, 0.f); + velocity += force * inverseMass * solverdt; + position += velocity * solverdt; + + g_vertexForceAccumulator[nodeID] = float4(0.f, 0.f, 0.f, 0.0f); + g_vertexPositions[nodeID] = float4(position, 0.f); + g_vertexVelocity[nodeID] = float4(velocity, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/OutputToVertexArray.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/OutputToVertexArray.hlsl new file mode 100644 index 0000000..cd2924d --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/OutputToVertexArray.hlsl @@ -0,0 +1,63 @@ +MSTRINGIFY( + +cbuffer OutputToVertexArrayCB : register( b0 ) +{ + int startNode; + int numNodes; + int positionOffset; + int positionStride; + + int normalOffset; + int normalStride; + int padding1; + int padding2; +}; + + +StructuredBuffer g_vertexPositions : register( t0 ); +StructuredBuffer g_vertexNormals : register( t1 ); + +RWBuffer g_vertexBuffer : register( u0 ); + + +[numthreads(128, 1, 1)] +void +OutputToVertexArrayWithNormalsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int nodeID = DTid.x; + if( nodeID < numNodes ) + { + float4 position = g_vertexPositions[nodeID + startNode]; + float4 normal = g_vertexNormals[nodeID + startNode]; + + // Stride should account for the float->float4 conversion + int positionDestination = nodeID * positionStride + positionOffset; + g_vertexBuffer[positionDestination] = position.x; + g_vertexBuffer[positionDestination+1] = position.y; + g_vertexBuffer[positionDestination+2] = position.z; + + int normalDestination = nodeID * normalStride + normalOffset; + g_vertexBuffer[normalDestination] = normal.x; + g_vertexBuffer[normalDestination+1] = normal.y; + g_vertexBuffer[normalDestination+2] = normal.z; + } +} + +[numthreads(128, 1, 1)] +void +OutputToVertexArrayWithoutNormalsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int nodeID = DTid.x; + if( nodeID < numNodes ) + { + float4 position = g_vertexPositions[nodeID + startNode]; + float4 normal = g_vertexNormals[nodeID + startNode]; + + // Stride should account for the float->float4 conversion + int positionDestination = nodeID * positionStride + positionOffset; + g_vertexBuffer[positionDestination] = position.x; + g_vertexBuffer[positionDestination+1] = position.y; + g_vertexBuffer[positionDestination+2] = position.z; + } +} +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/PrepareLinks.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/PrepareLinks.hlsl new file mode 100644 index 0000000..269e65c --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/PrepareLinks.hlsl @@ -0,0 +1,44 @@ +MSTRINGIFY( + +cbuffer PrepareLinksCB : register( b0 ) +{ + int numLinks; + int padding0; + int padding1; + int padding2; +}; + +// Node indices for each link +StructuredBuffer g_linksVertexIndices : register( t0 ); +StructuredBuffer g_linksMassLSC : register( t1 ); +StructuredBuffer g_nodesPreviousPosition : register( t2 ); + +RWStructuredBuffer g_linksLengthRatio : register( u0 ); +RWStructuredBuffer g_linksCurrentLength : register( u1 ); + +[numthreads(128, 1, 1)] +void +PrepareLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int linkID = DTid.x; + if( linkID < numLinks ) + { + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + + float4 nodePreviousPosition0 = g_nodesPreviousPosition[node0]; + float4 nodePreviousPosition1 = g_nodesPreviousPosition[node1]; + + float massLSC = g_linksMassLSC[linkID]; + + float4 linkCurrentLength = nodePreviousPosition1 - nodePreviousPosition0; + + float linkLengthRatio = dot(linkCurrentLength, linkCurrentLength)*massLSC; + linkLengthRatio = 1./linkLengthRatio; + + g_linksCurrentLength[linkID] = linkCurrentLength; + g_linksLengthRatio[linkID] = linkLengthRatio; + } +} +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositions.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositions.hlsl new file mode 100644 index 0000000..0eacaf1 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositions.hlsl @@ -0,0 +1,55 @@ +MSTRINGIFY( + +cbuffer SolvePositionsFromLinksKernelCB : register( b0 ) +{ + int startLink; + int numLinks; + float kst; + float ti; +}; + +// Node indices for each link +StructuredBuffer g_linksVertexIndices : register( t0 ); + +StructuredBuffer g_linksMassLSC : register( t1 ); +StructuredBuffer g_linksRestLengthSquared : register( t2 ); +StructuredBuffer g_verticesInverseMass : register( t3 ); + +RWStructuredBuffer g_vertexPositions : register( u0 ); + +[numthreads(128, 1, 1)] +void +SolvePositionsFromLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int linkID = DTid.x + startLink; + if( DTid.x < numLinks ) + { + float massLSC = g_linksMassLSC[linkID]; + float restLengthSquared = g_linksRestLengthSquared[linkID]; + + if( massLSC > 0.0f ) + { + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + + float3 position0 = g_vertexPositions[node0].xyz; + float3 position1 = g_vertexPositions[node1].xyz; + + float inverseMass0 = g_verticesInverseMass[node0]; + float inverseMass1 = g_verticesInverseMass[node1]; + + float3 del = position1 - position0; + float len = dot(del, del); + float k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst; + position0 = position0 - del*(k*inverseMass0); + position1 = position1 + del*(k*inverseMass1); + + g_vertexPositions[node0] = float4(position0, 0.f); + g_vertexPositions[node1] = float4(position1, 0.f); + + } + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositionsSIMDBatched.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositionsSIMDBatched.hlsl new file mode 100644 index 0000000..4834dc1 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/SolvePositionsSIMDBatched.hlsl @@ -0,0 +1,147 @@ +MSTRINGIFY( + + + +cbuffer SolvePositionsFromLinksKernelCB : register( b0 ) +{ + int startWaveInBatch; + int numWaves; + float kst; + float ti; +}; + + +// Number of batches per wavefront stored one element per logical wavefront +StructuredBuffer g_wavefrontBatchCountsVertexCounts : register( t0 ); +// Set of up to maxNumVertices vertex addresses per wavefront +StructuredBuffer g_vertexAddressesPerWavefront : register( t1 ); + +StructuredBuffer g_verticesInverseMass : register( t2 ); + +// Per-link data layed out structured in terms of sub batches within wavefronts +StructuredBuffer g_linksVertexIndices : register( t3 ); +StructuredBuffer g_linksMassLSC : register( t4 ); +StructuredBuffer g_linksRestLengthSquared : register( t5 ); + +RWStructuredBuffer g_vertexPositions : register( u0 ); + +// Data loaded on a per-wave basis +groupshared int2 wavefrontBatchCountsVertexCounts[WAVEFRONT_BLOCK_MULTIPLIER]; +groupshared float4 vertexPositionSharedData[MAX_NUM_VERTICES_PER_WAVE*WAVEFRONT_BLOCK_MULTIPLIER]; +groupshared float vertexInverseMassSharedData[MAX_NUM_VERTICES_PER_WAVE*WAVEFRONT_BLOCK_MULTIPLIER]; + +// Storing the vertex addresses actually slowed things down a little +//groupshared int vertexAddressSharedData[MAX_NUM_VERTICES_PER_WAVE*WAVEFRONT_BLOCK_MULTIPLIER]; + + +[numthreads(BLOCK_SIZE, 1, 1)] +void +SolvePositionsFromLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + const int laneInWavefront = (DTid.x & (WAVEFRONT_SIZE-1)); + const int wavefront = startWaveInBatch + (DTid.x / WAVEFRONT_SIZE); + const int firstWavefrontInBlock = startWaveInBatch + Gid.x * WAVEFRONT_BLOCK_MULTIPLIER; + const int localWavefront = wavefront - firstWavefrontInBlock; + + int batchesWithinWavefront = 0; + int verticesUsedByWave = 0; + int cond = wavefront < (startWaveInBatch + numWaves); + + // Mask out in case there's a stray "wavefront" at the end that's been forced in through the multiplier + if( cond) + { + + // Load the batch counts for the wavefronts + + int2 batchesAndVerticesWithinWavefront = g_wavefrontBatchCountsVertexCounts[wavefront]; + + batchesWithinWavefront = batchesAndVerticesWithinWavefront.x; + verticesUsedByWave = batchesAndVerticesWithinWavefront.y; + + // Load the vertices for the wavefronts + for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE ) + { + int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex]; + + //vertexAddressSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = vertexAddress; + vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_vertexPositions[vertexAddress]; + vertexInverseMassSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_verticesInverseMass[vertexAddress]; + } + + } + // Ensure compiler does not re-order memory operations + //AllMemoryBarrier(); + AllMemoryBarrierWithGroupSync (); + + if( cond) + { + // Loop through the batches performing the solve on each in LDS + int baseDataLocationForWave = WAVEFRONT_SIZE * wavefront * MAX_BATCHES_PER_WAVE; + + //for( int batch = 0; batch < batchesWithinWavefront; ++batch ) + + int batch = 0; + do + { + int baseDataLocation = baseDataLocationForWave + WAVEFRONT_SIZE * batch; + int locationOfValue = baseDataLocation + laneInWavefront; + + + // These loads should all be perfectly linear across the WF + int2 localVertexIndices = g_linksVertexIndices[locationOfValue]; + float massLSC = g_linksMassLSC[locationOfValue]; + float restLengthSquared = g_linksRestLengthSquared[locationOfValue]; + + + // LDS vertex addresses based on logical wavefront number in block and loaded index + int vertexAddress0 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.x; + int vertexAddress1 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.y; + + float3 position0 = vertexPositionSharedData[vertexAddress0].xyz; + float3 position1 = vertexPositionSharedData[vertexAddress1].xyz; + + float inverseMass0 = vertexInverseMassSharedData[vertexAddress0]; + float inverseMass1 = vertexInverseMassSharedData[vertexAddress1]; + + float3 del = position1 - position0; + float len = dot(del, del); + + float k = 0; + if( massLSC > 0.0f ) + { + k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst; + } + + position0 = position0 - del*(k*inverseMass0); + position1 = position1 + del*(k*inverseMass1); + + // Ensure compiler does not re-order memory operations + AllMemoryBarrier(); + + vertexPositionSharedData[vertexAddress0] = float4(position0, 0.f); + vertexPositionSharedData[vertexAddress1] = float4(position1, 0.f); + + // Ensure compiler does not re-order memory operations + AllMemoryBarrier(); + + + ++batch; + } while( batch < batchesWithinWavefront ); + + // Update the global memory vertices for the wavefronts + for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE ) + { + int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex]; + + g_vertexPositions[vertexAddress] = vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex]; + } + } + + +} + + + + +); + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateConstants.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateConstants.hlsl new file mode 100644 index 0000000..0b8031b --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateConstants.hlsl @@ -0,0 +1,48 @@ +MSTRINGIFY( + +cbuffer UpdateConstantsCB : register( b0 ) +{ + int numLinks; + int padding0; + int padding1; + int padding2; +}; + +// Node indices for each link +StructuredBuffer g_linksVertexIndices : register( t0 ); +StructuredBuffer g_vertexPositions : register( t1 ); +StructuredBuffer g_vertexInverseMasses : register( t2 ); +StructuredBuffer g_linksMaterialLSC : register( t3 ); + +RWStructuredBuffer g_linksMassLSC : register( u0 ); +RWStructuredBuffer g_linksRestLengthSquared : register( u1 ); +RWStructuredBuffer g_linksRestLengths : register( u2 ); + +[numthreads(128, 1, 1)] +void +UpdateConstantsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int linkID = DTid.x; + if( linkID < numLinks ) + { + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + float linearStiffnessCoefficient = g_linksMaterialLSC[ linkID ]; + + float3 position0 = g_vertexPositions[node0].xyz; + float3 position1 = g_vertexPositions[node1].xyz; + float inverseMass0 = g_vertexInverseMasses[node0]; + float inverseMass1 = g_vertexInverseMasses[node1]; + + float3 difference = position0 - position1; + float length2 = dot(difference, difference); + float length = sqrt(length2); + + g_linksRestLengths[linkID] = length; + g_linksMassLSC[linkID] = (inverseMass0 + inverseMass1)/linearStiffnessCoefficient; + g_linksRestLengthSquared[linkID] = length*length; + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNodes.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNodes.hlsl new file mode 100644 index 0000000..538cc22 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNodes.hlsl @@ -0,0 +1,49 @@ +MSTRINGIFY( + +cbuffer UpdateVelocitiesFromPositionsWithVelocitiesCB : register( b0 ) +{ + int numNodes; + float isolverdt; + int padding1; + int padding2; +}; + + +StructuredBuffer g_vertexPositions : register( t0 ); +StructuredBuffer g_vertexPreviousPositions : register( t1 ); +StructuredBuffer g_vertexClothIndices : register( t2 ); +StructuredBuffer g_clothVelocityCorrectionCoefficients : register( t3 ); +StructuredBuffer g_clothDampingFactor : register( t4 ); + +RWStructuredBuffer g_vertexVelocities : register( u0 ); +RWStructuredBuffer g_vertexForces : register( u1 ); + + +[numthreads(128, 1, 1)] +void +updateVelocitiesFromPositionsWithVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int nodeID = DTid.x; + if( nodeID < numNodes ) + { + float3 position = g_vertexPositions[nodeID].xyz; + float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz; + float3 velocity = g_vertexVelocities[nodeID].xyz; + int clothIndex = g_vertexClothIndices[nodeID]; + float velocityCorrectionCoefficient = g_clothVelocityCorrectionCoefficients[clothIndex]; + float dampingFactor = g_clothDampingFactor[clothIndex]; + float velocityCoefficient = (1.f - dampingFactor); + + float3 difference = position - previousPosition; + + velocity += difference*velocityCorrectionCoefficient*isolverdt; + + // Damp the velocity + velocity *= velocityCoefficient; + + g_vertexVelocities[nodeID] = float4(velocity, 0.f); + g_vertexForces[nodeID] = float4(0.f, 0.f, 0.f, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNormals.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNormals.hlsl new file mode 100644 index 0000000..edfd321 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdateNormals.hlsl @@ -0,0 +1,98 @@ +MSTRINGIFY( + +cbuffer UpdateSoftBodiesCB : register( b0 ) +{ + unsigned int numNodes; + unsigned int startFace; + unsigned int numFaces; + float epsilon; +}; + + +// Node indices for each link +StructuredBuffer g_triangleVertexIndexSet : register( t0 ); +StructuredBuffer g_vertexPositions : register( t1 ); +StructuredBuffer g_vertexTriangleCount : register( t2 ); + +RWStructuredBuffer g_vertexNormals : register( u0 ); +RWStructuredBuffer g_vertexArea : register( u1 ); +RWStructuredBuffer g_triangleNormals : register( u2 ); +RWStructuredBuffer g_triangleArea : register( u3 ); + + +[numthreads(128, 1, 1)] +void +ResetNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + if( DTid.x < numNodes ) + { + g_vertexNormals[DTid.x] = float4(0.0f, 0.0f, 0.0f, 0.0f); + g_vertexArea[DTid.x] = 0.0f; + } +} + + +[numthreads(128, 1, 1)] +void +UpdateSoftBodiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int faceID = DTid.x + startFace; + if( DTid.x < numFaces ) + { + int4 triangleIndexSet = g_triangleVertexIndexSet[ faceID ]; + int nodeIndex0 = triangleIndexSet.x; + int nodeIndex1 = triangleIndexSet.y; + int nodeIndex2 = triangleIndexSet.z; + + float3 node0 = g_vertexPositions[nodeIndex0].xyz; + float3 node1 = g_vertexPositions[nodeIndex1].xyz; + float3 node2 = g_vertexPositions[nodeIndex2].xyz; + float3 nodeNormal0 = g_vertexNormals[nodeIndex0].xyz; + float3 nodeNormal1 = g_vertexNormals[nodeIndex1].xyz; + float3 nodeNormal2 = g_vertexNormals[nodeIndex2].xyz; + float vertexArea0 = g_vertexArea[nodeIndex0]; + float vertexArea1 = g_vertexArea[nodeIndex1]; + float vertexArea2 = g_vertexArea[nodeIndex2]; + + float3 vector0 = node1 - node0; + float3 vector1 = node2 - node0; + + float3 faceNormal = cross(vector0.xyz, vector1.xyz); + float triangleArea = length(faceNormal); + + nodeNormal0 = nodeNormal0 + faceNormal; + nodeNormal1 = nodeNormal1 + faceNormal; + nodeNormal2 = nodeNormal2 + faceNormal; + vertexArea0 = vertexArea0 + triangleArea; + vertexArea1 = vertexArea1 + triangleArea; + vertexArea2 = vertexArea2 + triangleArea; + + g_triangleNormals[faceID] = float4(normalize(faceNormal), 0.f); + g_vertexNormals[nodeIndex0] = float4(nodeNormal0, 0.f); + g_vertexNormals[nodeIndex1] = float4(nodeNormal1, 0.f); + g_vertexNormals[nodeIndex2] = float4(nodeNormal2, 0.f); + g_triangleArea[faceID] = triangleArea; + g_vertexArea[nodeIndex0] = vertexArea0; + g_vertexArea[nodeIndex1] = vertexArea1; + g_vertexArea[nodeIndex2] = vertexArea2; + } +} + +[numthreads(128, 1, 1)] +void +NormalizeNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + if( DTid.x < numNodes ) + { + float4 normal = g_vertexNormals[DTid.x]; + float area = g_vertexArea[DTid.x]; + int numTriangles = g_vertexTriangleCount[DTid.x]; + + float vectorLength = length(normal); + + g_vertexNormals[DTid.x] = normalize(normal); + g_vertexArea[DTid.x] = area/float(numTriangles); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositions.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositions.hlsl new file mode 100644 index 0000000..3547a74 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositions.hlsl @@ -0,0 +1,44 @@ +MSTRINGIFY( + +cbuffer UpdateVelocitiesFromPositionsWithoutVelocitiesCB : register( b0 ) +{ + int numNodes; + float isolverdt; + int padding1; + int padding2; +}; + + +StructuredBuffer g_vertexPositions : register( t0 ); +StructuredBuffer g_vertexPreviousPositions : register( t1 ); +StructuredBuffer g_vertexClothIndices : register( t2 ); +StructuredBuffer g_clothDampingFactor : register( t3 ); + +RWStructuredBuffer g_vertexVelocities : register( u0 ); +RWStructuredBuffer g_vertexForces : register( u1 ); + + +[numthreads(128, 1, 1)] +void +updateVelocitiesFromPositionsWithoutVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int nodeID = DTid.x; + if( nodeID < numNodes ) + { + float3 position = g_vertexPositions[nodeID].xyz; + float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz; + float3 velocity = g_vertexVelocities[nodeID].xyz; + int clothIndex = g_vertexClothIndices[nodeID]; + float dampingFactor = g_clothDampingFactor[clothIndex]; + float velocityCoefficient = (1.f - dampingFactor); + + float3 difference = position - previousPosition; + + velocity = difference*velocityCoefficient*isolverdt; + + g_vertexVelocities[nodeID] = float4(velocity, 0.f); + g_vertexForces[nodeID] = float4(0.f, 0.f, 0.f, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositionsFromVelocities.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositionsFromVelocities.hlsl new file mode 100644 index 0000000..5c94bd0 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/UpdatePositionsFromVelocities.hlsl @@ -0,0 +1,35 @@ +MSTRINGIFY( + +cbuffer UpdatePositionsFromVelocitiesCB : register( b0 ) +{ + int numNodes; + float solverSDT; + int padding1; + int padding2; +}; + + +StructuredBuffer g_vertexVelocities : register( t0 ); + +RWStructuredBuffer g_vertexPreviousPositions : register( u0 ); +RWStructuredBuffer g_vertexCurrentPosition : register( u1 ); + + +[numthreads(128, 1, 1)] +void +UpdatePositionsFromVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int vertexID = DTid.x; + if( vertexID < numNodes ) + { + float3 previousPosition = g_vertexPreviousPositions[vertexID].xyz; + float3 velocity = g_vertexVelocities[vertexID].xyz; + + float3 newPosition = previousPosition + velocity*solverSDT; + + g_vertexCurrentPosition[vertexID] = float4(newPosition, 0.f); + g_vertexPreviousPositions[vertexID] = float4(newPosition, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/VSolveLinks.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/VSolveLinks.hlsl new file mode 100644 index 0000000..fc39195 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/VSolveLinks.hlsl @@ -0,0 +1,55 @@ +MSTRINGIFY( + +cbuffer VSolveLinksCB : register( b0 ) +{ + int startLink; + int numLinks; + float kst; + int padding; +}; + +// Node indices for each link +StructuredBuffer g_linksVertexIndices : register( t0 ); + +StructuredBuffer g_linksLengthRatio : register( t1 ); +StructuredBuffer g_linksCurrentLength : register( t2 ); +StructuredBuffer g_vertexInverseMass : register( t3 ); + +RWStructuredBuffer g_vertexVelocity : register( u0 ); + +[numthreads(128, 1, 1)] +void +VSolveLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int linkID = DTid.x + startLink; + if( DTid.x < numLinks ) + { + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + + float linkLengthRatio = g_linksLengthRatio[linkID]; + float3 linkCurrentLength = g_linksCurrentLength[linkID].xyz; + + float3 vertexVelocity0 = g_vertexVelocity[node0].xyz; + float3 vertexVelocity1 = g_vertexVelocity[node1].xyz; + + float vertexInverseMass0 = g_vertexInverseMass[node0]; + float vertexInverseMass1 = g_vertexInverseMass[node1]; + + float3 nodeDifference = vertexVelocity0 - vertexVelocity1; + float dotResult = dot(linkCurrentLength, nodeDifference); + float j = -dotResult*linkLengthRatio*kst; + + float3 velocityChange0 = linkCurrentLength*(j*vertexInverseMass0); + float3 velocityChange1 = linkCurrentLength*(j*vertexInverseMass1); + + vertexVelocity0 += velocityChange0; + vertexVelocity1 -= velocityChange1; + + g_vertexVelocity[node0] = float4(vertexVelocity0, 0.f); + g_vertexVelocity[node1] = float4(vertexVelocity1, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocities.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocities.hlsl new file mode 100644 index 0000000..399912f --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocities.hlsl @@ -0,0 +1,170 @@ +MSTRINGIFY( + +cbuffer SolvePositionsFromLinksKernelCB : register( b0 ) +{ + unsigned int numNodes; + float isolverdt; + int padding0; + int padding1; +}; + +struct CollisionObjectIndices +{ + int firstObject; + int endObject; +}; + +struct CollisionShapeDescription +{ + float4x4 shapeTransform; + float4 linearVelocity; + float4 angularVelocity; + + int softBodyIdentifier; + int collisionShapeType; + + + // Shape information + // Compressed from the union + float radius; + float halfHeight; + + float margin; + float friction; + + int padding0; + int padding1; + +}; + +// From btBroadphaseProxy.h +static const int CAPSULE_SHAPE_PROXYTYPE = 10; + +// Node indices for each link +StructuredBuffer g_vertexClothIdentifier : register( t0 ); +StructuredBuffer g_vertexPreviousPositions : register( t1 ); +StructuredBuffer g_perClothFriction : register( t2 ); +StructuredBuffer g_clothDampingFactor : register( t3 ); +StructuredBuffer g_perClothCollisionObjectIndices : register( t4 ); +StructuredBuffer g_collisionObjectDetails : register( t5 ); + +RWStructuredBuffer g_vertexForces : register( u0 ); +RWStructuredBuffer g_vertexVelocities : register( u1 ); +RWStructuredBuffer g_vertexPositions : register( u2 ); + +[numthreads(128, 1, 1)] +void +SolveCollisionsAndUpdateVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int nodeID = DTid.x; + float3 forceOnVertex = float3(0.f, 0.f, 0.f); + if( DTid.x < numNodes ) + { + int clothIdentifier = g_vertexClothIdentifier[nodeID]; + float4 position = float4(g_vertexPositions[nodeID].xyz, 1.f); + float4 previousPosition = float4(g_vertexPreviousPositions[nodeID].xyz, 1.f); + float3 velocity; + float clothFriction = g_perClothFriction[clothIdentifier]; + float dampingFactor = g_clothDampingFactor[clothIdentifier]; + float velocityCoefficient = (1.f - dampingFactor); + CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier]; + + if( collisionObjectIndices.firstObject != collisionObjectIndices.endObject ) + { + velocity = float3(15, 0, 0); + + // We have some possible collisions to deal with + for( int collision = collisionObjectIndices.firstObject; collision < collisionObjectIndices.endObject; ++collision ) + { + CollisionShapeDescription shapeDescription = g_collisionObjectDetails[collision]; + float colliderFriction = shapeDescription.friction; + + if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE ) + { + // Colliding with a capsule + + float capsuleHalfHeight = shapeDescription.halfHeight; + float capsuleRadius = shapeDescription.radius; + float capsuleMargin = shapeDescription.margin; + float4x4 worldTransform = shapeDescription.shapeTransform; + + float4 c1 = float4(0.f, -capsuleHalfHeight, 0.f, 1.f); + float4 c2 = float4(0.f, +capsuleHalfHeight, 0.f, 1.f); + float4 worldC1 = mul(worldTransform, c1); + float4 worldC2 = mul(worldTransform, c2); + float3 segment = (worldC2 - worldC1).xyz; + + // compute distance of tangent to vertex along line segment in capsule + float distanceAlongSegment = -( dot( (worldC1 - position).xyz, segment ) / dot(segment, segment) ); + + float4 closestPoint = (worldC1 + float4(segment * distanceAlongSegment, 0.f)); + float distanceFromLine = length(position - closestPoint); + float distanceFromC1 = length(worldC1 - position); + float distanceFromC2 = length(worldC2 - position); + + // Final distance from collision, point to push from, direction to push in + // for impulse force + float dist; + float3 normalVector; + if( distanceAlongSegment < 0 ) + { + dist = distanceFromC1; + normalVector = normalize(position - worldC1).xyz; + } else if( distanceAlongSegment > 1.f ) { + dist = distanceFromC2; + normalVector = normalize(position - worldC2).xyz; + } else { + dist = distanceFromLine; + normalVector = normalize(position - closestPoint).xyz; + } + + float3 colliderLinearVelocity = shapeDescription.linearVelocity.xyz; + float3 colliderAngularVelocity = shapeDescription.angularVelocity.xyz; + float3 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position.xyz - worldTransform._m03_m13_m23); + + float minDistance = capsuleRadius + capsuleMargin; + + // In case of no collision, this is the value of velocity + velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt; + + + // Check for a collision + if( dist < minDistance ) + { + // Project back to surface along normal + position = position + float4((minDistance - dist)*normalVector*0.9, 0.f); + velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt; + float3 relativeVelocity = velocity - velocityOfSurfacePoint; + + float3 p1 = normalize(cross(normalVector, segment)); + float3 p2 = normalize(cross(p1, normalVector)); + // Full friction is sum of velocities in each direction of plane + float3 frictionVector = p1*dot(relativeVelocity, p1) + p2*dot(relativeVelocity, p2); + + // Real friction is peak friction corrected by friction coefficients + frictionVector = frictionVector * (colliderFriction*clothFriction); + + float approachSpeed = dot(relativeVelocity, normalVector); + + if( approachSpeed <= 0.0 ) + forceOnVertex -= frictionVector; + } + + } + } + } else { + // Update velocity + float3 difference = position.xyz - previousPosition.xyz; + velocity = difference*velocityCoefficient*isolverdt; + } + + g_vertexVelocities[nodeID] = float4(velocity, 0.f); + + // Update external force + g_vertexForces[nodeID] = float4(forceOnVertex, 0.f); + + g_vertexPositions[nodeID] = float4(position.xyz, 0.f); + } +} + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocitiesSIMDBatched.hlsl b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocitiesSIMDBatched.hlsl new file mode 100644 index 0000000..9bb7e4d --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/HLSL/solveCollisionsAndUpdateVelocitiesSIMDBatched.hlsl @@ -0,0 +1,191 @@ +MSTRINGIFY( + +cbuffer SolvePositionsFromLinksKernelCB : register( b0 ) +{ + unsigned int numNodes; + float isolverdt; + int padding0; + int padding1; +}; + +struct CollisionObjectIndices +{ + int firstObject; + int endObject; +}; + +struct CollisionShapeDescription +{ + float4x4 shapeTransform; + float4 linearVelocity; + float4 angularVelocity; + + int softBodyIdentifier; + int collisionShapeType; + + + // Shape information + // Compressed from the union + float radius; + float halfHeight; + + float margin; + float friction; + + int padding0; + int padding1; + +}; + +// From btBroadphaseProxy.h +static const int CAPSULE_SHAPE_PROXYTYPE = 10; + +// Node indices for each link +StructuredBuffer g_vertexClothIdentifier : register( t0 ); +StructuredBuffer g_vertexPreviousPositions : register( t1 ); +StructuredBuffer g_perClothFriction : register( t2 ); +StructuredBuffer g_clothDampingFactor : register( t3 ); +StructuredBuffer g_perClothCollisionObjectIndices : register( t4 ); +StructuredBuffer g_collisionObjectDetails : register( t5 ); + +RWStructuredBuffer g_vertexForces : register( u0 ); +RWStructuredBuffer g_vertexVelocities : register( u1 ); +RWStructuredBuffer g_vertexPositions : register( u2 ); + +// A buffer of local collision shapes +// TODO: Iterate to support more than 16 +groupshared CollisionShapeDescription localCollisionShapes[16]; + +[numthreads(128, 1, 1)] +void +SolveCollisionsAndUpdateVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) +{ + int nodeID = DTid.x; + float3 forceOnVertex = float3(0.f, 0.f, 0.f); + + int clothIdentifier = g_vertexClothIdentifier[nodeID]; + float4 position = float4(g_vertexPositions[nodeID].xyz, 1.f); + float4 previousPosition = float4(g_vertexPreviousPositions[nodeID].xyz, 1.f); + float3 velocity; + float clothFriction = g_perClothFriction[clothIdentifier]; + float dampingFactor = g_clothDampingFactor[clothIdentifier]; + float velocityCoefficient = (1.f - dampingFactor); + CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier]; + + int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject; + if( numObjects > 0 ) + { + // We have some possible collisions to deal with + + // First load all of the collision objects into LDS + int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject; + if( GTid.x < numObjects ) + { + localCollisionShapes[GTid.x] = g_collisionObjectDetails[ collisionObjectIndices.firstObject + GTid.x ]; + } + } + + // Safe as the vertices are padded so that not more than one soft body is in a group + AllMemoryBarrierWithGroupSync(); + + // Annoyingly, even though I know the flow control is not varying, the compiler will not let me skip this + if( numObjects > 0 ) + { + velocity = float3(0, 0, 0); + + + // We have some possible collisions to deal with + for( int collision = 0; collision < numObjects; ++collision ) + { + CollisionShapeDescription shapeDescription = localCollisionShapes[collision]; + float colliderFriction = shapeDescription.friction; + + if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE ) + { + // Colliding with a capsule + + float capsuleHalfHeight = localCollisionShapes[collision].halfHeight; + float capsuleRadius = localCollisionShapes[collision].radius; + float capsuleMargin = localCollisionShapes[collision].margin; + + float4x4 worldTransform = localCollisionShapes[collision].shapeTransform; + + float4 c1 = float4(0.f, -capsuleHalfHeight, 0.f, 1.f); + float4 c2 = float4(0.f, +capsuleHalfHeight, 0.f, 1.f); + float4 worldC1 = mul(worldTransform, c1); + float4 worldC2 = mul(worldTransform, c2); + float3 segment = (worldC2 - worldC1).xyz; + + // compute distance of tangent to vertex along line segment in capsule + float distanceAlongSegment = -( dot( (worldC1 - position).xyz, segment ) / dot(segment, segment) ); + + float4 closestPoint = (worldC1 + float4(segment * distanceAlongSegment, 0.f)); + float distanceFromLine = length(position - closestPoint); + float distanceFromC1 = length(worldC1 - position); + float distanceFromC2 = length(worldC2 - position); + + // Final distance from collision, point to push from, direction to push in + // for impulse force + float dist; + float3 normalVector; + if( distanceAlongSegment < 0 ) + { + dist = distanceFromC1; + normalVector = normalize(position - worldC1).xyz; + } else if( distanceAlongSegment > 1.f ) { + dist = distanceFromC2; + normalVector = normalize(position - worldC2).xyz; + } else { + dist = distanceFromLine; + normalVector = normalize(position - closestPoint).xyz; + } + + float3 colliderLinearVelocity = localCollisionShapes[collision].linearVelocity.xyz; + float3 colliderAngularVelocity = localCollisionShapes[collision].angularVelocity.xyz; + float3 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position.xyz - worldTransform._m03_m13_m23); + + float minDistance = capsuleRadius + capsuleMargin; + + // In case of no collision, this is the value of velocity + velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt; + + + // Check for a collision + if( dist < minDistance ) + { + // Project back to surface along normal + position = position + float4((minDistance - dist)*normalVector*0.9, 0.f); + velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt; + float3 relativeVelocity = velocity - velocityOfSurfacePoint; + + float3 p1 = normalize(cross(normalVector, segment)); + float3 p2 = normalize(cross(p1, normalVector)); + // Full friction is sum of velocities in each direction of plane + float3 frictionVector = p1*dot(relativeVelocity, p1) + p2*dot(relativeVelocity, p2); + + // Real friction is peak friction corrected by friction coefficients + frictionVector = frictionVector * (colliderFriction*clothFriction); + + float approachSpeed = dot(relativeVelocity, normalVector); + + if( approachSpeed <= 0.0 ) + forceOnVertex -= frictionVector; + } + + } + } + } else { + // Update velocity + float3 difference = position.xyz - previousPosition.xyz; + velocity = difference*velocityCoefficient*isolverdt; + } + + g_vertexVelocities[nodeID] = float4(velocity, 0.f); + + // Update external force + g_vertexForces[nodeID] = float4(forceOnVertex, 0.f); + + g_vertexPositions[nodeID] = float4(position.xyz, 0.f); +} + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverBuffer_DX11.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverBuffer_DX11.h new file mode 100644 index 0000000..daf1ef8 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverBuffer_DX11.h @@ -0,0 +1,323 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H +#define BT_SOFT_BODY_SOLVER_BUFFER_DX11_H + +// DX11 support +#include +#include +#include +#include +#include + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } +#endif + +/** + * DX11 Buffer that tracks a host buffer on use to ensure size-correctness. + */ +template class btDX11Buffer +{ +protected: + ID3D11Device* m_d3dDevice; + ID3D11DeviceContext* m_d3dDeviceContext; + + ID3D11Buffer* m_Buffer; + ID3D11ShaderResourceView* m_SRV; + ID3D11UnorderedAccessView* m_UAV; + btAlignedObjectArray< ElementType >* m_CPUBuffer; + + // TODO: Separate this from the main class + // as read back buffers can be shared between buffers + ID3D11Buffer* m_readBackBuffer; + + int m_gpuSize; + bool m_onGPU; + + bool m_readOnlyOnGPU; + + bool createBuffer( ID3D11Buffer *preexistingBuffer = 0) + { + HRESULT hr = S_OK; + + // Create all CS buffers + if( preexistingBuffer ) + { + m_Buffer = preexistingBuffer; + } else { + D3D11_BUFFER_DESC buffer_desc; + ZeroMemory(&buffer_desc, sizeof(buffer_desc)); + buffer_desc.Usage = D3D11_USAGE_DEFAULT; + if( m_readOnlyOnGPU ) + buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + else + buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; + buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + + buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType); + // At a minimum the buffer must exist + if( buffer_desc.ByteWidth == 0 ) + buffer_desc.ByteWidth = sizeof(ElementType); + buffer_desc.StructureByteStride = sizeof(ElementType); + hr = m_d3dDevice->CreateBuffer(&buffer_desc, NULL, &m_Buffer); + if( FAILED( hr ) ) + return (hr==S_OK); + } + + if( m_readOnlyOnGPU ) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc; + ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc)); + srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN; + srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + + srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size(); + if( srvbuffer_desc.Buffer.ElementWidth == 0 ) + srvbuffer_desc.Buffer.ElementWidth = 1; + hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV); + if( FAILED( hr ) ) + return (hr==S_OK); + } else { + // Create SRV + D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc; + ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc)); + srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN; + srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + + srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size(); + if( srvbuffer_desc.Buffer.ElementWidth == 0 ) + srvbuffer_desc.Buffer.ElementWidth = 1; + hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV); + if( FAILED( hr ) ) + return (hr==S_OK); + + // Create UAV + D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc; + ZeroMemory(&uavbuffer_desc, sizeof(uavbuffer_desc)); + uavbuffer_desc.Format = DXGI_FORMAT_UNKNOWN; + uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + + uavbuffer_desc.Buffer.NumElements = m_CPUBuffer->size(); + if( uavbuffer_desc.Buffer.NumElements == 0 ) + uavbuffer_desc.Buffer.NumElements = 1; + hr = m_d3dDevice->CreateUnorderedAccessView(m_Buffer, &uavbuffer_desc, &m_UAV); + if( FAILED( hr ) ) + return (hr==S_OK); + + // Create read back buffer + D3D11_BUFFER_DESC readback_buffer_desc; + ZeroMemory(&readback_buffer_desc, sizeof(readback_buffer_desc)); + + readback_buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType); + readback_buffer_desc.Usage = D3D11_USAGE_STAGING; + readback_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + readback_buffer_desc.StructureByteStride = sizeof(ElementType); + hr = m_d3dDevice->CreateBuffer(&readback_buffer_desc, NULL, &m_readBackBuffer); + if( FAILED( hr ) ) + return (hr==S_OK); + } + + m_gpuSize = m_CPUBuffer->size(); + return true; + } + + + +public: + btDX11Buffer( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext, btAlignedObjectArray< ElementType > *CPUBuffer, bool readOnly ) + { + m_d3dDevice = d3dDevice; + m_d3dDeviceContext = d3dDeviceContext; + m_Buffer = 0; + m_SRV = 0; + m_UAV = 0; + m_readBackBuffer = 0; + + m_CPUBuffer = CPUBuffer; + + m_gpuSize = 0; + m_onGPU = false; + + m_readOnlyOnGPU = readOnly; + } + + virtual ~btDX11Buffer() + { + SAFE_RELEASE(m_Buffer); + SAFE_RELEASE(m_SRV); + SAFE_RELEASE(m_UAV); + SAFE_RELEASE(m_readBackBuffer); + } + + ID3D11ShaderResourceView* &getSRV() + { + return m_SRV; + } + + ID3D11UnorderedAccessView* &getUAV() + { + return m_UAV; + } + + ID3D11Buffer* &getBuffer() + { + return m_Buffer; + } + + /** + * Move the data to the GPU if it is not there already. + */ + bool moveToGPU() + { + // Reallocate if GPU size is too small + if( (m_CPUBuffer->size() > m_gpuSize ) ) + m_onGPU = false; + if( !m_onGPU && m_CPUBuffer->size() > 0 ) + { + // If the buffer doesn't exist or the CPU-side buffer has changed size, create + // We should really delete the old one, too, but let's leave that for later + if( !m_Buffer || (m_CPUBuffer->size() != m_gpuSize) ) + { + SAFE_RELEASE(m_Buffer); + SAFE_RELEASE(m_SRV); + SAFE_RELEASE(m_UAV); + SAFE_RELEASE(m_readBackBuffer); + if( !createBuffer() ) + { + btAssert("Buffer creation failed."); + return false; + } + } + + if( m_gpuSize > 0 ) + { + D3D11_BOX destRegion; + destRegion.left = 0; + destRegion.front = 0; + destRegion.top = 0; + destRegion.bottom = 1; + destRegion.back = 1; + destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType); + m_d3dDeviceContext->UpdateSubresource(m_Buffer, 0, &destRegion, &((*m_CPUBuffer)[0]), 0, 0); + + m_onGPU = true; + } + + } + + return true; + } + + /** + * Move the data back from the GPU if it is on there and isn't read only. + */ + bool moveFromGPU() + { + if( m_CPUBuffer->size() > 0 ) + { + if( m_onGPU && !m_readOnlyOnGPU ) + { + // Copy back + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + //m_pd3dImmediateContext->CopyResource(m_phAngVelReadBackBuffer, m_phAngVel); + + D3D11_BOX destRegion; + destRegion.left = 0; + destRegion.front = 0; + destRegion.top = 0; + destRegion.bottom = 1; + destRegion.back = 1; + + destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType); + m_d3dDeviceContext->CopySubresourceRegion( + m_readBackBuffer, + 0, + 0, + 0, + 0 , + m_Buffer, + 0, + &destRegion + ); + + m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource); + //memcpy(m_hAngVel, MappedResource.pData, (m_maxObjs * sizeof(float) )); + memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) )); + m_d3dDeviceContext->Unmap(m_readBackBuffer, 0); + + m_onGPU = false; + } + } + + return true; + } + + + /** + * Copy the data back from the GPU without changing its state to be CPU-side. + * Useful if we just want to view it on the host for visualization. + */ + bool copyFromGPU() + { + if( m_CPUBuffer->size() > 0 ) + { + if( m_onGPU && !m_readOnlyOnGPU ) + { + // Copy back + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + + D3D11_BOX destRegion; + destRegion.left = 0; + destRegion.front = 0; + destRegion.top = 0; + destRegion.bottom = 1; + destRegion.back = 1; + + destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType); + m_d3dDeviceContext->CopySubresourceRegion( + m_readBackBuffer, + 0, + 0, + 0, + 0 , + m_Buffer, + 0, + &destRegion + ); + + m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource); + //memcpy(m_hAngVel, MappedResource.pData, (m_maxObjs * sizeof(float) )); + memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) )); + m_d3dDeviceContext->Unmap(m_readBackBuffer, 0); + } + } + + return true; + } + + /** + * Call if data has changed on the CPU. + * Can then trigger a move to the GPU as necessary. + */ + virtual void changedOnCPU() + { + m_onGPU = false; + } +}; // class btDX11Buffer + + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11.h new file mode 100644 index 0000000..0f753ce --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11.h @@ -0,0 +1,103 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_DX11.h" + + +#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H +#define BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H + +struct ID3D11Device; +struct ID3D11DeviceContext; + + +class btSoftBodyLinkDataDX11 : public btSoftBodyLinkData +{ +public: + bool m_onGPU; + ID3D11Device *m_d3dDevice; + ID3D11DeviceContext *m_d3dDeviceContext; + + + btDX11Buffer m_dx11Links; + btDX11Buffer m_dx11LinkStrength; + btDX11Buffer m_dx11LinksMassLSC; + btDX11Buffer m_dx11LinksRestLengthSquared; + btDX11Buffer m_dx11LinksCLength; + btDX11Buffer m_dx11LinksLengthRatio; + btDX11Buffer m_dx11LinksRestLength; + btDX11Buffer m_dx11LinksMaterialLinearStiffnessCoefficient; + + struct BatchPair + { + int start; + int length; + + BatchPair() : + start(0), + length(0) + { + } + + BatchPair( int s, int l ) : + start( s ), + length( l ) + { + } + }; + + /** + * Link addressing information for each cloth. + * Allows link locations to be computed independently of data batching. + */ + btAlignedObjectArray< int > m_linkAddresses; + + /** + * Start and length values for computation batches over link data. + */ + btAlignedObjectArray< BatchPair > m_batchStartLengths; + + + //ID3D11Buffer* readBackBuffer; + + btSoftBodyLinkDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ); + + virtual ~btSoftBodyLinkDataDX11(); + + /** Allocate enough space in all link-related arrays to fit numLinks links */ + virtual void createLinks( int numLinks ); + + /** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ + virtual void setLinkAt( const LinkDescription &link, int linkIndex ); + + virtual bool onAccelerator(); + + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(); + + /** + * Generate (and later update) the batching for the entire link set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ + void generateBatches(); +}; + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11SIMDAware.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11SIMDAware.h new file mode 100644 index 0000000..82ce46a --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverLinkData_DX11SIMDAware.h @@ -0,0 +1,173 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_DX11.h" + +#ifndef BT_ACCELERATED_SOFT_BODY_LINK_DATA_DX11_SIMDAWARE_H +#define BT_ACCELERATED_SOFT_BODY_LINK_DATA_DX11_SIMDAWARE_H + +struct ID3D11Device; +struct ID3D11DeviceContext; + + +class btSoftBodyLinkDataDX11SIMDAware : public btSoftBodyLinkData +{ +public: + bool m_onGPU; + ID3D11Device *m_d3dDevice; + ID3D11DeviceContext *m_d3dDeviceContext; + + const int m_wavefrontSize; + const int m_linksPerWorkItem; + const int m_maxLinksPerWavefront; + int m_maxBatchesWithinWave; + int m_maxVerticesWithinWave; + int m_numWavefronts; + + int m_maxVertex; + + struct NumBatchesVerticesPair + { + int numBatches; + int numVertices; + }; + + // Array storing number of links in each wavefront + btAlignedObjectArray m_linksPerWavefront; + btAlignedObjectArray m_numBatchesAndVerticesWithinWaves; + btDX11Buffer< NumBatchesVerticesPair > m_dx11NumBatchesAndVerticesWithinWaves; + + // All arrays here will contain batches of m_maxLinksPerWavefront links + // ordered by wavefront. + // with either global vertex pairs or local vertex pairs + btAlignedObjectArray< int > m_wavefrontVerticesGlobalAddresses; // List of global vertices per wavefront + btDX11Buffer m_dx11WavefrontVerticesGlobalAddresses; + btAlignedObjectArray< LinkNodePair > m_linkVerticesLocalAddresses; // Vertex pair for the link + btDX11Buffer m_dx11LinkVerticesLocalAddresses; + btDX11Buffer m_dx11LinkStrength; + btDX11Buffer m_dx11LinksMassLSC; + btDX11Buffer m_dx11LinksRestLengthSquared; + btDX11Buffer m_dx11LinksRestLength; + btDX11Buffer m_dx11LinksMaterialLinearStiffnessCoefficient; + + struct BatchPair + { + int start; + int length; + + BatchPair() : + start(0), + length(0) + { + } + + BatchPair( int s, int l ) : + start( s ), + length( l ) + { + } + }; + + /** + * Link addressing information for each cloth. + * Allows link locations to be computed independently of data batching. + */ + btAlignedObjectArray< int > m_linkAddresses; + + /** + * Start and length values for computation batches over link data. + */ + btAlignedObjectArray< BatchPair > m_wavefrontBatchStartLengths; + + + //ID3D11Buffer* readBackBuffer; + + btSoftBodyLinkDataDX11SIMDAware( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ); + + virtual ~btSoftBodyLinkDataDX11SIMDAware(); + + /** Allocate enough space in all link-related arrays to fit numLinks links */ + virtual void createLinks( int numLinks ); + + /** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ + virtual void setLinkAt( const LinkDescription &link, int linkIndex ); + + virtual bool onAccelerator(); + + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(); + + /** + * Generate (and later update) the batching for the entire link set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ + void generateBatches(); + + int getMaxVerticesPerWavefront() + { + return m_maxVerticesWithinWave; + } + + int getWavefrontSize() + { + return m_wavefrontSize; + } + + int getLinksPerWorkItem() + { + return m_linksPerWorkItem; + } + + int getMaxLinksPerWavefront() + { + return m_maxLinksPerWavefront; + } + + int getMaxBatchesPerWavefront() + { + return m_maxBatchesWithinWave; + } + + int getNumWavefronts() + { + return m_numWavefronts; + } + + NumBatchesVerticesPair getNumBatchesAndVerticesWithinWavefront( int wavefront ) + { + return m_numBatchesAndVerticesWithinWaves[wavefront]; + } + + int getVertexGlobalAddresses( int vertexIndex ) + { + return m_wavefrontVerticesGlobalAddresses[vertexIndex]; + } + + /** + * Get post-batching local addresses of the vertex pair for a link assuming all vertices used by a wavefront are loaded locally. + */ + LinkNodePair getVertexPairLocalAddresses( int linkIndex ) + { + return m_linkVerticesLocalAddresses[linkIndex]; + } + +}; + + +#endif // #ifndef BT_ACCELERATED_SOFT_BODY_LINK_DATA_DX11_SIMDAWARE_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverTriangleData_DX11.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverTriangleData_DX11.h new file mode 100644 index 0000000..fc06a27 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverTriangleData_DX11.h @@ -0,0 +1,96 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_DX11.h" + + +#ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H +#define BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H + +struct ID3D11Device; +struct ID3D11DeviceContext; + +class btSoftBodyTriangleDataDX11 : public btSoftBodyTriangleData +{ +public: + bool m_onGPU; + ID3D11Device *m_d3dDevice; + ID3D11DeviceContext *m_d3dDeviceContext; + + btDX11Buffer m_dx11VertexIndices; + btDX11Buffer m_dx11Area; + btDX11Buffer m_dx11Normal; + + struct BatchPair + { + int start; + int length; + + BatchPair() : + start(0), + length(0) + { + } + + BatchPair( int s, int l ) : + start( s ), + length( l ) + { + } + }; + + + /** + * Link addressing information for each cloth. + * Allows link locations to be computed independently of data batching. + */ + btAlignedObjectArray< int > m_triangleAddresses; + + /** + * Start and length values for computation batches over link data. + */ + btAlignedObjectArray< BatchPair > m_batchStartLengths; + + //ID3D11Buffer* readBackBuffer; + +public: + btSoftBodyTriangleDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ); + + virtual ~btSoftBodyTriangleDataDX11(); + + + /** Allocate enough space in all link-related arrays to fit numLinks links */ + virtual void createTriangles( int numTriangles ); + + /** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ + virtual void setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex ); + + virtual bool onAccelerator(); + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(); + /** + * Generate (and later update) the batching for the entire triangle set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ + void generateBatches(); +}; + + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexBuffer_DX11.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexBuffer_DX11.h new file mode 100644 index 0000000..49d1d0f --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexBuffer_DX11.h @@ -0,0 +1,107 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H +#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H + + +#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h" + +#include +#include +#include +#include +#include + +class btDX11VertexBufferDescriptor : public btVertexBufferDescriptor +{ +protected: + /** Context of the DX11 device on which the vertex buffer is stored. */ + ID3D11DeviceContext* m_context; + /** DX11 vertex buffer */ + ID3D11Buffer* m_vertexBuffer; + /** UAV for DX11 buffer */ + ID3D11UnorderedAccessView* m_vertexBufferUAV; + + +public: + /** + * buffer is a pointer to the DX11 buffer to place the vertex data in. + * UAV is a pointer to the UAV representation of the buffer laid out in floats. + * vertexOffset is the offset in floats to the first vertex. + * vertexStride is the stride in floats between vertices. + */ + btDX11VertexBufferDescriptor( ID3D11DeviceContext* context, ID3D11Buffer* buffer, ID3D11UnorderedAccessView *UAV, int vertexOffset, int vertexStride ) + { + m_context = context; + m_vertexBuffer = buffer; + m_vertexBufferUAV = UAV; + m_vertexOffset = vertexOffset; + m_vertexStride = vertexStride; + m_hasVertexPositions = true; + } + + /** + * buffer is a pointer to the DX11 buffer to place the vertex data in. + * UAV is a pointer to the UAV representation of the buffer laid out in floats. + * vertexOffset is the offset in floats to the first vertex. + * vertexStride is the stride in floats between vertices. + * normalOffset is the offset in floats to the first normal. + * normalStride is the stride in floats between normals. + */ + btDX11VertexBufferDescriptor( ID3D11DeviceContext* context, ID3D11Buffer* buffer, ID3D11UnorderedAccessView *UAV, int vertexOffset, int vertexStride, int normalOffset, int normalStride ) + { + m_context = context; + m_vertexBuffer = buffer; + m_vertexBufferUAV = UAV; + m_vertexOffset = vertexOffset; + m_vertexStride = vertexStride; + m_hasVertexPositions = true; + + m_normalOffset = normalOffset; + m_normalStride = normalStride; + m_hasNormals = true; + } + + virtual ~btDX11VertexBufferDescriptor() + { + + } + + /** + * Return the type of the vertex buffer descriptor. + */ + virtual BufferTypes getBufferType() const + { + return DX11_BUFFER; + } + + virtual ID3D11DeviceContext* getContext() const + { + return m_context; + } + + virtual ID3D11Buffer* getbtDX11Buffer() const + { + return m_vertexBuffer; + } + + virtual ID3D11UnorderedAccessView* getDX11UAV() const + { + return m_vertexBufferUAV; + } +}; + +#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexData_DX11.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexData_DX11.h new file mode 100644 index 0000000..1374f3a --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexData_DX11.h @@ -0,0 +1,63 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_DX11.h" + + +#ifndef BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H +#define BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H + +class btSoftBodyLinkData; +class btSoftBodyLinkData::LinkDescription; + +struct ID3D11Device; +struct ID3D11DeviceContext; + +class btSoftBodyVertexDataDX11 : public btSoftBodyVertexData +{ +protected: + bool m_onGPU; + ID3D11Device *m_d3dDevice; + ID3D11DeviceContext *m_d3dDeviceContext; + +public: + btDX11Buffer m_dx11ClothIdentifier; + btDX11Buffer m_dx11VertexPosition; + btDX11Buffer m_dx11VertexPreviousPosition; + btDX11Buffer m_dx11VertexVelocity; + btDX11Buffer m_dx11VertexForceAccumulator; + btDX11Buffer m_dx11VertexNormal; + btDX11Buffer m_dx11VertexInverseMass; + btDX11Buffer m_dx11VertexArea; + btDX11Buffer m_dx11VertexTriangleCount; + + + //ID3D11Buffer* readBackBuffer; + +public: + btSoftBodyVertexDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ); + virtual ~btSoftBodyVertexDataDX11(); + + virtual bool onAccelerator(); + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(bool bCopy = false, bool bCopyMinimum = true); +}; + + +#endif // #ifndef BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.cpp b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.cpp new file mode 100644 index 0000000..d6d6739 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.cpp @@ -0,0 +1,2236 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "vectormath/vmInclude.h" + +#include "btSoftBodySolver_DX11.h" +#include "btSoftBodySolverVertexBuffer_DX11.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include //printf +#define MSTRINGIFY(A) #A +static char* PrepareLinksHLSLString = +#include "HLSL/PrepareLinks.hlsl" +static char* UpdatePositionsFromVelocitiesHLSLString = +#include "HLSL/UpdatePositionsFromVelocities.hlsl" +static char* SolvePositionsHLSLString = +#include "HLSL/SolvePositions.hlsl" +static char* UpdateNodesHLSLString = +#include "HLSL/UpdateNodes.hlsl" +static char* UpdatePositionsHLSLString = +#include "HLSL/UpdatePositions.hlsl" +static char* UpdateConstantsHLSLString = +#include "HLSL/UpdateConstants.hlsl" +static char* IntegrateHLSLString = +#include "HLSL/Integrate.hlsl" +static char* ApplyForcesHLSLString = +#include "HLSL/ApplyForces.hlsl" +static char* UpdateNormalsHLSLString = +#include "HLSL/UpdateNormals.hlsl" +static char* OutputToVertexArrayHLSLString = +#include "HLSL/OutputToVertexArray.hlsl" +static char* VSolveLinksHLSLString = +#include "HLSL/VSolveLinks.hlsl" +static char* ComputeBoundsHLSLString = +#include "HLSL/ComputeBounds.hlsl" +static char* SolveCollisionsAndUpdateVelocitiesHLSLString = +#include "HLSL/SolveCollisionsAndUpdateVelocities.hlsl" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +btSoftBodyLinkDataDX11::btSoftBodyLinkDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ) : + m_dx11Links( d3dDevice, d3dDeviceContext, &m_links, false ), + m_dx11LinkStrength( d3dDevice, d3dDeviceContext, &m_linkStrength, false ), + m_dx11LinksMassLSC( d3dDevice, d3dDeviceContext, &m_linksMassLSC, false ), + m_dx11LinksRestLengthSquared( d3dDevice, d3dDeviceContext, &m_linksRestLengthSquared, false ), + m_dx11LinksCLength( d3dDevice, d3dDeviceContext, &m_linksCLength, false ), + m_dx11LinksLengthRatio( d3dDevice, d3dDeviceContext, &m_linksLengthRatio, false ), + m_dx11LinksRestLength( d3dDevice, d3dDeviceContext, &m_linksRestLength, false ), + m_dx11LinksMaterialLinearStiffnessCoefficient( d3dDevice, d3dDeviceContext, &m_linksMaterialLinearStiffnessCoefficient, false ) +{ + m_d3dDevice = d3dDevice; + m_d3dDeviceContext = d3dDeviceContext; +} + +btSoftBodyLinkDataDX11::~btSoftBodyLinkDataDX11() +{ +} + +static Vectormath::Aos::Vector3 toVector3( const btVector3 &vec ) +{ + Vectormath::Aos::Vector3 outVec( vec.getX(), vec.getY(), vec.getZ() ); + return outVec; +} + +void btSoftBodyLinkDataDX11::createLinks( int numLinks ) +{ + int previousSize = m_links.size(); + int newSize = previousSize + numLinks; + + btSoftBodyLinkData::createLinks( numLinks ); + + // Resize the link addresses array as well + m_linkAddresses.resize( newSize ); +} + +void btSoftBodyLinkDataDX11::setLinkAt( const btSoftBodyLinkData::LinkDescription &link, int linkIndex ) +{ + btSoftBodyLinkData::setLinkAt( link, linkIndex ); + + // Set the link index correctly for initialisation + m_linkAddresses[linkIndex] = linkIndex; +} + +bool btSoftBodyLinkDataDX11::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyLinkDataDX11::moveToAccelerator() +{ + bool success = true; + success = success && m_dx11Links.moveToGPU(); + success = success && m_dx11LinkStrength.moveToGPU(); + success = success && m_dx11LinksMassLSC.moveToGPU(); + success = success && m_dx11LinksRestLengthSquared.moveToGPU(); + success = success && m_dx11LinksCLength.moveToGPU(); + success = success && m_dx11LinksLengthRatio.moveToGPU(); + success = success && m_dx11LinksRestLength.moveToGPU(); + success = success && m_dx11LinksMaterialLinearStiffnessCoefficient.moveToGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +bool btSoftBodyLinkDataDX11::moveFromAccelerator() +{ + bool success = true; + success = success && m_dx11Links.moveFromGPU(); + success = success && m_dx11LinkStrength.moveFromGPU(); + success = success && m_dx11LinksMassLSC.moveFromGPU(); + success = success && m_dx11LinksRestLengthSquared.moveFromGPU(); + success = success && m_dx11LinksCLength.moveFromGPU(); + success = success && m_dx11LinksLengthRatio.moveFromGPU(); + success = success && m_dx11LinksRestLength.moveFromGPU(); + success = success && m_dx11LinksMaterialLinearStiffnessCoefficient.moveFromGPU(); + + if( success ) + m_onGPU = false; + + return success; +} + +void btSoftBodyLinkDataDX11::generateBatches() +{ + int numLinks = getNumLinks(); + + // Do the graph colouring here temporarily + btAlignedObjectArray< int > batchValues; + batchValues.resize( numLinks, 0 ); + + // Find the maximum vertex value internally for now + int maxVertex = 0; + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + int vertex0 = getVertexPair(linkIndex).vertex0; + int vertex1 = getVertexPair(linkIndex).vertex1; + if( vertex0 > maxVertex ) + maxVertex = vertex0; + if( vertex1 > maxVertex ) + maxVertex = vertex1; + } + int numVertices = maxVertex + 1; + + // Set of lists, one for each node, specifying which colours are connected + // to that node. + // No two edges into a node can share a colour. + btAlignedObjectArray< btAlignedObjectArray< int > > vertexConnectedColourLists; + vertexConnectedColourLists.resize(numVertices); + + + + // Simple algorithm that chooses the lowest batch number + // that none of the links attached to either of the connected + // nodes is in + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + int linkLocation = m_linkAddresses[linkIndex]; + + int vertex0 = getVertexPair(linkLocation).vertex0; + int vertex1 = getVertexPair(linkLocation).vertex1; + + // Get the two node colour lists + btAlignedObjectArray< int > &colourListVertex0( vertexConnectedColourLists[vertex0] ); + btAlignedObjectArray< int > &colourListVertex1( vertexConnectedColourLists[vertex1] ); + + // Choose the minimum colour that is in neither list + int colour = 0; + while( colourListVertex0.findLinearSearch(colour) != colourListVertex0.size() || colourListVertex1.findLinearSearch(colour) != colourListVertex1.size() ) + ++colour; + // i should now be the minimum colour in neither list + // Add to the two lists so that future edges don't share + // And store the colour against this edge + + colourListVertex0.push_back(colour); + colourListVertex1.push_back(colour); + batchValues[linkIndex] = colour; + } + + // Check the colour counts + btAlignedObjectArray< int > batchCounts; + for( int i = 0; i < numLinks; ++i ) + { + int batch = batchValues[i]; + if( batch >= batchCounts.size() ) + batchCounts.push_back(1); + else + ++(batchCounts[batch]); + } + + m_batchStartLengths.resize(batchCounts.size()); + if( m_batchStartLengths.size() > 0 ) + { + m_batchStartLengths[0] = BatchPair( 0, 0 ); + + int sum = 0; + for( int batchIndex = 0; batchIndex < batchCounts.size(); ++batchIndex ) + { + m_batchStartLengths[batchIndex].start = sum; + m_batchStartLengths[batchIndex].length = batchCounts[batchIndex]; + sum += batchCounts[batchIndex]; + } + } + + ///////////////////////////// + // Sort data based on batches + + // Create source arrays by copying originals + btAlignedObjectArray m_links_Backup(m_links); + btAlignedObjectArray m_linkStrength_Backup(m_linkStrength); + btAlignedObjectArray m_linksMassLSC_Backup(m_linksMassLSC); + btAlignedObjectArray m_linksRestLengthSquared_Backup(m_linksRestLengthSquared); + btAlignedObjectArray m_linksCLength_Backup(m_linksCLength); + btAlignedObjectArray m_linksLengthRatio_Backup(m_linksLengthRatio); + btAlignedObjectArray m_linksRestLength_Backup(m_linksRestLength); + btAlignedObjectArray m_linksMaterialLinearStiffnessCoefficient_Backup(m_linksMaterialLinearStiffnessCoefficient); + + + for( int batch = 0; batch < batchCounts.size(); ++batch ) + batchCounts[batch] = 0; + + // Do sort as single pass into destination arrays + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + // To maintain locations run off the original link locations rather than the current position. + // It's not cache efficient, but as we run this rarely that should not matter. + // It's faster than searching the link location array for the current location and then updating it. + // The other alternative would be to unsort before resorting, but this is equivalent to doing that. + int linkLocation = m_linkAddresses[linkIndex]; + + // Obtain batch and calculate target location for the + // next element in that batch, incrementing the batch counter + // afterwards + int batch = batchValues[linkIndex]; + int newLocation = m_batchStartLengths[batch].start + batchCounts[batch]; + + batchCounts[batch] = batchCounts[batch] + 1; + m_links[newLocation] = m_links_Backup[linkLocation]; +#if 1 + m_linkStrength[newLocation] = m_linkStrength_Backup[linkLocation]; + m_linksMassLSC[newLocation] = m_linksMassLSC_Backup[linkLocation]; + m_linksRestLengthSquared[newLocation] = m_linksRestLengthSquared_Backup[linkLocation]; + m_linksLengthRatio[newLocation] = m_linksLengthRatio_Backup[linkLocation]; + m_linksRestLength[newLocation] = m_linksRestLength_Backup[linkLocation]; + m_linksMaterialLinearStiffnessCoefficient[newLocation] = m_linksMaterialLinearStiffnessCoefficient_Backup[linkLocation]; +#endif + // Update the locations array to account for the moved entry + m_linkAddresses[linkIndex] = newLocation; + } +} // void btSoftBodyLinkDataDX11::generateBatches() + + + +btSoftBodyVertexDataDX11::btSoftBodyVertexDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ) : + m_dx11ClothIdentifier( d3dDevice, d3dDeviceContext, &m_clothIdentifier, false ), + m_dx11VertexPosition( d3dDevice, d3dDeviceContext, &m_vertexPosition, false ), + m_dx11VertexPreviousPosition( d3dDevice, d3dDeviceContext, &m_vertexPreviousPosition, false ), + m_dx11VertexVelocity( d3dDevice, d3dDeviceContext, &m_vertexVelocity, false ), + m_dx11VertexForceAccumulator( d3dDevice, d3dDeviceContext, &m_vertexForceAccumulator, false ), + m_dx11VertexNormal( d3dDevice, d3dDeviceContext, &m_vertexNormal, false ), + m_dx11VertexInverseMass( d3dDevice, d3dDeviceContext, &m_vertexInverseMass, false ), + m_dx11VertexArea( d3dDevice, d3dDeviceContext, &m_vertexArea, false ), + m_dx11VertexTriangleCount( d3dDevice, d3dDeviceContext, &m_vertexTriangleCount, false ) +{ + m_d3dDevice = d3dDevice; + m_d3dDeviceContext = d3dDeviceContext; +} + +btSoftBodyVertexDataDX11::~btSoftBodyVertexDataDX11() +{ + +} + +bool btSoftBodyVertexDataDX11::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyVertexDataDX11::moveToAccelerator() +{ + bool success = true; + success = success && m_dx11ClothIdentifier.moveToGPU(); + success = success && m_dx11VertexPosition.moveToGPU(); + success = success && m_dx11VertexPreviousPosition.moveToGPU(); + success = success && m_dx11VertexVelocity.moveToGPU(); + success = success && m_dx11VertexForceAccumulator.moveToGPU(); + success = success && m_dx11VertexNormal.moveToGPU(); + success = success && m_dx11VertexInverseMass.moveToGPU(); + success = success && m_dx11VertexArea.moveToGPU(); + success = success && m_dx11VertexTriangleCount.moveToGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +bool btSoftBodyVertexDataDX11::moveFromAccelerator(bool bCopy, bool bCopyMinimum) +{ + bool success = true; + + if (!bCopy) + { + success = success && m_dx11ClothIdentifier.moveFromGPU(); + success = success && m_dx11VertexPosition.moveFromGPU(); + success = success && m_dx11VertexPreviousPosition.moveFromGPU(); + success = success && m_dx11VertexVelocity.moveFromGPU(); + success = success && m_dx11VertexForceAccumulator.moveFromGPU(); + success = success && m_dx11VertexNormal.moveFromGPU(); + success = success && m_dx11VertexInverseMass.moveFromGPU(); + success = success && m_dx11VertexArea.moveFromGPU(); + success = success && m_dx11VertexTriangleCount.moveFromGPU(); + } + else + { + if (bCopyMinimum) + { + success = success && m_dx11VertexPosition.copyFromGPU(); + success = success && m_dx11VertexNormal.copyFromGPU(); + } + else + { + success = success && m_dx11ClothIdentifier.copyFromGPU(); + success = success && m_dx11VertexPosition.copyFromGPU(); + success = success && m_dx11VertexPreviousPosition.copyFromGPU(); + success = success && m_dx11VertexVelocity.copyFromGPU(); + success = success && m_dx11VertexForceAccumulator.copyFromGPU(); + success = success && m_dx11VertexNormal.copyFromGPU(); + success = success && m_dx11VertexInverseMass.copyFromGPU(); + success = success && m_dx11VertexArea.copyFromGPU(); + success = success && m_dx11VertexTriangleCount.copyFromGPU(); + } + } + + if( success ) + m_onGPU = true; + + return success; +} + + +btSoftBodyTriangleDataDX11::btSoftBodyTriangleDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ) : + m_dx11VertexIndices( d3dDevice, d3dDeviceContext, &m_vertexIndices, false ), + m_dx11Area( d3dDevice, d3dDeviceContext, &m_area, false ), + m_dx11Normal( d3dDevice, d3dDeviceContext, &m_normal, false ) +{ + m_d3dDevice = d3dDevice; + m_d3dDeviceContext = d3dDeviceContext; +} + +btSoftBodyTriangleDataDX11::~btSoftBodyTriangleDataDX11() +{ + +} + + +/** Allocate enough space in all link-related arrays to fit numLinks links */ +void btSoftBodyTriangleDataDX11::createTriangles( int numTriangles ) +{ + int previousSize = getNumTriangles(); + int newSize = previousSize + numTriangles; + + btSoftBodyTriangleData::createTriangles( numTriangles ); + + // Resize the link addresses array as well + m_triangleAddresses.resize( newSize ); +} + +/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ +void btSoftBodyTriangleDataDX11::setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex ) +{ + btSoftBodyTriangleData::setTriangleAt( triangle, triangleIndex ); + + m_triangleAddresses[triangleIndex] = triangleIndex; +} + +bool btSoftBodyTriangleDataDX11::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyTriangleDataDX11::moveToAccelerator() +{ + bool success = true; + success = success && m_dx11VertexIndices.moveToGPU(); + success = success && m_dx11Area.moveToGPU(); + success = success && m_dx11Normal.moveToGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +bool btSoftBodyTriangleDataDX11::moveFromAccelerator() +{ + bool success = true; + success = success && m_dx11VertexIndices.moveFromGPU(); + success = success && m_dx11Area.moveFromGPU(); + success = success && m_dx11Normal.moveFromGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +/** + * Generate (and later update) the batching for the entire triangle set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ +void btSoftBodyTriangleDataDX11::generateBatches() +{ + int numTriangles = getNumTriangles(); + if( numTriangles == 0 ) + return; + + // Do the graph colouring here temporarily + btAlignedObjectArray< int > batchValues; + batchValues.resize( numTriangles ); + + // Find the maximum vertex value internally for now + int maxVertex = 0; + for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex ) + { + int vertex0 = getVertexSet(triangleIndex).vertex0; + int vertex1 = getVertexSet(triangleIndex).vertex1; + int vertex2 = getVertexSet(triangleIndex).vertex2; + + if( vertex0 > maxVertex ) + maxVertex = vertex0; + if( vertex1 > maxVertex ) + maxVertex = vertex1; + if( vertex2 > maxVertex ) + maxVertex = vertex2; + } + int numVertices = maxVertex + 1; + + // Set of lists, one for each node, specifying which colours are connected + // to that node. + // No two edges into a node can share a colour. + btAlignedObjectArray< btAlignedObjectArray< int > > vertexConnectedColourLists; + vertexConnectedColourLists.resize(numVertices); + + + //std::cout << "\n"; + // Simple algorithm that chooses the lowest batch number + // that none of the faces attached to either of the connected + // nodes is in + for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex ) + { + // To maintain locations run off the original link locations rather than the current position. + // It's not cache efficient, but as we run this rarely that should not matter. + // It's faster than searching the link location array for the current location and then updating it. + // The other alternative would be to unsort before resorting, but this is equivalent to doing that. + int triangleLocation = m_triangleAddresses[triangleIndex]; + + int vertex0 = getVertexSet(triangleLocation).vertex0; + int vertex1 = getVertexSet(triangleLocation).vertex1; + int vertex2 = getVertexSet(triangleLocation).vertex2; + + // Get the three node colour lists + btAlignedObjectArray< int > &colourListVertex0( vertexConnectedColourLists[vertex0] ); + btAlignedObjectArray< int > &colourListVertex1( vertexConnectedColourLists[vertex1] ); + btAlignedObjectArray< int > &colourListVertex2( vertexConnectedColourLists[vertex2] ); + + // Choose the minimum colour that is in none of the lists + int colour = 0; + while( + colourListVertex0.findLinearSearch(colour) != colourListVertex0.size() || + colourListVertex1.findLinearSearch(colour) != colourListVertex1.size() || + colourListVertex2.findLinearSearch(colour) != colourListVertex2.size() ) + { + ++colour; + } + // i should now be the minimum colour in neither list + // Add to the three lists so that future edges don't share + // And store the colour against this face + colourListVertex0.push_back(colour); + colourListVertex1.push_back(colour); + colourListVertex2.push_back(colour); + + batchValues[triangleIndex] = colour; + } + + + // Check the colour counts + btAlignedObjectArray< int > batchCounts; + for( int i = 0; i < numTriangles; ++i ) + { + int batch = batchValues[i]; + if( batch >= batchCounts.size() ) + batchCounts.push_back(1); + else + ++(batchCounts[batch]); + } + + + m_batchStartLengths.resize(batchCounts.size()); + m_batchStartLengths[0] = BatchPair( 0, 0 ); + + + int sum = 0; + for( int batchIndex = 0; batchIndex < batchCounts.size(); ++batchIndex ) + { + m_batchStartLengths[batchIndex].start = sum; + m_batchStartLengths[batchIndex].length = batchCounts[batchIndex]; + sum += batchCounts[batchIndex]; + } + + ///////////////////////////// + // Sort data based on batches + + // Create source arrays by copying originals + btAlignedObjectArray m_vertexIndices_Backup(m_vertexIndices); + btAlignedObjectArray m_area_Backup(m_area); + btAlignedObjectArray m_normal_Backup(m_normal); + + + for( int batch = 0; batch < batchCounts.size(); ++batch ) + batchCounts[batch] = 0; + + // Do sort as single pass into destination arrays + for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex ) + { + // To maintain locations run off the original link locations rather than the current position. + // It's not cache efficient, but as we run this rarely that should not matter. + // It's faster than searching the link location array for the current location and then updating it. + // The other alternative would be to unsort before resorting, but this is equivalent to doing that. + int triangleLocation = m_triangleAddresses[triangleIndex]; + + // Obtain batch and calculate target location for the + // next element in that batch, incrementing the batch counter + // afterwards + int batch = batchValues[triangleIndex]; + int newLocation = m_batchStartLengths[batch].start + batchCounts[batch]; + + batchCounts[batch] = batchCounts[batch] + 1; + m_vertexIndices[newLocation] = m_vertexIndices_Backup[triangleLocation]; + m_area[newLocation] = m_area_Backup[triangleLocation]; + m_normal[newLocation] = m_normal_Backup[triangleLocation]; + + // Update the locations array to account for the moved entry + m_triangleAddresses[triangleIndex] = newLocation; + } +} // btSoftBodyTriangleDataDX11::generateBatches + + + + + + + + + + + + +btDX11SoftBodySolver::btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context, DXFunctions::CompileFromMemoryFunc dx11CompileFromMemory) : + m_dx11Device( dx11Device ), + m_dx11Context( dx11Context ), + dxFunctions( m_dx11Device, m_dx11Context, dx11CompileFromMemory ), + m_linkData(m_dx11Device, m_dx11Context), + m_vertexData(m_dx11Device, m_dx11Context), + m_triangleData(m_dx11Device, m_dx11Context), + m_dx11PerClothAcceleration( m_dx11Device, m_dx11Context, &m_perClothAcceleration, true ), + m_dx11PerClothWindVelocity( m_dx11Device, m_dx11Context, &m_perClothWindVelocity, true ), + m_dx11PerClothDampingFactor( m_dx11Device, m_dx11Context, &m_perClothDampingFactor, true ), + m_dx11PerClothVelocityCorrectionCoefficient( m_dx11Device, m_dx11Context, &m_perClothVelocityCorrectionCoefficient, true ), + m_dx11PerClothLiftFactor( m_dx11Device, m_dx11Context, &m_perClothLiftFactor, true ), + m_dx11PerClothDragFactor( m_dx11Device, m_dx11Context, &m_perClothDragFactor, true ), + m_dx11PerClothMediumDensity( m_dx11Device, m_dx11Context, &m_perClothMediumDensity, true ), + m_dx11PerClothCollisionObjects( m_dx11Device, m_dx11Context, &m_perClothCollisionObjects, true ), + m_dx11CollisionObjectDetails( m_dx11Device, m_dx11Context, &m_collisionObjectDetails, true ), + m_dx11PerClothMinBounds( m_dx11Device, m_dx11Context, &m_perClothMinBounds, false ), + m_dx11PerClothMaxBounds( m_dx11Device, m_dx11Context, &m_perClothMaxBounds, false ), + m_dx11PerClothFriction( m_dx11Device, m_dx11Context, &m_perClothFriction, false ), + m_enableUpdateBounds(false) +{ + // Initial we will clearly need to update solver constants + // For now this is global for the cloths linked with this solver - we should probably make this body specific + // for performance in future once we understand more clearly when constants need to be updated + m_updateSolverConstants = true; + + m_shadersInitialized = false; +} + +btDX11SoftBodySolver::~btDX11SoftBodySolver() +{ + releaseKernels(); +} + +void btDX11SoftBodySolver::releaseKernels() +{ + + SAFE_RELEASE( prepareLinksKernel.kernel ); + SAFE_RELEASE( prepareLinksKernel.constBuffer ); + SAFE_RELEASE( integrateKernel.kernel ); + SAFE_RELEASE( integrateKernel.constBuffer ); + SAFE_RELEASE( integrateKernel.kernel ); + SAFE_RELEASE( solvePositionsFromLinksKernel.constBuffer ); + SAFE_RELEASE( solvePositionsFromLinksKernel.kernel ); + SAFE_RELEASE( updatePositionsFromVelocitiesKernel.constBuffer ); + SAFE_RELEASE( updatePositionsFromVelocitiesKernel.kernel ); + SAFE_RELEASE( updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer ); + SAFE_RELEASE( updateVelocitiesFromPositionsWithoutVelocitiesKernel.kernel ); + SAFE_RELEASE( updateVelocitiesFromPositionsWithVelocitiesKernel.constBuffer ); + SAFE_RELEASE( updateVelocitiesFromPositionsWithVelocitiesKernel.kernel ); + SAFE_RELEASE( resetNormalsAndAreasKernel.constBuffer ); + SAFE_RELEASE( resetNormalsAndAreasKernel.kernel ); + SAFE_RELEASE( normalizeNormalsAndAreasKernel.constBuffer ); + SAFE_RELEASE( normalizeNormalsAndAreasKernel.kernel ); + SAFE_RELEASE( updateSoftBodiesKernel.constBuffer ); + SAFE_RELEASE( updateSoftBodiesKernel.kernel ); + SAFE_RELEASE( solveCollisionsAndUpdateVelocitiesKernel.kernel ); + SAFE_RELEASE( solveCollisionsAndUpdateVelocitiesKernel.constBuffer ); + SAFE_RELEASE( computeBoundsKernel.kernel ); + SAFE_RELEASE( computeBoundsKernel.constBuffer ); + SAFE_RELEASE( vSolveLinksKernel.kernel ); + SAFE_RELEASE( vSolveLinksKernel.constBuffer ); + + SAFE_RELEASE( addVelocityKernel.constBuffer ); + SAFE_RELEASE( addVelocityKernel.kernel ); + SAFE_RELEASE( applyForcesKernel.constBuffer ); + SAFE_RELEASE( applyForcesKernel.kernel ); + + m_shadersInitialized = false; +} + + +void btDX11SoftBodySolver::copyBackToSoftBodies(bool bMove) +{ + // Move the vertex data back to the host first + m_vertexData.moveFromAccelerator(!bMove); + + // Loop over soft bodies, copying all the vertex positions back for each body in turn + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[ softBodyIndex ]; + btSoftBody *softBody = softBodyInterface->getSoftBody(); + + int firstVertex = softBodyInterface->getFirstVertex(); + int numVertices = softBodyInterface->getNumVertices(); + + // Copy vertices from solver back into the softbody + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + using Vectormath::Aos::Point3; + Point3 vertexPosition( getVertexData().getVertexPositions()[firstVertex + vertex] ); + + softBody->m_nodes[vertex].m_x.setX( vertexPosition.getX() ); + softBody->m_nodes[vertex].m_x.setY( vertexPosition.getY() ); + softBody->m_nodes[vertex].m_x.setZ( vertexPosition.getZ() ); + + softBody->m_nodes[vertex].m_n.setX( vertexPosition.getX() ); + softBody->m_nodes[vertex].m_n.setY( vertexPosition.getY() ); + softBody->m_nodes[vertex].m_n.setZ( vertexPosition.getZ() ); + } + } +} // btDX11SoftBodySolver::copyBackToSoftBodies + + +void btDX11SoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies, bool forceUpdate ) +{ + if( forceUpdate || m_softBodySet.size() != softBodies.size() ) + { + // Have a change in the soft body set so update, reloading all the data + getVertexData().clear(); + getTriangleData().clear(); + getLinkData().clear(); + m_softBodySet.resize(0); + + + for( int softBodyIndex = 0; softBodyIndex < softBodies.size(); ++softBodyIndex ) + { + btSoftBody *softBody = softBodies[ softBodyIndex ]; + using Vectormath::Aos::Matrix3; + using Vectormath::Aos::Point3; + + // Create SoftBody that will store the information within the solver + btAcceleratedSoftBodyInterface *newSoftBody = new btAcceleratedSoftBodyInterface( softBody ); + m_softBodySet.push_back( newSoftBody ); + + m_perClothAcceleration.push_back( toVector3(softBody->getWorldInfo()->m_gravity) ); + m_perClothDampingFactor.push_back(softBody->m_cfg.kDP); + m_perClothVelocityCorrectionCoefficient.push_back( softBody->m_cfg.kVCF ); + m_perClothLiftFactor.push_back( softBody->m_cfg.kLF ); + m_perClothDragFactor.push_back( softBody->m_cfg.kDG ); + m_perClothMediumDensity.push_back(softBody->getWorldInfo()->air_density); + // Simple init values. Actually we'll put 0 and -1 into them at the appropriate time + m_perClothMinBounds.push_back( UIntVector3( 0, 0, 0 ) ); + m_perClothMaxBounds.push_back( UIntVector3( UINT_MAX, UINT_MAX, UINT_MAX ) ); + m_perClothFriction.push_back( softBody->getFriction() ); + m_perClothCollisionObjects.push_back( CollisionObjectIndices(-1, -1) ); + + // Add space for new vertices and triangles in the default solver for now + // TODO: Include space here for tearing too later + int firstVertex = getVertexData().getNumVertices(); + int numVertices = softBody->m_nodes.size(); + int maxVertices = numVertices; + // Allocate space for new vertices in all the vertex arrays + getVertexData().createVertices( maxVertices, softBodyIndex ); + + int firstTriangle = getTriangleData().getNumTriangles(); + int numTriangles = softBody->m_faces.size(); + int maxTriangles = numTriangles; + getTriangleData().createTriangles( maxTriangles ); + + // Copy vertices from softbody into the solver + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + Point3 multPoint(softBody->m_nodes[vertex].m_x.getX(), softBody->m_nodes[vertex].m_x.getY(), softBody->m_nodes[vertex].m_x.getZ()); + btSoftBodyVertexData::VertexDescription desc; + + // TODO: Position in the softbody might be pre-transformed + // or we may need to adapt for the pose. + //desc.setPosition( cloth.getMeshTransform()*multPoint ); + desc.setPosition( multPoint ); + + float vertexInverseMass = softBody->m_nodes[vertex].m_im; + desc.setInverseMass(vertexInverseMass); + getVertexData().setVertexAt( desc, firstVertex + vertex ); + } + + // Copy triangles similarly + // We're assuming here that vertex indices are based on the firstVertex rather than the entire scene + for( int triangle = 0; triangle < numTriangles; ++triangle ) + { + // Note that large array storage is relative to the array not to the cloth + // So we need to add firstVertex to each value + int vertexIndex0 = (softBody->m_faces[triangle].m_n[0] - &(softBody->m_nodes[0])); + int vertexIndex1 = (softBody->m_faces[triangle].m_n[1] - &(softBody->m_nodes[0])); + int vertexIndex2 = (softBody->m_faces[triangle].m_n[2] - &(softBody->m_nodes[0])); + btSoftBodyTriangleData::TriangleDescription newTriangle(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, vertexIndex2 + firstVertex); + getTriangleData().setTriangleAt( newTriangle, firstTriangle + triangle ); + + // Increase vertex triangle counts for this triangle + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex0)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex1)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex2)++; + } + + int firstLink = getLinkData().getNumLinks(); + int numLinks = softBody->m_links.size(); + int maxLinks = numLinks; + + // Allocate space for the links + getLinkData().createLinks( numLinks ); + + // Add the links + for( int link = 0; link < numLinks; ++link ) + { + int vertexIndex0 = softBody->m_links[link].m_n[0] - &(softBody->m_nodes[0]); + int vertexIndex1 = softBody->m_links[link].m_n[1] - &(softBody->m_nodes[0]); + + btSoftBodyLinkData::LinkDescription newLink(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, softBody->m_links[link].m_material->m_kLST); + newLink.setLinkStrength(1.f); + getLinkData().setLinkAt(newLink, firstLink + link); + } + + newSoftBody->setFirstVertex( firstVertex ); + newSoftBody->setFirstTriangle( firstTriangle ); + newSoftBody->setNumVertices( numVertices ); + newSoftBody->setMaxVertices( maxVertices ); + newSoftBody->setNumTriangles( numTriangles ); + newSoftBody->setMaxTriangles( maxTriangles ); + newSoftBody->setFirstLink( firstLink ); + newSoftBody->setNumLinks( numLinks ); + } + + + + updateConstants(0.f); + + + m_linkData.generateBatches(); + m_triangleData.generateBatches(); + } +} + + +btSoftBodyLinkData &btDX11SoftBodySolver::getLinkData() +{ + // TODO: Consider setting link data to "changed" here + return m_linkData; +} + +btSoftBodyVertexData &btDX11SoftBodySolver::getVertexData() +{ + // TODO: Consider setting vertex data to "changed" here + return m_vertexData; +} + +btSoftBodyTriangleData &btDX11SoftBodySolver::getTriangleData() +{ + // TODO: Consider setting triangle data to "changed" here + return m_triangleData; +} + +bool btDX11SoftBodySolver::checkInitialized() +{ + if( !m_shadersInitialized ) + if( buildShaders() ) + m_shadersInitialized = true; + + return m_shadersInitialized; +} + +void btDX11SoftBodySolver::resetNormalsAndAreas( int numVertices ) +{ + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + UpdateSoftBodiesCB constBuffer; + + constBuffer.numNodes = numVertices; + constBuffer.epsilon = FLT_EPSILON; + + // Todo: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( integrateKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(UpdateSoftBodiesCB) ); + m_dx11Context->Unmap( integrateKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &integrateKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexNormal.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexArea.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( resetNormalsAndAreasKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks, 1, 1 ); + + { + // Tidy up + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::resetNormalsAndAreas + +void btDX11SoftBodySolver::normalizeNormalsAndAreas( int numVertices ) +{ + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + UpdateSoftBodiesCB constBuffer; + + constBuffer.numNodes = numVertices; + constBuffer.epsilon = FLT_EPSILON; + + // Todo: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( integrateKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(UpdateSoftBodiesCB) ); + m_dx11Context->Unmap( integrateKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &integrateKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 2, 1, &(m_vertexData.m_dx11VertexTriangleCount.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexNormal.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexArea.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( normalizeNormalsAndAreasKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks, 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::normalizeNormalsAndAreas + +void btDX11SoftBodySolver::executeUpdateSoftBodies( int firstTriangle, int numTriangles ) +{ + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + UpdateSoftBodiesCB constBuffer; + + constBuffer.startFace = firstTriangle; + constBuffer.numFaces = numTriangles; + + // Todo: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( updateSoftBodiesKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(UpdateSoftBodiesCB) ); + m_dx11Context->Unmap( updateSoftBodiesKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &updateSoftBodiesKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_triangleData.m_dx11VertexIndices.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexPosition.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexNormal.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexArea.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 2, 1, &(m_triangleData.m_dx11Normal.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 3, 1, &(m_triangleData.m_dx11Area.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( updateSoftBodiesKernel.kernel, NULL, 0 ); + + int numBlocks = (numTriangles + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks, 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 4, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::executeUpdateSoftBodies + +void btDX11SoftBodySolver::updateSoftBodies() +{ + using namespace Vectormath::Aos; + + + int numVertices = m_vertexData.getNumVertices(); + int numTriangles = m_triangleData.getNumTriangles(); + + // Ensure data is on accelerator + m_vertexData.moveToAccelerator(); + m_triangleData.moveToAccelerator(); + + resetNormalsAndAreas( numVertices ); + + + // Go through triangle batches so updates occur correctly + for( int batchIndex = 0; batchIndex < m_triangleData.m_batchStartLengths.size(); ++batchIndex ) + { + + int startTriangle = m_triangleData.m_batchStartLengths[batchIndex].start; + int numTriangles = m_triangleData.m_batchStartLengths[batchIndex].length; + + executeUpdateSoftBodies( startTriangle, numTriangles ); + } + + + normalizeNormalsAndAreas( numVertices ); + + +} // btDX11SoftBodySolver::updateSoftBodies + + +Vectormath::Aos::Vector3 btDX11SoftBodySolver::ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a ) +{ + return a*Vectormath::Aos::dot(v, a); +} + +void btDX11SoftBodySolver::ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce ) +{ + float dtInverseMass = solverdt*inverseMass; + if( Vectormath::Aos::lengthSqr(force * dtInverseMass) > Vectormath::Aos::lengthSqr(vertexVelocity) ) + { + vertexForce -= ProjectOnAxis( vertexVelocity, normalize( force ) )/dtInverseMass; + } else { + vertexForce += force; + } +} + +void btDX11SoftBodySolver::applyForces( float solverdt ) +{ + using namespace Vectormath::Aos; + + + // Ensure data is on accelerator + m_vertexData.moveToAccelerator(); + m_dx11PerClothAcceleration.moveToGPU(); + m_dx11PerClothLiftFactor.moveToGPU(); + m_dx11PerClothDragFactor.moveToGPU(); + m_dx11PerClothMediumDensity.moveToGPU(); + m_dx11PerClothWindVelocity.moveToGPU(); + + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + ApplyForcesCB constBuffer; + + constBuffer.numNodes = m_vertexData.getNumVertices(); + constBuffer.solverdt = solverdt; + constBuffer.epsilon = FLT_EPSILON; + + // Todo: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( integrateKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(ApplyForcesCB) ); + m_dx11Context->Unmap( integrateKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &integrateKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11ClothIdentifier.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexNormal.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_vertexData.m_dx11VertexArea.getSRV()) ); + m_dx11Context->CSSetShaderResources( 3, 1, &(m_vertexData.m_dx11VertexInverseMass.getSRV()) ); + m_dx11Context->CSSetShaderResources( 4, 1, &(m_dx11PerClothLiftFactor.getSRV()) ); + m_dx11Context->CSSetShaderResources( 5, 1, &(m_dx11PerClothDragFactor.getSRV()) ); + m_dx11Context->CSSetShaderResources( 6, 1, &(m_dx11PerClothWindVelocity.getSRV()) ); + m_dx11Context->CSSetShaderResources( 7, 1, &(m_dx11PerClothAcceleration.getSRV()) ); + m_dx11Context->CSSetShaderResources( 8, 1, &(m_dx11PerClothMediumDensity.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexForceAccumulator.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexVelocity.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( applyForcesKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks, 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 4, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 5, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 6, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 7, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 8, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::applyForces + +/** + * Integrate motion on the solver. + */ +void btDX11SoftBodySolver::integrate( float solverdt ) +{ + // TEMPORARY COPIES + m_vertexData.moveToAccelerator(); + + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + IntegrateCB constBuffer; + + constBuffer.numNodes = m_vertexData.getNumVertices(); + constBuffer.solverdt = solverdt; + + // Todo: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( integrateKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(IntegrateCB) ); + m_dx11Context->Unmap( integrateKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &integrateKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11VertexInverseMass.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexPosition.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexVelocity.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 2, 1, &(m_vertexData.m_dx11VertexPreviousPosition.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 3, 1, &(m_vertexData.m_dx11VertexForceAccumulator.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( integrateKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks, 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 2, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 3, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::integrate + +float btDX11SoftBodySolver::computeTriangleArea( + const Vectormath::Aos::Point3 &vertex0, + const Vectormath::Aos::Point3 &vertex1, + const Vectormath::Aos::Point3 &vertex2 ) +{ + Vectormath::Aos::Vector3 a = vertex1 - vertex0; + Vectormath::Aos::Vector3 b = vertex2 - vertex0; + Vectormath::Aos::Vector3 crossProduct = cross(a, b); + float area = length( crossProduct ); + return area; +} // btDX11SoftBodySolver::computeTriangleArea + + +void btDX11SoftBodySolver::updateBounds() +{ + using Vectormath::Aos::Point3; + // Interpretation structure for float and int + + struct FPRep { + unsigned int mantissa : 23; + unsigned int exponent : 8; + unsigned int sign : 1; + }; + union FloatAsInt + { + float floatValue; + int intValue; + unsigned int uintValue; + FPRep fpRep; + }; + + + // Update bounds array to min and max int values to allow easy atomics + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + m_perClothMinBounds[softBodyIndex] = UIntVector3( UINT_MAX, UINT_MAX, UINT_MAX ); + m_perClothMaxBounds[softBodyIndex] = UIntVector3( 0, 0, 0 ); + } + + m_dx11PerClothMinBounds.moveToGPU(); + m_dx11PerClothMaxBounds.moveToGPU(); + + + computeBounds( ); + + + m_dx11PerClothMinBounds.moveFromGPU(); + m_dx11PerClothMaxBounds.moveFromGPU(); + + + + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + UIntVector3 minBoundUInt = m_perClothMinBounds[softBodyIndex]; + UIntVector3 maxBoundUInt = m_perClothMaxBounds[softBodyIndex]; + + // Convert back to float + FloatAsInt fai; + + btVector3 minBound; + fai.uintValue = minBoundUInt.x; + fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000); + minBound.setX( fai.floatValue ); + fai.uintValue = minBoundUInt.y; + fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000); + minBound.setY( fai.floatValue ); + fai.uintValue = minBoundUInt.z; + fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000); + minBound.setZ( fai.floatValue ); + + btVector3 maxBound; + fai.uintValue = maxBoundUInt.x; + fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000); + maxBound.setX( fai.floatValue ); + fai.uintValue = maxBoundUInt.y; + fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000); + maxBound.setY( fai.floatValue ); + fai.uintValue = maxBoundUInt.z; + fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000); + maxBound.setZ( fai.floatValue ); + + // And finally assign to the soft body + m_softBodySet[softBodyIndex]->updateBounds( minBound, maxBound ); + } +} + +void btDX11SoftBodySolver::updateConstants( float timeStep ) +{ + using namespace Vectormath::Aos; + + if( m_updateSolverConstants ) + { + m_updateSolverConstants = false; + + // Will have to redo this if we change the structure (tear, maybe) or various other possible changes + + // Initialise link constants + const int numLinks = m_linkData.getNumLinks(); + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair &vertices( m_linkData.getVertexPair(linkIndex) ); + m_linkData.getRestLength(linkIndex) = length((m_vertexData.getPosition( vertices.vertex0 ) - m_vertexData.getPosition( vertices.vertex1 ))); + float invMass0 = m_vertexData.getInverseMass(vertices.vertex0); + float invMass1 = m_vertexData.getInverseMass(vertices.vertex1); + float linearStiffness = m_linkData.getLinearStiffnessCoefficient(linkIndex); + float massLSC = (invMass0 + invMass1)/linearStiffness; + m_linkData.getMassLSC(linkIndex) = massLSC; + float restLength = m_linkData.getRestLength(linkIndex); + float restLengthSquared = restLength*restLength; + m_linkData.getRestLengthSquared(linkIndex) = restLengthSquared; + } + } +} // btDX11SoftBodySolver::updateConstants + +/** + * Sort the collision object details array and generate indexing into it for the per-cloth collision object array. + */ +void btDX11SoftBodySolver::prepareCollisionConstraints() +{ + // First do a simple sort on the collision objects + btAlignedObjectArray numObjectsPerClothPrefixSum; + btAlignedObjectArray numObjectsPerCloth; + numObjectsPerCloth.resize( m_softBodySet.size(), 0 ); + numObjectsPerClothPrefixSum.resize( m_softBodySet.size(), 0 ); + + + class QuickSortCompare + { + public: + + bool operator() ( const CollisionShapeDescription& a, const CollisionShapeDescription& b ) const + { + return ( a.softBodyIdentifier < b.softBodyIdentifier ); + } + }; + + QuickSortCompare comparator; + m_collisionObjectDetails.quickSort( comparator ); + + // Generating indexing for perClothCollisionObjects + // First clear the previous values with the "no collision object for cloth" constant + for( int clothIndex = 0; clothIndex < m_perClothCollisionObjects.size(); ++clothIndex ) + { + m_perClothCollisionObjects[clothIndex].firstObject = -1; + m_perClothCollisionObjects[clothIndex].endObject = -1; + } + int currentCloth = 0; + int startIndex = 0; + for( int collisionObject = 0; collisionObject < m_collisionObjectDetails.size(); ++collisionObject ) + { + int nextCloth = m_collisionObjectDetails[collisionObject].softBodyIdentifier; + if( nextCloth != currentCloth ) + { + // Changed cloth in the array + // Set the end index and the range is what we need for currentCloth + m_perClothCollisionObjects[currentCloth].firstObject = startIndex; + m_perClothCollisionObjects[currentCloth].endObject = collisionObject; + currentCloth = nextCloth; + startIndex = collisionObject; + } + } + + // And update last cloth + m_perClothCollisionObjects[currentCloth].firstObject = startIndex; + m_perClothCollisionObjects[currentCloth].endObject = m_collisionObjectDetails.size(); + +} // btDX11SoftBodySolver::prepareCollisionConstraints + + +void btDX11SoftBodySolver::solveConstraints( float solverdt ) +{ + + //std::cerr << "'GPU' solve constraints\n"; + using Vectormath::Aos::Vector3; + using Vectormath::Aos::Point3; + using Vectormath::Aos::lengthSqr; + using Vectormath::Aos::dot; + + // Prepare links + int numLinks = m_linkData.getNumLinks(); + int numVertices = m_vertexData.getNumVertices(); + + float kst = 1.f; + float ti = 0.f; + + + m_dx11PerClothDampingFactor.moveToGPU(); + m_dx11PerClothVelocityCorrectionCoefficient.moveToGPU(); + + + // Ensure data is on accelerator + m_linkData.moveToAccelerator(); + m_vertexData.moveToAccelerator(); + + + prepareLinks(); + + for( int iteration = 0; iteration < m_numberOfVelocityIterations ; ++iteration ) + { + for( int i = 0; i < m_linkData.m_batchStartLengths.size(); ++i ) + { + int startLink = m_linkData.m_batchStartLengths[i].start; + int numLinks = m_linkData.m_batchStartLengths[i].length; + + solveLinksForVelocity( startLink, numLinks, kst ); + } + } + + + prepareCollisionConstraints(); + + // Compute new positions from velocity + // Also update the previous position so that our position computation is now based on the new position from the velocity solution + // rather than based directly on the original positions + if( m_numberOfVelocityIterations > 0 ) + { + updateVelocitiesFromPositionsWithVelocities( 1.f/solverdt ); + } else { + updateVelocitiesFromPositionsWithoutVelocities( 1.f/solverdt ); + } + + + // Solve drift + for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + { + for( int i = 0; i < m_linkData.m_batchStartLengths.size(); ++i ) + { + int startLink = m_linkData.m_batchStartLengths[i].start; + int numLinks = m_linkData.m_batchStartLengths[i].length; + + solveLinksForPosition( startLink, numLinks, kst, ti ); + } + + } // for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + + // At this point assume that the force array is blank - we will overwrite it + solveCollisionsAndUpdateVelocities( 1.f/solverdt ); +} // btDX11SoftBodySolver::solveConstraints + + + + +////////////////////////////////////// +// Kernel dispatches +void btDX11SoftBodySolver::prepareLinks() +{ + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + PrepareLinksCB constBuffer; + + constBuffer.numLinks = m_linkData.getNumLinks(); + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( prepareLinksKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(PrepareLinksCB) ); + m_dx11Context->Unmap( prepareLinksKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &prepareLinksKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_linkData.m_dx11Links.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_linkData.m_dx11LinksMassLSC.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_vertexData.m_dx11VertexPreviousPosition.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_linkData.m_dx11LinksLengthRatio.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_linkData.m_dx11LinksCLength.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( prepareLinksKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numLinks + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::prepareLinks + + +void btDX11SoftBodySolver::updatePositionsFromVelocities( float solverdt ) +{ + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + UpdatePositionsFromVelocitiesCB constBuffer; + + constBuffer.numNodes = m_vertexData.getNumVertices(); + constBuffer.solverSDT = solverdt; + + // Todo: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( updatePositionsFromVelocitiesKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(UpdatePositionsFromVelocitiesCB) ); + m_dx11Context->Unmap( updatePositionsFromVelocitiesKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &updatePositionsFromVelocitiesKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11VertexVelocity.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexPreviousPosition.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexPosition.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( updatePositionsFromVelocitiesKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks, 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::updatePositionsFromVelocities + +void btDX11SoftBodySolver::solveLinksForPosition( int startLink, int numLinks, float kst, float ti ) +{ + // Copy kernel parameters to GPU + SolvePositionsFromLinksKernelCB constBuffer; + + // Set the first link of the batch + // and the batch size + constBuffer.startLink = startLink; + constBuffer.numLinks = numLinks; + + constBuffer.kst = kst; + constBuffer.ti = ti; + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( solvePositionsFromLinksKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(SolvePositionsFromLinksKernelCB) ); + m_dx11Context->Unmap( solvePositionsFromLinksKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &solvePositionsFromLinksKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_linkData.m_dx11Links.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_linkData.m_dx11LinksMassLSC.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_linkData.m_dx11LinksRestLengthSquared.getSRV()) ); + m_dx11Context->CSSetShaderResources( 3, 1, &(m_vertexData.m_dx11VertexInverseMass.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexPosition.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( solvePositionsFromLinksKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numLinks + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } + +} // btDX11SoftBodySolver::solveLinksForPosition + +void btDX11SoftBodySolver::solveLinksForVelocity( int startLink, int numLinks, float kst ) +{ + // Copy kernel parameters to GPU + VSolveLinksCB constBuffer; + + // Set the first link of the batch + // and the batch size + + constBuffer.startLink = startLink; + constBuffer.numLinks = numLinks; + constBuffer.kst = kst; + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( vSolveLinksKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(VSolveLinksCB) ); + m_dx11Context->Unmap( vSolveLinksKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &vSolveLinksKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_linkData.m_dx11Links.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_linkData.m_dx11LinksLengthRatio.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_linkData.m_dx11LinksCLength.getSRV()) ); + m_dx11Context->CSSetShaderResources( 3, 1, &(m_vertexData.m_dx11VertexInverseMass.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexVelocity.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( vSolveLinksKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numLinks + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SoftBodySolver::solveLinksForVelocity + + +void btDX11SoftBodySolver::updateVelocitiesFromPositionsWithVelocities( float isolverdt ) +{ + // Copy kernel parameters to GPU + UpdateVelocitiesFromPositionsWithVelocitiesCB constBuffer; + + // Set the first link of the batch + // and the batch size + constBuffer.numNodes = m_vertexData.getNumVertices(); + constBuffer.isolverdt = isolverdt; + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( updateVelocitiesFromPositionsWithVelocitiesKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(UpdateVelocitiesFromPositionsWithVelocitiesCB) ); + m_dx11Context->Unmap( updateVelocitiesFromPositionsWithVelocitiesKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &updateVelocitiesFromPositionsWithVelocitiesKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11VertexPosition.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexPreviousPosition.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_vertexData.m_dx11ClothIdentifier.getSRV()) ); + m_dx11Context->CSSetShaderResources( 3, 1, &(m_dx11PerClothVelocityCorrectionCoefficient.getSRV()) ); + m_dx11Context->CSSetShaderResources( 4, 1, &(m_dx11PerClothDampingFactor.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexVelocity.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexForceAccumulator.getUAV()), NULL ); + + + // Execute the kernel + m_dx11Context->CSSetShader( updateVelocitiesFromPositionsWithVelocitiesKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 4, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } + +} // btDX11SoftBodySolver::updateVelocitiesFromPositionsWithVelocities + +void btDX11SoftBodySolver::updateVelocitiesFromPositionsWithoutVelocities( float isolverdt ) +{ + // Copy kernel parameters to GPU + UpdateVelocitiesFromPositionsWithoutVelocitiesCB constBuffer; + + // Set the first link of the batch + // and the batch size + constBuffer.numNodes = m_vertexData.getNumVertices(); + constBuffer.isolverdt = isolverdt; + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(UpdateVelocitiesFromPositionsWithoutVelocitiesCB) ); + m_dx11Context->Unmap( updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11VertexPosition.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexPreviousPosition.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_vertexData.m_dx11ClothIdentifier.getSRV()) ); + m_dx11Context->CSSetShaderResources( 3, 1, &(m_dx11PerClothDampingFactor.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexVelocity.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexForceAccumulator.getUAV()), NULL ); + + + // Execute the kernel + m_dx11Context->CSSetShader( updateVelocitiesFromPositionsWithoutVelocitiesKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } + +} // btDX11SoftBodySolver::updateVelocitiesFromPositionsWithoutVelocities + + +void btDX11SoftBodySolver::computeBounds( ) +{ + ComputeBoundsCB constBuffer; + m_vertexData.moveToAccelerator(); + + // Set the first link of the batch + // and the batch size + constBuffer.numNodes = m_vertexData.getNumVertices(); + constBuffer.numSoftBodies = m_softBodySet.size(); + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( computeBoundsKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(ComputeBoundsCB) ); + m_dx11Context->Unmap( computeBoundsKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &computeBoundsKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11ClothIdentifier.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexPosition.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_dx11PerClothMinBounds.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_dx11PerClothMaxBounds.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( computeBoundsKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} + +void btDX11SoftBodySolver::solveCollisionsAndUpdateVelocities( float isolverdt ) +{ + + // Copy kernel parameters to GPU + m_vertexData.moveToAccelerator(); + m_dx11PerClothFriction.moveToGPU(); + m_dx11PerClothDampingFactor.moveToGPU(); + m_dx11PerClothCollisionObjects.moveToGPU(); + m_dx11CollisionObjectDetails.moveToGPU(); + + SolveCollisionsAndUpdateVelocitiesCB constBuffer; + + // Set the first link of the batch + // and the batch size + constBuffer.numNodes = m_vertexData.getNumVertices(); + constBuffer.isolverdt = isolverdt; + + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( solveCollisionsAndUpdateVelocitiesKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(SolveCollisionsAndUpdateVelocitiesCB) ); + m_dx11Context->Unmap( solveCollisionsAndUpdateVelocitiesKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &solveCollisionsAndUpdateVelocitiesKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11ClothIdentifier.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexPreviousPosition.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_dx11PerClothFriction.getSRV()) ); + m_dx11Context->CSSetShaderResources( 3, 1, &(m_dx11PerClothDampingFactor.getSRV()) ); + m_dx11Context->CSSetShaderResources( 4, 1, &(m_dx11PerClothCollisionObjects.getSRV()) ); + m_dx11Context->CSSetShaderResources( 5, 1, &(m_dx11CollisionObjectDetails.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexForceAccumulator.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexVelocity.getUAV()), NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 2, 1, &(m_vertexData.m_dx11VertexPosition.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( solveCollisionsAndUpdateVelocitiesKernel.kernel, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 4, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 5, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL ); + m_dx11Context->CSSetUnorderedAccessViews( 2, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } + +} // btDX11SoftBodySolver::solveCollisionsAndUpdateVelocities + +// End kernel dispatches +///////////////////////////////////// + + + + + + + + + + + + + + +btDX11SoftBodySolver::btAcceleratedSoftBodyInterface *btDX11SoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody ) +{ + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex]; + if( softBodyInterface->getSoftBody() == softBody ) + return softBodyInterface; + } + return 0; +} + +const btDX11SoftBodySolver::btAcceleratedSoftBodyInterface * const btDX11SoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody ) const +{ + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex]; + if( softBodyInterface->getSoftBody() == softBody ) + return softBodyInterface; + } + return 0; +} + +int btDX11SoftBodySolver::findSoftBodyIndex( const btSoftBody* const softBody ) +{ + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex]; + if( softBodyInterface->getSoftBody() == softBody ) + return softBodyIndex; + } + return 1; +} + + +void btSoftBodySolverOutputDXtoCPU::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ) +{ + + + btSoftBodySolver *solver = softBody->getSoftBodySolver(); + btAssert( solver->getSolverType() == btSoftBodySolver::DX_SOLVER || solver->getSolverType() == btSoftBodySolver::DX_SIMD_SOLVER ); + btDX11SoftBodySolver *dxSolver = static_cast< btDX11SoftBodySolver * >( solver ); + + btDX11SoftBodySolver::btAcceleratedSoftBodyInterface * currentCloth = dxSolver->findSoftBodyInterface( softBody ); + btSoftBodyVertexDataDX11 &vertexData( dxSolver->m_vertexData ); + + + const int firstVertex = currentCloth->getFirstVertex(); + const int lastVertex = firstVertex + currentCloth->getNumVertices(); + + if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER ) + { + // If we're doing a CPU-buffer copy must copy the data back to the host first + vertexData.m_dx11VertexPosition.copyFromGPU(); + vertexData.m_dx11VertexNormal.copyFromGPU(); + + const int firstVertex = currentCloth->getFirstVertex(); + const int lastVertex = firstVertex + currentCloth->getNumVertices(); + const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast< btCPUVertexBufferDescriptor* >(vertexBuffer); + float *basePointer = cpuVertexBuffer->getBasePointer(); + + if( vertexBuffer->hasVertexPositions() ) + { + const int vertexOffset = cpuVertexBuffer->getVertexOffset(); + const int vertexStride = cpuVertexBuffer->getVertexStride(); + float *vertexPointer = basePointer + vertexOffset; + + for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex ) + { + Vectormath::Aos::Point3 position = vertexData.getPosition(vertexIndex); + *(vertexPointer + 0) = position.getX(); + *(vertexPointer + 1) = position.getY(); + *(vertexPointer + 2) = position.getZ(); + vertexPointer += vertexStride; + } + } + if( vertexBuffer->hasNormals() ) + { + const int normalOffset = cpuVertexBuffer->getNormalOffset(); + const int normalStride = cpuVertexBuffer->getNormalStride(); + float *normalPointer = basePointer + normalOffset; + + for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex ) + { + Vectormath::Aos::Vector3 normal = vertexData.getNormal(vertexIndex); + *(normalPointer + 0) = normal.getX(); + *(normalPointer + 1) = normal.getY(); + *(normalPointer + 2) = normal.getZ(); + normalPointer += normalStride; + } + } + } +} // btDX11SoftBodySolver::outputToVertexBuffers + + + +bool btSoftBodySolverOutputDXtoDX::checkInitialized() +{ + if( !m_shadersInitialized ) + if( buildShaders() ) + m_shadersInitialized = true; + + return m_shadersInitialized; +} + +void btSoftBodySolverOutputDXtoDX::releaseKernels() +{ + SAFE_RELEASE( outputToVertexArrayWithNormalsKernel.constBuffer ); + SAFE_RELEASE( outputToVertexArrayWithNormalsKernel.kernel ); + SAFE_RELEASE( outputToVertexArrayWithoutNormalsKernel.constBuffer ); + SAFE_RELEASE( outputToVertexArrayWithoutNormalsKernel.kernel ); + + m_shadersInitialized = false; +} + + +bool btSoftBodySolverOutputDXtoDX::buildShaders() +{ + // Ensure current kernels are released first + releaseKernels(); + + bool returnVal = true; + + if( m_shadersInitialized ) + return true; + + + outputToVertexArrayWithNormalsKernel = dxFunctions.compileComputeShaderFromString( OutputToVertexArrayHLSLString, "OutputToVertexArrayWithNormalsKernel", sizeof(OutputToVertexArrayCB) ); + if( !outputToVertexArrayWithNormalsKernel.constBuffer) + returnVal = false; + outputToVertexArrayWithoutNormalsKernel = dxFunctions.compileComputeShaderFromString( OutputToVertexArrayHLSLString, "OutputToVertexArrayWithoutNormalsKernel", sizeof(OutputToVertexArrayCB) ); + if( !outputToVertexArrayWithoutNormalsKernel.constBuffer ) + returnVal = false; + + + if( returnVal ) + m_shadersInitialized = true; + + return returnVal; +} + + +void btSoftBodySolverOutputDXtoDX::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ) +{ + + + btSoftBodySolver *solver = softBody->getSoftBodySolver(); + btAssert( solver->getSolverType() == btSoftBodySolver::DX_SOLVER || solver->getSolverType() == btSoftBodySolver::DX_SIMD_SOLVER ); + btDX11SoftBodySolver *dxSolver = static_cast< btDX11SoftBodySolver * >( solver ); + checkInitialized(); + btDX11SoftBodySolver::btAcceleratedSoftBodyInterface * currentCloth = dxSolver->findSoftBodyInterface( softBody ); + btSoftBodyVertexDataDX11 &vertexData( dxSolver->m_vertexData ); + + + const int firstVertex = currentCloth->getFirstVertex(); + const int lastVertex = firstVertex + currentCloth->getNumVertices(); + + if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER ) + { + btSoftBodySolverOutputDXtoDX::copySoftBodyToVertexBuffer( softBody, vertexBuffer ); + } else if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::DX11_BUFFER ) + { + // Do a DX11 copy shader DX to DX copy + + const btDX11VertexBufferDescriptor *dx11VertexBuffer = static_cast< btDX11VertexBufferDescriptor* >(vertexBuffer); + + // No need to batch link solver, it is entirely parallel + // Copy kernel parameters to GPU + OutputToVertexArrayCB constBuffer; + ID3D11ComputeShader* outputToVertexArrayShader = outputToVertexArrayWithoutNormalsKernel.kernel; + ID3D11Buffer* outputToVertexArrayConstBuffer = outputToVertexArrayWithoutNormalsKernel.constBuffer; + + constBuffer.startNode = firstVertex; + constBuffer.numNodes = currentCloth->getNumVertices(); + constBuffer.positionOffset = vertexBuffer->getVertexOffset(); + constBuffer.positionStride = vertexBuffer->getVertexStride(); + if( vertexBuffer->hasNormals() ) + { + constBuffer.normalOffset = vertexBuffer->getNormalOffset(); + constBuffer.normalStride = vertexBuffer->getNormalStride(); + outputToVertexArrayShader = outputToVertexArrayWithNormalsKernel.kernel; + outputToVertexArrayConstBuffer = outputToVertexArrayWithNormalsKernel.constBuffer; + } + + // TODO: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + dxFunctions.m_dx11Context->Map( outputToVertexArrayConstBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(OutputToVertexArrayCB) ); + dxFunctions.m_dx11Context->Unmap( outputToVertexArrayConstBuffer, 0 ); + dxFunctions.m_dx11Context->CSSetConstantBuffers( 0, 1, &outputToVertexArrayConstBuffer ); + + // Set resources and dispatch + dxFunctions.m_dx11Context->CSSetShaderResources( 0, 1, &(vertexData.m_dx11VertexPosition.getSRV()) ); + dxFunctions.m_dx11Context->CSSetShaderResources( 1, 1, &(vertexData.m_dx11VertexNormal.getSRV()) ); + + ID3D11UnorderedAccessView* dx11UAV = dx11VertexBuffer->getDX11UAV(); + dxFunctions.m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(dx11UAV), NULL ); + + // Execute the kernel + dxFunctions.m_dx11Context->CSSetShader( outputToVertexArrayShader, NULL, 0 ); + + int numBlocks = (constBuffer.numNodes + (128-1)) / 128; + dxFunctions.m_dx11Context->Dispatch(numBlocks, 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + dxFunctions.m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + dxFunctions.m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + dxFunctions.m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + dxFunctions.m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } + } +} // btDX11SoftBodySolver::outputToVertexBuffers + + + + +DXFunctions::KernelDesc DXFunctions::compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize, D3D10_SHADER_MACRO *compileMacros ) +{ + const char *cs5String = "cs_5_0"; + + HRESULT hr = S_OK; + ID3DBlob* pErrorBlob = NULL; + ID3DBlob* pBlob = NULL; + ID3D11ComputeShader* kernelPointer = 0; + + hr = m_dx11CompileFromMemory( + shaderString, + strlen(shaderString), + shaderName, + compileMacros, + NULL, + shaderName, + cs5String, + D3D10_SHADER_ENABLE_STRICTNESS, + NULL, + NULL, + &pBlob, + &pErrorBlob, + NULL + ); + + if( FAILED(hr) ) + { + if( pErrorBlob ) { + btAssert( "Compilation of compute shader failed\n" ); + char *debugString = (char*)pErrorBlob->GetBufferPointer(); + OutputDebugStringA( debugString ); + } + + SAFE_RELEASE( pErrorBlob ); + SAFE_RELEASE( pBlob ); + + DXFunctions::KernelDesc descriptor; + descriptor.kernel = 0; + descriptor.constBuffer = 0; + return descriptor; + } + + // Create the Compute Shader + hr = m_dx11Device->CreateComputeShader( pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, &kernelPointer ); + if( FAILED( hr ) ) + { + DXFunctions::KernelDesc descriptor; + descriptor.kernel = 0; + descriptor.constBuffer = 0; + return descriptor; + } + + ID3D11Buffer* constBuffer = 0; + if( constBufferSize > 0 ) + { + // Create the constant buffer + D3D11_BUFFER_DESC constant_buffer_desc; + ZeroMemory(&constant_buffer_desc, sizeof(constant_buffer_desc)); + constant_buffer_desc.ByteWidth = constBufferSize; + constant_buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + constant_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constant_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + m_dx11Device->CreateBuffer(&constant_buffer_desc, NULL, &constBuffer); + if( FAILED( hr ) ) + { + KernelDesc descriptor; + descriptor.kernel = 0; + descriptor.constBuffer = 0; + return descriptor; + } + } + + SAFE_RELEASE( pErrorBlob ); + SAFE_RELEASE( pBlob ); + + DXFunctions::KernelDesc descriptor; + descriptor.kernel = kernelPointer; + descriptor.constBuffer = constBuffer; + return descriptor; +} // compileComputeShader + + + +bool btDX11SoftBodySolver::buildShaders() +{ + // Ensure current kernels are released first + releaseKernels(); + + bool returnVal = true; + + if( m_shadersInitialized ) + return true; + + prepareLinksKernel = dxFunctions.compileComputeShaderFromString( PrepareLinksHLSLString, "PrepareLinksKernel", sizeof(PrepareLinksCB) ); + if( !prepareLinksKernel.constBuffer ) + returnVal = false; + updatePositionsFromVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdatePositionsFromVelocitiesHLSLString, "UpdatePositionsFromVelocitiesKernel", sizeof(UpdatePositionsFromVelocitiesCB) ); + if( !updatePositionsFromVelocitiesKernel.constBuffer ) + returnVal = false; + solvePositionsFromLinksKernel = dxFunctions.compileComputeShaderFromString( SolvePositionsHLSLString, "SolvePositionsFromLinksKernel", sizeof(SolvePositionsFromLinksKernelCB) ); + if( !updatePositionsFromVelocitiesKernel.constBuffer ) + returnVal = false; + vSolveLinksKernel = dxFunctions.compileComputeShaderFromString( VSolveLinksHLSLString, "VSolveLinksKernel", sizeof(VSolveLinksCB) ); + if( !vSolveLinksKernel.constBuffer ) + returnVal = false; + updateVelocitiesFromPositionsWithVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdateNodesHLSLString, "updateVelocitiesFromPositionsWithVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithVelocitiesCB) ); + if( !updateVelocitiesFromPositionsWithVelocitiesKernel.constBuffer ) + returnVal = false; + updateVelocitiesFromPositionsWithoutVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdatePositionsHLSLString, "updateVelocitiesFromPositionsWithoutVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithoutVelocitiesCB) ); + if( !updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer ) + returnVal = false; + integrateKernel = dxFunctions.compileComputeShaderFromString( IntegrateHLSLString, "IntegrateKernel", sizeof(IntegrateCB) ); + if( !integrateKernel.constBuffer ) + returnVal = false; + applyForcesKernel = dxFunctions.compileComputeShaderFromString( ApplyForcesHLSLString, "ApplyForcesKernel", sizeof(ApplyForcesCB) ); + if( !applyForcesKernel.constBuffer ) + returnVal = false; + solveCollisionsAndUpdateVelocitiesKernel = dxFunctions.compileComputeShaderFromString( SolveCollisionsAndUpdateVelocitiesHLSLString, "SolveCollisionsAndUpdateVelocitiesKernel", sizeof(SolveCollisionsAndUpdateVelocitiesCB) ); + if( !solveCollisionsAndUpdateVelocitiesKernel.constBuffer ) + returnVal = false; + + // TODO: Rename to UpdateSoftBodies + resetNormalsAndAreasKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "ResetNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) ); + if( !resetNormalsAndAreasKernel.constBuffer ) + returnVal = false; + normalizeNormalsAndAreasKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "NormalizeNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) ); + if( !normalizeNormalsAndAreasKernel.constBuffer ) + returnVal = false; + updateSoftBodiesKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "UpdateSoftBodiesKernel", sizeof(UpdateSoftBodiesCB) ); + if( !updateSoftBodiesKernel.constBuffer ) + returnVal = false; + + computeBoundsKernel = dxFunctions.compileComputeShaderFromString( ComputeBoundsHLSLString, "ComputeBoundsKernel", sizeof(ComputeBoundsCB) ); + if( !computeBoundsKernel.constBuffer ) + returnVal = false; + + + + if( returnVal ) + m_shadersInitialized = true; + + return returnVal; +} + + +static Vectormath::Aos::Transform3 toTransform3( const btTransform &transform ) +{ + Vectormath::Aos::Transform3 outTransform; + outTransform.setCol(0, toVector3(transform.getBasis().getColumn(0))); + outTransform.setCol(1, toVector3(transform.getBasis().getColumn(1))); + outTransform.setCol(2, toVector3(transform.getBasis().getColumn(2))); + outTransform.setCol(3, toVector3(transform.getOrigin())); + return outTransform; +} + + +void btDX11SoftBodySolver::btAcceleratedSoftBodyInterface::updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound ) +{ + float scalarMargin = this->getSoftBody()->getCollisionShape()->getMargin(); + btVector3 vectorMargin( scalarMargin, scalarMargin, scalarMargin ); + m_softBody->m_bounds[0] = lowerBound - vectorMargin; + m_softBody->m_bounds[1] = upperBound + vectorMargin; +} + +void btDX11SoftBodySolver::processCollision( btSoftBody*, btSoftBody* ) +{ + +} + +// Add the collision object to the set to deal with for a particular soft body +void btDX11SoftBodySolver::processCollision( btSoftBody *softBody, const btCollisionObjectWrapper* collisionObject ) +{ + int softBodyIndex = findSoftBodyIndex( softBody ); + + if( softBodyIndex >= 0 ) + { + const btCollisionShape *collisionShape = collisionObject->getCollisionShape(); + float friction = collisionObject->getCollisionObject()->getFriction(); + int shapeType = collisionShape->getShapeType(); + if( shapeType == CAPSULE_SHAPE_PROXYTYPE ) + { + // Add to the list of expected collision objects + CollisionShapeDescription newCollisionShapeDescription; + newCollisionShapeDescription.softBodyIdentifier = softBodyIndex; + newCollisionShapeDescription.collisionShapeType = shapeType; + // TODO: May need to transpose this matrix either here or in HLSL + newCollisionShapeDescription.shapeTransform = toTransform3(collisionObject->getWorldTransform()); + const btCapsuleShape *capsule = static_cast( collisionShape ); + newCollisionShapeDescription.radius = capsule->getRadius(); + newCollisionShapeDescription.halfHeight = capsule->getHalfHeight(); + newCollisionShapeDescription.margin = capsule->getMargin(); + newCollisionShapeDescription.friction = friction; + const btRigidBody* body = static_cast< const btRigidBody* >( collisionObject->getCollisionObject() ); + newCollisionShapeDescription.linearVelocity = toVector3(body->getLinearVelocity()); + newCollisionShapeDescription.angularVelocity = toVector3(body->getAngularVelocity()); + m_collisionObjectDetails.push_back( newCollisionShapeDescription ); + + } else { +#ifdef _DEBUG + printf("Unsupported collision shape type\n"); +#endif + } + } else { + btAssert("Unknown soft body"); + } +} // btDX11SoftBodySolver::processCollision + + + +void btDX11SoftBodySolver::predictMotion( float timeStep ) +{ + // Clear the collision shape array for the next frame + // Ensure that the DX11 ones are moved off the device so they will be updated correctly + m_dx11CollisionObjectDetails.changedOnCPU(); + m_dx11PerClothCollisionObjects.changedOnCPU(); + m_collisionObjectDetails.clear(); + + // Fill the force arrays with current acceleration data etc + m_perClothWindVelocity.resize( m_softBodySet.size() ); + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btSoftBody *softBody = m_softBodySet[softBodyIndex]->getSoftBody(); + + m_perClothWindVelocity[softBodyIndex] = toVector3(softBody->getWindVelocity()); + } + m_dx11PerClothWindVelocity.changedOnCPU(); + + // Apply forces that we know about to the cloths + applyForces( timeStep * getTimeScale() ); + + // Itegrate motion for all soft bodies dealt with by the solver + integrate( timeStep * getTimeScale() ); + + // Update bounds + // Will update the bounds for all softBodies being dealt with by the solver and + // set the values in the btSoftBody object + if (m_enableUpdateBounds) + updateBounds(); + + // End prediction work for solvers +} + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.h new file mode 100644 index 0000000..f2a6c73 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.h @@ -0,0 +1,691 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H +#define BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H + + +#include "vectormath/vmInclude.h" +#include "BulletSoftBody/btSoftBodySolvers.h" +#include "btSoftBodySolverVertexBuffer_DX11.h" +#include "btSoftBodySolverLinkData_DX11.h" +#include "btSoftBodySolverVertexData_DX11.h" +#include "btSoftBodySolverTriangleData_DX11.h" + + + +class DXFunctions +{ +public: + + typedef HRESULT (WINAPI * CompileFromMemoryFunc)(LPCSTR,SIZE_T,LPCSTR,const D3D10_SHADER_MACRO*,LPD3D10INCLUDE,LPCSTR,LPCSTR,UINT,UINT,ID3DX11ThreadPump*,ID3D10Blob**,ID3D10Blob**,HRESULT*); + + ID3D11Device * m_dx11Device; + ID3D11DeviceContext* m_dx11Context; + CompileFromMemoryFunc m_dx11CompileFromMemory; + + DXFunctions(ID3D11Device *dx11Device, ID3D11DeviceContext* dx11Context, CompileFromMemoryFunc dx11CompileFromMemory) : + m_dx11Device( dx11Device ), + m_dx11Context( dx11Context ), + m_dx11CompileFromMemory( dx11CompileFromMemory ) + { + + } + + class KernelDesc + { + protected: + + + public: + ID3D11ComputeShader* kernel; + ID3D11Buffer* constBuffer; + + KernelDesc() + { + kernel = 0; + constBuffer = 0; + } + + virtual ~KernelDesc() + { + // TODO: this should probably destroy its kernel but we need to be careful + // in case KernelDescs are copied + } + }; + + /** + * Compile a compute shader kernel from a string and return the appropriate KernelDesc object. + */ + KernelDesc compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize, D3D10_SHADER_MACRO *compileMacros = 0 ); + +}; + +class btDX11SoftBodySolver : public btSoftBodySolver +{ +protected: + /** + * Entry in the collision shape array. + * Specifies the shape type, the transform matrix and the necessary details of the collisionShape. + */ + struct CollisionShapeDescription + { + Vectormath::Aos::Transform3 shapeTransform; + Vectormath::Aos::Vector3 linearVelocity; + Vectormath::Aos::Vector3 angularVelocity; + + int softBodyIdentifier; + int collisionShapeType; + + // Both needed for capsule + float radius; + float halfHeight; + + float margin; + float friction; + + CollisionShapeDescription() + { + collisionShapeType = 0; + margin = 0; + friction = 0; + } + }; + + struct UIntVector3 + { + UIntVector3() + { + x = 0; + y = 0; + z = 0; + _padding = 0; + } + + UIntVector3( unsigned int x_, unsigned int y_, unsigned int z_ ) + { + x = x_; + y = y_; + z = z_; + _padding = 0; + } + + unsigned int x; + unsigned int y; + unsigned int z; + unsigned int _padding; + }; + + + +public: + /** + * SoftBody class to maintain information about a soft body instance + * within a solver. + * This data addresses the main solver arrays. + */ + class btAcceleratedSoftBodyInterface + { + protected: + /** Current number of vertices that are part of this cloth */ + int m_numVertices; + /** Maximum number of vertices allocated to be part of this cloth */ + int m_maxVertices; + /** Current number of triangles that are part of this cloth */ + int m_numTriangles; + /** Maximum number of triangles allocated to be part of this cloth */ + int m_maxTriangles; + /** Index of first vertex in the world allocated to this cloth */ + int m_firstVertex; + /** Index of first triangle in the world allocated to this cloth */ + int m_firstTriangle; + /** Index of first link in the world allocated to this cloth */ + int m_firstLink; + /** Maximum number of links allocated to this cloth */ + int m_maxLinks; + /** Current number of links allocated to this cloth */ + int m_numLinks; + + /** The actual soft body this data represents */ + btSoftBody *m_softBody; + + + public: + btAcceleratedSoftBodyInterface( btSoftBody *softBody ) : + m_softBody( softBody ) + { + m_numVertices = 0; + m_maxVertices = 0; + m_numTriangles = 0; + m_maxTriangles = 0; + m_firstVertex = 0; + m_firstTriangle = 0; + m_firstLink = 0; + m_maxLinks = 0; + m_numLinks = 0; + } + int getNumVertices() const + { + return m_numVertices; + } + + int getNumTriangles() const + { + return m_numTriangles; + } + + int getMaxVertices() const + { + return m_maxVertices; + } + + int getMaxTriangles() const + { + return m_maxTriangles; + } + + int getFirstVertex() const + { + return m_firstVertex; + } + + int getFirstTriangle() const + { + return m_firstTriangle; + } + + + /** + * Update the bounds in the btSoftBody object + */ + void updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound ); + + + // TODO: All of these set functions will have to do checks and + // update the world because restructuring of the arrays will be necessary + // Reasonable use of "friend"? + void setNumVertices( int numVertices ) + { + m_numVertices = numVertices; + } + + void setNumTriangles( int numTriangles ) + { + m_numTriangles = numTriangles; + } + + void setMaxVertices( int maxVertices ) + { + m_maxVertices = maxVertices; + } + + void setMaxTriangles( int maxTriangles ) + { + m_maxTriangles = maxTriangles; + } + + void setFirstVertex( int firstVertex ) + { + m_firstVertex = firstVertex; + } + + void setFirstTriangle( int firstTriangle ) + { + m_firstTriangle = firstTriangle; + } + + void setMaxLinks( int maxLinks ) + { + m_maxLinks = maxLinks; + } + + void setNumLinks( int numLinks ) + { + m_numLinks = numLinks; + } + + void setFirstLink( int firstLink ) + { + m_firstLink = firstLink; + } + + int getMaxLinks() + { + return m_maxLinks; + } + + int getNumLinks() + { + return m_numLinks; + } + + int getFirstLink() + { + return m_firstLink; + } + + btSoftBody* getSoftBody() + { + return m_softBody; + } + + }; + + + struct CollisionObjectIndices + { + CollisionObjectIndices( int f, int e ) + { + firstObject = f; + endObject = e; + } + + int firstObject; + int endObject; + }; + + + + + + struct PrepareLinksCB + { + int numLinks; + int padding0; + int padding1; + int padding2; + }; + + struct SolvePositionsFromLinksKernelCB + { + int startLink; + int numLinks; + float kst; + float ti; + }; + + struct IntegrateCB + { + int numNodes; + float solverdt; + int padding1; + int padding2; + }; + + struct UpdatePositionsFromVelocitiesCB + { + int numNodes; + float solverSDT; + int padding1; + int padding2; + }; + + struct UpdateVelocitiesFromPositionsWithoutVelocitiesCB + { + int numNodes; + float isolverdt; + int padding1; + int padding2; + }; + + struct UpdateVelocitiesFromPositionsWithVelocitiesCB + { + int numNodes; + float isolverdt; + int padding1; + int padding2; + }; + + struct UpdateSoftBodiesCB + { + int numNodes; + int startFace; + int numFaces; + float epsilon; + }; + + + struct ApplyForcesCB + { + unsigned int numNodes; + float solverdt; + float epsilon; + int padding3; + }; + + struct AddVelocityCB + { + int startNode; + int lastNode; + float velocityX; + float velocityY; + float velocityZ; + int padding1; + int padding2; + int padding3; + }; + + struct VSolveLinksCB + { + int startLink; + int numLinks; + float kst; + int padding; + }; + + struct ComputeBoundsCB + { + int numNodes; + int numSoftBodies; + int padding1; + int padding2; + }; + + struct SolveCollisionsAndUpdateVelocitiesCB + { + unsigned int numNodes; + float isolverdt; + int padding0; + int padding1; + }; + + + + +protected: + ID3D11Device * m_dx11Device; + ID3D11DeviceContext* m_dx11Context; + + DXFunctions dxFunctions; +public: + /** Link data for all cloths. Note that this will be sorted batch-wise for efficient computation and m_linkAddresses will maintain the addressing. */ + btSoftBodyLinkDataDX11 m_linkData; + btSoftBodyVertexDataDX11 m_vertexData; + btSoftBodyTriangleDataDX11 m_triangleData; + +protected: + + /** Variable to define whether we need to update solver constants on the next iteration */ + bool m_updateSolverConstants; + + bool m_shadersInitialized; + + /** + * Cloths owned by this solver. + * Only our cloths are in this array. + */ + btAlignedObjectArray< btAcceleratedSoftBodyInterface * > m_softBodySet; + + /** Acceleration value to be applied to all non-static vertices in the solver. + * Index n is cloth n, array sized by number of cloths in the world not the solver. + */ + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothAcceleration; + btDX11Buffer m_dx11PerClothAcceleration; + + /** Wind velocity to be applied normal to all non-static vertices in the solver. + * Index n is cloth n, array sized by number of cloths in the world not the solver. + */ + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothWindVelocity; + btDX11Buffer m_dx11PerClothWindVelocity; + + /** Velocity damping factor */ + btAlignedObjectArray< float > m_perClothDampingFactor; + btDX11Buffer m_dx11PerClothDampingFactor; + + /** Velocity correction coefficient */ + btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient; + btDX11Buffer m_dx11PerClothVelocityCorrectionCoefficient; + + /** Lift parameter for wind effect on cloth. */ + btAlignedObjectArray< float > m_perClothLiftFactor; + btDX11Buffer m_dx11PerClothLiftFactor; + + /** Drag parameter for wind effect on cloth. */ + btAlignedObjectArray< float > m_perClothDragFactor; + btDX11Buffer m_dx11PerClothDragFactor; + + /** Density of the medium in which each cloth sits */ + btAlignedObjectArray< float > m_perClothMediumDensity; + btDX11Buffer m_dx11PerClothMediumDensity; + + + /** + * Collision shape details: pair of index of first collision shape for the cloth and number of collision objects. + */ + btAlignedObjectArray< CollisionObjectIndices > m_perClothCollisionObjects; + btDX11Buffer m_dx11PerClothCollisionObjects; + + /** + * Collision shapes being passed across to the cloths in this solver. + */ + btAlignedObjectArray< CollisionShapeDescription > m_collisionObjectDetails; + btDX11Buffer< CollisionShapeDescription > m_dx11CollisionObjectDetails; + + /** + * Minimum bounds for each cloth. + * Updated by GPU and returned for use by broad phase. + * These are int vectors as a reminder that they store the int representation of a float, not a float. + * Bit 31 is inverted - is floats are stored with int-sortable values. + */ + btAlignedObjectArray< UIntVector3 > m_perClothMinBounds; + btDX11Buffer< UIntVector3 > m_dx11PerClothMinBounds; + + /** + * Maximum bounds for each cloth. + * Updated by GPU and returned for use by broad phase. + * These are int vectors as a reminder that they store the int representation of a float, not a float. + * Bit 31 is inverted - is floats are stored with int-sortable values. + */ + btAlignedObjectArray< UIntVector3 > m_perClothMaxBounds; + btDX11Buffer< UIntVector3 > m_dx11PerClothMaxBounds; + + + /** + * Friction coefficient for each cloth + */ + btAlignedObjectArray< float > m_perClothFriction; + btDX11Buffer< float > m_dx11PerClothFriction; + + DXFunctions::KernelDesc prepareLinksKernel; + DXFunctions::KernelDesc solvePositionsFromLinksKernel; + DXFunctions::KernelDesc vSolveLinksKernel; + DXFunctions::KernelDesc integrateKernel; + DXFunctions::KernelDesc addVelocityKernel; + DXFunctions::KernelDesc updatePositionsFromVelocitiesKernel; + DXFunctions::KernelDesc updateVelocitiesFromPositionsWithoutVelocitiesKernel; + DXFunctions::KernelDesc updateVelocitiesFromPositionsWithVelocitiesKernel; + DXFunctions::KernelDesc solveCollisionsAndUpdateVelocitiesKernel; + DXFunctions::KernelDesc resetNormalsAndAreasKernel; + DXFunctions::KernelDesc normalizeNormalsAndAreasKernel; + DXFunctions::KernelDesc computeBoundsKernel; + DXFunctions::KernelDesc updateSoftBodiesKernel; + + DXFunctions::KernelDesc applyForcesKernel; + + bool m_enableUpdateBounds; + + /** + * Integrate motion on the solver. + */ + virtual void integrate( float solverdt ); + float computeTriangleArea( + const Vectormath::Aos::Point3 &vertex0, + const Vectormath::Aos::Point3 &vertex1, + const Vectormath::Aos::Point3 &vertex2 ); + + + virtual bool buildShaders(); + + void resetNormalsAndAreas( int numVertices ); + + void normalizeNormalsAndAreas( int numVertices ); + + void executeUpdateSoftBodies( int firstTriangle, int numTriangles ); + + void prepareCollisionConstraints(); + + Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a ); + + void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce ); + + virtual void applyForces( float solverdt ); + + virtual void updateConstants( float timeStep ); + int findSoftBodyIndex( const btSoftBody* const softBody ); + + ////////////////////////////////////// + // Kernel dispatches + virtual void prepareLinks(); + + void updatePositionsFromVelocities( float solverdt ); + void solveLinksForPosition( int startLink, int numLinks, float kst, float ti ); + void solveLinksForVelocity( int startLink, int numLinks, float kst ); + + void updateVelocitiesFromPositionsWithVelocities( float isolverdt ); + void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt ); + void computeBounds( ); + void solveCollisionsAndUpdateVelocities( float isolverdt ); + + // End kernel dispatches + ///////////////////////////////////// + + void updateBounds(); + + + void releaseKernels(); + +public: + btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context, DXFunctions::CompileFromMemoryFunc dx11CompileFromMemory = &D3DX11CompileFromMemory); + + virtual ~btDX11SoftBodySolver(); + + + virtual SolverTypes getSolverType() const + { + return DX_SOLVER; + } + + void setEnableUpdateBounds(bool enableBounds) + { + m_enableUpdateBounds = enableBounds; + } + bool getEnableUpdateBounds() const + { + return m_enableUpdateBounds; + } + + + + virtual btSoftBodyLinkData &getLinkData(); + + virtual btSoftBodyVertexData &getVertexData(); + + virtual btSoftBodyTriangleData &getTriangleData(); + + + + + + btAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody ); + const btAcceleratedSoftBodyInterface * const findSoftBodyInterface( const btSoftBody* const softBody ) const; + + virtual bool checkInitialized(); + + virtual void updateSoftBodies( ); + + virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false); + + virtual void copyBackToSoftBodies(bool bMove = true); + + virtual void solveConstraints( float solverdt ); + + virtual void predictMotion( float solverdt ); + + + virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* ); + + virtual void processCollision( btSoftBody*, btSoftBody* ); + +}; + + + +/** + * Class to manage movement of data from a solver to a given target. + * This version is the DX to CPU version. + */ +class btSoftBodySolverOutputDXtoCPU : public btSoftBodySolverOutput +{ +protected: + +public: + btSoftBodySolverOutputDXtoCPU() + { + } + + /** Output current computed vertex data to the vertex buffers for all cloths in the solver. */ + virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ); +}; + +/** + * Class to manage movement of data from a solver to a given target. + * This version is the DX to DX version and subclasses DX to CPU so that it works for that too. + */ +class btSoftBodySolverOutputDXtoDX : public btSoftBodySolverOutputDXtoCPU +{ +protected: + struct OutputToVertexArrayCB + { + int startNode; + int numNodes; + int positionOffset; + int positionStride; + + int normalOffset; + int normalStride; + int padding1; + int padding2; + }; + + DXFunctions dxFunctions; + DXFunctions::KernelDesc outputToVertexArrayWithNormalsKernel; + DXFunctions::KernelDesc outputToVertexArrayWithoutNormalsKernel; + + + bool m_shadersInitialized; + + bool checkInitialized(); + bool buildShaders(); + void releaseKernels(); + +public: + btSoftBodySolverOutputDXtoDX(ID3D11Device *dx11Device, ID3D11DeviceContext* dx11Context, DXFunctions::CompileFromMemoryFunc dx11CompileFromMemory = &D3DX11CompileFromMemory) : + dxFunctions( dx11Device, dx11Context, dx11CompileFromMemory ) + { + m_shadersInitialized = false; + } + + ~btSoftBodySolverOutputDXtoDX() + { + releaseKernels(); + } + + /** Output current computed vertex data to the vertex buffers for all cloths in the solver. */ + virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ); +}; + +#endif // #ifndef BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H + + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.cpp b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.cpp new file mode 100644 index 0000000..b74c8d2 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.cpp @@ -0,0 +1,1051 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include + + +#define WAVEFRONT_SIZE 32 +#define WAVEFRONT_BLOCK_MULTIPLIER 2 +#define GROUP_SIZE (WAVEFRONT_SIZE*WAVEFRONT_BLOCK_MULTIPLIER) +#define LINKS_PER_SIMD_LANE 16 + +#define STRINGIFY( S ) STRINGIFY2( S ) +#define STRINGIFY2( S ) #S + +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "vectormath/vmInclude.h" + +#include "btSoftBodySolverLinkData_DX11SIMDAware.h" +#include "btSoftBodySolver_DX11SIMDAware.h" +#include "btSoftBodySolverVertexBuffer_DX11.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" + +#define MSTRINGIFY(A) #A +static char* UpdatePositionsFromVelocitiesHLSLString = +#include "HLSL/UpdatePositionsFromVelocities.hlsl" +static char* SolvePositionsSIMDBatchedHLSLString = +#include "HLSL/SolvePositionsSIMDBatched.hlsl" +static char* UpdateNodesHLSLString = +#include "HLSL/UpdateNodes.hlsl" +static char* UpdatePositionsHLSLString = +#include "HLSL/UpdatePositions.hlsl" +static char* UpdateConstantsHLSLString = +#include "HLSL/UpdateConstants.hlsl" +static char* IntegrateHLSLString = +#include "HLSL/Integrate.hlsl" +static char* ApplyForcesHLSLString = +#include "HLSL/ApplyForces.hlsl" +static char* UpdateNormalsHLSLString = +#include "HLSL/UpdateNormals.hlsl" +static char* OutputToVertexArrayHLSLString = +#include "HLSL/OutputToVertexArray.hlsl" +static char* VSolveLinksHLSLString = +#include "HLSL/VSolveLinks.hlsl" +static char* ComputeBoundsHLSLString = +#include "HLSL/ComputeBounds.hlsl" +static char* SolveCollisionsAndUpdateVelocitiesHLSLString = +#include "HLSL/solveCollisionsAndUpdateVelocitiesSIMDBatched.hlsl" + + + +btSoftBodyLinkDataDX11SIMDAware::btSoftBodyLinkDataDX11SIMDAware( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ) : + m_d3dDevice( d3dDevice ), + m_d3dDeviceContext( d3dDeviceContext ), + m_wavefrontSize( WAVEFRONT_SIZE ), + m_linksPerWorkItem( LINKS_PER_SIMD_LANE ), + m_maxBatchesWithinWave( 0 ), + m_maxLinksPerWavefront( m_wavefrontSize * m_linksPerWorkItem ), + m_numWavefronts( 0 ), + m_maxVertex( 0 ), + m_dx11NumBatchesAndVerticesWithinWaves( d3dDevice, d3dDeviceContext, &m_numBatchesAndVerticesWithinWaves, true ), + m_dx11WavefrontVerticesGlobalAddresses( d3dDevice, d3dDeviceContext, &m_wavefrontVerticesGlobalAddresses, true ), + m_dx11LinkVerticesLocalAddresses( d3dDevice, d3dDeviceContext, &m_linkVerticesLocalAddresses, true ), + m_dx11LinkStrength( d3dDevice, d3dDeviceContext, &m_linkStrength, true ), + m_dx11LinksMassLSC( d3dDevice, d3dDeviceContext, &m_linksMassLSC, true ), + m_dx11LinksRestLengthSquared( d3dDevice, d3dDeviceContext, &m_linksRestLengthSquared, true ), + m_dx11LinksRestLength( d3dDevice, d3dDeviceContext, &m_linksRestLength, true ), + m_dx11LinksMaterialLinearStiffnessCoefficient( d3dDevice, d3dDeviceContext, &m_linksMaterialLinearStiffnessCoefficient, true ) +{ + m_d3dDevice = d3dDevice; + m_d3dDeviceContext = d3dDeviceContext; +} + +btSoftBodyLinkDataDX11SIMDAware::~btSoftBodyLinkDataDX11SIMDAware() +{ +} + +static Vectormath::Aos::Vector3 toVector3( const btVector3 &vec ) +{ + Vectormath::Aos::Vector3 outVec( vec.getX(), vec.getY(), vec.getZ() ); + return outVec; +} + +void btSoftBodyLinkDataDX11SIMDAware::createLinks( int numLinks ) +{ + int previousSize = m_links.size(); + int newSize = previousSize + numLinks; + + btSoftBodyLinkData::createLinks( numLinks ); + + // Resize the link addresses array as well + m_linkAddresses.resize( newSize ); +} + +void btSoftBodyLinkDataDX11SIMDAware::setLinkAt( const btSoftBodyLinkData::LinkDescription &link, int linkIndex ) +{ + btSoftBodyLinkData::setLinkAt( link, linkIndex ); + + if( link.getVertex0() > m_maxVertex ) + m_maxVertex = link.getVertex0(); + if( link.getVertex1() > m_maxVertex ) + m_maxVertex = link.getVertex1(); + + // Set the link index correctly for initialisation + m_linkAddresses[linkIndex] = linkIndex; +} + +bool btSoftBodyLinkDataDX11SIMDAware::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyLinkDataDX11SIMDAware::moveToAccelerator() +{ + bool success = true; + + success = success && m_dx11NumBatchesAndVerticesWithinWaves.moveToGPU(); + success = success && m_dx11WavefrontVerticesGlobalAddresses.moveToGPU(); + success = success && m_dx11LinkVerticesLocalAddresses.moveToGPU(); + success = success && m_dx11LinkStrength.moveToGPU(); + success = success && m_dx11LinksMassLSC.moveToGPU(); + success = success && m_dx11LinksRestLengthSquared.moveToGPU(); + success = success && m_dx11LinksRestLength.moveToGPU(); + success = success && m_dx11LinksMaterialLinearStiffnessCoefficient.moveToGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +bool btSoftBodyLinkDataDX11SIMDAware::moveFromAccelerator() +{ + bool success = true; + success = success && m_dx11NumBatchesAndVerticesWithinWaves.moveFromGPU(); + success = success && m_dx11WavefrontVerticesGlobalAddresses.moveFromGPU(); + success = success && m_dx11LinkVerticesLocalAddresses.moveFromGPU(); + success = success && m_dx11LinkStrength.moveFromGPU(); + success = success && m_dx11LinksMassLSC.moveFromGPU(); + success = success && m_dx11LinksRestLengthSquared.moveFromGPU(); + success = success && m_dx11LinksRestLength.moveFromGPU(); + success = success && m_dx11LinksMaterialLinearStiffnessCoefficient.moveFromGPU(); + + if( success ) + m_onGPU = false; + + return success; +} + + + + + + + + + + + + + + + +btDX11SIMDAwareSoftBodySolver::btDX11SIMDAwareSoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context, DXFunctions::CompileFromMemoryFunc dx11CompileFromMemory) : + btDX11SoftBodySolver( dx11Device, dx11Context, dx11CompileFromMemory ), + m_linkData(m_dx11Device, m_dx11Context) +{ + // Initial we will clearly need to update solver constants + // For now this is global for the cloths linked with this solver - we should probably make this body specific + // for performance in future once we understand more clearly when constants need to be updated + m_updateSolverConstants = true; + + m_shadersInitialized = false; +} + +btDX11SIMDAwareSoftBodySolver::~btDX11SIMDAwareSoftBodySolver() +{ + releaseKernels(); +} + + +btSoftBodyLinkData &btDX11SIMDAwareSoftBodySolver::getLinkData() +{ + // TODO: Consider setting link data to "changed" here + return m_linkData; +} + + + +void btDX11SIMDAwareSoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate) +{ + if(forceUpdate || m_softBodySet.size() != softBodies.size() ) + { + // Have a change in the soft body set so update, reloading all the data + getVertexData().clear(); + getTriangleData().clear(); + getLinkData().clear(); + m_softBodySet.resize(0); + + + for( int softBodyIndex = 0; softBodyIndex < softBodies.size(); ++softBodyIndex ) + { + btSoftBody *softBody = softBodies[ softBodyIndex ]; + using Vectormath::Aos::Matrix3; + using Vectormath::Aos::Point3; + + // Create SoftBody that will store the information within the solver + btAcceleratedSoftBodyInterface *newSoftBody = new btAcceleratedSoftBodyInterface( softBody ); + m_softBodySet.push_back( newSoftBody ); + + m_perClothAcceleration.push_back( toVector3(softBody->getWorldInfo()->m_gravity) ); + m_perClothDampingFactor.push_back(softBody->m_cfg.kDP); + m_perClothVelocityCorrectionCoefficient.push_back( softBody->m_cfg.kVCF ); + m_perClothLiftFactor.push_back( softBody->m_cfg.kLF ); + m_perClothDragFactor.push_back( softBody->m_cfg.kDG ); + m_perClothMediumDensity.push_back(softBody->getWorldInfo()->air_density); + // Simple init values. Actually we'll put 0 and -1 into them at the appropriate time + m_perClothMinBounds.push_back( UIntVector3( 0, 0, 0 ) ); + m_perClothMaxBounds.push_back( UIntVector3( UINT_MAX, UINT_MAX, UINT_MAX ) ); + m_perClothFriction.push_back( softBody->getFriction() ); + m_perClothCollisionObjects.push_back( CollisionObjectIndices(-1, -1) ); + + // Add space for new vertices and triangles in the default solver for now + // TODO: Include space here for tearing too later + int firstVertex = getVertexData().getNumVertices(); + int numVertices = softBody->m_nodes.size(); + // Round maxVertices to a multiple of the workgroup size so we know we're safe to run over in a given group + // maxVertices can be increased to allow tearing, but should be used sparingly because these extra verts will always be processed + int maxVertices = GROUP_SIZE*((numVertices+GROUP_SIZE)/GROUP_SIZE); + // Allocate space for new vertices in all the vertex arrays + getVertexData().createVertices( numVertices, softBodyIndex, maxVertices ); + + int firstTriangle = getTriangleData().getNumTriangles(); + int numTriangles = softBody->m_faces.size(); + int maxTriangles = numTriangles; + getTriangleData().createTriangles( maxTriangles ); + + // Copy vertices from softbody into the solver + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + Point3 multPoint(softBody->m_nodes[vertex].m_x.getX(), softBody->m_nodes[vertex].m_x.getY(), softBody->m_nodes[vertex].m_x.getZ()); + btSoftBodyVertexData::VertexDescription desc; + + // TODO: Position in the softbody might be pre-transformed + // or we may need to adapt for the pose. + //desc.setPosition( cloth.getMeshTransform()*multPoint ); + desc.setPosition( multPoint ); + + float vertexInverseMass = softBody->m_nodes[vertex].m_im; + desc.setInverseMass(vertexInverseMass); + getVertexData().setVertexAt( desc, firstVertex + vertex ); + } + + // Copy triangles similarly + // We're assuming here that vertex indices are based on the firstVertex rather than the entire scene + for( int triangle = 0; triangle < numTriangles; ++triangle ) + { + // Note that large array storage is relative to the array not to the cloth + // So we need to add firstVertex to each value + int vertexIndex0 = (softBody->m_faces[triangle].m_n[0] - &(softBody->m_nodes[0])); + int vertexIndex1 = (softBody->m_faces[triangle].m_n[1] - &(softBody->m_nodes[0])); + int vertexIndex2 = (softBody->m_faces[triangle].m_n[2] - &(softBody->m_nodes[0])); + btSoftBodyTriangleData::TriangleDescription newTriangle(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, vertexIndex2 + firstVertex); + getTriangleData().setTriangleAt( newTriangle, firstTriangle + triangle ); + + // Increase vertex triangle counts for this triangle + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex0)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex1)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex2)++; + } + + int firstLink = getLinkData().getNumLinks(); + int numLinks = softBody->m_links.size(); + int maxLinks = numLinks; + + // Allocate space for the links + getLinkData().createLinks( numLinks ); + + // Add the links + for( int link = 0; link < numLinks; ++link ) + { + int vertexIndex0 = softBody->m_links[link].m_n[0] - &(softBody->m_nodes[0]); + int vertexIndex1 = softBody->m_links[link].m_n[1] - &(softBody->m_nodes[0]); + + btSoftBodyLinkData::LinkDescription newLink(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, softBody->m_links[link].m_material->m_kLST); + newLink.setLinkStrength(1.f); + getLinkData().setLinkAt(newLink, firstLink + link); + } + + newSoftBody->setFirstVertex( firstVertex ); + newSoftBody->setFirstTriangle( firstTriangle ); + newSoftBody->setNumVertices( numVertices ); + newSoftBody->setMaxVertices( maxVertices ); + newSoftBody->setNumTriangles( numTriangles ); + newSoftBody->setMaxTriangles( maxTriangles ); + newSoftBody->setFirstLink( firstLink ); + newSoftBody->setNumLinks( numLinks ); + } + + + + updateConstants(0.f); + + + m_linkData.generateBatches(); + m_triangleData.generateBatches(); + + + // Build the shaders to match the batching parameters + buildShaders(); + } + +} + + + +void btDX11SIMDAwareSoftBodySolver::solveConstraints( float solverdt ) +{ + + //std::cerr << "'GPU' solve constraints\n"; + using Vectormath::Aos::Vector3; + using Vectormath::Aos::Point3; + using Vectormath::Aos::lengthSqr; + using Vectormath::Aos::dot; + + // Prepare links + int numLinks = m_linkData.getNumLinks(); + int numVertices = m_vertexData.getNumVertices(); + + float kst = 1.f; + float ti = 0.f; + + + m_dx11PerClothDampingFactor.moveToGPU(); + m_dx11PerClothVelocityCorrectionCoefficient.moveToGPU(); + + + + // Ensure data is on accelerator + m_linkData.moveToAccelerator(); + m_vertexData.moveToAccelerator(); + + + + prepareCollisionConstraints(); + + + // Solve drift + for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + { + + for( int i = 0; i < m_linkData.m_wavefrontBatchStartLengths.size(); ++i ) + { + int startWave = m_linkData.m_wavefrontBatchStartLengths[i].start; + int numWaves = m_linkData.m_wavefrontBatchStartLengths[i].length; + + solveLinksForPosition( startWave, numWaves, kst, ti ); + } + + } // for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + + + + + // At this point assume that the force array is blank - we will overwrite it + solveCollisionsAndUpdateVelocities( 1.f/solverdt ); + +} // btDX11SIMDAwareSoftBodySolver::solveConstraints + + +void btDX11SIMDAwareSoftBodySolver::updateConstants( float timeStep ) +{ + using namespace Vectormath::Aos; + + if( m_updateSolverConstants ) + { + m_updateSolverConstants = false; + + // Will have to redo this if we change the structure (tear, maybe) or various other possible changes + + // Initialise link constants + const int numLinks = m_linkData.getNumLinks(); + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair &vertices( m_linkData.getVertexPair(linkIndex) ); + m_linkData.getRestLength(linkIndex) = length((m_vertexData.getPosition( vertices.vertex0 ) - m_vertexData.getPosition( vertices.vertex1 ))); + float invMass0 = m_vertexData.getInverseMass(vertices.vertex0); + float invMass1 = m_vertexData.getInverseMass(vertices.vertex1); + float linearStiffness = m_linkData.getLinearStiffnessCoefficient(linkIndex); + float massLSC = (invMass0 + invMass1)/linearStiffness; + m_linkData.getMassLSC(linkIndex) = massLSC; + float restLength = m_linkData.getRestLength(linkIndex); + float restLengthSquared = restLength*restLength; + m_linkData.getRestLengthSquared(linkIndex) = restLengthSquared; + } + } +} // btDX11SIMDAwareSoftBodySolver::updateConstants + +////////////////////////////////////// +// Kernel dispatches + + +void btDX11SIMDAwareSoftBodySolver::solveLinksForPosition( int startWave, int numWaves, float kst, float ti ) +{ + + + m_vertexData.moveToAccelerator(); + m_linkData.moveToAccelerator(); + + // Copy kernel parameters to GPU + SolvePositionsFromLinksKernelCB constBuffer; + + // Set the first wave of the batch and the number of waves + constBuffer.startWave = startWave; + constBuffer.numWaves = numWaves; + + constBuffer.kst = kst; + constBuffer.ti = ti; + + D3D11_MAPPED_SUBRESOURCE MappedResource = {0}; + m_dx11Context->Map( solvePositionsFromLinksKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ); + memcpy( MappedResource.pData, &constBuffer, sizeof(SolvePositionsFromLinksKernelCB) ); + m_dx11Context->Unmap( solvePositionsFromLinksKernel.constBuffer, 0 ); + m_dx11Context->CSSetConstantBuffers( 0, 1, &solvePositionsFromLinksKernel.constBuffer ); + + // Set resources and dispatch + m_dx11Context->CSSetShaderResources( 0, 1, &(m_linkData.m_dx11NumBatchesAndVerticesWithinWaves.getSRV()) ); + m_dx11Context->CSSetShaderResources( 1, 1, &(m_linkData.m_dx11WavefrontVerticesGlobalAddresses.getSRV()) ); + m_dx11Context->CSSetShaderResources( 2, 1, &(m_vertexData.m_dx11VertexInverseMass.getSRV()) ); + m_dx11Context->CSSetShaderResources( 3, 1, &(m_linkData.m_dx11LinkVerticesLocalAddresses.getSRV()) ); + m_dx11Context->CSSetShaderResources( 4, 1, &(m_linkData.m_dx11LinksMassLSC.getSRV()) ); + m_dx11Context->CSSetShaderResources( 5, 1, &(m_linkData.m_dx11LinksRestLengthSquared.getSRV()) ); + + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexPosition.getUAV()), NULL ); + + // Execute the kernel + m_dx11Context->CSSetShader( solvePositionsFromLinksKernel.kernel, NULL, 0 ); + + int numBlocks = ((constBuffer.numWaves + WAVEFRONT_BLOCK_MULTIPLIER - 1) / WAVEFRONT_BLOCK_MULTIPLIER ); + m_dx11Context->Dispatch(numBlocks , 1, 1 ); + + { + // Tidy up + ID3D11ShaderResourceView* pViewNULL = NULL; + m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 4, 1, &pViewNULL ); + m_dx11Context->CSSetShaderResources( 5, 1, &pViewNULL ); + + ID3D11UnorderedAccessView* pUAViewNULL = NULL; + m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL ); + + ID3D11Buffer *pBufferNull = NULL; + m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull ); + } +} // btDX11SIMDAwareSoftBodySolver::solveLinksForPosition + + + +// End kernel dispatches +///////////////////////////////////// + + + + + + + + + +bool btDX11SIMDAwareSoftBodySolver::buildShaders() +{ + // Ensure current kernels are released first + releaseKernels(); + + bool returnVal = true; + + + if( m_shadersInitialized ) + return true; + + + updatePositionsFromVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdatePositionsFromVelocitiesHLSLString, "UpdatePositionsFromVelocitiesKernel", sizeof(UpdatePositionsFromVelocitiesCB) ); + if( !updatePositionsFromVelocitiesKernel.constBuffer ) + returnVal = false; + + char maxVerticesPerWavefront[20]; + char maxBatchesPerWavefront[20]; + char waveFrontSize[20]; + char waveFrontBlockMultiplier[20]; + char blockSize[20]; + + sprintf(maxVerticesPerWavefront, "%d", m_linkData.getMaxVerticesPerWavefront()); + sprintf(maxBatchesPerWavefront, "%d", m_linkData.getMaxBatchesPerWavefront()); + sprintf(waveFrontSize, "%d", m_linkData.getWavefrontSize()); + sprintf(waveFrontBlockMultiplier, "%d", WAVEFRONT_BLOCK_MULTIPLIER); + sprintf(blockSize, "%d", WAVEFRONT_BLOCK_MULTIPLIER*m_linkData.getWavefrontSize()); + + D3D10_SHADER_MACRO solvePositionsMacros[6] = { "MAX_NUM_VERTICES_PER_WAVE", maxVerticesPerWavefront, "MAX_BATCHES_PER_WAVE", maxBatchesPerWavefront, "WAVEFRONT_SIZE", waveFrontSize, "WAVEFRONT_BLOCK_MULTIPLIER", waveFrontBlockMultiplier, "BLOCK_SIZE", blockSize, 0, 0 }; + + solvePositionsFromLinksKernel = dxFunctions.compileComputeShaderFromString( SolvePositionsSIMDBatchedHLSLString, "SolvePositionsFromLinksKernel", sizeof(SolvePositionsFromLinksKernelCB), solvePositionsMacros ); + if( !solvePositionsFromLinksKernel.constBuffer ) + returnVal = false; + + updateVelocitiesFromPositionsWithVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdateNodesHLSLString, "updateVelocitiesFromPositionsWithVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithVelocitiesCB) ); + if( !updateVelocitiesFromPositionsWithVelocitiesKernel.constBuffer ) + returnVal = false; + updateVelocitiesFromPositionsWithoutVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdatePositionsHLSLString, "updateVelocitiesFromPositionsWithoutVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithoutVelocitiesCB)); + if( !updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer ) + returnVal = false; + integrateKernel = dxFunctions.compileComputeShaderFromString( IntegrateHLSLString, "IntegrateKernel", sizeof(IntegrateCB) ); + if( !integrateKernel.constBuffer ) + returnVal = false; + applyForcesKernel = dxFunctions.compileComputeShaderFromString( ApplyForcesHLSLString, "ApplyForcesKernel", sizeof(ApplyForcesCB) ); + if( !applyForcesKernel.constBuffer ) + returnVal = false; + solveCollisionsAndUpdateVelocitiesKernel = dxFunctions.compileComputeShaderFromString( SolveCollisionsAndUpdateVelocitiesHLSLString, "SolveCollisionsAndUpdateVelocitiesKernel", sizeof(SolveCollisionsAndUpdateVelocitiesCB) ); + if( !solveCollisionsAndUpdateVelocitiesKernel.constBuffer ) + returnVal = false; + resetNormalsAndAreasKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "ResetNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) ); + if( !resetNormalsAndAreasKernel.constBuffer ) + returnVal = false; + normalizeNormalsAndAreasKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "NormalizeNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) ); + if( !normalizeNormalsAndAreasKernel.constBuffer ) + returnVal = false; + updateSoftBodiesKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "UpdateSoftBodiesKernel", sizeof(UpdateSoftBodiesCB) ); + if( !updateSoftBodiesKernel.constBuffer ) + returnVal = false; + + computeBoundsKernel = dxFunctions.compileComputeShaderFromString( ComputeBoundsHLSLString, "ComputeBoundsKernel", sizeof(ComputeBoundsCB) ); + if( !computeBoundsKernel.constBuffer ) + returnVal = false; + + if( returnVal ) + m_shadersInitialized = true; + + return returnVal; +} // btDX11SIMDAwareSoftBodySolver::buildShaders + +static Vectormath::Aos::Transform3 toTransform3( const btTransform &transform ) +{ + Vectormath::Aos::Transform3 outTransform; + outTransform.setCol(0, toVector3(transform.getBasis().getColumn(0))); + outTransform.setCol(1, toVector3(transform.getBasis().getColumn(1))); + outTransform.setCol(2, toVector3(transform.getBasis().getColumn(2))); + outTransform.setCol(3, toVector3(transform.getOrigin())); + return outTransform; +} + + + + + + + + + + + + +static void generateBatchesOfWavefronts( btAlignedObjectArray < btAlignedObjectArray > &linksForWavefronts, btSoftBodyLinkData &linkData, int numVertices, btAlignedObjectArray < btAlignedObjectArray > &wavefrontBatches ) +{ + // A per-batch map of truth values stating whether a given vertex is in that batch + // This allows us to significantly optimize the batching + btAlignedObjectArray > mapOfVerticesInBatches; + + for( int waveIndex = 0; waveIndex < linksForWavefronts.size(); ++waveIndex ) + { + btAlignedObjectArray &wavefront( linksForWavefronts[waveIndex] ); + + int batch = 0; + bool placed = false; + while( batch < wavefrontBatches.size() && !placed ) + { + // Test the current batch, see if this wave shares any vertex with the waves in the batch + bool foundSharedVertex = false; + for( int link = 0; link < wavefront.size(); ++link ) + { + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( wavefront[link] ); + if( (mapOfVerticesInBatches[batch])[vertices.vertex0] || (mapOfVerticesInBatches[batch])[vertices.vertex1] ) + { + foundSharedVertex = true; + } + } + + if( !foundSharedVertex ) + { + wavefrontBatches[batch].push_back( waveIndex ); + // Insert vertices into this batch too + for( int link = 0; link < wavefront.size(); ++link ) + { + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( wavefront[link] ); + (mapOfVerticesInBatches[batch])[vertices.vertex0] = true; + (mapOfVerticesInBatches[batch])[vertices.vertex1] = true; + } + placed = true; + } + batch++; + } + if( batch == wavefrontBatches.size() && !placed ) + { + wavefrontBatches.resize( batch + 1 ); + wavefrontBatches[batch].push_back( waveIndex ); + + // And resize map as well + mapOfVerticesInBatches.resize( batch + 1 ); + + // Resize maps with total number of vertices + mapOfVerticesInBatches[batch].resize( numVertices+1, false ); + + // Insert vertices into this batch too + for( int link = 0; link < wavefront.size(); ++link ) + { + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( wavefront[link] ); + (mapOfVerticesInBatches[batch])[vertices.vertex0] = true; + (mapOfVerticesInBatches[batch])[vertices.vertex1] = true; + } + } + } + mapOfVerticesInBatches.clear(); +} + +// Function to remove an object from a vector maintaining correct ordering of the vector +template< typename T > static void removeFromVector( btAlignedObjectArray< T > &vectorToUpdate, int indexToRemove ) +{ + int currentSize = vectorToUpdate.size(); + for( int i = indexToRemove; i < (currentSize-1); ++i ) + { + vectorToUpdate[i] = vectorToUpdate[i+1]; + } + if( currentSize > 0 ) + vectorToUpdate.resize( currentSize - 1 ); +} + +/** + * Insert element into vectorToUpdate at index index. + */ +template< typename T > static void insertAtIndex( btAlignedObjectArray< T > &vectorToUpdate, int index, T element ) +{ + vectorToUpdate.resize( vectorToUpdate.size() + 1 ); + for( int i = (vectorToUpdate.size() - 1); i > index; --i ) + { + vectorToUpdate[i] = vectorToUpdate[i-1]; + } + vectorToUpdate[index] = element; +} + +/** + * Insert into btAlignedObjectArray assuming the array is ordered and maintaining both ordering and uniqueness. + * ie it treats vectorToUpdate as an ordered set. + */ +template< typename T > static void insertUniqueAndOrderedIntoVector( btAlignedObjectArray &vectorToUpdate, T element ) +{ + int index = 0; + while( index < vectorToUpdate.size() && vectorToUpdate[index] < element ) + { + index++; + } + if( index == vectorToUpdate.size() || vectorToUpdate[index] != element ) + insertAtIndex( vectorToUpdate, index, element ); +} + +static void generateLinksPerVertex( int numVertices, btSoftBodyLinkData &linkData, btAlignedObjectArray< int > &listOfLinksPerVertex, btAlignedObjectArray &numLinksPerVertex, int &maxLinks ) +{ + for( int linkIndex = 0; linkIndex < linkData.getNumLinks(); ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair nodes( linkData.getVertexPair(linkIndex) ); + numLinksPerVertex[nodes.vertex0]++; + numLinksPerVertex[nodes.vertex1]++; + } + int maxLinksPerVertex = 0; + for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex ) + { + maxLinksPerVertex = btMax(numLinksPerVertex[vertexIndex], maxLinksPerVertex); + } + maxLinks = maxLinksPerVertex; + + btAlignedObjectArray< int > linksFoundPerVertex; + linksFoundPerVertex.resize( numVertices, 0 ); + + listOfLinksPerVertex.resize( maxLinksPerVertex * numVertices ); + + for( int linkIndex = 0; linkIndex < linkData.getNumLinks(); ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair nodes( linkData.getVertexPair(linkIndex) ); + { + // Do vertex 0 + int vertexIndex = nodes.vertex0; + int linkForVertex = linksFoundPerVertex[nodes.vertex0]; + int linkAddress = vertexIndex * maxLinksPerVertex + linkForVertex; + + listOfLinksPerVertex[linkAddress] = linkIndex; + + linksFoundPerVertex[nodes.vertex0] = linkForVertex + 1; + } + { + // Do vertex 1 + int vertexIndex = nodes.vertex1; + int linkForVertex = linksFoundPerVertex[nodes.vertex1]; + int linkAddress = vertexIndex * maxLinksPerVertex + linkForVertex; + + listOfLinksPerVertex[linkAddress] = linkIndex; + + linksFoundPerVertex[nodes.vertex1] = linkForVertex + 1; + } + } +} + +static void computeBatchingIntoWavefronts( + btSoftBodyLinkData &linkData, + int wavefrontSize, + int linksPerWorkItem, + int maxLinksPerWavefront, + btAlignedObjectArray < btAlignedObjectArray > &linksForWavefronts, + btAlignedObjectArray< btAlignedObjectArray < btAlignedObjectArray > > &batchesWithinWaves, /* wave, batch, links in batch */ + btAlignedObjectArray< btAlignedObjectArray< int > > &verticesForWavefronts /* wavefront, vertex */ + ) +{ + + + // Attempt generation of larger batches of links. + btAlignedObjectArray< bool > processedLink; + processedLink.resize( linkData.getNumLinks() ); + btAlignedObjectArray< int > listOfLinksPerVertex; + int maxLinksPerVertex = 0; + + // Count num vertices + int numVertices = 0; + for( int linkIndex = 0; linkIndex < linkData.getNumLinks(); ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair nodes( linkData.getVertexPair(linkIndex) ); + numVertices = btMax( numVertices, nodes.vertex0 + 1 ); + numVertices = btMax( numVertices, nodes.vertex1 + 1 ); + } + + // Need list of links per vertex + // Compute valence of each vertex + btAlignedObjectArray numLinksPerVertex; + numLinksPerVertex.resize(0); + numLinksPerVertex.resize( numVertices, 0 ); + + generateLinksPerVertex( numVertices, linkData, listOfLinksPerVertex, numLinksPerVertex, maxLinksPerVertex ); + + + // At this point we know what links we have for each vertex so we can start batching + + // We want a vertex to start with, let's go with 0 + int currentVertex = 0; + int linksProcessed = 0; + + btAlignedObjectArray verticesToProcess; + + while( linksProcessed < linkData.getNumLinks() ) + { + // Next wavefront + int nextWavefront = linksForWavefronts.size(); + linksForWavefronts.resize( nextWavefront + 1 ); + btAlignedObjectArray &linksForWavefront(linksForWavefronts[nextWavefront]); + verticesForWavefronts.resize( nextWavefront + 1 ); + btAlignedObjectArray &vertexSet( verticesForWavefronts[nextWavefront] ); + + linksForWavefront.resize(0); + + // Loop to find enough links to fill the wavefront + // Stopping if we either run out of links, or fill it + while( linksProcessed < linkData.getNumLinks() && linksForWavefront.size() < maxLinksPerWavefront ) + { + // Go through the links for the current vertex + for( int link = 0; link < numLinksPerVertex[currentVertex] && linksForWavefront.size() < maxLinksPerWavefront; ++link ) + { + int linkAddress = currentVertex * maxLinksPerVertex + link; + int linkIndex = listOfLinksPerVertex[linkAddress]; + + // If we have not already processed this link, add it to the wavefront + // Claim it as another processed link + // Add the vertex at the far end to the list of vertices to process. + if( !processedLink[linkIndex] ) + { + linksForWavefront.push_back( linkIndex ); + linksProcessed++; + processedLink[linkIndex] = true; + int v0 = linkData.getVertexPair(linkIndex).vertex0; + int v1 = linkData.getVertexPair(linkIndex).vertex1; + if( v0 == currentVertex ) + verticesToProcess.push_back( v1 ); + else + verticesToProcess.push_back( v0 ); + } + } + if( verticesToProcess.size() > 0 ) + { + // Get the element on the front of the queue and remove it + currentVertex = verticesToProcess[0]; + removeFromVector( verticesToProcess, 0 ); + } else { + // If we've not yet processed all the links, find the first unprocessed one + // and select one of its vertices as the current vertex + if( linksProcessed < linkData.getNumLinks() ) + { + int searchLink = 0; + while( processedLink[searchLink] ) + searchLink++; + currentVertex = linkData.getVertexPair(searchLink).vertex0; + } + } + } + + // We have either finished or filled a wavefront + for( int link = 0; link < linksForWavefront.size(); ++link ) + { + int v0 = linkData.getVertexPair( linksForWavefront[link] ).vertex0; + int v1 = linkData.getVertexPair( linksForWavefront[link] ).vertex1; + insertUniqueAndOrderedIntoVector( vertexSet, v0 ); + insertUniqueAndOrderedIntoVector( vertexSet, v1 ); + } + // Iterate over links mapped to the wave and batch those + // We can run a batch on each cycle trivially + + batchesWithinWaves.resize( batchesWithinWaves.size() + 1 ); + btAlignedObjectArray < btAlignedObjectArray > &batchesWithinWave( batchesWithinWaves[batchesWithinWaves.size()-1] ); + + + for( int link = 0; link < linksForWavefront.size(); ++link ) + { + int linkIndex = linksForWavefront[link]; + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( linkIndex ); + + int batch = 0; + bool placed = false; + while( batch < batchesWithinWave.size() && !placed ) + { + bool foundSharedVertex = false; + if( batchesWithinWave[batch].size() >= wavefrontSize ) + { + // If we have already filled this batch, move on to another + foundSharedVertex = true; + } else { + for( int link2 = 0; link2 < batchesWithinWave[batch].size(); ++link2 ) + { + btSoftBodyLinkData::LinkNodePair vertices2 = linkData.getVertexPair( (batchesWithinWave[batch])[link2] ); + + if( vertices.vertex0 == vertices2.vertex0 || + vertices.vertex1 == vertices2.vertex0 || + vertices.vertex0 == vertices2.vertex1 || + vertices.vertex1 == vertices2.vertex1 ) + { + foundSharedVertex = true; + break; + } + } + } + if( !foundSharedVertex ) + { + batchesWithinWave[batch].push_back( linkIndex ); + placed = true; + } else { + ++batch; + } + } + if( batch == batchesWithinWave.size() && !placed ) + { + batchesWithinWave.resize( batch + 1 ); + batchesWithinWave[batch].push_back( linkIndex ); + } + } + + } + +} + +void btSoftBodyLinkDataDX11SIMDAware::generateBatches() +{ + btAlignedObjectArray < btAlignedObjectArray > linksForWavefronts; + btAlignedObjectArray < btAlignedObjectArray > wavefrontBatches; + btAlignedObjectArray< btAlignedObjectArray < btAlignedObjectArray > > batchesWithinWaves; + btAlignedObjectArray< btAlignedObjectArray< int > > verticesForWavefronts; // wavefronts, vertices in wavefront as an ordered set + + // Group the links into wavefronts + computeBatchingIntoWavefronts( *this, m_wavefrontSize, m_linksPerWorkItem, m_maxLinksPerWavefront, linksForWavefronts, batchesWithinWaves, verticesForWavefronts ); + + + // Batch the wavefronts + generateBatchesOfWavefronts( linksForWavefronts, *this, m_maxVertex, wavefrontBatches ); + + m_numWavefronts = linksForWavefronts.size(); + + // At this point we have a description of which links we need to process in each wavefront + + // First correctly fill the batch ranges vector + int numBatches = wavefrontBatches.size(); + m_wavefrontBatchStartLengths.resize(0); + int prefixSum = 0; + for( int batchIndex = 0; batchIndex < numBatches; ++batchIndex ) + { + int wavesInBatch = wavefrontBatches[batchIndex].size(); + int nextPrefixSum = prefixSum + wavesInBatch; + m_wavefrontBatchStartLengths.push_back( BatchPair( prefixSum, nextPrefixSum - prefixSum ) ); + + prefixSum += wavesInBatch; + } + + // Also find max number of batches within a wave + m_maxBatchesWithinWave = 0; + m_maxVerticesWithinWave = 0; + m_numBatchesAndVerticesWithinWaves.resize( m_numWavefronts ); + for( int waveIndex = 0; waveIndex < m_numWavefronts; ++waveIndex ) + { + // See if the number of batches in this wave is greater than the current maxium + int batchesInCurrentWave = batchesWithinWaves[waveIndex].size(); + int verticesInCurrentWave = verticesForWavefronts[waveIndex].size(); + m_maxBatchesWithinWave = btMax( batchesInCurrentWave, m_maxBatchesWithinWave ); + m_maxVerticesWithinWave = btMax( verticesInCurrentWave, m_maxVerticesWithinWave ); + } + + // Add padding values both for alignment and as dudd addresses within LDS to compute junk rather than branch around + m_maxVerticesWithinWave = 16*((m_maxVerticesWithinWave/16)+2); + + // Now we know the maximum number of vertices per-wave we can resize the global vertices array + m_wavefrontVerticesGlobalAddresses.resize( m_maxVerticesWithinWave * m_numWavefronts ); + + // Grab backup copies of all the link data arrays for the sorting process + btAlignedObjectArray m_links_Backup(m_links); + btAlignedObjectArray m_linkStrength_Backup(m_linkStrength); + btAlignedObjectArray m_linksMassLSC_Backup(m_linksMassLSC); + btAlignedObjectArray m_linksRestLengthSquared_Backup(m_linksRestLengthSquared); + //btAlignedObjectArray m_linksCLength_Backup(m_linksCLength); + //btAlignedObjectArray m_linksLengthRatio_Backup(m_linksLengthRatio); + btAlignedObjectArray m_linksRestLength_Backup(m_linksRestLength); + btAlignedObjectArray m_linksMaterialLinearStiffnessCoefficient_Backup(m_linksMaterialLinearStiffnessCoefficient); + + // Resize to a wavefront sized batch per batch per wave so we get perfectly coherent memory accesses. + m_links.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linkVerticesLocalAddresses.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linkStrength.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksMassLSC.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksRestLengthSquared.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksRestLength.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksMaterialLinearStiffnessCoefficient.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + + // Then re-order links into wavefront blocks + + // Total number of wavefronts moved. This will decide the ordering of sorted wavefronts. + int wavefrontCount = 0; + + // Iterate over batches of wavefronts, then wavefronts in the batch + for( int batchIndex = 0; batchIndex < numBatches; ++batchIndex ) + { + btAlignedObjectArray &batch( wavefrontBatches[batchIndex] ); + int wavefrontsInBatch = batch.size(); + + + for( int wavefrontIndex = 0; wavefrontIndex < wavefrontsInBatch; ++wavefrontIndex ) + { + + int originalWavefrontIndex = batch[wavefrontIndex]; + btAlignedObjectArray< int > &wavefrontVertices( verticesForWavefronts[originalWavefrontIndex] ); + int verticesUsedByWavefront = wavefrontVertices.size(); + + // Copy the set of vertices into the correctly structured array for use on the device + // Fill the non-vertices with -1s + // so we can mask out those reads + for( int vertex = 0; vertex < verticesUsedByWavefront; ++vertex ) + { + m_wavefrontVerticesGlobalAddresses[m_maxVerticesWithinWave * wavefrontCount + vertex] = wavefrontVertices[vertex]; + } + for( int vertex = verticesUsedByWavefront; vertex < m_maxVerticesWithinWave; ++vertex ) + { + m_wavefrontVerticesGlobalAddresses[m_maxVerticesWithinWave * wavefrontCount + vertex] = -1; + } + + // Obtain the set of batches within the current wavefront + btAlignedObjectArray < btAlignedObjectArray > &batchesWithinWavefront( batchesWithinWaves[originalWavefrontIndex] ); + // Set the size of the batches for use in the solver, correctly ordered + NumBatchesVerticesPair batchesAndVertices; + batchesAndVertices.numBatches = batchesWithinWavefront.size(); + batchesAndVertices.numVertices = verticesUsedByWavefront; + m_numBatchesAndVerticesWithinWaves[wavefrontCount] = batchesAndVertices; + + + // Now iterate over batches within the wavefront to structure the links correctly + for( int wavefrontBatch = 0; wavefrontBatch < batchesWithinWavefront.size(); ++wavefrontBatch ) + { + btAlignedObjectArray &linksInBatch( batchesWithinWavefront[wavefrontBatch] ); + int wavefrontBatchSize = linksInBatch.size(); + + int batchAddressInTarget = m_maxBatchesWithinWave * m_wavefrontSize * wavefrontCount + m_wavefrontSize * wavefrontBatch; + + for( int linkIndex = 0; linkIndex < wavefrontBatchSize; ++linkIndex ) + { + int originalLinkAddress = linksInBatch[linkIndex]; + // Reorder simple arrays trivially + m_links[batchAddressInTarget + linkIndex] = m_links_Backup[originalLinkAddress]; + m_linkStrength[batchAddressInTarget + linkIndex] = m_linkStrength_Backup[originalLinkAddress]; + m_linksMassLSC[batchAddressInTarget + linkIndex] = m_linksMassLSC_Backup[originalLinkAddress]; + m_linksRestLengthSquared[batchAddressInTarget + linkIndex] = m_linksRestLengthSquared_Backup[originalLinkAddress]; + m_linksRestLength[batchAddressInTarget + linkIndex] = m_linksRestLength_Backup[originalLinkAddress]; + m_linksMaterialLinearStiffnessCoefficient[batchAddressInTarget + linkIndex] = m_linksMaterialLinearStiffnessCoefficient_Backup[originalLinkAddress]; + + // The local address is more complicated. We need to work out where a given vertex will end up + // by searching the set of vertices for this link and using the index as the local address + btSoftBodyLinkData::LinkNodePair localPair; + btSoftBodyLinkData::LinkNodePair globalPair = m_links[batchAddressInTarget + linkIndex]; + localPair.vertex0 = wavefrontVertices.findLinearSearch( globalPair.vertex0 ); + localPair.vertex1 = wavefrontVertices.findLinearSearch( globalPair.vertex1 ); + m_linkVerticesLocalAddresses[batchAddressInTarget + linkIndex] = localPair; + } + for( int linkIndex = wavefrontBatchSize; linkIndex < m_wavefrontSize; ++linkIndex ) + { + // Put 0s into these arrays for padding for cleanliness + m_links[batchAddressInTarget + linkIndex] = btSoftBodyLinkData::LinkNodePair(0, 0); + m_linkStrength[batchAddressInTarget + linkIndex] = 0.f; + m_linksMassLSC[batchAddressInTarget + linkIndex] = 0.f; + m_linksRestLengthSquared[batchAddressInTarget + linkIndex] = 0.f; + m_linksRestLength[batchAddressInTarget + linkIndex] = 0.f; + m_linksMaterialLinearStiffnessCoefficient[batchAddressInTarget + linkIndex] = 0.f; + + + // For local addresses of junk data choose a set of addresses just above the range of valid ones + // and cycling tyhrough % 16 so that we don't have bank conficts between all dud addresses + // The valid addresses will do scatter and gather in the valid range, the junk ones should happily work + // off the end of that range so we need no control + btSoftBodyLinkData::LinkNodePair localPair; + localPair.vertex0 = verticesUsedByWavefront + (linkIndex % 16); + localPair.vertex1 = verticesUsedByWavefront + (linkIndex % 16); + m_linkVerticesLocalAddresses[batchAddressInTarget + linkIndex] = localPair; + } + + } + + + wavefrontCount++; + } + + + } + +} // void btSoftBodyLinkDataDX11SIMDAware::generateBatches() diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.h new file mode 100644 index 0000000..554e40c --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.h @@ -0,0 +1,81 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "vectormath/vmInclude.h" +#include "btSoftBodySolver_DX11.h" +#include "btSoftBodySolverVertexBuffer_DX11.h" +#include "btSoftBodySolverLinkData_DX11SIMDAware.h" +#include "btSoftBodySolverVertexData_DX11.h" +#include "btSoftBodySolverTriangleData_DX11.h" + + +#ifndef BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H +#define BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H + +class btDX11SIMDAwareSoftBodySolver : public btDX11SoftBodySolver +{ +protected: + struct SolvePositionsFromLinksKernelCB + { + int startWave; + int numWaves; + float kst; + float ti; + }; + + + /** Link data for all cloths. Note that this will be sorted batch-wise for efficient computation and m_linkAddresses will maintain the addressing. */ + btSoftBodyLinkDataDX11SIMDAware m_linkData; + + /** Variable to define whether we need to update solver constants on the next iteration */ + bool m_updateSolverConstants; + + + virtual bool buildShaders(); + + void updateConstants( float timeStep ); + + + ////////////////////////////////////// + // Kernel dispatches + + + void solveLinksForPosition( int startLink, int numLinks, float kst, float ti ); + + // End kernel dispatches + ///////////////////////////////////// + + + +public: + btDX11SIMDAwareSoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context, DXFunctions::CompileFromMemoryFunc dx11CompileFromMemory = &D3DX11CompileFromMemory); + + virtual ~btDX11SIMDAwareSoftBodySolver(); + + virtual btSoftBodyLinkData &getLinkData(); + + virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false); + + virtual void solveConstraints( float solverdt ); + + virtual SolverTypes getSolverType() const + { + return DX_SIMD_SOLVER; + } + +}; + +#endif // #ifndef BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/premake4.lua b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/premake4.lua new file mode 100644 index 0000000..8f95f62 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/DX11/premake4.lua @@ -0,0 +1,23 @@ + +hasDX11 = findDirectX11() + +if (hasDX11) then + + project "BulletSoftBodyDX11Solvers" + + initDirectX11() + + kind "StaticLib" + + targetdir "../../../../lib" + + includedirs { + ".", + "../../.." + } + files { + "**.cpp", + "**.h" + } + +end diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/CMakeLists.txt new file mode 100644 index 0000000..d2a56ba --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/CMakeLists.txt @@ -0,0 +1,62 @@ + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${AMD_OPENCL_INCLUDES} +) + +ADD_DEFINITIONS(-DUSE_AMD_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_AMD) + + + +SET(BulletSoftBodyOpenCLSolvers_SRCS + ../btSoftBodySolver_OpenCL.cpp + ../btSoftBodySolver_OpenCLSIMDAware.cpp + ../btSoftBodySolverOutputCLtoGL.cpp +) + +SET(BulletSoftBodyOpenCLSolvers_HDRS + ../btSoftBodySolver_OpenCL.h + ../btSoftBodySolver_OpenCLSIMDAware.h + ../../Shared/btSoftBodySolverData.h + ../btSoftBodySolverVertexData_OpenCL.h + ../btSoftBodySolverTriangleData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCLSIMDAware.h + ../btSoftBodySolverBuffer_OpenCL.h + ../btSoftBodySolverVertexBuffer_OpenGL.h + ../btSoftBodySolverOutputCLtoGL.h +) + + + + +ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_AMD + ${BulletSoftBodyOpenCLSolvers_SRCS} + ${BulletSoftBodyOpenCLSolvers_HDRS} +) + +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_AMD BulletSoftBody) +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_AMD DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_AMD DESTINATION lib${LIB_SUFFIX}) +#headers are already installed by BulletMultiThreaded library + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/premake4.lua b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/premake4.lua new file mode 100644 index 0000000..05a9290 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/AMD/premake4.lua @@ -0,0 +1,27 @@ + +hasCL = findOpenCL_AMD() + +if (hasCL) then + + project "BulletSoftBodySolvers_OpenCL_AMD" + + defines { "USE_AMD_OPENCL","CL_PLATFORM_AMD"} + + initOpenCL_AMD() + + kind "StaticLib" + + targetdir "../../../../../lib" + + includedirs { + ".", + "../../../..", + "../../../../../Glut" + } + files { + "../btSoftBodySolver_OpenCL.cpp", + "../btSoftBodySolver_OpenCLSIMDAware.cpp", + "../btSoftBodySolverOutputCLtoGL.cpp" + } + +end diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Apple/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Apple/CMakeLists.txt new file mode 100644 index 0000000..3db66c9 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Apple/CMakeLists.txt @@ -0,0 +1,77 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + + + + +SET(BulletSoftBodyOpenCLSolvers_SRCS + ../btSoftBodySolver_OpenCL.cpp + ../btSoftBodySolver_OpenCLSIMDAware.cpp +) + +SET(BulletSoftBodyOpenCLSolvers_HDRS + ../btSoftBodySolver_OpenCL.h + ../../Shared/btSoftBodySolverData.h + ../btSoftBodySolverVertexData_OpenCL.h + ../btSoftBodySolverTriangleData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCL.h + ../btSoftBodySolverBuffer_OpenCL.h +) + +# OpenCL and HLSL Shaders. +# Build rules generated to stringify these into headers +# which are needed by some of the sources +SET(BulletSoftBodyOpenCLSolvers_Shaders +# OutputToVertexArray + UpdateNormals + Integrate + UpdatePositions + UpdateNodes + SolvePositions + UpdatePositionsFromVelocities + ApplyForces + PrepareLinks + VSolveLinks +) + +foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders}) + LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl") +endforeach(f) + + + +ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_Apple + ${BulletSoftBodyOpenCLSolvers_SRCS} + ${BulletSoftBodyOpenCLSolvers_HDRS} + ${BulletSoftBodyOpenCLSolvers_OpenCLC} +) + +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + IF (APPLE AND (BUILD_SHARED_LIBS OR FRAMEWORK) ) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES LINK_FLAGS "-framework OpenCL") + ENDIF (APPLE AND (BUILD_SHARED_LIBS OR FRAMEWORK) ) + TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_Apple BulletSoftBody) +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Apple DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Apple DESTINATION lib${LIB_SUFFIX}) +#headers are already installed by BulletMultiThreaded library + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/CMakeLists.txt new file mode 100644 index 0000000..64b029f --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/CMakeLists.txt @@ -0,0 +1,17 @@ + SUBDIRS( MiniCL ) + +IF(BUILD_INTEL_OPENCL_DEMOS) + SUBDIRS(Intel) +ENDIF() + +IF(BUILD_AMD_OPENCL_DEMOS) + SUBDIRS(AMD) +ENDIF() + +IF(BUILD_NVIDIA_OPENCL_DEMOS) + SUBDIRS(NVidia) +ENDIF() + +IF(APPLE AND OPENCL_LIBRARY) + SUBDIRS(Apple) +ENDIF() diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/CMakeLists.txt new file mode 100644 index 0000000..27d57f7 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/CMakeLists.txt @@ -0,0 +1,82 @@ + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${INTEL_OPENCL_INCLUDES} +) + +ADD_DEFINITIONS(-DUSE_INTEL_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_INTEL) + + + +SET(BulletSoftBodyOpenCLSolvers_SRCS + ../btSoftBodySolver_OpenCL.cpp + ../btSoftBodySolver_OpenCLSIMDAware.cpp + ../btSoftBodySolverOutputCLtoGL.cpp +) + +SET(BulletSoftBodyOpenCLSolvers_HDRS + ../btSoftBodySolver_OpenCL.h + ../btSoftBodySolver_OpenCLSIMDAware.h + ../../Shared/btSoftBodySolverData.h + ../btSoftBodySolverVertexData_OpenCL.h + ../btSoftBodySolverTriangleData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCLSIMDAware.h + ../btSoftBodySolverBuffer_OpenCL.h + ../btSoftBodySolverVertexBuffer_OpenGL.h + ../btSoftBodySolverOutputCLtoGL.h +) + +# OpenCL and HLSL Shaders. +# Build rules generated to stringify these into headers +# which are needed by some of the sources +SET(BulletSoftBodyOpenCLSolvers_Shaders +# OutputToVertexArray + UpdateNormals + Integrate + UpdatePositions + UpdateNodes + SolvePositions + UpdatePositionsFromVelocities + ApplyForces + PrepareLinks + VSolveLinks +) + +foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders}) + LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl") +endforeach(f) + + + +ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_Intel + ${BulletSoftBodyOpenCLSolvers_SRCS} + ${BulletSoftBodyOpenCLSolvers_HDRS} + ${BulletSoftBodyOpenCLSolvers_OpenCLC} +) + +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_Intel BulletSoftBody) +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Intel DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Intel DESTINATION lib${LIB_SUFFIX}) +#headers are already installed by BulletMultiThreaded library + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/premake4.lua b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/premake4.lua new file mode 100644 index 0000000..7d88776 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/Intel/premake4.lua @@ -0,0 +1,27 @@ + +hasCL = findOpenCL_Intel() + +if (hasCL) then + + project "BulletSoftBodySolvers_OpenCL_Intel" + + defines { "USE_INTEL_OPENCL","CL_PLATFORM_INTEL"} + + initOpenCL_Intel() + + kind "StaticLib" + + targetdir "../../../../../lib" + + includedirs { + ".", + "../../../..", + "../../../../../Glut" + } + files { + "../btSoftBodySolver_OpenCL.cpp", + "../btSoftBodySolver_OpenCLSIMDAware.cpp", + "../btSoftBodySolverOutputCLtoGL.cpp" + } + +end diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt new file mode 100644 index 0000000..72d0a73 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt @@ -0,0 +1,75 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src +) + +ADD_DEFINITIONS(-DUSE_MINICL) + + + + +SET(BulletSoftBodyOpenCLSolvers_SRCS + ../btSoftBodySolver_OpenCL.cpp +) + +SET(BulletSoftBodyOpenCLSolvers_HDRS + ../btSoftBodySolver_OpenCL.h + ../../Shared/btSoftBodySolverData.h + ../btSoftBodySolverVertexData_OpenCL.h + ../btSoftBodySolverTriangleData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCL.h + ../btSoftBodySolverBuffer_OpenCL.h +) + +# OpenCL and HLSL Shaders. +# Build rules generated to stringify these into headers +# which are needed by some of the sources +SET(BulletSoftBodyOpenCLSolvers_Shaders +# OutputToVertexArray + UpdateNormals + Integrate + UpdatePositions + UpdateNodes + SolvePositions + UpdatePositionsFromVelocities + ApplyForces + PrepareLinks + VSolveLinks +) + +foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders}) + LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl") +endforeach(f) + + + +ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_Mini + ${BulletSoftBodyOpenCLSolvers_SRCS} + ${BulletSoftBodyOpenCLSolvers_HDRS} + ${BulletSoftBodyOpenCLSolvers_OpenCLC} +) + +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_Mini MiniCL BulletMultiThreaded BulletSoftBody) +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Mini DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Mini DESTINATION lib${LIB_SUFFIX}) +#headers are already installed by BulletMultiThreaded library + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/MiniCLTaskWrap.cpp b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/MiniCLTaskWrap.cpp new file mode 100644 index 0000000..49ca12d --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/MiniCLTaskWrap.cpp @@ -0,0 +1,249 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include + +#define MSTRINGIFY(A) A +#include "../OpenCLC10/ApplyForces.cl" +#include "../OpenCLC10/Integrate.cl" +#include "../OpenCLC10/PrepareLinks.cl" +#include "../OpenCLC10/SolvePositions.cl" +#include "../OpenCLC10/UpdateNodes.cl" +#include "../OpenCLC10/UpdateNormals.cl" +#include "../OpenCLC10/UpdatePositions.cl" +#include "../OpenCLC10/UpdatePositionsFromVelocities.cl" +#include "../OpenCLC10/VSolveLinks.cl" +#include "../OpenCLC10/UpdateFixedVertexPositions.cl" +//#include "../OpenCLC10/SolveCollisionsAndUpdateVelocities.cl" + + +MINICL_REGISTER(PrepareLinksKernel) +MINICL_REGISTER(VSolveLinksKernel) +MINICL_REGISTER(UpdatePositionsFromVelocitiesKernel) +MINICL_REGISTER(SolvePositionsFromLinksKernel) +MINICL_REGISTER(updateVelocitiesFromPositionsWithVelocitiesKernel) +MINICL_REGISTER(updateVelocitiesFromPositionsWithoutVelocitiesKernel) +MINICL_REGISTER(IntegrateKernel) +MINICL_REGISTER(ApplyForcesKernel) +MINICL_REGISTER(ResetNormalsAndAreasKernel) +MINICL_REGISTER(NormalizeNormalsAndAreasKernel) +MINICL_REGISTER(UpdateSoftBodiesKernel) +MINICL_REGISTER(UpdateFixedVertexPositions) + +float mydot3a(float4 a, float4 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + + +typedef struct +{ + int firstObject; + int endObject; +} CollisionObjectIndices; + +typedef struct +{ + float4 shapeTransform[4]; // column major 4x4 matrix + float4 linearVelocity; + float4 angularVelocity; + + int softBodyIdentifier; + int collisionShapeType; + + + // Shape information + // Compressed from the union + float radius; + float halfHeight; + int upAxis; + + float margin; + float friction; + + int padding0; + +} CollisionShapeDescription; + +// From btBroadphaseProxy.h +__constant int CAPSULE_SHAPE_PROXYTYPE = 10; + +// Multiply column-major matrix against vector +float4 matrixVectorMul( float4 matrix[4], float4 vector ) +{ + float4 returnVector; + float4 row0 = float4(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x); + float4 row1 = float4(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y); + float4 row2 = float4(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z); + float4 row3 = float4(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w); + returnVector.x = dot(row0, vector); + returnVector.y = dot(row1, vector); + returnVector.z = dot(row2, vector); + returnVector.w = dot(row3, vector); + return returnVector; +} + +__kernel void +SolveCollisionsAndUpdateVelocitiesKernel( + const int numNodes, + const float isolverdt, + __global int *g_vertexClothIdentifier, + __global float4 *g_vertexPreviousPositions, + __global float * g_perClothFriction, + __global float * g_clothDampingFactor, + __global CollisionObjectIndices * g_perClothCollisionObjectIndices, + __global CollisionShapeDescription * g_collisionObjectDetails, + __global float4 * g_vertexForces, + __global float4 *g_vertexVelocities, + __global float4 *g_vertexPositions GUID_ARG) +{ + int nodeID = get_global_id(0); + float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f); + + if( get_global_id(0) < numNodes ) + { + int clothIdentifier = g_vertexClothIdentifier[nodeID]; + + // Abort if this is not a valid cloth + if( clothIdentifier < 0 ) + return; + + + float4 position (g_vertexPositions[nodeID].xyz, 1.f); + float4 previousPosition (g_vertexPreviousPositions[nodeID].xyz, 1.f); + + float clothFriction = g_perClothFriction[clothIdentifier]; + float dampingFactor = g_clothDampingFactor[clothIdentifier]; + float velocityCoefficient = (1.f - dampingFactor); + float4 difference = position - previousPosition; + float4 velocity = difference*velocityCoefficient*isolverdt; + + CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier]; + + int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject; + + if( numObjects > 0 ) + { + // We have some possible collisions to deal with + for( int collision = collisionObjectIndices.firstObject; collision < collisionObjectIndices.endObject; ++collision ) + { + CollisionShapeDescription shapeDescription = g_collisionObjectDetails[collision]; + float colliderFriction = shapeDescription.friction; + + if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE ) + { + // Colliding with a capsule + + float capsuleHalfHeight = shapeDescription.halfHeight; + float capsuleRadius = shapeDescription.radius; + float capsuleMargin = shapeDescription.margin; + int capsuleupAxis = shapeDescription.upAxis; + + // Four columns of worldTransform matrix + float4 worldTransform[4]; + worldTransform[0] = shapeDescription.shapeTransform[0]; + worldTransform[1] = shapeDescription.shapeTransform[1]; + worldTransform[2] = shapeDescription.shapeTransform[2]; + worldTransform[3] = shapeDescription.shapeTransform[3]; + + // Correctly define capsule centerline vector + float4 c1 (0.f, 0.f, 0.f, 1.f); + float4 c2 (0.f, 0.f, 0.f, 1.f); + c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 ); + c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 ); + c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 ); + c2.x = -c1.x; + c2.y = -c1.y; + c2.z = -c1.z; + + + float4 worldC1 = matrixVectorMul(worldTransform, c1); + float4 worldC2 = matrixVectorMul(worldTransform, c2); + float4 segment = (worldC2 - worldC1); + + // compute distance of tangent to vertex along line segment in capsule + float distanceAlongSegment = -( mydot3a( (worldC1 - position), segment ) / mydot3a(segment, segment) ); + + float4 closestPoint = (worldC1 + (segment * distanceAlongSegment)); + float distanceFromLine = length(position - closestPoint); + float distanceFromC1 = length(worldC1 - position); + float distanceFromC2 = length(worldC2 - position); + + // Final distance from collision, point to push from, direction to push in + // for impulse force + float dist; + float4 normalVector; + if( distanceAlongSegment < 0 ) + { + dist = distanceFromC1; + normalVector = float4(normalize(position - worldC1).xyz, 0.f); + } else if( distanceAlongSegment > 1.f ) { + dist = distanceFromC2; + normalVector = float4(normalize(position - worldC2).xyz, 0.f); + } else { + dist = distanceFromLine; + normalVector = float4(normalize(position - closestPoint).xyz, 0.f); + } + + float4 colliderLinearVelocity = shapeDescription.linearVelocity; + float4 colliderAngularVelocity = shapeDescription.angularVelocity; + float4 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position - float4(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w, 0.f)); + + float minDistance = capsuleRadius + capsuleMargin; + + // In case of no collision, this is the value of velocity + velocity = (position - previousPosition) * velocityCoefficient * isolverdt; + + + // Check for a collision + if( dist < minDistance ) + { + // Project back to surface along normal + position = position + float4(normalVector*(minDistance - dist)*0.9f); + velocity = (position - previousPosition) * velocityCoefficient * isolverdt; + float4 relativeVelocity = velocity - velocityOfSurfacePoint; + + float4 p1 = normalize(cross(normalVector, segment)); + float4 p2 = normalize(cross(p1, normalVector)); + // Full friction is sum of velocities in each direction of plane + float4 frictionVector = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2); + + // Real friction is peak friction corrected by friction coefficients + frictionVector = frictionVector * (colliderFriction*clothFriction); + + float approachSpeed = dot(relativeVelocity, normalVector); + + if( approachSpeed <= 0.0f ) + forceOnVertex -= frictionVector; + } + } + } + } + + g_vertexVelocities[nodeID] = float4(velocity.xyz, 0.f); + + // Update external force + g_vertexForces[nodeID] = float4(forceOnVertex.xyz, 0.f); + + g_vertexPositions[nodeID] = float4(position.xyz, 0.f); + } +} + + +MINICL_REGISTER(SolveCollisionsAndUpdateVelocitiesKernel); + + + + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/CMakeLists.txt b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/CMakeLists.txt new file mode 100644 index 0000000..10ed90f --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/CMakeLists.txt @@ -0,0 +1,81 @@ + +ADD_DEFINITIONS(-DUSE_NVIDIA_OPENCL) +ADD_DEFINITIONS(-DCL_PLATFORM_NVIDIA) + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${NVIDIA_OPENCL_INCLUDES} +) + + + +SET(BulletSoftBodyOpenCLSolvers_SRCS + ../btSoftBodySolver_OpenCL.cpp + ../btSoftBodySolver_OpenCLSIMDAware.cpp + ../btSoftBodySolverOutputCLtoGL.cpp +) + +SET(BulletSoftBodyOpenCLSolvers_HDRS + ../btSoftBodySolver_OpenCL.h + ../../Shared/btSoftBodySolverData.h + ../btSoftBodySolverVertexData_OpenCL.h + ../btSoftBodySolverTriangleData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCL.h + ../btSoftBodySolverLinkData_OpenCLSIMDAware.h + ../btSoftBodySolverBuffer_OpenCL.h + ../btSoftBodySolverVertexBuffer_OpenGL.h + ../btSoftBodySolverOutputCLtoGL.h +) + +# OpenCL and HLSL Shaders. +# Build rules generated to stringify these into headers +# which are needed by some of the sources +SET(BulletSoftBodyOpenCLSolvers_Shaders +# OutputToVertexArray + UpdateNormals + Integrate + UpdatePositions + UpdateNodes + SolvePositions + UpdatePositionsFromVelocities + ApplyForces + PrepareLinks + VSolveLinks +) + +foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders}) + LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl") +endforeach(f) + + + +ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_NVidia + ${BulletSoftBodyOpenCLSolvers_SRCS} + ${BulletSoftBodyOpenCLSolvers_HDRS} + ${BulletSoftBodyOpenCLSolvers_OpenCLC} +) + +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_NVidia BulletSoftBody BulletDynamics) +ENDIF (BUILD_SHARED_LIBS) + + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_NVidia DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_NVidia DESTINATION lib${LIB_SUFFIX}) +#headers are already installed by BulletMultiThreaded library + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/premake4.lua b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/premake4.lua new file mode 100644 index 0000000..6e64547 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/NVidia/premake4.lua @@ -0,0 +1,27 @@ + +hasCL = findOpenCL_NVIDIA() + +if (hasCL) then + + project "BulletSoftBodySolvers_OpenCL_NVIDIA" + + defines { "USE_NVIDIA_OPENCL","CL_PLATFORM_NVIDIA"} + + initOpenCL_NVIDIA() + + kind "StaticLib" + + targetdir "../../../../../lib" + + includedirs { + ".", + "../../../..", + "../../../../../Glut" + } + files { + "../btSoftBodySolver_OpenCL.cpp", + "../btSoftBodySolver_OpenCLSIMDAware.cpp", + "../btSoftBodySolverOutputCLtoGL.cpp" + } + +end diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ApplyForces.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ApplyForces.cl new file mode 100644 index 0000000..3d4d610 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ApplyForces.cl @@ -0,0 +1,102 @@ +MSTRINGIFY( + + +float adot3(float4 a, float4 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + +float alength3(float4 a) +{ + a.w = 0; + return length(a); +} + +float4 anormalize3(float4 a) +{ + a.w = 0; + return normalize(a); +} + +float4 projectOnAxis( float4 v, float4 a ) +{ + return (a*adot3(v, a)); +} + +__kernel void +ApplyForcesKernel( + const uint numNodes, + const float solverdt, + const float epsilon, + __global int * g_vertexClothIdentifier, + __global float4 * g_vertexNormal, + __global float * g_vertexArea, + __global float * g_vertexInverseMass, + __global float * g_clothLiftFactor, + __global float * g_clothDragFactor, + __global float4 * g_clothWindVelocity, + __global float4 * g_clothAcceleration, + __global float * g_clothMediumDensity, + __global float4 * g_vertexForceAccumulator, + __global float4 * g_vertexVelocity GUID_ARG) +{ + unsigned int nodeID = get_global_id(0); + if( nodeID < numNodes ) + { + int clothId = g_vertexClothIdentifier[nodeID]; + float nodeIM = g_vertexInverseMass[nodeID]; + + if( nodeIM > 0.0f ) + { + float4 nodeV = g_vertexVelocity[nodeID]; + float4 normal = g_vertexNormal[nodeID]; + float area = g_vertexArea[nodeID]; + float4 nodeF = g_vertexForceAccumulator[nodeID]; + + // Read per-cloth values + float4 clothAcceleration = g_clothAcceleration[clothId]; + float4 clothWindVelocity = g_clothWindVelocity[clothId]; + float liftFactor = g_clothLiftFactor[clothId]; + float dragFactor = g_clothDragFactor[clothId]; + float mediumDensity = g_clothMediumDensity[clothId]; + + // Apply the acceleration to the cloth rather than do this via a force + nodeV += (clothAcceleration*solverdt); + + g_vertexVelocity[nodeID] = nodeV; + + // Aerodynamics + float4 rel_v = nodeV - clothWindVelocity; + float rel_v_len = alength3(rel_v); + float rel_v2 = dot(rel_v, rel_v); + + if( rel_v2 > epsilon ) + { + float4 rel_v_nrm = anormalize3(rel_v); + float4 nrm = normal; + + nrm = nrm * (dot(nrm, rel_v) < 0 ? -1.f : 1.f); + + float4 fDrag = (float4)(0.f, 0.f, 0.f, 0.f); + float4 fLift = (float4)(0.f, 0.f, 0.f, 0.f); + + float n_dot_v = dot(nrm, rel_v_nrm); + + // drag force + if ( dragFactor > 0.f ) + fDrag = 0.5f * dragFactor * mediumDensity * rel_v2 * area * n_dot_v * (-1.0f) * rel_v_nrm; + + // lift force + // Check angle of attack + // cos(10º) = 0.98480 + if ( 0 < n_dot_v && n_dot_v < 0.98480f) + fLift = 0.5f * liftFactor * mediumDensity * rel_v_len * area * sqrt(1.0f-n_dot_v*n_dot_v) * (cross(cross(nrm, rel_v_nrm), rel_v_nrm)); + + nodeF += fDrag + fLift; + g_vertexForceAccumulator[nodeID] = nodeF; + } + } + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ComputeBounds.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ComputeBounds.cl new file mode 100644 index 0000000..f18eada --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/ComputeBounds.cl @@ -0,0 +1,82 @@ +MSTRINGIFY( +#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n +#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n + +__kernel void +ComputeBoundsKernel( + const int numNodes, + const int numSoftBodies, + __global int * g_vertexClothIdentifier, + __global float4 * g_vertexPositions, + /* Unfortunately, to get the atomics below to work these arrays cannot be */ + /* uint4, though that is the layout of the data */ + /* Therefore this is little-endian-only code */ + volatile __global uint * g_clothMinBounds, + volatile __global uint * g_clothMaxBounds, + volatile __local uint * clothMinBounds, + volatile __local uint * clothMaxBounds) +{ + // Init min and max bounds arrays + if( get_local_id(0) < numSoftBodies ) + { + + clothMinBounds[get_local_id(0)*4] = UINT_MAX; + clothMinBounds[get_local_id(0)*4+1] = UINT_MAX; + clothMinBounds[get_local_id(0)*4+2] = UINT_MAX; + clothMinBounds[get_local_id(0)*4+3] = UINT_MAX; + clothMaxBounds[get_local_id(0)*4] = 0; + clothMaxBounds[get_local_id(0)*4+1] = 0; + clothMaxBounds[get_local_id(0)*4+2] = 0; + clothMaxBounds[get_local_id(0)*4+3] = 0; + + } + + barrier(CLK_LOCAL_MEM_FENCE); + + int nodeID = get_global_id(0); + if( nodeID < numNodes ) + { + int clothIdentifier = g_vertexClothIdentifier[nodeID]; + if( clothIdentifier >= 0 ) + { + + float4 position = (float4)(g_vertexPositions[nodeID].xyz, 0.f); + + /* Reinterpret position as uint */ + uint4 positionUInt = (uint4)(as_uint(position.x), as_uint(position.y), as_uint(position.z), 0); + + /* Invert sign bit of positives and whole of negatives to allow comparison as unsigned ints */ + positionUInt.x ^= (1+~(positionUInt.x >> 31) | 0x80000000); + positionUInt.y ^= (1+~(positionUInt.y >> 31) | 0x80000000); + positionUInt.z ^= (1+~(positionUInt.z >> 31) | 0x80000000); + + // Min/max with the LDS values + atom_min(&(clothMinBounds[clothIdentifier*4]), positionUInt.x); + atom_min(&(clothMinBounds[clothIdentifier*4+1]), positionUInt.y); + atom_min(&(clothMinBounds[clothIdentifier*4+2]), positionUInt.z); + + atom_max(&(clothMaxBounds[clothIdentifier*4]), positionUInt.x); + atom_max(&(clothMaxBounds[clothIdentifier*4+1]), positionUInt.y); + atom_max(&(clothMaxBounds[clothIdentifier*4+2]), positionUInt.z); + } + } + + barrier(CLK_LOCAL_MEM_FENCE); + + + /* Use global atomics to update the global versions of the data */ + if( get_local_id(0) < numSoftBodies ) + { + /*atom_min(&(g_clothMinBounds[get_local_id(0)].x), clothMinBounds[get_local_id(0)].x);*/ + atom_min(&(g_clothMinBounds[get_local_id(0)*4]), clothMinBounds[get_local_id(0)*4]); + atom_min(&(g_clothMinBounds[get_local_id(0)*4+1]), clothMinBounds[get_local_id(0)*4+1]); + atom_min(&(g_clothMinBounds[get_local_id(0)*4+2]), clothMinBounds[get_local_id(0)*4+2]); + + atom_max(&(g_clothMaxBounds[get_local_id(0)*4]), clothMaxBounds[get_local_id(0)*4]); + atom_max(&(g_clothMaxBounds[get_local_id(0)*4+1]), clothMaxBounds[get_local_id(0)*4+1]); + atom_max(&(g_clothMaxBounds[get_local_id(0)*4+2]), clothMaxBounds[get_local_id(0)*4+2]); + } +} + + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/Integrate.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/Integrate.cl new file mode 100644 index 0000000..fb65330 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/Integrate.cl @@ -0,0 +1,35 @@ +MSTRINGIFY( + +// Node indices for each link + + + +__kernel void +IntegrateKernel( + const int numNodes, + const float solverdt, + __global float * g_vertexInverseMasses, + __global float4 * g_vertexPositions, + __global float4 * g_vertexVelocity, + __global float4 * g_vertexPreviousPositions, + __global float4 * g_vertexForceAccumulator GUID_ARG) +{ + int nodeID = get_global_id(0); + if( nodeID < numNodes ) + { + float4 position = g_vertexPositions[nodeID]; + float4 velocity = g_vertexVelocity[nodeID]; + float4 force = g_vertexForceAccumulator[nodeID]; + float inverseMass = g_vertexInverseMasses[nodeID]; + + g_vertexPreviousPositions[nodeID] = position; + velocity += force * inverseMass * solverdt; + position += velocity * solverdt; + + g_vertexForceAccumulator[nodeID] = (float4)(0.f, 0.f, 0.f, 0.0f); + g_vertexPositions[nodeID] = position; + g_vertexVelocity[nodeID] = velocity; + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/OutputToVertexArray.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/OutputToVertexArray.cl new file mode 100644 index 0000000..f04e092 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/OutputToVertexArray.cl @@ -0,0 +1,46 @@ +MSTRINGIFY( + +__kernel void +OutputToVertexArrayWithNormalsKernel( + const int startNode, const int numNodes, __global float *g_vertexBuffer, + const int positionOffset, const int positionStride, const __global float4* g_vertexPositions, + const int normalOffset, const int normalStride, const __global float4* g_vertexNormals ) +{ + int nodeID = get_global_id(0); + if( nodeID < numNodes ) + { + float4 position = g_vertexPositions[nodeID + startNode]; + float4 normal = g_vertexNormals[nodeID + startNode]; + + // Stride should account for the float->float4 conversion + int positionDestination = nodeID * positionStride + positionOffset; + g_vertexBuffer[positionDestination] = position.x; + g_vertexBuffer[positionDestination+1] = position.y; + g_vertexBuffer[positionDestination+2] = position.z; + + int normalDestination = nodeID * normalStride + normalOffset; + g_vertexBuffer[normalDestination] = normal.x; + g_vertexBuffer[normalDestination+1] = normal.y; + g_vertexBuffer[normalDestination+2] = normal.z; + } +} + +__kernel void +OutputToVertexArrayWithoutNormalsKernel( + const int startNode, const int numNodes, __global float *g_vertexBuffer, + const int positionOffset, const int positionStride, const __global float4* g_vertexPositions ) +{ + int nodeID = get_global_id(0); + if( nodeID < numNodes ) + { + float4 position = g_vertexPositions[nodeID + startNode]; + + // Stride should account for the float->float4 conversion + int positionDestination = nodeID * positionStride + positionOffset; + g_vertexBuffer[positionDestination] = position.x; + g_vertexBuffer[positionDestination+1] = position.y; + g_vertexBuffer[positionDestination+2] = position.z; + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/PrepareLinks.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/PrepareLinks.cl new file mode 100644 index 0000000..72d46cc --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/PrepareLinks.cl @@ -0,0 +1,38 @@ +MSTRINGIFY( + + + +__kernel void +PrepareLinksKernel( + const int numLinks, + __global int2 * g_linksVertexIndices, + __global float * g_linksMassLSC, + __global float4 * g_nodesPreviousPosition, + __global float * g_linksLengthRatio, + __global float4 * g_linksCurrentLength GUID_ARG) +{ + int linkID = get_global_id(0); + if( linkID < numLinks ) + { + + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + + float4 nodePreviousPosition0 = g_nodesPreviousPosition[node0]; + float4 nodePreviousPosition1 = g_nodesPreviousPosition[node1]; + + float massLSC = g_linksMassLSC[linkID]; + + float4 linkCurrentLength = nodePreviousPosition1 - nodePreviousPosition0; + linkCurrentLength.w = 0.f; + + float linkLengthRatio = dot(linkCurrentLength, linkCurrentLength)*massLSC; + linkLengthRatio = 1.0f/linkLengthRatio; + + g_linksCurrentLength[linkID] = linkCurrentLength; + g_linksLengthRatio[linkID] = linkLengthRatio; + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocities.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocities.cl new file mode 100644 index 0000000..099042f --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocities.cl @@ -0,0 +1,204 @@ +MSTRINGIFY( + + + +float mydot3a(float4 a, float4 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + + +typedef struct +{ + int firstObject; + int endObject; +} CollisionObjectIndices; + +typedef struct +{ + float4 shapeTransform[4]; // column major 4x4 matrix + float4 linearVelocity; + float4 angularVelocity; + + int softBodyIdentifier; + int collisionShapeType; + + + // Shape information + // Compressed from the union + float radius; + float halfHeight; + int upAxis; + + float margin; + float friction; + + int padding0; + +} CollisionShapeDescription; + +// From btBroadphaseProxy.h +__constant int CAPSULE_SHAPE_PROXYTYPE = 10; + +// Multiply column-major matrix against vector +float4 matrixVectorMul( float4 matrix[4], float4 vector ) +{ + float4 returnVector; + float4 row0 = (float4)(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x); + float4 row1 = (float4)(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y); + float4 row2 = (float4)(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z); + float4 row3 = (float4)(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w); + returnVector.x = dot(row0, vector); + returnVector.y = dot(row1, vector); + returnVector.z = dot(row2, vector); + returnVector.w = dot(row3, vector); + return returnVector; +} + +__kernel void +SolveCollisionsAndUpdateVelocitiesKernel( + const int numNodes, + const float isolverdt, + __global int *g_vertexClothIdentifier, + __global float4 *g_vertexPreviousPositions, + __global float * g_perClothFriction, + __global float * g_clothDampingFactor, + __global CollisionObjectIndices * g_perClothCollisionObjectIndices, + __global CollisionShapeDescription * g_collisionObjectDetails, + __global float4 * g_vertexForces, + __global float4 *g_vertexVelocities, + __global float4 *g_vertexPositions GUID_ARG) +{ + int nodeID = get_global_id(0); + float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f); + + if( get_global_id(0) < numNodes ) + { + int clothIdentifier = g_vertexClothIdentifier[nodeID]; + + // Abort if this is not a valid cloth + if( clothIdentifier < 0 ) + return; + + + float4 position = (float4)(g_vertexPositions[nodeID].xyz, 1.f); + float4 previousPosition = (float4)(g_vertexPreviousPositions[nodeID].xyz, 1.f); + + float clothFriction = g_perClothFriction[clothIdentifier]; + float dampingFactor = g_clothDampingFactor[clothIdentifier]; + float velocityCoefficient = (1.f - dampingFactor); + float4 difference = position - previousPosition; + float4 velocity = difference*velocityCoefficient*isolverdt; + + CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier]; + + int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject; + + if( numObjects > 0 ) + { + // We have some possible collisions to deal with + for( int collision = collisionObjectIndices.firstObject; collision < collisionObjectIndices.endObject; ++collision ) + { + CollisionShapeDescription shapeDescription = g_collisionObjectDetails[collision]; + float colliderFriction = shapeDescription.friction; + + if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE ) + { + // Colliding with a capsule + + float capsuleHalfHeight = shapeDescription.halfHeight; + float capsuleRadius = shapeDescription.radius; + float capsuleMargin = shapeDescription.margin; + int capsuleupAxis = shapeDescription.upAxis; + + // Four columns of worldTransform matrix + float4 worldTransform[4]; + worldTransform[0] = shapeDescription.shapeTransform[0]; + worldTransform[1] = shapeDescription.shapeTransform[1]; + worldTransform[2] = shapeDescription.shapeTransform[2]; + worldTransform[3] = shapeDescription.shapeTransform[3]; + + // Correctly define capsule centerline vector + float4 c1 = (float4)(0.f, 0.f, 0.f, 1.f); + float4 c2 = (float4)(0.f, 0.f, 0.f, 1.f); + c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 ); + c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 ); + c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 ); + c2.x = -c1.x; + c2.y = -c1.y; + c2.z = -c1.z; + + + float4 worldC1 = matrixVectorMul(worldTransform, c1); + float4 worldC2 = matrixVectorMul(worldTransform, c2); + float4 segment = (worldC2 - worldC1); + + // compute distance of tangent to vertex along line segment in capsule + float distanceAlongSegment = -( mydot3a( (worldC1 - position), segment ) / mydot3a(segment, segment) ); + + float4 closestPoint = (worldC1 + (float4)(segment * distanceAlongSegment)); + float distanceFromLine = length(position - closestPoint); + float distanceFromC1 = length(worldC1 - position); + float distanceFromC2 = length(worldC2 - position); + + // Final distance from collision, point to push from, direction to push in + // for impulse force + float dist; + float4 normalVector; + if( distanceAlongSegment < 0 ) + { + dist = distanceFromC1; + normalVector = (float4)(normalize(position - worldC1).xyz, 0.f); + } else if( distanceAlongSegment > 1.f ) { + dist = distanceFromC2; + normalVector = (float4)(normalize(position - worldC2).xyz, 0.f); + } else { + dist = distanceFromLine; + normalVector = (float4)(normalize(position - closestPoint).xyz, 0.f); + } + + float4 colliderLinearVelocity = shapeDescription.linearVelocity; + float4 colliderAngularVelocity = shapeDescription.angularVelocity; + float4 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position - (float4)(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w, 0.f)); + + float minDistance = capsuleRadius + capsuleMargin; + + // In case of no collision, this is the value of velocity + velocity = (position - previousPosition) * velocityCoefficient * isolverdt; + + + // Check for a collision + if( dist < minDistance ) + { + // Project back to surface along normal + position = position + (float4)((minDistance - dist)*normalVector*0.9f); + velocity = (position - previousPosition) * velocityCoefficient * isolverdt; + float4 relativeVelocity = velocity - velocityOfSurfacePoint; + + float4 p1 = normalize(cross(normalVector, segment)); + float4 p2 = normalize(cross(p1, normalVector)); + // Full friction is sum of velocities in each direction of plane + float4 frictionVector = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2); + + // Real friction is peak friction corrected by friction coefficients + frictionVector = frictionVector * (colliderFriction*clothFriction); + + float approachSpeed = dot(relativeVelocity, normalVector); + + if( approachSpeed <= 0.0f ) + forceOnVertex -= frictionVector; + } + } + } + } + + g_vertexVelocities[nodeID] = (float4)(velocity.xyz, 0.f); + + // Update external force + g_vertexForces[nodeID] = (float4)(forceOnVertex.xyz, 0.f); + + g_vertexPositions[nodeID] = (float4)(position.xyz, 0.f); + } +} + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl new file mode 100644 index 0000000..8709022 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl @@ -0,0 +1,242 @@ +MSTRINGIFY( + +//#pragma OPENCL EXTENSION cl_amd_printf:enable\n + +float mydot3a(float4 a, float4 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + +float mylength3(float4 a) +{ + a.w = 0; + return length(a); +} + +float4 mynormalize3(float4 a) +{ + a.w = 0; + return normalize(a); +} + +typedef struct +{ + int firstObject; + int endObject; +} CollisionObjectIndices; + +typedef struct +{ + float4 shapeTransform[4]; // column major 4x4 matrix + float4 linearVelocity; + float4 angularVelocity; + + int softBodyIdentifier; + int collisionShapeType; + + + // Shape information + // Compressed from the union + float radius; + float halfHeight; + int upAxis; + + float margin; + float friction; + + int padding0; + +} CollisionShapeDescription; + +// From btBroadphaseProxy.h +__constant int CAPSULE_SHAPE_PROXYTYPE = 10; + +// Multiply column-major matrix against vector +float4 matrixVectorMul( float4 matrix[4], float4 vector ) +{ + float4 returnVector; + float4 row0 = (float4)(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x); + float4 row1 = (float4)(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y); + float4 row2 = (float4)(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z); + float4 row3 = (float4)(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w); + returnVector.x = dot(row0, vector); + returnVector.y = dot(row1, vector); + returnVector.z = dot(row2, vector); + returnVector.w = dot(row3, vector); + return returnVector; +} + +__kernel void +SolveCollisionsAndUpdateVelocitiesKernel( + const int numNodes, + const float isolverdt, + __global int *g_vertexClothIdentifier, + __global float4 *g_vertexPreviousPositions, + __global float * g_perClothFriction, + __global float * g_clothDampingFactor, + __global CollisionObjectIndices * g_perClothCollisionObjectIndices, + __global CollisionShapeDescription * g_collisionObjectDetails, + __global float4 * g_vertexForces, + __global float4 *g_vertexVelocities, + __global float4 *g_vertexPositions, + __local CollisionShapeDescription *localCollisionShapes, + __global float * g_vertexInverseMasses) +{ + int nodeID = get_global_id(0); + float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f); + + int clothIdentifier = g_vertexClothIdentifier[nodeID]; + + // Abort if this is not a valid cloth + if( clothIdentifier < 0 ) + return; + + + float4 position = (float4)(g_vertexPositions[nodeID].xyz, 0.f); + float4 previousPosition = (float4)(g_vertexPreviousPositions[nodeID].xyz, 0.f); + + float clothFriction = g_perClothFriction[clothIdentifier]; + float dampingFactor = g_clothDampingFactor[clothIdentifier]; + float velocityCoefficient = (1.f - dampingFactor); + float4 difference = position - previousPosition; + float4 velocity = difference*velocityCoefficient*isolverdt; + float inverseMass = g_vertexInverseMasses[nodeID]; + + CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier]; + + int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject; + + if( numObjects > 0 ) + { + // We have some possible collisions to deal with + + // First load all of the collision objects into LDS + int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject; + if( get_local_id(0) < numObjects ) + { + localCollisionShapes[get_local_id(0)] = g_collisionObjectDetails[ collisionObjectIndices.firstObject + get_local_id(0) ]; + } + } + + // Safe as the vertices are padded so that not more than one soft body is in a group + barrier(CLK_LOCAL_MEM_FENCE); + + // Annoyingly, even though I know the flow control is not varying, the compiler will not let me skip this + if( numObjects > 0 ) + { + + + // We have some possible collisions to deal with + for( int collision = 0; collision < numObjects; ++collision ) + { + CollisionShapeDescription shapeDescription = localCollisionShapes[collision]; + float colliderFriction = localCollisionShapes[collision].friction; + + if( localCollisionShapes[collision].collisionShapeType == CAPSULE_SHAPE_PROXYTYPE ) + { + // Colliding with a capsule + + float capsuleHalfHeight = localCollisionShapes[collision].halfHeight; + float capsuleRadius = localCollisionShapes[collision].radius; + float capsuleMargin = localCollisionShapes[collision].margin; + int capsuleupAxis = localCollisionShapes[collision].upAxis; + + if ( capsuleHalfHeight <= 0 ) + capsuleHalfHeight = 0.0001f; + float4 worldTransform[4]; + worldTransform[0] = localCollisionShapes[collision].shapeTransform[0]; + worldTransform[1] = localCollisionShapes[collision].shapeTransform[1]; + worldTransform[2] = localCollisionShapes[collision].shapeTransform[2]; + worldTransform[3] = localCollisionShapes[collision].shapeTransform[3]; + + // Correctly define capsule centerline vector + float4 c1 = (float4)(0.f, 0.f, 0.f, 1.f); + float4 c2 = (float4)(0.f, 0.f, 0.f, 1.f); + c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 ); + c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 ); + c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 ); + c2.x = -c1.x; + c2.y = -c1.y; + c2.z = -c1.z; + + float4 worldC1 = matrixVectorMul(worldTransform, c1); + float4 worldC2 = matrixVectorMul(worldTransform, c2); + float4 segment = (float4)((worldC2 - worldC1).xyz, 0.f); + + float4 segmentNormalized = mynormalize3(segment); + float distanceAlongSegment =mydot3a( (position - worldC1), segmentNormalized ); + + float4 closestPointOnSegment = (worldC1 + (float4)(segmentNormalized * distanceAlongSegment)); + float distanceFromLine = mylength3(position - closestPointOnSegment); + float distanceFromC1 = mylength3(worldC1 - position); + float distanceFromC2 = mylength3(worldC2 - position); + + // Final distance from collision, point to push from, direction to push in + // for impulse force + float dist; + float4 normalVector; + + if( distanceAlongSegment < 0 ) + { + dist = distanceFromC1; + normalVector = (float4)(normalize(position - worldC1).xyz, 0.f); + } else if( distanceAlongSegment > length(segment) ) { + dist = distanceFromC2; + normalVector = (float4)(normalize(position - worldC2).xyz, 0.f); + } else { + dist = distanceFromLine; + normalVector = (float4)(normalize(position - closestPointOnSegment).xyz, 0.f); + } + + float minDistance = capsuleRadius + capsuleMargin; + float4 closestPointOnSurface = (float4)((position + (minDistance - dist) * normalVector).xyz, 0.f); + + float4 colliderLinearVelocity = shapeDescription.linearVelocity; + float4 colliderAngularVelocity = shapeDescription.angularVelocity; + float4 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, closestPointOnSurface - (float4)(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w, 0.f)); + + + // Check for a collision + if( dist < minDistance ) + { + // Project back to surface along normal + position = closestPointOnSurface; + velocity = (position - previousPosition) * velocityCoefficient * isolverdt; + float4 relativeVelocity = velocity - velocityOfSurfacePoint; + + float4 p1 = mynormalize3(cross(normalVector, segment)); + float4 p2 = mynormalize3(cross(p1, normalVector)); + + float4 tangentialVel = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2); + float frictionCoef = (colliderFriction * clothFriction); + if (frictionCoef>1.f) + frictionCoef = 1.f; + + //only apply friction if objects are not moving apart + float projVel = mydot3a(relativeVelocity,normalVector); + if ( projVel >= -0.001f) + { + if ( inverseMass > 0 ) + { + //float4 myforceOnVertex = -tangentialVel * frictionCoef * isolverdt * (1.0f / inverseMass); + position += (-tangentialVel * frictionCoef) / (isolverdt); + } + } + + // In case of no collision, this is the value of velocity + velocity = (position - previousPosition) * velocityCoefficient * isolverdt; + + } + } + } + } + + g_vertexVelocities[nodeID] = (float4)(velocity.xyz, 0.f); + + // Update external force + g_vertexForces[nodeID] = (float4)(forceOnVertex.xyz, 0.f); + + g_vertexPositions[nodeID] = (float4)(position.xyz, 0.f); +} + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositions.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositions.cl new file mode 100644 index 0000000..fe7aec6 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositions.cl @@ -0,0 +1,57 @@ + + + +MSTRINGIFY( + + +float mydot3(float4 a, float4 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + + +__kernel void +SolvePositionsFromLinksKernel( + const int startLink, + const int numLinks, + const float kst, + const float ti, + __global int2 * g_linksVertexIndices, + __global float * g_linksMassLSC, + __global float * g_linksRestLengthSquared, + __global float * g_verticesInverseMass, + __global float4 * g_vertexPositions GUID_ARG) + +{ + int linkID = get_global_id(0) + startLink; + if( get_global_id(0) < numLinks ) + { + float massLSC = g_linksMassLSC[linkID]; + float restLengthSquared = g_linksRestLengthSquared[linkID]; + + if( massLSC > 0.0f ) + { + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + + float4 position0 = g_vertexPositions[node0]; + float4 position1 = g_vertexPositions[node1]; + + float inverseMass0 = g_verticesInverseMass[node0]; + float inverseMass1 = g_verticesInverseMass[node1]; + + float4 del = position1 - position0; + float len = mydot3(del, del); + float k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst; + position0 = position0 - del*(k*inverseMass0); + position1 = position1 + del*(k*inverseMass1); + + g_vertexPositions[node0] = position0; + g_vertexPositions[node1] = position1; + + } + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositionsSIMDBatched.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositionsSIMDBatched.cl new file mode 100644 index 0000000..3316342 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/SolvePositionsSIMDBatched.cl @@ -0,0 +1,130 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +MSTRINGIFY( + +float mydot3(float4 a, float4 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + +__kernel __attribute__((reqd_work_group_size(WAVEFRONT_BLOCK_MULTIPLIER*WAVEFRONT_SIZE, 1, 1))) +void +SolvePositionsFromLinksKernel( + const int startWaveInBatch, + const int numWaves, + const float kst, + const float ti, + __global int2 *g_wavefrontBatchCountsVertexCounts, + __global int *g_vertexAddressesPerWavefront, + __global int2 * g_linksVertexIndices, + __global float * g_linksMassLSC, + __global float * g_linksRestLengthSquared, + __global float * g_verticesInverseMass, + __global float4 * g_vertexPositions, + __local int2 *wavefrontBatchCountsVertexCounts, + __local float4 *vertexPositionSharedData, + __local float *vertexInverseMassSharedData) +{ + const int laneInWavefront = (get_global_id(0) & (WAVEFRONT_SIZE-1)); + const int wavefront = startWaveInBatch + (get_global_id(0) / WAVEFRONT_SIZE); + const int firstWavefrontInBlock = startWaveInBatch + get_group_id(0) * WAVEFRONT_BLOCK_MULTIPLIER; + const int localWavefront = wavefront - firstWavefrontInBlock; + + // Mask out in case there's a stray "wavefront" at the end that's been forced in through the multiplier + if( wavefront < (startWaveInBatch + numWaves) ) + { + // Load the batch counts for the wavefronts + + int2 batchesAndVerticesWithinWavefront = g_wavefrontBatchCountsVertexCounts[wavefront]; + int batchesWithinWavefront = batchesAndVerticesWithinWavefront.x; + int verticesUsedByWave = batchesAndVerticesWithinWavefront.y; + + // Load the vertices for the wavefronts + for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE ) + { + int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex]; + + vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_vertexPositions[vertexAddress]; + vertexInverseMassSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_verticesInverseMass[vertexAddress]; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + // Loop through the batches performing the solve on each in LDS + int baseDataLocationForWave = WAVEFRONT_SIZE * wavefront * MAX_BATCHES_PER_WAVE; + + //for( int batch = 0; batch < batchesWithinWavefront; ++batch ) + + int batch = 0; + do + { + int baseDataLocation = baseDataLocationForWave + WAVEFRONT_SIZE * batch; + int locationOfValue = baseDataLocation + laneInWavefront; + + + // These loads should all be perfectly linear across the WF + int2 localVertexIndices = g_linksVertexIndices[locationOfValue]; + float massLSC = g_linksMassLSC[locationOfValue]; + float restLengthSquared = g_linksRestLengthSquared[locationOfValue]; + + // LDS vertex addresses based on logical wavefront number in block and loaded index + int vertexAddress0 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.x; + int vertexAddress1 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.y; + + float4 position0 = vertexPositionSharedData[vertexAddress0]; + float4 position1 = vertexPositionSharedData[vertexAddress1]; + + float inverseMass0 = vertexInverseMassSharedData[vertexAddress0]; + float inverseMass1 = vertexInverseMassSharedData[vertexAddress1]; + + float4 del = position1 - position0; + float len = mydot3(del, del); + + float k = 0; + if( massLSC > 0.0f ) + { + k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst; + } + + position0 = position0 - del*(k*inverseMass0); + position1 = position1 + del*(k*inverseMass1); + + // Ensure compiler does not re-order memory operations + barrier(CLK_LOCAL_MEM_FENCE); + + vertexPositionSharedData[vertexAddress0] = position0; + vertexPositionSharedData[vertexAddress1] = position1; + + // Ensure compiler does not re-order memory operations + barrier(CLK_LOCAL_MEM_FENCE); + + + ++batch; + } while( batch < batchesWithinWavefront ); + + // Update the global memory vertices for the wavefronts + for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE ) + { + int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex]; + + g_vertexPositions[vertexAddress] = (float4)(vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex].xyz, 0.f); + } + + } + +} + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateConstants.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateConstants.cl new file mode 100644 index 0000000..488a584 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateConstants.cl @@ -0,0 +1,44 @@ +MSTRINGIFY( + +/*#define float3 float4 + +float dot3(float3 a, float3 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +}*/ + +__kernel void +UpdateConstantsKernel( + const int numLinks, + __global int2 * g_linksVertexIndices, + __global float4 * g_vertexPositions, + __global float * g_vertexInverseMasses, + __global float * g_linksMaterialLSC, + __global float * g_linksMassLSC, + __global float * g_linksRestLengthSquared, + __global float * g_linksRestLengths) +{ + int linkID = get_global_id(0); + if( linkID < numLinks ) + { + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + float linearStiffnessCoefficient = g_linksMaterialLSC[ linkID ]; + + float3 position0 = g_vertexPositions[node0].xyz; + float3 position1 = g_vertexPositions[node1].xyz; + float inverseMass0 = g_vertexInverseMasses[node0]; + float inverseMass1 = g_vertexInverseMasses[node1]; + + float3 difference = position0 - position1; + float length2 = dot(difference, difference); + float length = sqrt(length2); + + g_linksRestLengths[linkID] = length; + g_linksMassLSC[linkID] = (inverseMass0 + inverseMass1)/linearStiffnessCoefficient; + g_linksRestLengthSquared[linkID] = length*length; + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateFixedVertexPositions.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateFixedVertexPositions.cl new file mode 100644 index 0000000..c631f16 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateFixedVertexPositions.cl @@ -0,0 +1,25 @@ +MSTRINGIFY( + +__kernel void +UpdateFixedVertexPositions( + const uint numNodes, + __global int * g_anchorIndex, + __global float4 * g_vertexPositions, + __global float4 * g_anchorPositions GUID_ARG) +{ + unsigned int nodeID = get_global_id(0); + + if( nodeID < numNodes ) + { + int anchorIndex = g_anchorIndex[nodeID]; + float4 position = g_vertexPositions[nodeID]; + + if ( anchorIndex >= 0 ) + { + float4 anchorPosition = g_anchorPositions[anchorIndex]; + g_vertexPositions[nodeID] = anchorPosition; + } + } +} + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNodes.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNodes.cl new file mode 100644 index 0000000..9ad227b --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNodes.cl @@ -0,0 +1,39 @@ +MSTRINGIFY( + + +__kernel void +updateVelocitiesFromPositionsWithVelocitiesKernel( + int numNodes, + float isolverdt, + __global float4 * g_vertexPositions, + __global float4 * g_vertexPreviousPositions, + __global int * g_vertexClothIndices, + __global float *g_clothVelocityCorrectionCoefficients, + __global float * g_clothDampingFactor, + __global float4 * g_vertexVelocities, + __global float4 * g_vertexForces GUID_ARG) +{ + int nodeID = get_global_id(0); + if( nodeID < numNodes ) + { + float4 position = g_vertexPositions[nodeID]; + float4 previousPosition = g_vertexPreviousPositions[nodeID]; + float4 velocity = g_vertexVelocities[nodeID]; + int clothIndex = g_vertexClothIndices[nodeID]; + float velocityCorrectionCoefficient = g_clothVelocityCorrectionCoefficients[clothIndex]; + float dampingFactor = g_clothDampingFactor[clothIndex]; + float velocityCoefficient = (1.f - dampingFactor); + + float4 difference = position - previousPosition; + + velocity += difference*velocityCorrectionCoefficient*isolverdt; + + // Damp the velocity + velocity *= velocityCoefficient; + + g_vertexVelocities[nodeID] = velocity; + g_vertexForces[nodeID] = (float4)(0.f, 0.f, 0.f, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNormals.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNormals.cl new file mode 100644 index 0000000..7bb2334 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdateNormals.cl @@ -0,0 +1,102 @@ +MSTRINGIFY( + +float length3(float4 a) +{ + a.w = 0; + return length(a); +} + +float4 normalize3(float4 a) +{ + a.w = 0; + return normalize(a); +} + +__kernel void +ResetNormalsAndAreasKernel( + const unsigned int numNodes, + __global float4 * g_vertexNormals, + __global float * g_vertexArea GUID_ARG) +{ + if( get_global_id(0) < numNodes ) + { + g_vertexNormals[get_global_id(0)] = (float4)(0.0f, 0.0f, 0.0f, 0.0f); + g_vertexArea[get_global_id(0)] = 0.0f; + } +} + + +__kernel void +UpdateSoftBodiesKernel( + const unsigned int startFace, + const unsigned int numFaces, + __global int4 * g_triangleVertexIndexSet, + __global float4 * g_vertexPositions, + __global float4 * g_vertexNormals, + __global float * g_vertexArea, + __global float4 * g_triangleNormals, + __global float * g_triangleArea GUID_ARG) +{ + int faceID = get_global_id(0) + startFace; + if( get_global_id(0) < numFaces ) + { + int4 triangleIndexSet = g_triangleVertexIndexSet[ faceID ]; + int nodeIndex0 = triangleIndexSet.x; + int nodeIndex1 = triangleIndexSet.y; + int nodeIndex2 = triangleIndexSet.z; + + float4 node0 = g_vertexPositions[nodeIndex0]; + float4 node1 = g_vertexPositions[nodeIndex1]; + float4 node2 = g_vertexPositions[nodeIndex2]; + float4 nodeNormal0 = g_vertexNormals[nodeIndex0]; + float4 nodeNormal1 = g_vertexNormals[nodeIndex1]; + float4 nodeNormal2 = g_vertexNormals[nodeIndex2]; + float vertexArea0 = g_vertexArea[nodeIndex0]; + float vertexArea1 = g_vertexArea[nodeIndex1]; + float vertexArea2 = g_vertexArea[nodeIndex2]; + + float4 vector0 = node1 - node0; + float4 vector1 = node2 - node0; + + float4 faceNormal = cross(vector0, vector1); + float triangleArea = length(faceNormal); + + nodeNormal0 = nodeNormal0 + faceNormal; + nodeNormal1 = nodeNormal1 + faceNormal; + nodeNormal2 = nodeNormal2 + faceNormal; + vertexArea0 = vertexArea0 + triangleArea; + vertexArea1 = vertexArea1 + triangleArea; + vertexArea2 = vertexArea2 + triangleArea; + + g_triangleNormals[faceID] = normalize3(faceNormal); + g_vertexNormals[nodeIndex0] = nodeNormal0; + g_vertexNormals[nodeIndex1] = nodeNormal1; + g_vertexNormals[nodeIndex2] = nodeNormal2; + g_triangleArea[faceID] = triangleArea; + g_vertexArea[nodeIndex0] = vertexArea0; + g_vertexArea[nodeIndex1] = vertexArea1; + g_vertexArea[nodeIndex2] = vertexArea2; + } +} + +__kernel void +NormalizeNormalsAndAreasKernel( + const unsigned int numNodes, + __global int * g_vertexTriangleCount, + __global float4 * g_vertexNormals, + __global float * g_vertexArea GUID_ARG) +{ + if( get_global_id(0) < numNodes ) + { + float4 normal = g_vertexNormals[get_global_id(0)]; + float area = g_vertexArea[get_global_id(0)]; + int numTriangles = g_vertexTriangleCount[get_global_id(0)]; + + float vectorLength = length3(normal); + + g_vertexNormals[get_global_id(0)] = normalize3(normal); + g_vertexArea[get_global_id(0)] = area/(float)(numTriangles); + } +} + +); diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositions.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositions.cl new file mode 100644 index 0000000..3155a04 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositions.cl @@ -0,0 +1,34 @@ +MSTRINGIFY( + +__kernel void +updateVelocitiesFromPositionsWithoutVelocitiesKernel( + const int numNodes, + const float isolverdt, + __global float4 * g_vertexPositions, + __global float4 * g_vertexPreviousPositions, + __global int * g_vertexClothIndices, + __global float * g_clothDampingFactor, + __global float4 * g_vertexVelocities, + __global float4 * g_vertexForces GUID_ARG) + +{ + int nodeID = get_global_id(0); + if( nodeID < numNodes ) + { + float4 position = g_vertexPositions[nodeID]; + float4 previousPosition = g_vertexPreviousPositions[nodeID]; + float4 velocity = g_vertexVelocities[nodeID]; + int clothIndex = g_vertexClothIndices[nodeID]; + float dampingFactor = g_clothDampingFactor[clothIndex]; + float velocityCoefficient = (1.f - dampingFactor); + + float4 difference = position - previousPosition; + + velocity = difference*velocityCoefficient*isolverdt; + + g_vertexVelocities[nodeID] = velocity; + g_vertexForces[nodeID] = (float4)(0.f, 0.f, 0.f, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositionsFromVelocities.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositionsFromVelocities.cl new file mode 100644 index 0000000..97e708b --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/UpdatePositionsFromVelocities.cl @@ -0,0 +1,28 @@ + +MSTRINGIFY( + + + + +__kernel void +UpdatePositionsFromVelocitiesKernel( + const int numNodes, + const float solverSDT, + __global float4 * g_vertexVelocities, + __global float4 * g_vertexPreviousPositions, + __global float4 * g_vertexCurrentPosition GUID_ARG) +{ + int vertexID = get_global_id(0); + if( vertexID < numNodes ) + { + float4 previousPosition = g_vertexPreviousPositions[vertexID]; + float4 velocity = g_vertexVelocities[vertexID]; + + float4 newPosition = previousPosition + velocity*solverSDT; + + g_vertexCurrentPosition[vertexID] = newPosition; + g_vertexPreviousPositions[vertexID] = newPosition; + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/VSolveLinks.cl b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/VSolveLinks.cl new file mode 100644 index 0000000..a618d69 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC10/VSolveLinks.cl @@ -0,0 +1,45 @@ +MSTRINGIFY( + +__kernel void +VSolveLinksKernel( + int startLink, + int numLinks, + float kst, + __global int2 * g_linksVertexIndices, + __global float * g_linksLengthRatio, + __global float4 * g_linksCurrentLength, + __global float * g_vertexInverseMass, + __global float4 * g_vertexVelocity GUID_ARG) +{ + int linkID = get_global_id(0) + startLink; + if( get_global_id(0) < numLinks ) + { + int2 nodeIndices = g_linksVertexIndices[linkID]; + int node0 = nodeIndices.x; + int node1 = nodeIndices.y; + + float linkLengthRatio = g_linksLengthRatio[linkID]; + float3 linkCurrentLength = g_linksCurrentLength[linkID].xyz; + + float3 vertexVelocity0 = g_vertexVelocity[node0].xyz; + float3 vertexVelocity1 = g_vertexVelocity[node1].xyz; + + float vertexInverseMass0 = g_vertexInverseMass[node0]; + float vertexInverseMass1 = g_vertexInverseMass[node1]; + + float3 nodeDifference = vertexVelocity0 - vertexVelocity1; + float dotResult = dot(linkCurrentLength, nodeDifference); + float j = -dotResult*linkLengthRatio*kst; + + float3 velocityChange0 = linkCurrentLength*(j*vertexInverseMass0); + float3 velocityChange1 = linkCurrentLength*(j*vertexInverseMass1); + + vertexVelocity0 += velocityChange0; + vertexVelocity1 -= velocityChange1; + + g_vertexVelocity[node0] = (float4)(vertexVelocity0, 0.f); + g_vertexVelocity[node1] = (float4)(vertexVelocity1, 0.f); + } +} + +); \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h new file mode 100644 index 0000000..61d474a --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverBuffer_OpenCL.h @@ -0,0 +1,209 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H +#define BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H + +// OpenCL support + +#ifdef USE_MINICL + #include "MiniCL/cl.h" +#else //USE_MINICL + #ifdef __APPLE__ + #include + #else + #include + #endif //__APPLE__ +#endif//USE_MINICL + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } +#endif + +template class btOpenCLBuffer +{ +public: + + cl_command_queue m_cqCommandQue; + cl_context m_clContext; + cl_mem m_buffer; + + + + btAlignedObjectArray< ElementType > * m_CPUBuffer; + + int m_gpuSize; + bool m_onGPU; + bool m_readOnlyOnGPU; + bool m_allocated; + + + bool createBuffer( cl_mem* preexistingBuffer = 0) + { + + cl_int err; + + + if( preexistingBuffer ) + { + m_buffer = *preexistingBuffer; + } + else { + + cl_mem_flags flags= m_readOnlyOnGPU ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE; + + size_t size = m_CPUBuffer->size() * sizeof(ElementType); + // At a minimum the buffer must exist + if( size == 0 ) + size = sizeof(ElementType); + m_buffer = clCreateBuffer(m_clContext, flags, size, 0, &err); + if( err != CL_SUCCESS ) + { + btAssert( "Buffer::Buffer(m_buffer)"); + } + } + + m_gpuSize = m_CPUBuffer->size(); + + return true; + } + +public: + btOpenCLBuffer( cl_command_queue commandQue,cl_context ctx, btAlignedObjectArray< ElementType >* CPUBuffer, bool readOnly) + :m_cqCommandQue(commandQue), + m_clContext(ctx), + m_buffer(0), + m_CPUBuffer(CPUBuffer), + m_gpuSize(0), + m_onGPU(false), + m_readOnlyOnGPU(readOnly), + m_allocated(false) + { + } + + ~btOpenCLBuffer() + { + clReleaseMemObject(m_buffer); + } + + + bool moveToGPU() + { + + + cl_int err; + + if( (m_CPUBuffer->size() != m_gpuSize) ) + { + m_onGPU = false; + } + + if( !m_allocated && m_CPUBuffer->size() == 0 ) + { + // If it isn't on the GPU and yet there is no data on the CPU side this may cause a problem with some kernels. + // We should create *something* on the device side + if (!createBuffer()) { + return false; + } + m_allocated = true; + } + + if( !m_onGPU && m_CPUBuffer->size() > 0 ) + { + if (!m_allocated || (m_CPUBuffer->size() != m_gpuSize)) { + if (!createBuffer()) { + return false; + } + m_allocated = true; + } + + size_t size = m_CPUBuffer->size() * sizeof(ElementType); + err = clEnqueueWriteBuffer(m_cqCommandQue,m_buffer, + CL_FALSE, + 0, + size, + &((*m_CPUBuffer)[0]),0,0,0); + if( err != CL_SUCCESS ) + { + btAssert( "CommandQueue::enqueueWriteBuffer(m_buffer)" ); + } + + m_onGPU = true; + } + + return true; + + } + + bool moveFromGPU() + { + + cl_int err; + + if (m_CPUBuffer->size() > 0) { + if (m_onGPU && !m_readOnlyOnGPU) { + size_t size = m_CPUBuffer->size() * sizeof(ElementType); + err = clEnqueueReadBuffer(m_cqCommandQue, + m_buffer, + CL_TRUE, + 0, + size, + &((*m_CPUBuffer)[0]),0,0,0); + + if( err != CL_SUCCESS ) + { + btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)" ); + } + + m_onGPU = false; + } + } + + return true; + } + + bool copyFromGPU() + { + + cl_int err; + size_t size = m_CPUBuffer->size() * sizeof(ElementType); + + if (m_CPUBuffer->size() > 0) { + if (m_onGPU && !m_readOnlyOnGPU) { + err = clEnqueueReadBuffer(m_cqCommandQue, + m_buffer, + CL_TRUE, + 0,size, + &((*m_CPUBuffer)[0]),0,0,0); + + if( err != CL_SUCCESS ) + { + btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)"); + } + + } + } + + return true; + } + + virtual void changedOnCPU() + { + m_onGPU = false; + } +}; // class btOpenCLBuffer + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCL.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCL.h new file mode 100644 index 0000000..0092c8f --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCL.h @@ -0,0 +1,99 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_OpenCL.h" + + +#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H +#define BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H + + +class btSoftBodyLinkDataOpenCL : public btSoftBodyLinkData +{ +public: + bool m_onGPU; + + cl_command_queue m_cqCommandQue; + + + btOpenCLBuffer m_clLinks; + btOpenCLBuffer m_clLinkStrength; + btOpenCLBuffer m_clLinksMassLSC; + btOpenCLBuffer m_clLinksRestLengthSquared; + btOpenCLBuffer m_clLinksCLength; + btOpenCLBuffer m_clLinksLengthRatio; + btOpenCLBuffer m_clLinksRestLength; + btOpenCLBuffer m_clLinksMaterialLinearStiffnessCoefficient; + + struct BatchPair + { + int start; + int length; + + BatchPair() : + start(0), + length(0) + { + } + + BatchPair( int s, int l ) : + start( s ), + length( l ) + { + } + }; + + /** + * Link addressing information for each cloth. + * Allows link locations to be computed independently of data batching. + */ + btAlignedObjectArray< int > m_linkAddresses; + + /** + * Start and length values for computation batches over link data. + */ + btAlignedObjectArray< BatchPair > m_batchStartLengths; + + btSoftBodyLinkDataOpenCL(cl_command_queue queue, cl_context ctx); + + virtual ~btSoftBodyLinkDataOpenCL(); + + /** Allocate enough space in all link-related arrays to fit numLinks links */ + virtual void createLinks( int numLinks ); + + /** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ + virtual void setLinkAt( + const LinkDescription &link, + int linkIndex ); + + virtual bool onAccelerator(); + + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(); + + /** + * Generate (and later update) the batching for the entire link set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ + void generateBatches(); +}; + + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCLSIMDAware.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCLSIMDAware.h new file mode 100644 index 0000000..7a6e726 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverLinkData_OpenCLSIMDAware.h @@ -0,0 +1,169 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_OpenCL.h" + + +#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H +#define BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H + + +class btSoftBodyLinkDataOpenCLSIMDAware : public btSoftBodyLinkData +{ +public: + bool m_onGPU; + + cl_command_queue m_cqCommandQue; + + const int m_wavefrontSize; + const int m_linksPerWorkItem; + const int m_maxLinksPerWavefront; + int m_maxBatchesWithinWave; + int m_maxVerticesWithinWave; + int m_numWavefronts; + + int m_maxVertex; + + struct NumBatchesVerticesPair + { + int numBatches; + int numVertices; + }; + + btAlignedObjectArray m_linksPerWavefront; + btAlignedObjectArray m_numBatchesAndVerticesWithinWaves; + btOpenCLBuffer< NumBatchesVerticesPair > m_clNumBatchesAndVerticesWithinWaves; + + // All arrays here will contain batches of m_maxLinksPerWavefront links + // ordered by wavefront. + // with either global vertex pairs or local vertex pairs + btAlignedObjectArray< int > m_wavefrontVerticesGlobalAddresses; // List of global vertices per wavefront + btOpenCLBuffer m_clWavefrontVerticesGlobalAddresses; + btAlignedObjectArray< LinkNodePair > m_linkVerticesLocalAddresses; // Vertex pair for the link + btOpenCLBuffer m_clLinkVerticesLocalAddresses; + btOpenCLBuffer m_clLinkStrength; + btOpenCLBuffer m_clLinksMassLSC; + btOpenCLBuffer m_clLinksRestLengthSquared; + btOpenCLBuffer m_clLinksRestLength; + btOpenCLBuffer m_clLinksMaterialLinearStiffnessCoefficient; + + struct BatchPair + { + int start; + int length; + + BatchPair() : + start(0), + length(0) + { + } + + BatchPair( int s, int l ) : + start( s ), + length( l ) + { + } + }; + + /** + * Link addressing information for each cloth. + * Allows link locations to be computed independently of data batching. + */ + btAlignedObjectArray< int > m_linkAddresses; + + /** + * Start and length values for computation batches over link data. + */ + btAlignedObjectArray< BatchPair > m_wavefrontBatchStartLengths; + + btSoftBodyLinkDataOpenCLSIMDAware(cl_command_queue queue, cl_context ctx); + + virtual ~btSoftBodyLinkDataOpenCLSIMDAware(); + + /** Allocate enough space in all link-related arrays to fit numLinks links */ + virtual void createLinks( int numLinks ); + + /** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ + virtual void setLinkAt( + const LinkDescription &link, + int linkIndex ); + + virtual bool onAccelerator(); + + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(); + + /** + * Generate (and later update) the batching for the entire link set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ + void generateBatches(); + + int getMaxVerticesPerWavefront() + { + return m_maxVerticesWithinWave; + } + + int getWavefrontSize() + { + return m_wavefrontSize; + } + + int getLinksPerWorkItem() + { + return m_linksPerWorkItem; + } + + int getMaxLinksPerWavefront() + { + return m_maxLinksPerWavefront; + } + + int getMaxBatchesPerWavefront() + { + return m_maxBatchesWithinWave; + } + + int getNumWavefronts() + { + return m_numWavefronts; + } + + NumBatchesVerticesPair getNumBatchesAndVerticesWithinWavefront( int wavefront ) + { + return m_numBatchesAndVerticesWithinWaves[wavefront]; + } + + int getVertexGlobalAddresses( int vertexIndex ) + { + return m_wavefrontVerticesGlobalAddresses[vertexIndex]; + } + + /** + * Get post-batching local addresses of the vertex pair for a link assuming all vertices used by a wavefront are loaded locally. + */ + LinkNodePair getVertexPairLocalAddresses( int linkIndex ) + { + return m_linkVerticesLocalAddresses[linkIndex]; + } +}; + + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.cpp b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.cpp new file mode 100644 index 0000000..e18b575 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.cpp @@ -0,0 +1,126 @@ +#include "btSoftBodySolverOutputCLtoGL.h" +#include //@todo: remove the debugging printf at some stage +#include "btSoftBodySolver_OpenCL.h" +#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h" +#include "btSoftBodySolverVertexBuffer_OpenGL.h" +#include "BulletSoftBody/btSoftBody.h" + +////OpenCL 1.0 kernels don't use float3 +#define MSTRINGIFY(A) #A +static char* OutputToVertexArrayCLString = +#include "OpenCLC10/OutputToVertexArray.cl" + + +#define RELEASE_CL_KERNEL(kernelName) {if( kernelName ){ clReleaseKernel( kernelName ); kernelName = 0; }} + +static const size_t workGroupSize = 128; + +void btSoftBodySolverOutputCLtoGL::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ) +{ + + btSoftBodySolver *solver = softBody->getSoftBodySolver(); + btAssert( solver->getSolverType() == btSoftBodySolver::CL_SOLVER || solver->getSolverType() == btSoftBodySolver::CL_SIMD_SOLVER ); + btOpenCLSoftBodySolver *dxSolver = static_cast< btOpenCLSoftBodySolver * >( solver ); + checkInitialized(); + btOpenCLAcceleratedSoftBodyInterface* currentCloth = dxSolver->findSoftBodyInterface( softBody ); + btSoftBodyVertexDataOpenCL &vertexData( dxSolver->m_vertexData ); + + const int firstVertex = currentCloth->getFirstVertex(); + const int lastVertex = firstVertex + currentCloth->getNumVertices(); + + if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::OPENGL_BUFFER ) { + + const btOpenGLInteropVertexBufferDescriptor *openGLVertexBuffer = static_cast< btOpenGLInteropVertexBufferDescriptor* >(vertexBuffer); + cl_int ciErrNum = CL_SUCCESS; + + cl_mem clBuffer = openGLVertexBuffer->getBuffer(); + cl_kernel outputKernel = outputToVertexArrayWithNormalsKernel; + if( !vertexBuffer->hasNormals() ) + outputKernel = outputToVertexArrayWithoutNormalsKernel; + + ciErrNum = clEnqueueAcquireGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, NULL); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)"); + } + + int numVertices = currentCloth->getNumVertices(); + + ciErrNum = clSetKernelArg(outputKernel, 0, sizeof(int), &firstVertex ); + ciErrNum = clSetKernelArg(outputKernel, 1, sizeof(int), &numVertices ); + ciErrNum = clSetKernelArg(outputKernel, 2, sizeof(cl_mem), (void*)&clBuffer ); + if( vertexBuffer->hasVertexPositions() ) + { + int vertexOffset = vertexBuffer->getVertexOffset(); + int vertexStride = vertexBuffer->getVertexStride(); + ciErrNum = clSetKernelArg(outputKernel, 3, sizeof(int), &vertexOffset ); + ciErrNum = clSetKernelArg(outputKernel, 4, sizeof(int), &vertexStride ); + ciErrNum = clSetKernelArg(outputKernel, 5, sizeof(cl_mem), (void*)&vertexData.m_clVertexPosition.m_buffer ); + + } + if( vertexBuffer->hasNormals() ) + { + int normalOffset = vertexBuffer->getNormalOffset(); + int normalStride = vertexBuffer->getNormalStride(); + ciErrNum = clSetKernelArg(outputKernel, 6, sizeof(int), &normalOffset ); + ciErrNum = clSetKernelArg(outputKernel, 7, sizeof(int), &normalStride ); + ciErrNum = clSetKernelArg(outputKernel, 8, sizeof(cl_mem), (void*)&vertexData.m_clVertexNormal.m_buffer ); + + } + size_t numWorkItems = workGroupSize*((vertexData.getNumVertices() + (workGroupSize-1)) / workGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, outputKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(copySoftBodyToVertexBuffer)"); + } + + ciErrNum = clEnqueueReleaseGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, 0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "clEnqueueReleaseGLObjects(copySoftBodyToVertexBuffer)"); + } + } else { + btAssert( "Undefined output for this solver output" == false ); + } + + // clFinish in here may not be the best thing. It's possible that we should have a waitForFrameComplete function. + clFinish(m_cqCommandQue); + +} // btSoftBodySolverOutputCLtoGL::outputToVertexBuffers + +bool btSoftBodySolverOutputCLtoGL::buildShaders() +{ + // Ensure current kernels are released first + releaseKernels(); + + bool returnVal = true; + + if( m_shadersInitialized ) + return true; + + outputToVertexArrayWithNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl"); + outputToVertexArrayWithoutNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithoutNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl"); + + + if( returnVal ) + m_shadersInitialized = true; + + return returnVal; +} // btSoftBodySolverOutputCLtoGL::buildShaders + +void btSoftBodySolverOutputCLtoGL::releaseKernels() +{ + RELEASE_CL_KERNEL( outputToVertexArrayWithNormalsKernel ); + RELEASE_CL_KERNEL( outputToVertexArrayWithoutNormalsKernel ); + + m_shadersInitialized = false; +} // btSoftBodySolverOutputCLtoGL::releaseKernels + +bool btSoftBodySolverOutputCLtoGL::checkInitialized() +{ + if( !m_shadersInitialized ) + if( buildShaders() ) + m_shadersInitialized = true; + + return m_shadersInitialized; +} \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.h new file mode 100644 index 0000000..45279b0 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverOutputCLtoGL.h @@ -0,0 +1,62 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H +#define BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H + +#include "btSoftBodySolver_OpenCL.h" + +/** + * Class to manage movement of data from a solver to a given target. + * This version is the CL to GL interop version. + */ +class btSoftBodySolverOutputCLtoGL : public btSoftBodySolverOutput +{ +protected: + cl_command_queue m_cqCommandQue; + cl_context m_cxMainContext; + CLFunctions clFunctions; + + cl_kernel outputToVertexArrayWithNormalsKernel; + cl_kernel outputToVertexArrayWithoutNormalsKernel; + + bool m_shadersInitialized; + + virtual bool checkInitialized(); + virtual bool buildShaders(); + void releaseKernels(); +public: + btSoftBodySolverOutputCLtoGL(cl_command_queue cqCommandQue, cl_context cxMainContext) : + m_cqCommandQue( cqCommandQue ), + m_cxMainContext( cxMainContext ), + clFunctions(cqCommandQue, cxMainContext), + outputToVertexArrayWithNormalsKernel( 0 ), + outputToVertexArrayWithoutNormalsKernel( 0 ), + m_shadersInitialized( false ) + { + } + + virtual ~btSoftBodySolverOutputCLtoGL() + { + releaseKernels(); + } + + /** Output current computed vertex data to the vertex buffers for all cloths in the solver. */ + virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ); +}; + + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H \ No newline at end of file diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverTriangleData_OpenCL.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverTriangleData_OpenCL.h new file mode 100644 index 0000000..9cafe83 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverTriangleData_OpenCL.h @@ -0,0 +1,84 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_OpenCL.h" + + +#ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H +#define BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H + + +class btSoftBodyTriangleDataOpenCL : public btSoftBodyTriangleData +{ +public: + bool m_onGPU; + cl_command_queue m_queue; + + btOpenCLBuffer m_clVertexIndices; + btOpenCLBuffer m_clArea; + btOpenCLBuffer m_clNormal; + + /** + * Link addressing information for each cloth. + * Allows link locations to be computed independently of data batching. + */ + btAlignedObjectArray< int > m_triangleAddresses; + + /** + * Start and length values for computation batches over link data. + */ + struct btSomePair + { + btSomePair() {} + btSomePair(int f,int s) + :first(f),second(s) + { + } + int first; + int second; + }; + btAlignedObjectArray< btSomePair > m_batchStartLengths; + +public: + btSoftBodyTriangleDataOpenCL( cl_command_queue queue, cl_context ctx ); + + virtual ~btSoftBodyTriangleDataOpenCL(); + + /** Allocate enough space in all link-related arrays to fit numLinks links */ + virtual void createTriangles( int numTriangles ); + + /** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ + virtual void setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex ); + + virtual bool onAccelerator(); + + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(); + + /** + * Generate (and later update) the batching for the entire triangle set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ + void generateBatches(); +}; // class btSoftBodyTriangleDataOpenCL + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h new file mode 100644 index 0000000..3a30b0e --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h @@ -0,0 +1,166 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H +#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H + + +#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h" +#ifdef USE_MINICL + #include "MiniCL/cl.h" +#else //USE_MINICL + #ifdef __APPLE__ + #include + #else + #include + #include + #endif //__APPLE__ +#endif//USE_MINICL + + +#ifdef _WIN32//for glut.h +#include +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#include +#else + + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#endif //_WINDOWS +#endif //APPLE + + + +class btOpenGLInteropVertexBufferDescriptor : public btVertexBufferDescriptor +{ +protected: + /** OpenCL context */ + cl_context m_context; + + /** OpenCL command queue */ + cl_command_queue m_commandQueue; + + /** OpenCL interop buffer */ + cl_mem m_buffer; + + /** VBO in GL that is the basis of the interop buffer */ + GLuint m_openGLVBO; + + +public: + /** + * context is the OpenCL context this interop buffer will work in. + * queue is the command queue that kernels and data movement will be enqueued into. + * openGLVBO is the OpenGL vertex buffer data will be copied into. + * vertexOffset is the offset in floats to the first vertex. + * vertexStride is the stride in floats between vertices. + */ + btOpenGLInteropVertexBufferDescriptor( cl_command_queue cqCommandQue, cl_context context, GLuint openGLVBO, int vertexOffset, int vertexStride ) + { +#ifndef USE_MINICL + cl_int ciErrNum = CL_SUCCESS; + m_context = context; + m_commandQueue = cqCommandQue; + + m_vertexOffset = vertexOffset; + m_vertexStride = vertexStride; + + m_openGLVBO = openGLVBO; + + m_buffer = clCreateFromGLBuffer(m_context, CL_MEM_WRITE_ONLY, openGLVBO, &ciErrNum); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)"); + } + + m_hasVertexPositions = true; +#else + btAssert(0);//MiniCL shouldn't get here +#endif + } + + /** + * context is the OpenCL context this interop buffer will work in. + * queue is the command queue that kernels and data movement will be enqueued into. + * openGLVBO is the OpenGL vertex buffer data will be copied into. + * vertexOffset is the offset in floats to the first vertex. + * vertexStride is the stride in floats between vertices. + * normalOffset is the offset in floats to the first normal. + * normalStride is the stride in floats between normals. + */ + btOpenGLInteropVertexBufferDescriptor( cl_command_queue cqCommandQue, cl_context context, GLuint openGLVBO, int vertexOffset, int vertexStride, int normalOffset, int normalStride ) + { +#ifndef USE_MINICL + cl_int ciErrNum = CL_SUCCESS; + m_context = context; + m_commandQueue = cqCommandQue; + + m_openGLVBO = openGLVBO; + + m_buffer = clCreateFromGLBuffer(m_context, CL_MEM_WRITE_ONLY, openGLVBO, &ciErrNum); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)"); + } + + m_vertexOffset = vertexOffset; + m_vertexStride = vertexStride; + m_hasVertexPositions = true; + + m_normalOffset = normalOffset; + m_normalStride = normalStride; + m_hasNormals = true; +#else + btAssert(0); +#endif //USE_MINICL + + } + + virtual ~btOpenGLInteropVertexBufferDescriptor() + { + clReleaseMemObject( m_buffer ); + } + + /** + * Return the type of the vertex buffer descriptor. + */ + virtual BufferTypes getBufferType() const + { + return OPENGL_BUFFER; + } + + virtual cl_context getContext() const + { + return m_context; + } + + virtual cl_mem getBuffer() const + { + return m_buffer; + } +}; + +#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexData_OpenCL.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexData_OpenCL.h new file mode 100644 index 0000000..3420c3f --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexData_OpenCL.h @@ -0,0 +1,52 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h" +#include "btSoftBodySolverBuffer_OpenCL.h" + +#ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H +#define BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H + + +class btSoftBodyVertexDataOpenCL : public btSoftBodyVertexData +{ +protected: + bool m_onGPU; + cl_command_queue m_queue; + +public: + btOpenCLBuffer m_clClothIdentifier; + btOpenCLBuffer m_clVertexPosition; + btOpenCLBuffer m_clVertexPreviousPosition; + btOpenCLBuffer m_clVertexVelocity; + btOpenCLBuffer m_clVertexForceAccumulator; + btOpenCLBuffer m_clVertexNormal; + btOpenCLBuffer m_clVertexInverseMass; + btOpenCLBuffer m_clVertexArea; + btOpenCLBuffer m_clVertexTriangleCount; +public: + btSoftBodyVertexDataOpenCL( cl_command_queue queue, cl_context ctx); + + virtual ~btSoftBodyVertexDataOpenCL(); + + virtual bool onAccelerator(); + + virtual bool moveToAccelerator(); + + virtual bool moveFromAccelerator(bool bCopy = false, bool bCopyMinimum = true); +}; + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.cpp b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.cpp new file mode 100644 index 0000000..31a6f77 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.cpp @@ -0,0 +1,1820 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "vectormath/vmInclude.h" +#include //@todo: remove the debugging printf at some stage +#include "btSoftBodySolver_OpenCL.h" +#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletSoftBody/btSoftBodyInternals.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "LinearMath/btQuickprof.h" +#include +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +#define BT_SUPPRESS_OPENCL_ASSERTS + +#ifdef USE_MINICL + #include "MiniCL/cl.h" +#else //USE_MINICL + #ifdef __APPLE__ + #include + #else + #include + #endif //__APPLE__ +#endif//USE_MINICL + +#define BT_DEFAULT_WORKGROUPSIZE 64 + + +#define RELEASE_CL_KERNEL(kernelName) {if( kernelName ){ clReleaseKernel( kernelName ); kernelName = 0; }} + + +//CL_VERSION_1_1 seems broken on NVidia SDK so just disable it + +////OpenCL 1.0 kernels don't use float3 +#define MSTRINGIFY(A) #A +static const char* PrepareLinksCLString = +#include "OpenCLC10/PrepareLinks.cl" +static const char* UpdatePositionsFromVelocitiesCLString = +#include "OpenCLC10/UpdatePositionsFromVelocities.cl" +static const char* SolvePositionsCLString = +#include "OpenCLC10/SolvePositions.cl" +static const char* UpdateNodesCLString = +#include "OpenCLC10/UpdateNodes.cl" +static const char* UpdatePositionsCLString = +#include "OpenCLC10/UpdatePositions.cl" +static const char* UpdateConstantsCLString = +#include "OpenCLC10/UpdateConstants.cl" +static const char* IntegrateCLString = +#include "OpenCLC10/Integrate.cl" +static const char* ApplyForcesCLString = +#include "OpenCLC10/ApplyForces.cl" +static const char* UpdateFixedVertexPositionsCLString = +#include "OpenCLC10/UpdateFixedVertexPositions.cl" +static const char* UpdateNormalsCLString = +#include "OpenCLC10/UpdateNormals.cl" +static const char* VSolveLinksCLString = +#include "OpenCLC10/VSolveLinks.cl" +static const char* SolveCollisionsAndUpdateVelocitiesCLString = +#include "OpenCLC10/SolveCollisionsAndUpdateVelocities.cl" + + +btSoftBodyVertexDataOpenCL::btSoftBodyVertexDataOpenCL( cl_command_queue queue, cl_context ctx) : + m_queue(queue), + m_clClothIdentifier( queue, ctx, &m_clothIdentifier, false ), + m_clVertexPosition( queue, ctx, &m_vertexPosition, false ), + m_clVertexPreviousPosition( queue, ctx, &m_vertexPreviousPosition, false ), + m_clVertexVelocity( queue, ctx, &m_vertexVelocity, false ), + m_clVertexForceAccumulator( queue, ctx, &m_vertexForceAccumulator, false ), + m_clVertexNormal( queue, ctx, &m_vertexNormal, false ), + m_clVertexInverseMass( queue, ctx, &m_vertexInverseMass, false ), + m_clVertexArea( queue, ctx, &m_vertexArea, false ), + m_clVertexTriangleCount( queue, ctx, &m_vertexTriangleCount, false ) +{ +} + +btSoftBodyVertexDataOpenCL::~btSoftBodyVertexDataOpenCL() +{ + +} + +bool btSoftBodyVertexDataOpenCL::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyVertexDataOpenCL::moveToAccelerator() +{ + bool success = true; + success = success && m_clClothIdentifier.moveToGPU(); + success = success && m_clVertexPosition.moveToGPU(); + success = success && m_clVertexPreviousPosition.moveToGPU(); + success = success && m_clVertexVelocity.moveToGPU(); + success = success && m_clVertexForceAccumulator.moveToGPU(); + success = success && m_clVertexNormal.moveToGPU(); + success = success && m_clVertexInverseMass.moveToGPU(); + success = success && m_clVertexArea.moveToGPU(); + success = success && m_clVertexTriangleCount.moveToGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +bool btSoftBodyVertexDataOpenCL::moveFromAccelerator(bool bCopy, bool bCopyMinimum) +{ + bool success = true; + + if (!bCopy) + { + success = success && m_clClothIdentifier.moveFromGPU(); + success = success && m_clVertexPosition.moveFromGPU(); + success = success && m_clVertexPreviousPosition.moveFromGPU(); + success = success && m_clVertexVelocity.moveFromGPU(); + success = success && m_clVertexForceAccumulator.moveFromGPU(); + success = success && m_clVertexNormal.moveFromGPU(); + success = success && m_clVertexInverseMass.moveFromGPU(); + success = success && m_clVertexArea.moveFromGPU(); + success = success && m_clVertexTriangleCount.moveFromGPU(); + } + else + { + if (bCopyMinimum) + { + success = success && m_clVertexPosition.copyFromGPU(); + success = success && m_clVertexNormal.copyFromGPU(); + } + else + { + success = success && m_clClothIdentifier.copyFromGPU(); + success = success && m_clVertexPosition.copyFromGPU(); + success = success && m_clVertexPreviousPosition.copyFromGPU(); + success = success && m_clVertexVelocity.copyFromGPU(); + success = success && m_clVertexForceAccumulator.copyFromGPU(); + success = success && m_clVertexNormal.copyFromGPU(); + success = success && m_clVertexInverseMass.copyFromGPU(); + success = success && m_clVertexArea.copyFromGPU(); + success = success && m_clVertexTriangleCount.copyFromGPU(); + } + } + + if( success ) + m_onGPU = true; + + return success; +} + +btSoftBodyLinkDataOpenCL::btSoftBodyLinkDataOpenCL(cl_command_queue queue, cl_context ctx) +:m_cqCommandQue(queue), + m_clLinks( queue, ctx, &m_links, false ), + m_clLinkStrength( queue, ctx, &m_linkStrength, false ), + m_clLinksMassLSC( queue, ctx, &m_linksMassLSC, false ), + m_clLinksRestLengthSquared( queue, ctx, &m_linksRestLengthSquared, false ), + m_clLinksCLength( queue, ctx, &m_linksCLength, false ), + m_clLinksLengthRatio( queue, ctx, &m_linksLengthRatio, false ), + m_clLinksRestLength( queue, ctx, &m_linksRestLength, false ), + m_clLinksMaterialLinearStiffnessCoefficient( queue, ctx, &m_linksMaterialLinearStiffnessCoefficient, false ) +{ +} + +btSoftBodyLinkDataOpenCL::~btSoftBodyLinkDataOpenCL() +{ +} + +static Vectormath::Aos::Vector3 toVector3( const btVector3 &vec ) +{ + Vectormath::Aos::Vector3 outVec( vec.getX(), vec.getY(), vec.getZ() ); + return outVec; +} + +/** Allocate enough space in all link-related arrays to fit numLinks links */ +void btSoftBodyLinkDataOpenCL::createLinks( int numLinks ) +{ + int previousSize = m_links.size(); + int newSize = previousSize + numLinks; + + btSoftBodyLinkData::createLinks( numLinks ); + + // Resize the link addresses array as well + m_linkAddresses.resize( newSize ); +} + +/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ +void btSoftBodyLinkDataOpenCL::setLinkAt( + const LinkDescription &link, + int linkIndex ) +{ + btSoftBodyLinkData::setLinkAt( link, linkIndex ); + + // Set the link index correctly for initialisation + m_linkAddresses[linkIndex] = linkIndex; +} + +bool btSoftBodyLinkDataOpenCL::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyLinkDataOpenCL::moveToAccelerator() +{ + bool success = true; + success = success && m_clLinks.moveToGPU(); + success = success && m_clLinkStrength.moveToGPU(); + success = success && m_clLinksMassLSC.moveToGPU(); + success = success && m_clLinksRestLengthSquared.moveToGPU(); + success = success && m_clLinksCLength.moveToGPU(); + success = success && m_clLinksLengthRatio.moveToGPU(); + success = success && m_clLinksRestLength.moveToGPU(); + success = success && m_clLinksMaterialLinearStiffnessCoefficient.moveToGPU(); + + if( success ) { + m_onGPU = true; + } + + return success; +} + +bool btSoftBodyLinkDataOpenCL::moveFromAccelerator() +{ + bool success = true; + success = success && m_clLinks.moveFromGPU(); + success = success && m_clLinkStrength.moveFromGPU(); + success = success && m_clLinksMassLSC.moveFromGPU(); + success = success && m_clLinksRestLengthSquared.moveFromGPU(); + success = success && m_clLinksCLength.moveFromGPU(); + success = success && m_clLinksLengthRatio.moveFromGPU(); + success = success && m_clLinksRestLength.moveFromGPU(); + success = success && m_clLinksMaterialLinearStiffnessCoefficient.moveFromGPU(); + + if( success ) { + m_onGPU = false; + } + + return success; +} + +/** + * Generate (and later update) the batching for the entire link set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ +void btSoftBodyLinkDataOpenCL::generateBatches() +{ + int numLinks = getNumLinks(); + + // Do the graph colouring here temporarily + btAlignedObjectArray< int > batchValues; + batchValues.resize( numLinks, 0 ); + + // Find the maximum vertex value internally for now + int maxVertex = 0; + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + int vertex0 = getVertexPair(linkIndex).vertex0; + int vertex1 = getVertexPair(linkIndex).vertex1; + if( vertex0 > maxVertex ) + maxVertex = vertex0; + if( vertex1 > maxVertex ) + maxVertex = vertex1; + } + int numVertices = maxVertex + 1; + + // Set of lists, one for each node, specifying which colours are connected + // to that node. + // No two edges into a node can share a colour. + btAlignedObjectArray< btAlignedObjectArray< int > > vertexConnectedColourLists; + vertexConnectedColourLists.resize(numVertices); + + // Simple algorithm that chooses the lowest batch number + // that none of the links attached to either of the connected + // nodes is in + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + int linkLocation = m_linkAddresses[linkIndex]; + + int vertex0 = getVertexPair(linkLocation).vertex0; + int vertex1 = getVertexPair(linkLocation).vertex1; + + // Get the two node colour lists + btAlignedObjectArray< int > &colourListVertex0( vertexConnectedColourLists[vertex0] ); + btAlignedObjectArray< int > &colourListVertex1( vertexConnectedColourLists[vertex1] ); + + // Choose the minimum colour that is in neither list + int colour = 0; + while( colourListVertex0.findLinearSearch(colour) != colourListVertex0.size() || colourListVertex1.findLinearSearch(colour) != colourListVertex1.size() ) + ++colour; + // i should now be the minimum colour in neither list + // Add to the two lists so that future edges don't share + // And store the colour against this edge + + colourListVertex0.push_back(colour); + colourListVertex1.push_back(colour); + batchValues[linkIndex] = colour; + } + + // Check the colour counts + btAlignedObjectArray< int > batchCounts; + for( int i = 0; i < numLinks; ++i ) + { + int batch = batchValues[i]; + if( batch >= batchCounts.size() ) + batchCounts.push_back(1); + else + ++(batchCounts[batch]); + } + + m_batchStartLengths.resize(batchCounts.size()); + if( m_batchStartLengths.size() > 0 ) + { + m_batchStartLengths.resize(batchCounts.size()); + m_batchStartLengths[0] = BatchPair(0, 0); + + int sum = 0; + for( int batchIndex = 0; batchIndex < batchCounts.size(); ++batchIndex ) + { + m_batchStartLengths[batchIndex].start = sum; + m_batchStartLengths[batchIndex].length = batchCounts[batchIndex]; + sum += batchCounts[batchIndex]; + } + } + + ///////////////////////////// + // Sort data based on batches + + // Create source arrays by copying originals + btAlignedObjectArray m_links_Backup(m_links); + btAlignedObjectArray m_linkStrength_Backup(m_linkStrength); + btAlignedObjectArray m_linksMassLSC_Backup(m_linksMassLSC); + btAlignedObjectArray m_linksRestLengthSquared_Backup(m_linksRestLengthSquared); + btAlignedObjectArray m_linksCLength_Backup(m_linksCLength); + btAlignedObjectArray m_linksLengthRatio_Backup(m_linksLengthRatio); + btAlignedObjectArray m_linksRestLength_Backup(m_linksRestLength); + btAlignedObjectArray m_linksMaterialLinearStiffnessCoefficient_Backup(m_linksMaterialLinearStiffnessCoefficient); + + + for( int batch = 0; batch < batchCounts.size(); ++batch ) + batchCounts[batch] = 0; + + // Do sort as single pass into destination arrays + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + // To maintain locations run off the original link locations rather than the current position. + // It's not cache efficient, but as we run this rarely that should not matter. + // It's faster than searching the link location array for the current location and then updating it. + // The other alternative would be to unsort before resorting, but this is equivalent to doing that. + int linkLocation = m_linkAddresses[linkIndex]; + + // Obtain batch and calculate target location for the + // next element in that batch, incrementing the batch counter + // afterwards + int batch = batchValues[linkIndex]; + int newLocation = m_batchStartLengths[batch].start + batchCounts[batch]; + + batchCounts[batch] = batchCounts[batch] + 1; + m_links[newLocation] = m_links_Backup[linkLocation]; +#if 1 + m_linkStrength[newLocation] = m_linkStrength_Backup[linkLocation]; + m_linksMassLSC[newLocation] = m_linksMassLSC_Backup[linkLocation]; + m_linksRestLengthSquared[newLocation] = m_linksRestLengthSquared_Backup[linkLocation]; + m_linksLengthRatio[newLocation] = m_linksLengthRatio_Backup[linkLocation]; + m_linksRestLength[newLocation] = m_linksRestLength_Backup[linkLocation]; + m_linksMaterialLinearStiffnessCoefficient[newLocation] = m_linksMaterialLinearStiffnessCoefficient_Backup[linkLocation]; +#endif + // Update the locations array to account for the moved entry + m_linkAddresses[linkIndex] = newLocation; + } + + +} // void generateBatches() + + + + + +btSoftBodyTriangleDataOpenCL::btSoftBodyTriangleDataOpenCL( cl_command_queue queue , cl_context ctx) : + m_queue( queue ), + m_clVertexIndices( queue, ctx, &m_vertexIndices, false ), + m_clArea( queue, ctx, &m_area, false ), + m_clNormal( queue, ctx, &m_normal, false ) +{ +} + +btSoftBodyTriangleDataOpenCL::~btSoftBodyTriangleDataOpenCL() +{ +} + +/** Allocate enough space in all link-related arrays to fit numLinks links */ +void btSoftBodyTriangleDataOpenCL::createTriangles( int numTriangles ) +{ + int previousSize = getNumTriangles(); + int newSize = previousSize + numTriangles; + + btSoftBodyTriangleData::createTriangles( numTriangles ); + + // Resize the link addresses array as well + m_triangleAddresses.resize( newSize ); +} + +/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ +void btSoftBodyTriangleDataOpenCL::setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex ) +{ + btSoftBodyTriangleData::setTriangleAt( triangle, triangleIndex ); + + m_triangleAddresses[triangleIndex] = triangleIndex; +} + +bool btSoftBodyTriangleDataOpenCL::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyTriangleDataOpenCL::moveToAccelerator() +{ + bool success = true; + success = success && m_clVertexIndices.moveToGPU(); + success = success && m_clArea.moveToGPU(); + success = success && m_clNormal.moveToGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +bool btSoftBodyTriangleDataOpenCL::moveFromAccelerator() +{ + bool success = true; + success = success && m_clVertexIndices.moveFromGPU(); + success = success && m_clArea.moveFromGPU(); + success = success && m_clNormal.moveFromGPU(); + + if( success ) + m_onGPU = true; + + return success; +} + +/** + * Generate (and later update) the batching for the entire triangle set. + * This redoes a lot of work because it batches the entire set when each cloth is inserted. + * In theory we could delay it until just before we need the cloth. + * It's a one-off overhead, though, so that is a later optimisation. + */ +void btSoftBodyTriangleDataOpenCL::generateBatches() +{ + int numTriangles = getNumTriangles(); + if( numTriangles == 0 ) + return; + + // Do the graph colouring here temporarily + btAlignedObjectArray< int > batchValues; + batchValues.resize( numTriangles ); + + // Find the maximum vertex value internally for now + int maxVertex = 0; + for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex ) + { + int vertex0 = getVertexSet(triangleIndex).vertex0; + int vertex1 = getVertexSet(triangleIndex).vertex1; + int vertex2 = getVertexSet(triangleIndex).vertex2; + + if( vertex0 > maxVertex ) + maxVertex = vertex0; + if( vertex1 > maxVertex ) + maxVertex = vertex1; + if( vertex2 > maxVertex ) + maxVertex = vertex2; + } + int numVertices = maxVertex + 1; + + // Set of lists, one for each node, specifying which colours are connected + // to that node. + // No two edges into a node can share a colour. + btAlignedObjectArray< btAlignedObjectArray< int > > vertexConnectedColourLists; + vertexConnectedColourLists.resize(numVertices); + + + //std::cout << "\n"; + // Simple algorithm that chooses the lowest batch number + // that none of the faces attached to either of the connected + // nodes is in + for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex ) + { + // To maintain locations run off the original link locations rather than the current position. + // It's not cache efficient, but as we run this rarely that should not matter. + // It's faster than searching the link location array for the current location and then updating it. + // The other alternative would be to unsort before resorting, but this is equivalent to doing that. + int triangleLocation = m_triangleAddresses[triangleIndex]; + + int vertex0 = getVertexSet(triangleLocation).vertex0; + int vertex1 = getVertexSet(triangleLocation).vertex1; + int vertex2 = getVertexSet(triangleLocation).vertex2; + + // Get the three node colour lists + btAlignedObjectArray< int > &colourListVertex0( vertexConnectedColourLists[vertex0] ); + btAlignedObjectArray< int > &colourListVertex1( vertexConnectedColourLists[vertex1] ); + btAlignedObjectArray< int > &colourListVertex2( vertexConnectedColourLists[vertex2] ); + + // Choose the minimum colour that is in none of the lists + int colour = 0; + while( + colourListVertex0.findLinearSearch(colour) != colourListVertex0.size() || + colourListVertex1.findLinearSearch(colour) != colourListVertex1.size() || + colourListVertex2.findLinearSearch(colour) != colourListVertex2.size() ) + { + ++colour; + } + // i should now be the minimum colour in neither list + // Add to the three lists so that future edges don't share + // And store the colour against this face + colourListVertex0.push_back(colour); + colourListVertex1.push_back(colour); + colourListVertex2.push_back(colour); + + batchValues[triangleIndex] = colour; + } + + + // Check the colour counts + btAlignedObjectArray< int > batchCounts; + for( int i = 0; i < numTriangles; ++i ) + { + int batch = batchValues[i]; + if( batch >= batchCounts.size() ) + batchCounts.push_back(1); + else + ++(batchCounts[batch]); + } + + + m_batchStartLengths.resize(batchCounts.size()); + m_batchStartLengths[0] = btSomePair(0,0); + + + int sum = 0; + for( int batchIndex = 0; batchIndex < batchCounts.size(); ++batchIndex ) + { + m_batchStartLengths[batchIndex].first = sum; + m_batchStartLengths[batchIndex].second = batchCounts[batchIndex]; + sum += batchCounts[batchIndex]; + } + + ///////////////////////////// + // Sort data based on batches + + // Create source arrays by copying originals + btAlignedObjectArray m_vertexIndices_Backup(m_vertexIndices); + btAlignedObjectArray m_area_Backup(m_area); + btAlignedObjectArray m_normal_Backup(m_normal); + + + for( int batch = 0; batch < batchCounts.size(); ++batch ) + batchCounts[batch] = 0; + + // Do sort as single pass into destination arrays + for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex ) + { + // To maintain locations run off the original link locations rather than the current position. + // It's not cache efficient, but as we run this rarely that should not matter. + // It's faster than searching the link location array for the current location and then updating it. + // The other alternative would be to unsort before resorting, but this is equivalent to doing that. + int triangleLocation = m_triangleAddresses[triangleIndex]; + + // Obtain batch and calculate target location for the + // next element in that batch, incrementing the batch counter + // afterwards + int batch = batchValues[triangleIndex]; + int newLocation = m_batchStartLengths[batch].first + batchCounts[batch]; + + batchCounts[batch] = batchCounts[batch] + 1; + m_vertexIndices[newLocation] = m_vertexIndices_Backup[triangleLocation]; + m_area[newLocation] = m_area_Backup[triangleLocation]; + m_normal[newLocation] = m_normal_Backup[triangleLocation]; + + // Update the locations array to account for the moved entry + m_triangleAddresses[triangleIndex] = newLocation; + } +} // btSoftBodyTriangleDataOpenCL::generateBatches + + + + + + + +btOpenCLSoftBodySolver::btOpenCLSoftBodySolver(cl_command_queue queue, cl_context ctx, bool bUpdateAchchoredNodePos) : + m_linkData(queue, ctx), + m_vertexData(queue, ctx), + m_triangleData(queue, ctx), + m_defaultCLFunctions(queue, ctx), + m_currentCLFunctions(&m_defaultCLFunctions), + m_clPerClothAcceleration(queue, ctx, &m_perClothAcceleration, true ), + m_clPerClothWindVelocity(queue, ctx, &m_perClothWindVelocity, true ), + m_clPerClothDampingFactor(queue,ctx, &m_perClothDampingFactor, true ), + m_clPerClothVelocityCorrectionCoefficient(queue, ctx,&m_perClothVelocityCorrectionCoefficient, true ), + m_clPerClothLiftFactor(queue, ctx,&m_perClothLiftFactor, true ), + m_clPerClothDragFactor(queue, ctx,&m_perClothDragFactor, true ), + m_clPerClothMediumDensity(queue, ctx,&m_perClothMediumDensity, true ), + m_clPerClothCollisionObjects( queue, ctx, &m_perClothCollisionObjects, true ), + m_clCollisionObjectDetails( queue, ctx, &m_collisionObjectDetails, true ), + m_clPerClothFriction( queue, ctx, &m_perClothFriction, false ), + m_clAnchorPosition( queue, ctx, &m_anchorPosition, true ), + m_clAnchorIndex( queue, ctx, &m_anchorIndex, true), + m_cqCommandQue( queue ), + m_cxMainContext(ctx), + m_defaultWorkGroupSize(BT_DEFAULT_WORKGROUPSIZE), + m_bUpdateAnchoredNodePos(bUpdateAchchoredNodePos) +{ + + // Initial we will clearly need to update solver constants + // For now this is global for the cloths linked with this solver - we should probably make this body specific + // for performance in future once we understand more clearly when constants need to be updated + m_updateSolverConstants = true; + + m_shadersInitialized = false; + + m_prepareLinksKernel = 0; + m_solvePositionsFromLinksKernel = 0; + m_updateConstantsKernel = 0; + m_integrateKernel = 0; + m_addVelocityKernel = 0; + m_updatePositionsFromVelocitiesKernel = 0; + m_updateVelocitiesFromPositionsWithoutVelocitiesKernel = 0; + m_updateVelocitiesFromPositionsWithVelocitiesKernel = 0; + m_vSolveLinksKernel = 0; + m_solveCollisionsAndUpdateVelocitiesKernel = 0; + m_resetNormalsAndAreasKernel = 0; + m_updateSoftBodiesKernel = 0; + m_normalizeNormalsAndAreasKernel = 0; + m_outputToVertexArrayKernel = 0; + m_applyForcesKernel = 0; + m_updateFixedVertexPositionsKernel = 0; +} + +btOpenCLSoftBodySolver::~btOpenCLSoftBodySolver() +{ + releaseKernels(); +} + +void btOpenCLSoftBodySolver::releaseKernels() +{ + RELEASE_CL_KERNEL( m_prepareLinksKernel ); + RELEASE_CL_KERNEL( m_solvePositionsFromLinksKernel ); + RELEASE_CL_KERNEL( m_updateConstantsKernel ); + RELEASE_CL_KERNEL( m_integrateKernel ); + RELEASE_CL_KERNEL( m_addVelocityKernel ); + RELEASE_CL_KERNEL( m_updatePositionsFromVelocitiesKernel ); + RELEASE_CL_KERNEL( m_updateVelocitiesFromPositionsWithoutVelocitiesKernel ); + RELEASE_CL_KERNEL( m_updateVelocitiesFromPositionsWithVelocitiesKernel ); + RELEASE_CL_KERNEL( m_vSolveLinksKernel ); + RELEASE_CL_KERNEL( m_solveCollisionsAndUpdateVelocitiesKernel ); + RELEASE_CL_KERNEL( m_resetNormalsAndAreasKernel ); + RELEASE_CL_KERNEL( m_normalizeNormalsAndAreasKernel ); + RELEASE_CL_KERNEL( m_outputToVertexArrayKernel ); + RELEASE_CL_KERNEL( m_applyForcesKernel ); + RELEASE_CL_KERNEL( m_updateFixedVertexPositionsKernel ); + + m_shadersInitialized = false; +} + +void btOpenCLSoftBodySolver::copyBackToSoftBodies(bool bMove) +{ + + // Move the vertex data back to the host first + m_vertexData.moveFromAccelerator(!bMove); + + // Loop over soft bodies, copying all the vertex positions back for each body in turn + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btOpenCLAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[ softBodyIndex ]; + btSoftBody *softBody = softBodyInterface->getSoftBody(); + + int firstVertex = softBodyInterface->getFirstVertex(); + int numVertices = softBodyInterface->getNumVertices(); + + // Copy vertices from solver back into the softbody + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + using Vectormath::Aos::Point3; + Point3 vertexPosition( m_vertexData.getVertexPositions()[firstVertex + vertex] ); + Point3 normal(m_vertexData.getNormal(firstVertex + vertex)); + + softBody->m_nodes[vertex].m_x.setX( vertexPosition.getX() ); + softBody->m_nodes[vertex].m_x.setY( vertexPosition.getY() ); + softBody->m_nodes[vertex].m_x.setZ( vertexPosition.getZ() ); + + softBody->m_nodes[vertex].m_n.setX( normal.getX() ); + softBody->m_nodes[vertex].m_n.setY( normal.getY() ); + softBody->m_nodes[vertex].m_n.setZ( normal.getZ() ); + } + } +} // btOpenCLSoftBodySolver::copyBackToSoftBodies + +void btOpenCLSoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies, bool forceUpdate ) +{ + if( forceUpdate || m_softBodySet.size() != softBodies.size() ) + { + // Have a change in the soft body set so update, reloading all the data + getVertexData().clear(); + getTriangleData().clear(); + getLinkData().clear(); + m_softBodySet.resize(0); + m_anchorIndex.clear(); + + int maxPiterations = 0; + int maxViterations = 0; + + for( int softBodyIndex = 0; softBodyIndex < softBodies.size(); ++softBodyIndex ) + { + btSoftBody *softBody = softBodies[ softBodyIndex ]; + using Vectormath::Aos::Matrix3; + using Vectormath::Aos::Point3; + + // Create SoftBody that will store the information within the solver + btOpenCLAcceleratedSoftBodyInterface *newSoftBody = new btOpenCLAcceleratedSoftBodyInterface( softBody ); + m_softBodySet.push_back( newSoftBody ); + + m_perClothAcceleration.push_back( toVector3(softBody->getWorldInfo()->m_gravity) ); + m_perClothDampingFactor.push_back(softBody->m_cfg.kDP); + m_perClothVelocityCorrectionCoefficient.push_back( softBody->m_cfg.kVCF ); + m_perClothLiftFactor.push_back( softBody->m_cfg.kLF ); + m_perClothDragFactor.push_back( softBody->m_cfg.kDG ); + m_perClothMediumDensity.push_back(softBody->getWorldInfo()->air_density); + // Simple init values. Actually we'll put 0 and -1 into them at the appropriate time + m_perClothFriction.push_back(softBody->m_cfg.kDF); + m_perClothCollisionObjects.push_back( CollisionObjectIndices(-1, -1) ); + + // Add space for new vertices and triangles in the default solver for now + // TODO: Include space here for tearing too later + int firstVertex = getVertexData().getNumVertices(); + int numVertices = softBody->m_nodes.size(); + int maxVertices = numVertices; + // Allocate space for new vertices in all the vertex arrays + getVertexData().createVertices( maxVertices, softBodyIndex ); + + int firstTriangle = getTriangleData().getNumTriangles(); + int numTriangles = softBody->m_faces.size(); + int maxTriangles = numTriangles; + getTriangleData().createTriangles( maxTriangles ); + + // Copy vertices from softbody into the solver + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + Point3 multPoint(softBody->m_nodes[vertex].m_x.getX(), softBody->m_nodes[vertex].m_x.getY(), softBody->m_nodes[vertex].m_x.getZ()); + btSoftBodyVertexData::VertexDescription desc; + + // TODO: Position in the softbody might be pre-transformed + // or we may need to adapt for the pose. + //desc.setPosition( cloth.getMeshTransform()*multPoint ); + desc.setPosition( multPoint ); + + float vertexInverseMass = softBody->m_nodes[vertex].m_im; + desc.setInverseMass(vertexInverseMass); + getVertexData().setVertexAt( desc, firstVertex + vertex ); + + m_anchorIndex.push_back(-1); + } + + // Copy triangles similarly + // We're assuming here that vertex indices are based on the firstVertex rather than the entire scene + for( int triangle = 0; triangle < numTriangles; ++triangle ) + { + // Note that large array storage is relative to the array not to the cloth + // So we need to add firstVertex to each value + int vertexIndex0 = (softBody->m_faces[triangle].m_n[0] - &(softBody->m_nodes[0])); + int vertexIndex1 = (softBody->m_faces[triangle].m_n[1] - &(softBody->m_nodes[0])); + int vertexIndex2 = (softBody->m_faces[triangle].m_n[2] - &(softBody->m_nodes[0])); + btSoftBodyTriangleData::TriangleDescription newTriangle(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, vertexIndex2 + firstVertex); + getTriangleData().setTriangleAt( newTriangle, firstTriangle + triangle ); + + // Increase vertex triangle counts for this triangle + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex0)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex1)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex2)++; + } + + int firstLink = getLinkData().getNumLinks(); + int numLinks = softBody->m_links.size(); +// int maxLinks = numLinks; + + // Allocate space for the links + getLinkData().createLinks( numLinks ); + + // Add the links + for( int link = 0; link < numLinks; ++link ) + { + int vertexIndex0 = softBody->m_links[link].m_n[0] - &(softBody->m_nodes[0]); + int vertexIndex1 = softBody->m_links[link].m_n[1] - &(softBody->m_nodes[0]); + + btSoftBodyLinkData::LinkDescription newLink(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, softBody->m_links[link].m_material->m_kLST); + newLink.setLinkStrength(1.f); + getLinkData().setLinkAt(newLink, firstLink + link); + } + + newSoftBody->setFirstVertex( firstVertex ); + newSoftBody->setFirstTriangle( firstTriangle ); + newSoftBody->setNumVertices( numVertices ); + newSoftBody->setMaxVertices( maxVertices ); + newSoftBody->setNumTriangles( numTriangles ); + newSoftBody->setMaxTriangles( maxTriangles ); + newSoftBody->setFirstLink( firstLink ); + newSoftBody->setNumLinks( numLinks ); + + // Find maximum piterations and viterations + int piterations = softBody->m_cfg.piterations; + + if ( piterations > maxPiterations ) + maxPiterations = piterations; + + int viterations = softBody->m_cfg.viterations; + + if ( viterations > maxViterations ) + maxViterations = viterations; + + // zero mass + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + if ( softBody->m_nodes[vertex].m_im == 0 ) + { + AnchorNodeInfoCL nodeInfo; + nodeInfo.clVertexIndex = firstVertex + vertex; + nodeInfo.pNode = &softBody->m_nodes[vertex]; + + m_anchorNodeInfoArray.push_back(nodeInfo); + } + } + + // anchor position + if ( numVertices > 0 ) + { + for ( int anchorIndex = 0; anchorIndex < softBody->m_anchors.size(); anchorIndex++ ) + { + btSoftBody::Node* anchorNode = softBody->m_anchors[anchorIndex].m_node; + btSoftBody::Node* firstNode = &softBody->m_nodes[0]; + + AnchorNodeInfoCL nodeInfo; + nodeInfo.clVertexIndex = firstVertex + (int)(anchorNode - firstNode); + nodeInfo.pNode = anchorNode; + + m_anchorNodeInfoArray.push_back(nodeInfo); + } + } + } + + + m_anchorPosition.clear(); + m_anchorPosition.resize(m_anchorNodeInfoArray.size()); + + for ( int anchorNode = 0; anchorNode < m_anchorNodeInfoArray.size(); anchorNode++ ) + { + const AnchorNodeInfoCL& anchorNodeInfo = m_anchorNodeInfoArray[anchorNode]; + m_anchorIndex[anchorNodeInfo.clVertexIndex] = anchorNode; + getVertexData().getInverseMass(anchorNodeInfo.clVertexIndex) = 0.0f; + } + + updateConstants(0.f); + + // set position and velocity iterations + setNumberOfPositionIterations(maxPiterations); + setNumberOfVelocityIterations(maxViterations); + + // set wind velocity + m_perClothWindVelocity.resize( m_softBodySet.size() ); + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btSoftBody *softBody = m_softBodySet[softBodyIndex]->getSoftBody(); + m_perClothWindVelocity[softBodyIndex] = toVector3(softBody->getWindVelocity()); + } + + m_clPerClothWindVelocity.changedOnCPU(); + + // generate batches + m_linkData.generateBatches(); + m_triangleData.generateBatches(); + + // Build the shaders to match the batching parameters + buildShaders(); + } +} + + +btSoftBodyLinkData &btOpenCLSoftBodySolver::getLinkData() +{ + // TODO: Consider setting link data to "changed" here + return m_linkData; +} + +btSoftBodyVertexData &btOpenCLSoftBodySolver::getVertexData() +{ + // TODO: Consider setting vertex data to "changed" here + return m_vertexData; +} + +btSoftBodyTriangleData &btOpenCLSoftBodySolver::getTriangleData() +{ + // TODO: Consider setting triangle data to "changed" here + return m_triangleData; +} + +void btOpenCLSoftBodySolver::resetNormalsAndAreas( int numVertices ) +{ + cl_int ciErrNum; + ciErrNum = clSetKernelArg(m_resetNormalsAndAreasKernel, 0, sizeof(numVertices), (void*)&numVertices); //oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clSetKernelArg(m_resetNormalsAndAreasKernel, 1, sizeof(cl_mem), (void*)&m_vertexData.m_clVertexNormal.m_buffer);//oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clSetKernelArg(m_resetNormalsAndAreasKernel, 2, sizeof(cl_mem), (void*)&m_vertexData.m_clVertexArea.m_buffer); //oclCHECKERROR(ciErrNum, CL_SUCCESS); + size_t numWorkItems = m_defaultWorkGroupSize*((numVertices + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + + if (numWorkItems) + { + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, m_resetNormalsAndAreasKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize, 0,0,0 ); + + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_resetNormalsAndAreasKernel)" ); + } + } + +} + +void btOpenCLSoftBodySolver::normalizeNormalsAndAreas( int numVertices ) +{ + cl_int ciErrNum; + + ciErrNum = clSetKernelArg(m_normalizeNormalsAndAreasKernel, 0, sizeof(int),(void*) &numVertices); + ciErrNum = clSetKernelArg(m_normalizeNormalsAndAreasKernel, 1, sizeof(cl_mem), &m_vertexData.m_clVertexTriangleCount.m_buffer); + ciErrNum = clSetKernelArg(m_normalizeNormalsAndAreasKernel, 2, sizeof(cl_mem), &m_vertexData.m_clVertexNormal.m_buffer); + ciErrNum = clSetKernelArg(m_normalizeNormalsAndAreasKernel, 3, sizeof(cl_mem), &m_vertexData.m_clVertexArea.m_buffer); + size_t numWorkItems = m_defaultWorkGroupSize*((numVertices + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + if (numWorkItems) + { + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, m_normalizeNormalsAndAreasKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize, 0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_normalizeNormalsAndAreasKernel)"); + } + } + +} + +void btOpenCLSoftBodySolver::executeUpdateSoftBodies( int firstTriangle, int numTriangles ) +{ + cl_int ciErrNum; + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 0, sizeof(int), (void*) &firstTriangle); + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 1, sizeof(int), &numTriangles); + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 2, sizeof(cl_mem), &m_triangleData.m_clVertexIndices.m_buffer); + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 3, sizeof(cl_mem), &m_vertexData.m_clVertexPosition.m_buffer); + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 4, sizeof(cl_mem), &m_vertexData.m_clVertexNormal.m_buffer); + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 5, sizeof(cl_mem), &m_vertexData.m_clVertexArea.m_buffer); + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 6, sizeof(cl_mem), &m_triangleData.m_clNormal.m_buffer); + ciErrNum = clSetKernelArg(m_updateSoftBodiesKernel, 7, sizeof(cl_mem), &m_triangleData.m_clArea.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((numTriangles + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, m_updateSoftBodiesKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_normalizeNormalsAndAreasKernel)"); + } + +} + +void btOpenCLSoftBodySolver::updateSoftBodies() +{ + using namespace Vectormath::Aos; + + + int numVertices = m_vertexData.getNumVertices(); +// int numTriangles = m_triangleData.getNumTriangles(); + + // Ensure data is on accelerator + m_vertexData.moveToAccelerator(); + m_triangleData.moveToAccelerator(); + + resetNormalsAndAreas( numVertices ); + + + // Go through triangle batches so updates occur correctly + for( int batchIndex = 0; batchIndex < m_triangleData.m_batchStartLengths.size(); ++batchIndex ) + { + + int startTriangle = m_triangleData.m_batchStartLengths[batchIndex].first; + int numTriangles = m_triangleData.m_batchStartLengths[batchIndex].second; + + executeUpdateSoftBodies( startTriangle, numTriangles ); + } + + + normalizeNormalsAndAreas( numVertices ); +} // updateSoftBodies + + +Vectormath::Aos::Vector3 btOpenCLSoftBodySolver::ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a ) +{ + return a*Vectormath::Aos::dot(v, a); +} + +void btOpenCLSoftBodySolver::ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce ) +{ + float dtInverseMass = solverdt*inverseMass; + if( Vectormath::Aos::lengthSqr(force * dtInverseMass) > Vectormath::Aos::lengthSqr(vertexVelocity) ) + { + vertexForce -= ProjectOnAxis( vertexVelocity, normalize( force ) )/dtInverseMass; + } else { + vertexForce += force; + } +} + +void btOpenCLSoftBodySolver::updateFixedVertexPositions() +{ + // Ensure data is on accelerator + m_vertexData.moveToAccelerator(); + m_clAnchorPosition.moveToGPU(); + m_clAnchorIndex.moveToGPU(); + + cl_int ciErrNum ; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_updateFixedVertexPositionsKernel, 0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_updateFixedVertexPositionsKernel,1, sizeof(cl_mem), &m_clAnchorIndex.m_buffer); + ciErrNum = clSetKernelArg(m_updateFixedVertexPositionsKernel,2, sizeof(cl_mem), &m_vertexData.m_clVertexPosition.m_buffer); + ciErrNum = clSetKernelArg(m_updateFixedVertexPositionsKernel,3, sizeof(cl_mem), &m_clAnchorPosition.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_vertexData.getNumVertices() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + if (numWorkItems) + { + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_updateFixedVertexPositionsKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize, 0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_updateFixedVertexPositionsKernel)"); + } + } + +} + +void btOpenCLSoftBodySolver::applyForces( float solverdt ) +{ + // Ensure data is on accelerator + m_vertexData.moveToAccelerator(); + m_clPerClothAcceleration.moveToGPU(); + m_clPerClothLiftFactor.moveToGPU(); + m_clPerClothDragFactor.moveToGPU(); + m_clPerClothMediumDensity.moveToGPU(); + m_clPerClothWindVelocity.moveToGPU(); + + cl_int ciErrNum ; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 1, sizeof(float), &solverdt); + float fl = FLT_EPSILON; + ciErrNum = clSetKernelArg(m_applyForcesKernel, 2, sizeof(float), &fl); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 3, sizeof(cl_mem), &m_vertexData.m_clClothIdentifier.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 4, sizeof(cl_mem), &m_vertexData.m_clVertexNormal.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 5, sizeof(cl_mem), &m_vertexData.m_clVertexArea.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 6, sizeof(cl_mem), &m_vertexData.m_clVertexInverseMass.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 7, sizeof(cl_mem), &m_clPerClothLiftFactor.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 8 ,sizeof(cl_mem), &m_clPerClothDragFactor.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel, 9, sizeof(cl_mem), &m_clPerClothWindVelocity.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel,10, sizeof(cl_mem), &m_clPerClothAcceleration.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel,11, sizeof(cl_mem), &m_clPerClothMediumDensity.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel,12, sizeof(cl_mem), &m_vertexData.m_clVertexForceAccumulator.m_buffer); + ciErrNum = clSetKernelArg(m_applyForcesKernel,13, sizeof(cl_mem), &m_vertexData.m_clVertexVelocity.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_vertexData.getNumVertices() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + if (numWorkItems) + { + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_applyForcesKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize, 0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_applyForcesKernel)"); + } + } + +} + +/** + * Integrate motion on the solver. + */ +void btOpenCLSoftBodySolver::integrate( float solverdt ) +{ + // Ensure data is on accelerator + m_vertexData.moveToAccelerator(); + + cl_int ciErrNum; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_integrateKernel, 0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_integrateKernel, 1, sizeof(float), &solverdt); + ciErrNum = clSetKernelArg(m_integrateKernel, 2, sizeof(cl_mem), &m_vertexData.m_clVertexInverseMass.m_buffer); + ciErrNum = clSetKernelArg(m_integrateKernel, 3, sizeof(cl_mem), &m_vertexData.m_clVertexPosition.m_buffer); + ciErrNum = clSetKernelArg(m_integrateKernel, 4, sizeof(cl_mem), &m_vertexData.m_clVertexVelocity.m_buffer); + ciErrNum = clSetKernelArg(m_integrateKernel, 5, sizeof(cl_mem), &m_vertexData.m_clVertexPreviousPosition.m_buffer); + ciErrNum = clSetKernelArg(m_integrateKernel, 6, sizeof(cl_mem), &m_vertexData.m_clVertexForceAccumulator.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_vertexData.getNumVertices() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + if (numWorkItems) + { + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_integrateKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_integrateKernel)"); + } + } + +} + +float btOpenCLSoftBodySolver::computeTriangleArea( + const Vectormath::Aos::Point3 &vertex0, + const Vectormath::Aos::Point3 &vertex1, + const Vectormath::Aos::Point3 &vertex2 ) +{ + Vectormath::Aos::Vector3 a = vertex1 - vertex0; + Vectormath::Aos::Vector3 b = vertex2 - vertex0; + Vectormath::Aos::Vector3 crossProduct = cross(a, b); + float area = length( crossProduct ); + return area; +} + + +void btOpenCLSoftBodySolver::updateBounds() +{ + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btVector3 minBound(-1e30,-1e30,-1e30), maxBound(1e30,1e30,1e30); + m_softBodySet[softBodyIndex]->updateBounds( minBound, maxBound ); + } + +} // btOpenCLSoftBodySolver::updateBounds + + +void btOpenCLSoftBodySolver::updateConstants( float timeStep ) +{ + + using namespace Vectormath::Aos; + + if( m_updateSolverConstants ) + { + m_updateSolverConstants = false; + + // Will have to redo this if we change the structure (tear, maybe) or various other possible changes + + // Initialise link constants + const int numLinks = m_linkData.getNumLinks(); + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair &vertices( m_linkData.getVertexPair(linkIndex) ); + m_linkData.getRestLength(linkIndex) = length((m_vertexData.getPosition( vertices.vertex0 ) - m_vertexData.getPosition( vertices.vertex1 ))); + float invMass0 = m_vertexData.getInverseMass(vertices.vertex0); + float invMass1 = m_vertexData.getInverseMass(vertices.vertex1); + float linearStiffness = m_linkData.getLinearStiffnessCoefficient(linkIndex); + float massLSC = (invMass0 + invMass1)/linearStiffness; + m_linkData.getMassLSC(linkIndex) = massLSC; + float restLength = m_linkData.getRestLength(linkIndex); + float restLengthSquared = restLength*restLength; + m_linkData.getRestLengthSquared(linkIndex) = restLengthSquared; + } + } + +} + +class QuickSortCompare +{ + public: + + bool operator() ( const CollisionShapeDescription& a, const CollisionShapeDescription& b ) const + { + return ( a.softBodyIdentifier < b.softBodyIdentifier ); + } +}; + + +/** + * Sort the collision object details array and generate indexing into it for the per-cloth collision object array. + */ +void btOpenCLSoftBodySolver::prepareCollisionConstraints() +{ + // First do a simple sort on the collision objects + btAlignedObjectArray numObjectsPerClothPrefixSum; + btAlignedObjectArray numObjectsPerCloth; + numObjectsPerCloth.resize( m_softBodySet.size(), 0 ); + numObjectsPerClothPrefixSum.resize( m_softBodySet.size(), 0 ); + + + + m_collisionObjectDetails.quickSort( QuickSortCompare() ); + + if (!m_perClothCollisionObjects.size()) + return; + + // Generating indexing for perClothCollisionObjects + // First clear the previous values with the "no collision object for cloth" constant + for( int clothIndex = 0; clothIndex < m_perClothCollisionObjects.size(); ++clothIndex ) + { + m_perClothCollisionObjects[clothIndex].firstObject = -1; + m_perClothCollisionObjects[clothIndex].endObject = -1; + } + int currentCloth = 0; + int startIndex = 0; + for( int collisionObject = 0; collisionObject < m_collisionObjectDetails.size(); ++collisionObject ) + { + int nextCloth = m_collisionObjectDetails[collisionObject].softBodyIdentifier; + if( nextCloth != currentCloth ) + { + // Changed cloth in the array + // Set the end index and the range is what we need for currentCloth + m_perClothCollisionObjects[currentCloth].firstObject = startIndex; + m_perClothCollisionObjects[currentCloth].endObject = collisionObject; + currentCloth = nextCloth; + startIndex = collisionObject; + } + } + + // And update last cloth + m_perClothCollisionObjects[currentCloth].firstObject = startIndex; + m_perClothCollisionObjects[currentCloth].endObject = m_collisionObjectDetails.size(); + +} // btOpenCLSoftBodySolver::prepareCollisionConstraints + + + +void btOpenCLSoftBodySolver::solveConstraints( float solverdt ) +{ + + using Vectormath::Aos::Vector3; + using Vectormath::Aos::Point3; + using Vectormath::Aos::lengthSqr; + using Vectormath::Aos::dot; + + // Prepare links +// int numLinks = m_linkData.getNumLinks(); +// int numVertices = m_vertexData.getNumVertices(); + + float kst = 1.f; + float ti = 0.f; + + + m_clPerClothDampingFactor.moveToGPU(); + m_clPerClothVelocityCorrectionCoefficient.moveToGPU(); + + + // Ensure data is on accelerator + m_linkData.moveToAccelerator(); + m_vertexData.moveToAccelerator(); + + prepareLinks(); + + + + for( int iteration = 0; iteration < m_numberOfVelocityIterations ; ++iteration ) + { + for( int i = 0; i < m_linkData.m_batchStartLengths.size(); ++i ) + { + int startLink = m_linkData.m_batchStartLengths[i].start; + int numLinks = m_linkData.m_batchStartLengths[i].length; + + solveLinksForVelocity( startLink, numLinks, kst ); + } + } + + + prepareCollisionConstraints(); + + // Compute new positions from velocity + // Also update the previous position so that our position computation is now based on the new position from the velocity solution + // rather than based directly on the original positions + if( m_numberOfVelocityIterations > 0 ) + { + updateVelocitiesFromPositionsWithVelocities( 1.f/solverdt ); + } else { + updateVelocitiesFromPositionsWithoutVelocities( 1.f/solverdt ); + } + + // Solve position + for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + { + for( int i = 0; i < m_linkData.m_batchStartLengths.size(); ++i ) + { + int startLink = m_linkData.m_batchStartLengths[i].start; + int numLinks = m_linkData.m_batchStartLengths[i].length; + + solveLinksForPosition( startLink, numLinks, kst, ti ); + } + + } // for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + + + // At this point assume that the force array is blank - we will overwrite it + solveCollisionsAndUpdateVelocities( 1.f/solverdt ); + +} + + +////////////////////////////////////// +// Kernel dispatches +void btOpenCLSoftBodySolver::prepareLinks() +{ + cl_int ciErrNum; + int numLinks = m_linkData.getNumLinks(); + ciErrNum = clSetKernelArg(m_prepareLinksKernel,0, sizeof(int), &numLinks); + ciErrNum = clSetKernelArg(m_prepareLinksKernel,1, sizeof(cl_mem), &m_linkData.m_clLinks.m_buffer); + ciErrNum = clSetKernelArg(m_prepareLinksKernel,2, sizeof(cl_mem), &m_linkData.m_clLinksMassLSC.m_buffer); + ciErrNum = clSetKernelArg(m_prepareLinksKernel,3, sizeof(cl_mem), &m_vertexData.m_clVertexPreviousPosition.m_buffer); + ciErrNum = clSetKernelArg(m_prepareLinksKernel,4, sizeof(cl_mem), &m_linkData.m_clLinksLengthRatio.m_buffer); + ciErrNum = clSetKernelArg(m_prepareLinksKernel,5, sizeof(cl_mem), &m_linkData.m_clLinksCLength.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_linkData.getNumLinks() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_prepareLinksKernel, 1 , NULL, &numWorkItems, &m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_prepareLinksKernel)"); + } + +} + +void btOpenCLSoftBodySolver::updatePositionsFromVelocities( float solverdt ) +{ + cl_int ciErrNum; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_updatePositionsFromVelocitiesKernel,0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_updatePositionsFromVelocitiesKernel,1, sizeof(float), &solverdt); + ciErrNum = clSetKernelArg(m_updatePositionsFromVelocitiesKernel,2, sizeof(cl_mem), &m_vertexData.m_clVertexVelocity.m_buffer); + ciErrNum = clSetKernelArg(m_updatePositionsFromVelocitiesKernel,3, sizeof(cl_mem), &m_vertexData.m_clVertexPreviousPosition.m_buffer); + ciErrNum = clSetKernelArg(m_updatePositionsFromVelocitiesKernel,4, sizeof(cl_mem), &m_vertexData.m_clVertexPosition.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_vertexData.getNumVertices() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_updatePositionsFromVelocitiesKernel, 1, NULL, &numWorkItems,&m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_updatePositionsFromVelocitiesKernel)"); + } + +} + +void btOpenCLSoftBodySolver::solveLinksForPosition( int startLink, int numLinks, float kst, float ti ) +{ + cl_int ciErrNum; + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,0, sizeof(int), &startLink); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,1, sizeof(int), &numLinks); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,2, sizeof(float), &kst); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,3, sizeof(float), &ti); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,4, sizeof(cl_mem), &m_linkData.m_clLinks.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,5, sizeof(cl_mem), &m_linkData.m_clLinksMassLSC.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,6, sizeof(cl_mem), &m_linkData.m_clLinksRestLengthSquared.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,7, sizeof(cl_mem), &m_vertexData.m_clVertexInverseMass.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,8, sizeof(cl_mem), &m_vertexData.m_clVertexPosition.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((numLinks + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_solvePositionsFromLinksKernel,1,NULL,&numWorkItems,&m_defaultWorkGroupSize,0,0,0); + if( ciErrNum!= CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_solvePositionsFromLinksKernel)"); + } + +} // solveLinksForPosition + + +void btOpenCLSoftBodySolver::solveLinksForVelocity( int startLink, int numLinks, float kst ) +{ + cl_int ciErrNum; + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 0, sizeof(int), &startLink); + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 1, sizeof(int), &numLinks); + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 2, sizeof(float), &kst); + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 3, sizeof(cl_mem), &m_linkData.m_clLinks.m_buffer); + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 4, sizeof(cl_mem), &m_linkData.m_clLinksLengthRatio.m_buffer); + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 5, sizeof(cl_mem), &m_linkData.m_clLinksCLength.m_buffer); + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 6, sizeof(cl_mem), &m_vertexData.m_clVertexInverseMass.m_buffer); + ciErrNum = clSetKernelArg(m_vSolveLinksKernel, 7, sizeof(cl_mem), &m_vertexData.m_clVertexVelocity.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((numLinks + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_vSolveLinksKernel,1,NULL,&numWorkItems, &m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_vSolveLinksKernel)"); + } + +} + +void btOpenCLSoftBodySolver::updateVelocitiesFromPositionsWithVelocities( float isolverdt ) +{ + cl_int ciErrNum; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel,0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 1, sizeof(float), &isolverdt); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 2, sizeof(cl_mem), &m_vertexData.m_clVertexPosition.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 3, sizeof(cl_mem), &m_vertexData.m_clVertexPreviousPosition.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 4, sizeof(cl_mem), &m_vertexData.m_clClothIdentifier.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 5, sizeof(cl_mem), &m_clPerClothVelocityCorrectionCoefficient.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 6, sizeof(cl_mem), &m_clPerClothDampingFactor.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 7, sizeof(cl_mem), &m_vertexData.m_clVertexVelocity.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithVelocitiesKernel, 8, sizeof(cl_mem), &m_vertexData.m_clVertexForceAccumulator.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_vertexData.getNumVertices() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_updateVelocitiesFromPositionsWithVelocitiesKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_updateVelocitiesFromPositionsWithVelocitiesKernel)"); + } + + +} // updateVelocitiesFromPositionsWithVelocities + +void btOpenCLSoftBodySolver::updateVelocitiesFromPositionsWithoutVelocities( float isolverdt ) +{ + cl_int ciErrNum; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 1, sizeof(float), &isolverdt); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 2, sizeof(cl_mem),&m_vertexData.m_clVertexPosition.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 3, sizeof(cl_mem),&m_vertexData.m_clVertexPreviousPosition.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 4, sizeof(cl_mem),&m_vertexData.m_clClothIdentifier.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 5, sizeof(cl_mem),&m_clPerClothDampingFactor.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 6, sizeof(cl_mem),&m_vertexData.m_clVertexVelocity.m_buffer); + ciErrNum = clSetKernelArg(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 7, sizeof(cl_mem),&m_vertexData.m_clVertexForceAccumulator.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_vertexData.getNumVertices() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_updateVelocitiesFromPositionsWithoutVelocitiesKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel)"); + } + +} // updateVelocitiesFromPositionsWithoutVelocities + + + +void btOpenCLSoftBodySolver::solveCollisionsAndUpdateVelocities( float isolverdt ) +{ + // Copy kernel parameters to GPU + m_vertexData.moveToAccelerator(); + m_clPerClothFriction.moveToGPU(); + m_clPerClothDampingFactor.moveToGPU(); + m_clPerClothCollisionObjects.moveToGPU(); + m_clCollisionObjectDetails.moveToGPU(); + + cl_int ciErrNum; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 1, sizeof(int), &isolverdt); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 2, sizeof(cl_mem),&m_vertexData.m_clClothIdentifier.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 3, sizeof(cl_mem),&m_vertexData.m_clVertexPreviousPosition.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 4, sizeof(cl_mem),&m_clPerClothFriction.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 5, sizeof(cl_mem),&m_clPerClothDampingFactor.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 6, sizeof(cl_mem),&m_clPerClothCollisionObjects.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 7, sizeof(cl_mem),&m_clCollisionObjectDetails.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 8, sizeof(cl_mem),&m_vertexData.m_clVertexForceAccumulator.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 9, sizeof(cl_mem),&m_vertexData.m_clVertexVelocity.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 10, sizeof(cl_mem),&m_vertexData.m_clVertexPosition.m_buffer); + + size_t numWorkItems = m_defaultWorkGroupSize*((m_vertexData.getNumVertices() + (m_defaultWorkGroupSize-1)) / m_defaultWorkGroupSize); + if (numWorkItems) + { + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_solveCollisionsAndUpdateVelocitiesKernel, 1, NULL, &numWorkItems, &m_defaultWorkGroupSize,0,0,0); + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_updateVelocitiesFromPositionsWithoutVelocitiesKernel)"); + } + } + +} // btOpenCLSoftBodySolver::updateVelocitiesFromPositionsWithoutVelocities + + + +// End kernel dispatches +///////////////////////////////////// + + +void btSoftBodySolverOutputCLtoCPU::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ) +{ + + btSoftBodySolver *solver = softBody->getSoftBodySolver(); + btAssert( solver->getSolverType() == btSoftBodySolver::CL_SOLVER || solver->getSolverType() == btSoftBodySolver::CL_SIMD_SOLVER ); + btOpenCLSoftBodySolver *dxSolver = static_cast< btOpenCLSoftBodySolver * >( solver ); + + btOpenCLAcceleratedSoftBodyInterface* currentCloth = dxSolver->findSoftBodyInterface( softBody ); + btSoftBodyVertexDataOpenCL &vertexData( dxSolver->m_vertexData ); + + + const int firstVertex = currentCloth->getFirstVertex(); + const int lastVertex = firstVertex + currentCloth->getNumVertices(); + + if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER ) + { + const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast< btCPUVertexBufferDescriptor* >(vertexBuffer); + float *basePointer = cpuVertexBuffer->getBasePointer(); + + vertexData.m_clVertexPosition.copyFromGPU(); + vertexData.m_clVertexNormal.copyFromGPU(); + + if( vertexBuffer->hasVertexPositions() ) + { + const int vertexOffset = cpuVertexBuffer->getVertexOffset(); + const int vertexStride = cpuVertexBuffer->getVertexStride(); + float *vertexPointer = basePointer + vertexOffset; + + for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex ) + { + Vectormath::Aos::Point3 position = vertexData.getPosition(vertexIndex); + *(vertexPointer + 0) = position.getX(); + *(vertexPointer + 1) = position.getY(); + *(vertexPointer + 2) = position.getZ(); + vertexPointer += vertexStride; + } + } + if( vertexBuffer->hasNormals() ) + { + const int normalOffset = cpuVertexBuffer->getNormalOffset(); + const int normalStride = cpuVertexBuffer->getNormalStride(); + float *normalPointer = basePointer + normalOffset; + + for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex ) + { + Vectormath::Aos::Vector3 normal = vertexData.getNormal(vertexIndex); + *(normalPointer + 0) = normal.getX(); + *(normalPointer + 1) = normal.getY(); + *(normalPointer + 2) = normal.getZ(); + normalPointer += normalStride; + } + } + } + +} // btSoftBodySolverOutputCLtoCPU::outputToVertexBuffers + + + +cl_kernel CLFunctions::compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros ,const char* orgSrcFileNameForCaching) +{ + printf("compiling kernelName: %s ",kernelName); + cl_kernel kernel=0; + cl_int ciErrNum; + size_t program_length = strlen(kernelSource); + + cl_program m_cpProgram = clCreateProgramWithSource(m_cxMainContext, 1, (const char**)&kernelSource, &program_length, &ciErrNum); +// oclCHECKERROR(ciErrNum, CL_SUCCESS); + + // Build the program with 'mad' Optimization option + + +#ifdef MAC + char* flags = "-cl-mad-enable -DMAC -DGUID_ARG"; +#else + //const char* flags = "-DGUID_ARG= -fno-alias"; + const char* flags = "-DGUID_ARG= "; +#endif + + char* compileFlags = new char[strlen(additionalMacros) + strlen(flags) + 5]; + sprintf(compileFlags, "%s %s", flags, additionalMacros); + ciErrNum = clBuildProgram(m_cpProgram, 0, NULL, compileFlags, NULL, NULL); + if (ciErrNum != CL_SUCCESS) + { + size_t numDevices; + clGetProgramInfo( m_cpProgram, CL_PROGRAM_DEVICES, 0, 0, &numDevices ); + cl_device_id *devices = new cl_device_id[numDevices]; + clGetProgramInfo( m_cpProgram, CL_PROGRAM_DEVICES, numDevices, devices, &numDevices ); + for( int i = 0; i < 2; ++i ) + { + char *build_log; + size_t ret_val_size; + clGetProgramBuildInfo(m_cpProgram, devices[i], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); + build_log = new char[ret_val_size+1]; + clGetProgramBuildInfo(m_cpProgram, devices[i], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); + + // to be carefully, terminate with \0 + // there's no information in the reference whether the string is 0 terminated or not + build_log[ret_val_size] = '\0'; + + + printf("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log); + delete[] build_log; + } +#ifndef BT_SUPPRESS_OPENCL_ASSERTS + btAssert(0); +#endif //BT_SUPPRESS_OPENCL_ASSERTS + m_kernelCompilationFailures++; + return 0; + } + + + // Create the kernel + kernel = clCreateKernel(m_cpProgram, kernelName, &ciErrNum); + if (ciErrNum != CL_SUCCESS) + { + const char* msg = ""; + switch(ciErrNum) + { + case CL_INVALID_PROGRAM: + msg = "Program is not a valid program object."; + break; + case CL_INVALID_PROGRAM_EXECUTABLE: + msg = "There is no successfully built executable for program."; + break; + case CL_INVALID_KERNEL_NAME: + msg = "kernel_name is not found in program."; + break; + case CL_INVALID_KERNEL_DEFINITION: + msg = "the function definition for __kernel function given by kernel_name such as the number of arguments, the argument types are not the same for all devices for which the program executable has been built."; + break; + case CL_INVALID_VALUE: + msg = "kernel_name is NULL."; + break; + case CL_OUT_OF_HOST_MEMORY: + msg = "Failure to allocate resources required by the OpenCL implementation on the host."; + break; + default: + { + } + } + + printf("Error in clCreateKernel for kernel '%s', error is \"%s\", Line %u in file %s !!!\n\n", kernelName, msg, __LINE__, __FILE__); + +#ifndef BT_SUPPRESS_OPENCL_ASSERTS + btAssert(0); +#endif //BT_SUPPRESS_OPENCL_ASSERTS + m_kernelCompilationFailures++; + return 0; + } + + printf("ready. \n"); + delete [] compileFlags; + if (!kernel) + m_kernelCompilationFailures++; + return kernel; + +} + +void btOpenCLSoftBodySolver::predictMotion( float timeStep ) +{ + // Clear the collision shape array for the next frame + // Ensure that the DX11 ones are moved off the device so they will be updated correctly + m_clCollisionObjectDetails.changedOnCPU(); + m_clPerClothCollisionObjects.changedOnCPU(); + m_collisionObjectDetails.clear(); + + if ( m_bUpdateAnchoredNodePos ) + { + // In OpenCL cloth solver, if softbody node has zero inverse mass(infinite mass) or anchor attached, + // we need to update the node position in case the node or anchor is animated externally. + // If there is no such node, we can eliminate the unnecessary CPU-to-GPU data trasferring. + for ( int i = 0; i < m_anchorNodeInfoArray.size(); i++ ) + { + const AnchorNodeInfoCL& anchorNodeInfo = m_anchorNodeInfoArray[i]; + btSoftBody::Node* node = anchorNodeInfo.pNode; + + using Vectormath::Aos::Point3; + Point3 pos((float)node->m_x.getX(), (float)node->m_x.getY(), (float)node->m_x.getZ()); + m_anchorPosition[i] = pos; + } + + if ( m_anchorNodeInfoArray.size() > 0 ) + m_clAnchorPosition.changedOnCPU(); + + updateFixedVertexPositions(); + } + + { + BT_PROFILE("applyForces"); + // Apply forces that we know about to the cloths + applyForces( timeStep * getTimeScale() ); + } + + { + BT_PROFILE("integrate"); + // Itegrate motion for all soft bodies dealt with by the solver + integrate( timeStep * getTimeScale() ); + } + + { + BT_PROFILE("updateBounds"); + updateBounds(); + } + // End prediction work for solvers +} + +static Vectormath::Aos::Transform3 toTransform3( const btTransform &transform ) +{ + Vectormath::Aos::Transform3 outTransform; + outTransform.setCol(0, toVector3(transform.getBasis().getColumn(0))); + outTransform.setCol(1, toVector3(transform.getBasis().getColumn(1))); + outTransform.setCol(2, toVector3(transform.getBasis().getColumn(2))); + outTransform.setCol(3, toVector3(transform.getOrigin())); + return outTransform; +} + +void btOpenCLAcceleratedSoftBodyInterface::updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound ) +{ + float scalarMargin = (float)getSoftBody()->getCollisionShape()->getMargin(); + btVector3 vectorMargin( scalarMargin, scalarMargin, scalarMargin ); + m_softBody->m_bounds[0] = lowerBound - vectorMargin; + m_softBody->m_bounds[1] = upperBound + vectorMargin; +} // btOpenCLSoftBodySolver::btDX11AcceleratedSoftBodyInterface::updateBounds + +void btOpenCLSoftBodySolver::processCollision( btSoftBody*, btSoftBody* ) +{ + +} + +// Add the collision object to the set to deal with for a particular soft body +void btOpenCLSoftBodySolver::processCollision( btSoftBody *softBody, const btCollisionObjectWrapper* collisionObject ) +{ + int softBodyIndex = findSoftBodyIndex( softBody ); + + if( softBodyIndex >= 0 ) + { + const btCollisionShape *collisionShape = collisionObject->getCollisionShape(); + float friction = collisionObject->getCollisionObject()->getFriction(); + int shapeType = collisionShape->getShapeType(); + if( shapeType == CAPSULE_SHAPE_PROXYTYPE ) + { + // Add to the list of expected collision objects + CollisionShapeDescription newCollisionShapeDescription; + newCollisionShapeDescription.softBodyIdentifier = softBodyIndex; + newCollisionShapeDescription.collisionShapeType = shapeType; + // TODO: May need to transpose this matrix either here or in HLSL + newCollisionShapeDescription.shapeTransform = toTransform3(collisionObject->getWorldTransform()); + const btCapsuleShape *capsule = static_cast( collisionShape ); + newCollisionShapeDescription.radius = capsule->getRadius(); + newCollisionShapeDescription.halfHeight = capsule->getHalfHeight(); + newCollisionShapeDescription.margin = capsule->getMargin(); + newCollisionShapeDescription.upAxis = capsule->getUpAxis(); + newCollisionShapeDescription.friction = friction; + const btRigidBody* body = static_cast< const btRigidBody* >( collisionObject->getCollisionObject() ); + newCollisionShapeDescription.linearVelocity = toVector3(body->getLinearVelocity()); + newCollisionShapeDescription.angularVelocity = toVector3(body->getAngularVelocity()); + m_collisionObjectDetails.push_back( newCollisionShapeDescription ); + + } + else { +#ifdef _DEBUG + printf("Unsupported collision shape type\n"); +#endif + //btAssert(0 && "Unsupported collision shape type\n"); + } + } else { + btAssert(0 && "Unknown soft body"); + } +} // btOpenCLSoftBodySolver::processCollision + + + + + +btOpenCLAcceleratedSoftBodyInterface* btOpenCLSoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody ) +{ + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btOpenCLAcceleratedSoftBodyInterface* softBodyInterface = m_softBodySet[softBodyIndex]; + if( softBodyInterface->getSoftBody() == softBody ) + return softBodyInterface; + } + return 0; +} + + +int btOpenCLSoftBodySolver::findSoftBodyIndex( const btSoftBody* const softBody ) +{ + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btOpenCLAcceleratedSoftBodyInterface* softBodyInterface = m_softBodySet[softBodyIndex]; + if( softBodyInterface->getSoftBody() == softBody ) + return softBodyIndex; + } + return 1; +} + +bool btOpenCLSoftBodySolver::checkInitialized() +{ + if( !m_shadersInitialized ) + if( buildShaders() ) + m_shadersInitialized = true; + + return m_shadersInitialized; +} + +bool btOpenCLSoftBodySolver::buildShaders() +{ + if( m_shadersInitialized ) + return true; + + const char* additionalMacros=""; + + // Ensure current kernels are released first + releaseKernels(); + + m_currentCLFunctions->clearKernelCompilationFailures(); + + m_prepareLinksKernel = m_currentCLFunctions->compileCLKernelFromString( PrepareLinksCLString, "PrepareLinksKernel",additionalMacros,"OpenCLC10/PrepareLinks.cl" ); + m_updatePositionsFromVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdatePositionsFromVelocitiesCLString, "UpdatePositionsFromVelocitiesKernel" ,additionalMacros,"OpenCLC10/UpdatePositionsFromVelocities.cl"); + m_solvePositionsFromLinksKernel = m_currentCLFunctions->compileCLKernelFromString( SolvePositionsCLString, "SolvePositionsFromLinksKernel",additionalMacros,"OpenCLC10/SolvePositions.cl" ); + m_vSolveLinksKernel = m_currentCLFunctions->compileCLKernelFromString( VSolveLinksCLString, "VSolveLinksKernel" ,additionalMacros,"OpenCLC10/VSolveLinks.cl"); + m_updateVelocitiesFromPositionsWithVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNodesCLString, "updateVelocitiesFromPositionsWithVelocitiesKernel" ,additionalMacros,"OpenCLC10/UpdateNodes.cl"); + m_updateVelocitiesFromPositionsWithoutVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdatePositionsCLString, "updateVelocitiesFromPositionsWithoutVelocitiesKernel" ,additionalMacros,"OpenCLC10/UpdatePositions.cl"); + m_solveCollisionsAndUpdateVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( SolveCollisionsAndUpdateVelocitiesCLString, "SolveCollisionsAndUpdateVelocitiesKernel" ,additionalMacros,"OpenCLC10/SolveCollisionsAndUpdateVelocities.cl"); + m_integrateKernel = m_currentCLFunctions->compileCLKernelFromString( IntegrateCLString, "IntegrateKernel" ,additionalMacros,"OpenCLC10/Integrate.cl"); + m_applyForcesKernel = m_currentCLFunctions->compileCLKernelFromString( ApplyForcesCLString, "ApplyForcesKernel" ,additionalMacros,"OpenCLC10/ApplyForces.cl"); + m_updateFixedVertexPositionsKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateFixedVertexPositionsCLString, "UpdateFixedVertexPositions" , additionalMacros, "OpenCLC10/UpdateFixedVertexPositions.cl"); + + // TODO: Rename to UpdateSoftBodies + m_resetNormalsAndAreasKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNormalsCLString, "ResetNormalsAndAreasKernel" ,additionalMacros,"OpenCLC10/UpdateNormals.cl"); + m_normalizeNormalsAndAreasKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNormalsCLString, "NormalizeNormalsAndAreasKernel" ,additionalMacros,"OpenCLC10/UpdateNormals.cl"); + m_updateSoftBodiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNormalsCLString, "UpdateSoftBodiesKernel" ,additionalMacros,"OpenCLC10/UpdateNormals.cl"); + + + if( m_currentCLFunctions->getKernelCompilationFailures()==0 ) + m_shadersInitialized = true; + + return m_shadersInitialized; +} + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h new file mode 100644 index 0000000..dfcfe8c --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h @@ -0,0 +1,527 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_OPENCL_H +#define BT_SOFT_BODY_SOLVER_OPENCL_H + +#include "stddef.h" //for size_t +#include "vectormath/vmInclude.h" + +#include "BulletSoftBody/btSoftBodySolvers.h" +#include "BulletSoftBody/btSoftBody.h" +#include "btSoftBodySolverBuffer_OpenCL.h" +#include "btSoftBodySolverLinkData_OpenCL.h" +#include "btSoftBodySolverVertexData_OpenCL.h" +#include "btSoftBodySolverTriangleData_OpenCL.h" + +class CLFunctions +{ +protected: + cl_command_queue m_cqCommandQue; + cl_context m_cxMainContext; + + int m_kernelCompilationFailures; + + +public: + CLFunctions(cl_command_queue cqCommandQue, cl_context cxMainContext) : + m_cqCommandQue( cqCommandQue ), + m_cxMainContext( cxMainContext ), + m_kernelCompilationFailures(0) + { + } + + int getKernelCompilationFailures() const + { + return m_kernelCompilationFailures; + } + + /** + * Compile a compute shader kernel from a string and return the appropriate cl_kernel object. + */ + virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros, const char* srcFileNameForCaching); + + void clearKernelCompilationFailures() + { + m_kernelCompilationFailures=0; + } +}; + +/** + * Entry in the collision shape array. + * Specifies the shape type, the transform matrix and the necessary details of the collisionShape. + */ +struct CollisionShapeDescription +{ + Vectormath::Aos::Transform3 shapeTransform; + Vectormath::Aos::Vector3 linearVelocity; + Vectormath::Aos::Vector3 angularVelocity; + + int softBodyIdentifier; + int collisionShapeType; + + // Both needed for capsule + float radius; + float halfHeight; + int upAxis; + + float margin; + float friction; + + CollisionShapeDescription() + { + collisionShapeType = 0; + margin = 0; + friction = 0; + } +}; + +/** + * SoftBody class to maintain information about a soft body instance + * within a solver. + * This data addresses the main solver arrays. + */ +class btOpenCLAcceleratedSoftBodyInterface +{ +protected: + /** Current number of vertices that are part of this cloth */ + int m_numVertices; + /** Maximum number of vertices allocated to be part of this cloth */ + int m_maxVertices; + /** Current number of triangles that are part of this cloth */ + int m_numTriangles; + /** Maximum number of triangles allocated to be part of this cloth */ + int m_maxTriangles; + /** Index of first vertex in the world allocated to this cloth */ + int m_firstVertex; + /** Index of first triangle in the world allocated to this cloth */ + int m_firstTriangle; + /** Index of first link in the world allocated to this cloth */ + int m_firstLink; + /** Maximum number of links allocated to this cloth */ + int m_maxLinks; + /** Current number of links allocated to this cloth */ + int m_numLinks; + + /** The actual soft body this data represents */ + btSoftBody *m_softBody; + + +public: + btOpenCLAcceleratedSoftBodyInterface( btSoftBody *softBody ) : + m_softBody( softBody ) + { + m_numVertices = 0; + m_maxVertices = 0; + m_numTriangles = 0; + m_maxTriangles = 0; + m_firstVertex = 0; + m_firstTriangle = 0; + m_firstLink = 0; + m_maxLinks = 0; + m_numLinks = 0; + } + int getNumVertices() + { + return m_numVertices; + } + + int getNumTriangles() + { + return m_numTriangles; + } + + int getMaxVertices() + { + return m_maxVertices; + } + + int getMaxTriangles() + { + return m_maxTriangles; + } + + int getFirstVertex() + { + return m_firstVertex; + } + + int getFirstTriangle() + { + return m_firstTriangle; + } + + /** + * Update the bounds in the btSoftBody object + */ + void updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound ); + + // TODO: All of these set functions will have to do checks and + // update the world because restructuring of the arrays will be necessary + // Reasonable use of "friend"? + void setNumVertices( int numVertices ) + { + m_numVertices = numVertices; + } + + void setNumTriangles( int numTriangles ) + { + m_numTriangles = numTriangles; + } + + void setMaxVertices( int maxVertices ) + { + m_maxVertices = maxVertices; + } + + void setMaxTriangles( int maxTriangles ) + { + m_maxTriangles = maxTriangles; + } + + void setFirstVertex( int firstVertex ) + { + m_firstVertex = firstVertex; + } + + void setFirstTriangle( int firstTriangle ) + { + m_firstTriangle = firstTriangle; + } + + void setMaxLinks( int maxLinks ) + { + m_maxLinks = maxLinks; + } + + void setNumLinks( int numLinks ) + { + m_numLinks = numLinks; + } + + void setFirstLink( int firstLink ) + { + m_firstLink = firstLink; + } + + int getMaxLinks() + { + return m_maxLinks; + } + + int getNumLinks() + { + return m_numLinks; + } + + int getFirstLink() + { + return m_firstLink; + } + + btSoftBody* getSoftBody() + { + return m_softBody; + } + +}; + + + +class btOpenCLSoftBodySolver : public btSoftBodySolver +{ +public: + + + struct UIntVector3 + { + UIntVector3() + { + x = 0; + y = 0; + z = 0; + _padding = 0; + } + + UIntVector3( unsigned int x_, unsigned int y_, unsigned int z_ ) + { + x = x_; + y = y_; + z = z_; + _padding = 0; + } + + unsigned int x; + unsigned int y; + unsigned int z; + unsigned int _padding; + }; + + struct CollisionObjectIndices + { + CollisionObjectIndices( int f, int e ) + { + firstObject = f; + endObject = e; + } + + int firstObject; + int endObject; + }; + + btSoftBodyLinkDataOpenCL m_linkData; + btSoftBodyVertexDataOpenCL m_vertexData; + btSoftBodyTriangleDataOpenCL m_triangleData; + +protected: + + CLFunctions m_defaultCLFunctions; + CLFunctions* m_currentCLFunctions; + + /** Variable to define whether we need to update solver constants on the next iteration */ + bool m_updateSolverConstants; + + bool m_shadersInitialized; + + /** + * Cloths owned by this solver. + * Only our cloths are in this array. + */ + btAlignedObjectArray< btOpenCLAcceleratedSoftBodyInterface * > m_softBodySet; + + /** Acceleration value to be applied to all non-static vertices in the solver. + * Index n is cloth n, array sized by number of cloths in the world not the solver. + */ + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothAcceleration; + btOpenCLBuffer m_clPerClothAcceleration; + + /** Wind velocity to be applied normal to all non-static vertices in the solver. + * Index n is cloth n, array sized by number of cloths in the world not the solver. + */ + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothWindVelocity; + btOpenCLBuffer m_clPerClothWindVelocity; + + /** Velocity damping factor */ + btAlignedObjectArray< float > m_perClothDampingFactor; + btOpenCLBuffer m_clPerClothDampingFactor; + + /** Velocity correction coefficient */ + btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient; + btOpenCLBuffer m_clPerClothVelocityCorrectionCoefficient; + + /** Lift parameter for wind effect on cloth. */ + btAlignedObjectArray< float > m_perClothLiftFactor; + btOpenCLBuffer m_clPerClothLiftFactor; + + /** Drag parameter for wind effect on cloth. */ + btAlignedObjectArray< float > m_perClothDragFactor; + btOpenCLBuffer m_clPerClothDragFactor; + + /** Density of the medium in which each cloth sits */ + btAlignedObjectArray< float > m_perClothMediumDensity; + btOpenCLBuffer m_clPerClothMediumDensity; + + /** + * Collision shape details: pair of index of first collision shape for the cloth and number of collision objects. + */ + btAlignedObjectArray< CollisionObjectIndices > m_perClothCollisionObjects; + btOpenCLBuffer m_clPerClothCollisionObjects; + + /** + * Collision shapes being passed across to the cloths in this solver. + */ + btAlignedObjectArray< CollisionShapeDescription > m_collisionObjectDetails; + btOpenCLBuffer< CollisionShapeDescription > m_clCollisionObjectDetails; + + + + /** + * Friction coefficient for each cloth + */ + btAlignedObjectArray< float > m_perClothFriction; + btOpenCLBuffer< float > m_clPerClothFriction; + + // anchor node info + struct AnchorNodeInfoCL + { + int clVertexIndex; + btSoftBody::Node* pNode; + }; + + btAlignedObjectArray m_anchorNodeInfoArray; + btAlignedObjectArray m_anchorPosition; + btOpenCLBuffer m_clAnchorPosition; + btAlignedObjectArray m_anchorIndex; + btOpenCLBuffer m_clAnchorIndex; + + bool m_bUpdateAnchoredNodePos; + + cl_kernel m_prepareLinksKernel; + cl_kernel m_solvePositionsFromLinksKernel; + cl_kernel m_updateConstantsKernel; + cl_kernel m_integrateKernel; + cl_kernel m_addVelocityKernel; + cl_kernel m_updatePositionsFromVelocitiesKernel; + cl_kernel m_updateVelocitiesFromPositionsWithoutVelocitiesKernel; + cl_kernel m_updateVelocitiesFromPositionsWithVelocitiesKernel; + cl_kernel m_vSolveLinksKernel; + cl_kernel m_solveCollisionsAndUpdateVelocitiesKernel; + cl_kernel m_resetNormalsAndAreasKernel; + cl_kernel m_normalizeNormalsAndAreasKernel; + cl_kernel m_updateSoftBodiesKernel; + + cl_kernel m_outputToVertexArrayKernel; + cl_kernel m_applyForcesKernel; + cl_kernel m_updateFixedVertexPositionsKernel; + + cl_command_queue m_cqCommandQue; + cl_context m_cxMainContext; + + size_t m_defaultWorkGroupSize; + + + virtual bool buildShaders(); + + void resetNormalsAndAreas( int numVertices ); + + void normalizeNormalsAndAreas( int numVertices ); + + void executeUpdateSoftBodies( int firstTriangle, int numTriangles ); + + void prepareCollisionConstraints(); + + Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a ); + + void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce ); + + + int findSoftBodyIndex( const btSoftBody* const softBody ); + + virtual void applyForces( float solverdt ); + + void updateFixedVertexPositions(); + + /** + * Integrate motion on the solver. + */ + virtual void integrate( float solverdt ); + + virtual void updateConstants( float timeStep ); + + float computeTriangleArea( + const Vectormath::Aos::Point3 &vertex0, + const Vectormath::Aos::Point3 &vertex1, + const Vectormath::Aos::Point3 &vertex2 ); + + + ////////////////////////////////////// + // Kernel dispatches + void prepareLinks(); + + void solveLinksForVelocity( int startLink, int numLinks, float kst ); + + void updatePositionsFromVelocities( float solverdt ); + + virtual void solveLinksForPosition( int startLink, int numLinks, float kst, float ti ); + + void updateVelocitiesFromPositionsWithVelocities( float isolverdt ); + + void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt ); + virtual void solveCollisionsAndUpdateVelocities( float isolverdt ); + + // End kernel dispatches + ///////////////////////////////////// + + void updateBounds(); + + void releaseKernels(); + +public: + btOpenCLSoftBodySolver(cl_command_queue queue,cl_context ctx, bool bUpdateAchchoredNodePos = false); + + virtual ~btOpenCLSoftBodySolver(); + + + + btOpenCLAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody ); + + virtual btSoftBodyLinkData &getLinkData(); + + virtual btSoftBodyVertexData &getVertexData(); + + virtual btSoftBodyTriangleData &getTriangleData(); + + virtual SolverTypes getSolverType() const + { + return CL_SOLVER; + } + + + virtual bool checkInitialized(); + + virtual void updateSoftBodies( ); + + virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false); + + virtual void copyBackToSoftBodies(bool bMove = true); + + virtual void solveConstraints( float solverdt ); + + virtual void predictMotion( float solverdt ); + + virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* ); + + virtual void processCollision( btSoftBody*, btSoftBody* ); + + virtual void setDefaultWorkgroupSize(size_t workGroupSize) + { + m_defaultWorkGroupSize = workGroupSize; + } + virtual size_t getDefaultWorkGroupSize() const + { + return m_defaultWorkGroupSize; + } + + void setCLFunctions(CLFunctions* funcs) + { + if (funcs) + m_currentCLFunctions = funcs; + else + m_currentCLFunctions = &m_defaultCLFunctions; + } + +}; // btOpenCLSoftBodySolver + + +/** + * Class to manage movement of data from a solver to a given target. + * This version is the CL to CPU version. + */ +class btSoftBodySolverOutputCLtoCPU : public btSoftBodySolverOutput +{ +protected: + +public: + btSoftBodySolverOutputCLtoCPU() + { + } + + /** Output current computed vertex data to the vertex buffers for all cloths in the solver. */ + virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ); +}; + + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.cpp b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.cpp new file mode 100644 index 0000000..32adca1 --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.cpp @@ -0,0 +1,1101 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "vectormath/vmInclude.h" +#include //@todo: remove the debugging printf at some stage +#include "btSoftBodySolver_OpenCLSIMDAware.h" +#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include + +#define WAVEFRONT_SIZE 32 +#define WAVEFRONT_BLOCK_MULTIPLIER 2 +#define GROUP_SIZE (WAVEFRONT_SIZE*WAVEFRONT_BLOCK_MULTIPLIER) +#define LINKS_PER_SIMD_LANE 16 + +static const size_t workGroupSize = GROUP_SIZE; + + +//CL_VERSION_1_1 seems broken on NVidia SDK so just disable it + +////OpenCL 1.0 kernels don't use float3 +#define MSTRINGIFY(A) #A +static const char* UpdatePositionsFromVelocitiesCLString = +#include "OpenCLC10/UpdatePositionsFromVelocities.cl" +static const char* SolvePositionsCLString = +#include "OpenCLC10/SolvePositionsSIMDBatched.cl" +static const char* UpdateNodesCLString = +#include "OpenCLC10/UpdateNodes.cl" +static const char* UpdatePositionsCLString = +#include "OpenCLC10/UpdatePositions.cl" +static const char* UpdateConstantsCLString = +#include "OpenCLC10/UpdateConstants.cl" +static const char* IntegrateCLString = +#include "OpenCLC10/Integrate.cl" +static const char* ApplyForcesCLString = +#include "OpenCLC10/ApplyForces.cl" +static const char* UpdateFixedVertexPositionsCLString = +#include "OpenCLC10/UpdateFixedVertexPositions.cl" +static const char* UpdateNormalsCLString = +#include "OpenCLC10/UpdateNormals.cl" +static const char* VSolveLinksCLString = +#include "OpenCLC10/VSolveLinks.cl" +static const char* SolveCollisionsAndUpdateVelocitiesCLString = +#include "OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl" +static const char* OutputToVertexArrayCLString = +#include "OpenCLC10/OutputToVertexArray.cl" + + + +btSoftBodyLinkDataOpenCLSIMDAware::btSoftBodyLinkDataOpenCLSIMDAware(cl_command_queue queue, cl_context ctx) : + m_cqCommandQue(queue), + m_wavefrontSize( WAVEFRONT_SIZE ), + m_linksPerWorkItem( LINKS_PER_SIMD_LANE ), + m_maxBatchesWithinWave( 0 ), + m_maxLinksPerWavefront( m_wavefrontSize * m_linksPerWorkItem ), + m_numWavefronts( 0 ), + m_maxVertex( 0 ), + m_clNumBatchesAndVerticesWithinWaves( queue, ctx, &m_numBatchesAndVerticesWithinWaves, true ), + m_clWavefrontVerticesGlobalAddresses( queue, ctx, &m_wavefrontVerticesGlobalAddresses, true ), + m_clLinkVerticesLocalAddresses( queue, ctx, &m_linkVerticesLocalAddresses, true ), + m_clLinkStrength( queue, ctx, &m_linkStrength, false ), + m_clLinksMassLSC( queue, ctx, &m_linksMassLSC, false ), + m_clLinksRestLengthSquared( queue, ctx, &m_linksRestLengthSquared, false ), + m_clLinksRestLength( queue, ctx, &m_linksRestLength, false ), + m_clLinksMaterialLinearStiffnessCoefficient( queue, ctx, &m_linksMaterialLinearStiffnessCoefficient, false ) +{ +} + +btSoftBodyLinkDataOpenCLSIMDAware::~btSoftBodyLinkDataOpenCLSIMDAware() +{ +} + +static Vectormath::Aos::Vector3 toVector3( const btVector3 &vec ) +{ + Vectormath::Aos::Vector3 outVec( vec.getX(), vec.getY(), vec.getZ() ); + return outVec; +} + +/** Allocate enough space in all link-related arrays to fit numLinks links */ +void btSoftBodyLinkDataOpenCLSIMDAware::createLinks( int numLinks ) +{ + int previousSize = m_links.size(); + int newSize = previousSize + numLinks; + + btSoftBodyLinkData::createLinks( numLinks ); + + // Resize the link addresses array as well + m_linkAddresses.resize( newSize ); +} + +/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ +void btSoftBodyLinkDataOpenCLSIMDAware::setLinkAt( + const LinkDescription &link, + int linkIndex ) +{ + btSoftBodyLinkData::setLinkAt( link, linkIndex ); + + if( link.getVertex0() > m_maxVertex ) + m_maxVertex = link.getVertex0(); + if( link.getVertex1() > m_maxVertex ) + m_maxVertex = link.getVertex1(); + + // Set the link index correctly for initialisation + m_linkAddresses[linkIndex] = linkIndex; +} + +bool btSoftBodyLinkDataOpenCLSIMDAware::onAccelerator() +{ + return m_onGPU; +} + +bool btSoftBodyLinkDataOpenCLSIMDAware::moveToAccelerator() +{ + bool success = true; + success = success && m_clNumBatchesAndVerticesWithinWaves.moveToGPU(); + success = success && m_clWavefrontVerticesGlobalAddresses.moveToGPU(); + success = success && m_clLinkVerticesLocalAddresses.moveToGPU(); + success = success && m_clLinkStrength.moveToGPU(); + success = success && m_clLinksMassLSC.moveToGPU(); + success = success && m_clLinksRestLengthSquared.moveToGPU(); + success = success && m_clLinksRestLength.moveToGPU(); + success = success && m_clLinksMaterialLinearStiffnessCoefficient.moveToGPU(); + + if( success ) { + m_onGPU = true; + } + + return success; +} + +bool btSoftBodyLinkDataOpenCLSIMDAware::moveFromAccelerator() +{ + bool success = true; + success = success && m_clNumBatchesAndVerticesWithinWaves.moveToGPU(); + success = success && m_clWavefrontVerticesGlobalAddresses.moveToGPU(); + success = success && m_clLinkVerticesLocalAddresses.moveToGPU(); + success = success && m_clLinkStrength.moveFromGPU(); + success = success && m_clLinksMassLSC.moveFromGPU(); + success = success && m_clLinksRestLengthSquared.moveFromGPU(); + success = success && m_clLinksRestLength.moveFromGPU(); + success = success && m_clLinksMaterialLinearStiffnessCoefficient.moveFromGPU(); + + if( success ) { + m_onGPU = false; + } + + return success; +} + + + + + + + + +btOpenCLSoftBodySolverSIMDAware::btOpenCLSoftBodySolverSIMDAware(cl_command_queue queue, cl_context ctx, bool bUpdateAchchoredNodePos) : + btOpenCLSoftBodySolver( queue, ctx, bUpdateAchchoredNodePos ), + m_linkData(queue, ctx) +{ + // Initial we will clearly need to update solver constants + // For now this is global for the cloths linked with this solver - we should probably make this body specific + // for performance in future once we understand more clearly when constants need to be updated + m_updateSolverConstants = true; + + m_shadersInitialized = false; +} + +btOpenCLSoftBodySolverSIMDAware::~btOpenCLSoftBodySolverSIMDAware() +{ + releaseKernels(); +} + +void btOpenCLSoftBodySolverSIMDAware::optimize( btAlignedObjectArray< btSoftBody * > &softBodies ,bool forceUpdate) +{ + if( forceUpdate || m_softBodySet.size() != softBodies.size() ) + { + // Have a change in the soft body set so update, reloading all the data + getVertexData().clear(); + getTriangleData().clear(); + getLinkData().clear(); + m_softBodySet.resize(0); + m_anchorIndex.clear(); + + int maxPiterations = 0; + int maxViterations = 0; + + for( int softBodyIndex = 0; softBodyIndex < softBodies.size(); ++softBodyIndex ) + { + btSoftBody *softBody = softBodies[ softBodyIndex ]; + using Vectormath::Aos::Matrix3; + using Vectormath::Aos::Point3; + + // Create SoftBody that will store the information within the solver + btOpenCLAcceleratedSoftBodyInterface* newSoftBody = new btOpenCLAcceleratedSoftBodyInterface( softBody ); + m_softBodySet.push_back( newSoftBody ); + + m_perClothAcceleration.push_back( toVector3(softBody->getWorldInfo()->m_gravity) ); + m_perClothDampingFactor.push_back(softBody->m_cfg.kDP); + m_perClothVelocityCorrectionCoefficient.push_back( softBody->m_cfg.kVCF ); + m_perClothLiftFactor.push_back( softBody->m_cfg.kLF ); + m_perClothDragFactor.push_back( softBody->m_cfg.kDG ); + m_perClothMediumDensity.push_back(softBody->getWorldInfo()->air_density); + // Simple init values. Actually we'll put 0 and -1 into them at the appropriate time + m_perClothFriction.push_back(softBody->m_cfg.kDF); + m_perClothCollisionObjects.push_back( CollisionObjectIndices(-1, -1) ); + + // Add space for new vertices and triangles in the default solver for now + // TODO: Include space here for tearing too later + int firstVertex = getVertexData().getNumVertices(); + int numVertices = softBody->m_nodes.size(); + // Round maxVertices to a multiple of the workgroup size so we know we're safe to run over in a given group + // maxVertices can be increased to allow tearing, but should be used sparingly because these extra verts will always be processed + int maxVertices = GROUP_SIZE*((numVertices+GROUP_SIZE)/GROUP_SIZE); + // Allocate space for new vertices in all the vertex arrays + getVertexData().createVertices( numVertices, softBodyIndex, maxVertices ); + + + int firstTriangle = getTriangleData().getNumTriangles(); + int numTriangles = softBody->m_faces.size(); + int maxTriangles = numTriangles; + getTriangleData().createTriangles( maxTriangles ); + + // Copy vertices from softbody into the solver + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + Point3 multPoint(softBody->m_nodes[vertex].m_x.getX(), softBody->m_nodes[vertex].m_x.getY(), softBody->m_nodes[vertex].m_x.getZ()); + btSoftBodyVertexData::VertexDescription desc; + + // TODO: Position in the softbody might be pre-transformed + // or we may need to adapt for the pose. + //desc.setPosition( cloth.getMeshTransform()*multPoint ); + desc.setPosition( multPoint ); + + float vertexInverseMass = softBody->m_nodes[vertex].m_im; + desc.setInverseMass(vertexInverseMass); + getVertexData().setVertexAt( desc, firstVertex + vertex ); + + m_anchorIndex.push_back(-1); + } + for( int vertex = numVertices; vertex < maxVertices; ++vertex ) + { + m_anchorIndex.push_back(-1.0); + } + + // Copy triangles similarly + // We're assuming here that vertex indices are based on the firstVertex rather than the entire scene + for( int triangle = 0; triangle < numTriangles; ++triangle ) + { + // Note that large array storage is relative to the array not to the cloth + // So we need to add firstVertex to each value + int vertexIndex0 = (softBody->m_faces[triangle].m_n[0] - &(softBody->m_nodes[0])); + int vertexIndex1 = (softBody->m_faces[triangle].m_n[1] - &(softBody->m_nodes[0])); + int vertexIndex2 = (softBody->m_faces[triangle].m_n[2] - &(softBody->m_nodes[0])); + btSoftBodyTriangleData::TriangleDescription newTriangle(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, vertexIndex2 + firstVertex); + getTriangleData().setTriangleAt( newTriangle, firstTriangle + triangle ); + + // Increase vertex triangle counts for this triangle + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex0)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex1)++; + getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex2)++; + } + + int firstLink = getLinkData().getNumLinks(); + int numLinks = softBody->m_links.size(); + int maxLinks = numLinks; + + // Allocate space for the links + getLinkData().createLinks( numLinks ); + + // Add the links + for( int link = 0; link < numLinks; ++link ) + { + int vertexIndex0 = softBody->m_links[link].m_n[0] - &(softBody->m_nodes[0]); + int vertexIndex1 = softBody->m_links[link].m_n[1] - &(softBody->m_nodes[0]); + + btSoftBodyLinkData::LinkDescription newLink(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, softBody->m_links[link].m_material->m_kLST); + newLink.setLinkStrength(1.f); + getLinkData().setLinkAt(newLink, firstLink + link); + } + + newSoftBody->setFirstVertex( firstVertex ); + newSoftBody->setFirstTriangle( firstTriangle ); + newSoftBody->setNumVertices( numVertices ); + newSoftBody->setMaxVertices( maxVertices ); + newSoftBody->setNumTriangles( numTriangles ); + newSoftBody->setMaxTriangles( maxTriangles ); + newSoftBody->setFirstLink( firstLink ); + newSoftBody->setNumLinks( numLinks ); + + // Find maximum piterations and viterations + int piterations = softBody->m_cfg.piterations; + + if ( piterations > maxPiterations ) + maxPiterations = piterations; + + int viterations = softBody->m_cfg.viterations; + + if ( viterations > maxViterations ) + maxViterations = viterations; + + // zero mass + for( int vertex = 0; vertex < numVertices; ++vertex ) + { + if ( softBody->m_nodes[vertex].m_im == 0 ) + { + AnchorNodeInfoCL nodeInfo; + nodeInfo.clVertexIndex = firstVertex + vertex; + nodeInfo.pNode = &softBody->m_nodes[vertex]; + + m_anchorNodeInfoArray.push_back(nodeInfo); + } + } + + // anchor position + if ( numVertices > 0 ) + { + for ( int anchorIndex = 0; anchorIndex < softBody->m_anchors.size(); anchorIndex++ ) + { + btSoftBody::Node* anchorNode = softBody->m_anchors[anchorIndex].m_node; + btSoftBody::Node* firstNode = &softBody->m_nodes[0]; + + AnchorNodeInfoCL nodeInfo; + nodeInfo.clVertexIndex = firstVertex + (int)(anchorNode - firstNode); + nodeInfo.pNode = anchorNode; + + m_anchorNodeInfoArray.push_back(nodeInfo); + } + } + } + + m_anchorPosition.clear(); + m_anchorPosition.resize(m_anchorNodeInfoArray.size()); + + for ( int anchorNode = 0; anchorNode < m_anchorNodeInfoArray.size(); anchorNode++ ) + { + const AnchorNodeInfoCL& anchorNodeInfo = m_anchorNodeInfoArray[anchorNode]; + m_anchorIndex[anchorNodeInfo.clVertexIndex] = anchorNode; + getVertexData().getInverseMass(anchorNodeInfo.clVertexIndex) = 0.0f; + } + + updateConstants(0.f); + + // set position and velocity iterations + setNumberOfPositionIterations(maxPiterations); + setNumberOfVelocityIterations(maxViterations); + + // set wind velocity + m_perClothWindVelocity.resize( m_softBodySet.size() ); + for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex ) + { + btSoftBody *softBody = m_softBodySet[softBodyIndex]->getSoftBody(); + m_perClothWindVelocity[softBodyIndex] = toVector3(softBody->getWindVelocity()); + } + + m_clPerClothWindVelocity.changedOnCPU(); + + // generate batches + m_linkData.generateBatches(); + m_triangleData.generateBatches(); + + // Build the shaders to match the batching parameters + buildShaders(); + } +} + + +btSoftBodyLinkData &btOpenCLSoftBodySolverSIMDAware::getLinkData() +{ + // TODO: Consider setting link data to "changed" here + return m_linkData; +} + + + + +void btOpenCLSoftBodySolverSIMDAware::updateConstants( float timeStep ) +{ + + using namespace Vectormath::Aos; + + if( m_updateSolverConstants ) + { + m_updateSolverConstants = false; + + // Will have to redo this if we change the structure (tear, maybe) or various other possible changes + + // Initialise link constants + const int numLinks = m_linkData.getNumLinks(); + for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair &vertices( m_linkData.getVertexPair(linkIndex) ); + m_linkData.getRestLength(linkIndex) = length((m_vertexData.getPosition( vertices.vertex0 ) - m_vertexData.getPosition( vertices.vertex1 ))); + float invMass0 = m_vertexData.getInverseMass(vertices.vertex0); + float invMass1 = m_vertexData.getInverseMass(vertices.vertex1); + float linearStiffness = m_linkData.getLinearStiffnessCoefficient(linkIndex); + float massLSC = (invMass0 + invMass1)/linearStiffness; + m_linkData.getMassLSC(linkIndex) = massLSC; + float restLength = m_linkData.getRestLength(linkIndex); + float restLengthSquared = restLength*restLength; + m_linkData.getRestLengthSquared(linkIndex) = restLengthSquared; + } + } + +} + + + +void btOpenCLSoftBodySolverSIMDAware::solveConstraints( float solverdt ) +{ + + using Vectormath::Aos::Vector3; + using Vectormath::Aos::Point3; + using Vectormath::Aos::lengthSqr; + using Vectormath::Aos::dot; + + // Prepare links + int numLinks = m_linkData.getNumLinks(); + int numVertices = m_vertexData.getNumVertices(); + + float kst = 1.f; + float ti = 0.f; + + + m_clPerClothDampingFactor.moveToGPU(); + m_clPerClothVelocityCorrectionCoefficient.moveToGPU(); + + + // Ensure data is on accelerator + m_linkData.moveToAccelerator(); + m_vertexData.moveToAccelerator(); + + + //prepareLinks(); + + prepareCollisionConstraints(); + + // Solve drift + for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + { + + for( int i = 0; i < m_linkData.m_wavefrontBatchStartLengths.size(); ++i ) + { + int startWave = m_linkData.m_wavefrontBatchStartLengths[i].start; + int numWaves = m_linkData.m_wavefrontBatchStartLengths[i].length; + solveLinksForPosition( startWave, numWaves, kst, ti ); + } + } // for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration ) + + + // At this point assume that the force array is blank - we will overwrite it + solveCollisionsAndUpdateVelocities( 1.f/solverdt ); +} + + +////////////////////////////////////// +// Kernel dispatches + + +void btOpenCLSoftBodySolverSIMDAware::solveLinksForPosition( int startWave, int numWaves, float kst, float ti ) +{ + cl_int ciErrNum; + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,0, sizeof(int), &startWave); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,1, sizeof(int), &numWaves); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,2, sizeof(float), &kst); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,3, sizeof(float), &ti); + + + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,4, sizeof(cl_mem), &m_linkData.m_clNumBatchesAndVerticesWithinWaves.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,5, sizeof(cl_mem), &m_linkData.m_clWavefrontVerticesGlobalAddresses.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,6, sizeof(cl_mem), &m_linkData.m_clLinkVerticesLocalAddresses.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,7, sizeof(cl_mem), &m_linkData.m_clLinksMassLSC.m_buffer); + + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,8, sizeof(cl_mem), &m_linkData.m_clLinksRestLengthSquared.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,9, sizeof(cl_mem), &m_vertexData.m_clVertexInverseMass.m_buffer); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,10, sizeof(cl_mem), &m_vertexData.m_clVertexPosition.m_buffer); + + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,11, WAVEFRONT_BLOCK_MULTIPLIER*sizeof(cl_int2), 0); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,12, m_linkData.getMaxVerticesPerWavefront()*WAVEFRONT_BLOCK_MULTIPLIER*sizeof(cl_float4), 0); + ciErrNum = clSetKernelArg(m_solvePositionsFromLinksKernel,13, m_linkData.getMaxVerticesPerWavefront()*WAVEFRONT_BLOCK_MULTIPLIER*sizeof(cl_float), 0); + + size_t numWorkItems = workGroupSize*((numWaves*WAVEFRONT_SIZE + (workGroupSize-1)) / workGroupSize); + + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_solvePositionsFromLinksKernel,1,NULL,&numWorkItems,&workGroupSize,0,0,0); + + if( ciErrNum!= CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_solvePositionsFromLinksKernel)"); + } + +} // solveLinksForPosition + +void btOpenCLSoftBodySolverSIMDAware::solveCollisionsAndUpdateVelocities( float isolverdt ) +{ + // Copy kernel parameters to GPU + m_vertexData.moveToAccelerator(); + m_clPerClothFriction.moveToGPU(); + m_clPerClothDampingFactor.moveToGPU(); + m_clPerClothCollisionObjects.moveToGPU(); + m_clCollisionObjectDetails.moveToGPU(); + + cl_int ciErrNum; + int numVerts = m_vertexData.getNumVertices(); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 0, sizeof(int), &numVerts); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 1, sizeof(int), &isolverdt); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 2, sizeof(cl_mem),&m_vertexData.m_clClothIdentifier.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 3, sizeof(cl_mem),&m_vertexData.m_clVertexPreviousPosition.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 4, sizeof(cl_mem),&m_clPerClothFriction.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 5, sizeof(cl_mem),&m_clPerClothDampingFactor.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 6, sizeof(cl_mem),&m_clPerClothCollisionObjects.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 7, sizeof(cl_mem),&m_clCollisionObjectDetails.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 8, sizeof(cl_mem),&m_vertexData.m_clVertexForceAccumulator.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 9, sizeof(cl_mem),&m_vertexData.m_clVertexVelocity.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 10, sizeof(cl_mem),&m_vertexData.m_clVertexPosition.m_buffer); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 11, sizeof(CollisionShapeDescription)*16,0); + ciErrNum = clSetKernelArg(m_solveCollisionsAndUpdateVelocitiesKernel, 12, sizeof(cl_mem),&m_vertexData.m_clVertexInverseMass.m_buffer); + size_t numWorkItems = workGroupSize*((m_vertexData.getNumVertices() + (workGroupSize-1)) / workGroupSize); + + if (numWorkItems) + { + ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue,m_solveCollisionsAndUpdateVelocitiesKernel, 1, NULL, &numWorkItems, &workGroupSize,0,0,0); + + if( ciErrNum != CL_SUCCESS ) + { + btAssert( 0 && "enqueueNDRangeKernel(m_solveCollisionsAndUpdateVelocitiesKernel)"); + } + } + +} // btOpenCLSoftBodySolverSIMDAware::updateVelocitiesFromPositionsWithoutVelocities + +// End kernel dispatches +///////////////////////////////////// + + + +bool btOpenCLSoftBodySolverSIMDAware::buildShaders() +{ + releaseKernels(); + + if( m_shadersInitialized ) + return true; + + const char* additionalMacros=""; + + m_currentCLFunctions->clearKernelCompilationFailures(); + + char *wavefrontMacros = new char[256]; + + sprintf( + wavefrontMacros, + "-DMAX_NUM_VERTICES_PER_WAVE=%d -DMAX_BATCHES_PER_WAVE=%d -DWAVEFRONT_SIZE=%d -DWAVEFRONT_BLOCK_MULTIPLIER=%d -DBLOCK_SIZE=%d", + m_linkData.getMaxVerticesPerWavefront(), + m_linkData.getMaxBatchesPerWavefront(), + m_linkData.getWavefrontSize(), + WAVEFRONT_BLOCK_MULTIPLIER, + WAVEFRONT_BLOCK_MULTIPLIER*m_linkData.getWavefrontSize()); + + m_updatePositionsFromVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdatePositionsFromVelocitiesCLString, "UpdatePositionsFromVelocitiesKernel", additionalMacros,"OpenCLC10/UpdatePositionsFromVelocities.cl"); + m_solvePositionsFromLinksKernel = m_currentCLFunctions->compileCLKernelFromString( SolvePositionsCLString, "SolvePositionsFromLinksKernel", wavefrontMacros ,"OpenCLC10/SolvePositionsSIMDBatched.cl"); + m_updateVelocitiesFromPositionsWithVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNodesCLString, "updateVelocitiesFromPositionsWithVelocitiesKernel", additionalMacros ,"OpenCLC10/UpdateNodes.cl"); + m_updateVelocitiesFromPositionsWithoutVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdatePositionsCLString, "updateVelocitiesFromPositionsWithoutVelocitiesKernel", additionalMacros,"OpenCLC10/UpdatePositions.cl"); + m_integrateKernel = m_currentCLFunctions->compileCLKernelFromString( IntegrateCLString, "IntegrateKernel", additionalMacros ,"OpenCLC10/Integrate.cl"); + m_applyForcesKernel = m_currentCLFunctions->compileCLKernelFromString( ApplyForcesCLString, "ApplyForcesKernel", additionalMacros,"OpenCLC10/ApplyForces.cl" ); + m_updateFixedVertexPositionsKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateFixedVertexPositionsCLString, "UpdateFixedVertexPositions" ,additionalMacros,"OpenCLC10/UpdateFixedVertexPositions.cl"); + m_solveCollisionsAndUpdateVelocitiesKernel = m_currentCLFunctions->compileCLKernelFromString( SolveCollisionsAndUpdateVelocitiesCLString, "SolveCollisionsAndUpdateVelocitiesKernel", additionalMacros ,"OpenCLC10/SolveCollisionsAndUpdateVelocitiesSIMDBatched.cl"); + + // TODO: Rename to UpdateSoftBodies + m_resetNormalsAndAreasKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNormalsCLString, "ResetNormalsAndAreasKernel", additionalMacros ,"OpenCLC10/UpdateNormals.cl"); + m_normalizeNormalsAndAreasKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNormalsCLString, "NormalizeNormalsAndAreasKernel", additionalMacros ,"OpenCLC10/UpdateNormals.cl"); + m_updateSoftBodiesKernel = m_currentCLFunctions->compileCLKernelFromString( UpdateNormalsCLString, "UpdateSoftBodiesKernel", additionalMacros ,"OpenCLC10/UpdateNormals.cl"); + + delete [] wavefrontMacros; + + if( m_currentCLFunctions->getKernelCompilationFailures()==0) + { + m_shadersInitialized = true; + } + + return m_shadersInitialized; +} + + + + +static Vectormath::Aos::Transform3 toTransform3( const btTransform &transform ) +{ + Vectormath::Aos::Transform3 outTransform; + outTransform.setCol(0, toVector3(transform.getBasis().getColumn(0))); + outTransform.setCol(1, toVector3(transform.getBasis().getColumn(1))); + outTransform.setCol(2, toVector3(transform.getBasis().getColumn(2))); + outTransform.setCol(3, toVector3(transform.getOrigin())); + return outTransform; +} + + +static void generateBatchesOfWavefronts( btAlignedObjectArray < btAlignedObjectArray > &linksForWavefronts, btSoftBodyLinkData &linkData, int numVertices, btAlignedObjectArray < btAlignedObjectArray > &wavefrontBatches ) +{ + // A per-batch map of truth values stating whether a given vertex is in that batch + // This allows us to significantly optimize the batching + btAlignedObjectArray > mapOfVerticesInBatches; + + for( int waveIndex = 0; waveIndex < linksForWavefronts.size(); ++waveIndex ) + { + btAlignedObjectArray &wavefront( linksForWavefronts[waveIndex] ); + + int batch = 0; + bool placed = false; + while( batch < wavefrontBatches.size() && !placed ) + { + // Test the current batch, see if this wave shares any vertex with the waves in the batch + bool foundSharedVertex = false; + for( int link = 0; link < wavefront.size(); ++link ) + { + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( wavefront[link] ); + if( (mapOfVerticesInBatches[batch])[vertices.vertex0] || (mapOfVerticesInBatches[batch])[vertices.vertex1] ) + { + foundSharedVertex = true; + } + } + + if( !foundSharedVertex ) + { + wavefrontBatches[batch].push_back( waveIndex ); + // Insert vertices into this batch too + for( int link = 0; link < wavefront.size(); ++link ) + { + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( wavefront[link] ); + (mapOfVerticesInBatches[batch])[vertices.vertex0] = true; + (mapOfVerticesInBatches[batch])[vertices.vertex1] = true; + } + placed = true; + } + batch++; + } + if( batch == wavefrontBatches.size() && !placed ) + { + wavefrontBatches.resize( batch + 1 ); + wavefrontBatches[batch].push_back( waveIndex ); + + // And resize map as well + mapOfVerticesInBatches.resize( batch + 1 ); + + // Resize maps with total number of vertices + mapOfVerticesInBatches[batch].resize( numVertices+1, false ); + + // Insert vertices into this batch too + for( int link = 0; link < wavefront.size(); ++link ) + { + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( wavefront[link] ); + (mapOfVerticesInBatches[batch])[vertices.vertex0] = true; + (mapOfVerticesInBatches[batch])[vertices.vertex1] = true; + } + } + } + mapOfVerticesInBatches.clear(); +} + +// Function to remove an object from a vector maintaining correct ordering of the vector +template< typename T > static void removeFromVector( btAlignedObjectArray< T > &vectorToUpdate, int indexToRemove ) +{ + int currentSize = vectorToUpdate.size(); + for( int i = indexToRemove; i < (currentSize-1); ++i ) + { + vectorToUpdate[i] = vectorToUpdate[i+1]; + } + if( currentSize > 0 ) + vectorToUpdate.resize( currentSize - 1 ); +} + +/** + * Insert element into vectorToUpdate at index index. + */ +template< typename T > static void insertAtIndex( btAlignedObjectArray< T > &vectorToUpdate, int index, T element ) +{ + vectorToUpdate.resize( vectorToUpdate.size() + 1 ); + for( int i = (vectorToUpdate.size() - 1); i > index; --i ) + { + vectorToUpdate[i] = vectorToUpdate[i-1]; + } + vectorToUpdate[index] = element; +} + +/** + * Insert into btAlignedObjectArray assuming the array is ordered and maintaining both ordering and uniqueness. + * ie it treats vectorToUpdate as an ordered set. + */ +template< typename T > static void insertUniqueAndOrderedIntoVector( btAlignedObjectArray &vectorToUpdate, T element ) +{ + int index = 0; + while( index < vectorToUpdate.size() && vectorToUpdate[index] < element ) + { + index++; + } + if( index == vectorToUpdate.size() || vectorToUpdate[index] != element ) + insertAtIndex( vectorToUpdate, index, element ); +} + +static void generateLinksPerVertex( int numVertices, btSoftBodyLinkData &linkData, btAlignedObjectArray< int > &listOfLinksPerVertex, btAlignedObjectArray &numLinksPerVertex, int &maxLinks ) +{ + for( int linkIndex = 0; linkIndex < linkData.getNumLinks(); ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair nodes( linkData.getVertexPair(linkIndex) ); + numLinksPerVertex[nodes.vertex0]++; + numLinksPerVertex[nodes.vertex1]++; + } + int maxLinksPerVertex = 0; + for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex ) + { + maxLinksPerVertex = btMax(numLinksPerVertex[vertexIndex], maxLinksPerVertex); + } + maxLinks = maxLinksPerVertex; + + btAlignedObjectArray< int > linksFoundPerVertex; + linksFoundPerVertex.resize( numVertices, 0 ); + + listOfLinksPerVertex.resize( maxLinksPerVertex * numVertices ); + + for( int linkIndex = 0; linkIndex < linkData.getNumLinks(); ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair nodes( linkData.getVertexPair(linkIndex) ); + { + // Do vertex 0 + int vertexIndex = nodes.vertex0; + int linkForVertex = linksFoundPerVertex[nodes.vertex0]; + int linkAddress = vertexIndex * maxLinksPerVertex + linkForVertex; + + listOfLinksPerVertex[linkAddress] = linkIndex; + + linksFoundPerVertex[nodes.vertex0] = linkForVertex + 1; + } + { + // Do vertex 1 + int vertexIndex = nodes.vertex1; + int linkForVertex = linksFoundPerVertex[nodes.vertex1]; + int linkAddress = vertexIndex * maxLinksPerVertex + linkForVertex; + + listOfLinksPerVertex[linkAddress] = linkIndex; + + linksFoundPerVertex[nodes.vertex1] = linkForVertex + 1; + } + } +} + +static void computeBatchingIntoWavefronts( + btSoftBodyLinkData &linkData, + int wavefrontSize, + int linksPerWorkItem, + int maxLinksPerWavefront, + btAlignedObjectArray < btAlignedObjectArray > &linksForWavefronts, + btAlignedObjectArray< btAlignedObjectArray < btAlignedObjectArray > > &batchesWithinWaves, /* wave, batch, links in batch */ + btAlignedObjectArray< btAlignedObjectArray< int > > &verticesForWavefronts /* wavefront, vertex */ + ) +{ + + + // Attempt generation of larger batches of links. + btAlignedObjectArray< bool > processedLink; + processedLink.resize( linkData.getNumLinks() ); + btAlignedObjectArray< int > listOfLinksPerVertex; + int maxLinksPerVertex = 0; + + // Count num vertices + int numVertices = 0; + for( int linkIndex = 0; linkIndex < linkData.getNumLinks(); ++linkIndex ) + { + btSoftBodyLinkData::LinkNodePair nodes( linkData.getVertexPair(linkIndex) ); + numVertices = btMax( numVertices, nodes.vertex0 + 1 ); + numVertices = btMax( numVertices, nodes.vertex1 + 1 ); + } + + // Need list of links per vertex + // Compute valence of each vertex + btAlignedObjectArray numLinksPerVertex; + numLinksPerVertex.resize(0); + numLinksPerVertex.resize( numVertices, 0 ); + + generateLinksPerVertex( numVertices, linkData, listOfLinksPerVertex, numLinksPerVertex, maxLinksPerVertex ); + + if (!numVertices) + return; + + for( int vertex = 0; vertex < 10; ++vertex ) + { + for( int link = 0; link < numLinksPerVertex[vertex]; ++link ) + { + int linkAddress = vertex * maxLinksPerVertex + link; + } + } + + + // At this point we know what links we have for each vertex so we can start batching + + // We want a vertex to start with, let's go with 0 + int currentVertex = 0; + int linksProcessed = 0; + + btAlignedObjectArray verticesToProcess; + + while( linksProcessed < linkData.getNumLinks() ) + { + // Next wavefront + int nextWavefront = linksForWavefronts.size(); + linksForWavefronts.resize( nextWavefront + 1 ); + btAlignedObjectArray &linksForWavefront(linksForWavefronts[nextWavefront]); + verticesForWavefronts.resize( nextWavefront + 1 ); + btAlignedObjectArray &vertexSet( verticesForWavefronts[nextWavefront] ); + + linksForWavefront.resize(0); + + // Loop to find enough links to fill the wavefront + // Stopping if we either run out of links, or fill it + while( linksProcessed < linkData.getNumLinks() && linksForWavefront.size() < maxLinksPerWavefront ) + { + // Go through the links for the current vertex + for( int link = 0; link < numLinksPerVertex[currentVertex] && linksForWavefront.size() < maxLinksPerWavefront; ++link ) + { + int linkAddress = currentVertex * maxLinksPerVertex + link; + int linkIndex = listOfLinksPerVertex[linkAddress]; + + // If we have not already processed this link, add it to the wavefront + // Claim it as another processed link + // Add the vertex at the far end to the list of vertices to process. + if( !processedLink[linkIndex] ) + { + linksForWavefront.push_back( linkIndex ); + linksProcessed++; + processedLink[linkIndex] = true; + int v0 = linkData.getVertexPair(linkIndex).vertex0; + int v1 = linkData.getVertexPair(linkIndex).vertex1; + if( v0 == currentVertex ) + verticesToProcess.push_back( v1 ); + else + verticesToProcess.push_back( v0 ); + } + } + if( verticesToProcess.size() > 0 ) + { + // Get the element on the front of the queue and remove it + currentVertex = verticesToProcess[0]; + removeFromVector( verticesToProcess, 0 ); + } else { + // If we've not yet processed all the links, find the first unprocessed one + // and select one of its vertices as the current vertex + if( linksProcessed < linkData.getNumLinks() ) + { + int searchLink = 0; + while( processedLink[searchLink] ) + searchLink++; + currentVertex = linkData.getVertexPair(searchLink).vertex0; + } + } + } + + // We have either finished or filled a wavefront + for( int link = 0; link < linksForWavefront.size(); ++link ) + { + int v0 = linkData.getVertexPair( linksForWavefront[link] ).vertex0; + int v1 = linkData.getVertexPair( linksForWavefront[link] ).vertex1; + insertUniqueAndOrderedIntoVector( vertexSet, v0 ); + insertUniqueAndOrderedIntoVector( vertexSet, v1 ); + } + // Iterate over links mapped to the wave and batch those + // We can run a batch on each cycle trivially + + batchesWithinWaves.resize( batchesWithinWaves.size() + 1 ); + btAlignedObjectArray < btAlignedObjectArray > &batchesWithinWave( batchesWithinWaves[batchesWithinWaves.size()-1] ); + + + for( int link = 0; link < linksForWavefront.size(); ++link ) + { + int linkIndex = linksForWavefront[link]; + btSoftBodyLinkData::LinkNodePair vertices = linkData.getVertexPair( linkIndex ); + + int batch = 0; + bool placed = false; + while( batch < batchesWithinWave.size() && !placed ) + { + bool foundSharedVertex = false; + if( batchesWithinWave[batch].size() >= wavefrontSize ) + { + // If we have already filled this batch, move on to another + foundSharedVertex = true; + } else { + for( int link2 = 0; link2 < batchesWithinWave[batch].size(); ++link2 ) + { + btSoftBodyLinkData::LinkNodePair vertices2 = linkData.getVertexPair( (batchesWithinWave[batch])[link2] ); + + if( vertices.vertex0 == vertices2.vertex0 || + vertices.vertex1 == vertices2.vertex0 || + vertices.vertex0 == vertices2.vertex1 || + vertices.vertex1 == vertices2.vertex1 ) + { + foundSharedVertex = true; + break; + } + } + } + if( !foundSharedVertex ) + { + batchesWithinWave[batch].push_back( linkIndex ); + placed = true; + } else { + ++batch; + } + } + if( batch == batchesWithinWave.size() && !placed ) + { + batchesWithinWave.resize( batch + 1 ); + batchesWithinWave[batch].push_back( linkIndex ); + } + } + + } + +} + +void btSoftBodyLinkDataOpenCLSIMDAware::generateBatches() +{ + btAlignedObjectArray < btAlignedObjectArray > linksForWavefronts; + btAlignedObjectArray < btAlignedObjectArray > wavefrontBatches; + btAlignedObjectArray< btAlignedObjectArray < btAlignedObjectArray > > batchesWithinWaves; + btAlignedObjectArray< btAlignedObjectArray< int > > verticesForWavefronts; // wavefronts, vertices in wavefront as an ordered set + + // Group the links into wavefronts + computeBatchingIntoWavefronts( *this, m_wavefrontSize, m_linksPerWorkItem, m_maxLinksPerWavefront, linksForWavefronts, batchesWithinWaves, verticesForWavefronts ); + + + // Batch the wavefronts + generateBatchesOfWavefronts( linksForWavefronts, *this, m_maxVertex, wavefrontBatches ); + + m_numWavefronts = linksForWavefronts.size(); + + // At this point we have a description of which links we need to process in each wavefront + + // First correctly fill the batch ranges vector + int numBatches = wavefrontBatches.size(); + m_wavefrontBatchStartLengths.resize(0); + int prefixSum = 0; + for( int batchIndex = 0; batchIndex < numBatches; ++batchIndex ) + { + int wavesInBatch = wavefrontBatches[batchIndex].size(); + int nextPrefixSum = prefixSum + wavesInBatch; + m_wavefrontBatchStartLengths.push_back( BatchPair( prefixSum, nextPrefixSum - prefixSum ) ); + + prefixSum += wavesInBatch; + } + + // Also find max number of batches within a wave + m_maxBatchesWithinWave = 0; + m_maxVerticesWithinWave = 0; + m_numBatchesAndVerticesWithinWaves.resize( m_numWavefronts ); + for( int waveIndex = 0; waveIndex < m_numWavefronts; ++waveIndex ) + { + // See if the number of batches in this wave is greater than the current maxium + int batchesInCurrentWave = batchesWithinWaves[waveIndex].size(); + int verticesInCurrentWave = verticesForWavefronts[waveIndex].size(); + m_maxBatchesWithinWave = btMax( batchesInCurrentWave, m_maxBatchesWithinWave ); + m_maxVerticesWithinWave = btMax( verticesInCurrentWave, m_maxVerticesWithinWave ); + } + + // Add padding values both for alignment and as dudd addresses within LDS to compute junk rather than branch around + m_maxVerticesWithinWave = 16*((m_maxVerticesWithinWave/16)+2); + + // Now we know the maximum number of vertices per-wave we can resize the global vertices array + m_wavefrontVerticesGlobalAddresses.resize( m_maxVerticesWithinWave * m_numWavefronts ); + + // Grab backup copies of all the link data arrays for the sorting process + btAlignedObjectArray m_links_Backup(m_links); + btAlignedObjectArray m_linkStrength_Backup(m_linkStrength); + btAlignedObjectArray m_linksMassLSC_Backup(m_linksMassLSC); + btAlignedObjectArray m_linksRestLengthSquared_Backup(m_linksRestLengthSquared); + //btAlignedObjectArray m_linksCLength_Backup(m_linksCLength); + //btAlignedObjectArray m_linksLengthRatio_Backup(m_linksLengthRatio); + btAlignedObjectArray m_linksRestLength_Backup(m_linksRestLength); + btAlignedObjectArray m_linksMaterialLinearStiffnessCoefficient_Backup(m_linksMaterialLinearStiffnessCoefficient); + + // Resize to a wavefront sized batch per batch per wave so we get perfectly coherent memory accesses. + m_links.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linkVerticesLocalAddresses.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linkStrength.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksMassLSC.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksRestLengthSquared.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksRestLength.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + m_linksMaterialLinearStiffnessCoefficient.resize( m_maxBatchesWithinWave * m_wavefrontSize * m_numWavefronts ); + + // Then re-order links into wavefront blocks + + // Total number of wavefronts moved. This will decide the ordering of sorted wavefronts. + int wavefrontCount = 0; + + // Iterate over batches of wavefronts, then wavefronts in the batch + for( int batchIndex = 0; batchIndex < numBatches; ++batchIndex ) + { + btAlignedObjectArray &batch( wavefrontBatches[batchIndex] ); + int wavefrontsInBatch = batch.size(); + + + for( int wavefrontIndex = 0; wavefrontIndex < wavefrontsInBatch; ++wavefrontIndex ) + { + + int originalWavefrontIndex = batch[wavefrontIndex]; + btAlignedObjectArray< int > &wavefrontVertices( verticesForWavefronts[originalWavefrontIndex] ); + int verticesUsedByWavefront = wavefrontVertices.size(); + + // Copy the set of vertices into the correctly structured array for use on the device + // Fill the non-vertices with -1s + // so we can mask out those reads + for( int vertex = 0; vertex < verticesUsedByWavefront; ++vertex ) + { + m_wavefrontVerticesGlobalAddresses[m_maxVerticesWithinWave * wavefrontCount + vertex] = wavefrontVertices[vertex]; + } + for( int vertex = verticesUsedByWavefront; vertex < m_maxVerticesWithinWave; ++vertex ) + { + m_wavefrontVerticesGlobalAddresses[m_maxVerticesWithinWave * wavefrontCount + vertex] = -1; + } + + // Obtain the set of batches within the current wavefront + btAlignedObjectArray < btAlignedObjectArray > &batchesWithinWavefront( batchesWithinWaves[originalWavefrontIndex] ); + // Set the size of the batches for use in the solver, correctly ordered + NumBatchesVerticesPair batchesAndVertices; + batchesAndVertices.numBatches = batchesWithinWavefront.size(); + batchesAndVertices.numVertices = verticesUsedByWavefront; + m_numBatchesAndVerticesWithinWaves[wavefrontCount] = batchesAndVertices; + + + // Now iterate over batches within the wavefront to structure the links correctly + for( int wavefrontBatch = 0; wavefrontBatch < batchesWithinWavefront.size(); ++wavefrontBatch ) + { + btAlignedObjectArray &linksInBatch( batchesWithinWavefront[wavefrontBatch] ); + int wavefrontBatchSize = linksInBatch.size(); + + int batchAddressInTarget = m_maxBatchesWithinWave * m_wavefrontSize * wavefrontCount + m_wavefrontSize * wavefrontBatch; + + for( int linkIndex = 0; linkIndex < wavefrontBatchSize; ++linkIndex ) + { + int originalLinkAddress = linksInBatch[linkIndex]; + // Reorder simple arrays trivially + m_links[batchAddressInTarget + linkIndex] = m_links_Backup[originalLinkAddress]; + m_linkStrength[batchAddressInTarget + linkIndex] = m_linkStrength_Backup[originalLinkAddress]; + m_linksMassLSC[batchAddressInTarget + linkIndex] = m_linksMassLSC_Backup[originalLinkAddress]; + m_linksRestLengthSquared[batchAddressInTarget + linkIndex] = m_linksRestLengthSquared_Backup[originalLinkAddress]; + m_linksRestLength[batchAddressInTarget + linkIndex] = m_linksRestLength_Backup[originalLinkAddress]; + m_linksMaterialLinearStiffnessCoefficient[batchAddressInTarget + linkIndex] = m_linksMaterialLinearStiffnessCoefficient_Backup[originalLinkAddress]; + + // The local address is more complicated. We need to work out where a given vertex will end up + // by searching the set of vertices for this link and using the index as the local address + btSoftBodyLinkData::LinkNodePair localPair; + btSoftBodyLinkData::LinkNodePair globalPair = m_links[batchAddressInTarget + linkIndex]; + localPair.vertex0 = wavefrontVertices.findLinearSearch( globalPair.vertex0 ); + localPair.vertex1 = wavefrontVertices.findLinearSearch( globalPair.vertex1 ); + m_linkVerticesLocalAddresses[batchAddressInTarget + linkIndex] = localPair; + } + for( int linkIndex = wavefrontBatchSize; linkIndex < m_wavefrontSize; ++linkIndex ) + { + // Put 0s into these arrays for padding for cleanliness + m_links[batchAddressInTarget + linkIndex] = btSoftBodyLinkData::LinkNodePair(0, 0); + m_linkStrength[batchAddressInTarget + linkIndex] = 0.f; + m_linksMassLSC[batchAddressInTarget + linkIndex] = 0.f; + m_linksRestLengthSquared[batchAddressInTarget + linkIndex] = 0.f; + m_linksRestLength[batchAddressInTarget + linkIndex] = 0.f; + m_linksMaterialLinearStiffnessCoefficient[batchAddressInTarget + linkIndex] = 0.f; + + + // For local addresses of junk data choose a set of addresses just above the range of valid ones + // and cycling tyhrough % 16 so that we don't have bank conficts between all dud addresses + // The valid addresses will do scatter and gather in the valid range, the junk ones should happily work + // off the end of that range so we need no control + btSoftBodyLinkData::LinkNodePair localPair; + localPair.vertex0 = verticesUsedByWavefront + (linkIndex % 16); + localPair.vertex1 = verticesUsedByWavefront + (linkIndex % 16); + m_linkVerticesLocalAddresses[batchAddressInTarget + linkIndex] = localPair; + } + + } + + + wavefrontCount++; + } + + + } + +} // void btSoftBodyLinkDataDX11SIMDAware::generateBatches() + + + diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h new file mode 100644 index 0000000..9dda3ed --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h @@ -0,0 +1,81 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H +#define BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H + +#include "stddef.h" //for size_t +#include "vectormath/vmInclude.h" + +#include "btSoftBodySolver_OpenCL.h" +#include "btSoftBodySolverBuffer_OpenCL.h" +#include "btSoftBodySolverLinkData_OpenCLSIMDAware.h" +#include "btSoftBodySolverVertexData_OpenCL.h" +#include "btSoftBodySolverTriangleData_OpenCL.h" + + + + + +class btOpenCLSoftBodySolverSIMDAware : public btOpenCLSoftBodySolver +{ +protected: + + + btSoftBodyLinkDataOpenCLSIMDAware m_linkData; + + + + + virtual bool buildShaders(); + + + void updateConstants( float timeStep ); + + float computeTriangleArea( + const Vectormath::Aos::Point3 &vertex0, + const Vectormath::Aos::Point3 &vertex1, + const Vectormath::Aos::Point3 &vertex2 ); + + + ////////////////////////////////////// + // Kernel dispatches + void solveLinksForPosition( int startLink, int numLinks, float kst, float ti ); + + void solveCollisionsAndUpdateVelocities( float isolverdt ); + // End kernel dispatches + ///////////////////////////////////// + +public: + btOpenCLSoftBodySolverSIMDAware(cl_command_queue queue,cl_context ctx, bool bUpdateAchchoredNodePos = false); + + virtual ~btOpenCLSoftBodySolverSIMDAware(); + + virtual SolverTypes getSolverType() const + { + return CL_SIMD_SOLVER; + } + + + virtual btSoftBodyLinkData &getLinkData(); + + + virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false); + + virtual void solveConstraints( float solverdt ); + +}; // btOpenCLSoftBodySolverSIMDAware + +#endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H diff --git a/src/BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h b/src/BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h new file mode 100644 index 0000000..e7d715b --- /dev/null +++ b/src/BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h @@ -0,0 +1,748 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_DATA_H +#define BT_SOFT_BODY_SOLVER_DATA_H + +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "vectormath/vmInclude.h" + + +class btSoftBodyLinkData +{ +public: + /** + * Class representing a link as a set of three indices into the vertex array. + */ + class LinkNodePair + { + public: + int vertex0; + int vertex1; + + LinkNodePair() + { + vertex0 = 0; + vertex1 = 0; + } + + LinkNodePair( int v0, int v1 ) + { + vertex0 = v0; + vertex1 = v1; + } + }; + + /** + * Class describing a link for input into the system. + */ + class LinkDescription + { + protected: + int m_vertex0; + int m_vertex1; + float m_linkLinearStiffness; + float m_linkStrength; + + public: + + LinkDescription() + { + m_vertex0 = 0; + m_vertex1 = 0; + m_linkLinearStiffness = 1.0; + m_linkStrength = 1.0; + } + + LinkDescription( int newVertex0, int newVertex1, float linkLinearStiffness ) + { + m_vertex0 = newVertex0; + m_vertex1 = newVertex1; + m_linkLinearStiffness = linkLinearStiffness; + m_linkStrength = 1.0; + } + + LinkNodePair getVertexPair() const + { + LinkNodePair nodes; + nodes.vertex0 = m_vertex0; + nodes.vertex1 = m_vertex1; + return nodes; + } + + void setVertex0( int vertex ) + { + m_vertex0 = vertex; + } + + void setVertex1( int vertex ) + { + m_vertex1 = vertex; + } + + void setLinkLinearStiffness( float linearStiffness ) + { + m_linkLinearStiffness = linearStiffness; + } + + void setLinkStrength( float strength ) + { + m_linkStrength = strength; + } + + int getVertex0() const + { + return m_vertex0; + } + + int getVertex1() const + { + return m_vertex1; + } + + float getLinkStrength() const + { + return m_linkStrength; + } + + float getLinkLinearStiffness() const + { + return m_linkLinearStiffness; + } + }; + + +protected: + // NOTE: + // Vertex reference data is stored relative to global array, not relative to individual cloth. + // Values must be correct if being passed into single-cloth VBOs or when migrating from one solver + // to another. + + btAlignedObjectArray< LinkNodePair > m_links; // Vertex pair for the link + btAlignedObjectArray< float > m_linkStrength; // Strength of each link + // (inverseMassA + inverseMassB)/ linear stiffness coefficient + btAlignedObjectArray< float > m_linksMassLSC; + btAlignedObjectArray< float > m_linksRestLengthSquared; + // Current vector length of link + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_linksCLength; + // 1/(current length * current length * massLSC) + btAlignedObjectArray< float > m_linksLengthRatio; + btAlignedObjectArray< float > m_linksRestLength; + btAlignedObjectArray< float > m_linksMaterialLinearStiffnessCoefficient; + +public: + btSoftBodyLinkData() + { + } + + virtual ~btSoftBodyLinkData() + { + } + + virtual void clear() + { + m_links.resize(0); + m_linkStrength.resize(0); + m_linksMassLSC.resize(0); + m_linksRestLengthSquared.resize(0); + m_linksLengthRatio.resize(0); + m_linksRestLength.resize(0); + m_linksMaterialLinearStiffnessCoefficient.resize(0); + } + + int getNumLinks() + { + return m_links.size(); + } + + /** Allocate enough space in all link-related arrays to fit numLinks links */ + virtual void createLinks( int numLinks ) + { + int previousSize = m_links.size(); + int newSize = previousSize + numLinks; + + // Resize all the arrays that store link data + m_links.resize( newSize ); + m_linkStrength.resize( newSize ); + m_linksMassLSC.resize( newSize ); + m_linksRestLengthSquared.resize( newSize ); + m_linksCLength.resize( newSize ); + m_linksLengthRatio.resize( newSize ); + m_linksRestLength.resize( newSize ); + m_linksMaterialLinearStiffnessCoefficient.resize( newSize ); + } + + /** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */ + virtual void setLinkAt( const LinkDescription &link, int linkIndex ) + { + m_links[linkIndex] = link.getVertexPair(); + m_linkStrength[linkIndex] = link.getLinkStrength(); + m_linksMassLSC[linkIndex] = 0.f; + m_linksRestLengthSquared[linkIndex] = 0.f; + m_linksCLength[linkIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f); + m_linksLengthRatio[linkIndex] = 0.f; + m_linksRestLength[linkIndex] = 0.f; + m_linksMaterialLinearStiffnessCoefficient[linkIndex] = link.getLinkLinearStiffness(); + } + + + /** + * Return true if data is on the accelerator. + * The CPU version of this class will return true here because + * the CPU is the same as the accelerator. + */ + virtual bool onAccelerator() + { + return true; + } + + /** + * Move data from host memory to the accelerator. + * The CPU version will always return that it has moved it. + */ + virtual bool moveToAccelerator() + { + return true; + } + + /** + * Move data from host memory from the accelerator. + * The CPU version will always return that it has moved it. + */ + virtual bool moveFromAccelerator() + { + return true; + } + + + + /** + * Return reference to the vertex index pair for link linkIndex as stored on the host. + */ + LinkNodePair &getVertexPair( int linkIndex ) + { + return m_links[linkIndex]; + } + + /** + * Return reference to strength of link linkIndex as stored on the host. + */ + float &getStrength( int linkIndex ) + { + return m_linkStrength[linkIndex]; + } + + /** + * Return a reference to the strength of the link corrected for link sorting. + * This is important if we are using data on an accelerator which has the data sorted in some fashion. + */ + virtual float &getStrengthCorrected( int linkIndex ) + { + return getStrength( linkIndex ); + } + + /** + * Return reference to the rest length of link linkIndex as stored on the host. + */ + float &getRestLength( int linkIndex ) + { + return m_linksRestLength[linkIndex]; + } + + /** + * Return reference to linear stiffness coefficient for link linkIndex as stored on the host. + */ + float &getLinearStiffnessCoefficient( int linkIndex ) + { + return m_linksMaterialLinearStiffnessCoefficient[linkIndex]; + } + + /** + * Return reference to the MassLSC value for link linkIndex as stored on the host. + */ + float &getMassLSC( int linkIndex ) + { + return m_linksMassLSC[linkIndex]; + } + + /** + * Return reference to rest length squared for link linkIndex as stored on the host. + */ + float &getRestLengthSquared( int linkIndex ) + { + return m_linksRestLengthSquared[linkIndex]; + } + + /** + * Return reference to current length of link linkIndex as stored on the host. + */ + Vectormath::Aos::Vector3 &getCurrentLength( int linkIndex ) + { + return m_linksCLength[linkIndex]; + } + + /** + * Return the link length ratio from for link linkIndex as stored on the host. + */ + float &getLinkLengthRatio( int linkIndex ) + { + return m_linksLengthRatio[linkIndex]; + } +}; + + + +/** + * Wrapper for vertex data information. + * By wrapping it like this we stand a good chance of being able to optimise for storage format easily. + * It should also help us make sure all the data structures remain consistent. + */ +class btSoftBodyVertexData +{ +public: + /** + * Class describing a vertex for input into the system. + */ + class VertexDescription + { + private: + Vectormath::Aos::Point3 m_position; + /** Inverse mass. If this is 0f then the mass was 0 because that simplifies calculations. */ + float m_inverseMass; + + public: + VertexDescription() + { + m_position = Vectormath::Aos::Point3( 0.f, 0.f, 0.f ); + m_inverseMass = 0.f; + } + + VertexDescription( const Vectormath::Aos::Point3 &position, float mass ) + { + m_position = position; + if( mass > 0.f ) + m_inverseMass = 1.0f/mass; + else + m_inverseMass = 0.f; + } + + void setPosition( const Vectormath::Aos::Point3 &position ) + { + m_position = position; + } + + void setInverseMass( float inverseMass ) + { + m_inverseMass = inverseMass; + } + + void setMass( float mass ) + { + if( mass > 0.f ) + m_inverseMass = 1.0f/mass; + else + m_inverseMass = 0.f; + } + + Vectormath::Aos::Point3 getPosition() const + { + return m_position; + } + + float getInverseMass() const + { + return m_inverseMass; + } + + float getMass() const + { + if( m_inverseMass == 0.f ) + return 0.f; + else + return 1.0f/m_inverseMass; + } + }; +protected: + + // identifier for the individual cloth + // For the CPU we don't really need this as we can grab the cloths and iterate over only their vertices + // For a parallel accelerator knowing on a per-vertex basis which cloth we're part of will help for obtaining + // per-cloth data + // For sorting etc it might also be helpful to be able to use in-array data such as this. + btAlignedObjectArray< int > m_clothIdentifier; + btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPosition; // vertex positions + btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPreviousPosition; // vertex positions + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexVelocity; // Velocity + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexForceAccumulator; // Force accumulator + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexNormal; // Normals + btAlignedObjectArray< float > m_vertexInverseMass; // Inverse mass + btAlignedObjectArray< float > m_vertexArea; // Area controlled by the vertex + btAlignedObjectArray< int > m_vertexTriangleCount; // Number of triangles touching this vertex + +public: + btSoftBodyVertexData() + { + } + + virtual ~btSoftBodyVertexData() + { + } + + virtual void clear() + { + m_clothIdentifier.resize(0); + m_vertexPosition.resize(0); + m_vertexPreviousPosition.resize(0); + m_vertexVelocity.resize(0); + m_vertexForceAccumulator.resize(0); + m_vertexNormal.resize(0); + m_vertexInverseMass.resize(0); + m_vertexArea.resize(0); + m_vertexTriangleCount.resize(0); + } + + int getNumVertices() + { + return m_vertexPosition.size(); + } + + int getClothIdentifier( int vertexIndex ) + { + return m_clothIdentifier[vertexIndex]; + } + + void setVertexAt( const VertexDescription &vertex, int vertexIndex ) + { + m_vertexPosition[vertexIndex] = vertex.getPosition(); + m_vertexPreviousPosition[vertexIndex] = vertex.getPosition(); + m_vertexVelocity[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f); + m_vertexForceAccumulator[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f); + m_vertexNormal[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f); + m_vertexInverseMass[vertexIndex] = vertex.getInverseMass(); + m_vertexArea[vertexIndex] = 0.f; + m_vertexTriangleCount[vertexIndex] = 0; + } + + /** + * Create numVertices new vertices for cloth clothIdentifier + * maxVertices allows a buffer zone of extra vertices for alignment or tearing reasons. + */ + void createVertices( int numVertices, int clothIdentifier, int maxVertices = 0 ) + { + int previousSize = m_vertexPosition.size(); + if( maxVertices == 0 ) + maxVertices = numVertices; + int newSize = previousSize + maxVertices; + + // Resize all the arrays that store vertex data + m_clothIdentifier.resize( newSize ); + m_vertexPosition.resize( newSize ); + m_vertexPreviousPosition.resize( newSize ); + m_vertexVelocity.resize( newSize ); + m_vertexForceAccumulator.resize( newSize ); + m_vertexNormal.resize( newSize ); + m_vertexInverseMass.resize( newSize ); + m_vertexArea.resize( newSize ); + m_vertexTriangleCount.resize( newSize ); + + for( int vertexIndex = previousSize; vertexIndex < newSize; ++vertexIndex ) + m_clothIdentifier[vertexIndex] = clothIdentifier; + for( int vertexIndex = (previousSize + numVertices); vertexIndex < newSize; ++vertexIndex ) + m_clothIdentifier[vertexIndex] = -1; + } + + // Get and set methods in header so they can be inlined + + /** + * Return a reference to the position of vertex vertexIndex as stored on the host. + */ + Vectormath::Aos::Point3 &getPosition( int vertexIndex ) + { + return m_vertexPosition[vertexIndex]; + } + + Vectormath::Aos::Point3 getPosition( int vertexIndex ) const + { + return m_vertexPosition[vertexIndex]; + } + + /** + * Return a reference to the previous position of vertex vertexIndex as stored on the host. + */ + Vectormath::Aos::Point3 &getPreviousPosition( int vertexIndex ) + { + return m_vertexPreviousPosition[vertexIndex]; + } + + /** + * Return a reference to the velocity of vertex vertexIndex as stored on the host. + */ + Vectormath::Aos::Vector3 &getVelocity( int vertexIndex ) + { + return m_vertexVelocity[vertexIndex]; + } + + /** + * Return a reference to the force accumulator of vertex vertexIndex as stored on the host. + */ + Vectormath::Aos::Vector3 &getForceAccumulator( int vertexIndex ) + { + return m_vertexForceAccumulator[vertexIndex]; + } + + /** + * Return a reference to the normal of vertex vertexIndex as stored on the host. + */ + Vectormath::Aos::Vector3 &getNormal( int vertexIndex ) + { + return m_vertexNormal[vertexIndex]; + } + + Vectormath::Aos::Vector3 getNormal( int vertexIndex ) const + { + return m_vertexNormal[vertexIndex]; + } + + /** + * Return a reference to the inverse mass of vertex vertexIndex as stored on the host. + */ + float &getInverseMass( int vertexIndex ) + { + return m_vertexInverseMass[vertexIndex]; + } + + /** + * Get access to the area controlled by this vertex. + */ + float &getArea( int vertexIndex ) + { + return m_vertexArea[vertexIndex]; + } + + /** + * Get access to the array of how many triangles touch each vertex. + */ + int &getTriangleCount( int vertexIndex ) + { + return m_vertexTriangleCount[vertexIndex]; + } + + + + /** + * Return true if data is on the accelerator. + * The CPU version of this class will return true here because + * the CPU is the same as the accelerator. + */ + virtual bool onAccelerator() + { + return true; + } + + /** + * Move data from host memory to the accelerator. + * The CPU version will always return that it has moved it. + */ + virtual bool moveToAccelerator() + { + return true; + } + + /** + * Move data to host memory from the accelerator if bCopy is false. + * If bCopy is true, copy data to host memory from the accelerator so that data + * won't be moved to accelerator when moveToAccelerator() is called next time. + * If bCopyMinimum is true, only vertex position and normal are copied. + * bCopyMinimum will be meaningful only if bCopy is true. + * The CPU version will always return that it has moved it. + */ + virtual bool moveFromAccelerator(bool bCopy = false, bool bCopyMinimum = true) + { + return true; + } + + btAlignedObjectArray< Vectormath::Aos::Point3 > &getVertexPositions() + { + return m_vertexPosition; + } +}; + + +class btSoftBodyTriangleData +{ +public: + /** + * Class representing a triangle as a set of three indices into the + * vertex array. + */ + class TriangleNodeSet + { + public: + int vertex0; + int vertex1; + int vertex2; + int _padding; + + TriangleNodeSet( ) + { + vertex0 = 0; + vertex1 = 0; + vertex2 = 0; + _padding = -1; + } + + TriangleNodeSet( int newVertex0, int newVertex1, int newVertex2 ) + { + vertex0 = newVertex0; + vertex1 = newVertex1; + vertex2 = newVertex2; + } + }; + + class TriangleDescription + { + protected: + int m_vertex0; + int m_vertex1; + int m_vertex2; + + public: + TriangleDescription() + { + m_vertex0 = 0; + m_vertex1 = 0; + m_vertex2 = 0; + } + + TriangleDescription( int newVertex0, int newVertex1, int newVertex2 ) + { + m_vertex0 = newVertex0; + m_vertex1 = newVertex1; + m_vertex2 = newVertex2; + } + + TriangleNodeSet getVertexSet() const + { + btSoftBodyTriangleData::TriangleNodeSet nodes; + nodes.vertex0 = m_vertex0; + nodes.vertex1 = m_vertex1; + nodes.vertex2 = m_vertex2; + return nodes; + } + }; + +protected: + // NOTE: + // Vertex reference data is stored relative to global array, not relative to individual cloth. + // Values must be correct if being passed into single-cloth VBOs or when migrating from one solver + // to another. + btAlignedObjectArray< TriangleNodeSet > m_vertexIndices; + btAlignedObjectArray< float > m_area; + btAlignedObjectArray< Vectormath::Aos::Vector3 > m_normal; + +public: + btSoftBodyTriangleData() + { + } + + virtual ~btSoftBodyTriangleData() + { + + } + + virtual void clear() + { + m_vertexIndices.resize(0); + m_area.resize(0); + m_normal.resize(0); + } + + int getNumTriangles() + { + return m_vertexIndices.size(); + } + + virtual void setTriangleAt( const TriangleDescription &triangle, int triangleIndex ) + { + m_vertexIndices[triangleIndex] = triangle.getVertexSet(); + } + + virtual void createTriangles( int numTriangles ) + { + int previousSize = m_vertexIndices.size(); + int newSize = previousSize + numTriangles; + + // Resize all the arrays that store triangle data + m_vertexIndices.resize( newSize ); + m_area.resize( newSize ); + m_normal.resize( newSize ); + } + + /** + * Return the vertex index set for triangle triangleIndex as stored on the host. + */ + const TriangleNodeSet &getVertexSet( int triangleIndex ) + { + return m_vertexIndices[triangleIndex]; + } + + /** + * Get access to the triangle area. + */ + float &getTriangleArea( int triangleIndex ) + { + return m_area[triangleIndex]; + } + + /** + * Get access to the normal vector for this triangle. + */ + Vectormath::Aos::Vector3 &getNormal( int triangleIndex ) + { + return m_normal[triangleIndex]; + } + + /** + * Return true if data is on the accelerator. + * The CPU version of this class will return true here because + * the CPU is the same as the accelerator. + */ + virtual bool onAccelerator() + { + return true; + } + + /** + * Move data from host memory to the accelerator. + * The CPU version will always return that it has moved it. + */ + virtual bool moveToAccelerator() + { + return true; + } + + /** + * Move data from host memory from the accelerator. + * The CPU version will always return that it has moved it. + */ + virtual bool moveFromAccelerator() + { + return true; + } +}; + + +#endif // #ifndef BT_SOFT_BODY_SOLVER_DATA_H + diff --git a/src/BulletMultiThreaded/HeapManager.h b/src/BulletMultiThreaded/HeapManager.h new file mode 100644 index 0000000..b2da4ef --- /dev/null +++ b/src/BulletMultiThreaded/HeapManager.h @@ -0,0 +1,117 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef BT_HEAP_MANAGER_H__ +#define BT_HEAP_MANAGER_H__ + +#ifdef __SPU__ + #define HEAP_STACK_SIZE 32 +#else + #define HEAP_STACK_SIZE 64 +#endif + +#define MIN_ALLOC_SIZE 16 + + +class HeapManager +{ +private: + ATTRIBUTE_ALIGNED16(unsigned char *mHeap); + ATTRIBUTE_ALIGNED16(unsigned int mHeapBytes); + ATTRIBUTE_ALIGNED16(unsigned char *mPoolStack[HEAP_STACK_SIZE]); + ATTRIBUTE_ALIGNED16(unsigned int mCurStack); + +public: + enum {ALIGN16,ALIGN128}; + + HeapManager(unsigned char *buf,int bytes) + { + mHeap = buf; + mHeapBytes = bytes; + clear(); + } + + ~HeapManager() + { + } + + int getAllocated() + { + return (int)(mPoolStack[mCurStack]-mHeap); + } + + int getRest() + { + return mHeapBytes-getAllocated(); + } + + void *allocate(size_t bytes,int alignment = ALIGN16) + { + if(bytes <= 0) bytes = MIN_ALLOC_SIZE; + btAssert(mCurStack < (HEAP_STACK_SIZE-1)); + + +#if defined(_WIN64) || defined(__LP64__) || defined(__x86_64__) + unsigned long long p = (unsigned long long )mPoolStack[mCurStack]; + if(alignment == ALIGN128) { + p = ((p+127) & 0xffffffffffffff80); + bytes = (bytes+127) & 0xffffffffffffff80; + } + else { + bytes = (bytes+15) & 0xfffffffffffffff0; + } + + btAssert(bytes <=(mHeapBytes-(p-(unsigned long long )mHeap)) ); + +#else + unsigned long p = (unsigned long )mPoolStack[mCurStack]; + if(alignment == ALIGN128) { + p = ((p+127) & 0xffffff80); + bytes = (bytes+127) & 0xffffff80; + } + else { + bytes = (bytes+15) & 0xfffffff0; + } + btAssert(bytes <=(mHeapBytes-(p-(unsigned long)mHeap)) ); +#endif + unsigned char * bla = (unsigned char *)(p + bytes); + mPoolStack[++mCurStack] = bla; + return (void*)p; + } + + void deallocate(void *p) + { + (void) p; + mCurStack--; + } + + void clear() + { + mPoolStack[0] = mHeap; + mCurStack = 0; + } + +// void printStack() +// { +// for(unsigned int i=0;i<=mCurStack;i++) { +// PRINTF("memStack %2d 0x%x\n",i,(uint32_t)mPoolStack[i]); +// } +// } + +}; + +#endif //BT_HEAP_MANAGER_H__ + diff --git a/src/BulletMultiThreaded/PlatformDefinitions.h b/src/BulletMultiThreaded/PlatformDefinitions.h new file mode 100644 index 0000000..142103a --- /dev/null +++ b/src/BulletMultiThreaded/PlatformDefinitions.h @@ -0,0 +1,99 @@ +#ifndef BT_TYPE_DEFINITIONS_H +#define BT_TYPE_DEFINITIONS_H + +///This file provides some platform/compiler checks for common definitions +#include "LinearMath/btScalar.h" +#include "LinearMath/btMinMax.h" + +#ifdef PFX_USE_FREE_VECTORMATH +#include "physics_effects/base_level/base/pfx_vectormath_include.win32.h" +typedef Vectormath::Aos::Vector3 vmVector3; +typedef Vectormath::Aos::Quat vmQuat; +typedef Vectormath::Aos::Matrix3 vmMatrix3; +typedef Vectormath::Aos::Transform3 vmTransform3; +typedef Vectormath::Aos::Point3 vmPoint3; +#else +#include "vectormath/vmInclude.h" +#endif//PFX_USE_FREE_VECTORMATH + + + + + +#ifdef _WIN32 + +typedef union +{ + unsigned int u; + void *p; +} addr64; + +#define USE_WIN32_THREADING 1 + + #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) + #else + #endif //__MINGW32__ + + typedef unsigned char uint8_t; +#ifndef __PHYSICS_COMMON_H__ +#ifndef PFX_USE_FREE_VECTORMATH +#ifndef __BT_SKIP_UINT64_H + typedef unsigned long int uint64_t; +#endif //__BT_SKIP_UINT64_H +#endif //PFX_USE_FREE_VECTORMATH + typedef unsigned int uint32_t; +#endif //__PHYSICS_COMMON_H__ + typedef unsigned short uint16_t; + + #include + #define memalign(alignment, size) malloc(size); + +#include //memcpy + + + + #include + #define spu_printf printf + +#else + #include + #include + #include //for memcpy + +#if defined (__CELLOS_LV2__) + // Playstation 3 Cell SDK +#include + +#else + // posix system + +#define USE_PTHREADS (1) + +#ifdef USE_LIBSPE2 +#include +#define spu_printf printf +#define DWORD unsigned int + typedef union + { + unsigned long long ull; + unsigned int ui[2]; + void *p; + } addr64; +#endif // USE_LIBSPE2 + +#endif //__CELLOS_LV2__ + +#endif + +#ifdef __SPU__ +#include +#define printf spu_printf +#endif + +/* Included here because we need uint*_t typedefs */ +#include "PpuAddressSpace.h" + +#endif //BT_TYPE_DEFINITIONS_H + + + diff --git a/src/BulletMultiThreaded/PosixThreadSupport.cpp b/src/BulletMultiThreaded/PosixThreadSupport.cpp new file mode 100644 index 0000000..81c0cf8 --- /dev/null +++ b/src/BulletMultiThreaded/PosixThreadSupport.cpp @@ -0,0 +1,409 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include "PosixThreadSupport.h" +#ifdef USE_PTHREADS +#include +#include + +#include "SpuCollisionTaskProcess.h" +#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" + +#define checkPThreadFunction(returnValue) \ + if(0 != returnValue) { \ + printf("PThread problem at line %i in file %s: %i %d\n", __LINE__, __FILE__, returnValue, errno); \ + } + +// The number of threads should be equal to the number of available cores +// Todo: each worker should be linked to a single core, using SetThreadIdealProcessor. + +// PosixThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication +// Setup and initialize SPU/CELL/Libspe2 +PosixThreadSupport::PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo) +{ + startThreads(threadConstructionInfo); +} + +// cleanup/shutdown Libspe2 +PosixThreadSupport::~PosixThreadSupport() +{ + stopSPU(); +} + +#if (defined (__APPLE__)) +#define NAMED_SEMAPHORES +#endif + +// this semaphore will signal, if and how many threads are finished with their work +static sem_t* mainSemaphore=0; + +static sem_t* createSem(const char* baseName) +{ + static int semCount = 0; +#ifdef NAMED_SEMAPHORES + /// Named semaphore begin + char name[32]; + snprintf(name, 32, "/%s-%d-%4.4d", baseName, getpid(), semCount++); + sem_t* tempSem = sem_open(name, O_CREAT, 0600, 0); + + if (tempSem != reinterpret_cast(SEM_FAILED)) + { +// printf("Created \"%s\" Semaphore %p\n", name, tempSem); + } + else + { + //printf("Error creating Semaphore %d\n", errno); + exit(-1); + } + /// Named semaphore end +#else + sem_t* tempSem = new sem_t; + checkPThreadFunction(sem_init(tempSem, 0, 0)); +#endif + return tempSem; +} + +static void destroySem(sem_t* semaphore) +{ +#ifdef NAMED_SEMAPHORES + checkPThreadFunction(sem_close(semaphore)); +#else + checkPThreadFunction(sem_destroy(semaphore)); + delete semaphore; +#endif +} + +static void *threadFunction(void *argument) +{ + + PosixThreadSupport::btSpuStatus* status = (PosixThreadSupport::btSpuStatus*)argument; + + + while (1) + { + checkPThreadFunction(sem_wait(status->startSemaphore)); + + void* userPtr = status->m_userPtr; + + if (userPtr) + { + btAssert(status->m_status); + status->m_userThreadFunc(userPtr,status->m_lsMemory); + status->m_status = 2; + checkPThreadFunction(sem_post(mainSemaphore)); + status->threadUsed++; + } else { + //exit Thread + status->m_status = 3; + checkPThreadFunction(sem_post(mainSemaphore)); + printf("Thread with taskId %i exiting\n",status->m_taskId); + break; + } + + } + + printf("Thread TERMINATED\n"); + return 0; + +} + +///send messages to SPUs +void PosixThreadSupport::sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t taskId) +{ + /// gMidphaseSPU.sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (uint32_t) &taskDesc); + + ///we should spawn an SPU task here, and in 'waitForResponse' it should wait for response of the (one of) the first tasks that finished + + + + switch (uiCommand) + { + case CMD_GATHER_AND_PROCESS_PAIRLIST: + { + btSpuStatus& spuStatus = m_activeSpuStatus[taskId]; + btAssert(taskId >= 0); + btAssert(taskId < m_activeSpuStatus.size()); + + spuStatus.m_commandId = uiCommand; + spuStatus.m_status = 1; + spuStatus.m_userPtr = (void*)uiArgument0; + + // fire event to start new task + checkPThreadFunction(sem_post(spuStatus.startSemaphore)); + break; + } + default: + { + ///not implemented + btAssert(0); + } + + }; + + +} + + +///check for messages from SPUs +void PosixThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) +{ + ///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response + + ///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback' + + + btAssert(m_activeSpuStatus.size()); + + // wait for any of the threads to finish + checkPThreadFunction(sem_wait(mainSemaphore)); + + // get at least one thread which has finished + size_t last = -1; + + for(size_t t=0; t < size_t(m_activeSpuStatus.size()); ++t) { + if(2 == m_activeSpuStatus[t].m_status) { + last = t; + break; + } + } + + btSpuStatus& spuStatus = m_activeSpuStatus[last]; + + btAssert(spuStatus.m_status > 1); + spuStatus.m_status = 0; + + // need to find an active spu + btAssert(last >= 0); + + *puiArgument0 = spuStatus.m_taskId; + *puiArgument1 = spuStatus.m_status; +} + + + +void PosixThreadSupport::startThreads(ThreadConstructionInfo& threadConstructionInfo) +{ + printf("%s creating %i threads.\n", __FUNCTION__, threadConstructionInfo.m_numThreads); + m_activeSpuStatus.resize(threadConstructionInfo.m_numThreads); + + mainSemaphore = createSem("main"); + //checkPThreadFunction(sem_wait(mainSemaphore)); + + for (int i=0;i < threadConstructionInfo.m_numThreads;i++) + { + printf("starting thread %d\n",i); + + btSpuStatus& spuStatus = m_activeSpuStatus[i]; + + spuStatus.startSemaphore = createSem("threadLocal"); + + checkPThreadFunction(pthread_create(&spuStatus.thread, NULL, &threadFunction, (void*)&spuStatus)); + + spuStatus.m_userPtr=0; + + spuStatus.m_taskId = i; + spuStatus.m_commandId = 0; + spuStatus.m_status = 0; + spuStatus.m_lsMemory = threadConstructionInfo.m_lsMemoryFunc(); + spuStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc; + spuStatus.threadUsed = 0; + + printf("started thread %d \n",i); + + } + +} + +void PosixThreadSupport::startSPU() +{ +} + + +///tell the task scheduler we are done with the SPU tasks +void PosixThreadSupport::stopSPU() +{ + for(size_t t=0; t < size_t(m_activeSpuStatus.size()); ++t) + { + btSpuStatus& spuStatus = m_activeSpuStatus[t]; + printf("%s: Thread %i used: %ld\n", __FUNCTION__, int(t), spuStatus.threadUsed); + + spuStatus.m_userPtr = 0; + checkPThreadFunction(sem_post(spuStatus.startSemaphore)); + checkPThreadFunction(sem_wait(mainSemaphore)); + + printf("destroy semaphore\n"); + destroySem(spuStatus.startSemaphore); + printf("semaphore destroyed\n"); + checkPThreadFunction(pthread_join(spuStatus.thread,0)); + + } + printf("destroy main semaphore\n"); + destroySem(mainSemaphore); + printf("main semaphore destroyed\n"); + m_activeSpuStatus.clear(); +} + +class PosixCriticalSection : public btCriticalSection +{ + pthread_mutex_t m_mutex; + +public: + PosixCriticalSection() + { + pthread_mutex_init(&m_mutex, NULL); + } + virtual ~PosixCriticalSection() + { + pthread_mutex_destroy(&m_mutex); + } + + ATTRIBUTE_ALIGNED16(unsigned int mCommonBuff[32]); + + virtual unsigned int getSharedParam(int i) + { + return mCommonBuff[i]; + } + virtual void setSharedParam(int i,unsigned int p) + { + mCommonBuff[i] = p; + } + + virtual void lock() + { + pthread_mutex_lock(&m_mutex); + } + virtual void unlock() + { + pthread_mutex_unlock(&m_mutex); + } +}; + + +#if defined(_POSIX_BARRIERS) && (_POSIX_BARRIERS - 20012L) >= 0 +/* OK to use barriers on this platform */ +class PosixBarrier : public btBarrier +{ + pthread_barrier_t m_barr; + int m_numThreads; +public: + PosixBarrier() + :m_numThreads(0) { } + virtual ~PosixBarrier() { + pthread_barrier_destroy(&m_barr); + } + + virtual void sync() + { + int rc = pthread_barrier_wait(&m_barr); + if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf("Could not wait on barrier\n"); + exit(-1); + } + } + virtual void setMaxCount(int numThreads) + { + int result = pthread_barrier_init(&m_barr, NULL, numThreads); + m_numThreads = numThreads; + btAssert(result==0); + } + virtual int getMaxCount() + { + return m_numThreads; + } +}; +#else +/* Not OK to use barriers on this platform - insert alternate code here */ +class PosixBarrier : public btBarrier +{ + pthread_mutex_t m_mutex; + pthread_cond_t m_cond; + + int m_numThreads; + int m_called; + +public: + PosixBarrier() + :m_numThreads(0) + { + } + virtual ~PosixBarrier() + { + if (m_numThreads>0) + { + pthread_mutex_destroy(&m_mutex); + pthread_cond_destroy(&m_cond); + } + } + + virtual void sync() + { + pthread_mutex_lock(&m_mutex); + m_called++; + if (m_called == m_numThreads) { + m_called = 0; + pthread_cond_broadcast(&m_cond); + } else { + pthread_cond_wait(&m_cond,&m_mutex); + } + pthread_mutex_unlock(&m_mutex); + + } + virtual void setMaxCount(int numThreads) + { + if (m_numThreads>0) + { + pthread_mutex_destroy(&m_mutex); + pthread_cond_destroy(&m_cond); + } + m_called = 0; + pthread_mutex_init(&m_mutex,NULL); + pthread_cond_init(&m_cond,NULL); + m_numThreads = numThreads; + } + virtual int getMaxCount() + { + return m_numThreads; + } +}; + +#endif//_POSIX_BARRIERS + + + +btBarrier* PosixThreadSupport::createBarrier() +{ + PosixBarrier* barrier = new PosixBarrier(); + barrier->setMaxCount(getNumTasks()); + return barrier; +} + +btCriticalSection* PosixThreadSupport::createCriticalSection() +{ + return new PosixCriticalSection(); +} + +void PosixThreadSupport::deleteBarrier(btBarrier* barrier) +{ + delete barrier; +} + +void PosixThreadSupport::deleteCriticalSection(btCriticalSection* cs) +{ + delete cs; +} +#endif // USE_PTHREADS + diff --git a/src/BulletMultiThreaded/PosixThreadSupport.h b/src/BulletMultiThreaded/PosixThreadSupport.h new file mode 100644 index 0000000..bf7578f --- /dev/null +++ b/src/BulletMultiThreaded/PosixThreadSupport.h @@ -0,0 +1,147 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_POSIX_THREAD_SUPPORT_H +#define BT_POSIX_THREAD_SUPPORT_H + + +#include "LinearMath/btScalar.h" +#include "PlatformDefinitions.h" + +#ifdef USE_PTHREADS //platform specifc defines are defined in PlatformDefinitions.h + +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 //for definition of pthread_barrier_t, see http://pages.cs.wisc.edu/~travitch/pthreads_primer.html +#endif //_XOPEN_SOURCE +#include +#include + + + +#include "LinearMath/btAlignedObjectArray.h" + +#include "btThreadSupportInterface.h" + + +typedef void (*PosixThreadFunc)(void* userPtr,void* lsMemory); +typedef void* (*PosixlsMemorySetupFunc)(); + +// PosixThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication +class PosixThreadSupport : public btThreadSupportInterface +{ +public: + typedef enum sStatus { + STATUS_BUSY, + STATUS_READY, + STATUS_FINISHED + } Status; + + // placeholder, until libspe2 support is there + struct btSpuStatus + { + uint32_t m_taskId; + uint32_t m_commandId; + uint32_t m_status; + + PosixThreadFunc m_userThreadFunc; + void* m_userPtr; //for taskDesc etc + void* m_lsMemory; //initialized using PosixLocalStoreMemorySetupFunc + + pthread_t thread; + sem_t* startSemaphore; + + unsigned long threadUsed; + }; +private: + + btAlignedObjectArray m_activeSpuStatus; +public: + ///Setup and initialize SPU/CELL/Libspe2 + + + + struct ThreadConstructionInfo + { + ThreadConstructionInfo(const char* uniqueName, + PosixThreadFunc userThreadFunc, + PosixlsMemorySetupFunc lsMemoryFunc, + int numThreads=1, + int threadStackSize=65535 + ) + :m_uniqueName(uniqueName), + m_userThreadFunc(userThreadFunc), + m_lsMemoryFunc(lsMemoryFunc), + m_numThreads(numThreads), + m_threadStackSize(threadStackSize) + { + + } + + const char* m_uniqueName; + PosixThreadFunc m_userThreadFunc; + PosixlsMemorySetupFunc m_lsMemoryFunc; + int m_numThreads; + int m_threadStackSize; + + }; + + PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo); + +///cleanup/shutdown Libspe2 + virtual ~PosixThreadSupport(); + + void startThreads(ThreadConstructionInfo& threadInfo); + + +///send messages to SPUs + virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1); + +///check for messages from SPUs + virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1); + +///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded) + virtual void startSPU(); + +///tell the task scheduler we are done with the SPU tasks + virtual void stopSPU(); + + virtual void setNumTasks(int numTasks) {} + + virtual int getNumTasks() const + { + return m_activeSpuStatus.size(); + } + + virtual btBarrier* createBarrier(); + + virtual btCriticalSection* createCriticalSection(); + + virtual void deleteBarrier(btBarrier* barrier); + + virtual void deleteCriticalSection(btCriticalSection* criticalSection); + + + virtual void* getThreadLocalMemory(int taskId) + { + return m_activeSpuStatus[taskId].m_lsMemory; + } + +}; + +#endif // USE_PTHREADS + +#endif // BT_POSIX_THREAD_SUPPORT_H + + diff --git a/src/BulletMultiThreaded/PpuAddressSpace.h b/src/BulletMultiThreaded/PpuAddressSpace.h new file mode 100644 index 0000000..6f22827 --- /dev/null +++ b/src/BulletMultiThreaded/PpuAddressSpace.h @@ -0,0 +1,37 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2010 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_PPU_ADDRESS_SPACE_H +#define BT_PPU_ADDRESS_SPACE_H + + +#ifdef _WIN32 +//stop those casting warnings until we have a better solution for ppu_address_t / void* / uint64 conversions +#pragma warning (disable: 4311) +#pragma warning (disable: 4312) +#endif //_WIN32 + + +#if defined(_WIN64) + typedef unsigned __int64 ppu_address_t; +#elif defined(__LP64__) || defined(__x86_64__) + typedef uint64_t ppu_address_t; +#else + typedef uint32_t ppu_address_t; +#endif //defined(_WIN64) + +#endif //BT_PPU_ADDRESS_SPACE_H + diff --git a/src/BulletMultiThreaded/SequentialThreadSupport.cpp b/src/BulletMultiThreaded/SequentialThreadSupport.cpp new file mode 100644 index 0000000..1999277 --- /dev/null +++ b/src/BulletMultiThreaded/SequentialThreadSupport.cpp @@ -0,0 +1,181 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SequentialThreadSupport.h" + + +#include "SpuCollisionTaskProcess.h" +#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" + +SequentialThreadSupport::SequentialThreadSupport(SequentialThreadConstructionInfo& threadConstructionInfo) +{ + startThreads(threadConstructionInfo); +} + +///cleanup/shutdown Libspe2 +SequentialThreadSupport::~SequentialThreadSupport() +{ + stopSPU(); +} + +#include + +///send messages to SPUs +void SequentialThreadSupport::sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t taskId) +{ + switch (uiCommand) + { + case CMD_GATHER_AND_PROCESS_PAIRLIST: + { + btSpuStatus& spuStatus = m_activeSpuStatus[0]; + spuStatus.m_userPtr=(void*)uiArgument0; + spuStatus.m_userThreadFunc(spuStatus.m_userPtr,spuStatus.m_lsMemory); + } + break; + default: + { + ///not implemented + btAssert(0 && "Not implemented"); + } + + }; + + +} + +///check for messages from SPUs +void SequentialThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) +{ + btAssert(m_activeSpuStatus.size()); + btSpuStatus& spuStatus = m_activeSpuStatus[0]; + *puiArgument0 = spuStatus.m_taskId; + *puiArgument1 = spuStatus.m_status; +} + +void SequentialThreadSupport::startThreads(SequentialThreadConstructionInfo& threadConstructionInfo) +{ + m_activeSpuStatus.resize(1); + printf("STS: Not starting any threads\n"); + btSpuStatus& spuStatus = m_activeSpuStatus[0]; + spuStatus.m_userPtr = 0; + spuStatus.m_taskId = 0; + spuStatus.m_commandId = 0; + spuStatus.m_status = 0; + spuStatus.m_lsMemory = threadConstructionInfo.m_lsMemoryFunc(); + spuStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc; + printf("STS: Created local store at %p for task %s\n", spuStatus.m_lsMemory, threadConstructionInfo.m_uniqueName); +} + +void SequentialThreadSupport::startSPU() +{ +} + +void SequentialThreadSupport::stopSPU() +{ + m_activeSpuStatus.clear(); +} + +void SequentialThreadSupport::setNumTasks(int numTasks) +{ + printf("SequentialThreadSupport::setNumTasks(%d) is not implemented and has no effect\n",numTasks); +} + + + + +class btDummyBarrier : public btBarrier +{ +private: + +public: + btDummyBarrier() + { + } + + virtual ~btDummyBarrier() + { + } + + void sync() + { + } + + virtual void setMaxCount(int n) {} + virtual int getMaxCount() {return 1;} +}; + +class btDummyCriticalSection : public btCriticalSection +{ + +public: + btDummyCriticalSection() + { + } + + virtual ~btDummyCriticalSection() + { + } + + unsigned int getSharedParam(int i) + { + btAssert(i>=0&&i<31); + return mCommonBuff[i+1]; + } + + void setSharedParam(int i,unsigned int p) + { + btAssert(i>=0&&i<31); + mCommonBuff[i+1] = p; + } + + void lock() + { + mCommonBuff[0] = 1; + } + + void unlock() + { + mCommonBuff[0] = 0; + } +}; + + + + +btBarrier* SequentialThreadSupport::createBarrier() +{ + return new btDummyBarrier(); +} + +btCriticalSection* SequentialThreadSupport::createCriticalSection() +{ + return new btDummyCriticalSection(); + +} + +void SequentialThreadSupport::deleteBarrier(btBarrier* barrier) +{ + delete barrier; +} + +void SequentialThreadSupport::deleteCriticalSection(btCriticalSection* criticalSection) +{ + delete criticalSection; +} + + + + + diff --git a/src/BulletMultiThreaded/SequentialThreadSupport.h b/src/BulletMultiThreaded/SequentialThreadSupport.h new file mode 100644 index 0000000..a188ef2 --- /dev/null +++ b/src/BulletMultiThreaded/SequentialThreadSupport.h @@ -0,0 +1,100 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "LinearMath/btScalar.h" +#include "PlatformDefinitions.h" + + +#ifndef BT_SEQUENTIAL_THREAD_SUPPORT_H +#define BT_SEQUENTIAL_THREAD_SUPPORT_H + +#include "LinearMath/btAlignedObjectArray.h" + +#include "btThreadSupportInterface.h" + +typedef void (*SequentialThreadFunc)(void* userPtr,void* lsMemory); +typedef void* (*SequentiallsMemorySetupFunc)(); + + + +///The SequentialThreadSupport is a portable non-parallel implementation of the btThreadSupportInterface +///This is useful for debugging and porting SPU Tasks to other platforms. +class SequentialThreadSupport : public btThreadSupportInterface +{ +public: + struct btSpuStatus + { + uint32_t m_taskId; + uint32_t m_commandId; + uint32_t m_status; + + SequentialThreadFunc m_userThreadFunc; + + void* m_userPtr; //for taskDesc etc + void* m_lsMemory; //initialized using SequentiallsMemorySetupFunc + }; +private: + btAlignedObjectArray m_activeSpuStatus; + btAlignedObjectArray m_completeHandles; +public: + struct SequentialThreadConstructionInfo + { + SequentialThreadConstructionInfo (const char* uniqueName, + SequentialThreadFunc userThreadFunc, + SequentiallsMemorySetupFunc lsMemoryFunc + ) + :m_uniqueName(uniqueName), + m_userThreadFunc(userThreadFunc), + m_lsMemoryFunc(lsMemoryFunc) + { + + } + + const char* m_uniqueName; + SequentialThreadFunc m_userThreadFunc; + SequentiallsMemorySetupFunc m_lsMemoryFunc; + }; + + SequentialThreadSupport(SequentialThreadConstructionInfo& threadConstructionInfo); + virtual ~SequentialThreadSupport(); + void startThreads(SequentialThreadConstructionInfo& threadInfo); +///send messages to SPUs + virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1); +///check for messages from SPUs + virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1); +///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded) + virtual void startSPU(); +///tell the task scheduler we are done with the SPU tasks + virtual void stopSPU(); + + virtual void setNumTasks(int numTasks); + + virtual int getNumTasks() const + { + return 1; + } + virtual btBarrier* createBarrier(); + + virtual btCriticalSection* createCriticalSection(); + + virtual void deleteBarrier(btBarrier* barrier); + + virtual void deleteCriticalSection(btCriticalSection* criticalSection); + + +}; + +#endif //BT_SEQUENTIAL_THREAD_SUPPORT_H + diff --git a/src/BulletMultiThreaded/SpuCollisionObjectWrapper.cpp b/src/BulletMultiThreaded/SpuCollisionObjectWrapper.cpp new file mode 100644 index 0000000..182aa26 --- /dev/null +++ b/src/BulletMultiThreaded/SpuCollisionObjectWrapper.cpp @@ -0,0 +1,48 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SpuCollisionObjectWrapper.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" + +SpuCollisionObjectWrapper::SpuCollisionObjectWrapper () +{ +} + +#ifndef __SPU__ +SpuCollisionObjectWrapper::SpuCollisionObjectWrapper (const btCollisionObject* collisionObject) +{ + m_shapeType = collisionObject->getCollisionShape()->getShapeType (); + m_collisionObjectPtr = (ppu_address_t)collisionObject; + m_margin = collisionObject->getCollisionShape()->getMargin (); +} +#endif + +int +SpuCollisionObjectWrapper::getShapeType () const +{ + return m_shapeType; +} + +float +SpuCollisionObjectWrapper::getCollisionMargin () const +{ + return m_margin; +} + +ppu_address_t +SpuCollisionObjectWrapper::getCollisionObjectPtr () const +{ + return m_collisionObjectPtr; +} diff --git a/src/BulletMultiThreaded/SpuCollisionObjectWrapper.h b/src/BulletMultiThreaded/SpuCollisionObjectWrapper.h new file mode 100644 index 0000000..f90da27 --- /dev/null +++ b/src/BulletMultiThreaded/SpuCollisionObjectWrapper.h @@ -0,0 +1,40 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPU_COLLISION_OBJECT_WRAPPER_H +#define BT_SPU_COLLISION_OBJECT_WRAPPER_H + +#include "PlatformDefinitions.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" + +ATTRIBUTE_ALIGNED16(class) SpuCollisionObjectWrapper +{ +protected: + int m_shapeType; + float m_margin; + ppu_address_t m_collisionObjectPtr; + +public: + SpuCollisionObjectWrapper (); + + SpuCollisionObjectWrapper (const btCollisionObject* collisionObject); + + int getShapeType () const; + float getCollisionMargin () const; + ppu_address_t getCollisionObjectPtr () const; +}; + + +#endif //BT_SPU_COLLISION_OBJECT_WRAPPER_H diff --git a/src/BulletMultiThreaded/SpuCollisionTaskProcess.cpp b/src/BulletMultiThreaded/SpuCollisionTaskProcess.cpp new file mode 100644 index 0000000..f606d13 --- /dev/null +++ b/src/BulletMultiThreaded/SpuCollisionTaskProcess.cpp @@ -0,0 +1,317 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +//#define DEBUG_SPU_TASK_SCHEDULING 1 + + +//class OptimizedBvhNode; + +#include "SpuCollisionTaskProcess.h" + + + + +void SpuCollisionTaskProcess::setNumTasks(int maxNumTasks) +{ + if (int(m_maxNumOutstandingTasks) != maxNumTasks) + { + m_maxNumOutstandingTasks = maxNumTasks; + m_taskBusy.resize(m_maxNumOutstandingTasks); + m_spuGatherTaskDesc.resize(m_maxNumOutstandingTasks); + + for (int i = 0; i < m_taskBusy.size(); i++) + { + m_taskBusy[i] = false; + } + + ///re-allocate task memory buffers + if (m_workUnitTaskBuffers != 0) + { + btAlignedFree(m_workUnitTaskBuffers); + } + + m_workUnitTaskBuffers = (unsigned char *)btAlignedAlloc(MIDPHASE_WORKUNIT_TASK_SIZE*m_maxNumOutstandingTasks, 128); + } + +} + + + +SpuCollisionTaskProcess::SpuCollisionTaskProcess(class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks) +:m_threadInterface(threadInterface), +m_maxNumOutstandingTasks(0) +{ + m_workUnitTaskBuffers = (unsigned char *)0; + setNumTasks(maxNumOutstandingTasks); + m_numBusyTasks = 0; + m_currentTask = 0; + m_currentPage = 0; + m_currentPageEntry = 0; + +#ifdef DEBUG_SpuCollisionTaskProcess + m_initialized = false; +#endif + + m_threadInterface->startSPU(); + + //printf("sizeof vec_float4: %d\n", sizeof(vec_float4)); + printf("sizeof SpuGatherAndProcessWorkUnitInput: %d\n", int(sizeof(SpuGatherAndProcessWorkUnitInput))); + +} + +SpuCollisionTaskProcess::~SpuCollisionTaskProcess() +{ + + if (m_workUnitTaskBuffers != 0) + { + btAlignedFree(m_workUnitTaskBuffers); + m_workUnitTaskBuffers = 0; + } + + + + m_threadInterface->stopSPU(); + +} + + + +void SpuCollisionTaskProcess::initialize2(bool useEpa) +{ + +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("SpuCollisionTaskProcess::initialize()\n"); +#endif //DEBUG_SPU_TASK_SCHEDULING + + for (int i = 0; i < int (m_maxNumOutstandingTasks); i++) + { + m_taskBusy[i] = false; + } + m_numBusyTasks = 0; + m_currentTask = 0; + m_currentPage = 0; + m_currentPageEntry = 0; + m_useEpa = useEpa; + +#ifdef DEBUG_SpuCollisionTaskProcess + m_initialized = true; + btAssert(MIDPHASE_NUM_WORKUNITS_PER_TASK*sizeof(SpuGatherAndProcessWorkUnitInput) <= MIDPHASE_WORKUNIT_TASK_SIZE); +#endif +} + + +void SpuCollisionTaskProcess::issueTask2() +{ + +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("SpuCollisionTaskProcess::issueTask (m_currentTask= %d\n)", m_currentTask); +#endif //DEBUG_SPU_TASK_SCHEDULING + + m_taskBusy[m_currentTask] = true; + m_numBusyTasks++; + + + SpuGatherAndProcessPairsTaskDesc& taskDesc = m_spuGatherTaskDesc[m_currentTask]; + taskDesc.m_useEpa = m_useEpa; + + { + // send task description in event message + // no error checking here... + // but, currently, event queue can be no larger than NUM_WORKUNIT_TASKS. + + taskDesc.m_inPairPtr = reinterpret_cast(MIDPHASE_TASK_PTR(m_currentTask)); + + taskDesc.taskId = m_currentTask; + taskDesc.numPages = m_currentPage+1; + taskDesc.numOnLastPage = m_currentPageEntry; + } + + + + m_threadInterface->sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (ppu_address_t) &taskDesc,m_currentTask); + + // if all tasks busy, wait for spu event to clear the task. + + + if (m_numBusyTasks >= m_maxNumOutstandingTasks) + { + unsigned int taskId; + unsigned int outputSize; + + + for (int i=0;i=0); + + + m_threadInterface->waitForResponse(&taskId, &outputSize); + +// printf("issueTask taskId %d completed, numBusy=%d\n",taskId,m_numBusyTasks); + + //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize); + + //postProcess(taskId, outputSize); + + m_taskBusy[taskId] = false; + + m_numBusyTasks--; + } + +} + +void SpuCollisionTaskProcess::addWorkToTask(void* pairArrayPtr,int startIndex,int endIndex) +{ +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("#"); +#endif //DEBUG_SPU_TASK_SCHEDULING + +#ifdef DEBUG_SpuCollisionTaskProcess + btAssert(m_initialized); + btAssert(m_workUnitTaskBuffers); + +#endif + + bool batch = true; + + if (batch) + { + if (m_currentPageEntry == MIDPHASE_NUM_WORKUNITS_PER_PAGE) + { + if (m_currentPage == MIDPHASE_NUM_WORKUNIT_PAGES-1) + { + // task buffer is full, issue current task. + // if all task buffers busy, this waits until SPU is done. + issueTask2(); + + // find new task buffer + for (unsigned int i = 0; i < m_maxNumOutstandingTasks; i++) + { + if (!m_taskBusy[i]) + { + m_currentTask = i; + //init the task data + + break; + } + } + + m_currentPage = 0; + } + else + { + m_currentPage++; + } + + m_currentPageEntry = 0; + } + } + + { + + + + SpuGatherAndProcessWorkUnitInput &wuInput = + *(reinterpret_cast + (MIDPHASE_ENTRY_PTR(m_currentTask, m_currentPage, m_currentPageEntry))); + + wuInput.m_pairArrayPtr = reinterpret_cast(pairArrayPtr); + wuInput.m_startIndex = startIndex; + wuInput.m_endIndex = endIndex; + + + + m_currentPageEntry++; + + if (!batch) + { + issueTask2(); + + // find new task buffer + for (unsigned int i = 0; i < m_maxNumOutstandingTasks; i++) + { + if (!m_taskBusy[i]) + { + m_currentTask = i; + //init the task data + + break; + } + } + + m_currentPage = 0; + m_currentPageEntry =0; + } + } +} + + +void +SpuCollisionTaskProcess::flush2() +{ +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("\nSpuCollisionTaskProcess::flush()\n"); +#endif //DEBUG_SPU_TASK_SCHEDULING + + // if there's a partially filled task buffer, submit that task + if (m_currentPage > 0 || m_currentPageEntry > 0) + { + issueTask2(); + } + + + // all tasks are issued, wait for all tasks to be complete + while(m_numBusyTasks > 0) + { + // Consolidating SPU code + unsigned int taskId=-1; + unsigned int outputSize; + + for (int i=0;i=0); + + + { + + // SPURS support. + m_threadInterface->waitForResponse(&taskId, &outputSize); + } +// printf("flush2 taskId %d completed, numBusy =%d \n",taskId,m_numBusyTasks); + //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize); + + //postProcess(taskId, outputSize); + + m_taskBusy[taskId] = false; + + m_numBusyTasks--; + } + + +} diff --git a/src/BulletMultiThreaded/SpuCollisionTaskProcess.h b/src/BulletMultiThreaded/SpuCollisionTaskProcess.h new file mode 100644 index 0000000..23b5b05 --- /dev/null +++ b/src/BulletMultiThreaded/SpuCollisionTaskProcess.h @@ -0,0 +1,163 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPU_COLLISION_TASK_PROCESS_H +#define BT_SPU_COLLISION_TASK_PROCESS_H + +#include + +#include "LinearMath/btScalar.h" + +#include "PlatformDefinitions.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" // for definitions processCollisionTask and createCollisionLocalStoreMemory + +#include "btThreadSupportInterface.h" + + +//#include "SPUAssert.h" +#include + + +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" + +#include "LinearMath/btAlignedAllocator.h" + +#include + + +#define DEBUG_SpuCollisionTaskProcess 1 + + +#define CMD_GATHER_AND_PROCESS_PAIRLIST 1 + +class btCollisionObject; +class btPersistentManifold; +class btDispatcher; + + +/////Task Description for SPU collision detection +//struct SpuGatherAndProcessPairsTaskDesc +//{ +// uint64_t inPtr;//m_pairArrayPtr; +// //mutex variable +// uint32_t m_someMutexVariableInMainMemory; +// +// uint64_t m_dispatcher; +// +// uint32_t numOnLastPage; +// +// uint16_t numPages; +// uint16_t taskId; +// +// struct CollisionTask_LocalStoreMemory* m_lsMemory; +//} +// +//#if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2) +//__attribute__ ((aligned (16))) +//#endif +//; + + +///MidphaseWorkUnitInput stores individual primitive versus mesh collision detection input, to be processed by the SPU. +ATTRIBUTE_ALIGNED16(struct) SpuGatherAndProcessWorkUnitInput +{ + uint64_t m_pairArrayPtr; + int m_startIndex; + int m_endIndex; +}; + + + + +/// SpuCollisionTaskProcess handles SPU processing of collision pairs. +/// Maintains a set of task buffers. +/// When the task is full, the task is issued for SPUs to process. Contact output goes into btPersistentManifold +/// associated with each task. +/// When PPU issues a task, it will look for completed task buffers +/// PPU will do postprocessing, dependent on workunit output (not likely) +class SpuCollisionTaskProcess +{ + + unsigned char *m_workUnitTaskBuffers; + + + // track task buffers that are being used, and total busy tasks + btAlignedObjectArray m_taskBusy; + btAlignedObjectArray m_spuGatherTaskDesc; + + class btThreadSupportInterface* m_threadInterface; + + unsigned int m_maxNumOutstandingTasks; + + unsigned int m_numBusyTasks; + + // the current task and the current entry to insert a new work unit + unsigned int m_currentTask; + unsigned int m_currentPage; + unsigned int m_currentPageEntry; + + bool m_useEpa; + +#ifdef DEBUG_SpuCollisionTaskProcess + bool m_initialized; +#endif + void issueTask2(); + //void postProcess(unsigned int taskId, int outputSize); + +public: + SpuCollisionTaskProcess(btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks); + + ~SpuCollisionTaskProcess(); + + ///call initialize in the beginning of the frame, before addCollisionPairToTask + void initialize2(bool useEpa = false); + + ///batch up additional work to a current task for SPU processing. When batch is full, it issues the task. + void addWorkToTask(void* pairArrayPtr,int startIndex,int endIndex); + + ///call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished + void flush2(); + + /// set the maximum number of SPU tasks allocated + void setNumTasks(int maxNumTasks); + + int getNumTasks() const + { + return m_maxNumOutstandingTasks; + } +}; + + + +#define MIDPHASE_TASK_PTR(task) (&m_workUnitTaskBuffers[0] + MIDPHASE_WORKUNIT_TASK_SIZE*task) +#define MIDPHASE_ENTRY_PTR(task,page,entry) (MIDPHASE_TASK_PTR(task) + MIDPHASE_WORKUNIT_PAGE_SIZE*page + sizeof(SpuGatherAndProcessWorkUnitInput)*entry) +#define MIDPHASE_OUTPUT_PTR(task) (&m_contactOutputBuffers[0] + MIDPHASE_MAX_CONTACT_BUFFER_SIZE*task) +#define MIDPHASE_TREENODES_PTR(task) (&m_complexShapeBuffers[0] + MIDPHASE_COMPLEX_SHAPE_BUFFER_SIZE*task) + + +#define MIDPHASE_WORKUNIT_PAGE_SIZE (16) +//#define MIDPHASE_WORKUNIT_PAGE_SIZE (128) + +#define MIDPHASE_NUM_WORKUNIT_PAGES 1 +#define MIDPHASE_WORKUNIT_TASK_SIZE (MIDPHASE_WORKUNIT_PAGE_SIZE*MIDPHASE_NUM_WORKUNIT_PAGES) +#define MIDPHASE_NUM_WORKUNITS_PER_PAGE (MIDPHASE_WORKUNIT_PAGE_SIZE / sizeof(SpuGatherAndProcessWorkUnitInput)) +#define MIDPHASE_NUM_WORKUNITS_PER_TASK (MIDPHASE_NUM_WORKUNITS_PER_PAGE*MIDPHASE_NUM_WORKUNIT_PAGES) + + +#endif // BT_SPU_COLLISION_TASK_PROCESS_H + diff --git a/src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp b/src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp new file mode 100644 index 0000000..62cf4f0 --- /dev/null +++ b/src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp @@ -0,0 +1,69 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SpuContactManifoldCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" + + + + +void SpuContactManifoldCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + btAssert(0); +} + +btScalar SpuContactManifoldCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + btAssert(0); + return 1.f; +} + +#ifndef __SPU__ +SpuContactManifoldCollisionAlgorithm::SpuContactManifoldCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObject* body0,const btCollisionObject* body1) +:btCollisionAlgorithm(ci) +#ifdef USE_SEPDISTANCE_UTIL +,m_sepDistance(body0->getCollisionShape()->getAngularMotionDisc(),body1->getCollisionShape()->getAngularMotionDisc()) +#endif //USE_SEPDISTANCE_UTIL +{ + m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1); + m_shapeType0 = body0->getCollisionShape()->getShapeType(); + m_shapeType1 = body1->getCollisionShape()->getShapeType(); + m_collisionMargin0 = body0->getCollisionShape()->getMargin(); + m_collisionMargin1 = body1->getCollisionShape()->getMargin(); + m_collisionObject0 = body0; + m_collisionObject1 = body1; + + if (body0->getCollisionShape()->isPolyhedral()) + { + btPolyhedralConvexShape* convex0 = (btPolyhedralConvexShape*)body0->getCollisionShape(); + m_shapeDimensions0 = convex0->getImplicitShapeDimensions(); + } + if (body1->getCollisionShape()->isPolyhedral()) + { + btPolyhedralConvexShape* convex1 = (btPolyhedralConvexShape*)body1->getCollisionShape(); + m_shapeDimensions1 = convex1->getImplicitShapeDimensions(); + } +} +#endif //__SPU__ + + +SpuContactManifoldCollisionAlgorithm::~SpuContactManifoldCollisionAlgorithm() +{ + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); +} diff --git a/src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h b/src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h new file mode 100644 index 0000000..14b0a94 --- /dev/null +++ b/src/BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h @@ -0,0 +1,121 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPU_CONTACTMANIFOLD_COLLISION_ALGORITHM_H +#define BT_SPU_CONTACTMANIFOLD_COLLISION_ALGORITHM_H + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "LinearMath/btTransformUtil.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +class btPersistentManifold; + +//#define USE_SEPDISTANCE_UTIL 1 + +/// SpuContactManifoldCollisionAlgorithm provides contact manifold and should be processed on SPU. +ATTRIBUTE_ALIGNED16(class) SpuContactManifoldCollisionAlgorithm : public btCollisionAlgorithm +{ + btVector3 m_shapeDimensions0; + btVector3 m_shapeDimensions1; + btPersistentManifold* m_manifoldPtr; + int m_shapeType0; + int m_shapeType1; + float m_collisionMargin0; + float m_collisionMargin1; + + const btCollisionObject* m_collisionObject0; + const btCollisionObject* m_collisionObject1; + + + + +public: + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + + SpuContactManifoldCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObject* body0,const btCollisionObject* body1); +#ifdef USE_SEPDISTANCE_UTIL + btConvexSeparatingDistanceUtil m_sepDistance; +#endif //USE_SEPDISTANCE_UTIL + + virtual ~SpuContactManifoldCollisionAlgorithm(); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr) + manifoldArray.push_back(m_manifoldPtr); + } + + btPersistentManifold* getContactManifoldPtr() + { + return m_manifoldPtr; + } + + const btCollisionObject* getCollisionObject0() + { + return m_collisionObject0; + } + + const btCollisionObject* getCollisionObject1() + { + return m_collisionObject1; + } + + int getShapeType0() const + { + return m_shapeType0; + } + + int getShapeType1() const + { + return m_shapeType1; + } + float getCollisionMargin0() const + { + return m_collisionMargin0; + } + float getCollisionMargin1() const + { + return m_collisionMargin1; + } + + const btVector3& getShapeDimensions0() const + { + return m_shapeDimensions0; + } + + const btVector3& getShapeDimensions1() const + { + return m_shapeDimensions1; + } + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(SpuContactManifoldCollisionAlgorithm)); + return new(mem) SpuContactManifoldCollisionAlgorithm(ci,body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + } + }; + +}; + +#endif //BT_SPU_CONTACTMANIFOLD_COLLISION_ALGORITHM_H diff --git a/src/BulletMultiThreaded/SpuDoubleBuffer.h b/src/BulletMultiThreaded/SpuDoubleBuffer.h new file mode 100644 index 0000000..558d615 --- /dev/null +++ b/src/BulletMultiThreaded/SpuDoubleBuffer.h @@ -0,0 +1,126 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_DOUBLE_BUFFER_H +#define BT_DOUBLE_BUFFER_H + +#include "SpuFakeDma.h" +#include "LinearMath/btScalar.h" + + +///DoubleBuffer +template +class DoubleBuffer +{ +#if defined(__SPU__) || defined(USE_LIBSPE2) + ATTRIBUTE_ALIGNED128( T m_buffer0[size] ) ; + ATTRIBUTE_ALIGNED128( T m_buffer1[size] ) ; +#else + T m_buffer0[size]; + T m_buffer1[size]; +#endif + + T *m_frontBuffer; + T *m_backBuffer; + + unsigned int m_dmaTag; + bool m_dmaPending; +public: + bool isPending() const { return m_dmaPending;} + DoubleBuffer(); + + void init (); + + // dma get and put commands + void backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag); + void backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag); + + // gets pointer to a buffer + T *getFront(); + T *getBack(); + + // if back buffer dma was started, wait for it to complete + // then move back to front and vice versa + T *swapBuffers(); +}; + +template +DoubleBuffer::DoubleBuffer() +{ + init (); +} + +template +void DoubleBuffer::init() +{ + this->m_dmaPending = false; + this->m_frontBuffer = &this->m_buffer0[0]; + this->m_backBuffer = &this->m_buffer1[0]; +} + +template +void +DoubleBuffer::backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag) +{ + m_dmaPending = true; + m_dmaTag = tag; + if (numBytes) + { + m_backBuffer = (T*)cellDmaLargeGetReadOnly(m_backBuffer, ea, numBytes, tag, 0, 0); + } +} + +template +void +DoubleBuffer::backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag) +{ + m_dmaPending = true; + m_dmaTag = tag; + cellDmaLargePut(m_backBuffer, ea, numBytes, tag, 0, 0); +} + +template +T * +DoubleBuffer::getFront() +{ + return m_frontBuffer; +} + +template +T * +DoubleBuffer::getBack() +{ + return m_backBuffer; +} + +template +T * +DoubleBuffer::swapBuffers() +{ + if (m_dmaPending) + { + cellDmaWaitTagStatusAll(1< //for btAssert +//Disabling memcpy sometimes helps debugging DMA + +#define USE_MEMCPY 1 +#ifdef USE_MEMCPY + +#endif + + +void* cellDmaLargeGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid) +{ + +#if defined (__SPU__) || defined (USE_LIBSPE2) + cellDmaLargeGet(ls,ea,size,tag,tid,rid); + return ls; +#else + return (void*)(ppu_address_t)ea; +#endif +} + +void* cellDmaSmallGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid) +{ +#if defined (__SPU__) || defined (USE_LIBSPE2) + mfc_get(ls,ea,size,tag,0,0); + return ls; +#else + return (void*)(ppu_address_t)ea; +#endif +} + + + + +void* cellDmaGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid) +{ +#if defined (__SPU__) || defined (USE_LIBSPE2) + cellDmaGet(ls,ea,size,tag,tid,rid); + return ls; +#else + return (void*)(ppu_address_t)ea; +#endif +} + + +///this unalignedDma should not be frequently used, only for small data. It handles alignment and performs check on size (<16 bytes) +int stallingUnalignedDmaSmallGet(void *ls, uint64_t ea, uint32_t size) +{ + + btAssert(size<32); + + ATTRIBUTE_ALIGNED16(char tmpBuffer[32]); + + + char* localStore = (char*)ls; + uint32_t i; + + + ///make sure last 4 bits are the same, for cellDmaSmallGet + uint32_t last4BitsOffset = ea & 0x0f; + char* tmpTarget = tmpBuffer + last4BitsOffset; + +#if defined (__SPU__) || defined (USE_LIBSPE2) + + int remainingSize = size; + +//#define FORCE_cellDmaUnalignedGet 1 +#ifdef FORCE_cellDmaUnalignedGet + cellDmaUnalignedGet(tmpTarget,ea,size,DMA_TAG(1),0,0); +#else + char* remainingTmpTarget = tmpTarget; + uint64_t remainingEa = ea; + + while (remainingSize) + { + switch (remainingSize) + { + case 1: + case 2: + case 4: + case 8: + case 16: + { + mfc_get(remainingTmpTarget,remainingEa,remainingSize,DMA_TAG(1),0,0); + remainingSize=0; + break; + } + default: + { + //spu_printf("unaligned DMA with non-natural size:%d\n",remainingSize); + int actualSize = 0; + + if (remainingSize > 16) + actualSize = 16; + else + if (remainingSize >8) + actualSize=8; + else + if (remainingSize >4) + actualSize=4; + else + if (remainingSize >2) + actualSize=2; + mfc_get(remainingTmpTarget,remainingEa,actualSize,DMA_TAG(1),0,0); + remainingSize-=actualSize; + remainingTmpTarget+=actualSize; + remainingEa += actualSize; + } + } + } +#endif//FORCE_cellDmaUnalignedGet + +#else + char* mainMem = (char*)ea; + //copy into final destination +#ifdef USE_MEMCPY + + memcpy(tmpTarget,mainMem,size); +#else + for ( i=0;i +#include + +#define DMA_TAG(xfer) (xfer + 1) +#define DMA_MASK(xfer) (1 << DMA_TAG(xfer)) + +#else // !USE_LIBSPE2 + +#define DMA_TAG(xfer) (xfer + 1) +#define DMA_MASK(xfer) (1 << DMA_TAG(xfer)) + +#include + +#define DEBUG_DMA +#ifdef DEBUG_DMA +#define dUASSERT(a,b) if (!(a)) { printf(b);} +#define uintsize ppu_address_t + +#define cellDmaLargeGet(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \ + dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \ + dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \ + dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \ + dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \ + dUASSERT(size < 16384, "size too big: "); \ + dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \ + dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\ + printf("GET %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ea,(unsigned int)ls,(unsigned int)size);\ + } \ + mfc_get(ls, ea, size, tag, tid, rid) +#define cellDmaGet(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \ + dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \ + dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \ + dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \ + dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \ + dUASSERT(size < 16384, "size too big: "); \ + dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \ + dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\ + printf("GET %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ea,(unsigned int)ls,(unsigned int)size);\ + } \ + mfc_get(ls, ea, size, tag, tid, rid) +#define cellDmaLargePut(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \ + dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \ + dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \ + dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \ + dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \ + dUASSERT(size < 16384, "size too big: "); \ + dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \ + dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\ + printf("PUT %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ls,(unsigned int)ea,(unsigned int)size); \ + } \ + mfc_put(ls, ea, size, tag, tid, rid) +#define cellDmaSmallGet(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \ + dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \ + dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \ + dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \ + dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \ + dUASSERT(size < 16384, "size too big: "); \ + dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \ + dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\ + printf("GET %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ea,(unsigned int)ls,(unsigned int)size);\ + } \ + mfc_get(ls, ea, size, tag, tid, rid) +#define cellDmaWaitTagStatusAll(ignore) mfc_write_tag_mask(ignore) ; mfc_read_tag_status_all() + +#else +#define cellDmaLargeGet(ls, ea, size, tag, tid, rid) mfc_get(ls, ea, size, tag, tid, rid) +#define cellDmaGet(ls, ea, size, tag, tid, rid) mfc_get(ls, ea, size, tag, tid, rid) +#define cellDmaLargePut(ls, ea, size, tag, tid, rid) mfc_put(ls, ea, size, tag, tid, rid) +#define cellDmaSmallGet(ls, ea, size, tag, tid, rid) mfc_get(ls, ea, size, tag, tid, rid) +#define cellDmaWaitTagStatusAll(ignore) mfc_write_tag_mask(ignore) ; mfc_read_tag_status_all() +#endif // DEBUG_DMA + + + + + + + + +#endif // USE_LIBSPE2 +#else // !__SPU__ +//Simulate DMA using memcpy or direct access on non-CELL platforms that don't have DMAs and SPUs (Win32, Mac, Linux etc) +//Potential to add networked simulation using this interface + +#define DMA_TAG(a) (a) +#define DMA_MASK(a) (a) + + /// cellDmaLargeGet Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy) + int cellDmaLargeGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid); + int cellDmaGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid); + /// cellDmaLargePut Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy) + int cellDmaLargePut(const void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid); + /// cellDmaWaitTagStatusAll Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy) + void cellDmaWaitTagStatusAll(int ignore); + + +#endif //__CELLOS_LV2__ + +///stallingUnalignedDmaSmallGet internally uses DMA_TAG(1) +int stallingUnalignedDmaSmallGet(void *ls, uint64_t ea, uint32_t size); + + +void* cellDmaLargeGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid); +void* cellDmaGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid); +void* cellDmaSmallGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid); + + +#endif //BT_FAKE_DMA_H diff --git a/src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp b/src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp new file mode 100644 index 0000000..b9e88a0 --- /dev/null +++ b/src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp @@ -0,0 +1,283 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SpuGatheringCollisionDispatcher.h" +#include "SpuCollisionTaskProcess.h" + + +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" +#include "SpuContactManifoldCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "LinearMath/btQuickprof.h" +#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + + + + +SpuGatheringCollisionDispatcher::SpuGatheringCollisionDispatcher(class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks,btCollisionConfiguration* collisionConfiguration) +:btCollisionDispatcher(collisionConfiguration), +m_spuCollisionTaskProcess(0), +m_threadInterface(threadInterface), +m_maxNumOutstandingTasks(maxNumOutstandingTasks) +{ + +} + + +bool SpuGatheringCollisionDispatcher::supportsDispatchPairOnSpu(int proxyType0,int proxyType1) +{ + bool supported0 = ( + (proxyType0 == BOX_SHAPE_PROXYTYPE) || + (proxyType0 == TRIANGLE_SHAPE_PROXYTYPE) || + (proxyType0 == SPHERE_SHAPE_PROXYTYPE) || + (proxyType0 == CAPSULE_SHAPE_PROXYTYPE) || + (proxyType0 == CYLINDER_SHAPE_PROXYTYPE) || +// (proxyType0 == CONE_SHAPE_PROXYTYPE) || + (proxyType0 == TRIANGLE_MESH_SHAPE_PROXYTYPE) || + (proxyType0 == CONVEX_HULL_SHAPE_PROXYTYPE)|| + (proxyType0 == STATIC_PLANE_PROXYTYPE)|| + (proxyType0 == COMPOUND_SHAPE_PROXYTYPE) + ); + + bool supported1 = ( + (proxyType1 == BOX_SHAPE_PROXYTYPE) || + (proxyType1 == TRIANGLE_SHAPE_PROXYTYPE) || + (proxyType1 == SPHERE_SHAPE_PROXYTYPE) || + (proxyType1 == CAPSULE_SHAPE_PROXYTYPE) || + (proxyType1 == CYLINDER_SHAPE_PROXYTYPE) || +// (proxyType1 == CONE_SHAPE_PROXYTYPE) || + (proxyType1 == TRIANGLE_MESH_SHAPE_PROXYTYPE) || + (proxyType1 == CONVEX_HULL_SHAPE_PROXYTYPE) || + (proxyType1 == STATIC_PLANE_PROXYTYPE) || + (proxyType1 == COMPOUND_SHAPE_PROXYTYPE) + ); + + + return supported0 && supported1; +} + + + +SpuGatheringCollisionDispatcher::~SpuGatheringCollisionDispatcher() +{ + if (m_spuCollisionTaskProcess) + delete m_spuCollisionTaskProcess; + +} + +#include "stdio.h" + + + +///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc) +///this is useful for the collision dispatcher. +class btSpuCollisionPairCallback : public btOverlapCallback +{ + const btDispatcherInfo& m_dispatchInfo; + SpuGatheringCollisionDispatcher* m_dispatcher; + +public: + + btSpuCollisionPairCallback(const btDispatcherInfo& dispatchInfo, SpuGatheringCollisionDispatcher* dispatcher) + :m_dispatchInfo(dispatchInfo), + m_dispatcher(dispatcher) + { + } + + virtual bool processOverlap(btBroadphasePair& collisionPair) + { + + + //PPU version + //(*m_dispatcher->getNearCallback())(collisionPair,*m_dispatcher,m_dispatchInfo); + + //only support discrete collision detection for now, we could fallback on PPU/unoptimized version for TOI/CCD + btAssert(m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE); + + //by default, Bullet will use this near callback + { + ///userInfo is used to determine if the SPU has to handle this case or not (skip PPU tasks) + if (!collisionPair.m_internalTmpValue) + { + collisionPair.m_internalTmpValue = 1; + } + if (!collisionPair.m_algorithm) + { + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + + btCollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher1 = m_dispatcher; + ci.m_manifold = 0; + + if (m_dispatcher->needsCollision(colObj0,colObj1)) + { + int proxyType0 = colObj0->getCollisionShape()->getShapeType(); + int proxyType1 = colObj1->getCollisionShape()->getShapeType(); + bool supportsSpuDispatch = m_dispatcher->supportsDispatchPairOnSpu(proxyType0,proxyType1) + && ((colObj0->getCollisionFlags() & btCollisionObject::CF_DISABLE_SPU_COLLISION_PROCESSING) == 0) + && ((colObj1->getCollisionFlags() & btCollisionObject::CF_DISABLE_SPU_COLLISION_PROCESSING) == 0); + + if (proxyType0 == COMPOUND_SHAPE_PROXYTYPE) + { + btCompoundShape* compound = (btCompoundShape*)colObj0->getCollisionShape(); + if (compound->getNumChildShapes()>MAX_SPU_COMPOUND_SUBSHAPES) + { + //printf("PPU fallback, compound->getNumChildShapes(%d)>%d\n",compound->getNumChildShapes(),MAX_SPU_COMPOUND_SUBSHAPES); + supportsSpuDispatch = false; + } + } + + if (proxyType1 == COMPOUND_SHAPE_PROXYTYPE) + { + btCompoundShape* compound = (btCompoundShape*)colObj1->getCollisionShape(); + if (compound->getNumChildShapes()>MAX_SPU_COMPOUND_SUBSHAPES) + { + //printf("PPU fallback, compound->getNumChildShapes(%d)>%d\n",compound->getNumChildShapes(),MAX_SPU_COMPOUND_SUBSHAPES); + supportsSpuDispatch = false; + } + } + + if (supportsSpuDispatch) + { + + int so = sizeof(SpuContactManifoldCollisionAlgorithm); +#ifdef ALLOCATE_SEPARATELY + void* mem = btAlignedAlloc(so,16);//m_dispatcher->allocateCollisionAlgorithm(so); +#else + void* mem = m_dispatcher->allocateCollisionAlgorithm(so); +#endif + collisionPair.m_algorithm = new(mem) SpuContactManifoldCollisionAlgorithm(ci,colObj0,colObj1); + collisionPair.m_internalTmpValue = 2; + } else + { + btCollisionObjectWrapper ob0(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform()); + btCollisionObjectWrapper ob1(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform()); + + collisionPair.m_algorithm = m_dispatcher->findAlgorithm(&ob0,&ob1); + collisionPair.m_internalTmpValue = 3; + } + } + } + } + return false; + } +}; + +void SpuGatheringCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo, btDispatcher* dispatcher) +{ + + if (dispatchInfo.m_enableSPU) + { + m_maxNumOutstandingTasks = m_threadInterface->getNumTasks(); + + { + BT_PROFILE("processAllOverlappingPairs"); + + if (!m_spuCollisionTaskProcess) + m_spuCollisionTaskProcess = new SpuCollisionTaskProcess(m_threadInterface,m_maxNumOutstandingTasks); + + m_spuCollisionTaskProcess->setNumTasks(m_maxNumOutstandingTasks); + // printf("m_maxNumOutstandingTasks =%d\n",m_maxNumOutstandingTasks); + + m_spuCollisionTaskProcess->initialize2(dispatchInfo.m_useEpa); + + + ///modified version of btCollisionDispatcher::dispatchAllCollisionPairs: + { + btSpuCollisionPairCallback collisionCallback(dispatchInfo,this); + + pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher); + } + } + + //send one big batch + int numTotalPairs = pairCache->getNumOverlappingPairs(); + if (numTotalPairs) + { + btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr(); + int i; + { + int pairRange = SPU_BATCHSIZE_BROADPHASE_PAIRS; + if (numTotalPairs < (m_spuCollisionTaskProcess->getNumTasks()*SPU_BATCHSIZE_BROADPHASE_PAIRS)) + { + pairRange = (numTotalPairs/m_spuCollisionTaskProcess->getNumTasks())+1; + } + + BT_PROFILE("addWorkToTask"); + for (i=0;iaddWorkToTask(pairPtr,i,endIndex); + i = endIndex; + } + } + { + BT_PROFILE("PPU fallback"); + //handle PPU fallback pairs + for (i=0;im_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + + if (dispatcher->needsCollision(colObj0,colObj1)) + { + //discrete collision detection query + btCollisionObjectWrapper ob0(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform()); + btCollisionObjectWrapper ob1(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform()); + + btManifoldResult contactPointResult(&ob0,&ob1); + + if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) + { + + collisionPair.m_algorithm->processCollision(&ob0,&ob1,dispatchInfo,&contactPointResult); + } else + { + //continuous collision detection query, time of impact (toi) + btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult); + if (dispatchInfo.m_timeOfImpact > toi) + dispatchInfo.m_timeOfImpact = toi; + + } + } + } + } + } + } + } + { + BT_PROFILE("flush2"); + //make sure all SPU work is done + m_spuCollisionTaskProcess->flush2(); + } + + } else + { + ///PPU fallback + ///!Need to make sure to clear all 'algorithms' when switching between SPU and PPU + btCollisionDispatcher::dispatchAllCollisionPairs(pairCache,dispatchInfo,dispatcher); + } +} diff --git a/src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h b/src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h new file mode 100644 index 0000000..f8bc7da --- /dev/null +++ b/src/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h @@ -0,0 +1,72 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef BT_SPU_GATHERING_COLLISION__DISPATCHER_H +#define BT_SPU_GATHERING_COLLISION__DISPATCHER_H + +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" + + +///Tuning value to optimized SPU utilization +///Too small value means Task overhead is large compared to computation (too fine granularity) +///Too big value might render some SPUs are idle, while a few other SPUs are doing all work. +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 8 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 16 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 64 +#define SPU_BATCHSIZE_BROADPHASE_PAIRS 128 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 256 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 512 +//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 1024 + + + +class SpuCollisionTaskProcess; + +///SpuGatheringCollisionDispatcher can use SPU to gather and calculate collision detection +///Time of Impact, Closest Points and Penetration Depth. +class SpuGatheringCollisionDispatcher : public btCollisionDispatcher +{ + + SpuCollisionTaskProcess* m_spuCollisionTaskProcess; + +protected: + + class btThreadSupportInterface* m_threadInterface; + + unsigned int m_maxNumOutstandingTasks; + + +public: + + //can be used by SPU collision algorithms + SpuCollisionTaskProcess* getSpuCollisionTaskProcess() + { + return m_spuCollisionTaskProcess; + } + + SpuGatheringCollisionDispatcher (class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks,btCollisionConfiguration* collisionConfiguration); + + virtual ~SpuGatheringCollisionDispatcher(); + + bool supportsDispatchPairOnSpu(int proxyType0,int proxyType1); + + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ; + +}; + + + +#endif //BT_SPU_GATHERING_COLLISION__DISPATCHER_H + + diff --git a/src/BulletMultiThreaded/SpuLibspe2Support.cpp b/src/BulletMultiThreaded/SpuLibspe2Support.cpp new file mode 100644 index 0000000..a312450 --- /dev/null +++ b/src/BulletMultiThreaded/SpuLibspe2Support.cpp @@ -0,0 +1,257 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifdef USE_LIBSPE2 + +#include "SpuLibspe2Support.h" + + + + +//SpuLibspe2Support helps to initialize/shutdown libspe2, start/stop SPU tasks and communication +///Setup and initialize SPU/CELL/Libspe2 +SpuLibspe2Support::SpuLibspe2Support(spe_program_handle_t *speprog, int numThreads) +{ + this->program = speprog; + this->numThreads = ((numThreads <= spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1)) ? numThreads : spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1)); +} + +///cleanup/shutdown Libspe2 +SpuLibspe2Support::~SpuLibspe2Support() +{ + + stopSPU(); +} + + + +///send messages to SPUs +void SpuLibspe2Support::sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1) +{ + spe_context_ptr_t context; + + switch (uiCommand) + { + case CMD_SAMPLE_TASK_COMMAND: + { + //get taskdescription + SpuSampleTaskDesc* taskDesc = (SpuSampleTaskDesc*) uiArgument0; + + btAssert(taskDesc->m_taskIdm_taskId]; + + //set data for spuStatus + spuStatus.m_commandId = uiCommand; + spuStatus.m_status = Spu_Status_Occupied; //set SPU as "occupied" + spuStatus.m_taskDesc.p = taskDesc; + + //get context + context = data[taskDesc->m_taskId].context; + + + taskDesc->m_mainMemoryPtr = reinterpret_cast (spuStatus.m_lsMemory.p); + + + break; + } + case CMD_GATHER_AND_PROCESS_PAIRLIST: + { + //get taskdescription + SpuGatherAndProcessPairsTaskDesc* taskDesc = (SpuGatherAndProcessPairsTaskDesc*) uiArgument0; + + btAssert(taskDesc->taskIdtaskId]; + + //set data for spuStatus + spuStatus.m_commandId = uiCommand; + spuStatus.m_status = Spu_Status_Occupied; //set SPU as "occupied" + spuStatus.m_taskDesc.p = taskDesc; + + //get context + context = data[taskDesc->taskId].context; + + + taskDesc->m_lsMemory = (CollisionTask_LocalStoreMemory*)spuStatus.m_lsMemory.p; + + break; + } + default: + { + ///not implemented + btAssert(0); + } + + }; + + + //write taskdescription in mailbox + unsigned int event = Spu_Mailbox_Event_Task; + spe_in_mbox_write(context, &event, 1, SPE_MBOX_ANY_NONBLOCKING); + +} + +///check for messages from SPUs +void SpuLibspe2Support::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) +{ + ///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response + + ///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback' + + btAssert(m_activeSpuStatus.size()); + + + int last = -1; + + //find an active spu/thread + while(last < 0) + { + for (int i=0;i=0); + + + + *puiArgument0 = spuStatus.m_taskId; + *puiArgument1 = spuStatus.m_status; + + +} + + +void SpuLibspe2Support::startSPU() +{ + this->internal_startSPU(); +} + + + +///start the spus group (can be called at the beginning of each frame, to make sure that the right SPU program is loaded) +void SpuLibspe2Support::internal_startSPU() +{ + m_activeSpuStatus.resize(numThreads); + + + for (int i=0; i < numThreads; i++) + { + + if(data[i].context == NULL) + { + + /* Create context */ + if ((data[i].context = spe_context_create(0, NULL)) == NULL) + { + perror ("Failed creating context"); + exit(1); + } + + /* Load program into context */ + if(spe_program_load(data[i].context, this->program)) + { + perror ("Failed loading program"); + exit(1); + } + + m_activeSpuStatus[i].m_status = Spu_Status_Startup; + m_activeSpuStatus[i].m_taskId = i; + m_activeSpuStatus[i].m_commandId = 0; + m_activeSpuStatus[i].m_lsMemory.p = NULL; + + + data[i].entry = SPE_DEFAULT_ENTRY; + data[i].flags = 0; + data[i].argp.p = &m_activeSpuStatus[i]; + data[i].envp.p = NULL; + + /* Create thread for each SPE context */ + if (pthread_create(&data[i].pthread, NULL, &ppu_pthread_function, &(data[i]) )) + { + perror ("Failed creating thread"); + exit(1); + } + /* + else + { + printf("started thread %d\n",i); + }*/ + } + } + + + for (int i=0; i < numThreads; i++) + { + if(data[i].context != NULL) + { + while( m_activeSpuStatus[i].m_status == Spu_Status_Startup) + { + // wait for spu to set up + sched_yield(); + } + printf("Spu %d is ready\n", i); + } + } +} + +///tell the task scheduler we are done with the SPU tasks +void SpuLibspe2Support::stopSPU() +{ + // wait for all threads to finish + int i; + for ( i = 0; i < this->numThreads; i++ ) + { + + unsigned int event = Spu_Mailbox_Event_Shutdown; + spe_context_ptr_t context = data[i].context; + spe_in_mbox_write(context, &event, 1, SPE_MBOX_ALL_BLOCKING); + pthread_join (data[i].pthread, NULL); + + } + // close SPE program + spe_image_close(program); + // destroy SPE contexts + for ( i = 0; i < this->numThreads; i++ ) + { + if(data[i].context != NULL) + { + spe_context_destroy (data[i].context); + } + } + + m_activeSpuStatus.clear(); + +} + + + +#endif //USE_LIBSPE2 + diff --git a/src/BulletMultiThreaded/SpuLibspe2Support.h b/src/BulletMultiThreaded/SpuLibspe2Support.h new file mode 100644 index 0000000..37a5e79 --- /dev/null +++ b/src/BulletMultiThreaded/SpuLibspe2Support.h @@ -0,0 +1,180 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_SPU_LIBSPE2_SUPPORT_H +#define BT_SPU_LIBSPE2_SUPPORT_H + +#include //for uint32_t etc. + +#ifdef USE_LIBSPE2 + +#include +#include +//#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#include "PlatformDefinitions.h" + + +//extern struct SpuGatherAndProcessPairsTaskDesc; + +enum +{ + Spu_Mailbox_Event_Nothing = 0, + Spu_Mailbox_Event_Task = 1, + Spu_Mailbox_Event_Shutdown = 2, + + Spu_Mailbox_Event_ForceDword = 0xFFFFFFFF + +}; + +enum +{ + Spu_Status_Free = 0, + Spu_Status_Occupied = 1, + Spu_Status_Startup = 2, + + Spu_Status_ForceDword = 0xFFFFFFFF + +}; + + +struct btSpuStatus +{ + uint32_t m_taskId; + uint32_t m_commandId; + uint32_t m_status; + + addr64 m_taskDesc; + addr64 m_lsMemory; + +} +__attribute__ ((aligned (128))) +; + + + +#ifndef __SPU__ + +#include "LinearMath/btAlignedObjectArray.h" +#include "SpuCollisionTaskProcess.h" +#include "SpuSampleTaskProcess.h" +#include "btThreadSupportInterface.h" +#include +#include +#include + +#define MAX_SPUS 4 + +typedef struct ppu_pthread_data +{ + spe_context_ptr_t context; + pthread_t pthread; + unsigned int entry; + unsigned int flags; + addr64 argp; + addr64 envp; + spe_stop_info_t stopinfo; +} ppu_pthread_data_t; + + +static void *ppu_pthread_function(void *arg) +{ + ppu_pthread_data_t * datap = (ppu_pthread_data_t *)arg; + /* + int rc; + do + {*/ + spe_context_run(datap->context, &datap->entry, datap->flags, datap->argp.p, datap->envp.p, &datap->stopinfo); + if (datap->stopinfo.stop_reason == SPE_EXIT) + { + if (datap->stopinfo.result.spe_exit_code != 0) + { + perror("FAILED: SPE returned a non-zero exit status: \n"); + exit(1); + } + } + else + { + perror("FAILED: SPE abnormally terminated\n"); + exit(1); + } + + + //} while (rc > 0); // loop until exit or error, and while any stop & signal + pthread_exit(NULL); +} + + + + + + +///SpuLibspe2Support helps to initialize/shutdown libspe2, start/stop SPU tasks and communication +class SpuLibspe2Support : public btThreadSupportInterface +{ + + btAlignedObjectArray m_activeSpuStatus; + +public: + //Setup and initialize SPU/CELL/Libspe2 + SpuLibspe2Support(spe_program_handle_t *speprog,int numThreads); + + // SPE program handle ptr. + spe_program_handle_t *program; + + // SPE program data + ppu_pthread_data_t data[MAX_SPUS]; + + //cleanup/shutdown Libspe2 + ~SpuLibspe2Support(); + + ///send messages to SPUs + void sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1=0); + + //check for messages from SPUs + void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1); + + //start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded) + virtual void startSPU(); + + //tell the task scheduler we are done with the SPU tasks + virtual void stopSPU(); + + virtual void setNumTasks(int numTasks) + { + //changing the number of tasks after initialization is not implemented (yet) + } + +private: + + ///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded) + void internal_startSPU(); + + + + + int numThreads; + +}; + +#endif // NOT __SPU__ + +#endif //USE_LIBSPE2 + +#endif //BT_SPU_LIBSPE2_SUPPORT_H + + + + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h new file mode 100644 index 0000000..e517961 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h @@ -0,0 +1,167 @@ +/* + Copyright (C) 2006, 2008 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef __BOX_H__ +#define __BOX_H__ + + +#ifndef PE_REF +#define PE_REF(a) a& +#endif + +#include + + +#include "../PlatformDefinitions.h" + + + + +enum FeatureType { F, E, V }; + +//---------------------------------------------------------------------------- +// Box +//---------------------------------------------------------------------------- +///The Box is an internal class used by the boxBoxDistance calculation. +class Box +{ +public: + vmVector3 mHalf; + + inline Box() + {} + inline Box(PE_REF(vmVector3) half_); + inline Box(float hx, float hy, float hz); + + inline void Set(PE_REF(vmVector3) half_); + inline void Set(float hx, float hy, float hz); + + inline vmVector3 GetAABB(const vmMatrix3& rotation) const; +}; + +inline +Box::Box(PE_REF(vmVector3) half_) +{ + Set(half_); +} + +inline +Box::Box(float hx, float hy, float hz) +{ + Set(hx, hy, hz); +} + +inline +void +Box::Set(PE_REF(vmVector3) half_) +{ + mHalf = half_; +} + +inline +void +Box::Set(float hx, float hy, float hz) +{ + mHalf = vmVector3(hx, hy, hz); +} + +inline +vmVector3 +Box::GetAABB(const vmMatrix3& rotation) const +{ + return absPerElem(rotation) * mHalf; +} + +//------------------------------------------------------------------------------------------------- +// BoxPoint +//------------------------------------------------------------------------------------------------- + +///The BoxPoint class is an internally used class to contain feature information for boxBoxDistance calculation. +class BoxPoint +{ +public: + BoxPoint() : localPoint(0.0f) {} + + vmPoint3 localPoint; + FeatureType featureType; + int featureIdx; + + inline void setVertexFeature(int plusX, int plusY, int plusZ); + inline void setEdgeFeature(int dim0, int plus0, int dim1, int plus1); + inline void setFaceFeature(int dim, int plus); + + inline void getVertexFeature(int & plusX, int & plusY, int & plusZ) const; + inline void getEdgeFeature(int & dim0, int & plus0, int & dim1, int & plus1) const; + inline void getFaceFeature(int & dim, int & plus) const; +}; + +inline +void +BoxPoint::setVertexFeature(int plusX, int plusY, int plusZ) +{ + featureType = V; + featureIdx = plusX << 2 | plusY << 1 | plusZ; +} + +inline +void +BoxPoint::setEdgeFeature(int dim0, int plus0, int dim1, int plus1) +{ + featureType = E; + + if (dim0 > dim1) { + featureIdx = plus1 << 5 | dim1 << 3 | plus0 << 2 | dim0; + } else { + featureIdx = plus0 << 5 | dim0 << 3 | plus1 << 2 | dim1; + } +} + +inline +void +BoxPoint::setFaceFeature(int dim, int plus) +{ + featureType = F; + featureIdx = plus << 2 | dim; +} + +inline +void +BoxPoint::getVertexFeature(int & plusX, int & plusY, int & plusZ) const +{ + plusX = featureIdx >> 2; + plusY = featureIdx >> 1 & 1; + plusZ = featureIdx & 1; +} + +inline +void +BoxPoint::getEdgeFeature(int & dim0, int & plus0, int & dim1, int & plus1) const +{ + plus0 = featureIdx >> 5; + dim0 = featureIdx >> 3 & 3; + plus1 = featureIdx >> 2 & 1; + dim1 = featureIdx & 3; +} + +inline +void +BoxPoint::getFaceFeature(int & dim, int & plus) const +{ + plus = featureIdx >> 2; + dim = featureIdx & 3; +} + +#endif /* __BOX_H__ */ diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp new file mode 100644 index 0000000..8d755b2 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp @@ -0,0 +1,302 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "SpuCollisionShapes.h" + +///not supported on IBM SDK, until we fix the alignment of btVector3 +#if defined (__CELLOS_LV2__) && defined (__SPU__) +#include +static inline vec_float4 vec_dot3( vec_float4 vec0, vec_float4 vec1 ) +{ + vec_float4 result; + result = spu_mul( vec0, vec1 ); + result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); + return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result ); +} +#endif //__SPU__ + + +void computeAabb (btVector3& aabbMin, btVector3& aabbMax, btConvexInternalShape* convexShape, ppu_address_t convexShapePtr, int shapeType, const btTransform& xform) +{ + //calculate the aabb, given the types... + switch (shapeType) + { + case CYLINDER_SHAPE_PROXYTYPE: + /* fall through */ + case BOX_SHAPE_PROXYTYPE: + { + btScalar margin=convexShape->getMarginNV(); + btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); + halfExtents += btVector3(margin,margin,margin); + const btTransform& t = xform; + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3( abs_b[0], abs_b[1], abs_b[2] ); + + aabbMin = center - extent; + aabbMax = center + extent; + break; + } + case CAPSULE_SHAPE_PROXYTYPE: + { + btScalar margin=convexShape->getMarginNV(); + btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); + //add the radius to y-axis to get full height + btScalar radius = halfExtents[0]; + halfExtents[1] += radius; + halfExtents += btVector3(margin,margin,margin); +#if 0 + int capsuleUpAxis = convexShape->getUpAxis(); + btScalar halfHeight = convexShape->getHalfHeight(); + btScalar radius = convexShape->getRadius(); + halfExtents[capsuleUpAxis] = radius + halfHeight; +#endif + const btTransform& t = xform; + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3( abs_b[0], abs_b[1], abs_b[2] ); + + aabbMin = center - extent; + aabbMax = center + extent; + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + btScalar radius = convexShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX(); + btScalar margin = radius + convexShape->getMarginNV(); + const btTransform& t = xform; + const btVector3& center = t.getOrigin(); + btVector3 extent(margin,margin,margin); + aabbMin = center - extent; + aabbMax = center + extent; + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]); + cellDmaGet(&convexHullShape0, convexShapePtr , sizeof(btConvexHullShape), DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + btConvexHullShape* localPtr = (btConvexHullShape*)&convexHullShape0; + const btTransform& t = xform; + btScalar margin = convexShape->getMarginNV(); + localPtr->getNonvirtualAabb(t,aabbMin,aabbMax,margin); + //spu_printf("SPU convex aabbMin=%f,%f,%f=\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ()); + //spu_printf("SPU convex aabbMax=%f,%f,%f=\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ()); + break; + } + default: + { + // spu_printf("SPU: unsupported shapetype %d in AABB calculation\n"); + } + }; +} + +void dmaBvhShapeData (bvhMeshShape_LocalStoreMemory* bvhMeshShape, btBvhTriangleMeshShape* triMeshShape) +{ + register int dmaSize; + register ppu_address_t dmaPpuAddress2; + + dmaSize = sizeof(btTriangleIndexVertexArray); + dmaPpuAddress2 = reinterpret_cast(triMeshShape->getMeshInterface()); + // spu_printf("trimeshShape->getMeshInterface() == %llx\n",dmaPpuAddress2); +#ifdef __SPU__ + cellDmaGet(&bvhMeshShape->gTriangleMeshInterfaceStorage, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + bvhMeshShape->gTriangleMeshInterfacePtr = &bvhMeshShape->gTriangleMeshInterfaceStorage; +#else + bvhMeshShape->gTriangleMeshInterfacePtr = (btTriangleIndexVertexArray*)cellDmaGetReadOnly(&bvhMeshShape->gTriangleMeshInterfaceStorage, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); +#endif + + //cellDmaWaitTagStatusAll(DMA_MASK(1)); + + ///now DMA over the BVH + + dmaSize = sizeof(btOptimizedBvh); + dmaPpuAddress2 = reinterpret_cast(triMeshShape->getOptimizedBvh()); + //spu_printf("trimeshShape->getOptimizedBvh() == %llx\n",dmaPpuAddress2); + cellDmaGet(&bvhMeshShape->gOptimizedBvh, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0); + //cellDmaWaitTagStatusAll(DMA_MASK(2)); + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); +} + +void dmaBvhIndexedMesh (btIndexedMesh* IndexMesh, IndexedMeshArray& indexArray, int index, uint32_t dmaTag) +{ + cellDmaGet(IndexMesh, (ppu_address_t)&indexArray[index] , sizeof(btIndexedMesh), DMA_TAG(dmaTag), 0, 0); + +} + +void dmaBvhSubTreeHeaders (btBvhSubtreeInfo* subTreeHeaders, ppu_address_t subTreePtr, int batchSize, uint32_t dmaTag) +{ + cellDmaGet(subTreeHeaders, subTreePtr, batchSize * sizeof(btBvhSubtreeInfo), DMA_TAG(dmaTag), 0, 0); +} + +void dmaBvhSubTreeNodes (btQuantizedBvhNode* nodes, const btBvhSubtreeInfo& subtree, QuantizedNodeArray& nodeArray, int dmaTag) +{ + cellDmaGet(nodes, reinterpret_cast(&nodeArray[subtree.m_rootNodeIndex]) , subtree.m_subtreeSize* sizeof(btQuantizedBvhNode), DMA_TAG(2), 0, 0); +} + +///getShapeTypeSize could easily be optimized, but it is not likely a bottleneck +int getShapeTypeSize(int shapeType) +{ + + + switch (shapeType) + { + case CYLINDER_SHAPE_PROXYTYPE: + { + int shapeSize = sizeof(btCylinderShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + case BOX_SHAPE_PROXYTYPE: + { + int shapeSize = sizeof(btBoxShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + case SPHERE_SHAPE_PROXYTYPE: + { + int shapeSize = sizeof(btSphereShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + case TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + int shapeSize = sizeof(btBvhTriangleMeshShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + case CAPSULE_SHAPE_PROXYTYPE: + { + int shapeSize = sizeof(btCapsuleShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + int shapeSize = sizeof(btConvexHullShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + + case COMPOUND_SHAPE_PROXYTYPE: + { + int shapeSize = sizeof(btCompoundShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + case STATIC_PLANE_PROXYTYPE: + { + int shapeSize = sizeof(btStaticPlaneShape); + btAssert(shapeSize < MAX_SHAPE_SIZE); + return shapeSize; + } + + default: + btAssert(0); + //unsupported shapetype, please add here + return 0; + } +} + +void dmaConvexVertexData (SpuConvexPolyhedronVertexData* convexVertexData, btConvexHullShape* convexShapeSPU) +{ + convexVertexData->gNumConvexPoints = convexShapeSPU->getNumPoints(); + if (convexVertexData->gNumConvexPoints>MAX_NUM_SPU_CONVEX_POINTS) + { + btAssert(0); + // spu_printf("SPU: Error: MAX_NUM_SPU_CONVEX_POINTS(%d) exceeded: %d\n",MAX_NUM_SPU_CONVEX_POINTS,convexVertexData->gNumConvexPoints); + return; + } + + register int dmaSize = convexVertexData->gNumConvexPoints*sizeof(btVector3); + ppu_address_t pointsPPU = (ppu_address_t) convexShapeSPU->getUnscaledPoints(); + cellDmaGet(&convexVertexData->g_convexPointBuffer[0], pointsPPU , dmaSize, DMA_TAG(2), 0, 0); +} + +void dmaCollisionShape (void* collisionShapeLocation, ppu_address_t collisionShapePtr, uint32_t dmaTag, int shapeType) +{ + register int dmaSize = getShapeTypeSize(shapeType); + cellDmaGet(collisionShapeLocation, collisionShapePtr , dmaSize, DMA_TAG(dmaTag), 0, 0); + //cellDmaGetReadOnly(collisionShapeLocation, collisionShapePtr , dmaSize, DMA_TAG(dmaTag), 0, 0); + //cellDmaWaitTagStatusAll(DMA_MASK(dmaTag)); +} + +void dmaCompoundShapeInfo (CompoundShape_LocalStoreMemory* compoundShapeLocation, btCompoundShape* spuCompoundShape, uint32_t dmaTag) +{ + register int dmaSize; + register ppu_address_t dmaPpuAddress2; + int childShapeCount = spuCompoundShape->getNumChildShapes(); + dmaSize = childShapeCount * sizeof(btCompoundShapeChild); + dmaPpuAddress2 = (ppu_address_t)spuCompoundShape->getChildList(); + cellDmaGet(&compoundShapeLocation->gSubshapes[0], dmaPpuAddress2, dmaSize, DMA_TAG(dmaTag), 0, 0); +} + +void dmaCompoundSubShapes (CompoundShape_LocalStoreMemory* compoundShapeLocation, btCompoundShape* spuCompoundShape, uint32_t dmaTag) +{ + int childShapeCount = spuCompoundShape->getNumChildShapes(); + int i; + // DMA all the subshapes + for ( i = 0; i < childShapeCount; ++i) + { + btCompoundShapeChild& childShape = compoundShapeLocation->gSubshapes[i]; + dmaCollisionShape (&compoundShapeLocation->gSubshapeShape[i],(ppu_address_t)childShape.m_childShape, dmaTag, childShape.m_childShapeType); + } +} + + +void spuWalkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,const btQuantizedBvhNode* rootNode,int startNodeIndex,int endNodeIndex) +{ + + int curIndex = startNodeIndex; + int walkIterations = 0; +#ifdef BT_DEBUG + int subTreeSize = endNodeIndex - startNodeIndex; +#endif + + int escapeIndex; + + unsigned int aabbOverlap, isLeafNode; + + while (curIndex < endNodeIndex) + { + //catch bugs in tree data + btAssert (walkIterations < subTreeSize); + + walkIterations++; + aabbOverlap = spuTestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + isLeafNode = rootNode->isLeafNode(); + + if (isLeafNode && aabbOverlap) + { + //printf("overlap with node %d\n",rootNode->getTriangleIndex()); + nodeCallback->processNode(0,rootNode->getTriangleIndex()); + // spu_printf("SPU: overlap detected with triangleIndex:%d\n",rootNode->getTriangleIndex()); + } + + if (aabbOverlap || isLeafNode) + { + rootNode++; + curIndex++; + } else + { + escapeIndex = rootNode->getEscapeIndex(); + rootNode += escapeIndex; + curIndex += escapeIndex; + } + } + +} diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h new file mode 100644 index 0000000..aa8a291 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h @@ -0,0 +1,128 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef __SPU_COLLISION_SHAPES_H +#define __SPU_COLLISION_SHAPES_H + +#include "../SpuDoubleBuffer.h" + +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionShapes/btConvexInternalShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" + +#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" + +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" + +#define MAX_NUM_SPU_CONVEX_POINTS 128 //@fallback to PPU if a btConvexHullShape has more than MAX_NUM_SPU_CONVEX_POINTS points +#define MAX_SPU_COMPOUND_SUBSHAPES 16 //@fallback on PPU if compound has more than MAX_SPU_COMPOUND_SUBSHAPES child shapes +#define MAX_SHAPE_SIZE 256 //@todo: assert on this + +ATTRIBUTE_ALIGNED16(struct) SpuConvexPolyhedronVertexData +{ + void* gSpuConvexShapePtr; + btVector3* gConvexPoints; + int gNumConvexPoints; + int unused; + ATTRIBUTE_ALIGNED16(btVector3 g_convexPointBuffer[MAX_NUM_SPU_CONVEX_POINTS]); +}; + + + +ATTRIBUTE_ALIGNED16(struct) CollisionShape_LocalStoreMemory +{ + ATTRIBUTE_ALIGNED16(char collisionShape[MAX_SHAPE_SIZE]); +}; + +ATTRIBUTE_ALIGNED16(struct) CompoundShape_LocalStoreMemory +{ + // Compound data + + ATTRIBUTE_ALIGNED16(btCompoundShapeChild gSubshapes[MAX_SPU_COMPOUND_SUBSHAPES]); + ATTRIBUTE_ALIGNED16(char gSubshapeShape[MAX_SPU_COMPOUND_SUBSHAPES][MAX_SHAPE_SIZE]); +}; + +ATTRIBUTE_ALIGNED16(struct) bvhMeshShape_LocalStoreMemory +{ + //ATTRIBUTE_ALIGNED16(btOptimizedBvh gOptimizedBvh); + ATTRIBUTE_ALIGNED16(char gOptimizedBvh[sizeof(btOptimizedBvh)+16]); + btOptimizedBvh* getOptimizedBvh() + { + return (btOptimizedBvh*) gOptimizedBvh; + } + + ATTRIBUTE_ALIGNED16(btTriangleIndexVertexArray gTriangleMeshInterfaceStorage); + btTriangleIndexVertexArray* gTriangleMeshInterfacePtr; + ///only a single mesh part for now, we can add support for multiple parts, but quantized trees don't support this at the moment + ATTRIBUTE_ALIGNED16(btIndexedMesh gIndexMesh); + #define MAX_SPU_SUBTREE_HEADERS 32 + //1024 + ATTRIBUTE_ALIGNED16(btBvhSubtreeInfo gSubtreeHeaders[MAX_SPU_SUBTREE_HEADERS]); + ATTRIBUTE_ALIGNED16(btQuantizedBvhNode gSubtreeNodes[MAX_SUBTREE_SIZE_IN_BYTES/sizeof(btQuantizedBvhNode)]); +}; + + +void computeAabb (btVector3& aabbMin, btVector3& aabbMax, btConvexInternalShape* convexShape, ppu_address_t convexShapePtr, int shapeType, const btTransform& xform); +void dmaBvhShapeData (bvhMeshShape_LocalStoreMemory* bvhMeshShape, btBvhTriangleMeshShape* triMeshShape); +void dmaBvhIndexedMesh (btIndexedMesh* IndexMesh, IndexedMeshArray& indexArray, int index, uint32_t dmaTag); +void dmaBvhSubTreeHeaders (btBvhSubtreeInfo* subTreeHeaders, ppu_address_t subTreePtr, int batchSize, uint32_t dmaTag); +void dmaBvhSubTreeNodes (btQuantizedBvhNode* nodes, const btBvhSubtreeInfo& subtree, QuantizedNodeArray& nodeArray, int dmaTag); + +int getShapeTypeSize(int shapeType); +void dmaConvexVertexData (SpuConvexPolyhedronVertexData* convexVertexData, btConvexHullShape* convexShapeSPU); +void dmaCollisionShape (void* collisionShapeLocation, ppu_address_t collisionShapePtr, uint32_t dmaTag, int shapeType); +void dmaCompoundShapeInfo (CompoundShape_LocalStoreMemory* compoundShapeLocation, btCompoundShape* spuCompoundShape, uint32_t dmaTag); +void dmaCompoundSubShapes (CompoundShape_LocalStoreMemory* compoundShapeLocation, btCompoundShape* spuCompoundShape, uint32_t dmaTag); + + +#define USE_BRANCHFREE_TEST 1 +#ifdef USE_BRANCHFREE_TEST +SIMD_FORCE_INLINE unsigned int spuTestQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) +{ +#if defined(__CELLOS_LV2__) && defined (__SPU__) + vec_ushort8 vecMin = {aabbMin1[0],aabbMin2[0],aabbMin1[2],aabbMin2[2],aabbMin1[1],aabbMin2[1],0,0}; + vec_ushort8 vecMax = {aabbMax2[0],aabbMax1[0],aabbMax2[2],aabbMax1[2],aabbMax2[1],aabbMax1[1],0,0}; + vec_ushort8 isGt = spu_cmpgt(vecMin,vecMax); + return spu_extract(spu_gather(isGt),0)==0; + +#else + return btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) + & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) + & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), + 1, 0); +#endif +} +#else + +SIMD_FORCE_INLINE unsigned int spuTestQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) +{ + unsigned int overlap = 1; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? 0 : overlap; + overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? 0 : overlap; + overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? 0 : overlap; + return overlap; +} +#endif + +void spuWalkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,const btQuantizedBvhNode* rootNode,int startNodeIndex,int endNodeIndex); + +#endif diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp new file mode 100644 index 0000000..8584e74 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp @@ -0,0 +1,248 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SpuContactResult.h" + +//#define DEBUG_SPU_COLLISION_DETECTION 1 + +#ifdef DEBUG_SPU_COLLISION_DETECTION +#ifndef __SPU__ +#include +#define spu_printf printf +#endif +#endif //DEBUG_SPU_COLLISION_DETECTION + +SpuContactResult::SpuContactResult() +{ + m_manifoldAddress = 0; + m_spuManifold = NULL; + m_RequiresWriteBack = false; +} + + SpuContactResult::~SpuContactResult() +{ + g_manifoldDmaExport.swapBuffers(); +} + + ///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(btScalar friction0,btScalar friction1) +{ + btScalar friction = friction0*friction1; + + const btScalar MAX_FRICTION = btScalar(10.); + + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(btScalar restitution0,btScalar restitution1) +{ + return restitution0*restitution1; +} + + + + void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, ppu_address_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction1, bool isSwapped) + { + //spu_printf("SpuContactResult::setContactInfo ManifoldAddress: %lu\n", manifoldAddress); + m_rootWorldTransform0 = worldTrans0; + m_rootWorldTransform1 = worldTrans1; + m_manifoldAddress = manifoldAddress; + m_spuManifold = spuManifold; + + m_combinedFriction = calculateCombinedFriction(friction0,friction1); + m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); + m_isSwapped = isSwapped; + } + + void SpuContactResult::setShapeIdentifiersA(int partId0,int index0) + { + + } + + void SpuContactResult::setShapeIdentifiersB(int partId1,int index1) + { + + } + + + + ///return true if it requires a dma transfer back +bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld, + const btVector3& pointInWorld, + float depth, + btPersistentManifold* manifoldPtr, + btTransform& transA, + btTransform& transB, + btScalar combinedFriction, + btScalar combinedRestitution, + bool isSwapped) +{ + +// float contactTreshold = manifoldPtr->getContactBreakingThreshold(); + + //spu_printf("SPU: add contactpoint, depth:%f, contactTreshold %f, manifoldPtr %llx\n",depth,contactTreshold,manifoldPtr); + +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("SPU: contactTreshold %f\n",contactTreshold); +#endif //DEBUG_SPU_COLLISION_DETECTION + if (depth > manifoldPtr->getContactBreakingThreshold()) + return false; + + //if (depth > manifoldPtr->getContactProcessingThreshold()) + // return false; + + + + btVector3 pointA; + btVector3 localA; + btVector3 localB; + btVector3 normal; + + + if (isSwapped) + { + normal = normalOnBInWorld * -1; + pointA = pointInWorld + normal * depth; + localA = transA.invXform(pointA ); + localB = transB.invXform(pointInWorld); + } + else + { + normal = normalOnBInWorld; + pointA = pointInWorld + normal * depth; + localA = transA.invXform(pointA ); + localB = transB.invXform(pointInWorld); + } + + btManifoldPoint newPt(localA,localB,normal,depth); + newPt.m_positionWorldOnA = pointA; + newPt.m_positionWorldOnB = pointInWorld; + + newPt.m_combinedFriction = combinedFriction; + newPt.m_combinedRestitution = combinedRestitution; + + + int insertIndex = manifoldPtr->getCacheEntry(newPt); + if (insertIndex >= 0) + { + // we need to replace the current contact point, otherwise small errors will accumulate (spheres start rolling etc) + manifoldPtr->replaceContactPoint(newPt,insertIndex); + return true; + + } else + { + + /* + ///@todo: SPU callbacks, either immediate (local on the SPU), or deferred + //User can override friction and/or restitution + if (gContactAddedCallback && + //and if either of the two bodies requires custom material + ((m_body0->m_collisionFlags & btCollisionObject::customMaterialCallback) || + (m_body1->m_collisionFlags & btCollisionObject::customMaterialCallback))) + { + //experimental feature info, for per-triangle material etc. + (*gContactAddedCallback)(newPt,m_body0,m_partId0,m_index0,m_body1,m_partId1,m_index1); + } + */ + + manifoldPtr->addManifoldPoint(newPt); + return true; + + } + return false; + +} + + +void SpuContactResult::writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold) +{ + ///only write back the contact information on SPU. Other platforms avoid copying, and use the data in-place + ///see SpuFakeDma.cpp 'cellDmaLargeGetReadOnly' +#if defined (__SPU__) || defined (USE_LIBSPE2) + memcpy(g_manifoldDmaExport.getFront(),lsManifold,sizeof(btPersistentManifold)); + + g_manifoldDmaExport.swapBuffers(); + ppu_address_t mmAddr = (ppu_address_t)mmManifold; + g_manifoldDmaExport.backBufferDmaPut(mmAddr, sizeof(btPersistentManifold), DMA_TAG(9)); + // Should there be any kind of wait here? What if somebody tries to use this tag again? What if we call this function again really soon? + //no, the swapBuffers does the wait +#endif +} + +void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) +{ +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("*** SpuContactResult::addContactPoint: depth = %f\n",depth); + spu_printf("*** normal = %f,%f,%f\n",normalOnBInWorld.getX(),normalOnBInWorld.getY(),normalOnBInWorld.getZ()); + spu_printf("*** position = %f,%f,%f\n",pointInWorld.getX(),pointInWorld.getY(),pointInWorld.getZ()); +#endif //DEBUG_SPU_COLLISION_DETECTION + + +#ifdef DEBUG_SPU_COLLISION_DETECTION + // int sman = sizeof(rage::phManifold); +// spu_printf("sizeof_manifold = %i\n",sman); +#endif //DEBUG_SPU_COLLISION_DETECTION + + btPersistentManifold* localManifold = m_spuManifold; + + btVector3 normalB(normalOnBInWorld.getX(),normalOnBInWorld.getY(),normalOnBInWorld.getZ()); + btVector3 pointWrld(pointInWorld.getX(),pointInWorld.getY(),pointInWorld.getZ()); + + //process the contact point + const bool retVal = ManifoldResultAddContactPoint(normalB, + pointWrld, + depth, + localManifold, + m_rootWorldTransform0, + m_rootWorldTransform1, + m_combinedFriction, + m_combinedRestitution, + m_isSwapped); + m_RequiresWriteBack = m_RequiresWriteBack || retVal; +} + +void SpuContactResult::flush() +{ + + if (m_spuManifold && m_spuManifold->getNumContacts()) + { + m_spuManifold->refreshContactPoints(m_rootWorldTransform0,m_rootWorldTransform1); + m_RequiresWriteBack = true; + } + + + if (m_RequiresWriteBack) + { +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("SPU: Start SpuContactResult::flush (Put) DMA\n"); + spu_printf("Num contacts:%d\n", m_spuManifold->getNumContacts()); + spu_printf("Manifold address: %llu\n", m_manifoldAddress); +#endif //DEBUG_SPU_COLLISION_DETECTION + // spu_printf("writeDoubleBufferedManifold\n"); + writeDoubleBufferedManifold(m_spuManifold, (btPersistentManifold*)m_manifoldAddress); +#ifdef DEBUG_SPU_COLLISION_DETECTION + spu_printf("SPU: Finished (Put) DMA\n"); +#endif //DEBUG_SPU_COLLISION_DETECTION + } + m_spuManifold = NULL; + m_RequiresWriteBack = false; +} + + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h new file mode 100644 index 0000000..394f56d --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h @@ -0,0 +1,106 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SPU_CONTACT_RESULT2_H +#define SPU_CONTACT_RESULT2_H + + +#ifndef _WIN32 +#include +#endif + + + +#include "../SpuDoubleBuffer.h" + + +#include "LinearMath/btTransform.h" + + +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" + +class btCollisionShape; + + +struct SpuCollisionPairInput +{ + ppu_address_t m_collisionShapes[2]; + btCollisionShape* m_spuCollisionShapes[2]; + + ppu_address_t m_persistentManifoldPtr; + btVector3 m_primitiveDimensions0; + btVector3 m_primitiveDimensions1; + int m_shapeType0; + int m_shapeType1; + float m_collisionMargin0; + float m_collisionMargin1; + + btTransform m_worldTransform0; + btTransform m_worldTransform1; + + bool m_isSwapped; + bool m_useEpa; +}; + + +struct SpuClosestPointInput : public btDiscreteCollisionDetectorInterface::ClosestPointInput +{ + struct SpuConvexPolyhedronVertexData* m_convexVertexData[2]; +}; + +///SpuContactResult exports the contact points using double-buffered DMA transfers, only when needed +///So when an existing contact point is duplicated, no transfer/refresh is performed. +class SpuContactResult : public btDiscreteCollisionDetectorInterface::Result +{ + btTransform m_rootWorldTransform0; + btTransform m_rootWorldTransform1; + ppu_address_t m_manifoldAddress; + + btPersistentManifold* m_spuManifold; + bool m_RequiresWriteBack; + btScalar m_combinedFriction; + btScalar m_combinedRestitution; + + bool m_isSwapped; + + DoubleBuffer g_manifoldDmaExport; + + public: + SpuContactResult(); + virtual ~SpuContactResult(); + + btPersistentManifold* GetSpuManifold() const + { + return m_spuManifold; + } + + virtual void setShapeIdentifiersA(int partId0,int index0); + virtual void setShapeIdentifiersB(int partId1,int index1); + + void setContactInfo(btPersistentManifold* spuManifold, ppu_address_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction01, bool isSwapped); + + + void writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold); + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth); + + void flush(); +}; + + + +#endif //SPU_CONTACT_RESULT2_H + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h new file mode 100644 index 0000000..449f192 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h @@ -0,0 +1,51 @@ + +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef SPU_CONVEX_PENETRATION_DEPTH_H +#define SPU_CONVEX_PENETRATION_DEPTH_H + + + +class btStackAlloc; +class btIDebugDraw; +#include "BulletCollision/NarrowphaseCollision/btConvexPenetrationDepthSolver.h" + +#include "LinearMath/btTransform.h" + + +///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation. +class SpuConvexPenetrationDepthSolver : public btConvexPenetrationDepthSolver +{ +public: + + virtual ~SpuConvexPenetrationDepthSolver() {}; + virtual bool calcPenDepth( SpuVoronoiSimplexSolver& simplexSolver, + void* convexA,void* convexB,int shapeTypeA, int shapeTypeB, float marginA, float marginB, + btTransform& transA,const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc, + struct SpuConvexPolyhedronVertexData* convexVertexDataA, + struct SpuConvexPolyhedronVertexData* convexVertexDataB + ) const = 0; + + +}; + + + +#endif //SPU_CONVEX_PENETRATION_DEPTH_H + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp new file mode 100644 index 0000000..46e4d98 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp @@ -0,0 +1,1432 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SpuGatheringCollisionTask.h" + +//#define DEBUG_SPU_COLLISION_DETECTION 1 +#include "../SpuDoubleBuffer.h" + +#include "../SpuCollisionTaskProcess.h" +#include "../SpuGatheringCollisionDispatcher.h" //for SPU_BATCHSIZE_BROADPHASE_PAIRS + +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "../SpuContactManifoldCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "SpuContactResult.h" +#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btConvexPointCloudShape.h" + +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" + +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" + +#include "SpuMinkowskiPenetrationDepthSolver.h" +//#include "SpuEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" + + +#include "boxBoxDistance.h" +#include "BulletMultiThreaded/vectormath2bullet.h" +#include "SpuCollisionShapes.h" //definition of SpuConvexPolyhedronVertexData +#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" + +#ifdef __SPU__ +///Software caching from the IBM Cell SDK, it reduces 25% SPU time for our test cases +#ifndef USE_LIBSPE2 +//#define USE_SOFTWARE_CACHE 1 +#endif +#endif //__SPU__ + +int gSkippedCol = 0; +int gProcessedCol = 0; + +//////////////////////////////////////////////// +/// software caching +#if USE_SOFTWARE_CACHE +#include +#include +#include +#include +#define SPE_CACHE_NWAY 4 +//#define SPE_CACHE_NSETS 32, 16 +#define SPE_CACHE_NSETS 8 +//#define SPE_CACHELINE_SIZE 512 +#define SPE_CACHELINE_SIZE 128 +#define SPE_CACHE_SET_TAGID(set) 15 +///make sure that spe_cache.h is below those defines! +#include "../Extras/software_cache/cache/include/spe_cache.h" + + +int g_CacheMisses=0; +int g_CacheHits=0; + +#if 0 // Added to allow cache misses and hits to be tracked, change this to 1 to restore unmodified version +#define spe_cache_read(ea) _spe_cache_lookup_xfer_wait_(ea, 0, 1) +#else +#define spe_cache_read(ea) \ +({ \ + int set, idx, line, byte; \ + _spe_cache_nway_lookup_(ea, set, idx); \ + \ + if (btUnlikely(idx < 0)) { \ + ++g_CacheMisses; \ + idx = _spe_cache_miss_(ea, set, -1); \ + spu_writech(22, SPE_CACHE_SET_TAGMASK(set)); \ + spu_mfcstat(MFC_TAG_UPDATE_ALL); \ + } \ + else \ + { \ + ++g_CacheHits; \ + } \ + line = _spe_cacheline_num_(set, idx); \ + byte = _spe_cacheline_byte_offset_(ea); \ + (void *) &spe_cache_mem[line + byte]; \ +}) + +#endif + +#endif // USE_SOFTWARE_CACHE + +bool gUseEpa = false; + +#ifdef USE_SN_TUNER +#include +#endif //USE_SN_TUNER + +#if defined (__SPU__) && !defined (USE_LIBSPE2) +#include +#elif defined (USE_LIBSPE2) +#define spu_printf(a) +#else +#define IGNORE_ALIGNMENT 1 +#include +#include +#define spu_printf printf + +#endif + +//int gNumConvexPoints0=0; + +///Make sure no destructors are called on this memory +struct CollisionTask_LocalStoreMemory +{ + ///This CollisionTask_LocalStoreMemory is mainly used for the SPU version, using explicit DMA + ///Other platforms can use other memory programming models. + + ATTRIBUTE_ALIGNED16(btBroadphasePair gBroadphasePairsBuffer[SPU_BATCHSIZE_BROADPHASE_PAIRS]); + DoubleBuffer g_workUnitTaskBuffers; + ATTRIBUTE_ALIGNED16(char gSpuContactManifoldAlgoBuffer [sizeof(SpuContactManifoldCollisionAlgorithm)+16]); + ATTRIBUTE_ALIGNED16(char gColObj0Buffer [sizeof(btCollisionObject)+16]); + ATTRIBUTE_ALIGNED16(char gColObj1Buffer [sizeof(btCollisionObject)+16]); + ///we reserve 32bit integer indices, even though they might be 16bit + ATTRIBUTE_ALIGNED16(int spuIndices[16]); + btPersistentManifold gPersistentManifoldBuffer; + CollisionShape_LocalStoreMemory gCollisionShapes[2]; + bvhMeshShape_LocalStoreMemory bvhShapeData; + SpuConvexPolyhedronVertexData convexVertexData[2]; + CompoundShape_LocalStoreMemory compoundShapeData[2]; + + ///The following pointers might either point into this local store memory, or to the original/other memory locations. + ///See SpuFakeDma for implementation of cellDmaSmallGetReadOnly. + btCollisionObject* m_lsColObj0Ptr; + btCollisionObject* m_lsColObj1Ptr; + btBroadphasePair* m_pairsPointer; + btPersistentManifold* m_lsManifoldPtr; + SpuContactManifoldCollisionAlgorithm* m_lsCollisionAlgorithmPtr; + + bool needsDmaPutContactManifoldAlgo; + + btCollisionObject* getColObj0() + { + return m_lsColObj0Ptr; + } + btCollisionObject* getColObj1() + { + return m_lsColObj1Ptr; + } + + + btBroadphasePair* getBroadphasePairPtr() + { + return m_pairsPointer; + } + + SpuContactManifoldCollisionAlgorithm* getlocalCollisionAlgorithm() + { + return m_lsCollisionAlgorithmPtr; + } + + btPersistentManifold* getContactManifoldPtr() + { + return m_lsManifoldPtr; + } +}; + + +#if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2) + +ATTRIBUTE_ALIGNED16(CollisionTask_LocalStoreMemory gLocalStoreMemory); + +void* createCollisionLocalStoreMemory() +{ + return &gLocalStoreMemory; +} +void deleteCollisionLocalStoreMemory() +{ +} +#else + +btAlignedObjectArray sLocalStorePointers; + +void* createCollisionLocalStoreMemory() +{ + CollisionTask_LocalStoreMemory* localStore = new CollisionTask_LocalStoreMemory; + sLocalStorePointers.push_back(localStore); + return localStore; +} + +void deleteCollisionLocalStoreMemory() +{ + for (int i=0;ibvhShapeData.gIndexMesh.m_indexType == PHY_SHORT) + { + unsigned short int* indexBasePtr = (unsigned short int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride); + ATTRIBUTE_ALIGNED16(unsigned short int tmpIndices[3]); + + small_cache_read_triple(&tmpIndices[0],(ppu_address_t)&indexBasePtr[0], + &tmpIndices[1],(ppu_address_t)&indexBasePtr[1], + &tmpIndices[2],(ppu_address_t)&indexBasePtr[2], + sizeof(unsigned short int)); + + m_lsMemPtr->spuIndices[0] = int(tmpIndices[0]); + m_lsMemPtr->spuIndices[1] = int(tmpIndices[1]); + m_lsMemPtr->spuIndices[2] = int(tmpIndices[2]); + } else + { + unsigned int* indexBasePtr = (unsigned int*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexBase+triangleIndex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_triangleIndexStride); + + small_cache_read_triple(&m_lsMemPtr->spuIndices[0],(ppu_address_t)&indexBasePtr[0], + &m_lsMemPtr->spuIndices[1],(ppu_address_t)&indexBasePtr[1], + &m_lsMemPtr->spuIndices[2],(ppu_address_t)&indexBasePtr[2], + sizeof(int)); + } + + // spu_printf("SPU index0=%d ,",spuIndices[0]); + // spu_printf("SPU index1=%d ,",spuIndices[1]); + // spu_printf("SPU index2=%d ,",spuIndices[2]); + // spu_printf("SPU: indexBasePtr=%llx\n",indexBasePtr); + + const btVector3& meshScaling = m_lsMemPtr->bvhShapeData.gTriangleMeshInterfacePtr->getScaling(); + for (int j=2;btLikely( j>=0 );j--) + { + int graphicsindex = m_lsMemPtr->spuIndices[j]; + + // spu_printf("SPU index=%d ,",graphicsindex); + btScalar* graphicsbasePtr = (btScalar*)(m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexBase+graphicsindex*m_lsMemPtr->bvhShapeData.gIndexMesh.m_vertexStride); + // spu_printf("SPU graphicsbasePtr=%llx\n",graphicsbasePtr); + + + ///handle un-aligned vertices... + + //another DMA for each vertex + small_cache_read_triple(&spuUnscaledVertex[0],(ppu_address_t)&graphicsbasePtr[0], + &spuUnscaledVertex[1],(ppu_address_t)&graphicsbasePtr[1], + &spuUnscaledVertex[2],(ppu_address_t)&graphicsbasePtr[2], + sizeof(btScalar)); + + m_tmpTriangleShape.getVertexPtr(j).setValue(spuUnscaledVertex[0]*meshScaling.getX(), + spuUnscaledVertex[1]*meshScaling.getY(), + spuUnscaledVertex[2]*meshScaling.getZ()); + + // spu_printf("SPU:triangle vertices:%f,%f,%f\n",spuTriangleVertices[j].x(),spuTriangleVertices[j].y(),spuTriangleVertices[j].z()); + } + + + SpuCollisionPairInput triangleConcaveInput(*m_wuInput); +// triangleConcaveInput.m_spuCollisionShapes[1] = &spuTriangleVertices[0]; + triangleConcaveInput.m_spuCollisionShapes[1] = &m_tmpTriangleShape; + triangleConcaveInput.m_shapeType1 = TRIANGLE_SHAPE_PROXYTYPE; + + m_spuContacts.setShapeIdentifiersB(subPart,triangleIndex); + + // m_spuContacts.flush(); + + ProcessSpuConvexConvexCollision(&triangleConcaveInput, m_lsMemPtr,m_spuContacts); + ///this flush should be automatic + // m_spuContacts.flush(); + } + +}; + + + +void btConvexPlaneCollideSingleContact (SpuCollisionPairInput* wuInput,CollisionTask_LocalStoreMemory* lsMemPtr,SpuContactResult& spuContacts) +{ + + btConvexShape* convexShape = (btConvexShape*) wuInput->m_spuCollisionShapes[0]; + btStaticPlaneShape* planeShape = (btStaticPlaneShape*) wuInput->m_spuCollisionShapes[1]; + + bool hasCollision = false; + const btVector3& planeNormal = planeShape->getPlaneNormal(); + const btScalar& planeConstant = planeShape->getPlaneConstant(); + + + btTransform convexWorldTransform = wuInput->m_worldTransform0; + btTransform convexInPlaneTrans; + convexInPlaneTrans= wuInput->m_worldTransform1.inverse() * convexWorldTransform; + btTransform planeInConvex; + planeInConvex= convexWorldTransform.inverse() * wuInput->m_worldTransform1; + + //btVector3 vtx = convexShape->localGetSupportVertexWithoutMarginNonVirtual(planeInConvex.getBasis()*-planeNormal); + btVector3 vtx = convexShape->localGetSupportVertexNonVirtual(planeInConvex.getBasis()*-planeNormal); + + btVector3 vtxInPlane = convexInPlaneTrans(vtx); + btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); + + btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal; + btVector3 vtxInPlaneWorld = wuInput->m_worldTransform1 * vtxInPlaneProjected; + + hasCollision = distance < lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold(); + //resultOut->setPersistentManifold(m_manifoldPtr); + if (hasCollision) + { + /// report a contact. internally this will be kept persistent, and contact reduction is done + btVector3 normalOnSurfaceB =wuInput->m_worldTransform1.getBasis() * planeNormal; + btVector3 pOnB = vtxInPlaneWorld; + spuContacts.addContactPoint(normalOnSurfaceB,pOnB,distance); + } +} + +void ProcessConvexPlaneSpuCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts) +{ + + register int dmaSize = 0; + register ppu_address_t dmaPpuAddress2; + btPersistentManifold* manifold = (btPersistentManifold*)wuInput->m_persistentManifoldPtr; + + ///DMA in the vertices for convex shapes + ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]); + ATTRIBUTE_ALIGNED16(char convexHullShape1[sizeof(btConvexHullShape)]); + + if ( btLikely( wuInput->m_shapeType0== CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + // spu_printf("SPU: DMA btConvexHullShape\n"); + + dmaSize = sizeof(btConvexHullShape); + dmaPpuAddress2 = wuInput->m_collisionShapes[0]; + + cellDmaGet(&convexHullShape0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + //cellDmaWaitTagStatusAll(DMA_MASK(1)); + } + + if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + // spu_printf("SPU: DMA btConvexHullShape\n"); + dmaSize = sizeof(btConvexHullShape); + dmaPpuAddress2 = wuInput->m_collisionShapes[1]; + cellDmaGet(&convexHullShape1, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + //cellDmaWaitTagStatusAll(DMA_MASK(1)); + } + + if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(1)); + dmaConvexVertexData (&lsMemPtr->convexVertexData[0], (btConvexHullShape*)&convexHullShape0); + lsMemPtr->convexVertexData[0].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[0]; + } + + + if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(1)); + dmaConvexVertexData (&lsMemPtr->convexVertexData[1], (btConvexHullShape*)&convexHullShape1); + lsMemPtr->convexVertexData[1].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[1]; + } + + + btConvexPointCloudShape cpc0,cpc1; + + if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(2)); + lsMemPtr->convexVertexData[0].gConvexPoints = &lsMemPtr->convexVertexData[0].g_convexPointBuffer[0]; + btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[0]; + const btVector3& localScaling = ch->getLocalScalingNV(); + cpc0.setPoints(lsMemPtr->convexVertexData[0].gConvexPoints,lsMemPtr->convexVertexData[0].gNumConvexPoints,false,localScaling); + wuInput->m_spuCollisionShapes[0] = &cpc0; + } + + if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(2)); + lsMemPtr->convexVertexData[1].gConvexPoints = &lsMemPtr->convexVertexData[1].g_convexPointBuffer[0]; + btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[1]; + const btVector3& localScaling = ch->getLocalScalingNV(); + cpc1.setPoints(lsMemPtr->convexVertexData[1].gConvexPoints,lsMemPtr->convexVertexData[1].gNumConvexPoints,false,localScaling); + wuInput->m_spuCollisionShapes[1] = &cpc1; + + } + + +// const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0]; +// const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1]; +// int shapeType0 = wuInput->m_shapeType0; +// int shapeType1 = wuInput->m_shapeType1; + float marginA = wuInput->m_collisionMargin0; + float marginB = wuInput->m_collisionMargin1; + + SpuClosestPointInput cpInput; + cpInput.m_convexVertexData[0] = &lsMemPtr->convexVertexData[0]; + cpInput.m_convexVertexData[1] = &lsMemPtr->convexVertexData[1]; + cpInput.m_transformA = wuInput->m_worldTransform0; + cpInput.m_transformB = wuInput->m_worldTransform1; + float sumMargin = (marginA+marginB+lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold()); + cpInput.m_maximumDistanceSquared = sumMargin * sumMargin; + + ppu_address_t manifoldAddress = (ppu_address_t)manifold; + + btPersistentManifold* spuManifold=lsMemPtr->getContactManifoldPtr(); + //spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped); + spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(), + lsMemPtr->getColObj1()->getWorldTransform(), + lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(), + lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(), + wuInput->m_isSwapped); + + + btConvexPlaneCollideSingleContact(wuInput,lsMemPtr,spuContacts); + + + + +} + + + + +//////////////////////// +/// Convex versus Concave triangle mesh collision detection (handles concave triangle mesh versus sphere, box, cylinder, triangle, cone, convex polyhedron etc) +/////////////////// +void ProcessConvexConcaveSpuCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts) +{ + //order: first collision shape is convex, second concave. m_isSwapped is true, if the original order was opposite + + btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)wuInput->m_spuCollisionShapes[1]; + //need the mesh interface, for access to triangle vertices + dmaBvhShapeData (&lsMemPtr->bvhShapeData, trimeshShape); + + btVector3 aabbMin(-1,-400,-1); + btVector3 aabbMax(1,400,1); + + + //recalc aabbs + btTransform convexInTriangleSpace; + convexInTriangleSpace = wuInput->m_worldTransform1.inverse() * wuInput->m_worldTransform0; + btConvexInternalShape* convexShape = (btConvexInternalShape*)wuInput->m_spuCollisionShapes[0]; + + computeAabb (aabbMin, aabbMax, convexShape, wuInput->m_collisionShapes[0], wuInput->m_shapeType0, convexInTriangleSpace); + + + //CollisionShape* triangleShape = static_cast(triBody->m_collisionShape); + //convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax); + + // btScalar extraMargin = collisionMarginTriangle; + // btVector3 extra(extraMargin,extraMargin,extraMargin); + // aabbMax += extra; + // aabbMin -= extra; + + ///quantize query AABB + unsigned short int quantizedQueryAabbMin[3]; + unsigned short int quantizedQueryAabbMax[3]; + lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0); + lsMemPtr->bvhShapeData.getOptimizedBvh()->quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1); + + QuantizedNodeArray& nodeArray = lsMemPtr->bvhShapeData.getOptimizedBvh()->getQuantizedNodeArray(); + //spu_printf("SPU: numNodes = %d\n",nodeArray.size()); + + BvhSubtreeInfoArray& subTrees = lsMemPtr->bvhShapeData.getOptimizedBvh()->getSubtreeInfoArray(); + + + spuNodeCallback nodeCallback(wuInput,lsMemPtr,spuContacts); + IndexedMeshArray& indexArray = lsMemPtr->bvhShapeData.gTriangleMeshInterfacePtr->getIndexedMeshArray(); + //spu_printf("SPU:indexArray.size() = %d\n",indexArray.size()); + + // spu_printf("SPU: numSubTrees = %d\n",subTrees.size()); + //not likely to happen + if (subTrees.size() && indexArray.size() == 1) + { + ///DMA in the index info + dmaBvhIndexedMesh (&lsMemPtr->bvhShapeData.gIndexMesh, indexArray, 0 /* index into indexArray */, 1 /* dmaTag */); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + //display the headers + int numBatch = subTrees.size(); + for (int i=0;ibvhShapeData.gSubtreeHeaders[0], (ppu_address_t)(&subTrees[i]), nextBatch, 1); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + + // spu_printf("nextBatch = %d\n",nextBatch); + + for (int j=0;jbvhShapeData.gSubtreeHeaders[j]; + + unsigned int overlap = spuTestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + if (overlap) + { + btAssert(subtree.m_subtreeSize); + + //dma the actual nodes of this subtree + dmaBvhSubTreeNodes (&lsMemPtr->bvhShapeData.gSubtreeNodes[0], subtree, nodeArray, 2); + cellDmaWaitTagStatusAll(DMA_MASK(2)); + + /* Walk this subtree */ + spuWalkStacklessQuantizedTree(&nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax, + &lsMemPtr->bvhShapeData.gSubtreeNodes[0], + 0, + subtree.m_subtreeSize); + } + // spu_printf("subtreeSize = %d\n",gSubtreeHeaders[j].m_subtreeSize); + } + + // unsigned short int m_quantizedAabbMin[3]; + // unsigned short int m_quantizedAabbMax[3]; + // int m_rootNodeIndex; + // int m_subtreeSize; + i+=nextBatch; + } + + //pre-fetch first tree, then loop and double buffer + } + +} + + +#define MAX_DEGENERATE_STATS 15 +int stats[MAX_DEGENERATE_STATS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +int degenerateStats[MAX_DEGENERATE_STATS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + +//////////////////////// +/// Convex versus Convex collision detection (handles collision between sphere, box, cylinder, triangle, cone, convex polyhedron etc) +/////////////////// +void ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTask_LocalStoreMemory* lsMemPtr, SpuContactResult& spuContacts) +{ + register int dmaSize; + register ppu_address_t dmaPpuAddress2; + +#ifdef DEBUG_SPU_COLLISION_DETECTION + //spu_printf("SPU: ProcessSpuConvexConvexCollision\n"); +#endif //DEBUG_SPU_COLLISION_DETECTION + //CollisionShape* shape0 = (CollisionShape*)wuInput->m_collisionShapes[0]; + //CollisionShape* shape1 = (CollisionShape*)wuInput->m_collisionShapes[1]; + btPersistentManifold* manifold = (btPersistentManifold*)wuInput->m_persistentManifoldPtr; + + bool genericGjk = true; + + if (genericGjk) + { + //try generic GJK + + + + //SpuConvexPenetrationDepthSolver* penetrationSolver=0; + btVoronoiSimplexSolver simplexSolver; + btGjkEpaPenetrationDepthSolver epaPenetrationSolver2; + + btConvexPenetrationDepthSolver* penetrationSolver = &epaPenetrationSolver2; + + //SpuMinkowskiPenetrationDepthSolver minkowskiPenetrationSolver; +#ifdef ENABLE_EPA + if (gUseEpa) + { + penetrationSolver = &epaPenetrationSolver2; + } else +#endif + { + //penetrationSolver = &minkowskiPenetrationSolver; + } + + + ///DMA in the vertices for convex shapes + ATTRIBUTE_ALIGNED16(char convexHullShape0[sizeof(btConvexHullShape)]); + ATTRIBUTE_ALIGNED16(char convexHullShape1[sizeof(btConvexHullShape)]); + + if ( btLikely( wuInput->m_shapeType0== CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + // spu_printf("SPU: DMA btConvexHullShape\n"); + + dmaSize = sizeof(btConvexHullShape); + dmaPpuAddress2 = wuInput->m_collisionShapes[0]; + + cellDmaGet(&convexHullShape0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + //cellDmaWaitTagStatusAll(DMA_MASK(1)); + } + + if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + // spu_printf("SPU: DMA btConvexHullShape\n"); + dmaSize = sizeof(btConvexHullShape); + dmaPpuAddress2 = wuInput->m_collisionShapes[1]; + cellDmaGet(&convexHullShape1, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + //cellDmaWaitTagStatusAll(DMA_MASK(1)); + } + + if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(1)); + dmaConvexVertexData (&lsMemPtr->convexVertexData[0], (btConvexHullShape*)&convexHullShape0); + lsMemPtr->convexVertexData[0].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[0]; + } + + + if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(1)); + dmaConvexVertexData (&lsMemPtr->convexVertexData[1], (btConvexHullShape*)&convexHullShape1); + lsMemPtr->convexVertexData[1].gSpuConvexShapePtr = wuInput->m_spuCollisionShapes[1]; + } + + + btConvexPointCloudShape cpc0,cpc1; + + if ( btLikely( wuInput->m_shapeType0 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(2)); + lsMemPtr->convexVertexData[0].gConvexPoints = &lsMemPtr->convexVertexData[0].g_convexPointBuffer[0]; + btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[0]; + const btVector3& localScaling = ch->getLocalScalingNV(); + cpc0.setPoints(lsMemPtr->convexVertexData[0].gConvexPoints,lsMemPtr->convexVertexData[0].gNumConvexPoints,false,localScaling); + wuInput->m_spuCollisionShapes[0] = &cpc0; + } + + if ( btLikely( wuInput->m_shapeType1 == CONVEX_HULL_SHAPE_PROXYTYPE ) ) + { + cellDmaWaitTagStatusAll(DMA_MASK(2)); + lsMemPtr->convexVertexData[1].gConvexPoints = &lsMemPtr->convexVertexData[1].g_convexPointBuffer[0]; + btConvexHullShape* ch = (btConvexHullShape*)wuInput->m_spuCollisionShapes[1]; + const btVector3& localScaling = ch->getLocalScalingNV(); + cpc1.setPoints(lsMemPtr->convexVertexData[1].gConvexPoints,lsMemPtr->convexVertexData[1].gNumConvexPoints,false,localScaling); + wuInput->m_spuCollisionShapes[1] = &cpc1; + + } + + + const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0]; + const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1]; + int shapeType0 = wuInput->m_shapeType0; + int shapeType1 = wuInput->m_shapeType1; + float marginA = wuInput->m_collisionMargin0; + float marginB = wuInput->m_collisionMargin1; + + SpuClosestPointInput cpInput; + cpInput.m_convexVertexData[0] = &lsMemPtr->convexVertexData[0]; + cpInput.m_convexVertexData[1] = &lsMemPtr->convexVertexData[1]; + cpInput.m_transformA = wuInput->m_worldTransform0; + cpInput.m_transformB = wuInput->m_worldTransform1; + float sumMargin = (marginA+marginB+lsMemPtr->getContactManifoldPtr()->getContactBreakingThreshold()); + cpInput.m_maximumDistanceSquared = sumMargin * sumMargin; + + ppu_address_t manifoldAddress = (ppu_address_t)manifold; + + btPersistentManifold* spuManifold=lsMemPtr->getContactManifoldPtr(); + //spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped); + spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(), + lsMemPtr->getColObj1()->getWorldTransform(), + lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(), + lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(), + wuInput->m_isSwapped); + + { + btGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&simplexSolver,penetrationSolver);//&vsSolver,penetrationSolver); + gjk.getClosestPoints(cpInput,spuContacts,0);//,debugDraw); + + btAssert(gjk.m_lastUsedMethod getContactBreakingThreshold(); + lsMemPtr->getlocalCollisionAlgorithm()->m_sepDistance.initSeparatingDistance(gjk.getCachedSeparatingAxis(),sepDist,wuInput->m_worldTransform0,wuInput->m_worldTransform1); + lsMemPtr->needsDmaPutContactManifoldAlgo = true; +#endif //USE_SEPDISTANCE_UTIL + + } + + } + + +} + + +template void DoSwap(T& a, T& b) +{ + char tmp[sizeof(T)]; + memcpy(tmp, &a, sizeof(T)); + memcpy(&a, &b, sizeof(T)); + memcpy(&b, tmp, sizeof(T)); +} + +SIMD_FORCE_INLINE void dmaAndSetupCollisionObjects(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem) +{ + register int dmaSize; + register ppu_address_t dmaPpuAddress2; + + dmaSize = sizeof(btCollisionObject);//btTransform); + dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr1->m_clientObject :*/ (ppu_address_t)lsMem.getlocalCollisionAlgorithm()->getCollisionObject0(); + lsMem.m_lsColObj0Ptr = (btCollisionObject*)cellDmaGetReadOnly(&lsMem.gColObj0Buffer, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + + dmaSize = sizeof(btCollisionObject);//btTransform); + dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (ppu_address_t)lsMem.gProxyPtr0->m_clientObject :*/ (ppu_address_t)lsMem.getlocalCollisionAlgorithm()->getCollisionObject1(); + lsMem.m_lsColObj1Ptr = (btCollisionObject*)cellDmaGetReadOnly(&lsMem.gColObj1Buffer, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0); + + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); + + btCollisionObject* ob0 = lsMem.getColObj0(); + btCollisionObject* ob1 = lsMem.getColObj1(); + + collisionPairInput.m_worldTransform0 = ob0->getWorldTransform(); + collisionPairInput.m_worldTransform1 = ob1->getWorldTransform(); +} + + + +void handleCollisionPair(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem, + SpuContactResult &spuContacts, + ppu_address_t collisionShape0Ptr, void* collisionShape0Loc, + ppu_address_t collisionShape1Ptr, void* collisionShape1Loc, bool dmaShapes = true) +{ + + if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0) + && btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1)) + { + if (dmaShapes) + { + dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0); + dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1); + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); + } + + btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc; + btConvexInternalShape* spuConvexShape1 = (btConvexInternalShape*)collisionShape1Loc; + + btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions(); + btVector3 dim1 = spuConvexShape1->getImplicitShapeDimensions(); + + collisionPairInput.m_primitiveDimensions0 = dim0; + collisionPairInput.m_primitiveDimensions1 = dim1; + collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr; + collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr; + collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0; + collisionPairInput.m_spuCollisionShapes[1] = spuConvexShape1; + ProcessSpuConvexConvexCollision(&collisionPairInput,&lsMem,spuContacts); + } + else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) && + btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1)) + { + //snPause(); + + dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0); + dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1); + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); + + // Both are compounds, do N^2 CD for now + ///@todo: add some AABB-based pruning (probably not -> slower) + + btCompoundShape* spuCompoundShape0 = (btCompoundShape*)collisionShape0Loc; + btCompoundShape* spuCompoundShape1 = (btCompoundShape*)collisionShape1Loc; + + dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape0, 1); + dmaCompoundShapeInfo (&lsMem.compoundShapeData[1], spuCompoundShape1, 2); + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); + + + dmaCompoundSubShapes (&lsMem.compoundShapeData[0], spuCompoundShape0, 1); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + dmaCompoundSubShapes (&lsMem.compoundShapeData[1], spuCompoundShape1, 1); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + int childShapeCount0 = spuCompoundShape0->getNumChildShapes(); + btAssert(childShapeCount0< MAX_SPU_COMPOUND_SUBSHAPES); + int childShapeCount1 = spuCompoundShape1->getNumChildShapes(); + btAssert(childShapeCount1< MAX_SPU_COMPOUND_SUBSHAPES); + + // Start the N^2 + for (int i = 0; i < childShapeCount0; ++i) + { + btCompoundShapeChild& childShape0 = lsMem.compoundShapeData[0].gSubshapes[i]; + btAssert(!btBroadphaseProxy::isCompound(childShape0.m_childShapeType)); + + for (int j = 0; j < childShapeCount1; ++j) + { + btCompoundShapeChild& childShape1 = lsMem.compoundShapeData[1].gSubshapes[j]; + btAssert(!btBroadphaseProxy::isCompound(childShape1.m_childShapeType)); + + + /* Create a new collision pair input struct using the two child shapes */ + SpuCollisionPairInput cinput (collisionPairInput); + + cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape0.m_transform; + cinput.m_shapeType0 = childShape0.m_childShapeType; + cinput.m_collisionMargin0 = childShape0.m_childMargin; + + cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape1.m_transform; + cinput.m_shapeType1 = childShape1.m_childShapeType; + cinput.m_collisionMargin1 = childShape1.m_childMargin; + /* Recursively call handleCollisionPair () with new collision pair input */ + + handleCollisionPair(cinput, lsMem, spuContacts, + (ppu_address_t)childShape0.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], + (ppu_address_t)childShape1.m_childShape, lsMem.compoundShapeData[1].gSubshapeShape[j], false); + } + } + } + else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) ) + { + //snPause(); + + dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0); + dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1); + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); + + // object 0 compound, object 1 non-compound + btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape0Loc; + dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + int childShapeCount = spuCompoundShape->getNumChildShapes(); + btAssert(childShapeCount< MAX_SPU_COMPOUND_SUBSHAPES); + + for (int i = 0; i < childShapeCount; ++i) + { + btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i]; + btAssert(!btBroadphaseProxy::isCompound(childShape.m_childShapeType)); + // Dma the child shape + dmaCollisionShape (&lsMem.compoundShapeData[0].gSubshapeShape[i], (ppu_address_t)childShape.m_childShape, 1, childShape.m_childShapeType); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + SpuCollisionPairInput cinput (collisionPairInput); + cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape.m_transform; + cinput.m_shapeType0 = childShape.m_childShapeType; + cinput.m_collisionMargin0 = childShape.m_childMargin; + + handleCollisionPair(cinput, lsMem, spuContacts, + (ppu_address_t)childShape.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], + collisionShape1Ptr, collisionShape1Loc, false); + } + } + else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1) ) + { + //snPause(); + + dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0); + dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1); + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); + // object 0 non-compound, object 1 compound + btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape1Loc; + dmaCompoundShapeInfo (&lsMem.compoundShapeData[0], spuCompoundShape, 1); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + int childShapeCount = spuCompoundShape->getNumChildShapes(); + btAssert(childShapeCount< MAX_SPU_COMPOUND_SUBSHAPES); + + + for (int i = 0; i < childShapeCount; ++i) + { + btCompoundShapeChild& childShape = lsMem.compoundShapeData[0].gSubshapes[i]; + btAssert(!btBroadphaseProxy::isCompound(childShape.m_childShapeType)); + // Dma the child shape + dmaCollisionShape (&lsMem.compoundShapeData[0].gSubshapeShape[i], (ppu_address_t)childShape.m_childShape, 1, childShape.m_childShapeType); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + SpuCollisionPairInput cinput (collisionPairInput); + cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape.m_transform; + cinput.m_shapeType1 = childShape.m_childShapeType; + cinput.m_collisionMargin1 = childShape.m_childMargin; + handleCollisionPair(cinput, lsMem, spuContacts, + collisionShape0Ptr, collisionShape0Loc, + (ppu_address_t)childShape.m_childShape, lsMem.compoundShapeData[0].gSubshapeShape[i], false); + } + + } + else + { + //a non-convex shape is involved + bool handleConvexConcave = false; + + //snPause(); + + if (btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType0) && + btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1)) + { + // Swap stuff + DoSwap(collisionShape0Ptr, collisionShape1Ptr); + DoSwap(collisionShape0Loc, collisionShape1Loc); + DoSwap(collisionPairInput.m_shapeType0, collisionPairInput.m_shapeType1); + DoSwap(collisionPairInput.m_worldTransform0, collisionPairInput.m_worldTransform1); + DoSwap(collisionPairInput.m_collisionMargin0, collisionPairInput.m_collisionMargin1); + + collisionPairInput.m_isSwapped = true; + } + + if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)&& + btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType1)) + { + handleConvexConcave = true; + } + if (handleConvexConcave) + { + if (dmaShapes) + { + dmaCollisionShape (collisionShape0Loc, collisionShape0Ptr, 1, collisionPairInput.m_shapeType0); + dmaCollisionShape (collisionShape1Loc, collisionShape1Ptr, 2, collisionPairInput.m_shapeType1); + cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2)); + } + + if (collisionPairInput.m_shapeType1 == STATIC_PLANE_PROXYTYPE) + { + btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc; + btStaticPlaneShape* planeShape= (btStaticPlaneShape*)collisionShape1Loc; + + btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions(); + collisionPairInput.m_primitiveDimensions0 = dim0; + collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr; + collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr; + collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0; + collisionPairInput.m_spuCollisionShapes[1] = planeShape; + + ProcessConvexPlaneSpuCollision(&collisionPairInput,&lsMem,spuContacts); + } else + { + btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc; + btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)collisionShape1Loc; + + btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions(); + collisionPairInput.m_primitiveDimensions0 = dim0; + collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr; + collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr; + collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0; + collisionPairInput.m_spuCollisionShapes[1] = trimeshShape; + + ProcessConvexConcaveSpuCollision(&collisionPairInput,&lsMem,spuContacts); + } + } + + } + + spuContacts.flush(); + +} + + +void processCollisionTask(void* userPtr, void* lsMemPtr) +{ + + SpuGatherAndProcessPairsTaskDesc* taskDescPtr = (SpuGatherAndProcessPairsTaskDesc*)userPtr; + SpuGatherAndProcessPairsTaskDesc& taskDesc = *taskDescPtr; + CollisionTask_LocalStoreMemory* colMemPtr = (CollisionTask_LocalStoreMemory*)lsMemPtr; + CollisionTask_LocalStoreMemory& lsMem = *(colMemPtr); + + gUseEpa = taskDesc.m_useEpa; + + // spu_printf("taskDescPtr=%llx\n",taskDescPtr); + + SpuContactResult spuContacts; + + //////////////////// + + ppu_address_t dmaInPtr = taskDesc.m_inPairPtr; + unsigned int numPages = taskDesc.numPages; + unsigned int numOnLastPage = taskDesc.numOnLastPage; + + // prefetch first set of inputs and wait + lsMem.g_workUnitTaskBuffers.init(); + + unsigned int nextNumOnPage = (numPages > 1)? MIDPHASE_NUM_WORKUNITS_PER_PAGE : numOnLastPage; + lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3)); + dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE; + + + register unsigned char *inputPtr; + register unsigned int numOnPage; + register unsigned int j; + SpuGatherAndProcessWorkUnitInput* wuInputs; + register int dmaSize; + register ppu_address_t dmaPpuAddress; + register ppu_address_t dmaPpuAddress2; + + int numPairs; + register int p; + SpuCollisionPairInput collisionPairInput; + + for (unsigned int i = 0; btLikely(i < numPages); i++) + { + + // wait for back buffer dma and swap buffers + inputPtr = lsMem.g_workUnitTaskBuffers.swapBuffers(); + + // number on current page is number prefetched last iteration + numOnPage = nextNumOnPage; + + + // prefetch next set of inputs +#if MIDPHASE_NUM_WORKUNIT_PAGES > 2 + if ( btLikely( i < numPages-1 ) ) +#else + if ( btUnlikely( i < numPages-1 ) ) +#endif + { + nextNumOnPage = (i == numPages-2)? numOnLastPage : MIDPHASE_NUM_WORKUNITS_PER_PAGE; + lsMem.g_workUnitTaskBuffers.backBufferDmaGet(dmaInPtr, nextNumOnPage*sizeof(SpuGatherAndProcessWorkUnitInput), DMA_TAG(3)); + dmaInPtr += MIDPHASE_WORKUNIT_PAGE_SIZE; + } + + wuInputs = reinterpret_cast(inputPtr); + + + for (j = 0; btLikely( j < numOnPage ); j++) + { +#ifdef DEBUG_SPU_COLLISION_DETECTION + // printMidphaseInput(&wuInputs[j]); +#endif //DEBUG_SPU_COLLISION_DETECTION + + + numPairs = wuInputs[j].m_endIndex - wuInputs[j].m_startIndex; + + if ( btLikely( numPairs ) ) + { + dmaSize = numPairs*sizeof(btBroadphasePair); + dmaPpuAddress = wuInputs[j].m_pairArrayPtr+wuInputs[j].m_startIndex * sizeof(btBroadphasePair); + lsMem.m_pairsPointer = (btBroadphasePair*)cellDmaGetReadOnly(&lsMem.gBroadphasePairsBuffer, dmaPpuAddress , dmaSize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + + for (p=0;pm_userInfo = %d\n",pair.m_userInfo); + spu_printf("pair->m_algorithm = %d\n",pair.m_algorithm); + spu_printf("pair->m_pProxy0 = %d\n",pair.m_pProxy0); + spu_printf("pair->m_pProxy1 = %d\n",pair.m_pProxy1); +#endif //DEBUG_SPU_COLLISION_DETECTION + + if (pair.m_internalTmpValue == 2 && pair.m_algorithm && pair.m_pProxy0 && pair.m_pProxy1) + { + dmaSize = sizeof(SpuContactManifoldCollisionAlgorithm); + dmaPpuAddress2 = (ppu_address_t)pair.m_algorithm; + lsMem.m_lsCollisionAlgorithmPtr = (SpuContactManifoldCollisionAlgorithm*)cellDmaGetReadOnly(&lsMem.gSpuContactManifoldAlgoBuffer, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + lsMem.needsDmaPutContactManifoldAlgo = false; + + collisionPairInput.m_persistentManifoldPtr = (ppu_address_t) lsMem.getlocalCollisionAlgorithm()->getContactManifoldPtr(); + collisionPairInput.m_isSwapped = false; + + if (1) + { + + ///can wait on the combined DMA_MASK, or dma on the same tag + + +#ifdef DEBUG_SPU_COLLISION_DETECTION + // spu_printf("SPU collisionPairInput->m_shapeType0 = %d\n",collisionPairInput->m_shapeType0); + // spu_printf("SPU collisionPairInput->m_shapeType1 = %d\n",collisionPairInput->m_shapeType1); +#endif //DEBUG_SPU_COLLISION_DETECTION + + + dmaSize = sizeof(btPersistentManifold); + + dmaPpuAddress2 = collisionPairInput.m_persistentManifoldPtr; + lsMem.m_lsManifoldPtr = (btPersistentManifold*)cellDmaGetReadOnly(&lsMem.gPersistentManifoldBuffer, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + + collisionPairInput.m_shapeType0 = lsMem.getlocalCollisionAlgorithm()->getShapeType0(); + collisionPairInput.m_shapeType1 = lsMem.getlocalCollisionAlgorithm()->getShapeType1(); + collisionPairInput.m_collisionMargin0 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin0(); + collisionPairInput.m_collisionMargin1 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin1(); + + + + //??cellDmaWaitTagStatusAll(DMA_MASK(1)); + + + if (1) + { + //snPause(); + + // Get the collision objects + dmaAndSetupCollisionObjects(collisionPairInput, lsMem); + + if (lsMem.getColObj0()->isActive() || lsMem.getColObj1()->isActive()) + { + + lsMem.needsDmaPutContactManifoldAlgo = true; +#ifdef USE_SEPDISTANCE_UTIL + lsMem.getlocalCollisionAlgorithm()->m_sepDistance.updateSeparatingDistance(collisionPairInput.m_worldTransform0,collisionPairInput.m_worldTransform1); +#endif //USE_SEPDISTANCE_UTIL + +#define USE_DEDICATED_BOX_BOX 1 +#ifdef USE_DEDICATED_BOX_BOX + bool boxbox = ((lsMem.getlocalCollisionAlgorithm()->getShapeType0()==BOX_SHAPE_PROXYTYPE)&& + (lsMem.getlocalCollisionAlgorithm()->getShapeType1()==BOX_SHAPE_PROXYTYPE)); + if (boxbox) + { + //spu_printf("boxbox dist = %f\n",distance); + btPersistentManifold* spuManifold=lsMem.getContactManifoldPtr(); + btPersistentManifold* manifold = (btPersistentManifold*)collisionPairInput.m_persistentManifoldPtr; + ppu_address_t manifoldAddress = (ppu_address_t)manifold; + + spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMem.getColObj0()->getWorldTransform(), + lsMem.getColObj1()->getWorldTransform(), + lsMem.getColObj0()->getRestitution(),lsMem.getColObj1()->getRestitution(), + lsMem.getColObj0()->getFriction(),lsMem.getColObj1()->getFriction(), + collisionPairInput.m_isSwapped); + + + //float distance=0.f; + btVector3 normalInB; + + + if (//!gUseEpa && +#ifdef USE_SEPDISTANCE_UTIL + lsMem.getlocalCollisionAlgorithm()->m_sepDistance.getConservativeSeparatingDistance()<=0.f +#else + 1 +#endif + ) + { +//#define USE_PE_BOX_BOX 1 +#ifdef USE_PE_BOX_BOX + { + + //getCollisionMargin0 + btScalar margin0 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin0(); + btScalar margin1 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin1(); + btVector3 shapeDim0 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions0()+btVector3(margin0,margin0,margin0); + btVector3 shapeDim1 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions1()+btVector3(margin1,margin1,margin1); +/* + //Box boxA(shapeDim0.getX(),shapeDim0.getY(),shapeDim0.getZ()); + vmVector3 vmPos0 = getVmVector3(collisionPairInput.m_worldTransform0.getOrigin()); + vmVector3 vmPos1 = getVmVector3(collisionPairInput.m_worldTransform1.getOrigin()); + vmMatrix3 vmMatrix0 = getVmMatrix3(collisionPairInput.m_worldTransform0.getBasis()); + vmMatrix3 vmMatrix1 = getVmMatrix3(collisionPairInput.m_worldTransform1.getBasis()); + + vmTransform3 transformA(vmMatrix0,vmPos0); + Box boxB(shapeDim1.getX(),shapeDim1.getY(),shapeDim1.getZ()); + vmTransform3 transformB(vmMatrix1,vmPos1); + BoxPoint resultClosestBoxPointA; + BoxPoint resultClosestBoxPointB; + vmVector3 resultNormal; + */ + +#ifdef USE_SEPDISTANCE_UTIL + float distanceThreshold = FLT_MAX +#else + //float distanceThreshold = 0.f; +#endif + + + vmVector3 n; + Box boxA; + vmVector3 hA(shapeDim0.getX(),shapeDim0.getY(),shapeDim0.getZ()); + vmVector3 hB(shapeDim1.getX(),shapeDim1.getY(),shapeDim1.getZ()); + boxA.mHalf= hA; + vmTransform3 trA; + trA.setTranslation(getVmVector3(collisionPairInput.m_worldTransform0.getOrigin())); + trA.setUpper3x3(getVmMatrix3(collisionPairInput.m_worldTransform0.getBasis())); + Box boxB; + boxB.mHalf = hB; + vmTransform3 trB; + trB.setTranslation(getVmVector3(collisionPairInput.m_worldTransform1.getOrigin())); + trB.setUpper3x3(getVmMatrix3(collisionPairInput.m_worldTransform1.getBasis())); + + float distanceThreshold = spuManifold->getContactBreakingThreshold();//0.001f; + + + BoxPoint ptA,ptB; + float dist = boxBoxDistance(n, ptA, ptB, + boxA, trA, boxB, trB, + distanceThreshold ); + + +// float distance = boxBoxDistance(resultNormal,resultClosestBoxPointA,resultClosestBoxPointB, boxA, transformA, boxB,transformB,distanceThreshold); + + normalInB = -getBtVector3(n);//resultNormal); + + //if(dist < distanceThreshold)//spuManifold->getContactBreakingThreshold()) + if(dist < spuManifold->getContactBreakingThreshold()) + { + btVector3 pointOnB = collisionPairInput.m_worldTransform1(getBtVector3(ptB.localPoint)); + + spuContacts.addContactPoint( + normalInB, + pointOnB, + dist); + } + } +#else + { + + btScalar margin0 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin0(); + btScalar margin1 = lsMem.getlocalCollisionAlgorithm()->getCollisionMargin1(); + btVector3 shapeDim0 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions0()+btVector3(margin0,margin0,margin0); + btVector3 shapeDim1 = lsMem.getlocalCollisionAlgorithm()->getShapeDimensions1()+btVector3(margin1,margin1,margin1); + + + btBoxShape box0(shapeDim0); + btBoxShape box1(shapeDim1); + + struct SpuBridgeContactCollector : public btDiscreteCollisionDetectorInterface::Result + { + SpuContactResult& m_spuContacts; + + virtual void setShapeIdentifiersA(int partId0,int index0) + { + m_spuContacts.setShapeIdentifiersA(partId0,index0); + } + virtual void setShapeIdentifiersB(int partId1,int index1) + { + m_spuContacts.setShapeIdentifiersB(partId1,index1); + } + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + m_spuContacts.addContactPoint(normalOnBInWorld,pointInWorld,depth); + } + + SpuBridgeContactCollector(SpuContactResult& spuContacts) + :m_spuContacts(spuContacts) + { + + } + }; + + SpuBridgeContactCollector bridgeOutput(spuContacts); + + btDiscreteCollisionDetectorInterface::ClosestPointInput input; + input.m_maximumDistanceSquared = BT_LARGE_FLOAT; + input.m_transformA = collisionPairInput.m_worldTransform0; + input.m_transformB = collisionPairInput.m_worldTransform1; + + btBoxBoxDetector detector(&box0,&box1); + + detector.getClosestPoints(input,bridgeOutput,0); + + } +#endif //USE_PE_BOX_BOX + + lsMem.needsDmaPutContactManifoldAlgo = true; +#ifdef USE_SEPDISTANCE_UTIL + btScalar sepDist2 = distance+spuManifold->getContactBreakingThreshold(); + lsMem.getlocalCollisionAlgorithm()->m_sepDistance.initSeparatingDistance(normalInB,sepDist2,collisionPairInput.m_worldTransform0,collisionPairInput.m_worldTransform1); +#endif //USE_SEPDISTANCE_UTIL + gProcessedCol++; + } else + { + gSkippedCol++; + } + + spuContacts.flush(); + + + } else +#endif //USE_DEDICATED_BOX_BOX + { + if ( +#ifdef USE_SEPDISTANCE_UTIL + lsMem.getlocalCollisionAlgorithm()->m_sepDistance.getConservativeSeparatingDistance()<=0.f +#else + 1 +#endif //USE_SEPDISTANCE_UTIL + ) + { + handleCollisionPair(collisionPairInput, lsMem, spuContacts, + (ppu_address_t)lsMem.getColObj0()->getCollisionShape(), &lsMem.gCollisionShapes[0].collisionShape, + (ppu_address_t)lsMem.getColObj1()->getCollisionShape(), &lsMem.gCollisionShapes[1].collisionShape); + } else + { + //spu_printf("boxbox dist = %f\n",distance); + btPersistentManifold* spuManifold=lsMem.getContactManifoldPtr(); + btPersistentManifold* manifold = (btPersistentManifold*)collisionPairInput.m_persistentManifoldPtr; + ppu_address_t manifoldAddress = (ppu_address_t)manifold; + + spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMem.getColObj0()->getWorldTransform(), + lsMem.getColObj1()->getWorldTransform(), + lsMem.getColObj0()->getRestitution(),lsMem.getColObj1()->getRestitution(), + lsMem.getColObj0()->getFriction(),lsMem.getColObj1()->getFriction(), + collisionPairInput.m_isSwapped); + + spuContacts.flush(); + } + } + + } + + } + } + +#ifdef USE_SEPDISTANCE_UTIL +#if defined (__SPU__) || defined (USE_LIBSPE2) + if (lsMem.needsDmaPutContactManifoldAlgo) + { + dmaSize = sizeof(SpuContactManifoldCollisionAlgorithm); + dmaPpuAddress2 = (ppu_address_t)pair.m_algorithm; + cellDmaLargePut(&lsMem.gSpuContactManifoldAlgoBuffer, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + } +#endif +#endif //#ifdef USE_SEPDISTANCE_UTIL + + } + } + } + } //end for (j = 0; j < numOnPage; j++) + + }// for + + + + return; +} + + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h new file mode 100644 index 0000000..64af964 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h @@ -0,0 +1,140 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SPU_GATHERING_COLLISION_TASK_H +#define SPU_GATHERING_COLLISION_TASK_H + +#include "../PlatformDefinitions.h" +//#define DEBUG_SPU_COLLISION_DETECTION 1 + + +///Task Description for SPU collision detection +struct SpuGatherAndProcessPairsTaskDesc +{ + ppu_address_t m_inPairPtr;//m_pairArrayPtr; + //mutex variable + uint32_t m_someMutexVariableInMainMemory; + + ppu_address_t m_dispatcher; + + uint32_t numOnLastPage; + + uint16_t numPages; + uint16_t taskId; + bool m_useEpa; + + struct CollisionTask_LocalStoreMemory* m_lsMemory; +} + +#if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2) +__attribute__ ((aligned (128))) +#endif +; + + +void processCollisionTask(void* userPtr, void* lsMemory); + +void* createCollisionLocalStoreMemory(); +void deleteCollisionLocalStoreMemory(); + +#if defined(USE_LIBSPE2) && defined(__SPU__) +#include "../SpuLibspe2Support.h" +#include +#include +#include + +//#define DEBUG_LIBSPE2_SPU_TASK + + + +int main(unsigned long long speid, addr64 argp, addr64 envp) +{ + printf("SPU: hello \n"); + + ATTRIBUTE_ALIGNED128(btSpuStatus status); + ATTRIBUTE_ALIGNED16( SpuGatherAndProcessPairsTaskDesc taskDesc ) ; + unsigned int received_message = Spu_Mailbox_Event_Nothing; + bool shutdown = false; + + cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + status.m_status = Spu_Status_Free; + status.m_lsMemory.p = createCollisionLocalStoreMemory(); + + cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + + while ( btLikely( !shutdown ) ) + { + + received_message = spu_read_in_mbox(); + + if( btLikely( received_message == Spu_Mailbox_Event_Task )) + { +#ifdef DEBUG_LIBSPE2_SPU_TASK + printf("SPU: received Spu_Mailbox_Event_Task\n"); +#endif //DEBUG_LIBSPE2_SPU_TASK + + // refresh the status + cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + btAssert(status.m_status==Spu_Status_Occupied); + + cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuGatherAndProcessPairsTaskDesc), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); +#ifdef DEBUG_LIBSPE2_SPU_TASK + printf("SPU:processCollisionTask\n"); +#endif //DEBUG_LIBSPE2_SPU_TASK + processCollisionTask((void*)&taskDesc, taskDesc.m_lsMemory); + +#ifdef DEBUG_LIBSPE2_SPU_TASK + printf("SPU:finished processCollisionTask\n"); +#endif //DEBUG_LIBSPE2_SPU_TASK + } + else + { +#ifdef DEBUG_LIBSPE2_SPU_TASK + printf("SPU: received ShutDown\n"); +#endif //DEBUG_LIBSPE2_SPU_TASK + if( btLikely( received_message == Spu_Mailbox_Event_Shutdown ) ) + { + shutdown = true; + } + else + { + //printf("SPU - Sth. recieved\n"); + } + } + + // set to status free and wait for next task + status.m_status = Spu_Status_Free; + cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + + } + + printf("SPU: shutdown\n"); + return 0; +} +#endif // USE_LIBSPE2 + + +#endif //SPU_GATHERING_COLLISION_TASK_H + + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h new file mode 100644 index 0000000..8b89de0 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h @@ -0,0 +1,19 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + + + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp new file mode 100644 index 0000000..9f7e64d --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp @@ -0,0 +1,348 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SpuMinkowskiPenetrationDepthSolver.h" +#include "SpuContactResult.h" +#include "SpuPreferredPenetrationDirections.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "SpuCollisionShapes.h" + +#define NUM_UNITSPHERE_POINTS 42 +static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = +{ +btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), +btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), +btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), +btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), +btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), +btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), +btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), +btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), +btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), +btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), +btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), +btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), +btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), +btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), +btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), +btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), +btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), +btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), +btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), +btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), +btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), +btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), +btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), +btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), +btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), +btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), +btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), +btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), +btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), +btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), +btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), +btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), +btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), +btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), +btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), +btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), +btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), +btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), +btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), +btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), +btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), +btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) +}; + + +bool SpuMinkowskiPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver, + const btConvexShape* convexA,const btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc) +{ +#if 0 + (void)stackAlloc; + (void)v; + + + struct btIntermediateResult : public SpuContactResult + { + + btIntermediateResult():m_hasResult(false) + { + } + + btVector3 m_normalOnBInWorld; + btVector3 m_pointInWorld; + btScalar m_depth; + bool m_hasResult; + + virtual void setShapeIdentifiersA(int partId0,int index0) + { + (void)partId0; + (void)index0; + } + + virtual void setShapeIdentifiersB(int partId1,int index1) + { + (void)partId1; + (void)index1; + } + void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + m_normalOnBInWorld = normalOnBInWorld; + m_pointInWorld = pointInWorld; + m_depth = depth; + m_hasResult = true; + } + }; + + //just take fixed number of orientation, and sample the penetration depth in that direction + btScalar minProj = btScalar(BT_LARGE_FLOAT); + btVector3 minNorm(0.f,0.f,0.f); + btVector3 minVertex; + btVector3 minA,minB; + btVector3 seperatingAxisInA,seperatingAxisInB; + btVector3 pInA,qInB,pWorld,qWorld,w; + +//#define USE_BATCHED_SUPPORT 1 +#ifdef USE_BATCHED_SUPPORT + + btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 supportVerticesBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 seperatingAxisInABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + int i; + + int numSampleDirections = NUM_UNITSPHERE_POINTS; + + for (i=0;igetNumPreferredPenetrationDirections(); + if (numPDA) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transA.getBasis() * norm; + sPenetrationDirections[numSampleDirections] = norm; + seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); + seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); + numSampleDirections++; + } + } + } + + { + int numPDB = convexB->getNumPreferredPenetrationDirections(); + if (numPDB) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transB.getBasis() * norm; + sPenetrationDirections[numSampleDirections] = norm; + seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); + seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); + numSampleDirections++; + } + } + } + + + + convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections); + convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections); + + for (i=0;ilocalGetSupportVertexWithoutMarginNonVirtual( seperatingAxisInA);//, NULL); + qInB = convexB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);//, NULL); + + // pInA = convexA->localGetSupportingVertexWithoutMargin(seperatingAxisInA); + // qInB = convexB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); + + pWorld = transA(pInA); + qWorld = transB(qInB); + w = qWorld - pWorld; + btScalar delta = norm.dot(w); + //find smallest delta + if (delta < minProj) + { + minProj = delta; + minNorm = norm; + minA = pWorld; + minB = qWorld; + } + } +#endif //USE_BATCHED_SUPPORT + + //add the margins + + minA += minNorm*marginA; + minB -= minNorm*marginB; + //no penetration + if (minProj < btScalar(0.)) + return false; + + minProj += (marginA + marginB) + btScalar(1.00); + + + + + +//#define DEBUG_DRAW 1 +#ifdef DEBUG_DRAW + if (debugDraw) + { + btVector3 color(0,1,0); + debugDraw->drawLine(minA,minB,color); + color = btVector3 (1,1,1); + btVector3 vec = minB-minA; + btScalar prj2 = minNorm.dot(vec); + debugDraw->drawLine(minA,minA+(minNorm*minProj),color); + + } +#endif //DEBUG_DRAW + + + btGjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0); + + btScalar offsetDist = minProj; + btVector3 offset = minNorm * offsetDist; + + + SpuClosestPointInput input; + input.m_convexVertexData[0] = convexVertexDataA; + input.m_convexVertexData[1] = convexVertexDataB; + btVector3 newOrg = transA.getOrigin() + offset; + + btTransform displacedTrans = transA; + displacedTrans.setOrigin(newOrg); + + input.m_transformA = displacedTrans; + input.m_transformB = transB; + input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);//minProj; + + btIntermediateResult res; + gjkdet.getClosestPoints(input,res,0); + + btScalar correctedMinNorm = minProj - res.m_depth; + + + //the penetration depth is over-estimated, relax it + btScalar penetration_relaxation= btScalar(1.); + minNorm*=penetration_relaxation; + + if (res.m_hasResult) + { + + pa = res.m_pointInWorld - minNorm * correctedMinNorm; + pb = res.m_pointInWorld; + +#ifdef DEBUG_DRAW + if (debugDraw) + { + btVector3 color(1,0,0); + debugDraw->drawLine(pa,pb,color); + } +#endif//DEBUG_DRAW + + + } else { + // could not seperate shapes + //btAssert (false); + } + return res.m_hasResult; +#endif + return false; +} + + + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h new file mode 100644 index 0000000..18ad223 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h @@ -0,0 +1,48 @@ + +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef MINKOWSKI_PENETRATION_DEPTH_SOLVER_H +#define MINKOWSKI_PENETRATION_DEPTH_SOLVER_H + + +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" + +class btStackAlloc; +class btIDebugDraw; +class btVoronoiSimplexSolver; +class btConvexShape; + +///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation. +///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points. +class SpuMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver +{ +public: + SpuMinkowskiPenetrationDepthSolver() {} + virtual ~SpuMinkowskiPenetrationDepthSolver() {}; + + virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, + const btConvexShape* convexA,const btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc + ); + + +}; + + +#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H + diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h new file mode 100644 index 0000000..774a0cb --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h @@ -0,0 +1,70 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SPU_PREFERRED_PENETRATION_DIRECTIONS_H +#define _SPU_PREFERRED_PENETRATION_DIRECTIONS_H + + +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" + +int spuGetNumPreferredPenetrationDirections(int shapeType, void* shape) +{ + switch (shapeType) + { + case TRIANGLE_SHAPE_PROXYTYPE: + { + return 2; + //spu_printf("2\n"); + break; + } + default: + { +#if __ASSERT + spu_printf("spuGetNumPreferredPenetrationDirections() - Unsupported bound type: %d.\n", shapeType); +#endif // __ASSERT + } + } + + return 0; +} + +void spuGetPreferredPenetrationDirection(int shapeType, void* shape, int index, btVector3& penetrationVector) +{ + + + switch (shapeType) + { + case TRIANGLE_SHAPE_PROXYTYPE: + { + btVector3* vertices = (btVector3*)shape; + ///calcNormal + penetrationVector = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]); + penetrationVector.normalize(); + if (index) + penetrationVector *= btScalar(-1.); + break; + } + default: + { + +#if __ASSERT + spu_printf("spuGetNumPreferredPenetrationDirections() - Unsupported bound type: %d.\n", shapeType); +#endif // __ASSERT + } + } + +} + +#endif //_SPU_PREFERRED_PENETRATION_DIRECTIONS_H diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp new file mode 100644 index 0000000..5e1202c --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp @@ -0,0 +1,1160 @@ +/* + Copyright (C) 2006, 2008 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + + +//#include "PfxContactBoxBox.h" + +#include +#include "../PlatformDefinitions.h" +#include "boxBoxDistance.h" + +static inline float sqr( float a ) +{ + return (a * a); +} + +enum BoxSepAxisType +{ + A_AXIS, B_AXIS, CROSS_AXIS +}; + +//------------------------------------------------------------------------------------------------- +// voronoiTol: bevels Voronoi planes slightly which helps when features are parallel. +//------------------------------------------------------------------------------------------------- + +static const float voronoiTol = -1.0e-5f; + +//------------------------------------------------------------------------------------------------- +// separating axis tests: gaps along each axis are computed, and the axis with the maximum +// gap is stored. cross product axes are normalized. +//------------------------------------------------------------------------------------------------- + +#define AaxisTest( dim, letter, first ) \ +{ \ + if ( first ) \ + { \ + maxGap = gap = gapsA.get##letter(); \ + if ( gap > distanceThreshold ) return gap; \ + axisType = A_AXIS; \ + faceDimA = dim; \ + axisA = identity.getCol##dim(); \ + } \ + else \ + { \ + gap = gapsA.get##letter(); \ + if ( gap > distanceThreshold ) return gap; \ + else if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = A_AXIS; \ + faceDimA = dim; \ + axisA = identity.getCol##dim(); \ + } \ + } \ +} + + +#define BaxisTest( dim, letter ) \ +{ \ + gap = gapsB.get##letter(); \ + if ( gap > distanceThreshold ) return gap; \ + else if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = B_AXIS; \ + faceDimB = dim; \ + axisB = identity.getCol##dim(); \ + } \ +} + +#define CrossAxisTest( dima, dimb, letterb ) \ +{ \ + const float lsqr_tolerance = 1.0e-30f; \ + float lsqr; \ + \ + lsqr = lsqrs.getCol##dima().get##letterb(); \ + \ + if ( lsqr > lsqr_tolerance ) \ + { \ + float l_recip = 1.0f / sqrtf( lsqr ); \ + gap = float(gapsAxB.getCol##dima().get##letterb()) * l_recip; \ + \ + if ( gap > distanceThreshold ) \ + { \ + return gap; \ + } \ + \ + if ( gap > maxGap ) \ + { \ + maxGap = gap; \ + axisType = CROSS_AXIS; \ + edgeDimA = dima; \ + edgeDimB = dimb; \ + axisA = cross(identity.getCol##dima(),matrixAB.getCol##dimb()) * l_recip; \ + } \ + } \ +} + +//------------------------------------------------------------------------------------------------- +// tests whether a vertex of box B and a face of box A are the closest features +//------------------------------------------------------------------------------------------------- + +inline +float +VertexBFaceATest( + bool & inVoronoi, + float & t0, + float & t1, + const vmVector3 & hA, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsB, + PE_REF(vmVector3) scalesB ) +{ + // compute a corner of box B in A's coordinate system + + vmVector3 corner = + vmVector3( faceOffsetAB + matrixAB.getCol0() * scalesB.getX() + matrixAB.getCol1() * scalesB.getY() ); + + // compute the parameters of the point on A, closest to this corner + + t0 = corner[0]; + t1 = corner[1]; + + if ( t0 > hA[0] ) + t0 = hA[0]; + else if ( t0 < -hA[0] ) + t0 = -hA[0]; + if ( t1 > hA[1] ) + t1 = hA[1]; + else if ( t1 < -hA[1] ) + t1 = -hA[1]; + + // do the Voronoi test: already know the point on B is in the Voronoi region of the + // point on A, check the reverse. + + vmVector3 facePointB = + vmVector3( mulPerElem( faceOffsetBA + matrixBA.getCol0() * t0 + matrixBA.getCol1() * t1 - scalesB, signsB ) ); + + inVoronoi = ( ( facePointB[0] >= voronoiTol * facePointB[2] ) && + ( facePointB[1] >= voronoiTol * facePointB[0] ) && + ( facePointB[2] >= voronoiTol * facePointB[1] ) ); + + return (sqr( corner[0] - t0 ) + sqr( corner[1] - t1 ) + sqr( corner[2] )); +} + +#define VertexBFaceA_SetNewMin() \ +{ \ + minDistSqr = distSqr; \ + localPointA.setX(t0); \ + localPointA.setY(t1); \ + localPointB.setX( scalesB.getX() ); \ + localPointB.setY( scalesB.getY() ); \ + featureA = F; \ + featureB = V; \ +} + +void +VertexBFaceATests( + bool & done, + float & minDistSqr, + vmPoint3 & localPointA, + vmPoint3 & localPointB, + FeatureType & featureA, + FeatureType & featureB, + const vmVector3 & hA, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsB, + PE_REF(vmVector3) scalesB, + bool first ) +{ + + float t0, t1; + float distSqr; + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( first ) { + VertexBFaceA_SetNewMin(); + } else { + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } + + if ( done ) + return; + + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = VertexBFaceATest( done, t0, t1, hA, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsB, scalesB ); + + if ( distSqr < minDistSqr ) { + VertexBFaceA_SetNewMin(); + } +} + +//------------------------------------------------------------------------------------------------- +// VertexAFaceBTest: tests whether a vertex of box A and a face of box B are the closest features +//------------------------------------------------------------------------------------------------- + +inline +float +VertexAFaceBTest( + bool & inVoronoi, + float & t0, + float & t1, + const vmVector3 & hB, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsA, + PE_REF(vmVector3) scalesA ) +{ + vmVector3 corner = + vmVector3( faceOffsetBA + matrixBA.getCol0() * scalesA.getX() + matrixBA.getCol1() * scalesA.getY() ); + + t0 = corner[0]; + t1 = corner[1]; + + if ( t0 > hB[0] ) + t0 = hB[0]; + else if ( t0 < -hB[0] ) + t0 = -hB[0]; + if ( t1 > hB[1] ) + t1 = hB[1]; + else if ( t1 < -hB[1] ) + t1 = -hB[1]; + + vmVector3 facePointA = + vmVector3( mulPerElem( faceOffsetAB + matrixAB.getCol0() * t0 + matrixAB.getCol1() * t1 - scalesA, signsA ) ); + + inVoronoi = ( ( facePointA[0] >= voronoiTol * facePointA[2] ) && + ( facePointA[1] >= voronoiTol * facePointA[0] ) && + ( facePointA[2] >= voronoiTol * facePointA[1] ) ); + + return (sqr( corner[0] - t0 ) + sqr( corner[1] - t1 ) + sqr( corner[2] )); +} + +#define VertexAFaceB_SetNewMin() \ +{ \ + minDistSqr = distSqr; \ + localPointB.setX(t0); \ + localPointB.setY(t1); \ + localPointA.setX( scalesA.getX() ); \ + localPointA.setY( scalesA.getY() ); \ + featureA = V; \ + featureB = F; \ +} + +void +VertexAFaceBTests( + bool & done, + float & minDistSqr, + vmPoint3 & localPointA, + vmPoint3 & localPointB, + FeatureType & featureA, + FeatureType & featureB, + const vmVector3 & hB, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsA, + PE_REF(vmVector3) scalesA, + bool first ) +{ + float t0, t1; + float distSqr; + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( first ) { + VertexAFaceB_SetNewMin(); + } else { + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = VertexAFaceBTest( done, t0, t1, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, scalesA ); + + if ( distSqr < minDistSqr ) { + VertexAFaceB_SetNewMin(); + } +} + +//------------------------------------------------------------------------------------------------- +// CustomEdgeEdgeTest: +// +// tests whether a pair of edges are the closest features +// +// note on the shorthand: +// 'a' & 'b' refer to the edges. +// 'c' is the dimension of the axis that points from the face center to the edge Center +// 'd' is the dimension of the edge Direction +// the dimension of the face normal is 2 +//------------------------------------------------------------------------------------------------- + +#define CustomEdgeEdgeTest( ac, ac_letter, ad, ad_letter, bc, bc_letter, bd, bd_letter ) \ +{ \ + vmVector3 edgeOffsetAB; \ + vmVector3 edgeOffsetBA; \ + \ + edgeOffsetAB = faceOffsetAB + matrixAB.getCol##bc() * scalesB.get##bc_letter(); \ + edgeOffsetAB.set##ac_letter( edgeOffsetAB.get##ac_letter() - scalesA.get##ac_letter() ); \ + \ + edgeOffsetBA = faceOffsetBA + matrixBA.getCol##ac() * scalesA.get##ac_letter(); \ + edgeOffsetBA.set##bc_letter( edgeOffsetBA.get##bc_letter() - scalesB.get##bc_letter() ); \ + \ + float dirDot = matrixAB.getCol##bd().get##ad_letter(); \ + float denom = 1.0f - dirDot*dirDot; \ + float edgeOffsetAB_ad = edgeOffsetAB.get##ad_letter(); \ + float edgeOffsetBA_bd = edgeOffsetBA.get##bd_letter(); \ + \ + if ( denom == 0.0f ) \ + { \ + tA = 0.0f; \ + } \ + else \ + { \ + tA = ( edgeOffsetAB_ad + edgeOffsetBA_bd * dirDot ) / denom; \ + } \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + \ + tB = tA * dirDot + edgeOffsetBA_bd; \ + \ + if ( tB < -hB[bd] ) \ + { \ + tB = -hB[bd]; \ + tA = tB * dirDot + edgeOffsetAB_ad; \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + } \ + else if ( tB > hB[bd] ) \ + { \ + tB = hB[bd]; \ + tA = tB * dirDot + edgeOffsetAB_ad; \ + \ + if ( tA < -hA[ad] ) tA = -hA[ad]; \ + else if ( tA > hA[ad] ) tA = hA[ad]; \ + } \ + \ + vmVector3 edgeOffAB = vmVector3( mulPerElem( edgeOffsetAB + matrixAB.getCol##bd() * tB, signsA ) );\ + vmVector3 edgeOffBA = vmVector3( mulPerElem( edgeOffsetBA + matrixBA.getCol##ad() * tA, signsB ) );\ + \ + inVoronoi = ( edgeOffAB[ac] >= voronoiTol * edgeOffAB[2] ) && \ + ( edgeOffAB[2] >= voronoiTol * edgeOffAB[ac] ) && \ + ( edgeOffBA[bc] >= voronoiTol * edgeOffBA[2] ) && \ + ( edgeOffBA[2] >= voronoiTol * edgeOffBA[bc] ); \ + \ + edgeOffAB[ad] -= tA; \ + edgeOffBA[bd] -= tB; \ + \ + return dot(edgeOffAB,edgeOffAB); \ +} + +float +CustomEdgeEdgeTest_0101( + bool & inVoronoi, + float & tA, + float & tB, + const vmVector3 & hA, + const vmVector3 & hB, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsA, + PE_REF(vmVector3) signsB, + PE_REF(vmVector3) scalesA, + PE_REF(vmVector3) scalesB ) +{ + CustomEdgeEdgeTest( 0, X, 1, Y, 0, X, 1, Y ); +} + +float +CustomEdgeEdgeTest_0110( + bool & inVoronoi, + float & tA, + float & tB, + const vmVector3 & hA, + const vmVector3 & hB, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsA, + PE_REF(vmVector3) signsB, + PE_REF(vmVector3) scalesA, + PE_REF(vmVector3) scalesB ) +{ + CustomEdgeEdgeTest( 0, X, 1, Y, 1, Y, 0, X ); +} + +float +CustomEdgeEdgeTest_1001( + bool & inVoronoi, + float & tA, + float & tB, + const vmVector3 & hA, + const vmVector3 & hB, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsA, + PE_REF(vmVector3) signsB, + PE_REF(vmVector3) scalesA, + PE_REF(vmVector3) scalesB ) +{ + CustomEdgeEdgeTest( 1, Y, 0, X, 0, X, 1, Y ); +} + +float +CustomEdgeEdgeTest_1010( + bool & inVoronoi, + float & tA, + float & tB, + const vmVector3 & hA, + const vmVector3 & hB, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsA, + PE_REF(vmVector3) signsB, + PE_REF(vmVector3) scalesA, + PE_REF(vmVector3) scalesB ) +{ + CustomEdgeEdgeTest( 1, Y, 0, X, 1, Y, 0, X ); +} + +#define EdgeEdge_SetNewMin( ac_letter, ad_letter, bc_letter, bd_letter ) \ +{ \ + minDistSqr = distSqr; \ + localPointA.set##ac_letter(scalesA.get##ac_letter()); \ + localPointA.set##ad_letter(tA); \ + localPointB.set##bc_letter(scalesB.get##bc_letter()); \ + localPointB.set##bd_letter(tB); \ + otherFaceDimA = testOtherFaceDimA; \ + otherFaceDimB = testOtherFaceDimB; \ + featureA = E; \ + featureB = E; \ +} + +void +EdgeEdgeTests( + bool & done, + float & minDistSqr, + vmPoint3 & localPointA, + vmPoint3 & localPointB, + int & otherFaceDimA, + int & otherFaceDimB, + FeatureType & featureA, + FeatureType & featureB, + const vmVector3 & hA, + const vmVector3 & hB, + PE_REF(vmVector3) faceOffsetAB, + PE_REF(vmVector3) faceOffsetBA, + const vmMatrix3 & matrixAB, + const vmMatrix3 & matrixBA, + PE_REF(vmVector3) signsA, + PE_REF(vmVector3) signsB, + PE_REF(vmVector3) scalesA, + PE_REF(vmVector3) scalesB, + bool first ) +{ + + float distSqr; + float tA, tB; + + int testOtherFaceDimA, testOtherFaceDimB; + + testOtherFaceDimA = 0; + testOtherFaceDimB = 0; + + distSqr = CustomEdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( first ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } else { + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = CustomEdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = CustomEdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = CustomEdgeEdgeTest_0101( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, X, Y ); + } + + if ( done ) + return; + + testOtherFaceDimA = 1; + testOtherFaceDimB = 0; + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = CustomEdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = CustomEdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = CustomEdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = CustomEdgeEdgeTest_1001( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, X, Y ); + } + + if ( done ) + return; + + testOtherFaceDimA = 0; + testOtherFaceDimB = 1; + signsB.setX( -signsB.getX() ); + scalesB.setX( -scalesB.getX() ); + + distSqr = CustomEdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = CustomEdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = CustomEdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + signsA.setX( -signsA.getX() ); + scalesA.setX( -scalesA.getX() ); + + distSqr = CustomEdgeEdgeTest_0110( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( X, Y, Y, X ); + } + + if ( done ) + return; + + testOtherFaceDimA = 1; + testOtherFaceDimB = 1; + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = CustomEdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = CustomEdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } + + if ( done ) + return; + + signsB.setY( -signsB.getY() ); + scalesB.setY( -scalesB.getY() ); + + distSqr = CustomEdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } + + if ( done ) + return; + + signsA.setY( -signsA.getY() ); + scalesA.setY( -scalesA.getY() ); + + distSqr = CustomEdgeEdgeTest_1010( done, tA, tB, hA, hB, faceOffsetAB, faceOffsetBA, + matrixAB, matrixBA, signsA, signsB, scalesA, scalesB ); + + if ( distSqr < minDistSqr ) { + EdgeEdge_SetNewMin( Y, X, Y, X ); + } +} + + +float +boxBoxDistance(vmVector3& normal, BoxPoint& boxPointA, BoxPoint& boxPointB, + PE_REF(Box) boxA, const vmTransform3 & transformA, PE_REF(Box) boxB, + const vmTransform3 & transformB, + float distanceThreshold) +{ + vmMatrix3 identity; + identity = vmMatrix3::identity(); + vmVector3 ident[3]; + ident[0] = identity.getCol0(); + ident[1] = identity.getCol1(); + ident[2] = identity.getCol2(); + + // get relative transformations + + vmTransform3 transformAB, transformBA; + vmMatrix3 matrixAB, matrixBA; + vmVector3 offsetAB, offsetBA; + + transformAB = orthoInverse(transformA) * transformB; + transformBA = orthoInverse(transformAB); + + matrixAB = transformAB.getUpper3x3(); + offsetAB = transformAB.getTranslation(); + matrixBA = transformBA.getUpper3x3(); + offsetBA = transformBA.getTranslation(); + + vmMatrix3 absMatrixAB = absPerElem(matrixAB); + vmMatrix3 absMatrixBA = absPerElem(matrixBA); + + // find separating axis with largest gap between projections + + BoxSepAxisType axisType; + vmVector3 axisA(0.0f), axisB(0.0f); + float gap, maxGap; + int faceDimA = 0, faceDimB = 0, edgeDimA = 0, edgeDimB = 0; + + // face axes + + vmVector3 gapsA = absPerElem(offsetAB) - boxA.mHalf - absMatrixAB * boxB.mHalf; + + AaxisTest(0,X,true); + AaxisTest(1,Y,false); + AaxisTest(2,Z,false); + + vmVector3 gapsB = absPerElem(offsetBA) - boxB.mHalf - absMatrixBA * boxA.mHalf; + + BaxisTest(0,X); + BaxisTest(1,Y); + BaxisTest(2,Z); + + // cross product axes + + // ŠOÏ‚ª‚O‚Ì‚Æ‚«‚̑΍ô + absMatrixAB += vmMatrix3(1.0e-5f); + absMatrixBA += vmMatrix3(1.0e-5f); + + vmMatrix3 lsqrs, projOffset, projAhalf, projBhalf; + + lsqrs.setCol0( mulPerElem( matrixBA.getCol2(), matrixBA.getCol2() ) + + mulPerElem( matrixBA.getCol1(), matrixBA.getCol1() ) ); + lsqrs.setCol1( mulPerElem( matrixBA.getCol2(), matrixBA.getCol2() ) + + mulPerElem( matrixBA.getCol0(), matrixBA.getCol0() ) ); + lsqrs.setCol2( mulPerElem( matrixBA.getCol1(), matrixBA.getCol1() ) + + mulPerElem( matrixBA.getCol0(), matrixBA.getCol0() ) ); + + projOffset.setCol0(matrixBA.getCol1() * offsetAB.getZ() - matrixBA.getCol2() * offsetAB.getY()); + projOffset.setCol1(matrixBA.getCol2() * offsetAB.getX() - matrixBA.getCol0() * offsetAB.getZ()); + projOffset.setCol2(matrixBA.getCol0() * offsetAB.getY() - matrixBA.getCol1() * offsetAB.getX()); + + projAhalf.setCol0(absMatrixBA.getCol1() * boxA.mHalf.getZ() + absMatrixBA.getCol2() * boxA.mHalf.getY()); + projAhalf.setCol1(absMatrixBA.getCol2() * boxA.mHalf.getX() + absMatrixBA.getCol0() * boxA.mHalf.getZ()); + projAhalf.setCol2(absMatrixBA.getCol0() * boxA.mHalf.getY() + absMatrixBA.getCol1() * boxA.mHalf.getX()); + + projBhalf.setCol0(absMatrixAB.getCol1() * boxB.mHalf.getZ() + absMatrixAB.getCol2() * boxB.mHalf.getY()); + projBhalf.setCol1(absMatrixAB.getCol2() * boxB.mHalf.getX() + absMatrixAB.getCol0() * boxB.mHalf.getZ()); + projBhalf.setCol2(absMatrixAB.getCol0() * boxB.mHalf.getY() + absMatrixAB.getCol1() * boxB.mHalf.getX()); + + vmMatrix3 gapsAxB = absPerElem(projOffset) - projAhalf - transpose(projBhalf); + + CrossAxisTest(0,0,X); + CrossAxisTest(0,1,Y); + CrossAxisTest(0,2,Z); + CrossAxisTest(1,0,X); + CrossAxisTest(1,1,Y); + CrossAxisTest(1,2,Z); + CrossAxisTest(2,0,X); + CrossAxisTest(2,1,Y); + CrossAxisTest(2,2,Z); + + // need to pick the face on each box whose normal best matches the separating axis. + // will transform vectors to be in the coordinate system of this face to simplify things later. + // for this, a permutation matrix can be used, which the next section computes. + + int dimA[3], dimB[3]; + + if ( axisType == A_AXIS ) { + if ( dot(axisA,offsetAB) < 0.0f ) + axisA = -axisA; + axisB = matrixBA * -axisA; + + vmVector3 absAxisB = vmVector3(absPerElem(axisB)); + + if ( ( absAxisB[0] > absAxisB[1] ) && ( absAxisB[0] > absAxisB[2] ) ) + faceDimB = 0; + else if ( absAxisB[1] > absAxisB[2] ) + faceDimB = 1; + else + faceDimB = 2; + } else if ( axisType == B_AXIS ) { + if ( dot(axisB,offsetBA) < 0.0f ) + axisB = -axisB; + axisA = matrixAB * -axisB; + + vmVector3 absAxisA = vmVector3(absPerElem(axisA)); + + if ( ( absAxisA[0] > absAxisA[1] ) && ( absAxisA[0] > absAxisA[2] ) ) + faceDimA = 0; + else if ( absAxisA[1] > absAxisA[2] ) + faceDimA = 1; + else + faceDimA = 2; + } + + if ( axisType == CROSS_AXIS ) { + if ( dot(axisA,offsetAB) < 0.0f ) + axisA = -axisA; + axisB = matrixBA * -axisA; + + vmVector3 absAxisA = vmVector3(absPerElem(axisA)); + vmVector3 absAxisB = vmVector3(absPerElem(axisB)); + + dimA[1] = edgeDimA; + dimB[1] = edgeDimB; + + if ( edgeDimA == 0 ) { + if ( absAxisA[1] > absAxisA[2] ) { + dimA[0] = 2; + dimA[2] = 1; + } else { + dimA[0] = 1; + dimA[2] = 2; + } + } else if ( edgeDimA == 1 ) { + if ( absAxisA[2] > absAxisA[0] ) { + dimA[0] = 0; + dimA[2] = 2; + } else { + dimA[0] = 2; + dimA[2] = 0; + } + } else { + if ( absAxisA[0] > absAxisA[1] ) { + dimA[0] = 1; + dimA[2] = 0; + } else { + dimA[0] = 0; + dimA[2] = 1; + } + } + + if ( edgeDimB == 0 ) { + if ( absAxisB[1] > absAxisB[2] ) { + dimB[0] = 2; + dimB[2] = 1; + } else { + dimB[0] = 1; + dimB[2] = 2; + } + } else if ( edgeDimB == 1 ) { + if ( absAxisB[2] > absAxisB[0] ) { + dimB[0] = 0; + dimB[2] = 2; + } else { + dimB[0] = 2; + dimB[2] = 0; + } + } else { + if ( absAxisB[0] > absAxisB[1] ) { + dimB[0] = 1; + dimB[2] = 0; + } else { + dimB[0] = 0; + dimB[2] = 1; + } + } + } else { + dimA[2] = faceDimA; + dimA[0] = (faceDimA+1)%3; + dimA[1] = (faceDimA+2)%3; + dimB[2] = faceDimB; + dimB[0] = (faceDimB+1)%3; + dimB[1] = (faceDimB+2)%3; + } + + vmMatrix3 aperm_col, bperm_col; + + aperm_col.setCol0(ident[dimA[0]]); + aperm_col.setCol1(ident[dimA[1]]); + aperm_col.setCol2(ident[dimA[2]]); + + bperm_col.setCol0(ident[dimB[0]]); + bperm_col.setCol1(ident[dimB[1]]); + bperm_col.setCol2(ident[dimB[2]]); + + vmMatrix3 aperm_row, bperm_row; + + aperm_row = transpose(aperm_col); + bperm_row = transpose(bperm_col); + + // permute all box parameters to be in the face coordinate systems + + vmMatrix3 matrixAB_perm = aperm_row * matrixAB * bperm_col; + vmMatrix3 matrixBA_perm = transpose(matrixAB_perm); + + vmVector3 offsetAB_perm, offsetBA_perm; + + offsetAB_perm = aperm_row * offsetAB; + offsetBA_perm = bperm_row * offsetBA; + + vmVector3 halfA_perm, halfB_perm; + + halfA_perm = aperm_row * boxA.mHalf; + halfB_perm = bperm_row * boxB.mHalf; + + // compute the vector between the centers of each face, in each face's coordinate frame + + vmVector3 signsA_perm, signsB_perm, scalesA_perm, scalesB_perm, faceOffsetAB_perm, faceOffsetBA_perm; + + signsA_perm = copySignPerElem(vmVector3(1.0f),aperm_row * axisA); + signsB_perm = copySignPerElem(vmVector3(1.0f),bperm_row * axisB); + scalesA_perm = mulPerElem( signsA_perm, halfA_perm ); + scalesB_perm = mulPerElem( signsB_perm, halfB_perm ); + + faceOffsetAB_perm = offsetAB_perm + matrixAB_perm.getCol2() * scalesB_perm.getZ(); + faceOffsetAB_perm.setZ( faceOffsetAB_perm.getZ() - scalesA_perm.getZ() ); + + faceOffsetBA_perm = offsetBA_perm + matrixBA_perm.getCol2() * scalesA_perm.getZ(); + faceOffsetBA_perm.setZ( faceOffsetBA_perm.getZ() - scalesB_perm.getZ() ); + + if ( maxGap < 0.0f ) { + // if boxes overlap, this will separate the faces for finding points of penetration. + + faceOffsetAB_perm -= aperm_row * axisA * maxGap * 1.01f; + faceOffsetBA_perm -= bperm_row * axisB * maxGap * 1.01f; + } + + // for each vertex/face or edge/edge pair of the two faces, find the closest points. + // + // these points each have an associated box feature (vertex, edge, or face). if each + // point is in the external Voronoi region of the other's feature, they are the + // closest points of the boxes, and the algorithm can exit. + // + // the feature pairs are arranged so that in the general case, the first test will + // succeed. degenerate cases (parallel faces) may require up to all tests in the + // worst case. + // + // if for some reason no case passes the Voronoi test, the features with the minimum + // distance are returned. + + vmPoint3 localPointA_perm, localPointB_perm; + float minDistSqr; + bool done; + + vmVector3 hA_perm( halfA_perm ), hB_perm( halfB_perm ); + + localPointA_perm.setZ( scalesA_perm.getZ() ); + localPointB_perm.setZ( scalesB_perm.getZ() ); + scalesA_perm.setZ(0.0f); + scalesB_perm.setZ(0.0f); + + int otherFaceDimA, otherFaceDimB; + FeatureType featureA, featureB; + + if ( axisType == CROSS_AXIS ) { + EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm, + otherFaceDimA, otherFaceDimB, featureA, featureB, + hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm, + scalesA_perm, scalesB_perm, true ); + + if ( !done ) { + VertexBFaceATests( done, minDistSqr, localPointA_perm, localPointB_perm, + featureA, featureB, + hA_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm, false ); + + if ( !done ) { + VertexAFaceBTests( done, minDistSqr, localPointA_perm, localPointB_perm, + featureA, featureB, + hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm, false ); + } + } + } else if ( axisType == B_AXIS ) { + VertexAFaceBTests( done, minDistSqr, localPointA_perm, localPointB_perm, + featureA, featureB, + hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm, true ); + + if ( !done ) { + VertexBFaceATests( done, minDistSqr, localPointA_perm, localPointB_perm, + featureA, featureB, + hA_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm, false ); + + if ( !done ) { + EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm, + otherFaceDimA, otherFaceDimB, featureA, featureB, + hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm, + scalesA_perm, scalesB_perm, false ); + } + } + } else { + VertexBFaceATests( done, minDistSqr, localPointA_perm, localPointB_perm, + featureA, featureB, + hA_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm, true ); + + if ( !done ) { + VertexAFaceBTests( done, minDistSqr, localPointA_perm, localPointB_perm, + featureA, featureB, + hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm, false ); + + if ( !done ) { + EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm, + otherFaceDimA, otherFaceDimB, featureA, featureB, + hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm, + matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm, + scalesA_perm, scalesB_perm, false ); + } + } + } + + // convert local points from face-local to box-local coordinate system + + + boxPointA.localPoint = vmPoint3( aperm_col * vmVector3( localPointA_perm )) ; + boxPointB.localPoint = vmPoint3( bperm_col * vmVector3( localPointB_perm )) ; + +#if 0 + // find which features of the boxes are involved. + // the only feature pairs which occur in this function are VF, FV, and EE, even though the + // closest points might actually lie on sub-features, as in a VF contact might be used for + // what's actually a VV contact. this means some feature pairs could possibly seem distinct + // from others, although their contact positions are the same. don't know yet whether this + // matters. + + int sA[3], sB[3]; + + sA[0] = boxPointA.localPoint.getX() > 0.0f; + sA[1] = boxPointA.localPoint.getY() > 0.0f; + sA[2] = boxPointA.localPoint.getZ() > 0.0f; + + sB[0] = boxPointB.localPoint.getX() > 0.0f; + sB[1] = boxPointB.localPoint.getY() > 0.0f; + sB[2] = boxPointB.localPoint.getZ() > 0.0f; + + if ( featureA == F ) { + boxPointA.setFaceFeature( dimA[2], sA[dimA[2]] ); + } else if ( featureA == E ) { + boxPointA.setEdgeFeature( dimA[2], sA[dimA[2]], dimA[otherFaceDimA], sA[dimA[otherFaceDimA]] ); + } else { + boxPointA.setVertexFeature( sA[0], sA[1], sA[2] ); + } + + if ( featureB == F ) { + boxPointB.setFaceFeature( dimB[2], sB[dimB[2]] ); + } else if ( featureB == E ) { + boxPointB.setEdgeFeature( dimB[2], sB[dimB[2]], dimB[otherFaceDimB], sB[dimB[otherFaceDimB]] ); + } else { + boxPointB.setVertexFeature( sB[0], sB[1], sB[2] ); + } +#endif + + normal = transformA * axisA; + + if ( maxGap < 0.0f ) { + return (maxGap); + } else { + return (sqrtf( minDistSqr )); + } +} diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h new file mode 100644 index 0000000..0d4957d --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2006, 2008 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + + +#ifndef __BOXBOXDISTANCE_H__ +#define __BOXBOXDISTANCE_H__ + + +#include "Box.h" + + +//--------------------------------------------------------------------------- +// boxBoxDistance: +// +// description: +// this computes info that can be used for the collision response of two boxes. when the boxes +// do not overlap, the points are set to the closest points of the boxes, and a positive +// distance between them is returned. if the boxes do overlap, a negative distance is returned +// and the points are set to two points that would touch after the boxes are translated apart. +// the contact normal gives the direction to repel or separate the boxes when they touch or +// overlap (it's being approximated here as one of the 15 "separating axis" directions). +// +// returns: +// positive or negative distance between two boxes. +// +// args: +// vmVector3& normal: set to a unit contact normal pointing from box A to box B. +// +// BoxPoint& boxPointA, BoxPoint& boxPointB: +// set to a closest point or point of penetration on each box. +// +// Box boxA, Box boxB: +// boxes, represented as 3 half-widths +// +// const vmTransform3& transformA, const vmTransform3& transformB: +// box transformations, in world coordinates +// +// float distanceThreshold: +// the algorithm will exit early if it finds that the boxes are more distant than this +// threshold, and not compute a contact normal or points. if this distance returned +// exceeds the threshold, all the other output data may not have been computed. by +// default, this is set to MAX_FLOAT so it will have no effect. +// +//--------------------------------------------------------------------------- + +float +boxBoxDistance(vmVector3& normal, BoxPoint& boxPointA, BoxPoint& boxPointB, + PE_REF(Box) boxA, const vmTransform3 & transformA, PE_REF(Box) boxB, + const vmTransform3 & transformB, + float distanceThreshold = FLT_MAX ); + +#endif /* __BOXBOXDISTANCE_H__ */ diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/readme.txt b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/readme.txt new file mode 100644 index 0000000..5b4a907 --- /dev/null +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/readme.txt @@ -0,0 +1 @@ +Empty placeholder for future Libspe2 SPU task diff --git a/src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp b/src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp new file mode 100644 index 0000000..fe61955 --- /dev/null +++ b/src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp @@ -0,0 +1,214 @@ +/* +Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + + +#include "SpuSampleTask.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "../PlatformDefinitions.h" +#include "../SpuFakeDma.h" +#include "LinearMath/btMinMax.h" + +#ifdef __SPU__ +#include +#else +#include +#define spu_printf printf +#endif + +#define MAX_NUM_BODIES 8192 + +struct SampleTask_LocalStoreMemory +{ + ATTRIBUTE_ALIGNED16(char gLocalRigidBody [sizeof(btRigidBody)+16]); + ATTRIBUTE_ALIGNED16(void* gPointerArray[MAX_NUM_BODIES]); + +}; + + + + +//-- MAIN METHOD +void processSampleTask(void* userPtr, void* lsMemory) +{ + // BT_PROFILE("processSampleTask"); + + SampleTask_LocalStoreMemory* localMemory = (SampleTask_LocalStoreMemory*)lsMemory; + + SpuSampleTaskDesc* taskDescPtr = (SpuSampleTaskDesc*)userPtr; + SpuSampleTaskDesc& taskDesc = *taskDescPtr; + + switch (taskDesc.m_sampleCommand) + { + case CMD_SAMPLE_INTEGRATE_BODIES: + { + btTransform predictedTrans; + btCollisionObject** eaPtr = (btCollisionObject**)taskDesc.m_mainMemoryPtr; + + int batchSize = taskDesc.m_sampleValue; + if (batchSize>MAX_NUM_BODIES) + { + spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n"); + break; + } + int dmaArraySize = batchSize*sizeof(void*); + + uint64_t ppuArrayAddress = reinterpret_cast(eaPtr); + + // spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize); + + if (dmaArraySize>=16) + { + cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + } else + { + stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize); + } + + + for ( int i=0;igLocalRigidBody[0]; + void* shortAdd = localMemory->gPointerArray[i]; + uint64_t ppuRigidBodyAddress = reinterpret_cast(shortAdd); + + // spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr); + + int dmaBodySize = sizeof(btRigidBody); + + cellDmaGet((void*)localPtr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + + float timeStep = 1.f/60.f; + + btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj); + if (body) + { + if (body->isActive() && (!body->isStaticOrKinematicObject())) + { + body->predictIntegratedTransform(timeStep, predictedTrans); + body->proceedToTransform( predictedTrans); + void* ptr = (void*)localPtr; + // spu_printf("cellDmaLargePut from %llx to LS %llx\n",ptr,ppuRigidBodyAddress); + + cellDmaLargePut(ptr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + } + } + + } + break; + } + + + case CMD_SAMPLE_PREDICT_MOTION_BODIES: + { + btTransform predictedTrans; + btCollisionObject** eaPtr = (btCollisionObject**)taskDesc.m_mainMemoryPtr; + + int batchSize = taskDesc.m_sampleValue; + int dmaArraySize = batchSize*sizeof(void*); + + if (batchSize>MAX_NUM_BODIES) + { + spu_printf("SPU Error: exceed number of bodies, see MAX_NUM_BODIES in SpuSampleTask.cpp\n"); + break; + } + + uint64_t ppuArrayAddress = reinterpret_cast(eaPtr); + + // spu_printf("array location is at %llx, batchSize = %d, DMA size = %d\n",ppuArrayAddress,batchSize,dmaArraySize); + + if (dmaArraySize>=16) + { + cellDmaLargeGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + } else + { + stallingUnalignedDmaSmallGet((void*)&localMemory->gPointerArray[0], ppuArrayAddress , dmaArraySize); + } + + + for ( int i=0;igLocalRigidBody[0]; + void* shortAdd = localMemory->gPointerArray[i]; + uint64_t ppuRigidBodyAddress = reinterpret_cast(shortAdd); + + // spu_printf("cellDmaGet at CMD_SAMPLE_INTEGRATE_BODIES from %llx to %llx\n",ppuRigidBodyAddress,localPtr); + + int dmaBodySize = sizeof(btRigidBody); + + cellDmaGet((void*)localPtr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + + + float timeStep = 1.f/60.f; + + btRigidBody* body = (btRigidBody*) localPtr;//btRigidBody::upcast(colObj); + if (body) + { + if (!body->isStaticOrKinematicObject()) + { + if (body->isActive()) + { + body->integrateVelocities( timeStep); + //damping + body->applyDamping(timeStep); + + body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); + + void* ptr = (void*)localPtr; + cellDmaLargePut(ptr, ppuRigidBodyAddress , dmaBodySize, DMA_TAG(1), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(1)); + } + } + } + + } + break; + } + + + + default: + { + + } + }; +} + + +#if defined(__CELLOS_LV2__) || defined (LIBSPE2) + +ATTRIBUTE_ALIGNED16(SampleTask_LocalStoreMemory gLocalStoreMemory); + +void* createSampleLocalStoreMemory() +{ + return &gLocalStoreMemory; +} +#else +void* createSampleLocalStoreMemory() +{ + return new SampleTask_LocalStoreMemory; +}; + +#endif diff --git a/src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h b/src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h new file mode 100644 index 0000000..c8ebdfd --- /dev/null +++ b/src/BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h @@ -0,0 +1,54 @@ +/* +Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef SPU_SAMPLE_TASK_H +#define SPU_SAMPLE_TASK_H + +#include "../PlatformDefinitions.h" +#include "LinearMath/btScalar.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" + +#include "LinearMath/btAlignedAllocator.h" + + +enum +{ + CMD_SAMPLE_INTEGRATE_BODIES = 1, + CMD_SAMPLE_PREDICT_MOTION_BODIES +}; + + + +ATTRIBUTE_ALIGNED16(struct) SpuSampleTaskDesc +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + uint32_t m_sampleCommand; + uint32_t m_taskId; + + uint64_t m_mainMemoryPtr; + int m_sampleValue; + + +}; + + +void processSampleTask(void* userPtr, void* lsMemory); +void* createSampleLocalStoreMemory(); + + +#endif //SPU_SAMPLE_TASK_H + diff --git a/src/BulletMultiThreaded/SpuSampleTask/readme.txt b/src/BulletMultiThreaded/SpuSampleTask/readme.txt new file mode 100644 index 0000000..5b4a907 --- /dev/null +++ b/src/BulletMultiThreaded/SpuSampleTask/readme.txt @@ -0,0 +1 @@ +Empty placeholder for future Libspe2 SPU task diff --git a/src/BulletMultiThreaded/SpuSampleTaskProcess.cpp b/src/BulletMultiThreaded/SpuSampleTaskProcess.cpp new file mode 100644 index 0000000..11cb9e7 --- /dev/null +++ b/src/BulletMultiThreaded/SpuSampleTaskProcess.cpp @@ -0,0 +1,222 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//#define __CELLOS_LV2__ 1 + +#define USE_SAMPLE_PROCESS 1 +#ifdef USE_SAMPLE_PROCESS + + +#include "SpuSampleTaskProcess.h" +#include + +#ifdef __SPU__ + + + +void SampleThreadFunc(void* userPtr,void* lsMemory) +{ + //do nothing + printf("hello world\n"); +} + + +void* SamplelsMemoryFunc() +{ + //don't create local store memory, just return 0 + return 0; +} + + +#else + + +#include "btThreadSupportInterface.h" + +//# include "SPUAssert.h" +#include + + + +extern "C" { + extern char SPU_SAMPLE_ELF_SYMBOL[]; +} + + + + + +SpuSampleTaskProcess::SpuSampleTaskProcess(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks) +:m_threadInterface(threadInterface), +m_maxNumOutstandingTasks(maxNumOutstandingTasks) +{ + + m_taskBusy.resize(m_maxNumOutstandingTasks); + m_spuSampleTaskDesc.resize(m_maxNumOutstandingTasks); + + for (int i = 0; i < m_maxNumOutstandingTasks; i++) + { + m_taskBusy[i] = false; + } + m_numBusyTasks = 0; + m_currentTask = 0; + + m_initialized = false; + + m_threadInterface->startSPU(); + + +} + +SpuSampleTaskProcess::~SpuSampleTaskProcess() +{ + m_threadInterface->stopSPU(); + +} + + + +void SpuSampleTaskProcess::initialize() +{ +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("SpuSampleTaskProcess::initialize()\n"); +#endif //DEBUG_SPU_TASK_SCHEDULING + + for (int i = 0; i < m_maxNumOutstandingTasks; i++) + { + m_taskBusy[i] = false; + } + m_numBusyTasks = 0; + m_currentTask = 0; + m_initialized = true; + +} + + +void SpuSampleTaskProcess::issueTask(void* sampleMainMemPtr,int sampleValue,int sampleCommand) +{ + +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("SpuSampleTaskProcess::issueTask (m_currentTask= %d\)n", m_currentTask); +#endif //DEBUG_SPU_TASK_SCHEDULING + + m_taskBusy[m_currentTask] = true; + m_numBusyTasks++; + + SpuSampleTaskDesc& taskDesc = m_spuSampleTaskDesc[m_currentTask]; + { + // send task description in event message + // no error checking here... + // but, currently, event queue can be no larger than NUM_WORKUNIT_TASKS. + + taskDesc.m_mainMemoryPtr = reinterpret_cast(sampleMainMemPtr); + taskDesc.m_sampleValue = sampleValue; + taskDesc.m_sampleCommand = sampleCommand; + + //some bookkeeping to recognize finished tasks + taskDesc.m_taskId = m_currentTask; + } + + + m_threadInterface->sendRequest(1, (ppu_address_t) &taskDesc, m_currentTask); + + // if all tasks busy, wait for spu event to clear the task. + + if (m_numBusyTasks >= m_maxNumOutstandingTasks) + { + unsigned int taskId; + unsigned int outputSize; + + for (int i=0;iwaitForResponse(&taskId, &outputSize); + + //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize); + + postProcess(taskId, outputSize); + + m_taskBusy[taskId] = false; + + m_numBusyTasks--; + } + + // find new task buffer + for (int i = 0; i < m_maxNumOutstandingTasks; i++) + { + if (!m_taskBusy[i]) + { + m_currentTask = i; + break; + } + } +} + + +///Optional PPU-size post processing for each task +void SpuSampleTaskProcess::postProcess(int taskId, int outputSize) +{ + +} + + +void SpuSampleTaskProcess::flush() +{ +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("\nSpuCollisionTaskProcess::flush()\n"); +#endif //DEBUG_SPU_TASK_SCHEDULING + + + // all tasks are issued, wait for all tasks to be complete + while(m_numBusyTasks > 0) + { +// Consolidating SPU code + unsigned int taskId; + unsigned int outputSize; + + for (int i=0;iwaitForResponse(&taskId, &outputSize); + } + + //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize); + + postProcess(taskId, outputSize); + + m_taskBusy[taskId] = false; + + m_numBusyTasks--; + } + + +} + +#endif + + +#endif //USE_SAMPLE_PROCESS diff --git a/src/BulletMultiThreaded/SpuSampleTaskProcess.h b/src/BulletMultiThreaded/SpuSampleTaskProcess.h new file mode 100644 index 0000000..6173225 --- /dev/null +++ b/src/BulletMultiThreaded/SpuSampleTaskProcess.h @@ -0,0 +1,153 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SPU_SAMPLE_TASK_PROCESS_H +#define BT_SPU_SAMPLE_TASK_PROCESS_H + +#include + + +#include "PlatformDefinitions.h" + +#include + +#include "LinearMath/btAlignedObjectArray.h" + + +#include "SpuSampleTask/SpuSampleTask.h" + + +//just add your commands here, try to keep them globally unique for debugging purposes +#define CMD_SAMPLE_TASK_COMMAND 10 + + + +/// SpuSampleTaskProcess handles SPU processing of collision pairs. +/// When PPU issues a task, it will look for completed task buffers +/// PPU will do postprocessing, dependent on workunit output (not likely) +class SpuSampleTaskProcess +{ + // track task buffers that are being used, and total busy tasks + btAlignedObjectArray m_taskBusy; + btAlignedObjectArraym_spuSampleTaskDesc; + + int m_numBusyTasks; + + // the current task and the current entry to insert a new work unit + int m_currentTask; + + bool m_initialized; + + void postProcess(int taskId, int outputSize); + + class btThreadSupportInterface* m_threadInterface; + + int m_maxNumOutstandingTasks; + + + +public: + SpuSampleTaskProcess(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks); + + ~SpuSampleTaskProcess(); + + ///call initialize in the beginning of the frame, before addCollisionPairToTask + void initialize(); + + void issueTask(void* sampleMainMemPtr,int sampleValue,int sampleCommand); + + ///call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished + void flush(); +}; + + +#if defined(USE_LIBSPE2) && defined(__SPU__) +////////////////////MAIN///////////////////////////// +#include "../SpuLibspe2Support.h" +#include +#include +#include + +void * SamplelsMemoryFunc(); +void SampleThreadFunc(void* userPtr,void* lsMemory); + +//#define DEBUG_LIBSPE2_MAINLOOP + +int main(unsigned long long speid, addr64 argp, addr64 envp) +{ + printf("SPU is up \n"); + + ATTRIBUTE_ALIGNED128(btSpuStatus status); + ATTRIBUTE_ALIGNED16( SpuSampleTaskDesc taskDesc ) ; + unsigned int received_message = Spu_Mailbox_Event_Nothing; + bool shutdown = false; + + cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + status.m_status = Spu_Status_Free; + status.m_lsMemory.p = SamplelsMemoryFunc(); + + cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + + while (!shutdown) + { + received_message = spu_read_in_mbox(); + + + + switch(received_message) + { + case Spu_Mailbox_Event_Shutdown: + shutdown = true; + break; + case Spu_Mailbox_Event_Task: + // refresh the status +#ifdef DEBUG_LIBSPE2_MAINLOOP + printf("SPU recieved Task \n"); +#endif //DEBUG_LIBSPE2_MAINLOOP + cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + btAssert(status.m_status==Spu_Status_Occupied); + + cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuSampleTaskDesc), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + SampleThreadFunc((void*)&taskDesc, reinterpret_cast (taskDesc.m_mainMemoryPtr) ); + break; + case Spu_Mailbox_Event_Nothing: + default: + break; + } + + // set to status free and wait for next task + status.m_status = Spu_Status_Free; + cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + + } + return 0; +} +////////////////////////////////////////////////////// +#endif + + + +#endif // BT_SPU_SAMPLE_TASK_PROCESS_H + diff --git a/src/BulletMultiThreaded/SpuSync.h b/src/BulletMultiThreaded/SpuSync.h new file mode 100644 index 0000000..4157b8f --- /dev/null +++ b/src/BulletMultiThreaded/SpuSync.h @@ -0,0 +1,149 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2007 Starbreeze Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Marten Svanfeldt +*/ + +#ifndef BT_SPU_SYNC_H +#define BT_SPU_SYNC_H + + +#include "PlatformDefinitions.h" + + +#if defined(WIN32) + +#define WIN32_LEAN_AND_MEAN +#ifdef _XBOX +#include +#else +#include +#endif + +///The btSpinlock is a structure to allow multi-platform synchronization. This allows to port the SPU tasks to other platforms. +class btSpinlock +{ +public: + //typedef volatile LONG SpinVariable; + typedef CRITICAL_SECTION SpinVariable; + + btSpinlock (SpinVariable* var) + : spinVariable (var) + {} + + void Init () + { + //*spinVariable = 0; + InitializeCriticalSection(spinVariable); + } + + void Lock () + { + EnterCriticalSection(spinVariable); + } + + void Unlock () + { + LeaveCriticalSection(spinVariable); + } + +private: + SpinVariable* spinVariable; +}; + + +#elif defined (__CELLOS_LV2__) + +//#include +#include + +///The btSpinlock is a structure to allow multi-platform synchronization. This allows to port the SPU tasks to other platforms. +class btSpinlock +{ +public: + typedef CellSyncMutex SpinVariable; + + btSpinlock (SpinVariable* var) + : spinVariable (var) + {} + + void Init () + { +#ifndef __SPU__ + //*spinVariable = 1; + cellSyncMutexInitialize(spinVariable); +#endif + } + + + + void Lock () + { +#ifdef __SPU__ + // lock semaphore + /*while (cellAtomicTestAndDecr32(atomic_buf, (uint64_t)spinVariable) == 0) + { + + };*/ + cellSyncMutexLock((uint64_t)spinVariable); +#endif + } + + void Unlock () + { +#ifdef __SPU__ + //cellAtomicIncr32(atomic_buf, (uint64_t)spinVariable); + cellSyncMutexUnlock((uint64_t)spinVariable); +#endif + } + + +private: + SpinVariable* spinVariable; + ATTRIBUTE_ALIGNED128(uint32_t atomic_buf[32]); +}; + +#else +//create a dummy implementation (without any locking) useful for serial processing +class btSpinlock +{ +public: + typedef int SpinVariable; + + btSpinlock (SpinVariable* var) + : spinVariable (var) + {} + + void Init () + { + } + + void Lock () + { + } + + void Unlock () + { + } + +private: + SpinVariable* spinVariable; +}; + + +#endif + + +#endif //BT_SPU_SYNC_H + diff --git a/src/BulletMultiThreaded/TrbDynBody.h b/src/BulletMultiThreaded/TrbDynBody.h new file mode 100644 index 0000000..a7f4bf1 --- /dev/null +++ b/src/BulletMultiThreaded/TrbDynBody.h @@ -0,0 +1,79 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef BT_RB_DYN_BODY_H__ +#define BT_RB_DYN_BODY_H__ + +#include "vectormath/vmInclude.h" +using namespace Vectormath::Aos; + +#include "TrbStateVec.h" + +class CollObject; + +class TrbDynBody +{ +public: + TrbDynBody() + { + fMass = 0.0f; + fCollObject = NULL; + fElasticity = 0.2f; + fFriction = 0.8f; + } + + // Get methods + float getMass() const {return fMass;}; + float getElasticity() const {return fElasticity;} + float getFriction() const {return fFriction;} + CollObject* getCollObject() const {return fCollObject;} + const Matrix3 &getBodyInertia() const {return fIBody;} + const Matrix3 &getBodyInertiaInv() const {return fIBodyInv;} + float getMassInv() const {return fMassInv;} + + // Set methods + void setMass(float mass) {fMass=mass;fMassInv=mass>0.0f?1.0f/mass:0.0f;} + void setBodyInertia(const Matrix3 bodyInertia) {fIBody = bodyInertia;fIBodyInv = inverse(bodyInertia);} + void setElasticity(float elasticity) {fElasticity = elasticity;} + void setFriction(float friction) {fFriction = friction;} + void setCollObject(CollObject *collObj) {fCollObject = collObj;} + + void setBodyInertiaInv(const Matrix3 bodyInertiaInv) + { + fIBody = inverse(bodyInertiaInv); + fIBodyInv = bodyInertiaInv; + } + void setMassInv(float invMass) { + fMass= invMass>0.0f ? 1.0f/invMass :0.0f; + fMassInv=invMass; + } + + +private: + // Rigid Body constants + float fMass; // Rigid Body mass + float fMassInv; // Inverse of mass + Matrix3 fIBody; // Inertia matrix in body's coords + Matrix3 fIBodyInv; // Inertia matrix inverse in body's coords + float fElasticity; // Coefficient of restitution + float fFriction; // Coefficient of friction + +public: + CollObject* fCollObject; // Collision object corresponding the RB +} __attribute__ ((aligned(16))); + +#endif //BT_RB_DYN_BODY_H__ + diff --git a/src/BulletMultiThreaded/TrbStateVec.h b/src/BulletMultiThreaded/TrbStateVec.h new file mode 100644 index 0000000..b6d895e --- /dev/null +++ b/src/BulletMultiThreaded/TrbStateVec.h @@ -0,0 +1,339 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef BT_TRBSTATEVEC_H__ +#define BT_TRBSTATEVEC_H__ + +#include +#ifdef PFX_USE_FREE_VECTORMATH +#include "vecmath/vmInclude.h" +#else +#include "vectormath/vmInclude.h" +#endif //PFX_USE_FREE_VECTORMATH + + +#include "PlatformDefinitions.h" + + +static inline vmVector3 read_Vector3(const float* p) +{ + vmVector3 v; + loadXYZ(v, p); + return v; +} + +static inline vmQuat read_Quat(const float* p) +{ + vmQuat vq; + loadXYZW(vq, p); + return vq; +} + +static inline void store_Vector3(const vmVector3 &src, float* p) +{ + vmVector3 v = src; + storeXYZ(v, p); +} + +static inline void store_Quat(const vmQuat &src, float* p) +{ + vmQuat vq = src; + storeXYZW(vq, p); +} + +// Motion Type +enum { + PfxMotionTypeFixed = 0, + PfxMotionTypeActive, + PfxMotionTypeKeyframe, + PfxMotionTypeOneWay, + PfxMotionTypeTrigger, + PfxMotionTypeCount +}; + +#define PFX_MOTION_MASK_DYNAMIC 0x0a // Active,OneWay +#define PFX_MOTION_MASK_STATIC 0x95 // Fixed,Keyframe,Trigger,Sleeping +#define PFX_MOTION_MASK_SLEEP 0x0e // Can sleep +#define PFX_MOTION_MASK_TYPE 0x7f + +// +// Rigid Body state +// + +#ifdef __CELLOS_LV2__ +ATTRIBUTE_ALIGNED128(class) TrbState +#else +ATTRIBUTE_ALIGNED16(class) TrbState +#endif + +{ +public: + TrbState() + { + setMotionType(PfxMotionTypeActive); + contactFilterSelf=contactFilterTarget=0xffffffff; + deleted = 0; + mSleeping = 0; + useSleep = 1; + trbBodyIdx=0; + mSleepCount=0; + useCcd = 0; + useContactCallback = 0; + useSleepCallback = 0; + linearDamping = 1.0f; + angularDamping = 0.99f; + } + + TrbState(const uint8_t m, const vmVector3& x, const vmQuat& q, const vmVector3& v, const vmVector3& omega ); + + uint16_t mSleepCount; + uint8_t mMotionType; + uint8_t deleted : 1; + uint8_t mSleeping : 1; + uint8_t useSleep : 1; + uint8_t useCcd : 1; + uint8_t useContactCallback : 1; + uint8_t useSleepCallback : 1; + + uint16_t trbBodyIdx; + uint32_t contactFilterSelf; + uint32_t contactFilterTarget; + + float center[3]; // AABB center(World) + float half[3]; // AABB half(World) + + float linearDamping; + float angularDamping; + + float deltaLinearVelocity[3]; + float deltaAngularVelocity[3]; + + float fX[3]; // position + float fQ[4]; // orientation + float fV[3]; // velocity + float fOmega[3]; // angular velocity + + inline void setZero(); // Zeroes out the elements + inline void setIdentity(); // Sets the rotation to identity and zeroes out the other elements + + bool isDeleted() const {return deleted==1;} + + uint16_t getRigidBodyId() const {return trbBodyIdx;} + void setRigidBodyId(uint16_t i) {trbBodyIdx = i;} + + + uint32_t getContactFilterSelf() const {return contactFilterSelf;} + void setContactFilterSelf(uint32_t filter) {contactFilterSelf = filter;} + + uint32_t getContactFilterTarget() const {return contactFilterTarget;} + void setContactFilterTarget(uint32_t filter) {contactFilterTarget = filter;} + + float getLinearDamping() const {return linearDamping;} + float getAngularDamping() const {return angularDamping;} + + void setLinearDamping(float damping) {linearDamping=damping;} + void setAngularDamping(float damping) {angularDamping=damping;} + + + uint8_t getMotionType() const {return mMotionType;} + void setMotionType(uint8_t t) {mMotionType = t;mSleeping=0;mSleepCount=0;} + + uint8_t getMotionMask() const {return (1< + +#include "SpuCollisionTaskProcess.h" + +#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" + + + +///The number of threads should be equal to the number of available cores +///@todo: each worker should be linked to a single core, using SetThreadIdealProcessor. + +///Win32ThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication +///Setup and initialize SPU/CELL/Libspe2 +Win32ThreadSupport::Win32ThreadSupport(const Win32ThreadConstructionInfo & threadConstructionInfo) +{ + m_maxNumTasks = threadConstructionInfo.m_numThreads; + startThreads(threadConstructionInfo); +} + +///cleanup/shutdown Libspe2 +Win32ThreadSupport::~Win32ThreadSupport() +{ + stopSPU(); +} + + + + +#include + +DWORD WINAPI Thread_no_1( LPVOID lpParam ) +{ + + Win32ThreadSupport::btSpuStatus* status = (Win32ThreadSupport::btSpuStatus*)lpParam; + + + while (1) + { + WaitForSingleObject(status->m_eventStartHandle,INFINITE); + + void* userPtr = status->m_userPtr; + + if (userPtr) + { + btAssert(status->m_status); + status->m_userThreadFunc(userPtr,status->m_lsMemory); + status->m_status = 2; + SetEvent(status->m_eventCompletetHandle); + } else + { + //exit Thread + status->m_status = 3; + printf("Thread with taskId %i with handle %p exiting\n",status->m_taskId, status->m_threadHandle); + SetEvent(status->m_eventCompletetHandle); + break; + } + + } + + printf("Thread TERMINATED\n"); + return 0; + +} + +///send messages to SPUs +void Win32ThreadSupport::sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t taskId) +{ + /// gMidphaseSPU.sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (ppu_address_t) &taskDesc); + + ///we should spawn an SPU task here, and in 'waitForResponse' it should wait for response of the (one of) the first tasks that finished + + + + switch (uiCommand) + { + case CMD_GATHER_AND_PROCESS_PAIRLIST: + { + + +//#define SINGLE_THREADED 1 +#ifdef SINGLE_THREADED + + btSpuStatus& spuStatus = m_activeSpuStatus[0]; + spuStatus.m_userPtr=(void*)uiArgument0; + spuStatus.m_userThreadFunc(spuStatus.m_userPtr,spuStatus.m_lsMemory); + HANDLE handle =0; +#else + + + btSpuStatus& spuStatus = m_activeSpuStatus[taskId]; + btAssert(taskId>=0); + btAssert(int(taskId) 1); + spuStatus.m_status = 0; + + ///need to find an active spu + btAssert(last>=0); + +#else + last=0; + btSpuStatus& spuStatus = m_activeSpuStatus[last]; +#endif //SINGLE_THREADED + + + + *puiArgument0 = spuStatus.m_taskId; + *puiArgument1 = spuStatus.m_status; + + +} + + +///check for messages from SPUs +bool Win32ThreadSupport::isTaskCompleted(unsigned int *puiArgument0, unsigned int *puiArgument1, int timeOutInMilliseconds) +{ + ///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response + + ///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback' + + + btAssert(m_activeSpuStatus.size()); + + int last = -1; +#ifndef SINGLE_THREADED + DWORD res = WaitForMultipleObjects(m_completeHandles.size(), &m_completeHandles[0], FALSE, timeOutInMilliseconds); + + if ((res != STATUS_TIMEOUT) && (res != WAIT_FAILED)) + { + + btAssert(res != WAIT_FAILED); + last = res - WAIT_OBJECT_0; + + btSpuStatus& spuStatus = m_activeSpuStatus[last]; + btAssert(spuStatus.m_threadHandle); + btAssert(spuStatus.m_eventCompletetHandle); + + //WaitForSingleObject(spuStatus.m_eventCompletetHandle, INFINITE); + btAssert(spuStatus.m_status > 1); + spuStatus.m_status = 0; + + ///need to find an active spu + btAssert(last>=0); + + #else + last=0; + btSpuStatus& spuStatus = m_activeSpuStatus[last]; + #endif //SINGLE_THREADED + + + + *puiArgument0 = spuStatus.m_taskId; + *puiArgument1 = spuStatus.m_status; + + return true; + } + + return false; +} + + +void Win32ThreadSupport::startThreads(const Win32ThreadConstructionInfo& threadConstructionInfo) +{ + + m_activeSpuStatus.resize(threadConstructionInfo.m_numThreads); + m_completeHandles.resize(threadConstructionInfo.m_numThreads); + + m_maxNumTasks = threadConstructionInfo.m_numThreads; + + for (int i=0;i0) + { + WaitForSingleObject(spuStatus.m_eventCompletetHandle, INFINITE); + } + + + spuStatus.m_userPtr = 0; + SetEvent(spuStatus.m_eventStartHandle); + WaitForSingleObject(spuStatus.m_eventCompletetHandle, INFINITE); + + CloseHandle(spuStatus.m_eventCompletetHandle); + CloseHandle(spuStatus.m_eventStartHandle); + CloseHandle(spuStatus.m_threadHandle); + + } + + m_activeSpuStatus.clear(); + m_completeHandles.clear(); + +} + + + +class btWin32Barrier : public btBarrier +{ +private: + CRITICAL_SECTION mExternalCriticalSection; + CRITICAL_SECTION mLocalCriticalSection; + HANDLE mRunEvent,mNotifyEvent; + int mCounter,mEnableCounter; + int mMaxCount; + +public: + btWin32Barrier() + { + mCounter = 0; + mMaxCount = 1; + mEnableCounter = 0; + InitializeCriticalSection(&mExternalCriticalSection); + InitializeCriticalSection(&mLocalCriticalSection); + mRunEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + mNotifyEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + } + + virtual ~btWin32Barrier() + { + DeleteCriticalSection(&mExternalCriticalSection); + DeleteCriticalSection(&mLocalCriticalSection); + CloseHandle(mRunEvent); + CloseHandle(mNotifyEvent); + } + + void sync() + { + int eventId; + + EnterCriticalSection(&mExternalCriticalSection); + + //PFX_PRINTF("enter taskId %d count %d stage %d phase %d mEnableCounter %d\n",taskId,mCounter,debug&0xff,debug>>16,mEnableCounter); + + if(mEnableCounter > 0) { + ResetEvent(mNotifyEvent); + LeaveCriticalSection(&mExternalCriticalSection); + WaitForSingleObject(mNotifyEvent,INFINITE); + EnterCriticalSection(&mExternalCriticalSection); + } + + eventId = mCounter; + mCounter++; + + if(eventId == mMaxCount-1) { + SetEvent(mRunEvent); + + mEnableCounter = mCounter-1; + mCounter = 0; + } + else { + ResetEvent(mRunEvent); + LeaveCriticalSection(&mExternalCriticalSection); + WaitForSingleObject(mRunEvent,INFINITE); + EnterCriticalSection(&mExternalCriticalSection); + mEnableCounter--; + } + + if(mEnableCounter == 0) { + SetEvent(mNotifyEvent); + } + + //PFX_PRINTF("leave taskId %d count %d stage %d phase %d mEnableCounter %d\n",taskId,mCounter,debug&0xff,debug>>16,mEnableCounter); + + LeaveCriticalSection(&mExternalCriticalSection); + } + + virtual void setMaxCount(int n) {mMaxCount = n;} + virtual int getMaxCount() {return mMaxCount;} +}; + +class btWin32CriticalSection : public btCriticalSection +{ +private: + CRITICAL_SECTION mCriticalSection; + +public: + btWin32CriticalSection() + { + InitializeCriticalSection(&mCriticalSection); + } + + ~btWin32CriticalSection() + { + DeleteCriticalSection(&mCriticalSection); + } + + unsigned int getSharedParam(int i) + { + btAssert(i>=0&&i<31); + return mCommonBuff[i+1]; + } + + void setSharedParam(int i,unsigned int p) + { + btAssert(i>=0&&i<31); + mCommonBuff[i+1] = p; + } + + void lock() + { + EnterCriticalSection(&mCriticalSection); + mCommonBuff[0] = 1; + } + + void unlock() + { + mCommonBuff[0] = 0; + LeaveCriticalSection(&mCriticalSection); + } +}; + + +btBarrier* Win32ThreadSupport::createBarrier() +{ + unsigned char* mem = (unsigned char*)btAlignedAlloc(sizeof(btWin32Barrier),16); + btWin32Barrier* barrier = new(mem) btWin32Barrier(); + barrier->setMaxCount(getNumTasks()); + return barrier; +} + +btCriticalSection* Win32ThreadSupport::createCriticalSection() +{ + unsigned char* mem = (unsigned char*) btAlignedAlloc(sizeof(btWin32CriticalSection),16); + btWin32CriticalSection* cs = new(mem) btWin32CriticalSection(); + return cs; +} + +void Win32ThreadSupport::deleteBarrier(btBarrier* barrier) +{ + barrier->~btBarrier(); + btAlignedFree(barrier); +} + +void Win32ThreadSupport::deleteCriticalSection(btCriticalSection* criticalSection) +{ + criticalSection->~btCriticalSection(); + btAlignedFree(criticalSection); +} + + +#endif //USE_WIN32_THREADING + + diff --git a/src/BulletMultiThreaded/Win32ThreadSupport.h b/src/BulletMultiThreaded/Win32ThreadSupport.h new file mode 100644 index 0000000..f688e6c --- /dev/null +++ b/src/BulletMultiThreaded/Win32ThreadSupport.h @@ -0,0 +1,141 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "LinearMath/btScalar.h" +#include "PlatformDefinitions.h" + +#ifdef USE_WIN32_THREADING //platform specific defines are defined in PlatformDefinitions.h + +#ifndef BT_WIN32_THREAD_SUPPORT_H +#define BT_WIN32_THREAD_SUPPORT_H + +#include "LinearMath/btAlignedObjectArray.h" + +#include "btThreadSupportInterface.h" + + +typedef void (*Win32ThreadFunc)(void* userPtr,void* lsMemory); +typedef void* (*Win32lsMemorySetupFunc)(); + + +///Win32ThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication +class Win32ThreadSupport : public btThreadSupportInterface +{ +public: + ///placeholder, until libspe2 support is there + struct btSpuStatus + { + uint32_t m_taskId; + uint32_t m_commandId; + uint32_t m_status; + + Win32ThreadFunc m_userThreadFunc; + void* m_userPtr; //for taskDesc etc + void* m_lsMemory; //initialized using Win32LocalStoreMemorySetupFunc + + void* m_threadHandle; //this one is calling 'Win32ThreadFunc' + + void* m_eventStartHandle; + char m_eventStartHandleName[32]; + + void* m_eventCompletetHandle; + char m_eventCompletetHandleName[32]; + + + }; +private: + + btAlignedObjectArray m_activeSpuStatus; + btAlignedObjectArray m_completeHandles; + + int m_maxNumTasks; +public: + ///Setup and initialize SPU/CELL/Libspe2 + + struct Win32ThreadConstructionInfo + { + Win32ThreadConstructionInfo(const char* uniqueName, + Win32ThreadFunc userThreadFunc, + Win32lsMemorySetupFunc lsMemoryFunc, + int numThreads=1, + int threadStackSize=65535 + ) + :m_uniqueName(uniqueName), + m_userThreadFunc(userThreadFunc), + m_lsMemoryFunc(lsMemoryFunc), + m_numThreads(numThreads), + m_threadStackSize(threadStackSize) + { + + } + + const char* m_uniqueName; + Win32ThreadFunc m_userThreadFunc; + Win32lsMemorySetupFunc m_lsMemoryFunc; + int m_numThreads; + int m_threadStackSize; + + }; + + + + Win32ThreadSupport(const Win32ThreadConstructionInfo& threadConstructionInfo); + +///cleanup/shutdown Libspe2 + virtual ~Win32ThreadSupport(); + + void startThreads(const Win32ThreadConstructionInfo& threadInfo); + + +///send messages to SPUs + virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1); + +///check for messages from SPUs + virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1); + + virtual bool isTaskCompleted(unsigned int *puiArgument0, unsigned int *puiArgument1, int timeOutInMilliseconds); + +///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded) + virtual void startSPU(); + +///tell the task scheduler we are done with the SPU tasks + virtual void stopSPU(); + + virtual void setNumTasks(int numTasks) + { + m_maxNumTasks = numTasks; + } + + virtual int getNumTasks() const + { + return m_maxNumTasks; + } + + virtual void* getThreadLocalMemory(int taskId) + { + return m_activeSpuStatus[taskId].m_lsMemory; + } + virtual btBarrier* createBarrier(); + + virtual btCriticalSection* createCriticalSection(); + + virtual void deleteBarrier(btBarrier* barrier); + + virtual void deleteCriticalSection(btCriticalSection* criticalSection); +}; + +#endif //BT_WIN32_THREAD_SUPPORT_H + +#endif //USE_WIN32_THREADING diff --git a/src/BulletMultiThreaded/btGpu3DGridBroadphase.cpp b/src/BulletMultiThreaded/btGpu3DGridBroadphase.cpp new file mode 100644 index 0000000..e1d0219 --- /dev/null +++ b/src/BulletMultiThreaded/btGpu3DGridBroadphase.cpp @@ -0,0 +1,590 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///The 3 following lines include the CPU implementation of the kernels, keep them in this order. +#include "BulletMultiThreaded/btGpuDefines.h" +#include "BulletMultiThreaded/btGpuUtilsSharedDefs.h" +#include "BulletMultiThreaded/btGpuUtilsSharedCode.h" + + + +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btQuickprof.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" + + + +#include "btGpuDefines.h" +#include "btGpuUtilsSharedDefs.h" + +#include "btGpu3DGridBroadphaseSharedDefs.h" + +#include "btGpu3DGridBroadphase.h" +#include //for memset + + +#include + + + +static bt3DGridBroadphaseParams s3DGridBroadphaseParams; + + + +btGpu3DGridBroadphase::btGpu3DGridBroadphase( const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, + int maxBodiesPerCell, + btScalar cellFactorAABB) : + btSimpleBroadphase(maxSmallProxies, +// new (btAlignedAlloc(sizeof(btSortedOverlappingPairCache),16)) btSortedOverlappingPairCache), + new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache), + m_bInitialized(false), + m_numBodies(0) +{ + _initialize(worldAabbMin, worldAabbMax, gridSizeX, gridSizeY, gridSizeZ, + maxSmallProxies, maxLargeProxies, maxPairsPerBody, + maxBodiesPerCell, cellFactorAABB); +} + + + +btGpu3DGridBroadphase::btGpu3DGridBroadphase( btOverlappingPairCache* overlappingPairCache, + const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, + int maxBodiesPerCell, + btScalar cellFactorAABB) : + btSimpleBroadphase(maxSmallProxies, overlappingPairCache), + m_bInitialized(false), + m_numBodies(0) +{ + _initialize(worldAabbMin, worldAabbMax, gridSizeX, gridSizeY, gridSizeZ, + maxSmallProxies, maxLargeProxies, maxPairsPerBody, + maxBodiesPerCell, cellFactorAABB); +} + + + +btGpu3DGridBroadphase::~btGpu3DGridBroadphase() +{ + //btSimpleBroadphase will free memory of btSortedOverlappingPairCache, because m_ownsPairCache + btAssert(m_bInitialized); + _finalize(); +} + + + +void btGpu3DGridBroadphase::_initialize( const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, + int maxBodiesPerCell, + btScalar cellFactorAABB) +{ + // set various paramerers + m_ownsPairCache = true; + m_params.m_gridSizeX = gridSizeX; + m_params.m_gridSizeY = gridSizeY; + m_params.m_gridSizeZ = gridSizeZ; + m_params.m_numCells = m_params.m_gridSizeX * m_params.m_gridSizeY * m_params.m_gridSizeZ; + btVector3 w_org = worldAabbMin; + m_params.m_worldOriginX = w_org.getX(); + m_params.m_worldOriginY = w_org.getY(); + m_params.m_worldOriginZ = w_org.getZ(); + btVector3 w_size = worldAabbMax - worldAabbMin; + m_params.m_cellSizeX = w_size.getX() / m_params.m_gridSizeX; + m_params.m_cellSizeY = w_size.getY() / m_params.m_gridSizeY; + m_params.m_cellSizeZ = w_size.getZ() / m_params.m_gridSizeZ; + m_maxRadius = btMin(btMin(m_params.m_cellSizeX, m_params.m_cellSizeY), m_params.m_cellSizeZ); + m_maxRadius *= btScalar(0.5f); + m_params.m_numBodies = m_numBodies; + m_params.m_maxBodiesPerCell = maxBodiesPerCell; + + m_numLargeHandles = 0; + m_maxLargeHandles = maxLargeProxies; + + m_maxPairsPerBody = maxPairsPerBody; + + m_cellFactorAABB = cellFactorAABB; + + m_LastLargeHandleIndex = -1; + + btAssert(!m_bInitialized); + // allocate host storage + m_hBodiesHash = new unsigned int[m_maxHandles * 2]; + memset(m_hBodiesHash, 0x00, m_maxHandles*2*sizeof(unsigned int)); + + m_hCellStart = new unsigned int[m_params.m_numCells]; + memset(m_hCellStart, 0x00, m_params.m_numCells * sizeof(unsigned int)); + + m_hPairBuffStartCurr = new unsigned int[m_maxHandles * 2 + 2]; + // --------------- for now, init with m_maxPairsPerBody for each body + m_hPairBuffStartCurr[0] = 0; + m_hPairBuffStartCurr[1] = 0; + for(int i = 1; i <= m_maxHandles; i++) + { + m_hPairBuffStartCurr[i * 2] = m_hPairBuffStartCurr[(i-1) * 2] + m_maxPairsPerBody; + m_hPairBuffStartCurr[i * 2 + 1] = 0; + } + //---------------- + unsigned int numAABB = m_maxHandles + m_maxLargeHandles; + m_hAABB = new bt3DGrid3F1U[numAABB * 2]; // AABB Min & Max + + m_hPairBuff = new unsigned int[m_maxHandles * m_maxPairsPerBody]; + memset(m_hPairBuff, 0x00, m_maxHandles * m_maxPairsPerBody * sizeof(unsigned int)); // needed? + + m_hPairScan = new unsigned int[m_maxHandles + 1]; + + m_hPairOut = new unsigned int[m_maxHandles * m_maxPairsPerBody]; + +// large proxies + + // allocate handles buffer and put all handles on free list + m_pLargeHandlesRawPtr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy) * m_maxLargeHandles, 16); + m_pLargeHandles = new(m_pLargeHandlesRawPtr) btSimpleBroadphaseProxy[m_maxLargeHandles]; + m_firstFreeLargeHandle = 0; + { + for (int i = m_firstFreeLargeHandle; i < m_maxLargeHandles; i++) + { + m_pLargeHandles[i].SetNextFree(i + 1); + m_pLargeHandles[i].m_uniqueId = m_maxHandles+2+i; + } + m_pLargeHandles[m_maxLargeHandles - 1].SetNextFree(0); + } + +// debug data + m_numPairsAdded = 0; + m_numOverflows = 0; + + m_bInitialized = true; +} + + + +void btGpu3DGridBroadphase::_finalize() +{ + btAssert(m_bInitialized); + delete [] m_hBodiesHash; + delete [] m_hCellStart; + delete [] m_hPairBuffStartCurr; + delete [] m_hAABB; + delete [] m_hPairBuff; + delete [] m_hPairScan; + delete [] m_hPairOut; + btAlignedFree(m_pLargeHandlesRawPtr); + m_bInitialized = false; +} + + + +void btGpu3DGridBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +{ + if(m_numHandles <= 0) + { + BT_PROFILE("addLarge2LargePairsToCache"); + addLarge2LargePairsToCache(dispatcher); + return; + } + // update constants + setParameters(&m_params); + // prepare AABB array + prepareAABB(); + // calculate hash + calcHashAABB(); + // sort bodies based on hash + sortHash(); + // find start of each cell + findCellStart(); + // findOverlappingPairs (small/small) + findOverlappingPairs(); + // findOverlappingPairs (small/large) + findPairsLarge(); + // add pairs to CPU cache + computePairCacheChanges(); + scanOverlappingPairBuff(); + squeezeOverlappingPairBuff(); + addPairsToCache(dispatcher); + // find and add large/large pairs to CPU cache + addLarge2LargePairsToCache(dispatcher); + return; +} + + + +void btGpu3DGridBroadphase::addPairsToCache(btDispatcher* dispatcher) +{ + m_numPairsAdded = 0; + m_numPairsRemoved = 0; + for(int i = 0; i < m_numHandles; i++) + { + unsigned int num = m_hPairScan[i+1] - m_hPairScan[i]; + if(!num) + { + continue; + } + unsigned int* pInp = m_hPairOut + m_hPairScan[i]; + unsigned int index0 = m_hAABB[i * 2].uw; + btSimpleBroadphaseProxy* proxy0 = &m_pHandles[index0]; + for(unsigned int j = 0; j < num; j++) + { + unsigned int indx1_s = pInp[j]; + unsigned int index1 = indx1_s & (~BT_3DGRID_PAIR_ANY_FLG); + btSimpleBroadphaseProxy* proxy1; + if(index1 < (unsigned int)m_maxHandles) + { + proxy1 = &m_pHandles[index1]; + } + else + { + index1 -= m_maxHandles; + btAssert((index1 >= 0) && (index1 < (unsigned int)m_maxLargeHandles)); + proxy1 = &m_pLargeHandles[index1]; + } + if(indx1_s & BT_3DGRID_PAIR_NEW_FLG) + { + m_pairCache->addOverlappingPair(proxy0,proxy1); + m_numPairsAdded++; + } + else + { + m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher); + m_numPairsRemoved++; + } + } + } +} + + + +btBroadphaseProxy* btGpu3DGridBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) +{ + btBroadphaseProxy* proxy; + bool bIsLarge = isLargeProxy(aabbMin, aabbMax); + if(bIsLarge) + { + if (m_numLargeHandles >= m_maxLargeHandles) + { + ///you have to increase the cell size, so 'large' proxies become 'small' proxies (fitting a cell) + btAssert(0); + return 0; //should never happen, but don't let the game crash ;-) + } + btAssert((aabbMin[0]<= aabbMax[0]) && (aabbMin[1]<= aabbMax[1]) && (aabbMin[2]<= aabbMax[2])); + int newHandleIndex = allocLargeHandle(); + proxy = new (&m_pLargeHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy); + } + else + { + proxy = btSimpleBroadphase::createProxy(aabbMin, aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask, dispatcher, multiSapProxy); + } + return proxy; +} + + + +void btGpu3DGridBroadphase::destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher) +{ + bool bIsLarge = isLargeProxy(proxy); + if(bIsLarge) + { + + btSimpleBroadphaseProxy* proxy0 = static_cast(proxy); + freeLargeHandle(proxy0); + m_pairCache->removeOverlappingPairsContainingProxy(proxy,dispatcher); + } + else + { + btSimpleBroadphase::destroyProxy(proxy, dispatcher); + } + return; +} + + + +void btGpu3DGridBroadphase::resetPool(btDispatcher* dispatcher) +{ + m_hPairBuffStartCurr[0] = 0; + m_hPairBuffStartCurr[1] = 0; + for(int i = 1; i <= m_maxHandles; i++) + { + m_hPairBuffStartCurr[i * 2] = m_hPairBuffStartCurr[(i-1) * 2] + m_maxPairsPerBody; + m_hPairBuffStartCurr[i * 2 + 1] = 0; + } +} + + + +bool btGpu3DGridBroadphase::isLargeProxy(const btVector3& aabbMin, const btVector3& aabbMax) +{ + btVector3 diag = aabbMax - aabbMin; + + ///use the bounding sphere radius of this bounding box, to include rotation + btScalar radius = diag.length() * btScalar(0.5f); + radius *= m_cellFactorAABB; // user-defined factor + + return (radius > m_maxRadius); +} + + + +bool btGpu3DGridBroadphase::isLargeProxy(btBroadphaseProxy* proxy) +{ + return (proxy->getUid() >= (m_maxHandles+2)); +} + + + +void btGpu3DGridBroadphase::addLarge2LargePairsToCache(btDispatcher* dispatcher) +{ + int i,j; + if (m_numLargeHandles <= 0) + { + return; + } + int new_largest_index = -1; + for(i = 0; i <= m_LastLargeHandleIndex; i++) + { + btSimpleBroadphaseProxy* proxy0 = &m_pLargeHandles[i]; + if(!proxy0->m_clientObject) + { + continue; + } + new_largest_index = i; + for(j = i + 1; j <= m_LastLargeHandleIndex; j++) + { + btSimpleBroadphaseProxy* proxy1 = &m_pLargeHandles[j]; + if(!proxy1->m_clientObject) + { + continue; + } + btAssert(proxy0 != proxy1); + btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); + btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); + if(aabbOverlap(p0,p1)) + { + if (!m_pairCache->findPair(proxy0,proxy1)) + { + m_pairCache->addOverlappingPair(proxy0,proxy1); + } + } + else + { + if(m_pairCache->findPair(proxy0,proxy1)) + { + m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher); + } + } + } + } + m_LastLargeHandleIndex = new_largest_index; + return; +} + + + +void btGpu3DGridBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) +{ + btSimpleBroadphase::rayTest(rayFrom, rayTo, rayCallback); + for (int i=0; i <= m_LastLargeHandleIndex; i++) + { + btSimpleBroadphaseProxy* proxy = &m_pLargeHandles[i]; + if(!proxy->m_clientObject) + { + continue; + } + rayCallback.process(proxy); + } +} + + + +// +// overrides for CPU version +// + + + +void btGpu3DGridBroadphase::prepareAABB() +{ + BT_PROFILE("prepareAABB"); + bt3DGrid3F1U* pBB = m_hAABB; + int i; + int new_largest_index = -1; + unsigned int num_small = 0; + for(i = 0; i <= m_LastHandleIndex; i++) + { + btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i]; + if(!proxy0->m_clientObject) + { + continue; + } + new_largest_index = i; + pBB->fx = proxy0->m_aabbMin.getX(); + pBB->fy = proxy0->m_aabbMin.getY(); + pBB->fz = proxy0->m_aabbMin.getZ(); + pBB->uw = i; + pBB++; + pBB->fx = proxy0->m_aabbMax.getX(); + pBB->fy = proxy0->m_aabbMax.getY(); + pBB->fz = proxy0->m_aabbMax.getZ(); + pBB->uw = num_small; + pBB++; + num_small++; + } + m_LastHandleIndex = new_largest_index; + new_largest_index = -1; + unsigned int num_large = 0; + for(i = 0; i <= m_LastLargeHandleIndex; i++) + { + btSimpleBroadphaseProxy* proxy0 = &m_pLargeHandles[i]; + if(!proxy0->m_clientObject) + { + continue; + } + new_largest_index = i; + pBB->fx = proxy0->m_aabbMin.getX(); + pBB->fy = proxy0->m_aabbMin.getY(); + pBB->fz = proxy0->m_aabbMin.getZ(); + pBB->uw = i + m_maxHandles; + pBB++; + pBB->fx = proxy0->m_aabbMax.getX(); + pBB->fy = proxy0->m_aabbMax.getY(); + pBB->fz = proxy0->m_aabbMax.getZ(); + pBB->uw = num_large + m_maxHandles; + pBB++; + num_large++; + } + m_LastLargeHandleIndex = new_largest_index; + // paranoid checks + btAssert(num_small == m_numHandles); + btAssert(num_large == m_numLargeHandles); + return; +} + + + +void btGpu3DGridBroadphase::setParameters(bt3DGridBroadphaseParams* hostParams) +{ + s3DGridBroadphaseParams = *hostParams; + return; +} + + + +void btGpu3DGridBroadphase::calcHashAABB() +{ + BT_PROFILE("bt3DGrid_calcHashAABB"); + btGpu_calcHashAABB(m_hAABB, m_hBodiesHash, m_numHandles); + return; +} + + + +void btGpu3DGridBroadphase::sortHash() +{ + class bt3DGridHashKey + { + public: + unsigned int hash; + unsigned int index; + void quickSort(bt3DGridHashKey* pData, int lo, int hi) + { + int i=lo, j=hi; + bt3DGridHashKey x = pData[(lo+hi)/2]; + do + { + while(pData[i].hash > x.hash) i++; + while(x.hash > pData[j].hash) j--; + if(i <= j) + { + bt3DGridHashKey t = pData[i]; + pData[i] = pData[j]; + pData[j] = t; + i++; j--; + } + } while(i <= j); + if(lo < j) pData->quickSort(pData, lo, j); + if(i < hi) pData->quickSort(pData, i, hi); + } + }; + BT_PROFILE("bt3DGrid_sortHash"); + bt3DGridHashKey* pHash = (bt3DGridHashKey*)m_hBodiesHash; + pHash->quickSort(pHash, 0, m_numHandles - 1); + return; +} + + + +void btGpu3DGridBroadphase::findCellStart() +{ + BT_PROFILE("bt3DGrid_findCellStart"); + btGpu_findCellStart(m_hBodiesHash, m_hCellStart, m_numHandles, m_params.m_numCells); + return; +} + + + +void btGpu3DGridBroadphase::findOverlappingPairs() +{ + BT_PROFILE("bt3DGrid_findOverlappingPairs"); + btGpu_findOverlappingPairs(m_hAABB, m_hBodiesHash, m_hCellStart, m_hPairBuff, m_hPairBuffStartCurr, m_numHandles); + return; +} + + + +void btGpu3DGridBroadphase::findPairsLarge() +{ + BT_PROFILE("bt3DGrid_findPairsLarge"); + btGpu_findPairsLarge(m_hAABB, m_hBodiesHash, m_hCellStart, m_hPairBuff, m_hPairBuffStartCurr, m_numHandles, m_numLargeHandles); + return; +} + + + +void btGpu3DGridBroadphase::computePairCacheChanges() +{ + BT_PROFILE("bt3DGrid_computePairCacheChanges"); + btGpu_computePairCacheChanges(m_hPairBuff, m_hPairBuffStartCurr, m_hPairScan, m_hAABB, m_numHandles); + return; +} + + + +void btGpu3DGridBroadphase::scanOverlappingPairBuff() +{ + BT_PROFILE("bt3DGrid_scanOverlappingPairBuff"); + m_hPairScan[0] = 0; + for(int i = 1; i <= m_numHandles; i++) + { + unsigned int delta = m_hPairScan[i]; + m_hPairScan[i] = m_hPairScan[i-1] + delta; + } + return; +} + + + +void btGpu3DGridBroadphase::squeezeOverlappingPairBuff() +{ + BT_PROFILE("bt3DGrid_squeezeOverlappingPairBuff"); + btGpu_squeezeOverlappingPairBuff(m_hPairBuff, m_hPairBuffStartCurr, m_hPairScan, m_hPairOut, m_hAABB, m_numHandles); + return; +} + + + +#include "btGpu3DGridBroadphaseSharedCode.h" + + diff --git a/src/BulletMultiThreaded/btGpu3DGridBroadphase.h b/src/BulletMultiThreaded/btGpu3DGridBroadphase.h new file mode 100644 index 0000000..1154a5f --- /dev/null +++ b/src/BulletMultiThreaded/btGpu3DGridBroadphase.h @@ -0,0 +1,140 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------------------------------------------------------------------------------------- + +#ifndef BTGPU3DGRIDBROADPHASE_H +#define BTGPU3DGRIDBROADPHASE_H + +//---------------------------------------------------------------------------------------- + +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" + +#include "btGpu3DGridBroadphaseSharedTypes.h" + +//---------------------------------------------------------------------------------------- + +///The btGpu3DGridBroadphase uses GPU-style code compiled for CPU to compute overlapping pairs + +class btGpu3DGridBroadphase : public btSimpleBroadphase +{ +protected: + bool m_bInitialized; + unsigned int m_numBodies; + unsigned int m_numCells; + unsigned int m_maxPairsPerBody; + btScalar m_cellFactorAABB; + unsigned int m_maxBodiesPerCell; + bt3DGridBroadphaseParams m_params; + btScalar m_maxRadius; + // CPU data + unsigned int* m_hBodiesHash; + unsigned int* m_hCellStart; + unsigned int* m_hPairBuffStartCurr; + bt3DGrid3F1U* m_hAABB; + unsigned int* m_hPairBuff; + unsigned int* m_hPairScan; + unsigned int* m_hPairOut; +// large proxies + int m_numLargeHandles; + int m_maxLargeHandles; + int m_LastLargeHandleIndex; + btSimpleBroadphaseProxy* m_pLargeHandles; + void* m_pLargeHandlesRawPtr; + int m_firstFreeLargeHandle; + int allocLargeHandle() + { + btAssert(m_numLargeHandles < m_maxLargeHandles); + int freeLargeHandle = m_firstFreeLargeHandle; + m_firstFreeLargeHandle = m_pLargeHandles[freeLargeHandle].GetNextFree(); + m_numLargeHandles++; + if(freeLargeHandle > m_LastLargeHandleIndex) + { + m_LastLargeHandleIndex = freeLargeHandle; + } + return freeLargeHandle; + } + void freeLargeHandle(btSimpleBroadphaseProxy* proxy) + { + int handle = int(proxy - m_pLargeHandles); + btAssert((handle >= 0) && (handle < m_maxHandles)); + if(handle == m_LastLargeHandleIndex) + { + m_LastLargeHandleIndex--; + } + proxy->SetNextFree(m_firstFreeLargeHandle); + m_firstFreeLargeHandle = handle; + proxy->m_clientObject = 0; + m_numLargeHandles--; + } + bool isLargeProxy(const btVector3& aabbMin, const btVector3& aabbMax); + bool isLargeProxy(btBroadphaseProxy* proxy); +// debug + unsigned int m_numPairsAdded; + unsigned int m_numPairsRemoved; + unsigned int m_numOverflows; +// +public: + btGpu3DGridBroadphase(const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, + int maxBodiesPerCell = 8, + btScalar cellFactorAABB = btScalar(1.0f)); + btGpu3DGridBroadphase( btOverlappingPairCache* overlappingPairCache, + const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, + int maxBodiesPerCell = 8, + btScalar cellFactorAABB = btScalar(1.0f)); + virtual ~btGpu3DGridBroadphase(); + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + + virtual btBroadphaseProxy* createProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy); + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0)); + + + virtual void resetPool(btDispatcher* dispatcher); + +protected: + void _initialize( const btVector3& worldAabbMin,const btVector3& worldAabbMax, + int gridSizeX, int gridSizeY, int gridSizeZ, + int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, + int maxBodiesPerCell = 8, + btScalar cellFactorAABB = btScalar(1.0f)); + void _finalize(); + void addPairsToCache(btDispatcher* dispatcher); + void addLarge2LargePairsToCache(btDispatcher* dispatcher); + +// overrides for CPU version + virtual void setParameters(bt3DGridBroadphaseParams* hostParams); + virtual void prepareAABB(); + virtual void calcHashAABB(); + virtual void sortHash(); + virtual void findCellStart(); + virtual void findOverlappingPairs(); + virtual void findPairsLarge(); + virtual void computePairCacheChanges(); + virtual void scanOverlappingPairBuff(); + virtual void squeezeOverlappingPairBuff(); +}; + +//---------------------------------------------------------------------------------------- + +#endif //BTGPU3DGRIDBROADPHASE_H + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- diff --git a/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedCode.h b/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedCode.h new file mode 100644 index 0000000..e0afb87 --- /dev/null +++ b/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedCode.h @@ -0,0 +1,430 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +// K E R N E L F U N C T I O N S +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + +// calculate position in uniform grid +BT_GPU___device__ int3 bt3DGrid_calcGridPos(float4 p) +{ + int3 gridPos; + gridPos.x = (int)floor((p.x - BT_GPU_params.m_worldOriginX) / BT_GPU_params.m_cellSizeX); + gridPos.y = (int)floor((p.y - BT_GPU_params.m_worldOriginY) / BT_GPU_params.m_cellSizeY); + gridPos.z = (int)floor((p.z - BT_GPU_params.m_worldOriginZ) / BT_GPU_params.m_cellSizeZ); + return gridPos; +} // bt3DGrid_calcGridPos() + +//---------------------------------------------------------------------------------------- + +// calculate address in grid from position (clamping to edges) +BT_GPU___device__ uint bt3DGrid_calcGridHash(int3 gridPos) +{ + gridPos.x = BT_GPU_max(0, BT_GPU_min(gridPos.x, (int)BT_GPU_params.m_gridSizeX - 1)); + gridPos.y = BT_GPU_max(0, BT_GPU_min(gridPos.y, (int)BT_GPU_params.m_gridSizeY - 1)); + gridPos.z = BT_GPU_max(0, BT_GPU_min(gridPos.z, (int)BT_GPU_params.m_gridSizeZ - 1)); + return BT_GPU___mul24(BT_GPU___mul24(gridPos.z, BT_GPU_params.m_gridSizeY), BT_GPU_params.m_gridSizeX) + BT_GPU___mul24(gridPos.y, BT_GPU_params.m_gridSizeX) + gridPos.x; +} // bt3DGrid_calcGridHash() + +//---------------------------------------------------------------------------------------- + +// calculate grid hash value for each body using its AABB +BT_GPU___global__ void calcHashAABBD(bt3DGrid3F1U* pAABB, uint2* pHash, uint numBodies) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + bt3DGrid3F1U bbMin = pAABB[index*2]; + bt3DGrid3F1U bbMax = pAABB[index*2 + 1]; + float4 pos; + pos.x = (bbMin.fx + bbMax.fx) * 0.5f; + pos.y = (bbMin.fy + bbMax.fy) * 0.5f; + pos.z = (bbMin.fz + bbMax.fz) * 0.5f; + // get address in grid + int3 gridPos = bt3DGrid_calcGridPos(pos); + uint gridHash = bt3DGrid_calcGridHash(gridPos); + // store grid hash and body index + pHash[index] = BT_GPU_make_uint2(gridHash, index); +} // calcHashAABBD() + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void findCellStartD(uint2* pHash, uint* cellStart, uint numBodies) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + uint2 sortedData = pHash[index]; + // Load hash data into shared memory so that we can look + // at neighboring body's hash value without loading + // two hash values per thread + BT_GPU___shared__ uint sharedHash[257]; + sharedHash[BT_GPU_threadIdx.x+1] = sortedData.x; + if((index > 0) && (BT_GPU_threadIdx.x == 0)) + { + // first thread in block must load neighbor body hash + volatile uint2 prevData = pHash[index-1]; + sharedHash[0] = prevData.x; + } + BT_GPU___syncthreads(); + if((index == 0) || (sortedData.x != sharedHash[BT_GPU_threadIdx.x])) + { + cellStart[sortedData.x] = index; + } +} // findCellStartD() + +//---------------------------------------------------------------------------------------- + +BT_GPU___device__ uint cudaTestAABBOverlap(bt3DGrid3F1U min0, bt3DGrid3F1U max0, bt3DGrid3F1U min1, bt3DGrid3F1U max1) +{ + return (min0.fx <= max1.fx)&& (min1.fx <= max0.fx) && + (min0.fy <= max1.fy)&& (min1.fy <= max0.fy) && + (min0.fz <= max1.fz)&& (min1.fz <= max0.fz); +} // cudaTestAABBOverlap() + +//---------------------------------------------------------------------------------------- + +BT_GPU___device__ void findPairsInCell( int3 gridPos, + uint index, + uint2* pHash, + uint* pCellStart, + bt3DGrid3F1U* pAABB, + uint* pPairBuff, + uint2* pPairBuffStartCurr, + uint numBodies) +{ + if ( (gridPos.x < 0) || (gridPos.x > (int)BT_GPU_params.m_gridSizeX - 1) + || (gridPos.y < 0) || (gridPos.y > (int)BT_GPU_params.m_gridSizeY - 1) + || (gridPos.z < 0) || (gridPos.z > (int)BT_GPU_params.m_gridSizeZ - 1)) + { + return; + } + uint gridHash = bt3DGrid_calcGridHash(gridPos); + // get start of bucket for this cell + uint bucketStart = pCellStart[gridHash]; + if (bucketStart == 0xffffffff) + { + return; // cell empty + } + // iterate over bodies in this cell + uint2 sortedData = pHash[index]; + uint unsorted_indx = sortedData.y; + bt3DGrid3F1U min0 = BT_GPU_FETCH(pAABB, unsorted_indx*2); + bt3DGrid3F1U max0 = BT_GPU_FETCH(pAABB, unsorted_indx*2 + 1); + uint handleIndex = min0.uw; + uint2 start_curr = pPairBuffStartCurr[handleIndex]; + uint start = start_curr.x; + uint curr = start_curr.y; + uint2 start_curr_next = pPairBuffStartCurr[handleIndex+1]; + uint curr_max = start_curr_next.x - start - 1; + uint bucketEnd = bucketStart + BT_GPU_params.m_maxBodiesPerCell; + bucketEnd = (bucketEnd > numBodies) ? numBodies : bucketEnd; + for(uint index2 = bucketStart; index2 < bucketEnd; index2++) + { + uint2 cellData = pHash[index2]; + if (cellData.x != gridHash) + { + break; // no longer in same bucket + } + uint unsorted_indx2 = cellData.y; + if (unsorted_indx2 < unsorted_indx) // check not colliding with self + { + bt3DGrid3F1U min1 = BT_GPU_FETCH(pAABB, unsorted_indx2*2); + bt3DGrid3F1U max1 = BT_GPU_FETCH(pAABB, unsorted_indx2*2 + 1); + if(cudaTestAABBOverlap(min0, max0, min1, max1)) + { + uint handleIndex2 = min1.uw; + uint k; + for(k = 0; k < curr; k++) + { + uint old_pair = pPairBuff[start+k] & (~BT_3DGRID_PAIR_ANY_FLG); + if(old_pair == handleIndex2) + { + pPairBuff[start+k] |= BT_3DGRID_PAIR_FOUND_FLG; + break; + } + } + if(k == curr) + { + if(curr >= curr_max) + { // not a good solution, but let's avoid crash + break; + } + pPairBuff[start+curr] = handleIndex2 | BT_3DGRID_PAIR_NEW_FLG; + curr++; + } + } + } + } + pPairBuffStartCurr[handleIndex] = BT_GPU_make_uint2(start, curr); + return; +} // findPairsInCell() + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void findOverlappingPairsD( bt3DGrid3F1U* pAABB, uint2* pHash, uint* pCellStart, + uint* pPairBuff, uint2* pPairBuffStartCurr, uint numBodies) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + uint2 sortedData = pHash[index]; + uint unsorted_indx = sortedData.y; + bt3DGrid3F1U bbMin = BT_GPU_FETCH(pAABB, unsorted_indx*2); + bt3DGrid3F1U bbMax = BT_GPU_FETCH(pAABB, unsorted_indx*2 + 1); + float4 pos; + pos.x = (bbMin.fx + bbMax.fx) * 0.5f; + pos.y = (bbMin.fy + bbMax.fy) * 0.5f; + pos.z = (bbMin.fz + bbMax.fz) * 0.5f; + // get address in grid + int3 gridPos = bt3DGrid_calcGridPos(pos); + // examine only neighbouring cells + for(int z=-1; z<=1; z++) { + for(int y=-1; y<=1; y++) { + for(int x=-1; x<=1; x++) { + findPairsInCell(gridPos + BT_GPU_make_int3(x, y, z), index, pHash, pCellStart, pAABB, pPairBuff, pPairBuffStartCurr, numBodies); + } + } + } +} // findOverlappingPairsD() + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void findPairsLargeD( bt3DGrid3F1U* pAABB, uint2* pHash, uint* pCellStart, uint* pPairBuff, + uint2* pPairBuffStartCurr, uint numBodies, uint numLarge) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + uint2 sortedData = pHash[index]; + uint unsorted_indx = sortedData.y; + bt3DGrid3F1U min0 = BT_GPU_FETCH(pAABB, unsorted_indx*2); + bt3DGrid3F1U max0 = BT_GPU_FETCH(pAABB, unsorted_indx*2 + 1); + uint handleIndex = min0.uw; + uint2 start_curr = pPairBuffStartCurr[handleIndex]; + uint start = start_curr.x; + uint curr = start_curr.y; + uint2 start_curr_next = pPairBuffStartCurr[handleIndex+1]; + uint curr_max = start_curr_next.x - start - 1; + for(uint i = 0; i < numLarge; i++) + { + uint indx2 = numBodies + i; + bt3DGrid3F1U min1 = BT_GPU_FETCH(pAABB, indx2*2); + bt3DGrid3F1U max1 = BT_GPU_FETCH(pAABB, indx2*2 + 1); + if(cudaTestAABBOverlap(min0, max0, min1, max1)) + { + uint k; + uint handleIndex2 = min1.uw; + for(k = 0; k < curr; k++) + { + uint old_pair = pPairBuff[start+k] & (~BT_3DGRID_PAIR_ANY_FLG); + if(old_pair == handleIndex2) + { + pPairBuff[start+k] |= BT_3DGRID_PAIR_FOUND_FLG; + break; + } + } + if(k == curr) + { + pPairBuff[start+curr] = handleIndex2 | BT_3DGRID_PAIR_NEW_FLG; + if(curr >= curr_max) + { // not a good solution, but let's avoid crash + break; + } + curr++; + } + } + } + pPairBuffStartCurr[handleIndex] = BT_GPU_make_uint2(start, curr); + return; +} // findPairsLargeD() + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void computePairCacheChangesD(uint* pPairBuff, uint2* pPairBuffStartCurr, + uint* pPairScan, bt3DGrid3F1U* pAABB, uint numBodies) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + bt3DGrid3F1U bbMin = pAABB[index * 2]; + uint handleIndex = bbMin.uw; + uint2 start_curr = pPairBuffStartCurr[handleIndex]; + uint start = start_curr.x; + uint curr = start_curr.y; + uint *pInp = pPairBuff + start; + uint num_changes = 0; + for(uint k = 0; k < curr; k++, pInp++) + { + if(!((*pInp) & BT_3DGRID_PAIR_FOUND_FLG)) + { + num_changes++; + } + } + pPairScan[index+1] = num_changes; +} // computePairCacheChangesD() + +//---------------------------------------------------------------------------------------- + +BT_GPU___global__ void squeezeOverlappingPairBuffD(uint* pPairBuff, uint2* pPairBuffStartCurr, uint* pPairScan, + uint* pPairOut, bt3DGrid3F1U* pAABB, uint numBodies) +{ + int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x; + if(index >= (int)numBodies) + { + return; + } + bt3DGrid3F1U bbMin = pAABB[index * 2]; + uint handleIndex = bbMin.uw; + uint2 start_curr = pPairBuffStartCurr[handleIndex]; + uint start = start_curr.x; + uint curr = start_curr.y; + uint* pInp = pPairBuff + start; + uint* pOut = pPairOut + pPairScan[index]; + uint* pOut2 = pInp; + uint num = 0; + for(uint k = 0; k < curr; k++, pInp++) + { + if(!((*pInp) & BT_3DGRID_PAIR_FOUND_FLG)) + { + *pOut = *pInp; + pOut++; + } + if((*pInp) & BT_3DGRID_PAIR_ANY_FLG) + { + *pOut2 = (*pInp) & (~BT_3DGRID_PAIR_ANY_FLG); + pOut2++; + num++; + } + } + pPairBuffStartCurr[handleIndex] = BT_GPU_make_uint2(start, num); +} // squeezeOverlappingPairBuffD() + + +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +// E N D O F K E R N E L F U N C T I O N S +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- + +extern "C" +{ + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(calcHashAABB)(bt3DGrid3F1U* pAABB, unsigned int* hash, unsigned int numBodies) +{ + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads); + // execute the kernel + BT_GPU_EXECKERNEL(numBlocks, numThreads, calcHashAABBD, (pAABB, (uint2*)hash, numBodies)); + // check if kernel invocation generated an error + BT_GPU_CHECK_ERROR("calcHashAABBD kernel execution failed"); +} // calcHashAABB() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(findCellStart(unsigned int* hash, unsigned int* cellStart, unsigned int numBodies, unsigned int numCells)) +{ + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads); + BT_GPU_SAFE_CALL(BT_GPU_Memset(cellStart, 0xffffffff, numCells*sizeof(uint))); + BT_GPU_EXECKERNEL(numBlocks, numThreads, findCellStartD, ((uint2*)hash, (uint*)cellStart, numBodies)); + BT_GPU_CHECK_ERROR("Kernel execution failed: findCellStartD"); +} // findCellStart() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(findOverlappingPairs(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies)) +{ +#if B_CUDA_USE_TEX + BT_GPU_SAFE_CALL(cudaBindTexture(0, pAABBTex, pAABB, numBodies * 2 * sizeof(bt3DGrid3F1U))); +#endif + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 64, numBlocks, numThreads); + BT_GPU_EXECKERNEL(numBlocks, numThreads, findOverlappingPairsD, (pAABB,(uint2*)pHash,(uint*)pCellStart,(uint*)pPairBuff,(uint2*)pPairBuffStartCurr,numBodies)); + BT_GPU_CHECK_ERROR("Kernel execution failed: bt_CudaFindOverlappingPairsD"); +#if B_CUDA_USE_TEX + BT_GPU_SAFE_CALL(cudaUnbindTexture(pAABBTex)); +#endif +} // findOverlappingPairs() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(findPairsLarge(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies, unsigned int numLarge)) +{ +#if B_CUDA_USE_TEX + BT_GPU_SAFE_CALL(cudaBindTexture(0, pAABBTex, pAABB, (numBodies+numLarge) * 2 * sizeof(bt3DGrid3F1U))); +#endif + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 64, numBlocks, numThreads); + BT_GPU_EXECKERNEL(numBlocks, numThreads, findPairsLargeD, (pAABB,(uint2*)pHash,(uint*)pCellStart,(uint*)pPairBuff,(uint2*)pPairBuffStartCurr,numBodies,numLarge)); + BT_GPU_CHECK_ERROR("Kernel execution failed: btCuda_findPairsLargeD"); +#if B_CUDA_USE_TEX + BT_GPU_SAFE_CALL(cudaUnbindTexture(pAABBTex)); +#endif +} // findPairsLarge() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(computePairCacheChanges(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, bt3DGrid3F1U* pAABB, unsigned int numBodies)) +{ + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads); + BT_GPU_EXECKERNEL(numBlocks, numThreads, computePairCacheChangesD, ((uint*)pPairBuff,(uint2*)pPairBuffStartCurr,(uint*)pPairScan,pAABB,numBodies)); + BT_GPU_CHECK_ERROR("Kernel execution failed: btCudaComputePairCacheChangesD"); +} // computePairCacheChanges() + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(squeezeOverlappingPairBuff(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, unsigned int* pPairOut, bt3DGrid3F1U* pAABB, unsigned int numBodies)) +{ + int numThreads, numBlocks; + BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads); + BT_GPU_EXECKERNEL(numBlocks, numThreads, squeezeOverlappingPairBuffD, ((uint*)pPairBuff,(uint2*)pPairBuffStartCurr,(uint*)pPairScan,(uint*)pPairOut,pAABB,numBodies)); + BT_GPU_CHECK_ERROR("Kernel execution failed: btCudaSqueezeOverlappingPairBuffD"); +} // btCuda_squeezeOverlappingPairBuff() + +//------------------------------------------------------------------------------------------------ + +} // extern "C" + +//------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------ diff --git a/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedDefs.h b/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedDefs.h new file mode 100644 index 0000000..607bda7 --- /dev/null +++ b/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedDefs.h @@ -0,0 +1,61 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------------------------------------------------------------------------------------- + +// Shared definitions for GPU-based 3D Grid collision detection broadphase + +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// Keep this file free from Bullet headers +// it is included into both CUDA and CPU code +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +//---------------------------------------------------------------------------------------- + +#ifndef BTGPU3DGRIDBROADPHASESHAREDDEFS_H +#define BTGPU3DGRIDBROADPHASESHAREDDEFS_H + +//---------------------------------------------------------------------------------------- + +#include "btGpu3DGridBroadphaseSharedTypes.h" + +//---------------------------------------------------------------------------------------- + +extern "C" +{ + +//---------------------------------------------------------------------------------------- + +void BT_GPU_PREF(calcHashAABB)(bt3DGrid3F1U* pAABB, unsigned int* hash, unsigned int numBodies); + +void BT_GPU_PREF(findCellStart)(unsigned int* hash, unsigned int* cellStart, unsigned int numBodies, unsigned int numCells); + +void BT_GPU_PREF(findOverlappingPairs)(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies); + +void BT_GPU_PREF(findPairsLarge)(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies, unsigned int numLarge); + +void BT_GPU_PREF(computePairCacheChanges)(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, bt3DGrid3F1U* pAABB, unsigned int numBodies); + +void BT_GPU_PREF(squeezeOverlappingPairBuff)(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, unsigned int* pPairOut, bt3DGrid3F1U* pAABB, unsigned int numBodies); + + +//---------------------------------------------------------------------------------------- + +} // extern "C" + +//---------------------------------------------------------------------------------------- + +#endif // BTGPU3DGRIDBROADPHASESHAREDDEFS_H + diff --git a/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedTypes.h b/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedTypes.h new file mode 100644 index 0000000..616a400 --- /dev/null +++ b/src/BulletMultiThreaded/btGpu3DGridBroadphaseSharedTypes.h @@ -0,0 +1,67 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//---------------------------------------------------------------------------------------- + +// Shared definitions for GPU-based 3D Grid collision detection broadphase + +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// Keep this file free from Bullet headers +// it is included into both CUDA and CPU code +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +//---------------------------------------------------------------------------------------- + +#ifndef BTGPU3DGRIDBROADPHASESHAREDTYPES_H +#define BTGPU3DGRIDBROADPHASESHAREDTYPES_H + +//---------------------------------------------------------------------------------------- + +#define BT_3DGRID_PAIR_FOUND_FLG (0x40000000) +#define BT_3DGRID_PAIR_NEW_FLG (0x20000000) +#define BT_3DGRID_PAIR_ANY_FLG (BT_3DGRID_PAIR_FOUND_FLG | BT_3DGRID_PAIR_NEW_FLG) + +//---------------------------------------------------------------------------------------- + +struct bt3DGridBroadphaseParams +{ + unsigned int m_gridSizeX; + unsigned int m_gridSizeY; + unsigned int m_gridSizeZ; + unsigned int m_numCells; + float m_worldOriginX; + float m_worldOriginY; + float m_worldOriginZ; + float m_cellSizeX; + float m_cellSizeY; + float m_cellSizeZ; + unsigned int m_numBodies; + unsigned int m_maxBodiesPerCell; +}; + +//---------------------------------------------------------------------------------------- + +struct bt3DGrid3F1U +{ + float fx; + float fy; + float fz; + unsigned int uw; +}; + +//---------------------------------------------------------------------------------------- + +#endif // BTGPU3DGRIDBROADPHASESHAREDTYPES_H + diff --git a/src/BulletMultiThreaded/btGpuDefines.h b/src/BulletMultiThreaded/btGpuDefines.h new file mode 100644 index 0000000..f9315ab --- /dev/null +++ b/src/BulletMultiThreaded/btGpuDefines.h @@ -0,0 +1,211 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006, 2009 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +// definitions for "GPU on CPU" code + + +#ifndef BT_GPU_DEFINES_H +#define BT_GPU_DEFINES_H + +typedef unsigned int uint; + +struct int2 +{ + int x, y; +}; + +struct uint2 +{ + unsigned int x, y; +}; + +struct int3 +{ + int x, y, z; +}; + +struct uint3 +{ + unsigned int x, y, z; +}; + +struct float4 +{ + float x, y, z, w; +}; + +struct float3 +{ + float x, y, z; +}; + + +#define BT_GPU___device__ inline +#define BT_GPU___devdata__ +#define BT_GPU___constant__ +#define BT_GPU_max(a, b) ((a) > (b) ? (a) : (b)) +#define BT_GPU_min(a, b) ((a) < (b) ? (a) : (b)) +#define BT_GPU_params s3DGridBroadphaseParams +#define BT_GPU___mul24(a, b) ((a)*(b)) +#define BT_GPU___global__ inline +#define BT_GPU___shared__ static +#define BT_GPU___syncthreads() +#define CUDART_PI_F SIMD_PI + +static inline uint2 bt3dGrid_make_uint2(unsigned int x, unsigned int y) +{ + uint2 t; t.x = x; t.y = y; return t; +} +#define BT_GPU_make_uint2(x, y) bt3dGrid_make_uint2(x, y) + +static inline int3 bt3dGrid_make_int3(int x, int y, int z) +{ + int3 t; t.x = x; t.y = y; t.z = z; return t; +} +#define BT_GPU_make_int3(x, y, z) bt3dGrid_make_int3(x, y, z) + +static inline float3 bt3dGrid_make_float3(float x, float y, float z) +{ + float3 t; t.x = x; t.y = y; t.z = z; return t; +} +#define BT_GPU_make_float3(x, y, z) bt3dGrid_make_float3(x, y, z) + +static inline float3 bt3dGrid_make_float34(float4 f) +{ + float3 t; t.x = f.x; t.y = f.y; t.z = f.z; return t; +} +#define BT_GPU_make_float34(f) bt3dGrid_make_float34(f) + +static inline float3 bt3dGrid_make_float31(float f) +{ + float3 t; t.x = t.y = t.z = f; return t; +} +#define BT_GPU_make_float31(x) bt3dGrid_make_float31(x) + +static inline float4 bt3dGrid_make_float42(float3 v, float f) +{ + float4 t; t.x = v.x; t.y = v.y; t.z = v.z; t.w = f; return t; +} +#define BT_GPU_make_float42(a, b) bt3dGrid_make_float42(a, b) + +static inline float4 bt3dGrid_make_float44(float a, float b, float c, float d) +{ + float4 t; t.x = a; t.y = b; t.z = c; t.w = d; return t; +} +#define BT_GPU_make_float44(a, b, c, d) bt3dGrid_make_float44(a, b, c, d) + +inline int3 operator+(int3 a, int3 b) +{ + return bt3dGrid_make_int3(a.x + b.x, a.y + b.y, a.z + b.z); +} + +inline float4 operator+(const float4& a, const float4& b) +{ + float4 r; r.x = a.x+b.x; r.y = a.y+b.y; r.z = a.z+b.z; r.w = a.w+b.w; return r; +} +inline float4 operator*(const float4& a, float fact) +{ + float4 r; r.x = a.x*fact; r.y = a.y*fact; r.z = a.z*fact; r.w = a.w*fact; return r; +} +inline float4 operator*(float fact, float4& a) +{ + return (a * fact); +} +inline float4& operator*=(float4& a, float fact) +{ + a = fact * a; + return a; +} +inline float4& operator+=(float4& a, const float4& b) +{ + a = a + b; + return a; +} + +inline float3 operator+(const float3& a, const float3& b) +{ + float3 r; r.x = a.x+b.x; r.y = a.y+b.y; r.z = a.z+b.z; return r; +} +inline float3 operator-(const float3& a, const float3& b) +{ + float3 r; r.x = a.x-b.x; r.y = a.y-b.y; r.z = a.z-b.z; return r; +} +static inline float bt3dGrid_dot(float3& a, float3& b) +{ + return a.x*b.x+a.y*b.y+a.z*b.z; +} +#define BT_GPU_dot(a,b) bt3dGrid_dot(a,b) + +static inline float bt3dGrid_dot4(float4& a, float4& b) +{ + return a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w; +} +#define BT_GPU_dot4(a,b) bt3dGrid_dot4(a,b) + +static inline float3 bt3dGrid_cross(const float3& a, const float3& b) +{ + float3 r; r.x = a.y*b.z-a.z*b.y; r.y = -a.x*b.z+a.z*b.x; r.z = a.x*b.y-a.y*b.x; return r; +} +#define BT_GPU_cross(a,b) bt3dGrid_cross(a,b) + + +inline float3 operator*(const float3& a, float fact) +{ + float3 r; r.x = a.x*fact; r.y = a.y*fact; r.z = a.z*fact; return r; +} + + +inline float3& operator+=(float3& a, const float3& b) +{ + a = a + b; + return a; +} +inline float3& operator-=(float3& a, const float3& b) +{ + a = a - b; + return a; +} +inline float3& operator*=(float3& a, float fact) +{ + a = a * fact; + return a; +} +inline float3 operator-(const float3& v) +{ + float3 r; r.x = -v.x; r.y = -v.y; r.z = -v.z; return r; +} + + +#define BT_GPU_FETCH(a, b) a[b] +#define BT_GPU_FETCH4(a, b) a[b] +#define BT_GPU_PREF(func) btGpu_##func +#define BT_GPU_SAFE_CALL(func) func +#define BT_GPU_Memset memset +#define BT_GPU_MemcpyToSymbol(a, b, c) memcpy(&a, b, c) +#define BT_GPU_BindTexture(a, b, c, d) +#define BT_GPU_UnbindTexture(a) + +static uint2 s_blockIdx, s_blockDim, s_threadIdx; +#define BT_GPU_blockIdx s_blockIdx +#define BT_GPU_blockDim s_blockDim +#define BT_GPU_threadIdx s_threadIdx +#define BT_GPU_EXECKERNEL(numb, numt, kfunc, args) {s_blockDim.x=numt;for(int nb=0;nb c.m_upperLimit) + { + deltaImpulse = c.m_upperLimit-c.m_appliedImpulse; + c.m_appliedImpulse = c.m_upperLimit; + } + else + { + c.m_appliedImpulse = sum; + } + + + if (body1.mMassInv) + { + btVector3 linearComponent = c.m_contactNormal*body1.mMassInv; + body1.mDeltaLinearVelocity += vmVector3(linearComponent.getX()*deltaImpulse,linearComponent.getY()*deltaImpulse,linearComponent.getZ()*deltaImpulse); + btVector3 tmp=c.m_angularComponentA*(btVector3(deltaImpulse,deltaImpulse,deltaImpulse)); + body1.mDeltaAngularVelocity += vmVector3(tmp.getX(),tmp.getY(),tmp.getZ()); + } + + if (body2.mMassInv) + { + btVector3 linearComponent = -c.m_contactNormal*body2.mMassInv; + body2.mDeltaLinearVelocity += vmVector3(linearComponent.getX()*deltaImpulse,linearComponent.getY()*deltaImpulse,linearComponent.getZ()*deltaImpulse); + btVector3 tmp = c.m_angularComponentB*((btVector3(deltaImpulse,deltaImpulse,deltaImpulse)));//*m_angularFactor); + body2.mDeltaAngularVelocity += vmVector3(tmp.getX(),tmp.getY(),tmp.getZ()); + } + + //body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); + //body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); + +} + + +static SIMD_FORCE_INLINE +void pfxSolveLinearConstraintRow(btConstraintRow &constraint, + vmVector3 &deltaLinearVelocityA,vmVector3 &deltaAngularVelocityA, + float massInvA,const vmMatrix3 &inertiaInvA,const vmVector3 &rA, + vmVector3 &deltaLinearVelocityB,vmVector3 &deltaAngularVelocityB, + float massInvB,const vmMatrix3 &inertiaInvB,const vmVector3 &rB) +{ + const vmVector3 normal(btReadVector3(constraint.m_normal)); + btScalar deltaImpulse = constraint.m_rhs; + vmVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); + vmVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); + deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); + btScalar oldImpulse = constraint.m_accumImpulse; + constraint.m_accumImpulse = btClamped(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); + deltaImpulse = constraint.m_accumImpulse - oldImpulse; + deltaLinearVelocityA += deltaImpulse * massInvA * normal; + deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); + deltaLinearVelocityB -= deltaImpulse * massInvB * normal; + deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); + +} + +void btSolveContactConstraint( + btConstraintRow &constraintResponse, + btConstraintRow &constraintFriction1, + btConstraintRow &constraintFriction2, + const vmVector3 &contactPointA, + const vmVector3 &contactPointB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + float friction + ) +{ + vmVector3 rA = rotate(solverBodyA.mOrientation,contactPointA); + vmVector3 rB = rotate(solverBodyB.mOrientation,contactPointB); + + pfxSolveLinearConstraintRow(constraintResponse, + solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA, + solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB); + + float mf = friction*fabsf(constraintResponse.m_accumImpulse); + constraintFriction1.m_lowerLimit = -mf; + constraintFriction1.m_upperLimit = mf; + constraintFriction2.m_lowerLimit = -mf; + constraintFriction2.m_upperLimit = mf; + + pfxSolveLinearConstraintRow(constraintFriction1, + solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA, + solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB); + + pfxSolveLinearConstraintRow(constraintFriction2, + solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA, + solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB); +} + + +void CustomSolveConstraintsTaskParallel( + const PfxParallelGroup *contactParallelGroup,const PfxParallelBatch *contactParallelBatches, + PfxConstraintPair *contactPairs,uint32_t numContactPairs, + btPersistentManifold* offsetContactManifolds, + btConstraintRow* offsetContactConstraintRows, + const PfxParallelGroup *jointParallelGroup,const PfxParallelBatch *jointParallelBatches, + PfxConstraintPair *jointPairs,uint32_t numJointPairs, + btSolverConstraint* offsetSolverConstraints, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + int iteration,unsigned int taskId,unsigned int numTasks,btBarrier *barrier) +{ + + PfxSolverBody staticBody; + staticBody.mMassInv = 0.f; + staticBody.mDeltaAngularVelocity=vmVector3(0,0,0); + staticBody.mDeltaLinearVelocity =vmVector3(0,0,0); + + + for(int k=0;knumPhases;phaseId++) { + for(uint32_t batchId=0;batchIdnumBatches[phaseId];batchId++) { + uint32_t numPairs = jointParallelGroup->numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; + if(batchId%numTasks == taskId && numPairs > 0) { + const PfxParallelBatch &batch = jointParallelBatches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; + for(uint32_t i=0;isync(); + } + + // Contact + for(uint32_t phaseId=0;phaseIdnumPhases;phaseId++) { + for(uint32_t batchId=0;batchIdnumBatches[phaseId];batchId++) { + uint32_t numPairs = contactParallelGroup->numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; + if(batchId%numTasks == taskId && numPairs > 0) { + const PfxParallelBatch &batch = contactParallelBatches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; + for(uint32_t i=0;isync(); + } + } +} + +void CustomPostSolverTask( + TrbState *states, + PfxSolverBody *solverBodies, + uint32_t numRigidBodies) +{ + for(uint32_t i=0;i 0.707f) { + // choose p in y-z plane + float a = n[1]*n[1] + n[2]*n[2]; + float k = 1.0f/sqrtf(a); + p[0] = 0; + p[1] = -n[2]*k; + p[2] = n[1]*k; + // set q = n x p + q[0] = a*k; + q[1] = -n[0]*p[2]; + q[2] = n[0]*p[1]; + } + else { + // choose p in x-y plane + float a = n[0]*n[0] + n[1]*n[1]; + float k = 1.0f/sqrtf(a); + p[0] = -n[1]*k; + p[1] = n[0]*k; + p[2] = 0; + // set q = n x p + q[0] = -n[2]*p[1]; + q[1] = n[2]*p[0]; + q[2] = a*k; + } +} + + + +#define PFX_CONTACT_SLOP 0.001f + +void btSetupContactConstraint( + btConstraintRow &constraintResponse, + btConstraintRow &constraintFriction1, + btConstraintRow &constraintFriction2, + float penetrationDepth, + float restitution, + float friction, + const vmVector3 &contactNormal, + const vmVector3 &contactPointA, + const vmVector3 &contactPointB, + const TrbState &stateA, + const TrbState &stateB, + PfxSolverBody &solverBodyA, + PfxSolverBody &solverBodyB, + const vmVector3& linVelA, + const vmVector3& angVelA, + const vmVector3& linVelB, + const vmVector3& angVelB, + + float separateBias, + float timeStep + ) +{ + vmVector3 rA = rotate(solverBodyA.mOrientation,contactPointA); + vmVector3 rB = rotate(solverBodyB.mOrientation,contactPointB); + + vmMatrix3 K = vmMatrix3::scale(vmVector3(solverBodyA.mMassInv + solverBodyB.mMassInv)) - + crossMatrix(rA) * solverBodyA.mInertiaInv * crossMatrix(rA) - + crossMatrix(rB) * solverBodyB.mInertiaInv * crossMatrix(rB); + + //use the velocities without the applied (gravity and external) forces for restitution computation + vmVector3 vArestitution = linVelA + cross(angVelA,rA); + vmVector3 vBrestitution = linVelB + cross(angVelB,rB); + vmVector3 vABrestitution = vArestitution-vBrestitution; + + vmVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA); + vmVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB); + vmVector3 vAB = vA-vB; + + + vmVector3 tangent1,tangent2; + btPlaneSpace1(contactNormal,tangent1,tangent2); + +// constraintResponse.m_accumImpulse = 0.f; +// constraintFriction1.m_accumImpulse = 0.f; +// constraintFriction2.m_accumImpulse = 0.f; + + // Contact Constraint + { + vmVector3 normal = contactNormal; + + float denom = dot(K*normal,normal); + + constraintResponse.m_rhs = -(1.0f+restitution)*dot(vAB,normal); // velocity error + constraintResponse.m_rhs -= (separateBias * btMin(0.0f,penetrationDepth+PFX_CONTACT_SLOP)) / timeStep; // position error + constraintResponse.m_rhs /= denom; + constraintResponse.m_jacDiagInv = 1.0f/denom; + constraintResponse.m_lowerLimit = 0.0f; + constraintResponse.m_upperLimit = SIMD_INFINITY; + btStoreVector3(normal,constraintResponse.m_normal); + } + + // Friction Constraint 1 + { + vmVector3 normal = tangent1; + + float denom = dot(K*normal,normal); + + constraintFriction1.m_jacDiagInv = 1.0f/denom; + constraintFriction1.m_rhs = -dot(vAB,normal); + constraintFriction1.m_rhs *= constraintFriction1.m_jacDiagInv; + constraintFriction1.m_lowerLimit = 0.0f; + constraintFriction1.m_upperLimit = SIMD_INFINITY; + btStoreVector3(normal,constraintFriction1.m_normal); + } + + // Friction Constraint 2 + { + vmVector3 normal = tangent2; + + float denom = dot(K*normal,normal); + + constraintFriction2.m_jacDiagInv = 1.0f/denom; + constraintFriction2.m_rhs = -dot(vAB,normal); + constraintFriction2.m_rhs *= constraintFriction2.m_jacDiagInv; + constraintFriction2.m_lowerLimit = 0.0f; + constraintFriction2.m_upperLimit = SIMD_INFINITY; + btStoreVector3(normal,constraintFriction2.m_normal); + } +} + + +void CustomSetupContactConstraintsTask( + PfxConstraintPair *contactPairs,uint32_t numContactPairs, + btPersistentManifold* offsetContactManifolds, + btConstraintRow* offsetContactConstraintRows, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + float separateBias, + float timeStep) +{ + for(uint32_t i=0;i 1) restitution = 0.0f; + + float friction = sqrtf(solverBodyA.friction * solverBodyB.friction); + + for(int j=0;jgetInvMass()>0.f)) + { + linVelA = rbA->getLinearVelocity(); + angVelA = rbA->getAngularVelocity(); + } else + { + linVelA.setValue(0,0,0); + angVelA.setValue(0,0,0); + } + + if (rbB && (rbB->getInvMass()>0.f)) + { + linVelB = rbB->getLinearVelocity(); + angVelB = rbB->getAngularVelocity(); + } else + { + linVelB.setValue(0,0,0); + angVelB.setValue(0,0,0); + } + + + + btSetupContactConstraint( + contactConstraintRows[j*3], + contactConstraintRows[j*3+1], + contactConstraintRows[j*3+2], + cp.getDistance(), + restitution, + friction, + btReadVector3(cp.m_normalWorldOnB),//.mConstraintRow[0].m_normal), + btReadVector3(cp.m_localPointA), + btReadVector3(cp.m_localPointB), + stateA, + stateB, + solverBodyA, + solverBodyB, + (const vmVector3&)linVelA, (const vmVector3&)angVelA, + (const vmVector3&)linVelB, (const vmVector3&)angVelB, + separateBias, + timeStep + ); + } + + //contact.setCompositeFriction(friction); + } +} + + +void CustomWritebackContactConstraintsTask( + PfxConstraintPair *contactPairs,uint32_t numContactPairs, + btPersistentManifold* offsetContactManifolds, + btConstraintRow* offsetContactConstraintRows, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + float separateBias, + float timeStep) +{ + for(uint32_t i=0;iio); + btCriticalSection* criticalsection = io->setupContactConstraints.criticalSection; + + + //CustomCriticalSection *criticalsection = &io->m_cs; + switch(io->cmd) { + + case PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS: + CustomSolveConstraintsTaskParallel( + io->solveConstraints.contactParallelGroup, + io->solveConstraints.contactParallelBatches, + io->solveConstraints.contactPairs, + io->solveConstraints.numContactPairs, + io->solveConstraints.offsetContactManifolds, + io->solveConstraints.offsetContactConstraintRows, + + io->solveConstraints.jointParallelGroup, + io->solveConstraints.jointParallelBatches, + io->solveConstraints.jointPairs, + io->solveConstraints.numJointPairs, + io->solveConstraints.offsetSolverConstraints, + io->solveConstraints.offsetRigStates1, + io->solveConstraints.offsetSolverBodies, + io->solveConstraints.numRigidBodies, + io->solveConstraints.iteration, + + io->solveConstraints.taskId, + io->maxTasks1, + io->solveConstraints.barrier + ); + break; + + case PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER: + CustomPostSolverTask( io->postSolver.states,io->postSolver.solverBodies, io->postSolver.numRigidBodies); + break; + + + case PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS: + { + bool empty = false; + while(!empty) { + int start,batch; + + criticalsection->lock(); + + start = (int)criticalsection->getSharedParam(0); + batch = (int)criticalsection->getSharedParam(1); + + //PFX_PRINTF("taskId %d start %d num %d\n",arg->taskId,start,batch); + + // ŽŸ‚̃oƒbƒtƒ@‚ðƒZƒbƒg + int nextStart = start + batch; + int rest = btMax((int)io->setupContactConstraints.numContactPairs1 - nextStart,0); + int nextBatch = (rest > batch)?batch:rest; + + criticalsection->setSharedParam(0,nextStart); + criticalsection->setSharedParam(1,nextBatch); + + criticalsection->unlock(); + + if(batch > 0) { + CustomSetupContactConstraintsTask( + io->setupContactConstraints.offsetContactPairs+start,batch, + io->setupContactConstraints.offsetContactManifolds, + io->setupContactConstraints.offsetContactConstraintRows, + io->setupContactConstraints.offsetRigStates, +// io->setupContactConstraints.offsetRigBodies, + io->setupContactConstraints.offsetSolverBodies, + io->setupContactConstraints.numRigidBodies, + io->setupContactConstraints.separateBias, + io->setupContactConstraints.timeStep); + } + else { + empty = true; + } + } + } + break; + + case PFX_CONSTRAINT_SOLVER_CMD_WRITEBACK_APPLIED_IMPULSES_CONTACT_CONSTRAINTS: + { + bool empty = false; + while(!empty) { + int start,batch; + + criticalsection->lock(); + + start = (int)criticalsection->getSharedParam(0); + batch = (int)criticalsection->getSharedParam(1); + + //PFX_PRINTF("taskId %d start %d num %d\n",arg->taskId,start,batch); + + // ŽŸ‚̃oƒbƒtƒ@‚ðƒZƒbƒg + int nextStart = start + batch; + int rest = btMax((int)io->setupContactConstraints.numContactPairs1 - nextStart,0); + int nextBatch = (rest > batch)?batch:rest; + + criticalsection->setSharedParam(0,nextStart); + criticalsection->setSharedParam(1,nextBatch); + + criticalsection->unlock(); + + if(batch > 0) { + CustomWritebackContactConstraintsTask( + io->setupContactConstraints.offsetContactPairs+start,batch, + io->setupContactConstraints.offsetContactManifolds, + io->setupContactConstraints.offsetContactConstraintRows, + io->setupContactConstraints.offsetRigStates, +// io->setupContactConstraints.offsetRigBodies, + io->setupContactConstraints.offsetSolverBodies, + io->setupContactConstraints.numRigidBodies, + io->setupContactConstraints.separateBias, + io->setupContactConstraints.timeStep); + } + else { + empty = true; + } + } + } + break; + + default: + { + btAssert(0); + } + } + +} + + +void CustomSetupContactConstraintsNew( + PfxConstraintPair *contactPairs1,uint32_t numContactPairs, + btPersistentManifold *offsetContactManifolds, + btConstraintRow* offsetContactConstraintRows, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + float separationBias, + float timeStep, + class btThreadSupportInterface* threadSupport, + btCriticalSection* criticalSection, + btConstraintSolverIO *io , + uint8_t cmd + ) +{ + int maxTasks = threadSupport->getNumTasks(); + + int div = (int)maxTasks * 4; + int batch = ((int)numContactPairs + div - 1) / div; +#ifdef __PPU__ + BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport; +#endif + if (criticalSection) + { + criticalSection->setSharedParam(0,0); + criticalSection->setSharedParam(1,btMin(batch,64)); // batched number + } else + { +#ifdef __PPU__ + spursThread->setSharedParam(0,0); + spursThread->setSharedParam(1,btMin(batch,64)); // batched number +#endif //__PPU__ + } + + for(int t=0;tgetBarrierAddress(); + io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); +#endif + + +//#define SEQUENTIAL_SETUP +#ifdef SEQUENTIAL_SETUP + CustomSetupContactConstraintsTask(contactPairs1,numContactPairs,offsetContactManifolds,offsetRigStates,offsetSolverBodies,numRigidBodies,separationBias,timeStep); +#else + threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); +#endif + + } +#ifndef SEQUENTIAL_SETUP + unsigned int arg0,arg1; + for(int t=0;twaitForResponse(&arg0,&arg1); + } +#endif //SEQUENTIAL_SETUP + +} + + +void CustomSplitConstraints( + PfxConstraintPair *pairs,uint32_t numPairs, + PfxParallelGroup &group,PfxParallelBatch *batches, + uint32_t numTasks, + uint32_t numRigidBodies, + void *poolBuff, + uint32_t poolBytes + ) +{ + HeapManager pool((unsigned char*)poolBuff,poolBytes); + + // ƒXƒe[ƒgƒ`ƒFƒbƒN—pƒrƒbƒgƒtƒ‰ƒOƒe[ƒuƒ‹ + int bufSize = sizeof(uint8_t)*numRigidBodies; + bufSize = ((bufSize+127)>>7)<<7; // 128 bytes alignment + uint8_t *bodyTable = (uint8_t*)pool.allocate(bufSize,HeapManager::ALIGN128); + + // ƒyƒAƒ`ƒFƒbƒN—pƒrƒbƒgƒtƒ‰ƒOƒe[ƒuƒ‹ + uint32_t *pairTable; + size_t allocSize = sizeof(uint32_t)*((numPairs+31)/32); + pairTable = (uint32_t*)pool.allocate(allocSize); + memset(pairTable,0,allocSize); + + // –Ú•W‚Æ‚·‚镪Š„” + uint32_t targetCount = btMax(uint32_t(PFX_MIN_SOLVER_PAIRS),btMin(numPairs / (numTasks*2),uint32_t(PFX_MAX_SOLVER_PAIRS))); + uint32_t startIndex = 0; + + uint32_t phaseId; + uint32_t batchId; + uint32_t totalCount=0; + + uint32_t maxBatches = btMin(numTasks,uint32_t(PFX_MAX_SOLVER_BATCHES)); + + for(phaseId=0;phaseId>5; + uint32_t maskP = 1L << (i & 31); + + //pair is already assigned to a phase/batch + if(pairTable[idxP] & maskP) { + continue; + } + + uint32_t idxA = pfxGetRigidBodyIdA(pairs[i]); + uint32_t idxB = pfxGetRigidBodyIdB(pairs[i]); + + // —¼•û‚Æ‚àƒAƒNƒeƒBƒu‚Å‚È‚¢A‚Ü‚½‚͏Փ˓_‚ª‚O‚̃yƒA‚Í“o˜^‘Ώۂ©‚ç‚Í‚¸‚· + if(!pfxGetActive(pairs[i]) || pfxGetNumConstraints(pairs[i]) == 0 || + ((pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_STATIC) && (pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_STATIC)) ) { + if(startIndexCheck) + startIndex++; + //assign pair -> skip it because it has no constraints + pairTable[idxP] |= maskP; + totalCount++; + continue; + } + + // ˆË‘¶«‚̃`ƒFƒbƒN + if( (bodyTable[idxA] != batchId && bodyTable[idxA] != 0xff) || + (bodyTable[idxB] != batchId && bodyTable[idxB] != 0xff) ) { + startIndexCheck = false; + //bodies of the pair are already assigned to another batch within this phase + continue; + } + + // ˆË‘¶«”»’èƒe[ƒuƒ‹‚É“o˜^ + if(pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_DYNAMIC) + bodyTable[idxA] = batchId; + if(pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_DYNAMIC) + bodyTable[idxB] = batchId; + + if(startIndexCheck) + startIndex++; + + pairTable[idxP] |= maskP; + //add the pair 'i' to the current batch + batch.pairIndices[pairId++] = i; + pairCount++; + } + + group.numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId] = (uint16_t)pairId; + totalCount += pairCount; + } + + group.numBatches[phaseId] = batchId; + } + + group.numPhases = phaseId; + + pool.clear(); +} + + + +void CustomSolveConstraintsParallel( + PfxConstraintPair *contactPairs,uint32_t numContactPairs, + + PfxConstraintPair *jointPairs,uint32_t numJointPairs, + btPersistentManifold* offsetContactManifolds, + btConstraintRow* offsetContactConstraintRows, + btSolverConstraint* offsetSolverConstraints, + TrbState *offsetRigStates, + PfxSolverBody *offsetSolverBodies, + uint32_t numRigidBodies, + struct btConstraintSolverIO* io, + class btThreadSupportInterface* threadSupport, + int iteration, + void* poolBuf, + int poolBytes, + class btBarrier* barrier) + { + + int maxTasks = threadSupport->getNumTasks(); +// config.taskManager->setTaskEntry(PFX_SOLVER_ENTRY); + + HeapManager pool((unsigned char*)poolBuf,poolBytes); + + { + PfxParallelGroup *cgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup)); + PfxParallelBatch *cbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES),128); + PfxParallelGroup *jgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup)); + PfxParallelBatch *jbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES),128); + + uint32_t tmpBytes = poolBytes - 2 * (sizeof(PfxParallelGroup) + sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES) + 128); + void *tmpBuff = pool.allocate(tmpBytes); + + { + BT_PROFILE("CustomSplitConstraints"); + CustomSplitConstraints(contactPairs,numContactPairs,*cgroup,cbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes); + CustomSplitConstraints(jointPairs,numJointPairs,*jgroup,jbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes); + } + + { + BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS"); +//#define SOLVE_SEQUENTIAL +#ifdef SOLVE_SEQUENTIAL + CustomSolveConstraintsTask( + io->solveConstraints.contactParallelGroup, + io->solveConstraints.contactParallelBatches, + io->solveConstraints.contactPairs, + io->solveConstraints.numContactPairs, + io->solveConstraints.offsetContactManifolds, + + io->solveConstraints.jointParallelGroup, + io->solveConstraints.jointParallelBatches, + io->solveConstraints.jointPairs, + io->solveConstraints.numJointPairs, + io->solveConstraints.offsetSolverConstraints, + + io->solveConstraints.offsetRigStates1, + io->solveConstraints.offsetSolverBodies, + io->solveConstraints.numRigidBodies, + io->solveConstraints.iteration,0,1,0);//arg->taskId,1,0);//,arg->maxTasks,arg->barrier); +#else + for(int t=0;tgetBarrierAddress(); + io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); +#endif + + threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); + } + + unsigned int arg0,arg1; + for(int t=0;twaitForResponse(&arg0,&arg1); + } +#endif + } + pool.clear(); + } + + { + BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER"); + int batch = ((int)numRigidBodies + maxTasks - 1) / maxTasks; + int rest = (int)numRigidBodies; + int start = 0; + + for(int t=0;t 0 ? batch : rest; + io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER; + io[t].postSolver.states = offsetRigStates + start; + io[t].postSolver.solverBodies = offsetSolverBodies + start; + io[t].postSolver.numRigidBodies = (uint32_t)num; + io[t].maxTasks1 = maxTasks; +#ifdef __PPU__ + BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport; + io[t].barrierAddr2 = (unsigned int)spursThread->getBarrierAddress(); + io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); +#endif + +#ifdef SOLVE_SEQUENTIAL + CustomPostSolverTask( io[t].postSolver.states,io[t].postSolver.solverBodies, io[t].postSolver.numRigidBodies); +#else + threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); +#endif + rest -= num; + start += num; + } + + unsigned int arg0,arg1; + for(int t=0;twaitForResponse(&arg0,&arg1); +#endif + } + } + +} + + + +void BPE_customConstraintSolverSequentialNew(unsigned int new_num, PfxBroadphasePair *new_pairs1 , + btPersistentManifold* offsetContactManifolds, + PfxConstraintRow* offsetContactConstraintRows, + TrbState* states,int numRigidBodies, + struct PfxSolverBody* solverBodies, + PfxConstraintPair* jointPairs, unsigned int numJoints, + btSolverConstraint* offsetSolverConstraints, + float separateBias, + float timeStep, + int iteration, + btThreadSupportInterface* solverThreadSupport, + btCriticalSection* criticalSection, + struct btConstraintSolverIO* solverIO, + btBarrier* barrier + ) +{ + + { + BT_PROFILE("pfxSetupConstraints"); + + for(uint32_t i=0;i m_mystates; + btAlignedObjectArray m_mysolverbodies; + btAlignedObjectArray m_mypairs; + btAlignedObjectArray m_jointPairs; + btAlignedObjectArray m_constraintRows; + +}; + + +btConstraintSolverIO* createSolverIO(int numThreads) +{ + return new btConstraintSolverIO[numThreads]; +} + +btParallelConstraintSolver::btParallelConstraintSolver(btThreadSupportInterface* solverThreadSupport) +{ + + m_solverThreadSupport = solverThreadSupport;//createSolverThreadSupport(maxNumThreads); + m_solverIO = createSolverIO(m_solverThreadSupport->getNumTasks()); + + m_barrier = m_solverThreadSupport->createBarrier(); + m_criticalSection = m_solverThreadSupport->createCriticalSection(); + + m_memoryCache = new btParallelSolverMemoryCache(); +} + +btParallelConstraintSolver::~btParallelConstraintSolver() +{ + delete m_memoryCache; + delete m_solverIO; + m_solverThreadSupport->deleteBarrier(m_barrier); + m_solverThreadSupport->deleteCriticalSection(m_criticalSection); +} + + + +btScalar btParallelConstraintSolver::solveGroup(btCollisionObject** bodies1,int numRigidBodies,btPersistentManifold** manifoldPtr,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) +{ + +/* int sz = sizeof(PfxSolverBody); + int sz2 = sizeof(vmVector3); + int sz3 = sizeof(vmMatrix3); + int sz4 = sizeof(vmQuat); + int sz5 = sizeof(btConstraintRow); + int sz6 = sizeof(btSolverConstraint); + int sz7 = sizeof(TrbState); +*/ + + btPersistentManifold* offsetContactManifolds= (btPersistentManifold*) dispatcher->getInternalManifoldPool()->getPoolAddress(); + + + m_memoryCache->m_mysolverbodies.resize(numRigidBodies); + m_memoryCache->m_mystates.resize(numRigidBodies); + + { + BT_PROFILE("create states and solver bodies"); + for (int i=0;isetCompanionId(i); + + PfxSolverBody& solverBody = m_memoryCache->m_mysolverbodies[i]; + btRigidBody* rb = btRigidBody::upcast(obj); + TrbState& state = m_memoryCache->m_mystates[i]; + + state.reset(); + const btQuaternion& orgOri = obj->getWorldTransform().getRotation(); + vmQuat orn(orgOri.getX(),orgOri.getY(),orgOri.getZ(),orgOri.getW()); + state.setPosition(getVmVector3(obj->getWorldTransform().getOrigin())); + state.setOrientation(orn); + state.setPosition(state.getPosition()); + state.setRigidBodyId(i); + state.setAngularDamping(0); + state.setLinearDamping(0); + + + solverBody.mOrientation = state.getOrientation(); + solverBody.mDeltaLinearVelocity = vmVector3(0.0f); + solverBody.mDeltaAngularVelocity = vmVector3(0.0f); + solverBody.friction = obj->getFriction(); + solverBody.restitution = obj->getRestitution(); + + state.resetSleepCount(); + + //if(state.getMotionMask()&PFX_MOTION_MASK_DYNAMIC) { + if (rb && (rb->getInvMass()>0.f)) + { + btVector3 angVelPlusForces = rb->getAngularVelocity()+rb->getTotalTorque()*rb->getInvInertiaTensorWorld()*infoGlobal.m_timeStep; + btVector3 linVelPlusForces = rb->getLinearVelocity()+rb->getTotalForce()*rb->getInvMass()*infoGlobal.m_timeStep; + + state.setAngularVelocity((const vmVector3&)angVelPlusForces); + state.setLinearVelocity((const vmVector3&) linVelPlusForces); + + state.setMotionType(PfxMotionTypeActive); + vmMatrix3 ori(solverBody.mOrientation); + vmMatrix3 localInvInertia = vmMatrix3::identity(); + localInvInertia.setCol(0,vmVector3(rb->getInvInertiaDiagLocal().getX(),0,0)); + localInvInertia.setCol(1,vmVector3(0, rb->getInvInertiaDiagLocal().getY(),0)); + localInvInertia.setCol(2,vmVector3(0,0, rb->getInvInertiaDiagLocal().getZ())); + + solverBody.mMassInv = rb->getInvMass(); + solverBody.mInertiaInv = ori * localInvInertia * transpose(ori); + } else + { + state.setAngularVelocity(vmVector3(0)); + state.setLinearVelocity(vmVector3(0)); + + state.setMotionType(PfxMotionTypeFixed); + m_memoryCache->m_mysolverbodies[i].mMassInv = 0.f; + m_memoryCache->m_mysolverbodies[i].mInertiaInv = vmMatrix3(0.0f); + } + + } + } + + + + int totalPoints = 0; +#ifndef USE_C_ARRAYS + m_memoryCache->m_mypairs.resize(numManifolds); + //4 points per manifold and 3 rows per point makes 12 rows per manifold + m_memoryCache->m_constraintRows.resize(numManifolds*12); + m_memoryCache->m_jointPairs.resize(numConstraints); +#endif//USE_C_ARRAYS + + int actualNumManifolds= 0; + { + BT_PROFILE("convert manifolds"); + for (int i1=0;i1getNumContacts()>0) + { + btPersistentManifold* m = manifoldPtr[i1]; + btCollisionObject* obA = (btCollisionObject*)m->getBody0(); + btCollisionObject* obB = (btCollisionObject*)m->getBody1(); + bool obAisActive = !obA->isStaticOrKinematicObject() && obA->isActive(); + bool obBisActive = !obB->isStaticOrKinematicObject() && obB->isActive(); + + if (!obAisActive && !obBisActive) + continue; + + + //int contactId = i1;//actualNumManifolds; + + PfxBroadphasePair& pair = m_memoryCache->m_mypairs[actualNumManifolds]; + //init those + // float compFric = obA->getFriction()*obB->getFriction();//@todo + int idA = obA->getCompanionId(); + int idB = obB->getCompanionId(); + + m->m_companionIdA = idA; + m->m_companionIdB = idB; + + + // if ((mysolverbodies[idA].mMassInv!=0)&&(mysolverbodies[idB].mMassInv!=0)) + // continue; + int numPosPoints=0; + for (int p=0;pgetNumContacts();p++) + { + //btManifoldPoint& pt = m->getContactPoint(p); + //float dist = pt.getDistance(); + //if (dist<0.001) + numPosPoints++; + } + + + totalPoints+=numPosPoints; + pfxSetRigidBodyIdA(pair,idA); + pfxSetRigidBodyIdB(pair,idB); + pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask()); + pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask()); + pfxSetActive(pair,numPosPoints>0); + + pfxSetBroadphaseFlag(pair,0); + int contactId = m-offsetContactManifolds; + //likely the contact pool is not contiguous, make sure to allocate large enough contact pool + btAssert(contactId>=0); + btAssert(contactIdgetInternalManifoldPool()->getMaxCount()); + + pfxSetContactId(pair,contactId); + pfxSetNumConstraints(pair,numPosPoints);//manifoldPtr[i]->getNumContacts()); + actualNumManifolds++; + } + + } + } + + PfxConstraintPair* jointPairs=0; + jointPairs = numConstraints? &m_memoryCache->m_jointPairs[0]:0; + int actualNumJoints=0; + + + btSolverConstraint* offsetSolverConstraints = 0; + + //if (1) + { + + { + BT_PROFILE("convert constraints"); + + int totalNumRows = 0; + int i; + + m_tmpConstraintSizesPool.resize(numConstraints); + //calculate the total number of contraint rows + for (i=0;igetInfo1(&info1); + totalNumRows += info1.m_numConstraintRows; + } + m_tmpSolverNonContactConstraintPool.resize(totalNumRows); + offsetSolverConstraints =totalNumRows? &m_tmpSolverNonContactConstraintPool[0]:0; + + + ///setup the btSolverConstraints + int currentRow = 0; + + for (i=0;igetRigidBodyA(); + btRigidBody& rbB = constraint->getRigidBodyB(); + + int idA = constraint->getRigidBodyA().getCompanionId(); + int idB = constraint->getRigidBodyB().getCompanionId(); + + + int j; + for ( j=0;jm_contactNormal; + info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; + info2.m_J2linearAxis = 0; + info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; + info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this + ///the size of btSolverConstraint needs be a multiple of btScalar + btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint)); + info2.m_constraintError = ¤tConstraintRow->m_rhs; + currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; + info2.cfm = ¤tConstraintRow->m_cfm; + info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit; + info2.m_upperLimit = ¤tConstraintRow->m_upperLimit; + info2.m_numIterations = infoGlobal.m_numIterations; + constraints[i]->getInfo2(&info2); + + + + + ///finalize the constraint setup + for ( j=0;jgetRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor(); + } + { + const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; + solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor(); + } + + { + btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass(); + btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal; + btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal? + btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal; + + btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal); + sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); + sum += iMJlB.dot(solverConstraint.m_contactNormal); + sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); + + solverConstraint.m_jacDiagABInv = btScalar(1.)/sum; + } + + + ///fix rhs + ///todo: add force/torque accelerators + { + btScalar rel_vel; + btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()); + btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()); + + rel_vel = vel1Dotn+vel2Dotn; + + btScalar restitution = 0.f; + btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 + btScalar velocityError = restitution - rel_vel;// * damping; + btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; + solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + solverConstraint.m_appliedImpulse = 0.f; + + } + } + + PfxConstraintPair& pair = jointPairs[actualNumJoints]; + + int numConstraintRows= info1.m_numConstraintRows; + pfxSetNumConstraints(pair,numConstraintRows); + + + + pfxSetRigidBodyIdA(pair,idA); + pfxSetRigidBodyIdB(pair,idB); + //is this needed? + if (idA>=0) + pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask()); + if (idB>=0) + pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask()); + + pfxSetActive(pair,true); + int id = currentConstraintRow-offsetSolverConstraints; + pfxSetContactId(pair,id); + actualNumJoints++; + + + } + currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows; + } + } + } + + + + float separateBias=0.1;//info.m_erp;//or m_erp2? + float timeStep=infoGlobal.m_timeStep; + int iteration=infoGlobal.m_numIterations; + + //create a pair for each constraints, copy over info etc + + + + + + { + BT_PROFILE("compute num contacts"); + int totalContacts =0; + + for (int i=0;im_mypairs[i]; + totalContacts += pfxGetNumConstraints(*pair); + } + //printf("numManifolds = %d\n",numManifolds); + //printf("totalContacts=%d\n",totalContacts); + } + + + +// printf("actualNumManifolds=%d\n",actualNumManifolds); + { + BT_PROFILE("BPE_customConstraintSolverSequentialNew"); + if (numRigidBodies>0 && (actualNumManifolds+actualNumJoints)>0) + { +// PFX_PRINTF("num points = %d\n",totalPoints); +// PFX_PRINTF("num points PFX = %d\n",total); + + + PfxConstraintRow* contactRows = actualNumManifolds? &m_memoryCache->m_constraintRows[0] : 0; + PfxBroadphasePair* actualPairs = m_memoryCache->m_mypairs.size() ? &m_memoryCache->m_mypairs[0] : 0; + BPE_customConstraintSolverSequentialNew( + actualNumManifolds, + actualPairs, + offsetContactManifolds, + contactRows, + &m_memoryCache->m_mystates[0],numRigidBodies, + &m_memoryCache->m_mysolverbodies[0], + jointPairs,actualNumJoints, + offsetSolverConstraints, + separateBias,timeStep,iteration, + m_solverThreadSupport,m_criticalSection,m_solverIO,m_barrier); + } + } + + //copy results back to bodies + { + BT_PROFILE("copy back"); + for (int i=0;im_mystates[i]; + if (rb && (rb->getInvMass()>0.f)) + { + rb->setLinearVelocity(btVector3(state.getLinearVelocity().getX(),state.getLinearVelocity().getY(),state.getLinearVelocity().getZ())); + rb->setAngularVelocity(btVector3(state.getAngularVelocity().getX(),state.getAngularVelocity().getY(),state.getAngularVelocity().getZ())); + } + } + } + + + return 0.f; +} diff --git a/src/BulletMultiThreaded/btParallelConstraintSolver.h b/src/BulletMultiThreaded/btParallelConstraintSolver.h new file mode 100644 index 0000000..af42a83 --- /dev/null +++ b/src/BulletMultiThreaded/btParallelConstraintSolver.h @@ -0,0 +1,288 @@ +/* + Copyright (C) 2010 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef __BT_PARALLEL_CONSTRAINT_SOLVER_H +#define __BT_PARALLEL_CONSTRAINT_SOLVER_H + +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" + + + + +#include "LinearMath/btScalar.h" +#include "PlatformDefinitions.h" + + +#define PFX_MAX_SOLVER_PHASES 64 +#define PFX_MAX_SOLVER_BATCHES 16 +#define PFX_MAX_SOLVER_PAIRS 128 +#define PFX_MIN_SOLVER_PAIRS 16 + +#ifdef __CELLOS_LV2__ +ATTRIBUTE_ALIGNED128(struct) PfxParallelBatch { +#else +ATTRIBUTE_ALIGNED16(struct) PfxParallelBatch { +#endif + uint16_t pairIndices[PFX_MAX_SOLVER_PAIRS]; +}; + +#ifdef __CELLOS_LV2__ +ATTRIBUTE_ALIGNED128(struct) PfxParallelGroup { +#else +ATTRIBUTE_ALIGNED16(struct) PfxParallelGroup { +#endif + uint16_t numPhases; + uint16_t numBatches[PFX_MAX_SOLVER_PHASES]; + uint16_t numPairs[PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES]; +}; + + + +ATTRIBUTE_ALIGNED16(struct) PfxSortData16 { + union { + uint8_t i8data[16]; + uint16_t i16data[8]; + uint32_t i32data[4]; +#ifdef __SPU__ + vec_uint4 vdata; +#endif + }; + +#ifdef __SPU__ + void set8(int elem,uint8_t data) {vdata=(vec_uint4)spu_insert(data,(vec_uchar16)vdata,elem);} + void set16(int elem,uint16_t data) {vdata=(vec_uint4)spu_insert(data,(vec_ushort8)vdata,elem);} + void set32(int elem,uint32_t data) {vdata=(vec_uint4)spu_insert(data,(vec_uint4)vdata,elem);} + uint8_t get8(int elem) const {return spu_extract((vec_uchar16)vdata,elem);} + uint16_t get16(int elem) const {return spu_extract((vec_ushort8)vdata,elem);} + uint32_t get32(int elem) const {return spu_extract((vec_uint4)vdata,elem);} +#else + void set8(int elem,uint8_t data) {i8data[elem] = data;} + void set16(int elem,uint16_t data) {i16data[elem] = data;} + void set32(int elem,uint32_t data) {i32data[elem] = data;} + uint8_t get8(int elem) const {return i8data[elem];} + uint16_t get16(int elem) const {return i16data[elem];} + uint32_t get32(int elem) const {return i32data[elem];} +#endif +}; + +typedef PfxSortData16 PfxConstraintPair; + + +//J PfxBroadphasePair‚Æ‹¤’Ê + +SIMD_FORCE_INLINE void pfxSetConstraintId(PfxConstraintPair &pair,uint32_t i) {pair.set32(2,i);} +SIMD_FORCE_INLINE void pfxSetNumConstraints(PfxConstraintPair &pair,uint8_t n) {pair.set8(7,n);} + +SIMD_FORCE_INLINE uint32_t pfxGetConstraintId1(const PfxConstraintPair &pair) {return pair.get32(2);} +SIMD_FORCE_INLINE uint8_t pfxGetNumConstraints(const PfxConstraintPair &pair) {return pair.get8(7);} + +typedef PfxSortData16 PfxBroadphasePair; + +SIMD_FORCE_INLINE void pfxSetRigidBodyIdA(PfxBroadphasePair &pair,uint16_t i) {pair.set16(0,i);} +SIMD_FORCE_INLINE void pfxSetRigidBodyIdB(PfxBroadphasePair &pair,uint16_t i) {pair.set16(1,i);} +SIMD_FORCE_INLINE void pfxSetMotionMaskA(PfxBroadphasePair &pair,uint8_t i) {pair.set8(4,i);} +SIMD_FORCE_INLINE void pfxSetMotionMaskB(PfxBroadphasePair &pair,uint8_t i) {pair.set8(5,i);} +SIMD_FORCE_INLINE void pfxSetBroadphaseFlag(PfxBroadphasePair &pair,uint8_t f) {pair.set8(6,(pair.get8(6)&0xf0)|(f&0x0f));} +SIMD_FORCE_INLINE void pfxSetActive(PfxBroadphasePair &pair,bool b) {pair.set8(6,(pair.get8(6)&0x0f)|((b?1:0)<<4));} +SIMD_FORCE_INLINE void pfxSetContactId(PfxBroadphasePair &pair,uint32_t i) {pair.set32(2,i);} + +SIMD_FORCE_INLINE uint16_t pfxGetRigidBodyIdA(const PfxBroadphasePair &pair) {return pair.get16(0);} +SIMD_FORCE_INLINE uint16_t pfxGetRigidBodyIdB(const PfxBroadphasePair &pair) {return pair.get16(1);} +SIMD_FORCE_INLINE uint8_t pfxGetMotionMaskA(const PfxBroadphasePair &pair) {return pair.get8(4);} +SIMD_FORCE_INLINE uint8_t pfxGetMotionMaskB(const PfxBroadphasePair &pair) {return pair.get8(5);} +SIMD_FORCE_INLINE uint8_t pfxGetBroadphaseFlag(const PfxBroadphasePair &pair) {return pair.get8(6)&0x0f;} +SIMD_FORCE_INLINE bool pfxGetActive(const PfxBroadphasePair &pair) {return (pair.get8(6)>>4)!=0;} +SIMD_FORCE_INLINE uint32_t pfxGetContactId1(const PfxBroadphasePair &pair) {return pair.get32(2);} + + + +#if defined(__PPU__) || defined (__SPU__) +ATTRIBUTE_ALIGNED128(struct) PfxSolverBody { +#else +ATTRIBUTE_ALIGNED16(struct) PfxSolverBody { +#endif + vmVector3 mDeltaLinearVelocity; + vmVector3 mDeltaAngularVelocity; + vmMatrix3 mInertiaInv; + vmQuat mOrientation; + float mMassInv; + float friction; + float restitution; + float unused; + float unused2; + float unused3; + float unused4; + float unused5; +}; + + +#ifdef __PPU__ +#include "SpuDispatch/BulletPE2ConstraintSolverSpursSupport.h" +#endif + +static SIMD_FORCE_INLINE vmVector3 btReadVector3(const double* p) +{ + float tmp[3] = {float(p[0]),float(p[1]),float(p[2])}; + vmVector3 v; + loadXYZ(v, tmp); + return v; +} + +static SIMD_FORCE_INLINE vmQuat btReadQuat(const double* p) +{ + float tmp[4] = {float(p[0]),float(p[1]),float(p[2]),float(p[4])}; + vmQuat vq; + loadXYZW(vq, tmp); + return vq; +} + +static SIMD_FORCE_INLINE void btStoreVector3(const vmVector3 &src, double* p) +{ + float tmp[3]; + vmVector3 v = src; + storeXYZ(v, tmp); + p[0] = tmp[0]; + p[1] = tmp[1]; + p[2] = tmp[2]; +} + + +static SIMD_FORCE_INLINE vmVector3 btReadVector3(const float* p) +{ + vmVector3 v; + loadXYZ(v, p); + return v; +} + +static SIMD_FORCE_INLINE vmQuat btReadQuat(const float* p) +{ + vmQuat vq; + loadXYZW(vq, p); + return vq; +} + +static SIMD_FORCE_INLINE void btStoreVector3(const vmVector3 &src, float* p) +{ + vmVector3 v = src; + storeXYZ(v, p); +} + + + + +class btPersistentManifold; + +enum { + PFX_CONSTRAINT_SOLVER_CMD_SETUP_SOLVER_BODIES, + PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS, + PFX_CONSTRAINT_SOLVER_CMD_WRITEBACK_APPLIED_IMPULSES_CONTACT_CONSTRAINTS, + PFX_CONSTRAINT_SOLVER_CMD_SETUP_JOINT_CONSTRAINTS, + PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS, + PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER +}; + + +struct PfxSetupContactConstraintsIO { + PfxConstraintPair *offsetContactPairs; + uint32_t numContactPairs1; + btPersistentManifold* offsetContactManifolds; + btConstraintRow* offsetContactConstraintRows; + class TrbState *offsetRigStates; + struct PfxSolverBody *offsetSolverBodies; + uint32_t numRigidBodies; + float separateBias; + float timeStep; + class btCriticalSection* criticalSection; +}; + + + +struct PfxSolveConstraintsIO { + PfxParallelGroup *contactParallelGroup; + PfxParallelBatch *contactParallelBatches; + PfxConstraintPair *contactPairs; + uint32_t numContactPairs; + btPersistentManifold *offsetContactManifolds; + btConstraintRow* offsetContactConstraintRows; + PfxParallelGroup *jointParallelGroup; + PfxParallelBatch *jointParallelBatches; + PfxConstraintPair *jointPairs; + uint32_t numJointPairs; + struct btSolverConstraint* offsetSolverConstraints; + TrbState *offsetRigStates1; + PfxSolverBody *offsetSolverBodies; + uint32_t numRigidBodies; + uint32_t iteration; + + uint32_t taskId; + + class btBarrier* barrier; + +}; + +struct PfxPostSolverIO { + TrbState *states; + PfxSolverBody *solverBodies; + uint32_t numRigidBodies; +}; + +ATTRIBUTE_ALIGNED16(struct) btConstraintSolverIO { + uint8_t cmd; + union { + PfxSetupContactConstraintsIO setupContactConstraints; + PfxSolveConstraintsIO solveConstraints; + PfxPostSolverIO postSolver; + }; + + //SPU only + uint32_t barrierAddr2; + uint32_t criticalsectionAddr2; + uint32_t maxTasks1; +}; + + + + +void SolverThreadFunc(void* userPtr,void* lsMemory); +void* SolverlsMemoryFunc(); +///The btParallelConstraintSolver performs computations on constraint rows in parallel +///Using the cross-platform threading it supports Windows, Linux, Mac OSX and PlayStation 3 Cell SPUs +class btParallelConstraintSolver : public btSequentialImpulseConstraintSolver +{ + +protected: + struct btParallelSolverMemoryCache* m_memoryCache; + + class btThreadSupportInterface* m_solverThreadSupport; + + struct btConstraintSolverIO* m_solverIO; + class btBarrier* m_barrier; + class btCriticalSection* m_criticalSection; + + +public: + + btParallelConstraintSolver(class btThreadSupportInterface* solverThreadSupport); + + virtual ~btParallelConstraintSolver(); + + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher); + +}; + + + +#endif //__BT_PARALLEL_CONSTRAINT_SOLVER_H \ No newline at end of file diff --git a/src/BulletMultiThreaded/btThreadSupportInterface.cpp b/src/BulletMultiThreaded/btThreadSupportInterface.cpp new file mode 100644 index 0000000..8192aa4 --- /dev/null +++ b/src/BulletMultiThreaded/btThreadSupportInterface.cpp @@ -0,0 +1,22 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btThreadSupportInterface.h" + +btThreadSupportInterface::~btThreadSupportInterface() +{ + +} + diff --git a/src/BulletMultiThreaded/btThreadSupportInterface.h b/src/BulletMultiThreaded/btThreadSupportInterface.h new file mode 100644 index 0000000..54f1769 --- /dev/null +++ b/src/BulletMultiThreaded/btThreadSupportInterface.h @@ -0,0 +1,89 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_THREAD_SUPPORT_INTERFACE_H +#define BT_THREAD_SUPPORT_INTERFACE_H + + +#include //for ATTRIBUTE_ALIGNED16 +#include "PlatformDefinitions.h" +#include "PpuAddressSpace.h" + +class btBarrier { +public: + btBarrier() {} + virtual ~btBarrier() {} + + virtual void sync() = 0; + virtual void setMaxCount(int n) = 0; + virtual int getMaxCount() = 0; +}; + +class btCriticalSection { +public: + btCriticalSection() {} + virtual ~btCriticalSection() {} + + ATTRIBUTE_ALIGNED16(unsigned int mCommonBuff[32]); + + virtual unsigned int getSharedParam(int i) = 0; + virtual void setSharedParam(int i,unsigned int p) = 0; + + virtual void lock() = 0; + virtual void unlock() = 0; +}; + + +class btThreadSupportInterface +{ +public: + + virtual ~btThreadSupportInterface(); + +///send messages to SPUs + virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1) =0; + +///check for messages from SPUs + virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) =0; + + + ///non-blocking test if a task is completed. First implement all versions, and then enable this API + ///virtual bool isTaskCompleted(unsigned int *puiArgument0, unsigned int *puiArgument1, int timeOutInMilliseconds)=0; + +///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded) + virtual void startSPU() =0; + +///tell the task scheduler we are done with the SPU tasks + virtual void stopSPU()=0; + + ///tell the task scheduler to use no more than numTasks tasks + virtual void setNumTasks(int numTasks)=0; + + virtual int getNumTasks() const = 0; + + virtual btBarrier* createBarrier() = 0; + + virtual btCriticalSection* createCriticalSection() = 0; + + virtual void deleteBarrier(btBarrier* barrier)=0; + + virtual void deleteCriticalSection(btCriticalSection* criticalSection)=0; + + virtual void* getThreadLocalMemory(int taskId) { return 0; } + +}; + +#endif //BT_THREAD_SUPPORT_INTERFACE_H + diff --git a/src/BulletMultiThreaded/vectormath2bullet.h b/src/BulletMultiThreaded/vectormath2bullet.h new file mode 100644 index 0000000..4cc72ac --- /dev/null +++ b/src/BulletMultiThreaded/vectormath2bullet.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef BT_AOS_VECTORMATH_BULLET_CONVERT_H +#define BT_AOS_VECTORMATH_BULLET_CONVERT_H + +#include "PlatformDefinitions.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btMatrix3x3.h" + +inline Vectormath::Aos::Vector3 getVmVector3(const btVector3& bulletVec) +{ + return Vectormath::Aos::Vector3((float)bulletVec.getX(),(float)bulletVec.getY(),(float)bulletVec.getZ()); +} + +inline btVector3 getBtVector3(const Vectormath::Aos::Vector3& vmVec) +{ + return btVector3(vmVec.getX(),vmVec.getY(),vmVec.getZ()); +} +inline btVector3 getBtVector3(const Vectormath::Aos::Point3& vmVec) +{ + return btVector3(vmVec.getX(),vmVec.getY(),vmVec.getZ()); +} + +inline Vectormath::Aos::Quat getVmQuat(const btQuaternion& bulletQuat) +{ + Vectormath::Aos::Quat vmQuat((float)bulletQuat.getX(),(float)bulletQuat.getY(),(float)bulletQuat.getZ(),(float)bulletQuat.getW()); + return vmQuat; +} + +inline btQuaternion getBtQuat(const Vectormath::Aos::Quat& vmQuat) +{ + return btQuaternion (vmQuat.getX(),vmQuat.getY(),vmQuat.getZ(),vmQuat.getW()); +} + +inline Vectormath::Aos::Matrix3 getVmMatrix3(const btMatrix3x3& btMat) +{ + Vectormath::Aos::Matrix3 mat( + getVmVector3(btMat.getColumn(0)), + getVmVector3(btMat.getColumn(1)), + getVmVector3(btMat.getColumn(2))); + return mat; +} + + +#endif //BT_AOS_VECTORMATH_BULLET_CONVERT_H diff --git a/src/BulletSoftBody/CMakeLists.txt b/src/BulletSoftBody/CMakeLists.txt new file mode 100644 index 0000000..1053795 --- /dev/null +++ b/src/BulletSoftBody/CMakeLists.txt @@ -0,0 +1,65 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src + +) + +#SUBDIRS( Solvers ) + +SET(BulletSoftBody_SRCS + btSoftBody.cpp + btSoftBodyConcaveCollisionAlgorithm.cpp + btSoftBodyHelpers.cpp + btSoftBodyRigidBodyCollisionConfiguration.cpp + btSoftRigidCollisionAlgorithm.cpp + btSoftRigidDynamicsWorld.cpp + btSoftSoftCollisionAlgorithm.cpp + btDefaultSoftBodySolver.cpp + +) + +SET(BulletSoftBody_HDRS + btSoftBody.h + btSoftBodyData.h + btSoftBodyConcaveCollisionAlgorithm.h + btSoftBodyHelpers.h + btSoftBodyRigidBodyCollisionConfiguration.h + btSoftRigidCollisionAlgorithm.h + btSoftRigidDynamicsWorld.h + btSoftSoftCollisionAlgorithm.h + btSparseSDF.h + + btSoftBodySolvers.h + btDefaultSoftBodySolver.h + + btSoftBodySolverVertexBuffer.h +) + + + +ADD_LIBRARY(BulletSoftBody ${BulletSoftBody_SRCS} ${BulletSoftBody_HDRS}) +SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES SOVERSION ${BULLET_VERSION}) +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(BulletSoftBody BulletDynamics) +ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBody DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS BulletSoftBody DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES PUBLIC_HEADER "${BulletSoftBody_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/BulletSoftBody/btDefaultSoftBodySolver.cpp b/src/BulletSoftBody/btDefaultSoftBodySolver.cpp new file mode 100644 index 0000000..e90d24e --- /dev/null +++ b/src/BulletSoftBody/btDefaultSoftBodySolver.cpp @@ -0,0 +1,151 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" + +#include "btDefaultSoftBodySolver.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletSoftBody/btSoftBody.h" + + +btDefaultSoftBodySolver::btDefaultSoftBodySolver() +{ + // Initial we will clearly need to update solver constants + // For now this is global for the cloths linked with this solver - we should probably make this body specific + // for performance in future once we understand more clearly when constants need to be updated + m_updateSolverConstants = true; +} + +btDefaultSoftBodySolver::~btDefaultSoftBodySolver() +{ +} + +// In this case the data is already in the soft bodies so there is no need for us to do anything +void btDefaultSoftBodySolver::copyBackToSoftBodies(bool bMove) +{ + +} + +void btDefaultSoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate) +{ + m_softBodySet.copyFromArray( softBodies ); +} + +void btDefaultSoftBodySolver::updateSoftBodies( ) +{ + for ( int i=0; i < m_softBodySet.size(); i++) + { + btSoftBody* psb=(btSoftBody*)m_softBodySet[i]; + if (psb->isActive()) + { + psb->integrateMotion(); + } + } +} // updateSoftBodies + +bool btDefaultSoftBodySolver::checkInitialized() +{ + return true; +} + +void btDefaultSoftBodySolver::solveConstraints( float solverdt ) +{ + // Solve constraints for non-solver softbodies + for(int i=0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = static_cast(m_softBodySet[i]); + if (psb->isActive()) + { + psb->solveConstraints(); + } + } +} // btDefaultSoftBodySolver::solveConstraints + + +void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer ) +{ + // Currently only support CPU output buffers + // TODO: check for DX11 buffers. Take all offsets into the same DX11 buffer + // and use them together on a single kernel call if possible by setting up a + // per-cloth target buffer array for the copy kernel. + + if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER ) + { + const btAlignedObjectArray &clothVertices( softBody->m_nodes ); + int numVertices = clothVertices.size(); + + const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast< btCPUVertexBufferDescriptor* >(vertexBuffer); + float *basePointer = cpuVertexBuffer->getBasePointer(); + + if( vertexBuffer->hasVertexPositions() ) + { + const int vertexOffset = cpuVertexBuffer->getVertexOffset(); + const int vertexStride = cpuVertexBuffer->getVertexStride(); + float *vertexPointer = basePointer + vertexOffset; + + for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex ) + { + btVector3 position = clothVertices[vertexIndex].m_x; + *(vertexPointer + 0) = position.getX(); + *(vertexPointer + 1) = position.getY(); + *(vertexPointer + 2) = position.getZ(); + vertexPointer += vertexStride; + } + } + if( vertexBuffer->hasNormals() ) + { + const int normalOffset = cpuVertexBuffer->getNormalOffset(); + const int normalStride = cpuVertexBuffer->getNormalStride(); + float *normalPointer = basePointer + normalOffset; + + for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex ) + { + btVector3 normal = clothVertices[vertexIndex].m_n; + *(normalPointer + 0) = normal.getX(); + *(normalPointer + 1) = normal.getY(); + *(normalPointer + 2) = normal.getZ(); + normalPointer += normalStride; + } + } + } +} // btDefaultSoftBodySolver::copySoftBodyToVertexBuffer + +void btDefaultSoftBodySolver::processCollision( btSoftBody* softBody, btSoftBody* otherSoftBody) +{ + softBody->defaultCollisionHandler( otherSoftBody); +} + +// For the default solver just leave the soft body to do its collision processing +void btDefaultSoftBodySolver::processCollision( btSoftBody *softBody, const btCollisionObjectWrapper* collisionObjectWrap ) +{ + softBody->defaultCollisionHandler( collisionObjectWrap ); +} // btDefaultSoftBodySolver::processCollision + + +void btDefaultSoftBodySolver::predictMotion( float timeStep ) +{ + for ( int i=0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + + if (psb->isActive()) + { + psb->predictMotion(timeStep); + } + } +} + diff --git a/src/BulletSoftBody/btDefaultSoftBodySolver.h b/src/BulletSoftBody/btDefaultSoftBodySolver.h new file mode 100644 index 0000000..1c17ffc --- /dev/null +++ b/src/BulletSoftBody/btDefaultSoftBodySolver.h @@ -0,0 +1,63 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_DEFAULT_SOLVER_H +#define BT_SOFT_BODY_DEFAULT_SOLVER_H + + +#include "BulletSoftBody/btSoftBodySolvers.h" +#include "btSoftBodySolverVertexBuffer.h" +struct btCollisionObjectWrapper; + +class btDefaultSoftBodySolver : public btSoftBodySolver +{ +protected: + /** Variable to define whether we need to update solver constants on the next iteration */ + bool m_updateSolverConstants; + + btAlignedObjectArray< btSoftBody * > m_softBodySet; + + +public: + btDefaultSoftBodySolver(); + + virtual ~btDefaultSoftBodySolver(); + + virtual SolverTypes getSolverType() const + { + return DEFAULT_SOLVER; + } + + virtual bool checkInitialized(); + + virtual void updateSoftBodies( ); + + virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies,bool forceUpdate=false ); + + virtual void copyBackToSoftBodies(bool bMove = true); + + virtual void solveConstraints( float solverdt ); + + virtual void predictMotion( float solverdt ); + + virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer ); + + virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* ); + + virtual void processCollision( btSoftBody*, btSoftBody* ); + +}; + +#endif // #ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp new file mode 100644 index 0000000..8fe3465 --- /dev/null +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -0,0 +1,3639 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +///btSoftBody implementation by Nathanael Presson + +#include "btSoftBodyInternals.h" +#include "BulletSoftBody/btSoftBodySolvers.h" +#include "btSoftBodyData.h" +#include "LinearMath/btSerializer.h" + + +// +btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m) +:m_softBodySolver(0),m_worldInfo(worldInfo) +{ + /* Init */ + initDefaults(); + + /* Default material */ + Material* pm=appendMaterial(); + pm->m_kLST = 1; + pm->m_kAST = 1; + pm->m_kVST = 1; + pm->m_flags = fMaterial::Default; + + /* Nodes */ + const btScalar margin=getCollisionShape()->getMargin(); + m_nodes.resize(node_count); + for(int i=0,ni=node_count;i0?1/n.m_im:0; + n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n); + n.m_material= pm; + } + updateBounds(); + +} + +btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo) +:m_worldInfo(worldInfo) +{ + initDefaults(); +} + + +void btSoftBody::initDefaults() +{ + m_internalType = CO_SOFT_BODY; + m_cfg.aeromodel = eAeroModel::V_Point; + m_cfg.kVCF = 1; + m_cfg.kDG = 0; + m_cfg.kLF = 0; + m_cfg.kDP = 0; + m_cfg.kPR = 0; + m_cfg.kVC = 0; + m_cfg.kDF = (btScalar)0.2; + m_cfg.kMT = 0; + m_cfg.kCHR = (btScalar)1.0; + m_cfg.kKHR = (btScalar)0.1; + m_cfg.kSHR = (btScalar)1.0; + m_cfg.kAHR = (btScalar)0.7; + m_cfg.kSRHR_CL = (btScalar)0.1; + m_cfg.kSKHR_CL = (btScalar)1; + m_cfg.kSSHR_CL = (btScalar)0.5; + m_cfg.kSR_SPLT_CL = (btScalar)0.5; + m_cfg.kSK_SPLT_CL = (btScalar)0.5; + m_cfg.kSS_SPLT_CL = (btScalar)0.5; + m_cfg.maxvolume = (btScalar)1; + m_cfg.timescale = 1; + m_cfg.viterations = 0; + m_cfg.piterations = 1; + m_cfg.diterations = 0; + m_cfg.citerations = 4; + m_cfg.collisions = fCollision::Default; + m_pose.m_bvolume = false; + m_pose.m_bframe = false; + m_pose.m_volume = 0; + m_pose.m_com = btVector3(0,0,0); + m_pose.m_rot.setIdentity(); + m_pose.m_scl.setIdentity(); + m_tag = 0; + m_timeacc = 0; + m_bUpdateRtCst = true; + m_bounds[0] = btVector3(0,0,0); + m_bounds[1] = btVector3(0,0,0); + m_worldTransform.setIdentity(); + setSolver(eSolverPresets::Positions); + + /* Collision shape */ + ///for now, create a collision shape internally + m_collisionShape = new btSoftBodyCollisionShape(this); + m_collisionShape->setMargin(0.25f); + + m_initialWorldTransform.setIdentity(); + + m_windVelocity = btVector3(0,0,0); + m_restLengthScale = btScalar(1.0); +} + +// +btSoftBody::~btSoftBody() +{ + //for now, delete the internal shape + delete m_collisionShape; + int i; + + releaseClusters(); + for(i=0;i0) + *pm=*m_materials[0]; + else + ZeroInitialize(*pm); + m_materials.push_back(pm); + return(pm); +} + +// +void btSoftBody::appendNote( const char* text, + const btVector3& o, + const btVector4& c, + Node* n0, + Node* n1, + Node* n2, + Node* n3) +{ + Note n; + ZeroInitialize(n); + n.m_rank = 0; + n.m_text = text; + n.m_offset = o; + n.m_coords[0] = c.x(); + n.m_coords[1] = c.y(); + n.m_coords[2] = c.z(); + n.m_coords[3] = c.w(); + n.m_nodes[0] = n0;n.m_rank+=n0?1:0; + n.m_nodes[1] = n1;n.m_rank+=n1?1:0; + n.m_nodes[2] = n2;n.m_rank+=n2?1:0; + n.m_nodes[3] = n3;n.m_rank+=n3?1:0; + m_notes.push_back(n); +} + +// +void btSoftBody::appendNote( const char* text, + const btVector3& o, + Node* feature) +{ + appendNote(text,o,btVector4(1,0,0,0),feature); +} + +// +void btSoftBody::appendNote( const char* text, + const btVector3& o, + Link* feature) +{ + static const btScalar w=1/(btScalar)2; + appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0], + feature->m_n[1]); +} + +// +void btSoftBody::appendNote( const char* text, + const btVector3& o, + Face* feature) +{ + static const btScalar w=1/(btScalar)3; + appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0], + feature->m_n[1], + feature->m_n[2]); +} + +// +void btSoftBody::appendNode( const btVector3& x,btScalar m) +{ + if(m_nodes.capacity()==m_nodes.size()) + { + pointersToIndices(); + m_nodes.reserve(m_nodes.size()*2+1); + indicesToPointers(); + } + const btScalar margin=getCollisionShape()->getMargin(); + m_nodes.push_back(Node()); + Node& n=m_nodes[m_nodes.size()-1]; + ZeroInitialize(n); + n.m_x = x; + n.m_q = n.m_x; + n.m_im = m>0?1/m:0; + n.m_material = m_materials[0]; + n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n); +} + +// +void btSoftBody::appendLink(int model,Material* mat) +{ + Link l; + if(model>=0) + l=m_links[model]; + else + { ZeroInitialize(l);l.m_material=mat?mat:m_materials[0]; } + m_links.push_back(l); +} + +// +void btSoftBody::appendLink( int node0, + int node1, + Material* mat, + bool bcheckexist) +{ + appendLink(&m_nodes[node0],&m_nodes[node1],mat,bcheckexist); +} + +// +void btSoftBody::appendLink( Node* node0, + Node* node1, + Material* mat, + bool bcheckexist) +{ + if((!bcheckexist)||(!checkLink(node0,node1))) + { + appendLink(-1,mat); + Link& l=m_links[m_links.size()-1]; + l.m_n[0] = node0; + l.m_n[1] = node1; + l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length(); + m_bUpdateRtCst=true; + } +} + +// +void btSoftBody::appendFace(int model,Material* mat) +{ + Face f; + if(model>=0) + { f=m_faces[model]; } + else + { ZeroInitialize(f);f.m_material=mat?mat:m_materials[0]; } + m_faces.push_back(f); +} + +// +void btSoftBody::appendFace(int node0,int node1,int node2,Material* mat) +{ + if (node0==node1) + return; + if (node1==node2) + return; + if (node2==node0) + return; + + appendFace(-1,mat); + Face& f=m_faces[m_faces.size()-1]; + btAssert(node0!=node1); + btAssert(node1!=node2); + btAssert(node2!=node0); + f.m_n[0] = &m_nodes[node0]; + f.m_n[1] = &m_nodes[node1]; + f.m_n[2] = &m_nodes[node2]; + f.m_ra = AreaOf( f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x); + m_bUpdateRtCst=true; +} + +// +void btSoftBody::appendTetra(int model,Material* mat) +{ +Tetra t; +if(model>=0) + t=m_tetras[model]; + else + { ZeroInitialize(t);t.m_material=mat?mat:m_materials[0]; } +m_tetras.push_back(t); +} + +// +void btSoftBody::appendTetra(int node0, + int node1, + int node2, + int node3, + Material* mat) +{ + appendTetra(-1,mat); + Tetra& t=m_tetras[m_tetras.size()-1]; + t.m_n[0] = &m_nodes[node0]; + t.m_n[1] = &m_nodes[node1]; + t.m_n[2] = &m_nodes[node2]; + t.m_n[3] = &m_nodes[node3]; + t.m_rv = VolumeOf(t.m_n[0]->m_x,t.m_n[1]->m_x,t.m_n[2]->m_x,t.m_n[3]->m_x); + m_bUpdateRtCst=true; +} + +// + +void btSoftBody::appendAnchor(int node,btRigidBody* body, bool disableCollisionBetweenLinkedBodies,btScalar influence) +{ + btVector3 local = body->getWorldTransform().inverse()*m_nodes[node].m_x; + appendAnchor(node,body,local,disableCollisionBetweenLinkedBodies,influence); +} + +// +void btSoftBody::appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies,btScalar influence) +{ + if (disableCollisionBetweenLinkedBodies) + { + if (m_collisionDisabledObjects.findLinearSearch(body)==m_collisionDisabledObjects.size()) + { + m_collisionDisabledObjects.push_back(body); + } + } + + Anchor a; + a.m_node = &m_nodes[node]; + a.m_body = body; + a.m_local = localPivot; + a.m_node->m_battach = 1; + a.m_influence = influence; + m_anchors.push_back(a); +} + +// +void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1) +{ + LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint(); + pj->m_bodies[0] = body0; + pj->m_bodies[1] = body1; + pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position; + pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position; + pj->m_cfm = specs.cfm; + pj->m_erp = specs.erp; + pj->m_split = specs.split; + m_joints.push_back(pj); +} + +// +void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Body body) +{ + appendLinearJoint(specs,m_clusters[0],body); +} + +// +void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body) +{ + appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]); +} + +// +void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1) +{ + AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint(); + pj->m_bodies[0] = body0; + pj->m_bodies[1] = body1; + pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis; + pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis; + pj->m_cfm = specs.cfm; + pj->m_erp = specs.erp; + pj->m_split = specs.split; + pj->m_icontrol = specs.icontrol; + m_joints.push_back(pj); +} + +// +void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Body body) +{ + appendAngularJoint(specs,m_clusters[0],body); +} + +// +void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body) +{ + appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]); +} + +// +void btSoftBody::addForce(const btVector3& force) +{ + for(int i=0,ni=m_nodes.size();i0) + { + n.m_f += force; + } +} + +void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeIndex) +{ + btAssert(nodeIndex >= 0 && nodeIndex < m_nodes.size()); + + const btScalar dt = m_sst.sdt; + const btScalar kLF = m_cfg.kLF; + const btScalar kDG = m_cfg.kDG; + //const btScalar kPR = m_cfg.kPR; + //const btScalar kVC = m_cfg.kVC; + const bool as_lift = kLF>0; + const bool as_drag = kDG>0; + const bool as_aero = as_lift || as_drag; + const bool as_vaero = as_aero && (m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided); + + Node& n = m_nodes[nodeIndex]; + + if( n.m_im>0 ) + { + btSoftBody::sMedium medium; + + EvaluateMedium(m_worldInfo, n.m_x, medium); + medium.m_velocity = windVelocity; + medium.m_density = m_worldInfo->air_density; + + /* Aerodynamics */ + if(as_vaero) + { + const btVector3 rel_v = n.m_v - medium.m_velocity; + const btScalar rel_v_len = rel_v.length(); + const btScalar rel_v2 = rel_v.length2(); + + if(rel_v2>SIMD_EPSILON) + { + const btVector3 rel_v_nrm = rel_v.normalized(); + btVector3 nrm = n.m_n; + + if (m_cfg.aeromodel == btSoftBody::eAeroModel::V_TwoSidedLiftDrag) + { + nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + btVector3 fDrag(0, 0, 0); + btVector3 fLift(0, 0, 0); + + btScalar n_dot_v = nrm.dot(rel_v_nrm); + btScalar tri_area = 0.5f * n.m_area; + + fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm); + + // Check angle of attack + // cos(10º) = 0.98480 + if ( 0 < n_dot_v && n_dot_v < 0.98480f) + fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f-n_dot_v*n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm)); + + // Check if the velocity change resulted by aero drag force exceeds the current velocity of the node. + btVector3 del_v_by_fDrag = fDrag*n.m_im*m_sst.sdt; + btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2(); + btScalar v_len2 = n.m_v.length2(); + + if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0) + { + btScalar del_v_by_fDrag_len = del_v_by_fDrag.length(); + btScalar v_len = n.m_v.length(); + fDrag *= btScalar(0.8)*(v_len / del_v_by_fDrag_len); + } + + n.m_f += fDrag; + n.m_f += fLift; + } + else if (m_cfg.aeromodel == btSoftBody::eAeroModel::V_Point || m_cfg.aeromodel == btSoftBody::eAeroModel::V_OneSided || m_cfg.aeromodel == btSoftBody::eAeroModel::V_TwoSided) + { + if (btSoftBody::eAeroModel::V_TwoSided) + nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + + const btScalar dvn = btDot(rel_v,nrm); + /* Compute forces */ + if(dvn>0) + { + btVector3 force(0,0,0); + const btScalar c0 = n.m_area * dvn * rel_v2/2; + const btScalar c1 = c0 * medium.m_density; + force += nrm*(-c1*kLF); + force += rel_v.normalized() * (-c1 * kDG); + ApplyClampedForce(n, force, dt); + } + } + } + } + } +} + +void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceIndex) +{ + const btScalar dt = m_sst.sdt; + const btScalar kLF = m_cfg.kLF; + const btScalar kDG = m_cfg.kDG; +// const btScalar kPR = m_cfg.kPR; +// const btScalar kVC = m_cfg.kVC; + const bool as_lift = kLF>0; + const bool as_drag = kDG>0; + const bool as_aero = as_lift || as_drag; + const bool as_faero = as_aero && (m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided); + + if(as_faero) + { + btSoftBody::Face& f=m_faces[faceIndex]; + + btSoftBody::sMedium medium; + + const btVector3 v=(f.m_n[0]->m_v+f.m_n[1]->m_v+f.m_n[2]->m_v)/3; + const btVector3 x=(f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3; + EvaluateMedium(m_worldInfo,x,medium); + medium.m_velocity = windVelocity; + medium.m_density = m_worldInfo->air_density; + const btVector3 rel_v=v-medium.m_velocity; + const btScalar rel_v_len = rel_v.length(); + const btScalar rel_v2=rel_v.length2(); + + if(rel_v2>SIMD_EPSILON) + { + const btVector3 rel_v_nrm = rel_v.normalized(); + btVector3 nrm = f.m_normal; + + if (m_cfg.aeromodel == btSoftBody::eAeroModel::F_TwoSidedLiftDrag) + { + nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + + btVector3 fDrag(0, 0, 0); + btVector3 fLift(0, 0, 0); + + btScalar n_dot_v = nrm.dot(rel_v_nrm); + btScalar tri_area = 0.5f * f.m_ra; + + fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm); + + // Check angle of attack + // cos(10º) = 0.98480 + if ( 0 < n_dot_v && n_dot_v < 0.98480f) + fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f-n_dot_v*n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm)); + + fDrag /= 3; + fLift /= 3; + + for(int j=0;j<3;++j) + { + if (f.m_n[j]->m_im>0) + { + // Check if the velocity change resulted by aero drag force exceeds the current velocity of the node. + btVector3 del_v_by_fDrag = fDrag*f.m_n[j]->m_im*m_sst.sdt; + btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2(); + btScalar v_len2 = f.m_n[j]->m_v.length2(); + + if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0) + { + btScalar del_v_by_fDrag_len = del_v_by_fDrag.length(); + btScalar v_len = f.m_n[j]->m_v.length(); + fDrag *= btScalar(0.8)*(v_len / del_v_by_fDrag_len); + } + + f.m_n[j]->m_f += fDrag; + f.m_n[j]->m_f += fLift; + } + } + } + else if (m_cfg.aeromodel == btSoftBody::eAeroModel::F_OneSided || m_cfg.aeromodel == btSoftBody::eAeroModel::F_TwoSided) + { + if (btSoftBody::eAeroModel::F_TwoSided) + nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + + const btScalar dvn=btDot(rel_v,nrm); + /* Compute forces */ + if(dvn>0) + { + btVector3 force(0,0,0); + const btScalar c0 = f.m_ra*dvn*rel_v2; + const btScalar c1 = c0*medium.m_density; + force += nrm*(-c1*kLF); + force += rel_v.normalized()*(-c1*kDG); + force /= 3; + for(int j=0;j<3;++j) ApplyClampedForce(*f.m_n[j],force,dt); + } + } + } + } + +} + +// +void btSoftBody::addVelocity(const btVector3& velocity) +{ + for(int i=0,ni=m_nodes.size();i0) + { + n.m_v = velocity; + } + } +} + + +// +void btSoftBody::addVelocity(const btVector3& velocity,int node) +{ + Node& n=m_nodes[node]; + if(n.m_im>0) + { + n.m_v += velocity; + } +} + +// +void btSoftBody::setMass(int node,btScalar mass) +{ + m_nodes[node].m_im=mass>0?1/mass:0; + m_bUpdateRtCst=true; +} + +// +btScalar btSoftBody::getMass(int node) const +{ + return(m_nodes[node].m_im>0?1/m_nodes[node].m_im:0); +} + +// +btScalar btSoftBody::getTotalMass() const +{ + btScalar mass=0; + for(int i=0;im_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x); + for(int j=0;j<3;++j) + { + f.m_n[j]->m_im+=twicearea; + } + } + for( i=0;i ranks; +ranks.resize(m_nodes.size(),0); +int i; + +for(i=0;im_im+=btFabs(t.m_rv); + ranks[int(t.m_n[j]-&m_nodes[0])]+=1; + } + } +for( i=0;i0) + { + m_nodes[i].m_im=ranks[i]/m_nodes[i].m_im; + } + } +setTotalMass(mass,false); +} + +// +void btSoftBody::setVolumeDensity(btScalar density) +{ +btScalar volume=0; +for(int i=0;igetMargin(); + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; + + for(int i=0,ni=m_nodes.size();igetMargin(); + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; + + for(int i=0,ni=m_nodes.size();i0 ? + 1/(m_nodes[i].m_im*tmass) : + kmass/tmass; + } + /* Pos */ + const btVector3 com=evaluateCom(); + m_pose.m_pos.resize(m_nodes.size()); + for( i=0,ni=m_nodes.size();im_x-l.m_n[1]->m_x).length(); + l.m_c1 = l.m_rl*l.m_rl; + } +} + +// +btScalar btSoftBody::getVolume() const +{ + btScalar vol=0; + if(m_nodes.size()>0) + { + int i,ni; + + const btVector3 org=m_nodes[0].m_x; + for(i=0,ni=m_faces.size();im_x-org,btCross(f.m_n[1]->m_x-org,f.m_n[2]->m_x-org)); + } + vol/=(btScalar)6; + } + return(vol); +} + +// +int btSoftBody::clusterCount() const +{ + return(m_clusters.size()); +} + +// +btVector3 btSoftBody::clusterCom(const Cluster* cluster) +{ + btVector3 com(0,0,0); + for(int i=0,ni=cluster->m_nodes.size();im_nodes[i]->m_x*cluster->m_masses[i]; + } + return(com*cluster->m_imass); +} + +// +btVector3 btSoftBody::clusterCom(int cluster) const +{ + return(clusterCom(m_clusters[cluster])); +} + +// +btVector3 btSoftBody::clusterVelocity(const Cluster* cluster,const btVector3& rpos) +{ + return(cluster->m_lv+btCross(cluster->m_av,rpos)); +} + +// +void btSoftBody::clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) +{ + const btVector3 li=cluster->m_imass*impulse; + const btVector3 ai=cluster->m_invwi*btCross(rpos,impulse); + cluster->m_vimpulses[0]+=li;cluster->m_lv+=li; + cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; + cluster->m_nvimpulses++; +} + +// +void btSoftBody::clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) +{ + const btVector3 li=cluster->m_imass*impulse; + const btVector3 ai=cluster->m_invwi*btCross(rpos,impulse); + cluster->m_dimpulses[0]+=li; + cluster->m_dimpulses[1]+=ai; + cluster->m_ndimpulses++; +} + +// +void btSoftBody::clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse) +{ + if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity); + if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift); +} + +// +void btSoftBody::clusterVAImpulse(Cluster* cluster,const btVector3& impulse) +{ + const btVector3 ai=cluster->m_invwi*impulse; + cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; + cluster->m_nvimpulses++; +} + +// +void btSoftBody::clusterDAImpulse(Cluster* cluster,const btVector3& impulse) +{ + const btVector3 ai=cluster->m_invwi*impulse; + cluster->m_dimpulses[1]+=ai; + cluster->m_ndimpulses++; +} + +// +void btSoftBody::clusterAImpulse(Cluster* cluster,const Impulse& impulse) +{ + if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity); + if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift); +} + +// +void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse) +{ + cluster->m_dimpulses[0]+=impulse*cluster->m_imass; + cluster->m_ndimpulses++; +} + +struct NodeLinks +{ + btAlignedObjectArray m_links; +}; + + + +// +int btSoftBody::generateBendingConstraints(int distance,Material* mat) +{ + int i,j; + + if(distance>1) + { + /* Build graph */ + const int n=m_nodes.size(); + const unsigned inf=(~(unsigned)0)>>1; + unsigned* adj=new unsigned[n*n]; + + +#define IDX(_x_,_y_) ((_y_)*n+(_x_)) + for(j=0;j nodeLinks; + + + /* Build node links */ + nodeLinks.resize(m_nodes.size()); + + for( i=0;isum) + { + adj[IDX(i,j)]=adj[IDX(j,i)]=sum; + } + } + + } + } + } + } else + { + ///generic Floyd's algorithm + for(int k=0;ksum) + { + adj[IDX(i,j)]=adj[IDX(j,i)]=sum; + } + } + } + } + } + + + /* Build links */ + int nlinks=0; + for(j=0;jm_leaf) m_cdbvt.remove(c->m_leaf); + c->~Cluster(); + btAlignedFree(c); + m_clusters.remove(c); +} + +// +void btSoftBody::releaseClusters() +{ + while(m_clusters.size()>0) releaseCluster(0); +} + +// +int btSoftBody::generateClusters(int k,int maxiterations) +{ + int i; + releaseClusters(); + m_clusters.resize(btMin(k,m_nodes.size())); + for(i=0;im_collide= true; + } + k=m_clusters.size(); + if(k>0) + { + /* Initialize */ + btAlignedObjectArray centers; + btVector3 cog(0,0,0); + int i; + for(i=0;im_nodes.push_back(&m_nodes[i]); + } + cog/=(btScalar)m_nodes.size(); + centers.resize(k,cog); + /* Iterate */ + const btScalar slope=16; + bool changed; + int iterations=0; + do { + const btScalar w=2-btMin(1,iterations/slope); + changed=false; + iterations++; + int i; + + for(i=0;im_nodes.size();++j) + { + c+=m_clusters[i]->m_nodes[j]->m_x; + } + if(m_clusters[i]->m_nodes.size()) + { + c /= (btScalar)m_clusters[i]->m_nodes.size(); + c = centers[i]+(c-centers[i])*w; + changed |= ((c-centers[i]).length2()>SIMD_EPSILON); + centers[i] = c; + m_clusters[i]->m_nodes.resize(0); + } + } + for(i=0;im_nodes.push_back(&m_nodes[i]); + } + } while(changed&&(iterations cids; + cids.resize(m_nodes.size(),-1); + for(i=0;im_nodes.size();++j) + { + cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i; + } + } + for(i=0;im_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size()) + { + m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]); + } + } + } + } + } + /* Master */ + if(m_clusters.size()>1) + { + Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); + pmaster->m_collide = false; + pmaster->m_nodes.reserve(m_nodes.size()); + for(int i=0;im_nodes.push_back(&m_nodes[i]); + m_clusters.push_back(pmaster); + btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]); + } + /* Terminate */ + for(i=0;im_nodes.size()==0) + { + releaseCluster(i--); + } + } + } else + { + //create a cluster for each tetrahedron (if tetrahedra exist) or each face + if (m_tetras.size()) + { + m_clusters.resize(m_tetras.size()); + for(i=0;im_collide= true; + } + for (i=0;im_nodes.push_back(m_tetras[i].m_n[j]); + } + } + + } else + { + m_clusters.resize(m_faces.size()); + for(i=0;im_collide= true; + } + + for(i=0;im_nodes.push_back(m_faces[i].m_n[j]); + } + } + } + } + + if (m_clusters.size()) + { + initializeClusters(); + updateClusters(); + + + //for self-collision + m_clusterConnectivity.resize(m_clusters.size()*m_clusters.size()); + { + for (int c0=0;c0m_clusterIndex=c0; + for (int c1=0;c1m_nodes.size();i++) + { + for (int j=0;jm_nodes.size();j++) + { + if (cla->m_nodes[i] == clb->m_nodes[j]) + { + connected=true; + break; + } + } + } + m_clusterConnectivity[c0+c1*m_clusters.size()]=connected; + } + } + } + } + + return(m_clusters.size()); +} + +// +void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut) +{ + const Node* nbase = &m_nodes[0]; + int ncount = m_nodes.size(); + btSymMatrix edges(ncount,-2); + int newnodes=0; + int i,j,k,ni; + + /* Filter out */ + for(i=0;iEval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x))) + { + btSwap(m_links[i],m_links[m_links.size()-1]); + m_links.pop_back();--i; + } + } + } + /* Fill edges */ + for(i=0;i0) + { + const btVector3 x=Lerp(a.m_x,b.m_x,t); + const btVector3 v=Lerp(a.m_v,b.m_v,t); + btScalar m=0; + if(a.m_im>0) + { + if(b.m_im>0) + { + const btScalar ma=1/a.m_im; + const btScalar mb=1/b.m_im; + const btScalar mc=Lerp(ma,mb,t); + const btScalar f=(ma+mb)/(ma+mb+mc); + a.m_im=1/(ma*f); + b.m_im=1/(mb*f); + m=mc*f; + } + else + { a.m_im/=0.5f;m=1/a.m_im; } + } + else + { + if(b.m_im>0) + { b.m_im/=0.5f;m=1/b.m_im; } + else + m=0; + } + appendNode(x,m); + edges(i,j)=m_nodes.size()-1; + m_nodes[edges(i,j)].m_v=v; + ++newnodes; + } + } + } + } + nbase=&m_nodes[0]; + /* Refine links */ + for(i=0,ni=m_links.size();i0) + { + appendLink(i); + Link* pft[]={ &m_links[i], + &m_links[m_links.size()-1]}; + pft[0]->m_n[0]=&m_nodes[idx[0]]; + pft[0]->m_n[1]=&m_nodes[ni]; + pft[1]->m_n[0]=&m_nodes[ni]; + pft[1]->m_n[1]=&m_nodes[idx[1]]; + } + } + } + /* Refine faces */ + for(i=0;i0) + { + appendFace(i); + const int l=(k+1)%3; + Face* pft[]={ &m_faces[i], + &m_faces[m_faces.size()-1]}; + pft[0]->m_n[0]=&m_nodes[idx[l]]; + pft[0]->m_n[1]=&m_nodes[idx[j]]; + pft[0]->m_n[2]=&m_nodes[ni]; + pft[1]->m_n[0]=&m_nodes[ni]; + pft[1]->m_n[1]=&m_nodes[idx[k]]; + pft[1]->m_n[2]=&m_nodes[idx[l]]; + appendLink(ni,idx[l],pft[0]->m_material); + --i;break; + } + } + } + } + /* Cut */ + if(cut) + { + btAlignedObjectArray cnodes; + const int pcount=ncount; + int i; + ncount=m_nodes.size(); + cnodes.resize(ncount,0); + /* Nodes */ + for(i=0;i=pcount)||(btFabs(ifn->Eval(x))0) { m*=0.5f;m_nodes[i].m_im/=0.5f; } + appendNode(x,m); + cnodes[i]=m_nodes.size()-1; + m_nodes[cnodes[i]].m_v=v; + } + } + nbase=&m_nodes[0]; + /* Links */ + for(i=0,ni=m_links.size();iEval(m_nodes[id[0]].m_x)Eval(m_nodes[id[1]].m_x)Eval(n[0]->m_x)Eval(n[1]->m_x)Eval(n[2]->m_x) ranks; + btAlignedObjectArray todelete; + ranks.resize(nnodes,0); + for(i=0,ni=m_links.size();i=0;--i) + { + if(!ranks[i]) todelete.push_back(i); + } + if(todelete.size()) + { + btAlignedObjectArray& map=ranks; + for(int i=0;im_v=v; + pn[1]->m_v=v; + for(i=0,ni=m_links.size();im_n[1]=pn[mtch]; + pft[1]->m_n[0]=pn[1-mtch]; + done=true; + } + } + for(i=0,ni=m_faces.size();im_n[l]=pn[mtch]; + pft[1]->m_n[k]=pn[1-mtch]; + appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); + appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); + } + } + } + if(!done) + { + m_ndbvt.remove(pn[0]->m_leaf); + m_ndbvt.remove(pn[1]->m_leaf); + m_nodes.pop_back(); + m_nodes.pop_back(); + } + return(done); +} + +// +bool btSoftBody::rayTest(const btVector3& rayFrom, + const btVector3& rayTo, + sRayCast& results) +{ + if(m_faces.size()&&m_fdbvt.empty()) + initializeFaceTree(); + + results.body = this; + results.fraction = 1.f; + results.feature = eFeature::None; + results.index = -1; + + return(rayTest(rayFrom,rayTo,results.fraction,results.feature,results.index,false)!=0); +} + +// +void btSoftBody::setSolver(eSolverPresets::_ preset) +{ + m_cfg.m_vsequence.clear(); + m_cfg.m_psequence.clear(); + m_cfg.m_dsequence.clear(); + switch(preset) + { + case eSolverPresets::Positions: + m_cfg.m_psequence.push_back(ePSolver::Anchors); + m_cfg.m_psequence.push_back(ePSolver::RContacts); + m_cfg.m_psequence.push_back(ePSolver::SContacts); + m_cfg.m_psequence.push_back(ePSolver::Linear); + break; + case eSolverPresets::Velocities: + m_cfg.m_vsequence.push_back(eVSolver::Linear); + + m_cfg.m_psequence.push_back(ePSolver::Anchors); + m_cfg.m_psequence.push_back(ePSolver::RContacts); + m_cfg.m_psequence.push_back(ePSolver::SContacts); + + m_cfg.m_dsequence.push_back(ePSolver::Linear); + break; + } +} + +// +void btSoftBody::predictMotion(btScalar dt) +{ + + int i,ni; + + /* Update */ + if(m_bUpdateRtCst) + { + m_bUpdateRtCst=false; + updateConstants(); + m_fdbvt.clear(); + if(m_cfg.collisions&fCollision::VF_SS) + { + initializeFaceTree(); + } + } + + /* Prepare */ + m_sst.sdt = dt*m_cfg.timescale; + m_sst.isdt = 1/m_sst.sdt; + m_sst.velmrg = m_sst.sdt*3; + m_sst.radmrg = getCollisionShape()->getMargin(); + m_sst.updmrg = m_sst.radmrg*(btScalar)0.25; + /* Forces */ + addVelocity(m_worldInfo->m_gravity*m_sst.sdt); + applyForces(); + /* Integrate */ + for(i=0,ni=m_nodes.size();im_v+ + f.m_n[1]->m_v+ + f.m_n[2]->m_v)/3; + vol = VolumeOf(f,m_sst.radmrg); + m_fdbvt.update( f.m_leaf, + vol, + v*m_sst.velmrg, + m_sst.updmrg); + } + } + /* Pose */ + updatePose(); + /* Match */ + if(m_pose.m_bframe&&(m_cfg.kMT>0)) + { + const btMatrix3x3 posetrs=m_pose.m_rot; + for(int i=0,ni=m_nodes.size();i0) + { + const btVector3 x=posetrs*m_pose.m_pos[i]+m_pose.m_com; + n.m_x=Lerp(n.m_x,x,m_cfg.kMT); + } + } + } + /* Clear contacts */ + m_rcontacts.resize(0); + m_scontacts.resize(0); + /* Optimize dbvt's */ + m_ndbvt.optimizeIncremental(1); + m_fdbvt.optimizeIncremental(1); + m_cdbvt.optimizeIncremental(1); +} + +// +void btSoftBody::solveConstraints() +{ + + /* Apply clusters */ + applyClusters(false); + /* Prepare links */ + + int i,ni; + + for(i=0,ni=m_links.size();im_q-l.m_n[0]->m_q; + l.m_c2 = 1/(l.m_c3.length2()*l.m_c0); + } + /* Prepare anchors */ + for(i=0,ni=m_anchors.size();igetWorldTransform().getBasis()*a.m_local; + a.m_c0 = ImpulseMatrix( m_sst.sdt, + a.m_node->m_im, + a.m_body->getInvMass(), + a.m_body->getInvInertiaTensorWorld(), + ra); + a.m_c1 = ra; + a.m_c2 = m_sst.sdt*a.m_node->m_im; + a.m_body->activate(); + } + /* Solve velocities */ + if(m_cfg.viterations>0) + { + /* Solve */ + for(int isolve=0;isolve0) + { + for(int isolve=0;isolve0) + { + const btScalar vcf=m_cfg.kVCF*m_sst.isdt; + for(i=0,ni=m_nodes.size();i& bodies) +{ + const int nb=bodies.size(); + int iterations=0; + int i; + + for(i=0;im_cfg.citerations); + } + for(i=0;iprepareClusters(iterations); + } + for(i=0;isolveClusters(sor); + } + } + for(i=0;icleanupClusters(); + } +} + +// +void btSoftBody::integrateMotion() +{ + /* Update */ + updateNormals(); +} + +// +btSoftBody::RayFromToCaster::RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt) +{ + m_rayFrom = rayFrom; + m_rayNormalizedDirection = (rayTo-rayFrom); + m_rayTo = rayTo; + m_mint = mxt; + m_face = 0; + m_tests = 0; +} + +// +void btSoftBody::RayFromToCaster::Process(const btDbvtNode* leaf) +{ + btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data; + const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection, + f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x, + m_mint); + if((t>0)&&(tteps)&&(tceps) && + (btDot(n,btCross(b-hit,c-hit))>ceps) && + (btDot(n,btCross(c-hit,a-hit))>ceps)) + { + return(t); + } + } + } + return(-1); +} + +// +void btSoftBody::pointersToIndices() +{ +#define PTR2IDX(_p_,_b_) reinterpret_cast((_p_)-(_b_)) + btSoftBody::Node* base=m_nodes.size() ? &m_nodes[0] : 0; + int i,ni; + + for(i=0,ni=m_nodes.size();idata=*(void**)&i; + } + } + for(i=0,ni=m_links.size();idata=*(void**)&i; + } + } + for(i=0,ni=m_anchors.size();idata=&m_nodes[i]; + } + } + for(i=0,ni=m_links.size();idata=&m_faces[i]; + } + } + for(i=0,ni=m_anchors.size();im_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x, + mint); + if(t>0) + { + ++cnt; + if(!bcountonly) + { + feature=btSoftBody::eFeature::Face; + index=i; + mint=t; + } + } + } + } + else + {/* Use dbvt */ + RayFromToCaster collider(rayFrom,rayTo,mint); + + btDbvt::rayTest(m_fdbvt.m_root,rayFrom,rayTo,collider); + if(collider.m_face) + { + mint=collider.m_mint; + feature=btSoftBody::eFeature::Face; + index=(int)(collider.m_face-&m_faces[0]); + cnt=1; + } + } + + for (int i=0;im_x; + btVector3 v1=tet.m_n[index1]->m_x; + btVector3 v2=tet.m_n[index2]->m_x; + + + const btScalar t=RayFromToCaster::rayFromToTriangle( rayFrom,rayTo,dir, + v0,v1,v2, + mint); + if(t>0) + { + ++cnt; + if(!bcountonly) + { + feature=btSoftBody::eFeature::Tetra; + index=i; + mint=t; + } + } + } + } + return(cnt); +} + +// +void btSoftBody::initializeFaceTree() +{ + m_fdbvt.clear(); + for(int i=0;igetCollisionShape(); +// const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); + //const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObjWrap->getWorldTransform(); + const btTransform &wtr = colObjWrap->getWorldTransform(); + //todo: check which transform is needed here + + btScalar dst = + m_worldInfo->m_sparsesdf.Evaluate( + wtr.invXform(x), + shp, + nrm, + margin); + if(dst<0) + { + cti.m_colObj = colObjWrap->getCollisionObject(); + cti.m_normal = wtr.getBasis()*nrm; + cti.m_offset = -btDot( cti.m_normal, x - cti.m_normal * dst ); + return(true); + } + return(false); +} + +// +void btSoftBody::updateNormals() +{ + + const btVector3 zv(0,0,0); + int i,ni; + + for(i=0,ni=m_nodes.size();im_x-f.m_n[0]->m_x, + f.m_n[2]->m_x-f.m_n[0]->m_x); + f.m_normal=n.normalized(); + f.m_n[0]->m_n+=n; + f.m_n[1]->m_n+=n; + f.m_n[2]->m_n+=n; + } + for(i=0,ni=m_nodes.size();iSIMD_EPSILON) + m_nodes[i].m_n /= len; + } +} + +// +void btSoftBody::updateBounds() +{ + /*if( m_acceleratedSoftBody ) + { + // If we have an accelerated softbody we need to obtain the bounds correctly + // For now (slightly hackily) just have a very large AABB + // TODO: Write get bounds kernel + // If that is updating in place, atomic collisions might be low (when the cloth isn't perfectly aligned to an axis) and we could + // probably do a test and exchange reasonably efficiently. + + m_bounds[0] = btVector3(-1000, -1000, -1000); + m_bounds[1] = btVector3(1000, 1000, 1000); + + } else {*/ + if(m_ndbvt.m_root) + { + const btVector3& mins=m_ndbvt.m_root->volume.Mins(); + const btVector3& maxs=m_ndbvt.m_root->volume.Maxs(); + const btScalar csm=getCollisionShape()->getMargin(); + const btVector3 mrg=btVector3( csm, + csm, + csm)*1; // ??? to investigate... + m_bounds[0]=mins-mrg; + m_bounds[1]=maxs+mrg; + if(0!=getBroadphaseHandle()) + { + m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(), + m_bounds[0], + m_bounds[1], + m_worldInfo->m_dispatcher); + } + } + else + { + m_bounds[0]= + m_bounds[1]=btVector3(0,0,0); + } + //} +} + + +// +void btSoftBody::updatePose() +{ + if(m_pose.m_bframe) + { + btSoftBody::Pose& pose=m_pose; + const btVector3 com=evaluateCom(); + /* Com */ + pose.m_com = com; + /* Rotation */ + btMatrix3x3 Apq; + const btScalar eps=SIMD_EPSILON; + Apq[0]=Apq[1]=Apq[2]=btVector3(0,0,0); + Apq[0].setX(eps);Apq[1].setY(eps*2);Apq[2].setZ(eps*3); + for(int i=0,ni=m_nodes.size();i1) + { + const btScalar idet=Clamp( 1/pose.m_scl.determinant(), + 1,m_cfg.maxvolume); + pose.m_scl=Mul(pose.m_scl,idet); + } + + } +} + +// +void btSoftBody::updateArea(bool averageArea) +{ + int i,ni; + + /* Face area */ + for(i=0,ni=m_faces.size();im_x,f.m_n[1]->m_x,f.m_n[2]->m_x); + } + + /* Node area */ + + if (averageArea) + { + btAlignedObjectArray counts; + counts.resize(m_nodes.size(),0); + for(i=0,ni=m_nodes.size();im_area+=btFabs(f.m_ra); + } + } + for(i=0,ni=m_nodes.size();i0) + m_nodes[i].m_area/=(btScalar)counts[i]; + else + m_nodes[i].m_area=0; + } + } + else + { + // initialize node area as zero + for(i=0,ni=m_nodes.size();im_area += f.m_ra; + } + } + + for(i=0,ni=m_nodes.size();im_im+l.m_n[1]->m_im)/m.m_kLST; + } +} + +void btSoftBody::updateConstants() +{ + resetLinkRestLengths(); + updateLinkConstants(); + updateArea(); +} + + + +// +void btSoftBody::initializeClusters() +{ + int i; + + for( i=0;im_im==0) + { + c.m_containsAnchor = true; + c.m_masses[j] = BT_LARGE_FLOAT; + } else + { + c.m_masses[j] = btScalar(1.)/c.m_nodes[j]->m_im; + } + c.m_imass += c.m_masses[j]; + } + c.m_imass = btScalar(1.)/c.m_imass; + c.m_com = btSoftBody::clusterCom(&c); + c.m_lv = btVector3(0,0,0); + c.m_av = btVector3(0,0,0); + c.m_leaf = 0; + /* Inertia */ + btMatrix3x3& ii=c.m_locii; + ii[0]=ii[1]=ii[2]=btVector3(0,0,0); + { + int i,ni; + + for(i=0,ni=c.m_nodes.size();im_x-c.m_com; + const btVector3 q=k*k; + const btScalar m=c.m_masses[i]; + ii[0][0] += m*(q[1]+q[2]); + ii[1][1] += m*(q[0]+q[2]); + ii[2][2] += m*(q[0]+q[1]); + ii[0][1] -= m*k[0]*k[1]; + ii[0][2] -= m*k[0]*k[2]; + ii[1][2] -= m*k[1]*k[2]; + } + } + ii[1][0]=ii[0][1]; + ii[2][0]=ii[0][2]; + ii[2][1]=ii[1][2]; + + ii = ii.inverse(); + + /* Frame */ + c.m_framexform.setIdentity(); + c.m_framexform.setOrigin(c.m_com); + c.m_framerefs.resize(c.m_nodes.size()); + { + int i; + for(i=0;im_x-c.m_com; + } + } + } +} + +// +void btSoftBody::updateClusters() +{ + BT_PROFILE("UpdateClusters"); + int i; + + for(i=0;im_x-c.m_com; + const btVector3& b=c.m_framerefs[i]; + m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b; + } + PolarDecompose(m,r,s); + c.m_framexform.setOrigin(c.m_com); + c.m_framexform.setBasis(r); + /* Inertia */ +#if 1/* Constant */ + c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose(); +#else +#if 0/* Sphere */ + const btScalar rk=(2*c.m_extents.length2())/(5*c.m_imass); + const btVector3 inertia(rk,rk,rk); + const btVector3 iin(btFabs(inertia[0])>SIMD_EPSILON?1/inertia[0]:0, + btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0, + btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0); + + c.m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose(); +#else/* Actual */ + c.m_invwi[0]=c.m_invwi[1]=c.m_invwi[2]=btVector3(0,0,0); + for(int i=0;im_x-c.m_com; + const btVector3 q=k*k; + const btScalar m=1/c.m_nodes[i]->m_im; + c.m_invwi[0][0] += m*(q[1]+q[2]); + c.m_invwi[1][1] += m*(q[0]+q[2]); + c.m_invwi[2][2] += m*(q[0]+q[1]); + c.m_invwi[0][1] -= m*k[0]*k[1]; + c.m_invwi[0][2] -= m*k[0]*k[2]; + c.m_invwi[1][2] -= m*k[1]*k[2]; + } + c.m_invwi[1][0]=c.m_invwi[0][1]; + c.m_invwi[2][0]=c.m_invwi[0][2]; + c.m_invwi[2][1]=c.m_invwi[1][2]; + c.m_invwi=c.m_invwi.inverse(); +#endif +#endif + /* Velocities */ + c.m_lv=btVector3(0,0,0); + c.m_av=btVector3(0,0,0); + { + int i; + + for(i=0;im_v*c.m_masses[i]; + c.m_lv += v; + c.m_av += btCross(c.m_nodes[i]->m_x-c.m_com,v); + } + } + c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping); + c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping); + c.m_vimpulses[0] = + c.m_vimpulses[1] = btVector3(0,0,0); + c.m_dimpulses[0] = + c.m_dimpulses[1] = btVector3(0,0,0); + c.m_nvimpulses = 0; + c.m_ndimpulses = 0; + /* Matching */ + if(c.m_matching>0) + { + for(int j=0;jm_x; + btVector3 mx=mi; + for(int j=1;jm_x); + mx.setMax(c.m_nodes[j]->m_x); + } + ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx); + if(c.m_leaf) + m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg); + else + c.m_leaf=m_cdbvt.insert(bounds,&c); + } + } + } + + +} + + + + +// +void btSoftBody::cleanupClusters() +{ + for(int i=0;iTerminate(m_sst.sdt); + if(m_joints[i]->m_delete) + { + btAlignedFree(m_joints[i]); + m_joints.remove(m_joints[i--]); + } + } +} + +// +void btSoftBody::prepareClusters(int iterations) +{ + for(int i=0;iPrepare(m_sst.sdt,iterations); + } +} + + +// +void btSoftBody::solveClusters(btScalar sor) +{ + for(int i=0,ni=m_joints.size();iSolve(m_sst.sdt,sor); + } +} + +// +void btSoftBody::applyClusters(bool drift) +{ + BT_PROFILE("ApplyClusters"); +// const btScalar f0=m_sst.sdt; + //const btScalar f1=f0/2; + btAlignedObjectArray deltas; + btAlignedObjectArray weights; + deltas.resize(m_nodes.size(),btVector3(0,0,0)); + weights.resize(m_nodes.size(),0); + int i; + + if(drift) + { + for(i=0;im_x; + const btScalar q=c.m_masses[j]; + deltas[idx] += (v+btCross(w,x-c.m_com))*q; + weights[idx] += q; + } + } + } + for(i=0;i0) + { + m_nodes[i].m_x+=deltas[i]/weights[i]; + } + } +} + +// +void btSoftBody::dampClusters() +{ + int i; + + for(i=0;i0) + { + for(int j=0;j0) + { + const btVector3 vx=c.m_lv+btCross(c.m_av,c.m_nodes[j]->m_q-c.m_com); + if(vx.length2()<=n.m_v.length2()) + { + n.m_v += c.m_ndamping*(vx-n.m_v); + } + } + } + } + } +} + +// +void btSoftBody::Joint::Prepare(btScalar dt,int) +{ + m_bodies[0].activate(); + m_bodies[1].activate(); +} + +// +void btSoftBody::LJoint::Prepare(btScalar dt,int iterations) +{ + static const btScalar maxdrift=4; + Joint::Prepare(dt,iterations); + m_rpos[0] = m_bodies[0].xform()*m_refs[0]; + m_rpos[1] = m_bodies[1].xform()*m_refs[1]; + m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt; + m_rpos[0] -= m_bodies[0].xform().getOrigin(); + m_rpos[1] -= m_bodies[1].xform().getOrigin(); + m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0], + m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]); + if(m_split>0) + { + m_sdrift = m_massmatrix*(m_drift*m_split); + m_drift *= 1-m_split; + } + m_drift /=(btScalar)iterations; +} + +// +void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor) +{ + const btVector3 va=m_bodies[0].velocity(m_rpos[0]); + const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); + const btVector3 vr=va-vb; + btSoftBody::Impulse impulse; + impulse.m_asVelocity = 1; + impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor; + m_bodies[0].applyImpulse(-impulse,m_rpos[0]); + m_bodies[1].applyImpulse( impulse,m_rpos[1]); +} + +// +void btSoftBody::LJoint::Terminate(btScalar dt) +{ + if(m_split>0) + { + m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); + m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); + } +} + +// +void btSoftBody::AJoint::Prepare(btScalar dt,int iterations) +{ + static const btScalar maxdrift=SIMD_PI/16; + m_icontrol->Prepare(this); + Joint::Prepare(dt,iterations); + m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0]; + m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1]; + m_drift = NormalizeAny(btCross(m_axis[1],m_axis[0])); + m_drift *= btMin(maxdrift,btAcos(Clamp(btDot(m_axis[0],m_axis[1]),-1,+1))); + m_drift *= m_erp/dt; + m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia()); + if(m_split>0) + { + m_sdrift = m_massmatrix*(m_drift*m_split); + m_drift *= 1-m_split; + } + m_drift /=(btScalar)iterations; +} + +// +void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor) +{ + const btVector3 va=m_bodies[0].angularVelocity(); + const btVector3 vb=m_bodies[1].angularVelocity(); + const btVector3 vr=va-vb; + const btScalar sp=btDot(vr,m_axis[0]); + const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp); + btSoftBody::Impulse impulse; + impulse.m_asVelocity = 1; + impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor; + m_bodies[0].applyAImpulse(-impulse); + m_bodies[1].applyAImpulse( impulse); +} + +// +void btSoftBody::AJoint::Terminate(btScalar dt) +{ + if(m_split>0) + { + m_bodies[0].applyDAImpulse(-m_sdrift); + m_bodies[1].applyDAImpulse( m_sdrift); + } +} + +// +void btSoftBody::CJoint::Prepare(btScalar dt,int iterations) +{ + Joint::Prepare(dt,iterations); + const bool dodrift=(m_life==0); + m_delete=(++m_life)>m_maxlife; + if(dodrift) + { + m_drift=m_drift*m_erp/dt; + if(m_split>0) + { + m_sdrift = m_massmatrix*(m_drift*m_split); + m_drift *= 1-m_split; + } + m_drift/=(btScalar)iterations; + } + else + { + m_drift=m_sdrift=btVector3(0,0,0); + } +} + +// +void btSoftBody::CJoint::Solve(btScalar dt,btScalar sor) +{ + const btVector3 va=m_bodies[0].velocity(m_rpos[0]); + const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); + const btVector3 vrel=va-vb; + const btScalar rvac=btDot(vrel,m_normal); + btSoftBody::Impulse impulse; + impulse.m_asVelocity = 1; + impulse.m_velocity = m_drift; + if(rvac<0) + { + const btVector3 iv=m_normal*rvac; + const btVector3 fv=vrel-iv; + impulse.m_velocity += iv+fv*m_friction; + } + impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor; + + if (m_bodies[0].m_soft==m_bodies[1].m_soft) + { + if ((impulse.m_velocity.getX() ==impulse.m_velocity.getX())&&(impulse.m_velocity.getY() ==impulse.m_velocity.getY())&& + (impulse.m_velocity.getZ() ==impulse.m_velocity.getZ())) + { + if (impulse.m_asVelocity) + { + if (impulse.m_velocity.length() m_maxSelfCollisionImpulse) + { + + } else + { + m_bodies[0].applyImpulse(-impulse*m_bodies[0].m_soft->m_selfCollisionImpulseFactor,m_rpos[0]); + m_bodies[1].applyImpulse( impulse*m_bodies[0].m_soft->m_selfCollisionImpulseFactor,m_rpos[1]); + } + } + } + } else + { + m_bodies[0].applyImpulse(-impulse,m_rpos[0]); + m_bodies[1].applyImpulse( impulse,m_rpos[1]); + } +} + +// +void btSoftBody::CJoint::Terminate(btScalar dt) +{ + if(m_split>0) + { + m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); + m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); + } +} + +// +void btSoftBody::applyForces() +{ + + BT_PROFILE("SoftBody applyForces"); +// const btScalar dt = m_sst.sdt; + const btScalar kLF = m_cfg.kLF; + const btScalar kDG = m_cfg.kDG; + const btScalar kPR = m_cfg.kPR; + const btScalar kVC = m_cfg.kVC; + const bool as_lift = kLF>0; + const bool as_drag = kDG>0; + const bool as_pressure = kPR!=0; + const bool as_volume = kVC>0; + const bool as_aero = as_lift || + as_drag ; + //const bool as_vaero = as_aero && + // (m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided); + //const bool as_faero = as_aero && + // (m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided); + const bool use_medium = as_aero; + const bool use_volume = as_pressure || + as_volume ; + btScalar volume = 0; + btScalar ivolumetp = 0; + btScalar dvolumetv = 0; + btSoftBody::sMedium medium; + if(use_volume) + { + volume = getVolume(); + ivolumetp = 1/btFabs(volume)*kPR; + dvolumetv = (m_pose.m_volume-volume)*kVC; + } + /* Per vertex forces */ + int i,ni; + + for(i=0,ni=m_nodes.size();i0) + { + if(use_medium) + { + /* Aerodynamics */ + addAeroForceToNode(m_windVelocity, i); + } + /* Pressure */ + if(as_pressure) + { + n.m_f += n.m_n*(n.m_area*ivolumetp); + } + /* Volume */ + if(as_volume) + { + n.m_f += n.m_n*(n.m_area*dvolumetv); + } + } + } + + /* Per face forces */ + for(i=0,ni=m_faces.size();im_cfg.kAHR*kst; + const btScalar dt=psb->m_sst.sdt; + for(int i=0,ni=psb->m_anchors.size();im_anchors[i]; + const btTransform& t=a.m_body->getWorldTransform(); + Node& n=*a.m_node; + const btVector3 wa=t*a.m_local; + const btVector3 va=a.m_body->getVelocityInLocalPoint(a.m_c1)*dt; + const btVector3 vb=n.m_x-n.m_q; + const btVector3 vr=(va-vb)+(wa-n.m_x)*kAHR; + const btVector3 impulse=a.m_c0*vr*a.m_influence; + n.m_x+=impulse*a.m_c2; + a.m_body->applyImpulse(-impulse,a.m_c1); + } +} + +// +void btSoftBody::PSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar ti) +{ + const btScalar dt = psb->m_sst.sdt; + const btScalar mrg = psb->getCollisionShape()->getMargin(); + for(int i=0,ni=psb->m_rcontacts.size();im_rcontacts[i]; + const sCti& cti = c.m_cti; + btRigidBody* tmpRigid = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + + const btVector3 va = tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0); + const btVector3 vb = c.m_node->m_x-c.m_node->m_q; + const btVector3 vr = vb-va; + const btScalar dn = btDot(vr, cti.m_normal); + if(dn<=SIMD_EPSILON) + { + const btScalar dp = btMin( (btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg ); + const btVector3 fv = vr - (cti.m_normal * dn); + // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient + const btVector3 impulse = c.m_c0 * ( (vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst ); + c.m_node->m_x -= impulse * c.m_c2; + if (tmpRigid) + tmpRigid->applyImpulse(impulse,c.m_c1); + } + } +} + +// +void btSoftBody::PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti) +{ + for(int i=0,ni=psb->m_scontacts.size();im_scontacts[i]; + const btVector3& nr=c.m_normal; + Node& n=*c.m_node; + Face& f=*c.m_face; + const btVector3 p=BaryEval( f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x, + c.m_weights); + const btVector3 q=BaryEval( f.m_n[0]->m_q, + f.m_n[1]->m_q, + f.m_n[2]->m_q, + c.m_weights); + const btVector3 vr=(n.m_x-n.m_q)-(p-q); + btVector3 corr(0,0,0); + btScalar dot = btDot(vr,nr); + if(dot<0) + { + const btScalar j=c.m_margin-(btDot(nr,n.m_x)-btDot(nr,p)); + corr+=c.m_normal*j; + } + corr -= ProjectOnPlane(vr,nr)*c.m_friction; + n.m_x += corr*c.m_cfm[0]; + f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x()); + f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y()); + f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z()); + } +} + +// +void btSoftBody::PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti) +{ + for(int i=0,ni=psb->m_links.size();im_links[i]; + if(l.m_c0>0) + { + Node& a=*l.m_n[0]; + Node& b=*l.m_n[1]; + const btVector3 del=b.m_x-a.m_x; + const btScalar len=del.length2(); + if (l.m_c1+len > SIMD_EPSILON) + { + const btScalar k=((l.m_c1-len)/(l.m_c0*(l.m_c1+len)))*kst; + a.m_x-=del*(k*a.m_im); + b.m_x+=del*(k*b.m_im); + } + } + } +} + +// +void btSoftBody::VSolve_Links(btSoftBody* psb,btScalar kst) +{ + for(int i=0,ni=psb->m_links.size();im_links[i]; + Node** n=l.m_n; + const btScalar j=-btDot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst; + n[0]->m_v+= l.m_c3*(j*n[0]->m_im); + n[1]->m_v-= l.m_c3*(j*n[1]->m_im); + } +} + +// +btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver) +{ + switch(solver) + { + case ePSolver::Anchors: + return(&btSoftBody::PSolve_Anchors); + case ePSolver::Linear: + return(&btSoftBody::PSolve_Links); + case ePSolver::RContacts: + return(&btSoftBody::PSolve_RContacts); + case ePSolver::SContacts: + return(&btSoftBody::PSolve_SContacts); + default: + { + } + } + return(0); +} + +// +btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver) +{ + switch(solver) + { + case eVSolver::Linear: return(&btSoftBody::VSolve_Links); + default: + { + } + } + return(0); +} + +// +void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap) +{ + + switch(m_cfg.collisions&fCollision::RVSmask) + { + case fCollision::SDF_RS: + { + btSoftColliders::CollideSDF_RS docollide; + btRigidBody* prb1=(btRigidBody*) btRigidBody::upcast(pcoWrap->getCollisionObject()); + btTransform wtr=pcoWrap->getWorldTransform(); + + const btTransform ctr=pcoWrap->getWorldTransform(); + const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length(); + const btScalar basemargin=getCollisionShape()->getMargin(); + btVector3 mins; + btVector3 maxs; + ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; + pcoWrap->getCollisionShape()->getAabb( pcoWrap->getWorldTransform(), + mins, + maxs); + volume=btDbvtVolume::FromMM(mins,maxs); + volume.Expand(btVector3(basemargin,basemargin,basemargin)); + docollide.psb = this; + docollide.m_colObj1Wrap = pcoWrap; + docollide.m_rigidBody = prb1; + + docollide.dynmargin = basemargin+timemargin; + docollide.stamargin = basemargin; + m_ndbvt.collideTV(m_ndbvt.m_root,volume,docollide); + } + break; + case fCollision::CL_RS: + { + btSoftColliders::CollideCL_RS collider; + collider.ProcessColObj(this,pcoWrap); + } + break; + } +} + +// +void btSoftBody::defaultCollisionHandler(btSoftBody* psb) +{ + const int cf=m_cfg.collisions&psb->m_cfg.collisions; + switch(cf&fCollision::SVSmask) + { + case fCollision::CL_SS: + { + + //support self-collision if CL_SELF flag set + if (this!=psb || psb->m_cfg.collisions&fCollision::CL_SELF) + { + btSoftColliders::CollideCL_SS docollide; + docollide.ProcessSoftSoft(this,psb); + } + + } + break; + case fCollision::VF_SS: + { + //only self-collision for Cluster, not Vertex-Face yet + if (this!=psb) + { + btSoftColliders::CollideVF_SS docollide; + /* common */ + docollide.mrg= getCollisionShape()->getMargin()+ + psb->getCollisionShape()->getMargin(); + /* psb0 nodes vs psb1 faces */ + docollide.psb[0]=this; + docollide.psb[1]=psb; + docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root, + docollide.psb[1]->m_fdbvt.m_root, + docollide); + /* psb1 nodes vs psb0 faces */ + docollide.psb[0]=psb; + docollide.psb[1]=this; + docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root, + docollide.psb[1]->m_fdbvt.m_root, + docollide); + } + } + break; + default: + { + + } + } +} + + + +void btSoftBody::setWindVelocity( const btVector3 &velocity ) +{ + m_windVelocity = velocity; +} + + +const btVector3& btSoftBody::getWindVelocity() +{ + return m_windVelocity; +} + + + +int btSoftBody::calculateSerializeBufferSize() const +{ + int sz = sizeof(btSoftBodyData); + return sz; +} + + ///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializer) const +{ + btSoftBodyData* sbd = (btSoftBodyData*) dataBuffer; + + btCollisionObject::serialize(&sbd->m_collisionObjectData, serializer); + + btHashMap m_nodeIndexMap; + + sbd->m_numMaterials = m_materials.size(); + sbd->m_materials = sbd->m_numMaterials? (SoftBodyMaterialData**) serializer->getUniquePointer((void*)&m_materials): 0; + + if (sbd->m_materials) + { + int sz = sizeof(SoftBodyMaterialData*); + int numElem = sbd->m_numMaterials; + btChunk* chunk = serializer->allocate(sz,numElem); + //SoftBodyMaterialData** memPtr = chunk->m_oldPtr; + SoftBodyMaterialData** memPtr = (SoftBodyMaterialData**)chunk->m_oldPtr; + for (int i=0;igetUniquePointer((void*)mat) : 0; + if (!serializer->findPointer(mat)) + { + //serialize it here + btChunk* chunk = serializer->allocate(sizeof(SoftBodyMaterialData),1); + SoftBodyMaterialData* memPtr = (SoftBodyMaterialData*)chunk->m_oldPtr; + memPtr->m_flags = mat->m_flags; + memPtr->m_angularStiffness = mat->m_kAST; + memPtr->m_linearStiffness = mat->m_kLST; + memPtr->m_volumeStiffness = mat->m_kVST; + serializer->finalizeChunk(chunk,"SoftBodyMaterialData",BT_SBMATERIAL_CODE,mat); + } + } + serializer->finalizeChunk(chunk,"SoftBodyMaterialData",BT_ARRAY_CODE,(void*) &m_materials); + } + + + + + sbd->m_numNodes = m_nodes.size(); + sbd->m_nodes = sbd->m_numNodes ? (SoftBodyNodeData*)serializer->getUniquePointer((void*)&m_nodes): 0; + if (sbd->m_nodes) + { + int sz = sizeof(SoftBodyNodeData); + int numElem = sbd->m_numNodes; + btChunk* chunk = serializer->allocate(sz,numElem); + SoftBodyNodeData* memPtr = (SoftBodyNodeData*)chunk->m_oldPtr; + for (int i=0;im_accumulatedForce); + memPtr->m_area = m_nodes[i].m_area; + memPtr->m_attach = m_nodes[i].m_battach; + memPtr->m_inverseMass = m_nodes[i].m_im; + memPtr->m_material = m_nodes[i].m_material? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_nodes[i].m_material):0; + m_nodes[i].m_n.serializeFloat(memPtr->m_normal); + m_nodes[i].m_x.serializeFloat(memPtr->m_position); + m_nodes[i].m_q.serializeFloat(memPtr->m_previousPosition); + m_nodes[i].m_v.serializeFloat(memPtr->m_velocity); + m_nodeIndexMap.insert(&m_nodes[i],i); + } + serializer->finalizeChunk(chunk,"SoftBodyNodeData",BT_SBNODE_CODE,(void*) &m_nodes); + } + + sbd->m_numLinks = m_links.size(); + sbd->m_links = sbd->m_numLinks? (SoftBodyLinkData*) serializer->getUniquePointer((void*)&m_links[0]):0; + if (sbd->m_links) + { + int sz = sizeof(SoftBodyLinkData); + int numElem = sbd->m_numLinks; + btChunk* chunk = serializer->allocate(sz,numElem); + SoftBodyLinkData* memPtr = (SoftBodyLinkData*)chunk->m_oldPtr; + for (int i=0;im_bbending = m_links[i].m_bbending; + memPtr->m_material = m_links[i].m_material? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_links[i].m_material):0; + memPtr->m_nodeIndices[0] = m_links[i].m_n[0] ? m_links[i].m_n[0] - &m_nodes[0]: -1; + memPtr->m_nodeIndices[1] = m_links[i].m_n[1] ? m_links[i].m_n[1] - &m_nodes[0]: -1; + btAssert(memPtr->m_nodeIndices[0]m_nodeIndices[1]m_restLength = m_links[i].m_rl; + } + serializer->finalizeChunk(chunk,"SoftBodyLinkData",BT_ARRAY_CODE,(void*) &m_links[0]); + + } + + + sbd->m_numFaces = m_faces.size(); + sbd->m_faces = sbd->m_numFaces? (SoftBodyFaceData*) serializer->getUniquePointer((void*)&m_faces[0]):0; + if (sbd->m_faces) + { + int sz = sizeof(SoftBodyFaceData); + int numElem = sbd->m_numFaces; + btChunk* chunk = serializer->allocate(sz,numElem); + SoftBodyFaceData* memPtr = (SoftBodyFaceData*)chunk->m_oldPtr; + for (int i=0;im_material = m_faces[i].m_material ? (SoftBodyMaterialData*) serializer->getUniquePointer((void*)m_faces[i].m_material): 0; + m_faces[i].m_normal.serializeFloat( memPtr->m_normal); + for (int j=0;j<3;j++) + { + memPtr->m_nodeIndices[j] = m_faces[i].m_n[j]? m_faces[i].m_n[j] - &m_nodes[0]: -1; + } + memPtr->m_restArea = m_faces[i].m_ra; + } + serializer->finalizeChunk(chunk,"SoftBodyFaceData",BT_ARRAY_CODE,(void*) &m_faces[0]); + } + + + sbd->m_numTetrahedra = m_tetras.size(); + sbd->m_tetrahedra = sbd->m_numTetrahedra ? (SoftBodyTetraData*) serializer->getUniquePointer((void*)&m_tetras[0]):0; + if (sbd->m_tetrahedra) + { + int sz = sizeof(SoftBodyTetraData); + int numElem = sbd->m_numTetrahedra; + btChunk* chunk = serializer->allocate(sz,numElem); + SoftBodyTetraData* memPtr = (SoftBodyTetraData*)chunk->m_oldPtr; + for (int i=0;im_c0[j] ); + memPtr->m_nodeIndices[j] = m_tetras[j].m_n[j]? m_tetras[j].m_n[j]-&m_nodes[0] : -1; + } + memPtr->m_c1 = m_tetras[i].m_c1; + memPtr->m_c2 = m_tetras[i].m_c2; + memPtr->m_material = m_tetras[i].m_material ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_tetras[i].m_material): 0; + memPtr->m_restVolume = m_tetras[i].m_rv; + } + serializer->finalizeChunk(chunk,"SoftBodyTetraData",BT_ARRAY_CODE,(void*) &m_tetras[0]); + } + + sbd->m_numAnchors = m_anchors.size(); + sbd->m_anchors = sbd->m_numAnchors ? (SoftRigidAnchorData*) serializer->getUniquePointer((void*)&m_anchors[0]):0; + if (sbd->m_anchors) + { + int sz = sizeof(SoftRigidAnchorData); + int numElem = sbd->m_numAnchors; + btChunk* chunk = serializer->allocate(sz,numElem); + SoftRigidAnchorData* memPtr = (SoftRigidAnchorData*)chunk->m_oldPtr; + for (int i=0;im_c0); + m_anchors[i].m_c1.serializeFloat(memPtr->m_c1); + memPtr->m_c2 = m_anchors[i].m_c2; + m_anchors[i].m_local.serializeFloat(memPtr->m_localFrame); + memPtr->m_nodeIndex = m_anchors[i].m_node? m_anchors[i].m_node-&m_nodes[0]: -1; + + memPtr->m_rigidBody = m_anchors[i].m_body? (btRigidBodyData*) serializer->getUniquePointer((void*)m_anchors[i].m_body): 0; + btAssert(memPtr->m_nodeIndex < m_nodes.size()); + } + serializer->finalizeChunk(chunk,"SoftRigidAnchorData",BT_ARRAY_CODE,(void*) &m_anchors[0]); + } + + + sbd->m_config.m_dynamicFriction = m_cfg.kDF; + sbd->m_config.m_baumgarte = m_cfg.kVCF; + sbd->m_config.m_pressure = m_cfg.kPR; + sbd->m_config.m_aeroModel = this->m_cfg.aeromodel; + sbd->m_config.m_lift = m_cfg.kLF; + sbd->m_config.m_drag = m_cfg.kDG; + sbd->m_config.m_positionIterations = m_cfg.piterations; + sbd->m_config.m_driftIterations = m_cfg.diterations; + sbd->m_config.m_clusterIterations = m_cfg.citerations; + sbd->m_config.m_velocityIterations = m_cfg.viterations; + sbd->m_config.m_maxVolume = m_cfg.maxvolume; + sbd->m_config.m_damping = m_cfg.kDP; + sbd->m_config.m_poseMatch = m_cfg.kMT; + sbd->m_config.m_collisionFlags = m_cfg.collisions; + sbd->m_config.m_volume = m_cfg.kVC; + sbd->m_config.m_rigidContactHardness = m_cfg.kCHR; + sbd->m_config.m_kineticContactHardness = m_cfg.kKHR; + sbd->m_config.m_softContactHardness = m_cfg.kSHR; + sbd->m_config.m_anchorHardness = m_cfg.kAHR; + sbd->m_config.m_timeScale = m_cfg.timescale; + sbd->m_config.m_maxVolume = m_cfg.maxvolume; + sbd->m_config.m_softRigidClusterHardness = m_cfg.kSRHR_CL; + sbd->m_config.m_softKineticClusterHardness = m_cfg.kSKHR_CL; + sbd->m_config.m_softSoftClusterHardness = m_cfg.kSSHR_CL; + sbd->m_config.m_softRigidClusterImpulseSplit = m_cfg.kSR_SPLT_CL; + sbd->m_config.m_softKineticClusterImpulseSplit = m_cfg.kSK_SPLT_CL; + sbd->m_config.m_softSoftClusterImpulseSplit = m_cfg.kSS_SPLT_CL; + + //pose for shape matching + { + sbd->m_pose = (SoftBodyPoseData*)serializer->getUniquePointer((void*)&m_pose); + + int sz = sizeof(SoftBodyPoseData); + btChunk* chunk = serializer->allocate(sz,1); + SoftBodyPoseData* memPtr = (SoftBodyPoseData*)chunk->m_oldPtr; + + m_pose.m_aqq.serializeFloat(memPtr->m_aqq); + memPtr->m_bframe = m_pose.m_bframe; + memPtr->m_bvolume = m_pose.m_bvolume; + m_pose.m_com.serializeFloat(memPtr->m_com); + + memPtr->m_numPositions = m_pose.m_pos.size(); + memPtr->m_positions = memPtr->m_numPositions ? (btVector3FloatData*)serializer->getUniquePointer((void*)&m_pose.m_pos[0]): 0; + if (memPtr->m_numPositions) + { + int numElem = memPtr->m_numPositions; + int sz = sizeof(btVector3Data); + btChunk* chunk = serializer->allocate(sz,numElem); + btVector3FloatData* memPtr = (btVector3FloatData*)chunk->m_oldPtr; + for (int i=0;ifinalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)&m_pose.m_pos[0]); + } + memPtr->m_restVolume = m_pose.m_volume; + m_pose.m_rot.serializeFloat(memPtr->m_rot); + m_pose.m_scl.serializeFloat(memPtr->m_scale); + + memPtr->m_numWeigts = m_pose.m_wgh.size(); + memPtr->m_weights = memPtr->m_numWeigts? (float*) serializer->getUniquePointer((void*) &m_pose.m_wgh[0]) : 0; + if (memPtr->m_numWeigts) + { + + int numElem = memPtr->m_numWeigts; + int sz = sizeof(float); + btChunk* chunk = serializer->allocate(sz,numElem); + float* memPtr = (float*) chunk->m_oldPtr; + for (int i=0;ifinalizeChunk(chunk,"float",BT_ARRAY_CODE,(void*)&m_pose.m_wgh[0]); + } + + serializer->finalizeChunk(chunk,"SoftBodyPoseData",BT_ARRAY_CODE,(void*)&m_pose); + } + + //clusters for convex-cluster collision detection + + sbd->m_numClusters = m_clusters.size(); + sbd->m_clusters = sbd->m_numClusters? (SoftBodyClusterData*) serializer->getUniquePointer((void*)m_clusters[0]) : 0; + if (sbd->m_numClusters) + { + int numElem = sbd->m_numClusters; + int sz = sizeof(SoftBodyClusterData); + btChunk* chunk = serializer->allocate(sz,numElem); + SoftBodyClusterData* memPtr = (SoftBodyClusterData*) chunk->m_oldPtr; + for (int i=0;im_adamping= m_clusters[i]->m_adamping; + m_clusters[i]->m_av.serializeFloat(memPtr->m_av); + memPtr->m_clusterIndex = m_clusters[i]->m_clusterIndex; + memPtr->m_collide = m_clusters[i]->m_collide; + m_clusters[i]->m_com.serializeFloat(memPtr->m_com); + memPtr->m_containsAnchor = m_clusters[i]->m_containsAnchor; + m_clusters[i]->m_dimpulses[0].serializeFloat(memPtr->m_dimpulses[0]); + m_clusters[i]->m_dimpulses[1].serializeFloat(memPtr->m_dimpulses[1]); + m_clusters[i]->m_framexform.serializeFloat(memPtr->m_framexform); + memPtr->m_idmass = m_clusters[i]->m_idmass; + memPtr->m_imass = m_clusters[i]->m_imass; + m_clusters[i]->m_invwi.serializeFloat(memPtr->m_invwi); + memPtr->m_ldamping = m_clusters[i]->m_ldamping; + m_clusters[i]->m_locii.serializeFloat(memPtr->m_locii); + m_clusters[i]->m_lv.serializeFloat(memPtr->m_lv); + memPtr->m_matching = m_clusters[i]->m_matching; + memPtr->m_maxSelfCollisionImpulse = m_clusters[i]->m_maxSelfCollisionImpulse; + memPtr->m_ndamping = m_clusters[i]->m_ndamping; + memPtr->m_ldamping = m_clusters[i]->m_ldamping; + memPtr->m_adamping = m_clusters[i]->m_adamping; + memPtr->m_selfCollisionImpulseFactor = m_clusters[i]->m_selfCollisionImpulseFactor; + + memPtr->m_numFrameRefs = m_clusters[i]->m_framerefs.size(); + memPtr->m_numMasses = m_clusters[i]->m_masses.size(); + memPtr->m_numNodes = m_clusters[i]->m_nodes.size(); + + memPtr->m_nvimpulses = m_clusters[i]->m_nvimpulses; + m_clusters[i]->m_vimpulses[0].serializeFloat(memPtr->m_vimpulses[0]); + m_clusters[i]->m_vimpulses[1].serializeFloat(memPtr->m_vimpulses[1]); + memPtr->m_ndimpulses = m_clusters[i]->m_ndimpulses; + + + + memPtr->m_framerefs = memPtr->m_numFrameRefs? (btVector3FloatData*)serializer->getUniquePointer((void*)&m_clusters[i]->m_framerefs[0]) : 0; + if (memPtr->m_framerefs) + { + int numElem = memPtr->m_numFrameRefs; + int sz = sizeof(btVector3FloatData); + btChunk* chunk = serializer->allocate(sz,numElem); + btVector3FloatData* memPtr = (btVector3FloatData*) chunk->m_oldPtr; + for (int j=0;jm_framerefs[j].serializeFloat(*memPtr); + } + serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)&m_clusters[i]->m_framerefs[0]); + } + + memPtr->m_masses = memPtr->m_numMasses ? (float*) serializer->getUniquePointer((void*)&m_clusters[i]->m_masses[0]): 0; + if (memPtr->m_masses) + { + int numElem = memPtr->m_numMasses; + int sz = sizeof(float); + btChunk* chunk = serializer->allocate(sz,numElem); + float* memPtr = (float*) chunk->m_oldPtr; + for (int j=0;jm_masses[j]; + } + serializer->finalizeChunk(chunk,"float",BT_ARRAY_CODE,(void*)&m_clusters[i]->m_masses[0]); + } + + memPtr->m_nodeIndices = memPtr->m_numNodes ? (int*) serializer->getUniquePointer((void*) &m_clusters[i]->m_nodes) : 0; + if (memPtr->m_nodeIndices ) + { + int numElem = memPtr->m_numMasses; + int sz = sizeof(int); + btChunk* chunk = serializer->allocate(sz,numElem); + int* memPtr = (int*) chunk->m_oldPtr; + for (int j=0;jm_nodes[j]); + btAssert(indexPtr); + *memPtr = *indexPtr; + } + serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_clusters[i]->m_nodes); + } + } + serializer->finalizeChunk(chunk,"SoftBodyClusterData",BT_ARRAY_CODE,(void*)m_clusters[0]); + + } + + + + sbd->m_numJoints = m_joints.size(); + sbd->m_joints = m_joints.size()? (btSoftBodyJointData*) serializer->getUniquePointer((void*)&m_joints[0]) : 0; + + if (sbd->m_joints) + { + int sz = sizeof(btSoftBodyJointData); + int numElem = m_joints.size(); + btChunk* chunk = serializer->allocate(sz,numElem); + btSoftBodyJointData* memPtr = (btSoftBodyJointData*)chunk->m_oldPtr; + + for (int i=0;im_jointType = (int)m_joints[i]->Type(); + m_joints[i]->m_refs[0].serializeFloat(memPtr->m_refs[0]); + m_joints[i]->m_refs[1].serializeFloat(memPtr->m_refs[1]); + memPtr->m_cfm = m_joints[i]->m_cfm; + memPtr->m_erp = m_joints[i]->m_erp; + memPtr->m_split = m_joints[i]->m_split; + memPtr->m_delete = m_joints[i]->m_delete; + + for (int j=0;j<4;j++) + { + memPtr->m_relPosition[0].m_floats[j] = 0.f; + memPtr->m_relPosition[1].m_floats[j] = 0.f; + } + memPtr->m_bodyA = 0; + memPtr->m_bodyB = 0; + if (m_joints[i]->m_bodies[0].m_soft) + { + memPtr->m_bodyAtype = BT_JOINT_SOFT_BODY_CLUSTER; + memPtr->m_bodyA = serializer->getUniquePointer((void*)m_joints[i]->m_bodies[0].m_soft); + } + if (m_joints[i]->m_bodies[0].m_collisionObject) + { + memPtr->m_bodyAtype = BT_JOINT_COLLISION_OBJECT; + memPtr->m_bodyA = serializer->getUniquePointer((void*)m_joints[i]->m_bodies[0].m_collisionObject); + } + if (m_joints[i]->m_bodies[0].m_rigid) + { + memPtr->m_bodyAtype = BT_JOINT_RIGID_BODY; + memPtr->m_bodyA = serializer->getUniquePointer((void*)m_joints[i]->m_bodies[0].m_rigid); + } + + if (m_joints[i]->m_bodies[1].m_soft) + { + memPtr->m_bodyBtype = BT_JOINT_SOFT_BODY_CLUSTER; + memPtr->m_bodyB = serializer->getUniquePointer((void*)m_joints[i]->m_bodies[1].m_soft); + } + if (m_joints[i]->m_bodies[1].m_collisionObject) + { + memPtr->m_bodyBtype = BT_JOINT_COLLISION_OBJECT; + memPtr->m_bodyB = serializer->getUniquePointer((void*)m_joints[i]->m_bodies[1].m_collisionObject); + } + if (m_joints[i]->m_bodies[1].m_rigid) + { + memPtr->m_bodyBtype = BT_JOINT_RIGID_BODY; + memPtr->m_bodyB = serializer->getUniquePointer((void*)m_joints[i]->m_bodies[1].m_rigid); + } + } + serializer->finalizeChunk(chunk,"btSoftBodyJointData",BT_ARRAY_CODE,(void*) &m_joints[0]); + } + + + return btSoftBodyDataName; +} + diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h new file mode 100644 index 0000000..2116c34 --- /dev/null +++ b/src/BulletSoftBody/btSoftBody.h @@ -0,0 +1,998 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +///btSoftBody implementation by Nathanael Presson + +#ifndef _BT_SOFT_BODY_H +#define _BT_SOFT_BODY_H + +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + +#include "BulletCollision/CollisionShapes/btConcaveShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +#include "btSparseSDF.h" +#include "BulletCollision/BroadphaseCollision/btDbvt.h" + +//#ifdef BT_USE_DOUBLE_PRECISION +//#define btRigidBodyData btRigidBodyDoubleData +//#define btRigidBodyDataName "btRigidBodyDoubleData" +//#else +#define btSoftBodyData btSoftBodyFloatData +#define btSoftBodyDataName "btSoftBodyFloatData" +//#endif //BT_USE_DOUBLE_PRECISION + +class btBroadphaseInterface; +class btDispatcher; +class btSoftBodySolver; + +/* btSoftBodyWorldInfo */ +struct btSoftBodyWorldInfo +{ + btScalar air_density; + btScalar water_density; + btScalar water_offset; + btVector3 water_normal; + btBroadphaseInterface* m_broadphase; + btDispatcher* m_dispatcher; + btVector3 m_gravity; + btSparseSdf<3> m_sparsesdf; + + btSoftBodyWorldInfo() + :air_density((btScalar)1.2), + water_density(0), + water_offset(0), + water_normal(0,0,0), + m_broadphase(0), + m_dispatcher(0), + m_gravity(0,-10,0) + { + } +}; + + +///The btSoftBody is an class to simulate cloth and volumetric soft bodies. +///There is two-way interaction between btSoftBody and btRigidBody/btCollisionObject. +class btSoftBody : public btCollisionObject +{ +public: + btAlignedObjectArray m_collisionDisabledObjects; + + // The solver object that handles this soft body + btSoftBodySolver *m_softBodySolver; + + // + // Enumerations + // + + ///eAeroModel + struct eAeroModel { enum _ { + V_Point, ///Vertex normals are oriented toward velocity + V_TwoSided, ///Vertex normals are flipped to match velocity + V_TwoSidedLiftDrag, ///Vertex normals are flipped to match velocity and lift and drag forces are applied + V_OneSided, ///Vertex normals are taken as it is + F_TwoSided, ///Face normals are flipped to match velocity + F_TwoSidedLiftDrag, ///Face normals are flipped to match velocity and lift and drag forces are applied + F_OneSided, ///Face normals are taken as it is + END + };}; + + ///eVSolver : velocities solvers + struct eVSolver { enum _ { + Linear, ///Linear solver + END + };}; + + ///ePSolver : positions solvers + struct ePSolver { enum _ { + Linear, ///Linear solver + Anchors, ///Anchor solver + RContacts, ///Rigid contacts solver + SContacts, ///Soft contacts solver + END + };}; + + ///eSolverPresets + struct eSolverPresets { enum _ { + Positions, + Velocities, + Default = Positions, + END + };}; + + ///eFeature + struct eFeature { enum _ { + None, + Node, + Link, + Face, + Tetra, + END + };}; + + typedef btAlignedObjectArray tVSolverArray; + typedef btAlignedObjectArray tPSolverArray; + + // + // Flags + // + + ///fCollision + struct fCollision { enum _ { + RVSmask = 0x000f, ///Rigid versus soft mask + SDF_RS = 0x0001, ///SDF based rigid vs soft + CL_RS = 0x0002, ///Cluster vs convex rigid vs soft + + SVSmask = 0x0030, ///Rigid versus soft mask + VF_SS = 0x0010, ///Vertex vs face soft vs soft handling + CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling + CL_SELF = 0x0040, ///Cluster soft body self collision + /* presets */ + Default = SDF_RS, + END + };}; + + ///fMaterial + struct fMaterial { enum _ { + DebugDraw = 0x0001, /// Enable debug draw + /* presets */ + Default = DebugDraw, + END + };}; + + // + // API Types + // + + /* sRayCast */ + struct sRayCast + { + btSoftBody* body; /// soft body + eFeature::_ feature; /// feature type + int index; /// feature index + btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction) + }; + + /* ImplicitFn */ + struct ImplicitFn + { + virtual btScalar Eval(const btVector3& x)=0; + }; + + // + // Internal types + // + + typedef btAlignedObjectArray tScalarArray; + typedef btAlignedObjectArray tVector3Array; + + /* sCti is Softbody contact info */ + struct sCti + { + const btCollisionObject* m_colObj; /* Rigid body */ + btVector3 m_normal; /* Outward normal */ + btScalar m_offset; /* Offset from origin */ + }; + + /* sMedium */ + struct sMedium + { + btVector3 m_velocity; /* Velocity */ + btScalar m_pressure; /* Pressure */ + btScalar m_density; /* Density */ + }; + + /* Base type */ + struct Element + { + void* m_tag; // User data + Element() : m_tag(0) {} + }; + /* Material */ + struct Material : Element + { + btScalar m_kLST; // Linear stiffness coefficient [0,1] + btScalar m_kAST; // Area/Angular stiffness coefficient [0,1] + btScalar m_kVST; // Volume stiffness coefficient [0,1] + int m_flags; // Flags + }; + + /* Feature */ + struct Feature : Element + { + Material* m_material; // Material + }; + /* Node */ + struct Node : Feature + { + btVector3 m_x; // Position + btVector3 m_q; // Previous step position + btVector3 m_v; // Velocity + btVector3 m_f; // Force accumulator + btVector3 m_n; // Normal + btScalar m_im; // 1/mass + btScalar m_area; // Area + btDbvtNode* m_leaf; // Leaf data + int m_battach:1; // Attached + }; + /* Link */ + struct Link : Feature + { + Node* m_n[2]; // Node pointers + btScalar m_rl; // Rest length + int m_bbending:1; // Bending link + btScalar m_c0; // (ima+imb)*kLST + btScalar m_c1; // rl^2 + btScalar m_c2; // |gradient|^2/c0 + btVector3 m_c3; // gradient + }; + /* Face */ + struct Face : Feature + { + Node* m_n[3]; // Node pointers + btVector3 m_normal; // Normal + btScalar m_ra; // Rest area + btDbvtNode* m_leaf; // Leaf data + }; + /* Tetra */ + struct Tetra : Feature + { + Node* m_n[4]; // Node pointers + btScalar m_rv; // Rest volume + btDbvtNode* m_leaf; // Leaf data + btVector3 m_c0[4]; // gradients + btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3) + btScalar m_c2; // m_c1/sum(|g0..3|^2) + }; + /* RContact */ + struct RContact + { + sCti m_cti; // Contact infos + Node* m_node; // Owner node + btMatrix3x3 m_c0; // Impulse matrix + btVector3 m_c1; // Relative anchor + btScalar m_c2; // ima*dt + btScalar m_c3; // Friction + btScalar m_c4; // Hardness + }; + /* SContact */ + struct SContact + { + Node* m_node; // Node + Face* m_face; // Face + btVector3 m_weights; // Weigths + btVector3 m_normal; // Normal + btScalar m_margin; // Margin + btScalar m_friction; // Friction + btScalar m_cfm[2]; // Constraint force mixing + }; + /* Anchor */ + struct Anchor + { + Node* m_node; // Node pointer + btVector3 m_local; // Anchor position in body space + btRigidBody* m_body; // Body + btScalar m_influence; + btMatrix3x3 m_c0; // Impulse matrix + btVector3 m_c1; // Relative anchor + btScalar m_c2; // ima*dt + }; + /* Note */ + struct Note : Element + { + const char* m_text; // Text + btVector3 m_offset; // Offset + int m_rank; // Rank + Node* m_nodes[4]; // Nodes + btScalar m_coords[4]; // Coordinates + }; + /* Pose */ + struct Pose + { + bool m_bvolume; // Is valid + bool m_bframe; // Is frame + btScalar m_volume; // Rest volume + tVector3Array m_pos; // Reference positions + tScalarArray m_wgh; // Weights + btVector3 m_com; // COM + btMatrix3x3 m_rot; // Rotation + btMatrix3x3 m_scl; // Scale + btMatrix3x3 m_aqq; // Base scaling + }; + /* Cluster */ + struct Cluster + { + tScalarArray m_masses; + btAlignedObjectArray m_nodes; + tVector3Array m_framerefs; + btTransform m_framexform; + btScalar m_idmass; + btScalar m_imass; + btMatrix3x3 m_locii; + btMatrix3x3 m_invwi; + btVector3 m_com; + btVector3 m_vimpulses[2]; + btVector3 m_dimpulses[2]; + int m_nvimpulses; + int m_ndimpulses; + btVector3 m_lv; + btVector3 m_av; + btDbvtNode* m_leaf; + btScalar m_ndamping; /* Node damping */ + btScalar m_ldamping; /* Linear damping */ + btScalar m_adamping; /* Angular damping */ + btScalar m_matching; + btScalar m_maxSelfCollisionImpulse; + btScalar m_selfCollisionImpulseFactor; + bool m_containsAnchor; + bool m_collide; + int m_clusterIndex; + Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) + ,m_maxSelfCollisionImpulse(100.f), + m_selfCollisionImpulseFactor(0.01f), + m_containsAnchor(false) + {} + }; + /* Impulse */ + struct Impulse + { + btVector3 m_velocity; + btVector3 m_drift; + int m_asVelocity:1; + int m_asDrift:1; + Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {} + Impulse operator -() const + { + Impulse i=*this; + i.m_velocity=-i.m_velocity; + i.m_drift=-i.m_drift; + return(i); + } + Impulse operator*(btScalar x) const + { + Impulse i=*this; + i.m_velocity*=x; + i.m_drift*=x; + return(i); + } + }; + /* Body */ + struct Body + { + Cluster* m_soft; + btRigidBody* m_rigid; + const btCollisionObject* m_collisionObject; + + Body() : m_soft(0),m_rigid(0),m_collisionObject(0) {} + Body(Cluster* p) : m_soft(p),m_rigid(0),m_collisionObject(0) {} + Body(const btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj) + { + m_rigid = (btRigidBody*)btRigidBody::upcast(m_collisionObject); + } + + void activate() const + { + if(m_rigid) + m_rigid->activate(); + if (m_collisionObject) + m_collisionObject->activate(); + + } + const btMatrix3x3& invWorldInertia() const + { + static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0); + if(m_rigid) return(m_rigid->getInvInertiaTensorWorld()); + if(m_soft) return(m_soft->m_invwi); + return(iwi); + } + btScalar invMass() const + { + if(m_rigid) return(m_rigid->getInvMass()); + if(m_soft) return(m_soft->m_imass); + return(0); + } + const btTransform& xform() const + { + static const btTransform identity=btTransform::getIdentity(); + if(m_collisionObject) return(m_collisionObject->getWorldTransform()); + if(m_soft) return(m_soft->m_framexform); + return(identity); + } + btVector3 linearVelocity() const + { + if(m_rigid) return(m_rigid->getLinearVelocity()); + if(m_soft) return(m_soft->m_lv); + return(btVector3(0,0,0)); + } + btVector3 angularVelocity(const btVector3& rpos) const + { + if(m_rigid) return(btCross(m_rigid->getAngularVelocity(),rpos)); + if(m_soft) return(btCross(m_soft->m_av,rpos)); + return(btVector3(0,0,0)); + } + btVector3 angularVelocity() const + { + if(m_rigid) return(m_rigid->getAngularVelocity()); + if(m_soft) return(m_soft->m_av); + return(btVector3(0,0,0)); + } + btVector3 velocity(const btVector3& rpos) const + { + return(linearVelocity()+angularVelocity(rpos)); + } + void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const + { + if(m_rigid) m_rigid->applyImpulse(impulse,rpos); + if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse); + } + void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const + { + if(m_rigid) m_rigid->applyImpulse(impulse,rpos); + if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse); + } + void applyImpulse(const Impulse& impulse,const btVector3& rpos) const + { + if(impulse.m_asVelocity) + { +// printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ()); + applyVImpulse(impulse.m_velocity,rpos); + } + if(impulse.m_asDrift) + { +// printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ()); + applyDImpulse(impulse.m_drift,rpos); + } + } + void applyVAImpulse(const btVector3& impulse) const + { + if(m_rigid) m_rigid->applyTorqueImpulse(impulse); + if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse); + } + void applyDAImpulse(const btVector3& impulse) const + { + if(m_rigid) m_rigid->applyTorqueImpulse(impulse); + if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse); + } + void applyAImpulse(const Impulse& impulse) const + { + if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity); + if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift); + } + void applyDCImpulse(const btVector3& impulse) const + { + if(m_rigid) m_rigid->applyCentralImpulse(impulse); + if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse); + } + }; + /* Joint */ + struct Joint + { + struct eType { enum _ { + Linear=0, + Angular, + Contact + };}; + struct Specs + { + Specs() : erp(1),cfm(1),split(1) {} + btScalar erp; + btScalar cfm; + btScalar split; + }; + Body m_bodies[2]; + btVector3 m_refs[2]; + btScalar m_cfm; + btScalar m_erp; + btScalar m_split; + btVector3 m_drift; + btVector3 m_sdrift; + btMatrix3x3 m_massmatrix; + bool m_delete; + virtual ~Joint() {} + Joint() : m_delete(false) {} + virtual void Prepare(btScalar dt,int iterations); + virtual void Solve(btScalar dt,btScalar sor)=0; + virtual void Terminate(btScalar dt)=0; + virtual eType::_ Type() const=0; + }; + /* LJoint */ + struct LJoint : Joint + { + struct Specs : Joint::Specs + { + btVector3 position; + }; + btVector3 m_rpos[2]; + void Prepare(btScalar dt,int iterations); + void Solve(btScalar dt,btScalar sor); + void Terminate(btScalar dt); + eType::_ Type() const { return(eType::Linear); } + }; + /* AJoint */ + struct AJoint : Joint + { + struct IControl + { + virtual void Prepare(AJoint*) {} + virtual btScalar Speed(AJoint*,btScalar current) { return(current); } + static IControl* Default() { static IControl def;return(&def); } + }; + struct Specs : Joint::Specs + { + Specs() : icontrol(IControl::Default()) {} + btVector3 axis; + IControl* icontrol; + }; + btVector3 m_axis[2]; + IControl* m_icontrol; + void Prepare(btScalar dt,int iterations); + void Solve(btScalar dt,btScalar sor); + void Terminate(btScalar dt); + eType::_ Type() const { return(eType::Angular); } + }; + /* CJoint */ + struct CJoint : Joint + { + int m_life; + int m_maxlife; + btVector3 m_rpos[2]; + btVector3 m_normal; + btScalar m_friction; + void Prepare(btScalar dt,int iterations); + void Solve(btScalar dt,btScalar sor); + void Terminate(btScalar dt); + eType::_ Type() const { return(eType::Contact); } + }; + /* Config */ + struct Config + { + eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point) + btScalar kVCF; // Velocities correction factor (Baumgarte) + btScalar kDP; // Damping coefficient [0,1] + btScalar kDG; // Drag coefficient [0,+inf] + btScalar kLF; // Lift coefficient [0,+inf] + btScalar kPR; // Pressure coefficient [-inf,+inf] + btScalar kVC; // Volume conversation coefficient [0,+inf] + btScalar kDF; // Dynamic friction coefficient [0,1] + btScalar kMT; // Pose matching coefficient [0,1] + btScalar kCHR; // Rigid contacts hardness [0,1] + btScalar kKHR; // Kinetic contacts hardness [0,1] + btScalar kSHR; // Soft contacts hardness [0,1] + btScalar kAHR; // Anchors hardness [0,1] + btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only) + btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only) + btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only) + btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) + btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) + btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) + btScalar maxvolume; // Maximum volume ratio for pose + btScalar timescale; // Time scale + int viterations; // Velocities solver iterations + int piterations; // Positions solver iterations + int diterations; // Drift solver iterations + int citerations; // Cluster solver iterations + int collisions; // Collisions flags + tVSolverArray m_vsequence; // Velocity solvers sequence + tPSolverArray m_psequence; // Position solvers sequence + tPSolverArray m_dsequence; // Drift solvers sequence + }; + /* SolverState */ + struct SolverState + { + btScalar sdt; // dt*timescale + btScalar isdt; // 1/sdt + btScalar velmrg; // velocity margin + btScalar radmrg; // radial margin + btScalar updmrg; // Update margin + }; + /// RayFromToCaster takes a ray from, ray to (instead of direction!) + struct RayFromToCaster : btDbvt::ICollide + { + btVector3 m_rayFrom; + btVector3 m_rayTo; + btVector3 m_rayNormalizedDirection; + btScalar m_mint; + Face* m_face; + int m_tests; + RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt); + void Process(const btDbvtNode* leaf); + + static inline btScalar rayFromToTriangle(const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& rayNormalizedDirection, + const btVector3& a, + const btVector3& b, + const btVector3& c, + btScalar maxt=SIMD_INFINITY); + }; + + // + // Typedefs + // + + typedef void (*psolver_t)(btSoftBody*,btScalar,btScalar); + typedef void (*vsolver_t)(btSoftBody*,btScalar); + typedef btAlignedObjectArray tClusterArray; + typedef btAlignedObjectArray tNoteArray; + typedef btAlignedObjectArray tNodeArray; + typedef btAlignedObjectArray tLeafArray; + typedef btAlignedObjectArray tLinkArray; + typedef btAlignedObjectArray tFaceArray; + typedef btAlignedObjectArray tTetraArray; + typedef btAlignedObjectArray tAnchorArray; + typedef btAlignedObjectArray tRContactArray; + typedef btAlignedObjectArray tSContactArray; + typedef btAlignedObjectArray tMaterialArray; + typedef btAlignedObjectArray tJointArray; + typedef btAlignedObjectArray tSoftBodyArray; + + // + // Fields + // + + Config m_cfg; // Configuration + SolverState m_sst; // Solver state + Pose m_pose; // Pose + void* m_tag; // User data + btSoftBodyWorldInfo* m_worldInfo; // World info + tNoteArray m_notes; // Notes + tNodeArray m_nodes; // Nodes + tLinkArray m_links; // Links + tFaceArray m_faces; // Faces + tTetraArray m_tetras; // Tetras + tAnchorArray m_anchors; // Anchors + tRContactArray m_rcontacts; // Rigid contacts + tSContactArray m_scontacts; // Soft contacts + tJointArray m_joints; // Joints + tMaterialArray m_materials; // Materials + btScalar m_timeacc; // Time accumulator + btVector3 m_bounds[2]; // Spatial bounds + bool m_bUpdateRtCst; // Update runtime constants + btDbvt m_ndbvt; // Nodes tree + btDbvt m_fdbvt; // Faces tree + btDbvt m_cdbvt; // Clusters tree + tClusterArray m_clusters; // Clusters + + btAlignedObjectArraym_clusterConnectivity;//cluster connectivity, for self-collision + + btTransform m_initialWorldTransform; + + btVector3 m_windVelocity; + + btScalar m_restLengthScale; + + // + // Api + // + + /* ctor */ + btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m); + + /* ctor */ + btSoftBody( btSoftBodyWorldInfo* worldInfo); + + void initDefaults(); + + /* dtor */ + virtual ~btSoftBody(); + /* Check for existing link */ + + btAlignedObjectArray m_userIndexMapping; + + btSoftBodyWorldInfo* getWorldInfo() + { + return m_worldInfo; + } + + ///@todo: avoid internal softbody shape hack and move collision code to collision library + virtual void setCollisionShape(btCollisionShape* collisionShape) + { + + } + + bool checkLink( int node0, + int node1) const; + bool checkLink( const Node* node0, + const Node* node1) const; + /* Check for existring face */ + bool checkFace( int node0, + int node1, + int node2) const; + /* Append material */ + Material* appendMaterial(); + /* Append note */ + void appendNote( const char* text, + const btVector3& o, + const btVector4& c=btVector4(1,0,0,0), + Node* n0=0, + Node* n1=0, + Node* n2=0, + Node* n3=0); + void appendNote( const char* text, + const btVector3& o, + Node* feature); + void appendNote( const char* text, + const btVector3& o, + Link* feature); + void appendNote( const char* text, + const btVector3& o, + Face* feature); + /* Append node */ + void appendNode( const btVector3& x,btScalar m); + /* Append link */ + void appendLink(int model=-1,Material* mat=0); + void appendLink( int node0, + int node1, + Material* mat=0, + bool bcheckexist=false); + void appendLink( Node* node0, + Node* node1, + Material* mat=0, + bool bcheckexist=false); + /* Append face */ + void appendFace(int model=-1,Material* mat=0); + void appendFace( int node0, + int node1, + int node2, + Material* mat=0); + void appendTetra(int model,Material* mat); + // + void appendTetra(int node0, + int node1, + int node2, + int node3, + Material* mat=0); + + + /* Append anchor */ + void appendAnchor( int node, + btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1); + void appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1); + /* Append linear joint */ + void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1); + void appendLinearJoint(const LJoint::Specs& specs,Body body=Body()); + void appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body); + /* Append linear joint */ + void appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1); + void appendAngularJoint(const AJoint::Specs& specs,Body body=Body()); + void appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body); + /* Add force (or gravity) to the entire body */ + void addForce( const btVector3& force); + /* Add force (or gravity) to a node of the body */ + void addForce( const btVector3& force, + int node); + /* Add aero force to a node of the body */ + void addAeroForceToNode(const btVector3& windVelocity,int nodeIndex); + + /* Add aero force to a face of the body */ + void addAeroForceToFace(const btVector3& windVelocity,int faceIndex); + + /* Add velocity to the entire body */ + void addVelocity( const btVector3& velocity); + + /* Set velocity for the entire body */ + void setVelocity( const btVector3& velocity); + + /* Add velocity to a node of the body */ + void addVelocity( const btVector3& velocity, + int node); + /* Set mass */ + void setMass( int node, + btScalar mass); + /* Get mass */ + btScalar getMass( int node) const; + /* Get total mass */ + btScalar getTotalMass() const; + /* Set total mass (weighted by previous masses) */ + void setTotalMass( btScalar mass, + bool fromfaces=false); + /* Set total density */ + void setTotalDensity(btScalar density); + /* Set volume mass (using tetrahedrons) */ + void setVolumeMass( btScalar mass); + /* Set volume density (using tetrahedrons) */ + void setVolumeDensity( btScalar density); + /* Transform */ + void transform( const btTransform& trs); + /* Translate */ + void translate( const btVector3& trs); + /* Rotate */ + void rotate( const btQuaternion& rot); + /* Scale */ + void scale( const btVector3& scl); + /* Get link resting lengths scale */ + btScalar getRestLengthScale(); + /* Scale resting length of all springs */ + void setRestLengthScale(btScalar restLength); + /* Set current state as pose */ + void setPose( bool bvolume, + bool bframe); + /* Set current link lengths as resting lengths */ + void resetLinkRestLengths(); + /* Return the volume */ + btScalar getVolume() const; + /* Cluster count */ + int clusterCount() const; + /* Cluster center of mass */ + static btVector3 clusterCom(const Cluster* cluster); + btVector3 clusterCom(int cluster) const; + /* Cluster velocity at rpos */ + static btVector3 clusterVelocity(const Cluster* cluster,const btVector3& rpos); + /* Cluster impulse */ + static void clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); + static void clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); + static void clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse); + static void clusterVAImpulse(Cluster* cluster,const btVector3& impulse); + static void clusterDAImpulse(Cluster* cluster,const btVector3& impulse); + static void clusterAImpulse(Cluster* cluster,const Impulse& impulse); + static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse); + /* Generate bending constraints based on distance in the adjency graph */ + int generateBendingConstraints( int distance, + Material* mat=0); + /* Randomize constraints to reduce solver bias */ + void randomizeConstraints(); + /* Release clusters */ + void releaseCluster(int index); + void releaseClusters(); + /* Generate clusters (K-mean) */ + ///generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle + ///otherwise an approximation will be used (better performance) + int generateClusters(int k,int maxiterations=8192); + /* Refine */ + void refine(ImplicitFn* ifn,btScalar accurary,bool cut); + /* CutLink */ + bool cutLink(int node0,int node1,btScalar position); + bool cutLink(const Node* node0,const Node* node1,btScalar position); + + ///Ray casting using rayFrom and rayTo in worldspace, (not direction!) + bool rayTest(const btVector3& rayFrom, + const btVector3& rayTo, + sRayCast& results); + /* Solver presets */ + void setSolver(eSolverPresets::_ preset); + /* predictMotion */ + void predictMotion(btScalar dt); + /* solveConstraints */ + void solveConstraints(); + /* staticSolve */ + void staticSolve(int iterations); + /* solveCommonConstraints */ + static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations); + /* solveClusters */ + static void solveClusters(const btAlignedObjectArray& bodies); + /* integrateMotion */ + void integrateMotion(); + /* defaultCollisionHandlers */ + void defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap); + void defaultCollisionHandler(btSoftBody* psb); + + + + // + // Functionality to deal with new accelerated solvers. + // + + /** + * Set a wind velocity for interaction with the air. + */ + void setWindVelocity( const btVector3 &velocity ); + + + /** + * Return the wind velocity for interaction with the air. + */ + const btVector3& getWindVelocity(); + + // + // Set the solver that handles this soft body + // Should not be allowed to get out of sync with reality + // Currently called internally on addition to the world + void setSoftBodySolver( btSoftBodySolver *softBodySolver ) + { + m_softBodySolver = softBodySolver; + } + + // + // Return the solver that handles this soft body + // + btSoftBodySolver *getSoftBodySolver() + { + return m_softBodySolver; + } + + // + // Return the solver that handles this soft body + // + btSoftBodySolver *getSoftBodySolver() const + { + return m_softBodySolver; + } + + + // + // Cast + // + + static const btSoftBody* upcast(const btCollisionObject* colObj) + { + if (colObj->getInternalType()==CO_SOFT_BODY) + return (const btSoftBody*)colObj; + return 0; + } + static btSoftBody* upcast(btCollisionObject* colObj) + { + if (colObj->getInternalType()==CO_SOFT_BODY) + return (btSoftBody*)colObj; + return 0; + } + + // + // ::btCollisionObject + // + + virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const + { + aabbMin = m_bounds[0]; + aabbMax = m_bounds[1]; + } + // + // Private + // + void pointersToIndices(); + void indicesToPointers(const int* map=0); + + int rayTest(const btVector3& rayFrom,const btVector3& rayTo, + btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; + void initializeFaceTree(); + btVector3 evaluateCom() const; + bool checkContact(const btCollisionObjectWrapper* colObjWrap,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const; + void updateNormals(); + void updateBounds(); + void updatePose(); + void updateConstants(); + void updateLinkConstants(); + void updateArea(bool averageArea = true); + void initializeClusters(); + void updateClusters(); + void cleanupClusters(); + void prepareClusters(int iterations); + void solveClusters(btScalar sor); + void applyClusters(bool drift); + void dampClusters(); + void applyForces(); + static void PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti); + static void PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti); + static void PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti); + static void PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti); + static void VSolve_Links(btSoftBody* psb,btScalar kst); + static psolver_t getSolver(ePSolver::_ solver); + static vsolver_t getSolver(eVSolver::_ solver); + + + virtual int calculateSerializeBufferSize() const; + + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; + + //virtual void serializeSingleObject(class btSerializer* serializer) const; + + +}; + + + + +#endif //_BT_SOFT_BODY_H diff --git a/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp new file mode 100644 index 0000000..6e94d0a --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp @@ -0,0 +1,357 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btSoftBodyConcaveCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionShapes/btConcaveShape.h" +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + + +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletSoftBody/btSoftBody.h" + +#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06)//make this configurable + +btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped) +: btCollisionAlgorithm(ci), +m_isSwapped(isSwapped), +m_btSoftBodyTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped) +{ +} + + + +btSoftBodyConcaveCollisionAlgorithm::~btSoftBodyConcaveCollisionAlgorithm() +{ +} + + + +btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped): +m_dispatcher(dispatcher), +m_dispatchInfoPtr(0) +{ + m_softBody = (isSwapped? (btSoftBody*)body1Wrap->getCollisionObject():(btSoftBody*)body0Wrap->getCollisionObject()); + m_triBody = isSwapped? body0Wrap->getCollisionObject():body1Wrap->getCollisionObject(); + + // + // create the manifold from the dispatcher 'manifold pool' + // + // m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody); + + clearCache(); +} + +btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback() +{ + clearCache(); + // m_dispatcher->releaseManifold( m_manifoldPtr ); + +} + + +void btSoftBodyTriangleCallback::clearCache() +{ + for (int i=0;im_childShape); + m_softBody->getWorldInfo()->m_sparsesdf.RemoveReferences(tmp->m_childShape);//necessary? + delete tmp->m_childShape; + } + m_shapeCache.clear(); +} + + +void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) +{ + //just for debugging purposes + //printf("triangle %d",m_triangleCount++); + + btCollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher1 = m_dispatcher; + + ///debug drawing of the overlapping triangles + if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe)) + { + btVector3 color(1,1,0); + const btTransform& tr = m_triBody->getWorldTransform(); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color); + } + + btTriIndex triIndex(partId,triangleIndex,0); + btHashKey triKey(triIndex.getUid()); + + + btTriIndex* shapeIndex = m_shapeCache[triKey]; + if (shapeIndex) + { + btCollisionShape* tm = shapeIndex->m_childShape; + btAssert(tm); + + //copy over user pointers to temporary shape + tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer()); + + btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform()); + //btCollisionObjectWrapper triBody(0,tm, ob, btTransform::getIdentity());//ob->getWorldTransform());//?? + btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform()); + + btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0);//m_manifoldPtr); + + colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut); + colAlgo->~btCollisionAlgorithm(); + ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); + + return; + } + + //aabb filter is already applied! + + //btCollisionObject* colObj = static_cast(m_convexProxy->m_clientObject); + + // if (m_softBody->getCollisionShape()->getShapeType()== + { + // btVector3 other; + btVector3 normal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]); + normal.normalize(); + normal*= BT_SOFTBODY_TRIANGLE_EXTRUSION; + // other=(triangle[0]+triangle[1]+triangle[2])*0.333333f; + // other+=normal*22.f; + btVector3 pts[6] = {triangle[0]+normal, + triangle[1]+normal, + triangle[2]+normal, + triangle[0]-normal, + triangle[1]-normal, + triangle[2]-normal}; + + btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(),6); + + + // btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other); + + //btTriangleShape tm(triangle[0],triangle[1],triangle[2]); + // tm.setMargin(m_collisionMarginTriangle); + + //copy over user pointers to temporary shape + tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer()); + + + btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform()); + btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform());//btTransform::getIdentity());//?? + + btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0);//m_manifoldPtr); + + colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut); + colAlgo->~btCollisionAlgorithm(); + ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); + + triIndex.m_childShape = tm; + m_shapeCache.insert(triKey,triIndex); + + } + + + +} + + + +void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triBodyWrap, const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + m_dispatchInfoPtr = &dispatchInfo; + m_collisionMarginTriangle = collisionMarginTriangle+btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION); + m_resultOut = resultOut; + + + btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax; + m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax); + btVector3 halfExtents = (aabbWorldSpaceMax-aabbWorldSpaceMin)*btScalar(0.5); + btVector3 softBodyCenter = (aabbWorldSpaceMax+aabbWorldSpaceMin)*btScalar(0.5); + + btTransform softTransform; + softTransform.setIdentity(); + softTransform.setOrigin(softBodyCenter); + + btTransform convexInTriangleSpace; + convexInTriangleSpace = triBodyWrap->getWorldTransform().inverse() * softTransform; + btTransformAabb(halfExtents,m_collisionMarginTriangle,convexInTriangleSpace,m_aabbMin,m_aabbMax); +} + +void btSoftBodyConcaveCollisionAlgorithm::clearCache() +{ + m_btSoftBodyTriangleCallback.clearCache(); + +} + +void btSoftBodyConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + + + //btCollisionObject* convexBody = m_isSwapped ? body1 : body0; + const btCollisionObjectWrapper* triBody = m_isSwapped ? body0Wrap : body1Wrap; + + if (triBody->getCollisionShape()->isConcave()) + { + + + const btCollisionObject* triOb = triBody->getCollisionObject(); + const btConcaveShape* concaveShape = static_cast( triOb->getCollisionShape()); + + // if (convexBody->getCollisionShape()->isConvex()) + { + btScalar collisionMarginTriangle = concaveShape->getMargin(); + + // resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr); + m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,triBody,dispatchInfo,resultOut); + + + concaveShape->processAllTriangles( &m_btSoftBodyTriangleCallback,m_btSoftBodyTriangleCallback.getAabbMin(),m_btSoftBodyTriangleCallback.getAabbMax()); + + // resultOut->refreshContactPoints(); + + } + + } + +} + + +btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + btCollisionObject* convexbody = m_isSwapped ? body1 : body0; + btCollisionObject* triBody = m_isSwapped ? body0 : body1; + + + //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) + + //only perform CCD above a certain threshold, this prevents blocking on the long run + //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame... + btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2(); + if (squareMot0 < convexbody->getCcdSquareMotionThreshold()) + { + return btScalar(1.); + } + + //const btVector3& from = convexbody->m_worldTransform.getOrigin(); + //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin(); + //todo: only do if the motion exceeds the 'radius' + + btTransform triInv = triBody->getWorldTransform().inverse(); + btTransform convexFromLocal = triInv * convexbody->getWorldTransform(); + btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform(); + + struct LocalTriangleSphereCastCallback : public btTriangleCallback + { + btTransform m_ccdSphereFromTrans; + btTransform m_ccdSphereToTrans; + btTransform m_meshTransform; + + btScalar m_ccdSphereRadius; + btScalar m_hitFraction; + + + LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) + :m_ccdSphereFromTrans(from), + m_ccdSphereToTrans(to), + m_ccdSphereRadius(ccdSphereRadius), + m_hitFraction(hitFraction) + { + } + + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; + //do a swept sphere for now + btTransform ident; + ident.setIdentity(); + btConvexCast::CastResult castResult; + castResult.m_fraction = m_hitFraction; + btSphereShape pointShape(m_ccdSphereRadius); + btTriangleShape triShape(triangle[0],triangle[1],triangle[2]); + btVoronoiSimplexSolver simplexSolver; + btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver); + //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); + //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); + //local space? + + if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans, + ident,ident,castResult)) + { + if (m_hitFraction > castResult.m_fraction) + m_hitFraction = castResult.m_fraction; + } + + } + + }; + + + + + + if (triBody->getCollisionShape()->isConcave()) + { + btVector3 rayAabbMin = convexFromLocal.getOrigin(); + rayAabbMin.setMin(convexToLocal.getOrigin()); + btVector3 rayAabbMax = convexFromLocal.getOrigin(); + rayAabbMax.setMax(convexToLocal.getOrigin()); + btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius(); + rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + + btScalar curHitFraction = btScalar(1.); //is this available? + LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal, + convexbody->getCcdSweptSphereRadius(),curHitFraction); + + raycastCallback.m_hitFraction = convexbody->getHitFraction(); + + btCollisionObject* concavebody = triBody; + + btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); + + if (triangleMesh) + { + triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); + } + + + + if (raycastCallback.m_hitFraction < convexbody->getHitFraction()) + { + convexbody->setHitFraction( raycastCallback.m_hitFraction); + return raycastCallback.m_hitFraction; + } + } + + return btScalar(1.); + +} diff --git a/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h new file mode 100644 index 0000000..11c7b88 --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h @@ -0,0 +1,155 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_CONCAVE_COLLISION_ALGORITHM_H +#define BT_SOFT_BODY_CONCAVE_COLLISION_ALGORITHM_H + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionShapes/btTriangleCallback.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +class btDispatcher; +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +class btSoftBody; +class btCollisionShape; + +#include "LinearMath/btHashMap.h" + +#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" //for definition of MAX_NUM_PARTS_IN_BITS + +struct btTriIndex +{ + int m_PartIdTriangleIndex; + class btCollisionShape* m_childShape; + + btTriIndex(int partId,int triangleIndex,btCollisionShape* shape) + { + m_PartIdTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; + m_childShape = shape; + } + + int getTriangleIndex() const + { + // Get only the lower bits where the triangle index is stored + unsigned int x = 0; + unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS); + return (m_PartIdTriangleIndex&~(y)); + } + int getPartId() const + { + // Get only the highest bits where the part index is stored + return (m_PartIdTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS)); + } + int getUid() const + { + return m_PartIdTriangleIndex; + } +}; + + +///For each triangle in the concave mesh that overlaps with the AABB of a soft body (m_softBody), processTriangle is called. +class btSoftBodyTriangleCallback : public btTriangleCallback +{ + btSoftBody* m_softBody; + const btCollisionObject* m_triBody; + + btVector3 m_aabbMin; + btVector3 m_aabbMax ; + + btManifoldResult* m_resultOut; + + btDispatcher* m_dispatcher; + const btDispatcherInfo* m_dispatchInfoPtr; + btScalar m_collisionMarginTriangle; + + btHashMap,btTriIndex> m_shapeCache; + +public: + int m_triangleCount; + + // btPersistentManifold* m_manifoldPtr; + + btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + + void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triObjWrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual ~btSoftBodyTriangleCallback(); + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); + + void clearCache(); + + SIMD_FORCE_INLINE const btVector3& getAabbMin() const + { + return m_aabbMin; + } + SIMD_FORCE_INLINE const btVector3& getAabbMax() const + { + return m_aabbMax; + } + +}; + + + + +/// btSoftBodyConcaveCollisionAlgorithm supports collision between soft body shapes and (concave) trianges meshes. +class btSoftBodyConcaveCollisionAlgorithm : public btCollisionAlgorithm +{ + + bool m_isSwapped; + + btSoftBodyTriangleCallback m_btSoftBodyTriangleCallback; + +public: + + btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + + virtual ~btSoftBodyConcaveCollisionAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + //we don't add any manifolds + } + + void clearCache(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm)); + return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false); + } + }; + + struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm)); + return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true); + } + }; + +}; + +#endif //BT_SOFT_BODY_CONCAVE_COLLISION_ALGORITHM_H diff --git a/src/BulletSoftBody/btSoftBodyData.h b/src/BulletSoftBody/btSoftBodyData.h new file mode 100644 index 0000000..87d8841 --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyData.h @@ -0,0 +1,217 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFTBODY_FLOAT_DATA +#define BT_SOFTBODY_FLOAT_DATA + +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + + +struct SoftBodyMaterialData +{ + float m_linearStiffness; + float m_angularStiffness; + float m_volumeStiffness; + int m_flags; +}; + +struct SoftBodyNodeData +{ + SoftBodyMaterialData *m_material; + btVector3FloatData m_position; + btVector3FloatData m_previousPosition; + btVector3FloatData m_velocity; + btVector3FloatData m_accumulatedForce; + btVector3FloatData m_normal; + float m_inverseMass; + float m_area; + int m_attach; + int m_pad; +}; + +struct SoftBodyLinkData +{ + SoftBodyMaterialData *m_material; + int m_nodeIndices[2]; // Node pointers + float m_restLength; // Rest length + int m_bbending; // Bending link +}; + +struct SoftBodyFaceData +{ + btVector3FloatData m_normal; // Normal + SoftBodyMaterialData *m_material; + int m_nodeIndices[3]; // Node pointers + float m_restArea; // Rest area +}; + +struct SoftBodyTetraData +{ + btVector3FloatData m_c0[4]; // gradients + SoftBodyMaterialData *m_material; + int m_nodeIndices[4]; // Node pointers + float m_restVolume; // Rest volume + float m_c1; // (4*kVST)/(im0+im1+im2+im3) + float m_c2; // m_c1/sum(|g0..3|^2) + int m_pad; +}; + +struct SoftRigidAnchorData +{ + btMatrix3x3FloatData m_c0; // Impulse matrix + btVector3FloatData m_c1; // Relative anchor + btVector3FloatData m_localFrame; // Anchor position in body space + btRigidBodyData *m_rigidBody; + int m_nodeIndex; // Node pointer + float m_c2; // ima*dt +}; + + + +struct SoftBodyConfigData +{ + int m_aeroModel; // Aerodynamic model (default: V_Point) + float m_baumgarte; // Velocities correction factor (Baumgarte) + float m_damping; // Damping coefficient [0,1] + float m_drag; // Drag coefficient [0,+inf] + float m_lift; // Lift coefficient [0,+inf] + float m_pressure; // Pressure coefficient [-inf,+inf] + float m_volume; // Volume conversation coefficient [0,+inf] + float m_dynamicFriction; // Dynamic friction coefficient [0,1] + float m_poseMatch; // Pose matching coefficient [0,1] + float m_rigidContactHardness; // Rigid contacts hardness [0,1] + float m_kineticContactHardness; // Kinetic contacts hardness [0,1] + float m_softContactHardness; // Soft contacts hardness [0,1] + float m_anchorHardness; // Anchors hardness [0,1] + float m_softRigidClusterHardness; // Soft vs rigid hardness [0,1] (cluster only) + float m_softKineticClusterHardness; // Soft vs kinetic hardness [0,1] (cluster only) + float m_softSoftClusterHardness; // Soft vs soft hardness [0,1] (cluster only) + float m_softRigidClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) + float m_softKineticClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) + float m_softSoftClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) + float m_maxVolume; // Maximum volume ratio for pose + float m_timeScale; // Time scale + int m_velocityIterations; // Velocities solver iterations + int m_positionIterations; // Positions solver iterations + int m_driftIterations; // Drift solver iterations + int m_clusterIterations; // Cluster solver iterations + int m_collisionFlags; // Collisions flags +}; + +struct SoftBodyPoseData +{ + btMatrix3x3FloatData m_rot; // Rotation + btMatrix3x3FloatData m_scale; // Scale + btMatrix3x3FloatData m_aqq; // Base scaling + btVector3FloatData m_com; // COM + + btVector3FloatData *m_positions; // Reference positions + float *m_weights; // Weights + int m_numPositions; + int m_numWeigts; + + int m_bvolume; // Is valid + int m_bframe; // Is frame + float m_restVolume; // Rest volume + int m_pad; +}; + +struct SoftBodyClusterData +{ + btTransformFloatData m_framexform; + btMatrix3x3FloatData m_locii; + btMatrix3x3FloatData m_invwi; + btVector3FloatData m_com; + btVector3FloatData m_vimpulses[2]; + btVector3FloatData m_dimpulses[2]; + btVector3FloatData m_lv; + btVector3FloatData m_av; + + btVector3FloatData *m_framerefs; + int *m_nodeIndices; + float *m_masses; + + int m_numFrameRefs; + int m_numNodes; + int m_numMasses; + + float m_idmass; + float m_imass; + int m_nvimpulses; + int m_ndimpulses; + float m_ndamping; + float m_ldamping; + float m_adamping; + float m_matching; + float m_maxSelfCollisionImpulse; + float m_selfCollisionImpulseFactor; + int m_containsAnchor; + int m_collide; + int m_clusterIndex; +}; + + +enum btSoftJointBodyType +{ + BT_JOINT_SOFT_BODY_CLUSTER=1, + BT_JOINT_RIGID_BODY, + BT_JOINT_COLLISION_OBJECT +}; + +struct btSoftBodyJointData +{ + void *m_bodyA; + void *m_bodyB; + btVector3FloatData m_refs[2]; + float m_cfm; + float m_erp; + float m_split; + int m_delete; + btVector3FloatData m_relPosition[2];//linear + int m_bodyAtype; + int m_bodyBtype; + int m_jointType; + int m_pad; +}; + +///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 +struct btSoftBodyFloatData +{ + btCollisionObjectFloatData m_collisionObjectData; + + SoftBodyPoseData *m_pose; + SoftBodyMaterialData **m_materials; + SoftBodyNodeData *m_nodes; + SoftBodyLinkData *m_links; + SoftBodyFaceData *m_faces; + SoftBodyTetraData *m_tetrahedra; + SoftRigidAnchorData *m_anchors; + SoftBodyClusterData *m_clusters; + btSoftBodyJointData *m_joints; + + int m_numMaterials; + int m_numNodes; + int m_numLinks; + int m_numFaces; + int m_numTetrahedra; + int m_numAnchors; + int m_numClusters; + int m_numJoints; + SoftBodyConfigData m_config; +}; + +#endif //BT_SOFTBODY_FLOAT_DATA + diff --git a/src/BulletSoftBody/btSoftBodyHelpers.cpp b/src/BulletSoftBody/btSoftBodyHelpers.cpp new file mode 100644 index 0000000..0fb3560 --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyHelpers.cpp @@ -0,0 +1,1055 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +///btSoftBodyHelpers.cpp by Nathanael Presson + +#include "btSoftBodyInternals.h" +#include +#include +#include "btSoftBodyHelpers.h" +#include "LinearMath/btConvexHull.h" +#include "LinearMath/btConvexHullComputer.h" + + +// +static void drawVertex( btIDebugDraw* idraw, + const btVector3& x,btScalar s,const btVector3& c) +{ + idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c); + idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c); + idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c); +} + +// +static void drawBox( btIDebugDraw* idraw, + const btVector3& mins, + const btVector3& maxs, + const btVector3& color) +{ + const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()), + btVector3(maxs.x(),mins.y(),mins.z()), + btVector3(maxs.x(),maxs.y(),mins.z()), + btVector3(mins.x(),maxs.y(),mins.z()), + btVector3(mins.x(),mins.y(),maxs.z()), + btVector3(maxs.x(),mins.y(),maxs.z()), + btVector3(maxs.x(),maxs.y(),maxs.z()), + btVector3(mins.x(),maxs.y(),maxs.z())}; + idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color); + idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color); + idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color); + idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color); + idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color); + idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color); +} + +// +static void drawTree( btIDebugDraw* idraw, + const btDbvtNode* node, + int depth, + const btVector3& ncolor, + const btVector3& lcolor, + int mindepth, + int maxdepth) +{ + if(node) + { + if(node->isinternal()&&((depthchilds[0],depth+1,ncolor,lcolor,mindepth,maxdepth); + drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth); + } + if(depth>=mindepth) + { + const btScalar scl=(btScalar)(node->isinternal()?1:1); + const btVector3 mi=node->volume.Center()-node->volume.Extents()*scl; + const btVector3 mx=node->volume.Center()+node->volume.Extents()*scl; + drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor); + } + } +} + +// +template +static inline T sum(const btAlignedObjectArray& items) +{ + T v; + if(items.size()) + { + v=items[0]; + for(int i=1,ni=items.size();i +static inline void add(btAlignedObjectArray& items,const Q& value) +{ + for(int i=0,ni=items.size();i +static inline void mul(btAlignedObjectArray& items,const Q& value) +{ + for(int i=0,ni=items.size();i +static inline T average(const btAlignedObjectArray& items) +{ + const btScalar n=(btScalar)(items.size()>0?items.size():1); + return(sum(items)/n); +} + +// +static inline btScalar tetravolume(const btVector3& x0, + const btVector3& x1, + const btVector3& x2, + const btVector3& x3) +{ + const btVector3 a=x1-x0; + const btVector3 b=x2-x0; + const btVector3 c=x3-x0; + return(btDot(a,btCross(b,c))); +} + +// +#if 0 +static btVector3 stresscolor(btScalar stress) +{ + static const btVector3 spectrum[]= { btVector3(1,0,1), + btVector3(0,0,1), + btVector3(0,1,1), + btVector3(0,1,0), + btVector3(1,1,0), + btVector3(1,0,0), + btVector3(1,0,0)}; + static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1; + static const btScalar one=1; + stress=btMax(0,btMin(1,stress))*ncolors; + const int sel=(int)stress; + const btScalar frc=stress-sel; + return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc); +} +#endif + +// +void btSoftBodyHelpers::Draw( btSoftBody* psb, + btIDebugDraw* idraw, + int drawflags) +{ + const btScalar scl=(btScalar)0.1; + const btScalar nscl=scl*5; + const btVector3 lcolor=btVector3(0,0,0); + const btVector3 ncolor=btVector3(1,1,1); + const btVector3 ccolor=btVector3(1,0,0); + int i,j,nj; + + /* Clusters */ + if(0!=(drawflags&fDrawFlags::Clusters)) + { + srand(1806); + for(i=0;im_clusters.size();++i) + { + if(psb->m_clusters[i]->m_collide) + { + btVector3 color( rand()/(btScalar)RAND_MAX, + rand()/(btScalar)RAND_MAX, + rand()/(btScalar)RAND_MAX); + color=color.normalized()*0.75; + btAlignedObjectArray vertices; + vertices.resize(psb->m_clusters[i]->m_nodes.size()); + for(j=0,nj=vertices.size();jm_clusters[i]->m_nodes[j]->m_x; + } +#define USE_NEW_CONVEX_HULL_COMPUTER +#ifdef USE_NEW_CONVEX_HULL_COMPUTER + btConvexHullComputer computer; + int stride = sizeof(btVector3); + int count = vertices.size(); + btScalar shrink=0.f; + btScalar shrinkClamp=0.f; + computer.compute(&vertices[0].getX(),stride,count,shrink,shrinkClamp); + for (int i=0;igetNextEdgeOfFace(); + + int v0 = firstEdge->getSourceVertex(); + int v1 = firstEdge->getTargetVertex(); + while (edge!=firstEdge) + { + int v2 = edge->getTargetVertex(); + idraw->drawTriangle(computer.vertices[v0],computer.vertices[v1],computer.vertices[v2],color,1); + edge = edge->getNextEdgeOfFace(); + v0=v1; + v1=v2; + }; + } +#else + + HullDesc hdsc(QF_TRIANGLES,vertices.size(),&vertices[0]); + HullResult hres; + HullLibrary hlib; + hdsc.mMaxVertices=vertices.size(); + hlib.CreateConvexHull(hdsc,hres); + const btVector3 center=average(hres.m_OutputVertices); + add(hres.m_OutputVertices,-center); + mul(hres.m_OutputVertices,(btScalar)1); + add(hres.m_OutputVertices,center); + for(j=0;j<(int)hres.mNumFaces;++j) + { + const int idx[]={hres.m_Indices[j*3+0],hres.m_Indices[j*3+1],hres.m_Indices[j*3+2]}; + idraw->drawTriangle(hres.m_OutputVertices[idx[0]], + hres.m_OutputVertices[idx[1]], + hres.m_OutputVertices[idx[2]], + color,1); + } + hlib.ReleaseResult(hres); +#endif + + } + /* Velocities */ +#if 0 + for(int j=0;jm_clusters[i].m_nodes.size();++j) + { + const btSoftBody::Cluster& c=psb->m_clusters[i]; + const btVector3 r=c.m_nodes[j]->m_x-c.m_com; + const btVector3 v=c.m_lv+btCross(c.m_av,r); + idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0)); + } +#endif + /* Frame */ + // btSoftBody::Cluster& c=*psb->m_clusters[i]; + // idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0)); + // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0)); + // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1)); + } + } + else + { + /* Nodes */ + if(0!=(drawflags&fDrawFlags::Nodes)) + { + for(i=0;im_nodes.size();++i) + { + const btSoftBody::Node& n=psb->m_nodes[i]; + if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; + idraw->drawLine(n.m_x-btVector3(scl,0,0),n.m_x+btVector3(scl,0,0),btVector3(1,0,0)); + idraw->drawLine(n.m_x-btVector3(0,scl,0),n.m_x+btVector3(0,scl,0),btVector3(0,1,0)); + idraw->drawLine(n.m_x-btVector3(0,0,scl),n.m_x+btVector3(0,0,scl),btVector3(0,0,1)); + } + } + /* Links */ + if(0!=(drawflags&fDrawFlags::Links)) + { + for(i=0;im_links.size();++i) + { + const btSoftBody::Link& l=psb->m_links[i]; + if(0==(l.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; + idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,lcolor); + } + } + /* Normals */ + if(0!=(drawflags&fDrawFlags::Normals)) + { + for(i=0;im_nodes.size();++i) + { + const btSoftBody::Node& n=psb->m_nodes[i]; + if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; + const btVector3 d=n.m_n*nscl; + idraw->drawLine(n.m_x,n.m_x+d,ncolor); + idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5); + } + } + /* Contacts */ + if(0!=(drawflags&fDrawFlags::Contacts)) + { + static const btVector3 axis[]={btVector3(1,0,0), + btVector3(0,1,0), + btVector3(0,0,1)}; + for(i=0;im_rcontacts.size();++i) + { + const btSoftBody::RContact& c=psb->m_rcontacts[i]; + const btVector3 o= c.m_node->m_x-c.m_cti.m_normal* + (btDot(c.m_node->m_x,c.m_cti.m_normal)+c.m_cti.m_offset); + const btVector3 x=btCross(c.m_cti.m_normal,axis[c.m_cti.m_normal.minAxis()]).normalized(); + const btVector3 y=btCross(x,c.m_cti.m_normal).normalized(); + idraw->drawLine(o-x*nscl,o+x*nscl,ccolor); + idraw->drawLine(o-y*nscl,o+y*nscl,ccolor); + idraw->drawLine(o,o+c.m_cti.m_normal*nscl*3,btVector3(1,1,0)); + } + } + /* Faces */ + if(0!=(drawflags&fDrawFlags::Faces)) + { + const btScalar scl=(btScalar)0.8; + const btScalar alp=(btScalar)1; + const btVector3 col(0,(btScalar)0.7,0); + for(i=0;im_faces.size();++i) + { + const btSoftBody::Face& f=psb->m_faces[i]; + if(0==(f.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; + const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x}; + const btVector3 c=(x[0]+x[1]+x[2])/3; + idraw->drawTriangle((x[0]-c)*scl+c, + (x[1]-c)*scl+c, + (x[2]-c)*scl+c, + col,alp); + } + } + /* Tetras */ + if(0!=(drawflags&fDrawFlags::Tetras)) + { + const btScalar scl=(btScalar)0.8; + const btScalar alp=(btScalar)1; + const btVector3 col((btScalar)0.3,(btScalar)0.3,(btScalar)0.7); + for(int i=0;im_tetras.size();++i) + { + const btSoftBody::Tetra& t=psb->m_tetras[i]; + if(0==(t.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; + const btVector3 x[]={t.m_n[0]->m_x,t.m_n[1]->m_x,t.m_n[2]->m_x,t.m_n[3]->m_x}; + const btVector3 c=(x[0]+x[1]+x[2]+x[3])/4; + idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[2]-c)*scl+c,col,alp); + idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[3]-c)*scl+c,col,alp); + idraw->drawTriangle((x[1]-c)*scl+c,(x[2]-c)*scl+c,(x[3]-c)*scl+c,col,alp); + idraw->drawTriangle((x[2]-c)*scl+c,(x[0]-c)*scl+c,(x[3]-c)*scl+c,col,alp); + } + } + } + /* Anchors */ + if(0!=(drawflags&fDrawFlags::Anchors)) + { + for(i=0;im_anchors.size();++i) + { + const btSoftBody::Anchor& a=psb->m_anchors[i]; + const btVector3 q=a.m_body->getWorldTransform()*a.m_local; + drawVertex(idraw,a.m_node->m_x,0.25,btVector3(1,0,0)); + drawVertex(idraw,q,0.25,btVector3(0,1,0)); + idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1)); + } + for(i=0;im_nodes.size();++i) + { + const btSoftBody::Node& n=psb->m_nodes[i]; + if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; + if(n.m_im<=0) + { + drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0)); + } + } + } + + + /* Notes */ + if(0!=(drawflags&fDrawFlags::Notes)) + { + for(i=0;im_notes.size();++i) + { + const btSoftBody::Note& n=psb->m_notes[i]; + btVector3 p=n.m_offset; + for(int j=0;jm_x*n.m_coords[j]; + } + idraw->draw3dText(p,n.m_text); + } + } + /* Node tree */ + if(0!=(drawflags&fDrawFlags::NodeTree)) DrawNodeTree(psb,idraw); + /* Face tree */ + if(0!=(drawflags&fDrawFlags::FaceTree)) DrawFaceTree(psb,idraw); + /* Cluster tree */ + if(0!=(drawflags&fDrawFlags::ClusterTree)) DrawClusterTree(psb,idraw); + /* Joints */ + if(0!=(drawflags&fDrawFlags::Joints)) + { + for(i=0;im_joints.size();++i) + { + const btSoftBody::Joint* pj=psb->m_joints[i]; + switch(pj->Type()) + { + case btSoftBody::Joint::eType::Linear: + { + const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj; + const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0]; + const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1]; + idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0)); + idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1)); + drawVertex(idraw,a0,0.25,btVector3(1,1,0)); + drawVertex(idraw,a1,0.25,btVector3(0,1,1)); + } + break; + case btSoftBody::Joint::eType::Angular: + { + //const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj; + const btVector3 o0=pj->m_bodies[0].xform().getOrigin(); + const btVector3 o1=pj->m_bodies[1].xform().getOrigin(); + const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0]; + const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1]; + idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0)); + idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0)); + idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1)); + idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1)); + break; + } + default: + { + } + + } + } + } +} + +// +void btSoftBodyHelpers::DrawInfos( btSoftBody* psb, + btIDebugDraw* idraw, + bool masses, + bool areas, + bool /*stress*/) +{ + for(int i=0;im_nodes.size();++i) + { + const btSoftBody::Node& n=psb->m_nodes[i]; + char text[2048]={0}; + char buff[1024]; + if(masses) + { + sprintf(buff," M(%.2f)",1/n.m_im); + strcat(text,buff); + } + if(areas) + { + sprintf(buff," A(%.2f)",n.m_area); + strcat(text,buff); + } + if(text[0]) idraw->draw3dText(n.m_x,text); + } +} + +// +void btSoftBodyHelpers::DrawNodeTree( btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth, + int maxdepth) +{ + drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth); +} + +// +void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth, + int maxdepth) +{ + drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth); +} + +// +void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth, + int maxdepth) +{ + drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth); +} + +// +void btSoftBodyHelpers::DrawFrame( btSoftBody* psb, + btIDebugDraw* idraw) +{ + if(psb->m_pose.m_bframe) + { + static const btScalar ascl=10; + static const btScalar nscl=(btScalar)0.1; + const btVector3 com=psb->m_pose.m_com; + const btMatrix3x3 trs=psb->m_pose.m_rot*psb->m_pose.m_scl; + const btVector3 Xaxis=(trs*btVector3(1,0,0)).normalized(); + const btVector3 Yaxis=(trs*btVector3(0,1,0)).normalized(); + const btVector3 Zaxis=(trs*btVector3(0,0,1)).normalized(); + idraw->drawLine(com,com+Xaxis*ascl,btVector3(1,0,0)); + idraw->drawLine(com,com+Yaxis*ascl,btVector3(0,1,0)); + idraw->drawLine(com,com+Zaxis*ascl,btVector3(0,0,1)); + for(int i=0;im_pose.m_pos.size();++i) + { + const btVector3 x=com+trs*psb->m_pose.m_pos[i]; + drawVertex(idraw,x,nscl,btVector3(1,0,1)); + } + } +} + +// +btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBodyWorldInfo& worldInfo, const btVector3& from, + const btVector3& to, + int res, + int fixeds) +{ + /* Create nodes */ + const int r=res+2; + btVector3* x=new btVector3[r]; + btScalar* m=new btScalar[r]; + int i; + + for(i=0;isetMass(0,0); + if(fixeds&2) psb->setMass(r-1,0); + delete[] x; + delete[] m; + /* Create links */ + for(i=1;iappendLink(i-1,i); + } + /* Finished */ + return(psb); +} + +// +btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo,const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags) +{ +#define IDX(_x_,_y_) ((_y_)*rx+(_x_)) + /* Create nodes */ + if((resx<2)||(resy<2)) return(0); + const int rx=resx; + const int ry=resy; + const int tot=rx*ry; + btVector3* x=new btVector3[tot]; + btScalar* m=new btScalar[tot]; + int iy; + + for(iy=0;iysetMass(IDX(0,0),0); + if(fixeds&2) psb->setMass(IDX(rx-1,0),0); + if(fixeds&4) psb->setMass(IDX(0,ry-1),0); + if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0); + delete[] x; + delete[] m; + /* Create links and faces */ + for(iy=0;iyappendLink(idx,IDX(ix+1,iy)); + if(mdy) psb->appendLink(idx,IDX(ix,iy+1)); + if(mdx&&mdy) + { + if((ix+iy)&1) + { + psb->appendFace(IDX(ix,iy),IDX(ix+1,iy),IDX(ix+1,iy+1)); + psb->appendFace(IDX(ix,iy),IDX(ix+1,iy+1),IDX(ix,iy+1)); + if(gendiags) + { + psb->appendLink(IDX(ix,iy),IDX(ix+1,iy+1)); + } + } + else + { + psb->appendFace(IDX(ix,iy+1),IDX(ix,iy),IDX(ix+1,iy)); + psb->appendFace(IDX(ix,iy+1),IDX(ix+1,iy),IDX(ix+1,iy+1)); + if(gendiags) + { + psb->appendLink(IDX(ix+1,iy),IDX(ix,iy+1)); + } + } + } + } + } + /* Finished */ +#undef IDX + return(psb); +} + +// +btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo, + const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags, + float* tex_coords) +{ + + /* + * + * corners: + * + * [0][0] corner00 ------- corner01 [resx][0] + * | | + * | | + * [0][resy] corner10 -------- corner11 [resx][resy] + * + * + * + * + * + * + * "fixedgs" map: + * + * corner00 --> +1 + * corner01 --> +2 + * corner10 --> +4 + * corner11 --> +8 + * upper middle --> +16 + * left middle --> +32 + * right middle --> +64 + * lower middle --> +128 + * center --> +256 + * + * + * tex_coords size (resx-1)*(resy-1)*12 + * + * + * + * SINGLE QUAD INTERNALS + * + * 1) btSoftBody's nodes and links, + * diagonal link is optional ("gendiags") + * + * + * node00 ------ node01 + * | . + * | . + * | . + * | . + * | . + * node10 node11 + * + * + * + * 2) Faces: + * two triangles, + * UV Coordinates (hier example for single quad) + * + * (0,1) (0,1) (1,1) + * 1 |\ 3 \-----| 2 + * | \ \ | + * | \ \ | + * | \ \ | + * | \ \ | + * 2 |-----\ 3 \| 1 + * (0,0) (1,0) (1,0) + * + * + * + * + * + * + */ + +#define IDX(_x_,_y_) ((_y_)*rx+(_x_)) + /* Create nodes */ + if((resx<2)||(resy<2)) return(0); + const int rx=resx; + const int ry=resy; + const int tot=rx*ry; + btVector3* x=new btVector3[tot]; + btScalar* m=new btScalar[tot]; + + int iy; + + for(iy=0;iysetMass(IDX(0,0),0); + if(fixeds&2) psb->setMass(IDX(rx-1,0),0); + if(fixeds&4) psb->setMass(IDX(0,ry-1),0); + if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0); + if(fixeds&16) psb->setMass(IDX((rx-1)/2,0),0); + if(fixeds&32) psb->setMass(IDX(0,(ry-1)/2),0); + if(fixeds&64) psb->setMass(IDX(rx-1,(ry-1)/2),0); + if(fixeds&128) psb->setMass(IDX((rx-1)/2,ry-1),0); + if(fixeds&256) psb->setMass(IDX((rx-1)/2,(ry-1)/2),0); + delete[] x; + delete[] m; + + + int z = 0; + /* Create links and faces */ + for(iy=0;iyappendLink(node00,node01); + if(mdy) psb->appendLink(node00,node10); + if(mdx&&mdy) + { + psb->appendFace(node00,node10,node11); + if (tex_coords) { + tex_coords[z+0]=CalculateUV(resx,resy,ix,iy,0); + tex_coords[z+1]=CalculateUV(resx,resy,ix,iy,1); + tex_coords[z+2]=CalculateUV(resx,resy,ix,iy,0); + tex_coords[z+3]=CalculateUV(resx,resy,ix,iy,2); + tex_coords[z+4]=CalculateUV(resx,resy,ix,iy,3); + tex_coords[z+5]=CalculateUV(resx,resy,ix,iy,2); + } + psb->appendFace(node11,node01,node00); + if (tex_coords) { + tex_coords[z+6 ]=CalculateUV(resx,resy,ix,iy,3); + tex_coords[z+7 ]=CalculateUV(resx,resy,ix,iy,2); + tex_coords[z+8 ]=CalculateUV(resx,resy,ix,iy,3); + tex_coords[z+9 ]=CalculateUV(resx,resy,ix,iy,1); + tex_coords[z+10]=CalculateUV(resx,resy,ix,iy,0); + tex_coords[z+11]=CalculateUV(resx,resy,ix,iy,1); + } + if (gendiags) psb->appendLink(node00,node11); + z += 12; + } + } + } + /* Finished */ +#undef IDX + return(psb); +} + +float btSoftBodyHelpers::CalculateUV(int resx,int resy,int ix,int iy,int id) +{ + + /* + * + * + * node00 --- node01 + * | | + * node10 --- node11 + * + * + * ID map: + * + * node00 s --> 0 + * node00 t --> 1 + * + * node01 s --> 3 + * node01 t --> 1 + * + * node10 s --> 0 + * node10 t --> 2 + * + * node11 s --> 3 + * node11 t --> 2 + * + * + */ + + float tc=0.0f; + if (id == 0) { + tc = (1.0f/((resx-1))*ix); + } + else if (id==1) { + tc = (1.0f/((resy-1))*(resy-1-iy)); + } + else if (id==2) { + tc = (1.0f/((resy-1))*(resy-1-iy-1)); + } + else if (id==3) { + tc = (1.0f/((resx-1))*(ix+1)); + } + return tc; +} +// +btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,const btVector3& center, + const btVector3& radius, + int res) +{ + struct Hammersley + { + static void Generate(btVector3* x,int n) + { + for(int i=0;i>=1) if(j&1) t+=p; + btScalar w=2*t-1; + btScalar a=(SIMD_PI+2*i*SIMD_PI)/n; + btScalar s=btSqrt(1-w*w); + *x++=btVector3(s*btCos(a),s*btSin(a),w); + } + } + }; + btAlignedObjectArray vtx; + vtx.resize(3+res); + Hammersley::Generate(&vtx[0],vtx.size()); + for(int i=0;i chks; + btAlignedObjectArray vtx; + chks.resize(maxidx*maxidx,false); + vtx.resize(maxidx); + for(i=0,j=0,ni=maxidx*3;iappendLink(idx[j],idx[k]); + } + } +#undef IDX + psb->appendFace(idx[0],idx[1],idx[2]); + } + + if (randomizeConstraints) + { + psb->randomizeConstraints(); + } + + return(psb); +} + +// +btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices, + int nvertices, bool randomizeConstraints) +{ + HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); + HullResult hres; + HullLibrary hlib;/*??*/ + hdsc.mMaxVertices=nvertices; + hlib.CreateConvexHull(hdsc,hres); + btSoftBody* psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices, + &hres.m_OutputVertices[0],0); + for(int i=0;i<(int)hres.mNumFaces;++i) + { + const int idx[]={ hres.m_Indices[i*3+0], + hres.m_Indices[i*3+1], + hres.m_Indices[i*3+2]}; + if(idx[0]appendLink( idx[0],idx[1]); + if(idx[1]appendLink( idx[1],idx[2]); + if(idx[2]appendLink( idx[2],idx[0]); + psb->appendFace(idx[0],idx[1],idx[2]); + } + hlib.ReleaseResult(hres); + if (randomizeConstraints) + { + psb->randomizeConstraints(); + } + return(psb); +} + + + + +static int nextLine(const char* buffer) +{ + int numBytesRead=0; + + while (*buffer != '\n') + { + buffer++; + numBytesRead++; + } + + + if (buffer[0]==0x0a) + { + buffer++; + numBytesRead++; + } + return numBytesRead; +} + +/* Create from TetGen .ele, .face, .node data */ +btSoftBody* btSoftBodyHelpers::CreateFromTetGenData(btSoftBodyWorldInfo& worldInfo, + const char* ele, + const char* face, + const char* node, + bool bfacelinks, + bool btetralinks, + bool bfacesfromtetras) +{ +btAlignedObjectArray pos; +int nnode=0; +int ndims=0; +int nattrb=0; +int hasbounds=0; +int result = sscanf(node,"%d %d %d %d",&nnode,&ndims,&nattrb,&hasbounds); +result = sscanf(node,"%d %d %d %d",&nnode,&ndims,&nattrb,&hasbounds); +node += nextLine(node); + +pos.resize(nnode); +for(int i=0;i>index; +// sn>>x;sn>>y;sn>>z; + node += nextLine(node); + + //for(int j=0;j>a; + + //if(hasbounds) + // sn>>bound; + + pos[index].setX(btScalar(x)); + pos[index].setY(btScalar(y)); + pos[index].setZ(btScalar(z)); + } +btSoftBody* psb=new btSoftBody(&worldInfo,nnode,&pos[0],0); +#if 0 +if(face&&face[0]) + { + int nface=0; + sf>>nface;sf>>hasbounds; + for(int i=0;i>index; + sf>>ni[0];sf>>ni[1];sf>>ni[2]; + sf>>bound; + psb->appendFace(ni[0],ni[1],ni[2]); + if(btetralinks) + { + psb->appendLink(ni[0],ni[1],0,true); + psb->appendLink(ni[1],ni[2],0,true); + psb->appendLink(ni[2],ni[0],0,true); + } + } + } +#endif + +if(ele&&ele[0]) + { + int ntetra=0; + int ncorner=0; + int neattrb=0; + sscanf(ele,"%d %d %d",&ntetra,&ncorner,&neattrb); + ele += nextLine(ele); + + //se>>ntetra;se>>ncorner;se>>neattrb; + for(int i=0;i>index; + //se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3]; + sscanf(ele,"%d %d %d %d %d",&index,&ni[0],&ni[1],&ni[2],&ni[3]); + ele+=nextLine(ele); + //for(int j=0;j>a; + psb->appendTetra(ni[0],ni[1],ni[2],ni[3]); + if(btetralinks) + { + psb->appendLink(ni[0],ni[1],0,true); + psb->appendLink(ni[1],ni[2],0,true); + psb->appendLink(ni[2],ni[0],0,true); + psb->appendLink(ni[0],ni[3],0,true); + psb->appendLink(ni[1],ni[3],0,true); + psb->appendLink(ni[2],ni[3],0,true); + } + } + } +printf("Nodes: %u\r\n",psb->m_nodes.size()); +printf("Links: %u\r\n",psb->m_links.size()); +printf("Faces: %u\r\n",psb->m_faces.size()); +printf("Tetras: %u\r\n",psb->m_tetras.size()); +return(psb); +} + diff --git a/src/BulletSoftBody/btSoftBodyHelpers.h b/src/BulletSoftBody/btSoftBodyHelpers.h new file mode 100644 index 0000000..620a52f --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyHelpers.h @@ -0,0 +1,143 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_HELPERS_H +#define BT_SOFT_BODY_HELPERS_H + +#include "btSoftBody.h" + +// +// Helpers +// + +/* fDrawFlags */ +struct fDrawFlags { enum _ { + Nodes = 0x0001, + Links = 0x0002, + Faces = 0x0004, + Tetras = 0x0008, + Normals = 0x0010, + Contacts = 0x0020, + Anchors = 0x0040, + Notes = 0x0080, + Clusters = 0x0100, + NodeTree = 0x0200, + FaceTree = 0x0400, + ClusterTree = 0x0800, + Joints = 0x1000, + /* presets */ + Std = Links+Faces+Tetras+Anchors+Notes+Joints, + StdTetra = Std-Faces+Tetras +};}; + +struct btSoftBodyHelpers +{ + /* Draw body */ + static void Draw( btSoftBody* psb, + btIDebugDraw* idraw, + int drawflags=fDrawFlags::Std); + /* Draw body infos */ + static void DrawInfos( btSoftBody* psb, + btIDebugDraw* idraw, + bool masses, + bool areas, + bool stress); + /* Draw node tree */ + static void DrawNodeTree( btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth=0, + int maxdepth=-1); + /* Draw face tree */ + static void DrawFaceTree( btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth=0, + int maxdepth=-1); + /* Draw cluster tree */ + static void DrawClusterTree(btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth=0, + int maxdepth=-1); + /* Draw rigid frame */ + static void DrawFrame( btSoftBody* psb, + btIDebugDraw* idraw); + /* Create a rope */ + static btSoftBody* CreateRope( btSoftBodyWorldInfo& worldInfo, + const btVector3& from, + const btVector3& to, + int res, + int fixeds); + /* Create a patch */ + static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo, + const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags); + /* Create a patch with UV Texture Coordinates */ + static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo, + const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags, + float* tex_coords=0); + static float CalculateUV(int resx,int resy,int ix,int iy,int id); + /* Create an ellipsoid */ + static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo, + const btVector3& center, + const btVector3& radius, + int res); + /* Create from trimesh */ + static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo, + const btScalar* vertices, + const int* triangles, + int ntriangles, + bool randomizeConstraints = true); + /* Create from convex-hull */ + static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo, + const btVector3* vertices, + int nvertices, + bool randomizeConstraints = true); + + + /* Export TetGen compatible .smesh file */ +// static void ExportAsSMeshFile( btSoftBody* psb, +// const char* filename); + /* Create from TetGen .ele, .face, .node files */ +// static btSoftBody* CreateFromTetGenFile( btSoftBodyWorldInfo& worldInfo, +// const char* ele, +// const char* face, +// const char* node, +// bool bfacelinks, +// bool btetralinks, +// bool bfacesfromtetras); + /* Create from TetGen .ele, .face, .node data */ + static btSoftBody* CreateFromTetGenData( btSoftBodyWorldInfo& worldInfo, + const char* ele, + const char* face, + const char* node, + bool bfacelinks, + bool btetralinks, + bool bfacesfromtetras); + +}; + +#endif //BT_SOFT_BODY_HELPERS_H diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h new file mode 100644 index 0000000..19d0543 --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -0,0 +1,908 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +///btSoftBody implementation by Nathanael Presson + +#ifndef _BT_SOFT_BODY_INTERNALS_H +#define _BT_SOFT_BODY_INTERNALS_H + +#include "btSoftBody.h" + + +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btPolarDecomposition.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btConvexInternalShape.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#include //for memset +// +// btSymMatrix +// +template +struct btSymMatrix +{ + btSymMatrix() : dim(0) {} + btSymMatrix(int n,const T& init=T()) { resize(n,init); } + void resize(int n,const T& init=T()) { dim=n;store.resize((n*(n+1))/2,init); } + int index(int c,int r) const { if(c>r) btSwap(c,r);btAssert(r store; + int dim; +}; + +// +// btSoftBodyCollisionShape +// +class btSoftBodyCollisionShape : public btConcaveShape +{ +public: + btSoftBody* m_body; + + btSoftBodyCollisionShape(btSoftBody* backptr) + { + m_shapeType = SOFTBODY_SHAPE_PROXYTYPE; + m_body=backptr; + } + + virtual ~btSoftBodyCollisionShape() + { + + } + + void processAllTriangles(btTriangleCallback* /*callback*/,const btVector3& /*aabbMin*/,const btVector3& /*aabbMax*/) const + { + //not yet + btAssert(0); + } + + ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + /* t is usually identity, except when colliding against btCompoundShape. See Issue 512 */ + const btVector3 mins=m_body->m_bounds[0]; + const btVector3 maxs=m_body->m_bounds[1]; + const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()), + t*btVector3(maxs.x(),mins.y(),mins.z()), + t*btVector3(maxs.x(),maxs.y(),mins.z()), + t*btVector3(mins.x(),maxs.y(),mins.z()), + t*btVector3(mins.x(),mins.y(),maxs.z()), + t*btVector3(maxs.x(),mins.y(),maxs.z()), + t*btVector3(maxs.x(),maxs.y(),maxs.z()), + t*btVector3(mins.x(),maxs.y(),maxs.z())}; + aabbMin=aabbMax=crns[0]; + for(int i=1;i<8;++i) + { + aabbMin.setMin(crns[i]); + aabbMax.setMax(crns[i]); + } + } + + + virtual void setLocalScaling(const btVector3& /*scaling*/) + { + ///na + } + virtual const btVector3& getLocalScaling() const + { + static const btVector3 dummy(1,1,1); + return dummy; + } + virtual void calculateLocalInertia(btScalar /*mass*/,btVector3& /*inertia*/) const + { + ///not yet + btAssert(0); + } + virtual const char* getName()const + { + return "SoftBody"; + } + +}; + +// +// btSoftClusterCollisionShape +// +class btSoftClusterCollisionShape : public btConvexInternalShape +{ +public: + const btSoftBody::Cluster* m_cluster; + + btSoftClusterCollisionShape (const btSoftBody::Cluster* cluster) : m_cluster(cluster) { setMargin(0); } + + + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const + { + btSoftBody::Node* const * n=&m_cluster->m_nodes[0]; + btScalar d=btDot(vec,n[0]->m_x); + int j=0; + for(int i=1,ni=m_cluster->m_nodes.size();im_x); + if(k>d) { d=k;j=i; } + } + return(n[j]->m_x); + } + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + { + return(localGetSupportingVertex(vec)); + } + //notice that the vectors should be unit length + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + {} + + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const + {} + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + {} + + virtual int getShapeType() const { return SOFTBODY_SHAPE_PROXYTYPE; } + + //debugging + virtual const char* getName()const {return "SOFTCLUSTER";} + + virtual void setMargin(btScalar margin) + { + btConvexInternalShape::setMargin(margin); + } + virtual btScalar getMargin() const + { + return getMargin(); + } +}; + +// +// Inline's +// + +// +template +static inline void ZeroInitialize(T& value) +{ + memset(&value,0,sizeof(T)); +} +// +template +static inline bool CompLess(const T& a,const T& b) +{ return(a +static inline bool CompGreater(const T& a,const T& b) +{ return(a>b); } +// +template +static inline T Lerp(const T& a,const T& b,btScalar t) +{ return(a+(b-a)*t); } +// +template +static inline T InvLerp(const T& a,const T& b,btScalar t) +{ return((b+a*t-b*t)/(a*b)); } +// +static inline btMatrix3x3 Lerp( const btMatrix3x3& a, + const btMatrix3x3& b, + btScalar t) +{ + btMatrix3x3 r; + r[0]=Lerp(a[0],b[0],t); + r[1]=Lerp(a[1],b[1],t); + r[2]=Lerp(a[2],b[2],t); + return(r); +} +// +static inline btVector3 Clamp(const btVector3& v,btScalar maxlength) +{ + const btScalar sql=v.length2(); + if(sql>(maxlength*maxlength)) + return((v*maxlength)/btSqrt(sql)); + else + return(v); +} +// +template +static inline T Clamp(const T& x,const T& l,const T& h) +{ return(xh?h:x); } +// +template +static inline T Sq(const T& x) +{ return(x*x); } +// +template +static inline T Cube(const T& x) +{ return(x*x*x); } +// +template +static inline T Sign(const T& x) +{ return((T)(x<0?-1:+1)); } +// +template +static inline bool SameSign(const T& x,const T& y) +{ return((x*y)>0); } +// +static inline btScalar ClusterMetric(const btVector3& x,const btVector3& y) +{ + const btVector3 d=x-y; + return(btFabs(d[0])+btFabs(d[1])+btFabs(d[2])); +} +// +static inline btMatrix3x3 ScaleAlongAxis(const btVector3& a,btScalar s) +{ + const btScalar xx=a.x()*a.x(); + const btScalar yy=a.y()*a.y(); + const btScalar zz=a.z()*a.z(); + const btScalar xy=a.x()*a.y(); + const btScalar yz=a.y()*a.z(); + const btScalar zx=a.z()*a.x(); + btMatrix3x3 m; + m[0]=btVector3(1-xx+xx*s,xy*s-xy,zx*s-zx); + m[1]=btVector3(xy*s-xy,1-yy+yy*s,yz*s-yz); + m[2]=btVector3(zx*s-zx,yz*s-yz,1-zz+zz*s); + return(m); +} +// +static inline btMatrix3x3 Cross(const btVector3& v) +{ + btMatrix3x3 m; + m[0]=btVector3(0,-v.z(),+v.y()); + m[1]=btVector3(+v.z(),0,-v.x()); + m[2]=btVector3(-v.y(),+v.x(),0); + return(m); +} +// +static inline btMatrix3x3 Diagonal(btScalar x) +{ + btMatrix3x3 m; + m[0]=btVector3(x,0,0); + m[1]=btVector3(0,x,0); + m[2]=btVector3(0,0,x); + return(m); +} +// +static inline btMatrix3x3 Add(const btMatrix3x3& a, + const btMatrix3x3& b) +{ + btMatrix3x3 r; + for(int i=0;i<3;++i) r[i]=a[i]+b[i]; + return(r); +} +// +static inline btMatrix3x3 Sub(const btMatrix3x3& a, + const btMatrix3x3& b) +{ + btMatrix3x3 r; + for(int i=0;i<3;++i) r[i]=a[i]-b[i]; + return(r); +} +// +static inline btMatrix3x3 Mul(const btMatrix3x3& a, + btScalar b) +{ + btMatrix3x3 r; + for(int i=0;i<3;++i) r[i]=a[i]*b; + return(r); +} +// +static inline void Orthogonalize(btMatrix3x3& m) +{ + m[2]=btCross(m[0],m[1]).normalized(); + m[1]=btCross(m[2],m[0]).normalized(); + m[0]=btCross(m[1],m[2]).normalized(); +} +// +static inline btMatrix3x3 MassMatrix(btScalar im,const btMatrix3x3& iwi,const btVector3& r) +{ + const btMatrix3x3 cr=Cross(r); + return(Sub(Diagonal(im),cr*iwi*cr)); +} + +// +static inline btMatrix3x3 ImpulseMatrix( btScalar dt, + btScalar ima, + btScalar imb, + const btMatrix3x3& iwi, + const btVector3& r) +{ + return(Diagonal(1/dt)*Add(Diagonal(ima),MassMatrix(imb,iwi,r)).inverse()); +} + +// +static inline btMatrix3x3 ImpulseMatrix( btScalar ima,const btMatrix3x3& iia,const btVector3& ra, + btScalar imb,const btMatrix3x3& iib,const btVector3& rb) +{ + return(Add(MassMatrix(ima,iia,ra),MassMatrix(imb,iib,rb)).inverse()); +} + +// +static inline btMatrix3x3 AngularImpulseMatrix( const btMatrix3x3& iia, + const btMatrix3x3& iib) +{ + return(Add(iia,iib).inverse()); +} + +// +static inline btVector3 ProjectOnAxis( const btVector3& v, + const btVector3& a) +{ + return(a*btDot(v,a)); +} +// +static inline btVector3 ProjectOnPlane( const btVector3& v, + const btVector3& a) +{ + return(v-ProjectOnAxis(v,a)); +} + +// +static inline void ProjectOrigin( const btVector3& a, + const btVector3& b, + btVector3& prj, + btScalar& sqd) +{ + const btVector3 d=b-a; + const btScalar m2=d.length2(); + if(m2>SIMD_EPSILON) + { + const btScalar t=Clamp(-btDot(a,d)/m2,0,1); + const btVector3 p=a+d*t; + const btScalar l2=p.length2(); + if(l2SIMD_EPSILON) + { + const btVector3 n=q/btSqrt(m2); + const btScalar k=btDot(a,n); + const btScalar k2=k*k; + if(k20)&& + (btDot(btCross(b-p,c-p),q)>0)&& + (btDot(btCross(c-p,a-p),q)>0)) + { + prj=p; + sqd=k2; + } + else + { + ProjectOrigin(a,b,prj,sqd); + ProjectOrigin(b,c,prj,sqd); + ProjectOrigin(c,a,prj,sqd); + } + } + } +} + +// +template +static inline T BaryEval( const T& a, + const T& b, + const T& c, + const btVector3& coord) +{ + return(a*coord.x()+b*coord.y()+c*coord.z()); +} +// +static inline btVector3 BaryCoord( const btVector3& a, + const btVector3& b, + const btVector3& c, + const btVector3& p) +{ + const btScalar w[]={ btCross(a-p,b-p).length(), + btCross(b-p,c-p).length(), + btCross(c-p,a-p).length()}; + const btScalar isum=1/(w[0]+w[1]+w[2]); + return(btVector3(w[1]*isum,w[2]*isum,w[0]*isum)); +} + +// +static btScalar ImplicitSolve( btSoftBody::ImplicitFn* fn, + const btVector3& a, + const btVector3& b, + const btScalar accuracy, + const int maxiterations=256) +{ + btScalar span[2]={0,1}; + btScalar values[2]={fn->Eval(a),fn->Eval(b)}; + if(values[0]>values[1]) + { + btSwap(span[0],span[1]); + btSwap(values[0],values[1]); + } + if(values[0]>-accuracy) return(-1); + if(values[1]<+accuracy) return(-1); + for(int i=0;iEval(Lerp(a,b,t)); + if((t<=0)||(t>=1)) break; + if(btFabs(v)SIMD_EPSILON) + return(v/l); + else + return(btVector3(0,0,0)); +} + +// +static inline btDbvtVolume VolumeOf( const btSoftBody::Face& f, + btScalar margin) +{ + const btVector3* pts[]={ &f.m_n[0]->m_x, + &f.m_n[1]->m_x, + &f.m_n[2]->m_x}; + btDbvtVolume vol=btDbvtVolume::FromPoints(pts,3); + vol.Expand(btVector3(margin,margin,margin)); + return(vol); +} + +// +static inline btVector3 CenterOf( const btSoftBody::Face& f) +{ + return((f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3); +} + +// +static inline btScalar AreaOf( const btVector3& x0, + const btVector3& x1, + const btVector3& x2) +{ + const btVector3 a=x1-x0; + const btVector3 b=x2-x0; + const btVector3 cr=btCross(a,b); + const btScalar area=cr.length(); + return(area); +} + +// +static inline btScalar VolumeOf( const btVector3& x0, + const btVector3& x1, + const btVector3& x2, + const btVector3& x3) +{ + const btVector3 a=x1-x0; + const btVector3 b=x2-x0; + const btVector3 c=x3-x0; + return(btDot(a,btCross(b,c))); +} + +// +static void EvaluateMedium( const btSoftBodyWorldInfo* wfi, + const btVector3& x, + btSoftBody::sMedium& medium) +{ + medium.m_velocity = btVector3(0,0,0); + medium.m_pressure = 0; + medium.m_density = wfi->air_density; + if(wfi->water_density>0) + { + const btScalar depth=-(btDot(x,wfi->water_normal)+wfi->water_offset); + if(depth>0) + { + medium.m_density = wfi->water_density; + medium.m_pressure = depth*wfi->water_density*wfi->m_gravity.length(); + } + } +} + +// +static inline void ApplyClampedForce( btSoftBody::Node& n, + const btVector3& f, + btScalar dt) +{ + const btScalar dtim=dt*n.m_im; + if((f*dtim).length2()>n.m_v.length2()) + {/* Clamp */ + n.m_f-=ProjectOnAxis(n.m_v,f.normalized())/dtim; + } + else + {/* Apply */ + n.m_f+=f; + } +} + +// +static inline int MatchEdge( const btSoftBody::Node* a, + const btSoftBody::Node* b, + const btSoftBody::Node* ma, + const btSoftBody::Node* mb) +{ + if((a==ma)&&(b==mb)) return(0); + if((a==mb)&&(b==ma)) return(1); + return(-1); +} + +// +// btEigen : Extract eigen system, +// straitforward implementation of http://math.fullerton.edu/mathews/n2003/JacobiMethodMod.html +// outputs are NOT sorted. +// +struct btEigen +{ + static int system(btMatrix3x3& a,btMatrix3x3* vectors,btVector3* values=0) + { + static const int maxiterations=16; + static const btScalar accuracy=(btScalar)0.0001; + btMatrix3x3& v=*vectors; + int iterations=0; + vectors->setIdentity(); + do { + int p=0,q=1; + if(btFabs(a[p][q])accuracy) + { + const btScalar w=(a[q][q]-a[p][p])/(2*a[p][q]); + const btScalar z=btFabs(w); + const btScalar t=w/(z*(btSqrt(1+w*w)+z)); + if(t==t)/* [WARNING] let hope that one does not get thrown aways by some compilers... */ + { + const btScalar c=1/btSqrt(t*t+1); + const btScalar s=c*t; + mulPQ(a,c,s,p,q); + mulTPQ(a,c,s,p,q); + mulPQ(v,c,s,p,q); + } else break; + } else break; + } while((++iterations)data; + btSoftClusterCollisionShape cshape(cluster); + + const btConvexShape* rshape=(const btConvexShape*)m_colObjWrap->getCollisionShape(); + + ///don't collide an anchored cluster with a static/kinematic object + if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject() && cluster->m_containsAnchor) + return; + + btGjkEpaSolver2::sResults res; + if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(), + rshape,m_colObjWrap->getWorldTransform(), + btVector3(1,0,0),res)) + { + btSoftBody::CJoint joint; + if(SolveContact(res,cluster,m_colObjWrap->getCollisionObject(),joint))//prb,joint)) + { + btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); + *pj=joint;psb->m_joints.push_back(pj); + if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject()) + { + pj->m_erp *= psb->m_cfg.kSKHR_CL; + pj->m_split *= psb->m_cfg.kSK_SPLT_CL; + } + else + { + pj->m_erp *= psb->m_cfg.kSRHR_CL; + pj->m_split *= psb->m_cfg.kSR_SPLT_CL; + } + } + } + } + void ProcessColObj(btSoftBody* ps,const btCollisionObjectWrapper* colObWrap) + { + psb = ps; + m_colObjWrap = colObWrap; + idt = ps->m_sst.isdt; + m_margin = m_colObjWrap->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin(); + ///Bullet rigid body uses multiply instead of minimum to determine combined friction. Some customization would be useful. + friction = btMin(psb->m_cfg.kDF,m_colObjWrap->getCollisionObject()->getFriction()); + btVector3 mins; + btVector3 maxs; + + ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; + colObWrap->getCollisionShape()->getAabb(colObWrap->getWorldTransform(),mins,maxs); + volume=btDbvtVolume::FromMM(mins,maxs); + volume.Expand(btVector3(1,1,1)*m_margin); + ps->m_cdbvt.collideTV(ps->m_cdbvt.m_root,volume,*this); + } + }; + // + // CollideCL_SS + // + struct CollideCL_SS : ClusterBase + { + btSoftBody* bodies[2]; + void Process(const btDbvtNode* la,const btDbvtNode* lb) + { + btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data; + btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data; + + + bool connected=false; + if ((bodies[0]==bodies[1])&&(bodies[0]->m_clusterConnectivity.size())) + { + connected = bodies[0]->m_clusterConnectivity[cla->m_clusterIndex+bodies[0]->m_clusters.size()*clb->m_clusterIndex]; + } + + if (!connected) + { + btSoftClusterCollisionShape csa(cla); + btSoftClusterCollisionShape csb(clb); + btGjkEpaSolver2::sResults res; + if(btGjkEpaSolver2::SignedDistance( &csa,btTransform::getIdentity(), + &csb,btTransform::getIdentity(), + cla->m_com-clb->m_com,res)) + { + btSoftBody::CJoint joint; + if(SolveContact(res,cla,clb,joint)) + { + btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); + *pj=joint;bodies[0]->m_joints.push_back(pj); + pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL,bodies[1]->m_cfg.kSSHR_CL); + pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2; + } + } + } else + { + static int count=0; + count++; + //printf("count=%d\n",count); + + } + } + void ProcessSoftSoft(btSoftBody* psa,btSoftBody* psb) + { + idt = psa->m_sst.isdt; + //m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2; + m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin()); + friction = btMin(psa->m_cfg.kDF,psb->m_cfg.kDF); + bodies[0] = psa; + bodies[1] = psb; + psa->m_cdbvt.collideTT(psa->m_cdbvt.m_root,psb->m_cdbvt.m_root,*this); + } + }; + // + // CollideSDF_RS + // + struct CollideSDF_RS : btDbvt::ICollide + { + void Process(const btDbvtNode* leaf) + { + btSoftBody::Node* node=(btSoftBody::Node*)leaf->data; + DoNode(*node); + } + void DoNode(btSoftBody::Node& n) const + { + const btScalar m=n.m_im>0?dynmargin:stamargin; + btSoftBody::RContact c; + + if( (!n.m_battach)&& + psb->checkContact(m_colObj1Wrap,n.m_x,m,c.m_cti)) + { + const btScalar ima=n.m_im; + const btScalar imb= m_rigidBody? m_rigidBody->getInvMass() : 0.f; + const btScalar ms=ima+imb; + if(ms>0) + { + const btTransform& wtr=m_rigidBody?m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); + static const btMatrix3x3 iwiStatic(0,0,0,0,0,0,0,0,0); + const btMatrix3x3& iwi=m_rigidBody?m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; + const btVector3 ra=n.m_x-wtr.getOrigin(); + const btVector3 va=m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra)*psb->m_sst.sdt : btVector3(0,0,0); + const btVector3 vb=n.m_x-n.m_q; + const btVector3 vr=vb-va; + const btScalar dn=btDot(vr,c.m_cti.m_normal); + const btVector3 fv=vr-c.m_cti.m_normal*dn; + const btScalar fc=psb->m_cfg.kDF*m_colObj1Wrap->getCollisionObject()->getFriction(); + c.m_node = &n; + c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra); + c.m_c1 = ra; + c.m_c2 = ima*psb->m_sst.sdt; + c.m_c3 = fv.length2()<(dn*fc*dn*fc)?0:1-fc; + c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR; + psb->m_rcontacts.push_back(c); + if (m_rigidBody) + m_rigidBody->activate(); + } + } + } + btSoftBody* psb; + const btCollisionObjectWrapper* m_colObj1Wrap; + btRigidBody* m_rigidBody; + btScalar dynmargin; + btScalar stamargin; + }; + // + // CollideVF_SS + // + struct CollideVF_SS : btDbvt::ICollide + { + void Process(const btDbvtNode* lnode, + const btDbvtNode* lface) + { + btSoftBody::Node* node=(btSoftBody::Node*)lnode->data; + btSoftBody::Face* face=(btSoftBody::Face*)lface->data; + btVector3 o=node->m_x; + btVector3 p; + btScalar d=SIMD_INFINITY; + ProjectOrigin( face->m_n[0]->m_x-o, + face->m_n[1]->m_x-o, + face->m_n[2]->m_x-o, + p,d); + const btScalar m=mrg+(o-node->m_q).length()*2; + if(d<(m*m)) + { + const btSoftBody::Node* n[]={face->m_n[0],face->m_n[1],face->m_n[2]}; + const btVector3 w=BaryCoord(n[0]->m_x,n[1]->m_x,n[2]->m_x,p+o); + const btScalar ma=node->m_im; + btScalar mb=BaryEval(n[0]->m_im,n[1]->m_im,n[2]->m_im,w); + if( (n[0]->m_im<=0)|| + (n[1]->m_im<=0)|| + (n[2]->m_im<=0)) + { + mb=0; + } + const btScalar ms=ma+mb; + if(ms>0) + { + btSoftBody::SContact c; + c.m_normal = p/-btSqrt(d); + c.m_margin = m; + c.m_node = node; + c.m_face = face; + c.m_weights = w; + c.m_friction = btMax(psb[0]->m_cfg.kDF,psb[1]->m_cfg.kDF); + c.m_cfm[0] = ma/ms*psb[0]->m_cfg.kSHR; + c.m_cfm[1] = mb/ms*psb[1]->m_cfg.kSHR; + psb[0]->m_scontacts.push_back(c); + } + } + } + btSoftBody* psb[2]; + btScalar mrg; + }; +}; + +#endif //_BT_SOFT_BODY_INTERNALS_H diff --git a/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp new file mode 100644 index 0000000..f5a67f6 --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp @@ -0,0 +1,134 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSoftBodyRigidBodyCollisionConfiguration.h" +#include "btSoftRigidCollisionAlgorithm.h" +#include "btSoftBodyConcaveCollisionAlgorithm.h" +#include "btSoftSoftCollisionAlgorithm.h" + +#include "LinearMath/btPoolAllocator.h" + +#define ENABLE_SOFTBODY_CONCAVE_COLLISIONS 1 + +btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo) +:btDefaultCollisionConfiguration(constructionInfo) +{ + void* mem; + + mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16); + m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc; + + mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); + m_softRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; + + mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); + m_swappedSoftRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; + m_swappedSoftRigidConvexCreateFunc->m_swapped=true; + +#ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS + mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); + m_softRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc; + + mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); + m_swappedSoftRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc; + m_swappedSoftRigidConcaveCreateFunc->m_swapped=true; +#endif + + //replace pool by a new one, with potential larger size + + if (m_ownsCollisionAlgorithmPool && m_collisionAlgorithmPool) + { + int curElemSize = m_collisionAlgorithmPool->getElementSize(); + ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool + + + int maxSize0 = sizeof(btSoftSoftCollisionAlgorithm); + int maxSize1 = sizeof(btSoftRigidCollisionAlgorithm); + int maxSize2 = sizeof(btSoftBodyConcaveCollisionAlgorithm); + + int collisionAlgorithmMaxElementSize = btMax(maxSize0,maxSize1); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2); + + if (collisionAlgorithmMaxElementSize > curElemSize) + { + m_collisionAlgorithmPool->~btPoolAllocator(); + btAlignedFree(m_collisionAlgorithmPool); + void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); + m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize); + } + } + +} + +btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration() +{ + m_softSoftCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_softSoftCreateFunc); + + m_softRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_softRigidConvexCreateFunc); + + m_swappedSoftRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_swappedSoftRigidConvexCreateFunc); + +#ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS + m_softRigidConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_softRigidConcaveCreateFunc); + + m_swappedSoftRigidConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_swappedSoftRigidConcaveCreateFunc); +#endif +} + +///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation +btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) +{ + + ///try to handle the softbody interactions first + + if ((proxyType0 == SOFTBODY_SHAPE_PROXYTYPE ) && (proxyType1==SOFTBODY_SHAPE_PROXYTYPE)) + { + return m_softSoftCreateFunc; + } + + ///softbody versus convex + if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConvex(proxyType1)) + { + return m_softRigidConvexCreateFunc; + } + + ///convex versus soft body + if (btBroadphaseProxy::isConvex(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE ) + { + return m_swappedSoftRigidConvexCreateFunc; + } + +#ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS + ///softbody versus convex + if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConcave(proxyType1)) + { + return m_softRigidConcaveCreateFunc; + } + + ///convex versus soft body + if (btBroadphaseProxy::isConcave(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE ) + { + return m_swappedSoftRigidConcaveCreateFunc; + } +#endif + + ///fallback to the regular rigid collision shape + return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0,proxyType1); +} diff --git a/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h new file mode 100644 index 0000000..21addcf --- /dev/null +++ b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h @@ -0,0 +1,48 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION +#define BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION + +#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h" + +class btVoronoiSimplexSolver; +class btGjkEpaPenetrationDepthSolver; + + +///btSoftBodyRigidBodyCollisionConfiguration add softbody interaction on top of btDefaultCollisionConfiguration +class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfiguration +{ + + //default CreationFunctions, filling the m_doubleDispatch table + btCollisionAlgorithmCreateFunc* m_softSoftCreateFunc; + btCollisionAlgorithmCreateFunc* m_softRigidConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc; + +public: + + btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo()); + + virtual ~btSoftBodyRigidBodyCollisionConfiguration(); + + ///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation + virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); + +}; + +#endif //BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION + diff --git a/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h b/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h new file mode 100644 index 0000000..c4733d6 --- /dev/null +++ b/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h @@ -0,0 +1,165 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H +#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H + + +class btVertexBufferDescriptor +{ +public: + enum BufferTypes + { + CPU_BUFFER, + DX11_BUFFER, + OPENGL_BUFFER + }; + +protected: + + bool m_hasVertexPositions; + bool m_hasNormals; + + int m_vertexOffset; + int m_vertexStride; + + int m_normalOffset; + int m_normalStride; + +public: + btVertexBufferDescriptor() + { + m_hasVertexPositions = false; + m_hasNormals = false; + m_vertexOffset = 0; + m_vertexStride = 0; + m_normalOffset = 0; + m_normalStride = 0; + } + + virtual ~btVertexBufferDescriptor() + { + + } + + virtual bool hasVertexPositions() const + { + return m_hasVertexPositions; + } + + virtual bool hasNormals() const + { + return m_hasNormals; + } + + /** + * Return the type of the vertex buffer descriptor. + */ + virtual BufferTypes getBufferType() const = 0; + + /** + * Return the vertex offset in floats from the base pointer. + */ + virtual int getVertexOffset() const + { + return m_vertexOffset; + } + + /** + * Return the vertex stride in number of floats between vertices. + */ + virtual int getVertexStride() const + { + return m_vertexStride; + } + + /** + * Return the vertex offset in floats from the base pointer. + */ + virtual int getNormalOffset() const + { + return m_normalOffset; + } + + /** + * Return the vertex stride in number of floats between vertices. + */ + virtual int getNormalStride() const + { + return m_normalStride; + } +}; + + +class btCPUVertexBufferDescriptor : public btVertexBufferDescriptor +{ +protected: + float *m_basePointer; + +public: + /** + * vertexBasePointer is pointer to beginning of the buffer. + * vertexOffset is the offset in floats to the first vertex. + * vertexStride is the stride in floats between vertices. + */ + btCPUVertexBufferDescriptor( float *basePointer, int vertexOffset, int vertexStride ) + { + m_basePointer = basePointer; + m_vertexOffset = vertexOffset; + m_vertexStride = vertexStride; + m_hasVertexPositions = true; + } + + /** + * vertexBasePointer is pointer to beginning of the buffer. + * vertexOffset is the offset in floats to the first vertex. + * vertexStride is the stride in floats between vertices. + */ + btCPUVertexBufferDescriptor( float *basePointer, int vertexOffset, int vertexStride, int normalOffset, int normalStride ) + { + m_basePointer = basePointer; + + m_vertexOffset = vertexOffset; + m_vertexStride = vertexStride; + m_hasVertexPositions = true; + + m_normalOffset = normalOffset; + m_normalStride = normalStride; + m_hasNormals = true; + } + + virtual ~btCPUVertexBufferDescriptor() + { + + } + + /** + * Return the type of the vertex buffer descriptor. + */ + virtual BufferTypes getBufferType() const + { + return CPU_BUFFER; + } + + /** + * Return the base pointer in memory to the first vertex. + */ + virtual float *getBasePointer() const + { + return m_basePointer; + } +}; + +#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H diff --git a/src/BulletSoftBody/btSoftBodySolvers.h b/src/BulletSoftBody/btSoftBodySolvers.h new file mode 100644 index 0000000..6947bc2 --- /dev/null +++ b/src/BulletSoftBody/btSoftBodySolvers.h @@ -0,0 +1,154 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_BODY_SOLVERS_H +#define BT_SOFT_BODY_SOLVERS_H + +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" + + +class btSoftBodyTriangleData; +class btSoftBodyLinkData; +class btSoftBodyVertexData; +class btVertexBufferDescriptor; +class btCollisionObject; +class btSoftBody; + + +class btSoftBodySolver +{ +public: + enum SolverTypes + { + DEFAULT_SOLVER, + CPU_SOLVER, + CL_SOLVER, + CL_SIMD_SOLVER, + DX_SOLVER, + DX_SIMD_SOLVER + }; + + +protected: + int m_numberOfPositionIterations; + int m_numberOfVelocityIterations; + // Simulation timescale + float m_timeScale; + +public: + btSoftBodySolver() : + m_numberOfPositionIterations( 10 ), + m_timeScale( 1 ) + { + m_numberOfVelocityIterations = 0; + m_numberOfPositionIterations = 5; + } + + virtual ~btSoftBodySolver() + { + } + + /** + * Return the type of the solver. + */ + virtual SolverTypes getSolverType() const = 0; + + + /** Ensure that this solver is initialized. */ + virtual bool checkInitialized() = 0; + + /** Optimize soft bodies in this solver. */ + virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false) = 0; + + /** Copy necessary data back to the original soft body source objects. */ + virtual void copyBackToSoftBodies(bool bMove = true) = 0; + + /** Predict motion of soft bodies into next timestep */ + virtual void predictMotion( float solverdt ) = 0; + + /** Solve constraints for a set of soft bodies */ + virtual void solveConstraints( float solverdt ) = 0; + + /** Perform necessary per-step updates of soft bodies such as recomputing normals and bounding boxes */ + virtual void updateSoftBodies() = 0; + + /** Process a collision between one of the world's soft bodies and another collision object */ + virtual void processCollision( btSoftBody *, const struct btCollisionObjectWrapper* ) = 0; + + /** Process a collision between two soft bodies */ + virtual void processCollision( btSoftBody*, btSoftBody* ) = 0; + + /** Set the number of velocity constraint solver iterations this solver uses. */ + virtual void setNumberOfPositionIterations( int iterations ) + { + m_numberOfPositionIterations = iterations; + } + + /** Get the number of velocity constraint solver iterations this solver uses. */ + virtual int getNumberOfPositionIterations() + { + return m_numberOfPositionIterations; + } + + /** Set the number of velocity constraint solver iterations this solver uses. */ + virtual void setNumberOfVelocityIterations( int iterations ) + { + m_numberOfVelocityIterations = iterations; + } + + /** Get the number of velocity constraint solver iterations this solver uses. */ + virtual int getNumberOfVelocityIterations() + { + return m_numberOfVelocityIterations; + } + + /** Return the timescale that the simulation is using */ + float getTimeScale() + { + return m_timeScale; + } + +#if 0 + /** + * Add a collision object to be used by the indicated softbody. + */ + virtual void addCollisionObjectForSoftBody( int clothIdentifier, btCollisionObject *collisionObject ) = 0; +#endif +}; + +/** + * Class to manage movement of data from a solver to a given target. + * This version is abstract. Subclasses will have custom pairings for different combinations. + */ +class btSoftBodySolverOutput +{ +protected: + +public: + btSoftBodySolverOutput() + { + } + + virtual ~btSoftBodySolverOutput() + { + } + + + /** Output current computed vertex data to the vertex buffers for all cloths in the solver. */ + virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ) = 0; +}; + + +#endif // #ifndef BT_SOFT_BODY_SOLVERS_H diff --git a/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp new file mode 100644 index 0000000..01c148a --- /dev/null +++ b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp @@ -0,0 +1,86 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSoftRigidCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "btSoftBody.h" +#include "BulletSoftBody/btSoftBodySolvers.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +///TODO: include all the shapes that the softbody can collide with +///alternatively, implement special case collision algorithms (just like for rigid collision shapes) + +//#include + +btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* , bool isSwapped) +: btCollisionAlgorithm(ci), +//m_ownManifold(false), +//m_manifoldPtr(mf), +m_isSwapped(isSwapped) +{ +} + + +btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm() +{ + + //m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject); + + /*if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } + */ + +} + + +#include + +void btSoftRigidCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)dispatchInfo; + (void)resultOut; + //printf("btSoftRigidCollisionAlgorithm\n"); +// const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap; +// const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap; + btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject(); + const btCollisionObjectWrapper* rigidCollisionObjectWrap = m_isSwapped? body0Wrap : body1Wrap; + + if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObjectWrap->getCollisionObject())==softBody->m_collisionDisabledObjects.size()) + { + softBody->getSoftBodySolver()->processCollision(softBody, rigidCollisionObjectWrap); + } + + +} + +btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + (void)col0; + (void)col1; + + //not yet + return btScalar(1.); +} + + + diff --git a/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h new file mode 100644 index 0000000..a9b513e --- /dev/null +++ b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h @@ -0,0 +1,75 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_RIGID_COLLISION_ALGORITHM_H +#define BT_SOFT_RIGID_COLLISION_ALGORITHM_H + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +class btPersistentManifold; +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" + +#include "LinearMath/btVector3.h" +class btSoftBody; + +/// btSoftRigidCollisionAlgorithm provides collision detection between btSoftBody and btRigidBody +class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm +{ + // bool m_ownManifold; + // btPersistentManifold* m_manifoldPtr; + + btSoftBody* m_softBody; + btCollisionObject* m_rigidCollisionObject; + + ///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean + bool m_isSwapped; + +public: + + btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0,const btCollisionObjectWrapper* col1Wrap, bool isSwapped); + + virtual ~btSoftRigidCollisionAlgorithm(); + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + //we don't add any manifolds + } + + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftRigidCollisionAlgorithm)); + if (!m_swapped) + { + return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false); + } else + { + return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true); + } + } + }; + +}; + +#endif //BT_SOFT_RIGID_COLLISION_ALGORITHM_H + + diff --git a/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp b/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp new file mode 100644 index 0000000..5f35935 --- /dev/null +++ b/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp @@ -0,0 +1,367 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "btSoftRigidDynamicsWorld.h" +#include "LinearMath/btQuickprof.h" + +//softbody & helpers +#include "btSoftBody.h" +#include "btSoftBodyHelpers.h" +#include "btSoftBodySolvers.h" +#include "btDefaultSoftBodySolver.h" +#include "LinearMath/btSerializer.h" + + +btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld( + btDispatcher* dispatcher, + btBroadphaseInterface* pairCache, + btConstraintSolver* constraintSolver, + btCollisionConfiguration* collisionConfiguration, + btSoftBodySolver *softBodySolver ) : + btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration), + m_softBodySolver( softBodySolver ), + m_ownsSolver(false) +{ + if( !m_softBodySolver ) + { + void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver),16); + m_softBodySolver = new(ptr) btDefaultSoftBodySolver(); + m_ownsSolver = true; + } + + m_drawFlags = fDrawFlags::Std; + m_drawNodeTree = true; + m_drawFaceTree = false; + m_drawClusterTree = false; + m_sbi.m_broadphase = pairCache; + m_sbi.m_dispatcher = dispatcher; + m_sbi.m_sparsesdf.Initialize(); + m_sbi.m_sparsesdf.Reset(); + + m_sbi.air_density = (btScalar)1.2; + m_sbi.water_density = 0; + m_sbi.water_offset = 0; + m_sbi.water_normal = btVector3(0,0,0); + m_sbi.m_gravity.setValue(0,-10,0); + + m_sbi.m_sparsesdf.Initialize(); + + +} + +btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld() +{ + if (m_ownsSolver) + { + m_softBodySolver->~btSoftBodySolver(); + btAlignedFree(m_softBodySolver); + } +} + +void btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +{ + btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep ); + { + BT_PROFILE("predictUnconstraintMotionSoftBody"); + m_softBodySolver->predictMotion( timeStep ); + } +} + +void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep ) +{ + + // Let the solver grab the soft bodies and if necessary optimize for it + m_softBodySolver->optimize( getSoftBodyArray() ); + + if( !m_softBodySolver->checkInitialized() ) + { + btAssert( "Solver initialization failed\n" ); + } + + btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep ); + + ///solve soft bodies constraints + solveSoftBodiesConstraints( timeStep ); + + //self collisions + for ( int i=0;idefaultCollisionHandler(psb); + } + + ///update soft bodies + m_softBodySolver->updateSoftBodies( ); + + // End solver-wise simulation step + // /////////////////////////////// + +} + +void btSoftRigidDynamicsWorld::solveSoftBodiesConstraints( btScalar timeStep ) +{ + BT_PROFILE("solveSoftConstraints"); + + if(m_softBodies.size()) + { + btSoftBody::solveClusters(m_softBodies); + } + + // Solve constraints solver-wise + m_softBodySolver->solveConstraints( timeStep * m_softBodySolver->getTimeScale() ); + +} + +void btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body,short int collisionFilterGroup,short int collisionFilterMask) +{ + m_softBodies.push_back(body); + + // Set the soft body solver that will deal with this body + // to be the world's solver + body->setSoftBodySolver( m_softBodySolver ); + + btCollisionWorld::addCollisionObject(body, + collisionFilterGroup, + collisionFilterMask); + +} + +void btSoftRigidDynamicsWorld::removeSoftBody(btSoftBody* body) +{ + m_softBodies.remove(body); + + btCollisionWorld::removeCollisionObject(body); +} + +void btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) +{ + btSoftBody* body = btSoftBody::upcast(collisionObject); + if (body) + removeSoftBody(body); + else + btDiscreteDynamicsWorld::removeCollisionObject(collisionObject); +} + +void btSoftRigidDynamicsWorld::debugDrawWorld() +{ + btDiscreteDynamicsWorld::debugDrawWorld(); + + if (getDebugDrawer()) + { + int i; + for ( i=0;im_softBodies.size();i++) + { + btSoftBody* psb=(btSoftBody*)this->m_softBodies[i]; + if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) + { + btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer); + btSoftBodyHelpers::Draw(psb,m_debugDrawer,m_drawFlags); + } + + if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) + { + if(m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer); + if(m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb,m_debugDrawer); + if(m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb,m_debugDrawer); + } + } + } +} + + + + +struct btSoftSingleRayCallback : public btBroadphaseRayCallback +{ + btVector3 m_rayFromWorld; + btVector3 m_rayToWorld; + btTransform m_rayFromTrans; + btTransform m_rayToTrans; + btVector3 m_hitNormal; + + const btSoftRigidDynamicsWorld* m_world; + btCollisionWorld::RayResultCallback& m_resultCallback; + + btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftRigidDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback) + :m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld), + m_world(world), + m_resultCallback(resultCallback) + { + m_rayFromTrans.setIdentity(); + m_rayFromTrans.setOrigin(m_rayFromWorld); + m_rayToTrans.setIdentity(); + m_rayToTrans.setOrigin(m_rayToWorld); + + btVector3 rayDir = (rayToWorld-rayFromWorld); + + rayDir.normalize (); + ///what about division by zero? --> just set rayDirection[i] to INF/1e30 + m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; + m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; + m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2]; + m_signs[0] = m_rayDirectionInverse[0] < 0.0; + m_signs[1] = m_rayDirectionInverse[1] < 0.0; + m_signs[2] = m_rayDirectionInverse[2] < 0.0; + + m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld); + + } + + + + virtual bool process(const btBroadphaseProxy* proxy) + { + ///terminate further ray tests, once the closestHitFraction reached zero + if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) + return false; + + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + + //only perform raycast if filterMask matches + if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + { + //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); + //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; +#if 0 +#ifdef RECALCULATE_AABB + btVector3 collisionObjectAabbMin,collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); +#else + //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax); + const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin; + const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax; +#endif +#endif + //btScalar hitLambda = m_resultCallback.m_closestHitFraction; + //culling already done by broadphase + //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal)) + { + m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback); + } + } + return true; + } +}; + +void btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const +{ + BT_PROFILE("rayTest"); + /// use the broadphase to accelerate the search for objects, based on their aabb + /// and for each object with ray-aabb overlap, perform an exact ray test + btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback); + +#ifndef USE_BRUTEFORCE_RAYBROADPHASE + m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB); +#else + for (int i=0;igetNumCollisionObjects();i++) + { + rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); + } +#endif //USE_BRUTEFORCE_RAYBROADPHASE + +} + + +void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback) +{ + if (collisionShape->isSoftBody()) { + btSoftBody* softBody = btSoftBody::upcast(collisionObject); + if (softBody) { + btSoftBody::sRayCast softResult; + if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) + { + + if (softResult.fraction<= resultCallback.m_closestHitFraction) + { + + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = 0; + shapeInfo.m_triangleIndex = softResult.index; + // get the normal + btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin(); + btVector3 normal=-rayDir; + normal.normalize(); + + if (softResult.feature == btSoftBody::eFeature::Face) + { + normal = softBody->m_faces[softResult.index].m_normal; + if (normal.dot(rayDir) > 0) { + // normal always point toward origin of the ray + normal = -normal; + } + } + + btCollisionWorld::LocalRayResult rayResult + (collisionObject, + &shapeInfo, + normal, + softResult.fraction); + bool normalInWorldSpace = true; + resultCallback.addSingleResult(rayResult,normalInWorldSpace); + } + } + } + } + else { + btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback); + } +} + + +void btSoftRigidDynamicsWorld::serializeSoftBodies(btSerializer* serializer) +{ + int i; + //serialize all collision objects + for (i=0;igetInternalType() & btCollisionObject::CO_SOFT_BODY) + { + int len = colObj->calculateSerializeBufferSize(); + btChunk* chunk = serializer->allocate(len,1); + const char* structType = colObj->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk,structType,BT_SOFTBODY_CODE,colObj); + } + } + +} + +void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer) +{ + + serializer->startSerialization(); + + serializeDynamicsWorldInfo( serializer); + + serializeSoftBodies(serializer); + + serializeRigidBodies(serializer); + + serializeCollisionObjects(serializer); + + serializer->finishSerialization(); +} + + diff --git a/src/BulletSoftBody/btSoftRigidDynamicsWorld.h b/src/BulletSoftBody/btSoftRigidDynamicsWorld.h new file mode 100644 index 0000000..3e0efaf --- /dev/null +++ b/src/BulletSoftBody/btSoftRigidDynamicsWorld.h @@ -0,0 +1,107 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_RIGID_DYNAMICS_WORLD_H +#define BT_SOFT_RIGID_DYNAMICS_WORLD_H + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "btSoftBody.h" + +typedef btAlignedObjectArray btSoftBodyArray; + +class btSoftBodySolver; + +class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld +{ + + btSoftBodyArray m_softBodies; + int m_drawFlags; + bool m_drawNodeTree; + bool m_drawFaceTree; + bool m_drawClusterTree; + btSoftBodyWorldInfo m_sbi; + ///Solver classes that encapsulate multiple soft bodies for solving + btSoftBodySolver *m_softBodySolver; + bool m_ownsSolver; + +protected: + + virtual void predictUnconstraintMotion(btScalar timeStep); + + virtual void internalSingleStepSimulation( btScalar timeStep); + + void solveSoftBodiesConstraints( btScalar timeStep ); + + void serializeSoftBodies(btSerializer* serializer); + +public: + + btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver *softBodySolver = 0 ); + + virtual ~btSoftRigidDynamicsWorld(); + + virtual void debugDrawWorld(); + + void addSoftBody(btSoftBody* body,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter); + + void removeSoftBody(btSoftBody* body); + + ///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btDiscreteDynamicsWorld::removeCollisionObject + virtual void removeCollisionObject(btCollisionObject* collisionObject); + + int getDrawFlags() const { return(m_drawFlags); } + void setDrawFlags(int f) { m_drawFlags=f; } + + btSoftBodyWorldInfo& getWorldInfo() + { + return m_sbi; + } + const btSoftBodyWorldInfo& getWorldInfo() const + { + return m_sbi; + } + + virtual btDynamicsWorldType getWorldType() const + { + return BT_SOFT_RIGID_DYNAMICS_WORLD; + } + + btSoftBodyArray& getSoftBodyArray() + { + return m_softBodies; + } + + const btSoftBodyArray& getSoftBodyArray() const + { + return m_softBodies; + } + + + virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; + + /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. + /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. + /// This allows more customization. + static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback); + + virtual void serialize(btSerializer* serializer); + +}; + +#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp new file mode 100644 index 0000000..72043e6 --- /dev/null +++ b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp @@ -0,0 +1,48 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btSoftSoftCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletSoftBody/btSoftBodySolvers.h" +#include "btSoftBody.h" +#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" + +#define USE_PERSISTENT_CONTACTS 1 + +btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* /*obj0*/,const btCollisionObjectWrapper* /*obj1*/) +: btCollisionAlgorithm(ci) +//m_ownManifold(false), +//m_manifoldPtr(mf) +{ +} + +btSoftSoftCollisionAlgorithm::~btSoftSoftCollisionAlgorithm() +{ +} + +void btSoftSoftCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +{ + btSoftBody* soft0 = (btSoftBody*)body0Wrap->getCollisionObject(); + btSoftBody* soft1 = (btSoftBody*)body1Wrap->getCollisionObject(); + soft0->getSoftBodySolver()->processCollision(soft0, soft1); +} + +btScalar btSoftSoftCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +{ + //not yet + return 1.f; +} diff --git a/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h new file mode 100644 index 0000000..43b1439 --- /dev/null +++ b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h @@ -0,0 +1,69 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SOFT_SOFT_COLLISION_ALGORITHM_H +#define BT_SOFT_SOFT_COLLISION_ALGORITHM_H + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" + +class btPersistentManifold; +class btSoftBody; + +///collision detection between two btSoftBody shapes +class btSoftSoftCollisionAlgorithm : public btCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + + btSoftBody* m_softBody0; + btSoftBody* m_softBody1; + + +public: + btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btCollisionAlgorithm(ci) {} + + virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + { + if (m_manifoldPtr && m_ownManifold) + manifoldArray.push_back(m_manifoldPtr); + } + + btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + + virtual ~btSoftSoftCollisionAlgorithm(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + { + int bbsize = sizeof(btSoftSoftCollisionAlgorithm); + void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize); + return new(ptr) btSoftSoftCollisionAlgorithm(0,ci,body0Wrap,body1Wrap); + } + }; + +}; + +#endif //BT_SOFT_SOFT_COLLISION_ALGORITHM_H + + diff --git a/src/BulletSoftBody/btSparseSDF.h b/src/BulletSoftBody/btSparseSDF.h new file mode 100644 index 0000000..180e3c2 --- /dev/null +++ b/src/BulletSoftBody/btSparseSDF.h @@ -0,0 +1,306 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +///btSparseSdf implementation by Nathanael Presson + +#ifndef BT_SPARSE_SDF_H +#define BT_SPARSE_SDF_H + +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" + +// Modified Paul Hsieh hash +template +unsigned int HsiehHash(const void* pdata) +{ + const unsigned short* data=(const unsigned short*)pdata; + unsigned hash=DWORDLEN<<2,tmp; + for(int i=0;i>11; + } + hash^=hash<<3;hash+=hash>>5; + hash^=hash<<4;hash+=hash>>17; + hash^=hash<<25;hash+=hash>>6; + return(hash); +} + +template +struct btSparseSdf +{ + // + // Inner types + // + struct IntFrac + { + int b; + int i; + btScalar f; + }; + struct Cell + { + btScalar d[CELLSIZE+1][CELLSIZE+1][CELLSIZE+1]; + int c[3]; + int puid; + unsigned hash; + const btCollisionShape* pclient; + Cell* next; + }; + // + // Fields + // + + btAlignedObjectArray cells; + btScalar voxelsz; + int puid; + int ncells; + int nprobes; + int nqueries; + + // + // Methods + // + + // + void Initialize(int hashsize=2383) + { + cells.resize(hashsize,0); + Reset(); + } + // + void Reset() + { + for(int i=0,ni=cells.size();inext; + delete pc; + pc=pn; + } + } + voxelsz =0.25; + puid =0; + ncells =0; + nprobes =1; + nqueries =1; + } + // + void GarbageCollect(int lifetime=256) + { + const int life=puid-lifetime; + for(int i=0;inext; + if(pc->puidnext=pn; else root=pn; + delete pc;pc=pp;--ncells; + } + pp=pc;pc=pn; + } + } + //printf("GC[%d]: %d cells, PpQ: %f\r\n",puid,ncells,nprobes/(btScalar)nqueries); + nqueries=1; + nprobes=1; + ++puid; ///@todo: Reset puid's when int range limit is reached */ + /* else setup a priority list... */ + } + // + int RemoveReferences(btCollisionShape* pcs) + { + int refcount=0; + for(int i=0;inext; + if(pc->pclient==pcs) + { + if(pp) pp->next=pn; else root=pn; + delete pc;pc=pp;++refcount; + } + pp=pc;pc=pn; + } + } + return(refcount); + } + // + btScalar Evaluate( const btVector3& x, + const btCollisionShape* shape, + btVector3& normal, + btScalar margin) + { + /* Lookup cell */ + const btVector3 scx=x/voxelsz; + const IntFrac ix=Decompose(scx.x()); + const IntFrac iy=Decompose(scx.y()); + const IntFrac iz=Decompose(scx.z()); + const unsigned h=Hash(ix.b,iy.b,iz.b,shape); + Cell*& root=cells[static_cast(h%cells.size())]; + Cell* c=root; + ++nqueries; + while(c) + { + ++nprobes; + if( (c->hash==h) && + (c->c[0]==ix.b) && + (c->c[1]==iy.b) && + (c->c[2]==iz.b) && + (c->pclient==shape)) + { break; } + else + { c=c->next; } + } + if(!c) + { + ++nprobes; + ++ncells; + c=new Cell(); + c->next=root;root=c; + c->pclient=shape; + c->hash=h; + c->c[0]=ix.b;c->c[1]=iy.b;c->c[2]=iz.b; + BuildCell(*c); + } + c->puid=puid; + /* Extract infos */ + const int o[]={ ix.i,iy.i,iz.i}; + const btScalar d[]={ c->d[o[0]+0][o[1]+0][o[2]+0], + c->d[o[0]+1][o[1]+0][o[2]+0], + c->d[o[0]+1][o[1]+1][o[2]+0], + c->d[o[0]+0][o[1]+1][o[2]+0], + c->d[o[0]+0][o[1]+0][o[2]+1], + c->d[o[0]+1][o[1]+0][o[2]+1], + c->d[o[0]+1][o[1]+1][o[2]+1], + c->d[o[0]+0][o[1]+1][o[2]+1]}; + /* Normal */ +#if 1 + const btScalar gx[]={ d[1]-d[0],d[2]-d[3], + d[5]-d[4],d[6]-d[7]}; + const btScalar gy[]={ d[3]-d[0],d[2]-d[1], + d[7]-d[4],d[6]-d[5]}; + const btScalar gz[]={ d[4]-d[0],d[5]-d[1], + d[7]-d[3],d[6]-d[2]}; + normal.setX(Lerp( Lerp(gx[0],gx[1],iy.f), + Lerp(gx[2],gx[3],iy.f),iz.f)); + normal.setY(Lerp( Lerp(gy[0],gy[1],ix.f), + Lerp(gy[2],gy[3],ix.f),iz.f)); + normal.setZ(Lerp( Lerp(gz[0],gz[1],ix.f), + Lerp(gz[2],gz[3],ix.f),iy.f)); + normal = normal.normalized(); +#else + normal = btVector3(d[1]-d[0],d[3]-d[0],d[4]-d[0]).normalized(); +#endif + /* Distance */ + const btScalar d0=Lerp(Lerp(d[0],d[1],ix.f), + Lerp(d[3],d[2],ix.f),iy.f); + const btScalar d1=Lerp(Lerp(d[4],d[5],ix.f), + Lerp(d[7],d[6],ix.f),iy.f); + return(Lerp(d0,d1,iz.f)-margin); + } + // + void BuildCell(Cell& c) + { + const btVector3 org=btVector3( (btScalar)c.c[0], + (btScalar)c.c[1], + (btScalar)c.c[2]) * + CELLSIZE*voxelsz; + for(int k=0;k<=CELLSIZE;++k) + { + const btScalar z=voxelsz*k+org.z(); + for(int j=0;j<=CELLSIZE;++j) + { + const btScalar y=voxelsz*j+org.y(); + for(int i=0;i<=CELLSIZE;++i) + { + const btScalar x=voxelsz*i+org.x(); + c.d[i][j][k]=DistanceToShape( btVector3(x,y,z), + c.pclient); + } + } + } + } + // + static inline btScalar DistanceToShape(const btVector3& x, + const btCollisionShape* shape) + { + btTransform unit; + unit.setIdentity(); + if(shape->isConvex()) + { + btGjkEpaSolver2::sResults res; + const btConvexShape* csh=static_cast(shape); + return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res)); + } + return(0); + } + // + static inline IntFrac Decompose(btScalar x) + { + /* That one need a lot of improvements... */ + /* Remove test, faster floor... */ + IntFrac r; + x/=CELLSIZE; + const int o=x<0?(int)(-x+1):0; + x+=o;r.b=(int)x; + const btScalar k=(x-r.b)*CELLSIZE; + r.i=(int)k;r.f=k-r.i;r.b-=o; + return(r); + } + // + static inline btScalar Lerp(btScalar a,btScalar b,btScalar t) + { + return(a+(b-a)*t); + } + + + + // + static inline unsigned int Hash(int x,int y,int z,const btCollisionShape* shape) + { + struct btS + { + int x,y,z; + void* p; + }; + + btS myset; + + myset.x=x;myset.y=y;myset.z=z;myset.p=(void*)shape; + const void* ptr = &myset; + + unsigned int result = HsiehHash (ptr); + + + return result; + } +}; + + +#endif //BT_SPARSE_SDF_H diff --git a/src/BulletSoftBody/premake4.lua b/src/BulletSoftBody/premake4.lua new file mode 100644 index 0000000..2c78bbb --- /dev/null +++ b/src/BulletSoftBody/premake4.lua @@ -0,0 +1,11 @@ + project "BulletSoftBody" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + "..", + } + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3a736b4 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,32 @@ +SUBDIRS( BulletSoftBody BulletCollision BulletDynamics LinearMath ) + +IF(BUILD_MULTITHREADING) + SUBDIRS(MiniCL BulletMultiThreaded) +ENDIF() + +IF(INSTALL_LIBS) + #INSTALL of other files requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + # Don't actually need to install any common files, the frameworks include everything + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(FILES btBulletCollisionCommon.h btBulletDynamicsCommon.h Bullet-C-Api.h DESTINATION ${INCLUDE_INSTALL_DIR}) + INSTALL(FILES vectormath/vmInclude.h DESTINATION ${INCLUDE_INSTALL_DIR}/vectormath) + INSTALL(FILES vectormath/scalar/boolInVec.h + vectormath/scalar/floatInVec.h + vectormath/scalar/mat_aos.h + vectormath/scalar/quat_aos.h + vectormath/scalar/vec_aos.h + vectormath/scalar/vectormath_aos.h + DESTINATION ${INCLUDE_INSTALL_DIR}/vectormath/scalar) + INSTALL(FILES vectormath/sse/boolInVec.h + vectormath/sse/floatInVec.h + vectormath/sse/mat_aos.h + vectormath/sse/quat_aos.h + vectormath/sse/vec_aos.h + vectormath/sse/vecidx_aos.h + vectormath/sse/vectormath_aos.h + DESTINATION ${INCLUDE_INSTALL_DIR}/vectormath/sse) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) +ENDIF(INSTALL_LIBS) diff --git a/src/LinearMath/CMakeLists.txt b/src/LinearMath/CMakeLists.txt new file mode 100644 index 0000000..cc77583 --- /dev/null +++ b/src/LinearMath/CMakeLists.txt @@ -0,0 +1,69 @@ + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src +) + +SET(LinearMath_SRCS + btAlignedAllocator.cpp + btConvexHull.cpp + btConvexHullComputer.cpp + btGeometryUtil.cpp + btPolarDecomposition.cpp + btQuickprof.cpp + btSerializer.cpp + btVector3.cpp +) + +SET(LinearMath_HDRS + btAabbUtil2.h + btAlignedAllocator.h + btAlignedObjectArray.h + btConvexHull.h + btConvexHullComputer.h + btDefaultMotionState.h + btGeometryUtil.h + btGrahamScan2dConvexHull.h + btHashMap.h + btIDebugDraw.h + btList.h + btMatrix3x3.h + btMinMax.h + btMotionState.h + btPolarDecomposition.h + btPoolAllocator.h + btQuadWord.h + btQuaternion.h + btQuickprof.h + btRandom.h + btScalar.h + btSerializer.h + btStackAlloc.h + btTransform.h + btTransformUtil.h + btVector3.h +) + +ADD_LIBRARY(LinearMath ${LinearMath_SRCS} ${LinearMath_HDRS}) +SET_TARGET_PROPERTIES(LinearMath PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(LinearMath PROPERTIES SOVERSION ${BULLET_VERSION}) + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #FILES_MATCHING requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS LinearMath DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS LinearMath DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN +".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(LinearMath PROPERTIES FRAMEWORK true) + SET_TARGET_PROPERTIES(LinearMath PROPERTIES PUBLIC_HEADER "${LinearMath_HDRS}") + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) diff --git a/src/LinearMath/btAabbUtil2.h b/src/LinearMath/btAabbUtil2.h new file mode 100644 index 0000000..d2997b4 --- /dev/null +++ b/src/LinearMath/btAabbUtil2.h @@ -0,0 +1,232 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_AABB_UTIL2 +#define BT_AABB_UTIL2 + +#include "btTransform.h" +#include "btVector3.h" +#include "btMinMax.h" + + + +SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin, + btVector3& aabbMax, + const btVector3& expansionMin, + const btVector3& expansionMax) +{ + aabbMin = aabbMin + expansionMin; + aabbMax = aabbMax + expansionMax; +} + +/// conservative test for overlap between two aabbs +SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, + const btVector3 &point) +{ + bool overlap = true; + overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap; + overlap = (aabbMin1.getZ() > point.getZ() || aabbMax1.getZ() < point.getZ()) ? false : overlap; + overlap = (aabbMin1.getY() > point.getY() || aabbMax1.getY() < point.getY()) ? false : overlap; + return overlap; +} + + +/// conservative test for overlap between two aabbs +SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, + const btVector3 &aabbMin2, const btVector3 &aabbMax2) +{ + bool overlap = true; + overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap; + overlap = (aabbMin1.getZ() > aabbMax2.getZ() || aabbMax1.getZ() < aabbMin2.getZ()) ? false : overlap; + overlap = (aabbMin1.getY() > aabbMax2.getY() || aabbMax1.getY() < aabbMin2.getY()) ? false : overlap; + return overlap; +} + +/// conservative test for overlap between triangle and aabb +SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices, + const btVector3 &aabbMin, const btVector3 &aabbMax) +{ + const btVector3 &p1 = vertices[0]; + const btVector3 &p2 = vertices[1]; + const btVector3 &p3 = vertices[2]; + + if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false; + if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false; + + if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false; + if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false; + + if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false; + if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false; + return true; +} + + +SIMD_FORCE_INLINE int btOutcode(const btVector3& p,const btVector3& halfExtent) +{ + return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) | + (p.getX() > halfExtent.getX() ? 0x08 : 0x0) | + (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) | + (p.getY() > halfExtent.getY() ? 0x10 : 0x0) | + (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) | + (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); +} + + + +SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom, + const btVector3& rayInvDirection, + const unsigned int raySign[3], + const btVector3 bounds[2], + btScalar& tmin, + btScalar lambda_min, + btScalar lambda_max) +{ + btScalar tmax, tymin, tymax, tzmin, tzmax; + tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); + tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); + tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); + tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); + + if ( (tmin > tymax) || (tymin > tmax) ) + return false; + + if (tymin > tmin) + tmin = tymin; + + if (tymax < tmax) + tmax = tymax; + + tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); + tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); + + if ( (tmin > tzmax) || (tzmin > tmax) ) + return false; + if (tzmin > tmin) + tmin = tzmin; + if (tzmax < tmax) + tmax = tzmax; + return ( (tmin < lambda_max) && (tmax > lambda_min) ); +} + +SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& aabbMin, + const btVector3& aabbMax, + btScalar& param, btVector3& normal) +{ + btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5); + btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5); + btVector3 source = rayFrom - aabbCenter; + btVector3 target = rayTo - aabbCenter; + int sourceOutcode = btOutcode(source,aabbHalfExtent); + int targetOutcode = btOutcode(target,aabbHalfExtent); + if ((sourceOutcode & targetOutcode) == 0x0) + { + btScalar lambda_enter = btScalar(0.0); + btScalar lambda_exit = param; + btVector3 r = target - source; + int i; + btScalar normSign = 1; + btVector3 hitNormal(0,0,0); + int bit=1; + + for (int j=0;j<2;j++) + { + for (i = 0; i != 3; ++i) + { + if (sourceOutcode & bit) + { + btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + if (lambda_enter <= lambda) + { + lambda_enter = lambda; + hitNormal.setValue(0,0,0); + hitNormal[i] = normSign; + } + } + else if (targetOutcode & bit) + { + btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + btSetMin(lambda_exit, lambda); + } + bit<<=1; + } + normSign = btScalar(-1.); + } + if (lambda_enter <= lambda_exit) + { + param = lambda_enter; + normal = hitNormal; + return true; + } + } + return false; +} + + + +SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar margin,const btTransform& t,btVector3& aabbMinOut,btVector3& aabbMaxOut) +{ + btVector3 halfExtentsWithMargin = halfExtents+btVector3(margin,margin,margin); + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtentsWithMargin.dot3( abs_b[0], abs_b[1], abs_b[2] ); + aabbMinOut = center - extent; + aabbMaxOut = center + extent; +} + + +SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin,const btVector3& localAabbMax, btScalar margin,const btTransform& trans,btVector3& aabbMinOut,btVector3& aabbMaxOut) +{ + btAssert(localAabbMin.getX() <= localAabbMax.getX()); + btAssert(localAabbMin.getY() <= localAabbMax.getY()); + btAssert(localAabbMin.getZ() <= localAabbMax.getZ()); + btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin); + localHalfExtents+=btVector3(margin,margin,margin); + + btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin); + btMatrix3x3 abs_b = trans.getBasis().absolute(); + btVector3 center = trans(localCenter); + btVector3 extent = localHalfExtents.dot3( abs_b[0], abs_b[1], abs_b[2] ); + aabbMinOut = center-extent; + aabbMaxOut = center+extent; +} + +#define USE_BANCHLESS 1 +#ifdef USE_BANCHLESS + //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) + SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) + { + return static_cast(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) + & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) + & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), + 1, 0)); + } +#else + SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) + { + bool overlap = true; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; + overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; + overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; + return overlap; + } +#endif //USE_BANCHLESS + +#endif //BT_AABB_UTIL2 + + diff --git a/src/LinearMath/btAlignedAllocator.cpp b/src/LinearMath/btAlignedAllocator.cpp new file mode 100644 index 0000000..a65296c --- /dev/null +++ b/src/LinearMath/btAlignedAllocator.cpp @@ -0,0 +1,181 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btAlignedAllocator.h" + +int gNumAlignedAllocs = 0; +int gNumAlignedFree = 0; +int gTotalBytesAlignedAllocs = 0;//detect memory leaks + +static void *btAllocDefault(size_t size) +{ + return malloc(size); +} + +static void btFreeDefault(void *ptr) +{ + free(ptr); +} + +static btAllocFunc *sAllocFunc = btAllocDefault; +static btFreeFunc *sFreeFunc = btFreeDefault; + + + +#if defined (BT_HAS_ALIGNED_ALLOCATOR) +#include +static void *btAlignedAllocDefault(size_t size, int alignment) +{ + return _aligned_malloc(size, (size_t)alignment); +} + +static void btAlignedFreeDefault(void *ptr) +{ + _aligned_free(ptr); +} +#elif defined(__CELLOS_LV2__) +#include + +static inline void *btAlignedAllocDefault(size_t size, int alignment) +{ + return memalign(alignment, size); +} + +static inline void btAlignedFreeDefault(void *ptr) +{ + free(ptr); +} +#else + + + + + +static inline void *btAlignedAllocDefault(size_t size, int alignment) +{ + void *ret; + char *real; + real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1)); + if (real) { + ret = btAlignPointer(real + sizeof(void *),alignment); + *((void **)(ret)-1) = (void *)(real); + } else { + ret = (void *)(real); + } + return (ret); +} + +static inline void btAlignedFreeDefault(void *ptr) +{ + void* real; + + if (ptr) { + real = *((void **)(ptr)-1); + sFreeFunc(real); + } +} +#endif + + +static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault; +static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault; + +void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc) +{ + sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; + sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; +} + +void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc) +{ + sAllocFunc = allocFunc ? allocFunc : btAllocDefault; + sFreeFunc = freeFunc ? freeFunc : btFreeDefault; +} + +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS +//this generic allocator provides the total allocated number of bytes +#include + +void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) +{ + void *ret; + char *real; + + gTotalBytesAlignedAllocs += size; + gNumAlignedAllocs++; + + + real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1)); + if (real) { + ret = (void*) btAlignPointer(real + 2*sizeof(void *), alignment); + *((void **)(ret)-1) = (void *)(real); + *((int*)(ret)-2) = size; + + } else { + ret = (void *)(real);//?? + } + + printf("allocation#%d at address %x, from %s,line %d, size %d\n",gNumAlignedAllocs,real, filename,line,size); + + int* ptr = (int*)ret; + *ptr = 12; + return (ret); +} + +void btAlignedFreeInternal (void* ptr,int line,char* filename) +{ + + void* real; + gNumAlignedFree++; + + if (ptr) { + real = *((void **)(ptr)-1); + int size = *((int*)(ptr)-2); + gTotalBytesAlignedAllocs -= size; + + printf("free #%d at address %x, from %s,line %d, size %d\n",gNumAlignedFree,real, filename,line,size); + + sFreeFunc(real); + } else + { + printf("NULL ptr\n"); + } +} + +#else //BT_DEBUG_MEMORY_ALLOCATIONS + +void* btAlignedAllocInternal (size_t size, int alignment) +{ + gNumAlignedAllocs++; + void* ptr; + ptr = sAlignedAllocFunc(size, alignment); +// printf("btAlignedAllocInternal %d, %x\n",size,ptr); + return ptr; +} + +void btAlignedFreeInternal (void* ptr) +{ + if (!ptr) + { + return; + } + + gNumAlignedFree++; +// printf("btAlignedFreeInternal %x\n",ptr); + sAlignedFreeFunc(ptr); +} + +#endif //BT_DEBUG_MEMORY_ALLOCATIONS + diff --git a/src/LinearMath/btAlignedAllocator.h b/src/LinearMath/btAlignedAllocator.h new file mode 100644 index 0000000..f168f3c --- /dev/null +++ b/src/LinearMath/btAlignedAllocator.h @@ -0,0 +1,107 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_ALIGNED_ALLOCATOR +#define BT_ALIGNED_ALLOCATOR + +///we probably replace this with our own aligned memory allocator +///so we replace _aligned_malloc and _aligned_free with our own +///that is better portable and more predictable + +#include "btScalar.h" +//#define BT_DEBUG_MEMORY_ALLOCATIONS 1 +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS + +#define btAlignedAlloc(a,b) \ + btAlignedAllocInternal(a,b,__LINE__,__FILE__) + +#define btAlignedFree(ptr) \ + btAlignedFreeInternal(ptr,__LINE__,__FILE__) + +void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename); + +void btAlignedFreeInternal (void* ptr,int line,char* filename); + +#else + void* btAlignedAllocInternal (size_t size, int alignment); + void btAlignedFreeInternal (void* ptr); + + #define btAlignedAlloc(size,alignment) btAlignedAllocInternal(size,alignment) + #define btAlignedFree(ptr) btAlignedFreeInternal(ptr) + +#endif +typedef int size_type; + +typedef void *(btAlignedAllocFunc)(size_t size, int alignment); +typedef void (btAlignedFreeFunc)(void *memblock); +typedef void *(btAllocFunc)(size_t size); +typedef void (btFreeFunc)(void *memblock); + +///The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom +void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc); +///If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it. +void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc); + + +///The btAlignedAllocator is a portable class for aligned memory allocations. +///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using btAlignedAllocSetCustom and btAlignedAllocSetCustomAligned. +template < typename T , unsigned Alignment > +class btAlignedAllocator { + + typedef btAlignedAllocator< T , Alignment > self_type; + +public: + + //just going down a list: + btAlignedAllocator() {} + /* + btAlignedAllocator( const self_type & ) {} + */ + + template < typename Other > + btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {} + + typedef const T* const_pointer; + typedef const T& const_reference; + typedef T* pointer; + typedef T& reference; + typedef T value_type; + + pointer address ( reference ref ) const { return &ref; } + const_pointer address ( const_reference ref ) const { return &ref; } + pointer allocate ( size_type n , const_pointer * hint = 0 ) { + (void)hint; + return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment )); + } + void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); } + void deallocate( pointer ptr ) { + btAlignedFree( reinterpret_cast< void * >( ptr ) ); + } + void destroy ( pointer ptr ) { ptr->~value_type(); } + + + template < typename O > struct rebind { + typedef btAlignedAllocator< O , Alignment > other; + }; + template < typename O > + self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; } + + friend bool operator==( const self_type & , const self_type & ) { return true; } +}; + + + +#endif //BT_ALIGNED_ALLOCATOR + diff --git a/src/LinearMath/btAlignedObjectArray.h b/src/LinearMath/btAlignedObjectArray.h new file mode 100644 index 0000000..24e59ab --- /dev/null +++ b/src/LinearMath/btAlignedObjectArray.h @@ -0,0 +1,511 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_OBJECT_ARRAY__ +#define BT_OBJECT_ARRAY__ + +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btAlignedAllocator.h" + +///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW +///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors +///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator= +///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and +///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240 + +#define BT_USE_PLACEMENT_NEW 1 +//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in or or otherwise... +#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful + +#ifdef BT_USE_MEMCPY +#include +#include +#endif //BT_USE_MEMCPY + +#ifdef BT_USE_PLACEMENT_NEW +#include //for placement new +#endif //BT_USE_PLACEMENT_NEW + + +///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods +///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data +template +//template +class btAlignedObjectArray +{ + btAlignedAllocator m_allocator; + + int m_size; + int m_capacity; + T* m_data; + //PCK: added this line + bool m_ownsMemory; + +#ifdef BT_ALLOW_ARRAY_COPY_OPERATOR +public: + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray &other) + { + copyFromArray(other); + return *this; + } +#else//BT_ALLOW_ARRAY_COPY_OPERATOR +private: + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray &other); +#endif//BT_ALLOW_ARRAY_COPY_OPERATOR + +protected: + SIMD_FORCE_INLINE int allocSize(int size) + { + return (size ? size*2 : 1); + } + SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const + { + int i; + for (i=start;i=0); + btAssert(n=0); + btAssert(n=0); + btAssert(n=0); + btAssert(n0); + m_size--; + m_data[m_size].~T(); + } + + + ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. + ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. + SIMD_FORCE_INLINE void resizeNoInitialize(int newsize) + { + int curSize = size(); + + if (newsize < curSize) + { + } else + { + if (newsize > size()) + { + reserve(newsize); + } + //leave this uninitialized + } + m_size = newsize; + } + + SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T()) + { + int curSize = size(); + + if (newsize < curSize) + { + for(int i = newsize; i < curSize; i++) + { + m_data[i].~T(); + } + } else + { + if (newsize > size()) + { + reserve(newsize); + } +#ifdef BT_USE_PLACEMENT_NEW + for (int i=curSize;i + void quickSortInternal(const L& CompareFunc,int lo, int hi) + { + // lo is the lower index, hi is the upper index + // of the region of array a that is to be sorted + int i=lo, j=hi; + T x=m_data[(lo+hi)/2]; + + // partition + do + { + while (CompareFunc(m_data[i],x)) + i++; + while (CompareFunc(x,m_data[j])) + j--; + if (i<=j) + { + swap(i,j); + i++; j--; + } + } while (i<=j); + + // recursion + if (lo + void quickSort(const L& CompareFunc) + { + //don't sort 0 or 1 elements + if (size()>1) + { + quickSortInternal(CompareFunc,0,size()-1); + } + } + + + ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ + template + void downHeap(T *pArr, int k, int n, const L& CompareFunc) + { + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ + + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n/2) + { + int child = 2*k; + + if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp , pArr[child - 1])) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; + } + else + { + break; + } + } + pArr[k - 1] = temp; + } /*downHeap*/ + + void swap(int index0,int index1) + { +#ifdef BT_USE_MEMCPY + char temp[sizeof(T)]; + memcpy(temp,&m_data[index0],sizeof(T)); + memcpy(&m_data[index0],&m_data[index1],sizeof(T)); + memcpy(&m_data[index1],temp,sizeof(T)); +#else + T temp = m_data[index0]; + m_data[index0] = m_data[index1]; + m_data[index1] = temp; +#endif //BT_USE_PLACEMENT_NEW + + } + + template + void heapSort(const L& CompareFunc) + { + /* sort a[0..N-1], N.B. 0 to N-1 */ + int k; + int n = m_size; + for (k = n/2; k > 0; k--) + { + downHeap(m_data, k, n, CompareFunc); + } + + /* a[1..N] is now a heap */ + while ( n>=1 ) + { + swap(0,n-1); /* largest of a[0..n-1] */ + + + n = n - 1; + /* restore a[1..i-1] heap */ + downHeap(m_data, 1, n, CompareFunc); + } + } + + ///non-recursive binary search, assumes sorted array + int findBinarySearch(const T& key) const + { + int first = 0; + int last = size()-1; + + //assume sorted array + while (first <= last) { + int mid = (first + last) / 2; // compute mid point. + if (key > m_data[mid]) + first = mid + 1; // repeat search in top half. + else if (key < m_data[mid]) + last = mid - 1; // repeat search in bottom half. + else + return mid; // found it. return position ///// + } + return size(); // failed to find key + } + + + int findLinearSearch(const T& key) const + { + int index=size(); + int i; + + for (i=0;i + +#include "btConvexHull.h" +#include "btAlignedObjectArray.h" +#include "btMinMax.h" +#include "btVector3.h" + + + + + +//---------------------------------- + +class int3 +{ +public: + int x,y,z; + int3(){}; + int3(int _x,int _y, int _z){x=_x;y=_y;z=_z;} + const int& operator[](int i) const {return (&x)[i];} + int& operator[](int i) {return (&x)[i];} +}; + + +//------- btPlane ---------- + + +inline btPlane PlaneFlip(const btPlane &plane){return btPlane(-plane.normal,-plane.dist);} +inline int operator==( const btPlane &a, const btPlane &b ) { return (a.normal==b.normal && a.dist==b.dist); } +inline int coplanar( const btPlane &a, const btPlane &b ) { return (a==b || a==PlaneFlip(b)); } + + +//--------- Utility Functions ------ + +btVector3 PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1); +btVector3 PlaneProject(const btPlane &plane, const btVector3 &point); + +btVector3 ThreePlaneIntersection(const btPlane &p0,const btPlane &p1, const btPlane &p2); +btVector3 ThreePlaneIntersection(const btPlane &p0,const btPlane &p1, const btPlane &p2) +{ + btVector3 N1 = p0.normal; + btVector3 N2 = p1.normal; + btVector3 N3 = p2.normal; + + btVector3 n2n3; n2n3 = N2.cross(N3); + btVector3 n3n1; n3n1 = N3.cross(N1); + btVector3 n1n2; n1n2 = N1.cross(N2); + + btScalar quotient = (N1.dot(n2n3)); + + btAssert(btFabs(quotient) > btScalar(0.000001)); + + quotient = btScalar(-1.) / quotient; + n2n3 *= p0.dist; + n3n1 *= p1.dist; + n1n2 *= p2.dist; + btVector3 potentialVertex = n2n3; + potentialVertex += n3n1; + potentialVertex += n1n2; + potentialVertex *= quotient; + + btVector3 result(potentialVertex.getX(),potentialVertex.getY(),potentialVertex.getZ()); + return result; + +} + +btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint=NULL, btVector3 *vpoint=NULL); +btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2); +btVector3 NormalOf(const btVector3 *vert, const int n); + + +btVector3 PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1) +{ + // returns the point where the line p0-p1 intersects the plane n&d + static btVector3 dif; + dif = p1-p0; + btScalar dn= btDot(plane.normal,dif); + btScalar t = -(plane.dist+btDot(plane.normal,p0) )/dn; + return p0 + (dif*t); +} + +btVector3 PlaneProject(const btPlane &plane, const btVector3 &point) +{ + return point - plane.normal * (btDot(point,plane.normal)+plane.dist); +} + +btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) +{ + // return the normal of the triangle + // inscribed by v0, v1, and v2 + btVector3 cp=btCross(v1-v0,v2-v1); + btScalar m=cp.length(); + if(m==0) return btVector3(1,0,0); + return cp*(btScalar(1.0)/m); +} + + +btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint, btVector3 *vpoint) +{ + static btVector3 cp; + cp = btCross(udir,vdir).normalized(); + + btScalar distu = -btDot(cp,ustart); + btScalar distv = -btDot(cp,vstart); + btScalar dist = (btScalar)fabs(distu-distv); + if(upoint) + { + btPlane plane; + plane.normal = btCross(vdir,cp).normalized(); + plane.dist = -btDot(plane.normal,vstart); + *upoint = PlaneLineIntersection(plane,ustart,ustart+udir); + } + if(vpoint) + { + btPlane plane; + plane.normal = btCross(udir,cp).normalized(); + plane.dist = -btDot(plane.normal,ustart); + *vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir); + } + return dist; +} + + + + + + + +#define COPLANAR (0) +#define UNDER (1) +#define OVER (2) +#define SPLIT (OVER|UNDER) +#define PAPERWIDTH (btScalar(0.001)) + +btScalar planetestepsilon = PAPERWIDTH; + + + +typedef ConvexH::HalfEdge HalfEdge; + +ConvexH::ConvexH(int vertices_size,int edges_size,int facets_size) +{ + vertices.resize(vertices_size); + edges.resize(edges_size); + facets.resize(facets_size); +} + + +int PlaneTest(const btPlane &p, const btVector3 &v); +int PlaneTest(const btPlane &p, const btVector3 &v) { + btScalar a = btDot(v,p.normal)+p.dist; + int flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR); + return flag; +} + +int SplitTest(ConvexH &convex,const btPlane &plane); +int SplitTest(ConvexH &convex,const btPlane &plane) { + int flag=0; + for(int i=0;i +int maxdirfiltered(const T *p,int count,const T &dir,btAlignedObjectArray &allow) +{ + btAssert(count); + int m=-1; + for(int i=0;ibtDot(p[m],dir)) + m=i; + } + btAssert(m!=-1); + return m; +} + +btVector3 orth(const btVector3 &v); +btVector3 orth(const btVector3 &v) +{ + btVector3 a=btCross(v,btVector3(0,0,1)); + btVector3 b=btCross(v,btVector3(0,1,0)); + if (a.length() > b.length()) + { + return a.normalized(); + } else { + return b.normalized(); + } +} + + +template +int maxdirsterid(const T *p,int count,const T &dir,btAlignedObjectArray &allow) +{ + int m=-1; + while(m==-1) + { + m = maxdirfiltered(p,count,dir,allow); + if(allow[m]==3) return m; + T u = orth(dir); + T v = btCross(u,dir); + int ma=-1; + for(btScalar x = btScalar(0.0) ; x<= btScalar(360.0) ; x+= btScalar(45.0)) + { + btScalar s = btSin(SIMD_RADS_PER_DEG*(x)); + btScalar c = btCos(SIMD_RADS_PER_DEG*(x)); + int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow); + if(ma==m && mb==m) + { + allow[m]=3; + return m; + } + if(ma!=-1 && ma!=mb) // Yuck - this is really ugly + { + int mc = ma; + for(btScalar xx = x-btScalar(40.0) ; xx <= x ; xx+= btScalar(5.0)) + { + btScalar s = btSin(SIMD_RADS_PER_DEG*(xx)); + btScalar c = btCos(SIMD_RADS_PER_DEG*(xx)); + int md = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow); + if(mc==m && md==m) + { + allow[m]=3; + return m; + } + mc=md; + } + } + ma=mb; + } + allow[m]=0; + m=-1; + } + btAssert(0); + return m; +} + + + + +int operator ==(const int3 &a,const int3 &b); +int operator ==(const int3 &a,const int3 &b) +{ + for(int i=0;i<3;i++) + { + if(a[i]!=b[i]) return 0; + } + return 1; +} + + +int above(btVector3* vertices,const int3& t, const btVector3 &p, btScalar epsilon); +int above(btVector3* vertices,const int3& t, const btVector3 &p, btScalar epsilon) +{ + btVector3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]); + return (btDot(n,p-vertices[t[0]]) > epsilon); // EPSILON??? +} +int hasedge(const int3 &t, int a,int b); +int hasedge(const int3 &t, int a,int b) +{ + for(int i=0;i<3;i++) + { + int i1= (i+1)%3; + if(t[i]==a && t[i1]==b) return 1; + } + return 0; +} +int hasvert(const int3 &t, int v); +int hasvert(const int3 &t, int v) +{ + return (t[0]==v || t[1]==v || t[2]==v) ; +} +int shareedge(const int3 &a,const int3 &b); +int shareedge(const int3 &a,const int3 &b) +{ + int i; + for(i=0;i<3;i++) + { + int i1= (i+1)%3; + if(hasedge(a,b[i1],b[i])) return 1; + } + return 0; +} + +class btHullTriangle; + + + +class btHullTriangle : public int3 +{ +public: + int3 n; + int id; + int vmax; + btScalar rise; + btHullTriangle(int a,int b,int c):int3(a,b,c),n(-1,-1,-1) + { + vmax=-1; + rise = btScalar(0.0); + } + ~btHullTriangle() + { + } + int &neib(int a,int b); +}; + + +int &btHullTriangle::neib(int a,int b) +{ + static int er=-1; + int i; + for(i=0;i<3;i++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + if((*this)[i]==a && (*this)[i1]==b) return n[i2]; + if((*this)[i]==b && (*this)[i1]==a) return n[i2]; + } + btAssert(0); + return er; +} +void HullLibrary::b2bfix(btHullTriangle* s,btHullTriangle*t) +{ + int i; + for(i=0;i<3;i++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + int a = (*s)[i1]; + int b = (*s)[i2]; + btAssert(m_tris[s->neib(a,b)]->neib(b,a) == s->id); + btAssert(m_tris[t->neib(a,b)]->neib(b,a) == t->id); + m_tris[s->neib(a,b)]->neib(b,a) = t->neib(b,a); + m_tris[t->neib(b,a)]->neib(a,b) = s->neib(a,b); + } +} + +void HullLibrary::removeb2b(btHullTriangle* s,btHullTriangle*t) +{ + b2bfix(s,t); + deAllocateTriangle(s); + + deAllocateTriangle(t); +} + +void HullLibrary::checkit(btHullTriangle *t) +{ + (void)t; + + int i; + btAssert(m_tris[t->id]==t); + for(i=0;i<3;i++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + int a = (*t)[i1]; + int b = (*t)[i2]; + + // release compile fix + (void)i1; + (void)i2; + (void)a; + (void)b; + + btAssert(a!=b); + btAssert( m_tris[t->n[i]]->neib(b,a) == t->id); + } +} + +btHullTriangle* HullLibrary::allocateTriangle(int a,int b,int c) +{ + void* mem = btAlignedAlloc(sizeof(btHullTriangle),16); + btHullTriangle* tr = new (mem)btHullTriangle(a,b,c); + tr->id = m_tris.size(); + m_tris.push_back(tr); + + return tr; +} + +void HullLibrary::deAllocateTriangle(btHullTriangle* tri) +{ + btAssert(m_tris[tri->id]==tri); + m_tris[tri->id]=NULL; + tri->~btHullTriangle(); + btAlignedFree(tri); +} + + +void HullLibrary::extrude(btHullTriangle *t0,int v) +{ + int3 t= *t0; + int n = m_tris.size(); + btHullTriangle* ta = allocateTriangle(v,t[1],t[2]); + ta->n = int3(t0->n[0],n+1,n+2); + m_tris[t0->n[0]]->neib(t[1],t[2]) = n+0; + btHullTriangle* tb = allocateTriangle(v,t[2],t[0]); + tb->n = int3(t0->n[1],n+2,n+0); + m_tris[t0->n[1]]->neib(t[2],t[0]) = n+1; + btHullTriangle* tc = allocateTriangle(v,t[0],t[1]); + tc->n = int3(t0->n[2],n+0,n+1); + m_tris[t0->n[2]]->neib(t[0],t[1]) = n+2; + checkit(ta); + checkit(tb); + checkit(tc); + if(hasvert(*m_tris[ta->n[0]],v)) removeb2b(ta,m_tris[ta->n[0]]); + if(hasvert(*m_tris[tb->n[0]],v)) removeb2b(tb,m_tris[tb->n[0]]); + if(hasvert(*m_tris[tc->n[0]],v)) removeb2b(tc,m_tris[tc->n[0]]); + deAllocateTriangle(t0); + +} + +btHullTriangle* HullLibrary::extrudable(btScalar epsilon) +{ + int i; + btHullTriangle *t=NULL; + for(i=0;iriserise)) + { + t = m_tris[i]; + } + } + return (t->rise >epsilon)?t:NULL ; +} + + + + +int4 HullLibrary::FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray &allow) +{ + btVector3 basis[3]; + basis[0] = btVector3( btScalar(0.01), btScalar(0.02), btScalar(1.0) ); + int p0 = maxdirsterid(verts,verts_count, basis[0],allow); + int p1 = maxdirsterid(verts,verts_count,-basis[0],allow); + basis[0] = verts[p0]-verts[p1]; + if(p0==p1 || basis[0]==btVector3(0,0,0)) + return int4(-1,-1,-1,-1); + basis[1] = btCross(btVector3( btScalar(1),btScalar(0.02), btScalar(0)),basis[0]); + basis[2] = btCross(btVector3(btScalar(-0.02), btScalar(1), btScalar(0)),basis[0]); + if (basis[1].length() > basis[2].length()) + { + basis[1].normalize(); + } else { + basis[1] = basis[2]; + basis[1].normalize (); + } + int p2 = maxdirsterid(verts,verts_count,basis[1],allow); + if(p2 == p0 || p2 == p1) + { + p2 = maxdirsterid(verts,verts_count,-basis[1],allow); + } + if(p2 == p0 || p2 == p1) + return int4(-1,-1,-1,-1); + basis[1] = verts[p2] - verts[p0]; + basis[2] = btCross(basis[1],basis[0]).normalized(); + int p3 = maxdirsterid(verts,verts_count,basis[2],allow); + if(p3==p0||p3==p1||p3==p2) p3 = maxdirsterid(verts,verts_count,-basis[2],allow); + if(p3==p0||p3==p1||p3==p2) + return int4(-1,-1,-1,-1); + btAssert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3)); + if(btDot(verts[p3]-verts[p0],btCross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {btSwap(p2,p3);} + return int4(p0,p1,p2,p3); +} + +int HullLibrary::calchullgen(btVector3 *verts,int verts_count, int vlimit) +{ + if(verts_count <4) return 0; + if(vlimit==0) vlimit=1000000000; + int j; + btVector3 bmin(*verts),bmax(*verts); + btAlignedObjectArray isextreme; + isextreme.reserve(verts_count); + btAlignedObjectArray allow; + allow.reserve(verts_count); + + for(j=0;jn=int3(2,3,1); + btHullTriangle *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0); + btHullTriangle *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3); + btHullTriangle *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2); + isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1; + checkit(t0);checkit(t1);checkit(t2);checkit(t3); + + for(j=0;jvmax<0); + btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); + t->vmax = maxdirsterid(verts,verts_count,n,allow); + t->rise = btDot(n,verts[t->vmax]-verts[(*t)[0]]); + } + btHullTriangle *te; + vlimit-=4; + while(vlimit >0 && ((te=extrudable(epsilon)) != 0)) + { + //int3 ti=*te; + int v=te->vmax; + btAssert(v != -1); + btAssert(!isextreme[v]); // wtf we've already done this vertex + isextreme[v]=1; + //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already + j=m_tris.size(); + while(j--) { + if(!m_tris[j]) continue; + int3 t=*m_tris[j]; + if(above(verts,t,verts[v],btScalar(0.01)*epsilon)) + { + extrude(m_tris[j],v); + } + } + // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle + j=m_tris.size(); + while(j--) + { + if(!m_tris[j]) continue; + if(!hasvert(*m_tris[j],v)) break; + int3 nt=*m_tris[j]; + if(above(verts,nt,center,btScalar(0.01)*epsilon) || btCross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]).length()< epsilon*epsilon*btScalar(0.1) ) + { + btHullTriangle *nb = m_tris[m_tris[j]->n[0]]; + btAssert(nb);btAssert(!hasvert(*nb,v));btAssert(nb->idvmax>=0) break; + btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); + t->vmax = maxdirsterid(verts,verts_count,n,allow); + if(isextreme[t->vmax]) + { + t->vmax=-1; // already done that vertex - algorithm needs to be able to terminate. + } + else + { + t->rise = btDot(n,verts[t->vmax]-verts[(*t)[0]]); + } + } + vlimit --; + } + return 1; +} + +int HullLibrary::calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit) +{ + int rc=calchullgen(verts,verts_count, vlimit) ; + if(!rc) return 0; + btAlignedObjectArray ts; + int i; + + for(i=0;i(ts[i]); + } + m_tris.resize(0); + + return 1; +} + + + + + +bool HullLibrary::ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit) +{ + + int tris_count; + int ret = calchull( (btVector3 *) vertices, (int) vcount, result.m_Indices, tris_count, static_cast(vlimit) ); + if(!ret) return false; + result.mIndexCount = (unsigned int) (tris_count*3); + result.mFaceCount = (unsigned int) tris_count; + result.mVertices = (btVector3*) vertices; + result.mVcount = (unsigned int) vcount; + return true; + +} + + +void ReleaseHull(PHullResult &result); +void ReleaseHull(PHullResult &result) +{ + if ( result.m_Indices.size() ) + { + result.m_Indices.clear(); + } + + result.mVcount = 0; + result.mIndexCount = 0; + result.mVertices = 0; +} + + +//********************************************************************* +//********************************************************************* +//******** HullLib header +//********************************************************************* +//********************************************************************* + +//********************************************************************* +//********************************************************************* +//******** HullLib implementation +//********************************************************************* +//********************************************************************* + +HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // describes the input request + HullResult &result) // contains the resulst +{ + HullError ret = QE_FAIL; + + + PHullResult hr; + + unsigned int vcount = desc.mVcount; + if ( vcount < 8 ) vcount = 8; + + btAlignedObjectArray vertexSource; + vertexSource.resize(static_cast(vcount)); + + btVector3 scale; + + unsigned int ovcount; + + bool ok = CleanupVertices(desc.mVcount,desc.mVertices, desc.mVertexStride, ovcount, &vertexSource[0], desc.mNormalEpsilon, scale ); // normalize point cloud, remove duplicates! + + if ( ok ) + { + + +// if ( 1 ) // scale vertices back to their original size. + { + for (unsigned int i=0; i(i)]; + v[0]*=scale[0]; + v[1]*=scale[1]; + v[2]*=scale[2]; + } + } + + ok = ComputeHull(ovcount,&vertexSource[0],hr,desc.mMaxVertices); + + if ( ok ) + { + + // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table. + btAlignedObjectArray vertexScratch; + vertexScratch.resize(static_cast(hr.mVcount)); + + BringOutYourDead(hr.mVertices,hr.mVcount, &vertexScratch[0], ovcount, &hr.m_Indices[0], hr.mIndexCount ); + + ret = QE_OK; + + if ( desc.HasHullFlag(QF_TRIANGLES) ) // if he wants the results as triangle! + { + result.mPolygons = false; + result.mNumOutputVertices = ovcount; + result.m_OutputVertices.resize(static_cast(ovcount)); + result.mNumFaces = hr.mFaceCount; + result.mNumIndices = hr.mIndexCount; + + result.m_Indices.resize(static_cast(hr.mIndexCount)); + + memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3)*ovcount ); + + if ( desc.HasHullFlag(QF_REVERSE_ORDER) ) + { + + const unsigned int *source = &hr.m_Indices[0]; + unsigned int *dest = &result.m_Indices[0]; + + for (unsigned int i=0; i(ovcount)); + result.mNumFaces = hr.mFaceCount; + result.mNumIndices = hr.mIndexCount+hr.mFaceCount; + result.m_Indices.resize(static_cast(result.mNumIndices)); + memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3)*ovcount ); + +// if ( 1 ) + { + const unsigned int *source = &hr.m_Indices[0]; + unsigned int *dest = &result.m_Indices[0]; + for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + } + } + } + + btScalar dx = bmax[0] - bmin[0]; + btScalar dy = bmax[1] - bmin[1]; + btScalar dz = bmax[2] - bmin[2]; + + btVector3 center; + + center[0] = dx*btScalar(0.5) + bmin[0]; + center[1] = dy*btScalar(0.5) + bmin[1]; + center[2] = dz*btScalar(0.5) + bmin[2]; + + if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 ) + { + + btScalar len = FLT_MAX; + + if ( dx > EPSILON && dx < len ) len = dx; + if ( dy > EPSILON && dy < len ) len = dy; + if ( dz > EPSILON && dz < len ) len = dz; + + if ( len == FLT_MAX ) + { + dx = dy = dz = btScalar(0.01); // one centimeter + } + else + { + if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. + if ( dy < EPSILON ) dy = len * btScalar(0.05); + if ( dz < EPSILON ) dz = len * btScalar(0.05); + } + + btScalar x1 = center[0] - dx; + btScalar x2 = center[0] + dx; + + btScalar y1 = center[1] - dy; + btScalar y2 = center[1] + dy; + + btScalar z1 = center[2] - dz; + btScalar z2 = center[2] + dz; + + addPoint(vcount,vertices,x1,y1,z1); + addPoint(vcount,vertices,x2,y1,z1); + addPoint(vcount,vertices,x2,y2,z1); + addPoint(vcount,vertices,x1,y2,z1); + addPoint(vcount,vertices,x1,y1,z2); + addPoint(vcount,vertices,x2,y1,z2); + addPoint(vcount,vertices,x2,y2,z2); + addPoint(vcount,vertices,x1,y2,z2); + + return true; // return cube + + + } + else + { + if ( scale ) + { + scale[0] = dx; + scale[1] = dy; + scale[2] = dz; + + recip[0] = 1 / dx; + recip[1] = 1 / dy; + recip[2] = 1 / dz; + + center[0]*=recip[0]; + center[1]*=recip[1]; + center[2]*=recip[2]; + + } + + } + + + + vtx = (const char *) svertices; + + for (unsigned int i=0; igetX(); + btScalar py = p->getY(); + btScalar pz = p->getZ(); + + if ( scale ) + { + px = px*recip[0]; // normalize + py = py*recip[1]; // normalize + pz = pz*recip[2]; // normalize + } + +// if ( 1 ) + { + unsigned int j; + + for (j=0; j dist2 ) + { + v[0] = px; + v[1] = py; + v[2] = pz; + + } + + break; + } + } + + if ( j == vcount ) + { + btVector3& dest = vertices[vcount]; + dest[0] = px; + dest[1] = py; + dest[2] = pz; + vcount++; + } + m_vertexIndexMapping.push_back(j); + } + } + + // ok..now make sure we didn't prune so many vertices it is now invalid. +// if ( 1 ) + { + btScalar bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; + btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; + + for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + } + } + + btScalar dx = bmax[0] - bmin[0]; + btScalar dy = bmax[1] - bmin[1]; + btScalar dz = bmax[2] - bmin[2]; + + if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) + { + btScalar cx = dx*btScalar(0.5) + bmin[0]; + btScalar cy = dy*btScalar(0.5) + bmin[1]; + btScalar cz = dz*btScalar(0.5) + bmin[2]; + + btScalar len = FLT_MAX; + + if ( dx >= EPSILON && dx < len ) len = dx; + if ( dy >= EPSILON && dy < len ) len = dy; + if ( dz >= EPSILON && dz < len ) len = dz; + + if ( len == FLT_MAX ) + { + dx = dy = dz = btScalar(0.01); // one centimeter + } + else + { + if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. + if ( dy < EPSILON ) dy = len * btScalar(0.05); + if ( dz < EPSILON ) dz = len * btScalar(0.05); + } + + btScalar x1 = cx - dx; + btScalar x2 = cx + dx; + + btScalar y1 = cy - dy; + btScalar y2 = cy + dy; + + btScalar z1 = cz - dz; + btScalar z2 = cz + dz; + + vcount = 0; // add box + + addPoint(vcount,vertices,x1,y1,z1); + addPoint(vcount,vertices,x2,y1,z1); + addPoint(vcount,vertices,x2,y2,z1); + addPoint(vcount,vertices,x1,y2,z1); + addPoint(vcount,vertices,x1,y1,z2); + addPoint(vcount,vertices,x2,y1,z2); + addPoint(vcount,vertices,x2,y2,z2); + addPoint(vcount,vertices,x1,y2,z2); + + return true; + } + } + + return true; +} + +void HullLibrary::BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount) +{ + btAlignedObjectArraytmpIndices; + tmpIndices.resize(m_vertexIndexMapping.size()); + int i; + + for (i=0;i(vcount)); + memset(&usedIndices[0],0,sizeof(unsigned int)*vcount); + + ocount = 0; + + for (i=0; i= 0 && v < vcount ); + + if ( usedIndices[static_cast(v)] ) // if already remapped + { + indices[i] = usedIndices[static_cast(v)]-1; // index to new array + } + else + { + + indices[i] = ocount; // new index mapping + + overts[ocount][0] = verts[v][0]; // copy old vert to new vert array + overts[ocount][1] = verts[v][1]; + overts[ocount][2] = verts[v][2]; + + for (int k=0;k=0 && ocount <= vcount ); + + usedIndices[static_cast(v)] = ocount; // assign new index remapping + + + } + } + + +} diff --git a/src/LinearMath/btConvexHull.h b/src/LinearMath/btConvexHull.h new file mode 100644 index 0000000..69c52bc --- /dev/null +++ b/src/LinearMath/btConvexHull.h @@ -0,0 +1,241 @@ + +/* +Stan Melax Convex Hull Computation +Copyright (c) 2008 Stan Melax http://www.melax.com/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///includes modifications/improvements by John Ratcliff, see BringOutYourDead below. + +#ifndef BT_CD_HULL_H +#define BT_CD_HULL_H + +#include "btVector3.h" +#include "btAlignedObjectArray.h" + +typedef btAlignedObjectArray TUIntArray; + +class HullResult +{ +public: + HullResult(void) + { + mPolygons = true; + mNumOutputVertices = 0; + mNumFaces = 0; + mNumIndices = 0; + } + bool mPolygons; // true if indices represents polygons, false indices are triangles + unsigned int mNumOutputVertices; // number of vertices in the output hull + btAlignedObjectArray m_OutputVertices; // array of vertices + unsigned int mNumFaces; // the number of faces produced + unsigned int mNumIndices; // the total number of indices + btAlignedObjectArray m_Indices; // pointer to indices. + +// If triangles, then indices are array indexes into the vertex list. +// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. +}; + +enum HullFlag +{ + QF_TRIANGLES = (1<<0), // report results as triangles, not polygons. + QF_REVERSE_ORDER = (1<<1), // reverse order of the triangle indices. + QF_DEFAULT = QF_TRIANGLES +}; + + +class HullDesc +{ +public: + HullDesc(void) + { + mFlags = QF_DEFAULT; + mVcount = 0; + mVertices = 0; + mVertexStride = sizeof(btVector3); + mNormalEpsilon = 0.001f; + mMaxVertices = 4096; // maximum number of points to be considered for a convex hull. + mMaxFaces = 4096; + }; + + HullDesc(HullFlag flag, + unsigned int vcount, + const btVector3 *vertices, + unsigned int stride = sizeof(btVector3)) + { + mFlags = flag; + mVcount = vcount; + mVertices = vertices; + mVertexStride = stride; + mNormalEpsilon = btScalar(0.001); + mMaxVertices = 4096; + } + + bool HasHullFlag(HullFlag flag) const + { + if ( mFlags & flag ) return true; + return false; + } + + void SetHullFlag(HullFlag flag) + { + mFlags|=flag; + } + + void ClearHullFlag(HullFlag flag) + { + mFlags&=~flag; + } + + unsigned int mFlags; // flags to use when generating the convex hull. + unsigned int mVcount; // number of vertices in the input point cloud + const btVector3 *mVertices; // the array of vertices. + unsigned int mVertexStride; // the stride of each vertex, in bytes. + btScalar mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on. + unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull! + unsigned int mMaxFaces; +}; + +enum HullError +{ + QE_OK, // success! + QE_FAIL // failed. +}; + +class btPlane +{ + public: + btVector3 normal; + btScalar dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 + btPlane(const btVector3 &n,btScalar d):normal(n),dist(d){} + btPlane():normal(),dist(0){} + +}; + + + +class ConvexH +{ + public: + class HalfEdge + { + public: + short ea; // the other half of the edge (index into edges list) + unsigned char v; // the vertex at the start of this edge (index into vertices list) + unsigned char p; // the facet on which this edge lies (index into facets list) + HalfEdge(){} + HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){} + }; + ConvexH() + { + } + ~ConvexH() + { + } + btAlignedObjectArray vertices; + btAlignedObjectArray edges; + btAlignedObjectArray facets; + ConvexH(int vertices_size,int edges_size,int facets_size); +}; + + +class int4 +{ +public: + int x,y,z,w; + int4(){}; + int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;} + const int& operator[](int i) const {return (&x)[i];} + int& operator[](int i) {return (&x)[i];} +}; + +class PHullResult +{ +public: + + PHullResult(void) + { + mVcount = 0; + mIndexCount = 0; + mFaceCount = 0; + mVertices = 0; + } + + unsigned int mVcount; + unsigned int mIndexCount; + unsigned int mFaceCount; + btVector3* mVertices; + TUIntArray m_Indices; +}; + + + +///The HullLibrary class can create a convex hull from a collection of vertices, using the ComputeHull method. +///The btShapeHull class uses this HullLibrary to create a approximate convex mesh given a general (non-polyhedral) convex shape. +class HullLibrary +{ + + btAlignedObjectArray m_tris; + +public: + + btAlignedObjectArray m_vertexIndexMapping; + + + HullError CreateConvexHull(const HullDesc& desc, // describes the input request + HullResult& result); // contains the resulst + HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it. + +private: + + bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit); + + class btHullTriangle* allocateTriangle(int a,int b,int c); + void deAllocateTriangle(btHullTriangle*); + void b2bfix(btHullTriangle* s,btHullTriangle*t); + + void removeb2b(btHullTriangle* s,btHullTriangle*t); + + void checkit(btHullTriangle *t); + + btHullTriangle* extrudable(btScalar epsilon); + + int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit); + + int calchullgen(btVector3 *verts,int verts_count, int vlimit); + + int4 FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray &allow); + + class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice); + + void extrude(class btHullTriangle* t0,int v); + + ConvexH* test_cube(); + + //BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'. + //After the hull is generated it give you back a set of polygon faces which index the *original* point cloud. + //The thing is, often times, there are many 'dead vertices' in the point cloud that are on longer referenced by the hull. + //The routine 'BringOutYourDead' find only the referenced vertices, copies them to an new buffer, and re-indexes the hull so that it is a minimal representation. + void BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int* indices,unsigned indexcount); + + bool CleanupVertices(unsigned int svcount, + const btVector3* svertices, + unsigned int stride, + unsigned int &vcount, // output number of vertices + btVector3* vertices, // location to store the results. + btScalar normalepsilon, + btVector3& scale); +}; + + +#endif //BT_CD_HULL_H + diff --git a/src/LinearMath/btConvexHullComputer.cpp b/src/LinearMath/btConvexHullComputer.cpp new file mode 100644 index 0000000..c03c901 --- /dev/null +++ b/src/LinearMath/btConvexHullComputer.cpp @@ -0,0 +1,2751 @@ +/* +Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include + +#include "btConvexHullComputer.h" +#include "btAlignedObjectArray.h" +#include "btMinMax.h" +#include "btVector3.h" + +#ifdef __GNUC__ + #include +#elif defined(_MSC_VER) + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; +#else + typedef int int32_t; + typedef long long int int64_t; + typedef unsigned int uint32_t; + typedef unsigned long long int uint64_t; +#endif + + +//The definition of USE_X86_64_ASM is moved into the build system. You can enable it manually by commenting out the following lines +//#if (defined(__GNUC__) && defined(__x86_64__) && !defined(__ICL)) // || (defined(__ICL) && defined(_M_X64)) bug in Intel compiler, disable inline assembly +// #define USE_X86_64_ASM +//#endif + + +//#define DEBUG_CONVEX_HULL +//#define SHOW_ITERATIONS + +#if defined(DEBUG_CONVEX_HULL) || defined(SHOW_ITERATIONS) + #include +#endif + +// Convex hull implementation based on Preparata and Hong +// Ole Kniemeyer, MAXON Computer GmbH +class btConvexHullInternal +{ + public: + + class Point64 + { + public: + int64_t x; + int64_t y; + int64_t z; + + Point64(int64_t x, int64_t y, int64_t z): x(x), y(y), z(z) + { + } + + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } + + int64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } + }; + + class Point32 + { + public: + int32_t x; + int32_t y; + int32_t z; + int index; + + Point32() + { + } + + Point32(int32_t x, int32_t y, int32_t z): x(x), y(y), z(z), index(-1) + { + } + + bool operator==(const Point32& b) const + { + return (x == b.x) && (y == b.y) && (z == b.z); + } + + bool operator!=(const Point32& b) const + { + return (x != b.x) || (y != b.y) || (z != b.z); + } + + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } + + Point64 cross(const Point32& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + Point64 cross(const Point64& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + int64_t dot(const Point32& b) const + { + return x * b.x + y * b.y + z * b.z; + } + + int64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } + + Point32 operator+(const Point32& b) const + { + return Point32(x + b.x, y + b.y, z + b.z); + } + + Point32 operator-(const Point32& b) const + { + return Point32(x - b.x, y - b.y, z - b.z); + } + }; + + class Int128 + { + public: + uint64_t low; + uint64_t high; + + Int128() + { + } + + Int128(uint64_t low, uint64_t high): low(low), high(high) + { + } + + Int128(uint64_t low): low(low), high(0) + { + } + + Int128(int64_t value): low(value), high((value >= 0) ? 0 : (uint64_t) -1LL) + { + } + + static Int128 mul(int64_t a, int64_t b); + + static Int128 mul(uint64_t a, uint64_t b); + + Int128 operator-() const + { + return Int128((uint64_t) -(int64_t)low, ~high + (low == 0)); + } + + Int128 operator+(const Int128& b) const + { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__ ("addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r" (result.low), [rh] "=r" (result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc" ); + return result; +#else + uint64_t lo = low + b.low; + return Int128(lo, high + b.high + (lo < low)); +#endif + } + + Int128 operator-(const Int128& b) const + { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__ ("subq %[bl], %[rl]\n\t" + "sbbq %[bh], %[rh]\n\t" + : [rl] "=r" (result.low), [rh] "=r" (result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc" ); + return result; +#else + return *this + -b; +#endif + } + + Int128& operator+=(const Int128& b) + { +#ifdef USE_X86_64_ASM + __asm__ ("addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r" (low), [rh] "=r" (high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc" ); +#else + uint64_t lo = low + b.low; + if (lo < low) + { + ++high; + } + low = lo; + high += b.high; +#endif + return *this; + } + + Int128& operator++() + { + if (++low == 0) + { + ++high; + } + return *this; + } + + Int128 operator*(int64_t b) const; + + btScalar toScalar() const + { + return ((int64_t) high >= 0) ? btScalar(high) * (btScalar(0x100000000LL) * btScalar(0x100000000LL)) + btScalar(low) + : -(-*this).toScalar(); + } + + int getSign() const + { + return ((int64_t) high < 0) ? -1 : (high || low) ? 1 : 0; + } + + bool operator<(const Int128& b) const + { + return (high < b.high) || ((high == b.high) && (low < b.low)); + } + + int ucmp(const Int128&b) const + { + if (high < b.high) + { + return -1; + } + if (high > b.high) + { + return 1; + } + if (low < b.low) + { + return -1; + } + if (low > b.low) + { + return 1; + } + return 0; + } + }; + + + class Rational64 + { + private: + uint64_t m_numerator; + uint64_t m_denominator; + int sign; + + public: + Rational64(int64_t numerator, int64_t denominator) + { + if (numerator > 0) + { + sign = 1; + m_numerator = (uint64_t) numerator; + } + else if (numerator < 0) + { + sign = -1; + m_numerator = (uint64_t) -numerator; + } + else + { + sign = 0; + m_numerator = 0; + } + if (denominator > 0) + { + m_denominator = (uint64_t) denominator; + } + else if (denominator < 0) + { + sign = -sign; + m_denominator = (uint64_t) -denominator; + } + else + { + m_denominator = 0; + } + } + + bool isNegativeInfinity() const + { + return (sign < 0) && (m_denominator == 0); + } + + bool isNaN() const + { + return (sign == 0) && (m_denominator == 0); + } + + int compare(const Rational64& b) const; + + btScalar toScalar() const + { + return sign * ((m_denominator == 0) ? SIMD_INFINITY : (btScalar) m_numerator / m_denominator); + } + }; + + + class Rational128 + { + private: + Int128 numerator; + Int128 denominator; + int sign; + bool isInt64; + + public: + Rational128(int64_t value) + { + if (value > 0) + { + sign = 1; + this->numerator = value; + } + else if (value < 0) + { + sign = -1; + this->numerator = -value; + } + else + { + sign = 0; + this->numerator = (uint64_t) 0; + } + this->denominator = (uint64_t) 1; + isInt64 = true; + } + + Rational128(const Int128& numerator, const Int128& denominator) + { + sign = numerator.getSign(); + if (sign >= 0) + { + this->numerator = numerator; + } + else + { + this->numerator = -numerator; + } + int dsign = denominator.getSign(); + if (dsign >= 0) + { + this->denominator = denominator; + } + else + { + sign = -sign; + this->denominator = -denominator; + } + isInt64 = false; + } + + int compare(const Rational128& b) const; + + int compare(int64_t b) const; + + btScalar toScalar() const + { + return sign * ((denominator.getSign() == 0) ? SIMD_INFINITY : numerator.toScalar() / denominator.toScalar()); + } + }; + + class PointR128 + { + public: + Int128 x; + Int128 y; + Int128 z; + Int128 denominator; + + PointR128() + { + } + + PointR128(Int128 x, Int128 y, Int128 z, Int128 denominator): x(x), y(y), z(z), denominator(denominator) + { + } + + btScalar xvalue() const + { + return x.toScalar() / denominator.toScalar(); + } + + btScalar yvalue() const + { + return y.toScalar() / denominator.toScalar(); + } + + btScalar zvalue() const + { + return z.toScalar() / denominator.toScalar(); + } + }; + + + class Edge; + class Face; + + class Vertex + { + public: + Vertex* next; + Vertex* prev; + Edge* edges; + Face* firstNearbyFace; + Face* lastNearbyFace; + PointR128 point128; + Point32 point; + int copy; + + Vertex(): next(NULL), prev(NULL), edges(NULL), firstNearbyFace(NULL), lastNearbyFace(NULL), copy(-1) + { + } + +#ifdef DEBUG_CONVEX_HULL + void print() + { + printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); + } + + void printGraph(); +#endif + + Point32 operator-(const Vertex& b) const + { + return point - b.point; + } + + Rational128 dot(const Point64& b) const + { + return (point.index >= 0) ? Rational128(point.dot(b)) + : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); + } + + btScalar xvalue() const + { + return (point.index >= 0) ? btScalar(point.x) : point128.xvalue(); + } + + btScalar yvalue() const + { + return (point.index >= 0) ? btScalar(point.y) : point128.yvalue(); + } + + btScalar zvalue() const + { + return (point.index >= 0) ? btScalar(point.z) : point128.zvalue(); + } + + void receiveNearbyFaces(Vertex* src) + { + if (lastNearbyFace) + { + lastNearbyFace->nextWithSameNearbyVertex = src->firstNearbyFace; + } + else + { + firstNearbyFace = src->firstNearbyFace; + } + if (src->lastNearbyFace) + { + lastNearbyFace = src->lastNearbyFace; + } + for (Face* f = src->firstNearbyFace; f; f = f->nextWithSameNearbyVertex) + { + btAssert(f->nearbyVertex == src); + f->nearbyVertex = this; + } + src->firstNearbyFace = NULL; + src->lastNearbyFace = NULL; + } + }; + + + class Edge + { + public: + Edge* next; + Edge* prev; + Edge* reverse; + Vertex* target; + Face* face; + int copy; + + ~Edge() + { + next = NULL; + prev = NULL; + reverse = NULL; + target = NULL; + face = NULL; + } + + void link(Edge* n) + { + btAssert(reverse->target == n->reverse->target); + next = n; + n->prev = this; + } + +#ifdef DEBUG_CONVEX_HULL + void print() + { + printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, + reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); + } +#endif + }; + + class Face + { + public: + Face* next; + Vertex* nearbyVertex; + Face* nextWithSameNearbyVertex; + Point32 origin; + Point32 dir0; + Point32 dir1; + + Face(): next(NULL), nearbyVertex(NULL), nextWithSameNearbyVertex(NULL) + { + } + + void init(Vertex* a, Vertex* b, Vertex* c) + { + nearbyVertex = a; + origin = a->point; + dir0 = *b - *a; + dir1 = *c - *a; + if (a->lastNearbyFace) + { + a->lastNearbyFace->nextWithSameNearbyVertex = this; + } + else + { + a->firstNearbyFace = this; + } + a->lastNearbyFace = this; + } + + Point64 getNormal() + { + return dir0.cross(dir1); + } + }; + + template class DMul + { + private: + static uint32_t high(uint64_t value) + { + return (uint32_t) (value >> 32); + } + + static uint32_t low(uint64_t value) + { + return (uint32_t) value; + } + + static uint64_t mul(uint32_t a, uint32_t b) + { + return (uint64_t) a * (uint64_t) b; + } + + static void shlHalf(uint64_t& value) + { + value <<= 32; + } + + static uint64_t high(Int128 value) + { + return value.high; + } + + static uint64_t low(Int128 value) + { + return value.low; + } + + static Int128 mul(uint64_t a, uint64_t b) + { + return Int128::mul(a, b); + } + + static void shlHalf(Int128& value) + { + value.high = value.low; + value.low = 0; + } + + public: + + static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh) + { + UWord p00 = mul(low(a), low(b)); + UWord p01 = mul(low(a), high(b)); + UWord p10 = mul(high(a), low(b)); + UWord p11 = mul(high(a), high(b)); + UWord p0110 = UWord(low(p01)) + UWord(low(p10)); + p11 += high(p01); + p11 += high(p10); + p11 += high(p0110); + shlHalf(p0110); + p00 += p0110; + if (p00 < p0110) + { + ++p11; + } + resLow = p00; + resHigh = p11; + } + }; + + private: + + class IntermediateHull + { + public: + Vertex* minXy; + Vertex* maxXy; + Vertex* minYx; + Vertex* maxYx; + + IntermediateHull(): minXy(NULL), maxXy(NULL), minYx(NULL), maxYx(NULL) + { + } + + void print(); + }; + + enum Orientation {NONE, CLOCKWISE, COUNTER_CLOCKWISE}; + + template class PoolArray + { + private: + T* array; + int size; + + public: + PoolArray* next; + + PoolArray(int size): size(size), next(NULL) + { + array = (T*) btAlignedAlloc(sizeof(T) * size, 16); + } + + ~PoolArray() + { + btAlignedFree(array); + } + + T* init() + { + T* o = array; + for (int i = 0; i < size; i++, o++) + { + o->next = (i+1 < size) ? o + 1 : NULL; + } + return array; + } + }; + + template class Pool + { + private: + PoolArray* arrays; + PoolArray* nextArray; + T* freeObjects; + int arraySize; + + public: + Pool(): arrays(NULL), nextArray(NULL), freeObjects(NULL), arraySize(256) + { + } + + ~Pool() + { + while (arrays) + { + PoolArray* p = arrays; + arrays = p->next; + p->~PoolArray(); + btAlignedFree(p); + } + } + + void reset() + { + nextArray = arrays; + freeObjects = NULL; + } + + void setArraySize(int arraySize) + { + this->arraySize = arraySize; + } + + T* newObject() + { + T* o = freeObjects; + if (!o) + { + PoolArray* p = nextArray; + if (p) + { + nextArray = p->next; + } + else + { + p = new(btAlignedAlloc(sizeof(PoolArray), 16)) PoolArray(arraySize); + p->next = arrays; + arrays = p; + } + o = p->init(); + } + freeObjects = o->next; + return new(o) T(); + }; + + void freeObject(T* object) + { + object->~T(); + object->next = freeObjects; + freeObjects = object; + } + }; + + btVector3 scaling; + btVector3 center; + Pool vertexPool; + Pool edgePool; + Pool facePool; + btAlignedObjectArray originalVertices; + int mergeStamp; + int minAxis; + int medAxis; + int maxAxis; + int usedEdgePairs; + int maxUsedEdgePairs; + + static Orientation getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t); + Edge* findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot); + void findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1); + + Edge* newEdgePair(Vertex* from, Vertex* to); + + void removeEdgePair(Edge* edge) + { + Edge* n = edge->next; + Edge* r = edge->reverse; + + btAssert(edge->target && r->target); + + if (n != edge) + { + n->prev = edge->prev; + edge->prev->next = n; + r->target->edges = n; + } + else + { + r->target->edges = NULL; + } + + n = r->next; + + if (n != r) + { + n->prev = r->prev; + r->prev->next = n; + edge->target->edges = n; + } + else + { + edge->target->edges = NULL; + } + + edgePool.freeObject(edge); + edgePool.freeObject(r); + usedEdgePairs--; + } + + void computeInternal(int start, int end, IntermediateHull& result); + + bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1); + + void merge(IntermediateHull& h0, IntermediateHull& h1); + + btVector3 toBtVector(const Point32& v); + + btVector3 getBtNormal(Face* face); + + bool shiftFace(Face* face, btScalar amount, btAlignedObjectArray stack); + + public: + Vertex* vertexList; + + void compute(const void* coords, bool doubleCoords, int stride, int count); + + btVector3 getCoordinates(const Vertex* v); + + btScalar shrink(btScalar amount, btScalar clampAmount); +}; + + +btConvexHullInternal::Int128 btConvexHullInternal::Int128::operator*(int64_t b) const +{ + bool negative = (int64_t) high < 0; + Int128 a = negative ? -*this : *this; + if (b < 0) + { + negative = !negative; + b = -b; + } + Int128 result = mul(a.low, (uint64_t) b); + result.high += a.high * (uint64_t) b; + return negative ? -result : result; +} + +btConvexHullInternal::Int128 btConvexHullInternal::Int128::mul(int64_t a, int64_t b) +{ + Int128 result; + +#ifdef USE_X86_64_ASM + __asm__ ("imulq %[b]" + : "=a" (result.low), "=d" (result.high) + : "0"(a), [b] "r"(b) + : "cc" ); + return result; + +#else + bool negative = a < 0; + if (negative) + { + a = -a; + } + if (b < 0) + { + negative = !negative; + b = -b; + } + DMul::mul((uint64_t) a, (uint64_t) b, result.low, result.high); + return negative ? -result : result; +#endif +} + +btConvexHullInternal::Int128 btConvexHullInternal::Int128::mul(uint64_t a, uint64_t b) +{ + Int128 result; + +#ifdef USE_X86_64_ASM + __asm__ ("mulq %[b]" + : "=a" (result.low), "=d" (result.high) + : "0"(a), [b] "r"(b) + : "cc" ); + +#else + DMul::mul(a, b, result.low, result.high); +#endif + + return result; +} + +int btConvexHullInternal::Rational64::compare(const Rational64& b) const +{ + if (sign != b.sign) + { + return sign - b.sign; + } + else if (sign == 0) + { + return 0; + } + + // return (numerator * b.denominator > b.numerator * denominator) ? sign : (numerator * b.denominator < b.numerator * denominator) ? -sign : 0; + +#ifdef USE_X86_64_ASM + + int result; + int64_t tmp; + int64_t dummy; + __asm__ ("mulq %[bn]\n\t" + "movq %%rax, %[tmp]\n\t" + "movq %%rdx, %%rbx\n\t" + "movq %[tn], %%rax\n\t" + "mulq %[bd]\n\t" + "subq %[tmp], %%rax\n\t" + "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" + "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise + "orq %%rdx, %%rax\n\t" + "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero + "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) + "shll $16, %%ebx\n\t" // ebx has same sign as difference + : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) + : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) + : "%rdx", "cc" ); + return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) + // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) + : 0; + +#else + + return sign * Int128::mul(m_numerator, b.m_denominator).ucmp(Int128::mul(m_denominator, b.m_numerator)); + +#endif +} + +int btConvexHullInternal::Rational128::compare(const Rational128& b) const +{ + if (sign != b.sign) + { + return sign - b.sign; + } + else if (sign == 0) + { + return 0; + } + if (isInt64) + { + return -b.compare(sign * (int64_t) numerator.low); + } + + Int128 nbdLow, nbdHigh, dbnLow, dbnHigh; + DMul::mul(numerator, b.denominator, nbdLow, nbdHigh); + DMul::mul(denominator, b.numerator, dbnLow, dbnHigh); + + int cmp = nbdHigh.ucmp(dbnHigh); + if (cmp) + { + return cmp * sign; + } + return nbdLow.ucmp(dbnLow) * sign; +} + +int btConvexHullInternal::Rational128::compare(int64_t b) const +{ + if (isInt64) + { + int64_t a = sign * (int64_t) numerator.low; + return (a > b) ? 1 : (a < b) ? -1 : 0; + } + if (b > 0) + { + if (sign <= 0) + { + return -1; + } + } + else if (b < 0) + { + if (sign >= 0) + { + return 1; + } + b = -b; + } + else + { + return sign; + } + + return numerator.ucmp(denominator * b) * sign; +} + + +btConvexHullInternal::Edge* btConvexHullInternal::newEdgePair(Vertex* from, Vertex* to) +{ + btAssert(from && to); + Edge* e = edgePool.newObject(); + Edge* r = edgePool.newObject(); + e->reverse = r; + r->reverse = e; + e->copy = mergeStamp; + r->copy = mergeStamp; + e->target = to; + r->target = from; + e->face = NULL; + r->face = NULL; + usedEdgePairs++; + if (usedEdgePairs > maxUsedEdgePairs) + { + maxUsedEdgePairs = usedEdgePairs; + } + return e; +} + +bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1) +{ + Vertex* v0 = h0.maxYx; + Vertex* v1 = h1.minYx; + if ((v0->point.x == v1->point.x) && (v0->point.y == v1->point.y)) + { + btAssert(v0->point.z < v1->point.z); + Vertex* v1p = v1->prev; + if (v1p == v1) + { + c0 = v0; + if (v1->edges) + { + btAssert(v1->edges->next == v1->edges); + v1 = v1->edges->target; + btAssert(v1->edges->next == v1->edges); + } + c1 = v1; + return false; + } + Vertex* v1n = v1->next; + v1p->next = v1n; + v1n->prev = v1p; + if (v1 == h1.minXy) + { + if ((v1n->point.x < v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y < v1p->point.y))) + { + h1.minXy = v1n; + } + else + { + h1.minXy = v1p; + } + } + if (v1 == h1.maxXy) + { + if ((v1n->point.x > v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y > v1p->point.y))) + { + h1.maxXy = v1n; + } + else + { + h1.maxXy = v1p; + } + } + } + + v0 = h0.maxXy; + v1 = h1.maxXy; + Vertex* v00 = NULL; + Vertex* v10 = NULL; + int32_t sign = 1; + + for (int side = 0; side <= 1; side++) + { + int32_t dx = (v1->point.x - v0->point.x) * sign; + if (dx > 0) + { + while (true) + { + int32_t dy = v1->point.y - v0->point.y; + + Vertex* w0 = side ? v0->next : v0->prev; + if (w0 != v0) + { + int32_t dx0 = (w0->point.x - v0->point.x) * sign; + int32_t dy0 = w0->point.y - v0->point.y; + if ((dy0 <= 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx <= dy * dx0)))) + { + v0 = w0; + dx = (v1->point.x - v0->point.x) * sign; + continue; + } + } + + Vertex* w1 = side ? v1->next : v1->prev; + if (w1 != v1) + { + int32_t dx1 = (w1->point.x - v1->point.x) * sign; + int32_t dy1 = w1->point.y - v1->point.y; + int32_t dxn = (w1->point.x - v0->point.x) * sign; + if ((dxn > 0) && (dy1 < 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx < dy * dx1)))) + { + v1 = w1; + dx = dxn; + continue; + } + } + + break; + } + } + else if (dx < 0) + { + while (true) + { + int32_t dy = v1->point.y - v0->point.y; + + Vertex* w1 = side ? v1->prev : v1->next; + if (w1 != v1) + { + int32_t dx1 = (w1->point.x - v1->point.x) * sign; + int32_t dy1 = w1->point.y - v1->point.y; + if ((dy1 >= 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx <= dy * dx1)))) + { + v1 = w1; + dx = (v1->point.x - v0->point.x) * sign; + continue; + } + } + + Vertex* w0 = side ? v0->prev : v0->next; + if (w0 != v0) + { + int32_t dx0 = (w0->point.x - v0->point.x) * sign; + int32_t dy0 = w0->point.y - v0->point.y; + int32_t dxn = (v1->point.x - w0->point.x) * sign; + if ((dxn < 0) && (dy0 > 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx < dy * dx0)))) + { + v0 = w0; + dx = dxn; + continue; + } + } + + break; + } + } + else + { + int32_t x = v0->point.x; + int32_t y0 = v0->point.y; + Vertex* w0 = v0; + Vertex* t; + while (((t = side ? w0->next : w0->prev) != v0) && (t->point.x == x) && (t->point.y <= y0)) + { + w0 = t; + y0 = t->point.y; + } + v0 = w0; + + int32_t y1 = v1->point.y; + Vertex* w1 = v1; + while (((t = side ? w1->prev : w1->next) != v1) && (t->point.x == x) && (t->point.y >= y1)) + { + w1 = t; + y1 = t->point.y; + } + v1 = w1; + } + + if (side == 0) + { + v00 = v0; + v10 = v1; + + v0 = h0.minXy; + v1 = h1.minXy; + sign = -1; + } + } + + v0->prev = v1; + v1->next = v0; + + v00->next = v10; + v10->prev = v00; + + if (h1.minXy->point.x < h0.minXy->point.x) + { + h0.minXy = h1.minXy; + } + if (h1.maxXy->point.x >= h0.maxXy->point.x) + { + h0.maxXy = h1.maxXy; + } + + h0.maxYx = h1.maxYx; + + c0 = v00; + c1 = v10; + + return true; +} + +void btConvexHullInternal::computeInternal(int start, int end, IntermediateHull& result) +{ + int n = end - start; + switch (n) + { + case 0: + result.minXy = NULL; + result.maxXy = NULL; + result.minYx = NULL; + result.maxYx = NULL; + return; + case 2: + { + Vertex* v = originalVertices[start]; + Vertex* w = v + 1; + if (v->point != w->point) + { + int32_t dx = v->point.x - w->point.x; + int32_t dy = v->point.y - w->point.y; + + if ((dx == 0) && (dy == 0)) + { + if (v->point.z > w->point.z) + { + Vertex* t = w; + w = v; + v = t; + } + btAssert(v->point.z < w->point.z); + v->next = v; + v->prev = v; + result.minXy = v; + result.maxXy = v; + result.minYx = v; + result.maxYx = v; + } + else + { + v->next = w; + v->prev = w; + w->next = v; + w->prev = v; + + if ((dx < 0) || ((dx == 0) && (dy < 0))) + { + result.minXy = v; + result.maxXy = w; + } + else + { + result.minXy = w; + result.maxXy = v; + } + + if ((dy < 0) || ((dy == 0) && (dx < 0))) + { + result.minYx = v; + result.maxYx = w; + } + else + { + result.minYx = w; + result.maxYx = v; + } + } + + Edge* e = newEdgePair(v, w); + e->link(e); + v->edges = e; + + e = e->reverse; + e->link(e); + w->edges = e; + + return; + } + } + // lint -fallthrough + case 1: + { + Vertex* v = originalVertices[start]; + v->edges = NULL; + v->next = v; + v->prev = v; + + result.minXy = v; + result.maxXy = v; + result.minYx = v; + result.maxYx = v; + + return; + } + } + + int split0 = start + n / 2; + Point32 p = originalVertices[split0-1]->point; + int split1 = split0; + while ((split1 < end) && (originalVertices[split1]->point == p)) + { + split1++; + } + computeInternal(start, split0, result); + IntermediateHull hull1; + computeInternal(split1, end, hull1); +#ifdef DEBUG_CONVEX_HULL + printf("\n\nMerge\n"); + result.print(); + hull1.print(); +#endif + merge(result, hull1); +#ifdef DEBUG_CONVEX_HULL + printf("\n Result\n"); + result.print(); +#endif +} + +#ifdef DEBUG_CONVEX_HULL +void btConvexHullInternal::IntermediateHull::print() +{ + printf(" Hull\n"); + for (Vertex* v = minXy; v; ) + { + printf(" "); + v->print(); + if (v == maxXy) + { + printf(" maxXy"); + } + if (v == minYx) + { + printf(" minYx"); + } + if (v == maxYx) + { + printf(" maxYx"); + } + if (v->next->prev != v) + { + printf(" Inconsistency"); + } + printf("\n"); + v = v->next; + if (v == minXy) + { + break; + } + } + if (minXy) + { + minXy->copy = (minXy->copy == -1) ? -2 : -1; + minXy->printGraph(); + } +} + +void btConvexHullInternal::Vertex::printGraph() +{ + print(); + printf("\nEdges\n"); + Edge* e = edges; + if (e) + { + do + { + e->print(); + printf("\n"); + e = e->next; + } while (e != edges); + do + { + Vertex* v = e->target; + if (v->copy != copy) + { + v->copy = copy; + v->printGraph(); + } + e = e->next; + } while (e != edges); + } +} +#endif + +btConvexHullInternal::Orientation btConvexHullInternal::getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t) +{ + btAssert(prev->reverse->target == next->reverse->target); + if (prev->next == next) + { + if (prev->prev == next) + { + Point64 n = t.cross(s); + Point64 m = (*prev->target - *next->reverse->target).cross(*next->target - *next->reverse->target); + btAssert(!m.isZero()); + int64_t dot = n.dot(m); + btAssert(dot != 0); + return (dot > 0) ? COUNTER_CLOCKWISE : CLOCKWISE; + } + return COUNTER_CLOCKWISE; + } + else if (prev->prev == next) + { + return CLOCKWISE; + } + else + { + return NONE; + } +} + +btConvexHullInternal::Edge* btConvexHullInternal::findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot) +{ + Edge* minEdge = NULL; + +#ifdef DEBUG_CONVEX_HULL + printf("find max edge for %d\n", start->point.index); +#endif + Edge* e = start->edges; + if (e) + { + do + { + if (e->copy > mergeStamp) + { + Point32 t = *e->target - *start; + Rational64 cot(t.dot(sxrxs), t.dot(rxs)); +#ifdef DEBUG_CONVEX_HULL + printf(" Angle is %f (%d) for ", (float) btAtan(cot.toScalar()), (int) cot.isNaN()); + e->print(); +#endif + if (cot.isNaN()) + { + btAssert(ccw ? (t.dot(s) < 0) : (t.dot(s) > 0)); + } + else + { + int cmp; + if (minEdge == NULL) + { + minCot = cot; + minEdge = e; + } + else if ((cmp = cot.compare(minCot)) < 0) + { + minCot = cot; + minEdge = e; + } + else if ((cmp == 0) && (ccw == (getOrientation(minEdge, e, s, t) == COUNTER_CLOCKWISE))) + { + minEdge = e; + } + } +#ifdef DEBUG_CONVEX_HULL + printf("\n"); +#endif + } + e = e->next; + } while (e != start->edges); + } + return minEdge; +} + +void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1) +{ + Edge* start0 = e0; + Edge* start1 = e1; + Point32 et0 = start0 ? start0->target->point : c0->point; + Point32 et1 = start1 ? start1->target->point : c1->point; + Point32 s = c1->point - c0->point; + Point64 normal = ((start0 ? start0 : start1)->target->point - c0->point).cross(s); + int64_t dist = c0->point.dot(normal); + btAssert(!start1 || (start1->target->point.dot(normal) == dist)); + Point64 perp = s.cross(normal); + btAssert(!perp.isZero()); + +#ifdef DEBUG_CONVEX_HULL + printf(" Advancing %d %d (%p %p, %d %d)\n", c0->point.index, c1->point.index, start0, start1, start0 ? start0->target->point.index : -1, start1 ? start1->target->point.index : -1); +#endif + + int64_t maxDot0 = et0.dot(perp); + if (e0) + { + while (e0->target != stop0) + { + Edge* e = e0->reverse->prev; + if (e->target->point.dot(normal) < dist) + { + break; + } + btAssert(e->target->point.dot(normal) == dist); + if (e->copy == mergeStamp) + { + break; + } + int64_t dot = e->target->point.dot(perp); + if (dot <= maxDot0) + { + break; + } + maxDot0 = dot; + e0 = e; + et0 = e->target->point; + } + } + + int64_t maxDot1 = et1.dot(perp); + if (e1) + { + while (e1->target != stop1) + { + Edge* e = e1->reverse->next; + if (e->target->point.dot(normal) < dist) + { + break; + } + btAssert(e->target->point.dot(normal) == dist); + if (e->copy == mergeStamp) + { + break; + } + int64_t dot = e->target->point.dot(perp); + if (dot <= maxDot1) + { + break; + } + maxDot1 = dot; + e1 = e; + et1 = e->target->point; + } + } + +#ifdef DEBUG_CONVEX_HULL + printf(" Starting at %d %d\n", et0.index, et1.index); +#endif + + int64_t dx = maxDot1 - maxDot0; + if (dx > 0) + { + while (true) + { + int64_t dy = (et1 - et0).dot(s); + + if (e0 && (e0->target != stop0)) + { + Edge* f0 = e0->next->reverse; + if (f0->copy > mergeStamp) + { + int64_t dx0 = (f0->target->point - et0).dot(perp); + int64_t dy0 = (f0->target->point - et0).dot(s); + if ((dx0 == 0) ? (dy0 < 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) >= 0))) + { + et0 = f0->target->point; + dx = (et1 - et0).dot(perp); + e0 = (e0 == start0) ? NULL : f0; + continue; + } + } + } + + if (e1 && (e1->target != stop1)) + { + Edge* f1 = e1->reverse->next; + if (f1->copy > mergeStamp) + { + Point32 d1 = f1->target->point - et1; + if (d1.dot(normal) == 0) + { + int64_t dx1 = d1.dot(perp); + int64_t dy1 = d1.dot(s); + int64_t dxn = (f1->target->point - et0).dot(perp); + if ((dxn > 0) && ((dx1 == 0) ? (dy1 < 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) > 0)))) + { + e1 = f1; + et1 = e1->target->point; + dx = dxn; + continue; + } + } + else + { + btAssert((e1 == start1) && (d1.dot(normal) < 0)); + } + } + } + + break; + } + } + else if (dx < 0) + { + while (true) + { + int64_t dy = (et1 - et0).dot(s); + + if (e1 && (e1->target != stop1)) + { + Edge* f1 = e1->prev->reverse; + if (f1->copy > mergeStamp) + { + int64_t dx1 = (f1->target->point - et1).dot(perp); + int64_t dy1 = (f1->target->point - et1).dot(s); + if ((dx1 == 0) ? (dy1 > 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) <= 0))) + { + et1 = f1->target->point; + dx = (et1 - et0).dot(perp); + e1 = (e1 == start1) ? NULL : f1; + continue; + } + } + } + + if (e0 && (e0->target != stop0)) + { + Edge* f0 = e0->reverse->prev; + if (f0->copy > mergeStamp) + { + Point32 d0 = f0->target->point - et0; + if (d0.dot(normal) == 0) + { + int64_t dx0 = d0.dot(perp); + int64_t dy0 = d0.dot(s); + int64_t dxn = (et1 - f0->target->point).dot(perp); + if ((dxn < 0) && ((dx0 == 0) ? (dy0 > 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) < 0)))) + { + e0 = f0; + et0 = e0->target->point; + dx = dxn; + continue; + } + } + else + { + btAssert((e0 == start0) && (d0.dot(normal) < 0)); + } + } + } + + break; + } + } +#ifdef DEBUG_CONVEX_HULL + printf(" Advanced edges to %d %d\n", et0.index, et1.index); +#endif +} + + +void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) +{ + if (!h1.maxXy) + { + return; + } + if (!h0.maxXy) + { + h0 = h1; + return; + } + + mergeStamp--; + + Vertex* c0 = NULL; + Edge* toPrev0 = NULL; + Edge* firstNew0 = NULL; + Edge* pendingHead0 = NULL; + Edge* pendingTail0 = NULL; + Vertex* c1 = NULL; + Edge* toPrev1 = NULL; + Edge* firstNew1 = NULL; + Edge* pendingHead1 = NULL; + Edge* pendingTail1 = NULL; + Point32 prevPoint; + + if (mergeProjection(h0, h1, c0, c1)) + { + Point32 s = *c1 - *c0; + Point64 normal = Point32(0, 0, -1).cross(s); + Point64 t = s.cross(normal); + btAssert(!t.isZero()); + + Edge* e = c0->edges; + Edge* start0 = NULL; + if (e) + { + do + { + int64_t dot = (*e->target - *c0).dot(normal); + btAssert(dot <= 0); + if ((dot == 0) && ((*e->target - *c0).dot(t) > 0)) + { + if (!start0 || (getOrientation(start0, e, s, Point32(0, 0, -1)) == CLOCKWISE)) + { + start0 = e; + } + } + e = e->next; + } while (e != c0->edges); + } + + e = c1->edges; + Edge* start1 = NULL; + if (e) + { + do + { + int64_t dot = (*e->target - *c1).dot(normal); + btAssert(dot <= 0); + if ((dot == 0) && ((*e->target - *c1).dot(t) > 0)) + { + if (!start1 || (getOrientation(start1, e, s, Point32(0, 0, -1)) == COUNTER_CLOCKWISE)) + { + start1 = e; + } + } + e = e->next; + } while (e != c1->edges); + } + + if (start0 || start1) + { + findEdgeForCoplanarFaces(c0, c1, start0, start1, NULL, NULL); + if (start0) + { + c0 = start0->target; + } + if (start1) + { + c1 = start1->target; + } + } + + prevPoint = c1->point; + prevPoint.z++; + } + else + { + prevPoint = c1->point; + prevPoint.x++; + } + + Vertex* first0 = c0; + Vertex* first1 = c1; + bool firstRun = true; + + while (true) + { + Point32 s = *c1 - *c0; + Point32 r = prevPoint - c0->point; + Point64 rxs = r.cross(s); + Point64 sxrxs = s.cross(rxs); + +#ifdef DEBUG_CONVEX_HULL + printf("\n Checking %d %d\n", c0->point.index, c1->point.index); +#endif + Rational64 minCot0(0, 0); + Edge* min0 = findMaxAngle(false, c0, s, rxs, sxrxs, minCot0); + Rational64 minCot1(0, 0); + Edge* min1 = findMaxAngle(true, c1, s, rxs, sxrxs, minCot1); + if (!min0 && !min1) + { + Edge* e = newEdgePair(c0, c1); + e->link(e); + c0->edges = e; + + e = e->reverse; + e->link(e); + c1->edges = e; + return; + } + else + { + int cmp = !min0 ? 1 : !min1 ? -1 : minCot0.compare(minCot1); +#ifdef DEBUG_CONVEX_HULL + printf(" -> Result %d\n", cmp); +#endif + if (firstRun || ((cmp >= 0) ? !minCot1.isNegativeInfinity() : !minCot0.isNegativeInfinity())) + { + Edge* e = newEdgePair(c0, c1); + if (pendingTail0) + { + pendingTail0->prev = e; + } + else + { + pendingHead0 = e; + } + e->next = pendingTail0; + pendingTail0 = e; + + e = e->reverse; + if (pendingTail1) + { + pendingTail1->next = e; + } + else + { + pendingHead1 = e; + } + e->prev = pendingTail1; + pendingTail1 = e; + } + + Edge* e0 = min0; + Edge* e1 = min1; + +#ifdef DEBUG_CONVEX_HULL + printf(" Found min edges to %d %d\n", e0 ? e0->target->point.index : -1, e1 ? e1->target->point.index : -1); +#endif + + if (cmp == 0) + { + findEdgeForCoplanarFaces(c0, c1, e0, e1, NULL, NULL); + } + + if ((cmp >= 0) && e1) + { + if (toPrev1) + { + for (Edge* e = toPrev1->next, *n = NULL; e != min1; e = n) + { + n = e->next; + removeEdgePair(e); + } + } + + if (pendingTail1) + { + if (toPrev1) + { + toPrev1->link(pendingHead1); + } + else + { + min1->prev->link(pendingHead1); + firstNew1 = pendingHead1; + } + pendingTail1->link(min1); + pendingHead1 = NULL; + pendingTail1 = NULL; + } + else if (!toPrev1) + { + firstNew1 = min1; + } + + prevPoint = c1->point; + c1 = e1->target; + toPrev1 = e1->reverse; + } + + if ((cmp <= 0) && e0) + { + if (toPrev0) + { + for (Edge* e = toPrev0->prev, *n = NULL; e != min0; e = n) + { + n = e->prev; + removeEdgePair(e); + } + } + + if (pendingTail0) + { + if (toPrev0) + { + pendingHead0->link(toPrev0); + } + else + { + pendingHead0->link(min0->next); + firstNew0 = pendingHead0; + } + min0->link(pendingTail0); + pendingHead0 = NULL; + pendingTail0 = NULL; + } + else if (!toPrev0) + { + firstNew0 = min0; + } + + prevPoint = c0->point; + c0 = e0->target; + toPrev0 = e0->reverse; + } + } + + if ((c0 == first0) && (c1 == first1)) + { + if (toPrev0 == NULL) + { + pendingHead0->link(pendingTail0); + c0->edges = pendingTail0; + } + else + { + for (Edge* e = toPrev0->prev, *n = NULL; e != firstNew0; e = n) + { + n = e->prev; + removeEdgePair(e); + } + if (pendingTail0) + { + pendingHead0->link(toPrev0); + firstNew0->link(pendingTail0); + } + } + + if (toPrev1 == NULL) + { + pendingTail1->link(pendingHead1); + c1->edges = pendingTail1; + } + else + { + for (Edge* e = toPrev1->next, *n = NULL; e != firstNew1; e = n) + { + n = e->next; + removeEdgePair(e); + } + if (pendingTail1) + { + toPrev1->link(pendingHead1); + pendingTail1->link(firstNew1); + } + } + + return; + } + + firstRun = false; + } +} + + +static bool pointCmp(const btConvexHullInternal::Point32& p, const btConvexHullInternal::Point32& q) +{ + return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z)))); +} + +void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int stride, int count) +{ + btVector3 min(btScalar(1e30), btScalar(1e30), btScalar(1e30)), max(btScalar(-1e30), btScalar(-1e30), btScalar(-1e30)); + const char* ptr = (const char*) coords; + if (doubleCoords) + { + for (int i = 0; i < count; i++) + { + const double* v = (const double*) ptr; + btVector3 p((btScalar) v[0], (btScalar) v[1], (btScalar) v[2]); + ptr += stride; + min.setMin(p); + max.setMax(p); + } + } + else + { + for (int i = 0; i < count; i++) + { + const float* v = (const float*) ptr; + btVector3 p(v[0], v[1], v[2]); + ptr += stride; + min.setMin(p); + max.setMax(p); + } + } + + btVector3 s = max - min; + maxAxis = s.maxAxis(); + minAxis = s.minAxis(); + if (minAxis == maxAxis) + { + minAxis = (maxAxis + 1) % 3; + } + medAxis = 3 - maxAxis - minAxis; + + s /= btScalar(10216); + if (((medAxis + 1) % 3) != maxAxis) + { + s *= -1; + } + scaling = s; + + if (s[0] != 0) + { + s[0] = btScalar(1) / s[0]; + } + if (s[1] != 0) + { + s[1] = btScalar(1) / s[1]; + } + if (s[2] != 0) + { + s[2] = btScalar(1) / s[2]; + } + + center = (min + max) * btScalar(0.5); + + btAlignedObjectArray points; + points.resize(count); + ptr = (const char*) coords; + if (doubleCoords) + { + for (int i = 0; i < count; i++) + { + const double* v = (const double*) ptr; + btVector3 p((btScalar) v[0], (btScalar) v[1], (btScalar) v[2]); + ptr += stride; + p = (p - center) * s; + points[i].x = (int32_t) p[medAxis]; + points[i].y = (int32_t) p[maxAxis]; + points[i].z = (int32_t) p[minAxis]; + points[i].index = i; + } + } + else + { + for (int i = 0; i < count; i++) + { + const float* v = (const float*) ptr; + btVector3 p(v[0], v[1], v[2]); + ptr += stride; + p = (p - center) * s; + points[i].x = (int32_t) p[medAxis]; + points[i].y = (int32_t) p[maxAxis]; + points[i].z = (int32_t) p[minAxis]; + points[i].index = i; + } + } + points.quickSort(pointCmp); + + vertexPool.reset(); + vertexPool.setArraySize(count); + originalVertices.resize(count); + for (int i = 0; i < count; i++) + { + Vertex* v = vertexPool.newObject(); + v->edges = NULL; + v->point = points[i]; + v->copy = -1; + originalVertices[i] = v; + } + + points.clear(); + + edgePool.reset(); + edgePool.setArraySize(6 * count); + + usedEdgePairs = 0; + maxUsedEdgePairs = 0; + + mergeStamp = -3; + + IntermediateHull hull; + computeInternal(0, count, hull); + vertexList = hull.minXy; +#ifdef DEBUG_CONVEX_HULL + printf("max. edges %d (3v = %d)", maxUsedEdgePairs, 3 * count); +#endif +} + +btVector3 btConvexHullInternal::toBtVector(const Point32& v) +{ + btVector3 p; + p[medAxis] = btScalar(v.x); + p[maxAxis] = btScalar(v.y); + p[minAxis] = btScalar(v.z); + return p * scaling; +} + +btVector3 btConvexHullInternal::getBtNormal(Face* face) +{ + return toBtVector(face->dir0).cross(toBtVector(face->dir1)).normalized(); +} + +btVector3 btConvexHullInternal::getCoordinates(const Vertex* v) +{ + btVector3 p; + p[medAxis] = v->xvalue(); + p[maxAxis] = v->yvalue(); + p[minAxis] = v->zvalue(); + return p * scaling + center; +} + +btScalar btConvexHullInternal::shrink(btScalar amount, btScalar clampAmount) +{ + if (!vertexList) + { + return 0; + } + int stamp = --mergeStamp; + btAlignedObjectArray stack; + vertexList->copy = stamp; + stack.push_back(vertexList); + btAlignedObjectArray faces; + + Point32 ref = vertexList->point; + Int128 hullCenterX(0, 0); + Int128 hullCenterY(0, 0); + Int128 hullCenterZ(0, 0); + Int128 volume(0, 0); + + while (stack.size() > 0) + { + Vertex* v = stack[stack.size() - 1]; + stack.pop_back(); + Edge* e = v->edges; + if (e) + { + do + { + if (e->target->copy != stamp) + { + e->target->copy = stamp; + stack.push_back(e->target); + } + if (e->copy != stamp) + { + Face* face = facePool.newObject(); + face->init(e->target, e->reverse->prev->target, v); + faces.push_back(face); + Edge* f = e; + + Vertex* a = NULL; + Vertex* b = NULL; + do + { + if (a && b) + { + int64_t vol = (v->point - ref).dot((a->point - ref).cross(b->point - ref)); + btAssert(vol >= 0); + Point32 c = v->point + a->point + b->point + ref; + hullCenterX += vol * c.x; + hullCenterY += vol * c.y; + hullCenterZ += vol * c.z; + volume += vol; + } + + btAssert(f->copy != stamp); + f->copy = stamp; + f->face = face; + + a = b; + b = f->target; + + f = f->reverse->prev; + } while (f != e); + } + e = e->next; + } while (e != v->edges); + } + } + + if (volume.getSign() <= 0) + { + return 0; + } + + btVector3 hullCenter; + hullCenter[medAxis] = hullCenterX.toScalar(); + hullCenter[maxAxis] = hullCenterY.toScalar(); + hullCenter[minAxis] = hullCenterZ.toScalar(); + hullCenter /= 4 * volume.toScalar(); + hullCenter *= scaling; + + int faceCount = faces.size(); + + if (clampAmount > 0) + { + btScalar minDist = SIMD_INFINITY; + for (int i = 0; i < faceCount; i++) + { + btVector3 normal = getBtNormal(faces[i]); + btScalar dist = normal.dot(toBtVector(faces[i]->origin) - hullCenter); + if (dist < minDist) + { + minDist = dist; + } + } + + if (minDist <= 0) + { + return 0; + } + + amount = btMin(amount, minDist * clampAmount); + } + + unsigned int seed = 243703; + for (int i = 0; i < faceCount; i++, seed = 1664525 * seed + 1013904223) + { + btSwap(faces[i], faces[seed % faceCount]); + } + + for (int i = 0; i < faceCount; i++) + { + if (!shiftFace(faces[i], amount, stack)) + { + return -amount; + } + } + + return amount; +} + +bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjectArray stack) +{ + btVector3 origShift = getBtNormal(face) * -amount; + if (scaling[0] != 0) + { + origShift[0] /= scaling[0]; + } + if (scaling[1] != 0) + { + origShift[1] /= scaling[1]; + } + if (scaling[2] != 0) + { + origShift[2] /= scaling[2]; + } + Point32 shift((int32_t) origShift[medAxis], (int32_t) origShift[maxAxis], (int32_t) origShift[minAxis]); + if (shift.isZero()) + { + return true; + } + Point64 normal = face->getNormal(); +#ifdef DEBUG_CONVEX_HULL + printf("\nShrinking face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n", + face->origin.x, face->origin.y, face->origin.z, face->dir0.x, face->dir0.y, face->dir0.z, face->dir1.x, face->dir1.y, face->dir1.z, shift.x, shift.y, shift.z); +#endif + int64_t origDot = face->origin.dot(normal); + Point32 shiftedOrigin = face->origin + shift; + int64_t shiftedDot = shiftedOrigin.dot(normal); + btAssert(shiftedDot <= origDot); + if (shiftedDot >= origDot) + { + return false; + } + + Edge* intersection = NULL; + + Edge* startEdge = face->nearbyVertex->edges; +#ifdef DEBUG_CONVEX_HULL + printf("Start edge is "); + startEdge->print(); + printf(", normal is (%lld %lld %lld), shifted dot is %lld\n", normal.x, normal.y, normal.z, shiftedDot); +#endif + Rational128 optDot = face->nearbyVertex->dot(normal); + int cmp = optDot.compare(shiftedDot); +#ifdef SHOW_ITERATIONS + int n = 0; +#endif + if (cmp >= 0) + { + Edge* e = startEdge; + do + { +#ifdef SHOW_ITERATIONS + n++; +#endif + Rational128 dot = e->target->dot(normal); + btAssert(dot.compare(origDot) <= 0); +#ifdef DEBUG_CONVEX_HULL + printf("Moving downwards, edge is "); + e->print(); + printf(", dot is %f (%f %lld)\n", (float) dot.toScalar(), (float) optDot.toScalar(), shiftedDot); +#endif + if (dot.compare(optDot) < 0) + { + int c = dot.compare(shiftedDot); + optDot = dot; + e = e->reverse; + startEdge = e; + if (c < 0) + { + intersection = e; + break; + } + cmp = c; + } + e = e->prev; + } while (e != startEdge); + + if (!intersection) + { + return false; + } + } + else + { + Edge* e = startEdge; + do + { +#ifdef SHOW_ITERATIONS + n++; +#endif + Rational128 dot = e->target->dot(normal); + btAssert(dot.compare(origDot) <= 0); +#ifdef DEBUG_CONVEX_HULL + printf("Moving upwards, edge is "); + e->print(); + printf(", dot is %f (%f %lld)\n", (float) dot.toScalar(), (float) optDot.toScalar(), shiftedDot); +#endif + if (dot.compare(optDot) > 0) + { + cmp = dot.compare(shiftedDot); + if (cmp >= 0) + { + intersection = e; + break; + } + optDot = dot; + e = e->reverse; + startEdge = e; + } + e = e->prev; + } while (e != startEdge); + + if (!intersection) + { + return true; + } + } + +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to find initial intersection\n", n); +#endif + + if (cmp == 0) + { + Edge* e = intersection->reverse->next; +#ifdef SHOW_ITERATIONS + n = 0; +#endif + while (e->target->dot(normal).compare(shiftedDot) <= 0) + { +#ifdef SHOW_ITERATIONS + n++; +#endif + e = e->next; + if (e == intersection->reverse) + { + return true; + } +#ifdef DEBUG_CONVEX_HULL + printf("Checking for outwards edge, current edge is "); + e->print(); + printf("\n"); +#endif + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to check for complete containment\n", n); +#endif + } + + Edge* firstIntersection = NULL; + Edge* faceEdge = NULL; + Edge* firstFaceEdge = NULL; + +#ifdef SHOW_ITERATIONS + int m = 0; +#endif + while (true) + { +#ifdef SHOW_ITERATIONS + m++; +#endif +#ifdef DEBUG_CONVEX_HULL + printf("Intersecting edge is "); + intersection->print(); + printf("\n"); +#endif + if (cmp == 0) + { + Edge* e = intersection->reverse->next; + startEdge = e; +#ifdef SHOW_ITERATIONS + n = 0; +#endif + while (true) + { +#ifdef SHOW_ITERATIONS + n++; +#endif + if (e->target->dot(normal).compare(shiftedDot) >= 0) + { + break; + } + intersection = e->reverse; + e = e->next; + if (e == startEdge) + { + return true; + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to advance intersection\n", n); +#endif + } + +#ifdef DEBUG_CONVEX_HULL + printf("Advanced intersecting edge to "); + intersection->print(); + printf(", cmp = %d\n", cmp); +#endif + + if (!firstIntersection) + { + firstIntersection = intersection; + } + else if (intersection == firstIntersection) + { + break; + } + + int prevCmp = cmp; + Edge* prevIntersection = intersection; + Edge* prevFaceEdge = faceEdge; + + Edge* e = intersection->reverse; +#ifdef SHOW_ITERATIONS + n = 0; +#endif + while (true) + { +#ifdef SHOW_ITERATIONS + n++; +#endif + e = e->reverse->prev; + btAssert(e != intersection->reverse); + cmp = e->target->dot(normal).compare(shiftedDot); +#ifdef DEBUG_CONVEX_HULL + printf("Testing edge "); + e->print(); + printf(" -> cmp = %d\n", cmp); +#endif + if (cmp >= 0) + { + intersection = e; + break; + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to find other intersection of face\n", n); +#endif + + if (cmp > 0) + { + Vertex* removed = intersection->target; + e = intersection->reverse; + if (e->prev == e) + { + removed->edges = NULL; + } + else + { + removed->edges = e->prev; + e->prev->link(e->next); + e->link(e); + } +#ifdef DEBUG_CONVEX_HULL + printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); +#endif + + Point64 n0 = intersection->face->getNormal(); + Point64 n1 = intersection->reverse->face->getNormal(); + int64_t m00 = face->dir0.dot(n0); + int64_t m01 = face->dir1.dot(n0); + int64_t m10 = face->dir0.dot(n1); + int64_t m11 = face->dir1.dot(n1); + int64_t r0 = (intersection->face->origin - shiftedOrigin).dot(n0); + int64_t r1 = (intersection->reverse->face->origin - shiftedOrigin).dot(n1); + Int128 det = Int128::mul(m00, m11) - Int128::mul(m01, m10); + btAssert(det.getSign() != 0); + Vertex* v = vertexPool.newObject(); + v->point.index = -1; + v->copy = -1; + v->point128 = PointR128(Int128::mul(face->dir0.x * r0, m11) - Int128::mul(face->dir0.x * r1, m01) + + Int128::mul(face->dir1.x * r1, m00) - Int128::mul(face->dir1.x * r0, m10) + det * shiftedOrigin.x, + Int128::mul(face->dir0.y * r0, m11) - Int128::mul(face->dir0.y * r1, m01) + + Int128::mul(face->dir1.y * r1, m00) - Int128::mul(face->dir1.y * r0, m10) + det * shiftedOrigin.y, + Int128::mul(face->dir0.z * r0, m11) - Int128::mul(face->dir0.z * r1, m01) + + Int128::mul(face->dir1.z * r1, m00) - Int128::mul(face->dir1.z * r0, m10) + det * shiftedOrigin.z, + det); + v->point.x = (int32_t) v->point128.xvalue(); + v->point.y = (int32_t) v->point128.yvalue(); + v->point.z = (int32_t) v->point128.zvalue(); + intersection->target = v; + v->edges = e; + + stack.push_back(v); + stack.push_back(removed); + stack.push_back(NULL); + } + + if (cmp || prevCmp || (prevIntersection->reverse->next->target != intersection->target)) + { + faceEdge = newEdgePair(prevIntersection->target, intersection->target); + if (prevCmp == 0) + { + faceEdge->link(prevIntersection->reverse->next); + } + if ((prevCmp == 0) || prevFaceEdge) + { + prevIntersection->reverse->link(faceEdge); + } + if (cmp == 0) + { + intersection->reverse->prev->link(faceEdge->reverse); + } + faceEdge->reverse->link(intersection->reverse); + } + else + { + faceEdge = prevIntersection->reverse->next; + } + + if (prevFaceEdge) + { + if (prevCmp > 0) + { + faceEdge->link(prevFaceEdge->reverse); + } + else if (faceEdge != prevFaceEdge->reverse) + { + stack.push_back(prevFaceEdge->target); + while (faceEdge->next != prevFaceEdge->reverse) + { + Vertex* removed = faceEdge->next->target; + removeEdgePair(faceEdge->next); + stack.push_back(removed); +#ifdef DEBUG_CONVEX_HULL + printf("2: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); +#endif + } + stack.push_back(NULL); + } + } + faceEdge->face = face; + faceEdge->reverse->face = intersection->face; + + if (!firstFaceEdge) + { + firstFaceEdge = faceEdge; + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to process all intersections\n", m); +#endif + + if (cmp > 0) + { + firstFaceEdge->reverse->target = faceEdge->target; + firstIntersection->reverse->link(firstFaceEdge); + firstFaceEdge->link(faceEdge->reverse); + } + else if (firstFaceEdge != faceEdge->reverse) + { + stack.push_back(faceEdge->target); + while (firstFaceEdge->next != faceEdge->reverse) + { + Vertex* removed = firstFaceEdge->next->target; + removeEdgePair(firstFaceEdge->next); + stack.push_back(removed); +#ifdef DEBUG_CONVEX_HULL + printf("3: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); +#endif + } + stack.push_back(NULL); + } + + btAssert(stack.size() > 0); + vertexList = stack[0]; + +#ifdef DEBUG_CONVEX_HULL + printf("Removing part\n"); +#endif +#ifdef SHOW_ITERATIONS + n = 0; +#endif + int pos = 0; + while (pos < stack.size()) + { + int end = stack.size(); + while (pos < end) + { + Vertex* kept = stack[pos++]; +#ifdef DEBUG_CONVEX_HULL + kept->print(); +#endif + bool deeper = false; + Vertex* removed; + while ((removed = stack[pos++]) != NULL) + { +#ifdef SHOW_ITERATIONS + n++; +#endif + kept->receiveNearbyFaces(removed); + while (removed->edges) + { + if (!deeper) + { + deeper = true; + stack.push_back(kept); + } + stack.push_back(removed->edges->target); + removeEdgePair(removed->edges); + } + } + if (deeper) + { + stack.push_back(NULL); + } + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to remove part\n", n); +#endif + + stack.resize(0); + face->origin = shiftedOrigin; + + return true; +} + + +static int getVertexCopy(btConvexHullInternal::Vertex* vertex, btAlignedObjectArray& vertices) +{ + int index = vertex->copy; + if (index < 0) + { + index = vertices.size(); + vertex->copy = index; + vertices.push_back(vertex); +#ifdef DEBUG_CONVEX_HULL + printf("Vertex %d gets index *%d\n", vertex->point.index, index); +#endif + } + return index; +} + +btScalar btConvexHullComputer::compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp) +{ + if (count <= 0) + { + vertices.clear(); + edges.clear(); + faces.clear(); + return 0; + } + + btConvexHullInternal hull; + hull.compute(coords, doubleCoords, stride, count); + + btScalar shift = 0; + if ((shrink > 0) && ((shift = hull.shrink(shrink, shrinkClamp)) < 0)) + { + vertices.clear(); + edges.clear(); + faces.clear(); + return shift; + } + + vertices.resize(0); + edges.resize(0); + faces.resize(0); + + btAlignedObjectArray oldVertices; + getVertexCopy(hull.vertexList, oldVertices); + int copied = 0; + while (copied < oldVertices.size()) + { + btConvexHullInternal::Vertex* v = oldVertices[copied]; + vertices.push_back(hull.getCoordinates(v)); + btConvexHullInternal::Edge* firstEdge = v->edges; + if (firstEdge) + { + int firstCopy = -1; + int prevCopy = -1; + btConvexHullInternal::Edge* e = firstEdge; + do + { + if (e->copy < 0) + { + int s = edges.size(); + edges.push_back(Edge()); + edges.push_back(Edge()); + Edge* c = &edges[s]; + Edge* r = &edges[s + 1]; + e->copy = s; + e->reverse->copy = s + 1; + c->reverse = 1; + r->reverse = -1; + c->targetVertex = getVertexCopy(e->target, oldVertices); + r->targetVertex = copied; +#ifdef DEBUG_CONVEX_HULL + printf(" CREATE: Vertex *%d has edge to *%d\n", copied, c->getTargetVertex()); +#endif + } + if (prevCopy >= 0) + { + edges[e->copy].next = prevCopy - e->copy; + } + else + { + firstCopy = e->copy; + } + prevCopy = e->copy; + e = e->next; + } while (e != firstEdge); + edges[firstCopy].next = prevCopy - firstCopy; + } + copied++; + } + + for (int i = 0; i < copied; i++) + { + btConvexHullInternal::Vertex* v = oldVertices[i]; + btConvexHullInternal::Edge* firstEdge = v->edges; + if (firstEdge) + { + btConvexHullInternal::Edge* e = firstEdge; + do + { + if (e->copy >= 0) + { +#ifdef DEBUG_CONVEX_HULL + printf("Vertex *%d has edge to *%d\n", i, edges[e->copy].getTargetVertex()); +#endif + faces.push_back(e->copy); + btConvexHullInternal::Edge* f = e; + do + { +#ifdef DEBUG_CONVEX_HULL + printf(" Face *%d\n", edges[f->copy].getTargetVertex()); +#endif + f->copy = -1; + f = f->reverse->prev; + } while (f != e); + } + e = e->next; + } while (e != firstEdge); + } + } + + return shift; +} + + + + + diff --git a/src/LinearMath/btConvexHullComputer.h b/src/LinearMath/btConvexHullComputer.h new file mode 100644 index 0000000..7240ac4 --- /dev/null +++ b/src/LinearMath/btConvexHullComputer.h @@ -0,0 +1,103 @@ +/* +Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_CONVEX_HULL_COMPUTER_H +#define BT_CONVEX_HULL_COMPUTER_H + +#include "btVector3.h" +#include "btAlignedObjectArray.h" + +/// Convex hull implementation based on Preparata and Hong +/// See http://code.google.com/p/bullet/issues/detail?id=275 +/// Ole Kniemeyer, MAXON Computer GmbH +class btConvexHullComputer +{ + private: + btScalar compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp); + + public: + + class Edge + { + private: + int next; + int reverse; + int targetVertex; + + friend class btConvexHullComputer; + + public: + int getSourceVertex() const + { + return (this + reverse)->targetVertex; + } + + int getTargetVertex() const + { + return targetVertex; + } + + const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex + { + return this + next; + } + + const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face + { + return (this + reverse)->getNextEdgeOfVertex(); + } + + const Edge* getReverseEdge() const + { + return this + reverse; + } + }; + + + // Vertices of the output hull + btAlignedObjectArray vertices; + + // Edges of the output hull + btAlignedObjectArray edges; + + // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons + btAlignedObjectArray faces; + + /* + Compute convex hull of "count" vertices stored in "coords". "stride" is the difference in bytes + between the addresses of consecutive vertices. If "shrink" is positive, the convex hull is shrunken + by that amount (each face is moved by "shrink" length units towards the center along its normal). + If "shrinkClamp" is positive, "shrink" is clamped to not exceed "shrinkClamp * innerRadius", where "innerRadius" + is the minimum distance of a face to the center of the convex hull. + + The returned value is the amount by which the hull has been shrunken. If it is negative, the amount was so large + that the resulting convex hull is empty. + + The output convex hull can be found in the member variables "vertices", "edges", "faces". + */ + btScalar compute(const float* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) + { + return compute(coords, false, stride, count, shrink, shrinkClamp); + } + + // same as above, but double precision + btScalar compute(const double* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) + { + return compute(coords, true, stride, count, shrink, shrinkClamp); + } +}; + + +#endif //BT_CONVEX_HULL_COMPUTER_H + diff --git a/src/LinearMath/btDefaultMotionState.h b/src/LinearMath/btDefaultMotionState.h new file mode 100644 index 0000000..c90b749 --- /dev/null +++ b/src/LinearMath/btDefaultMotionState.h @@ -0,0 +1,42 @@ +#ifndef BT_DEFAULT_MOTION_STATE_H +#define BT_DEFAULT_MOTION_STATE_H + +#include "btMotionState.h" + +///The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets. +ATTRIBUTE_ALIGNED16(struct) btDefaultMotionState : public btMotionState +{ + btTransform m_graphicsWorldTrans; + btTransform m_centerOfMassOffset; + btTransform m_startWorldTrans; + void* m_userPointer; + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(),const btTransform& centerOfMassOffset = btTransform::getIdentity()) + : m_graphicsWorldTrans(startTrans), + m_centerOfMassOffset(centerOfMassOffset), + m_startWorldTrans(startTrans), + m_userPointer(0) + + { + } + + ///synchronizes world transform from user to physics + virtual void getWorldTransform(btTransform& centerOfMassWorldTrans ) const + { + centerOfMassWorldTrans = m_centerOfMassOffset.inverse() * m_graphicsWorldTrans ; + } + + ///synchronizes world transform from physics to user + ///Bullet only calls the update of worldtransform for active objects + virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans) + { + m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset ; + } + + + +}; + +#endif //BT_DEFAULT_MOTION_STATE_H diff --git a/src/LinearMath/btGeometryUtil.cpp b/src/LinearMath/btGeometryUtil.cpp new file mode 100644 index 0000000..5ac230f --- /dev/null +++ b/src/LinearMath/btGeometryUtil.cpp @@ -0,0 +1,185 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#include "btGeometryUtil.h" + + +/* + Make sure this dummy function never changes so that it + can be used by probes that are checking whether the + library is actually installed. +*/ +extern "C" +{ + void btBulletMathProbe (); + + void btBulletMathProbe () {} +} + + +bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin) +{ + int numbrushes = planeEquations.size(); + for (int i=0;ibtScalar(0.)) + { + return false; + } + } + return true; + +} + + +bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin) +{ + int numvertices = vertices.size(); + for (int i=0;ibtScalar(0.)) + { + return false; + } + } + return true; +} + +bool notExist(const btVector3& planeEquation,const btAlignedObjectArray& planeEquations); + +bool notExist(const btVector3& planeEquation,const btAlignedObjectArray& planeEquations) +{ + int numbrushes = planeEquations.size(); + for (int i=0;i btScalar(0.999)) + { + return false; + } + } + return true; +} + +void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ) +{ + const int numvertices = vertices.size(); + // brute force: + for (int i=0;i btScalar(0.0001)) + { + planeEquation.normalize(); + if (notExist(planeEquation,planeEquationsOut)) + { + planeEquation[3] = -planeEquation.dot(N1); + + //check if inside, and replace supportingVertexOut if needed + if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01))) + { + planeEquationsOut.push_back(planeEquation); + } + } + } + normalSign = btScalar(-1.); + } + + } + } + } + +} + +void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ) +{ + const int numbrushes = planeEquations.size(); + // brute force: + for (int i=0;i btScalar(0.0001) ) && + ( n3n1.length2() > btScalar(0.0001) ) && + ( n1n2.length2() > btScalar(0.0001) ) ) + { + //point P out of 3 plane equations: + + // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) + //P = ------------------------------------------------------------------------- + // N1 . ( N2 * N3 ) + + + btScalar quotient = (N1.dot(n2n3)); + if (btFabs(quotient) > btScalar(0.000001)) + { + quotient = btScalar(-1.) / quotient; + n2n3 *= N1[3]; + n3n1 *= N2[3]; + n1n2 *= N3[3]; + btVector3 potentialVertex = n2n3; + potentialVertex += n3n1; + potentialVertex += n1n2; + potentialVertex *= quotient; + + //check if inside, and replace supportingVertexOut if needed + if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01))) + { + verticesOut.push_back(potentialVertex); + } + } + } + } + } + } +} + diff --git a/src/LinearMath/btGeometryUtil.h b/src/LinearMath/btGeometryUtil.h new file mode 100644 index 0000000..a4b13b4 --- /dev/null +++ b/src/LinearMath/btGeometryUtil.h @@ -0,0 +1,42 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_GEOMETRY_UTIL_H +#define BT_GEOMETRY_UTIL_H + +#include "btVector3.h" +#include "btAlignedObjectArray.h" + +///The btGeometryUtil helper class provides a few methods to convert between plane equations and vertices. +class btGeometryUtil +{ + public: + + + static void getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ); + + static void getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ); + + static bool isInside(const btAlignedObjectArray& vertices, const btVector3& planeNormal, btScalar margin); + + static bool isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin); + + static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin); + +}; + + +#endif //BT_GEOMETRY_UTIL_H + diff --git a/src/LinearMath/btGrahamScan2dConvexHull.h b/src/LinearMath/btGrahamScan2dConvexHull.h new file mode 100644 index 0000000..06af4ee --- /dev/null +++ b/src/LinearMath/btGrahamScan2dConvexHull.h @@ -0,0 +1,117 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef GRAHAM_SCAN_2D_CONVEX_HULL_H +#define GRAHAM_SCAN_2D_CONVEX_HULL_H + + +#include "btVector3.h" +#include "btAlignedObjectArray.h" + +struct GrahamVector3 : public btVector3 +{ + GrahamVector3(const btVector3& org, int orgIndex) + :btVector3(org), + m_orgIndex(orgIndex) + { + } + btScalar m_angle; + int m_orgIndex; +}; + + +struct btAngleCompareFunc { + btVector3 m_anchor; + btAngleCompareFunc(const btVector3& anchor) + : m_anchor(anchor) + { + } + bool operator()(const GrahamVector3& a, const GrahamVector3& b) const { + if (a.m_angle != b.m_angle) + return a.m_angle < b.m_angle; + else + { + btScalar al = (a-m_anchor).length2(); + btScalar bl = (b-m_anchor).length2(); + if (al != bl) + return al < bl; + else + { + return a.m_orgIndex < b.m_orgIndex; + } + } + } +}; + +inline void GrahamScanConvexHull2D(btAlignedObjectArray& originalPoints, btAlignedObjectArray& hull, const btVector3& normalAxis) +{ + btVector3 axis0,axis1; + btPlaneSpace1(normalAxis,axis0,axis1); + + + if (originalPoints.size()<=1) + { + for (int i=0;i1) { + btVector3& a = hull[hull.size()-2]; + btVector3& b = hull[hull.size()-1]; + isConvex = btCross(a-b,a-originalPoints[i]).dot(normalAxis)> 0; + if (!isConvex) + hull.pop_back(); + else + hull.push_back(originalPoints[i]); + } + } +} + +#endif //GRAHAM_SCAN_2D_CONVEX_HULL_H diff --git a/src/LinearMath/btHashMap.h b/src/LinearMath/btHashMap.h new file mode 100644 index 0000000..ce07db3 --- /dev/null +++ b/src/LinearMath/btHashMap.h @@ -0,0 +1,450 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_HASH_MAP_H +#define BT_HASH_MAP_H + +#include "btAlignedObjectArray.h" + +///very basic hashable string implementation, compatible with btHashMap +struct btHashString +{ + const char* m_string; + unsigned int m_hash; + + SIMD_FORCE_INLINE unsigned int getHash()const + { + return m_hash; + } + + btHashString(const char* name) + :m_string(name) + { + /* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */ + static const unsigned int InitialFNV = 2166136261u; + static const unsigned int FNVMultiple = 16777619u; + + /* Fowler / Noll / Vo (FNV) Hash */ + unsigned int hash = InitialFNV; + + for(int i = 0; m_string[i]; i++) + { + hash = hash ^ (m_string[i]); /* xor the low 8 bits */ + hash = hash * FNVMultiple; /* multiply by the magic number */ + } + m_hash = hash; + } + + int portableStringCompare(const char* src, const char* dst) const + { + int ret = 0 ; + + while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) + ++src, ++dst; + + if ( ret < 0 ) + ret = -1 ; + else if ( ret > 0 ) + ret = 1 ; + + return( ret ); + } + + bool equals(const btHashString& other) const + { + return (m_string == other.m_string) || + (0==portableStringCompare(m_string,other.m_string)); + + } + +}; + +const int BT_HASH_NULL=0xffffffff; + + +class btHashInt +{ + int m_uid; +public: + btHashInt(int uid) :m_uid(uid) + { + } + + int getUid1() const + { + return m_uid; + } + + void setUid1(int uid) + { + m_uid = uid; + } + + bool equals(const btHashInt& other) const + { + return getUid1() == other.getUid1(); + } + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } +}; + + + +class btHashPtr +{ + + union + { + const void* m_pointer; + int m_hashValues[2]; + }; + +public: + + btHashPtr(const void* ptr) + :m_pointer(ptr) + { + } + + const void* getPointer() const + { + return m_pointer; + } + + bool equals(const btHashPtr& other) const + { + return getPointer() == other.getPointer(); + } + + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + const bool VOID_IS_8 = ((sizeof(void*)==8)); + + int key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[0]; + + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } + + +}; + + +template +class btHashKeyPtr +{ + int m_uid; +public: + + btHashKeyPtr(int uid) :m_uid(uid) + { + } + + int getUid1() const + { + return m_uid; + } + + bool equals(const btHashKeyPtr& other) const + { + return getUid1() == other.getUid1(); + } + + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } + + +}; + + +template +class btHashKey +{ + int m_uid; +public: + + btHashKey(int uid) :m_uid(uid) + { + } + + int getUid1() const + { + return m_uid; + } + + bool equals(const btHashKey& other) const + { + return getUid1() == other.getUid1(); + } + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } +}; + + +///The btHashMap template class implements a generic and lightweight hashmap. +///A basic sample of how to use btHashMap is located in Demos\BasicDemo\main.cpp +template +class btHashMap +{ + +protected: + btAlignedObjectArray m_hashTable; + btAlignedObjectArray m_next; + + btAlignedObjectArray m_valueArray; + btAlignedObjectArray m_keyArray; + + void growTables(const Key& /*key*/) + { + int newCapacity = m_valueArray.capacity(); + + if (m_hashTable.size() < newCapacity) + { + //grow hashtable and next table + int curHashtableSize = m_hashTable.size(); + + m_hashTable.resize(newCapacity); + m_next.resize(newCapacity); + + int i; + + for (i= 0; i < newCapacity; ++i) + { + m_hashTable[i] = BT_HASH_NULL; + } + for (i = 0; i < newCapacity; ++i) + { + m_next[i] = BT_HASH_NULL; + } + + for(i=0;i= (unsigned int)m_hashTable.size()) + { + return BT_HASH_NULL; + } + + int index = m_hashTable[hash]; + while ((index != BT_HASH_NULL) && key.equals(m_keyArray[index]) == false) + { + index = m_next[index]; + } + return index; + } + + void clear() + { + m_hashTable.clear(); + m_next.clear(); + m_valueArray.clear(); + m_keyArray.clear(); + } + +}; + +#endif //BT_HASH_MAP_H diff --git a/src/LinearMath/btIDebugDraw.h b/src/LinearMath/btIDebugDraw.h new file mode 100644 index 0000000..a00d776 --- /dev/null +++ b/src/LinearMath/btIDebugDraw.h @@ -0,0 +1,419 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_IDEBUG_DRAW__H +#define BT_IDEBUG_DRAW__H + +#include "btVector3.h" +#include "btTransform.h" + + +///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations. +///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld. +///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum. +///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1] +class btIDebugDraw +{ + public: + + enum DebugDrawModes + { + DBG_NoDebug=0, + DBG_DrawWireframe = 1, + DBG_DrawAabb=2, + DBG_DrawFeaturesText=4, + DBG_DrawContactPoints=8, + DBG_NoDeactivation=16, + DBG_NoHelpText = 32, + DBG_DrawText=64, + DBG_ProfileTimings = 128, + DBG_EnableSatComparison = 256, + DBG_DisableBulletLCP = 512, + DBG_EnableCCD = 1024, + DBG_DrawConstraints = (1 << 11), + DBG_DrawConstraintLimits = (1 << 12), + DBG_FastWireframe = (1<<13), + DBG_DrawNormals = (1<<14), + DBG_MAX_DEBUG_DRAW_MODE + }; + + virtual ~btIDebugDraw() {}; + + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0; + + virtual void drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor) + { + (void) toColor; + drawLine (from, to, fromColor); + } + + virtual void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color) + { + btVector3 start = transform.getOrigin(); + + const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0); + const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0); + const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius); + + // XY + drawLine(start-xoffs, start+yoffs, color); + drawLine(start+yoffs, start+xoffs, color); + drawLine(start+xoffs, start-yoffs, color); + drawLine(start-yoffs, start-xoffs, color); + + // XZ + drawLine(start-xoffs, start+zoffs, color); + drawLine(start+zoffs, start+xoffs, color); + drawLine(start+xoffs, start-zoffs, color); + drawLine(start-zoffs, start-xoffs, color); + + // YZ + drawLine(start-yoffs, start+zoffs, color); + drawLine(start+zoffs, start+yoffs, color); + drawLine(start+yoffs, start-zoffs, color); + drawLine(start-zoffs, start-yoffs, color); + } + + virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color) + { + btTransform tr; + tr.setIdentity(); + tr.setOrigin(p); + drawSphere(radius,tr,color); + } + + virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha) + { + drawTriangle(v0,v1,v2,color,alpha); + } + virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& color, btScalar /*alpha*/) + { + drawLine(v0,v1,color); + drawLine(v1,v2,color); + drawLine(v2,v0,color); + } + + virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0; + + virtual void reportErrorWarning(const char* warningString) = 0; + + virtual void draw3dText(const btVector3& location,const char* textString) = 0; + + virtual void setDebugMode(int debugMode) =0; + + virtual int getDebugMode() const = 0; + + virtual void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color) + { + + btVector3 halfExtents = (to-from)* 0.5f; + btVector3 center = (to+from) *0.5f; + int i,j; + + btVector3 edgecoord(1.f,1.f,1.f),pa,pb; + for (i=0;i<4;i++) + { + for (j=0;j<3;j++) + { + pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], + edgecoord[2]*halfExtents[2]); + pa+=center; + + int othercoord = j%3; + edgecoord[othercoord]*=-1.f; + pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], + edgecoord[2]*halfExtents[2]); + pb+=center; + + drawLine(pa,pb,color); + } + edgecoord = btVector3(-1.f,-1.f,-1.f); + if (i<3) + edgecoord[i]*=-1.f; + } + } + virtual void drawTransform(const btTransform& transform, btScalar orthoLen) + { + btVector3 start = transform.getOrigin(); + drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(0.7f,0,0)); + drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(0,0.7f,0)); + drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(0,0,0.7f)); + } + + virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle, + const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f)) + { + const btVector3& vx = axis; + btVector3 vy = normal.cross(axis); + btScalar step = stepDegrees * SIMD_RADS_PER_DEG; + int nSteps = (int)((maxAngle - minAngle) / step); + if(!nSteps) nSteps = 1; + btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle); + if(drawSect) + { + drawLine(center, prev, color); + } + for(int i = 1; i <= nSteps; i++) + { + btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps); + btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle); + drawLine(prev, next, color); + prev = next; + } + if(drawSect) + { + drawLine(center, prev, color); + } + } + virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius, + btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f)) + { + btVector3 vA[74]; + btVector3 vB[74]; + btVector3 *pvA = vA, *pvB = vB, *pT; + btVector3 npole = center + up * radius; + btVector3 spole = center - up * radius; + btVector3 arcStart; + btScalar step = stepDegrees * SIMD_RADS_PER_DEG; + const btVector3& kv = up; + const btVector3& iv = axis; + btVector3 jv = kv.cross(iv); + bool drawN = false; + bool drawS = false; + if(minTh <= -SIMD_HALF_PI) + { + minTh = -SIMD_HALF_PI + step; + drawN = true; + } + if(maxTh >= SIMD_HALF_PI) + { + maxTh = SIMD_HALF_PI - step; + drawS = true; + } + if(minTh > maxTh) + { + minTh = -SIMD_HALF_PI + step; + maxTh = SIMD_HALF_PI - step; + drawN = drawS = true; + } + int n_hor = (int)((maxTh - minTh) / step) + 1; + if(n_hor < 2) n_hor = 2; + btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1); + bool isClosed = false; + if(minPs > maxPs) + { + minPs = -SIMD_PI + step; + maxPs = SIMD_PI; + isClosed = true; + } + else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f)) + { + isClosed = true; + } + else + { + isClosed = false; + } + int n_vert = (int)((maxPs - minPs) / step) + 1; + if(n_vert < 2) n_vert = 2; + btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1); + for(int i = 0; i < n_hor; i++) + { + btScalar th = minTh + btScalar(i) * step_h; + btScalar sth = radius * btSin(th); + btScalar cth = radius * btCos(th); + for(int j = 0; j < n_vert; j++) + { + btScalar psi = minPs + btScalar(j) * step_v; + btScalar sps = btSin(psi); + btScalar cps = btCos(psi); + pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv; + if(i) + { + drawLine(pvA[j], pvB[j], color); + } + else if(drawS) + { + drawLine(spole, pvB[j], color); + } + if(j) + { + drawLine(pvB[j-1], pvB[j], color); + } + else + { + arcStart = pvB[j]; + } + if((i == (n_hor - 1)) && drawN) + { + drawLine(npole, pvB[j], color); + } + if(isClosed) + { + if(j == (n_vert-1)) + { + drawLine(arcStart, pvB[j], color); + } + } + else + { + if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1)))) + { + drawLine(center, pvB[j], color); + } + } + } + pT = pvA; pvA = pvB; pvB = pT; + } + } + + + virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color) + { + drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color); + drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color); + drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color); + drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color); + drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color); + } + virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color) + { + drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color); + } + + virtual void drawCapsule(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color) + { + btVector3 capStart(0.f,0.f,0.f); + capStart[upAxis] = -halfHeight; + + btVector3 capEnd(0.f,0.f,0.f); + capEnd[upAxis] = halfHeight; + + // Draw the ends + { + + btTransform childTransform = transform; + childTransform.getOrigin() = transform * capStart; + drawSphere(radius, childTransform, color); + } + + { + btTransform childTransform = transform; + childTransform.getOrigin() = transform * capEnd; + drawSphere(radius, childTransform, color); + } + + // Draw some additional lines + btVector3 start = transform.getOrigin(); + + capStart[(upAxis+1)%3] = radius; + capEnd[(upAxis+1)%3] = radius; + drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color); + capStart[(upAxis+1)%3] = -radius; + capEnd[(upAxis+1)%3] = -radius; + drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color); + + capStart[(upAxis+1)%3] = 0.f; + capEnd[(upAxis+1)%3] = 0.f; + + capStart[(upAxis+2)%3] = radius; + capEnd[(upAxis+2)%3] = radius; + drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color); + capStart[(upAxis+2)%3] = -radius; + capEnd[(upAxis+2)%3] = -radius; + drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color); + } + + virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color) + { + btVector3 start = transform.getOrigin(); + btVector3 offsetHeight(0,0,0); + offsetHeight[upAxis] = halfHeight; + btVector3 offsetRadius(0,0,0); + offsetRadius[(upAxis+1)%3] = radius; + drawLine(start+transform.getBasis() * (offsetHeight+offsetRadius),start+transform.getBasis() * (-offsetHeight+offsetRadius),color); + drawLine(start+transform.getBasis() * (offsetHeight-offsetRadius),start+transform.getBasis() * (-offsetHeight-offsetRadius),color); + + // Drawing top and bottom caps of the cylinder + btVector3 yaxis(0,0,0); + yaxis[upAxis] = btScalar(1.0); + btVector3 xaxis(0,0,0); + xaxis[(upAxis+1)%3] = btScalar(1.0); + drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0)); + drawArc(start+transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0)); + } + + virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform& transform, const btVector3& color) + { + + btVector3 start = transform.getOrigin(); + + btVector3 offsetHeight(0,0,0); + offsetHeight[upAxis] = height * btScalar(0.5); + btVector3 offsetRadius(0,0,0); + offsetRadius[(upAxis+1)%3] = radius; + btVector3 offset2Radius(0,0,0); + offset2Radius[(upAxis+2)%3] = radius; + + drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offsetRadius),color); + drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offsetRadius),color); + drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offset2Radius),color); + drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offset2Radius),color); + + // Drawing the base of the cone + btVector3 yaxis(0,0,0); + yaxis[upAxis] = btScalar(1.0); + btVector3 xaxis(0,0,0); + xaxis[(upAxis+1)%3] = btScalar(1.0); + drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,10.0); + } + + virtual void drawPlane(const btVector3& planeNormal, btScalar planeConst, const btTransform& transform, const btVector3& color) + { + btVector3 planeOrigin = planeNormal * planeConst; + btVector3 vec0,vec1; + btPlaneSpace1(planeNormal,vec0,vec1); + btScalar vecLen = 100.f; + btVector3 pt0 = planeOrigin + vec0*vecLen; + btVector3 pt1 = planeOrigin - vec0*vecLen; + btVector3 pt2 = planeOrigin + vec1*vecLen; + btVector3 pt3 = planeOrigin - vec1*vecLen; + drawLine(transform*pt0,transform*pt1,color); + drawLine(transform*pt2,transform*pt3,color); + } +}; + + +#endif //BT_IDEBUG_DRAW__H + diff --git a/src/LinearMath/btList.h b/src/LinearMath/btList.h new file mode 100644 index 0000000..eec80a7 --- /dev/null +++ b/src/LinearMath/btList.h @@ -0,0 +1,73 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_GEN_LIST_H +#define BT_GEN_LIST_H + +class btGEN_Link { +public: + btGEN_Link() : m_next(0), m_prev(0) {} + btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {} + + btGEN_Link *getNext() const { return m_next; } + btGEN_Link *getPrev() const { return m_prev; } + + bool isHead() const { return m_prev == 0; } + bool isTail() const { return m_next == 0; } + + void insertBefore(btGEN_Link *link) { + m_next = link; + m_prev = link->m_prev; + m_next->m_prev = this; + m_prev->m_next = this; + } + + void insertAfter(btGEN_Link *link) { + m_next = link->m_next; + m_prev = link; + m_next->m_prev = this; + m_prev->m_next = this; + } + + void remove() { + m_next->m_prev = m_prev; + m_prev->m_next = m_next; + } + +private: + btGEN_Link *m_next; + btGEN_Link *m_prev; +}; + +class btGEN_List { +public: + btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {} + + btGEN_Link *getHead() const { return m_head.getNext(); } + btGEN_Link *getTail() const { return m_tail.getPrev(); } + + void addHead(btGEN_Link *link) { link->insertAfter(&m_head); } + void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); } + +private: + btGEN_Link m_head; + btGEN_Link m_tail; +}; + +#endif //BT_GEN_LIST_H + + + diff --git a/src/LinearMath/btMatrix3x3.h b/src/LinearMath/btMatrix3x3.h new file mode 100644 index 0000000..d4f5c95 --- /dev/null +++ b/src/LinearMath/btMatrix3x3.h @@ -0,0 +1,1362 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_MATRIX3x3_H +#define BT_MATRIX3x3_H + +#include "btVector3.h" +#include "btQuaternion.h" +#include + +#ifdef BT_USE_SSE +//const __m128 ATTRIBUTE_ALIGNED16(v2220) = {2.0f, 2.0f, 2.0f, 0.0f}; +const __m128 ATTRIBUTE_ALIGNED16(vMPPP) = {-0.0f, +0.0f, +0.0f, +0.0f}; +#endif + +#if defined(BT_USE_SSE) || defined(BT_USE_NEON) +const btSimdFloat4 ATTRIBUTE_ALIGNED16(v1000) = {1.0f, 0.0f, 0.0f, 0.0f}; +const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0100) = {0.0f, 1.0f, 0.0f, 0.0f}; +const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0010) = {0.0f, 0.0f, 1.0f, 0.0f}; +#endif + +#ifdef BT_USE_DOUBLE_PRECISION +#define btMatrix3x3Data btMatrix3x3DoubleData +#else +#define btMatrix3x3Data btMatrix3x3FloatData +#endif //BT_USE_DOUBLE_PRECISION + + +/**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3. +* Make sure to only include a pure orthogonal matrix without scaling. */ +ATTRIBUTE_ALIGNED16(class) btMatrix3x3 { + + ///Data storage for the matrix, each vector is a row of the matrix + btVector3 m_el[3]; + +public: + /** @brief No initializaion constructor */ + btMatrix3x3 () {} + + // explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); } + + /**@brief Constructor from Quaternion */ + explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); } + /* + template + Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + setEulerYPR(yaw, pitch, roll); + } + */ + /** @brief Constructor with row major formatting */ + btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz, + const btScalar& yx, const btScalar& yy, const btScalar& yz, + const btScalar& zx, const btScalar& zy, const btScalar& zz) + { + setValue(xx, xy, xz, + yx, yy, yz, + zx, zy, zz); + } + +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + SIMD_FORCE_INLINE btMatrix3x3 (const btSimdFloat4 v0, const btSimdFloat4 v1, const btSimdFloat4 v2 ) + { + m_el[0].mVec128 = v0; + m_el[1].mVec128 = v1; + m_el[2].mVec128 = v2; + } + + SIMD_FORCE_INLINE btMatrix3x3 (const btVector3& v0, const btVector3& v1, const btVector3& v2 ) + { + m_el[0] = v0; + m_el[1] = v1; + m_el[2] = v2; + } + + // Copy constructor + SIMD_FORCE_INLINE btMatrix3x3(const btMatrix3x3& rhs) + { + m_el[0].mVec128 = rhs.m_el[0].mVec128; + m_el[1].mVec128 = rhs.m_el[1].mVec128; + m_el[2].mVec128 = rhs.m_el[2].mVec128; + } + + // Assignment Operator + SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& m) + { + m_el[0].mVec128 = m.m_el[0].mVec128; + m_el[1].mVec128 = m.m_el[1].mVec128; + m_el[2].mVec128 = m.m_el[2].mVec128; + + return *this; + } + +#else + + /** @brief Copy constructor */ + SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other) + { + m_el[0] = other.m_el[0]; + m_el[1] = other.m_el[1]; + m_el[2] = other.m_el[2]; + } + + /** @brief Assignment Operator */ + SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other) + { + m_el[0] = other.m_el[0]; + m_el[1] = other.m_el[1]; + m_el[2] = other.m_el[2]; + return *this; + } + +#endif + + /** @brief Get a column of the matrix as a vector + * @param i Column number 0 indexed */ + SIMD_FORCE_INLINE btVector3 getColumn(int i) const + { + return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]); + } + + + /** @brief Get a row of the matrix as a vector + * @param i Row number 0 indexed */ + SIMD_FORCE_INLINE const btVector3& getRow(int i) const + { + btFullAssert(0 <= i && i < 3); + return m_el[i]; + } + + /** @brief Get a mutable reference to a row of the matrix as a vector + * @param i Row number 0 indexed */ + SIMD_FORCE_INLINE btVector3& operator[](int i) + { + btFullAssert(0 <= i && i < 3); + return m_el[i]; + } + + /** @brief Get a const reference to a row of the matrix as a vector + * @param i Row number 0 indexed */ + SIMD_FORCE_INLINE const btVector3& operator[](int i) const + { + btFullAssert(0 <= i && i < 3); + return m_el[i]; + } + + /** @brief Multiply by the target matrix on the right + * @param m Rotation matrix to be applied + * Equivilant to this = this * m */ + btMatrix3x3& operator*=(const btMatrix3x3& m); + + /** @brief Adds by the target matrix on the right + * @param m matrix to be applied + * Equivilant to this = this + m */ + btMatrix3x3& operator+=(const btMatrix3x3& m); + + /** @brief Substractss by the target matrix on the right + * @param m matrix to be applied + * Equivilant to this = this - m */ + btMatrix3x3& operator-=(const btMatrix3x3& m); + + /** @brief Set from the rotational part of a 4x4 OpenGL matrix + * @param m A pointer to the beginning of the array of scalars*/ + void setFromOpenGLSubMatrix(const btScalar *m) + { + m_el[0].setValue(m[0],m[4],m[8]); + m_el[1].setValue(m[1],m[5],m[9]); + m_el[2].setValue(m[2],m[6],m[10]); + + } + /** @brief Set the values of the matrix explicitly (row major) + * @param xx Top left + * @param xy Top Middle + * @param xz Top Right + * @param yx Middle Left + * @param yy Middle Middle + * @param yz Middle Right + * @param zx Bottom Left + * @param zy Bottom Middle + * @param zz Bottom Right*/ + void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, + const btScalar& yx, const btScalar& yy, const btScalar& yz, + const btScalar& zx, const btScalar& zy, const btScalar& zz) + { + m_el[0].setValue(xx,xy,xz); + m_el[1].setValue(yx,yy,yz); + m_el[2].setValue(zx,zy,zz); + } + + /** @brief Set the matrix from a quaternion + * @param q The Quaternion to match */ + void setRotation(const btQuaternion& q) + { + btScalar d = q.length2(); + btFullAssert(d != btScalar(0.0)); + btScalar s = btScalar(2.0) / d; + + #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vs, Q = q.get128(); + __m128i Qi = btCastfTo128i(Q); + __m128 Y, Z; + __m128 V1, V2, V3; + __m128 V11, V21, V31; + __m128 NQ = _mm_xor_ps(Q, btvMzeroMask); + __m128i NQi = btCastfTo128i(NQ); + + V1 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,0,2,3))); // Y X Z W + V2 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(0,0,1,3)); // -X -X Y W + V3 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(2,1,0,3))); // Z Y X W + V1 = _mm_xor_ps(V1, vMPPP); // change the sign of the first element + + V11 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,1,0,3))); // Y Y X W + V21 = _mm_unpackhi_ps(Q, Q); // Z Z W W + V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(0,2,0,3)); // X Z -X -W + + V2 = V2 * V1; // + V1 = V1 * V11; // + V3 = V3 * V31; // + + V11 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(2,3,1,3)); // -Z -W Y W + V11 = V11 * V21; // + V21 = _mm_xor_ps(V21, vMPPP); // change the sign of the first element + V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(3,3,1,3)); // W W -Y -W + V31 = _mm_xor_ps(V31, vMPPP); // change the sign of the first element + Y = btCastiTo128f(_mm_shuffle_epi32 (NQi, BT_SHUFFLE(3,2,0,3))); // -W -Z -X -W + Z = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,0,1,3))); // Y X Y W + + vs = _mm_load_ss(&s); + V21 = V21 * Y; + V31 = V31 * Z; + + V1 = V1 + V11; + V2 = V2 + V21; + V3 = V3 + V31; + + vs = bt_splat3_ps(vs, 0); + // s ready + V1 = V1 * vs; + V2 = V2 * vs; + V3 = V3 * vs; + + V1 = V1 + v1000; + V2 = V2 + v0100; + V3 = V3 + v0010; + + m_el[0] = V1; + m_el[1] = V2; + m_el[2] = V3; + #else + btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; + btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; + btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; + btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; + setValue( + btScalar(1.0) - (yy + zz), xy - wz, xz + wy, + xy + wz, btScalar(1.0) - (xx + zz), yz - wx, + xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); + #endif + } + + + /** @brief Set the matrix from euler angles using YPR around YXZ respectively + * @param yaw Yaw about Y axis + * @param pitch Pitch about X axis + * @param roll Roll about Z axis + */ + void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + setEulerZYX(roll, pitch, yaw); + } + + /** @brief Set the matrix from euler angles YPR around ZYX axes + * @param eulerX Roll about X axis + * @param eulerY Pitch around Y axis + * @param eulerZ Yaw aboud Z axis + * + * These angles are used to produce a rotation matrix. The euler + * angles are applied in ZYX order. I.e a vector is first rotated + * about X then Y and then Z + **/ + void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { + ///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code + btScalar ci ( btCos(eulerX)); + btScalar cj ( btCos(eulerY)); + btScalar ch ( btCos(eulerZ)); + btScalar si ( btSin(eulerX)); + btScalar sj ( btSin(eulerY)); + btScalar sh ( btSin(eulerZ)); + btScalar cc = ci * ch; + btScalar cs = ci * sh; + btScalar sc = si * ch; + btScalar ss = si * sh; + + setValue(cj * ch, sj * sc - cs, sj * cc + ss, + cj * sh, sj * ss + cc, sj * cs - sc, + -sj, cj * si, cj * ci); + } + + /**@brief Set the matrix to the identity */ + void setIdentity() + { +#if (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined(BT_USE_NEON) + m_el[0] = v1000; + m_el[1] = v0100; + m_el[2] = v0010; +#else + setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), + btScalar(0.0), btScalar(1.0), btScalar(0.0), + btScalar(0.0), btScalar(0.0), btScalar(1.0)); +#endif + } + + static const btMatrix3x3& getIdentity() + { +#if (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined(BT_USE_NEON) + static const btMatrix3x3 + identityMatrix(v1000, v0100, v0010); +#else + static const btMatrix3x3 + identityMatrix( + btScalar(1.0), btScalar(0.0), btScalar(0.0), + btScalar(0.0), btScalar(1.0), btScalar(0.0), + btScalar(0.0), btScalar(0.0), btScalar(1.0)); +#endif + return identityMatrix; + } + + /**@brief Fill the rotational part of an OpenGL matrix and clear the shear/perspective + * @param m The array to be filled */ + void getOpenGLSubMatrix(btScalar *m) const + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 v0 = m_el[0].mVec128; + __m128 v1 = m_el[1].mVec128; + __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 + __m128 *vm = (__m128 *)m; + __m128 vT; + + v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0 + + vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * + v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 + + v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0 + v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0 + v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0 + + vm[0] = v0; + vm[1] = v1; + vm[2] = v2; +#elif defined(BT_USE_NEON) + // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. + static const uint32x2_t zMask = (const uint32x2_t) {-1, 0 }; + float32x4_t *vm = (float32x4_t *)m; + float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1} + float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0} + float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] ); + float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] ); + float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask ); + float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0 + + vm[0] = v0; + vm[1] = v1; + vm[2] = v2; +#else + m[0] = btScalar(m_el[0].x()); + m[1] = btScalar(m_el[1].x()); + m[2] = btScalar(m_el[2].x()); + m[3] = btScalar(0.0); + m[4] = btScalar(m_el[0].y()); + m[5] = btScalar(m_el[1].y()); + m[6] = btScalar(m_el[2].y()); + m[7] = btScalar(0.0); + m[8] = btScalar(m_el[0].z()); + m[9] = btScalar(m_el[1].z()); + m[10] = btScalar(m_el[2].z()); + m[11] = btScalar(0.0); +#endif + } + + /**@brief Get the matrix represented as a quaternion + * @param q The quaternion which will be set */ + void getRotation(btQuaternion& q) const + { +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); + btScalar s, x; + + union { + btSimdFloat4 vec; + btScalar f[4]; + } temp; + + if (trace > btScalar(0.0)) + { + x = trace + btScalar(1.0); + + temp.f[0]=m_el[2].y() - m_el[1].z(); + temp.f[1]=m_el[0].z() - m_el[2].x(); + temp.f[2]=m_el[1].x() - m_el[0].y(); + temp.f[3]=x; + //temp.f[3]= s * btScalar(0.5); + } + else + { + int i, j, k; + if(m_el[0].x() < m_el[1].y()) + { + if( m_el[1].y() < m_el[2].z() ) + { i = 2; j = 0; k = 1; } + else + { i = 1; j = 2; k = 0; } + } + else + { + if( m_el[0].x() < m_el[2].z()) + { i = 2; j = 0; k = 1; } + else + { i = 0; j = 1; k = 2; } + } + + x = m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0); + + temp.f[3] = (m_el[k][j] - m_el[j][k]); + temp.f[j] = (m_el[j][i] + m_el[i][j]); + temp.f[k] = (m_el[k][i] + m_el[i][k]); + temp.f[i] = x; + //temp.f[i] = s * btScalar(0.5); + } + + s = btSqrt(x); + q.set128(temp.vec); + s = btScalar(0.5) / s; + + q *= s; +#else + btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); + + btScalar temp[4]; + + if (trace > btScalar(0.0)) + { + btScalar s = btSqrt(trace + btScalar(1.0)); + temp[3]=(s * btScalar(0.5)); + s = btScalar(0.5) / s; + + temp[0]=((m_el[2].y() - m_el[1].z()) * s); + temp[1]=((m_el[0].z() - m_el[2].x()) * s); + temp[2]=((m_el[1].x() - m_el[0].y()) * s); + } + else + { + int i = m_el[0].x() < m_el[1].y() ? + (m_el[1].y() < m_el[2].z() ? 2 : 1) : + (m_el[0].x() < m_el[2].z() ? 2 : 0); + int j = (i + 1) % 3; + int k = (i + 2) % 3; + + btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); + temp[i] = s * btScalar(0.5); + s = btScalar(0.5) / s; + + temp[3] = (m_el[k][j] - m_el[j][k]) * s; + temp[j] = (m_el[j][i] + m_el[i][j]) * s; + temp[k] = (m_el[k][i] + m_el[i][k]) * s; + } + q.setValue(temp[0],temp[1],temp[2],temp[3]); +#endif + } + + /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR + * @param yaw Yaw around Y axis + * @param pitch Pitch around X axis + * @param roll around Z axis */ + void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const + { + + // first use the normal calculus + yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); + pitch = btScalar(btAsin(-m_el[2].x())); + roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); + + // on pitch = +/-HalfPI + if (btFabs(pitch)==SIMD_HALF_PI) + { + if (yaw>0) + yaw-=SIMD_PI; + else + yaw+=SIMD_PI; + + if (roll>0) + roll-=SIMD_PI; + else + roll+=SIMD_PI; + } + }; + + + /**@brief Get the matrix represented as euler angles around ZYX + * @param yaw Yaw around X axis + * @param pitch Pitch around Y axis + * @param roll around X axis + * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/ + void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const + { + struct Euler + { + btScalar yaw; + btScalar pitch; + btScalar roll; + }; + + Euler euler_out; + Euler euler_out2; //second solution + //get the pointer to the raw data + + // Check that pitch is not at a singularity + if (btFabs(m_el[2].x()) >= 1) + { + euler_out.yaw = 0; + euler_out2.yaw = 0; + + // From difference of angles formula + btScalar delta = btAtan2(m_el[0].x(),m_el[0].z()); + if (m_el[2].x() > 0) //gimbal locked up + { + euler_out.pitch = SIMD_PI / btScalar(2.0); + euler_out2.pitch = SIMD_PI / btScalar(2.0); + euler_out.roll = euler_out.pitch + delta; + euler_out2.roll = euler_out.pitch + delta; + } + else // gimbal locked down + { + euler_out.pitch = -SIMD_PI / btScalar(2.0); + euler_out2.pitch = -SIMD_PI / btScalar(2.0); + euler_out.roll = -euler_out.pitch + delta; + euler_out2.roll = -euler_out.pitch + delta; + } + } + else + { + euler_out.pitch = - btAsin(m_el[2].x()); + euler_out2.pitch = SIMD_PI - euler_out.pitch; + + euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch), + m_el[2].z()/btCos(euler_out.pitch)); + euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch), + m_el[2].z()/btCos(euler_out2.pitch)); + + euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch), + m_el[0].x()/btCos(euler_out.pitch)); + euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch), + m_el[0].x()/btCos(euler_out2.pitch)); + } + + if (solution_number == 1) + { + yaw = euler_out.yaw; + pitch = euler_out.pitch; + roll = euler_out.roll; + } + else + { + yaw = euler_out2.yaw; + pitch = euler_out2.pitch; + roll = euler_out2.roll; + } + } + + /**@brief Create a scaled copy of the matrix + * @param s Scaling vector The elements of the vector will scale each column */ + + btMatrix3x3 scaled(const btVector3& s) const + { +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + return btMatrix3x3(m_el[0] * s, m_el[1] * s, m_el[2] * s); +#else + return btMatrix3x3( + m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(), + m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(), + m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z()); +#endif + } + + /**@brief Return the determinant of the matrix */ + btScalar determinant() const; + /**@brief Return the adjoint of the matrix */ + btMatrix3x3 adjoint() const; + /**@brief Return the matrix with all values non negative */ + btMatrix3x3 absolute() const; + /**@brief Return the transpose of the matrix */ + btMatrix3x3 transpose() const; + /**@brief Return the inverse of the matrix */ + btMatrix3x3 inverse() const; + + btMatrix3x3 transposeTimes(const btMatrix3x3& m) const; + btMatrix3x3 timesTranspose(const btMatrix3x3& m) const; + + SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const + { + return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z(); + } + SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const + { + return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z(); + } + SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const + { + return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z(); + } + + + /**@brief diagonalizes this matrix by the Jacobi method. + * @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original + * coordinate system, i.e., old_this = rot * new_this * rot^T. + * @param threshold See iteration + * @param iteration The iteration stops when all off-diagonal elements are less than the threshold multiplied + * by the sum of the absolute values of the diagonal, or when maxSteps have been executed. + * + * Note that this matrix is assumed to be symmetric. + */ + void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps) + { + rot.setIdentity(); + for (int step = maxSteps; step > 0; step--) + { + // find off-diagonal element [p][q] with largest magnitude + int p = 0; + int q = 1; + int r = 2; + btScalar max = btFabs(m_el[0][1]); + btScalar v = btFabs(m_el[0][2]); + if (v > max) + { + q = 2; + r = 1; + max = v; + } + v = btFabs(m_el[1][2]); + if (v > max) + { + p = 1; + q = 2; + r = 0; + max = v; + } + + btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2])); + if (max <= t) + { + if (max <= SIMD_EPSILON * t) + { + return; + } + step = 1; + } + + // compute Jacobi rotation J which leads to a zero for element [p][q] + btScalar mpq = m_el[p][q]; + btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq); + btScalar theta2 = theta * theta; + btScalar cos; + btScalar sin; + if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON)) + { + t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2)) + : 1 / (theta - btSqrt(1 + theta2)); + cos = 1 / btSqrt(1 + t * t); + sin = cos * t; + } + else + { + // approximation for large theta-value, i.e., a nearly diagonal matrix + t = 1 / (theta * (2 + btScalar(0.5) / theta2)); + cos = 1 - btScalar(0.5) * t * t; + sin = cos * t; + } + + // apply rotation to matrix (this = J^T * this * J) + m_el[p][q] = m_el[q][p] = 0; + m_el[p][p] -= t * mpq; + m_el[q][q] += t * mpq; + btScalar mrp = m_el[r][p]; + btScalar mrq = m_el[r][q]; + m_el[r][p] = m_el[p][r] = cos * mrp - sin * mrq; + m_el[r][q] = m_el[q][r] = cos * mrq + sin * mrp; + + // apply rotation to rot (rot = rot * J) + for (int i = 0; i < 3; i++) + { + btVector3& row = rot[i]; + mrp = row[p]; + mrq = row[q]; + row[p] = cos * mrp - sin * mrq; + row[q] = cos * mrq + sin * mrp; + } + } + } + + + + + /**@brief Calculate the matrix cofactor + * @param r1 The first row to use for calculating the cofactor + * @param c1 The first column to use for calculating the cofactor + * @param r1 The second row to use for calculating the cofactor + * @param c1 The second column to use for calculating the cofactor + * See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details + */ + btScalar cofac(int r1, int c1, int r2, int c2) const + { + return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1]; + } + + void serialize(struct btMatrix3x3Data& dataOut) const; + + void serializeFloat(struct btMatrix3x3FloatData& dataOut) const; + + void deSerialize(const struct btMatrix3x3Data& dataIn); + + void deSerializeFloat(const struct btMatrix3x3FloatData& dataIn); + + void deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn); + +}; + + +SIMD_FORCE_INLINE btMatrix3x3& +btMatrix3x3::operator*=(const btMatrix3x3& m) +{ +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 rv00, rv01, rv02; + __m128 rv10, rv11, rv12; + __m128 rv20, rv21, rv22; + __m128 mv0, mv1, mv2; + + rv02 = m_el[0].mVec128; + rv12 = m_el[1].mVec128; + rv22 = m_el[2].mVec128; + + mv0 = _mm_and_ps(m[0].mVec128, btvFFF0fMask); + mv1 = _mm_and_ps(m[1].mVec128, btvFFF0fMask); + mv2 = _mm_and_ps(m[2].mVec128, btvFFF0fMask); + + // rv0 + rv00 = bt_splat_ps(rv02, 0); + rv01 = bt_splat_ps(rv02, 1); + rv02 = bt_splat_ps(rv02, 2); + + rv00 = _mm_mul_ps(rv00, mv0); + rv01 = _mm_mul_ps(rv01, mv1); + rv02 = _mm_mul_ps(rv02, mv2); + + // rv1 + rv10 = bt_splat_ps(rv12, 0); + rv11 = bt_splat_ps(rv12, 1); + rv12 = bt_splat_ps(rv12, 2); + + rv10 = _mm_mul_ps(rv10, mv0); + rv11 = _mm_mul_ps(rv11, mv1); + rv12 = _mm_mul_ps(rv12, mv2); + + // rv2 + rv20 = bt_splat_ps(rv22, 0); + rv21 = bt_splat_ps(rv22, 1); + rv22 = bt_splat_ps(rv22, 2); + + rv20 = _mm_mul_ps(rv20, mv0); + rv21 = _mm_mul_ps(rv21, mv1); + rv22 = _mm_mul_ps(rv22, mv2); + + rv00 = _mm_add_ps(rv00, rv01); + rv10 = _mm_add_ps(rv10, rv11); + rv20 = _mm_add_ps(rv20, rv21); + + m_el[0].mVec128 = _mm_add_ps(rv00, rv02); + m_el[1].mVec128 = _mm_add_ps(rv10, rv12); + m_el[2].mVec128 = _mm_add_ps(rv20, rv22); + +#elif defined(BT_USE_NEON) + + float32x4_t rv0, rv1, rv2; + float32x4_t v0, v1, v2; + float32x4_t mv0, mv1, mv2; + + v0 = m_el[0].mVec128; + v1 = m_el[1].mVec128; + v2 = m_el[2].mVec128; + + mv0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask); + mv1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask); + mv2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask); + + rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); + rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); + rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); + + rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); + rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); + rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); + + rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); + rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); + rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + + m_el[0].mVec128 = rv0; + m_el[1].mVec128 = rv1; + m_el[2].mVec128 = rv2; +#else + setValue( + m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), + m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), + m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); +#endif + return *this; +} + +SIMD_FORCE_INLINE btMatrix3x3& +btMatrix3x3::operator+=(const btMatrix3x3& m) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + m_el[0].mVec128 = m_el[0].mVec128 + m.m_el[0].mVec128; + m_el[1].mVec128 = m_el[1].mVec128 + m.m_el[1].mVec128; + m_el[2].mVec128 = m_el[2].mVec128 + m.m_el[2].mVec128; +#else + setValue( + m_el[0][0]+m.m_el[0][0], + m_el[0][1]+m.m_el[0][1], + m_el[0][2]+m.m_el[0][2], + m_el[1][0]+m.m_el[1][0], + m_el[1][1]+m.m_el[1][1], + m_el[1][2]+m.m_el[1][2], + m_el[2][0]+m.m_el[2][0], + m_el[2][1]+m.m_el[2][1], + m_el[2][2]+m.m_el[2][2]); +#endif + return *this; +} + +SIMD_FORCE_INLINE btMatrix3x3 +operator*(const btMatrix3x3& m, const btScalar & k) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + __m128 vk = bt_splat_ps(_mm_load_ss((float *)&k), 0x80); + return btMatrix3x3( + _mm_mul_ps(m[0].mVec128, vk), + _mm_mul_ps(m[1].mVec128, vk), + _mm_mul_ps(m[2].mVec128, vk)); +#elif defined(BT_USE_NEON) + return btMatrix3x3( + vmulq_n_f32(m[0].mVec128, k), + vmulq_n_f32(m[1].mVec128, k), + vmulq_n_f32(m[2].mVec128, k)); +#else + return btMatrix3x3( + m[0].x()*k,m[0].y()*k,m[0].z()*k, + m[1].x()*k,m[1].y()*k,m[1].z()*k, + m[2].x()*k,m[2].y()*k,m[2].z()*k); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3 +operator+(const btMatrix3x3& m1, const btMatrix3x3& m2) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + return btMatrix3x3( + m1[0].mVec128 + m2[0].mVec128, + m1[1].mVec128 + m2[1].mVec128, + m1[2].mVec128 + m2[2].mVec128); +#else + return btMatrix3x3( + m1[0][0]+m2[0][0], + m1[0][1]+m2[0][1], + m1[0][2]+m2[0][2], + + m1[1][0]+m2[1][0], + m1[1][1]+m2[1][1], + m1[1][2]+m2[1][2], + + m1[2][0]+m2[2][0], + m1[2][1]+m2[2][1], + m1[2][2]+m2[2][2]); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3 +operator-(const btMatrix3x3& m1, const btMatrix3x3& m2) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + return btMatrix3x3( + m1[0].mVec128 - m2[0].mVec128, + m1[1].mVec128 - m2[1].mVec128, + m1[2].mVec128 - m2[2].mVec128); +#else + return btMatrix3x3( + m1[0][0]-m2[0][0], + m1[0][1]-m2[0][1], + m1[0][2]-m2[0][2], + + m1[1][0]-m2[1][0], + m1[1][1]-m2[1][1], + m1[1][2]-m2[1][2], + + m1[2][0]-m2[2][0], + m1[2][1]-m2[2][1], + m1[2][2]-m2[2][2]); +#endif +} + + +SIMD_FORCE_INLINE btMatrix3x3& +btMatrix3x3::operator-=(const btMatrix3x3& m) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + m_el[0].mVec128 = m_el[0].mVec128 - m.m_el[0].mVec128; + m_el[1].mVec128 = m_el[1].mVec128 - m.m_el[1].mVec128; + m_el[2].mVec128 = m_el[2].mVec128 - m.m_el[2].mVec128; +#else + setValue( + m_el[0][0]-m.m_el[0][0], + m_el[0][1]-m.m_el[0][1], + m_el[0][2]-m.m_el[0][2], + m_el[1][0]-m.m_el[1][0], + m_el[1][1]-m.m_el[1][1], + m_el[1][2]-m.m_el[1][2], + m_el[2][0]-m.m_el[2][0], + m_el[2][1]-m.m_el[2][1], + m_el[2][2]-m.m_el[2][2]); +#endif + return *this; +} + + +SIMD_FORCE_INLINE btScalar +btMatrix3x3::determinant() const +{ + return btTriple((*this)[0], (*this)[1], (*this)[2]); +} + + +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::absolute() const +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + return btMatrix3x3( + _mm_and_ps(m_el[0].mVec128, btvAbsfMask), + _mm_and_ps(m_el[1].mVec128, btvAbsfMask), + _mm_and_ps(m_el[2].mVec128, btvAbsfMask)); +#elif defined(BT_USE_NEON) + return btMatrix3x3( + (float32x4_t)vandq_s32((int32x4_t)m_el[0].mVec128, btv3AbsMask), + (float32x4_t)vandq_s32((int32x4_t)m_el[1].mVec128, btv3AbsMask), + (float32x4_t)vandq_s32((int32x4_t)m_el[2].mVec128, btv3AbsMask)); +#else + return btMatrix3x3( + btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()), + btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()), + btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z())); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::transpose() const +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + __m128 v0 = m_el[0].mVec128; + __m128 v1 = m_el[1].mVec128; + __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 + __m128 vT; + + v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0 + + vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * + v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 + + v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0 + v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0 + v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0 + + + return btMatrix3x3( v0, v1, v2 ); +#elif defined(BT_USE_NEON) + // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. + static const uint32x2_t zMask = (const uint32x2_t) {-1, 0 }; + float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1} + float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0} + float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] ); + float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] ); + float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask ); + float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0 + return btMatrix3x3( v0, v1, v2 ); +#else + return btMatrix3x3( m_el[0].x(), m_el[1].x(), m_el[2].x(), + m_el[0].y(), m_el[1].y(), m_el[2].y(), + m_el[0].z(), m_el[1].z(), m_el[2].z()); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::adjoint() const +{ + return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2), + cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), + cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); +} + +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::inverse() const +{ + btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)); + btScalar det = (*this)[0].dot(co); + btFullAssert(det != btScalar(0.0)); + btScalar s = btScalar(1.0) / det; + return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, + co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, + co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); +} + +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::transposeTimes(const btMatrix3x3& m) const +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + // zeros w +// static const __m128i xyzMask = (const __m128i){ -1ULL, 0xffffffffULL }; + __m128 row = m_el[0].mVec128; + __m128 m0 = _mm_and_ps( m.getRow(0).mVec128, btvFFF0fMask ); + __m128 m1 = _mm_and_ps( m.getRow(1).mVec128, btvFFF0fMask); + __m128 m2 = _mm_and_ps( m.getRow(2).mVec128, btvFFF0fMask ); + __m128 r0 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0)); + __m128 r1 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0x55)); + __m128 r2 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0xaa)); + row = m_el[1].mVec128; + r0 = _mm_add_ps( r0, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0))); + r1 = _mm_add_ps( r1, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0x55))); + r2 = _mm_add_ps( r2, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0xaa))); + row = m_el[2].mVec128; + r0 = _mm_add_ps( r0, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0))); + r1 = _mm_add_ps( r1, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0x55))); + r2 = _mm_add_ps( r2, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0xaa))); + return btMatrix3x3( r0, r1, r2 ); + +#elif defined BT_USE_NEON + // zeros w + static const uint32x4_t xyzMask = (const uint32x4_t){ -1, -1, -1, 0 }; + float32x4_t m0 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(0).mVec128, xyzMask ); + float32x4_t m1 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(1).mVec128, xyzMask ); + float32x4_t m2 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(2).mVec128, xyzMask ); + float32x4_t row = m_el[0].mVec128; + float32x4_t r0 = vmulq_lane_f32( m0, vget_low_f32(row), 0); + float32x4_t r1 = vmulq_lane_f32( m0, vget_low_f32(row), 1); + float32x4_t r2 = vmulq_lane_f32( m0, vget_high_f32(row), 0); + row = m_el[1].mVec128; + r0 = vmlaq_lane_f32( r0, m1, vget_low_f32(row), 0); + r1 = vmlaq_lane_f32( r1, m1, vget_low_f32(row), 1); + r2 = vmlaq_lane_f32( r2, m1, vget_high_f32(row), 0); + row = m_el[2].mVec128; + r0 = vmlaq_lane_f32( r0, m2, vget_low_f32(row), 0); + r1 = vmlaq_lane_f32( r1, m2, vget_low_f32(row), 1); + r2 = vmlaq_lane_f32( r2, m2, vget_high_f32(row), 0); + return btMatrix3x3( r0, r1, r2 ); +#else + return btMatrix3x3( + m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), + m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), + m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), + m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(), + m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(), + m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), + m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), + m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), + m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z()); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::timesTranspose(const btMatrix3x3& m) const +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + __m128 a0 = m_el[0].mVec128; + __m128 a1 = m_el[1].mVec128; + __m128 a2 = m_el[2].mVec128; + + btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here + __m128 mx = mT[0].mVec128; + __m128 my = mT[1].mVec128; + __m128 mz = mT[2].mVec128; + + __m128 r0 = _mm_mul_ps(mx, _mm_shuffle_ps(a0, a0, 0x00)); + __m128 r1 = _mm_mul_ps(mx, _mm_shuffle_ps(a1, a1, 0x00)); + __m128 r2 = _mm_mul_ps(mx, _mm_shuffle_ps(a2, a2, 0x00)); + r0 = _mm_add_ps(r0, _mm_mul_ps(my, _mm_shuffle_ps(a0, a0, 0x55))); + r1 = _mm_add_ps(r1, _mm_mul_ps(my, _mm_shuffle_ps(a1, a1, 0x55))); + r2 = _mm_add_ps(r2, _mm_mul_ps(my, _mm_shuffle_ps(a2, a2, 0x55))); + r0 = _mm_add_ps(r0, _mm_mul_ps(mz, _mm_shuffle_ps(a0, a0, 0xaa))); + r1 = _mm_add_ps(r1, _mm_mul_ps(mz, _mm_shuffle_ps(a1, a1, 0xaa))); + r2 = _mm_add_ps(r2, _mm_mul_ps(mz, _mm_shuffle_ps(a2, a2, 0xaa))); + return btMatrix3x3( r0, r1, r2); + +#elif defined BT_USE_NEON + float32x4_t a0 = m_el[0].mVec128; + float32x4_t a1 = m_el[1].mVec128; + float32x4_t a2 = m_el[2].mVec128; + + btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here + float32x4_t mx = mT[0].mVec128; + float32x4_t my = mT[1].mVec128; + float32x4_t mz = mT[2].mVec128; + + float32x4_t r0 = vmulq_lane_f32( mx, vget_low_f32(a0), 0); + float32x4_t r1 = vmulq_lane_f32( mx, vget_low_f32(a1), 0); + float32x4_t r2 = vmulq_lane_f32( mx, vget_low_f32(a2), 0); + r0 = vmlaq_lane_f32( r0, my, vget_low_f32(a0), 1); + r1 = vmlaq_lane_f32( r1, my, vget_low_f32(a1), 1); + r2 = vmlaq_lane_f32( r2, my, vget_low_f32(a2), 1); + r0 = vmlaq_lane_f32( r0, mz, vget_high_f32(a0), 0); + r1 = vmlaq_lane_f32( r1, mz, vget_high_f32(a1), 0); + r2 = vmlaq_lane_f32( r2, mz, vget_high_f32(a2), 0); + return btMatrix3x3( r0, r1, r2 ); + +#else + return btMatrix3x3( + m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), + m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]), + m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2])); +#endif +} + +SIMD_FORCE_INLINE btVector3 +operator*(const btMatrix3x3& m, const btVector3& v) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) + return v.dot3(m[0], m[1], m[2]); +#else + return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); +#endif +} + + +SIMD_FORCE_INLINE btVector3 +operator*(const btVector3& v, const btMatrix3x3& m) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + + const __m128 vv = v.mVec128; + + __m128 c0 = bt_splat_ps( vv, 0); + __m128 c1 = bt_splat_ps( vv, 1); + __m128 c2 = bt_splat_ps( vv, 2); + + c0 = _mm_mul_ps(c0, _mm_and_ps(m[0].mVec128, btvFFF0fMask) ); + c1 = _mm_mul_ps(c1, _mm_and_ps(m[1].mVec128, btvFFF0fMask) ); + c0 = _mm_add_ps(c0, c1); + c2 = _mm_mul_ps(c2, _mm_and_ps(m[2].mVec128, btvFFF0fMask) ); + + return btVector3(_mm_add_ps(c0, c2)); +#elif defined(BT_USE_NEON) + const float32x4_t vv = v.mVec128; + const float32x2_t vlo = vget_low_f32(vv); + const float32x2_t vhi = vget_high_f32(vv); + + float32x4_t c0, c1, c2; + + c0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask); + c1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask); + c2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask); + + c0 = vmulq_lane_f32(c0, vlo, 0); + c1 = vmulq_lane_f32(c1, vlo, 1); + c2 = vmulq_lane_f32(c2, vhi, 0); + c0 = vaddq_f32(c0, c1); + c0 = vaddq_f32(c0, c2); + + return btVector3(c0); +#else + return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3 +operator*(const btMatrix3x3& m1, const btMatrix3x3& m2) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + + __m128 m10 = m1[0].mVec128; + __m128 m11 = m1[1].mVec128; + __m128 m12 = m1[2].mVec128; + + __m128 m2v = _mm_and_ps(m2[0].mVec128, btvFFF0fMask); + + __m128 c0 = bt_splat_ps( m10, 0); + __m128 c1 = bt_splat_ps( m11, 0); + __m128 c2 = bt_splat_ps( m12, 0); + + c0 = _mm_mul_ps(c0, m2v); + c1 = _mm_mul_ps(c1, m2v); + c2 = _mm_mul_ps(c2, m2v); + + m2v = _mm_and_ps(m2[1].mVec128, btvFFF0fMask); + + __m128 c0_1 = bt_splat_ps( m10, 1); + __m128 c1_1 = bt_splat_ps( m11, 1); + __m128 c2_1 = bt_splat_ps( m12, 1); + + c0_1 = _mm_mul_ps(c0_1, m2v); + c1_1 = _mm_mul_ps(c1_1, m2v); + c2_1 = _mm_mul_ps(c2_1, m2v); + + m2v = _mm_and_ps(m2[2].mVec128, btvFFF0fMask); + + c0 = _mm_add_ps(c0, c0_1); + c1 = _mm_add_ps(c1, c1_1); + c2 = _mm_add_ps(c2, c2_1); + + m10 = bt_splat_ps( m10, 2); + m11 = bt_splat_ps( m11, 2); + m12 = bt_splat_ps( m12, 2); + + m10 = _mm_mul_ps(m10, m2v); + m11 = _mm_mul_ps(m11, m2v); + m12 = _mm_mul_ps(m12, m2v); + + c0 = _mm_add_ps(c0, m10); + c1 = _mm_add_ps(c1, m11); + c2 = _mm_add_ps(c2, m12); + + return btMatrix3x3(c0, c1, c2); + +#elif defined(BT_USE_NEON) + + float32x4_t rv0, rv1, rv2; + float32x4_t v0, v1, v2; + float32x4_t mv0, mv1, mv2; + + v0 = m1[0].mVec128; + v1 = m1[1].mVec128; + v2 = m1[2].mVec128; + + mv0 = (float32x4_t) vandq_s32((int32x4_t)m2[0].mVec128, btvFFF0Mask); + mv1 = (float32x4_t) vandq_s32((int32x4_t)m2[1].mVec128, btvFFF0Mask); + mv2 = (float32x4_t) vandq_s32((int32x4_t)m2[2].mVec128, btvFFF0Mask); + + rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); + rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); + rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); + + rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); + rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); + rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); + + rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); + rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); + rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + + return btMatrix3x3(rv0, rv1, rv2); + +#else + return btMatrix3x3( + m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]), + m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]), + m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2])); +#endif +} + +/* +SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) { +return btMatrix3x3( +m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0], +m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1], +m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2], +m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0], +m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1], +m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2], +m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0], +m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1], +m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); +} +*/ + +/**@brief Equality operator between two matrices +* It will test all elements are equal. */ +SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2) +{ +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + + __m128 c0, c1, c2; + + c0 = _mm_cmpeq_ps(m1[0].mVec128, m2[0].mVec128); + c1 = _mm_cmpeq_ps(m1[1].mVec128, m2[1].mVec128); + c2 = _mm_cmpeq_ps(m1[2].mVec128, m2[2].mVec128); + + c0 = _mm_and_ps(c0, c1); + c0 = _mm_and_ps(c0, c2); + + return (0x7 == _mm_movemask_ps((__m128)c0)); +#else + return + ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] && + m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] && + m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] ); +#endif +} + +///for serialization +struct btMatrix3x3FloatData +{ + btVector3FloatData m_el[3]; +}; + +///for serialization +struct btMatrix3x3DoubleData +{ + btVector3DoubleData m_el[3]; +}; + + + + +SIMD_FORCE_INLINE void btMatrix3x3::serialize(struct btMatrix3x3Data& dataOut) const +{ + for (int i=0;i<3;i++) + m_el[i].serialize(dataOut.m_el[i]); +} + +SIMD_FORCE_INLINE void btMatrix3x3::serializeFloat(struct btMatrix3x3FloatData& dataOut) const +{ + for (int i=0;i<3;i++) + m_el[i].serializeFloat(dataOut.m_el[i]); +} + + +SIMD_FORCE_INLINE void btMatrix3x3::deSerialize(const struct btMatrix3x3Data& dataIn) +{ + for (int i=0;i<3;i++) + m_el[i].deSerialize(dataIn.m_el[i]); +} + +SIMD_FORCE_INLINE void btMatrix3x3::deSerializeFloat(const struct btMatrix3x3FloatData& dataIn) +{ + for (int i=0;i<3;i++) + m_el[i].deSerializeFloat(dataIn.m_el[i]); +} + +SIMD_FORCE_INLINE void btMatrix3x3::deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn) +{ + for (int i=0;i<3;i++) + m_el[i].deSerializeDouble(dataIn.m_el[i]); +} + +#endif //BT_MATRIX3x3_H + diff --git a/src/LinearMath/btMinMax.h b/src/LinearMath/btMinMax.h new file mode 100644 index 0000000..5b436e9 --- /dev/null +++ b/src/LinearMath/btMinMax.h @@ -0,0 +1,71 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_GEN_MINMAX_H +#define BT_GEN_MINMAX_H + +#include "btScalar.h" + +template +SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) +{ + return a < b ? a : b ; +} + +template +SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) +{ + return a > b ? a : b; +} + +template +SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub) +{ + return a < lb ? lb : (ub < a ? ub : a); +} + +template +SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) +{ + if (b < a) + { + a = b; + } +} + +template +SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) +{ + if (a < b) + { + a = b; + } +} + +template +SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub) +{ + if (a < lb) + { + a = lb; + } + else if (ub < a) + { + a = ub; + } +} + +#endif //BT_GEN_MINMAX_H diff --git a/src/LinearMath/btMotionState.h b/src/LinearMath/btMotionState.h new file mode 100644 index 0000000..9431814 --- /dev/null +++ b/src/LinearMath/btMotionState.h @@ -0,0 +1,40 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_MOTIONSTATE_H +#define BT_MOTIONSTATE_H + +#include "btTransform.h" + +///The btMotionState interface class allows the dynamics world to synchronize and interpolate the updated world transforms with graphics +///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation) +class btMotionState +{ + public: + + virtual ~btMotionState() + { + + } + + virtual void getWorldTransform(btTransform& worldTrans ) const =0; + + //Bullet only calls the update of worldtransform for active objects + virtual void setWorldTransform(const btTransform& worldTrans)=0; + + +}; + +#endif //BT_MOTIONSTATE_H diff --git a/src/LinearMath/btPolarDecomposition.cpp b/src/LinearMath/btPolarDecomposition.cpp new file mode 100644 index 0000000..d7de204 --- /dev/null +++ b/src/LinearMath/btPolarDecomposition.cpp @@ -0,0 +1,99 @@ +#include "btPolarDecomposition.h" +#include "btMinMax.h" + +namespace +{ + btScalar abs_column_sum(const btMatrix3x3& a, int i) + { + return btFabs(a[0][i]) + btFabs(a[1][i]) + btFabs(a[2][i]); + } + + btScalar abs_row_sum(const btMatrix3x3& a, int i) + { + return btFabs(a[i][0]) + btFabs(a[i][1]) + btFabs(a[i][2]); + } + + btScalar p1_norm(const btMatrix3x3& a) + { + const btScalar sum0 = abs_column_sum(a,0); + const btScalar sum1 = abs_column_sum(a,1); + const btScalar sum2 = abs_column_sum(a,2); + return btMax(btMax(sum0, sum1), sum2); + } + + btScalar pinf_norm(const btMatrix3x3& a) + { + const btScalar sum0 = abs_row_sum(a,0); + const btScalar sum1 = abs_row_sum(a,1); + const btScalar sum2 = abs_row_sum(a,2); + return btMax(btMax(sum0, sum1), sum2); + } +} + +const btScalar btPolarDecomposition::DEFAULT_TOLERANCE = btScalar(0.0001); +const unsigned int btPolarDecomposition::DEFAULT_MAX_ITERATIONS = 16; + +btPolarDecomposition::btPolarDecomposition(btScalar tolerance, unsigned int maxIterations) +: m_tolerance(tolerance) +, m_maxIterations(maxIterations) +{ +} + +unsigned int btPolarDecomposition::decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const +{ + // Use the 'u' and 'h' matrices for intermediate calculations + u = a; + h = a.inverse(); + + for (unsigned int i = 0; i < m_maxIterations; ++i) + { + const btScalar h_1 = p1_norm(h); + const btScalar h_inf = pinf_norm(h); + const btScalar u_1 = p1_norm(u); + const btScalar u_inf = pinf_norm(u); + + const btScalar h_norm = h_1 * h_inf; + const btScalar u_norm = u_1 * u_inf; + + // The matrix is effectively singular so we cannot invert it + if (btFuzzyZero(h_norm) || btFuzzyZero(u_norm)) + break; + + const btScalar gamma = btPow(h_norm / u_norm, 0.25f); + const btScalar inv_gamma = 1.0 / gamma; + + // Determine the delta to 'u' + const btMatrix3x3 delta = (u * (gamma - 2.0) + h.transpose() * inv_gamma) * 0.5; + + // Update the matrices + u += delta; + h = u.inverse(); + + // Check for convergence + if (p1_norm(delta) <= m_tolerance * u_1) + { + h = u.transpose() * a; + h = (h + h.transpose()) * 0.5; + return i; + } + } + + // The algorithm has failed to converge to the specified tolerance, but we + // want to make sure that the matrices returned are in the right form. + h = u.transpose() * a; + h = (h + h.transpose()) * 0.5; + + return m_maxIterations; +} + +unsigned int btPolarDecomposition::maxIterations() const +{ + return m_maxIterations; +} + +unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) +{ + static btPolarDecomposition polar; + return polar.decompose(a, u, h); +} + diff --git a/src/LinearMath/btPolarDecomposition.h b/src/LinearMath/btPolarDecomposition.h new file mode 100644 index 0000000..5615667 --- /dev/null +++ b/src/LinearMath/btPolarDecomposition.h @@ -0,0 +1,73 @@ +#ifndef POLARDECOMPOSITION_H +#define POLARDECOMPOSITION_H + +#include "btMatrix3x3.h" + +/** + * This class is used to compute the polar decomposition of a matrix. In + * general, the polar decomposition factorizes a matrix, A, into two parts: a + * unitary matrix (U) and a positive, semi-definite Hermitian matrix (H). + * However, in this particular implementation the original matrix, A, is + * required to be a square 3x3 matrix with real elements. This means that U will + * be an orthogonal matrix and H with be a positive-definite, symmetric matrix. + */ +class btPolarDecomposition +{ + public: + static const btScalar DEFAULT_TOLERANCE; + static const unsigned int DEFAULT_MAX_ITERATIONS; + + /** + * Creates an instance with optional parameters. + * + * @param tolerance - the tolerance used to determine convergence of the + * algorithm + * @param maxIterations - the maximum number of iterations used to achieve + * convergence + */ + btPolarDecomposition(btScalar tolerance = DEFAULT_TOLERANCE, + unsigned int maxIterations = DEFAULT_MAX_ITERATIONS); + + /** + * Decomposes a matrix into orthogonal and symmetric, positive-definite + * parts. If the number of iterations returned by this function is equal to + * the maximum number of iterations, the algorithm has failed to converge. + * + * @param a - the original matrix + * @param u - the resulting orthogonal matrix + * @param h - the resulting symmetric matrix + * + * @return the number of iterations performed by the algorithm. + */ + unsigned int decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const; + + /** + * Returns the maximum number of iterations that this algorithm will perform + * to achieve convergence. + * + * @return maximum number of iterations + */ + unsigned int maxIterations() const; + + private: + btScalar m_tolerance; + unsigned int m_maxIterations; +}; + +/** + * This functions decomposes the matrix 'a' into two parts: an orthogonal matrix + * 'u' and a symmetric, positive-definite matrix 'h'. If the number of + * iterations returned by this function is equal to + * btPolarDecomposition::DEFAULT_MAX_ITERATIONS, the algorithm has failed to + * converge. + * + * @param a - the original matrix + * @param u - the resulting orthogonal matrix + * @param h - the resulting symmetric matrix + * + * @return the number of iterations performed by the algorithm. + */ +unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h); + +#endif // POLARDECOMPOSITION_H + diff --git a/src/LinearMath/btPoolAllocator.h b/src/LinearMath/btPoolAllocator.h new file mode 100755 index 0000000..ef20845 --- /dev/null +++ b/src/LinearMath/btPoolAllocator.h @@ -0,0 +1,121 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef _BT_POOL_ALLOCATOR_H +#define _BT_POOL_ALLOCATOR_H + +#include "btScalar.h" +#include "btAlignedAllocator.h" + +///The btPoolAllocator class allows to efficiently allocate a large pool of objects, instead of dynamically allocating them separately. +class btPoolAllocator +{ + int m_elemSize; + int m_maxElements; + int m_freeCount; + void* m_firstFree; + unsigned char* m_pool; + +public: + + btPoolAllocator(int elemSize, int maxElements) + :m_elemSize(elemSize), + m_maxElements(maxElements) + { + m_pool = (unsigned char*) btAlignedAlloc( static_cast(m_elemSize*m_maxElements),16); + + unsigned char* p = m_pool; + m_firstFree = p; + m_freeCount = m_maxElements; + int count = m_maxElements; + while (--count) { + *(void**)p = (p + m_elemSize); + p += m_elemSize; + } + *(void**)p = 0; + } + + ~btPoolAllocator() + { + btAlignedFree( m_pool); + } + + int getFreeCount() const + { + return m_freeCount; + } + + int getUsedCount() const + { + return m_maxElements - m_freeCount; + } + + int getMaxCount() const + { + return m_maxElements; + } + + void* allocate(int size) + { + // release mode fix + (void)size; + btAssert(!size || size<=m_elemSize); + btAssert(m_freeCount>0); + void* result = m_firstFree; + m_firstFree = *(void**)m_firstFree; + --m_freeCount; + return result; + } + + bool validPtr(void* ptr) + { + if (ptr) { + if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize)) + { + return true; + } + } + return false; + } + + void freeMemory(void* ptr) + { + if (ptr) { + btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize); + + *(void**)ptr = m_firstFree; + m_firstFree = ptr; + ++m_freeCount; + } + } + + int getElementSize() const + { + return m_elemSize; + } + + unsigned char* getPoolAddress() + { + return m_pool; + } + + const unsigned char* getPoolAddress() const + { + return m_pool; + } + +}; + +#endif //_BT_POOL_ALLOCATOR_H diff --git a/src/LinearMath/btQuadWord.h b/src/LinearMath/btQuadWord.h new file mode 100644 index 0000000..11067ef --- /dev/null +++ b/src/LinearMath/btQuadWord.h @@ -0,0 +1,244 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_SIMD_QUADWORD_H +#define BT_SIMD_QUADWORD_H + +#include "btScalar.h" +#include "btMinMax.h" + + + + + +#if defined (__CELLOS_LV2) && defined (__SPU__) +#include +#endif + +/**@brief The btQuadWord class is base class for btVector3 and btQuaternion. + * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. + */ +#ifndef USE_LIBSPE2 +ATTRIBUTE_ALIGNED16(class) btQuadWord +#else +class btQuadWord +#endif +{ +protected: + +#if defined (__SPU__) && defined (__CELLOS_LV2__) + union { + vec_float4 mVec128; + btScalar m_floats[4]; + }; +public: + vec_float4 get128() const + { + return mVec128; + } +protected: +#else //__CELLOS_LV2__ __SPU__ + +#if defined(BT_USE_SSE) || defined(BT_USE_NEON) + union { + btSimdFloat4 mVec128; + btScalar m_floats[4]; + }; +public: + SIMD_FORCE_INLINE btSimdFloat4 get128() const + { + return mVec128; + } + SIMD_FORCE_INLINE void set128(btSimdFloat4 v128) + { + mVec128 = v128; + } +#else + btScalar m_floats[4]; +#endif // BT_USE_SSE + +#endif //__CELLOS_LV2__ __SPU__ + + public: + +#if defined(BT_USE_SSE) || defined(BT_USE_NEON) + + // Set Vector + SIMD_FORCE_INLINE btQuadWord(const btSimdFloat4 vec) + { + mVec128 = vec; + } + + // Copy constructor + SIMD_FORCE_INLINE btQuadWord(const btQuadWord& rhs) + { + mVec128 = rhs.mVec128; + } + + // Assignment Operator + SIMD_FORCE_INLINE btQuadWord& + operator=(const btQuadWord& v) + { + mVec128 = v.mVec128; + + return *this; + } + +#endif + + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } + /**@brief Set the x value */ + SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x;}; + /**@brief Set the y value */ + SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y;}; + /**@brief Set the z value */ + SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z;}; + /**@brief Set the w value */ + SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w;}; + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } + /**@brief Return the w value */ + SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } + + //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } + //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } + ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. + SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; } + SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; } + + SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const + { +#ifdef BT_USE_SSE + return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); +#else + return ((m_floats[3]==other.m_floats[3]) && + (m_floats[2]==other.m_floats[2]) && + (m_floats[1]==other.m_floats[1]) && + (m_floats[0]==other.m_floats[0])); +#endif + } + + SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const + { + return !(*this == other); + } + + /**@brief Set x,y,z and zero w + * @param x Value of x + * @param y Value of y + * @param z Value of z + */ + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z) + { + m_floats[0]=_x; + m_floats[1]=_y; + m_floats[2]=_z; + m_floats[3] = 0.f; + } + +/* void getValue(btScalar *m) const + { + m[0] = m_floats[0]; + m[1] = m_floats[1]; + m[2] = m_floats[2]; + } +*/ +/**@brief Set the values + * @param x Value of x + * @param y Value of y + * @param z Value of z + * @param w Value of w + */ + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) + { + m_floats[0]=_x; + m_floats[1]=_y; + m_floats[2]=_z; + m_floats[3]=_w; + } + /**@brief No initialization constructor */ + SIMD_FORCE_INLINE btQuadWord() + // :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.)) + { + } + + /**@brief Three argument constructor (zeros w) + * @param x Value of x + * @param y Value of y + * @param z Value of z + */ + SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z) + { + m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f; + } + +/**@brief Initializing constructor + * @param x Value of x + * @param y Value of y + * @param z Value of z + * @param w Value of w + */ + SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) + { + m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w; + } + + /**@brief Set each element to the max of the current values and the values of another btQuadWord + * @param other The other btQuadWord to compare with + */ + SIMD_FORCE_INLINE void setMax(const btQuadWord& other) + { + #ifdef BT_USE_SSE + mVec128 = _mm_max_ps(mVec128, other.mVec128); + #elif defined(BT_USE_NEON) + mVec128 = vmaxq_f32(mVec128, other.mVec128); + #else + btSetMax(m_floats[0], other.m_floats[0]); + btSetMax(m_floats[1], other.m_floats[1]); + btSetMax(m_floats[2], other.m_floats[2]); + btSetMax(m_floats[3], other.m_floats[3]); + #endif + } + /**@brief Set each element to the min of the current values and the values of another btQuadWord + * @param other The other btQuadWord to compare with + */ + SIMD_FORCE_INLINE void setMin(const btQuadWord& other) + { + #ifdef BT_USE_SSE + mVec128 = _mm_min_ps(mVec128, other.mVec128); + #elif defined(BT_USE_NEON) + mVec128 = vminq_f32(mVec128, other.mVec128); + #else + btSetMin(m_floats[0], other.m_floats[0]); + btSetMin(m_floats[1], other.m_floats[1]); + btSetMin(m_floats[2], other.m_floats[2]); + btSetMin(m_floats[3], other.m_floats[3]); + #endif + } + + + +}; + +#endif //BT_SIMD_QUADWORD_H diff --git a/src/LinearMath/btQuaternion.h b/src/LinearMath/btQuaternion.h new file mode 100644 index 0000000..a1db819 --- /dev/null +++ b/src/LinearMath/btQuaternion.h @@ -0,0 +1,877 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_SIMD__QUATERNION_H_ +#define BT_SIMD__QUATERNION_H_ + + +#include "btVector3.h" +#include "btQuadWord.h" + + + + + +#ifdef BT_USE_SSE + +const __m128 ATTRIBUTE_ALIGNED16(vOnes) = {1.0f, 1.0f, 1.0f, 1.0f}; + +#endif + +#if defined(BT_USE_SSE) || defined(BT_USE_NEON) + +const btSimdFloat4 ATTRIBUTE_ALIGNED16(vQInv) = {-0.0f, -0.0f, -0.0f, +0.0f}; +const btSimdFloat4 ATTRIBUTE_ALIGNED16(vPPPM) = {+0.0f, +0.0f, +0.0f, -0.0f}; + +#endif + +/**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */ +class btQuaternion : public btQuadWord { +public: + /**@brief No initialization constructor */ + btQuaternion() {} + +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE))|| defined(BT_USE_NEON) + // Set Vector + SIMD_FORCE_INLINE btQuaternion(const btSimdFloat4 vec) + { + mVec128 = vec; + } + + // Copy constructor + SIMD_FORCE_INLINE btQuaternion(const btQuaternion& rhs) + { + mVec128 = rhs.mVec128; + } + + // Assignment Operator + SIMD_FORCE_INLINE btQuaternion& + operator=(const btQuaternion& v) + { + mVec128 = v.mVec128; + + return *this; + } + +#endif + + // template + // explicit Quaternion(const btScalar *v) : Tuple4(v) {} + /**@brief Constructor from scalars */ + btQuaternion(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w) + : btQuadWord(_x, _y, _z, _w) + {} + /**@brief Axis angle Constructor + * @param axis The axis which the rotation is around + * @param angle The magnitude of the rotation around the angle (Radians) */ + btQuaternion(const btVector3& _axis, const btScalar& _angle) + { + setRotation(_axis, _angle); + } + /**@brief Constructor from Euler angles + * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z + * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y + * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */ + btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { +#ifndef BT_EULER_DEFAULT_ZYX + setEuler(yaw, pitch, roll); +#else + setEulerZYX(yaw, pitch, roll); +#endif + } + /**@brief Set the rotation using axis angle notation + * @param axis The axis around which to rotate + * @param angle The magnitude of the rotation in Radians */ + void setRotation(const btVector3& axis, const btScalar& _angle) + { + btScalar d = axis.length(); + btAssert(d != btScalar(0.0)); + btScalar s = btSin(_angle * btScalar(0.5)) / d; + setValue(axis.x() * s, axis.y() * s, axis.z() * s, + btCos(_angle * btScalar(0.5))); + } + /**@brief Set the quaternion using Euler angles + * @param yaw Angle around Y + * @param pitch Angle around X + * @param roll Angle around Z */ + void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + btScalar halfYaw = btScalar(yaw) * btScalar(0.5); + btScalar halfPitch = btScalar(pitch) * btScalar(0.5); + btScalar halfRoll = btScalar(roll) * btScalar(0.5); + btScalar cosYaw = btCos(halfYaw); + btScalar sinYaw = btSin(halfYaw); + btScalar cosPitch = btCos(halfPitch); + btScalar sinPitch = btSin(halfPitch); + btScalar cosRoll = btCos(halfRoll); + btScalar sinRoll = btSin(halfRoll); + setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + } + /**@brief Set the quaternion using euler angles + * @param yaw Angle around Z + * @param pitch Angle around Y + * @param roll Angle around X */ + void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + btScalar halfYaw = btScalar(yaw) * btScalar(0.5); + btScalar halfPitch = btScalar(pitch) * btScalar(0.5); + btScalar halfRoll = btScalar(roll) * btScalar(0.5); + btScalar cosYaw = btCos(halfYaw); + btScalar sinYaw = btSin(halfYaw); + btScalar cosPitch = btCos(halfPitch); + btScalar sinPitch = btSin(halfPitch); + btScalar cosRoll = btCos(halfRoll); + btScalar sinRoll = btSin(halfRoll); + setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x + cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx + } + /**@brief Add two quaternions + * @param q The quaternion to add to this one */ + SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q) + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = _mm_add_ps(mVec128, q.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vaddq_f32(mVec128, q.mVec128); +#else + m_floats[0] += q.x(); + m_floats[1] += q.y(); + m_floats[2] += q.z(); + m_floats[3] += q.m_floats[3]; +#endif + return *this; + } + + /**@brief Subtract out a quaternion + * @param q The quaternion to subtract from this one */ + btQuaternion& operator-=(const btQuaternion& q) + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = _mm_sub_ps(mVec128, q.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vsubq_f32(mVec128, q.mVec128); +#else + m_floats[0] -= q.x(); + m_floats[1] -= q.y(); + m_floats[2] -= q.z(); + m_floats[3] -= q.m_floats[3]; +#endif + return *this; + } + + /**@brief Scale this quaternion + * @param s The scalar to scale by */ + btQuaternion& operator*=(const btScalar& s) + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0); // (S S S S) + mVec128 = _mm_mul_ps(mVec128, vs); +#elif defined(BT_USE_NEON) + mVec128 = vmulq_n_f32(mVec128, s); +#else + m_floats[0] *= s; + m_floats[1] *= s; + m_floats[2] *= s; + m_floats[3] *= s; +#endif + return *this; + } + + /**@brief Multiply this quaternion by q on the right + * @param q The other quaternion + * Equivilant to this = this * q */ + btQuaternion& operator*=(const btQuaternion& q) + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vQ2 = q.get128(); + + __m128 A1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(0,1,2,0)); + __m128 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); + + A1 = A1 * B1; + + __m128 A2 = bt_pshufd_ps(mVec128, BT_SHUFFLE(1,2,0,1)); + __m128 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); + + A2 = A2 * B2; + + B1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(2,0,1,2)); + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); + + B1 = B1 * B2; // A3 *= B3 + + mVec128 = bt_splat_ps(mVec128, 3); // A0 + mVec128 = mVec128 * vQ2; // A0 * B0 + + A1 = A1 + A2; // AB12 + mVec128 = mVec128 - B1; // AB03 = AB0 - AB3 + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + mVec128 = mVec128+ A1; // AB03 + AB12 + +#elif defined(BT_USE_NEON) + + float32x4_t vQ1 = mVec128; + float32x4_t vQ2 = q.get128(); + float32x4_t A0, A1, B1, A2, B2, A3, B3; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; + + { + float32x2x2_t tmp; + tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} + vQ1zx = tmp.val[0]; + + tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + + A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + + A1 = vmulq_f32(A1, B1); + A2 = vmulq_f32(A2, B2); + A3 = vmulq_f32(A3, B3); // A3 *= B3 + A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + A0 = vaddq_f32(A0, A1); // AB03 + AB12 + + mVec128 = A0; +#else + setValue( + m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(), + m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(), + m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(), + m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z()); +#endif + return *this; + } + /**@brief Return the dot product between this quaternion and another + * @param q The other quaternion */ + btScalar dot(const btQuaternion& q) const + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vd; + + vd = _mm_mul_ps(mVec128, q.mVec128); + + __m128 t = _mm_movehl_ps(vd, vd); + vd = _mm_add_ps(vd, t); + t = _mm_shuffle_ps(vd, vd, 0x55); + vd = _mm_add_ss(vd, t); + + return _mm_cvtss_f32(vd); +#elif defined(BT_USE_NEON) + float32x4_t vd = vmulq_f32(mVec128, q.mVec128); + float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_high_f32(vd)); + x = vpadd_f32(x, x); + return vget_lane_f32(x, 0); +#else + return m_floats[0] * q.x() + + m_floats[1] * q.y() + + m_floats[2] * q.z() + + m_floats[3] * q.m_floats[3]; +#endif + } + + /**@brief Return the length squared of the quaternion */ + btScalar length2() const + { + return dot(*this); + } + + /**@brief Return the length of the quaternion */ + btScalar length() const + { + return btSqrt(length2()); + } + + /**@brief Normalize the quaternion + * Such that x^2 + y^2 + z^2 +w^2 = 1 */ + btQuaternion& normalize() + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vd; + + vd = _mm_mul_ps(mVec128, mVec128); + + __m128 t = _mm_movehl_ps(vd, vd); + vd = _mm_add_ps(vd, t); + t = _mm_shuffle_ps(vd, vd, 0x55); + vd = _mm_add_ss(vd, t); + + vd = _mm_sqrt_ss(vd); + vd = _mm_div_ss(vOnes, vd); + vd = bt_pshufd_ps(vd, 0); // splat + mVec128 = _mm_mul_ps(mVec128, vd); + + return *this; +#else + return *this /= length(); +#endif + } + + /**@brief Return a scaled version of this quaternion + * @param s The scale factor */ + SIMD_FORCE_INLINE btQuaternion + operator*(const btScalar& s) const + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0x00); // (S S S S) + + return btQuaternion(_mm_mul_ps(mVec128, vs)); +#elif defined(BT_USE_NEON) + return btQuaternion(vmulq_n_f32(mVec128, s)); +#else + return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s); +#endif + } + + /**@brief Return an inversely scaled versionof this quaternion + * @param s The inverse scale factor */ + btQuaternion operator/(const btScalar& s) const + { + btAssert(s != btScalar(0.0)); + return *this * (btScalar(1.0) / s); + } + + /**@brief Inversely scale this quaternion + * @param s The scale factor */ + btQuaternion& operator/=(const btScalar& s) + { + btAssert(s != btScalar(0.0)); + return *this *= btScalar(1.0) / s; + } + + /**@brief Return a normalized version of this quaternion */ + btQuaternion normalized() const + { + return *this / length(); + } + /**@brief Return the angle between this quaternion and the other + * @param q The other quaternion */ + btScalar angle(const btQuaternion& q) const + { + btScalar s = btSqrt(length2() * q.length2()); + btAssert(s != btScalar(0.0)); + return btAcos(dot(q) / s); + } + /**@brief Return the angle of rotation represented by this quaternion */ + btScalar getAngle() const + { + btScalar s = btScalar(2.) * btAcos(m_floats[3]); + return s; + } + + /**@brief Return the axis of the rotation represented by this quaternion */ + btVector3 getAxis() const + { + btScalar s_squared = 1.f-m_floats[3]*m_floats[3]; + + if (s_squared < btScalar(10.) * SIMD_EPSILON) //Check for divide by zero + return btVector3(1.0, 0.0, 0.0); // Arbitrary + btScalar s = 1.f/btSqrt(s_squared); + return btVector3(m_floats[0] * s, m_floats[1] * s, m_floats[2] * s); + } + + /**@brief Return the inverse of this quaternion */ + btQuaternion inverse() const + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btQuaternion(_mm_xor_ps(mVec128, vQInv)); +#elif defined(BT_USE_NEON) + return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)vQInv)); +#else + return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]); +#endif + } + + /**@brief Return the sum of this quaternion and the other + * @param q2 The other quaternion */ + SIMD_FORCE_INLINE btQuaternion + operator+(const btQuaternion& q2) const + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btQuaternion(_mm_add_ps(mVec128, q2.mVec128)); +#elif defined(BT_USE_NEON) + return btQuaternion(vaddq_f32(mVec128, q2.mVec128)); +#else + const btQuaternion& q1 = *this; + return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]); +#endif + } + + /**@brief Return the difference between this quaternion and the other + * @param q2 The other quaternion */ + SIMD_FORCE_INLINE btQuaternion + operator-(const btQuaternion& q2) const + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btQuaternion(_mm_sub_ps(mVec128, q2.mVec128)); +#elif defined(BT_USE_NEON) + return btQuaternion(vsubq_f32(mVec128, q2.mVec128)); +#else + const btQuaternion& q1 = *this; + return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]); +#endif + } + + /**@brief Return the negative of this quaternion + * This simply negates each element */ + SIMD_FORCE_INLINE btQuaternion operator-() const + { +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btQuaternion(_mm_xor_ps(mVec128, btvMzeroMask)); +#elif defined(BT_USE_NEON) + return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)btvMzeroMask) ); +#else + const btQuaternion& q2 = *this; + return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_floats[3]); +#endif + } + /**@todo document this and it's use */ + SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const + { + btQuaternion diff,sum; + diff = *this - qd; + sum = *this + qd; + if( diff.dot(diff) > sum.dot(sum) ) + return qd; + return (-qd); + } + + /**@todo document this and it's use */ + SIMD_FORCE_INLINE btQuaternion nearest( const btQuaternion& qd) const + { + btQuaternion diff,sum; + diff = *this - qd; + sum = *this + qd; + if( diff.dot(diff) < sum.dot(sum) ) + return qd; + return (-qd); + } + + + /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion + * @param q The other quaternion to interpolate with + * @param t The ratio between this and q to interpolate. If t = 0 the result is this, if t=1 the result is q. + * Slerp interpolates assuming constant velocity. */ + btQuaternion slerp(const btQuaternion& q, const btScalar& t) const + { + btScalar magnitude = btSqrt(length2() * q.length2()); + btAssert(magnitude > btScalar(0)); + + btScalar product = dot(q) / magnitude; + if (btFabs(product) != btScalar(1)) + { + // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp + const btScalar sign = (product < 0) ? btScalar(-1) : btScalar(1); + + const btScalar theta = btAcos(sign * product); + const btScalar s1 = btSin(sign * t * theta); + const btScalar d = btScalar(1.0) / btSin(theta); + const btScalar s0 = btSin((btScalar(1.0) - t) * theta); + + return btQuaternion( + (m_floats[0] * s0 + q.x() * s1) * d, + (m_floats[1] * s0 + q.y() * s1) * d, + (m_floats[2] * s0 + q.z() * s1) * d, + (m_floats[3] * s0 + q.m_floats[3] * s1) * d); + } + else + { + return *this; + } + } + + static const btQuaternion& getIdentity() + { + static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.)); + return identityQuat; + } + + SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; } + + +}; + + + + + +/**@brief Return the product of two quaternions */ +SIMD_FORCE_INLINE btQuaternion +operator*(const btQuaternion& q1, const btQuaternion& q2) +{ +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vQ1 = q1.get128(); + __m128 vQ2 = q2.get128(); + __m128 A0, A1, B1, A2, B2; + + A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0)); // X Y z x // vtrn + B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); // W W W X // vdup vext + + A1 = A1 * B1; + + A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1)); // Y Z X Y // vext + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); // z x Y Y // vtrn vdup + + A2 = A2 * B2; + + B1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2)); // z x Y Z // vtrn vext + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); // Y Z x z // vext vtrn + + B1 = B1 * B2; // A3 *= B3 + + A0 = bt_splat_ps(vQ1, 3); // A0 + A0 = A0 * vQ2; // A0 * B0 + + A1 = A1 + A2; // AB12 + A0 = A0 - B1; // AB03 = AB0 - AB3 + + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + A0 = A0 + A1; // AB03 + AB12 + + return btQuaternion(A0); + +#elif defined(BT_USE_NEON) + + float32x4_t vQ1 = q1.get128(); + float32x4_t vQ2 = q2.get128(); + float32x4_t A0, A1, B1, A2, B2, A3, B3; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; + + { + float32x2x2_t tmp; + tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} + vQ1zx = tmp.val[0]; + + tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + + A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + + A1 = vmulq_f32(A1, B1); + A2 = vmulq_f32(A2, B2); + A3 = vmulq_f32(A3, B3); // A3 *= B3 + A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + A0 = vaddq_f32(A0, A1); // AB03 + AB12 + + return btQuaternion(A0); + +#else + return btQuaternion( + q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), + q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), + q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); +#endif +} + +SIMD_FORCE_INLINE btQuaternion +operator*(const btQuaternion& q, const btVector3& w) +{ +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vQ1 = q.get128(); + __m128 vQ2 = w.get128(); + __m128 A1, B1, A2, B2, A3, B3; + + A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(3,3,3,0)); + B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(0,1,2,0)); + + A1 = A1 * B1; + + A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1)); + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); + + A2 = A2 * B2; + + A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2)); + B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); + + A3 = A3 * B3; // A3 *= B3 + + A1 = A1 + A2; // AB12 + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + A1 = A1 - A3; // AB123 = AB12 - AB3 + + return btQuaternion(A1); + +#elif defined(BT_USE_NEON) + + float32x4_t vQ1 = q.get128(); + float32x4_t vQ2 = w.get128(); + float32x4_t A1, B1, A2, B2, A3, B3; + float32x2_t vQ1wx, vQ2zx, vQ1yz, vQ2yz, vQ1zx, vQ2xz; + + vQ1wx = vext_f32(vget_high_f32(vQ1), vget_low_f32(vQ1), 1); + { + float32x2x2_t tmp; + + tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} + vQ2zx = tmp.val[0]; + + tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} + vQ1zx = tmp.val[0]; + } + + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ1), 1), vQ1wx); // W W W X + B1 = vcombine_f32(vget_low_f32(vQ2), vQ2zx); // X Y z x + + A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + + A1 = vmulq_f32(A1, B1); + A2 = vmulq_f32(A2, B2); + A3 = vmulq_f32(A3, B3); // A3 *= B3 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + + A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 + + return btQuaternion(A1); + +#else + return btQuaternion( + q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); +#endif +} + +SIMD_FORCE_INLINE btQuaternion +operator*(const btVector3& w, const btQuaternion& q) +{ +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vQ1 = w.get128(); + __m128 vQ2 = q.get128(); + __m128 A1, B1, A2, B2, A3, B3; + + A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0)); // X Y z x + B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); // W W W X + + A1 = A1 * B1; + + A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1)); + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); + + A2 = A2 *B2; + + A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2)); + B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); + + A3 = A3 * B3; // A3 *= B3 + + A1 = A1 + A2; // AB12 + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + A1 = A1 - A3; // AB123 = AB12 - AB3 + + return btQuaternion(A1); + +#elif defined(BT_USE_NEON) + + float32x4_t vQ1 = w.get128(); + float32x4_t vQ2 = q.get128(); + float32x4_t A1, B1, A2, B2, A3, B3; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; + + { + float32x2x2_t tmp; + + tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} + vQ1zx = tmp.val[0]; + + tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + + A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + + A1 = vmulq_f32(A1, B1); + A2 = vmulq_f32(A2, B2); + A3 = vmulq_f32(A3, B3); // A3 *= B3 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + + A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 + + return btQuaternion(A1); + +#else + return btQuaternion( + +w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + +w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), + +w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); +#endif +} + +/**@brief Calculate the dot product between two quaternions */ +SIMD_FORCE_INLINE btScalar +dot(const btQuaternion& q1, const btQuaternion& q2) +{ + return q1.dot(q2); +} + + +/**@brief Return the length of a quaternion */ +SIMD_FORCE_INLINE btScalar +length(const btQuaternion& q) +{ + return q.length(); +} + +/**@brief Return the angle between two quaternions*/ +SIMD_FORCE_INLINE btScalar +btAngle(const btQuaternion& q1, const btQuaternion& q2) +{ + return q1.angle(q2); +} + +/**@brief Return the inverse of a quaternion*/ +SIMD_FORCE_INLINE btQuaternion +inverse(const btQuaternion& q) +{ + return q.inverse(); +} + +/**@brief Return the result of spherical linear interpolation betwen two quaternions + * @param q1 The first quaternion + * @param q2 The second quaternion + * @param t The ration between q1 and q2. t = 0 return q1, t=1 returns q2 + * Slerp assumes constant velocity between positions. */ +SIMD_FORCE_INLINE btQuaternion +slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) +{ + return q1.slerp(q2, t); +} + +SIMD_FORCE_INLINE btVector3 +quatRotate(const btQuaternion& rotation, const btVector3& v) +{ + btQuaternion q = rotation * v; + q *= rotation.inverse(); +#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btVector3(_mm_and_ps(q.get128(), btvFFF0fMask)); +#elif defined(BT_USE_NEON) + return btVector3((float32x4_t)vandq_s32((int32x4_t)q.get128(), btvFFF0Mask)); +#else + return btVector3(q.getX(),q.getY(),q.getZ()); +#endif +} + +SIMD_FORCE_INLINE btQuaternion +shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized +{ + btVector3 c = v0.cross(v1); + btScalar d = v0.dot(v1); + + if (d < -1.0 + SIMD_EPSILON) + { + btVector3 n,unused; + btPlaneSpace1(v0,n,unused); + return btQuaternion(n.x(),n.y(),n.z(),0.0f); // just pick any vector that is orthogonal to v0 + } + + btScalar s = btSqrt((1.0f + d) * 2.0f); + btScalar rs = 1.0f / s; + + return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f); +} + +SIMD_FORCE_INLINE btQuaternion +shortestArcQuatNormalize2(btVector3& v0,btVector3& v1) +{ + v0.normalize(); + v1.normalize(); + return shortestArcQuat(v0,v1); +} + +#endif //BT_SIMD__QUATERNION_H_ + + + diff --git a/src/LinearMath/btQuickprof.cpp b/src/LinearMath/btQuickprof.cpp new file mode 100644 index 0000000..544aee8 --- /dev/null +++ b/src/LinearMath/btQuickprof.cpp @@ -0,0 +1,566 @@ +/* + +*************************************************************************************************** +** +** profile.cpp +** +** Real-Time Hierarchical Profiling for Game Programming Gems 3 +** +** by Greg Hjelstrom & Byon Garrabrant +** +***************************************************************************************************/ + +// Credits: The Clock class was inspired by the Timer classes in +// Ogre (www.ogre3d.org). + +#include "btQuickprof.h" + +#ifndef BT_NO_PROFILE + + +static btClock gProfileClock; + + +#ifdef __CELLOS_LV2__ +#include +#include +#include +#endif + +#if defined (SUNOS) || defined (__SUNOS__) +#include +#endif + +#if defined(WIN32) || defined(_WIN32) + +#define BT_USE_WINDOWS_TIMERS +#define WIN32_LEAN_AND_MEAN +#define NOWINRES +#define NOMCX +#define NOIME + +#ifdef _XBOX + #include +#else //_XBOX + #include +#endif //_XBOX + +#include + + +#else //_WIN32 +#include +#endif //_WIN32 + +#define mymin(a,b) (a > b ? a : b) + +struct btClockData +{ + +#ifdef BT_USE_WINDOWS_TIMERS + LARGE_INTEGER mClockFrequency; + DWORD mStartTick; + LONGLONG mPrevElapsedTime; + LARGE_INTEGER mStartTime; +#else +#ifdef __CELLOS_LV2__ + uint64_t mStartTime; +#else + struct timeval mStartTime; +#endif +#endif //__CELLOS_LV2__ + +}; + +///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. +btClock::btClock() +{ + m_data = new btClockData; +#ifdef BT_USE_WINDOWS_TIMERS + QueryPerformanceFrequency(&m_data->mClockFrequency); +#endif + reset(); +} + +btClock::~btClock() +{ + delete m_data; +} + +btClock::btClock(const btClock& other) +{ + m_data = new btClockData; + *m_data = *other.m_data; +} + +btClock& btClock::operator=(const btClock& other) +{ + *m_data = *other.m_data; + return *this; +} + + + /// Resets the initial reference time. +void btClock::reset() +{ +#ifdef BT_USE_WINDOWS_TIMERS + QueryPerformanceCounter(&m_data->mStartTime); + m_data->mStartTick = GetTickCount(); + m_data->mPrevElapsedTime = 0; +#else +#ifdef __CELLOS_LV2__ + + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET( newTime ); + m_data->mStartTime = newTime; +#else + gettimeofday(&m_data->mStartTime, 0); +#endif +#endif +} + +/// Returns the time in ms since the last call to reset or since +/// the btClock was created. +unsigned long int btClock::getTimeMilliseconds() +{ +#ifdef BT_USE_WINDOWS_TIMERS + LARGE_INTEGER currentTime; + QueryPerformanceCounter(¤tTime); + LONGLONG elapsedTime = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + // Compute the number of millisecond ticks elapsed. + unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + // Check for unexpected leaps in the Win32 performance counter. + // (This is caused by unexpected data across the PCI to ISA + // bridge, aka south bridge. See Microsoft KB274323.) + unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick; + signed long msecOff = (signed long)(msecTicks - elapsedTicks); + if (msecOff < -100 || msecOff > 100) + { + // Adjust the starting time forwards. + LONGLONG msecAdjustment = mymin(msecOff * + m_data->mClockFrequency.QuadPart / 1000, elapsedTime - + m_data->mPrevElapsedTime); + m_data->mStartTime.QuadPart += msecAdjustment; + elapsedTime -= msecAdjustment; + + // Recompute the number of millisecond ticks elapsed. + msecTicks = (unsigned long)(1000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + } + + // Store the current elapsed time for adjustments next time. + m_data->mPrevElapsedTime = elapsedTime; + + return msecTicks; +#else + +#ifdef __CELLOS_LV2__ + uint64_t freq=sys_time_get_timebase_frequency(); + double dFreq=((double) freq) / 1000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + SYS_TIMEBASE_GET( newTime ); + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + + return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); +#else + + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; +#endif //__CELLOS_LV2__ +#endif +} + + /// Returns the time in us since the last call to reset or since + /// the Clock was created. +unsigned long int btClock::getTimeMicroseconds() +{ +#ifdef BT_USE_WINDOWS_TIMERS + LARGE_INTEGER currentTime; + QueryPerformanceCounter(¤tTime); + LONGLONG elapsedTime = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + + // Compute the number of millisecond ticks elapsed. + unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + + // Check for unexpected leaps in the Win32 performance counter. + // (This is caused by unexpected data across the PCI to ISA + // bridge, aka south bridge. See Microsoft KB274323.) + unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick; + signed long msecOff = (signed long)(msecTicks - elapsedTicks); + if (msecOff < -100 || msecOff > 100) + { + // Adjust the starting time forwards. + LONGLONG msecAdjustment = mymin(msecOff * + m_data->mClockFrequency.QuadPart / 1000, elapsedTime - + m_data->mPrevElapsedTime); + m_data->mStartTime.QuadPart += msecAdjustment; + elapsedTime -= msecAdjustment; + } + + // Store the current elapsed time for adjustments next time. + m_data->mPrevElapsedTime = elapsedTime; + + // Convert to microseconds. + unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + + return usecTicks; +#else + +#ifdef __CELLOS_LV2__ + uint64_t freq=sys_time_get_timebase_frequency(); + double dFreq=((double) freq)/ 1000000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET( newTime ); + + return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); +#else + + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec); +#endif//__CELLOS_LV2__ +#endif +} + + + + + +inline void Profile_Get_Ticks(unsigned long int * ticks) +{ + *ticks = gProfileClock.getTimeMicroseconds(); +} + +inline float Profile_Get_Tick_Rate(void) +{ +// return 1000000.f; + return 1000.f; + +} + + + +/*************************************************************************************************** +** +** CProfileNode +** +***************************************************************************************************/ + +/*********************************************************************************************** + * INPUT: * + * name - pointer to a static string which is the name of this profile node * + * parent - parent pointer * + * * + * WARNINGS: * + * The name is assumed to be a static pointer, only the pointer is stored and compared for * + * efficiency reasons. * + *=============================================================================================*/ +CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) : + Name( name ), + TotalCalls( 0 ), + TotalTime( 0 ), + StartTime( 0 ), + RecursionCounter( 0 ), + Parent( parent ), + Child( NULL ), + Sibling( NULL ), + m_userPtr(0) +{ + Reset(); +} + + +void CProfileNode::CleanupMemory() +{ + delete ( Child); + Child = NULL; + delete ( Sibling); + Sibling = NULL; +} + +CProfileNode::~CProfileNode( void ) +{ + delete ( Child); + delete ( Sibling); +} + + +/*********************************************************************************************** + * INPUT: * + * name - static string pointer to the name of the node we are searching for * + * * + * WARNINGS: * + * All profile names are assumed to be static strings so this function uses pointer compares * + * to find the named node. * + *=============================================================================================*/ +CProfileNode * CProfileNode::Get_Sub_Node( const char * name ) +{ + // Try to find this sub node + CProfileNode * child = Child; + while ( child ) { + if ( child->Name == name ) { + return child; + } + child = child->Sibling; + } + + // We didn't find it, so add it + + CProfileNode * node = new CProfileNode( name, this ); + node->Sibling = Child; + Child = node; + return node; +} + + +void CProfileNode::Reset( void ) +{ + TotalCalls = 0; + TotalTime = 0.0f; + + + if ( Child ) { + Child->Reset(); + } + if ( Sibling ) { + Sibling->Reset(); + } +} + + +void CProfileNode::Call( void ) +{ + TotalCalls++; + if (RecursionCounter++ == 0) { + Profile_Get_Ticks(&StartTime); + } +} + + +bool CProfileNode::Return( void ) +{ + if ( --RecursionCounter == 0 && TotalCalls != 0 ) { + unsigned long int time; + Profile_Get_Ticks(&time); + time-=StartTime; + TotalTime += (float)time / Profile_Get_Tick_Rate(); + } + return ( RecursionCounter == 0 ); +} + + +/*************************************************************************************************** +** +** CProfileIterator +** +***************************************************************************************************/ +CProfileIterator::CProfileIterator( CProfileNode * start ) +{ + CurrentParent = start; + CurrentChild = CurrentParent->Get_Child(); +} + + +void CProfileIterator::First(void) +{ + CurrentChild = CurrentParent->Get_Child(); +} + + +void CProfileIterator::Next(void) +{ + CurrentChild = CurrentChild->Get_Sibling(); +} + + +bool CProfileIterator::Is_Done(void) +{ + return CurrentChild == NULL; +} + + +void CProfileIterator::Enter_Child( int index ) +{ + CurrentChild = CurrentParent->Get_Child(); + while ( (CurrentChild != NULL) && (index != 0) ) { + index--; + CurrentChild = CurrentChild->Get_Sibling(); + } + + if ( CurrentChild != NULL ) { + CurrentParent = CurrentChild; + CurrentChild = CurrentParent->Get_Child(); + } +} + + +void CProfileIterator::Enter_Parent( void ) +{ + if ( CurrentParent->Get_Parent() != NULL ) { + CurrentParent = CurrentParent->Get_Parent(); + } + CurrentChild = CurrentParent->Get_Child(); +} + + +/*************************************************************************************************** +** +** CProfileManager +** +***************************************************************************************************/ + +CProfileNode CProfileManager::Root( "Root", NULL ); +CProfileNode * CProfileManager::CurrentNode = &CProfileManager::Root; +int CProfileManager::FrameCounter = 0; +unsigned long int CProfileManager::ResetTime = 0; + + +/*********************************************************************************************** + * CProfileManager::Start_Profile -- Begin a named profile * + * * + * Steps one level deeper into the tree, if a child already exists with the specified name * + * then it accumulates the profiling; otherwise a new child node is added to the profile tree. * + * * + * INPUT: * + * name - name of this profiling record * + * * + * WARNINGS: * + * The string used is assumed to be a static string; pointer compares are used throughout * + * the profiling code for efficiency. * + *=============================================================================================*/ +void CProfileManager::Start_Profile( const char * name ) +{ + if (name != CurrentNode->Get_Name()) { + CurrentNode = CurrentNode->Get_Sub_Node( name ); + } + + CurrentNode->Call(); +} + + +/*********************************************************************************************** + * CProfileManager::Stop_Profile -- Stop timing and record the results. * + *=============================================================================================*/ +void CProfileManager::Stop_Profile( void ) +{ + // Return will indicate whether we should back up to our parent (we may + // be profiling a recursive function) + if (CurrentNode->Return()) { + CurrentNode = CurrentNode->Get_Parent(); + } +} + + +/*********************************************************************************************** + * CProfileManager::Reset -- Reset the contents of the profiling system * + * * + * This resets everything except for the tree structure. All of the timing data is reset. * + *=============================================================================================*/ +void CProfileManager::Reset( void ) +{ + gProfileClock.reset(); + Root.Reset(); + Root.Call(); + FrameCounter = 0; + Profile_Get_Ticks(&ResetTime); +} + + +/*********************************************************************************************** + * CProfileManager::Increment_Frame_Counter -- Increment the frame counter * + *=============================================================================================*/ +void CProfileManager::Increment_Frame_Counter( void ) +{ + FrameCounter++; +} + + +/*********************************************************************************************** + * CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset * + *=============================================================================================*/ +float CProfileManager::Get_Time_Since_Reset( void ) +{ + unsigned long int time; + Profile_Get_Ticks(&time); + time -= ResetTime; + return (float)time / Profile_Get_Tick_Rate(); +} + +#include + +void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing) +{ + profileIterator->First(); + if (profileIterator->Is_Done()) + return; + + float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + int i; + int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); + for (i=0;iGet_Current_Parent_Name(), parent_time ); + float totalTime = 0.f; + + + int numChildren = 0; + + for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + { + numChildren++; + float current_total_time = profileIterator->Get_Current_Total_Time(); + accumulated_time += current_total_time; + float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; + { + int i; for (i=0;iGet_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); + totalTime += current_total_time; + //recurse into children + } + + if (parent_time < accumulated_time) + { + printf("what's wrong\n"); + } + for (i=0;i SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + + for (i=0;iEnter_Child(i); + dumpRecursive(profileIterator,spacing+3); + profileIterator->Enter_Parent(); + } +} + + + +void CProfileManager::dumpAll() +{ + CProfileIterator* profileIterator = 0; + profileIterator = CProfileManager::Get_Iterator(); + + dumpRecursive(profileIterator,0); + + CProfileManager::Release_Iterator(profileIterator); +} + + + + +#endif //BT_NO_PROFILE diff --git a/src/LinearMath/btQuickprof.h b/src/LinearMath/btQuickprof.h new file mode 100644 index 0000000..93f3f4a --- /dev/null +++ b/src/LinearMath/btQuickprof.h @@ -0,0 +1,203 @@ + +/*************************************************************************************************** +** +** Real-Time Hierarchical Profiling for Game Programming Gems 3 +** +** by Greg Hjelstrom & Byon Garrabrant +** +***************************************************************************************************/ + +// Credits: The Clock class was inspired by the Timer classes in +// Ogre (www.ogre3d.org). + + + +#ifndef BT_QUICK_PROF_H +#define BT_QUICK_PROF_H + +//To disable built-in profiling, please comment out next line +//#define BT_NO_PROFILE 1 +#ifndef BT_NO_PROFILE +#include //@todo remove this, backwards compatibility +#include "btScalar.h" +#include "btAlignedAllocator.h" +#include + + + + + +#define USE_BT_CLOCK 1 + +#ifdef USE_BT_CLOCK + +///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. +class btClock +{ +public: + btClock(); + + btClock(const btClock& other); + btClock& operator=(const btClock& other); + + ~btClock(); + + /// Resets the initial reference time. + void reset(); + + /// Returns the time in ms since the last call to reset or since + /// the btClock was created. + unsigned long int getTimeMilliseconds(); + + /// Returns the time in us since the last call to reset or since + /// the Clock was created. + unsigned long int getTimeMicroseconds(); +private: + struct btClockData* m_data; +}; + +#endif //USE_BT_CLOCK + + + + +///A node in the Profile Hierarchy Tree +class CProfileNode { + +public: + CProfileNode( const char * name, CProfileNode * parent ); + ~CProfileNode( void ); + + CProfileNode * Get_Sub_Node( const char * name ); + + CProfileNode * Get_Parent( void ) { return Parent; } + CProfileNode * Get_Sibling( void ) { return Sibling; } + CProfileNode * Get_Child( void ) { return Child; } + + void CleanupMemory(); + void Reset( void ); + void Call( void ); + bool Return( void ); + + const char * Get_Name( void ) { return Name; } + int Get_Total_Calls( void ) { return TotalCalls; } + float Get_Total_Time( void ) { return TotalTime; } + void* GetUserPointer() const {return m_userPtr;} + void SetUserPointer(void* ptr) { m_userPtr = ptr;} +protected: + + const char * Name; + int TotalCalls; + float TotalTime; + unsigned long int StartTime; + int RecursionCounter; + + CProfileNode * Parent; + CProfileNode * Child; + CProfileNode * Sibling; + void* m_userPtr; +}; + +///An iterator to navigate through the tree +class CProfileIterator +{ +public: + // Access all the children of the current parent + void First(void); + void Next(void); + bool Is_Done(void); + bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } + + void Enter_Child( int index ); // Make the given child the new parent + void Enter_Largest_Child( void ); // Make the largest child the new parent + void Enter_Parent( void ); // Make the current parent's parent the new parent + + // Access the current child + const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); } + int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); } + float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); } + + void* Get_Current_UserPointer( void ) { return CurrentChild->GetUserPointer(); } + void Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);} + // Access the current parent + const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); } + int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); } + float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); } + + + +protected: + + CProfileNode * CurrentParent; + CProfileNode * CurrentChild; + + + CProfileIterator( CProfileNode * start ); + friend class CProfileManager; +}; + + +///The Manager for the Profile system +class CProfileManager { +public: + static void Start_Profile( const char * name ); + static void Stop_Profile( void ); + + static void CleanupMemory(void) + { + Root.CleanupMemory(); + } + + static void Reset( void ); + static void Increment_Frame_Counter( void ); + static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; } + static float Get_Time_Since_Reset( void ); + + static CProfileIterator * Get_Iterator( void ) + { + + return new CProfileIterator( &Root ); + } + static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); } + + static void dumpRecursive(CProfileIterator* profileIterator, int spacing); + + static void dumpAll(); + +private: + static CProfileNode Root; + static CProfileNode * CurrentNode; + static int FrameCounter; + static unsigned long int ResetTime; +}; + + +///ProfileSampleClass is a simple way to profile a function's scope +///Use the BT_PROFILE macro at the start of scope to time +class CProfileSample { +public: + CProfileSample( const char * name ) + { + CProfileManager::Start_Profile( name ); + } + + ~CProfileSample( void ) + { + CProfileManager::Stop_Profile(); + } +}; + + +#define BT_PROFILE( name ) CProfileSample __profile( name ) + +#else + +#define BT_PROFILE( name ) + +#endif //#ifndef BT_NO_PROFILE + + + +#endif //BT_QUICK_PROF_H + + diff --git a/src/LinearMath/btRandom.h b/src/LinearMath/btRandom.h new file mode 100644 index 0000000..4cbfc6b --- /dev/null +++ b/src/LinearMath/btRandom.h @@ -0,0 +1,42 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_GEN_RANDOM_H +#define BT_GEN_RANDOM_H + +#ifdef MT19937 + +#include +#include + +#define GEN_RAND_MAX UINT_MAX + +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); } + +#else + +#include + +#define GEN_RAND_MAX RAND_MAX + +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); } + +#endif + +#endif //BT_GEN_RANDOM_H + diff --git a/src/LinearMath/btScalar.h b/src/LinearMath/btScalar.h new file mode 100644 index 0000000..7154b8f --- /dev/null +++ b/src/LinearMath/btScalar.h @@ -0,0 +1,661 @@ +/* +Copyright (c) 2003-2009 Erwin Coumans http://bullet.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_SCALAR_H +#define BT_SCALAR_H + +#ifdef BT_MANAGED_CODE +//Aligned data types not supported in managed code +#pragma unmanaged +#endif + + +#include +#include //size_t for MSVC 6.0 +#include + +/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/ +#define BT_BULLET_VERSION 281 + +inline int btGetVersion() +{ + return BT_BULLET_VERSION; +} + +#if defined(DEBUG) || defined (_DEBUG) +#define BT_DEBUG +#endif + + +#ifdef _WIN32 + + #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) + + #define SIMD_FORCE_INLINE inline + #define ATTRIBUTE_ALIGNED16(a) a + #define ATTRIBUTE_ALIGNED64(a) a + #define ATTRIBUTE_ALIGNED128(a) a + #else + //#define BT_HAS_ALIGNED_ALLOCATOR + #pragma warning(disable : 4324) // disable padding warning +// #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. +// #pragma warning(disable:4996) //Turn off warnings about deprecated C routines +// #pragma warning(disable:4786) // Disable the "debug name too long" warning + + #define SIMD_FORCE_INLINE __forceinline + #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a + #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a + #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a + #ifdef _XBOX + #define BT_USE_VMX128 + + #include + #define BT_HAVE_NATIVE_FSEL + #define btFsel(a,b,c) __fsel((a),(b),(c)) + #else + +#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION)) + #define BT_USE_SSE + #ifdef BT_USE_SSE + //BT_USE_SSE_IN_API is disabled under Windows by default, because + //it makes it harder to integrate Bullet into your application under Windows + //(structured embedding Bullet structs/classes need to be 16-byte aligned) + //with relatively little performance gain + //If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries + //you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage) + //#define BT_USE_SSE_IN_API + #endif //BT_USE_SSE + #include +#endif + + #endif//_XBOX + + #endif //__MINGW32__ + +#ifdef BT_DEBUG + #ifdef _MSC_VER + #include + #define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);__debugbreak(); }} + #else//_MSC_VER + #include + #define btAssert assert + #endif//_MSC_VER +#else + #define btAssert(x) +#endif + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + + #define btLikely(_c) _c + #define btUnlikely(_c) _c + +#else + +#if defined (__CELLOS_LV2__) + #define SIMD_FORCE_INLINE inline __attribute__((always_inline)) + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #ifndef assert + #include + #endif +#ifdef BT_DEBUG +#ifdef __SPU__ +#include +#define printf spu_printf + #define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}} +#else + #define btAssert assert +#endif + +#else + #define btAssert(x) +#endif + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + + #define btLikely(_c) _c + #define btUnlikely(_c) _c + +#else + +#ifdef USE_LIBSPE2 + + #define SIMD_FORCE_INLINE __inline + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #ifndef assert + #include + #endif +#ifdef BT_DEBUG + #define btAssert assert +#else + #define btAssert(x) +#endif + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + + + #define btLikely(_c) __builtin_expect((_c), 1) + #define btUnlikely(_c) __builtin_expect((_c), 0) + + +#else + //non-windows systems + +#if (defined (__APPLE__) && (!defined (BT_USE_DOUBLE_PRECISION))) + #if defined (__i386__) || defined (__x86_64__) + #define BT_USE_SSE + //BT_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries + //if apps run into issues, we will disable the next line + #define BT_USE_SSE_IN_API + #ifdef BT_USE_SSE + // include appropriate SSE level + #if defined (__SSE4_1__) + #include + #elif defined (__SSSE3__) + #include + #elif defined (__SSE3__) + #include + #else + #include + #endif + #endif //BT_USE_SSE + #elif defined( __armv7__ ) + #ifdef __clang__ + #define BT_USE_NEON 1 + + #if defined BT_USE_NEON && defined (__clang__) + #include + #endif//BT_USE_NEON + #endif //__clang__ + #endif//__arm__ + + #define SIMD_FORCE_INLINE inline __attribute__ ((always_inline)) +///@todo: check out alignment methods for other platforms/compilers + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #ifndef assert + #include + #endif + + #if defined(DEBUG) || defined (_DEBUG) + #if defined (__i386__) || defined (__x86_64__) + #include + #define btAssert(x)\ + {\ + if(!(x))\ + {\ + printf("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\ + asm volatile ("int3");\ + }\ + } + #else//defined (__i386__) || defined (__x86_64__) + #define btAssert assert + #end//defined (__i386__) || defined (__x86_64__) + #endif + #else//defined(DEBUG) || defined (_DEBUG) + #define btAssert(x) + #endif//defined(DEBUG) || defined (_DEBUG) + + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + #define btLikely(_c) _c + #define btUnlikely(_c) _c + +#else + + #define SIMD_FORCE_INLINE inline + ///@todo: check out alignment methods for other platforms/compilers + ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + ///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #define ATTRIBUTE_ALIGNED16(a) a + #define ATTRIBUTE_ALIGNED64(a) a + #define ATTRIBUTE_ALIGNED128(a) a + #ifndef assert + #include + #endif + +#if defined(DEBUG) || defined (_DEBUG) + #define btAssert assert +#else + #define btAssert(x) +#endif + + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + #define btLikely(_c) _c + #define btUnlikely(_c) _c +#endif //__APPLE__ + +#endif // LIBSPE2 + +#endif //__CELLOS_LV2__ +#endif + + +///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision. +#if defined(BT_USE_DOUBLE_PRECISION) +typedef double btScalar; +//this number could be bigger in double precision +#define BT_LARGE_FLOAT 1e30 +#else +typedef float btScalar; +//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX +#define BT_LARGE_FLOAT 1e18f +#endif + +#ifdef BT_USE_SSE +typedef __m128 btSimdFloat4; +#endif//BT_USE_SSE + +#if defined BT_USE_SSE_IN_API && defined (BT_USE_SSE) +#ifdef _WIN32 + +#ifndef BT_NAN +static int btNanMask = 0x7F800001; +#define BT_NAN (*(float*)&btNanMask) +#endif + +#ifndef BT_INFINITY +static int btInfinityMask = 0x7F800000; +#define BT_INFINITY (*(float*)&btInfinityMask) +#endif + +inline __m128 operator + (const __m128 A, const __m128 B) +{ + return _mm_add_ps(A, B); +} + +inline __m128 operator - (const __m128 A, const __m128 B) +{ + return _mm_sub_ps(A, B); +} + +inline __m128 operator * (const __m128 A, const __m128 B) +{ + return _mm_mul_ps(A, B); +} + +#define btCastfTo128i(a) (_mm_castps_si128(a)) +#define btCastfTo128d(a) (_mm_castps_pd(a)) +#define btCastiTo128f(a) (_mm_castsi128_ps(a)) +#define btCastdTo128f(a) (_mm_castpd_ps(a)) +#define btCastdTo128i(a) (_mm_castpd_si128(a)) +#define btAssign128(r0,r1,r2,r3) _mm_setr_ps(r0,r1,r2,r3) + +#else//_WIN32 + +#define btCastfTo128i(a) ((__m128i)(a)) +#define btCastfTo128d(a) ((__m128d)(a)) +#define btCastiTo128f(a) ((__m128) (a)) +#define btCastdTo128f(a) ((__m128) (a)) +#define btCastdTo128i(a) ((__m128i)(a)) +#define btAssign128(r0,r1,r2,r3) (__m128){r0,r1,r2,r3} +#define BT_INFINITY INFINITY +#define BT_NAN NAN +#endif//_WIN32 +#endif //BT_USE_SSE_IN_API + +#ifdef BT_USE_NEON +#include + +typedef float32x4_t btSimdFloat4; +#define BT_INFINITY INFINITY +#define BT_NAN NAN +#define btAssign128(r0,r1,r2,r3) (float32x4_t){r0,r1,r2,r3} +#endif + + + + + +#define BT_DECLARE_ALIGNED_ALLOCATOR() \ + SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \ + SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \ + SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \ + SIMD_FORCE_INLINE void operator delete(void*, void*) { } \ + SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \ + SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \ + SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \ + SIMD_FORCE_INLINE void operator delete[](void*, void*) { } \ + + + +#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) + +SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); } +SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); } +SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); } +SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); } +SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (xbtScalar(1)) x=btScalar(1); return acos(x); } +SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (xbtScalar(1)) x=btScalar(1); return asin(x); } +SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); } +SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); } +SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); } +SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); } +SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); } +SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); } + +#else + +SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) +{ +#ifdef USE_APPROXIMATION + double x, z, tempf; + unsigned long *tfptr = ((unsigned long *)&tempf) + 1; + + tempf = y; + *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */ + x = tempf; + z = y*btScalar(0.5); + x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */ + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + return x*y; +#else + return sqrtf(y); +#endif +} +SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); } +SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } +SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } +SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { + if (xbtScalar(1)) + x=btScalar(1); + return acosf(x); +} +SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { + if (xbtScalar(1)) + x=btScalar(1); + return asinf(x); +} +SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } +SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } +SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); } +SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); } +SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } +SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); } + +#endif + +#define SIMD_2_PI btScalar(6.283185307179586232) +#define SIMD_PI (SIMD_2_PI * btScalar(0.5)) +#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25)) +#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0)) +#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI) +#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490) + +#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */ + + +#ifdef BT_USE_DOUBLE_PRECISION +#define SIMD_EPSILON DBL_EPSILON +#define SIMD_INFINITY DBL_MAX +#else +#define SIMD_EPSILON FLT_EPSILON +#define SIMD_INFINITY FLT_MAX +#endif + +SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) +{ + btScalar coeff_1 = SIMD_PI / 4.0f; + btScalar coeff_2 = 3.0f * coeff_1; + btScalar abs_y = btFabs(y); + btScalar angle; + if (x >= 0.0f) { + btScalar r = (x - abs_y) / (x + abs_y); + angle = coeff_1 - coeff_1 * r; + } else { + btScalar r = (x + abs_y) / (abs_y - x); + angle = coeff_2 - coeff_1 * r; + } + return (y < 0.0f) ? -angle : angle; +} + +SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; } + +SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) { + return (((a) <= eps) && !((a) < -eps)); +} +SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) { + return (!((a) <= eps)); +} + + +SIMD_FORCE_INLINE int btIsNegative(btScalar x) { + return x < btScalar(0.0) ? 1 : 0; +} + +SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; } +SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; } + +#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name + +#ifndef btFsel +SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c) +{ + return a >= 0 ? b : c; +} +#endif +#define btFsels(a,b,c) (btScalar)btFsel(a,b,c) + + +SIMD_FORCE_INLINE bool btMachineIsLittleEndian() +{ + long int i = 1; + const char *p = (const char *) &i; + if (p[0] == 1) // Lowest address contains the least significant byte + return true; + else + return false; +} + + + +///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360 +///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html +SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) +{ + // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero + // Rely on positive value or'ed with its negative having sign bit on + // and zero value or'ed with its negative (which is still zero) having sign bit off + // Use arithmetic shift right, shifting the sign bit through all 32 bits + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); +} +SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero) +{ + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return static_cast((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); +} +SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero) +{ +#ifdef BT_HAVE_NATIVE_FSEL + return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); +#else + return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; +#endif +} + +template SIMD_FORCE_INLINE void btSwap(T& a, T& b) +{ + T tmp = a; + a = b; + b = tmp; +} + + +//PCK: endian swapping functions +SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val) +{ + return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); +} + +SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val) +{ + return static_cast(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)); +} + +SIMD_FORCE_INLINE unsigned btSwapEndian(int val) +{ + return btSwapEndian((unsigned)val); +} + +SIMD_FORCE_INLINE unsigned short btSwapEndian(short val) +{ + return btSwapEndian((unsigned short) val); +} + +///btSwapFloat uses using char pointers to swap the endianness +////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values +///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. +///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. +///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you. +///so instead of returning a float/double, we return integer/long long integer +SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d) +{ + unsigned int a = 0; + unsigned char *dst = (unsigned char *)&a; + unsigned char *src = (unsigned char *)&d; + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + return a; +} + +// unswap using char pointers +SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) +{ + float d = 0.0f; + unsigned char *src = (unsigned char *)&a; + unsigned char *dst = (unsigned char *)&d; + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + + return d; +} + + +// swap using char pointers +SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst) +{ + unsigned char *src = (unsigned char *)&d; + + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; + +} + +// unswap using char pointers +SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) +{ + double d = 0.0; + unsigned char *dst = (unsigned char *)&d; + + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; + + return d; +} + +// returns normalized value in range [-SIMD_PI, SIMD_PI] +SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) +{ + angleInRadians = btFmod(angleInRadians, SIMD_2_PI); + if(angleInRadians < -SIMD_PI) + { + return angleInRadians + SIMD_2_PI; + } + else if(angleInRadians > SIMD_PI) + { + return angleInRadians - SIMD_2_PI; + } + else + { + return angleInRadians; + } +} + +///rudimentary class to provide type info +struct btTypedObject +{ + btTypedObject(int objectType) + :m_objectType(objectType) + { + } + int m_objectType; + inline int getObjectType() const + { + return m_objectType; + } +}; + + + +///align a pointer to the provided alignment, upwards +template T* btAlignPointer(T* unalignedPtr, size_t alignment) +{ + + struct btConvertPointerSizeT + { + union + { + T* ptr; + size_t integer; + }; + }; + btConvertPointerSizeT converter; + + + const size_t bit_mask = ~(alignment - 1); + converter.ptr = unalignedPtr; + converter.integer += alignment-1; + converter.integer &= bit_mask; + return converter.ptr; +} + +#endif //BT_SCALAR_H diff --git a/src/LinearMath/btSerializer.cpp b/src/LinearMath/btSerializer.cpp new file mode 100644 index 0000000..d6b2b3a --- /dev/null +++ b/src/LinearMath/btSerializer.cpp @@ -0,0 +1,908 @@ +char sBulletDNAstr[]= { +char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(63),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109), +char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95), +char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(115),char(0),char(109),char(95),char(99),char(111), +char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110), +char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(115),char(0),char(42),char(102),char(105),char(114),char(115),char(116),char(0),char(42),char(108),char(97),char(115), +char(116),char(0),char(109),char(95),char(102),char(108),char(111),char(97),char(116),char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(108),char(91),char(51), +char(93),char(0),char(109),char(95),char(98),char(97),char(115),char(105),char(115),char(0),char(109),char(95),char(111),char(114),char(105),char(103),char(105),char(110),char(0),char(109), +char(95),char(114),char(111),char(111),char(116),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98), +char(116),char(114),char(101),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100), +char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(91),char(51),char(93),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122), +char(101),char(100),char(65),char(97),char(98),char(98),char(77),char(97),char(120),char(91),char(51),char(93),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77), +char(105),char(110),char(79),char(114),char(103),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),char(97),char(120),char(79),char(114),char(103),char(0),char(109), +char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),char(80),char(97), +char(114),char(116),char(0),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109), +char(95),char(112),char(97),char(100),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101), +char(120),char(79),char(114),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(98), +char(118),char(104),char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(0),char(109),char(95),char(98),char(118),char(104),char(65),char(97),char(98),char(98),char(77), +char(97),char(120),char(0),char(109),char(95),char(98),char(118),char(104),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110), +char(0),char(109),char(95),char(99),char(117),char(114),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(117),char(115), +char(101),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(110),char(117),char(109),char(67), +char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(76),char(101),char(97),char(102),char(78),char(111),char(100),char(101),char(115),char(0),char(109), +char(95),char(110),char(117),char(109),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117), +char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(99),char(111),char(110),char(116),char(105),char(103),char(117),char(111), +char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105), +char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116), +char(114),char(0),char(42),char(109),char(95),char(115),char(117),char(98),char(84),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(80),char(116),char(114),char(0), +char(109),char(95),char(116),char(114),char(97),char(118),char(101),char(114),char(115),char(97),char(108),char(77),char(111),char(100),char(101),char(0),char(109),char(95),char(110),char(117), +char(109),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(72),char(101),char(97),char(100),char(101),char(114),char(115),char(0),char(42),char(109),char(95),char(110), +char(97),char(109),char(101),char(0),char(109),char(95),char(115),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(112),char(97), +char(100),char(100),char(105),char(110),char(103),char(91),char(52),char(93),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110), +char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(83),char(99),char(97), +char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(101),char(78),char(111),char(114),char(109),char(97),char(108),char(0),char(109), +char(95),char(112),char(108),char(97),char(110),char(101),char(67),char(111),char(110),char(115),char(116),char(97),char(110),char(116),char(0),char(109),char(95),char(105),char(109),char(112), +char(108),char(105),char(99),char(105),char(116),char(83),char(104),char(97),char(112),char(101),char(68),char(105),char(109),char(101),char(110),char(115),char(105),char(111),char(110),char(115), +char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(109), +char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(111),char(115),char(0),char(109),char(95),char(114),char(97),char(100), +char(105),char(117),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108), +char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(42),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(80),char(111), +char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(108),char(111),char(99), +char(97),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(83),char(105),char(122),char(101),char(0), +char(109),char(95),char(118),char(97),char(108),char(117),char(101),char(0),char(109),char(95),char(112),char(97),char(100),char(91),char(50),char(93),char(0),char(109),char(95),char(118), +char(97),char(108),char(117),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(112),char(97),char(100),char(0),char(42),char(109),char(95),char(118),char(101), +char(114),char(116),char(105),char(99),char(101),char(115),char(51),char(102),char(0),char(42),char(109),char(95),char(118),char(101),char(114),char(116),char(105),char(99),char(101),char(115), +char(51),char(100),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(51),char(50),char(0),char(42),char(109),char(95),char(51), +char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(42),char(109),char(95),char(51),char(105),char(110),char(100),char(105),char(99),char(101), +char(115),char(56),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(109),char(95),char(110),char(117), +char(109),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(86),char(101),char(114),char(116), +char(105),char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(109),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(115),char(80),char(116),char(114), +char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(101),char(115),char(104), +char(80),char(97),char(114),char(116),char(115),char(0),char(109),char(95),char(109),char(101),char(115),char(104),char(73),char(110),char(116),char(101),char(114),char(102),char(97),char(99), +char(101),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(70),char(108),char(111),char(97),char(116),char(66), +char(118),char(104),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(68),char(111),char(117),char(98),char(108), +char(101),char(66),char(118),char(104),char(0),char(42),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111), +char(77),char(97),char(112),char(0),char(109),char(95),char(112),char(97),char(100),char(51),char(91),char(52),char(93),char(0),char(109),char(95),char(116),char(114),char(105),char(109), +char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(116),char(114),char(97),char(110),char(115), +char(102),char(111),char(114),char(109),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(0),char(109), +char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(99),char(104), +char(105),char(108),char(100),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104), +char(97),char(112),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(67),char(104),char(105),char(108),char(100),char(83),char(104),char(97), +char(112),char(101),char(115),char(0),char(109),char(95),char(117),char(112),char(65),char(120),char(105),char(115),char(0),char(109),char(95),char(102),char(108),char(97),char(103),char(115), +char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),char(48),char(86),char(49),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101), +char(100),char(103),char(101),char(86),char(49),char(86),char(50),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86), +char(50),char(86),char(48),char(65),char(110),char(103),char(108),char(101),char(0),char(42),char(109),char(95),char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108), +char(101),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(110),char(101),char(120),char(116),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(118), +char(97),char(108),char(117),char(101),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(107),char(101),char(121),char(65), +char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(69),char(112),char(115),char(105), +char(108),char(111),char(110),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(97),char(114),char(69),char(112),char(115),char(105),char(108),char(111),char(110),char(0), +char(109),char(95),char(101),char(113),char(117),char(97),char(108),char(86),char(101),char(114),char(116),char(101),char(120),char(84),char(104),char(114),char(101),char(115),char(104),char(111), +char(108),char(100),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(68),char(105),char(115),char(116),char(97),char(110),char(99),char(101),char(84),char(104),char(114), +char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(122),char(101),char(114),char(111),char(65),char(114),char(101),char(97),char(84),char(104),char(114), +char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(101),char(120),char(116),char(83),char(105),char(122),char(101),char(0),char(109),char(95), +char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(110),char(117),char(109),char(86), +char(97),char(108),char(117),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(75),char(101),char(121),char(115),char(0),char(109),char(95),char(103),char(105), +char(109),char(112),char(97),char(99),char(116),char(83),char(117),char(98),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(117),char(110),char(115),char(99), +char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(70),char(108),char(111),char(97),char(116),char(80),char(116),char(114),char(0),char(42), +char(109),char(95),char(117),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(68),char(111),char(117),char(98), +char(108),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(85),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80), +char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(51),char(91),char(52),char(93),char(0), +char(42),char(109),char(95),char(98),char(114),char(111),char(97),char(100),char(112),char(104),char(97),char(115),char(101),char(72),char(97),char(110),char(100),char(108),char(101),char(0), +char(42),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),char(42),char(109), +char(95),char(114),char(111),char(111),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0), +char(109),char(95),char(119),char(111),char(114),char(108),char(100),char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105), +char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(87),char(111),char(114),char(108),char(100),char(84),char(114),char(97), +char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105), +char(111),char(110),char(76),char(105),char(110),char(101),char(97),char(114),char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(105), +char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(86), +char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105), +char(99),char(70),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(99),char(116),char(80), +char(114),char(111),char(99),char(101),char(115),char(115),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(100),char(101),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),char(84),char(105),char(109),char(101),char(0),char(109),char(95), +char(102),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114), +char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110), +char(0),char(109),char(95),char(104),char(105),char(116),char(70),char(114),char(97),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(99),char(100), +char(83),char(119),char(101),char(112),char(116),char(83),char(112),char(104),char(101),char(114),char(101),char(82),char(97),char(100),char(105),char(117),char(115),char(0),char(109),char(95), +char(99),char(99),char(100),char(77),char(111),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(104),char(97),char(115),char(65),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),char(99),char(70),char(114),char(105),char(99),char(116), +char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(70),char(108),char(97),char(103),char(115), +char(0),char(109),char(95),char(105),char(115),char(108),char(97),char(110),char(100),char(84),char(97),char(103),char(49),char(0),char(109),char(95),char(99),char(111),char(109),char(112), +char(97),char(110),char(105),char(111),char(110),char(73),char(100),char(0),char(109),char(95),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110), +char(83),char(116),char(97),char(116),char(101),char(49),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(84),char(121),char(112), +char(101),char(0),char(109),char(95),char(99),char(104),char(101),char(99),char(107),char(67),char(111),char(108),char(108),char(105),char(100),char(101),char(87),char(105),char(116),char(104), +char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(0),char(109),char(95),char(103),char(114),char(97),char(118), +char(105),char(116),char(121),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99), +char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(84),char(101), +char(110),char(115),char(111),char(114),char(87),char(111),char(114),char(108),char(100),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(86),char(101), +char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(86),char(101),char(108),char(111), +char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114), +char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(103),char(114), +char(97),char(118),char(105),char(116),char(121),char(95),char(97),char(99),char(99),char(101),char(108),char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(0),char(109), +char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(76),char(111),char(99),char(97),char(108),char(0),char(109),char(95),char(116), +char(111),char(116),char(97),char(108),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(116),char(111),char(116),char(97),char(108),char(84),char(111),char(114), +char(113),char(117),char(101),char(0),char(109),char(95),char(105),char(110),char(118),char(101),char(114),char(115),char(101),char(77),char(97),char(115),char(115),char(0),char(109),char(95), +char(108),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(110),char(103),char(117), +char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111), +char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(97), +char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(76),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105), +char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100), +char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110), +char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),char(105), +char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103), +char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(101),char(101),char(112), +char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108), +char(97),char(114),char(83),char(108),char(101),char(101),char(112),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0), +char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0), +char(109),char(95),char(110),char(117),char(109),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(82),char(111),char(119),char(115),char(0), +char(110),char(117),char(98),char(0),char(42),char(109),char(95),char(114),char(98),char(65),char(0),char(42),char(109),char(95),char(114),char(98),char(66),char(0),char(109),char(95), +char(111),char(98),char(106),char(101),char(99),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),char(110), +char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111), +char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(100),char(0),char(109),char(95),char(110),char(101),char(101),char(100),char(115),char(70),char(101), +char(101),char(100),char(98),char(97),char(99),char(107),char(0),char(109),char(95),char(97),char(112),char(112),char(108),char(105),char(101),char(100),char(73),char(109),char(112),char(117), +char(108),char(115),char(101),char(0),char(109),char(95),char(100),char(98),char(103),char(68),char(114),char(97),char(119),char(83),char(105),char(122),char(101),char(0),char(109),char(95), +char(100),char(105),char(115),char(97),char(98),char(108),char(101),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(115),char(66),char(101),char(116), +char(119),char(101),char(101),char(110),char(76),char(105),char(110),char(107),char(101),char(100),char(66),char(111),char(100),char(105),char(101),char(115),char(0),char(109),char(95),char(111), +char(118),char(101),char(114),char(114),char(105),char(100),char(101),char(78),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(116),char(101),char(114), +char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(98),char(114),char(101),char(97),char(107),char(105),char(110),char(103),char(73),char(109),char(112), +char(117),char(108),char(115),char(101),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(105),char(115),char(69),char(110), +char(97),char(98),char(108),char(101),char(100),char(0),char(109),char(95),char(116),char(121),char(112),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), +char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(65),char(0),char(109),char(95), +char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(66),char(0),char(109),char(95),char(114),char(98),char(65),char(70),char(114),char(97),char(109),char(101),char(0), +char(109),char(95),char(114),char(98),char(66),char(70),char(114),char(97),char(109),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(82),char(101),char(102),char(101), +char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97), +char(114),char(79),char(110),char(108),char(121),char(0),char(109),char(95),char(101),char(110),char(97),char(98),char(108),char(101),char(65),char(110),char(103),char(117),char(108),char(97), +char(114),char(77),char(111),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(111),char(116),char(111),char(114),char(84),char(97),char(114),char(103),char(101),char(116), +char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(109),char(97),char(120),char(77),char(111),char(116),char(111),char(114),char(73), +char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),char(95),char(108),char(111),char(119),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0), +char(109),char(95),char(117),char(112),char(112),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(109),char(105),char(116), +char(83),char(111),char(102),char(116),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(98),char(105),char(97),char(115),char(70),char(97),char(99),char(116),char(111), +char(114),char(0),char(109),char(95),char(114),char(101),char(108),char(97),char(120),char(97),char(116),char(105),char(111),char(110),char(70),char(97),char(99),char(116),char(111),char(114), +char(0),char(109),char(95),char(115),char(119),char(105),char(110),char(103),char(83),char(112),char(97),char(110),char(49),char(0),char(109),char(95),char(115),char(119),char(105),char(110), +char(103),char(83),char(112),char(97),char(110),char(50),char(0),char(109),char(95),char(116),char(119),char(105),char(115),char(116),char(83),char(112),char(97),char(110),char(0),char(109), +char(95),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(85),char(112),char(112), +char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(76),char(111),char(119),char(101), +char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(85),char(112),char(112),char(101), +char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(76),char(111),char(119),char(101), +char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(117),char(115),char(101),char(76),char(105),char(110),char(101),char(97),char(114),char(82),char(101), +char(102),char(101),char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(117),char(115),char(101),char(79), +char(102),char(102),char(115),char(101),char(116),char(70),char(111),char(114),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(114), +char(97),char(109),char(101),char(0),char(109),char(95),char(54),char(100),char(111),char(102),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(115),char(112),char(114), +char(105),char(110),char(103),char(69),char(110),char(97),char(98),char(108),char(101),char(100),char(91),char(54),char(93),char(0),char(109),char(95),char(101),char(113),char(117),char(105), +char(108),char(105),char(98),char(114),char(105),char(117),char(109),char(80),char(111),char(105),char(110),char(116),char(91),char(54),char(93),char(0),char(109),char(95),char(115),char(112), +char(114),char(105),char(110),char(103),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(91),char(54),char(93),char(0),char(109),char(95),char(115), +char(112),char(114),char(105),char(110),char(103),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(91),char(54),char(93),char(0),char(109),char(95),char(116),char(97), +char(117),char(0),char(109),char(95),char(116),char(105),char(109),char(101),char(83),char(116),char(101),char(112),char(0),char(109),char(95),char(109),char(97),char(120),char(69),char(114), +char(114),char(111),char(114),char(82),char(101),char(100),char(117),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(115),char(111),char(114),char(0),char(109), +char(95),char(101),char(114),char(112),char(0),char(109),char(95),char(101),char(114),char(112),char(50),char(0),char(109),char(95),char(103),char(108),char(111),char(98),char(97),char(108), +char(67),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(80),char(101), +char(110),char(101),char(116),char(114),char(97),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(84),char(117),char(114),char(110),char(69),char(114),char(112), +char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(111),char(112),char(0),char(109),char(95),char(119),char(97),char(114),char(109), +char(115),char(116),char(97),char(114),char(116),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(97),char(120), +char(71),char(121),char(114),char(111),char(115),char(99),char(111),char(112),char(105),char(99),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(115),char(105), +char(110),char(103),char(108),char(101),char(65),char(120),char(105),char(115),char(82),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),char(105),char(99),char(116), +char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(117),char(109),char(73),char(116), +char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(77),char(111),char(100), +char(101),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(110),char(103),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(82),char(101), +char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(109),char(105),char(110),char(105),char(109),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(66),char(97),char(116),char(99),char(104),char(83), +char(105),char(122),char(101),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109), +char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97), +char(110),char(103),char(117),char(108),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(118),char(111), +char(108),char(117),char(109),char(101),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(42),char(109),char(95),char(109),char(97),char(116), +char(101),char(114),char(105),char(97),char(108),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112), +char(114),char(101),char(118),char(105),char(111),char(117),char(115),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(118),char(101), +char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(99),char(99),char(117),char(109),char(117),char(108),char(97),char(116),char(101),char(100), +char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(110),char(111),char(114),char(109),char(97),char(108),char(0),char(109),char(95),char(97),char(114),char(101), +char(97),char(0),char(109),char(95),char(97),char(116),char(116),char(97),char(99),char(104),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100), +char(105),char(99),char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(76),char(101),char(110),char(103),char(116),char(104), +char(0),char(109),char(95),char(98),char(98),char(101),char(110),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110), +char(100),char(105),char(99),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(65),char(114),char(101),char(97),char(0), +char(109),char(95),char(99),char(48),char(91),char(52),char(93),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101), +char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95), +char(99),char(49),char(0),char(109),char(95),char(99),char(50),char(0),char(109),char(95),char(99),char(48),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108), +char(70),char(114),char(97),char(109),char(101),char(0),char(42),char(109),char(95),char(114),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(0),char(109), +char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(97),char(101),char(114),char(111),char(77),char(111),char(100), +char(101),char(108),char(0),char(109),char(95),char(98),char(97),char(117),char(109),char(103),char(97),char(114),char(116),char(101),char(0),char(109),char(95),char(100),char(114),char(97), +char(103),char(0),char(109),char(95),char(108),char(105),char(102),char(116),char(0),char(109),char(95),char(112),char(114),char(101),char(115),char(115),char(117),char(114),char(101),char(0), +char(109),char(95),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(100),char(121),char(110),char(97),char(109),char(105),char(99),char(70),char(114), +char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),char(111),char(115),char(101),char(77),char(97),char(116),char(99),char(104),char(0),char(109), +char(95),char(114),char(105),char(103),char(105),char(100),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),char(114),char(100),char(110),char(101),char(115), +char(115),char(0),char(109),char(95),char(107),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97), +char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), +char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(72),char(97),char(114), +char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),char(108),char(117), +char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(75), +char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115), +char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72), +char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67), +char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109), +char(95),char(115),char(111),char(102),char(116),char(75),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73), +char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111), +char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105), +char(116),char(0),char(109),char(95),char(109),char(97),char(120),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(116),char(105),char(109),char(101), +char(83),char(99),char(97),char(108),char(101),char(0),char(109),char(95),char(118),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(73),char(116),char(101),char(114), +char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(73),char(116),char(101), +char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(100),char(114),char(105),char(102),char(116),char(73),char(116),char(101),char(114),char(97), +char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(116),char(101),char(114),char(97), +char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(114),char(111),char(116),char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(101),char(0), +char(109),char(95),char(97),char(113),char(113),char(0),char(109),char(95),char(99),char(111),char(109),char(0),char(42),char(109),char(95),char(112),char(111),char(115),char(105),char(116), +char(105),char(111),char(110),char(115),char(0),char(42),char(109),char(95),char(119),char(101),char(105),char(103),char(104),char(116),char(115),char(0),char(109),char(95),char(110),char(117), +char(109),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(87),char(101),char(105),char(103), +char(116),char(115),char(0),char(109),char(95),char(98),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(98),char(102),char(114),char(97),char(109), +char(101),char(0),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(120),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(108),char(111),char(99), +char(105),char(105),char(0),char(109),char(95),char(105),char(110),char(118),char(119),char(105),char(0),char(109),char(95),char(118),char(105),char(109),char(112),char(117),char(108),char(115), +char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(91),char(50),char(93), +char(0),char(109),char(95),char(108),char(118),char(0),char(109),char(95),char(97),char(118),char(0),char(42),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(114), +char(101),char(102),char(115),char(0),char(42),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),char(115),char(0),char(42), +char(109),char(95),char(109),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(70),char(114),char(97),char(109),char(101),char(82), +char(101),char(102),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(78),char(111),char(100),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109), +char(77),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(105),char(100),char(109),char(97),char(115),char(115),char(0),char(109),char(95),char(105),char(109), +char(97),char(115),char(115),char(0),char(109),char(95),char(110),char(118),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110), +char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(100),char(97),char(109),char(112),char(105),char(110),char(103), +char(0),char(109),char(95),char(108),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(97),char(109),char(112),char(105), +char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(116),char(99),char(104),char(105),char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(120),char(83), +char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0), +char(109),char(95),char(115),char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108), +char(115),char(101),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(105),char(110),char(115),char(65), +char(110),char(99),char(104),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(100),char(101),char(0),char(109),char(95),char(99),char(108), +char(117),char(115),char(116),char(101),char(114),char(73),char(110),char(100),char(101),char(120),char(0),char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(65),char(0), +char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(0),char(109),char(95),char(114),char(101),char(102),char(115),char(91),char(50),char(93),char(0),char(109), +char(95),char(99),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(100),char(101),char(108),char(101),char(116), +char(101),char(0),char(109),char(95),char(114),char(101),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(91),char(50),char(93),char(0),char(109), +char(95),char(98),char(111),char(100),char(121),char(65),char(116),char(121),char(112),char(101),char(0),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(116),char(121), +char(112),char(101),char(0),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(112),char(111), +char(115),char(101),char(0),char(42),char(42),char(109),char(95),char(109),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(115),char(0),char(42),char(109),char(95), +char(110),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(108),char(105),char(110),char(107),char(115),char(0),char(42),char(109),char(95),char(102),char(97), +char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(116),char(101),char(116),char(114),char(97),char(104),char(101),char(100),char(114),char(97),char(0),char(42),char(109), +char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(42),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(115), +char(0),char(42),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(97),char(116),char(101), +char(114),char(105),char(97),char(108),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(76),char(105),char(110),char(107),char(115),char(0),char(109),char(95),char(110), +char(117),char(109),char(70),char(97),char(99),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(84),char(101),char(116),char(114),char(97),char(104),char(101), +char(100),char(114),char(97),char(0),char(109),char(95),char(110),char(117),char(109),char(65),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(109),char(95),char(110), +char(117),char(109),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(74),char(111),char(105),char(110), +char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(102),char(105),char(103),char(0),char(84),char(89),char(80),char(69),char(76),char(0),char(0),char(0), +char(99),char(104),char(97),char(114),char(0),char(117),char(99),char(104),char(97),char(114),char(0),char(115),char(104),char(111),char(114),char(116),char(0),char(117),char(115),char(104), +char(111),char(114),char(116),char(0),char(105),char(110),char(116),char(0),char(108),char(111),char(110),char(103),char(0),char(117),char(108),char(111),char(110),char(103),char(0),char(102), +char(108),char(111),char(97),char(116),char(0),char(100),char(111),char(117),char(98),char(108),char(101),char(0),char(118),char(111),char(105),char(100),char(0),char(80),char(111),char(105), +char(110),char(116),char(101),char(114),char(65),char(114),char(114),char(97),char(121),char(0),char(98),char(116),char(80),char(104),char(121),char(115),char(105),char(99),char(115),char(83), +char(121),char(115),char(116),char(101),char(109),char(0),char(76),char(105),char(115),char(116),char(66),char(97),char(115),char(101),char(0),char(98),char(116),char(86),char(101),char(99), +char(116),char(111),char(114),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(86),char(101),char(99),char(116), +char(111),char(114),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),char(114), +char(105),char(120),char(51),char(120),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116), +char(114),char(105),char(120),char(51),char(120),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84), +char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0), +char(98),char(116),char(66),char(118),char(104),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(70), +char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100), +char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(70),char(108),char(111),char(97),char(116), +char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(68), +char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111), +char(110),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(97),char(116),char(105),char(99),char(80), +char(108),char(97),char(110),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118), +char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0), +char(98),char(116),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(110),char(100),char(82),char(97),char(100),char(105),char(117),char(115),char(0), +char(98),char(116),char(77),char(117),char(108),char(116),char(105),char(83),char(112),char(104),char(101),char(114),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),char(108),char(101),char(116), +char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(104),char(97),char(114),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112), +char(108),char(101),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(114),char(105),char(100),char(105),char(110),char(103),char(77),char(101),char(115),char(104),char(73),char(110),char(116), +char(101),char(114),char(102),char(97),char(99),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), +char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105), +char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),char(77),char(97),char(112),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83), +char(99),char(97),char(108),char(101),char(100),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97), +char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),char(110),char(100),char(83),char(104),char(97), +char(112),char(101),char(67),char(104),char(105),char(108),char(100),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117), +char(110),char(100),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(121),char(108),char(105),char(110),char(100), +char(101),char(114),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(97),char(112),char(115),char(117),char(108), +char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), +char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(73),char(109),char(112),char(97),char(99),char(116),char(77), +char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),char(101), +char(120),char(72),char(117),char(108),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108), +char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116), +char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115), +char(87),char(111),char(114),char(108),char(100),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111), +char(110),char(116),char(97),char(99),char(116),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(68),char(111),char(117),char(98),char(108), +char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),char(87),char(111),char(114),char(108), +char(100),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), +char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0), +char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(110),char(102),char(111),char(49), +char(0),char(98),char(116),char(84),char(121),char(112),char(101),char(100),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(97),char(116),char(97),char(0),char(98), +char(116),char(80),char(111),char(105),char(110),char(116),char(50),char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), +char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(80),char(111),char(105),char(110),char(116),char(50), +char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108), +char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97), +char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103), +char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(67),char(111),char(110),char(101),char(84),char(119),char(105),char(115),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), +char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102), +char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110), +char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),char(83),char(112),char(114),char(105),char(110),char(103),char(67),char(111),char(110),char(115),char(116),char(114), +char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(108),char(105),char(100),char(101),char(114),char(67),char(111),char(110), +char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121), +char(77),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100), +char(121),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(76),char(105), +char(110),char(107),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(97),char(99),char(101),char(68), +char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(84),char(101),char(116),char(114),char(97),char(68),char(97),char(116), +char(97),char(0),char(83),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(65),char(110),char(99),char(104),char(111),char(114),char(68),char(97),char(116), +char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(111),char(110),char(102),char(105),char(103),char(68),char(97),char(116),char(97), +char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(80),char(111),char(115),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111), +char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(74),char(111),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(0),char(0), +char(84),char(76),char(69),char(78),char(1),char(0),char(1),char(0),char(2),char(0),char(2),char(0),char(4),char(0),char(4),char(0),char(4),char(0),char(4),char(0), +char(8),char(0),char(0),char(0),char(12),char(0),char(36),char(0),char(8),char(0),char(16),char(0),char(32),char(0),char(48),char(0),char(96),char(0),char(64),char(0), +char(-128),char(0),char(20),char(0),char(48),char(0),char(80),char(0),char(16),char(0),char(84),char(0),char(-124),char(0),char(12),char(0),char(52),char(0),char(52),char(0), +char(20),char(0),char(64),char(0),char(4),char(0),char(4),char(0),char(8),char(0),char(4),char(0),char(32),char(0),char(28),char(0),char(60),char(0),char(56),char(0), +char(76),char(0),char(76),char(0),char(24),char(0),char(60),char(0),char(60),char(0),char(16),char(0),char(64),char(0),char(68),char(0),char(-48),char(1),char(0),char(1), +char(-72),char(0),char(-104),char(0),char(104),char(0),char(88),char(0),char(-24),char(1),char(-96),char(3),char(8),char(0),char(52),char(0),char(0),char(0),char(84),char(0), +char(116),char(0),char(92),char(1),char(-36),char(0),char(-44),char(0),char(-4),char(0),char(92),char(1),char(-52),char(0),char(16),char(0),char(100),char(0),char(20),char(0), +char(36),char(0),char(100),char(0),char(92),char(0),char(104),char(0),char(-64),char(0),char(92),char(1),char(104),char(0),char(-84),char(1),char(83),char(84),char(82),char(67), +char(65),char(0),char(0),char(0),char(10),char(0),char(3),char(0),char(4),char(0),char(0),char(0),char(4),char(0),char(1),char(0),char(9),char(0),char(2),char(0), +char(11),char(0),char(3),char(0),char(10),char(0),char(3),char(0),char(10),char(0),char(4),char(0),char(10),char(0),char(5),char(0),char(12),char(0),char(2),char(0), +char(9),char(0),char(6),char(0),char(9),char(0),char(7),char(0),char(13),char(0),char(1),char(0),char(7),char(0),char(8),char(0),char(14),char(0),char(1),char(0), +char(8),char(0),char(8),char(0),char(15),char(0),char(1),char(0),char(13),char(0),char(9),char(0),char(16),char(0),char(1),char(0),char(14),char(0),char(9),char(0), +char(17),char(0),char(2),char(0),char(15),char(0),char(10),char(0),char(13),char(0),char(11),char(0),char(18),char(0),char(2),char(0),char(16),char(0),char(10),char(0), +char(14),char(0),char(11),char(0),char(19),char(0),char(4),char(0),char(4),char(0),char(12),char(0),char(4),char(0),char(13),char(0),char(2),char(0),char(14),char(0), +char(2),char(0),char(15),char(0),char(20),char(0),char(6),char(0),char(13),char(0),char(16),char(0),char(13),char(0),char(17),char(0),char(4),char(0),char(18),char(0), +char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),char(21),char(0),char(6),char(0),char(14),char(0),char(16),char(0), +char(14),char(0),char(17),char(0),char(4),char(0),char(18),char(0),char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0), +char(22),char(0),char(3),char(0),char(2),char(0),char(14),char(0),char(2),char(0),char(15),char(0),char(4),char(0),char(22),char(0),char(23),char(0),char(12),char(0), +char(13),char(0),char(23),char(0),char(13),char(0),char(24),char(0),char(13),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0), +char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),char(20),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(19),char(0),char(32),char(0), +char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(24),char(0),char(12),char(0),char(14),char(0),char(23),char(0),char(14),char(0),char(24),char(0), +char(14),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0), +char(21),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(19),char(0),char(32),char(0), +char(25),char(0),char(3),char(0),char(0),char(0),char(35),char(0),char(4),char(0),char(36),char(0),char(0),char(0),char(37),char(0),char(26),char(0),char(5),char(0), +char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(40),char(0),char(7),char(0),char(41),char(0),char(0),char(0),char(21),char(0), +char(27),char(0),char(5),char(0),char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(42),char(0),char(7),char(0),char(43),char(0), +char(4),char(0),char(44),char(0),char(28),char(0),char(2),char(0),char(13),char(0),char(45),char(0),char(7),char(0),char(46),char(0),char(29),char(0),char(4),char(0), +char(27),char(0),char(47),char(0),char(28),char(0),char(48),char(0),char(4),char(0),char(49),char(0),char(0),char(0),char(37),char(0),char(30),char(0),char(1),char(0), +char(4),char(0),char(50),char(0),char(31),char(0),char(2),char(0),char(2),char(0),char(50),char(0),char(0),char(0),char(51),char(0),char(32),char(0),char(2),char(0), +char(2),char(0),char(52),char(0),char(0),char(0),char(51),char(0),char(33),char(0),char(2),char(0),char(0),char(0),char(52),char(0),char(0),char(0),char(53),char(0), +char(34),char(0),char(8),char(0),char(13),char(0),char(54),char(0),char(14),char(0),char(55),char(0),char(30),char(0),char(56),char(0),char(32),char(0),char(57),char(0), +char(33),char(0),char(58),char(0),char(31),char(0),char(59),char(0),char(4),char(0),char(60),char(0),char(4),char(0),char(61),char(0),char(35),char(0),char(4),char(0), +char(34),char(0),char(62),char(0),char(13),char(0),char(63),char(0),char(4),char(0),char(64),char(0),char(0),char(0),char(37),char(0),char(36),char(0),char(7),char(0), +char(25),char(0),char(38),char(0),char(35),char(0),char(65),char(0),char(23),char(0),char(66),char(0),char(24),char(0),char(67),char(0),char(37),char(0),char(68),char(0), +char(7),char(0),char(43),char(0),char(0),char(0),char(69),char(0),char(38),char(0),char(2),char(0),char(36),char(0),char(70),char(0),char(13),char(0),char(39),char(0), +char(39),char(0),char(4),char(0),char(17),char(0),char(71),char(0),char(25),char(0),char(72),char(0),char(4),char(0),char(73),char(0),char(7),char(0),char(74),char(0), +char(40),char(0),char(4),char(0),char(25),char(0),char(38),char(0),char(39),char(0),char(75),char(0),char(4),char(0),char(76),char(0),char(7),char(0),char(43),char(0), +char(41),char(0),char(3),char(0),char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(42),char(0),char(3),char(0), +char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(43),char(0),char(4),char(0),char(4),char(0),char(78),char(0), +char(7),char(0),char(79),char(0),char(7),char(0),char(80),char(0),char(7),char(0),char(81),char(0),char(37),char(0),char(14),char(0),char(4),char(0),char(82),char(0), +char(4),char(0),char(83),char(0),char(43),char(0),char(84),char(0),char(4),char(0),char(85),char(0),char(7),char(0),char(86),char(0),char(7),char(0),char(87),char(0), +char(7),char(0),char(88),char(0),char(7),char(0),char(89),char(0),char(7),char(0),char(90),char(0),char(4),char(0),char(91),char(0),char(4),char(0),char(92),char(0), +char(4),char(0),char(93),char(0),char(4),char(0),char(94),char(0),char(0),char(0),char(37),char(0),char(44),char(0),char(5),char(0),char(25),char(0),char(38),char(0), +char(35),char(0),char(65),char(0),char(13),char(0),char(39),char(0),char(7),char(0),char(43),char(0),char(4),char(0),char(95),char(0),char(45),char(0),char(5),char(0), +char(27),char(0),char(47),char(0),char(13),char(0),char(96),char(0),char(14),char(0),char(97),char(0),char(4),char(0),char(98),char(0),char(0),char(0),char(99),char(0), +char(46),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),char(0),char(0),char(35),char(0), +char(18),char(0),char(103),char(0),char(18),char(0),char(104),char(0),char(14),char(0),char(105),char(0),char(14),char(0),char(106),char(0),char(14),char(0),char(107),char(0), +char(8),char(0),char(108),char(0),char(8),char(0),char(109),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(111),char(0),char(8),char(0),char(112),char(0), +char(8),char(0),char(113),char(0),char(8),char(0),char(114),char(0),char(8),char(0),char(115),char(0),char(4),char(0),char(116),char(0),char(4),char(0),char(117),char(0), +char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),char(4),char(0),char(122),char(0), +char(0),char(0),char(37),char(0),char(47),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0), +char(0),char(0),char(35),char(0),char(17),char(0),char(103),char(0),char(17),char(0),char(104),char(0),char(13),char(0),char(105),char(0),char(13),char(0),char(106),char(0), +char(13),char(0),char(107),char(0),char(7),char(0),char(108),char(0),char(7),char(0),char(109),char(0),char(7),char(0),char(110),char(0),char(7),char(0),char(111),char(0), +char(7),char(0),char(112),char(0),char(7),char(0),char(113),char(0),char(7),char(0),char(114),char(0),char(7),char(0),char(115),char(0),char(4),char(0),char(116),char(0), +char(4),char(0),char(117),char(0),char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0), +char(4),char(0),char(122),char(0),char(0),char(0),char(37),char(0),char(48),char(0),char(2),char(0),char(49),char(0),char(123),char(0),char(14),char(0),char(124),char(0), +char(50),char(0),char(2),char(0),char(51),char(0),char(123),char(0),char(13),char(0),char(124),char(0),char(52),char(0),char(21),char(0),char(47),char(0),char(125),char(0), +char(15),char(0),char(126),char(0),char(13),char(0),char(127),char(0),char(13),char(0),char(-128),char(0),char(13),char(0),char(-127),char(0),char(13),char(0),char(-126),char(0), +char(13),char(0),char(124),char(0),char(13),char(0),char(-125),char(0),char(13),char(0),char(-124),char(0),char(13),char(0),char(-123),char(0),char(13),char(0),char(-122),char(0), +char(7),char(0),char(-121),char(0),char(7),char(0),char(-120),char(0),char(7),char(0),char(-119),char(0),char(7),char(0),char(-118),char(0),char(7),char(0),char(-117),char(0), +char(7),char(0),char(-116),char(0),char(7),char(0),char(-115),char(0),char(7),char(0),char(-114),char(0),char(7),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0), +char(53),char(0),char(22),char(0),char(46),char(0),char(125),char(0),char(16),char(0),char(126),char(0),char(14),char(0),char(127),char(0),char(14),char(0),char(-128),char(0), +char(14),char(0),char(-127),char(0),char(14),char(0),char(-126),char(0),char(14),char(0),char(124),char(0),char(14),char(0),char(-125),char(0),char(14),char(0),char(-124),char(0), +char(14),char(0),char(-123),char(0),char(14),char(0),char(-122),char(0),char(8),char(0),char(-121),char(0),char(8),char(0),char(-120),char(0),char(8),char(0),char(-119),char(0), +char(8),char(0),char(-118),char(0),char(8),char(0),char(-117),char(0),char(8),char(0),char(-116),char(0),char(8),char(0),char(-115),char(0),char(8),char(0),char(-114),char(0), +char(8),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),char(0),char(0),char(37),char(0),char(54),char(0),char(2),char(0),char(4),char(0),char(-111),char(0), +char(4),char(0),char(-110),char(0),char(55),char(0),char(13),char(0),char(56),char(0),char(-109),char(0),char(56),char(0),char(-108),char(0),char(0),char(0),char(35),char(0), +char(4),char(0),char(-107),char(0),char(4),char(0),char(-106),char(0),char(4),char(0),char(-105),char(0),char(4),char(0),char(-104),char(0),char(7),char(0),char(-103),char(0), +char(7),char(0),char(-102),char(0),char(4),char(0),char(-101),char(0),char(4),char(0),char(-100),char(0),char(7),char(0),char(-99),char(0),char(4),char(0),char(-98),char(0), +char(57),char(0),char(3),char(0),char(55),char(0),char(-97),char(0),char(13),char(0),char(-96),char(0),char(13),char(0),char(-95),char(0),char(58),char(0),char(3),char(0), +char(55),char(0),char(-97),char(0),char(14),char(0),char(-96),char(0),char(14),char(0),char(-95),char(0),char(59),char(0),char(13),char(0),char(55),char(0),char(-97),char(0), +char(18),char(0),char(-94),char(0),char(18),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0), +char(7),char(0),char(-89),char(0),char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0), +char(7),char(0),char(-84),char(0),char(7),char(0),char(-83),char(0),char(60),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0), +char(17),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),char(7),char(0),char(-89),char(0), +char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), +char(7),char(0),char(-83),char(0),char(61),char(0),char(11),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0), +char(7),char(0),char(-82),char(0),char(7),char(0),char(-81),char(0),char(7),char(0),char(-80),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), +char(7),char(0),char(-83),char(0),char(7),char(0),char(-79),char(0),char(0),char(0),char(21),char(0),char(62),char(0),char(9),char(0),char(55),char(0),char(-97),char(0), +char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(13),char(0),char(-78),char(0),char(13),char(0),char(-77),char(0),char(13),char(0),char(-76),char(0), +char(13),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(63),char(0),char(5),char(0),char(62),char(0),char(-72),char(0), +char(4),char(0),char(-71),char(0),char(7),char(0),char(-70),char(0),char(7),char(0),char(-69),char(0),char(7),char(0),char(-68),char(0),char(64),char(0),char(9),char(0), +char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(7),char(0),char(-78),char(0),char(7),char(0),char(-77),char(0), +char(7),char(0),char(-76),char(0),char(7),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(49),char(0),char(22),char(0), +char(8),char(0),char(-67),char(0),char(8),char(0),char(-79),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(-66),char(0),char(8),char(0),char(112),char(0), +char(8),char(0),char(-65),char(0),char(8),char(0),char(-64),char(0),char(8),char(0),char(-63),char(0),char(8),char(0),char(-62),char(0),char(8),char(0),char(-61),char(0), +char(8),char(0),char(-60),char(0),char(8),char(0),char(-59),char(0),char(8),char(0),char(-58),char(0),char(8),char(0),char(-57),char(0),char(8),char(0),char(-56),char(0), +char(8),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0), +char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),char(51),char(0),char(22),char(0),char(7),char(0),char(-67),char(0),char(7),char(0),char(-79),char(0), +char(7),char(0),char(110),char(0),char(7),char(0),char(-66),char(0),char(7),char(0),char(112),char(0),char(7),char(0),char(-65),char(0),char(7),char(0),char(-64),char(0), +char(7),char(0),char(-63),char(0),char(7),char(0),char(-62),char(0),char(7),char(0),char(-61),char(0),char(7),char(0),char(-60),char(0),char(7),char(0),char(-59),char(0), +char(7),char(0),char(-58),char(0),char(7),char(0),char(-57),char(0),char(7),char(0),char(-56),char(0),char(7),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0), +char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0), +char(65),char(0),char(4),char(0),char(7),char(0),char(-49),char(0),char(7),char(0),char(-48),char(0),char(7),char(0),char(-47),char(0),char(4),char(0),char(78),char(0), +char(66),char(0),char(10),char(0),char(65),char(0),char(-46),char(0),char(13),char(0),char(-45),char(0),char(13),char(0),char(-44),char(0),char(13),char(0),char(-43),char(0), +char(13),char(0),char(-42),char(0),char(13),char(0),char(-41),char(0),char(7),char(0),char(-121),char(0),char(7),char(0),char(-40),char(0),char(4),char(0),char(-39),char(0), +char(4),char(0),char(53),char(0),char(67),char(0),char(4),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-38),char(0),char(7),char(0),char(-37),char(0), +char(4),char(0),char(-36),char(0),char(68),char(0),char(4),char(0),char(13),char(0),char(-41),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-35),char(0), +char(7),char(0),char(-34),char(0),char(69),char(0),char(7),char(0),char(13),char(0),char(-33),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-32),char(0), +char(7),char(0),char(-31),char(0),char(7),char(0),char(-30),char(0),char(7),char(0),char(-29),char(0),char(4),char(0),char(53),char(0),char(70),char(0),char(6),char(0), +char(15),char(0),char(-28),char(0),char(13),char(0),char(-30),char(0),char(13),char(0),char(-27),char(0),char(56),char(0),char(-26),char(0),char(4),char(0),char(-25),char(0), +char(7),char(0),char(-29),char(0),char(71),char(0),char(26),char(0),char(4),char(0),char(-24),char(0),char(7),char(0),char(-23),char(0),char(7),char(0),char(-79),char(0), +char(7),char(0),char(-22),char(0),char(7),char(0),char(-21),char(0),char(7),char(0),char(-20),char(0),char(7),char(0),char(-19),char(0),char(7),char(0),char(-18),char(0), +char(7),char(0),char(-17),char(0),char(7),char(0),char(-16),char(0),char(7),char(0),char(-15),char(0),char(7),char(0),char(-14),char(0),char(7),char(0),char(-13),char(0), +char(7),char(0),char(-12),char(0),char(7),char(0),char(-11),char(0),char(7),char(0),char(-10),char(0),char(7),char(0),char(-9),char(0),char(7),char(0),char(-8),char(0), +char(7),char(0),char(-7),char(0),char(7),char(0),char(-6),char(0),char(7),char(0),char(-5),char(0),char(4),char(0),char(-4),char(0),char(4),char(0),char(-3),char(0), +char(4),char(0),char(-2),char(0),char(4),char(0),char(-1),char(0),char(4),char(0),char(117),char(0),char(72),char(0),char(12),char(0),char(15),char(0),char(0),char(1), +char(15),char(0),char(1),char(1),char(15),char(0),char(2),char(1),char(13),char(0),char(3),char(1),char(13),char(0),char(4),char(1),char(7),char(0),char(5),char(1), +char(4),char(0),char(6),char(1),char(4),char(0),char(7),char(1),char(4),char(0),char(8),char(1),char(4),char(0),char(9),char(1),char(7),char(0),char(-31),char(0), +char(4),char(0),char(53),char(0),char(73),char(0),char(27),char(0),char(17),char(0),char(10),char(1),char(15),char(0),char(11),char(1),char(15),char(0),char(12),char(1), +char(13),char(0),char(3),char(1),char(13),char(0),char(13),char(1),char(13),char(0),char(14),char(1),char(13),char(0),char(15),char(1),char(13),char(0),char(16),char(1), +char(13),char(0),char(17),char(1),char(4),char(0),char(18),char(1),char(7),char(0),char(19),char(1),char(4),char(0),char(20),char(1),char(4),char(0),char(21),char(1), +char(4),char(0),char(22),char(1),char(7),char(0),char(23),char(1),char(7),char(0),char(24),char(1),char(4),char(0),char(25),char(1),char(4),char(0),char(26),char(1), +char(7),char(0),char(27),char(1),char(7),char(0),char(28),char(1),char(7),char(0),char(29),char(1),char(7),char(0),char(30),char(1),char(7),char(0),char(31),char(1), +char(7),char(0),char(32),char(1),char(4),char(0),char(33),char(1),char(4),char(0),char(34),char(1),char(4),char(0),char(35),char(1),char(74),char(0),char(12),char(0), +char(9),char(0),char(36),char(1),char(9),char(0),char(37),char(1),char(13),char(0),char(38),char(1),char(7),char(0),char(39),char(1),char(7),char(0),char(-63),char(0), +char(7),char(0),char(40),char(1),char(4),char(0),char(41),char(1),char(13),char(0),char(42),char(1),char(4),char(0),char(43),char(1),char(4),char(0),char(44),char(1), +char(4),char(0),char(45),char(1),char(4),char(0),char(53),char(0),char(75),char(0),char(19),char(0),char(47),char(0),char(125),char(0),char(72),char(0),char(46),char(1), +char(65),char(0),char(47),char(1),char(66),char(0),char(48),char(1),char(67),char(0),char(49),char(1),char(68),char(0),char(50),char(1),char(69),char(0),char(51),char(1), +char(70),char(0),char(52),char(1),char(73),char(0),char(53),char(1),char(74),char(0),char(54),char(1),char(4),char(0),char(55),char(1),char(4),char(0),char(21),char(1), +char(4),char(0),char(56),char(1),char(4),char(0),char(57),char(1),char(4),char(0),char(58),char(1),char(4),char(0),char(59),char(1),char(4),char(0),char(60),char(1), +char(4),char(0),char(61),char(1),char(71),char(0),char(62),char(1),}; +int sBulletDNAlen= sizeof(sBulletDNAstr); +char sBulletDNAstr64[]= { +char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(63),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109), +char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95), +char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(115),char(0),char(109),char(95),char(99),char(111), +char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110), +char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(115),char(0),char(42),char(102),char(105),char(114),char(115),char(116),char(0),char(42),char(108),char(97),char(115), +char(116),char(0),char(109),char(95),char(102),char(108),char(111),char(97),char(116),char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(108),char(91),char(51), +char(93),char(0),char(109),char(95),char(98),char(97),char(115),char(105),char(115),char(0),char(109),char(95),char(111),char(114),char(105),char(103),char(105),char(110),char(0),char(109), +char(95),char(114),char(111),char(111),char(116),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98), +char(116),char(114),char(101),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100), +char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(91),char(51),char(93),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122), +char(101),char(100),char(65),char(97),char(98),char(98),char(77),char(97),char(120),char(91),char(51),char(93),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77), +char(105),char(110),char(79),char(114),char(103),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),char(97),char(120),char(79),char(114),char(103),char(0),char(109), +char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),char(80),char(97), +char(114),char(116),char(0),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109), +char(95),char(112),char(97),char(100),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101), +char(120),char(79),char(114),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(98), +char(118),char(104),char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(0),char(109),char(95),char(98),char(118),char(104),char(65),char(97),char(98),char(98),char(77), +char(97),char(120),char(0),char(109),char(95),char(98),char(118),char(104),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110), +char(0),char(109),char(95),char(99),char(117),char(114),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(117),char(115), +char(101),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(110),char(117),char(109),char(67), +char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(76),char(101),char(97),char(102),char(78),char(111),char(100),char(101),char(115),char(0),char(109), +char(95),char(110),char(117),char(109),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117), +char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(99),char(111),char(110),char(116),char(105),char(103),char(117),char(111), +char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105), +char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116), +char(114),char(0),char(42),char(109),char(95),char(115),char(117),char(98),char(84),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(80),char(116),char(114),char(0), +char(109),char(95),char(116),char(114),char(97),char(118),char(101),char(114),char(115),char(97),char(108),char(77),char(111),char(100),char(101),char(0),char(109),char(95),char(110),char(117), +char(109),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(72),char(101),char(97),char(100),char(101),char(114),char(115),char(0),char(42),char(109),char(95),char(110), +char(97),char(109),char(101),char(0),char(109),char(95),char(115),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(112),char(97), +char(100),char(100),char(105),char(110),char(103),char(91),char(52),char(93),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110), +char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(83),char(99),char(97), +char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(101),char(78),char(111),char(114),char(109),char(97),char(108),char(0),char(109), +char(95),char(112),char(108),char(97),char(110),char(101),char(67),char(111),char(110),char(115),char(116),char(97),char(110),char(116),char(0),char(109),char(95),char(105),char(109),char(112), +char(108),char(105),char(99),char(105),char(116),char(83),char(104),char(97),char(112),char(101),char(68),char(105),char(109),char(101),char(110),char(115),char(105),char(111),char(110),char(115), +char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(109), +char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(111),char(115),char(0),char(109),char(95),char(114),char(97),char(100), +char(105),char(117),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108), +char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(42),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(80),char(111), +char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(108),char(111),char(99), +char(97),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(83),char(105),char(122),char(101),char(0), +char(109),char(95),char(118),char(97),char(108),char(117),char(101),char(0),char(109),char(95),char(112),char(97),char(100),char(91),char(50),char(93),char(0),char(109),char(95),char(118), +char(97),char(108),char(117),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(112),char(97),char(100),char(0),char(42),char(109),char(95),char(118),char(101), +char(114),char(116),char(105),char(99),char(101),char(115),char(51),char(102),char(0),char(42),char(109),char(95),char(118),char(101),char(114),char(116),char(105),char(99),char(101),char(115), +char(51),char(100),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(51),char(50),char(0),char(42),char(109),char(95),char(51), +char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(42),char(109),char(95),char(51),char(105),char(110),char(100),char(105),char(99),char(101), +char(115),char(56),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(109),char(95),char(110),char(117), +char(109),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(86),char(101),char(114),char(116), +char(105),char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(109),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(115),char(80),char(116),char(114), +char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(101),char(115),char(104), +char(80),char(97),char(114),char(116),char(115),char(0),char(109),char(95),char(109),char(101),char(115),char(104),char(73),char(110),char(116),char(101),char(114),char(102),char(97),char(99), +char(101),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(70),char(108),char(111),char(97),char(116),char(66), +char(118),char(104),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(68),char(111),char(117),char(98),char(108), +char(101),char(66),char(118),char(104),char(0),char(42),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111), +char(77),char(97),char(112),char(0),char(109),char(95),char(112),char(97),char(100),char(51),char(91),char(52),char(93),char(0),char(109),char(95),char(116),char(114),char(105),char(109), +char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(116),char(114),char(97),char(110),char(115), +char(102),char(111),char(114),char(109),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(0),char(109), +char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(99),char(104), +char(105),char(108),char(100),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104), +char(97),char(112),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(67),char(104),char(105),char(108),char(100),char(83),char(104),char(97), +char(112),char(101),char(115),char(0),char(109),char(95),char(117),char(112),char(65),char(120),char(105),char(115),char(0),char(109),char(95),char(102),char(108),char(97),char(103),char(115), +char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),char(48),char(86),char(49),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101), +char(100),char(103),char(101),char(86),char(49),char(86),char(50),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86), +char(50),char(86),char(48),char(65),char(110),char(103),char(108),char(101),char(0),char(42),char(109),char(95),char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108), +char(101),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(110),char(101),char(120),char(116),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(118), +char(97),char(108),char(117),char(101),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(107),char(101),char(121),char(65), +char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(69),char(112),char(115),char(105), +char(108),char(111),char(110),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(97),char(114),char(69),char(112),char(115),char(105),char(108),char(111),char(110),char(0), +char(109),char(95),char(101),char(113),char(117),char(97),char(108),char(86),char(101),char(114),char(116),char(101),char(120),char(84),char(104),char(114),char(101),char(115),char(104),char(111), +char(108),char(100),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(68),char(105),char(115),char(116),char(97),char(110),char(99),char(101),char(84),char(104),char(114), +char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(122),char(101),char(114),char(111),char(65),char(114),char(101),char(97),char(84),char(104),char(114), +char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(101),char(120),char(116),char(83),char(105),char(122),char(101),char(0),char(109),char(95), +char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(110),char(117),char(109),char(86), +char(97),char(108),char(117),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(75),char(101),char(121),char(115),char(0),char(109),char(95),char(103),char(105), +char(109),char(112),char(97),char(99),char(116),char(83),char(117),char(98),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(117),char(110),char(115),char(99), +char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(70),char(108),char(111),char(97),char(116),char(80),char(116),char(114),char(0),char(42), +char(109),char(95),char(117),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(68),char(111),char(117),char(98), +char(108),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(85),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80), +char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(51),char(91),char(52),char(93),char(0), +char(42),char(109),char(95),char(98),char(114),char(111),char(97),char(100),char(112),char(104),char(97),char(115),char(101),char(72),char(97),char(110),char(100),char(108),char(101),char(0), +char(42),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),char(42),char(109), +char(95),char(114),char(111),char(111),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0), +char(109),char(95),char(119),char(111),char(114),char(108),char(100),char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105), +char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(87),char(111),char(114),char(108),char(100),char(84),char(114),char(97), +char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105), +char(111),char(110),char(76),char(105),char(110),char(101),char(97),char(114),char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(105), +char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(86), +char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105), +char(99),char(70),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(99),char(116),char(80), +char(114),char(111),char(99),char(101),char(115),char(115),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(100),char(101),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),char(84),char(105),char(109),char(101),char(0),char(109),char(95), +char(102),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114), +char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110), +char(0),char(109),char(95),char(104),char(105),char(116),char(70),char(114),char(97),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(99),char(100), +char(83),char(119),char(101),char(112),char(116),char(83),char(112),char(104),char(101),char(114),char(101),char(82),char(97),char(100),char(105),char(117),char(115),char(0),char(109),char(95), +char(99),char(99),char(100),char(77),char(111),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(104),char(97),char(115),char(65),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),char(99),char(70),char(114),char(105),char(99),char(116), +char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(70),char(108),char(97),char(103),char(115), +char(0),char(109),char(95),char(105),char(115),char(108),char(97),char(110),char(100),char(84),char(97),char(103),char(49),char(0),char(109),char(95),char(99),char(111),char(109),char(112), +char(97),char(110),char(105),char(111),char(110),char(73),char(100),char(0),char(109),char(95),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110), +char(83),char(116),char(97),char(116),char(101),char(49),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(84),char(121),char(112), +char(101),char(0),char(109),char(95),char(99),char(104),char(101),char(99),char(107),char(67),char(111),char(108),char(108),char(105),char(100),char(101),char(87),char(105),char(116),char(104), +char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(0),char(109),char(95),char(103),char(114),char(97),char(118), +char(105),char(116),char(121),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99), +char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(84),char(101), +char(110),char(115),char(111),char(114),char(87),char(111),char(114),char(108),char(100),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(86),char(101), +char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(86),char(101),char(108),char(111), +char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114), +char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(103),char(114), +char(97),char(118),char(105),char(116),char(121),char(95),char(97),char(99),char(99),char(101),char(108),char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(0),char(109), +char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(76),char(111),char(99),char(97),char(108),char(0),char(109),char(95),char(116), +char(111),char(116),char(97),char(108),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(116),char(111),char(116),char(97),char(108),char(84),char(111),char(114), +char(113),char(117),char(101),char(0),char(109),char(95),char(105),char(110),char(118),char(101),char(114),char(115),char(101),char(77),char(97),char(115),char(115),char(0),char(109),char(95), +char(108),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(110),char(103),char(117), +char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111), +char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(97), +char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(76),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105), +char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100), +char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110), +char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),char(105), +char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103), +char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(101),char(101),char(112), +char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108), +char(97),char(114),char(83),char(108),char(101),char(101),char(112),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0), +char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0), +char(109),char(95),char(110),char(117),char(109),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(82),char(111),char(119),char(115),char(0), +char(110),char(117),char(98),char(0),char(42),char(109),char(95),char(114),char(98),char(65),char(0),char(42),char(109),char(95),char(114),char(98),char(66),char(0),char(109),char(95), +char(111),char(98),char(106),char(101),char(99),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),char(110), +char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111), +char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(100),char(0),char(109),char(95),char(110),char(101),char(101),char(100),char(115),char(70),char(101), +char(101),char(100),char(98),char(97),char(99),char(107),char(0),char(109),char(95),char(97),char(112),char(112),char(108),char(105),char(101),char(100),char(73),char(109),char(112),char(117), +char(108),char(115),char(101),char(0),char(109),char(95),char(100),char(98),char(103),char(68),char(114),char(97),char(119),char(83),char(105),char(122),char(101),char(0),char(109),char(95), +char(100),char(105),char(115),char(97),char(98),char(108),char(101),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(115),char(66),char(101),char(116), +char(119),char(101),char(101),char(110),char(76),char(105),char(110),char(107),char(101),char(100),char(66),char(111),char(100),char(105),char(101),char(115),char(0),char(109),char(95),char(111), +char(118),char(101),char(114),char(114),char(105),char(100),char(101),char(78),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(116),char(101),char(114), +char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(98),char(114),char(101),char(97),char(107),char(105),char(110),char(103),char(73),char(109),char(112), +char(117),char(108),char(115),char(101),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(105),char(115),char(69),char(110), +char(97),char(98),char(108),char(101),char(100),char(0),char(109),char(95),char(116),char(121),char(112),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), +char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(65),char(0),char(109),char(95), +char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(66),char(0),char(109),char(95),char(114),char(98),char(65),char(70),char(114),char(97),char(109),char(101),char(0), +char(109),char(95),char(114),char(98),char(66),char(70),char(114),char(97),char(109),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(82),char(101),char(102),char(101), +char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97), +char(114),char(79),char(110),char(108),char(121),char(0),char(109),char(95),char(101),char(110),char(97),char(98),char(108),char(101),char(65),char(110),char(103),char(117),char(108),char(97), +char(114),char(77),char(111),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(111),char(116),char(111),char(114),char(84),char(97),char(114),char(103),char(101),char(116), +char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(109),char(97),char(120),char(77),char(111),char(116),char(111),char(114),char(73), +char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),char(95),char(108),char(111),char(119),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0), +char(109),char(95),char(117),char(112),char(112),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(109),char(105),char(116), +char(83),char(111),char(102),char(116),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(98),char(105),char(97),char(115),char(70),char(97),char(99),char(116),char(111), +char(114),char(0),char(109),char(95),char(114),char(101),char(108),char(97),char(120),char(97),char(116),char(105),char(111),char(110),char(70),char(97),char(99),char(116),char(111),char(114), +char(0),char(109),char(95),char(115),char(119),char(105),char(110),char(103),char(83),char(112),char(97),char(110),char(49),char(0),char(109),char(95),char(115),char(119),char(105),char(110), +char(103),char(83),char(112),char(97),char(110),char(50),char(0),char(109),char(95),char(116),char(119),char(105),char(115),char(116),char(83),char(112),char(97),char(110),char(0),char(109), +char(95),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(85),char(112),char(112), +char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(76),char(111),char(119),char(101), +char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(85),char(112),char(112),char(101), +char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(76),char(111),char(119),char(101), +char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(117),char(115),char(101),char(76),char(105),char(110),char(101),char(97),char(114),char(82),char(101), +char(102),char(101),char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(117),char(115),char(101),char(79), +char(102),char(102),char(115),char(101),char(116),char(70),char(111),char(114),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(114), +char(97),char(109),char(101),char(0),char(109),char(95),char(54),char(100),char(111),char(102),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(115),char(112),char(114), +char(105),char(110),char(103),char(69),char(110),char(97),char(98),char(108),char(101),char(100),char(91),char(54),char(93),char(0),char(109),char(95),char(101),char(113),char(117),char(105), +char(108),char(105),char(98),char(114),char(105),char(117),char(109),char(80),char(111),char(105),char(110),char(116),char(91),char(54),char(93),char(0),char(109),char(95),char(115),char(112), +char(114),char(105),char(110),char(103),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(91),char(54),char(93),char(0),char(109),char(95),char(115), +char(112),char(114),char(105),char(110),char(103),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(91),char(54),char(93),char(0),char(109),char(95),char(116),char(97), +char(117),char(0),char(109),char(95),char(116),char(105),char(109),char(101),char(83),char(116),char(101),char(112),char(0),char(109),char(95),char(109),char(97),char(120),char(69),char(114), +char(114),char(111),char(114),char(82),char(101),char(100),char(117),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(115),char(111),char(114),char(0),char(109), +char(95),char(101),char(114),char(112),char(0),char(109),char(95),char(101),char(114),char(112),char(50),char(0),char(109),char(95),char(103),char(108),char(111),char(98),char(97),char(108), +char(67),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(80),char(101), +char(110),char(101),char(116),char(114),char(97),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(84),char(117),char(114),char(110),char(69),char(114),char(112), +char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(111),char(112),char(0),char(109),char(95),char(119),char(97),char(114),char(109), +char(115),char(116),char(97),char(114),char(116),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(97),char(120), +char(71),char(121),char(114),char(111),char(115),char(99),char(111),char(112),char(105),char(99),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(115),char(105), +char(110),char(103),char(108),char(101),char(65),char(120),char(105),char(115),char(82),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),char(105),char(99),char(116), +char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(117),char(109),char(73),char(116), +char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(77),char(111),char(100), +char(101),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(110),char(103),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(82),char(101), +char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), +char(95),char(109),char(105),char(110),char(105),char(109),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(66),char(97),char(116),char(99),char(104),char(83), +char(105),char(122),char(101),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109), +char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97), +char(110),char(103),char(117),char(108),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(118),char(111), +char(108),char(117),char(109),char(101),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(42),char(109),char(95),char(109),char(97),char(116), +char(101),char(114),char(105),char(97),char(108),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112), +char(114),char(101),char(118),char(105),char(111),char(117),char(115),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(118),char(101), +char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(99),char(99),char(117),char(109),char(117),char(108),char(97),char(116),char(101),char(100), +char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(110),char(111),char(114),char(109),char(97),char(108),char(0),char(109),char(95),char(97),char(114),char(101), +char(97),char(0),char(109),char(95),char(97),char(116),char(116),char(97),char(99),char(104),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100), +char(105),char(99),char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(76),char(101),char(110),char(103),char(116),char(104), +char(0),char(109),char(95),char(98),char(98),char(101),char(110),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110), +char(100),char(105),char(99),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(65),char(114),char(101),char(97),char(0), +char(109),char(95),char(99),char(48),char(91),char(52),char(93),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101), +char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95), +char(99),char(49),char(0),char(109),char(95),char(99),char(50),char(0),char(109),char(95),char(99),char(48),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108), +char(70),char(114),char(97),char(109),char(101),char(0),char(42),char(109),char(95),char(114),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(0),char(109), +char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(97),char(101),char(114),char(111),char(77),char(111),char(100), +char(101),char(108),char(0),char(109),char(95),char(98),char(97),char(117),char(109),char(103),char(97),char(114),char(116),char(101),char(0),char(109),char(95),char(100),char(114),char(97), +char(103),char(0),char(109),char(95),char(108),char(105),char(102),char(116),char(0),char(109),char(95),char(112),char(114),char(101),char(115),char(115),char(117),char(114),char(101),char(0), +char(109),char(95),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(100),char(121),char(110),char(97),char(109),char(105),char(99),char(70),char(114), +char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),char(111),char(115),char(101),char(77),char(97),char(116),char(99),char(104),char(0),char(109), +char(95),char(114),char(105),char(103),char(105),char(100),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),char(114),char(100),char(110),char(101),char(115), +char(115),char(0),char(109),char(95),char(107),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97), +char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), +char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(72),char(97),char(114), +char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),char(108),char(117), +char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(75), +char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115), +char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72), +char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67), +char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109), +char(95),char(115),char(111),char(102),char(116),char(75),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73), +char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111), +char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105), +char(116),char(0),char(109),char(95),char(109),char(97),char(120),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(116),char(105),char(109),char(101), +char(83),char(99),char(97),char(108),char(101),char(0),char(109),char(95),char(118),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(73),char(116),char(101),char(114), +char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(73),char(116),char(101), +char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(100),char(114),char(105),char(102),char(116),char(73),char(116),char(101),char(114),char(97), +char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(116),char(101),char(114),char(97), +char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(114),char(111),char(116),char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(101),char(0), +char(109),char(95),char(97),char(113),char(113),char(0),char(109),char(95),char(99),char(111),char(109),char(0),char(42),char(109),char(95),char(112),char(111),char(115),char(105),char(116), +char(105),char(111),char(110),char(115),char(0),char(42),char(109),char(95),char(119),char(101),char(105),char(103),char(104),char(116),char(115),char(0),char(109),char(95),char(110),char(117), +char(109),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(87),char(101),char(105),char(103), +char(116),char(115),char(0),char(109),char(95),char(98),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(98),char(102),char(114),char(97),char(109), +char(101),char(0),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(120),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(108),char(111),char(99), +char(105),char(105),char(0),char(109),char(95),char(105),char(110),char(118),char(119),char(105),char(0),char(109),char(95),char(118),char(105),char(109),char(112),char(117),char(108),char(115), +char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(91),char(50),char(93), +char(0),char(109),char(95),char(108),char(118),char(0),char(109),char(95),char(97),char(118),char(0),char(42),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(114), +char(101),char(102),char(115),char(0),char(42),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),char(115),char(0),char(42), +char(109),char(95),char(109),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(70),char(114),char(97),char(109),char(101),char(82), +char(101),char(102),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(78),char(111),char(100),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109), +char(77),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(105),char(100),char(109),char(97),char(115),char(115),char(0),char(109),char(95),char(105),char(109), +char(97),char(115),char(115),char(0),char(109),char(95),char(110),char(118),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110), +char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(100),char(97),char(109),char(112),char(105),char(110),char(103), +char(0),char(109),char(95),char(108),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(97),char(109),char(112),char(105), +char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(116),char(99),char(104),char(105),char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(120),char(83), +char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0), +char(109),char(95),char(115),char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108), +char(115),char(101),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(105),char(110),char(115),char(65), +char(110),char(99),char(104),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(100),char(101),char(0),char(109),char(95),char(99),char(108), +char(117),char(115),char(116),char(101),char(114),char(73),char(110),char(100),char(101),char(120),char(0),char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(65),char(0), +char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(0),char(109),char(95),char(114),char(101),char(102),char(115),char(91),char(50),char(93),char(0),char(109), +char(95),char(99),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(100),char(101),char(108),char(101),char(116), +char(101),char(0),char(109),char(95),char(114),char(101),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(91),char(50),char(93),char(0),char(109), +char(95),char(98),char(111),char(100),char(121),char(65),char(116),char(121),char(112),char(101),char(0),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(116),char(121), +char(112),char(101),char(0),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(112),char(111), +char(115),char(101),char(0),char(42),char(42),char(109),char(95),char(109),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(115),char(0),char(42),char(109),char(95), +char(110),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(108),char(105),char(110),char(107),char(115),char(0),char(42),char(109),char(95),char(102),char(97), +char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(116),char(101),char(116),char(114),char(97),char(104),char(101),char(100),char(114),char(97),char(0),char(42),char(109), +char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(42),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(115), +char(0),char(42),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(97),char(116),char(101), +char(114),char(105),char(97),char(108),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(76),char(105),char(110),char(107),char(115),char(0),char(109),char(95),char(110), +char(117),char(109),char(70),char(97),char(99),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(84),char(101),char(116),char(114),char(97),char(104),char(101), +char(100),char(114),char(97),char(0),char(109),char(95),char(110),char(117),char(109),char(65),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(109),char(95),char(110), +char(117),char(109),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(74),char(111),char(105),char(110), +char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(102),char(105),char(103),char(0),char(84),char(89),char(80),char(69),char(76),char(0),char(0),char(0), +char(99),char(104),char(97),char(114),char(0),char(117),char(99),char(104),char(97),char(114),char(0),char(115),char(104),char(111),char(114),char(116),char(0),char(117),char(115),char(104), +char(111),char(114),char(116),char(0),char(105),char(110),char(116),char(0),char(108),char(111),char(110),char(103),char(0),char(117),char(108),char(111),char(110),char(103),char(0),char(102), +char(108),char(111),char(97),char(116),char(0),char(100),char(111),char(117),char(98),char(108),char(101),char(0),char(118),char(111),char(105),char(100),char(0),char(80),char(111),char(105), +char(110),char(116),char(101),char(114),char(65),char(114),char(114),char(97),char(121),char(0),char(98),char(116),char(80),char(104),char(121),char(115),char(105),char(99),char(115),char(83), +char(121),char(115),char(116),char(101),char(109),char(0),char(76),char(105),char(115),char(116),char(66),char(97),char(115),char(101),char(0),char(98),char(116),char(86),char(101),char(99), +char(116),char(111),char(114),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(86),char(101),char(99),char(116), +char(111),char(114),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),char(114), +char(105),char(120),char(51),char(120),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116), +char(114),char(105),char(120),char(51),char(120),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84), +char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0), +char(98),char(116),char(66),char(118),char(104),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(70), +char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100), +char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(70),char(108),char(111),char(97),char(116), +char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(68), +char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111), +char(110),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(97),char(116),char(105),char(99),char(80), +char(108),char(97),char(110),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118), +char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0), +char(98),char(116),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(110),char(100),char(82),char(97),char(100),char(105),char(117),char(115),char(0), +char(98),char(116),char(77),char(117),char(108),char(116),char(105),char(83),char(112),char(104),char(101),char(114),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),char(108),char(101),char(116), +char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(104),char(97),char(114),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112), +char(108),char(101),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(114),char(105),char(100),char(105),char(110),char(103),char(77),char(101),char(115),char(104),char(73),char(110),char(116), +char(101),char(114),char(102),char(97),char(99),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), +char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105), +char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),char(77),char(97),char(112),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83), +char(99),char(97),char(108),char(101),char(100),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97), +char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),char(110),char(100),char(83),char(104),char(97), +char(112),char(101),char(67),char(104),char(105),char(108),char(100),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117), +char(110),char(100),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(121),char(108),char(105),char(110),char(100), +char(101),char(114),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(97),char(112),char(115),char(117),char(108), +char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), +char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(73),char(109),char(112),char(97),char(99),char(116),char(77), +char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),char(101), +char(120),char(72),char(117),char(108),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108), +char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116), +char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115), +char(87),char(111),char(114),char(108),char(100),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111), +char(110),char(116),char(97),char(99),char(116),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(68),char(111),char(117),char(98),char(108), +char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),char(87),char(111),char(114),char(108), +char(100),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), +char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0), +char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(110),char(102),char(111),char(49), +char(0),char(98),char(116),char(84),char(121),char(112),char(101),char(100),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97), +char(116),char(97),char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(97),char(116),char(97),char(0),char(98), +char(116),char(80),char(111),char(105),char(110),char(116),char(50),char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), +char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(80),char(111),char(105),char(110),char(116),char(50), +char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108), +char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97), +char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103), +char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), +char(0),char(98),char(116),char(67),char(111),char(110),char(101),char(84),char(119),char(105),char(115),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), +char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102), +char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110), +char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),char(83),char(112),char(114),char(105),char(110),char(103),char(67),char(111),char(110),char(115),char(116),char(114), +char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(108),char(105),char(100),char(101),char(114),char(67),char(111),char(110), +char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121), +char(77),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100), +char(121),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(76),char(105), +char(110),char(107),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(97),char(99),char(101),char(68), +char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(84),char(101),char(116),char(114),char(97),char(68),char(97),char(116), +char(97),char(0),char(83),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(65),char(110),char(99),char(104),char(111),char(114),char(68),char(97),char(116), +char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(111),char(110),char(102),char(105),char(103),char(68),char(97),char(116),char(97), +char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(80),char(111),char(115),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111), +char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(74),char(111),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), +char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(0),char(0), +char(84),char(76),char(69),char(78),char(1),char(0),char(1),char(0),char(2),char(0),char(2),char(0),char(4),char(0),char(4),char(0),char(4),char(0),char(4),char(0), +char(8),char(0),char(0),char(0),char(16),char(0),char(48),char(0),char(16),char(0),char(16),char(0),char(32),char(0),char(48),char(0),char(96),char(0),char(64),char(0), +char(-128),char(0),char(20),char(0),char(48),char(0),char(80),char(0),char(16),char(0),char(96),char(0),char(-112),char(0),char(16),char(0),char(56),char(0),char(56),char(0), +char(20),char(0),char(72),char(0),char(4),char(0),char(4),char(0),char(8),char(0),char(4),char(0),char(56),char(0),char(32),char(0),char(80),char(0),char(72),char(0), +char(96),char(0),char(80),char(0),char(32),char(0),char(64),char(0),char(64),char(0),char(16),char(0),char(72),char(0),char(80),char(0),char(-32),char(1),char(16),char(1), +char(-72),char(0),char(-104),char(0),char(104),char(0),char(88),char(0),char(-8),char(1),char(-80),char(3),char(8),char(0),char(64),char(0),char(0),char(0),char(96),char(0), +char(-128),char(0),char(104),char(1),char(-24),char(0),char(-32),char(0),char(8),char(1),char(104),char(1),char(-40),char(0),char(16),char(0),char(104),char(0),char(24),char(0), +char(40),char(0),char(104),char(0),char(96),char(0),char(104),char(0),char(-56),char(0),char(104),char(1),char(112),char(0),char(-32),char(1),char(83),char(84),char(82),char(67), +char(65),char(0),char(0),char(0),char(10),char(0),char(3),char(0),char(4),char(0),char(0),char(0),char(4),char(0),char(1),char(0),char(9),char(0),char(2),char(0), +char(11),char(0),char(3),char(0),char(10),char(0),char(3),char(0),char(10),char(0),char(4),char(0),char(10),char(0),char(5),char(0),char(12),char(0),char(2),char(0), +char(9),char(0),char(6),char(0),char(9),char(0),char(7),char(0),char(13),char(0),char(1),char(0),char(7),char(0),char(8),char(0),char(14),char(0),char(1),char(0), +char(8),char(0),char(8),char(0),char(15),char(0),char(1),char(0),char(13),char(0),char(9),char(0),char(16),char(0),char(1),char(0),char(14),char(0),char(9),char(0), +char(17),char(0),char(2),char(0),char(15),char(0),char(10),char(0),char(13),char(0),char(11),char(0),char(18),char(0),char(2),char(0),char(16),char(0),char(10),char(0), +char(14),char(0),char(11),char(0),char(19),char(0),char(4),char(0),char(4),char(0),char(12),char(0),char(4),char(0),char(13),char(0),char(2),char(0),char(14),char(0), +char(2),char(0),char(15),char(0),char(20),char(0),char(6),char(0),char(13),char(0),char(16),char(0),char(13),char(0),char(17),char(0),char(4),char(0),char(18),char(0), +char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),char(21),char(0),char(6),char(0),char(14),char(0),char(16),char(0), +char(14),char(0),char(17),char(0),char(4),char(0),char(18),char(0),char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0), +char(22),char(0),char(3),char(0),char(2),char(0),char(14),char(0),char(2),char(0),char(15),char(0),char(4),char(0),char(22),char(0),char(23),char(0),char(12),char(0), +char(13),char(0),char(23),char(0),char(13),char(0),char(24),char(0),char(13),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0), +char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),char(20),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(19),char(0),char(32),char(0), +char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(24),char(0),char(12),char(0),char(14),char(0),char(23),char(0),char(14),char(0),char(24),char(0), +char(14),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0), +char(21),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(19),char(0),char(32),char(0), +char(25),char(0),char(3),char(0),char(0),char(0),char(35),char(0),char(4),char(0),char(36),char(0),char(0),char(0),char(37),char(0),char(26),char(0),char(5),char(0), +char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(40),char(0),char(7),char(0),char(41),char(0),char(0),char(0),char(21),char(0), +char(27),char(0),char(5),char(0),char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(42),char(0),char(7),char(0),char(43),char(0), +char(4),char(0),char(44),char(0),char(28),char(0),char(2),char(0),char(13),char(0),char(45),char(0),char(7),char(0),char(46),char(0),char(29),char(0),char(4),char(0), +char(27),char(0),char(47),char(0),char(28),char(0),char(48),char(0),char(4),char(0),char(49),char(0),char(0),char(0),char(37),char(0),char(30),char(0),char(1),char(0), +char(4),char(0),char(50),char(0),char(31),char(0),char(2),char(0),char(2),char(0),char(50),char(0),char(0),char(0),char(51),char(0),char(32),char(0),char(2),char(0), +char(2),char(0),char(52),char(0),char(0),char(0),char(51),char(0),char(33),char(0),char(2),char(0),char(0),char(0),char(52),char(0),char(0),char(0),char(53),char(0), +char(34),char(0),char(8),char(0),char(13),char(0),char(54),char(0),char(14),char(0),char(55),char(0),char(30),char(0),char(56),char(0),char(32),char(0),char(57),char(0), +char(33),char(0),char(58),char(0),char(31),char(0),char(59),char(0),char(4),char(0),char(60),char(0),char(4),char(0),char(61),char(0),char(35),char(0),char(4),char(0), +char(34),char(0),char(62),char(0),char(13),char(0),char(63),char(0),char(4),char(0),char(64),char(0),char(0),char(0),char(37),char(0),char(36),char(0),char(7),char(0), +char(25),char(0),char(38),char(0),char(35),char(0),char(65),char(0),char(23),char(0),char(66),char(0),char(24),char(0),char(67),char(0),char(37),char(0),char(68),char(0), +char(7),char(0),char(43),char(0),char(0),char(0),char(69),char(0),char(38),char(0),char(2),char(0),char(36),char(0),char(70),char(0),char(13),char(0),char(39),char(0), +char(39),char(0),char(4),char(0),char(17),char(0),char(71),char(0),char(25),char(0),char(72),char(0),char(4),char(0),char(73),char(0),char(7),char(0),char(74),char(0), +char(40),char(0),char(4),char(0),char(25),char(0),char(38),char(0),char(39),char(0),char(75),char(0),char(4),char(0),char(76),char(0),char(7),char(0),char(43),char(0), +char(41),char(0),char(3),char(0),char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(42),char(0),char(3),char(0), +char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(43),char(0),char(4),char(0),char(4),char(0),char(78),char(0), +char(7),char(0),char(79),char(0),char(7),char(0),char(80),char(0),char(7),char(0),char(81),char(0),char(37),char(0),char(14),char(0),char(4),char(0),char(82),char(0), +char(4),char(0),char(83),char(0),char(43),char(0),char(84),char(0),char(4),char(0),char(85),char(0),char(7),char(0),char(86),char(0),char(7),char(0),char(87),char(0), +char(7),char(0),char(88),char(0),char(7),char(0),char(89),char(0),char(7),char(0),char(90),char(0),char(4),char(0),char(91),char(0),char(4),char(0),char(92),char(0), +char(4),char(0),char(93),char(0),char(4),char(0),char(94),char(0),char(0),char(0),char(37),char(0),char(44),char(0),char(5),char(0),char(25),char(0),char(38),char(0), +char(35),char(0),char(65),char(0),char(13),char(0),char(39),char(0),char(7),char(0),char(43),char(0),char(4),char(0),char(95),char(0),char(45),char(0),char(5),char(0), +char(27),char(0),char(47),char(0),char(13),char(0),char(96),char(0),char(14),char(0),char(97),char(0),char(4),char(0),char(98),char(0),char(0),char(0),char(99),char(0), +char(46),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),char(0),char(0),char(35),char(0), +char(18),char(0),char(103),char(0),char(18),char(0),char(104),char(0),char(14),char(0),char(105),char(0),char(14),char(0),char(106),char(0),char(14),char(0),char(107),char(0), +char(8),char(0),char(108),char(0),char(8),char(0),char(109),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(111),char(0),char(8),char(0),char(112),char(0), +char(8),char(0),char(113),char(0),char(8),char(0),char(114),char(0),char(8),char(0),char(115),char(0),char(4),char(0),char(116),char(0),char(4),char(0),char(117),char(0), +char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),char(4),char(0),char(122),char(0), +char(0),char(0),char(37),char(0),char(47),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0), +char(0),char(0),char(35),char(0),char(17),char(0),char(103),char(0),char(17),char(0),char(104),char(0),char(13),char(0),char(105),char(0),char(13),char(0),char(106),char(0), +char(13),char(0),char(107),char(0),char(7),char(0),char(108),char(0),char(7),char(0),char(109),char(0),char(7),char(0),char(110),char(0),char(7),char(0),char(111),char(0), +char(7),char(0),char(112),char(0),char(7),char(0),char(113),char(0),char(7),char(0),char(114),char(0),char(7),char(0),char(115),char(0),char(4),char(0),char(116),char(0), +char(4),char(0),char(117),char(0),char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0), +char(4),char(0),char(122),char(0),char(0),char(0),char(37),char(0),char(48),char(0),char(2),char(0),char(49),char(0),char(123),char(0),char(14),char(0),char(124),char(0), +char(50),char(0),char(2),char(0),char(51),char(0),char(123),char(0),char(13),char(0),char(124),char(0),char(52),char(0),char(21),char(0),char(47),char(0),char(125),char(0), +char(15),char(0),char(126),char(0),char(13),char(0),char(127),char(0),char(13),char(0),char(-128),char(0),char(13),char(0),char(-127),char(0),char(13),char(0),char(-126),char(0), +char(13),char(0),char(124),char(0),char(13),char(0),char(-125),char(0),char(13),char(0),char(-124),char(0),char(13),char(0),char(-123),char(0),char(13),char(0),char(-122),char(0), +char(7),char(0),char(-121),char(0),char(7),char(0),char(-120),char(0),char(7),char(0),char(-119),char(0),char(7),char(0),char(-118),char(0),char(7),char(0),char(-117),char(0), +char(7),char(0),char(-116),char(0),char(7),char(0),char(-115),char(0),char(7),char(0),char(-114),char(0),char(7),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0), +char(53),char(0),char(22),char(0),char(46),char(0),char(125),char(0),char(16),char(0),char(126),char(0),char(14),char(0),char(127),char(0),char(14),char(0),char(-128),char(0), +char(14),char(0),char(-127),char(0),char(14),char(0),char(-126),char(0),char(14),char(0),char(124),char(0),char(14),char(0),char(-125),char(0),char(14),char(0),char(-124),char(0), +char(14),char(0),char(-123),char(0),char(14),char(0),char(-122),char(0),char(8),char(0),char(-121),char(0),char(8),char(0),char(-120),char(0),char(8),char(0),char(-119),char(0), +char(8),char(0),char(-118),char(0),char(8),char(0),char(-117),char(0),char(8),char(0),char(-116),char(0),char(8),char(0),char(-115),char(0),char(8),char(0),char(-114),char(0), +char(8),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),char(0),char(0),char(37),char(0),char(54),char(0),char(2),char(0),char(4),char(0),char(-111),char(0), +char(4),char(0),char(-110),char(0),char(55),char(0),char(13),char(0),char(56),char(0),char(-109),char(0),char(56),char(0),char(-108),char(0),char(0),char(0),char(35),char(0), +char(4),char(0),char(-107),char(0),char(4),char(0),char(-106),char(0),char(4),char(0),char(-105),char(0),char(4),char(0),char(-104),char(0),char(7),char(0),char(-103),char(0), +char(7),char(0),char(-102),char(0),char(4),char(0),char(-101),char(0),char(4),char(0),char(-100),char(0),char(7),char(0),char(-99),char(0),char(4),char(0),char(-98),char(0), +char(57),char(0),char(3),char(0),char(55),char(0),char(-97),char(0),char(13),char(0),char(-96),char(0),char(13),char(0),char(-95),char(0),char(58),char(0),char(3),char(0), +char(55),char(0),char(-97),char(0),char(14),char(0),char(-96),char(0),char(14),char(0),char(-95),char(0),char(59),char(0),char(13),char(0),char(55),char(0),char(-97),char(0), +char(18),char(0),char(-94),char(0),char(18),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0), +char(7),char(0),char(-89),char(0),char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0), +char(7),char(0),char(-84),char(0),char(7),char(0),char(-83),char(0),char(60),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0), +char(17),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),char(7),char(0),char(-89),char(0), +char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), +char(7),char(0),char(-83),char(0),char(61),char(0),char(11),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0), +char(7),char(0),char(-82),char(0),char(7),char(0),char(-81),char(0),char(7),char(0),char(-80),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), +char(7),char(0),char(-83),char(0),char(7),char(0),char(-79),char(0),char(0),char(0),char(21),char(0),char(62),char(0),char(9),char(0),char(55),char(0),char(-97),char(0), +char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(13),char(0),char(-78),char(0),char(13),char(0),char(-77),char(0),char(13),char(0),char(-76),char(0), +char(13),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(63),char(0),char(5),char(0),char(62),char(0),char(-72),char(0), +char(4),char(0),char(-71),char(0),char(7),char(0),char(-70),char(0),char(7),char(0),char(-69),char(0),char(7),char(0),char(-68),char(0),char(64),char(0),char(9),char(0), +char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(7),char(0),char(-78),char(0),char(7),char(0),char(-77),char(0), +char(7),char(0),char(-76),char(0),char(7),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(49),char(0),char(22),char(0), +char(8),char(0),char(-67),char(0),char(8),char(0),char(-79),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(-66),char(0),char(8),char(0),char(112),char(0), +char(8),char(0),char(-65),char(0),char(8),char(0),char(-64),char(0),char(8),char(0),char(-63),char(0),char(8),char(0),char(-62),char(0),char(8),char(0),char(-61),char(0), +char(8),char(0),char(-60),char(0),char(8),char(0),char(-59),char(0),char(8),char(0),char(-58),char(0),char(8),char(0),char(-57),char(0),char(8),char(0),char(-56),char(0), +char(8),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0), +char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),char(51),char(0),char(22),char(0),char(7),char(0),char(-67),char(0),char(7),char(0),char(-79),char(0), +char(7),char(0),char(110),char(0),char(7),char(0),char(-66),char(0),char(7),char(0),char(112),char(0),char(7),char(0),char(-65),char(0),char(7),char(0),char(-64),char(0), +char(7),char(0),char(-63),char(0),char(7),char(0),char(-62),char(0),char(7),char(0),char(-61),char(0),char(7),char(0),char(-60),char(0),char(7),char(0),char(-59),char(0), +char(7),char(0),char(-58),char(0),char(7),char(0),char(-57),char(0),char(7),char(0),char(-56),char(0),char(7),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0), +char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0), +char(65),char(0),char(4),char(0),char(7),char(0),char(-49),char(0),char(7),char(0),char(-48),char(0),char(7),char(0),char(-47),char(0),char(4),char(0),char(78),char(0), +char(66),char(0),char(10),char(0),char(65),char(0),char(-46),char(0),char(13),char(0),char(-45),char(0),char(13),char(0),char(-44),char(0),char(13),char(0),char(-43),char(0), +char(13),char(0),char(-42),char(0),char(13),char(0),char(-41),char(0),char(7),char(0),char(-121),char(0),char(7),char(0),char(-40),char(0),char(4),char(0),char(-39),char(0), +char(4),char(0),char(53),char(0),char(67),char(0),char(4),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-38),char(0),char(7),char(0),char(-37),char(0), +char(4),char(0),char(-36),char(0),char(68),char(0),char(4),char(0),char(13),char(0),char(-41),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-35),char(0), +char(7),char(0),char(-34),char(0),char(69),char(0),char(7),char(0),char(13),char(0),char(-33),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-32),char(0), +char(7),char(0),char(-31),char(0),char(7),char(0),char(-30),char(0),char(7),char(0),char(-29),char(0),char(4),char(0),char(53),char(0),char(70),char(0),char(6),char(0), +char(15),char(0),char(-28),char(0),char(13),char(0),char(-30),char(0),char(13),char(0),char(-27),char(0),char(56),char(0),char(-26),char(0),char(4),char(0),char(-25),char(0), +char(7),char(0),char(-29),char(0),char(71),char(0),char(26),char(0),char(4),char(0),char(-24),char(0),char(7),char(0),char(-23),char(0),char(7),char(0),char(-79),char(0), +char(7),char(0),char(-22),char(0),char(7),char(0),char(-21),char(0),char(7),char(0),char(-20),char(0),char(7),char(0),char(-19),char(0),char(7),char(0),char(-18),char(0), +char(7),char(0),char(-17),char(0),char(7),char(0),char(-16),char(0),char(7),char(0),char(-15),char(0),char(7),char(0),char(-14),char(0),char(7),char(0),char(-13),char(0), +char(7),char(0),char(-12),char(0),char(7),char(0),char(-11),char(0),char(7),char(0),char(-10),char(0),char(7),char(0),char(-9),char(0),char(7),char(0),char(-8),char(0), +char(7),char(0),char(-7),char(0),char(7),char(0),char(-6),char(0),char(7),char(0),char(-5),char(0),char(4),char(0),char(-4),char(0),char(4),char(0),char(-3),char(0), +char(4),char(0),char(-2),char(0),char(4),char(0),char(-1),char(0),char(4),char(0),char(117),char(0),char(72),char(0),char(12),char(0),char(15),char(0),char(0),char(1), +char(15),char(0),char(1),char(1),char(15),char(0),char(2),char(1),char(13),char(0),char(3),char(1),char(13),char(0),char(4),char(1),char(7),char(0),char(5),char(1), +char(4),char(0),char(6),char(1),char(4),char(0),char(7),char(1),char(4),char(0),char(8),char(1),char(4),char(0),char(9),char(1),char(7),char(0),char(-31),char(0), +char(4),char(0),char(53),char(0),char(73),char(0),char(27),char(0),char(17),char(0),char(10),char(1),char(15),char(0),char(11),char(1),char(15),char(0),char(12),char(1), +char(13),char(0),char(3),char(1),char(13),char(0),char(13),char(1),char(13),char(0),char(14),char(1),char(13),char(0),char(15),char(1),char(13),char(0),char(16),char(1), +char(13),char(0),char(17),char(1),char(4),char(0),char(18),char(1),char(7),char(0),char(19),char(1),char(4),char(0),char(20),char(1),char(4),char(0),char(21),char(1), +char(4),char(0),char(22),char(1),char(7),char(0),char(23),char(1),char(7),char(0),char(24),char(1),char(4),char(0),char(25),char(1),char(4),char(0),char(26),char(1), +char(7),char(0),char(27),char(1),char(7),char(0),char(28),char(1),char(7),char(0),char(29),char(1),char(7),char(0),char(30),char(1),char(7),char(0),char(31),char(1), +char(7),char(0),char(32),char(1),char(4),char(0),char(33),char(1),char(4),char(0),char(34),char(1),char(4),char(0),char(35),char(1),char(74),char(0),char(12),char(0), +char(9),char(0),char(36),char(1),char(9),char(0),char(37),char(1),char(13),char(0),char(38),char(1),char(7),char(0),char(39),char(1),char(7),char(0),char(-63),char(0), +char(7),char(0),char(40),char(1),char(4),char(0),char(41),char(1),char(13),char(0),char(42),char(1),char(4),char(0),char(43),char(1),char(4),char(0),char(44),char(1), +char(4),char(0),char(45),char(1),char(4),char(0),char(53),char(0),char(75),char(0),char(19),char(0),char(47),char(0),char(125),char(0),char(72),char(0),char(46),char(1), +char(65),char(0),char(47),char(1),char(66),char(0),char(48),char(1),char(67),char(0),char(49),char(1),char(68),char(0),char(50),char(1),char(69),char(0),char(51),char(1), +char(70),char(0),char(52),char(1),char(73),char(0),char(53),char(1),char(74),char(0),char(54),char(1),char(4),char(0),char(55),char(1),char(4),char(0),char(21),char(1), +char(4),char(0),char(56),char(1),char(4),char(0),char(57),char(1),char(4),char(0),char(58),char(1),char(4),char(0),char(59),char(1),char(4),char(0),char(60),char(1), +char(4),char(0),char(61),char(1),char(71),char(0),char(62),char(1),}; +int sBulletDNAlen64= sizeof(sBulletDNAstr64); diff --git a/src/LinearMath/btSerializer.h b/src/LinearMath/btSerializer.h new file mode 100644 index 0000000..c5bc96b --- /dev/null +++ b/src/LinearMath/btSerializer.h @@ -0,0 +1,640 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_SERIALIZER_H +#define BT_SERIALIZER_H + +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btStackAlloc.h" +#include "btHashMap.h" + +#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#include +#endif +#include + + + +///only the 32bit versions for now +extern char sBulletDNAstr[]; +extern int sBulletDNAlen; +extern char sBulletDNAstr64[]; +extern int sBulletDNAlen64; + +SIMD_FORCE_INLINE int btStrLen(const char* str) +{ + if (!str) + return(0); + int len = 0; + + while (*str != 0) + { + str++; + len++; + } + + return len; +} + + +class btChunk +{ +public: + int m_chunkCode; + int m_length; + void *m_oldPtr; + int m_dna_nr; + int m_number; +}; + +enum btSerializationFlags +{ + BT_SERIALIZE_NO_BVH = 1, + BT_SERIALIZE_NO_TRIANGLEINFOMAP = 2, + BT_SERIALIZE_NO_DUPLICATE_ASSERT = 4 +}; + +class btSerializer +{ + +public: + + virtual ~btSerializer() {} + + virtual const unsigned char* getBufferPointer() const = 0; + + virtual int getCurrentBufferSize() const = 0; + + virtual btChunk* allocate(size_t size, int numElements) = 0; + + virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0; + + virtual void* findPointer(void* oldPtr) = 0; + + virtual void* getUniquePointer(void*oldPtr) = 0; + + virtual void startSerialization() = 0; + + virtual void finishSerialization() = 0; + + virtual const char* findNameForPointer(const void* ptr) const = 0; + + virtual void registerNameForPointer(const void* ptr, const char* name) = 0; + + virtual void serializeName(const char* ptr) = 0; + + virtual int getSerializationFlags() const = 0; + + virtual void setSerializationFlags(int flags) = 0; + + +}; + + + +#define BT_HEADER_LENGTH 12 +#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +# define BT_MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#else +# define BT_MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) +#endif + +#define BT_SOFTBODY_CODE BT_MAKE_ID('S','B','D','Y') +#define BT_COLLISIONOBJECT_CODE BT_MAKE_ID('C','O','B','J') +#define BT_RIGIDBODY_CODE BT_MAKE_ID('R','B','D','Y') +#define BT_CONSTRAINT_CODE BT_MAKE_ID('C','O','N','S') +#define BT_BOXSHAPE_CODE BT_MAKE_ID('B','O','X','S') +#define BT_QUANTIZED_BVH_CODE BT_MAKE_ID('Q','B','V','H') +#define BT_TRIANLGE_INFO_MAP BT_MAKE_ID('T','M','A','P') +#define BT_SHAPE_CODE BT_MAKE_ID('S','H','A','P') +#define BT_ARRAY_CODE BT_MAKE_ID('A','R','A','Y') +#define BT_SBMATERIAL_CODE BT_MAKE_ID('S','B','M','T') +#define BT_SBNODE_CODE BT_MAKE_ID('S','B','N','D') +#define BT_DYNAMICSWORLD_CODE BT_MAKE_ID('D','W','L','D') +#define BT_DNA_CODE BT_MAKE_ID('D','N','A','1') + + +struct btPointerUid +{ + union + { + void* m_ptr; + int m_uniqueIds[2]; + }; +}; + +///The btDefaultSerializer is the main Bullet serialization class. +///The constructor takes an optional argument for backwards compatibility, it is recommended to leave this empty/zero. +class btDefaultSerializer : public btSerializer +{ + + + btAlignedObjectArray mTypes; + btAlignedObjectArray mStructs; + btAlignedObjectArray mTlens; + btHashMap mStructReverse; + btHashMap mTypeLookup; + + + btHashMap m_chunkP; + + btHashMap m_nameMap; + + btHashMap m_uniquePointers; + int m_uniqueIdGenerator; + + int m_totalSize; + unsigned char* m_buffer; + int m_currentSize; + void* m_dna; + int m_dnaLength; + + int m_serializationFlags; + + + btAlignedObjectArray m_chunkPtrs; + +protected: + + virtual void* findPointer(void* oldPtr) + { + void** ptr = m_chunkP.find(oldPtr); + if (ptr && *ptr) + return *ptr; + return 0; + } + + + + + + void writeDNA() + { + btChunk* dnaChunk = allocate(m_dnaLength,1); + memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength); + finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna); + } + + int getReverseType(const char *type) const + { + + btHashString key(type); + const int* valuePtr = mTypeLookup.find(key); + if (valuePtr) + return *valuePtr; + + return -1; + } + + void initDNA(const char* bdnaOrg,int dnalen) + { + ///was already initialized + if (m_dna) + return; + + int littleEndian= 1; + littleEndian= ((char*)&littleEndian)[0]; + + + m_dna = btAlignedAlloc(dnalen,16); + memcpy(m_dna,bdnaOrg,dnalen); + m_dnaLength = dnalen; + + int *intPtr=0; + short *shtPtr=0; + char *cp = 0;int dataLen =0; + intPtr = (int*)m_dna; + + /* + SDNA (4 bytes) (magic number) + NAME (4 bytes) + (4 bytes) amount of names (int) + + + */ + + if (strncmp((const char*)m_dna, "SDNA", 4)==0) + { + // skip ++ NAME + intPtr++; intPtr++; + } + + // Parse names + if (!littleEndian) + *intPtr = btSwapEndian(*intPtr); + + dataLen = *intPtr; + + intPtr++; + + cp = (char*)intPtr; + int i; + for ( i=0; i amount of types (int) + + + */ + + intPtr = (int*)cp; + btAssert(strncmp(cp, "TYPE", 4)==0); intPtr++; + + if (!littleEndian) + *intPtr = btSwapEndian(*intPtr); + + dataLen = *intPtr; + intPtr++; + + + cp = (char*)intPtr; + for (i=0; i (short) the lengths of types + + */ + + // Parse type lens + intPtr = (int*)cp; + btAssert(strncmp(cp, "TLEN", 4)==0); intPtr++; + + dataLen = (int)mTypes.size(); + + shtPtr = (short*)intPtr; + for (i=0; i amount of structs (int) + + + + + + + */ + + intPtr = (int*)shtPtr; + cp = (char*)intPtr; + btAssert(strncmp(cp, "STRC", 4)==0); intPtr++; + + if (!littleEndian) + *intPtr = btSwapEndian(*intPtr); + dataLen = *intPtr ; + intPtr++; + + + shtPtr = (short*)intPtr; + for (i=0; im_length; + memcpy(currentPtr,m_chunkPtrs[i], curLength); + btAlignedFree(m_chunkPtrs[i]); + currentPtr+=curLength; + mysize+=curLength; + } + } + + mTypes.clear(); + mStructs.clear(); + mTlens.clear(); + mStructReverse.clear(); + mTypeLookup.clear(); + m_chunkP.clear(); + m_nameMap.clear(); + m_uniquePointers.clear(); + m_chunkPtrs.clear(); + } + + virtual void* getUniquePointer(void*oldPtr) + { + if (!oldPtr) + return 0; + + btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr); + if (uptr) + { + return uptr->m_ptr; + } + m_uniqueIdGenerator++; + + btPointerUid uid; + uid.m_uniqueIds[0] = m_uniqueIdGenerator; + uid.m_uniqueIds[1] = m_uniqueIdGenerator; + m_uniquePointers.insert(oldPtr,uid); + return uid.m_ptr; + + } + + virtual const unsigned char* getBufferPointer() const + { + return m_buffer; + } + + virtual int getCurrentBufferSize() const + { + return m_currentSize; + } + + virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr) + { + if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT)) + { + btAssert(!findPointer(oldPtr)); + } + + chunk->m_dna_nr = getReverseType(structType); + + chunk->m_chunkCode = chunkCode; + + void* uniquePtr = getUniquePointer(oldPtr); + + m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr); + chunk->m_oldPtr = uniquePtr;//oldPtr; + + } + + + virtual unsigned char* internalAlloc(size_t size) + { + unsigned char* ptr = 0; + + if (m_totalSize) + { + ptr = m_buffer+m_currentSize; + m_currentSize += int(size); + btAssert(m_currentSizem_chunkCode = 0; + chunk->m_oldPtr = data; + chunk->m_length = int(size)*numElements; + chunk->m_number = numElements; + + m_chunkPtrs.push_back(chunk); + + + return chunk; + } + + virtual const char* findNameForPointer(const void* ptr) const + { + const char*const * namePtr = m_nameMap.find(ptr); + if (namePtr && *namePtr) + return *namePtr; + return 0; + + } + + virtual void registerNameForPointer(const void* ptr, const char* name) + { + m_nameMap.insert(ptr,name); + } + + virtual void serializeName(const char* name) + { + if (name) + { + //don't serialize name twice + if (findPointer((void*)name)) + return; + + int len = btStrLen(name); + if (len) + { + + int newLen = len+1; + int padding = ((newLen+3)&~3)-newLen; + newLen += padding; + + //serialize name string now + btChunk* chunk = allocate(sizeof(char),newLen); + char* destinationName = (char*)chunk->m_oldPtr; + for (int i=0;i(totalsize - usedsize); + } + + unsigned char* allocate(unsigned int size) + { + const unsigned int nus(usedsize+size); + if(nusprevious = current; + pb->address = data+usedsize; + current = pb; + return(pb); + } + SIMD_FORCE_INLINE void endBlock(btBlock* block) + { + btAssert(block==current); + //Raise(L"Unmatched blocks"); + if(block==current) + { + current = block->previous; + usedsize = (unsigned int)((block->address-data)-sizeof(btBlock)); + } + } + +private: + void ctor() + { + data = 0; + totalsize = 0; + usedsize = 0; + current = 0; + ischild = false; + } + unsigned char* data; + unsigned int totalsize; + unsigned int usedsize; + btBlock* current; + bool ischild; +}; + +#endif //BT_STACK_ALLOC diff --git a/src/LinearMath/btTransform.h b/src/LinearMath/btTransform.h new file mode 100644 index 0000000..9076273 --- /dev/null +++ b/src/LinearMath/btTransform.h @@ -0,0 +1,305 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_TRANSFORM_H +#define BT_TRANSFORM_H + + +#include "btMatrix3x3.h" + +#ifdef BT_USE_DOUBLE_PRECISION +#define btTransformData btTransformDoubleData +#else +#define btTransformData btTransformFloatData +#endif + + + + +/**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear. + *It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */ +ATTRIBUTE_ALIGNED16(class) btTransform { + + ///Storage for the rotation + btMatrix3x3 m_basis; + ///Storage for the translation + btVector3 m_origin; + +public: + + /**@brief No initialization constructor */ + btTransform() {} + /**@brief Constructor from btQuaternion (optional btVector3 ) + * @param q Rotation from quaternion + * @param c Translation from Vector (default 0,0,0) */ + explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, + const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) + : m_basis(q), + m_origin(c) + {} + + /**@brief Constructor from btMatrix3x3 (optional btVector3) + * @param b Rotation from Matrix + * @param c Translation from Vector default (0,0,0)*/ + explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, + const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) + : m_basis(b), + m_origin(c) + {} + /**@brief Copy constructor */ + SIMD_FORCE_INLINE btTransform (const btTransform& other) + : m_basis(other.m_basis), + m_origin(other.m_origin) + { + } + /**@brief Assignment Operator */ + SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other) + { + m_basis = other.m_basis; + m_origin = other.m_origin; + return *this; + } + + + /**@brief Set the current transform as the value of the product of two transforms + * @param t1 Transform 1 + * @param t2 Transform 2 + * This = Transform1 * Transform2 */ + SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) { + m_basis = t1.m_basis * t2.m_basis; + m_origin = t1(t2.m_origin); + } + +/* void multInverseLeft(const btTransform& t1, const btTransform& t2) { + btVector3 v = t2.m_origin - t1.m_origin; + m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis); + m_origin = v * t1.m_basis; + } + */ + +/**@brief Return the transform of the vector */ + SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const + { + return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin; + } + + /**@brief Return the transform of the vector */ + SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const + { + return (*this)(x); + } + + /**@brief Return the transform of the btQuaternion */ + SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const + { + return getRotation() * q; + } + + /**@brief Return the basis matrix for the rotation */ + SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; } + /**@brief Return the basis matrix for the rotation */ + SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; } + + /**@brief Return the origin vector translation */ + SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; } + /**@brief Return the origin vector translation */ + SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; } + + /**@brief Return a quaternion representing the rotation */ + btQuaternion getRotation() const { + btQuaternion q; + m_basis.getRotation(q); + return q; + } + + + /**@brief Set from an array + * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */ + void setFromOpenGLMatrix(const btScalar *m) + { + m_basis.setFromOpenGLSubMatrix(m); + m_origin.setValue(m[12],m[13],m[14]); + } + + /**@brief Fill an array representation + * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */ + void getOpenGLMatrix(btScalar *m) const + { + m_basis.getOpenGLSubMatrix(m); + m[12] = m_origin.x(); + m[13] = m_origin.y(); + m[14] = m_origin.z(); + m[15] = btScalar(1.0); + } + + /**@brief Set the translational element + * @param origin The vector to set the translation to */ + SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) + { + m_origin = origin; + } + + SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const; + + + /**@brief Set the rotational element by btMatrix3x3 */ + SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis) + { + m_basis = basis; + } + + /**@brief Set the rotational element by btQuaternion */ + SIMD_FORCE_INLINE void setRotation(const btQuaternion& q) + { + m_basis.setRotation(q); + } + + + /**@brief Set this transformation to the identity */ + void setIdentity() + { + m_basis.setIdentity(); + m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + } + + /**@brief Multiply this Transform by another(this = this * another) + * @param t The other transform */ + btTransform& operator*=(const btTransform& t) + { + m_origin += m_basis * t.m_origin; + m_basis *= t.m_basis; + return *this; + } + + /**@brief Return the inverse of this transform */ + btTransform inverse() const + { + btMatrix3x3 inv = m_basis.transpose(); + return btTransform(inv, inv * -m_origin); + } + + /**@brief Return the inverse of this transform times the other transform + * @param t The other transform + * return this.inverse() * the other */ + btTransform inverseTimes(const btTransform& t) const; + + /**@brief Return the product of this transform and the other */ + btTransform operator*(const btTransform& t) const; + + /**@brief Return an identity transform */ + static const btTransform& getIdentity() + { + static const btTransform identityTransform(btMatrix3x3::getIdentity()); + return identityTransform; + } + + void serialize(struct btTransformData& dataOut) const; + + void serializeFloat(struct btTransformFloatData& dataOut) const; + + void deSerialize(const struct btTransformData& dataIn); + + void deSerializeDouble(const struct btTransformDoubleData& dataIn); + + void deSerializeFloat(const struct btTransformFloatData& dataIn); + +}; + + +SIMD_FORCE_INLINE btVector3 +btTransform::invXform(const btVector3& inVec) const +{ + btVector3 v = inVec - m_origin; + return (m_basis.transpose() * v); +} + +SIMD_FORCE_INLINE btTransform +btTransform::inverseTimes(const btTransform& t) const +{ + btVector3 v = t.getOrigin() - m_origin; + return btTransform(m_basis.transposeTimes(t.m_basis), + v * m_basis); +} + +SIMD_FORCE_INLINE btTransform +btTransform::operator*(const btTransform& t) const +{ + return btTransform(m_basis * t.m_basis, + (*this)(t.m_origin)); +} + +/**@brief Test if two transforms have all elements equal */ +SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2) +{ + return ( t1.getBasis() == t2.getBasis() && + t1.getOrigin() == t2.getOrigin() ); +} + + +///for serialization +struct btTransformFloatData +{ + btMatrix3x3FloatData m_basis; + btVector3FloatData m_origin; +}; + +struct btTransformDoubleData +{ + btMatrix3x3DoubleData m_basis; + btVector3DoubleData m_origin; +}; + + + +SIMD_FORCE_INLINE void btTransform::serialize(btTransformData& dataOut) const +{ + m_basis.serialize(dataOut.m_basis); + m_origin.serialize(dataOut.m_origin); +} + +SIMD_FORCE_INLINE void btTransform::serializeFloat(btTransformFloatData& dataOut) const +{ + m_basis.serializeFloat(dataOut.m_basis); + m_origin.serializeFloat(dataOut.m_origin); +} + + +SIMD_FORCE_INLINE void btTransform::deSerialize(const btTransformData& dataIn) +{ + m_basis.deSerialize(dataIn.m_basis); + m_origin.deSerialize(dataIn.m_origin); +} + +SIMD_FORCE_INLINE void btTransform::deSerializeFloat(const btTransformFloatData& dataIn) +{ + m_basis.deSerializeFloat(dataIn.m_basis); + m_origin.deSerializeFloat(dataIn.m_origin); +} + +SIMD_FORCE_INLINE void btTransform::deSerializeDouble(const btTransformDoubleData& dataIn) +{ + m_basis.deSerializeDouble(dataIn.m_basis); + m_origin.deSerializeDouble(dataIn.m_origin); +} + + +#endif //BT_TRANSFORM_H + + + + + + diff --git a/src/LinearMath/btTransformUtil.h b/src/LinearMath/btTransformUtil.h new file mode 100644 index 0000000..2303c27 --- /dev/null +++ b/src/LinearMath/btTransformUtil.h @@ -0,0 +1,228 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_TRANSFORM_UTIL_H +#define BT_TRANSFORM_UTIL_H + +#include "btTransform.h" +#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI + + + + +SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) +{ + return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), + supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), + supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); +} + + + + + + +/// Utils related to temporal transforms +class btTransformUtil +{ + +public: + + static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform) + { + predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); +// #define QUATERNION_DERIVATIVE + #ifdef QUATERNION_DERIVATIVE + btQuaternion predictedOrn = curTrans.getRotation(); + predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5)); + predictedOrn.normalize(); + #else + //Exponential map + //google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia + + btVector3 axis; + btScalar fAngle = angvel.length(); + //limit the angular motion + if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD) + { + fAngle = ANGULAR_MOTION_THRESHOLD / timeStep; + } + + if ( fAngle < btScalar(0.001) ) + { + // use Taylor's expansions of sync function + axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle ); + } + else + { + // sync(fAngle) = sin(c*fAngle)/t + axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle ); + } + btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) )); + btQuaternion orn0 = curTrans.getRotation(); + + btQuaternion predictedOrn = dorn * orn0; + predictedOrn.normalize(); + #endif + predictedTransform.setRotation(predictedOrn); + } + + static void calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel) + { + linVel = (pos1 - pos0) / timeStep; + btVector3 axis; + btScalar angle; + if (orn0 != orn1) + { + calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle); + angVel = axis * angle / timeStep; + } else + { + angVel.setValue(0,0,0); + } + } + + static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle) + { + btQuaternion orn1 = orn0.nearest(orn1a); + btQuaternion dorn = orn1 * orn0.inverse(); + angle = dorn.getAngle(); + axis = btVector3(dorn.x(),dorn.y(),dorn.z()); + axis[3] = btScalar(0.); + //check for axis length + btScalar len = axis.length2(); + if (len < SIMD_EPSILON*SIMD_EPSILON) + axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); + else + axis /= btSqrt(len); + } + + static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel) + { + linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep; + btVector3 axis; + btScalar angle; + calculateDiffAxisAngle(transform0,transform1,axis,angle); + angVel = axis * angle / timeStep; + } + + static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle) + { + btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); + btQuaternion dorn; + dmat.getRotation(dorn); + + ///floating point inaccuracy can lead to w component > 1..., which breaks + dorn.normalize(); + + angle = dorn.getAngle(); + axis = btVector3(dorn.x(),dorn.y(),dorn.z()); + axis[3] = btScalar(0.); + //check for axis length + btScalar len = axis.length2(); + if (len < SIMD_EPSILON*SIMD_EPSILON) + axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); + else + axis /= btSqrt(len); + } + +}; + + +///The btConvexSeparatingDistanceUtil can help speed up convex collision detection +///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance +class btConvexSeparatingDistanceUtil +{ + btQuaternion m_ornA; + btQuaternion m_ornB; + btVector3 m_posA; + btVector3 m_posB; + + btVector3 m_separatingNormal; + + btScalar m_boundingRadiusA; + btScalar m_boundingRadiusB; + btScalar m_separatingDistance; + +public: + + btConvexSeparatingDistanceUtil(btScalar boundingRadiusA,btScalar boundingRadiusB) + :m_boundingRadiusA(boundingRadiusA), + m_boundingRadiusB(boundingRadiusB), + m_separatingDistance(0.f) + { + } + + btScalar getConservativeSeparatingDistance() + { + return m_separatingDistance; + } + + void updateSeparatingDistance(const btTransform& transA,const btTransform& transB) + { + const btVector3& toPosA = transA.getOrigin(); + const btVector3& toPosB = transB.getOrigin(); + btQuaternion toOrnA = transA.getRotation(); + btQuaternion toOrnB = transB.getRotation(); + + if (m_separatingDistance>0.f) + { + + + btVector3 linVelA,angVelA,linVelB,angVelB; + btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA); + btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB); + btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB; + btVector3 relLinVel = (linVelB-linVelA); + btScalar relLinVelocLength = relLinVel.dot(m_separatingNormal); + if (relLinVelocLength<0.f) + { + relLinVelocLength = 0.f; + } + + btScalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength; + m_separatingDistance -= projectedMotion; + } + + m_posA = toPosA; + m_posB = toPosB; + m_ornA = toOrnA; + m_ornB = toOrnB; + } + + void initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB) + { + m_separatingDistance = separatingDistance; + + if (m_separatingDistance>0.f) + { + m_separatingNormal = separatingVector; + + const btVector3& toPosA = transA.getOrigin(); + const btVector3& toPosB = transB.getOrigin(); + btQuaternion toOrnA = transA.getRotation(); + btQuaternion toOrnB = transB.getRotation(); + m_posA = toPosA; + m_posB = toPosB; + m_ornA = toOrnA; + m_ornB = toOrnB; + } + } + +}; + + +#endif //BT_TRANSFORM_UTIL_H + diff --git a/src/LinearMath/btVector3.cpp b/src/LinearMath/btVector3.cpp new file mode 100644 index 0000000..24bd521 --- /dev/null +++ b/src/LinearMath/btVector3.cpp @@ -0,0 +1,1631 @@ +/* + Copyright (c) 2011 Apple Inc. + http://continuousphysics.com/Bullet/ + + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from the use of this software. + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it freely, + subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + This source version has been altered. + */ + +#if defined (_WIN32) || defined (__i386__) +#define BT_USE_SSE_IN_API +#endif + +#include "btVector3.h" + +#if defined (BT_USE_SSE) || defined (BT_USE_NEON) + +#ifdef __APPLE__ +#include +typedef float float4 __attribute__ ((vector_size(16))); +#else +#define float4 __m128 +#endif +//typedef uint32_t uint4 __attribute__ ((vector_size(16))); + + +#if defined BT_USE_SSE || defined _WIN32 + +#define LOG2_ARRAY_SIZE 6 +#define STACK_ARRAY_COUNT (1UL << LOG2_ARRAY_SIZE) + +#include + +long _maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult ); +long _maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult ) +{ + const float4 *vertices = (const float4*) vv; + static const unsigned char indexTable[16] = {-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; + float4 dotMax = btAssign128( -BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY ); + float4 vvec = _mm_loadu_ps( vec ); + float4 vHi = btCastiTo128f(_mm_shuffle_epi32( btCastfTo128i( vvec), 0xaa )); /// zzzz + float4 vLo = _mm_movelh_ps( vvec, vvec ); /// xyxy + + long maxIndex = -1L; + + size_t segment = 0; + float4 stack_array[ STACK_ARRAY_COUNT ]; + +#if DEBUG + memset( stack_array, -1, STACK_ARRAY_COUNT * sizeof(stack_array[0]) ); +#endif + + size_t index; + float4 max; + // Faster loop without cleanup code for full tiles + for ( segment = 0; segment + STACK_ARRAY_COUNT*4 <= count; segment += STACK_ARRAY_COUNT*4 ) + { + max = dotMax; + + for( index = 0; index < STACK_ARRAY_COUNT; index+= 4 ) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; vertices += 4; + + float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+1] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+2] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+3] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. + } + + // If we found a new max + if( 0xf != _mm_movemask_ps( (float4) _mm_cmpeq_ps(max, dotMax))) + { + // copy the new max across all lanes of our max accumulator + max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0x4e)); + max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0xb1)); + + dotMax = max; + + // find first occurrence of that max + size_t test; + for( index = 0; 0 == (test=_mm_movemask_ps( _mm_cmpeq_ps( stack_array[index], max))); index++ ) // local_count must be a multiple of 4 + {} + // record where it is. + maxIndex = 4*index + segment + indexTable[test]; + } + } + + // account for work we've already done + count -= segment; + + // Deal with the last < STACK_ARRAY_COUNT vectors + max = dotMax; + index = 0; + + + if( btUnlikely( count > 16) ) + { + for( ; index + 4 <= count / 4; index+=4 ) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; vertices += 4; + + float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+1] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+2] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+3] = x; + max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + + // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. + } + } + + size_t localCount = (count & -4L) - 4*index; + if( localCount ) + { +#ifdef __APPLE__ + float4 t0, t1, t2, t3, t4; + float4 * sap = &stack_array[index + localCount / 4]; + vertices += localCount; // counter the offset + size_t byteIndex = -(localCount) * sizeof(float); + //AT&T Code style assembly + asm volatile + ( ".align 4 \n\ + 0: movaps %[max], %[t2] // move max out of the way to avoid propagating NaNs in max \n\ + movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\ + movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\ + movaps %[t0], %[max] // vertices[0] \n\ + movlhps %[t1], %[max] // x0y0x1y1 \n\ + movaps 32(%[vertices], %[byteIndex], 4), %[t3] // vertices[2] \n\ + movaps 48(%[vertices], %[byteIndex], 4), %[t4] // vertices[3] \n\ + mulps %[vLo], %[max] // x0y0x1y1 * vLo \n\ + movhlps %[t0], %[t1] // z0w0z1w1 \n\ + movaps %[t3], %[t0] // vertices[2] \n\ + movlhps %[t4], %[t0] // x2y2x3y3 \n\ + mulps %[vLo], %[t0] // x2y2x3y3 * vLo \n\ + movhlps %[t3], %[t4] // z2w2z3w3 \n\ + shufps $0x88, %[t4], %[t1] // z0z1z2z3 \n\ + mulps %[vHi], %[t1] // z0z1z2z3 * vHi \n\ + movaps %[max], %[t3] // x0y0x1y1 * vLo \n\ + shufps $0x88, %[t0], %[max] // x0x1x2x3 * vLo.x \n\ + shufps $0xdd, %[t0], %[t3] // y0y1y2y3 * vLo.y \n\ + addps %[t3], %[max] // x + y \n\ + addps %[t1], %[max] // x + y + z \n\ + movaps %[max], (%[sap], %[byteIndex]) // record result for later scrutiny \n\ + maxps %[t2], %[max] // record max, restore max \n\ + add $16, %[byteIndex] // advance loop counter\n\ + jnz 0b \n\ + " + : [max] "+x" (max), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex) + : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap) + : "memory", "cc" + ); + index += localCount/4; +#else + { + for( unsigned int i=0; i 16) ) + { + for( ; index + 4 <= count / 4; index+=4 ) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; vertices += 4; + + float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index] = x; + min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+1] = x; + min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+2] = x; + min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; vertices += 4; + + lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + + lo0 = lo0*vLo; + lo1 = lo1*vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z*vHi; + x = x+y; + x = x+z; + stack_array[index+3] = x; + min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan + + // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way. + } + } + + size_t localCount = (count & -4L) - 4*index; + if( localCount ) + { + + +#ifdef __APPLE__ + vertices += localCount; // counter the offset + float4 t0, t1, t2, t3, t4; + size_t byteIndex = -(localCount) * sizeof(float); + float4 * sap = &stack_array[index + localCount / 4]; + + asm volatile + ( ".align 4 \n\ + 0: movaps %[min], %[t2] // move min out of the way to avoid propagating NaNs in min \n\ + movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\ + movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\ + movaps %[t0], %[min] // vertices[0] \n\ + movlhps %[t1], %[min] // x0y0x1y1 \n\ + movaps 32(%[vertices], %[byteIndex], 4), %[t3] // vertices[2] \n\ + movaps 48(%[vertices], %[byteIndex], 4), %[t4] // vertices[3] \n\ + mulps %[vLo], %[min] // x0y0x1y1 * vLo \n\ + movhlps %[t0], %[t1] // z0w0z1w1 \n\ + movaps %[t3], %[t0] // vertices[2] \n\ + movlhps %[t4], %[t0] // x2y2x3y3 \n\ + movhlps %[t3], %[t4] // z2w2z3w3 \n\ + mulps %[vLo], %[t0] // x2y2x3y3 * vLo \n\ + shufps $0x88, %[t4], %[t1] // z0z1z2z3 \n\ + mulps %[vHi], %[t1] // z0z1z2z3 * vHi \n\ + movaps %[min], %[t3] // x0y0x1y1 * vLo \n\ + shufps $0x88, %[t0], %[min] // x0x1x2x3 * vLo.x \n\ + shufps $0xdd, %[t0], %[t3] // y0y1y2y3 * vLo.y \n\ + addps %[t3], %[min] // x + y \n\ + addps %[t1], %[min] // x + y + z \n\ + movaps %[min], (%[sap], %[byteIndex]) // record result for later scrutiny \n\ + minps %[t2], %[min] // record min, restore min \n\ + add $16, %[byteIndex] // advance loop counter\n\ + jnz 0b \n\ + " + : [min] "+x" (min), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex) + : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap) + : "memory", "cc" + ); + index += localCount/4; +#else + { + for( unsigned int i=0; i + + +static long _maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ); +static long _maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ); +static long _maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ); +static long _mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ); +static long _mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ); +static long _mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ); + +long (*_maxdot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _maxdot_large_sel; +long (*_mindot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _mindot_large_sel; + +extern "C" {int _get_cpu_capabilities( void );} + +static long _maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) +{ + if( _get_cpu_capabilities() & 0x2000 ) + _maxdot_large = _maxdot_large_v1; + else + _maxdot_large = _maxdot_large_v0; + + return _maxdot_large(vv, vec, count, dotResult); +} + +static long _mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) +{ + if( _get_cpu_capabilities() & 0x2000 ) + _mindot_large = _mindot_large_v1; + else + _mindot_large = _mindot_large_v0; + + return _mindot_large(vv, vec, count, dotResult); +} + + + +#define vld1q_f32_aligned_postincrement( _ptr ) ({ float32x4_t _r; asm( "vld1.f32 {%0}, [%1, :128]!\n" : "=w" (_r), "+r" (_ptr) ); /*return*/ _r; }) + + +long _maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ) +{ + unsigned long i = 0; + float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); + float32x2_t vLo = vget_low_f32(vvec); + float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); + float32x2_t dotMaxLo = (float32x2_t) { -BT_INFINITY, -BT_INFINITY }; + float32x2_t dotMaxHi = (float32x2_t) { -BT_INFINITY, -BT_INFINITY }; + uint32x2_t indexLo = (uint32x2_t) {0, 1}; + uint32x2_t indexHi = (uint32x2_t) {2, 3}; + uint32x2_t iLo = (uint32x2_t) {-1, -1}; + uint32x2_t iHi = (uint32x2_t) {-1, -1}; + const uint32x2_t four = (uint32x2_t) {4,4}; + + for( ; i+8 <= count; i+= 8 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + float32x2_t zHi = vmul_f32( z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + float32x2_t rHi = vpadd_f32( xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); + uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); + dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + + v0 = vld1q_f32_aligned_postincrement( vv ); + v1 = vld1q_f32_aligned_postincrement( vv ); + v2 = vld1q_f32_aligned_postincrement( vv ); + v3 = vld1q_f32_aligned_postincrement( vv ); + + xy0 = vmul_f32( vget_low_f32(v0), vLo); + xy1 = vmul_f32( vget_low_f32(v1), vLo); + xy2 = vmul_f32( vget_low_f32(v2), vLo); + xy3 = vmul_f32( vget_low_f32(v3), vLo); + + z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); + zLo = vmul_f32( z0.val[0], vHi); + zHi = vmul_f32( z1.val[0], vHi); + + rLo = vpadd_f32( xy0, xy1); + rHi = vpadd_f32( xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + maskLo = vcgt_f32( rLo, dotMaxLo ); + maskHi = vcgt_f32( rHi, dotMaxHi ); + dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + + for( ; i+4 <= count; i+= 4 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + float32x2_t zHi = vmul_f32( z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + float32x2_t rHi = vpadd_f32( xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); + uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); + dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + + switch( count & 3 ) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + float32x2_t rHi = vpadd_f32( xy2, xy2); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); + uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); + dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + } + break; + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + rLo = vadd_f32(rLo, zLo); + + uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); + dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); + float32x2_t zLo = vmul_f32( z0, vHi); + float32x2_t rLo = vpadd_f32( xy0, xy0); + rLo = vadd_f32(rLo, zLo); + uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); + dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vcgt_f32( dotMaxHi, dotMaxLo ); + dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); + iLo = vbsl_u32(mask, iHi, iLo); + + // select best answer between even and odd results + dotMaxHi = vdup_lane_f32(dotMaxLo, 1); + iHi = vdup_lane_u32(iLo, 1); + mask = vcgt_f32( dotMaxHi, dotMaxLo ); + dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); + iLo = vbsl_u32(mask, iHi, iLo); + + *dotResult = vget_lane_f32( dotMaxLo, 0); + return vget_lane_u32(iLo, 0); +} + + +long _maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ) +{ + float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); + float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); + float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); + const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 }; + uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3}; + uint32x4_t index = (uint32x4_t) { -1, -1, -1, -1 }; + float32x4_t maxDot = (float32x4_t) { -BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY }; + + unsigned long i = 0; + for( ; i + 8 <= count; i += 8 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z1); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32( mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + + v0 = vld1q_f32_aligned_postincrement( vv ); + v1 = vld1q_f32_aligned_postincrement( vv ); + v2 = vld1q_f32_aligned_postincrement( vv ); + v3 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + zb = vuzpq_f32( z0, z1); + z = vmulq_f32( zb.val[0], vHi); + xy = vuzpq_f32( xy0, xy1); + x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32( mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + for( ; i + 4 <= count; i += 4 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z1); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32( mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + switch (count & 3) { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z1); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32( mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + + xy0 = vmulq_f32(xy0, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z0); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32( mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); + + xy0 = vmulq_f32(xy0, vLo); + + z = vmulq_f32( z, vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32( mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + default: + break; + } + + + // select best answer between hi and lo results + uint32x2_t mask = vcgt_f32( vget_high_f32(maxDot), vget_low_f32(maxDot)); + float32x2_t maxDot2 = vbsl_f32(mask, vget_high_f32(maxDot), vget_low_f32(maxDot)); + uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); + + // select best answer between even and odd results + float32x2_t maxDotO = vdup_lane_f32(maxDot2, 1); + uint32x2_t indexHi = vdup_lane_u32(index2, 1); + mask = vcgt_f32( maxDotO, maxDot2 ); + maxDot2 = vbsl_f32(mask, maxDotO, maxDot2); + index2 = vbsl_u32(mask, indexHi, index2); + + *dotResult = vget_lane_f32( maxDot2, 0); + return vget_lane_u32(index2, 0); + +} + +long _mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ) +{ + unsigned long i = 0; + float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); + float32x2_t vLo = vget_low_f32(vvec); + float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); + float32x2_t dotMinLo = (float32x2_t) { BT_INFINITY, BT_INFINITY }; + float32x2_t dotMinHi = (float32x2_t) { BT_INFINITY, BT_INFINITY }; + uint32x2_t indexLo = (uint32x2_t) {0, 1}; + uint32x2_t indexHi = (uint32x2_t) {2, 3}; + uint32x2_t iLo = (uint32x2_t) {-1, -1}; + uint32x2_t iHi = (uint32x2_t) {-1, -1}; + const uint32x2_t four = (uint32x2_t) {4,4}; + + for( ; i+8 <= count; i+= 8 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + float32x2_t zHi = vmul_f32( z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + float32x2_t rHi = vpadd_f32( xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); + uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); + dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + + v0 = vld1q_f32_aligned_postincrement( vv ); + v1 = vld1q_f32_aligned_postincrement( vv ); + v2 = vld1q_f32_aligned_postincrement( vv ); + v3 = vld1q_f32_aligned_postincrement( vv ); + + xy0 = vmul_f32( vget_low_f32(v0), vLo); + xy1 = vmul_f32( vget_low_f32(v1), vLo); + xy2 = vmul_f32( vget_low_f32(v2), vLo); + xy3 = vmul_f32( vget_low_f32(v3), vLo); + + z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); + zLo = vmul_f32( z0.val[0], vHi); + zHi = vmul_f32( z1.val[0], vHi); + + rLo = vpadd_f32( xy0, xy1); + rHi = vpadd_f32( xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + maskLo = vclt_f32( rLo, dotMinLo ); + maskHi = vclt_f32( rHi, dotMinHi ); + dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + + for( ; i+4 <= count; i+= 4 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + float32x2_t zHi = vmul_f32( z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + float32x2_t rHi = vpadd_f32( xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); + uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); + dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + switch( count & 3 ) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + float32x2_t rHi = vpadd_f32( xy2, xy2); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); + uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); + dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + } + break; + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + + float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32( z0.val[0], vHi); + + float32x2_t rLo = vpadd_f32( xy0, xy1); + rLo = vadd_f32(rLo, zLo); + + uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); + dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); + float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); + float32x2_t zLo = vmul_f32( z0, vHi); + float32x2_t rLo = vpadd_f32( xy0, xy0); + rLo = vadd_f32(rLo, zLo); + uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); + dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vclt_f32( dotMinHi, dotMinLo ); + dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); + iLo = vbsl_u32(mask, iHi, iLo); + + // select best answer between even and odd results + dotMinHi = vdup_lane_f32(dotMinLo, 1); + iHi = vdup_lane_u32(iLo, 1); + mask = vclt_f32( dotMinHi, dotMinLo ); + dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); + iLo = vbsl_u32(mask, iHi, iLo); + + *dotResult = vget_lane_f32( dotMinLo, 0); + return vget_lane_u32(iLo, 0); +} + +long _mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ) +{ + float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); + float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); + float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); + const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 }; + uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3}; + uint32x4_t index = (uint32x4_t) { -1, -1, -1, -1 }; + float32x4_t minDot = (float32x4_t) { BT_INFINITY, BT_INFINITY, BT_INFINITY, BT_INFINITY }; + + unsigned long i = 0; + for( ; i + 8 <= count; i += 8 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z1); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32( mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + + v0 = vld1q_f32_aligned_postincrement( vv ); + v1 = vld1q_f32_aligned_postincrement( vv ); + v2 = vld1q_f32_aligned_postincrement( vv ); + v3 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + zb = vuzpq_f32( z0, z1); + z = vmulq_f32( zb.val[0], vHi); + xy = vuzpq_f32( xy0, xy1); + x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + mask = vcltq_f32(x, minDot); + minDot = vbslq_f32( mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + for( ; i + 4 <= count; i += 4 ) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z1); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32( mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + switch (count & 3) { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z1); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32( mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + + xy0 = vmulq_f32(xy0, vLo); + + float32x4x2_t zb = vuzpq_f32( z0, z0); + float32x4_t z = vmulq_f32( zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32( mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); + + xy0 = vmulq_f32(xy0, vLo); + + z = vmulq_f32( z, vHi); + float32x4x2_t xy = vuzpq_f32( xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32( mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + default: + break; + } + + + // select best answer between hi and lo results + uint32x2_t mask = vclt_f32( vget_high_f32(minDot), vget_low_f32(minDot)); + float32x2_t minDot2 = vbsl_f32(mask, vget_high_f32(minDot), vget_low_f32(minDot)); + uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); + + // select best answer between even and odd results + float32x2_t minDotO = vdup_lane_f32(minDot2, 1); + uint32x2_t indexHi = vdup_lane_u32(index2, 1); + mask = vclt_f32( minDotO, minDot2 ); + minDot2 = vbsl_f32(mask, minDotO, minDot2); + index2 = vbsl_u32(mask, indexHi, index2); + + *dotResult = vget_lane_f32( minDot2, 0); + return vget_lane_u32(index2, 0); + +} + +#else + #error Unhandled __APPLE__ arch +#endif + +#endif /* __APPLE__ */ + + diff --git a/src/LinearMath/btVector3.h b/src/LinearMath/btVector3.h new file mode 100644 index 0000000..5001dfa --- /dev/null +++ b/src/LinearMath/btVector3.h @@ -0,0 +1,1343 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_VECTOR3_H +#define BT_VECTOR3_H + +//#include +#include "btScalar.h" +#include "btMinMax.h" +#include "btAlignedAllocator.h" + +#ifdef BT_USE_DOUBLE_PRECISION +#define btVector3Data btVector3DoubleData +#define btVector3DataName "btVector3DoubleData" +#else +#define btVector3Data btVector3FloatData +#define btVector3DataName "btVector3FloatData" +#endif //BT_USE_DOUBLE_PRECISION + +#if defined BT_USE_SSE + +//typedef uint32_t __m128i __attribute__ ((vector_size(16))); + +#ifdef _MSC_VER +#pragma warning(disable: 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255' +#endif + + +#define BT_SHUFFLE(x,y,z,w) ((w)<<6 | (z)<<4 | (y)<<2 | (x)) +//#define bt_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) ) +#define bt_pshufd_ps( _a, _mask ) _mm_shuffle_ps((_a), (_a), (_mask) ) +#define bt_splat3_ps( _a, _i ) bt_pshufd_ps((_a), BT_SHUFFLE(_i,_i,_i, 3) ) +#define bt_splat_ps( _a, _i ) bt_pshufd_ps((_a), BT_SHUFFLE(_i,_i,_i,_i) ) + +#define btv3AbsiMask (_mm_set_epi32(0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) +#define btvAbsMask (_mm_set_epi32( 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) +#define btvFFF0Mask (_mm_set_epi32(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)) +#define btv3AbsfMask btCastiTo128f(btv3AbsiMask) +#define btvFFF0fMask btCastiTo128f(btvFFF0Mask) +#define btvxyzMaskf btvFFF0fMask +#define btvAbsfMask btCastiTo128f(btvAbsMask) + + + +const __m128 ATTRIBUTE_ALIGNED16(btvMzeroMask) = {-0.0f, -0.0f, -0.0f, -0.0f}; +const __m128 ATTRIBUTE_ALIGNED16(v1110) = {1.0f, 1.0f, 1.0f, 0.0f}; +const __m128 ATTRIBUTE_ALIGNED16(vHalf) = {0.5f, 0.5f, 0.5f, 0.5f}; +const __m128 ATTRIBUTE_ALIGNED16(v1_5) = {1.5f, 1.5f, 1.5f, 1.5f}; + +#endif + +#ifdef BT_USE_NEON + +const float32x4_t ATTRIBUTE_ALIGNED16(btvMzeroMask) = (float32x4_t){-0.0f, -0.0f, -0.0f, -0.0f}; +const int32x4_t ATTRIBUTE_ALIGNED16(btvFFF0Mask) = (int32x4_t){0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0}; +const int32x4_t ATTRIBUTE_ALIGNED16(btvAbsMask) = (int32x4_t){0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}; +const int32x4_t ATTRIBUTE_ALIGNED16(btv3AbsMask) = (int32x4_t){0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x0}; + +#endif + +/**@brief btVector3 can be used to represent 3D points and vectors. + * It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user + * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers + */ +ATTRIBUTE_ALIGNED16(class) btVector3 +{ +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + +#if defined (__SPU__) && defined (__CELLOS_LV2__) + btScalar m_floats[4]; +public: + SIMD_FORCE_INLINE const vec_float4& get128() const + { + return *((const vec_float4*)&m_floats[0]); + } +public: +#else //__CELLOS_LV2__ __SPU__ + #if defined (BT_USE_SSE) || defined(BT_USE_NEON) // _WIN32 || ARM + union { + btSimdFloat4 mVec128; + btScalar m_floats[4]; + }; + SIMD_FORCE_INLINE btSimdFloat4 get128() const + { + return mVec128; + } + SIMD_FORCE_INLINE void set128(btSimdFloat4 v128) + { + mVec128 = v128; + } + #else + btScalar m_floats[4]; + #endif +#endif //__CELLOS_LV2__ __SPU__ + + public: + + /**@brief No initialization constructor */ + SIMD_FORCE_INLINE btVector3() + { + + } + + + + /**@brief Constructor from scalars + * @param x X value + * @param y Y value + * @param z Z value + */ + SIMD_FORCE_INLINE btVector3(const btScalar& _x, const btScalar& _y, const btScalar& _z) + { + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = btScalar(0.f); + } + +#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) )|| defined (BT_USE_NEON) + // Set Vector + SIMD_FORCE_INLINE btVector3( btSimdFloat4 v) + { + mVec128 = v; + } + + // Copy constructor + SIMD_FORCE_INLINE btVector3(const btVector3& rhs) + { + mVec128 = rhs.mVec128; + } + + // Assignment Operator + SIMD_FORCE_INLINE btVector3& + operator=(const btVector3& v) + { + mVec128 = v.mVec128; + + return *this; + } +#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + +/**@brief Add a vector to this one + * @param The vector to add to this one */ + SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = _mm_add_ps(mVec128, v.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vaddq_f32(mVec128, v.mVec128); +#else + m_floats[0] += v.m_floats[0]; + m_floats[1] += v.m_floats[1]; + m_floats[2] += v.m_floats[2]; +#endif + return *this; + } + + + /**@brief Subtract a vector from this one + * @param The vector to subtract */ + SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = _mm_sub_ps(mVec128, v.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vsubq_f32(mVec128, v.mVec128); +#else + m_floats[0] -= v.m_floats[0]; + m_floats[1] -= v.m_floats[1]; + m_floats[2] -= v.m_floats[2]; +#endif + return *this; + } + + /**@brief Scale the vector + * @param s Scale factor */ + SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0) + mVec128 = _mm_mul_ps(mVec128, vs); +#elif defined(BT_USE_NEON) + mVec128 = vmulq_n_f32(mVec128, s); +#else + m_floats[0] *= s; + m_floats[1] *= s; + m_floats[2] *= s; +#endif + return *this; + } + + /**@brief Inversely scale the vector + * @param s Scale factor to divide by */ + SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) + { + btFullAssert(s != btScalar(0.0)); + +#if 0 //defined(BT_USE_SSE_IN_API) +// this code is not faster ! + __m128 vs = _mm_load_ss(&s); + vs = _mm_div_ss(v1110, vs); + vs = bt_pshufd_ps(vs, 0x00); // (S S S S) + + mVec128 = _mm_mul_ps(mVec128, vs); + + return *this; +#else + return *this *= btScalar(1.0) / s; +#endif + } + + /**@brief Return the dot product + * @param v The other vector in the dot product */ + SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vd = _mm_mul_ps(mVec128, v.mVec128); + __m128 z = _mm_movehl_ps(vd, vd); + __m128 y = _mm_shuffle_ps(vd, vd, 0x55); + vd = _mm_add_ss(vd, y); + vd = _mm_add_ss(vd, z); + return _mm_cvtss_f32(vd); +#elif defined(BT_USE_NEON) + float32x4_t vd = vmulq_f32(mVec128, v.mVec128); + float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_low_f32(vd)); + x = vadd_f32(x, vget_high_f32(vd)); + return vget_lane_f32(x, 0); +#else + return m_floats[0] * v.m_floats[0] + + m_floats[1] * v.m_floats[1] + + m_floats[2] * v.m_floats[2]; +#endif + } + + /**@brief Return the length of the vector squared */ + SIMD_FORCE_INLINE btScalar length2() const + { + return dot(*this); + } + + /**@brief Return the length of the vector */ + SIMD_FORCE_INLINE btScalar length() const + { + return btSqrt(length2()); + } + + /**@brief Return the distance squared between the ends of this and another vector + * This is symantically treating the vector like a point */ + SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; + + /**@brief Return the distance between the ends of this and another vector + * This is symantically treating the vector like a point */ + SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; + + SIMD_FORCE_INLINE btVector3& safeNormalize() + { + btVector3 absVec = this->absolute(); + int maxIndex = absVec.maxAxis(); + if (absVec[maxIndex]>0) + { + *this /= absVec[maxIndex]; + return *this /= length(); + } + setValue(1,0,0); + return *this; + } + + /**@brief Normalize this vector + * x^2 + y^2 + z^2 = 1 */ + SIMD_FORCE_INLINE btVector3& normalize() + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + // dot product first + __m128 vd = _mm_mul_ps(mVec128, mVec128); + __m128 z = _mm_movehl_ps(vd, vd); + __m128 y = _mm_shuffle_ps(vd, vd, 0x55); + vd = _mm_add_ss(vd, y); + vd = _mm_add_ss(vd, z); + + #if 0 + vd = _mm_sqrt_ss(vd); + vd = _mm_div_ss(v1110, vd); + vd = bt_splat_ps(vd, 0x80); + mVec128 = _mm_mul_ps(mVec128, vd); + #else + + // NR step 1/sqrt(x) - vd is x, y is output + y = _mm_rsqrt_ss(vd); // estimate + + // one step NR + z = v1_5; + vd = _mm_mul_ss(vd, vHalf); // vd * 0.5 + //x2 = vd; + vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 + vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 * y0 + z = _mm_sub_ss(z, vd); // 1.5 - vd * 0.5 * y0 * y0 + + y = _mm_mul_ss(y, z); // y0 * (1.5 - vd * 0.5 * y0 * y0) + + y = bt_splat_ps(y, 0x80); + mVec128 = _mm_mul_ps(mVec128, y); + + #endif + + + return *this; +#else + return *this /= length(); +#endif + } + + /**@brief Return a normalized version of this vector */ + SIMD_FORCE_INLINE btVector3 normalized() const; + + /**@brief Return a rotated version of this vector + * @param wAxis The axis to rotate about + * @param angle The angle to rotate by */ + SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ) const; + + /**@brief Return the angle between this and another vector + * @param v The other vector */ + SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const + { + btScalar s = btSqrt(length2() * v.length2()); + btFullAssert(s != btScalar(0.0)); + return btAcos(dot(v) / s); + } + + /**@brief Return a vector will the absolute values of each element */ + SIMD_FORCE_INLINE btVector3 absolute() const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btVector3(_mm_and_ps(mVec128, btv3AbsfMask)); +#elif defined(BT_USE_NEON) + return btVector3(vabsq_f32(mVec128)); +#else + return btVector3( + btFabs(m_floats[0]), + btFabs(m_floats[1]), + btFabs(m_floats[2])); +#endif + } + + /**@brief Return the cross product between this and another vector + * @param v The other vector */ + SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 T, V; + + T = bt_pshufd_ps(mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + V = bt_pshufd_ps(v.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + + V = _mm_mul_ps(V, mVec128); + T = _mm_mul_ps(T, v.mVec128); + V = _mm_sub_ps(V, T); + + V = bt_pshufd_ps(V, BT_SHUFFLE(1, 2, 0, 3)); + return btVector3(V); +#elif defined(BT_USE_NEON) + float32x4_t T, V; + // form (Y, Z, X, _) of mVec128 and v.mVec128 + float32x2_t Tlow = vget_low_f32(mVec128); + float32x2_t Vlow = vget_low_f32(v.mVec128); + T = vcombine_f32(vext_f32(Tlow, vget_high_f32(mVec128), 1), Tlow); + V = vcombine_f32(vext_f32(Vlow, vget_high_f32(v.mVec128), 1), Vlow); + + V = vmulq_f32(V, mVec128); + T = vmulq_f32(T, v.mVec128); + V = vsubq_f32(V, T); + Vlow = vget_low_f32(V); + // form (Y, Z, X, _); + V = vcombine_f32(vext_f32(Vlow, vget_high_f32(V), 1), Vlow); + V = (float32x4_t)vandq_s32((int32x4_t)V, btvFFF0Mask); + + return btVector3(V); +#else + return btVector3( + m_floats[1] * v.m_floats[2] - m_floats[2] * v.m_floats[1], + m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2], + m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]); +#endif + } + + SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + // cross: + __m128 T = _mm_shuffle_ps(v1.mVec128, v1.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + __m128 V = _mm_shuffle_ps(v2.mVec128, v2.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + + V = _mm_mul_ps(V, v1.mVec128); + T = _mm_mul_ps(T, v2.mVec128); + V = _mm_sub_ps(V, T); + + V = _mm_shuffle_ps(V, V, BT_SHUFFLE(1, 2, 0, 3)); + + // dot: + V = _mm_mul_ps(V, mVec128); + __m128 z = _mm_movehl_ps(V, V); + __m128 y = _mm_shuffle_ps(V, V, 0x55); + V = _mm_add_ss(V, y); + V = _mm_add_ss(V, z); + return _mm_cvtss_f32(V); + +#elif defined(BT_USE_NEON) + // cross: + float32x4_t T, V; + // form (Y, Z, X, _) of mVec128 and v.mVec128 + float32x2_t Tlow = vget_low_f32(v1.mVec128); + float32x2_t Vlow = vget_low_f32(v2.mVec128); + T = vcombine_f32(vext_f32(Tlow, vget_high_f32(v1.mVec128), 1), Tlow); + V = vcombine_f32(vext_f32(Vlow, vget_high_f32(v2.mVec128), 1), Vlow); + + V = vmulq_f32(V, v1.mVec128); + T = vmulq_f32(T, v2.mVec128); + V = vsubq_f32(V, T); + Vlow = vget_low_f32(V); + // form (Y, Z, X, _); + V = vcombine_f32(vext_f32(Vlow, vget_high_f32(V), 1), Vlow); + + // dot: + V = vmulq_f32(mVec128, V); + float32x2_t x = vpadd_f32(vget_low_f32(V), vget_low_f32(V)); + x = vadd_f32(x, vget_high_f32(V)); + return vget_lane_f32(x, 0); +#else + return + m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + + m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + + m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); +#endif + } + + /**@brief Return the axis with the smallest value + * Note return values are 0,1,2 for x, y, or z */ + SIMD_FORCE_INLINE int minAxis() const + { + return m_floats[0] < m_floats[1] ? (m_floats[0] return this, t=1 => return other) */ + SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vt = _mm_load_ss(&t); // (t 0 0 0) + vt = bt_pshufd_ps(vt, 0x80); // (rt rt rt 0.0) + __m128 vl = _mm_sub_ps(v.mVec128, mVec128); + vl = _mm_mul_ps(vl, vt); + vl = _mm_add_ps(vl, mVec128); + + return btVector3(vl); +#elif defined(BT_USE_NEON) + float32x4_t vl = vsubq_f32(v.mVec128, mVec128); + vl = vmulq_n_f32(vl, t); + vl = vaddq_f32(vl, mVec128); + + return btVector3(vl); +#else + return + btVector3( m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, + m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, + m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); +#endif + } + + /**@brief Elementwise multiply this vector by the other + * @param v The other vector */ + SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = _mm_mul_ps(mVec128, v.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vmulq_f32(mVec128, v.mVec128); +#else + m_floats[0] *= v.m_floats[0]; + m_floats[1] *= v.m_floats[1]; + m_floats[2] *= v.m_floats[2]; +#endif + return *this; + } + + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } + /**@brief Set the x value */ + SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x;}; + /**@brief Set the y value */ + SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y;}; + /**@brief Set the z value */ + SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z;}; + /**@brief Set the w value */ + SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w;}; + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } + /**@brief Return the w value */ + SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } + + //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } + //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } + ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. + SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; } + SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; } + + SIMD_FORCE_INLINE bool operator==(const btVector3& other) const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); +#else + return ((m_floats[3]==other.m_floats[3]) && + (m_floats[2]==other.m_floats[2]) && + (m_floats[1]==other.m_floats[1]) && + (m_floats[0]==other.m_floats[0])); +#endif + } + + SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const + { + return !(*this == other); + } + + /**@brief Set each element to the max of the current values and the values of another btVector3 + * @param other The other btVector3 to compare with + */ + SIMD_FORCE_INLINE void setMax(const btVector3& other) + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = _mm_max_ps(mVec128, other.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vmaxq_f32(mVec128, other.mVec128); +#else + btSetMax(m_floats[0], other.m_floats[0]); + btSetMax(m_floats[1], other.m_floats[1]); + btSetMax(m_floats[2], other.m_floats[2]); + btSetMax(m_floats[3], other.w()); +#endif + } + + /**@brief Set each element to the min of the current values and the values of another btVector3 + * @param other The other btVector3 to compare with + */ + SIMD_FORCE_INLINE void setMin(const btVector3& other) + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = _mm_min_ps(mVec128, other.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vminq_f32(mVec128, other.mVec128); +#else + btSetMin(m_floats[0], other.m_floats[0]); + btSetMin(m_floats[1], other.m_floats[1]); + btSetMin(m_floats[2], other.m_floats[2]); + btSetMin(m_floats[3], other.w()); +#endif + } + + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z) + { + m_floats[0]=_x; + m_floats[1]=_y; + m_floats[2]=_z; + m_floats[3] = btScalar(0.f); + } + + void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + + __m128 V = _mm_and_ps(mVec128, btvFFF0fMask); + __m128 V0 = _mm_xor_ps(btvMzeroMask, V); + __m128 V2 = _mm_movelh_ps(V0, V); + + __m128 V1 = _mm_shuffle_ps(V, V0, 0xCE); + + V0 = _mm_shuffle_ps(V0, V, 0xDB); + V2 = _mm_shuffle_ps(V2, V, 0xF9); + + v0->mVec128 = V0; + v1->mVec128 = V1; + v2->mVec128 = V2; +#else + v0->setValue(0. ,-z() ,y()); + v1->setValue(z() ,0. ,-x()); + v2->setValue(-y() ,x() ,0.); +#endif + } + + void setZero() + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + mVec128 = (__m128)_mm_xor_ps(mVec128, mVec128); +#elif defined(BT_USE_NEON) + int32x4_t vi = vdupq_n_s32(0); + mVec128 = vreinterpretq_f32_s32(vi); +#else + setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +#endif + } + + SIMD_FORCE_INLINE bool isZero() const + { + return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0); + } + + SIMD_FORCE_INLINE bool fuzzyZero() const + { + return length2() < SIMD_EPSILON; + } + + SIMD_FORCE_INLINE void serialize(struct btVector3Data& dataOut) const; + + SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn); + + SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData& dataOut) const; + + SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn); + + SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData& dataOut) const; + + SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn); + + /**@brief returns index of maximum dot product between this and vectors in array[] + * @param array The other vectors + * @param array_count The number of other vectors + * @param dotOut The maximum dot product */ + SIMD_FORCE_INLINE long maxDot( const btVector3 *array, long array_count, btScalar &dotOut ) const; + + /**@brief returns index of minimum dot product between this and vectors in array[] + * @param array The other vectors + * @param array_count The number of other vectors + * @param dotOut The minimum dot product */ + SIMD_FORCE_INLINE long minDot( const btVector3 *array, long array_count, btScalar &dotOut ) const; + + /* create a vector as btVector3( this->dot( btVector3 v0 ), this->dot( btVector3 v1), this->dot( btVector3 v2 )) */ + SIMD_FORCE_INLINE btVector3 dot3( const btVector3 &v0, const btVector3 &v1, const btVector3 &v2 ) const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + + __m128 a0 = _mm_mul_ps( v0.mVec128, this->mVec128 ); + __m128 a1 = _mm_mul_ps( v1.mVec128, this->mVec128 ); + __m128 a2 = _mm_mul_ps( v2.mVec128, this->mVec128 ); + __m128 b0 = _mm_unpacklo_ps( a0, a1 ); + __m128 b1 = _mm_unpackhi_ps( a0, a1 ); + __m128 b2 = _mm_unpacklo_ps( a2, _mm_setzero_ps() ); + __m128 r = _mm_movelh_ps( b0, b2 ); + r = _mm_add_ps( r, _mm_movehl_ps( b2, b0 )); + a2 = _mm_and_ps( a2, btvxyzMaskf); + r = _mm_add_ps( r, btCastdTo128f (_mm_move_sd( btCastfTo128d(a2), btCastfTo128d(b1) ))); + return btVector3(r); + +#elif defined(BT_USE_NEON) + static const uint32x4_t xyzMask = (const uint32x4_t){ -1, -1, -1, 0 }; + float32x4_t a0 = vmulq_f32( v0.mVec128, this->mVec128); + float32x4_t a1 = vmulq_f32( v1.mVec128, this->mVec128); + float32x4_t a2 = vmulq_f32( v2.mVec128, this->mVec128); + float32x2x2_t zLo = vtrn_f32( vget_high_f32(a0), vget_high_f32(a1)); + a2 = (float32x4_t) vandq_u32((uint32x4_t) a2, xyzMask ); + float32x2_t b0 = vadd_f32( vpadd_f32( vget_low_f32(a0), vget_low_f32(a1)), zLo.val[0] ); + float32x2_t b1 = vpadd_f32( vpadd_f32( vget_low_f32(a2), vget_high_f32(a2)), vdup_n_f32(0.0f)); + return btVector3( vcombine_f32(b0, b1) ); +#else + return btVector3( dot(v0), dot(v1), dot(v2)); +#endif + } +}; + +/**@brief Return the sum of two vectors (Point symantics)*/ +SIMD_FORCE_INLINE btVector3 +operator+(const btVector3& v1, const btVector3& v2) +{ +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btVector3(_mm_add_ps(v1.mVec128, v2.mVec128)); +#elif defined(BT_USE_NEON) + return btVector3(vaddq_f32(v1.mVec128, v2.mVec128)); +#else + return btVector3( + v1.m_floats[0] + v2.m_floats[0], + v1.m_floats[1] + v2.m_floats[1], + v1.m_floats[2] + v2.m_floats[2]); +#endif +} + +/**@brief Return the elementwise product of two vectors */ +SIMD_FORCE_INLINE btVector3 +operator*(const btVector3& v1, const btVector3& v2) +{ +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btVector3(_mm_mul_ps(v1.mVec128, v2.mVec128)); +#elif defined(BT_USE_NEON) + return btVector3(vmulq_f32(v1.mVec128, v2.mVec128)); +#else + return btVector3( + v1.m_floats[0] * v2.m_floats[0], + v1.m_floats[1] * v2.m_floats[1], + v1.m_floats[2] * v2.m_floats[2]); +#endif +} + +/**@brief Return the difference between two vectors */ +SIMD_FORCE_INLINE btVector3 +operator-(const btVector3& v1, const btVector3& v2) +{ +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) + + // without _mm_and_ps this code causes slowdown in Concave moving + __m128 r = _mm_sub_ps(v1.mVec128, v2.mVec128); + return btVector3(_mm_and_ps(r, btvFFF0fMask)); +#elif defined(BT_USE_NEON) + float32x4_t r = vsubq_f32(v1.mVec128, v2.mVec128); + return btVector3((float32x4_t)vandq_s32((int32x4_t)r, btvFFF0Mask)); +#else + return btVector3( + v1.m_floats[0] - v2.m_floats[0], + v1.m_floats[1] - v2.m_floats[1], + v1.m_floats[2] - v2.m_floats[2]); +#endif +} + +/**@brief Return the negative of the vector */ +SIMD_FORCE_INLINE btVector3 +operator-(const btVector3& v) +{ +#if (defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) + __m128 r = _mm_xor_ps(v.mVec128, btvMzeroMask); + return btVector3(_mm_and_ps(r, btvFFF0fMask)); +#elif defined(BT_USE_NEON) + return btVector3((btSimdFloat4)veorq_s32((int32x4_t)v.mVec128, (int32x4_t)btvMzeroMask)); +#else + return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]); +#endif +} + +/**@brief Return the vector scaled by s */ +SIMD_FORCE_INLINE btVector3 +operator*(const btVector3& v, const btScalar& s) +{ +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0) + return btVector3(_mm_mul_ps(v.mVec128, vs)); +#elif defined(BT_USE_NEON) + float32x4_t r = vmulq_n_f32(v.mVec128, s); + return btVector3((float32x4_t)vandq_s32((int32x4_t)r, btvFFF0Mask)); +#else + return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s); +#endif +} + +/**@brief Return the vector scaled by s */ +SIMD_FORCE_INLINE btVector3 +operator*(const btScalar& s, const btVector3& v) +{ + return v * s; +} + +/**@brief Return the vector inversely scaled by s */ +SIMD_FORCE_INLINE btVector3 +operator/(const btVector3& v, const btScalar& s) +{ + btFullAssert(s != btScalar(0.0)); +#if 0 //defined(BT_USE_SSE_IN_API) +// this code is not faster ! + __m128 vs = _mm_load_ss(&s); + vs = _mm_div_ss(v1110, vs); + vs = bt_pshufd_ps(vs, 0x00); // (S S S S) + + return btVector3(_mm_mul_ps(v.mVec128, vs)); +#else + return v * (btScalar(1.0) / s); +#endif +} + +/**@brief Return the vector inversely scaled by s */ +SIMD_FORCE_INLINE btVector3 +operator/(const btVector3& v1, const btVector3& v2) +{ +#if (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) + __m128 vec = _mm_div_ps(v1.mVec128, v2.mVec128); + vec = _mm_and_ps(vec, btvFFF0fMask); + return btVector3(vec); +#elif defined(BT_USE_NEON) + float32x4_t x, y, v, m; + + x = v1.mVec128; + y = v2.mVec128; + + v = vrecpeq_f32(y); // v ~ 1/y + m = vrecpsq_f32(y, v); // m = (2-v*y) + v = vmulq_f32(v, m); // vv = v*m ~~ 1/y + m = vrecpsq_f32(y, v); // mm = (2-vv*y) + v = vmulq_f32(v, x); // x*vv + v = vmulq_f32(v, m); // (x*vv)*(2-vv*y) = x*(vv(2-vv*y)) ~~~ x/y + + return btVector3(v); +#else + return btVector3( + v1.m_floats[0] / v2.m_floats[0], + v1.m_floats[1] / v2.m_floats[1], + v1.m_floats[2] / v2.m_floats[2]); +#endif +} + +/**@brief Return the dot product between two vectors */ +SIMD_FORCE_INLINE btScalar +btDot(const btVector3& v1, const btVector3& v2) +{ + return v1.dot(v2); +} + + +/**@brief Return the distance squared between two vectors */ +SIMD_FORCE_INLINE btScalar +btDistance2(const btVector3& v1, const btVector3& v2) +{ + return v1.distance2(v2); +} + + +/**@brief Return the distance between two vectors */ +SIMD_FORCE_INLINE btScalar +btDistance(const btVector3& v1, const btVector3& v2) +{ + return v1.distance(v2); +} + +/**@brief Return the angle between two vectors */ +SIMD_FORCE_INLINE btScalar +btAngle(const btVector3& v1, const btVector3& v2) +{ + return v1.angle(v2); +} + +/**@brief Return the cross product of two vectors */ +SIMD_FORCE_INLINE btVector3 +btCross(const btVector3& v1, const btVector3& v2) +{ + return v1.cross(v2); +} + +SIMD_FORCE_INLINE btScalar +btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3) +{ + return v1.triple(v2, v3); +} + +/**@brief Return the linear interpolation between two vectors + * @param v1 One vector + * @param v2 The other vector + * @param t The ration of this to v (t = 0 => return v1, t=1 => return v2) */ +SIMD_FORCE_INLINE btVector3 +lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) +{ + return v1.lerp(v2, t); +} + + + +SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const +{ + return (v - *this).length2(); +} + +SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const +{ + return (v - *this).length(); +} + +SIMD_FORCE_INLINE btVector3 btVector3::normalized() const +{ +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + btVector3 norm = *this; + + return norm.normalize(); +#else + return *this / length(); +#endif +} + +SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar _angle ) const +{ + // wAxis must be a unit lenght vector + +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + + __m128 O = _mm_mul_ps(wAxis.mVec128, mVec128); + btScalar ssin = btSin( _angle ); + __m128 C = wAxis.cross( mVec128 ).mVec128; + O = _mm_and_ps(O, btvFFF0fMask); + btScalar scos = btCos( _angle ); + + __m128 vsin = _mm_load_ss(&ssin); // (S 0 0 0) + __m128 vcos = _mm_load_ss(&scos); // (S 0 0 0) + + __m128 Y = bt_pshufd_ps(O, 0xC9); // (Y Z X 0) + __m128 Z = bt_pshufd_ps(O, 0xD2); // (Z X Y 0) + O = _mm_add_ps(O, Y); + vsin = bt_pshufd_ps(vsin, 0x80); // (S S S 0) + O = _mm_add_ps(O, Z); + vcos = bt_pshufd_ps(vcos, 0x80); // (S S S 0) + + vsin = vsin * C; + O = O * wAxis.mVec128; + __m128 X = mVec128 - O; + + O = O + vsin; + vcos = vcos * X; + O = O + vcos; + + return btVector3(O); +#else + btVector3 o = wAxis * wAxis.dot( *this ); + btVector3 _x = *this - o; + btVector3 _y; + + _y = wAxis.cross( *this ); + + return ( o + _x * btCos( _angle ) + _y * btSin( _angle ) ); +#endif +} + +SIMD_FORCE_INLINE long btVector3::maxDot( const btVector3 *array, long array_count, btScalar &dotOut ) const +{ +#if defined (BT_USE_SSE) || defined (BT_USE_NEON) + #if defined _WIN32 || defined (BT_USE_SSE) + const long scalar_cutoff = 10; + long _maxdot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut ); + #elif defined BT_USE_NEON + const long scalar_cutoff = 4; + extern long (*_maxdot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut ); + #endif + if( array_count < scalar_cutoff ) +#else + +#endif//BT_USE_SSE || BT_USE_NEON + { + btScalar maxDot = -SIMD_INFINITY; + int i = 0; + int ptIndex = -1; + for( i = 0; i < array_count; i++ ) + { + btScalar dot = array[i].dot(*this); + + if( dot > maxDot ) + { + maxDot = dot; + ptIndex = i; + } + } + + dotOut = maxDot; + return ptIndex; + } +#if defined (BT_USE_SSE) || defined (BT_USE_NEON) + return _maxdot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut ); +#endif +} + +SIMD_FORCE_INLINE long btVector3::minDot( const btVector3 *array, long array_count, btScalar &dotOut ) const +{ +#if defined (BT_USE_SSE) || defined (BT_USE_NEON) + #if defined BT_USE_SSE + const long scalar_cutoff = 10; + long _mindot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut ); + #elif defined BT_USE_NEON + const long scalar_cutoff = 4; + extern long (*_mindot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut ); + #else + #error unhandled arch! + #endif + + if( array_count < scalar_cutoff ) +#endif//BT_USE_SSE || BT_USE_NEON + { + btScalar minDot = SIMD_INFINITY; + int i = 0; + int ptIndex = -1; + + for( i = 0; i < array_count; i++ ) + { + btScalar dot = array[i].dot(*this); + + if( dot < minDot ) + { + minDot = dot; + ptIndex = i; + } + } + + dotOut = minDot; + + return ptIndex; + } +#if defined (BT_USE_SSE) || defined (BT_USE_NEON) + return _mindot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut ); +#endif +} + + +class btVector4 : public btVector3 +{ +public: + + SIMD_FORCE_INLINE btVector4() {} + + + SIMD_FORCE_INLINE btVector4(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) + : btVector3(_x,_y,_z) + { + m_floats[3] = _w; + } + +#if (defined (BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined (BT_USE_NEON) + SIMD_FORCE_INLINE btVector4(const btSimdFloat4 vec) + { + mVec128 = vec; + } + + SIMD_FORCE_INLINE btVector4(const btVector3& rhs) + { + mVec128 = rhs.mVec128; + } + + SIMD_FORCE_INLINE btVector4& + operator=(const btVector4& v) + { + mVec128 = v.mVec128; + return *this; + } +#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + SIMD_FORCE_INLINE btVector4 absolute4() const + { +#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + return btVector4(_mm_and_ps(mVec128, btvAbsfMask)); +#elif defined(BT_USE_NEON) + return btVector4(vabsq_f32(mVec128)); +#else + return btVector4( + btFabs(m_floats[0]), + btFabs(m_floats[1]), + btFabs(m_floats[2]), + btFabs(m_floats[3])); +#endif + } + + + btScalar getW() const { return m_floats[3];} + + + SIMD_FORCE_INLINE int maxAxis4() const + { + int maxIndex = -1; + btScalar maxVal = btScalar(-BT_LARGE_FLOAT); + if (m_floats[0] > maxVal) + { + maxIndex = 0; + maxVal = m_floats[0]; + } + if (m_floats[1] > maxVal) + { + maxIndex = 1; + maxVal = m_floats[1]; + } + if (m_floats[2] > maxVal) + { + maxIndex = 2; + maxVal =m_floats[2]; + } + if (m_floats[3] > maxVal) + { + maxIndex = 3; + maxVal = m_floats[3]; + } + + return maxIndex; + } + + + SIMD_FORCE_INLINE int minAxis4() const + { + int minIndex = -1; + btScalar minVal = btScalar(BT_LARGE_FLOAT); + if (m_floats[0] < minVal) + { + minIndex = 0; + minVal = m_floats[0]; + } + if (m_floats[1] < minVal) + { + minIndex = 1; + minVal = m_floats[1]; + } + if (m_floats[2] < minVal) + { + minIndex = 2; + minVal =m_floats[2]; + } + if (m_floats[3] < minVal) + { + minIndex = 3; + minVal = m_floats[3]; + } + + return minIndex; + } + + + SIMD_FORCE_INLINE int closestAxis4() const + { + return absolute4().maxAxis4(); + } + + + + + /**@brief Set x,y,z and zero w + * @param x Value of x + * @param y Value of y + * @param z Value of z + */ + + +/* void getValue(btScalar *m) const + { + m[0] = m_floats[0]; + m[1] = m_floats[1]; + m[2] =m_floats[2]; + } +*/ +/**@brief Set the values + * @param x Value of x + * @param y Value of y + * @param z Value of z + * @param w Value of w + */ + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) + { + m_floats[0]=_x; + m_floats[1]=_y; + m_floats[2]=_z; + m_floats[3]=_w; + } + + +}; + + +///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization +SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal) +{ + #ifdef BT_USE_DOUBLE_PRECISION + unsigned char* dest = (unsigned char*) &destVal; + unsigned char* src = (unsigned char*) &sourceVal; + dest[0] = src[7]; + dest[1] = src[6]; + dest[2] = src[5]; + dest[3] = src[4]; + dest[4] = src[3]; + dest[5] = src[2]; + dest[6] = src[1]; + dest[7] = src[0]; +#else + unsigned char* dest = (unsigned char*) &destVal; + unsigned char* src = (unsigned char*) &sourceVal; + dest[0] = src[3]; + dest[1] = src[2]; + dest[2] = src[1]; + dest[3] = src[0]; +#endif //BT_USE_DOUBLE_PRECISION +} +///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization +SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec) +{ + for (int i=0;i<4;i++) + { + btSwapScalarEndian(sourceVec[i],destVec[i]); + } + +} + +///btUnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization +SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector) +{ + + btVector3 swappedVec; + for (int i=0;i<4;i++) + { + btSwapScalarEndian(vector[i],swappedVec[i]); + } + vector = swappedVec; +} + +template +SIMD_FORCE_INLINE void btPlaneSpace1 (const T& n, T& p, T& q) +{ + if (btFabs(n[2]) > SIMDSQRT12) { + // choose p in y-z plane + btScalar a = n[1]*n[1] + n[2]*n[2]; + btScalar k = btRecipSqrt (a); + p[0] = 0; + p[1] = -n[2]*k; + p[2] = n[1]*k; + // set q = n x p + q[0] = a*k; + q[1] = -n[0]*p[2]; + q[2] = n[0]*p[1]; + } + else { + // choose p in x-y plane + btScalar a = n[0]*n[0] + n[1]*n[1]; + btScalar k = btRecipSqrt (a); + p[0] = -n[1]*k; + p[1] = n[0]*k; + p[2] = 0; + // set q = n x p + q[0] = -n[2]*p[1]; + q[1] = n[2]*p[0]; + q[2] = a*k; + } +} + + +struct btVector3FloatData +{ + float m_floats[4]; +}; + +struct btVector3DoubleData +{ + double m_floats[4]; + +}; + +SIMD_FORCE_INLINE void btVector3::serializeFloat(struct btVector3FloatData& dataOut) const +{ + ///could also do a memcpy, check if it is worth it + for (int i=0;i<4;i++) + dataOut.m_floats[i] = float(m_floats[i]); +} + +SIMD_FORCE_INLINE void btVector3::deSerializeFloat(const struct btVector3FloatData& dataIn) +{ + for (int i=0;i<4;i++) + m_floats[i] = btScalar(dataIn.m_floats[i]); +} + + +SIMD_FORCE_INLINE void btVector3::serializeDouble(struct btVector3DoubleData& dataOut) const +{ + ///could also do a memcpy, check if it is worth it + for (int i=0;i<4;i++) + dataOut.m_floats[i] = double(m_floats[i]); +} + +SIMD_FORCE_INLINE void btVector3::deSerializeDouble(const struct btVector3DoubleData& dataIn) +{ + for (int i=0;i<4;i++) + m_floats[i] = btScalar(dataIn.m_floats[i]); +} + + +SIMD_FORCE_INLINE void btVector3::serialize(struct btVector3Data& dataOut) const +{ + ///could also do a memcpy, check if it is worth it + for (int i=0;i<4;i++) + dataOut.m_floats[i] = m_floats[i]; +} + +SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3Data& dataIn) +{ + for (int i=0;i<4;i++) + m_floats[i] = dataIn.m_floats[i]; +} + +#endif //BT_VECTOR3_H diff --git a/src/LinearMath/premake4.lua b/src/LinearMath/premake4.lua new file mode 100644 index 0000000..b698bed --- /dev/null +++ b/src/LinearMath/premake4.lua @@ -0,0 +1,11 @@ + project "LinearMath" + + kind "StaticLib" + targetdir "../../lib" + includedirs { + "..", + } + files { + "**.cpp", + "**.h" + } \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..ec39e7a --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,563 @@ +bullet_includedir = $(includedir)/bullet +nobase_bullet_include_HEADERS = \ + btBulletDynamicsCommon.h \ + Bullet-C-Api.h \ + btBulletCollisionCommon.h + +if CONDITIONAL_BUILD_MULTITHREADED +nobase_bullet_include_HEADERS += \ + BulletMultiThreaded/PosixThreadSupport.h \ + BulletMultiThreaded/vectormath/scalar/cpp/mat_aos.h \ + BulletMultiThreaded/vectormath/scalar/cpp/vec_aos.h \ + BulletMultiThreaded/vectormath/scalar/cpp/quat_aos.h \ + BulletMultiThreaded/vectormath/scalar/cpp/vectormath_aos.h \ + BulletMultiThreaded/PpuAddressSpace.h \ + BulletMultiThreaded/SpuCollisionTaskProcess.h \ + BulletMultiThreaded/PlatformDefinitions.h \ + BulletMultiThreaded/vectormath2bullet.h \ + BulletMultiThreaded/SpuGatheringCollisionDispatcher.h \ + BulletMultiThreaded/SpuCollisionObjectWrapper.h \ + BulletMultiThreaded/SpuSampleTaskProcess.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h \ + BulletMultiThreaded/SpuSync.h \ + BulletMultiThreaded/btThreadSupportInterface.h \ + BulletMultiThreaded/SpuLibspe2Support.h \ + BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h \ + BulletMultiThreaded/SpuFakeDma.h \ + BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h \ + BulletMultiThreaded/SpuDoubleBuffer.h \ + BulletMultiThreaded/Win32ThreadSupport.h \ + BulletMultiThreaded/SequentialThreadSupport.h + +lib_LTLIBRARIES = libLinearMath.la libBulletCollision.la libBulletDynamics.la libBulletSoftBody.la libBulletMultiThreaded.la + +libBulletMultiThreaded_la_CXXFLAGS = ${CXXFLAGS} -I./BulletMultiThreaded/vectormath/scalar/cpp +libBulletMultiThreaded_la_SOURCES =\ + BulletMultiThreaded/SpuCollisionObjectWrapper.cpp \ + BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp \ + BulletMultiThreaded/SpuLibspe2Support.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp \ + BulletMultiThreaded/btThreadSupportInterface.cpp \ + BulletMultiThreaded/SequentialThreadSupport.cpp \ + BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp \ + BulletMultiThreaded/Win32ThreadSupport.cpp \ + BulletMultiThreaded/SpuFakeDma.cpp \ + BulletMultiThreaded/PosixThreadSupport.cpp \ + BulletMultiThreaded/SpuCollisionTaskProcess.cpp \ + BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp \ + BulletMultiThreaded/SpuSampleTaskProcess.cpp \ + BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h \ + BulletMultiThreaded/PpuAddressSpace.h \ + BulletMultiThreaded/SpuSampleTaskProcess.h \ + BulletMultiThreaded/SequentialThreadSupport.h \ + BulletMultiThreaded/PlatformDefinitions.h \ + BulletMultiThreaded/Win32ThreadSupport.h \ + BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h \ + BulletMultiThreaded/btThreadSupportInterface.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h \ + BulletMultiThreaded/SpuGatheringCollisionDispatcher.h \ + BulletMultiThreaded/SpuFakeDma.h \ + BulletMultiThreaded/SpuSync.h \ + BulletMultiThreaded/SpuCollisionObjectWrapper.h \ + BulletMultiThreaded/SpuDoubleBuffer.h \ + BulletMultiThreaded/SpuCollisionTaskProcess.h \ + BulletMultiThreaded/PosixThreadSupport.h \ + BulletMultiThreaded/SpuLibspe2Support.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h + +else +lib_LTLIBRARIES = libLinearMath.la libBulletCollision.la libBulletDynamics.la libBulletSoftBody.la +endif + + +libLinearMath_la_SOURCES = \ + LinearMath/btQuickprof.cpp \ + LinearMath/btGeometryUtil.cpp \ + LinearMath/btAlignedAllocator.cpp \ + LinearMath/btSerializer.cpp \ + LinearMath/btConvexHull.cpp \ + LinearMath/btPolarDecomposition.cpp \ + LinearMath/btVector3.cpp \ + LinearMath/btConvexHullComputer.cpp \ + LinearMath/btHashMap.h \ + LinearMath/btConvexHull.h \ + LinearMath/btAabbUtil2.h \ + LinearMath/btGeometryUtil.h \ + LinearMath/btQuadWord.h \ + LinearMath/btPoolAllocator.h \ + LinearMath/btPolarDecomposition.h \ + LinearMath/btScalar.h \ + LinearMath/btMinMax.h \ + LinearMath/btVector3.h \ + LinearMath/btList.h \ + LinearMath/btStackAlloc.h \ + LinearMath/btMatrix3x3.h \ + LinearMath/btMotionState.h \ + LinearMath/btAlignedAllocator.h \ + LinearMath/btQuaternion.h \ + LinearMath/btAlignedObjectArray.h \ + LinearMath/btQuickprof.h \ + LinearMath/btSerializer.h \ + LinearMath/btTransformUtil.h \ + LinearMath/btTransform.h \ + LinearMath/btDefaultMotionState.h \ + LinearMath/btIDebugDraw.h \ + LinearMath/btRandom.h + + +libBulletCollision_la_SOURCES = \ + BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp \ + BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp \ + BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp \ + BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp \ + BulletCollision/NarrowPhaseCollision/btConvexCast.cpp \ + BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp \ + BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp \ + BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp \ + BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btCollisionObject.cpp \ + BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btGhostObject.cpp \ + BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp \ + BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp \ + BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp \ + BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp \ + BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp \ + BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp \ + BulletCollision/CollisionDispatch/btManifoldResult.cpp \ + BulletCollision/CollisionDispatch/btCollisionWorld.cpp \ + BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btUnionFind.cpp \ + BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp \ + BulletCollision/CollisionShapes/btTetrahedronShape.cpp \ + BulletCollision/CollisionShapes/btShapeHull.cpp \ + BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp \ + BulletCollision/CollisionShapes/btCompoundShape.cpp \ + BulletCollision/CollisionShapes/btConeShape.cpp \ + BulletCollision/CollisionShapes/btConvexPolyhedron.cpp \ + BulletCollision/CollisionShapes/btMultiSphereShape.cpp \ + BulletCollision/CollisionShapes/btUniformScalingShape.cpp \ + BulletCollision/CollisionShapes/btSphereShape.cpp \ + BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp \ + BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btTriangleBuffer.cpp \ + BulletCollision/CollisionShapes/btStaticPlaneShape.cpp \ + BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp \ + BulletCollision/CollisionShapes/btEmptyShape.cpp \ + BulletCollision/CollisionShapes/btCollisionShape.cpp \ + BulletCollision/CollisionShapes/btConvexShape.cpp \ + BulletCollision/CollisionShapes/btConvex2dShape.cpp \ + BulletCollision/CollisionShapes/btConvexInternalShape.cpp \ + BulletCollision/CollisionShapes/btConvexHullShape.cpp \ + BulletCollision/CollisionShapes/btTriangleCallback.cpp \ + BulletCollision/CollisionShapes/btCapsuleShape.cpp \ + BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btConcaveShape.cpp \ + BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp \ + BulletCollision/CollisionShapes/btBoxShape.cpp \ + BulletCollision/CollisionShapes/btBox2dShape.cpp \ + BulletCollision/CollisionShapes/btOptimizedBvh.cpp \ + BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp \ + BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btCylinderShape.cpp \ + BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btStridingMeshInterface.cpp \ + BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp \ + BulletCollision/CollisionShapes/btTriangleMesh.cpp \ + BulletCollision/BroadphaseCollision/btAxisSweep3.cpp \ + BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp \ + BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp \ + BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp \ + BulletCollision/BroadphaseCollision/btDispatcher.cpp \ + BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp \ + BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp \ + BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp \ + BulletCollision/BroadphaseCollision/btDbvt.cpp \ + BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h \ + BulletCollision/NarrowPhaseCollision/btConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpa2.h \ + BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h \ + BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btPointCollector.h \ + BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h \ + BulletCollision/NarrowPhaseCollision/btRaycastCallback.h \ + BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h \ + BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btPersistentManifold.h \ + BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btManifoldPoint.h \ + BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h \ + BulletCollision/CollisionDispatch/btCollisionObject.h \ + BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h \ + BulletCollision/CollisionDispatch/btGhostObject.h \ + BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionCreateFunc.h \ + BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxDetector.h \ + BulletCollision/CollisionDispatch/btCollisionDispatcher.h \ + BulletCollision/CollisionDispatch/SphereTriangleDetector.h \ + BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btUnionFind.h \ + BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btSimulationIslandManager.h \ + BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCollisionWorld.h \ + BulletCollision/CollisionDispatch/btInternalEdgeUtility.h \ + BulletCollision/CollisionDispatch/btManifoldResult.h \ + BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionConfiguration.h \ + BulletCollision/CollisionShapes/btConvexShape.h \ + BulletCollision/CollisionShapes/btConvex2dShape.h \ + BulletCollision/CollisionShapes/btTriangleCallback.h \ + BulletCollision/CollisionShapes/btPolyhedralConvexShape.h \ + BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btCompoundShape.h \ + BulletCollision/CollisionShapes/btBoxShape.h \ + BulletCollision/CollisionShapes/btBox2dShape.h \ + BulletCollision/CollisionShapes/btMultiSphereShape.h \ + BulletCollision/CollisionShapes/btCollisionMargin.h \ + BulletCollision/CollisionShapes/btConcaveShape.h \ + BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btEmptyShape.h \ + BulletCollision/CollisionShapes/btUniformScalingShape.h \ + BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btMaterial.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h \ + BulletCollision/CollisionShapes/btTriangleInfoMap.h \ + BulletCollision/CollisionShapes/btSphereShape.h \ + BulletCollision/CollisionShapes/btConvexPointCloudShape.h \ + BulletCollision/CollisionShapes/btCapsuleShape.h \ + BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h \ + BulletCollision/CollisionShapes/btCollisionShape.h \ + BulletCollision/CollisionShapes/btStaticPlaneShape.h \ + BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btStridingMeshInterface.h \ + BulletCollision/CollisionShapes/btTriangleMesh.h \ + BulletCollision/CollisionShapes/btTriangleBuffer.h \ + BulletCollision/CollisionShapes/btShapeHull.h \ + BulletCollision/CollisionShapes/btMinkowskiSumShape.h \ + BulletCollision/CollisionShapes/btOptimizedBvh.h \ + BulletCollision/CollisionShapes/btTriangleShape.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h \ + BulletCollision/CollisionShapes/btCylinderShape.h \ + BulletCollision/CollisionShapes/btTetrahedronShape.h \ + BulletCollision/CollisionShapes/btConvexInternalShape.h \ + BulletCollision/CollisionShapes/btConeShape.h \ + BulletCollision/CollisionShapes/btConvexHullShape.h \ + BulletCollision/BroadphaseCollision/btAxisSweep3.h \ + BulletCollision/BroadphaseCollision/btDbvtBroadphase.h \ + BulletCollision/BroadphaseCollision/btSimpleBroadphase.h \ + BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h \ + BulletCollision/BroadphaseCollision/btDbvt.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h \ + BulletCollision/BroadphaseCollision/btDispatcher.h \ + BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h \ + BulletCollision/BroadphaseCollision/btBroadphaseProxy.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCache.h \ + BulletCollision/BroadphaseCollision/btBroadphaseInterface.h \ + BulletCollision/BroadphaseCollision/btQuantizedBvh.h \ + BulletCollision/Gimpact/btGImpactBvh.cpp\ + BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp\ + BulletCollision/Gimpact/btTriangleShapeEx.cpp\ + BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp\ + BulletCollision/Gimpact/btGImpactShape.cpp\ + BulletCollision/Gimpact/gim_box_set.cpp\ + BulletCollision/Gimpact/gim_contact.cpp\ + BulletCollision/Gimpact/gim_memory.cpp\ + BulletCollision/Gimpact/gim_tri_collision.cpp + +libBulletDynamics_la_SOURCES = \ + BulletDynamics/Dynamics/btRigidBody.cpp \ + BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp \ + BulletDynamics/Dynamics/Bullet-C-API.cpp \ + BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp \ + BulletDynamics/ConstraintSolver/btGearConstraint.cpp \ + BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp \ + BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp \ + BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp \ + BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp \ + BulletDynamics/ConstraintSolver/btTypedConstraint.cpp \ + BulletDynamics/ConstraintSolver/btContactConstraint.cpp \ + BulletDynamics/ConstraintSolver/btSliderConstraint.cpp \ + BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp \ + BulletDynamics/ConstraintSolver/btHingeConstraint.cpp \ + BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp \ + BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp \ + BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp \ + BulletDynamics/Vehicle/btWheelInfo.cpp \ + BulletDynamics/Vehicle/btRaycastVehicle.cpp \ + BulletDynamics/Character/btKinematicCharacterController.cpp \ + BulletDynamics/Character/btKinematicCharacterController.h \ + BulletDynamics/Character/btCharacterControllerInterface.h \ + BulletDynamics/Dynamics/btActionInterface.h \ + BulletDynamics/Dynamics/btSimpleDynamicsWorld.h \ + BulletDynamics/Dynamics/btRigidBody.h \ + BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h \ + BulletDynamics/Dynamics/btDynamicsWorld.h \ + BulletDynamics/ConstraintSolver/btSolverBody.h \ + BulletDynamics/ConstraintSolver/btConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btConeTwistConstraint.h \ + BulletDynamics/ConstraintSolver/btTypedConstraint.h \ + BulletDynamics/ConstraintSolver/btContactSolverInfo.h \ + BulletDynamics/ConstraintSolver/btContactConstraint.h \ + BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h \ + BulletDynamics/ConstraintSolver/btJacobianEntry.h \ + BulletDynamics/ConstraintSolver/btSolverConstraint.h \ + BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btGearConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h \ + BulletDynamics/ConstraintSolver/btSliderConstraint.h \ + BulletDynamics/ConstraintSolver/btHingeConstraint.h \ + BulletDynamics/ConstraintSolver/btHinge2Constraint.h \ + BulletDynamics/ConstraintSolver/btUniversalConstraint.h \ + BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h \ + BulletDynamics/Vehicle/btVehicleRaycaster.h \ + BulletDynamics/Vehicle/btRaycastVehicle.h \ + BulletDynamics/Vehicle/btWheelInfo.h + +libBulletSoftBody_la_SOURCES = \ + BulletSoftBody/btDefaultSoftBodySolver.cpp \ + BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp \ + BulletSoftBody/btSoftBody.cpp \ + BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp \ + BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp \ + BulletSoftBody/btSoftRigidDynamicsWorld.cpp \ + BulletSoftBody/btSoftBodyHelpers.cpp \ + BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp \ + BulletSoftBody/btSparseSDF.h \ + BulletSoftBody/btSoftRigidCollisionAlgorithm.h \ + BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h \ + BulletSoftBody/btSoftBody.h \ + BulletSoftBody/btSoftSoftCollisionAlgorithm.h \ + BulletSoftBody/btSoftBodyInternals.h \ + BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h \ + BulletSoftBody/btSoftRigidDynamicsWorld.h \ + BulletSoftBody/btSoftBodyHelpers.h + + + +nobase_bullet_include_HEADERS += \ + BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h \ + BulletSoftBody/btSoftBodyInternals.h \ + BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h \ + BulletSoftBody/btSoftSoftCollisionAlgorithm.h \ + BulletSoftBody/btSoftBody.h \ + BulletSoftBody/btSoftBodyHelpers.h \ + BulletSoftBody/btSparseSDF.h \ + BulletSoftBody/btSoftRigidCollisionAlgorithm.h \ + BulletSoftBody/btSoftRigidDynamicsWorld.h \ + BulletDynamics/Vehicle/btRaycastVehicle.h \ + BulletDynamics/Vehicle/btWheelInfo.h \ + BulletDynamics/Vehicle/btVehicleRaycaster.h \ + BulletDynamics/Dynamics/btActionInterface.h \ + BulletDynamics/Dynamics/btRigidBody.h \ + BulletDynamics/Dynamics/btDynamicsWorld.h \ + BulletDynamics/Dynamics/btSimpleDynamicsWorld.h \ + BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h \ + BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btSolverConstraint.h \ + BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h \ + BulletDynamics/ConstraintSolver/btTypedConstraint.h \ + BulletDynamics/ConstraintSolver/btSliderConstraint.h \ + BulletDynamics/ConstraintSolver/btConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btContactConstraint.h \ + BulletDynamics/ConstraintSolver/btContactSolverInfo.h \ + BulletDynamics/ConstraintSolver/btGearConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h \ + BulletDynamics/ConstraintSolver/btJacobianEntry.h \ + BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h \ + BulletDynamics/ConstraintSolver/btConeTwistConstraint.h \ + BulletDynamics/ConstraintSolver/btHingeConstraint.h \ + BulletDynamics/ConstraintSolver/btHinge2Constraint.h \ + BulletDynamics/ConstraintSolver/btUniversalConstraint.h \ + BulletDynamics/ConstraintSolver/btSolverBody.h \ + BulletDynamics/Character/btCharacterControllerInterface.h \ + BulletDynamics/Character/btKinematicCharacterController.h \ + BulletCollision/CollisionShapes/btShapeHull.h \ + BulletCollision/CollisionShapes/btConcaveShape.h \ + BulletCollision/CollisionShapes/btCollisionMargin.h \ + BulletCollision/CollisionShapes/btCompoundShape.h \ + BulletCollision/CollisionShapes/btConvexHullShape.h \ + BulletCollision/CollisionShapes/btCylinderShape.h \ + BulletCollision/CollisionShapes/btTriangleMesh.h \ + BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h \ + BulletCollision/CollisionShapes/btUniformScalingShape.h \ + BulletCollision/CollisionShapes/btConvexPointCloudShape.h \ + BulletCollision/CollisionShapes/btTetrahedronShape.h \ + BulletCollision/CollisionShapes/btCapsuleShape.h \ + BulletCollision/CollisionShapes/btSphereShape.h \ + BulletCollision/CollisionShapes/btMultiSphereShape.h \ + BulletCollision/CollisionShapes/btConvexInternalShape.h \ + BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btStridingMeshInterface.h \ + BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btEmptyShape.h \ + BulletCollision/CollisionShapes/btOptimizedBvh.h \ + BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btTriangleCallback.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h \ + BulletCollision/CollisionShapes/btTriangleInfoMap.h \ + BulletCollision/CollisionShapes/btTriangleBuffer.h \ + BulletCollision/CollisionShapes/btConvexShape.h \ + BulletCollision/CollisionShapes/btConvex2dShape.h \ + BulletCollision/CollisionShapes/btStaticPlaneShape.h \ + BulletCollision/CollisionShapes/btConeShape.h \ + BulletCollision/CollisionShapes/btCollisionShape.h \ + BulletCollision/CollisionShapes/btTriangleShape.h \ + BulletCollision/CollisionShapes/btBoxShape.h \ + BulletCollision/CollisionShapes/btBox2dShape.h \ + BulletCollision/CollisionShapes/btMinkowskiSumShape.h \ + BulletCollision/CollisionShapes/btTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btMaterial.h \ + BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btPolyhedralConvexShape.h \ + BulletCollision/NarrowPhaseCollision/btConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpa2.h \ + BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h \ + BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h \ + BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h \ + BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h \ + BulletCollision/NarrowPhaseCollision/btPersistentManifold.h \ + BulletCollision/NarrowPhaseCollision/btManifoldPoint.h \ + BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btRaycastCallback.h \ + BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btPointCollector.h \ + BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h \ + BulletCollision/BroadphaseCollision/btDbvt.h \ + BulletCollision/BroadphaseCollision/btDispatcher.h \ + BulletCollision/BroadphaseCollision/btDbvtBroadphase.h \ + BulletCollision/BroadphaseCollision/btSimpleBroadphase.h \ + BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h \ + BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h \ + BulletCollision/BroadphaseCollision/btQuantizedBvh.h \ + BulletCollision/BroadphaseCollision/btAxisSweep3.h \ + BulletCollision/BroadphaseCollision/btBroadphaseInterface.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCache.h \ + BulletCollision/BroadphaseCollision/btBroadphaseProxy.h \ + BulletCollision/CollisionDispatch/btUnionFind.h \ + BulletCollision/CollisionDispatch/btCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCollisionDispatcher.h \ + BulletCollision/CollisionDispatch/SphereTriangleDetector.h \ + BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionWorld.h \ + BulletCollision/CollisionDispatch/btCollisionCreateFunc.h \ + BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionObject.h \ + BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h \ + BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btGhostObject.h \ + BulletCollision/CollisionDispatch/btSimulationIslandManager.h \ + BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxDetector.h \ + BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btInternalEdgeUtility.h \ + BulletCollision/CollisionDispatch/btManifoldResult.h \ + BulletCollision/Gimpact/gim_memory.h \ + BulletCollision/Gimpact/gim_clip_polygon.h \ + BulletCollision/Gimpact/gim_bitset.h \ + BulletCollision/Gimpact/gim_linear_math.h \ + BulletCollision/Gimpact/btGeometryOperations.h \ + BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h \ + BulletCollision/Gimpact/btGImpactBvh.h \ + BulletCollision/Gimpact/gim_box_set.h \ + BulletCollision/Gimpact/gim_array.h \ + BulletCollision/Gimpact/btGImpactShape.h \ + BulletCollision/Gimpact/btTriangleShapeEx.h \ + BulletCollision/Gimpact/btClipPolygon.h \ + BulletCollision/Gimpact/gim_box_collision.h \ + BulletCollision/Gimpact/gim_tri_collision.h \ + BulletCollision/Gimpact/gim_geometry.h \ + BulletCollision/Gimpact/gim_math.h \ + BulletCollision/Gimpact/btQuantization.h \ + BulletCollision/Gimpact/btGImpactQuantizedBvh.h \ + BulletCollision/Gimpact/gim_geom_types.h \ + BulletCollision/Gimpact/gim_basic_geometry_operations.h \ + BulletCollision/Gimpact/gim_contact.h \ + BulletCollision/Gimpact/gim_hash_table.h \ + BulletCollision/Gimpact/gim_radixsort.h \ + BulletCollision/Gimpact/btGImpactMassUtil.h \ + BulletCollision/Gimpact/btGenericPoolAllocator.h \ + BulletCollision/Gimpact/btBoxCollision.h \ + BulletCollision/Gimpact/btContactProcessing.h \ + LinearMath/btGeometryUtil.h \ + LinearMath/btConvexHull.h \ + LinearMath/btList.h \ + LinearMath/btMatrix3x3.h \ + LinearMath/btVector3.h \ + LinearMath/btPoolAllocator.h \ + LinearMath/btPolarDecomposition.h \ + LinearMath/btScalar.h \ + LinearMath/btDefaultMotionState.h \ + LinearMath/btTransform.h \ + LinearMath/btQuadWord.h \ + LinearMath/btAabbUtil2.h \ + LinearMath/btTransformUtil.h \ + LinearMath/btRandom.h \ + LinearMath/btQuaternion.h \ + LinearMath/btMinMax.h \ + LinearMath/btMotionState.h \ + LinearMath/btIDebugDraw.h \ + LinearMath/btAlignedAllocator.h \ + LinearMath/btStackAlloc.h \ + LinearMath/btAlignedObjectArray.h \ + LinearMath/btHashMap.h \ + LinearMath/btQuickprof.h\ + LinearMath/btSerializer.h diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..d454b06 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,2603 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@am__append_1 = \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/PosixThreadSupport.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/vectormath/scalar/cpp/mat_aos.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/vectormath/scalar/cpp/vec_aos.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/vectormath/scalar/cpp/quat_aos.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/vectormath/scalar/cpp/vectormath_aos.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/PpuAddressSpace.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuCollisionTaskProcess.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/PlatformDefinitions.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/vectormath2bullet.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuGatheringCollisionDispatcher.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuCollisionObjectWrapper.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSampleTaskProcess.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSync.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/btThreadSupportInterface.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuLibspe2Support.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuFakeDma.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuDoubleBuffer.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/Win32ThreadSupport.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SequentialThreadSupport.h + +subdir = src +DIST_COMMON = $(am__nobase_bullet_include_HEADERS_DIST) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" \ + "$(DESTDIR)$(bullet_includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libBulletCollision_la_LIBADD = +am_libBulletCollision_la_OBJECTS = btRaycastCallback.lo \ + btMinkowskiPenetrationDepthSolver.lo btSubSimplexConvexCast.lo \ + btGjkEpaPenetrationDepthSolver.lo btGjkConvexCast.lo \ + btPersistentManifold.lo btConvexCast.lo \ + btPolyhedralContactClipping.lo btContinuousConvexCollision.lo \ + btGjkPairDetector.lo btGjkEpa2.lo btVoronoiSimplexSolver.lo \ + btActivatingCollisionAlgorithm.lo btCollisionObject.lo \ + btEmptyCollisionAlgorithm.lo btGhostObject.lo \ + btSphereSphereCollisionAlgorithm.lo \ + btSphereBoxCollisionAlgorithm.lo btCollisionDispatcher.lo \ + btDefaultCollisionConfiguration.lo \ + btSimulationIslandManager.lo btBoxBoxDetector.lo \ + btConvexPlaneCollisionAlgorithm.lo \ + btConvexConcaveCollisionAlgorithm.lo \ + btBoxBoxCollisionAlgorithm.lo \ + btBox2dBox2dCollisionAlgorithm.lo SphereTriangleDetector.lo \ + btInternalEdgeUtility.lo btManifoldResult.lo \ + btCollisionWorld.lo btSphereTriangleCollisionAlgorithm.lo \ + btConvexConvexAlgorithm.lo btConvex2dConvex2dAlgorithm.lo \ + btUnionFind.lo btCompoundCollisionAlgorithm.lo \ + btTetrahedronShape.lo btShapeHull.lo btMinkowskiSumShape.lo \ + btCompoundShape.lo btConeShape.lo btConvexPolyhedron.lo \ + btMultiSphereShape.lo btUniformScalingShape.lo \ + btSphereShape.lo btTriangleIndexVertexArray.lo \ + btBvhTriangleMeshShape.lo btTriangleMeshShape.lo \ + btTriangleBuffer.lo btStaticPlaneShape.lo \ + btPolyhedralConvexShape.lo btEmptyShape.lo btCollisionShape.lo \ + btConvexShape.lo btConvex2dShape.lo btConvexInternalShape.lo \ + btConvexHullShape.lo btTriangleCallback.lo btCapsuleShape.lo \ + btConvexTriangleMeshShape.lo btConcaveShape.lo \ + btConvexPointCloudShape.lo btBoxShape.lo btBox2dShape.lo \ + btOptimizedBvh.lo btHeightfieldTerrainShape.lo \ + btMultimaterialTriangleMeshShape.lo btCylinderShape.lo \ + btScaledBvhTriangleMeshShape.lo btStridingMeshInterface.lo \ + btTriangleIndexVertexMaterialArray.lo btTriangleMesh.lo \ + btAxisSweep3.lo btOverlappingPairCache.lo btDbvtBroadphase.lo \ + btMultiSapBroadphase.lo btDispatcher.lo btBroadphaseProxy.lo \ + btQuantizedBvh.lo btCollisionAlgorithm.lo btDbvt.lo \ + btSimpleBroadphase.lo btGImpactBvh.lo btGImpactQuantizedBvh.lo \ + btTriangleShapeEx.lo btGImpactCollisionAlgorithm.lo \ + btGImpactShape.lo gim_box_set.lo gim_contact.lo gim_memory.lo \ + gim_tri_collision.lo +libBulletCollision_la_OBJECTS = $(am_libBulletCollision_la_OBJECTS) +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@am_libBulletCollision_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@ -rpath $(libdir) +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@am_libBulletCollision_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ -rpath $(libdir) +libBulletDynamics_la_LIBADD = +am_libBulletDynamics_la_OBJECTS = btRigidBody.lo \ + btSimpleDynamicsWorld.lo Bullet-C-API.lo \ + btDiscreteDynamicsWorld.lo btGearConstraint.lo \ + btGeneric6DofConstraint.lo btGeneric6DofSpringConstraint.lo \ + btSolve2LinearConstraint.lo btPoint2PointConstraint.lo \ + btTypedConstraint.lo btContactConstraint.lo \ + btSliderConstraint.lo btConeTwistConstraint.lo \ + btHingeConstraint.lo btHinge2Constraint.lo \ + btUniversalConstraint.lo \ + btSequentialImpulseConstraintSolver.lo btWheelInfo.lo \ + btRaycastVehicle.lo btKinematicCharacterController.lo +libBulletDynamics_la_OBJECTS = $(am_libBulletDynamics_la_OBJECTS) +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@am_libBulletDynamics_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@ -rpath $(libdir) +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@am_libBulletDynamics_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ -rpath $(libdir) +libBulletMultiThreaded_la_LIBADD = +am__libBulletMultiThreaded_la_SOURCES_DIST = \ + BulletMultiThreaded/SpuCollisionObjectWrapper.cpp \ + BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp \ + BulletMultiThreaded/SpuLibspe2Support.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp \ + BulletMultiThreaded/btThreadSupportInterface.cpp \ + BulletMultiThreaded/SequentialThreadSupport.cpp \ + BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp \ + BulletMultiThreaded/Win32ThreadSupport.cpp \ + BulletMultiThreaded/SpuFakeDma.cpp \ + BulletMultiThreaded/PosixThreadSupport.cpp \ + BulletMultiThreaded/SpuCollisionTaskProcess.cpp \ + BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp \ + BulletMultiThreaded/SpuSampleTaskProcess.cpp \ + BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h \ + BulletMultiThreaded/PpuAddressSpace.h \ + BulletMultiThreaded/SpuSampleTaskProcess.h \ + BulletMultiThreaded/SequentialThreadSupport.h \ + BulletMultiThreaded/PlatformDefinitions.h \ + BulletMultiThreaded/Win32ThreadSupport.h \ + BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h \ + BulletMultiThreaded/btThreadSupportInterface.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h \ + BulletMultiThreaded/SpuGatheringCollisionDispatcher.h \ + BulletMultiThreaded/SpuFakeDma.h BulletMultiThreaded/SpuSync.h \ + BulletMultiThreaded/SpuCollisionObjectWrapper.h \ + BulletMultiThreaded/SpuDoubleBuffer.h \ + BulletMultiThreaded/SpuCollisionTaskProcess.h \ + BulletMultiThreaded/PosixThreadSupport.h \ + BulletMultiThreaded/SpuLibspe2Support.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@am_libBulletMultiThreaded_la_OBJECTS = libBulletMultiThreaded_la-SpuCollisionObjectWrapper.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuSampleTask.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuLibspe2Support.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuContactResult.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuGatheringCollisionTask.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuCollisionShapes.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-btThreadSupportInterface.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SequentialThreadSupport.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-Win32ThreadSupport.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuFakeDma.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-PosixThreadSupport.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuCollisionTaskProcess.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-SpuSampleTaskProcess.lo \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ libBulletMultiThreaded_la-boxBoxDistance.lo +libBulletMultiThreaded_la_OBJECTS = \ + $(am_libBulletMultiThreaded_la_OBJECTS) +libBulletMultiThreaded_la_LINK = $(LIBTOOL) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@am_libBulletMultiThreaded_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ -rpath $(libdir) +libBulletSoftBody_la_LIBADD = +am_libBulletSoftBody_la_OBJECTS = btDefaultSoftBodySolver.lo \ + btSoftBodyRigidBodyCollisionConfiguration.lo btSoftBody.lo \ + btSoftRigidCollisionAlgorithm.lo \ + btSoftBodyConcaveCollisionAlgorithm.lo \ + btSoftRigidDynamicsWorld.lo btSoftBodyHelpers.lo \ + btSoftSoftCollisionAlgorithm.lo +libBulletSoftBody_la_OBJECTS = $(am_libBulletSoftBody_la_OBJECTS) +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@am_libBulletSoftBody_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@ -rpath $(libdir) +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@am_libBulletSoftBody_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ -rpath $(libdir) +libLinearMath_la_LIBADD = +am_libLinearMath_la_OBJECTS = btQuickprof.lo btGeometryUtil.lo \ + btAlignedAllocator.lo btSerializer.lo btConvexHull.lo \ + btPolarDecomposition.lo btVector3.lo btConvexHullComputer.lo +libLinearMath_la_OBJECTS = $(am_libLinearMath_la_OBJECTS) +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@am_libLinearMath_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@ -rpath $(libdir) +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@am_libLinearMath_la_rpath = \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ -rpath $(libdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libBulletCollision_la_SOURCES) \ + $(libBulletDynamics_la_SOURCES) \ + $(libBulletMultiThreaded_la_SOURCES) \ + $(libBulletSoftBody_la_SOURCES) $(libLinearMath_la_SOURCES) +DIST_SOURCES = $(libBulletCollision_la_SOURCES) \ + $(libBulletDynamics_la_SOURCES) \ + $(am__libBulletMultiThreaded_la_SOURCES_DIST) \ + $(libBulletSoftBody_la_SOURCES) $(libLinearMath_la_SOURCES) +am__nobase_bullet_include_HEADERS_DIST = btBulletDynamicsCommon.h \ + Bullet-C-Api.h btBulletCollisionCommon.h \ + BulletMultiThreaded/PosixThreadSupport.h \ + BulletMultiThreaded/vectormath/scalar/cpp/mat_aos.h \ + BulletMultiThreaded/vectormath/scalar/cpp/vec_aos.h \ + BulletMultiThreaded/vectormath/scalar/cpp/quat_aos.h \ + BulletMultiThreaded/vectormath/scalar/cpp/vectormath_aos.h \ + BulletMultiThreaded/PpuAddressSpace.h \ + BulletMultiThreaded/SpuCollisionTaskProcess.h \ + BulletMultiThreaded/PlatformDefinitions.h \ + BulletMultiThreaded/vectormath2bullet.h \ + BulletMultiThreaded/SpuGatheringCollisionDispatcher.h \ + BulletMultiThreaded/SpuCollisionObjectWrapper.h \ + BulletMultiThreaded/SpuSampleTaskProcess.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h \ + BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h \ + BulletMultiThreaded/SpuSync.h \ + BulletMultiThreaded/btThreadSupportInterface.h \ + BulletMultiThreaded/SpuLibspe2Support.h \ + BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h \ + BulletMultiThreaded/SpuFakeDma.h \ + BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h \ + BulletMultiThreaded/SpuDoubleBuffer.h \ + BulletMultiThreaded/Win32ThreadSupport.h \ + BulletMultiThreaded/SequentialThreadSupport.h \ + BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h \ + BulletSoftBody/btSoftBodyInternals.h \ + BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h \ + BulletSoftBody/btSoftSoftCollisionAlgorithm.h \ + BulletSoftBody/btSoftBody.h BulletSoftBody/btSoftBodyHelpers.h \ + BulletSoftBody/btSparseSDF.h \ + BulletSoftBody/btSoftRigidCollisionAlgorithm.h \ + BulletSoftBody/btSoftRigidDynamicsWorld.h \ + BulletDynamics/Vehicle/btRaycastVehicle.h \ + BulletDynamics/Vehicle/btWheelInfo.h \ + BulletDynamics/Vehicle/btVehicleRaycaster.h \ + BulletDynamics/Dynamics/btActionInterface.h \ + BulletDynamics/Dynamics/btRigidBody.h \ + BulletDynamics/Dynamics/btDynamicsWorld.h \ + BulletDynamics/Dynamics/btSimpleDynamicsWorld.h \ + BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h \ + BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btSolverConstraint.h \ + BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h \ + BulletDynamics/ConstraintSolver/btTypedConstraint.h \ + BulletDynamics/ConstraintSolver/btSliderConstraint.h \ + BulletDynamics/ConstraintSolver/btConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btContactConstraint.h \ + BulletDynamics/ConstraintSolver/btContactSolverInfo.h \ + BulletDynamics/ConstraintSolver/btGearConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h \ + BulletDynamics/ConstraintSolver/btJacobianEntry.h \ + BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h \ + BulletDynamics/ConstraintSolver/btConeTwistConstraint.h \ + BulletDynamics/ConstraintSolver/btHingeConstraint.h \ + BulletDynamics/ConstraintSolver/btHinge2Constraint.h \ + BulletDynamics/ConstraintSolver/btUniversalConstraint.h \ + BulletDynamics/ConstraintSolver/btSolverBody.h \ + BulletDynamics/Character/btCharacterControllerInterface.h \ + BulletDynamics/Character/btKinematicCharacterController.h \ + BulletCollision/CollisionShapes/btShapeHull.h \ + BulletCollision/CollisionShapes/btConcaveShape.h \ + BulletCollision/CollisionShapes/btCollisionMargin.h \ + BulletCollision/CollisionShapes/btCompoundShape.h \ + BulletCollision/CollisionShapes/btConvexHullShape.h \ + BulletCollision/CollisionShapes/btCylinderShape.h \ + BulletCollision/CollisionShapes/btTriangleMesh.h \ + BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h \ + BulletCollision/CollisionShapes/btUniformScalingShape.h \ + BulletCollision/CollisionShapes/btConvexPointCloudShape.h \ + BulletCollision/CollisionShapes/btTetrahedronShape.h \ + BulletCollision/CollisionShapes/btCapsuleShape.h \ + BulletCollision/CollisionShapes/btSphereShape.h \ + BulletCollision/CollisionShapes/btMultiSphereShape.h \ + BulletCollision/CollisionShapes/btConvexInternalShape.h \ + BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btStridingMeshInterface.h \ + BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btEmptyShape.h \ + BulletCollision/CollisionShapes/btOptimizedBvh.h \ + BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btTriangleCallback.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h \ + BulletCollision/CollisionShapes/btTriangleInfoMap.h \ + BulletCollision/CollisionShapes/btTriangleBuffer.h \ + BulletCollision/CollisionShapes/btConvexShape.h \ + BulletCollision/CollisionShapes/btConvex2dShape.h \ + BulletCollision/CollisionShapes/btStaticPlaneShape.h \ + BulletCollision/CollisionShapes/btConeShape.h \ + BulletCollision/CollisionShapes/btCollisionShape.h \ + BulletCollision/CollisionShapes/btTriangleShape.h \ + BulletCollision/CollisionShapes/btBoxShape.h \ + BulletCollision/CollisionShapes/btBox2dShape.h \ + BulletCollision/CollisionShapes/btMinkowskiSumShape.h \ + BulletCollision/CollisionShapes/btTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btMaterial.h \ + BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btPolyhedralConvexShape.h \ + BulletCollision/NarrowPhaseCollision/btConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpa2.h \ + BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h \ + BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h \ + BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h \ + BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h \ + BulletCollision/NarrowPhaseCollision/btPersistentManifold.h \ + BulletCollision/NarrowPhaseCollision/btManifoldPoint.h \ + BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btRaycastCallback.h \ + BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btPointCollector.h \ + BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h \ + BulletCollision/BroadphaseCollision/btDbvt.h \ + BulletCollision/BroadphaseCollision/btDispatcher.h \ + BulletCollision/BroadphaseCollision/btDbvtBroadphase.h \ + BulletCollision/BroadphaseCollision/btSimpleBroadphase.h \ + BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h \ + BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h \ + BulletCollision/BroadphaseCollision/btQuantizedBvh.h \ + BulletCollision/BroadphaseCollision/btAxisSweep3.h \ + BulletCollision/BroadphaseCollision/btBroadphaseInterface.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCache.h \ + BulletCollision/BroadphaseCollision/btBroadphaseProxy.h \ + BulletCollision/CollisionDispatch/btUnionFind.h \ + BulletCollision/CollisionDispatch/btCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCollisionDispatcher.h \ + BulletCollision/CollisionDispatch/SphereTriangleDetector.h \ + BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionWorld.h \ + BulletCollision/CollisionDispatch/btCollisionCreateFunc.h \ + BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionObject.h \ + BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h \ + BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btGhostObject.h \ + BulletCollision/CollisionDispatch/btSimulationIslandManager.h \ + BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxDetector.h \ + BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btInternalEdgeUtility.h \ + BulletCollision/CollisionDispatch/btManifoldResult.h \ + BulletCollision/Gimpact/gim_memory.h \ + BulletCollision/Gimpact/gim_clip_polygon.h \ + BulletCollision/Gimpact/gim_bitset.h \ + BulletCollision/Gimpact/gim_linear_math.h \ + BulletCollision/Gimpact/btGeometryOperations.h \ + BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h \ + BulletCollision/Gimpact/btGImpactBvh.h \ + BulletCollision/Gimpact/gim_box_set.h \ + BulletCollision/Gimpact/gim_array.h \ + BulletCollision/Gimpact/btGImpactShape.h \ + BulletCollision/Gimpact/btTriangleShapeEx.h \ + BulletCollision/Gimpact/btClipPolygon.h \ + BulletCollision/Gimpact/gim_box_collision.h \ + BulletCollision/Gimpact/gim_tri_collision.h \ + BulletCollision/Gimpact/gim_geometry.h \ + BulletCollision/Gimpact/gim_math.h \ + BulletCollision/Gimpact/btQuantization.h \ + BulletCollision/Gimpact/btGImpactQuantizedBvh.h \ + BulletCollision/Gimpact/gim_geom_types.h \ + BulletCollision/Gimpact/gim_basic_geometry_operations.h \ + BulletCollision/Gimpact/gim_contact.h \ + BulletCollision/Gimpact/gim_hash_table.h \ + BulletCollision/Gimpact/gim_radixsort.h \ + BulletCollision/Gimpact/btGImpactMassUtil.h \ + BulletCollision/Gimpact/btGenericPoolAllocator.h \ + BulletCollision/Gimpact/btBoxCollision.h \ + BulletCollision/Gimpact/btContactProcessing.h \ + LinearMath/btGeometryUtil.h LinearMath/btConvexHull.h \ + LinearMath/btList.h LinearMath/btMatrix3x3.h \ + LinearMath/btVector3.h LinearMath/btPoolAllocator.h \ + LinearMath/btPolarDecomposition.h LinearMath/btScalar.h \ + LinearMath/btDefaultMotionState.h LinearMath/btTransform.h \ + LinearMath/btQuadWord.h LinearMath/btAabbUtil2.h \ + LinearMath/btTransformUtil.h LinearMath/btRandom.h \ + LinearMath/btQuaternion.h LinearMath/btMinMax.h \ + LinearMath/btMotionState.h LinearMath/btIDebugDraw.h \ + LinearMath/btAlignedAllocator.h LinearMath/btStackAlloc.h \ + LinearMath/btAlignedObjectArray.h LinearMath/btHashMap.h \ + LinearMath/btQuickprof.h LinearMath/btSerializer.h +HEADERS = $(nobase_bullet_include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +opengl_LIBS = @opengl_LIBS@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +bullet_includedir = $(includedir)/bullet +nobase_bullet_include_HEADERS = btBulletDynamicsCommon.h \ + Bullet-C-Api.h btBulletCollisionCommon.h $(am__append_1) \ + BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h \ + BulletSoftBody/btSoftBodyInternals.h \ + BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h \ + BulletSoftBody/btSoftSoftCollisionAlgorithm.h \ + BulletSoftBody/btSoftBody.h BulletSoftBody/btSoftBodyHelpers.h \ + BulletSoftBody/btSparseSDF.h \ + BulletSoftBody/btSoftRigidCollisionAlgorithm.h \ + BulletSoftBody/btSoftRigidDynamicsWorld.h \ + BulletDynamics/Vehicle/btRaycastVehicle.h \ + BulletDynamics/Vehicle/btWheelInfo.h \ + BulletDynamics/Vehicle/btVehicleRaycaster.h \ + BulletDynamics/Dynamics/btActionInterface.h \ + BulletDynamics/Dynamics/btRigidBody.h \ + BulletDynamics/Dynamics/btDynamicsWorld.h \ + BulletDynamics/Dynamics/btSimpleDynamicsWorld.h \ + BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h \ + BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btSolverConstraint.h \ + BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h \ + BulletDynamics/ConstraintSolver/btTypedConstraint.h \ + BulletDynamics/ConstraintSolver/btSliderConstraint.h \ + BulletDynamics/ConstraintSolver/btConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btContactConstraint.h \ + BulletDynamics/ConstraintSolver/btContactSolverInfo.h \ + BulletDynamics/ConstraintSolver/btGearConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h \ + BulletDynamics/ConstraintSolver/btJacobianEntry.h \ + BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h \ + BulletDynamics/ConstraintSolver/btConeTwistConstraint.h \ + BulletDynamics/ConstraintSolver/btHingeConstraint.h \ + BulletDynamics/ConstraintSolver/btHinge2Constraint.h \ + BulletDynamics/ConstraintSolver/btUniversalConstraint.h \ + BulletDynamics/ConstraintSolver/btSolverBody.h \ + BulletDynamics/Character/btCharacterControllerInterface.h \ + BulletDynamics/Character/btKinematicCharacterController.h \ + BulletCollision/CollisionShapes/btShapeHull.h \ + BulletCollision/CollisionShapes/btConcaveShape.h \ + BulletCollision/CollisionShapes/btCollisionMargin.h \ + BulletCollision/CollisionShapes/btCompoundShape.h \ + BulletCollision/CollisionShapes/btConvexHullShape.h \ + BulletCollision/CollisionShapes/btCylinderShape.h \ + BulletCollision/CollisionShapes/btTriangleMesh.h \ + BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h \ + BulletCollision/CollisionShapes/btUniformScalingShape.h \ + BulletCollision/CollisionShapes/btConvexPointCloudShape.h \ + BulletCollision/CollisionShapes/btTetrahedronShape.h \ + BulletCollision/CollisionShapes/btCapsuleShape.h \ + BulletCollision/CollisionShapes/btSphereShape.h \ + BulletCollision/CollisionShapes/btMultiSphereShape.h \ + BulletCollision/CollisionShapes/btConvexInternalShape.h \ + BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btStridingMeshInterface.h \ + BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btEmptyShape.h \ + BulletCollision/CollisionShapes/btOptimizedBvh.h \ + BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btTriangleCallback.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h \ + BulletCollision/CollisionShapes/btTriangleInfoMap.h \ + BulletCollision/CollisionShapes/btTriangleBuffer.h \ + BulletCollision/CollisionShapes/btConvexShape.h \ + BulletCollision/CollisionShapes/btConvex2dShape.h \ + BulletCollision/CollisionShapes/btStaticPlaneShape.h \ + BulletCollision/CollisionShapes/btConeShape.h \ + BulletCollision/CollisionShapes/btCollisionShape.h \ + BulletCollision/CollisionShapes/btTriangleShape.h \ + BulletCollision/CollisionShapes/btBoxShape.h \ + BulletCollision/CollisionShapes/btBox2dShape.h \ + BulletCollision/CollisionShapes/btMinkowskiSumShape.h \ + BulletCollision/CollisionShapes/btTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btMaterial.h \ + BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btPolyhedralConvexShape.h \ + BulletCollision/NarrowPhaseCollision/btConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpa2.h \ + BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h \ + BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h \ + BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h \ + BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h \ + BulletCollision/NarrowPhaseCollision/btPersistentManifold.h \ + BulletCollision/NarrowPhaseCollision/btManifoldPoint.h \ + BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btRaycastCallback.h \ + BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btPointCollector.h \ + BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h \ + BulletCollision/BroadphaseCollision/btDbvt.h \ + BulletCollision/BroadphaseCollision/btDispatcher.h \ + BulletCollision/BroadphaseCollision/btDbvtBroadphase.h \ + BulletCollision/BroadphaseCollision/btSimpleBroadphase.h \ + BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h \ + BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h \ + BulletCollision/BroadphaseCollision/btQuantizedBvh.h \ + BulletCollision/BroadphaseCollision/btAxisSweep3.h \ + BulletCollision/BroadphaseCollision/btBroadphaseInterface.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCache.h \ + BulletCollision/BroadphaseCollision/btBroadphaseProxy.h \ + BulletCollision/CollisionDispatch/btUnionFind.h \ + BulletCollision/CollisionDispatch/btCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCollisionDispatcher.h \ + BulletCollision/CollisionDispatch/SphereTriangleDetector.h \ + BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionWorld.h \ + BulletCollision/CollisionDispatch/btCollisionCreateFunc.h \ + BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionObject.h \ + BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h \ + BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btGhostObject.h \ + BulletCollision/CollisionDispatch/btSimulationIslandManager.h \ + BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxDetector.h \ + BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btInternalEdgeUtility.h \ + BulletCollision/CollisionDispatch/btManifoldResult.h \ + BulletCollision/Gimpact/gim_memory.h \ + BulletCollision/Gimpact/gim_clip_polygon.h \ + BulletCollision/Gimpact/gim_bitset.h \ + BulletCollision/Gimpact/gim_linear_math.h \ + BulletCollision/Gimpact/btGeometryOperations.h \ + BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h \ + BulletCollision/Gimpact/btGImpactBvh.h \ + BulletCollision/Gimpact/gim_box_set.h \ + BulletCollision/Gimpact/gim_array.h \ + BulletCollision/Gimpact/btGImpactShape.h \ + BulletCollision/Gimpact/btTriangleShapeEx.h \ + BulletCollision/Gimpact/btClipPolygon.h \ + BulletCollision/Gimpact/gim_box_collision.h \ + BulletCollision/Gimpact/gim_tri_collision.h \ + BulletCollision/Gimpact/gim_geometry.h \ + BulletCollision/Gimpact/gim_math.h \ + BulletCollision/Gimpact/btQuantization.h \ + BulletCollision/Gimpact/btGImpactQuantizedBvh.h \ + BulletCollision/Gimpact/gim_geom_types.h \ + BulletCollision/Gimpact/gim_basic_geometry_operations.h \ + BulletCollision/Gimpact/gim_contact.h \ + BulletCollision/Gimpact/gim_hash_table.h \ + BulletCollision/Gimpact/gim_radixsort.h \ + BulletCollision/Gimpact/btGImpactMassUtil.h \ + BulletCollision/Gimpact/btGenericPoolAllocator.h \ + BulletCollision/Gimpact/btBoxCollision.h \ + BulletCollision/Gimpact/btContactProcessing.h \ + LinearMath/btGeometryUtil.h LinearMath/btConvexHull.h \ + LinearMath/btList.h LinearMath/btMatrix3x3.h \ + LinearMath/btVector3.h LinearMath/btPoolAllocator.h \ + LinearMath/btPolarDecomposition.h LinearMath/btScalar.h \ + LinearMath/btDefaultMotionState.h LinearMath/btTransform.h \ + LinearMath/btQuadWord.h LinearMath/btAabbUtil2.h \ + LinearMath/btTransformUtil.h LinearMath/btRandom.h \ + LinearMath/btQuaternion.h LinearMath/btMinMax.h \ + LinearMath/btMotionState.h LinearMath/btIDebugDraw.h \ + LinearMath/btAlignedAllocator.h LinearMath/btStackAlloc.h \ + LinearMath/btAlignedObjectArray.h LinearMath/btHashMap.h \ + LinearMath/btQuickprof.h LinearMath/btSerializer.h +@CONDITIONAL_BUILD_MULTITHREADED_FALSE@lib_LTLIBRARIES = libLinearMath.la libBulletCollision.la libBulletDynamics.la libBulletSoftBody.la +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@lib_LTLIBRARIES = libLinearMath.la libBulletCollision.la libBulletDynamics.la libBulletSoftBody.la libBulletMultiThreaded.la +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@libBulletMultiThreaded_la_CXXFLAGS = ${CXXFLAGS} -I./BulletMultiThreaded/vectormath/scalar/cpp +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@libBulletMultiThreaded_la_SOURCES = \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuCollisionObjectWrapper.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuLibspe2Support.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/btThreadSupportInterface.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SequentialThreadSupport.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/Win32ThreadSupport.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuFakeDma.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/PosixThreadSupport.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuCollisionTaskProcess.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSampleTaskProcess.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSampleTask/SpuSampleTask.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/PpuAddressSpace.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSampleTaskProcess.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SequentialThreadSupport.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/PlatformDefinitions.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/Win32ThreadSupport.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/btThreadSupportInterface.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuConvexPenetrationDepthSolver.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuPreferredPenetrationDirections.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuLocalSupport.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuGatheringCollisionDispatcher.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuFakeDma.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuSync.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuCollisionObjectWrapper.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuDoubleBuffer.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuCollisionTaskProcess.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/PosixThreadSupport.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuLibspe2Support.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.h \ +@CONDITIONAL_BUILD_MULTITHREADED_TRUE@ BulletMultiThreaded/SpuNarrowPhaseCollisionTask/Box.h + +libLinearMath_la_SOURCES = \ + LinearMath/btQuickprof.cpp \ + LinearMath/btGeometryUtil.cpp \ + LinearMath/btAlignedAllocator.cpp \ + LinearMath/btSerializer.cpp \ + LinearMath/btConvexHull.cpp \ + LinearMath/btPolarDecomposition.cpp \ + LinearMath/btVector3.cpp \ + LinearMath/btConvexHullComputer.cpp \ + LinearMath/btHashMap.h \ + LinearMath/btConvexHull.h \ + LinearMath/btAabbUtil2.h \ + LinearMath/btGeometryUtil.h \ + LinearMath/btQuadWord.h \ + LinearMath/btPoolAllocator.h \ + LinearMath/btPolarDecomposition.h \ + LinearMath/btScalar.h \ + LinearMath/btMinMax.h \ + LinearMath/btVector3.h \ + LinearMath/btList.h \ + LinearMath/btStackAlloc.h \ + LinearMath/btMatrix3x3.h \ + LinearMath/btMotionState.h \ + LinearMath/btAlignedAllocator.h \ + LinearMath/btQuaternion.h \ + LinearMath/btAlignedObjectArray.h \ + LinearMath/btQuickprof.h \ + LinearMath/btSerializer.h \ + LinearMath/btTransformUtil.h \ + LinearMath/btTransform.h \ + LinearMath/btDefaultMotionState.h \ + LinearMath/btIDebugDraw.h \ + LinearMath/btRandom.h + +libBulletCollision_la_SOURCES = \ + BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp \ + BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp \ + BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp \ + BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp \ + BulletCollision/NarrowPhaseCollision/btConvexCast.cpp \ + BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp \ + BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp \ + BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp \ + BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btCollisionObject.cpp \ + BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btGhostObject.cpp \ + BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp \ + BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp \ + BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp \ + BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp \ + BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp \ + BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp \ + BulletCollision/CollisionDispatch/btManifoldResult.cpp \ + BulletCollision/CollisionDispatch/btCollisionWorld.cpp \ + BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp \ + BulletCollision/CollisionDispatch/btUnionFind.cpp \ + BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp \ + BulletCollision/CollisionShapes/btTetrahedronShape.cpp \ + BulletCollision/CollisionShapes/btShapeHull.cpp \ + BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp \ + BulletCollision/CollisionShapes/btCompoundShape.cpp \ + BulletCollision/CollisionShapes/btConeShape.cpp \ + BulletCollision/CollisionShapes/btConvexPolyhedron.cpp \ + BulletCollision/CollisionShapes/btMultiSphereShape.cpp \ + BulletCollision/CollisionShapes/btUniformScalingShape.cpp \ + BulletCollision/CollisionShapes/btSphereShape.cpp \ + BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp \ + BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btTriangleBuffer.cpp \ + BulletCollision/CollisionShapes/btStaticPlaneShape.cpp \ + BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp \ + BulletCollision/CollisionShapes/btEmptyShape.cpp \ + BulletCollision/CollisionShapes/btCollisionShape.cpp \ + BulletCollision/CollisionShapes/btConvexShape.cpp \ + BulletCollision/CollisionShapes/btConvex2dShape.cpp \ + BulletCollision/CollisionShapes/btConvexInternalShape.cpp \ + BulletCollision/CollisionShapes/btConvexHullShape.cpp \ + BulletCollision/CollisionShapes/btTriangleCallback.cpp \ + BulletCollision/CollisionShapes/btCapsuleShape.cpp \ + BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btConcaveShape.cpp \ + BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp \ + BulletCollision/CollisionShapes/btBoxShape.cpp \ + BulletCollision/CollisionShapes/btBox2dShape.cpp \ + BulletCollision/CollisionShapes/btOptimizedBvh.cpp \ + BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp \ + BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btCylinderShape.cpp \ + BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp \ + BulletCollision/CollisionShapes/btStridingMeshInterface.cpp \ + BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp \ + BulletCollision/CollisionShapes/btTriangleMesh.cpp \ + BulletCollision/BroadphaseCollision/btAxisSweep3.cpp \ + BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp \ + BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp \ + BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp \ + BulletCollision/BroadphaseCollision/btDispatcher.cpp \ + BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp \ + BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp \ + BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp \ + BulletCollision/BroadphaseCollision/btDbvt.cpp \ + BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp \ + BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h \ + BulletCollision/NarrowPhaseCollision/btConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btGjkEpa2.h \ + BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h \ + BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btPointCollector.h \ + BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h \ + BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h \ + BulletCollision/NarrowPhaseCollision/btRaycastCallback.h \ + BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h \ + BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btPersistentManifold.h \ + BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h \ + BulletCollision/NarrowPhaseCollision/btManifoldPoint.h \ + BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h \ + BulletCollision/CollisionDispatch/btCollisionObject.h \ + BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h \ + BulletCollision/CollisionDispatch/btGhostObject.h \ + BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionCreateFunc.h \ + BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h \ + BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h \ + BulletCollision/CollisionDispatch/btBoxBoxDetector.h \ + BulletCollision/CollisionDispatch/btCollisionDispatcher.h \ + BulletCollision/CollisionDispatch/SphereTriangleDetector.h \ + BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btUnionFind.h \ + BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btSimulationIslandManager.h \ + BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h \ + BulletCollision/CollisionDispatch/btCollisionWorld.h \ + BulletCollision/CollisionDispatch/btInternalEdgeUtility.h \ + BulletCollision/CollisionDispatch/btManifoldResult.h \ + BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h \ + BulletCollision/CollisionDispatch/btCollisionConfiguration.h \ + BulletCollision/CollisionShapes/btConvexShape.h \ + BulletCollision/CollisionShapes/btConvex2dShape.h \ + BulletCollision/CollisionShapes/btTriangleCallback.h \ + BulletCollision/CollisionShapes/btPolyhedralConvexShape.h \ + BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btCompoundShape.h \ + BulletCollision/CollisionShapes/btBoxShape.h \ + BulletCollision/CollisionShapes/btBox2dShape.h \ + BulletCollision/CollisionShapes/btMultiSphereShape.h \ + BulletCollision/CollisionShapes/btCollisionMargin.h \ + BulletCollision/CollisionShapes/btConcaveShape.h \ + BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btEmptyShape.h \ + BulletCollision/CollisionShapes/btUniformScalingShape.h \ + BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btMaterial.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h \ + BulletCollision/CollisionShapes/btTriangleInfoMap.h \ + BulletCollision/CollisionShapes/btSphereShape.h \ + BulletCollision/CollisionShapes/btConvexPointCloudShape.h \ + BulletCollision/CollisionShapes/btCapsuleShape.h \ + BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h \ + BulletCollision/CollisionShapes/btCollisionShape.h \ + BulletCollision/CollisionShapes/btStaticPlaneShape.h \ + BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btTriangleMeshShape.h \ + BulletCollision/CollisionShapes/btStridingMeshInterface.h \ + BulletCollision/CollisionShapes/btTriangleMesh.h \ + BulletCollision/CollisionShapes/btTriangleBuffer.h \ + BulletCollision/CollisionShapes/btShapeHull.h \ + BulletCollision/CollisionShapes/btMinkowskiSumShape.h \ + BulletCollision/CollisionShapes/btOptimizedBvh.h \ + BulletCollision/CollisionShapes/btTriangleShape.h \ + BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h \ + BulletCollision/CollisionShapes/btCylinderShape.h \ + BulletCollision/CollisionShapes/btTetrahedronShape.h \ + BulletCollision/CollisionShapes/btConvexInternalShape.h \ + BulletCollision/CollisionShapes/btConeShape.h \ + BulletCollision/CollisionShapes/btConvexHullShape.h \ + BulletCollision/BroadphaseCollision/btAxisSweep3.h \ + BulletCollision/BroadphaseCollision/btDbvtBroadphase.h \ + BulletCollision/BroadphaseCollision/btSimpleBroadphase.h \ + BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h \ + BulletCollision/BroadphaseCollision/btDbvt.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h \ + BulletCollision/BroadphaseCollision/btDispatcher.h \ + BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h \ + BulletCollision/BroadphaseCollision/btBroadphaseProxy.h \ + BulletCollision/BroadphaseCollision/btOverlappingPairCache.h \ + BulletCollision/BroadphaseCollision/btBroadphaseInterface.h \ + BulletCollision/BroadphaseCollision/btQuantizedBvh.h \ + BulletCollision/Gimpact/btGImpactBvh.cpp\ + BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp\ + BulletCollision/Gimpact/btTriangleShapeEx.cpp\ + BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp\ + BulletCollision/Gimpact/btGImpactShape.cpp\ + BulletCollision/Gimpact/gim_box_set.cpp\ + BulletCollision/Gimpact/gim_contact.cpp\ + BulletCollision/Gimpact/gim_memory.cpp\ + BulletCollision/Gimpact/gim_tri_collision.cpp + +libBulletDynamics_la_SOURCES = \ + BulletDynamics/Dynamics/btRigidBody.cpp \ + BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp \ + BulletDynamics/Dynamics/Bullet-C-API.cpp \ + BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp \ + BulletDynamics/ConstraintSolver/btGearConstraint.cpp \ + BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp \ + BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp \ + BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp \ + BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp \ + BulletDynamics/ConstraintSolver/btTypedConstraint.cpp \ + BulletDynamics/ConstraintSolver/btContactConstraint.cpp \ + BulletDynamics/ConstraintSolver/btSliderConstraint.cpp \ + BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp \ + BulletDynamics/ConstraintSolver/btHingeConstraint.cpp \ + BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp \ + BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp \ + BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp \ + BulletDynamics/Vehicle/btWheelInfo.cpp \ + BulletDynamics/Vehicle/btRaycastVehicle.cpp \ + BulletDynamics/Character/btKinematicCharacterController.cpp \ + BulletDynamics/Character/btKinematicCharacterController.h \ + BulletDynamics/Character/btCharacterControllerInterface.h \ + BulletDynamics/Dynamics/btActionInterface.h \ + BulletDynamics/Dynamics/btSimpleDynamicsWorld.h \ + BulletDynamics/Dynamics/btRigidBody.h \ + BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h \ + BulletDynamics/Dynamics/btDynamicsWorld.h \ + BulletDynamics/ConstraintSolver/btSolverBody.h \ + BulletDynamics/ConstraintSolver/btConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btConeTwistConstraint.h \ + BulletDynamics/ConstraintSolver/btTypedConstraint.h \ + BulletDynamics/ConstraintSolver/btContactSolverInfo.h \ + BulletDynamics/ConstraintSolver/btContactConstraint.h \ + BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h \ + BulletDynamics/ConstraintSolver/btJacobianEntry.h \ + BulletDynamics/ConstraintSolver/btSolverConstraint.h \ + BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h \ + BulletDynamics/ConstraintSolver/btGearConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h \ + BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h \ + BulletDynamics/ConstraintSolver/btSliderConstraint.h \ + BulletDynamics/ConstraintSolver/btHingeConstraint.h \ + BulletDynamics/ConstraintSolver/btHinge2Constraint.h \ + BulletDynamics/ConstraintSolver/btUniversalConstraint.h \ + BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h \ + BulletDynamics/Vehicle/btVehicleRaycaster.h \ + BulletDynamics/Vehicle/btRaycastVehicle.h \ + BulletDynamics/Vehicle/btWheelInfo.h + +libBulletSoftBody_la_SOURCES = \ + BulletSoftBody/btDefaultSoftBodySolver.cpp \ + BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp \ + BulletSoftBody/btSoftBody.cpp \ + BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp \ + BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp \ + BulletSoftBody/btSoftRigidDynamicsWorld.cpp \ + BulletSoftBody/btSoftBodyHelpers.cpp \ + BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp \ + BulletSoftBody/btSparseSDF.h \ + BulletSoftBody/btSoftRigidCollisionAlgorithm.h \ + BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h \ + BulletSoftBody/btSoftBody.h \ + BulletSoftBody/btSoftSoftCollisionAlgorithm.h \ + BulletSoftBody/btSoftBodyInternals.h \ + BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h \ + BulletSoftBody/btSoftRigidDynamicsWorld.h \ + BulletSoftBody/btSoftBodyHelpers.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libBulletCollision.la: $(libBulletCollision_la_OBJECTS) $(libBulletCollision_la_DEPENDENCIES) + $(CXXLINK) $(am_libBulletCollision_la_rpath) $(libBulletCollision_la_OBJECTS) $(libBulletCollision_la_LIBADD) $(LIBS) +libBulletDynamics.la: $(libBulletDynamics_la_OBJECTS) $(libBulletDynamics_la_DEPENDENCIES) + $(CXXLINK) $(am_libBulletDynamics_la_rpath) $(libBulletDynamics_la_OBJECTS) $(libBulletDynamics_la_LIBADD) $(LIBS) +libBulletMultiThreaded.la: $(libBulletMultiThreaded_la_OBJECTS) $(libBulletMultiThreaded_la_DEPENDENCIES) + $(libBulletMultiThreaded_la_LINK) $(am_libBulletMultiThreaded_la_rpath) $(libBulletMultiThreaded_la_OBJECTS) $(libBulletMultiThreaded_la_LIBADD) $(LIBS) +libBulletSoftBody.la: $(libBulletSoftBody_la_OBJECTS) $(libBulletSoftBody_la_DEPENDENCIES) + $(CXXLINK) $(am_libBulletSoftBody_la_rpath) $(libBulletSoftBody_la_OBJECTS) $(libBulletSoftBody_la_LIBADD) $(LIBS) +libLinearMath.la: $(libLinearMath_la_OBJECTS) $(libLinearMath_la_DEPENDENCIES) + $(CXXLINK) $(am_libLinearMath_la_rpath) $(libLinearMath_la_OBJECTS) $(libLinearMath_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Bullet-C-API.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SphereTriangleDetector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btActivatingCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btAlignedAllocator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btAxisSweep3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btBox2dBox2dCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btBox2dShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btBoxBoxCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btBoxBoxDetector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btBoxShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btBroadphaseProxy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btBvhTriangleMeshShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCapsuleShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCollisionDispatcher.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCollisionObject.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCollisionShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCollisionWorld.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCompoundCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCompoundShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConcaveShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConeShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConeTwistConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btContactConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btContinuousConvexCollision.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvex2dConvex2dAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvex2dShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexCast.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexConcaveCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexConvexAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexHull.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexHullComputer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexHullShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexInternalShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexPlaneCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexPointCloudShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexPolyhedron.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btConvexTriangleMeshShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btCylinderShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btDbvt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btDbvtBroadphase.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btDefaultCollisionConfiguration.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btDefaultSoftBodySolver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btDiscreteDynamicsWorld.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btDispatcher.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btEmptyCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btEmptyShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGImpactBvh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGImpactCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGImpactQuantizedBvh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGImpactShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGearConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGeneric6DofConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGeneric6DofSpringConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGeometryUtil.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGhostObject.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGjkConvexCast.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGjkEpa2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGjkEpaPenetrationDepthSolver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btGjkPairDetector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btHeightfieldTerrainShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btHinge2Constraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btHingeConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btInternalEdgeUtility.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btKinematicCharacterController.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btManifoldResult.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btMinkowskiPenetrationDepthSolver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btMinkowskiSumShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btMultiSapBroadphase.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btMultiSphereShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btMultimaterialTriangleMeshShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btOptimizedBvh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btOverlappingPairCache.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btPersistentManifold.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btPoint2PointConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btPolarDecomposition.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btPolyhedralContactClipping.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btPolyhedralConvexShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btQuantizedBvh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btQuickprof.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btRaycastCallback.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btRaycastVehicle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btRigidBody.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btScaledBvhTriangleMeshShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSequentialImpulseConstraintSolver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSerializer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btShapeHull.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSimpleBroadphase.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSimpleDynamicsWorld.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSimulationIslandManager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSliderConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSoftBody.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSoftBodyConcaveCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSoftBodyHelpers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSoftBodyRigidBodyCollisionConfiguration.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSoftRigidCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSoftRigidDynamicsWorld.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSoftSoftCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSolve2LinearConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSphereBoxCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSphereShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSphereSphereCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSphereTriangleCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btStaticPlaneShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btStridingMeshInterface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btSubSimplexConvexCast.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTetrahedronShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTriangleBuffer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTriangleCallback.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTriangleIndexVertexArray.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTriangleIndexVertexMaterialArray.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTriangleMesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTriangleMeshShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTriangleShapeEx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btTypedConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btUniformScalingShape.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btUnionFind.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btUniversalConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btVector3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btVoronoiSimplexSolver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btWheelInfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_box_set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_contact.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_memory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_tri_collision.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-PosixThreadSupport.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SequentialThreadSupport.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionObjectWrapper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionShapes.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionTaskProcess.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuContactResult.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuFakeDma.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionTask.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuLibspe2Support.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTask.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTaskProcess.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-Win32ThreadSupport.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-boxBoxDistance.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libBulletMultiThreaded_la-btThreadSupportInterface.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +btRaycastCallback.lo: BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btRaycastCallback.lo -MD -MP -MF $(DEPDIR)/btRaycastCallback.Tpo -c -o btRaycastCallback.lo `test -f 'BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btRaycastCallback.Tpo $(DEPDIR)/btRaycastCallback.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp' object='btRaycastCallback.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btRaycastCallback.lo `test -f 'BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp + +btMinkowskiPenetrationDepthSolver.lo: BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btMinkowskiPenetrationDepthSolver.lo -MD -MP -MF $(DEPDIR)/btMinkowskiPenetrationDepthSolver.Tpo -c -o btMinkowskiPenetrationDepthSolver.lo `test -f 'BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btMinkowskiPenetrationDepthSolver.Tpo $(DEPDIR)/btMinkowskiPenetrationDepthSolver.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp' object='btMinkowskiPenetrationDepthSolver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btMinkowskiPenetrationDepthSolver.lo `test -f 'BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp + +btSubSimplexConvexCast.lo: BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSubSimplexConvexCast.lo -MD -MP -MF $(DEPDIR)/btSubSimplexConvexCast.Tpo -c -o btSubSimplexConvexCast.lo `test -f 'BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSubSimplexConvexCast.Tpo $(DEPDIR)/btSubSimplexConvexCast.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp' object='btSubSimplexConvexCast.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSubSimplexConvexCast.lo `test -f 'BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp + +btGjkEpaPenetrationDepthSolver.lo: BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGjkEpaPenetrationDepthSolver.lo -MD -MP -MF $(DEPDIR)/btGjkEpaPenetrationDepthSolver.Tpo -c -o btGjkEpaPenetrationDepthSolver.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGjkEpaPenetrationDepthSolver.Tpo $(DEPDIR)/btGjkEpaPenetrationDepthSolver.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp' object='btGjkEpaPenetrationDepthSolver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGjkEpaPenetrationDepthSolver.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp + +btGjkConvexCast.lo: BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGjkConvexCast.lo -MD -MP -MF $(DEPDIR)/btGjkConvexCast.Tpo -c -o btGjkConvexCast.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGjkConvexCast.Tpo $(DEPDIR)/btGjkConvexCast.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp' object='btGjkConvexCast.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGjkConvexCast.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp + +btPersistentManifold.lo: BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btPersistentManifold.lo -MD -MP -MF $(DEPDIR)/btPersistentManifold.Tpo -c -o btPersistentManifold.lo `test -f 'BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btPersistentManifold.Tpo $(DEPDIR)/btPersistentManifold.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp' object='btPersistentManifold.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btPersistentManifold.lo `test -f 'BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp + +btConvexCast.lo: BulletCollision/NarrowPhaseCollision/btConvexCast.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexCast.lo -MD -MP -MF $(DEPDIR)/btConvexCast.Tpo -c -o btConvexCast.lo `test -f 'BulletCollision/NarrowPhaseCollision/btConvexCast.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btConvexCast.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexCast.Tpo $(DEPDIR)/btConvexCast.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btConvexCast.cpp' object='btConvexCast.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexCast.lo `test -f 'BulletCollision/NarrowPhaseCollision/btConvexCast.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btConvexCast.cpp + +btPolyhedralContactClipping.lo: BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btPolyhedralContactClipping.lo -MD -MP -MF $(DEPDIR)/btPolyhedralContactClipping.Tpo -c -o btPolyhedralContactClipping.lo `test -f 'BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btPolyhedralContactClipping.Tpo $(DEPDIR)/btPolyhedralContactClipping.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp' object='btPolyhedralContactClipping.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btPolyhedralContactClipping.lo `test -f 'BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp + +btContinuousConvexCollision.lo: BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btContinuousConvexCollision.lo -MD -MP -MF $(DEPDIR)/btContinuousConvexCollision.Tpo -c -o btContinuousConvexCollision.lo `test -f 'BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btContinuousConvexCollision.Tpo $(DEPDIR)/btContinuousConvexCollision.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp' object='btContinuousConvexCollision.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btContinuousConvexCollision.lo `test -f 'BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp + +btGjkPairDetector.lo: BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGjkPairDetector.lo -MD -MP -MF $(DEPDIR)/btGjkPairDetector.Tpo -c -o btGjkPairDetector.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGjkPairDetector.Tpo $(DEPDIR)/btGjkPairDetector.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp' object='btGjkPairDetector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGjkPairDetector.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp + +btGjkEpa2.lo: BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGjkEpa2.lo -MD -MP -MF $(DEPDIR)/btGjkEpa2.Tpo -c -o btGjkEpa2.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGjkEpa2.Tpo $(DEPDIR)/btGjkEpa2.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp' object='btGjkEpa2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGjkEpa2.lo `test -f 'BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp + +btVoronoiSimplexSolver.lo: BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btVoronoiSimplexSolver.lo -MD -MP -MF $(DEPDIR)/btVoronoiSimplexSolver.Tpo -c -o btVoronoiSimplexSolver.lo `test -f 'BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btVoronoiSimplexSolver.Tpo $(DEPDIR)/btVoronoiSimplexSolver.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp' object='btVoronoiSimplexSolver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btVoronoiSimplexSolver.lo `test -f 'BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp' || echo '$(srcdir)/'`BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp + +btActivatingCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btActivatingCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btActivatingCollisionAlgorithm.Tpo -c -o btActivatingCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btActivatingCollisionAlgorithm.Tpo $(DEPDIR)/btActivatingCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp' object='btActivatingCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btActivatingCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp + +btCollisionObject.lo: BulletCollision/CollisionDispatch/btCollisionObject.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCollisionObject.lo -MD -MP -MF $(DEPDIR)/btCollisionObject.Tpo -c -o btCollisionObject.lo `test -f 'BulletCollision/CollisionDispatch/btCollisionObject.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCollisionObject.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCollisionObject.Tpo $(DEPDIR)/btCollisionObject.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btCollisionObject.cpp' object='btCollisionObject.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCollisionObject.lo `test -f 'BulletCollision/CollisionDispatch/btCollisionObject.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCollisionObject.cpp + +btEmptyCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btEmptyCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btEmptyCollisionAlgorithm.Tpo -c -o btEmptyCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btEmptyCollisionAlgorithm.Tpo $(DEPDIR)/btEmptyCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp' object='btEmptyCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btEmptyCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp + +btGhostObject.lo: BulletCollision/CollisionDispatch/btGhostObject.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGhostObject.lo -MD -MP -MF $(DEPDIR)/btGhostObject.Tpo -c -o btGhostObject.lo `test -f 'BulletCollision/CollisionDispatch/btGhostObject.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btGhostObject.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGhostObject.Tpo $(DEPDIR)/btGhostObject.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btGhostObject.cpp' object='btGhostObject.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGhostObject.lo `test -f 'BulletCollision/CollisionDispatch/btGhostObject.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btGhostObject.cpp + +btSphereSphereCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSphereSphereCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btSphereSphereCollisionAlgorithm.Tpo -c -o btSphereSphereCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSphereSphereCollisionAlgorithm.Tpo $(DEPDIR)/btSphereSphereCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp' object='btSphereSphereCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSphereSphereCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp + +btSphereBoxCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSphereBoxCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btSphereBoxCollisionAlgorithm.Tpo -c -o btSphereBoxCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSphereBoxCollisionAlgorithm.Tpo $(DEPDIR)/btSphereBoxCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp' object='btSphereBoxCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSphereBoxCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp + +btCollisionDispatcher.lo: BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCollisionDispatcher.lo -MD -MP -MF $(DEPDIR)/btCollisionDispatcher.Tpo -c -o btCollisionDispatcher.lo `test -f 'BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCollisionDispatcher.Tpo $(DEPDIR)/btCollisionDispatcher.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp' object='btCollisionDispatcher.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCollisionDispatcher.lo `test -f 'BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp + +btDefaultCollisionConfiguration.lo: BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btDefaultCollisionConfiguration.lo -MD -MP -MF $(DEPDIR)/btDefaultCollisionConfiguration.Tpo -c -o btDefaultCollisionConfiguration.lo `test -f 'BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btDefaultCollisionConfiguration.Tpo $(DEPDIR)/btDefaultCollisionConfiguration.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp' object='btDefaultCollisionConfiguration.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btDefaultCollisionConfiguration.lo `test -f 'BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp + +btSimulationIslandManager.lo: BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSimulationIslandManager.lo -MD -MP -MF $(DEPDIR)/btSimulationIslandManager.Tpo -c -o btSimulationIslandManager.lo `test -f 'BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSimulationIslandManager.Tpo $(DEPDIR)/btSimulationIslandManager.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp' object='btSimulationIslandManager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSimulationIslandManager.lo `test -f 'BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp + +btBoxBoxDetector.lo: BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btBoxBoxDetector.lo -MD -MP -MF $(DEPDIR)/btBoxBoxDetector.Tpo -c -o btBoxBoxDetector.lo `test -f 'BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btBoxBoxDetector.Tpo $(DEPDIR)/btBoxBoxDetector.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp' object='btBoxBoxDetector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btBoxBoxDetector.lo `test -f 'BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp + +btConvexPlaneCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexPlaneCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btConvexPlaneCollisionAlgorithm.Tpo -c -o btConvexPlaneCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexPlaneCollisionAlgorithm.Tpo $(DEPDIR)/btConvexPlaneCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp' object='btConvexPlaneCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexPlaneCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp + +btConvexConcaveCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexConcaveCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btConvexConcaveCollisionAlgorithm.Tpo -c -o btConvexConcaveCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexConcaveCollisionAlgorithm.Tpo $(DEPDIR)/btConvexConcaveCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp' object='btConvexConcaveCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexConcaveCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp + +btBoxBoxCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btBoxBoxCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btBoxBoxCollisionAlgorithm.Tpo -c -o btBoxBoxCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btBoxBoxCollisionAlgorithm.Tpo $(DEPDIR)/btBoxBoxCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp' object='btBoxBoxCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btBoxBoxCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp + +btBox2dBox2dCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btBox2dBox2dCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btBox2dBox2dCollisionAlgorithm.Tpo -c -o btBox2dBox2dCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btBox2dBox2dCollisionAlgorithm.Tpo $(DEPDIR)/btBox2dBox2dCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp' object='btBox2dBox2dCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btBox2dBox2dCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp + +SphereTriangleDetector.lo: BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT SphereTriangleDetector.lo -MD -MP -MF $(DEPDIR)/SphereTriangleDetector.Tpo -c -o SphereTriangleDetector.lo `test -f 'BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/SphereTriangleDetector.Tpo $(DEPDIR)/SphereTriangleDetector.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp' object='SphereTriangleDetector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o SphereTriangleDetector.lo `test -f 'BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp + +btInternalEdgeUtility.lo: BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btInternalEdgeUtility.lo -MD -MP -MF $(DEPDIR)/btInternalEdgeUtility.Tpo -c -o btInternalEdgeUtility.lo `test -f 'BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btInternalEdgeUtility.Tpo $(DEPDIR)/btInternalEdgeUtility.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp' object='btInternalEdgeUtility.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btInternalEdgeUtility.lo `test -f 'BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp + +btManifoldResult.lo: BulletCollision/CollisionDispatch/btManifoldResult.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btManifoldResult.lo -MD -MP -MF $(DEPDIR)/btManifoldResult.Tpo -c -o btManifoldResult.lo `test -f 'BulletCollision/CollisionDispatch/btManifoldResult.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btManifoldResult.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btManifoldResult.Tpo $(DEPDIR)/btManifoldResult.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btManifoldResult.cpp' object='btManifoldResult.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btManifoldResult.lo `test -f 'BulletCollision/CollisionDispatch/btManifoldResult.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btManifoldResult.cpp + +btCollisionWorld.lo: BulletCollision/CollisionDispatch/btCollisionWorld.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCollisionWorld.lo -MD -MP -MF $(DEPDIR)/btCollisionWorld.Tpo -c -o btCollisionWorld.lo `test -f 'BulletCollision/CollisionDispatch/btCollisionWorld.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCollisionWorld.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCollisionWorld.Tpo $(DEPDIR)/btCollisionWorld.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btCollisionWorld.cpp' object='btCollisionWorld.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCollisionWorld.lo `test -f 'BulletCollision/CollisionDispatch/btCollisionWorld.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCollisionWorld.cpp + +btSphereTriangleCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSphereTriangleCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btSphereTriangleCollisionAlgorithm.Tpo -c -o btSphereTriangleCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSphereTriangleCollisionAlgorithm.Tpo $(DEPDIR)/btSphereTriangleCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp' object='btSphereTriangleCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSphereTriangleCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp + +btConvexConvexAlgorithm.lo: BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexConvexAlgorithm.lo -MD -MP -MF $(DEPDIR)/btConvexConvexAlgorithm.Tpo -c -o btConvexConvexAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexConvexAlgorithm.Tpo $(DEPDIR)/btConvexConvexAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp' object='btConvexConvexAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexConvexAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp + +btConvex2dConvex2dAlgorithm.lo: BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvex2dConvex2dAlgorithm.lo -MD -MP -MF $(DEPDIR)/btConvex2dConvex2dAlgorithm.Tpo -c -o btConvex2dConvex2dAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvex2dConvex2dAlgorithm.Tpo $(DEPDIR)/btConvex2dConvex2dAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp' object='btConvex2dConvex2dAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvex2dConvex2dAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp + +btUnionFind.lo: BulletCollision/CollisionDispatch/btUnionFind.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btUnionFind.lo -MD -MP -MF $(DEPDIR)/btUnionFind.Tpo -c -o btUnionFind.lo `test -f 'BulletCollision/CollisionDispatch/btUnionFind.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btUnionFind.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btUnionFind.Tpo $(DEPDIR)/btUnionFind.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btUnionFind.cpp' object='btUnionFind.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btUnionFind.lo `test -f 'BulletCollision/CollisionDispatch/btUnionFind.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btUnionFind.cpp + +btCompoundCollisionAlgorithm.lo: BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCompoundCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btCompoundCollisionAlgorithm.Tpo -c -o btCompoundCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCompoundCollisionAlgorithm.Tpo $(DEPDIR)/btCompoundCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp' object='btCompoundCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCompoundCollisionAlgorithm.lo `test -f 'BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp + +btTetrahedronShape.lo: BulletCollision/CollisionShapes/btTetrahedronShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTetrahedronShape.lo -MD -MP -MF $(DEPDIR)/btTetrahedronShape.Tpo -c -o btTetrahedronShape.lo `test -f 'BulletCollision/CollisionShapes/btTetrahedronShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTetrahedronShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTetrahedronShape.Tpo $(DEPDIR)/btTetrahedronShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btTetrahedronShape.cpp' object='btTetrahedronShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTetrahedronShape.lo `test -f 'BulletCollision/CollisionShapes/btTetrahedronShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTetrahedronShape.cpp + +btShapeHull.lo: BulletCollision/CollisionShapes/btShapeHull.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btShapeHull.lo -MD -MP -MF $(DEPDIR)/btShapeHull.Tpo -c -o btShapeHull.lo `test -f 'BulletCollision/CollisionShapes/btShapeHull.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btShapeHull.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btShapeHull.Tpo $(DEPDIR)/btShapeHull.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btShapeHull.cpp' object='btShapeHull.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btShapeHull.lo `test -f 'BulletCollision/CollisionShapes/btShapeHull.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btShapeHull.cpp + +btMinkowskiSumShape.lo: BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btMinkowskiSumShape.lo -MD -MP -MF $(DEPDIR)/btMinkowskiSumShape.Tpo -c -o btMinkowskiSumShape.lo `test -f 'BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btMinkowskiSumShape.Tpo $(DEPDIR)/btMinkowskiSumShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp' object='btMinkowskiSumShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btMinkowskiSumShape.lo `test -f 'BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp + +btCompoundShape.lo: BulletCollision/CollisionShapes/btCompoundShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCompoundShape.lo -MD -MP -MF $(DEPDIR)/btCompoundShape.Tpo -c -o btCompoundShape.lo `test -f 'BulletCollision/CollisionShapes/btCompoundShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCompoundShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCompoundShape.Tpo $(DEPDIR)/btCompoundShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btCompoundShape.cpp' object='btCompoundShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCompoundShape.lo `test -f 'BulletCollision/CollisionShapes/btCompoundShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCompoundShape.cpp + +btConeShape.lo: BulletCollision/CollisionShapes/btConeShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConeShape.lo -MD -MP -MF $(DEPDIR)/btConeShape.Tpo -c -o btConeShape.lo `test -f 'BulletCollision/CollisionShapes/btConeShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConeShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConeShape.Tpo $(DEPDIR)/btConeShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConeShape.cpp' object='btConeShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConeShape.lo `test -f 'BulletCollision/CollisionShapes/btConeShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConeShape.cpp + +btConvexPolyhedron.lo: BulletCollision/CollisionShapes/btConvexPolyhedron.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexPolyhedron.lo -MD -MP -MF $(DEPDIR)/btConvexPolyhedron.Tpo -c -o btConvexPolyhedron.lo `test -f 'BulletCollision/CollisionShapes/btConvexPolyhedron.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexPolyhedron.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexPolyhedron.Tpo $(DEPDIR)/btConvexPolyhedron.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConvexPolyhedron.cpp' object='btConvexPolyhedron.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexPolyhedron.lo `test -f 'BulletCollision/CollisionShapes/btConvexPolyhedron.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexPolyhedron.cpp + +btMultiSphereShape.lo: BulletCollision/CollisionShapes/btMultiSphereShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btMultiSphereShape.lo -MD -MP -MF $(DEPDIR)/btMultiSphereShape.Tpo -c -o btMultiSphereShape.lo `test -f 'BulletCollision/CollisionShapes/btMultiSphereShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btMultiSphereShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btMultiSphereShape.Tpo $(DEPDIR)/btMultiSphereShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btMultiSphereShape.cpp' object='btMultiSphereShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btMultiSphereShape.lo `test -f 'BulletCollision/CollisionShapes/btMultiSphereShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btMultiSphereShape.cpp + +btUniformScalingShape.lo: BulletCollision/CollisionShapes/btUniformScalingShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btUniformScalingShape.lo -MD -MP -MF $(DEPDIR)/btUniformScalingShape.Tpo -c -o btUniformScalingShape.lo `test -f 'BulletCollision/CollisionShapes/btUniformScalingShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btUniformScalingShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btUniformScalingShape.Tpo $(DEPDIR)/btUniformScalingShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btUniformScalingShape.cpp' object='btUniformScalingShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btUniformScalingShape.lo `test -f 'BulletCollision/CollisionShapes/btUniformScalingShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btUniformScalingShape.cpp + +btSphereShape.lo: BulletCollision/CollisionShapes/btSphereShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSphereShape.lo -MD -MP -MF $(DEPDIR)/btSphereShape.Tpo -c -o btSphereShape.lo `test -f 'BulletCollision/CollisionShapes/btSphereShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btSphereShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSphereShape.Tpo $(DEPDIR)/btSphereShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btSphereShape.cpp' object='btSphereShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSphereShape.lo `test -f 'BulletCollision/CollisionShapes/btSphereShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btSphereShape.cpp + +btTriangleIndexVertexArray.lo: BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTriangleIndexVertexArray.lo -MD -MP -MF $(DEPDIR)/btTriangleIndexVertexArray.Tpo -c -o btTriangleIndexVertexArray.lo `test -f 'BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTriangleIndexVertexArray.Tpo $(DEPDIR)/btTriangleIndexVertexArray.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp' object='btTriangleIndexVertexArray.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTriangleIndexVertexArray.lo `test -f 'BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp + +btBvhTriangleMeshShape.lo: BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btBvhTriangleMeshShape.lo -MD -MP -MF $(DEPDIR)/btBvhTriangleMeshShape.Tpo -c -o btBvhTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btBvhTriangleMeshShape.Tpo $(DEPDIR)/btBvhTriangleMeshShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp' object='btBvhTriangleMeshShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btBvhTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp + +btTriangleMeshShape.lo: BulletCollision/CollisionShapes/btTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTriangleMeshShape.lo -MD -MP -MF $(DEPDIR)/btTriangleMeshShape.Tpo -c -o btTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTriangleMeshShape.Tpo $(DEPDIR)/btTriangleMeshShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btTriangleMeshShape.cpp' object='btTriangleMeshShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleMeshShape.cpp + +btTriangleBuffer.lo: BulletCollision/CollisionShapes/btTriangleBuffer.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTriangleBuffer.lo -MD -MP -MF $(DEPDIR)/btTriangleBuffer.Tpo -c -o btTriangleBuffer.lo `test -f 'BulletCollision/CollisionShapes/btTriangleBuffer.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleBuffer.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTriangleBuffer.Tpo $(DEPDIR)/btTriangleBuffer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btTriangleBuffer.cpp' object='btTriangleBuffer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTriangleBuffer.lo `test -f 'BulletCollision/CollisionShapes/btTriangleBuffer.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleBuffer.cpp + +btStaticPlaneShape.lo: BulletCollision/CollisionShapes/btStaticPlaneShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btStaticPlaneShape.lo -MD -MP -MF $(DEPDIR)/btStaticPlaneShape.Tpo -c -o btStaticPlaneShape.lo `test -f 'BulletCollision/CollisionShapes/btStaticPlaneShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btStaticPlaneShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btStaticPlaneShape.Tpo $(DEPDIR)/btStaticPlaneShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btStaticPlaneShape.cpp' object='btStaticPlaneShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btStaticPlaneShape.lo `test -f 'BulletCollision/CollisionShapes/btStaticPlaneShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btStaticPlaneShape.cpp + +btPolyhedralConvexShape.lo: BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btPolyhedralConvexShape.lo -MD -MP -MF $(DEPDIR)/btPolyhedralConvexShape.Tpo -c -o btPolyhedralConvexShape.lo `test -f 'BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btPolyhedralConvexShape.Tpo $(DEPDIR)/btPolyhedralConvexShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp' object='btPolyhedralConvexShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btPolyhedralConvexShape.lo `test -f 'BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp + +btEmptyShape.lo: BulletCollision/CollisionShapes/btEmptyShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btEmptyShape.lo -MD -MP -MF $(DEPDIR)/btEmptyShape.Tpo -c -o btEmptyShape.lo `test -f 'BulletCollision/CollisionShapes/btEmptyShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btEmptyShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btEmptyShape.Tpo $(DEPDIR)/btEmptyShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btEmptyShape.cpp' object='btEmptyShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btEmptyShape.lo `test -f 'BulletCollision/CollisionShapes/btEmptyShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btEmptyShape.cpp + +btCollisionShape.lo: BulletCollision/CollisionShapes/btCollisionShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCollisionShape.lo -MD -MP -MF $(DEPDIR)/btCollisionShape.Tpo -c -o btCollisionShape.lo `test -f 'BulletCollision/CollisionShapes/btCollisionShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCollisionShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCollisionShape.Tpo $(DEPDIR)/btCollisionShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btCollisionShape.cpp' object='btCollisionShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCollisionShape.lo `test -f 'BulletCollision/CollisionShapes/btCollisionShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCollisionShape.cpp + +btConvexShape.lo: BulletCollision/CollisionShapes/btConvexShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexShape.lo -MD -MP -MF $(DEPDIR)/btConvexShape.Tpo -c -o btConvexShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexShape.Tpo $(DEPDIR)/btConvexShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConvexShape.cpp' object='btConvexShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexShape.cpp + +btConvex2dShape.lo: BulletCollision/CollisionShapes/btConvex2dShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvex2dShape.lo -MD -MP -MF $(DEPDIR)/btConvex2dShape.Tpo -c -o btConvex2dShape.lo `test -f 'BulletCollision/CollisionShapes/btConvex2dShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvex2dShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvex2dShape.Tpo $(DEPDIR)/btConvex2dShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConvex2dShape.cpp' object='btConvex2dShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvex2dShape.lo `test -f 'BulletCollision/CollisionShapes/btConvex2dShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvex2dShape.cpp + +btConvexInternalShape.lo: BulletCollision/CollisionShapes/btConvexInternalShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexInternalShape.lo -MD -MP -MF $(DEPDIR)/btConvexInternalShape.Tpo -c -o btConvexInternalShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexInternalShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexInternalShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexInternalShape.Tpo $(DEPDIR)/btConvexInternalShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConvexInternalShape.cpp' object='btConvexInternalShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexInternalShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexInternalShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexInternalShape.cpp + +btConvexHullShape.lo: BulletCollision/CollisionShapes/btConvexHullShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexHullShape.lo -MD -MP -MF $(DEPDIR)/btConvexHullShape.Tpo -c -o btConvexHullShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexHullShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexHullShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexHullShape.Tpo $(DEPDIR)/btConvexHullShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConvexHullShape.cpp' object='btConvexHullShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexHullShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexHullShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexHullShape.cpp + +btTriangleCallback.lo: BulletCollision/CollisionShapes/btTriangleCallback.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTriangleCallback.lo -MD -MP -MF $(DEPDIR)/btTriangleCallback.Tpo -c -o btTriangleCallback.lo `test -f 'BulletCollision/CollisionShapes/btTriangleCallback.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleCallback.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTriangleCallback.Tpo $(DEPDIR)/btTriangleCallback.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btTriangleCallback.cpp' object='btTriangleCallback.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTriangleCallback.lo `test -f 'BulletCollision/CollisionShapes/btTriangleCallback.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleCallback.cpp + +btCapsuleShape.lo: BulletCollision/CollisionShapes/btCapsuleShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCapsuleShape.lo -MD -MP -MF $(DEPDIR)/btCapsuleShape.Tpo -c -o btCapsuleShape.lo `test -f 'BulletCollision/CollisionShapes/btCapsuleShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCapsuleShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCapsuleShape.Tpo $(DEPDIR)/btCapsuleShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btCapsuleShape.cpp' object='btCapsuleShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCapsuleShape.lo `test -f 'BulletCollision/CollisionShapes/btCapsuleShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCapsuleShape.cpp + +btConvexTriangleMeshShape.lo: BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexTriangleMeshShape.lo -MD -MP -MF $(DEPDIR)/btConvexTriangleMeshShape.Tpo -c -o btConvexTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexTriangleMeshShape.Tpo $(DEPDIR)/btConvexTriangleMeshShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp' object='btConvexTriangleMeshShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp + +btConcaveShape.lo: BulletCollision/CollisionShapes/btConcaveShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConcaveShape.lo -MD -MP -MF $(DEPDIR)/btConcaveShape.Tpo -c -o btConcaveShape.lo `test -f 'BulletCollision/CollisionShapes/btConcaveShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConcaveShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConcaveShape.Tpo $(DEPDIR)/btConcaveShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConcaveShape.cpp' object='btConcaveShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConcaveShape.lo `test -f 'BulletCollision/CollisionShapes/btConcaveShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConcaveShape.cpp + +btConvexPointCloudShape.lo: BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexPointCloudShape.lo -MD -MP -MF $(DEPDIR)/btConvexPointCloudShape.Tpo -c -o btConvexPointCloudShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexPointCloudShape.Tpo $(DEPDIR)/btConvexPointCloudShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp' object='btConvexPointCloudShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexPointCloudShape.lo `test -f 'BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp + +btBoxShape.lo: BulletCollision/CollisionShapes/btBoxShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btBoxShape.lo -MD -MP -MF $(DEPDIR)/btBoxShape.Tpo -c -o btBoxShape.lo `test -f 'BulletCollision/CollisionShapes/btBoxShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btBoxShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btBoxShape.Tpo $(DEPDIR)/btBoxShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btBoxShape.cpp' object='btBoxShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btBoxShape.lo `test -f 'BulletCollision/CollisionShapes/btBoxShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btBoxShape.cpp + +btBox2dShape.lo: BulletCollision/CollisionShapes/btBox2dShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btBox2dShape.lo -MD -MP -MF $(DEPDIR)/btBox2dShape.Tpo -c -o btBox2dShape.lo `test -f 'BulletCollision/CollisionShapes/btBox2dShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btBox2dShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btBox2dShape.Tpo $(DEPDIR)/btBox2dShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btBox2dShape.cpp' object='btBox2dShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btBox2dShape.lo `test -f 'BulletCollision/CollisionShapes/btBox2dShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btBox2dShape.cpp + +btOptimizedBvh.lo: BulletCollision/CollisionShapes/btOptimizedBvh.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btOptimizedBvh.lo -MD -MP -MF $(DEPDIR)/btOptimizedBvh.Tpo -c -o btOptimizedBvh.lo `test -f 'BulletCollision/CollisionShapes/btOptimizedBvh.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btOptimizedBvh.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btOptimizedBvh.Tpo $(DEPDIR)/btOptimizedBvh.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btOptimizedBvh.cpp' object='btOptimizedBvh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btOptimizedBvh.lo `test -f 'BulletCollision/CollisionShapes/btOptimizedBvh.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btOptimizedBvh.cpp + +btHeightfieldTerrainShape.lo: BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btHeightfieldTerrainShape.lo -MD -MP -MF $(DEPDIR)/btHeightfieldTerrainShape.Tpo -c -o btHeightfieldTerrainShape.lo `test -f 'BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btHeightfieldTerrainShape.Tpo $(DEPDIR)/btHeightfieldTerrainShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp' object='btHeightfieldTerrainShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btHeightfieldTerrainShape.lo `test -f 'BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp + +btMultimaterialTriangleMeshShape.lo: BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btMultimaterialTriangleMeshShape.lo -MD -MP -MF $(DEPDIR)/btMultimaterialTriangleMeshShape.Tpo -c -o btMultimaterialTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btMultimaterialTriangleMeshShape.Tpo $(DEPDIR)/btMultimaterialTriangleMeshShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp' object='btMultimaterialTriangleMeshShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btMultimaterialTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp + +btCylinderShape.lo: BulletCollision/CollisionShapes/btCylinderShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCylinderShape.lo -MD -MP -MF $(DEPDIR)/btCylinderShape.Tpo -c -o btCylinderShape.lo `test -f 'BulletCollision/CollisionShapes/btCylinderShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCylinderShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCylinderShape.Tpo $(DEPDIR)/btCylinderShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btCylinderShape.cpp' object='btCylinderShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCylinderShape.lo `test -f 'BulletCollision/CollisionShapes/btCylinderShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btCylinderShape.cpp + +btScaledBvhTriangleMeshShape.lo: BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btScaledBvhTriangleMeshShape.lo -MD -MP -MF $(DEPDIR)/btScaledBvhTriangleMeshShape.Tpo -c -o btScaledBvhTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btScaledBvhTriangleMeshShape.Tpo $(DEPDIR)/btScaledBvhTriangleMeshShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp' object='btScaledBvhTriangleMeshShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btScaledBvhTriangleMeshShape.lo `test -f 'BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp + +btStridingMeshInterface.lo: BulletCollision/CollisionShapes/btStridingMeshInterface.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btStridingMeshInterface.lo -MD -MP -MF $(DEPDIR)/btStridingMeshInterface.Tpo -c -o btStridingMeshInterface.lo `test -f 'BulletCollision/CollisionShapes/btStridingMeshInterface.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btStridingMeshInterface.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btStridingMeshInterface.Tpo $(DEPDIR)/btStridingMeshInterface.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btStridingMeshInterface.cpp' object='btStridingMeshInterface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btStridingMeshInterface.lo `test -f 'BulletCollision/CollisionShapes/btStridingMeshInterface.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btStridingMeshInterface.cpp + +btTriangleIndexVertexMaterialArray.lo: BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTriangleIndexVertexMaterialArray.lo -MD -MP -MF $(DEPDIR)/btTriangleIndexVertexMaterialArray.Tpo -c -o btTriangleIndexVertexMaterialArray.lo `test -f 'BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTriangleIndexVertexMaterialArray.Tpo $(DEPDIR)/btTriangleIndexVertexMaterialArray.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp' object='btTriangleIndexVertexMaterialArray.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTriangleIndexVertexMaterialArray.lo `test -f 'BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp + +btTriangleMesh.lo: BulletCollision/CollisionShapes/btTriangleMesh.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTriangleMesh.lo -MD -MP -MF $(DEPDIR)/btTriangleMesh.Tpo -c -o btTriangleMesh.lo `test -f 'BulletCollision/CollisionShapes/btTriangleMesh.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleMesh.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTriangleMesh.Tpo $(DEPDIR)/btTriangleMesh.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/CollisionShapes/btTriangleMesh.cpp' object='btTriangleMesh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTriangleMesh.lo `test -f 'BulletCollision/CollisionShapes/btTriangleMesh.cpp' || echo '$(srcdir)/'`BulletCollision/CollisionShapes/btTriangleMesh.cpp + +btAxisSweep3.lo: BulletCollision/BroadphaseCollision/btAxisSweep3.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btAxisSweep3.lo -MD -MP -MF $(DEPDIR)/btAxisSweep3.Tpo -c -o btAxisSweep3.lo `test -f 'BulletCollision/BroadphaseCollision/btAxisSweep3.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btAxisSweep3.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btAxisSweep3.Tpo $(DEPDIR)/btAxisSweep3.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btAxisSweep3.cpp' object='btAxisSweep3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btAxisSweep3.lo `test -f 'BulletCollision/BroadphaseCollision/btAxisSweep3.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btAxisSweep3.cpp + +btOverlappingPairCache.lo: BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btOverlappingPairCache.lo -MD -MP -MF $(DEPDIR)/btOverlappingPairCache.Tpo -c -o btOverlappingPairCache.lo `test -f 'BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btOverlappingPairCache.Tpo $(DEPDIR)/btOverlappingPairCache.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp' object='btOverlappingPairCache.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btOverlappingPairCache.lo `test -f 'BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp + +btDbvtBroadphase.lo: BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btDbvtBroadphase.lo -MD -MP -MF $(DEPDIR)/btDbvtBroadphase.Tpo -c -o btDbvtBroadphase.lo `test -f 'BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btDbvtBroadphase.Tpo $(DEPDIR)/btDbvtBroadphase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp' object='btDbvtBroadphase.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btDbvtBroadphase.lo `test -f 'BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp + +btMultiSapBroadphase.lo: BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btMultiSapBroadphase.lo -MD -MP -MF $(DEPDIR)/btMultiSapBroadphase.Tpo -c -o btMultiSapBroadphase.lo `test -f 'BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btMultiSapBroadphase.Tpo $(DEPDIR)/btMultiSapBroadphase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp' object='btMultiSapBroadphase.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btMultiSapBroadphase.lo `test -f 'BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp + +btDispatcher.lo: BulletCollision/BroadphaseCollision/btDispatcher.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btDispatcher.lo -MD -MP -MF $(DEPDIR)/btDispatcher.Tpo -c -o btDispatcher.lo `test -f 'BulletCollision/BroadphaseCollision/btDispatcher.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btDispatcher.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btDispatcher.Tpo $(DEPDIR)/btDispatcher.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btDispatcher.cpp' object='btDispatcher.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btDispatcher.lo `test -f 'BulletCollision/BroadphaseCollision/btDispatcher.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btDispatcher.cpp + +btBroadphaseProxy.lo: BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btBroadphaseProxy.lo -MD -MP -MF $(DEPDIR)/btBroadphaseProxy.Tpo -c -o btBroadphaseProxy.lo `test -f 'BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btBroadphaseProxy.Tpo $(DEPDIR)/btBroadphaseProxy.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp' object='btBroadphaseProxy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btBroadphaseProxy.lo `test -f 'BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp + +btQuantizedBvh.lo: BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btQuantizedBvh.lo -MD -MP -MF $(DEPDIR)/btQuantizedBvh.Tpo -c -o btQuantizedBvh.lo `test -f 'BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btQuantizedBvh.Tpo $(DEPDIR)/btQuantizedBvh.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp' object='btQuantizedBvh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btQuantizedBvh.lo `test -f 'BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp + +btCollisionAlgorithm.lo: BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btCollisionAlgorithm.Tpo -c -o btCollisionAlgorithm.lo `test -f 'BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btCollisionAlgorithm.Tpo $(DEPDIR)/btCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp' object='btCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btCollisionAlgorithm.lo `test -f 'BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp + +btDbvt.lo: BulletCollision/BroadphaseCollision/btDbvt.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btDbvt.lo -MD -MP -MF $(DEPDIR)/btDbvt.Tpo -c -o btDbvt.lo `test -f 'BulletCollision/BroadphaseCollision/btDbvt.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btDbvt.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btDbvt.Tpo $(DEPDIR)/btDbvt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btDbvt.cpp' object='btDbvt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btDbvt.lo `test -f 'BulletCollision/BroadphaseCollision/btDbvt.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btDbvt.cpp + +btSimpleBroadphase.lo: BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSimpleBroadphase.lo -MD -MP -MF $(DEPDIR)/btSimpleBroadphase.Tpo -c -o btSimpleBroadphase.lo `test -f 'BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSimpleBroadphase.Tpo $(DEPDIR)/btSimpleBroadphase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp' object='btSimpleBroadphase.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSimpleBroadphase.lo `test -f 'BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp' || echo '$(srcdir)/'`BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp + +btGImpactBvh.lo: BulletCollision/Gimpact/btGImpactBvh.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGImpactBvh.lo -MD -MP -MF $(DEPDIR)/btGImpactBvh.Tpo -c -o btGImpactBvh.lo `test -f 'BulletCollision/Gimpact/btGImpactBvh.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactBvh.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGImpactBvh.Tpo $(DEPDIR)/btGImpactBvh.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/btGImpactBvh.cpp' object='btGImpactBvh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGImpactBvh.lo `test -f 'BulletCollision/Gimpact/btGImpactBvh.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactBvh.cpp + +btGImpactQuantizedBvh.lo: BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGImpactQuantizedBvh.lo -MD -MP -MF $(DEPDIR)/btGImpactQuantizedBvh.Tpo -c -o btGImpactQuantizedBvh.lo `test -f 'BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGImpactQuantizedBvh.Tpo $(DEPDIR)/btGImpactQuantizedBvh.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp' object='btGImpactQuantizedBvh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGImpactQuantizedBvh.lo `test -f 'BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp + +btTriangleShapeEx.lo: BulletCollision/Gimpact/btTriangleShapeEx.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTriangleShapeEx.lo -MD -MP -MF $(DEPDIR)/btTriangleShapeEx.Tpo -c -o btTriangleShapeEx.lo `test -f 'BulletCollision/Gimpact/btTriangleShapeEx.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btTriangleShapeEx.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTriangleShapeEx.Tpo $(DEPDIR)/btTriangleShapeEx.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/btTriangleShapeEx.cpp' object='btTriangleShapeEx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTriangleShapeEx.lo `test -f 'BulletCollision/Gimpact/btTriangleShapeEx.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btTriangleShapeEx.cpp + +btGImpactCollisionAlgorithm.lo: BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGImpactCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btGImpactCollisionAlgorithm.Tpo -c -o btGImpactCollisionAlgorithm.lo `test -f 'BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGImpactCollisionAlgorithm.Tpo $(DEPDIR)/btGImpactCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp' object='btGImpactCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGImpactCollisionAlgorithm.lo `test -f 'BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp + +btGImpactShape.lo: BulletCollision/Gimpact/btGImpactShape.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGImpactShape.lo -MD -MP -MF $(DEPDIR)/btGImpactShape.Tpo -c -o btGImpactShape.lo `test -f 'BulletCollision/Gimpact/btGImpactShape.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactShape.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGImpactShape.Tpo $(DEPDIR)/btGImpactShape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/btGImpactShape.cpp' object='btGImpactShape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGImpactShape.lo `test -f 'BulletCollision/Gimpact/btGImpactShape.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/btGImpactShape.cpp + +gim_box_set.lo: BulletCollision/Gimpact/gim_box_set.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gim_box_set.lo -MD -MP -MF $(DEPDIR)/gim_box_set.Tpo -c -o gim_box_set.lo `test -f 'BulletCollision/Gimpact/gim_box_set.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_box_set.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/gim_box_set.Tpo $(DEPDIR)/gim_box_set.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/gim_box_set.cpp' object='gim_box_set.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gim_box_set.lo `test -f 'BulletCollision/Gimpact/gim_box_set.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_box_set.cpp + +gim_contact.lo: BulletCollision/Gimpact/gim_contact.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gim_contact.lo -MD -MP -MF $(DEPDIR)/gim_contact.Tpo -c -o gim_contact.lo `test -f 'BulletCollision/Gimpact/gim_contact.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_contact.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/gim_contact.Tpo $(DEPDIR)/gim_contact.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/gim_contact.cpp' object='gim_contact.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gim_contact.lo `test -f 'BulletCollision/Gimpact/gim_contact.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_contact.cpp + +gim_memory.lo: BulletCollision/Gimpact/gim_memory.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gim_memory.lo -MD -MP -MF $(DEPDIR)/gim_memory.Tpo -c -o gim_memory.lo `test -f 'BulletCollision/Gimpact/gim_memory.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_memory.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/gim_memory.Tpo $(DEPDIR)/gim_memory.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/gim_memory.cpp' object='gim_memory.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gim_memory.lo `test -f 'BulletCollision/Gimpact/gim_memory.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_memory.cpp + +gim_tri_collision.lo: BulletCollision/Gimpact/gim_tri_collision.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gim_tri_collision.lo -MD -MP -MF $(DEPDIR)/gim_tri_collision.Tpo -c -o gim_tri_collision.lo `test -f 'BulletCollision/Gimpact/gim_tri_collision.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_tri_collision.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/gim_tri_collision.Tpo $(DEPDIR)/gim_tri_collision.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletCollision/Gimpact/gim_tri_collision.cpp' object='gim_tri_collision.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gim_tri_collision.lo `test -f 'BulletCollision/Gimpact/gim_tri_collision.cpp' || echo '$(srcdir)/'`BulletCollision/Gimpact/gim_tri_collision.cpp + +btRigidBody.lo: BulletDynamics/Dynamics/btRigidBody.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btRigidBody.lo -MD -MP -MF $(DEPDIR)/btRigidBody.Tpo -c -o btRigidBody.lo `test -f 'BulletDynamics/Dynamics/btRigidBody.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/btRigidBody.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btRigidBody.Tpo $(DEPDIR)/btRigidBody.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/Dynamics/btRigidBody.cpp' object='btRigidBody.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btRigidBody.lo `test -f 'BulletDynamics/Dynamics/btRigidBody.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/btRigidBody.cpp + +btSimpleDynamicsWorld.lo: BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSimpleDynamicsWorld.lo -MD -MP -MF $(DEPDIR)/btSimpleDynamicsWorld.Tpo -c -o btSimpleDynamicsWorld.lo `test -f 'BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSimpleDynamicsWorld.Tpo $(DEPDIR)/btSimpleDynamicsWorld.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp' object='btSimpleDynamicsWorld.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSimpleDynamicsWorld.lo `test -f 'BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp + +Bullet-C-API.lo: BulletDynamics/Dynamics/Bullet-C-API.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Bullet-C-API.lo -MD -MP -MF $(DEPDIR)/Bullet-C-API.Tpo -c -o Bullet-C-API.lo `test -f 'BulletDynamics/Dynamics/Bullet-C-API.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/Bullet-C-API.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/Bullet-C-API.Tpo $(DEPDIR)/Bullet-C-API.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/Dynamics/Bullet-C-API.cpp' object='Bullet-C-API.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Bullet-C-API.lo `test -f 'BulletDynamics/Dynamics/Bullet-C-API.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/Bullet-C-API.cpp + +btDiscreteDynamicsWorld.lo: BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btDiscreteDynamicsWorld.lo -MD -MP -MF $(DEPDIR)/btDiscreteDynamicsWorld.Tpo -c -o btDiscreteDynamicsWorld.lo `test -f 'BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btDiscreteDynamicsWorld.Tpo $(DEPDIR)/btDiscreteDynamicsWorld.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp' object='btDiscreteDynamicsWorld.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btDiscreteDynamicsWorld.lo `test -f 'BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp' || echo '$(srcdir)/'`BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp + +btGearConstraint.lo: BulletDynamics/ConstraintSolver/btGearConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGearConstraint.lo -MD -MP -MF $(DEPDIR)/btGearConstraint.Tpo -c -o btGearConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btGearConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btGearConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGearConstraint.Tpo $(DEPDIR)/btGearConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btGearConstraint.cpp' object='btGearConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGearConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btGearConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btGearConstraint.cpp + +btGeneric6DofConstraint.lo: BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGeneric6DofConstraint.lo -MD -MP -MF $(DEPDIR)/btGeneric6DofConstraint.Tpo -c -o btGeneric6DofConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGeneric6DofConstraint.Tpo $(DEPDIR)/btGeneric6DofConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp' object='btGeneric6DofConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGeneric6DofConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp + +btGeneric6DofSpringConstraint.lo: BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGeneric6DofSpringConstraint.lo -MD -MP -MF $(DEPDIR)/btGeneric6DofSpringConstraint.Tpo -c -o btGeneric6DofSpringConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGeneric6DofSpringConstraint.Tpo $(DEPDIR)/btGeneric6DofSpringConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp' object='btGeneric6DofSpringConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGeneric6DofSpringConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp + +btSolve2LinearConstraint.lo: BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSolve2LinearConstraint.lo -MD -MP -MF $(DEPDIR)/btSolve2LinearConstraint.Tpo -c -o btSolve2LinearConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSolve2LinearConstraint.Tpo $(DEPDIR)/btSolve2LinearConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp' object='btSolve2LinearConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSolve2LinearConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp + +btPoint2PointConstraint.lo: BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btPoint2PointConstraint.lo -MD -MP -MF $(DEPDIR)/btPoint2PointConstraint.Tpo -c -o btPoint2PointConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btPoint2PointConstraint.Tpo $(DEPDIR)/btPoint2PointConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp' object='btPoint2PointConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btPoint2PointConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp + +btTypedConstraint.lo: BulletDynamics/ConstraintSolver/btTypedConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btTypedConstraint.lo -MD -MP -MF $(DEPDIR)/btTypedConstraint.Tpo -c -o btTypedConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btTypedConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btTypedConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btTypedConstraint.Tpo $(DEPDIR)/btTypedConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btTypedConstraint.cpp' object='btTypedConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btTypedConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btTypedConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btTypedConstraint.cpp + +btContactConstraint.lo: BulletDynamics/ConstraintSolver/btContactConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btContactConstraint.lo -MD -MP -MF $(DEPDIR)/btContactConstraint.Tpo -c -o btContactConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btContactConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btContactConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btContactConstraint.Tpo $(DEPDIR)/btContactConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btContactConstraint.cpp' object='btContactConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btContactConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btContactConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btContactConstraint.cpp + +btSliderConstraint.lo: BulletDynamics/ConstraintSolver/btSliderConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSliderConstraint.lo -MD -MP -MF $(DEPDIR)/btSliderConstraint.Tpo -c -o btSliderConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btSliderConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btSliderConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSliderConstraint.Tpo $(DEPDIR)/btSliderConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btSliderConstraint.cpp' object='btSliderConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSliderConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btSliderConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btSliderConstraint.cpp + +btConeTwistConstraint.lo: BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConeTwistConstraint.lo -MD -MP -MF $(DEPDIR)/btConeTwistConstraint.Tpo -c -o btConeTwistConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConeTwistConstraint.Tpo $(DEPDIR)/btConeTwistConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp' object='btConeTwistConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConeTwistConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp + +btHingeConstraint.lo: BulletDynamics/ConstraintSolver/btHingeConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btHingeConstraint.lo -MD -MP -MF $(DEPDIR)/btHingeConstraint.Tpo -c -o btHingeConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btHingeConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btHingeConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btHingeConstraint.Tpo $(DEPDIR)/btHingeConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btHingeConstraint.cpp' object='btHingeConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btHingeConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btHingeConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btHingeConstraint.cpp + +btHinge2Constraint.lo: BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btHinge2Constraint.lo -MD -MP -MF $(DEPDIR)/btHinge2Constraint.Tpo -c -o btHinge2Constraint.lo `test -f 'BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btHinge2Constraint.Tpo $(DEPDIR)/btHinge2Constraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp' object='btHinge2Constraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btHinge2Constraint.lo `test -f 'BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp + +btUniversalConstraint.lo: BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btUniversalConstraint.lo -MD -MP -MF $(DEPDIR)/btUniversalConstraint.Tpo -c -o btUniversalConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btUniversalConstraint.Tpo $(DEPDIR)/btUniversalConstraint.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp' object='btUniversalConstraint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btUniversalConstraint.lo `test -f 'BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp + +btSequentialImpulseConstraintSolver.lo: BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSequentialImpulseConstraintSolver.lo -MD -MP -MF $(DEPDIR)/btSequentialImpulseConstraintSolver.Tpo -c -o btSequentialImpulseConstraintSolver.lo `test -f 'BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSequentialImpulseConstraintSolver.Tpo $(DEPDIR)/btSequentialImpulseConstraintSolver.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp' object='btSequentialImpulseConstraintSolver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSequentialImpulseConstraintSolver.lo `test -f 'BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp' || echo '$(srcdir)/'`BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp + +btWheelInfo.lo: BulletDynamics/Vehicle/btWheelInfo.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btWheelInfo.lo -MD -MP -MF $(DEPDIR)/btWheelInfo.Tpo -c -o btWheelInfo.lo `test -f 'BulletDynamics/Vehicle/btWheelInfo.cpp' || echo '$(srcdir)/'`BulletDynamics/Vehicle/btWheelInfo.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btWheelInfo.Tpo $(DEPDIR)/btWheelInfo.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/Vehicle/btWheelInfo.cpp' object='btWheelInfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btWheelInfo.lo `test -f 'BulletDynamics/Vehicle/btWheelInfo.cpp' || echo '$(srcdir)/'`BulletDynamics/Vehicle/btWheelInfo.cpp + +btRaycastVehicle.lo: BulletDynamics/Vehicle/btRaycastVehicle.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btRaycastVehicle.lo -MD -MP -MF $(DEPDIR)/btRaycastVehicle.Tpo -c -o btRaycastVehicle.lo `test -f 'BulletDynamics/Vehicle/btRaycastVehicle.cpp' || echo '$(srcdir)/'`BulletDynamics/Vehicle/btRaycastVehicle.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btRaycastVehicle.Tpo $(DEPDIR)/btRaycastVehicle.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/Vehicle/btRaycastVehicle.cpp' object='btRaycastVehicle.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btRaycastVehicle.lo `test -f 'BulletDynamics/Vehicle/btRaycastVehicle.cpp' || echo '$(srcdir)/'`BulletDynamics/Vehicle/btRaycastVehicle.cpp + +btKinematicCharacterController.lo: BulletDynamics/Character/btKinematicCharacterController.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btKinematicCharacterController.lo -MD -MP -MF $(DEPDIR)/btKinematicCharacterController.Tpo -c -o btKinematicCharacterController.lo `test -f 'BulletDynamics/Character/btKinematicCharacterController.cpp' || echo '$(srcdir)/'`BulletDynamics/Character/btKinematicCharacterController.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btKinematicCharacterController.Tpo $(DEPDIR)/btKinematicCharacterController.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletDynamics/Character/btKinematicCharacterController.cpp' object='btKinematicCharacterController.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btKinematicCharacterController.lo `test -f 'BulletDynamics/Character/btKinematicCharacterController.cpp' || echo '$(srcdir)/'`BulletDynamics/Character/btKinematicCharacterController.cpp + +libBulletMultiThreaded_la-SpuCollisionObjectWrapper.lo: BulletMultiThreaded/SpuCollisionObjectWrapper.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuCollisionObjectWrapper.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionObjectWrapper.Tpo -c -o libBulletMultiThreaded_la-SpuCollisionObjectWrapper.lo `test -f 'BulletMultiThreaded/SpuCollisionObjectWrapper.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuCollisionObjectWrapper.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionObjectWrapper.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionObjectWrapper.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuCollisionObjectWrapper.cpp' object='libBulletMultiThreaded_la-SpuCollisionObjectWrapper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuCollisionObjectWrapper.lo `test -f 'BulletMultiThreaded/SpuCollisionObjectWrapper.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuCollisionObjectWrapper.cpp + +libBulletMultiThreaded_la-SpuSampleTask.lo: BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuSampleTask.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTask.Tpo -c -o libBulletMultiThreaded_la-SpuSampleTask.lo `test -f 'BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTask.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTask.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp' object='libBulletMultiThreaded_la-SpuSampleTask.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuSampleTask.lo `test -f 'BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuSampleTask/SpuSampleTask.cpp + +libBulletMultiThreaded_la-SpuLibspe2Support.lo: BulletMultiThreaded/SpuLibspe2Support.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuLibspe2Support.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuLibspe2Support.Tpo -c -o libBulletMultiThreaded_la-SpuLibspe2Support.lo `test -f 'BulletMultiThreaded/SpuLibspe2Support.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuLibspe2Support.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuLibspe2Support.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuLibspe2Support.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuLibspe2Support.cpp' object='libBulletMultiThreaded_la-SpuLibspe2Support.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuLibspe2Support.lo `test -f 'BulletMultiThreaded/SpuLibspe2Support.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuLibspe2Support.cpp + +libBulletMultiThreaded_la-SpuContactResult.lo: BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuContactResult.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuContactResult.Tpo -c -o libBulletMultiThreaded_la-SpuContactResult.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuContactResult.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuContactResult.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp' object='libBulletMultiThreaded_la-SpuContactResult.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuContactResult.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp + +libBulletMultiThreaded_la-SpuGatheringCollisionTask.lo: BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuGatheringCollisionTask.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionTask.Tpo -c -o libBulletMultiThreaded_la-SpuGatheringCollisionTask.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionTask.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionTask.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp' object='libBulletMultiThreaded_la-SpuGatheringCollisionTask.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuGatheringCollisionTask.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp + +libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.lo: BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.Tpo -c -o libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp' object='libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuMinkowskiPenetrationDepthSolver.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp + +libBulletMultiThreaded_la-SpuCollisionShapes.lo: BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuCollisionShapes.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionShapes.Tpo -c -o libBulletMultiThreaded_la-SpuCollisionShapes.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionShapes.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionShapes.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp' object='libBulletMultiThreaded_la-SpuCollisionShapes.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuCollisionShapes.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuCollisionShapes.cpp + +libBulletMultiThreaded_la-btThreadSupportInterface.lo: BulletMultiThreaded/btThreadSupportInterface.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-btThreadSupportInterface.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-btThreadSupportInterface.Tpo -c -o libBulletMultiThreaded_la-btThreadSupportInterface.lo `test -f 'BulletMultiThreaded/btThreadSupportInterface.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/btThreadSupportInterface.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-btThreadSupportInterface.Tpo $(DEPDIR)/libBulletMultiThreaded_la-btThreadSupportInterface.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/btThreadSupportInterface.cpp' object='libBulletMultiThreaded_la-btThreadSupportInterface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-btThreadSupportInterface.lo `test -f 'BulletMultiThreaded/btThreadSupportInterface.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/btThreadSupportInterface.cpp + +libBulletMultiThreaded_la-SequentialThreadSupport.lo: BulletMultiThreaded/SequentialThreadSupport.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SequentialThreadSupport.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SequentialThreadSupport.Tpo -c -o libBulletMultiThreaded_la-SequentialThreadSupport.lo `test -f 'BulletMultiThreaded/SequentialThreadSupport.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SequentialThreadSupport.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SequentialThreadSupport.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SequentialThreadSupport.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SequentialThreadSupport.cpp' object='libBulletMultiThreaded_la-SequentialThreadSupport.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SequentialThreadSupport.lo `test -f 'BulletMultiThreaded/SequentialThreadSupport.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SequentialThreadSupport.cpp + +libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.lo: BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.Tpo -c -o libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.lo `test -f 'BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp' object='libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuGatheringCollisionDispatcher.lo `test -f 'BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp + +libBulletMultiThreaded_la-Win32ThreadSupport.lo: BulletMultiThreaded/Win32ThreadSupport.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-Win32ThreadSupport.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-Win32ThreadSupport.Tpo -c -o libBulletMultiThreaded_la-Win32ThreadSupport.lo `test -f 'BulletMultiThreaded/Win32ThreadSupport.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/Win32ThreadSupport.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-Win32ThreadSupport.Tpo $(DEPDIR)/libBulletMultiThreaded_la-Win32ThreadSupport.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/Win32ThreadSupport.cpp' object='libBulletMultiThreaded_la-Win32ThreadSupport.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-Win32ThreadSupport.lo `test -f 'BulletMultiThreaded/Win32ThreadSupport.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/Win32ThreadSupport.cpp + +libBulletMultiThreaded_la-SpuFakeDma.lo: BulletMultiThreaded/SpuFakeDma.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuFakeDma.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuFakeDma.Tpo -c -o libBulletMultiThreaded_la-SpuFakeDma.lo `test -f 'BulletMultiThreaded/SpuFakeDma.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuFakeDma.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuFakeDma.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuFakeDma.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuFakeDma.cpp' object='libBulletMultiThreaded_la-SpuFakeDma.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuFakeDma.lo `test -f 'BulletMultiThreaded/SpuFakeDma.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuFakeDma.cpp + +libBulletMultiThreaded_la-PosixThreadSupport.lo: BulletMultiThreaded/PosixThreadSupport.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-PosixThreadSupport.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-PosixThreadSupport.Tpo -c -o libBulletMultiThreaded_la-PosixThreadSupport.lo `test -f 'BulletMultiThreaded/PosixThreadSupport.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/PosixThreadSupport.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-PosixThreadSupport.Tpo $(DEPDIR)/libBulletMultiThreaded_la-PosixThreadSupport.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/PosixThreadSupport.cpp' object='libBulletMultiThreaded_la-PosixThreadSupport.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-PosixThreadSupport.lo `test -f 'BulletMultiThreaded/PosixThreadSupport.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/PosixThreadSupport.cpp + +libBulletMultiThreaded_la-SpuCollisionTaskProcess.lo: BulletMultiThreaded/SpuCollisionTaskProcess.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuCollisionTaskProcess.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionTaskProcess.Tpo -c -o libBulletMultiThreaded_la-SpuCollisionTaskProcess.lo `test -f 'BulletMultiThreaded/SpuCollisionTaskProcess.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuCollisionTaskProcess.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionTaskProcess.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuCollisionTaskProcess.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuCollisionTaskProcess.cpp' object='libBulletMultiThreaded_la-SpuCollisionTaskProcess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuCollisionTaskProcess.lo `test -f 'BulletMultiThreaded/SpuCollisionTaskProcess.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuCollisionTaskProcess.cpp + +libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.lo: BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.Tpo -c -o libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.lo `test -f 'BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp' object='libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuContactManifoldCollisionAlgorithm.lo `test -f 'BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuContactManifoldCollisionAlgorithm.cpp + +libBulletMultiThreaded_la-SpuSampleTaskProcess.lo: BulletMultiThreaded/SpuSampleTaskProcess.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-SpuSampleTaskProcess.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTaskProcess.Tpo -c -o libBulletMultiThreaded_la-SpuSampleTaskProcess.lo `test -f 'BulletMultiThreaded/SpuSampleTaskProcess.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuSampleTaskProcess.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTaskProcess.Tpo $(DEPDIR)/libBulletMultiThreaded_la-SpuSampleTaskProcess.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuSampleTaskProcess.cpp' object='libBulletMultiThreaded_la-SpuSampleTaskProcess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-SpuSampleTaskProcess.lo `test -f 'BulletMultiThreaded/SpuSampleTaskProcess.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuSampleTaskProcess.cpp + +libBulletMultiThreaded_la-boxBoxDistance.lo: BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -MT libBulletMultiThreaded_la-boxBoxDistance.lo -MD -MP -MF $(DEPDIR)/libBulletMultiThreaded_la-boxBoxDistance.Tpo -c -o libBulletMultiThreaded_la-boxBoxDistance.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libBulletMultiThreaded_la-boxBoxDistance.Tpo $(DEPDIR)/libBulletMultiThreaded_la-boxBoxDistance.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp' object='libBulletMultiThreaded_la-boxBoxDistance.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libBulletMultiThreaded_la_CXXFLAGS) $(CXXFLAGS) -c -o libBulletMultiThreaded_la-boxBoxDistance.lo `test -f 'BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp' || echo '$(srcdir)/'`BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp + +btDefaultSoftBodySolver.lo: BulletSoftBody/btDefaultSoftBodySolver.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btDefaultSoftBodySolver.lo -MD -MP -MF $(DEPDIR)/btDefaultSoftBodySolver.Tpo -c -o btDefaultSoftBodySolver.lo `test -f 'BulletSoftBody/btDefaultSoftBodySolver.cpp' || echo '$(srcdir)/'`BulletSoftBody/btDefaultSoftBodySolver.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btDefaultSoftBodySolver.Tpo $(DEPDIR)/btDefaultSoftBodySolver.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btDefaultSoftBodySolver.cpp' object='btDefaultSoftBodySolver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btDefaultSoftBodySolver.lo `test -f 'BulletSoftBody/btDefaultSoftBodySolver.cpp' || echo '$(srcdir)/'`BulletSoftBody/btDefaultSoftBodySolver.cpp + +btSoftBodyRigidBodyCollisionConfiguration.lo: BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSoftBodyRigidBodyCollisionConfiguration.lo -MD -MP -MF $(DEPDIR)/btSoftBodyRigidBodyCollisionConfiguration.Tpo -c -o btSoftBodyRigidBodyCollisionConfiguration.lo `test -f 'BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSoftBodyRigidBodyCollisionConfiguration.Tpo $(DEPDIR)/btSoftBodyRigidBodyCollisionConfiguration.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp' object='btSoftBodyRigidBodyCollisionConfiguration.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSoftBodyRigidBodyCollisionConfiguration.lo `test -f 'BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp + +btSoftBody.lo: BulletSoftBody/btSoftBody.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSoftBody.lo -MD -MP -MF $(DEPDIR)/btSoftBody.Tpo -c -o btSoftBody.lo `test -f 'BulletSoftBody/btSoftBody.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBody.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSoftBody.Tpo $(DEPDIR)/btSoftBody.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btSoftBody.cpp' object='btSoftBody.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSoftBody.lo `test -f 'BulletSoftBody/btSoftBody.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBody.cpp + +btSoftRigidCollisionAlgorithm.lo: BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSoftRigidCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btSoftRigidCollisionAlgorithm.Tpo -c -o btSoftRigidCollisionAlgorithm.lo `test -f 'BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSoftRigidCollisionAlgorithm.Tpo $(DEPDIR)/btSoftRigidCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp' object='btSoftRigidCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSoftRigidCollisionAlgorithm.lo `test -f 'BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp + +btSoftBodyConcaveCollisionAlgorithm.lo: BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSoftBodyConcaveCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btSoftBodyConcaveCollisionAlgorithm.Tpo -c -o btSoftBodyConcaveCollisionAlgorithm.lo `test -f 'BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSoftBodyConcaveCollisionAlgorithm.Tpo $(DEPDIR)/btSoftBodyConcaveCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp' object='btSoftBodyConcaveCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSoftBodyConcaveCollisionAlgorithm.lo `test -f 'BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp + +btSoftRigidDynamicsWorld.lo: BulletSoftBody/btSoftRigidDynamicsWorld.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSoftRigidDynamicsWorld.lo -MD -MP -MF $(DEPDIR)/btSoftRigidDynamicsWorld.Tpo -c -o btSoftRigidDynamicsWorld.lo `test -f 'BulletSoftBody/btSoftRigidDynamicsWorld.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftRigidDynamicsWorld.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSoftRigidDynamicsWorld.Tpo $(DEPDIR)/btSoftRigidDynamicsWorld.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btSoftRigidDynamicsWorld.cpp' object='btSoftRigidDynamicsWorld.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSoftRigidDynamicsWorld.lo `test -f 'BulletSoftBody/btSoftRigidDynamicsWorld.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftRigidDynamicsWorld.cpp + +btSoftBodyHelpers.lo: BulletSoftBody/btSoftBodyHelpers.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSoftBodyHelpers.lo -MD -MP -MF $(DEPDIR)/btSoftBodyHelpers.Tpo -c -o btSoftBodyHelpers.lo `test -f 'BulletSoftBody/btSoftBodyHelpers.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBodyHelpers.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSoftBodyHelpers.Tpo $(DEPDIR)/btSoftBodyHelpers.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btSoftBodyHelpers.cpp' object='btSoftBodyHelpers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSoftBodyHelpers.lo `test -f 'BulletSoftBody/btSoftBodyHelpers.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftBodyHelpers.cpp + +btSoftSoftCollisionAlgorithm.lo: BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSoftSoftCollisionAlgorithm.lo -MD -MP -MF $(DEPDIR)/btSoftSoftCollisionAlgorithm.Tpo -c -o btSoftSoftCollisionAlgorithm.lo `test -f 'BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSoftSoftCollisionAlgorithm.Tpo $(DEPDIR)/btSoftSoftCollisionAlgorithm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp' object='btSoftSoftCollisionAlgorithm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSoftSoftCollisionAlgorithm.lo `test -f 'BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp' || echo '$(srcdir)/'`BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp + +btQuickprof.lo: LinearMath/btQuickprof.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btQuickprof.lo -MD -MP -MF $(DEPDIR)/btQuickprof.Tpo -c -o btQuickprof.lo `test -f 'LinearMath/btQuickprof.cpp' || echo '$(srcdir)/'`LinearMath/btQuickprof.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btQuickprof.Tpo $(DEPDIR)/btQuickprof.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btQuickprof.cpp' object='btQuickprof.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btQuickprof.lo `test -f 'LinearMath/btQuickprof.cpp' || echo '$(srcdir)/'`LinearMath/btQuickprof.cpp + +btGeometryUtil.lo: LinearMath/btGeometryUtil.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btGeometryUtil.lo -MD -MP -MF $(DEPDIR)/btGeometryUtil.Tpo -c -o btGeometryUtil.lo `test -f 'LinearMath/btGeometryUtil.cpp' || echo '$(srcdir)/'`LinearMath/btGeometryUtil.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btGeometryUtil.Tpo $(DEPDIR)/btGeometryUtil.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btGeometryUtil.cpp' object='btGeometryUtil.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btGeometryUtil.lo `test -f 'LinearMath/btGeometryUtil.cpp' || echo '$(srcdir)/'`LinearMath/btGeometryUtil.cpp + +btAlignedAllocator.lo: LinearMath/btAlignedAllocator.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btAlignedAllocator.lo -MD -MP -MF $(DEPDIR)/btAlignedAllocator.Tpo -c -o btAlignedAllocator.lo `test -f 'LinearMath/btAlignedAllocator.cpp' || echo '$(srcdir)/'`LinearMath/btAlignedAllocator.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btAlignedAllocator.Tpo $(DEPDIR)/btAlignedAllocator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btAlignedAllocator.cpp' object='btAlignedAllocator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btAlignedAllocator.lo `test -f 'LinearMath/btAlignedAllocator.cpp' || echo '$(srcdir)/'`LinearMath/btAlignedAllocator.cpp + +btSerializer.lo: LinearMath/btSerializer.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btSerializer.lo -MD -MP -MF $(DEPDIR)/btSerializer.Tpo -c -o btSerializer.lo `test -f 'LinearMath/btSerializer.cpp' || echo '$(srcdir)/'`LinearMath/btSerializer.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btSerializer.Tpo $(DEPDIR)/btSerializer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btSerializer.cpp' object='btSerializer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btSerializer.lo `test -f 'LinearMath/btSerializer.cpp' || echo '$(srcdir)/'`LinearMath/btSerializer.cpp + +btConvexHull.lo: LinearMath/btConvexHull.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexHull.lo -MD -MP -MF $(DEPDIR)/btConvexHull.Tpo -c -o btConvexHull.lo `test -f 'LinearMath/btConvexHull.cpp' || echo '$(srcdir)/'`LinearMath/btConvexHull.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexHull.Tpo $(DEPDIR)/btConvexHull.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btConvexHull.cpp' object='btConvexHull.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexHull.lo `test -f 'LinearMath/btConvexHull.cpp' || echo '$(srcdir)/'`LinearMath/btConvexHull.cpp + +btPolarDecomposition.lo: LinearMath/btPolarDecomposition.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btPolarDecomposition.lo -MD -MP -MF $(DEPDIR)/btPolarDecomposition.Tpo -c -o btPolarDecomposition.lo `test -f 'LinearMath/btPolarDecomposition.cpp' || echo '$(srcdir)/'`LinearMath/btPolarDecomposition.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btPolarDecomposition.Tpo $(DEPDIR)/btPolarDecomposition.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btPolarDecomposition.cpp' object='btPolarDecomposition.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btPolarDecomposition.lo `test -f 'LinearMath/btPolarDecomposition.cpp' || echo '$(srcdir)/'`LinearMath/btPolarDecomposition.cpp + +btVector3.lo: LinearMath/btVector3.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btVector3.lo -MD -MP -MF $(DEPDIR)/btVector3.Tpo -c -o btVector3.lo `test -f 'LinearMath/btVector3.cpp' || echo '$(srcdir)/'`LinearMath/btVector3.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btVector3.Tpo $(DEPDIR)/btVector3.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btVector3.cpp' object='btVector3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btVector3.lo `test -f 'LinearMath/btVector3.cpp' || echo '$(srcdir)/'`LinearMath/btVector3.cpp + +btConvexHullComputer.lo: LinearMath/btConvexHullComputer.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT btConvexHullComputer.lo -MD -MP -MF $(DEPDIR)/btConvexHullComputer.Tpo -c -o btConvexHullComputer.lo `test -f 'LinearMath/btConvexHullComputer.cpp' || echo '$(srcdir)/'`LinearMath/btConvexHullComputer.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/btConvexHullComputer.Tpo $(DEPDIR)/btConvexHullComputer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='LinearMath/btConvexHullComputer.cpp' object='btConvexHullComputer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o btConvexHullComputer.lo `test -f 'LinearMath/btConvexHullComputer.cpp' || echo '$(srcdir)/'`LinearMath/btConvexHullComputer.cpp + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-nobase_bullet_includeHEADERS: $(nobase_bullet_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(bullet_includedir)" || $(MKDIR_P) "$(DESTDIR)$(bullet_includedir)" + @list='$(nobase_bullet_include_HEADERS)'; test -n "$(bullet_includedir)" || list=; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo "$(MKDIR_P) '$(DESTDIR)$(bullet_includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(bullet_includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(bullet_includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(bullet_includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_bullet_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_bullet_include_HEADERS)'; test -n "$(bullet_includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bullet_includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bullet_includedir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bullet_includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-nobase_bullet_includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES \ + uninstall-nobase_bullet_includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man \ + install-nobase_bullet_includeHEADERS install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-nobase_bullet_includeHEADERS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/MiniCL/CMakeLists.txt b/src/MiniCL/CMakeLists.txt new file mode 100644 index 0000000..9fe5753 --- /dev/null +++ b/src/MiniCL/CMakeLists.txt @@ -0,0 +1,66 @@ +#MiniCL provides a small subset of OpenCL + +INCLUDE_DIRECTORIES( + ${BULLET_PHYSICS_SOURCE_DIR}/src + ${VECTOR_MATH_INCLUDE} +) + +SET(MiniCL_SRCS + MiniCL.cpp + MiniCLTaskScheduler.cpp + MiniCLTask/MiniCLTask.cpp +) + +SET(Root_HDRS + MiniCLTaskScheduler.h + cl.h + cl_gl.h + cl_platform.h + cl_MiniCL_Defs.h +) + +SET(MiniCLTask_HDRS + MiniCLTask/MiniCLTask.h +) + +SET(MiniCL_HDRS + ${Root_HDRS} + ${MiniCLTask_HDRS} +) + +ADD_LIBRARY(MiniCL ${MiniCL_SRCS} ${MiniCL_HDRS} ) +SET_TARGET_PROPERTIES(MiniCL PROPERTIES VERSION ${BULLET_VERSION}) +SET_TARGET_PROPERTIES(MiniCL PROPERTIES SOVERSION ${BULLET_VERSION}) + + +IF (BUILD_SHARED_LIBS) + TARGET_LINK_LIBRARIES(MiniCL BulletMultiThreaded BulletDynamics BulletCollision) +ENDIF (BUILD_SHARED_LIBS) + +IF (INSTALL_LIBS) + IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) + #INSTALL of other files requires CMake 2.6 + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) +# IF(INSTALL_EXTRA_LIBS) + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS MiniCL DESTINATION .) + ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + INSTALL(TARGETS MiniCL DESTINATION lib${LIB_SUFFIX}) + INSTALL(DIRECTORY +${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING +PATTERN "*.h" PATTERN ".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) +# ENDIF (INSTALL_EXTRA_LIBS) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) + + IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + SET_TARGET_PROPERTIES(MiniCL PROPERTIES FRAMEWORK true) + + SET_TARGET_PROPERTIES(MiniCL PROPERTIES PUBLIC_HEADER "${Root_HDRS}") + # Have to list out sub-directories manually: + SET_PROPERTY(SOURCE ${MiniCLTask_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/MiniCLTask) + + ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) + ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES) +ENDIF (INSTALL_LIBS) + diff --git a/src/MiniCL/MiniCL.cpp b/src/MiniCL/MiniCL.cpp new file mode 100644 index 0000000..ba0865a --- /dev/null +++ b/src/MiniCL/MiniCL.cpp @@ -0,0 +1,788 @@ +/* + Copyright (C) 2010 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + + +#include "MiniCL/cl.h" +#define __PHYSICS_COMMON_H__ 1 +#ifdef _WIN32 +#include "BulletMultiThreaded/Win32ThreadSupport.h" +#endif + +#include "BulletMultiThreaded/PlatformDefinitions.h" +#ifdef USE_PTHREADS +#include "BulletMultiThreaded/PosixThreadSupport.h" +#endif + + +#include "BulletMultiThreaded/SequentialThreadSupport.h" +#include "MiniCLTaskScheduler.h" +#include "MiniCLTask/MiniCLTask.h" +#include "LinearMath/btMinMax.h" +#include +#include + +//#define DEBUG_MINICL_KERNELS 1 + +static const char* spPlatformID = "MiniCL, SCEA"; +static const char* spDriverVersion= "1.0"; + +CL_API_ENTRY cl_int CL_API_CALL clGetPlatformIDs( + cl_uint num_entries, + cl_platform_id * platforms, + cl_uint * num_platforms ) CL_API_SUFFIX__VERSION_1_0 +{ + if(platforms != NULL) + { + if(num_entries <= 0) + { + return CL_INVALID_VALUE; + } + *((const char**)platforms) = spPlatformID; + } + if(num_platforms != NULL) + { + *num_platforms = 1; + } + return CL_SUCCESS; +} + + +CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo( + cl_platform_id platform, + cl_platform_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0 +{ + char* pId = (char*)platform; + if(strcmp(pId, spPlatformID)) + { + return CL_INVALID_PLATFORM; + } + switch(param_name) + { + case CL_PLATFORM_VERSION: + { + if(param_value_size < (strlen(spDriverVersion) + 1)) + { + return CL_INVALID_VALUE; + } + strcpy((char*)param_value, spDriverVersion); + if(param_value_size_ret != NULL) + { + *param_value_size_ret = strlen(spDriverVersion) + 1; + } + break; + } + case CL_PLATFORM_NAME: + case CL_PLATFORM_VENDOR : + if(param_value_size < (strlen(spPlatformID) + 1)) + { + return CL_INVALID_VALUE; + } + strcpy((char*)param_value, spPlatformID); + if(param_value_size_ret != NULL) + { + *param_value_size_ret = strlen(spPlatformID) + 1; + } + break; + default : + return CL_INVALID_VALUE; + } + return CL_SUCCESS; +} + + + + +CL_API_ENTRY cl_int CL_API_CALL clGetDeviceInfo( + cl_device_id device , + cl_device_info param_name , + size_t param_value_size , + void * param_value , + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0 +{ + + switch (param_name) + { + case CL_DEVICE_NAME: + { + char deviceName[] = "MiniCL CPU"; + unsigned int nameLen = (unsigned int)strlen(deviceName)+1; + btAssert(param_value_size>strlen(deviceName)); + if (nameLen < param_value_size) + { + const char* cpuName = "MiniCL CPU"; + sprintf((char*)param_value,"%s",cpuName); + } else + { + printf("error: param_value_size should be at least %d, but it is %zu\n",nameLen,param_value_size); + return CL_INVALID_VALUE; + } + break; + } + case CL_DEVICE_TYPE: + { + if (param_value_size>=sizeof(cl_device_type)) + { + cl_device_type* deviceType = (cl_device_type*)param_value; + *deviceType = CL_DEVICE_TYPE_CPU; + } else + { + printf("error: param_value_size should be at least %zu\n",sizeof(cl_device_type)); + return CL_INVALID_VALUE; + } + break; + } + case CL_DEVICE_MAX_COMPUTE_UNITS: + { + if (param_value_size>=sizeof(cl_uint)) + { + cl_uint* numUnits = (cl_uint*)param_value; + *numUnits= 4; + } else + { + printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint)); + return CL_INVALID_VALUE; + } + + break; + } + case CL_DEVICE_MAX_WORK_ITEM_SIZES: + { + size_t workitem_size[3]; + + if (param_value_size>=sizeof(workitem_size)) + { + size_t* workItemSize = (size_t*)param_value; + workItemSize[0] = 64; + workItemSize[1] = 24; + workItemSize[2] = 16; + } else + { + printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint)); + return CL_INVALID_VALUE; + } + break; + } + case CL_DEVICE_MAX_CLOCK_FREQUENCY: + { + cl_uint* clock_frequency = (cl_uint*)param_value; + *clock_frequency = 3*1024; + break; + } + + case CL_DEVICE_VENDOR : + { + if(param_value_size < (strlen(spPlatformID) + 1)) + { + return CL_INVALID_VALUE; + } + strcpy((char*)param_value, spPlatformID); + if(param_value_size_ret != NULL) + { + *param_value_size_ret = strlen(spPlatformID) + 1; + } + break; + } + case CL_DRIVER_VERSION: + { + if(param_value_size < (strlen(spDriverVersion) + 1)) + { + return CL_INVALID_VALUE; + } + strcpy((char*)param_value, spDriverVersion); + if(param_value_size_ret != NULL) + { + *param_value_size_ret = strlen(spDriverVersion) + 1; + } + + break; + } + case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: + { + cl_uint* maxDimensions = (cl_uint*)param_value; + *maxDimensions = 1; + break; + } + case CL_DEVICE_MAX_WORK_GROUP_SIZE: + { + cl_uint* maxWorkGroupSize = (cl_uint*)param_value; + *maxWorkGroupSize = 128;//1; + break; + } + case CL_DEVICE_ADDRESS_BITS: + { + cl_uint* addressBits = (cl_uint*)param_value; + *addressBits= 32; //@todo: should this be 64 for 64bit builds? + break; + } + case CL_DEVICE_MAX_MEM_ALLOC_SIZE: + { + cl_ulong* maxMemAlloc = (cl_ulong*)param_value; + *maxMemAlloc= 512*1024*1024; //this "should be enough for everyone" ? + break; + } + case CL_DEVICE_GLOBAL_MEM_SIZE: + { + cl_ulong* maxMemAlloc = (cl_ulong*)param_value; + *maxMemAlloc= 1024*1024*1024; //this "should be enough for everyone" ? + break; + } + + case CL_DEVICE_ERROR_CORRECTION_SUPPORT: + { + cl_bool* error_correction_support = (cl_bool*)param_value; + *error_correction_support = CL_FALSE; + break; + } + + case CL_DEVICE_LOCAL_MEM_TYPE: + { + cl_device_local_mem_type* local_mem_type = (cl_device_local_mem_type*)param_value; + *local_mem_type = CL_GLOBAL; + break; + } + case CL_DEVICE_LOCAL_MEM_SIZE: + { + cl_ulong* localmem = (cl_ulong*) param_value; + *localmem = 32*1024; + break; + } + + case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: + { + cl_ulong* localmem = (cl_ulong*) param_value; + *localmem = 64*1024; + break; + } + case CL_DEVICE_QUEUE_PROPERTIES: + { + cl_command_queue_properties* queueProp = (cl_command_queue_properties*) param_value; + memset(queueProp,0,param_value_size); + + break; + } + case CL_DEVICE_IMAGE_SUPPORT: + { + cl_bool* imageSupport = (cl_bool*) param_value; + *imageSupport = CL_FALSE; + break; + } + + case CL_DEVICE_MAX_WRITE_IMAGE_ARGS: + case CL_DEVICE_MAX_READ_IMAGE_ARGS: + { + cl_uint* imageArgs = (cl_uint*) param_value; + *imageArgs = 0; + break; + } + case CL_DEVICE_IMAGE3D_MAX_DEPTH: + case CL_DEVICE_IMAGE3D_MAX_HEIGHT: + case CL_DEVICE_IMAGE2D_MAX_HEIGHT: + case CL_DEVICE_IMAGE3D_MAX_WIDTH: + case CL_DEVICE_IMAGE2D_MAX_WIDTH: + { + size_t* maxSize = (size_t*) param_value; + *maxSize = 0; + break; + } + + case CL_DEVICE_EXTENSIONS: + { + char* extensions = (char*) param_value; + *extensions = 0; + break; + } + + case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: + case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: + case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: + case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: + case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: + case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: + { + cl_uint* width = (cl_uint*) param_value; + *width = 1; + break; + } + + default: + { + printf("error: unsupported param_name:%d\n",param_name); + } + } + + + return 0; +} + +CL_API_ENTRY cl_int CL_API_CALL clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0 +{ + return 0; +} + + + +CL_API_ENTRY cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0 +{ + return 0; +} + +CL_API_ENTRY cl_int CL_API_CALL clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0 +{ + return 0; +} + +CL_API_ENTRY cl_int CL_API_CALL clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0 +{ + return 0; +} + + +// Enqueued Commands APIs +CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadBuffer(cl_command_queue command_queue , + cl_mem buffer , + cl_bool /* blocking_read */, + size_t offset , + size_t cb , + void * ptr , + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0 +{ + MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; + + ///wait for all work items to be completed + scheduler->flush(); + + memcpy(ptr,(char*)buffer + offset,cb); + return 0; +} + + +CL_API_ENTRY cl_int clGetProgramBuildInfo(cl_program /* program */, + cl_device_id /* device */, + cl_program_build_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0 +{ + + return 0; +} + + +// Program Object APIs +CL_API_ENTRY cl_program +clCreateProgramWithSource(cl_context context , + cl_uint /* count */, + const char ** /* strings */, + const size_t * /* lengths */, + cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 +{ + *errcode_ret = CL_SUCCESS; + return (cl_program)context; +} + +CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue command_queue , + cl_mem buffer , + cl_bool /* blocking_read */, + size_t offset, + size_t cb , + const void * ptr , + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0 +{ + MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; + + ///wait for all work items to be completed + scheduler->flush(); + + memcpy((char*)buffer + offset, ptr,cb); + return 0; +} + +CL_API_ENTRY cl_int CL_API_CALL clFlush(cl_command_queue command_queue) +{ + MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; + ///wait for all work items to be completed + scheduler->flush(); + return 0; +} + + +CL_API_ENTRY cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue /* command_queue */, + cl_kernel clKernel , + cl_uint work_dim , + const size_t * /* global_work_offset */, + const size_t * global_work_size , + const size_t * /* local_work_size */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0 +{ + + + MiniCLKernel* kernel = (MiniCLKernel*) clKernel; + for (unsigned int ii=0;iim_scheduler->getMaxNumOutstandingTasks(); + int numWorkItems = global_work_size[ii]; + +// //at minimum 64 work items per task +// int numWorkItemsPerTask = btMax(64,numWorkItems / maxTask); + int numWorkItemsPerTask = numWorkItems / maxTask; + if (!numWorkItemsPerTask) numWorkItemsPerTask = 1; + + for (int t=0;tm_scheduler->issueTask(t, endIndex, kernel); + t = endIndex; + } + } +/* + + void* bla = 0; + + scheduler->issueTask(bla,2,3); + scheduler->flush(); + + */ + + return 0; +} + +#define LOCAL_BUF_SIZE 32768 +static int sLocalMemBuf[LOCAL_BUF_SIZE * 4 + 16]; +static int* spLocalBufCurr = NULL; +static int sLocalBufUsed = LOCAL_BUF_SIZE; // so it will be reset at the first call +static void* localBufMalloc(int size) +{ + int size16 = (size + 15) >> 4; // in 16-byte units + if((sLocalBufUsed + size16) > LOCAL_BUF_SIZE) + { // reset + spLocalBufCurr = sLocalMemBuf; + while((size_t)spLocalBufCurr & 0x0F) spLocalBufCurr++; // align to 16 bytes + sLocalBufUsed = 0; + } + void* ret = spLocalBufCurr; + spLocalBufCurr += size16 * 4; + sLocalBufUsed += size; + return ret; +} + + + +CL_API_ENTRY cl_int CL_API_CALL clSetKernelArg(cl_kernel clKernel , + cl_uint arg_index , + size_t arg_size , + const void * arg_value ) CL_API_SUFFIX__VERSION_1_0 +{ + MiniCLKernel* kernel = (MiniCLKernel* ) clKernel; + btAssert(arg_size <= MINICL_MAX_ARGLENGTH); + if (arg_index>MINI_CL_MAX_ARG) + { + printf("error: clSetKernelArg arg_index (%u) exceeds %u\n",arg_index,MINI_CL_MAX_ARG); + } else + { + if (arg_size>MINICL_MAX_ARGLENGTH) + //if (arg_size != MINICL_MAX_ARGLENGTH) + { + printf("error: clSetKernelArg argdata too large: %zu (maximum is %zu)\n",arg_size,MINICL_MAX_ARGLENGTH); + } + else + { + if(arg_value == NULL) + { // this is only for __local memory qualifier + void* ptr = localBufMalloc(arg_size); + kernel->m_argData[arg_index] = ptr; + } + else + { + memcpy(&(kernel->m_argData[arg_index]), arg_value, arg_size); + } + kernel->m_argSizes[arg_index] = arg_size; + if(arg_index >= kernel->m_numArgs) + { + kernel->m_numArgs = arg_index + 1; + kernel->updateLauncher(); + } + } + } + return 0; +} + +// Kernel Object APIs +CL_API_ENTRY cl_kernel CL_API_CALL clCreateKernel(cl_program program , + const char * kernel_name , + cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 +{ + MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) program; + int nameLen = strlen(kernel_name); + if(nameLen >= MINI_CL_MAX_KERNEL_NAME) + { + *errcode_ret = CL_INVALID_KERNEL_NAME; + return NULL; + } + + MiniCLKernel* kernel = new MiniCLKernel(); + + strcpy(kernel->m_name, kernel_name); + kernel->m_numArgs = 0; + + //kernel->m_kernelProgramCommandId = scheduler->findProgramCommandIdByName(kernel_name); + //if (kernel->m_kernelProgramCommandId>=0) + //{ + // *errcode_ret = CL_SUCCESS; + //} else + //{ + // *errcode_ret = CL_INVALID_KERNEL_NAME; + //} + kernel->m_scheduler = scheduler; + if(kernel->registerSelf() == NULL) + { + *errcode_ret = CL_INVALID_KERNEL_NAME; + delete kernel; + return NULL; + } + else + { + *errcode_ret = CL_SUCCESS; + } + + return (cl_kernel)kernel; + +} + + +CL_API_ENTRY cl_int CL_API_CALL clBuildProgram(cl_program /* program */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const char * /* options */, + void (*pfn_notify)(cl_program /* program */, void * /* user_data */), + void * /* user_data */) CL_API_SUFFIX__VERSION_1_0 +{ + return CL_SUCCESS; +} + +CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithBinary(cl_context context , + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const size_t * /* lengths */, + const unsigned char ** /* binaries */, + cl_int * /* binary_status */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0 +{ + return (cl_program)context; +} + + +// Memory Object APIs +CL_API_ENTRY cl_mem CL_API_CALL clCreateBuffer(cl_context /* context */, + cl_mem_flags flags , + size_t size, + void * host_ptr , + cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 +{ + cl_mem buf = (cl_mem)malloc(size); + if ((flags&CL_MEM_COPY_HOST_PTR) && host_ptr) + { + memcpy(buf,host_ptr,size); + } + *errcode_ret = 0; + return buf; +} + +// Command Queue APIs +CL_API_ENTRY cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context context , + cl_device_id /* device */, + cl_command_queue_properties /* properties */, + cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 +{ + *errcode_ret = 0; + return (cl_command_queue) context; +} + +extern CL_API_ENTRY cl_int CL_API_CALL clGetContextInfo(cl_context /* context */, + cl_context_info param_name , + size_t param_value_size , + void * param_value, + size_t * param_value_size_ret ) CL_API_SUFFIX__VERSION_1_0 +{ + + switch (param_name) + { + case CL_CONTEXT_DEVICES: + { + if (!param_value_size) + { + *param_value_size_ret = 13; + } else + { + const char* testName = "MiniCL_Test."; + sprintf((char*)param_value,"%s",testName); + } + break; + }; + default: + { + printf("unsupported\n"); + } + } + + return 0; +} + + + +CL_API_ENTRY cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * /* properties */, + cl_device_type device_type , + void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */, + void * /* user_data */, + cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 +{ + int maxNumOutstandingTasks = 4; +// int maxNumOutstandingTasks = 2; +// int maxNumOutstandingTasks = 1; + gMiniCLNumOutstandingTasks = maxNumOutstandingTasks; + const int maxNumOfThreadSupports = 8; + static int sUniqueThreadSupportIndex = 0; + static const char* sUniqueThreadSupportName[maxNumOfThreadSupports] = + { + "MiniCL_0", "MiniCL_1", "MiniCL_2", "MiniCL_3", "MiniCL_4", "MiniCL_5", "MiniCL_6", "MiniCL_7" + }; + + btThreadSupportInterface* threadSupport = 0; + + if (device_type==CL_DEVICE_TYPE_DEBUG) + { + SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory); + threadSupport = new SequentialThreadSupport(stc); + } else + { + +#if _WIN32 + btAssert(sUniqueThreadSupportIndex < maxNumOfThreadSupports); + const char* bla = "MiniCL"; + threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( +// bla, + sUniqueThreadSupportName[sUniqueThreadSupportIndex++], + processMiniCLTask, //processCollisionTask, + createMiniCLLocalStoreMemory,//createCollisionLocalStoreMemory, + maxNumOutstandingTasks)); +#else + +#ifdef USE_PTHREADS + PosixThreadSupport::ThreadConstructionInfo constructionInfo("PosixThreads", + processMiniCLTask, + createMiniCLLocalStoreMemory, + maxNumOutstandingTasks); + threadSupport = new PosixThreadSupport(constructionInfo); + +#else + ///todo: add posix thread support for other platforms + SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory); + threadSupport = new SequentialThreadSupport(stc); +#endif //USE_PTHREADS +#endif + + } + + + MiniCLTaskScheduler* scheduler = new MiniCLTaskScheduler(threadSupport,maxNumOutstandingTasks); + + *errcode_ret = 0; + return (cl_context)scheduler; +} + +CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDs(cl_platform_id /* platform */, + cl_device_type /* device_type */, + cl_uint /* num_entries */, + cl_device_id * /* devices */, + cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0 +{ + return 0; +} + +CL_API_ENTRY cl_context CL_API_CALL +clCreateContext(const cl_context_properties * properties , + cl_uint num_devices , + const cl_device_id * devices , + void (*pfn_notify)(const char *, const void *, size_t, void *), + void * user_data , + cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 +{ + + return clCreateContextFromType(properties,CL_DEVICE_TYPE_ALL,pfn_notify,user_data,errcode_ret); +} + +CL_API_ENTRY cl_int CL_API_CALL clReleaseContext(cl_context context ) CL_API_SUFFIX__VERSION_1_0 +{ + + MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) context; + + btThreadSupportInterface* threadSupport = scheduler->getThreadSupportInterface(); + delete scheduler; + delete threadSupport; + + return 0; +} +extern CL_API_ENTRY cl_int CL_API_CALL +clFinish(cl_command_queue command_queue ) CL_API_SUFFIX__VERSION_1_0 +{ + MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; + ///wait for all work items to be completed + scheduler->flush(); + return CL_SUCCESS; +} + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetProgramInfo(cl_program /* program */, + cl_program_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0 +{ + return 0; +} + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelWorkGroupInfo(cl_kernel kernel , + cl_device_id /* device */, + cl_kernel_work_group_info wgi/* param_name */, + size_t sz /* param_value_size */, + void * ptr /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0 +{ + if((wgi == CL_KERNEL_WORK_GROUP_SIZE) + &&(sz == sizeof(size_t)) + &&(ptr != NULL)) + { + MiniCLKernel* miniCLKernel = (MiniCLKernel*)kernel; + MiniCLTaskScheduler* scheduler = miniCLKernel->m_scheduler; + *((size_t*)ptr) = scheduler->getMaxNumOutstandingTasks(); + return CL_SUCCESS; + } + else + { + return CL_INVALID_VALUE; + } +} diff --git a/src/MiniCL/MiniCLTask/MiniCLTask.cpp b/src/MiniCL/MiniCLTask/MiniCLTask.cpp new file mode 100644 index 0000000..a56e96a --- /dev/null +++ b/src/MiniCL/MiniCLTask/MiniCLTask.cpp @@ -0,0 +1,74 @@ +/* +Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + + +#include "MiniCLTask.h" +#include "BulletMultiThreaded/PlatformDefinitions.h" +#include "BulletMultiThreaded/SpuFakeDma.h" +#include "LinearMath/btMinMax.h" +#include "MiniCLTask.h" +#include "MiniCL/MiniCLTaskScheduler.h" + + +#ifdef __SPU__ +#include +#else +#include +#define spu_printf printf +#endif + +int gMiniCLNumOutstandingTasks = 0; + +struct MiniCLTask_LocalStoreMemory +{ + +}; + + +//-- MAIN METHOD +void processMiniCLTask(void* userPtr, void* lsMemory) +{ + // BT_PROFILE("processSampleTask"); + + MiniCLTask_LocalStoreMemory* localMemory = (MiniCLTask_LocalStoreMemory*)lsMemory; + + MiniCLTaskDesc* taskDescPtr = (MiniCLTaskDesc*)userPtr; + MiniCLTaskDesc& taskDesc = *taskDescPtr; + + for (unsigned int i=taskDesc.m_firstWorkUnit;im_launcher(&taskDesc, i); + } + +// printf("Compute Unit[%d] executed kernel %d work items [%d..%d)\n",taskDesc.m_taskId,taskDesc.m_kernelProgramId,taskDesc.m_firstWorkUnit,taskDesc.m_lastWorkUnit); + +} + + +#if defined(__CELLOS_LV2__) || defined (LIBSPE2) + +ATTRIBUTE_ALIGNED16(MiniCLTask_LocalStoreMemory gLocalStoreMemory); + +void* createMiniCLLocalStoreMemory() +{ + return &gLocalStoreMemory; +} +#else +void* createMiniCLLocalStoreMemory() +{ + return new MiniCLTask_LocalStoreMemory; +}; + +#endif diff --git a/src/MiniCL/MiniCLTask/MiniCLTask.h b/src/MiniCL/MiniCLTask/MiniCLTask.h new file mode 100644 index 0000000..7e78be0 --- /dev/null +++ b/src/MiniCL/MiniCLTask/MiniCLTask.h @@ -0,0 +1,62 @@ +/* +Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef MINICL__TASK_H +#define MINICL__TASK_H + +#include "BulletMultiThreaded/PlatformDefinitions.h" +#include "LinearMath/btScalar.h" + +#include "LinearMath/btAlignedAllocator.h" + + +#define MINICL_MAX_ARGLENGTH (sizeof(void*)) +#define MINI_CL_MAX_ARG 16 +#define MINI_CL_MAX_KERNEL_NAME 256 + +struct MiniCLKernel; + +ATTRIBUTE_ALIGNED16(struct) MiniCLTaskDesc +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + MiniCLTaskDesc() + { + for (int i=0;i + +#ifdef __SPU__ + + + +void SampleThreadFunc(void* userPtr,void* lsMemory) +{ + //do nothing + printf("hello world\n"); +} + + +void* SamplelsMemoryFunc() +{ + //don't create local store memory, just return 0 + return 0; +} + + +#else + + +#include "BulletMultiThreaded/btThreadSupportInterface.h" + +//# include "SPUAssert.h" +#include + +#include "MiniCL/cl_platform.h" + +extern "C" { + extern char SPU_SAMPLE_ELF_SYMBOL[]; +} + + +MiniCLTaskScheduler::MiniCLTaskScheduler(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks) +:m_threadInterface(threadInterface), +m_maxNumOutstandingTasks(maxNumOutstandingTasks) +{ + + m_taskBusy.resize(m_maxNumOutstandingTasks); + m_spuSampleTaskDesc.resize(m_maxNumOutstandingTasks); + + m_kernels.resize(0); + + for (int i = 0; i < m_maxNumOutstandingTasks; i++) + { + m_taskBusy[i] = false; + } + m_numBusyTasks = 0; + m_currentTask = 0; + + m_initialized = false; + + m_threadInterface->startSPU(); + + +} + +MiniCLTaskScheduler::~MiniCLTaskScheduler() +{ + m_threadInterface->stopSPU(); + +} + + + +void MiniCLTaskScheduler::initialize() +{ +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("MiniCLTaskScheduler::initialize()\n"); +#endif //DEBUG_SPU_TASK_SCHEDULING + + for (int i = 0; i < m_maxNumOutstandingTasks; i++) + { + m_taskBusy[i] = false; + } + m_numBusyTasks = 0; + m_currentTask = 0; + m_initialized = true; + +} + + +void MiniCLTaskScheduler::issueTask(int firstWorkUnit, int lastWorkUnit, MiniCLKernel* kernel) +{ + +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("MiniCLTaskScheduler::issueTask (m_currentTask= %d\)n", m_currentTask); +#endif //DEBUG_SPU_TASK_SCHEDULING + + m_taskBusy[m_currentTask] = true; + m_numBusyTasks++; + + MiniCLTaskDesc& taskDesc = m_spuSampleTaskDesc[m_currentTask]; + { + // send task description in event message + taskDesc.m_firstWorkUnit = firstWorkUnit; + taskDesc.m_lastWorkUnit = lastWorkUnit; + taskDesc.m_kernel = kernel; + //some bookkeeping to recognize finished tasks + taskDesc.m_taskId = m_currentTask; + +// for (int i=0;im_numArgs; i++) + { + taskDesc.m_argSizes[i] = kernel->m_argSizes[i]; + if (taskDesc.m_argSizes[i]) + { + taskDesc.m_argData[i] = kernel->m_argData[i]; +// memcpy(&taskDesc.m_argData[i],&argData[MINICL_MAX_ARGLENGTH*i],taskDesc.m_argSizes[i]); + } + } + } + + + m_threadInterface->sendRequest(1, (ppu_address_t) &taskDesc, m_currentTask); + + // if all tasks busy, wait for spu event to clear the task. + + if (m_numBusyTasks >= m_maxNumOutstandingTasks) + { + unsigned int taskId; + unsigned int outputSize; + + for (int i=0;iwaitForResponse(&taskId, &outputSize); + + //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize); + + postProcess(taskId, outputSize); + + m_taskBusy[taskId] = false; + + m_numBusyTasks--; + } + + // find new task buffer + for (int i = 0; i < m_maxNumOutstandingTasks; i++) + { + if (!m_taskBusy[i]) + { + m_currentTask = i; + break; + } + } +} + + +///Optional PPU-size post processing for each task +void MiniCLTaskScheduler::postProcess(int taskId, int outputSize) +{ + +} + + +void MiniCLTaskScheduler::flush() +{ +#ifdef DEBUG_SPU_TASK_SCHEDULING + printf("\nSpuCollisionTaskProcess::flush()\n"); +#endif //DEBUG_SPU_TASK_SCHEDULING + + + // all tasks are issued, wait for all tasks to be complete + while(m_numBusyTasks > 0) + { +// Consolidating SPU code + unsigned int taskId; + unsigned int outputSize; + + for (int i=0;iwaitForResponse(&taskId, &outputSize); + } + + //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize); + + postProcess(taskId, outputSize); + + m_taskBusy[taskId] = false; + + m_numBusyTasks--; + } + + +} + + + +typedef void (*MiniCLKernelLauncher0)(int); +typedef void (*MiniCLKernelLauncher1)(void*, int); +typedef void (*MiniCLKernelLauncher2)(void*, void*, int); +typedef void (*MiniCLKernelLauncher3)(void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher4)(void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher5)(void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher6)(void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher7)(void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher8)(void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher9)(void*, void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int); +typedef void (*MiniCLKernelLauncher16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int); + + +static void kernelLauncher0(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher0)(taskDesc->m_kernel->m_launcher))(guid); +} +static void kernelLauncher1(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher1)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + guid); +} +static void kernelLauncher2(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher2)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + guid); +} +static void kernelLauncher3(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher3)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + guid); +} +static void kernelLauncher4(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher4)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + guid); +} +static void kernelLauncher5(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher5)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + guid); +} +static void kernelLauncher6(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher6)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + guid); +} +static void kernelLauncher7(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher7)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + guid); +} +static void kernelLauncher8(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher8)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + guid); +} +static void kernelLauncher9(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher9)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + guid); +} +static void kernelLauncher10(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher10)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + taskDesc->m_argData[9], + guid); +} +static void kernelLauncher11(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher11)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + taskDesc->m_argData[9], + taskDesc->m_argData[10], + guid); +} +static void kernelLauncher12(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher12)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + taskDesc->m_argData[9], + taskDesc->m_argData[10], + taskDesc->m_argData[11], + guid); +} +static void kernelLauncher13(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher13)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + taskDesc->m_argData[9], + taskDesc->m_argData[10], + taskDesc->m_argData[11], + taskDesc->m_argData[12], + guid); +} +static void kernelLauncher14(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher14)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + taskDesc->m_argData[9], + taskDesc->m_argData[10], + taskDesc->m_argData[11], + taskDesc->m_argData[12], + taskDesc->m_argData[13], + guid); +} +static void kernelLauncher15(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher15)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + taskDesc->m_argData[9], + taskDesc->m_argData[10], + taskDesc->m_argData[11], + taskDesc->m_argData[12], + taskDesc->m_argData[13], + taskDesc->m_argData[14], + guid); +} +static void kernelLauncher16(MiniCLTaskDesc* taskDesc, int guid) +{ + ((MiniCLKernelLauncher16)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], + taskDesc->m_argData[1], + taskDesc->m_argData[2], + taskDesc->m_argData[3], + taskDesc->m_argData[4], + taskDesc->m_argData[5], + taskDesc->m_argData[6], + taskDesc->m_argData[7], + taskDesc->m_argData[8], + taskDesc->m_argData[9], + taskDesc->m_argData[10], + taskDesc->m_argData[11], + taskDesc->m_argData[12], + taskDesc->m_argData[13], + taskDesc->m_argData[14], + taskDesc->m_argData[15], + guid); +} + +static kernelLauncherCB spLauncherList[MINI_CL_MAX_ARG+1] = +{ + kernelLauncher0, + kernelLauncher1, + kernelLauncher2, + kernelLauncher3, + kernelLauncher4, + kernelLauncher5, + kernelLauncher6, + kernelLauncher7, + kernelLauncher8, + kernelLauncher9, + kernelLauncher10, + kernelLauncher11, + kernelLauncher12, + kernelLauncher13, + kernelLauncher14, + kernelLauncher15, + kernelLauncher16 +}; + +void MiniCLKernel::updateLauncher() +{ + m_launcher = spLauncherList[m_numArgs]; +} + +struct MiniCLKernelDescEntry +{ + void* pCode; + const char* pName; +}; +static MiniCLKernelDescEntry spKernelDesc[256]; +static int sNumKernelDesc = 0; + +MiniCLKernelDesc::MiniCLKernelDesc(void* pCode, const char* pName) +{ + for(int i = 0; i < sNumKernelDesc; i++) + { + if(!strcmp(pName, spKernelDesc[i].pName)) + { // already registered + btAssert(spKernelDesc[i].pCode == pCode); + return; + } + } + spKernelDesc[sNumKernelDesc].pCode = pCode; + spKernelDesc[sNumKernelDesc].pName = pName; + sNumKernelDesc++; +} + + +MiniCLKernel* MiniCLKernel::registerSelf() +{ + m_scheduler->registerKernel(this); + for(int i = 0; i < sNumKernelDesc; i++) + { + if(!strcmp(m_name, spKernelDesc[i].pName)) + { + m_pCode = spKernelDesc[i].pCode; + return this; + } + } + return NULL; +} + +#endif + + +#endif //USE_SAMPLE_PROCESS diff --git a/src/MiniCL/MiniCLTaskScheduler.h b/src/MiniCL/MiniCLTaskScheduler.h new file mode 100644 index 0000000..3061a71 --- /dev/null +++ b/src/MiniCL/MiniCLTaskScheduler.h @@ -0,0 +1,194 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef MINICL_TASK_SCHEDULER_H +#define MINICL_TASK_SCHEDULER_H + +#include + + +#include "BulletMultiThreaded/PlatformDefinitions.h" + +#include + +#include "LinearMath/btAlignedObjectArray.h" + + +#include "MiniCLTask/MiniCLTask.h" + +//just add your commands here, try to keep them globally unique for debugging purposes +#define CMD_SAMPLE_TASK_COMMAND 10 + +struct MiniCLKernel; + +/// MiniCLTaskScheduler handles SPU processing of collision pairs. +/// When PPU issues a task, it will look for completed task buffers +/// PPU will do postprocessing, dependent on workunit output (not likely) +class MiniCLTaskScheduler +{ + // track task buffers that are being used, and total busy tasks + btAlignedObjectArray m_taskBusy; + btAlignedObjectArray m_spuSampleTaskDesc; + + + btAlignedObjectArray m_kernels; + + + int m_numBusyTasks; + + // the current task and the current entry to insert a new work unit + int m_currentTask; + + bool m_initialized; + + void postProcess(int taskId, int outputSize); + + class btThreadSupportInterface* m_threadInterface; + + int m_maxNumOutstandingTasks; + + + +public: + MiniCLTaskScheduler(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks); + + ~MiniCLTaskScheduler(); + + ///call initialize in the beginning of the frame, before addCollisionPairToTask + void initialize(); + + void issueTask(int firstWorkUnit, int lastWorkUnit, MiniCLKernel* kernel); + + ///call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished + void flush(); + + class btThreadSupportInterface* getThreadSupportInterface() + { + return m_threadInterface; + } + + int findProgramCommandIdByName(const char* programName) const; + + int getMaxNumOutstandingTasks() const + { + return m_maxNumOutstandingTasks; + } + + void registerKernel(MiniCLKernel* kernel) + { + m_kernels.push_back(kernel); + } +}; + +typedef void (*kernelLauncherCB)(MiniCLTaskDesc* taskDesc, int guid); + +struct MiniCLKernel +{ + MiniCLTaskScheduler* m_scheduler; + +// int m_kernelProgramCommandId; + + char m_name[MINI_CL_MAX_KERNEL_NAME]; + unsigned int m_numArgs; + kernelLauncherCB m_launcher; + void* m_pCode; + void updateLauncher(); + MiniCLKernel* registerSelf(); + + void* m_argData[MINI_CL_MAX_ARG]; + int m_argSizes[MINI_CL_MAX_ARG]; +}; + + +#if defined(USE_LIBSPE2) && defined(__SPU__) +////////////////////MAIN///////////////////////////// +#include "../SpuLibspe2Support.h" +#include +#include +#include + +void * SamplelsMemoryFunc(); +void SampleThreadFunc(void* userPtr,void* lsMemory); + +//#define DEBUG_LIBSPE2_MAINLOOP + +int main(unsigned long long speid, addr64 argp, addr64 envp) +{ + printf("SPU is up \n"); + + ATTRIBUTE_ALIGNED128(btSpuStatus status); + ATTRIBUTE_ALIGNED16( SpuSampleTaskDesc taskDesc ) ; + unsigned int received_message = Spu_Mailbox_Event_Nothing; + bool shutdown = false; + + cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + status.m_status = Spu_Status_Free; + status.m_lsMemory.p = SamplelsMemoryFunc(); + + cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + + while (!shutdown) + { + received_message = spu_read_in_mbox(); + + + + switch(received_message) + { + case Spu_Mailbox_Event_Shutdown: + shutdown = true; + break; + case Spu_Mailbox_Event_Task: + // refresh the status +#ifdef DEBUG_LIBSPE2_MAINLOOP + printf("SPU recieved Task \n"); +#endif //DEBUG_LIBSPE2_MAINLOOP + cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + btAssert(status.m_status==Spu_Status_Occupied); + + cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuSampleTaskDesc), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + SampleThreadFunc((void*)&taskDesc, reinterpret_cast (taskDesc.m_mainMemoryPtr) ); + break; + case Spu_Mailbox_Event_Nothing: + default: + break; + } + + // set to status free and wait for next task + status.m_status = Spu_Status_Free; + cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0); + cellDmaWaitTagStatusAll(DMA_MASK(3)); + + + } + return 0; +} +////////////////////////////////////////////////////// +#endif + + + +#endif // MINICL_TASK_SCHEDULER_H + diff --git a/src/MiniCL/cl.h b/src/MiniCL/cl.h new file mode 100644 index 0000000..3528298 --- /dev/null +++ b/src/MiniCL/cl.h @@ -0,0 +1,867 @@ +/******************************************************************************* + * Copyright (c) 2008-2009 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + ******************************************************************************/ + +#ifndef __OPENCL_CL_H +#define __OPENCL_CL_H + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************/ + +typedef struct _cl_platform_id * cl_platform_id; +typedef struct _cl_device_id * cl_device_id; +typedef struct _cl_context * cl_context; +typedef struct _cl_command_queue * cl_command_queue; +typedef struct _cl_mem * cl_mem; +typedef struct _cl_program * cl_program; +typedef struct _cl_kernel * cl_kernel; +typedef struct _cl_event * cl_event; +typedef struct _cl_sampler * cl_sampler; + +typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */ +typedef cl_ulong cl_bitfield; +typedef cl_bitfield cl_device_type; +typedef cl_uint cl_platform_info; +typedef cl_uint cl_device_info; +typedef cl_bitfield cl_device_address_info; +typedef cl_bitfield cl_device_fp_config; +typedef cl_uint cl_device_mem_cache_type; +typedef cl_uint cl_device_local_mem_type; +typedef cl_bitfield cl_device_exec_capabilities; +typedef cl_bitfield cl_command_queue_properties; + +typedef intptr_t cl_context_properties; +typedef cl_uint cl_context_info; +typedef cl_uint cl_command_queue_info; +typedef cl_uint cl_channel_order; +typedef cl_uint cl_channel_type; +typedef cl_bitfield cl_mem_flags; +typedef cl_uint cl_mem_object_type; +typedef cl_uint cl_mem_info; +typedef cl_uint cl_image_info; +typedef cl_uint cl_addressing_mode; +typedef cl_uint cl_filter_mode; +typedef cl_uint cl_sampler_info; +typedef cl_bitfield cl_map_flags; +typedef cl_uint cl_program_info; +typedef cl_uint cl_program_build_info; +typedef cl_int cl_build_status; +typedef cl_uint cl_kernel_info; +typedef cl_uint cl_kernel_work_group_info; +typedef cl_uint cl_event_info; +typedef cl_uint cl_command_type; +typedef cl_uint cl_profiling_info; + +typedef struct _cl_image_format { + cl_channel_order image_channel_order; + cl_channel_type image_channel_data_type; +} cl_image_format; + +/******************************************************************************/ + +// Error Codes +#define CL_SUCCESS 0 +#define CL_DEVICE_NOT_FOUND -1 +#define CL_DEVICE_NOT_AVAILABLE -2 +#define CL_DEVICE_COMPILER_NOT_AVAILABLE -3 +#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4 +#define CL_OUT_OF_RESOURCES -5 +#define CL_OUT_OF_HOST_MEMORY -6 +#define CL_PROFILING_INFO_NOT_AVAILABLE -7 +#define CL_MEM_COPY_OVERLAP -8 +#define CL_IMAGE_FORMAT_MISMATCH -9 +#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 +#define CL_BUILD_PROGRAM_FAILURE -11 +#define CL_MAP_FAILURE -12 + +#define CL_INVALID_VALUE -30 +#define CL_INVALID_DEVICE_TYPE -31 +#define CL_INVALID_PLATFORM -32 +#define CL_INVALID_DEVICE -33 +#define CL_INVALID_CONTEXT -34 +#define CL_INVALID_QUEUE_PROPERTIES -35 +#define CL_INVALID_COMMAND_QUEUE -36 +#define CL_INVALID_HOST_PTR -37 +#define CL_INVALID_MEM_OBJECT -38 +#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39 +#define CL_INVALID_IMAGE_SIZE -40 +#define CL_INVALID_SAMPLER -41 +#define CL_INVALID_BINARY -42 +#define CL_INVALID_BUILD_OPTIONS -43 +#define CL_INVALID_PROGRAM -44 +#define CL_INVALID_PROGRAM_EXECUTABLE -45 +#define CL_INVALID_KERNEL_NAME -46 +#define CL_INVALID_KERNEL_DEFINITION -47 +#define CL_INVALID_KERNEL -48 +#define CL_INVALID_ARG_INDEX -49 +#define CL_INVALID_ARG_VALUE -50 +#define CL_INVALID_ARG_SIZE -51 +#define CL_INVALID_KERNEL_ARGS -52 +#define CL_INVALID_WORK_DIMENSION -53 +#define CL_INVALID_WORK_GROUP_SIZE -54 +#define CL_INVALID_WORK_ITEM_SIZE -55 +#define CL_INVALID_GLOBAL_OFFSET -56 +#define CL_INVALID_EVENT_WAIT_LIST -57 +#define CL_INVALID_EVENT -58 +#define CL_INVALID_OPERATION -59 +#define CL_INVALID_GL_OBJECT -60 +#define CL_INVALID_BUFFER_SIZE -61 +#define CL_INVALID_MIP_LEVEL -62 + +// OpenCL Version +#define CL_VERSION_1_0 1 + +// cl_bool +#define CL_FALSE 0 +#define CL_TRUE 1 + +// cl_platform_info +#define CL_PLATFORM_PROFILE 0x0900 +#define CL_PLATFORM_VERSION 0x0901 +#define CL_PLATFORM_NAME 0x0902 +#define CL_PLATFORM_VENDOR 0x0903 +#define CL_PLATFORM_EXTENSIONS 0x0904 + +// cl_device_type - bitfield +#define CL_DEVICE_TYPE_DEFAULT (1 << 0) +#define CL_DEVICE_TYPE_CPU (1 << 1) +#define CL_DEVICE_TYPE_GPU (1 << 2) +#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) +#define CL_DEVICE_TYPE_DEBUG (1 << 4) +#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF + + +// cl_device_info +#define CL_DEVICE_TYPE 0x1000 +#define CL_DEVICE_VENDOR_ID 0x1001 +#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002 +#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003 +#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004 +#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B +#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C +#define CL_DEVICE_ADDRESS_BITS 0x100D +#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E +#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F +#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010 +#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011 +#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012 +#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013 +#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014 +#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015 +#define CL_DEVICE_IMAGE_SUPPORT 0x1016 +#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017 +#define CL_DEVICE_MAX_SAMPLERS 0x1018 +#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019 +#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A +#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B +#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C +#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D +#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E +#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F +#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020 +#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021 +#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022 +#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023 +#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024 +#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025 +#define CL_DEVICE_ENDIAN_LITTLE 0x1026 +#define CL_DEVICE_AVAILABLE 0x1027 +#define CL_DEVICE_COMPILER_AVAILABLE 0x1028 +#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029 +#define CL_DEVICE_QUEUE_PROPERTIES 0x102A +#define CL_DEVICE_NAME 0x102B +#define CL_DEVICE_VENDOR 0x102C +#define CL_DRIVER_VERSION 0x102D +#define CL_DEVICE_PROFILE 0x102E +#define CL_DEVICE_VERSION 0x102F +#define CL_DEVICE_EXTENSIONS 0x1030 +#define CL_DEVICE_PLATFORM 0x1031 + +// cl_device_address_info - bitfield +#define CL_DEVICE_ADDRESS_32_BITS (1 << 0) +#define CL_DEVICE_ADDRESS_64_BITS (1 << 1) + +// cl_device_fp_config - bitfield +#define CL_FP_DENORM (1 << 0) +#define CL_FP_INF_NAN (1 << 1) +#define CL_FP_ROUND_TO_NEAREST (1 << 2) +#define CL_FP_ROUND_TO_ZERO (1 << 3) +#define CL_FP_ROUND_TO_INF (1 << 4) +#define CL_FP_FMA (1 << 5) + +// cl_device_mem_cache_type +#define CL_NONE 0x0 +#define CL_READ_ONLY_CACHE 0x1 +#define CL_READ_WRITE_CACHE 0x2 + +// cl_device_local_mem_type +#define CL_LOCAL 0x1 +#define CL_GLOBAL 0x2 + +// cl_device_exec_capabilities - bitfield +#define CL_EXEC_KERNEL (1 << 0) +#define CL_EXEC_NATIVE_KERNEL (1 << 1) + +// cl_command_queue_properties - bitfield +#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0) +#define CL_QUEUE_PROFILING_ENABLE (1 << 1) + +// cl_context_info +#define CL_CONTEXT_REFERENCE_COUNT 0x1080 +#define CL_CONTEXT_NUM_DEVICES 0x1081 +#define CL_CONTEXT_DEVICES 0x1082 +#define CL_CONTEXT_PROPERTIES 0x1083 +#define CL_CONTEXT_PLATFORM 0x1084 + +// cl_command_queue_info +#define CL_QUEUE_CONTEXT 0x1090 +#define CL_QUEUE_DEVICE 0x1091 +#define CL_QUEUE_REFERENCE_COUNT 0x1092 +#define CL_QUEUE_PROPERTIES 0x1093 + +// cl_mem_flags - bitfield +#define CL_MEM_READ_WRITE (1 << 0) +#define CL_MEM_WRITE_ONLY (1 << 1) +#define CL_MEM_READ_ONLY (1 << 2) +#define CL_MEM_USE_HOST_PTR (1 << 3) +#define CL_MEM_ALLOC_HOST_PTR (1 << 4) +#define CL_MEM_COPY_HOST_PTR (1 << 5) + +// cl_channel_order +#define CL_R 0x10B0 +#define CL_A 0x10B1 +#define CL_RG 0x10B2 +#define CL_RA 0x10B3 +#define CL_RGB 0x10B4 +#define CL_RGBA 0x10B5 +#define CL_BGRA 0x10B6 +#define CL_ARGB 0x10B7 +#define CL_INTENSITY 0x10B8 +#define CL_LUMINANCE 0x10B9 + +// cl_channel_type +#define CL_SNORM_INT8 0x10D0 +#define CL_SNORM_INT16 0x10D1 +#define CL_UNORM_INT8 0x10D2 +#define CL_UNORM_INT16 0x10D3 +#define CL_UNORM_SHORT_565 0x10D4 +#define CL_UNORM_SHORT_555 0x10D5 +#define CL_UNORM_INT_101010 0x10D6 +#define CL_SIGNED_INT8 0x10D7 +#define CL_SIGNED_INT16 0x10D8 +#define CL_SIGNED_INT32 0x10D9 +#define CL_UNSIGNED_INT8 0x10DA +#define CL_UNSIGNED_INT16 0x10DB +#define CL_UNSIGNED_INT32 0x10DC +#define CL_HALF_FLOAT 0x10DD +#define CL_FLOAT 0x10DE + +// cl_mem_object_type +#define CL_MEM_OBJECT_BUFFER 0x10F0 +#define CL_MEM_OBJECT_IMAGE2D 0x10F1 +#define CL_MEM_OBJECT_IMAGE3D 0x10F2 + +// cl_mem_info +#define CL_MEM_TYPE 0x1100 +#define CL_MEM_FLAGS 0x1101 +#define CL_MEM_SIZE 0x1102 +#define CL_MEM_HOST_PTR 0x1103 +#define CL_MEM_MAP_COUNT 0x1104 +#define CL_MEM_REFERENCE_COUNT 0x1105 +#define CL_MEM_CONTEXT 0x1106 + +// cl_image_info +#define CL_IMAGE_FORMAT 0x1110 +#define CL_IMAGE_ELEMENT_SIZE 0x1111 +#define CL_IMAGE_ROW_PITCH 0x1112 +#define CL_IMAGE_SLICE_PITCH 0x1113 +#define CL_IMAGE_WIDTH 0x1114 +#define CL_IMAGE_HEIGHT 0x1115 +#define CL_IMAGE_DEPTH 0x1116 + +// cl_addressing_mode +#define CL_ADDRESS_NONE 0x1130 +#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 +#define CL_ADDRESS_CLAMP 0x1132 +#define CL_ADDRESS_REPEAT 0x1133 + +// cl_filter_mode +#define CL_FILTER_NEAREST 0x1140 +#define CL_FILTER_LINEAR 0x1141 + +// cl_sampler_info +#define CL_SAMPLER_REFERENCE_COUNT 0x1150 +#define CL_SAMPLER_CONTEXT 0x1151 +#define CL_SAMPLER_NORMALIZED_COORDS 0x1152 +#define CL_SAMPLER_ADDRESSING_MODE 0x1153 +#define CL_SAMPLER_FILTER_MODE 0x1154 + +// cl_map_flags - bitfield +#define CL_MAP_READ (1 << 0) +#define CL_MAP_WRITE (1 << 1) + +// cl_program_info +#define CL_PROGRAM_REFERENCE_COUNT 0x1160 +#define CL_PROGRAM_CONTEXT 0x1161 +#define CL_PROGRAM_NUM_DEVICES 0x1162 +#define CL_PROGRAM_DEVICES 0x1163 +#define CL_PROGRAM_SOURCE 0x1164 +#define CL_PROGRAM_BINARY_SIZES 0x1165 +#define CL_PROGRAM_BINARIES 0x1166 + +// cl_program_build_info +#define CL_PROGRAM_BUILD_STATUS 0x1181 +#define CL_PROGRAM_BUILD_OPTIONS 0x1182 +#define CL_PROGRAM_BUILD_LOG 0x1183 + +// cl_build_status +#define CL_BUILD_SUCCESS 0 +#define CL_BUILD_NONE -1 +#define CL_BUILD_ERROR -2 +#define CL_BUILD_IN_PROGRESS -3 + +// cl_kernel_info +#define CL_KERNEL_FUNCTION_NAME 0x1190 +#define CL_KERNEL_NUM_ARGS 0x1191 +#define CL_KERNEL_REFERENCE_COUNT 0x1192 +#define CL_KERNEL_CONTEXT 0x1193 +#define CL_KERNEL_PROGRAM 0x1194 + +// cl_kernel_work_group_info +#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 +#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 +#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 + +// cl_event_info +#define CL_EVENT_COMMAND_QUEUE 0x11D0 +#define CL_EVENT_COMMAND_TYPE 0x11D1 +#define CL_EVENT_REFERENCE_COUNT 0x11D2 +#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 + +// cl_command_type +#define CL_COMMAND_NDRANGE_KERNEL 0x11F0 +#define CL_COMMAND_TASK 0x11F1 +#define CL_COMMAND_NATIVE_KERNEL 0x11F2 +#define CL_COMMAND_READ_BUFFER 0x11F3 +#define CL_COMMAND_WRITE_BUFFER 0x11F4 +#define CL_COMMAND_COPY_BUFFER 0x11F5 +#define CL_COMMAND_READ_IMAGE 0x11F6 +#define CL_COMMAND_WRITE_IMAGE 0x11F7 +#define CL_COMMAND_COPY_IMAGE 0x11F8 +#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9 +#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA +#define CL_COMMAND_MAP_BUFFER 0x11FB +#define CL_COMMAND_MAP_IMAGE 0x11FC +#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD +#define CL_COMMAND_MARKER 0x11FE +#define CL_COMMAND_WAIT_FOR_EVENTS 0x11FF +#define CL_COMMAND_BARRIER 0x1200 +#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x1201 +#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1202 + +// command execution status +#define CL_COMPLETE 0x0 +#define CL_RUNNING 0x1 +#define CL_SUBMITTED 0x2 +#define CL_QUEUED 0x3 + +// cl_profiling_info +#define CL_PROFILING_COMMAND_QUEUED 0x1280 +#define CL_PROFILING_COMMAND_SUBMIT 0x1281 +#define CL_PROFILING_COMMAND_START 0x1282 +#define CL_PROFILING_COMMAND_END 0x1283 + +/********************************************************************************************************/ + +// Platform API +extern CL_API_ENTRY cl_int CL_API_CALL +clGetPlatformIDs(cl_uint /* num_entries */, + cl_platform_id * /* platforms */, + cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetPlatformInfo(cl_platform_id /* platform */, + cl_platform_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Device APIs +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDs(cl_platform_id /* platform */, + cl_device_type /* device_type */, + cl_uint /* num_entries */, + cl_device_id * /* devices */, + cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceInfo(cl_device_id /* device */, + cl_device_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Context APIs +extern CL_API_ENTRY cl_context CL_API_CALL +clCreateContext(const cl_context_properties * /* properties */, + cl_uint /* num_devices */, + const cl_device_id * /* devices */, + void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */, + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_context CL_API_CALL +clCreateContextFromType(const cl_context_properties * /* properties */, + cl_device_type /* device_type */, + void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */, + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetContextInfo(cl_context /* context */, + cl_context_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Command Queue APIs +extern CL_API_ENTRY cl_command_queue CL_API_CALL +clCreateCommandQueue(cl_context /* context */, + cl_device_id /* device */, + cl_command_queue_properties /* properties */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetCommandQueueInfo(cl_command_queue /* command_queue */, + cl_command_queue_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetCommandQueueProperty(cl_command_queue /* command_queue */, + cl_command_queue_properties /* properties */, + cl_bool /* enable */, + cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0; + +// Memory Object APIs +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateBuffer(cl_context /* context */, + cl_mem_flags /* flags */, + size_t /* size */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateImage2D(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_row_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateImage3D(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_depth */, + size_t /* image_row_pitch */, + size_t /* image_slice_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSupportedImageFormats(cl_context /* context */, + cl_mem_flags /* flags */, + cl_mem_object_type /* image_type */, + cl_uint /* num_entries */, + cl_image_format * /* image_formats */, + cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetMemObjectInfo(cl_mem /* memobj */, + cl_mem_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetImageInfo(cl_mem /* image */, + cl_image_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Sampler APIs +extern CL_API_ENTRY cl_sampler CL_API_CALL +clCreateSampler(cl_context /* context */, + cl_bool /* normalized_coords */, + cl_addressing_mode /* addressing_mode */, + cl_filter_mode /* filter_mode */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSamplerInfo(cl_sampler /* sampler */, + cl_sampler_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Program Object APIs +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithSource(cl_context /* context */, + cl_uint /* count */, + const char ** /* strings */, + const size_t * /* lengths */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithBinary(cl_context /* context */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const size_t * /* lengths */, + const unsigned char ** /* binaries */, + cl_int * /* binary_status */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clBuildProgram(cl_program /* program */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const char * /* options */, + void (*pfn_notify)(cl_program /* program */, void * /* user_data */), + void * /* user_data */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetProgramInfo(cl_program /* program */, + cl_program_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetProgramBuildInfo(cl_program /* program */, + cl_device_id /* device */, + cl_program_build_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Kernel Object APIs +extern CL_API_ENTRY cl_kernel CL_API_CALL +clCreateKernel(cl_program /* program */, + const char * /* kernel_name */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCreateKernelsInProgram(cl_program /* program */, + cl_uint /* num_kernels */, + cl_kernel * /* kernels */, + cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelArg(cl_kernel /* kernel */, + cl_uint /* arg_index */, + size_t /* arg_size */, + const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelInfo(cl_kernel /* kernel */, + cl_kernel_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelWorkGroupInfo(cl_kernel /* kernel */, + cl_device_id /* device */, + cl_kernel_work_group_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Event Object APIs +extern CL_API_ENTRY cl_int CL_API_CALL +clWaitForEvents(cl_uint /* num_events */, + const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetEventInfo(cl_event /* event */, + cl_event_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; + +// Profiling APIs +extern CL_API_ENTRY cl_int CL_API_CALL +clGetEventProfilingInfo(cl_event /* event */, + cl_profiling_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +// Flush and Finish APIs +extern CL_API_ENTRY cl_int CL_API_CALL +clFlush(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clFinish(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +// Enqueued Commands APIs +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReadBuffer(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_read */, + size_t /* offset */, + size_t /* cb */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWriteBuffer(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_write */, + size_t /* offset */, + size_t /* cb */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyBuffer(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_buffer */, + size_t /* src_offset */, + size_t /* dst_offset */, + size_t /* cb */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReadImage(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_read */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t /* row_pitch */, + size_t /* slice_pitch */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWriteImage(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_write */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t /* input_row_pitch */, + size_t /* input_slice_pitch */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyImage(cl_command_queue /* command_queue */, + cl_mem /* src_image */, + cl_mem /* dst_image */, + const size_t * /* src_origin[3] */, + const size_t * /* dst_origin[3] */, + const size_t * /* region[3] */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyImageToBuffer(cl_command_queue /* command_queue */, + cl_mem /* src_image */, + cl_mem /* dst_buffer */, + const size_t * /* src_origin[3] */, + const size_t * /* region[3] */, + size_t /* dst_offset */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyBufferToImage(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_image */, + size_t /* src_offset */, + const size_t * /* dst_origin[3] */, + const size_t * /* region[3] */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY void * CL_API_CALL +clEnqueueMapBuffer(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_map */, + cl_map_flags /* map_flags */, + size_t /* offset */, + size_t /* cb */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY void * CL_API_CALL +clEnqueueMapImage(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_map */, + cl_map_flags /* map_flags */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t * /* image_row_pitch */, + size_t * /* image_slice_pitch */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueUnmapMemObject(cl_command_queue /* command_queue */, + cl_mem /* memobj */, + void * /* mapped_ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueNDRangeKernel(cl_command_queue /* command_queue */, + cl_kernel /* kernel */, + cl_uint /* work_dim */, + const size_t * /* global_work_offset */, + const size_t * /* global_work_size */, + const size_t * /* local_work_size */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueTask(cl_command_queue /* command_queue */, + cl_kernel /* kernel */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueNativeKernel(cl_command_queue /* command_queue */, + void (*user_func)(void *), + void * /* args */, + size_t /* cb_args */, + cl_uint /* num_mem_objects */, + const cl_mem * /* mem_list */, + const void ** /* args_mem_loc */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMarker(cl_command_queue /* command_queue */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWaitForEvents(cl_command_queue /* command_queue */, + cl_uint /* num_events */, + const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueBarrier(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + +#ifdef __cplusplus +} +#endif + +#endif // __OPENCL_CL_H + diff --git a/src/MiniCL/cl_MiniCL_Defs.h b/src/MiniCL/cl_MiniCL_Defs.h new file mode 100644 index 0000000..0773c85 --- /dev/null +++ b/src/MiniCL/cl_MiniCL_Defs.h @@ -0,0 +1,439 @@ +/* +Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#include +#include +#include "LinearMath/btScalar.h" + +#include "MiniCL/cl.h" + + +#define __kernel +#define __global +#define __local +#define get_global_id(a) __guid_arg +#define get_local_id(a) ((__guid_arg) % gMiniCLNumOutstandingTasks) +#define get_local_size(a) (gMiniCLNumOutstandingTasks) +#define get_group_id(a) ((__guid_arg) / gMiniCLNumOutstandingTasks) + +//static unsigned int as_uint(float val) { return *((unsigned int*)&val); } + + +#define CLK_LOCAL_MEM_FENCE 0x01 +#define CLK_GLOBAL_MEM_FENCE 0x02 + +static void barrier(unsigned int a) +{ + // TODO : implement +} + +//ATTRIBUTE_ALIGNED16(struct) float8 +struct float8 +{ + float s0; + float s1; + float s2; + float s3; + float s4; + float s5; + float s6; + float s7; + + float8(float scalar) + { + s0=s1=s2=s3=s4=s5=s6=s7=scalar; + } +}; + + +float select( float arg0, float arg1, bool select) +{ + if (select) + return arg0; + return arg1; +} + +#define __constant + + +struct float3 +{ + float x,y,z; + + float3& operator+=(const float3& other) + { + x += other.x; + y += other.y; + z += other.z; + return *this; + } + + float3& operator-=(const float3& other) + { + x -= other.x; + y -= other.y; + z -= other.z; + return *this; + } + +}; + +static float dot(const float3&a ,const float3& b) +{ + float3 tmp; + tmp.x = a.x*b.x; + tmp.y = a.y*b.y; + tmp.z = a.z*b.z; + return tmp.x+tmp.y+tmp.z; +} + +static float3 operator-(const float3& a,const float3& b) +{ + float3 tmp; + tmp.x = a.x - b.x; + tmp.y = a.y - b.y; + tmp.z = a.z - b.z; + return tmp; +} + +static float3 operator*(const float& scalar,const float3& b) +{ + float3 tmp; + tmp.x = scalar * b.x; + tmp.y = scalar * b.y; + tmp.z = scalar * b.z; + return tmp; +} + +static float3 operator*(const float3& a,const float& scalar) +{ + float3 tmp; + tmp.x = a.x * scalar; + tmp.y = a.y * scalar; + tmp.z = a.z * scalar; + return tmp; +} + + +static float3 operator*(const float3& a,const float3& b) +{ + float3 tmp; + tmp.x = a.x * b.x; + tmp.y = a.y * b.y; + tmp.z = a.z * b.z; + return tmp; +} + + +//ATTRIBUTE_ALIGNED16(struct) float4 +struct float4 +{ + union + { + struct { + float x; + float y; + float z; + }; + float3 xyz; + }; + float w; + + float4() {} + + float4(float v0, float v1, float v2, float v3) + { + x=v0; + y=v1; + z=v2; + w=v3; + + } + float4(float3 xyz, float scalarW) + { + x = xyz.x; + y = xyz.y; + z = xyz.z; + w = scalarW; + } + + float4(float v) + { + x = y = z = w = v; + } + float4 operator*(const float4& other) + { + float4 tmp; + tmp.x = x*other.x; + tmp.y = y*other.y; + tmp.z = z*other.z; + tmp.w = w*other.w; + return tmp; + } + + + + float4 operator*(const float& other) + { + float4 tmp; + tmp.x = x*other; + tmp.y = y*other; + tmp.z = z*other; + tmp.w = w*other; + return tmp; + } + + + + float4& operator+=(const float4& other) + { + x += other.x; + y += other.y; + z += other.z; + w += other.w; + return *this; + } + + float4& operator-=(const float4& other) + { + x -= other.x; + y -= other.y; + z -= other.z; + w -= other.w; + return *this; + } + + float4& operator *=(float scalar) + { + x *= scalar; + y *= scalar; + z *= scalar; + w *= scalar; + return (*this); + } + + + + + +}; + +static float4 fabs(const float4& a) +{ + float4 tmp; + tmp.x = a.x < 0.f ? 0.f : a.x; + tmp.y = a.y < 0.f ? 0.f : a.y; + tmp.z = a.z < 0.f ? 0.f : a.z; + tmp.w = a.w < 0.f ? 0.f : a.w; + return tmp; +} +static float4 operator+(const float4& a,const float4& b) +{ + float4 tmp; + tmp.x = a.x + b.x; + tmp.y = a.y + b.y; + tmp.z = a.z + b.z; + tmp.w = a.w + b.w; + return tmp; +} + + +static float8 operator+(const float8& a,const float8& b) +{ + float8 tmp(0); + tmp.s0 = a.s0 + b.s0; + tmp.s1 = a.s1 + b.s1; + tmp.s2 = a.s2 + b.s2; + tmp.s3 = a.s3 + b.s3; + tmp.s4 = a.s4 + b.s4; + tmp.s5 = a.s5 + b.s5; + tmp.s6 = a.s6 + b.s6; + tmp.s7 = a.s7 + b.s7; + return tmp; +} + + +static float4 operator-(const float4& a,const float4& b) +{ + float4 tmp; + tmp.x = a.x - b.x; + tmp.y = a.y - b.y; + tmp.z = a.z - b.z; + tmp.w = a.w - b.w; + return tmp; +} + +static float8 operator-(const float8& a,const float8& b) +{ + float8 tmp(0); + tmp.s0 = a.s0 - b.s0; + tmp.s1 = a.s1 - b.s1; + tmp.s2 = a.s2 - b.s2; + tmp.s3 = a.s3 - b.s3; + tmp.s4 = a.s4 - b.s4; + tmp.s5 = a.s5 - b.s5; + tmp.s6 = a.s6 - b.s6; + tmp.s7 = a.s7 - b.s7; + return tmp; +} + +static float4 operator*(float a,const float4& b) +{ + float4 tmp; + tmp.x = a * b.x; + tmp.y = a * b.y; + tmp.z = a * b.z; + tmp.w = a * b.w; + return tmp; +} + +static float4 operator/(const float4& b,float a) +{ + float4 tmp; + tmp.x = b.x/a; + tmp.y = b.y/a; + tmp.z = b.z/a; + tmp.w = b.w/a; + return tmp; +} + + + + + +static float dot(const float4&a ,const float4& b) +{ + float4 tmp; + tmp.x = a.x*b.x; + tmp.y = a.y*b.y; + tmp.z = a.z*b.z; + tmp.w = a.w*b.w; + return tmp.x+tmp.y+tmp.z+tmp.w; +} + +static float length(const float4&a) +{ + float l = sqrtf(a.x*a.x+a.y*a.y+a.z*a.z); + return l; +} + +static float4 normalize(const float4&a) +{ + float4 tmp; + float l = length(a); + tmp = 1.f/l*a; + return tmp; +} + + + +static float4 cross(const float4&a ,const float4& b) +{ + float4 tmp; + tmp.x = a.y*b.z - a.z*b.y; + tmp.y = -a.x*b.z + a.z*b.x; + tmp.z = a.x*b.y - a.y*b.x; + tmp.w = 0.f; + return tmp; +} + +static float max(float a, float b) +{ + return (a >= b) ? a : b; +} + + +static float min(float a, float b) +{ + return (a <= b) ? a : b; +} + +static float fmax(float a, float b) +{ + return (a >= b) ? a : b; +} + +static float fmin(float a, float b) +{ + return (a <= b) ? a : b; +} + +struct int2 +{ + int x,y; +}; + +struct uint2 +{ + unsigned int x,y; +}; + +//typedef int2 uint2; + +typedef unsigned int uint; + +struct int4 +{ + int x,y,z,w; +}; + +struct uint4 +{ + unsigned int x,y,z,w; + uint4() {} + uint4(uint val) { x = y = z = w = val; } + uint4& operator+=(const uint4& other) + { + x += other.x; + y += other.y; + z += other.z; + w += other.w; + return *this; + } +}; +static uint4 operator+(const uint4& a,const uint4& b) +{ + uint4 tmp; + tmp.x = a.x + b.x; + tmp.y = a.y + b.y; + tmp.z = a.z + b.z; + tmp.w = a.w + b.w; + return tmp; +} +static uint4 operator-(const uint4& a,const uint4& b) +{ + uint4 tmp; + tmp.x = a.x - b.x; + tmp.y = a.y - b.y; + tmp.z = a.z - b.z; + tmp.w = a.w - b.w; + return tmp; +} + +#define native_sqrt sqrtf +#define native_sin sinf +#define native_cos cosf +#define native_powr powf + +#define GUID_ARG ,int __guid_arg +#define GUID_ARG_VAL ,__guid_arg + + +#define as_int(a) (*((int*)&(a))) + +extern "C" int gMiniCLNumOutstandingTasks; +// extern "C" void __kernel_func(); + + diff --git a/src/MiniCL/cl_gl.h b/src/MiniCL/cl_gl.h new file mode 100644 index 0000000..0a69d6e --- /dev/null +++ b/src/MiniCL/cl_gl.h @@ -0,0 +1,113 @@ +/********************************************************************************** + * Copyright (c) 2008-2009 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + **********************************************************************************/ + +#ifndef __OPENCL_CL_GL_H +#define __OPENCL_CL_GL_H + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// NOTE: Make sure that appropriate GL header file is included separately + +typedef cl_uint cl_gl_object_type; +typedef cl_uint cl_gl_texture_info; +typedef cl_uint cl_gl_platform_info; + +// cl_gl_object_type +#define CL_GL_OBJECT_BUFFER 0x2000 +#define CL_GL_OBJECT_TEXTURE2D 0x2001 +#define CL_GL_OBJECT_TEXTURE3D 0x2002 +#define CL_GL_OBJECT_RENDERBUFFER 0x2003 + +// cl_gl_texture_info +#define CL_GL_TEXTURE_TARGET 0x2004 +#define CL_GL_MIPMAP_LEVEL 0x2005 + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLBuffer(cl_context /* context */, + cl_mem_flags /* flags */, + GLuint /* bufobj */, + int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLTexture2D(cl_context /* context */, + cl_mem_flags /* flags */, + GLenum /* target */, + GLint /* miplevel */, + GLuint /* texture */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLTexture3D(cl_context /* context */, + cl_mem_flags /* flags */, + GLenum /* target */, + GLint /* miplevel */, + GLuint /* texture */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLRenderbuffer(cl_context /* context */, + cl_mem_flags /* flags */, + GLuint /* renderbuffer */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetGLObjectInfo(cl_mem /* memobj */, + cl_gl_object_type * /* gl_object_type */, + GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetGLTextureInfo(cl_mem /* memobj */, + cl_gl_texture_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireGLObjects(cl_command_queue /* command_queue */, + cl_uint /* num_objects */, + const cl_mem * /* mem_objects */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */, + cl_uint /* num_objects */, + const cl_mem * /* mem_objects */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +#ifdef __cplusplus +} +#endif + +#endif // __OPENCL_CL_GL_H diff --git a/src/MiniCL/cl_platform.h b/src/MiniCL/cl_platform.h new file mode 100644 index 0000000..43219e1 --- /dev/null +++ b/src/MiniCL/cl_platform.h @@ -0,0 +1,254 @@ +/********************************************************************************** + * Copyright (c) 2008-2009 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + **********************************************************************************/ + +#ifndef __CL_PLATFORM_H +#define __CL_PLATFORM_H + +#define CL_PLATFORM_MINI_CL 0x12345 + +struct MiniCLKernelDesc +{ + MiniCLKernelDesc(void* pCode, const char* pName); +}; + +#define MINICL_REGISTER(__kernel_func) static MiniCLKernelDesc __kernel_func##Desc((void*)__kernel_func, #__kernel_func); + + +#ifdef __APPLE__ + /* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */ + #include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define CL_API_ENTRY +#define CL_API_CALL +#ifdef __APPLE__ +#define CL_API_SUFFIX__VERSION_1_0 // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) +#else +#define CL_API_SUFFIX__VERSION_1_0 +#define CL_EXTENSION_WEAK_LINK +#endif + +#if defined (_WIN32) && ! defined (__MINGW32__) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + +typedef int8_t cl_char; +typedef uint8_t cl_uchar; +typedef int16_t cl_short ; +typedef uint16_t cl_ushort ; +typedef int32_t cl_int ; +typedef uint32_t cl_uint ; +typedef int64_t cl_long ; +typedef uint64_t cl_ulong ; + +typedef uint16_t cl_half ; +typedef float cl_float ; +typedef double cl_double ; + + +typedef int8_t cl_char2[2] ; +typedef int8_t cl_char4[4] ; +typedef int8_t cl_char8[8] ; +typedef int8_t cl_char16[16] ; +typedef uint8_t cl_uchar2[2] ; +typedef uint8_t cl_uchar4[4] ; +typedef uint8_t cl_uchar8[8] ; +typedef uint8_t cl_uchar16[16] ; + +typedef int16_t cl_short2[2] ; +typedef int16_t cl_short4[4] ; +typedef int16_t cl_short8[8] ; +typedef int16_t cl_short16[16] ; +typedef uint16_t cl_ushort2[2] ; +typedef uint16_t cl_ushort4[4] ; +typedef uint16_t cl_ushort8[8] ; +typedef uint16_t cl_ushort16[16] ; + +typedef int32_t cl_int2[2] ; +typedef int32_t cl_int4[4] ; +typedef int32_t cl_int8[8] ; +typedef int32_t cl_int16[16] ; +typedef uint32_t cl_uint2[2] ; +typedef uint32_t cl_uint4[4] ; +typedef uint32_t cl_uint8[8] ; +typedef uint32_t cl_uint16[16] ; + +typedef int64_t cl_long2[2] ; +typedef int64_t cl_long4[4] ; +typedef int64_t cl_long8[8] ; +typedef int64_t cl_long16[16] ; +typedef uint64_t cl_ulong2[2] ; +typedef uint64_t cl_ulong4[4] ; +typedef uint64_t cl_ulong8[8] ; +typedef uint64_t cl_ulong16[16] ; + +typedef float cl_float2[2] ; +typedef float cl_float4[4] ; +typedef float cl_float8[8] ; +typedef float cl_float16[16] ; + +typedef double cl_double2[2] ; +typedef double cl_double4[4] ; +typedef double cl_double8[8] ; +typedef double cl_double16[16] ; + + +#else +#include + +/* scalar types */ +typedef int8_t cl_char; +typedef uint8_t cl_uchar; +typedef int16_t cl_short __attribute__((aligned(2))); +typedef uint16_t cl_ushort __attribute__((aligned(2))); +typedef int32_t cl_int __attribute__((aligned(4))); +typedef uint32_t cl_uint __attribute__((aligned(4))); +typedef int64_t cl_long __attribute__((aligned(8))); +typedef uint64_t cl_ulong __attribute__((aligned(8))); + +typedef uint16_t cl_half __attribute__((aligned(2))); +typedef float cl_float __attribute__((aligned(4))); +typedef double cl_double __attribute__((aligned(8))); + + +/* + * Vector types + * + * Note: OpenCL requires that all types be naturally aligned. + * This means that vector types must be naturally aligned. + * For example, a vector of four floats must be aligned to + * a 16 byte boundary (calculated as 4 * the natural 4-byte + * alignment of the float). The alignment qualifiers here + * will only function properly if your compiler supports them + * and if you don't actively work to defeat them. For example, + * in order for a cl_float4 to be 16 byte aligned in a struct, + * the start of the struct must itself be 16-byte aligned. + * + * Maintaining proper alignment is the user's responsibility. + */ +typedef int8_t cl_char2[2] __attribute__((aligned(2))); +typedef int8_t cl_char4[4] __attribute__((aligned(4))); +typedef int8_t cl_char8[8] __attribute__((aligned(8))); +typedef int8_t cl_char16[16] __attribute__((aligned(16))); +typedef uint8_t cl_uchar2[2] __attribute__((aligned(2))); +typedef uint8_t cl_uchar4[4] __attribute__((aligned(4))); +typedef uint8_t cl_uchar8[8] __attribute__((aligned(8))); +typedef uint8_t cl_uchar16[16] __attribute__((aligned(16))); + +typedef int16_t cl_short2[2] __attribute__((aligned(4))); +typedef int16_t cl_short4[4] __attribute__((aligned(8))); +typedef int16_t cl_short8[8] __attribute__((aligned(16))); +typedef int16_t cl_short16[16] __attribute__((aligned(32))); +typedef uint16_t cl_ushort2[2] __attribute__((aligned(4))); +typedef uint16_t cl_ushort4[4] __attribute__((aligned(8))); +typedef uint16_t cl_ushort8[8] __attribute__((aligned(16))); +typedef uint16_t cl_ushort16[16] __attribute__((aligned(32))); + +typedef int32_t cl_int2[2] __attribute__((aligned(8))); +typedef int32_t cl_int4[4] __attribute__((aligned(16))); +typedef int32_t cl_int8[8] __attribute__((aligned(32))); +typedef int32_t cl_int16[16] __attribute__((aligned(64))); +typedef uint32_t cl_uint2[2] __attribute__((aligned(8))); +typedef uint32_t cl_uint4[4] __attribute__((aligned(16))); +typedef uint32_t cl_uint8[8] __attribute__((aligned(32))); +typedef uint32_t cl_uint16[16] __attribute__((aligned(64))); + +typedef int64_t cl_long2[2] __attribute__((aligned(16))); +typedef int64_t cl_long4[4] __attribute__((aligned(32))); +typedef int64_t cl_long8[8] __attribute__((aligned(64))); +typedef int64_t cl_long16[16] __attribute__((aligned(128))); +typedef uint64_t cl_ulong2[2] __attribute__((aligned(16))); +typedef uint64_t cl_ulong4[4] __attribute__((aligned(32))); +typedef uint64_t cl_ulong8[8] __attribute__((aligned(64))); +typedef uint64_t cl_ulong16[16] __attribute__((aligned(128))); + +typedef float cl_float2[2] __attribute__((aligned(8))); +typedef float cl_float4[4] __attribute__((aligned(16))); +typedef float cl_float8[8] __attribute__((aligned(32))); +typedef float cl_float16[16] __attribute__((aligned(64))); + +typedef double cl_double2[2] __attribute__((aligned(16))); +typedef double cl_double4[4] __attribute__((aligned(32))); +typedef double cl_double8[8] __attribute__((aligned(64))); +typedef double cl_double16[16] __attribute__((aligned(128))); +#endif + +#include + +/* and a few goodies to go with them */ +#define CL_CHAR_BIT 8 +#define CL_SCHAR_MAX 127 +#define CL_SCHAR_MIN (-127-1) +#define CL_CHAR_MAX CL_SCHAR_MAX +#define CL_CHAR_MIN CL_SCHAR_MIN +#define CL_UCHAR_MAX 255 +#define CL_SHRT_MAX 32767 +#define CL_SHRT_MIN (-32767-1) +#define CL_USHRT_MAX 65535 +#define CL_INT_MAX 2147483647 +#define CL_INT_MIN (-2147483647-1) +#define CL_UINT_MAX 0xffffffffU +#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) +#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) +#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) + +#define CL_FLT_DIG 6 +#define CL_FLT_MANT_DIG 24 +#define CL_FLT_MAX_10_EXP +38 +#define CL_FLT_MAX_EXP +128 +#define CL_FLT_MIN_10_EXP -37 +#define CL_FLT_MIN_EXP -125 +#define CL_FLT_RADIX 2 +#define CL_FLT_MAX 0x1.fffffep127f +#define CL_FLT_MIN 0x1.0p-126f +#define CL_FLT_EPSILON 0x1.0p-23f + +#define CL_DBL_DIG 15 +#define CL_DBL_MANT_DIG 53 +#define CL_DBL_MAX_10_EXP +308 +#define CL_DBL_MAX_EXP +1024 +#define CL_DBL_MIN_10_EXP -307 +#define CL_DBL_MIN_EXP -1021 +#define CL_DBL_RADIX 2 +#define CL_DBL_MAX 0x1.fffffffffffffp1023 +#define CL_DBL_MIN 0x1.0p-1022 +#define CL_DBL_EPSILON 0x1.0p-52 + +/* There are no vector types for half */ + +#ifdef __cplusplus +} +#endif + +#endif // __CL_PLATFORM_H diff --git a/src/btBulletCollisionCommon.h b/src/btBulletCollisionCommon.h new file mode 100644 index 0000000..af981b5 --- /dev/null +++ b/src/btBulletCollisionCommon.h @@ -0,0 +1,68 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BULLET_COLLISION_COMMON_H +#define BULLET_COLLISION_COMMON_H + +///Common headerfile includes for Bullet Collision Detection + +///Bullet's btCollisionWorld and btCollisionObject definitions +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" + +///Collision Shapes +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btConeShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "BulletCollision/CollisionShapes/btTriangleMesh.h" +#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" +#include "BulletCollision/CollisionShapes/btEmptyShape.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btUniformScalingShape.h" + +///Narrowphase Collision Detector +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" + +//#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h" + +///Dispatching and generation of collision pairs (broadphase) +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h" +#include "BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h" +#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h" + +///Math library & Utils +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btDefaultMotionState.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btSerializer.h" + + +#endif //BULLET_COLLISION_COMMON_H + diff --git a/src/btBulletDynamicsCommon.h b/src/btBulletDynamicsCommon.h new file mode 100644 index 0000000..dbd175c --- /dev/null +++ b/src/btBulletDynamicsCommon.h @@ -0,0 +1,49 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BULLET_DYNAMICS_COMMON_H +#define BULLET_DYNAMICS_COMMON_H + +///Common headerfile includes for Bullet Dynamics, including Collision Detection +#include "btBulletCollisionCommon.h" + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" + +#include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" +#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" +#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" +#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" +#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" +#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h" +#include "BulletDynamics/ConstraintSolver/btUniversalConstraint.h" +#include "BulletDynamics/ConstraintSolver/btHinge2Constraint.h" +#include "BulletDynamics/ConstraintSolver/btGearConstraint.h" + +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" + + +///Vehicle simulation, with wheel contact simulated by raycasts +#include "BulletDynamics/Vehicle/btRaycastVehicle.h" + + + + + + +#endif //BULLET_DYNAMICS_COMMON_H + diff --git a/src/vectormath/neon/boolInVec.h b/src/vectormath/neon/boolInVec.h new file mode 100644 index 0000000..ba16838 --- /dev/null +++ b/src/vectormath/neon/boolInVec.h @@ -0,0 +1,226 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _BOOLINVEC_H +#define _BOOLINVEC_H + +#include +namespace Vectormath { + +class floatInVec; + +//-------------------------------------------------------------------------------------------------- +// boolInVec class +// + +class boolInVec +{ +private: + unsigned int mData; + +public: + // Default constructor; does no initialization + // + inline boolInVec( ) { }; + + // Construct from a value converted from float + // + inline boolInVec(floatInVec vec); + + // Explicit cast from bool + // + explicit inline boolInVec(bool scalar); + + // Explicit cast to bool + // + inline bool getAsBool() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to bool + // + inline operator bool() const; +#endif + + // Boolean negation operator + // + inline const boolInVec operator ! () const; + + // Assignment operator + // + inline boolInVec& operator = (boolInVec vec); + + // Boolean and assignment operator + // + inline boolInVec& operator &= (boolInVec vec); + + // Boolean exclusive or assignment operator + // + inline boolInVec& operator ^= (boolInVec vec); + + // Boolean or assignment operator + // + inline boolInVec& operator |= (boolInVec vec); + +}; + +// Equal operator +// +inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); + +// And operator +// +inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); + +// Exclusive or operator +// +inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); + +// Or operator +// +inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); + +// Conditionally select between two values +// +inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// boolInVec implementation +// + +#include "floatInVec.h" + +namespace Vectormath { + +inline +boolInVec::boolInVec(floatInVec vec) +{ + *this = (vec != floatInVec(0.0f)); +} + +inline +boolInVec::boolInVec(bool scalar) +{ + mData = -(int)scalar; +} + +inline +bool +boolInVec::getAsBool() const +{ + return (mData > 0); +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +boolInVec::operator bool() const +{ + return getAsBool(); +} +#endif + +inline +const boolInVec +boolInVec::operator ! () const +{ + return boolInVec(!mData); +} + +inline +boolInVec& +boolInVec::operator = (boolInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +boolInVec& +boolInVec::operator &= (boolInVec vec) +{ + *this = *this & vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator ^= (boolInVec vec) +{ + *this = *this ^ vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator |= (boolInVec vec) +{ + *this = *this | vec; + return *this; +} + +inline +const boolInVec +operator == (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() == vec1.getAsBool()); +} + +inline +const boolInVec +operator != (boolInVec vec0, boolInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const boolInVec +operator & (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() & vec1.getAsBool()); +} + +inline +const boolInVec +operator | (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() | vec1.getAsBool()); +} + +inline +const boolInVec +operator ^ (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); +} + +inline +const boolInVec +select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // boolInVec_h + diff --git a/src/vectormath/neon/floatInVec.h b/src/vectormath/neon/floatInVec.h new file mode 100644 index 0000000..26147d2 --- /dev/null +++ b/src/vectormath/neon/floatInVec.h @@ -0,0 +1,344 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ +#ifndef _FLOATINVEC_H +#define _FLOATINVEC_H + +#include +namespace Vectormath { + +class boolInVec; + +//-------------------------------------------------------------------------------------------------- +// floatInVec class +// + +// A class representing a scalar float value contained in a vector register +// This class does not support fastmath +class floatInVec +{ +private: + float mData; + +public: + // Default constructor; does no initialization + // + inline floatInVec( ) { }; + + // Construct from a value converted from bool + // + inline floatInVec(boolInVec vec); + + // Explicit cast from float + // + explicit inline floatInVec(float scalar); + + // Explicit cast to float + // + inline float getAsFloat() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to float + // + inline operator float() const; +#endif + + // Post increment (add 1.0f) + // + inline const floatInVec operator ++ (int); + + // Post decrement (subtract 1.0f) + // + inline const floatInVec operator -- (int); + + // Pre increment (add 1.0f) + // + inline floatInVec& operator ++ (); + + // Pre decrement (subtract 1.0f) + // + inline floatInVec& operator -- (); + + // Negation operator + // + inline const floatInVec operator - () const; + + // Assignment operator + // + inline floatInVec& operator = (floatInVec vec); + + // Multiplication assignment operator + // + inline floatInVec& operator *= (floatInVec vec); + + // Division assignment operator + // + inline floatInVec& operator /= (floatInVec vec); + + // Addition assignment operator + // + inline floatInVec& operator += (floatInVec vec); + + // Subtraction assignment operator + // + inline floatInVec& operator -= (floatInVec vec); + +}; + +// Multiplication operator +// +inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); + +// Division operator +// +inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); + +// Addition operator +// +inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); + +// Subtraction operator +// +inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); + +// Less than operator +// +inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); + +// Less than or equal operator +// +inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); + +// Greater than operator +// +inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); + +// Greater than or equal operator +// +inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); + +// Equal operator +// +inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); + +// Conditionally select between two values +// +inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// floatInVec implementation +// + +#include "boolInVec.h" + +namespace Vectormath { + +inline +floatInVec::floatInVec(boolInVec vec) +{ + mData = float(vec.getAsBool()); +} + +inline +floatInVec::floatInVec(float scalar) +{ + mData = scalar; +} + +inline +float +floatInVec::getAsFloat() const +{ + return mData; +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +floatInVec::operator float() const +{ + return getAsFloat(); +} +#endif + +inline +const floatInVec +floatInVec::operator ++ (int) +{ + float olddata = mData; + operator ++(); + return floatInVec(olddata); +} + +inline +const floatInVec +floatInVec::operator -- (int) +{ + float olddata = mData; + operator --(); + return floatInVec(olddata); +} + +inline +floatInVec& +floatInVec::operator ++ () +{ + *this += floatInVec(1.0f); + return *this; +} + +inline +floatInVec& +floatInVec::operator -- () +{ + *this -= floatInVec(1.0f); + return *this; +} + +inline +const floatInVec +floatInVec::operator - () const +{ + return floatInVec(-mData); +} + +inline +floatInVec& +floatInVec::operator = (floatInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +floatInVec& +floatInVec::operator *= (floatInVec vec) +{ + *this = *this * vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator /= (floatInVec vec) +{ + *this = *this / vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator += (floatInVec vec) +{ + *this = *this + vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator -= (floatInVec vec) +{ + *this = *this - vec; + return *this; +} + +inline +const floatInVec +operator * (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); +} + +inline +const floatInVec +operator / (floatInVec num, floatInVec den) +{ + return floatInVec(num.getAsFloat() / den.getAsFloat()); +} + +inline +const floatInVec +operator + (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); +} + +inline +const floatInVec +operator - (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); +} + +inline +const boolInVec +operator < (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); +} + +inline +const boolInVec +operator <= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 > vec1); +} + +inline +const boolInVec +operator > (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); +} + +inline +const boolInVec +operator >= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 < vec1); +} + +inline +const boolInVec +operator == (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); +} + +inline +const boolInVec +operator != (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const floatInVec +select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // floatInVec_h + diff --git a/src/vectormath/neon/mat_aos.h b/src/vectormath/neon/mat_aos.h new file mode 100644 index 0000000..e61f601 --- /dev/null +++ b/src/vectormath/neon/mat_aos.h @@ -0,0 +1,1631 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _VECTORMATH_MAT_AOS_CPP_H +#define _VECTORMATH_MAT_AOS_CPP_H + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_PI_OVER_2 1.570796327f + +//----------------------------------------------------------------------------- +// Definitions + +inline Matrix3::Matrix3( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; +} + +inline Matrix3::Matrix3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +inline Matrix3::Matrix3( const Quat & unitQuat ) +{ + float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; + qx = unitQuat.getX(); + qy = unitQuat.getY(); + qz = unitQuat.getZ(); + qw = unitQuat.getW(); + qx2 = ( qx + qx ); + qy2 = ( qy + qy ); + qz2 = ( qz + qz ); + qxqx2 = ( qx * qx2 ); + qxqy2 = ( qx * qy2 ); + qxqz2 = ( qx * qz2 ); + qxqw2 = ( qw * qx2 ); + qyqy2 = ( qy * qy2 ); + qyqz2 = ( qy * qz2 ); + qyqw2 = ( qw * qy2 ); + qzqz2 = ( qz * qz2 ); + qzqw2 = ( qw * qz2 ); + mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); + mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); + mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); +} + +inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; +} + +inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + return *this; +} + +inline Matrix3 & Matrix3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Matrix3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Matrix3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Matrix3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Matrix3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::getRow( int row ) const +{ + return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); +} + +inline Vector3 & Matrix3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; +} + +inline const Matrix3 transpose( const Matrix3 & mat ) +{ + return Matrix3( + Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), + Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), + Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) + ); +} + +inline const Matrix3 inverse( const Matrix3 & mat ) +{ + Vector3 tmp0, tmp1, tmp2; + float detinv; + tmp0 = cross( mat.getCol1(), mat.getCol2() ); + tmp1 = cross( mat.getCol2(), mat.getCol0() ); + tmp2 = cross( mat.getCol0(), mat.getCol1() ); + detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) ); + return Matrix3( + Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ), + Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ), + Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ) + ); +} + +inline float determinant( const Matrix3 & mat ) +{ + return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); +} + +inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ) + ); +} + +inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ) + ); +} + +inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix3 Matrix3::operator -( ) const +{ + return Matrix3( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ) + ); +} + +inline const Matrix3 absPerElem( const Matrix3 & mat ) +{ + return Matrix3( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::operator *( float scalar ) const +{ + return Matrix3( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ) + ); +} + +inline Matrix3 & Matrix3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) +{ + return mat * scalar; +} + +inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const +{ + return Vector3( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ); +} + +inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +{ + return Matrix3( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ) + ); +} + +inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +{ + *this = *this * mat; + return *this; +} + +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +{ + return Matrix3( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::identity( ) +{ + return Matrix3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ) + ); +} + +inline const Matrix3 Matrix3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ) + ); +} + +inline const Matrix3 Matrix3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix3( + Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ), + Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ), + Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) +{ + return Matrix3( unitQuat ); +} + +inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) +{ + return Matrix3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ) + ); +} + +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) +{ + return Matrix3( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ) + ); +} + +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) +{ + return Matrix3( + mulPerElem( mat.getCol0(), scaleVec ), + mulPerElem( mat.getCol1(), scaleVec ), + mulPerElem( mat.getCol2(), scaleVec ) + ); +} + +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix3 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); +} + +inline void print( const Matrix3 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Matrix4::Matrix4( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; +} + +inline Matrix4::Matrix4( float scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +inline Matrix4::Matrix4( const Transform3 & mat ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( mat.getCol3(), 1.0f ); +} + +inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) +{ + Matrix3 mat; + mat = Matrix3( unitQuat ); + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Matrix4 & Matrix4::setElem( int col, int row, float val ) +{ + Vector4 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix4::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector4 Matrix4::getCol0( ) const +{ + return mCol0; +} + +inline const Vector4 Matrix4::getCol1( ) const +{ + return mCol1; +} + +inline const Vector4 Matrix4::getCol2( ) const +{ + return mCol2; +} + +inline const Vector4 Matrix4::getCol3( ) const +{ + return mCol3; +} + +inline const Vector4 Matrix4::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector4 & Matrix4::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; +} + +inline const Matrix4 transpose( const Matrix4 & mat ) +{ + return Matrix4( + Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), + Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), + Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), + Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) + ); +} + +inline const Matrix4 inverse( const Matrix4 & mat ) +{ + Vector4 res0, res1, res2, res3; + float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); + res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); + res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); + res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); + detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) ); + res1.setX( ( mI * tmp1 ) ); + res1.setY( ( mM * tmp0 ) ); + res1.setZ( ( mA * tmp1 ) ); + res1.setW( ( mE * tmp0 ) ); + res3.setX( ( mI * tmp3 ) ); + res3.setY( ( mM * tmp2 ) ); + res3.setZ( ( mA * tmp3 ) ); + res3.setW( ( mE * tmp2 ) ); + res2.setX( ( mI * tmp5 ) ); + res2.setY( ( mM * tmp4 ) ); + res2.setZ( ( mA * tmp5 ) ); + res2.setW( ( mE * tmp4 ) ); + tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); + tmp1 = ( ( mM * mF ) - ( mE * mN ) ); + tmp2 = ( ( mI * mD ) - ( mA * mL ) ); + tmp3 = ( ( mM * mH ) - ( mE * mP ) ); + tmp4 = ( ( mI * mC ) - ( mA * mK ) ); + tmp5 = ( ( mM * mG ) - ( mE * mO ) ); + res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) ); + res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) ); + res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) ); + res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) ); + res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) ); + res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) ); + res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) ); + res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) ); + res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) ); + res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) ); + res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) ); + res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) ); + return Matrix4( + ( res0 * detInv ), + ( res1 * detInv ), + ( res2 * detInv ), + ( res3 * detInv ) + ); +} + +inline const Matrix4 affineInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( inverse( affineMat ) ); +} + +inline const Matrix4 orthoInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( orthoInverse( affineMat ) ); +} + +inline float determinant( const Matrix4 & mat ) +{ + float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); + dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); + dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); + dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); + return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); +} + +inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ), + ( mCol3 + mat.mCol3 ) + ); +} + +inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ), + ( mCol3 - mat.mCol3 ) + ); +} + +inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix4 Matrix4::operator -( ) const +{ + return Matrix4( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ), + ( -mCol3 ) + ); +} + +inline const Matrix4 absPerElem( const Matrix4 & mat ) +{ + return Matrix4( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ), + absPerElem( mat.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::operator *( float scalar ) const +{ + return Matrix4( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ), + ( mCol3 * scalar ) + ); +} + +inline Matrix4 & Matrix4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) +{ + return mat * scalar; +} + +inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), + ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), + ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), + ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const +{ + return Vector4( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ), + ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ), + ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() ) + ); +} + +inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +{ + return Matrix4( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ), + ( *this * mat.mCol3 ) + ); +} + +inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +{ + *this = *this * mat; + return *this; +} + +inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +{ + return Matrix4( + ( *this * tfrm.getCol0() ), + ( *this * tfrm.getCol1() ), + ( *this * tfrm.getCol2() ), + ( *this * Point3( tfrm.getCol3() ) ) + ); +} + +inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +{ + return Matrix4( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ), + mulPerElem( mat0.getCol3(), mat1.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::identity( ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +{ + mCol0.setXYZ( mat3.getCol0() ); + mCol1.setXYZ( mat3.getCol1() ); + mCol2.setXYZ( mat3.getCol2() ); + return *this; +} + +inline const Matrix3 Matrix4::getUpper3x3( ) const +{ + return Matrix3( + mCol0.getXYZ( ), + mCol1.getXYZ( ), + mCol2.getXYZ( ) + ); +} + +inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) +{ + mCol3.setXYZ( translateVec ); + return *this; +} + +inline const Vector3 Matrix4::getTranslation( ) const +{ + return mCol3.getXYZ( ); +} + +inline const Matrix4 Matrix4::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4::xAxis( ), + Vector4( 0.0f, c, s, 0.0f ), + Vector4( 0.0f, -s, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, 0.0f, -s, 0.0f ), + Vector4::yAxis( ), + Vector4( s, 0.0f, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, s, 0.0f, 0.0f ), + Vector4( -s, c, 0.0f, 0.0f ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix4( + Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ), + Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ), + Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix4( + Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ), + Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ), + Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) +{ + return Matrix4( Transform3::rotation( unitQuat ) ); +} + +inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) +{ + return Matrix4( + Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) +{ + return Matrix4( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ), + mat.getCol3() + ); +} + +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) +{ + Vector4 scale4; + scale4 = Vector4( scaleVec, 1.0f ); + return Matrix4( + mulPerElem( mat.getCol0(), scale4 ), + mulPerElem( mat.getCol1(), scale4 ), + mulPerElem( mat.getCol2(), scale4 ), + mulPerElem( mat.getCol3(), scale4 ) + ); +} + +inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4( translateVec, 1.0f ) + ); +} + +inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) +{ + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize( upVec ); + v3Z = normalize( ( eyePos - lookAtPos ) ); + v3X = normalize( cross( v3Y, v3Z ) ); + v3Y = cross( v3Z, v3X ); + m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); + return orthoInverse( m4EyeFrame ); +} + +inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +{ + float f, rangeInv; + f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); + rangeInv = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, f, 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + n2 = ( zNear + zNear ); + return Matrix4( + Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ), + Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ), + Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ) + ); +} + +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix4 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); + print( mat.getRow( 3 ) ); +} + +inline void print( const Matrix4 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Transform3::Transform3( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; +} + +inline Transform3::Transform3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) +{ + this->setUpper3x3( tfrm ); + this->setTranslation( translateVec ); +} + +inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) +{ + this->setUpper3x3( Matrix3( unitQuat ) ); + this->setTranslation( translateVec ); +} + +inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Transform3 & Transform3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Transform3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Transform3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Transform3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Transform3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Transform3::getCol3( ) const +{ + return mCol3; +} + +inline const Vector3 Transform3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Transform3::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector3 & Transform3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Transform3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; +} + +inline const Transform3 inverse( const Transform3 & tfrm ) +{ + Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; + float detinv; + tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); + tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); + tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); + detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) ); + inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ); + inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ); + inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ); + return Transform3( + inv0, + inv1, + inv2, + Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) + ); +} + +inline const Transform3 orthoInverse( const Transform3 & tfrm ) +{ + Vector3 inv0, inv1, inv2; + inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); + inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); + inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); + return Transform3( + inv0, + inv1, + inv2, + Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) + ); +} + +inline const Transform3 absPerElem( const Transform3 & tfrm ) +{ + return Transform3( + absPerElem( tfrm.getCol0() ), + absPerElem( tfrm.getCol1() ), + absPerElem( tfrm.getCol2() ), + absPerElem( tfrm.getCol3() ) + ); +} + +inline const Vector3 Transform3::operator *( const Vector3 & vec ) const +{ + return Vector3( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ); +} + +inline const Point3 Transform3::operator *( const Point3 & pnt ) const +{ + return Point3( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ) + ); +} + +inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +{ + return Transform3( + ( *this * tfrm.mCol0 ), + ( *this * tfrm.mCol1 ), + ( *this * tfrm.mCol2 ), + Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) + ); +} + +inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +{ + return Transform3( + mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), + mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), + mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), + mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) + ); +} + +inline const Transform3 Transform3::identity( ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +{ + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; +} + +inline const Matrix3 Transform3::getUpper3x3( ) const +{ + return Matrix3( mCol0, mCol1, mCol2 ); +} + +inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) +{ + mCol3 = translateVec; + return *this; +} + +inline const Vector3 Transform3::getTranslation( ) const +{ + return mCol3; +} + +inline const Transform3 Transform3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Transform3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec ) +{ + return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::rotation( const Quat & unitQuat ) +{ + return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) +{ + return Transform3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) +{ + return Transform3( + ( tfrm.getCol0() * scaleVec.getX( ) ), + ( tfrm.getCol1() * scaleVec.getY( ) ), + ( tfrm.getCol2() * scaleVec.getZ( ) ), + tfrm.getCol3() + ); +} + +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) +{ + return Transform3( + mulPerElem( tfrm.getCol0(), scaleVec ), + mulPerElem( tfrm.getCol1(), scaleVec ), + mulPerElem( tfrm.getCol2(), scaleVec ), + mulPerElem( tfrm.getCol3(), scaleVec ) + ); +} + +inline const Transform3 Transform3::translation( const Vector3 & translateVec ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + translateVec + ); +} + +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Transform3 & tfrm ) +{ + print( tfrm.getRow( 0 ) ); + print( tfrm.getRow( 1 ) ); + print( tfrm.getRow( 2 ) ); +} + +inline void print( const Transform3 & tfrm, const char * name ) +{ + printf("%s:\n", name); + print( tfrm ); +} + +#endif + +inline Quat::Quat( const Matrix3 & tfrm ) +{ + float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; + int negTrace, ZgtX, ZgtY, YgtX; + int largestXorY, largestYorZ, largestZorX; + + xx = tfrm.getCol0().getX(); + yx = tfrm.getCol0().getY(); + zx = tfrm.getCol0().getZ(); + xy = tfrm.getCol1().getX(); + yy = tfrm.getCol1().getY(); + zy = tfrm.getCol1().getZ(); + xz = tfrm.getCol2().getX(); + yz = tfrm.getCol2().getY(); + zz = tfrm.getCol2().getZ(); + + trace = ( ( xx + yy ) + zz ); + + negTrace = ( trace < 0.0f ); + ZgtX = zz > xx; + ZgtY = zz > yy; + YgtX = yy > xx; + largestXorY = ( !ZgtX || !ZgtY ) && negTrace; + largestYorZ = ( YgtX || ZgtX ) && negTrace; + largestZorX = ( ZgtY || !YgtX ) && negTrace; + + if ( largestXorY ) + { + zz = -zz; + xy = -xy; + } + if ( largestYorZ ) + { + xx = -xx; + yz = -yz; + } + if ( largestZorX ) + { + yy = -yy; + zx = -zx; + } + + radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); + scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); + + tmpx = ( ( zy - yz ) * scale ); + tmpy = ( ( xz - zx ) * scale ); + tmpz = ( ( yx - xy ) * scale ); + tmpw = ( radicand * scale ); + qx = tmpx; + qy = tmpy; + qz = tmpz; + qw = tmpw; + + if ( largestXorY ) + { + qx = tmpw; + qy = tmpz; + qz = tmpy; + qw = tmpx; + } + if ( largestYorZ ) + { + tmpx = qx; + tmpz = qz; + qx = qy; + qy = tmpx; + qz = qw; + qw = tmpz; + } + + mXYZW[0] = qx; + mXYZW[1] = qy; + mXYZW[2] = qz; + mXYZW[3] = qw; +} + +inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) +{ + return Matrix3( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ) + ); +} + +inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) +{ + return Matrix4( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ), + ( tfrm0 * tfrm1.getW( ) ) + ); +} + +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Vector3( + ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ), + ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ), + ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) ) + ); +} + +inline const Matrix3 crossMatrix( const Vector3 & vec ) +{ + return Matrix3( + Vector3( 0.0f, vec.getZ(), -vec.getY() ), + Vector3( -vec.getZ(), 0.0f, vec.getX() ), + Vector3( vec.getY(), -vec.getX(), 0.0f ) + ); +} + +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); +} + +} // namespace Aos +} // namespace Vectormath + +#endif + diff --git a/src/vectormath/neon/quat_aos.h b/src/vectormath/neon/quat_aos.h new file mode 100644 index 0000000..d061846 --- /dev/null +++ b/src/vectormath/neon/quat_aos.h @@ -0,0 +1,413 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _VECTORMATH_QUAT_AOS_CPP_H +#define _VECTORMATH_QUAT_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + + inline Quat::Quat( const Quat & quat ) + { + vXYZW = quat.vXYZW; + } + + inline Quat::Quat( float _x, float _y, float _z, float _w ) + { + mXYZW[0] = _x; + mXYZW[1] = _y; + mXYZW[2] = _z; + mXYZW[3] = _w; + } + + inline Quat::Quat( float32x4_t fXYZW ) + { + vXYZW = fXYZW; + } + + inline Quat::Quat( const Vector3 & xyz, float _w ) + { + this->setXYZ( xyz ); + this->setW( _w ); + } + + inline Quat::Quat( const Vector4 & vec ) + { + mXYZW[0] = vec.getX(); + mXYZW[1] = vec.getY(); + mXYZW[2] = vec.getZ(); + mXYZW[3] = vec.getW(); + } + + inline Quat::Quat( float scalar ) + { + vXYZW = vdupq_n_f32(scalar); + } + + inline const Quat Quat::identity( ) + { + return Quat( 0.0f, 0.0f, 0.0f, 1.0f ); + } + + inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ) + { + return ( quat0 + ( ( quat1 - quat0 ) * t ) ); + } + + inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ) + { + Quat start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitQuat0, unitQuat1 ); + if ( cosAngle < 0.0f ) { + cosAngle = -cosAngle; + start = ( -unitQuat0 ); + } else { + start = unitQuat0; + } + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); + } + + inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) + { + Quat tmp0, tmp1; + tmp0 = slerp( t, unitQuat0, unitQuat3 ); + tmp1 = slerp( t, unitQuat1, unitQuat2 ); + return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); + } + + inline void loadXYZW( Quat & quat, const float * fptr ) + { + quat = Quat( fptr[0], fptr[1], fptr[2], fptr[3] ); + } + + inline void storeXYZW( const Quat & quat, float * fptr ) + { + vst1q_f32(fptr, quat.getvXYZW()); + } + + inline Quat & Quat::operator =( const Quat & quat ) + { + vXYZW = quat.getvXYZW(); + return *this; + } + + inline Quat & Quat::setXYZ( const Vector3 & vec ) + { + mXYZW[0] = vec.getX(); + mXYZW[1] = vec.getY(); + mXYZW[2] = vec.getZ(); + return *this; + } + + inline const Vector3 Quat::getXYZ( ) const + { + return Vector3( mXYZW[0], mXYZW[1], mXYZW[2] ); + } + + inline float32x4_t Quat::getvXYZW( ) const + { + return vXYZW; + } + + inline Quat & Quat::setX( float _x ) + { + mXYZW[0] = _x; + return *this; + } + + inline float Quat::getX( ) const + { + return mXYZW[0]; + } + + inline Quat & Quat::setY( float _y ) + { + mXYZW[1] = _y; + return *this; + } + + inline float Quat::getY( ) const + { + return mXYZW[1]; + } + + inline Quat & Quat::setZ( float _z ) + { + mXYZW[2] = _z; + return *this; + } + + inline float Quat::getZ( ) const + { + return mXYZW[2]; + } + + inline Quat & Quat::setW( float _w ) + { + mXYZW[3] = _w; + return *this; + } + + inline float Quat::getW( ) const + { + return mXYZW[3]; + } + + inline Quat & Quat::setElem( int idx, float value ) + { + *(&mXYZW[0] + idx) = value; + return *this; + } + + inline float Quat::getElem( int idx ) const + { + return *(&mXYZW[0] + idx); + } + + inline float & Quat::operator []( int idx ) + { + return *(&mXYZW[0] + idx); + } + + inline float Quat::operator []( int idx ) const + { + return *(&mXYZW[0] + idx); + } + + inline const Quat Quat::operator +( const Quat & quat ) const + { + return Quat( vaddq_f32(vXYZW, quat.vXYZW) ); + } + + inline const Quat Quat::operator -( const Quat & quat ) const + { + return Quat( vsubq_f32(vXYZW, quat.vXYZW) ); + } + + inline const Quat Quat::operator *( float scalar ) const + { + float32x4_t v_scalar = vdupq_n_f32(scalar); + return Quat( vmulq_f32(vXYZW, v_scalar) ); + } + + inline Quat & Quat::operator +=( const Quat & quat ) + { + *this = *this + quat; + return *this; + } + + inline Quat & Quat::operator -=( const Quat & quat ) + { + *this = *this - quat; + return *this; + } + + inline Quat & Quat::operator *=( float scalar ) + { + *this = *this * scalar; + return *this; + } + + inline const Quat Quat::operator /( float scalar ) const + { + return Quat( + ( mXYZW[0] / scalar ), + ( mXYZW[1] / scalar ), + ( mXYZW[2] / scalar ), + ( mXYZW[3] / scalar ) + ); + } + + inline Quat & Quat::operator /=( float scalar ) + { + *this = *this / scalar; + return *this; + } + + inline const Quat Quat::operator -( ) const + { + return Quat( vnegq_f32(vXYZW) ); + } + + inline const Quat operator *( float scalar, const Quat & quat ) + { + return quat * scalar; + } + + inline float dot( const Quat & quat0, const Quat & quat1 ) + { + float result; + result = ( quat0.getX() * quat1.getX() ); + result = ( result + ( quat0.getY() * quat1.getY() ) ); + result = ( result + ( quat0.getZ() * quat1.getZ() ) ); + result = ( result + ( quat0.getW() * quat1.getW() ) ); + return result; + } + + inline float norm( const Quat & quat ) + { + float result; + result = ( quat.getX() * quat.getX() ); + result = ( result + ( quat.getY() * quat.getY() ) ); + result = ( result + ( quat.getZ() * quat.getZ() ) ); + result = ( result + ( quat.getW() * quat.getW() ) ); + return result; + } + + inline float length( const Quat & quat ) + { + return ::sqrtf( norm( quat ) ); + } + + inline const Quat normalize( const Quat & quat ) + { + float lenSqr, lenInv; + lenSqr = norm( quat ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Quat( + ( quat.getX() * lenInv ), + ( quat.getY() * lenInv ), + ( quat.getZ() * lenInv ), + ( quat.getW() * lenInv ) + ); + } + + inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) + { + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); + recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); + return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); + } + + inline const Quat Quat::rotation( float radians, const Vector3 & unitVec ) + { + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( ( unitVec * s ), c ); + } + + inline const Quat Quat::rotationX( float radians ) + { + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( s, 0.0f, 0.0f, c ); + } + + inline const Quat Quat::rotationY( float radians ) + { + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, s, 0.0f, c ); + } + + inline const Quat Quat::rotationZ( float radians ) + { + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, 0.0f, s, c ); + } + + inline const Quat Quat::operator *( const Quat & quat ) const + { + return Quat( + ( ( ( ( mXYZW[3] * quat.mXYZW[0] ) + ( mXYZW[0] * quat.mXYZW[3] ) ) + ( mXYZW[1] * quat.mXYZW[2] ) ) - ( mXYZW[2] * quat.mXYZW[1] ) ), + ( ( ( ( mXYZW[3] * quat.mXYZW[1] ) + ( mXYZW[1] * quat.mXYZW[3] ) ) + ( mXYZW[2] * quat.mXYZW[0] ) ) - ( mXYZW[0] * quat.mXYZW[2] ) ), + ( ( ( ( mXYZW[3] * quat.mXYZW[2] ) + ( mXYZW[2] * quat.mXYZW[3] ) ) + ( mXYZW[0] * quat.mXYZW[1] ) ) - ( mXYZW[1] * quat.mXYZW[0] ) ), + ( ( ( ( mXYZW[3] * quat.mXYZW[3] ) - ( mXYZW[0] * quat.mXYZW[0] ) ) - ( mXYZW[1] * quat.mXYZW[1] ) ) - ( mXYZW[2] * quat.mXYZW[2] ) ) + ); + } + + inline Quat & Quat::operator *=( const Quat & quat ) + { + *this = *this * quat; + return *this; + } + + inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) + { + float tmpX, tmpY, tmpZ, tmpW; + tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); + tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); + tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); + tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); + return Vector3( + ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), + ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), + ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) + ); + } + + inline const Quat conj( const Quat & quat ) + { + return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); + } + + inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ) + { + return Quat( + ( select1 )? quat1.getX() : quat0.getX(), + ( select1 )? quat1.getY() : quat0.getY(), + ( select1 )? quat1.getZ() : quat0.getZ(), + ( select1 )? quat1.getW() : quat0.getW() + ); + } + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Quat & quat ) +{ + printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +inline void print( const Quat & quat, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif + diff --git a/src/vectormath/neon/vec_aos.h b/src/vectormath/neon/vec_aos.h new file mode 100644 index 0000000..7bcf8db --- /dev/null +++ b/src/vectormath/neon/vec_aos.h @@ -0,0 +1,1427 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _VECTORMATH_VEC_AOS_CPP_H +#define _VECTORMATH_VEC_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_SLERP_TOL 0.999f + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +inline Vector3::Vector3( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; +} + +inline Vector3::Vector3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +} + +inline Vector3::Vector3( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); +} + +inline Vector3::Vector3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +} + +inline const Vector3 Vector3::xAxis( ) +{ + return Vector3( 1.0f, 0.0f, 0.0f ); +} + +inline const Vector3 Vector3::yAxis( ) +{ + return Vector3( 0.0f, 1.0f, 0.0f ); +} + +inline const Vector3 Vector3::zAxis( ) +{ + return Vector3( 0.0f, 0.0f, 1.0f ); +} + +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZ( Vector3 & vec, const float * fptr ) +{ + vec = Vector3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Vector3 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector3 & Vector3::operator =( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + return *this; +} + +inline Vector3 & Vector3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector3::getX( ) const +{ + return mX; +} + +inline Vector3 & Vector3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector3::getY( ) const +{ + return mY; +} + +inline Vector3 & Vector3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector3::getZ( ) const +{ + return mZ; +} + +inline Vector3 & Vector3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Vector3::operator +( const Vector3 & vec ) const +{ + return Vector3( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ) + ); +} + +inline const Vector3 Vector3::operator -( const Vector3 & vec ) const +{ + return Vector3( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ) + ); +} + +inline const Point3 Vector3::operator +( const Point3 & pnt ) const +{ + return Point3( + ( mX + pnt.getX() ), + ( mY + pnt.getY() ), + ( mZ + pnt.getZ() ) + ); +} + +inline const Vector3 Vector3::operator *( float scalar ) const +{ + return Vector3( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ) + ); +} + +inline Vector3 & Vector3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector3 & Vector3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector3 & Vector3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector3 Vector3::operator /( float scalar ) const +{ + return Vector3( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ) + ); +} + +inline Vector3 & Vector3::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector3 Vector3::operator -( ) const +{ + return Vector3( + -mX, + -mY, + -mZ + ); +} + +inline const Vector3 operator *( float scalar, const Vector3 & vec ) +{ + return vec * scalar; +} + +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ) + ); +} + +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ) + ); +} + +inline const Vector3 recipPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ) + ); +} + +inline const Vector3 sqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ) + ); +} + +inline const Vector3 rsqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ) + ); +} + +inline const Vector3 absPerElem( const Vector3 & vec ) +{ + return Vector3( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ) + ); +} + +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ) + ); +} + +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float maxElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + return result; +} + +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float minElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + return result; +} + +inline float sum( const Vector3 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + return result; +} + +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ) +{ + float result; + result = ( vec0.getX() * vec1.getX() ); + result = ( result + ( vec0.getY() * vec1.getY() ) ); + result = ( result + ( vec0.getZ() * vec1.getZ() ) ); + return result; +} + +inline float lengthSqr( const Vector3 & vec ) +{ + float result; + result = ( vec.getX() * vec.getX() ); + result = ( result + ( vec.getY() * vec.getY() ) ); + result = ( result + ( vec.getZ() * vec.getZ() ) ); + return result; +} + +inline float length( const Vector3 & vec ) +{ + return ::sqrtf( lengthSqr( vec ) ); +} + +inline const Vector3 normalize( const Vector3 & vec ) +{ + float lenSqr, lenInv; + lenSqr = lengthSqr( vec ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Vector3( + ( vec.getX() * lenInv ), + ( vec.getY() * lenInv ), + ( vec.getZ() * lenInv ) + ); +} + +inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( ( vec0.getY() * vec1.getZ() ) - ( vec0.getZ() * vec1.getY() ) ), + ( ( vec0.getZ() * vec1.getX() ) - ( vec0.getX() * vec1.getZ() ) ), + ( ( vec0.getX() * vec1.getY() ) - ( vec0.getY() * vec1.getX() ) ) + ); +} + +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ) +{ + return Vector3( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector3 & vec ) +{ + printf( "( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ() ); +} + +inline void print( const Vector3 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ() ); +} + +#endif + +inline Vector4::Vector4( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; +} + +inline Vector4::Vector4( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Vector4::Vector4( const Vector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Vector4::Vector4( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = 0.0f; +} + +inline Vector4::Vector4( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); + mW = 1.0f; +} + +inline Vector4::Vector4( const Quat & quat ) +{ + mX = quat.getX(); + mY = quat.getY(); + mZ = quat.getZ(); + mW = quat.getW(); +} + +inline Vector4::Vector4( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Vector4 Vector4::xAxis( ) +{ + return Vector4( 1.0f, 0.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::yAxis( ) +{ + return Vector4( 0.0f, 1.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::zAxis( ) +{ + return Vector4( 0.0f, 0.0f, 1.0f, 0.0f ); +} + +inline const Vector4 Vector4::wAxis( ) +{ + return Vector4( 0.0f, 0.0f, 0.0f, 1.0f ); +} + +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZW( Vector4 & vec, const float * fptr ) +{ + vec = Vector4( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW( const Vector4 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); + fptr[3] = vec.getW(); +} + +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector4 & Vector4::operator =( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; + return *this; +} + +inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const Vector3 Vector4::getXYZ( ) const +{ + return Vector3( mX, mY, mZ ); +} + +inline Vector4 & Vector4::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector4::getX( ) const +{ + return mX; +} + +inline Vector4 & Vector4::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector4::getY( ) const +{ + return mY; +} + +inline Vector4 & Vector4::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector4::getZ( ) const +{ + return mZ; +} + +inline Vector4 & Vector4::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Vector4::getW( ) const +{ + return mW; +} + +inline Vector4 & Vector4::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector4::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector4::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector4::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector4 Vector4::operator +( const Vector4 & vec ) const +{ + return Vector4( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ), + ( mW + vec.mW ) + ); +} + +inline const Vector4 Vector4::operator -( const Vector4 & vec ) const +{ + return Vector4( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ), + ( mW - vec.mW ) + ); +} + +inline const Vector4 Vector4::operator *( float scalar ) const +{ + return Vector4( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Vector4 & Vector4::operator +=( const Vector4 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector4 & Vector4::operator -=( const Vector4 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector4 & Vector4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector4 Vector4::operator /( float scalar ) const +{ + return Vector4( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Vector4 & Vector4::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector4 Vector4::operator -( ) const +{ + return Vector4( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Vector4 operator *( float scalar, const Vector4 & vec ) +{ + return vec * scalar; +} + +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ), + ( vec0.getW() * vec1.getW() ) + ); +} + +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ), + ( vec0.getW() / vec1.getW() ) + ); +} + +inline const Vector4 recipPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ), + ( 1.0f / vec.getW() ) + ); +} + +inline const Vector4 sqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ), + sqrtf( vec.getW() ) + ); +} + +inline const Vector4 rsqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ), + ( 1.0f / sqrtf( vec.getW() ) ) + ); +} + +inline const Vector4 absPerElem( const Vector4 & vec ) +{ + return Vector4( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ), + fabsf( vec.getW() ) + ); +} + +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ), + ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() ) + ); +} + +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float maxElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + result = (vec.getW() > result)? vec.getW() : result; + return result; +} + +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float minElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + result = (vec.getW() < result)? vec.getW() : result; + return result; +} + +inline float sum( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + result = ( result + vec.getW() ); + return result; +} + +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ) +{ + float result; + result = ( vec0.getX() * vec1.getX() ); + result = ( result + ( vec0.getY() * vec1.getY() ) ); + result = ( result + ( vec0.getZ() * vec1.getZ() ) ); + result = ( result + ( vec0.getW() * vec1.getW() ) ); + return result; +} + +inline float lengthSqr( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() * vec.getX() ); + result = ( result + ( vec.getY() * vec.getY() ) ); + result = ( result + ( vec.getZ() * vec.getZ() ) ); + result = ( result + ( vec.getW() * vec.getW() ) ); + return result; +} + +inline float length( const Vector4 & vec ) +{ + return ::sqrtf( lengthSqr( vec ) ); +} + +inline const Vector4 normalize( const Vector4 & vec ) +{ + float lenSqr, lenInv; + lenSqr = lengthSqr( vec ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Vector4( + ( vec.getX() * lenInv ), + ( vec.getY() * lenInv ), + ( vec.getZ() * lenInv ), + ( vec.getW() * lenInv ) + ); +} + +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ) +{ + return Vector4( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ(), + ( select1 )? vec1.getW() : vec0.getW() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector4 & vec ) +{ + printf( "( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +inline void print( const Vector4 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +#endif + +inline Point3::Point3( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; +} + +inline Point3::Point3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +} + +inline Point3::Point3( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); +} + +inline Point3::Point3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +} + +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ) +{ + return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); +} + +inline void loadXYZ( Point3 & pnt, const float * fptr ) +{ + pnt = Point3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Point3 & pnt, float * fptr ) +{ + fptr[0] = pnt.getX(); + fptr[1] = pnt.getY(); + fptr[2] = pnt.getZ(); +} + +inline void loadHalfFloats( Point3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Point3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Point3 & Point3::operator =( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; + return *this; +} + +inline Point3 & Point3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Point3::getX( ) const +{ + return mX; +} + +inline Point3 & Point3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Point3::getY( ) const +{ + return mY; +} + +inline Point3 & Point3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Point3::getZ( ) const +{ + return mZ; +} + +inline Point3 & Point3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Point3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Point3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Point3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Point3::operator -( const Point3 & pnt ) const +{ + return Vector3( + ( mX - pnt.mX ), + ( mY - pnt.mY ), + ( mZ - pnt.mZ ) + ); +} + +inline const Point3 Point3::operator +( const Vector3 & vec ) const +{ + return Point3( + ( mX + vec.getX() ), + ( mY + vec.getY() ), + ( mZ + vec.getZ() ) + ); +} + +inline const Point3 Point3::operator -( const Vector3 & vec ) const +{ + return Point3( + ( mX - vec.getX() ), + ( mY - vec.getY() ), + ( mZ - vec.getZ() ) + ); +} + +inline Point3 & Point3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Point3 & Point3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() * pnt1.getX() ), + ( pnt0.getY() * pnt1.getY() ), + ( pnt0.getZ() * pnt1.getZ() ) + ); +} + +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() / pnt1.getX() ), + ( pnt0.getY() / pnt1.getY() ), + ( pnt0.getZ() / pnt1.getZ() ) + ); +} + +inline const Point3 recipPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / pnt.getX() ), + ( 1.0f / pnt.getY() ), + ( 1.0f / pnt.getZ() ) + ); +} + +inline const Point3 sqrtPerElem( const Point3 & pnt ) +{ + return Point3( + sqrtf( pnt.getX() ), + sqrtf( pnt.getY() ), + sqrtf( pnt.getZ() ) + ); +} + +inline const Point3 rsqrtPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / sqrtf( pnt.getX() ) ), + ( 1.0f / sqrtf( pnt.getY() ) ), + ( 1.0f / sqrtf( pnt.getZ() ) ) + ); +} + +inline const Point3 absPerElem( const Point3 & pnt ) +{ + return Point3( + fabsf( pnt.getX() ), + fabsf( pnt.getY() ), + fabsf( pnt.getZ() ) + ); +} + +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ), + ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ), + ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() ) + ); +} + +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float maxElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() > result)? pnt.getZ() : result; + return result; +} + +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float minElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() < result)? pnt.getZ() : result; + return result; +} + +inline float sum( const Point3 & pnt ) +{ + float result; + result = ( pnt.getX() + pnt.getY() ); + result = ( result + pnt.getZ() ); + return result; +} + +inline const Point3 scale( const Point3 & pnt, float scaleVal ) +{ + return mulPerElem( pnt, Point3( scaleVal ) ); +} + +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) +{ + return mulPerElem( pnt, Point3( scaleVec ) ); +} + +inline float projection( const Point3 & pnt, const Vector3 & unitVec ) +{ + float result; + result = ( pnt.getX() * unitVec.getX() ); + result = ( result + ( pnt.getY() * unitVec.getY() ) ); + result = ( result + ( pnt.getZ() * unitVec.getZ() ) ); + return result; +} + +inline float distSqrFromOrigin( const Point3 & pnt ) +{ + return lengthSqr( Vector3( pnt ) ); +} + +inline float distFromOrigin( const Point3 & pnt ) +{ + return length( Vector3( pnt ) ); +} + +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return lengthSqr( ( pnt1 - pnt0 ) ); +} + +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return length( ( pnt1 - pnt0 ) ); +} + +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ) +{ + return Point3( + ( select1 )? pnt1.getX() : pnt0.getX(), + ( select1 )? pnt1.getY() : pnt0.getY(), + ( select1 )? pnt1.getZ() : pnt0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Point3 & pnt ) +{ + printf( "( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +inline void print( const Point3 & pnt, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif + diff --git a/src/vectormath/neon/vectormath_aos.h b/src/vectormath/neon/vectormath_aos.h new file mode 100644 index 0000000..97bdc27 --- /dev/null +++ b/src/vectormath/neon/vectormath_aos.h @@ -0,0 +1,1890 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +This source version has been altered. + +*/ + +#ifndef _VECTORMATH_AOS_CPP_H +#define _VECTORMATH_AOS_CPP_H + +#include + +#ifdef _VECTORMATH_DEBUG +#include +#endif + +namespace Vectormath { + +namespace Aos { + +//----------------------------------------------------------------------------- +// Forward Declarations +// + +class Vector3; +class Vector4; +class Point3; +class Quat; +class Matrix3; +class Matrix4; +class Transform3; + +// A 3-D vector in array-of-structures format +// +class Vector3 +{ + float mX; + float mY; + float mZ; +#ifndef __GNUC__ + float d; +#endif + +public: + // Default constructor; does no initialization + // + inline Vector3( ) { }; + + // Copy a 3-D vector + // + inline Vector3( const Vector3 & vec ); + + // Construct a 3-D vector from x, y, and z elements + // + inline Vector3( float x, float y, float z ); + + // Copy elements from a 3-D point into a 3-D vector + // + explicit inline Vector3( const Point3 & pnt ); + + // Set all elements of a 3-D vector to the same scalar value + // + explicit inline Vector3( float scalar ); + + // Assign one 3-D vector to another + // + inline Vector3 & operator =( const Vector3 & vec ); + + // Set the x element of a 3-D vector + // + inline Vector3 & setX( float x ); + + // Set the y element of a 3-D vector + // + inline Vector3 & setY( float y ); + + // Set the z element of a 3-D vector + // + inline Vector3 & setZ( float z ); + + // Get the x element of a 3-D vector + // + inline float getX( ) const; + + // Get the y element of a 3-D vector + // + inline float getY( ) const; + + // Get the z element of a 3-D vector + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D vector by index + // + inline Vector3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 3-D vectors + // + inline const Vector3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from another 3-D vector + // + inline const Vector3 operator -( const Vector3 & vec ) const; + + // Add a 3-D vector to a 3-D point + // + inline const Point3 operator +( const Point3 & pnt ) const; + + // Multiply a 3-D vector by a scalar + // + inline const Vector3 operator *( float scalar ) const; + + // Divide a 3-D vector by a scalar + // + inline const Vector3 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Vector3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Vector3 & operator -=( const Vector3 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector3 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector3 & operator /=( float scalar ); + + // Negate all elements of a 3-D vector + // + inline const Vector3 operator -( ) const; + + // Construct x axis + // + static inline const Vector3 xAxis( ); + + // Construct y axis + // + static inline const Vector3 yAxis( ); + + // Construct z axis + // + static inline const Vector3 zAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 3-D vector by a scalar +// +inline const Vector3 operator *( float scalar, const Vector3 & vec ); + +// Multiply two 3-D vectors per element +// +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Divide two 3-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the reciprocal of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector3 recipPerElem( const Vector3 & vec ); + +// Compute the square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector3 sqrtPerElem( const Vector3 & vec ); + +// Compute the reciprocal square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector3 rsqrtPerElem( const Vector3 & vec ); + +// Compute the absolute value of a 3-D vector per element +// +inline const Vector3 absPerElem( const Vector3 & vec ); + +// Copy sign from one 3-D vector to another, per element +// +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum of two 3-D vectors per element +// +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Minimum of two 3-D vectors per element +// +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum element of a 3-D vector +// +inline float maxElem( const Vector3 & vec ); + +// Minimum element of a 3-D vector +// +inline float minElem( const Vector3 & vec ); + +// Compute the sum of all elements of a 3-D vector +// +inline float sum( const Vector3 & vec ); + +// Compute the dot product of two 3-D vectors +// +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the square of the length of a 3-D vector +// +inline float lengthSqr( const Vector3 & vec ); + +// Compute the length of a 3-D vector +// +inline float length( const Vector3 & vec ); + +// Normalize a 3-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector3 normalize( const Vector3 & vec ); + +// Compute cross product of two 3-D vectors +// +inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); + +// Outer product of two 3-D vectors +// +inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); + +// Pre-multiply a row vector by a 3x3 matrix +// +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); + +// Cross-product matrix of a 3-D vector +// +inline const Matrix3 crossMatrix( const Vector3 & vec ); + +// Create cross-product matrix and multiply +// NOTE: +// Faster than separately creating a cross-product matrix and multiplying. +// +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); + +// Linear interpolation between two 3-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ); + +// Spherical linear interpolation between two 3-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); + +// Conditionally select between two 3-D vectors +// +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Vector3 & vec, const float * fptr ); + +// Store x, y, and z elements of a 3-D vector in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Vector3 & vec, float * fptr ); + +// Load three-half-floats as a 3-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ); + +// Store a 3-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec ); + +// Print a 3-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec, const char * name ); + +#endif + +// A 4-D vector in array-of-structures format +// +class Vector4 +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Vector4( ) { }; + + // Copy a 4-D vector + // + inline Vector4( const Vector4 & vec ); + + // Construct a 4-D vector from x, y, z, and w elements + // + inline Vector4( float x, float y, float z, float w ); + + // Construct a 4-D vector from a 3-D vector and a scalar + // + inline Vector4( const Vector3 & xyz, float w ); + + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit inline Vector4( const Vector3 & vec ); + + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit inline Vector4( const Point3 & pnt ); + + // Copy elements from a quaternion into a 4-D vector + // + explicit inline Vector4( const Quat & quat ); + + // Set all elements of a 4-D vector to the same scalar value + // + explicit inline Vector4( float scalar ); + + // Assign one 4-D vector to another + // + inline Vector4 & operator =( const Vector4 & vec ); + + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + inline Vector4 & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a 4-D vector + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a 4-D vector + // + inline Vector4 & setX( float x ); + + // Set the y element of a 4-D vector + // + inline Vector4 & setY( float y ); + + // Set the z element of a 4-D vector + // + inline Vector4 & setZ( float z ); + + // Set the w element of a 4-D vector + // + inline Vector4 & setW( float w ); + + // Get the x element of a 4-D vector + // + inline float getX( ) const; + + // Get the y element of a 4-D vector + // + inline float getY( ) const; + + // Get the z element of a 4-D vector + // + inline float getZ( ) const; + + // Get the w element of a 4-D vector + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a 4-D vector by index + // + inline Vector4 & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a 4-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 4-D vectors + // + inline const Vector4 operator +( const Vector4 & vec ) const; + + // Subtract a 4-D vector from another 4-D vector + // + inline const Vector4 operator -( const Vector4 & vec ) const; + + // Multiply a 4-D vector by a scalar + // + inline const Vector4 operator *( float scalar ) const; + + // Divide a 4-D vector by a scalar + // + inline const Vector4 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 4-D vector + // + inline Vector4 & operator +=( const Vector4 & vec ); + + // Perform compound assignment and subtraction by a 4-D vector + // + inline Vector4 & operator -=( const Vector4 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector4 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector4 & operator /=( float scalar ); + + // Negate all elements of a 4-D vector + // + inline const Vector4 operator -( ) const; + + // Construct x axis + // + static inline const Vector4 xAxis( ); + + // Construct y axis + // + static inline const Vector4 yAxis( ); + + // Construct z axis + // + static inline const Vector4 zAxis( ); + + // Construct w axis + // + static inline const Vector4 wAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 4-D vector by a scalar +// +inline const Vector4 operator *( float scalar, const Vector4 & vec ); + +// Multiply two 4-D vectors per element +// +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Divide two 4-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the reciprocal of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector4 recipPerElem( const Vector4 & vec ); + +// Compute the square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector4 sqrtPerElem( const Vector4 & vec ); + +// Compute the reciprocal square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector4 rsqrtPerElem( const Vector4 & vec ); + +// Compute the absolute value of a 4-D vector per element +// +inline const Vector4 absPerElem( const Vector4 & vec ); + +// Copy sign from one 4-D vector to another, per element +// +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum of two 4-D vectors per element +// +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Minimum of two 4-D vectors per element +// +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum element of a 4-D vector +// +inline float maxElem( const Vector4 & vec ); + +// Minimum element of a 4-D vector +// +inline float minElem( const Vector4 & vec ); + +// Compute the sum of all elements of a 4-D vector +// +inline float sum( const Vector4 & vec ); + +// Compute the dot product of two 4-D vectors +// +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the square of the length of a 4-D vector +// +inline float lengthSqr( const Vector4 & vec ); + +// Compute the length of a 4-D vector +// +inline float length( const Vector4 & vec ); + +// Normalize a 4-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector4 normalize( const Vector4 & vec ); + +// Outer product of two 4-D vectors +// +inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); + +// Linear interpolation between two 4-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ); + +// Spherical linear interpolation between two 4-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); + +// Conditionally select between two 4-D vectors +// +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Vector4 & vec, const float * fptr ); + +// Store x, y, z, and w elements of a 4-D vector in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Vector4 & vec, float * fptr ); + +// Load four-half-floats as a 4-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ); + +// Store a 4-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec ); + +// Print a 4-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec, const char * name ); + +#endif + +// A 3-D point in array-of-structures format +// +class Point3 +{ + float mX; + float mY; + float mZ; +#ifndef __GNUC__ + float d; +#endif + +public: + // Default constructor; does no initialization + // + inline Point3( ) { }; + + // Copy a 3-D point + // + inline Point3( const Point3 & pnt ); + + // Construct a 3-D point from x, y, and z elements + // + inline Point3( float x, float y, float z ); + + // Copy elements from a 3-D vector into a 3-D point + // + explicit inline Point3( const Vector3 & vec ); + + // Set all elements of a 3-D point to the same scalar value + // + explicit inline Point3( float scalar ); + + // Assign one 3-D point to another + // + inline Point3 & operator =( const Point3 & pnt ); + + // Set the x element of a 3-D point + // + inline Point3 & setX( float x ); + + // Set the y element of a 3-D point + // + inline Point3 & setY( float y ); + + // Set the z element of a 3-D point + // + inline Point3 & setZ( float z ); + + // Get the x element of a 3-D point + // + inline float getX( ) const; + + // Get the y element of a 3-D point + // + inline float getY( ) const; + + // Get the z element of a 3-D point + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D point by index + // + inline Point3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D point by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Subtract a 3-D point from another 3-D point + // + inline const Vector3 operator -( const Point3 & pnt ) const; + + // Add a 3-D point to a 3-D vector + // + inline const Point3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from a 3-D point + // + inline const Point3 operator -( const Vector3 & vec ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Point3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Point3 & operator -=( const Vector3 & vec ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply two 3-D points per element +// +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Divide two 3-D points per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the reciprocal of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Point3 recipPerElem( const Point3 & pnt ); + +// Compute the square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Point3 sqrtPerElem( const Point3 & pnt ); + +// Compute the reciprocal square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Point3 rsqrtPerElem( const Point3 & pnt ); + +// Compute the absolute value of a 3-D point per element +// +inline const Point3 absPerElem( const Point3 & pnt ); + +// Copy sign from one 3-D point to another, per element +// +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum of two 3-D points per element +// +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Minimum of two 3-D points per element +// +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum element of a 3-D point +// +inline float maxElem( const Point3 & pnt ); + +// Minimum element of a 3-D point +// +inline float minElem( const Point3 & pnt ); + +// Compute the sum of all elements of a 3-D point +// +inline float sum( const Point3 & pnt ); + +// Apply uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, float scaleVal ); + +// Apply non-uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); + +// Scalar projection of a 3-D point on a unit-length 3-D vector +// +inline float projection( const Point3 & pnt, const Vector3 & unitVec ); + +// Compute the square of the distance of a 3-D point from the coordinate-system origin +// +inline float distSqrFromOrigin( const Point3 & pnt ); + +// Compute the distance of a 3-D point from the coordinate-system origin +// +inline float distFromOrigin( const Point3 & pnt ); + +// Compute the square of the distance between two 3-D points +// +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the distance between two 3-D points +// +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ); + +// Linear interpolation between two 3-D points +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ); + +// Conditionally select between two 3-D points +// +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Point3 & pnt, const float * fptr ); + +// Store x, y, and z elements of a 3-D point in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Point3 & pnt, float * fptr ); + +// Load three-half-floats as a 3-D point +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Point3 & pnt, const unsigned short * hfptr ); + +// Store a 3-D point as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Point3 & pnt, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D point +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt ); + +// Print a 3-D point and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt, const char * name ); + +#endif + +// A quaternion in array-of-structures format +// +class Quat +{ +#if defined( __APPLE__ ) && defined( BT_USE_NEON ) + union{ + float32x4_t vXYZW; + float mXYZW[4]; + }; +#else + float mX; + float mY; + float mZ; + float mW; +#endif + +public: + // Default constructor; does no initialization + // + inline Quat( ) { }; + + // Copy a quaternion + // + inline Quat( const Quat & quat ); + + // Construct a quaternion from x, y, z, and w elements + // + inline Quat( float x, float y, float z, float w ); + + // Construct a quaternion from vector of x, y, z, and w elements + // + inline Quat( float32x4_t fXYZW ); + + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat( const Vector3 & xyz, float w ); + + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat( const Vector4 & vec ); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat( const Matrix3 & rotMat ); + + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat( float scalar ); + + // Assign one quaternion to another + // + inline Quat & operator =( const Quat & quat ); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a quaternion + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a quaternion + // + inline Quat & setX( float x ); + + // Set the y element of a quaternion + // + inline Quat & setY( float y ); + + // Set the z element of a quaternion + // + inline Quat & setZ( float z ); + + // Set the w element of a quaternion + // + inline Quat & setW( float w ); + +#if defined( __APPLE__ ) && defined( BT_USE_NEON ) + inline float32x4_t getvXYZW( ) const; +#endif + + // Get the x element of a quaternion + // + inline float getX( ) const; + + // Get the y element of a quaternion + // + inline float getY( ) const; + + // Get the z element of a quaternion + // + inline float getZ( ) const; + + // Get the w element of a quaternion + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two quaternions + // + inline const Quat operator +( const Quat & quat ) const; + + // Subtract a quaternion from another quaternion + // + inline const Quat operator -( const Quat & quat ) const; + + // Multiply two quaternions + // + inline const Quat operator *( const Quat & quat ) const; + + // Multiply a quaternion by a scalar + // + inline const Quat operator *( float scalar ) const; + + // Divide a quaternion by a scalar + // + inline const Quat operator /( float scalar ) const; + + // Perform compound assignment and addition with a quaternion + // + inline Quat & operator +=( const Quat & quat ); + + // Perform compound assignment and subtraction by a quaternion + // + inline Quat & operator -=( const Quat & quat ); + + // Perform compound assignment and multiplication by a quaternion + // + inline Quat & operator *=( const Quat & quat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Quat & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Quat & operator /=( float scalar ); + + // Negate all elements of a quaternion + // + inline const Quat operator -( ) const; + + // Construct an identity quaternion + // + static inline const Quat identity( ); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat rotation( float radians, const Vector3 & unitVec ); + + // Construct a quaternion to rotate around the x axis + // + static inline const Quat rotationX( float radians ); + + // Construct a quaternion to rotate around the y axis + // + static inline const Quat rotationY( float radians ); + + // Construct a quaternion to rotate around the z axis + // + static inline const Quat rotationZ( float radians ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a quaternion by a scalar +// +inline const Quat operator *( float scalar, const Quat & quat ); + +// Compute the conjugate of a quaternion +// +inline const Quat conj( const Quat & quat ); + +// Use a unit-length quaternion to rotate a 3-D vector +// +inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); + +// Compute the dot product of two quaternions +// +inline float dot( const Quat & quat0, const Quat & quat1 ); + +// Compute the norm of a quaternion +// +inline float norm( const Quat & quat ); + +// Compute the length of a quaternion +// +inline float length( const Quat & quat ); + +// Normalize a quaternion +// NOTE: +// The result is unpredictable when all elements of quat are at or near zero. +// +inline const Quat normalize( const Quat & quat ); + +// Linear interpolation between two quaternions +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ); + +// Spherical linear interpolation between two quaternions +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ); + +// Spherical quadrangle interpolation +// +inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); + +// Conditionally select between two quaternions +// +inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Quat & quat, const float * fptr ); + +// Store x, y, z, and w elements of a quaternion in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Quat & quat, float * fptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a quaternion +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat ); + +// Print a quaternion and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat, const char * name ); + +#endif + +// A 3x3 matrix in array-of-structures format +// +class Matrix3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + +public: + // Default constructor; does no initialization + // + inline Matrix3( ) { }; + + // Copy a 3x3 matrix + // + inline Matrix3( const Matrix3 & mat ); + + // Construct a 3x3 matrix containing the specified columns + // + inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); + + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit inline Matrix3( const Quat & unitQuat ); + + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit inline Matrix3( float scalar ); + + // Assign one 3x3 matrix to another + // + inline Matrix3 & operator =( const Matrix3 & mat ); + + // Set column 0 of a 3x3 matrix + // + inline Matrix3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x3 matrix + // + inline Matrix3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x3 matrix + // + inline Matrix3 & setCol2( const Vector3 & col2 ); + + // Get column 0 of a 3x3 matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x3 matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x3 matrix + // + inline const Vector3 getCol2( ) const; + + // Set the column of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setRow( int row, const Vector3 & vec ); + + // Get the column of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x3 matrix referred to by column and row indices + // + inline Matrix3 & setElem( int col, int row, float val ); + + // Get the element of a 3x3 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 3x3 matrices + // + inline const Matrix3 operator +( const Matrix3 & mat ) const; + + // Subtract a 3x3 matrix from another 3x3 matrix + // + inline const Matrix3 operator -( const Matrix3 & mat ) const; + + // Negate all elements of a 3x3 matrix + // + inline const Matrix3 operator -( ) const; + + // Multiply a 3x3 matrix by a scalar + // + inline const Matrix3 operator *( float scalar ) const; + + // Multiply a 3x3 matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply two 3x3 matrices + // + inline const Matrix3 operator *( const Matrix3 & mat ) const; + + // Perform compound assignment and addition with a 3x3 matrix + // + inline Matrix3 & operator +=( const Matrix3 & mat ); + + // Perform compound assignment and subtraction by a 3x3 matrix + // + inline Matrix3 & operator -=( const Matrix3 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix3 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 3x3 matrix + // + inline Matrix3 & operator *=( const Matrix3 & mat ); + + // Construct an identity 3x3 matrix + // + static inline const Matrix3 identity( ); + + // Construct a 3x3 matrix to rotate around the x axis + // + static inline const Matrix3 rotationX( float radians ); + + // Construct a 3x3 matrix to rotate around the y axis + // + static inline const Matrix3 rotationY( float radians ); + + // Construct a 3x3 matrix to rotate around the z axis + // + static inline const Matrix3 rotationZ( float radians ); + + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix3 rotation( const Quat & unitQuat ); + + // Construct a 3x3 matrix to perform scaling + // + static inline const Matrix3 scale( const Vector3 & scaleVec ); + +}; +// Multiply a 3x3 matrix by a scalar +// +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); + +// Append (post-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); + +// Multiply two 3x3 matrices per element +// +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); + +// Compute the absolute value of a 3x3 matrix per element +// +inline const Matrix3 absPerElem( const Matrix3 & mat ); + +// Transpose of a 3x3 matrix +// +inline const Matrix3 transpose( const Matrix3 & mat ); + +// Compute the inverse of a 3x3 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix3 inverse( const Matrix3 & mat ); + +// Determinant of a 3x3 matrix +// +inline float determinant( const Matrix3 & mat ); + +// Conditionally select between two 3x3 matrices +// +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x3 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat ); + +// Print a 3x3 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat, const char * name ); + +#endif + +// A 4x4 matrix in array-of-structures format +// +class Matrix4 +{ + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; + +public: + // Default constructor; does no initialization + // + inline Matrix4( ) { }; + + // Copy a 4x4 matrix + // + inline Matrix4( const Matrix4 & mat ); + + // Construct a 4x4 matrix containing the specified columns + // + inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); + + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit inline Matrix4( const Transform3 & mat ); + + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); + + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit inline Matrix4( float scalar ); + + // Assign one 4x4 matrix to another + // + inline Matrix4 & operator =( const Matrix4 & mat ); + + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 4x4 matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 4x4 matrix + // + inline Matrix4 & setCol0( const Vector4 & col0 ); + + // Set column 1 of a 4x4 matrix + // + inline Matrix4 & setCol1( const Vector4 & col1 ); + + // Set column 2 of a 4x4 matrix + // + inline Matrix4 & setCol2( const Vector4 & col2 ); + + // Set column 3 of a 4x4 matrix + // + inline Matrix4 & setCol3( const Vector4 & col3 ); + + // Get column 0 of a 4x4 matrix + // + inline const Vector4 getCol0( ) const; + + // Get column 1 of a 4x4 matrix + // + inline const Vector4 getCol1( ) const; + + // Get column 2 of a 4x4 matrix + // + inline const Vector4 getCol2( ) const; + + // Get column 3 of a 4x4 matrix + // + inline const Vector4 getCol3( ) const; + + // Set the column of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setCol( int col, const Vector4 & vec ); + + // Set the row of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getCol( int col ) const; + + // Get the row of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector4 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector4 operator []( int col ) const; + + // Set the element of a 4x4 matrix referred to by column and row indices + // + inline Matrix4 & setElem( int col, int row, float val ); + + // Get the element of a 4x4 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 4x4 matrices + // + inline const Matrix4 operator +( const Matrix4 & mat ) const; + + // Subtract a 4x4 matrix from another 4x4 matrix + // + inline const Matrix4 operator -( const Matrix4 & mat ) const; + + // Negate all elements of a 4x4 matrix + // + inline const Matrix4 operator -( ) const; + + // Multiply a 4x4 matrix by a scalar + // + inline const Matrix4 operator *( float scalar ) const; + + // Multiply a 4x4 matrix by a 4-D vector + // + inline const Vector4 operator *( const Vector4 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D vector + // + inline const Vector4 operator *( const Vector3 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D point + // + inline const Vector4 operator *( const Point3 & pnt ) const; + + // Multiply two 4x4 matrices + // + inline const Matrix4 operator *( const Matrix4 & mat ) const; + + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + inline const Matrix4 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and addition with a 4x4 matrix + // + inline Matrix4 & operator +=( const Matrix4 & mat ); + + // Perform compound assignment and subtraction by a 4x4 matrix + // + inline Matrix4 & operator -=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix4 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 4x4 matrix + // + inline Matrix4 & operator *=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Matrix4 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 4x4 matrix + // + static inline const Matrix4 identity( ); + + // Construct a 4x4 matrix to rotate around the x axis + // + static inline const Matrix4 rotationX( float radians ); + + // Construct a 4x4 matrix to rotate around the y axis + // + static inline const Matrix4 rotationY( float radians ); + + // Construct a 4x4 matrix to rotate around the z axis + // + static inline const Matrix4 rotationZ( float radians ); + + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix4 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix4 rotation( const Quat & unitQuat ); + + // Construct a 4x4 matrix to perform scaling + // + static inline const Matrix4 scale( const Vector3 & scaleVec ); + + // Construct a 4x4 matrix to perform translation + // + static inline const Matrix4 translation( const Vector3 & translateVec ); + + // Construct viewing matrix based on eye position, position looked at, and up direction + // + static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); + + // Construct a perspective projection matrix + // + static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + + // Construct a perspective projection matrix based on frustum + // + static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); + + // Construct an orthographic projection matrix + // + static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + +}; +// Multiply a 4x4 matrix by a scalar +// +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); + +// Append (post-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); + +// Multiply two 4x4 matrices per element +// +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); + +// Compute the absolute value of a 4x4 matrix per element +// +inline const Matrix4 absPerElem( const Matrix4 & mat ); + +// Transpose of a 4x4 matrix +// +inline const Matrix4 transpose( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 inverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 affineInverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. +// +inline const Matrix4 orthoInverse( const Matrix4 & mat ); + +// Determinant of a 4x4 matrix +// +inline float determinant( const Matrix4 & mat ); + +// Conditionally select between two 4x4 matrices +// +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4x4 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat ); + +// Print a 4x4 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat, const char * name ); + +#endif + +// A 3x4 transformation matrix in array-of-structures format +// +class Transform3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; + +public: + // Default constructor; does no initialization + // + inline Transform3( ) { }; + + // Copy a 3x4 transformation matrix + // + inline Transform3( const Transform3 & tfrm ); + + // Construct a 3x4 transformation matrix containing the specified columns + // + inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); + + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); + + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit inline Transform3( float scalar ); + + // Assign one 3x4 transformation matrix to another + // + inline Transform3 & operator =( const Transform3 & tfrm ); + + // Set the upper-left 3x3 submatrix + // + inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // + inline Transform3 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 3x4 transformation matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 3x4 transformation matrix + // + inline Transform3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x4 transformation matrix + // + inline Transform3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x4 transformation matrix + // + inline Transform3 & setCol2( const Vector3 & col2 ); + + // Set column 3 of a 3x4 transformation matrix + // + inline Transform3 & setCol3( const Vector3 & col3 ); + + // Get column 0 of a 3x4 transformation matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x4 transformation matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x4 transformation matrix + // + inline const Vector3 getCol2( ) const; + + // Get column 3 of a 3x4 transformation matrix + // + inline const Vector3 getCol3( ) const; + + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + inline Transform3 & setElem( int col, int row, float val ); + + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Multiply a 3x4 transformation matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply a 3x4 transformation matrix by a 3-D point + // + inline const Point3 operator *( const Point3 & pnt ) const; + + // Multiply two 3x4 transformation matrices + // + inline const Transform3 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Transform3 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 3x4 transformation matrix + // + static inline const Transform3 identity( ); + + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static inline const Transform3 rotationX( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static inline const Transform3 rotationY( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static inline const Transform3 rotationZ( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static inline const Transform3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Transform3 rotation( const Quat & unitQuat ); + + // Construct a 3x4 transformation matrix to perform scaling + // + static inline const Transform3 scale( const Vector3 & scaleVec ); + + // Construct a 3x4 transformation matrix to perform translation + // + static inline const Transform3 translation( const Vector3 & translateVec ); + +}; +// Append (post-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); + +// Multiply two 3x4 transformation matrices per element +// +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); + +// Compute the absolute value of a 3x4 transformation matrix per element +// +inline const Transform3 absPerElem( const Transform3 & tfrm ); + +// Inverse of a 3x4 transformation matrix +// NOTE: +// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. +// +inline const Transform3 inverse( const Transform3 & tfrm ); + +// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. +// +inline const Transform3 orthoInverse( const Transform3 & tfrm ); + +// Conditionally select between two 3x4 transformation matrices +// +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x4 transformation matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm ); + +// Print a 3x4 transformation matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm, const char * name ); + +#endif + +} // namespace Aos +} // namespace Vectormath + +#include "vec_aos.h" +#include "quat_aos.h" +#include "mat_aos.h" + +#endif + diff --git a/src/vectormath/scalar/boolInVec.h b/src/vectormath/scalar/boolInVec.h new file mode 100644 index 0000000..c5eeeeb --- /dev/null +++ b/src/vectormath/scalar/boolInVec.h @@ -0,0 +1,225 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _BOOLINVEC_H +#define _BOOLINVEC_H + +#include +namespace Vectormath { + +class floatInVec; + +//-------------------------------------------------------------------------------------------------- +// boolInVec class +// + +class boolInVec +{ +private: + unsigned int mData; + +public: + // Default constructor; does no initialization + // + inline boolInVec( ) { }; + + // Construct from a value converted from float + // + inline boolInVec(floatInVec vec); + + // Explicit cast from bool + // + explicit inline boolInVec(bool scalar); + + // Explicit cast to bool + // + inline bool getAsBool() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to bool + // + inline operator bool() const; +#endif + + // Boolean negation operator + // + inline const boolInVec operator ! () const; + + // Assignment operator + // + inline boolInVec& operator = (boolInVec vec); + + // Boolean and assignment operator + // + inline boolInVec& operator &= (boolInVec vec); + + // Boolean exclusive or assignment operator + // + inline boolInVec& operator ^= (boolInVec vec); + + // Boolean or assignment operator + // + inline boolInVec& operator |= (boolInVec vec); + +}; + +// Equal operator +// +inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); + +// And operator +// +inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); + +// Exclusive or operator +// +inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); + +// Or operator +// +inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); + +// Conditionally select between two values +// +inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// boolInVec implementation +// + +#include "floatInVec.h" + +namespace Vectormath { + +inline +boolInVec::boolInVec(floatInVec vec) +{ + *this = (vec != floatInVec(0.0f)); +} + +inline +boolInVec::boolInVec(bool scalar) +{ + mData = -(int)scalar; +} + +inline +bool +boolInVec::getAsBool() const +{ + return (mData > 0); +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +boolInVec::operator bool() const +{ + return getAsBool(); +} +#endif + +inline +const boolInVec +boolInVec::operator ! () const +{ + return boolInVec(!mData); +} + +inline +boolInVec& +boolInVec::operator = (boolInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +boolInVec& +boolInVec::operator &= (boolInVec vec) +{ + *this = *this & vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator ^= (boolInVec vec) +{ + *this = *this ^ vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator |= (boolInVec vec) +{ + *this = *this | vec; + return *this; +} + +inline +const boolInVec +operator == (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() == vec1.getAsBool()); +} + +inline +const boolInVec +operator != (boolInVec vec0, boolInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const boolInVec +operator & (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() & vec1.getAsBool()); +} + +inline +const boolInVec +operator | (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() | vec1.getAsBool()); +} + +inline +const boolInVec +operator ^ (boolInVec vec0, boolInVec vec1) +{ + return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); +} + +inline +const boolInVec +select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // boolInVec_h diff --git a/src/vectormath/scalar/floatInVec.h b/src/vectormath/scalar/floatInVec.h new file mode 100644 index 0000000..12d89e4 --- /dev/null +++ b/src/vectormath/scalar/floatInVec.h @@ -0,0 +1,343 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ +#ifndef _FLOATINVEC_H +#define _FLOATINVEC_H + +#include +namespace Vectormath { + +class boolInVec; + +//-------------------------------------------------------------------------------------------------- +// floatInVec class +// + +// A class representing a scalar float value contained in a vector register +// This class does not support fastmath +class floatInVec +{ +private: + float mData; + +public: + // Default constructor; does no initialization + // + inline floatInVec( ) { }; + + // Construct from a value converted from bool + // + inline floatInVec(boolInVec vec); + + // Explicit cast from float + // + explicit inline floatInVec(float scalar); + + // Explicit cast to float + // + inline float getAsFloat() const; + +#ifndef _VECTORMATH_NO_SCALAR_CAST + // Implicit cast to float + // + inline operator float() const; +#endif + + // Post increment (add 1.0f) + // + inline const floatInVec operator ++ (int); + + // Post decrement (subtract 1.0f) + // + inline const floatInVec operator -- (int); + + // Pre increment (add 1.0f) + // + inline floatInVec& operator ++ (); + + // Pre decrement (subtract 1.0f) + // + inline floatInVec& operator -- (); + + // Negation operator + // + inline const floatInVec operator - () const; + + // Assignment operator + // + inline floatInVec& operator = (floatInVec vec); + + // Multiplication assignment operator + // + inline floatInVec& operator *= (floatInVec vec); + + // Division assignment operator + // + inline floatInVec& operator /= (floatInVec vec); + + // Addition assignment operator + // + inline floatInVec& operator += (floatInVec vec); + + // Subtraction assignment operator + // + inline floatInVec& operator -= (floatInVec vec); + +}; + +// Multiplication operator +// +inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); + +// Division operator +// +inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); + +// Addition operator +// +inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); + +// Subtraction operator +// +inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); + +// Less than operator +// +inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); + +// Less than or equal operator +// +inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); + +// Greater than operator +// +inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); + +// Greater than or equal operator +// +inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); + +// Equal operator +// +inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); + +// Not equal operator +// +inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); + +// Conditionally select between two values +// +inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); + + +} // namespace Vectormath + + +//-------------------------------------------------------------------------------------------------- +// floatInVec implementation +// + +#include "boolInVec.h" + +namespace Vectormath { + +inline +floatInVec::floatInVec(boolInVec vec) +{ + mData = float(vec.getAsBool()); +} + +inline +floatInVec::floatInVec(float scalar) +{ + mData = scalar; +} + +inline +float +floatInVec::getAsFloat() const +{ + return mData; +} + +#ifndef _VECTORMATH_NO_SCALAR_CAST +inline +floatInVec::operator float() const +{ + return getAsFloat(); +} +#endif + +inline +const floatInVec +floatInVec::operator ++ (int) +{ + float olddata = mData; + operator ++(); + return floatInVec(olddata); +} + +inline +const floatInVec +floatInVec::operator -- (int) +{ + float olddata = mData; + operator --(); + return floatInVec(olddata); +} + +inline +floatInVec& +floatInVec::operator ++ () +{ + *this += floatInVec(1.0f); + return *this; +} + +inline +floatInVec& +floatInVec::operator -- () +{ + *this -= floatInVec(1.0f); + return *this; +} + +inline +const floatInVec +floatInVec::operator - () const +{ + return floatInVec(-mData); +} + +inline +floatInVec& +floatInVec::operator = (floatInVec vec) +{ + mData = vec.mData; + return *this; +} + +inline +floatInVec& +floatInVec::operator *= (floatInVec vec) +{ + *this = *this * vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator /= (floatInVec vec) +{ + *this = *this / vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator += (floatInVec vec) +{ + *this = *this + vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator -= (floatInVec vec) +{ + *this = *this - vec; + return *this; +} + +inline +const floatInVec +operator * (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); +} + +inline +const floatInVec +operator / (floatInVec num, floatInVec den) +{ + return floatInVec(num.getAsFloat() / den.getAsFloat()); +} + +inline +const floatInVec +operator + (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); +} + +inline +const floatInVec +operator - (floatInVec vec0, floatInVec vec1) +{ + return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); +} + +inline +const boolInVec +operator < (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); +} + +inline +const boolInVec +operator <= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 > vec1); +} + +inline +const boolInVec +operator > (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); +} + +inline +const boolInVec +operator >= (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 < vec1); +} + +inline +const boolInVec +operator == (floatInVec vec0, floatInVec vec1) +{ + return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); +} + +inline +const boolInVec +operator != (floatInVec vec0, floatInVec vec1) +{ + return !(vec0 == vec1); +} + +inline +const floatInVec +select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) +{ + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; +} + +} // namespace Vectormath + +#endif // floatInVec_h diff --git a/src/vectormath/scalar/mat_aos.h b/src/vectormath/scalar/mat_aos.h new file mode 100644 index 0000000..e103243 --- /dev/null +++ b/src/vectormath/scalar/mat_aos.h @@ -0,0 +1,1630 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _VECTORMATH_MAT_AOS_CPP_H +#define _VECTORMATH_MAT_AOS_CPP_H + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_PI_OVER_2 1.570796327f + +//----------------------------------------------------------------------------- +// Definitions + +inline Matrix3::Matrix3( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; +} + +inline Matrix3::Matrix3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +inline Matrix3::Matrix3( const Quat & unitQuat ) +{ + float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; + qx = unitQuat.getX(); + qy = unitQuat.getY(); + qz = unitQuat.getZ(); + qw = unitQuat.getW(); + qx2 = ( qx + qx ); + qy2 = ( qy + qy ); + qz2 = ( qz + qz ); + qxqx2 = ( qx * qx2 ); + qxqy2 = ( qx * qy2 ); + qxqz2 = ( qx * qz2 ); + qxqw2 = ( qw * qx2 ); + qyqy2 = ( qy * qy2 ); + qyqz2 = ( qy * qz2 ); + qyqw2 = ( qw * qy2 ); + qzqz2 = ( qz * qz2 ); + qzqw2 = ( qw * qz2 ); + mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); + mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); + mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); +} + +inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; +} + +inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + return *this; +} + +inline Matrix3 & Matrix3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Matrix3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Matrix3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Matrix3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Matrix3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::getRow( int row ) const +{ + return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); +} + +inline Vector3 & Matrix3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Matrix3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; +} + +inline const Matrix3 transpose( const Matrix3 & mat ) +{ + return Matrix3( + Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), + Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), + Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) + ); +} + +inline const Matrix3 inverse( const Matrix3 & mat ) +{ + Vector3 tmp0, tmp1, tmp2; + float detinv; + tmp0 = cross( mat.getCol1(), mat.getCol2() ); + tmp1 = cross( mat.getCol2(), mat.getCol0() ); + tmp2 = cross( mat.getCol0(), mat.getCol1() ); + detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) ); + return Matrix3( + Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ), + Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ), + Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ) + ); +} + +inline float determinant( const Matrix3 & mat ) +{ + return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); +} + +inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ) + ); +} + +inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ) + ); +} + +inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix3 Matrix3::operator -( ) const +{ + return Matrix3( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ) + ); +} + +inline const Matrix3 absPerElem( const Matrix3 & mat ) +{ + return Matrix3( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::operator *( float scalar ) const +{ + return Matrix3( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ) + ); +} + +inline Matrix3 & Matrix3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) +{ + return mat * scalar; +} + +inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const +{ + return Vector3( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ); +} + +inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +{ + return Matrix3( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ) + ); +} + +inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +{ + *this = *this * mat; + return *this; +} + +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +{ + return Matrix3( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ) + ); +} + +inline const Matrix3 Matrix3::identity( ) +{ + return Matrix3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ) + ); +} + +inline const Matrix3 Matrix3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ) + ); +} + +inline const Matrix3 Matrix3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ) + ); +} + +inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix3( + Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ), + Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ), + Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ) + ); +} + +inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) +{ + return Matrix3( unitQuat ); +} + +inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) +{ + return Matrix3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ) + ); +} + +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) +{ + return Matrix3( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ) + ); +} + +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) +{ + return Matrix3( + mulPerElem( mat.getCol0(), scaleVec ), + mulPerElem( mat.getCol1(), scaleVec ), + mulPerElem( mat.getCol2(), scaleVec ) + ); +} + +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix3 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); +} + +inline void print( const Matrix3 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Matrix4::Matrix4( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; +} + +inline Matrix4::Matrix4( float scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +inline Matrix4::Matrix4( const Transform3 & mat ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( mat.getCol3(), 1.0f ); +} + +inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) +{ + Matrix3 mat; + mat = Matrix3( unitQuat ); + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Matrix4 & Matrix4::setElem( int col, int row, float val ) +{ + Vector4 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Matrix4::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector4 Matrix4::getCol0( ) const +{ + return mCol0; +} + +inline const Vector4 Matrix4::getCol1( ) const +{ + return mCol1; +} + +inline const Vector4 Matrix4::getCol2( ) const +{ + return mCol2; +} + +inline const Vector4 Matrix4::getCol3( ) const +{ + return mCol3; +} + +inline const Vector4 Matrix4::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector4 & Matrix4::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector4 Matrix4::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; +} + +inline const Matrix4 transpose( const Matrix4 & mat ) +{ + return Matrix4( + Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), + Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), + Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), + Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) + ); +} + +inline const Matrix4 inverse( const Matrix4 & mat ) +{ + Vector4 res0, res1, res2, res3; + float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); + res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); + res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); + res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); + detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) ); + res1.setX( ( mI * tmp1 ) ); + res1.setY( ( mM * tmp0 ) ); + res1.setZ( ( mA * tmp1 ) ); + res1.setW( ( mE * tmp0 ) ); + res3.setX( ( mI * tmp3 ) ); + res3.setY( ( mM * tmp2 ) ); + res3.setZ( ( mA * tmp3 ) ); + res3.setW( ( mE * tmp2 ) ); + res2.setX( ( mI * tmp5 ) ); + res2.setY( ( mM * tmp4 ) ); + res2.setZ( ( mA * tmp5 ) ); + res2.setW( ( mE * tmp4 ) ); + tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); + tmp1 = ( ( mM * mF ) - ( mE * mN ) ); + tmp2 = ( ( mI * mD ) - ( mA * mL ) ); + tmp3 = ( ( mM * mH ) - ( mE * mP ) ); + tmp4 = ( ( mI * mC ) - ( mA * mK ) ); + tmp5 = ( ( mM * mG ) - ( mE * mO ) ); + res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) ); + res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) ); + res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) ); + res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) ); + res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) ); + res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) ); + res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) ); + res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) ); + res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) ); + res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) ); + res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) ); + res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) ); + return Matrix4( + ( res0 * detInv ), + ( res1 * detInv ), + ( res2 * detInv ), + ( res3 * detInv ) + ); +} + +inline const Matrix4 affineInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( inverse( affineMat ) ); +} + +inline const Matrix4 orthoInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( orthoInverse( affineMat ) ); +} + +inline float determinant( const Matrix4 & mat ) +{ + float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ( ( mK * mD ) - ( mC * mL ) ); + tmp1 = ( ( mO * mH ) - ( mG * mP ) ); + tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); + tmp3 = ( ( mF * mO ) - ( mN * mG ) ); + tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); + tmp5 = ( ( mN * mH ) - ( mF * mP ) ); + dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); + dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); + dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); + dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); + return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); +} + +inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ), + ( mCol3 + mat.mCol3 ) + ); +} + +inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ), + ( mCol3 - mat.mCol3 ) + ); +} + +inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +{ + *this = *this + mat; + return *this; +} + +inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +{ + *this = *this - mat; + return *this; +} + +inline const Matrix4 Matrix4::operator -( ) const +{ + return Matrix4( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ), + ( -mCol3 ) + ); +} + +inline const Matrix4 absPerElem( const Matrix4 & mat ) +{ + return Matrix4( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ), + absPerElem( mat.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::operator *( float scalar ) const +{ + return Matrix4( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ), + ( mCol3 * scalar ) + ); +} + +inline Matrix4 & Matrix4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) +{ + return mat * scalar; +} + +inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), + ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), + ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), + ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const +{ + return Vector4( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ), + ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ); +} + +inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const +{ + return Vector4( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ), + ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() ) + ); +} + +inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +{ + return Matrix4( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ), + ( *this * mat.mCol3 ) + ); +} + +inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +{ + *this = *this * mat; + return *this; +} + +inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +{ + return Matrix4( + ( *this * tfrm.getCol0() ), + ( *this * tfrm.getCol1() ), + ( *this * tfrm.getCol2() ), + ( *this * Point3( tfrm.getCol3() ) ) + ); +} + +inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +{ + return Matrix4( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ), + mulPerElem( mat0.getCol3(), mat1.getCol3() ) + ); +} + +inline const Matrix4 Matrix4::identity( ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +{ + mCol0.setXYZ( mat3.getCol0() ); + mCol1.setXYZ( mat3.getCol1() ); + mCol2.setXYZ( mat3.getCol2() ); + return *this; +} + +inline const Matrix3 Matrix4::getUpper3x3( ) const +{ + return Matrix3( + mCol0.getXYZ( ), + mCol1.getXYZ( ), + mCol2.getXYZ( ) + ); +} + +inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) +{ + mCol3.setXYZ( translateVec ); + return *this; +} + +inline const Vector3 Matrix4::getTranslation( ) const +{ + return mCol3.getXYZ( ); +} + +inline const Matrix4 Matrix4::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4::xAxis( ), + Vector4( 0.0f, c, s, 0.0f ), + Vector4( 0.0f, -s, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, 0.0f, -s, 0.0f ), + Vector4::yAxis( ), + Vector4( s, 0.0f, c, 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Matrix4( + Vector4( c, s, 0.0f, 0.0f ), + Vector4( -s, c, 0.0f, 0.0f ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Matrix4( + Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ), + Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ), + Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec ) +{ + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf( radians ); + c = cosf( radians ); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = ( x * y ); + yz = ( y * z ); + zx = ( z * x ); + oneMinusC = ( 1.0f - c ); + return Matrix4( + Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ), + Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ), + Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) +{ + return Matrix4( Transform3::rotation( unitQuat ) ); +} + +inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) +{ + return Matrix4( + Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ), + Vector4::wAxis( ) + ); +} + +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) +{ + return Matrix4( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ), + mat.getCol3() + ); +} + +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) +{ + Vector4 scale4; + scale4 = Vector4( scaleVec, 1.0f ); + return Matrix4( + mulPerElem( mat.getCol0(), scale4 ), + mulPerElem( mat.getCol1(), scale4 ), + mulPerElem( mat.getCol2(), scale4 ), + mulPerElem( mat.getCol3(), scale4 ) + ); +} + +inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4( translateVec, 1.0f ) + ); +} + +inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) +{ + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize( upVec ); + v3Z = normalize( ( eyePos - lookAtPos ) ); + v3X = normalize( cross( v3Y, v3Z ) ); + v3Y = cross( v3Z, v3X ); + m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); + return orthoInverse( m4EyeFrame ); +} + +inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +{ + float f, rangeInv; + f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); + rangeInv = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, f, 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + n2 = ( zNear + zNear ); + return Matrix4( + Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ), + Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ), + Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ) + ); +} + +inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; + sum_rl = ( right + left ); + sum_tb = ( top + bottom ); + sum_nf = ( zNear + zFar ); + inv_rl = ( 1.0f / ( right - left ) ); + inv_tb = ( 1.0f / ( top - bottom ) ); + inv_nf = ( 1.0f / ( zNear - zFar ) ); + return Matrix4( + Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ), + Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ), + Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ), + Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ) + ); +} + +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Matrix4 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); + print( mat.getRow( 3 ) ); +} + +inline void print( const Matrix4 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +inline Transform3::Transform3( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; +} + +inline Transform3::Transform3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) +{ + this->setUpper3x3( tfrm ); + this->setTranslation( translateVec ); +} + +inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) +{ + this->setUpper3x3( Matrix3( unitQuat ) ); + this->setTranslation( translateVec ); +} + +inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) +{ + mCol0 = _col0; + return *this; +} + +inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) +{ + mCol1 = _col1; + return *this; +} + +inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) +{ + mCol2 = _col2; + return *this; +} + +inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) +{ + mCol3 = _col3; + return *this; +} + +inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +inline Transform3 & Transform3::setElem( int col, int row, float val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +inline float Transform3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +inline const Vector3 Transform3::getCol0( ) const +{ + return mCol0; +} + +inline const Vector3 Transform3::getCol1( ) const +{ + return mCol1; +} + +inline const Vector3 Transform3::getCol2( ) const +{ + return mCol2; +} + +inline const Vector3 Transform3::getCol3( ) const +{ + return mCol3; +} + +inline const Vector3 Transform3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +inline const Vector4 Transform3::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +inline Vector3 & Transform3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +inline const Vector3 Transform3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; +} + +inline const Transform3 inverse( const Transform3 & tfrm ) +{ + Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; + float detinv; + tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); + tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); + tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); + detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) ); + inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ); + inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ); + inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ); + return Transform3( + inv0, + inv1, + inv2, + Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) + ); +} + +inline const Transform3 orthoInverse( const Transform3 & tfrm ) +{ + Vector3 inv0, inv1, inv2; + inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); + inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); + inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); + return Transform3( + inv0, + inv1, + inv2, + Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) + ); +} + +inline const Transform3 absPerElem( const Transform3 & tfrm ) +{ + return Transform3( + absPerElem( tfrm.getCol0() ), + absPerElem( tfrm.getCol1() ), + absPerElem( tfrm.getCol2() ), + absPerElem( tfrm.getCol3() ) + ); +} + +inline const Vector3 Transform3::operator *( const Vector3 & vec ) const +{ + return Vector3( + ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), + ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), + ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ); +} + +inline const Point3 Transform3::operator *( const Point3 & pnt ) const +{ + return Point3( + ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), + ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), + ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ) + ); +} + +inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +{ + return Transform3( + ( *this * tfrm.mCol0 ), + ( *this * tfrm.mCol1 ), + ( *this * tfrm.mCol2 ), + Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) + ); +} + +inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +{ + return Transform3( + mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), + mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), + mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), + mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) + ); +} + +inline const Transform3 Transform3::identity( ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +{ + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; +} + +inline const Matrix3 Transform3::getUpper3x3( ) const +{ + return Matrix3( mCol0, mCol1, mCol2 ); +} + +inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) +{ + mCol3 = translateVec; + return *this; +} + +inline const Vector3 Transform3::getTranslation( ) const +{ + return mCol3; +} + +inline const Transform3 Transform3::rotationX( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3::xAxis( ), + Vector3( 0.0f, c, s ), + Vector3( 0.0f, -s, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationY( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, 0.0f, -s ), + Vector3::yAxis( ), + Vector3( s, 0.0f, c ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZ( float radians ) +{ + float s, c; + s = sinf( radians ); + c = cosf( radians ); + return Transform3( + Vector3( c, s, 0.0f ), + Vector3( -s, c, 0.0f ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) +{ + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf( radiansXYZ.getX() ); + cX = cosf( radiansXYZ.getX() ); + sY = sinf( radiansXYZ.getY() ); + cY = cosf( radiansXYZ.getY() ); + sZ = sinf( radiansXYZ.getZ() ); + cZ = cosf( radiansXYZ.getZ() ); + tmp0 = ( cZ * sY ); + tmp1 = ( sZ * sY ); + return Transform3( + Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), + Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), + Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec ) +{ + return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::rotation( const Quat & unitQuat ) +{ + return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); +} + +inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) +{ + return Transform3( + Vector3( scaleVec.getX(), 0.0f, 0.0f ), + Vector3( 0.0f, scaleVec.getY(), 0.0f ), + Vector3( 0.0f, 0.0f, scaleVec.getZ() ), + Vector3( 0.0f ) + ); +} + +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) +{ + return Transform3( + ( tfrm.getCol0() * scaleVec.getX( ) ), + ( tfrm.getCol1() * scaleVec.getY( ) ), + ( tfrm.getCol2() * scaleVec.getZ( ) ), + tfrm.getCol3() + ); +} + +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) +{ + return Transform3( + mulPerElem( tfrm.getCol0(), scaleVec ), + mulPerElem( tfrm.getCol1(), scaleVec ), + mulPerElem( tfrm.getCol2(), scaleVec ), + mulPerElem( tfrm.getCol3(), scaleVec ) + ); +} + +inline const Transform3 Transform3::translation( const Vector3 & translateVec ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + translateVec + ); +} + +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Transform3 & tfrm ) +{ + print( tfrm.getRow( 0 ) ); + print( tfrm.getRow( 1 ) ); + print( tfrm.getRow( 2 ) ); +} + +inline void print( const Transform3 & tfrm, const char * name ) +{ + printf("%s:\n", name); + print( tfrm ); +} + +#endif + +inline Quat::Quat( const Matrix3 & tfrm ) +{ + float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; + int negTrace, ZgtX, ZgtY, YgtX; + int largestXorY, largestYorZ, largestZorX; + + xx = tfrm.getCol0().getX(); + yx = tfrm.getCol0().getY(); + zx = tfrm.getCol0().getZ(); + xy = tfrm.getCol1().getX(); + yy = tfrm.getCol1().getY(); + zy = tfrm.getCol1().getZ(); + xz = tfrm.getCol2().getX(); + yz = tfrm.getCol2().getY(); + zz = tfrm.getCol2().getZ(); + + trace = ( ( xx + yy ) + zz ); + + negTrace = ( trace < 0.0f ); + ZgtX = zz > xx; + ZgtY = zz > yy; + YgtX = yy > xx; + largestXorY = ( !ZgtX || !ZgtY ) && negTrace; + largestYorZ = ( YgtX || ZgtX ) && negTrace; + largestZorX = ( ZgtY || !YgtX ) && negTrace; + + if ( largestXorY ) + { + zz = -zz; + xy = -xy; + } + if ( largestYorZ ) + { + xx = -xx; + yz = -yz; + } + if ( largestZorX ) + { + yy = -yy; + zx = -zx; + } + + radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); + scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); + + tmpx = ( ( zy - yz ) * scale ); + tmpy = ( ( xz - zx ) * scale ); + tmpz = ( ( yx - xy ) * scale ); + tmpw = ( radicand * scale ); + qx = tmpx; + qy = tmpy; + qz = tmpz; + qw = tmpw; + + if ( largestXorY ) + { + qx = tmpw; + qy = tmpz; + qz = tmpy; + qw = tmpx; + } + if ( largestYorZ ) + { + tmpx = qx; + tmpz = qz; + qx = qy; + qy = tmpx; + qz = qw; + qw = tmpz; + } + + mX = qx; + mY = qy; + mZ = qz; + mW = qw; +} + +inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) +{ + return Matrix3( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ) + ); +} + +inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) +{ + return Matrix4( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ), + ( tfrm0 * tfrm1.getW( ) ) + ); +} + +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Vector3( + ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ), + ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ), + ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) ) + ); +} + +inline const Matrix3 crossMatrix( const Vector3 & vec ) +{ + return Matrix3( + Vector3( 0.0f, vec.getZ(), -vec.getY() ), + Vector3( -vec.getZ(), 0.0f, vec.getX() ), + Vector3( vec.getY(), -vec.getX(), 0.0f ) + ); +} + +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) +{ + return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); +} + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/src/vectormath/scalar/quat_aos.h b/src/vectormath/scalar/quat_aos.h new file mode 100644 index 0000000..764e017 --- /dev/null +++ b/src/vectormath/scalar/quat_aos.h @@ -0,0 +1,433 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _VECTORMATH_QUAT_AOS_CPP_H +#define _VECTORMATH_QUAT_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +inline Quat::Quat( const Quat & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; +} + +inline Quat::Quat( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Quat::Quat( const Vector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Quat::Quat( const Vector4 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = vec.getW(); +} + +inline Quat::Quat( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Quat Quat::identity( ) +{ + return Quat( 0.0f, 0.0f, 0.0f, 1.0f ); +} + +inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ) +{ + return ( quat0 + ( ( quat1 - quat0 ) * t ) ); +} + +inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ) +{ + Quat start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitQuat0, unitQuat1 ); + if ( cosAngle < 0.0f ) { + cosAngle = -cosAngle; + start = ( -unitQuat0 ); + } else { + start = unitQuat0; + } + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); +} + +inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) +{ + Quat tmp0, tmp1; + tmp0 = slerp( t, unitQuat0, unitQuat3 ); + tmp1 = slerp( t, unitQuat1, unitQuat2 ); + return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); +} + +inline void loadXYZW( Quat & quat, const float * fptr ) +{ + quat = Quat( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW( const Quat & quat, float * fptr ) +{ + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); +} + +inline Quat & Quat::operator =( const Quat & quat ) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; + return *this; +} + +inline Quat & Quat::setXYZ( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const Vector3 Quat::getXYZ( ) const +{ + return Vector3( mX, mY, mZ ); +} + +inline Quat & Quat::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Quat::getX( ) const +{ + return mX; +} + +inline Quat & Quat::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Quat::getY( ) const +{ + return mY; +} + +inline Quat & Quat::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Quat::getZ( ) const +{ + return mZ; +} + +inline Quat & Quat::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Quat::getW( ) const +{ + return mW; +} + +inline Quat & Quat::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Quat::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Quat::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Quat::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Quat Quat::operator +( const Quat & quat ) const +{ + return Quat( + ( mX + quat.mX ), + ( mY + quat.mY ), + ( mZ + quat.mZ ), + ( mW + quat.mW ) + ); +} + +inline const Quat Quat::operator -( const Quat & quat ) const +{ + return Quat( + ( mX - quat.mX ), + ( mY - quat.mY ), + ( mZ - quat.mZ ), + ( mW - quat.mW ) + ); +} + +inline const Quat Quat::operator *( float scalar ) const +{ + return Quat( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Quat & Quat::operator +=( const Quat & quat ) +{ + *this = *this + quat; + return *this; +} + +inline Quat & Quat::operator -=( const Quat & quat ) +{ + *this = *this - quat; + return *this; +} + +inline Quat & Quat::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Quat Quat::operator /( float scalar ) const +{ + return Quat( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Quat & Quat::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Quat Quat::operator -( ) const +{ + return Quat( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Quat operator *( float scalar, const Quat & quat ) +{ + return quat * scalar; +} + +inline float dot( const Quat & quat0, const Quat & quat1 ) +{ + float result; + result = ( quat0.getX() * quat1.getX() ); + result = ( result + ( quat0.getY() * quat1.getY() ) ); + result = ( result + ( quat0.getZ() * quat1.getZ() ) ); + result = ( result + ( quat0.getW() * quat1.getW() ) ); + return result; +} + +inline float norm( const Quat & quat ) +{ + float result; + result = ( quat.getX() * quat.getX() ); + result = ( result + ( quat.getY() * quat.getY() ) ); + result = ( result + ( quat.getZ() * quat.getZ() ) ); + result = ( result + ( quat.getW() * quat.getW() ) ); + return result; +} + +inline float length( const Quat & quat ) +{ + return ::sqrtf( norm( quat ) ); +} + +inline const Quat normalize( const Quat & quat ) +{ + float lenSqr, lenInv; + lenSqr = norm( quat ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Quat( + ( quat.getX() * lenInv ), + ( quat.getY() * lenInv ), + ( quat.getZ() * lenInv ), + ( quat.getW() * lenInv ) + ); +} + +inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) +{ + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); + recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); + return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); +} + +inline const Quat Quat::rotation( float radians, const Vector3 & unitVec ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( ( unitVec * s ), c ); +} + +inline const Quat Quat::rotationX( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( s, 0.0f, 0.0f, c ); +} + +inline const Quat Quat::rotationY( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, s, 0.0f, c ); +} + +inline const Quat Quat::rotationZ( float radians ) +{ + float s, c, angle; + angle = ( radians * 0.5f ); + s = sinf( angle ); + c = cosf( angle ); + return Quat( 0.0f, 0.0f, s, c ); +} + +inline const Quat Quat::operator *( const Quat & quat ) const +{ + return Quat( + ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ), + ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ), + ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ), + ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) ) + ); +} + +inline Quat & Quat::operator *=( const Quat & quat ) +{ + *this = *this * quat; + return *this; +} + +inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) +{ + float tmpX, tmpY, tmpZ, tmpW; + tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); + tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); + tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); + tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); + return Vector3( + ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), + ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), + ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) + ); +} + +inline const Quat conj( const Quat & quat ) +{ + return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); +} + +inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ) +{ + return Quat( + ( select1 )? quat1.getX() : quat0.getX(), + ( select1 )? quat1.getY() : quat0.getY(), + ( select1 )? quat1.getZ() : quat0.getZ(), + ( select1 )? quat1.getW() : quat0.getW() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Quat & quat ) +{ + printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +inline void print( const Quat & quat, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/src/vectormath/scalar/vec_aos.h b/src/vectormath/scalar/vec_aos.h new file mode 100644 index 0000000..46d4d6b --- /dev/null +++ b/src/vectormath/scalar/vec_aos.h @@ -0,0 +1,1426 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _VECTORMATH_VEC_AOS_CPP_H +#define _VECTORMATH_VEC_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Constants + +#define _VECTORMATH_SLERP_TOL 0.999f + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +inline Vector3::Vector3( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; +} + +inline Vector3::Vector3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +} + +inline Vector3::Vector3( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); +} + +inline Vector3::Vector3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +} + +inline const Vector3 Vector3::xAxis( ) +{ + return Vector3( 1.0f, 0.0f, 0.0f ); +} + +inline const Vector3 Vector3::yAxis( ) +{ + return Vector3( 0.0f, 1.0f, 0.0f ); +} + +inline const Vector3 Vector3::zAxis( ) +{ + return Vector3( 0.0f, 0.0f, 1.0f ); +} + +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZ( Vector3 & vec, const float * fptr ) +{ + vec = Vector3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Vector3 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector3 & Vector3::operator =( const Vector3 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + return *this; +} + +inline Vector3 & Vector3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector3::getX( ) const +{ + return mX; +} + +inline Vector3 & Vector3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector3::getY( ) const +{ + return mY; +} + +inline Vector3 & Vector3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector3::getZ( ) const +{ + return mZ; +} + +inline Vector3 & Vector3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Vector3::operator +( const Vector3 & vec ) const +{ + return Vector3( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ) + ); +} + +inline const Vector3 Vector3::operator -( const Vector3 & vec ) const +{ + return Vector3( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ) + ); +} + +inline const Point3 Vector3::operator +( const Point3 & pnt ) const +{ + return Point3( + ( mX + pnt.getX() ), + ( mY + pnt.getY() ), + ( mZ + pnt.getZ() ) + ); +} + +inline const Vector3 Vector3::operator *( float scalar ) const +{ + return Vector3( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ) + ); +} + +inline Vector3 & Vector3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector3 & Vector3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector3 & Vector3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector3 Vector3::operator /( float scalar ) const +{ + return Vector3( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ) + ); +} + +inline Vector3 & Vector3::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector3 Vector3::operator -( ) const +{ + return Vector3( + -mX, + -mY, + -mZ + ); +} + +inline const Vector3 operator *( float scalar, const Vector3 & vec ) +{ + return vec * scalar; +} + +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ) + ); +} + +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ) + ); +} + +inline const Vector3 recipPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ) + ); +} + +inline const Vector3 sqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ) + ); +} + +inline const Vector3 rsqrtPerElem( const Vector3 & vec ) +{ + return Vector3( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ) + ); +} + +inline const Vector3 absPerElem( const Vector3 & vec ) +{ + return Vector3( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ) + ); +} + +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ) + ); +} + +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float maxElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + return result; +} + +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() + ); +} + +inline float minElem( const Vector3 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + return result; +} + +inline float sum( const Vector3 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + return result; +} + +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ) +{ + float result; + result = ( vec0.getX() * vec1.getX() ); + result = ( result + ( vec0.getY() * vec1.getY() ) ); + result = ( result + ( vec0.getZ() * vec1.getZ() ) ); + return result; +} + +inline float lengthSqr( const Vector3 & vec ) +{ + float result; + result = ( vec.getX() * vec.getX() ); + result = ( result + ( vec.getY() * vec.getY() ) ); + result = ( result + ( vec.getZ() * vec.getZ() ) ); + return result; +} + +inline float length( const Vector3 & vec ) +{ + return ::sqrtf( lengthSqr( vec ) ); +} + +inline const Vector3 normalize( const Vector3 & vec ) +{ + float lenSqr, lenInv; + lenSqr = lengthSqr( vec ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Vector3( + ( vec.getX() * lenInv ), + ( vec.getY() * lenInv ), + ( vec.getZ() * lenInv ) + ); +} + +inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) +{ + return Vector3( + ( ( vec0.getY() * vec1.getZ() ) - ( vec0.getZ() * vec1.getY() ) ), + ( ( vec0.getZ() * vec1.getX() ) - ( vec0.getX() * vec1.getZ() ) ), + ( ( vec0.getX() * vec1.getY() ) - ( vec0.getY() * vec1.getX() ) ) + ); +} + +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ) +{ + return Vector3( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector3 & vec ) +{ + printf( "( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ() ); +} + +inline void print( const Vector3 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ() ); +} + +#endif + +inline Vector4::Vector4( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; +} + +inline Vector4::Vector4( float _x, float _y, float _z, float _w ) +{ + mX = _x; + mY = _y; + mZ = _z; + mW = _w; +} + +inline Vector4::Vector4( const Vector3 & xyz, float _w ) +{ + this->setXYZ( xyz ); + this->setW( _w ); +} + +inline Vector4::Vector4( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = 0.0f; +} + +inline Vector4::Vector4( const Point3 & pnt ) +{ + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); + mW = 1.0f; +} + +inline Vector4::Vector4( const Quat & quat ) +{ + mX = quat.getX(); + mY = quat.getY(); + mZ = quat.getZ(); + mW = quat.getW(); +} + +inline Vector4::Vector4( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; +} + +inline const Vector4 Vector4::xAxis( ) +{ + return Vector4( 1.0f, 0.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::yAxis( ) +{ + return Vector4( 0.0f, 1.0f, 0.0f, 0.0f ); +} + +inline const Vector4 Vector4::zAxis( ) +{ + return Vector4( 0.0f, 0.0f, 1.0f, 0.0f ); +} + +inline const Vector4 Vector4::wAxis( ) +{ + return Vector4( 0.0f, 0.0f, 0.0f, 1.0f ); +} + +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) +{ + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot( unitVec0, unitVec1 ); + if ( cosAngle < _VECTORMATH_SLERP_TOL ) { + angle = acosf( cosAngle ); + recipSinAngle = ( 1.0f / sinf( angle ) ); + scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); + scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); + } else { + scale0 = ( 1.0f - t ); + scale1 = t; + } + return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); +} + +inline void loadXYZW( Vector4 & vec, const float * fptr ) +{ + vec = Vector4( fptr[0], fptr[1], fptr[2], fptr[3] ); +} + +inline void storeXYZW( const Vector4 & vec, float * fptr ) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); + fptr[3] = vec.getW(); +} + +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 4; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Vector4 & Vector4::operator =( const Vector4 & vec ) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; + return *this; +} + +inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; +} + +inline const Vector3 Vector4::getXYZ( ) const +{ + return Vector3( mX, mY, mZ ); +} + +inline Vector4 & Vector4::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Vector4::getX( ) const +{ + return mX; +} + +inline Vector4 & Vector4::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Vector4::getY( ) const +{ + return mY; +} + +inline Vector4 & Vector4::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Vector4::getZ( ) const +{ + return mZ; +} + +inline Vector4 & Vector4::setW( float _w ) +{ + mW = _w; + return *this; +} + +inline float Vector4::getW( ) const +{ + return mW; +} + +inline Vector4 & Vector4::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Vector4::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Vector4::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Vector4::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector4 Vector4::operator +( const Vector4 & vec ) const +{ + return Vector4( + ( mX + vec.mX ), + ( mY + vec.mY ), + ( mZ + vec.mZ ), + ( mW + vec.mW ) + ); +} + +inline const Vector4 Vector4::operator -( const Vector4 & vec ) const +{ + return Vector4( + ( mX - vec.mX ), + ( mY - vec.mY ), + ( mZ - vec.mZ ), + ( mW - vec.mW ) + ); +} + +inline const Vector4 Vector4::operator *( float scalar ) const +{ + return Vector4( + ( mX * scalar ), + ( mY * scalar ), + ( mZ * scalar ), + ( mW * scalar ) + ); +} + +inline Vector4 & Vector4::operator +=( const Vector4 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Vector4 & Vector4::operator -=( const Vector4 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline Vector4 & Vector4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +inline const Vector4 Vector4::operator /( float scalar ) const +{ + return Vector4( + ( mX / scalar ), + ( mY / scalar ), + ( mZ / scalar ), + ( mW / scalar ) + ); +} + +inline Vector4 & Vector4::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +inline const Vector4 Vector4::operator -( ) const +{ + return Vector4( + -mX, + -mY, + -mZ, + -mW + ); +} + +inline const Vector4 operator *( float scalar, const Vector4 & vec ) +{ + return vec * scalar; +} + +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() * vec1.getX() ), + ( vec0.getY() * vec1.getY() ), + ( vec0.getZ() * vec1.getZ() ), + ( vec0.getW() * vec1.getW() ) + ); +} + +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec0.getX() / vec1.getX() ), + ( vec0.getY() / vec1.getY() ), + ( vec0.getZ() / vec1.getZ() ), + ( vec0.getW() / vec1.getW() ) + ); +} + +inline const Vector4 recipPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / vec.getX() ), + ( 1.0f / vec.getY() ), + ( 1.0f / vec.getZ() ), + ( 1.0f / vec.getW() ) + ); +} + +inline const Vector4 sqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + sqrtf( vec.getX() ), + sqrtf( vec.getY() ), + sqrtf( vec.getZ() ), + sqrtf( vec.getW() ) + ); +} + +inline const Vector4 rsqrtPerElem( const Vector4 & vec ) +{ + return Vector4( + ( 1.0f / sqrtf( vec.getX() ) ), + ( 1.0f / sqrtf( vec.getY() ) ), + ( 1.0f / sqrtf( vec.getZ() ) ), + ( 1.0f / sqrtf( vec.getW() ) ) + ); +} + +inline const Vector4 absPerElem( const Vector4 & vec ) +{ + return Vector4( + fabsf( vec.getX() ), + fabsf( vec.getY() ), + fabsf( vec.getZ() ), + fabsf( vec.getW() ) + ); +} + +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), + ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), + ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ), + ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() ) + ); +} + +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float maxElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() > result)? vec.getZ() : result; + result = (vec.getW() > result)? vec.getW() : result; + return result; +} + +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +{ + return Vector4( + (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(), + (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW() + ); +} + +inline float minElem( const Vector4 & vec ) +{ + float result; + result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); + result = (vec.getZ() < result)? vec.getZ() : result; + result = (vec.getW() < result)? vec.getW() : result; + return result; +} + +inline float sum( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() + vec.getY() ); + result = ( result + vec.getZ() ); + result = ( result + vec.getW() ); + return result; +} + +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ) +{ + float result; + result = ( vec0.getX() * vec1.getX() ); + result = ( result + ( vec0.getY() * vec1.getY() ) ); + result = ( result + ( vec0.getZ() * vec1.getZ() ) ); + result = ( result + ( vec0.getW() * vec1.getW() ) ); + return result; +} + +inline float lengthSqr( const Vector4 & vec ) +{ + float result; + result = ( vec.getX() * vec.getX() ); + result = ( result + ( vec.getY() * vec.getY() ) ); + result = ( result + ( vec.getZ() * vec.getZ() ) ); + result = ( result + ( vec.getW() * vec.getW() ) ); + return result; +} + +inline float length( const Vector4 & vec ) +{ + return ::sqrtf( lengthSqr( vec ) ); +} + +inline const Vector4 normalize( const Vector4 & vec ) +{ + float lenSqr, lenInv; + lenSqr = lengthSqr( vec ); + lenInv = ( 1.0f / sqrtf( lenSqr ) ); + return Vector4( + ( vec.getX() * lenInv ), + ( vec.getY() * lenInv ), + ( vec.getZ() * lenInv ), + ( vec.getW() * lenInv ) + ); +} + +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ) +{ + return Vector4( + ( select1 )? vec1.getX() : vec0.getX(), + ( select1 )? vec1.getY() : vec0.getY(), + ( select1 )? vec1.getZ() : vec0.getZ(), + ( select1 )? vec1.getW() : vec0.getW() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Vector4 & vec ) +{ + printf( "( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +inline void print( const Vector4 & vec, const char * name ) +{ + printf( "%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); +} + +#endif + +inline Point3::Point3( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; +} + +inline Point3::Point3( float _x, float _y, float _z ) +{ + mX = _x; + mY = _y; + mZ = _z; +} + +inline Point3::Point3( const Vector3 & vec ) +{ + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); +} + +inline Point3::Point3( float scalar ) +{ + mX = scalar; + mY = scalar; + mZ = scalar; +} + +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ) +{ + return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); +} + +inline void loadXYZ( Point3 & pnt, const float * fptr ) +{ + pnt = Point3( fptr[0], fptr[1], fptr[2] ); +} + +inline void storeXYZ( const Point3 & pnt, float * fptr ) +{ + fptr[0] = pnt.getX(); + fptr[1] = pnt.getY(); + fptr[2] = pnt.getZ(); +} + +inline void loadHalfFloats( Point3 & vec, const unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); + + if (exponent == 0) { + // zero + mantissa = 0; + + } else if (exponent == 31) { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + + } else { + exponent += 127 - 15; + mantissa <<= 13; + } + + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } +} + +inline void storeHalfFloats( const Point3 & vec, unsigned short * hfptr ) +{ + union Data32 { + unsigned int u32; + float f32; + }; + + for (int i = 0; i < 3; i++) { + Data32 d; + d.f32 = vec[i]; + + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + + if (exponent == 0) { + // zero or denorm -> zero + mantissa = 0; + + } else if (exponent == 255 && mantissa != 0) { + // nan -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent >= 127 - 15 + 31) { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + + } else if (exponent <= 127 - 15) { + // underflow -> zero + exponent = 0; + mantissa = 0; + + } else { + exponent -= 127 - 15; + mantissa >>= 13; + } + + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } +} + +inline Point3 & Point3::operator =( const Point3 & pnt ) +{ + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; + return *this; +} + +inline Point3 & Point3::setX( float _x ) +{ + mX = _x; + return *this; +} + +inline float Point3::getX( ) const +{ + return mX; +} + +inline Point3 & Point3::setY( float _y ) +{ + mY = _y; + return *this; +} + +inline float Point3::getY( ) const +{ + return mY; +} + +inline Point3 & Point3::setZ( float _z ) +{ + mZ = _z; + return *this; +} + +inline float Point3::getZ( ) const +{ + return mZ; +} + +inline Point3 & Point3::setElem( int idx, float value ) +{ + *(&mX + idx) = value; + return *this; +} + +inline float Point3::getElem( int idx ) const +{ + return *(&mX + idx); +} + +inline float & Point3::operator []( int idx ) +{ + return *(&mX + idx); +} + +inline float Point3::operator []( int idx ) const +{ + return *(&mX + idx); +} + +inline const Vector3 Point3::operator -( const Point3 & pnt ) const +{ + return Vector3( + ( mX - pnt.mX ), + ( mY - pnt.mY ), + ( mZ - pnt.mZ ) + ); +} + +inline const Point3 Point3::operator +( const Vector3 & vec ) const +{ + return Point3( + ( mX + vec.getX() ), + ( mY + vec.getY() ), + ( mZ + vec.getZ() ) + ); +} + +inline const Point3 Point3::operator -( const Vector3 & vec ) const +{ + return Point3( + ( mX - vec.getX() ), + ( mY - vec.getY() ), + ( mZ - vec.getZ() ) + ); +} + +inline Point3 & Point3::operator +=( const Vector3 & vec ) +{ + *this = *this + vec; + return *this; +} + +inline Point3 & Point3::operator -=( const Vector3 & vec ) +{ + *this = *this - vec; + return *this; +} + +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() * pnt1.getX() ), + ( pnt0.getY() * pnt1.getY() ), + ( pnt0.getZ() * pnt1.getZ() ) + ); +} + +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt0.getX() / pnt1.getX() ), + ( pnt0.getY() / pnt1.getY() ), + ( pnt0.getZ() / pnt1.getZ() ) + ); +} + +inline const Point3 recipPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / pnt.getX() ), + ( 1.0f / pnt.getY() ), + ( 1.0f / pnt.getZ() ) + ); +} + +inline const Point3 sqrtPerElem( const Point3 & pnt ) +{ + return Point3( + sqrtf( pnt.getX() ), + sqrtf( pnt.getY() ), + sqrtf( pnt.getZ() ) + ); +} + +inline const Point3 rsqrtPerElem( const Point3 & pnt ) +{ + return Point3( + ( 1.0f / sqrtf( pnt.getX() ) ), + ( 1.0f / sqrtf( pnt.getY() ) ), + ( 1.0f / sqrtf( pnt.getZ() ) ) + ); +} + +inline const Point3 absPerElem( const Point3 & pnt ) +{ + return Point3( + fabsf( pnt.getX() ), + fabsf( pnt.getY() ), + fabsf( pnt.getZ() ) + ); +} + +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ), + ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ), + ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() ) + ); +} + +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float maxElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() > result)? pnt.getZ() : result; + return result; +} + +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return Point3( + (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(), + (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ() + ); +} + +inline float minElem( const Point3 & pnt ) +{ + float result; + result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY(); + result = (pnt.getZ() < result)? pnt.getZ() : result; + return result; +} + +inline float sum( const Point3 & pnt ) +{ + float result; + result = ( pnt.getX() + pnt.getY() ); + result = ( result + pnt.getZ() ); + return result; +} + +inline const Point3 scale( const Point3 & pnt, float scaleVal ) +{ + return mulPerElem( pnt, Point3( scaleVal ) ); +} + +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) +{ + return mulPerElem( pnt, Point3( scaleVec ) ); +} + +inline float projection( const Point3 & pnt, const Vector3 & unitVec ) +{ + float result; + result = ( pnt.getX() * unitVec.getX() ); + result = ( result + ( pnt.getY() * unitVec.getY() ) ); + result = ( result + ( pnt.getZ() * unitVec.getZ() ) ); + return result; +} + +inline float distSqrFromOrigin( const Point3 & pnt ) +{ + return lengthSqr( Vector3( pnt ) ); +} + +inline float distFromOrigin( const Point3 & pnt ) +{ + return length( Vector3( pnt ) ); +} + +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return lengthSqr( ( pnt1 - pnt0 ) ); +} + +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ) +{ + return length( ( pnt1 - pnt0 ) ); +} + +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ) +{ + return Point3( + ( select1 )? pnt1.getX() : pnt0.getX(), + ( select1 )? pnt1.getY() : pnt0.getY(), + ( select1 )? pnt1.getZ() : pnt0.getZ() + ); +} + +#ifdef _VECTORMATH_DEBUG + +inline void print( const Point3 & pnt ) +{ + printf( "( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +inline void print( const Point3 & pnt, const char * name ) +{ + printf( "%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ() ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/src/vectormath/scalar/vectormath_aos.h b/src/vectormath/scalar/vectormath_aos.h new file mode 100644 index 0000000..d00456d --- /dev/null +++ b/src/vectormath/scalar/vectormath_aos.h @@ -0,0 +1,1872 @@ +/* + Copyright (C) 2009 Sony Computer Entertainment Inc. + All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _VECTORMATH_AOS_CPP_H +#define _VECTORMATH_AOS_CPP_H + +#include + +#ifdef _VECTORMATH_DEBUG +#include +#endif + +namespace Vectormath { + +namespace Aos { + +//----------------------------------------------------------------------------- +// Forward Declarations +// + +class Vector3; +class Vector4; +class Point3; +class Quat; +class Matrix3; +class Matrix4; +class Transform3; + +// A 3-D vector in array-of-structures format +// +class Vector3 +{ + float mX; + float mY; + float mZ; +#ifndef __GNUC__ + float d; +#endif + +public: + // Default constructor; does no initialization + // + inline Vector3( ) { }; + + // Copy a 3-D vector + // + inline Vector3( const Vector3 & vec ); + + // Construct a 3-D vector from x, y, and z elements + // + inline Vector3( float x, float y, float z ); + + // Copy elements from a 3-D point into a 3-D vector + // + explicit inline Vector3( const Point3 & pnt ); + + // Set all elements of a 3-D vector to the same scalar value + // + explicit inline Vector3( float scalar ); + + // Assign one 3-D vector to another + // + inline Vector3 & operator =( const Vector3 & vec ); + + // Set the x element of a 3-D vector + // + inline Vector3 & setX( float x ); + + // Set the y element of a 3-D vector + // + inline Vector3 & setY( float y ); + + // Set the z element of a 3-D vector + // + inline Vector3 & setZ( float z ); + + // Get the x element of a 3-D vector + // + inline float getX( ) const; + + // Get the y element of a 3-D vector + // + inline float getY( ) const; + + // Get the z element of a 3-D vector + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D vector by index + // + inline Vector3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 3-D vectors + // + inline const Vector3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from another 3-D vector + // + inline const Vector3 operator -( const Vector3 & vec ) const; + + // Add a 3-D vector to a 3-D point + // + inline const Point3 operator +( const Point3 & pnt ) const; + + // Multiply a 3-D vector by a scalar + // + inline const Vector3 operator *( float scalar ) const; + + // Divide a 3-D vector by a scalar + // + inline const Vector3 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Vector3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Vector3 & operator -=( const Vector3 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector3 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector3 & operator /=( float scalar ); + + // Negate all elements of a 3-D vector + // + inline const Vector3 operator -( ) const; + + // Construct x axis + // + static inline const Vector3 xAxis( ); + + // Construct y axis + // + static inline const Vector3 yAxis( ); + + // Construct z axis + // + static inline const Vector3 zAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 3-D vector by a scalar +// +inline const Vector3 operator *( float scalar, const Vector3 & vec ); + +// Multiply two 3-D vectors per element +// +inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Divide two 3-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the reciprocal of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector3 recipPerElem( const Vector3 & vec ); + +// Compute the square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector3 sqrtPerElem( const Vector3 & vec ); + +// Compute the reciprocal square root of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector3 rsqrtPerElem( const Vector3 & vec ); + +// Compute the absolute value of a 3-D vector per element +// +inline const Vector3 absPerElem( const Vector3 & vec ); + +// Copy sign from one 3-D vector to another, per element +// +inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum of two 3-D vectors per element +// +inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Minimum of two 3-D vectors per element +// +inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); + +// Maximum element of a 3-D vector +// +inline float maxElem( const Vector3 & vec ); + +// Minimum element of a 3-D vector +// +inline float minElem( const Vector3 & vec ); + +// Compute the sum of all elements of a 3-D vector +// +inline float sum( const Vector3 & vec ); + +// Compute the dot product of two 3-D vectors +// +inline float dot( const Vector3 & vec0, const Vector3 & vec1 ); + +// Compute the square of the length of a 3-D vector +// +inline float lengthSqr( const Vector3 & vec ); + +// Compute the length of a 3-D vector +// +inline float length( const Vector3 & vec ); + +// Normalize a 3-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector3 normalize( const Vector3 & vec ); + +// Compute cross product of two 3-D vectors +// +inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); + +// Outer product of two 3-D vectors +// +inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); + +// Pre-multiply a row vector by a 3x3 matrix +// +inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); + +// Cross-product matrix of a 3-D vector +// +inline const Matrix3 crossMatrix( const Vector3 & vec ); + +// Create cross-product matrix and multiply +// NOTE: +// Faster than separately creating a cross-product matrix and multiplying. +// +inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); + +// Linear interpolation between two 3-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ); + +// Spherical linear interpolation between two 3-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); + +// Conditionally select between two 3-D vectors +// +inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Vector3 & vec, const float * fptr ); + +// Store x, y, and z elements of a 3-D vector in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Vector3 & vec, float * fptr ); + +// Load three-half-floats as a 3-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ); + +// Store a 3-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec ); + +// Print a 3-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector3 & vec, const char * name ); + +#endif + +// A 4-D vector in array-of-structures format +// +class Vector4 +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Vector4( ) { }; + + // Copy a 4-D vector + // + inline Vector4( const Vector4 & vec ); + + // Construct a 4-D vector from x, y, z, and w elements + // + inline Vector4( float x, float y, float z, float w ); + + // Construct a 4-D vector from a 3-D vector and a scalar + // + inline Vector4( const Vector3 & xyz, float w ); + + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit inline Vector4( const Vector3 & vec ); + + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit inline Vector4( const Point3 & pnt ); + + // Copy elements from a quaternion into a 4-D vector + // + explicit inline Vector4( const Quat & quat ); + + // Set all elements of a 4-D vector to the same scalar value + // + explicit inline Vector4( float scalar ); + + // Assign one 4-D vector to another + // + inline Vector4 & operator =( const Vector4 & vec ); + + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + inline Vector4 & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a 4-D vector + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a 4-D vector + // + inline Vector4 & setX( float x ); + + // Set the y element of a 4-D vector + // + inline Vector4 & setY( float y ); + + // Set the z element of a 4-D vector + // + inline Vector4 & setZ( float z ); + + // Set the w element of a 4-D vector + // + inline Vector4 & setW( float w ); + + // Get the x element of a 4-D vector + // + inline float getX( ) const; + + // Get the y element of a 4-D vector + // + inline float getY( ) const; + + // Get the z element of a 4-D vector + // + inline float getZ( ) const; + + // Get the w element of a 4-D vector + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a 4-D vector by index + // + inline Vector4 & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a 4-D vector by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two 4-D vectors + // + inline const Vector4 operator +( const Vector4 & vec ) const; + + // Subtract a 4-D vector from another 4-D vector + // + inline const Vector4 operator -( const Vector4 & vec ) const; + + // Multiply a 4-D vector by a scalar + // + inline const Vector4 operator *( float scalar ) const; + + // Divide a 4-D vector by a scalar + // + inline const Vector4 operator /( float scalar ) const; + + // Perform compound assignment and addition with a 4-D vector + // + inline Vector4 & operator +=( const Vector4 & vec ); + + // Perform compound assignment and subtraction by a 4-D vector + // + inline Vector4 & operator -=( const Vector4 & vec ); + + // Perform compound assignment and multiplication by a scalar + // + inline Vector4 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Vector4 & operator /=( float scalar ); + + // Negate all elements of a 4-D vector + // + inline const Vector4 operator -( ) const; + + // Construct x axis + // + static inline const Vector4 xAxis( ); + + // Construct y axis + // + static inline const Vector4 yAxis( ); + + // Construct z axis + // + static inline const Vector4 zAxis( ); + + // Construct w axis + // + static inline const Vector4 wAxis( ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a 4-D vector by a scalar +// +inline const Vector4 operator *( float scalar, const Vector4 & vec ); + +// Multiply two 4-D vectors per element +// +inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Divide two 4-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the reciprocal of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Vector4 recipPerElem( const Vector4 & vec ); + +// Compute the square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Vector4 sqrtPerElem( const Vector4 & vec ); + +// Compute the reciprocal square root of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Vector4 rsqrtPerElem( const Vector4 & vec ); + +// Compute the absolute value of a 4-D vector per element +// +inline const Vector4 absPerElem( const Vector4 & vec ); + +// Copy sign from one 4-D vector to another, per element +// +inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum of two 4-D vectors per element +// +inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Minimum of two 4-D vectors per element +// +inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); + +// Maximum element of a 4-D vector +// +inline float maxElem( const Vector4 & vec ); + +// Minimum element of a 4-D vector +// +inline float minElem( const Vector4 & vec ); + +// Compute the sum of all elements of a 4-D vector +// +inline float sum( const Vector4 & vec ); + +// Compute the dot product of two 4-D vectors +// +inline float dot( const Vector4 & vec0, const Vector4 & vec1 ); + +// Compute the square of the length of a 4-D vector +// +inline float lengthSqr( const Vector4 & vec ); + +// Compute the length of a 4-D vector +// +inline float length( const Vector4 & vec ); + +// Normalize a 4-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +inline const Vector4 normalize( const Vector4 & vec ); + +// Outer product of two 4-D vectors +// +inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); + +// Linear interpolation between two 4-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ); + +// Spherical linear interpolation between two 4-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); + +// Conditionally select between two 4-D vectors +// +inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Vector4 & vec, const float * fptr ); + +// Store x, y, z, and w elements of a 4-D vector in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Vector4 & vec, float * fptr ); + +// Load four-half-floats as a 4-D vector +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ); + +// Store a 4-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec ); + +// Print a 4-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Vector4 & vec, const char * name ); + +#endif + +// A 3-D point in array-of-structures format +// +class Point3 +{ + float mX; + float mY; + float mZ; +#ifndef __GNUC__ + float d; +#endif + +public: + // Default constructor; does no initialization + // + inline Point3( ) { }; + + // Copy a 3-D point + // + inline Point3( const Point3 & pnt ); + + // Construct a 3-D point from x, y, and z elements + // + inline Point3( float x, float y, float z ); + + // Copy elements from a 3-D vector into a 3-D point + // + explicit inline Point3( const Vector3 & vec ); + + // Set all elements of a 3-D point to the same scalar value + // + explicit inline Point3( float scalar ); + + // Assign one 3-D point to another + // + inline Point3 & operator =( const Point3 & pnt ); + + // Set the x element of a 3-D point + // + inline Point3 & setX( float x ); + + // Set the y element of a 3-D point + // + inline Point3 & setY( float y ); + + // Set the z element of a 3-D point + // + inline Point3 & setZ( float z ); + + // Get the x element of a 3-D point + // + inline float getX( ) const; + + // Get the y element of a 3-D point + // + inline float getY( ) const; + + // Get the z element of a 3-D point + // + inline float getZ( ) const; + + // Set an x, y, or z element of a 3-D point by index + // + inline Point3 & setElem( int idx, float value ); + + // Get an x, y, or z element of a 3-D point by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Subtract a 3-D point from another 3-D point + // + inline const Vector3 operator -( const Point3 & pnt ) const; + + // Add a 3-D point to a 3-D vector + // + inline const Point3 operator +( const Vector3 & vec ) const; + + // Subtract a 3-D vector from a 3-D point + // + inline const Point3 operator -( const Vector3 & vec ) const; + + // Perform compound assignment and addition with a 3-D vector + // + inline Point3 & operator +=( const Vector3 & vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + inline Point3 & operator -=( const Vector3 & vec ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply two 3-D points per element +// +inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Divide two 3-D points per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the reciprocal of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +inline const Point3 recipPerElem( const Point3 & pnt ); + +// Compute the square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function sqrtf4. +// +inline const Point3 sqrtPerElem( const Point3 & pnt ); + +// Compute the reciprocal square root of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function rsqrtf4. +// +inline const Point3 rsqrtPerElem( const Point3 & pnt ); + +// Compute the absolute value of a 3-D point per element +// +inline const Point3 absPerElem( const Point3 & pnt ); + +// Copy sign from one 3-D point to another, per element +// +inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum of two 3-D points per element +// +inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Minimum of two 3-D points per element +// +inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); + +// Maximum element of a 3-D point +// +inline float maxElem( const Point3 & pnt ); + +// Minimum element of a 3-D point +// +inline float minElem( const Point3 & pnt ); + +// Compute the sum of all elements of a 3-D point +// +inline float sum( const Point3 & pnt ); + +// Apply uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, float scaleVal ); + +// Apply non-uniform scale to a 3-D point +// +inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); + +// Scalar projection of a 3-D point on a unit-length 3-D vector +// +inline float projection( const Point3 & pnt, const Vector3 & unitVec ); + +// Compute the square of the distance of a 3-D point from the coordinate-system origin +// +inline float distSqrFromOrigin( const Point3 & pnt ); + +// Compute the distance of a 3-D point from the coordinate-system origin +// +inline float distFromOrigin( const Point3 & pnt ); + +// Compute the square of the distance between two 3-D points +// +inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ); + +// Compute the distance between two 3-D points +// +inline float dist( const Point3 & pnt0, const Point3 & pnt1 ); + +// Linear interpolation between two 3-D points +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ); + +// Conditionally select between two 3-D points +// +inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ); + +// Load x, y, and z elements from the first three words of a float array. +// +// +inline void loadXYZ( Point3 & pnt, const float * fptr ); + +// Store x, y, and z elements of a 3-D point in the first three words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZ( const Point3 & pnt, float * fptr ); + +// Load three-half-floats as a 3-D point +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. +// +inline void loadHalfFloats( Point3 & pnt, const unsigned short * hfptr ); + +// Store a 3-D point as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// NOTE: +// This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. +// +inline void storeHalfFloats( const Point3 & pnt, unsigned short * hfptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D point +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt ); + +// Print a 3-D point and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Point3 & pnt, const char * name ); + +#endif + +// A quaternion in array-of-structures format +// +class Quat +{ + float mX; + float mY; + float mZ; + float mW; + +public: + // Default constructor; does no initialization + // + inline Quat( ) { }; + + // Copy a quaternion + // + inline Quat( const Quat & quat ); + + // Construct a quaternion from x, y, z, and w elements + // + inline Quat( float x, float y, float z, float w ); + + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat( const Vector3 & xyz, float w ); + + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat( const Vector4 & vec ); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat( const Matrix3 & rotMat ); + + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat( float scalar ); + + // Assign one quaternion to another + // + inline Quat & operator =( const Quat & quat ); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat & setXYZ( const Vector3 & vec ); + + // Get the x, y, and z elements of a quaternion + // + inline const Vector3 getXYZ( ) const; + + // Set the x element of a quaternion + // + inline Quat & setX( float x ); + + // Set the y element of a quaternion + // + inline Quat & setY( float y ); + + // Set the z element of a quaternion + // + inline Quat & setZ( float z ); + + // Set the w element of a quaternion + // + inline Quat & setW( float w ); + + // Get the x element of a quaternion + // + inline float getX( ) const; + + // Get the y element of a quaternion + // + inline float getY( ) const; + + // Get the z element of a quaternion + // + inline float getZ( ) const; + + // Get the w element of a quaternion + // + inline float getW( ) const; + + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat & setElem( int idx, float value ); + + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + inline float & operator []( int idx ); + + // Subscripting operator to get an element + // + inline float operator []( int idx ) const; + + // Add two quaternions + // + inline const Quat operator +( const Quat & quat ) const; + + // Subtract a quaternion from another quaternion + // + inline const Quat operator -( const Quat & quat ) const; + + // Multiply two quaternions + // + inline const Quat operator *( const Quat & quat ) const; + + // Multiply a quaternion by a scalar + // + inline const Quat operator *( float scalar ) const; + + // Divide a quaternion by a scalar + // + inline const Quat operator /( float scalar ) const; + + // Perform compound assignment and addition with a quaternion + // + inline Quat & operator +=( const Quat & quat ); + + // Perform compound assignment and subtraction by a quaternion + // + inline Quat & operator -=( const Quat & quat ); + + // Perform compound assignment and multiplication by a quaternion + // + inline Quat & operator *=( const Quat & quat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Quat & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + inline Quat & operator /=( float scalar ); + + // Negate all elements of a quaternion + // + inline const Quat operator -( ) const; + + // Construct an identity quaternion + // + static inline const Quat identity( ); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat rotation( float radians, const Vector3 & unitVec ); + + // Construct a quaternion to rotate around the x axis + // + static inline const Quat rotationX( float radians ); + + // Construct a quaternion to rotate around the y axis + // + static inline const Quat rotationY( float radians ); + + // Construct a quaternion to rotate around the z axis + // + static inline const Quat rotationZ( float radians ); + +} +#ifdef __GNUC__ +__attribute__ ((aligned(16))) +#endif +; + +// Multiply a quaternion by a scalar +// +inline const Quat operator *( float scalar, const Quat & quat ); + +// Compute the conjugate of a quaternion +// +inline const Quat conj( const Quat & quat ); + +// Use a unit-length quaternion to rotate a 3-D vector +// +inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); + +// Compute the dot product of two quaternions +// +inline float dot( const Quat & quat0, const Quat & quat1 ); + +// Compute the norm of a quaternion +// +inline float norm( const Quat & quat ); + +// Compute the length of a quaternion +// +inline float length( const Quat & quat ); + +// Normalize a quaternion +// NOTE: +// The result is unpredictable when all elements of quat are at or near zero. +// +inline const Quat normalize( const Quat & quat ); + +// Linear interpolation between two quaternions +// NOTE: +// Does not clamp t between 0 and 1. +// +inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ); + +// Spherical linear interpolation between two quaternions +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ); + +// Spherical quadrangle interpolation +// +inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); + +// Conditionally select between two quaternions +// +inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ); + +// Load x, y, z, and w elements from the first four words of a float array. +// +// +inline void loadXYZW( Quat & quat, const float * fptr ); + +// Store x, y, z, and w elements of a quaternion in the first four words of a float array. +// Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed +// +inline void storeXYZW( const Quat & quat, float * fptr ); + +#ifdef _VECTORMATH_DEBUG + +// Print a quaternion +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat ); + +// Print a quaternion and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Quat & quat, const char * name ); + +#endif + +// A 3x3 matrix in array-of-structures format +// +class Matrix3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + +public: + // Default constructor; does no initialization + // + inline Matrix3( ) { }; + + // Copy a 3x3 matrix + // + inline Matrix3( const Matrix3 & mat ); + + // Construct a 3x3 matrix containing the specified columns + // + inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); + + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit inline Matrix3( const Quat & unitQuat ); + + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit inline Matrix3( float scalar ); + + // Assign one 3x3 matrix to another + // + inline Matrix3 & operator =( const Matrix3 & mat ); + + // Set column 0 of a 3x3 matrix + // + inline Matrix3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x3 matrix + // + inline Matrix3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x3 matrix + // + inline Matrix3 & setCol2( const Vector3 & col2 ); + + // Get column 0 of a 3x3 matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x3 matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x3 matrix + // + inline const Vector3 getCol2( ) const; + + // Set the column of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x3 matrix referred to by the specified index + // + inline Matrix3 & setRow( int row, const Vector3 & vec ); + + // Get the column of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x3 matrix referred to by column and row indices + // + inline Matrix3 & setElem( int col, int row, float val ); + + // Get the element of a 3x3 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 3x3 matrices + // + inline const Matrix3 operator +( const Matrix3 & mat ) const; + + // Subtract a 3x3 matrix from another 3x3 matrix + // + inline const Matrix3 operator -( const Matrix3 & mat ) const; + + // Negate all elements of a 3x3 matrix + // + inline const Matrix3 operator -( ) const; + + // Multiply a 3x3 matrix by a scalar + // + inline const Matrix3 operator *( float scalar ) const; + + // Multiply a 3x3 matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply two 3x3 matrices + // + inline const Matrix3 operator *( const Matrix3 & mat ) const; + + // Perform compound assignment and addition with a 3x3 matrix + // + inline Matrix3 & operator +=( const Matrix3 & mat ); + + // Perform compound assignment and subtraction by a 3x3 matrix + // + inline Matrix3 & operator -=( const Matrix3 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix3 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 3x3 matrix + // + inline Matrix3 & operator *=( const Matrix3 & mat ); + + // Construct an identity 3x3 matrix + // + static inline const Matrix3 identity( ); + + // Construct a 3x3 matrix to rotate around the x axis + // + static inline const Matrix3 rotationX( float radians ); + + // Construct a 3x3 matrix to rotate around the y axis + // + static inline const Matrix3 rotationY( float radians ); + + // Construct a 3x3 matrix to rotate around the z axis + // + static inline const Matrix3 rotationZ( float radians ); + + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix3 rotation( const Quat & unitQuat ); + + // Construct a 3x3 matrix to perform scaling + // + static inline const Matrix3 scale( const Vector3 & scaleVec ); + +}; +// Multiply a 3x3 matrix by a scalar +// +inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); + +// Append (post-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); + +// Multiply two 3x3 matrices per element +// +inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); + +// Compute the absolute value of a 3x3 matrix per element +// +inline const Matrix3 absPerElem( const Matrix3 & mat ); + +// Transpose of a 3x3 matrix +// +inline const Matrix3 transpose( const Matrix3 & mat ); + +// Compute the inverse of a 3x3 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix3 inverse( const Matrix3 & mat ); + +// Determinant of a 3x3 matrix +// +inline float determinant( const Matrix3 & mat ); + +// Conditionally select between two 3x3 matrices +// +inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x3 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat ); + +// Print a 3x3 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix3 & mat, const char * name ); + +#endif + +// A 4x4 matrix in array-of-structures format +// +class Matrix4 +{ + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; + +public: + // Default constructor; does no initialization + // + inline Matrix4( ) { }; + + // Copy a 4x4 matrix + // + inline Matrix4( const Matrix4 & mat ); + + // Construct a 4x4 matrix containing the specified columns + // + inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); + + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit inline Matrix4( const Transform3 & mat ); + + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); + + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit inline Matrix4( float scalar ); + + // Assign one 4x4 matrix to another + // + inline Matrix4 & operator =( const Matrix4 & mat ); + + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 4x4 matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 4x4 matrix + // + inline Matrix4 & setCol0( const Vector4 & col0 ); + + // Set column 1 of a 4x4 matrix + // + inline Matrix4 & setCol1( const Vector4 & col1 ); + + // Set column 2 of a 4x4 matrix + // + inline Matrix4 & setCol2( const Vector4 & col2 ); + + // Set column 3 of a 4x4 matrix + // + inline Matrix4 & setCol3( const Vector4 & col3 ); + + // Get column 0 of a 4x4 matrix + // + inline const Vector4 getCol0( ) const; + + // Get column 1 of a 4x4 matrix + // + inline const Vector4 getCol1( ) const; + + // Get column 2 of a 4x4 matrix + // + inline const Vector4 getCol2( ) const; + + // Get column 3 of a 4x4 matrix + // + inline const Vector4 getCol3( ) const; + + // Set the column of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setCol( int col, const Vector4 & vec ); + + // Set the row of a 4x4 matrix referred to by the specified index + // + inline Matrix4 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getCol( int col ) const; + + // Get the row of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector4 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector4 operator []( int col ) const; + + // Set the element of a 4x4 matrix referred to by column and row indices + // + inline Matrix4 & setElem( int col, int row, float val ); + + // Get the element of a 4x4 matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Add two 4x4 matrices + // + inline const Matrix4 operator +( const Matrix4 & mat ) const; + + // Subtract a 4x4 matrix from another 4x4 matrix + // + inline const Matrix4 operator -( const Matrix4 & mat ) const; + + // Negate all elements of a 4x4 matrix + // + inline const Matrix4 operator -( ) const; + + // Multiply a 4x4 matrix by a scalar + // + inline const Matrix4 operator *( float scalar ) const; + + // Multiply a 4x4 matrix by a 4-D vector + // + inline const Vector4 operator *( const Vector4 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D vector + // + inline const Vector4 operator *( const Vector3 & vec ) const; + + // Multiply a 4x4 matrix by a 3-D point + // + inline const Vector4 operator *( const Point3 & pnt ) const; + + // Multiply two 4x4 matrices + // + inline const Matrix4 operator *( const Matrix4 & mat ) const; + + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + inline const Matrix4 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and addition with a 4x4 matrix + // + inline Matrix4 & operator +=( const Matrix4 & mat ); + + // Perform compound assignment and subtraction by a 4x4 matrix + // + inline Matrix4 & operator -=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + inline Matrix4 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a 4x4 matrix + // + inline Matrix4 & operator *=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Matrix4 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 4x4 matrix + // + static inline const Matrix4 identity( ); + + // Construct a 4x4 matrix to rotate around the x axis + // + static inline const Matrix4 rotationX( float radians ); + + // Construct a 4x4 matrix to rotate around the y axis + // + static inline const Matrix4 rotationY( float radians ); + + // Construct a 4x4 matrix to rotate around the z axis + // + static inline const Matrix4 rotationZ( float radians ); + + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix4 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix4 rotation( const Quat & unitQuat ); + + // Construct a 4x4 matrix to perform scaling + // + static inline const Matrix4 scale( const Vector3 & scaleVec ); + + // Construct a 4x4 matrix to perform translation + // + static inline const Matrix4 translation( const Vector3 & translateVec ); + + // Construct viewing matrix based on eye position, position looked at, and up direction + // + static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); + + // Construct a perspective projection matrix + // + static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + + // Construct a perspective projection matrix based on frustum + // + static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); + + // Construct an orthographic projection matrix + // + static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + +}; +// Multiply a 4x4 matrix by a scalar +// +inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); + +// Append (post-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); + +// Multiply two 4x4 matrices per element +// +inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); + +// Compute the absolute value of a 4x4 matrix per element +// +inline const Matrix4 absPerElem( const Matrix4 & mat ); + +// Transpose of a 4x4 matrix +// +inline const Matrix4 transpose( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 inverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. +// +inline const Matrix4 affineInverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. +// +inline const Matrix4 orthoInverse( const Matrix4 & mat ); + +// Determinant of a 4x4 matrix +// +inline float determinant( const Matrix4 & mat ); + +// Conditionally select between two 4x4 matrices +// +inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4x4 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat ); + +// Print a 4x4 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Matrix4 & mat, const char * name ); + +#endif + +// A 3x4 transformation matrix in array-of-structures format +// +class Transform3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; + +public: + // Default constructor; does no initialization + // + inline Transform3( ) { }; + + // Copy a 3x4 transformation matrix + // + inline Transform3( const Transform3 & tfrm ); + + // Construct a 3x4 transformation matrix containing the specified columns + // + inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); + + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); + + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit inline Transform3( float scalar ); + + // Assign one 3x4 transformation matrix to another + // + inline Transform3 & operator =( const Transform3 & tfrm ); + + // Set the upper-left 3x3 submatrix + // + inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + inline const Matrix3 getUpper3x3( ) const; + + // Set translation component + // + inline Transform3 & setTranslation( const Vector3 & translateVec ); + + // Get the translation component of a 3x4 transformation matrix + // + inline const Vector3 getTranslation( ) const; + + // Set column 0 of a 3x4 transformation matrix + // + inline Transform3 & setCol0( const Vector3 & col0 ); + + // Set column 1 of a 3x4 transformation matrix + // + inline Transform3 & setCol1( const Vector3 & col1 ); + + // Set column 2 of a 3x4 transformation matrix + // + inline Transform3 & setCol2( const Vector3 & col2 ); + + // Set column 3 of a 3x4 transformation matrix + // + inline Transform3 & setCol3( const Vector3 & col3 ); + + // Get column 0 of a 3x4 transformation matrix + // + inline const Vector3 getCol0( ) const; + + // Get column 1 of a 3x4 transformation matrix + // + inline const Vector3 getCol1( ) const; + + // Get column 2 of a 3x4 transformation matrix + // + inline const Vector3 getCol2( ) const; + + // Get column 3 of a 3x4 transformation matrix + // + inline const Vector3 getCol3( ) const; + + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setCol( int col, const Vector3 & vec ); + + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 & setRow( int row, const Vector4 & vec ); + + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector3 getCol( int col ) const; + + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + inline Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + inline const Vector3 operator []( int col ) const; + + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + inline Transform3 & setElem( int col, int row, float val ); + + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + inline float getElem( int col, int row ) const; + + // Multiply a 3x4 transformation matrix by a 3-D vector + // + inline const Vector3 operator *( const Vector3 & vec ) const; + + // Multiply a 3x4 transformation matrix by a 3-D point + // + inline const Point3 operator *( const Point3 & pnt ) const; + + // Multiply two 3x4 transformation matrices + // + inline const Transform3 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Transform3 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 3x4 transformation matrix + // + static inline const Transform3 identity( ); + + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static inline const Transform3 rotationX( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static inline const Transform3 rotationY( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static inline const Transform3 rotationZ( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static inline const Transform3 rotation( float radians, const Vector3 & unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Transform3 rotation( const Quat & unitQuat ); + + // Construct a 3x4 transformation matrix to perform scaling + // + static inline const Transform3 scale( const Vector3 & scaleVec ); + + // Construct a 3x4 transformation matrix to perform translation + // + static inline const Transform3 translation( const Vector3 & translateVec ); + +}; +// Append (post-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); + +// Multiply two 3x4 transformation matrices per element +// +inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); + +// Compute the absolute value of a 3x4 transformation matrix per element +// +inline const Transform3 absPerElem( const Transform3 & tfrm ); + +// Inverse of a 3x4 transformation matrix +// NOTE: +// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. +// +inline const Transform3 inverse( const Transform3 & tfrm ); + +// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. +// +inline const Transform3 orthoInverse( const Transform3 & tfrm ); + +// Conditionally select between two 3x4 transformation matrices +// +inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x4 transformation matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm ); + +// Print a 3x4 transformation matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +inline void print( const Transform3 & tfrm, const char * name ); + +#endif + +} // namespace Aos +} // namespace Vectormath + +#include "vec_aos.h" +#include "quat_aos.h" +#include "mat_aos.h" + +#endif diff --git a/src/vectormath/sse/boolInVec.h b/src/vectormath/sse/boolInVec.h new file mode 100644 index 0000000..d21d25c --- /dev/null +++ b/src/vectormath/sse/boolInVec.h @@ -0,0 +1,247 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _BOOLINVEC_H +#define _BOOLINVEC_H + +#include + +namespace Vectormath { + +class floatInVec; + +//-------------------------------------------------------------------------------------------------- +// boolInVec class +// + +class boolInVec +{ + private: + __m128 mData; + + inline boolInVec(__m128 vec); + public: + inline boolInVec() {} + + // matches standard type conversions + // + inline boolInVec(const floatInVec &vec); + + // explicit cast from bool + // + explicit inline boolInVec(bool scalar); + +#ifdef _VECTORMATH_NO_SCALAR_CAST + // explicit cast to bool + // + inline bool getAsBool() const; +#else + // implicit cast to bool + // + inline operator bool() const; +#endif + + // get vector data + // bool value is splatted across all word slots of vector as 0 (false) or -1 (true) + // + inline __m128 get128() const; + + // operators + // + inline const boolInVec operator ! () const; + inline boolInVec& operator = (const boolInVec &vec); + inline boolInVec& operator &= (const boolInVec &vec); + inline boolInVec& operator ^= (const boolInVec &vec); + inline boolInVec& operator |= (const boolInVec &vec); + + // friend functions + // + friend inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); +}; + +//-------------------------------------------------------------------------------------------------- +// boolInVec functions +// + +// operators +// +inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); + +// select between vec0 and vec1 using boolInVec. +// false selects vec0, true selects vec1 +// +inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); + +} // namespace Vectormath + +//-------------------------------------------------------------------------------------------------- +// boolInVec implementation +// + +#include "floatInVec.h" + +namespace Vectormath { + +inline +boolInVec::boolInVec(__m128 vec) +{ + mData = vec; +} + +inline +boolInVec::boolInVec(const floatInVec &vec) +{ + *this = (vec != floatInVec(0.0f)); +} + +inline +boolInVec::boolInVec(bool scalar) +{ + unsigned int mask = -(int)scalar; + mData = _mm_set1_ps(*(float *)&mask); // TODO: Union +} + +#ifdef _VECTORMATH_NO_SCALAR_CAST +inline +bool +boolInVec::getAsBool() const +#else +inline +boolInVec::operator bool() const +#endif +{ + return *(bool *)&mData; +} + +inline +__m128 +boolInVec::get128() const +{ + return mData; +} + +inline +const boolInVec +boolInVec::operator ! () const +{ + return boolInVec(_mm_andnot_ps(mData, _mm_cmpneq_ps(_mm_setzero_ps(),_mm_setzero_ps()))); +} + +inline +boolInVec& +boolInVec::operator = (const boolInVec &vec) +{ + mData = vec.mData; + return *this; +} + +inline +boolInVec& +boolInVec::operator &= (const boolInVec &vec) +{ + *this = *this & vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator ^= (const boolInVec &vec) +{ + *this = *this ^ vec; + return *this; +} + +inline +boolInVec& +boolInVec::operator |= (const boolInVec &vec) +{ + *this = *this | vec; + return *this; +} + +inline +const boolInVec +operator == (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator != (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator & (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_and_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator | (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_or_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator ^ (const boolInVec &vec0, const boolInVec &vec1) +{ + return boolInVec(_mm_xor_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1) +{ + return boolInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); +} + +} // namespace Vectormath + +#endif // boolInVec_h diff --git a/src/vectormath/sse/floatInVec.h b/src/vectormath/sse/floatInVec.h new file mode 100644 index 0000000..e8ac595 --- /dev/null +++ b/src/vectormath/sse/floatInVec.h @@ -0,0 +1,340 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _FLOATINVEC_H +#define _FLOATINVEC_H + +#include +#include + +namespace Vectormath { + +class boolInVec; + +//-------------------------------------------------------------------------------------------------- +// floatInVec class +// + +class floatInVec +{ + private: + __m128 mData; + + public: + inline floatInVec(__m128 vec); + + inline floatInVec() {} + + // matches standard type conversions + // + inline floatInVec(const boolInVec &vec); + + // construct from a slot of __m128 + // + inline floatInVec(__m128 vec, int slot); + + // explicit cast from float + // + explicit inline floatInVec(float scalar); + +#ifdef _VECTORMATH_NO_SCALAR_CAST + // explicit cast to float + // + inline float getAsFloat() const; +#else + // implicit cast to float + // + inline operator float() const; +#endif + + // get vector data + // float value is splatted across all word slots of vector + // + inline __m128 get128() const; + + // operators + // + inline const floatInVec operator ++ (int); + inline const floatInVec operator -- (int); + inline floatInVec& operator ++ (); + inline floatInVec& operator -- (); + inline const floatInVec operator - () const; + inline floatInVec& operator = (const floatInVec &vec); + inline floatInVec& operator *= (const floatInVec &vec); + inline floatInVec& operator /= (const floatInVec &vec); + inline floatInVec& operator += (const floatInVec &vec); + inline floatInVec& operator -= (const floatInVec &vec); + + // friend functions + // + friend inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, boolInVec select_vec1); +}; + +//-------------------------------------------------------------------------------------------------- +// floatInVec functions +// + +// operators +// +inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); + +// select between vec0 and vec1 using boolInVec. +// false selects vec0, true selects vec1 +// +inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1); + +} // namespace Vectormath + +//-------------------------------------------------------------------------------------------------- +// floatInVec implementation +// + +#include "boolInVec.h" + +namespace Vectormath { + +inline +floatInVec::floatInVec(__m128 vec) +{ + mData = vec; +} + +inline +floatInVec::floatInVec(const boolInVec &vec) +{ + mData = vec_sel(_mm_setzero_ps(), _mm_set1_ps(1.0f), vec.get128()); +} + +inline +floatInVec::floatInVec(__m128 vec, int slot) +{ + SSEFloat v; + v.m128 = vec; + mData = _mm_set1_ps(v.f[slot]); +} + +inline +floatInVec::floatInVec(float scalar) +{ + mData = _mm_set1_ps(scalar); +} + +#ifdef _VECTORMATH_NO_SCALAR_CAST +inline +float +floatInVec::getAsFloat() const +#else +inline +floatInVec::operator float() const +#endif +{ + return *((float *)&mData); +} + +inline +__m128 +floatInVec::get128() const +{ + return mData; +} + +inline +const floatInVec +floatInVec::operator ++ (int) +{ + __m128 olddata = mData; + operator ++(); + return floatInVec(olddata); +} + +inline +const floatInVec +floatInVec::operator -- (int) +{ + __m128 olddata = mData; + operator --(); + return floatInVec(olddata); +} + +inline +floatInVec& +floatInVec::operator ++ () +{ + *this += floatInVec(_mm_set1_ps(1.0f)); + return *this; +} + +inline +floatInVec& +floatInVec::operator -- () +{ + *this -= floatInVec(_mm_set1_ps(1.0f)); + return *this; +} + +inline +const floatInVec +floatInVec::operator - () const +{ + return floatInVec(_mm_sub_ps(_mm_setzero_ps(), mData)); +} + +inline +floatInVec& +floatInVec::operator = (const floatInVec &vec) +{ + mData = vec.mData; + return *this; +} + +inline +floatInVec& +floatInVec::operator *= (const floatInVec &vec) +{ + *this = *this * vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator /= (const floatInVec &vec) +{ + *this = *this / vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator += (const floatInVec &vec) +{ + *this = *this + vec; + return *this; +} + +inline +floatInVec& +floatInVec::operator -= (const floatInVec &vec) +{ + *this = *this - vec; + return *this; +} + +inline +const floatInVec +operator * (const floatInVec &vec0, const floatInVec &vec1) +{ + return floatInVec(_mm_mul_ps(vec0.get128(), vec1.get128())); +} + +inline +const floatInVec +operator / (const floatInVec &num, const floatInVec &den) +{ + return floatInVec(_mm_div_ps(num.get128(), den.get128())); +} + +inline +const floatInVec +operator + (const floatInVec &vec0, const floatInVec &vec1) +{ + return floatInVec(_mm_add_ps(vec0.get128(), vec1.get128())); +} + +inline +const floatInVec +operator - (const floatInVec &vec0, const floatInVec &vec1) +{ + return floatInVec(_mm_sub_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator < (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpgt_ps(vec1.get128(), vec0.get128())); +} + +inline +const boolInVec +operator <= (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpge_ps(vec1.get128(), vec0.get128())); +} + +inline +const boolInVec +operator > (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpgt_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator >= (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpge_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator == (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); +} + +inline +const boolInVec +operator != (const floatInVec &vec0, const floatInVec &vec1) +{ + return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); +} + +inline +const floatInVec +select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1) +{ + return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); +} + +} // namespace Vectormath + +#endif // floatInVec_h diff --git a/src/vectormath/sse/mat_aos.h b/src/vectormath/sse/mat_aos.h new file mode 100644 index 0000000..a2c66cc --- /dev/null +++ b/src/vectormath/sse/mat_aos.h @@ -0,0 +1,2190 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _VECTORMATH_MAT_AOS_CPP_H +#define _VECTORMATH_MAT_AOS_CPP_H + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// Constants +// for shuffles, words are labeled [x,y,z,w] [a,b,c,d] + +#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }) +#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D }) +#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C }) +#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z }) +#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D }) +#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y }) +#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C }) +#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) +#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B }) +#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C }) +#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PI_OVER_2 1.570796327f + +//----------------------------------------------------------------------------- +// Definitions + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const floatInVec &scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Quat &unitQuat ) +{ + __m128 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + VM_ATTRIBUTE_ALIGN16 unsigned int sx[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int sz[4] = {0, 0, 0xffffffff, 0}; + __m128 select_x = _mm_load_ps((float *)sx); + __m128 select_z = _mm_load_ps((float *)sz); + + xyzw_2 = _mm_add_ps( unitQuat.get128(), unitQuat.get128() ); + wwww = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,3,3,3) ); + yzxw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,0,2,1) ); + zxyw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,1,0,2) ); + yzxw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,0,2,1) ); + zxyw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,1,0,2) ); + + tmp0 = _mm_mul_ps( yzxw_2, wwww ); // tmp0 = 2yw, 2zw, 2xw, 2w2 + tmp1 = _mm_sub_ps( _mm_set1_ps(1.0f), _mm_mul_ps(yzxw, yzxw_2) ); // tmp1 = 1 - 2y2, 1 - 2z2, 1 - 2x2, 1 - 2w2 + tmp2 = _mm_mul_ps( yzxw, xyzw_2 ); // tmp2 = 2xy, 2yz, 2xz, 2w2 + tmp0 = _mm_add_ps( _mm_mul_ps(zxyw, xyzw_2), tmp0 ); // tmp0 = 2yw + 2zx, 2zw + 2xy, 2xw + 2yz, 2w2 + 2w2 + tmp1 = _mm_sub_ps( tmp1, _mm_mul_ps(zxyw, zxyw_2) ); // tmp1 = 1 - 2y2 - 2z2, 1 - 2z2 - 2x2, 1 - 2x2 - 2y2, 1 - 2w2 - 2w2 + tmp2 = _mm_sub_ps( tmp2, _mm_mul_ps(zxyw_2, wwww) ); // tmp2 = 2xy - 2zw, 2yz - 2xw, 2xz - 2yw, 2w2 -2w2 + + tmp3 = vec_sel( tmp0, tmp1, select_x ); + tmp4 = vec_sel( tmp1, tmp2, select_x ); + tmp5 = vec_sel( tmp2, tmp0, select_x ); + mCol0 = Vector3( vec_sel( tmp3, tmp2, select_z ) ); + mCol1 = Vector3( vec_sel( tmp4, tmp0, select_z ) ); + mCol2 = Vector3( vec_sel( tmp5, tmp1, select_z ) ); +} + +VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol0( const Vector3 &_col0 ) +{ + mCol0 = _col0; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol1( const Vector3 &_col1 ) +{ + mCol1 = _col1; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol2( const Vector3 &_col2 ) +{ + mCol2 = _col2; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol( int col, const Vector3 &vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setRow( int row, const Vector3 &vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setElem( int col, int row, float val ) +{ + (*this)[col].setElem(row, val); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setElem( int col, int row, const floatInVec &val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Matrix3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol0( ) const +{ + return mCol0; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol1( ) const +{ + return mCol1; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol2( ) const +{ + return mCol2; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getRow( int row ) const +{ + return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Matrix3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 transpose( const Matrix3 & mat ) +{ + __m128 tmp0, tmp1, res0, res1, res2; + tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); + res0 = vec_mergeh( tmp0, mat.getCol1().get128() ); + //res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + res1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + res1 = vec_sel(res1, mat.getCol1().get128(), select_y); + //res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + res2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + res2 = vec_sel(res2, vec_splat(mat.getCol1().get128(), 2), select_y); + return Matrix3( + Vector3( res0 ), + Vector3( res1 ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 inverse( const Matrix3 & mat ) +{ + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; + tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() ); + tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() ); + tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() ); + dot = _vmathVfDot3( tmp2, mat.getCol2().get128() ); + dot = vec_splat( dot, 0 ); + invdet = recipf4( dot ); + tmp3 = vec_mergeh( tmp0, tmp2 ); + tmp4 = vec_mergel( tmp0, tmp2 ); + inv0 = vec_mergeh( tmp3, tmp1 ); + //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); + inv1 = vec_sel(inv1, tmp1, select_y); + //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); + inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); + inv0 = vec_mul( inv0, invdet ); + inv1 = vec_mul( inv1, invdet ); + inv2 = vec_mul( inv2, invdet ); + return Matrix3( + Vector3( inv0 ), + Vector3( inv1 ), + Vector3( inv2 ) + ); +} + +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix3 & mat ) +{ + return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +{ + return Matrix3( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +{ + *this = *this + mat; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +{ + *this = *this - mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator -( ) const +{ + return Matrix3( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 absPerElem( const Matrix3 & mat ) +{ + return Matrix3( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( const floatInVec &scalar ) const +{ + return Matrix3( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( float scalar ) +{ + return *this *= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar, const Matrix3 & mat ) +{ + return floatInVec(scalar) * mat; +} + +VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ) +{ + return mat * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator *( const Vector3 &vec ) const +{ + __m128 res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat( vec.get128(), 0 ); + yyyy = vec_splat( vec.get128(), 1 ); + zzzz = vec_splat( vec.get128(), 2 ); + res = vec_mul( mCol0.get128(), xxxx ); + res = vec_madd( mCol1.get128(), yyyy, res ); + res = vec_madd( mCol2.get128(), zzzz, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +{ + return Matrix3( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +{ + *this = *this * mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +{ + return Matrix3( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::identity( ) +{ + return Matrix3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX( const floatInVec &radians ) +{ + __m128 s, c, res1, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res1 = vec_sel( zero, c, select_y ); + res1 = vec_sel( res1, s, select_z ); + res2 = vec_sel( zero, negatef4(s), select_y ); + res2 = vec_sel( res2, c, select_z ); + return Matrix3( + Vector3::xAxis( ), + Vector3( res1 ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY( const floatInVec &radians ) +{ + __m128 s, c, res0, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, negatef4(s), select_z ); + res2 = vec_sel( zero, s, select_x ); + res2 = vec_sel( res2, c, select_z ); + return Matrix3( + Vector3( res0 ), + Vector3::yAxis( ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, res0, res1; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, s, select_y ); + res1 = vec_sel( zero, negatef4(s), select_x ); + res1 = vec_sel( res1, c, select_y ); + return Matrix3( + Vector3( res0 ), + Vector3( res1 ), + Vector3::zAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZYX( const Vector3 &radiansXYZ ) +{ + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4( radiansXYZ, 0.0f ).get128(); + sincosf4( angles, &s, &c ); + negS = negatef4( s ); + Z0 = vec_mergel( c, s ); + Z1 = vec_mergel( negS, c ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); + Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); + Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); + X0 = vec_splat( s, 0 ); + X1 = vec_splat( c, 0 ); + tmp = vec_mul( Z0, Y1 ); + return Matrix3( + Vector3( vec_mul( Z0, Y0 ) ), + Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), + Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; + axis = unitVec.get128(); + sincosf4( radians.get128(), &s, &c ); + xxxx = vec_splat( axis, 0 ); + yyyy = vec_splat( axis, 1 ); + zzzz = vec_splat( axis, 2 ); + oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); + axisS = vec_mul( axis, s ); + negAxisS = negatef4( axisS ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); + tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); + tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); + //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); + tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); + //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); + tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); + tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); + tmp0 = vec_sel( tmp0, c, select_x ); + tmp1 = vec_sel( tmp1, c, select_y ); + tmp2 = vec_sel( tmp2, c, select_z ); + return Matrix3( + Vector3( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), + Vector3( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), + Vector3( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( const Quat &unitQuat ) +{ + return Matrix3( unitQuat ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::scale( const Vector3 &scaleVec ) +{ + __m128 zero = _mm_setzero_ps(); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + return Matrix3( + Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ) +{ + return Matrix3( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ) +{ + return Matrix3( + mulPerElem( mat.getCol0(), scaleVec ), + mulPerElem( mat.getCol1(), scaleVec ), + mulPerElem( mat.getCol2(), scaleVec ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ) +{ + return Matrix3( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); +} + +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( float scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const floatInVec &scalar ) +{ + mCol0 = Vector4( scalar ); + mCol1 = Vector4( scalar ); + mCol2 = Vector4( scalar ); + mCol3 = Vector4( scalar ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Transform3 & mat ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( mat.getCol3(), 1.0f ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Matrix3 & mat, const Vector3 &translateVec ) +{ + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Quat &unitQuat, const Vector3 &translateVec ) +{ + Matrix3 mat; + mat = Matrix3( unitQuat ); + mCol0 = Vector4( mat.getCol0(), 0.0f ); + mCol1 = Vector4( mat.getCol1(), 0.0f ); + mCol2 = Vector4( mat.getCol2(), 0.0f ); + mCol3 = Vector4( translateVec, 1.0f ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol0( const Vector4 &_col0 ) +{ + mCol0 = _col0; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol1( const Vector4 &_col1 ) +{ + mCol1 = _col1; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol2( const Vector4 &_col2 ) +{ + mCol2 = _col2; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol3( const Vector4 &_col3 ) +{ + mCol3 = _col3; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol( int col, const Vector4 &vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setRow( int row, const Vector4 &vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setElem( int col, int row, float val ) +{ + (*this)[col].setElem(row, val); + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setElem( int col, int row, const floatInVec &val ) +{ + Vector4 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Matrix4::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol0( ) const +{ + return mCol0; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol1( ) const +{ + return mCol1; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol2( ) const +{ + return mCol2; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol3( ) const +{ + return mCol3; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Matrix4::operator []( int col ) +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +{ + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 transpose( const Matrix4 & mat ) +{ + __m128 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; + tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp1 = vec_mergeh( mat.getCol1().get128(), mat.getCol3().get128() ); + tmp2 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp3 = vec_mergel( mat.getCol1().get128(), mat.getCol3().get128() ); + res0 = vec_mergeh( tmp0, tmp1 ); + res1 = vec_mergel( tmp0, tmp1 ); + res2 = vec_mergeh( tmp2, tmp3 ); + res3 = vec_mergel( tmp2, tmp3 ); + return Matrix4( + Vector4( res0 ), + Vector4( res1 ), + Vector4( res2 ), + Vector4( res3 ) + ); +} + +// TODO: Tidy +static VM_ATTRIBUTE_ALIGN16 const unsigned int _vmathPNPN[4] = {0x00000000, 0x80000000, 0x00000000, 0x80000000}; +static VM_ATTRIBUTE_ALIGN16 const unsigned int _vmathNPNP[4] = {0x80000000, 0x00000000, 0x80000000, 0x00000000}; +static VM_ATTRIBUTE_ALIGN16 const float _vmathZERONE[4] = {1.0f, 0.0f, 0.0f, 1.0f}; + +VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ) +{ + __m128 Va,Vb,Vc; + __m128 r1,r2,r3,tt,tt2; + __m128 sum,Det,RDet; + __m128 trns0,trns1,trns2,trns3; + + __m128 _L1 = mat.getCol0().get128(); + __m128 _L2 = mat.getCol1().get128(); + __m128 _L3 = mat.getCol2().get128(); + __m128 _L4 = mat.getCol3().get128(); + // Calculating the minterms for the first line. + + // _mm_ror_ps is just a macro using _mm_shuffle_ps(). + tt = _L4; tt2 = _mm_ror_ps(_L3,1); + Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3'dot V4 + Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3'dot V4" + Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3' dot V4^ + + r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4" + r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^ + r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4' + + tt = _L2; + Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); + Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); + Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); + + // Calculating the determinant. + Det = _mm_mul_ps(sum,_L1); + Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); + + const __m128 Sign_PNPN = _mm_load_ps((float *)_vmathPNPN); + const __m128 Sign_NPNP = _mm_load_ps((float *)_vmathNPNP); + + __m128 mtL1 = _mm_xor_ps(sum,Sign_PNPN); + + // Calculating the minterms of the second line (using previous results). + tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + __m128 mtL2 = _mm_xor_ps(sum,Sign_NPNP); + + // Testing the determinant. + Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); + + // Calculating the minterms of the third line. + tt = _mm_ror_ps(_L1,1); + Va = _mm_mul_ps(tt,Vb); // V1' dot V2" + Vb = _mm_mul_ps(tt,Vc); // V1' dot V2^ + Vc = _mm_mul_ps(tt,_L2); // V1' dot V2 + + r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V1" dot V2^ - V1^ dot V2" + r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V1^ dot V2' - V1' dot V2^ + r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V1' dot V2" - V1" dot V2' + + tt = _mm_ror_ps(_L4,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + __m128 mtL3 = _mm_xor_ps(sum,Sign_PNPN); + + // Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs). + RDet = _mm_div_ss(_mm_load_ss((float *)&_vmathZERONE), Det); // TODO: just 1.0f? + RDet = _mm_shuffle_ps(RDet,RDet,0x00); + + // Devide the first 12 minterms with the determinant. + mtL1 = _mm_mul_ps(mtL1, RDet); + mtL2 = _mm_mul_ps(mtL2, RDet); + mtL3 = _mm_mul_ps(mtL3, RDet); + + // Calculate the minterms of the forth line and devide by the determinant. + tt = _mm_ror_ps(_L3,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + __m128 mtL4 = _mm_xor_ps(sum,Sign_NPNP); + mtL4 = _mm_mul_ps(mtL4, RDet); + + // Now we just have to transpose the minterms matrix. + trns0 = _mm_unpacklo_ps(mtL1,mtL2); + trns1 = _mm_unpacklo_ps(mtL3,mtL4); + trns2 = _mm_unpackhi_ps(mtL1,mtL2); + trns3 = _mm_unpackhi_ps(mtL3,mtL4); + _L1 = _mm_movelh_ps(trns0,trns1); + _L2 = _mm_movehl_ps(trns1,trns0); + _L3 = _mm_movelh_ps(trns2,trns3); + _L4 = _mm_movehl_ps(trns3,trns2); + + return Matrix4( + Vector4( _L1 ), + Vector4( _L2 ), + Vector4( _L3 ), + Vector4( _L4 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 affineInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( inverse( affineMat ) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse( const Matrix4 & mat ) +{ + Transform3 affineMat; + affineMat.setCol0( mat.getCol0().getXYZ( ) ); + affineMat.setCol1( mat.getCol1().getXYZ( ) ); + affineMat.setCol2( mat.getCol2().getXYZ( ) ); + affineMat.setCol3( mat.getCol3().getXYZ( ) ); + return Matrix4( orthoInverse( affineMat ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat ) +{ + __m128 Va,Vb,Vc; + __m128 r1,r2,r3,tt,tt2; + __m128 sum,Det; + + __m128 _L1 = mat.getCol0().get128(); + __m128 _L2 = mat.getCol1().get128(); + __m128 _L3 = mat.getCol2().get128(); + __m128 _L4 = mat.getCol3().get128(); + // Calculating the minterms for the first line. + + // _mm_ror_ps is just a macro using _mm_shuffle_ps(). + tt = _L4; tt2 = _mm_ror_ps(_L3,1); + Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3' dot V4 + Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3' dot V4" + Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3' dot V4^ + + r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4" + r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^ + r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4' + + tt = _L2; + Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); + Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); + Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); + + // Calculating the determinant. + Det = _mm_mul_ps(sum,_L1); + Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); + + // Calculating the minterms of the second line (using previous results). + tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); + tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + + // Testing the determinant. + Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); + return floatInVec(Det, 0); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 + mat.mCol0 ), + ( mCol1 + mat.mCol1 ), + ( mCol2 + mat.mCol2 ), + ( mCol3 + mat.mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +{ + return Matrix4( + ( mCol0 - mat.mCol0 ), + ( mCol1 - mat.mCol1 ), + ( mCol2 - mat.mCol2 ), + ( mCol3 - mat.mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +{ + *this = *this + mat; + return *this; +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +{ + *this = *this - mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator -( ) const +{ + return Matrix4( + ( -mCol0 ), + ( -mCol1 ), + ( -mCol2 ), + ( -mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 absPerElem( const Matrix4 & mat ) +{ + return Matrix4( + absPerElem( mat.getCol0() ), + absPerElem( mat.getCol1() ), + absPerElem( mat.getCol2() ), + absPerElem( mat.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const floatInVec &scalar ) const +{ + return Matrix4( + ( mCol0 * scalar ), + ( mCol1 * scalar ), + ( mCol2 * scalar ), + ( mCol3 * scalar ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( float scalar ) +{ + return *this *= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar, const Matrix4 & mat ) +{ + return floatInVec(scalar) * mat; +} + +VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ) +{ + return mat * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Vector4 &vec ) const +{ + return Vector4( + _mm_add_ps( + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))), + _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2))), _mm_mul_ps(mCol3.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(3,3,3,3))))) + ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Vector3 &vec ) const +{ + return Vector4( + _mm_add_ps( + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))), + _mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2)))) + ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Point3 &pnt ) const +{ + return Vector4( + _mm_add_ps( + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(1,1,1,1)))), + _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(2,2,2,2))), mCol3.get128())) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +{ + return Matrix4( + ( *this * mat.mCol0 ), + ( *this * mat.mCol1 ), + ( *this * mat.mCol2 ), + ( *this * mat.mCol3 ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +{ + *this = *this * mat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +{ + return Matrix4( + ( *this * tfrm.getCol0() ), + ( *this * tfrm.getCol1() ), + ( *this * tfrm.getCol2() ), + ( *this * Point3( tfrm.getCol3() ) ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +{ + return Matrix4( + mulPerElem( mat0.getCol0(), mat1.getCol0() ), + mulPerElem( mat0.getCol1(), mat1.getCol1() ), + mulPerElem( mat0.getCol2(), mat1.getCol2() ), + mulPerElem( mat0.getCol3(), mat1.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::identity( ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +{ + mCol0.setXYZ( mat3.getCol0() ); + mCol1.setXYZ( mat3.getCol1() ); + mCol2.setXYZ( mat3.getCol2() ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 Matrix4::getUpper3x3( ) const +{ + return Matrix3( + mCol0.getXYZ( ), + mCol1.getXYZ( ), + mCol2.getXYZ( ) + ); +} + +VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setTranslation( const Vector3 &translateVec ) +{ + mCol3.setXYZ( translateVec ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Matrix4::getTranslation( ) const +{ + return mCol3.getXYZ( ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX( const floatInVec &radians ) +{ + __m128 s, c, res1, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res1 = vec_sel( zero, c, select_y ); + res1 = vec_sel( res1, s, select_z ); + res2 = vec_sel( zero, negatef4(s), select_y ); + res2 = vec_sel( res2, c, select_z ); + return Matrix4( + Vector4::xAxis( ), + Vector4( res1 ), + Vector4( res2 ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY( const floatInVec &radians ) +{ + __m128 s, c, res0, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, negatef4(s), select_z ); + res2 = vec_sel( zero, s, select_x ); + res2 = vec_sel( res2, c, select_z ); + return Matrix4( + Vector4( res0 ), + Vector4::yAxis( ), + Vector4( res2 ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, res0, res1; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, s, select_y ); + res1 = vec_sel( zero, negatef4(s), select_x ); + res1 = vec_sel( res1, c, select_y ); + return Matrix4( + Vector4( res0 ), + Vector4( res1 ), + Vector4::zAxis( ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZYX( const Vector3 &radiansXYZ ) +{ + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4( radiansXYZ, 0.0f ).get128(); + sincosf4( angles, &s, &c ); + negS = negatef4( s ); + Z0 = vec_mergel( c, s ); + Z1 = vec_mergel( negS, c ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); + Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); + Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); + X0 = vec_splat( s, 0 ); + X1 = vec_splat( c, 0 ); + tmp = vec_mul( Z0, Y1 ); + return Matrix4( + Vector4( vec_mul( Z0, Y0 ) ), + Vector4( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), + Vector4( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; + axis = unitVec.get128(); + sincosf4( radians.get128(), &s, &c ); + xxxx = vec_splat( axis, 0 ); + yyyy = vec_splat( axis, 1 ); + zzzz = vec_splat( axis, 2 ); + oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); + axisS = vec_mul( axis, s ); + negAxisS = negatef4( axisS ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); + tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); + tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); + //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); + tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); + //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); + tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); + tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); + tmp0 = vec_sel( tmp0, c, select_x ); + tmp1 = vec_sel( tmp1, c, select_y ); + tmp2 = vec_sel( tmp2, c, select_z ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + axis = vec_and( axis, _mm_load_ps( (float *)select_xyz ) ); + tmp0 = vec_and( tmp0, _mm_load_ps( (float *)select_xyz ) ); + tmp1 = vec_and( tmp1, _mm_load_ps( (float *)select_xyz ) ); + tmp2 = vec_and( tmp2, _mm_load_ps( (float *)select_xyz ) ); + return Matrix4( + Vector4( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), + Vector4( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), + Vector4( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( const Quat &unitQuat ) +{ + return Matrix4( Transform3::rotation( unitQuat ) ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::scale( const Vector3 &scaleVec ) +{ + __m128 zero = _mm_setzero_ps(); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + return Matrix4( + Vector4( vec_sel( zero, scaleVec.get128(), select_x ) ), + Vector4( vec_sel( zero, scaleVec.get128(), select_y ) ), + Vector4( vec_sel( zero, scaleVec.get128(), select_z ) ), + Vector4::wAxis( ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ) +{ + return Matrix4( + ( mat.getCol0() * scaleVec.getX( ) ), + ( mat.getCol1() * scaleVec.getY( ) ), + ( mat.getCol2() * scaleVec.getZ( ) ), + mat.getCol3() + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ) +{ + Vector4 scale4; + scale4 = Vector4( scaleVec, 1.0f ); + return Matrix4( + mulPerElem( mat.getCol0(), scale4 ), + mulPerElem( mat.getCol1(), scale4 ), + mulPerElem( mat.getCol2(), scale4 ), + mulPerElem( mat.getCol3(), scale4 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::translation( const Vector3 &translateVec ) +{ + return Matrix4( + Vector4::xAxis( ), + Vector4::yAxis( ), + Vector4::zAxis( ), + Vector4( translateVec, 1.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ) +{ + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize( upVec ); + v3Z = normalize( ( eyePos - lookAtPos ) ); + v3X = normalize( cross( v3Y, v3Z ) ); + v3Y = cross( v3Z, v3X ); + m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); + return orthoInverse( m4EyeFrame ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +{ + float f, rangeInv; + __m128 zero, col0, col1, col2, col3; + union { __m128 v; float s[4]; } tmp; + f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); + rangeInv = 1.0f / ( zNear - zFar ); + zero = _mm_setzero_ps(); + tmp.v = zero; + tmp.s[0] = f / aspect; + col0 = tmp.v; + tmp.v = zero; + tmp.s[1] = f; + col1 = tmp.v; + tmp.v = zero; + tmp.s[2] = ( zNear + zFar ) * rangeInv; + tmp.s[3] = -1.0f; + col2 = tmp.v; + tmp.v = zero; + tmp.s[2] = zNear * zFar * rangeInv * 2.0f; + col3 = tmp.v; + return Matrix4( + Vector4( col0 ), + Vector4( col1 ), + Vector4( col2 ), + Vector4( col3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + /* function implementation based on code from STIDC SDK: */ + /* -------------------------------------------------------------- */ + /* PLEASE DO NOT MODIFY THIS SECTION */ + /* This prolog section is automatically generated. */ + /* */ + /* (C)Copyright */ + /* Sony Computer Entertainment, Inc., */ + /* Toshiba Corporation, */ + /* International Business Machines Corporation, */ + /* 2001,2002. */ + /* S/T/I Confidential Information */ + /* -------------------------------------------------------------- */ + __m128 lbf, rtn; + __m128 diff, sum, inv_diff; + __m128 diagonal, column, near2; + __m128 zero = _mm_setzero_ps(); + union { __m128 v; float s[4]; } l, f, r, n, b, t; // TODO: Union? + l.s[0] = left; + f.s[0] = zFar; + r.s[0] = right; + n.s[0] = zNear; + b.s[0] = bottom; + t.s[0] = top; + lbf = vec_mergeh( l.v, f.v ); + rtn = vec_mergeh( r.v, n.v ); + lbf = vec_mergeh( lbf, b.v ); + rtn = vec_mergeh( rtn, t.v ); + diff = vec_sub( rtn, lbf ); + sum = vec_add( rtn, lbf ); + inv_diff = recipf4( diff ); + near2 = vec_splat( n.v, 0 ); + near2 = vec_add( near2, near2 ); + diagonal = vec_mul( near2, inv_diff ); + column = vec_mul( sum, inv_diff ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; + return Matrix4( + Vector4( vec_sel( zero, diagonal, select_x ) ), + Vector4( vec_sel( zero, diagonal, select_y ) ), + Vector4( vec_sel( column, _mm_set1_ps(-1.0f), select_w ) ), + Vector4( vec_sel( zero, vec_mul( diagonal, vec_splat( f.v, 0 ) ), select_z ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +{ + /* function implementation based on code from STIDC SDK: */ + /* -------------------------------------------------------------- */ + /* PLEASE DO NOT MODIFY THIS SECTION */ + /* This prolog section is automatically generated. */ + /* */ + /* (C)Copyright */ + /* Sony Computer Entertainment, Inc., */ + /* Toshiba Corporation, */ + /* International Business Machines Corporation, */ + /* 2001,2002. */ + /* S/T/I Confidential Information */ + /* -------------------------------------------------------------- */ + __m128 lbf, rtn; + __m128 diff, sum, inv_diff, neg_inv_diff; + __m128 diagonal, column; + __m128 zero = _mm_setzero_ps(); + union { __m128 v; float s[4]; } l, f, r, n, b, t; + l.s[0] = left; + f.s[0] = zFar; + r.s[0] = right; + n.s[0] = zNear; + b.s[0] = bottom; + t.s[0] = top; + lbf = vec_mergeh( l.v, f.v ); + rtn = vec_mergeh( r.v, n.v ); + lbf = vec_mergeh( lbf, b.v ); + rtn = vec_mergeh( rtn, t.v ); + diff = vec_sub( rtn, lbf ); + sum = vec_add( rtn, lbf ); + inv_diff = recipf4( diff ); + neg_inv_diff = negatef4( inv_diff ); + diagonal = vec_add( inv_diff, inv_diff ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; + column = vec_mul( sum, vec_sel( neg_inv_diff, inv_diff, select_z ) ); // TODO: no madds with zero + return Matrix4( + Vector4( vec_sel( zero, diagonal, select_x ) ), + Vector4( vec_sel( zero, diagonal, select_y ) ), + Vector4( vec_sel( zero, diagonal, select_z ) ), + Vector4( vec_sel( column, _mm_set1_ps(1.0f), select_w ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ) +{ + return Matrix4( + select( mat0.getCol0(), mat1.getCol0(), select1 ), + select( mat0.getCol1(), mat1.getCol1(), select1 ), + select( mat0.getCol2(), mat1.getCol2(), select1 ), + select( mat0.getCol3(), mat1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat ) +{ + print( mat.getRow( 0 ) ); + print( mat.getRow( 1 ) ); + print( mat.getRow( 2 ) ); + print( mat.getRow( 3 ) ); +} + +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name ) +{ + printf("%s:\n", name); + print( mat ); +} + +#endif + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( float scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const floatInVec &scalar ) +{ + mCol0 = Vector3( scalar ); + mCol1 = Vector3( scalar ); + mCol2 = Vector3( scalar ); + mCol3 = Vector3( scalar ); +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3 ) +{ + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ) +{ + this->setUpper3x3( tfrm ); + this->setTranslation( translateVec ); +} + +VECTORMATH_FORCE_INLINE Transform3::Transform3( const Quat &unitQuat, const Vector3 &translateVec ) +{ + this->setUpper3x3( Matrix3( unitQuat ) ); + this->setTranslation( translateVec ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol0( const Vector3 &_col0 ) +{ + mCol0 = _col0; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol1( const Vector3 &_col1 ) +{ + mCol1 = _col1; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol2( const Vector3 &_col2 ) +{ + mCol2 = _col2; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol3( const Vector3 &_col3 ) +{ + mCol3 = _col3; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol( int col, const Vector3 &vec ) +{ + *(&mCol0 + col) = vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setRow( int row, const Vector4 &vec ) +{ + mCol0.setElem( row, vec.getElem( 0 ) ); + mCol1.setElem( row, vec.getElem( 1 ) ); + mCol2.setElem( row, vec.getElem( 2 ) ); + mCol3.setElem( row, vec.getElem( 3 ) ); + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setElem( int col, int row, float val ) +{ + (*this)[col].setElem(row, val); + return *this; +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setElem( int col, int row, const floatInVec &val ) +{ + Vector3 tmpV3_0; + tmpV3_0 = this->getCol( col ); + tmpV3_0.setElem( row, val ); + this->setCol( col, tmpV3_0 ); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Transform3::getElem( int col, int row ) const +{ + return this->getCol( col ).getElem( row ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol0( ) const +{ + return mCol0; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol1( ) const +{ + return mCol1; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol2( ) const +{ + return mCol2; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol3( ) const +{ + return mCol3; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector4 Transform3::getRow( int row ) const +{ + return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Transform3::operator []( int col ) +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator []( int col ) const +{ + return *(&mCol0 + col); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::operator =( const Transform3 & tfrm ) +{ + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; +} + +VECTORMATH_FORCE_INLINE const Transform3 inverse( const Transform3 & tfrm ) +{ + __m128 inv0, inv1, inv2, inv3; + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; + __m128 xxxx, yyyy, zzzz; + tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() ); + tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() ); + tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() ); + inv3 = negatef4( tfrm.getCol3().get128() ); + dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() ); + dot = vec_splat( dot, 0 ); + invdet = recipf4( dot ); + tmp3 = vec_mergeh( tmp0, tmp2 ); + tmp4 = vec_mergel( tmp0, tmp2 ); + inv0 = vec_mergeh( tmp3, tmp1 ); + xxxx = vec_splat( inv3, 0 ); + //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); + inv1 = vec_sel(inv1, tmp1, select_y); + //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); + inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); + yyyy = vec_splat( inv3, 1 ); + zzzz = vec_splat( inv3, 2 ); + inv3 = vec_mul( inv0, xxxx ); + inv3 = vec_madd( inv1, yyyy, inv3 ); + inv3 = vec_madd( inv2, zzzz, inv3 ); + inv0 = vec_mul( inv0, invdet ); + inv1 = vec_mul( inv1, invdet ); + inv2 = vec_mul( inv2, invdet ); + inv3 = vec_mul( inv3, invdet ); + return Transform3( + Vector3( inv0 ), + Vector3( inv1 ), + Vector3( inv2 ), + Vector3( inv3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 orthoInverse( const Transform3 & tfrm ) +{ + __m128 inv0, inv1, inv2, inv3; + __m128 tmp0, tmp1; + __m128 xxxx, yyyy, zzzz; + tmp0 = vec_mergeh( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); + tmp1 = vec_mergel( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); + inv3 = negatef4( tfrm.getCol3().get128() ); + inv0 = vec_mergeh( tmp0, tfrm.getCol1().get128() ); + xxxx = vec_splat( inv3, 0 ); + //inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + inv1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + inv1 = vec_sel(inv1, tfrm.getCol1().get128(), select_y); + //inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + inv2 = vec_sel(inv2, vec_splat(tfrm.getCol1().get128(), 2), select_y); + yyyy = vec_splat( inv3, 1 ); + zzzz = vec_splat( inv3, 2 ); + inv3 = vec_mul( inv0, xxxx ); + inv3 = vec_madd( inv1, yyyy, inv3 ); + inv3 = vec_madd( inv2, zzzz, inv3 ); + return Transform3( + Vector3( inv0 ), + Vector3( inv1 ), + Vector3( inv2 ), + Vector3( inv3 ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 absPerElem( const Transform3 & tfrm ) +{ + return Transform3( + absPerElem( tfrm.getCol0() ), + absPerElem( tfrm.getCol1() ), + absPerElem( tfrm.getCol2() ), + absPerElem( tfrm.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator *( const Vector3 &vec ) const +{ + __m128 res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat( vec.get128(), 0 ); + yyyy = vec_splat( vec.get128(), 1 ); + zzzz = vec_splat( vec.get128(), 2 ); + res = vec_mul( mCol0.get128(), xxxx ); + res = vec_madd( mCol1.get128(), yyyy, res ); + res = vec_madd( mCol2.get128(), zzzz, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Point3 Transform3::operator *( const Point3 &pnt ) const +{ + __m128 tmp0, tmp1, res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat( pnt.get128(), 0 ); + yyyy = vec_splat( pnt.get128(), 1 ); + zzzz = vec_splat( pnt.get128(), 2 ); + tmp0 = vec_mul( mCol0.get128(), xxxx ); + tmp1 = vec_mul( mCol1.get128(), yyyy ); + tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 ); + tmp1 = vec_add( mCol3.get128(), tmp1 ); + res = vec_add( tmp0, tmp1 ); + return Point3( res ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +{ + return Transform3( + ( *this * tfrm.mCol0 ), + ( *this * tfrm.mCol1 ), + ( *this * tfrm.mCol2 ), + Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) + ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +{ + *this = *this * tfrm; + return *this; +} + +VECTORMATH_FORCE_INLINE const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +{ + return Transform3( + mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), + mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), + mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), + mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::identity( ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +{ + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; +} + +VECTORMATH_FORCE_INLINE const Matrix3 Transform3::getUpper3x3( ) const +{ + return Matrix3( mCol0, mCol1, mCol2 ); +} + +VECTORMATH_FORCE_INLINE Transform3 & Transform3::setTranslation( const Vector3 &translateVec ) +{ + mCol3 = translateVec; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getTranslation( ) const +{ + return mCol3; +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX( const floatInVec &radians ) +{ + __m128 s, c, res1, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res1 = vec_sel( zero, c, select_y ); + res1 = vec_sel( res1, s, select_z ); + res2 = vec_sel( zero, negatef4(s), select_y ); + res2 = vec_sel( res2, c, select_z ); + return Transform3( + Vector3::xAxis( ), + Vector3( res1 ), + Vector3( res2 ), + Vector3( _mm_setzero_ps() ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY( const floatInVec &radians ) +{ + __m128 s, c, res0, res2; + __m128 zero; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, negatef4(s), select_z ); + res2 = vec_sel( zero, s, select_x ); + res2 = vec_sel( res2, c, select_z ); + return Transform3( + Vector3( res0 ), + Vector3::yAxis( ), + Vector3( res2 ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, res0, res1; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + __m128 zero = _mm_setzero_ps(); + sincosf4( radians.get128(), &s, &c ); + res0 = vec_sel( zero, c, select_x ); + res0 = vec_sel( res0, s, select_y ); + res1 = vec_sel( zero, negatef4(s), select_x ); + res1 = vec_sel( res1, c, select_y ); + return Transform3( + Vector3( res0 ), + Vector3( res1 ), + Vector3::zAxis( ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZYX( const Vector3 &radiansXYZ ) +{ + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4( radiansXYZ, 0.0f ).get128(); + sincosf4( angles, &s, &c ); + negS = negatef4( s ); + Z0 = vec_mergel( c, s ); + Z1 = vec_mergel( negS, c ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; + Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); + Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); + Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); + X0 = vec_splat( s, 0 ); + X1 = vec_splat( c, 0 ); + tmp = vec_mul( Z0, Y1 ); + return Transform3( + Vector3( vec_mul( Z0, Y0 ) ), + Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), + Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( const Quat &unitQuat ) +{ + return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::scale( const Vector3 &scaleVec ) +{ + __m128 zero = _mm_setzero_ps(); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + return Transform3( + Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), + Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ), + Vector3( 0.0f ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ) +{ + return Transform3( + ( tfrm.getCol0() * scaleVec.getX( ) ), + ( tfrm.getCol1() * scaleVec.getY( ) ), + ( tfrm.getCol2() * scaleVec.getZ( ) ), + tfrm.getCol3() + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ) +{ + return Transform3( + mulPerElem( tfrm.getCol0(), scaleVec ), + mulPerElem( tfrm.getCol1(), scaleVec ), + mulPerElem( tfrm.getCol2(), scaleVec ), + mulPerElem( tfrm.getCol3(), scaleVec ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 Transform3::translation( const Vector3 &translateVec ) +{ + return Transform3( + Vector3::xAxis( ), + Vector3::yAxis( ), + Vector3::zAxis( ), + translateVec + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ) +{ + return Transform3( + select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), + select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), + select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), + select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) + ); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm ) +{ + print( tfrm.getRow( 0 ) ); + print( tfrm.getRow( 1 ) ); + print( tfrm.getRow( 2 ) ); +} + +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm, const char * name ) +{ + printf("%s:\n", name); + print( tfrm ); +} + +#endif + +VECTORMATH_FORCE_INLINE Quat::Quat( const Matrix3 & tfrm ) +{ + __m128 res; + __m128 col0, col1, col2; + __m128 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; + __m128 zy_xz_yx, yz_zx_xy, sum, diff; + __m128 radicand, invSqrt, scale; + __m128 res0, res1, res2, res3; + __m128 xx, yy, zz; + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; + + col0 = tfrm.getCol0().get128(); + col1 = tfrm.getCol1().get128(); + col2 = tfrm.getCol2().get128(); + + /* four cases: */ + /* trace > 0 */ + /* else */ + /* xx largest diagonal element */ + /* yy largest diagonal element */ + /* zz largest diagonal element */ + + /* compute quaternion for each case */ + + xx_yy = vec_sel( col0, col1, select_y ); + //xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX ); + //yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY ); + //zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC ); + xx_yy_zz_xx = _mm_shuffle_ps( xx_yy, xx_yy, _MM_SHUFFLE(0,0,1,0) ); + xx_yy_zz_xx = vec_sel( xx_yy_zz_xx, col2, select_z ); // TODO: Ck + yy_zz_xx_yy = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(1,0,2,1) ); + zz_xx_yy_zz = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(2,1,0,2) ); + + diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); + diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); + radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), _mm_set1_ps(1.0f) ); + // invSqrt = rsqrtf4( radicand ); + invSqrt = newtonrapson_rsqrt4( radicand ); + + + + zy_xz_yx = vec_sel( col0, col1, select_z ); // zy_xz_yx = 00 01 12 03 + //zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX ); + zy_xz_yx = _mm_shuffle_ps( zy_xz_yx, zy_xz_yx, _MM_SHUFFLE(0,1,2,2) ); // zy_xz_yx = 12 12 01 00 + zy_xz_yx = vec_sel( zy_xz_yx, vec_splat(col2, 0), select_y ); // zy_xz_yx = 12 20 01 00 + yz_zx_xy = vec_sel( col0, col1, select_x ); // yz_zx_xy = 10 01 02 03 + //yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX ); + yz_zx_xy = _mm_shuffle_ps( yz_zx_xy, yz_zx_xy, _MM_SHUFFLE(0,0,2,0) ); // yz_zx_xy = 10 02 10 10 + yz_zx_xy = vec_sel( yz_zx_xy, vec_splat(col2, 1), select_x ); // yz_zx_xy = 21 02 10 10 + + sum = vec_add( zy_xz_yx, yz_zx_xy ); + diff = vec_sub( zy_xz_yx, yz_zx_xy ); + + scale = vec_mul( invSqrt, _mm_set1_ps(0.5f) ); + + //res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA ); + res0 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,1,2,0) ); + res0 = vec_sel( res0, vec_splat(diff, 0), select_w ); // TODO: Ck + //res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB ); + res1 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,2) ); + res1 = vec_sel( res1, vec_splat(diff, 1), select_w ); // TODO: Ck + //res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC ); + res2 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,1) ); + res2 = vec_sel( res2, vec_splat(diff, 2), select_w ); // TODO: Ck + res3 = diff; + res0 = vec_sel( res0, radicand, select_x ); + res1 = vec_sel( res1, radicand, select_y ); + res2 = vec_sel( res2, radicand, select_z ); + res3 = vec_sel( res3, radicand, select_w ); + res0 = vec_mul( res0, vec_splat( scale, 0 ) ); + res1 = vec_mul( res1, vec_splat( scale, 1 ) ); + res2 = vec_mul( res2, vec_splat( scale, 2 ) ); + res3 = vec_mul( res3, vec_splat( scale, 3 ) ); + + /* determine case and select answer */ + + xx = vec_splat( col0, 0 ); + yy = vec_splat( col1, 1 ); + zz = vec_splat( col2, 2 ); + res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) ); + res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) ); + res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), _mm_setzero_ps() ) ); + mVec128 = res; +} + +VECTORMATH_FORCE_INLINE const Matrix3 outer( const Vector3 &tfrm0, const Vector3 &tfrm1 ) +{ + return Matrix3( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix4 outer( const Vector4 &tfrm0, const Vector4 &tfrm1 ) +{ + return Matrix4( + ( tfrm0 * tfrm1.getX( ) ), + ( tfrm0 * tfrm1.getY( ) ), + ( tfrm0 * tfrm1.getZ( ) ), + ( tfrm0 * tfrm1.getW( ) ) + ); +} + +VECTORMATH_FORCE_INLINE const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ) +{ + __m128 tmp0, tmp1, mcol0, mcol1, mcol2, res; + __m128 xxxx, yyyy, zzzz; + tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); + tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); + xxxx = vec_splat( vec.get128(), 0 ); + mcol0 = vec_mergeh( tmp0, mat.getCol1().get128() ); + //mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + mcol1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + mcol1 = vec_sel(mcol1, mat.getCol1().get128(), select_y); + //mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + mcol2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + mcol2 = vec_sel(mcol2, vec_splat(mat.getCol1().get128(), 2), select_y); + yyyy = vec_splat( vec.get128(), 1 ); + res = vec_mul( mcol0, xxxx ); + zzzz = vec_splat( vec.get128(), 2 ); + res = vec_madd( mcol1, yyyy, res ); + res = vec_madd( mcol2, zzzz, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix( const Vector3 &vec ) +{ + __m128 neg, res0, res1, res2; + neg = negatef4( vec.get128() ); + VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; + //res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX ); + res0 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,2,2,0) ); + res0 = vec_sel(res0, vec_splat(neg, 1), select_z); + //res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX ); + res1 = vec_sel(vec_splat(vec.get128(), 0), vec_splat(neg, 2), select_x); + //res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX ); + res2 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,1,1) ); + res2 = vec_sel(res2, vec_splat(neg, 0), select_y); + VM_ATTRIBUTE_ALIGN16 unsigned int filter_x[4] = {0, 0xffffffff, 0xffffffff, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int filter_y[4] = {0xffffffff, 0, 0xffffffff, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int filter_z[4] = {0xffffffff, 0xffffffff, 0, 0xffffffff}; + res0 = vec_and( res0, _mm_load_ps((float *)filter_x ) ); + res1 = vec_and( res1, _mm_load_ps((float *)filter_y ) ); + res2 = vec_and( res2, _mm_load_ps((float *)filter_z ) ); // TODO: Use selects? + return Matrix3( + Vector3( res0 ), + Vector3( res1 ), + Vector3( res2 ) + ); +} + +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ) +{ + return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); +} + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/src/vectormath/sse/quat_aos.h b/src/vectormath/sse/quat_aos.h new file mode 100644 index 0000000..7eac59f --- /dev/null +++ b/src/vectormath/sse/quat_aos.h @@ -0,0 +1,579 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _VECTORMATH_QUAT_AOS_CPP_H +#define _VECTORMATH_QUAT_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#endif + +namespace Vectormath { +namespace Aos { + +VECTORMATH_FORCE_INLINE void Quat::set128(vec_float4 vec) +{ + mVec128 = vec; +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) +{ + mVec128 = _mm_unpacklo_ps( + _mm_unpacklo_ps( _x.get128(), _z.get128() ), + _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const Vector3 &xyz, float _w ) +{ + mVec128 = xyz.get128(); + _vmathVfSetElement(mVec128, _w, 3); +} + + + +VECTORMATH_FORCE_INLINE Quat::Quat(const Quat& quat) +{ + mVec128 = quat.get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( float _x, float _y, float _z, float _w ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, _w); +} + + + + + +VECTORMATH_FORCE_INLINE Quat::Quat( const Vector3 &xyz, const floatInVec &_w ) +{ + mVec128 = xyz.get128(); + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const Vector4 &vec ) +{ + mVec128 = vec.get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Quat::Quat( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Quat Quat::identity( ) +{ + return Quat( _VECTORMATH_UNIT_0001 ); +} + +VECTORMATH_FORCE_INLINE const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ) +{ + return lerp( floatInVec(t), quat0, quat1 ); +} + +VECTORMATH_FORCE_INLINE const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ) +{ + return ( quat0 + ( ( quat1 - quat0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ) +{ + return slerp( floatInVec(t), unitQuat0, unitQuat1 ); +} + +VECTORMATH_FORCE_INLINE const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ) +{ + Quat start; + vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + __m128 selectMask; + cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() ); + selectMask = (__m128)vec_cmpgt( _mm_setzero_ps(), cosAngle ); + cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); + start = Quat( vec_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) ); + selectMask = (__m128)vec_cmpgt( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); + angle = acosf4( cosAngle ); + tttt = t.get128(); + oneMinusT = vec_sub( _mm_set1_ps(1.0f), tttt ); + angles = vec_mergeh( _mm_set1_ps(1.0f), tttt ); + angles = vec_mergeh( angles, oneMinusT ); + angles = vec_madd( angles, angle, _mm_setzero_ps() ); + sines = sinf4( angles ); + scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); + scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); + scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); + return Quat( vec_madd( start.get128(), scale0, vec_mul( unitQuat1.get128(), scale1 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) +{ + return squad( floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3 ); +} + +VECTORMATH_FORCE_INLINE const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) +{ + return slerp( ( ( floatInVec(2.0f) * t ) * ( floatInVec(1.0f) - t ) ), slerp( t, unitQuat0, unitQuat3 ), slerp( t, unitQuat1, unitQuat2 ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Quat::get128( ) const +{ + return mVec128; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator =( const Quat &quat ) +{ + mVec128 = quat.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setXYZ( const Vector3 &vec ) +{ + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + mVec128 = vec_sel( vec.get128(), mVec128, sw ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Quat::getXYZ( ) const +{ + return Vector3( mVec128 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setW( float _w ) +{ + _vmathVfSetElement(mVec128, _w, 3); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setW( const floatInVec &_w ) +{ + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getW( ) const +{ + return floatInVec( mVec128, 3 ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Quat::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Quat::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator +( const Quat &quat ) const +{ + return Quat( _mm_add_ps( mVec128, quat.mVec128 ) ); +} + + +VECTORMATH_FORCE_INLINE const Quat Quat::operator -( const Quat &quat ) const +{ + return Quat( _mm_sub_ps( mVec128, quat.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator *( const floatInVec &scalar ) const +{ + return Quat( _mm_mul_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator +=( const Quat &quat ) +{ + *this = *this + quat; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator -=( const Quat &quat ) +{ + *this = *this - quat; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator /( float scalar ) const +{ + return *this / floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator /( const floatInVec &scalar ) const +{ + return Quat( _mm_div_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator /=( const floatInVec &scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator -( ) const +{ + return Quat(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Quat operator *( float scalar, const Quat &quat ) +{ + return floatInVec(scalar) * quat; +} + +VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar, const Quat &quat ) +{ + return quat * scalar; +} + +VECTORMATH_FORCE_INLINE const floatInVec dot( const Quat &quat0, const Quat &quat1 ) +{ + return floatInVec( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec norm( const Quat &quat ) +{ + return floatInVec( _vmathVfDot4( quat.get128(), quat.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec length( const Quat &quat ) +{ + return floatInVec( _mm_sqrt_ps(_vmathVfDot4( quat.get128(), quat.get128() )), 0 ); +} + +VECTORMATH_FORCE_INLINE const Quat normalize( const Quat &quat ) +{ + vec_float4 dot =_vmathVfDot4( quat.get128(), quat.get128()); + return Quat( _mm_mul_ps( quat.get128(), newtonrapson_rsqrt4( dot ) ) ); +} + + +VECTORMATH_FORCE_INLINE const Quat Quat::rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ) +{ + Vector3 crossVec; + __m128 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; + cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); + cosAngleX2Plus2 = vec_madd( cosAngle, _mm_set1_ps(2.0f), _mm_set1_ps(2.0f) ); + recipCosHalfAngleX2 = _mm_rsqrt_ps( cosAngleX2Plus2 ); + cosHalfAngleX2 = vec_mul( recipCosHalfAngleX2, cosAngleX2Plus2 ); + crossVec = cross( unitVec0, unitVec1 ); + res = vec_mul( crossVec.get128(), recipCosHalfAngleX2 ); + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( res, vec_mul( cosHalfAngleX2, _mm_set1_ps(0.5f) ), sw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotation( float radians, const Vector3 &unitVec ) +{ + return rotation( floatInVec(radians), unitVec ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotation( const floatInVec &radians, const Vector3 &unitVec ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( vec_mul( unitVec.get128(), s ), c, sw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationX( float radians ) +{ + return rotationX( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationX( const floatInVec &radians ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0xffffffff, 0, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( _mm_setzero_ps(), s, xsw ); + res = vec_sel( res, c, wsw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationY( float radians ) +{ + return rotationY( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationY( const floatInVec &radians ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int ysw[4] = {0, 0xffffffff, 0, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( _mm_setzero_ps(), s, ysw ); + res = vec_sel( res, c, wsw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ( float radians ) +{ + return rotationZ( floatInVec(radians) ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ( const floatInVec &radians ) +{ + __m128 s, c, angle, res; + angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); + sincosf4( angle, &s, &c ); + VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0, 0, 0xffffffff, 0}; + VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; + res = vec_sel( _mm_setzero_ps(), s, zsw ); + res = vec_sel( res, c, wsw ); + return Quat( res ); +} + +VECTORMATH_FORCE_INLINE const Quat Quat::operator *( const Quat &quat ) const +{ + __m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; + __m128 product, l_wxyz, r_wxyz, xy, qw; + ldata = mVec128; + rdata = quat.mVec128; + tmp0 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,0,2,1) ); + tmp1 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,1,0,2) ); + tmp2 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,0,2,1) ); + qv = vec_mul( vec_splat( ldata, 3 ), rdata ); + qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv ); + qv = vec_madd( tmp0, tmp1, qv ); + qv = vec_nmsub( tmp2, tmp3, qv ); + product = vec_mul( ldata, rdata ); + l_wxyz = vec_sld( ldata, ldata, 12 ); + r_wxyz = vec_sld( rdata, rdata, 12 ); + qw = vec_nmsub( l_wxyz, r_wxyz, product ); + xy = vec_madd( l_wxyz, r_wxyz, product ); + qw = vec_sub( qw, vec_sld( xy, xy, 8 ) ); + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + return Quat( vec_sel( qv, qw, sw ) ); +} + +VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( const Quat &quat ) +{ + *this = *this * quat; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 rotate( const Quat &quat, const Vector3 &vec ) +{ __m128 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; + qdata = quat.get128(); + vdata = vec.get128(); + tmp0 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,0,2,1) ); + tmp1 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,1,0,2) ); + tmp2 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,0,2,1) ); + wwww = vec_splat( qdata, 3 ); + qv = vec_mul( wwww, vdata ); + qv = vec_madd( tmp0, tmp1, qv ); + qv = vec_nmsub( tmp2, tmp3, qv ); + product = vec_mul( qdata, vdata ); + qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product ); + qw = vec_add( vec_sld( product, product, 8 ), qw ); + tmp1 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,0,2,1) ); + res = vec_mul( vec_splat( qw, 0 ), qdata ); + res = vec_madd( wwww, qv, res ); + res = vec_madd( tmp0, tmp1, res ); + res = vec_nmsub( tmp2, tmp3, res ); + return Vector3( res ); +} + +VECTORMATH_FORCE_INLINE const Quat conj( const Quat &quat ) +{ + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0x80000000,0x80000000,0x80000000,0}; + return Quat( vec_xor( quat.get128(), _mm_load_ps((float *)sw) ) ); +} + +VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ) +{ + return select( quat0, quat1, boolInVec(select1) ); +} + +//VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ) +//{ +// return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) ); +//} + +VECTORMATH_FORCE_INLINE void loadXYZW(Quat& quat, const float* fptr) +{ +#ifdef USE_SSE3_LDDQU + quat = Quat( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); +#else + SSEFloat fl; + fl.f[0] = fptr[0]; + fl.f[1] = fptr[1]; + fl.f[2] = fptr[2]; + fl.f[3] = fptr[3]; + quat = Quat( fl.m128); +#endif + + +} + +VECTORMATH_FORCE_INLINE void storeXYZW(const Quat& quat, float* fptr) +{ + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); +// _mm_storeu_ps((float*)quat.get128(),fptr); +} + + + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Quat &quat ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = quat.get128(); + printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = quat.get128(); + printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/src/vectormath/sse/vec_aos.h b/src/vectormath/sse/vec_aos.h new file mode 100644 index 0000000..35aeeaf --- /dev/null +++ b/src/vectormath/sse/vec_aos.h @@ -0,0 +1,1455 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_VEC_AOS_CPP_H +#define _VECTORMATH_VEC_AOS_CPP_H + +//----------------------------------------------------------------------------- +// Constants +// for permutes words are labeled [x,y,z,w] [a,b,c,d] + +#define _VECTORMATH_PERM_X 0x00010203 +#define _VECTORMATH_PERM_Y 0x04050607 +#define _VECTORMATH_PERM_Z 0x08090a0b +#define _VECTORMATH_PERM_W 0x0c0d0e0f +#define _VECTORMATH_PERM_A 0x10111213 +#define _VECTORMATH_PERM_B 0x14151617 +#define _VECTORMATH_PERM_C 0x18191a1b +#define _VECTORMATH_PERM_D 0x1c1d1e1f +#define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } +#define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } +#define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } +#define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } +#define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 } +#define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 } +#define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 } +#define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff } +#define _VECTORMATH_UNIT_1000 _mm_setr_ps(1.0f,0.0f,0.0f,0.0f) // (__m128){ 1.0f, 0.0f, 0.0f, 0.0f } +#define _VECTORMATH_UNIT_0100 _mm_setr_ps(0.0f,1.0f,0.0f,0.0f) // (__m128){ 0.0f, 1.0f, 0.0f, 0.0f } +#define _VECTORMATH_UNIT_0010 _mm_setr_ps(0.0f,0.0f,1.0f,0.0f) // (__m128){ 0.0f, 0.0f, 1.0f, 0.0f } +#define _VECTORMATH_UNIT_0001 _mm_setr_ps(0.0f,0.0f,0.0f,1.0f) // (__m128){ 0.0f, 0.0f, 0.0f, 1.0f } +#define _VECTORMATH_SLERP_TOL 0.999f +//_VECTORMATH_SLERP_TOLF + +//----------------------------------------------------------------------------- +// Definitions + +#ifndef _VECTORMATH_INTERNAL_FUNCTIONS +#define _VECTORMATH_INTERNAL_FUNCTIONS + +#define _vmath_shufps(a, b, immx, immy, immz, immw) _mm_shuffle_ps(a, b, _MM_SHUFFLE(immw, immz, immy, immx)) +static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 ) +{ + __m128 result = _mm_mul_ps( vec0, vec1); + return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) ); +} + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot4( __m128 vec0, __m128 vec1 ) +{ + __m128 result = _mm_mul_ps(vec0, vec1); + return _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(0,0,0,0)), + _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(1,1,1,1)), + _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(2,2,2,2)), _mm_shuffle_ps(result, result, _MM_SHUFFLE(3,3,3,3))))); +} + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfCross( __m128 vec0, __m128 vec1 ) +{ + __m128 tmp0, tmp1, tmp2, tmp3, result; + tmp0 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,0,2,1) ); + tmp1 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,1,0,2) ); + tmp2 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,1,0,2) ); + tmp3 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,0,2,1) ); + result = vec_mul( tmp0, tmp1 ); + result = vec_nmsub( tmp2, tmp3, result ); + return result; +} +/* +static VECTORMATH_FORCE_INLINE vec_uint4 _vmathVfToHalfFloatsUnpacked(__m128 v) +{ +#if 0 + vec_int4 bexp; + vec_uint4 mant, sign, hfloat; + vec_uint4 notZero, isInf; + const vec_uint4 hfloatInf = (vec_uint4)(0x00007c00u); + const vec_uint4 mergeMant = (vec_uint4)(0x000003ffu); + const vec_uint4 mergeSign = (vec_uint4)(0x00008000u); + + sign = vec_sr((vec_uint4)v, (vec_uint4)16); + mant = vec_sr((vec_uint4)v, (vec_uint4)13); + bexp = vec_and(vec_sr((vec_int4)v, (vec_uint4)23), (vec_int4)0xff); + + notZero = (vec_uint4)vec_cmpgt(bexp, (vec_int4)112); + isInf = (vec_uint4)vec_cmpgt(bexp, (vec_int4)142); + + bexp = _mm_add_ps(bexp, (vec_int4)-112); + bexp = vec_sl(bexp, (vec_uint4)10); + + hfloat = vec_sel((vec_uint4)bexp, mant, mergeMant); + hfloat = vec_sel((vec_uint4)(0), hfloat, notZero); + hfloat = vec_sel(hfloat, hfloatInf, isInf); + hfloat = vec_sel(hfloat, sign, mergeSign); + + return hfloat; +#else + assert(0); + return _mm_setzero_ps(); +#endif +} + +static VECTORMATH_FORCE_INLINE vec_ushort8 _vmath2VfToHalfFloats(__m128 u, __m128 v) +{ +#if 0 + vec_uint4 hfloat_u, hfloat_v; + const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31}; + hfloat_u = _vmathVfToHalfFloatsUnpacked(u); + hfloat_v = _vmathVfToHalfFloatsUnpacked(v); + return (vec_ushort8)vec_perm(hfloat_u, hfloat_v, pack); +#else + assert(0); + return _mm_setzero_si128(); +#endif +} +*/ + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfInsert(__m128 dst, __m128 src, int slot) +{ + SSEFloat s; + s.m128 = src; + SSEFloat d; + d.m128 = dst; + d.f[slot] = s.f[slot]; + return d.m128; +} + +#define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar + +static VECTORMATH_FORCE_INLINE __m128 _vmathVfSplatScalar(float scalar) +{ + return _mm_set1_ps(scalar); +} + +#endif + +namespace Vectormath { +namespace Aos { + + +#ifdef _VECTORMATH_NO_SCALAR_CAST +VECTORMATH_FORCE_INLINE VecIdx::operator floatInVec() const +{ + return floatInVec(ref, i); +} + +VECTORMATH_FORCE_INLINE float VecIdx::getAsFloat() const +#else +VECTORMATH_FORCE_INLINE VecIdx::operator float() const +#endif +{ + return ((float *)&ref)[i]; +} + +VECTORMATH_FORCE_INLINE float VecIdx::operator =( float scalar ) +{ + _vmathVfSetElement(ref, scalar, i); + return scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator =( const floatInVec &scalar ) +{ + ref = _vmathVfInsert(ref, scalar.get128(), i); + return scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator =( const VecIdx& scalar ) +{ + return *this = floatInVec(scalar.ref, scalar.i); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator *=( float scalar ) +{ + return *this *= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator *=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) * scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator /=( float scalar ) +{ + return *this /= floatInVec(scalar); +} + +inline floatInVec VecIdx::operator /=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) / scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator +=( float scalar ) +{ + return *this += floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator +=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) + scalar; +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator -=( float scalar ) +{ + return *this -= floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator -=( const floatInVec &scalar ) +{ + return *this = floatInVec(ref, i) - scalar; +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3(const Vector3& vec) +{ + set128(vec.get128()); +} + +VECTORMATH_FORCE_INLINE void Vector3::set128(vec_float4 vec) +{ + mVec128 = vec; +} + + +VECTORMATH_FORCE_INLINE Vector3::Vector3( float _x, float _y, float _z ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) +{ + __m128 xz = _mm_unpacklo_ps( _x.get128(), _z.get128() ); + mVec128 = _mm_unpacklo_ps( xz, _y.get128() ); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( const Point3 &pnt ) +{ + mVec128 = pnt.get128(); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Vector3::Vector3( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::xAxis( ) +{ + return Vector3( _VECTORMATH_UNIT_1000 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::yAxis( ) +{ + return Vector3( _VECTORMATH_UNIT_0100 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::zAxis( ) +{ + return Vector3( _VECTORMATH_UNIT_0010 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ) +{ + return lerp( floatInVec(t), vec0, vec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) +{ + return slerp( floatInVec(t), unitVec0, unitVec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) +{ + __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); + __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); + angle = acosf4( cosAngle ); + tttt = t.get128(); + oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); + angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t + angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t + angles = _mm_mul_ps( angles, angle ); + sines = sinf4( angles ); + scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); + scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); + scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); + return Vector3( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Vector3::get128( ) const +{ + return mVec128; +} + +VECTORMATH_FORCE_INLINE void loadXYZ(Point3& vec, const float* fptr) +{ +#ifdef USE_SSE3_LDDQU + vec = Point3( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); +#else + SSEFloat fl; + fl.f[0] = fptr[0]; + fl.f[1] = fptr[1]; + fl.f[2] = fptr[2]; + fl.f[3] = fptr[3]; + vec = Point3( fl.m128); +#endif //USE_SSE3_LDDQU + +} + + + +VECTORMATH_FORCE_INLINE void loadXYZ(Vector3& vec, const float* fptr) +{ +#ifdef USE_SSE3_LDDQU + vec = Vector3( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); +#else + SSEFloat fl; + fl.f[0] = fptr[0]; + fl.f[1] = fptr[1]; + fl.f[2] = fptr[2]; + fl.f[3] = fptr[3]; + vec = Vector3( fl.m128); +#endif //USE_SSE3_LDDQU + +} + +VECTORMATH_FORCE_INLINE void storeXYZ( const Vector3 &vec, __m128 * quad ) +{ + __m128 dstVec = *quad; + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize + dstVec = vec_sel(vec.get128(), dstVec, sw); + *quad = dstVec; +} + +VECTORMATH_FORCE_INLINE void storeXYZ(const Point3& vec, float* fptr) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + +VECTORMATH_FORCE_INLINE void storeXYZ(const Vector3& vec, float* fptr) +{ + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); +} + + +VECTORMATH_FORCE_INLINE void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ) +{ + const float *quads = (float *)threeQuads; + vec0 = Vector3( _mm_load_ps(quads) ); + vec1 = Vector3( _mm_loadu_ps(quads + 3) ); + vec2 = Vector3( _mm_loadu_ps(quads + 6) ); + vec3 = Vector3( _mm_loadu_ps(quads + 9) ); +} + +VECTORMATH_FORCE_INLINE void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ) +{ + __m128 xxxx = _mm_shuffle_ps( vec1.get128(), vec1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); + __m128 zzzz = _mm_shuffle_ps( vec2.get128(), vec2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); + VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0, 0, 0, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0xffffffff, 0, 0, 0}; + threeQuads[0] = vec_sel( vec0.get128(), xxxx, xsw ); + threeQuads[1] = _mm_shuffle_ps( vec1.get128(), vec2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); + threeQuads[2] = vec_sel( _mm_shuffle_ps( vec3.get128(), vec3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); +} +/* +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads ) +{ + assert(0); +#if 0 + __m128 xyz0[3]; + __m128 xyz1[3]; + storeXYZArray( vec0, vec1, vec2, vec3, xyz0 ); + storeXYZArray( vec4, vec5, vec6, vec7, xyz1 ); + threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); + threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); + threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); +#endif +} +*/ +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator =( const Vector3 &vec ) +{ + mVec128 = vec.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Vector3::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector3::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator +( const Vector3 &vec ) const +{ + return Vector3( _mm_add_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator -( const Vector3 &vec ) const +{ + return Vector3( _mm_sub_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 Vector3::operator +( const Point3 &pnt ) const +{ + return Point3( _mm_add_ps( mVec128, pnt.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator *( const floatInVec &scalar ) const +{ + return Vector3( _mm_mul_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator +=( const Vector3 &vec ) +{ + *this = *this + vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator -=( const Vector3 &vec ) +{ + *this = *this - vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator /( float scalar ) const +{ + return *this / floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator /( const floatInVec &scalar ) const +{ + return Vector3( _mm_div_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator /=( const floatInVec &scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator -( ) const +{ + //return Vector3(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); + + VM_ATTRIBUTE_ALIGN16 static const int array[] = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; + __m128 NEG_MASK = SSEFloat(*(const vec_float4*)array).vf; + return Vector3(_mm_xor_ps(get128(),NEG_MASK)); +} + +VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar, const Vector3 &vec ) +{ + return floatInVec(scalar) * vec; +} + +VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ) +{ + return vec * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_div_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 recipPerElem( const Vector3 &vec ) +{ + return Vector3( _mm_rcp_ps( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 absPerElem( const Vector3 &vec ) +{ + return Vector3( fabsf4( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + __m128 vmask = toM128(0x7fffffff); + return Vector3( _mm_or_ps( + _mm_and_ps ( vmask, vec0.get128() ), // Value + _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs +} + +VECTORMATH_FORCE_INLINE const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_max_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector3 &vec ) +{ + return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _mm_min_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector3 &vec ) +{ + return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector3 &vec ) +{ + return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return floatInVec( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector3 &vec ) +{ + return floatInVec( _vmathVfDot3( vec.get128(), vec.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector3 &vec ) +{ + return floatInVec( _mm_sqrt_ps(_vmathVfDot3( vec.get128(), vec.get128() )), 0 ); +} + + +VECTORMATH_FORCE_INLINE const Vector3 normalizeApprox( const Vector3 &vec ) +{ + return Vector3( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 normalize( const Vector3 &vec ) +{ + return Vector3( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ) +{ + return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ) +{ + return select( vec0, vec1, boolInVec(select1) ); +} + + +VECTORMATH_FORCE_INLINE const Vector4 select(const Vector4& vec0, const Vector4& vec1, const boolInVec& select1) +{ + return Vector4(vec_sel(vec0.get128(), vec1.get128(), select1.get128())); +} + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +#endif + +VECTORMATH_FORCE_INLINE Vector4::Vector4( float _x, float _y, float _z, float _w ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, _w); + } + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) +{ + mVec128 = _mm_unpacklo_ps( + _mm_unpacklo_ps( _x.get128(), _z.get128() ), + _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &xyz, float _w ) +{ + mVec128 = xyz.get128(); + _vmathVfSetElement(mVec128, _w, 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &xyz, const floatInVec &_w ) +{ + mVec128 = xyz.get128(); + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &vec ) +{ + mVec128 = vec.get128(); + mVec128 = _vmathVfInsert(mVec128, _mm_setzero_ps(), 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Point3 &pnt ) +{ + mVec128 = pnt.get128(); + mVec128 = _vmathVfInsert(mVec128, _mm_set1_ps(1.0f), 3); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const Quat &quat ) +{ + mVec128 = quat.get128(); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Vector4::Vector4( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::xAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_1000 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::yAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_0100 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::zAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_0010 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::wAxis( ) +{ + return Vector4( _VECTORMATH_UNIT_0001 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ) +{ + return lerp( floatInVec(t), vec0, vec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ) +{ + return ( vec0 + ( ( vec1 - vec0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) +{ + return slerp( floatInVec(t), unitVec0, unitVec1 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) +{ + __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() ); + __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); + angle = acosf4( cosAngle ); + tttt = t.get128(); + oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); + angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t + angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t + angles = _mm_mul_ps( angles, angle ); + sines = sinf4( angles ); + scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); + scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); + scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); + return Vector4( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Vector4::get128( ) const +{ + return mVec128; +} +/* +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads ) +{ + twoQuads[0] = _vmath2VfToHalfFloats(vec0.get128(), vec1.get128()); + twoQuads[1] = _vmath2VfToHalfFloats(vec2.get128(), vec3.get128()); +} +*/ +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator =( const Vector4 &vec ) +{ + mVec128 = vec.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setXYZ( const Vector3 &vec ) +{ + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; + mVec128 = vec_sel( vec.get128(), mVec128, sw ); + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector3 Vector4::getXYZ( ) const +{ + return Vector3( mVec128 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setW( float _w ) +{ + _vmathVfSetElement(mVec128, _w, 3); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setW( const floatInVec &_w ) +{ + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getW( ) const +{ + return floatInVec( mVec128, 3 ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Vector4::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Vector4::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator +( const Vector4 &vec ) const +{ + return Vector4( _mm_add_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator -( const Vector4 &vec ) const +{ + return Vector4( _mm_sub_ps( mVec128, vec.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator *( float scalar ) const +{ + return *this * floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator *( const floatInVec &scalar ) const +{ + return Vector4( _mm_mul_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator +=( const Vector4 &vec ) +{ + *this = *this + vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator -=( const Vector4 &vec ) +{ + *this = *this - vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator *=( float scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator *=( const floatInVec &scalar ) +{ + *this = *this * scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator /( float scalar ) const +{ + return *this / floatInVec(scalar); +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator /( const floatInVec &scalar ) const +{ + return Vector4( _mm_div_ps( mVec128, scalar.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator /=( float scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator /=( const floatInVec &scalar ) +{ + *this = *this / scalar; + return *this; +} + +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator -( ) const +{ + return Vector4(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar, const Vector4 &vec ) +{ + return floatInVec(scalar) * vec; +} + +VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ) +{ + return vec * scalar; +} + +VECTORMATH_FORCE_INLINE const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_div_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 recipPerElem( const Vector4 &vec ) +{ + return Vector4( _mm_rcp_ps( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 absPerElem( const Vector4 &vec ) +{ + return Vector4( fabsf4( vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + __m128 vmask = toM128(0x7fffffff); + return Vector4( _mm_or_ps( + _mm_and_ps ( vmask, vec0.get128() ), // Value + _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs +} + +VECTORMATH_FORCE_INLINE const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_max_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector4 &vec ) +{ + return floatInVec( _mm_max_ps( + _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), + _mm_max_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return Vector4( _mm_min_ps( vec0.get128(), vec1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector4 &vec ) +{ + return floatInVec( _mm_min_ps( + _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), + _mm_min_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector4 &vec ) +{ + return floatInVec( _mm_add_ps( + _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), + _mm_add_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ) +{ + return floatInVec( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector4 &vec ) +{ + return floatInVec( _vmathVfDot4( vec.get128(), vec.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector4 &vec ) +{ + return floatInVec( _mm_sqrt_ps(_vmathVfDot4( vec.get128(), vec.get128() )), 0 ); +} + +VECTORMATH_FORCE_INLINE const Vector4 normalizeApprox( const Vector4 &vec ) +{ + return Vector4( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 normalize( const Vector4 &vec ) +{ + return Vector4( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); +} + +VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ) +{ + return select( vec0, vec1, boolInVec(select1) ); +} + + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = vec.get128(); + printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); +} + +#endif + +VECTORMATH_FORCE_INLINE Point3::Point3( float _x, float _y, float _z ) +{ + mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) +{ + mVec128 = _mm_unpacklo_ps( _mm_unpacklo_ps( _x.get128(), _z.get128() ), _y.get128() ); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( const Vector3 &vec ) +{ + mVec128 = vec.get128(); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( float scalar ) +{ + mVec128 = floatInVec(scalar).get128(); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( const floatInVec &scalar ) +{ + mVec128 = scalar.get128(); +} + +VECTORMATH_FORCE_INLINE Point3::Point3( __m128 vf4 ) +{ + mVec128 = vf4; +} + +VECTORMATH_FORCE_INLINE const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ) +{ + return lerp( floatInVec(t), pnt0, pnt1 ); +} + +VECTORMATH_FORCE_INLINE const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ) +{ + return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); +} + +VECTORMATH_FORCE_INLINE __m128 Point3::get128( ) const +{ + return mVec128; +} + +VECTORMATH_FORCE_INLINE void storeXYZ( const Point3 &pnt, __m128 * quad ) +{ + __m128 dstVec = *quad; + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize + dstVec = vec_sel(pnt.get128(), dstVec, sw); + *quad = dstVec; +} + +VECTORMATH_FORCE_INLINE void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ) +{ + const float *quads = (float *)threeQuads; + pnt0 = Point3( _mm_load_ps(quads) ); + pnt1 = Point3( _mm_loadu_ps(quads + 3) ); + pnt2 = Point3( _mm_loadu_ps(quads + 6) ); + pnt3 = Point3( _mm_loadu_ps(quads + 9) ); +} + +VECTORMATH_FORCE_INLINE void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ) +{ + __m128 xxxx = _mm_shuffle_ps( pnt1.get128(), pnt1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); + __m128 zzzz = _mm_shuffle_ps( pnt2.get128(), pnt2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); + VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0, 0, 0, 0xffffffff}; + VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0xffffffff, 0, 0, 0}; + threeQuads[0] = vec_sel( pnt0.get128(), xxxx, xsw ); + threeQuads[1] = _mm_shuffle_ps( pnt1.get128(), pnt2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); + threeQuads[2] = vec_sel( _mm_shuffle_ps( pnt3.get128(), pnt3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); +} +/* +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads ) +{ +#if 0 + __m128 xyz0[3]; + __m128 xyz1[3]; + storeXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 ); + storeXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 ); + threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); + threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); + threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); +#else + assert(0); +#endif +} +*/ +VECTORMATH_FORCE_INLINE Point3 & Point3::operator =( const Point3 &pnt ) +{ + mVec128 = pnt.mVec128; + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setX( float _x ) +{ + _vmathVfSetElement(mVec128, _x, 0); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setX( const floatInVec &_x ) +{ + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getX( ) const +{ + return floatInVec( mVec128, 0 ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setY( float _y ) +{ + _vmathVfSetElement(mVec128, _y, 1); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setY( const floatInVec &_y ) +{ + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getY( ) const +{ + return floatInVec( mVec128, 1 ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setZ( float _z ) +{ + _vmathVfSetElement(mVec128, _z, 2); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setZ( const floatInVec &_z ) +{ + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getZ( ) const +{ + return floatInVec( mVec128, 2 ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setElem( int idx, float value ) +{ + _vmathVfSetElement(mVec128, value, idx); + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::setElem( int idx, const floatInVec &value ) +{ + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::getElem( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE VecIdx Point3::operator []( int idx ) +{ + return VecIdx( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const floatInVec Point3::operator []( int idx ) const +{ + return floatInVec( mVec128, idx ); +} + +VECTORMATH_FORCE_INLINE const Vector3 Point3::operator -( const Point3 &pnt ) const +{ + return Vector3( _mm_sub_ps( mVec128, pnt.mVec128 ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 Point3::operator +( const Vector3 &vec ) const +{ + return Point3( _mm_add_ps( mVec128, vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 Point3::operator -( const Vector3 &vec ) const +{ + return Point3( _mm_sub_ps( mVec128, vec.get128() ) ); +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::operator +=( const Vector3 &vec ) +{ + *this = *this + vec; + return *this; +} + +VECTORMATH_FORCE_INLINE Point3 & Point3::operator -=( const Vector3 &vec ) +{ + *this = *this - vec; + return *this; +} + +VECTORMATH_FORCE_INLINE const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_mul_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_div_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 recipPerElem( const Point3 &pnt ) +{ + return Point3( _mm_rcp_ps( pnt.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 absPerElem( const Point3 &pnt ) +{ + return Point3( fabsf4( pnt.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + __m128 vmask = toM128(0x7fffffff); + return Point3( _mm_or_ps( + _mm_and_ps ( vmask, pnt0.get128() ), // Value + _mm_andnot_ps( vmask, pnt1.get128() ) ) ); // Signs +} + +VECTORMATH_FORCE_INLINE const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_max_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Point3 &pnt ) +{ + return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return Point3( _mm_min_ps( pnt0.get128(), pnt1.get128() ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Point3 &pnt ) +{ + return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec sum( const Point3 &pnt ) +{ + return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, float scaleVal ) +{ + return scale( pnt, floatInVec( scaleVal ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ) +{ + return mulPerElem( pnt, Point3( scaleVal ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ) +{ + return mulPerElem( pnt, Point3( scaleVec ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ) +{ + return floatInVec( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 ); +} + +VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin( const Point3 &pnt ) +{ + return lengthSqr( Vector3( pnt ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin( const Point3 &pnt ) +{ + return length( Vector3( pnt ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return lengthSqr( ( pnt1 - pnt0 ) ); +} + +VECTORMATH_FORCE_INLINE const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ) +{ + return length( ( pnt1 - pnt0 ) ); +} + +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ) +{ + return select( pnt0, pnt1, boolInVec(select1) ); +} + +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ) +{ + return Point3( vec_sel( pnt0.get128(), pnt1.get128(), select1.get128() ) ); +} + + + +#ifdef _VECTORMATH_DEBUG + +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = pnt.get128(); + printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name ) +{ + union { __m128 v; float s[4]; } tmp; + tmp.v = pnt.get128(); + printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); +} + +#endif + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/src/vectormath/sse/vecidx_aos.h b/src/vectormath/sse/vecidx_aos.h new file mode 100644 index 0000000..8ba4b1d --- /dev/null +++ b/src/vectormath/sse/vecidx_aos.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _VECTORMATH_VECIDX_AOS_H +#define _VECTORMATH_VECIDX_AOS_H + + +#include "floatInVec.h" + +namespace Vectormath { +namespace Aos { + +//----------------------------------------------------------------------------- +// VecIdx +// Used in setting elements of Vector3, Vector4, Point3, or Quat with the +// subscripting operator. +// + +VM_ATTRIBUTE_ALIGNED_CLASS16 (class) VecIdx +{ +private: + __m128 &ref; + int i; +public: + inline VecIdx( __m128& vec, int idx ): ref(vec) { i = idx; } + + // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined + // in which case, implicitly casts to floatInVec, and one must call + // getAsFloat to convert to float. + // +#ifdef _VECTORMATH_NO_SCALAR_CAST + inline operator floatInVec() const; + inline float getAsFloat() const; +#else + inline operator float() const; +#endif + + inline float operator =( float scalar ); + inline floatInVec operator =( const floatInVec &scalar ); + inline floatInVec operator =( const VecIdx& scalar ); + inline floatInVec operator *=( float scalar ); + inline floatInVec operator *=( const floatInVec &scalar ); + inline floatInVec operator /=( float scalar ); + inline floatInVec operator /=( const floatInVec &scalar ); + inline floatInVec operator +=( float scalar ); + inline floatInVec operator +=( const floatInVec &scalar ); + inline floatInVec operator -=( float scalar ); + inline floatInVec operator -=( const floatInVec &scalar ); +}; + +} // namespace Aos +} // namespace Vectormath + +#endif diff --git a/src/vectormath/sse/vectormath_aos.h b/src/vectormath/sse/vectormath_aos.h new file mode 100644 index 0000000..be5ae8c --- /dev/null +++ b/src/vectormath/sse/vectormath_aos.h @@ -0,0 +1,2547 @@ +/* + Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. + All rights reserved. + + Redistribution and use in source and binary forms, + with or without modification, are permitted provided that the + following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Sony Computer Entertainment Inc nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _VECTORMATH_AOS_CPP_SSE_H +#define _VECTORMATH_AOS_CPP_SSE_H + +#include +#include +#include +#include + +#define Vector3Ref Vector3& +#define QuatRef Quat& +#define Matrix3Ref Matrix3& + +#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) + #define USE_SSE3_LDDQU + + #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) __declspec(align(16)) a + #define VM_ATTRIBUTE_ALIGN16 __declspec(align(16)) + #define VECTORMATH_FORCE_INLINE __forceinline +#else + #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) a __attribute__ ((aligned (16))) + #define VM_ATTRIBUTE_ALIGN16 __attribute__ ((aligned (16))) + #define VECTORMATH_FORCE_INLINE inline __attribute__ ((always_inline)) + #ifdef __SSE3__ + #define USE_SSE3_LDDQU + #endif //__SSE3__ +#endif//_WIN32 + + +#ifdef USE_SSE3_LDDQU +#include //_mm_lddqu_si128 +#endif //USE_SSE3_LDDQU + + +// TODO: Tidy +typedef __m128 vec_float4; +typedef __m128 vec_uint4; +typedef __m128 vec_int4; +typedef __m128i vec_uchar16; +typedef __m128i vec_ushort8; + +#define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e)) + +#define _mm_ror_ps(vec,i) \ + (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec)) +#define _mm_rol_ps(vec,i) \ + (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(7-i)%4,(unsigned char)(6-i)%4,(unsigned char)(5-i)%4,(unsigned char)(4-i)%4))) : (vec)) + +#define vec_sld(vec,vec2,x) _mm_ror_ps(vec, ((x)/4)) + +#define _mm_abs_ps(vec) _mm_andnot_ps(_MASKSIGN_,vec) +#define _mm_neg_ps(vec) _mm_xor_ps(_MASKSIGN_,vec) + +#define vec_madd(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b) ) + +union SSEFloat +{ + __m128i vi; + __m128 m128; + __m128 vf; + unsigned int ui[4]; + unsigned short s[8]; + float f[4]; + SSEFloat(__m128 v) : m128(v) {} + SSEFloat(__m128i v) : vi(v) {} + SSEFloat() {}//uninitialized +}; + +static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, __m128 mask) +{ + return _mm_or_ps(_mm_and_ps(mask, b), _mm_andnot_ps(mask, a)); +} +static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, const unsigned int *_mask) +{ + return vec_sel(a, b, _mm_load_ps((float *)_mask)); +} +static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, unsigned int _mask) +{ + return vec_sel(a, b, _mm_set1_ps(*(float *)&_mask)); +} + +static VECTORMATH_FORCE_INLINE __m128 toM128(unsigned int x) +{ + return _mm_set1_ps( *(float *)&x ); +} + +static VECTORMATH_FORCE_INLINE __m128 fabsf4(__m128 x) +{ + return _mm_and_ps( x, toM128( 0x7fffffff ) ); +} +/* +union SSE64 +{ + __m128 m128; + struct + { + __m64 m01; + __m64 m23; + } m64; +}; + +static VECTORMATH_FORCE_INLINE __m128 vec_cts(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + SSE64 sse64; + sse64.m64.m01 = _mm_cvttps_pi32(x); + sse64.m64.m23 = _mm_cvttps_pi32(_mm_ror_ps(x,2)); + _mm_empty(); + return sse64.m128; +} + +static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + SSE64 sse64; + sse64.m128 = x; + __m128 result =_mm_movelh_ps( + _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m01), + _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m23)); + _mm_empty(); + return result; +} +*/ +static VECTORMATH_FORCE_INLINE __m128 vec_cts(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + __m128i result = _mm_cvtps_epi32(x); + return (__m128 &)result; +} + +static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a) +{ + assert(a == 0); // Only 2^0 supported + (void)a; + return _mm_cvtepi32_ps((__m128i &)x); +} + +#define vec_nmsub(a,b,c) _mm_sub_ps( c, _mm_mul_ps( a, b ) ) +#define vec_sub(a,b) _mm_sub_ps( a, b ) +#define vec_add(a,b) _mm_add_ps( a, b ) +#define vec_mul(a,b) _mm_mul_ps( a, b ) +#define vec_xor(a,b) _mm_xor_ps( a, b ) +#define vec_and(a,b) _mm_and_ps( a, b ) +#define vec_cmpeq(a,b) _mm_cmpeq_ps( a, b ) +#define vec_cmpgt(a,b) _mm_cmpgt_ps( a, b ) + +#define vec_mergeh(a,b) _mm_unpacklo_ps( a, b ) +#define vec_mergel(a,b) _mm_unpackhi_ps( a, b ) + +#define vec_andc(a,b) _mm_andnot_ps( b, a ) + +#define sqrtf4(x) _mm_sqrt_ps( x ) +#define rsqrtf4(x) _mm_rsqrt_ps( x ) +#define recipf4(x) _mm_rcp_ps( x ) +#define negatef4(x) _mm_sub_ps( _mm_setzero_ps(), x ) + +static VECTORMATH_FORCE_INLINE __m128 newtonrapson_rsqrt4( const __m128 v ) +{ +#define _half4 _mm_setr_ps(.5f,.5f,.5f,.5f) +#define _three _mm_setr_ps(3.f,3.f,3.f,3.f) +const __m128 approx = _mm_rsqrt_ps( v ); +const __m128 muls = _mm_mul_ps(_mm_mul_ps(v, approx), approx); +return _mm_mul_ps(_mm_mul_ps(_half4, approx), _mm_sub_ps(_three, muls) ); +} + +static VECTORMATH_FORCE_INLINE __m128 acosf4(__m128 x) +{ + __m128 xabs = fabsf4(x); + __m128 select = _mm_cmplt_ps( x, _mm_setzero_ps() ); + __m128 t1 = sqrtf4(vec_sub(_mm_set1_ps(1.0f), xabs)); + + /* Instruction counts can be reduced if the polynomial was + * computed entirely from nested (dependent) fma's. However, + * to reduce the number of pipeline stalls, the polygon is evaluated + * in two halves (hi amd lo). + */ + __m128 xabs2 = _mm_mul_ps(xabs, xabs); + __m128 xabs4 = _mm_mul_ps(xabs2, xabs2); + __m128 hi = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0012624911f), + xabs, _mm_set1_ps(0.0066700901f)), + xabs, _mm_set1_ps(-0.0170881256f)), + xabs, _mm_set1_ps( 0.0308918810f)); + __m128 lo = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0501743046f), + xabs, _mm_set1_ps(0.0889789874f)), + xabs, _mm_set1_ps(-0.2145988016f)), + xabs, _mm_set1_ps( 1.5707963050f)); + + __m128 result = vec_madd(hi, xabs4, lo); + + // Adjust the result if x is negactive. + return vec_sel( + vec_mul(t1, result), // Positive + vec_nmsub(t1, result, _mm_set1_ps(3.1415926535898f)), // Negative + select); +} + +static VECTORMATH_FORCE_INLINE __m128 sinf4(vec_float4 x) +{ + +// +// Common constants used to evaluate sinf4/cosf4/tanf4 +// +#define _SINCOS_CC0 -0.0013602249f +#define _SINCOS_CC1 0.0416566950f +#define _SINCOS_CC2 -0.4999990225f +#define _SINCOS_SC0 -0.0001950727f +#define _SINCOS_SC1 0.0083320758f +#define _SINCOS_SC2 -0.1666665247f + +#define _SINCOS_KC1 1.57079625129f +#define _SINCOS_KC2 7.54978995489e-8f + + vec_float4 xl,xl2,xl3,res; + + // Range reduction using : xl = angle * TwoOverPi; + // + xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); + + // Find the quadrant the angle falls in + // using: q = (int) (ceil(abs(xl))*sign(xl)) + // + vec_int4 q = vec_cts(xl,0); + + // Compute an offset based on the quadrant that the angle falls in + // + vec_int4 offset = _mm_and_ps(q,toM128(0x3)); + + // Remainder in range [-pi/4..pi/4] + // + vec_float4 qf = vec_ctf(q,0); + xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); + + // Compute x^2 and x^3 + // + xl2 = vec_mul(xl,xl); + xl3 = vec_mul(xl2,xl); + + // Compute both the sin and cos of the angles + // using a polynomial expression: + // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and + // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) + // + + vec_float4 cx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); + vec_float4 sx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); + + // Use the cosine when the offset is odd and the sin + // when the offset is even + // + res = vec_sel(cx,sx,vec_cmpeq(vec_and(offset, + toM128(0x1)), + _mm_setzero_ps())); + + // Flip the sign of the result when (offset mod 4) = 1 or 2 + // + return vec_sel( + vec_xor(toM128(0x80000000U), res), // Negative + res, // Positive + vec_cmpeq(vec_and(offset,toM128(0x2)),_mm_setzero_ps())); +} + +static VECTORMATH_FORCE_INLINE void sincosf4(vec_float4 x, vec_float4* s, vec_float4* c) +{ + vec_float4 xl,xl2,xl3; + vec_int4 offsetSin, offsetCos; + + // Range reduction using : xl = angle * TwoOverPi; + // + xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); + + // Find the quadrant the angle falls in + // using: q = (int) (ceil(abs(xl))*sign(xl)) + // + //vec_int4 q = vec_cts(vec_add(xl,vec_sel(_mm_set1_ps(0.5f),xl,(0x80000000))),0); + vec_int4 q = vec_cts(xl,0); + + // Compute the offset based on the quadrant that the angle falls in. + // Add 1 to the offset for the cosine. + // + offsetSin = vec_and(q,toM128((int)0x3)); + __m128i temp = _mm_add_epi32(_mm_set1_epi32(1),(__m128i &)offsetSin); + offsetCos = (__m128 &)temp; + + // Remainder in range [-pi/4..pi/4] + // + vec_float4 qf = vec_ctf(q,0); + xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); + + // Compute x^2 and x^3 + // + xl2 = vec_mul(xl,xl); + xl3 = vec_mul(xl2,xl); + + // Compute both the sin and cos of the angles + // using a polynomial expression: + // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and + // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) + // + vec_float4 cx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); + vec_float4 sx = + vec_madd( + vec_madd( + vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); + + // Use the cosine when the offset is odd and the sin + // when the offset is even + // + vec_uint4 sinMask = (vec_uint4)vec_cmpeq(vec_and(offsetSin,toM128(0x1)),_mm_setzero_ps()); + vec_uint4 cosMask = (vec_uint4)vec_cmpeq(vec_and(offsetCos,toM128(0x1)),_mm_setzero_ps()); + *s = vec_sel(cx,sx,sinMask); + *c = vec_sel(cx,sx,cosMask); + + // Flip the sign of the result when (offset mod 4) = 1 or 2 + // + sinMask = vec_cmpeq(vec_and(offsetSin,toM128(0x2)),_mm_setzero_ps()); + cosMask = vec_cmpeq(vec_and(offsetCos,toM128(0x2)),_mm_setzero_ps()); + + *s = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*s),*s,sinMask); + *c = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*c),*c,cosMask); +} + +#include "vecidx_aos.h" +#include "floatInVec.h" +#include "boolInVec.h" + +#ifdef _VECTORMATH_DEBUG +#include +#endif +namespace Vectormath { + +namespace Aos { + +//----------------------------------------------------------------------------- +// Forward Declarations +// + +class Vector3; +class Vector4; +class Point3; +class Quat; +class Matrix3; +class Matrix4; +class Transform3; + +// A 3-D vector in array-of-structures format +// +class Vector3 +{ + __m128 mVec128; + + VECTORMATH_FORCE_INLINE void set128(vec_float4 vec); + + VECTORMATH_FORCE_INLINE vec_float4& get128Ref(); + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Vector3( ) { }; + + // Default copy constructor + // + VECTORMATH_FORCE_INLINE Vector3(const Vector3& vec); + + // Construct a 3-D vector from x, y, and z elements + // + VECTORMATH_FORCE_INLINE Vector3( float x, float y, float z ); + + // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); + + // Copy elements from a 3-D point into a 3-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector3( const Point3 &pnt ); + + // Set all elements of a 3-D vector to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Vector3( float scalar ); + + // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Vector3( const floatInVec &scalar ); + + // Set vector float data in a 3-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector3( __m128 vf4 ); + + // Get vector float data from a 3-D vector + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Assign one 3-D vector to another + // + VECTORMATH_FORCE_INLINE Vector3 & operator =( const Vector3 &vec ); + + // Set the x element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & setX( float x ); + + // Set the y element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & setY( float y ); + + // Set the z element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & setZ( float z ); + + // Set the x element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setX( const floatInVec &x ); + + // Set the y element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setY( const floatInVec &y ); + + // Set the z element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setZ( const floatInVec &z ); + + // Get the x element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Set an x, y, or z element of a 3-D vector by index + // + VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, float value ); + + // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, const floatInVec &value ); + + // Get an x, y, or z element of a 3-D vector by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Add two 3-D vectors + // + VECTORMATH_FORCE_INLINE const Vector3 operator +( const Vector3 &vec ) const; + + // Subtract a 3-D vector from another 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator -( const Vector3 &vec ) const; + + // Add a 3-D vector to a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator +( const Point3 &pnt ) const; + + // Multiply a 3-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar ) const; + + // Divide a 3-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector3 operator /( float scalar ) const; + + // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar ) const; + + // Divide a 3-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector3 operator /( const floatInVec &scalar ) const; + + // Perform compound assignment and addition with a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & operator +=( const Vector3 &vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 & operator -=( const Vector3 &vec ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Vector3 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Vector3 & operator /=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 & operator /=( const floatInVec &scalar ); + + // Negate all elements of a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator -( ) const; + + // Construct x axis + // + static VECTORMATH_FORCE_INLINE const Vector3 xAxis( ); + + // Construct y axis + // + static VECTORMATH_FORCE_INLINE const Vector3 yAxis( ); + + // Construct z axis + // + static VECTORMATH_FORCE_INLINE const Vector3 zAxis( ); + +}; + +// Multiply a 3-D vector by a scalar +// +VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar, const Vector3 &vec ); + +// Multiply a 3-D vector by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ); + +// Multiply two 3-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Divide two 3-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +VECTORMATH_FORCE_INLINE const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Compute the reciprocal of a 3-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +VECTORMATH_FORCE_INLINE const Vector3 recipPerElem( const Vector3 &vec ); + +// Compute the absolute value of a 3-D vector per element +// +VECTORMATH_FORCE_INLINE const Vector3 absPerElem( const Vector3 &vec ); + +// Copy sign from one 3-D vector to another, per element +// +VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Maximum of two 3-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Minimum of two 3-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ); + +// Maximum element of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector3 &vec ); + +// Minimum element of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector3 &vec ); + +// Compute the sum of all elements of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector3 &vec ); + +// Compute the dot product of two 3-D vectors +// +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ); + +// Compute the square of the length of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector3 &vec ); + +// Compute the length of a 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector3 &vec ); + +// Normalize a 3-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +VECTORMATH_FORCE_INLINE const Vector3 normalize( const Vector3 &vec ); + +// Compute cross product of two 3-D vectors +// +VECTORMATH_FORCE_INLINE const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ); + +// Outer product of two 3-D vectors +// +VECTORMATH_FORCE_INLINE const Matrix3 outer( const Vector3 &vec0, const Vector3 &vec1 ); + +// Pre-multiply a row vector by a 3x3 matrix +// NOTE: +// Slower than column post-multiply. +// +VECTORMATH_FORCE_INLINE const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ); + +// Cross-product matrix of a 3-D vector +// +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix( const Vector3 &vec ); + +// Create cross-product matrix and multiply +// NOTE: +// Faster than separately creating a cross-product matrix and multiplying. +// +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ); + +// Linear interpolation between two 3-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ); + +// Linear interpolation between two 3-D vectors (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ); + +// Spherical linear interpolation between two 3-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); + +// Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type) +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); + +// Conditionally select between two 3-D vectors +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ); + +// Conditionally select between two 3-D vectors (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 ); + +// Store x, y, and z elements of 3-D vector in first three words of a quadword, preserving fourth word +// +VECTORMATH_FORCE_INLINE void storeXYZ( const Vector3 &vec, __m128 * quad ); + +// Load four three-float 3-D vectors, stored in three quadwords +// +VECTORMATH_FORCE_INLINE void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ); + +// Store four 3-D vectors in three quadwords +// +VECTORMATH_FORCE_INLINE void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ); + +// Store eight 3-D vectors as half-floats +// +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec ); + +// Print a 3-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name ); + +#endif + +// A 4-D vector in array-of-structures format +// +class Vector4 +{ + __m128 mVec128; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Vector4( ) { }; + + // Construct a 4-D vector from x, y, z, and w elements + // + VECTORMATH_FORCE_INLINE Vector4( float x, float y, float z, float w ); + + // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); + + // Construct a 4-D vector from a 3-D vector and a scalar + // + VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, float w ); + + // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, const floatInVec &w ); + + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit VECTORMATH_FORCE_INLINE Vector4( const Vector3 &vec ); + + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit VECTORMATH_FORCE_INLINE Vector4( const Point3 &pnt ); + + // Copy elements from a quaternion into a 4-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector4( const Quat &quat ); + + // Set all elements of a 4-D vector to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Vector4( float scalar ); + + // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Vector4( const floatInVec &scalar ); + + // Set vector float data in a 4-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector4( __m128 vf4 ); + + // Get vector float data from a 4-D vector + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Assign one 4-D vector to another + // + VECTORMATH_FORCE_INLINE Vector4 & operator =( const Vector4 &vec ); + + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + VECTORMATH_FORCE_INLINE Vector4 & setXYZ( const Vector3 &vec ); + + // Get the x, y, and z elements of a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const; + + // Set the x element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setX( float x ); + + // Set the y element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setY( float y ); + + // Set the z element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setZ( float z ); + + // Set the w element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & setW( float w ); + + // Set the x element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setX( const floatInVec &x ); + + // Set the y element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setY( const floatInVec &y ); + + // Set the z element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setZ( const floatInVec &z ); + + // Set the w element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setW( const floatInVec &w ); + + // Get the x element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Get the w element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getW( ) const; + + // Set an x, y, z, or w element of a 4-D vector by index + // + VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, float value ); + + // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, const floatInVec &value ); + + // Get an x, y, z, or w element of a 4-D vector by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Add two 4-D vectors + // + VECTORMATH_FORCE_INLINE const Vector4 operator +( const Vector4 &vec ) const; + + // Subtract a 4-D vector from another 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator -( const Vector4 &vec ) const; + + // Multiply a 4-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar ) const; + + // Divide a 4-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector4 operator /( float scalar ) const; + + // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar ) const; + + // Divide a 4-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector4 operator /( const floatInVec &scalar ) const; + + // Perform compound assignment and addition with a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & operator +=( const Vector4 &vec ); + + // Perform compound assignment and subtraction by a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 & operator -=( const Vector4 &vec ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Vector4 & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Vector4 & operator /=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 & operator /=( const floatInVec &scalar ); + + // Negate all elements of a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator -( ) const; + + // Construct x axis + // + static VECTORMATH_FORCE_INLINE const Vector4 xAxis( ); + + // Construct y axis + // + static VECTORMATH_FORCE_INLINE const Vector4 yAxis( ); + + // Construct z axis + // + static VECTORMATH_FORCE_INLINE const Vector4 zAxis( ); + + // Construct w axis + // + static VECTORMATH_FORCE_INLINE const Vector4 wAxis( ); + +}; + +// Multiply a 4-D vector by a scalar +// +VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar, const Vector4 &vec ); + +// Multiply a 4-D vector by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ); + +// Multiply two 4-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Divide two 4-D vectors per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +VECTORMATH_FORCE_INLINE const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Compute the reciprocal of a 4-D vector per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +VECTORMATH_FORCE_INLINE const Vector4 recipPerElem( const Vector4 &vec ); + +// Compute the absolute value of a 4-D vector per element +// +VECTORMATH_FORCE_INLINE const Vector4 absPerElem( const Vector4 &vec ); + +// Copy sign from one 4-D vector to another, per element +// +VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Maximum of two 4-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Minimum of two 4-D vectors per element +// +VECTORMATH_FORCE_INLINE const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ); + +// Maximum element of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector4 &vec ); + +// Minimum element of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector4 &vec ); + +// Compute the sum of all elements of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector4 &vec ); + +// Compute the dot product of two 4-D vectors +// +VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ); + +// Compute the square of the length of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector4 &vec ); + +// Compute the length of a 4-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec length( const Vector4 &vec ); + +// Normalize a 4-D vector +// NOTE: +// The result is unpredictable when all elements of vec are at or near zero. +// +VECTORMATH_FORCE_INLINE const Vector4 normalize( const Vector4 &vec ); + +// Outer product of two 4-D vectors +// +VECTORMATH_FORCE_INLINE const Matrix4 outer( const Vector4 &vec0, const Vector4 &vec1 ); + +// Linear interpolation between two 4-D vectors +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ); + +// Linear interpolation between two 4-D vectors (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ); + +// Spherical linear interpolation between two 4-D vectors +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); + +// Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type) +// NOTE: +// The result is unpredictable if the vectors point in opposite directions. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); + +// Conditionally select between two 4-D vectors +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ); + +// Conditionally select between two 4-D vectors (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 ); + +// Store four 4-D vectors as half-floats +// +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4-D vector +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec ); + +// Print a 4-D vector and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name ); + +#endif + +// A 3-D point in array-of-structures format +// +class Point3 +{ + __m128 mVec128; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Point3( ) { }; + + // Construct a 3-D point from x, y, and z elements + // + VECTORMATH_FORCE_INLINE Point3( float x, float y, float z ); + + // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); + + // Copy elements from a 3-D vector into a 3-D point + // + explicit VECTORMATH_FORCE_INLINE Point3( const Vector3 &vec ); + + // Set all elements of a 3-D point to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Point3( float scalar ); + + // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Point3( const floatInVec &scalar ); + + // Set vector float data in a 3-D point + // + explicit VECTORMATH_FORCE_INLINE Point3( __m128 vf4 ); + + // Get vector float data from a 3-D point + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Assign one 3-D point to another + // + VECTORMATH_FORCE_INLINE Point3 & operator =( const Point3 &pnt ); + + // Set the x element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 & setX( float x ); + + // Set the y element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 & setY( float y ); + + // Set the z element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 & setZ( float z ); + + // Set the x element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setX( const floatInVec &x ); + + // Set the y element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setY( const floatInVec &y ); + + // Set the z element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setZ( const floatInVec &z ); + + // Get the x element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Set an x, y, or z element of a 3-D point by index + // + VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, float value ); + + // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, const floatInVec &value ); + + // Get an x, y, or z element of a 3-D point by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Subtract a 3-D point from another 3-D point + // + VECTORMATH_FORCE_INLINE const Vector3 operator -( const Point3 &pnt ) const; + + // Add a 3-D point to a 3-D vector + // + VECTORMATH_FORCE_INLINE const Point3 operator +( const Vector3 &vec ) const; + + // Subtract a 3-D vector from a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator -( const Vector3 &vec ) const; + + // Perform compound assignment and addition with a 3-D vector + // + VECTORMATH_FORCE_INLINE Point3 & operator +=( const Vector3 &vec ); + + // Perform compound assignment and subtraction by a 3-D vector + // + VECTORMATH_FORCE_INLINE Point3 & operator -=( const Vector3 &vec ); + +}; + +// Multiply two 3-D points per element +// +VECTORMATH_FORCE_INLINE const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Divide two 3-D points per element +// NOTE: +// Floating-point behavior matches standard library function divf4. +// +VECTORMATH_FORCE_INLINE const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Compute the reciprocal of a 3-D point per element +// NOTE: +// Floating-point behavior matches standard library function recipf4. +// +VECTORMATH_FORCE_INLINE const Point3 recipPerElem( const Point3 &pnt ); + +// Compute the absolute value of a 3-D point per element +// +VECTORMATH_FORCE_INLINE const Point3 absPerElem( const Point3 &pnt ); + +// Copy sign from one 3-D point to another, per element +// +VECTORMATH_FORCE_INLINE const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Maximum of two 3-D points per element +// +VECTORMATH_FORCE_INLINE const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Minimum of two 3-D points per element +// +VECTORMATH_FORCE_INLINE const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ); + +// Maximum element of a 3-D point +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Point3 &pnt ); + +// Minimum element of a 3-D point +// +VECTORMATH_FORCE_INLINE const floatInVec minElem( const Point3 &pnt ); + +// Compute the sum of all elements of a 3-D point +// +VECTORMATH_FORCE_INLINE const floatInVec sum( const Point3 &pnt ); + +// Apply uniform scale to a 3-D point +// +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, float scaleVal ); + +// Apply uniform scale to a 3-D point (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ); + +// Apply non-uniform scale to a 3-D point +// +VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ); + +// Scalar projection of a 3-D point on a unit-length 3-D vector +// +VECTORMATH_FORCE_INLINE const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ); + +// Compute the square of the distance of a 3-D point from the coordinate-system origin +// +VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin( const Point3 &pnt ); + +// Compute the distance of a 3-D point from the coordinate-system origin +// +VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin( const Point3 &pnt ); + +// Compute the square of the distance between two 3-D points +// +VECTORMATH_FORCE_INLINE const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ); + +// Compute the distance between two 3-D points +// +VECTORMATH_FORCE_INLINE const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ); + +// Linear interpolation between two 3-D points +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ); + +// Linear interpolation between two 3-D points (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ); + +// Conditionally select between two 3-D points +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ); + +// Conditionally select between two 3-D points (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ); + +// Store x, y, and z elements of 3-D point in first three words of a quadword, preserving fourth word +// +VECTORMATH_FORCE_INLINE void storeXYZ( const Point3 &pnt, __m128 * quad ); + +// Load four three-float 3-D points, stored in three quadwords +// +VECTORMATH_FORCE_INLINE void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ); + +// Store four 3-D points in three quadwords +// +VECTORMATH_FORCE_INLINE void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ); + +// Store eight 3-D points as half-floats +// +VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3-D point +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt ); + +// Print a 3-D point and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name ); + +#endif + +// A quaternion in array-of-structures format +// +class Quat +{ + __m128 mVec128; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Quat( ) { }; + + VECTORMATH_FORCE_INLINE Quat(const Quat& quat); + + // Construct a quaternion from x, y, z, and w elements + // + VECTORMATH_FORCE_INLINE Quat( float x, float y, float z, float w ); + + // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); + + // Construct a quaternion from a 3-D vector and a scalar + // + VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, float w ); + + // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, const floatInVec &w ); + + // Copy elements from a 4-D vector into a quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat( const Vector4 &vec ); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat( const Matrix3 & rotMat ); + + // Set all elements of a quaternion to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Quat( float scalar ); + + // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Quat( const floatInVec &scalar ); + + // Set vector float data in a quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat( __m128 vf4 ); + + // Get vector float data from a quaternion + // + VECTORMATH_FORCE_INLINE __m128 get128( ) const; + + // Set a quaterion from vector float data + // + VECTORMATH_FORCE_INLINE void set128(vec_float4 vec); + + // Assign one quaternion to another + // + VECTORMATH_FORCE_INLINE Quat & operator =( const Quat &quat ); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + VECTORMATH_FORCE_INLINE Quat & setXYZ( const Vector3 &vec ); + + // Get the x, y, and z elements of a quaternion + // + VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const; + + // Set the x element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setX( float x ); + + // Set the y element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setY( float y ); + + // Set the z element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setZ( float z ); + + // Set the w element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat & setW( float w ); + + // Set the x element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setX( const floatInVec &x ); + + // Set the y element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setY( const floatInVec &y ); + + // Set the z element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setZ( const floatInVec &z ); + + // Set the w element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setW( const floatInVec &w ); + + // Get the x element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + + // Get the y element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + + // Get the z element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + + // Get the w element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getW( ) const; + + // Set an x, y, z, or w element of a quaternion by index + // + VECTORMATH_FORCE_INLINE Quat & setElem( int idx, float value ); + + // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & setElem( int idx, const floatInVec &value ); + + // Get an x, y, z, or w element of a quaternion by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + + // Add two quaternions + // + VECTORMATH_FORCE_INLINE const Quat operator +( const Quat &quat ) const; + + // Subtract a quaternion from another quaternion + // + VECTORMATH_FORCE_INLINE const Quat operator -( const Quat &quat ) const; + + // Multiply two quaternions + // + VECTORMATH_FORCE_INLINE const Quat operator *( const Quat &quat ) const; + + // Multiply a quaternion by a scalar + // + VECTORMATH_FORCE_INLINE const Quat operator *( float scalar ) const; + + // Divide a quaternion by a scalar + // + VECTORMATH_FORCE_INLINE const Quat operator /( float scalar ) const; + + // Multiply a quaternion by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar ) const; + + // Divide a quaternion by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Quat operator /( const floatInVec &scalar ) const; + + // Perform compound assignment and addition with a quaternion + // + VECTORMATH_FORCE_INLINE Quat & operator +=( const Quat &quat ); + + // Perform compound assignment and subtraction by a quaternion + // + VECTORMATH_FORCE_INLINE Quat & operator -=( const Quat &quat ); + + // Perform compound assignment and multiplication by a quaternion + // + VECTORMATH_FORCE_INLINE Quat & operator *=( const Quat &quat ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Quat & operator *=( float scalar ); + + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Quat & operator /=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat & operator /=( const floatInVec &scalar ); + + // Negate all elements of a quaternion + // + VECTORMATH_FORCE_INLINE const Quat operator -( ) const; + + // Construct an identity quaternion + // + static VECTORMATH_FORCE_INLINE const Quat identity( ); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static VECTORMATH_FORCE_INLINE const Quat rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Quat rotation( float radians, const Vector3 &unitVec ); + + // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a quaternion to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationX( float radians ); + + // Construct a quaternion to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationY( float radians ); + + // Construct a quaternion to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationZ( float radians ); + + // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationX( const floatInVec &radians ); + + // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationY( const floatInVec &radians ); + + // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationZ( const floatInVec &radians ); + +}; + +// Multiply a quaternion by a scalar +// +VECTORMATH_FORCE_INLINE const Quat operator *( float scalar, const Quat &quat ); + +// Multiply a quaternion by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar, const Quat &quat ); + +// Compute the conjugate of a quaternion +// +VECTORMATH_FORCE_INLINE const Quat conj( const Quat &quat ); + +// Use a unit-length quaternion to rotate a 3-D vector +// +VECTORMATH_FORCE_INLINE const Vector3 rotate( const Quat &unitQuat, const Vector3 &vec ); + +// Compute the dot product of two quaternions +// +VECTORMATH_FORCE_INLINE const floatInVec dot( const Quat &quat0, const Quat &quat1 ); + +// Compute the norm of a quaternion +// +VECTORMATH_FORCE_INLINE const floatInVec norm( const Quat &quat ); + +// Compute the length of a quaternion +// +VECTORMATH_FORCE_INLINE const floatInVec length( const Quat &quat ); + +// Normalize a quaternion +// NOTE: +// The result is unpredictable when all elements of quat are at or near zero. +// +VECTORMATH_FORCE_INLINE const Quat normalize( const Quat &quat ); + +// Linear interpolation between two quaternions +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ); + +// Linear interpolation between two quaternions (scalar data contained in vector data type) +// NOTE: +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ); + +// Spherical linear interpolation between two quaternions +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ); + +// Spherical linear interpolation between two quaternions (scalar data contained in vector data type) +// NOTE: +// Interpolates along the shortest path between orientations. +// Does not clamp t between 0 and 1. +// +VECTORMATH_FORCE_INLINE const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ); + +// Spherical quadrangle interpolation +// +VECTORMATH_FORCE_INLINE const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); + +// Spherical quadrangle interpolation (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); + +// Conditionally select between two quaternions +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ); + +// Conditionally select between two quaternions (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a quaternion +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Quat &quat ); + +// Print a quaternion and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name ); + +#endif + +// A 3x3 matrix in array-of-structures format +// +class Matrix3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Matrix3( ) { }; + + // Copy a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3( const Matrix3 & mat ); + + // Construct a 3x3 matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Matrix3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2 ); + + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit VECTORMATH_FORCE_INLINE Matrix3( const Quat &unitQuat ); + + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Matrix3( float scalar ); + + // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Matrix3( const floatInVec &scalar ); + + // Assign one 3x3 matrix to another + // + VECTORMATH_FORCE_INLINE Matrix3 & operator =( const Matrix3 & mat ); + + // Set column 0 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol0( const Vector3 &col0 ); + + // Set column 1 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol1( const Vector3 &col1 ); + + // Set column 2 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol2( const Vector3 &col2 ); + + // Get column 0 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const; + + // Get column 1 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const; + + // Get column 2 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const; + + // Set the column of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix3 & setCol( int col, const Vector3 &vec ); + + // Set the row of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix3 & setRow( int row, const Vector3 &vec ); + + // Get the column of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const; + + // Get the row of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const; + + // Set the element of a 3x3 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, float val ); + + // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, const floatInVec &val ); + + // Get the element of a 3x3 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + + // Add two 3x3 matrices + // + VECTORMATH_FORCE_INLINE const Matrix3 operator +( const Matrix3 & mat ) const; + + // Subtract a 3x3 matrix from another 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 operator -( const Matrix3 & mat ) const; + + // Negate all elements of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 operator -( ) const; + + // Multiply a 3x3 matrix by a scalar + // + VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar ) const; + + // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar ) const; + + // Multiply a 3x3 matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const; + + // Multiply two 3x3 matrices + // + VECTORMATH_FORCE_INLINE const Matrix3 operator *( const Matrix3 & mat ) const; + + // Perform compound assignment and addition with a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & operator +=( const Matrix3 & mat ); + + // Perform compound assignment and subtraction by a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & operator -=( const Matrix3 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Matrix3 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and multiplication by a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const Matrix3 & mat ); + + // Construct an identity 3x3 matrix + // + static VECTORMATH_FORCE_INLINE const Matrix3 identity( ); + + // Construct a 3x3 matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( float radians ); + + // Construct a 3x3 matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( float radians ); + + // Construct a 3x3 matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( float radians ); + + // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( const floatInVec &radians ); + + // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( const floatInVec &radians ); + + // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( const floatInVec &radians ); + + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZYX( const Vector3 &radiansXYZ ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation( float radians, const Vector3 &unitVec ); + + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const Quat &unitQuat ); + + // Construct a 3x3 matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Matrix3 scale( const Vector3 &scaleVec ); + +}; +// Multiply a 3x3 matrix by a scalar +// +VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar, const Matrix3 & mat ); + +// Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ); + +// Append (post-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x3 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ); + +// Multiply two 3x3 matrices per element +// +VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); + +// Compute the absolute value of a 3x3 matrix per element +// +VECTORMATH_FORCE_INLINE const Matrix3 absPerElem( const Matrix3 & mat ); + +// Transpose of a 3x3 matrix +// +VECTORMATH_FORCE_INLINE const Matrix3 transpose( const Matrix3 & mat ); + +// Compute the inverse of a 3x3 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Matrix3 inverse( const Matrix3 & mat ); + +// Determinant of a 3x3 matrix +// +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix3 & mat ); + +// Conditionally select between two 3x3 matrices +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); + +// Conditionally select between two 3x3 matrices (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x3 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat ); + +// Print a 3x3 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name ); + +#endif + +// A 4x4 matrix in array-of-structures format +// +class Matrix4 +{ + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Matrix4( ) { }; + + // Copy a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4( const Matrix4 & mat ); + + // Construct a 4x4 matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Matrix4( const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3 ); + + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit VECTORMATH_FORCE_INLINE Matrix4( const Transform3 & mat ); + + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + VECTORMATH_FORCE_INLINE Matrix4( const Matrix3 & mat, const Vector3 &translateVec ); + + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + VECTORMATH_FORCE_INLINE Matrix4( const Quat &unitQuat, const Vector3 &translateVec ); + + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Matrix4( float scalar ); + + // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Matrix4( const floatInVec &scalar ); + + // Assign one 4x4 matrix to another + // + VECTORMATH_FORCE_INLINE Matrix4 & operator =( const Matrix4 & mat ); + + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + VECTORMATH_FORCE_INLINE Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const; + + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + VECTORMATH_FORCE_INLINE Matrix4 & setTranslation( const Vector3 &translateVec ); + + // Get the translation component of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const; + + // Set column 0 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol0( const Vector4 &col0 ); + + // Set column 1 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol1( const Vector4 &col1 ); + + // Set column 2 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol2( const Vector4 &col2 ); + + // Set column 3 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol3( const Vector4 &col3 ); + + // Get column 0 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol0( ) const; + + // Get column 1 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol1( ) const; + + // Get column 2 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol2( ) const; + + // Get column 3 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol3( ) const; + + // Set the column of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix4 & setCol( int col, const Vector4 &vec ); + + // Set the row of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix4 & setRow( int row, const Vector4 &vec ); + + // Get the column of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getCol( int col ) const; + + // Get the row of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector4 & operator []( int col ); + + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector4 operator []( int col ) const; + + // Set the element of a 4x4 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, float val ); + + // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, const floatInVec &val ); + + // Get the element of a 4x4 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + + // Add two 4x4 matrices + // + VECTORMATH_FORCE_INLINE const Matrix4 operator +( const Matrix4 & mat ) const; + + // Subtract a 4x4 matrix from another 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator -( const Matrix4 & mat ) const; + + // Negate all elements of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator -( ) const; + + // Multiply a 4x4 matrix by a scalar + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar ) const; + + // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar ) const; + + // Multiply a 4x4 matrix by a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector4 &vec ) const; + + // Multiply a 4x4 matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector3 &vec ) const; + + // Multiply a 4x4 matrix by a 3-D point + // + VECTORMATH_FORCE_INLINE const Vector4 operator *( const Point3 &pnt ) const; + + // Multiply two 4x4 matrices + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Matrix4 & mat ) const; + + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and addition with a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator +=( const Matrix4 & mat ); + + // Perform compound assignment and subtraction by a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator -=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( float scalar ); + + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const floatInVec &scalar ); + + // Perform compound assignment and multiplication by a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Matrix4 & mat ); + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 4x4 matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 identity( ); + + // Construct a 4x4 matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( float radians ); + + // Construct a 4x4 matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( float radians ); + + // Construct a 4x4 matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( float radians ); + + // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( const floatInVec &radians ); + + // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( const floatInVec &radians ); + + // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( const floatInVec &radians ); + + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZYX( const Vector3 &radiansXYZ ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation( float radians, const Vector3 &unitVec ); + + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const Quat &unitQuat ); + + // Construct a 4x4 matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Matrix4 scale( const Vector3 &scaleVec ); + + // Construct a 4x4 matrix to perform translation + // + static VECTORMATH_FORCE_INLINE const Matrix4 translation( const Vector3 &translateVec ); + + // Construct viewing matrix based on eye, position looked at, and up direction + // + static VECTORMATH_FORCE_INLINE const Matrix4 lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ); + + // Construct a perspective projection matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + + // Construct a perspective projection matrix based on frustum + // + static VECTORMATH_FORCE_INLINE const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); + + // Construct an orthographic projection matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + +}; +// Multiply a 4x4 matrix by a scalar +// +VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar, const Matrix4 & mat ); + +// Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) +// +VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ); + +// Append (post-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 4x4 matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ); + +// Multiply two 4x4 matrices per element +// +VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); + +// Compute the absolute value of a 4x4 matrix per element +// +VECTORMATH_FORCE_INLINE const Matrix4 absPerElem( const Matrix4 & mat ); + +// Transpose of a 4x4 matrix +// +VECTORMATH_FORCE_INLINE const Matrix4 transpose( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix +// NOTE: +// Result is unpredictable when the determinant of mat is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Matrix4 affineInverse( const Matrix4 & mat ); + +// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. +// +VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse( const Matrix4 & mat ); + +// Determinant of a 4x4 matrix +// +VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat ); + +// Conditionally select between two 4x4 matrices +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); + +// Conditionally select between two 4x4 matrices (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 4x4 matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat ); + +// Print a 4x4 matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name ); + +#endif + +// A 3x4 transformation matrix in array-of-structures format +// +class Transform3 +{ + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; + +public: + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Transform3( ) { }; + + // Copy a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3( const Transform3 & tfrm ); + + // Construct a 3x4 transformation matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Transform3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3 ); + + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + VECTORMATH_FORCE_INLINE Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ); + + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + VECTORMATH_FORCE_INLINE Transform3( const Quat &unitQuat, const Vector3 &translateVec ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Transform3( float scalar ); + + // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Transform3( const floatInVec &scalar ); + + // Assign one 3x4 transformation matrix to another + // + VECTORMATH_FORCE_INLINE Transform3 & operator =( const Transform3 & tfrm ); + + // Set the upper-left 3x3 submatrix + // + VECTORMATH_FORCE_INLINE Transform3 & setUpper3x3( const Matrix3 & mat3 ); + + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const; + + // Set translation component + // + VECTORMATH_FORCE_INLINE Transform3 & setTranslation( const Vector3 &translateVec ); + + // Get the translation component of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const; + + // Set column 0 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol0( const Vector3 &col0 ); + + // Set column 1 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol1( const Vector3 &col1 ); + + // Set column 2 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol2( const Vector3 &col2 ); + + // Set column 3 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & setCol3( const Vector3 &col3 ); + + // Get column 0 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const; + + // Get column 1 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const; + + // Get column 2 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const; + + // Get column 3 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol3( ) const; + + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Transform3 & setCol( int col, const Vector3 &vec ); + + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Transform3 & setRow( int row, const Vector4 &vec ); + + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const; + + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const; + + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector3 & operator []( int col ); + + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const; + + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, float val ); + + // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, const floatInVec &val ); + + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + + // Multiply a 3x4 transformation matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const; + + // Multiply a 3x4 transformation matrix by a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator *( const Point3 &pnt ) const; + + // Multiply two 3x4 transformation matrices + // + VECTORMATH_FORCE_INLINE const Transform3 operator *( const Transform3 & tfrm ) const; + + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 & operator *=( const Transform3 & tfrm ); + + // Construct an identity 3x4 transformation matrix + // + static VECTORMATH_FORCE_INLINE const Transform3 identity( ); + + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationX( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationY( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( float radians ); + + // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationX( const floatInVec &radians ); + + // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationY( const floatInVec &radians ); + + // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( const floatInVec &radians ); + + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZYX( const Vector3 &radiansXYZ ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation( float radians, const Vector3 &unitVec ); + + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation( const floatInVec &radians, const Vector3 &unitVec ); + + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation( const Quat &unitQuat ); + + // Construct a 3x4 transformation matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Transform3 scale( const Vector3 &scaleVec ); + + // Construct a 3x4 transformation matrix to perform translation + // + static VECTORMATH_FORCE_INLINE const Transform3 translation( const Vector3 &translateVec ); + +}; +// Append (post-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ); + +// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix +// NOTE: +// Faster than creating and multiplying a scale transformation matrix. +// +VECTORMATH_FORCE_INLINE const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ); + +// Multiply two 3x4 transformation matrices per element +// +VECTORMATH_FORCE_INLINE const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); + +// Compute the absolute value of a 3x4 transformation matrix per element +// +VECTORMATH_FORCE_INLINE const Transform3 absPerElem( const Transform3 & tfrm ); + +// Inverse of a 3x4 transformation matrix +// NOTE: +// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. +// +VECTORMATH_FORCE_INLINE const Transform3 inverse( const Transform3 & tfrm ); + +// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix +// NOTE: +// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. +// +VECTORMATH_FORCE_INLINE const Transform3 orthoInverse( const Transform3 & tfrm ); + +// Conditionally select between two 3x4 transformation matrices +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// However, the transfer of select1 to a VMX register may use more processing time than a branch. +// Use the boolInVec version for better performance. +// +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); + +// Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type) +// NOTE: +// This function uses a conditional select instruction to avoid a branch. +// +VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ); + +#ifdef _VECTORMATH_DEBUG + +// Print a 3x4 transformation matrix +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm ); + +// Print a 3x4 transformation matrix and an associated string identifier +// NOTE: +// Function is only defined when _VECTORMATH_DEBUG is defined. +// +VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm, const char * name ); + +#endif + +} // namespace Aos +} // namespace Vectormath + +#include "vec_aos.h" +#include "quat_aos.h" +#include "mat_aos.h" + +#endif diff --git a/src/vectormath/vmInclude.h b/src/vectormath/vmInclude.h new file mode 100644 index 0000000..656514e --- /dev/null +++ b/src/vectormath/vmInclude.h @@ -0,0 +1,31 @@ + +#ifndef __VM_INCLUDE_H +#define __VM_INCLUDE_H + +#include "LinearMath/btScalar.h" + +#if defined (USE_SYSTEM_VECTORMATH) || defined (__CELLOS_LV2__) + #include +#else //(USE_SYSTEM_VECTORMATH) + #if defined (BT_USE_SSE) + #include "sse/vectormath_aos.h" + #else //all other platforms + #if defined (BT_USE_NEON) + #include "neon/vectormath_aos.h" + #else + #include "scalar/vectormath_aos.h" + #endif + #endif //(BT_USE_SSE) && defined (_WIN32) +#endif //(USE_SYSTEM_VECTORMATH) + + + +typedef Vectormath::Aos::Vector3 vmVector3; +typedef Vectormath::Aos::Quat vmQuat; +typedef Vectormath::Aos::Matrix3 vmMatrix3; +typedef Vectormath::Aos::Transform3 vmTransform3; +typedef Vectormath::Aos::Point3 vmPoint3; + +#endif //__VM_INCLUDE_H + + diff --git a/test1.oec b/test1.oec new file mode 100644 index 0000000..7fac1d1 --- /dev/null +++ b/test1.oec @@ -0,0 +1,227 @@ +# OctaveEngine Casual (Jul 14 2008) +version 2 +p 22000 1 ff 7fff66ff 13 79 0 0 13 79 0 0 0 +p 22000 1 ff 7fff66ff 12.25 77.5 0 0 12.25 77.5 0 0 0 +p 22000 1 ff 7fff66ff 12.25 78.25 0 0 12.25 78.25 0 0 0 +p 22000 1 ff 7fff66ff 13 77.5 0 0 13 77.5 0 0 0 +p 22000 1 ff 7fff66ff 13 78.25 0 0 13 78.25 0 0 0 +p 22000 1 ff 7fff66ff 13.75 77.5 0 0 13.75 77.5 0 0 0 +p 22000 1 ff 7fff66ff 13.75 78.25 0 0 13.75 78.25 0 0 0 +p 22000 2 ff 7fff66ff 14.75 73.625 0 0 14.75 73.625 0 0 0 +p 22000 2 ff 7fff66ff 15.5 73.625 0 0 15.5 73.625 0 0 0 +p 22000 2 ff 7fff66ff 16.25 73.625 0 0 16.25 73.625 0 0 0 +p 22000 2 ff 7fff66ff 17 73.625 0 0 17 73.625 0 0 0 +p 22000 2 ff 7fff66ff 17.75 73.625 0 0 17.75 73.625 0 0 0 +p 22000 2 ff 7fff66ff 18.5 73.625 0 0 18.5 73.625 0 0 0 +p 22000 3 ff 7fff66ff 26 79 0 0 26 79 0 0 0 +p 22000 3 ff 7fff66ff 26.2372 78.2885 0 0 26.2372 78.2885 0 0 0 +p 22000 3 ff 7fff66ff 26.9705 78.1313 0 0 26.9705 78.1313 0 0 0 +p 22000 3 ff 7fff66ff 27.2344 78.8334 0 0 27.2344 78.8334 0 0 0 +p 22000 3 ff 7fff66ff 27.0215 79.5525 0 0 27.0215 79.5525 0 0 0 +p 22000 3 ff 7fff66ff 26.5164 80.107 0 0 26.5164 80.107 0 0 0 +p 22000 4 ff 7fff66ff 42 73.875 0 0 42 73.875 0 0 0 +p 22000 4 ff 7fff66ff 42.5857 73.4065 0 0 42.5857 73.4065 0 0 0 +p 22000 4 ff 7fff66ff 41.8884 73.1303 0 0 41.8884 73.1303 0 0 0 +p 22000 4 ff 7fff66ff 41.3003 72.6648 0 0 41.3003 72.6648 0 0 0 +p 22000 4 ff 7fff66ff 40.6805 73.0872 0 0 40.6805 73.0872 0 0 0 +p 22000 5 ff 7fff66ff 57.125 74 0 0 57.125 74 0 0 0 +p 22000 5 ff 7fff66ff 57.7958 73.6646 0 0 57.7958 73.6646 0 0 0 +p 22000 5 ff 7fff66ff 58.1111 74.3451 0 0 58.1111 74.3451 0 0 0 +p 22000 5 ff 7fff66ff 57.5445 74.8364 0 0 57.5445 74.8364 0 0 0 +p 822000 12 ff 99cc7fff 41.875 70 0 0 41.875 70 0 0 0 +p 822000 12 ff 99cc7fff 41.125 70 0 0 41.125 70 0 0 0 +p 822000 12 ff 99cc7fff 40.3852 70.1233 0 0 40.3852 70.1233 0 0 0 +p 822000 12 ff 99cc7fff 39.6352 70.125 0 0 39.6352 70.125 0 0 0 +p 822000 12 ff 99cc7fff 38.8926 70.2299 0 0 38.8926 70.2299 0 0 0 +p 822000 12 ff 99cc7fff 38.1428 70.2495 0 0 38.1428 70.2495 0 0 0 +p 822000 12 ff 99cc7fff 37.3928 70.25 0 0 37.3928 70.25 0 0 0 +p 22000 15 ff 7fff66ff 62.25 57.625 0 0 62.25 57.625 0 0 0 +p 22000 15 ff 7fff66ff 62.9615 57.3878 0 0 62.9615 57.3878 0 0 0 +p 22000 15 ff 7fff66ff 62.8866 58.1341 0 0 62.8866 58.1341 0 0 0 +p 22000 15 ff 7fff66ff 62.2927 58.5921 0 0 62.2927 58.5921 0 0 0 +p 22000 14 ff 7fff66ff 46.875 59 0 0 46.875 59 0 0 0 +p 22000 14 ff 7fff66ff 47.3435 58.4143 0 0 47.3435 58.4143 0 0 0 +p 22000 14 ff 7fff66ff 48.0775 58.26 0 0 48.0775 58.26 0 0 0 +p 22000 14 ff 7fff66ff 48.4494 58.9113 0 0 48.4494 58.9113 0 0 0 +p 22000 14 ff 7fff66ff 48.2759 59.641 0 0 48.2759 59.641 0 0 0 +p 22000 17 ff 7fff66ff 32.625 58.625 0 0 32.625 58.625 0 0 0 +p 22000 17 ff 7fff66ff 33.2958 58.2896 0 0 33.2958 58.2896 0 0 0 +p 22000 17 ff 7fff66ff 34.045 58.2538 0 0 34.045 58.2538 0 0 0 +p 22000 17 ff 7fff66ff 34.3483 58.9397 0 0 34.3483 58.9397 0 0 0 +p 22000 16 ff 7fff66ff 23 50 0 0 23 50 0 0 0 +p 22000 16 ff 7fff66ff 23.6512 49.6279 0 0 23.6512 49.6279 0 0 0 +p 22000 16 ff 7fff66ff 24.3928 49.5162 0 0 24.3928 49.5162 0 0 0 +p 22000 16 ff 7fff66ff 24.1695 50.2321 0 0 24.1695 50.2321 0 0 0 +p 22000 18 ff 7fff66ff 18.375 59.25 0 0 18.375 59.25 0 0 0 +p 22000 18 ff 7fff66ff 18.9053 58.7197 0 0 18.9053 58.7197 0 0 0 +p 22000 18 ff 7fff66ff 19.4651 59.2189 0 0 19.4651 59.2189 0 0 0 +p 22000 18 ff 7fff66ff 19.3792 59.9639 0 0 19.3792 59.9639 0 0 0 +p 22000 7 ff 7fff66ff 44.125 51.75 0 0 44.125 51.75 0 0 0 +p 22000 7 ff 7fff66ff 44.0017 51.0102 0 0 44.0017 51.0102 0 0 0 +p 22000 7 ff 7fff66ff 44.743 51.1239 0 0 44.743 51.1239 0 0 0 +p 22000 7 ff 7fff66ff 45.0428 51.8114 0 0 45.0428 51.8114 0 0 0 +p 22000 8 ff 7fff66ff 59.125 49.375 0 0 59.125 49.375 0 0 0 +p 22000 8 ff 7fff66ff 59.125 48.625 0 0 59.125 48.625 0 0 0 +p 22000 8 ff 7fff66ff 59.7958 48.2896 0 0 59.7958 48.2896 0 0 0 +p 22000 8 ff 7fff66ff 59.9739 49.0181 0 0 59.9739 49.0181 0 0 0 +p 22000 9 ff 7fff66ff 42.5 41.625 0 0 42.5 41.625 0 0 0 +p 22000 9 ff 7fff66ff 43.0303 41.0947 0 0 43.0303 41.0947 0 0 0 +p 22000 9 ff 7fff66ff 43.7798 41.1216 0 0 43.7798 41.1216 0 0 0 +p 22000 9 ff 7fff66ff 44.3525 41.6059 0 0 44.3525 41.6059 0 0 0 +p 22000 9 ff 7fff66ff 43.9569 42.2431 0 0 43.9569 42.2431 0 0 0 +p 22000 a ff 7fff66ff 70.375 63.125 0 0 70.375 63.125 0 0 0 +p 22000 a ff 7fff66ff 70.375 62.375 0 0 70.375 62.375 0 0 0 +p 22000 a ff 7fff66ff 71.1148 62.4983 0 0 71.1148 62.4983 0 0 0 +p 22000 a ff 7fff66ff 71.2476 63.2365 0 0 71.2476 63.2365 0 0 0 +p 22000 b ff 7fff66ff 15.5 40.375 0 0 15.5 40.375 0 0 0 +p 22000 b ff 7fff66ff 16.124 39.959 0 0 16.124 39.959 0 0 0 +p 22000 b ff 7fff66ff 16.8729 39.9999 0 0 16.8729 39.9999 0 0 0 +p 22000 b ff 7fff66ff 17.2098 40.67 0 0 17.2098 40.67 0 0 0 +p 22000 c ff 7fff66ff 29.375 37.875 0 0 29.375 37.875 0 0 0 +p 22000 c ff 7fff66ff 29.791 37.251 0 0 29.791 37.251 0 0 0 +p 22000 c ff 7fff66ff 30.5326 37.139 0 0 30.5326 37.139 0 0 0 +p 22000 c ff 7fff66ff 30.6126 37.8847 0 0 30.6126 37.8847 0 0 0 +p 22000 d ff 7fff66ff 69.75 49 0 0 69.75 49 0 0 0 +p 22000 d ff 7fff66ff 69.8733 48.2602 0 0 69.8733 48.2602 0 0 0 +p 22000 d ff 7fff66ff 69.875 47.5102 0 0 69.875 47.5102 0 0 0 +p 22000 d ff 7fff66ff 69.875 46.7602 0 0 69.875 46.7602 0 0 0 +p 22000 d ff 7fff66ff 69.875 46.0102 0 0 69.875 46.0102 0 0 0 +p 22000 e ff 7fff66ff 61.625 38 0 0 61.625 38 0 0 0 +p 22000 e ff 7fff66ff 61.625 37.25 0 0 61.625 37.25 0 0 0 +p 22000 e ff 7fff66ff 61.625 36.5 0 0 61.625 36.5 0 0 0 +p 22000 e ff 7fff66ff 61.625 35.75 0 0 61.625 35.75 0 0 0 +p 22000 e ff 7fff66ff 61.625 35 0 0 61.625 35 0 0 0 +p 22000 11 ff 7fff66ff 7.25 54 0 0 7.25 54 0 0 0 +p 22000 11 ff 7fff66ff 7.25 53.25 0 0 7.25 53.25 0 0 0 +p 22000 11 ff 7fff66ff 7.25 52.5 0 0 7.25 52.5 0 0 0 +p 22000 11 ff 7fff66ff 7.25 51.75 0 0 7.25 51.75 0 0 0 +p 402000 0 ff b26666ff 55.75 70.75 0 0 55.75 70.75 0 0 0 +p 402000 0 ff b26666ff 55.75 70 0 0 55.75 70 0 0 0 +p 402000 0 ff b26666ff 56.5 70 0 0 56.5 70 0 0 0 +p 402000 0 ff b26666ff 56.5 70.75 0 0 56.5 70.75 0 0 0 +p 402000 0 ff b26666ff 57.25 70.75 0 0 57.25 70.75 0 0 0 +p 402000 0 ff b26666ff 57.25 70 0 0 57.25 70 0 0 0 +p 402000 0 ff b26666ff 58 70 0 0 58 70 0 0 0 +p 402000 0 ff b26666ff 58 70.75 0 0 58 70.75 0 0 0 +p 402000 0 ff b26666ff 58.75 70 0 0 58.75 70 0 0 0 +p 402000 0 ff b26666ff 58.75 70.75 0 0 58.75 70.75 0 0 0 +p 402000 0 ff b26666ff 59.5 70.75 0 0 59.5 70.75 0 0 0 +p 402000 0 ff b26666ff 59.5 70 0 0 59.5 70 0 0 0 +p 402000 0 ff b26666ff 60.25 70 0 0 60.25 70 0 0 0 +p 402000 0 ff b26666ff 60.25 70.75 0 0 60.25 70.75 0 0 0 +p 402000 0 ff b26666ff 61 70 0 0 61 70 0 0 0 +p 402000 0 ff b26666ff 61 70.75 0 0 61 70.75 0 0 0 +p 402000 0 ff b26666ff 43 35.5 0 0 43 35.5 0 0 0 +p 402000 0 ff b26666ff 43 34 0 0 43 34 0 0 0 +p 402000 0 ff b26666ff 43 34.75 0 0 43 34.75 0 0 0 +p 402000 0 ff b26666ff 43.75 35.5 0 0 43.75 35.5 0 0 0 +p 402000 0 ff b26666ff 43.75 34 0 0 43.75 34 0 0 0 +p 402000 0 ff b26666ff 43.75 34.75 0 0 43.75 34.75 0 0 0 +p 402000 0 ff b26666ff 44.5 34.75 0 0 44.5 34.75 0 0 0 +p 402000 0 ff b26666ff 44.5 34 0 0 44.5 34 0 0 0 +p 402000 0 ff b26666ff 45.25 34 0 0 45.25 34 0 0 0 +p 402000 0 ff b26666ff 45.25 34.75 0 0 45.25 34.75 0 0 0 +p 402000 0 ff b26666ff 46 34 0 0 46 34 0 0 0 +p 402000 0 ff b26666ff 46 34.75 0 0 46 34.75 0 0 0 +@ time 7.52012 +@ timeStep 1504 +@ scale 8 +@ timeStepsPerFrame 8 +@ framesPerSecond 25 +@ pauseFlag 1 +@ randSeed 0 +@ gravityFlag 1 +@ gravityAcceleration 0.001 +@ gravityAmplification 1 +@ gravityAngle 0 +@ boundsFlag 1 +@ boundsThickness 0.25 +@ boundsLeft 0 +@ boundsRight 94.75 +@ boundsBottom 0 +@ boundsTop 89.25 +@ boundsRadius 1 +@ standardDistance 0.75 +@ standardDensity 1.0025 +@ maxSpeed 0.5 +@ pressureCoefficient 0.05 +@ repulsionCoefficient 0.05 +@ dampingFlag 1 +@ dampingCoefficient 0.05 +@ staticPressureFlag 0 +@ staticPressureCoefficient 0.5 +@ staticPressureIteration 1 +@ staticMaxPressure 0.5 +@ springCoefficient 0.05 +@ springIteration 5 +@ elasticCoefficient 0.5 +@ elasticIteration 5 +@ mochiElasticityCoefficient 0.1 +@ mochiSpringCoefficient 0.1 +@ mochiIteration 3 +@ viscosityCoefficient 0.4 +@ viscosityIteration 5 +@ surfaceTensionCoefficient 0.1 +@ surfacePressureCoefficient 0.05 +@ surfaceTensionIteration 5 +@ powderSpringCoefficient 0.5 +@ powderDampingCoefficient 0.3 +@ powderFrictionCoefficient 0.05 +@ powderLightProbability 0.5 +@ powderExtinguishProbability 0.05 +@ powderExplosionCoefficient 1 +@ brittlenessCoefficient 0.5 +@ jetCoefficient 0.5 +@ fuelLightProbability 0.01 +@ fuelExtinguishProbability 0.0005 +@ upCoefficient 10 +@ downCoefficient 10 +@ yukiSpringCoefficient 0.02 +@ yukiMeltingProbability 0.0001 +@ resistanceFlag 0 +@ resistanceCoefficient 0.02 +@ fireFlag 1 +@ fireProbability 0.005 +@ fireLife 1000 +@ fireBuoyancyCoefficient 10 +@ splashFlag 0 +@ splashProbability 0.05 +@ splashExpansion 1e-005 +@ splashMinLife 50 +@ bubbleFlag 0 +@ bubbleProbability 0.05 +@ bubbleLife 10000 +@ bubbleBuoyancyCoefficient 20 +@ pouringFlag 0 +@ pouringRainFlag 0 +@ pouringLocation 10 +@ pouringThickness 2 +@ pouringVelocity 0.1 +@ pouringTimer 0 +@ pouringMaterial 113 +@ pouringLayer -1 +@ clearFlag 1 +@ clearColorRed 0.2 +@ clearColorBlue 0.2 +@ clearColorGreen 0.2 +@ clearColorAlpha 1 +@ mouseRadius 1 +@ mouseDelay 10 +@ mouseForce 1 +@ lineWidth 1 +@ usersCharge 0 +@ usersMaxCharge 15 +@ usersSpeedX 0.05 +@ usersSpeedY 0.15 +@ usersForceX 0.05 +@ usersForceY 0.5 +@ usersX 0 +@ usersY 0 +@ viewWidth 0 +@ viewHeight 0 +@ scrollFlag 0 +@ scrollX 0 +@ scrollY 0 +@ scrollAngle 0 +@ colorFlag 1 +@ renderMode 2 -- 2.7.4
  6. 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ü`Q`HYv~Mdh_ys!WPIP|%RhEE$ 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

  7. Am5qy|8O^>0bFcb+d2j9=o&f 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